From 3a59ca37180016c116c323dd1192dc8d70f314c1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 16 Jun 2017 01:19:58 +0200 Subject: [PATCH 0001/4321] added pull request template moves github specific files into .github --- ISSUE_TEMPLATE.md => .github/ISSUE_TEMPLATE.md | 0 .github/PULL_REQUEST_TEMPLATE.md | 14 ++++++++++++++ 2 files changed, 14 insertions(+) rename ISSUE_TEMPLATE.md => .github/ISSUE_TEMPLATE.md (100%) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 100% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..5bb125c986 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ + + +##### Checklist + +- [ ] Documentation is added or updated +- [ ] New files have a LGPL 2.1 license statement +- [ ] Tested with the following card: + - [ ] tested PKCS#11 + - [ ] tested Windows Minidriver + - [ ] tested macOS Tokend From 9fe9b9266b1b086cf737798c99721ae612e7cd4f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 16 Jun 2017 01:44:14 +0200 Subject: [PATCH 0002/4321] use a better issue template removes CONTRIBUTING.md --- .github/ISSUE_TEMPLATE.md | 28 ++++++++++------------------ CONTRIBUTING.md | 3 --- 2 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 109d58838f..49ba8602b8 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,24 +1,17 @@ -### Expected behaviour +### Problem Description -What should happen? - - -### Actual behaviour - -What happens instead? + +### Proposed Resolution ### Steps to reproduce -1. -2. -3. - - ### Logs -Debug output is essential to identify the problem. You can enable debugging by -editing the file `opensc.conf`: + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index d587910ab8..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Reporting Bugs - -Please read about [reporting bugs](https://github.com/OpenSC/OpenSC/wiki/How-to-report-bugs-so-that-they-can-be-fixed) before opening an issue. From e069654f3b0f6816ac5d45ce13ff6fa41c1eb536 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 4 Jul 2017 14:25:50 +0200 Subject: [PATCH 0003/4321] [coolkey] Copy labels from certificate objects to the keys --- src/libopensc/pkcs15-coolkey.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 5064a0f4f7..a5f457acde 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -484,7 +484,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) sc_card_t *card = p15card->card; sc_serial_number_t serial; int count; - + struct sc_pkcs15_object *obj; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -558,6 +558,8 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) memset(&obj_obj, 0, sizeof(obj_obj)); + /* coolkey applets have label only on the certificates, + * but we should copy it also to the keys maching the same ID */ coolkey_get_attribute_bytes(card, &coolkey_obj, CKA_LABEL, (u8 *)obj_obj.label, &len, sizeof(obj_obj.label)); coolkey_get_flags(card, &coolkey_obj, &obj_obj.flags); if (obj_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE) { @@ -677,6 +679,35 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count); + /* Iterate over all the created objects and fill missing labels */ + for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { + struct sc_pkcs15_id *id = NULL; + struct sc_pkcs15_object *cert_object; + + /* label non-empty -- do not overwrite */ + if (obj->label[0] != '\0') + continue; + + switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { + case SC_PKCS15_TYPE_PUBKEY: + id = &((struct sc_pkcs15_pubkey_info *)obj->data)->id; + break; + case SC_PKCS15_TYPE_PRKEY: + id = &((struct sc_pkcs15_prkey_info *)obj->data)->id; + break; + default: + /* We do not care about other objects */ + continue; + } + r = sc_pkcs15_find_cert_by_id(p15card, id, &cert_object); + if (r != 0) + continue; + + sc_log(card->ctx, "Copy label \"%s\" from cert to key object", + cert_object->label); + memcpy(obj->label, cert_object->label, SC_PKCS15_MAX_LABEL_SIZE); + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } From deab9cce73377f973d2020ab5ab7adc302018bf6 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 7 Jul 2017 12:44:46 +0200 Subject: [PATCH 0004/4321] MyEID support for RAW RSA signature for 2048 bit keys MyEID does not support RAW RSA signature for 2048 bit key. (Source: MyEID reference manual 2.1.4) This hack uses decipher operation for calculating RAW 2048 bit signature. --- src/libopensc/card-myeid.c | 83 +++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 1b053a03c7..b276040a6a 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -881,7 +881,73 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char * free(buf); return buflen; } +/* + MyEID does not support RAW RSA signature for 2048 bit key. + (Source: MyEID reference manual 2.1.4) + This function uses decipher operation for calculating RAW 2048 bit signature. +*/ +static int +myeid_compute_raw_2048_signature(struct sc_card *card, const u8 * data, size_t datalen, + u8 * out, size_t outlen) +{ + int r; + struct sc_context *ctx; + struct myeid_private_data *priv; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + sc_security_env_t env; + + ctx = card->ctx; + LOG_FUNC_CALLED(ctx); + + priv = (myeid_private_data_t *) card->drv_data; + +/* security env change - use DECIPHER operation */ + memcpy(&env, priv->sec_env, sizeof(sc_security_env_t)); + env.flags |= SC_SEC_ENV_ALG_REF_PRESENT; + env.flags |= SC_SEC_ENV_FILE_REF_PRESENT; + env.flags |= SC_SEC_ENV_KEY_REF_PRESENT; + env.operation = SC_SEC_OPERATION_DECIPHER; + myeid_set_security_env_rsa(card, &env, 0); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 0; /* there is no response to 1st part of data */ + +/* prepare 1st part of data */ + sbuf[0] = 0x81; + memcpy(sbuf + 1, data, datalen / 2); + apdu.lc = datalen / 2 + 1; + apdu.datalen = apdu.lc; + apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { +/* prepare 2nd part of data */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = datalen; + sbuf[0] = 0x82; + memcpy(sbuf + 1, data + datalen / 2, datalen / 2); + apdu.lc = datalen / 2 + 1; + apdu.datalen = apdu.lc; + apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + int len = apdu.resplen > outlen ? outlen : apdu.resplen; + memcpy(out, apdu.resp, len); + LOG_FUNC_RETURN(card->ctx, len); + } + } + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} static int myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, @@ -919,6 +985,9 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, if ((datalen + pad_chars) > 256) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + if (datalen == 256 && priv->sec_env->algorithm == SC_ALGORITHM_RSA) + return myeid_compute_raw_2048_signature(card, data, datalen, out, outlen); + /* INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x9E Resp: Digital Signature * P2: 0x9A Cmd: Input for Digital Signature */ @@ -926,17 +995,9 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; - if (datalen == 256) { - apdu.p2 = data[0]; - memcpy(sbuf, data+1, datalen-1); - apdu.lc = datalen - 1; - apdu.datalen = datalen - 1; - } - else { - memcpy(sbuf + pad_chars, data, datalen); - apdu.lc = datalen + pad_chars; - apdu.datalen = datalen + pad_chars; - } + memcpy(sbuf + pad_chars, data, datalen); + apdu.lc = datalen + pad_chars; + apdu.datalen = datalen + pad_chars; apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); From 93fa520bc991cc027617a71b8cc007651e8ca34a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 11 Jul 2017 10:12:17 +0200 Subject: [PATCH 0005/4321] Cope with incomplete ASN.1 data in sc_asn1_read_tag --- src/libopensc/asn1.c | 7 +++++-- src/libopensc/pkcs15-pubkey.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 88d35db959..d3d1b87eb1 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -112,12 +112,15 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, } len = a; } - if (len > left) - return SC_ERROR_INVALID_ASN1_OBJECT; + *cla_out = cla; *tag_out = tag; *taglen = len; *buf = p; + + if (len > left) + return SC_ERROR_ASN1_END_OF_CONTENTS; + return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 63879fca28..16acdc6175 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1234,7 +1234,7 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename, int r; int f = -1; size_t len, offs; - u8 tagbuf[1024]; /* enough to read in the tag and length */ + u8 tagbuf[16]; /* enough to read in the tag and length */ u8 * rbuf = NULL; size_t rbuflen = 0; const u8 * body = NULL; @@ -1264,7 +1264,7 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename, body = tagbuf; r = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen); - if (r != SC_SUCCESS) + if (r != SC_SUCCESS && r != SC_ERROR_ASN1_END_OF_CONTENTS) goto out; if (tag_out == SC_ASN1_TAG_EOC || body == NULL) { From e2fe24d56ac4a90bf140c670ebea02dee6a599d6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 16 Jun 2017 11:29:20 +0200 Subject: [PATCH 0006/4321] clang static analyzer reports tools/pkcs15-tool.c: Dead assignment: Value stored to 'c' is never read tools/pkcs11-tool.c: Dead assignment: Value stored to 'n' is never read Dead assignment: Value stored to 'rv' is never read libopensc/card-cac.c: Dead assignemnt: Value stored to 'tl_head_len' is never read Dead increment: Value stored to 'outp' is never read common/libpkcs11.c: Memory leak in case of C_UnloadModule() fails libopensc/pkcs15-pubkey.c: Potential memory leaks pkcs11/mechanism.c: Potential memory leak pkcs11/framework-pkcs15.c: Potential memory leaks Dereference of null pointer Dead assignments tools/sc-hsm-tool.c: Function call argument is an uninitialized value Dead assignment: Value stored to 'r' is never read libopensc/card-openpgp.c: Dead assignment: ignoring the errors in case of sc_pkcs15_encode_pubkey() failed libopensc/pkcs15-cac.c: Dead assignments: ignoring return values libopensc/pkcs15-coolkey.c: Dead assignments: ignoring return values libopensc/card-sc-hsm.c: Dereference of undefined pointer value: Properly check the file allocation pkcs11/slot.c: Dead assignment pkcs15init/pkcs15-cflex.c: Dereference of null pointer Uninitialized argument values --- src/common/libpkcs11.c | 5 +++-- src/libopensc/card-cac.c | 3 +-- src/libopensc/card-openpgp.c | 1 + src/libopensc/card-sc-hsm.c | 4 ++-- src/libopensc/pkcs15-cac.c | 7 +++++++ src/libopensc/pkcs15-coolkey.c | 3 +++ src/libopensc/pkcs15-pubkey.c | 10 +++++++--- src/pkcs11/framework-pkcs15.c | 20 +++++++++----------- src/pkcs11/mechanism.c | 6 ++++-- src/pkcs11/slot.c | 2 -- src/pkcs15init/pkcs15-cflex.c | 6 +++--- src/tools/pkcs11-tool.c | 5 ++++- src/tools/pkcs15-tool.c | 2 -- src/tools/sc-hsm-tool.c | 9 ++++++--- 14 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index e65fda7ecb..9f99b8af89 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -75,8 +75,9 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) return (void *) mod; else { fprintf(stderr, "C_GetFunctionList failed %lx", rv); - C_UnloadModule((void *) mod); - return NULL; + rv = C_UnloadModule((void *) mod); + if (rv == CKR_OK) + mod = NULL; /* already freed */ } failed: free(mod); diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 36f911ed91..ed15ba0a89 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -665,7 +665,6 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, cert_len = 0; cert_ptr = NULL; cert_type = 0; - tl_head_len = 2; for (tl_ptr = tl, val_ptr=val; tl_len >= 2; val_len -= len, val_ptr += len, tl_len -= tl_head_len) { tl_start = tl_ptr; @@ -943,7 +942,7 @@ static int cac_rsa_op(sc_card_t *card, if (rbuflen != 0) { int n = MIN(rbuflen, outplen); memcpy(outp,rbuf, n); - outp += n; + /*outp += n; unused */ outplen -= n; } free(rbuf); diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cf4de26f70..12e048aa5a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2020,6 +2020,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, pubkey.u.rsa.exponent.len = exponent_len >> 3; r = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &data, &len); + LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey."); sc_log(card->ctx, "Update blob content."); r = pgp_set_blob(pk_blob, data, len); diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cfa084a060..09eb89a207 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1489,7 +1489,7 @@ static int sc_hsm_init(struct sc_card *card) size_t expanded_len = PATH_MAX; #endif int flags,ext_flags; - sc_file_t *file; + sc_file_t *file = NULL; sc_path_t path; sc_hsm_private_data_t *priv = card->drv_data; @@ -1530,7 +1530,7 @@ static int sc_hsm_init(struct sc_card *card) sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS - && file->prop_attr && file->prop_attr_len >= 5) { + && file && file->prop_attr && file->prop_attr_len >= 5) { static char card_name[SC_MAX_APDU_BUFFER_SIZE]; u8 type = file->prop_attr[2]; u8 major = file->prop_attr[3]; diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 45e5988f8e..fa76ec34ea 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -257,6 +257,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* set other objects */ r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_INIT_GET_GENERIC_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not initiate generic objects."); + for (i = 0; i < count; i++) { struct sc_pkcs15_data_info obj_info; struct sc_pkcs15_object obj_obj; @@ -273,6 +275,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not finalize generic objects."); /* * certs, pubkeys and priv keys are related and we assume @@ -282,6 +285,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) */ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC adding certs, pub and priv keys..."); r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_INIT_GET_CERT_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not initiate cert objects."); + for (i = 0; i < count; i++) { struct sc_pkcs15_data_info obj_info; struct sc_pkcs15_cert_info cert_info; @@ -294,6 +299,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_pkcs15_cert_t *cert_out = NULL; r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_GET_NEXT_CERT_OBJECT, &obj_info); + LOG_TEST_RET(card->ctx, r, "Can not get next object"); memset(&cert_info, 0, sizeof(cert_info)); memset(&pubkey_info, 0, sizeof(pubkey_info)); @@ -421,6 +427,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not finalize cert objects."); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index a5f457acde..41b0ff32d3 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -539,6 +539,8 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) /* set other objects */ r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_INIT_GET_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not initiate objects."); + for (i = 0; i < count; i++) { struct sc_cardctl_coolkey_object coolkey_obj; struct sc_pkcs15_object obj_obj; @@ -678,6 +680,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count); + LOG_TEST_RET(card->ctx, r, "Can not finalize objects."); /* Iterate over all the created objects and fill missing labels */ for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 16acdc6175..cb522a0924 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1098,8 +1098,10 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc rv = sc_asn1_encode_algorithm_id(ctx, &alg, &alglen,key->alg_id, 0); if (rv == SC_SUCCESS) { pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id)); - if (pubkey->alg_id == NULL) + if (pubkey->alg_id == NULL) { + free(pubkey); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } rv = sc_asn1_decode_algorithm_id(ctx, alg, alglen, pubkey->alg_id, 0); free(alg); } @@ -1389,8 +1391,10 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke } pubkey->u.ec.ecpointQ.value = malloc(pk.len); - if (pubkey->u.ec.ecpointQ.value == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + if (pubkey->u.ec.ecpointQ.value == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "failed to malloc() memory"); + } memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len); pubkey->u.ec.ecpointQ.len = pk.len; } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 776f466879..5b3cb32e54 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -718,7 +718,7 @@ __pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data, } else if (!(pubkey->emulated && (fw_data->p15_card->flags & SC_PKCS15_CARD_FLAG_EMULATED))) { sc_pkcs15_free_pubkey(p15_key); } - if (object->pub_data) { + if (object && object->pub_data) { if ((object->pub_data->alg_id)&&(object->pub_data->algorithm == SC_ALGORITHM_GOSTR3410)) object->pub_data->alg_id->params = &((object->pub_data->u).gostr3410.params); } @@ -734,7 +734,7 @@ static int __pkcs15_create_prkey_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_object *prkey, struct pkcs15_any_object **prkey_object) { - struct pkcs15_prkey_object *object; + struct pkcs15_prkey_object *object = NULL; int rv; rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &object, @@ -1821,7 +1821,7 @@ pkcs15_initialize(struct sc_pkcs11_slot *slot, void *ptr, if (p15card) { sc_log(context, "pkcs15init erase card"); - rc = sc_pkcs15init_erase_card(p15card, profile, NULL); + sc_pkcs15init_erase_card(p15card, profile, NULL); sc_log(context, "pkcs15init unbind"); sc_pkcs15init_unbind(profile); @@ -2253,11 +2253,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile key_obj->flags = 2; /* TODO not sure what these mean */ - skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); + skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); if (skey_info == NULL) { rv = CKR_HOST_MEMORY; goto out; - } + } key_obj->data = skey_info; skey_info->usage = args.usage; skey_info->native = 0; /* card can not use this */ @@ -2266,7 +2266,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile skey_info->data.value = args.key.data; skey_info->data.len = args.key.data_len; skey_info->value_len = args.value_len; /* callers prefered length */ - + args.key.data = NULL; } else { #if 1 @@ -2290,6 +2290,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile rv = CKR_OK; out: + free(args.key.data); /* if allocated */ free(key_obj); return rv; } @@ -2335,7 +2336,6 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile return CKR_ATTRIBUTE_VALUE_INVALID; } - rv = CKR_OK; while (ulCount--) { CK_ATTRIBUTE_PTR attr = pTemplate++; sc_pkcs15_bignum_t *bn = NULL; @@ -2429,7 +2429,6 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot, if (cert_type != CKC_X_509) return CKR_ATTRIBUTE_VALUE_INVALID; - rv = CKR_OK; while (ulCount--) { CK_ATTRIBUTE_PTR attr = pTemplate++; @@ -2438,7 +2437,7 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot, case CKA_CLASS: break; case CKA_PRIVATE: - rv = attr_extract(attr, &bValue, NULL); + attr_extract(attr, &bValue, NULL); if (bValue) { rv = CKR_TEMPLATE_INCONSISTENT; goto out; @@ -2505,7 +2504,6 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); - rv = CKR_OK; while (ulCount--) { CK_ATTRIBUTE_PTR attr = pTemplate++; @@ -2514,7 +2512,7 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, case CKA_CLASS: break; case CKA_PRIVATE: - rv = attr_extract(attr, &bValue, NULL); + attr_extract(attr, &bValue, NULL); if (bValue) { pin = slot_data_auth_info(slot->fw_data); if (pin == NULL) { diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index b64d052036..f3ab284a15 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1059,8 +1059,10 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, info->hash_mech = hash_mech; new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_type, info, free_info); - - if (!new_type) + if (!new_type) { + free(info); return CKR_HOST_MEMORY; + } + return sc_pkcs11_register_mechanism(p11card, new_type); } diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 0b6b208b4f..5a3c8d1f39 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -230,8 +230,6 @@ CK_RV card_detect(sc_reader_t *reader) unsigned int i; int j; - rv = CKR_OK; - sc_log(context, "%s: Detecting smart card", reader->name); /* Check if someone inserted a card */ again: diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 4117e146d0..19579d836f 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -296,9 +296,9 @@ cflex_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_obj goto out; } - if (prkf->size < size) + if (prkf && prkf->size < size) prkf->size = size; - if (pukf->size < size + 4) + if (pukf && pukf->size < size + 4) pukf->size = size + 4; /* Now create the files */ @@ -385,7 +385,7 @@ cflex_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, { sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; sc_card_t *card = p15card->card; - sc_file_t *prkf, *pukf; + sc_file_t *prkf = NULL, *pukf = NULL; unsigned char keybuf[1024]; size_t size; int r; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 665318c250..f1ff0efb8b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2193,7 +2193,6 @@ static void parse_certificate(struct x509cert_info *cert, cert->issuer_len = n; /* check length first */ - n = 0; n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL); if (n < 0) util_fatal("OpenSSL error while encoding serial number"); @@ -3542,6 +3541,9 @@ get_mechanisms(CK_SLOT_ID slot, CK_MECHANISM_TYPE_PTR *pList, CK_FLAGS flags) CK_RV rv; rv = p11->C_GetMechanismList(slot, *pList, &ulCount); + if (rv != CKR_OK) + p11_fatal("C_GetMechanismList", rv); + *pList = calloc(ulCount, sizeof(**pList)); if (*pList == NULL) util_fatal("calloc failed: %m"); @@ -5193,6 +5195,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE p11_fatal("C_SignInit", rv); if (getALWAYS_AUTHENTICATE(session, priv_key)) login(session,CKU_CONTEXT_SPECIFIC); + rv = p11->C_Sign(session, data, data_len, sig, &sig_len); if (rv != CKR_OK) p11_fatal("C_Sign", rv); diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 2c15cb6a17..15ddde07e3 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2061,8 +2061,6 @@ int main(int argc, char * const argv[]) assert(sizeof(option_help)/sizeof(char *)==sizeof(options)/sizeof(struct option)); - c = OPT_PUK; - while (1) { c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind); if (c == -1) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 718a8f1190..938a8955da 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -45,6 +45,7 @@ #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/asn1.h" +#include "libopensc/log.h" #include "libopensc/card-sc-hsm.h" #include "util.h" @@ -1387,8 +1388,9 @@ static int wrap_key(sc_card_t *card, int keyid, const char *outf, const char *pi // Encode key in octet string object key_len = 0; - wrap_with_tag(0x04, wrapped_key.wrapped_key, wrapped_key.wrapped_key_length, + r = wrap_with_tag(0x04, wrapped_key.wrapped_key, wrapped_key.wrapped_key_length, &key, &key_len); + LOG_TEST_RET(ctx, r, "Out of memory"); memcpy(ptr, key, key_len); ptr += key_len; @@ -1410,7 +1412,8 @@ static int wrap_key(sc_card_t *card, int keyid, const char *outf, const char *pi } // Encode key, key decription and certificate object in sequence - wrap_with_tag(0x30, keyblob, ptr - keyblob, &key, &key_len); + r = wrap_with_tag(0x30, keyblob, ptr - keyblob, &key, &key_len); + LOG_TEST_RET(ctx, r, "Out of memory"); out = fopen(outf, "wb"); @@ -1449,7 +1452,7 @@ static int update_ef(sc_card_t *card, u8 prefix, u8 id, int erase, const u8 *buf r = sc_select_file(card, &path, NULL); if ((r == SC_SUCCESS) && erase) { - r = sc_delete_file(card, &path); + sc_delete_file(card, &path); r = SC_ERROR_FILE_NOT_FOUND; } From def06389bfeec4eabfb88801c388ae30a6f7b693 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 19 Jul 2017 00:09:36 +0200 Subject: [PATCH 0007/4321] sc-hsm: fixed building with --disable-sm Closes https://github.com/OpenSC/OpenSC/pull/1103 --- src/libopensc/card-sc-hsm.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 09eb89a207..7f166379c7 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -284,7 +284,9 @@ static int sc_hsm_soc_select_minbioclient(sc_card_t *card) }; /* Select MinBioClient */ +#ifdef ENABLE_SM sc_sm_stop(card); +#endif sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); apdu.data = minBioClient_aid.value; apdu.datalen = minBioClient_aid.len; @@ -533,7 +535,9 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; sc_apdu_t apdu; u8 cmdbuff[16]; +#ifdef ENABLE_SM u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; +#endif int r; int cmd = data->cmd; size_t pin2_len = data->pin2.len; @@ -563,7 +567,10 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, if ((card->type == SC_CARD_TYPE_SC_HSM_SOC || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN) && (data->cmd != SC_PIN_CMD_GET_INFO) - && card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { +#ifdef ENABLE_SM + && card->sm_ctx.sm_mode != SM_MODE_TRANSMIT +#endif + ) { LOG_TEST_RET(card->ctx, sc_hsm_perform_chip_authentication(card), "Could not perform chip authentication"); @@ -604,6 +611,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->apdu = &apdu; } +#ifdef ENABLE_SM if ((data->cmd == SC_PIN_CMD_GET_INFO) && (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT)) { /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */ @@ -612,6 +620,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.resplen = sizeof rbuf; data->apdu = &apdu; } +#endif data->pin1.offset = 5; data->pin1.length_offset = 4; @@ -627,11 +636,17 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->cmd = SC_PIN_CMD_GET_SESSION_PIN; if (data->pin_reference == 0x81) { u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; +#ifdef ENABLE_SM if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Session PIN generation only supported in SM"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +#else + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "Session PIN generation only supported in SM"); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +#endif sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x5A, 0x01, data->pin_reference); apdu.cla = 0x80; apdu.resp = recvbuf; @@ -669,7 +684,9 @@ static int sc_hsm_logout(sc_card_t * card) sc_path_t path; sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; memset(priv->sopin, 0, sizeof(priv->sopin)); +#ifdef ENABLE_SM sc_sm_stop(card); +#endif sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); @@ -1586,7 +1603,9 @@ static int sc_hsm_init(struct sc_card *card) static int sc_hsm_finish(sc_card_t * card) { sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; +#ifdef ENABLE_SM sc_sm_stop(card); +#endif if (priv->serialno) { free(priv->serialno); } From 1c7ef66ce793d334e12e9fe9cd5c129fad620ec0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 19 Jul 2017 09:29:18 +0200 Subject: [PATCH 0008/4321] fixed date of 0.17.0 in NEWS Fixes https://github.com/OpenSC/OpenSC/issues/1105 https://github.com/OpenSC/OpenSC/releases/download/0.17.0/opensc-0.17.0.tar.gz has been updated to include this fix. --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index de485baa72..85cc4e292b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.17.0; 2016-07-18 +# New in 0.17.0; 2017-07-18 ## Support for new Cards * CAC (Common Access Card) * GoID (SC-HSM with built-in PIN pad and fingerprint sensor) From 7a39d6d058fb7af1987d38a98860bb065e8a0262 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 21 Jul 2017 14:05:47 +0200 Subject: [PATCH 0009/4321] build against OpenSSL 1.1.0 on Windows, by default - build with AppVeyor's OpenSSL 1.1.0 - updates AppVeyor version of OpenPACE Fixes https://github.com/OpenSC/OpenSC/issues/1108 --- appveyor.yml | 13 +++---------- src/libopensc/card-sc-hsm.c | 2 +- src/sm/sm-eac.c | 14 +++++++------- src/tools/npa-tool.c | 2 +- win32/Make.rules.mak | 12 ++++++++++-- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6aa47b547e..3d0392fa97 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,8 +29,7 @@ install: throw "There are newer queued builds for this pull request, failing early." } - date /T & time /T - set PATH=C:\cygwin\bin;%PATH% - - set OPENSSL_VER=1_0_2f - - set OPENPACE_VER=1.0.1 + - set OPENPACE_VER=1.0.2 - set ZLIB_VER_DOT=1.2.8 - ps: $env:PACKAGE_NAME=(git describe --tags) - ps: >- @@ -49,10 +48,6 @@ install: } - ps: >- If (!($env:Configuration -Like "*Light*")) { - If (!(Test-Path -Path "C:\OpenSSL-${env:OPENSSL_PF}" )) { - Start-FileDownload https://slproweb.com/download/${env:OPENSSL_PF}OpenSSL-${env:OPENSSL_VER}.exe -FileName C:\WinOpenSSL.exe - C:\WinOpenSSL.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART - } $env:NMAKE_EXTRA="OPENSSL_DEF=/DENABLE_OPENSSL ${env:NMAKE_EXTRA}" If (!(Test-Path C:\zlib )) { appveyor DownloadFile "https://github.com/madler/zlib/archive/v${env:ZLIB_VER_DOT}.zip" -FileName zlib.zip @@ -92,8 +87,8 @@ build_script: # build libeac.lib as a static library xcopy C:\openpace C:\openpace-${env:OPENSSL_PF} /e /i /y /s cd C:\openpace-${env:OPENSSL_PF}\src - cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c - lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj + cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c + lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj cd C:\projects\OpenSC } $env:NMAKE_EXTRA="OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=C:\openpace-${env:OPENSSL_PF} ${env:NMAKE_EXTRA}" @@ -114,8 +109,6 @@ build_script: } cache: - - C:\OpenSSL-Win32 -> appveyor.yml - - C:\OpenSSL-Win64 -> appveyor.yml - C:\zlib -> appveyor.yml - C:\zlib-Win32 -> appveyor.yml - C:\zlib-Win64 -> appveyor.yml diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 7f166379c7..5a4179133d 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -500,7 +500,7 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) goto err; } EVP_PKEY_free(ctx->ca_ctx->ka_ctx->key); - CRYPTO_add(&ctx->ta_ctx->pub_key->references, 1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(ctx->ta_ctx->pub_key); ctx->ca_ctx->ka_ctx->key = ctx->ta_ctx->pub_key; /* generate keys for CA */ diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index a556105569..89712bd77e 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -425,7 +425,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, if (key_reference1 && key_reference1_len) { data->key_reference1 = ASN1_OCTET_STRING_new(); if (!data->key_reference1 - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( data->key_reference1, key_reference1, key_reference1_len)) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 1 of MSE:Set AT data"); r = SC_ERROR_INTERNAL; @@ -436,7 +436,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, if (key_reference2 && key_reference2_len) { data->key_reference2 = ASN1_OCTET_STRING_new(); if (!data->key_reference2 - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( data->key_reference2, key_reference2, key_reference2_len)) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 2 of MSE:Set AT data"); r = SC_ERROR_INTERNAL; @@ -447,7 +447,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, if (eph_pub_key && eph_pub_key_len) { data->eph_pub_key = ASN1_OCTET_STRING_new(); if (!data->eph_pub_key - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( data->eph_pub_key, eph_pub_key, eph_pub_key_len)) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting ephemeral Public Key of MSE:Set AT data"); r = SC_ERROR_INTERNAL; @@ -710,7 +710,7 @@ static int npa_gen_auth_2_map_nonce(sc_card_t *card, } c_data->mapping_data = ASN1_OCTET_STRING_new(); if (!c_data->mapping_data - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( c_data->mapping_data, in, in_len)) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -802,7 +802,7 @@ static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, } c_data->eph_pub_key = ASN1_OCTET_STRING_new(); if (!c_data->eph_pub_key - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( c_data->eph_pub_key, in, in_len)) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -895,7 +895,7 @@ static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, } c_data->auth_token = ASN1_OCTET_STRING_new(); if (!c_data->auth_token - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( c_data->auth_token, in, in_len)) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -1684,7 +1684,7 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, } c_data->eph_pub_key = ASN1_OCTET_STRING_new(); if (!c_data->eph_pub_key - || !M_ASN1_OCTET_STRING_set( c_data->eph_pub_key, + || !ASN1_OCTET_STRING_set( c_data->eph_pub_key, eph_pub_key->data, eph_pub_key->length)) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 11b557598e..4f2a5d0a41 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -319,7 +319,7 @@ static int add_to_ASN1_AUXILIARY_DATA( if (data && data_len) { template->discretionary_data3 = ASN1_OCTET_STRING_new(); if (!template->discretionary_data3 - || !M_ASN1_OCTET_STRING_set( + || !ASN1_OCTET_STRING_set( template->discretionary_data3, data, data_len)) { r = SC_ERROR_INTERNAL; goto err; diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 8a009448cf..b8e0adf670 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -44,9 +44,17 @@ OPENSSL_INCL_DIR = /I$(OPENSSL_DIR)\include OPENSSL_STATIC_DIR = static !IF "$(DEBUG_DEF)" == "/DDEBUG" -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib +!IF "$(PLATFORM)" == "x86" +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +!ELSE +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +!ENDIF !ELSE -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib +!IF "$(PLATFORM)" == "x86" +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +!ELSE +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +!ENDIF !ENDIF PROGRAMS_OPENSSL = cryptoflex-tool.exe pkcs15-init.exe netkey-tool.exe piv-tool.exe \ From 78100508a82ba74c995d1f8ddf3e0ade0f63350e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 19 Jul 2017 13:30:29 +0200 Subject: [PATCH 0010/4321] AppVeyor: cache cngsdk.msi --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3d0392fa97..843add918d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -60,10 +60,12 @@ install: Rename-Item -path "c:\openpace-${env:OPENPACE_VER}" -newName "openpace" } } + If (!(Test-Path cngsdk.msi )) { + appveyor DownloadFile "http://download.microsoft.com/download/2/C/9/2C93059C-0532-42DF-8C24-9AEAFF00768E/cngsdk.msi" + } - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% - - appveyor DownloadFile "http://download.microsoft.com/download/2/C/9/2C93059C-0532-42DF-8C24-9AEAFF00768E/cngsdk.msi" - cngsdk.msi /quiet - uname -a - set @@ -115,6 +117,7 @@ cache: - C:\openpace -> appveyor.yml - C:\openpace-Win32 -> appveyor.yml - C:\openpace-Win64 -> appveyor.yml + - cngsdk.msi -> appveyor.yml deploy: - provider: GitHub From 29589e8a92e082226c65f1d3a5bd6c58dc8b20fd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 21 Jul 2017 17:43:52 +0200 Subject: [PATCH 0011/4321] AppVeyor: Drop VS2010 build The pre-compiled OpenSSL binaries on AppVeyor are incompatible with VS2010 --- appveyor.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 843add918d..01762cb3a3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.16.0.{build} +version: 0.17.0.{build} platform: - x86 @@ -14,13 +14,6 @@ environment: matrix: - VSVER: 14 - VSVER: 12 - - VSVER: 10 - -matrix: - allow_failures: - # not included in AppVeyor right now - - platform: x64 - VSVER: 10 install: - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` From 977728a5bfea0e8bd6c392caba4211e5d2f64058 Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Fri, 14 Jul 2017 16:17:29 +0900 Subject: [PATCH 0012/4321] jpki: set user_consent flag --- src/libopensc/pkcs15-jpki.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 1a43320cef..b814d8d7ca 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -164,7 +164,7 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) "User Authentication Key", "Digital Signature Key" }; - + static int prkey_user_consent[2] = { 0, 1 }; struct sc_pkcs15_prkey_info prkey_info; struct sc_pkcs15_object prkey_obj; @@ -181,7 +181,7 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) strlcpy(prkey_obj.label, prkey_name[i], sizeof (prkey_obj.label)); prkey_obj.auth_id.len = 1; prkey_obj.auth_id.value[0] = prkey_pin[i]; - prkey_obj.user_consent = 0; + prkey_obj.user_consent = prkey_user_consent[i]; prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; rc = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); From da9484bd6b4052ea6fb022d27bd7e75350d6cf76 Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Mon, 10 Apr 2017 16:39:44 +0900 Subject: [PATCH 0013/4321] fix trivial leak --- src/libopensc/card-jpki.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 069470fac7..5fed179e7e 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -82,7 +82,10 @@ jpki_finish(sc_card_t * card) struct jpki_private_data *drvdata = JPKI_DRVDATA(card); LOG_FUNC_CALLED(card->ctx); - + if (drvdata->mf) { + free(drvdata->mf); + drvdata->mf = NULL; + } if (drvdata) { free(drvdata); card->drv_data = NULL; From e25565d851b6e4aab0ee00f0533b4c128a24e0ff Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Tue, 1 Aug 2017 16:31:00 +0900 Subject: [PATCH 0014/4321] add public keys --- src/libopensc/pkcs15-jpki.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index b814d8d7ca..1c31bea97e 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -188,6 +188,37 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) if (rc < 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } + + /* add public keys */ + for (i = 0; i < 2; i++) { + static int pubkey_id[2] = { 1, 2 }; + static const char *jpki_pubkey_names[2] = { + "User Authentication Public Key", + "Digital Signature Public Key" + }; + struct sc_pkcs15_pubkey_info pubkey_info; + struct sc_pkcs15_object pubkey_obj; + static char const *jpki_pubkey_paths[2] = { + "000A", + "0001" + }; + + memset(&pubkey_info, 0, sizeof (pubkey_info)); + memset(&pubkey_obj, 0, sizeof (pubkey_obj)); + + strlcpy(pubkey_obj.label, jpki_pubkey_names[i], sizeof (pubkey_obj.label)); + pubkey_info.id.len = 1; + pubkey_info.id.value[0] = pubkey_id[i]; + pubkey_info.native = 1; + pubkey_info.key_reference = i + 1; + + sc_format_path(jpki_pubkey_paths[i], &pubkey_info.path); + pubkey_info.path.type = SC_PATH_TYPE_FILE_ID; + + rc = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + if (rc < 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } From 3d187d9ac45cbaf46d3f5211ccd4c6808456296d Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Wed, 2 Aug 2017 17:45:53 +0900 Subject: [PATCH 0015/4321] documentation for ignore_private_certificate parameter. --- etc/opensc.conf.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 63abba9bf3..ff87ee137c 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -782,6 +782,11 @@ app tokend { # Default: 300 # # score = 10; + + # Tokend ignore to read PIN protected certificate that is set SC_PKCS15_CO_FLAG_PRIVATE flag. + # Default: true + # + # ignore_private_certificate = false; } } From 61916be728607385f264ce3c10fe63159d8d3fac Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 13 Jan 2017 19:40:03 +0100 Subject: [PATCH 0016/4321] md: added cancel button to PINPAD GUI ... as required by minidriver spec - Shows PIN purpose depending on the PIN type similar to Base CSP --- src/minidriver/minidriver.c | 63 ++++++++++++++++----- src/minidriver/versioninfo-minidriver.rc.in | 7 ++- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 0e6ab7869f..f0c247b8b2 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -113,6 +113,7 @@ HINSTANCE g_inst; /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ #define IDD_PINPAD 101 #define IDI_LOGO 102 +#define IDC_PURPOSE_TEXT 1002 #define IDC_PINPAD_TEXT 1001 #define IDC_PINPAD_ICON 1000 @@ -2366,8 +2367,8 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) rv = (DWORD) ERROR_INVALID_PARAMETER; break; } - if (parameter[9] != 0) { - EndDialog((HWND) parameter[9], rv); + if (parameter[10] != 0) { + EndDialog((HWND) parameter[10], rv); } return (DWORD) rv; } @@ -2379,6 +2380,7 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L { case WM_INITDIALOG: { + DWORD role = (DWORD) (((LONG_PTR*)lParam)[8]); HICON hIcon = NULL; PCARD_DATA pCardData = (PCARD_DATA) (((LONG_PTR*)lParam)[7]); VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; @@ -2386,7 +2388,20 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); /* change the text shown on the screen */ if (vs->wszPinContext ) { - SetWindowTextW(GetDlgItem(hWnd, IDC_PINPAD_TEXT), vs->wszPinContext ); + SetWindowTextW(GetDlgItem(hWnd, IDC_PURPOSE_TEXT), vs->wszPinContext); + } + switch (role) { + case ROLE_ADMIN: + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Please enter your PIN to unblock the user PIN on the PINPAD."); + break; + case ROLE_USER: + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Please enter your digital signature PIN on the PINPAD."); + break; + default: + break; + } CenterWindow(hWnd, vs->hwndParent); /* load the information icon */ @@ -2400,8 +2415,29 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); } /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)lParam)[9] = (LONG_PTR) hWnd; - ((LONG_PTR*)lParam)[8] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (PVOID) lParam, 0, NULL); + ((LONG_PTR*)lParam)[10] = (LONG_PTR) hWnd; + ((LONG_PTR*)lParam)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (PVOID) lParam, 0, NULL); + } + return TRUE; + case WM_COMMAND: + { + /* This *must* be IDCANCEL, because we don't have any other command */ + if (LOWORD(wParam) != IDCANCEL) + return FALSE; + + /* cancel request */ + LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; + VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + sc_cancel(vs->ctx); + /* Some readers don't support SCardCancel, though they're + * reporting SCARD_S_SUCCESS. We force closing of the dialog so + * that at least the application can continue. */ + if (((LONG_PTR*)param)[10] != 0) { + EndDialog((HWND) ((LONG_PTR*)param)[10], SC_ERROR_KEYPAD_CANCELLED); + } + } } return TRUE; case WM_DESTROY: @@ -2409,7 +2445,7 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L /* clean resources used */ LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); if (param) { - HANDLE hThread = (HANDLE)((LONG_PTR*)param)[8]; + HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; CloseHandle(hThread); } } @@ -2424,9 +2460,9 @@ static int md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj, const u8 *pin1, size_t pin1len, - const u8 *pin2, size_t *pin2len, BOOL displayUI) + const u8 *pin2, size_t *pin2len, BOOL displayUI, DWORD role) { - LONG_PTR parameter[10]; + LONG_PTR parameter[11]; INT_PTR result = 0; int rv = 0; VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); @@ -2439,8 +2475,9 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p parameter[5] = (LONG_PTR)pin2; parameter[6] = (LONG_PTR)pin2len; parameter[7] = (LONG_PTR)pCardData; - parameter[8] = 0; /* place holder for thread handle */ - parameter[9] = 0; /* place holder for window handle */ + parameter[8] = (LONG_PTR)role; + parameter[9] = 0; /* place holder for thread handle */ + parameter[10] = 0; /* place holder for window handle */ /* launch the function to perform in the same thread context */ if (!displayUI) { rv = md_dialog_perform_pin_operation_thread(parameter); @@ -4845,7 +4882,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (ppbSessionPin) *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE); if (ppbSessionPin) *pcbSessionPin = SC_MAX_PIN_SIZE; r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_GET_SESSION_PIN, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, - ppbSessionPin && *ppbSessionPin ? *ppbSessionPin : NULL, pcbSessionPin, DisplayPinpadUI); + ppbSessionPin && *ppbSessionPin ? *ppbSessionPin : NULL, pcbSessionPin, DisplayPinpadUI, PinId); if (r) { if (ppbSessionPin) { pCardData->pfnCspFree(*ppbSessionPin); @@ -4868,7 +4905,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (pcbSessionPin) *pcbSessionPin = 0; if (ppbSessionPin) *ppbSessionPin = NULL; logprintf(pCardData, 2, "standard pin verification"); - r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_VERIFY, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, NULL, NULL, DisplayPinpadUI); + r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_VERIFY, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, NULL, NULL, DisplayPinpadUI, PinId); } /* restore the pin type */ @@ -4995,7 +5032,7 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, (*pcAttemptsRemaining) = (DWORD) -1; rv = md_dialog_perform_pin_operation(pCardData, (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? SC_PIN_CMD_UNBLOCK:SC_PIN_CMD_CHANGE), - vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, &cbTargetData, DisplayPinpadUI); + vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, &cbTargetData, DisplayPinpadUI, dwTargetPinId); if (rv) { logprintf(pCardData, 2, "Failed to %s %s PIN: '%s' (%i)\n", diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index 4ff841cc4d..bcb5c7890e 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -4,6 +4,7 @@ /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ #define IDD_PINPAD 101 #define IDI_LOGO 102 +#define IDC_PURPOSE_TEXT 1002 #define IDC_PINPAD_TEXT 1001 #define IDC_PINPAD_ICON 1000 @@ -43,14 +44,16 @@ BEGIN END END -IDD_PINPAD DIALOGEX 0, 0, 309, 71 +IDD_PINPAD DIALOGEX 0, 0, 309, 89 STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION CAPTION "PIN Entry Required" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LTEXT "Please enter PIN on PINPAD",IDC_STATIC,46,9,256,31 + LTEXT "OpenSC Smart Card Provider",IDC_PURPOSE_TEXT,46,9,256,10 + LTEXT "Please enter your PIN on the PINPAD",IDC_PINPAD_TEXT,46,19,256,19 ICON "",IDC_PINPAD_ICON,6,11,20,20 LTEXT "This window will be closed automatically after the PIN has been submitted on the PINPAD or if the PINPAD timeout occurs (in general 30 seconds).",IDC_STATIC,7,46,298,19 + PUSHBUTTON "Cancel",IDCANCEL,250,67,50,14 END #ifndef __MINGW32__ From d6e1d2ae8e7d1c34f886fc7af1a0813648a85c97 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Jan 2017 14:05:49 +0100 Subject: [PATCH 0017/4321] md: Implemented German locale for PINPAD-dialog --- src/minidriver/minidriver.c | 38 +++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index f0c247b8b2..b1508ead08 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -113,6 +113,7 @@ HINSTANCE g_inst; /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ #define IDD_PINPAD 101 #define IDI_LOGO 102 +#define IDC_EXPLANATION_TEXT 1003 #define IDC_PURPOSE_TEXT 1002 #define IDC_PINPAD_TEXT 1001 #define IDC_PINPAD_ICON 1000 @@ -2380,6 +2381,8 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L { case WM_INITDIALOG: { + LANGID lang = GetUserDefaultUILanguage(); + struct sc_pkcs15_card *p15card = (struct sc_pkcs15_card *) (((LONG_PTR*)lParam)[1]); DWORD role = (DWORD) (((LONG_PTR*)lParam)[8]); HICON hIcon = NULL; PCARD_DATA pCardData = (PCARD_DATA) (((LONG_PTR*)lParam)[7]); @@ -2387,17 +2390,44 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L /* store parameter like pCardData for further use if needed */ SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); /* change the text shown on the screen */ + if (p15card->tokeninfo->preferred_language) { + /* choose the token's preferred language over the system's language */ + if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) + lang = LANG_GERMAN|SUBLANG_GERMAN; + } + if (vs->wszPinContext ) { SetWindowTextW(GetDlgItem(hWnd, IDC_PURPOSE_TEXT), vs->wszPinContext); } + if (lang & LANG_GERMAN) { + SetWindowText(hWnd, + "PIN-Eingabe notwendig"); + SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), + "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); + SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), + "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); + SetWindowText(GetDlgItem(hWnd, IDCANCEL), + "Abbrechen"); + } + switch (role) { case ROLE_ADMIN: - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your PIN to unblock the user PIN on the PINPAD."); + if (lang & LANG_GERMAN) { + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."); + } else { + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Please enter your PIN to unblock the user PIN on the PINPAD."); + } break; case ROLE_USER: - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your digital signature PIN on the PINPAD."); + if (lang & LANG_GERMAN) { + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Bitte geben Sie Ihre Signatur-PIN auf dem PINPAD ein."); + } else { + SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), + "Please enter your digital signature PIN on the PINPAD."); + } break; default: break; From c57c9c36bf40c9dd6fee645e83fdc044f54051a4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Feb 2017 13:44:07 +0100 Subject: [PATCH 0018/4321] md: added themable PIN-pad dialog - themable in the sense of using OS native design - user messages on PIN pad dialog are identical to Base CSP, which still displays the dialog for PIN entry if no PIN pad is available - adds progress bar to dialog - Uses Smartcard icon extracted from DDORes.dll - requires windows vista/windows server 2008 or above --- src/minidriver/Makefile.mak | 2 +- src/minidriver/minidriver.c | 255 ++++++++---------- src/minidriver/opensc-minidriver.dll.manifest | 15 ++ src/minidriver/versioninfo-minidriver.rc.in | 24 +- win32/DDORes.dll_14_2302.ico | Bin 0 -> 55077 bytes win32/Make.rules.mak | 8 +- 6 files changed, 136 insertions(+), 168 deletions(-) create mode 100644 src/minidriver/opensc-minidriver.dll.manifest create mode 100644 win32/DDORes.dll_14_2302.ico diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index 5ce80ef533..da4c66f12d 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -14,5 +14,5 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index b1508ead08..fad646bf99 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -30,11 +30,14 @@ #pragma managed(push, off) #endif + #include #include #include #include +#include +#include "cardmod.h" #include "common/compat_strlcpy.h" #include "libopensc/asn1.h" @@ -111,12 +114,7 @@ HINSTANCE g_inst; #endif /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ -#define IDD_PINPAD 101 -#define IDI_LOGO 102 -#define IDC_EXPLANATION_TEXT 1003 -#define IDC_PURPOSE_TEXT 1002 -#define IDC_PINPAD_TEXT 1001 -#define IDC_PINPAD_ICON 1000 +#define IDI_SMARTCARD 102 /* magic to determine previous pinpad authentication */ #define MAGIC_SESSION_PIN "opensc-minidriver" @@ -2304,39 +2302,6 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi return SCARD_S_SUCCESS; } -static VOID CenterWindow(HWND hwndWindow, HWND hwndParent) -{ - RECT rectWindow, rectParent; - int nWidth,nHeight, nScreenWidth, nScreenHeight; - int nX, nY; - GetWindowRect(hwndWindow, &rectWindow); - - nWidth = rectWindow.right - rectWindow.left; - nHeight = rectWindow.bottom - rectWindow.top; - - nScreenWidth = GetSystemMetrics(SM_CXSCREEN); - nScreenHeight = GetSystemMetrics(SM_CYSCREEN); - - // make the window relative to its parent - if (hwndParent != NULL) { - GetWindowRect(hwndParent, &rectParent); - nX = ((rectParent.right - rectParent.left) - nWidth) / 2 + rectParent.left; - nY = ((rectParent.bottom - rectParent.top) - nHeight) / 2 + rectParent.top; - } - else { - nX = (nScreenWidth - nWidth) /2; - nY = (nScreenHeight - nHeight) /2; - } - // make sure that the dialog box never moves outside of the screen - if (nX < 0) nX = 0; - if (nY < 0) nY = 0; - if (nX + nWidth > nScreenWidth) nX = nScreenWidth - nWidth; - if (nY + nHeight > nScreenHeight) nY = nScreenHeight - nHeight; - - MoveWindow(hwndWindow, nX, nY, nWidth, nHeight, TRUE); -} - - static DWORD WINAPI md_dialog_perform_pin_operation_thread(PVOID lpParameter) { @@ -2374,114 +2339,57 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) return (DWORD) rv; } -static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { - UNREFERENCED_PARAMETER(wParam); - switch (message) - { - case WM_INITDIALOG: - { - LANGID lang = GetUserDefaultUILanguage(); - struct sc_pkcs15_card *p15card = (struct sc_pkcs15_card *) (((LONG_PTR*)lParam)[1]); - DWORD role = (DWORD) (((LONG_PTR*)lParam)[8]); - HICON hIcon = NULL; - PCARD_DATA pCardData = (PCARD_DATA) (((LONG_PTR*)lParam)[7]); - VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - /* store parameter like pCardData for further use if needed */ - SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); - /* change the text shown on the screen */ - if (p15card->tokeninfo->preferred_language) { - /* choose the token's preferred language over the system's language */ - if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) - lang = LANG_GERMAN|SUBLANG_GERMAN; - } - - if (vs->wszPinContext ) { - SetWindowTextW(GetDlgItem(hWnd, IDC_PURPOSE_TEXT), vs->wszPinContext); - } - if (lang & LANG_GERMAN) { - SetWindowText(hWnd, - "PIN-Eingabe notwendig"); - SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), - "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); - SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), - "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); - SetWindowText(GetDlgItem(hWnd, IDCANCEL), - "Abbrechen"); - } - - switch (role) { - case ROLE_ADMIN: - if (lang & LANG_GERMAN) { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."); - } else { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your PIN to unblock the user PIN on the PINPAD."); - } - break; - case ROLE_USER: - if (lang & LANG_GERMAN) { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Bitte geben Sie Ihre Signatur-PIN auf dem PINPAD ein."); - } else { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your digital signature PIN on the PINPAD."); - } - break; - default: - break; - - } - CenterWindow(hWnd, vs->hwndParent); - /* load the information icon */ - hIcon = (HICON) LoadImage(0, IDI_INFORMATION, IMAGE_ICON, 0, 0, LR_SHARED); - SendMessage(GetDlgItem(hWnd, IDC_PINPAD_ICON),STM_SETIMAGE,IMAGE_ICON, (LPARAM) hIcon); - /* change the icon */ - hIcon = LoadIcon(g_inst, MAKEINTRESOURCE(IDI_LOGO)); - if (hIcon) + UNREFERENCED_PARAMETER(lParam); + switch (message) { + case TDN_CREATED: { - SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIcon); - SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + /* remove the icon from the window title */ + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + /* store parameter like pCardData for further use if needed */ + SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); } - /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)lParam)[10] = (LONG_PTR) hWnd; - ((LONG_PTR*)lParam)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (PVOID) lParam, 0, NULL); - } - return TRUE; - case WM_COMMAND: - { - /* This *must* be IDCANCEL, because we don't have any other command */ - if (LOWORD(wParam) != IDCANCEL) - return FALSE; - - /* cancel request */ - LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; - VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - sc_cancel(vs->ctx); - /* Some readers don't support SCardCancel, though they're - * reporting SCARD_S_SUCCESS. We force closing of the dialog so - * that at least the application can continue. */ - if (((LONG_PTR*)param)[10] != 0) { - EndDialog((HWND) ((LONG_PTR*)param)[10], SC_ERROR_KEYPAD_CANCELLED); + case TDN_TIMER: + // progress bar 30 seconds. + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam / 300 , 0L); + /* continue the tickcount */ + return S_OK; + case TDN_BUTTON_CLICKED: + { + /* We ignore anything else than the Cancel button */ + if (LOWORD(wParam) != IDCANCEL) + return S_FALSE; + + LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; + VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + sc_cancel(vs->ctx); } } - } - return TRUE; - case WM_DESTROY: - { - /* clean resources used */ - LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; - CloseHandle(hThread); + /* Some readers don't support SCardCancel, though they're + * reporting SCARD_S_SUCCESS. We force closing of the dialog so + * that at least the application can continue. */ + return S_OK; + case TDN_DESTROYED: + { + /* clean resources used */ + LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; + CloseHandle(hThread); + } } - } - break; + break; } - return FALSE; + + /* don't close the Task Dialog */ + return S_FALSE; } @@ -2494,8 +2402,12 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p { LONG_PTR parameter[11]; INT_PTR result = 0; + HWND hWndDlg = 0; + TASKDIALOGCONFIG tc = {0}; int rv = 0; VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + LANGID lang = GetUserDefaultUILanguage(); + /* stack the parameters */ parameter[0] = (LONG_PTR)operation; parameter[1] = (LONG_PTR)p15card; @@ -2508,16 +2420,77 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p parameter[8] = (LONG_PTR)role; parameter[9] = 0; /* place holder for thread handle */ parameter[10] = 0; /* place holder for window handle */ + /* launch the function to perform in the same thread context */ if (!displayUI) { rv = md_dialog_perform_pin_operation_thread(parameter); SecureZeroMemory(parameter, sizeof(parameter)); return rv; } + /* launch the UI in the same thread context than the parent and the function to perform in another thread context this is the only way to display a modal dialog attached to a parent (hwndParent != 0) */ - result = DialogBoxParam(g_inst, MAKEINTRESOURCE(IDD_PINPAD), pv->hwndParent, md_dialog_proc, (LPARAM) parameter); + tc.hwndParent = pv->hwndParent; + tc.hInstance = g_inst; + tc.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER | TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_USE_HICON_FOOTER; + tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; + + if (p15card->tokeninfo->preferred_language) { + /* choose the token's preferred language over the system's language */ + if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) + lang = LANG_GERMAN|SUBLANG_GERMAN; + } + + if (lang & LANG_GERMAN) { + tc.pszWindowTitle = L"Windows-Sicherheit"; + tc.pszMainInstruction = L"OpenSC Smartcard-Anbieter"; + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein."; + break; + } + tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; + tc.pszExpandedControlText = L"Weitere Informationen"; + tc.pszCollapsedControlText = L"Weitere Informationen"; + } else { + tc.pszWindowTitle = L"Windows Security"; + tc.pszMainInstruction = L"OpenSC Smart Card Provider"; + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Please enter your digital signature PIN on the PINPAD."; + break; + } + tc.pszExpandedInformation = L"This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)."; + tc.pszExpandedControlText = L"Click here for more information"; + tc.pszCollapsedControlText = L"Click here for more information"; + } + if (pv->wszPinContext ) { + tc.pszMainInstruction = pv->wszPinContext; + } + + tc.pszMainIcon = MAKEINTRESOURCE(IDI_SMARTCARD); + tc.cButtons = 0; + tc.pButtons = NULL; + tc.cRadioButtons = 0; + tc.pRadioButtons = NULL; + tc.pfCallback = md_dialog_proc; + tc.lpCallbackData = (LONG_PTR)parameter; + tc.cbSize = sizeof(tc); + + result = TaskDialogIndirect(&tc, NULL, NULL, NULL); + SecureZeroMemory(parameter, sizeof(parameter)); + return (int) result; } diff --git a/src/minidriver/opensc-minidriver.dll.manifest b/src/minidriver/opensc-minidriver.dll.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/minidriver/opensc-minidriver.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index bcb5c7890e..f99d2b9200 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -2,11 +2,7 @@ #define IDC_STATIC -1 /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ -#define IDD_PINPAD 101 -#define IDI_LOGO 102 -#define IDC_PURPOSE_TEXT 1002 -#define IDC_PINPAD_TEXT 1001 -#define IDC_PINPAD_ICON 1000 +#define IDI_SMARTCARD 102 VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -44,20 +40,4 @@ BEGIN END END -IDD_PINPAD DIALOGEX 0, 0, 309, 89 -STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION -CAPTION "PIN Entry Required" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - LTEXT "OpenSC Smart Card Provider",IDC_PURPOSE_TEXT,46,9,256,10 - LTEXT "Please enter your PIN on the PINPAD",IDC_PINPAD_TEXT,46,19,256,19 - ICON "",IDC_PINPAD_ICON,6,11,20,20 - LTEXT "This window will be closed automatically after the PIN has been submitted on the PINPAD or if the PINPAD timeout occurs (in general 30 seconds).",IDC_STATIC,7,46,298,19 - PUSHBUTTON "Cancel",IDCANCEL,250,67,50,14 -END - -#ifndef __MINGW32__ -IDI_LOGO ICON "..\\..\\win32\\OpenSC.ico" -#else -IDI_LOGO ICON "../../win32/OpenSC.ico" -#endif +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" diff --git a/win32/DDORes.dll_14_2302.ico b/win32/DDORes.dll_14_2302.ico new file mode 100644 index 0000000000000000000000000000000000000000..4b4af23071213359c25e0bfe4f67039eb79fb39d GIT binary patch literal 55077 zcmeEt1zc85x9_GNx}-t68>PELknRpCK^g?4l~SaXP(eaUq(!GA8?gzxz z_dVae-?`sC_nvd^?;V&ud)EAC&6>4muUTt0000bt4sdW_fh9a(4FP~5001Z`uIfv$ z03d=00EC1;>o5R7hXMdtSXXrhu#SNSfc*imKN9dB0|0o?q5Xf>kpN(V1ls?q-Ujjy zrh)dqs#_xffD$t}AedkP3c$q_07^k#SNte|_p|`O_~M!$SO@#{m0k0r078)gz_aa| z9|d3y5Ax{;00xjB$ObUEqPp1nfB&ljyn?r2_6O?g>%oSL%U|H) z0(u8#@CQnQUj9Ezp^^UoU`C;#7Z;)bh8`Lkd2x6V@)tT16nyws{3R7ij{Kd^Pi!Qp z$=~>Z)I$&oGXH(tD-Iy=Fw`URF!WlU&`7X%PfO7i% z#3O-xLB=7Gb%*8U<#pfySMnf1!659AugWVFOn>k>1i2oDR)v9ZF#W~{golQO@s)dp zd4&Fw2jl}4CM>kdvkZ#=6CY6QGWYT@FrD~C9$e}Tln0bPG%U2ds=TZmI_|YR;Hcnq z!ot8Y!UVnie(DYBQnes1w7iVBEG*3L_xXaV2@CV`3VZrzIiV^8Q&<={z;FDasssmz zHid@$K?iBzxQC&Kb&+8gp%;-?&ljrCOZ7%VdxU^G{6l^y9;AW~0My~(PdbPPQ)s9M zxEe0g^}L|`!C^12V0k?+DEXQQ>N_;V|4Ki<$d|-W$Dgb1^7&p#@8NMx1lyqcyhMil zMugHqQ9}QO{K+UZ)cxn(f6L-ZjhD6vy#3co#H)Ura6fI@Re1 zvR?nQ1j(26|4JovUQl`bu1a#Ke*6K%OFj9+Ks5&d_0R$=FN=SnWB~b7fLRR8(Eal= zfqUjZPX1Q{f%^)02WIdGN&+wcdHW1fC{&i~galf|t2Y=*f!6-8%vZIGYs+=nb{OJ* zWw9=6ks+WdytEidms^9E7ieQI@lg93>Lm!;#IVaZ9tmnC%gf8kyh5+=pj|#J7ld}W zY6q(apfM}23JZnG1KK_CwJtBO^76XEgK|NQUA$nqAJnp3+NV$t5dO0rY6mXLL&CgD zF6VRE9vN9)&g*e0?-l;aIzcVmm0g7zAkgwb>sMw9YDz9`&LtkKc>LV%kU*0U+7l4@ zGhG|3>-v9id9^+q)d*~AKDhmq*7ZB3n;X#!%zX%1FVOd$oPyC_#)2b`_ z#R0hfLd&n{2N$8`?$Ct`@&x@8aPeHxq1roy$_Ax_HA;?22cPjFjIi}`Z@c9_y0KggAWyK z0Uz#V0baq|f9W}U{7in}YYu(&LBGJmJtXwN@4~CB%A@?iFA@rHKZv{l-|;H2e&JD7 zR^<+sAt50i9w6QCpxmnrd?5}&9JJqMItX!hcL($J>HvkkN>?`jy7uoculqsu1br7w zzzmIhE)y7w{7TSw7wbjK1vy&YjbM`QRpC3ug0?1K`2f0pK)#06d&H z1bikBf%y1%;7vjTkdYV%WF)-?^3q=c5%2SX><=G+kGWYu#iw+jxUc}otf&P_OG|*d zsuG~8vJ$AT&Idl%7XxigpTM#bXm73pzO>f>(N!%#O#2X!)ingv4vhjYzpnxxM&^Og znIquE+!644;Rr}xJO-+!egNsq$3V`HW1xKX7-(#41ln7gfbPyl;7jKhps%|H7#!#X zh6V?LZ$rJn*!KaTZ*&3}8yf?r#)pCVnQ@?Xd={8k*#O#qYy<7vr@-juJ}|I*28`~X z0kd;+z|z7r@MCEn__4eUto>L5HdcQCD=VwO+S)3x36`7dYry8_I=KdjYcyI{poSp-RheyEi@hNb6 zatfTBUjXOl=f581-#342;9t=I)JFfE{%dQ1ibY&b?B6LO6&|i7DKa+=3emqJ`)t>i@M=~c{atjs0<%Ac8;SzK05&l==wr4RmSn9DHJ5>rT9sZ)zu zncMssFD51>rv_@`60EPUuOTBuOH6aez=qw%#@LDil;=-)5j726s0h%xX_%`EQIN3l zDY7dYE8k_itE8+%4C?1k^A*$3)z#HA2W7C*wGt)gR75aV7DVOZ;pTw|2;RL*Y;JD- zS3KAQL~EGqYmg`@^TQKjW5A>1adAWVFY#99QoqmllE1E=hMt~=xhT6J0U|sS3MK+N z0T&m9o1KjVl*jxp{55nhe>C(o=-CM|(BUz#un{oOU}51Pw*>@=&Gr5)zX%kp21*1b zdUk9=TzEuy7#LUtd@gPta1z9N=H@cL%Oe6#7sRVU6FvJ4SXfvDbbJB=d@M{%Yd^-ugQK^`JJEG#^H zFySJAW8EMIRrgo^);3@=my?sDy(K6hz|X@)hyV)@0}q1*_9E8P`wL#*@)8g20^$YP zArM#uSadw_Az)&lU=V}kzwp0?+t>(+-s0e76X4;3;9z4Q!($Ti^N{=-y#8-^RU2dF zTS|8Y*>Cgk@S_Ucy?a{-T+e^vFRc3;Ud6`7=$5jQ5~m=z);N`wIY~5ZEdPT4jlZZ2 zIE!1*tgNiSNkdK|qyb&#f99|E2Y*$15G!r0c#D>Vf>u}pe2c+kZuMt8XkdONAqsH) zQwT|@{lNo#f&YyEjlYeJm8#XR&Q~|)dg_0&S1iBH_b*UA4OJ--1~Ss$mm9$HC;mTq zf5*sTun++gb~W~-y*MiUgPytrNmemsQwqoD?GEFuBt3J_&-Pf zluV2fD(7Ft{JZ}DMgv!2*uQ?h2JQd%`Q*Q@KWLmv0cJ5U|B6%L!OC^|Yn=Kf7jS+3 z?oaWmc4;?YP&@Qn%(?^c{ft>}4P5}jBNvykt7QKkAU}3~8Mj)s&s@f;_eZZ{RFj!= zz<22!coQ22L?t8v3D8(IIRS`F%>Xjf(|`}Tc|cK47En@@{wr23`Im`rpK@fzyY;(;sI*%*H8@ymJcV&Tayk8{0tP z{>kNeYg5x_pslqP=<00x6|463v|q-nU;Dd&p|3r_@bEAgxAtAet)nA@U^xVgj*bEo z6BC#5>(s;;Ff;WXn41~}rl-b%g}I5#c(&vC7#KP~0%oSCfw|ckkUkA8EG&Yt>f|K*~?fKjAOU9wt(H8?aNqoZ|^Ejg~q5yzsIMiXMe}1*X#H1^8Z)^ z|83(`W@Zk_|Jm%Bnc2iu%*?cj{{euNl~r8P)Xc`p%tq<2?HnA;qH+diHa2EvW>#iq zD!;dbanCJTJu@3lB+fg8} zh{)WGW_PdUgSLaon1K)n1_FVgVBR1kBw#dC{MBxG1)#w~!nuKofq?-6@EMGMYqzm6 zFi_E>;Uyxx0R^B!Aczd6a=-dpS%Qw8fgX(@FA*LhI06g?1~!B7AMHQgJ|?c)a99M0 zH=t6YG1&alKl4w=lu1*AlaB|H@CMipt7P>@yUi7VNmG+ckPnLh7akUl!rJJIot~bIgh34IXIfhs|B?^d4n@caDS=P#GU;l`iCues%r+nZin(ghR+40AVWuP} zzg`~Dc4(9CT{%e(7G^5)KbkHfw)Y6~ezJfF%_bH7CEUtelY0A9QMJ>RbGhva&oJ zBy^0oDSzT=Z*hY(SxQ1UGz>&0Rso`)bQ)PHSxH%P2r?`(I_wQB1|pFw{?w8pB9f9g z*yu3u2(Sp4Oho)wbQ(z^ArTQA6a)lhWMp(~>|b<65q=>N9OfI?=*XxD2oNIPpLj(@ zMM-`f76v$2SQsQ^^gr;5igJoL^o)czuwjvrQ7J|Lz$+@^$lal5#v(+7qg4Dwm%AgU z$U#C$!oej8^1P-~L)pkd35tr+qP*->H?R3XiPDlhAccU4i0E2r)RO$SsK{>qM!9OC zAtU>RxyJqnme4iyr~H5Q`}xoB!au(QUrytuQV+;ZU5iTw= zyb^TWd zqRVy&DJs|nWC^*dV<27u5HY|y2`LHmP#>B=8~&^3_02z1%k|&U{4?BN+pqgQRZ)^f zMo^9&)Z{ateURD4f8J;=gysHsxH*F^)mf#>UFQiwtZSB zkG4Q@;D+?G8|+B9cT@lvG>#_?H-!gWlzUv=-89_{UvI3Dd)5ejsI1Jg;t*TpHOtJo zZCv}MBYtx7%t#^_jp(*{TNI__fAO0_RZ1o4tWZAgQ2a<3_~9#C5QY>6)9GMh6{v#yz8D zibd&?xkskWkqAFQg^Q-WG3)RJ)Ez1fJXADM{@b@6Zrw{hmok0efi?Q@J@*?vc{7Tb z`$*gTsGVGlb1wZ@uo*P{s(cYo*5uNui%3IkGCEFAVcqR}iuvl=`ulIhItM+fF>1j> zE4ZPDu~B=NLC`(EIGIe@6f7eFoDMGft~p%nCSQ!yxtMRT1)rRZ(ZN0#&D3&GvEyRU z&e5=SV=56)6F@S3pJ?%->~3tQuIs#W$8E**S&9slz{k|2H)YjwhIGq0d-5s-WANj3 zm}1|@Fl)relS&ZGaHX2?x%oLL1f!9_A;WBz`K|e#O)Or_EG7$8y9lbu7sNV}pag7+ zdKH3l*C=IZrBxePRA^-x2_k|XY- zD{~mPH1&;c4x-9Xdn%uOH$x2u)Z*584Qiq%_$;d*Ms6qvqmf(dY@t_3_)4M=zLl7^OZs`W|{pT~582vU_@k#CY#HfhCWV;G$ne8vj*bsPj*gnonuBJ}gMyl^%1kVJ+!W5E?nAnOmSk$svcE*Z(CMlk?n=^Kzkr1=80;KO)y9AfTu%4j= zsiDjt<3?LP5f(<<+owzKQnS#FiHm1s*Ur|+nb}u+-R%4tI-nJFSP`r2eD8>feESUl z+H6pLKG8PqDo2bIo{;uEHcQ8VCiNTspT;Ct}ZW^tI*g-ki;7{Yg3CO5^kc4C(HY$StCQbOGG%r)%t;4sYJFN=MH!Rqhw?JjCFe(^xTrJ;{ z1@bqPO+GRo0J%k9669XB0r#8o2Hf!FL{D|JU{kW9va)jOGoz>5_Q5yDa|B(8ja9o@ z&EoaS4k`n}k%7|u-Iw{*%MdD51Pfw_{2m9FP<<(>esn)_F^=MBwU5{NA-H}$vX>xa z%%+x93c8ja#uVeQOS?;WB>4qcOS_c@whfV-fwK79o|W64Eg>OPYb)V&^Lm;w@wP0n zo$n0tZk6dY#$oUes2wFP>tf&s87L8DK2>{m9w5SgxK!?j9+AE*x3IW=lNmogA{JjE zrW3mX3kiN>W2JtXpl(-UFW*5a7|pg`pcz;XFEx%GpwRP0p4LTma;HizChXed6yWeT zq53vaXa~NTIv-f7vO9m=-kG;}qe#-prAcWOU3@o|Q_0*jmg6newSpXl9Pw$oALBVZw!BKmd4{KX2qUD}6x1l1Q z`tlr=rOD)dL44|Yt<>JV3@x1I?c1?$NNiuRv#Q&2wY|>l(5K_?)QG!phQ~5Eua9;n zd{bALBDrd77i@$L)lP8D?ZxLOmBt`jc-P^~)bxhw$HgNja96Z)*B za?{0OCtmH`(;u>VI89h+yZaoy!(m2*tg-JjbTJ-B&fA1L=gDMfQ9I}{SrNa=oJI+* zmhR>n*9)$-=dmM`6)^Jr#A{_%VepoP4WB;#Sw1G_1vUsMsyXvnq>u=v> zX;QJAc-Q%bIRm$*M)-LIW?H&)F;0W|hwp7OW?Ne`r~R`E3ersTD4qGuQ&}v=vdod) z;7g%rI!|HpVXa^TF)*1vv#Yh`f}+b- zcjK0s)3V2Xa4*qFt*l3J0#8kFF^#0CdttG#gx!@7~vT4(d&ma zY9CA{0%zs$7YQO_o@G#HsJ-4+Yj>xmP|&qUa*ab+lG_Uj7hu9%%ANnw?j9dl=WedN z>>c#7Vl@_fB?W4^qVB~6v~BIlyae~Ia@3NqpPfr&N{kLH9TjM?Ud25Ps>hP3bi47Q z_M9!9lL(iO-{{B3a-HwSOl)iHtg%ViF`Y5-9kqiT3WUa>W!rGct;C?v#Fw%}Z7Hd7 z|LjA31}AaoCaAhy?`Rk7m>}x&sJwukii7y!OPf4Oo4v}i7wS*+YV5zOrN*cPVWIjl3n(5?fFd=$;zHWb9RYmQ? zucl_pC6%F$dxf31==1x$a4LN1>kUI_xK1+|QHb>2R^uBl|`#eGQl0F)exW=>;lL z29IqS2pjE!v36bE`bIU8x~JlmwZSEuH=I43@NVdViUXHaP2Xp9PPyT`QSuDKk5%Lu zH5>?@G@adb7+pn%@FI;o;HruTO)R)Ox1MDWCz$}lLEu9@fFZSlnbC*M_%!kTa<*do zC&Yd#IebI zX1I&F|Iu@WE~ZQ_cNR~GbxfD9_EWiQwHjNofsuXe$6dH+2dK-FSXC`ag702NXQBc7 zNqSVO@k|c!;n((K)$Q6SFFgDD%Ekn{<+Li5lqwZDt{hK%iL{Y)(^0O3()YXx>s~bJ zpG!#}w5qBJ$jfJ>+e-Hij5dFbyTjg{64l>OO55B#6TPjrESI6N^?{uEJn^ZEb!Xel z3>HC|PWk$;RyoD7qU%pf>&WM8R)*GU>T6yHI}!9IN2N2v^v3q|#r9yA-$=6Pv*x+~ zod?|zsTSty8P%Bp&UwJhgbg-Z zYdKx+kxJ|#ARpbMJLiJm@Eq9zKXZ+b%Z_B!uuheWl%&<^E-jv0)gAEZmXcbG@f16|I$nlLyVpe6;E{%=v812Z|9+;;+nCC39>5Q4zCsF12l!OMKpKTQw zkm8|QpvTBTxXihg>Qh`|Li*u+{h0W6?sMD*3ZRp#=q}FqI~A;I=kA9$Z?=zl2OmopjS}HXx~;lO3RqJ(HUzo z8GDFXUtpj9J;)ViDl!aZ-aunXZqv@v4e8Ys_4i8z0~{Ra zPrSR)EF?Fb^;#1c8G~l!($(k~;%vEpC??3HWfLbUfR7_qt#@Fcd2=aBu&Q4{pNE9U zO8M>4SZr8vq$n7DB|}59>Mf(w-IH*yVy43UHSMYxlUARCns~(E&5ik>-0iUdlBicy z`Fg%~Bds<)EE?NlFc8=#t|GL7(f8H;R?_aNQ!U6bxc1u(K7{eMZZ=(X;g;%y#EPH| zb4^e0jh)@3mTe4hWDAH&)crkDw;E|#$xW| z-2iOmPl@$|5zWl&1la=_`lOW~dy(`56~s_jn#6*NQyZd zg<(0=275?VT433u@5wxrWNVtT=#v3ncyLqa#ZR zdraRIrl?UIo3)5Xu`XXn)vJd5)4}mQVPDe^VdXPx3hErwJU-g4S~jQEjEgO-emrOm zhnp!XBqlfATz8H9V{KLXUj#Cng!`Te6D7rx)uO59uD){bjjKo~ z3?7#CT1*pUoQ*PA7n9X@z@xu`&9)H9L0igWMo<^*l&iJZkxesc&X*oTUpjrPRgA}z z1b|wl>CNVh6|-Hd%;&A7W=%F-D^EBXUjH_@q0dPA?f$|2DxMoh)Aq&~-}}%?c4gkp z&W=vO^l$GydYi!O0GU+mG<#(8L%1Rik!&qDL{ks{t&Im|pzYU=UDp(Crt;}t9;Ej> z#jM)WVY~Jn=BZV+?U-20Fh+i7ZbrUG7MASB3-tkThnzaZT@Z)rExOTCyL*ppo@FoJ z=W&?$vilWRQc{w6|AgY6aPCFPUi1QL;HVnkTR!!iHIdt>DWqI7vbKIh^lv8B+JsEf z5fA$!eLpL(*L)6mf_T*9JFiVhOiaVXW~h;)iBGUt;k!n>*j?MCUAt|uut+c>#NYmP zmrK9wfoW$P>w}5v*AgA?h%vdenr8;H&m0v9x9d(^O`N@5&Bg1Hv|bIS`dK%O?G5i^ z21oCQ_#K9LUm%K36`YmSwMwLbG9lAb@W^a$<3?e#k{Wa z2@^g1F?{Ifdr}5NNJ461^XScTHX}I2o8G>Tg%QzpRjcxa-OKgp&$?Ftt%e$@M;spR zCi1*n;g}4|KHiIhlha)<={?Vn7KOt}hhEFNg`yCQ?;aqmXQhDu-`hgBEVK4u&BdYcgvX9ysof}kIcBYjN5Ocg*AK|2HSaZhe|9eT zM$&}9xi%I6vv17WnonB6eVr#b{$WR94`SFMP_{8PZEJiXV0=15AV^aOn?BUd%(-RE zn@_V>S@pm$Pmjh*k&{cPvA2!zh<4c~|0kaT|dhRW^=;-g`fmqyNJ#2d|^8Xv;? z`1pLHs(V%r%m*L=oe*FC1NEy%qdNqVucD9 zFLZ(Qu|Qlc_ZUjKl_?(?Z-3{CFF6IZ9g89d{4eI*xxFffltEtzRmnmPhLOb4ad==q zf&lh_4B24XnVFe{L{Do!oYv0T_XiZ6k!Ham-$QJtW3CxHe-aYG;vZFs5~L%&7c~@sy|L0j zUlTEGsgNZrZU9m5!-8eG%Pw49ECY> z)tg#d2igtboK6f+&J~65?kxIE4`?uH+K*K?1aW2^J(;ZP4j&B{BYZGfYBy;A+3O9) zUG*(clAtm}=~4%-ZAp4q3TY=ZG?v^5qbdC8-cha=i2~zERf~(R81xu)gg{bXHYP{cfq`gOM!`WnUJ=#zuPpJit=25$_7dld8sFtWi1QkSU~&UA`vFD|x55I7-E`#oR8A@h#uu&Au6 z>}^j%I?TouPjSuLcsc2?@{*8h3wHd5NG~GBVI&*N*L~1|QfCCwL zFj~p&$XHobC0JXwaYq1aY}-VXv^>?C{9Q4NSm2qRRD*!?u{bBvn=ZP{Wm(bnxKp(i zSyUt{Lpw6cy06Du+%=O*_x&v79?;e#WcAn|6twn<@Tx|@YEn7U2L?1sAfY~oZQKle z(x*7_!*pOl_`w^I#y%Xn9?G`u2J%RB;4Z0}d zAM(v@liss~7!uu-KbiW8qv`Fac7^jii}6JtsgaEU8_u?n ziBZ=n8L2Q{I8VRvMTU-c4bjO??Dy{nFH&$Gm23_tIw+o(FJL~6=bC+r;vYAsymfZZ zT&V@|RJ-avEQRG$se9( zyM*zOe05<~1}3n1dxnUuD{-#OZ-tkTP_$82bQ}BO#zc)?ci9*_7LDZOb4PjAvo^vaz#LcW!$+!+s{6`; z!1(TWi!!Tae|6~*izv;FEV)QzH9^sGUgH~kaBhzkUNlntIH;KG4|+1G3}?Zs@({W2 zmE?RrC5k@3<1YPCRoz2>f{W#iLWAth-2vr-N9IG!q~(3RA`prh5`ihJZBOf?v$I7= zIu<2&D>?6x+jdBxR)_fabpxO^|A_%4>$#d@TiElhk|RO4=WgS2+PJQJ_-1bH6|6zPfI|^@Ll@ ziIYEn&u2S?Sm4eR|lmd;z;KB&zJjQCC zB`xuTt!ZfDC|kgLOKd)dtmhvLKSyzI2d$kB8lNE;9fn-QwRgP~a^1C_S;7}`c+x!( zK;ooYSQ;c|H*tu^qkjv-anhniSn3&jxZ>0Xvmn>-J-sp7JoJ7it20W~k9V4=v&Rh{ zw%;dERT9P`_9bVcC}R_Q&?D{m$;ERE# z_~fa{(}vEQLXQ3hZ1J}-bOju1dbb`^thaW*ItoxkgwT1bpR8IFf1|g-Nq6{oLi~Ml zXg3tK4bty4DYk|ZNhi-U#uF%|jlH&xN|by$?QVQhMLbUPoW1<9!hJUB&!l(Y@zP*g z<$erYuqZIlMmxhdZNiJ$;m_k@Q$^lJ@n0T7CG=eri$CCvyy1yu)DX=fJ`@$MPe|4J z?ejyW)r9F4;|s|o&jqWoWJk<_fa&6jEgFf%AhAl0P#o_PkK`7Z^atd@k!~=t1*x+Rpz`~VM3Pxyp%6Ac}6MNY;Wp}&5( zQ*A2^a669O@9ZxX%1f3d@+^}P!&R{?V21y~7Q+IE!Yta%?)~V6=+Vpgqg5+Efu+hc zR}(!IjxLMPEVw6=Wln`3mh0W;A-VVmulEF|Ng1Qn%)IbLmb*7wHVo@Sd6YKf??;A*jcfD(cJ#t6kmxaorIYrY@$%W0UcK@m z`|++HiCYwGp-Q8~D})|e28u5t>AC){eAN!G{PswUXE~FPTnJ^Xa#YgiIo}!U>7$a^ zkpa1GcQ}UXdk$eXibzs$J4w7X!{gFjD!5sSjdutFRq(5p)qX zCEEq$2Yb8DhUlt{cHvC(jUyR9mw1i!hYrFoo!1m{?Jc}4kL@A9Kz)1voU8OR)mil5 z^Xj#UHwYf$8uNT&U0nivw1r_QH2f}6l7h60>;@(W`Qz)UtjRA+vfyU5YomKVVli|K zo8O%B4cQ-VqS!2{ruJzR%x`hO8F|_7>>!O#}Cup6Qd60n}^pOA}{8{F1Q<4E!T%`TJ;!Ct*Kk_yX@b# z>NbL$Gg!M@U*MAoRK|~29dL-;l6K!vJ(!Nyh{WKaIN>%^b%*kmoO)a`bG0jh_q&NYV)}*plq&9^`?cCZuU-(uYNBHD|*W6 zioV)pJ(l7(MeGmYtUrL%1EicbDGTkYVqKVj`XmYgwgC{YhIq2p7;&_8bs6t}r)GMk5R z^W7}P)Nwh?N&?0%oM%MLx6;|@$<$>&Y|}zw)=7+`M&N@l(Q~pG4(!H8EPe=L6(O;} z=hUWFkA=m%H><>*rXj=mh6`gy3e|3p;$CLuJ8pl)o2nA`Lp(rJcPI}M>*OwkB*CY3 z<{>@kPJP3x60UDg>gNJ;pPed^b~v_|4o13t14l4(en{#(Hk5quQzNy7#z1SkgY^m5 zHsZ;1F*$|+eTEnaf;>aa4I~G%m(z?4%g9ueVhngX2z~sR*`oKFQq!cx2SoGx&~;eV zl&E8!OR8mEM>#j_T9LVH3`A#6982zWGiU9oyRA3TwFgWuln3=SZ<-J^QOoi>@2ZL% z?BG9ic|CK=oo`eHhFiteZpTbnJ*@CP7dw-Whu_80oE=3W{cii-&0=ww9skqV}XbZoJq!rf9~C>DvVXP9}ti4A~ZEQ zdp`Z6M!QDj18(Fq6g7+SyOom}akB@DwWusH(K|z5R~k9I2#J1}n(q?IM*6(!3A=$_Cb4cnJ70Yb#u~HosGwTE>&^7p-sktdCS|J+qTXOx z8^5M^s^3TT2LhSVp2ONVC}1`&-7|lm+}C&Srtm&r@!NeS1jNJg(1r<3UUs z;s%X`jy-F2AG!=?<7#sugpi!n+d7%4yD>=@zVTJ5Fn6~Dhp`nQ=9em^1Y@ORNe08R5;z};Yo&WB~upx7Uk=RHW zgYK3k#zT4E9#XYis1#kT!^7A}a&Im7!8ZgOAGN4a@}>PsGbeDahfs^U@^XShu7ryR zR*wZ4Uwyllq|nI8Un_+1F^W*~W+}B(`obt;m?KT}K4ESPx*V3smSDQfQZGU;^UjMo zhg-1(h>STV?AF=*SX3dmD}_;02~5#V^dz50MsSF1@zIm5%(4@D5|;?Fd@-Esi0!O) z*@rmPs?VH=8cl&2P=Yn_AYLC@qZ`hjG~ek~j@lT(kbg%!9JQy=_WikFSb^vG+qQc> zUg|HH^Am80Si(=m3wtK3WmhY6G6%D|>zgA^+kb?;FF`ANix<>9U>9 z17k2g2_nj3IJm5t+wvu7UvR$sz-fHTanF@H*Eet^q%ina9(GHs%&S-4&u}95wmM}3 z9_``plo_NtK3w1t717MBW~sPswb>|oF0$!!{AlVhl@f#OTgQ-{7ZLFVG765ML0N_q zx@J{quA$VBm1;Q2I+~~#%zOroG)Eo9`o+oI21nO$;{j$H`2z+1x3VUwK9S)cMuU6h zaiMa z8K(+Wo)7OHQ$Qz_0cUiOF@H!J)&JISGO@|8HRT>5Qs1l|@(@MiO^LadLg(2B#N<}a zHuU7a&i-}gxbI^NoKF_e;@OR-zXS2|_ZM~v>+$ACe8R;c9KTQ>cJhT_nu>Q2( z?J&-hk9)E7l0z+L^4V!+7{x$)@~hSYR>rtjlLf=8UYY^N@Z_?o@87LfY}OLuH!g|4 zdV*w27)=6edy`qT;p>7T_$jt$mV8Y%6n3!R!hW){ZFN4U+Qm1CcQSjYYoiC6;R@h5 zZZmkyZ6bwWu9^?bag870yjtMJk}$y#3hHx*1>@TXokuEjf(z}4+~gneXiQ0K7h^qedxfFF5VH&Co&TEr?&tfOZ%861 z+z7k$N3x7x@8(sh1iE}Lxg*H@Wel~QJo(1W;nSiYwV!85pJ{B<+Z@$wDB;X&sCJD` zA=W-mB#_+vuxTXU`6sT`eS;b8`q-m&i8teY*bi6>771ig2Z zH>R>^#G^Rz3eJ{j_iuVX3n)^4*%|pHx9V|gtkTiH0 zmb#2|UNBjMWB_mC{ADJZI^kQLJAFdgs)fn!0AYox!+2eSJ<~_0aW~UdX@{1%kAk}L zBT}e=<`4YM=CrLxrm#&U+x+wcef`$9rBeJ^n;VcB0S-+-=lNHfe z?Z>%QVXwJ1JPrmw-$FrhsrLzsVwf1+wq!PnHa!ujQk z(fr%uokZ`lj^SFD*aDwLrp?>HKmv-8xA_YnFZW{4N0?{S$&G~&F|Ft>e%{&M@_9?r zMB11dcqMGp&n?vZv~3F+kX^Ybq4NhpeVL!Ub{b?AQ0v*>07V~MQzQ^jZTN_{#E>nuXwa`!}x50c1j<3knm$+np*!`nLF=G^{QpkW5VFU4V0i3R`WHMpcxV| z$*S{mxG0_nR1~EN4$sc*FX$nVtjUI!*^6UVpDejacfPYLddGN<oXk2jAscDxC@zH44EFvWd z!#qA}gR}#(W1aPVq-c_DGt{)*IoXjCFU+cgoBysOh)qyd&~yauCXt(931y& zZg9p=LMAZsU0Wkar@bz|ABWtxOmg53Y^5d3(pd=)j4;ALNu}sTc&vd!t7)qL zMB3gvkbQ`3c(HP#zFTA2BJERwt4QubyZbf|BC^^<8))kGg!_3E&-%NYoir||sso~T z7ssU|E|R{?D(lu{ksfI$b|h#`-3#{VfXK6^B+|Y&mL}v+?+fQR#@4E%$Aw@IQNYzS zp{)zH)%qav`Oew-u1p%Ev5PA9*+MeB5ChM{Zmi85P?z5$Q9LV_!0M$BR<_`6BX}`R z@2elafy2H4k+Np?7AA$D+*1;J-0RdW6ByV#0~D2Zcs=UpBkyCNst_J7Ce88s)@8x# zP_eVM<|!4`!4$BY_XLmYVtnCnSSWV*Y|OV}{S}4Ippb7~rm^uDb<(V?|ATiL*tDIX zF~DPUqke8w2*ILK_S|AJL6E!wIiUKA?kD@>+p)dau~{lILSX>BxRo1#;&4QZck5)_ zN{RL!tN)L=u6I#Xgsw9-0+ZyEJZ$2<2F=RjdIPd0-VgNAE;j0p4iY`)u=L9|EF5>S z@8(Q)+3_w`Yd*^NLSRRg^J>r^=rKNXf9rgD@Su5u?`ZF}7webvui4dR7TYVMpHRfG z!H+_1#PV~|{gB*mE~!2$-@nnd2y388C2__U-fl8no1r5Ya*aVyk%xSaXG(lQvRJOX zph7`2?k@&}72f%J8`WpOFxi9hy(M1g;n26N_s5azh5@@0)?V|e!lSh_3{ zK|b0Y;B)egt0W;QdX|EvY$nfl&@dy*smlPUaSRD95)9xtW>-FrgpRVAxZQnU} z*Q|0v7eT=~=lGk8P{-aj@~`Lmw_vclkuYJc)$7UnCfn- ztel9{iMrh`L<=2nHE*N9?ZF}{G&hh96hD8}f|>4z^>nx3)P3;S<)ZxOgHd(kLgz}E+sAWC^fk)P*dzIkus4UovX|&B&dyup8TQt8J*)B@8_xL5I*nKJHFFB1lC{iU)6CpeaQ$* z6mfYwJi)dd9-qG%9^ZHXzdAVx9#dqF6kD<5sE05-KSfJ1h)?C2&F@#QTg~qucqKWq zGgX1H&RlV3-2Wp0y}fS#=7k>UQd{oOn!#ul8mE5-P8sW`pNXAUj1@h9_9@0n70XBZ zm1WWoWmCSPTjVCQTXkJ8Op*W8ILiI|*xUgGz@D zL@KqwSgcAmIcgv0bN>x&r24{2Y#CnXBd+x~zWfJ<2bKl#vt;!jWxjFUYRt@z-1)4$ zyB!~N$Mc+OxWIUB^+;DKDQWRbkVUrvA8I1Pxxa+c=GQcwn`3pctojEWd|Qic^Yki8 zBPBO%79~@A%Zb>=X_+ZVicUr%PHSJ2(_f(QpX)>woC%$CZOh(ayD`eGO<{V6CdlIr ze*c4NlP|jg_}HdVbV59tBvDKNE_|(Te|w~lVnyoOU5`42nzXj5`>k|{Om7wjA|~gGt8{6 zx2mgqRae!T^>J7J>-ovhT(t1XQjP@W^+@*U8K=*UmC|Im%{k+2<*lA3*orzsF8w zdk-O*8qFC`-wQ20Kj^dA7-~g+FgiafFk-F*w(rJmBwc;PR{J!&GD$|cI zs$9Cu&8f*Ew{*N`on*%7mX>>02YKMwh0CUv4vQbeC(n{JfAZe3l74_1A4;QD^Y?l#@``u42JdzWaHv#DcW%0<-Ga#m3T$n$g>|iVoLXn|;#N#eaFO z!>Y7*JgD@T`N;j~8S|8dRaezlQN53xpJ>px*|>598?PHWRqE`Uzh#RfH+_F)JDZ8E zb*V^6Eo=9gNvRPXzsJikoaEy>SlbhesTTDe^)?rDm=&Drb{p(J;N6~P$idk7am+P%Fg}cGOJ3Wf(vy*J)(+L z1}sXu)tk~Ba>ox%EM#yy-9B1y6mt}FVT{pG(7Ti)VoK7GH~i^ zr{=Rt+zYbp+O?lwJTTsKuaIHltJ$D;6MUxdIyEqzRCQml)S)-K?6}VH-1Q2!Uem|h zjdog;pLS-XyRJXhCvrG!rBMjOR4{g_eW47yGw#7SYenuLrGW2_vd1njO{$)_=k*aUldTC$X#WpIl>m zSC?Q#;W%NNX0YPys(4H)X}wtJKIf(P%6LJo?xeYDU|YgsxsOFgKQM(l+4_@e(y4>r zf_yJwgQt^v7FO}G%1)vt@AF-^4$FEtz1Fe3Vf|pYuI8>Pvlqou4`{58330i%y&Zb) zhh05LZ6C6>TU#ZoEQ6-iXu;Q5HdlFMD63zB%~Y6@!|V~?N4jafUK$?kmJ^z&;oDuF zj@aWBcq!pK)z#<4Bo??D-;s8!UQXLurCUW>J`WfnX zZALo+f_7QtCMspB4fpi%$kOk2q7DpNQQ-={BpQdk9M{EC4RI?E+>gCd{oxLq5yR+()gS|2jEzM)@hU~RCp3FDu zLtJCWUp}18m7EeI(-tCyyU(=&EBjd(4bgf3!v9t7!5U zGOF#oA{pK@38f_cZl|DEZN4z`-A}eTWyfvC{@N$kis)7L)pZ=3d&*ogW0Tq^tv~%S zykU#$<+*KYr!Q`+Z3!ZXmw2_3(>gkCEk6<%7c&_8=Az7Gr_?hl@=5Ywj|GObeHVPs zSzc~sH|dnU!o45A!^7wJNf`dc6_;@sv}{?E8hSN)%lJ#)FziTP&Z^^JoPtF>4)4 zwJ9=uf9b*}8=VWdCbF)rR84wL6S7wp)vcUDl|uFQlFDebePs- zN$`E=f*rC>$d5U}RMmPtXs#NR?sUucDr=6j!kw~vH+hAVN3Ott`#tNKJu`x4XBj`g zyBGav+uP%Wuiw%x!KynNWka?RM*j(MnJdrxd0S(v^|4il?!TR+lr2@__km1T9s1#&C!Rf>Uu6#FvImiBA6uj|XubhjHt z@7`&u2POFLd_tCK>qW>PwLQDjl@^t(cV8jyIzAbV*Hekp_F7-IuiORQJVnr`M_hij^+Io4_mz!Z8 zzUsB^Z}+L zN9p9>*{ABgG;n!n>=c+QZo}g^t&g+2Y~D5G0Ip~4a8I_oA{^ya8n@!Pm;@tcbX*hZ zcdbyYGd2gZYd~-7b(lPrtFYa9H&_5$Gc5ff`F1`UWXVJaluS05mIb%jw7#qvBa9G;%*U6q= z?QHlC$~CX?VU(|le!{D8D5t*c$9CO$^U_mncXt4DdR7Xy)7e}#bp8^pUHBSWWMNg3 zMr!D={8HulXAh7pEWC&$ze zj#bf=tNYsgESjzB%SVomVlkb457)^rnLRifyV&xe*7b9Ct86FNL#naZF-oygZmR3+ zY?Ks@wv2Ad6Se9?QU|c7S?ymx{IJ`S>B>x6^ZQS!LMH=Q7?_>Xt{*&g)C#}8ve3+J zZp|h7j`je*Wup&SDb4+E=M=04X~51kGLCjG7$q1Zypp@e=x@>Z30Hnh#HlS-Es5lV zo&HM~l{cD9Qxx<9Y0-)X#u9;hK8wuXt%bQxBu!`7)t!P-q%U~SpAXi-91K= zY;kB~5)0L=H=$o|%&~ovW4Jgz-Qt$+Bb$QxZmP{QUwG^o30b23BQpOshO1}WSXzs* zT;1j@PIpbzZ#=ku@tV+pK37XFBcte!n=kFFz4?<~-ne;;e|)lM+N}y(`KEhG3Ey#N zjq%W8DIdc)T}lo?;Gp>#8v3nd;*-WW6A=-m9Cty7-nbU~x+8~59du3K4qHTie_8p3 z>r5v76Bb)-n|5oStntZ7_1;|TDIwj@Pt9ryv~LTnjX10Z&1Uap#P#o9s_h?SRienu zQ?P5Pmv6t_H~8_0emWJ}%_@DqRWYS_u_Z*!o`7>6(o5k4@cIc$uJxvZVi z9-Fo6`OuA;?M+V^F0~LOtzHB?DvsG1-_6h18g+G=>d^FQ%>+^QMH+uD26^f|S7?K2 zP-h|!&s>^c4sZK-IsR+1W&N`B<)i!WhEQW=_9!vXi?)4pq3uh#GW+=T_dFh2Gs393 zrTJ24Z{Czqe*rf91#U*8=o=9$bY)BWXoXI$LDqLTfh$vaRn zGghC>zt;0f-6wZ2(DiSu;ssaf2b)dqo_-icFWRF))p0-V$X)AF4s)Nta%tmf>E3)+ z?3JqgF#3$^oHol|$<5!?dSf(K&##&8e|xZzLQ3WsH+E=J%V39e`QC3A9t%DBmQByg zBTjJTr9Bz#)OQc8q~vJi=gtXSYcoGtA_kHfSSWNfNW=uyo!2pbx6rS5xhgo_y%NK* zJ2idU-?3x7hy|lVf@ys*7WdhoQ1$fu>*pRdxh>-e( zAaf7TkfHL`;oZ=I?8O((QAuIt*KuJ(C1{KGx8&-}(#dz{FJyAsXQ9MYlER$S##niu z%Ss=>+f47E5D_fzW;1ue?F&?np=R3O?Q=s^WPC?(4Rz7vf$4Lh`=)m@SSEC^A8nbu zBzBcX?0GJu4L=`VMrN4T_|5W8fb)U(&qSQa z_G3kPXPh;?L^(~HY;K_MJDToTX>^QwUUYj~O zU+}fa*|Wt>O-!N-?X~*r%UY*Y((};k9RjCRvD@*gJ4JA1XV&Sao;JEUICJ2r$qE6} zk;dk%-AU%OPX3qLU-eaIT8A164Lq{bY(KKrZQ(a_e|02TR=;kDg! zj(HRGV-g3ZO@iF6dOc>`X;MxV@7#Y=<~hbqRwiC~c0Nlb!Fgq$5_&iF<%aaV3xin= zcl7VY?@`vSWFd9>_@a37=`e}etj%g$+b#_ajSI_d8Ym`vsVArI4|$uL_$7@JC_bp< z(Q8u#YFu;d#i?27JAR2Oo1l#}t5^10KUZ;|RB_pDvoaih`C;=HEj> zh2~Oev=w#s3(1fzUy@%_S&1}MgGUVVtMmp_l*xr#30BM`b0JhG_n4z>3O-GeB!9d* zWHC{pRu}YI+K$@7P}j)NdA$L>F8!=9MCbn5nVf)KY-~gQ8l^_7ZKqKcu3K52K1nwk z-=RhbTELCWid5d>@EV!3?7pTYba6J+pIqHYb4g92JF7LpeB|C`B=E;u~~fY*67eBAy>g?2Q#BjK_3m19T_RWmdlFxtJ<+6L{P zy!G8lj^xH}*K=oc_qLl_?x`bb5Nb4~_Qhcu!-S1zX)GP-QLYciJ844Z3r&TENeVl= z3v3>6M)u?Jmh@LrW~3@oU0%fqY_B6J=CIJc5h&M}N5HeSp*eIFI-!fXf3~J-?xXp< z>XRpC_Keb(jE36or)u|B_Iae;Mdys=uE&{Gt0wjONuSj|5G^Rj)zslPqT@Y6gHB7@ zN*~HB!xH>_S+>ldb?9>uc?)MfqwO~Bj_*u%hh^M#O|<1$s4-g4rh8dh#3fMYzb@3m zTQ{qL_5zov`p60URi^Tbg7hn*-P@i`k`<+eoptbwziyqJaM{chUBE*N?|rGB>CUp& zN=i!dLF-z&-(TCu$723*x>5B4VNB%BtU%e^>PH@Z$@`)GCyaYgW)|v7>2W*v%#qqZ z^Acv4)U|7^Ic7___>R;rUUh$)yM(@IHH(0BRVKZe=)M-dy&esc@2qD@$8yGdg#;?e zwD!W^nX*?i>F?@Yom9hd8_slKxVKMr9X-)_ao2~p8h4aJ&n&O+FR&PTCT04eSyG4~ zevPU}^JQo17p=}zie8=SYQ32$MYEOTalCvB;PmN-`UCx{Y!{4n-Fit9P}lsW{uRA^ zn`Po?zT#H5;Ww(3c7Cav=(}hU(|a6-I--$MUqxl+A8AQ`!)c?Z8SfavDprPYqgm^x zBt@zgvV_#E#N;;1Tzu|?bC8o0V zxJs_Rb41L?vL%1i<1B571=-cZ9Ev3EbN8o*X_|uRF9&ZSTh+GSAAxDq$LZPUr5#?( z3zW)Gd916;vy^5SY^LD3{d3CchkHx~>Sd`N=LN3wjB%ONcD;8SSenImkD@7Fn#11( zlU`=;0RA_0dR7>mR?>+Oa zc@5$t#h7_`c?-(Qs7pDF$t`Y16jfExn$K6zj+(7!HAPDKVdqG;@9n5=@uaHg{y<_kJFteyZGog^Iw z5{X(*cEa>BbAkIE)8)KGMxRHks7MQaV`jbi2Q4ld4t?w|Z$rO5z@U zEE#2^tLD?7_*JcL%Nhf-PWIY%^s2quGdx-6wpN+-hjQi2n6T$(wJprtR#ROEs8&we zrcazD0cmJZ{3=fkg9g~%wU44HppNiV`jWKYF8Bj}?CfluI*LR30$bhQs~hF-3z2*7 zoThM;c0f3|r~E7{GslUEu%M`@<42U4k=q0L`1pJT-#Ybz612vXCm+H@-dTM7%Km6_ zxqFdrrkF>64x|~*i0d=0>;*I3)6*JHOfsJ?=L;J&_!@*U>RahiSRS<5drVIDn!vsX z-#IBhqVA;c&=hFj!9*po!&WR_{-}P%m1C~wWseQZMTlMAdF5p!8;}F-S>_4ZWSZM)2_L?&K0C8=H08+~c2mBrh4rP``tCuM<=&x%z!m1e zfkT{fl$K(pR+P8ykgE%r2^{96L7S^c^Vj&{MXQ)C{d)Y$I70Vj#mOI!#ICuVL}f@R zh}IVG7xUGKjNRIN<5eYlW2oA8Y?HIv>R}5V(!6`>Dry23l4H!Jdhu>rs_x}&R}T1I zGBjkfGh)dc)FU74Q*Dh&rXR_>d4npls(G6S4aSHK{vhzK-Mf!!d3$)|+1YK$Cd9?{ z4Hc1JYFT{Pc%7p#GQXKeid#_7xhE?7NsS3N`_y*_-re-F`9SXMIi``~ zyuLn8N-8Q#WgQBXkBBL&sLANwY~vw+UHyloroyEB+Ue|gQ{!}$ppYQFy)x=Vk(Z4RJA3M-AicgQip5n172d?S zkV4CvLOPMLHUIQP>W60$q;djAV|hnW4r>%|mviIQm*(nNVxn`3YuW_V6TjXz>Ak&Q(w*Z#hZ6f;@qOOf@7o)Rc&7%w7ACx zmX^&2d^H%;2fqrjX5|TrDpbFb+#meOBk}h8EX7JO)0>mR1{1xXKAk>uQ=vFt!6%`> z$gozdR~S!*_urZN+F46kkk264c}wsP_^3xns+7h!zN~agK;|e8r8{Z@a1K#kc8TO&HtKA9ul=EAqXv*4l8z?aBbB!O_Ief^jVg^Mqq|=`Xg5J&xwlj$z+xcBIp} z^NHfanD~qQjb|bLx^GtwGIob(>@DRxUbxf3+`(xpN`BArl~hkslu|UgQaDQH4z`tF zK)}wKkNEbTgze6PfxSw{ww!de@skPcoHg&u{2E5j znSna?Dw(va0(5+MA5Y3GK~mOTOk(cXSVS)Ccfrn{g?peW;+BVx&qYCBN)#;}oyMbS zrD#`DC-qjPTO#L~sbjy&xS8(n+9W+dBeo_H`ARYp!f7vhzu!h3Gt1OVQ;UB(%kgq*?^v(8M+x(-x%;Q8JR&sd zKWq(@~_r1vvVcN$g;d%k<)t%CodS7U4j z&+EQ>Pfx}?JeIenduRZ4GUnU>|MQ{INMXVF6R)(_gr`$%(soyJMu%t{C|`?+8#&pk zr1ovA*hpU>StE+j!M*GF=cntfv?68a*SGoZ*7WSV;?1Wk`B96t?$*)Si><{|FBzuK zDZI-nC1GybW*dJ`iC2&(9IYS1=t{b+iFxcvi>4x_dgpf+8keQ`tP|5}^IOG+Vc$!f|!7+LkPGF?Vyz6uOkskq+J5;`~MJ#wWNbxG2{GA{Ja zo!F)sGakmTvHRlQ#_-4VZ)onMG2N6|clRZgGhS}TaG;EitY!mGmRY8ZsyDv7`6qpb zuhlpX9zNlm&ud`t+QeB)u-F7+U0kfMM>Y{cRvBkRMK8kjz(ee#mV$#kMViyApi}{d zrF{cFa{W|pffRBM!Z)Vg?ar%2@!Z|TpM)1)ng9G+N2WEF-zMTQ#m8dWwon#n6e|7H zr{aeZk_{4#GunAp4L9vWZmO2G`10-w_oJXs5uWh4H1YYp52IOsf5GgL(GN$r-bAIG zhwD8BN^OazWa}W=@ed!_ue^x3F%g>ZL3zKnH|=ii{e{=z8j8BwruxiL%6GegYKD-Q z3q{>!`|dK#mzJYy#&y^z^GbOc)qbkWBvp3SAGhOn<;kM^B22k)`)fPsg11dG`+DOg zJQ7ZfmQgdFWGZIlcvaqs!yA^{%kbvt)hhzvsjaf@GZ2wf_OLkU2~7V zsI91mM2PWv{A`43FXfyT3K~J!lwX%{)ef}hxy3IZ9-KIEp0~?Ji}zmD5zp!3hY2p) zFS*>VvY{-#ZFl(^$Mz_+hMMWbXyd2aW?ng+ee?ve^gEW^GM$ArbnltO>=D@?qs+%y zKJP4v8{f-n#1k`V7_v>vR~>V)XGgq;rB7d7qkg8|o0=I3#IV!^>$VZr%memQ%5~Ug zD3Ymmdq?7cI=SA{; zA0eluDX4Dcm6KO~r#NOGu8kkBvRzDZreqc@G>0 z^6=UFWy>q?N|IMoU1GbRbx71w-=FY&cDhjLs0Zz1_8dlc#88-CExmc-nSlC! z-)p3E?27{z8opE~8Z}tPc9>Byiv@^lzV41m*(S4B|M)2yGr33o?zi6Qn@(V}_ff=` zVYnoX8@St&R^D&BE3)wRxn$=u zX7W;SSS3YNJ1_M$yjWY9{7GDjl4&B!_Sy1m_iOSzQw#pxpSqpbU;8DbYJSMIQSNv4v=MKyIbG%I*oUR^zy^u22(&(VbIlvn;WXcv*kZkCcZ-6WOINAuh= zS5m4di1WgU3)4^@wRmhJy1T+1H*n)a!>!AFgLmPATA3<%@=4wkTDOP;4BTORB)i{J zK8HWd^!($y&wC`(UqrNaP+e_q@+aYWFXJrQ7WQUzTgLbImP~oPCH}O-{e26$Pw(Rl z4*TP^s?VJBv>MIeaT=yoY28PgoZ;f!^vJ(-x>eC8>!G4ZXI8F8tr`di4+!^Zdw ziLDk#Fing?Y7}$F`mTTY#xd4;EU`sr`~yM0ky+`|+&5mHkRH2NSNT)b*ig0?0$PeI zWW;COxoOPm1}d$%)3Eu}A~q-DsDn|qa!@ft3ORJqtg5%_Xz{l`drR)uDAsynv2IFd zWyqfyOBQx-`qYUJ1_8?Bq^SA@k}@mql~(ub>qjFlQeZ8j4z7~GUOvomNv>I`#Tx>5 z?egUj(J(#@nk1t*EsO^bE%nItH1>3w{He>lTBDRrxi0ZXEWH|NY~HdC-&Nab);@$j zHe$95c4C}hSj&PY>l1=wE)$C$WfyYKP~iXKoqp1z_QB9F6vUddDqi6) z#4y+JW(wwo7|-dYY17bpHvb#Pej04Lq;6nef^L z1jVw5h98i=UQAN4Ek(5c6I>3>a#{QRFHI|&bTC6CcZ#90(c!JSvzB9a?_$SYNLvlN zrX8EecQ-6T^Fb!%tyV`{Ly}nc(5MOD^R)&KbYIN13yF+;Pps5-$>3-Sl#We|K~%F7 zt{4>P2fdAIxjBXbv-?V_PZlr>RPt(EYs@4UcX;bRaJEq zD-LNja>4+9g%R5n$^xgE2%WNbmieu=q$`C=a@|w7L53x&Jb`Ze>@oK zX5}Ya*wirgwbazou%D^2C4+T(c4{h*%Kb2A2KeX!%q(cfmuE4mttW|!;@FOny|eG> zqJx+c9uXHTd=%DD*WSFKqD?rpZ?B2qurhV|RzqI*$%-+vAV*S8HwumSn5n)ouXR3w zw^{TLV_Z`*zZkHhbd6tBczSwaJAxdh+SW?;=v000n&f`zL-@vEW&s7cX1rLBZ;f3a z!=B6xR7DQByJSq5e_VE2%y?y47NMi977P#dfZ5q8u)4ZRq=xzm5bWm% zAXwyS$6SzpJXh|2AHJWP!{P7%Plv?l@9p_H@$2<91)!&^8B9)$z;O8z#JfhM<>eKy zxQM)81&#HUoA{-E$bh&JjF6Cr;r&~WZ+7pu1bI6fMum76r6q^$G2*#C_RRABAN5qWaCK7zV0zYep^$b7se*uCOg2WGr8`2&~RFM8h52)iCVS(<+ ziO~V$=*%ckS6u+QJDb4N=XWi$wZ~c@z7OmWaQxW)uGz2=p|hlaP)=LcBNR z@s`MAwEpy11bMsgLYwf6kM!@&N(;x8m!yOC)*3K6(hv2x2z9$cBt*aS^9w}U#ErE7 z3_J37BL1e@P5j3o&cl%QLxSErQU5Hk-2rI}q~A5SJss_LCPsyP&Pa-^%g;_+tuD{` zX%iT@`S^Rh7|i@n+(i5f3qSQfG&Bt0?g?aOW`UfXTrfB|1QwT|{rs>c#I9PJ>o@Tu znAsrhg2V)g0n&Czi2ji|O%CZFjzeNpuwH&vN>x>9-a>0*CFq57Ze*|r%*{^!#EZ;1 z1RsL;SK8D$(spf3ker+X{QUeuNJKPf=NXo&%1Q!^koJ`u`Oy@4OffXt27 z=7vrDJ0U(q*9c}BNQlmn>jHxNZ*(6K=yNDPGbOvevINu94zUjOfQivTFgHC3R-k@X zp-mvP1YiFn%n1IO8MqN_?*K(b#UL&&9(a5EfUwLwP~0^D`Y=mi4Nm}pMb%&h55O{{ zCHQ_~VHt#mhW*X_ZEyLBpY{i4WX}FmUBk~%RV8`LlOw}mW_%3H&&+^D3Yw)`vpv9WOgAN35Pqho-(UjXpSD+4K=!=QC;1$?dS1U<_*Fo7ii_;_bf zF^>ZdStX!)0SD?A@t_UW9> zdU}JP4D)ld#5Hdo>ULp%gEnmg(RW2fC2)ZSUC|vQpc&%T$ZZC*>jcoYga>Ie>p(NR z4t(lf0B$2|;M?#TaE4@-ln0_Gupk3|UIFE(fwYN#37Nmp{@dG{H}P-6`k>G5H!qVK?l@h$jAz~oLB=4x>o^w z^f!=gS_W5QOMqO>40zJ90xbJh!MC9`V46}0LdMrYCd6M3#{;1a{K&er2;d{Np$+~S z{KZ85Z{nYup86rfG;z)%^L7@>gV5aU?1t`38bI9SI?(M}0b&(X;AB`SI8n6#MCz7+ zT=O!xl~f7t)Xl=rSHb)KRqzGkf0JAUT!&V{=h9~IDZLPc*0vMzFF;$JhlJqoXm9xw z`iJ-@5c`<~vr`jb7HNN>8Tfj7dIHiUn1N%Iot+IFtGdDKo)sY7xCCz1&H$0PN+8j& z1Qc49fm-_txSLu7u2jzg*}{HsH7pM(#uR{Ok(t0Gy&QP7je`hiNAOYUMEvvf7`QIX zL!Sb{-};B~*Hsj)&qDl&{%0p4ekcQcOfHxv(irhtIyo^4{gw^N%*+J# z4d*Wg`WA?7B6Fa#z3oro$3UBzM{ERQMrdYo3`|2G06zK`OpXr&_!wX?J~l+8jEr>P zTGEKREHBhOUfHuDj^q^e&ke+s~0Hs!FPjFmrH7@}r*y_P~ zVn4V+2>vQh@X&=o(2MQ zOMq|t7}Vt&)a4rZipU+ zzi-pEK-52c3^Gv$WDa+AcKl)e*OnKq&%-qbxmK;g>naxdwQKNNh>XJof`4=XV($Z^ z!@XbxQhItSNNepOt|RUc|Jz=;enOj9gnCwn^a#qJ1?RO6)Uzhk|4aB9u`#8rMsPK< z07!-8fa}3oK)bYe13z3JkTF2!ard9VUsF~9@y`%-zXsP}1poRP7ObzY1Kc`}xCV_5 z_kocih#&4Z($i8vR&y6fh4U|J0uo$@LdG}j+HPY3e03k%4 zS!i1sQ2+T&?I3Rs2eQT&flpN{Fi$B0+OcS$6b|P?Tq(E?=YxFhEYWW6x2?cy!V(aV zCj3zgUk$?H82F81fgQB(XX(}8e&ZZ*Ek*DO)-Hi_!Fk{Y z#Qz%3gD^O50i&zH*VhlMLVn9|+z~&tySwWT>wg3P>`&bj@&B-$e}=z*cm(=k1TYQ# zo4&<0klNG%nxJ1(hQSf%g?CLCaOqzJ-f(^d!gVqj%4S;F3?kvWUkJa0_(2|xgCIY@ z5c-`E|1!kC_~-CLKN-6KudBb=&TqEAsq-*RLyM~*r?DNhL*J)q z5eFKe91%@$o=>b0aW=!hBmP=c=NRzZfwlwJjfDlo{=5IM z{;NvRSj1o3z>fvkHE8=-99aJcwu8t~Qc?=Ky1D=XK3f{PY+w<7zp$kf%)vKvP#z4V z^o~K$4gJr7m32@#xd0M7hJZ&(E^v!aC)y0+w@yq>LEFdvw0#7BPxl|kUs;?B@k9HE za|oGB8}<+JL;GJ}N9HZ0U*-U^k3#lPn+G0_Ls@$_n1ed(8J_|rO|2j*B^`MB_<`Wy z5Rj6R3Q9}MKwEn|n3$L(_KSu3S%Y)zr|m=AnV(-I?sZ|48O=y2=^(7-(OTz1Y%?3h&n~uyu5tS)CBiHBcnur_*c8z&<74+pcwvXWNfqS+;ioc>b=QsUB{K%Lh_z@j#(kAa;$7B}n1N-|2pI3N)!4GW*@>_s=q*Sc|&xC&L*w`S96?T9&7`Ldc$_M$`351wX zAA-NTBi_!;bm6Uz9xQMA{YQCG)(`!|7#>`QkugQ=azl>aWI@LKS9uT}|7st|Yb=~U z^YgQCT^Ry{{hgqzqX9J56@!YB41msxC&Whh6MS92;+;O)%zZR{R|T=UL(+tF5fT!k z`ol+A;ScIY zC-}I0L2!OH}ntjB5Mz#V`RJ$T3%X&`+zYpG|&aw zTB>1uEgzH>LH{8;7G$J^6QV)zy#)GHvleBSyA$O{Y7GuRg1^3n+6@UAi~nL1kl#UcRY@T zr)*YQL}E^66wzkdTB=|^q7UYG=ZX1ggy$wdBuCoO(MinnfAtRn1`&ziU2z?-EUX0n zFs>H8h69l!BOo^yO+4op{z$GI$vOX*vCqqiA@ujQ6LV`zkmoYYHy}B2M3Uilpp3L zVU7&uSdskR9LyQa!MODtl4FJWD}?t=?-+2l6#$;NTEN``z!~^j5aw2|^$>vSAOSqc zt_EgPcwj%Z3hdzXs?*cciTwL|yMXt`_(ReE@v*^w8cf5vGChgp=U|@hM_v)J>y(rf zAlJ4E#M=qrOk54%ZU*2KBwqMhs9*p{!kp+8uPC6JUIw1$RDh2I(=eBj4)wPH=SJrr z;!n&?ZRP|ao++5GN=`}yj|cETu4x_!xkP}oF;##kx(b{ME&#m6<3Ok#fGgbupg2GP znxh0@G_U~DQd5cfzn<>4-^Cxv5g_~gsR<;fhvf4Hi8en5>m?Es;(&f(6Hv)-f%&>c zAk{$t=aI31;)F?486(1K3Vi#dfcoqjNp{+k_#{k)cG9Vs`2Ir&8 z!Re@SaLP57s1JUK=^~sP$;k<@c4P{!Rlkov5?}i@H}-4%Ehi@jgw@sqhk_EI`#lo8 zDsBSWLwF#cS`B2n2tXL}L~Ie!12Q)Rsxi?1Qi-v?p~3#&B|kAX4t0;j(>C%$zr_F% z{!IidD1o|hDX9d$Fu(O-0uR(PVJ@hT0Iop{f(bR?%ny6G;hzLLJG+VTI)wl4nSaFi z7%{H;UvpCk|290VfrA)=VSPx-GR!f-T#Zp-9e6dg4%Ewff!g;(pyV3^w48ll+&gw7 z1`p$Ie}q30*G2MUKV#89as%zK{wF9k2^92pf{?5X;0x!LTSO#qfO!_AhN-$5)|rit z{W$MO93A$BwScEqE_=y9?HQU-c0DKxW)N2=UUE8z|JRXh{LO-w~ z?JDGpfq9S7;Q^TUuLGfh&i``$A^QI{uDTHq-iXt0=6euco3U%8MRH?EesvtK5xqSv zpr#TH5FaErGYXp=AG{VG;xifG=icb)?)3hjPJZ|SGXD{|i8+p+`u{CQvl$;B9_l8_ zgTx@qiqZhQW-ceheqRX<_FnPxajkcCb_lWmWUFUxZXp5*smc472h=qya*ZeY5b)ZE z)RT-1^#SC1*i>H%N@1)sJvnS4CenZDdw|EXkC#iWv(uL#Yb&c~KluD#$K#;CfrmQ7 zrzVChM1=V+`un;qd%AzCb8`F~WNmG&_5Qt$wEZW$LqUOF|CYEf)c+PJ3-=Fs{#2~~ zUn=^qFZ`u}f1rVlxWcdh6F6Xug${;W$Y7|21X;L{5Q_!$T_JHm68&R@bYTuG=m7Zm zE1Ms$kvIiX2+IR$GfwdUsVM#H_+QlkT!WCk<%Pt!z|WyUZf1}_aJjFB8}wXJ%@cW>Wn3%=DDd>5{@UTuW0m z%r*A^+#8O<*Ma`T{k{&v0f(gXJn zn4f!1q%Hy3V-6T{wYL}kXcny12#!wz{y9Y;zqK2b!g}khtn6R=NA!>E(UJWk5kKs^wYmb0>*|Cx zxzM-W><_8=MtrpQ(W&5dSQ1bv=>sZVSfH0&4D7}Lh@AzXWd(qckdR;d|1Ua${f{E| zLm;vvwTm13zj=_BmIl=F+JFe$V_XeK6Wc4D0Njs81KmLYtm+4WXJHKp3J(6Ye+c_; z57_?*W^NkpYX-r@_z0Ln_IYrB=k4tc9`^$v+XaA}emaxWmt;SXy{kbLle*FWNSjgJiw_az&A`hcgW2MC>pdKdveFY~ z96qrB0eG*|zrw%S|7Pps;{%ejb6~Aj7xk>7kIMpji3PwsDwSxzh<}URL-gPEk6`}km;dm&k@!SRObo0Y z$^~e^_P*?|EhnahGEn9-r%$02NQJ#&;PYQBtA3=_sV_HSFI?` z1?cQ}0M`=W;r3GktbfFR9vbWgHB|+mFh3P!rbU97NWbyWV6R#~ zALnp4*RQ%?zt~E|Mu+T!{U9-^-+g4HhBe1U`S%9;yT%6ix#{}*xr-$yM(l_E{9F9u z-wo{l2VaEl5-~xv(NdwnDhUc$Y~;IO1N}29NOZrCU?R-oZ~6l$#1BI*WSo#T{V*|d z_~t+Ch>D7y^z`(EYwjPX=;)1eXW)H9GjQLG+_!+l_mKL3q}_-+!WbwL3q|6ekdS>m zLP#z7CeK;SBA9}4g-LjCN>c;$XTE<*xwWU^)|Q`ZN%p{&!3r_hy0Kl@?n5{ zeh9WqBZI_q>4pcv-qB&=Yk3%t)rWk8gM(l^bn++v8CX+?U`Ar%f6woqz5n(6HMssD z*LWnxjeK7j$}0k8*~CE$;})AZ&LH^<_#H%7oA{CQ;ZjXJkk72==l+6I1TKw&NSjR`KN8GF{`=vi(jTwxgApIlX*}SI|iQ^;uVQuKlCXPSaMn*=> d{J)-#8@cE|j^fXr_s2Q?Th6#w_s!$-{{d|rlpX*8 literal 0 HcmV?d00001 diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index b8e0adf670..8780dadb54 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -125,14 +125,14 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" !ENDIF -LINKFLAGS = /NOLOGO /INCREMENTAL:NO /MACHINE:$(PLATFORM) /MANIFEST:NO /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:MSVCRT /NXCOMPAT /DYNAMICBASE $(LINKDEBUGFLAGS) +LINKFLAGS = /NOLOGO /INCREMENTAL:NO /MACHINE:$(PLATFORM) /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:MSVCRT /NXCOMPAT /DYNAMICBASE $(LINKDEBUGFLAGS) LIBFLAGS = /nologo /machine:$(PLATFORM) !IF "$(PLATFORM)" == "x86" CANDLEFLAGS = -dPlatform=x86 $(CANDLEFLAGS) @@ -150,4 +150,4 @@ CANDLEFLAGS = -dPlatform=x64 $(CANDLEFLAGS) rc /l 0x0409 $< clean:: - del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.manifest *.res + del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.res From bfa7aef042600f9a4b76b7e420b8421f4166b82f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 10 Feb 2017 11:26:49 +0100 Subject: [PATCH 0019/4321] md: fixed race condition when showin pin pad dialog When the dialog is shown in a separate thread and the user removes the card, both, the thread for the pin pad operation and the main thread are trying to access the card and context handles. Even worse, the main thread deletes the context handle, which may result in a segmentation fault for the thread with the pin pad operation. --- src/minidriver/minidriver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index fad646bf99..cc140bac5e 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -217,6 +217,7 @@ typedef struct _VENDOR_SPECIFIC struct md_opensc_static_data { unsigned flags, flags_checked; unsigned long attach_check; + CRITICAL_SECTION hScard_lock; }; static struct md_opensc_static_data md_static_data; @@ -2315,6 +2316,7 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) const u8 *pin2 = (const u8 *) parameter[5]; size_t *pin2len = (size_t *) parameter[6]; int rv = 0; + EnterCriticalSection(&md_static_data.hScard_lock); switch (operation) { case SC_PIN_CMD_VERIFY: @@ -2333,6 +2335,7 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) rv = (DWORD) ERROR_INVALID_PARAMETER; break; } + LeaveCriticalSection(&md_static_data.hScard_lock); if (parameter[10] != 0) { EndDialog((HWND) parameter[10], rv); } @@ -5996,6 +5999,8 @@ static int disassociate_card(PCARD_DATA pCardData) vs->obj_user_pin = NULL; vs->obj_sopin = NULL; + EnterCriticalSection(&md_static_data.hScard_lock); + if(vs->p15card) { logprintf(pCardData, 6, "sc_pkcs15_unbind\n"); sc_pkcs15_unbind(vs->p15card); @@ -6013,6 +6018,8 @@ static int disassociate_card(PCARD_DATA pCardData) vs->hSCardCtx = -1; vs->hScard = -1; + LeaveCriticalSection(&md_static_data.hScard_lock); + return SCARD_S_SUCCESS; } @@ -6051,9 +6058,11 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, { case DLL_PROCESS_ATTACH: g_inst = hinstDLL; + InitializeCriticalSection(&md_static_data.hScard_lock); md_static_data.attach_check = MD_STATIC_PROCESS_ATTACHED; break; case DLL_PROCESS_DETACH: + DeleteCriticalSection(&md_static_data.hScard_lock); md_static_data.attach_check = 0; break; } From 378bc1f3814c78d31a56f3dd9cb44d9fd32b7d13 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 16 Feb 2017 12:16:13 +0100 Subject: [PATCH 0020/4321] md: Use card specifiic pin pad strings implemented for sc-hsm SoC --- src/minidriver/minidriver.c | 85 +++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index cc140bac5e..b9abead165 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2447,40 +2447,79 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p if (lang & LANG_GERMAN) { tc.pszWindowTitle = L"Windows-Sicherheit"; tc.pszMainInstruction = L"OpenSC Smartcard-Anbieter"; - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein."; - break; - } - tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; tc.pszExpandedControlText = L"Weitere Informationen"; tc.pszCollapsedControlText = L"Weitere Informationen"; } else { tc.pszWindowTitle = L"Windows Security"; tc.pszMainInstruction = L"OpenSC Smart Card Provider"; - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Please enter your digital signature PIN on the PINPAD."; - break; - } - tc.pszExpandedInformation = L"This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)."; tc.pszExpandedControlText = L"Click here for more information"; tc.pszCollapsedControlText = L"Click here for more information"; } - if (pv->wszPinContext ) { + if (pv->wszPinContext) { tc.pszMainInstruction = pv->wszPinContext; } + /* card specific strings */ + switch (p15card->card->type) { + case SC_CARD_TYPE_SC_HSM_SOC: + if (lang & LANG_GERMAN) { + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + break; + } + tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn der Fingerabdruck oder die PIN auf der Karte verifiziert wurde (Timeout nach 30 Sekunden)."; + } else { + tc.pszWindowTitle = L"Windows Security"; + tc.pszMainInstruction = L"OpenSC Smart Card Provider"; + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Please verify your fingerprint or PIN for the digital signature PIN on the card."; + break; + } + tc.pszExpandedInformation = L"This window will be closed automatically after the fingerpritn or the PIN has been verified on the card (timeout after 30 seconds)."; + } + break; + + default: + if (lang & LANG_GERMAN) { + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein."; + break; + } + tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; + } else { + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Please enter your digital signature PIN on the PINPAD."; + break; + } + tc.pszExpandedInformation = L"This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)."; + } + break; + } + tc.pszMainIcon = MAKEINTRESOURCE(IDI_SMARTCARD); tc.cButtons = 0; tc.pButtons = NULL; From 60e4f501cf74156acf943907e0a2bf413f2a42e5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Feb 2017 08:24:37 +0100 Subject: [PATCH 0021/4321] md: configure certificate propagation service --- win32/OpenSC.wxs.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 9ae8b21031..adadc0dbad 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -68,6 +68,12 @@ + + + + + - - - - + + + + + + + + @@ -331,6 +334,7 @@ + From 0b3d7f25c8dce71dde6c20331991affb6063e69e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Mar 2017 21:15:11 +0100 Subject: [PATCH 0024/4321] md: use c89 style to silence VC2010 --- src/minidriver/minidriver.c | 38 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 0623131370..7d33511598 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2344,30 +2344,33 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { + LONG_PTR param; + UNREFERENCED_PARAMETER(lParam); switch (message) { case TDN_CREATED: - { - /* remove the icon from the window title */ - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); - /* store parameter like pCardData for further use if needed */ - SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); - /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; - ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); - } + /* remove the icon from the window title */ + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + /* store parameter like pCardData for further use if needed */ + SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); + return S_OK; + case TDN_TIMER: // progress bar 30 seconds. SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam / 300 , 0L); /* continue the tickcount */ return S_OK; + case TDN_BUTTON_CLICKED: /* We ignore anything else than the Cancel button */ if (LOWORD(wParam) != IDCANCEL) return S_FALSE; - LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + param = GetWindowLongPtr(hWnd, GWLP_USERDATA); if (param) { LANGID lang = GetUserDefaultUILanguage(); PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; @@ -2397,14 +2400,13 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); } break; + case TDN_DESTROYED: - { - /* clean resources used */ - LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; - CloseHandle(hThread); - } + /* clean resources used */ + param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; + CloseHandle(hThread); } break; } From bf828014e5361cd8425e9276ae3b3e59be938f8a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 24 May 2017 12:46:42 +0200 Subject: [PATCH 0025/4321] macOS: Added support for notifications - adds framework for user defined message strings - automatically determine the system's language --- MacOSX/build-package.in | 18 +- configure.ac | 46 ++++- src/Makefile.am | 2 +- src/Makefile.mak | 2 +- src/libopensc/Makefile.am | 2 + src/libopensc/Makefile.mak | 2 + src/libopensc/libopensc.exports | 5 + src/libopensc/pkcs15-pin.c | 26 ++- src/pkcs11/framework-pkcs15.c | 21 ++- src/tools/Makefile.am | 3 +- src/tools/Makefile.mak | 1 + src/tools/opensc-notify.c | 50 +++++ src/ui/Makefile.am | 16 ++ src/ui/Makefile.mak | 17 ++ src/ui/notify.c | 176 ++++++++++++++++++ src/ui/notify.h | 40 ++++ src/ui/strings.c | 313 ++++++++++++++++++++++++++++++++ src/ui/strings.h | 59 ++++++ 18 files changed, 786 insertions(+), 13 deletions(-) create mode 100644 src/tools/opensc-notify.c create mode 100644 src/ui/Makefile.am create mode 100644 src/ui/Makefile.mak create mode 100644 src/ui/notify.c create mode 100644 src/ui/notify.h create mode 100644 src/ui/strings.c create mode 100644 src/ui/strings.h diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index e0ab9fb30f..6ec5f6ba69 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -91,7 +91,23 @@ fi test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src # Build and copy OpenSC.tokend -xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${PWD}/target +xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target + +#if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then + #if ! test -e terminal-notifier-1.7.1.zip; then + #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip + #fi + #if ! test -e terminal-notifier-1.7.1; then + #unzip terminal-notifier-1.7.1.zip + #fi + #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications + #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications +#fi + +if ! test -e NotificationProxy; then + git clone http://github.com/frankmorgner/NotificationProxy.git +fi +xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ # Prepare target root # The "UnInstaller" diff --git a/configure.ac b/configure.ac index ba45c2109b..e0bcf53974 100644 --- a/configure.ac +++ b/configure.ac @@ -245,6 +245,13 @@ AC_ARG_ENABLE( [enable_dnie_ui="no"] ) +AC_ARG_ENABLE( + [notify], + [AS_HELP_STRING([--enable-notify],[enable notifications @<:@detect@:>@])], + , + [enable_notify="detect"] +) + AC_ARG_ENABLE( [werror-declaration-after-statement], [AS_HELP_STRING([--disable-werror-declaration-after-statement],[disable -Werror 'declaration-after-statement' @<:@enabled@:>@])], @@ -443,7 +450,7 @@ if test "${enable_dnie_ui}" = "yes"; then AC_DEFINE([ENABLE_DNIE_UI], [1], [Enable the use of external user interface program to request DNIe user pin]) case "${host}" in - *-apple-*) + *-*-darwin) if test "${enable_dnie_ui}" = "yes"; then LDFLAGS="${LDFLAGS} -framework Carbon" fi @@ -451,6 +458,37 @@ if test "${enable_dnie_ui}" = "yes"; then esac fi +case "${host}" in + *-*-darwin*) + have_notify="yes" + ;; + *) + ;; +esac + +case "${enable_notify}" in + no) + have_notify="no" + ;; + detect) + if test "${have_notify}" = "yes"; then + enable_notify="yes" + else + enable_notify="no" + fi + ;; +esac + +if test "${enable_notify}" = "yes"; then + if test "${have_notify}" = "yes"; then + AC_DEFINE([ENABLE_NOTIFY], [1], [Use notification libraries and header files]) + OPTIONAL_NOTIFY_CFLAGS="${NOTIFY_CFLAGS}" + OPTIONAL_NOTIFY_LIBS="${NOTIFY_LIBS}" + else + AC_MSG_ERROR([notification linkage required, but no notification provider was found]) + fi +fi + AC_ARG_VAR([ZLIB_CFLAGS], [C compiler flags for zlib]) AC_ARG_VAR([ZLIB_LIBS], [linker flags for zlib]) if test -z "${ZLIB_LIBS}"; then @@ -914,6 +952,8 @@ AC_SUBST([DEFAULT_SM_MODULE_PATH]) AC_SUBST([DEBUG_FILE]) AC_SUBST([PROFILE_DIR]) AC_SUBST([PROFILE_DIR_DEFAULT]) +AC_SUBST([OPTIONAL_NOTIFY_CFLAGS]) +AC_SUBST([OPTIONAL_NOTIFY_LIBS]) AM_CONDITIONAL([ENABLE_MAN], [test "${enable_man}" = "yes"]) AM_CONDITIONAL([ENABLE_THREAD_LOCKING], [test "${enable_thread_locking}" = "yes"]) @@ -956,6 +996,7 @@ AC_CONFIG_FILES([ etc/Makefile src/Makefile src/common/Makefile + src/ui/Makefile src/libopensc/Makefile src/sm/Makefile src/pkcs11/Makefile @@ -1021,6 +1062,7 @@ minidriver support: ${enable_minidriver} SM support: ${enable_sm} SM default module: ${DEFAULT_SM_MODULE} DNIe UI support: ${enable_dnie_ui} +Notification support: ${enable_notify} Debug file: ${DEBUG_FILE} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} @@ -1045,6 +1087,8 @@ OPENCT_CFLAGS: ${OPENCT_CFLAGS} OPENCT_LIBS: ${OPENCT_LIBS} PCSC_CFLAGS: ${PCSC_CFLAGS} CRYPTOTOKENKIT_CFLAGS: ${CRYPTOTOKENKIT_CFLAGS} +NOTIFY_CFLAGS: ${NOTIFY_CFLAGS} +NOTIFY_LIBS: ${NOTIFY_LIBS} EOF diff --git a/src/Makefile.am b/src/Makefile.am index ab1dd1a316..64d05d9303 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak # Order IS important -SUBDIRS = common scconf pkcs15init sm \ +SUBDIRS = common scconf ui pkcs15init sm \ libopensc pkcs11 tools tests minidriver if ENABLE_SM diff --git a/src/Makefile.mak b/src/Makefile.mak index 52be9224c5..f6609f774e 100644 --- a/src/Makefile.mak +++ b/src/Makefile.mak @@ -1,6 +1,6 @@ TOPDIR = .. -SUBDIRS = common scconf sm pkcs15init \ +SUBDIRS = common scconf ui sm pkcs15init \ libopensc pkcs11 tools tests default: all diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 6dc37c30aa..c1172eb213 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -78,6 +78,8 @@ libopensc_la_LIBADD = $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) \ $(top_builddir)/src/pkcs15init/libpkcs15init.la \ $(top_builddir)/src/scconf/libscconf.la \ $(top_builddir)/src/common/libscdl.la \ + $(top_builddir)/src/ui/libnotify.la \ + $(top_builddir)/src/ui/libstrings.la \ $(top_builddir)/src/sm/libsmeac.la \ $(top_builddir)/src/common/libcompat.la if WIN32 diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 00c291744f..f0ee0838c1 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -41,6 +41,8 @@ OBJECTS = \ LIBS = $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\common\libscdl.lib \ + $(TOPDIR)\src\ui\strings.lib \ + $(TOPDIR)\src\ui\notify.lib \ $(TOPDIR)\src\sm\libsmiso.lib \ $(TOPDIR)\src\sm\libsmeac.lib \ $(TOPDIR)\src\pkcs15init\pkcs15init.lib diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 7931a2686b..c402ffb60e 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -363,3 +363,8 @@ escape_pace_output_to_buf escape_buf_to_pace_output escape_pace_capabilities_to_buf escape_buf_to_pace_capabilities +ui_get_str +sc_notify_init +sc_notify_close +sc_notify +sc_notify_id diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 1c7df89148..f59802782e 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -30,6 +30,7 @@ #include "internal.h" #include "asn1.h" #include "pkcs15.h" +#include "ui/notify.h" int _sc_pkcs15_verify_pin(struct sc_pkcs15_card *, struct sc_pkcs15_object *, const unsigned char *, size_t); @@ -358,11 +359,13 @@ int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card, "PIN(type:%X; method:%X; value(%p:%"SC_FORMAT_LEN_SIZE_T"u)", auth_info->auth_type, auth_info->auth_method, pincode, pinlen); + card = p15card->card; - if (pinlen > SC_MAX_PIN_SIZE) + if (pinlen > SC_MAX_PIN_SIZE) { + sc_notify_id(card->ctx, &card->reader->atr, p15card, + NOTIFY_PIN_BAD); LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_LENGTH, "Invalid PIN size"); - - card = p15card->card; + } /* Initialize arguments */ memset(&data, 0, sizeof(data)); @@ -408,10 +411,10 @@ int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card, data.pin_reference = skey_info->key_reference; } - if((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD - || p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH) - && !pinlen) { - data.flags |= SC_PIN_CMD_USE_PINPAD; + if ((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD + || p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) { + if (!pincode && !pinlen) + data.flags |= SC_PIN_CMD_USE_PINPAD; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) data.pin1.prompt = "Please enter SO PIN"; @@ -450,10 +453,19 @@ int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card, *sessionpinlen = data.pin2.len; } } else { + sc_notify_id(card->ctx, &card->reader->atr, p15card, + NOTIFY_PIN_BAD); if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN) { *sessionpinlen = 0; } } + + if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN + && auth_info->auth_method != SC_AC_SESSION) { + sc_notify_id(card->ctx, &card->reader->atr, p15card, + r == SC_SUCCESS ? NOTIFY_PIN_GOOD : NOTIFY_PIN_BAD); + } + out: sc_unlock(card); LOG_FUNC_RETURN(ctx, r); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 5b3cb32e54..2f0ddc2b8f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -25,6 +25,7 @@ #include "libopensc/internal.h" #include "libopensc/asn1.h" #include "libopensc/cardctl.h" +#include "ui/notify.h" #include "common/compat_strnlen.h" #ifdef ENABLE_OPENSSL @@ -329,6 +330,12 @@ pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info) } } + if (idx == 0) { + /* send a notification only for the first application that's bound */ + sc_notify_id(p11card->card->ctx, &p11card->reader->atr, fw_data->p15_card, + NOTIFY_CARD_INSERTED); + } + return CKR_OK; } @@ -356,8 +363,20 @@ pkcs15_unbind(struct sc_pkcs11_card *p11card) unlock_card(fw_data); - if (fw_data->p15_card) + if (fw_data->p15_card) { + if (idx == 0) { + int rc = sc_detect_card_presence(fw_data->p15_card->card->reader); + if (rc <= 0 || rc & SC_READER_CARD_CHANGED) { + /* send a notification only if the card was removed/changed + * and only for the first application that's unbound */ + sc_notify_id(fw_data->p15_card->card->ctx, + &fw_data->p15_card->card->reader->atr, + fw_data->p15_card, + NOTIFY_CARD_REMOVED); + } + } rv = sc_pkcs15_unbind(fw_data->p15_card); + } fw_data->p15_card = NULL; free(fw_data); diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 471ed5a889..9eb827b17b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -19,7 +19,7 @@ EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1 noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \ - pkcs11-tool cardos-tool eidenv openpgp-tool iasecc-tool + pkcs11-tool cardos-tool eidenv openpgp-tool iasecc-tool opensc-notify if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool @@ -46,6 +46,7 @@ piv_tool_SOURCES = piv-tool.c util.c piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) opensc_explorer_SOURCES = opensc-explorer.c util.c opensc_explorer_LDADD = $(OPTIONAL_READLINE_LIBS) +opensc_notify_SOURCES = opensc-notify.c pkcs15_tool_SOURCES = pkcs15-tool.c util.c pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) pkcs11_tool_SOURCES = pkcs11-tool.c util.c diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index d03c52c7f4..2032c94a60 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -6,6 +6,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ + opensc-notify.exe \ $(PROGRAMS_OPENSSL) OBJECTS = util.obj npa-tool-cmdline.obj fread_to_eof.obj versioninfo-tools.res diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c new file mode 100644 index 0000000000..c5b16c86ff --- /dev/null +++ b/src/tools/opensc-notify.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ui/notify.h" +#include + +int +main (int argc, char **argv) +{ + const char *title = NULL, *text = NULL; + switch (argc) { + case 3: + text = argv[2]; + /* fall through */ + case 2: + text = argv[1]; + /* fall through */ + case 1: + break; + + default: + fprintf(stderr, "Usage: opensc-notify [title [text]]"); + return 1; + } + sc_notify_init(); + sc_notify(title, text); + sc_notify_close(); + + return 0; +} diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am new file mode 100644 index 0000000000..f64f24fd01 --- /dev/null +++ b/src/ui/Makefile.am @@ -0,0 +1,16 @@ +include $(top_srcdir)/win32/ltrc.inc + +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = Makefile.mak + +noinst_LTLIBRARIES = libstrings.la libnotify.la +noinst_HEADERS = strings.h notify.h + +AM_CPPFLAGS = -I$(top_srcdir)/src +AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) +AM_OBJCFLAGS = $(AM_CFLAGS) + +libstrings_la_SOURCES = strings.c + +libnotify_la_SOURCES = notify.c +libnotify_la_LIBADD = $(OPTIONAL_NOTIFY_LIBS) diff --git a/src/ui/Makefile.mak b/src/ui/Makefile.mak new file mode 100644 index 0000000000..f1a3754034 --- /dev/null +++ b/src/ui/Makefile.mak @@ -0,0 +1,17 @@ +TOPDIR = ..\.. + +TARGET = strings.lib +OBJECTS = strings.obj + +TARGET2 = notify.lib +OBJECTS2 = notify.obj + +all: $(TARGET) $(TARGET2) + +!INCLUDE $(TOPDIR)\win32\Make.rules.mak + +$(TARGET): $(OBJECTS) + lib $(LIBFLAGS) /out:$(TARGET) $(OBJECTS) + +$(TARGET2): $(OBJECTS2) + lib $(LIBFLAGS) /out:$(TARGET2) $(OBJECTS2) diff --git a/src/ui/notify.c b/src/ui/notify.c new file mode 100644 index 0000000000..b55432dca8 --- /dev/null +++ b/src/ui/notify.c @@ -0,0 +1,176 @@ +/* + * notify.c: Notification implementation + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "notify.h" + +#if defined(ENABLE_NOTIFY) && defined(__APPLE__) + +#include "libopensc/log.h" +#include +#include +#include +#include +#include + +static pid_t child = -1; + +void sc_notify_init(void) +{ +} + +void sc_notify_close(void) +{ + if (child > 0) { + int i, status; + for (i = 0; child != waitpid(child, &status, WNOHANG); i++) { + switch (i) { + case 0: + kill(child, SIGKILL); + break; + case 1: + kill(child, SIGTERM); + break; + default: + /* SIGTERM was our last resort */ + return; + } + usleep(100); + } + child = -1; + } +} + +static void notify_proxy(struct sc_context *ctx, + const char *title, const char* subtitle, + const char *text, const char *icon, const char *sound, + const char *group) +{ + /* terminal-notifier does not reliably activate keychain when clicked on + * the notification + * (https://github.com/julienXX/terminal-notifier/issues/196), that's why + * we're including NotificationProxy which has similar features */ + const char notificationproxy[] = "/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/NotificationProxy.app/Contents/MacOS/NotificationProxy"; + + if (child > 0) { + int status; + if (0 == waitpid(child, &status, WNOHANG)) { + kill(child, SIGKILL); + usleep(100); + if (0 == waitpid(child, &status, WNOHANG)) { + sc_log(ctx, "Can't kill %ld, skipping current notification", (long) child); + return; + } + } + } + + child = fork(); + switch (child) { + case 0: + /* child process */ + + /* for some reason the user _tokend can call brew's installation of + * terminal-notifier, but it cannot call `/usr/bin/open` with + * NotificationProxy.app that we're shipping... However, while + * `sudo -u _tokend /usr/local/bin/terminal-notifier -title test` + * works in the terminal, it hangs when executed from the tokend + * process. For now, we try to deliver the notification anyway + * making sure that we are waiting for only one forked process. */ + if (0 > execl(notificationproxy, notificationproxy, + title ? title : "", + subtitle ? subtitle : "", + text ? text : "", + icon ? icon : "", + group ? group : "", + sound ? sound : "", + (char *) NULL)) { + perror("exec failed"); + exit(0); + } + break; + case -1: + sc_log(ctx, "failed to fork for notification"); + break; + default: + if (ctx) { + sc_log(ctx, "Created %ld for notification:", (long) child); + sc_log(ctx, "%s %s %s %s %s %s %s", notificationproxy, + title ? title : "", + subtitle ? subtitle : "", + text ? text : "", + icon ? icon : "", + group ? group : "", + sound ? sound : ""); + } + break; + } +} + +void sc_notify(const char *title, const char *text) +{ + notify_proxy(NULL, title, NULL, text, NULL, NULL, NULL); +} + +void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id) +{ + const char *title, *text, *icon, *group; + title = ui_get_str(ctx, atr, p15card, id); + text = ui_get_str(ctx, atr, p15card, id+1); + + if (p15card && p15card->card && p15card->card->reader) { + group = p15card->card->reader->name; + } else { + group = ctx ? ctx->app_name : NULL; + } + + switch (id) { + case NOTIFY_CARD_INSERTED: + icon = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/VCard.icns"; + break; + case NOTIFY_CARD_REMOVED: + icon = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/EjectMediaIcon.icns"; + break; + case NOTIFY_PIN_GOOD: + icon = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/UnlockedIcon.icns"; + break; + case NOTIFY_PIN_BAD: + icon = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/LockedIcon.icns"; + break; + default: + icon = NULL; + break; + } + + notify_proxy(ctx, title, NULL, text, icon, NULL, group); +} + +#else + +void sc_notify_init(void) {} +void sc_notify_close(void) {} +void sc_notify(const char *title, const char *text) {} +void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id) {} + +#endif diff --git a/src/ui/notify.h b/src/ui/notify.h new file mode 100644 index 0000000000..d290cb1bdb --- /dev/null +++ b/src/ui/notify.h @@ -0,0 +1,40 @@ +/* + * notify.h: OpenSC library header file + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _NOTIFY_H +#define _NOTIFY_H + +#include "strings.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void sc_notify_init(void); +void sc_notify_close(void); +void sc_notify(const char *title, const char *text); +void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ui/strings.c b/src/ui/strings.c new file mode 100644 index 0000000000..383eb7ff03 --- /dev/null +++ b/src/ui/strings.c @@ -0,0 +1,313 @@ +/* + * strings.c: Implementation of default UI strings + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "libopensc/internal.h" +#include "strings.h" +#include +#include + +enum ui_langs { + EN, + DE, +}; + +static const char *get_inserted_text(struct sc_pkcs15_card *p15card, struct sc_atr *atr) +{ + static char text[3*SC_MAX_ATR_SIZE] = {0}; + const char prefix[] = "ATR: "; + + if (p15card && p15card->card && p15card->card->name) { + return p15card->card->name; + } + + if (!atr) + return NULL; + + strcpy(text, prefix); + sc_bin_to_hex(atr->value, atr->len, text + (sizeof prefix) - 1, + sizeof(text) - (sizeof prefix) - 1, ':'); + + return text; +} + +static const char *get_removed_text(struct sc_pkcs15_card *p15card) +{ + if (p15card && p15card->card && p15card->card->reader + && p15card->card->reader->name) { + return p15card->card->reader->name; + } + + return NULL; +} + +static const char *ui_get_config_str(struct sc_context *ctx, + struct sc_atr *atr, const char *flag_name, const char *ret_default) +{ + const char *ret = ret_default; + + scconf_block *atrblock = _sc_match_atr_block(ctx, NULL, atr); + + if (atrblock) + ret = scconf_get_str(atrblock, flag_name, ret_default); + + return ret; +} + +static int find_lang_str(const char *str, enum ui_langs *lang) +{ + if (str) { + if (0 == strncmp(str, "de", 2)) { + if (lang) { + *lang = DE; + } + return 1; + } else if (0 == strncmp(str, "en", 2)) { + if (lang) { + *lang = EN; + } + return 1; + } + } + + return 0; +} + +const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id) +{ + enum ui_langs lang = EN; + const char *str, *option; + + /* load option strings */ + switch (id) { + case MD_PINPAD_DLG_TITLE: + option = "md_pinpad_dlg_title"; + break; + case MD_PINPAD_DLG_MAIN: + option = "md_pinpad_dlg_main"; + break; + case MD_PINPAD_DLG_CONTENT_USER: + option = "md_pinpad_dlg_content_user"; + break; + case MD_PINPAD_DLG_CONTENT_ADMIN: + option = "md_pinpad_dlg_content_admin"; + break; + case MD_PINPAD_DLG_CONTENT_CANCEL: + option = "md_pinpad_dlg_content_cancel"; + break; + case MD_PINPAD_DLG_EXPANDED: + option = "md_pinpad_dlg_expanded"; + break; + case MD_PINPAD_DLG_EXPANDED_CANCEL: + option = "md_pinpad_dlg_expanded_cancel"; + break; + case MD_PINPAD_DLG_ICON: + option = "md_pinpad_dlg_icon"; + break; + case NOTIFY_CARD_INSERTED: + option = "notify_card_inserted"; + break; + case NOTIFY_CARD_INSERTED_TEXT: + option = "notify_card_inserted_text"; + break; + case NOTIFY_CARD_REMOVED: + option = "notify_card_removed"; + break; + case NOTIFY_CARD_REMOVED_TEXT: + option = "notify_card_removed_text"; + break; + case NOTIFY_PIN_GOOD: + option = "notify_pin_good"; + break; + case NOTIFY_PIN_GOOD_TEXT: + option = "notify_pin_good_text"; + break; + case NOTIFY_PIN_BAD: + option = "notify_pin_bad"; + break; + case NOTIFY_PIN_BAD_TEXT: + option = "notify_pin_bad_text"; + break; + default: + option = NULL; + break; + } + + /* load language */ + /* card's language supersedes system's language */ + if (!p15card || !p15card->tokeninfo + || !find_lang_str(p15card->tokeninfo->preferred_language, &lang)) { +#ifdef _WIN32 + LANGID langid = GetUserDefaultUILanguage(); + if (langid & LANG_GERMAN) { + lang = DE; + } +#else + /* LANGUAGE supersedes locale */ + if (!find_lang_str(getenv("LANGUAGE"), &lang)) { + /* XXX Should we use LC_MESSAGES instead? */ + find_lang_str(setlocale(LC_ALL, ""), &lang); + } +#endif + } + + /* load default strings */ + switch (lang) { + case DE: + switch (id) { + case MD_PINPAD_DLG_TITLE: + str = "Windows-Sicherheit"; + break; + case MD_PINPAD_DLG_MAIN: + str = "OpenSC Smartcard-Anbieter"; + break; + case MD_PINPAD_DLG_CONTENT_USER: + str = "Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PIN-Pad ein."; + break; + case MD_PINPAD_DLG_CONTENT_ADMIN: + str = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + break; + case MD_PINPAD_DLG_CONTENT_CANCEL: + str = "Nutzen Sie das PIN-Pad, um den Vorgang abzubrechen."; + break; + case MD_PINPAD_DLG_EXPANDED: + str = "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PIN-Pad eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; + break; + case MD_PINPAD_DLG_EXPANDED_CANCEL: + str = "Einige Kartenleser unterstützen das Abbrechen ausschließlich am PIN-Pad. Drücken Sie Cancel (Abbruch) oder entfernen Sie die Karte."; + break; + case NOTIFY_CARD_INSERTED: + if (p15card) { + str = "Smartcard kann jetzt verwendet werden"; + } else { + str = "Smartcard erkannt"; + } + break; + case NOTIFY_CARD_INSERTED_TEXT: + str = get_inserted_text(p15card, atr); + break; + case NOTIFY_CARD_REMOVED: + str = "Smartcard entfernt"; + break; + case NOTIFY_CARD_REMOVED_TEXT: + str = get_removed_text(p15card); + break; + case NOTIFY_PIN_GOOD: + str = "PIN verifiziert"; + break; + case NOTIFY_PIN_GOOD_TEXT: + str = "Smartcard ist entsperrt"; + break; + case NOTIFY_PIN_BAD: + str = "PIN nicht verifiziert"; + break; + case NOTIFY_PIN_BAD_TEXT: + str = "Smartcard ist gesperrt"; + break; + + case MD_PINPAD_DLG_CONTROL_COLLAPSED: + /* fall through */ + case MD_PINPAD_DLG_CONTROL_EXPANDED: + str = "Weitere Informationen"; + break; + case MD_PINPAD_DLG_CANCEL: + str = "Abbrechen"; + break; + default: + str = NULL; + break; + } + break; + case EN: + /* fall through */ + default: + switch (id) { + case MD_PINPAD_DLG_TITLE: + str = "Windows Security"; + break; + case MD_PINPAD_DLG_MAIN: + str = "OpenSC Smart Card Provider"; + break; + case MD_PINPAD_DLG_CONTENT_USER: + str = "Please enter your digital signature PIN on the PIN pad."; + break; + case MD_PINPAD_DLG_CONTENT_ADMIN: + str = "Please enter your PIN to unblock the user PIN on the PIN pad."; + break; + case MD_PINPAD_DLG_CONTENT_CANCEL: + str = "Use the PIN pad to cancel the operation."; + break; + case MD_PINPAD_DLG_EXPANDED: + str = "This window will be closed automatically after the PIN has been submitted on the PIN pad (timeout typically after 30 seconds)."; + break; + case MD_PINPAD_DLG_EXPANDED_CANCEL: + str = "Some readers only support canceling the operation on the PIN pad. Press Cancel or remove the card."; + break; + case NOTIFY_CARD_INSERTED: + if (p15card) { + str = "Smart card is ready to use"; + } else { + str = "Smart card detected"; + } + break; + case NOTIFY_CARD_INSERTED_TEXT: + str = get_inserted_text(p15card, atr); + break; + case NOTIFY_CARD_REMOVED: + str = "Smart card removed"; + break; + case NOTIFY_CARD_REMOVED_TEXT: + str = get_removed_text(p15card); + break; + case NOTIFY_PIN_GOOD: + str = "PIN verified"; + break; + case NOTIFY_PIN_GOOD_TEXT: + str = "Smart card is unlocked"; + break; + case NOTIFY_PIN_BAD: + str = "PIN not verified"; + break; + case NOTIFY_PIN_BAD_TEXT: + str = "Smart card is locked"; + break; + case MD_PINPAD_DLG_CONTROL_COLLAPSED: + /* fall through */ + case MD_PINPAD_DLG_CONTROL_EXPANDED: + str = "Click here for more information"; + break; + case MD_PINPAD_DLG_CANCEL: + str = "Cancel"; + break; + default: + str = NULL; + break; + } + break; + } + + /* user's strings supersede default strings */ + if (option != NULL) { + /* overwrite str with the user's choice */ + str = ui_get_config_str(ctx, atr, option, str); + } + + return str; +} diff --git a/src/ui/strings.h b/src/ui/strings.h new file mode 100644 index 0000000000..6369d8bcb9 --- /dev/null +++ b/src/ui/strings.h @@ -0,0 +1,59 @@ +/* + * strings.c: default UI strings + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _STRINGS_H +#define _STRINGS_H + +#include "libopensc/pkcs15.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum ui_str { + MD_PINPAD_DLG_TITLE, + MD_PINPAD_DLG_MAIN, + MD_PINPAD_DLG_CONTENT_USER, + MD_PINPAD_DLG_CONTENT_ADMIN, + MD_PINPAD_DLG_CONTENT_CANCEL, + MD_PINPAD_DLG_EXPANDED, + MD_PINPAD_DLG_EXPANDED_CANCEL, + MD_PINPAD_DLG_CONTROL_COLLAPSED, + MD_PINPAD_DLG_CONTROL_EXPANDED, + MD_PINPAD_DLG_ICON, + MD_PINPAD_DLG_CANCEL, + NOTIFY_CARD_INSERTED, + NOTIFY_CARD_INSERTED_TEXT, + NOTIFY_CARD_REMOVED, + NOTIFY_CARD_REMOVED_TEXT, + NOTIFY_PIN_GOOD, + NOTIFY_PIN_GOOD_TEXT, + NOTIFY_PIN_BAD, + NOTIFY_PIN_BAD_TEXT, +}; + +const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id); + +#ifdef __cplusplus +} +#endif + +#endif From 417a409406502f9bf77063752251d0c644db5b08 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 24 May 2017 12:46:25 +0200 Subject: [PATCH 0026/4321] md: allow user defined data for PIN pad dialog - use UI framework - timeout progressbar is running backwards - cancelling is disabled by default - removes card specific UI strings, use opensc.conf for that instead - icon can be loaded by file --- etc/opensc.conf.in | 72 ++++++++ src/minidriver/Makefile.am | 2 +- src/minidriver/minidriver.c | 357 +++++++++++++++++++++++++----------- 3 files changed, 318 insertions(+), 113 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 63abba9bf3..8caf49362c 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -301,6 +301,61 @@ app default { # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false - no label set) # md_supports_container_key_gen: Card allows generating key pairs on the card (Default: false) # md_supports_container_key_import: Card allows importing private keys (Default: false) + # + # Window title of the PIN pad dialog + # Default: "Windows Security" + # md_pinpad_dlg_title = "Title"; + # + # Filename of the icon for the PIN pad dialog; use "" for no icon + # Default: Built-in smart card icon + # md_pinpad_dlg_icon = ""; + # + # Main instruction of the PIN pad dialog + # Default: "OpenSC Smart Card Provider" + # md_pinpad_dlg_main = "Main"; + # + # Content of the PIN pad dialog for role "user" + # Default: "Please verify your fingerprint or PIN for the digital signature PIN on the card." + # md_pinpad_dlg_content_user = "Content User"; + # + # Content of the PIN pad dialog for role "admin" + # Default: "Please enter your PIN to unblock the user PIN on the PINPAD." + # md_pinpad_dlg_content_admin = "Content Admin"; + # + # Content of the PIN pad dialog after pressing "Cancel", when the reader doesn't respond to SCardCancel + # md_pinpad_dlg_content_cancel = "Content Cancel"; + # + # Expanded information of the PIN pad dialog + # Default: "This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)." + # md_pinpad_dlg_expanded = "Expanded Information"; + # + # Expanded information of the PIN pad dialog after pressing "Cancel", when the reader doesn't respond to SCardCancel + # Default: "Some readers only support canceling the operation on the PIN pad. Press Cancel or remove the card." + # md_pinpad_dlg_expanded_cancel = "Expanded Information Cancel"; + # + # Allow the user to cancel the PIN pad dialog + # Default: false + # md_pinpad_dlg_enable_cancel = true; + # + # Time in seconds for the progress bar of the PIN pad dialog to tick. "0" removes the progress bar. + # Default: 30 + # md_pinpad_dlg_timeout = 0; + + # Notification title and text when card was inserted + # notify_card_inserted "inserted title"; + # notify_card_inserted_text "inserted text"; + # + # Notification title and text when card was removed + # notify_card_removed = "card removed"; + # notify_card_removed_text = "removed text"; + # + # Notification title and text when PIN was verified + # notify_pin_good = "good PIN"; + # notify_pin_good_text = "good text"; + # + # Notification title and text when PIN was wrong + # notify_pin_bad = "bad PIN"; + # notify_pin_bad_text = "bad text"; # } # PIV cards need an entry similar to this one: @@ -427,6 +482,23 @@ app default { md_guid_as_label = true; } + # SmartCard-HSM with fingerprint sensor and PIN pad + card_atr 3B:80:80:01:01 { + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + } + secure_messaging local_authentic { # name of external SM module # module_name = @DEFAULT_SM_MODULE@; diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index 6448e7aeea..ac774e39b7 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-minidriver.rc -EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc.in +EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc.in opensc-minidriver.dll.manifest if ENABLE_MINIDRIVER lib_LTLIBRARIES = opensc-minidriver@LIBRARY_BITNESS@.la diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 7d33511598..22208004a5 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -47,6 +47,7 @@ #include "libopensc/log.h" #include "libopensc/internal.h" #include "libopensc/aux-data.h" +#include "ui/strings.h" #include "pkcs15init/pkcs15-init.h" #ifdef ENABLE_OPENSSL @@ -212,11 +213,13 @@ typedef struct _VENDOR_SPECIFIC #define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_IMPORT 32 #define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_GEN 64 #define MD_STATIC_FLAG_IGNORE_PIN_LENGTH 128 +#define MD_STATIC_FLAG_PINPAD_DLG_ENABLE_CANCEL 256 #define MD_STATIC_PROCESS_ATTACHED 0xA11AC4EDL struct md_opensc_static_data { unsigned flags, flags_checked; unsigned long attach_check; + HICON pinpad_dlg_icon; CRITICAL_SECTION hScard_lock; }; static struct md_opensc_static_data md_static_data; @@ -433,6 +436,116 @@ md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object ** } +static const char * +md_get_config_str(PCARD_DATA pCardData, enum ui_str id) +{ + VENDOR_SPECIFIC *vs; + const char *ret = NULL; + + if (!pCardData) + return ret; + + vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (vs->ctx && vs->reader) { + const char *preferred_language = NULL; + struct sc_atr atr; + atr.len = pCardData->cbAtr; + memcpy(atr.value, pCardData->pbAtr, atr.len); + if (vs->p15card && vs->p15card->tokeninfo + && vs->p15card->tokeninfo->preferred_language) { + preferred_language = vs->p15card->tokeninfo->preferred_language; + } + ret = ui_get_str(vs->ctx, &atr, vs->p15card, id); + } + + return ret; +} + + +static HICON +md_get_config_icon(PCARD_DATA pCardData, char *flag_name, HICON ret_default) +{ + VENDOR_SPECIFIC *vs; + HICON ret = ret_default; + + if (!pCardData) + return ret; + + logprintf(pCardData, 2, "Get '%s' option\n", flag_name); + + vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (vs->ctx && vs->reader) { + struct sc_atr atr; + scconf_block *atrblock; + atr.len = pCardData->cbAtr; + memcpy(atr.value, pCardData->pbAtr, atr.len); + atrblock = _sc_match_atr_block(vs->ctx, NULL, &atr); + logprintf(pCardData, 2, "Match ATR:\n"); + loghex(pCardData, 3, atr.value, atr.len); + + if (atrblock) { + const char *filename = scconf_get_str(atrblock, flag_name, NULL); + if (filename) { + ret = (HICON) LoadImage(g_inst, filename, IMAGE_ICON, 0, 0, + LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_SHARED); + } + if (!ret) + ret = ret_default; + } + } + + + return ret; +} + + +static HICON +md_get_pinpad_dlg_icon(PCARD_DATA pCardData) +{ + if (!md_static_data.pinpad_dlg_icon) { + md_static_data.pinpad_dlg_icon = md_get_config_icon(pCardData, "md_pinpad_dlg_icon", NULL); + } + + return md_static_data.pinpad_dlg_icon; +} + + +static int +md_get_config_int(PCARD_DATA pCardData, char *flag_name, int ret_default) +{ + VENDOR_SPECIFIC *vs; + int ret = ret_default; + + if (!pCardData) + return ret; + + logprintf(pCardData, 2, "Get '%s' option\n", flag_name); + + vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (vs->ctx && vs->reader) { + struct sc_atr atr; + scconf_block *atrblock; + atr.len = pCardData->cbAtr; + memcpy(atr.value, pCardData->pbAtr, atr.len); + atrblock = _sc_match_atr_block(vs->ctx, NULL, &atr); + logprintf(pCardData, 2, "Match ATR:\n"); + loghex(pCardData, 3, atr.value, atr.len); + + if (atrblock) + ret = scconf_get_int(atrblock, flag_name, ret_default); + } + + return ret; +} + + +static int +md_get_pinpad_dlg_timeout(PCARD_DATA pCardData) +{ + return md_get_config_int(pCardData, "md_pinpad_dlg_timeout", 30); +} + + static BOOL md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL ret_default) { @@ -476,6 +589,15 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL re } +/* 'Write' mode can be enabled from the OpenSC configuration file*/ +static BOOL +md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) +{ + logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enableed?\n"); + return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", MD_STATIC_FLAG_PINPAD_DLG_ENABLE_CANCEL, FALSE); +} + + /* 'Write' mode can be enabled from the OpenSC configuration file*/ static BOOL md_is_read_only(PCARD_DATA pCardData) @@ -2342,27 +2464,76 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) return (DWORD) rv; } +static const char *md_get_ui_str(PCARD_DATA pCardData, enum ui_str id) +{ + const char *str = md_get_config_str(pCardData, id); + + if (str && *str == '\0') { + /* if the user used an empty string, remove the field by setting it to NULL */ + str = NULL; + } + + return str; +} + +static WCHAR *wchar_from_char_str(const char *in) +{ + WCHAR *out; + int out_len; + + if (!in) + return NULL; + + out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); + if (0 >= out_len) + return NULL; + + out = LocalAlloc(0, (sizeof *out) * out_len); + if (!out) + return NULL; + + out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, out, out_len); + if (out_len == 0xFFFD || 0 >= out_len) { + LocalFree(out); + return NULL; + } + + return out; +} + static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { LONG_PTR param; + int timeout; UNREFERENCED_PARAMETER(lParam); switch (message) { case TDN_CREATED: - /* remove the icon from the window title */ - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); - /* store parameter like pCardData for further use if needed */ - SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); - /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; - ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); + { + PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)dwRefData)[7]; + /* remove the icon from the window title */ + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + if (!md_is_pinpad_dlg_enable_cancel(pCardData)) { + /* disable "Close" */ + SendMessage(hWnd, TDM_ENABLE_BUTTON, IDCLOSE, 0); + } + timeout = md_get_pinpad_dlg_timeout(pCardData); + if (timeout > 0) { + /* update the progress bar with the tick counter for the number of specified seconds */ + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, timeout*1000)); + } + /* store parameter like pCardData for further use if needed */ + SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); + } return S_OK; case TDN_TIMER: - // progress bar 30 seconds. - SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam / 300 , 0L); - /* continue the tickcount */ + /* tick down for 30 seconds */ + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, 30000 - wParam, 0L); return S_OK; case TDN_BUTTON_CLICKED: @@ -2372,32 +2543,26 @@ static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L param = GetWindowLongPtr(hWnd, GWLP_USERDATA); if (param) { - LANGID lang = GetUserDefaultUILanguage(); PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - sc_cancel(vs->ctx); + WCHAR *pszContent = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTENT_CANCEL)); + WCHAR *pszExpandedInformation = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_EXPANDED_CANCEL)); - /* Some readers don't support SCardCancel, though they're - * reporting SCARD_S_SUCCESS. We leave this window open and - * just report to the user. */ - if (vs->p15card->tokeninfo->preferred_language) { - /* choose the token's preferred language over the system's - * language */ - if (strncmp(vs->p15card->tokeninfo->preferred_language, "de", 2)) - lang = LANG_GERMAN|SUBLANG_GERMAN; - } + sc_cancel(vs->ctx); - if (lang & LANG_GERMAN) { - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, TDE_CONTENT, (LPARAM)L"Nutzen Sie das PIN-Pad, um den Vorgang abzubrechen."); - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, TDE_EXPANDED_INFORMATION, (LPARAM)L"Einige Kartenleser unterstützen das Abbrechen ausschließlich am PIN-Pad. Drücken Sie Cancel (Abbruch) oder entfernen Sie die Karte."); - } else { - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, TDE_CONTENT, (LPARAM)L"Use the PIN pad to cancel the operation."); - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, TDE_EXPANDED_INFORMATION, (LPARAM)L"Some readers only support canceling the operation on the PIN pad. Press Cancel or remove the card."); - } - SendMessage(hWnd, TDM_UPDATE_ICON, TDIE_ICON_MAIN, (LPARAM)MAKEINTRESOURCE(TD_WARNING_ICON)); + SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, + TDE_CONTENT, (LPARAM) pszContent); + SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, + TDE_EXPANDED_INFORMATION, (LPARAM) pszExpandedInformation); + SendMessage(hWnd, TDM_UPDATE_ICON, TDIE_ICON_MAIN, (LPARAM)MAKEINTRESOURCE(TD_INFORMATION_ICON)); /* remove the icon from the window title */ SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + + LocalFree(pszContent); + LocalFree(pszExpandedInformation); } break; @@ -2429,7 +2594,6 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p TASKDIALOGCONFIG tc = {0}; int rv = 0; VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - LANGID lang = GetUserDefaultUILanguage(); /* stack the parameters */ parameter[0] = (LONG_PTR)operation; @@ -2455,102 +2619,71 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p this is the only way to display a modal dialog attached to a parent (hwndParent != 0) */ tc.hwndParent = pv->hwndParent; tc.hInstance = g_inst; - tc.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER | TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_USE_HICON_FOOTER; - tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; - if (p15card->tokeninfo->preferred_language) { - /* choose the token's preferred language over the system's language */ - if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) - lang = LANG_GERMAN|SUBLANG_GERMAN; + tc.pszWindowTitle = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_TITLE)); + tc.pszMainInstruction = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_MAIN)); + tc.pszExpandedControlText = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTROL_EXPANDED)); + tc.pszCollapsedControlText = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTROL_COLLAPSED)); + tc.pszExpandedInformation = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_EXPANDED)); + switch (role) { + case ROLE_ADMIN: + tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTENT_ADMIN)); + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTENT_USER)); + break; } - if (lang & LANG_GERMAN) { - tc.pszWindowTitle = L"Windows-Sicherheit"; - tc.pszMainInstruction = L"OpenSC Smartcard-Anbieter"; - tc.pszExpandedControlText = L"Weitere Informationen"; - tc.pszCollapsedControlText = L"Weitere Informationen"; - } else { - tc.pszWindowTitle = L"Windows Security"; - tc.pszMainInstruction = L"OpenSC Smart Card Provider"; - tc.pszExpandedControlText = L"Click here for more information"; - tc.pszCollapsedControlText = L"Click here for more information"; - } if (pv->wszPinContext) { + /* overwrite the main instruction with the application's information if + * possible */ tc.pszMainInstruction = pv->wszPinContext; } - /* card specific strings */ - switch (p15card->card->type) { - case SC_CARD_TYPE_SC_HSM_SOC: - if (lang & LANG_GERMAN) { - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - break; - } - tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn der Fingerabdruck oder die PIN auf der Karte verifiziert wurde (Timeout nach 30 Sekunden)."; - } else { - tc.pszWindowTitle = L"Windows Security"; - tc.pszMainInstruction = L"OpenSC Smart Card Provider"; - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Please verify your fingerprint or PIN for the digital signature PIN on the card."; - break; - } - tc.pszExpandedInformation = L"This window will be closed automatically after the fingerpritn or the PIN has been verified on the card (timeout after 30 seconds)."; - } - break; - - default: - if (lang & LANG_GERMAN) { - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein."; - break; - } - tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; - } else { - switch (role) { - case ROLE_ADMIN: - tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; - break; - case ROLE_USER: - /* fall through */ - default: - tc.pszContent = L"Please enter your digital signature PIN on the PINPAD."; - break; - } - tc.pszExpandedInformation = L"This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)."; - } - break; + tc.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW; + if (tc.pszExpandedInformation != NULL) { + tc.dwFlags |= TDF_EXPAND_FOOTER_AREA; + } + if (md_get_pinpad_dlg_timeout(pCardData) > 0) { + tc.dwFlags |= TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER; + } + + if (md_is_pinpad_dlg_enable_cancel(pCardData)) { + tc.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION; + tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; + } else { + /* can't use TDCBF_CANCEL_BUTTON since this would implicitely set TDF_ALLOW_DIALOG_CANCELLATION */ + tc.dwCommonButtons = TDCBF_CLOSE_BUTTON; } - tc.pszMainIcon = MAKEINTRESOURCE(IDI_SMARTCARD); - tc.cButtons = 0; - tc.pButtons = NULL; - tc.cRadioButtons = 0; - tc.pRadioButtons = NULL; + tc.hMainIcon = md_get_pinpad_dlg_icon(pCardData); + if (tc.hMainIcon) { + tc.dwFlags |= TDF_USE_HICON_MAIN; + } else { + tc.pszMainIcon = MAKEINTRESOURCEW(IDI_SMARTCARD); + } tc.pfCallback = md_dialog_proc; tc.lpCallbackData = (LONG_PTR)parameter; tc.cbSize = sizeof(tc); result = TaskDialogIndirect(&tc, NULL, NULL, NULL); + LocalFree((WCHAR *) tc.pszWindowTitle); + LocalFree((WCHAR *) tc.pszMainInstruction); + LocalFree((WCHAR *) tc.pszExpandedControlText); + LocalFree((WCHAR *) tc.pszCollapsedControlText); + LocalFree((WCHAR *) tc.pszExpandedInformation); + LocalFree((WCHAR *) tc.pszContent); + SecureZeroMemory(parameter, sizeof(parameter)); return (int) result; From cd62c6cdf5d85d85cde7b8f779cb68528ebe063d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Jun 2017 16:10:43 +0200 Subject: [PATCH 0027/4321] Linux: Added support for notifications --- configure.ac | 46 ++++++++- src/libopensc/opensc.h | 2 +- src/libopensc/sc.c | 2 +- src/tools/opensc-notify.c | 22 ++++- src/ui/notify.c | 193 +++++++++++++++++++++++++++++++++++++- 5 files changed, 257 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index e0bcf53974..06107417e2 100644 --- a/configure.ac +++ b/configure.ac @@ -463,6 +463,37 @@ case "${host}" in have_notify="yes" ;; *) + AC_PATH_PROG([GDBUS], [gdbus], [not found]) + if test "${GDBUS}" = "not found"; then + have_notify="no" + have_gdbus="no" + else + have_notify="yes" + have_gdbus="yes" + fi + + if test "${have_notify}" = "no"; then + PKG_CHECK_MODULES( [GIO2], [gio-2.0], + [ have_notify="yes" + have_gio2="yes" ], + [ have_notify="no" + have_gio2="no" ]) + saved_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${GIO2_CFLAGS}" + AC_CHECK_HEADERS(gio/gio.h, [], + [ AC_MSG_WARN([glib2 headers not found]) + have_notify="no" + have_gio2="no" ]) + CFLAGS="${saved_CFLAGS}" + saved_LIBS="$LIBS" + LIBS="$LIBS ${GIO2_LIBS}" + AC_MSG_CHECKING([for g_application_send_notification]) + AC_TRY_LINK_FUNC(g_application_send_notification, [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_WARN([Cannot link against glib2]) + have_notify="no" + have_gio2="no" ]) + LIBS="$saved_LIBS" + fi ;; esac @@ -482,8 +513,14 @@ esac if test "${enable_notify}" = "yes"; then if test "${have_notify}" = "yes"; then AC_DEFINE([ENABLE_NOTIFY], [1], [Use notification libraries and header files]) - OPTIONAL_NOTIFY_CFLAGS="${NOTIFY_CFLAGS}" - OPTIONAL_NOTIFY_LIBS="${NOTIFY_LIBS}" + if test "${have_gdbus}" = "yes"; then + AC_DEFINE_UNQUOTED([GDBUS], ["${GDBUS}"], [Path to gdbus]) + fi + if test "${have_gio2}" = "yes"; then + AC_DEFINE([ENABLE_GIO2], [1], [Use glib2 libraries and header files]) + OPTIONAL_NOTIFY_CFLAGS="${GIO2_CFLAGS}" + OPTIONAL_NOTIFY_LIBS="${GIO2_LIBS}" + fi else AC_MSG_ERROR([notification linkage required, but no notification provider was found]) fi @@ -1087,8 +1124,9 @@ OPENCT_CFLAGS: ${OPENCT_CFLAGS} OPENCT_LIBS: ${OPENCT_LIBS} PCSC_CFLAGS: ${PCSC_CFLAGS} CRYPTOTOKENKIT_CFLAGS: ${CRYPTOTOKENKIT_CFLAGS} -NOTIFY_CFLAGS: ${NOTIFY_CFLAGS} -NOTIFY_LIBS: ${NOTIFY_LIBS} +GDBUS: ${GDBUS} +GIO2_CFLAGS: ${GIO2_CFLAGS} +GIO2_LIBS: ${GIO2_LIBS} EOF diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index f81f27e3ae..bd2eb5007d 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1333,7 +1333,7 @@ scconf_block *sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *drive * @param value pointer to data used for CRC calculation * @param len length of data used for CRC calculation */ -unsigned sc_crc32(unsigned char *value, size_t len); +unsigned sc_crc32(const unsigned char *value, size_t len); /** * Used to initialize the @c sc_remote_data structure -- diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 051fcf69d9..6c40839e39 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -949,7 +949,7 @@ void sc_remote_data_init(struct sc_remote_data *rdata) static unsigned long sc_CRC_tab32[256]; static int sc_CRC_tab32_initialized = 0; -unsigned sc_crc32(unsigned char *value, size_t len) +unsigned sc_crc32(const unsigned char *value, size_t len) { size_t ii, jj; unsigned long crc; diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index c5b16c86ff..18a9ce355b 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -24,6 +24,25 @@ #include "ui/notify.h" #include +#ifndef _WIN32 +#include + +void Sleep(unsigned int Milliseconds) +{ + struct timespec req, rem; + + if (Milliseconds > 999) { + req.tv_sec = Milliseconds / 1000; /* Must be Non-Negative */ + req.tv_nsec = (Milliseconds - (req.tv_sec * 1000)) * 1000000; /* Must be in range of 0 to 999999999 */ + } else { + req.tv_sec = 0; /* Must be Non-Negative */ + req.tv_nsec = Milliseconds * 1000000; /* Must be in range of 0 to 999999999 */ + } + + nanosleep(&req , &rem); +} +#endif + int main (int argc, char **argv) { @@ -33,7 +52,7 @@ main (int argc, char **argv) text = argv[2]; /* fall through */ case 2: - text = argv[1]; + title = argv[1]; /* fall through */ case 1: break; @@ -44,6 +63,7 @@ main (int argc, char **argv) } sc_notify_init(); sc_notify(title, text); + Sleep(250); sc_notify_close(); return 0; diff --git a/src/ui/notify.c b/src/ui/notify.c index b55432dca8..1be6706b5d 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -24,7 +24,7 @@ #include "notify.h" -#if defined(ENABLE_NOTIFY) && defined(__APPLE__) +#if defined(ENABLE_NOTIFY) && (defined(__APPLE__) || defined(GDBUS)) #include "libopensc/log.h" #include @@ -61,6 +61,10 @@ void sc_notify_close(void) } } +#endif + +#if defined(ENABLE_NOTIFY) && defined(__APPLE__) + static void notify_proxy(struct sc_context *ctx, const char *title, const char* subtitle, const char *text, const char *icon, const char *sound, @@ -165,6 +169,151 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, notify_proxy(ctx, title, NULL, text, icon, NULL, group); } +#elif defined(ENABLE_NOTIFY) && defined(GDBUS) + +#include +/* save the notification's id for replacement with a new one */ +uint32_t message_id = 0; + +static void notify_gio(struct sc_context *ctx, + const char *title, const char *text, const char *icon, + const char *group) +{ + char message_id_str[22]; + int pipefd[2]; + int pass_to_pipe = 1; + snprintf(message_id_str, sizeof message_id_str, "%"PRIu32, message_id); + + if (child > 0) { + int status; + if (0 == waitpid(child, &status, WNOHANG)) { + kill(child, SIGKILL); + usleep(100); + if (0 == waitpid(child, &status, WNOHANG)) { + sc_log(ctx, "Can't kill %ld, skipping current notification", (long) child); + return; + } + } + } + + if (0 == pipe(pipefd)) { + pass_to_pipe = 1; + } + + child = fork(); + switch (child) { + case 0: + /* child process */ + if (pass_to_pipe) { + /* close reading end of the pipe */ + close(pipefd[0]); + /* send stdout to the pipe */ + dup2(pipefd[1], 1); + /* this descriptor is no longer needed */ + close(pipefd[1]); + } + + if (0 > execl(GDBUS, GDBUS, + "call", "--session", + "--dest", "org.freedesktop.Notifications", + "--object-path", "/org/freedesktop/Notifications", + "--method", "org.freedesktop.Notifications.Notify", + "org.opensc-project", + message_id_str, + icon ? icon : "", + title ? title : "", + text ? text : "", + "[]", "{}", "5000", + (char *) NULL)) { + perror("exec failed"); + exit(1); + } + break; + case -1: + sc_log(ctx, "failed to fork for notification"); + break; + default: + /* parent process */ + + if (ctx) { + sc_log(ctx, "Created %ld for notification:", (long) child); + sc_log(ctx, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", GDBUS, + "call", "--session", + "--dest", "org.freedesktop.Notifications", + "--object-path", "/org/freedesktop/Notifications", + "--method", "org.freedesktop.Notifications.Notify", + "org.opensc-project", + message_id_str, + icon ? icon : "", + title ? title : "", + text ? text : "", + "[]", "{}", "5000"); + } + + if (pass_to_pipe) { + /* close the write end of the pipe */ + close(pipefd[1]); + memset(message_id_str, '\0', sizeof message_id_str); + if (0 < read(pipefd[0], message_id_str, sizeof(message_id_str))) { + message_id_str[(sizeof message_id_str) - 1] = '\0'; + sscanf(message_id_str, "(uint32 %"SCNu32",)", &message_id); + } + /* close the read end of the pipe */ + close(pipefd[0]); + } + break; + } +} + +#elif defined(ENABLE_NOTIFY) && defined(ENABLE_GIO2) + +static GtkApplication *application = NULL; + +#include + +void sc_notify_init(void) +{ + sc_notify_close(); + application = g_application_new("org.opensc-project", G_APPLICATION_FLAGS_NONE); + if (application) { + g_application_register(application, NULL, NULL); + } +} + +void sc_notify_close(void) +{ + if (application) { + g_object_unref(application); + application = NULL; + } +} + +static void notify_gio(struct sc_context *ctx, + const char *title, const char *text, const char *icon, + const char *group) +{ + GIcon *gicon = NULL; + GNotification *notification = g_notification_new (title); + if (!notification) { + return; + } + + g_notification_set_body (notification, text); + if (icon) { + gicon = g_themed_icon_new (icon); + if (gicon) { + g_notification_set_icon (notification, gicon); + } + } + + g_application_send_notification(application, group, notification); + + if (gicon) { + g_object_unref(gicon); + } + g_object_unref(notification); +} + #else void sc_notify_init(void) {} @@ -174,3 +323,45 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, struct sc_pkcs15_card *p15card, enum ui_str id) {} #endif + +#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS)) +void sc_notify(const char *title, const char *text) +{ + notify_gio(NULL, title, text, NULL, NULL); +} + +void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id) +{ + const char *title, *text, *icon, *group; + title = ui_get_str(ctx, atr, p15card, id); + text = ui_get_str(ctx, atr, p15card, id+1); + + if (p15card && p15card->card && p15card->card->reader) { + group = p15card->card->reader->name; + } else { + group = ctx ? ctx->app_name : NULL; + } + + switch (id) { + case NOTIFY_CARD_INSERTED: + icon = "dialog-information"; + break; + case NOTIFY_CARD_REMOVED: + icon = "media-removed"; + break; + case NOTIFY_PIN_GOOD: + icon = "changes-allow"; + break; + case NOTIFY_PIN_BAD: + icon = "changes-prevent"; + break; + default: + icon = NULL; + break; + } + + notify_gio(ctx, title, text, icon, group); +} + +#endif From b2cde0f7fb40d8317cff65364afaab1d28dd3055 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 13 Jun 2017 13:35:32 +0200 Subject: [PATCH 0028/4321] Windows: Added support for notifications --- src/libopensc/Makefile.am | 2 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/opensc.dll.manifest | 15 ++ src/minidriver/minidriver.c | 30 +-- src/minidriver/versioninfo-minidriver.rc.in | 24 ++- src/pkcs11/Makefile.am | 2 +- src/pkcs11/onepin-opensc-pkcs11.dll.manifest | 15 ++ src/pkcs11/opensc-pkcs11.dll.manifest | 15 ++ src/pkcs11/versioninfo-pkcs11-spy.rc.in | 23 +- src/pkcs11/versioninfo-pkcs11.rc.in | 23 +- src/smm/Makefile.am | 2 +- src/smm/smm-local.dll.manifest | 15 ++ src/tools/Makefile.mak | 2 +- src/tools/exe.manifest | 15 ++ src/tools/versioninfo-tools.rc.in | 22 ++ src/ui/Makefile.am | 2 +- src/ui/notify.c | 215 ++++++++++++++++++- src/ui/notify.h | 8 + src/ui/wchar_from_char_str.h | 44 ++++ win32/Make.rules.mak | 4 +- win32/SCardDlg.dll_14_142.ico | Bin 0 -> 4772 bytes win32/SCardDlg.dll_14_143.ico | Bin 0 -> 4772 bytes win32/certmgr.dll_14_452.ico | Bin 0 -> 10224 bytes win32/certmgr.dll_14_6170.ico | Bin 0 -> 10224 bytes win32/versioninfo.rc.in | 23 +- win32/winconfig.h.in | 2 + 26 files changed, 463 insertions(+), 44 deletions(-) create mode 100644 src/libopensc/opensc.dll.manifest create mode 100644 src/pkcs11/onepin-opensc-pkcs11.dll.manifest create mode 100644 src/pkcs11/opensc-pkcs11.dll.manifest create mode 100644 src/smm/smm-local.dll.manifest create mode 100644 src/tools/exe.manifest create mode 100644 src/ui/wchar_from_char_str.h create mode 100644 win32/SCardDlg.dll_14_142.ico create mode 100644 win32/SCardDlg.dll_14_143.ico create mode 100644 win32/certmgr.dll_14_452.ico create mode 100644 win32/certmgr.dll_14_6170.ico diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index c1172eb213..a3bea3c6f2 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak +EXTRA_DIST = Makefile.mak opensc.dll.manifest lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index f0ee0838c1..5808f38e5e 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -55,8 +55,8 @@ opensc.dll: $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type lib$*.exports >> $*.def - link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib advapi32.lib ws2_32.lib + link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib if EXIST opensc.dll.manifest mt -manifest opensc.dll.manifest -outputresource:opensc.dll;2 opensc_a.lib: $(OBJECTS) $(LIBS) - lib $(LIBFLAGS) /out:opensc_a.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) user32.lib advapi32.lib ws2_32.lib + lib $(LIBFLAGS) /out:opensc_a.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib diff --git a/src/libopensc/opensc.dll.manifest b/src/libopensc/opensc.dll.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/libopensc/opensc.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 22208004a5..b9157f925d 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -47,7 +47,9 @@ #include "libopensc/log.h" #include "libopensc/internal.h" #include "libopensc/aux-data.h" +#include "ui/notify.h" #include "ui/strings.h" +#include "ui/wchar_from_char_str.h" #include "pkcs15init/pkcs15-init.h" #ifdef ENABLE_OPENSSL @@ -2476,31 +2478,6 @@ static const char *md_get_ui_str(PCARD_DATA pCardData, enum ui_str id) return str; } -static WCHAR *wchar_from_char_str(const char *in) -{ - WCHAR *out; - int out_len; - - if (!in) - return NULL; - - out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); - if (0 >= out_len) - return NULL; - - out = LocalAlloc(0, (sizeof *out) * out_len); - if (!out) - return NULL; - - out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, out, out_len); - if (out_len == 0xFFFD || 0 >= out_len) { - LocalFree(out); - return NULL; - } - - return out; -} - static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { LONG_PTR param; @@ -6250,10 +6227,13 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, { case DLL_PROCESS_ATTACH: g_inst = hinstDLL; + sc_notify_instance = hinstDLL; + sc_notify_init(); InitializeCriticalSection(&md_static_data.hScard_lock); md_static_data.attach_check = MD_STATIC_PROCESS_ATTACHED; break; case DLL_PROCESS_DETACH: + sc_notify_close(); DeleteCriticalSection(&md_static_data.hScard_lock); md_static_data.attach_check = 0; break; diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index f99d2b9200..71a7089c14 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -1,8 +1,26 @@ #include #define IDC_STATIC -1 -/* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ -#define IDI_SMARTCARD 102 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" +#endif VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -39,5 +57,3 @@ BEGIN VALUE "Translation", 0x409, 1200 END END - -IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 23cfa97d6b..2494491001 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-pkcs11.rc $(srcdir)/versioninfo-pkcs11-spy.rc -EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in +EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest onepin-opensc-pkcs11.dll.manifest lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la onepin-opensc-pkcs11.la diff --git a/src/pkcs11/onepin-opensc-pkcs11.dll.manifest b/src/pkcs11/onepin-opensc-pkcs11.dll.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/pkcs11/onepin-opensc-pkcs11.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/pkcs11/opensc-pkcs11.dll.manifest b/src/pkcs11/opensc-pkcs11.dll.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/pkcs11/opensc-pkcs11.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/pkcs11/versioninfo-pkcs11-spy.rc.in b/src/pkcs11/versioninfo-pkcs11-spy.rc.in index a4a1a281da..f3a7f59ed4 100644 --- a/src/pkcs11/versioninfo-pkcs11-spy.rc.in +++ b/src/pkcs11/versioninfo-pkcs11-spy.rc.in @@ -1,5 +1,27 @@ #include +#define IDC_STATIC -1 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" +#endif + VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -35,4 +57,3 @@ BEGIN VALUE "Translation", 0x409, 1200 END END - diff --git a/src/pkcs11/versioninfo-pkcs11.rc.in b/src/pkcs11/versioninfo-pkcs11.rc.in index e8bc91d3be..946d3f8e1a 100644 --- a/src/pkcs11/versioninfo-pkcs11.rc.in +++ b/src/pkcs11/versioninfo-pkcs11.rc.in @@ -1,5 +1,27 @@ #include +#define IDC_STATIC -1 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" +#endif + VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -35,4 +57,3 @@ BEGIN VALUE "Translation", 0x409, 1200 END END - diff --git a/src/smm/Makefile.am b/src/smm/Makefile.am index 50d8cd89d7..ce5e4c4256 100644 --- a/src/smm/Makefile.am +++ b/src/smm/Makefile.am @@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = Makefile.mak +EXTRA_DIST = Makefile.mak smm-local.dll.manifest AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/common -I$(top_builddir)/src/include diff --git a/src/smm/smm-local.dll.manifest b/src/smm/smm-local.dll.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/smm/smm-local.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 2032c94a60..c3ef65c583 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -24,4 +24,4 @@ $(TARGETS): $(OBJECTS) $(LIBS) .c.exe: cl $(COPTS) /c $< link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib ws2_32.lib - if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + mt -manifest exe.manifest -outputresource:$@;1 diff --git a/src/tools/exe.manifest b/src/tools/exe.manifest new file mode 100644 index 0000000000..029b353778 --- /dev/null +++ b/src/tools/exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/tools/versioninfo-tools.rc.in b/src/tools/versioninfo-tools.rc.in index 444b1a2522..2c7f14c558 100644 --- a/src/tools/versioninfo-tools.rc.in +++ b/src/tools/versioninfo-tools.rc.in @@ -1,5 +1,27 @@ #include +#define IDC_STATIC -1 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" +#endif + VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index f64f24fd01..5a29358f20 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak noinst_LTLIBRARIES = libstrings.la libnotify.la -noinst_HEADERS = strings.h notify.h +noinst_HEADERS = strings.h notify.h wchar_from_char_str.h AM_CPPFLAGS = -I$(top_srcdir)/src AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) diff --git a/src/ui/notify.c b/src/ui/notify.c index 1be6706b5d..faad0af824 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -24,7 +24,7 @@ #include "notify.h" -#if defined(ENABLE_NOTIFY) && (defined(__APPLE__) || defined(GDBUS)) +#if defined(ENABLE_NOTIFY) && (defined(__APPLE__) || (defined(GDBUS) && !defined(_WIN32))) #include "libopensc/log.h" #include @@ -63,7 +63,216 @@ void sc_notify_close(void) #endif -#if defined(ENABLE_NOTIFY) && defined(__APPLE__) +#if defined(ENABLE_NOTIFY) && defined(_WIN32) + +#include "wchar_from_char_str.h" +#include + +static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8, + 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}}; +HINSTANCE sc_notify_instance = NULL; +HWND hwndNotification = NULL; +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 +UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; +BOOL RestoreTooltip(void); + +// we need commctrl v6 for LoadIconMetric() +#include + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if ((message == WM_DESTROY) + || (message == WMAPP_NOTIFYCALLBACK + && (LOWORD(lParam) == NIN_BALLOONTIMEOUT + || LOWORD(lParam) == NIN_BALLOONUSERCLICK))) { +#if 0 + DeleteNotificationIcon(); +#else + RestoreTooltip(); +#endif + return TRUE; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +static const char* class_name = "DUMMY_CLASS"; +static const char* window_name = "DUMMY_WINDOW"; + +static BOOL create_invisible_window(void) +{ + if (!hwndNotification) { + //Register Window class + WNDCLASSEX wx = {0}; + wx.cbSize = sizeof(WNDCLASSEX); + wx.lpfnWndProc = WndProc; // function which will handle messages + wx.hInstance = sc_notify_instance; + wx.lpszClassName = class_name; + if (!RegisterClassEx(&wx)) { + return FALSE; + } + /* create window */ + hwndNotification = CreateWindowEx(0, class_name, window_name, + 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); + } + + if (hwndNotification) { + return TRUE; + } + + return FALSE; +} + +static BOOL delete_invisible_window(void) +{ + BOOL r; + r = DestroyWindow(hwndNotification); + r &= UnregisterClass(class_name, sc_notify_instance); + + hwndNotification = NULL; + + return r; +} + +static BOOL AddNotificationIcon(void) +{ + NOTIFYICONDATA nid = {sizeof(nid)}; + TCHAR path[MAX_PATH]={0}; + BOOL r; + + if (!create_invisible_window()) { + return FALSE; + } + + nid.hWnd = hwndNotification; + // add the icon, setting the icon, tooltip, and callback message. + // the icon will be identified with the GUID + nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID; + nid.guidItem = myGUID; + nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK; + LoadIconMetric(sc_notify_instance, MAKEINTRESOURCEW(IDI_SMARTCARD), LIM_SMALL, &nid.hIcon); + if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { + strcpy_s(nid.szTip, ARRAYSIZE(nid.szTip), path); + } else { + strcpy(nid.szTip, PACKAGE_NAME); + } + + r = Shell_NotifyIcon(NIM_ADD, &nid); + + nid.uVersion = NOTIFYICON_VERSION_4; + r &= Shell_NotifyIcon(NIM_SETVERSION, &nid); + + return r; +} + +static BOOL DeleteNotificationIcon(void) +{ + BOOL r; + NOTIFYICONDATA nid = {sizeof(nid)}; + + nid.uFlags = NIF_GUID; + nid.guidItem = myGUID; + + r = Shell_NotifyIcon(NIM_DELETE, &nid); + r &= delete_invisible_window(); + + return r; +} + +static BOOL RestoreTooltip() +{ + // After the balloon is dismissed, restore the tooltip. + NOTIFYICONDATA nid = {sizeof(nid)}; + + nid.uFlags = NIF_SHOWTIP | NIF_GUID; + nid.guidItem = myGUID; + + return Shell_NotifyIcon(NIM_MODIFY, &nid); +} + +static void notify_shell(struct sc_context *ctx, + const char *title, const char *text, WORD icon) +{ + NOTIFYICONDATA nid = {sizeof(nid)}; + + nid.uFlags = NIF_GUID; + nid.guidItem = myGUID; + + if (title) { + strcpy_s(nid.szInfoTitle, ARRAYSIZE(nid.szInfoTitle), title); + } + if (text) { + nid.uFlags |= NIF_INFO; + strcpy_s(nid.szInfo, ARRAYSIZE(nid.szInfo), text); + } + if (icon) { + nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; + LoadIconMetric(sc_notify_instance, MAKEINTRESOURCEW(icon), LIM_LARGE, &nid.hBalloonIcon); + } + + Shell_NotifyIcon(NIM_MODIFY, &nid); +} + +void sc_notify_init(void) +{ + if (!sc_notify_instance) { + /* returns the HINSTANCE of the exe. If the code executes in a DLL, + * sc_notify_instance_notify should be pre-initialized */ + sc_notify_instance = GetModuleHandle(NULL); + } + AddNotificationIcon(); +} + +void sc_notify_close(void) +{ + DeleteNotificationIcon(); +} + +void sc_notify(const char *title, const char *text) +{ + notify_shell(NULL, title, text, 0); +} + +void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, + struct sc_pkcs15_card *p15card, enum ui_str id) +{ + const char *title, *text, *group; + WORD icon; + title = ui_get_str(ctx, atr, p15card, id); + text = ui_get_str(ctx, atr, p15card, id+1); + + if (p15card && p15card->card && p15card->card->reader) { + group = p15card->card->reader->name; + } else { + group = ctx ? ctx->app_name : NULL; + } + + switch (id) { + case NOTIFY_CARD_INSERTED: + icon = IDI_CARD_INSERTED; + break; + case NOTIFY_CARD_REMOVED: + icon = IDI_READER_EMPTY; + break; + case NOTIFY_PIN_GOOD: + icon = IDI_UNLOCKED; + break; + case NOTIFY_PIN_BAD: + icon = IDI_LOCKED; + break; + default: + icon = 0; + break; + } + + notify_shell(ctx, title, text, icon); +} + +#elif defined(ENABLE_NOTIFY) && defined(__APPLE__) static void notify_proxy(struct sc_context *ctx, const char *title, const char* subtitle, @@ -169,7 +378,7 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, notify_proxy(ctx, title, NULL, text, icon, NULL, group); } -#elif defined(ENABLE_NOTIFY) && defined(GDBUS) +#elif defined(ENABLE_NOTIFY) && defined(GDBUS) && !defined(_WIN32) #include /* save the notification's id for replacement with a new one */ diff --git a/src/ui/notify.h b/src/ui/notify.h index d290cb1bdb..d32d69dd0c 100644 --- a/src/ui/notify.h +++ b/src/ui/notify.h @@ -33,6 +33,14 @@ void sc_notify(const char *title, const char *text); void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, struct sc_pkcs15_card *p15card, enum ui_str id); +#ifdef _WIN32 +#include +/* If the code executes in a DLL, `sc_notify_instance_notify` should be + * initialized before calling `sc_notify_init()`. If not initialized, we're + * using the HINSTANCE of the EXE */ +extern HINSTANCE sc_notify_instance; +#endif + #ifdef __cplusplus } #endif diff --git a/src/ui/wchar_from_char_str.h b/src/ui/wchar_from_char_str.h new file mode 100644 index 0000000000..359f16da2f --- /dev/null +++ b/src/ui/wchar_from_char_str.h @@ -0,0 +1,44 @@ +/* + * wchar_from_char_str.h: Conversion from string to wide string + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +static WCHAR *wchar_from_char_str(const char *in) +{ + WCHAR *out; + int out_len; + + if (!in) + return NULL; + + out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); + if (0 >= out_len) + return NULL; + + out = LocalAlloc(0, (sizeof *out) * out_len); + if (!out) + return NULL; + + out_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, out, out_len); + if (out_len == 0xFFFD || 0 >= out_len) { + LocalFree(out); + return NULL; + } + + return out; +} diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 8780dadb54..2c14ad6f7f 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -125,10 +125,10 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" !ENDIF diff --git a/win32/SCardDlg.dll_14_142.ico b/win32/SCardDlg.dll_14_142.ico new file mode 100644 index 0000000000000000000000000000000000000000..5fe23fe2fd77a01a5cad17e3daa2c6531b75863b GIT binary patch literal 4772 zcmeI0v1=Sh6vm$-#e0Q7cH_z*$7!r45C%e2DY!@{aHBLSOqwD8!Knyn)A%l=P`H3$ z8{;A|Ns&fn5ctw0CZ5`AA`qx>EU&n`Lfk=&C%^aR_OvHUa$`se&1rV$eczk+zI{8l zvnP=mnUm|+FWdR=cSJrFk;|8peRD?SgIR$W_=fz{5czCQ`DB0juE?u-k(-m&Nt2G5Q)|yR~Y z-1ZrE>G=vPV>FxFJhROR~1MCabHfa_iPDSzcb2{HrLpZ%6rFo=Pl({Qk5jPoF)L z?|%M;436&U1wACwfjKY-<`m;1)Ww5)1|HmldvKjrfEVBeMgd-cbCLiazyo*y2;dPr zV#i>a9Y;rSM1c3h zaA^*~PIYjDQDrJTM~@bd7LOLYWVCpadlGqqdbC&>AUy+*7LOJy3pzYH zJUTo&JUXmY=f;6lf^WP*4ZGZB)gs9)vSTy^Yi$kT0Mu zpd*maZmsH|1_2#Gb#P&JyO|Ww63`M55lCoD04;%u0jB^E(83>`INXzfmZ0@8ExH=? zE`XsSq9LLoq9LLoqQRCE8Uh+38X_738VEzj9}N)=5e*RygrKM*W3 zG2-Nj;jukBqQzDpFYn2Za_7z+;W;9A@7|Sr_wLD)Cr@N+YfE-^c4T*VSN8Y!<>25z z27`f&MkDF}6Xk~o5BMJER9C+PdLo`#8dpuV{x_{G%k#99S+?}z#hD&urqh?siUFOS z<6-nsuXjd_L}xwPX&yCt*c+SZ@ z8V3!}{7!jTTCFDZ$@yi9P*RqoZ9PsLs`-Z+!02q7(v2M~0r{D)`pToD?d@$G%tH%Q zFP9udZ>eXRP&GN%EKJgg9M!^dhB7Bpf{*9JV^`c$U+7cm?|^L z&mhy4XCBI*GCMh|M=v{*PBG4-@puEB64j0-t!AGXzJZo=zf#2F8F1YG^Y^*&dy2l_ zoZ51IIid4@q9^?@xOh*wcu%=_Pq}zc;SoOlykoCsJK#x?TA3Y*q#axVOm-YYDw7Rj zs7PW51KV>g0?ug*)C~%xJc4C2(j5grcaOnfn~ijAYJ?I%eZ~ryR032_Y(qgNtcuV} zsGpL-Q6JJTH)0$u#@Nqd+?(O2H$A8G(|OYKSvdH|3o+iucjZy~-TeIXUt|1swg2^R mUH)VAe6_OVQv0KC9)7VVa(y|S?Z@TJYX8HJc*82>&k43E-R&A+ot(yvgEG+tDW)^V43Q%JcK{1yHGroTokM z1B(mw^1Pd`)pDS+5LeE-U*76=gBdI?F2qswixcodt1MKz3RDMlty)!}Heb-y9O!#P z8&IZp=51?SbiKHk(`GSDE3kzIh^1cb)^m5g#-iQ>0Q;pbZ~?@`8v>xW0MNsL(L+G2 zEG??%G4hqjLLM~kuOlX8DZHU+l_gMXO4IbKS{vBq%Rb#FHTc#RZ(Xtn{$?BWY9X}8 z!|F;Dn$3}bk?xEQw%${bQV-2-k^L)-O*(W0J>2)R9tS_MB2vRXY{*D>Dy7gPWT&@3 ztZs~l-@@&%M7DAI33`ow3`e%U?e$`x6XzKXhR?sX&x;*?$+l@F{``ba>g`u=g(p^NE^+Eo!40N)8l;L%G90*%|Dyc{^N#>j*cR=B4cA? za`50mIdtfd96o$ljvhTK6B83MJv}X_PMwmesVSM9oRs*>Ag50U`9|(a$Wrw z(csYF(BRPE(BJ|XIvhHj>fi>W%2ar+9xWa%9xe8j(c($&N#qIY(PCwQ^h`WjJX)+Q z=A)yX>+o+0tdk{vhdK;-h zO1>0rDLPW}*{xL_)F4Gisyg^$cDr#((UPJiMMO$M+X84waZE8v0aCQ^p%aIDlAe}_UH%}TW!3&CO^oTGiQY7hg`XGMXp}GDtGSOk()Pf%DsE{gxZ14#cyS#?_^+UZlD`SddX-E1}dQO$6{*Y`0@3U zdbig$d85}_Ew#WP+Lex4G_`28)L^@}(cM;8MYdW)$@Ab*t1!qd%9vT(K{vV$jnU`( zbTs7OXfz(Hg|=au1my4H-^dvdpI_&?SFMn}t(u5Vxo$dA9J zUt3#VUdF&Iv_M7vLSLp9YC!1eeMMjIJWYW7+B0J6KNuy3AjR`oaRql;!1Q zFA(*~vQB527pw862ZR?Pi2BoT$^eQdxS=2ewy?6%&TH2=v%TQ&!ILu=XXa*3zAJKT y-}`f)&CGptVd~;-+%&(aC-c#MSdPq`d*f}n^vS2^=05)L;>>Dt7jdJ_h34i0^SNizVT_#>l@;3X@+13T%rPn>6q4NB zbgub6lQa8>w_$RDz+9+rs=m)cXhm{$a|_djHcMh-j|hb_;(58LAT~D4f;cKqa*b00 z!ID@9CKjp-)CHEr3&JdUp0%$LCJ+k35){0tK%L~&4)IKzsf7ieT0#k`4;BlBLJJ3! zQS~LrcuPcc2bqi-Oi=QslqWkEMGqmEQ`*#lhJpp+natFJ6#c}@1QtReUxehR7Gk$x zSa}=jt-4GoQ_6(`8v!+;2vnZN$3n@n_NgIiTt>vF82?isxdR)5p8^};;Q_`B=Y%vP z|G9vppINq!@X)Xt@x~P3Y19;Ikyi1qheQ(nGgL+G{$#5n#nw5!0{mK6u5&Bme>qsu zq9zHgYd)eUCI6vy&K4cjgjia3ub9|@AWR?_lemv~fnaoO1TeWk5Gxox*VM9Op`e40 z!zea4wQvwu?8vB~6_Ji!Lw)$# z^f=@%90`#te+RBR7l5DkJc!&mAD(S^2U=E-1n#TxAl7;Zsy9!8l)wH7(zi~BtnD8| z?Y3!9WF&x6^QBO``y-I-nFW%)0ti2_5_}GChlf9W2I3Q1kbHhSa8^3dban$sZMQ(r z#jPN+*##{gmXLnK1ln#Hfc%yrV1O~G=vl)%hG*e@lui7QR1jjJ==%g3SJLL^aPJ6*p zp)aV}_<@>j04%l(gvAaau+%9GG+e3OlWy?!k5|A{co9Ao-h{P6Z&+>T51*g+hfTKL zu+Aw6zH#)0O^yNZjgud&bcuj=g5k)eTVUyU1NOLv zz>XWSpz9R}hF;Nd>}EJ^zR3V~N${F|62R$9c=sIfPFVm~vfw?}ha}4fa49Cf2wrzC zh4B}QLDeM(KJ<7D;9Uj~@C-D93t(wz1%Rsv;ASm=KasZtAg~c2qyZp|@&npnS!@k_ z>Gc4#ypmws?R3!g&w?%f8K51M59=a|V0~OUYzuh=Iuz^sr-E)!CYS^yf#Ka8_#rF< zc11h}qliM#jVTAC_zEzIECBPk5;&Oj4Av#rfKEy^XgzFzy@^$@C$k=mvg*MswH7Q= zYrrzI0gh#fU~hgSnB+@9_faoI*q?-xp22YP<~^{w6$PgPRz}i?t$Q%PKe{WAgrkuGO}{uY1TtX zEqV%7IhjzMp9A$}CGfDc8Xi5Vg6tX*JgsYhw5Cpw)Yd?gh=ZyI5!5zGp}A24t<6o) z-YSJEX$Np^9njR)2K9Xd(9zKjow9D|>g@&jKtI0)&_*=0A%q$UUfIHPf8?Kk8j=9) z+MuScsik9YKYuI02k-KdkKP+B5Vl!2Ai&YlURO)!lJgpfpZKOKNfQ42)`xrnTH674 zE-X-+Gh0npS8E5n|Hj+DBf-pRDie5lk%zl`k*B_afxf<@qs~H@I^~_$CPVC`-@p3@ zUha9xx46<(Q&VmBZ0${&JNDh5@%o6-fBAgO*ztGsQ}d$1*Vn_N=$ej!y@9>Eqvj|1 zlIg2|q!Z8X)p0ozNkMzGr+YwYwWp4@`kXo1T3S1{?p>pCSZHl)ZTHo^l$6whJnuV! z0mZIbI=cGy9`ytSe1+wS zmFCvRF7}f=FW}DO(#i+>9qgSBT)CpXQSP(+RKh2zgV$$ z?b`D#l$kGyri+@}4yx8EGt|7-+1V*;ZL9FRd8?#N#>-j#{ohiuU;eFTIE#k|zWyF< zLzXAsp%p4_6|+FyP=tJ@f2XEHH?d7>n?iYMeXCO3Um%I1lWNpPx9j+bzyil{1=N48pg{5~p`d{3Ljjk^|FXDz{+GwG6nkc+@N4{E z`S{;;pBucV4BkulaT#_`S-9C4nlwi8_mA3bQ~7&EjsAT84$*yi3x8KoG53HG7Pt8G zed6((pki@@&U>1MqtWn{i7l)@WCv@_96;yzCD?3v1yrm9VDc$HP&s`^an7HK2bFVC zpmIJ27SZ{;+9?pe@Q8q8SA$@KXC%BzjtvM?`14ie;seFm>QVxK_Q>JS(3#!^@bRr; znCo8(w7J8`o7Dh*O>~Az`SWvGWF4%E6T@E;nqW<0Gkl&bg|8kyhYgus{8?sDgJ4*T zkbC_y6o=mh%yNgSq$9je96P%mx*d0+3pa@qV__rFKre{2NUJ!R}*P%2%h zzC>--tXX5>mC>-A{F<55=l^-)#ED~J%uDbx@t-VMtTuDz%(3w5$8+Y41o*=rW=?$V zjW@=Q_~ZC#^Jb420TbQ_)o~M6ta$xTi>7_JLdmaQJ!!@VAHGSv>g1_YCcd+5*~&>O zDl3Tx)d>^cUbR{g7*9DXRxe$;RAcGV)q}iJJjAb321R+*p}_M>TmGT=ztkU8RvaG-I#r#z{Jdj*nZXe|pl+6Fw7n9DDZ8mcvq&EvB*KW~eV3-cpUh zC$or(i3T@xg|x+X!)wh)mX_5Ss{Lhn`Cm#;*=+jO`&*Cb&N*nGy3oqKi~Kqye-7uK z_Q3^qcW{Z*J^bos8m{+A!>Rl2y2s92<@D01S5zF<&KO^#J3pmv^VA;FZ#cYd^fR&~ z9}>lTrnl8@|3G^7@bL$@fL_jj?viAJeLJ1*4e)`K@nX$A}{l zN~+C@(5-B*96oEWu}o^?8b*=UsT3=gJpcr06tMQs&-gUIJnpT(l5dUVn5#g^ml$P)ZEq6AN8acCS~fS3FG>eWk+2jb`~=B|G( z@)|n{-$8K9!B>ukBVim!SO>zfSOn(`gxfS8S4wcry+T=E{{XMwFE)eM&+I>tTrEAG zEkg3&(W$rvy`FWURcrz7^o&Ct?_^wmGX)9jKwX~%Gzd&X{o5(1Ve5y>&-(Uv_4SE2 zKB(>{Yzg5;84?DAEsEBV z7fv&CM#9=q%{CC#>0Mh$>yPa>^G^E==(&bqKrx5QzIX0*3k+|msH~QBc03maHTFsg zH$%e8XstcNaSq8y_!Ew?Peiy_KyA?gPeFNeFL|%Vza;`#ua6-0nGt#{l zif&nz`1$z&WNp(OMAS>|cgea%grkTyyG6LrLsYbRwy`kHtyrr$ILBf~m>FpWPA2z7pH7I__{%>i1x88`sb&f&UOZ^;9U48O~ zwN632{^NHNI+QXwmFvTSp|UUXFP39+_Wp;b7x3eMh4w$C{Tt4DN|w{uZ@d)7?C0dv zE+HNq8@DcbAGg}pSFV0O2#>hm>8LJz#5Gh_ay2E7x%%=_u8yd>sDP_2DdwJcJ|`WD z_nft(B-Wl%KVf(Z{ef{q_HR1pgKT`Yy_2xM?YXFLu&+%2!>Wd+X(ks2*x6%#J%se< zb2X2PxH_i4tdy%NEa1x0(>PI0^-!OgURIY8OVe5!(jS#s%$)yX~Y>f$<{cko1OldYZ)|u8wTxZKrYPDxT1|E9OBe5p(SwZJe~Jk!x>j<=Wd@DJ|hTD35ST zu8aE0#v(Smgx614?U4P^S&y>`W5uO5w{W>*C=v#Xdcj#pm^;!p0MvE~>8Yrx7qfQT zq*AW6rG?@a($U7XQC=(Ql#-72j&`nv`oZV5G;z{K313bsk#L=Z`r~p+75Z=gWPiwm zJU)+bWc(o{rPKI!Vvo_)pq}+M9zAEm(mLv-ZK5uEhq`*Yx$eFmPDX1|LA_izld0#I-|7`4skN^GLGG3SS?dYG`&+Z1-f)fVUzv5kC?^hkIwTiT4?pbyQ zSDl~DRc1ZpM3qmus=REjp{#^^l9|Rm%}C?QQxduAM>*WnhpALf5!X{)rn`4=4Y2V~ z$S)t%A2l@pK}m`|kv?Pr9|BimQlyB(QPgwgbl#b!UoxSSG<&nw0Id1aXR zsGO(*lM5>_I->xcZ~tU}3d!QKiurpHn}`2SVs|g5YqUZDJ)mz6{~@M5 zBb&ZQ@c9wxg?xN3t$>f&dBWGDHOyi*mn{CZd?vqfkIu?}hyV8@&^ppyBN6D^K8$)( zK|t}}4~bOdpP;|l5~i zg#9Any-0X4&h~vgM9TWik0cBk2|wn2N9H#w^%F*ogi#}5%}Cfa67G$Jb@RmP6IPCd zRU_fvNO(2xdojO@PQ$n5)O}q$s^(3JQ3clXoK#}?C#9? z;q^Bic9=nZh+0o}d}(5fgz00gxS9Qb#jl3p^_64EVrG9O*~S84??Xh``%s$6eycuV z^Q_2khTp1RFKI@?_IYZcG$Uo6lCPFXhsOWK{xci?5mL_I@cRGf(y`QI_Wv=b28p5z zgJeZ9qt+LQeePD0o-PSN-$-wtuBx$-sj1O^1D-!*YNopXu(7Jyfdi`hb{#U%14F%C ox_XBc83(A8(Y}3p2D|pD?lv+rH9JK0RP_%WGTvpz+GDc60V*{2YybcN literal 0 HcmV?d00001 diff --git a/win32/certmgr.dll_14_6170.ico b/win32/certmgr.dll_14_6170.ico new file mode 100644 index 0000000000000000000000000000000000000000..23571d786ff4ebfbf7d673e56ca4feaca2a11e81 GIT binary patch literal 10224 zcmeHNcUY8H)<4*jO`@Ab&8AthX(pCvA`nz;F=~PujWxxMEvC3Jny7rZieh9GBWuNy zC`JQTP*DL90TGZQ(h&p%23}qUhM~_e%*^?I_Z@~sW6D13^L*bQdx!Jha_+h3w)egF z{0>BR)QNic?uNJn$?b?15mC2p*8EF$M3dSR_ym3zI@*P3MF+vR<`;J)diG%(zc(F4 z`Nl_W{NA(}bq730^b*=c6EqSe^e6$k?j78T@JH_M)(B4|LGBb883_g}f5a?OApAs; zc-X>HBK)<6&XGi0T607Xl~I>U_kR^^O`m*WtpAa4WmPCGnRDn1hw8tN2* zythLzdmGpzRORHjR`B=FG8ou9)XB>=NZ~szSFwscoSd8-y$xQZ@OXrEy)pNDa-8o?&(1kYPc1%0^vz*xY=5GaC$VJ%uueflt1*|~hLfG!MS6Z=D2<-y zPGi2@MKf0IqxoO0BbPNt>HTjH(?r*BqJLbao~zQRqx)X!veB11tPh~azyFEad!UW) zE)#9OOb={{pg(U5A}8B&r`2^9LedlTEj!Q)AuAuEWv~`6Z+!{r+A%S{&T_M_$M6@T7p5A*6n=OTCS0?fq z^w5r*)NNNb_1~C84v_2PlR_^Z%%b7@GHK|pTyi{6Ky)~V=)`Su4ostAXY+{mmDBT{ z#q`%LjWqNCliiVGqT?k*KgozIh)$Og1tEQ`hDIDKC1-yPIUm*0@UUWf^@NFr9MhB2 z@fvy~&_vFskv?an*F#O@aLGhtwkFf8gE1Iu9*sVnNfZ3iX!OxMdgnq0O}dmzGeF-2 zq|@|(avB}TH0E3*jfDKza1%`oWm*;@(d*Zk-nmjtGp-iVv}|r)wb>h!cLK181Yi{cI*3 zIv-6(LSpII#aQyYc#TemCs07-bvkq9I$erMq@b8ox^OLn!V)tnJozR?q~y}~c~$gX zLN%?s)j+CSOh4o^`4v>qk*sQRFEY}ek~;c9$K+#V3Metrk#ZxQLO!U{NTHf$I&5OP z9ve@I@d=cl6i+cpS#&)qgQ9QTq?n9+%FW26?5sR0yq-WsDc4DJE1pVovZ+jcn_{vG z>DtXA$|)|Re7S;RD;ub&u#hzBVycuSDlU~tt*NA{3Jq0jE2*xgiYj!~R8?C`rOg(q ztE;01gPt0V#yih*>!$$EUP`J@YyPgpUvc?Bc*h!J#s2O zD)s{EB&c=THsOV_->h-_AGZe{iqmS<4X9AkaHch!I}_yMFxS;}wd@%{lnGuhQ$)2jfA{*(1vecsSPNWq+*N3|Mhu}Uo3W<=els4 z;4AWje0C2rl-Jic)LSeE?3ey6cV```Q56liKo3u?`I<0gLn@%)b$jvkt6vBYXc|FwhG?ww|8z>1mB$s2|Gl`?%L9PMEO18g=7alzh4ra%NJu_hFGuZX?uqwx9FLF2y3oLy1K?A>rJtlumIau_dt=zyExMHohcYD}J%X@hFQaiN*HX zncNPWm_{BNE}~zC_wsH!b?7we*rZ>wtR+(-(sNVy&-^tu%I8d;7WixI|6ljHmU~Le zy+rA=NVnu2W-X!NGrpz~vsWnh5pfq$3?i6~T*~;BPxdW`k_H_%jp5YtA zY3}X_TD?DzK0Xvd4~TPEg)<-LuX66DfdYb;d{&f{iruyn+6n zQbh|A4YVK$g!621x`n>JsV860E%f7wiQ`YGdlzIL%apI3u7!^+EBjU*` zzmEJXnkZBMQ2NteyfnO3W_Q9wnWz@ z9px03P;RM)3d$-dzpRq3)>Z`R>Qdv!SBYth0{I~qSGw^>l z1F)A`b$5AyoI17Uh#u@fo!jRB)Vpurjtc)#I}sj#r2Aj{ASQZr>^OvndJOLV#JF)H zKW_HS8MC|g>iNXOvqgTwv%}wXnC;TFTQ?Ua|J0!Nvu#1}pXxVs_U!Rv-ky%a$s*r| zFY-?gY5#_!y}kV~dwaou^3_q#w|}dpf%om6?musZ3ad!zwmOK?ESR|dn+xwcWa~IJ|>GledAS7CaC3uZf(43^OOg* zD~9EiEPnm1`>5`Yrlb|49xPrk_-e_lK26ZSxGj^9ezq3&B$v;BsYdt(}J5vl#X@ z!~SM@QrC*ikNUqScm+G>ErC7Fu(w$~?-hpajz0E$%_euhV%X^xz0WL*X7KJZaCVaNcwBQj*V!FouoCzzY}{1p{xe0MlUD^9);_foCu< z3-hLMt zHZTL9VBj818ni}K`SKHtl6F-dY_LWZ1?mLp$_PnBUB z$rfgL;f;z0U_eYeZg8hH7a5od14Ch29fmRh4aYDad$M`lxpYIb*`nw_8WykUzt{MM ze&84kJcEH9aYMaUF28wIE-aE{b!oW_dt1JZw9sv0i~L@6ksfzXCf^*!-I9R^Fz$Q| zEQe`*1l9s`fc`iIq&791tm8i(o}lO#`}X{ zydYmLE4nRLN~N+6z?&Gj8{f{)m*b*Eanj37M_y z51fj}hB1G#&cCs`zFt;i4m4Fdxu&5(*4EU>y4qT0KZ-q|Gg-<$jF$|+12NVptaZAT zPLu+W!9H-k$PQ=nn$*pfa;%x6Kd@!5i*Jfee?XMAPh$MQ*_5?U$|l zl13_#@=GQ8P@bmxlZ4X7aZ$yFNpWR*&)lk-oHC74r^(pVsz0bjzxbBg^k0ZeSNbHz zKfy1Pf#WHA(1<>pK+SBCM7k~AU4D1oR@YW8V)6c;k4sZ@iSM{gf7|g-^h;r2k&1pX zZ-RteZM9A+y_F*srKd_|1qD)Zc9v9{ds8X_6=kGJ>g-GjpbY9--*X{jBfP81I7A-! zo>f225S#vUvDQ9`@dN8*V4`>E2Sg$1O(v;0GadRYimU(WO zncpuqEBo)j{(V(dl@${9oTNisr74$6FlJ@!n0G1f7Utc$4m$8^>uQvGwKdgJZEZEu z8mSItz$T?e^i}8&OUhRC1Glw}|4)m)^C<<^%+u42JoC1RC+C^??FcjXaam{DxnsMo zs-i-w#`jCKTcgt&?xnE8jaM@qW{wMn^yhD ztmE%Kdcg|d`TQ32y>->ZE@>tnf8E4m;w|iO*2wTTSp1G2t!l(O)YzoQ8Z=1;Q*#R$ zB|XZ;{=oMEe1kQQbuu&?mAxS5zU};9PR>#E?>L6@@}Zsshiy)30RGOv<9X;s69aqa zAt5FneYuHe6qxz7tIPu?FKLQCd%CO1W1f zrJ~g9QvS6V2{^J6mtvm^-A3#O5sUc;rrn}HBhK9SdpaT*O$lbDy5GEqm&OB3dy3GZ(+^on;- z=#NUxQ}hG7=K+g$CBj$0@S*%B!N0-drhm@j>=ftMsmLS_j7sJ+(aC%kdl$Gpi|>kf zw}ay|I27+#SW*^Wx}MG9xYu32k;9Rxxu870lAgz*@oBu{SV+>Kh1;Uwzu<{e7xSgW zOyyp5_x%rkBZhB<;Tu!>eK-H#&5OI2&?Uy-XNtQIdr6Vf&47X85p_a`CMeeDTc^v3Pft`q5VT0L;s8l?%S_Ih>UUPfy&i;OkRqO&b!b zP1Lb39Ak>R)%IC>q5J6d7vZnrp5wj=rOy5DyZt~N2R!!dhX*vr zu$^Ex37e^HJzE<>J~BDWka)9z+mf(Bg#96G55@k1&0*tue{)Sh$NtOxXTo2=!1LL8&PoQJ&%p2*cz!DZ$8SxG_JF}F`W@E>jfcO1 z;U{3=`V3zJ+E@V$;?}*?ww3|6SMFSFI=`pSHOqD?`{b%8@p)ZAC|TKZ_Mxgf6U!| zu*1&x0NG7^X`(9T>#w4d9=kFoq-IR#FNbYV-@*jK(aM3p<` Fe*w$~lUe`( literal 0 HcmV?d00001 diff --git a/win32/versioninfo.rc.in b/win32/versioninfo.rc.in index fb34084007..246efa6d87 100644 --- a/win32/versioninfo.rc.in +++ b/win32/versioninfo.rc.in @@ -1,5 +1,27 @@ #include +#define IDC_STATIC -1 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 +#define IDI_UNLOCKED 103 +#define IDI_LOCKED 104 +#define IDI_READER_EMPTY 105 +#define IDI_CARD_INSERTED 106 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" +IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" +IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" +IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" +#endif + VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -35,4 +57,3 @@ BEGIN VALUE "Translation", 0x409, 1200 END END - diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index f17066612e..298bbbd13a 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -82,6 +82,8 @@ #define DEFAULT_PCSC_PROVIDER "@DEFAULT_PCSC_PROVIDER@" #endif +#define ENABLE_NOTIFY + #define SC_PKCS15_PROFILE_DIRECTORY "C:\\Program Files\\OpenSC Project\\OpenSC\\profiles" #define PATH_MAX FILENAME_MAX From ce3f27ff5467a27ccd2ed86e5377d5daf647d4c1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 19 Jun 2017 11:57:18 +0200 Subject: [PATCH 0029/4321] opensc-notify: notify for card events ... manually or in daemon mode fixes compilation in MinGW/Travis CI --- .travis.yml | 2 +- MacOSX/OpenSC_Notify.applescript | 2 + MacOSX/build-package.in | 2 + MacOSX/opensc-uninstall | 1 + configure.ac | 5 +- m4/ax_check_compile_flag.m4 | 74 ++ src/tools/Makefile.am | 35 +- src/tools/Makefile.mak | 10 +- src/tools/opensc-notify-cmdline.c | 1246 +++++++++++++++++++++++++++++ src/tools/opensc-notify-cmdline.h | 196 +++++ src/tools/opensc-notify.c | 203 ++++- src/tools/opensc-notify.ggo.in | 45 ++ src/ui/char_str_from_wchar.h | 46 ++ src/ui/invisible_window.h | 52 ++ src/ui/notify.c | 102 +-- win32/OpenSC.wxs.in | 4 + 16 files changed, 1941 insertions(+), 84 deletions(-) create mode 100644 MacOSX/OpenSC_Notify.applescript create mode 100644 m4/ax_check_compile_flag.m4 create mode 100644 src/tools/opensc-notify-cmdline.c create mode 100644 src/tools/opensc-notify-cmdline.h create mode 100644 src/tools/opensc-notify.ggo.in create mode 100644 src/ui/char_str_from_wchar.h create mode 100644 src/ui/invisible_window.h diff --git a/.travis.yml b/.travis.yml index 287349191b..e958bedad0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,7 +63,7 @@ before_script: fi - ./bootstrap - if [ -z "$HOST" ]; then - CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui; + CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui --disable-notify; else if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16; diff --git a/MacOSX/OpenSC_Notify.applescript b/MacOSX/OpenSC_Notify.applescript new file mode 100644 index 0000000000..d2910c226b --- /dev/null +++ b/MacOSX/OpenSC_Notify.applescript @@ -0,0 +1,2 @@ +do shell script "killall opensc-notify || true" +do shell script "nohup /Library/OpenSC/bin/opensc-notify > /dev/null 2>&1 &" diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 6ec5f6ba69..5724f9bfa0 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -108,6 +108,8 @@ if ! test -e NotificationProxy; then git clone http://github.com/frankmorgner/NotificationProxy.git fi xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ +mkdir -p "$BUILDPATH/target/Applications" +osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" # Prepare target root # The "UnInstaller" diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index 2dcfcec9e7..d4331a9ad9 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -16,6 +16,7 @@ rm -f /usr/local/lib/opensc-pkcs11.so rm -f /usr/local/lib/onepin-opensc-pkcs11.so # Remove installed files +rm -rf "/Applications/OpenSC Notify.app" rm -rf /Library/OpenSC rm -rf /Library/Security/tokend/OpenSC.tokend rm -rf /System/Library/Security/tokend/OpenSC.tokend diff --git a/configure.ac b/configure.ac index 06107417e2..9ebbb066d8 100644 --- a/configure.ac +++ b/configure.ac @@ -133,6 +133,9 @@ case "${host}" in ;; esac +AX_CHECK_COMPILE_FLAG(-Wno-error=unused-but-set-variable, [have_unused_but_set_variable="yes"], [have_unused_but_set_variable="no"], [-Werror -Wunknown-warning-option]) +AM_CONDITIONAL([HAVE_UNUSED_BUT_SET_VARIABLE], [test "${have_unused_but_set_variable}" = "yes"]) + AC_ARG_ENABLE( [strict], [AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@disabled@:>@])], @@ -384,7 +387,7 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([ \ getpass gettimeofday getline memset mkdir \ strdup strerror getopt_long getopt_long_only \ - strlcpy strlcat strnlen + strlcpy strlcat strnlen sigaction ]) AC_CHECK_SIZEOF(void *) if test "${ac_cv_sizeof_void_p}" = 8; then diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000000..dcabb92a14 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 9eb827b17b..3011e1685d 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -12,14 +12,16 @@ do_subst = $(SED) \ -e 's,[@]X509DIR[@],$(X509DIR),g' NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c +OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1 +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example -bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \ - pkcs11-tool cardos-tool eidenv openpgp-tool iasecc-tool opensc-notify +bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ + pkcs15-tool pkcs15-crypt pkcs11-tool \ + cardos-tool eidenv openpgp-tool iasecc-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool @@ -46,7 +48,6 @@ piv_tool_SOURCES = piv-tool.c util.c piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) opensc_explorer_SOURCES = opensc-explorer.c util.c opensc_explorer_LDADD = $(OPTIONAL_READLINE_LIBS) -opensc_notify_SOURCES = opensc-notify.c pkcs15_tool_SOURCES = pkcs15-tool.c util.c pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) pkcs11_tool_SOURCES = pkcs11-tool.c util.c @@ -101,6 +102,30 @@ npa-tool.1: --source='$(PACKAGE_STRING)' \ $(builddir)/npa-tool$(EXEEXT) +opensc_notify_SOURCES = opensc-notify.c $(OPENSC_NOTIFY_BUILT_SOURCES) +opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) +opensc_notify_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_NOTIFY_CFLAGS) +opensc_notify_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option + +opensc-notify.c: $(abs_builddir)/opensc-notify.ggo $(OPENSC_NOTIFY_BUILT_SOURCES) + +# We only want *cmdline* to be generated when they have explicitly been removed. +$(OPENSC_NOTIFY_BUILT_SOURCES): + $(MAKE) $(abs_builddir)/opensc-notify.ggo + $(GENGETOPT) --include-getopt --file-name=opensc-notify-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-notify.ggo + +$(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in + $(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@ + +# We only want opensc-notify.1 to be generated when it has explicitly been removed. +opensc-notify.1: + $(MAKE) opensc-notify$(EXEEXT) + $(HELP2MAN) \ + --output=$@ \ + --no-info \ + --source='$(PACKAGE_STRING)' \ + $(builddir)/opensc-notify$(EXEEXT) + if WIN32 opensc_tool_SOURCES += versioninfo-tools.rc piv_tool_SOURCES += versioninfo-tools.rc @@ -121,4 +146,4 @@ gids_tool_SOURCES += versioninfo-tools.rc endif clean-local: - rm -f $(abs_builddir)/npa-tool.ggo + rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index c3ef65c583..8e3be233f1 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -10,6 +10,10 @@ TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ $(PROGRAMS_OPENSSL) OBJECTS = util.obj npa-tool-cmdline.obj fread_to_eof.obj versioninfo-tools.res + +TARGET2 = opensc-notify.exe +OBJECT2 = opensc-notify-cmdline.obj versioninfo-tools.res + LIBS = $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\libopensc\opensc.lib \ @@ -17,11 +21,13 @@ LIBS = $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\common\libpkcs11.lib \ $(TOPDIR)\src\common\libscdl.lib -all: $(TARGETS) +all: $(TARGETS) $(TARGET2) $(TARGETS): $(OBJECTS) $(LIBS) +$(TARGET2): $(OBJECT2) $(LIBS) + .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c new file mode 100644 index 0000000000..bfdb3dd784 --- /dev/null +++ b/src/tools/opensc-notify-cmdline.c @@ -0,0 +1,1246 @@ +/* + File autogenerated by gengetopt version 2.22.6 + generated with the following command: + /usr/bin/gengetopt --include-getopt --file-name=opensc-notify-cmdline --output-dir=. + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + + +#include "opensc-notify-cmdline.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: opensc-notify [OPTIONS]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = "If no arguments are given, monitor smart card events and send the appropriate\nnotification."; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + "\n Mode: customized\n Send customized notifications.", + " -t, --title[=STRING] Title of the notification", + " -m, --message[=STRING] Main text of the notification", + "\n Mode: standard\n Manually send standard notifications.", + " -I, --notify-card-inserted See notify_card_inserted in opensc.conf\n (default=off)", + " -R, --notify-card-removed See notify_card_inserted in opensc.conf\n (default=off)", + " -G, --notify-pin-good See notify_pin_good in opensc.conf (default=off)", + " -B, --notify-pin-bad See notify_pin_bad in opensc.conf (default=off)", + "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + 0 +}; + +typedef enum {ARG_NO + , ARG_FLAG + , ARG_STRING +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->title_given = 0 ; + args_info->message_given = 0 ; + args_info->notify_card_inserted_given = 0 ; + args_info->notify_card_removed_given = 0 ; + args_info->notify_pin_good_given = 0 ; + args_info->notify_pin_bad_given = 0 ; + args_info->customized_mode_counter = 0 ; + args_info->daemon_mode_counter = 0 ; + args_info->standard_mode_counter = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->title_arg = NULL; + args_info->title_orig = NULL; + args_info->message_arg = NULL; + args_info->message_orig = NULL; + args_info->notify_card_inserted_flag = 0; + args_info->notify_card_removed_flag = 0; + args_info->notify_pin_good_flag = 0; + args_info->notify_pin_bad_flag = 0; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->title_help = gengetopt_args_info_help[3] ; + args_info->message_help = gengetopt_args_info_help[4] ; + args_info->notify_card_inserted_help = gengetopt_args_info_help[6] ; + args_info->notify_card_removed_help = gengetopt_args_info_help[7] ; + args_info->notify_pin_good_help = gengetopt_args_info_help[8] ; + args_info->notify_pin_bad_help = gengetopt_args_info_help[9] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + free_string_field (&(args_info->title_arg)); + free_string_field (&(args_info->title_orig)); + free_string_field (&(args_info->message_arg)); + free_string_field (&(args_info->message_orig)); + + + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->title_given) + write_into_file(outfile, "title", args_info->title_orig, 0); + if (args_info->message_given) + write_into_file(outfile, "message", args_info->message_orig, 0); + if (args_info->notify_card_inserted_given) + write_into_file(outfile, "notify-card-inserted", 0, 0 ); + if (args_info->notify_card_removed_given) + write_into_file(outfile, "notify-card-removed", 0, 0 ); + if (args_info->notify_pin_good_given) + write_into_file(outfile, "notify-pin-good", 0, 0 ); + if (args_info->notify_pin_bad_given) + write_into_file(outfile, "notify-pin-bad", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + FIX_UNUSED (args_info); + FIX_UNUSED (prog_name); + return EXIT_SUCCESS; +} + +/* + * Extracted from the glibc source tree, version 2.3.6 + * + * Licensed under the GPL as per the whole glibc source tree. + * + * This file was modified so that getopt_long can be called + * many times without risking previous memory to be spoiled. + * + * Modified by Andre Noll and Lorenzo Bettini for use in + * GNU gengetopt generated files. + * + */ + +/* + * we must include anything we need since this file is not thought to be + * inserted in a file already using getopt.h + * + * Lorenzo + */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. +*/ +/* + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `custom_optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +/* Names for the values of the `has_arg' field of `struct option'. */ +#ifndef no_argument +#define no_argument 0 +#endif + +#ifndef required_argument +#define required_argument 1 +#endif + +#ifndef optional_argument +#define optional_argument 2 +#endif + +struct custom_getopt_data { + /* + * These have exactly the same meaning as the corresponding global variables, + * except that they are used for the reentrant versions of getopt. + */ + int custom_optind; + int custom_opterr; + int custom_optopt; + char *custom_optarg; + + /* True if the internal members have been initialized. */ + int initialized; + + /* + * The next char to be scanned in the option-element in which the last option + * character we returned was found. This allows us to pick up the scan where + * we left off. If this is zero, or a null string, it means resume the scan by + * advancing to the next ARGV-element. + */ + char *nextchar; + + /* + * Describe the part of ARGV that contains non-options that have been skipped. + * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is + * the index after the last of them. + */ + int first_nonopt; + int last_nonopt; +}; + +/* + * the variables optarg, optind, opterr and optopt are renamed with + * the custom_ prefix so that they don't interfere with getopt ones. + * + * Moreover they're static so they are visible only from within the + * file where this very file will be included. + */ + +/* + * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an + * option that takes an argument, the argument value is returned here. + */ +static char *custom_optarg; + +/* + * Index in ARGV of the next element to be scanned. This is used for + * communication to and from the caller and for communication between + * successive calls to `custom_getopt'. + * + * On entry to `custom_getopt', 1 means this is the first call; initialize. + * + * When `custom_getopt' returns -1, this is the index of the first of the non-option + * elements that the caller should itself scan. + * + * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV + * has been scanned so far. + * + * 1003.2 says this must be 1 before any call. + */ +static int custom_optind = 1; + +/* + * Callers store zero here to inhibit the error message for unrecognized + * options. + */ +static int custom_opterr = 1; + +/* + * Set to an option character which was unrecognized. This must be initialized + * on some systems to avoid linking in the system's own getopt implementation. + */ +static int custom_optopt = '?'; + +/* + * Exchange two adjacent subsequences of ARGV. One subsequence is elements + * [first_nonopt,last_nonopt) which contains all the non-options that have been + * skipped so far. The other is elements [last_nonopt,custom_optind), which contains + * all the options processed since those non-options were skipped. + * `first_nonopt' and `last_nonopt' are relocated so that they describe the new + * indices of the non-options in ARGV after they are moved. + */ +static void exchange(char **argv, struct custom_getopt_data *d) +{ + int bottom = d->first_nonopt; + int middle = d->last_nonopt; + int top = d->custom_optind; + char *tem; + + /* + * Exchange the shorter segment with the far end of the longer segment. + * That puts the shorter segment into the right place. It leaves the + * longer segment in the right place overall, but it consists of two + * parts that need to be swapped next. + */ + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = + argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + /* Update records for the slots the non-options now occupy. */ + d->first_nonopt += (d->custom_optind - d->last_nonopt); + d->last_nonopt = d->custom_optind; +} + +/* Initialize the internal data when the first call is made. */ +static void custom_getopt_initialize(struct custom_getopt_data *d) +{ + /* + * Start processing options with ARGV-element 1 (since ARGV-element 0 + * is the program name); the sequence of previously skipped non-option + * ARGV-elements is empty. + */ + d->first_nonopt = d->last_nonopt = d->custom_optind; + d->nextchar = NULL; + d->initialized = 1; +} + +#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') + +/* return: zero: continue, nonzero: return given value to user */ +static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, + struct custom_getopt_data *d) +{ + /* + * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been + * moved back by the user (who may also have changed the arguments). + */ + if (d->last_nonopt > d->custom_optind) + d->last_nonopt = d->custom_optind; + if (d->first_nonopt > d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * If we have just processed some options following some + * non-options, exchange them so that the options come first. + */ + if (d->first_nonopt != d->last_nonopt && + d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->last_nonopt != d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * Skip any additional non-options and extend the range of + * non-options previously skipped. + */ + while (d->custom_optind < argc && NONOPTION_P) + d->custom_optind++; + d->last_nonopt = d->custom_optind; + /* + * The special ARGV-element `--' means premature end of options. Skip + * it like a null option, then exchange with previous non-options as if + * it were an option, then skip everything else like a non-option. + */ + if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { + d->custom_optind++; + if (d->first_nonopt != d->last_nonopt + && d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->first_nonopt == d->last_nonopt) + d->first_nonopt = d->custom_optind; + d->last_nonopt = argc; + d->custom_optind = argc; + } + /* + * If we have done all the ARGV-elements, stop the scan and back over + * any non-options that we skipped and permuted. + */ + if (d->custom_optind == argc) { + /* + * Set the next-arg-index to point at the non-options that we + * previously skipped, so the caller will digest them. + */ + if (d->first_nonopt != d->last_nonopt) + d->custom_optind = d->first_nonopt; + return -1; + } + /* + * If we have come to a non-option and did not permute it, either stop + * the scan or describe it to the caller and pass it by. + */ + if (NONOPTION_P) { + d->custom_optarg = argv[d->custom_optind++]; + return 1; + } + /* + * We have found another option-ARGV-element. Skip the initial + * punctuation. + */ + d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); + return 0; +} + +/* + * Check whether the ARGV-element is a long option. + * + * If there's a long option "fubar" and the ARGV-element is "-fu", consider + * that an abbreviation of the long option, just like "--fu", and not "-f" with + * arg "u". + * + * This distinction seems to be the most useful approach. + * + */ +static int check_long_opt(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int print_errors, struct custom_getopt_data *d) +{ + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { + if ((unsigned int) (nameend - d->nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else if (pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[d->custom_optind]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optind++; + d->custom_optopt = 0; + return '?'; + } + if (pfound) { + option_index = indfound; + d->custom_optind++; + if (*nameend) { + if (pfound->has_arg != no_argument) + d->custom_optarg = nameend + 1; + else { + if (print_errors) { + if (argv[d->custom_optind - 1][1] == '-') { + /* --option */ + fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + } else { + /* +option or -option */ + fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[d->custom_optind - 1][0], pfound->name); + } + + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == required_argument) { + if (d->custom_optind < argc) + d->custom_optarg = argv[d->custom_optind++]; + else { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], + argv[d->custom_optind - 1]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->nextchar += strlen(d->nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* + * Can't find it as a long option. If this is not getopt_long_only, or + * the option starts with '--' or is not a valid short option, then + * it's an error. Otherwise interpret it as a short option. + */ + if (print_errors) { + if (argv[d->custom_optind][1] == '-') { + /* --option */ + fprintf(stderr, + "%s: unrecognized option `--%s'\n", + argv[0], d->nextchar); + } else { + /* +option or -option */ + fprintf(stderr, + "%s: unrecognized option `%c%s'\n", + argv[0], argv[d->custom_optind][0], + d->nextchar); + } + } + d->nextchar = (char *) ""; + d->custom_optind++; + d->custom_optopt = 0; + return '?'; +} + +static int check_short_opt(int argc, char *const *argv, const char *optstring, + int print_errors, struct custom_getopt_data *d) +{ + char c = *d->nextchar++; + const char *temp = strchr(optstring, c); + + /* Increment `custom_optind' when we start to process its last character. */ + if (*d->nextchar == '\0') + ++d->custom_optind; + if (!temp || c == ':') { + if (print_errors) + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + + d->custom_optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + d->custom_optind++; + } else + d->custom_optarg = NULL; + d->nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + /* + * If we end this ARGV-element by taking the + * rest as an arg, we must advance to the next + * element now. + */ + d->custom_optind++; + } else if (d->custom_optind == argc) { + if (print_errors) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + d->custom_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* + * We already incremented `custom_optind' once; + * increment it again when taking next ARGV-elt + * as argument. + */ + d->custom_optarg = argv[d->custom_optind++]; + d->nextchar = NULL; + } + } + return c; +} + +/* + * Scan elements of ARGV for option characters given in OPTSTRING. + * + * If an element of ARGV starts with '-', and is not exactly "-" or "--", + * then it is an option element. The characters of this element + * (aside from the initial '-') are option characters. If `getopt' + * is called repeatedly, it returns successively each of the option characters + * from each of the option elements. + * + * If `getopt' finds another option character, it returns that character, + * updating `custom_optind' and `nextchar' so that the next call to `getopt' can + * resume the scan with the following option character or ARGV-element. + * + * If there are no more option characters, `getopt' returns -1. + * Then `custom_optind' is the index in ARGV of the first ARGV-element + * that is not an option. (The ARGV-elements have been permuted + * so that those that are not options now come last.) + * + * OPTSTRING is a string containing the legitimate option characters. + * If an option character is seen that is not listed in OPTSTRING, + * return '?' after printing an error message. If you set `custom_opterr' to + * zero, the error message is suppressed but we still return '?'. + * + * If a char in OPTSTRING is followed by a colon, that means it wants an arg, + * so the following text in the same ARGV-element, or the text of the following + * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that + * wants an optional arg; if there is text in the current ARGV-element, + * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. + * + * If OPTSTRING starts with `-' or `+', it requests different methods of + * handling the non-option ARGV-elements. + * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + * + * Long-named options begin with `--' instead of `-'. + * Their names may be abbreviated as long as the abbreviation is unique + * or is an exact match for some defined option. If they have an + * argument, it follows the option name in the same ARGV-element, separated + * from the option name by a `=', or else the in next ARGV-element. + * When `getopt' finds a long-named option, it returns 0 if that option's + * `flag' field is nonzero, the value of the option's `val' field + * if the `flag' field is zero. + * + * The elements of ARGV aren't really const, because we permute them. + * But we pretend they're const in the prototype to be compatible + * with other systems. + * + * LONGOPTS is a vector of `struct option' terminated by an + * element containing a name which is zero. + * + * LONGIND returns the index in LONGOPT of the long-named option found. + * It is only valid when a long-named option has been found by the most + * recent call. + * + * Return the option character from OPTS just read. Return -1 when there are + * no more options. For unrecognized options, or options missing arguments, + * `custom_optopt' is set to the option letter, and '?' is returned. + * + * The OPTS string is a list of characters which are recognized option letters, + * optionally followed by colons, specifying that that letter takes an + * argument, to be placed in `custom_optarg'. + * + * If a letter in OPTS is followed by two colons, its argument is optional. + * This behavior is specific to the GNU `getopt'. + * + * The argument `--' causes premature termination of argument scanning, + * explicitly telling `getopt' that there are no more options. If OPTS begins + * with `--', then non-option arguments are treated as arguments to the option + * '\0'. This behavior is specific to the GNU `getopt'. + */ + +static int getopt_internal_r(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + struct custom_getopt_data *d) +{ + int ret, print_errors = d->custom_opterr; + + if (optstring[0] == ':') + print_errors = 0; + if (argc < 1) + return -1; + d->custom_optarg = NULL; + + /* + * This is a big difference with GNU getopt, since optind == 0 + * means initialization while here 1 means first call. + */ + if (d->custom_optind == 0 || !d->initialized) { + if (d->custom_optind == 0) + d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ + custom_getopt_initialize(d); + } + if (d->nextchar == NULL || *d->nextchar == '\0') { + ret = shuffle_argv(argc, argv, longopts, d); + if (ret) + return ret; + } + if (longopts && (argv[d->custom_optind][1] == '-' )) + return check_long_opt(argc, argv, optstring, longopts, + longind, print_errors, d); + return check_short_opt(argc, argv, optstring, print_errors, d); +} + +static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind) +{ + int result; + /* Keep a global copy of all internal members of d */ + static struct custom_getopt_data d; + + d.custom_optind = custom_optind; + d.custom_opterr = custom_opterr; + result = getopt_internal_r(argc, argv, optstring, longopts, + longind, &d); + custom_optind = d.custom_optind; + custom_optarg = d.custom_optarg; + custom_optopt = d.custom_optopt; + return result; +} + +static int custom_getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return custom_getopt_internal(argc, argv, options, long_options, + opt_index); +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + FIX_UNUSED (default_value); + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_FLAG: + *((int *)field) = !*((int *)field); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + case ARG_FLAG: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +static int check_modes( + int given1[], const char *options1[], + int given2[], const char *options2[]) +{ + int i = 0, j = 0, errors = 0; + + while (given1[i] >= 0) { + if (given1[i]) { + while (given2[j] >= 0) { + if (given2[j]) { + ++errors; + fprintf(stderr, "%s: option %s conflicts with option %s\n", + package_name, options1[i], options2[j]); + } + ++j; + } + } + ++i; + } + + return errors; +} + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + char *optarg; + int optind; + int opterr; + int optopt; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "title", 2, NULL, 't' }, + { "message", 2, NULL, 'm' }, + { "notify-card-inserted", 0, NULL, 'I' }, + { "notify-card-removed", 0, NULL, 'R' }, + { "notify-pin-good", 0, NULL, 'G' }, + { "notify-pin-bad", 0, NULL, 'B' }, + { 0, 0, 0, 0 } + }; + + custom_optarg = optarg; + custom_optind = optind; + custom_opterr = opterr; + custom_optopt = optopt; + + c = custom_getopt_long (argc, argv, "hVt::m::IRGB", long_options, &option_index); + + optarg = custom_optarg; + optind = custom_optind; + opterr = custom_opterr; + optopt = custom_optopt; + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 't': /* Title of the notification. */ + args_info->customized_mode_counter += 1; + + + if (update_arg( (void *)&(args_info->title_arg), + &(args_info->title_orig), &(args_info->title_given), + &(local_args_info.title_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "title", 't', + additional_error)) + goto failure; + + break; + case 'm': /* Main text of the notification. */ + args_info->customized_mode_counter += 1; + + + if (update_arg( (void *)&(args_info->message_arg), + &(args_info->message_orig), &(args_info->message_given), + &(local_args_info.message_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "message", 'm', + additional_error)) + goto failure; + + break; + case 'I': /* See notify_card_inserted in opensc.conf. */ + args_info->standard_mode_counter += 1; + + + if (update_arg((void *)&(args_info->notify_card_inserted_flag), 0, &(args_info->notify_card_inserted_given), + &(local_args_info.notify_card_inserted_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "notify-card-inserted", 'I', + additional_error)) + goto failure; + + break; + case 'R': /* See notify_card_inserted in opensc.conf. */ + args_info->standard_mode_counter += 1; + + + if (update_arg((void *)&(args_info->notify_card_removed_flag), 0, &(args_info->notify_card_removed_given), + &(local_args_info.notify_card_removed_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "notify-card-removed", 'R', + additional_error)) + goto failure; + + break; + case 'G': /* See notify_pin_good in opensc.conf. */ + args_info->standard_mode_counter += 1; + + + if (update_arg((void *)&(args_info->notify_pin_good_flag), 0, &(args_info->notify_pin_good_given), + &(local_args_info.notify_pin_good_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "notify-pin-good", 'G', + additional_error)) + goto failure; + + break; + case 'B': /* See notify_pin_bad in opensc.conf. */ + args_info->standard_mode_counter += 1; + + + if (update_arg((void *)&(args_info->notify_pin_bad_flag), 0, &(args_info->notify_pin_bad_given), + &(local_args_info.notify_pin_bad_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "notify-pin-bad", 'B', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + if (args_info->customized_mode_counter && args_info->standard_mode_counter) { + int customized_given[] = {args_info->title_given, args_info->message_given, -1}; + const char *customized_desc[] = {"--title", "--message", 0}; + int standard_given[] = {args_info->notify_card_inserted_given, args_info->notify_card_removed_given, args_info->notify_pin_good_given, args_info->notify_pin_bad_given, -1}; + const char *standard_desc[] = {"--notify-card-inserted", "--notify-card-removed", "--notify-pin-good", "--notify-pin-bad", 0}; + error_occurred += check_modes(customized_given, customized_desc, standard_given, standard_desc); + } + + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/src/tools/opensc-notify-cmdline.h b/src/tools/opensc-notify-cmdline.h new file mode 100644 index 0000000000..f0783d6281 --- /dev/null +++ b/src/tools/opensc-notify-cmdline.h @@ -0,0 +1,196 @@ +/** @file opensc-notify-cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.6 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef OPENSC_NOTIFY_CMDLINE_H +#define OPENSC_NOTIFY_CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "opensc-notify" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "opensc-notify" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * title_arg; /**< @brief Title of the notification. */ + char * title_orig; /**< @brief Title of the notification original value given at command line. */ + const char *title_help; /**< @brief Title of the notification help description. */ + char * message_arg; /**< @brief Main text of the notification. */ + char * message_orig; /**< @brief Main text of the notification original value given at command line. */ + const char *message_help; /**< @brief Main text of the notification help description. */ + int notify_card_inserted_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */ + const char *notify_card_inserted_help; /**< @brief See notify_card_inserted in opensc.conf help description. */ + int notify_card_removed_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */ + const char *notify_card_removed_help; /**< @brief See notify_card_inserted in opensc.conf help description. */ + int notify_pin_good_flag; /**< @brief See notify_pin_good in opensc.conf (default=off). */ + const char *notify_pin_good_help; /**< @brief See notify_pin_good in opensc.conf help description. */ + int notify_pin_bad_flag; /**< @brief See notify_pin_bad in opensc.conf (default=off). */ + const char *notify_pin_bad_help; /**< @brief See notify_pin_bad in opensc.conf help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int title_given ; /**< @brief Whether title was given. */ + unsigned int message_given ; /**< @brief Whether message was given. */ + unsigned int notify_card_inserted_given ; /**< @brief Whether notify-card-inserted was given. */ + unsigned int notify_card_removed_given ; /**< @brief Whether notify-card-removed was given. */ + unsigned int notify_pin_good_given ; /**< @brief Whether notify-pin-good was given. */ + unsigned int notify_pin_bad_given ; /**< @brief Whether notify-pin-bad was given. */ + + int customized_mode_counter; /**< @brief Counter for mode customized */ + int daemon_mode_counter; /**< @brief Counter for mode daemon */ + int standard_mode_counter; /**< @brief Counter for mode standard */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* OPENSC_NOTIFY_CMDLINE_H */ diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 18a9ce355b..91f9b91284 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -21,8 +21,24 @@ #include "config.h" #endif +#include "libopensc/log.h" +#include "opensc-notify-cmdline.h" #include "ui/notify.h" +#include #include +#include +#include + +static int run_daemon = 0; +static struct sc_context *ctx = NULL; + +void stop_daemon(int signo) +{ +#ifdef PCSCLITE_GOOD + sc_cancel(ctx); +#endif + run_daemon = 0; +} #ifndef _WIN32 #include @@ -41,30 +57,183 @@ void Sleep(unsigned int Milliseconds) nanosleep(&req , &rem); } +#else +#include "ui/invisible_window.h" +static HINSTANCE g_hInstance = NULL; + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_CLOSE) { + sc_cancel(ctx); + run_daemon = 0; + return TRUE; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} #endif +void notify_daemon(void) +{ + int r; + const unsigned int event_mask = SC_EVENT_CARD_EVENTS; + unsigned int event; + struct sc_reader *event_reader = NULL; + size_t error_count = 0; + /* timeout adjusted to the maximum response time for WM_CLOSE in case + * canceling doesn't work */ + const int timeout = 20000; + struct sc_atr old_atr; + void *reader_states = NULL; +#ifdef _WIN32 + LPCTSTR lpszClassName = "OPENSC_NOTIFY_CLASS"; + HWND hwnd = create_invisible_window(lpszClassName, WndProc, g_hInstance); +#elif HAVE_SIGACTION + struct sigaction new_sig, old_sig; + + /* Register signal handlers */ + new_sig.sa_handler = stop_daemon; + sigemptyset(&new_sig.sa_mask); + new_sig.sa_flags = SA_RESTART; + if ((sigaction(SIGINT, &new_sig, &old_sig) < 0) + || (sigaction(SIGTERM, &new_sig, &old_sig) < 0)) { + fprintf(stderr, "Failed to create signal handler: %s", strerror(errno)); + return; + } +#endif + + r = sc_establish_context(&ctx, "opensc-notify"); + if (r < 0 || !ctx) { + fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); + return; + } + + while (run_daemon) { + if (0 > sc_wait_for_event(ctx, event_mask, &event_reader, + &event, timeout, &reader_states)) { + error_count++; + continue; + } + + error_count = 0; + + if (event & SC_EVENT_CARD_REMOVED) { + sc_notify_id(ctx, &old_atr, NULL, NOTIFY_CARD_REMOVED); + } + if (event & SC_EVENT_CARD_INSERTED) { + if (event_reader) { + /* FIXME `pcsc_wait_for_event` has all the information that's + * requested again with `pcsc_detect_card_presence`, but it + * doesn't use the ATR, for example, to refresh the reader's + * attributes. To get the ATR we need to call + * sc_detect_card_presence. Eventually this should be fixed. */ + sc_detect_card_presence(event_reader); + memcpy(old_atr.value, event_reader->atr.value, + event_reader->atr.len); + old_atr.len = event_reader->atr.len; + } else { + old_atr.len = 0; + } + sc_notify_id(ctx, old_atr.len ? &old_atr : NULL, NULL, + NOTIFY_CARD_INSERTED); + } + } + + if (ctx) { + /* free `reader_states` */ + sc_wait_for_event(ctx, 0, NULL, NULL, 0, &reader_states); + reader_states = NULL; + sc_release_context(ctx); + ctx = NULL; + } +#ifdef _WIN32 + delete_invisible_window(hwnd, lpszClassName, g_hInstance); +#endif +} + +#ifdef _WIN32 +#include "ui/char_str_from_wchar.h" +#include + +/* This application shall be executable without a console. Therefor we're + * creating a windows application that requires `WinMain()` rather than + * `main()` as entry point. As benefit, we can properly handle `WM_CLOSE`. */ +int WINAPI +WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + LPWSTR *wargv = NULL; + char **argv = NULL; + int argc = 0, i; + struct gengetopt_args_info cmdline; + + wargv = CommandLineToArgvW(GetCommandLineW(), &argc); + if (wargv == NULL) { + return 1; + } + + argv = LocalAlloc(0, (sizeof *argv) * argc); + if (argv == NULL) { + goto err; + } + for (i = 0; i < argc; i++) { + argv[i] = char_str_from_wchar(wargv[i]); + } + + g_hInstance = hInstance; + +#else int main (int argc, char **argv) { - const char *title = NULL, *text = NULL; - switch (argc) { - case 3: - text = argv[2]; - /* fall through */ - case 2: - title = argv[1]; - /* fall through */ - case 1: - break; - - default: - fprintf(stderr, "Usage: opensc-notify [title [text]]"); - return 1; - } + struct gengetopt_args_info cmdline; +#endif + + if (cmdline_parser(argc, argv, &cmdline) != 0) + goto err; + sc_notify_init(); - sc_notify(title, text); - Sleep(250); + + if (cmdline.customized_mode_counter) { + sc_notify(cmdline.title_arg, cmdline.message_arg); + } + + if (cmdline.standard_mode_counter) { + if (cmdline.notify_card_inserted_flag) { + sc_notify_id(NULL, NULL, NULL, NOTIFY_CARD_INSERTED); + } + if (cmdline.notify_card_removed_flag) { + sc_notify_id(NULL, NULL, NULL, NOTIFY_CARD_REMOVED); + } + if (cmdline.notify_pin_good_flag) { + sc_notify_id(NULL, NULL, NULL, NOTIFY_PIN_GOOD); + } + if (cmdline.notify_pin_bad_flag) { + sc_notify_id(NULL, NULL, NULL, NOTIFY_PIN_BAD); + } + } + + if ((!cmdline.customized_mode_counter && !cmdline.standard_mode_counter) + || cmdline.daemon_mode_counter) { + run_daemon = 1; + notify_daemon(); + } else { + /* give the notification process some time to spawn */ + Sleep(100); + } + sc_notify_close(); + cmdline_parser_free (&cmdline); +err: +#ifdef _WIN32 + if (argv) { + for (i = 0; i <= argc; i++) { + LocalFree(argv[i]); + } + LocalFree(argv); + } + LocalFree(wargv); +#endif + return 0; } diff --git a/src/tools/opensc-notify.ggo.in b/src/tools/opensc-notify.ggo.in new file mode 100644 index 0000000000..f419835aae --- /dev/null +++ b/src/tools/opensc-notify.ggo.in @@ -0,0 +1,45 @@ +package "opensc-notify" +purpose "@PACKAGE_SUMMARY@" +description "If no arguments are given, monitor smart card events and send the appropriate notification." + +defmode "daemon" + modedesc="Monitor smart card events to send notifications." +defmode "standard" + modedesc="Manually send standard notifications." +defmode "customized" + modedesc="Send customized notifications." + +modeoption "title" t + "Title of the notification" + string + mode="customized" + argoptional + optional +modeoption "message" m + "Main text of the notification" + string + mode="customized" + argoptional + optional + +modeoption "notify-card-inserted" I + "See notify_card_inserted in opensc.conf" + flag off + mode="standard" +modeoption "notify-card-removed" R + "See notify_card_inserted in opensc.conf" + flag off + mode="standard" +modeoption "notify-pin-good" G + "See notify_pin_good in opensc.conf" + flag off + mode="standard" +modeoption "notify-pin-bad" B + "See notify_pin_bad in opensc.conf" + flag off + mode="standard" + +text " +Report bugs to @PACKAGE_BUGREPORT@ + +Written by Frank Morgner " diff --git a/src/ui/char_str_from_wchar.h b/src/ui/char_str_from_wchar.h new file mode 100644 index 0000000000..270251c0dd --- /dev/null +++ b/src/ui/char_str_from_wchar.h @@ -0,0 +1,46 @@ +/* + * char_str_from_wchar.h: Conversion from wide string to string + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +static char *char_str_from_wchar(const WCHAR *in) +{ + char *out; + int out_len; + + if (!in) + return NULL; + + out_len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL); + if (0 >= out_len) + return NULL; + + out = LocalAlloc(0, (sizeof *out) * out_len); + if (!out) + return NULL; + + out_len = WideCharToMultiByte(CP_UTF8, 0, in, -1, out, out_len, NULL, NULL); + if (out_len == 0xFFFD || 0 >= out_len) { + LocalFree(out); + return NULL; + } + + return out; +} diff --git a/src/ui/invisible_window.h b/src/ui/invisible_window.h new file mode 100644 index 0000000000..f75056c245 --- /dev/null +++ b/src/ui/invisible_window.h @@ -0,0 +1,52 @@ +/* + * invisible_window.h: Create invisible Window + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +HWND create_invisible_window(LPCTSTR lpszClassName, + LRESULT (CALLBACK* WndProc)(HWND, UINT, WPARAM, LPARAM), + HINSTANCE hInstance) +{ + HWND hWnd = NULL; + WNDCLASSEX wx = {0}; + + //Register Window class + wx.cbSize = sizeof(WNDCLASSEX); + wx.lpfnWndProc = WndProc; + wx.hInstance = hInstance; + wx.lpszClassName = lpszClassName; + if (RegisterClassEx(&wx)) { + /* create window */ + hWnd = CreateWindowEx(0, lpszClassName, lpszClassName, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, NULL, NULL ); + } + + return hWnd; +} + +static BOOL delete_invisible_window(HWND hWnd, LPCTSTR lpszClassName, + HINSTANCE hInstance) +{ + BOOL r; + r = DestroyWindow(hWnd); + r &= UnregisterClass(lpszClassName, hInstance); + + return r; +} diff --git a/src/ui/notify.c b/src/ui/notify.c index faad0af824..fff0f6b54c 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -65,6 +65,7 @@ void sc_notify_close(void) #if defined(ENABLE_NOTIFY) && defined(_WIN32) +#include "invisible_window.h" #include "wchar_from_char_str.h" #include @@ -72,13 +73,14 @@ static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8, 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}}; HINSTANCE sc_notify_instance = NULL; HWND hwndNotification = NULL; +BOOL delete_icon = TRUE; #define IDI_SMARTCARD 102 #define IDI_UNLOCKED 103 #define IDI_LOCKED 104 #define IDI_READER_EMPTY 105 #define IDI_CARD_INSERTED 106 UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; -BOOL RestoreTooltip(void); +static BOOL RestoreTooltip(); // we need commctrl v6 for LoadIconMetric() #include @@ -100,54 +102,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(hwnd, message, wParam, lParam); } -static const char* class_name = "DUMMY_CLASS"; -static const char* window_name = "DUMMY_WINDOW"; - -static BOOL create_invisible_window(void) -{ - if (!hwndNotification) { - //Register Window class - WNDCLASSEX wx = {0}; - wx.cbSize = sizeof(WNDCLASSEX); - wx.lpfnWndProc = WndProc; // function which will handle messages - wx.hInstance = sc_notify_instance; - wx.lpszClassName = class_name; - if (!RegisterClassEx(&wx)) { - return FALSE; - } - /* create window */ - hwndNotification = CreateWindowEx(0, class_name, window_name, - 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); - } - - if (hwndNotification) { - return TRUE; - } - - return FALSE; -} - -static BOOL delete_invisible_window(void) -{ - BOOL r; - r = DestroyWindow(hwndNotification); - r &= UnregisterClass(class_name, sc_notify_instance); - - hwndNotification = NULL; - - return r; -} +static const char* lpszClassName = "NOTIFY_CLASS"; static BOOL AddNotificationIcon(void) { - NOTIFYICONDATA nid = {sizeof(nid)}; + NOTIFYICONDATA nid; TCHAR path[MAX_PATH]={0}; BOOL r; - if (!create_invisible_window()) { - return FALSE; - } - + memset(&nid, 0, sizeof nid); + nid.cbSize = sizeof nid; nid.hWnd = hwndNotification; // add the icon, setting the icon, tooltip, and callback message. // the icon will be identified with the GUID @@ -156,7 +120,18 @@ static BOOL AddNotificationIcon(void) nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK; LoadIconMetric(sc_notify_instance, MAKEINTRESOURCEW(IDI_SMARTCARD), LIM_SMALL, &nid.hIcon); if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { - strcpy_s(nid.szTip, ARRAYSIZE(nid.szTip), path); + const char *basename = strrchr(path, '\\'); + if (basename) { + basename++; + if (0 != strcmp(basename, "opensc-notify.exe")) { + /* Allow creation of sytem tray icon only for + * "opensc-notify.exe" to avoid creation of the same icon by + * multiple processes. */ + delete_icon = FALSE; + return FALSE; + } + } + strlcpy(nid.szTip, path, ARRAYSIZE(nid.szTip)); } else { strcpy(nid.szTip, PACKAGE_NAME); } @@ -166,19 +141,32 @@ static BOOL AddNotificationIcon(void) nid.uVersion = NOTIFYICON_VERSION_4; r &= Shell_NotifyIcon(NIM_SETVERSION, &nid); + hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance); + if (!hwndNotification) { + r = FALSE; + } + return r; } static BOOL DeleteNotificationIcon(void) { BOOL r; - NOTIFYICONDATA nid = {sizeof(nid)}; + NOTIFYICONDATA nid; + if (!delete_icon) { + return FALSE; + } + + memset(&nid, 0, sizeof nid); + nid.cbSize = sizeof nid; nid.uFlags = NIF_GUID; nid.guidItem = myGUID; r = Shell_NotifyIcon(NIM_DELETE, &nid); - r &= delete_invisible_window(); + + r &= delete_invisible_window(hwndNotification, lpszClassName, + sc_notify_instance); return r; } @@ -186,8 +174,10 @@ static BOOL DeleteNotificationIcon(void) static BOOL RestoreTooltip() { // After the balloon is dismissed, restore the tooltip. - NOTIFYICONDATA nid = {sizeof(nid)}; + NOTIFYICONDATA nid; + memset(&nid, 0, sizeof nid); + nid.cbSize = sizeof nid; nid.uFlags = NIF_SHOWTIP | NIF_GUID; nid.guidItem = myGUID; @@ -197,17 +187,19 @@ static BOOL RestoreTooltip() static void notify_shell(struct sc_context *ctx, const char *title, const char *text, WORD icon) { - NOTIFYICONDATA nid = {sizeof(nid)}; + NOTIFYICONDATA nid; + memset(&nid, 0, sizeof nid); + nid.cbSize = sizeof nid; nid.uFlags = NIF_GUID; nid.guidItem = myGUID; if (title) { - strcpy_s(nid.szInfoTitle, ARRAYSIZE(nid.szInfoTitle), title); + strlcpy(nid.szInfoTitle, title, ARRAYSIZE(nid.szInfoTitle)); } if (text) { nid.uFlags |= NIF_INFO; - strcpy_s(nid.szInfo, ARRAYSIZE(nid.szInfo), text); + strlcpy(nid.szInfo, text, ARRAYSIZE(nid.szInfo)); } if (icon) { nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; @@ -240,17 +232,11 @@ void sc_notify(const char *title, const char *text) void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, struct sc_pkcs15_card *p15card, enum ui_str id) { - const char *title, *text, *group; + const char *title, *text; WORD icon; title = ui_get_str(ctx, atr, p15card, id); text = ui_get_str(ctx, atr, p15card, id+1); - if (p15card && p15card->card && p15card->card->reader) { - group = p15card->card->reader->name; - } else { - group = ctx ? ctx->app_name : NULL; - } - switch (id) { case NOTIFY_CARD_INSERTED: icon = IDI_CARD_INSERTED; @@ -533,7 +519,7 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, #endif -#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS)) +#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS) && !defined(_WIN32)) void sc_notify(const char *title, const char *text) { notify_gio(NULL, title, text, NULL, NULL); diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index e34477e9d7..9c17ebce6a 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -138,6 +138,9 @@ + + + @@ -340,6 +343,7 @@ + From dd4e96cb24a46d6411d768ffc594623581a0c89d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Jul 2017 16:12:06 +0200 Subject: [PATCH 0030/4321] quick workarounds for notifications --- src/tools/opensc-notify.c | 9 +++++++++ src/ui/notify.c | 38 +++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 91f9b91284..a03ff7f25d 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -188,6 +188,7 @@ main (int argc, char **argv) struct gengetopt_args_info cmdline; #endif +#ifndef _WIN32 if (cmdline_parser(argc, argv, &cmdline) != 0) goto err; @@ -224,6 +225,14 @@ main (int argc, char **argv) sc_notify_close(); cmdline_parser_free (&cmdline); +#else + /* FIXME the command line parser fails with our transformed argv. As quick + * fix, we only use daemon mode */ + sc_notify_init(); + run_daemon = 1; + notify_daemon(); + sc_notify_close(); +#endif err: #ifdef _WIN32 if (argv) { diff --git a/src/ui/notify.c b/src/ui/notify.c index fff0f6b54c..2e928bfa19 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -65,9 +65,11 @@ void sc_notify_close(void) #if defined(ENABLE_NOTIFY) && defined(_WIN32) +#include "common/compat_strlcpy.h" #include "invisible_window.h" #include "wchar_from_char_str.h" #include +#include static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8, 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}}; @@ -81,6 +83,12 @@ BOOL delete_icon = TRUE; #define IDI_CARD_INSERTED 106 UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; static BOOL RestoreTooltip(); +#if 1 +/* FIXME should be V3 */ +#define NOTIFYICONDATA_cbSize NOTIFYICONDATA_V2_SIZE +#else +#define NOTIFYICONDATA_cbSize (sizeof(NOTIFYICONDATA)) +#endif // we need commctrl v6 for LoadIconMetric() #include @@ -106,12 +114,16 @@ static const char* lpszClassName = "NOTIFY_CLASS"; static BOOL AddNotificationIcon(void) { - NOTIFYICONDATA nid; + NOTIFYICONDATA nid = {0}; TCHAR path[MAX_PATH]={0}; BOOL r; - memset(&nid, 0, sizeof nid); - nid.cbSize = sizeof nid; + hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance); + if (!hwndNotification) { + return FALSE; + } + + nid.cbSize = NOTIFYICONDATA_cbSize; nid.hWnd = hwndNotification; // add the icon, setting the icon, tooltip, and callback message. // the icon will be identified with the GUID @@ -141,25 +153,19 @@ static BOOL AddNotificationIcon(void) nid.uVersion = NOTIFYICON_VERSION_4; r &= Shell_NotifyIcon(NIM_SETVERSION, &nid); - hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance); - if (!hwndNotification) { - r = FALSE; - } - return r; } static BOOL DeleteNotificationIcon(void) { BOOL r; - NOTIFYICONDATA nid; + NOTIFYICONDATA nid = {0}; if (!delete_icon) { return FALSE; } - memset(&nid, 0, sizeof nid); - nid.cbSize = sizeof nid; + nid.cbSize = NOTIFYICONDATA_cbSize; nid.uFlags = NIF_GUID; nid.guidItem = myGUID; @@ -174,10 +180,9 @@ static BOOL DeleteNotificationIcon(void) static BOOL RestoreTooltip() { // After the balloon is dismissed, restore the tooltip. - NOTIFYICONDATA nid; + NOTIFYICONDATA nid = {0}; - memset(&nid, 0, sizeof nid); - nid.cbSize = sizeof nid; + nid.cbSize = NOTIFYICONDATA_cbSize; nid.uFlags = NIF_SHOWTIP | NIF_GUID; nid.guidItem = myGUID; @@ -187,10 +192,9 @@ static BOOL RestoreTooltip() static void notify_shell(struct sc_context *ctx, const char *title, const char *text, WORD icon) { - NOTIFYICONDATA nid; + NOTIFYICONDATA nid = {0}; - memset(&nid, 0, sizeof nid); - nid.cbSize = sizeof nid; + nid.cbSize = NOTIFYICONDATA_cbSize; nid.uFlags = NIF_GUID; nid.guidItem = myGUID; From 0fd92c6d79b8fd6653486a874c84129112e42a83 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 11 Jul 2017 16:41:18 +0200 Subject: [PATCH 0031/4321] opensc-notify: use a dedicated GUID on windows --- src/ui/notify.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index 2e928bfa19..0a9c0091b9 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -71,8 +71,8 @@ void sc_notify_close(void) #include #include -static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8, - 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}}; +// {83C35893-99C6-4600-BFDB-45925C53BDD9} +static const GUID myGUID = { 0x83c35893, 0x99c6, 0x4600, { 0xbf, 0xdb, 0x45, 0x92, 0x5c, 0x53, 0xbd, 0xd9 } }; HINSTANCE sc_notify_instance = NULL; HWND hwndNotification = NULL; BOOL delete_icon = TRUE; @@ -83,12 +83,6 @@ BOOL delete_icon = TRUE; #define IDI_CARD_INSERTED 106 UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; static BOOL RestoreTooltip(); -#if 1 -/* FIXME should be V3 */ -#define NOTIFYICONDATA_cbSize NOTIFYICONDATA_V2_SIZE -#else -#define NOTIFYICONDATA_cbSize (sizeof(NOTIFYICONDATA)) -#endif // we need commctrl v6 for LoadIconMetric() #include @@ -123,7 +117,7 @@ static BOOL AddNotificationIcon(void) return FALSE; } - nid.cbSize = NOTIFYICONDATA_cbSize; + nid.cbSize = sizeof(NOTIFYICONDATA); nid.hWnd = hwndNotification; // add the icon, setting the icon, tooltip, and callback message. // the icon will be identified with the GUID @@ -165,7 +159,7 @@ static BOOL DeleteNotificationIcon(void) return FALSE; } - nid.cbSize = NOTIFYICONDATA_cbSize; + nid.cbSize = sizeof(NOTIFYICONDATA); nid.uFlags = NIF_GUID; nid.guidItem = myGUID; @@ -182,7 +176,7 @@ static BOOL RestoreTooltip() // After the balloon is dismissed, restore the tooltip. NOTIFYICONDATA nid = {0}; - nid.cbSize = NOTIFYICONDATA_cbSize; + nid.cbSize = sizeof(NOTIFYICONDATA); nid.uFlags = NIF_SHOWTIP | NIF_GUID; nid.guidItem = myGUID; @@ -194,7 +188,7 @@ static void notify_shell(struct sc_context *ctx, { NOTIFYICONDATA nid = {0}; - nid.cbSize = NOTIFYICONDATA_cbSize; + nid.cbSize = sizeof(NOTIFYICONDATA); nid.uFlags = NIF_GUID; nid.guidItem = myGUID; From e3604143d1c3ac5338262c473676de0cbd420d0e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Jul 2017 09:09:14 +0200 Subject: [PATCH 0032/4321] opensc.conf: added default notification texts --- etc/opensc.conf.in | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 8caf49362c..2941949dcb 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -342,19 +342,27 @@ app default { # md_pinpad_dlg_timeout = 0; # Notification title and text when card was inserted - # notify_card_inserted "inserted title"; - # notify_card_inserted_text "inserted text"; + # Default: "Smart card detected" + # notify_card_inserted = "inserted title"; + # Default: ATR of the card + # notify_card_inserted_text = "inserted text"; # # Notification title and text when card was removed + # Default: "Smart card removed" # notify_card_removed = "card removed"; + # Default: Name of smart card reader # notify_card_removed_text = "removed text"; # # Notification title and text when PIN was verified + # Default: "PIN verified" # notify_pin_good = "good PIN"; + # Default: "Smart card is unlocked" # notify_pin_good_text = "good text"; # # Notification title and text when PIN was wrong + # Default: "PIN not verified" # notify_pin_bad = "bad PIN"; + # Default: "Smart card is locked" # notify_pin_bad_text = "bad text"; # } From b0a85a149773ac326f49dba2a18e0bfe9271e1a5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Jul 2017 09:18:08 +0200 Subject: [PATCH 0033/4321] opensc-conf: Added notification text for GoID --- etc/opensc.conf.in | 298 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 2941949dcb..966151607b 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -492,6 +492,297 @@ app default { # SmartCard-HSM with fingerprint sensor and PIN pad card_atr 3B:80:80:01:01 { + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:84:80:01:47:6f:49:44:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:85:80:01:47:6f:49:44:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:86:80:01:47:6f:49:44:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:87:80:01:47:6f:49:44:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:88:80:01:47:6f:49:44:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:89:80:01:47:6f:49:44:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8A:80:01:47:6f:49:44:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8B:80:01:47:6f:49:44:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8C:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8D:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8E:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + md_read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; + md_pinpad_dlg_allow_cancel = false; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8F:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; md_read_only = false; @@ -505,6 +796,13 @@ app default { md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; } secure_messaging local_authentic { From 496e2afc9e465687d0b0c24bc177a199a85a40bc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 00:07:28 +0200 Subject: [PATCH 0034/4321] reader-pcsc: allow no attached reader for notification Return an error only on OS X, where PnP notification is not supported. --- src/libopensc/reader-pcsc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index d970fa83f9..120993ecb8 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1459,7 +1459,8 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE; rgReaderStates[i].dwEventState = SCARD_STATE_UNAWARE; } -#ifndef __APPLE__ /* OS X 10.6.2 does not support PnP notification */ +#ifndef __APPLE__ + /* OS X 10.6.2 - 10.12.6 do not support PnP notification */ if (event_mask & SC_EVENT_READER_ATTACHED) { rgReaderStates[i].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE; @@ -1492,12 +1493,14 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re goto out; } +#ifdef __APPLE__ if (num_watch == 0) { sc_log(ctx, "No readers available, PnP notification not supported"); *event_reader = NULL; r = SC_ERROR_NO_READERS_FOUND; goto out; } +#endif rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx, 0, rgReaderStates, num_watch); if (rv != SCARD_S_SUCCESS) { From dcf9d230098ee1974635f54d61314c519250a7ea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 00:10:04 +0200 Subject: [PATCH 0035/4321] opensc-notify: fixed heavy load on OS X if no reader Also, if too many errors are supported, opensc-notify will abort --- src/tools/opensc-notify.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index a03ff7f25d..244047ab4a 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -108,10 +108,16 @@ void notify_daemon(void) return; } - while (run_daemon) { - if (0 > sc_wait_for_event(ctx, event_mask, &event_reader, - &event, timeout, &reader_states)) { - error_count++; + while (run_daemon && error_count < 1000) { + r = sc_wait_for_event(ctx, event_mask, + &event_reader, &event, timeout, &reader_states); + if (r < 0) { + if (r == SC_ERROR_NO_READERS_FOUND) { + /* No readers available, PnP notification not supported */ + Sleep(200); + } else { + error_count++; + } continue; } @@ -140,6 +146,9 @@ void notify_daemon(void) } if (ctx) { + if (error_count >= 1000) { + sc_log(ctx, "Too many errors; aborting."); + } /* free `reader_states` */ sc_wait_for_event(ctx, 0, NULL, NULL, 0, &reader_states); reader_states = NULL; From 956ad33e31e062ac66802f64e76a5916ab69f020 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 22:04:17 +0200 Subject: [PATCH 0036/4321] travis: fixed disabling of notifications for mingw --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e958bedad0..e51b72ed1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,7 +63,7 @@ before_script: fi - ./bootstrap - if [ -z "$HOST" ]; then - CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui --disable-notify; + CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui; else if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16; @@ -73,7 +73,7 @@ before_script: fi; unset CC; unset CXX; - ./configure --host=$HOST --disable-openssl --disable-readline --disable-zlib --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; + ./configure --host=$HOST --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; fi script: From 7bc070ac67a3c75900892f4bc76e12f532bebd8f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 17:14:26 +0200 Subject: [PATCH 0037/4321] win32: Load notification icons from Windows DLLs fixes showing wrong icons when loaded as PKCS#11 module --- configure.ac | 1 + src/minidriver/versioninfo-minidriver.rc.in | 12 ----- src/pkcs11/versioninfo-pkcs11-spy.rc.in | 23 +--------- src/pkcs11/versioninfo-pkcs11.rc.in | 23 +--------- src/tools/Makefile.am | 5 ++- src/tools/Makefile.mak | 10 ++--- src/tools/versioninfo-opensc-notify.rc.in | 47 ++++++++++++++++++++ src/tools/versioninfo-tools.rc.in | 22 --------- src/ui/notify.c | 40 ++++++++++------- win32/SCardDlg.dll_14_142.ico | Bin 4772 -> 0 bytes win32/SCardDlg.dll_14_143.ico | Bin 4772 -> 0 bytes win32/certmgr.dll_14_452.ico | Bin 10224 -> 0 bytes win32/certmgr.dll_14_6170.ico | Bin 10224 -> 0 bytes win32/versioninfo.rc.in | 23 +--------- 14 files changed, 83 insertions(+), 123 deletions(-) create mode 100644 src/tools/versioninfo-opensc-notify.rc.in delete mode 100644 win32/SCardDlg.dll_14_142.ico delete mode 100644 win32/SCardDlg.dll_14_143.ico delete mode 100644 win32/certmgr.dll_14_452.ico delete mode 100644 win32/certmgr.dll_14_6170.ico diff --git a/configure.ac b/configure.ac index 9ebbb066d8..bbedd37cad 100644 --- a/configure.ac +++ b/configure.ac @@ -1049,6 +1049,7 @@ AC_CONFIG_FILES([ src/tests/regression/Makefile src/tools/Makefile src/tools/versioninfo-tools.rc + src/tools/versioninfo-opensc-notify.rc src/smm/Makefile src/minidriver/Makefile src/minidriver/versioninfo-minidriver.rc diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index 71a7089c14..2a91b5c33c 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -3,23 +3,11 @@ #define IDC_STATIC -1 /* defined twice: in ressource file and in source code */ #define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 #ifndef __MINGW32__ IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" #else IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" #endif VS_VERSION_INFO VERSIONINFO diff --git a/src/pkcs11/versioninfo-pkcs11-spy.rc.in b/src/pkcs11/versioninfo-pkcs11-spy.rc.in index f3a7f59ed4..a4a1a281da 100644 --- a/src/pkcs11/versioninfo-pkcs11-spy.rc.in +++ b/src/pkcs11/versioninfo-pkcs11-spy.rc.in @@ -1,27 +1,5 @@ #include -#define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ -#define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 - -#ifndef __MINGW32__ -IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" -#else -IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" -#endif - VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -57,3 +35,4 @@ BEGIN VALUE "Translation", 0x409, 1200 END END + diff --git a/src/pkcs11/versioninfo-pkcs11.rc.in b/src/pkcs11/versioninfo-pkcs11.rc.in index 946d3f8e1a..e8bc91d3be 100644 --- a/src/pkcs11/versioninfo-pkcs11.rc.in +++ b/src/pkcs11/versioninfo-pkcs11.rc.in @@ -1,27 +1,5 @@ #include -#define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ -#define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 - -#ifndef __MINGW32__ -IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" -#else -IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" -#endif - VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -57,3 +35,4 @@ BEGIN VALUE "Translation", 0x409, 1200 END END + diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 3011e1685d..6de171d39b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -14,8 +14,8 @@ do_subst = $(SED) \ NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example @@ -143,6 +143,7 @@ openpgp_tool_SOURCES += versioninfo-tools.rc iasecc_tool_SOURCES += versioninfo-tools.rc sc_hsm_tool_SOURCES += versioninfo-tools.rc gids_tool_SOURCES += versioninfo-tools.rc +opensc_notify_SOURCES += versioninfo-opensc-notify.rc endif clean-local: diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 8e3be233f1..fdaae5365f 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -11,9 +11,6 @@ TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ OBJECTS = util.obj npa-tool-cmdline.obj fread_to_eof.obj versioninfo-tools.res -TARGET2 = opensc-notify.exe -OBJECT2 = opensc-notify-cmdline.obj versioninfo-tools.res - LIBS = $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\libopensc\opensc.lib \ @@ -21,11 +18,14 @@ LIBS = $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\common\libpkcs11.lib \ $(TOPDIR)\src\common\libscdl.lib -all: $(TARGETS) $(TARGET2) +all: $(TARGETS) $(TARGETS): $(OBJECTS) $(LIBS) -$(TARGET2): $(OBJECT2) $(LIBS) +opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 .c.exe: cl $(COPTS) /c $< diff --git a/src/tools/versioninfo-opensc-notify.rc.in b/src/tools/versioninfo-opensc-notify.rc.in new file mode 100644 index 0000000000..3c6aa7f6b6 --- /dev/null +++ b/src/tools/versioninfo-opensc-notify.rc.in @@ -0,0 +1,47 @@ +#include + +#define IDC_STATIC -1 +/* defined twice: in ressource file and in source code */ +#define IDI_SMARTCARD 102 + +#ifndef __MINGW32__ +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" +#else +IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ + PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" + VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" + VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" + VALUE "InternalName", "@PACKAGE_NAME@" + VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" + VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC Notify" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/tools/versioninfo-tools.rc.in b/src/tools/versioninfo-tools.rc.in index 2c7f14c558..444b1a2522 100644 --- a/src/tools/versioninfo-tools.rc.in +++ b/src/tools/versioninfo-tools.rc.in @@ -1,27 +1,5 @@ #include -#define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ -#define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 - -#ifndef __MINGW32__ -IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" -#else -IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" -#endif - VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ diff --git a/src/ui/notify.c b/src/ui/notify.c index 0a9c0091b9..9cb7ac5954 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -77,10 +77,6 @@ HINSTANCE sc_notify_instance = NULL; HWND hwndNotification = NULL; BOOL delete_icon = TRUE; #define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; static BOOL RestoreTooltip(); @@ -184,9 +180,10 @@ static BOOL RestoreTooltip() } static void notify_shell(struct sc_context *ctx, - const char *title, const char *text, WORD icon) + const char *title, const char *text, LPCTSTR icon_path, int icon_index) { NOTIFYICONDATA nid = {0}; + HICON icon = NULL; nid.cbSize = sizeof(NOTIFYICONDATA); nid.uFlags = NIF_GUID; @@ -199,12 +196,19 @@ static void notify_shell(struct sc_context *ctx, nid.uFlags |= NIF_INFO; strlcpy(nid.szInfo, text, ARRAYSIZE(nid.szInfo)); } - if (icon) { - nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; - LoadIconMetric(sc_notify_instance, MAKEINTRESOURCEW(icon), LIM_LARGE, &nid.hBalloonIcon); + if (icon_path) { + ExtractIconEx(icon_path, icon_index, &icon, NULL, 1); + if (icon) { + nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; + nid.hBalloonIcon = icon; + } } Shell_NotifyIcon(NIM_MODIFY, &nid); + + if (icon) { + DestroyIcon(icon); + } } void sc_notify_init(void) @@ -224,36 +228,40 @@ void sc_notify_close(void) void sc_notify(const char *title, const char *text) { - notify_shell(NULL, title, text, 0); + notify_shell(NULL, title, text, NULL, 0); } void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, struct sc_pkcs15_card *p15card, enum ui_str id) { const char *title, *text; - WORD icon; + LPCTSTR icon_path = NULL; + int icon_index = 0; title = ui_get_str(ctx, atr, p15card, id); text = ui_get_str(ctx, atr, p15card, id+1); switch (id) { case NOTIFY_CARD_INSERTED: - icon = IDI_CARD_INSERTED; + icon_path = TEXT("%SYSTEMROOT%\\system32\\SCardDlg.dll"); + icon_index = 3; break; case NOTIFY_CARD_REMOVED: - icon = IDI_READER_EMPTY; + icon_path = TEXT("%SYSTEMROOT%\\system32\\SCardDlg.dll"); + icon_index = 2; break; case NOTIFY_PIN_GOOD: - icon = IDI_UNLOCKED; + icon_path = TEXT("%SYSTEMROOT%\\system32\\certmgr.dll"); + icon_index = 16; break; case NOTIFY_PIN_BAD: - icon = IDI_LOCKED; + icon_path = TEXT("%SYSTEMROOT%\\system32\\certmgr.dll"); + icon_index = 11; break; default: - icon = 0; break; } - notify_shell(ctx, title, text, icon); + notify_shell(ctx, title, text, icon_path, icon_index); } #elif defined(ENABLE_NOTIFY) && defined(__APPLE__) diff --git a/win32/SCardDlg.dll_14_142.ico b/win32/SCardDlg.dll_14_142.ico deleted file mode 100644 index 5fe23fe2fd77a01a5cad17e3daa2c6531b75863b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4772 zcmeI0v1=Sh6vm$-#e0Q7cH_z*$7!r45C%e2DY!@{aHBLSOqwD8!Knyn)A%l=P`H3$ z8{;A|Ns&fn5ctw0CZ5`AA`qx>EU&n`Lfk=&C%^aR_OvHUa$`se&1rV$eczk+zI{8l zvnP=mnUm|+FWdR=cSJrFk;|8peRD?SgIR$W_=fz{5czCQ`DB0juE?u-k(-m&Nt2G5Q)|yR~Y z-1ZrE>G=vPV>FxFJhROR~1MCabHfa_iPDSzcb2{HrLpZ%6rFo=Pl({Qk5jPoF)L z?|%M;436&U1wACwfjKY-<`m;1)Ww5)1|HmldvKjrfEVBeMgd-cbCLiazyo*y2;dPr zV#i>a9Y;rSM1c3h zaA^*~PIYjDQDrJTM~@bd7LOLYWVCpadlGqqdbC&>AUy+*7LOJy3pzYH zJUTo&JUXmY=f;6lf^WP*4ZGZB)gs9)vSTy^Yi$kT0Mu zpd*maZmsH|1_2#Gb#P&JyO|Ww63`M55lCoD04;%u0jB^E(83>`INXzfmZ0@8ExH=? zE`XsSq9LLoq9LLoqQRCE8Uh+38X_738VEzj9}N)=5e*RygrKM*W3 zG2-Nj;jukBqQzDpFYn2Za_7z+;W;9A@7|Sr_wLD)Cr@N+YfE-^c4T*VSN8Y!<>25z z27`f&MkDF}6Xk~o5BMJER9C+PdLo`#8dpuV{x_{G%k#99S+?}z#hD&urqh?siUFOS z<6-nsuXjd_L}xwPX&yCt*c+SZ@ z8V3!}{7!jTTCFDZ$@yi9P*RqoZ9PsLs`-Z+!02q7(v2M~0r{D)`pToD?d@$G%tH%Q zFP9udZ>eXRP&GN%EKJgg9M!^dhB7Bpf{*9JV^`c$U+7cm?|^L z&mhy4XCBI*GCMh|M=v{*PBG4-@puEB64j0-t!AGXzJZo=zf#2F8F1YG^Y^*&dy2l_ zoZ51IIid4@q9^?@xOh*wcu%=_Pq}zc;SoOlykoCsJK#x?TA3Y*q#axVOm-YYDw7Rj zs7PW51KV>g0?ug*)C~%xJc4C2(j5grcaOnfn~ijAYJ?I%eZ~ryR032_Y(qgNtcuV} zsGpL-Q6JJTH)0$u#@Nqd+?(O2H$A8G(|OYKSvdH|3o+iucjZy~-TeIXUt|1swg2^R mUH)VAe6_OVQv0KC9)7VVa(y|S?Z@TJYX8HJc*82>&k43E-R&A+ot(yvgEG+tDW)^V43Q%JcK{1yHGroTokM z1B(mw^1Pd`)pDS+5LeE-U*76=gBdI?F2qswixcodt1MKz3RDMlty)!}Heb-y9O!#P z8&IZp=51?SbiKHk(`GSDE3kzIh^1cb)^m5g#-iQ>0Q;pbZ~?@`8v>xW0MNsL(L+G2 zEG??%G4hqjLLM~kuOlX8DZHU+l_gMXO4IbKS{vBq%Rb#FHTc#RZ(Xtn{$?BWY9X}8 z!|F;Dn$3}bk?xEQw%${bQV-2-k^L)-O*(W0J>2)R9tS_MB2vRXY{*D>Dy7gPWT&@3 ztZs~l-@@&%M7DAI33`ow3`e%U?e$`x6XzKXhR?sX&x;*?$+l@F{``ba>g`u=g(p^NE^+Eo!40N)8l;L%G90*%|Dyc{^N#>j*cR=B4cA? za`50mIdtfd96o$ljvhTK6B83MJv}X_PMwmesVSM9oRs*>Ag50U`9|(a$Wrw z(csYF(BRPE(BJ|XIvhHj>fi>W%2ar+9xWa%9xe8j(c($&N#qIY(PCwQ^h`WjJX)+Q z=A)yX>+o+0tdk{vhdK;-h zO1>0rDLPW}*{xL_)F4Gisyg^$cDr#((UPJiMMO$M+X84waZE8v0aCQ^p%aIDlAe}_UH%}TW!3&CO^oTGiQY7hg`XGMXp}GDtGSOk()Pf%DsE{gxZ14#cyS#?_^+UZlD`SddX-E1}dQO$6{*Y`0@3U zdbig$d85}_Ew#WP+Lex4G_`28)L^@}(cM;8MYdW)$@Ab*t1!qd%9vT(K{vV$jnU`( zbTs7OXfz(Hg|=au1my4H-^dvdpI_&?SFMn}t(u5Vxo$dA9J zUt3#VUdF&Iv_M7vLSLp9YC!1eeMMjIJWYW7+B0J6KNuy3AjR`oaRql;!1Q zFA(*~vQB527pw862ZR?Pi2BoT$^eQdxS=2ewy?6%&TH2=v%TQ&!ILu=XXa*3zAJKT y-}`f)&CGptVd~;-+%&(aC-c#MSdPq`d*f}n^vS2^=05)L;>>Dt7jdJ_h34i0^SNizVT_#>l@;3X@+13T%rPn>6q4NB zbgub6lQa8>w_$RDz+9+rs=m)cXhm{$a|_djHcMh-j|hb_;(58LAT~D4f;cKqa*b00 z!ID@9CKjp-)CHEr3&JdUp0%$LCJ+k35){0tK%L~&4)IKzsf7ieT0#k`4;BlBLJJ3! zQS~LrcuPcc2bqi-Oi=QslqWkEMGqmEQ`*#lhJpp+natFJ6#c}@1QtReUxehR7Gk$x zSa}=jt-4GoQ_6(`8v!+;2vnZN$3n@n_NgIiTt>vF82?isxdR)5p8^};;Q_`B=Y%vP z|G9vppINq!@X)Xt@x~P3Y19;Ikyi1qheQ(nGgL+G{$#5n#nw5!0{mK6u5&Bme>qsu zq9zHgYd)eUCI6vy&K4cjgjia3ub9|@AWR?_lemv~fnaoO1TeWk5Gxox*VM9Op`e40 z!zea4wQvwu?8vB~6_Ji!Lw)$# z^f=@%90`#te+RBR7l5DkJc!&mAD(S^2U=E-1n#TxAl7;Zsy9!8l)wH7(zi~BtnD8| z?Y3!9WF&x6^QBO``y-I-nFW%)0ti2_5_}GChlf9W2I3Q1kbHhSa8^3dban$sZMQ(r z#jPN+*##{gmXLnK1ln#Hfc%yrV1O~G=vl)%hG*e@lui7QR1jjJ==%g3SJLL^aPJ6*p zp)aV}_<@>j04%l(gvAaau+%9GG+e3OlWy?!k5|A{co9Ao-h{P6Z&+>T51*g+hfTKL zu+Aw6zH#)0O^yNZjgud&bcuj=g5k)eTVUyU1NOLv zz>XWSpz9R}hF;Nd>}EJ^zR3V~N${F|62R$9c=sIfPFVm~vfw?}ha}4fa49Cf2wrzC zh4B}QLDeM(KJ<7D;9Uj~@C-D93t(wz1%Rsv;ASm=KasZtAg~c2qyZp|@&npnS!@k_ z>Gc4#ypmws?R3!g&w?%f8K51M59=a|V0~OUYzuh=Iuz^sr-E)!CYS^yf#Ka8_#rF< zc11h}qliM#jVTAC_zEzIECBPk5;&Oj4Av#rfKEy^XgzFzy@^$@C$k=mvg*MswH7Q= zYrrzI0gh#fU~hgSnB+@9_faoI*q?-xp22YP<~^{w6$PgPRz}i?t$Q%PKe{WAgrkuGO}{uY1TtX zEqV%7IhjzMp9A$}CGfDc8Xi5Vg6tX*JgsYhw5Cpw)Yd?gh=ZyI5!5zGp}A24t<6o) z-YSJEX$Np^9njR)2K9Xd(9zKjow9D|>g@&jKtI0)&_*=0A%q$UUfIHPf8?Kk8j=9) z+MuScsik9YKYuI02k-KdkKP+B5Vl!2Ai&YlURO)!lJgpfpZKOKNfQ42)`xrnTH674 zE-X-+Gh0npS8E5n|Hj+DBf-pRDie5lk%zl`k*B_afxf<@qs~H@I^~_$CPVC`-@p3@ zUha9xx46<(Q&VmBZ0${&JNDh5@%o6-fBAgO*ztGsQ}d$1*Vn_N=$ej!y@9>Eqvj|1 zlIg2|q!Z8X)p0ozNkMzGr+YwYwWp4@`kXo1T3S1{?p>pCSZHl)ZTHo^l$6whJnuV! z0mZIbI=cGy9`ytSe1+wS zmFCvRF7}f=FW}DO(#i+>9qgSBT)CpXQSP(+RKh2zgV$$ z?b`D#l$kGyri+@}4yx8EGt|7-+1V*;ZL9FRd8?#N#>-j#{ohiuU;eFTIE#k|zWyF< zLzXAsp%p4_6|+FyP=tJ@f2XEHH?d7>n?iYMeXCO3Um%I1lWNpPx9j+bzyil{1=N48pg{5~p`d{3Ljjk^|FXDz{+GwG6nkc+@N4{E z`S{;;pBucV4BkulaT#_`S-9C4nlwi8_mA3bQ~7&EjsAT84$*yi3x8KoG53HG7Pt8G zed6((pki@@&U>1MqtWn{i7l)@WCv@_96;yzCD?3v1yrm9VDc$HP&s`^an7HK2bFVC zpmIJ27SZ{;+9?pe@Q8q8SA$@KXC%BzjtvM?`14ie;seFm>QVxK_Q>JS(3#!^@bRr; znCo8(w7J8`o7Dh*O>~Az`SWvGWF4%E6T@E;nqW<0Gkl&bg|8kyhYgus{8?sDgJ4*T zkbC_y6o=mh%yNgSq$9je96P%mx*d0+3pa@qV__rFKre{2NUJ!R}*P%2%h zzC>--tXX5>mC>-A{F<55=l^-)#ED~J%uDbx@t-VMtTuDz%(3w5$8+Y41o*=rW=?$V zjW@=Q_~ZC#^Jb420TbQ_)o~M6ta$xTi>7_JLdmaQJ!!@VAHGSv>g1_YCcd+5*~&>O zDl3Tx)d>^cUbR{g7*9DXRxe$;RAcGV)q}iJJjAb321R+*p}_M>TmGT=ztkU8RvaG-I#r#z{Jdj*nZXe|pl+6Fw7n9DDZ8mcvq&EvB*KW~eV3-cpUh zC$or(i3T@xg|x+X!)wh)mX_5Ss{Lhn`Cm#;*=+jO`&*Cb&N*nGy3oqKi~Kqye-7uK z_Q3^qcW{Z*J^bos8m{+A!>Rl2y2s92<@D01S5zF<&KO^#J3pmv^VA;FZ#cYd^fR&~ z9}>lTrnl8@|3G^7@bL$@fL_jj?viAJeLJ1*4e)`K@nX$A}{l zN~+C@(5-B*96oEWu}o^?8b*=UsT3=gJpcr06tMQs&-gUIJnpT(l5dUVn5#g^ml$P)ZEq6AN8acCS~fS3FG>eWk+2jb`~=B|G( z@)|n{-$8K9!B>ukBVim!SO>zfSOn(`gxfS8S4wcry+T=E{{XMwFE)eM&+I>tTrEAG zEkg3&(W$rvy`FWURcrz7^o&Ct?_^wmGX)9jKwX~%Gzd&X{o5(1Ve5y>&-(Uv_4SE2 zKB(>{Yzg5;84?DAEsEBV z7fv&CM#9=q%{CC#>0Mh$>yPa>^G^E==(&bqKrx5QzIX0*3k+|msH~QBc03maHTFsg zH$%e8XstcNaSq8y_!Ew?Peiy_KyA?gPeFNeFL|%Vza;`#ua6-0nGt#{l zif&nz`1$z&WNp(OMAS>|cgea%grkTyyG6LrLsYbRwy`kHtyrr$ILBf~m>FpWPA2z7pH7I__{%>i1x88`sb&f&UOZ^;9U48O~ zwN632{^NHNI+QXwmFvTSp|UUXFP39+_Wp;b7x3eMh4w$C{Tt4DN|w{uZ@d)7?C0dv zE+HNq8@DcbAGg}pSFV0O2#>hm>8LJz#5Gh_ay2E7x%%=_u8yd>sDP_2DdwJcJ|`WD z_nft(B-Wl%KVf(Z{ef{q_HR1pgKT`Yy_2xM?YXFLu&+%2!>Wd+X(ks2*x6%#J%se< zb2X2PxH_i4tdy%NEa1x0(>PI0^-!OgURIY8OVe5!(jS#s%$)yX~Y>f$<{cko1OldYZ)|u8wTxZKrYPDxT1|E9OBe5p(SwZJe~Jk!x>j<=Wd@DJ|hTD35ST zu8aE0#v(Smgx614?U4P^S&y>`W5uO5w{W>*C=v#Xdcj#pm^;!p0MvE~>8Yrx7qfQT zq*AW6rG?@a($U7XQC=(Ql#-72j&`nv`oZV5G;z{K313bsk#L=Z`r~p+75Z=gWPiwm zJU)+bWc(o{rPKI!Vvo_)pq}+M9zAEm(mLv-ZK5uEhq`*Yx$eFmPDX1|LA_izld0#I-|7`4skN^GLGG3SS?dYG`&+Z1-f)fVUzv5kC?^hkIwTiT4?pbyQ zSDl~DRc1ZpM3qmus=REjp{#^^l9|Rm%}C?QQxduAM>*WnhpALf5!X{)rn`4=4Y2V~ z$S)t%A2l@pK}m`|kv?Pr9|BimQlyB(QPgwgbl#b!UoxSSG<&nw0Id1aXR zsGO(*lM5>_I->xcZ~tU}3d!QKiurpHn}`2SVs|g5YqUZDJ)mz6{~@M5 zBb&ZQ@c9wxg?xN3t$>f&dBWGDHOyi*mn{CZd?vqfkIu?}hyV8@&^ppyBN6D^K8$)( zK|t}}4~bOdpP;|l5~i zg#9Any-0X4&h~vgM9TWik0cBk2|wn2N9H#w^%F*ogi#}5%}Cfa67G$Jb@RmP6IPCd zRU_fvNO(2xdojO@PQ$n5)O}q$s^(3JQ3clXoK#}?C#9? z;q^Bic9=nZh+0o}d}(5fgz00gxS9Qb#jl3p^_64EVrG9O*~S84??Xh``%s$6eycuV z^Q_2khTp1RFKI@?_IYZcG$Uo6lCPFXhsOWK{xci?5mL_I@cRGf(y`QI_Wv=b28p5z zgJeZ9qt+LQeePD0o-PSN-$-wtuBx$-sj1O^1D-!*YNopXu(7Jyfdi`hb{#U%14F%C ox_XBc83(A8(Y}3p2D|pD?lv+rH9JK0RP_%WGTvpz+GDc60V*{2YybcN diff --git a/win32/certmgr.dll_14_6170.ico b/win32/certmgr.dll_14_6170.ico deleted file mode 100644 index 23571d786ff4ebfbf7d673e56ca4feaca2a11e81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10224 zcmeHNcUY8H)<4*jO`@Ab&8AthX(pCvA`nz;F=~PujWxxMEvC3Jny7rZieh9GBWuNy zC`JQTP*DL90TGZQ(h&p%23}qUhM~_e%*^?I_Z@~sW6D13^L*bQdx!Jha_+h3w)egF z{0>BR)QNic?uNJn$?b?15mC2p*8EF$M3dSR_ym3zI@*P3MF+vR<`;J)diG%(zc(F4 z`Nl_W{NA(}bq730^b*=c6EqSe^e6$k?j78T@JH_M)(B4|LGBb883_g}f5a?OApAs; zc-X>HBK)<6&XGi0T607Xl~I>U_kR^^O`m*WtpAa4WmPCGnRDn1hw8tN2* zythLzdmGpzRORHjR`B=FG8ou9)XB>=NZ~szSFwscoSd8-y$xQZ@OXrEy)pNDa-8o?&(1kYPc1%0^vz*xY=5GaC$VJ%uueflt1*|~hLfG!MS6Z=D2<-y zPGi2@MKf0IqxoO0BbPNt>HTjH(?r*BqJLbao~zQRqx)X!veB11tPh~azyFEad!UW) zE)#9OOb={{pg(U5A}8B&r`2^9LedlTEj!Q)AuAuEWv~`6Z+!{r+A%S{&T_M_$M6@T7p5A*6n=OTCS0?fq z^w5r*)NNNb_1~C84v_2PlR_^Z%%b7@GHK|pTyi{6Ky)~V=)`Su4ostAXY+{mmDBT{ z#q`%LjWqNCliiVGqT?k*KgozIh)$Og1tEQ`hDIDKC1-yPIUm*0@UUWf^@NFr9MhB2 z@fvy~&_vFskv?an*F#O@aLGhtwkFf8gE1Iu9*sVnNfZ3iX!OxMdgnq0O}dmzGeF-2 zq|@|(avB}TH0E3*jfDKza1%`oWm*;@(d*Zk-nmjtGp-iVv}|r)wb>h!cLK181Yi{cI*3 zIv-6(LSpII#aQyYc#TemCs07-bvkq9I$erMq@b8ox^OLn!V)tnJozR?q~y}~c~$gX zLN%?s)j+CSOh4o^`4v>qk*sQRFEY}ek~;c9$K+#V3Metrk#ZxQLO!U{NTHf$I&5OP z9ve@I@d=cl6i+cpS#&)qgQ9QTq?n9+%FW26?5sR0yq-WsDc4DJE1pVovZ+jcn_{vG z>DtXA$|)|Re7S;RD;ub&u#hzBVycuSDlU~tt*NA{3Jq0jE2*xgiYj!~R8?C`rOg(q ztE;01gPt0V#yih*>!$$EUP`J@YyPgpUvc?Bc*h!J#s2O zD)s{EB&c=THsOV_->h-_AGZe{iqmS<4X9AkaHch!I}_yMFxS;}wd@%{lnGuhQ$)2jfA{*(1vecsSPNWq+*N3|Mhu}Uo3W<=els4 z;4AWje0C2rl-Jic)LSeE?3ey6cV```Q56liKo3u?`I<0gLn@%)b$jvkt6vBYXc|FwhG?ww|8z>1mB$s2|Gl`?%L9PMEO18g=7alzh4ra%NJu_hFGuZX?uqwx9FLF2y3oLy1K?A>rJtlumIau_dt=zyExMHohcYD}J%X@hFQaiN*HX zncNPWm_{BNE}~zC_wsH!b?7we*rZ>wtR+(-(sNVy&-^tu%I8d;7WixI|6ljHmU~Le zy+rA=NVnu2W-X!NGrpz~vsWnh5pfq$3?i6~T*~;BPxdW`k_H_%jp5YtA zY3}X_TD?DzK0Xvd4~TPEg)<-LuX66DfdYb;d{&f{iruyn+6n zQbh|A4YVK$g!621x`n>JsV860E%f7wiQ`YGdlzIL%apI3u7!^+EBjU*` zzmEJXnkZBMQ2NteyfnO3W_Q9wnWz@ z9px03P;RM)3d$-dzpRq3)>Z`R>Qdv!SBYth0{I~qSGw^>l z1F)A`b$5AyoI17Uh#u@fo!jRB)Vpurjtc)#I}sj#r2Aj{ASQZr>^OvndJOLV#JF)H zKW_HS8MC|g>iNXOvqgTwv%}wXnC;TFTQ?Ua|J0!Nvu#1}pXxVs_U!Rv-ky%a$s*r| zFY-?gY5#_!y}kV~dwaou^3_q#w|}dpf%om6?musZ3ad!zwmOK?ESR|dn+xwcWa~IJ|>GledAS7CaC3uZf(43^OOg* zD~9EiEPnm1`>5`Yrlb|49xPrk_-e_lK26ZSxGj^9ezq3&B$v;BsYdt(}J5vl#X@ z!~SM@QrC*ikNUqScm+G>ErC7Fu(w$~?-hpajz0E$%_euhV%X^xz0WL*X7KJZaCVaNcwBQj*V!FouoCzzY}{1p{xe0MlUD^9);_foCu< z3-hLMt zHZTL9VBj818ni}K`SKHtl6F-dY_LWZ1?mLp$_PnBUB z$rfgL;f;z0U_eYeZg8hH7a5od14Ch29fmRh4aYDad$M`lxpYIb*`nw_8WykUzt{MM ze&84kJcEH9aYMaUF28wIE-aE{b!oW_dt1JZw9sv0i~L@6ksfzXCf^*!-I9R^Fz$Q| zEQe`*1l9s`fc`iIq&791tm8i(o}lO#`}X{ zydYmLE4nRLN~N+6z?&Gj8{f{)m*b*Eanj37M_y z51fj}hB1G#&cCs`zFt;i4m4Fdxu&5(*4EU>y4qT0KZ-q|Gg-<$jF$|+12NVptaZAT zPLu+W!9H-k$PQ=nn$*pfa;%x6Kd@!5i*Jfee?XMAPh$MQ*_5?U$|l zl13_#@=GQ8P@bmxlZ4X7aZ$yFNpWR*&)lk-oHC74r^(pVsz0bjzxbBg^k0ZeSNbHz zKfy1Pf#WHA(1<>pK+SBCM7k~AU4D1oR@YW8V)6c;k4sZ@iSM{gf7|g-^h;r2k&1pX zZ-RteZM9A+y_F*srKd_|1qD)Zc9v9{ds8X_6=kGJ>g-GjpbY9--*X{jBfP81I7A-! zo>f225S#vUvDQ9`@dN8*V4`>E2Sg$1O(v;0GadRYimU(WO zncpuqEBo)j{(V(dl@${9oTNisr74$6FlJ@!n0G1f7Utc$4m$8^>uQvGwKdgJZEZEu z8mSItz$T?e^i}8&OUhRC1Glw}|4)m)^C<<^%+u42JoC1RC+C^??FcjXaam{DxnsMo zs-i-w#`jCKTcgt&?xnE8jaM@qW{wMn^yhD ztmE%Kdcg|d`TQ32y>->ZE@>tnf8E4m;w|iO*2wTTSp1G2t!l(O)YzoQ8Z=1;Q*#R$ zB|XZ;{=oMEe1kQQbuu&?mAxS5zU};9PR>#E?>L6@@}Zsshiy)30RGOv<9X;s69aqa zAt5FneYuHe6qxz7tIPu?FKLQCd%CO1W1f zrJ~g9QvS6V2{^J6mtvm^-A3#O5sUc;rrn}HBhK9SdpaT*O$lbDy5GEqm&OB3dy3GZ(+^on;- z=#NUxQ}hG7=K+g$CBj$0@S*%B!N0-drhm@j>=ftMsmLS_j7sJ+(aC%kdl$Gpi|>kf zw}ay|I27+#SW*^Wx}MG9xYu32k;9Rxxu870lAgz*@oBu{SV+>Kh1;Uwzu<{e7xSgW zOyyp5_x%rkBZhB<;Tu!>eK-H#&5OI2&?Uy-XNtQIdr6Vf&47X85p_a`CMeeDTc^v3Pft`q5VT0L;s8l?%S_Ih>UUPfy&i;OkRqO&b!b zP1Lb39Ak>R)%IC>q5J6d7vZnrp5wj=rOy5DyZt~N2R!!dhX*vr zu$^Ex37e^HJzE<>J~BDWka)9z+mf(Bg#96G55@k1&0*tue{)Sh$NtOxXTo2=!1LL8&PoQJ&%p2*cz!DZ$8SxG_JF}F`W@E>jfcO1 z;U{3=`V3zJ+E@V$;?}*?ww3|6SMFSFI=`pSHOqD?`{b%8@p)ZAC|TKZ_Mxgf6U!| zu*1&x0NG7^X`(9T>#w4d9=kFoq-IR#FNbYV-@*jK(aM3p<` Fe*w$~lUe`( diff --git a/win32/versioninfo.rc.in b/win32/versioninfo.rc.in index 246efa6d87..fb34084007 100644 --- a/win32/versioninfo.rc.in +++ b/win32/versioninfo.rc.in @@ -1,27 +1,5 @@ #include -#define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ -#define IDI_SMARTCARD 102 -#define IDI_UNLOCKED 103 -#define IDI_LOCKED 104 -#define IDI_READER_EMPTY 105 -#define IDI_CARD_INSERTED 106 - -#ifndef __MINGW32__ -IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "..\\..\\win32\\certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "..\\..\\win32\\certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "..\\..\\win32\\SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "..\\..\\win32\\SCardDlg.dll_14_143.ico" -#else -IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.ico" -IDI_UNLOCKED ICON "../../win32/certmgr.dll_14_6170.ico" -IDI_LOCKED ICON "../../win32/certmgr.dll_14_452.ico" -IDI_READER_EMPTY ICON "../../win32/SCardDlg.dll_14_142.ico" -IDI_CARD_INSERTED ICON "../../win32/SCardDlg.dll_14_143.ico" -#endif - VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -57,3 +35,4 @@ BEGIN VALUE "Translation", 0x409, 1200 END END + From 9b772ebdc45cfcf5de00470f9100bb9fe9919117 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 18:14:25 +0200 Subject: [PATCH 0038/4321] win32: switch back to OpenSSL 1.0.2 as default AppVeyor changed the default version back to 1.0.2, see https://github.com/appveyor/ci/issues/1671 --- appveyor.yml | 5 ++++- win32/Make.rules.mak | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 01762cb3a3..bf528b207e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -82,7 +82,10 @@ build_script: # build libeac.lib as a static library xcopy C:\openpace C:\openpace-${env:OPENSSL_PF} /e /i /y /s cd C:\openpace-${env:OPENSSL_PF}\src - cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c + # OpenSSL 1.1.0 + #cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c + # OpenSSL 1.0.2 + cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj cd C:\projects\OpenSC } diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index b8e0adf670..62530f44ad 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -45,15 +45,27 @@ OPENSSL_STATIC_DIR = static !IF "$(DEBUG_DEF)" == "/DDEBUG" !IF "$(PLATFORM)" == "x86" -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.0.2 +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.1.0 +#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib !ELSE -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.0.2 +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.1.0 +#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib !ENDIF !ELSE !IF "$(PLATFORM)" == "x86" -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.0.2 +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.1.0 +#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib !ELSE -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.0.2 +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +# OpenSSL 1.1.0 +#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib !ENDIF !ENDIF From 0dcf6732960878f242e1922c14edfccb80027887 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 4 Aug 2017 08:48:24 +0200 Subject: [PATCH 0039/4321] CAC issues (#1120) * cac: Make the retransmitted APDU valid by restoring the resplen * cac: Check SWs for all the APDUs and report the errors to underlying layers * cac: Fallback from CACv1 to CACv2 when CACv1 instruction is not recognized for the lack of other pointers how to recongnize them * avoid goto --- src/libopensc/card-cac.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index ed15ba0a89..82f5c7869a 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -390,9 +390,7 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, goto err; } - if (apdu.sw1 == 0x61) { - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card returned error "); @@ -606,9 +604,14 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* SPICE smart card emulator only presents CAC-1 cards with the old CAC-1 interface as * certs. If we are a cac 1 card, use the old interface */ r = cac_cac1_get_certificate(card, &val, &val_len); - if (r < 0) + if (r == SC_ERROR_INS_NOT_SUPPORTED) { + /* The CACv1 instruction is not recognized. Try with CACv2 */ + card->type = SC_CARD_TYPE_CAC_II; + } else if (r < 0) goto done; + } + if ((card->type == SC_CARD_TYPE_CAC_I) && (priv->object_type == CAC_OBJECT_TYPE_CERT)) { r = cac_cac1_get_cert_tag(card, val_len, &tl, &tl_len); if (r < 0) goto done; @@ -1106,6 +1109,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86) { apdu.p2 = 0x00; + apdu.resplen = sizeof(buf); if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS) r = sc_check_sw(card, apdu.sw1, apdu.sw2); } From e0eb5bf888323175e3ca601ea45b4f75fbcd4875 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 3 Aug 2017 09:52:43 +0200 Subject: [PATCH 0040/4321] Do not call list_init() twice (amend 6bfb39454) --- src/pkcs11/pkcs11-global.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 5f04a7f18f..24074ab5a8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -264,7 +264,6 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) list_attributes_seeker(&sessions, session_list_seeker); /* List of slots */ - list_init(&virtual_slots); if (0 != list_init(&virtual_slots)) { rv = CKR_HOST_MEMORY; goto out; From a007ab7820357c466d28ac442b53ab71e5dbd4b5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 30 Jun 2017 14:52:08 +0200 Subject: [PATCH 0041/4321] sc-hsm: New PIN commands for GoID 1.0 --- src/libopensc/card-sc-hsm.c | 125 ++++++++++++++++++++++------------ src/libopensc/cards.h | 1 + src/libopensc/pkcs15-sc-hsm.c | 6 +- 3 files changed, 86 insertions(+), 46 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 5a4179133d..ff9810c4c6 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -68,62 +68,62 @@ static struct sc_atr_table sc_hsm_atrs[] = { { "3B:84:80:01:47:6f:49:44:00", "FF:FF:FF:FF:FF:FF:FF:FF:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:85:80:01:47:6f:49:44:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:86:80:01:47:6f:49:44:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:87:80:01:47:6f:49:44:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:88:80:01:47:6f:49:44:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:89:80:01:47:6f:49:44:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8a:80:01:47:6f:49:44:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8b:80:01:47:6f:49:44:00:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8c:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8d:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8e:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, { "3B:8f:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00", "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00", - "GoID", SC_CARD_TYPE_SC_HSM_SOC, 0, NULL + "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL }, {NULL, NULL, NULL, 0, 0, NULL} }; @@ -305,30 +305,56 @@ static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, sc_path_t path; int r; - /* Select MinBioClient */ - r = sc_hsm_soc_select_minbioclient(card); - LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application"); + if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { + /* Select MinBioClient */ + r = sc_hsm_soc_select_minbioclient(card); + LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application"); - /* verify PIN */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN"); + /* verify PIN */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN"); - /* change PIN */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN"); + /* change PIN */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN"); + } else { + unsigned sm_mode = card->sm_ctx.sm_mode; + + /* verify PIN */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x85); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); + + /* temporary disable SM, change reference data does not reach the applet */ + card->sm_ctx.sm_mode = SM_MODE_NONE; + + /* change PIN */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x85); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + /* restore SM if possible */ + card->sm_ctx.sm_mode = sm_mode; + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN"); + } err: - /* Select SC-HSM */ - sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); - LOG_TEST_RET(card->ctx, - sc_hsm_select_file_ex(card, &path, 1, NULL), - "Could not select SmartCard-HSM application"); + if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { + /* Select SC-HSM */ + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, + sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); + LOG_TEST_RET(card->ctx, + sc_hsm_select_file_ex(card, &path, 1, NULL), + "Could not select SmartCard-HSM application"); + } return r; } @@ -340,6 +366,10 @@ static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data, sc_path_t path; int r; + if (card->type == SC_CARD_TYPE_SC_HSM_GOID) { + return SC_ERROR_NOT_SUPPORTED; + } + /* Select MinBioClient */ r = sc_hsm_soc_select_minbioclient(card); LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application"); @@ -375,19 +405,24 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85); - apdu.cla = 0x80; - apdu.data = (unsigned char*)"\x7F\x24\x00"; - apdu.datalen = 3; - apdu.lc = 3; - apdu.resplen = 0; + if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85); + apdu.cla = 0x80; + apdu.data = (unsigned char*)"\x7F\x24\x00"; + apdu.datalen = 3; + apdu.lc = 3; + apdu.resplen = 0; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - /* ignore the actual status bytes */ + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + /* ignore the actual status bytes */ + } /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, 0x81); + if (card->type == SC_CARD_TYPE_SC_HSM_GOID) { + apdu.cla = 0x80; + } apdu.resp = rbuf; apdu.resplen = sizeof rbuf; r = sc_transmit_apdu(card, &apdu); @@ -564,8 +599,9 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, /* For contactless cards always establish a secure channel before PIN * verification. Also, Session PIN generation requires SM. */ - if ((card->type == SC_CARD_TYPE_SC_HSM_SOC || card->reader->uid.len - || cmd == SC_PIN_CMD_GET_SESSION_PIN) + if ((card->type == SC_CARD_TYPE_SC_HSM_SOC + || card->type == SC_CARD_TYPE_SC_HSM_GOID + || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN) && (data->cmd != SC_PIN_CMD_GET_INFO) #ifdef ENABLE_SM && card->sm_ctx.sm_mode != SM_MODE_TRANSMIT @@ -1575,7 +1611,8 @@ static int sc_hsm_init(struct sc_card *card) } card->max_send_size = 1431; // 1439 buffer size - 8 byte TLV because of odd ins in UPDATE BINARY - if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { + if (card->type == SC_CARD_TYPE_SC_HSM_SOC + || card->type == SC_CARD_TYPE_SC_HSM_GOID) { card->max_recv_size = 0x0630; // SoC Proxy forces this limit } else { card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index f7c78dd8a1..fb4f9d6a47 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -204,6 +204,7 @@ enum { /* SmartCard-HSM */ SC_CARD_TYPE_SC_HSM = 26000, SC_CARD_TYPE_SC_HSM_SOC = 26001, + SC_CARD_TYPE_SC_HSM_GOID = 26002, /* Spanish DNIe card */ SC_CARD_TYPE_DNIE_BASE = 27000, diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 26eaa05858..3829f2f3fc 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -941,7 +941,8 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) LOG_FUNC_RETURN(card->ctx, r); - if (card->type == SC_CARD_TYPE_SC_HSM_SOC) { + if (card->type == SC_CARD_TYPE_SC_HSM_SOC + || card->type == SC_CARD_TYPE_SC_HSM_GOID) { /* SC-HSM of this type always has a PIN-Pad */ r = SC_SUCCESS; } else { @@ -998,7 +999,8 @@ int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card, return sc_pkcs15emu_sc_hsm_init(p15card); } else { if (p15card->card->type != SC_CARD_TYPE_SC_HSM - && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC) { + && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC + && p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) { return SC_ERROR_WRONG_CARD; } return sc_pkcs15emu_sc_hsm_init(p15card); From a1466f7395945cdde8be7b005d69de3875dd7d06 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 11 Jul 2017 15:13:53 +0200 Subject: [PATCH 0042/4321] sc-hsm: better error messages for optional files --- src/libopensc/pkcs15-sc-hsm.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 3829f2f3fc..dd428fac5f 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -606,13 +606,13 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) { /* Try to select a related EF containing the PKCS#15 description of the key */ len = sizeof efbin; r = read_file(p15card, fid, efbin, &len, 1); - LOG_TEST_RET(card->ctx, r, "Could not read EF.PRKD"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD"); ptr = efbin; memset(&prkd, 0, sizeof(prkd)); r = sc_pkcs15_decode_prkdf_entry(p15card, &prkd, (const u8 **)&ptr, &len); - LOG_TEST_RET(card->ctx, r, "Could not decode EF.PRKD"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD"); /* All keys require user PIN authentication */ prkd.auth_id.len = 1; @@ -642,8 +642,6 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) { r = read_file(p15card, fid, efbin, &len, 0); LOG_TEST_RET(card->ctx, r, "Could not read EF"); - LOG_TEST_RET(card->ctx, r, "Could not read EF"); - if (efbin[0] == 0x67) { /* Decode CSR and create public key object */ sc_pkcs15emu_sc_hsm_add_pubkey(p15card, efbin, len, key_info, prkd.label); free(key_info); @@ -702,13 +700,13 @@ static int sc_pkcs15emu_sc_hsm_add_dcod(sc_pkcs15_card_t * p15card, u8 id) { /* Try to select a related EF containing the PKCS#15 description of the data */ len = sizeof efbin; r = read_file(p15card, fid, efbin, &len, 1); - LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD"); ptr = efbin; memset(&data_obj, 0, sizeof(data_obj)); r = sc_pkcs15_decode_dodf_entry(p15card, &data_obj, &ptr, &len); - LOG_TEST_RET(card->ctx, r, "Could not decode EF.DCOD"); + LOG_TEST_RET(card->ctx, r, "Could not decode optional EF.DCOD"); data_info = (sc_pkcs15_data_info_t *)data_obj.data; @@ -741,13 +739,13 @@ static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) { /* Try to select a related EF containing the PKCS#15 description of the data */ len = sizeof efbin; r = read_file(p15card, fid, efbin, &len, 1); - LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD"); ptr = efbin; memset(&obj, 0, sizeof(obj)); r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &len); - LOG_TEST_RET(card->ctx, r, "Could not decode EF.CD"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.CDOD"); cert_info = (sc_pkcs15_cert_info_t *)obj.data; @@ -772,10 +770,10 @@ static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card) /* Read token info */ len = sizeof efbin; r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len, 1); - LOG_TEST_RET(card->ctx, r, "Could not read EF.TokenInfo"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo"); r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, len); - LOG_TEST_RET(card->ctx, r, "Could not decode EF.TokenInfo"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -835,7 +833,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) } else { len = sizeof efbin; r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1); - LOG_TEST_RET(card->ctx, r, "Could not select EF.C_DevAut"); + LOG_TEST_RET(card->ctx, r, "Skipping optional EF.C_DevAut"); /* save EF_C_DevAut for further use */ ptr = realloc(priv->EF_C_DevAut, len); From d5647fe53d18154489320cae31402bb602da12e3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Aug 2017 14:20:56 +0200 Subject: [PATCH 0043/4321] [pkcs11-tool] Properly define RSA-PSS mechanisms --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f1ff0efb8b..edbf5ce20a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5622,9 +5622,9 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL }, { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL }, { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", NULL }, - { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS-PSS", NULL }, - { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS-PSS", NULL }, - { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS-PSS", NULL }, + { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", NULL }, + { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", NULL }, + { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", NULL }, { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL }, { CKM_DSA, "DSA", NULL }, { CKM_DSA_SHA1, "DSA-SHA1", NULL }, From 41796ff0ed3125bebe29479fc831165ba40c9a3b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Aug 2017 14:21:22 +0200 Subject: [PATCH 0044/4321] [pkcs11-tool] Add SHA2 HMAC mechanisms --- src/tools/pkcs11-tool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index edbf5ce20a..53d26da1cb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5671,8 +5671,11 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL }, { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL }, { CKM_SHA256, "SHA256", NULL }, + { CKM_SHA256_HMAC, "SHA256-HMAC", NULL }, { CKM_SHA384, "SHA384", NULL }, + { CKM_SHA384_HMAC, "SHA384-HMAC", NULL }, { CKM_SHA512, "SHA512", NULL }, + { CKM_SHA512_HMAC, "SHA512-HMAC", NULL }, { CKM_RIPEMD128, "RIPEMD128", NULL }, { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL }, { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL }, From 2765b7b1a097daa46e412b58933ec5a6e85f6ce3 Mon Sep 17 00:00:00 2001 From: Arnaud Fontaine Date: Tue, 22 Aug 2017 01:13:18 +0200 Subject: [PATCH 0045/4321] Support for new MinInt agent card (#1092) * Support for new MinInt agent card This card uses the same ATR as the existing card, but the applet installed does not have the same AID. This card actually works exactly as the IASECC_SAGEM. Unify iasecc_init for AMOS/SAGEM and MI cards --- src/libopensc/card-iasecc.c | 104 ++++++++++++------------------------ src/libopensc/cards.h | 1 + 2 files changed, 36 insertions(+), 69 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 9b97c18fa2..ea61db3cbb 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -264,6 +264,9 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) apdu.resplen = sizeof(apdu_resp); apdu.resp = apdu_resp; + if (card->type == SC_CARD_TYPE_IASECC_MI2) + apdu.p2 = 0x04; + rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); rv = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -514,38 +517,33 @@ iasecc_init_oberthur(struct sc_card *card) static int -iasecc_init_sagem(struct sc_card *card) +iasecc_mi_match(struct sc_card *card) { struct sc_context *ctx = card->ctx; - unsigned int flags; + unsigned char resp[0x100]; + size_t resp_len; int rv = 0; LOG_FUNC_CALLED(ctx); - flags = IASECC_CARD_DEFAULT_FLAGS; - - _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); - _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); - - card->caps = SC_CARD_CAP_RNG; - card->caps |= SC_CARD_CAP_APDU_EXT; - card->caps |= SC_CARD_CAP_USE_FCI_AC; + resp_len = sizeof(resp); + rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len); + LOG_TEST_RET(ctx, rv, "IASECC: failed to select MI IAS/ECC applet"); - rv = iasecc_parse_ef_atr(card); - if (rv == SC_ERROR_FILE_NOT_FOUND) { - rv = iasecc_select_mf(card, NULL); - LOG_TEST_RET(ctx, rv, "MF selection error"); + if (!card->ef_atr) + card->ef_atr = calloc(1, sizeof(struct sc_ef_atr)); + if (!card->ef_atr) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - rv = iasecc_parse_ef_atr(card); - } - LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed"); + memcpy(card->ef_atr->aid.value, MIIASECC_AID.value, MIIASECC_AID.len); + card->ef_atr->aid.len = MIIASECC_AID.len; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } static int -iasecc_init_amos(struct sc_card *card) +iasecc_init_amos_or_sagem(struct sc_card *card) { struct sc_context *ctx = card->ctx; unsigned int flags; @@ -562,6 +560,14 @@ iasecc_init_amos(struct sc_card *card) card->caps |= SC_CARD_CAP_APDU_EXT; card->caps |= SC_CARD_CAP_USE_FCI_AC; + if (card->type == SC_CARD_TYPE_IASECC_MI) { + rv = iasecc_mi_match(card); + if (rv) + card->type = SC_CARD_TYPE_IASECC_MI2; + else + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + } + rv = iasecc_parse_ef_atr(card); if (rv == SC_ERROR_FILE_NOT_FOUND) { rv = iasecc_select_mf(card, NULL); @@ -569,58 +575,11 @@ iasecc_init_amos(struct sc_card *card) rv = iasecc_parse_ef_atr(card); } - LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed"); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} - -static int -iasecc_mi_match(struct sc_card *card) -{ - struct sc_context *ctx = card->ctx; - - LOG_FUNC_CALLED(ctx); - - if (!card->ef_atr) - card->ef_atr = calloc(1, sizeof(struct sc_ef_atr)); - if (!card->ef_atr) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - - memcpy(card->ef_atr->aid.value, MIIASECC_AID.value, MIIASECC_AID.len); - card->ef_atr->aid.len = MIIASECC_AID.len; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } -static int -iasecc_init_mi(struct sc_card *card) -{ - struct sc_context *ctx = card->ctx; - unsigned int flags; - unsigned char resp[0x100]; - size_t resp_len; - int rv = 0; - - LOG_FUNC_CALLED(ctx); - - flags = IASECC_CARD_DEFAULT_FLAGS; - - _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); - _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); - - card->caps = SC_CARD_CAP_RNG; - card->caps |= SC_CARD_CAP_APDU_EXT; - card->caps |= SC_CARD_CAP_USE_FCI_AC; - - resp_len = sizeof(resp); - rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len); - LOG_TEST_RET(ctx, rv, "Could not select MI's AID"); - - rv = iasecc_mi_match(card); - LOG_TEST_RET(ctx, rv, "Could not match MI's AID"); - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} static int iasecc_init(struct sc_card *card) @@ -642,11 +601,11 @@ iasecc_init(struct sc_card *card) else if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR) rv = iasecc_init_oberthur(card); else if (card->type == SC_CARD_TYPE_IASECC_SAGEM) - rv = iasecc_init_sagem(card); + rv = iasecc_init_amos_or_sagem(card); else if (card->type == SC_CARD_TYPE_IASECC_AMOS) - rv = iasecc_init_amos(card); + rv = iasecc_init_amos_or_sagem(card); else if (card->type == SC_CARD_TYPE_IASECC_MI) - rv = iasecc_init_mi(card); + rv = iasecc_init_amos_or_sagem(card); else LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT); @@ -950,7 +909,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, && card->type != SC_CARD_TYPE_IASECC_OBERTHUR && card->type != SC_CARD_TYPE_IASECC_SAGEM && card->type != SC_CARD_TYPE_IASECC_AMOS - && card->type != SC_CARD_TYPE_IASECC_MI) + && card->type != SC_CARD_TYPE_IASECC_MI + && card->type != SC_CARD_TYPE_IASECC_MI2) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported card"); if (lpath.type == SC_PATH_TYPE_FILE_ID) { @@ -963,6 +923,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, apdu.p2 = 0x04; if (card->type == SC_CARD_TYPE_IASECC_MI) apdu.p2 = 0x04; + if (card->type == SC_CARD_TYPE_IASECC_MI2) + apdu.p2 = 0x04; } else if (lpath.type == SC_PATH_TYPE_FROM_CURRENT) { apdu.p1 = 0x09; @@ -972,6 +934,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, apdu.p2 = 0x04; if (card->type == SC_CARD_TYPE_IASECC_MI) apdu.p2 = 0x04; + if (card->type == SC_CARD_TYPE_IASECC_MI2) + apdu.p2 = 0x04; } else if (lpath.type == SC_PATH_TYPE_PARENT) { apdu.p1 = 0x03; @@ -982,6 +946,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, apdu.p1 = 0x04; if (card->type == SC_CARD_TYPE_IASECC_AMOS) apdu.p2 = 0x04; + if (card->type == SC_CARD_TYPE_IASECC_MI2) + apdu.p2 = 0x04; } else { sc_log(ctx, "Invalid PATH type: 0x%X", lpath.type); diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index fb4f9d6a47..0cc7650e12 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -200,6 +200,7 @@ enum { SC_CARD_TYPE_IASECC_SAGEM, SC_CARD_TYPE_IASECC_AMOS, SC_CARD_TYPE_IASECC_MI, + SC_CARD_TYPE_IASECC_MI2, /* SmartCard-HSM */ SC_CARD_TYPE_SC_HSM = 26000, From 172f320c9a1b5664240be5fa3e143622941b2845 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 17 Jul 2017 22:53:07 +0200 Subject: [PATCH 0046/4321] win32: Dedicated md/pkcs11 installation folders Don't install non-permanent files (md/pkcs11) to system folder anymore. --- configure.ac | 6 +- src/minidriver/Makefile.am | 4 +- src/minidriver/minidriver-feitian.reg | 30 -------- src/minidriver/minidriver-italian-cns.reg | 33 --------- src/minidriver/minidriver-sc-hsm.reg | Bin 1460 -> 0 bytes src/minidriver/minidriver-westcos.reg | 7 -- src/pkcs11/pkcs11-spy.c | 2 +- src/pkcs11/sc-pkcs11.h | 6 -- src/tools/pkcs11-tool.c | 13 +++- win32/OpenSC.wxs.in | 80 +++++++++++----------- win32/customactions.cpp | 17 +++-- 11 files changed, 73 insertions(+), 125 deletions(-) delete mode 100644 src/minidriver/minidriver-feitian.reg delete mode 100644 src/minidriver/minidriver-italian-cns.reg delete mode 100644 src/minidriver/minidriver-sc-hsm.reg delete mode 100644 src/minidriver/minidriver-westcos.reg diff --git a/configure.ac b/configure.ac index ba45c2109b..e1c3f8a02a 100644 --- a/configure.ac +++ b/configure.ac @@ -784,7 +784,11 @@ if test "${enable_sm}" = "yes"; then fi if test "${with_pkcs11_provider}" = "detect"; then - DEFAULT_PKCS11_PROVIDER="opensc-pkcs11${DYN_LIB_EXT}" + if test "${WIN32}" != "yes"; then + DEFAULT_PKCS11_PROVIDER="opensc-pkcs11${DYN_LIB_EXT}" + else + DEFAULT_PKCS11_PROVIDER="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\pkcs11\\\opensc-pkcs11.dll" + fi else DEFAULT_PKCS11_PROVIDER="${with_pkcs11_provider}" fi diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index 6448e7aeea..d276f97e8f 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -7,9 +7,9 @@ if ENABLE_MINIDRIVER lib_LTLIBRARIES = opensc-minidriver@LIBRARY_BITNESS@.la # Do we need this on bin? Why can't we # put it in dedicated directory -dist_sbin_SCRIPTS = opensc-minidriver.inf minidriver-westcos.reg minidriver-sc-hsm.reg minidriver-feitian.reg +dist_sbin_SCRIPTS = opensc-minidriver.inf else -dist_noinst_DATA = opensc-minidriver.inf minidriver-westcos.reg minidriver-sc-hsm.reg minidriver-feitian.reg +dist_noinst_DATA = opensc-minidriver.inf endif AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) diff --git a/src/minidriver/minidriver-feitian.reg b/src/minidriver/minidriver-feitian.reg deleted file mode 100644 index 446ef1cfef..0000000000 --- a/src/minidriver/minidriver-feitian.reg +++ /dev/null @@ -1,30 +0,0 @@ -Windows Registry Editor Version 5.00 - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\ePass2003] -"ATR"=hex:3b,9f,95,81,31,fe,9f,00,66,46,53,05,01,00,11,71,df,00,00,03,6a,82,f8 -"ATRMask"=hex,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" - -[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\ePass2003] -"ATR"=hex:3b,9f,95,81,31,fe,9f,00,66,46,53,05,01,00,11,71,df,00,00,03,6a,82,f8 -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" - - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\FTCOS/PK-01C] -"ATR"=hex:3b,9f,95,81,31,fe,9f,00,65,46,53,05,00,06,71,df,00,00,00,00,00,00,00 -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,00,00,00,00 -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" - -[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\FTCOS/PK-01C] -"ATR"=hex:3b,9f,95,81,31,fe,9f,00,65,46,53,05,00,06,71,df,00,00,00,00,00,00,00 -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,00,ff,ff,ff,ff,ff,ff,00,00,00,00 -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" diff --git a/src/minidriver/minidriver-italian-cns.reg b/src/minidriver/minidriver-italian-cns.reg deleted file mode 100644 index 3bca8d4ad8..0000000000 --- a/src/minidriver/minidriver-italian-cns.reg +++ /dev/null @@ -1,33 +0,0 @@ -Windows Registry Editor Version 5.00 - -[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\CPS] -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" -"ATR"=hex:3b,ff,18,00,ff,c1,0a,31,fe,55,00,6b,05,08,c8,0c,01,11,01,43,4e,53,10,\ - 31,80,05 -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ - ff,ff,ff,ff,ff - -[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\CPS-Athena] -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" -"ATR"=hex:3b,df,18,00,81,31,fe,7d,00,6b,02,0c,01,82,01,11,01,43,4e,53,10,31,80,fc -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\CPS] -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" -"ATR"=hex:3b,ff,18,00,ff,c1,0a,31,fe,55,00,6b,05,08,c8,0c,01,11,01,43,4e,53,10,\ - 31,80,05 -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,\ - ff,ff,ff,ff,ff - -[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\CPS-Athena] -"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" -"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" -"80000001"="opensc-minidriver.dll" -"ATR"=hex:3b,df,18,00,81,31,fe,7d,00,6b,02,0c,01,82,01,11,01,43,4e,53,10,31,80,fc -"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff diff --git a/src/minidriver/minidriver-sc-hsm.reg b/src/minidriver/minidriver-sc-hsm.reg deleted file mode 100644 index 38598b2cd21547baba26ef38c8cd7bfaa15c26f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1460 zcmd^|u?##oRreVNb9|+-KZN%B#Ry*P7cG zI?xd@=jy4h6VgMptk=Z&FkuyO) zxcc+lrY!$G&mvDxr+CJAT8woo&HBAQPgU5?@$nWa@IGoV?X&)6d9CX{9cdu2kd zCv9m{R|@Fi5Lu+kz}1(@3Rr-T$6T6G& Q? #ifndef _WIN32 -#include #include #include +#include #else +#include #include #endif @@ -537,6 +538,9 @@ int main(int argc, char * argv[]) CK_RV rv; #ifdef _WIN32 + char expanded_val[PATH_MAX]; + DWORD expanded_len; + if(_setmode(_fileno(stdout), _O_BINARY ) == -1) util_fatal("Cannot set FMODE to O_BINARY"); if(_setmode(_fileno(stdin), _O_BINARY ) == -1) @@ -844,6 +848,13 @@ int main(int argc, char * argv[]) if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); +#ifdef _WIN32 + expanded_len = PATH_MAX; + expanded_len = ExpandEnvironmentStringsA(opt_module, expanded_val, expanded_len); + if (0 < expanded_len && expanded_len < sizeof expanded_val) + opt_module = expanded_val; +#endif + module = C_LoadModule(opt_module, &p11); if (module == NULL) util_fatal("Failed to load pkcs11 module"); diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 9ae8b21031..52121028f5 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -7,7 +7,6 @@ - @@ -17,7 +16,6 @@ - @@ -59,47 +57,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -113,6 +74,38 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -288,6 +281,15 @@ + + + + + + + + + diff --git a/win32/customactions.cpp b/win32/customactions.cpp index f576fc6eac..f417d74bdf 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -64,12 +64,10 @@ typedef struct _MD_REGISTRATION For example, do not uninstall the minidriver for a card if a middleware is already installed */ MD_REGISTRATION minidriver_registration[] = { - /* from minidriver-feitian.reg */ {TEXT("ePass2003"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x66,0x46,0x53,0x05,0x01,0x00,0x11,0x71,0xdf,0x00,0x00,0x03,0x6a,0x82,0xf8}, 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("FTCOS/PK-01C"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x65,0x46,0x53,0x05,0x00,0x06,0x71,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00}}, - /* from minidriver-sc-hsm.reg */ {TEXT("SmartCard-HSM"), {0x3b,0xfe,0x18,0x00,0x00,0x81,0x31,0xfe,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4d,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xfa}, 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("SmartCard-HSM-CL"), {0x3B,0x8E,0x80,0x01,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x18}, @@ -100,7 +98,6 @@ MD_REGISTRATION minidriver_registration[] = { 19, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, {TEXT("GoID (11)"), {0x3B,0x8f,0x80,0x01,0x47,0x6f,0x49,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 20, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - /* from minidriver-westcos.reg */ {TEXT("CEV WESTCOS"), {0x3f,0x69,0x00,0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x80,0x90,0x00}, 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xf0,0xff,0xff}}, /* from card-openpgp.c */ @@ -254,8 +251,18 @@ void RegisterCardWithKey(PTSTR szKey, PTSTR szCard, PTSTR szPath, PBYTE pbATR, D VOID RegisterSmartCard(PMD_REGISTRATION registration) { - RegisterCardWithKey(SC_DATABASE, registration->szName, TEXT("opensc-minidriver.dll"),registration->pbAtr, registration->dwAtrSize, registration->pbAtrMask ); - + DWORD expanded_len = PATH_MAX; + TCHAR expanded_val[PATH_MAX]; + PTSTR szPath = TEXT("C:\\Program Files\\OpenSC Project\\OpenSC\\minidriver\\opensc-minidriver.dll"); + + /* cope with x86 installation on x64 */ + expanded_len = ExpandEnvironmentStrings( + TEXT("%ProgramFiles%\\OpenSC Project\\OpenSC\\minidriver\\opensc-minidriver.dll"), + expanded_val, expanded_len); + if (0 < expanded_len && expanded_len < sizeof expanded_val) + szPath = expanded_val; + + RegisterCardWithKey(SC_DATABASE, registration->szName, szPath, registration->pbAtr, registration->dwAtrSize, registration->pbAtrMask ); } UINT WINAPI AddSmartCardConfiguration(MSIHANDLE hInstall) From 555671b54d307a0b62cca8de63b74e2f248fd877 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Aug 2017 21:46:21 +0200 Subject: [PATCH 0047/4321] sc_read_binary may return less bytes than requested Note, that there are a number of card drivers that still use `sc_read_binary` in the wrong way. Unfortunately, I don't have the time to go through all of them. Fixes https://github.com/OpenSC/OpenSC/issues/1112 --- src/libopensc/pkcs15.c | 33 ++++++++++++++++++--------------- src/pkcs15init/pkcs15-lib.c | 2 +- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 2ce34b6c02..05fe030610 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1059,15 +1059,17 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) } if (err < 0) { err = sc_read_binary(card, 0, buf, len, 0); - if (err < 0) { - sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err)); - goto end; - } - else if (err < 2) { - err = SC_ERROR_PKCS15_APP_NOT_FOUND; - sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err)); + if (err < 2) { + if (err < 0) { + sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err)); + } else { + err = SC_ERROR_PKCS15_APP_NOT_FOUND; + sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err)); + } goto end; } + /* sc_read_binary may return less than requested */ + len = err; if (p15card->opts.use_file_cache) { sc_pkcs15_cache_file(p15card, &tmppath, buf, len); @@ -1125,20 +1127,21 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) } if (err < 0) { err = sc_read_binary(card, 0, buf, len, 0); - if (err < 0) { - sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err)); - goto end; - } if (err <= 2) { - err = SC_ERROR_PKCS15_APP_NOT_FOUND; - sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err)); + if (err < 0) { + sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err)); + } else { + err = SC_ERROR_PKCS15_APP_NOT_FOUND; + sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err)); + } goto end; } + /* sc_read_binary may return less than requested */ + len = err; if (p15card->opts.use_file_cache) { sc_pkcs15_cache_file(p15card, &tmppath, buf, len); } - err = len; } memset(&tokeninfo, 0, sizeof(tokeninfo)); @@ -2392,7 +2395,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_file_free(file); - if (p15card->opts.use_file_cache) { + if (len && p15card->opts.use_file_cache) { sc_pkcs15_cache_file(p15card, in_path, data, len); } } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 9339aebbac..5dfe2be6b5 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4211,7 +4211,7 @@ sc_pkcs15init_read_info(struct sc_card *card, struct sc_profile *profile) } if (r >= 0) - r = sc_pkcs15init_parse_info(card, mem, len, profile); + r = sc_pkcs15init_parse_info(card, mem, r, profile); if (mem) free(mem); From 1efc73fa2fe86678f8c89a36756cec634de1d7de Mon Sep 17 00:00:00 2001 From: Mouse Date: Thu, 24 Aug 2017 21:27:47 -0400 Subject: [PATCH 0048/4321] Fix typo in ECDSA-SHA384 for pkcs11-tool --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8aa1cffe37..64f11c89d8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5784,7 +5784,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_ECDSA_SHA1, "ECDSA-SHA1", NULL }, { CKM_ECDSA_SHA224, "ECDSA-SHA224", NULL }, { CKM_ECDSA_SHA256, "ECDSA-SHA256", NULL }, - { CKM_ECDSA_SHA384, "ECDSA-SHA348", NULL }, + { CKM_ECDSA_SHA384, "ECDSA-SHA384", NULL }, { CKM_ECDSA_SHA512, "ECDSA-SHA512", NULL }, { CKM_ECDH1_DERIVE, "ECDH1-DERIVE", NULL }, { CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL }, From f0e703be4935cadd76d8773c4ce5bd3ad7386da0 Mon Sep 17 00:00:00 2001 From: Mouse Date: Tue, 29 Aug 2017 00:31:39 -0400 Subject: [PATCH 0049/4321] Fix bug in pkcs11-tool (did not ASN.1-encode ECDSA-SHA-2 signature) --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 64f11c89d8..4240a0c30b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1670,7 +1670,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("failed to open %s: %m", opt_output); } - if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1) { + if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512) { if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { unsigned char *seq; size_t seqlen; From 56c8f59b25c222cfe2b57dcf78c8bbc26eb595df Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 Aug 2017 13:49:57 +0200 Subject: [PATCH 0050/4321] Use shorter PIN name for default PIN to accomodate Card Holder name in future --- src/libopensc/pkcs15-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index d38d7ba736..7f9015dccf 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -359,7 +359,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) }; static const pindata pins[] = { - { "01", "PIV Card Holder pin", "", 0x80, + { "01", "PIN", "", 0x80, /* label, flag and ref will change if using global pin */ SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 8, 4, 8, @@ -932,7 +932,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.reference = pin_ref; pin_info.attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; label = "Global PIN"; - } + } sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; From d018855b9ff638698ff063c0157039ae2f45721b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 Aug 2017 14:18:00 +0200 Subject: [PATCH 0051/4321] Get cardholder name from the first certificate --- src/libopensc/pkcs15-piv.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 7f9015dccf..6f3c9199d8 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -613,7 +613,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) char buf[SC_MAX_SERIALNR * 2 + 1]; common_key_info ckis[PIV_NUM_CERTS_AND_KEYS]; int follows_nist_fascn = 0; - + char *token_name = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -765,6 +765,28 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); continue; } + + /* set the token name to the name of the CN of the first certificate */ + if (!token_name) { + u8 * cn_name = NULL; + size_t cn_len = 0; + static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; + r = sc_pkcs15_get_name_from_dn(card->ctx, cert_out->subject, + cert_out->subject_len, &cn_oid, &cn_name, &cn_len); + if (r == SC_SUCCESS) { + token_name = malloc (cn_len+1); + if (!token_name) { + SC_FUNC_RETURN(card->ctx, + SC_ERROR_OUT_OF_MEMORY, r); + } + memcpy(token_name, cn_name, cn_len); + free(cn_name); + token_name[cn_len] = 0; + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = token_name; + } + } + /* * get keyUsage if present save in ckis[i] * Will only use it if this in a non FED issued card From 804f47b2988d3b21233d8e90dbe79dd22e5c9757 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 21 Aug 2017 13:43:08 +0200 Subject: [PATCH 0052/4321] Do not add non-informative PIN to the token label --- src/pkcs11/framework-pkcs15.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 5b3cb32e54..8ded1125b5 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1024,6 +1024,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, struct sc_pkcs15_auth_info *pin_info = NULL; char label[64]; + sc_log(context, "Called"); pkcs15_init_token_info(p15card, &slot->token_info); slot->token_info.flags |= CKF_TOKEN_INITIALIZED; if (auth != NULL) @@ -1048,9 +1049,10 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, pin_info = NULL; } else { - if (auth->label[0]) + if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) snprintf(label, sizeof(label), "%.*s (%s)", (int) sizeof auth->label, auth->label, p15card->tokeninfo->label); else + /* The PIN label is empty or says just non-useful "PIN" */ snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label); slot->token_info.flags |= CKF_LOGIN_REQUIRED; } From eee4964d7fc9f134eb50caab2f011490dd05f281 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 22 Aug 2017 10:29:40 +0200 Subject: [PATCH 0053/4321] The cardos driver supports also CardOS 5 CardOS M4 is confusing since it refers to the old card versions --- src/libopensc/card-cardos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 41e28835f4..bbdb814e8f 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -171,7 +171,7 @@ static int cardos_init(sc_card_t *card) sc_apdu_t apdu; u8 rbuf[2]; - card->name = "CardOS M4"; + card->name = "Atos CardOS"; card->cla = 0x00; /* Set up algorithm info. */ From 60dbebf511cf6112e5fc2c3549ce38881847b121 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 22 Aug 2017 10:46:26 +0200 Subject: [PATCH 0054/4321] Parse the ECC parameters from TokenInfo (CHOICE in AlgorithmInfo) Fixes #1134 --- src/libopensc/opensc.h | 1 + src/libopensc/pkcs15.c | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index f81f27e3ae..688c14003a 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -163,6 +163,7 @@ extern "C" { struct sc_supported_algo_info { unsigned int reference; unsigned int mechanism; + struct sc_object_id *parameters; /* OID for ECC, NULL for RSA */ unsigned int operations; struct sc_object_id algo_id; unsigned int algo_ref; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 05fe030610..ba99c8af9a 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -50,13 +50,19 @@ static const struct sc_asn1_entry c_asn1_twlabel[] = { static const struct sc_asn1_entry c_asn1_algorithm_info[7] = { { "reference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, { "algorithmPKCS#11", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { "parameters", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "parameters", SC_ASN1_CHOICE, 0, 0, NULL, NULL }, { "supportedOperations",SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, { "objId", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL }, { "algRef", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; +static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = { + { "PKCS15RSAParameters",SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "PKCS15ECParameters", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + /* * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 */ @@ -134,9 +140,11 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, u8 preferred_language[3]; size_t lang_length = sizeof(preferred_language); struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1], - asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7]; + asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7], + asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3]; size_t reference_len = sizeof(ti->supported_algos[0].reference); size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism); + size_t parameter_len = sizeof(ti->supported_algos[0].parameters); size_t operations_len = sizeof(ti->supported_algos[0].operations); size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref); @@ -152,14 +160,22 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0); sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication); - for (ii=0; iisupported_algos[ii].reference, &reference_len, 0); sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0); - sc_format_asn1_entry(asn1_algo_infos[ii] + 2, NULL, NULL, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 2, + asn1_algo_infos_parameters[ii], NULL, 0); + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0, + NULL, NULL, 0); + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1, + &ti->supported_algos[ii].parameters, ¶meter_len, 0); sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0); sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0); @@ -270,9 +286,11 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE]; struct sc_asn1_entry asn1_tokeninfo[2]; struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1], - asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7]; + asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7], + asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3]; size_t reference_len = sizeof(ti->supported_algos[0].reference); size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism); + size_t parameter_len = sizeof(ti->supported_algos[0].parameters); size_t operations_len = sizeof(ti->supported_algos[0].operations); size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref); struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE]; @@ -283,14 +301,22 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update); sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication); - for (ii=0; iisupported_algos[ii].reference; ii++) + for (ii=0; iisupported_algos[ii].reference; ii++) { sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]); + sc_copy_asn1_entry(c_asn1_algorithm_info_parameters, + asn1_algo_infos_parameters[ii]); + } sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms); for (ii=0; iisupported_algos[ii].reference; ii++) { sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1); - sc_format_asn1_entry(asn1_algo_infos[ii] + 2, NULL, NULL, 0); + sc_format_asn1_entry(asn1_algo_infos[ii] + 2, + asn1_algo_infos_parameters[ii], NULL, 0); + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0, + NULL, NULL, 0); + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1, + &ti->supported_algos[ii].parameters, ¶meter_len, 0); sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 1); From eeeefecf122e9a81ddc82ab3ec716953d2b1c387 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 22 Aug 2017 10:51:18 +0200 Subject: [PATCH 0055/4321] Add newly reported ATR for CardOS 5.3 --- src/libopensc/card-cardos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index bbdb814e8f..077191731a 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -59,6 +59,7 @@ static struct sc_atr_table cardos_atrs[] = { /* CardOS v5.0 */ { "3b:d2:18:00:81:31:fe:58:c9:01:14", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, /* CardOS v5.3 */ + { "3b:d2:18:00:81:31:fe:58:c9:02:17", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, { "3b:d2:18:00:81:31:fe:58:c9:03:16", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, { NULL, NULL, NULL, 0, 0, NULL } }; From 789dd16320ed449e4f60842791fe71282bbb77f3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 22 Aug 2017 14:10:02 +0200 Subject: [PATCH 0056/4321] List human-readable version in the cardos-tool --- src/tools/cardos-tool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index c3c6406be2..cccc76d323 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -188,6 +188,9 @@ static int cardos_info(void) printf(" (that's CardOS M4.4)\n"); } else if (apdu.resp[0] == 0xc9 && apdu.resp[1] == 0x01) { printf(" (that's CardOS V5.0)\n"); + } else if (apdu.resp[0] == 0xc9 && + (apdu.resp[1] == 0x02 || apdu.resp[1] == 0x03)) { + printf(" (that's CardOS V5.3)\n"); } else { printf(" (unknown Version)\n"); } From 5882df745a746783a759e11bdeb1d38b73f18ee7 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Thu, 31 Aug 2017 15:20:41 -0400 Subject: [PATCH 0057/4321] Use |, not ||, when decoding CAC key_reference This quiets two compiler warnings and is almost surely what was actually meant. However, I do not have a CAC card to test. --- src/libopensc/pkcs15-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index fa76ec34ea..609d5fad83 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -323,8 +323,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) prkey_info.path.len += 2; } pubkey_info.native = 1; - pubkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 || obj_info.id.value[1]; - prkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 || obj_info.id.value[1]; + pubkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 | obj_info.id.value[1]; + prkey_info.key_reference = ((int)obj_info.id.value[0]) << 8 | obj_info.id.value[1]; prkey_info.native = 1; memcpy(cert_obj.label, obj_info.app_label, sizeof(obj_info.app_label)); From ab8a51a1ab61057c66482d4f225c49888ef24ac3 Mon Sep 17 00:00:00 2001 From: vletoux Date: Fri, 1 Sep 2017 11:01:04 +0200 Subject: [PATCH 0058/4321] Fix wrong padding for GIDS admin authentication --- src/libopensc/card-gids.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 923cf3bd9a..930dd0514e 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1879,8 +1879,6 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { u8 apduSetRandomResponse[256]; u8* randomR2 = apduSetRandomResponse+4; u8 apduSendReponse[40 + 4] = {0x7C,0x2A,0x82,0x28}; - // according to the specification, the z size (z1||z2) should be 14 bytes - // but because the buffer must be a multiple of the 3DES block size (8 bytes), 7 isn't working u8 z1[8]; u8 buffer[16+16+8]; u8* buffer2 = apduSendReponse + 4; @@ -1923,8 +1921,10 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // compute the half size of the mutual authentication secret - r = RAND_bytes(z1, sizeof(z1)); + r = RAND_bytes(z1, 7); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to set computer random"); + // set the padding + z1[7] = 0x80; // Encrypt R2||R1||Z1 memcpy(buffer, randomR2, 16); From 00535f0174698300ca39c431fe34b7a9f76e5ed8 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Thu, 31 Aug 2017 15:27:47 -0400 Subject: [PATCH 0059/4321] sc_pkcs15_get_bitstring_extension: int, not long long Use the ASN.1 decoder's SC_ASN1_BIT_FIELD decoder to properly decode into a machine word. As _bitstring_extension is used only for the OID 2.5.29.15 by all callers, which is at most 9 bits wide, this is a reasonable thing to do. --- src/libopensc/pkcs15-cac.c | 6 +++--- src/libopensc/pkcs15-cert.c | 4 ++-- src/libopensc/pkcs15-piv.c | 6 ++---- src/libopensc/pkcs15.h | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 609d5fad83..fd463a9b4f 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -139,7 +139,7 @@ cac_alg_flags_from_algorithm(int algorithm) /* map a cert usage and algorithm to public and private key usages */ static int -cac_map_usage(unsigned long long cert_usage, int algorithm, unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr, int allow_nonrepudiation) +cac_map_usage(unsigned int cert_usage, int algorithm, unsigned int *pub_usage_ptr, unsigned int *pr_usage_ptr, int allow_nonrepudiation) { unsigned int pub_usage = 0, pr_usage = 0; unsigned int alg_flags = cac_alg_flags_from_algorithm(algorithm); @@ -184,7 +184,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) }; /* oid for key usage */ static const struct sc_object_id usage_type = {{ 2, 5, 29, 15, -1 }}; - unsigned long long usage; + unsigned int usage; /* @@ -401,7 +401,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) usage = 0xd9ULL; /* basic default usage */ } cac_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cert %s: cert_usage=0x%llx, pub_usage=0x%x priv_usage=0x%x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n", sc_dump_hex(cert_info.id.value, cert_info.id.len), usage, pubkey_info.usage, prkey_info.usage); if (cert_out->key->algorithm != SC_ALGORITHM_RSA) { diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 5a607e161c..b7b16bb7a5 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -310,13 +310,13 @@ sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert, int sc_pkcs15_get_bitstring_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert, const struct sc_object_id *type, - unsigned long long *value, int *is_critical) + unsigned int *value, int *is_critical) { int r; u8 *bit_string = NULL; size_t bit_string_len=0, val_len = sizeof(*value); struct sc_asn1_entry asn1_bit_string[] = { - { "bitString", SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, value, &val_len }, + { "bitString", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, value, &val_len }, { NULL, 0, 0, 0, NULL, NULL } }; diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 6f3c9199d8..73fc2d4867 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -104,7 +104,7 @@ typedef struct common_key_info_st { int pubkey_from_file; int key_alg; unsigned int pubkey_len; - unsigned long long cert_keyUsage; /* x509 key usage as defined in certificate */ + unsigned int cert_keyUsage; /* x509 key usage as defined in certificate */ int cert_keyUsage_present; /* 1 if keyUsage found in certificate */ int pub_usage; int priv_usage; @@ -795,13 +795,11 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) if (follows_nist_fascn == 0) { struct sc_object_id keyUsage_oid={{2,5,29,15,-1}}; - unsigned long long *value; int r = 0; - value = &ckis[i].cert_keyUsage; r = sc_pkcs15_get_bitstring_extension(card->ctx, cert_out, &keyUsage_oid, - value, NULL); + &ckis[i].cert_keyUsage, NULL); if ( r >= 0) ckis[i].cert_keyUsage_present = 1; /* TODO if no key usage, we could set all uses */ diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 7d922c397d..b6a2dd3406 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -738,7 +738,7 @@ int sc_pkcs15_get_extension(struct sc_context *ctx, int sc_pkcs15_get_bitstring_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert, const struct sc_object_id *type, - unsigned long long *value, + unsigned int *value, int *is_critical); /* sc_pkcs15_create_cdf: Creates a new certificate DF on a card pointed * by . Information about the file, such as the file ID, is read From 2cf0a119f428585469c1ec2258aacc343c28c8ff Mon Sep 17 00:00:00 2001 From: Pavel Cherezov Date: Tue, 12 Sep 2017 16:08:22 +0300 Subject: [PATCH 0060/4321] sensitive flag added to generate key with CKA_SENSITIVE flag --- src/tools/pkcs11-tool.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4240a0c30b..73023b48d8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -134,6 +134,7 @@ enum { OPT_KEY_USAGE_DECRYPT, OPT_KEY_USAGE_DERIVE, OPT_PRIVATE, + OPT_SENSITIVE, OPT_TEST_HOTPLUG, OPT_UNLOCK_PIN, OPT_PUK, @@ -204,6 +205,7 @@ static const struct option options[] = { { "moz-cert", 1, NULL, 'z' }, { "verbose", 0, NULL, 'v' }, { "private", 0, NULL, OPT_PRIVATE }, + { "sensitive", 0, NULL, OPT_SENSITIVE }, { "test-ec", 0, NULL, OPT_TEST_EC }, #ifndef _WIN32 { "test-fork", 0, NULL, OPT_TEST_FORK }, @@ -269,6 +271,7 @@ static const char *option_help[] = { "Test Mozilla-like keypair gen and cert req, =certfile", "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", "Set the CKA_PRIVATE attribute (object is only viewable after a login)", + "Set the CKA_SENSITIVE attribute (object is protected by HSM)", "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 "Test forking and calling C_Initialize() in the child", @@ -308,6 +311,7 @@ static char * opt_subject = NULL; static char * opt_key_type = NULL; static char * opt_sig_format = NULL; static int opt_is_private = 0; +static int opt_is_sensitive = 0; static int opt_test_hotplug = 0; static int opt_login_type = -1; static int opt_key_usage_sign = 0; @@ -808,6 +812,9 @@ int main(int argc, char * argv[]) case OPT_PRIVATE: opt_is_private = 1; break; + case OPT_SENSITIVE: + opt_is_sensitive = 1; + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -1329,7 +1336,7 @@ static int login(CK_SESSION_HANDLE session, int login_type) pin_flags=info.flags & ( CKF_SO_PIN_COUNT_LOW | CKF_SO_PIN_FINAL_TRY | - CKF_SO_PIN_LOCKED | + CKF_SO_PIN_LOCKED | CKF_SO_PIN_TO_BE_CHANGED); if(pin_flags) printf("WARNING: %s\n",p11_token_info_flags(pin_flags)); @@ -1340,7 +1347,7 @@ static int login(CK_SESSION_HANDLE session, int login_type) pin_flags=info.flags & ( CKF_USER_PIN_COUNT_LOW | CKF_USER_PIN_FINAL_TRY | - CKF_USER_PIN_LOCKED | + CKF_USER_PIN_LOCKED | CKF_USER_PIN_TO_BE_CHANGED); if(pin_flags) printf("WARNING: %s\n",p11_token_info_flags(pin_flags)); @@ -2039,6 +2046,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey CK_MECHANISM mechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0}; CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY; CK_BBOOL _true = TRUE; + CK_BBOOL _false = FALSE; CK_KEY_TYPE key_type = CKK_AES; CK_ULONG key_length; CK_ATTRIBUTE keyTemplate[20] = { @@ -2113,6 +2121,15 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Unknown key type %s", type); } + if (opt_is_sensitive != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); + n_attr++; + } + else { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); + n_attr++; + } + FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); n_attr++; FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); From ecb1656b91ce8de8de095f1ab1d5097304c02420 Mon Sep 17 00:00:00 2001 From: Pavel Cherezov Date: Tue, 12 Sep 2017 16:08:22 +0300 Subject: [PATCH 0061/4321] sensitive flag added to generate key with CKA_SENSITIVE flag. pull request issues fix: replace spaces with tabs and fix description of the argument. --- src/tools/pkcs11-tool.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 73023b48d8..9392760840 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -271,7 +271,7 @@ static const char *option_help[] = { "Test Mozilla-like keypair gen and cert req, =certfile", "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", "Set the CKA_PRIVATE attribute (object is only viewable after a login)", - "Set the CKA_SENSITIVE attribute (object is protected by HSM)", + "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 "Test forking and calling C_Initialize() in the child", @@ -2121,14 +2121,14 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Unknown key type %s", type); } - if (opt_is_sensitive != 0) { - FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); - n_attr++; - } - else { - FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); - n_attr++; - } + if (opt_is_sensitive != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); + n_attr++; + } + else { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); + n_attr++; + } FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); n_attr++; From 0a8213f3d418cc54b94511bd876288622c19503e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Sep 2017 17:41:20 +0200 Subject: [PATCH 0062/4321] Do not overwrite digestinfo + hash for RSA-PKCS Signature --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9392760840..e7bf1d5956 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4338,14 +4338,14 @@ static int test_signature(CK_SESSION_HANDLE sess) break; case CKM_RSA_X_509: dataLen = modLenBytes; + pseudo_randomize(data, dataLen); break; default: dataLen = sizeof(data); /* let's hope it's OK */ + pseudo_randomize(data, dataLen); break; } - pseudo_randomize(data, dataLen); - if (firstMechType == CKM_RSA_X_509) { /* make sure our data is smaller than the modulus */ data[0] = 0x00; From 41b55b93d48491b9eddcb4df9b605b702334cb8f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Sep 2017 17:42:28 +0200 Subject: [PATCH 0063/4321] Print well formated report from decryption stage and do not fail with OAEP mechanisms --- src/tools/pkcs11-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e7bf1d5956..ec681a2d85 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4864,7 +4864,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; if (EVP_PKEY_size(pkey) > (int)sizeof(encrypted)) { - fprintf(stderr, "Ciphertext buffer too small\n"); + printf("Ciphertext buffer too small\n"); EVP_PKEY_free(pkey); return 0; } @@ -4875,14 +4875,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, #endif EVP_PKEY_free(pkey); if (((int) encrypted_len) <= 0) { - fprintf(stderr, "Encryption failed, returning\n"); + printf("Encryption failed, returning\n"); return 0; } mech.mechanism = mech_type; rv = p11->C_DecryptInit(session, &mech, privKeyObject); - if (rv == CKR_MECHANISM_INVALID) { - fprintf(stderr, "Mechanism not supported\n"); + if (rv == CKR_MECHANISM_INVALID || rv == CKR_MECHANISM_PARAM_INVALID) { + printf("Mechanism not supported\n"); return 0; } if (rv != CKR_OK) From 8965ee38dde5a394e0c1264136324b2d855a1d69 Mon Sep 17 00:00:00 2001 From: vletoux Date: Fri, 15 Sep 2017 21:22:26 +0200 Subject: [PATCH 0064/4321] Gids verified mutual auth --- src/libopensc/card-gids.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 930dd0514e..a10de90295 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1884,6 +1884,8 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { u8* buffer2 = apduSendReponse + 4; int buffer2size = 40; u8 apduSendResponseResponse[256]; + u8 buffer3[16+16+8]; + int buffer3size = 40; sc_apdu_t apdu; const EVP_CIPHER *cipher; @@ -1963,6 +1965,47 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + + if (apdu.resplen != 44) + { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Expecting a response len of 44 - found %d",(int) apdu.resplen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + } + // init crypto + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + } + if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { + EVP_CIPHER_CTX_free(ctx); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + } + EVP_CIPHER_CTX_set_padding(ctx,0); + if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt data"); + EVP_CIPHER_CTX_free(ctx); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + } + if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt final data"); + EVP_CIPHER_CTX_free(ctx); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + } + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "data has been decrypted using the key"); + if (memcmp(buffer3, randomR1, 16) != 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R1 doesn't match"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + } + if (memcmp(buffer3 + 16, randomR2, 16) != 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R2 doesn't match"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + } + if (buffer[39] != 0x80) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding not found"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); #endif From bdb1961dee1aa0e67eb23f474f9a5dcf7d4e316d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 21 Sep 2017 11:19:22 +0200 Subject: [PATCH 0065/4321] Enable RSA-PSS signatures in pkcs11-tool (#1146) * Add missing SHA224 RSA algorithms * Fix wrong replacement in pkcs11-tool manual page * Add MGF and PSS_PARAMS definitions in PKCS#11 header file * Inspect PSS signature parameters in pkcs11-spy * Enable RSA-PSS signatures in pkcs11-tool * Added short names to RSA-PSS methods * Reintroduce portable NORETURN indication for functions and use it to avoid compilers complaining --- doc/tools/pkcs11-tool.1.xml | 32 ++++++- src/pkcs11/pkcs11-display.c | 9 ++ src/pkcs11/pkcs11-display.h | 1 + src/pkcs11/pkcs11-spy.c | 18 ++++ src/pkcs11/pkcs11.h | 24 +++++ src/tools/pkcs11-tool.c | 183 +++++++++++++++++++++++++++++++++++- src/tools/util.c | 5 +- src/tools/util.h | 17 +++- 8 files changed, 280 insertions(+), 9 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 471b9b4d4d..037c955146 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -71,6 +71,14 @@ Hash some data. + + + mechanism + + Specify hash algorithm used with + RSA-PKCS-PSS signature. Default is SHA-1. + + id, @@ -116,7 +124,7 @@ - specification + specification Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1. @@ -212,6 +220,17 @@ of mechanisms supported by your token. + + + function + + Use the specified Message Generation + Function (MGF) function + for RSA-PSS signatures. Supported arguments are MGF1-SHA1 + to MGF1-SHA512 if supported by the driver. + The default is based on the hash selection. + + mod @@ -309,6 +328,17 @@ Derive a secret key using another key and some data. + + + bytes + + Specify how many bytes of salt should + be used in RSA-PSS signatures. Accepts two special values: + "-1" means salt length equals to digest length, + "-2" means use maximum permissible length. + Default is digest length (-1). + + id diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index a05a7f9376..753c05fa20 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -521,6 +521,14 @@ static enum_specs ck_mec_s[] = { { CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED " } }; +static enum_specs ck_mgf_s[] = { + { CKG_MGF1_SHA1 , "CKG_MGF1_SHA1 " }, + { CKG_MGF1_SHA224, "CKG_MGF1_SHA224" }, + { CKG_MGF1_SHA256, "CKG_MGF1_SHA256" }, + { CKG_MGF1_SHA384, "CKG_MGF1_SHA384" }, + { CKG_MGF1_SHA512, "CKG_MGF1_SHA512" }, +}; + static enum_specs ck_err_s[] = { { CKR_OK, "CKR_OK" }, { CKR_CANCEL, "CKR_CANCEL" }, @@ -630,6 +638,7 @@ enum_spec ck_types[] = { { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, { MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, + { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE"}, { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 0f7bc5fb38..9473ce9c08 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -56,6 +56,7 @@ enum ck_type{ KEY_T, CRT_T, MEC_T, + MGF_T, USR_T, STA_T, RV_T diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index d0201772ed..8011f0471c 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -969,6 +969,24 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA enter("C_SignInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_PSS_PARAMS *param = + (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", + param->sLen); + } + break; + } spy_dump_ulong_in("hKey", hKey); rv = po->C_SignInit(hSession, pMechanism, hKey); return retne(rv); diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 74b13c6894..d24597b26f 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -153,6 +153,8 @@ extern "C" { #define ck_mechanism_type_t CK_MECHANISM_TYPE +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE + #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen @@ -478,6 +480,8 @@ struct ck_date typedef unsigned long ck_mechanism_type_t; +typedef unsigned long int ck_rsa_pkcs_mgf_type_t; + #define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) #define CKM_RSA_PKCS (1UL) #define CKM_RSA_9796 (2UL) @@ -508,6 +512,8 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_SHA256_RSA_PKCS_PSS (0x43UL) #define CKM_SHA384_RSA_PKCS_PSS (0x44UL) #define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) #define CKM_RC2_KEY_GEN (0x100UL) #define CKM_RC2_ECB (0x101UL) #define CKM_RC2_CBC (0x102UL) @@ -553,6 +559,9 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_SHA256 (0x250UL) #define CKM_SHA256_HMAC (0x251UL) #define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) #define CKM_SHA384 (0x260UL) #define CKM_SHA384_HMAC (0x261UL) #define CKM_SHA384_HMAC_GENERAL (0x262UL) @@ -755,6 +764,17 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned char * pPublicData; } CK_ECDH1_DERIVE_PARAMS; +typedef struct CK_RSA_PKCS_PSS_PARAMS { + ck_mechanism_type_t hashAlg; + unsigned long mgf; + unsigned long sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +#define CKG_MGF1_SHA1 (0x00000001UL) +#define CKG_MGF1_SHA224 (0x00000005UL) +#define CKG_MGF1_SHA256 (0x00000002UL) +#define CKG_MGF1_SHA384 (0x00000003UL) +#define CKG_MGF1_SHA512 (0x00000004UL) typedef unsigned long ck_rv_t; @@ -1292,6 +1312,8 @@ typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; +typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; + typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; @@ -1362,6 +1384,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_mechanism_type_t +#undef ck_rsa_pkcs_mgf_type_t + #undef ck_mechanism #undef parameter #undef parameter_len diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ec681a2d85..dfd6913d41 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -147,6 +147,9 @@ enum { OPT_TEST_FORK, OPT_GENERATE_KEY, OPT_GENERATE_RANDOM, + OPT_HASH_ALGORITHM, + OPT_MGF, + OPT_SALT, }; static const struct option options[] = { @@ -163,6 +166,9 @@ static const struct option options[] = { { "derive", 0, NULL, OPT_DERIVE }, { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER }, { "mechanism", 1, NULL, 'm' }, + { "hash-algorithm", 1, NULL, OPT_HASH_ALGORITHM }, + { "mgf", 1, NULL, OPT_MGF }, + { "salt-len", 1, NULL, OPT_SALT }, { "login", 0, NULL, 'l' }, { "login-type", 1, NULL, OPT_LOGIN_TYPE }, @@ -229,6 +235,9 @@ static const char *option_help[] = { "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", "Specify mechanism (use -M for a list of supported mechanisms)", + "Specify hash algorithm used with RSA-PKCS-PSS signature", + "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)", + "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", "Log into the token first", "Specify login type ('so', 'user', 'context-specific'; default:'user')", @@ -320,6 +329,10 @@ static int opt_key_usage_derive = 0; static int opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */ static int opt_derive_pass_der = 0; static unsigned long opt_random_bytes = 0; +static CK_MECHANISM_TYPE opt_hash_alg = 0; +static unsigned long opt_mgf = 0; +static long salt_len = 0; +static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -410,6 +423,8 @@ static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t); static const char * p11_flag_names(struct flag_info *, CK_FLAGS); static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE); static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); +static const char * p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE); +static CK_MECHANISM_TYPE p11_name_to_mgf(const char *); static void p11_perror(const char *, CK_RV); static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); @@ -677,6 +692,16 @@ int main(int argc, char * argv[]) opt_mechanism_used = 1; opt_mechanism = p11_name_to_mechanism(optarg); break; + case OPT_HASH_ALGORITHM: + opt_hash_alg = p11_name_to_mechanism(optarg); + break; + case OPT_MGF: + opt_mgf = p11_name_to_mgf(optarg); + break; + case OPT_SALT: + salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); + salt_len_given = 1; + break; case 'o': opt_output = optarg; break; @@ -1609,15 +1634,45 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +/* return digest length in bytes */ +static unsigned long figure_pss_salt_length(const int hash) { + unsigned long sLen = 0; + switch (hash) { + case CKM_SHA_1: + sLen = 20; + break; + case CKM_SHA224: + sLen = 28; + break; + case CKM_SHA256: + sLen = 32; + break; + case CKM_SHA384: + sLen = 48; + break; + case CKM_SHA512: + sLen = 64; + break; + default: + util_fatal("Unknown hash algorithm '%s' for RSA-PSS signatures", + p11_mechanism_to_name(hash)); + break; + } + return sLen; +} + static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { unsigned char in_buffer[1025], sig_buffer[512]; CK_MECHANISM mech; + CK_RSA_PKCS_PSS_PARAMS pss_params; CK_RV rv; CK_ULONG sig_len; int fd, r; + unsigned long hashlen = 0, modlen = 0; + if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) util_fatal("Sign mechanism not supported"); @@ -1625,6 +1680,93 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; + pss_params.hashAlg = 0; + + if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS) + util_fatal("The hash-algorithm is applicable only to " + "RSA-PKCS-PSS mechanism"); + + /* set "default" MGF and hash algorithms. We can overwrite MGF later */ + switch (opt_mechanism) { + case CKM_RSA_PKCS_PSS: + pss_params.hashAlg = opt_hash_alg; + + switch (opt_hash_alg) { + case CKM_SHA256: + pss_params.mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + pss_params.mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + pss_params.mgf = CKG_MGF1_SHA512; + break; + default: + /* the PSS should use SHA-1 if not specified */ + pss_params.hashAlg = CKM_SHA_1; + /* fallthrough */ + case CKM_SHA_1: + pss_params.mgf = CKG_MGF1_SHA1; + } + break; + + case CKM_SHA1_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA_1; + pss_params.mgf = CKG_MGF1_SHA1; + break; + + case CKM_SHA256_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA256; + pss_params.mgf = CKG_MGF1_SHA256; + break; + + case CKM_SHA384_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA384; + pss_params.mgf = CKG_MGF1_SHA384; + break; + + case CKM_SHA512_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA512; + pss_params.mgf = CKG_MGF1_SHA512; + break; + } + + /* One of RSA-PSS mechanisms above: They need parameters */ + if (pss_params.hashAlg) { + if (opt_mgf != 0) + pss_params.mgf = opt_mgf; + + hashlen = figure_pss_salt_length(pss_params.hashAlg); + + if (salt_len_given == 1) { /* salt size explicitly given */ + if (salt_len < 0 && salt_len != -1 && salt_len != -2) + util_fatal("Salt length must be greater or equal \ +to zero, or equal to -1 (meaning: use digest size) or to -2 \ +(meaning: use maximum permissible size"); + + modlen = (get_private_key_length(session, key) + 7) / 8; + switch(salt_len) { + case -1: /* salt size equals to digest size */ + pss_params.sLen = hashlen; + break; + case -2: /* maximum permissible salt len */ + pss_params.sLen = modlen - hashlen -2; + break; + default: /* use given size but its value must be >= 0 */ + pss_params.sLen = salt_len; + break; + } /* end switch (salt_len_given) */ + } else { /* use default: salt len of digest size */ + pss_params.sLen = hashlen; + } + + mech.pParameter = &pss_params; + mech.ulParameterLen = sizeof(pss_params); + fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", + p11_mechanism_to_name(pss_params.hashAlg), + p11_mgf_to_name(pss_params.mgf), + pss_params.sLen); + } if (opt_input == NULL) fd = 0; @@ -5649,10 +5791,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_RSA_X9_31, "RSA-X9-31", NULL }, { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL }, { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL }, - { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", NULL }, - { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", NULL }, - { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", NULL }, - { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", NULL }, + { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1" }, + { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256" }, + { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384" }, + { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512" }, { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL }, { CKM_DSA, "DSA", NULL }, { CKM_DSA_SHA1, "DSA-SHA1", NULL }, @@ -5829,6 +5971,15 @@ static struct mech_info p11_mechanisms[] = { { 0, NULL, NULL } }; +static struct mech_info p11_mgf[] = { + { CKG_MGF1_SHA1, "MGF1-SHA1", NULL }, + { CKG_MGF1_SHA224, "MGF1-SHA224", NULL }, + { CKG_MGF1_SHA256, "MGF1-SHA256", NULL }, + { CKG_MGF1_SHA384, "MGF1-SHA384", NULL }, + { CKG_MGF1_SHA512, "MGF1-SHA512", NULL }, + { 0, NULL, NULL } +}; + static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech) { static char temp[64]; @@ -5855,6 +6006,30 @@ static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name) return 0; /* gcc food */ } +static CK_RSA_PKCS_MGF_TYPE p11_name_to_mgf(const char *name) +{ + struct mech_info *mi; + + for (mi = p11_mgf; mi->name; mi++) { + if (!strcasecmp(mi->name, name)) + return mi->mech; + } + util_fatal("Unknown PKCS11 MGF \"%s\"", name); +} + +static const char *p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf) +{ + static char temp[64]; + struct mech_info *mi; + + for (mi = p11_mgf; mi->name; mi++) { + if (mi->mech == mgf) + return mi->name; + } + snprintf(temp, sizeof(temp), "mgf-0x%lX", (unsigned long) mgf); + return temp; +} + static const char * CKR2Str(CK_ULONG res) { switch (res) { diff --git a/src/tools/util.c b/src/tools/util.c index f5a0370090..9c9f37c8bf 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -232,7 +232,8 @@ void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr) } } -void util_print_usage_and_die(const char *app_name, const struct option options[], +NORETURN void +util_print_usage_and_die(const char *app_name, const struct option options[], const char *option_help[], const char *args) { int i; @@ -343,7 +344,7 @@ const char * util_acl_to_str(const sc_acl_entry_t *e) return line; } -void +NORETURN void util_fatal(const char *fmt, ...) { va_list ap; diff --git a/src/tools/util.h b/src/tools/util.h index b907808773..d3a155708f 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -23,15 +23,28 @@ extern "C" { #endif +#if _MSC_VER >= 1310 +/* MS Visual Studio 2003/.NET Framework 1.1 or newer */ +# define NORETURN _declspec( noreturn) +#elif __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ >= 5)) || (defined __clang__) +# define NORETURN __attribute__ ((noreturn)) +#elif __cplusplus >= 201103L +# define NORETURN [[noreturn]] +#elif __STDC_VERSION__ >= 201112L +# define NORETURN _Noreturn +#else +# define NORETURN +#endif + void util_print_binary(FILE *f, const u8 *buf, int count); void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep); void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr); -void util_print_usage_and_die(const char *app_name, const struct option options[], +NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[], const char *option_help[], const char *args); const char * util_acl_to_str(const struct sc_acl_entry *e); void util_warn(const char *fmt, ...); void util_error(const char *fmt, ...); -void util_fatal(const char *fmt, ...); +NORETURN void util_fatal(const char *fmt, ...); /* All singing all dancing card connect routine */ int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose); int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose); From dfd18389346296f8e4617832e0d5f4171835620d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 24 Sep 2017 22:14:19 +0200 Subject: [PATCH 0066/4321] fixed building without SM fixes https://github.com/OpenSC/OpenSC/issues/1155 --- src/libopensc/card-sc-hsm.c | 6 ++++++ src/libopensc/sm.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index ff9810c4c6..84f767b2ea 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -324,7 +324,9 @@ static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN"); } else { +#ifdef ENABLE_SM unsigned sm_mode = card->sm_ctx.sm_mode; +#endif /* verify PIN */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x85); @@ -332,15 +334,19 @@ static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, r = sc_transmit_apdu(card, &apdu); LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); +#ifdef ENABLE_SM /* temporary disable SM, change reference data does not reach the applet */ card->sm_ctx.sm_mode = SM_MODE_NONE; +#endif /* change PIN */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x85); apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); +#ifdef ENABLE_SM /* restore SM if possible */ card->sm_ctx.sm_mode = sm_mode; +#endif LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN"); diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c index a5f53de16d..94f7ce7c3c 100644 --- a/src/libopensc/sm.c +++ b/src/libopensc/sm.c @@ -31,6 +31,7 @@ #include "asn1.h" #include "sm.h" +#ifdef ENABLE_SM static const struct sc_asn1_entry c_asn1_sm_response[4] = { { "encryptedData", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 7, SC_ASN1_OPTIONAL, NULL, NULL }, { "statusWord", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0x19, 0, NULL, NULL }, @@ -38,7 +39,6 @@ static const struct sc_asn1_entry c_asn1_sm_response[4] = { { NULL, 0, 0, 0, NULL, NULL } }; -#ifdef ENABLE_SM int sc_sm_parse_answer(struct sc_card *card, unsigned char *resp_data, size_t resp_len, struct sm_card_response *out) From 4923947b0aa0ff744377486cebfb04829f7485f7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 16 Oct 2017 09:25:34 +0200 Subject: [PATCH 0067/4321] md: added CNS ATR (#1166) fixes https://github.com/OpenSC/OpenSC/issues/1153 --- win32/customactions.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index f417d74bdf..3a3291c73a 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -117,12 +117,14 @@ MD_REGISTRATION minidriver_registration[] = { /* from card-cardos.c */ {TEXT("CardOS 4.0"), {0x3b,0xe2,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0xc8,0x02,0x9c}, 12, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("Italian eID card, postecert"), {0x3b,0xe9,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x00,0xc8,0x02,0x31,0x80,0x00,0x47}, + {TEXT("Italian CNS (a)"), {0x3b,0xe9,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x00,0xc8,0x02,0x31,0x80,0x00,0x47}, 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("Italian eID card, infocamere"), {0x3b,0xfb,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x20,0x47,0x03,0x31,0x80,0x00,0x90,0x00,0xf3}, + {TEXT("Italian CNS (b)"), {0x3b,0xfb,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x20,0x47,0x03,0x31,0x80,0x00,0x90,0x00,0xf3}, 22, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("Italian InfocamereCard"), {0x3b,0xfc,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0xc8,0x03,0x49,0x6e,0x66,0x6f,0x63,0x61,0x6d,0x65,0x72,0x65,0x28}, + {TEXT("Italian CNS (c)"), {0x3b,0xfc,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0xc8,0x03,0x49,0x6e,0x66,0x6f,0x63,0x61,0x6d,0x65,0x72,0x65,0x28}, 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("Italian CNS (d)"), {0x3b,0xff,0x18,0x00,0xff,0x81,0x31,0xfe,0x55,0x00,0x6b,0x02,0x09,0x03,0x03,0x01,0x01,0x01,0x43,0x4e,0x53,0x10,0x31,0x80,0x9d}, + 25, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("CardOS 4.0 a"), {0x3b,0xf4,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x4d,0x34,0x63,0x76,0xb4}, 15, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Cardos M4"), {0x3b,0xf2,0x18,0x00,0x02,0xc1,0x0a,0x31,0xfe,0x58,0xc8,0x08,0x74}, From a8126ad696d50d83cabf5771f73022ee9f783503 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 22 Sep 2017 13:52:19 -0500 Subject: [PATCH 0068/4321] Make OpenSC PKCS#11 Vendor Defined attributes, mechanisms etc unique This will help when p11-kit is usead and wil allow for additional CK*_* things to be defined that have a much better chance of being unique. OR in "OSC" to any CK*_VENDOR_DEFINED thing. with #define SC_VENDOR_DEFINED 0x4F534300 /* OSC */ This follows Netscapes convention of doing the same but using: #define NSSCK_VENDOR_NSS 0x4E534350 /* NSCP */ The current 2 defines CKA_* are for internal attributes. On branch OSC_VENDOR_DEFINED Changes to be committed: modified: pkcs11-opensc.h --- src/pkcs11/pkcs11-opensc.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index 33beb6a3d6..6f0954dd67 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -2,13 +2,22 @@ #define PKCS11_OPENSC_H /* OpenSC specific extensions */ +/* + * define OpenSC specific Vendor Defined extensions + * to make unique OpenSC flags, attribures, mechanisms, etc. + * + * Netscape used NSSCK_VENDOR_NSS 0x4E534350 "NSCP" + */ + +#define SC_VENDOR_DEFINED 0x4F534300 /* OSC */ + /* * In PKCS#11 there is no CKA_ attribute dedicated to the NON-REPUDIATION flag. * We need this flag in PKCS#15/libopensc to make dinstinction between * 'signature' and 'qualified signature' key slots. */ -#define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | 1UL) +#define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 1UL) -#define CKA_SPKI (CKA_VENDOR_DEFINED | 2UL) +#define CKA_SPKI (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 2UL) #endif From bd9cdd243d1c35da2e83be6792565c27c685f17d Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Fri, 16 Jun 2017 14:51:41 +0200 Subject: [PATCH 0069/4321] Add multiple PINs support to minidriver Many cards need multiple PINs to work correctly since different on-card keys are secured by different PINs (this is true for for example OpenPGP card). Smart Card Minidriver API has supported such cards since version 6.02 (Vista+). Use the same method as PKCS#11 driver does to discover user and sign PINs, for consistency. However, if there is a default container on card we'll make sure that its PIN is an user PIN and if there is no default container we'll mark the one with the user PIN as default. All other PINs securing containers on card are added as next PINs, up to MD_MAX_PINS. Use this opportunity to also fix two cases where a pointer-to-DWORD variable was passed as pointer-to-size_t parameter to md_dialog_perform_pin_operation() - they are of different size on Win64. Signed-off-by: Maciej S. Szmigiero --- src/minidriver/minidriver.c | 643 +++++++++++++++++++++++++--------- src/pkcs11/framework-pkcs15.c | 1 + 2 files changed, 480 insertions(+), 164 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 0e6ab7869f..ecec13e754 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -71,6 +71,13 @@ HINSTANCE g_inst; #define MD_MAX_KEY_CONTAINERS 12 #define MD_CARDID_SIZE 16 +#define MD_ROLE_USER_SIGN (ROLE_ADMIN + 1) +/* + * must be higher than MD_ROLE_USER_SIGN and + * less than or equal MAX_PINS + */ +#define MD_MAX_PINS MAX_PINS + #define MD_UTC_TIME_LENGTH_MAX 16 #define MD_CARDCF_LENGTH (sizeof(CARD_CACHE_FILE_FORMAT)) @@ -172,7 +179,7 @@ struct md_guid_conversion md_static_conversions[MD_MAX_CONVERSIONS] = {0}; typedef struct _VENDOR_SPECIFIC { - struct sc_pkcs15_object *obj_user_pin, *obj_sopin; + struct sc_pkcs15_object *pin_objs[MD_MAX_PINS]; struct sc_context *ctx; struct sc_reader *reader; @@ -335,6 +342,9 @@ static void loghex(PCARD_DATA pCardData, int level, PBYTE data, size_t len) * caller has changed the handles. * if so, then free up all previous card info * and reestablish + * + * FIXME: if this fails the context can be left + * in inconsistent state. */ static int check_reader_status(PCARD_DATA pCardData) @@ -385,7 +395,7 @@ static DWORD md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object **ret_obj) { VENDOR_SPECIFIC *vs; - int rv = SC_SUCCESS; + int rv; if (!pCardData) return SCARD_E_INVALID_PARAMETER; @@ -394,43 +404,65 @@ md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object ** if (!ret_obj) return SCARD_E_INVALID_PARAMETER; - *ret_obj = NULL; - - if (role == ROLE_USER) { - if (!vs->obj_user_pin) { - /* Get 'global' User PIN; if no, get the 'local' one */ - rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, - SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_user_pin); - if (rv) + /* please keep me in sync with _get_auth_object_by_name() in pkcs11/framework-pkcs15.c */ + if (role == ROLE_USER) { + /* Get 'global' User PIN; if no, get the 'local' one */ + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); + if (rv) + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); + } + else if (role == MD_ROLE_USER_SIGN) { + int idx = 0; + + /* Get the 'global' user PIN */ + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); + if (!rv) { + /* Global (user) PIN exists, get the local one -- sign PIN */ + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); + } + else { + /* No global PIN, try to get first local one -- user PIN */ + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj); + if (!rv) { + /* User PIN is local, try to get the second local -- sign PIN */ + idx++; rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, - SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_user_pin); + SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj); + } } - - *ret_obj = vs->obj_user_pin; } - else if (role == ROLE_ADMIN) { + else if (role == ROLE_ADMIN) { /* Get SO PIN; if no, get the 'global' PUK; if no get the 'local' one */ - if (!vs->obj_sopin) { - rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_SOPIN, - SC_PKCS15_PIN_TYPE_FLAGS_SOPIN, NULL, &vs->obj_sopin); - if (rv) - rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL, - SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_sopin); - if (rv) - rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL, - SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &vs->obj_sopin); - } - - *ret_obj = vs->obj_sopin; + rv = sc_pkcs15_find_so_pin(vs->p15card, ret_obj); + if (rv) + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); + if (rv) + rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL, + SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj); } else { - logprintf(pCardData, 2, "cannot get PIN object: unsupported role\n"); + logprintf(pCardData, 2, + "cannot get PIN object: unsupported role %u\n", + (unsigned int)role); return SCARD_E_UNSUPPORTED_FEATURE; } - return (rv == SC_SUCCESS) ? SCARD_S_SUCCESS : SCARD_E_UNSUPPORTED_FEATURE; -} + if (rv) + return SCARD_E_UNSUPPORTED_FEATURE; + if (*ret_obj) + logprintf(pCardData, 7, "Returning PIN '%.*s' for role %u\n", + (int) sizeof (*ret_obj)->label, (*ret_obj)->label, + (unsigned int)role); + + return SCARD_S_SUCCESS; +} static BOOL md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL ret_default) @@ -1376,6 +1408,14 @@ md_fs_add_msroots(PCARD_DATA pCardData, struct md_file **head) static DWORD md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) { + typedef enum { SCF_NONE, + SCF_NONDEFAULT_SIGN_PIN, + SCF_NONDEFAULT_OTHER_PIN, + SCF_NONDEFAULT_USER_PIN, + SCF_DEFAULT_SIGN_PIN, + SCF_DEFAULT_OTHER_PIN, + SCF_DEFAULT_USER_PIN + } pin_mode_t; VENDOR_SPECIFIC *vs; PCONTAINER_MAP_RECORD p; unsigned char *cmap_buf = NULL; @@ -1384,12 +1424,33 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) int ii, rv, conts_num, found_default = 0; /* struct sc_pkcs15_data *data_object; */ struct sc_pkcs15_object *prkey_objs[MD_MAX_KEY_CONTAINERS]; + pin_mode_t pin_mode = SCF_NONE; + int pin_cont_idx = -1; if (!pCardData || !file) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 2, "set 'cmapfile'\n"); vs = pCardData->pvVendorSpecific; + + dwret = md_get_pin_by_role(pCardData, ROLE_USER, &vs->pin_objs[ROLE_USER]); + if (dwret != SCARD_S_SUCCESS) { + logprintf(pCardData, 2, "Cannot get User PIN object"); + return dwret; + } + + dwret = md_get_pin_by_role(pCardData, MD_ROLE_USER_SIGN, &vs->pin_objs[MD_ROLE_USER_SIGN]); + if (dwret != SCARD_S_SUCCESS) { + logprintf(pCardData, 2, "Cannot get Sign PIN object -- ignored"); + vs->pin_objs[MD_ROLE_USER_SIGN] = NULL; + } + + dwret = md_get_pin_by_role(pCardData, ROLE_ADMIN, &vs->pin_objs[ROLE_ADMIN]); + if (dwret != SCARD_S_SUCCESS) { + logprintf(pCardData, 2, "Cannot get Admin PIN object -- ignored"); + vs->pin_objs[ROLE_ADMIN] = NULL; + } + cmap_len = MD_MAX_KEY_CONTAINERS*sizeof(CONTAINER_MAP_RECORD); cmap_buf = pCardData->pfnCspAlloc(cmap_len); if(!cmap_buf) @@ -1431,7 +1492,116 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) dwret = md_cont_flags_from_key(pCardData, key_obj, &cont->flags); if (dwret != SCARD_S_SUCCESS) return dwret; - if (cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER) + + logprintf(pCardData, 7, "Container[%i] is '%.*s' guid=%.*s\n", ii, + (int) sizeof key_obj->label, key_obj->label, + (int) sizeof cont->guid, cont->guid); + + if (cont->flags & CONTAINER_MAP_VALID_CONTAINER && + key_obj->auth_id.len > 0) { + struct sc_pkcs15_object *keypin_obj; + struct sc_pkcs15_auth_info *userpin_info = + (struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_USER]->data; + struct sc_pkcs15_auth_info *signpin_info = + vs->pin_objs[MD_ROLE_USER_SIGN] ? + (struct sc_pkcs15_auth_info *)vs->pin_objs[MD_ROLE_USER_SIGN]->data : + NULL; + struct sc_pkcs15_auth_info *adminpin_info = + vs->pin_objs[ROLE_ADMIN] ? + (struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_ADMIN]->data : + NULL; + + if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj)) + logprintf(pCardData, 2, + "Container[%i] has an unknown auth id, might not work properly\n", + ii); + else { + size_t pinidx; + size_t pinidxempty = MD_MAX_PINS; + for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) { + struct sc_pkcs15_auth_info *pin_info; + + if (!vs->pin_objs[pinidx]) { + if (pinidxempty >= MD_MAX_PINS) + pinidxempty = pinidx; + + continue; + } + + pin_info = + (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data; + + if (sc_pkcs15_compare_id(&key_obj->auth_id, + &pin_info->auth_id)) + break; + } + + if (pinidx >= MD_MAX_PINS) { + if (pinidxempty >= MD_MAX_PINS) + logprintf(pCardData, 2, + "no free slot for container[%i] auth id, might not work properly\n", + ii); + else + vs->pin_objs[pinidxempty] = keypin_obj; + } + + if (sc_pkcs15_compare_id(&key_obj->auth_id, &userpin_info->auth_id)) { + pin_mode_t pin_mode_n = + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + SCF_DEFAULT_USER_PIN : SCF_NONDEFAULT_USER_PIN; + + logprintf(pCardData, 7, + "Container[%i]%s is secured by User PIN\n", + ii, + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + " (default)" : ""); + + if (pin_mode < pin_mode_n) { + pin_mode = pin_mode_n; + pin_cont_idx = ii; + } + } else if (signpin_info != NULL && + sc_pkcs15_compare_id(&key_obj->auth_id, &signpin_info->auth_id)) { + pin_mode_t pin_mode_n = + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + SCF_DEFAULT_SIGN_PIN : SCF_NONDEFAULT_SIGN_PIN; + + logprintf(pCardData, 7, + "Container[%i]%s is secured by Sign PIN\n", + ii, + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + " (default)" : ""); + + if (pin_mode < pin_mode_n) { + pin_mode = pin_mode_n; + pin_cont_idx = ii; + } + } else if (adminpin_info != NULL && + sc_pkcs15_compare_id(&key_obj->auth_id, &adminpin_info->auth_id)) { + logprintf(pCardData, 2, + "Container[%i] is secured by Admin PIN, might not work properly\n", + ii); + } else { + pin_mode_t pin_mode_n = + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + SCF_DEFAULT_OTHER_PIN : SCF_NONDEFAULT_OTHER_PIN; + + logprintf(pCardData, 7, + "Container[%i]%s is secured by other PIN\n", + ii, + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? + " (default)" : ""); + + if (pin_mode < pin_mode_n) { + pin_mode = pin_mode_n; + pin_cont_idx = ii; + } + } + } + } + + if (cont->flags & CONTAINER_MAP_VALID_CONTAINER && + cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER) found_default = 1; /* AT_KEYEXCHANGE is more general key usage, @@ -1455,7 +1625,6 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) cont->size_key_exchange = prkey_info->field_length; } - logprintf(pCardData, 7, "Container[%i]'s guid=%.*s\n", ii, (int) sizeof cont->guid, cont->guid); logprintf(pCardData, 7, "Container[%i]'s key-exchange:%"SC_FORMAT_LEN_SIZE_T"u, sign:%"SC_FORMAT_LEN_SIZE_T"u\n", ii, cont->size_key_exchange, cont->size_sign); @@ -1513,6 +1682,108 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) } } #endif + + /* if no default container was found promote the best one (PIN-wise) to default */ + if (!found_default && (pin_mode == SCF_NONDEFAULT_SIGN_PIN || + pin_mode == SCF_NONDEFAULT_OTHER_PIN || + pin_mode == SCF_NONDEFAULT_USER_PIN)) { + struct md_pkcs15_container *cont = + &vs->p15_containers[pin_cont_idx]; + cont->flags |= CONTAINER_MAP_DEFAULT_CONTAINER; + + found_default = 1; + + logprintf(pCardData, 7, + "Container[%i] promoted to default\n", + pin_cont_idx); + + if (pin_mode == SCF_NONDEFAULT_SIGN_PIN) + pin_mode = SCF_DEFAULT_SIGN_PIN; + else if (pin_mode == SCF_NONDEFAULT_OTHER_PIN) + pin_mode = SCF_DEFAULT_OTHER_PIN; + else + pin_mode = SCF_DEFAULT_USER_PIN; + } + + /* if all containers use non-user PINs we need to make the best container PIN the user (primary) one */ + if (pin_mode == SCF_NONDEFAULT_SIGN_PIN || + pin_mode == SCF_DEFAULT_SIGN_PIN || + pin_mode == SCF_NONDEFAULT_OTHER_PIN || + pin_mode == SCF_DEFAULT_OTHER_PIN) { + struct sc_pkcs15_object *user_pin_old = + vs->pin_objs[ROLE_USER]; + struct sc_pkcs15_object *user_pin_new = + NULL; + + if (pin_mode == SCF_NONDEFAULT_SIGN_PIN || + pin_mode == SCF_DEFAULT_SIGN_PIN) { + user_pin_new = vs->pin_objs[MD_ROLE_USER_SIGN]; + vs->pin_objs[MD_ROLE_USER_SIGN] = NULL; + + logprintf(pCardData, 7, + "Sign PIN%s promoted to user one\n", + pin_mode == SCF_DEFAULT_SIGN_PIN ? + " (from default container)" : ""); + } else { + struct sc_pkcs15_object *key_obj = + vs->p15_containers[pin_cont_idx].prkey_obj; + struct sc_pkcs15_object *keypin_obj; + + if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj)) + logprintf(pCardData, 2, + "Cannot find container[%i] auth id again, might not work properly\n", + pin_cont_idx); + else { + size_t pinidx; + + logprintf(pCardData, 7, + "Container[%i]%s PIN will be made the user one\n", + pin_cont_idx, + pin_mode == SCF_DEFAULT_OTHER_PIN ? + " (default)" : ""); + + for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) { + struct sc_pkcs15_auth_info *pin_info; + + if (!vs->pin_objs[pinidx]) + continue; + + pin_info = + (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data; + + if (sc_pkcs15_compare_id(&key_obj->auth_id, + &pin_info->auth_id)) { + vs->pin_objs[pinidx] = NULL; + break; + } + } + + user_pin_new = keypin_obj; + } + } + + if (user_pin_new) { + size_t pinidx; + + vs->pin_objs[ROLE_USER] = user_pin_new; + + for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) { + if (vs->pin_objs[pinidx]) + continue; + + vs->pin_objs[pinidx] = user_pin_old; + break; + } + + if (pinidx >= MD_MAX_PINS) { + logprintf(pCardData, 2, + "no free slot for previous User PIN, replacing last one\n"); + + vs->pin_objs[MD_MAX_PINS - 1] = user_pin_old; + } + } + } + /* Initialize 'CMAPFILE' content from the P15 containers */ p = (PCONTAINER_MAP_RECORD)cmap_buf; for (ii=0; iipvVendorSpecific); + + if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId]) + return SCARD_E_INVALID_PARAMETER; + card = vs->p15card->card; memset(&pub_args, 0, sizeof(pub_args)); @@ -1904,12 +2179,7 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke keygen_args.prkey_args.access_flags = MD_KEY_ACCESS; - dw = md_get_pin_by_role(pCardData, ROLE_USER, &pin_obj); - if (dw != SCARD_S_SUCCESS) { - logprintf(pCardData, 2, "MdGenerateKey(): cannot get User PIN object"); - return dw; - } - + pin_obj = vs->pin_objs[PinId]; auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data; keygen_args.prkey_args.auth_id = pub_args.auth_id = auth_info->auth_id; @@ -1970,9 +2240,8 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke return dwret; } - static DWORD -md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, DWORD blob_size) +md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, DWORD blob_size, PIN_ID PinId) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L VENDOR_SPECIFIC *vs; @@ -1986,13 +2255,17 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, BYTE *ptr = blob; EVP_PKEY *pkey=NULL; int rv; - DWORD dw, dwret = SCARD_F_INTERNAL_ERROR; + DWORD dwret = SCARD_F_INTERNAL_ERROR; CHAR szGuid[MAX_CONTAINER_NAME_LEN +1] = "Default key label"; if (!pCardData) return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + + if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId]) + return SCARD_E_INVALID_PARAMETER; + card = vs->p15card->card; pkey = b2i_PrivateKey((const unsigned char **)&ptr, blob_size); @@ -2032,12 +2305,7 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, prkey_args.access_flags = MD_KEY_ACCESS; - dw = md_get_pin_by_role(pCardData, ROLE_USER, &pin_obj); - if (dw != SCARD_S_SUCCESS) { - logprintf(pCardData, 2, "MdStoreKey(): cannot get User PIN object"); - return dw; - } - + pin_obj = vs->pin_objs[PinId]; prkey_args.auth_id = ((struct sc_pkcs15_auth_info *) pin_obj->data)->auth_id; rv = sc_lock(card); @@ -2628,26 +2896,40 @@ DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData, return SCARD_S_SUCCESS; } - -DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, - __in BYTE bContainerIndex, - __in DWORD dwFlags, - __in DWORD dwKeySpec, - __in DWORD dwKeySize, - __in PBYTE pbKeyData) +/** The CardCreateContainerEx function creates a new key container that the +container index identifies and the bContainerIndex parameter specifies. The function +associates the key container with the PIN that the PinId parameter specified. +This function is useful if the card-edge does not allow for changing the key attributes +after the key container is created. This function replaces the need to call +CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer +is called. +The caller of this function can provide the key material that the card imports. +This is useful in those situations in which the card either does not support internal +key generation or the caller requests that the key be archived in the card.*/ +DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, + __in BYTE bContainerIndex, + __in DWORD dwFlags, + __in DWORD dwKeySpec, + __in DWORD dwKeySize, + __in PBYTE pbKeyData, + __in PIN_ID PinId) { DWORD dwret; if (!pCardData) return SCARD_E_INVALID_PARAMETER; + if (PinId == ROLE_ADMIN) + return SCARD_W_SECURITY_VIOLATION; + logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, - "CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p)\n", + "CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p,pin:%u)\n", (unsigned int)bContainerIndex, (unsigned long)dwFlags, - (unsigned long)dwKeySpec, (unsigned long)dwKeySize, pbKeyData); + (unsigned long)dwKeySpec, (unsigned long)dwKeySize, pbKeyData, + (unsigned int)PinId); if (pbKeyData) { logprintf(pCardData, 7, "Key data\n"); @@ -2676,7 +2958,7 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, } if (dwFlags & CARD_CREATE_CONTAINER_KEY_GEN) { - dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize); + dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize, PinId); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "key generation failed\n"); return dwret; @@ -2684,7 +2966,7 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, logprintf(pCardData, 1, "key generated\n"); } else if ((dwFlags & CARD_CREATE_CONTAINER_KEY_IMPORT) && (pbKeyData != NULL)) { - dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize); + dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize, PinId); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "key store failed\n"); return dwret; @@ -2700,6 +2982,17 @@ DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, return SCARD_S_SUCCESS; } +DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, + __in BYTE bContainerIndex, + __in DWORD dwFlags, + __in DWORD dwKeySpec, + __in DWORD dwKeySize, + __in PBYTE pbKeyData) +{ + return CardCreateContainerEx(pCardData, bContainerIndex, dwFlags, + dwKeySpec, dwKeySize, pbKeyData, + ROLE_USER); +} typedef struct { PUBLICKEYSTRUC publickeystruc; @@ -4777,6 +5070,13 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if ((vs->p15card) == NULL) return SCARD_F_INTERNAL_ERROR; + if (PinId >= MD_MAX_PINS) + return SCARD_E_INVALID_PARAMETER; + + pin_obj = vs->pin_objs[PinId]; + if (!pin_obj) + return SCARD_E_INVALID_PARAMETER; + #if 0 /* TODO do we need to return SCARD_E_UNSUPPORTED_FEATURE if the card * doesn't support it or if the minidriver doesn't support it in general? @@ -4791,6 +5091,10 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (dwFlags & ~(CARD_AUTHENTICATE_GENERATE_SESSION_PIN | CARD_AUTHENTICATE_SESSION_PIN | CARD_PIN_SILENT_CONTEXT)) return SCARD_E_INVALID_PARAMETER; + if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN && + (ppbSessionPin == NULL || pcbSessionPin == NULL)) + return SCARD_E_INVALID_PARAMETER; + /* using a pin pad */ if (NULL == pbPinData) { if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD @@ -4802,20 +5106,9 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, } } - if (PinId != ROLE_USER) - return SCARD_E_INVALID_PARAMETER; - if(pcAttemptsRemaining) (*pcAttemptsRemaining) = (DWORD) -1; - r = md_get_pin_by_role(pCardData, PinId, &pin_obj); - if (r != SCARD_S_SUCCESS) { - logprintf(pCardData, 2, "Cannot get User PIN object"); - return r; - } - - if (!pin_obj) - return SCARD_F_INTERNAL_ERROR; auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; /* save the pin type */ auth_method = auth_info->auth_method; @@ -4834,34 +5127,49 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, cbPinData = 0; } else { /* seems we have a real session pin, set the pin type accordingly */ - logprintf(pCardData, 2, "use real session pin with %d bytes", cbPinData); + logprintf(pCardData, 2, + "use real session pin with %lu bytes", + (unsigned long)cbPinData); auth_info->auth_method = SC_AC_SESSION; } } /* set the session pin according to the minidriver specification */ if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN) { + size_t session_pin_len = SC_MAX_PIN_SIZE; + logprintf(pCardData, 2, "generating session pin"); - if (ppbSessionPin) *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE); - if (ppbSessionPin) *pcbSessionPin = SC_MAX_PIN_SIZE; - r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_GET_SESSION_PIN, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, - ppbSessionPin && *ppbSessionPin ? *ppbSessionPin : NULL, pcbSessionPin, DisplayPinpadUI); + *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE); + r = md_dialog_perform_pin_operation(pCardData, + SC_PIN_CMD_GET_SESSION_PIN, + vs->p15card, pin_obj, + (const u8 *) pbPinData, + cbPinData, + *ppbSessionPin, + *ppbSessionPin != NULL ? + &session_pin_len : NULL, + DisplayPinpadUI); if (r) { - if (ppbSessionPin) { + if (*ppbSessionPin != NULL) { pCardData->pfnCspFree(*ppbSessionPin); *ppbSessionPin = NULL; } - if (pcbSessionPin) *pcbSessionPin = 0; + *pcbSessionPin = 0; logprintf(pCardData, 2, "generating session pin failed"); } else { - if (pcbSessionPin && *pcbSessionPin) { - logprintf(pCardData, 2, "generated session pin with %d bytes", *pcbSessionPin); + if (*ppbSessionPin != NULL && session_pin_len > 0) { + logprintf(pCardData, 2, + "generated session pin with %"SC_FORMAT_LEN_SIZE_T"u bytes", + session_pin_len); + + *pcbSessionPin = session_pin_len; } else { logprintf(pCardData, 2, "session pin not supported"); - if (ppbSessionPin) { + if (*ppbSessionPin != NULL) { pCardData->pfnCspFree(*ppbSessionPin); *ppbSessionPin = NULL; } + *pcbSessionPin = 0; } } } else { @@ -4891,16 +5199,16 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, logprintf(pCardData, 2, "Pin code correct.\n"); /* set the session pin according to the minidriver specification */ - if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN - && pcbSessionPin && *pcbSessionPin == 0 + if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN + && *pcbSessionPin == 0 && (vs->reader->capabilities & SC_READER_CAP_PIN_PAD || vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) { /* If we could not generate a real session PIN, set it to a special * value for pinpad authentication to force a new pinpad authentication */ - *pcbSessionPin = sizeof(MAGIC_SESSION_PIN); - if (ppbSessionPin) { - *ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN)); - if (ppbSessionPin) memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN)); + *ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN)); + if (*ppbSessionPin != NULL) { + memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN)); + *pcbSessionPin = sizeof(MAGIC_SESSION_PIN); } } @@ -4920,11 +5228,11 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, __out_opt PDWORD pcAttemptsRemaining) { VENDOR_SPECIFIC *vs = NULL; - DWORD dw_rv; struct sc_pkcs15_object *pin_obj = NULL; int rv; struct sc_pkcs15_auth_info *auth_info; BOOL DisplayPinpadUI = FALSE; + size_t target_len = cbTargetData; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), @@ -4933,6 +5241,9 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, if (!pCardData) return SCARD_E_INVALID_PARAMETER; + + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!(dwFlags & PIN_CHANGE_FLAG_UNBLOCK) && !(dwFlags & PIN_CHANGE_FLAG_CHANGEPIN)){ logprintf(pCardData, 1, "Unknown flag\n"); return SCARD_E_INVALID_PARAMETER; @@ -4941,12 +5252,11 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, return SCARD_E_INVALID_PARAMETER; if (dwFlags & PIN_CHANGE_FLAG_UNBLOCK && dwAuthenticatingPinId == dwTargetPinId) return SCARD_E_INVALID_PARAMETER; - if (dwAuthenticatingPinId != ROLE_USER && dwAuthenticatingPinId != ROLE_ADMIN) + if (dwAuthenticatingPinId >= MD_MAX_PINS || dwTargetPinId >= MD_MAX_PINS) return SCARD_E_INVALID_PARAMETER; - if (dwTargetPinId != ROLE_USER && dwTargetPinId != ROLE_ADMIN) { - logprintf(pCardData, 1, "Only ROLE_USER or ROLE_ADMIN is supported\n"); + if (!vs->pin_objs[dwAuthenticatingPinId] || !vs->pin_objs[dwTargetPinId]) return SCARD_E_INVALID_PARAMETER; - } + /* according to the spec: cRetryCount MUST be zero */ if (cRetryCount) return SCARD_E_INVALID_PARAMETER; @@ -4961,8 +5271,6 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, check_reader_status(pCardData); - vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD || vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) { if (pbAuthenticatingPinData == NULL || cbAuthenticatingPinData == 0) { @@ -4983,20 +5291,22 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, } } - dw_rv = md_get_pin_by_role(pCardData, dwTargetPinId, &pin_obj); - if (dw_rv != SCARD_S_SUCCESS) { - logprintf(pCardData, 2, "Cannot get User PIN object %s", (dwTargetPinId==ROLE_ADMIN?"admin":"user")); - return dw_rv; - } - if (!pin_obj) - return SCARD_F_INTERNAL_ERROR; + pin_obj = vs->pin_objs[dwTargetPinId]; if(pcAttemptsRemaining) (*pcAttemptsRemaining) = (DWORD) -1; - rv = md_dialog_perform_pin_operation(pCardData, (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? SC_PIN_CMD_UNBLOCK:SC_PIN_CMD_CHANGE), - vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, &cbTargetData, DisplayPinpadUI); - + /* FIXME: this does not enforce dwAuthenticatingPinId */ + rv = md_dialog_perform_pin_operation(pCardData, + (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? + SC_PIN_CMD_UNBLOCK : + SC_PIN_CMD_CHANGE), + vs->p15card, pin_obj, + (const u8 *) pbAuthenticatingPinData, + cbAuthenticatingPinData, + pbTargetData, &target_len, + DisplayPinpadUI); + if (rv) { logprintf(pCardData, 2, "Failed to %s %s PIN: '%s' (%i)\n", (dwFlags & PIN_CHANGE_FLAG_CHANGEPIN?"change":"unblock"), @@ -5091,7 +5401,34 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData, *pdwDataLen = sizeof(*p); if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER; - *p = ROLE_USER; + + if (cont->prkey_obj->auth_id.len == 0) + *p = ROLE_EVERYONE; + else { + size_t pinidx; + for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) { + struct sc_pkcs15_auth_info *pin_info; + + if (!vs->pin_objs[pinidx]) + continue; + + pin_info = + (struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data; + + if (sc_pkcs15_compare_id(&cont->prkey_obj->auth_id, + &pin_info->auth_id)) + break; + } + + if (pinidx >= MD_MAX_PINS) { + logprintf(pCardData, 2, + "Could not find container %i PIN, returning no PIN needed, might not work properly\n", + bContainerIndex); + *p = ROLE_EVERYONE; + } else + *p = (PIN_ID)pinidx; + } + logprintf(pCardData, 2, "Return Pin id %u\n", (unsigned int)*p); return SCARD_S_SUCCESS; @@ -5249,22 +5586,17 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, if (p->dwVersion != PIN_INFO_CURRENT_VERSION) return ERROR_REVISION_MISMATCH; + if (dwFlags >= MD_MAX_PINS) + return SCARD_E_INVALID_PARAMETER; + + if (!vs->pin_objs[dwFlags]) + return SCARD_E_INVALID_PARAMETER; + p->PinType = vs->reader->capabilities & SC_READER_CAP_PIN_PAD || vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH ? ExternalPinType : AlphaNumericPinType; p->dwFlags = 0; switch (dwFlags) { - case ROLE_USER: - logprintf(pCardData, 2, - "returning info on PIN ROLE_USER ( Auth ) [%lu]\n", - (unsigned long)dwFlags); - p->PinPurpose = DigitalSignaturePin; - p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION; - p->PinCachePolicy.dwPinCachePolicyInfo = 0; - p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; - p->dwChangePermission = CREATE_PIN_SET(ROLE_USER); - p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN); - break; case ROLE_ADMIN: logprintf(pCardData, 2, "returning info on PIN ROLE_ADMIN ( Unblock ) [%lu]\n", @@ -5277,19 +5609,40 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, p->dwUnblockPermission = 0; break; default: - logprintf(pCardData, 0, - "Invalid Pin number %lu requested\n", + logprintf(pCardData, 2, + "returning info on normal PIN [%lu]\n", (unsigned long)dwFlags); - return SCARD_E_INVALID_PARAMETER; + + if (dwFlags == ROLE_USER) + p->PinPurpose = PrimaryCardPin; + else if (dwFlags == MD_ROLE_USER_SIGN) + p->PinPurpose = DigitalSignaturePin; + else + p->PinPurpose = AuthenticationPin; + + p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION; + p->PinCachePolicy.dwPinCachePolicyInfo = 0; + p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; + p->dwChangePermission = CREATE_PIN_SET(dwFlags); + p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN); + break; } } else if (wcscmp(CP_CARD_LIST_PINS,wszProperty) == 0) { PPIN_SET p = (PPIN_SET) pbData; + size_t pinidx; if (pdwDataLen) *pdwDataLen = sizeof(*p); if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER; - SET_PIN(*p, ROLE_USER); + + memset(p, 0, sizeof(*p)); + for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) { + if (!vs->pin_objs[pinidx]) + continue; + + SET_PIN(*p, (PIN_ID)pinidx); + } } else if (wcscmp(CP_CARD_AUTHENTICATED_STATE,wszProperty) == 0) { PPIN_SET p = (PPIN_SET) pbData; @@ -5304,8 +5657,12 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, else if (wcscmp(CP_CARD_PIN_STRENGTH_VERIFY,wszProperty) == 0) { DWORD *p = (DWORD *)pbData; - if (dwFlags != ROLE_USER) + if (dwFlags >= MD_MAX_PINS) + return SCARD_E_INVALID_PARAMETER; + + if (!vs->pin_objs[dwFlags]) return SCARD_E_INVALID_PARAMETER; + if (pdwDataLen) *pdwDataLen = sizeof(*p); if (cbData < sizeof(*p)) @@ -5678,35 +6035,6 @@ DWORD WINAPI CardProcessEncryptedData( return SCARD_E_UNSUPPORTED_FEATURE; } -/** The CardCreateContainerEx function creates a new key container that the -container index identifies and the bContainerIndex parameter specifies. The function -associates the key container with the PIN that the PinId parameter specified. -This function is useful if the card-edge does not allow for changing the key attributes -after the key container is created. This function replaces the need to call -CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer -is called. -The caller of this function can provide the key material that the card imports. -This is useful in those situations in which the card either does not support internal -key generation or the caller requests that the key be archived in the card.*/ - -DWORD WINAPI CardCreateContainerEx( - __in PCARD_DATA pCardData, - __in BYTE bContainerIndex, - __in DWORD dwFlags, - __in DWORD dwKeySpec, - __in DWORD dwKeySize, - __in PBYTE pbKeyData, - __in PIN_ID PinId -) -{ - if (PinId == ROLE_ADMIN) - return SCARD_W_SECURITY_VIOLATION; - if (PinId != ROLE_USER) - return SCARD_E_INVALID_PARAMETER; - /* basically CardCreateContainerEx is CardCreateContainer + the PinId */ - return CardCreateContainer(pCardData, bContainerIndex, dwFlags, dwKeySpec, dwKeySize, pbKeyData); -} - DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags) { VENDOR_SPECIFIC *vs; @@ -5870,7 +6198,6 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags static int associate_card(PCARD_DATA pCardData) { VENDOR_SPECIFIC *vs; - DWORD dw; int r; logprintf(pCardData, 1, "associate_card\n"); @@ -5929,18 +6256,7 @@ static int associate_card(PCARD_DATA pCardData) return SCARD_E_UNKNOWN_CARD; } - dw = md_get_pin_by_role(pCardData, ROLE_USER, &vs->obj_user_pin); - if (dw != SCARD_S_SUCCESS) { - logprintf(pCardData, 2, "Cannot get User PIN object"); - return dw; - } - - dw = md_get_pin_by_role(pCardData, ROLE_USER, &vs->obj_sopin); - if (dw != SCARD_S_SUCCESS) - logprintf(pCardData, 2, "Cannot get ADMIN PIN object -- ignored"); - return SCARD_S_SUCCESS; - } static int disassociate_card(PCARD_DATA pCardData) @@ -5953,8 +6269,8 @@ static int disassociate_card(PCARD_DATA pCardData) vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - vs->obj_user_pin = NULL; - vs->obj_sopin = NULL; + memset(vs->pin_objs, 0, sizeof(vs->pin_objs)); + memset(vs->p15_containers, 0, sizeof(vs->p15_containers)); if(vs->p15card) { logprintf(pCardData, 6, "sc_pkcs15_unbind\n"); @@ -6024,4 +6340,3 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, #pragma managed(pop) #endif #endif - diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 8ded1125b5..37b2da7c10 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1213,6 +1213,7 @@ _get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name) struct sc_pkcs15_object *out = NULL; int rv = SC_ERROR_OBJECT_NOT_FOUND; + /* please keep me in sync with md_get_pin_by_role() in minidriver */ if (!strcmp(name, "UserPIN")) { /* Try to get 'global' PIN; if no, get the 'local' one */ rv = sc_pkcs15_find_pin_by_flags(p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, From 294c232ca963c439a9fbdd15a5f75ef12b8d0ecd Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 17 Jun 2017 19:33:37 +0200 Subject: [PATCH 0070/4321] Minidriver card reinitialization cleanup In minidriver before performing a card operation we currently check whether the supplied card handles have changed. If they did the card in reader might have been changed so we reinitialize it. However, in few places in reinitialization call path an error returned by some operation would leave the context in an inconsistent state. So let's walk through this path to make sure that functions there will exit cleanly if an error happens. Also, make sure that all card operations that actually do something have the necessary check call in the first place and also that they all consistently check whether VENDOR_SPECIFIC pointer is not NULL before dereferencing it. This is a cleanup part of "Keep track of card resets by other contexts in minidriver" (that is, it does not include the actual reset handling code introduced by that commit), simplified. Signed-off-by: Maciej S. Szmigiero --- src/minidriver/minidriver.c | 472 +++++++++++++++++++++++++++--------- 1 file changed, 352 insertions(+), 120 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index ecec13e754..99b99408b0 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -179,6 +180,8 @@ struct md_guid_conversion md_static_conversions[MD_MAX_CONVERSIONS] = {0}; typedef struct _VENDOR_SPECIFIC { + BOOL initialized; + struct sc_pkcs15_object *pin_objs[MD_MAX_PINS]; struct sc_context *ctx; @@ -247,10 +250,11 @@ static const struct sc_asn1_entry c_asn1_md_container[C_ASN1_MD_CONTAINER_SIZE] static DWORD md_translate_OpenSC_to_Windows_error(int OpenSCerror, DWORD dwDefaulCode); -static int associate_card(PCARD_DATA pCardData); -static int disassociate_card(PCARD_DATA pCardData); +static DWORD associate_card(PCARD_DATA pCardData); +static void disassociate_card(PCARD_DATA pCardData); static DWORD md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_object *obj); static DWORD md_fs_init(PCARD_DATA pCardData); +static void md_fs_finalize(PCARD_DATA pCardData); #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf @@ -337,25 +341,91 @@ static void loghex(PCARD_DATA pCardData, int level, PBYTE data, size_t len) logprintf(pCardData, level, " %04X %s\n", a, line); } +static DWORD reinit_card(PCARD_DATA pCardData) +{ + VENDOR_SPECIFIC *vs; + DWORD r; + + if (!pCardData) + return SCARD_E_INVALID_PARAMETER; + + vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + + logprintf(pCardData, 2, "trying to reinit card\n"); + + if (vs->initialized) { + disassociate_card(pCardData); + md_fs_finalize(pCardData); + } + + r = associate_card(pCardData); + if (r != SCARD_S_SUCCESS) + return r; + + r = md_fs_init(pCardData); + if (r != SCARD_S_SUCCESS) { + logprintf(pCardData, 1, + "reinit_card md_fs_init failed, r = 0x%lX\n", + (unsigned long)r); + disassociate_card(pCardData); + return r; + } + + return SCARD_S_SUCCESS; +} + +static DWORD reinit_card_for(PCARD_DATA pCardData, const char *name) +{ + DWORD r; + + r = reinit_card(pCardData); + if (r != SCARD_S_SUCCESS) + logprintf(pCardData, 1, + "%s was called, but unable to initialize card, r = %u\n", + name, (unsigned int)r); + + return r; +} + +static DWORD check_card_status(PCARD_DATA pCardData, const char *name) +{ + VENDOR_SPECIFIC *vs; + + if (!pCardData) + return SCARD_E_INVALID_PARAMETER; + + vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + + if (vs->initialized) + return SCARD_S_SUCCESS; + + return reinit_card_for(pCardData, name); +} + /* - * check if the card has been removed, or the + * check if the card is OK, has been removed, or the * caller has changed the handles. - * if so, then free up all previous card info - * and reestablish - * - * FIXME: if this fails the context can be left - * in inconsistent state. + * if so, then try to reinit card */ -static int -check_reader_status(PCARD_DATA pCardData) +static DWORD +check_card_reader_status(PCARD_DATA pCardData, const char *name) { - int r = SCARD_S_SUCCESS; VENDOR_SPECIFIC *vs = NULL; + DWORD dwRet; + int r; logprintf(pCardData, 4, "check_reader_status\n"); if(!pCardData) return SCARD_E_INVALID_PARAMETER; + dwRet = check_card_status(pCardData, name); + if (dwRet != SCARD_S_SUCCESS) + return dwRet; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); if(!vs) return SCARD_E_INVALID_PARAMETER; @@ -368,27 +438,29 @@ check_reader_status(PCARD_DATA pCardData) logprintf(pCardData, 1, "HANDLES CHANGED from 0x%08X 0x%08X\n", (unsigned int)vs->hSCardCtx, (unsigned int)vs->hScard); + return reinit_card_for(pCardData, name); + } - /* Basically a mini AcquireContext */ - r = disassociate_card(pCardData); - logprintf(pCardData, 1, "disassociate_card r = 0x%08X\n", r); - r = associate_card(pCardData); /* need to check return codes */ - if (r != SCARD_S_SUCCESS) - return r; - logprintf(pCardData, 1, "associate_card r = 0x%08X\n", r); - /* Rebuild 'soft' fs - in case changed */ - r = md_fs_init(pCardData); - logprintf(pCardData, 1, "md_fs_init r = 0x%08X\n", r); - } - else if (vs->reader) { - /* This should always work, as BaseCSP should be checking for removal too */ - r = sc_detect_card_presence(vs->reader); - logprintf(pCardData, 2, - "check_reader_status r=%d flags 0x%08X\n", r, - (unsigned int)vs->reader->flags); + /* This should always work, as BaseCSP should be checking for removal too */ + r = sc_detect_card_presence(vs->reader); + logprintf(pCardData, 2, + "check_reader_status r=%d flags 0x%08X\n", r, + (unsigned int)vs->reader->flags); + if (r < 0) + return md_translate_OpenSC_to_Windows_error(r, + SCARD_F_INTERNAL_ERROR); + + if (!(r & SC_READER_CARD_PRESENT)) { + /* + * if there is really no card present it may not make sense to + * try initializing the card but since it won't hurt let's try + * it anyway for completeness + */ + logprintf(pCardData, 1, "no card present? trying to reinit\n"); + return reinit_card_for(pCardData, name); } - return r; + return SCARD_S_SUCCESS; } static DWORD @@ -481,6 +553,9 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL re } vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (!vs) + return ret; + if (vs->ctx && vs->reader) { struct sc_atr atr; scconf_block *atrblock; @@ -581,6 +656,9 @@ md_contguid_get_guid_from_card(PCARD_DATA pCardData, struct sc_pkcs15_object *pr size_t guid_len = MAX_CONTAINER_NAME_LEN+1; vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; + rv = sc_pkcs15_get_object_guid(vs->p15card, prkey, 1, (unsigned char*) szGuid, &guid_len); if (rv) { logprintf(pCardData, 2, "md_contguid_get_guid_from_card(): error %d\n", rv); @@ -683,6 +761,9 @@ md_cont_flags_from_key(PCARD_DATA pCardData, struct sc_pkcs15_object *key_obj, u int rv; vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; + prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data; *cont_flags = CONTAINER_MAP_VALID_CONTAINER; @@ -710,6 +791,9 @@ md_fs_find_directory(PCARD_DATA pCardData, struct md_directory *parent, char *na return SCARD_E_INVALID_PARAMETER; vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; + if (!parent) parent = &vs->root; @@ -889,6 +973,8 @@ md_fs_delete_file(PCARD_DATA pCardData, char *parent, char *name) return SCARD_E_INVALID_PARAMETER; vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; dwret = md_fs_find_directory(pCardData, NULL, parent, &dir); if (dwret != SCARD_S_SUCCESS) { @@ -949,7 +1035,7 @@ md_fs_delete_file(PCARD_DATA pCardData, char *parent, char *name) return dwret; } -static DWORD +static void md_fs_finalize(PCARD_DATA pCardData) { VENDOR_SPECIFIC *vs; @@ -957,9 +1043,11 @@ md_fs_finalize(PCARD_DATA pCardData) struct md_directory *dir = NULL, *dir_to_rm; if (!pCardData) - return SCARD_E_INVALID_PARAMETER; + return; vs = pCardData->pvVendorSpecific; + if (!vs) + return; file = vs->root.files; while (file != NULL) { @@ -967,6 +1055,7 @@ md_fs_finalize(PCARD_DATA pCardData) file = file->next; md_fs_free_file(pCardData, file_to_rm); } + vs->root.files = NULL; dir = vs->root.subdirs; while(dir) { @@ -980,7 +1069,7 @@ md_fs_finalize(PCARD_DATA pCardData) dir = dir->next; pCardData->pfnCspFree(dir_to_rm); } - return 0; + vs->root.subdirs = NULL; } /* @@ -998,6 +1087,8 @@ md_pkcs15_update_containers(PCARD_DATA pCardData, unsigned char *blob, size_t si return SCARD_E_INVALID_PARAMETER; vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; nn_records = (int) size/sizeof(CONTAINER_MAP_RECORD); if (nn_records > MD_MAX_KEY_CONTAINERS) @@ -1044,6 +1135,9 @@ md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_object *obj) if (!pCardData) return SCARD_E_INVALID_PARAMETER; vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; + card = vs->p15card->card; if (!obj) @@ -1124,6 +1218,9 @@ md_set_cardid(PCARD_DATA pCardData, struct md_file *file) return SCARD_E_INVALID_PARAMETER; vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; + if (vs->p15card->tokeninfo && vs->p15card->tokeninfo->serial_number) { unsigned char sn_bin[SC_MAX_SERIALNR]; unsigned char cardid_bin[MD_CARDID_SIZE]; @@ -1375,6 +1472,8 @@ md_fs_add_msroots(PCARD_DATA pCardData, struct md_file **head) return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC *) pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; rv = sc_pkcs15_get_objects(vs->p15card, SC_PKCS15_TYPE_CERT_X509, prkey_objs, MD_MAX_KEY_CONTAINERS); if (rv < 0) { @@ -1432,6 +1531,8 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) logprintf(pCardData, 2, "set 'cmapfile'\n"); vs = pCardData->pvVendorSpecific; + if (!vs) + return SCARD_E_INVALID_PARAMETER; dwret = md_get_pin_by_role(pCardData, ROLE_USER, &vs->pin_objs[ROLE_USER]); if (dwret != SCARD_S_SUCCESS) { @@ -1860,32 +1961,32 @@ md_fs_init(PCARD_DATA pCardData) return dwret; dwret = md_set_cardid(pCardData, cardid); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_fs_add_file(pCardData, &(vs->root.files), "cardcf", EveryoneReadUserWriteAc, NULL, 0, &cardcf); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_set_cardcf(pCardData, cardcf); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_fs_add_file(pCardData, &(vs->root.files), "cardapps", EveryoneReadAdminWriteAc, NULL, 0, &cardapps); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_set_cardapps(pCardData, cardapps); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_fs_add_directory(pCardData, &(vs->root.subdirs), "mscp", UserCreateDeleteDirAc, &mscp); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_fs_add_file(pCardData, &(mscp->files), "cmapfile", EveryoneReadUserWriteAc, NULL, 0, &cmapfile); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; dwret = md_set_cmapfile(pCardData, cmapfile); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto ret_cleanup; #ifdef OPENSSL_VERSION_NUMBER logprintf(pCardData, 3, @@ -1896,6 +1997,10 @@ md_fs_init(PCARD_DATA pCardData) "MD virtual file system initialized; Without OPENSSL\n"); #endif return SCARD_S_SUCCESS; + +ret_cleanup: + md_fs_finalize(pCardData); + return dwret; } /* Create SC context */ @@ -1955,6 +2060,8 @@ md_free_space(PCARD_DATA pCardData, PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo) return ERROR_REVISION_MISMATCH; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; /* Count free containers */ for (idx=0, count=0; idxpvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (flags & CARD_CREATE_CONTAINER_KEY_IMPORT) { if (key_algo == SC_ALGORITHM_RSA) { @@ -2123,6 +2232,8 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId]) return SCARD_E_INVALID_PARAMETER; @@ -2262,6 +2373,8 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId]) return SCARD_E_INVALID_PARAMETER; @@ -2398,6 +2511,9 @@ md_pkcs15_store_certificate(PCARD_DATA pCardData, char *file_name, unsigned char logprintf(pCardData, 1, "MdStoreCert(): store certificate '%s'\n", file_name); vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + card = vs->p15card->card; memset(&args, 0, sizeof(args)); @@ -2467,6 +2583,9 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi logprintf(pCardData, 1, "md_query_key_sizes: store dwKeySpec '%lu'\n", (unsigned long)dwKeySpec); vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + count = vs->p15card->card->algorithm_count; pKeySizes->dwVersion = CARD_KEY_SIZES_CURRENT_VERSION; @@ -2808,7 +2927,10 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData) if(!vs) return SCARD_E_INVALID_PARAMETER; - disassociate_card(pCardData); + if (vs->initialized) { + disassociate_card(pCardData); + md_fs_finalize(pCardData); + } if(vs->ctx) { logprintf(pCardData, 6, "release context\n"); @@ -2819,7 +2941,6 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData) logprintf(pCardData, 1, "**********************************************************************\n"); - md_fs_finalize(pCardData); pCardData->pfnCspFree(pCardData->pvVendorSpecific); pCardData->pvVendorSpecific = NULL; @@ -2839,11 +2960,13 @@ DWORD WINAPI CardQueryCapabilities(__in PCARD_DATA pCardData, if (!pCardData || !pCardCapabilities) return SCARD_E_INVALID_PARAMETER; - dwret = md_card_capabilities(pCardData, pCardCapabilities); + dwret = check_card_status(pCardData, "CardQueryCapabilities"); if (dwret != SCARD_S_SUCCESS) return dwret; - check_reader_status(pCardData); + dwret = md_card_capabilities(pCardData, pCardCapabilities); + if (dwret != SCARD_S_SUCCESS) + return dwret; return SCARD_S_SUCCESS; } @@ -2864,6 +2987,10 @@ DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData, if (!pCardData) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardDeleteContainer"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) return SCARD_E_INVALID_PARAMETER; @@ -2922,6 +3049,10 @@ DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, if (PinId == ROLE_ADMIN) return SCARD_W_SECURITY_VIOLATION; + dwret = check_card_reader_status(pCardData, "CardCreateContainerEx"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); @@ -3004,7 +3135,7 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine { VENDOR_SPECIFIC *vs = NULL; DWORD sz = 0; - DWORD ret = SCARD_F_UNKNOWN_ERROR; + DWORD ret; struct md_pkcs15_container *cont = NULL; struct sc_pkcs15_der pubkey_der; struct sc_pkcs15_prkey_info *prkey_info = NULL; @@ -3015,6 +3146,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine if (!pContainerInfo) return SCARD_E_INVALID_PARAMETER; + ret = check_card_reader_status(pCardData, "CardGetContainerInfo"); + if (ret != SCARD_S_SUCCESS) + return ret; + logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); @@ -3035,6 +3170,9 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine pContainerInfo->dwVersion = CONTAINER_INFO_CURRENT_VERSION; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + cont = &vs->p15_containers[bContainerIndex]; if (!cont->prkey_obj) { @@ -3043,13 +3181,9 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine return SCARD_E_NO_KEY_CONTAINER; } - if (vs->p15card == NULL) { - return SCARD_F_INTERNAL_ERROR; - } - + ret = SCARD_F_UNKNOWN_ERROR; prkey_info = (struct sc_pkcs15_prkey_info *)cont->prkey_obj->data; - check_reader_status(pCardData); pubkey_der.value = NULL; pubkey_der.len = 0; @@ -3284,6 +3418,7 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData, __out PDWORD pcbChallengeData) { VENDOR_SPECIFIC *vs; + DWORD dwret; int rv; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", @@ -3296,9 +3431,13 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData, if (!ppbChallengeData || !pcbChallengeData) return SCARD_E_INVALID_PARAMETER; - vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + dwret = check_card_reader_status(pCardData, "CardGetChallenge"); + if (dwret != SCARD_S_SUCCESS) + return dwret; - check_reader_status(pCardData); + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; *pcbChallengeData = 8; @@ -3446,14 +3585,12 @@ DWORD WINAPI CardChangeAuthenticator(__in PCARD_DATA pCardData, cRetryCount, pcAttemptsRemaining); } -/* this function is not called on purpose. -If a deauthentication is not possible, it should be set to NULL in CardAcquireContext. -Because this function do nothing - it is not called. -Note: the PIN freshnesh will be managed by the Base CSP*/ +/* Note: the PIN freshness will be managed by the Base CSP */ DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData, __in LPWSTR pwszUserId, __in DWORD dwFlags) { + DWORD dwret; VENDOR_SPECIFIC* vs = NULL; int rv; logprintf(pCardData, 1, "\nP:%ld T:%ld pCardData:%p ", @@ -3465,7 +3602,13 @@ DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData, if(!pCardData) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardDeauthenticate"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; sc_pkcs15_pincache_clear(vs->p15card); @@ -3515,6 +3658,10 @@ DWORD WINAPI CardCreateFile(__in PCARD_DATA pCardData, NULLSTR(pszDirectoryName), NULLSTR(pszFileName), (unsigned long)cbInitialCreationSize, AccessCondition); + dwret = check_card_status(pCardData, "CardCreateFile"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + dwret = md_fs_find_directory(pCardData, NULL, pszDirectoryName, &dir); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "CardCreateFile() cannot find parent directory '%s'", NULLSTR(pszDirectoryName)); @@ -3537,6 +3684,7 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData, __out PDWORD pcbData) { struct md_file *file = NULL; + DWORD dwret; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), @@ -3556,7 +3704,9 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData, if (dwFlags) return SCARD_E_INVALID_PARAMETER; - check_reader_status(pCardData); + dwret = check_card_reader_status(pCardData, "CardReadFile"); + if (dwret != SCARD_S_SUCCESS) + return dwret; md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file); if (!file) { @@ -3607,7 +3757,9 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardWriteFile() dirName:'%s', fileName:'%s' \n", NULLSTR(pszDirectoryName), NULLSTR(pszFileName)); - check_reader_status(pCardData); + dwret = check_card_reader_status(pCardData, "CardWriteFile"); + if (dwret != SCARD_S_SUCCESS) + return dwret; if (pbData && cbData) { logprintf(pCardData, 1, "CardWriteFile try to write (%lu):\n", @@ -3659,7 +3811,9 @@ DWORD WINAPI CardDeleteFile(__in PCARD_DATA pCardData, if(!pCardData) return SCARD_E_INVALID_PARAMETER; - check_reader_status(pCardData); + dwret = check_card_reader_status(pCardData, "CardDeleteFile"); + if (dwret != SCARD_S_SUCCESS) + return dwret; dwret = md_fs_delete_file(pCardData, pszDirectoryName, pszFileName); if (dwret != SCARD_S_SUCCESS) { @@ -3680,6 +3834,7 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData, __in DWORD dwFlags) { VENDOR_SPECIFIC *vs = NULL; + DWORD dwret; char mstr[0x100]; struct md_directory *dir = NULL; struct md_file *file = NULL; @@ -3701,7 +3856,13 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData, return SCARD_E_INVALID_PARAMETER; } + dwret = check_card_status(pCardData, "CardEnumFiles"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; memset(mstr, 0, sizeof(mstr)); @@ -3739,6 +3900,7 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData, __in LPSTR pszFileName, __inout PCARD_FILE_INFO pCardFileInfo) { + DWORD dwret; struct md_file *file = NULL; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", @@ -3746,6 +3908,10 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardGetFileInfo(dirName:'%s',fileName:'%s', out %p)\n", NULLSTR(pszDirectoryName), NULLSTR(pszFileName), pCardFileInfo); + dwret = check_card_status(pCardData, "CardGetFileInfo"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file); if (!file) { logprintf(pCardData, 2, "CardWriteFile(): file '%s' not found in '%s'\n", NULLSTR(pszFileName), NULLSTR(pszDirectoryName)); @@ -3776,7 +3942,9 @@ DWORD WINAPI CardQueryFreeSpace(__in PCARD_DATA pCardData, __in DWORD dwFlags, if (!pCardData) return SCARD_E_INVALID_PARAMETER; - check_reader_status(pCardData); + dwret = check_card_status(pCardData, "CardQueryFreeSpace"); + if (dwret != SCARD_S_SUCCESS) + return dwret; dwret = md_free_space(pCardData, pCardFreeSpaceInfo); if (dwret != SCARD_S_SUCCESS) { @@ -3812,6 +3980,10 @@ DWORD WINAPI CardQueryKeySizes(__in PCARD_DATA pCardData, if ( dwKeySpec == 0 ) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_status(pCardData, "CardQueryKeySizes"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + dwret = md_query_key_sizes(pCardData, dwKeySpec, pKeySizes); if (dwret != SCARD_S_SUCCESS) return dwret; @@ -3826,6 +3998,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, __inout PCARD_RSA_DECRYPT_INFO pInfo) { + DWORD dwret; int r, opt_crypt_flags = 0; unsigned ui; VENDOR_SPECIFIC *vs; @@ -3852,14 +4025,18 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, if (pInfo->dwKeySpec != AT_KEYEXCHANGE) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardRSADecrypt"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; /* check if the container exists */ if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) return SCARD_E_NO_KEY_CONTAINER; - check_reader_status(pCardData); - logprintf(pCardData, 2, "CardRSADecrypt dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu pbData=%p, cbData=%lu\n", (unsigned long)pInfo->dwVersion, @@ -4007,6 +4184,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO pInfo) { + DWORD dwret; VENDOR_SPECIFIC *vs; ALG_ID hashAlg; sc_pkcs15_prkey_info_t *prkey_info; @@ -4044,6 +4222,10 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO if (pInfo->dwSigningFlags & ~(CARD_PADDING_INFO_PRESENT | CARD_PADDING_NONE | CARD_BUFFER_SIZE_ONLY | CARD_PADDING_PKCS1 | CARD_PADDING_PSS | CARD_PADDING_OAEP)) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardSignData"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + logprintf(pCardData, 2, "CardSignData dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu, dwSigningFlags=0x%08X, aiHashAlg=0x%08X\n", (unsigned long)pInfo->dwVersion, @@ -4059,6 +4241,9 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO hashAlg = pInfo->aiHashAlg; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) return SCARD_E_NO_KEY_CONTAINER; @@ -4067,8 +4252,6 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO return SCARD_E_NO_KEY_CONTAINER; prkey_info = (struct sc_pkcs15_prkey_info *)(pkey->data); - check_reader_status(pCardData); - logprintf(pCardData, 2, "pInfo->dwVersion = %lu\n", (unsigned long)pInfo->dwVersion); @@ -4264,6 +4447,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, __inout PCARD_DH_AGREEMENT_INFO pAgreementInfo) { + DWORD dwret; VENDOR_SPECIFIC *vs; struct sc_pkcs15_object *pkey = NULL; int r, opt_derive_flags = 0; @@ -4292,14 +4476,18 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, && pCardData->dwVersion == CARD_DATA_CURRENT_VERSION) return ERROR_REVISION_MISMATCH; + dwret = check_card_reader_status(pCardData, "CardConstructDHAgreement"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; /* check if the container exists */ if (pAgreementInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) return SCARD_E_NO_KEY_CONTAINER; - check_reader_status(pCardData); - logprintf(pCardData, 2, "CardConstructDHAgreement dwVersion=%lu, dwKeySpec=%u pbData=%p, cbData=%lu\n", (unsigned long)pAgreementInfo->dwVersion, (unsigned int)pAgreementInfo->bContainerIndex, @@ -4835,6 +5023,8 @@ DWORD WINAPI CardDeriveKey(__in PCARD_DATA pCardData, return ERROR_REVISION_MISMATCH;*/ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; /* check if the agreement index is ok */ if (pAgreementInfo->bSecretAgreementIndex >= vs->allocatedAgreements) { @@ -5005,6 +5195,8 @@ DWORD WINAPI CardDestroyDHAgreement( if (dwFlags) return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (bSecretAgreementIndex >= vs->allocatedAgreements) { return SCARD_E_INVALID_PARAMETER; @@ -5043,6 +5235,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, __out_opt PDWORD pcbSessionPin, __out_opt PDWORD pcAttemptsRemaining) { + DWORD dwret; VENDOR_SPECIFIC *vs; struct sc_pkcs15_object *pin_obj = NULL; struct sc_pkcs15_auth_info *auth_info = NULL; @@ -5058,17 +5251,18 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (!pCardData) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardAuthenticateEx"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + logprintf(pCardData, 2, "CardAuthenticateEx: PinId=%u, dwFlags=0x%08X, cbPinData=%lu, Attempts %s\n", (unsigned int)PinId, (unsigned int)dwFlags, (unsigned long)cbPinData, pcAttemptsRemaining ? "YES" : "NO"); vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - - r = check_reader_status(pCardData); - - if ((vs->p15card) == NULL) - return SCARD_F_INTERNAL_ERROR; + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (PinId >= MD_MAX_PINS) return SCARD_E_INVALID_PARAMETER; @@ -5227,6 +5421,7 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, __in DWORD cRetryCount, __out_opt PDWORD pcAttemptsRemaining) { + DWORD dwret; VENDOR_SPECIFIC *vs = NULL; struct sc_pkcs15_object *pin_obj = NULL; int rv; @@ -5242,7 +5437,13 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, if (!pCardData) return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardChangeAuthenticatorEx"); + if (dwret != SCARD_S_SUCCESS) + return dwret; + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (!(dwFlags & PIN_CHANGE_FLAG_UNBLOCK) && !(dwFlags & PIN_CHANGE_FLAG_CHANGEPIN)){ logprintf(pCardData, 1, "Unknown flag\n"); @@ -5268,9 +5469,6 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData, (unsigned int)dwTargetPinId, (unsigned long)cbTargetData, pcAttemptsRemaining ? "YES" : "NO"); - - check_reader_status(pCardData); - if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD || vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) { if (pbAuthenticatingPinData == NULL || cbAuthenticatingPinData == 0) { @@ -5350,6 +5548,7 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData, __out PDWORD pdwDataLen, __in DWORD dwFlags) { + DWORD dwret; VENDOR_SPECIFIC *vs = NULL; struct md_pkcs15_container *cont = NULL; @@ -5358,9 +5557,13 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardGetContainerProperty\n"); - check_reader_status(pCardData); + if (!pCardData) + return SCARD_E_INVALID_PARAMETER; + + dwret = check_card_status(pCardData, "CardGetContainerProperty"); + if (dwret != SCARD_S_SUCCESS) + return dwret; - if (!pCardData) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 2, "CardGetContainerProperty bContainerIndex=%u, wszProperty=%S, cbData=%lu, dwFlags=0x%08X\n", (unsigned int)bContainerIndex, NULLWSTR(wszProperty), @@ -5376,6 +5579,9 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData, /* the test for the existence of containers is redondant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + cont = &vs->p15_containers[bContainerIndex]; if (!cont->prkey_obj) { @@ -5475,9 +5681,13 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, if (!pbData || !pdwDataLen) return SCARD_E_INVALID_PARAMETER; - vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + dwret = check_card_reader_status(pCardData, "CardGetProperty"); + if (dwret != SCARD_S_SUCCESS) + return dwret; - check_reader_status(pCardData); + vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (wcscmp(CP_CARD_FREE_SPACE,wszProperty) == 0) { PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo = (PCARD_FREE_SPACE_INFO )pbData; @@ -5728,6 +5938,8 @@ DWORD WINAPI CardSetProperty(__in PCARD_DATA pCardData, (unsigned long)dwFlags); vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; if (!wszProperty) return SCARD_E_INVALID_PARAMETER; @@ -6042,7 +6254,7 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags if (!pCardData) return SCARD_E_INVALID_PARAMETER; - if (dwFlags) + if (dwFlags & ~CARD_SECURE_KEY_INJECTION_NO_CARD_MODE) return SCARD_E_INVALID_PARAMETER; if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE)) { if( pCardData->hSCardCtx == 0) { @@ -6109,11 +6321,8 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags (unsigned long)pCardData->dwVersion); dwret = md_create_context(pCardData, vs); - if (dwret != SCARD_S_SUCCESS) { - pCardData->pfnCspFree(pCardData->pvVendorSpecific); - pCardData->pvVendorSpecific = NULL; - return dwret; - } + if (dwret != SCARD_S_SUCCESS) + goto ret_free; md_static_data.flags &= ~MD_STATIC_FLAG_CONTEXT_DELETED; pCardData->pfnCardDeleteContext = CardDeleteContext; @@ -6144,18 +6353,12 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags pCardData->pfnCardConstructDHAgreement = CardConstructDHAgreement; dwret = associate_card(pCardData); - if (dwret != SCARD_S_SUCCESS) { - pCardData->pfnCspFree(pCardData->pvVendorSpecific); - pCardData->pvVendorSpecific = NULL; - return dwret; - } + if (dwret != SCARD_S_SUCCESS) + goto ret_release; dwret = md_fs_init(pCardData); - if (dwret != SCARD_S_SUCCESS) { - pCardData->pfnCspFree(pCardData->pvVendorSpecific); - pCardData->pvVendorSpecific = NULL; - return dwret; - } + if (dwret != SCARD_S_SUCCESS) + goto ret_disassoc; logprintf(pCardData, 1, "OpenSC init done.\n"); logprintf(pCardData, 1, "Supplied version %lu - version used %lu.\n", @@ -6193,18 +6396,35 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags } return SCARD_S_SUCCESS; + +ret_disassoc: + disassociate_card(pCardData); + +ret_release: + sc_release_context(vs->ctx); + md_static_data.flags |= MD_STATIC_FLAG_CONTEXT_DELETED; + +ret_free: + pCardData->pfnCspFree(pCardData->pvVendorSpecific); + pCardData->pvVendorSpecific = NULL; + return dwret; } -static int associate_card(PCARD_DATA pCardData) +static DWORD associate_card(PCARD_DATA pCardData) { VENDOR_SPECIFIC *vs; int r; + struct sc_app_info *app_generic; + struct sc_aid *aid; logprintf(pCardData, 1, "associate_card\n"); if (!pCardData) return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) + return SCARD_E_INVALID_PARAMETER; + /* * set the addresses of the reader and card handles * Our pcsc code will use these when we call sc_ctx_use_reader @@ -6225,49 +6445,62 @@ static int associate_card(PCARD_DATA pCardData) } /* set the provided reader and card handles into ctx */ - logprintf(pCardData, 5, "sc_ctx_use_reader %d\n", sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard)); + r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard); + if (r != SC_SUCCESS) { + logprintf(pCardData, 0, "sc_ctx_use_reader() failed with %d\n", r); + return SCARD_E_COMM_DATA_LOST; + } /* should be only one reader */ logprintf(pCardData, 5, "sc_ctx_get_reader_count(ctx): %d\n", sc_ctx_get_reader_count(vs->ctx)); vs->reader = sc_ctx_get_reader(vs->ctx, 0); - if(vs->reader) { - struct sc_app_info *app_generic = NULL; - struct sc_aid *aid = NULL; - - r = sc_connect_card(vs->reader, &(vs->card)); - if(r) { - logprintf(pCardData, 0, "Cannot connect card in reader '%s'\n", NULLSTR(vs->reader->name)); - return SCARD_E_UNKNOWN_CARD; - } - logprintf(pCardData, 3, "Connected card in '%s'\n", NULLSTR(vs->reader->name)); + if (!vs->reader) + return SCARD_E_COMM_DATA_LOST; - app_generic = sc_pkcs15_get_application_by_type(vs->card, "generic"); - if (app_generic) - logprintf(pCardData, 3, "Use generic application '%s'\n", app_generic->label); - aid = app_generic ? &app_generic->aid : NULL; - - r = sc_pkcs15_bind(vs->card, aid, &(vs->p15card)); - logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", r, sc_strerror(r)); + r = sc_connect_card(vs->reader, &(vs->card)); + if (r != SC_SUCCESS) { + logprintf(pCardData, 0, "Cannot connect card in reader '%s'\n", NULLSTR(vs->reader->name)); + return SCARD_E_UNKNOWN_CARD; } + logprintf(pCardData, 3, "Connected card in '%s'\n", NULLSTR(vs->reader->name)); - if(vs->card == NULL || vs->p15card == NULL) { - logprintf(pCardData, 0, "Card unknown.\n"); + app_generic = sc_pkcs15_get_application_by_type(vs->card, "generic"); + if (app_generic) + logprintf(pCardData, 3, "Use generic application '%s'\n", app_generic->label); + aid = app_generic ? &app_generic->aid : NULL; + + r = sc_pkcs15_bind(vs->card, aid, &(vs->p15card)); + logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", r, sc_strerror(r)); + if (r != SC_SUCCESS) { + logprintf(pCardData, 0, "PKCS#15 init failed.\n"); + sc_disconnect_card(vs->card); return SCARD_E_UNKNOWN_CARD; } + vs->initialized = TRUE; + return SCARD_S_SUCCESS; } -static int disassociate_card(PCARD_DATA pCardData) +static void disassociate_card(PCARD_DATA pCardData) { VENDOR_SPECIFIC *vs; + if (!pCardData) { + logprintf(pCardData, 1, + "disassociate_card called without card data\n"); + return; + } + logprintf(pCardData, 1, "disassociate_card\n"); - if (!pCardData) - return SCARD_E_INVALID_PARAMETER; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (!vs) { + logprintf(pCardData, 1, + "disassociate_card called without vendor specific data\n"); + return; + } memset(vs->pin_objs, 0, sizeof(vs->pin_objs)); memset(vs->p15_containers, 0, sizeof(vs->p15_containers)); @@ -6288,8 +6521,7 @@ static int disassociate_card(PCARD_DATA pCardData) vs->hSCardCtx = -1; vs->hScard = -1; - - return SCARD_S_SUCCESS; + vs->initialized = FALSE; } From 0cb654ca78d0a007489e3a1f59e4726152d310d7 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 17 Jun 2017 19:41:06 +0200 Subject: [PATCH 0071/4321] sc-hsm: fix unused variable warnings in sc_hsm_init() When building without OpenPACE there are two unused variables in sc_hsm_init() that cause compiler to emit warnings about them. Signed-off-by: Maciej S. Szmigiero --- src/libopensc/card-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 84f767b2ea..fc74192481 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1543,7 +1543,7 @@ static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int sc_hsm_init(struct sc_card *card) { -#ifdef _WIN32 +#if defined(ENABLE_OPENPACE) && defined(_WIN32) char expanded_val[PATH_MAX]; size_t expanded_len = PATH_MAX; #endif From 8d7346406d166a9db4afd239e6669df3e3b99f79 Mon Sep 17 00:00:00 2001 From: Feitian Technologies Date: Mon, 4 Sep 2017 19:29:24 +0800 Subject: [PATCH 0072/4321] Add ECC support and solve wrong Length status codes with SM card Fix #1073 Fix #1115 --- src/libopensc/card-epass2003.c | 171 ++++++++++++++++++++++++++---- src/libopensc/cardctl.h | 4 +- src/libopensc/sm.c | 2 +- src/pkcs15init/pkcs15-epass2003.c | 49 +++++++-- 4 files changed, 197 insertions(+), 29 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 84ab645692..7feab59846 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -98,6 +98,8 @@ typedef struct epass2003_exdata_st { unsigned char sk_enc[16]; /* encrypt session key */ unsigned char sk_mac[16]; /* mac session key */ unsigned char icv_mac[16]; /* instruction counter vector(for sm) */ + unsigned char currAlg; /* current Alg */ + unsigned int ecAlgFlags; /* Ec Alg mechanism type*/ } epass2003_exdata; #define REVERSE_ORDER4(x) ( \ @@ -170,6 +172,7 @@ static const struct sc_card_error epass2003_errors[] = { static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out); int epass2003_refresh(struct sc_card *card); +static int hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType); static int epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) @@ -403,6 +406,12 @@ sha1_digest(const unsigned char *input, size_t length, unsigned char *output) return openssl_dig(EVP_sha1(), input, length, output); } +static int +sha256_digest(const unsigned char *input, size_t length, unsigned char *output) +{ + return openssl_dig(EVP_sha256(), input, length, output); +} + static int gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_mac, @@ -1140,6 +1149,7 @@ static int epass2003_init(struct sc_card *card) { unsigned int flags; + unsigned int ext_flags; unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; size_t datalen = SC_MAX_APDU_BUFFER_SIZE; epass2003_exdata *exdata = NULL; @@ -1192,6 +1202,11 @@ epass2003_init(struct sc_card *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); + //set EC Alg Flags + flags = SC_ALGORITHM_ONBOARD_KEY_GEN|SC_ALGORITHM_ECDSA_HASH_SHA1|SC_ALGORITHM_ECDSA_HASH_SHA256|SC_ALGORITHM_ECDSA_HASH_NONE|SC_ALGORITHM_ECDSA_RAW; + ext_flags = 0; + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + card->caps = SC_CARD_CAP_RNG | SC_CARD_CAP_APDU_EXT; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); @@ -1561,6 +1576,13 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, u8 *p; unsigned short fid = 0; int r, locked = 0; + epass2003_exdata *exdata = NULL; + + if (!card->drv_data) + return SC_ERROR_INVALID_ARGUMENTS; + + exdata = (epass2003_exdata *)card->drv_data; + exdata->currAlg = SC_ALGORITHM_RSA; //default algorithm sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); switch (env->operation) { @@ -1590,6 +1612,28 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, apdu.lc = r; apdu.datalen = r; apdu.data = sbuf; + + if (env->algorithm == SC_ALGORITHM_EC) + { + apdu.p2 = 0xB6; + exdata->currAlg = SC_ALGORITHM_EC; + if(env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA1) + { + sbuf[2] = 0x91; + exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1; + } + else if (env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA256) + { + sbuf[2] = 0x92; + exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256; + } + else + { + sc_log(card->ctx, "%0x Alg Not Support! ", env->algorithm_flags); + goto err; + } + } + if (se_num > 0) { r = sc_lock(card); LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); @@ -1640,7 +1684,55 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data struct sc_apdu apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + epass2003_exdata *exdata = NULL; + + LOG_FUNC_CALLED(card->ctx); + + if (!card->drv_data) + return SC_ERROR_INVALID_ARGUMENTS; + + exdata = (epass2003_exdata *)card->drv_data; + if(exdata->currAlg == SC_ALGORITHM_EC) + { + unsigned char hash[HASH_LEN] = { 0 }; + if(exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA1) + { + hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + memset(sbuf, 0, sizeof(sbuf)); + memcpy(sbuf, hash, 0x14); + apdu.data = sbuf; + apdu.lc = 0x14; + apdu.datalen = 0x14; + } + else if (exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA256) + { + hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA256); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + memset(sbuf, 0, sizeof(sbuf)); + memcpy(sbuf, hash, 0x20); + apdu.data = sbuf; + apdu.lc = 0x20; + apdu.datalen = 0x20; + } + else + { + return SC_ERROR_NOT_SUPPORTED; + } + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 0; + + r = sc_transmit_apdu_t(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; + memcpy(out, apdu.resp, len); + LOG_FUNC_RETURN(card->ctx, len); + } + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -1862,11 +1954,13 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { - if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { buf[0] = 0x11; buf[1] = 0x00; } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { buf[0] = 0x12; buf[1] = 0x00; } @@ -1903,7 +1997,9 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT|| + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { buf[0] = (file->size >> 8) & 0xFF; buf[1] = file->size & 0xFF; sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p); @@ -1942,13 +2038,14 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, ops[3] = SC_AC_OP_DELETE; } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { - if (file->ef_structure == - SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_CRYPTO; ops[3] = SC_AC_OP_DELETE; } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { ops[0] = SC_AC_OP_READ; ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_CRYPTO; @@ -1973,13 +2070,22 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, buf[ii] = rv; } sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p); + if(file->size == 256) + { + out[4]= 0x13; + } } /* VT ??? */ - if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { unsigned char data[2] = {0x00, 0x66}; sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p); + if(file->size == 256) + { + out[4]= 0x14; + } } out[1] = p - out - 2; @@ -2129,19 +2235,36 @@ internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs1 static int -hash_data(unsigned char *data, size_t datalen, unsigned char *hash) +hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType) { - unsigned char data_hash[24] = { 0 }; - size_t len = 0; if ((NULL == data) || (NULL == hash)) return SC_ERROR_INVALID_ARGUMENTS; - sha1_digest(data, datalen, data_hash); + if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA1) + { + unsigned char data_hash[24] = { 0 }; + size_t len = 0; - len = REVERSE_ORDER4(datalen); - memcpy(&data_hash[20], &len, 4); - memcpy(hash, data_hash, 24); + sha1_digest(data, datalen, data_hash); + len = REVERSE_ORDER4(datalen); + memcpy(&data_hash[20], &len, 4); + memcpy(hash, data_hash, 24); + } + else if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA256) + { + unsigned char data_hash[36] = { 0 }; + size_t len = 0; + + sha256_digest(data, datalen, data_hash); + len = REVERSE_ORDER4(datalen); + memcpy(&data_hash[32], &len, 4); + memcpy(hash, data_hash, 36); + } + else + { + return SC_ERROR_NOT_SUPPORTED; + } return SC_SUCCESS; } @@ -2214,7 +2337,7 @@ internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin) int r; unsigned char hash[HASH_LEN] = { 0 }; - r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash); + r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid, @@ -2265,7 +2388,14 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) LOG_FUNC_CALLED(card->ctx); - sbuf[0] = 0x01; + if(len == 256) + { + sbuf[0] = 0x02; + } + else + { + sbuf[0] = 0x01; + } sbuf[1] = (u8) ((len >> 8) & 0xff); sbuf[2] = (u8) (len & 0xff); sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF); @@ -2285,6 +2415,10 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) /* read public key */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00); + if(len == 256) + { + apdu.p1 = 0x00; + } apdu.cla = 0x80; apdu.lc = apdu.datalen = 2; apdu.data = &sbuf[5]; @@ -2349,6 +2483,7 @@ epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) { LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "cmd is %0lx", cmd); switch (cmd) { case SC_CARDCTL_ENTERSAFE_WRITE_KEY: return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr); @@ -2474,7 +2609,7 @@ external_key_auth(struct sc_card *card, unsigned char kid, r = sc_get_challenge(card, random, 8); LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed"); - r = hash_data(data, datalen, hash); + r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); des3_encrypt_cbc(hash, HASH_LEN, iv, random, 8, tmp_data); @@ -2501,7 +2636,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, unsigned char tmp_data[256] = { 0 }; unsigned char maxtries = 0; - r = hash_data(data, datalen, hash); + r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); r = get_external_key_maxtries(card, &maxtries); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 9a58427b7a..b647b0537e 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -490,7 +490,9 @@ enum SC_CARDCTL_OBERTHUR_KEY_TYPE { SC_CARDCTL_OBERTHUR_KEY_RSA_SFM, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, SC_CARDCTL_OBERTHUR_KEY_DSA_PUBLIC, - SC_CARDCTL_OBERTHUR_KEY_DSA_PRIVATE + SC_CARDCTL_OBERTHUR_KEY_DSA_PRIVATE, + SC_CARDCTL_OBERTHUR_KEY_EC_CRT, + SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC }; struct sc_cardctl_oberthur_genkey_info { diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c index 94f7ce7c3c..877a5ef120 100644 --- a/src/libopensc/sm.c +++ b/src/libopensc/sm.c @@ -157,7 +157,7 @@ sc_sm_single_transmit(struct sc_card *card, struct sc_apdu *apdu) } /* send APDU flagged as NO_SM */ - sm_apdu->flags |= SC_APDU_FLAGS_NO_SM; + sm_apdu->flags |= SC_APDU_FLAGS_NO_SM | SC_APDU_FLAGS_NO_RETRY_WL; rv = sc_transmit_apdu(card, sm_apdu); if (rv < 0) { card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu); diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 3be5ab856f..786a712588 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -312,6 +312,16 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, num); while (1) { switch (type) { + case SC_PKCS15_TYPE_PRKEY_EC: + desc = "RSA private key"; + _template = "private-key"; + structure = SC_CARDCTL_OBERTHUR_KEY_EC_CRT; + break; + case SC_PKCS15_TYPE_PUBKEY_EC: + desc = "RSA public key"; + _template = "public-key"; + structure = SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC; + break; case SC_PKCS15_TYPE_PRKEY_RSA: desc = "RSA private key"; _template = "private-key"; @@ -497,11 +507,14 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA && obj->type != SC_PKCS15_TYPE_PRKEY_EC) return SC_ERROR_NOT_SUPPORTED; + if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 0) + keybits = 256; //EC key length is 256 ... + /* allocate key object */ - r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &file); + r = cosm_new_file(profile, card, obj->type, idx, &file); //replace SC_PKCS15_TYPE_PRKEY_RSA with obj->type SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "create key: failed to allocate new key object"); file->size = keybits; @@ -525,11 +538,18 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, "index %"SC_FORMAT_LEN_SIZE_T"u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n", idx, keybits); if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, - "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", - keybits); - r = SC_ERROR_INVALID_ARGUMENTS; - goto err; + if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 256) + { + sc_log(card->ctx, "current Alg is EC,Only support 256 ..\n"); + } + else + { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", + keybits); + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } } path = key_info->path; @@ -549,12 +569,23 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed"); - if ((r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx, - &pukf)) < 0) { + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA ) + { + + r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_EC, idx, &pukf); + } + else + { + + r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx, &pukf); + } + + if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "generate key: create temporary pukf failed\n"); goto err; } + pukf->size = keybits; pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100 + pukf->path.value[pukf->path.len - 1]; From 6a4e120b447acd12072e3bc23b6030de34a4a111 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Oct 2017 09:38:19 +0200 Subject: [PATCH 0073/4321] md: added default text for role: user+sign --- etc/opensc.conf.in | 45 +++++++++++++++++++++++++------------ src/minidriver/minidriver.c | 5 ++++- src/ui/strings.c | 9 ++++++++ src/ui/strings.h | 1 + 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index c24d65f9ed..797cb4beeb 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -315,9 +315,13 @@ app default { # md_pinpad_dlg_main = "Main"; # # Content of the PIN pad dialog for role "user" - # Default: "Please verify your fingerprint or PIN for the digital signature PIN on the card." + # Default: "Please verify your fingerprint or PIN on the card." # md_pinpad_dlg_content_user = "Content User"; # + # Content of the PIN pad dialog for role "user+signature" + # Default: "Please verify your fingerprint or PIN for the digital signature PIN on the card." + # md_pinpad_dlg_content_user_sign = "Content User+Sign"; + # # Content of the PIN pad dialog for role "admin" # Default: "Please enter your PIN to unblock the user PIN on the PINPAD." # md_pinpad_dlg_content_admin = "Content Admin"; @@ -498,7 +502,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -523,7 +528,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -547,7 +553,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -571,7 +578,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -595,7 +603,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -619,7 +628,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -643,7 +653,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -667,7 +678,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -691,7 +703,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -715,7 +728,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -740,7 +754,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -765,7 +780,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; @@ -790,7 +806,8 @@ app default { md_supports_container_key_gen = true; md_guid_as_label = true; md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 7058e23cc1..7f952888ce 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2998,8 +2998,11 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, MD_PINPAD_DLG_CONTENT_ADMIN)); break; + case MD_ROLE_USER_SIGN: + tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_CONTENT_USER_SIGN)); + break; case ROLE_USER: - /* fall through */ default: tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, MD_PINPAD_DLG_CONTENT_USER)); diff --git a/src/ui/strings.c b/src/ui/strings.c index 383eb7ff03..e7d4ffbd19 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -106,6 +106,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CONTENT_USER: option = "md_pinpad_dlg_content_user"; break; + case MD_PINPAD_DLG_CONTENT_USER_SIGN: + option = "md_pinpad_dlg_content_user_sign"; + break; case MD_PINPAD_DLG_CONTENT_ADMIN: option = "md_pinpad_dlg_content_admin"; break; @@ -179,6 +182,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, str = "OpenSC Smartcard-Anbieter"; break; case MD_PINPAD_DLG_CONTENT_USER: + str = "Bitte geben Sie Ihre PIN auf dem PIN-Pad ein."; + break; + case MD_PINPAD_DLG_CONTENT_USER_SIGN: str = "Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PIN-Pad ein."; break; case MD_PINPAD_DLG_CONTENT_ADMIN: @@ -246,6 +252,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, str = "OpenSC Smart Card Provider"; break; case MD_PINPAD_DLG_CONTENT_USER: + str = "Please enter your PIN on the PIN pad."; + break; + case MD_PINPAD_DLG_CONTENT_USER_SIGN: str = "Please enter your digital signature PIN on the PIN pad."; break; case MD_PINPAD_DLG_CONTENT_ADMIN: diff --git a/src/ui/strings.h b/src/ui/strings.h index 6369d8bcb9..0cc81cf69b 100644 --- a/src/ui/strings.h +++ b/src/ui/strings.h @@ -47,6 +47,7 @@ enum ui_str { NOTIFY_PIN_GOOD_TEXT, NOTIFY_PIN_BAD, NOTIFY_PIN_BAD_TEXT, + MD_PINPAD_DLG_CONTENT_USER_SIGN, }; const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, From e4c589639d34a41f8e7a3daccd672106d629cc08 Mon Sep 17 00:00:00 2001 From: Mouse Date: Thu, 19 Oct 2017 16:12:47 -0400 Subject: [PATCH 0074/4321] Add support in pkcs11-tool and pkcs11-spy for RSA-OAEP (#1169) * Add RSA-OAEP documentation * Add definitions and structures needed for RSA-OAEP * Add ability to display RSA-OAEP parameters to SPY Closes https://github.com/OpenSC/OpenSC/issues/1170 --- doc/tools/pkcs11-tool.1.xml | 23 ++++++++-- src/pkcs11/pkcs11-spy.c | 23 ++++++++++ src/pkcs11/pkcs11.h | 16 +++++-- src/tools/pkcs11-tool.c | 87 +++++++++++++++++++++++++++++++++++-- 4 files changed, 138 insertions(+), 11 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 037c955146..7c17972e7a 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -75,8 +75,22 @@ mechanism - Specify hash algorithm used with - RSA-PKCS-PSS signature. Default is SHA-1. + + + Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + also allow "SHA224". Default is "SHA-1". + + + Note that the input to RSA-PKCS-PSS has to be of the size equal to + the specified hash algorithm. E.g., for SHA256 the signature input must + be exactly 32 bytes long (for mechanisms SHA256-RSA-PKCS-PSS there is no + such restriction). For RSA-OAEP, the plaintext input size mLen must be + at most keyLen - 2 - 2*hashLen. For example, for RSA 3072-bit key and + SHA384, the longest plaintext to encrypt with RSA-OAEP is (with all + sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes. + + @@ -226,9 +240,10 @@ Use the specified Message Generation Function (MGF) function - for RSA-PSS signatures. Supported arguments are MGF1-SHA1 + for RSA-PKCS-PSS signatures or RSA-OAEP decryptions. Supported arguments are MGF1-SHA1 to MGF1-SHA512 if supported by the driver. - The default is based on the hash selection. + The default is based on the hash selection. + diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 8011f0471c..275094abb9 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -844,6 +844,26 @@ C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_DecryptInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS_OAEP: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_OAEP_PARAMS *param = + (CK_RSA_PKCS_OAEP_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "pMechanism->pParameter->source=%lu\n", param->source); + spy_dump_string_out("pSourceData[ulSourceDalaLen]", + param->pSourceData, param->ulSourceDataLen); + } else { + fprintf(spy_output, "Parameters block for %s is empty...\n", + lookup_enum(MEC_T, pMechanism->mechanism)); + } + break; + default: + break; + } spy_dump_ulong_in("hKey", hKey); rv = po->C_DecryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -984,6 +1004,9 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA lookup_enum(MGF_T, param->mgf)); fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", param->sLen); + } else { + fprintf(spy_output, "Parameters block for %s is empty...\n", + lookup_enum(MEC_T, pMechanism->mechanism)); } break; } diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index d24597b26f..2c5c4f2e71 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -764,10 +764,20 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned char * pPublicData; } CK_ECDH1_DERIVE_PARAMS; +typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; + +typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + void *pSourceData; + unsigned long ulSourceDataLen; +} CK_RSA_PKCS_OAEP_PARAMS; + typedef struct CK_RSA_PKCS_PSS_PARAMS { - ck_mechanism_type_t hashAlg; - unsigned long mgf; - unsigned long sLen; + ck_mechanism_type_t hashAlg; + unsigned long mgf; + unsigned long sLen; } CK_RSA_PKCS_PSS_PARAMS; #define CKG_MGF1_SHA1 (0x00000001UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index dfd6913d41..68b41b46f5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -235,8 +235,8 @@ static const char *option_help[] = { "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", "Specify mechanism (use -M for a list of supported mechanisms)", - "Specify hash algorithm used with RSA-PKCS-PSS signature", - "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)", + "Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption", + "Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)", "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", "Log into the token first", @@ -1692,6 +1692,9 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, pss_params.hashAlg = opt_hash_alg; switch (opt_hash_alg) { + case CKM_SHA224: + pss_params.mgf = CKG_MGF1_SHA224; + break; case CKM_SHA256: pss_params.mgf = CKG_MGF1_SHA256; break; @@ -1715,6 +1718,11 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, pss_params.mgf = CKG_MGF1_SHA1; break; + case CKM_SHA224_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA224; + pss_params.mgf = CKG_MGF1_SHA224; + break; + case CKM_SHA256_RSA_PKCS_PSS: pss_params.hashAlg = CKM_SHA256; pss_params.mgf = CKG_MGF1_SHA256; @@ -1762,7 +1770,8 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); - fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", + + fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt_len=%lu B\n", p11_mechanism_to_name(pss_params.hashAlg), p11_mgf_to_name(pss_params.mgf), pss_params.sLen); @@ -1777,6 +1786,10 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ if (r < 0) util_fatal("Cannot read from %s: %m", opt_input); + if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) + util_fatal("For %s mechanism, message size (got %d bytes) must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), r, hashlen); + rv = CKR_CANCEL; if (r < (int) sizeof(in_buffer)) { rv = p11->C_SignInit(session, &mech, key); @@ -1819,7 +1832,7 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ util_fatal("failed to open %s: %m", opt_output); } - if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512) { + if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { unsigned char *seq; size_t seqlen; @@ -1849,6 +1862,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1024], out_buffer[1024]; CK_MECHANISM mech; CK_RV rv; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_ULONG in_len, out_len; int fd, r; @@ -1859,6 +1873,11 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; + oaep_params.hashAlg = 0; + + if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) + util_fatal("The hash-algorithm is applicable only to " + "RSA-PKCS-OAEP mechanism"); if (opt_input == NULL) fd = 0; @@ -1870,6 +1889,62 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Cannot read from %s: %m", opt_input); in_len = r; + /* set "default" MGF and hash algorithms. We can overwrite MGF later */ + switch (opt_mechanism) { + case CKM_RSA_PKCS_OAEP: + oaep_params.hashAlg = opt_hash_alg; + switch (opt_hash_alg) { + case CKM_SHA224: + oaep_params.mgf = CKG_MGF1_SHA224; + break; + case CKM_SHA256: + oaep_params.mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + oaep_params.mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + oaep_params.mgf = CKG_MGF1_SHA512; + break; + default: + oaep_params.hashAlg = CKM_SHA_1; + /* fallthrough to SHA-1 default */ + case CKM_SHA_1: + oaep_params.mgf = CKG_MGF1_SHA1; + break; + } + break; + case CKM_RSA_PKCS: + mech.pParameter = NULL; + mech.ulParameterLen = 0; + break; + default: + util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); + } + + + /* If an RSA-OAEP mechanism, it needs parameters */ + if (oaep_params.hashAlg) { + if (opt_mgf != 0) + oaep_params.mgf = opt_mgf; + + /* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */ + oaep_params.source = 0UL; /* empty encoding parameter (label) */ + oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ + oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ + + mech.pParameter = &oaep_params; + mech.ulParameterLen = sizeof(oaep_params); + + fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", + p11_mechanism_to_name(oaep_params.hashAlg), + p11_mgf_to_name(oaep_params.mgf), + oaep_params.source, + oaep_params.pSourceData, + oaep_params.ulSourceDataLen); + + } + rv = p11->C_DecryptInit(session, &mech, key); if (rv != CKR_OK) p11_fatal("C_DecryptInit", rv); @@ -5781,6 +5856,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS", NULL }, { CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5" }, { CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1" }, + { CKM_SHA224_RSA_PKCS, "SHA224-RSA-PKCS", "rsa-sha224" }, { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256" }, { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384" }, { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512" }, @@ -5792,6 +5868,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL }, { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL }, { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1" }, + { CKM_SHA224_RSA_PKCS_PSS,"SHA224-RSA-PKCS-PSS", "rsa-pss-sha224" }, { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256" }, { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384" }, { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512" }, @@ -5840,6 +5917,8 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA_1, "SHA-1", NULL }, { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL }, { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL }, + { CKM_SHA224, "SHA224", NULL }, + { CKM_SHA224_HMAC, "SHA224-HMAC", NULL }, { CKM_SHA256, "SHA256", NULL }, { CKM_SHA256_HMAC, "SHA256-HMAC", NULL }, { CKM_SHA384, "SHA384", NULL }, From 5918e005d7c4cc35ec520c484e2380eb05af3b1b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 12 Sep 2017 11:34:55 +0200 Subject: [PATCH 0075/4321] starcos: added serial number for 3.4 --- src/libopensc/card-starcos.c | 65 ++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 5a46f164c3..b2d93bbce4 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1336,7 +1336,7 @@ static int starcos_set_security_env(sc_card_t *card, * algorithm / cipher from PKCS#1 padding prefix */ *p++ = 0x84; *p++ = 0x01; - *p++ = 0x84; + *p++ = *env->key_ref; /* algorithm / cipher selector? */ *p++ = 0x89; @@ -1631,6 +1631,9 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) { int r; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + const u8 *p; + unsigned int ef_gdo_tag, cla; + size_t ef_gdo_tag_len; sc_apdu_t apdu; if (!serial) @@ -1640,24 +1643,52 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) memcpy(serial, &card->serialnr, sizeof(*serial)); return SC_SUCCESS; } - CHECK_NOT_SUPPORTED_V3_4(card); - /* get serial number via GET CARD DATA */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00); - apdu.cla |= 0x80; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - apdu.lc = 0; - apdu.datalen = 0; - r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) - return SC_ERROR_INTERNAL; - /* cache serial number */ - memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); + + switch (card->type) { + case SC_CARD_TYPE_STARCOS_V3_4: + r = sc_select_file(card, sc_get_mf_path(), NULL); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "SELECT MF failed"); + /* get serial number via EF.GDO */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x82, 0x00); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + apdu.lc = 0; + apdu.datalen = 0; + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + p = apdu.resp; + r = sc_asn1_read_tag(&p, apdu.resplen, &cla, &ef_gdo_tag, &ef_gdo_tag_len); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to parse EF.GDO"); + if ((ef_gdo_tag|cla) != 0x5A) + return SC_ERROR_INTERNAL; + /* cache serial number */ + memcpy(card->serialnr.value, p, MIN(ef_gdo_tag_len, SC_MAX_SERIALNR)); + card->serialnr.len = MIN(ef_gdo_tag_len, SC_MAX_SERIALNR); + break; + + default: + /* get serial number via GET CARD DATA */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00); + apdu.cla |= 0x80; + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + apdu.lc = 0; + apdu.datalen = 0; + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + return SC_ERROR_INTERNAL; + /* cache serial number */ + memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); + card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); + break; + } + /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); + return SC_SUCCESS; } From 293d02ea4ba834a5b7196952ebe2d4b546dd54de Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 13 Sep 2017 10:26:23 +0200 Subject: [PATCH 0076/4321] removed unused test test is performed by sc_asn1_read_tag --- src/libopensc/asn1.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index d3d1b87eb1..93d80b7a4f 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -351,10 +351,6 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, /* read a tag */ if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS) return NULL; - if (left < (size_t)(p - buf)) { - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid TLV object\n"); - return NULL; - } left -= (p - buf); /* we need to shift the class byte to the leftmost * byte of the tag */ @@ -371,10 +367,6 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, return p; } /* otherwise continue reading tags */ - if (left < taglen) { - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid TLV object\n"); - return NULL; - } left -= taglen; p += taglen; } From 0502a839c654555220964e9f4d58ca508471472e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 13 Sep 2017 12:21:59 +0200 Subject: [PATCH 0077/4321] unified reading of EF.GDO --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-starcos.c | 29 ++----- src/libopensc/card-tcos.c | 29 +++---- src/libopensc/ef-gdo.c | 132 ++++++++++++++++++++++++++++++ src/libopensc/opensc.h | 3 + src/libopensc/pkcs15-infocamere.c | 76 +++++------------ src/libopensc/pkcs15-tccardos.c | 10 +-- 8 files changed, 183 insertions(+), 102 deletions(-) create mode 100644 src/libopensc/ef-gdo.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index a3bea3c6f2..0f92feea21 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -22,8 +22,8 @@ AM_OBJCFLAGS = $(AM_CFLAGS) libopensc_la_SOURCES_BASE = \ sc.c ctx.c log.c errors.c \ - asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c padding.c apdu.c \ - simpletlv.c \ + asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c \ + ef-gdo.c padding.c apdu.c simpletlv.c \ \ pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 5808f38e5e..bfee45f8aa 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -4,7 +4,7 @@ TARGET = opensc.dll opensc_a.lib OBJECTS = \ sc.obj ctx.obj log.obj errors.obj \ asn1.obj base64.obj sec.obj card.obj iso7816.obj dir.obj ef-atr.obj \ - padding.obj apdu.obj simpletlv.obj \ + ef-gdo.obj padding.obj apdu.obj simpletlv.obj \ \ pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \ pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-skey.obj \ diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index b2d93bbce4..ac22a926bf 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1631,13 +1631,13 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) { int r; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - const u8 *p; - unsigned int ef_gdo_tag, cla; - size_t ef_gdo_tag_len; + const unsigned char *iccsn; + size_t iccsn_len; sc_apdu_t apdu; if (!serial) return SC_ERROR_INVALID_ARGUMENTS; + /* see if we have cached serial number */ if (card->serialnr.len) { memcpy(serial, &card->serialnr, sizeof(*serial)); @@ -1646,25 +1646,12 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) switch (card->type) { case SC_CARD_TYPE_STARCOS_V3_4: - r = sc_select_file(card, sc_get_mf_path(), NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "SELECT MF failed"); - /* get serial number via EF.GDO */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x82, 0x00); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - apdu.lc = 0; - apdu.datalen = 0; - r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - p = apdu.resp; - r = sc_asn1_read_tag(&p, apdu.resplen, &cla, &ef_gdo_tag, &ef_gdo_tag_len); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to parse EF.GDO"); - if ((ef_gdo_tag|cla) != 0x5A) - return SC_ERROR_INTERNAL; + r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); + if (r < 0) + return r; /* cache serial number */ - memcpy(card->serialnr.value, p, MIN(ef_gdo_tag_len, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(ef_gdo_tag_len, SC_MAX_SERIALNR); + memcpy(card->serialnr.value, iccsn, MIN(iccsn_len, SC_MAX_SERIALNR)); + card->serialnr.len = MIN(iccsn_len, SC_MAX_SERIALNR); break; default: diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index c804878438..12b7129054 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -705,33 +705,28 @@ static int tcos_setperm(sc_card_t *card, int enable_nullpin) static int tcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) { - int r; - u8 buf[64]; - size_t len; - sc_path_t tpath; - sc_file_t *tfile = NULL; + int r; + const unsigned char *iccsn; + size_t iccsn_len; - if (!serial) return SC_ERROR_INVALID_ARGUMENTS; + if (!serial) + return SC_ERROR_INVALID_ARGUMENTS; /* see if we have cached serial number */ if (card->serialnr.len) { memcpy(serial, &card->serialnr, sizeof(*serial)); return SC_SUCCESS; } - sc_format_path("3F002F02", &tpath); - r = sc_select_file(card, &tpath, &tfile); - if (r < 0) return r; - len = tfile->size; - sc_file_free(tfile); - if (len > sizeof(buf) || len < 12) return SC_ERROR_INTERNAL; + r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); + if (r < 0) + return r; - r = sc_read_binary(card, 0, buf, len, 0); - if (r < 0) return r; - if (buf[0] != 0x5a || buf[1] > len - 2) return SC_ERROR_INTERNAL; + /* cache serial number */ + memcpy(card->serialnr.value, iccsn, MIN(iccsn_len, SC_MAX_SERIALNR)); + card->serialnr.len = MIN(iccsn_len, SC_MAX_SERIALNR); - card->serialnr.len = buf[1]; - memcpy(card->serialnr.value, buf+2, buf[1]); + /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); return SC_SUCCESS; diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c new file mode 100644 index 0000000000..4d7a86bab8 --- /dev/null +++ b/src/libopensc/ef-gdo.c @@ -0,0 +1,132 @@ +/* + * ef-atr.c: Stuff for handling EF(GDO) + * + * Copyright (C) 2017 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "internal.h" +#include "asn1.h" + +static int +sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, + const unsigned char **iccsn, size_t *iccsn_len, + const unsigned char **chn, size_t *chn_len) +{ + int r = SC_SUCCESS; + const unsigned char *p = gdo; + size_t left = gdo_len; + + if (iccsn) + *iccsn = NULL; + if (iccsn_len) + *iccsn_len = 0; + if (chn) + *chn = NULL; + if (chn_len) + *chn_len = 0; + + while (left >= 2) { + unsigned int cla, tag; + size_t tag_len; + + r = sc_asn1_read_tag(&p, left, &cla, &tag, &tag_len); + if (r != SC_SUCCESS) { + if (r == SC_ERROR_ASN1_END_OF_CONTENTS) { + /* not enough data */ + r = SC_SUCCESS; + } + break; + } + if (tag == SC_ASN1_TAG_EOC) { + /* done parsing */ + break; + } + + if (cla == SC_ASN1_TAG_APPLICATION) { + switch (tag) { + case 0x1A: + if (iccsn) + *iccsn = p; + if (iccsn_len) + *iccsn_len = tag_len; + break; + case 0x1F20: + if (chn) + *chn = p; + if (chn_len) + *chn_len = tag_len; + break; + } + } + + p += tag_len; + left -= (p - gdo); + } + + return r; +} + + + +int +sc_parse_ef_gdo(struct sc_card *card, + const unsigned char **iccsn, size_t *iccsn_len, + const unsigned char **chn, size_t *chn_len) +{ + struct sc_context *ctx; + struct sc_path path; + struct sc_file *file; + unsigned char *gdo = NULL; + size_t gdo_len = 0; + int r; + + if (!card) + return SC_ERROR_INVALID_ARGUMENTS; + + ctx = card->ctx; + + LOG_FUNC_CALLED(ctx); + + sc_format_path("3F002F02", &path); + r = sc_select_file(card, &path, &file); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot select EF(GDO) file"); + + if (file->size) { + gdo_len = file->size; + } else { + gdo_len = 64; + } + gdo = malloc(gdo_len); + if (!gdo) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + + r = sc_read_binary(card, 0, gdo, gdo_len, 0); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot read EF(GDO) file"); + + r = sc_parse_ef_gdo_content(gdo, r, iccsn, iccsn_len, chn, chn_len); + +err: + sc_file_free(file); + free(gdo); + + LOG_FUNC_RETURN(ctx, r); +} diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 209e4aba95..5c2ec3cf86 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1317,6 +1317,9 @@ struct sc_app_info *sc_find_app(struct sc_card *card, struct sc_aid *aid); void sc_free_apps(struct sc_card *card); int sc_parse_ef_atr(struct sc_card *card); void sc_free_ef_atr(struct sc_card *card); +int sc_parse_ef_gdo(struct sc_card *card, + const unsigned char **iccsn, size_t *iccsn_len, + const unsigned char **chn, size_t *chn_len); int sc_update_dir(struct sc_card *card, sc_app_info_t *app); void sc_print_cache(struct sc_card *card); diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index 14c188794a..63ffee134d 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -166,10 +166,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) sc_card_t *card = p15card->card; sc_path_t path; - sc_file_t *file; sc_pkcs15_id_t id, auth_id; - unsigned char buffer[256]; - unsigned char ef_gdo[256]; char serial[256]; unsigned char certlen[2]; int authority, change_sign = 0; @@ -235,64 +232,31 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING; - int r, len_iccsn, len_chn; - - sc_format_path("3F002F02", &path); - - r = sc_select_file(card, &path, &file); - - if (r != SC_SUCCESS || file->size > 255) { - /* Not EF.GDO */ - sc_file_free(file); - return SC_ERROR_WRONG_CARD; - } - - sc_read_binary(card, 0, ef_gdo, file->size, 0); - - if (ef_gdo[0] != 0x5A || file->size < 3) { - /* Not EF.GDO */ - sc_file_free(file); - return SC_ERROR_WRONG_CARD; - } - - len_iccsn = ef_gdo[1]; - - memcpy(buffer, ef_gdo + 2, len_iccsn); + int r; - sc_bin_to_hex(buffer, len_iccsn, serial, sizeof(serial), 0); + const unsigned char *iccsn, *chn; + size_t iccsn_len, chn_len; - if (file->size < (size_t) (len_iccsn + 5)) { - /* Not CHN */ - sc_file_free(file); - return SC_ERROR_WRONG_CARD; - } - sc_file_free(file); + r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, &chn, &chn_len); + if (r < 0) + return r; - if (! - (ef_gdo[len_iccsn + 2] == 0x5F - && ef_gdo[len_iccsn + 3] == 0x20)) { - /* Not CHN */ + if (!iccsn_len || chn_len < 2 || chn_len > 8) { return SC_ERROR_WRONG_CARD; } - len_chn = ef_gdo[len_iccsn + 4]; - - if (len_chn < 2 || len_chn > 8) { - /* Length CHN incorrect */ - return SC_ERROR_WRONG_CARD; - } + sc_bin_to_hex(iccsn, iccsn_len, serial, sizeof(serial), 0); if (! - (ef_gdo[len_iccsn + 5] == 0x12 - && (ef_gdo[len_iccsn + 6] == 0x02 - || ef_gdo[len_iccsn + 6] == 0x03))) { + (chn[0] == 0x12 + && (chn[1] == 0x02 || chn[1] == 0x03))) { /* Not Infocamere Card */ return SC_ERROR_WRONG_CARD; } set_string(&p15card->tokeninfo->serial_number, serial); - if (ef_gdo[len_iccsn + 6] == 0x02) + if (chn[1] == 0x02) set_string(&p15card->tokeninfo->label, "Infocamere 1202 Card"); else { set_string(&p15card->tokeninfo->label, "Infocamere 1203 Card"); @@ -305,7 +269,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) /* Get the authentication certificate length */ - sc_format_path(infocamere_auth_certpath[ef_gdo[len_iccsn+6]-2], &path); + sc_format_path(infocamere_auth_certpath[chn[1]-2], &path); r = sc_select_file(card, &path, NULL); @@ -336,11 +300,11 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) if (!change_sign) { /* add authentication PIN */ - sc_format_path(infocamere_auth_path[ef_gdo[len_iccsn+6]-2], &path); + sc_format_path(infocamere_auth_path[chn[1]-2], &path); sc_pkcs15_format_id("01", &id); sc_pkcs15emu_add_pin(p15card, &id, - authPIN, &path, infocamere_idpin_auth_obj[ef_gdo[len_iccsn+6]-2], + authPIN, &path, infocamere_idpin_auth_obj[chn[1]-2], SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); @@ -354,7 +318,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) authPRKEY, SC_PKCS15_TYPE_PRKEY_RSA, 1024, authprkey_usage, - &path, infocamere_idprkey_auth_obj[ef_gdo[len_iccsn+6]-2], + &path, infocamere_idprkey_auth_obj[chn[1]-2], &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); } @@ -362,7 +326,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) /* Get the non-repudiation certificate length */ - sc_format_path(infocamere_cert_path[ef_gdo[len_iccsn+6]-2], &path); + sc_format_path(infocamere_cert_path[chn[1]-2], &path); if (sc_select_file(card, &path, NULL) < 0) { return SC_ERROR_INTERNAL; @@ -392,7 +356,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) authority = 1; - sc_format_path(infocamere_cacert_path[ef_gdo[len_iccsn+6]-2], &path); + sc_format_path(infocamere_cacert_path[chn[1]-2], &path); r = sc_select_file(card, &path, NULL); @@ -425,11 +389,11 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) /* add non repudiation PIN */ - sc_format_path(infocamere_nrepud_path[ef_gdo[len_iccsn+6]-2], &path); + sc_format_path(infocamere_nrepud_path[chn[1]-2], &path); sc_pkcs15_format_id("02", &id); sc_pkcs15emu_add_pin(p15card, &id, - nonrepPIN, &path, infocamere_idpin_nrepud_obj[ef_gdo[len_iccsn+6]-2], + nonrepPIN, &path, infocamere_idpin_nrepud_obj[chn[1]-2], SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); @@ -442,7 +406,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) sc_pkcs15emu_add_prkey(p15card, &id, nonrepPRKEY, SC_PKCS15_TYPE_PRKEY_RSA, 1024, prkey_usage, - &path, infocamere_idprkey_nrepud_obj[ef_gdo[len_iccsn+6]-2], + &path, infocamere_idprkey_nrepud_obj[chn[1]-2], &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index b1779b5ec6..d8986a9dc5 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -304,9 +304,9 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) int r; struct sc_path path; struct sc_file *file = NULL; - u8 gdo[MAX_INFO1_SIZE]; char hex_buf[256]; - size_t gdo_len = MAX_INFO1_SIZE; + const unsigned char *iccsn; + size_t iccsn_len; struct sc_card *card = p15card->card; /* check if we have the correct card OS */ @@ -329,10 +329,10 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) if (p15card->tokeninfo->manufacturer_id == NULL) return SC_ERROR_OUT_OF_MEMORY; /* set the serial number */ - r = read_file(p15card->card, "3F002F02", gdo, &gdo_len); - if (r != SC_SUCCESS) + r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); + if (r != SC_SUCCESS || iccsn_len < 5+8) return SC_ERROR_INTERNAL; - sc_bin_to_hex(gdo + 7, 8, hex_buf, sizeof(hex_buf), 0); + sc_bin_to_hex(iccsn + 5, 8, hex_buf, sizeof(hex_buf), 0); p15card->tokeninfo->serial_number = strdup(hex_buf); if (p15card->tokeninfo->serial_number == NULL) return SC_ERROR_OUT_OF_MEMORY; From 60e8db4c22dba1c0a629cbc78759e5cc3406a758 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 14 Sep 2017 19:40:40 +0200 Subject: [PATCH 0078/4321] Added tool for German eGK Fixes missing opensc-notify.1 --- src/tools/Makefile.am | 38 +- src/tools/Makefile.mak | 18 +- src/tools/egk-tool-cmdline.c | 1306 ++++++++++++++++++++++++++++++++++ src/tools/egk-tool-cmdline.h | 193 +++++ src/tools/egk-tool.1 | 39 + src/tools/egk-tool.c | 317 +++++++++ src/tools/egk-tool.ggo.in | 31 + src/tools/opensc-notify.1 | 45 ++ 8 files changed, 1980 insertions(+), 7 deletions(-) create mode 100644 src/tools/egk-tool-cmdline.c create mode 100644 src/tools/egk-tool-cmdline.h create mode 100644 src/tools/egk-tool.1 create mode 100644 src/tools/egk-tool.c create mode 100644 src/tools/egk-tool.ggo.in create mode 100644 src/tools/opensc-notify.1 diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 6de171d39b..98fb448826 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -1,5 +1,11 @@ include $(top_srcdir)/win32/ltrc.inc +if ENABLE_ZLIB +VDFORMAT=XML +else +VDFORMAT=GZIP +endif + do_subst = $(SED) \ -e 's,[@]CVCDIR[@],$(CVCDIR),g' \ -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ @@ -9,26 +15,28 @@ do_subst = $(SED) \ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ -e 's,[@]PACKAGE_VERSION[@],"$(PACKAGE_VERSION)",g' \ + -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' +EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool \ - cardos-tool eidenv openpgp-tool iasecc-tool + cardos-tool eidenv openpgp-tool iasecc-tool egk-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool endif if ENABLE_MAN -dist_man1_MANS = npa-tool.1 +dist_man1_MANS = npa-tool.1 opensc-notify.1 egk-tool.1 endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb @@ -126,6 +134,30 @@ opensc-notify.1: --source='$(PACKAGE_STRING)' \ $(builddir)/opensc-notify$(EXEEXT) +egk_tool_SOURCES = egk-tool.c $(EGK_TOOL_BUILT_SOURCES) +egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) +egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) +egk_tool_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option + +egk-tool.c: $(abs_builddir)/egk-tool.ggo $(EGK_TOOL_BUILT_SOURCES) + +# We only want *cmdline* to be generated when they have explicitly been removed. +$(EGK_TOOL_BUILT_SOURCES): + $(MAKE) $(abs_builddir)/egk-tool.ggo + $(GENGETOPT) --include-getopt --file-name=egk-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/egk-tool.ggo + +$(abs_builddir)/egk-tool.ggo: egk-tool.ggo.in + $(do_subst) < $(abs_srcdir)/egk-tool.ggo.in > $@ + +# We only want egk-tool.1 to be generated when it has explicitly been removed. +egk-tool.1: + $(MAKE) egk-tool$(EXEEXT) + $(HELP2MAN) \ + --output=$@ \ + --no-info \ + --source='$(PACKAGE_STRING)' \ + $(builddir)/egk-tool$(EXEEXT) + if WIN32 opensc_tool_SOURCES += versioninfo-tools.rc piv_tool_SOURCES += versioninfo-tools.rc diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index fdaae5365f..05b8e6130c 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -6,10 +6,10 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ - opensc-notify.exe \ + opensc-notify.exe egk-tool.exe \ $(PROGRAMS_OPENSSL) -OBJECTS = util.obj npa-tool-cmdline.obj fread_to_eof.obj versioninfo-tools.res +OBJECTS = util.obj versioninfo-tools.res LIBS = $(TOPDIR)\src\common\common.lib \ $(TOPDIR)\src\scconf\scconf.lib \ @@ -24,10 +24,20 @@ $(TARGETS): $(OBJECTS) $(LIBS) opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + +npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + +egk-tool.exe: egk-tool-cmdline.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 diff --git a/src/tools/egk-tool-cmdline.c b/src/tools/egk-tool-cmdline.c new file mode 100644 index 0000000000..9fc4e4bcf5 --- /dev/null +++ b/src/tools/egk-tool-cmdline.c @@ -0,0 +1,1306 @@ +/* + File autogenerated by gengetopt version 2.22.6 + generated with the following command: + /usr/local/bin/gengetopt --include-getopt --file-name=egk-tool-cmdline --output-dir=. + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + + +#include "egk-tool-cmdline.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: egk-tool [OPTIONS]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -r, --reader=INT Number of the PC/SC reader to use (-1 for autodetect)\n (default=`-1')", + " -v, --verbose Use (several times) to be more verbose", + "\nHealth Care Application (HCA):", + " --pd Show 'Persönliche Versicherungsdaten' (XML) (default=off)", + " --vd Show 'Allgemeine Versicherungsdaten' (XML) (default=off)", + " --gvd Show 'Geschützte Versicherungsdaten' (XML) (default=off)", + " --vsd-status Show 'Versichertenstammdaten-Status' (default=off)", + "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + 0 +}; + +typedef enum {ARG_NO + , ARG_FLAG + , ARG_INT +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->reader_given = 0 ; + args_info->verbose_given = 0 ; + args_info->pd_given = 0 ; + args_info->vd_given = 0 ; + args_info->gvd_given = 0 ; + args_info->vsd_status_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->reader_arg = -1; + args_info->reader_orig = NULL; + args_info->pd_flag = 0; + args_info->vd_flag = 0; + args_info->gvd_flag = 0; + args_info->vsd_status_flag = 0; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->reader_help = gengetopt_args_info_help[2] ; + args_info->verbose_help = gengetopt_args_info_help[3] ; + args_info->verbose_min = 0; + args_info->verbose_max = 0; + args_info->pd_help = gengetopt_args_info_help[5] ; + args_info->vd_help = gengetopt_args_info_help[6] ; + args_info->gvd_help = gengetopt_args_info_help[7] ; + args_info->vsd_status_help = gengetopt_args_info_help[8] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + free_string_field (&(args_info->reader_orig)); + + + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + +static void +write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[]) +{ + int i; + + for (i = 0; i < len; ++i) + write_into_file(outfile, opt, (arg ? arg[i] : 0), values); +} + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->reader_given) + write_into_file(outfile, "reader", args_info->reader_orig, 0); + write_multiple_into_file(outfile, args_info->verbose_given, "verbose", 0, 0); + if (args_info->pd_given) + write_into_file(outfile, "pd", 0, 0 ); + if (args_info->vd_given) + write_into_file(outfile, "vd", 0, 0 ); + if (args_info->gvd_given) + write_into_file(outfile, "gvd", 0, 0 ); + if (args_info->vsd_status_given) + write_into_file(outfile, "vsd-status", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +static int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc); + +int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc) +{ + int error_occurred = 0; + + if (option_given && (min > 0 || max > 0)) + { + if (min > 0 && max > 0) + { + if (min == max) + { + /* specific occurrences */ + if (option_given != (unsigned int) min) + { + fprintf (stderr, "%s: %s option occurrences must be %d\n", + prog_name, option_desc, min); + error_occurred = 1; + } + } + else if (option_given < (unsigned int) min + || option_given > (unsigned int) max) + { + /* range occurrences */ + fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n", + prog_name, option_desc, min, max); + error_occurred = 1; + } + } + else if (min > 0) + { + /* at least check */ + if (option_given < min) + { + fprintf (stderr, "%s: %s option occurrences must be at least %d\n", + prog_name, option_desc, min); + error_occurred = 1; + } + } + else if (max > 0) + { + /* at most check */ + if (option_given > max) + { + fprintf (stderr, "%s: %s option occurrences must be at most %d\n", + prog_name, option_desc, max); + error_occurred = 1; + } + } + } + + return error_occurred; +} +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ + int error_occurred = 0; + FIX_UNUSED (additional_error); + + /* checks for required options */ + if (check_multiple_option_occurrences(prog_name, args_info->verbose_given, args_info->verbose_min, args_info->verbose_max, "'--verbose' ('-v')")) + error_occurred = 1; + + + /* checks for dependences among options */ + + return error_occurred; +} + +/* + * Extracted from the glibc source tree, version 2.3.6 + * + * Licensed under the GPL as per the whole glibc source tree. + * + * This file was modified so that getopt_long can be called + * many times without risking previous memory to be spoiled. + * + * Modified by Andre Noll and Lorenzo Bettini for use in + * GNU gengetopt generated files. + * + */ + +/* + * we must include anything we need since this file is not thought to be + * inserted in a file already using getopt.h + * + * Lorenzo + */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. +*/ +/* + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `custom_optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +/* Names for the values of the `has_arg' field of `struct option'. */ +#ifndef no_argument +#define no_argument 0 +#endif + +#ifndef required_argument +#define required_argument 1 +#endif + +#ifndef optional_argument +#define optional_argument 2 +#endif + +struct custom_getopt_data { + /* + * These have exactly the same meaning as the corresponding global variables, + * except that they are used for the reentrant versions of getopt. + */ + int custom_optind; + int custom_opterr; + int custom_optopt; + char *custom_optarg; + + /* True if the internal members have been initialized. */ + int initialized; + + /* + * The next char to be scanned in the option-element in which the last option + * character we returned was found. This allows us to pick up the scan where + * we left off. If this is zero, or a null string, it means resume the scan by + * advancing to the next ARGV-element. + */ + char *nextchar; + + /* + * Describe the part of ARGV that contains non-options that have been skipped. + * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is + * the index after the last of them. + */ + int first_nonopt; + int last_nonopt; +}; + +/* + * the variables optarg, optind, opterr and optopt are renamed with + * the custom_ prefix so that they don't interfere with getopt ones. + * + * Moreover they're static so they are visible only from within the + * file where this very file will be included. + */ + +/* + * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an + * option that takes an argument, the argument value is returned here. + */ +static char *custom_optarg; + +/* + * Index in ARGV of the next element to be scanned. This is used for + * communication to and from the caller and for communication between + * successive calls to `custom_getopt'. + * + * On entry to `custom_getopt', 1 means this is the first call; initialize. + * + * When `custom_getopt' returns -1, this is the index of the first of the non-option + * elements that the caller should itself scan. + * + * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV + * has been scanned so far. + * + * 1003.2 says this must be 1 before any call. + */ +static int custom_optind = 1; + +/* + * Callers store zero here to inhibit the error message for unrecognized + * options. + */ +static int custom_opterr = 1; + +/* + * Set to an option character which was unrecognized. This must be initialized + * on some systems to avoid linking in the system's own getopt implementation. + */ +static int custom_optopt = '?'; + +/* + * Exchange two adjacent subsequences of ARGV. One subsequence is elements + * [first_nonopt,last_nonopt) which contains all the non-options that have been + * skipped so far. The other is elements [last_nonopt,custom_optind), which contains + * all the options processed since those non-options were skipped. + * `first_nonopt' and `last_nonopt' are relocated so that they describe the new + * indices of the non-options in ARGV after they are moved. + */ +static void exchange(char **argv, struct custom_getopt_data *d) +{ + int bottom = d->first_nonopt; + int middle = d->last_nonopt; + int top = d->custom_optind; + char *tem; + + /* + * Exchange the shorter segment with the far end of the longer segment. + * That puts the shorter segment into the right place. It leaves the + * longer segment in the right place overall, but it consists of two + * parts that need to be swapped next. + */ + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = + argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + /* Update records for the slots the non-options now occupy. */ + d->first_nonopt += (d->custom_optind - d->last_nonopt); + d->last_nonopt = d->custom_optind; +} + +/* Initialize the internal data when the first call is made. */ +static void custom_getopt_initialize(struct custom_getopt_data *d) +{ + /* + * Start processing options with ARGV-element 1 (since ARGV-element 0 + * is the program name); the sequence of previously skipped non-option + * ARGV-elements is empty. + */ + d->first_nonopt = d->last_nonopt = d->custom_optind; + d->nextchar = NULL; + d->initialized = 1; +} + +#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') + +/* return: zero: continue, nonzero: return given value to user */ +static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, + struct custom_getopt_data *d) +{ + /* + * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been + * moved back by the user (who may also have changed the arguments). + */ + if (d->last_nonopt > d->custom_optind) + d->last_nonopt = d->custom_optind; + if (d->first_nonopt > d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * If we have just processed some options following some + * non-options, exchange them so that the options come first. + */ + if (d->first_nonopt != d->last_nonopt && + d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->last_nonopt != d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * Skip any additional non-options and extend the range of + * non-options previously skipped. + */ + while (d->custom_optind < argc && NONOPTION_P) + d->custom_optind++; + d->last_nonopt = d->custom_optind; + /* + * The special ARGV-element `--' means premature end of options. Skip + * it like a null option, then exchange with previous non-options as if + * it were an option, then skip everything else like a non-option. + */ + if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { + d->custom_optind++; + if (d->first_nonopt != d->last_nonopt + && d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->first_nonopt == d->last_nonopt) + d->first_nonopt = d->custom_optind; + d->last_nonopt = argc; + d->custom_optind = argc; + } + /* + * If we have done all the ARGV-elements, stop the scan and back over + * any non-options that we skipped and permuted. + */ + if (d->custom_optind == argc) { + /* + * Set the next-arg-index to point at the non-options that we + * previously skipped, so the caller will digest them. + */ + if (d->first_nonopt != d->last_nonopt) + d->custom_optind = d->first_nonopt; + return -1; + } + /* + * If we have come to a non-option and did not permute it, either stop + * the scan or describe it to the caller and pass it by. + */ + if (NONOPTION_P) { + d->custom_optarg = argv[d->custom_optind++]; + return 1; + } + /* + * We have found another option-ARGV-element. Skip the initial + * punctuation. + */ + d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); + return 0; +} + +/* + * Check whether the ARGV-element is a long option. + * + * If there's a long option "fubar" and the ARGV-element is "-fu", consider + * that an abbreviation of the long option, just like "--fu", and not "-f" with + * arg "u". + * + * This distinction seems to be the most useful approach. + * + */ +static int check_long_opt(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int print_errors, struct custom_getopt_data *d) +{ + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { + if ((unsigned int) (nameend - d->nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else if (pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[d->custom_optind]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optind++; + d->custom_optopt = 0; + return '?'; + } + if (pfound) { + option_index = indfound; + d->custom_optind++; + if (*nameend) { + if (pfound->has_arg != no_argument) + d->custom_optarg = nameend + 1; + else { + if (print_errors) { + if (argv[d->custom_optind - 1][1] == '-') { + /* --option */ + fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + } else { + /* +option or -option */ + fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[d->custom_optind - 1][0], pfound->name); + } + + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == required_argument) { + if (d->custom_optind < argc) + d->custom_optarg = argv[d->custom_optind++]; + else { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], + argv[d->custom_optind - 1]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->nextchar += strlen(d->nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* + * Can't find it as a long option. If this is not getopt_long_only, or + * the option starts with '--' or is not a valid short option, then + * it's an error. Otherwise interpret it as a short option. + */ + if (print_errors) { + if (argv[d->custom_optind][1] == '-') { + /* --option */ + fprintf(stderr, + "%s: unrecognized option `--%s'\n", + argv[0], d->nextchar); + } else { + /* +option or -option */ + fprintf(stderr, + "%s: unrecognized option `%c%s'\n", + argv[0], argv[d->custom_optind][0], + d->nextchar); + } + } + d->nextchar = (char *) ""; + d->custom_optind++; + d->custom_optopt = 0; + return '?'; +} + +static int check_short_opt(int argc, char *const *argv, const char *optstring, + int print_errors, struct custom_getopt_data *d) +{ + char c = *d->nextchar++; + const char *temp = strchr(optstring, c); + + /* Increment `custom_optind' when we start to process its last character. */ + if (*d->nextchar == '\0') + ++d->custom_optind; + if (!temp || c == ':') { + if (print_errors) + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + + d->custom_optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + d->custom_optind++; + } else + d->custom_optarg = NULL; + d->nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + /* + * If we end this ARGV-element by taking the + * rest as an arg, we must advance to the next + * element now. + */ + d->custom_optind++; + } else if (d->custom_optind == argc) { + if (print_errors) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + d->custom_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* + * We already incremented `custom_optind' once; + * increment it again when taking next ARGV-elt + * as argument. + */ + d->custom_optarg = argv[d->custom_optind++]; + d->nextchar = NULL; + } + } + return c; +} + +/* + * Scan elements of ARGV for option characters given in OPTSTRING. + * + * If an element of ARGV starts with '-', and is not exactly "-" or "--", + * then it is an option element. The characters of this element + * (aside from the initial '-') are option characters. If `getopt' + * is called repeatedly, it returns successively each of the option characters + * from each of the option elements. + * + * If `getopt' finds another option character, it returns that character, + * updating `custom_optind' and `nextchar' so that the next call to `getopt' can + * resume the scan with the following option character or ARGV-element. + * + * If there are no more option characters, `getopt' returns -1. + * Then `custom_optind' is the index in ARGV of the first ARGV-element + * that is not an option. (The ARGV-elements have been permuted + * so that those that are not options now come last.) + * + * OPTSTRING is a string containing the legitimate option characters. + * If an option character is seen that is not listed in OPTSTRING, + * return '?' after printing an error message. If you set `custom_opterr' to + * zero, the error message is suppressed but we still return '?'. + * + * If a char in OPTSTRING is followed by a colon, that means it wants an arg, + * so the following text in the same ARGV-element, or the text of the following + * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that + * wants an optional arg; if there is text in the current ARGV-element, + * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. + * + * If OPTSTRING starts with `-' or `+', it requests different methods of + * handling the non-option ARGV-elements. + * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + * + * Long-named options begin with `--' instead of `-'. + * Their names may be abbreviated as long as the abbreviation is unique + * or is an exact match for some defined option. If they have an + * argument, it follows the option name in the same ARGV-element, separated + * from the option name by a `=', or else the in next ARGV-element. + * When `getopt' finds a long-named option, it returns 0 if that option's + * `flag' field is nonzero, the value of the option's `val' field + * if the `flag' field is zero. + * + * The elements of ARGV aren't really const, because we permute them. + * But we pretend they're const in the prototype to be compatible + * with other systems. + * + * LONGOPTS is a vector of `struct option' terminated by an + * element containing a name which is zero. + * + * LONGIND returns the index in LONGOPT of the long-named option found. + * It is only valid when a long-named option has been found by the most + * recent call. + * + * Return the option character from OPTS just read. Return -1 when there are + * no more options. For unrecognized options, or options missing arguments, + * `custom_optopt' is set to the option letter, and '?' is returned. + * + * The OPTS string is a list of characters which are recognized option letters, + * optionally followed by colons, specifying that that letter takes an + * argument, to be placed in `custom_optarg'. + * + * If a letter in OPTS is followed by two colons, its argument is optional. + * This behavior is specific to the GNU `getopt'. + * + * The argument `--' causes premature termination of argument scanning, + * explicitly telling `getopt' that there are no more options. If OPTS begins + * with `--', then non-option arguments are treated as arguments to the option + * '\0'. This behavior is specific to the GNU `getopt'. + */ + +static int getopt_internal_r(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + struct custom_getopt_data *d) +{ + int ret, print_errors = d->custom_opterr; + + if (optstring[0] == ':') + print_errors = 0; + if (argc < 1) + return -1; + d->custom_optarg = NULL; + + /* + * This is a big difference with GNU getopt, since optind == 0 + * means initialization while here 1 means first call. + */ + if (d->custom_optind == 0 || !d->initialized) { + if (d->custom_optind == 0) + d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ + custom_getopt_initialize(d); + } + if (d->nextchar == NULL || *d->nextchar == '\0') { + ret = shuffle_argv(argc, argv, longopts, d); + if (ret) + return ret; + } + if (longopts && (argv[d->custom_optind][1] == '-' )) + return check_long_opt(argc, argv, optstring, longopts, + longind, print_errors, d); + return check_short_opt(argc, argv, optstring, print_errors, d); +} + +static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind) +{ + int result; + /* Keep a global copy of all internal members of d */ + static struct custom_getopt_data d; + + d.custom_optind = custom_optind; + d.custom_opterr = custom_opterr; + result = getopt_internal_r(argc, argv, optstring, longopts, + longind, &d); + custom_optind = d.custom_optind; + custom_optarg = d.custom_optarg; + custom_optopt = d.custom_optopt; + return result; +} + +static int custom_getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return custom_getopt_internal(argc, argv, options, long_options, + opt_index); +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + FIX_UNUSED (default_value); + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_FLAG: + *((int *)field) = !*((int *)field); + break; + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; + default: + break; + }; + + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + case ARG_FLAG: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + char *optarg; + int optind; + int opterr; + int optopt; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "reader", 1, NULL, 'r' }, + { "verbose", 0, NULL, 'v' }, + { "pd", 0, NULL, 0 }, + { "vd", 0, NULL, 0 }, + { "gvd", 0, NULL, 0 }, + { "vsd-status", 0, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + custom_optarg = optarg; + custom_optind = optind; + custom_opterr = opterr; + custom_optopt = optopt; + + c = custom_getopt_long (argc, argv, "hVr:v", long_options, &option_index); + + optarg = custom_optarg; + optind = custom_optind; + opterr = custom_opterr; + optopt = custom_optopt; + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'r': /* Number of the PC/SC reader to use (-1 for autodetect). */ + + + if (update_arg( (void *)&(args_info->reader_arg), + &(args_info->reader_orig), &(args_info->reader_given), + &(local_args_info.reader_given), optarg, 0, "-1", ARG_INT, + check_ambiguity, override, 0, 0, + "reader", 'r', + additional_error)) + goto failure; + + break; + case 'v': /* Use (several times) to be more verbose. */ + + local_args_info.verbose_given++; + + break; + + case 0: /* Long option with no short option */ + /* Show 'Persönliche Versicherungsdaten' (XML). */ + if (strcmp (long_options[option_index].name, "pd") == 0) + { + + + if (update_arg((void *)&(args_info->pd_flag), 0, &(args_info->pd_given), + &(local_args_info.pd_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "pd", '-', + additional_error)) + goto failure; + + } + /* Show 'Allgemeine Versicherungsdaten' (XML). */ + else if (strcmp (long_options[option_index].name, "vd") == 0) + { + + + if (update_arg((void *)&(args_info->vd_flag), 0, &(args_info->vd_given), + &(local_args_info.vd_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "vd", '-', + additional_error)) + goto failure; + + } + /* Show 'Geschützte Versicherungsdaten' (XML). */ + else if (strcmp (long_options[option_index].name, "gvd") == 0) + { + + + if (update_arg((void *)&(args_info->gvd_flag), 0, &(args_info->gvd_given), + &(local_args_info.gvd_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "gvd", '-', + additional_error)) + goto failure; + + } + /* Show 'Versichertenstammdaten-Status'. */ + else if (strcmp (long_options[option_index].name, "vsd-status") == 0) + { + + + if (update_arg((void *)&(args_info->vsd_status_flag), 0, &(args_info->vsd_status_given), + &(local_args_info.vsd_status_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "vsd-status", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + args_info->verbose_given += local_args_info.verbose_given; + local_args_info.verbose_given = 0; + + if (check_required) + { + error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error); + } + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/src/tools/egk-tool-cmdline.h b/src/tools/egk-tool-cmdline.h new file mode 100644 index 0000000000..4b8912649f --- /dev/null +++ b/src/tools/egk-tool-cmdline.h @@ -0,0 +1,193 @@ +/** @file egk-tool-cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.6 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef EGK_TOOL_CMDLINE_H +#define EGK_TOOL_CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "egk-tool" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "egk-tool" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ + char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ + const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ + const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ + int pd_flag; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) (default=off). */ + const char *pd_help; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) help description. */ + int vd_flag; /**< @brief Show 'Allgemeine Versicherungsdaten' (XML) (default=off). */ + const char *vd_help; /**< @brief Show 'Allgemeine Versicherungsdaten' (XML) help description. */ + int gvd_flag; /**< @brief Show 'Geschützte Versicherungsdaten' (XML) (default=off). */ + const char *gvd_help; /**< @brief Show 'Geschützte Versicherungsdaten' (XML) help description. */ + int vsd_status_flag; /**< @brief Show 'Versichertenstammdaten-Status' (default=off). */ + const char *vsd_status_help; /**< @brief Show 'Versichertenstammdaten-Status' help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int reader_given ; /**< @brief Whether reader was given. */ + unsigned int verbose_given ; /**< @brief Whether verbose was given. */ + unsigned int pd_given ; /**< @brief Whether pd was given. */ + unsigned int vd_given ; /**< @brief Whether vd was given. */ + unsigned int gvd_given ; /**< @brief Whether gvd was given. */ + unsigned int vsd_status_given ; /**< @brief Whether vsd-status was given. */ + +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* EGK_TOOL_CMDLINE_H */ diff --git a/src/tools/egk-tool.1 b/src/tools/egk-tool.1 new file mode 100644 index 0000000000..f88a4bfeef --- /dev/null +++ b/src/tools/egk-tool.1 @@ -0,0 +1,39 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH EGK-TOOL "1" "Oktober 2017" "OpenSC 0.17.0" "User Commands" +.SH NAME +egk-tool \- manual page for egk-tool 0.17.0 +.SH SYNOPSIS +.B egk-tool +[\fI\,OPTIONS\/\fR]... +.SH DESCRIPTION +egk\-tool 0.17.0 +.TP +\fB\-h\fR, \fB\-\-help\fR +Print help and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version and exit +.TP +\fB\-r\fR, \fB\-\-reader\fR=\fI\,INT\/\fR +Number of the PC/SC reader to use (\fB\-1\fR for autodetect) +(default=`\-1') +.TP +\fB\-v\fR, \fB\-\-verbose\fR +Use (several times) to be more verbose +.SS "Health Care Application (HCA):" +.TP +\fB\-\-pd\fR +Show 'Persönliche Versicherungsdaten' (XML) (default=off) +.TP +\fB\-\-vd\fR +Show 'Allgemeine Versicherungsdaten' (XML) (default=off) +.TP +\fB\-\-gvd\fR +Show 'Geschützte Versicherungsdaten' (XML) (default=off) +.TP +\fB\-\-vsd\-status\fR +Show 'Versichertenstammdaten\-Status' (default=off) +.SH AUTHOR +Written by Frank Morgner +.SH "REPORTING BUGS" +Report bugs to opensc\-devel@lists.sourceforge.net diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c new file mode 100644 index 0000000000..8424e9c694 --- /dev/null +++ b/src/tools/egk-tool.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2017 Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "egk-tool-cmdline.h" +#include "libopensc/log.h" +#include "libopensc/opensc.h" +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#endif + +#ifdef ENABLE_ZLIB +#include + +int uncompress_gzip(void* uncompressed, size_t *uncompressed_len, + const void* compressed, size_t compressed_len) +{ + z_stream stream; + memset(&stream, 0, sizeof stream); + stream.total_in = compressed_len; + stream.avail_in = compressed_len; + stream.total_out = *uncompressed_len; + stream.avail_out = *uncompressed_len; + stream.next_in = (Bytef *) compressed; + stream.next_out = (Bytef *) uncompressed; + + /* 15 window bits, and the +32 tells zlib to to detect if using gzip or zlib */ + if (Z_OK == inflateInit2(&stream, (15 + 32)) + && Z_STREAM_END == inflate(&stream, Z_FINISH)) { + *uncompressed_len = stream.total_out; + } else { + return SC_ERROR_INVALID_DATA; + } + inflateEnd(&stream); + + return SC_SUCCESS; +} +#else +int uncompress_gzip(const void* compressed, size_t compressed_len, + void* uncompressed, size_t *uncompressed_len) +{ + return SC_ERROR_NOT_SUPPORTED; +} +#endif + +#define PRINT(c) (isprint(c) ? c : '?') + +void dump_binary(void *buf, size_t buf_len) +{ +#ifdef _WIN32 + _setmode(fileno(stdout), _O_BINARY); +#endif + fwrite(buf, 1, buf_len, stdout); +#ifdef _WIN32 + _setmode(fileno(stdout), _O_TEXT); +#endif +} + +const unsigned char aid_hca[] = {0xD2, 0x76, 0x00, 0x00, 0x01, 0x02}; + +static int initialize(int reader_id, int verbose, + sc_context_t **ctx, sc_reader_t **reader) +{ + unsigned int i, reader_count; + int r; + + if (!ctx || !reader) + return SC_ERROR_INVALID_ARGUMENTS; + + r = sc_establish_context(ctx, ""); + if (r < 0 || !*ctx) { + fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); + return r; + } + + (*ctx)->debug = verbose; + (*ctx)->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; + + reader_count = sc_ctx_get_reader_count(*ctx); + + if (reader_count == 0) { + sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n"); + return SC_ERROR_NO_READERS_FOUND; + } + + if (reader_id < 0) { + /* Automatically try to skip to a reader with a card if reader not specified */ + for (i = 0; i < reader_count; i++) { + *reader = sc_ctx_get_reader(*ctx, i); + if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { + reader_id = i; + sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader" + " with a card: %s", (*reader)->name); + break; + } + } + if ((unsigned int) reader_id >= reader_count) { + sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader."); + reader_id = 0; + } + } + + if ((unsigned int) reader_id >= reader_count) { + sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number " + "(%d), only %d available.\n", reader_id, reader_count); + return SC_ERROR_NO_READERS_FOUND; + } + + *reader = sc_ctx_get_reader(*ctx, reader_id); + + return SC_SUCCESS; +} + +int read_file(struct sc_card *card, char *str_path, unsigned char **data, size_t *data_len) +{ + struct sc_path path; + struct sc_file *file; + unsigned char *p; + int ok = 0; + int r; + size_t len; + + sc_format_path(str_path, &path); + if (SC_SUCCESS != sc_select_file(card, &path, &file)) { + goto err; + } + + len = file ? file->size : 4096; + p = realloc(*data, len); + if (!p) { + goto err; + } + *data = p; + *data_len = len; + + r = sc_read_binary(card, 0, p, len, 0); + if (r < 0) + goto err; + + *data_len = r; + ok = 1; + +err: + sc_file_free(file); + + return ok; +} + +void decode_version(unsigned char *bcd, unsigned int *major, unsigned int *minor, unsigned int *fix) +{ + *major = 0; + *minor = 0; + *fix = 0; + + /* decode BCD to decimal */ + if ((bcd[0]>>4) < 10 && ((bcd[0]&0xF) < 10) && ((bcd[1]>>4) < 10)) { + *major = (bcd[0]>>4)*100 + (bcd[0]&0xF)*10 + (bcd[1]>>4); + } + if (((bcd[1]&0xF) < 10) && ((bcd[2]>>4) < 10) && ((bcd[2]&0xF) < 10)) { + *minor = (bcd[1]&0xF)*100 + (bcd[2]>>4)*10 + (bcd[2]&0xF); + } + if ((bcd[3]>>4) < 10 && ((bcd[3]&0xF) < 10) + && (bcd[4]>>4) < 10 && ((bcd[4]&0xF) < 10)) { + *fix = (bcd[3]>>4)*1000 + (bcd[3]&0xF)*100 + + (bcd[4]>>4)*10 + (bcd[4]&0xF); + } +} + +int +main (int argc, char **argv) +{ + struct gengetopt_args_info cmdline; + struct sc_path path; + struct sc_context *ctx; + struct sc_reader *reader; + struct sc_card *card; + unsigned char *data = NULL; + size_t data_len = 0; + int r; + + if (cmdline_parser(argc, argv, &cmdline) != 0) + exit(1); + + r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader); + if (r < 0) { + fprintf(stderr, "Can't initialize reader\n"); + exit(1); + } + + if (sc_connect_card(reader, &card) < 0) { + fprintf(stderr, "Could not connect to card\n"); + sc_release_context(ctx); + exit(1); + } + + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_hca, sizeof aid_hca, 0, 0); + if (SC_SUCCESS != sc_select_file(card, &path, NULL)) + goto err; + + if (cmdline.pd_flag + && read_file(card, "D001", &data, &data_len) + && data_len >= 2) { + size_t len_pd = (data[0] << 8) | data[1]; + + if (len_pd + 2 <= data_len) { + unsigned char uncompressed[1024]; + size_t uncompressed_len = sizeof uncompressed; + + if (uncompress_gzip(uncompressed, &uncompressed_len, + data + 2, len_pd) == SC_SUCCESS) { + dump_binary(uncompressed, uncompressed_len); + } else { + dump_binary(data + 2, len_pd); + } + } + } + + if ((cmdline.vd_flag || cmdline.gvd_flag) + && read_file(card, "D001", &data, &data_len) + && data_len >= 8) { + size_t off_vd = (data[0] << 8) | data[1]; + size_t end_vd = (data[2] << 8) | data[3]; + size_t off_gvd = (data[4] << 8) | data[5]; + size_t end_gvd = (data[6] << 8) | data[7]; + size_t len_vd = end_vd - off_vd + 1; + size_t len_gvd = end_gvd - off_gvd + 1; + + if (off_vd <= end_vd && end_vd < data_len + && off_gvd <= end_gvd && end_gvd < data_len) { + unsigned char uncompressed[1024]; + size_t uncompressed_len = sizeof uncompressed; + + if (cmdline.vd_flag) { + if (uncompress_gzip(uncompressed, &uncompressed_len, + data + off_vd, len_vd) == SC_SUCCESS) { + dump_binary(uncompressed, uncompressed_len); + } else { + dump_binary(data + off_vd, len_vd); + } + } + + if (cmdline.gvd_flag) { + if (uncompress_gzip(uncompressed, &uncompressed_len, + data + off_gvd, len_gvd) == SC_SUCCESS) { + dump_binary(uncompressed, uncompressed_len); + } else { + dump_binary(data + off_gvd, len_gvd); + } + } + } + } + + if (cmdline.vsd_status_flag + && read_file(card, "D00C", &data, &data_len) + && data_len >= 25) { + char *status; + unsigned int major, minor, fix; + + switch (data[0]) { + case '0': + status = "Transactions pending"; + break; + case '1': + status = "No transactions pending"; + break; + default: + status = "Unknown"; + break; + } + + decode_version(data+15, &major, &minor, &fix); + + printf( + "Status %s\n" + "Timestamp %c%c.%c%c.%c%c%c%c at %c%c:%c%c:%c%c\n" + "Version %u.%u.%u\n", + status, + PRINT(data[7]), PRINT(data[8]), + PRINT(data[5]), PRINT(data[6]), + PRINT(data[1]), PRINT(data[2]), PRINT(data[3]), PRINT(data[4]), + PRINT(data[9]), PRINT(data[10]), + PRINT(data[11]), PRINT(data[12]), + PRINT(data[13]), PRINT(data[14]), + major, minor, fix); + } + +err: + sc_disconnect_card(card); + sc_release_context(ctx); + cmdline_parser_free (&cmdline); + + return 0; +} diff --git a/src/tools/egk-tool.ggo.in b/src/tools/egk-tool.ggo.in new file mode 100644 index 0000000000..9142c3e8d8 --- /dev/null +++ b/src/tools/egk-tool.ggo.in @@ -0,0 +1,31 @@ +package "egk-tool" +purpose "@PACKAGE_SUMMARY@" + +option "reader" r + "Number of the PC/SC reader to use (-1 for autodetect)" + int + default="-1" + optional +option "verbose" v + "Use (several times) to be more verbose" + multiple + optional + +section "Health Care Application (HCA)" +option "pd" - + "Show 'Persönliche Versicherungsdaten' (@VDFORMAT@)" + flag off +option "vd" - + "Show 'Allgemeine Versicherungsdaten' (@VDFORMAT@)" + flag off +option "gvd" - + "Show 'Geschützte Versicherungsdaten' (@VDFORMAT@)" + flag off +option "vsd-status" - + "Show 'Versichertenstammdaten-Status'" + flag off + +text " +Report bugs to @PACKAGE_BUGREPORT@ + +Written by Frank Morgner " diff --git a/src/tools/opensc-notify.1 b/src/tools/opensc-notify.1 new file mode 100644 index 0000000000..3dce58c358 --- /dev/null +++ b/src/tools/opensc-notify.1 @@ -0,0 +1,45 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH OPENSC-NOTIFY "1" "Oktober 2017" "OpenSC 0.17.0" "User Commands" +.SH NAME +opensc-notify \- manual page for opensc-notify 0.17.0 +.SH SYNOPSIS +.B opensc-notify +[\fI\,OPTIONS\/\fR]... +.SH DESCRIPTION +opensc\-notify 0.17.0 +.PP +If no arguments are given, monitor smart card events and send the appropriate +notification. +.TP +\fB\-h\fR, \fB\-\-help\fR +Print help and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version and exit +.IP +Mode: customized +.IP +Send customized notifications. +\fB\-t\fR, \fB\-\-title\fR[=\fI\,STRING\/\fR] Title of the notification +\fB\-m\fR, \fB\-\-message\fR[=\fI\,STRING\/\fR] Main text of the notification +.IP +Mode: standard +.IP +Manually send standard notifications. +\fB\-I\fR, \fB\-\-notify\-card\-inserted\fR See notify_card_inserted in opensc.conf +.IP +(default=off) +.TP +\fB\-R\fR, \fB\-\-notify\-card\-removed\fR +See notify_card_inserted in opensc.conf +(default=off) +.TP +\fB\-G\fR, \fB\-\-notify\-pin\-good\fR +See notify_pin_good in opensc.conf (default=off) +.TP +\fB\-B\fR, \fB\-\-notify\-pin\-bad\fR +See notify_pin_bad in opensc.conf (default=off) +.SH AUTHOR +Written by Frank Morgner +.SH "REPORTING BUGS" +Report bugs to opensc\-devel@lists.sourceforge.net From 4f189a51742fe833805aea21760244e00a7583b2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Sep 2017 10:13:26 +0200 Subject: [PATCH 0079/4321] check for digits in case of BCD encoded PIN --- src/libopensc/sec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 024b21628d..ff2f650f3f 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -258,6 +258,9 @@ int sc_build_pin(u8 *buf, size_t buflen, struct sc_pin_cmd_pin *pin, int pad) if (pin_len > 2 * buflen) return SC_ERROR_BUFFER_TOO_SMALL; for (i = j = 0; j < pin_len; j++) { + if (!isdigit(pin->data[j])) { + return SC_ERROR_INVALID_DATA; + } buf[i] <<= 4; buf[i] |= pin->data[j] & 0xf; if (j & 1) From e54684b9db2da78e8dd3ceebb0f4f135967f0bcb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Sep 2017 13:32:29 +0200 Subject: [PATCH 0080/4321] fixed documentation of GLP encoded PIN --- src/libopensc/sec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index ff2f650f3f..7cfd9fd881 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H #include #endif @@ -223,7 +224,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, * PIN buffers are allways 16 nibbles (8 bytes) and look like this: * 0x2 + len + pin_in_BCD + paddingnibbles * in which the paddingnibble = 0xF - * E.g. if PIN = 12345, then sbuf = {0x24, 0x12, 0x34, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF} + * E.g. if PIN = 12345, then sbuf = {0x25, 0x12, 0x34, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF} * E.g. if PIN = 123456789012, then sbuf = {0x2C, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0xFF} * Reference: Global Platform - Card Specification - version 2.0.1' - April 7, 2000 */ From b7b6680f389583cff8dba0b1e3cfc3cf9bc2193e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Sep 2017 13:36:43 +0200 Subject: [PATCH 0081/4321] starcos: 3.4 supports ISO based PIN status queries --- src/libopensc/card-starcos.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index ac22a926bf..74bd253d45 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -130,6 +130,8 @@ static int starcos_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { card->name = "STARCOS SPK 3.4"; + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + flags |= SC_CARD_FLAG_RNG | SC_ALGORITHM_RSA_HASH_SHA224 | SC_ALGORITHM_RSA_HASH_SHA256 From bc075d66396f870153dde9572c343626c6cf3d1b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Sep 2017 11:11:15 +0200 Subject: [PATCH 0082/4321] iso7816: don't show error for PIN status on 63C3 --- src/libopensc/iso7816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 72fa6c41c7..cc9a7c3149 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -116,7 +116,7 @@ iso7816_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) if (sw1 == 0x90) return SC_SUCCESS; if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) { - sc_log(card->ctx, "Verification failed (remaining tries: %d)", (sw2 & 0x0f)); + sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } for (i = 0; i < err_count; i++) { From 594e125f06e1bf7c818d1690de25dfb51d8a351c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 15 Sep 2017 11:47:10 +0200 Subject: [PATCH 0083/4321] Added PKCS#15 emulator for DIN 66291 profile --- src/libopensc/Makefile.am | 2 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/pkcs15-din-66291.c | 277 +++++++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 1 + src/libopensc/pkcs15-syn.h | 1 + src/libopensc/pkcs15.c | 60 ++++--- src/libopensc/pkcs15.h | 2 + 7 files changed, 319 insertions(+), 26 deletions(-) create mode 100644 src/libopensc/pkcs15-din-66291.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 0f92feea21..a71256b065 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -52,7 +52,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ - pkcs15-coolkey.c \ + pkcs15-coolkey.c pkcs15-din-66291.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c \ compression.c p15card-helper.c sm.c \ aux-data.c diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index bfee45f8aa..ac1564d326 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -32,7 +32,7 @@ OBJECTS = \ pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ - pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj \ + pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ compression.obj p15card-helper.obj sm.obj \ diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c new file mode 100644 index 0000000000..31894d5def --- /dev/null +++ b/src/libopensc/pkcs15-din-66291.c @@ -0,0 +1,277 @@ +/* + * PKCS15 emulation layer for DIN 66291–4 profile. + * + * Copyright (C) 2017, Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "common/compat_strlcpy.h" +#include "log.h" +#include "pkcs15.h" +#include +#include + +static const unsigned char aid_CIA[] = {0xE8, 0x28, 0xBD, 0x08, 0x0F, + 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E}; +static const unsigned char aid_ESIGN[] = {0xA0, 0x00, 0x00, 0x01, 0x67, + 0x45, 0x53, 0x49, 0x47, 0x4E}; + +int din_66291_match_p15card(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + int ok = 0, r; + sc_path_t path; + unsigned char *tokeninfo_content = NULL; + struct sc_file *file_tokeninfo = NULL; + struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); + + if (!p15card || !tokeninfo + || (aid && (aid->len != sizeof aid_CIA + || 0 != memcmp(aid->value, aid_CIA, sizeof aid_CIA)))) + goto err; + + if (p15card->tokeninfo + && p15card->tokeninfo->profile_indication.name + && 0 == strcmp("DIN V 66291", + p15card->tokeninfo->profile_indication.name)) { + ok = 1; + goto err; + } + + /* it is possible that p15card->tokeninfo has not been touched yet */ + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_CIA, sizeof aid_CIA, 0, 0); + if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL)) + goto err; + + sc_format_path("5032", &path); + if (SC_SUCCESS != sc_select_file(p15card->card, &path, &file_tokeninfo)) + goto err; + + tokeninfo_content = malloc(file_tokeninfo->size); + if (!tokeninfo_content) + goto err; + r = sc_read_binary(p15card->card, 0, tokeninfo_content, file_tokeninfo->size, 0); + if (r < 0) + goto err; + r = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, tokeninfo, tokeninfo_content, r); + if (r != SC_SUCCESS) + goto err; + + if (tokeninfo->profile_indication.name + && 0 == strcmp("DIN V 66291", + tokeninfo->profile_indication.name)) { + ok = 1; + /* save tokeninfo and file_tokeninfo */ + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); + sc_file_free(p15card->file_tokeninfo); + p15card->tokeninfo = tokeninfo; + p15card->file_tokeninfo = file_tokeninfo; + tokeninfo = NULL; + file_tokeninfo = NULL; + } + +err: + sc_pkcs15_free_tokeninfo(tokeninfo); + sc_file_free(file_tokeninfo); + free(tokeninfo_content); + + return ok; +} + + static int +sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) +{ + /* EF.C.CH.AUT + * fileIdentifier ´C5 00´ + * shortFileIdentifier ´01´= 1 + * PrK.CH.AUT + * keyIdentifier ´02´ = 2 + * privateKey …, Moduluslänge 2048 Bit + * + * EF.C.CH.ENC + * fileIdentifier ´C2 00´ + * shortFileIdentifier ´02´= 2 + * PrK.CH.ENC + * keyIdentifier ´03´ = 3 + * privateKey …, Moduluslänge 2048 Bit + */ + sc_path_t path; + size_t i; + struct sc_pin_cmd_data data; + const unsigned char user_pin_ref = 0x02; + sc_serial_number_t serial; + + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_ESIGN, sizeof aid_ESIGN, 0, 0); + if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL)) + return SC_ERROR_WRONG_CARD; + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_GET_INFO; + data.pin_type = SC_AC_CHV; + data.pin_reference = user_pin_ref; + + if (SC_SUCCESS == sc_pin_cmd(p15card->card, &data, NULL)) { + const unsigned char user_pin_id = 1; + + for (i = 0; i < 2; i++) { + const char *pin_names[3] = { "PIN", "PUK" }; + const int pin_min[] = {6, 10}; + const int pin_max[] = {8, 8}; + const unsigned char user_puk_id = 2; + const int pin_id[] = {user_pin_id, user_puk_id}; + const int pin_flags[] = {SC_PKCS15_PIN_FLAG_INITIALIZED, + SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED}; + const int max_tries[] = {3, 10}; + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + pin_info.auth_id.value[0] = pin_id[i]; + pin_info.auth_id.len = 1; + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.flags = pin_flags[i]; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.attrs.pin.min_length = pin_min[i]; + pin_info.attrs.pin.stored_length = pin_max[i]; + pin_info.attrs.pin.max_length = pin_max[i]; + pin_info.max_tries = max_tries[i]; + + strlcpy(pin_obj.label, pin_names[i], sizeof(pin_obj.label)); + + /* catch the differences between PIN and PUK */ + if (pin_flags[i] & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) { + pin_info.tries_left = max_tries[i]; + } else { + pin_info.attrs.pin.reference = user_pin_ref; + pin_info.tries_left = data.pin1.tries_left; + pin_info.logged_in = data.pin1.logged_in; + pin_obj.auth_id.value[0] = user_puk_id; + pin_obj.auth_id.len = 1; + } + + if (0 > sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info)) + return SC_ERROR_INTERNAL; + } + + for (i = 0; i < 2; i++) { + struct sc_aid aid; + const char *din_66291_cert_fids[] = { "C500", "C200"}; + const char prk_id[] = { 0x10, 0x11,}; + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + const int prk_usage[2] = { + SC_PKCS15_PRKEY_USAGE_ENCRYPT + | SC_PKCS15_PRKEY_USAGE_DECRYPT + | SC_PKCS15_PRKEY_USAGE_SIGN, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + + memcpy(aid.value, aid_CIA, sizeof aid_CIA); + aid.len = sizeof aid_CIA; + + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + + sc_format_path(din_66291_cert_fids[i], &cert_info.path); + if (SC_SUCCESS != sc_select_file(p15card->card, &cert_info.path, NULL)) + continue; + cert_info.path.aid = aid; + + cert_info.id.value[0] = prk_id[i]; + cert_info.id.len = 1; + + if (0 > sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info)) + continue; + + if (i == 0) { + sc_pkcs15_cert_t *cert; + if (SC_SUCCESS == sc_pkcs15_read_certificate(p15card, &cert_info, &cert)) { + static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; + u8 *cn_name = NULL; + size_t cn_len = 0; + sc_pkcs15_get_name_from_dn(p15card->card->ctx, cert->subject, + cert->subject_len, &cn_oid, &cn_name, &cn_len); + if (cn_len > 0) { + char *token_name = malloc(cn_len+1); + if (token_name) { + memcpy(token_name, cn_name, cn_len); + token_name[cn_len] = '\0'; + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = token_name; + } + } + free(cn_name); + sc_pkcs15_free_certificate(cert); + } + } + + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + prkey_info.id.value[0] = prk_id[i]; + prkey_info.id.len = 1; + prkey_info.usage = prk_usage[i]; + prkey_info.native = 1; + prkey_info.key_reference = prk_id[i]; + prkey_info.modulus_length = 2048; + prkey_obj.auth_id.value[0] = user_pin_id; + prkey_obj.auth_id.len = 1; + prkey_obj.user_consent = 0; + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + if (0 > sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info)) + continue; + } + } + + /* get the card serial number */ + if (!p15card->tokeninfo->serial_number + && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { + char serial_hex[SC_MAX_SERIALNR*2+2]; + sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex - 1, 0); + p15card->tokeninfo->serial_number = strdup(serial_hex); + } + + return SC_SUCCESS; +} + +int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, + sc_pkcs15emu_opt_t *opts) +{ + if (!p15card || ! p15card->card) + return SC_ERROR_INVALID_ARGUMENTS; + + SC_FUNC_CALLED(p15card->card->ctx, 1); + + /* Check card */ + if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { + if (!din_66291_match_p15card(p15card, aid)) + return SC_ERROR_WRONG_CARD; + } + + /* Init card */ + return sc_pkcs15emu_din_66291_init(p15card); +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index d72fc313ba..4f2932e4e5 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -59,6 +59,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "iasecc", sc_pkcs15emu_iasecc_init_ex }, { "jpki", sc_pkcs15emu_jpki_init_ex }, { "coolkey", sc_pkcs15emu_coolkey_init_ex }, + { "din66291", sc_pkcs15emu_din_66291_init_ex }, { NULL, NULL } }; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index 22db061bec..202711d0b0 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -53,6 +53,7 @@ int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_ int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); +int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); struct sc_pkcs15_emulator_handler { const char *name; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index ba99c8af9a..d136021b1a 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -738,40 +738,52 @@ sc_pkcs15_card_new(void) return NULL; } - sc_init_oid(&p15card->tokeninfo->profile_indication.oid); - p15card->magic = SC_PKCS15_CARD_MAGIC; return p15card; } +struct sc_pkcs15_tokeninfo * +sc_pkcs15_tokeninfo_new(void) +{ + struct sc_pkcs15_tokeninfo *tokeninfo; + + tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo)); + if (tokeninfo == NULL) { + return NULL; + } + + sc_init_oid(&tokeninfo->profile_indication.oid); + + return tokeninfo; +} + + void -sc_pkcs15_free_tokeninfo(struct sc_pkcs15_card *p15card) +sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo) { - if (!p15card || !p15card->tokeninfo) + if (!tokeninfo) return; - if (p15card->tokeninfo->label != NULL) - free(p15card->tokeninfo->label); - if (p15card->tokeninfo->serial_number != NULL) - free(p15card->tokeninfo->serial_number); - if (p15card->tokeninfo->manufacturer_id != NULL) - free(p15card->tokeninfo->manufacturer_id); - if (p15card->tokeninfo->last_update.gtime != NULL) - free(p15card->tokeninfo->last_update.gtime); - if (p15card->tokeninfo->preferred_language != NULL) - free(p15card->tokeninfo->preferred_language); - if (p15card->tokeninfo->profile_indication.name != NULL) - free(p15card->tokeninfo->profile_indication.name); - if (p15card->tokeninfo->seInfo != NULL) { + if (tokeninfo->label != NULL) + free(tokeninfo->label); + if (tokeninfo->serial_number != NULL) + free(tokeninfo->serial_number); + if (tokeninfo->manufacturer_id != NULL) + free(tokeninfo->manufacturer_id); + if (tokeninfo->last_update.gtime != NULL) + free(tokeninfo->last_update.gtime); + if (tokeninfo->preferred_language != NULL) + free(tokeninfo->preferred_language); + if (tokeninfo->profile_indication.name != NULL) + free(tokeninfo->profile_indication.name); + if (tokeninfo->seInfo != NULL) { unsigned i; - for (i = 0; i < p15card->tokeninfo->num_seInfo; i++) - free(p15card->tokeninfo->seInfo[i]); - free(p15card->tokeninfo->seInfo); + for (i = 0; i < tokeninfo->num_seInfo; i++) + free(tokeninfo->seInfo[i]); + free(tokeninfo->seInfo); } - free(p15card->tokeninfo); - - p15card->tokeninfo = NULL; + free(tokeninfo); } @@ -815,7 +827,7 @@ sc_pkcs15_card_free(struct sc_pkcs15_card *p15card) sc_file_free(p15card->file_unusedspace); p15card->magic = 0; - sc_pkcs15_free_tokeninfo(p15card); + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); sc_pkcs15_free_app(p15card); free(p15card); } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index b6a2dd3406..6ba61c2171 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -647,6 +647,8 @@ int sc_pkcs15_find_object_by_id(struct sc_pkcs15_card *, unsigned int, struct sc_pkcs15_card * sc_pkcs15_card_new(void); void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card); void sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card); +struct sc_pkcs15_tokeninfo * sc_pkcs15_tokeninfo_new(void); +void sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo); int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, From 5bd4716ea06960082db83c91a80a8e52da51b9c1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Oct 2017 08:06:20 +0200 Subject: [PATCH 0084/4321] added missing include --- src/common/compat_strlcpy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/compat_strlcpy.h b/src/common/compat_strlcpy.h index a293142a29..d97e405ccc 100644 --- a/src/common/compat_strlcpy.h +++ b/src/common/compat_strlcpy.h @@ -32,5 +32,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef HAVE_STRLCPY +#include size_t strlcpy(char *dst, const char *src, size_t siz); #endif From 19d9ec7d5d498ee0b91d2e180af777bd77d0c099 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Oct 2017 14:52:52 +0200 Subject: [PATCH 0085/4321] msvc: don't warn about deprecated crt functions See https://msdn.microsoft.com/de-de/library/ms235384.aspx --- win32/Make.rules.mak | 4 ++-- win32/winconfig.h.in | 40 ++-------------------------------------- 2 files changed, 4 insertions(+), 40 deletions(-) diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 00f076d6c8..39ef8ec399 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -137,10 +137,10 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" !ENDIF diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index 298bbbd13a..aac13eeb16 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -15,48 +15,12 @@ #define strncasecmp strnicmp #endif -#ifndef snprintf -#define snprintf _snprintf -#endif - #ifndef vsnprintf #define vsnprintf _vsnprintf #endif -#ifndef isatty -#define isatty _isatty -#endif - -#ifndef strnicmp -#define strnicmp _strnicmp -#endif - -#ifndef stricmp -#define stricmp _stricmp -#endif - -#ifndef strdup -#define strdup _strdup -#endif - -#ifndef fileno -#define fileno _fileno -#endif - -#ifndef mkdir -#define mkdir _mkdir -#endif - -#ifndef access -#define access _access -#endif - -#ifndef unlink -#define unlink _unlink -#endif - -#ifndef putenv -#define putenv _putenv +#ifndef snprintf +#define snprintf _snprintf #endif #ifndef R_OK From be35d3d026634ad7eaacf898c2935b3558ac612e Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 27 Oct 2017 20:51:33 +0300 Subject: [PATCH 0086/4321] EstEID ECDSA token support (#1158) --- src/libopensc/card-mcrd.c | 10 +++++--- src/libopensc/pkcs15-esteid.c | 47 ++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index cbba3fdfa4..28f8abfad2 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -304,7 +304,7 @@ static int mcrd_match_card(sc_card_t * card) static int mcrd_init(sc_card_t * card) { - unsigned long flags; + unsigned long flags, ext_flags; struct mcrd_priv_data *priv; int r; sc_path_t tmppath; @@ -329,6 +329,10 @@ static int mcrd_init(sc_card_t * card) flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; /* EstEID v3.0 has 2048 bit keys */ _sc_card_add_rsa_alg(card, 2048, flags, 0); + + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); sc_reset(card, 0); sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); @@ -1188,7 +1192,7 @@ static int mcrd_set_security_env(sc_card_t * card, if (is_esteid_card(card)) { /* some sanity checks */ if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - if (env->algorithm != SC_ALGORITHM_RSA) + if (env->algorithm != SC_ALGORITHM_RSA && env->algorithm != SC_ALGORITHM_EC) return SC_ERROR_INVALID_ARGUMENTS; } if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) @@ -1375,7 +1379,7 @@ static int mcrd_compute_signature(sc_card_t * card, apdu.lc = datalen; apdu.data = data; apdu.datalen = datalen; - apdu.le = 0x80; + apdu.le = MIN(0x80u, outlen); apdu.resp = out; apdu.resplen = outlen; diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 361b2525a4..a4655b7f76 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -33,6 +33,7 @@ #include "common/compat_strlcat.h" #include "internal.h" +#include "opensc.h" #include "pkcs15.h" #include "esteid.h" @@ -64,6 +65,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) sc_card_t *card = p15card->card; unsigned char buff[128]; int r, i; + size_t field_length = 0, modulus_length = 0; sc_path_t tmppath; set_string (&p15card->tokeninfo->label, "ID-kaart"); @@ -74,7 +76,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_select_file (card, &tmppath, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "select esteid PD failed"); - /* read the serial (document number) */ + /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); buff[r] = '\0'; @@ -93,10 +95,10 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) "3f00eeeeaace", "3f00eeeeddce"}; static int esteid_cert_ids[2] = {1, 2}; - + struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; - + memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); @@ -110,6 +112,10 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) if (i == 0) { sc_pkcs15_cert_t *cert; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + if (cert->key->algorithm == SC_ALGORITHM_EC) + field_length = cert->key->u.ec.params.field_length; + else + modulus_length = cert->key->u.rsa.modulus.len * 8; if (r == SC_SUCCESS) { static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; u8 *cn_name = NULL; @@ -155,16 +161,16 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) memset(&pin_info, 0, sizeof(pin_info)); memset(&pin_obj, 0, sizeof(pin_obj)); - + /* read the number of tries left for the PIN */ r = sc_read_record (card, i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); if (r < 0) return SC_ERROR_INTERNAL; tries_left = buff[5]; - + pin_info.auth_id.len = 1; pin_info.auth_id.value[0] = esteid_pin_authid[i]; - pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; pin_info.attrs.pin.reference = esteid_pin_ref[i]; pin_info.attrs.pin.flags = esteid_pin_flags[i]; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; @@ -188,16 +194,11 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) if (r < 0) return SC_ERROR_INTERNAL; } - + /* add private keys */ for (i = 0; i < 2; i++) { static int prkey_pin[2] = {1, 2}; - static int prkey_usage[2] = { - SC_PKCS15_PRKEY_USAGE_ENCRYPT - | SC_PKCS15_PRKEY_USAGE_DECRYPT - | SC_PKCS15_PRKEY_USAGE_SIGN, - SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; - + static const char *prkey_name[2] = { "Isikutuvastus", "Allkirjastamine"}; @@ -207,16 +208,19 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) memset(&prkey_info, 0, sizeof(prkey_info)); memset(&prkey_obj, 0, sizeof(prkey_obj)); - + prkey_info.id.len = 1; prkey_info.id.value[0] = prkey_pin[i]; - prkey_info.usage = prkey_usage[i]; prkey_info.native = 1; prkey_info.key_reference = i + 1; - if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) - prkey_info.modulus_length = 2048; + prkey_info.field_length = field_length; + prkey_info.modulus_length = modulus_length; + if (i == 1) + prkey_info.usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; + else if(field_length > 0) // ECC has only sign usage + prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN; else - prkey_info.modulus_length = 1024; + prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label)); prkey_obj.auth_id.len = 1; @@ -224,7 +228,10 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) prkey_obj.user_consent = 0; prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; - r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + if(field_length > 0) + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + else + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) return SC_ERROR_INTERNAL; } @@ -236,7 +243,7 @@ static int esteid_detect_card(sc_pkcs15_card_t *p15card) { if (is_esteid_card(p15card->card)) return SC_SUCCESS; - else + else return SC_ERROR_WRONG_CARD; } From 4dfa7aa40c3b7ae448cea344d923b147ef74154e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Oct 2017 20:02:37 +0100 Subject: [PATCH 0087/4321] cope with system's fixes https://github.com/OpenSC/OpenSC/issues/1180 --- src/ui/notify.h | 2 +- src/ui/strings.c | 2 +- src/ui/strings.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/notify.h b/src/ui/notify.h index d32d69dd0c..df1ad77a8f 100644 --- a/src/ui/notify.h +++ b/src/ui/notify.h @@ -21,7 +21,7 @@ #ifndef _NOTIFY_H #define _NOTIFY_H -#include "strings.h" +#include "ui/strings.h" #ifdef __cplusplus extern "C" { diff --git a/src/ui/strings.c b/src/ui/strings.c index e7d4ffbd19..e129e9118a 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -19,7 +19,7 @@ */ #include "libopensc/internal.h" -#include "strings.h" +#include "ui/strings.h" #include #include diff --git a/src/ui/strings.h b/src/ui/strings.h index 0cc81cf69b..49dd25ee9c 100644 --- a/src/ui/strings.h +++ b/src/ui/strings.h @@ -18,8 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _STRINGS_H -#define _STRINGS_H +#ifndef _SC_STRINGS_H +#define _SC_STRINGS_H #include "libopensc/pkcs15.h" From 221d8c72aa38c7652a3f653ce4287f437ca4a6e5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Oct 2017 21:14:52 +0100 Subject: [PATCH 0088/4321] include branch in CI links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bcbba6606..c06cfc1ab4 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. -[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) +[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) From 189368e49fe0b82b7d18ce7e1aa72a5fa5358ccd Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 8 Nov 2017 14:24:18 +0200 Subject: [PATCH 0089/4321] Fix crash when certificate read failed (#1189) Fixes https://github.com/OpenSC/OpenSC/issues/1176 --- src/libopensc/pkcs15-esteid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index a4655b7f76..a5f9af8b2c 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -110,8 +110,10 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) if (r < 0) return SC_ERROR_INTERNAL; if (i == 0) { - sc_pkcs15_cert_t *cert; + sc_pkcs15_cert_t *cert = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + if (r < 0) + return SC_ERROR_INTERNAL; if (cert->key->algorithm == SC_ALGORITHM_EC) field_length = cert->key->u.ec.params.field_length; else From 04a7075290bcfaa16a9150255e4bed5c604d3d80 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 23:12:58 +0200 Subject: [PATCH 0090/4321] fixed compiler warnings --- configure.ac | 4 ++-- src/common/compat___iob_func.c | 14 ++++++++++---- src/libopensc/card-cardos.c | 4 ++-- src/libopensc/card-sc-hsm.c | 11 +++++++---- src/libopensc/ef-gdo.c | 3 ++- src/libopensc/iso7816.c | 8 ++++++-- src/libopensc/reader-tr03119.c | 6 +++--- src/libopensc/sec.c | 2 +- src/minidriver/minidriver.c | 2 +- src/pkcs11/framework-pkcs15.c | 4 +++- src/sm/sm-eac.c | 5 +++-- src/sm/sm-iso.c | 6 +++--- src/tools/Makefile.am | 10 ++++++++-- src/tools/cardos-tool.c | 2 +- src/tools/cryptoflex-tool.c | 2 +- src/tools/egk-tool.c | 6 +++--- src/tools/eidenv.c | 2 ++ src/tools/gids-tool.c | 2 +- src/tools/iasecc-tool.c | 2 +- src/tools/opensc-explorer.c | 2 +- src/tools/opensc-notify.c | 1 - src/tools/opensc-tool.c | 2 +- src/tools/piv-tool.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- src/tools/pkcs15-tool.c | 2 +- src/tools/sc-hsm-tool.c | 2 +- src/ui/strings.c | 3 ++- 27 files changed, 68 insertions(+), 43 deletions(-) diff --git a/configure.ac b/configure.ac index 3cdd4342c6..af5b257091 100644 --- a/configure.ac +++ b/configure.ac @@ -133,8 +133,8 @@ case "${host}" in ;; esac -AX_CHECK_COMPILE_FLAG(-Wno-error=unused-but-set-variable, [have_unused_but_set_variable="yes"], [have_unused_but_set_variable="no"], [-Werror -Wunknown-warning-option]) -AM_CONDITIONAL([HAVE_UNUSED_BUT_SET_VARIABLE], [test "${have_unused_but_set_variable}" = "yes"]) +AX_CHECK_COMPILE_FLAG(-Wunknown-warning-option, [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror]) +AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"]) AC_ARG_ENABLE( [strict], diff --git a/src/common/compat___iob_func.c b/src/common/compat___iob_func.c index 86a1d39fa6..b770243321 100644 --- a/src/common/compat___iob_func.c +++ b/src/common/compat___iob_func.c @@ -7,14 +7,20 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1900) // needed for OpenSSL static link // only for vs 2015 or later +// +// this is a horrible hack, the correct fix would be to recompile OpenSSL with +// VS 2015 or later. However, since in OpenSC, we don't need OpenSSL to send +// output to any of these buffers, we don't need to cope with runtime errors +// induced by this hack. See https://stackoverflow.com/a/34655235 for details. +// #pragma comment(lib, "legacy_stdio_definitions.lib") #include FILE * __cdecl __iob_func(void) { - static FILE *my_iob[3]; - my_iob[0] = stdin; - my_iob[1] = stdout; - my_iob[2] = stderr; + static FILE my_iob[3]; + my_iob[0] = *stdin; + my_iob[1] = *stdout; + my_iob[2] = *stderr; return my_iob; } #endif diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 077191731a..4d2ad6f3f4 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -559,8 +559,8 @@ static int cardos_set_file_attributes(sc_card_t *card, sc_file_t *file) status[0] = 0x01; if (file->type == SC_FILE_TYPE_DF) { - status[1] = file->size >> 8; - status[2] = file->size; + status[1] = (file->size >> 8) & 0xFF; + status[2] = file->size & 0xFF; } else { status[1] = status[2] = 0x00; /* not used */ } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index fc74192481..e415a12a47 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -805,15 +805,15 @@ static int sc_hsm_write_ef(sc_card_t *card, *p++ = idx & 0xFF; *p++ = 0x53; if (count < 128) { - *p++ = count; + *p++ = (u8) count; len = 6; } else if (count < 256) { *p++ = 0x81; - *p++ = count; + *p++ = (u8) count; len = 7; } else { *p++ = 0x82; - *p++ = count >> 8; + *p++ = (count >> 8) & 0xFF; *p++ = count & 0xFF; len = 8; } @@ -1199,8 +1199,11 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa memcpy(p, params->options, 2); p += 2; + if (params->user_pin_len > 0xFF) { + return SC_ERROR_INVALID_ARGUMENTS; + } *p++ = 0x81; // User PIN - *p++ = params->user_pin_len; + *p++ = (u8) params->user_pin_len; memcpy(p, params->user_pin, params->user_pin_len); p += params->user_pin_len; diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index 4d7a86bab8..d1017f755e 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -21,8 +21,9 @@ #include "config.h" #endif -#include "internal.h" #include "asn1.h" +#include "internal.h" +#include static int sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index cc9a7c3149..1fa4860cd8 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -828,8 +828,10 @@ iso7816_set_security_env(struct sc_card *card, *p++ = env->algorithm_ref & 0xFF; } if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { + if (env->file_ref.len > 0xFF) + return SC_ERROR_INVALID_ARGUMENTS; *p++ = 0x81; - *p++ = env->file_ref.len; + *p++ = (u8) env->file_ref.len; assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len); memcpy(p, env->file_ref.value, env->file_ref.len); p += env->file_ref.len; @@ -839,7 +841,9 @@ iso7816_set_security_env(struct sc_card *card, *p++ = 0x83; else *p++ = 0x84; - *p++ = env->key_ref_len; + if (env->key_ref_len > 0xFF) + return SC_ERROR_INVALID_ARGUMENTS; + *p++ = env->key_ref_len & 0xFF; assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len); memcpy(p, env->key_ref, env->key_ref_len); p += env->key_ref_len; diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index 7a9d4a4500..c3d2dcc5e3 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -494,7 +494,7 @@ static int escape_pin_cmd_to_buf(sc_context_t *ctx, /* GLP PIN length is encoded in 4 bits and block size is always 8 bytes */ bmPINBlockString = 0x40 | 0x08; } else if (pin_ref->encoding == SC_PIN_ENCODING_ASCII && data->flags & SC_PIN_CMD_NEED_PADDING) { - bmPINBlockString = pin_ref->pad_length; + bmPINBlockString = (uint8_t) pin_ref->pad_length; } else { bmPINBlockString = 0x00; } @@ -566,11 +566,11 @@ static int escape_pin_cmd_to_buf(sc_context_t *ctx, modify->bmPINLengthFormat = bmPINLengthFormat; if (!(data->flags & SC_PIN_CMD_IMPLICIT_CHANGE) && data->pin1.offset) { - modify->bInsertionOffsetOld = data->pin1.offset - 5; + modify->bInsertionOffsetOld = (uint8_t) data->pin1.offset - 5; } else { modify->bInsertionOffsetOld = 0; } - modify->bInsertionOffsetNew = data->pin2.offset ? data->pin2.offset - 5 : 0; + modify->bInsertionOffsetNew = data->pin2.offset ? (uint8_t) data->pin2.offset - 5 : 0; modify->wPINMaxExtraDigit = wPINMaxExtraDigit; modify->bConfirmPIN = CCID_PIN_CONFIRM_NEW | (data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0 : CCID_PIN_INSERT_OLD); diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 7cfd9fd881..2af61225ca 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -244,7 +244,7 @@ int sc_build_pin(u8 *buf, size_t buflen, struct sc_pin_cmd_pin *pin, int pad) if (pin->data[i] < '0' || pin->data[i] > '9') return SC_ERROR_INVALID_ARGUMENTS; } - buf[0] = 0x20 | pin_len; + buf[0] = 0x20 | (u8) pin_len; buf++; buflen--; } diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 7f952888ce..6478ff9b7a 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2864,7 +2864,7 @@ static const char *md_get_ui_str(PCARD_DATA pCardData, enum ui_str id) return str; } -static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) +static HRESULT CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { LONG_PTR param; int timeout; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 34d92cb515..ad398d8fc1 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -175,6 +175,7 @@ static const struct { const CK_BYTE gostr3411_94_cryptopro_paramset_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }; const unsigned int gostr3411_94_cryptopro_paramset_oid[] = {1, 2, 643, 2, 2, 30, 1, (unsigned int)-1}; +#ifdef USE_PKCS15_INIT static const struct { const CK_BYTE *encoded_oid; const unsigned int encoded_oid_size; @@ -186,6 +187,7 @@ static const struct { &gostr3411_94_cryptopro_paramset_oid[0], sizeof(gostr3411_94_cryptopro_paramset_oid)} }; +#endif static int __pkcs15_release_object(struct pkcs15_any_object *); static CK_RV register_mechanisms(struct sc_pkcs11_card *p11card); @@ -978,7 +980,7 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj, unsigned int i; struct pkcs15_fw_data *card_fw_data; CK_OBJECT_HANDLE handle = - (CK_OBJECT_HANDLE)obj; /* cast pointer to long, will truncate on Win64 */ + (CK_OBJECT_HANDLE)(uintptr_t)obj; /* cast pointer to long, will truncate on Win64 */ if (obj == NULL || slot == NULL) return; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 89712bd77e..4c66ff764a 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1684,8 +1684,9 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, } c_data->eph_pub_key = ASN1_OCTET_STRING_new(); if (!c_data->eph_pub_key - || !ASN1_OCTET_STRING_set( c_data->eph_pub_key, - eph_pub_key->data, eph_pub_key->length)) { + || !ASN1_OCTET_STRING_set(c_data->eph_pub_key, + (const unsigned char *) eph_pub_key->data, + eph_pub_key->length)) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 2f419cbfb9..b702a2f4b9 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -156,15 +156,15 @@ static int format_le(size_t le, struct sc_asn1_entry *le_entry, switch (*le_len) { case 1: - p[0] = le; + p[0] = le & 0xff; break; case 2: - p[0] = le >> 8; + p[0] = (le >> 8) & 0xff; p[1] = le & 0xff; break; case 3: p[0] = 0x00; - p[1] = le >> 8; + p[1] = (le >> 8) & 0xff; p[2] = le & 0xff; break; default: diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 98fb448826..6d823c6edc 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -113,7 +113,10 @@ npa-tool.1: opensc_notify_SOURCES = opensc-notify.c $(OPENSC_NOTIFY_BUILT_SOURCES) opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) opensc_notify_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_NOTIFY_CFLAGS) -opensc_notify_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option +opensc_notify_CFLAGS += -Wno-unused-but-set-variable +if HAVE_UNKNOWN_WARNING_OPTION +opensc_notify_CFLAGS += -Wno-unknown-warning-option +endif opensc-notify.c: $(abs_builddir)/opensc-notify.ggo $(OPENSC_NOTIFY_BUILT_SOURCES) @@ -137,7 +140,10 @@ opensc-notify.1: egk_tool_SOURCES = egk-tool.c $(EGK_TOOL_BUILT_SOURCES) egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) -egk_tool_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option +egk_tool_CFLAGS += -Wno-unused-but-set-variable +if HAVE_UNKNOWN_WARNING_OPTION +egk_tool_CFLAGS += -Wno-unknown-warning-option +endif egk-tool.c: $(abs_builddir)/egk-tool.ggo $(EGK_TOOL_BUILT_SOURCES) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index cccc76d323..c90bf0350d 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1027,7 +1027,7 @@ static int cardos_change_startkey(const char *change_startkey_apdu) { } #endif -int main(int argc, char *const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_info = 0; diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index ed9255e050..21b0baa16d 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -978,7 +978,7 @@ static int create_pin(void) return create_pin_file(&path, opt_pin_num, ""); } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index 8424e9c694..0a8834b6f7 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -60,8 +60,8 @@ int uncompress_gzip(void* uncompressed, size_t *uncompressed_len, return SC_SUCCESS; } #else -int uncompress_gzip(const void* compressed, size_t compressed_len, - void* uncompressed, size_t *uncompressed_len) +int uncompress_gzip(void* uncompressed, size_t *uncompressed_len, + const void* compressed, size_t compressed_len) { return SC_ERROR_NOT_SUPPORTED; } @@ -196,7 +196,7 @@ main (int argc, char **argv) struct gengetopt_args_info cmdline; struct sc_path path; struct sc_context *ctx; - struct sc_reader *reader; + struct sc_reader *reader = NULL; struct sc_card *card; unsigned char *data = NULL; size_t data_len = 0; diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 4d2029b355..7caaa1363c 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -23,6 +23,8 @@ #include #ifndef _WIN32 #include +#else +#include #endif #include #include diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 48084d8c3e..58e77e1f7a 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -466,7 +466,7 @@ static int print_info(sc_card_t *card) { return SC_SUCCESS; } -int main(int argc, char * const argv[]) +int main(int argc, char * argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 6b79494b17..d8a31faa5a 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -197,7 +197,7 @@ static int list_apps(FILE *fout) return 0; } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_list_sdos = 0; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 8ec63cf630..0a66bcb5cf 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1867,7 +1867,7 @@ static char *read_cmdline(FILE *script, char *prompt) return buf; } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int r, c, long_optind = 0, err = 0; char *line; diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 244047ab4a..5a586911e5 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -173,7 +173,6 @@ WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowC LPWSTR *wargv = NULL; char **argv = NULL; int argc = 0, i; - struct gengetopt_args_info cmdline; wargv = CommandLineToArgvW(GetCommandLineW(), &argc); if (wargv == NULL) { diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 4d7efc7a3e..102492c60b 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -668,7 +668,7 @@ static int card_reset(const char *reset_type) return 0; } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_info = 0; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 89581064f4..bab5fb80e0 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -459,7 +459,7 @@ static void print_serial(sc_card_t *in_card) util_hex_dump_asc(stdout, serial.value, serial.len, -1); } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_send_apdu = 0; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 8d5be6d5b9..05ee99a194 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -352,7 +352,7 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) return 0; } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_decipher = 0; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 15ddde07e3..9fef9a68b1 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2031,7 +2031,7 @@ static int update(sc_card_t *in_card) return 0; } -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int do_read_cert = 0; diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 938a8955da..6ae2116395 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1654,7 +1654,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p -int main(int argc, char * const argv[]) +int main(int argc, char *argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; diff --git a/src/ui/strings.c b/src/ui/strings.c index e129e9118a..d98dbe3a6a 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -20,8 +20,9 @@ #include "libopensc/internal.h" #include "ui/strings.h" -#include #include +#include +#include enum ui_langs { EN, From 251a5f9fef8d8110fe6f5029863ea545bbe9635a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 23:34:05 +0200 Subject: [PATCH 0091/4321] reader-pcsc: use sc_apdu2bytes for PIN APDU --- src/libopensc/apdu.c | 4 ++-- src/libopensc/opensc.h | 18 ++++++++++++++++++ src/libopensc/reader-pcsc.c | 34 ++++++++++++---------------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 3a46825096..99c0da4beb 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -39,7 +39,7 @@ * @param proto the desired protocol * @return length of the encoded APDU */ -static size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto) +size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto) { size_t ret = 4; @@ -80,7 +80,7 @@ static size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto) * @param outlen size of hte output buffer * @return SC_SUCCESS on success and an error code otherwise */ -static int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu, +int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu, unsigned int proto, u8 *out, size_t outlen) { u8 *p = out; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5c2ec3cf86..67410eabc3 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -746,6 +746,24 @@ int sc_check_apdu(struct sc_card *, const struct sc_apdu *); */ int sc_bytes2apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu); +/** Encodes a APDU as an octet string + * @param ctx sc_context_t object (used for logging) + * @param apdu APDU to be encoded as an octet string + * @param proto protocol version to be used + * @param out output buffer of size outlen. + * @param outlen size of hte output buffer + * @return SC_SUCCESS on success and an error code otherwise + */ +int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu, + unsigned int proto, u8 *out, size_t outlen); + +/** Calculates the length of the encoded APDU in octets. + * @param apdu the APDU + * @param proto the desired protocol + * @return length of the encoded APDU + */ +size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto); + int sc_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2); /********************************************************************/ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 120993ecb8..20eaf30cef 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1706,17 +1706,12 @@ static int part10_build_verify_pin_block(struct sc_reader *reader, u8 * buf, siz pin_verify->bTeoPrologue[2] = 0x00; /* APDU itself */ - pin_verify->abData[offset++] = apdu->cla; - pin_verify->abData[offset++] = apdu->ins; - pin_verify->abData[offset++] = apdu->p1; - pin_verify->abData[offset++] = apdu->p2; - - /* Copy data if not Case 1 */ - if (data->pin1.length_offset != 4) { - pin_verify->abData[offset++] = apdu->lc; - memcpy(&pin_verify->abData[offset], apdu->data, apdu->datalen); - offset += apdu->datalen; - } + LOG_TEST_RET(reader->ctx, + sc_apdu2bytes(reader->ctx, apdu, + reader->active_protocol, pin_verify->abData, + SC_MAX_APDU_BUFFER_SIZE), + "Could not encode PIN APDU"); + offset += sc_apdu_get_length(apdu, reader->active_protocol); pin_verify->ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */ @@ -1825,17 +1820,12 @@ static int part10_build_modify_pin_block(struct sc_reader *reader, u8 * buf, siz pin_modify->bTeoPrologue[2] = 0x00; /* APDU itself */ - pin_modify->abData[offset++] = apdu->cla; - pin_modify->abData[offset++] = apdu->ins; - pin_modify->abData[offset++] = apdu->p1; - pin_modify->abData[offset++] = apdu->p2; - - /* Copy data if not Case 1 */ - if (pin_ref->length_offset != 4) { - pin_modify->abData[offset++] = apdu->lc; - memcpy(&pin_modify->abData[offset], apdu->data, apdu->datalen); - offset += apdu->datalen; - } + LOG_TEST_RET(reader->ctx, + sc_apdu2bytes(reader->ctx, apdu, + reader->active_protocol, pin_modify->abData, + SC_MAX_APDU_BUFFER_SIZE), + "Could not encode PIN APDU"); + offset += sc_apdu_get_length(apdu, reader->active_protocol); pin_modify->ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */ From 45be3da23fd5e53b1892cae0945f0debb8416a76 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Aug 2017 23:49:45 +0200 Subject: [PATCH 0092/4321] win32: fixed OpenSC major/minor version --- win32/winconfig.h.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index aac13eeb16..0f685c77d5 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -69,11 +69,11 @@ #endif #ifndef OPENSC_VERSION_MAJOR -#define OPENSC_VERSION_MAJOR "@OPENSC_VERSION_MAJOR@" +#define OPENSC_VERSION_MAJOR @OPENSC_VERSION_MAJOR@ #endif #ifndef OPENSC_VERSION_MINOR -#define OPENSC_VERSION_MINOR "@OPENSC_VERSION_MINOR@" +#define OPENSC_VERSION_MINOR @OPENSC_VERSION_MINOR@ #endif #ifndef OPENSC_VS_FF_COMPANY_NAME From f4946df4e9ee31f1b56b9be4708ca3a9641f525e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 3 Aug 2017 17:02:03 +0200 Subject: [PATCH 0093/4321] fixed dead assignments --- src/libopensc/reader-tr03119.c | 2 -- src/pkcs15init/pkcs15-entersafe.c | 4 +++- src/pkcs15init/pkcs15-epass2003.c | 8 ++++++-- src/pkcs15init/pkcs15-isoApplet.c | 4 ++-- src/pkcs15init/pkcs15-muscle.c | 6 ++++-- src/pkcs15init/pkcs15-oberthur.c | 2 +- src/pkcs15init/pkcs15-westcos.c | 2 +- src/sm/sm-eac.c | 3 +++ src/tests/lottery.c | 2 +- src/tools/npa-tool.c | 11 ++++++----- src/tools/pkcs15-crypt.c | 2 +- 11 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index c3d2dcc5e3..a62deca28d 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -659,8 +659,6 @@ static int escape_perform_verify(struct sc_reader *reader, } apdu.lc = apdu.datalen; - r = SC_SUCCESS; - r = reader->ops->transmit(reader, &apdu); if (r < 0) { sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 712a02f397..468bd6a5a1 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -292,6 +292,8 @@ static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card data.key_data.symmetric.key_len=16; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); + if (r < 0) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); /* Cache new PIN value. */ sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len); @@ -316,7 +318,7 @@ static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 786a712588..9a365a4bbf 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -122,6 +122,8 @@ static int epass2003_pkcs15_create_dir(struct sc_profile *profile, "Get SKey info failed"); ret = sc_create_file(card, skey_file); sc_file_free(skey_file); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + "Create SKey info failed"); ret = sc_profile_get_file(profile, "MAXPIN", &ef_file); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, @@ -250,6 +252,8 @@ static int epass2003_pkcs15_create_pin(struct sc_profile *profile, data.key_data.es_secret.key_len = pin_len; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); + if (r < 0) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); if (pin_obj) { /* Cache new PIN value. */ sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len); @@ -444,7 +448,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, sc_print_path(&(file->path))); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key_info path: %s", sc_print_path(&(key_info->path))); - r = sc_delete_file(p15card->card, &file->path); + sc_delete_file(p15card->card, &file->path); /* create */ r = sc_pkcs15init_create_file(profile, p15card, file); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, @@ -528,7 +532,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "generate key: pkcs15init_authenticate(SC_AC_OP_DELETE) failed"); - r = sc_delete_file(p15card->card, &file->path); + sc_delete_file(p15card->card, &file->path); /* create */ r = sc_pkcs15init_create_file(profile, p15card, file); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index a49bf938ca..78d88e6815 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -609,7 +609,7 @@ isoApplet_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Authentication stuff. */ r = sc_profile_get_file_by_path(profile, &key_info->path, &privKeyFile); - if(!privKeyFile) + if(r < 0 || !privKeyFile) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); } @@ -692,7 +692,7 @@ isoApplet_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_ /* Authentication stuff. */ r = sc_profile_get_file_by_path(profile, &key_info->path, &privKeyFile); - if(!privKeyFile) + if(r < 0 || !privKeyFile) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); } diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index bcd4fd314b..93d3b8f9cd 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -177,7 +177,8 @@ muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Verification stuff */ /* Used for verification AND for obtaining private key acls */ r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf); - if(!prkf) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); + if (r < 0 || !prkf) + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO); if (r < 0) { sc_file_free(prkf); @@ -241,7 +242,8 @@ muscle_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Verification stuff */ /* Used for verification AND for obtaining private key acls */ r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf); - if(!prkf) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); + if(r < 0 || !prkf) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO); if (r < 0) { sc_file_free(prkf); diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index f090cd5eb7..76f21d63e2 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -182,7 +182,7 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file ddf %04X",df->id); - rv = cosm_delete_file(p15card, profile, df); + cosm_delete_file(p15card, profile, df); if (sc_profile_get_file(profile, "private-DF", &dir) >= 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file dir %04X",dir->id); diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 4f0632065b..194d6deb4d 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -60,7 +60,7 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile, int r; /* Create the application DF */ - r = sc_pkcs15init_create_file(profile, p15card, df); + sc_pkcs15init_create_file(profile, p15card, df); r = sc_select_file(p15card->card, &df->path, NULL); if(r) return r; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 4c66ff764a..3be597241e 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -576,6 +576,8 @@ static int npa_mse_set_at_pace(sc_card_t *card, int protocol, r = npa_mse_set_at(card, 0xC1, protocol, &key, sizeof key, NULL, 0, NULL, 0, NULL, 0, chat, sw1, sw2); + if (0 > r) + goto err; if (*sw1 == 0x63) { if ((*sw2 & 0xc0) == 0xc0) { @@ -599,6 +601,7 @@ static int npa_mse_set_at_pace(sc_card_t *card, int protocol, r = sc_check_sw(card, *sw1, *sw2); } +err: return r; } diff --git a/src/tests/lottery.c b/src/tests/lottery.c index c64f093c8e..b330784afe 100644 --- a/src/tests/lottery.c +++ b/src/tests/lottery.c @@ -24,7 +24,7 @@ int main(int argc, char *argv[]) struct timeval tv1, tv2; u8 buf[14]; - i = sc_test_init(&argc, argv); + sc_test_init(&argc, argv); for (i = 0; i < 39; i++) freq[i] = 0; c = 0; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 4f2a5d0a41..3608a5e483 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -390,12 +390,13 @@ main (int argc, char **argv) pin = getenv("PIN"); puk = getenv("PUK"); newpin = getenv("NEWPIN"); + } else { + can = cmdline.can_arg; + mrz = cmdline.mrz_arg; + pin = cmdline.pin_arg; + puk = cmdline.puk_arg; + newpin = cmdline.new_pin_arg; } - can = cmdline.can_arg; - mrz = cmdline.mrz_arg; - pin = cmdline.pin_arg; - puk = cmdline.puk_arg; - newpin = cmdline.new_pin_arg; if (cmdline.chat_given) { pace_input.chat = chat; pace_input.chat_length = sizeof chat; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 05ee99a194..52dc853be0 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -285,7 +285,7 @@ static int decipher(struct sc_pkcs15_object *obj) } r = write_output(out, r); - return 0; + return r; } static int get_key(unsigned int usage, sc_pkcs15_object_t **result) From 1b880b5675fbfa7dd949c958ccb988a8e1712ea2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 Aug 2017 01:02:17 +0200 Subject: [PATCH 0094/4321] fixed uninitialized buffer --- src/libopensc/card-cardos.c | 2 ++ src/libopensc/card-gids.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 4d2ad6f3f4..5dfc6d79a9 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -599,6 +599,8 @@ static int cardos_construct_fcp(sc_card_t *card, const sc_file_t *file, /* we will add the length later */ p++; + memset(buf, 0, sizeof(buf)); + /* set the length */ buf[0] = (file->size >> 8) & 0xff; buf[1] = file->size & 0xff; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index a10de90295..c9a1c350c8 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -743,6 +743,7 @@ static int gids_set_security_env(sc_card_t *card, assert(card != NULL && env != NULL); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + memset(sbuf, 0, sizeof(sbuf)); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_MANAGE_SECURITY_ENVIRONMENT, P1_DECIPHERMENT_INTERNAL_AUTHENTICATE_KEY_AGREEMENT, 0); switch (env->operation) { From 4251a362b52afab1195135f4ced7bd0c8f5ec970 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 Aug 2017 07:08:52 +0200 Subject: [PATCH 0095/4321] fixed potential memory leak --- src/common/simclist.c | 6 ++++ src/libopensc/pkcs15-sc-hsm.c | 2 +- src/libopensc/pkcs15.c | 6 ++-- src/pkcs11/mechanism.c | 11 ++++++-- src/pkcs15init/pkcs15-lib.c | 9 ++++-- src/pkcs15init/pkcs15-oberthur-awp.c | 41 ++++++++++++++-------------- src/scconf/parse.c | 1 + 7 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/common/simclist.c b/src/common/simclist.c index c8e87ccaba..e22c236771 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -489,6 +489,12 @@ int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int p /* actually append element */ prec = list_findpos(l, pos-1); if (prec == NULL) { + if (l->attrs.copy_data) { + free(lent->data); + } + if (!(l->spareelsnum > 0)) { + free(lent); + } return -1; } succ = prec->next; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index dd428fac5f..0a7d4c2db3 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -191,7 +191,7 @@ static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2], path.aid = sc_hsm_aid; /* we don't have a pre-known size of the file */ path.count = -1; - if (!p15card->opts.use_file_cache + if (!p15card->opts.use_file_cache || !efbin || SC_SUCCESS != sc_pkcs15_read_cached_file(p15card, &path, &efbin, len)) { /* avoid re-selection of SC-HSM */ path.aid.len = 0; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index d136021b1a..c520cd504c 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2362,7 +2362,8 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat if (r) { r = sc_lock(p15card->card); - LOG_TEST_RET(ctx, r, "sc_lock() failed"); + if (r) + goto fail; r = sc_select_file(p15card->card, in_path, &file); if (r) goto fail_unlock; @@ -2442,9 +2443,10 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat LOG_FUNC_RETURN(ctx, SC_SUCCESS); fail_unlock: + sc_unlock(p15card->card); +fail: free(data); sc_file_free(file); - sc_unlock(p15card->card); LOG_FUNC_RETURN(ctx, r); } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index f3ab284a15..9082d37add 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1041,6 +1041,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, sc_pkcs11_mechanism_type_t *hash_type, *new_type; struct hash_signature_info *info; CK_MECHANISM_INFO mech_info = sign_type->mech_info; + CK_RV rv; if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST))) return CKR_MECHANISM_INVALID; @@ -1060,9 +1061,15 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_type, info, free_info); if (!new_type) { - free(info); + free_info(info); return CKR_HOST_MEMORY; } - return sc_pkcs11_register_mechanism(p11card, new_type); + rv = sc_pkcs11_register_mechanism(p11card, new_type); + if (CKR_OK != rv) { + new_type->free_mech_data(new_type->mech_data); + free(new_type); + } + + return rv; } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 5dfe2be6b5..52544f13a3 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -903,11 +903,16 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); if (r >= 0) { r = sc_pkcs15init_update_dir(p15card, profile, app); - if (r >= 0) + if (r >= 0) { r = sc_pkcs15init_update_tokeninfo(p15card, profile); - /* FIXME: what to do if sc_pkcs15init_update_dir failed? */ + } else { + /* FIXME: what to do if sc_pkcs15init_update_dir failed? */ + free(app->label); + free(app); /* unused */ + } } else { + free(app->label); free(app); /* unused */ } diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index f55f3d33b5..7589d146c9 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -831,12 +831,9 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj static void awp_free_key_info(struct awp_key_info *ki) { - if (ki->modulus.value) - free(ki->modulus.value); - if (ki->exponent.value) - free(ki->exponent.value); - if (ki->id.value) - free(ki->id.value); + free(ki->modulus.value); + free(ki->exponent.value); + free(ki->id.value); } @@ -1072,22 +1069,24 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob static void awp_free_cert_info(struct awp_cert_info *ci) { - if (ci->cn.len && ci->cn.value) - free(ci->cn.value); + if (ci) { + if (ci->cn.len && ci->cn.value) + free(ci->cn.value); - if (ci->id.len && ci->id.value) - free(ci->id.value); + if (ci->id.len && ci->id.value) + free(ci->id.value); - if (ci->subject.len && ci->subject.value) - free(ci->subject.value); + if (ci->subject.len && ci->subject.value) + free(ci->subject.value); - if (ci->issuer.len && ci->issuer.value) - free(ci->issuer.value); + if (ci->issuer.len && ci->issuer.value) + free(ci->issuer.value); - if (ci->x509) - X509_free(ci->x509); + if (ci->x509) + X509_free(ci->x509); - memset(ci,0,sizeof(struct awp_cert_info)); + memset(ci,0,sizeof(struct awp_cert_info)); + } } @@ -1495,8 +1494,8 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p sc_file_free(info_file); if (cert_obj) awp_free_cert_info(&icert); - awp_free_key_info(&ikey); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); } @@ -1521,6 +1520,8 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p index = path.value[path.len-1] & 0xFF; obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; + memset(&ikey, 0, sizeof(ikey)); + rv = awp_new_file(p15card, profile, obj->type, index, &info_file, NULL); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "New public key info file error"); @@ -1530,7 +1531,6 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: decode public key error"); - memset(&ikey, 0, sizeof(ikey)); rv = awp_encode_key_info(p15card, obj, &pubkey.u.rsa, &ikey); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: encode info error"); @@ -1543,9 +1543,8 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = awp_update_container(p15card, profile, obj->type, &ikey.id, obj_id, NULL); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: update container error"); - awp_free_key_info(&ikey); - err: + awp_free_key_info(&ikey); sc_file_free(info_file); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); } diff --git a/src/scconf/parse.c b/src/scconf/parse.c index c8bf141961..b32f0e8ef2 100644 --- a/src/scconf/parse.c +++ b/src/scconf/parse.c @@ -166,6 +166,7 @@ scconf_item *scconf_item_add(scconf_context * config, scconf_block * block, scco } } else { /* FIXME is it an error if item is NULL? */ + free(parser.key); } return parser.current_item; } From 854123c75e03b0ea5825dcd6734282be2767e4ad Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Oct 2017 19:11:15 +0200 Subject: [PATCH 0096/4321] fixed binary comparison --- src/libopensc/card-gids.c | 2 +- src/libopensc/card-jcop.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index c9a1c350c8..d47cf371b0 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1053,7 +1053,7 @@ gids_get_container_detail(sc_card_t* card, sc_cardctl_gids_get_container_t* cont memset(container, 0, sizeof(sc_cardctl_gids_get_container_t)); container->containernum = num; - if (!records[num].bFlags & CONTAINER_MAP_VALID_CONTAINER) { + if (!(records[num].bFlags & CONTAINER_MAP_VALID_CONTAINER)) { return SC_SUCCESS; } // ignore problematic containers diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index a87ea4e4a3..f522a59e57 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -655,7 +655,7 @@ static int jcop_set_security_env(sc_card_t *card, return SC_ERROR_INVALID_ARGUMENTS; } apdu.le = 0; - if (!env->flags & SC_SEC_ENV_ALG_REF_PRESENT) + if (!(env->flags & SC_SEC_ENV_ALG_REF_PRESENT)) return SC_ERROR_INVALID_ARGUMENTS; if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT)) return SC_ERROR_INVALID_ARGUMENTS; From d4befcc2e5f364b2908a89bad9fd99d8860adf63 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Oct 2017 16:49:50 +0200 Subject: [PATCH 0097/4321] fixed unused dependency --- src/common/Makefile.mak | 2 +- src/pkcs11/Makefile.mak | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Makefile.mak b/src/common/Makefile.mak index 82273080fd..a777eea291 100644 --- a/src/common/Makefile.mak +++ b/src/common/Makefile.mak @@ -9,7 +9,7 @@ all: common.lib libpkcs11.lib libscdl.lib common.lib: $(COMMON_OBJECTS) lib $(LIBFLAGS) /out:common.lib $(COMMON_OBJECTS) -libpkcs11.lib: libpkcs11.obj libscdl.obj +libpkcs11.lib: libpkcs11.obj lib $(LIBFLAGS) /out:libpkcs11.lib libpkcs11.obj libscdl.lib: libscdl.obj diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index 1aeb9e66bc..dab3791477 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -27,5 +27,5 @@ $(TARGET2): $(OBJECTS) $(LIBS) if EXIST $(TARGET2).manifest mt -manifest $(TARGET2).manifest -outputresource:$(TARGET2);2 $(TARGET3): $(OBJECTS3) $(LIBS3) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib advapi32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib if EXIST $(TARGET3).manifest mt -manifest $(TARGET3).manifest -outputresource:$(TARGET3);2 From 3693a96911e1dc633fa9690eb1b5d9f8974ca224 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Oct 2017 16:54:18 +0200 Subject: [PATCH 0098/4321] win32: don't link static libs into static libs --- src/libopensc/Makefile.mak | 4 ++-- src/minidriver/Makefile.mak | 12 +++++++++--- src/pkcs11/Makefile.mak | 15 ++++++++++++--- src/smm/Makefile.mak | 14 ++++++++++++-- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index ac1564d326..26760ae22d 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -58,5 +58,5 @@ opensc.dll: $(OBJECTS) $(LIBS) link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib if EXIST opensc.dll.manifest mt -manifest opensc.dll.manifest -outputresource:opensc.dll;2 -opensc_a.lib: $(OBJECTS) $(LIBS) - lib $(LIBFLAGS) /out:opensc_a.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib +opensc_a.lib: $(OBJECTS) + lib $(LIBFLAGS) /out:opensc_a.lib $(OBJECTS) diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index da4c66f12d..c63232bc71 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -3,8 +3,14 @@ TOPDIR = ..\.. TARGET = opensc-minidriver.dll OBJECTS = minidriver.obj versioninfo-minidriver.res LIBS = $(TOPDIR)\src\libopensc\opensc_a.lib \ - $(TOPDIR)\src\pkcs15init\pkcs15init.lib \ - $(TOPDIR)\src\common\libscdl.lib + $(TOPDIR)\src\scconf\scconf.lib \ + $(TOPDIR)\src\common\common.lib \ + $(TOPDIR)\src\common\libscdl.lib \ + $(TOPDIR)\src\ui\strings.lib \ + $(TOPDIR)\src\ui\notify.lib \ + $(TOPDIR)\src\sm\libsmiso.lib \ + $(TOPDIR)\src\sm\libsmeac.lib \ + $(TOPDIR)\src\pkcs15init\pkcs15init.lib all: $(TARGET) @@ -14,5 +20,5 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib /DELAYLOAD:bcrypt.dll if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index dab3791477..a420fa2aae 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -9,7 +9,16 @@ OBJECTS = pkcs11-global.obj pkcs11-session.obj pkcs11-object.obj misc.obj slot debug.obj pkcs11-display.obj versioninfo-pkcs11.res OBJECTS3 = pkcs11-spy.obj pkcs11-display.obj versioninfo-pkcs11-spy.res -LIBS = $(TOPDIR)\src\libopensc\opensc_a.lib $(TOPDIR)\src\pkcs15init\pkcs15init.lib +LIBS = $(TOPDIR)\src\libopensc\opensc_a.lib \ + $(TOPDIR)\src\pkcs15init\pkcs15init.lib \ + $(TOPDIR)\src\scconf\scconf.lib \ + $(TOPDIR)\src\common\common.lib \ + $(TOPDIR)\src\common\libscdl.lib \ + $(TOPDIR)\src\ui\strings.lib \ + $(TOPDIR)\src\ui\notify.lib \ + $(TOPDIR)\src\sm\libsmiso.lib \ + $(TOPDIR)\src\sm\libsmeac.lib \ + $(TOPDIR)\src\pkcs15init\pkcs15init.lib LIBS3 = $(TOPDIR)\src\common\libpkcs11.lib $(TOPDIR)\src\common\libscdl.lib $(TOPDIR)\src\common\common.lib all: $(TARGET1) $(TARGET2) $(TARGET3) @@ -17,13 +26,13 @@ all: $(TARGET1) $(TARGET2) $(TARGET3) !INCLUDE $(TOPDIR)\win32\Make.rules.mak $(TARGET1): $(OBJECTS) $(LIBS) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib if EXIST $(TARGET1).manifest mt -manifest $(TARGET1).manifest -outputresource:$(TARGET1);2 $(TARGET2): $(OBJECTS) $(LIBS) del pkcs11-global.obj cl $(CODE_OPTIMIZATION) $(COPTS) /DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" /c pkcs11-global.c - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib if EXIST $(TARGET2).manifest mt -manifest $(TARGET2).manifest -outputresource:$(TARGET2);2 $(TARGET3): $(OBJECTS3) $(LIBS3) diff --git a/src/smm/Makefile.mak b/src/smm/Makefile.mak index a50ccbc3b9..a0dbbdc647 100644 --- a/src/smm/Makefile.mak +++ b/src/smm/Makefile.mak @@ -3,7 +3,17 @@ TOPDIR = ..\.. TARGET = smm-local.dll OBJECTS = smm-local.obj sm-global-platform.obj sm-cwa14890.obj sm-card-iasecc.obj sm-card-authentic.obj -LIBS = $(TOPDIR)\src\sm\libsm.lib $(TOPDIR)\src\libopensc\opensc_a.lib $(TOPDIR)\src\common\libscdl.lib +LIBS = $(TOPDIR)\src\sm\libsm.lib \ + $(TOPDIR)\src\libopensc\opensc_a.lib \ + $(TOPDIR)\src\pkcs15init\pkcs15init.lib \ + $(TOPDIR)\src\scconf\scconf.lib \ + $(TOPDIR)\src\common\common.lib \ + $(TOPDIR)\src\common\libscdl.lib \ + $(TOPDIR)\src\ui\strings.lib \ + $(TOPDIR)\src\ui\notify.lib \ + $(TOPDIR)\src\sm\libsmiso.lib \ + $(TOPDIR)\src\sm\libsmeac.lib \ + $(TOPDIR)\src\pkcs15init\pkcs15init.lib all: $(TARGET) @@ -14,7 +24,7 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type $*.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 !ELSE From 385a0392ce610980d64e4453ee462e67dc0e7a15 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 28 Oct 2017 00:11:21 +0200 Subject: [PATCH 0099/4321] msvc: disable type truncation warnings --- win32/winconfig.h.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index 0f685c77d5..3aa2beec11 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -7,6 +7,13 @@ #include #include +#ifdef _MSC_VER +// TODO fix data truncation instead of disabling them +// VC++ 2015 changes truncation warnings from 4244 to 4267. +#pragma warning (disable : 4267) +#pragma warning (disable : 4244) +#endif + #ifndef strcasecmp #define strcasecmp stricmp #endif From 08ca27197aab4290798616aab08d0c7aea130cdf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 28 Oct 2017 08:26:17 +0200 Subject: [PATCH 0100/4321] treat warnings as errors --- configure.ac | 2 +- win32/Make.rules.mak | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index af5b257091..c25c21bcb4 100644 --- a/configure.ac +++ b/configure.ac @@ -1022,7 +1022,7 @@ if test "${enable_pedantic}" = "yes"; then CFLAGS="${CFLAGS} -pedantic -Wextra" fi if test "${enable_strict}" = "yes"; then - CFLAGS="${CFLAGS} -Wall -Wextra -Wno-unused-parameter" + CFLAGS="${CFLAGS} -Wall -Wextra -Wno-unused-parameter -Werror" fi if test "$GCC" = "yes"; then # This should be resolved not ignored. diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 39ef8ec399..fa9d5917c4 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -137,10 +137,10 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" !ENDIF From 7d0f05b247649bbf3bdeca4cdbd004854a273761 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 28 Oct 2017 22:00:32 +0200 Subject: [PATCH 0101/4321] removed unused compile options --- configure.ac | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index c25c21bcb4..8a305f24d2 100644 --- a/configure.ac +++ b/configure.ac @@ -255,13 +255,6 @@ AC_ARG_ENABLE( [enable_notify="detect"] ) -AC_ARG_ENABLE( - [werror-declaration-after-statement], - [AS_HELP_STRING([--disable-werror-declaration-after-statement],[disable -Werror 'declaration-after-statement' @<:@enabled@:>@])], - , - [werror_declaration_after_statement="yes"] -) - AC_ARG_WITH( [xsl-stylesheetsdir], [AS_HELP_STRING([--with-xsl-stylesheetsdir=PATH],[docbook xsl-stylesheets for svn build @<:@detect@:>@])], @@ -1019,19 +1012,11 @@ AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) if test "${enable_pedantic}" = "yes"; then enable_strict="yes"; - CFLAGS="${CFLAGS} -pedantic -Wextra" + CFLAGS="${CFLAGS} -pedantic" fi if test "${enable_strict}" = "yes"; then CFLAGS="${CFLAGS} -Wall -Wextra -Wno-unused-parameter -Werror" fi -if test "$GCC" = "yes"; then - # This should be resolved not ignored. - CFLAGS="-fno-strict-aliasing ${CFLAGS}" -fi - -if test "${werror_declaration_after_statement}" = "yes"; then - CFLAGS="${CFLAGS} -Werror=declaration-after-statement" -fi AC_CONFIG_FILES([ Makefile From 10101984dacdf2fcd3ecb8fc099c7f185b4d5a94 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 28 Oct 2017 23:29:50 +0200 Subject: [PATCH 0102/4321] fixed dereferencing type-punned pointer --- src/libopensc/reader-pcsc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 20eaf30cef..6075dc0614 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1219,11 +1219,10 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) reader->vendor = strdup((char *) rbuf); } - rcount = sizeof rbuf; + rcount = sizeof i; if(gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_IFD_VERSION, - rbuf, &rcount) == SCARD_S_SUCCESS - && rcount == 4) { - i = *(DWORD *) rbuf; + (u8 *) &i, &rcount) == SCARD_S_SUCCESS + && rcount == sizeof i) { reader->version_major = (i >> 24) & 0xFF; reader->version_minor = (i >> 16) & 0xFF; } From 3ca6c4b04a425d863a48cd7687e3f8d62b82cb52 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Oct 2017 16:32:57 +0100 Subject: [PATCH 0103/4321] fixed possible NULL dereference --- src/libopensc/asn1.c | 68 ++++++++++++++++++++++--------------- src/libopensc/pkcs15-pin.c | 4 +-- src/pkcs15init/pkcs15-lib.c | 4 +++ 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 93d80b7a4f..cf035ea943 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1609,44 +1609,56 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr break; case SC_ASN1_BIT_STRING_NI: case SC_ASN1_BIT_STRING: - assert(len != NULL); - if (entry->type == SC_ASN1_BIT_STRING) - r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1); - else - r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0); + if (len != NULL) { + if (entry->type == SC_ASN1_BIT_STRING) + r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1); + else + r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0); + } else { + r = SC_ERROR_INVALID_ARGUMENTS; + } break; case SC_ASN1_BIT_FIELD: - assert(len != NULL); - r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen); + if (len != NULL) { + r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen); + } else { + r = SC_ERROR_INVALID_ARGUMENTS; + } break; case SC_ASN1_PRINTABLESTRING: case SC_ASN1_OCTET_STRING: case SC_ASN1_UTF8STRING: - assert(len != NULL); - buf = malloc(*len + 1); - if (buf == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - break; - } - buflen = 0; - /* If the integer is supposed to be unsigned, insert - * a padding byte if the MSB is one */ - if ((entry->flags & SC_ASN1_UNSIGNED) - && (((u8 *) parm)[0] & 0x80)) { - buf[buflen++] = 0x00; + if (len != NULL) { + buf = malloc(*len + 1); + if (buf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + break; + } + buflen = 0; + /* If the integer is supposed to be unsigned, insert + * a padding byte if the MSB is one */ + if ((entry->flags & SC_ASN1_UNSIGNED) + && (((u8 *) parm)[0] & 0x80)) { + buf[buflen++] = 0x00; + } + memcpy(buf + buflen, parm, *len); + buflen += *len; + } else { + r = SC_ERROR_INVALID_ARGUMENTS; } - memcpy(buf + buflen, parm, *len); - buflen += *len; break; case SC_ASN1_GENERALIZEDTIME: - assert(len != NULL); - buf = malloc(*len); - if (buf == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - break; + if (len != NULL) { + buf = malloc(*len); + if (buf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + break; + } + memcpy(buf, parm, *len); + buflen = *len; + } else { + r = SC_ERROR_INVALID_ARGUMENTS; } - memcpy(buf, parm, *len); - buflen = *len; break; case SC_ASN1_OBJECT: r = sc_asn1_encode_object_id(&buf, &buflen, (struct sc_object_id *) parm); diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index f59802782e..4e807be907 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -449,13 +449,13 @@ int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card, sc_log(ctx, "PIN cmd result %i", r); if (r == SC_SUCCESS) { sc_pkcs15_pincache_add(p15card, pin_obj, pincode, pinlen); - if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN) { + if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN && sessionpinlen) { *sessionpinlen = data.pin2.len; } } else { sc_notify_id(card->ctx, &card->reader->atr, p15card, NOTIFY_PIN_BAD); - if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN) { + if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN && sessionpinlen) { *sessionpinlen = 0; } } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 52544f13a3..e98ababc24 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3880,6 +3880,10 @@ sc_pkcs15init_create_file(struct sc_profile *profile, struct sc_pkcs15_card *p15 int r; LOG_FUNC_CALLED(ctx); + if (!file) { + return SC_ERROR_INVALID_ARGUMENTS; + } + sc_log(ctx, "create file '%s'", sc_print_path(&file->path)); /* Select parent DF and verify PINs/key as necessary */ r = do_select_parent(profile, p15card, file, &parent); From 17132b04c7efc0913485b7d8cc530b5fd7014070 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Oct 2017 16:42:02 +0100 Subject: [PATCH 0104/4321] fixed possible bad memory access --- src/pkcs15init/pkcs15-oberthur-awp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 7589d146c9..a2696e31ae 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1433,6 +1433,7 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); memset(&ikey, 0, sizeof(ikey)); + memset(&icert, 0, sizeof(icert)); key_info = (struct sc_pkcs15_prkey_info *)key_obj->data; der = key_obj->content; From a332f72b385e7eeddaeb2df0aab10be5e3081a4f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Oct 2017 09:29:05 +0100 Subject: [PATCH 0105/4321] honor return values of read and sscanf --- src/ui/notify.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index 9cb7ac5954..12def1680c 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -26,6 +26,7 @@ #if defined(ENABLE_NOTIFY) && (defined(__APPLE__) || (defined(GDBUS) && !defined(_WIN32))) +#include "libopensc/internal.h" #include "libopensc/log.h" #include #include @@ -452,12 +453,16 @@ static void notify_gio(struct sc_context *ctx, } if (pass_to_pipe) { + ssize_t r; /* close the write end of the pipe */ close(pipefd[1]); memset(message_id_str, '\0', sizeof message_id_str); - if (0 < read(pipefd[0], message_id_str, sizeof(message_id_str))) { - message_id_str[(sizeof message_id_str) - 1] = '\0'; - sscanf(message_id_str, "(uint32 %"SCNu32",)", &message_id); + r = read(pipefd[0], message_id_str, sizeof(message_id_str)); + if (0 < r) { + message_id_str[MIN((sizeof message_id_str) - 1, (size_t) r)] = '\0'; + if (0 >= sscanf(message_id_str, "(uint32 %"SCNu32",)", &message_id)) { + message_id = 0; + } } /* close the read end of the pipe */ close(pipefd[0]); From 9c025280a68b6666db374e129114d9852433d067 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Oct 2017 09:31:29 +0100 Subject: [PATCH 0106/4321] avoid integer underflow --- src/libopensc/card-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index e415a12a47..69d1cc9c71 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -190,7 +190,7 @@ static int sc_hsm_select_file_ex(sc_card_t *card, return rv; } - if ((in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) { + if ((in_path->len >= 2) && (in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) { // The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF if (in_path->len == 2) { file = sc_file_new(); From 1d0300022277d12fcbfacd0e281a439bf93ad32b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Oct 2017 10:12:12 +0100 Subject: [PATCH 0107/4321] fixed dead assignment --- src/libopensc/card-asepcos.c | 3 --- src/libopensc/card-gids.c | 1 - src/libopensc/card-jpki.c | 7 +++---- src/libopensc/card-myeid.c | 2 +- src/libopensc/card-piv.c | 6 +++--- src/libopensc/muscle.c | 5 +++-- src/libopensc/pkcs15-esinit.c | 2 ++ src/libopensc/pkcs15-gemsafeGPK.c | 6 ++++-- src/libopensc/pkcs15-iasecc.c | 1 - src/libopensc/pkcs15-infocamere.c | 2 +- src/libopensc/pkcs15-openpgp.c | 11 +++++++---- src/libopensc/pkcs15-starcert.c | 2 ++ src/libopensc/pkcs15-westcos.c | 2 ++ src/tools/eidenv.c | 2 ++ src/tools/openpgp-tool.c | 4 ++++ src/tools/opensc-notify-cmdline.c | 2 -- 16 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 76d4396be5..efb4d3fd19 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -971,7 +971,6 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, } if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { /* unable to verify the old PIN */ - r = sc_check_sw(card, apdu.sw1, apdu.sw2); break; } /* 2, step: use CHANGE KEY to update the PIN */ @@ -981,7 +980,6 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); break; case SC_PIN_CMD_UNBLOCK: if (pdata->pin_type != SC_AC_CHV) @@ -1008,7 +1006,6 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); break; } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); break; default: sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error: unknow cmd type"); diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index d47cf371b0..7fa1b2f312 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1259,7 +1259,6 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } // else can be empty if not record - keymaprecordnum = 0; keymapbuffersize = 0; } else { keymaprecordnum = (keymapbuffersize - 1) / sizeof(struct gids_keymap_record); diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 5fed179e7e..3996b40849 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -82,11 +82,10 @@ jpki_finish(sc_card_t * card) struct jpki_private_data *drvdata = JPKI_DRVDATA(card); LOG_FUNC_CALLED(card->ctx); - if (drvdata->mf) { - free(drvdata->mf); - drvdata->mf = NULL; - } if (drvdata) { + if (drvdata->mf) { + free(drvdata->mf); + } free(drvdata); card->drv_data = NULL; } diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index b276040a6a..b7dafed7b7 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -925,6 +925,7 @@ myeid_compute_raw_2048_signature(struct sc_card *card, const u8 * data, size_t d apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { /* prepare 2nd part of data */ sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); @@ -1270,7 +1271,6 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) if(mode == LOAD_KEY_MODULUS && value_len >= 256) { - r=0; if((value_len % 2) > 0 && value[0] == 0x00) { value_len--; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 6f492fcc05..d3122ac1e1 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3122,12 +3122,12 @@ static int piv_init(sc_card_t *card) * We want to process them now as this has information on what * keys and certs the card has and how the pin might be used. */ - r = piv_process_history(card); + piv_process_history(card); r = piv_process_discovery(card); - if (r > 0) r = 0; + LOG_FUNC_RETURN(card->ctx, r); } @@ -3294,7 +3294,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) /* if access to applet is know to be reset by other driver we select_aid and try again */ if ( priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) { sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd"); - r = piv_find_aid(card, priv->aid_file); /* return not tested */ + piv_find_aid(card, priv->aid_file); /* return not tested */ priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ r = iso_drv->ops->pin_cmd(card, data, tries_left); diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 78f06fbae1..311edd9016 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -788,10 +788,11 @@ static int msc_compute_crypt_final_object( SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { r = msc_read_object(card, inputId, 2, outputData, dataLength); - *outputDataLength = dataLength; + if (r >= 0) + *outputDataLength = r; msc_delete_object(card, outputId, 0); msc_delete_object(card, inputId, 0); - return 0; + return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index e4749461b3..2124a50543 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -55,6 +55,8 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index 0b8185db1e..d3f886b21f 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -225,9 +225,11 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); - if (r != SC_SUCCESS) - return SC_ERROR_INTERNAL; + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; p15card->tokeninfo->serial_number = strdup(buf); /* test if we have a gemsafe app df */ diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index d291ccc8d4..d891fadef5 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -60,7 +60,6 @@ _iasecc_md_update_keyinfo(struct sc_pkcs15_card *p15card, struct sc_pkcs15_objec LOG_TEST_RET(ctx, rv, "Failed to read container DATA object data"); offs = 0; - rv = SC_ERROR_INVALID_DATA; if (*(ddata->data + offs++) != 0x01) { sc_pkcs15_free_data_object(ddata); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index 63ffee134d..02c55ee36d 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -774,7 +774,7 @@ static int infocamere_1600_init(sc_pkcs15_card_t * p15card) /* return to MF */ sc_format_path("3F00", &path); - r = sc_select_file(card, &path, NULL); + sc_select_file(card, &path, NULL); return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 678dedf6c4..2505e079dc 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -369,12 +369,15 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } /* PKCS#15 DATA object from OpenPGP private DOs */ - r = sc_pkcs15emu_openpgp_add_data(p15card); + sc_pkcs15emu_openpgp_add_data(p15card); - return 0; +failed: + if (r < 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "Failed to initialize OpenPGP emulation: %s\n", + sc_strerror(r)); + } -failed: sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP emulation: %s\n", - sc_strerror(r)); return r; } diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 68f2eeeddf..1c4110a72c 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -164,6 +164,8 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 424ca0cd38..490e57399d 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -54,6 +54,8 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + if (r) + goto out; r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r) goto out; diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 7caaa1363c..b141f5d5a5 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -158,6 +158,8 @@ static void do_esteid(sc_card_t *card) /* print the counters */ for (i = 1; i <= 4; i++) { r = sc_read_record(card, i, buff, 128, SC_RECORD_BY_REC_NR); + if (r < 0) + goto out; key_used[i - 1] = 0xffffff - ((unsigned char) buff[0xc] * 65536 + (unsigned char) buff[0xd] * 256 + (unsigned char) buff[0xe]); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index e1fa256530..53bc5b64c2 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -449,6 +449,10 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) } sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); + if (r < 0) { + printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r)); + return 1; + } r = sc_read_binary(card, 0, fingerprints, 60, 0); if (r < 0) { printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r)); diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index bfdb3dd784..81c4b993dd 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -1072,7 +1072,6 @@ cmdline_parser_internal ( int override; int initialize; - int check_required; int check_ambiguity; char *optarg; @@ -1084,7 +1083,6 @@ cmdline_parser_internal ( override = params->override; initialize = params->initialize; - check_required = params->check_required; check_ambiguity = params->check_ambiguity; if (initialize) From 260716f968facaca03c2255a1fe38243668100e4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Oct 2017 10:12:20 +0100 Subject: [PATCH 0108/4321] fixed memory leak --- src/pkcs15init/pkcs15-openpgp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 4fcaec922a..0b4412e286 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -188,8 +188,10 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card /* The OpenPGP supports only 32-bit exponent. */ key_info.exponent_len = 32; key_info.exponent = calloc(key_info.exponent_len>>3, 1); /* 1/8 */ - if (key_info.exponent == NULL) + if (key_info.exponent == NULL) { + free(key_info.modulus); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + } r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); if (r < 0) From 4d5b73d8690775212e1c9df1bf09a058b245c058 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Oct 2017 10:18:35 +0100 Subject: [PATCH 0109/4321] fixed accessing garbage value --- src/libopensc/card-asepcos.c | 14 +++++++++----- src/libopensc/card-belpic.c | 10 +++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index efb4d3fd19..5fe360fff8 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -1014,12 +1014,16 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, /* Clear the buffer - it may contain pins */ sc_mem_clear(sbuf, sizeof(sbuf)); /* check for remaining tries if verification failed */ - if (apdu.sw1 == 0x63) { - if ((apdu.sw2 & 0xF0) == 0xC0 && tries_left != NULL) - *tries_left = apdu.sw2 & 0x0F; - return SC_ERROR_PIN_CODE_INCORRECT; + if (r == SC_SUCCESS) { + if (apdu.sw1 == 0x63) { + if ((apdu.sw2 & 0xF0) == 0xC0 && tries_left != NULL) + *tries_left = apdu.sw2 & 0x0F; + r = SC_ERROR_PIN_CODE_INCORRECT; + } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); } - return sc_check_sw(card, apdu.sw1, apdu.sw2); + + return r; } static struct sc_card_driver * sc_get_driver(void) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index c223189264..3642d629a5 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -917,8 +917,6 @@ static int belpic_init(sc_card_t *card) { struct belpic_priv_data *priv = NULL; scconf_block *conf_block; - u8 applet_version; - u8 carddata[BELPIC_CARDDATA_RESP_LEN]; int key_size = 1024; int r; @@ -940,15 +938,17 @@ static int belpic_init(sc_card_t *card) card->drv_data = priv; card->cla = 0x00; if (card->type == SC_CARD_TYPE_BELPIC_EID) { + u8 carddata[BELPIC_CARDDATA_RESP_LEN]; + memset(carddata, 0, sizeof(carddata)); + if((r = get_carddata(card, carddata, sizeof(carddata))) < 0) { return r; } - applet_version = carddata[BELPIC_CARDDATA_OFF_APPLETVERS]; - if(applet_version >= 0x17) { + if (carddata[BELPIC_CARDDATA_OFF_APPLETVERS] >= 0x17) { key_size = 2048; } _sc_card_add_rsa_alg(card, key_size, - SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); + SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); } /* State that we have an RNG */ From eacb53fc606f77adae82000b2f1a8c9c42830e6b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 18 Oct 2017 11:52:48 +0200 Subject: [PATCH 0110/4321] added boilerplate for disabling old card driver currently disabled: - miocos - jcop --- etc/opensc.conf.in | 5 ++++- src/libopensc/ctx.c | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 797cb4beeb..83b7deed98 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -143,6 +143,9 @@ app default { # from the output of: # $ opensc-tool --list-drivers # + # A special value of 'old' will load all + # statically linked drivers that may be removed in the future. + # # A special value of 'internal' will load all # statically linked drivers. If an unknown (ie. not # internal) driver is supplied, a separate configuration @@ -150,7 +153,7 @@ app default { # Default: internal # NOTE: When "internal" keyword is used, must be last entry # - card_drivers = npa, internal; + #card_drivers = old, internal; # Card driver configuration blocks. diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 21801712d5..629480c1db 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -76,11 +76,9 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "gpk", (void *(*)(void)) sc_get_gpk_driver }, #endif { "gemsafeV1", (void *(*)(void)) sc_get_gemsafeV1_driver }, - { "miocos", (void *(*)(void)) sc_get_miocos_driver }, { "asepcos", (void *(*)(void)) sc_get_asepcos_driver }, { "starcos", (void *(*)(void)) sc_get_starcos_driver }, { "tcos", (void *(*)(void)) sc_get_tcos_driver }, - { "jcop", (void *(*)(void)) sc_get_jcop_driver }, #ifdef ENABLE_OPENSSL { "oberthur", (void *(*)(void)) sc_get_oberthur_driver }, { "authentic", (void *(*)(void)) sc_get_authentic_driver }, @@ -129,6 +127,12 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { NULL, NULL } }; +static const struct _sc_driver_entry old_card_drivers[] = { + { "miocos", (void *(*)(void)) sc_get_miocos_driver }, + { "jcop", (void *(*)(void)) sc_get_jcop_driver }, + { NULL, NULL } +}; + struct _sc_ctx_options { struct _sc_driver_entry cdrv[SC_MAX_CARD_DRIVERS]; int ccount; @@ -256,6 +260,19 @@ static void add_internal_drvs(struct _sc_ctx_options *opts) } } +static void add_old_drvs(struct _sc_ctx_options *opts) +{ + const struct _sc_driver_entry *lst; + int i; + + lst = old_card_drivers; + i = 0; + while (lst[i].name != NULL) { + add_drv(opts, lst[i].name); + i++; + } +} + static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts) { ctx->debug = 0; @@ -316,7 +333,7 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * { int err = 0; const scconf_list *list; - const char *val, *s_internal = "internal"; + const char *val, *s_internal = "internal", *s_old = "old"; int debug; #ifdef _WIN32 char expanded_val[PATH_MAX]; @@ -372,6 +389,8 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * while (list != NULL) { if (strcmp(list->data, s_internal) == 0) add_internal_drvs(opts); + else if (strcmp(list->data, s_old) == 0) + add_old_drvs(opts); else add_drv(opts, list->data); list = list->next; @@ -507,11 +526,20 @@ static int load_card_drivers(sc_context_t *ctx, struct _sc_ctx_options *opts) } ent = &opts->cdrv[i]; - for (j = 0; internal_card_drivers[j].name != NULL; j++) + for (j = 0; internal_card_drivers[j].name != NULL; j++) { if (strcmp(ent->name, internal_card_drivers[j].name) == 0) { func = (struct sc_card_driver *(*)(void)) internal_card_drivers[j].func; break; } + } + if (func == NULL) { + for (j = 0; old_card_drivers[j].name != NULL; j++) { + if (strcmp(ent->name, old_card_drivers[j].name) == 0) { + func = (struct sc_card_driver *(*)(void)) old_card_drivers[j].func; + break; + } + } + } /* if not initialized assume external module */ if (func == NULL) *(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name); From fd6882f686d802e56b69003af303ff7100d40a68 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 3 Nov 2017 10:55:35 +0100 Subject: [PATCH 0111/4321] Enable CAC ALT token card operations --- src/libopensc/card-cac.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 82f5c7869a..bc0a754a53 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -229,6 +229,12 @@ static int cac_add_object_to_list(list_t *list, const cac_object_t *object) #define CAC_1_RID "\xA0\x00\x00\x00\x79" #define CAC_1_CM_AID "\xA0\x00\x00\x00\x30\x00\00" +static const sc_path_t cac_ACA_Path = { + "", 0, + 0,0,SC_PATH_TYPE_DF_NAME, + { CAC_TO_AID(CAC_1_RID "\x10\x00") } +}; + static const sc_path_t cac_CCC_Path = { "", 0, 0,0,SC_PATH_TYPE_DF_NAME, @@ -284,6 +290,8 @@ static const cac_object_t cac_1_objects[] = { static const int cac_1_object_count = sizeof(cac_1_objects)/sizeof(cac_1_objects[0]); +static int cac_select_ACA(sc_card_t *card); + /* * use the object id to find our object info on the object in our CAC-1 list */ @@ -815,6 +823,8 @@ static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) case SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS: return cac_final_iterator(&priv->general_list); case SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS: + /* select ACA to be able to verify PIN */ + cac_select_ACA(card); return cac_final_iterator(&priv->pki_list); } @@ -1157,6 +1167,12 @@ static int cac_select_CCC(sc_card_t *card) return cac_select_file_by_type(card, &cac_CCC_Path, NULL, SC_CARD_TYPE_CAC_II); } +/* Select ACA in non-standard location */ +static int cac_select_ACA(sc_card_t *card) +{ + return cac_select_file_by_type(card, &cac_ACA_Path, NULL, SC_CARD_TYPE_CAC_II); +} + static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_t *val, int len) { if (len < 10) { @@ -1476,6 +1492,23 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) } } + /* Even some ALT tokens can be missing CCC so we should try with ACA */ + r = cac_select_ACA(card); + if (r == SC_SUCCESS) { + r = cac_find_first_pki_applet(card, &index); + if (r == SC_SUCCESS) { + priv = cac_new_private_data(); + if (!priv) + return SC_ERROR_OUT_OF_MEMORY; + r = cac_populate_cac_1(card, index, priv); + if (r == SC_SUCCESS) { + card->type = SC_CARD_TYPE_CAC_II; + card->drv_data = priv; + return r; + } + } + } + /* is this a CAC-1 specified in DoD "CAC Applet Developer Guide" version 1.0 September 2002 */ r = cac_find_first_pki_applet(card, &index); if (r == SC_SUCCESS) { From 07267df313fb0ade46d051aeaee09cd49a668bd4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 6 Nov 2017 12:37:40 +0100 Subject: [PATCH 0112/4321] Add the ACA path to the PIN structure if we have one --- src/libopensc/card-cac.c | 25 +++++++++++++++++++------ src/libopensc/cardctl.h | 1 + src/libopensc/pkcs15-cac.c | 6 ++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index bc0a754a53..178150d354 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -169,6 +169,7 @@ typedef struct cac_private_data { cac_object_t *pki_current; /* current pki object _ctl function */ list_t general_list; /* list of general containers */ cac_object_t *general_current; /* current object for _ctl function */ + sc_path_t *aca_path; /* ACA path to be selected before pin verification */ } cac_private_data_t; #define CAC_DATA(card) ((cac_private_data_t*)card->drv_data) @@ -207,6 +208,7 @@ static void cac_free_private_data(cac_private_data_t *priv) { free(priv->cac_id); free(priv->cache_buf); + free(priv->aca_path); list_destroy(&priv->pki_list); list_destroy(&priv->general_list); free(priv); @@ -289,9 +291,6 @@ static const cac_object_t cac_1_objects[] = { static const int cac_1_object_count = sizeof(cac_1_objects)/sizeof(cac_1_objects[0]); - -static int cac_select_ACA(sc_card_t *card); - /* * use the object id to find our object info on the object in our CAC-1 list */ @@ -793,11 +792,21 @@ static int cac_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* seri if (priv->cac_id_len) { serial->len = MIN(priv->cac_id_len, SC_MAX_SERIALNR); memcpy(serial->value, priv->cac_id, priv->cac_id_len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); } +static int cac_get_ACA_path(sc_card_t *card, sc_path_t *path) +{ + cac_private_data_t * priv = CAC_DATA(card); + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + if (priv->aca_path) { + *path = *priv->aca_path; + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); +} static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) { @@ -810,6 +819,8 @@ static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } switch(cmd) { + case SC_CARDCTL_CAC_GET_ACA_PATH: + return cac_get_ACA_path(card, (sc_path_t *) ptr); case SC_CARDCTL_GET_SERIALNR: return cac_get_serial_nr_from_CUID(card, (sc_serial_number_t *) ptr); case SC_CARDCTL_CAC_INIT_GET_GENERIC_OBJECTS: @@ -823,8 +834,6 @@ static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) case SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS: return cac_final_iterator(&priv->general_list); case SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS: - /* select ACA to be able to verify PIN */ - cac_select_ACA(card); return cac_final_iterator(&priv->pki_list); } @@ -1502,6 +1511,10 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) return SC_ERROR_OUT_OF_MEMORY; r = cac_populate_cac_1(card, index, priv); if (r == SC_SUCCESS) { + priv->aca_path = malloc(sizeof(sc_path_t)); + if (!priv->aca_path) + return SC_ERROR_OUT_OF_MEMORY; + memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t)); card->type = SC_CARD_TYPE_CAC_II; card->drv_data = priv; return r; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index b647b0537e..b610eacc77 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -220,6 +220,7 @@ enum { SC_CARDCTL_CAC_INIT_GET_CERT_OBJECTS, SC_CARDCTL_CAC_GET_NEXT_CERT_OBJECT, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, + SC_CARDCTL_CAC_GET_ACA_PATH, /* * AuthentIC v3 diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index fd463a9b4f..ff87a2345c 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -250,6 +250,12 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; + /* get the ACA path in case it needs to be selected before PIN verify */ + r = sc_card_ctl(card, SC_CARDCTL_CAC_GET_ACA_PATH, &pin_info.path); + if (r < 0) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + } + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); From 77f2640ea78ee9d6ee8a5c36a822554ad383be82 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 6 Nov 2017 12:38:07 +0100 Subject: [PATCH 0113/4321] Avoid potential memory leak --- src/libopensc/pkcs15-piv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 73fc2d4867..267014313f 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -776,6 +776,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) if (r == SC_SUCCESS) { token_name = malloc (cn_len+1); if (!token_name) { + sc_pkcs15_free_certificate(cert_out); + free(cn_name); SC_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY, r); } From 2846295e1f12790bd9d8b01531affbf6feccf22c Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 10 Nov 2017 09:58:31 +0200 Subject: [PATCH 0114/4321] EstEID ECDH token support (#1185) --- src/libopensc/card-mcrd.c | 89 +++++++++++++++++++++++++++++++++-- src/libopensc/pkcs15-esteid.c | 4 +- 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 28f8abfad2..085d029659 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -59,9 +59,9 @@ static struct sc_atr_table mcrd_atrs[] = { {NULL, NULL, NULL, 0, 0, NULL} }; -static unsigned char EstEID_v3_AID[] = {0xF0, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30}; -static unsigned char EstEID_v35_AID[] = {0xD2, 0x33, 0x00, 0x00, 0x00, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x33, 0x35}; -static unsigned char AzeDIT_v35_AID[] = {0xD0, 0x31, 0x00, 0x00, 0x00, 0x44, 0x69, 0x67, 0x69, 0x49, 0x44}; +static const unsigned char EstEID_v3_AID[] = {0xF0, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30}; +static const unsigned char EstEID_v35_AID[] = {0xD2, 0x33, 0x00, 0x00, 0x00, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x33, 0x35}; +static const unsigned char AzeDIT_v35_AID[] = {0xD0, 0x31, 0x00, 0x00, 0x00, 0x44, 0x69, 0x67, 0x69, 0x49, 0x44}; static struct sc_card_operations mcrd_ops; static struct sc_card_driver mcrd_drv = { @@ -119,6 +119,24 @@ struct mcrd_priv_data { #define DRVDATA(card) ((struct mcrd_priv_data *) ((card)->drv_data)) +// Control Reference Template Tag for Key Agreement (ISO 7816-4:2013 Table 54) +static const struct sc_asn1_entry c_asn1_control[] = { + { "control", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 0xA6, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +// Ephemeral public key Template Tag (ISO 7816-8:2016 Table 3) +static const struct sc_asn1_entry c_asn1_ephermal[] = { + { "ephemeral", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x7F49, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +// External Public Key +static const struct sc_asn1_entry c_asn1_public[] = { + { "publicKey", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0x86, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + static int load_special_files(sc_card_t * card); static int select_part(sc_card_t * card, u8 kind, unsigned short int fid, sc_file_t ** file); @@ -1208,6 +1226,7 @@ static int mcrd_set_security_env(sc_card_t * card, select_esteid_df(card); switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: + case SC_SEC_OPERATION_DERIVE: sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Using keyref %d to dechiper\n", env->key_ref[0]); @@ -1351,11 +1370,14 @@ static int mcrd_compute_signature(sc_card_t * card, u8 * out, size_t outlen) { struct mcrd_priv_data *priv = DRVDATA(card); - sc_security_env_t *env = &priv->sec_env; + sc_security_env_t *env = NULL; int r; sc_apdu_t apdu; - assert(card != NULL && data != NULL && out != NULL); + if (card == NULL || data == NULL || out == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + env = &priv->sec_env; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); if (env->operation != SC_SEC_OPERATION_SIGN) return SC_ERROR_INVALID_ARGUMENTS; @@ -1391,6 +1413,62 @@ static int mcrd_compute_signature(sc_card_t * card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); } +static int mcrd_decipher(struct sc_card *card, + const u8 * crgram, size_t crgram_len, + u8 * out, size_t outlen) +{ + sc_security_env_t *env = NULL; + int r = 0; + size_t sbuf_len = 0; + sc_apdu_t apdu; + u8 *sbuf = NULL; + struct sc_asn1_entry asn1_control[2], asn1_ephermal[2], asn1_public[2]; + + if (card == NULL || crgram == NULL || out == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + env = &DRVDATA(card)->sec_env; + + LOG_FUNC_CALLED(card->ctx); + if (env->operation != SC_SEC_OPERATION_DERIVE) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->decipher(card, crgram, crgram_len, out, outlen)); + if (crgram_len > 255) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "Will dervie (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n", + env->operation, crgram_len, crgram_len, env->key_ref[0], + env->algorithm, env->algorithm_flags); + + // Encode TLV + sc_copy_asn1_entry(c_asn1_control, asn1_control); + sc_copy_asn1_entry(c_asn1_ephermal, asn1_ephermal); + sc_copy_asn1_entry(c_asn1_public, asn1_public); + sc_format_asn1_entry(asn1_public + 0, (void*)crgram, &crgram_len, 1); + sc_format_asn1_entry(asn1_ephermal + 0, &asn1_public, NULL, 1); + sc_format_asn1_entry(asn1_control + 0, &asn1_ephermal, NULL, 1); + r = sc_asn1_encode(card->ctx, asn1_control, &sbuf, &sbuf_len); + LOG_TEST_RET(card->ctx, r, "Error encoding TLV."); + + // Create APDU + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86); + apdu.lc = sbuf_len; + apdu.data = sbuf; + apdu.datalen = sbuf_len; + apdu.le = MIN(0x80u, outlen); + apdu.resp = out; + apdu.resplen = outlen; + + r = sc_transmit_apdu(card, &apdu); + sc_mem_clear(sbuf, sbuf_len); + free(sbuf); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "Card returned error"); + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); +} + /* added by -mp, to give pin information in the card driver (pkcs15emu->driver needed) */ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int *tries_left) @@ -1454,6 +1532,7 @@ static struct sc_card_driver *sc_get_driver(void) mcrd_ops.select_file = mcrd_select_file; mcrd_ops.set_security_env = mcrd_set_security_env; mcrd_ops.compute_signature = mcrd_compute_signature; + mcrd_ops.decipher = mcrd_decipher; mcrd_ops.pin_cmd = mcrd_pin_cmd; return &mcrd_drv; diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index a5f9af8b2c..b3cf5178fc 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -219,8 +219,8 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) prkey_info.modulus_length = modulus_length; if (i == 1) prkey_info.usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - else if(field_length > 0) // ECC has only sign usage - prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN; + else if(field_length > 0) // ECC has sign and derive usage + prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE; else prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; From 4317df10e63fda5f69e68ee4fc5d2c679990289c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Nov 2017 08:05:10 +0100 Subject: [PATCH 0115/4321] created opensc-asn1 fixes installation of egk-tool.exe on win32 --- src/common/compat_strlcat.h | 1 + src/common/compat_strnlen.h | 1 + src/tools/Makefile.am | 31 +- src/tools/Makefile.mak | 7 +- src/tools/fread_to_eof.h | 2 + src/tools/opensc-asn1-cmdline.c | 1007 +++++++++++++++++++++++++++++++ src/tools/opensc-asn1-cmdline.h | 175 ++++++ src/tools/opensc-asn1.c | 52 ++ src/tools/opensc-asn1.ggo.in | 8 + win32/OpenSC.wxs.in | 8 + 10 files changed, 1288 insertions(+), 4 deletions(-) create mode 100644 src/tools/opensc-asn1-cmdline.c create mode 100644 src/tools/opensc-asn1-cmdline.h create mode 100644 src/tools/opensc-asn1.c create mode 100644 src/tools/opensc-asn1.ggo.in diff --git a/src/common/compat_strlcat.h b/src/common/compat_strlcat.h index 5ac0c7cc0d..d3cce7eb65 100644 --- a/src/common/compat_strlcat.h +++ b/src/common/compat_strlcat.h @@ -4,5 +4,6 @@ */ #ifndef HAVE_STRLCAT +#include size_t strlcat(char *dst, const char *src, size_t siz); #endif diff --git a/src/common/compat_strnlen.h b/src/common/compat_strnlen.h index 3c1f352d6e..dd9bc9841a 100644 --- a/src/common/compat_strnlen.h +++ b/src/common/compat_strnlen.h @@ -4,5 +4,6 @@ */ #ifndef HAVE_STRNLEN +#include size_t strnlen(const char *str, size_t maxlen); #endif diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 6d823c6edc..e8a0aea797 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -21,22 +21,23 @@ do_subst = $(SED) \ EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c +OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool \ - cardos-tool eidenv openpgp-tool iasecc-tool egk-tool + cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool endif if ENABLE_MAN -dist_man1_MANS = npa-tool.1 opensc-notify.1 egk-tool.1 +dist_man1_MANS = npa-tool.1 opensc-notify.1 egk-tool.1 opensc-asn1.1 endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb @@ -164,6 +165,30 @@ egk-tool.1: --source='$(PACKAGE_STRING)' \ $(builddir)/egk-tool$(EXEEXT) +opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c $(OPENSC_ASN1_BUILT_SOURCES) +opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) +opensc_asn1_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) +opensc_asn1_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option + +opensc-asn1.c: $(abs_builddir)/opensc-asn1.ggo $(OPENSC_ASN1_BUILT_SOURCES) + +# We only want *cmdline* to be generated when they have explicitly been removed. +$(OPENSC_ASN1_BUILT_SOURCES): + $(MAKE) $(abs_builddir)/opensc-asn1.ggo + $(GENGETOPT) --include-getopt --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-asn1.ggo --unamed-opts + +$(abs_builddir)/opensc-asn1.ggo: opensc-asn1.ggo.in + $(do_subst) < $(abs_srcdir)/opensc-asn1.ggo.in > $@ + +# We only want opensc-asn1.1 to be generated when it has explicitly been removed. +opensc-asn1.1: + $(MAKE) opensc-asn1$(EXEEXT) + $(HELP2MAN) \ + --output=$@ \ + --no-info \ + --source='$(PACKAGE_STRING)' \ + $(builddir)/opensc-asn1$(EXEEXT) + if WIN32 opensc_tool_SOURCES += versioninfo-tools.rc piv_tool_SOURCES += versioninfo-tools.rc diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 05b8e6130c..20be4b0476 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -6,7 +6,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ - opensc-notify.exe egk-tool.exe \ + opensc-notify.exe egk-tool.exe opensc-asn1.exe \ $(PROGRAMS_OPENSSL) OBJECTS = util.obj versioninfo-tools.res @@ -37,6 +37,11 @@ egk-tool.exe: egk-tool-cmdline.obj $(LIBS) link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 +opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + .c.exe: cl $(COPTS) /c $< link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib diff --git a/src/tools/fread_to_eof.h b/src/tools/fread_to_eof.h index 14a176c8bf..7f5520fe41 100644 --- a/src/tools/fread_to_eof.h +++ b/src/tools/fread_to_eof.h @@ -20,6 +20,8 @@ #ifndef _FREAD_TO_EOF_H #define _FREAD_TO_EOF_H +#include + int fread_to_eof(const char *file, unsigned char **buf, size_t *buflen); #endif diff --git a/src/tools/opensc-asn1-cmdline.c b/src/tools/opensc-asn1-cmdline.c new file mode 100644 index 0000000000..0f3b0f68f4 --- /dev/null +++ b/src/tools/opensc-asn1-cmdline.c @@ -0,0 +1,1007 @@ +/* + File autogenerated by gengetopt version 2.22.6 + generated with the following command: + /usr/local/bin/gengetopt --include-getopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + + +#include "opensc-asn1-cmdline.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: opensc-asn1 [OPTIONS]... [FILES]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = "Parse ASN.1 data."; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + 0 +}; + +typedef enum {ARG_NO +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = 0; + args_info->inputs_num = 0; +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + unsigned int i; + + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + FIX_UNUSED (args_info); + FIX_UNUSED (prog_name); + return EXIT_SUCCESS; +} + +/* + * Extracted from the glibc source tree, version 2.3.6 + * + * Licensed under the GPL as per the whole glibc source tree. + * + * This file was modified so that getopt_long can be called + * many times without risking previous memory to be spoiled. + * + * Modified by Andre Noll and Lorenzo Bettini for use in + * GNU gengetopt generated files. + * + */ + +/* + * we must include anything we need since this file is not thought to be + * inserted in a file already using getopt.h + * + * Lorenzo + */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. +*/ +/* + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `custom_optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +/* Names for the values of the `has_arg' field of `struct option'. */ +#ifndef no_argument +#define no_argument 0 +#endif + +#ifndef required_argument +#define required_argument 1 +#endif + +#ifndef optional_argument +#define optional_argument 2 +#endif + +struct custom_getopt_data { + /* + * These have exactly the same meaning as the corresponding global variables, + * except that they are used for the reentrant versions of getopt. + */ + int custom_optind; + int custom_opterr; + int custom_optopt; + char *custom_optarg; + + /* True if the internal members have been initialized. */ + int initialized; + + /* + * The next char to be scanned in the option-element in which the last option + * character we returned was found. This allows us to pick up the scan where + * we left off. If this is zero, or a null string, it means resume the scan by + * advancing to the next ARGV-element. + */ + char *nextchar; + + /* + * Describe the part of ARGV that contains non-options that have been skipped. + * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is + * the index after the last of them. + */ + int first_nonopt; + int last_nonopt; +}; + +/* + * the variables optarg, optind, opterr and optopt are renamed with + * the custom_ prefix so that they don't interfere with getopt ones. + * + * Moreover they're static so they are visible only from within the + * file where this very file will be included. + */ + +/* + * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an + * option that takes an argument, the argument value is returned here. + */ +static char *custom_optarg; + +/* + * Index in ARGV of the next element to be scanned. This is used for + * communication to and from the caller and for communication between + * successive calls to `custom_getopt'. + * + * On entry to `custom_getopt', 1 means this is the first call; initialize. + * + * When `custom_getopt' returns -1, this is the index of the first of the non-option + * elements that the caller should itself scan. + * + * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV + * has been scanned so far. + * + * 1003.2 says this must be 1 before any call. + */ +static int custom_optind = 1; + +/* + * Callers store zero here to inhibit the error message for unrecognized + * options. + */ +static int custom_opterr = 1; + +/* + * Set to an option character which was unrecognized. This must be initialized + * on some systems to avoid linking in the system's own getopt implementation. + */ +static int custom_optopt = '?'; + +/* + * Exchange two adjacent subsequences of ARGV. One subsequence is elements + * [first_nonopt,last_nonopt) which contains all the non-options that have been + * skipped so far. The other is elements [last_nonopt,custom_optind), which contains + * all the options processed since those non-options were skipped. + * `first_nonopt' and `last_nonopt' are relocated so that they describe the new + * indices of the non-options in ARGV after they are moved. + */ +static void exchange(char **argv, struct custom_getopt_data *d) +{ + int bottom = d->first_nonopt; + int middle = d->last_nonopt; + int top = d->custom_optind; + char *tem; + + /* + * Exchange the shorter segment with the far end of the longer segment. + * That puts the shorter segment into the right place. It leaves the + * longer segment in the right place overall, but it consists of two + * parts that need to be swapped next. + */ + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = + argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + /* Update records for the slots the non-options now occupy. */ + d->first_nonopt += (d->custom_optind - d->last_nonopt); + d->last_nonopt = d->custom_optind; +} + +/* Initialize the internal data when the first call is made. */ +static void custom_getopt_initialize(struct custom_getopt_data *d) +{ + /* + * Start processing options with ARGV-element 1 (since ARGV-element 0 + * is the program name); the sequence of previously skipped non-option + * ARGV-elements is empty. + */ + d->first_nonopt = d->last_nonopt = d->custom_optind; + d->nextchar = NULL; + d->initialized = 1; +} + +#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') + +/* return: zero: continue, nonzero: return given value to user */ +static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, + struct custom_getopt_data *d) +{ + /* + * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been + * moved back by the user (who may also have changed the arguments). + */ + if (d->last_nonopt > d->custom_optind) + d->last_nonopt = d->custom_optind; + if (d->first_nonopt > d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * If we have just processed some options following some + * non-options, exchange them so that the options come first. + */ + if (d->first_nonopt != d->last_nonopt && + d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->last_nonopt != d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * Skip any additional non-options and extend the range of + * non-options previously skipped. + */ + while (d->custom_optind < argc && NONOPTION_P) + d->custom_optind++; + d->last_nonopt = d->custom_optind; + /* + * The special ARGV-element `--' means premature end of options. Skip + * it like a null option, then exchange with previous non-options as if + * it were an option, then skip everything else like a non-option. + */ + if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { + d->custom_optind++; + if (d->first_nonopt != d->last_nonopt + && d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->first_nonopt == d->last_nonopt) + d->first_nonopt = d->custom_optind; + d->last_nonopt = argc; + d->custom_optind = argc; + } + /* + * If we have done all the ARGV-elements, stop the scan and back over + * any non-options that we skipped and permuted. + */ + if (d->custom_optind == argc) { + /* + * Set the next-arg-index to point at the non-options that we + * previously skipped, so the caller will digest them. + */ + if (d->first_nonopt != d->last_nonopt) + d->custom_optind = d->first_nonopt; + return -1; + } + /* + * If we have come to a non-option and did not permute it, either stop + * the scan or describe it to the caller and pass it by. + */ + if (NONOPTION_P) { + d->custom_optarg = argv[d->custom_optind++]; + return 1; + } + /* + * We have found another option-ARGV-element. Skip the initial + * punctuation. + */ + d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); + return 0; +} + +/* + * Check whether the ARGV-element is a long option. + * + * If there's a long option "fubar" and the ARGV-element is "-fu", consider + * that an abbreviation of the long option, just like "--fu", and not "-f" with + * arg "u". + * + * This distinction seems to be the most useful approach. + * + */ +static int check_long_opt(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int print_errors, struct custom_getopt_data *d) +{ + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { + if ((unsigned int) (nameend - d->nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else if (pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[d->custom_optind]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optind++; + d->custom_optopt = 0; + return '?'; + } + if (pfound) { + option_index = indfound; + d->custom_optind++; + if (*nameend) { + if (pfound->has_arg != no_argument) + d->custom_optarg = nameend + 1; + else { + if (print_errors) { + if (argv[d->custom_optind - 1][1] == '-') { + /* --option */ + fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + } else { + /* +option or -option */ + fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[d->custom_optind - 1][0], pfound->name); + } + + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == required_argument) { + if (d->custom_optind < argc) + d->custom_optarg = argv[d->custom_optind++]; + else { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], + argv[d->custom_optind - 1]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->nextchar += strlen(d->nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* + * Can't find it as a long option. If this is not getopt_long_only, or + * the option starts with '--' or is not a valid short option, then + * it's an error. Otherwise interpret it as a short option. + */ + if (print_errors) { + if (argv[d->custom_optind][1] == '-') { + /* --option */ + fprintf(stderr, + "%s: unrecognized option `--%s'\n", + argv[0], d->nextchar); + } else { + /* +option or -option */ + fprintf(stderr, + "%s: unrecognized option `%c%s'\n", + argv[0], argv[d->custom_optind][0], + d->nextchar); + } + } + d->nextchar = (char *) ""; + d->custom_optind++; + d->custom_optopt = 0; + return '?'; +} + +static int check_short_opt(int argc, char *const *argv, const char *optstring, + int print_errors, struct custom_getopt_data *d) +{ + char c = *d->nextchar++; + const char *temp = strchr(optstring, c); + + /* Increment `custom_optind' when we start to process its last character. */ + if (*d->nextchar == '\0') + ++d->custom_optind; + if (!temp || c == ':') { + if (print_errors) + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + + d->custom_optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + d->custom_optind++; + } else + d->custom_optarg = NULL; + d->nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + /* + * If we end this ARGV-element by taking the + * rest as an arg, we must advance to the next + * element now. + */ + d->custom_optind++; + } else if (d->custom_optind == argc) { + if (print_errors) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + d->custom_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* + * We already incremented `custom_optind' once; + * increment it again when taking next ARGV-elt + * as argument. + */ + d->custom_optarg = argv[d->custom_optind++]; + d->nextchar = NULL; + } + } + return c; +} + +/* + * Scan elements of ARGV for option characters given in OPTSTRING. + * + * If an element of ARGV starts with '-', and is not exactly "-" or "--", + * then it is an option element. The characters of this element + * (aside from the initial '-') are option characters. If `getopt' + * is called repeatedly, it returns successively each of the option characters + * from each of the option elements. + * + * If `getopt' finds another option character, it returns that character, + * updating `custom_optind' and `nextchar' so that the next call to `getopt' can + * resume the scan with the following option character or ARGV-element. + * + * If there are no more option characters, `getopt' returns -1. + * Then `custom_optind' is the index in ARGV of the first ARGV-element + * that is not an option. (The ARGV-elements have been permuted + * so that those that are not options now come last.) + * + * OPTSTRING is a string containing the legitimate option characters. + * If an option character is seen that is not listed in OPTSTRING, + * return '?' after printing an error message. If you set `custom_opterr' to + * zero, the error message is suppressed but we still return '?'. + * + * If a char in OPTSTRING is followed by a colon, that means it wants an arg, + * so the following text in the same ARGV-element, or the text of the following + * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that + * wants an optional arg; if there is text in the current ARGV-element, + * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. + * + * If OPTSTRING starts with `-' or `+', it requests different methods of + * handling the non-option ARGV-elements. + * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + * + * Long-named options begin with `--' instead of `-'. + * Their names may be abbreviated as long as the abbreviation is unique + * or is an exact match for some defined option. If they have an + * argument, it follows the option name in the same ARGV-element, separated + * from the option name by a `=', or else the in next ARGV-element. + * When `getopt' finds a long-named option, it returns 0 if that option's + * `flag' field is nonzero, the value of the option's `val' field + * if the `flag' field is zero. + * + * The elements of ARGV aren't really const, because we permute them. + * But we pretend they're const in the prototype to be compatible + * with other systems. + * + * LONGOPTS is a vector of `struct option' terminated by an + * element containing a name which is zero. + * + * LONGIND returns the index in LONGOPT of the long-named option found. + * It is only valid when a long-named option has been found by the most + * recent call. + * + * Return the option character from OPTS just read. Return -1 when there are + * no more options. For unrecognized options, or options missing arguments, + * `custom_optopt' is set to the option letter, and '?' is returned. + * + * The OPTS string is a list of characters which are recognized option letters, + * optionally followed by colons, specifying that that letter takes an + * argument, to be placed in `custom_optarg'. + * + * If a letter in OPTS is followed by two colons, its argument is optional. + * This behavior is specific to the GNU `getopt'. + * + * The argument `--' causes premature termination of argument scanning, + * explicitly telling `getopt' that there are no more options. If OPTS begins + * with `--', then non-option arguments are treated as arguments to the option + * '\0'. This behavior is specific to the GNU `getopt'. + */ + +static int getopt_internal_r(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + struct custom_getopt_data *d) +{ + int ret, print_errors = d->custom_opterr; + + if (optstring[0] == ':') + print_errors = 0; + if (argc < 1) + return -1; + d->custom_optarg = NULL; + + /* + * This is a big difference with GNU getopt, since optind == 0 + * means initialization while here 1 means first call. + */ + if (d->custom_optind == 0 || !d->initialized) { + if (d->custom_optind == 0) + d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ + custom_getopt_initialize(d); + } + if (d->nextchar == NULL || *d->nextchar == '\0') { + ret = shuffle_argv(argc, argv, longopts, d); + if (ret) + return ret; + } + if (longopts && (argv[d->custom_optind][1] == '-' )) + return check_long_opt(argc, argv, optstring, longopts, + longind, print_errors, d); + return check_short_opt(argc, argv, optstring, print_errors, d); +} + +static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind) +{ + int result; + /* Keep a global copy of all internal members of d */ + static struct custom_getopt_data d; + + d.custom_optind = custom_optind; + d.custom_opterr = custom_opterr; + result = getopt_internal_r(argc, argv, optstring, longopts, + longind, &d); + custom_optind = d.custom_optind; + custom_optarg = d.custom_optarg; + custom_optopt = d.custom_optopt; + return result; +} + +static int custom_getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return custom_getopt_internal(argc, argv, options, long_options, + opt_index); +} + + +static char *package_name = 0; + + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + char *optarg; + int optind; + int opterr; + int optopt; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { 0, 0, 0, 0 } + }; + + custom_optarg = optarg; + custom_optind = optind; + custom_opterr = opterr; + custom_optopt = optopt; + + c = custom_getopt_long (argc, argv, "hV", long_options, &option_index); + + optarg = custom_optarg; + optind = custom_optind; + opterr = custom_opterr; + optopt = custom_optopt; + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + + case 0: /* Long option with no short option */ + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/src/tools/opensc-asn1-cmdline.h b/src/tools/opensc-asn1-cmdline.h new file mode 100644 index 0000000000..43baee5b95 --- /dev/null +++ b/src/tools/opensc-asn1-cmdline.h @@ -0,0 +1,175 @@ +/** @file opensc-asn1-cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.6 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef OPENSC_ASN1_CMDLINE_H +#define OPENSC_ASN1_CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "opensc-asn1" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "opensc-asn1" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + + char **inputs ; /**< @brief unamed options (options without names) */ + unsigned inputs_num ; /**< @brief unamed options number */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* OPENSC_ASN1_CMDLINE_H */ diff --git a/src/tools/opensc-asn1.c b/src/tools/opensc-asn1.c new file mode 100644 index 0000000000..18ca680349 --- /dev/null +++ b/src/tools/opensc-asn1.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fread_to_eof.h" +#include "libopensc/asn1.h" +#include "opensc-asn1-cmdline.h" +#include + +int +main (int argc, char **argv) +{ + struct gengetopt_args_info cmdline; + unsigned char *buf = NULL; + size_t buflen = 0, i; + + if (cmdline_parser(argc, argv, &cmdline) != 0) + return 1; + + for (i = 0; i < cmdline.inputs_num; i++) { + if (!fread_to_eof(cmdline.inputs[i], &buf, &buflen)) + continue; + + printf("Parsing '%s' (%"SC_FORMAT_LEN_SIZE_T"u byte%s)\n", + cmdline.inputs[i], buflen, buflen == 1 ? "" : "s"); + sc_asn1_print_tags(buf, buflen); + } + + free(buf); + cmdline_parser_free (&cmdline); + + return 0; +} diff --git a/src/tools/opensc-asn1.ggo.in b/src/tools/opensc-asn1.ggo.in new file mode 100644 index 0000000000..2f44ef2e6c --- /dev/null +++ b/src/tools/opensc-asn1.ggo.in @@ -0,0 +1,8 @@ +package "opensc-asn1" +purpose "@PACKAGE_SUMMARY@" +description "Parse ASN.1 data." + +text " +Report bugs to @PACKAGE_BUGREPORT@ + +Written by Frank Morgner " diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index cd02ab5fcc..b32eb70c04 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -125,6 +125,9 @@ + + + @@ -140,6 +143,9 @@ + + + @@ -343,11 +349,13 @@ + + From 9468ce7f89f9b84704c94a9b9eb433f4ba5fbde1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 10 Nov 2017 09:05:29 +0100 Subject: [PATCH 0116/4321] beautify printed ASN.1 output - fixed printing tags on multiple bytes - align indenting with raw tags - use OpenSSL's human readable OID database - only print the canonical names for universal tags --- src/libopensc/asn1.c | 80 +++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index cf035ea943..15e0dea06e 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -43,13 +43,13 @@ static const char *tag2str(unsigned int tag) { static const char *tags[] = { "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ - "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ - "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ - "", "", "SEQUENCE", "SET", /* 15-17 */ - "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ - "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */ - "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ - "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ + "NULL", "OBJECT IDENTIFIER", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ + "ENUMERATED", "Universal 11", "UTF8String", "Universal 13", /* 10-13 */ + "Universal 14", "Universal 15", "SEQUENCE", "SET", /* 15-17 */ + "NumericString", "PrintableString", "T61String", /* 18-20 */ + "VideotexString", "IA5String", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */ + "GraphicString", "VisibleString", "GeneralString", /* 25-27 */ + "UniversalString", "Universal 29", "BMPString" /* 28-30 */ }; if (tag > 30) @@ -214,6 +214,26 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen) } } +#ifdef ENABLE_OPENSSL +#include + +static void openssl_print_object_sn(const char *s) +{ + ASN1_OBJECT *obj = OBJ_txt2obj(s, 0); + if (obj) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) { + printf("%s ", OBJ_nid2sn(nid)); + } + ASN1_OBJECT_free(obj); + } +} +#else +static void openssl_print_object_sn(const char *s) +{ +} +#endif + static void sc_asn1_print_object_id(const u8 * buf, size_t buflen) { struct sc_object_id oid; @@ -234,6 +254,8 @@ static void sc_asn1_print_object_id(const u8 * buf, size_t buflen) sprintf(tmp, "%d", oid.value[i]); strcat(sbuf, tmp); } + + openssl_print_object_sn(sbuf); printf("%s", sbuf); } @@ -245,12 +267,16 @@ static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen) } static void print_tags_recursive(const u8 * buf0, const u8 * buf, - size_t buflen, int depth) + size_t buflen, size_t depth) { - int i, r; + int r; + size_t i; size_t bytesleft = buflen; const char *classes[4] = { - "Univ", "Appl", "Cntx", "Priv" + "Universal", + "Application", + "Context", + "Private" }; const u8 *p = buf; @@ -271,25 +297,40 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, } for (i = 0; i < depth; i++) { putchar(' '); - putchar(' '); } - printf("%02X %s: tag 0x%02X, length %3d: ", - cla | tag, classes[cla >> 6], tag & 0x1f, (int) len); + /* let i be the length of the tag in bytes */ + for (i = 1; i < sizeof tag - 1; i++) { + if (!(tag >> 8*i)) + break; + } + printf("%02X", cla<<(i-1)*8 | tag); + + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) { + printf(" %s", tag2str(tag)); + } else { + printf(" %s %-2u", + classes[cla >> 6], + i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8)); + } + printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)", + len, + len != 1 ? "s" : ""); + if (len + hlen > bytesleft) { printf(" Illegal length!\n"); return; } p += hlen + len; bytesleft -= hlen + len; - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) - printf("%s", tag2str(tag)); if (cla & SC_ASN1_TAG_CONSTRUCTED) { putchar('\n'); - print_tags_recursive(buf0, tagp, len, depth + 1); + print_tags_recursive(buf0, tagp, len, depth + 2*i + 1); continue; } - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) { + + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL + && tag != SC_ASN1_TAG_NULL) { printf(" ["); switch (tag) { case SC_ASN1_TAG_BIT_STRING: @@ -321,10 +362,10 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, } if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) - printf(" [%s]", sc_dump_hex(tagp, len)); + printf(" [%s]", sc_dump_hex(tagp, len)); if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) - printf(" [%s]", sc_dump_hex(tagp, len)); + printf(" [%s]", sc_dump_hex(tagp, len)); putchar('\n'); } @@ -333,7 +374,6 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, void sc_asn1_print_tags(const u8 * buf, size_t buflen) { - printf("Printing tags for buffer of length %d\n", (int) buflen); print_tags_recursive(buf, buf, buflen, 0); } From 8de544653c049b996786bb7c1600276841487e06 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 13 Nov 2017 15:11:58 +0100 Subject: [PATCH 0117/4321] dump data with sc_debug_hex and sc_log_hex --- src/libopensc/apdu.c | 2 +- src/libopensc/card-authentic.c | 11 ++-- src/libopensc/card-dnie.c | 29 ++++------- src/libopensc/card-epass2003.c | 4 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-gpk.c | 9 +--- src/libopensc/card-iasecc.c | 7 ++- src/libopensc/card-mcrd.c | 94 ++++++++++++++++------------------ src/libopensc/card-oberthur.c | 16 +----- src/libopensc/card-westcos.c | 8 +-- src/libopensc/cwa14890.c | 4 +- src/libopensc/iso7816.c | 5 +- src/libopensc/log.c | 20 +++----- src/libopensc/log.h | 8 +-- src/smm/sm-card-authentic.c | 23 ++------- src/tools/npa-tool.c | 2 +- 16 files changed, 93 insertions(+), 151 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 99c0da4beb..258e0f2253 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -468,7 +468,7 @@ sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen) if (rv < 0) { #ifdef ENABLE_SM if (resp_len) { - sc_log(ctx, "SM response data %s", sc_dump_hex(resp, resp_len)); + sc_log_hex(ctx, "SM response data", resp, resp_len); sc_sm_update_apdu_response(card, resp, resp_len, rv, apdu); } #endif diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 4da5933534..89e6a40a5e 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -413,7 +413,7 @@ authentic_match_card(struct sc_card *card) struct sc_context *ctx = card->ctx; int i; - sc_log(ctx, "try to match card with ATR %s", sc_dump_hex(card->atr.value, card->atr.len)); + sc_log_hex(ctx, "try to match card with ATR", card->atr.value, card->atr.len); i = _sc_match_atr(card, authentic_known_atrs, &card->type); if (i < 0) { sc_log(ctx, "card not matched"); @@ -1041,9 +1041,7 @@ authentic_process_fci(struct sc_card *card, struct sc_file *file, LOG_TEST_RET(ctx, rv, "ISO parse FCI failed"); if (!file->sec_attr_len) { - sc_log(ctx, - "ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s", - buflen, sc_dump_hex(buf, buflen)); + sc_log_hex(ctx, "ACLs not found in data", buf, buflen); sc_log(ctx, "Path:%s; Type:%X; PathType:%X", sc_print_path(&file->path), file->type, file->path.type); if (file->path.type == SC_PATH_TYPE_DF_NAME || file->type == SC_FILE_TYPE_DF) { file->type = SC_FILE_TYPE_DF; @@ -1053,8 +1051,7 @@ authentic_process_fci(struct sc_card *card, struct sc_file *file, } } - sc_log(ctx, "ACL data(%"SC_FORMAT_LEN_SIZE_T"u):%s", file->sec_attr_len, - sc_dump_hex(file->sec_attr, file->sec_attr_len)); + sc_log_hex(ctx, "ACL data", file->sec_attr, file->sec_attr_len); for (ii = 0; ii < file->sec_attr_len / 2; ii++) { unsigned char op = file->type == SC_FILE_TYPE_DF ? ops_DF[ii] : ops_EF[ii]; unsigned char acl = *(file->sec_attr + ii*2); @@ -1908,7 +1905,7 @@ authentic_manage_sdo_encode(struct sc_card *card, struct sc_authentic_sdo *sdo, free(data); - sc_log(ctx, "encoded SDO operation data %s", sc_dump_hex(*out, *out_len)); + sc_log_hex(ctx, "encoded SDO operation data", *out, *out_len); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 6260e81c7f..92edf59626 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -645,8 +645,7 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) /* if serial number is cached, use it */ if (card->serialnr.len) { memcpy(serial, &card->serialnr, sizeof(*serial)); - sc_log(card->ctx, "Serial Number (cached): '%s'", - sc_dump_hex(serial->value, serial->len)); + sc_log_hex(card->ctx, "Serial Number (cached)", serial->value, serial->len); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } /* not cached, retrieve it by mean of an APDU */ @@ -672,8 +671,7 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) */ /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); - sc_log(card->ctx, "Serial Number (apdu): '%s'", - sc_dump_hex(serial->value, serial->len)); + sc_log_hex(card->ctx, "Serial Number (apdu)", serial->value, serial->len); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -962,13 +960,8 @@ static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) } /* Done; update buffer len and return pt to uncompressed data */ *len = uncompressed; - sc_log(card->ctx, "Compressed data:\n%s\n", - sc_dump_hex(from + 8, compressed)); - sc_log(card->ctx, - "Uncompress() done. Before:'%"SC_FORMAT_LEN_SIZE_T"u' After: '%"SC_FORMAT_LEN_SIZE_T"u'", - compressed, uncompressed); - sc_log(card->ctx, "Uncompressed data:\n%s\n", - sc_dump_hex(upt, uncompressed)); + sc_log_hex(card->ctx, "Compressed data", from + 8, compressed); + sc_log_hex(card->ctx, "Uncompressed data", upt, uncompressed); compress_exit: #endif @@ -1259,18 +1252,18 @@ static int dnie_select_file(struct sc_card *card, */ if (in_path->len != 2) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "select_file(ID): %s", sc_dump_hex(in_path->value, in_path->len)); + sc_log_hex(ctx, "select_file(ID)", in_path->value, in_path->len); res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 0, file_out); break; case SC_PATH_TYPE_DF_NAME: - sc_log(ctx, "select_file(NAME): %s", sc_dump_hex(in_path->value, in_path->len)); + sc_log_hex(ctx, "select_file(NAME)", in_path->value, in_path->len); res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 4, file_out); break; case SC_PATH_TYPE_PATH: if ((in_path->len == 0) || ((in_path->len & 1) != 0)) /* not divisible by 2 */ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "select_file(PATH): requested:%s ", sc_dump_hex(in_path->value, in_path->len)); + sc_log_hex(ctx, "select_file(PATH): requested", in_path->value, in_path->len); /* convert to SC_PATH_TYPE_FILE_ID */ res = sc_lock(card); /* lock to ensure path traversal */ @@ -1278,7 +1271,7 @@ static int dnie_select_file(struct sc_card *card, if (memcmp(in_path->value, "\x3F\x00", 2) == 0) { /* if MF, use the name as path */ strcpy((char *)tmp_path, DNIE_MF_NAME); - sc_log(ctx, "select_file(NAME): requested:%s ", sc_dump_hex(tmp_path, sizeof(DNIE_MF_NAME) - 1)); + sc_log_hex(ctx, "select_file(NAME): requested", tmp_path, sizeof(DNIE_MF_NAME) - 1); res = dnie_compose_and_send_apdu(card, tmp_path, sizeof(DNIE_MF_NAME) - 1, 4, file_out); if (res != SC_SUCCESS) { sc_unlock(card); @@ -1689,9 +1682,9 @@ static int dnie_compute_signature(struct sc_card *card, So just extract 15+20 DigestInfo+Hash info from ASN.1 provided data and feed them into sign() command */ - sc_log(card->ctx, - "Compute signature len: '%"SC_FORMAT_LEN_SIZE_T"u' bytes:\n%s\n============================================================", - datalen, sc_dump_hex(data, datalen)); + sc_log_hex(card->ctx, + "Compute signature\n============================================================", + data, datalen); /*INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x9E Resp: Digital Signature diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 7feab59846..4c118b2c7d 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1868,12 +1868,10 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen); if (tag != NULL && taglen > 0 && taglen <= 16) { - char tbuf[128]; memcpy(file->name, tag, taglen); file->namelen = taglen; - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, file->name, file->namelen, tbuf, sizeof(tbuf)); - sc_log(ctx, "File name: %s", tbuf); + sc_log_hex(ctx, "File name", file->name, file->namelen); if (!file->type) file->type = SC_FILE_TYPE_DF; } diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 7fa1b2f312..52f06816d6 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -902,7 +902,7 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, } if (response && responselen) - sc_log(card->ctx, "encoded public key: %s", sc_dump_hex(*response, *responselen)); + sc_log_hex(card->ctx, "encoded public key", *response, *responselen); return SC_SUCCESS; } diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 86bfebd8b7..883bf7c60c 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -1527,13 +1527,8 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) return SC_ERROR_INTERNAL; if (0) { - char buf[2048]; - - sc_hex_dump(card->ctx, SC_LOG_DEBUG_NORMAL, - args->data, args->datalen, - buf, sizeof(buf)); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Sending %d bytes (cleartext):\n%s", - args->datalen, buf); + sc_log_hex(card->ctx, "Sending (cleartext)", + args->data, args->datalen); } memset(&apdu, 0, sizeof(apdu)); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index ea61db3cbb..b6c6995db9 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -157,7 +157,7 @@ iasecc_chv_cache_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) else memset(pin_status->sha1, 0, SHA_DIGEST_LENGTH); - sc_log(ctx, "iasecc_chv_cache_verified() sha1(PIN): %s", sc_dump_hex(pin_status->sha1, SHA_DIGEST_LENGTH)); + sc_log_hex(ctx, "iasecc_chv_cache_verified() sha1(PIN)", pin_status->sha1, SHA_DIGEST_LENGTH); if (!current) { if (!checked_pins) { @@ -219,7 +219,7 @@ iasecc_chv_cache_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_c SHA1(pin_cmd->pin1.data, pin_cmd->pin1.len, data_sha1); else memset(data_sha1, 0, SHA_DIGEST_LENGTH); - sc_log(ctx, "data_sha1: %s", sc_dump_hex(data_sha1, SHA_DIGEST_LENGTH)); + sc_log_hex(ctx, "data_sha1: %s", data_sha1, SHA_DIGEST_LENGTH); for(current = checked_pins; current; current = current->next) if (current->reference == pin_cmd->pin_reference) @@ -345,7 +345,6 @@ iasecc_match_card(struct sc_card *card) struct sc_context *ctx = card->ctx; int i; - sc_log(ctx, "iasecc_match_card(%s) called", sc_dump_hex(card->atr.value, card->atr.len)); i = _sc_match_atr(card, iasecc_known_atrs, &card->type); if (i < 0) { sc_log(ctx, "card not matched"); @@ -457,7 +456,7 @@ iasecc_oberthur_match(struct sc_card *card) if (*hist != 0x80 || ((*(hist+1)&0xF0) != 0xF0)) LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND); - sc_log(ctx, "AID in historical_bytes '%s'", sc_dump_hex(hist + 2, *(hist+1) & 0x0F)); + sc_log_hex(ctx, "AID in historical_bytes", hist + 2, *(hist+1) & 0x0F); if (memcmp(hist + 2, OberthurIASECC_AID.value, *(hist+1) & 0x0F)) LOG_FUNC_RETURN(ctx, SC_ERROR_RECORD_NOT_FOUND); diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 085d029659..e4f711e636 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -152,7 +152,7 @@ static struct df_info_s *get_df_info(sc_card_t * card) assert(!priv->is_ef); if (!priv->curpathlen) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no current path to find the df_info\n"); + sc_log(ctx, "no current path to find the df_info\n"); return NULL; } @@ -165,7 +165,7 @@ static struct df_info_s *get_df_info(sc_card_t * card) /* Not found, create it. */ dfi = calloc(1, sizeof *dfi); if (!dfi) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "out of memory while allocating df_info\n"); + sc_log(ctx, "out of memory while allocating df_info\n"); return NULL; } dfi->pathlen = priv->curpathlen; @@ -253,11 +253,11 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) SC_ESTEID_KEYREF_FILE_RECLEN, SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Can't read keyref info file!"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "authkey reference 0x%02x%02x\n", keyref_data[9], keyref_data[10]); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "signkey reference 0x%02x%02x\n", keyref_data[19], keyref_data[20]); @@ -474,12 +474,12 @@ static int load_special_files(sc_card_t * card) } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "new EF_Rule file loaded (%d records)\n", recno - 1); + sc_log(ctx, "new EF_Rule file loaded (%d records)\n", recno - 1); /* Read the KeyD file. Note that we bypass our cache here. */ r = select_part(card, MCRD_SEL_EF, EF_KeyD, NULL); if (r == SC_ERROR_FILE_NOT_FOUND) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no EF_KeyD file available\n"); + sc_log(ctx, "no EF_KeyD file available\n"); return 0; /* That is okay. */ } SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "selecting EF_KeyD failed"); @@ -505,7 +505,7 @@ static int load_special_files(sc_card_t * card) } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "new EF_KeyD file loaded (%d records)\n", recno - 1); + sc_log(ctx, "new EF_KeyD file loaded (%d records)\n", recno - 1); /* FIXME: Do we need to restore the current DF? I guess it is not required, but we could try to do so by selecting 3fff? */ return 0; @@ -522,7 +522,6 @@ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, struct keyd_record_s *keyd; size_t len, taglen; const u8 *p, *tag; - char dbgbuf[2048]; u8 fidbuf[2]; fidbuf[0] = (fid >> 8) & 0xFF; @@ -530,7 +529,7 @@ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, dfi = get_df_info(card); if (!dfi || !dfi->keyd_file) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "EF_keyD not loaded\n"); + sc_log(ctx, "EF_keyD not loaded\n"); return -1; } @@ -538,9 +537,8 @@ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, p = keyd->data; len = keyd->datalen; - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, - p, len, dbgbuf, sizeof dbgbuf); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "keyd no %d:\n%s", keyd->recno, dbgbuf); + sc_log(ctx, "keyd no %d", keyd->recno); + sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, "", p, len); tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (!tag || taglen != 4 || @@ -563,7 +561,7 @@ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, continue; return *tag; /* found. */ } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "EF_keyD for %04hx not found\n", fid); + sc_log(ctx, "EF_keyD for %04hx not found\n", fid); return -1; } @@ -582,7 +580,7 @@ static void process_arr(sc_card_t * card, sc_file_t * file, /* Currently we support only the short for. */ if (buflen != 1) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "can't handle long ARRs\n"); + sc_log(ctx, "can't handle long ARRs\n"); return; } @@ -590,13 +588,12 @@ static void process_arr(sc_card_t * card, sc_file_t * file, for (rule = dfi ? dfi->rule_file : NULL; rule && rule->recno != *buf; rule = rule->next) ; if (!rule) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "referenced EF_rule record %d not found\n", *buf); + sc_log(ctx, "referenced EF_rule record %d not found\n", *buf); return; } - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, - rule->data, rule->datalen, dbgbuf, sizeof dbgbuf); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_hex_dump(rule->data, rule->datalen, dbgbuf, sizeof dbgbuf); + sc_log(ctx, "rule for record %d:\n%s", *buf, dbgbuf); p = rule->data; @@ -613,11 +610,11 @@ static void process_arr(sc_card_t * card, sc_file_t * file, if (tag == 0x80 && taglen != 1) { skip = 1; } else if (tag == 0x80) { /* AM byte. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " AM_DO: %02x\n", *p); + sc_log(ctx, " AM_DO: %02x\n", *p); skip = 0; } else if (tag >= 0x81 && tag <= 0x8f) { /* Cmd description */ - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, p, taglen, dbgbuf, sizeof dbgbuf); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " AM_DO: cmd[%s%s%s%s] %s", + sc_hex_dump(p, taglen, dbgbuf, sizeof dbgbuf); + sc_log(ctx, " AM_DO: cmd[%s%s%s%s] %s", (tag & 8) ? "C" : "", (tag & 4) ? "I" : "", (tag & 2) ? "1" : "", @@ -626,33 +623,32 @@ static void process_arr(sc_card_t * card, sc_file_t * file, } else if (tag == 0x9C) { /* Proprietary state machine descrip. */ skip = 1; } else if (!skip) { - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, p, taglen, dbgbuf, sizeof dbgbuf); switch (tag) { case 0x90: /* Always */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: always\n"); + sc_log(ctx, " SC: always\n"); break; case 0x97: /* Never */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: never\n"); + sc_log(ctx, " SC: never\n"); break; case 0xA4: /* Authentication, value is a CRT. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: auth %s", dbgbuf); + sc_log_hex(ctx, " SC: auth", p, taglen); break; case 0xB4: case 0xB6: case 0xB8: /* Cmd or resp with SM, value is a CRT. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: cmd/resp %s", dbgbuf); + sc_log_hex(ctx, " SC: cmd/resp", p, taglen); break; case 0x9E: /* Security Condition byte. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: condition %s", dbgbuf); + sc_log_hex(ctx, " SC: condition", p, taglen); break; case 0xA0: /* OR template. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: OR\n"); + sc_log(ctx, " SC: OR\n"); break; case 0xAF: /* AND template. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " SC: AND\n"); + sc_log(ctx, " SC: AND\n"); break; } } @@ -670,13 +666,13 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, const u8 *tag = NULL, *p = buf; int bad_fde = 0; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "processing FCI bytes\n"); + sc_log(ctx, "processing FCI bytes\n"); /* File identifier. */ tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (tag != NULL && taglen == 2) { file->id = (tag[0] << 8) | tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " file identifier: 0x%02X%02X\n", tag[0], tag[1]); } /* Number of data bytes in the file including structural information. */ @@ -691,7 +687,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, } if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -699,7 +695,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -714,7 +710,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, const char *type; file->shareable = byte & 0x40 ? 1 : 0; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " shareable: %s\n", (byte & 0x40) ? "yes" : "no"); file->ef_structure = byte & 0x07; @@ -735,9 +731,9 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, type = "unknown"; break; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " type: %s\n", type); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " EF structure: %d\n", byte & 0x07); } } @@ -759,7 +755,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, name[i] = '?'; } name[taglen] = 0; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " file name: %s\n", name); + sc_log(ctx, " file name: %s\n", name); } /* Proprietary information. */ @@ -875,7 +871,7 @@ select_part(sc_card_t * card, u8 kind, unsigned short int fid, unsigned int len; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "select_part (0x%04X, kind=%u)\n", fid, kind); if (fid == MFID) { @@ -1106,7 +1102,7 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) linep += 4; } strcpy(linep, "\n"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s", line); + sc_log(card->ctx, "%s", line); } if (path->type == SC_PATH_TYPE_DF_NAME) { @@ -1169,7 +1165,7 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) linep += 4; } strcpy(linep, "\n"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s", line); + sc_log(card->ctx, "%s", line); } return r; } @@ -1227,7 +1223,7 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_DERIVE: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Using keyref %d to dechiper\n", env->key_ref[0]); mcrd_restore_se(card, 6); @@ -1236,7 +1232,7 @@ static int mcrd_set_security_env(sc_card_t * card, mcrd_set_decipher_key_ref(card, env->key_ref[0]); break; case SC_SEC_OPERATION_SIGN: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Using keyref %d to sign\n", + sc_log(card->ctx, "Using keyref %d to sign\n", env->key_ref[0]); mcrd_restore_se(card, 1); break; @@ -1249,7 +1245,7 @@ static int mcrd_set_security_env(sc_card_t * card, if (card->type == SC_CARD_TYPE_MCRD_DTRUST || card->type == SC_CARD_TYPE_MCRD_GENERIC) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Using SC_CARD_TYPE_MCRD_DTRUST\n"); + sc_log(card->ctx, "Using SC_CARD_TYPE_MCRD_DTRUST\n"); /* some sanity checks */ if (env->flags & SC_SEC_ENV_ALG_PRESENT) { if (env->algorithm != SC_ALGORITHM_RSA) @@ -1261,7 +1257,7 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Using keyref %d to dechiper\n", env->key_ref[0]); mcrd_delete_ref_to_authkey(card); @@ -1269,7 +1265,7 @@ static int mcrd_set_security_env(sc_card_t * card, mcrd_set_decipher_key_ref(card, env->key_ref[0]); break; case SC_SEC_OPERATION_SIGN: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Using keyref %d to sign\n", + sc_log(card->ctx, "Using keyref %d to sign\n", env->key_ref[0]); break; default: @@ -1342,13 +1338,13 @@ static int mcrd_set_security_env(sc_card_t * card, if (apdu.datalen != 0) { r = sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); goto err; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); goto err; } @@ -1384,7 +1380,7 @@ static int mcrd_compute_signature(sc_card_t * card, if (datalen > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Will compute signature (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n", env->operation, datalen, datalen, env->key_ref[0], env->algorithm, env->algorithm_flags); @@ -1511,7 +1507,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, if (card->type == SC_CARD_TYPE_MCRD_DTRUST || card->type == SC_CARD_TYPE_MCRD_GENERIC) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "modify pin reference for D-Trust\n"); + sc_log(card->ctx, "modify pin reference for D-Trust\n"); if (data->pin_reference == 0x02) data->pin_reference = data->pin_reference | 0x80; } diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 9842055a08..75ad10db2c 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2023,16 +2023,10 @@ write_publickey (struct sc_card *card, unsigned int offset, struct sc_pkcs15_pubkey_rsa key; int ii, rv; size_t len = 0, der_size = 0; - char debug_buf[2048]; LOG_FUNC_CALLED(card->ctx); - debug_buf[0] = 0; - sc_hex_dump(card->ctx, SC_LOG_DEBUG_NORMAL, - buf, count, debug_buf, sizeof(debug_buf)); - sc_log(card->ctx, - "write_publickey in %"SC_FORMAT_LEN_SIZE_T"u bytes :\n%s", - count, debug_buf); + sc_log_hex(card->ctx, "write_publickey", buf, count); if (1+offset > sizeof(rsa_der)) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid offset value"); @@ -2121,7 +2115,6 @@ auth_read_binary(struct sc_card *card, unsigned int offset, unsigned char *buf, size_t count, unsigned long flags) { int rv; - char debug_buf[2048]; struct sc_pkcs15_bignum bn[2]; unsigned char *out = NULL; bn[0].data = NULL; @@ -2183,12 +2176,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, rv = out_len - offset > count ? count : out_len - offset; memcpy(buf, out + offset, rv); - debug_buf[0] = 0; - sc_hex_dump(card->ctx, SC_LOG_DEBUG_NORMAL, - buf, rv, debug_buf, sizeof(debug_buf)); - sc_log(card->ctx, - "write_publickey in %"SC_FORMAT_LEN_SIZE_T"u bytes :\n%s", - count, debug_buf); + sc_log_hex(card->ctx, "write_publickey", buf, rv); } } else { diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 3290b6829b..0e62029667 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -361,13 +361,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, if (tag != NULL && taglen > 0 && taglen <= 16) { memcpy(file->name, tag, taglen); file->namelen = taglen; - { - char tbuf[128]; - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, - file->name, file->namelen, tbuf, sizeof(tbuf)); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - " File name: %s\n", tbuf); - } + sc_log_hex(card->ctx, " File name", file->name, file->namelen); } if (file->type == SC_FILE_TYPE_DF) { tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen); diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index f60d094bc5..ab616e08a3 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -83,7 +83,7 @@ static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag) return; if (flag == 0) { /* apdu command */ if (apdu->datalen > 0) { /* apdu data to show */ - sc_hex_dump(card->ctx, SC_LOG_DEBUG_NORMAL, apdu->data, apdu->datalen, buf, sizeof(buf)); + sc_hex_dump(apdu->data, apdu->datalen, buf, sizeof(buf)); sc_log(card->ctx, "\nAPDU before encode: ==================================================\nCLA: %02X INS: %02X P1: %02X P2: %02X Lc: %02"SC_FORMAT_LEN_SIZE_T"X Le: %02"SC_FORMAT_LEN_SIZE_T"X DATA: [%5"SC_FORMAT_LEN_SIZE_T"u bytes]\n%s======================================================================\n", apdu->cla, apdu->ins, apdu->p1, apdu->p2, @@ -95,7 +95,7 @@ static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag) apdu->lc, apdu->le); } } else { /* apdu response */ - sc_hex_dump(card->ctx, SC_LOG_DEBUG_NORMAL, apdu->resp, apdu->resplen, buf, sizeof(buf)); + sc_hex_dump(apdu->resp, apdu->resplen, buf, sizeof(buf)); sc_log(card->ctx, "\nAPDU response after decode: ==========================================\nSW1: %02X SW2: %02X RESP: [%5"SC_FORMAT_LEN_SIZE_T"u bytes]\n%s======================================================================\n", apdu->sw1, apdu->sw2, apdu->resplen, buf); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 1fa4860cd8..b196a94831 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -403,13 +403,10 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen); if (tag != NULL && taglen > 0 && taglen <= 16) { - char tbuf[128]; - memcpy(file->name, tag, taglen); file->namelen = taglen; - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, file->name, file->namelen, tbuf, sizeof(tbuf)); - sc_log(ctx, " File name: %s", tbuf); + sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, " File name:", file->name, file->namelen); if (!file->type) file->type = SC_FILE_TYPE_DF; } diff --git a/src/libopensc/log.c b/src/libopensc/log.c index f26eadf5ae..01c005d154 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -163,29 +163,25 @@ void _sc_debug_hex(sc_context_t *ctx, int type, const char *file, int line, if (buf == NULL) return; - sc_hex_dump(ctx, type, data, len, buf, blen); + sc_hex_dump(data, len, buf, blen); if (label) sc_do_log(ctx, type, file, line, func, - "\n%s (%u byte%s):\n%s", - label, (unsigned int) len, len==1?"":"s", buf); + "\n%s (%"SC_FORMAT_LEN_SIZE_T"u byte%s):\n%s", + label, len, len==1?"":"s", buf); else sc_do_log(ctx, type, file, line, func, - "%u byte%s:\n%s", - (unsigned int) len, len==1?"":"s", buf); + "%"SC_FORMAT_LEN_SIZE_T"u byte%s:\n%s", + len, len==1?"":"s", buf); free(buf); } -/* Although not used, we need this for consistent exports */ -void sc_hex_dump(struct sc_context *ctx, int level, const u8 * in, size_t count, char *buf, size_t len) +void sc_hex_dump(const u8 * in, size_t count, char *buf, size_t len) { char *p = buf; int lines = 0; - if (!ctx || ctx->debug < level) - return; - if (buf == NULL || (in == NULL && count != 0)) { return; } @@ -219,7 +215,7 @@ void sc_hex_dump(struct sc_context *ctx, int level, const u8 * in, size_t count, } } -char * +const char * sc_dump_hex(const u8 * in, size_t count) { static char dump_buf[0x1000]; @@ -252,7 +248,7 @@ sc_dump_hex(const u8 * in, size_t count) return dump_buf; } -char * +const char * sc_dump_oid(const struct sc_object_id *oid) { static char dump_buf[SC_MAX_OBJECT_ID_OCTETS * 20]; diff --git a/src/libopensc/log.h b/src/libopensc/log.h index d0c6c2809b..a91d86468e 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -87,6 +87,8 @@ void _sc_log(struct sc_context *ctx, const char *format, ...); */ #define sc_debug_hex(ctx, level, label, data, len) \ _sc_debug_hex(ctx, level, __FILE__, __LINE__, __FUNCTION__, label, data, len) +#define sc_log_hex(ctx, label, data, len) \ + sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, label, data, len) /** * @brief Log binary data * @@ -102,9 +104,9 @@ void _sc_log(struct sc_context *ctx, const char *format, ...); void _sc_debug_hex(struct sc_context *ctx, int level, const char *file, int line, const char *func, const char *label, const u8 *data, size_t len); -void sc_hex_dump(struct sc_context *ctx, int level, const u8 * buf, size_t len, char *out, size_t outlen); -char * sc_dump_hex(const u8 * in, size_t count); -char * sc_dump_oid(const struct sc_object_id *oid); +void sc_hex_dump(const u8 *buf, size_t len, char *out, size_t outlen); +const char * sc_dump_hex(const u8 * in, size_t count); +const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_FUNC_CALLED(ctx, level) do { \ sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, "called\n"); \ } while (0) diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index 13cde7ebbe..8b7e8ec2dc 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -91,24 +91,11 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, } if (!rv && ctx) { - char dump_buf[2048]; - - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, - gp_session->card_challenge, sizeof(gp_session->card_challenge), dump_buf, sizeof(dump_buf)); - sc_log(ctx, "Card challenge: %s", dump_buf); - - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, - gp_session->host_challenge, sizeof(gp_session->host_challenge), dump_buf, sizeof(dump_buf)); - sc_log(ctx, "Host challenge: %s", dump_buf); - - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->enc, sizeof(gp_keyset->enc), dump_buf, sizeof(dump_buf)); - sc_log(ctx, "ENC: %s", dump_buf); - - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->mac, sizeof(gp_keyset->mac), dump_buf, sizeof(dump_buf)); - sc_log(ctx, "MAC: %s", dump_buf); - - sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->kek, sizeof(gp_keyset->kek), dump_buf, sizeof(dump_buf)); - sc_log(ctx, "KEK: %s", dump_buf); + sc_log_hex(ctx, "Card challenge", gp_session->card_challenge, sizeof(gp_session->card_challenge)); + sc_log_hex(ctx, "Host challenge", gp_session->host_challenge, sizeof(gp_session->host_challenge)); + sc_log_hex(ctx, "ENC", gp_keyset->enc, sizeof(gp_keyset->enc)); + sc_log_hex(ctx, "MAC", gp_keyset->mac, sizeof(gp_keyset->mac)); + sc_log_hex(ctx, "KEK", gp_keyset->kek, sizeof(gp_keyset->kek)); } return rv; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 3608a5e483..aa675fe7af 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -172,7 +172,7 @@ static void read_dg(sc_card_t *card, unsigned char sfid, const char *dg_str, sfid, dg_str, sc_strerror(r)); else { char buf[0x200]; - sc_hex_dump(NULL, 0, *dg, *dg_len, buf, sizeof buf); + sc_hex_dump(*dg, *dg_len, buf, sizeof buf); fprintf(stdout, "Read %s", buf); } } From baa709ff74631336694c609ccfc2b7c32bd3cf53 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 13 Nov 2017 15:12:43 +0100 Subject: [PATCH 0118/4321] print ASN.1 time and ASCII tranlation --- src/libopensc/asn1.c | 226 +++++++++++++++++++++++++++++-------------- 1 file changed, 156 insertions(+), 70 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 15e0dea06e..c7a629e7ca 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -22,11 +22,12 @@ #include "config.h" #endif -#include -#include -#include #include +#include +#include +#include #include +#include #include "internal.h" #include "asn1.h" @@ -144,40 +145,79 @@ void sc_copy_asn1_entry(const struct sc_asn1_entry *src, dest->name = NULL; } -static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen) +static void print_indent(size_t depth) { - size_t i; + for (; depth > 0; depth--) { + putchar(' '); + } +} + +static void print_hex(const u8 * buf, size_t buflen, size_t depth) +{ + size_t lines_len = buflen * 5 + 128; + char *lines = malloc(lines_len); + char *line = lines; + + if (buf == NULL || buflen == 0 || lines == NULL) + return; + + sc_hex_dump(buf, buflen, lines, lines_len); + + while (*line != '\0') { + char *line_end = strchr(line, '\n'); + ptrdiff_t width = line_end - line; + if (!line_end || width <= 1) { + /* don't print empty lines */ + break; + } + if (buflen > 8) { + putchar('\n'); + print_indent(depth); + } else { + printf(": "); + } + printf("%.*s", (int) width, line); + line = line_end + 1; + } - for (i = 0; i < buflen; i++) - printf("%02X", buf[i]); + free(lines); } -static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen) +static void print_ascii(const u8 * buf, size_t buflen) { - size_t i; + for (; 0 < buflen; buflen--, buf++) { + if (isprint(*buf)) + printf("%c", *buf); + else + putchar('.'); + } +} + +static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen, size_t depth) +{ + print_hex(buf, buflen, depth); +} - for (i = 0; i < buflen; i++) - printf("%c", buf[i]); +static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen) +{ + /* FIXME UTF-8 is not ASCII */ + print_ascii(buf, buflen); } static void sc_asn1_print_integer(const u8 * buf, size_t buflen) { -#ifndef _WIN32 - long long a = 0; -#else - __int64 a = 0; -#endif - size_t i; + size_t a = 0; if (buflen > sizeof(a)) { - printf("too long"); - return; - } - for (i = 0; i < buflen; i++) { - a <<= 8; - a |= buf[i]; + printf("0x%s", sc_dump_hex(buf, buflen)); + } else { + size_t i; + for (i = 0; i < buflen; i++) { + a <<= 8; + a |= buf[i]; + } + printf("%"SC_FORMAT_LEN_SIZE_T"u", a); } - printf("%lld", a); } static void sc_asn1_print_boolean(const u8 * buf, size_t buflen) @@ -191,7 +231,7 @@ static void sc_asn1_print_boolean(const u8 * buf, size_t buflen) printf("false"); } -static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen) +static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth) { #ifndef _WIN32 long long a = 0; @@ -201,16 +241,16 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen) int r, i; if (buflen > sizeof(a) + 1) { - printf("too long"); - return; - } - r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a)); - if (r < 0) { - printf("decode error"); - return; - } - for (i = r - 1; i >= 0; i--) { - printf("%c", ((a >> i) & 1) ? '1' : '0'); + print_hex(buf, buflen, depth); + } else { + r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a)); + if (r < 0) { + printf("decode error"); + return; + } + for (i = r - 1; i >= 0; i--) { + printf("%c", ((a >> i) & 1) ? '1' : '0'); + } } } @@ -223,7 +263,7 @@ static void openssl_print_object_sn(const char *s) if (obj) { int nid = OBJ_obj2nid(obj); if (nid != NID_undef) { - printf("%s ", OBJ_nid2sn(nid)); + printf(", %s", OBJ_nid2sn(nid)); } ASN1_OBJECT_free(obj); } @@ -237,33 +277,71 @@ static void openssl_print_object_sn(const char *s) static void sc_asn1_print_object_id(const u8 * buf, size_t buflen) { struct sc_object_id oid; - int i = 0; - char tmp[12]; - char sbuf[(sizeof tmp)*SC_MAX_OBJECT_ID_OCTETS]; + const char *sbuf; if (sc_asn1_decode_object_id(buf, buflen, &oid)) { printf("decode error"); return; } - sbuf[0] = 0; - for (i = 0; (i < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[i] != -1); i++) { + sbuf = sc_dump_oid(&oid); + printf(" %s", sbuf); + openssl_print_object_sn(sbuf); +} - if (i) - strcat(sbuf, "."); - sprintf(tmp, "%d", oid.value[i]); - strcat(sbuf, tmp); +static void sc_asn1_print_utctime(const u8 * buf, size_t buflen) +{ + if (buflen < 8) { + printf("Error in decoding.\n"); + return; } - openssl_print_object_sn(sbuf); - printf("%s", sbuf); + print_ascii(buf, 2); /* YY */ + putchar('-'); + print_ascii(buf+2, 2); /* MM */ + putchar('-'); + print_ascii(buf+4, 2); /* DD */ + putchar(' '); + print_ascii(buf+6, 2); /* hh */ + buf += 8; + buflen -= 8; + if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) { + putchar(':'); + print_ascii(buf, 2); /* mm */ + buf += 2; + buflen -= 2; + } + if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) { + putchar(':'); + print_ascii(buf, 2); /* ss */ + buf += 2; + buflen -= 2; + } + if (buflen >= 4 && '.' == buf[0]) { + print_ascii(buf, 4); /* fff */ + buf += 4; + buflen -= 4; + } + + if (buflen >= 1 && 'Z' == buf[0]) { + printf(" UTC"); + } else if (buflen >= 5 && ('-' == buf[0] || '+' == buf[0])) { + putchar(' '); + print_ascii(buf, 3); /* +/-hh */ + putchar(':'); + print_ascii(buf+3, 2); /* mm */ + } } static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen) { - size_t ii; - for (ii=0; ii> 8*i)) @@ -312,9 +388,12 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, classes[cla >> 6], i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8)); } - printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)", - len, - len != 1 ? "s" : ""); + if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL + && tag == SC_ASN1_TAG_NULL && len == 0)) { + printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)", + len, + len != 1 ? "s" : ""); + } if (len + hlen > bytesleft) { printf(" Illegal length!\n"); @@ -329,47 +408,54 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, continue; } - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL - && tag != SC_ASN1_TAG_NULL) { - printf(" ["); - switch (tag) { + switch (tag) { case SC_ASN1_TAG_BIT_STRING: - sc_asn1_print_bit_string(tagp, len); + printf(": "); + sc_asn1_print_bit_string(tagp, len, depth + 2*i + 1); break; case SC_ASN1_TAG_OCTET_STRING: - sc_asn1_print_octet_string(tagp, len); + sc_asn1_print_octet_string(tagp, len, depth + 2*i + 1); break; case SC_ASN1_TAG_OBJECT: + printf(": "); sc_asn1_print_object_id(tagp, len); break; case SC_ASN1_TAG_INTEGER: case SC_ASN1_TAG_ENUMERATED: + printf(": "); sc_asn1_print_integer(tagp, len); break; - case SC_ASN1_TAG_T61STRING: + case SC_ASN1_TAG_IA5STRING: case SC_ASN1_TAG_PRINTABLESTRING: + case SC_ASN1_TAG_T61STRING: case SC_ASN1_TAG_UTF8STRING: + printf(": "); sc_asn1_print_utf8string(tagp, len); break; case SC_ASN1_TAG_BOOLEAN: + printf(": "); sc_asn1_print_boolean(tagp, len); break; case SC_ASN1_GENERALIZEDTIME: + printf(": "); sc_asn1_print_generalizedtime(tagp, len); break; - } - printf("]"); + case SC_ASN1_UTCTIME: + printf(": "); + sc_asn1_print_utctime(tagp, len); + break; } - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) - printf(" [%s]", sc_dump_hex(tagp, len)); + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) { + print_hex(tagp, len, depth + 2*i + 1); + } - if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) - printf(" [%s]", sc_dump_hex(tagp, len)); + if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) { + print_hex(tagp, len, depth + 2*i + 1); + } putchar('\n'); } - return; } void sc_asn1_print_tags(const u8 * buf, size_t buflen) From 2494765cdc92fb328ed31431b4e3b74f3c5c4896 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 27 Sep 2017 10:53:12 +0200 Subject: [PATCH 0119/4321] CTK: fixed initializing ATR and UID --- src/libopensc/reader-cryptotokenkit.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index cead041c71..8101fe7072 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -329,6 +329,8 @@ int cryptotokenkit_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void /* attempt to detect protocol in use T0/T1/RAW */ ctk_set_proto(reader); + cryptotokenkit_detect_card_presence(reader); + r = _sc_add_reader(ctx, reader); err: From b4072af26ebf7d60da0521c769f1c83c786118cc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Oct 2017 23:49:04 +0200 Subject: [PATCH 0120/4321] export sc_card_find_ec_alg --- src/libopensc/libopensc.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index c402ffb60e..f7385245df 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -323,6 +323,7 @@ sc_pkcs15init_verify_secret sc_pkcs15init_sanity_check sc_pkcs15init_finalize_profile sc_card_find_rsa_alg +sc_card_find_ec_alg sc_check_apdu sc_print_cache sc_find_app From ad6515ba55ba9da90c2d3f17c8e0074bb1731dc3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Oct 2017 17:59:50 +0200 Subject: [PATCH 0121/4321] CTX: detect card resets --- src/libopensc/reader-cryptotokenkit.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index 8101fe7072..a889fc65ae 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -155,9 +155,13 @@ static int cryptotokenkit_connect(sc_reader_t *reader) priv->tksmartcard = [priv->tksmartcardslot makeSmartCard]; } - if (!priv->tksmartcard || ![priv->tksmartcard valid]) + if (!priv->tksmartcard || !priv->tksmartcard.valid) return SC_ERROR_CARD_NOT_PRESENT; + /* if tksmartcard.context is set to nil, we know that the card has been + * reset or aquired by a different session */ + priv->tksmartcard.context = @(YES); + /* attempt to detect protocol in use T0/T1/RAW */ ctk_set_proto(reader); @@ -185,6 +189,12 @@ static int cryptotokenkit_lock(sc_reader_t *reader) if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) goto err; + if (priv->tksmartcard.context == nil) { + r = SC_ERROR_CARD_RESET; + priv->tksmartcard.context = @(YES); + goto err; + } + [priv->tksmartcard beginSessionWithReply:^(BOOL success, NSError *error) { if (success != TRUE) { NSLog(@"Error locking card <%@>", error); From c70ed3466955818afba383e7854d514e329d424b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 12 Oct 2017 08:39:19 +0200 Subject: [PATCH 0122/4321] CTK: Added support for PIN pad --- src/libopensc/reader-cryptotokenkit.m | 206 ++++++++++++++++++++++++-- 1 file changed, 195 insertions(+), 11 deletions(-) diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index a889fc65ae..ad73843a01 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -43,6 +43,30 @@ NULL }; +static int convertError(NSError *error) +{ + switch (error.code) { + case TKErrorCodeNotImplemented: + return SC_ERROR_NOT_IMPLEMENTED; + case TKErrorCodeCommunicationError: + return SC_ERROR_TRANSMIT_FAILED; + case TKErrorCodeCorruptedData: + return SC_ERROR_CORRUPTED_DATA; + case TKErrorCodeCanceledByUser: + return SC_ERROR_KEYPAD_CANCELLED; + case TKErrorCodeAuthenticationFailed: + return SC_ERROR_PIN_CODE_INCORRECT; + case TKErrorCodeObjectNotFound: + return SC_ERROR_OBJECT_NOT_FOUND; + case TKErrorCodeTokenNotFound: + return SC_ERROR_CARD_REMOVED; + case TKErrorCodeBadParameter: + return SC_ERROR_INVALID_ARGUMENTS; + default: + return SC_ERROR_UNKNOWN; + } +} + static int cryptotokenkit_init(sc_context_t *ctx) { return SC_SUCCESS; @@ -197,8 +221,7 @@ static int cryptotokenkit_lock(sc_reader_t *reader) [priv->tksmartcard beginSessionWithReply:^(BOOL success, NSError *error) { if (success != TRUE) { - NSLog(@"Error locking card <%@>", error); - r = SC_ERROR_UNKNOWN; + r = convertError(error); } else { r = SC_SUCCESS; } @@ -250,18 +273,14 @@ static int cryptotokenkit_transmit(sc_reader_t *reader, sc_apdu_t *apdu) if (response) { rsize = [response length]; rbuf = malloc(rsize); - if (!rbuf) + if (!rbuf) { r = SC_ERROR_OUT_OF_MEMORY; - else - memcpy(rbuf, (unsigned char*) [response bytes], rsize); - } - if (r == SC_SUCCESS) { - if (error) { - NSLog(@"Error transmitting to card <%@>", error); - r = SC_ERROR_TRANSMIT_FAILED; } else { + memcpy(rbuf, (unsigned char*) [response bytes], rsize); r = SC_SUCCESS; } + } else { + r = convertError(error); } dispatch_semaphore_signal(sema); }]; @@ -285,6 +304,169 @@ static int cryptotokenkit_transmit(sc_reader_t *reader, sc_apdu_t *apdu) LOG_FUNC_RETURN(reader->ctx, r); } +TKSmartCardPINFormat *getPINFormat(struct sc_pin_cmd_pin *pin) +{ + TKSmartCardPINFormat *format = [[TKSmartCardPINFormat alloc] init]; + switch (pin->encoding) { + case SC_PIN_ENCODING_GLP: + /* GLP PIN length is encoded in 4 bits and block size is always 8 bytes */ + format.PINLengthBitSize = 4; + format.PINBlockByteLength = 8; + /* fall through */ + case SC_PIN_ENCODING_BCD: + format.encoding = TKSmartCardPINEncodingBCD; + break; + case SC_PIN_ENCODING_ASCII: + format.encoding = TKSmartCardPINEncodingASCII; + format.PINBlockByteLength = pin->pad_length; + break; + default: + return nil; + } + format.minPINLength = pin->min_length; + format.maxPINLength = pin->max_length; + if (pin->length_offset > 4) { + format.PINLengthBitOffset = (pin->length_offset-5)*8; + } + + return format; +} + +int cryptotokenkit_perform_verify(struct sc_reader *reader, struct sc_pin_cmd_data *data) +{ + u8 template[SC_MAX_APDU_BUFFER_SIZE]; + __block int r; + __block UInt16 sw; + size_t ssize = 0; + u8 *sbuf = NULL, *rbuf = NULL; + struct cryptotokenkit_private_data *priv = reader->drv_data; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + LOG_FUNC_CALLED(reader->ctx); + + if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) + return SC_ERROR_NOT_ALLOWED; + + /* The APDU must be provided by the card driver */ + if (!data->apdu) { + return SC_ERROR_NOT_SUPPORTED; + } + + r = sc_apdu_get_octets(reader->ctx, data->apdu, &sbuf, &ssize, reader->active_protocol); + LOG_TEST_GOTO_ERR(reader->ctx, r, "Could not encode APDU template"); + + NSData *apdu = [NSData dataWithBytes:sbuf length:ssize]; + TKSmartCardPINFormat *format; + struct sc_pin_cmd_pin *pin_ref = &data->pin1; + TKSmartCardUserInteractionForPINOperation *interaction; + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + format = getPINFormat(pin_ref); + NSInteger offset; + if (data->pin1.length_offset != 4) { + offset = data->pin1.offset - 5; + } else { + offset = 0; + } + interaction = [priv->tksmartcard userInteractionForSecurePINVerificationWithPINFormat:format APDU:apdu PINByteOffset:offset]; + break; + case SC_PIN_CMD_CHANGE: + case SC_PIN_CMD_UNBLOCK: + if (data->flags & SC_PIN_CMD_IMPLICIT_CHANGE) { + pin_ref = &data->pin2; + } + /* TODO: set confirmation and text */ + format = getPINFormat(pin_ref); + NSInteger oldOffset, newOffset; + if (data->pin1.length_offset != 4) { + oldOffset = data->pin1.offset - 5; + newOffset = data->pin2.offset - 5; + } else { + oldOffset = 0; + newOffset = 0; + } + interaction = [priv->tksmartcard userInteractionForSecurePINChangeWithPINFormat:format APDU:apdu currentPINByteOffset:oldOffset newPINByteOffset:newOffset]; + break; + default: + sc_log(reader->ctx, "Unknown PIN command %d", data->cmd); + r = SC_ERROR_NOT_SUPPORTED; + goto err; + } + if (nil == interaction) { + r = SC_ERROR_NOT_SUPPORTED; + goto err; + } + + [interaction runWithReply:^(BOOL success, NSError *error) { + if (success) { + NSData *response = interaction.resultData; + if (nil != response) { + data->apdu->resplen = response.length; + memcpy(data->apdu->resp, (unsigned char *) response.bytes, response.length); + } else { + data->apdu->resplen = 0; + } + sw = interaction.resultSW; + r = SC_SUCCESS; + } else { + r = convertError(error); + } + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + if (r != SC_SUCCESS) { + goto err; + } + + data->apdu->sw1 = sw >> 8; + data->apdu->sw2 = sw & 0xFF; + + switch (sw) { + case 0x6400: + /* Input timed out */ + r = SC_ERROR_KEYPAD_TIMEOUT; + break; + case 0x6401: + /* Input cancelled */ + r = SC_ERROR_KEYPAD_CANCELLED; + break; + case 0x6402: + /* PINs don't match */ + r = SC_ERROR_KEYPAD_PIN_MISMATCH; + break; + case 0x6403: + /* Entered PIN is not in length limits */ + r = SC_ERROR_INVALID_PIN_LENGTH; /* XXX: designed to be returned when PIN is in API call */ + break; + case 0x6B80: + /* Wrong data in the buffer, rejected by firmware */ + r = SC_ERROR_READER; + break; + } + +err: + if (sbuf != NULL) { + sc_mem_clear(sbuf, ssize); + free(sbuf); + } + + LOG_FUNC_RETURN(reader->ctx, r); +} + +void cryptotokenkit_detect_reader_features(struct sc_reader *reader, TKSmartCard* tksmartcard) +{ + if (tksmartcard) { + const u8 template[] = {tksmartcard.cla, 0x20, 0x00, 0x80, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + NSData *data = [NSData dataWithBytes:template length:sizeof template]; + TKSmartCardPINFormat *PINFormat = [[TKSmartCardPINFormat alloc] init]; + PINFormat.PINBitOffset = 0; + + if (nil != [tksmartcard userInteractionForSecurePINVerificationWithPINFormat:PINFormat APDU:data PINByteOffset:0]) + reader->capabilities |= SC_READER_CAP_PIN_PAD; + } +} + int cryptotokenkit_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void *pcsc_card_handle) { int r; @@ -341,6 +523,8 @@ int cryptotokenkit_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void cryptotokenkit_detect_card_presence(reader); + cryptotokenkit_detect_reader_features(reader, tksmartcard); + r = _sc_add_reader(ctx, reader); err: @@ -426,7 +610,7 @@ static int cryptotokenkit_detect_readers(sc_context_t *ctx) cryptotokenkit_ops.lock = cryptotokenkit_lock; cryptotokenkit_ops.unlock = cryptotokenkit_unlock; cryptotokenkit_ops.transmit = cryptotokenkit_transmit; - cryptotokenkit_ops.perform_verify = NULL; + cryptotokenkit_ops.perform_verify = cryptotokenkit_perform_verify; cryptotokenkit_ops.perform_pace = NULL; cryptotokenkit_ops.use_reader = cryptotokenkit_use_reader; cryptotokenkit_ops.detect_readers = cryptotokenkit_detect_readers; From c9984ca7628e3f4655a7f78e89e1520b08db3209 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 13 Oct 2017 13:31:57 +0200 Subject: [PATCH 0123/4321] MacOS: optionally use CTK in package builder --- MacOSX/build-package.in | 91 ++++++++++++++++++++++++++--------------- MacOSX/opensc-uninstall | 1 + 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 5724f9bfa0..75829f0613 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -6,6 +6,17 @@ # You need to have the following from homebrew or macports or fink: # autoconf automake libtool pkg-config +# If you want to compile with OpenSCToken/CryptoTokenKit set the following: +#ENABLE_CRYPTOTOKENKIT="--disable-pcsc --enable-cryptotokenkit" +# When using CryptoTokenKit, code signing is required +#SIGNING_IDENTITY=BA3CE53D402E3C75246557E2890F929F4A778DDE + +if test -z "$ENABLE_CRYPTOTOKENKIT"; then + MACOS_VERSION_MIN="10.10" +else + MACOS_VERSION_MIN="10.12" +fi + set -ex test -x ./configure || ./bootstrap BUILDPATH=${PWD} @@ -14,7 +25,7 @@ BUILDPATH=${PWD} SDK_PATH=$(xcrun --sdk macosx --show-sdk-path) # Set SDK path -export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=10.10" +export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=$MACOS_VERSION_MIN" export SED=/usr/bin/sed PREFIX=/Library/OpenSC @@ -28,7 +39,7 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then git clone --depth=1 https://github.com/openssl/openssl.git -b OpenSSL_1_0_2-stable fi cd openssl - KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=10.10 + KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=$MACOS_VERSION_MIN make clean make update make depend @@ -58,6 +69,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then --sysconfdir=$PREFIX/etc \ --enable-cvcdir=$PREFIX/etc/cvc \ --enable-x509dir=$PREFIX/etc/x509 \ + $ENABLE_CRYPTOTOKENKIT \ --disable-dependency-tracking \ --enable-shared \ --disable-static \ @@ -72,56 +84,69 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then make -j 2 # copy files - rm -rf target + rm -rf ${BUILDPATH}/target make install DESTDIR=${BUILDPATH}/target # remove garbage - rm -f target/$PREFIX/lib/*.la + rm -f ${BUILDPATH}/target/$PREFIX/lib/*.la # generate .bundle (required by Adobe Acrobat) - ./MacOSX/libtool-bundle target/$PREFIX/lib/opensc-pkcs11.so target/$PREFIX/lib + ./MacOSX/libtool-bundle ${BUILDPATH}/target/$PREFIX/lib/opensc-pkcs11.so ${BUILDPATH}/target/$PREFIX/lib fi -# Check out OpenSC.tokend, if not already fetched. -if ! test -e OpenSC.tokend; then - git clone http://github.com/OpenSC/OpenSC.tokend.git -fi +if test -z "$ENABLE_CRYPTOTOKENKIT"; then + # Check out OpenSC.tokend, if not already fetched. + if ! test -e OpenSC.tokend; then + git clone http://github.com/OpenSC/OpenSC.tokend.git + fi -# Create the symlink to OpenSC sources -test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src + # Create the symlink to OpenSC sources + test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src + + # Build and copy OpenSC.tokend + xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target + + #if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then + #if ! test -e terminal-notifier-1.7.1.zip; then + #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip + #fi + #if ! test -e terminal-notifier-1.7.1; then + #unzip terminal-notifier-1.7.1.zip + #fi + #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications + #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications + #fi -# Build and copy OpenSC.tokend -xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target + if ! test -e NotificationProxy; then + git clone http://github.com/frankmorgner/NotificationProxy.git + fi + xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ + mkdir -p "$BUILDPATH/target/Applications" + osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" +else + # Check out OpenSCToken, if not already fetched. + if ! test -e OpenSCToken; then + git clone http://github.com/frankmorgner/OpenSCToken.git + fi -#if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then - #if ! test -e terminal-notifier-1.7.1.zip; then - #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip - #fi - #if ! test -e terminal-notifier-1.7.1; then - #unzip terminal-notifier-1.7.1.zip - #fi - #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications - #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications -#fi + # Build and copy OpenSCToken + xcodebuild -target OpenSCToken -configuration Deployment -project OpenSCToken/OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target -if ! test -e NotificationProxy; then - git clone http://github.com/frankmorgner/NotificationProxy.git + #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/bin/* + #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/lib/*.dylib + #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements --deep target/Library/OpenSC/lib/opensc-pkcs11.bundle fi -xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ -mkdir -p "$BUILDPATH/target/Applications" -osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" # Prepare target root -# The "UnInstaller" -mkdir -p target/usr/local/bin -cp MacOSX/opensc-uninstall target/usr/local/bin +mkdir -p ${BUILDPATH}/target/usr/local/bin +cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin # Build package -pkgbuild --root target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg +pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg # Build product productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "OpenSC @PACKAGE_VERSION@.pkg" -# Build "uninstaller" +# Build "Uninstaller" osacompile -o "OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript" # Create .dmg diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index d4331a9ad9..e34368da9e 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -20,6 +20,7 @@ rm -rf "/Applications/OpenSC Notify.app" rm -rf /Library/OpenSC rm -rf /Library/Security/tokend/OpenSC.tokend rm -rf /System/Library/Security/tokend/OpenSC.tokend +rm -rf /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/OpenSCToken.appex # delete receipts on 10.6+ for file in /var/db/receipts/org.opensc-project.mac.bom /var/db/receipts/org.opensc-project.mac.plist; do From 20ea45b8f11137ba9d816723fc8b607242796c07 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Oct 2017 11:13:57 +0100 Subject: [PATCH 0124/4321] allow static linking of OpenSCToken --- MacOSX/build-package.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 75829f0613..0fe0b66acf 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -72,7 +72,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then $ENABLE_CRYPTOTOKENKIT \ --disable-dependency-tracking \ --enable-shared \ - --disable-static \ + --enable-static \ --enable-strict \ --disable-assert \ --enable-sm # TODO: remove this (must be sensible default in master) @@ -89,6 +89,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then # remove garbage rm -f ${BUILDPATH}/target/$PREFIX/lib/*.la + rm -f ${BUILDPATH}/target/$PREFIX/lib/*.a # generate .bundle (required by Adobe Acrobat) ./MacOSX/libtool-bundle ${BUILDPATH}/target/$PREFIX/lib/opensc-pkcs11.so ${BUILDPATH}/target/$PREFIX/lib From 718d4852dad67ad1a9d8182072c41da8f6754b44 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Nov 2017 16:14:25 +0100 Subject: [PATCH 0125/4321] use pluginkit to register OpenSCToken --- MacOSX/build-package.in | 4 ++-- MacOSX/opensc-uninstall | 6 +++++- MacOSX/scripts/postinstall | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 0fe0b66acf..0b60ecb406 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -130,8 +130,8 @@ else git clone http://github.com/frankmorgner/OpenSCToken.git fi - # Build and copy OpenSCToken - xcodebuild -target OpenSCToken -configuration Deployment -project OpenSCToken/OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target + # Build and copy OpenSCTokenApp + xcodebuild -target OpenSCTokenApp -configuration Release -project OpenSCToken/OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/bin/* #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/lib/*.dylib diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index e34368da9e..1a71161a49 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -20,7 +20,11 @@ rm -rf "/Applications/OpenSC Notify.app" rm -rf /Library/OpenSC rm -rf /Library/Security/tokend/OpenSC.tokend rm -rf /System/Library/Security/tokend/OpenSC.tokend -rm -rf /System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/OpenSCToken.appex + +if [ -e "/Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex" ] +then + pluginkit -r /Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex +fi # delete receipts on 10.6+ for file in /var/db/receipts/org.opensc-project.mac.bom /var/db/receipts/org.opensc-project.mac.plist; do diff --git a/MacOSX/scripts/postinstall b/MacOSX/scripts/postinstall index fed5aa8649..27ba2a4b36 100755 --- a/MacOSX/scripts/postinstall +++ b/MacOSX/scripts/postinstall @@ -19,4 +19,8 @@ for f in /Library/OpenSC/bin/* do ln -sf $f /usr/local/bin done +if [ -e "/Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex" ] +then + pluginkit -a /Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex +fi exit 0 From 027205cc4d0eb99a77e2a7eba172285d8feac8f5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Nov 2017 16:29:19 +0100 Subject: [PATCH 0126/4321] use MACOSX_DEPLOYMENT_TARGET --- MacOSX/build-package.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 0b60ecb406..6236477134 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -12,9 +12,9 @@ #SIGNING_IDENTITY=BA3CE53D402E3C75246557E2890F929F4A778DDE if test -z "$ENABLE_CRYPTOTOKENKIT"; then - MACOS_VERSION_MIN="10.10" + export MACOSX_DEPLOYMENT_TARGET="10.10" else - MACOS_VERSION_MIN="10.12" + export MACOSX_DEPLOYMENT_TARGET="10.12" fi set -ex @@ -25,7 +25,7 @@ BUILDPATH=${PWD} SDK_PATH=$(xcrun --sdk macosx --show-sdk-path) # Set SDK path -export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=$MACOS_VERSION_MIN" +export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" export SED=/usr/bin/sed PREFIX=/Library/OpenSC @@ -39,7 +39,7 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then git clone --depth=1 https://github.com/openssl/openssl.git -b OpenSSL_1_0_2-stable fi cd openssl - KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=$MACOS_VERSION_MIN + KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET make clean make update make depend From c35eb1c9bc74e284723ffd726478720b69aed970 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 6 Nov 2017 09:13:20 +0100 Subject: [PATCH 0127/4321] macOS: Disable notifications by default fixes https://github.com/OpenSC/OpenSC/issues/1174 --- MacOSX/build-package.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 6236477134..bb832cc645 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -70,6 +70,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then --enable-cvcdir=$PREFIX/etc/cvc \ --enable-x509dir=$PREFIX/etc/x509 \ $ENABLE_CRYPTOTOKENKIT \ + --disable-notify \ --disable-dependency-tracking \ --enable-shared \ --enable-static \ From 9a2a62e641c65423b6116d4a352eecb5fc165c7c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Nov 2017 16:14:25 +0100 Subject: [PATCH 0128/4321] fixed codesigning of opensc tools --- MacOSX/build-package.in | 6 +++--- MacOSX/opensc.entitlements | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 MacOSX/opensc.entitlements diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index bb832cc645..5611b74087 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -134,9 +134,9 @@ else # Build and copy OpenSCTokenApp xcodebuild -target OpenSCTokenApp -configuration Release -project OpenSCToken/OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target - #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/bin/* - #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements target/Library/OpenSC/lib/*.dylib - #codesign --sign "$SIGNING_IDENTITY" --force --entitlements OpenSCToken/OpenSCToken/opensctoken.entitlements --deep target/Library/OpenSC/lib/opensc-pkcs11.bundle + codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements target/Library/OpenSC/bin/* + codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements target/Library/OpenSC/lib/*.dylib + codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements --deep target/Library/OpenSC/lib/opensc-pkcs11.bundle fi # Prepare target root diff --git a/MacOSX/opensc.entitlements b/MacOSX/opensc.entitlements new file mode 100644 index 0000000000..0eecdb30ae --- /dev/null +++ b/MacOSX/opensc.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.smartcard + + + From 0211f638c353fbeec3d35769512bf93b8c47de03 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 14 Nov 2017 21:56:43 +0100 Subject: [PATCH 0129/4321] only set MACOSX_DEPLOYMENT_TARGET which is equivalent to use -mmacosx-version-min --- MacOSX/build-package.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 5611b74087..123cdf5c24 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -25,7 +25,7 @@ BUILDPATH=${PWD} SDK_PATH=$(xcrun --sdk macosx --show-sdk-path) # Set SDK path -export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" +export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64" export SED=/usr/bin/sed PREFIX=/Library/OpenSC @@ -39,7 +39,7 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then git clone --depth=1 https://github.com/openssl/openssl.git -b OpenSSL_1_0_2-stable fi cd openssl - KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET + KERNEL_BITS=64 ./config --prefix=$PREFIX make clean make update make depend From f1aa2a61c94870b71f054f1d53c860ae7ceb2619 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 9 Nov 2017 14:42:30 +0200 Subject: [PATCH 0130/4321] Cleanup expired EstEID card ATR-s Signed-off-by: Raul Metsma --- etc/opensc.conf.in | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 83b7deed98..d1b3730b05 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -379,33 +379,11 @@ app default { # driver = "piv"; # } - # Estonian ID card and Micardo driver sometimes only play together with T=0 + # Micardo driver sometimes only play together with T=0 # In theory only the 'cold' ATR should be specified, as T=0 will # be the preferred protocol once you boot it up with T=0, but be # paranoid. # - # Warm ATR v1 - card_atr 3b:6e:00:ff:45:73:74:45:49:44:20:76:65:72:20:31:2e:30 { - force_protocol = t0; - } - # Cold ATR v1 - card_atr 3b:fe:94:00:ff:80:b1:fa:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:43 { - force_protocol = t0; - } - # Warm ATR v2 - card_atr 3b:5e:11:ff:45:73:74:45:49:44:20:76:65:72:20:31:2e:30 { - force_protocol = t0; - } - # Cold ATR v2 - card_atr 3b:de:18:ff:c0:80:b1:fe:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:2b { - force_protocol = t0; - } - # Digi-ID cold ATR. The same card has the same warm ATR as "Cold ATR v1" above - # The card is claimed to only support T=0 but in fact (sometimes) works with T=1, even if not advertised in ATR. - card_atr 3b:6e:00:00:45:73:74:45:49:44:20:76:65:72:20:31:2e:30 { - force_protocol = t0; - } - # D-Trust cards are also based on micardo and need T=0 for some reason card_atr 3b:ff:94:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:23 { force_protocol = t0; From 514f89867158ab4054c9c2f9920d5c6ca2834fae Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 17 Nov 2017 11:46:34 +0200 Subject: [PATCH 0131/4321] Fix reading EstEID certificates with T=0 (#1193) --- src/libopensc/card-mcrd.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index e4f711e636..57ead6bdf8 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -365,15 +365,20 @@ static int mcrd_init(sc_card_t * card) if(apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); - apdu.lc = sizeof(EstEID_v35_AID); - apdu.data = EstEID_v35_AID; - apdu.datalen = sizeof(EstEID_v35_AID); - apdu.resplen = 0; - apdu.le = 0; + apdu.lc = sizeof(EstEID_v35_AID); + apdu.data = EstEID_v35_AID; + apdu.datalen = sizeof(EstEID_v35_AID); + apdu.resplen = 0; + apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); - if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary + // sc_read_binary cannot handle recursive 61 00 calls + if (card->reader && card->reader->active_protocol == SC_PROTO_T0) + card->max_recv_size = 255; + } else { sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); apdu.lc = sizeof(AzeDIT_v35_AID); apdu.data = AzeDIT_v35_AID; From 09af8714ad111d4e957a1f2f82e586cd5f20fd59 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 17 Nov 2017 10:47:53 +0100 Subject: [PATCH 0132/4321] Avoid GCC 7 warnings with -Werror (#1196) * Avoid GCC 7 warnings with -Werror -Werror=implicit-fallthrough= libopensc/card-incrypto34.c not sure if this is a bug or intention libopensc/card-rutoken.c most probably intention libopensc/card-westcos.c remove bogus if so the compile is not confused I will fill a separate bug to gcc probably pkcs15init/pkcs15-iasecc.c Simplify the log and avoid compiler confusion sm/sm-common.c explicit fallthrough tools/pkcs11-tool.c use explicit fallthrough comment tools/pkcs15-init.c The fallthrough is obvious here -Werror=format-truncation= libopensc/pkcs15-itacns.c use explicit string lengths pkcs11/framework-pkcs15.c calculate the truncation tests/pintest.c avoid sprintf tools/pkcs15-crypt.c avoid sprintf tools/pkcs15-init.c calculate the truncation --- src/libopensc/card-incrypto34.c | 1 + src/libopensc/card-rutoken.c | 3 ++- src/libopensc/card-westcos.c | 2 +- src/libopensc/pkcs15-itacns.c | 6 ++++-- src/pkcs11/framework-pkcs15.c | 6 ++++-- src/pkcs15init/pkcs15-iasecc.c | 3 ++- src/sm/sm-common.c | 7 +++++++ src/tests/pintest.c | 6 ++++-- src/tools/pkcs11-tool.c | 2 +- src/tools/pkcs15-crypt.c | 6 ++++-- src/tools/pkcs15-init.c | 8 ++++++-- 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 676a755dc7..7804af4c2a 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -357,6 +357,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) * generation. */ case SC_FILE_EF_LINEAR_VARIABLE_TLV: type[1] = 0xff; + /* fall through */ default: type[0] |= file->ef_structure & 7; break; diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 6e2276a58b..6c71070360 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -925,7 +925,8 @@ static int rutoken_get_do_info(sc_card_t *card, sc_DO_INFO_t * pInfo) apdu.cse = SC_APDU_CASE_2_SHORT; break; case select_next: - apdu.p2 = 0x02; + apdu.p2 = 0x02; + /* fall through */ case select_by_id: data[0] = pInfo->DoId; apdu.data = data; diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 0e62029667..3c03c666e4 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -972,7 +972,7 @@ static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) data.pin1.data = priv_data->default_key.key_value; return sc_pin_cmd(card, &data, NULL); case SC_CARDCTL_WESTCOS_CHANGE_KEY: - if (1) { + { int lrc; u8 temp[7]; sc_changekey_t *ck = (sc_changekey_t *) ptr; diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 53aa2b0a53..4941e78df8 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -473,8 +473,10 @@ static int get_name_from_EF_DatiPersonali(unsigned char *EFdata, if (fields[f_first_name].len + fields[f_last_name].len + 1 >= name_len) return -1; - snprintf(name, name_len, "%s %s", - fields[f_first_name].value, fields[f_last_name].value); + /* the lengths are already checked that they will fit in buffer */ + snprintf(name, name_len, "%.*s %.*s", + fields[f_first_name].len, fields[f_first_name].value, + fields[f_last_name].len, fields[f_last_name].value); return 0; } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ad398d8fc1..2fe8ad5c34 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1043,7 +1043,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, { struct pkcs15_slot_data *fw_data; struct sc_pkcs15_auth_info *pin_info = NULL; - char label[64]; + char label[(sizeof auth->label) + 10]; sc_log(context, "Called"); pkcs15_init_token_info(p15card, &slot->token_info); @@ -1071,7 +1071,9 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, } else { if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) - snprintf(label, sizeof(label), "%.*s (%s)", (int) sizeof auth->label, auth->label, p15card->tokeninfo->label); + snprintf(label, sizeof(label), "%.*s (%s)", + (int) sizeof(auth->label), auth->label, + p15card->tokeninfo->label); else /* The PIN label is empty or says just non-useful "PIN" */ snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label); diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index ce2e8e3f14..e5bc2c79d3 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -335,7 +335,8 @@ iasecc_file_convert_acls(struct sc_context *ctx, struct sc_profile *profile, str if (acl) { switch (acl->method) { case SC_AC_IDA: - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "'IDA' not actually supported"); + sc_log(ctx, "'IDA' not actually supported"); + return SC_ERROR_NOT_SUPPORTED; case SC_AC_SCB: if ((acl->key_ref & IASECC_SCB_METHOD_MASK) == IASECC_SCB_METHOD_USER_AUTH) { acl->method = SC_AC_SEN; diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 49647b7aba..0a19eb203d 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -62,12 +62,19 @@ l1=l2=0; \ switch (n) { \ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + /* fall through */ \ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + /* fall through */ \ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + /* fall through */ \ case 5: l2|=((DES_LONG)(*(--(c)))); \ + /* fall through */ \ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + /* fall through */ \ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + /* fall through */ \ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + /* fall through */ \ case 1: l1|=((DES_LONG)(*(--(c)))); \ } \ } diff --git a/src/tests/pintest.c b/src/tests/pintest.c index 42607f3b95..1003dbc246 100644 --- a/src/tests/pintest.c +++ b/src/tests/pintest.c @@ -13,6 +13,7 @@ #include #endif +#include "libopensc/internal.h" #include "libopensc/opensc.h" #include "libopensc/pkcs15.h" #include "common/compat_getpass.h" @@ -56,7 +57,7 @@ static int ask_and_verify_pin(struct sc_pkcs15_object *pin_obj) { struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *) pin_obj->data; int i = 0; - char prompt[80]; + char prompt[(sizeof pin_obj->label) + 30]; u8 *pass; if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) { @@ -64,7 +65,8 @@ static int ask_and_verify_pin(struct sc_pkcs15_object *pin_obj) return 0; } - sprintf(prompt, "Please enter PIN code [%.*s]: ", (int) sizeof pin_obj->label, pin_obj->label); + snprintf(prompt, sizeof(prompt), "Please enter PIN code [%.*s]: ", + (int) sizeof pin_obj->label, pin_obj->label); pass = (u8 *) getpass(prompt); if (SC_SUCCESS != sc_lock(card)) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 68b41b46f5..876bba2dcc 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1908,7 +1908,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; default: oaep_params.hashAlg = CKM_SHA_1; - /* fallthrough to SHA-1 default */ + /* fall through */ case CKM_SHA_1: oaep_params.mgf = CKG_MGF1_SHA1; break; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 52dc853be0..e8ef279af0 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -34,6 +34,7 @@ #endif #include "common/compat_getpass.h" +#include "libopensc/internal.h" #include "libopensc/opensc.h" #include "libopensc/pkcs15.h" #include "libopensc/asn1.h" @@ -129,7 +130,7 @@ static char *readpin_stdin(void) static char * get_pin(struct sc_pkcs15_object *obj) { - char buf[80]; + char buf[(sizeof obj->label) + 20]; char *pincode; struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) obj->data; @@ -143,7 +144,8 @@ static char * get_pin(struct sc_pkcs15_object *obj) return strdup(opt_pincode); } - sprintf(buf, "Enter PIN [%.*s]: ", (int) sizeof obj->label, obj->label); + snprintf(buf, sizeof(buf), "Enter PIN [%.*s]: ", + (int) sizeof obj->label, obj->label); while (1) { pincode = getpass(buf); if (strlen(pincode) == 0) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 38a40b92ac..985d6b1070 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -61,6 +61,7 @@ #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ #include "common/compat_strlcpy.h" +#include "libopensc/internal.h" #include "libopensc/cardctl.h" #include "libopensc/pkcs15.h" #include "libopensc/log.h" @@ -2793,6 +2794,7 @@ handle_option(const struct option *opt) break; case OPT_USE_PINPAD_DEPRECATED: fprintf(stderr, "'--no-prompt' is deprecated , use '--use-pinpad' instead.\n"); + /* fall through */ case OPT_USE_PINPAD: opt_use_pinpad = 1; break; @@ -2889,6 +2891,7 @@ parse_commandline(int argc, char **argv) switch (o->has_arg) { case optional_argument: *sp++ = ':'; + /* fall through */ case required_argument: *sp++ = ':'; case no_argument: @@ -3088,7 +3091,7 @@ int get_pin(sc_ui_hints_t *hints, char **out) static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) { struct sc_pkcs15_object *pin_obj = NULL; - char pin_label[64]; + char pin_label[(sizeof pin_obj->label) + 20]; char *pin = NULL; int r; @@ -3142,7 +3145,8 @@ static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) return SC_ERROR_OBJECT_NOT_FOUND; if (pin_obj->label[0]) - snprintf(pin_label, sizeof(pin_label), "User PIN [%s]", pin_obj->label); + snprintf(pin_label, sizeof(pin_label), "User PIN [%.*s]", + (int) sizeof pin_obj->label, pin_obj->label); else snprintf(pin_label, sizeof(pin_label), "User PIN"); memset(&hints, 0, sizeof(hints)); From ddc9baed2524364b22a96a7e63865701ad2be2a1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 Nov 2017 10:42:58 +0100 Subject: [PATCH 0133/4321] added missing opensc-asn1.1 fixes https://github.com/OpenSC/OpenSC/issues/1206 --- src/tools/opensc-asn1.1 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/tools/opensc-asn1.1 diff --git a/src/tools/opensc-asn1.1 b/src/tools/opensc-asn1.1 new file mode 100644 index 0000000000..e56762fcf2 --- /dev/null +++ b/src/tools/opensc-asn1.1 @@ -0,0 +1,21 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH OPENSC-ASN1 "1" "November 2017" "OpenSC 0.17.0" "User Commands" +.SH NAME +opensc-asn1 \- manual page for opensc-asn1 0.17.0 +.SH SYNOPSIS +.B opensc-asn1 +[\fI\,OPTIONS\/\fR]... [\fI\,FILES\/\fR]... +.SH DESCRIPTION +opensc\-asn1 0.17.0 +.PP +Parse ASN.1 data. +.TP +\fB\-h\fR, \fB\-\-help\fR +Print help and exit +.TP +\fB\-V\fR, \fB\-\-version\fR +Print version and exit +.SH AUTHOR +Written by Frank Morgner +.SH "REPORTING BUGS" +Report bugs to opensc\-devel@lists.sourceforge.net From 4444d24f5979bb1d0066d59762c055db1c8c77b5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 15 Nov 2017 08:25:07 +0100 Subject: [PATCH 0134/4321] win32: generate PDB files for releases https://msdn.microsoft.com/fsk896zz.aspx fixes https://github.com/OpenSC/OpenSC/issues/1191 --- appveyor.yml | 20 ++++++++------------ src/libopensc/card-tcos.c | 1 + src/libopensc/log.c | 4 +++- src/tools/westcos-tool.c | 10 +++++++--- win32/Make.rules.mak | 4 ++-- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index bf528b207e..dff2fe192c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,9 +6,7 @@ platform: configuration: - Release - - Debug - Light-Release - - Light-Debug environment: matrix: @@ -29,15 +27,11 @@ install: If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:OPENSSL_PF="Win32" - $env:ARTIFACT="OpenSC-win32_vs${env:VSVER}-${env:CONFIGURATION}.msi" + $env:ARTIFACT="OpenSC-win32_vs${env:VSVER}-${env:CONFIGURATION}" } Else { $env:VCVARS_PLATFORM="amd64" $env:OPENSSL_PF="Win64" - $env:ARTIFACT="OpenSC-win64_vs${env:VSVER}-${env:CONFIGURATION}.msi" - } - - ps: >- - If ($env:Configuration -Like "*Debug*") { - $env:NMAKE_EXTRA="DEBUG_DEF=/DDEBUG ${env:NMAKE_EXTRA}" + $env:ARTIFACT="OpenSC-win64_vs${env:VSVER}-${env:CONFIGURATION}" } - ps: >- If (!($env:Configuration -Like "*Light*")) { @@ -98,13 +92,15 @@ build_script: - cp win32/winconfig.h config.h - nmake /f Makefile.mak %NMAKE_EXTRA% - cd win32 && nmake /f Makefile.mak %NMAKE_EXTRA% VSVER=%VSVER% OpenSC.msi - - move OpenSC.msi %ARTIFACT% - - appveyor PushArtifact %ARTIFACT% + - move OpenSC.msi %ARTIFACT%.msi + - appveyor PushArtifact %ARTIFACT%.msi # put all pdb files for dump analysis, but this consumes approx 100 MB per build + - md %ARTIFACT%-Debug - ps: >- - If ($env:Configuration -Like "*Debug*") { - Get-ChildItem -recurse c:\projects\OpenSC -exclude vc*.pdb *.pdb | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } + Get-ChildItem -recurse C:\projects\OpenSC -exclude vc*.pdb *.pdb | % { + 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName } + - appveyor PushArtifact %ARTIFACT%-Debug.zip cache: - C:\zlib -> appveyor.yml diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 12b7129054..c8a05afb47 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -44,6 +44,7 @@ static struct sc_atr_table tcos_atrs[] = { { "3B:BA:96:00:81:31:86:5D:00:64:05:7B:02:03:31:80:90:00:7D", NULL, NULL, SC_CARD_TYPE_TCOS_V2, 0, NULL }, /* Philips P5CT072 */ { "3B:BF:96:00:81:31:FE:5D:00:64:04:11:03:01:31:C0:73:F7:01:D0:00:90:00:7D", NULL, NULL, SC_CARD_TYPE_TCOS_V3, 0, NULL }, + { "3B:BF:96:00:81:31:FE:5D:00:64:04:11:04:0F:31:C0:73:F7:01:D0:00:90:00:74", NULL, NULL, SC_CARD_TYPE_TCOS_V3, 0, NULL }, /* Philips P5CT080 */ { "3B:BF:B6:00:81:31:FE:5D:00:64:04:28:03:02:31:C0:73:F7:01:D0:00:90:00:67", NULL, NULL, SC_CARD_TYPE_TCOS_V3, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 01c005d154..28c53c599e 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -84,7 +84,9 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin #ifdef _WIN32 GetLocalTime(&st); r = snprintf(p, left, - "%i-%02i-%02i %02i:%02i:%02i.%03i ", + "P:%lu; T:%lu %i-%02i-%02i %02i:%02i:%02i.%03i ", + (unsigned long)GetCurrentProcessId(), + (unsigned long)GetCurrentThreadId(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); #else diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 186bb66b23..b016ea65e3 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -864,14 +864,18 @@ int main(int argc, char *argv[]) b = malloc(file->size); if(b == NULL) { - printf("Not enougth memory.\n"); - goto out; + printf("Not enougth memory.\n"); + goto out; } memset(b, 0, file->size); fp = fopen(put_filename, "rb"); - fread(b, 1, file->size, fp); + if (fp == NULL || file->size != fread(b, 1, file->size, fp)) + { + printf("could not read %s.\n", put_filename); + goto out; + } fclose(fp); r = sc_update_binary(card, 0, b, file->size, 0); diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index fa9d5917c4..93d58f8f4d 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -139,8 +139,8 @@ LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE -LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD /DEBUG /OPT:REF /OPT:ICF +COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /Zi !ENDIF From 3f0d5ce3368a47c17eb1ca46b97c8b9cb3c8e15d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 7 Nov 2017 16:10:28 +0100 Subject: [PATCH 0135/4321] opensc-notify: register a desktop menu entry - fixes showing notifications in gnome-shell via gio2 - removes gdbus interface for notifications - fixes https://github.com/OpenSC/OpenSC/issues/1186 --- configure.ac | 55 +++------ src/tools/Makefile.am | 9 +- ...rg.opensc-project.opensc-notify.desktop.in | 7 ++ src/ui/notify.c | 114 ++---------------- 4 files changed, 43 insertions(+), 142 deletions(-) create mode 100644 src/tools/org.opensc-project.opensc-notify.desktop.in diff --git a/configure.ac b/configure.ac index 8a305f24d2..9b319f28a7 100644 --- a/configure.ac +++ b/configure.ac @@ -459,37 +459,26 @@ case "${host}" in have_notify="yes" ;; *) - AC_PATH_PROG([GDBUS], [gdbus], [not found]) - if test "${GDBUS}" = "not found"; then - have_notify="no" - have_gdbus="no" - else - have_notify="yes" - have_gdbus="yes" - fi - - if test "${have_notify}" = "no"; then - PKG_CHECK_MODULES( [GIO2], [gio-2.0], - [ have_notify="yes" - have_gio2="yes" ], - [ have_notify="no" - have_gio2="no" ]) - saved_CFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} ${GIO2_CFLAGS}" - AC_CHECK_HEADERS(gio/gio.h, [], - [ AC_MSG_WARN([glib2 headers not found]) - have_notify="no" - have_gio2="no" ]) - CFLAGS="${saved_CFLAGS}" - saved_LIBS="$LIBS" - LIBS="$LIBS ${GIO2_LIBS}" - AC_MSG_CHECKING([for g_application_send_notification]) - AC_TRY_LINK_FUNC(g_application_send_notification, [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_WARN([Cannot link against glib2]) - have_notify="no" - have_gio2="no" ]) - LIBS="$saved_LIBS" - fi + PKG_CHECK_MODULES( [GIO2], [gio-2.0], + [ have_notify="yes" + have_gio2="yes" ], + [ have_notify="no" + have_gio2="no" ]) + saved_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${GIO2_CFLAGS}" + AC_CHECK_HEADERS(gio/gio.h, [], + [ AC_MSG_WARN([glib2 headers not found]) + have_notify="no" + have_gio2="no" ]) + CFLAGS="${saved_CFLAGS}" + saved_LIBS="$LIBS" + LIBS="$LIBS ${GIO2_LIBS}" + AC_MSG_CHECKING([for g_application_send_notification]) + AC_TRY_LINK_FUNC(g_application_send_notification, [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_WARN([Cannot link against glib2]) + have_notify="no" + have_gio2="no" ]) + LIBS="$saved_LIBS" ;; esac @@ -509,9 +498,6 @@ esac if test "${enable_notify}" = "yes"; then if test "${have_notify}" = "yes"; then AC_DEFINE([ENABLE_NOTIFY], [1], [Use notification libraries and header files]) - if test "${have_gdbus}" = "yes"; then - AC_DEFINE_UNQUOTED([GDBUS], ["${GDBUS}"], [Path to gdbus]) - fi if test "${have_gio2}" = "yes"; then AC_DEFINE([ENABLE_GIO2], [1], [Use glib2 libraries and header files]) OPTIONAL_NOTIFY_CFLAGS="${GIO2_CFLAGS}" @@ -1117,7 +1103,6 @@ OPENCT_CFLAGS: ${OPENCT_CFLAGS} OPENCT_LIBS: ${OPENCT_LIBS} PCSC_CFLAGS: ${PCSC_CFLAGS} CRYPTOTOKENKIT_CFLAGS: ${CRYPTOTOKENKIT_CFLAGS} -GDBUS: ${GDBUS} GIO2_CFLAGS: ${GIO2_CFLAGS} GIO2_LIBS: ${GIO2_LIBS} diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index e8a0aea797..789b84957d 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -7,6 +7,7 @@ VDFORMAT=GZIP endif do_subst = $(SED) \ + -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]CVCDIR[@],$(CVCDIR),g' \ -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ @@ -24,7 +25,7 @@ OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc-project.opensc-notify.desktop.in noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example @@ -209,5 +210,11 @@ gids_tool_SOURCES += versioninfo-tools.rc opensc_notify_SOURCES += versioninfo-opensc-notify.rc endif +applicationsdir = $(datadir)/applications +applications_DATA = org.opensc-project.opensc-notify.desktop + +org.opensc-project.opensc-notify.desktop: org.opensc-project.opensc-notify.desktop + $(do_subst) < $(abs_srcdir)/org.opensc-project.opensc-notify.desktop.in > $@ + clean-local: rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo diff --git a/src/tools/org.opensc-project.opensc-notify.desktop.in b/src/tools/org.opensc-project.opensc-notify.desktop.in new file mode 100644 index 0000000000..fbb22e3866 --- /dev/null +++ b/src/tools/org.opensc-project.opensc-notify.desktop.in @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=OpenSC Notify +Type=Application +Comment=Monitor smart card events to send notifications. +Exec=@bindir@/opensc-notify +Icon=preferences-system-notifications +Categories=Security;System; diff --git a/src/ui/notify.c b/src/ui/notify.c index 12def1680c..37118fb795 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -24,7 +24,7 @@ #include "notify.h" -#if defined(ENABLE_NOTIFY) && (defined(__APPLE__) || (defined(GDBUS) && !defined(_WIN32))) +#if defined(ENABLE_NOTIFY) && (defined(__APPLE__)) #include "libopensc/internal.h" #include "libopensc/log.h" @@ -371,116 +371,16 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, notify_proxy(ctx, title, NULL, text, icon, NULL, group); } -#elif defined(ENABLE_NOTIFY) && defined(GDBUS) && !defined(_WIN32) - -#include -/* save the notification's id for replacement with a new one */ -uint32_t message_id = 0; - -static void notify_gio(struct sc_context *ctx, - const char *title, const char *text, const char *icon, - const char *group) -{ - char message_id_str[22]; - int pipefd[2]; - int pass_to_pipe = 1; - snprintf(message_id_str, sizeof message_id_str, "%"PRIu32, message_id); - - if (child > 0) { - int status; - if (0 == waitpid(child, &status, WNOHANG)) { - kill(child, SIGKILL); - usleep(100); - if (0 == waitpid(child, &status, WNOHANG)) { - sc_log(ctx, "Can't kill %ld, skipping current notification", (long) child); - return; - } - } - } - - if (0 == pipe(pipefd)) { - pass_to_pipe = 1; - } - - child = fork(); - switch (child) { - case 0: - /* child process */ - if (pass_to_pipe) { - /* close reading end of the pipe */ - close(pipefd[0]); - /* send stdout to the pipe */ - dup2(pipefd[1], 1); - /* this descriptor is no longer needed */ - close(pipefd[1]); - } - - if (0 > execl(GDBUS, GDBUS, - "call", "--session", - "--dest", "org.freedesktop.Notifications", - "--object-path", "/org/freedesktop/Notifications", - "--method", "org.freedesktop.Notifications.Notify", - "org.opensc-project", - message_id_str, - icon ? icon : "", - title ? title : "", - text ? text : "", - "[]", "{}", "5000", - (char *) NULL)) { - perror("exec failed"); - exit(1); - } - break; - case -1: - sc_log(ctx, "failed to fork for notification"); - break; - default: - /* parent process */ - - if (ctx) { - sc_log(ctx, "Created %ld for notification:", (long) child); - sc_log(ctx, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", GDBUS, - "call", "--session", - "--dest", "org.freedesktop.Notifications", - "--object-path", "/org/freedesktop/Notifications", - "--method", "org.freedesktop.Notifications.Notify", - "org.opensc-project", - message_id_str, - icon ? icon : "", - title ? title : "", - text ? text : "", - "[]", "{}", "5000"); - } - - if (pass_to_pipe) { - ssize_t r; - /* close the write end of the pipe */ - close(pipefd[1]); - memset(message_id_str, '\0', sizeof message_id_str); - r = read(pipefd[0], message_id_str, sizeof(message_id_str)); - if (0 < r) { - message_id_str[MIN((sizeof message_id_str) - 1, (size_t) r)] = '\0'; - if (0 >= sscanf(message_id_str, "(uint32 %"SCNu32",)", &message_id)) { - message_id = 0; - } - } - /* close the read end of the pipe */ - close(pipefd[0]); - } - break; - } -} - #elif defined(ENABLE_NOTIFY) && defined(ENABLE_GIO2) -static GtkApplication *application = NULL; - #include +static GApplication *application = NULL; + void sc_notify_init(void) { sc_notify_close(); - application = g_application_new("org.opensc-project", G_APPLICATION_FLAGS_NONE); + application = g_application_new("org.opensc-project.opensc-notify", G_APPLICATION_FLAGS_NONE); if (application) { g_application_register(application, NULL, NULL); } @@ -504,7 +404,9 @@ static void notify_gio(struct sc_context *ctx, return; } - g_notification_set_body (notification, text); + if (text) { + g_notification_set_body (notification, text); + } if (icon) { gicon = g_themed_icon_new (icon); if (gicon) { @@ -530,7 +432,7 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, #endif -#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS) && !defined(_WIN32)) +#if defined(ENABLE_NOTIFY) && defined(ENABLE_GIO2) void sc_notify(const char *title, const char *text) { notify_gio(NULL, title, text, NULL, NULL); From 654ca69c47f98dd6a82b4adc0bb6bb8ead887163 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 8 Nov 2017 12:23:05 +0100 Subject: [PATCH 0136/4321] initialize notifications in PKCS#11 and tools ... and don't panic when they are not initialized --- src/pkcs11/pkcs11-global.c | 5 +++++ src/tools/util.c | 6 ++++++ src/ui/notify.c | 36 +++++++++++++++++++----------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 24074ab5a8..504026dea0 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -35,6 +35,7 @@ #endif /* PKCS11_THREAD_LOCKING */ #include "sc-pkcs11.h" +#include "ui/notify.h" #ifndef MODULE_APP_NAME #define MODULE_APP_NAME "opensc-pkcs11" @@ -237,6 +238,8 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) return CKR_CRYPTOKI_ALREADY_INITIALIZED; } + sc_notify_init(); + rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pInitArgs); if (rv != CKR_OK) goto out; @@ -300,6 +303,8 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) if (pReserved != NULL_PTR) return CKR_ARGUMENTS_BAD; + sc_notify_close(); + if (context == NULL) return CKR_CRYPTOKI_NOT_INITIALIZED; diff --git a/src/tools/util.c b/src/tools/util.c index 9c9f37c8bf..40f77677e0 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -30,6 +30,7 @@ #endif #include #include "util.h" +#include "ui/notify.h" int is_string_valid_atr(const char *atr_str) @@ -54,6 +55,8 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, struct sc_card *card = NULL; int r; + sc_notify_init(); + if (do_wait) { unsigned int event; @@ -354,6 +357,9 @@ util_fatal(const char *fmt, ...) vfprintf(stderr, fmt, ap); fprintf(stderr, "\nAborting.\n"); va_end(ap); + + sc_notify_close(); + exit(1); } diff --git a/src/ui/notify.c b/src/ui/notify.c index 37118fb795..096776660f 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -398,28 +398,30 @@ static void notify_gio(struct sc_context *ctx, const char *title, const char *text, const char *icon, const char *group) { - GIcon *gicon = NULL; - GNotification *notification = g_notification_new (title); - if (!notification) { - return; - } + if (application) { + GIcon *gicon = NULL; + GNotification *notification = g_notification_new (title); + if (!notification) { + return; + } - if (text) { - g_notification_set_body (notification, text); - } - if (icon) { - gicon = g_themed_icon_new (icon); - if (gicon) { - g_notification_set_icon (notification, gicon); + if (text) { + g_notification_set_body (notification, text); + } + if (icon) { + gicon = g_themed_icon_new (icon); + if (gicon) { + g_notification_set_icon (notification, gicon); + } } - } - g_application_send_notification(application, group, notification); + g_application_send_notification(application, group, notification); - if (gicon) { - g_object_unref(gicon); + if (gicon) { + g_object_unref(gicon); + } + g_object_unref(notification); } - g_object_unref(notification); } #else From 9583d3b650db501a0a878e4fd267e0b5fe830f2d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 14 Nov 2017 16:10:28 +0100 Subject: [PATCH 0137/4321] md: fixed memory leak may be related to https://github.com/OpenSC/OpenSC/issues/1106 --- src/minidriver/minidriver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 6478ff9b7a..773f85e3ec 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -3593,6 +3593,8 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine } } + free(pubkey_der.value); + logprintf(pCardData, 7, "returns container(idx:%u) info", (unsigned int)bContainerIndex); return SCARD_S_SUCCESS; From d0d9b974a72cfcb92ed3aefd0141b06a1f2f74f1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 Nov 2017 13:20:02 +0100 Subject: [PATCH 0138/4321] md: protect MD entry points with CriticalSection CardDeleteContext may be called at any time, interrupting any ongoing operation with the same PCARD_DATA. This leads to a race condition when CardDeleteContext deletes, for example, the sc_context_t which the interrupted call still wants to access. We have seen and fixed this problem in https://github.com/OpenSC/OpenSC/issues/973 specifically for the PIN entry process, however, it also applies to all other calls to the md. The new implementation removes the need for global data in the md. --- src/minidriver/minidriver.c | 793 +++++++++++++++++++++--------------- 1 file changed, 454 insertions(+), 339 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 773f85e3ec..435ba96412 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -84,12 +84,8 @@ HINSTANCE g_inst; */ #define MD_MAX_PINS MAX_PINS -#define MD_UTC_TIME_LENGTH_MAX 16 #define MD_CARDCF_LENGTH (sizeof(CARD_CACHE_FILE_FORMAT)) -#define MD_DATA_APPLICAITON_NAME "CSP" -#define MD_DATA_DEFAULT_CONT_LABEL "Default Key Container" - #define MD_KEY_USAGE_KEYEXCHANGE \ SC_PKCS15INIT_X509_KEY_ENCIPHERMENT | \ SC_PKCS15INIT_X509_DATA_ENCIPHERMENT | \ @@ -206,52 +202,9 @@ typedef struct _VENDOR_SPECIFIC /* these will be used to store intermediate dh agreements results */ struct md_dh_agreement* dh_agreements; BYTE allocatedAgreements; -}VENDOR_SPECIFIC; -/* - * Windows (ex. Vista) may access the card from more than one thread. - * The following data type and static data is an attempt to resolve - * some of the encountered multi-thread issues of OpenSC - * on the minidriver side. - * - * TODO: resolve multi-thread issues on the OpenSC side - */ -#define MD_STATIC_FLAG_READ_ONLY 1 -#define MD_STATIC_FLAG_SUPPORTS_X509_ENROLLMENT 2 -#define MD_STATIC_FLAG_CONTEXT_DELETED 4 -#define MD_STATIC_FLAG_GUID_AS_ID 8 -#define MD_STATIC_FLAG_GUID_AS_LABEL 16 -#define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_IMPORT 32 -#define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_GEN 64 -#define MD_STATIC_FLAG_IGNORE_PIN_LENGTH 128 -#define MD_STATIC_FLAG_PINPAD_DLG_ENABLE_CANCEL 256 - -#define MD_STATIC_PROCESS_ATTACHED 0xA11AC4EDL -struct md_opensc_static_data { - unsigned flags, flags_checked; - unsigned long attach_check; - HICON pinpad_dlg_icon; CRITICAL_SECTION hScard_lock; -}; -static struct md_opensc_static_data md_static_data; - - -#define C_ASN1_MD_CONTAINER_ATTRS_SIZE 7 -static const struct sc_asn1_entry c_asn1_md_container_attrs[C_ASN1_MD_CONTAINER_ATTRS_SIZE] = { - { "index", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { "id", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_EMPTY_ALLOWED, NULL, NULL }, - { "guid", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_EMPTY_ALLOWED, NULL, NULL }, - { "flags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, - { "sizeKeyExchange", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { "sizeSign", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -#define C_ASN1_MD_CONTAINER_SIZE 2 -static const struct sc_asn1_entry c_asn1_md_container[C_ASN1_MD_CONTAINER_SIZE] = { - { "mdContainer", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; +} VENDOR_SPECIFIC; static DWORD md_translate_OpenSC_to_Windows_error(int OpenSCerror, DWORD dwDefaulCode); @@ -261,10 +214,6 @@ static DWORD md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_obje static DWORD md_fs_init(PCARD_DATA pCardData); static void md_fs_finalize(PCARD_DATA pCardData); -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define snprintf _snprintf -#endif - #if defined(__GNUC__) static void logprintf(PCARD_DATA pCardData, int level, const char* format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 3, 4))); @@ -381,6 +330,29 @@ static DWORD reinit_card(PCARD_DATA pCardData) return SCARD_S_SUCCESS; } +static BOOL lock(PCARD_DATA pCardData) +{ + if (pCardData) { + VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (vs) { + EnterCriticalSection(&vs->hScard_lock); + return TRUE; + } + } + + return FALSE; +} + +static void unlock(PCARD_DATA pCardData) +{ + if (pCardData) { + VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + if (vs) { + LeaveCriticalSection(&vs->hScard_lock); + } + } +} + static DWORD reinit_card_for(PCARD_DATA pCardData, const char *name) { DWORD r; @@ -607,11 +579,7 @@ md_get_config_icon(PCARD_DATA pCardData, char *flag_name, HICON ret_default) static HICON md_get_pinpad_dlg_icon(PCARD_DATA pCardData) { - if (!md_static_data.pinpad_dlg_icon) { - md_static_data.pinpad_dlg_icon = md_get_config_icon(pCardData, "md_pinpad_dlg_icon", NULL); - } - - return md_static_data.pinpad_dlg_icon; + return md_get_config_icon(pCardData, "md_pinpad_dlg_icon", NULL); } @@ -652,7 +620,7 @@ md_get_pinpad_dlg_timeout(PCARD_DATA pCardData) static BOOL -md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL ret_default) +md_get_config_bool(PCARD_DATA pCardData, char *flag_name, BOOL ret_default) { VENDOR_SPECIFIC *vs; BOOL ret = ret_default; @@ -660,13 +628,6 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL re if (!pCardData) return ret; - logprintf(pCardData, 2, "Get '%s' option\n", flag_name); - if (md_static_data.flags_checked & flag) { - ret = (md_static_data.flags & flag) ? TRUE : FALSE; - logprintf(pCardData, 2, "Returns checked flag: %s\n", ret ? "TRUE" : "FALSE"); - return ret; - } - vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; if (!vs) return ret; @@ -684,15 +645,6 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, unsigned flag, BOOL re ret = scconf_get_bool(atrblock, flag_name, ret_default) ? TRUE : FALSE; } - md_static_data.flags_checked |= flag; - if (ret == TRUE) - md_static_data.flags |= flag; - else - md_static_data.flags &= ~flag; - - logprintf(pCardData, 2, "Returns '%s' flag '%s', static flags/checked %X/%X\n", - flag_name, ret ? "TRUE" : "FALSE", - md_static_data.flags, md_static_data.flags_checked); return ret; } @@ -702,7 +654,7 @@ static BOOL md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enableed?\n"); - return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", MD_STATIC_FLAG_PINPAD_DLG_ENABLE_CANCEL, FALSE); + return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", FALSE); } @@ -711,7 +663,7 @@ static BOOL md_is_read_only(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is read-only?\n"); - return md_get_config_bool(pCardData, "md_read_only", MD_STATIC_FLAG_READ_ONLY, TRUE); + return md_get_config_bool(pCardData, "md_read_only", TRUE); } @@ -721,7 +673,7 @@ md_is_supports_X509_enrollment(PCARD_DATA pCardData) { BOOL defaultvalue = !md_is_read_only(pCardData); logprintf(pCardData, 2, "Is supports X509 enrollment?\n"); - return md_get_config_bool(pCardData, "md_supports_X509_enrollment", MD_STATIC_FLAG_SUPPORTS_X509_ENROLLMENT, defaultvalue); + return md_get_config_bool(pCardData, "md_supports_X509_enrollment", defaultvalue); } @@ -730,7 +682,7 @@ static BOOL md_is_guid_as_id(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is GUID has to be used as ID of crypto objects?\n"); - return md_get_config_bool(pCardData, "md_guid_as_id", MD_STATIC_FLAG_GUID_AS_ID, FALSE); + return md_get_config_bool(pCardData, "md_guid_as_id", FALSE); } @@ -739,7 +691,7 @@ static BOOL md_is_guid_as_label(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is GUID has to be used as label of crypto objects?\n"); - return md_get_config_bool(pCardData, "md_guid_as_label", MD_STATIC_FLAG_GUID_AS_LABEL, FALSE); + return md_get_config_bool(pCardData, "md_guid_as_label", FALSE); } @@ -748,7 +700,7 @@ static BOOL md_is_supports_container_key_gen(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is supports 'key generation' create_container mechanism?\n"); - return md_get_config_bool(pCardData, "md_supports_container_key_gen", MD_STATIC_FLAG_CREATE_CONTAINER_KEY_GEN, TRUE); + return md_get_config_bool(pCardData, "md_supports_container_key_gen", TRUE); } @@ -757,7 +709,7 @@ static BOOL md_is_supports_container_key_import(PCARD_DATA pCardData) { logprintf(pCardData, 2, "Is supports 'key import' create container mechanism?\n"); - return md_get_config_bool(pCardData, "md_supports_container_key_import", MD_STATIC_FLAG_CREATE_CONTAINER_KEY_IMPORT, TRUE); + return md_get_config_bool(pCardData, "md_supports_container_key_import", TRUE); } /* generate unique key label (GUID)*/ @@ -1883,11 +1835,11 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) for (ii=0;iidata; - if (strcmp(dinfo->app_label, MD_DATA_APPLICAITON_NAME)) + if (strcmp(dinfo->app_label, "CSP")) continue; logprintf(pCardData, 2, "Found 'DATA' object '%.*s'\n", (int) sizeof dobjs[ii]->label, dobjs[ii]->label); - if (!strncmp(dobjs[ii]->label, MD_DATA_DEFAULT_CONT_LABEL, sizeof dobjs[ii]->label)) { + if (!strncmp(dobjs[ii]->label, "Default Key Container", sizeof dobjs[ii]->label)) { default_cont = dobjs[ii]; continue; } @@ -2826,7 +2778,6 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) const u8 *pin2 = (const u8 *) parameter[5]; size_t *pin2len = (size_t *) parameter[6]; int rv = 0; - EnterCriticalSection(&md_static_data.hScard_lock); switch (operation) { case SC_PIN_CMD_VERIFY: @@ -2845,7 +2796,6 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) rv = (DWORD) ERROR_INVALID_PARAMETER; break; } - LeaveCriticalSection(&md_static_data.hScard_lock); if (parameter[10] != 0) { EndDialog((HWND) parameter[10], rv); } @@ -3123,9 +3073,7 @@ static DWORD md_translate_OpenSC_to_Windows_error(int OpenSCerror, DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData) { VENDOR_SPECIFIC *vs = NULL; - - if (md_static_data.attach_check != MD_STATIC_PROCESS_ATTACHED) - return SCARD_S_SUCCESS; + CRITICAL_SECTION hScard_lock; if(!pCardData) return SCARD_E_INVALID_PARAMETER; @@ -3141,15 +3089,15 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData) if(!vs) return SCARD_E_INVALID_PARAMETER; - if (vs->initialized) { - disassociate_card(pCardData); - md_fs_finalize(pCardData); - } + hScard_lock = vs->hScard_lock; + EnterCriticalSection(&hScard_lock); + + disassociate_card(pCardData); + md_fs_finalize(pCardData); if(vs->ctx) { logprintf(pCardData, 6, "release context\n"); sc_release_context(vs->ctx); - md_static_data.flags |= MD_STATIC_FLAG_CONTEXT_DELETED; vs->ctx = NULL; } @@ -3158,6 +3106,9 @@ DWORD WINAPI CardDeleteContext(__inout PCARD_DATA pCardData) pCardData->pfnCspFree(pCardData->pvVendorSpecific); pCardData->pvVendorSpecific = NULL; + LeaveCriticalSection(&hScard_lock); + DeleteCriticalSection(&hScard_lock); + return SCARD_S_SUCCESS; } @@ -3171,18 +3122,23 @@ DWORD WINAPI CardQueryCapabilities(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "pCardCapabilities=%p\n", pCardCapabilities); - if (!pCardData || !pCardCapabilities) + if (!pCardData || !pCardCapabilities || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_status(pCardData, "CardQueryCapabilities"); - if (dwret != SCARD_S_SUCCESS) - return dwret; + if (dwret != SCARD_S_SUCCESS) { + goto err; + } dwret = md_card_capabilities(pCardData, pCardCapabilities); - if (dwret != SCARD_S_SUCCESS) - return dwret; + if (dwret != SCARD_S_SUCCESS) { + goto err; + } - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + + return dwret; } DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData, @@ -3198,43 +3154,53 @@ DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData, logprintf(pCardData, 1, "CardDeleteContainer(idx:%u)\n", (unsigned int)bContainerIndex); - if (!pCardData) + if (!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_reader_status(pCardData, "CardDeleteContainer"); - if (dwret != SCARD_S_SUCCESS) - return dwret; + if (dwret != SCARD_S_SUCCESS) { + goto err; + } - if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) - return SCARD_E_INVALID_PARAMETER; + if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } if (!md_is_supports_container_key_gen(pCardData)) { logprintf(pCardData, 1, "Denied 'deletion' mechanism to delete container.\n"); - return SCARD_E_UNSUPPORTED_FEATURE; + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if(!vs) - return SCARD_E_INVALID_PARAMETER; + if(!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } cont = &(vs->p15_containers[bContainerIndex]); dwret = md_pkcs15_delete_object(pCardData, cont->prkey_obj); - if (dwret != SCARD_S_SUCCESS) { + if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "private key deletion failed\n"); - return dwret; + goto err; } dwret = md_pkcs15_delete_object(pCardData, cont->pubkey_obj); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "public key deletion failed\n"); - return dwret; + goto err; } ZeroMemory(cont, sizeof(struct md_pkcs15_container)); logprintf(pCardData, 1, "key deleted\n"); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + + return dwret; } /** The CardCreateContainerEx function creates a new key container that the @@ -3257,15 +3223,17 @@ DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, { DWORD dwret; - if (!pCardData) + if (!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; - if (PinId == ROLE_ADMIN) - return SCARD_W_SECURITY_VIOLATION; + if (PinId == ROLE_ADMIN) { + dwret = SCARD_W_SECURITY_VIOLATION; + goto err; + } dwret = check_card_reader_status(pCardData, "CardCreateContainerEx"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), @@ -3284,7 +3252,7 @@ DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, dwret = md_check_key_compatibility(pCardData, dwFlags, dwKeySpec, dwKeySize, pbKeyData); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "check key compatibility failed\n"); - return dwret; + goto err; } if (!md_is_supports_container_key_gen(pCardData)) { @@ -3299,14 +3267,15 @@ DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, if (!dwFlags) { logprintf(pCardData, 1, "Unsupported create container mechanism.\n"); - return SCARD_E_UNSUPPORTED_FEATURE; + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } if (dwFlags & CARD_CREATE_CONTAINER_KEY_GEN) { dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize, PinId); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "key generation failed\n"); - return dwret; + goto err; } logprintf(pCardData, 1, "key generated\n"); } @@ -3314,17 +3283,21 @@ DWORD WINAPI CardCreateContainerEx(__in PCARD_DATA pCardData, dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize, PinId); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "key store failed\n"); - return dwret; + goto err; } logprintf(pCardData, 1, "key imported\n"); } else { logprintf(pCardData, 1, "Invalid dwFlags value: 0x%lX\n", (unsigned long)dwFlags); - return SCARD_E_INVALID_PARAMETER; + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + + return dwret; } DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData, @@ -3354,15 +3327,17 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine struct sc_pkcs15_der pubkey_der; struct sc_pkcs15_prkey_info *prkey_info = NULL; int rv; + pubkey_der.value = NULL; + pubkey_der.len = 0; if(!pCardData) return SCARD_E_INVALID_PARAMETER; - if (!pContainerInfo) + if (!pContainerInfo || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; ret = check_card_reader_status(pCardData, "CardGetContainerInfo"); if (ret != SCARD_S_SUCCESS) - return ret; + goto err; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), @@ -3374,33 +3349,39 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine (unsigned long)pContainerInfo->cbSigPublicKey, (unsigned long)pContainerInfo->cbKeyExPublicKey); - if (dwFlags) - return SCARD_E_INVALID_PARAMETER; - if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) - return SCARD_E_NO_KEY_CONTAINER; - if (pContainerInfo->dwVersion > CONTAINER_INFO_CURRENT_VERSION) - return ERROR_REVISION_MISMATCH; + if (dwFlags) { + ret = SCARD_E_INVALID_PARAMETER; + goto err; + } + if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) { + ret = SCARD_E_NO_KEY_CONTAINER; + goto err; + } + if (pContainerInfo->dwVersion > CONTAINER_INFO_CURRENT_VERSION) { + ret = ERROR_REVISION_MISMATCH; + goto err; + } pContainerInfo->dwVersion = CONTAINER_INFO_CURRENT_VERSION; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + ret = SCARD_E_INVALID_PARAMETER; + goto err; + } cont = &vs->p15_containers[bContainerIndex]; if (!cont->prkey_obj) { logprintf(pCardData, 7, "Container %u is empty\n", (unsigned int)bContainerIndex); - return SCARD_E_NO_KEY_CONTAINER; + ret = SCARD_E_NO_KEY_CONTAINER; + goto err; } ret = SCARD_F_UNKNOWN_ERROR; prkey_info = (struct sc_pkcs15_prkey_info *)cont->prkey_obj->data; - pubkey_der.value = NULL; - pubkey_der.len = 0; - if ((cont->prkey_obj->content.value != NULL) && (cont->prkey_obj->content.len > 0)) { sc_der_copy(&pubkey_der, &cont->prkey_obj->content); ret = SCARD_S_SUCCESS; @@ -3458,14 +3439,15 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine if (!pubkey_der.value && (cont->size_sign || cont->size_key_exchange)) { logprintf(pCardData, 2, "cannot find public key\n"); - return SCARD_F_INTERNAL_ERROR; + ret = SCARD_F_INTERNAL_ERROR; + goto err; } if (ret != SCARD_S_SUCCESS) { logprintf(pCardData, 7, "GetContainerInfo(idx:%u) failed; error %lX", (unsigned int)bContainerIndex, (unsigned long)ret); - return ret; + goto err; } logprintf(pCardData, 7, "SubjectPublicKeyInfo:\n"); @@ -3480,8 +3462,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine if (cont->size_sign) { PUBRSAKEYSTRUCT_BASE *publicKey = (PUBRSAKEYSTRUCT_BASE *)pCardData->pfnCspAlloc(sz); - if (!publicKey) - return SCARD_E_NO_MEMORY; + if (!publicKey) { + ret = SCARD_E_NO_MEMORY; + goto err; + } CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pubkey_der.value, (DWORD) pubkey_der.len, 0, publicKey, &sz); @@ -3497,8 +3481,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine if (cont->size_key_exchange) { PUBRSAKEYSTRUCT_BASE *publicKey = (PUBRSAKEYSTRUCT_BASE*)pCardData->pfnCspAlloc(sz); - if (!publicKey) - return SCARD_E_NO_MEMORY; + if (!publicKey) { + ret = SCARD_E_NO_MEMORY; + goto err; + } CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pubkey_der.value, (DWORD) pubkey_der.len, 0, publicKey, &sz); @@ -3536,12 +3522,15 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine logprintf(pCardData, 3, "Unable to match the ECC public size to one of Microsoft algorithm %"SC_FORMAT_LEN_SIZE_T"u\n", cont->size_sign); - return SCARD_F_INTERNAL_ERROR; + ret = SCARD_F_INTERNAL_ERROR; + goto err; } publicKey = (BCRYPT_ECCKEY_BLOB *)pCardData->pfnCspAlloc(sz); - if (!publicKey) - return SCARD_E_NO_MEMORY; + if (!publicKey) { + ret = SCARD_E_NO_MEMORY; + goto err; + } publicKey->cbKey = (DWORD)(pubkey_der.len -3) /2; publicKey->dwMagic = dwMagic; @@ -3572,12 +3561,15 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine logprintf(pCardData, 3, "Unable to match the ECC public size to one of Microsoft algorithm %"SC_FORMAT_LEN_SIZE_T"u\n", cont->size_key_exchange); - return SCARD_F_INTERNAL_ERROR; + ret = SCARD_F_INTERNAL_ERROR; + goto err; } publicKey = (BCRYPT_ECCKEY_BLOB *)pCardData->pfnCspAlloc(sz); - if (!publicKey) - return SCARD_E_NO_MEMORY; + if (!publicKey) { + ret = SCARD_E_NO_MEMORY; + goto err; + } publicKey->cbKey = (DWORD)(pubkey_der.len -3) /2; publicKey->dwMagic = dwMagic; @@ -3592,12 +3584,14 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine } } } + logprintf(pCardData, 7, "returns container(idx:%u) info", + (unsigned int)bContainerIndex); +err: free(pubkey_der.value); + unlock(pCardData); - logprintf(pCardData, 7, "returns container(idx:%u) info", - (unsigned int)bContainerIndex); - return SCARD_S_SUCCESS; + return ret; } DWORD WINAPI CardAuthenticatePin(__in PCARD_DATA pCardData, @@ -3644,35 +3638,45 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData, if(!pCardData) return SCARD_E_INVALID_PARAMETER; - if (!ppbChallengeData || !pcbChallengeData) + if (!ppbChallengeData || !pcbChallengeData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_reader_status(pCardData, "CardGetChallenge"); - if (dwret != SCARD_S_SUCCESS) - return dwret; + if (dwret != SCARD_S_SUCCESS) { + goto err; + } vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } *pcbChallengeData = 8; *ppbChallengeData = (PBYTE) pCardData->pfnCspAlloc(8); - if (!*ppbChallengeData) - return SCARD_E_NO_MEMORY; + if (!*ppbChallengeData) { + dwret = SCARD_E_NO_MEMORY; + goto err; + } rv = sc_get_challenge(vs->p15card->card, *ppbChallengeData, 8); if (rv) { logprintf(pCardData, 1, "Get challenge failed: %s\n", sc_strerror(rv)); pCardData->pfnCspFree(*ppbChallengeData); *ppbChallengeData = NULL; - return SCARD_E_UNEXPECTED; + dwret = SCARD_E_UNEXPECTED; + goto err; } + dwret = SCARD_S_SUCCESS; logprintf(pCardData, 7, "returns %lu bytes:\n", (unsigned long)*pcbChallengeData); loghex(pCardData, 7, *ppbChallengeData, *pcbChallengeData); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -3698,7 +3702,9 @@ DWORD WINAPI CardUnblockPin(__in PCARD_DATA pCardData, __in DWORD cRetryCount, __in DWORD dwFlags) { - if(!pCardData) + DWORD r = SCARD_S_SUCCESS; + + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", @@ -3708,43 +3714,52 @@ DWORD WINAPI CardUnblockPin(__in PCARD_DATA pCardData, if (pwszUserId == NULL) { logprintf(pCardData, 1, "no user ID\n"); - return SCARD_E_INVALID_PARAMETER; + r = SCARD_E_INVALID_PARAMETER; + goto err; } if (wcscmp(wszCARD_USER_USER, pwszUserId) != 0 && wcscmp(wszCARD_USER_ADMIN,pwszUserId) != 0) { logprintf(pCardData, 1, "unknown user ID %S\n", pwszUserId); - return SCARD_E_INVALID_PARAMETER; + r = SCARD_E_INVALID_PARAMETER; + goto err; } if (wcscmp(wszCARD_USER_ADMIN, pwszUserId) == 0) { logprintf(pCardData, 1, "unlocking admin not supported\n"); - return SCARD_E_UNSUPPORTED_FEATURE; + r = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } if (dwFlags & CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE) { logprintf(pCardData, 1, - "challenge / response not supported, we'll treat response as a PUK\n"); + "challenge / response not supported, we'll treat response as a PUK\n"); logprintf(pCardData, 1, - "note that you'll need to type PUK in hex (replace every PUK digit X with '3X') in Win CAD unblock dialog response field\n"); + "note that you'll need to type PUK in hex (replace every PUK digit X with '3X') in Win CAD unblock dialog response field\n"); dwFlags &= ~CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE; } if (dwFlags) { logprintf(pCardData, 1, "flags of %x not supported\n", - (unsigned int)dwFlags); - return SCARD_E_INVALID_PARAMETER; + (unsigned int)dwFlags); + r = SCARD_E_INVALID_PARAMETER; + goto err; } logprintf(pCardData, 1, - "UserID('%S'), AuthData(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX)\n", - pwszUserId, pbAuthenticationData, - (unsigned long)cbAuthenticationData, pbNewPinData, - (unsigned long)cbNewPinData, (unsigned long)cRetryCount, - (unsigned long)dwFlags); + "UserID('%S'), AuthData(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX)\n", + pwszUserId, pbAuthenticationData, + (unsigned long)cbAuthenticationData, pbNewPinData, + (unsigned long)cbNewPinData, (unsigned long)cRetryCount, + (unsigned long)dwFlags); + + r = CardChangeAuthenticatorEx(pCardData, + PIN_CHANGE_FLAG_UNBLOCK | + CARD_PIN_SILENT_CONTEXT, + ROLE_ADMIN, pbAuthenticationData, + cbAuthenticationData, ROLE_USER, + pbNewPinData, cbNewPinData, + cRetryCount, NULL); + +err: + unlock(pCardData); - return CardChangeAuthenticatorEx(pCardData, - PIN_CHANGE_FLAG_UNBLOCK | - CARD_PIN_SILENT_CONTEXT, - ROLE_ADMIN, pbAuthenticationData, - cbAuthenticationData, ROLE_USER, - pbNewPinData, cbNewPinData, - cRetryCount, NULL); + return r; } @@ -3758,47 +3773,59 @@ DWORD WINAPI CardChangeAuthenticator(__in PCARD_DATA pCardData, __in DWORD dwFlags, __out_opt PDWORD pcAttemptsRemaining) { + DWORD r = SCARD_S_SUCCESS; PIN_ID pinid; - if(!pCardData) + + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", - (unsigned long)GetCurrentProcessId(), - (unsigned long)GetCurrentThreadId(), pCardData); + (unsigned long)GetCurrentProcessId(), + (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardChangeAuthenticator\n"); - if (pwszUserId == NULL) - return SCARD_E_INVALID_PARAMETER; + if (pwszUserId == NULL) { + r = SCARD_E_INVALID_PARAMETER; + goto err; + } if (dwFlags == CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE) { logprintf(pCardData, 1, "Other then 'authentication' the PIN are not supported\n"); - return SCARD_E_UNSUPPORTED_FEATURE; + r = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } else if (dwFlags != CARD_AUTHENTICATE_PIN_PIN){ - return SCARD_E_INVALID_PARAMETER; + r = SCARD_E_INVALID_PARAMETER; + goto err; } - if (wcscmp(wszCARD_USER_USER, pwszUserId) != 0 && wcscmp(wszCARD_USER_ADMIN, pwszUserId) != 0) - return SCARD_E_INVALID_PARAMETER; + if (wcscmp(wszCARD_USER_USER, pwszUserId) != 0 && wcscmp(wszCARD_USER_ADMIN, pwszUserId) != 0) { + r = SCARD_E_INVALID_PARAMETER; + goto err; + } logprintf(pCardData, 1, - "UserID('%S'), CurrentPIN(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX)\n", - pwszUserId, pbCurrentAuthenticator, - (unsigned long)cbCurrentAuthenticator, pbNewAuthenticator, - (unsigned long)cbNewAuthenticator, (unsigned long)cRetryCount, - (unsigned long)dwFlags); + "UserID('%S'), CurrentPIN(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX)\n", + pwszUserId, pbCurrentAuthenticator, + (unsigned long)cbCurrentAuthenticator, pbNewAuthenticator, + (unsigned long)cbNewAuthenticator, (unsigned long)cRetryCount, + (unsigned long)dwFlags); if (wcscmp(wszCARD_USER_USER, pwszUserId) == 0) pinid = ROLE_USER; else pinid = ROLE_ADMIN; - return CardChangeAuthenticatorEx(pCardData, PIN_CHANGE_FLAG_CHANGEPIN | - CARD_PIN_SILENT_CONTEXT, pinid, - pbCurrentAuthenticator, - cbCurrentAuthenticator, pinid, - pbNewAuthenticator, cbNewAuthenticator, - cRetryCount, pcAttemptsRemaining); + r = CardChangeAuthenticatorEx(pCardData, PIN_CHANGE_FLAG_CHANGEPIN | + CARD_PIN_SILENT_CONTEXT, pinid, + pbCurrentAuthenticator, + cbCurrentAuthenticator, pinid, + pbNewAuthenticator, cbNewAuthenticator, + cRetryCount, pcAttemptsRemaining); + +err: + unlock(pCardData); + return r; } /* Note: the PIN freshness will be managed by the Base CSP */ @@ -3809,31 +3836,43 @@ DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData, DWORD dwret; VENDOR_SPECIFIC* vs = NULL; int rv; + logprintf(pCardData, 1, "\nP:%ld T:%ld pCardData:%p ", (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardDeauthenticate(%S) %lu\n", NULLWSTR(pwszUserId), (unsigned long)dwFlags); - if(!pCardData) + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_reader_status(pCardData, "CardDeauthenticate"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } sc_pkcs15_pincache_clear(vs->p15card); rv = sc_logout(vs->p15card->card); - if (rv != SC_SUCCESS) - return SCARD_E_UNSUPPORTED_FEATURE; - /* force a reset of a card - SCARD_S_SUCCESS do not lead to the reset of the card and leave it still authenticated */ - return SCARD_S_SUCCESS; + if (rv != SC_SUCCESS) { + /* force a reset of a card - SCARD_S_SUCCESS do not lead to the reset + * of the card and leave it still authenticated */ + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } + + dwret = SCARD_S_SUCCESS; + +err: + unlock(pCardData); + + return dwret; } DWORD WINAPI CardCreateDirectory(__in PCARD_DATA pCardData, @@ -3874,21 +3913,27 @@ DWORD WINAPI CardCreateFile(__in PCARD_DATA pCardData, NULLSTR(pszDirectoryName), NULLSTR(pszFileName), (unsigned long)cbInitialCreationSize, AccessCondition); + if (!lock(pCardData)) + return SCARD_E_INVALID_PARAMETER; + dwret = check_card_status(pCardData, "CardCreateFile"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; dwret = md_fs_find_directory(pCardData, NULL, pszDirectoryName, &dir); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "CardCreateFile() cannot find parent directory '%s'", NULLSTR(pszDirectoryName)); - return dwret; + goto err; } dwret = md_fs_add_file(pCardData, &dir->files, pszFileName, AccessCondition, NULL, cbInitialCreationSize, NULL); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + + return dwret; } @@ -3907,7 +3952,7 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardReadFile\n"); - if(!pCardData) + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 2, @@ -3915,33 +3960,34 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData, NULLSTR(pszDirectoryName), NULLSTR(pszFileName), (unsigned long)dwFlags, pcbData, ppbData); - if (!pszFileName || !strlen(pszFileName)) - return SCARD_E_INVALID_PARAMETER; - if (dwFlags) - return SCARD_E_INVALID_PARAMETER; + if (!pszFileName || !strlen(pszFileName) || dwFlags) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } dwret = check_card_reader_status(pCardData, "CardReadFile"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file); if (!file) { logprintf(pCardData, 2, "CardReadFile(): file '%s' not found in '%s'\n", NULLSTR(pszFileName), NULLSTR(pszDirectoryName)); - return SCARD_E_FILE_NOT_FOUND; + dwret = SCARD_E_FILE_NOT_FOUND; + goto err; } if (!file->blob) { - DWORD dwret; - dwret = md_fs_read_content(pCardData, pszDirectoryName, file); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; } if (ppbData) { *ppbData = pCardData->pfnCspAlloc(file->size); - if(!*ppbData) - return SCARD_E_NO_MEMORY; + if(!*ppbData) { + dwret = SCARD_E_NO_MEMORY; + goto err; + } memcpy(*ppbData, file->blob, file->size); } @@ -3951,7 +3997,11 @@ DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData, logprintf(pCardData, 7, "returns '%s' content:\n", NULLSTR(pszFileName)); loghex(pCardData, 7, file->blob, file->size); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + + return dwret; } @@ -3965,7 +4015,7 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData, struct md_file *file = NULL; DWORD dwret; - if(!pCardData) + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", @@ -3975,7 +4025,7 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData, dwret = check_card_reader_status(pCardData, "CardWriteFile"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; if (pbData && cbData) { logprintf(pCardData, 1, "CardWriteFile try to write (%lu):\n", @@ -3986,7 +4036,8 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData, md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file); if (!file) { logprintf(pCardData, 2, "CardWriteFile(): file '%s' not found in '%s'\n", NULLSTR(pszFileName), NULLSTR(pszDirectoryName)); - return SCARD_E_FILE_NOT_FOUND; + dwret = SCARD_E_FILE_NOT_FOUND; + goto err; } logprintf(pCardData, 7, "set content of '%s' to:\n", NULLSTR(pszFileName)); @@ -3996,20 +4047,23 @@ DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData, if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "cannot set file content: %lu\n", (unsigned long)dwret); - return dwret; + goto err; } if (pszDirectoryName && !strcmp(pszDirectoryName, "mscp")) { if ((strstr(pszFileName, "kxc") == pszFileName) || (strstr(pszFileName, "ksc") == pszFileName)) { dwret = md_pkcs15_store_certificate(pCardData, pszFileName, pbData, cbData); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; logprintf(pCardData, 2, "md_pkcs15_store_certificate() OK\n"); } } logprintf(pCardData, 2, "write '%s' ok.\n", NULLSTR(pszFileName)); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } DWORD WINAPI CardDeleteFile(__in PCARD_DATA pCardData, @@ -4024,22 +4078,24 @@ DWORD WINAPI CardDeleteFile(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardDeleteFile(%s, %s) called\n", NULLSTR(pszDirectoryName), NULLSTR(pszFileName)); - if(!pCardData) + if(!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_reader_status(pCardData, "CardDeleteFile"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; dwret = md_fs_delete_file(pCardData, pszDirectoryName, pszFileName); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 2, "CardDeleteFile(): delete file error: %lX\n", (unsigned long)dwret); - return dwret; + goto err; } - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + return dwret; } @@ -4061,24 +4117,25 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData, (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardEnumFiles() directory '%s'\n", NULLSTR(pszDirectoryName)); - if (!pCardData) - return SCARD_E_INVALID_PARAMETER; - if (!pmszFileNames || !pdwcbFileName) + if (!pCardData || !pmszFileNames || !pdwcbFileName || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; if (dwFlags) { logprintf(pCardData, 1, "CardEnumFiles() dwFlags not 'zero' -- %lX\n", (unsigned long)dwFlags); - return SCARD_E_INVALID_PARAMETER; + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } dwret = check_card_status(pCardData, "CardEnumFiles"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } memset(mstr, 0, sizeof(mstr)); @@ -4088,7 +4145,8 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData, md_fs_find_directory(pCardData, NULL, pszDirectoryName, &dir); if (!dir) { logprintf(pCardData, 2, "enum files() failed: directory '%s' not found\n", NULLSTR(pszDirectoryName)); - return SCARD_E_FILE_NOT_FOUND; + dwret = SCARD_E_FILE_NOT_FOUND; + goto err; } file = dir->files; @@ -4102,12 +4160,17 @@ DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData, offs += 1; *pmszFileNames = (LPSTR)(*pCardData->pfnCspAlloc)(offs); - if (*pmszFileNames == NULL) - return SCARD_E_NO_MEMORY; + if (*pmszFileNames == NULL) { + dwret = SCARD_E_NO_MEMORY; + goto err; + } CopyMemory(*pmszFileNames, mstr, offs); *pdwcbFileName = (DWORD) offs; - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -4119,6 +4182,9 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData, DWORD dwret; struct md_file *file = NULL; + if(!pCardData || !lock(pCardData)) + return SCARD_E_INVALID_PARAMETER; + logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); @@ -4126,19 +4192,22 @@ DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData, dwret = check_card_status(pCardData, "CardGetFileInfo"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; md_fs_find_file(pCardData, pszDirectoryName, pszFileName, &file); if (!file) { logprintf(pCardData, 2, "CardWriteFile(): file '%s' not found in '%s'\n", NULLSTR(pszFileName), NULLSTR(pszDirectoryName)); - return SCARD_E_FILE_NOT_FOUND; + dwret = SCARD_E_FILE_NOT_FOUND; + goto err; } pCardFileInfo->dwVersion = CARD_FILE_INFO_CURRENT_VERSION; pCardFileInfo->cbFileSize = (DWORD) file->size; pCardFileInfo->AccessCondition = file->acl; - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + return dwret; } @@ -4155,22 +4224,25 @@ DWORD WINAPI CardQueryFreeSpace(__in PCARD_DATA pCardData, __in DWORD dwFlags, pCardFreeSpaceInfo, (unsigned long)dwFlags, (unsigned long)pCardFreeSpaceInfo->dwVersion); - if (!pCardData) + if (!pCardData || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_status(pCardData, "CardQueryFreeSpace"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; dwret = md_free_space(pCardData, pCardFreeSpaceInfo); if (dwret != SCARD_S_SUCCESS) { logprintf(pCardData, 1, "CardQueryFreeSpace() md free space error"); - return dwret; + goto err; } logprintf(pCardData, 7, "FreeSpace:\n"); loghex(pCardData, 7, (BYTE *)pCardFreeSpaceInfo, sizeof(*pCardFreeSpaceInfo)); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -4189,24 +4261,23 @@ DWORD WINAPI CardQueryKeySizes(__in PCARD_DATA pCardData, (unsigned long)dwKeySpec, (unsigned long)dwFlags, pKeySizes ? (unsigned long)pKeySizes->dwVersion : 0); - if (!pCardData) - return SCARD_E_INVALID_PARAMETER; - if ( dwFlags != 0 ) - return SCARD_E_INVALID_PARAMETER; - if ( dwKeySpec == 0 ) + if (!pCardData || dwFlags != 0 || dwKeySpec == 0 || !lock(pCardData)) return SCARD_E_INVALID_PARAMETER; dwret = check_card_status(pCardData, "CardQueryKeySizes"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; dwret = md_query_key_sizes(pCardData, dwKeySpec, pKeySizes); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; logprintf(pCardData, 7, "pKeySizes:\n"); loghex(pCardData, 7, (BYTE *)pKeySizes, sizeof(*pKeySizes)); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -4227,11 +4298,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), pCardData); logprintf(pCardData, 1, "CardRSADecrypt\n"); - if (!pCardData) - return SCARD_E_INVALID_PARAMETER; - if (!pInfo) - return SCARD_E_INVALID_PARAMETER; - if ( pInfo->pbData == NULL ) + if (!pCardData || !pInfo || pInfo->pbData == NULL) return SCARD_E_INVALID_PARAMETER; if (pInfo->dwVersion > CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION) return ERROR_REVISION_MISMATCH; @@ -4241,17 +4308,24 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, if (pInfo->dwKeySpec != AT_KEYEXCHANGE) return SCARD_E_INVALID_PARAMETER; + if (!lock(pCardData)) + return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardRSADecrypt"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } /* check if the container exists */ - if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) - return SCARD_E_NO_KEY_CONTAINER; + if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) { + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; + } logprintf(pCardData, 2, "CardRSADecrypt dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu pbData=%p, cbData=%lu\n", @@ -4269,18 +4343,22 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, pkey = vs->p15_containers[pInfo->bContainerIndex].prkey_obj; if (!pkey) { logprintf(pCardData, 2, "CardRSADecrypt prkey not found\n"); - return SCARD_E_NO_KEY_CONTAINER; + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; } /* input and output buffers are always the same size */ pbuf = pCardData->pfnCspAlloc(pInfo->cbData); - if (!pbuf) - return SCARD_E_NO_MEMORY; + if (!pbuf) { + dwret = SCARD_E_NO_MEMORY; + goto err; + } pbuf2 = pCardData->pfnCspAlloc(pInfo->cbData); if (!pbuf2) { pCardData->pfnCspFree(pbuf); - return SCARD_E_NO_MEMORY; + dwret = SCARD_E_NO_MEMORY; + goto err; } /*inversion donnees*/ @@ -4297,7 +4375,8 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, prkey_info->modulus_length); pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_F_INTERNAL_ERROR; + dwret = SCARD_F_INTERNAL_ERROR; + goto err; } /* filter boggus input: the data to decrypt is shorter than the RSA key ? */ @@ -4307,7 +4386,8 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, (instead of invalid parameter when the call is forwarded to the card implementation) */ pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_E_INSUFFICIENT_BUFFER; + dwret = SCARD_E_INSUFFICIENT_BUFFER; + goto err; } if (alg_info->flags & SC_ALGORITHM_RSA_RAW) { @@ -4330,7 +4410,8 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, logprintf(pCardData, 2, "Cannot strip PKCS1 padding: %i\n", r); pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_F_INTERNAL_ERROR; + dwret = SCARD_F_INTERNAL_ERROR; + goto err; } } else if (pInfo->dwPaddingType == CARD_PADDING_OAEP) { @@ -4338,7 +4419,8 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, logprintf(pCardData, 2, "OAEP padding not implemented\n"); pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_F_INTERNAL_ERROR; + dwret = SCARD_F_INTERNAL_ERROR; + goto err; } } } @@ -4374,14 +4456,16 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, logprintf(pCardData, 2, "CardRSADecrypt: no usable RSA algorithm\n"); pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_E_INVALID_PARAMETER; + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } if ( r < 0) { logprintf(pCardData, 2, "sc_pkcs15_decipher error(%i): %s\n", r, sc_strerror(r)); pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + goto err; } logprintf(pCardData, 2, "decrypted data(%lu):\n", @@ -4394,7 +4478,10 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, pCardData->pfnCspFree(pbuf); pCardData->pfnCspFree(pbuf2); - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -4438,9 +4525,12 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO if (pInfo->dwSigningFlags & ~(CARD_PADDING_INFO_PRESENT | CARD_PADDING_NONE | CARD_BUFFER_SIZE_ONLY | CARD_PADDING_PKCS1 | CARD_PADDING_PSS | CARD_PADDING_OAEP)) return SCARD_E_INVALID_PARAMETER; + if (!lock(pCardData)) + return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardSignData"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; logprintf(pCardData, 2, "CardSignData dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu, dwSigningFlags=0x%08X, aiHashAlg=0x%08X\n", @@ -4457,22 +4547,30 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO hashAlg = pInfo->aiHashAlg; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } - if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) - return SCARD_E_NO_KEY_CONTAINER; + if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) { + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; + } pkey = vs->p15_containers[pInfo->bContainerIndex].prkey_obj; - if (!pkey) - return SCARD_E_NO_KEY_CONTAINER; + if (!pkey) { + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; + } prkey_info = (struct sc_pkcs15_prkey_info *)(pkey->data); logprintf(pCardData, 2, "pInfo->dwVersion = %lu\n", (unsigned long)pInfo->dwVersion); - if (dataToSignLen < pInfo->cbData) - return SCARD_E_INSUFFICIENT_BUFFER; + if (dataToSignLen < pInfo->cbData) { + dwret = SCARD_E_INSUFFICIENT_BUFFER; + goto err; + } memcpy(dataToSign, pInfo->pbData, pInfo->cbData); dataToSignLen = pInfo->cbData; @@ -4480,11 +4578,13 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; if (CARD_PADDING_PSS == pInfo->dwPaddingType) { logprintf(pCardData, 0, "unsupported paddingtype CARD_PADDING_PSS\n"); - return SCARD_E_UNSUPPORTED_FEATURE; + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } else if (CARD_PADDING_PKCS1 != pInfo->dwPaddingType) { logprintf(pCardData, 0, "unsupported paddingtype\n"); - return SCARD_E_INVALID_PARAMETER; + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } if (!pinf->pszAlgId) { @@ -4509,11 +4609,11 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512; else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; - else - { + else { logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); - return SCARD_E_UNSUPPORTED_FEATURE; - } + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } } } else { @@ -4535,7 +4635,8 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; else if (hashAlg !=0) { logprintf(pCardData, 0, "bogus aiHashAlg %i\n", hashAlg); - return SCARD_E_UNSUPPORTED_FEATURE; + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; } } @@ -4566,7 +4667,8 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO r = sc_pkcs1_encode(vs->ctx, opt_hash_flags, pInfo->pbData, pInfo->cbData, dataToSign, &dataToSignLen, 0); if (r) { logprintf(pCardData, 2, "PKCS#1 encode error %s\n", sc_strerror(r)); - return SCARD_E_INVALID_VALUE; + dwret = SCARD_E_INVALID_VALUE; + goto err; } } @@ -4594,11 +4696,13 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO logprintf(pCardData, 0, "unknown ECC key size %"SC_FORMAT_LEN_SIZE_T"u\n", prkey_info->field_length); - return SCARD_E_INVALID_VALUE; + dwret = SCARD_E_INVALID_VALUE; + goto err; } } else { logprintf(pCardData, 0, "invalid private key\n"); - return SCARD_E_INVALID_VALUE; + dwret = SCARD_E_INVALID_VALUE; + goto err; } logprintf(pCardData, 3, "pInfo->cbSignedData = %lu\n", @@ -4612,8 +4716,10 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO lg = pInfo->cbSignedData; logprintf(pCardData, 3, "lg = %lu\n", (unsigned long)lg); pbuf = pCardData->pfnCspAlloc(lg); - if (!pbuf) - return SCARD_E_NO_MEMORY; + if (!pbuf) { + dwret = SCARD_E_NO_MEMORY; + goto err; + } logprintf(pCardData, 7, "Data to sign: "); loghex(pCardData, 7, dataToSign, dataToSignLen); @@ -4621,7 +4727,8 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO pInfo->pbSignedData = (PBYTE) pCardData->pfnCspAlloc(pInfo->cbSignedData); if (!pInfo->pbSignedData) { pCardData->pfnCspFree(pbuf); - return SCARD_E_NO_MEMORY; + dwret = SCARD_E_NO_MEMORY; + goto err; } r = sc_pkcs15_compute_signature(vs->p15card, pkey, opt_crypt_flags, dataToSign, dataToSignLen, pbuf, lg); @@ -4629,7 +4736,8 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO if(r < 0) { logprintf(pCardData, 2, "sc_pkcs15_compute_signature error %s\n", sc_strerror(r)); pCardData->pfnCspFree(pbuf); - return md_translate_OpenSC_to_Windows_error(r, SCARD_F_INTERNAL_ERROR); + dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_F_INTERNAL_ERROR); + goto err; } pInfo->cbSignedData = r; @@ -4657,7 +4765,9 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO (unsigned int)pCardData->hScard, (unsigned int)pCardData->hSCardCtx); - return SCARD_S_SUCCESS; +err: + unlock(pCardData); + return dwret; } DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, @@ -4692,17 +4802,24 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, && pCardData->dwVersion == CARD_DATA_CURRENT_VERSION) return ERROR_REVISION_MISMATCH; + if (!lock(pCardData)) + return SCARD_E_INVALID_PARAMETER; + dwret = check_card_reader_status(pCardData, "CardConstructDHAgreement"); if (dwret != SCARD_S_SUCCESS) - return dwret; + goto err; vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); - if (!vs) - return SCARD_E_INVALID_PARAMETER; + if (!vs) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; + } /* check if the container exists */ - if (pAgreementInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) - return SCARD_E_NO_KEY_CONTAINER; + if (pAgreementInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) { + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; + } logprintf(pCardData, 2, "CardConstructDHAgreement dwVersion=%lu, dwKeySpec=%u pbData=%p, cbData=%lu\n", (unsigned long)pAgreementInfo->dwVersion, @@ -4713,14 +4830,16 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, pkey = vs->p15_containers[pAgreementInfo->bContainerIndex].prkey_obj; if (!pkey) { logprintf(pCardData, 2, "CardConstructDHAgreement prkey not found\n"); - return SCARD_E_NO_KEY_CONTAINER; + dwret = SCARD_E_NO_KEY_CONTAINER; + goto err; } /* convert the Windows public key into an OpenSC public key */ dwPublicKeySize = pAgreementInfo->dwPublicKey - sizeof(BCRYPT_ECCKEY_BLOB) + 1; pbPublicKey = (PBYTE) pCardData->pfnCspAlloc(dwPublicKeySize); if (!pbPublicKey) { - return ERROR_OUTOFMEMORY; + dwret = ERROR_OUTOFMEMORY; + goto err; } pbPublicKey[0] = 4; @@ -4733,13 +4852,15 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, if ( r < 0) { logprintf(pCardData, 2, "sc_pkcs15_derive error(%i): %s\n", r, sc_strerror(r)); pCardData->pfnCspFree(pbPublicKey); - return md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + goto err; } out = pCardData->pfnCspAlloc(outlen); if (!out) { - return ERROR_OUTOFMEMORY; + dwret = ERROR_OUTOFMEMORY; + goto err; } r = sc_pkcs15_derive(vs->p15card, pkey, opt_derive_flags, pbPublicKey, dwPublicKeySize, out, &outlen ); @@ -4750,7 +4871,8 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, if ( r < 0) { logprintf(pCardData, 2, "sc_pkcs15_derive error(%i): %s\n", r, sc_strerror(r)); pCardData->pfnCspFree(out); - return md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE); + goto err; } /* save the dh agreement for later use */ @@ -4762,14 +4884,16 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, pAgreementInfo->bSecretAgreementIndex = i; dh_agreement->pbAgreement = out; dh_agreement->dwSize = outlen; - return SCARD_S_SUCCESS; + dwret = SCARD_S_SUCCESS; + goto err; } } /* no empty space => need to allocate memory */ temp = (struct md_dh_agreement*) pCardData->pfnCspAlloc((vs->allocatedAgreements+1) * sizeof(struct md_dh_agreement)); if (!temp) { pCardData->pfnCspFree(out); - return SCARD_E_NO_MEMORY; + dwret = SCARD_E_NO_MEMORY; + goto err; } if ((vs->allocatedAgreements) > 0) { memcpy(temp, vs->dh_agreements, sizeof(struct md_dh_agreement) * (vs->allocatedAgreements)); @@ -4781,7 +4905,10 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, dh_agreement->pbAgreement = out; dh_agreement->dwSize = outlen; vs->allocatedAgreements++; - return SCARD_S_SUCCESS; + +err: + unlock(pCardData); + return dwret; } @@ -6467,6 +6594,7 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags { VENDOR_SPECIFIC *vs; DWORD dwret, suppliedVersion = 0; + CRITICAL_SECTION hScard_lock; if (!pCardData) return SCARD_E_INVALID_PARAMETER; @@ -6516,6 +6644,9 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags return SCARD_E_NO_MEMORY; memset(vs, 0, sizeof(VENDOR_SPECIFIC)); + InitializeCriticalSection(&vs->hScard_lock); + lock(pCardData); + logprintf(pCardData, 1, "==================================================================\n"); logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ", (unsigned long)GetCurrentProcessId(), @@ -6539,7 +6670,6 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags dwret = md_create_context(pCardData, vs); if (dwret != SCARD_S_SUCCESS) goto ret_free; - md_static_data.flags &= ~MD_STATIC_FLAG_CONTEXT_DELETED; pCardData->pfnCardDeleteContext = CardDeleteContext; pCardData->pfnCardQueryCapabilities = CardQueryCapabilities; @@ -6611,6 +6741,8 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags } } + unlock(pCardData); + return SCARD_S_SUCCESS; ret_disassoc: @@ -6618,11 +6750,13 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags ret_release: sc_release_context(vs->ctx); - md_static_data.flags |= MD_STATIC_FLAG_CONTEXT_DELETED; ret_free: + hScard_lock = vs->hScard_lock; pCardData->pfnCspFree(pCardData->pvVendorSpecific); pCardData->pvVendorSpecific = NULL; + LeaveCriticalSection(&hScard_lock); + DeleteCriticalSection(&hScard_lock); return dwret; } @@ -6649,17 +6783,6 @@ static DWORD associate_card(PCARD_DATA pCardData) vs->hSCardCtx = pCardData->hSCardCtx; vs->hScard = pCardData->hScard; - /** - * Check if a linked context has been deleted - if so, repair shared data. - * Multithreaded issue - TODO: proper multithreaded handling - */ - if (md_static_data.flags & MD_STATIC_FLAG_CONTEXT_DELETED) - { - r = sc_context_repair(&(vs->ctx)); - logprintf(pCardData, 2, "sc_context_repair called - result = %d, %s\n", r, sc_strerror(r)); - md_static_data.flags &= ~MD_STATIC_FLAG_CONTEXT_DELETED; - } - /* set the provided reader and card handles into ctx */ r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard); if (r != SC_SUCCESS) { @@ -6721,8 +6844,6 @@ static void disassociate_card(PCARD_DATA pCardData) memset(vs->pin_objs, 0, sizeof(vs->pin_objs)); memset(vs->p15_containers, 0, sizeof(vs->p15_containers)); - EnterCriticalSection(&md_static_data.hScard_lock); - if(vs->p15card) { logprintf(pCardData, 6, "sc_pkcs15_unbind\n"); sc_pkcs15_unbind(vs->p15card); @@ -6740,8 +6861,6 @@ static void disassociate_card(PCARD_DATA pCardData) vs->hSCardCtx = -1; vs->hScard = -1; vs->initialized = FALSE; - - LeaveCriticalSection(&md_static_data.hScard_lock); } @@ -6781,13 +6900,9 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, g_inst = hinstDLL; sc_notify_instance = hinstDLL; sc_notify_init(); - InitializeCriticalSection(&md_static_data.hScard_lock); - md_static_data.attach_check = MD_STATIC_PROCESS_ATTACHED; break; case DLL_PROCESS_DETACH: sc_notify_close(); - DeleteCriticalSection(&md_static_data.hScard_lock); - md_static_data.attach_check = 0; break; } return TRUE; From 6f372293035000c001dcc82910d2e27d65545a8f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Nov 2017 14:13:55 +0100 Subject: [PATCH 0139/4321] opensc-explorer/opensc-tool: Allow extended APDUs --- src/tools/opensc-explorer.c | 8 ++++---- src/tools/opensc-tool.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 0a66bcb5cf..bc1f22dc65 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1530,14 +1530,14 @@ static int do_erase(int argc, char **argv) static int do_random(int argc, char **argv) { - unsigned char buffer[256]; + unsigned char buffer[SC_MAX_EXT_APDU_BUFFER_SIZE]; int r, count; if (argc != 1) return usage(do_random); count = atoi(argv[0]); - if (count < 0 || count > 256) { + if (count < 0 || (size_t) count > sizeof buffer) { printf("Number must be in range 0..256\n"); return -1; } @@ -1625,8 +1625,8 @@ static int do_put_data(int argc, char **argv) static int do_apdu(int argc, char **argv) { sc_apdu_t apdu; - u8 buf[SC_MAX_APDU_BUFFER_SIZE * 2]; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE * 2]; + u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE * 2]; + u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; size_t len, i; int r; diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 102492c60b..b285b28faa 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -498,8 +498,8 @@ static int list_files(void) static int send_apdu(void) { sc_apdu_t apdu; - u8 buf[SC_MAX_APDU_BUFFER_SIZE], - rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE], + rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; size_t len0, r; int c; From 5ca99febe3e1b5d5ab1b5e12744663a316ca28a6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Nov 2017 14:52:48 +0100 Subject: [PATCH 0140/4321] ISO 7816-4 doesn't force a maximum for GET CHALLENGE --- src/libopensc/iso7816.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index b196a94831..7251498e13 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -605,28 +605,29 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { int r; struct sc_apdu apdu; - u8 buf[10]; - if (!rnd && len) + if (len == 0) + return SC_SUCCESS; + + if (!rnd) return SC_ERROR_INVALID_ARGUMENTS; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = 8; - apdu.resp = buf; - apdu.resplen = 8; /* include SW's */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00); + apdu.le = len; + apdu.resp = rnd; + apdu.resplen = len; - while (len > 0) { - size_t n = len > 8 ? 8 : len; + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen != 8) - return sc_check_sw(card, apdu.sw1, apdu.sw2); - memcpy(rnd, apdu.resp, n); - len -= n; - rnd += n; + if (apdu.resplen != len) { + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r == SC_SUCCESS) { + r = SC_ERROR_WRONG_LENGTH; + } } - return 0; + + return r; } From 804ac2b7f2ea8c7fd1795f93e8daa6d88748d7d0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Nov 2017 21:26:41 +0100 Subject: [PATCH 0141/4321] fixed compiler warning --- src/tools/npa-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index aa675fe7af..7ff0edb155 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -359,7 +359,7 @@ main (int argc, char **argv) sc_context_t *ctx = NULL; sc_card_t *card = NULL; - sc_reader_t *reader; + sc_reader_t *reader = NULL; int r, tr_version = EAC_TR_VERSION_2_02; struct establish_pace_channel_input pace_input; From 3e7f7e632c8562db7ffbe9d712dd020cb806825d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 29 Nov 2017 14:18:09 +0100 Subject: [PATCH 0142/4321] SC-HSM: Don't block generic contactless ATR --- src/libopensc/card-sc-hsm.c | 14 ++++++++++---- win32/customactions.cpp | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 69d1cc9c71..b7d84bd087 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -228,17 +228,23 @@ static int sc_hsm_select_file(sc_card_t *card, static int sc_hsm_match_card(struct sc_card *card) { sc_path_t path; - int i, r; + int i, r, type = 0; - i = _sc_match_atr(card, sc_hsm_atrs, &card->type); - if (i >= 0) + i = _sc_match_atr(card, sc_hsm_atrs, &type); + if (i >= 0 && type != SC_CARD_TYPE_SC_HSM_SOC) { + card->type = type; return 1; + } sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); r = sc_hsm_select_file(card, &path, NULL); LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application"); - card->type = SC_CARD_TYPE_SC_HSM; + if (type == SC_CARD_TYPE_SC_HSM_SOC) { + card->type = SC_CARD_TYPE_SC_HSM_SOC; + } else { + card->type = SC_CARD_TYPE_SC_HSM; + } return 1; } diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 3a3291c73a..9380384d64 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -72,7 +72,7 @@ MD_REGISTRATION minidriver_registration[] = { 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("SmartCard-HSM-CL"), {0x3B,0x8E,0x80,0x01,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x18}, 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("SmartCard-HSM-FP"), {0x3B,0x80,0x80,0x01,0x01}, + {TEXT("Contactless Smart Card"), {0x3B,0x80,0x80,0x01,0x01}, 5, {0xff,0xff,0xff,0xff,0xff}}, {TEXT("GoID"), {0x3B,0x84,0x80,0x01,0x47,0x6f,0x49,0x44,0x00}, 9, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00}}, From bb4bdc8a2c1f5002496f9ce8f4623e04b675baef Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 27 Nov 2017 11:41:07 +0100 Subject: [PATCH 0143/4321] CardOS: Try forcing max_send_size for PSO:DEC Fixes https://github.com/OpenSC/OpenSC/issues/1208 Fixes https://github.com/OpenSC/OpenSC/issues/1118 Fixes https://github.com/OpenSC/OpenSC/issues/1005 Fixes https://github.com/OpenSC/OpenSC/issues/802 --- src/libopensc/card-cardos.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 5dfc6d79a9..e3349e7092 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -977,6 +977,32 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); } +static int +cardos_decipher(struct sc_card *card, + const u8 * crgram, size_t crgram_len, + u8 * out, size_t outlen) +{ + int r; + size_t card_max_send_size = card->max_send_size; + size_t reader_max_send_size = card->reader->max_send_size; + + if (sc_get_max_send_size(card) < crgram_len + 1) { + /* CardOS doesn't support chaining for PSO:DEC, so we just _hope_ + * that both, the reader and the card are able to send enough data. + * (data is prefixed with 1 byte padding content indicator) */ + card->max_send_size = crgram_len + 1; + card->reader->max_send_size = crgram_len + 1; + } + + r = iso_ops->decipher(card, crgram, crgram_len, out, outlen); + + /* reset whatever we've modified above */ + card->max_send_size = card_max_send_size; + card->reader->max_send_size = reader_max_send_size; + + return r; +} + static int cardos_lifecycle_get(sc_card_t *card, int *mode) { @@ -1280,6 +1306,7 @@ static struct sc_card_driver * sc_get_driver(void) cardos_ops.set_security_env = cardos_set_security_env; cardos_ops.restore_security_env = cardos_restore_security_env; cardos_ops.compute_signature = cardos_compute_signature; + cardos_ops.decipher = cardos_decipher; cardos_ops.list_files = cardos_list_files; cardos_ops.check_sw = cardos_check_sw; From 47993116daca4f637bdce04af0b32baf024a07e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 5 Dec 2017 08:27:55 +0100 Subject: [PATCH 0144/4321] macOS High Sierra: fixed dmg creation fixes https://github.com/OpenSC/OpenSC/issues/1198 --- MacOSX/build-package.in | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 123cdf5c24..fdac9ca273 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -139,6 +139,8 @@ else codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements --deep target/Library/OpenSC/lib/opensc-pkcs11.bundle fi +imagedir=$(mktemp -d) + # Prepare target root mkdir -p ${BUILDPATH}/target/usr/local/bin cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin @@ -146,15 +148,15 @@ cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin # Build package pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg # Build product -productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "OpenSC @PACKAGE_VERSION@.pkg" +productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" # Build "Uninstaller" -osacompile -o "OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript" +osacompile -o "${imagedir}/OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript" # Create .dmg rm -f OpenSC-@PACKAGE_VERSION@.dmg i=0 -while ! hdiutil create -srcfolder "OpenSC @PACKAGE_VERSION@.pkg" -srcfolder "OpenSC Uninstaller.app" -volname "@PACKAGE_NAME@" OpenSC-@PACKAGE_VERSION@.dmg +while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" OpenSC-@PACKAGE_VERSION@.dmg do i=$[$i+1] if [ $i -gt 2 ] @@ -162,3 +164,4 @@ do exit 1 fi done +rm -rf ${imagedir} From b2cca652373ac19933d88ed6b8563ba6d6b44ac5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 4 Dec 2017 15:59:12 +0100 Subject: [PATCH 0145/4321] sc-hsm: check integrity of SM channel cope with multiple processes that may reset the SM channel when accessing the card at the same time --- src/libopensc/card-sc-hsm.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index b7d84bd087..22c33858b4 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -609,20 +609,32 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, return sc_hsm_soc_unblock(card, data, tries_left); } +#ifdef ENABLE_SM /* For contactless cards always establish a secure channel before PIN * verification. Also, Session PIN generation requires SM. */ if ((card->type == SC_CARD_TYPE_SC_HSM_SOC || card->type == SC_CARD_TYPE_SC_HSM_GOID || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN) - && (data->cmd != SC_PIN_CMD_GET_INFO) -#ifdef ENABLE_SM - && card->sm_ctx.sm_mode != SM_MODE_TRANSMIT -#endif - ) { - LOG_TEST_RET(card->ctx, - sc_hsm_perform_chip_authentication(card), - "Could not perform chip authentication"); + && (data->cmd != SC_PIN_CMD_GET_INFO)) { + struct sc_pin_cmd_data check_sm_pin_data; + memset(&check_sm_pin_data, 0, sizeof(check_sm_pin_data)); + check_sm_pin_data.cmd = SC_PIN_CMD_GET_INFO; + check_sm_pin_data.pin_type = data->pin_type; + check_sm_pin_data.pin_reference = data->pin_reference; + + r = SC_ERROR_NOT_ALLOWED; + if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) { + /* check if the existing SM channel is still valid */ + r = sc_pin_cmd(card, &check_sm_pin_data, NULL); + } + if (r == SC_ERROR_ASN1_OBJECT_NOT_FOUND || r == SC_ERROR_NOT_ALLOWED) { + /* need to establish a new SM channel */ + LOG_TEST_RET(card->ctx, + sc_hsm_perform_chip_authentication(card), + "Could not perform chip authentication"); + } } +#endif if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH) && (data->cmd == SC_PIN_CMD_VERIFY) From 74e7200c311871c7402563ee7dfca43459200ed3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Dec 2017 12:52:50 +0100 Subject: [PATCH 0146/4321] macOS: fixed detection of OpenPACE package --- MacOSX/build-package.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index fdac9ca273..137aa9071b 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -60,8 +60,8 @@ if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then ./configure --disable-shared --prefix=$PREFIX CRYPTO_CFLAGS="$OPENSSL_CFLAGS" CRYPTO_LIBS="$OPENSSL_LIBS" make DESTDIR=$BUILDPATH/openpace_bin install cd .. - export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" - export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" + export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" + export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" fi if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then From 9b2023c7ae47e82ba97a0e778f503a8f8467bc4f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 17 Jan 2018 00:28:05 +0100 Subject: [PATCH 0147/4321] SimpleTLV: Skip correctly two bytes after reading 2b size (#1231) --- src/libopensc/simpletlv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c index f526a1cd71..ab0401b5e7 100644 --- a/src/libopensc/simpletlv.c +++ b/src/libopensc/simpletlv.c @@ -90,8 +90,9 @@ sc_simpletlv_read_tag(u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen) *taglen = 0; return SC_ERROR_INVALID_ARGUMENTS; } + /* skip two bytes (the size) */ len = lebytes2ushort(p); - p++; + p+=2; } *taglen = len; *buf = p; From 44447b780137e5ed4c25ec432e5133c8d4162201 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Jan 2018 18:34:52 +0100 Subject: [PATCH 0148/4321] fixed warnings about uninitialized data --- src/libopensc/asn1.c | 4 ++-- src/libopensc/card-piv.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index c7a629e7ca..d6a94a3908 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -471,7 +471,7 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, *taglen_in = 0; while (left >= 2) { - unsigned int cla, tag, mask = 0xff00; + unsigned int cla = 0, tag, mask = 0xff00; buf = p; /* read a tag */ @@ -504,7 +504,7 @@ const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen, { const u8 *p = *buf; size_t len = *buflen, taglen; - unsigned int cla, tag; + unsigned int cla = 0, tag; if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS) return NULL; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d3122ac1e1..52c899b7b1 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2333,7 +2333,7 @@ static int piv_validate_general_authentication(sc_card_t *card, u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ u8 *rbuf = NULL; - size_t rbuflen; + size_t rbuflen = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); From 16354f11afade2a3a8f7031e8b9e4fd6cb4c87b3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Jan 2018 12:37:20 +0100 Subject: [PATCH 0149/4321] OpenPGP: fixed selecting Applet fixes https://github.com/OpenSC/OpenSC/issues/1230 --- src/libopensc/card-openpgp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 12e048aa5a..177f9e3b3a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -333,11 +333,15 @@ pgp_match_card(sc_card_t *card) else { sc_path_t partial_aid; unsigned char aid[16]; + sc_file_t *file = NULL; /* select application "OpenPGP" */ sc_format_path("D276:0001:2401", &partial_aid); partial_aid.type = SC_PATH_TYPE_DF_NAME; - if (SC_SUCCESS == iso_ops->select_file(card, &partial_aid, NULL)) { + /* OpenPGP card only supports selection *with* requested FCI */ + i = iso_ops->select_file(card, &partial_aid, &file); + sc_file_free(file); + if (SC_SUCCESS == i) { /* read information from AID */ i = sc_get_data(card, 0x004F, aid, sizeof aid); if (i == 16) { From fccc42295dea04fcf8d3df7adef2faaa53007c78 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Jan 2018 11:08:14 +0100 Subject: [PATCH 0150/4321] OpenPGP: Added basic support for OpenPGP card V3 partially implements https://github.com/OpenSC/OpenSC/issues/1215 Refactored OpenPGP code so that future versions of the card will be accessed using the logic for OpenPGP V2. We hope that backward compatibility of the standard will keep the new versions functional. --- src/libopensc/card-openpgp.c | 75 ++++++++++++++++++++-------------- src/libopensc/cards.h | 1 + src/libopensc/pkcs15-openpgp.c | 11 +++-- src/tools/openpgp-tool.c | 16 +++----- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 177f9e3b3a..94a4832051 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -49,6 +49,7 @@ static struct sc_atr_table pgp_atrs[] = { { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, "CryptoStick v1.2 (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, { "3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1", NULL, "Yubikey NEO (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, + { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:f5:73:c0:01:60:00:90:00:1c", NULL, "OpenPGP card V3", SC_CARD_TYPE_OPENPGP_V3, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -332,7 +333,6 @@ pgp_match_card(sc_card_t *card) } else { sc_path_t partial_aid; - unsigned char aid[16]; sc_file_t *file = NULL; /* select application "OpenPGP" */ @@ -340,26 +340,28 @@ pgp_match_card(sc_card_t *card) partial_aid.type = SC_PATH_TYPE_DF_NAME; /* OpenPGP card only supports selection *with* requested FCI */ i = iso_ops->select_file(card, &partial_aid, &file); - sc_file_free(file); if (SC_SUCCESS == i) { - /* read information from AID */ - i = sc_get_data(card, 0x004F, aid, sizeof aid); - if (i == 16) { - switch ((aid[6] << 8) | aid[7]) { /* BCD-coded bytes */ - case 0x0101: - card->type = SC_CARD_TYPE_OPENPGP_V1; - sc_log(card->ctx, "OpenPGPv1-type card found"); - return 1; - case 0x0200: - case 0x0201: - card->type = SC_CARD_TYPE_OPENPGP_V2; - sc_log(card->ctx, "OpenPGPv2-type card found"); - return 1; - default: - sc_log(card->ctx, "unsupported OpenPGP-type card found"); - /* fall through */ + static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; + card->type = SC_CARD_TYPE_OPENPGP_BASE; + card->name = card_name; + if (file->namelen == 16) { + unsigned char major = file->name[6]; + unsigned char minor = file->name[7]; + switch (major) { + case 1: + card->type = SC_CARD_TYPE_OPENPGP_V1; + break; + case 2: + card->type = SC_CARD_TYPE_OPENPGP_V2; + break; + case 3: + card->type = SC_CARD_TYPE_OPENPGP_V3; + break; } + snprintf(card_name, sizeof card_name, "OpenPGP card V%u.%u", major, minor); } + sc_file_free(file); + return 1; } } return 0; @@ -390,14 +392,6 @@ pgp_init(sc_card_t *card) card->cla = 0x00; - /* set pointer to correct list of card objects */ - priv->pgp_objects = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) - ? pgp2_objects : pgp1_objects; - - /* set detailed card version */ - priv->bcd_version = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) - ? OPENPGP_CARD_2_0 : OPENPGP_CARD_1_1; - /* select application "OpenPGP" */ sc_format_path("D276:0001:2401", &aid); aid.type = SC_PATH_TYPE_DF_NAME; @@ -432,6 +426,27 @@ pgp_init(sc_card_t *card) /* kludge: get card's serial number from manufacturer ID + serial number */ memcpy(card->serialnr.value, file->name + 8, 6); card->serialnr.len = 6; + } else { + /* set detailed card version */ + switch (card->type) { + case SC_CARD_TYPE_OPENPGP_V3: + priv->bcd_version = OPENPGP_CARD_3_0; + break; + case SC_CARD_TYPE_OPENPGP_GNUK: + case SC_CARD_TYPE_OPENPGP_V2: + priv->bcd_version = OPENPGP_CARD_2_0; + break; + default: + priv->bcd_version = OPENPGP_CARD_1_1; + break; + } + } + + /* set pointer to correct list of card objects */ + if (priv->bcd_version < OPENPGP_CARD_2_0) { + priv->pgp_objects = pgp1_objects; + } else { + priv->pgp_objects = pgp2_objects; } /* change file path to MF for re-use in MF */ @@ -527,9 +542,9 @@ pgp_get_card_features(sc_card_t *card) /* get "extended capabilities" DO */ if ((pgp_get_blob(card, blob73, 0x00c0, &blob) >= 0) && (blob->data != NULL) && (blob->len > 0)) { - /* in v2.0 bit 0x04 in first byte means "algorithm attributes changeable */ + /* in v2.0 bit 0x04 in first byte means "algorithm attributes changeable" */ if ((blob->data[0] & 0x04) && - (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK)) + (priv->bcd_version >= OPENPGP_CARD_2_0)) priv->ext_caps |= EXT_CAP_ALG_ATTR_CHANGEABLE; /* bit 0x08 in first byte means "support for private use DOs" */ if (blob->data[0] & 0x08) @@ -547,7 +562,7 @@ pgp_get_card_features(sc_card_t *card) } /* in v2.0 bit 0x80 in first byte means "support Secure Messaging" */ if ((blob->data[0] & 0x80) && - (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK)) + (priv->bcd_version >= OPENPGP_CARD_2_0)) priv->ext_caps |= EXT_CAP_SM; if ((priv->bcd_version >= OPENPGP_CARD_2_0) && (blob->len >= 10)) { @@ -993,7 +1008,7 @@ pgp_seek_blob(sc_card_t *card, pgp_blob_t *root, unsigned int id, for (child = root->files; child; child = child->next) { /* The DO of SIMPLE type or the DO holding certificate * does not contain children */ - if (child->info->type == SIMPLE || child->id == DO_CERT) + if ((child->info && child->info->type == SIMPLE) || child->id == DO_CERT) continue; r = pgp_seek_blob(card, child, id, ret); if (r == 0) diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 0cc7650e12..41514532ce 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -106,6 +106,7 @@ enum { SC_CARD_TYPE_OPENPGP_BASE = 9000, SC_CARD_TYPE_OPENPGP_V1, SC_CARD_TYPE_OPENPGP_V2, + SC_CARD_TYPE_OPENPGP_V3, SC_CARD_TYPE_OPENPGP_GNUK, /* jcop driver */ diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 2505e079dc..26077d5239 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -159,8 +159,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) u8 c4data[10]; u8 c5data[70]; int r, i; - const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) - ? pin_cfg_v2 : pin_cfg_v1; + const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V1) + ? pin_cfg_v1 : pin_cfg_v2; sc_path_t path; sc_file_t *file; @@ -430,8 +430,11 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) static int openpgp_detect_card(sc_pkcs15_card_t *p15card) { - if (p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2 - || p15card->card->type == SC_CARD_TYPE_OPENPGP_GNUK) + if (p15card->card->type == SC_CARD_TYPE_OPENPGP_BASE + || p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 + || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2 + || p15card->card->type == SC_CARD_TYPE_OPENPGP_GNUK + || p15card->card->type == SC_CARD_TYPE_OPENPGP_V3) return SC_SUCCESS; else return SC_ERROR_WRONG_CARD; diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 53bc5b64c2..86664d1899 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -572,14 +572,8 @@ int do_delete_key(sc_card_t *card, u8 key_id) int do_erase(sc_card_t *card) { - int r; - /* Check card version */ - if (card->type != SC_CARD_TYPE_OPENPGP_V2) { - printf("Do not erase card which is not OpenPGP v2\n"); - } printf("Erase card\n"); - r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); - return r; + return sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); } int main(int argc, char **argv) @@ -619,9 +613,11 @@ int main(int argc, char **argv) } /* check card type */ - if ((card->type != SC_CARD_TYPE_OPENPGP_V1) && - (card->type != SC_CARD_TYPE_OPENPGP_V2) && - (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { + if ((card->type != SC_CARD_TYPE_OPENPGP_BASE) && + (card->type != SC_CARD_TYPE_OPENPGP_V1) && + (card->type != SC_CARD_TYPE_OPENPGP_V2) && + (card->type != SC_CARD_TYPE_OPENPGP_V3) && + (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { util_error("not an OpenPGP card"); fprintf(stderr, "Card type %X\n", card->type); exit_status = EXIT_FAILURE; From ddeb01ddc1766d0e0dd3f0e7eb73667f56587785 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 9 Jan 2018 12:54:09 +0100 Subject: [PATCH 0151/4321] ISO7816: allow nested CP DOs --- src/libopensc/asn1.c | 2 +- src/libopensc/iso7816.c | 200 +++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 94 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index d6a94a3908..f1424029b8 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -695,7 +695,7 @@ int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out) int a = 0; size_t i; - if (inlen > sizeof(int)) + if (inlen > sizeof(int) || inlen == 0) return SC_ERROR_INVALID_ASN1_OBJECT; if (inbuf[0] & 0x80) a = -1; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 7251498e13..845f58d554 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -334,112 +334,126 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *buf, size_t buflen) { struct sc_context *ctx = card->ctx; - size_t taglen, len = buflen; - int i; - const unsigned char *tag = NULL, *p = buf; + const unsigned char *p, *end; + unsigned int cla = 0, tag = 0; + size_t length; + int size; - sc_log(ctx, "processing FCI bytes"); - tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); - if (tag != NULL && taglen == 2) { - file->id = (tag[0] << 8) | tag[1]; - sc_log(ctx, " file identifier: 0x%02X%02X", tag[0], tag[1]); - } + for (p = buf, length = buflen, end = buf + buflen; + p < end; + p += length, length = end - p) { - /* determine the file size */ - /* try the tag 0x80 then the tag 0x81 */ - file->size = 0; - for (i = 0x80; i <= 0x81; i++) { - int size = 0; - len = buflen; - tag = sc_asn1_find_tag(ctx, p, len, i, &taglen); - if (tag == NULL) - continue; - if (taglen == 0) - continue; - if (sc_asn1_decode_integer(tag, taglen, &size) < 0) - continue; - if (size <0) - continue; - - file->size = size; - sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", - file->size); - break; - } + if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length)) { + break; + } + switch (cla | tag) { + case 0x81: + if (file->size != 0) { + /* don't overwrite existing file size excluding structural information */ + break; + } + /* fall through */ + case 0x80: + /* determine the file size */ + if (sc_asn1_decode_integer(p, length, &size) == 0 && size >= 0) { + file->size = size; + sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", + file->size); + } + break; + + case 0x82: + if (length > 0) { + unsigned char byte = p[0]; + const char *type; + + file->shareable = byte & 0x40 ? 1 : 0; + sc_log(ctx, " shareable: %s", (byte & 0x40) ? "yes" : "no"); + file->ef_structure = byte & 0x07; + switch ((byte >> 3) & 7) { + case 0: + type = "working EF"; + file->type = SC_FILE_TYPE_WORKING_EF; + break; + case 1: + type = "internal EF"; + file->type = SC_FILE_TYPE_INTERNAL_EF; + break; + case 7: + type = "DF"; + file->type = SC_FILE_TYPE_DF; + break; + default: + type = "unknown"; + break; + } + sc_log(ctx, " type: %s", type); + sc_log(ctx, " EF structure: %d", byte & 0x07); + sc_log(ctx, " tag 0x82: 0x%02x", byte); + if (SC_SUCCESS != sc_file_set_type_attr(file, &byte, 1)) + sc_log(ctx, "Warning: Could not set file attributes"); + } + break; - tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen); - if (tag != NULL) { - if (taglen > 0) { - unsigned char byte = tag[0]; - const char *type; - - file->shareable = byte & 0x40 ? 1 : 0; - sc_log(ctx, " shareable: %s", (byte & 0x40) ? "yes" : "no"); - file->ef_structure = byte & 0x07; - switch ((byte >> 3) & 7) { - case 0: - type = "working EF"; - file->type = SC_FILE_TYPE_WORKING_EF; + case 0x83: + if (length == 2) { + file->id = (p[0] << 8) | p[1]; + sc_log(ctx, " file identifier: 0x%02X%02X", p[0], p[1]); + } break; - case 1: - type = "internal EF"; - file->type = SC_FILE_TYPE_INTERNAL_EF; + + case 0x84: + if (length > 0 && length <= 16) { + memcpy(file->name, p, length); + file->namelen = length; + + sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, " File name:", file->name, file->namelen); + if (!file->type) + file->type = SC_FILE_TYPE_DF; + } break; - case 7: - type = "DF"; - file->type = SC_FILE_TYPE_DF; + + case 0x85: + case 0xA5: + if (SC_SUCCESS != sc_file_set_prop_attr(file, p, length)) { + sc_log(ctx, "Warning: Could not set proprietary file properties"); + } break; - default: - type = "unknown"; + + case 0x86: + if (SC_SUCCESS != sc_file_set_sec_attr(file, p, length)) { + sc_log(ctx, "Warning: Could not set file security prperties"); + } break; - } - sc_log(ctx, " type: %s", type); - sc_log(ctx, " EF structure: %d", byte & 0x07); - sc_log(ctx, " tag 0x82: 0x%02x", byte); - if (SC_SUCCESS != sc_file_set_type_attr(file, &byte, 1)) - sc_log(ctx, "Warning: Could not set file attributes"); - } - } - tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen); - if (tag != NULL && taglen > 0 && taglen <= 16) { - memcpy(file->name, tag, taglen); - file->namelen = taglen; + case 0x88: + if (length == 1) { + file->sid = *p; + sc_log(ctx, " short file identifier: 0x%02X", *p); + } + break; - sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, " File name:", file->name, file->namelen); - if (!file->type) - file->type = SC_FILE_TYPE_DF; - } + case 0x8A: + if (length == 1) { + if (p[0] == 0x01) + file->status = SC_FILE_STATUS_CREATION; + else if (p[0] == 0x07 || p[0] == 0x05) + file->status = SC_FILE_STATUS_ACTIVATED; + else if (p[0] == 0x06 || p[0] == 0x04) + file->status = SC_FILE_STATUS_INVALIDATED; + } + break; - tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen); - if (tag != NULL && taglen) - sc_file_set_prop_attr(file, tag, taglen); - else - file->prop_attr_len = 0; - - tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen); - if (tag != NULL && taglen) - sc_file_set_prop_attr(file, tag, taglen); - - tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen); - if (tag != NULL && taglen) - sc_file_set_sec_attr(file, tag, taglen); - - tag = sc_asn1_find_tag(ctx, p, len, 0x88, &taglen); - if (tag != NULL && taglen == 1) - file->sid = *tag; - - tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen); - if (tag != NULL && taglen==1) { - if (tag[0] == 0x01) - file->status = SC_FILE_STATUS_CREATION; - else if (tag[0] == 0x07 || tag[0] == 0x05) - file->status = SC_FILE_STATUS_ACTIVATED; - else if (tag[0] == 0x06 || tag[0] == 0x04) - file->status = SC_FILE_STATUS_INVALIDATED; + case 0x62: + case 0x64: + case 0x6F: + /* allow nested FCP/FMD/FCI templates */ + iso7816_process_fci(card, file, p, length); + } } file->magic = SC_FILE_MAGIC; + return SC_SUCCESS; } From 995845b0027431039bec9bb2e03195ff8386c35c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 9 Jan 2018 14:55:48 +0100 Subject: [PATCH 0152/4321] openpgp: factory reset is possible if LCS is supported --- src/libopensc/card-openpgp.c | 76 ++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 94a4832051..5143424070 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2588,7 +2588,7 @@ pgp_erase_card(sc_card_t *card) * according to https://www.crypto-stick.com/en/faq * (How to reset a Crypto Stick? question). * Gnuk is known not to support this feature. */ - static const char *apdu_hex[] = { + const char *apdu_hex[] = { /* block PIN1 */ "00:20:00:81:08:40:40:40:40:40:40:40:40", "00:20:00:81:08:40:40:40:40:40:40:40:40", @@ -2601,47 +2601,57 @@ pgp_erase_card(sc_card_t *card) "00:20:00:83:08:40:40:40:40:40:40:40:40", /* TERMINATE */ "00:e6:00:00", - /* ACTIVATE */ - "00:44:00:00", NULL }; + sc_apdu_t apdu; int i; int r = SC_SUCCESS; + struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); - /* check card version */ - if (card->type != SC_CARD_TYPE_OPENPGP_V2) { - sc_log(card->ctx, "Card is not OpenPGP v2"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT); - } - sc_log(card->ctx, "Card is OpenPGP v2. Erase card."); - - /* iterate over the commands above */ - for (i = 0; apdu_hex[i] != NULL; i++) { - u8 apdu_bin[25]; /* large enough to convert apdu_hex */ - size_t apdu_bin_len = sizeof(apdu_bin); - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - - /* convert hex array to bin array */ - r = sc_hex_to_bin(apdu_hex[i], apdu_bin, &apdu_bin_len); - LOG_TEST_RET(card->ctx, r, "Failed to convert APDU bytes"); - - /* build APDU from binary array */ - r = sc_bytes2apdu(card->ctx, apdu_bin, apdu_bin_len, &apdu); - if (r) { - sc_log(card->ctx, "Failed to build APDU"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - } + if (priv->bcd_version < OPENPGP_CARD_2_0 + || priv->state == CARD_STATE_UNKNOWN) { + LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT, + "Card does not offer life cycle management"); + } + + switch (priv->state) { + case CARD_STATE_ACTIVATED: + /* iterate over the commands above */ + for (i = 0; apdu_hex[i] != NULL; i++) { + u8 apdu_bin[25]; /* large enough to convert apdu_hex */ + size_t apdu_bin_len = sizeof(apdu_bin); + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + + /* convert hex array to bin array */ + r = sc_hex_to_bin(apdu_hex[i], apdu_bin, &apdu_bin_len); + LOG_TEST_RET(card->ctx, r, "Failed to convert APDU bytes"); + + /* build APDU from binary array */ + r = sc_bytes2apdu(card->ctx, apdu_bin, apdu_bin_len, &apdu); + if (r) { + sc_log(card->ctx, "Failed to build APDU"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); - /* send APDU to card */ - sc_log(card->ctx, "Sending APDU%d %s", i, apdu_hex[i]); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "Transmitting APDU failed"); + /* send APDU to card */ + sc_log(card->ctx, "Sending APDU%d %s", i, apdu_hex[i]); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "Transmitting APDU failed"); + } + /* fall through */ + case CARD_STATE_INITIALIZATION: + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0, 0); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "Transmitting APDU failed"); + break; + default: + LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT, + "Card does not offer life cycle management"); } LOG_FUNC_RETURN(card->ctx, r); From 449f6c2b9462e265204811a417b871ca82f2192d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 17 Jan 2018 21:11:16 +0100 Subject: [PATCH 0153/4321] OpenPGP: Added support for PIN logout and status --- src/libopensc/card-openpgp.c | 38 +++++++++++++++++++++++++++++++++++- src/libopensc/iso7816.c | 16 +++++++++++++++ src/libopensc/opensc.h | 10 ++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5143424070..04b9134269 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -84,7 +84,8 @@ enum _version { /* 2-byte BCD-alike encoded version number */ OPENPGP_CARD_1_1 = 0x0101, OPENPGP_CARD_2_0 = 0x0200, OPENPGP_CARD_2_1 = 0x0201, - OPENPGP_CARD_3_0 = 0x0300 + OPENPGP_CARD_3_0 = 0x0300, + OPENPGP_CARD_3_1 = 0x0301, }; enum _access { /* access flags for the respective DO/file */ @@ -536,6 +537,10 @@ pgp_get_card_features(sc_card_t *card) } } + if (priv->bcd_version >= OPENPGP_CARD_3_1) { + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + } + if ((pgp_get_blob(card, priv->mf, 0x006e, &blob6e) >= 0) && (pgp_get_blob(card, blob6e, 0x0073, &blob73) >= 0)) { @@ -1617,6 +1622,36 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } +int pgp_logout(struct sc_card *card) +{ + int r = SC_SUCCESS; + struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + + if (priv->bcd_version >= OPENPGP_CARD_3_1) { + unsigned char pin_reference; + for (pin_reference = 0x81; pin_reference <= 0x83; pin_reference++) { + int tmp = iso7816_logout(card, pin_reference); + if (r == SC_SUCCESS) { + r = tmp; + } + } + } else { + sc_path_t path; + sc_file_t *file = NULL; + + /* select application "OpenPGP" */ + sc_format_path("D276:0001:2401", &path); + path.type = SC_PATH_TYPE_DF_NAME; + r = iso_ops->select_file(card, &path, &file); + sc_file_free(file); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + + /** * ABI: set security environment. */ @@ -2834,6 +2869,7 @@ sc_get_driver(void) pgp_ops.read_binary = pgp_read_binary; pgp_ops.write_binary = pgp_write_binary; pgp_ops.pin_cmd = pgp_pin_cmd; + pgp_ops.logout = pgp_logout; pgp_ops.get_data = pgp_get_data; pgp_ops.put_data = pgp_put_data; pgp_ops.set_security_env= pgp_set_security_env; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 845f58d554..e5916e7dd4 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1417,3 +1417,19 @@ int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, err: return r; } + +int iso7816_logout(sc_card_t *card, unsigned char pin_reference) +{ + int r; + sc_apdu_t apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0xFF, pin_reference); + + r = sc_transmit_apdu(card, &apdu); + if (r < 0) + return r; + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + + return r; +} diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 67410eabc3..3024919d57 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1418,6 +1418,16 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, u8 *ef, size_t ef_len); +/** + * @brief Set verification status of a specific PIN to “not verified†+ * + * @param[in] card + * @param[in] pin_reference PIN reference written to P2 + * + * @note The appropriate directory must be selected before calling this function. + * */ +int iso7816_logout(sc_card_t *card, unsigned char pin_reference); + #ifdef __cplusplus } #endif From 490e825a65b0df626c2f7e16caf5e72cafe4d7d0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 18 Jan 2018 12:33:34 +0100 Subject: [PATCH 0154/4321] OpenPGP: implemented GET CHALLENGE --- src/libopensc/card-openpgp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 04b9134269..022e5d4cd0 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1202,6 +1202,24 @@ pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) LOG_FUNC_RETURN(card->ctx, k); } +static int +pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) +{ + struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + + if (0 == (priv->ext_caps & EXT_CAP_GET_CHALLENGE)) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + if (priv->max_challenge_size > 0 && len > priv->max_challenge_size) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); + } + + LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len)); +} + /** * ABI: READ BINARY. @@ -2866,6 +2884,7 @@ sc_get_driver(void) pgp_ops.finish = pgp_finish; pgp_ops.select_file = pgp_select_file; pgp_ops.list_files = pgp_list_files; + pgp_ops.get_challenge = pgp_get_challenge; pgp_ops.read_binary = pgp_read_binary; pgp_ops.write_binary = pgp_write_binary; pgp_ops.pin_cmd = pgp_pin_cmd; From 74553a5a8fc85157db0f907ca0ff2a50c3992293 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 16 Jan 2018 10:59:15 +0100 Subject: [PATCH 0155/4321] PC/SC: don't reset the card on disconnection Windows/macOS (minidriver/tokend) handle the authentication status and perform an explicit logout on shutdown. PKCS#11 standard requires a session for logging into the card; when closing the session we perform an explicit logout. Hence, the authentication status should be reset even if not performing a reset on disconnect. --- etc/opensc.conf.in | 4 ++-- src/libopensc/reader-pcsc.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index d1b3730b05..a417fe227b 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -84,8 +84,8 @@ app default { # # What to do when disconnecting from a card (SCardDisconnect) # Valid values: leave, reset, unpower. - # Default: reset - # disconnect_action = unpower; + # Default: leave + # disconnect_action = reset; # # What to do at the end of a transaction (SCardEndTransaction) # Valid values: leave, reset, unpower. diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 6075dc0614..b80aa94079 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -781,7 +781,7 @@ static int pcsc_init(sc_context_t *ctx) gpriv->connect_exclusive = scconf_get_bool(conf_block, "connect_exclusive", gpriv->connect_exclusive); gpriv->disconnect_action = - pcsc_reset_action(scconf_get_str(conf_block, "disconnect_action", "reset")); + pcsc_reset_action(scconf_get_str(conf_block, "disconnect_action", "leave")); gpriv->transaction_end_action = pcsc_reset_action(scconf_get_str(conf_block, "transaction_end_action", "leave")); gpriv->reconnect_action = From f24b55db4a9ba0fb3827655873793a5c14913f4c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 15 Jan 2018 16:07:53 +0100 Subject: [PATCH 0156/4321] IAS/ECC: fixed applet selection fixes https://github.com/OpenSC/OpenSC/issues/1240 --- src/libopensc/card-iasecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index b6c6995db9..0df02f63bf 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -319,7 +319,7 @@ iasecc_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, int rv; /* Select application (deselect previously selected application) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x00); + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); apdu.lc = aid->len; apdu.data = aid->value; apdu.datalen = aid->len; From a0b562a7c8f14f4efbc7ba45ebb2296e6908adbe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 24 Jan 2018 11:01:58 +0100 Subject: [PATCH 0157/4321] documented usage of SM_MODE_ACL fixes https://github.com/OpenSC/OpenSC/issues/971 --- src/libopensc/sm.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index e27725f45b..55b918b467 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -45,8 +45,11 @@ extern "C" { #define SM_TYPE_CWA14890 0x400 #define SM_TYPE_DH_RSA 0x500 +/** don't use SM */ #define SM_MODE_NONE 0x0 +/** let the card driver decide when to use SM, possibly based on the card's ACLs */ #define SM_MODE_ACL 0x100 +/** use SM for all commands */ #define SM_MODE_TRANSMIT 0x200 #define SM_CMD_INITIALIZE 0x10 From e5699ef04b415dca63e76f13351b1782f643f4de Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 28 Jan 2018 21:25:42 +0100 Subject: [PATCH 0158/4321] DNIe: card also supports 1920 bits (#1247) fixes https://github.com/OpenSC/OpenSC/issues/1246 --- src/libopensc/card-dnie.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 92edf59626..076d4415c3 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -712,6 +712,7 @@ static void init_flags(struct sc_card *card) /* RSA Support with PKCS1.5 padding */ algoflags = SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_PKCS1; _sc_card_add_rsa_alg(card, 1024, algoflags, 0); + _sc_card_add_rsa_alg(card, 1920, algoflags, 0); _sc_card_add_rsa_alg(card, 2048, algoflags, 0); } @@ -1664,8 +1665,6 @@ static int dnie_compute_signature(struct sc_card *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); if (datalen > SC_MAX_APDU_BUFFER_SIZE) /* should be 256 */ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if (outlen<256) /* enought space to store 2048 bit response */ - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); #ifdef ENABLE_DNIE_UI /* (Requested by DGP): on signature operation, ask user consent */ @@ -1704,6 +1703,8 @@ static int dnie_compute_signature(struct sc_card *card, /* ok: copy result from buffer */ result_resplen = apdu.resplen; + if ((int)outlenctx, SC_ERROR_INVALID_ARGUMENTS); memcpy(out, apdu.resp, result_resplen); /* and return response length */ LOG_FUNC_RETURN(card->ctx, result_resplen); From a7b066cc839dad61adae62af6139445e5cbc1348 Mon Sep 17 00:00:00 2001 From: edgarholleis Date: Mon, 29 Jan 2018 10:30:03 +0100 Subject: [PATCH 0159/4321] Fix memleak (#1255) --- src/pkcs11/framework-pkcs15.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 2fe8ad5c34..a4a1e1c373 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4626,7 +4626,18 @@ get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) if (rc != SC_SUCCESS) return sc_to_cryptoki_error(rc, NULL); - check_attribute_buffer(attr, value_len); + if (attr->pValue == NULL_PTR) { + attr->ulValueLen = value_len; + free(value); + return CKR_OK; + } + if (attr->ulValueLen < value_len) { + attr->ulValueLen = value_len; + free(value); + return CKR_BUFFER_TOO_SMALL; + } + attr->ulValueLen = value_len; + memcpy(attr->pValue, value, value_len); free(value); return CKR_OK; From ed0cfbd8089c2e5e19559339d2770803172fd9a5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 10 Jan 2018 13:13:48 +0100 Subject: [PATCH 0160/4321] libopensc: Log what configuration file is used This simplifies debugging --- src/libopensc/ctx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 629480c1db..0a40b79bcb 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -676,6 +676,7 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) if (!conf_path) conf_path = OPENSC_CONF_PATH; #endif + sc_log(ctx, "Using configuration file '%s'", conf_path); ctx->conf = scconf_new(conf_path); if (ctx->conf == NULL) return; From e7deb3410dd61a7cedcea24ae7d0d3c9cef3088a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 11 Jan 2018 11:16:57 +0100 Subject: [PATCH 0161/4321] cac: Fail if the read instruction does not return anything To avoid infinite loop on "unfriendly" cards, we assume that read data instruction always returns some data. It it does not, we can safely assume the file is not there or it is not the card we are looking for. --- src/libopensc/card-cac.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 178150d354..1a11fb9d5a 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -445,6 +445,9 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o len = sizeof(count); out_ptr = count; r = cac_apdu_io(card, CAC_INS_READ_FILE, 0, 0, ¶ms[0], sizeof(params), &out_ptr, &len); + if (len == 0) { + r = SC_ERROR_FILE_NOT_FOUND; + } if (r < 0) goto fail; @@ -462,6 +465,10 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o params[1] = len; r = cac_apdu_io(card, CAC_INS_READ_FILE, HIGH_BYTE_OF_SHORT(offset), LOW_BYTE_OF_SHORT(offset), ¶ms[0], sizeof(params), &out_ptr, &len); + /* if there is no data, assume there is no file */ + if (len == 0) { + r = SC_ERROR_FILE_NOT_FOUND; + } if (r < 0) { goto fail; } From ccfd4b4c3557b6d85581e6154f9152cb36d58bf0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 11 Jan 2018 11:42:06 +0100 Subject: [PATCH 0162/4321] cac: Try to read the ACA file Some "unfriendly" cards return SW 90 00 to any instruction including the ACA file selection and therefore they are identified as CAC card. To avoid this, we will try to read the assumed ACA file and we will mark the card as matched only if we will read something from that file. We do not parse the content yet. --- src/libopensc/card-cac.c | 63 ++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 1a11fb9d5a..113c9f77d1 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1476,6 +1476,48 @@ static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *pr return SC_SUCCESS; } +static int cac_process_ACA(sc_card_t *card, cac_private_data_t *priv) +{ + int r, index; + u8 *tl = NULL, *val = NULL; + size_t tl_len, val_len; + + + r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len); + if (r < 0) + goto done; + + r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len); + if (r < 0) + goto done; + + /* TODO we should process the ACA file -- so far we are happy we can read it */ + //r = cac_parse_ACA(card, priv, tl, tl_len, val, val_len); + r = cac_find_first_pki_applet(card, &index); + if (r == SC_SUCCESS) { + priv = cac_new_private_data(); + if (!priv) { + r = SC_ERROR_OUT_OF_MEMORY; + goto done; + } + r = cac_populate_cac_1(card, index, priv); + if (r == SC_SUCCESS) { + priv->aca_path = malloc(sizeof(sc_path_t)); + if (!priv->aca_path) { + r = SC_ERROR_OUT_OF_MEMORY; + goto done; + } + memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t)); + } + } +done: + if (tl) + free(tl); + if (val) + free(val); + return r; +} + /* * Look for a CAC card. If it exists, initialize our data structures */ @@ -1511,21 +1553,12 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) /* Even some ALT tokens can be missing CCC so we should try with ACA */ r = cac_select_ACA(card); if (r == SC_SUCCESS) { - r = cac_find_first_pki_applet(card, &index); - if (r == SC_SUCCESS) { - priv = cac_new_private_data(); - if (!priv) - return SC_ERROR_OUT_OF_MEMORY; - r = cac_populate_cac_1(card, index, priv); - if (r == SC_SUCCESS) { - priv->aca_path = malloc(sizeof(sc_path_t)); - if (!priv->aca_path) - return SC_ERROR_OUT_OF_MEMORY; - memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t)); - card->type = SC_CARD_TYPE_CAC_II; - card->drv_data = priv; - return r; - } + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "ACA found, is CAC-2 without CCC"); + r = cac_process_ACA(card, priv); + if (r == SC_SUCCESS) { + card->type = SC_CARD_TYPE_CAC_II; + card->drv_data = priv; + return r; } } From 1d49e8e0db405e15cda13fa9d16dc75d9ceaf061 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Jan 2018 16:59:18 +0100 Subject: [PATCH 0163/4321] docs/tools: Improve bash-completion template and generation This allows us to generate templates also for arguments expecting files (input, output) or PKCS#11 modules. The general ideal was already implemented, but never completed. --- doc/tools/Makefile.am | 7 +++++-- doc/tools/completion-template | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index cc2b944845..5eb892094b 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -36,8 +36,11 @@ tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdi $(shell sed -n 's,.*.*.*,\1,pg' $< \ | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,')," \ | sed "s,FILEOPTS,\ - $(shell sed -n 's,.*.*.*filename.*,\1,pg' $< \ - | sort -u | grep -- '^\-' | tr '\n' '|')," \ + $(shell sed -n 's,.*.*.*\(filename\|path\).*,\1,pg' $< \ + | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,' | grep ^ || echo "!*")," \ + | sed "s,MODULEOPTS,\ + $(shell sed -n 's,.*.*.*mod.*,\1,pg' $< \ + | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,' | grep ^ || echo "!*")," \ | sed "s,FUNCTION_NAME,$(shell echo $@ | sed s,-,_,g)," \ | sed "s,PROGRAM_NAME,$@," \ > $@ diff --git a/doc/tools/completion-template b/doc/tools/completion-template index e0796b62d5..94e40c2c56 100644 --- a/doc/tools/completion-template +++ b/doc/tools/completion-template @@ -15,6 +15,14 @@ _FUNCTION_NAME() fi case "${prev}" in + MODULEOPTS) + _filedir so + return 0 + ;; + FILEOPTS) + _filedir + return 0 + ;; OPTSWITHARGS) return 0 ;; From 5cb0484ea6d6c2c0229bde9cbb17364c17173a24 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 6 Feb 2018 13:52:23 +0100 Subject: [PATCH 0164/4321] Correctly autocomplete --write-object option --- doc/tools/pkcs11-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 7c17972e7a..faec4bdff6 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -519,7 +519,7 @@ - id, + path, path Write a key or certificate object to the token. From 391ad1db01619fa4357d7992002a6ba0ca7f9490 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 6 Feb 2018 15:01:38 +0100 Subject: [PATCH 0165/4321] Use filename replacement to allow completion --- doc/tools/pkcs11-tool.1.xml | 24 ++++++++++++------------ doc/tools/westcos-tool.1.xml | 16 ++++++++-------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index faec4bdff6..f8d638b450 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -37,9 +37,9 @@ - path + filename - Extract information from path + Extract information from filename (DER-encoded certificate file) and create the corresponding attributes when writing an object to the token. Example: the certificate subject name is used to create the CKA_SUBJECT @@ -122,8 +122,8 @@ - path, - path + filename, + filename Specify the path to a file for input. @@ -256,18 +256,18 @@ - path, - path + filename, + filename Test a Mozilla-like keypair generation - and certificate request. Specify the path + and certificate request. Specify the filename to the certificate file. - path, - path + filename, + filename Specify the path to a file for output. @@ -519,11 +519,11 @@ - path, - path + filename, + filename Write a key or certificate object to the token. - path points to the DER-encoded certificate or key file. + filename points to the DER-encoded certificate or key file. diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index 240128cd5c..d1609967ab 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -138,11 +138,11 @@ - path, - path + filename, + filename - Read the file path from the card. - The file is written on disk with name path. + Read the file filename from the card. + The file is written on disk with name filename. User authentication is required for this operation. @@ -184,12 +184,12 @@ - path, - path + filename, + filename - Put the file with name path + Put the file with name filename from disk to card. - On the card the file is written in path. + On the card the file is written in filename. User authentication is required for this operation. From e46193499b67de1712e4d2e18c330f8fcf716364 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 6 Feb 2018 15:05:41 +0100 Subject: [PATCH 0166/4321] Use only 'filename' for file arguments replacements --- doc/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 5eb892094b..bc8af488cf 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -36,7 +36,7 @@ tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdi $(shell sed -n 's,.*.*.*,\1,pg' $< \ | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,')," \ | sed "s,FILEOPTS,\ - $(shell sed -n 's,.*.*.*\(filename\|path\).*,\1,pg' $< \ + $(shell sed -n 's,.*.*.*filename.*,\1,pg' $< \ | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,' | grep ^ || echo "!*")," \ | sed "s,MODULEOPTS,\ $(shell sed -n 's,.*.*.*mod.*,\1,pg' $< \ From d719977d144d8bc7a261076211ebe54c69c6cbcf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 16 Jan 2018 21:03:30 +0100 Subject: [PATCH 0167/4321] Reselect PKI-Applets after card reset PKI-Applets may not be active if the card has been reset or unpowered. The SELECT command used to activate the applet, is identical to the one used during card matching or initialization. --- src/libopensc/card-asepcos.c | 15 +++++++++++ src/libopensc/card-authentic.c | 17 ++++++++++++- src/libopensc/card-coolkey.c | 17 +++++++++++++ src/libopensc/card-gemsafeV1.c | 15 +++++++++++ src/libopensc/card-gids.c | 18 ++++++++++++- src/libopensc/card-isoApplet.c | 16 ++++++++++++ src/libopensc/card-jpki.c | 14 +++++++++++ src/libopensc/card-muscle.c | 16 ++++++++++++ src/libopensc/card-openpgp.c | 46 ++++++++++++++++++++-------------- src/libopensc/card-piv.c | 2 +- 10 files changed, 154 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 5fe360fff8..6a79b80e18 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -1026,6 +1026,20 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, return r; } +static int asepcos_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0 && card->type == SC_CARD_TYPE_ASEPCOS_JAVA) { + /* in case of a Java card try to select the ASEPCOS applet */ + r = asepcos_select_asepcos_applet(card); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver * sc_get_driver(void) { if (iso_ops == NULL) @@ -1042,6 +1056,7 @@ static struct sc_card_driver * sc_get_driver(void) asepcos_ops.list_files = asepcos_list_files; asepcos_ops.card_ctl = asepcos_card_ctl; asepcos_ops.pin_cmd = asepcos_pin_cmd; + asepcos_ops.card_reader_lock_obtained = asepcos_card_reader_lock_obtained; return &asepcos_drv; } diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 89e6a40a5e..8bf49c90ea 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -491,7 +491,6 @@ authentic_init(struct sc_card *card) LOG_FUNC_RETURN(ctx, rv); } - static int authentic_erase_binary(struct sc_card *card, unsigned int offs, size_t count, unsigned long flags) { @@ -2115,6 +2114,21 @@ authentic_finish(struct sc_card *card) } +static int authentic_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0 + && card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { + r = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + + /* SM related */ #ifdef ENABLE_SM static int @@ -2367,6 +2381,7 @@ sc_get_driver(void) authentic_ops.card_ctl = authentic_card_ctl; authentic_ops.process_fci = authentic_process_fci; authentic_ops.pin_cmd = authentic_pin_cmd; + authentic_ops.card_reader_lock_obtained = authentic_card_reader_lock_obtained; return &authentic_drv; } diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 5d462a8f99..4ad347372b 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2287,6 +2287,7 @@ static int coolkey_init(sc_card_t *card) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } + static int coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { @@ -2342,6 +2343,7 @@ coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) return r; } + static int coolkey_logout(sc_card_t *card) { @@ -2358,6 +2360,20 @@ coolkey_logout(sc_card_t *card) return SC_SUCCESS; } + +static int coolkey_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + r = coolkey_select_applet(card); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_operations coolkey_ops; static struct sc_card_driver coolkey_drv = { @@ -2388,6 +2404,7 @@ static struct sc_card_driver * sc_get_driver(void) coolkey_ops.check_sw = coolkey_check_sw; coolkey_ops.pin_cmd = coolkey_pin_cmd; coolkey_ops.logout = coolkey_logout; + coolkey_ops.card_reader_lock_obtained = coolkey_card_reader_lock_obtained; return &coolkey_drv; } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index ff05629768..c560772068 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -566,6 +566,20 @@ static int gemsafe_get_challenge(sc_card_t *card, u8 *rnd, size_t len) return r; } +static int gemsafe_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + gemsafe_exdata *exdata = (gemsafe_exdata *)card->drv_data; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0 && exdata) { + r = gp_select_applet(card, exdata->aid, exdata->aid_len); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver *sc_get_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -585,6 +599,7 @@ static struct sc_card_driver *sc_get_driver(void) gemsafe_ops.get_challenge = gemsafe_get_challenge; gemsafe_ops.process_fci = gemsafe_process_fci; gemsafe_ops.pin_cmd = iso_ops->pin_cmd; + gemsafe_ops.card_reader_lock_obtained = gemsafe_card_reader_lock_obtained; return &gemsafe_drv; } diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 52f06816d6..73b0c9a6db 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -2047,13 +2047,27 @@ static int gids_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) } } +static int gids_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + size_t resplen = sizeof(rbuf); + r = gids_select_aid(card, gids_aid.value, gids_aid.len, rbuf, &resplen); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver *sc_get_driver(void) { if (iso_ops == NULL) iso_ops = sc_get_iso7816_driver()->ops; - gids_ops.match_card = gids_match_card; gids_ops.init = gids_init; gids_ops.finish = gids_finish; @@ -2088,6 +2102,8 @@ static struct sc_card_driver *sc_get_driver(void) gids_ops.put_data = NULL; gids_ops.delete_record = NULL; gids_ops.read_public_key = gids_read_public_key; + gids_ops.card_reader_lock_obtained = gids_card_reader_lock_obtained; + return &gids_drv; } diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 2682608f74..4cf865a310 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1224,6 +1224,21 @@ isoApplet_get_challenge(struct sc_card *card, u8 *rnd, size_t len) LOG_FUNC_RETURN(ctx, r); } +static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + size_t rlen = SC_MAX_APDU_BUFFER_SIZE; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + r = isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver *sc_get_driver(void) { sc_card_driver_t *iso_drv = sc_get_iso7816_driver(); @@ -1246,6 +1261,7 @@ static struct sc_card_driver *sc_get_driver(void) isoApplet_ops.set_security_env = isoApplet_set_security_env; isoApplet_ops.compute_signature = isoApplet_compute_signature; isoApplet_ops.get_challenge = isoApplet_get_challenge; + isoApplet_ops.card_reader_lock_obtained = isoApplet_card_reader_lock_obtained; /* unsupported functions */ isoApplet_ops.write_binary = NULL; diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 3996b40849..65618af506 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -362,6 +362,19 @@ jpki_compute_signature(sc_card_t * card, LOG_FUNC_RETURN(card->ctx, apdu.resplen); } +static int jpki_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + r = jpki_select_ap(card); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver * sc_get_driver(void) { @@ -376,6 +389,7 @@ sc_get_driver(void) jpki_ops.pin_cmd = jpki_pin_cmd; jpki_ops.set_security_env = jpki_set_security_env; jpki_ops.compute_signature = jpki_compute_signature; + jpki_ops.card_reader_lock_obtained = jpki_card_reader_lock_obtained; return &jpki_drv; } diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 85862b7e91..5733ab0a0a 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -810,6 +810,21 @@ static int muscle_check_sw(sc_card_t * card, unsigned int sw1, unsigned int sw2) return iso_ops->check_sw(card, sw1, sw2); } +static int muscle_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) != 1) { + r = SC_ERROR_INVALID_CARD; + } + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver * sc_get_driver(void) { @@ -837,6 +852,7 @@ static struct sc_card_driver * sc_get_driver(void) muscle_ops.select_file = muscle_select_file; muscle_ops.delete_file = muscle_delete_file; muscle_ops.list_files = muscle_list_files; + muscle_ops.card_reader_lock_obtained = muscle_card_reader_lock_obtained; return &muscle_drv; } diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 022e5d4cd0..e66cf87fc5 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -378,7 +378,7 @@ static int pgp_init(sc_card_t *card) { struct pgp_priv_data *priv; - sc_path_t aid; + sc_path_t path; sc_file_t *file = NULL; struct do_info *info; int r; @@ -394,9 +394,9 @@ pgp_init(sc_card_t *card) card->cla = 0x00; /* select application "OpenPGP" */ - sc_format_path("D276:0001:2401", &aid); - aid.type = SC_PATH_TYPE_DF_NAME; - if ((r = iso_ops->select_file(card, &aid, &file)) < 0) { + sc_format_path("D276:0001:2401", &path); + path.type = SC_PATH_TYPE_DF_NAME; + if ((r = iso_ops->select_file(card, &path, &file)) < 0) { pgp_finish(card); LOG_FUNC_RETURN(card->ctx, r); } @@ -2868,11 +2868,28 @@ pgp_update_binary(sc_card_t *card, unsigned int idx, } -/** - * ABI: driver binding stuff. - */ -static struct sc_card_driver * -sc_get_driver(void) +static int pgp_card_reader_lock_obtained(sc_card_t *card, int was_reset) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (was_reset > 0) { + sc_file_t *file = NULL; + sc_path_t path; + /* select application "OpenPGP" */ + sc_format_path("D276:0001:2401", &path); + path.type = SC_PATH_TYPE_DF_NAME; + r = iso_ops->select_file(card, &path, &file); + sc_file_free(file); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + + +struct sc_card_driver * +sc_get_openpgp_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -2897,16 +2914,7 @@ sc_get_driver(void) pgp_ops.card_ctl = pgp_card_ctl; pgp_ops.delete_file = pgp_delete_file; pgp_ops.update_binary = pgp_update_binary; + pgp_ops.card_reader_lock_obtained = pgp_card_reader_lock_obtained; return &pgp_drv; } - - -/** - * ABI: driver binding stuff. - */ -struct sc_card_driver * -sc_get_openpgp_driver(void) -{ - return sc_get_driver(); -} diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 52c899b7b1..d3122ac1e1 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2333,7 +2333,7 @@ static int piv_validate_general_authentication(sc_card_t *card, u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ u8 *rbuf = NULL; - size_t rbuflen = 0; + size_t rbuflen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); From 87cdfcb08c7450d003786ad73ee28dfa7636b346 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 19 Jan 2018 23:55:35 +0100 Subject: [PATCH 0168/4321] OpenPGP: Implemented "keep alive" command --- etc/opensc.conf.in | 32 ++++++++++++++++++++++++++------ src/libopensc/card-openpgp.c | 15 +++++++++++++++ src/libopensc/ctx.c | 2 ++ src/libopensc/dir.c | 6 ++---- src/libopensc/opensc.h | 1 + src/libopensc/pkcs15.c | 11 ++++------- 6 files changed, 50 insertions(+), 17 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index a417fe227b..939901e026 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -272,8 +272,9 @@ app default { # can be specified as strings: # # rng - On-board random number source + # keep_alive - Request the card driver to send a "keep alive" command before each transaction to make sure that the required applet is still selected. # - # flags = "rng", "0x80000000"; + # flags = "rng", "keep_alive", "0x80000000"; # Enable pkcs11 initialization. # Default: no @@ -373,11 +374,30 @@ app default { # notify_pin_bad_text = "bad text"; # } - # PIV cards need an entry similar to this one: - # card_atr 3B:7D:96:00:00:80:31:80:65:B0:83:11:00:AC:83:00:90:00 { - # name = "PIV-II"; - # driver = "piv"; - # } + # Yubikey is known to have the PIV applet and the OpenPGP applet. OpenSC + # can handle both to access keys and certificates, but only one at a time. + card_atr 3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4 { + name = "Yubikey 4"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } + card_atr 3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1 { + name = "Yubikey Neo"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } + card_atr 3b:8c:80:01:59:75:62:69:6b:65:79:4e:45:4f:72:33:58 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00"; + name = "Yubikey Neo"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } # Micardo driver sometimes only play together with T=0 # In theory only the 'cold' ATR should be specified, as T=0 will diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e66cf87fc5..fb6ae52681 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2870,10 +2870,25 @@ pgp_update_binary(sc_card_t *card, unsigned int idx, static int pgp_card_reader_lock_obtained(sc_card_t *card, int was_reset) { + struct pgp_priv_data *priv = DRVDATA(card); /* may be null during initialization */ int r = SC_SUCCESS; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (card->flags & SC_CARD_FLAG_KEEP_ALIVE + && was_reset <= 0 + && priv != NULL && priv->mf && priv->mf->file) { + /* check whether applet is still selected */ + unsigned char aid[16]; + + r = sc_get_data(card, 0x004F, aid, sizeof aid); + if ((size_t) r != priv->mf->file->namelen + || 0 != memcmp(aid, priv->mf->file->name, r)) { + /* reselect is required */ + was_reset = 1; + } + } + if (was_reset > 0) { sc_file_t *file = NULL; sc_path_t path; diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 0a40b79bcb..3f4e73d387 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -631,6 +631,8 @@ static int load_card_atrs(sc_context_t *ctx) if (!strcmp(list->data, "rng")) flags = SC_CARD_FLAG_RNG; + else if (!strcmp(list->data, "keep_alive")) + flags = SC_CARD_FLAG_KEEP_ALIVE; else if (sscanf(list->data, "%x", &flags) != 1) flags = 0; diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 59e988d77c..12751bd7e4 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -259,10 +259,8 @@ void sc_free_apps(sc_card_t *card) int i; for (i = 0; i < card->app_count; i++) { - if (card->app[i]->label) - free(card->app[i]->label); - if (card->app[i]->ddo.value) - free(card->app[i]->ddo.value); + free(card->app[i]->label); + free(card->app[i]->ddo.value); free(card->app[i]); } card->app_count = -1; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 3024919d57..943d55da3f 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -453,6 +453,7 @@ struct sc_reader_operations { /* Hint SC_CARD_CAP_RNG */ #define SC_CARD_FLAG_RNG 0x00000002 +#define SC_CARD_FLAG_KEEP_ALIVE 0x00000004 /* * Card capabilities diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index c520cd504c..3e0588631a 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -790,15 +790,12 @@ sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo) void sc_pkcs15_free_app(struct sc_pkcs15_card *p15card) { - if (!p15card || !p15card->app) - return; - - if (p15card->app->label) + if (p15card && p15card->app) { free(p15card->app->label); - if (p15card->app->ddo.value) free(p15card->app->ddo.value); - free(p15card->app); - p15card->app = NULL; + free(p15card->app); + p15card->app = NULL; + } } From 88175e35d313c72f945ee4c6c68600915a6d7d79 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 29 Jan 2018 22:14:53 +0100 Subject: [PATCH 0169/4321] PIV: use better long name --- src/libopensc/card-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d3122ac1e1..1ae90e760e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -388,7 +388,7 @@ static const struct piv_object piv_objects[] = { static struct sc_card_operations piv_ops; static struct sc_card_driver piv_drv = { - "PIV-II for multiple cards", + "Personal Identity Verification Card", "PIV-II", &piv_ops, NULL, 0, NULL @@ -3030,7 +3030,7 @@ static int piv_init(sc_card_t *card) card->max_send_size, card->max_recv_size, card->type); card->cla = 0x00; if(card->name == NULL) - card->name = "PIV-II card"; + card->name = card->driver->name; /* * Set card_issues based on card type either set by piv_match_card or by opensc.conf From 36894c87cf8aa5cce28f71cc6715e8749c88a422 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 7 Feb 2018 12:00:09 +0100 Subject: [PATCH 0170/4321] sc-hsm: fixed accessing version info (#1252) fixes https://github.com/OpenSC/OpenSC/issues/1244 --- src/libopensc/card-sc-hsm.c | 11 +++++++---- src/libopensc/pkcs15-sc-hsm.c | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 22c33858b4..e2af52b942 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1610,14 +1610,17 @@ static int sc_hsm_init(struct sc_card *card) sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS - && file && file->prop_attr && file->prop_attr_len >= 5) { + && file && file->prop_attr && file->prop_attr_len >= 2) { static char card_name[SC_MAX_APDU_BUFFER_SIZE]; - u8 type = file->prop_attr[2]; - u8 major = file->prop_attr[3]; - u8 minor = file->prop_attr[4]; + u8 type = 0xFF; + u8 major = file->prop_attr[file->prop_attr_len - 2]; + u8 minor = file->prop_attr[file->prop_attr_len - 1]; char p00[] = "SmartCard-HSM Applet for JCOP"; char p01[] = "SmartCard-HSM Demo Applet for JCOP"; char *p = "SmartCard-HSM"; + if (file->prop_attr_len >= 3) { + type = file->prop_attr[file->prop_attr_len - 3]; + } switch (type) { case 0x00: p = p00; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 0a7d4c2db3..5fbc910945 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -821,8 +821,10 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) p15card->card->version.hw_major = 24; /* JCOP 2.4.1r3 */ p15card->card->version.hw_minor = 13; - p15card->card->version.fw_major = file->prop_attr[file->prop_attr_len - 2]; - p15card->card->version.fw_minor = file->prop_attr[file->prop_attr_len - 1]; + if (file && file->prop_attr && file->prop_attr_len >= 2) { + p15card->card->version.fw_major = file->prop_attr[file->prop_attr_len - 2]; + p15card->card->version.fw_minor = file->prop_attr[file->prop_attr_len - 1]; + } sc_file_free(file); From 50a35c1bae057230e8e508ad1a5104574d115481 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 7 Feb 2018 16:40:03 +0100 Subject: [PATCH 0171/4321] OpenPGP: Workaround for change in Extended Capabilities The maximum length for sending and receiving data can now be found in DO 7F66. For now, we just use the default values for short/extended length capabiliites. --- src/libopensc/card-openpgp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fb6ae52681..767969437d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -575,9 +575,12 @@ pgp_get_card_features(sc_card_t *card) priv->max_challenge_size = bebytes2ushort(blob->data + 2); /* max. cert size it at bytes 5-6 */ priv->max_cert_size = bebytes2ushort(blob->data + 4); - /* max. send/receive sizes are at bytes 7-8 resp. 9-10 */ - card->max_send_size = bebytes2ushort(blob->data + 6); - card->max_recv_size = bebytes2ushort(blob->data + 8); + if (priv->bcd_version < OPENPGP_CARD_3_0) { + /* max. send/receive sizes are at bytes 7-8 resp. 9-10 */ + card->max_send_size = bebytes2ushort(blob->data + 6); + card->max_recv_size = bebytes2ushort(blob->data + 8); + } + /* TODO read Extended length information from DO 7F66 in OpenPGP 3.0 and later */ } } From 8ee2c61932382b938bc8a65f50422bd967c8e769 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 7 Feb 2018 16:41:52 +0100 Subject: [PATCH 0172/4321] Return SC_SUCCESS in openpgp_card_reader_lock_obtained prevents locking the card forever in case of a problem --- src/libopensc/card-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 767969437d..b34493dbc7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2890,6 +2890,7 @@ static int pgp_card_reader_lock_obtained(sc_card_t *card, int was_reset) /* reselect is required */ was_reset = 1; } + r = SC_SUCCESS; } if (was_reset > 0) { From 6843ab41904397dd2905735bfc8b6f828f0faf7a Mon Sep 17 00:00:00 2001 From: Mardalemer <35370670+Mardalemer@users.noreply.github.com> Date: Tue, 13 Feb 2018 15:24:28 +0300 Subject: [PATCH 0173/4321] pkcs15init: Fix rutokenS FCP parsing (#1259) RutokenS returns data with little endian byte order, due to this fact token wouldn't work with standard function. So function for parsing fcp from little endian data was inplemented. --- src/libopensc/card-rutoken.c | 39 ++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 6c71070360..c1331ee913 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -358,7 +358,6 @@ static int rutoken_select_file(sc_card_t *card, u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; sc_file_t *file = NULL; size_t pathlen; - u8 t0, t1; int ret; assert(card && card->ctx); @@ -428,15 +427,6 @@ static int rutoken_select_file(sc_card_t *card, if (apdu.resplen > 1 && apdu.resplen >= (size_t)apdu.resp[1] + 2) { ret = card->ops->process_fci(card, file, apdu.resp+2, apdu.resp[1]); - if (ret == SC_SUCCESS) - { - t0 = file->id & 0xFF; - t1 = (file->id >> 8) & 0xFF; - file->id = (t0 << 8) | t1; - t0 = file->size & 0xFF; - t1 = (file->size >> 8) & 0xFF; - file->size = (t0 << 8) | t1; - } } if (file->sec_attr && file->sec_attr_len == sizeof(sc_SecAttrV2_t)) set_acl_from_sec_attr(card, file); @@ -452,6 +442,33 @@ static int rutoken_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); } +static int rutoken_process_fci(struct sc_card *card, sc_file_t *file, + const unsigned char *buf, size_t buflen) +{ + size_t taglen; + int ret; + const unsigned char *tag; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + ret = iso_ops->process_fci(card, file, buf, buflen); + if (ret == SC_SUCCESS) + { + /* Rutoken S returns buffers in little-endian. */ + /* Set correct file id. */ + file->id = ((file->id & 0xFF) << 8) | ((file->id >> 8) & 0xFF); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " file identifier: 0x%04X", file->id); + /* Determine file size. */ + tag = sc_asn1_find_tag(card->ctx, buf, buflen, 0x80, &taglen); + /* Rutoken S always returns 2 bytes. */ + if (tag != NULL && taglen == 2) + { + file->size = (tag[1] << 8) | tag[0]; + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); + } + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); +} + static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, u8 *out, size_t *outlen) { @@ -1286,7 +1303,7 @@ static struct sc_card_driver* get_rutoken_driver(void) rutoken_ops.list_files = rutoken_list_files; rutoken_ops.check_sw = rutoken_check_sw; rutoken_ops.card_ctl = rutoken_card_ctl; - /* process_fci */ + rutoken_ops.process_fci = rutoken_process_fci; rutoken_ops.construct_fci = rutoken_construct_fci; rutoken_ops.pin_cmd = NULL; From f86206061495b31e5e5b4a84fe5f5f051f650f2e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Jan 2018 23:30:51 +0100 Subject: [PATCH 0174/4321] EAC: Clearify naming of functions and data Use names that are specific to EAC, not the German ID card (nPA), because Protocol and Commands are defined by BSI TR-03110 and ICAO. Functions that are nPA specific are moved to card-npa.h. --- src/libopensc/card-npa.c | 93 +++++- src/libopensc/card-npa.h | 39 +++ src/libopensc/libopensc.exports | 6 +- src/libopensc/reader-tr03119.c | 43 +-- src/libopensc/reader-tr03119.h | 56 +++- src/sm/sm-eac.c | 494 +++++++++++++------------------- src/sm/sm-eac.h | 128 ++------- src/tools/npa-tool.c | 29 +- src/tools/sceac-example.c | 1 + 9 files changed, 447 insertions(+), 442 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 2de14d29ec..457c4aac51 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -1,7 +1,7 @@ /* * card-npa.c: Recognize known German identity cards * - * Copyright (C) 2011-2015 Frank Morgner + * Copyright (C) 2011-2018 Frank Morgner * * This file is part of OpenSC. * @@ -291,9 +291,9 @@ static int npa_unlock_esign(sc_card_t *card) } /* FIXME set flags with opensc.conf */ - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_ALL; - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_TA; - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_CA; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA; /* FIXME show an alert to the user if can == NULL */ r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); @@ -451,7 +451,7 @@ static int npa_pin_cmd_get_info(struct sc_card *card, /* usually 10 tries */ *tries_left = 10; data->pin1.max_tries = 10; - r = npa_pace_get_tries_left(card, + r = eac_pace_get_tries_left(card, pin_reference, tries_left); data->pin1.tries_left = *tries_left; break; @@ -460,7 +460,7 @@ static int npa_pin_cmd_get_info(struct sc_card *card, /* usually 3 tries */ *tries_left = 3; data->pin1.max_tries = 3; - r = npa_pace_get_tries_left(card, + r = eac_pace_get_tries_left(card, pin_reference, tries_left); data->pin1.tries_left = *tries_left; break; @@ -511,10 +511,10 @@ static int npa_pace_verify(struct sc_card *card, && r != SC_SUCCESS && pace_output.mse_set_at_sw1 == 0x63 && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0 - && (pace_output.mse_set_at_sw2 & 0x0f) <= UC_PIN_SUSPENDED) { + && (pace_output.mse_set_at_sw2 & 0x0f) <= EAC_UC_PIN_SUSPENDED) { /* TODO ask for user consent when automatically resuming the PIN */ sc_log(card->ctx, "%s is suspended. Will try to resume it with %s.\n", - npa_secret_name(pin_reference), npa_secret_name(PACE_PIN_ID_CAN)); + eac_secret_name(pin_reference), eac_secret_name(PACE_PIN_ID_CAN)); pace_input.pin_id = PACE_PIN_ID_CAN; pace_input.pin = NULL; @@ -532,9 +532,9 @@ static int npa_pace_verify(struct sc_card *card, r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); if (r == SC_SUCCESS) { - sc_log(card->ctx, "%s resumed.\n", npa_secret_name(pin_reference)); + sc_log(card->ctx, "%s resumed.\n", eac_secret_name(pin_reference)); if (tries_left) { - *tries_left = MAX_PIN_TRIES; + *tries_left = EAC_MAX_PIN_TRIES; } } else { if (tries_left) { @@ -552,10 +552,10 @@ static int npa_pace_verify(struct sc_card *card, if (pin_reference == PACE_PIN_ID_PIN && tries_left) { if (*tries_left == 0) { sc_log(card->ctx, "%s is suspended and must be resumed.\n", - npa_secret_name(pin_reference)); + eac_secret_name(pin_reference)); } else if (*tries_left == 1) { sc_log(card->ctx, "%s is blocked and must be unblocked.\n", - npa_secret_name(pin_reference)); + eac_secret_name(pin_reference)); } } @@ -586,6 +586,75 @@ static int npa_standard_pin_cmd(struct sc_card *card, return r; } +int +npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, + int ask_for_secret, const char *new, size_t new_len) +{ + sc_apdu_t apdu; + char *p = NULL; + int r; + + if (ask_for_secret && (!new || !new_len)) { + if (!(SC_READER_CAP_PIN_PAD & card->reader->capabilities)) { +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + p = malloc(EAC_MAX_PIN_LEN+1); + if (!p) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for new PIN.\n"); + return SC_ERROR_OUT_OF_MEMORY; + } + if (0 > EVP_read_pw_string_min(p, + EAC_MIN_PIN_LEN, EAC_MAX_PIN_LEN+1, + "Please enter your new PIN: ", 0)) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n"); + free(p); + return SC_ERROR_INTERNAL; + } + new_len = strlen(p); + if (new_len > EAC_MAX_PIN_LEN) + return SC_ERROR_INVALID_PIN_LENGTH; + new = p; +#else + return SC_ERROR_NOT_SUPPORTED; +#endif + } + } + + sc_format_apdu(card, &apdu, 0, 0x2C, 0, pin_id); + apdu.data = (u8 *) new; + apdu.datalen = new_len; + apdu.lc = apdu.datalen; + + if (new_len || ask_for_secret) { + apdu.p1 = 0x02; + apdu.cse = SC_APDU_CASE_3_SHORT; + } else { + apdu.p1 = 0x03; + apdu.cse = SC_APDU_CASE_1; + } + + if (ask_for_secret && !new_len) { + struct sc_pin_cmd_data data; + data.apdu = &apdu; + data.cmd = SC_PIN_CMD_CHANGE; + data.flags = SC_PIN_CMD_IMPLICIT_CHANGE; + data.pin2.encoding = SC_PIN_ENCODING_ASCII; + data.pin2.length_offset = 0; + data.pin2.offset = 5; + data.pin2.max_length = EAC_MAX_PIN_LEN; + data.pin2.min_length = EAC_MIN_PIN_LEN; + data.pin2.pad_length = 0; + r = card->reader->ops->perform_verify(card->reader, &data); + } else + r = sc_transmit_apdu(card, &apdu); + + if (p) { + sc_mem_clear(p, new_len); + free(p); + } + + return r; +} + static int npa_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) { diff --git a/src/libopensc/card-npa.h b/src/libopensc/card-npa.h index eca8516771..5cac5b0a66 100644 --- a/src/libopensc/card-npa.h +++ b/src/libopensc/card-npa.h @@ -25,6 +25,8 @@ extern "C" { #endif +#include "sm/sm-eac.h" + const unsigned char esign_chat[] = { 0x7F, 0x4C, 0x0E, 0x06, 0x09, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x03, 0x01, 0x02, 0x03, @@ -33,6 +35,43 @@ const unsigned char esign_chat[] = { const unsigned char df_esign_aid[] = { 0xa0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4e}; +/** + * @brief Sends a reset retry counter APDU + * + * According to TR-03110 the reset retry counter APDU is used to set a new PIN + * or to reset the retry counter of the PIN. The standard requires this + * operation to be authorized either by an established PACE channel or by the + * effective authorization of the terminal's certificate. + * + * @param[in] card + * @param[in] pin_id Type of secret (usually PIN or CAN). You may use enum s_type from \c . + * @param[in] ask_for_secret whether to ask the user for the secret (\c 1) or not (\c 0) + * @param[in] new (optional) new secret + * @param[in] new_len (optional) length of \a new + * + * @return \c SC_SUCCESS or error code if an error occurred + */ +int npa_reset_retry_counter(sc_card_t *card, + enum s_type pin_id, int ask_for_secret, + const char *new, size_t new_len); + +/** + * @brief Send APDU to unblock the PIN + * + * @param[in] card + */ +#define npa_unblock_pin(card) \ + npa_reset_retry_counter(card, PACE_PIN, 0, NULL, 0) +/** + * @brief Send APDU to set a new PIN + * + * @param[in] card + * @param[in] newp (optional) new PIN + * @param[in] newplen (optional) length of \a new + */ +#define npa_change_pin(card, newp, newplen) \ + npa_reset_retry_counter(card, PACE_PIN, 1, newp, newplen) + #ifdef __cplusplus } #endif diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index f7385245df..44ef561950 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -350,14 +350,14 @@ _sc_card_add_ec_alg _sc_card_add_rsa_alg _sc_match_atr _sc_log -npa_secret_name +eac_secret_name get_pace_capabilities perform_pace perform_terminal_authentication perform_chip_authentication -npa_default_flags +eac_default_flags +eac_pace_get_tries_left npa_reset_retry_counter -npa_pace_get_tries_left escape_pace_input_to_buf escape_buf_to_pace_input escape_pace_output_to_buf diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index a62deca28d..ed2eacb142 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -1,7 +1,7 @@ /* * reader-escape.c: implementation related to escape commands with pseudo APDUs * - * Copyright (C) 2013-2015 Frank Morgner + * Copyright (C) 2013-2018 Frank Morgner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,20 +43,31 @@ #include #endif -static const u8 escape_cla = 0xff; -static const u8 escape_ins = 0x9a; +int get_pace_capabilities(u8 *bitmap) +{ + if (!bitmap) + return SC_ERROR_INVALID_ARGUMENTS; + + /* BitMap */ + *bitmap = EAC_BITMAP_PACE|EAC_BITMAP_EID|EAC_BITMAP_ESIGN; + + return SC_SUCCESS; +} + +const u8 escape_cla = 0xff; +const u8 escape_ins = 0x9a; -static const u8 escape_p1_PIN = 0x04; -static const u8 escape_p2_GetReaderPACECapabilities = 0x01; -static const u8 escape_p2_EstablishPACEChannel = 0x02; -/*static const u8 escape_p2_DestroyPACEChannel = 0x03;*/ -static const u8 escape_p2_PC_to_RDR_Secure = 0x10; +const u8 escape_p1_PIN = 0x04; +const u8 escape_p2_GetReaderPACECapabilities = 0x01; +const u8 escape_p2_EstablishPACEChannel = 0x02; +/*const u8 escape_p2_DestroyPACEChannel = 0x03;*/ +const u8 escape_p2_PC_to_RDR_Secure = 0x10; -static const u8 escape_p1_IFD = 0x01; -static const u8 escape_p2_vendor = 0x01; -/*static const u8 escape_p2_product = 0x03;*/ -static const u8 escape_p2_version_firmware = 0x06; -/*static const u8 escape_p2_version_driver = 0x07;*/ +const u8 escape_p1_IFD = 0x01; +const u8 escape_p2_vendor = 0x01; +/*const u8 escape_p2_product = 0x03;*/ +const u8 escape_p2_version_firmware = 0x06; +/*const u8 escape_p2_version_driver = 0x07;*/ struct sc_asn1_entry g_boolean[] = { { "boolean", @@ -79,7 +90,7 @@ struct sc_asn1_entry g_numeric_string_as_octet_string[] = { { NULL , 0 , 0 , 0 , NULL , NULL } }; -static const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = { +const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = { { "passwordID", /* use an OCTET STRING to avoid a conversion to int */ SC_ASN1_STRUCT, SC_ASN1_CTX|0x01|SC_ASN1_CONS, 0, NULL, NULL }, @@ -94,7 +105,7 @@ static const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = { SC_ASN1_STRUCT, SC_ASN1_CTX|0x05|SC_ASN1_CONS, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, { NULL , 0 , 0 , 0 , NULL , NULL } }; -static const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = { +const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = { { "errorCode", SC_ASN1_STRUCT, SC_ASN1_CTX|0x01|SC_ASN1_CONS, 0, NULL, NULL }, { "statusMSESetAT", @@ -109,7 +120,7 @@ static const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = { SC_ASN1_STRUCT, SC_ASN1_CTX|0x06|SC_ASN1_CONS, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, { NULL , 0 , 0 , 0 , NULL , NULL } }; -static const struct sc_asn1_entry g_EstablishPACEChannel[] = { +const struct sc_asn1_entry g_EstablishPACEChannel[] = { { "EstablishPACEChannel", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE|SC_ASN1_CONS, 0, NULL, NULL }, { NULL , 0 , 0 , 0 , NULL , NULL } diff --git a/src/libopensc/reader-tr03119.h b/src/libopensc/reader-tr03119.h index 089074fb97..d8f60a2034 100644 --- a/src/libopensc/reader-tr03119.h +++ b/src/libopensc/reader-tr03119.h @@ -1,7 +1,7 @@ /* * reader-tr03119.h: interface related to escape commands with pseudo APDUs * - * Copyright (C) 2013-2015 Frank Morgner + * Copyright (C) 2013-2018 Frank Morgner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,60 @@ extern "C" { #endif +/** @brief NPA capabilities (TR-03119): PACE */ +#define EAC_BITMAP_PACE 0x40 +/** @brief NPA capabilities (TR-03119): EPA: eID */ +#define EAC_BITMAP_EID 0x20 +/** @brief NPA capabilities (TR-03119): EPA: eSign */ +#define EAC_BITMAP_ESIGN 0x10 + +/** + * @brief Get the PACE capabilities + * + * @param[in,out] bitmap where to store capabilities bitmap + * @note Since this code offers no support for terminal certificate, the bitmap is always \c PACE_BITMAP_PACE|PACE_BITMAP_EID + * + * @return \c SC_SUCCESS or error code if an error occurred + */ +int get_pace_capabilities(u8 *bitmap); + +/** @brief NPA result (TR-03119): Kein Fehler */ +#define EAC_SUCCESS 0x00000000 +/** @brief NPA result (TR-03119): Längen im Input sind inkonsistent */ +#define EAC_ERROR_LENGTH_INCONSISTENT 0xD0000001 +/** @brief NPA result (TR-03119): Unerwartete Daten im Input */ +#define EAC_ERROR_UNEXPECTED_DATA 0xD0000002 +/** @brief NPA result (TR-03119): Unerwartete Kombination von Daten im Input */ +#define EAC_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003 +/** @brief NPA result (TR-03119): Die Karte unterstützt das PACE – Verfahren nicht. (Unerwartete Struktur in Antwortdaten der Karte) */ +#define EAC_ERROR_CARD_NOT_SUPPORTED 0xE0000001 +/** @brief NPA result (TR-03119): Der Kartenleser unterstützt den angeforderten bzw. den ermittelten Algorithmus nicht. */ +#define EAC_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002 +/** @brief NPA result (TR-03119): Der Kartenleser kennt die PIN – ID nicht. */ +#define EAC_ERROR_PINID_NOT_SUPPORTED 0xE0000003 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Select EF_CardAccess (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_SELECT_EF_CARDACCESS 0xF0000000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Read Binary (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_READ_BINARY 0xF0010000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf MSE: Set AT (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_MSE_SET_AT 0xF0020000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 1 (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 2 (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 3 (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000 +/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 4 (needs to be OR-ed with SW1|SW2) */ +#define EAC_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000 +/** @brief NPA result (TR-03119): Kommunikationsabbruch mit Karte. */ +#define EAC_ERROR_COMMUNICATION 0xF0100001 +/** @brief NPA result (TR-03119): Keine Karte im Feld. */ +#define EAC_ERROR_NO_CARD 0xF0100002 +/** @brief NPA result (TR-03119): Benutzerabbruch. */ +#define EAC_ERROR_ABORTED 0xF0200001 +/** @brief NPA result (TR-03119): Benutzer – Timeout */ +#define EAC_ERROR_TIMEOUT 0xF0200002 + void sc_detect_escape_cmds(sc_reader_t *reader); int escape_pace_input_to_buf(sc_context_t *ctx, diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 3be597241e..d789a51572 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2015 Frank Morgner + * Copyright (C) 2011-2018 Frank Morgner * * This file is part of OpenSC. * @@ -34,7 +34,7 @@ #include #endif -char npa_default_flags = 0; +char eac_default_flags = 0; #define ISO_MSE 0x22 #if defined(ENABLE_OPENPACE) @@ -70,46 +70,46 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) * MSE:Set AT */ -typedef struct npa_mse_cd_st { +typedef struct { ASN1_OBJECT *cryptographic_mechanism_reference; ASN1_OCTET_STRING *key_reference1; ASN1_OCTET_STRING *key_reference2; ASN1_OCTET_STRING *eph_pub_key; ASN1_AUXILIARY_DATA *auxiliary_data; CVC_CHAT *chat; -} NPA_MSE_C; +} EAC_MSE_C; /* Note that we can not use ASN1_AUXILIARY_DATA for the auxiliary_data element * here. Due to limitations of OpenSSL it is not possible to *encode* an * optional item template (such as auxiliary_data) in an other item template * (such as ASN1_AUXILIARY_DATA). However, we can do * - * NPA_MSE_C->auxiliary_data = d2i_ASN1_AUXILIARY_DATA(...) + * EAC_MSE_C->auxiliary_data = d2i_ASN1_AUXILIARY_DATA(...) * * because they both use the same underlying struct. * * See also openssl/crypto/asn1/tasn_dec.c:183 */ -ASN1_SEQUENCE(NPA_MSE_C) = { +ASN1_SEQUENCE(EAC_MSE_C) = { /* 0x80 * Cryptographic mechanism reference */ - ASN1_IMP_OPT(NPA_MSE_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0), + ASN1_IMP_OPT(EAC_MSE_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0), /* 0x83 * Reference of a public key / secret key */ - ASN1_IMP_OPT(NPA_MSE_C, key_reference1, ASN1_OCTET_STRING, 3), + ASN1_IMP_OPT(EAC_MSE_C, key_reference1, ASN1_OCTET_STRING, 3), /* 0x84 * Reference of a private key / Reference for computing a session key */ - ASN1_IMP_OPT(NPA_MSE_C, key_reference2, ASN1_OCTET_STRING, 4), + ASN1_IMP_OPT(EAC_MSE_C, key_reference2, ASN1_OCTET_STRING, 4), /* 0x91 * Ephemeral Public Key */ - ASN1_IMP_OPT(NPA_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11), + ASN1_IMP_OPT(EAC_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11), /* 0x67 * Auxiliary authenticated data. See note above. */ - ASN1_APP_IMP_SEQUENCE_OF_OPT(NPA_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATE, 7), + ASN1_APP_IMP_SEQUENCE_OF_OPT(EAC_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATE, 7), /* Certificate Holder Authorization Template */ - ASN1_OPT(NPA_MSE_C, chat, CVC_CHAT), -} ASN1_SEQUENCE_END(NPA_MSE_C) -DECLARE_ASN1_FUNCTIONS(NPA_MSE_C) -IMPLEMENT_ASN1_FUNCTIONS(NPA_MSE_C) + ASN1_OPT(EAC_MSE_C, chat, CVC_CHAT), +} ASN1_SEQUENCE_END(EAC_MSE_C) +DECLARE_ASN1_FUNCTIONS(EAC_MSE_C) +IMPLEMENT_ASN1_FUNCTIONS(EAC_MSE_C) /* @@ -117,78 +117,78 @@ IMPLEMENT_ASN1_FUNCTIONS(NPA_MSE_C) */ /* Protocol Command Data */ -typedef struct npa_gen_auth_pace_cd_st { +typedef struct { ASN1_OCTET_STRING *mapping_data; ASN1_OCTET_STRING *eph_pub_key; ASN1_OCTET_STRING *auth_token; -} NPA_GEN_AUTH_PACE_C_BODY; -ASN1_SEQUENCE(NPA_GEN_AUTH_PACE_C_BODY) = { +} EAC_GEN_AUTH_PACE_C_BODY; +ASN1_SEQUENCE(EAC_GEN_AUTH_PACE_C_BODY) = { /* 0x81 * Mapping Data */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_C_BODY, mapping_data, ASN1_OCTET_STRING, 1), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, mapping_data, ASN1_OCTET_STRING, 1), /* 0x83 * Ephemeral Public Key */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 3), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 3), /* 0x85 * Authentication Token */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_C_BODY, auth_token, ASN1_OCTET_STRING, 5), -} ASN1_SEQUENCE_END(NPA_GEN_AUTH_PACE_C_BODY) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_C_BODY) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_C_BODY) + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, auth_token, ASN1_OCTET_STRING, 5), +} ASN1_SEQUENCE_END(EAC_GEN_AUTH_PACE_C_BODY) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C_BODY) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C_BODY) -typedef NPA_GEN_AUTH_PACE_C_BODY NPA_GEN_AUTH_PACE_C; +typedef EAC_GEN_AUTH_PACE_C_BODY EAC_GEN_AUTH_PACE_C; /* 0x7C * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(NPA_GEN_AUTH_PACE_C) = +ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_PACE_C) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, NPA_GEN_AUTH_PACE_C, NPA_GEN_AUTH_PACE_C_BODY) -ASN1_ITEM_TEMPLATE_END(NPA_GEN_AUTH_PACE_C) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_C) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_C) + 0x1c, EAC_GEN_AUTH_PACE_C, EAC_GEN_AUTH_PACE_C_BODY) +ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_PACE_C) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C) /* Protocol Response Data */ -typedef struct npa_gen_auth_pace_rapdu_body_st { +typedef struct { ASN1_OCTET_STRING *enc_nonce; ASN1_OCTET_STRING *mapping_data; ASN1_OCTET_STRING *eph_pub_key; ASN1_OCTET_STRING *auth_token; ASN1_OCTET_STRING *cur_car; ASN1_OCTET_STRING *prev_car; -} NPA_GEN_AUTH_PACE_R_BODY; -ASN1_SEQUENCE(NPA_GEN_AUTH_PACE_R_BODY) = { +} EAC_GEN_AUTH_PACE_R_BODY; +ASN1_SEQUENCE(EAC_GEN_AUTH_PACE_R_BODY) = { /* 0x80 * Encrypted Nonce */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, enc_nonce, ASN1_OCTET_STRING, 0), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, enc_nonce, ASN1_OCTET_STRING, 0), /* 0x82 * Mapping Data */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, mapping_data, ASN1_OCTET_STRING, 2), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, mapping_data, ASN1_OCTET_STRING, 2), /* 0x84 * Ephemeral Public Key */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, eph_pub_key, ASN1_OCTET_STRING, 4), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, eph_pub_key, ASN1_OCTET_STRING, 4), /* 0x86 * Authentication Token */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, auth_token, ASN1_OCTET_STRING, 6), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, auth_token, ASN1_OCTET_STRING, 6), /* 0x87 * Most recent Certification Authority Reference */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, cur_car, ASN1_OCTET_STRING, 7), + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, cur_car, ASN1_OCTET_STRING, 7), /* 0x88 * Previous Certification Authority Reference */ - ASN1_IMP_OPT(NPA_GEN_AUTH_PACE_R_BODY, prev_car, ASN1_OCTET_STRING, 8), -} ASN1_SEQUENCE_END(NPA_GEN_AUTH_PACE_R_BODY) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_R_BODY) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_R_BODY) + ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, prev_car, ASN1_OCTET_STRING, 8), +} ASN1_SEQUENCE_END(EAC_GEN_AUTH_PACE_R_BODY) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R_BODY) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R_BODY) -typedef NPA_GEN_AUTH_PACE_R_BODY NPA_GEN_AUTH_PACE_R; +typedef EAC_GEN_AUTH_PACE_R_BODY EAC_GEN_AUTH_PACE_R; /* 0x7C * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(NPA_GEN_AUTH_PACE_R) = +ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_PACE_R) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, NPA_GEN_AUTH_PACE_R, NPA_GEN_AUTH_PACE_R_BODY) -ASN1_ITEM_TEMPLATE_END(NPA_GEN_AUTH_PACE_R) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_R) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_R) + 0x1c, EAC_GEN_AUTH_PACE_R, EAC_GEN_AUTH_PACE_R_BODY) +ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_PACE_R) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R) /* @@ -196,61 +196,61 @@ IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_PACE_R) */ /* Protocol Command Data */ -typedef struct npa_gen_auth_ca_cd_st { +typedef struct eac_gen_auth_ca_cd_st { ASN1_OCTET_STRING *eph_pub_key; -} NPA_GEN_AUTH_CA_C_BODY; -ASN1_SEQUENCE(NPA_GEN_AUTH_CA_C_BODY) = { +} EAC_GEN_AUTH_CA_C_BODY; +ASN1_SEQUENCE(EAC_GEN_AUTH_CA_C_BODY) = { /* 0x80 * Ephemeral Public Key */ - ASN1_IMP_OPT(NPA_GEN_AUTH_CA_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 0), -} ASN1_SEQUENCE_END(NPA_GEN_AUTH_CA_C_BODY) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_C_BODY) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_C_BODY) + ASN1_IMP_OPT(EAC_GEN_AUTH_CA_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 0), +} ASN1_SEQUENCE_END(EAC_GEN_AUTH_CA_C_BODY) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C_BODY) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C_BODY) -typedef NPA_GEN_AUTH_CA_C_BODY NPA_GEN_AUTH_CA_C; +typedef EAC_GEN_AUTH_CA_C_BODY EAC_GEN_AUTH_CA_C; /* 0x7C * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(NPA_GEN_AUTH_CA_C) = +ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_CA_C) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, NPA_GEN_AUTH_CA_C, NPA_GEN_AUTH_CA_C_BODY) -ASN1_ITEM_TEMPLATE_END(NPA_GEN_AUTH_CA_C) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_C) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_C) + 0x1c, EAC_GEN_AUTH_CA_C, EAC_GEN_AUTH_CA_C_BODY) +ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_CA_C) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C) /* Protocol Response Data */ -typedef struct npa_gen_auth_ca_rapdu_body_st { +typedef struct eac_gen_auth_ca_rapdu_body_st { ASN1_OCTET_STRING *nonce; ASN1_OCTET_STRING *auth_token; -} NPA_GEN_AUTH_CA_R_BODY; -ASN1_SEQUENCE(NPA_GEN_AUTH_CA_R_BODY) = { +} EAC_GEN_AUTH_CA_R_BODY; +ASN1_SEQUENCE(EAC_GEN_AUTH_CA_R_BODY) = { /* 0x81 * Nonce */ - ASN1_IMP_OPT(NPA_GEN_AUTH_CA_R_BODY, nonce, ASN1_OCTET_STRING, 1), + ASN1_IMP_OPT(EAC_GEN_AUTH_CA_R_BODY, nonce, ASN1_OCTET_STRING, 1), /* 0x82 * Authentication Token */ - ASN1_IMP_OPT(NPA_GEN_AUTH_CA_R_BODY, auth_token, ASN1_OCTET_STRING, 2), -} ASN1_SEQUENCE_END(NPA_GEN_AUTH_CA_R_BODY) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_R_BODY) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_R_BODY) + ASN1_IMP_OPT(EAC_GEN_AUTH_CA_R_BODY, auth_token, ASN1_OCTET_STRING, 2), +} ASN1_SEQUENCE_END(EAC_GEN_AUTH_CA_R_BODY) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R_BODY) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R_BODY) -typedef NPA_GEN_AUTH_CA_R_BODY NPA_GEN_AUTH_CA_R; +typedef EAC_GEN_AUTH_CA_R_BODY EAC_GEN_AUTH_CA_R; /* 0x7C * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(NPA_GEN_AUTH_CA_R) = +ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_CA_R) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, NPA_GEN_AUTH_CA_R, NPA_GEN_AUTH_CA_R_BODY) -ASN1_ITEM_TEMPLATE_END(NPA_GEN_AUTH_CA_R) -DECLARE_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_R) -IMPLEMENT_ASN1_FUNCTIONS(NPA_GEN_AUTH_CA_R) + 0x1c, EAC_GEN_AUTH_CA_R, EAC_GEN_AUTH_CA_R_BODY) +ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_CA_R) +DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R) +IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R) #define maxresp SC_MAX_APDU_BUFFER_SIZE - 2 /** @brief NPA secure messaging context */ -struct npa_sm_ctx { +struct eac_sm_ctx { /** @brief EAC context */ EAC_CTX *ctx; /** @brief Certificate Description given on initialization of PACE */ @@ -270,32 +270,32 @@ extern BUF_MEM *BUF_MEM_create(size_t len); extern BUF_MEM *BUF_MEM_create_init(const void *buf, size_t len); -static int npa_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, u8 **enc); -static int npa_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *enc, size_t enclen, u8 **data); -static int npa_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, u8 **outdata); -static int npa_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *mac, size_t maclen, const u8 *macdata, size_t macdatalen); -static int npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu); -static int npa_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu); -static int npa_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, +static int eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu); -static void npa_sm_clear_free(const struct iso_sm_ctx *ctx); +static void eac_sm_clear_free(const struct iso_sm_ctx *ctx); -static struct npa_sm_ctx * -npa_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, +static struct eac_sm_ctx * +eac_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, size_t certificate_description_length, const unsigned char *id_icc, size_t id_icc_length) { - struct npa_sm_ctx *out = malloc(sizeof *out); + struct eac_sm_ctx *out = malloc(sizeof *out); if (!out) goto err; @@ -320,10 +320,10 @@ npa_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, out->eph_pub_key = NULL; out->auxiliary_data = NULL; - out->flags = npa_default_flags; - if (out->flags & NPA_FLAG_DISABLE_CHECK_TA) + out->flags = eac_default_flags; + if (out->flags & EAC_FLAG_DISABLE_CHECK_TA) TA_disable_checks(out->ctx); - if (out->flags & NPA_FLAG_DISABLE_CHECK_CA) + if (out->flags & EAC_FLAG_DISABLE_CHECK_CA) CA_disable_passive_authentication(out->ctx); return out; @@ -334,7 +334,7 @@ npa_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, } static int -npa_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, +eac_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, const unsigned char *certificate_description, size_t certificate_description_length, const unsigned char *id_icc, size_t id_icc_length) @@ -353,7 +353,7 @@ npa_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, goto err; } - sctx->priv_data = npa_sm_ctx_create(eac_ctx, + sctx->priv_data = eac_sm_ctx_create(eac_ctx, certificate_description, certificate_description_length, id_icc, id_icc_length); if (!sctx->priv_data) { @@ -361,14 +361,14 @@ npa_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, goto err; } - sctx->authenticate = npa_sm_authenticate; - sctx->encrypt = npa_sm_encrypt; - sctx->decrypt = npa_sm_decrypt; - sctx->verify_authentication = npa_sm_verify_authentication; - sctx->pre_transmit = npa_sm_pre_transmit; - sctx->post_transmit = npa_sm_post_transmit; - sctx->finish = npa_sm_finish; - sctx->clear_free = npa_sm_clear_free; + sctx->authenticate = eac_sm_authenticate; + sctx->encrypt = eac_sm_encrypt; + sctx->decrypt = eac_sm_decrypt; + sctx->verify_authentication = eac_sm_verify_authentication; + sctx->pre_transmit = eac_sm_pre_transmit; + sctx->post_transmit = eac_sm_post_transmit; + sctx->finish = eac_sm_finish; + sctx->clear_free = eac_sm_clear_free; sctx->padding_indicator = SM_ISO_PADDING; sctx->block_length = EVP_CIPHER_block_size(eac_ctx->key_ctx->cipher); @@ -394,7 +394,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, const unsigned char *auxiliary_data, size_t auxiliary_data_len, const CVC_CHAT *chat, unsigned char **cdata) { - NPA_MSE_C *data = NULL; + EAC_MSE_C *data = NULL; unsigned char *data_sequence = NULL; const unsigned char *data_no_sequence; unsigned char *p; @@ -406,7 +406,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, goto err; } - data = NPA_MSE_C_new(); + data = EAC_MSE_C_new(); if (!data) { ssl_error(ctx); r = SC_ERROR_INTERNAL; @@ -467,7 +467,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, data->chat = (CVC_CHAT *) chat; - length = i2d_NPA_MSE_C(data, &data_sequence); + length = i2d_EAC_MSE_C(data, &data_sequence); data_no_sequence = data_sequence; if (length < 0 || (0x80 & ASN1_get_object(&data_no_sequence, &length, &tag, &class, length))) { @@ -496,14 +496,14 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, if (data) { /* do not free the functions parameter chat */ data->chat = NULL; - NPA_MSE_C_free(data); + EAC_MSE_C_free(data); } OPENSSL_free(data_sequence); return r; } -static int npa_mse(sc_card_t *card, +static int eac_mse(sc_card_t *card, unsigned char p1, unsigned char p2, int protocol, const unsigned char *key_reference1, size_t key_reference1_len, const unsigned char *key_reference2, size_t key_reference2_len, @@ -555,26 +555,26 @@ static int npa_mse(sc_card_t *card, return r; } -static int npa_mse_set_at(sc_card_t *card, unsigned char p1, int protocol, +static int eac_mse_set_at(sc_card_t *card, unsigned char p1, int protocol, const unsigned char *key_reference1, size_t key_reference1_len, const unsigned char *key_reference2, size_t key_reference2_len, const unsigned char *eph_pub_key, size_t eph_pub_key_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len, const CVC_CHAT *chat, u8 *sw1, u8 *sw2) { - return npa_mse(card, p1, 0xA4, protocol, key_reference1, + return eac_mse(card, p1, 0xA4, protocol, key_reference1, key_reference1_len, key_reference2, key_reference2_len, eph_pub_key, eph_pub_key_len, auxiliary_data, auxiliary_data_len, chat, sw1, sw2); } -static int npa_mse_set_at_pace(sc_card_t *card, int protocol, +static int eac_mse_set_at_pace(sc_card_t *card, int protocol, enum s_type secret_key, const CVC_CHAT *chat, u8 *sw1, u8 *sw2) { int r, tries; unsigned char key = secret_key; - r = npa_mse_set_at(card, 0xC1, protocol, &key, sizeof key, NULL, + r = eac_mse_set_at(card, 0xC1, protocol, &key, sizeof key, NULL, 0, NULL, 0, NULL, 0, chat, sw1, sw2); if (0 > r) goto err; @@ -585,7 +585,7 @@ static int npa_mse_set_at_pace(sc_card_t *card, int protocol, if (tries <= 1) { /* this is only a warning... */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Remaining tries: %d (%s must be %s)\n", - tries, npa_secret_name(secret_key), + tries, eac_secret_name(secret_key), tries ? "resumed" : "unblocked"); } r = SC_SUCCESS; @@ -608,12 +608,12 @@ static int npa_mse_set_at_pace(sc_card_t *card, int protocol, #define ISO_GENERAL_AUTHENTICATE 0x86 #define ISO_COMMAND_CHAINING 0x10 -static int npa_gen_auth_1_encrypted_nonce(sc_card_t *card, +static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, u8 **enc_nonce, size_t *enc_nonce_len) { sc_apdu_t apdu; - NPA_GEN_AUTH_PACE_C *c_data = NULL; - NPA_GEN_AUTH_PACE_R *r_data = NULL; + EAC_GEN_AUTH_PACE_C *c_data = NULL; + EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; unsigned char resp[maxresp]; @@ -622,12 +622,12 @@ static int npa_gen_auth_1_encrypted_nonce(sc_card_t *card, 0x00, 0x00); apdu.cla = ISO_COMMAND_CHAINING; - c_data = NPA_GEN_AUTH_PACE_C_new(); + c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - r = i2d_NPA_GEN_AUTH_PACE_C(c_data, &d); + r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); if (r < 0) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -651,7 +651,7 @@ static int npa_gen_auth_1_encrypted_nonce(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen); - if (!d2i_NPA_GEN_AUTH_PACE_R(&r_data, + if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); ssl_error(card->ctx); @@ -684,20 +684,20 @@ static int npa_gen_auth_1_encrypted_nonce(sc_card_t *card, err: if (c_data) - NPA_GEN_AUTH_PACE_C_free(c_data); + EAC_GEN_AUTH_PACE_C_free(c_data); OPENSSL_free(d); if (r_data) - NPA_GEN_AUTH_PACE_R_free(r_data); + EAC_GEN_AUTH_PACE_R_free(r_data); return r; } -static int npa_gen_auth_2_map_nonce(sc_card_t *card, +static int eac_gen_auth_2_map_nonce(sc_card_t *card, const u8 *in, size_t in_len, u8 **map_data_out, size_t *map_data_out_len) { sc_apdu_t apdu; - NPA_GEN_AUTH_PACE_C *c_data = NULL; - NPA_GEN_AUTH_PACE_R *r_data = NULL; + EAC_GEN_AUTH_PACE_C *c_data = NULL; + EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; unsigned char resp[maxresp]; @@ -706,7 +706,7 @@ static int npa_gen_auth_2_map_nonce(sc_card_t *card, 0x00, 0x00); apdu.cla = ISO_COMMAND_CHAINING; - c_data = NPA_GEN_AUTH_PACE_C_new(); + c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; @@ -719,7 +719,7 @@ static int npa_gen_auth_2_map_nonce(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = i2d_NPA_GEN_AUTH_PACE_C(c_data, &d); + r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); if (r < 0) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -743,7 +743,7 @@ static int npa_gen_auth_2_map_nonce(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen); - if (!d2i_NPA_GEN_AUTH_PACE_R(&r_data, + if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); ssl_error(card->ctx); @@ -776,20 +776,20 @@ static int npa_gen_auth_2_map_nonce(sc_card_t *card, err: if (c_data) - NPA_GEN_AUTH_PACE_C_free(c_data); + EAC_GEN_AUTH_PACE_C_free(c_data); OPENSSL_free(d); if (r_data) - NPA_GEN_AUTH_PACE_R_free(r_data); + EAC_GEN_AUTH_PACE_R_free(r_data); return r; } -static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, +static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, const u8 *in, size_t in_len, u8 **eph_pub_key_out, size_t *eph_pub_key_out_len) { sc_apdu_t apdu; - NPA_GEN_AUTH_PACE_C *c_data = NULL; - NPA_GEN_AUTH_PACE_R *r_data = NULL; + EAC_GEN_AUTH_PACE_C *c_data = NULL; + EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; unsigned char resp[maxresp]; @@ -798,7 +798,7 @@ static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, 0x00, 0x00); apdu.cla = ISO_COMMAND_CHAINING; - c_data = NPA_GEN_AUTH_PACE_C_new(); + c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; @@ -811,7 +811,7 @@ static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = i2d_NPA_GEN_AUTH_PACE_C(c_data, &d); + r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); if (r < 0) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -835,7 +835,7 @@ static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - if (!d2i_NPA_GEN_AUTH_PACE_R(&r_data, + if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); ssl_error(card->ctx); @@ -868,22 +868,22 @@ static int npa_gen_auth_3_perform_key_agreement(sc_card_t *card, err: if (c_data) - NPA_GEN_AUTH_PACE_C_free(c_data); + EAC_GEN_AUTH_PACE_C_free(c_data); OPENSSL_free(d); if (r_data) - NPA_GEN_AUTH_PACE_R_free(r_data); + EAC_GEN_AUTH_PACE_R_free(r_data); return r; } -static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, +static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, const u8 *in, size_t in_len, u8 **auth_token_out, size_t *auth_token_out_len, u8 **recent_car, size_t *recent_car_len, u8 **prev_car, size_t *prev_car_len) { sc_apdu_t apdu; - NPA_GEN_AUTH_PACE_C *c_data = NULL; - NPA_GEN_AUTH_PACE_R *r_data = NULL; + EAC_GEN_AUTH_PACE_C *c_data = NULL; + EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; unsigned char resp[maxresp]; @@ -891,7 +891,7 @@ static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00); - c_data = NPA_GEN_AUTH_PACE_C_new(); + c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; @@ -904,7 +904,7 @@ static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = i2d_NPA_GEN_AUTH_PACE_C(c_data, &d); + r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); if (r < 0) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -928,7 +928,7 @@ static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - if (!d2i_NPA_GEN_AUTH_PACE_R(&r_data, + if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); ssl_error(card->ctx); @@ -985,10 +985,10 @@ static int npa_gen_auth_4_mutual_authentication(sc_card_t *card, err: if (c_data) - NPA_GEN_AUTH_PACE_C_free(c_data); + EAC_GEN_AUTH_PACE_C_free(c_data); OPENSSL_free(d); if (r_data) - NPA_GEN_AUTH_PACE_R_free(r_data); + EAC_GEN_AUTH_PACE_R_free(r_data); return r; } @@ -999,27 +999,27 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id char *p = NULL; PACE_SEC *r; /* Flawfinder: ignore */ - char buf[MAX_MRZ_LEN > 32 ? MAX_MRZ_LEN : 32]; + char buf[EAC_MAX_MRZ_LEN > 32 ? EAC_MAX_MRZ_LEN : 32]; if (!length_pin || !pin) { if (0 > snprintf(buf, sizeof buf, "Please enter your %s: ", - npa_secret_name(pin_id))) { + eac_secret_name(pin_id))) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create password prompt.\n"); return NULL; } - p = malloc(MAX_MRZ_LEN+1); + p = malloc(EAC_MAX_MRZ_LEN+1); if (!p) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for %s.\n", - npa_secret_name(pin_id)); + eac_secret_name(pin_id)); return NULL; } - if (0 > EVP_read_pw_string_min(p, 0, MAX_MRZ_LEN, buf, 0)) { + if (0 > EVP_read_pw_string_min(p, 0, EAC_MAX_MRZ_LEN, buf, 0)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s.\n", - npa_secret_name(pin_id)); + eac_secret_name(pin_id)); return NULL; } length_pin = strlen(p); - if (length_pin > MAX_MRZ_LEN) { + if (length_pin > EAC_MAX_MRZ_LEN) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "MRZ too long"); return NULL; } @@ -1181,7 +1181,7 @@ int perform_pace(sc_card_t *card, eac_ctx->tr_version = tr_version; - r = npa_mse_set_at_pace(card, eac_ctx->pace_ctx->protocol, + r = eac_mse_set_at_pace(card, eac_ctx->pace_ctx->protocol, pace_input.pin_id, chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2); if (r < 0) { @@ -1196,7 +1196,7 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - r = npa_gen_auth_1_encrypted_nonce(card, (u8 **) &enc_nonce->data, + r = eac_gen_auth_1_encrypted_nonce(card, (u8 **) &enc_nonce->data, &enc_nonce->length); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get encrypted nonce from card " @@ -1230,7 +1230,7 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = npa_gen_auth_2_map_nonce(card, (u8 *) mdata->data, mdata->length, + r = eac_gen_auth_2_map_nonce(card, (u8 *) mdata->data, mdata->length, (u8 **) &mdata_opp->data, &mdata_opp->length); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange mapping data with card " @@ -1256,7 +1256,7 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = npa_gen_auth_3_perform_key_agreement(card, (u8 *) pub->data, pub->length, + r = eac_gen_auth_3_perform_key_agreement(card, (u8 *) pub->data, pub->length, (u8 **) &pub_opp->data, &pub_opp->length); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange ephemeral public key with card " @@ -1283,7 +1283,7 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = npa_gen_auth_4_mutual_authentication(card, (u8 *) token->data, token->length, + r = eac_gen_auth_4_mutual_authentication(card, (u8 *) token->data, token->length, (u8 **) &token_opp->data, &token_opp->length, &pace_output->recent_car, &pace_output->recent_car_length, &pace_output->previous_car, &pace_output->previous_car_length); @@ -1344,7 +1344,7 @@ int perform_pace(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd, pace_output->id_pcd_length); - r = npa_sm_start(card, eac_ctx, pace_input.certificate_description, + r = eac_sm_start(card, eac_ctx, pace_input.certificate_description, pace_input.certificate_description_length, pace_output->id_icc, pace_output->id_icc_length); } @@ -1382,24 +1382,24 @@ int perform_pace(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } -static int npa_mse_set_at_ta(sc_card_t *card, int protocol, +static int eac_mse_set_at_ta(sc_card_t *card, int protocol, const unsigned char *chr, size_t chr_len, const unsigned char *eph_pub_key, size_t eph_pub_key_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len) { - return npa_mse_set_at(card, 0x81, protocol, chr, chr_len, NULL, 0, + return eac_mse_set_at(card, 0x81, protocol, chr, chr_len, NULL, 0, eph_pub_key, eph_pub_key_len, auxiliary_data, auxiliary_data_len, NULL, NULL, NULL); } -static int npa_mse_set_dst(sc_card_t *card, +static int eac_mse_set_dst(sc_card_t *card, const unsigned char *chr, size_t chr_len) { - return npa_mse(card, 0x81, 0xb6, 0, chr, chr_len, NULL, 0, NULL, 0, NULL, + return eac_mse(card, 0x81, 0xb6, 0, chr, chr_len, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, NULL); } -static int npa_get_challenge(sc_card_t *card, +static int eac_get_challenge(sc_card_t *card, unsigned char *challenge, size_t len) { sc_apdu_t apdu; @@ -1425,7 +1425,7 @@ static int npa_get_challenge(sc_card_t *card, return r; } -static int npa_verify(sc_card_t *card, +static int eac_verify(sc_card_t *card, const unsigned char *cert, size_t cert_len) { sc_apdu_t apdu; @@ -1461,7 +1461,7 @@ static int npa_verify(sc_card_t *card, return r; } -static int npa_external_authenticate(sc_card_t *card, +static int eac_external_authenticate(sc_card_t *card, unsigned char *signature, size_t signature_len) { int r; @@ -1501,7 +1501,7 @@ int perform_terminal_authentication(sc_card_t *card, CVC_CERT *cvc_cert = NULL; BUF_MEM *nonce = NULL, *signature = NULL; struct iso_sm_ctx *isosmctx = NULL; - struct npa_sm_ctx *eacsmctx = NULL; + struct eac_sm_ctx *eacsmctx = NULL; unsigned char *ef_cardaccess = NULL; EAC_CTX *eac_ctx = NULL; @@ -1544,7 +1544,7 @@ int perform_terminal_authentication(sc_card_t *card, goto err; } - isosmctx->priv_data = npa_sm_ctx_create(eac_ctx, NULL, 0, NULL, 0); + isosmctx->priv_data = eac_sm_ctx_create(eac_ctx, NULL, 0, NULL, 0); if (!isosmctx->priv_data) { r = SC_ERROR_INTERNAL; goto err; @@ -1566,7 +1566,7 @@ int perform_terminal_authentication(sc_card_t *card, } cert = *certs; - r = npa_mse_set_dst(card, + r = eac_mse_set_dst(card, cvc_cert->body->certificate_authority_reference->data, cvc_cert->body->certificate_authority_reference->length); if (r < 0) { @@ -1575,7 +1575,7 @@ int perform_terminal_authentication(sc_card_t *card, goto err; } - r = npa_verify(card, cert, cert_len); + r = eac_verify(card, cert, cert_len); if (r < 0) goto err; @@ -1603,7 +1603,7 @@ int perform_terminal_authentication(sc_card_t *card, } - r = npa_mse_set_at_ta(card, eacsmctx->ctx->ta_ctx->protocol, + r = eac_mse_set_at_ta(card, eacsmctx->ctx->ta_ctx->protocol, cvc_cert->body->certificate_holder_reference->data, cvc_cert->body->certificate_holder_reference->length, (unsigned char *) eacsmctx->eph_pub_key->data, eacsmctx->eph_pub_key->length, @@ -1620,7 +1620,7 @@ int perform_terminal_authentication(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = npa_get_challenge(card, (unsigned char *) nonce->data, nonce->length); + r = eac_get_challenge(card, (unsigned char *) nonce->data, nonce->length); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get nonce for TA."); goto err; @@ -1644,7 +1644,7 @@ int perform_terminal_authentication(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - r = npa_external_authenticate(card, (unsigned char *) signature->data, + r = eac_external_authenticate(card, (unsigned char *) signature->data, signature->length); err: @@ -1661,18 +1661,18 @@ int perform_terminal_authentication(sc_card_t *card, return r; } -static int npa_mse_set_at_ca(sc_card_t *card, int protocol) +static int eac_mse_set_at_ca(sc_card_t *card, int protocol) { - return npa_mse_set_at(card, 0x41, protocol, NULL, 0, NULL, 0, NULL, 0, + return eac_mse_set_at(card, 0x41, protocol, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, NULL); } -static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, +static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, BUF_MEM **nonce, BUF_MEM **token) { sc_apdu_t apdu; - NPA_GEN_AUTH_CA_C *c_data = NULL; - NPA_GEN_AUTH_CA_R *r_data = NULL; + EAC_GEN_AUTH_CA_C *c_data = NULL; + EAC_GEN_AUTH_CA_R *r_data = NULL; unsigned char *d = NULL; int r; unsigned char resp[maxresp]; @@ -1680,7 +1680,7 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, 0, 0); - c_data = NPA_GEN_AUTH_CA_C_new(); + c_data = EAC_GEN_AUTH_CA_C_new(); if (!c_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; @@ -1694,7 +1694,7 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, r = SC_ERROR_INTERNAL; goto err; } - r = i2d_NPA_GEN_AUTH_CA_C(c_data, &d); + r = i2d_EAC_GEN_AUTH_CA_C(c_data, &d); if (r < 0) { ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -1718,7 +1718,7 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - if (!d2i_NPA_GEN_AUTH_CA_R(&r_data, + if (!d2i_EAC_GEN_AUTH_CA_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); ssl_error(card->ctx); @@ -1748,9 +1748,9 @@ static int npa_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, err: if (c_data) - NPA_GEN_AUTH_CA_C_free(c_data); + EAC_GEN_AUTH_CA_C_free(c_data); if (r_data) - NPA_GEN_AUTH_CA_R_free(r_data); + EAC_GEN_AUTH_CA_R_free(r_data); OPENSSL_free(d); return r; @@ -1768,7 +1768,7 @@ int perform_chip_authentication(sc_card_t *card, int r; BUF_MEM *picc_pubkey = NULL; struct iso_sm_ctx *isosmctx; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card || !ef_cardsecurity || !ef_cardsecurity_len) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -1832,7 +1832,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, } - r = npa_mse_set_at_ca(card, ctx->ca_ctx->protocol); + r = eac_mse_set_at_ca(card, ctx->ca_ctx->protocol); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " "(MSE: Set AT failed)."); @@ -1847,7 +1847,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, r = SC_ERROR_INTERNAL; goto err; } - r = npa_gen_auth_ca(card, eph_pub_key, &nonce, &token); + r = eac_gen_auth_ca(card, eph_pub_key, &nonce, &token); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "(General Authenticate failed)."); goto err; @@ -1879,7 +1879,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, } if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - r = npa_sm_start(card, ctx, NULL, 0, NULL, 0); + r = eac_sm_start(card, ctx, NULL, 0, NULL, 0); } err: @@ -1895,7 +1895,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, } static int -increment_ssc(struct npa_sm_ctx *eacsmctx) +increment_ssc(struct eac_sm_ctx *eacsmctx) { if (!eacsmctx) return SC_ERROR_INVALID_ARGUMENTS; @@ -1907,13 +1907,13 @@ increment_ssc(struct npa_sm_ctx *eacsmctx) } static int -npa_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, u8 **enc) { BUF_MEM *encbuf = NULL, *databuf = NULL; u8 *p = NULL; int r; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card || !ctx || !enc || !ctx->priv_data) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -1949,13 +1949,13 @@ npa_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, } static int -npa_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *enc, size_t enclen, u8 **data) { BUF_MEM *encbuf = NULL, *databuf = NULL; u8 *p = NULL; int r; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card || !ctx || !enc || !ctx->priv_data || !data) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -1991,13 +1991,13 @@ npa_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, } static int -npa_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, u8 **macdata) { BUF_MEM *inbuf = NULL, *macbuf = NULL; u8 *p = NULL; int r; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card || !ctx || !ctx->priv_data || !macdata) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -2040,13 +2040,13 @@ npa_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, } static int -npa_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *mac, size_t maclen, const u8 *macdata, size_t macdatalen) { int r; BUF_MEM *inbuf = NULL, *my_mac = NULL; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card || !ctx || !ctx->priv_data) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -2115,7 +2115,7 @@ add_tag(unsigned char **asn1new, int constructed, int tag, return newlen; } static int -npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu) { int r; @@ -2124,9 +2124,9 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, int len; BUF_MEM *signature = NULL; unsigned char *sequence = NULL; - NPA_MSE_C *msesetat = NULL; + EAC_MSE_C *msesetat = NULL; const unsigned char *p; - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card) return SC_ERROR_INVALID_ARGUMENTS; @@ -2136,7 +2136,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, } eacsmctx = ctx->priv_data; - if (!(eacsmctx->flags & NPA_FLAG_DISABLE_CHECK_ALL)) { + if (!(eacsmctx->flags & EAC_FLAG_DISABLE_CHECK_ALL)) { if (apdu->ins == 0x2a && apdu->p1 == 0x00 && apdu->p2 == 0xbe) { /* PSO:Verify Certificate * check certificate description to match given certificate */ @@ -2210,7 +2210,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, len = add_tag(&sequence, 1, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, apdu->data, apdu->datalen); p = sequence; - if (len < 0 || !d2i_NPA_MSE_C(&msesetat, &p, len)) { + if (len < 0 || !d2i_EAC_MSE_C(&msesetat, &p, len)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse MSE:Set AT."); ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -2306,13 +2306,13 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, if (sequence) OPENSSL_free(sequence); if (msesetat) - NPA_MSE_C_free(msesetat); + EAC_MSE_C_free(msesetat); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } static int -npa_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, @@ -2320,10 +2320,10 @@ npa_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, } static int -npa_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, +eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu) { - struct npa_sm_ctx *eacsmctx; + struct eac_sm_ctx *eacsmctx; if (!card) return SC_ERROR_INVALID_ARGUMENTS; if(!ctx || !ctx->priv_data || !apdu) @@ -2331,7 +2331,7 @@ npa_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, SC_ERROR_INVALID_ARGUMENTS); eacsmctx = ctx->priv_data; - if (!(eacsmctx->flags & NPA_FLAG_DISABLE_CHECK_ALL)) { + if (!(eacsmctx->flags & EAC_FLAG_DISABLE_CHECK_ALL)) { if (apdu->sw1 == 0x90 && apdu->sw2 == 0x00) { if (apdu->ins == 0x84 && apdu->p1 == 0x00 && apdu->p2 == 0x00 && apdu->le == 8 && apdu->resplen == 8) { @@ -2359,10 +2359,10 @@ npa_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, } static void -npa_sm_clear_free(const struct iso_sm_ctx *ctx) +eac_sm_clear_free(const struct iso_sm_ctx *ctx) { if (ctx) { - struct npa_sm_ctx *eacsmctx = ctx->priv_data; + struct eac_sm_ctx *eacsmctx = ctx->priv_data; EAC_CTX_clear_free(eacsmctx->ctx); if (eacsmctx->certificate_description) BUF_MEM_free(eacsmctx->certificate_description); @@ -2423,7 +2423,7 @@ static const char *PIN_name = "eID PIN"; static const char *PUK_name = "PUK"; static const char *CAN_name = "CAN"; static const char *UNDEF_name = "UNDEF"; -const char *npa_secret_name(enum s_type pin_id) { +const char *eac_secret_name(enum s_type pin_id) { switch (pin_id) { case PACE_MRZ: return MRZ_name; @@ -2438,76 +2438,7 @@ const char *npa_secret_name(enum s_type pin_id) { } } -int -npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, - int ask_for_secret, const char *new, size_t new_len) -{ - sc_apdu_t apdu; - char *p = NULL; - int r; - - if (ask_for_secret && (!new || !new_len)) { - if (!(SC_READER_CAP_PIN_PAD & card->reader->capabilities)) { -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - p = malloc(MAX_PIN_LEN+1); - if (!p) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for new PIN.\n"); - return SC_ERROR_OUT_OF_MEMORY; - } - if (0 > EVP_read_pw_string_min(p, - MIN_PIN_LEN, MAX_PIN_LEN+1, - "Please enter your new PIN: ", 0)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n"); - free(p); - return SC_ERROR_INTERNAL; - } - new_len = strlen(p); - if (new_len > MAX_PIN_LEN) - return SC_ERROR_INVALID_PIN_LENGTH; - new = p; -#else - return SC_ERROR_NOT_SUPPORTED; -#endif - } - } - - sc_format_apdu(card, &apdu, 0, 0x2C, 0, pin_id); - apdu.data = (u8 *) new; - apdu.datalen = new_len; - apdu.lc = apdu.datalen; - - if (new_len || ask_for_secret) { - apdu.p1 = 0x02; - apdu.cse = SC_APDU_CASE_3_SHORT; - } else { - apdu.p1 = 0x03; - apdu.cse = SC_APDU_CASE_1; - } - - if (ask_for_secret && !new_len) { - struct sc_pin_cmd_data data; - data.apdu = &apdu; - data.cmd = SC_PIN_CMD_CHANGE; - data.flags = SC_PIN_CMD_IMPLICIT_CHANGE; - data.pin2.encoding = SC_PIN_ENCODING_ASCII; - data.pin2.length_offset = 0; - data.pin2.offset = 5; - data.pin2.max_length = MAX_PIN_LEN; - data.pin2.min_length = MIN_PIN_LEN; - data.pin2.pad_length = 0; - r = card->reader->ops->perform_verify(card->reader, &data); - } else - r = sc_transmit_apdu(card, &apdu); - - if (p) { - sc_mem_clear(p, new_len); - free(p); - } - - return r; -} - -int npa_pace_get_tries_left(sc_card_t *card, +int eac_pace_get_tries_left(sc_card_t *card, enum s_type pin_id, int *tries_left) { int r; @@ -2515,7 +2446,7 @@ int npa_pace_get_tries_left(sc_card_t *card, if (tries_left) { #if defined(ENABLE_OPENPACE) && defined(ENABLE_SM) - r = npa_mse_set_at_pace(card, 0, pin_id, 0, &sw1, &sw2); + r = eac_mse_set_at_pace(card, 0, pin_id, 0, &sw1, &sw2); #else sc_apdu_t apdu; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ISO_MSE, 0xC1, 0xA4); @@ -2535,14 +2466,3 @@ int npa_pace_get_tries_left(sc_card_t *card, return r; } - -int get_pace_capabilities(u8 *bitmap) -{ - if (!bitmap) - return SC_ERROR_INVALID_ARGUMENTS; - - /* BitMap */ - *bitmap = NPA_BITMAP_PACE|NPA_BITMAP_EID|NPA_BITMAP_ESIGN; - - return SC_SUCCESS; -} diff --git a/src/sm/sm-eac.h b/src/sm/sm-eac.h index fcb35773f2..0fa353f28d 100644 --- a/src/sm/sm-eac.h +++ b/src/sm/sm-eac.h @@ -19,7 +19,7 @@ */ /** * @file - * @defgroup npa Interface to German identity card (neuer Personalausweis, nPA) + * @defgroup eac Interface to Extended Access Control * @{ */ #ifndef _SC_EAC_H @@ -38,10 +38,6 @@ extern "C" { #include #include -/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */ -typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA; -DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) - #else /** @brief Type of the secret */ enum s_type { @@ -80,50 +76,6 @@ enum eac_tr_version { }; #endif -/** @brief NPA capabilities (TR-03119): PACE */ -#define NPA_BITMAP_PACE 0x40 -/** @brief NPA capabilities (TR-03119): EPA: eID */ -#define NPA_BITMAP_EID 0x20 -/** @brief NPA capabilities (TR-03119): EPA: eSign */ -#define NPA_BITMAP_ESIGN 0x10 - -/** @brief NPA result (TR-03119): Kein Fehler */ -#define NPA_SUCCESS 0x00000000 -/** @brief NPA result (TR-03119): Längen im Input sind inkonsistent */ -#define NPA_ERROR_LENGTH_INCONSISTENT 0xD0000001 -/** @brief NPA result (TR-03119): Unerwartete Daten im Input */ -#define NPA_ERROR_UNEXPECTED_DATA 0xD0000002 -/** @brief NPA result (TR-03119): Unerwartete Kombination von Daten im Input */ -#define NPA_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003 -/** @brief NPA result (TR-03119): Die Karte unterstützt das PACE – Verfahren nicht. (Unerwartete Struktur in Antwortdaten der Karte) */ -#define NPA_ERROR_CARD_NOT_SUPPORTED 0xE0000001 -/** @brief NPA result (TR-03119): Der Kartenleser unterstützt den angeforderten bzw. den ermittelten Algorithmus nicht. */ -#define NPA_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002 -/** @brief NPA result (TR-03119): Der Kartenleser kennt die PIN – ID nicht. */ -#define NPA_ERROR_PINID_NOT_SUPPORTED 0xE0000003 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Select EF_CardAccess (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_SELECT_EF_CARDACCESS 0xF0000000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Read Binary (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_READ_BINARY 0xF0010000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf MSE: Set AT (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_MSE_SET_AT 0xF0020000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 1 (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 2 (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 3 (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000 -/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 4 (needs to be OR-ed with SW1|SW2) */ -#define NPA_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000 -/** @brief NPA result (TR-03119): Kommunikationsabbruch mit Karte. */ -#define NPA_ERROR_COMMUNICATION 0xF0100001 -/** @brief NPA result (TR-03119): Keine Karte im Feld. */ -#define NPA_ERROR_NO_CARD 0xF0100002 -/** @brief NPA result (TR-03119): Benutzerabbruch. */ -#define NPA_ERROR_ABORTED 0xF0200001 -/** @brief NPA result (TR-03119): Benutzer – Timeout */ -#define NPA_ERROR_TIMEOUT 0xF0200002 - /** @brief File identifier of EF.CardAccess */ #define FID_EF_CARDACCESS 0x011C /** @brief Short file identifier of EF.CardAccess */ @@ -134,17 +86,17 @@ enum eac_tr_version { #define SFID_EF_CARDSECURITY 0x1D /** @brief Maximum length of PIN */ -#define MAX_PIN_LEN 6 +#define EAC_MAX_PIN_LEN 6 /** @brief Minimum length of PIN */ -#define MIN_PIN_LEN 6 +#define EAC_MIN_PIN_LEN 6 /** @brief Length of CAN */ -#define CAN_LEN 6 +#define EAC_CAN_LEN 6 /** @brief Minimum length of MRZ */ -#define MAX_MRZ_LEN 128 +#define EAC_MAX_MRZ_LEN 128 /** @brief Number of retries for PIN */ -#define MAX_PIN_TRIES 3 +#define EAC_MAX_PIN_TRIES 3 /** @brief Usage counter of PIN in suspended state */ -#define UC_PIN_SUSPENDED 1 +#define EAC_UC_PIN_SUSPENDED 1 /** @@ -154,18 +106,7 @@ enum eac_tr_version { * * @return Printable string containing the name */ -const char *npa_secret_name(enum s_type pin_id); - - -/** - * @brief Get the PACE capabilities - * - * @param[in,out] bitmap where to store capabilities bitmap - * @note Since this code offers no support for terminal certificate, the bitmap is always \c PACE_BITMAP_PACE|PACE_BITMAP_EID - * - * @return \c SC_SUCCESS or error code if an error occurred - */ -int get_pace_capabilities(u8 *bitmap); +const char *eac_secret_name(enum s_type pin_id); /** * @brief Establish secure messaging using PACE @@ -217,6 +158,10 @@ int perform_terminal_authentication(sc_card_t *card, const unsigned char *privkey, size_t privkey_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len); +/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */ +typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA; +DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) + /** * @brief Establish secure messaging using Chip Authentication version 2 * @@ -233,25 +178,8 @@ int perform_chip_authentication(sc_card_t *card, int perform_chip_authentication_ex(sc_card_t *card, void *eacsmctx, unsigned char *picc_pubkey, size_t picc_pubkey_len); -/** - * @brief Sends a reset retry counter APDU - * - * According to TR-03110 the reset retry counter APDU is used to set a new PIN - * or to reset the retry counter of the PIN. The standard requires this - * operation to be authorized either by an established PACE channel or by the - * effective authorization of the terminal's certificate. - * - * @param[in] card - * @param[in] pin_id Type of secret (usually PIN or CAN). You may use enum s_type from \c . - * @param[in] ask_for_secret whether to ask the user for the secret (\c 1) or not (\c 0) - * @param[in] new (optional) new secret - * @param[in] new_len (optional) length of \a new - * - * @return \c SC_SUCCESS or error code if an error occurred - */ -int npa_reset_retry_counter(sc_card_t *card, - enum s_type pin_id, int ask_for_secret, - const char *new, size_t new_len); +/** @brief Disable all sanity checks done by OpenSC */ +#define EAC_FLAG_DISABLE_CHECK_ALL 1 /** * @brief Sends an MSE:Set AT to determine the number of remaining tries @@ -262,34 +190,16 @@ int npa_reset_retry_counter(sc_card_t *card, * * @return \c SC_SUCCESS or error code if an error occurred */ -int npa_pace_get_tries_left(sc_card_t *card, +int eac_pace_get_tries_left(sc_card_t *card, enum s_type pin_id, int *tries_left); -/** - * @brief Send APDU to unblock the PIN - * - * @param[in] card - */ -#define npa_unblock_pin(card) \ - npa_reset_retry_counter(card, PACE_PIN, 0, NULL, 0) -/** - * @brief Send APDU to set a new PIN - * - * @param[in] card - * @param[in] newp (optional) new PIN - * @param[in] newplen (optional) length of \a new - */ -#define npa_change_pin(card, newp, newplen) \ - npa_reset_retry_counter(card, PACE_PIN, 1, newp, newplen) -/** @brief Disable all sanity checks done by libnpa */ -#define NPA_FLAG_DISABLE_CHECK_ALL 1 /** @brief Disable checking validity period of CV certificates */ -#define NPA_FLAG_DISABLE_CHECK_TA 2 +#define EAC_FLAG_DISABLE_CHECK_TA 2 /** @brief Disable checking passive authentication during CA */ -#define NPA_FLAG_DISABLE_CHECK_CA 4 +#define EAC_FLAG_DISABLE_CHECK_CA 4 -/** @brief Use \c npa_default_flags to disable checks for EAC/SM */ -extern char npa_default_flags; +/** @brief Use \c eac_default_flags to disable checks for EAC/SM */ +extern char eac_default_flags; #ifdef __cplusplus } diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 7ff0edb155..8b10d81abe 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Frank Morgner + * Copyright (C) 2010-2018 Frank Morgner * * This file is part of OpenSC. * @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -419,11 +420,11 @@ main (int argc, char **argv) if (cmdline.tr_03110v201_flag) tr_version = EAC_TR_VERSION_2_01; if (cmdline.disable_all_checks_flag) - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_ALL; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL; if (cmdline.disable_ta_checks_flag) - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_TA; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA; if (cmdline.disable_ca_checks_flag) - npa_default_flags |= NPA_FLAG_DISABLE_CHECK_CA; + eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA; r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader); @@ -457,12 +458,12 @@ main (int argc, char **argv) if (pin) { if (sscanf(pin, "%llu", &secret) != 1) { fprintf(stderr, "%s is not an unsigned long long.\n", - npa_secret_name(pace_input.pin_id)); + eac_secret_name(pace_input.pin_id)); exit(2); } if (strlen(pin) > pace_input.pin_length) { fprintf(stderr, "%s too big, only %u digits allowed.\n", - npa_secret_name(pace_input.pin_id), + eac_secret_name(pace_input.pin_id), (unsigned int) pace_input.pin_length); exit(2); } @@ -474,12 +475,12 @@ main (int argc, char **argv) if (can) { if (sscanf(can, "%llu", &secret) != 1) { fprintf(stderr, "%s is not an unsigned long long.\n", - npa_secret_name(pace_input.pin_id)); + eac_secret_name(pace_input.pin_id)); exit(2); } if (strlen(can) > pace_input.pin_length) { fprintf(stderr, "%s too big, only %u digits allowed.\n", - npa_secret_name(pace_input.pin_id), + eac_secret_name(pace_input.pin_id), (unsigned int) pace_input.pin_length); exit(2); } @@ -491,12 +492,12 @@ main (int argc, char **argv) if (puk) { if (sscanf(puk, "%llu", &secret) != 1) { fprintf(stderr, "%s is not an unsigned long long.\n", - npa_secret_name(pace_input.pin_id)); + eac_secret_name(pace_input.pin_id)); exit(2); } if (strlen(puk) > pace_input.pin_length) { fprintf(stderr, "%s too big, only %u digits allowed.\n", - npa_secret_name(pace_input.pin_id), + eac_secret_name(pace_input.pin_id), (unsigned int) pace_input.pin_length); exit(2); } @@ -515,7 +516,7 @@ main (int argc, char **argv) gettimeofday(&tv, NULL); printf("%u,%06u: Trying %s=%s\n", (unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec, - npa_secret_name(pace_input.pin_id), pace_input.pin); + eac_secret_name(pace_input.pin_id), pace_input.pin); r = perform_pace(card, pace_input, &pace_output, tr_version); @@ -526,12 +527,12 @@ main (int argc, char **argv) if (0 > r) { printf("%u,%06u: Tried breaking %s without success.\n", (unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec, - npa_secret_name(pace_input.pin_id)); + eac_secret_name(pace_input.pin_id)); goto err; } else { printf("%u,%06u: Tried breaking %s with success (=%s).\n", (unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec, - npa_secret_name(pace_input.pin_id), + eac_secret_name(pace_input.pin_id), pace_input.pin); } } @@ -750,7 +751,7 @@ main (int argc, char **argv) if (r < 0) goto err; printf("Established PACE channel with %s.\n", - npa_secret_name(pace_input.pin_id)); + eac_secret_name(pace_input.pin_id)); nopace: if (cmdline.cv_certificate_given || cmdline.private_key_given) { diff --git a/src/tools/sceac-example.c b/src/tools/sceac-example.c index 49d8bbe3f9..28770e09a8 100644 --- a/src/tools/sceac-example.c +++ b/src/tools/sceac-example.c @@ -30,6 +30,7 @@ #include "libopensc/sm.h" #include "sm/sm-iso.h" #include "sm/sm-eac.h" +#include "libopensc/card-npa.h" #include static const char *newpin = NULL; From 905e95eb3724dcb3721fa58feffe2839b0aa1deb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jan 2018 10:47:43 +0100 Subject: [PATCH 0175/4321] compiler fix --- src/sm/sm-eac.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sm/sm-eac.h b/src/sm/sm-eac.h index 0fa353f28d..bf6b4dc569 100644 --- a/src/sm/sm-eac.h +++ b/src/sm/sm-eac.h @@ -38,6 +38,10 @@ extern "C" { #include #include +/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */ +typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA; +DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) + #else /** @brief Type of the secret */ enum s_type { @@ -158,10 +162,6 @@ int perform_terminal_authentication(sc_card_t *card, const unsigned char *privkey, size_t privkey_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len); -/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */ -typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA; -DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) - /** * @brief Establish secure messaging using Chip Authentication version 2 * From 86350d3f72eaa54226f81c41c9bf7a1c1002a646 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jan 2018 11:29:09 +0100 Subject: [PATCH 0176/4321] fixed compilation proble --- src/libopensc/card-npa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 457c4aac51..c4932cd790 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -586,6 +586,10 @@ static int npa_standard_pin_cmd(struct sc_card *card, return r; } +#ifdef ENABLE_OPENSSL +#include +#endif + int npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, int ask_for_secret, const char *new, size_t new_len) From 1d4f59ea51dd1713a3b99186498cb8fe074abc4c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jan 2018 12:28:43 +0100 Subject: [PATCH 0177/4321] compiler fix --- src/libopensc/card-npa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index c4932cd790..d1175eb498 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -587,7 +587,7 @@ static int npa_standard_pin_cmd(struct sc_card *card, } #ifdef ENABLE_OPENSSL -#include +#include #endif int From 8cc0c3911ae2a58fdad9d6cec98e5e0f8e0dc6f8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 28 Jan 2018 19:15:40 -0600 Subject: [PATCH 0178/4321] Yubico PIV application fixed CI_VERIFY_LC0_FAIL in version 4.3.2 Also add PIV card types to sc_pkcs15_is_emulation_only On branch piv-aid-discovery Changes to be committed: modified: src/libopensc/card-piv.c modified: src/libopensc/pkcs15-syn.c --- src/libopensc/card-piv.c | 11 +++++++---- src/libopensc/pkcs15-syn.c | 5 +++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 1ae90e760e..cb4b64456f 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3048,7 +3048,7 @@ static int piv_init(sc_card_t *card) apdu.le = apdu.resplen; r = sc_transmit_apdu(card, &apdu); priv->neo_version = (neo_version_buf[0]<<16) | (neo_version_buf[1] <<8) | neo_version_buf[2]; - sc_log(card->ctx, "NEO card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->neo_version); + sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->neo_version); break; } @@ -3066,16 +3066,18 @@ static int piv_init(sc_card_t *card) case SC_CARD_TYPE_PIV_II_NEO: priv->card_issues = CI_NO_EC384 | CI_VERIFY_630X - | CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND | CI_NFC_EXPOSE_TOO_MUCH; + if (priv->neo_version < 0x00040302) + priv->card_issues |= CI_VERIFY_LC0_FAIL; break; case SC_CARD_TYPE_PIV_II_YUBIKEY4: - priv->card_issues = CI_VERIFY_LC0_FAIL - | CI_OTHER_AID_LOSE_STATE + priv->card_issues = CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND; + if (priv->neo_version < 0x00040302) + priv->card_issues |= CI_VERIFY_LC0_FAIL; break; case SC_CARD_TYPE_PIV_II_HIST: @@ -3085,6 +3087,7 @@ static int piv_init(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GENERIC: priv->card_issues = CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE; + /* TODO may need more research */ break; default: diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 4f2932e4e5..9f03cdaa30 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -90,6 +90,11 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_DNIE_USER: case SC_CARD_TYPE_DNIE_TERMINATED: case SC_CARD_TYPE_IASECC_GEMALTO: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + return 1; default: return 0; From 3fea6b792739b658a588f28de5516f277d5c1083 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 29 Jan 2018 10:37:47 -0600 Subject: [PATCH 0179/4321] PIV detection of AID using Discovery Object before doing select AID Many OpenSC drivers try and detect during match if the card supports their AID by doing a SELECT FILE for the AID. But this can cause problems with cards such as Yubico that do not ignore SELECT AID commands for applications they do not support. Other cards may have the same problems. Selecting the wrong AID can also lose the security state. The card-piv.c will now uses the GET DATA to read the PIV Discovery Object '7E' which is a ISO standard template that will contain the AID of the currently active application. The driver will then double check that the template is for the PIV application. If the template contains the PIV AID, then no SELECT AID is done. PIV standards say there can only be one PIV application on a card. PIV standards also say PIV must be the the default application, but Yubico does not follow this. The command fails only then will a SELECT AID be done. Thus this can avoid the Yubico problem. This logic is used in both "match" and in the piv_card_reader_lock_obtained routine. Additional logic was in piv_card_reader_lock_obtained was added to handle when the card reset was received by some other program. Multiple programs may be trying to use the PIV application on the card, and thus multiple programs will all receive that the card was reset. The first program to receive the card was reset will do all of the above logic, and may leave the card in a state will cause other programs to not have to do much at all. The intent of all of this is to avoid sending extra commands to the card including SELECT AID that could change the card state when not needed. On branch piv-aid-discovery Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 211 +++++++++++++++++++++++++++++---------- 1 file changed, 160 insertions(+), 51 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index cb4b64456f..d6381847b6 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -141,6 +141,12 @@ typedef struct piv_obj_cache { int flags; } piv_obj_cache_t; +enum { + PIV_STATE_NORMAL = 0, + PIV_STATE_MATCH, + PIV_STATE_INIT +}; + typedef struct piv_private_data { sc_file_t *aid_file; int enumtag; @@ -160,6 +166,7 @@ typedef struct piv_private_data { char * offCardCertURL; int pin_preference; /* set from Discovery object */ int logged_in; + int pstate; int pin_cmd_verify; int pin_cmd_noparse; unsigned int pin_cmd_verify_sw1; @@ -180,7 +187,7 @@ struct piv_aid { }; /* - * The Generic entry should be the "A0 00 00 03 08 00 00 01 00 " + * The Generic entry should be the "A0 00 00 03 08 00 00 10 00 " * NIST published this on 10/6/2005 * 800-73-2 Part 1 now refers to version "02 00" * i.e. "A0 00 00 03 08 00 00 01 00 02 00". @@ -2072,8 +2079,6 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) const u8 *fascn; const u8 *guid; size_t rbuflen = 0, bodylen, fascnlen, guidlen; - u8 temp[2000]; - size_t templen = sizeof(temp); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (card->serialnr.len) { @@ -2081,15 +2086,12 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - /* ensure we've got the PIV selected, and nothing else is in process */ - /* This fixes several problems due to previous incomplete APDUs during card detection */ - /* Note: We need the temp because (some?) Oberthur cards don't like selecting an applet without response data */ - /* 800-73-3 part1 draft, and CIO Council docs imply for PIV Compatible card - * The FASC-N Agency code should be 9999 and there should be a GUID - * based on RFC 4122. RIf so and the GUID is not all 0's + /* + * 800-73-3 Part 1 and CIO Council docs say for PIV Compatible cards + * the FASC-N Agency code should be 9999 and there should be a GUID + * based on RFC 4122. If GUID present and not zero * we will use the GUID as the serial number. */ - piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); r = piv_get_cached_data(card, PIV_OBJ_CHUI, &rbuf, &rbuflen); LOG_TEST_RET(card->ctx, r, "Failure retrieving CHUI"); @@ -2577,12 +2579,10 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, } -static int piv_process_discovery(sc_card_t *card) +static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int aid_only) { piv_private_data_t * priv = PIV_DATA(card); - int r; - u8 * rbuf = NULL; - size_t rbuflen = 0; + int r = 0; const u8 * body; size_t bodylen; const u8 * aid; @@ -2592,20 +2592,6 @@ static int piv_process_discovery(sc_card_t *card) unsigned int cla_out, tag_out; - r = piv_get_cached_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen); - if (r <= 0) { - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - /* Discovery object is only object that has 3 byte Lc= 50017E - * and pree 800-73-3 cards may treat this as a strange error. - * So treat any error as not present - */ - r = 0; - goto err; - } - - sc_log(card->ctx, "Discovery = %p:%"SC_FORMAT_LEN_SIZE_T"u", rbuf, - rbuflen); - /* the object is now cached, see what we have */ if (rbuflen != 0) { body = rbuf; if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) { @@ -2625,19 +2611,21 @@ static int piv_process_discovery(sc_card_t *card) if (aid == NULL || aidlen < piv_aids[0].len_short || memcmp(aid,piv_aids[0].value,piv_aids[0].len_short) != 0) { /*TODO look at long */ sc_log(card->ctx, "Discovery object not PIV"); - r = SC_SUCCESS; /* not an error could be some other appl */ + r = SC_ERROR_INVALID_CARD; /* This is an error */ goto err; } - pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen); - sc_log(card->ctx, - "Discovery pinp=%p:%"SC_FORMAT_LEN_SIZE_T"u", - pinp, pinplen); - if (pinp && pinplen == 2) { - sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); - r = SC_SUCCESS; - if (*pinp == 0x60 && *(pinp+1) == 0x20) { /* use Global pin */ - sc_log(card->ctx, "Pin Preference - Global"); - priv->pin_preference = 0x00; + if (aid_only == 0) { + pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen); + sc_log(card->ctx, + "Discovery pinp=%p:%"SC_FORMAT_LEN_SIZE_T"u", + pinp, pinplen); + if (pinp && pinplen == 2) { + sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); + r = SC_SUCCESS; + if (*pinp == 0x60 && *(pinp+1) == 0x20) { /* use Global pin */ + sc_log(card->ctx, "Pin Preference - Global"); + priv->pin_preference = 0x00; + } } } } @@ -2647,6 +2635,61 @@ static int piv_process_discovery(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } + +/* normal way to get the discovery object via cache */ +static int piv_process_discovery(sc_card_t *card) +{ + int r; + u8 * rbuf = NULL; + size_t rbuflen = 0; + + r = piv_get_cached_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen); + /* Note rbuf and rbuflen are now pointers into cache */ + if (r < 0) + goto err; + + sc_log(card->ctx, "Discovery = %p:%"SC_FORMAT_LEN_SIZE_T"u", rbuf, + rbuflen); + /* the object is now cached, see what we have */ + r = piv_parse_discovery(card, rbuf, rbuflen, 0); + +err: + LOG_FUNC_RETURN(card->ctx, r); +} + + +/* Do not use the cache value but read every time */ +static int piv_find_discovery(sc_card_t *card) +{ + int r = 0; + u8 rbuf[256]; + size_t rbuflen = sizeof(rbuf); + u8 * arbuf = rbuf; + piv_private_data_t * priv = PIV_DATA(card); + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* + * During piv_match or piv_card_reader_lock_obtained, + * we use the discovery object to test if card present, and + * if PIV AID is active. So we can not use the cache + */ + + /* If not valid, read, cache and test */ + if (!(priv->obj_cache[PIV_OBJ_DISCOVERY].flags & PIV_OBJ_CACHE_VALID)) { + r = piv_process_discovery(card); + } else { + /* if already in cache,force read */ + r = piv_get_data(card, PIV_OBJ_DISCOVERY, &arbuf, &rbuflen); + if (r >= 0) + /* make sure it is PIV AID */ + r = piv_parse_discovery(card, rbuf, rbuflen, 1); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + + /* * The history object lists what retired keys and certs are on the card * or listed in the offCardCertURL. The user may have read the offCardURL file, @@ -2902,6 +2945,7 @@ piv_finish(sc_card_t *card) free(priv->obj_cache[i].internal_obj_data); } free(priv); + card->drv_data = NULL; /* priv */ } return 0; } @@ -2914,7 +2958,7 @@ static int piv_match_card(sc_card_t *card) u8 *p, *pe; sc_file_t aidfile; int type = -1; - piv_private_data_t *priv; + piv_private_data_t *priv = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -2978,11 +3022,7 @@ static int piv_match_card(sc_card_t *card) type = SC_CARD_TYPE_PIV_II_GENERIC; } - /* Detect by selecting applet */ - i = piv_find_aid(card, &aidfile); - - if (i < 0) - return 0; /* don't match. Does not have a PIV applet. */ + /* allocate and init basic fields */ priv = calloc(1, sizeof(piv_private_data_t)); @@ -2992,19 +3032,47 @@ static int piv_match_card(sc_card_t *card) if (card->type == -1) card->type = type; - card->drv_data = priv; + card->drv_data = priv; /* will frre if no match, or pass on to piv_init */ priv->aid_file = sc_file_new(); priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ priv->logged_in = SC_PIN_STATE_UNKNOWN; priv->tries_left = 10; /* will assume OK at start */ + priv->pstate = PIV_STATE_MATCH; /* Some objects will only be present if Histroy object says so */ for (i=0; i < PIV_OBJ_LAST_ENUM -1; i++) if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + sc_lock(card); + /* + * detect if active AID is PIV. NIST 800-73 says Only one PIV application per card + * and PIV must be the default application + * This can avoid doing doing a select_aid and losing the login state on some cards + * We may get interference on some cards by other drivers trying SELECT_AID before + * we get to see if PIV application is still active. + * putting PIV driver first might help. + * TODO could be cached too + */ + i = piv_find_discovery(card); + + if (i < 0) { + /* Detect by selecting applet */ + i = piv_find_aid(card, &aidfile); + } + + if (i < 0) { + piv_finish(card); + /* don't match. Does not have a PIV applet. */ + sc_unlock(card); + return 0; + } + + /* Matched, and priv is being passed to piv_init */ + /* hold the lock and pass to piv_init */ + priv->pstate=PIV_STATE_INIT; return 1; /* match */ } @@ -3131,6 +3199,8 @@ static int piv_init(sc_card_t *card) if (r > 0) r = 0; + priv->pstate=PIV_STATE_NORMAL; + sc_unlock(card) ; /* obtained in piv_match */ LOG_FUNC_RETURN(card->ctx, r); } @@ -3358,21 +3428,60 @@ static int piv_logout(sc_card_t *card) } +/* + * Called when a sc_lock gets a reader lock and PCSC SCardBeginTransaction + * If SCardBeginTransaction may pass back tha a card reset was seen since + * the last transaction completed. + * There may have been one or more resets, by other card drivers in different + * processes, and they may have taken action already + * and changed the AID and or may have sent a VERIFY with PIN + * So test the state of the card. + * this is very similiar to what the piv_match routtine does, + */ + static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) { int r = 0; - u8 temp[2000]; + u8 temp[256]; size_t templen = sizeof(temp); + struct sc_pin_cmd_data data; piv_private_data_t * priv = PIV_DATA(card); /* may be null */ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (was_reset > 0) { - if (priv) - priv->logged_in = SC_PIN_STATE_UNKNOWN; - r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + /* We have a PCSC transaction and sc_lock */ + if (priv == NULL || priv->pstate == PIV_STATE_MATCH) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + priv ? "PIV_STATE_MATCH" : "priv==NULL"); + r = 0; /* do nothing, piv_match will take care of it */ + goto err; } + /* make sure our application is active */ + + /* first see if AID is active AID be reading discovery obkect '7E' */ + /* If not try selecting AID */ + r = piv_find_discovery(card); + if (r < 0) + r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + + if (r < 0) /* bad error return will show up in sc_lock as error*/ + goto err; + + if (was_reset > 0) + priv->logged_in = SC_PIN_STATE_UNKNOWN; + + /* See if VERIFY Lc=empty will tell us the state */ + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_GET_INFO; + data.pin_type = SC_AC_CHV; + data.pin_reference = priv->pin_preference; + /* will try our best to see if logged_in or not */ + r = piv_pin_cmd(card, &data, NULL); + + r = 0; /* ignore return from piv_pin_cmd */ + +err: LOG_FUNC_RETURN(card->ctx, r); } From 27add2ee3c10269fba9465616a49231cfb68c65f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 1 Feb 2018 09:04:10 -0600 Subject: [PATCH 0180/4321] Inform pkcs15 and card drivers of PKCS#11 C_Login(CKU_CONTEXT_SPECIFIC)" Framework-pkcs15.c will now set pin_info->auth_method to SC_AC_CONTEXT_SPECIFIC iso7816.c iso7816_build_pin_apdu treats this the same as SC_AC_CHV card-piv.c piv_pin_cmd sets priv->xcontext_specific=1 and calls sc_lock before the verify command. If the verify fails sc_unlock is called. Later after the next card command returns, if priv->context_specific==1 piv_check_sw will call sc_unlock as the application may not have requested the crypto but some other command. Some additional calls to sc_lock and sc_unlock have been added to make sure PIV internal command sequences including the crypto command ('87') and any get responses are always protected by a lock. This guarantees the card is locked for verify and the next command which should be the crypto operation. The PIV card also inforces this restriction on the card. This is based on suggestions in: ://github.com/OpenSC/OpenSC/pull/1256#issuecomment-361975751 On branch piv-aid-discovery Changes to be committed: modified: src/libopensc/card-piv.c modified: src/libopensc/iso7816.c modified: src/libopensc/types.h modified: src/pkcs11/framework-pkcs15.c --- src/libopensc/card-piv.c | 53 ++++++++++++++++++++++++++++------- src/libopensc/iso7816.c | 1 + src/libopensc/types.h | 1 + src/pkcs11/framework-pkcs15.c | 11 +++++++- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d6381847b6..7cdb93ff5b 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -168,6 +168,7 @@ typedef struct piv_private_data { int logged_in; int pstate; int pin_cmd_verify; + int context_specific; int pin_cmd_noparse; unsigned int pin_cmd_verify_sw1; unsigned int pin_cmd_verify_sw2; @@ -919,6 +920,8 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, "#%d", enumtag); + sc_lock(card); /* do check len and get data in same transaction */ + /* assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); */ tag_len = piv_objects[enumtag].tag_len; @@ -970,6 +973,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, buf, buf_len); err: + sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } @@ -3032,7 +3036,7 @@ static int piv_match_card(sc_card_t *card) if (card->type == -1) card->type = type; - card->drv_data = priv; /* will frre if no match, or pass on to piv_init */ + card->drv_data = priv; /* will free if no match, or pass on to piv_init */ priv->aid_file = sc_file_new(); priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ @@ -3056,18 +3060,18 @@ static int piv_match_card(sc_card_t *card) * putting PIV driver first might help. * TODO could be cached too */ - i = piv_find_discovery(card); + i = piv_find_discovery(card); if (i < 0) { - /* Detect by selecting applet */ - i = piv_find_aid(card, &aidfile); + /* Detect by selecting applet */ + i = piv_find_aid(card, &aidfile); } if (i < 0) { piv_finish(card); - /* don't match. Does not have a PIV applet. */ - sc_unlock(card); - return 0; + /* don't match. Does not have a PIV applet. */ + sc_unlock(card); + return 0; } /* Matched, and priv is being passed to piv_init */ @@ -3218,7 +3222,16 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 if (priv->pin_cmd_verify) { priv->pin_cmd_verify_sw1 = sw1; priv->pin_cmd_verify_sw2 = sw2; + } else { + /* a command has completed and it is not verify */ + /* If we are in a context_specific sequence, unlock */ + if (priv->context_specific) { + sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC lock"); + priv->context_specific = 0; + sc_unlock(card); + } } + if (priv->card_issues & CI_VERIFY_630X) { /* Handle the Yubikey NEO or any other PIV card which returns in response to a verify @@ -3360,10 +3373,30 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } } + /* + * If this was for a CKU_CONTEXT_SPECFIC login, lock the card one more time. + * to avoid any interference from other applications. + * Sc_unlock will be called at a later time after the next card command + * that should be a crypto operation. If its not then it is a error by the + * calling appication. + */ + if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { + priv->context_specific = 1; + sc_log(card->ctx,"Starting CONTEXT_SPECIFIC verify"); + sc_lock(card); + } + priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ r = iso_drv->ops->pin_cmd(card, data, tries_left); priv->pin_cmd_verify = 0; + /* if verify failed, release the lock */ + if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) { + sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC"); + priv->context_specific = 0; + sc_unlock(card); + } + /* if access to applet is know to be reset by other driver we select_aid and try again */ if ( priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) { sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd"); @@ -3452,17 +3485,17 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) /* We have a PCSC transaction and sc_lock */ if (priv == NULL || priv->pstate == PIV_STATE_MATCH) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - priv ? "PIV_STATE_MATCH" : "priv==NULL"); + priv ? "PIV_STATE_MATCH" : "priv==NULL"); r = 0; /* do nothing, piv_match will take care of it */ goto err; } /* make sure our application is active */ - /* first see if AID is active AID be reading discovery obkect '7E' */ + /* first see if AID is active AID by reading discovery object '7E' */ /* If not try selecting AID */ r = piv_find_discovery(card); - if (r < 0) + if (r < 0) r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); if (r < 0) /* bad error return will show up in sc_lock as error*/ diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index e5916e7dd4..9ed49f2b5a 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1017,6 +1017,7 @@ iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu, case SC_AC_CHV: /* fall through */ case SC_AC_SESSION: + case SC_AC_CONTEXT_SPECIFIC: break; default: return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/types.h b/src/libopensc/types.h index e665c54b2d..ab0ddd8e30 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -149,6 +149,7 @@ struct sc_crt { #define SC_AC_SCB 0x00000040 /* IAS/ECC SCB byte. */ #define SC_AC_IDA 0x00000080 /* PKCS#15 authentication ID */ #define SC_AC_SESSION 0x00000100 /* Session PIN */ +#define SC_AC_CONTEXT_SPECIFIC 0x00000200 /* Context specific login */ #define SC_AC_UNKNOWN 0xFFFFFFFE #define SC_AC_NEVER 0xFFFFFFFF diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index a4a1e1c373..aee08a4a31 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1617,7 +1617,16 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, } } - rc = sc_pkcs15_verify_pin(p15card, auth_object, pPin, ulPinLen); + if (userType == CKU_CONTEXT_SPECIFIC && pin_info) { + int auth_meth_saved = pin_info->auth_method; + + sc_log(context, "Setting SC_AC_CONTEXT_SPECIFIC"); + pin_info->auth_method = SC_AC_CONTEXT_SPECIFIC; + rc = sc_pkcs15_verify_pin(p15card, auth_object, pPin, ulPinLen); + pin_info->auth_method = auth_meth_saved; + } else + rc = sc_pkcs15_verify_pin(p15card, auth_object, pPin, ulPinLen); + sc_log(context, "PKCS15 verify PIN returned %d", rc); if (rc != SC_SUCCESS) From efe7eb598fed5a92e097bc355cdec8239d86f151 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 8 Feb 2018 20:08:43 -0600 Subject: [PATCH 0181/4321] Some CAC / PIV cards do not support Discovery Object Some CAC card return '6A80` Incorrect parameters in APDU when trying to read the Discovery object. If it fails other then not found, then we can not use the Discovery object to test for the active AID. The test is done in piv_match_card just after doing a SELECT AID for the PIV. and set CI_DISCOVERY_USELESS if needed. piv_card_reader_lock_obtained will then not use the Discovery object. Some older PIV cards, prior to the introduction of the PIV Discovery and History objects, may get errors trying to read them. Ignore these errors too. Remove comment and remove code to check verify Lc=0 as requested in: https://github.com/OpenSC/OpenSC/pull/1256#pullrequestreview-96124443 They can easily be added back in. On branch piv-aid-discovery Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 59 +++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 7cdb93ff5b..63d80ccac5 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -213,6 +213,7 @@ static struct piv_aid piv_aids[] = { /* will also test after first PIN verify if protected object can be used instead */ #define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */ #define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */ +#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */ #define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */ #define CI_NFC_EXPOSE_TOO_MUCH 0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */ @@ -2662,7 +2663,6 @@ static int piv_process_discovery(sc_card_t *card) } -/* Do not use the cache value but read every time */ static int piv_find_discovery(sc_card_t *card) { int r = 0; @@ -2957,7 +2957,7 @@ piv_finish(sc_card_t *card) static int piv_match_card(sc_card_t *card) { - int i, k; + int i, i7e, k; size_t j; u8 *p, *pe; sc_file_t aidfile; @@ -3058,7 +3058,7 @@ static int piv_match_card(sc_card_t *card) * We may get interference on some cards by other drivers trying SELECT_AID before * we get to see if PIV application is still active. * putting PIV driver first might help. - * TODO could be cached too + * This may fail if the wrong AID is active */ i = piv_find_discovery(card); @@ -3067,6 +3067,22 @@ static int piv_match_card(sc_card_t *card) i = piv_find_aid(card, &aidfile); } + if (i >= 0) { + /* + * We now know PIV AID is active, test DISCOVERY object + * Some CAC cards with PIV don't support DISCOVERY and return + * SC_ERROR_INCORRECT_PARAMETERS. Any error other then + * SC_ERROR_FILE_NOT_FOUND means we cannot use discovery + * to test for active AID. + */ + i7e = piv_find_discovery(card); + if (i7e != 0 && i7e != SC_ERROR_FILE_NOT_FOUND) { + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + } + } + + if (i < 0) { piv_finish(card); /* don't match. Does not have a PIV applet. */ @@ -3083,7 +3099,7 @@ static int piv_match_card(sc_card_t *card) static int piv_init(sc_card_t *card) { - int r; + int r = 0; piv_private_data_t * priv = PIV_DATA(card); sc_apdu_t apdu; unsigned long flags; @@ -3136,7 +3152,7 @@ static int piv_init(sc_card_t *card) switch(card->type) { case SC_CARD_TYPE_PIV_II_NEO: - priv->card_issues = CI_NO_EC384 + priv->card_issues |= CI_NO_EC384 | CI_VERIFY_630X | CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND @@ -3146,18 +3162,18 @@ static int piv_init(sc_card_t *card) break; case SC_CARD_TYPE_PIV_II_YUBIKEY4: - priv->card_issues = CI_OTHER_AID_LOSE_STATE + priv->card_issues |= CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND; if (priv->neo_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; break; case SC_CARD_TYPE_PIV_II_HIST: - priv->card_issues = 0; + priv->card_issues |= 0; break; case SC_CARD_TYPE_PIV_II_GENERIC: - priv->card_issues = CI_VERIFY_LC0_FAIL + priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE; /* TODO may need more research */ break; @@ -3196,12 +3212,13 @@ static int piv_init(sc_card_t *card) * 800-73-3 cards may have a history object and/or a discovery object * We want to process them now as this has information on what * keys and certs the card has and how the pin might be used. + * If they fail, ignore it there are optional and introdced in + * NIST 800-73-3 and NIST 800-73-2 so some older cards may + * not handle the requets. */ piv_process_history(card); - r = piv_process_discovery(card); - if (r > 0) - r = 0; + piv_process_discovery(card); priv->pstate=PIV_STATE_NORMAL; sc_unlock(card) ; /* obtained in piv_match */ @@ -3477,7 +3494,6 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) int r = 0; u8 temp[256]; size_t templen = sizeof(temp); - struct sc_pin_cmd_data data; piv_private_data_t * priv = PIV_DATA(card); /* may be null */ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -3494,7 +3510,14 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) /* first see if AID is active AID by reading discovery object '7E' */ /* If not try selecting AID */ - r = piv_find_discovery(card); + + /* but if x card does not support DISCOVERY object we can not use it */ + if (priv->card_issues & CI_DISCOVERY_USELESS) { + r = SC_ERROR_NO_CARD_SUPPORT; + } else { + r = piv_find_discovery(card); + } + if (r < 0) r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); @@ -3504,15 +3527,7 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) if (was_reset > 0) priv->logged_in = SC_PIN_STATE_UNKNOWN; - /* See if VERIFY Lc=empty will tell us the state */ - memset(&data, 0, sizeof(data)); - data.cmd = SC_PIN_CMD_GET_INFO; - data.pin_type = SC_AC_CHV; - data.pin_reference = priv->pin_preference; - /* will try our best to see if logged_in or not */ - r = piv_pin_cmd(card, &data, NULL); - - r = 0; /* ignore return from piv_pin_cmd */ + r = 0; err: LOG_FUNC_RETURN(card->ctx, r); From aee62c7c67da111ffe4db881670e6d95dba92ed2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 13 Feb 2018 15:54:38 -0600 Subject: [PATCH 0182/4321] Requested changed to not rely on success *_match_card being followed by *_init As requested and as the alternative solution see: https://github.com/OpenSC/OpenSC/pull/1256#issuecomment-365319444 In order to not pass a card lock and the card->drv_data from piv_match_card piv_match_card is split in 2 parts. the piv_match_card_continued is called from piv_init. piv_init may now return with SC_ERROR_INVALID_CARD to single to sc_connect_card to look for additional drivers. Cosmetic change to indicate neo_version is really a Yubico version. Change wording on the comments when setting card_issues. On branch piv-aid-discovery Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 79 +++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 63d80ccac5..af6dc44568 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -175,7 +175,7 @@ typedef struct piv_private_data { int tries_left; /* SC_PIN_CMD_GET_INFO tries_left from last */ unsigned int card_issues; /* card_issues flags for this card */ int object_test_verify; /* Can test this object to set verification state of card */ - int neo_version; /* 3 byte version number of NEO or Ybuikey4 as integer */ + int yubico_version; /* 3 byte version number of NEO or Ybuikey4 as integer */ } piv_private_data_t; #define PIV_DATA(card) ((piv_private_data_t*)card->drv_data) @@ -825,7 +825,7 @@ static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file) r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->type != 0 && card->type == piv_aids[i].enumtag) - LOG_FUNC_RETURN(card->ctx, i); + LOG_FUNC_RETURN(card->ctx, (r < 0)? r: i); continue; } @@ -2949,13 +2949,33 @@ piv_finish(sc_card_t *card) free(priv->obj_cache[i].internal_obj_data); } free(priv); - card->drv_data = NULL; /* priv */ + card->drv_data = NULL; /* priv */ } return 0; } - static int piv_match_card(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* piv_match_card may be called with card->type, set by opensc.conf */ + /* user provide card type must be one we know */ + switch (card->type) { + case -1: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + break; + default: + return 0; /* can not handle the card */ + } + /* its one we know, or we can test for it in piv_init */ + return 1; /* Let piv_init finish matching */ +} + + +static int piv_match_card_continued(sc_card_t *card) { int i, i7e, k; size_t j; @@ -3100,18 +3120,28 @@ static int piv_match_card(sc_card_t *card) static int piv_init(sc_card_t *card) { int r = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t * priv = NULL; sc_apdu_t apdu; unsigned long flags; unsigned long ext_flags; - u8 neo_version_buf[3]; + u8 yubico_version_buf[3]; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* continue the matching get a lock and the priv */ + r = piv_match_card_continued(card); + if (r != 1) { + sc_log(card->ctx,"piv_match_card_continued failed"); + piv_finish(card); + /* tell sc_connect_card to try other drivers */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } + + priv = PIV_DATA(card); - /* can not force the PIV driver to use non-PIV cards as tested in piv_card_match */ + /* can not force the PIV driver to use non-PIV cards as tested in piv_card_match_continued */ if (!priv || card->type == -1) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); sc_log(card->ctx, "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type = %d", @@ -3131,23 +3161,28 @@ static int piv_init(sc_card_t *card) apdu.lc = 0; apdu.data = NULL; apdu.datalen = 0; - apdu.resp = neo_version_buf; - apdu.resplen = sizeof(neo_version_buf); + apdu.resp = yubico_version_buf; + apdu.resplen = sizeof(yubico_version_buf); apdu.le = apdu.resplen; r = sc_transmit_apdu(card, &apdu); - priv->neo_version = (neo_version_buf[0]<<16) | (neo_version_buf[1] <<8) | neo_version_buf[2]; - sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->neo_version); + priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; + sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); break; } /* - * set card_issues flags based card->type and new versions - * YubiKey NEO and Ybuikey 4 have PIV applets, with compliance issues - * with the the NIST 800-73-3 specs The OpenSC developers do not have - * access to the different versions the NEO and 4, so it is a best - * if using a protected object can be use to test verify state. - * TODO use NEO version numbers to set the flags. Allows for finer control - * but needs input from Yubico or users. + * Set card_issues flags based card->type and version numbers if available. + * + * YubiKey NEO, Yubikey 4 and other devices with PIV applets, have compliance + * issues with the NIST 800-73-3 specs. The OpenSC developers do not have + * access to all the different devices or versions of the devices. + * Vendor and user input is welcome on any compliance issues. + * + * For the Yubico devices The assumption is also made that if a bug is + * fixed in a Yubico version that means it is fixed on both NEO and Yubikey 4. + * + * The flags CI_CANT_USE_GETDATA_FOR_STATE and CI_DISCOVERY_USELESS + * may be set earlier or later then in the following code. */ switch(card->type) { @@ -3157,14 +3192,14 @@ static int piv_init(sc_card_t *card) | CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND | CI_NFC_EXPOSE_TOO_MUCH; - if (priv->neo_version < 0x00040302) + if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; break; case SC_CARD_TYPE_PIV_II_YUBIKEY4: priv->card_issues |= CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND; - if (priv->neo_version < 0x00040302) + if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; break; @@ -3220,6 +3255,8 @@ static int piv_init(sc_card_t *card) piv_process_discovery(card); + r = 0; + priv->pstate=PIV_STATE_NORMAL; sc_unlock(card) ; /* obtained in piv_match */ LOG_FUNC_RETURN(card->ctx, r); From 4222036a60c92701d1ef233734463182f2410484 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 28 Feb 2018 13:49:14 -0600 Subject: [PATCH 0183/4321] PIV completely separate piv_match_card from piv_init In order to satisfy some concerns over the use of _match_card and _init, this modification will do that at the cost of additional overhead of repeating some card commands. Hopefully this commit will not be needed. On branch piv-aid-discovery Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index af6dc44568..c291374dd7 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -403,6 +403,7 @@ static struct sc_card_driver piv_drv = { NULL, 0, NULL }; +static int piv_match_card_continued(sc_card_t *card); static int piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) @@ -2956,6 +2957,8 @@ piv_finish(sc_card_t *card) static int piv_match_card(sc_card_t *card) { + int r = 0; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* piv_match_card may be called with card->type, set by opensc.conf */ @@ -2971,7 +2974,20 @@ static int piv_match_card(sc_card_t *card) return 0; /* can not handle the card */ } /* its one we know, or we can test for it in piv_init */ - return 1; /* Let piv_init finish matching */ + /* + * We will call piv_match_card_continued here then + * again in piv_init to avoid any issues with passing + * anything from piv_match_card + * to piv_init as had been done in the past + */ + r = piv_match_card_continued(card); + if (r == 1) { + /* clean up what we left in card */ + sc_unlock(card); + piv_finish(card); + } + + return r; } @@ -3104,14 +3120,13 @@ static int piv_match_card_continued(sc_card_t *card) if (i < 0) { - piv_finish(card); /* don't match. Does not have a PIV applet. */ sc_unlock(card); + piv_finish(card); return 0; } - /* Matched, and priv is being passed to piv_init */ - /* hold the lock and pass to piv_init */ + /* Matched, caller will use or free priv and sc_lock as needed */ priv->pstate=PIV_STATE_INIT; return 1; /* match */ } From b05273b01e814fb37f1e4edafa07d1c3e5e196d3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Feb 2018 14:45:54 +0100 Subject: [PATCH 0184/4321] starcos: fixed key reference for "local" key id --- src/libopensc/card-starcos.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 74bd253d45..3998f0cdda 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1338,7 +1338,11 @@ static int starcos_set_security_env(sc_card_t *card, * algorithm / cipher from PKCS#1 padding prefix */ *p++ = 0x84; *p++ = 0x01; - *p++ = *env->key_ref; + if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { + *p++ = *env->key_ref | 0x80; + } else { + *p++ = *env->key_ref; + } /* algorithm / cipher selector? */ *p++ = 0x89; From e2ba2f81926760c0dc816f0a61b16a11743c57c6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Feb 2018 17:46:10 +0100 Subject: [PATCH 0185/4321] Starcos 3.4: implemented PSO:DEC --- src/libopensc/card-starcos.c | 90 ++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 3998f0cdda..5efecc18a2 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1321,19 +1321,11 @@ static int starcos_set_security_env(sc_card_t *card, p = sbuf; if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { - if (operation != SC_SEC_OPERATION_SIGN) { - /* we only support signatures for now */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "not supported for STARCOS 3.4 cards"); - return SC_ERROR_NOT_SUPPORTED; \ - } - if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); /* don't know what these mean but doesn't matter as card seems to take * algorithm / cipher from PKCS#1 padding prefix */ *p++ = 0x84; @@ -1344,11 +1336,26 @@ static int starcos_set_security_env(sc_card_t *card, *p++ = *env->key_ref; } - /* algorithm / cipher selector? */ - *p++ = 0x89; - *p++ = 0x02; - *p++ = 0x13; - *p++ = 0x23; + switch (operation) { + case SC_SEC_OPERATION_SIGN: + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); + + /* algorithm / cipher selector? */ + *p++ = 0x89; + *p++ = 0x02; + *p++ = 0x13; + *p++ = 0x23; + break; + + case SC_SEC_OPERATION_DECIPHER: + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); + break; + + default: + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "not supported for STARCOS 3.4 cards"); + return SC_ERROR_NOT_SUPPORTED; + } apdu.data = sbuf; apdu.datalen = p - sbuf; @@ -1604,6 +1611,62 @@ static int starcos_compute_signature(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } +static int starcos_decipher(struct sc_card *card, + const u8 * crgram, size_t crgram_len, + u8 * out, size_t outlen) +{ + if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + int r; + size_t card_max_send_size = card->max_send_size; + size_t reader_max_send_size = card->reader->max_send_size; + int caps = card->caps; + sc_apdu_t apdu; + + u8 *sbuf = malloc(crgram_len + 1); + if (sbuf == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86); + apdu.resp = out; + apdu.resplen = outlen; + apdu.le = outlen; + + sbuf[0] = 0x81; + memcpy(sbuf + 1, crgram, crgram_len); + apdu.data = sbuf; + apdu.lc = crgram_len + 1; + apdu.datalen = crgram_len + 1; + + if (sc_get_max_send_size(card) < crgram_len + 1) { + /* Starcos doesn't support chaining for PSO:DEC, so we just _hope_ + * that both, the reader and the card are able to send enough data. + * (data is prefixed with 1 byte padding content indicator) */ + card->max_send_size = crgram_len + 1; + card->reader->max_send_size = crgram_len + 1; + card->caps |= SC_CARD_CAP_APDU_EXT; + } + + r = sc_transmit_apdu(card, &apdu); + sc_mem_clear(sbuf, crgram_len + 1); + + /* reset whatever we've modified above */ + card->max_send_size = card_max_send_size; + card->reader->max_send_size = reader_max_send_size; + card->caps = caps; + + free(sbuf); + + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + LOG_FUNC_RETURN(card->ctx, apdu.resplen); + else + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } else { + return iso_ops->decipher(card, crgram, crgram_len, out, outlen); + } +} + static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) { const int err_count = sizeof(starcos_errors)/sizeof(starcos_errors[0]); @@ -1771,6 +1834,7 @@ static struct sc_card_driver * sc_get_driver(void) starcos_ops.delete_file = NULL; starcos_ops.set_security_env = starcos_set_security_env; starcos_ops.compute_signature = starcos_compute_signature; + starcos_ops.decipher = starcos_decipher; starcos_ops.card_ctl = starcos_card_ctl; starcos_ops.logout = starcos_logout; starcos_ops.pin_cmd = starcos_pin_cmd; From c3ffdecd0be586dc45e2402d40c1f2a3c43ea2ff Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 21 Feb 2018 14:07:53 +0100 Subject: [PATCH 0186/4321] rename SC_SEC_ENV_KEY_REF_ASYMMETRIC to SC_SEC_ENV_KEY_REF_SYMMETRIC This reflects the actual use of the identifier by the card drivers. --- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-isoApplet.c | 2 +- src/libopensc/card-myeid.c | 8 ++++---- src/libopensc/card-setcos.c | 6 +++--- src/libopensc/card-starcos.c | 2 +- src/libopensc/card-tcos.c | 2 +- src/libopensc/iso7816.c | 2 +- src/libopensc/opensc.h | 3 +-- 9 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 33496b7376..a26b43ab3a 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -551,7 +551,7 @@ static int atrust_acos_set_security_env(struct sc_card *card, /* copy key reference, if present */ if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 73b0c9a6db..34b4ce753f 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -773,7 +773,7 @@ static int gids_set_security_env(sc_card_t *card, if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); } - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 4cf865a310..d9b92af913 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1141,7 +1141,7 @@ isoApplet_set_security_env(sc_card_t *card, if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index b7dafed7b7..88eef9e972 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -614,9 +614,9 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * assert(card != NULL && env != NULL); LOG_FUNC_CALLED(card->ctx); - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) { - sc_log(card->ctx, "asymmetric keyref not supported.\n"); + sc_log(card->ctx, "symmetric keyref not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (se_num > 0) @@ -697,9 +697,9 @@ static int myeid_set_security_env_ec(sc_card_t *card, const sc_security_env_t *e assert(card != NULL && env != NULL); LOG_FUNC_CALLED(card->ctx); - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) { - sc_log(card->ctx, "asymmetric keyref not supported."); + sc_log(card->ctx, "symmetric keyref not supported."); return SC_ERROR_NOT_SUPPORTED; } if (se_num > 0) diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index a852180aee..4152709436 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -574,8 +574,8 @@ static int setcos_set_security_env2(sc_card_t *card, if (card->type == SC_CARD_TYPE_SETCOS_44 || card->type == SC_CARD_TYPE_SETCOS_NIDEL || SETCOS_IS_EID_APPLET(card)) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "asymmetric keyref not supported.\n"); + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "symmetric keyref not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (se_num > 0) { @@ -619,7 +619,7 @@ static int setcos_set_security_env2(sc_card_t *card, if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && !(card->type == SC_CARD_TYPE_SETCOS_NIDEL || card->type == SC_CARD_TYPE_SETCOS_FINEID_V2_2048)) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 5efecc18a2..2e52836fda 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1378,7 +1378,7 @@ static int starcos_set_security_env(sc_card_t *card, /* copy key reference, if present */ if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index c8a05afb47..3a885e943c 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -546,7 +546,7 @@ static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, p = sbuf; *p++=0x80; *p++=0x01; *p++=tcos3 ? 0x0A : 0x10; if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - *p++ = (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) ? 0x83 : 0x84; + *p++ = (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) ? 0x83 : 0x84; *p++ = env->key_ref_len; memcpy(p, env->key_ref, env->key_ref_len); p += env->key_ref_len; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index e5916e7dd4..5ca5286a94 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -849,7 +849,7 @@ iso7816_set_security_env(struct sc_card *card, p += env->file_ref.len; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else *p++ = 0x84; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 943d55da3f..6e121a1d66 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -62,8 +62,7 @@ extern "C" { #define SC_SEC_ENV_ALG_REF_PRESENT 0x0001 #define SC_SEC_ENV_FILE_REF_PRESENT 0x0002 #define SC_SEC_ENV_KEY_REF_PRESENT 0x0004 -/* FIXME: the flag below is misleading */ -#define SC_SEC_ENV_KEY_REF_ASYMMETRIC 0x0008 +#define SC_SEC_ENV_KEY_REF_SYMMETRIC 0x0008 #define SC_SEC_ENV_ALG_PRESENT 0x0010 /* PK algorithms */ From d29bdf9da0712ddade161fd684ca532b757f4cdf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Feb 2018 19:48:28 +0100 Subject: [PATCH 0187/4321] md: register starcos cards --- src/libopensc/card-starcos.c | 6 +++--- win32/customactions.cpp | 12 +++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 2e52836fda..17c4578a91 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -44,7 +44,7 @@ static struct sc_card_operations starcos_ops; static struct sc_card_operations *iso_ops = NULL; static struct sc_card_driver starcos_drv = { - "STARCOS SPK 2.3/2.4/3.4", + "STARCOS", "starcos", &starcos_ops, NULL, 0, NULL @@ -113,7 +113,7 @@ static int starcos_init(sc_card_t *card) if (ex_data == NULL) return SC_ERROR_OUT_OF_MEMORY; - card->name = "STARCOS SPK 2.3"; + card->name = "STARCOS"; card->cla = 0x00; card->drv_data = (void *)ex_data; @@ -129,7 +129,7 @@ static int starcos_init(sc_card_t *card) card->caps = SC_CARD_CAP_RNG; if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { - card->name = "STARCOS SPK 3.4"; + card->name = "STARCOS 3.4"; card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; flags |= SC_CARD_FLAG_RNG diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 9380384d64..b5bcef9269 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -134,7 +134,17 @@ MD_REGISTRATION minidriver_registration[] = { {TEXT("CardOS v5.0"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x01,0x14}, 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("JPKI"), {0x3b,0xe0,0x00,0xff,0x81,0x31,0xfe,0x45,0x14}, - 9, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + 9, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + + /* from card-starcos.c */ + {TEXT("STARCOS (a)"), {0x3B,0xB7,0x94,0x00,0xc0,0x24,0x31,0xfe,0x65,0x53,0x50,0x4b,0x32,0x33,0x90,0x00,0xb4}, + 17, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS (b)"), {0x3B,0xB7,0x94,0x00,0x81,0x31,0xfe,0x65,0x53,0x50,0x4b,0x32,0x33,0x90,0x00,0xd1}, + 16, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS (c)"), {0x3b,0xb7,0x18,0x00,0xc0,0x3e,0x31,0xfe,0x65,0x53,0x50,0x4b,0x32,0x34,0x90,0x00,0x25}, + 17, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.4"), {0x3b,0xd8,0x18,0xff,0x81,0xb1,0xfe,0x45,0x1f,0x03,0x80,0x64,0x04,0x1a,0xb4,0x03,0x81,0x05,0x61}, + 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, }; From e8e8153cda9e66a10fdcd1f622fa9de4f1940579 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Feb 2018 13:29:54 +0100 Subject: [PATCH 0188/4321] md: prevent endless loop for card without sn --- src/minidriver/minidriver.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 435ba96412..ddd1f09d70 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1312,12 +1312,16 @@ md_set_cardid(PCARD_DATA pCardData, struct md_file *file) memcpy(sn_bin, vs->p15card->tokeninfo->serial_number, sn_len); } - for (offs=0; offs < MD_CARDID_SIZE; ) { - wr = MD_CARDID_SIZE - offs; - if (wr > sn_len) - wr = sn_len; - memcpy(cardid_bin + offs, sn_bin, wr); - offs += wr; + if (sn_len > 0) { + for (offs=0; offs < MD_CARDID_SIZE; ) { + wr = MD_CARDID_SIZE - offs; + if (wr > sn_len) + wr = sn_len; + memcpy(cardid_bin + offs, sn_bin, wr); + offs += wr; + } + } else { + memset(cardid_bin, 0, MD_CARDID_SIZE); } dwret = md_fs_set_content(pCardData, file, cardid_bin, MD_CARDID_SIZE); From b403934718daec2d09d456edce230b55a9b8590d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Feb 2018 13:58:39 +0100 Subject: [PATCH 0189/4321] PKCS#15: prevent use of empty serial number in TokenInfo ... and initialize the serial number with the card's serial number if nothing useful is in EF.TokenInfo --- src/libopensc/pkcs15.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 3e0588631a..892d424401 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -207,7 +207,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL); LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed"); - if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT) { + if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0) { ti->serial_number = malloc(serial_len * 2 + 1); if (ti->serial_number == NULL) return SC_ERROR_OUT_OF_MEMORY; @@ -1188,6 +1188,10 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) *(p15card->tokeninfo) = tokeninfo; + if (!p15card->tokeninfo->serial_number && 0 == card->serialnr.len) { + sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &card->serialnr); + } + if (!p15card->tokeninfo->serial_number && card->serialnr.len) { char *serial = calloc(1, card->serialnr.len*2 + 1); size_t ii; From 196c8389572b72fa1b837c209d798185cb58686f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Feb 2018 23:15:03 +0100 Subject: [PATCH 0190/4321] fixed use after free ICCSN and CHN pointed into EF.GDO's content, which was freed preemptively. Regression of 0502a839c654555220964e9f4d58ca508471472e --- src/libopensc/card-starcos.c | 12 ++++----- src/libopensc/card-tcos.c | 13 ++++------ src/libopensc/ef-gdo.c | 43 +++++++++++++++---------------- src/libopensc/opensc.h | 4 +-- src/libopensc/pkcs15-infocamere.c | 13 ++++++---- src/libopensc/pkcs15-tccardos.c | 10 +++---- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 17c4578a91..f31a1f0068 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1700,8 +1700,6 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) { int r; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - const unsigned char *iccsn; - size_t iccsn_len; sc_apdu_t apdu; if (!serial) @@ -1715,12 +1713,12 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) switch (card->type) { case SC_CARD_TYPE_STARCOS_V3_4: - r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); - if (r < 0) + card->serialnr.len = SC_MAX_SERIALNR; + r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); + if (r < 0) { + card->serialnr.len = 0; return r; - /* cache serial number */ - memcpy(card->serialnr.value, iccsn, MIN(iccsn_len, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(iccsn_len, SC_MAX_SERIALNR); + } break; default: diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 3a885e943c..6221017cb6 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -707,8 +707,6 @@ static int tcos_setperm(sc_card_t *card, int enable_nullpin) static int tcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) { int r; - const unsigned char *iccsn; - size_t iccsn_len; if (!serial) return SC_ERROR_INVALID_ARGUMENTS; @@ -719,13 +717,12 @@ static int tcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) return SC_SUCCESS; } - r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); - if (r < 0) + card->serialnr.len = sizeof card->serialnr.value; + r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); + if (r < 0) { + card->serialnr.len = 0; return r; - - /* cache serial number */ - memcpy(card->serialnr.value, iccsn, MIN(iccsn_len, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(iccsn_len, SC_MAX_SERIALNR); + } /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index d1017f755e..bda51f220b 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -24,25 +24,17 @@ #include "asn1.h" #include "internal.h" #include +#include static int sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, - const unsigned char **iccsn, size_t *iccsn_len, - const unsigned char **chn, size_t *chn_len) + unsigned char *iccsn, size_t *iccsn_len, + unsigned char *chn, size_t *chn_len) { - int r = SC_SUCCESS; + int r = SC_SUCCESS, iccsn_found = 0, chn_found = 0; const unsigned char *p = gdo; size_t left = gdo_len; - if (iccsn) - *iccsn = NULL; - if (iccsn_len) - *iccsn_len = 0; - if (chn) - *chn = NULL; - if (chn_len) - *chn_len = 0; - while (left >= 2) { unsigned int cla, tag; size_t tag_len; @@ -63,16 +55,18 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, if (cla == SC_ASN1_TAG_APPLICATION) { switch (tag) { case 0x1A: - if (iccsn) - *iccsn = p; - if (iccsn_len) - *iccsn_len = tag_len; + iccsn_found = 1; + if (iccsn && iccsn_len) { + memcpy(iccsn, p, MIN(tag_len, *iccsn_len)); + *iccsn_len = MIN(tag_len, *iccsn_len); + } break; case 0x1F20: - if (chn) - *chn = p; - if (chn_len) - *chn_len = tag_len; + chn_found = 1; + if (chn && chn_len) { + memcpy(chn, p, MIN(tag_len, *chn_len)); + *chn_len = MIN(tag_len, *chn_len); + } break; } } @@ -81,6 +75,11 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, left -= (p - gdo); } + if (!iccsn_found && iccsn_len) + *iccsn_len = 0; + if (!chn_found && chn_len) + *chn_len = 0; + return r; } @@ -88,8 +87,8 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, int sc_parse_ef_gdo(struct sc_card *card, - const unsigned char **iccsn, size_t *iccsn_len, - const unsigned char **chn, size_t *chn_len) + unsigned char *iccsn, size_t *iccsn_len, + unsigned char *chn, size_t *chn_len) { struct sc_context *ctx; struct sc_path path; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6e121a1d66..be4f905582 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1336,8 +1336,8 @@ void sc_free_apps(struct sc_card *card); int sc_parse_ef_atr(struct sc_card *card); void sc_free_ef_atr(struct sc_card *card); int sc_parse_ef_gdo(struct sc_card *card, - const unsigned char **iccsn, size_t *iccsn_len, - const unsigned char **chn, size_t *chn_len); + unsigned char *iccsn, size_t *iccsn_len, + unsigned char *chn, size_t *chn_len); int sc_update_dir(struct sc_card *card, sc_app_info_t *app); void sc_print_cache(struct sc_card *card); diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index 02c55ee36d..6532ffc508 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -234,18 +234,21 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) int r; - const unsigned char *iccsn, *chn; - size_t iccsn_len, chn_len; + unsigned char chn[8]; + size_t chn_len = sizeof chn; + sc_serial_number_t iccsn; + iccsn.len = sizeof iccsn.value; - r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, &chn, &chn_len); + + r = sc_parse_ef_gdo(card, iccsn.value, &iccsn.len, chn, &chn_len); if (r < 0) return r; - if (!iccsn_len || chn_len < 2 || chn_len > 8) { + if (!iccsn.len || chn_len < 2 || chn_len > 8) { return SC_ERROR_WRONG_CARD; } - sc_bin_to_hex(iccsn, iccsn_len, serial, sizeof(serial), 0); + sc_bin_to_hex(iccsn.value, iccsn.len, serial, sizeof(serial), 0); if (! (chn[0] == 0x12 diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index d8986a9dc5..8792cf1566 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -305,9 +305,9 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) struct sc_path path; struct sc_file *file = NULL; char hex_buf[256]; - const unsigned char *iccsn; - size_t iccsn_len; struct sc_card *card = p15card->card; + sc_serial_number_t iccsn; + iccsn.len = sizeof iccsn.value; /* check if we have the correct card OS */ if (strcmp(card->name, "CardOS M4")) @@ -329,10 +329,10 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) if (p15card->tokeninfo->manufacturer_id == NULL) return SC_ERROR_OUT_OF_MEMORY; /* set the serial number */ - r = sc_parse_ef_gdo(card, &iccsn, &iccsn_len, NULL, 0); - if (r != SC_SUCCESS || iccsn_len < 5+8) + r = sc_parse_ef_gdo(card, iccsn.value, &iccsn.len, NULL, 0); + if (r != SC_SUCCESS || iccsn.len < 5+8) return SC_ERROR_INTERNAL; - sc_bin_to_hex(iccsn + 5, 8, hex_buf, sizeof(hex_buf), 0); + sc_bin_to_hex(iccsn.value + 5, 8, hex_buf, sizeof(hex_buf), 0); p15card->tokeninfo->serial_number = strdup(hex_buf); if (p15card->tokeninfo->serial_number == NULL) return SC_ERROR_OUT_OF_MEMORY; From 01810fcb664416d9e749a9cc717acdf17c34c38f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Feb 2018 09:30:38 +0100 Subject: [PATCH 0191/4321] STARCOS: Added support for 3.5 ATR and differences between 3.4/3.5 are based on https://github.com/CardContact/sc-hsm-embedded Actually, 3.5 is untested, but 3.4 is almost identical, so we hope that for 3.5 everything is fine. --- src/libopensc/card-starcos.c | 55 +++++++++++++++++++++++++++--------- src/libopensc/cards.h | 1 + 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index f31a1f0068..1864844982 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -35,8 +35,13 @@ static struct sc_atr_table starcos_atrs[] = { { "3B:B7:94:00:c0:24:31:fe:65:53:50:4b:32:33:90:00:b4", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3B:B7:94:00:81:31:fe:65:53:50:4b:32:33:90:00:d1", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3b:b7:18:00:c0:3e:31:fe:65:53:50:4b:32:34:90:00:25", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, - /* STARCOS 3.4 */ { "3b:d8:18:ff:81:b1:fe:45:1f:03:80:64:04:1a:b4:03:81:05:61", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, + { "3B:9B:96:C0:0A:31:FE:45:80:67:04:1E:B5:01:00:89:4C:81:05:45", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:DB:96:FF:81:31:FE:45:80:67:05:34:B5:02:01:C0:A1:81:05:3C", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:C0:81:05:02", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:DF:96:FF:81:31:FE:45:80:5B:44:45:2E:42:4E:4F:54:4B:31:31:31:81:05:A0", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:DF:96:FF:81:31:FE:45:80:5B:44:45:2E:42:4E:4F:54:4B:31:30:30:81:05:A0", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:E0:81:05:22", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -128,8 +133,12 @@ static int starcos_init(sc_card_t *card) card->caps = SC_CARD_CAP_RNG; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { - card->name = "STARCOS 3.4"; + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4) + card->name = "STARCOS 3.4"; + else + card->name = "STARCOS 3.5"; card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; flags |= SC_CARD_FLAG_RNG @@ -512,7 +521,8 @@ static int starcos_select_fid(sc_card_t *card, apdu.data = (u8*)data; apdu.datalen = 2; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { if (id_hi == 0x3f && id_lo == 0x0) { apdu.p1 = 0x0; apdu.p2 = 0x0; @@ -540,7 +550,9 @@ static int starcos_select_fid(sc_card_t *card, apdu.le = 0; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); - } else if (card->type == SC_CARD_TYPE_STARCOS_V3_4 && apdu.p2 == 0x4 && apdu.sw1 == 0x6a && apdu.sw2 == 0x82) { + } else if ((card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) + && apdu.p2 == 0x4 && apdu.sw1 == 0x6a && apdu.sw2 == 0x82) { /* not a file, could be a path */ bIsDF = 1; apdu.p1 = 0x1; @@ -604,7 +616,8 @@ static int starcos_select_fid(sc_card_t *card, *file_out = file; } else { /* ok, assume we have a EF */ - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { if (isFCP) { r = process_fcp_v3_4(card->ctx, file, apdu.resp, apdu.resplen); @@ -691,8 +704,9 @@ static int starcos_select_file(sc_card_t *card, if (pathlen == 6 && ( path[0] != 0x3f || path[1] != 0x00 )) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - if (card->type != SC_CARD_TYPE_STARCOS_V3_4 || - (pathlen == 0 && card->cache.current_path.type != SC_PATH_TYPE_DF_NAME)) { + if (card->type != SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5 + || (pathlen == 0 && card->cache.current_path.type != SC_PATH_TYPE_DF_NAME)) { /* unify path (the first FID should be MF) */ if (path[0] != 0x3f || path[1] != 0x00) { @@ -717,9 +731,9 @@ static int starcos_select_file(sc_card_t *card, && card->cache.current_path.value[i+1] == path[i+1] ) bMatch += 2; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 && - bMatch > 0 && - (size_t) bMatch < card->cache.current_path.len) { + if ((card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) + && bMatch > 0 && (size_t) bMatch < card->cache.current_path.len) { /* we're in the wrong folder, start traversing from root */ bMatch = 0; card->cache.current_path.len = 0; @@ -1320,7 +1334,8 @@ static int starcos_set_security_env(sc_card_t *card, p = sbuf; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); @@ -1349,6 +1364,15 @@ static int starcos_set_security_env(sc_card_t *card, case SC_SEC_OPERATION_DECIPHER: sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); + + /* algorithm / cipher selector? */ + *p++ = 0x89; + *p++ = 0x02; + *p++ = 0x11; + if (card->type == SC_CARD_TYPE_STARCOS_V3_4) + *p++ = 0x30; + else + *p++ = 0x31; break; default: @@ -1503,7 +1527,8 @@ static int starcos_compute_signature(sc_card_t *card, if (ex_data->sec_ops == SC_SEC_OPERATION_SIGN) { /* compute signature with the COMPUTE SIGNATURE command */ - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { size_t tmp_len; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, @@ -1615,7 +1640,8 @@ static int starcos_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) { - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { int r; size_t card_max_send_size = card->max_send_size; size_t reader_max_send_size = card->reader->max_send_size; @@ -1713,6 +1739,7 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) switch (card->type) { case SC_CARD_TYPE_STARCOS_V3_4: + case SC_CARD_TYPE_STARCOS_V3_5: card->serialnr.len = SC_MAX_SERIALNR; r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); if (r < 0) { diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 41514532ce..e1a9d4469c 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -95,6 +95,7 @@ enum { SC_CARD_TYPE_STARCOS_BASE = 7000, SC_CARD_TYPE_STARCOS_GENERIC, SC_CARD_TYPE_STARCOS_V3_4, + SC_CARD_TYPE_STARCOS_V3_5, /* tcos driver */ SC_CARD_TYPE_TCOS_BASE = 8000, From 6f58a97906fead52dd4a859dd9fa2d86bb12f4bf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Feb 2018 16:55:00 +0100 Subject: [PATCH 0192/4321] md: added STARCOS 3.5 ATRs --- win32/customactions.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index b5bcef9269..a946566af0 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -145,6 +145,18 @@ MD_REGISTRATION minidriver_registration[] = { 17, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("STARCOS 3.4"), {0x3b,0xd8,0x18,0xff,0x81,0xb1,0xfe,0x45,0x1f,0x03,0x80,0x64,0x04,0x1a,0xb4,0x03,0x81,0x05,0x61}, 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (a)"), {0x3B,0x9B,0x96,0xC0,0x0A,0x31,0xFE,0x45,0x80,0x67,0x04,0x1E,0xB5,0x01,0x00,0x89,0x4C,0x81,0x05,0x45}, + 20, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (b)"), {0x3B,0xDB,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x67,0x05,0x34,0xB5,0x02,0x01,0xC0,0xA1,0x81,0x05,0x3C}, + 20, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (c)"), {0x3B,0xD9,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x31,0xB8,0x73,0x86,0x01,0xC0,0x81,0x05,0x02}, + 18, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (d)"), {0x3B,0xDF,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x5B,0x44,0x45,0x2E,0x42,0x4E,0x4F,0x54,0x4B,0x31,0x31,0x31,0x81,0x05,0xA0}, + 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (e)"), {0x3B,0xDF,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x5B,0x44,0x45,0x2E,0x42,0x4E,0x4F,0x54,0x4B,0x31,0x30,0x30,0x81,0x05,0xA0}, + 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("STARCOS 3.5 (f)"), {0x3B,0xD9,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x31,0xB8,0x73,0x86,0x01,0xE0,0x81,0x05,0x22}, + 18, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, }; From a97fc86cc93f35c37e11a59a645b8cba9cbf29e2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Feb 2018 21:54:50 +0100 Subject: [PATCH 0193/4321] starcos: reverted deactivation of pin cmd for 2.X It simply uses the implementation of iso7816. Fixes regression from 19bbfc76f5ace2ef17f2cb17f0315889e1607b39 --- src/libopensc/card-starcos.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 1864844982..450d32eb59 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -89,15 +89,6 @@ typedef struct starcos_ex_data_st { } \ } while (0); -#define CHECK_ONLY_SUPPORTED_V3_4(card) \ - do { \ - if ((card)->type != SC_CARD_TYPE_STARCOS_V3_4) { \ - sc_debug((card)->ctx, SC_LOG_DEBUG_NORMAL, \ - "only supported for STARCOS 3.4 cards"); \ - return SC_ERROR_NOT_SUPPORTED; \ - } \ - } while (0); - /* the starcos part */ static int starcos_match_card(sc_card_t *card) { @@ -1832,15 +1823,19 @@ static int starcos_logout(sc_card_t *card) static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { - int ret; - - CHECK_ONLY_SUPPORTED_V3_4(card); + int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); - data->flags |= SC_PIN_CMD_NEED_PADDING; - data->pin1.encoding = SC_PIN_ENCODING_GLP; - ret = iso_ops->pin_cmd(card, data, tries_left); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); + switch (card->type) { + case SC_CARD_TYPE_STARCOS_V3_4: + case SC_CARD_TYPE_STARCOS_V3_5: + data->flags |= SC_PIN_CMD_NEED_PADDING; + data->pin1.encoding = SC_PIN_ENCODING_GLP; + /* fall through */ + default: + r = iso_ops->pin_cmd(card, data, tries_left); + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static struct sc_card_driver * sc_get_driver(void) From 5d5caecfab968e5da2c137429b7c50b8ee5a5563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Casta=C3=B1eda=20Ferreira?= Date: Fri, 9 Mar 2018 14:37:38 +0100 Subject: [PATCH 0194/4321] Fix DNIe UI integration (#1280) --- configure.ac | 11 +++++++---- src/libopensc/card-dnie.c | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 9b319f28a7..80ae2fe40b 100644 --- a/configure.ac +++ b/configure.ac @@ -446,10 +446,13 @@ if test "${enable_dnie_ui}" = "yes"; then AC_DEFINE([ENABLE_DNIE_UI], [1], [Enable the use of external user interface program to request DNIe user pin]) case "${host}" in - *-*-darwin) - if test "${enable_dnie_ui}" = "yes"; then - LDFLAGS="${LDFLAGS} -framework Carbon" - fi + *-*-darwin*) + LDFLAGS="${LDFLAGS} -framework Carbon" + ;; + esac + case "${host}" in + *-apple-*) + LDFLAGS="${LDFLAGS} -framework CoreFoundation" ;; esac fi diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 076d4415c3..d55920c6b4 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -163,6 +163,7 @@ const char *user_consent_message="Esta a punto de realizar una firma digital\nco */ char *user_consent_msgs[] = { "SETTITLE", "SETDESC", "CONFIRM", "BYE" }; +#ifdef linux /** * Do fgets() without interruptions. * @@ -181,6 +182,7 @@ static char *nointr_fgets(char *s, int size, FILE *stream) } return s; } +#endif /** * Ask for user consent. From ea4baf50d57a7a41164fedcd1b10fdb0438305c5 Mon Sep 17 00:00:00 2001 From: AnthonyA Date: Mon, 19 Mar 2018 15:58:21 +0800 Subject: [PATCH 0195/4321] pkcs11-tool: make ECPoint behaviour standards compliant by default Fixes #1286. The behaviour of pkcs11-tool will follow the standard - send DER. If EC_POINT_NO_ASN1_OCTET_STRING is defined then it will write plain bytes. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 876bba2dcc..63e5c5f7fd 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2632,7 +2632,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) header_len = point-gost->public.value; memcpy(point, buf, point_len); gost->public.len = header_len+point_len; -#ifndef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding +#ifdef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding gost->public.len -= header_len; gost->public.value += header_len; #endif From 1ac08f96e762d98ef74f8599c71ee5eaf588e82a Mon Sep 17 00:00:00 2001 From: Vadim Penzin Date: Tue, 13 Mar 2018 22:49:22 +0200 Subject: [PATCH 0196/4321] epass2003: Fix buffer underrun in epass2003_decipher(), etc. 1. Buffer underrun in epass2003_decipher(). 2. The parameter `data' in update_secret_key() must be constant. (Discovered by Clang 4.0.0 on OpenBSD 6.2.) --- src/libopensc/card-epass2003.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 4c118b2c7d..c8611d15ff 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1695,23 +1695,18 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data if(exdata->currAlg == SC_ALGORITHM_EC) { - unsigned char hash[HASH_LEN] = { 0 }; if(exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA1) { - hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); - memset(sbuf, 0, sizeof(sbuf)); - memcpy(sbuf, hash, 0x14); apdu.data = sbuf; apdu.lc = 0x14; apdu.datalen = 0x14; } else if (exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA256) { - hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA256); + hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); - memset(sbuf, 0, sizeof(sbuf)); - memcpy(sbuf, hash, 0x20); apdu.data = sbuf; apdu.lc = 0x20; apdu.datalen = 0x20; @@ -2626,7 +2621,7 @@ external_key_auth(struct sc_card *card, unsigned char kid, static int update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, - unsigned char *data, unsigned long datalen) + const unsigned char *data, unsigned long datalen) { int r; struct sc_apdu apdu; @@ -2707,7 +2702,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */ - r = update_secret_key(card, 0x04, kid, (unsigned char *)data->pin2.data, + r = update_secret_key(card, 0x04, kid, data->pin2.data, (unsigned long)data->pin2.len); LOG_TEST_RET(card->ctx, r, "verify pin failed"); } From e1d6f0869bdac873878d72044bfc44d6ca5373b4 Mon Sep 17 00:00:00 2001 From: Vadim Penzin Date: Tue, 13 Mar 2018 22:56:32 +0200 Subject: [PATCH 0197/4321] Add missing initialisation of variables to pacify Clang. 1. src/libopensc/card-openpgp.c:pgp_store_key(). 2. src/libopensc/cwa14890.c:cwa_verify_icc_certificates(). 3. src/libopensc/cwa14890.c:cwa_prepare_external_auth(). 4. src/libopensc/pkcs15-itacns.c:itacns_check_and_add_keyset(). (Discovered by Clang 4.0.0 on OpenBSD 6.2.) --- src/libopensc/card-openpgp.c | 4 ++-- src/libopensc/cwa14890.c | 4 ++-- src/libopensc/pkcs15-itacns.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b34493dbc7..55c1939585 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2547,8 +2547,8 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) { sc_context_t *ctx = card->ctx; sc_cardctl_openpgp_keygen_info_t pubkey; - u8 *data; - size_t len; + u8 *data = NULL; + size_t len = 0; int r; LOG_FUNC_CALLED(ctx); diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index ab616e08a3..9cd850cc1a 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -328,7 +328,7 @@ static int cwa_verify_icc_certificates(sc_card_t * card, cwa_provider_t * provider, X509 * sub_ca_cert, X509 * icc_cert) { - char *msg; + char *msg = NULL; int res = SC_SUCCESS; EVP_PKEY *root_ca_key = NULL; EVP_PKEY *sub_ca_key = NULL; @@ -543,7 +543,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, then, we should encrypt with our private key and then with icc pub key returning resulting data */ - char *msg; /* to store error messages */ + char *msg = NULL; /* to store error messages */ int res = SC_SUCCESS; u8 *buf1; /* where to encrypt with icc pub key */ u8 *buf2; /* where to encrypt with ifd pub key */ diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 4941e78df8..fea3d52a5c 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -653,7 +653,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, sc_path_t path; sc_pkcs15_id_t cert_id; int ext_info_ok; - int ku, xku; + int ku = 0, xku = 0; int pubkey_usage_flags = 0, prkey_usage_flags = 0; cert_id.len = 1; From b643bbbe4022b8f766fb0b2ce982c644741ea810 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Mar 2018 14:23:58 +0100 Subject: [PATCH 0198/4321] fixed memory in case of a certificate parsing problem --- src/libopensc/pkcs15-cert.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index b7b16bb7a5..2f27a6e5c5 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -98,38 +98,40 @@ parse_x509_cert(sc_context_t *ctx, struct sc_pkcs15_der *der, struct sc_pkcs15_c cert->data.len = data_len; r = sc_asn1_decode(ctx, asn1_cert, obj, objlen, NULL, NULL); - LOG_TEST_RET(ctx, r, "ASN.1 parsing of certificate failed"); - + cert->key = pubkey; cert->version++; + LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 parsing of certificate failed"); + if (!pubkey) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Unable to decode subjectPublicKeyInfo from cert"); - cert->key = pubkey; + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Unable to decode subjectPublicKeyInfo from cert"); sc_asn1_clear_algorithm_id(&sig_alg); if (serial && serial_len) { sc_format_asn1_entry(asn1_serial_number + 0, serial, &serial_len, 1); r = sc_asn1_encode(ctx, asn1_serial_number, &cert->serial, &cert->serial_len); - free(serial); - LOG_TEST_RET(ctx, r, "ASN.1 encoding of serial failed"); + LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of serial failed"); } if (subject && subject_len) { sc_format_asn1_entry(asn1_subject + 0, subject, &subject_len, 1); r = sc_asn1_encode(ctx, asn1_subject, &cert->subject, &cert->subject_len); - free(subject); - LOG_TEST_RET(ctx, r, "ASN.1 encoding of subject"); + LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of subject"); } if (issuer && issuer_len) { sc_format_asn1_entry(asn1_issuer + 0, issuer, &issuer_len, 1); r = sc_asn1_encode(ctx, asn1_issuer, &cert->issuer, &cert->issuer_len); - free(issuer); - LOG_TEST_RET(ctx, r, "ASN.1 encoding of issuer"); + LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encoding of issuer"); } - return SC_SUCCESS; +err: + free(serial); + free(subject); + free(issuer); + + return r; } @@ -539,8 +541,7 @@ sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) return; } - if (cert->key) - sc_pkcs15_free_pubkey(cert->key); + sc_pkcs15_free_pubkey(cert->key); free(cert->subject); free(cert->issuer); free(cert->serial); @@ -555,7 +556,6 @@ sc_pkcs15_free_cert_info(sc_pkcs15_cert_info_t *cert) { if (!cert) return; - if (cert->value.value) - free(cert->value.value); + free(cert->value.value); free(cert); } From a84bf918af6d47e321d21e94dfc30c51ff0b020a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Mar 2018 14:48:07 +0100 Subject: [PATCH 0199/4321] fixed memory leak --- src/libopensc/pkcs15-pubkey.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index cb522a0924..1d54dbe227 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -939,7 +939,6 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey)); if (pubkey == NULL) { - free(data); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } pubkey->algorithm = algorithm; @@ -990,10 +989,11 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj } err: - if (r) + if (r) { sc_pkcs15_free_pubkey(pubkey); - else + } else *out = pubkey; + free(data); LOG_FUNC_RETURN(ctx, r); } From fe0d6f9187f1460863271e51dc4040167ffe10e3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Mar 2018 15:09:25 +0100 Subject: [PATCH 0200/4321] fixed invalid read --- src/pkcs11/framework-pkcs15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index aee08a4a31..5e42496987 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -625,7 +625,8 @@ pkcs15_cert_extract_label(struct pkcs15_cert_object *cert) cert->cert_data->subject, cert->cert_data->subject_len, &cn_oid, &cn_name, &cn_len); if (rv == SC_SUCCESS) { - sc_log(context, "pkcs15_cert_extract_label(): Name from DN is %s", cn_name); + sc_log(context, "pkcs15_cert_extract_label(): Name from DN is %.*s", + (unsigned int) cn_len, cn_name); cn_len = MIN(cn_len, SC_PKCS15_MAX_LABEL_SIZE-1); memcpy(cert->cert_p15obj->label, cn_name, cn_len); cert->cert_p15obj->label[cn_len] = '\0'; From 45ad44e3115c2fda36c46f77b792f0f9da6152ab Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 19 Mar 2018 15:25:14 +0100 Subject: [PATCH 0201/4321] fixed handling SC_ASN1_TAG_EOC from sc_asn1_read_tag We can't check for `tag == SC_ASN1_TAG_EOC` directly, because this would also be true for a tag of 0x80 (with `class == SC_ASN1_CLASS_CONSTRUCTED`). So what we do is we check for the output buffer to be NULL! fixes https://github.com/OpenSC/OpenSC/issues/1273 --- src/libopensc/asn1.c | 9 ++++++--- src/libopensc/card-gids.c | 8 +++++--- src/libopensc/card-mcrd.c | 4 ++-- src/libopensc/card-openpgp.c | 4 +++- src/libopensc/card-piv.c | 20 +++++++++++++------- src/libopensc/ef-gdo.c | 2 +- src/libopensc/iso7816.c | 3 ++- src/libopensc/pkcs15-pubkey.c | 2 +- src/pkcs15init/pkcs15-myeid.c | 2 ++ src/tools/sc-hsm-tool.c | 15 ++++++++------- 10 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index f1424029b8..d70d03191a 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -364,7 +364,7 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, size_t len; r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &len); - if (r != SC_SUCCESS) { + if (r != SC_SUCCESS || tagp == NULL) { printf("Error in decoding.\n"); return; } @@ -475,8 +475,10 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, buf = p; /* read a tag */ - if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS) + if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS + || p == NULL) return NULL; + left -= (p - buf); /* we need to shift the class byte to the leftmost * byte of the tag */ @@ -506,7 +508,8 @@ const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen, size_t len = *buflen, taglen; unsigned int cla = 0, tag; - if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS) + if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS + || p == NULL) return NULL; switch (cla & 0xC0) { case SC_ASN1_TAG_UNIVERSAL: diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 34b4ce753f..d8bcb88567 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -533,17 +533,19 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef r = gids_get_DO(card, GIDS_APPLET_EFID, dataObjectIdentifier, buffer, &buffersize); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the masterfile"); - p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_COUNTER_OLD_TAG, &datasize); + buffersize = buffersize > sizeof(buffer) ? sizeof(buffer) : buffersize; + + p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_OLD_TAG, &datasize); if (p && datasize == 1) { if (tries_left) *tries_left = p[0]; } - p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_COUNTER_TAG, &datasize); + p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_TAG, &datasize); if (p && datasize == 1) { if (tries_left) *tries_left = p[0]; } - p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_LIMIT_TAG, &datasize); + p = sc_asn1_find_tag(card->ctx, buffer, buffersize , GIDS_TRY_LIMIT_TAG, &datasize); if (p && datasize == 1) { if (tries_left) *max_tries = p[0]; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 57ead6bdf8..2923d1f535 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -606,8 +606,8 @@ static void process_arr(sc_card_t * card, sc_file_t * file, skip = 1; /* Skip over initial unknown SC DOs. */ for (;;) { buf = p; - if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != - SC_SUCCESS) + if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS + || p == NULL) break; left -= (p - buf); tag |= cla; diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 55c1939585..bfb0014920 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -922,7 +922,7 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); - if (r < 0) { + if (r < 0 || data == NULL) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unexpected end of contents\n"); return SC_ERROR_OBJECT_NOT_VALID; @@ -2132,6 +2132,8 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, r = sc_asn1_read_tag((const u8**)&part, data_len - (in - data), &cla, &tag, &len); + if (part == NULL) + r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; LOG_TEST_RET(card->ctx, r, "Unexpected end of contents."); /* undo ASN1's split of tag & class */ for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c291374dd7..70fbd6605e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -573,7 +573,8 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, * the buffer is bigger, so it will not produce "ASN1.tag too long!" */ body = rbuf; - if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) { + if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + || body == NULL) { /* only early beta cards had this problem */ sc_log(card->ctx, "***** received buffer tag MISSING "); body = rbuf; @@ -679,6 +680,9 @@ static int piv_generate_key(sc_card_t *card, in_len = rbuflen; r = sc_asn1_read_tag(&cp, rbuflen, &cla_out, &tag_out, &in_len); + if (cp == NULL) { + r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; + } if (r != SC_SUCCESS) { sc_log(card->ctx, "Tag buffer not found"); goto err; @@ -881,7 +885,8 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, goto err; } body = tagbuf; - if (sc_asn1_read_tag(&body, 0xfffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) { + if (sc_asn1_read_tag(&body, 0xfffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + || body == NULL) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -947,7 +952,8 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, &rbuf, &rbuflen); if (r > 0) { body = rbuf; - if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) { + if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + || body == NULL) { sc_log(card->ctx, "***** received buffer tag MISSING "); r = SC_ERROR_FILE_NOT_FOUND; goto err; @@ -2847,8 +2853,8 @@ piv_process_history(sc_card_t *card) body = ocfhfbuf; if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, - &tag_out, &bodylen) != SC_SUCCESS || - cla_out+tag_out != 0x30) { + &tag_out, &bodylen) != SC_SUCCESS + || cla_out+tag_out != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -2857,8 +2863,8 @@ piv_process_history(sc_card_t *card) while (bodylen > 0) { seqtag = seq; if (sc_asn1_read_tag(&seq, bodylen, &cla_out, - &tag_out, &seqlen) != SC_SUCCESS || - cla_out+tag_out != 0x30) { + &tag_out, &seqlen) != SC_SUCCESS + || cla_out+tag_out != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index bda51f220b..39dea2e502 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -47,7 +47,7 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, } break; } - if (tag == SC_ASN1_TAG_EOC) { + if (p == NULL) { /* done parsing */ break; } diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index a8c12b51ff..df283d2049 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -343,7 +343,8 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, p < end; p += length, length = end - p) { - if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length)) { + if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length) + || p == NULL) { break; } switch (cla | tag) { diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 1d54dbe227..0be05bf7c7 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1269,7 +1269,7 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename, if (r != SC_SUCCESS && r != SC_ERROR_ASN1_END_OF_CONTENTS) goto out; - if (tag_out == SC_ASN1_TAG_EOC || body == NULL) { + if (body == NULL) { r = SC_SUCCESS; goto out; } diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 4931027d82..29f9aa2220 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -821,6 +821,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, dataptr = data_obj.Data; r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen); + if (dataptr == NULL) + r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure."); if (taglen == 0) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 6ae2116395..d246b461a5 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1223,7 +1223,8 @@ static size_t determineLength(const u8 *tlv, size_t buflen) unsigned int cla,tag; size_t len; - if (sc_asn1_read_tag(&ptr, buflen, &cla, &tag, &len) != SC_SUCCESS) { + if (sc_asn1_read_tag(&ptr, buflen, &cla, &tag, &len) != SC_SUCCESS + || ptr == NULL) { return 0; } @@ -1515,16 +1516,16 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p fclose(in); ptr = keyblob; - if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) || - ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) || - ((tag != SC_ASN1_TAG_SEQUENCE)) ){ + if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) + || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) + || (tag != SC_ASN1_TAG_SEQUENCE) ){ fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n"); return -1; } - if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) || - (cla & SC_ASN1_TAG_CONSTRUCTED) || - ((tag != SC_ASN1_TAG_OCTET_STRING)) ){ + if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) + || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) + || (tag != SC_ASN1_TAG_OCTET_STRING) ){ fprintf(stderr, "Invalid wrapped key format (Key binary).\n"); return -1; } From 74885fb1c174468cc0a505cd7404e228d465efd8 Mon Sep 17 00:00:00 2001 From: AnthonyA Date: Tue, 27 Mar 2018 00:48:05 +0000 Subject: [PATCH 0202/4321] pkcs11-tool: allow mechanism to be specified in hexadecimal To support vendor mechanisms, let -m accept hexadecimal strings, e.g., -m 0x80001234 --- doc/tools/pkcs11-tool.1.xml | 3 ++- src/tools/pkcs11-tool.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index f8d638b450..e78570b102 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -231,7 +231,8 @@ Use the specified mechanism for token operations. See for a list - of mechanisms supported by your token. + of mechanisms supported by your token. The mechanism can also be specified in + hexadecimal, e.g., 0x80001234. diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 63e5c5f7fd..484c019d86 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -234,7 +234,7 @@ static const char *option_help[] = { "Hash some data", "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", - "Specify mechanism (use -M for a list of supported mechanisms)", + "Specify mechanism (use -M for a list of supported mechanisms), or by hexadecimal, e.g., 0x80001234", "Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption", "Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)", "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", @@ -6076,6 +6076,9 @@ static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name) { struct mech_info *mi; + if (strncasecmp("0x", name, 2) == 0) { + return strtoul(name, NULL, 0); + } for (mi = p11_mechanisms; mi->name; mi++) { if (!strcasecmp(mi->name, name) || (mi->short_name && !strcasecmp(mi->short_name, name))) From 098eed146f50f0375bd41d70116f9dd9ebc4dde4 Mon Sep 17 00:00:00 2001 From: sergioag Date: Sat, 31 Mar 2018 14:51:11 -0500 Subject: [PATCH 0203/4321] [AuthentIC v3] Correctly handle APDUs with more than 256 bytes (#1205) --- src/libopensc/card-authentic.c | 140 +++++++++------------------------ 1 file changed, 37 insertions(+), 103 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 8bf49c90ea..fb88404ae5 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -806,53 +806,13 @@ authentic_select_file(struct sc_card *card, const struct sc_path *path, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - -static int -authentic_apdus_allocate(struct sc_apdu **head, struct sc_apdu **new) -{ - struct sc_apdu *allocated_apdu = NULL, *tmp_apdu = NULL; - - if (!head) - return SC_ERROR_INVALID_ARGUMENTS; - - allocated_apdu = calloc(1, sizeof(struct sc_apdu)); - if (!allocated_apdu) - return SC_ERROR_OUT_OF_MEMORY; - - if (*head == NULL) - *head = allocated_apdu; - - if (new) - *new = allocated_apdu; - - tmp_apdu = *head; - while(tmp_apdu->next) - tmp_apdu = tmp_apdu->next; - - tmp_apdu->next = allocated_apdu; - - return 0; -} - - -static void -authentic_apdus_free(struct sc_apdu *apdu) -{ - while(apdu) { - struct sc_apdu *tmp_apdu = apdu->next; - free(apdu); - apdu = tmp_apdu; - } -} - - static int authentic_read_binary(struct sc_card *card, unsigned int idx, unsigned char *buf, size_t count, unsigned long flags) { struct sc_context *ctx = card->ctx; - struct sc_apdu *apdus = NULL, *cur_apdu = NULL; - size_t sz, rest; + struct sc_apdu apdu; + size_t sz, rest, ret_count = 0; int rv; LOG_FUNC_CALLED(ctx); @@ -860,42 +820,32 @@ authentic_read_binary(struct sc_card *card, unsigned int idx, "offs:%i,count:%"SC_FORMAT_LEN_SIZE_T"u,max_recv_size:%"SC_FORMAT_LEN_SIZE_T"u", idx, count, card->max_recv_size); - /* Data size more then 256 bytes can happen when card reader is - * configurated with max_send/recv_size more then 255/256 bytes - * (for ex. 'remote-access' reader) . - * In this case create chained 'read-binary' APDUs. - */ - sc_log(ctx, "reader flags 0x%lX", card->reader->flags); - if (count > 256 && !(card->reader->flags & SC_READER_HAS_WAITING_AREA)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid size of the data to read"); - rest = count; while(rest) { - if (authentic_apdus_allocate(&apdus, &cur_apdu)) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cannot allocate APDU"); - sz = rest > 256 ? 256 : rest; - sc_format_apdu(card, cur_apdu, SC_APDU_CASE_2_SHORT, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF); - cur_apdu->le = sz; - cur_apdu->resplen = count; - cur_apdu->resp = buf; + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF); + apdu.le = sz; + apdu.resplen = sz; + apdu.resp = (buf + ret_count); + + rv = sc_transmit_apdu(card, &apdu); + if(!rv) + ret_count += apdu.resplen; + else + break; idx += sz; rest -= sz; } - if (!apdus) { + if (rv) { LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "authentic_read_binary() failed"); LOG_FUNC_RETURN(ctx, count); } - rv = sc_transmit_apdu(card, apdus); - if (!rv) - rv = sc_check_sw(card, apdus->sw1, apdus->sw2); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); if (!rv) - count = apdus->resplen; - - authentic_apdus_free(apdus); + count = ret_count; LOG_TEST_RET(ctx, rv, "authentic_read_binary() failed"); LOG_FUNC_RETURN(ctx, count); @@ -907,7 +857,7 @@ authentic_write_binary(struct sc_card *card, unsigned int idx, const unsigned char *buf, size_t count, unsigned long flags) { struct sc_context *ctx = card->ctx; - struct sc_apdu *apdus = NULL, *cur_apdu = NULL; + struct sc_apdu apdu; size_t sz, rest; int rv; @@ -916,37 +866,29 @@ authentic_write_binary(struct sc_card *card, unsigned int idx, "offs:%i,count:%"SC_FORMAT_LEN_SIZE_T"u,max_send_size:%"SC_FORMAT_LEN_SIZE_T"u", idx, count, card->max_send_size); - /* see comments for authentic_read_binary() */ - sc_log(ctx, "reader flags 0x%lX", card->reader->flags); - if (count > 255 && !(card->reader->flags & SC_READER_HAS_WAITING_AREA)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid size of the data to read"); - rest = count; while(rest) { - if (authentic_apdus_allocate(&apdus, &cur_apdu)) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cannot allocate APDU"); - sz = rest > 255 ? 255 : rest; - sc_format_apdu(card, cur_apdu, SC_APDU_CASE_3_SHORT, 0xD0, (idx >> 8) & 0x7F, idx & 0xFF); - cur_apdu->lc = sz; - cur_apdu->datalen = sz; - cur_apdu->data = buf + count - rest; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD0, (idx >> 8) & 0x7F, idx & 0xFF); + apdu.lc = sz; + apdu.datalen = sz; + apdu.data = buf + count - rest; + + rv = sc_transmit_apdu(card, &apdu); + if(rv) + break; idx += sz; rest -= sz; } - if (!apdus) + if (rv) { LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "authentic_write_binary() failed"); LOG_FUNC_RETURN(ctx, count); } - rv = sc_transmit_apdu(card, apdus); - if (!rv) - rv = sc_check_sw(card, apdus->sw1, apdus->sw2); - - authentic_apdus_free(apdus); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, rv, "authentic_write_binary() failed"); LOG_FUNC_RETURN(ctx, count); @@ -958,7 +900,7 @@ authentic_update_binary(struct sc_card *card, unsigned int idx, const unsigned char *buf, size_t count, unsigned long flags) { struct sc_context *ctx = card->ctx; - struct sc_apdu *apdus = NULL, *cur_apdu = NULL; + struct sc_apdu apdu; size_t sz, rest; int rv; @@ -967,37 +909,29 @@ authentic_update_binary(struct sc_card *card, unsigned int idx, "offs:%i,count:%"SC_FORMAT_LEN_SIZE_T"u,max_send_size:%"SC_FORMAT_LEN_SIZE_T"u", idx, count, card->max_send_size); - /* see comments for authentic_read_binary() */ - sc_log(ctx, "reader flags 0x%lX", card->reader->flags); - if (count > 255 && !(card->reader->flags & SC_READER_HAS_WAITING_AREA)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid size of the data to read"); - rest = count; while(rest) { - if (authentic_apdus_allocate(&apdus, &cur_apdu)) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cannot allocate APDU"); - sz = rest > 255 ? 255 : rest; - sc_format_apdu(card, cur_apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0x7F, idx & 0xFF); - cur_apdu->lc = sz; - cur_apdu->datalen = sz; - cur_apdu->data = buf + count - rest; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0x7F, idx & 0xFF); + apdu.lc = sz; + apdu.datalen = sz; + apdu.data = buf + count - rest; + + rv = sc_transmit_apdu(card, &apdu); + if(rv) + break; idx += sz; rest -= sz; } - if (!apdus) + if (rv) { LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "authentic_update_binary() failed"); LOG_FUNC_RETURN(ctx, count); } - rv = sc_transmit_apdu(card, apdus); - if (!rv) - rv = sc_check_sw(card, apdus->sw1, apdus->sw2); - - authentic_apdus_free(apdus); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, rv, "authentic_update_binary() failed"); LOG_FUNC_RETURN(ctx, count); From 3e22daf7b55d0fcafcbf397365881639d709adc6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Apr 2018 10:02:30 +0200 Subject: [PATCH 0204/4321] OpenPGP: fixed memory leak --- src/libopensc/pkcs15-openpgp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 26077d5239..e68b65344c 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -147,6 +147,9 @@ read_file(sc_card_t *card, const char *path_name, void *buf, size_t len) if (file->size < len) len = file->size; + + sc_file_free(file); + return sc_read_binary(card, 0, (u8 *) buf, len, 0); } @@ -162,7 +165,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V1) ? pin_cfg_v1 : pin_cfg_v2; sc_path_t path; - sc_file_t *file; + sc_file_t *file = NULL; set_string(&p15card->tokeninfo->label, "OpenPGP card"); set_string(&p15card->tokeninfo->manufacturer_id, "OpenPGP project"); @@ -377,6 +380,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) "Failed to initialize OpenPGP emulation: %s\n", sc_strerror(r)); } + sc_file_free(file); return r; } From b7dc5a0890838366fc18e308aa5ef47cb3d89d8b Mon Sep 17 00:00:00 2001 From: Mouse Date: Wed, 4 Apr 2018 15:41:39 -0400 Subject: [PATCH 0205/4321] Retrieve OpenPGP applet version from OpenPGP applet on YubiKey token (#1262) --- src/libopensc/card-openpgp.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index bfb0014920..cf163bb33e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -49,6 +49,7 @@ static struct sc_atr_table pgp_atrs[] = { { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, "CryptoStick v1.2 (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, { "3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1", NULL, "Yubikey NEO (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, + { "3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4", NULL, "Yubikey 4 (OpenPGP v2.1)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:f5:73:c0:01:60:00:90:00:1c", NULL, "OpenPGP card V3", SC_CARD_TYPE_OPENPGP_V3, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -317,6 +318,16 @@ struct pgp_priv_data { sc_security_env_t sec_env; }; +static int +get_full_pgp_aid(sc_card_t *card, sc_file_t *file) +{ + int r = 0; + /* explicitly get the full aid */ + r = sc_get_data(card, 0x004F, file->name, sizeof file->name); + file->namelen = MAX(r, 0); + + return r; +} /** * ABI: check if card's ATR matches one of driver's @@ -330,7 +341,7 @@ pgp_match_card(sc_card_t *card) i = _sc_match_atr(card, pgp_atrs, &card->type); if (i >= 0) { card->name = pgp_atrs[i].name; - return 1; + LOG_FUNC_RETURN(card->ctx, 1); } else { sc_path_t partial_aid; @@ -345,6 +356,8 @@ pgp_match_card(sc_card_t *card) static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; card->type = SC_CARD_TYPE_OPENPGP_BASE; card->name = card_name; + if (file->namelen != 16) + (void) get_full_pgp_aid(card, file); if (file->namelen == 16) { unsigned char major = file->name[6]; unsigned char minor = file->name[7]; @@ -358,8 +371,10 @@ pgp_match_card(sc_card_t *card) case 3: card->type = SC_CARD_TYPE_OPENPGP_V3; break; + default: + break; } - snprintf(card_name, sizeof card_name, "OpenPGP card V%u.%u", major, minor); + snprintf(card_name, sizeof(card_name), "OpenPGP card V%u.%u", major, minor); } sc_file_free(file); return 1; @@ -409,12 +424,11 @@ pgp_init(sc_card_t *card) if (file->namelen != 16) { /* explicitly get the full aid */ - r = sc_get_data(card, 0x004F, file->name, sizeof file->name); + r = get_full_pgp_aid(card, file); if (r < 0) { pgp_finish(card); return r; } - file->namelen = r; } /* read information from AID */ From e193b31e1a5878efc9cbf6233ea13253be4055e0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Feb 2018 12:50:41 +0100 Subject: [PATCH 0206/4321] Log the used config file after processing it --- src/libopensc/ctx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 3f4e73d387..3dd0c0521f 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -678,7 +678,6 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) if (!conf_path) conf_path = OPENSC_CONF_PATH; #endif - sc_log(ctx, "Using configuration file '%s'", conf_path); ctx->conf = scconf_new(conf_path); if (ctx->conf == NULL) return; @@ -700,6 +699,8 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) ctx->conf = NULL; return; } + /* needs to be after the log file is known */ + sc_log(ctx, "Used configuration file '%s'", conf_path); blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name); if (blocks && blocks[0]) ctx->conf_blocks[count++] = blocks[0]; From 161e83a243d03ccbe4f529a4eb22c00bbe38f17b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Feb 2018 12:59:19 +0100 Subject: [PATCH 0207/4321] Add missing pkcs11-tool options to man page --- doc/tools/pkcs11-tool.1.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index e78570b102..8db0e84a7a 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -135,6 +135,12 @@ Generate a new key pair (public and private pair.) + + + + + Generate a new key. + @@ -306,6 +312,13 @@ Supply new User PIN on the command line. + + + + + Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext). + + id, @@ -344,6 +357,13 @@ Derive a secret key using another key and some data. + + + , + + Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations + + bytes From db2ceff9117e6ff85af9162d2d60f4d54f1769ea Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 19 Feb 2018 14:52:21 +0100 Subject: [PATCH 0208/4321] Avoid circullar dependency --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 789b84957d..16349db8ef 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -213,7 +213,7 @@ endif applicationsdir = $(datadir)/applications applications_DATA = org.opensc-project.opensc-notify.desktop -org.opensc-project.opensc-notify.desktop: org.opensc-project.opensc-notify.desktop +org.opensc-project.opensc-notify.desktop: org.opensc-project.opensc-notify.desktop.in $(do_subst) < $(abs_srcdir)/org.opensc-project.opensc-notify.desktop.in > $@ clean-local: From 0c974a0cc7d0d5e25f589241fa418c5bddcc1b64 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 19 Feb 2018 15:06:41 +0100 Subject: [PATCH 0209/4321] Incorporate the first manpage integrity check --- doc/tools/Makefile.am | 2 ++ doc/tools/test-manpage.sh | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100755 doc/tools/test-manpage.sh diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index bc8af488cf..17e4fbf125 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -2,6 +2,8 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = completion-template +TESTS = test-manpage.sh + dist_noinst_DATA = $(wildcard $(srcdir)/*.xml) if ENABLE_DOC html_DATA = tools.html diff --git a/doc/tools/test-manpage.sh b/doc/tools/test-manpage.sh new file mode 100755 index 0000000000..8fdb091372 --- /dev/null +++ b/doc/tools/test-manpage.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SOURCE_PATH=../../ + +# find all the manual pages in src/tools +TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|"` +ALL=1 + +for T in $TOOLS; do + SWITCHES=`${SOURCE_PATH}/src/tools/${T} 2>&1 | awk '{if (match($0,"--[a-zA-Z0-9-]*",a) != 0) print a[0]} {if (match($0," -[a-zA-Z0-9]",a) != 0) print a[0]}'` + for S in $SWITCHES; do + grep -q -- "$S" ${SOURCE_PATH}/doc/tools/${T}.1.xml || { echo "${T}: missing switch $S"; ALL=0; }; + done +done +if [ "$ALL" = 0 ]; then + echo "Not all the switches in help are documented in manual pages" + exit 1; +fi From a6e6cfb6de94b55a7e67d398802ad62f92df328e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Mar 2018 18:02:49 +0100 Subject: [PATCH 0210/4321] Log return value of C_GenerateRandom() --- src/pkcs11/pkcs11-object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index e5125e134a..bdf8845cfb 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1152,6 +1152,7 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ } sc_pkcs11_unlock(); + sc_log(context, "C_GenerateRandom() = %s", lookup_enum ( RV_T, rv )); return rv; } From 0997c33a3093611ad9050dcc424ea0789f6330e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 29 Mar 2018 16:00:30 +0200 Subject: [PATCH 0211/4321] pkcs11-tool: Print also SUBJECT of certificate List also the names of generated functions for better searchability --- src/tools/pkcs11-tool.c | 74 ++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 484c019d86..bd70ed8ab8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -490,34 +490,35 @@ get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \ /* * Define attribute accessors */ -ATTR_METHOD(CLASS, CK_OBJECT_CLASS); -ATTR_METHOD(ALWAYS_AUTHENTICATE, CK_BBOOL); -ATTR_METHOD(PRIVATE, CK_BBOOL); -ATTR_METHOD(MODIFIABLE, CK_BBOOL); -ATTR_METHOD(ENCRYPT, CK_BBOOL); -ATTR_METHOD(DECRYPT, CK_BBOOL); -ATTR_METHOD(SIGN, CK_BBOOL); -ATTR_METHOD(VERIFY, CK_BBOOL); -ATTR_METHOD(WRAP, CK_BBOOL); -ATTR_METHOD(UNWRAP, CK_BBOOL); -ATTR_METHOD(DERIVE, CK_BBOOL); -ATTR_METHOD(OPENSC_NON_REPUDIATION, CK_BBOOL); -ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE); -ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); -ATTR_METHOD(MODULUS_BITS, CK_ULONG); -ATTR_METHOD(VALUE_LEN, CK_ULONG); -VARATTR_METHOD(LABEL, char); -VARATTR_METHOD(APPLICATION, char); -VARATTR_METHOD(ID, unsigned char); -VARATTR_METHOD(OBJECT_ID, unsigned char); -VARATTR_METHOD(MODULUS, CK_BYTE); +ATTR_METHOD(CLASS, CK_OBJECT_CLASS); /* getCLASS */ +ATTR_METHOD(ALWAYS_AUTHENTICATE, CK_BBOOL); /* getALWAYS_AUTHENTICATE */ +ATTR_METHOD(PRIVATE, CK_BBOOL); /* getPRIVATE */ +ATTR_METHOD(MODIFIABLE, CK_BBOOL); /* getMODIFIABLE */ +ATTR_METHOD(ENCRYPT, CK_BBOOL); /* getENCRYPT */ +ATTR_METHOD(DECRYPT, CK_BBOOL); /* getDECRYPT */ +ATTR_METHOD(SIGN, CK_BBOOL); /* getSIGN */ +ATTR_METHOD(VERIFY, CK_BBOOL); /* getVERIFY */ +ATTR_METHOD(WRAP, CK_BBOOL); /* getWRAP */ +ATTR_METHOD(UNWRAP, CK_BBOOL); /* getUNWRAP */ +ATTR_METHOD(DERIVE, CK_BBOOL); /* getDERIVE */ +ATTR_METHOD(OPENSC_NON_REPUDIATION, CK_BBOOL); /* getOPENSC_NON_REPUDIATION */ +ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE); /* getKEY_TYPE */ +ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */ +ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */ +ATTR_METHOD(VALUE_LEN, CK_ULONG); /* getVALUE_LEN */ +VARATTR_METHOD(LABEL, char); /* getLABEL */ +VARATTR_METHOD(SUBJECT, unsigned char); /* getSUBJECT */ +VARATTR_METHOD(APPLICATION, char); /* getAPPLICATION */ +VARATTR_METHOD(ID, unsigned char); /* getID */ +VARATTR_METHOD(OBJECT_ID, unsigned char); /* getOBJECT_ID */ +VARATTR_METHOD(MODULUS, CK_BYTE); /* getMODULUS */ #ifdef ENABLE_OPENSSL -VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); +VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ #endif -VARATTR_METHOD(VALUE, unsigned char); -VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); -VARATTR_METHOD(EC_POINT, unsigned char); -VARATTR_METHOD(EC_PARAMS, unsigned char); +VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ +VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */ +VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */ +VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */ int main(int argc, char * argv[]) @@ -3676,6 +3677,9 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) CK_ULONG size; unsigned char *id; char *label; +#if defined(ENABLE_OPENSSL) + unsigned char *subject; +#endif /* ENABLE_OPENSSL */ printf("Certificate Object; type = "); switch (cert_type) { @@ -3698,6 +3702,24 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(label); } +#if defined(ENABLE_OPENSSL) + if ((subject = getSUBJECT(sess, obj, &size)) != NULL) { + X509_NAME *name; + const unsigned char *tmp = subject; + + name = d2i_X509_NAME(NULL, &tmp, size); + if(name) { + BIO *bio = BIO_new(BIO_s_file()); + BIO_set_fp(bio, stdout, BIO_NOCLOSE); + printf(" subject: DN: "); + X509_NAME_print(bio, name, XN_FLAG_RFC2253); + printf("\n"); + BIO_free(bio); + } + free(subject); + } +#endif /* ENABLE_OPENSSL */ + if ((id = getID(sess, obj, &size)) != NULL && size) { unsigned int n; From 58cd9aaeb699d495d060aa98b2837cc9dec9ce4a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Apr 2018 09:52:01 +0200 Subject: [PATCH 0212/4321] card-authentic.c: Initialize variables and make it build Ammends: #1205 --- src/libopensc/card-authentic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index fb88404ae5..1d3bb26750 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -813,7 +813,7 @@ authentic_read_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest, ret_count = 0; - int rv; + int rv = SC_SUCCESS; LOG_FUNC_CALLED(ctx); sc_log(ctx, @@ -859,7 +859,7 @@ authentic_write_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest; - int rv; + int rv = SC_SUCCESS; LOG_FUNC_CALLED(ctx); sc_log(ctx, @@ -902,7 +902,7 @@ authentic_update_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest; - int rv; + int rv = SC_SUCCESS; LOG_FUNC_CALLED(ctx); sc_log(ctx, From eb646dd370490fdfe7bd6cfc7483ab813d11513b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Apr 2018 10:22:36 +0200 Subject: [PATCH 0213/4321] Do not create getSUBJECT without OpenSSL --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bd70ed8ab8..8940548aec 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -507,12 +507,12 @@ ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */ ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */ ATTR_METHOD(VALUE_LEN, CK_ULONG); /* getVALUE_LEN */ VARATTR_METHOD(LABEL, char); /* getLABEL */ -VARATTR_METHOD(SUBJECT, unsigned char); /* getSUBJECT */ VARATTR_METHOD(APPLICATION, char); /* getAPPLICATION */ VARATTR_METHOD(ID, unsigned char); /* getID */ VARATTR_METHOD(OBJECT_ID, unsigned char); /* getOBJECT_ID */ VARATTR_METHOD(MODULUS, CK_BYTE); /* getMODULUS */ #ifdef ENABLE_OPENSSL +VARATTR_METHOD(SUBJECT, unsigned char); /* getSUBJECT */ VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ #endif VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ From 8a63103229d83095091efb491b0ec949497b0fd9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Apr 2018 15:46:49 +0200 Subject: [PATCH 0214/4321] Properly report errors from make check in travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e51b72ed1f..c9a6e82c77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,8 +85,7 @@ script: fi; fi - if [ -z "$HOST" -a "${COVERITY_SCAN_BRANCH}" != 1 ]; then - make check; - make dist; + make check && make dist; fi - if [ ! -z "$HOST" -a "${COVERITY_SCAN_BRANCH}" != 1 ]; then make install; From a5839bb83c7fd772923219b82a13fa4791349be1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Apr 2018 15:48:46 +0200 Subject: [PATCH 0215/4321] Temporarily disable tests to make CI pass --- doc/tools/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 17e4fbf125..83a361999f 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -2,7 +2,8 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = completion-template -TESTS = test-manpage.sh +# TODO XXX Uncomment after fixing issue #1267 +#TESTS = test-manpage.sh dist_noinst_DATA = $(wildcard $(srcdir)/*.xml) if ENABLE_DOC From 0911982bef3aba1da24c2d70b4942d19ceb6ae78 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 31 Mar 2018 08:46:29 -0500 Subject: [PATCH 0216/4321] Various PIV changes Some ActivIdentity CAC/PIV cards lose the login state when selecting the PIV AID SC_CARD_TYPE_PIV_II_CAC and CI_PIV_AID_LOSE_STATE were added so piv_card_reader_lock_obtained will try and do a SELECT PIV AID. card->type is reset to its original value if piv_match_card_continued fails to match a card as PIV. pkcs15-piv.c now uses sc_card_ctl which checks card->ops->card_ctl for NULL. closes https://github.com/OpenSC/OpenSC/pull/1307 fixes https://github.com/OpenSC/OpenSC/issues/1297 --- src/libopensc/card-piv.c | 44 ++++++++++++++++++++++++++++++++------ src/libopensc/cards.h | 1 + src/libopensc/pkcs15-piv.c | 6 +++--- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 70fbd6605e..ef114db8f9 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -214,6 +214,7 @@ static struct piv_aid piv_aids[] = { #define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */ #define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */ #define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */ +#define CI_PIV_AID_LOSE_STATE 0x00000040U /* PIV AID can lose the login state run with out it*/ #define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */ #define CI_NFC_EXPOSE_TOO_MUCH 0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */ @@ -2965,8 +2966,6 @@ static int piv_match_card(sc_card_t *card) { int r = 0; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* piv_match_card may be called with card->type, set by opensc.conf */ /* user provide card type must be one we know */ switch (card->type) { @@ -2975,6 +2974,7 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE: break; default: return 0; /* can not handle the card */ @@ -3005,8 +3005,7 @@ static int piv_match_card_continued(sc_card_t *card) sc_file_t aidfile; int type = -1; piv_private_data_t *priv = NULL; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + int saved_type = card->type; /* Since we send an APDU, the card's logout function may be called... * however it may be in dirty memory */ @@ -3020,6 +3019,7 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE: type = card->type; break; default: @@ -3043,6 +3043,18 @@ static int piv_match_card_continued(sc_card_t *card) !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) { type = SC_CARD_TYPE_PIV_II_NEO; } + /* + * https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp1239.pdf + * lists 2 ATRS with historical bytes: + * 73 66 74 65 2D 63 64 30 38 30 + * 73 66 74 65 20 63 64 31 34 34 + * will check for 73 66 74 65 + */ + else if (card->reader->atr_info.hist_bytes_len >= 4 && + !(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) { + type = SC_CARD_TYPE_PIV_II_GI_DE; + } + else if (card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ p = card->reader->atr_info.hist_bytes; pe = p + card->reader->atr_info.hist_bytes_len; @@ -3129,6 +3141,7 @@ static int piv_match_card_continued(sc_card_t *card) /* don't match. Does not have a PIV applet. */ sc_unlock(card); piv_finish(card); + card->type = saved_type; return 0; } @@ -3228,6 +3241,13 @@ static int piv_init(sc_card_t *card) priv->card_issues |= 0; break; + case SC_CARD_TYPE_PIV_II_GI_DE: + priv->card_issues |= CI_VERIFY_LC0_FAIL + | CI_PIV_AID_LOSE_STATE + | CI_OTHER_AID_LOSE_STATE;; + /* TODO may need more research */ + break; + case SC_CARD_TYPE_PIV_II_GENERIC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE; @@ -3564,6 +3584,13 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) goto err; } + /* can we detect and then select the PIV AID without losinig the login state? */ + if ((priv->card_issues & CI_DISCOVERY_USELESS) + && (priv->card_issues & CI_PIV_AID_LOSE_STATE)) { + r = 0; /* do nothing, hope card was not interferred with */ + goto err; + } + /* make sure our application is active */ /* first see if AID is active AID by reading discovery object '7E' */ @@ -3576,8 +3603,13 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) r = piv_find_discovery(card); } - if (r < 0) - r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + if (r < 0) { + if (!(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { + r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + } else { + r = 0; /* cant do anything with this card, hope there was no interference */ + } + } if (r < 0) /* bad error return will show up in sc_lock as error*/ goto err; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index e1a9d4469c..23e7c5d10b 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -138,6 +138,7 @@ enum { SC_CARD_TYPE_PIV_II_HIST, SC_CARD_TYPE_PIV_II_NEO, SC_CARD_TYPE_PIV_II_YUBIKEY4, + SC_CARD_TYPE_PIV_II_GI_DE, /* MuscleApplet */ SC_CARD_TYPE_MUSCLE_BASE = 15000, diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 267014313f..e6b4e31abc 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -658,7 +658,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) sc_format_path(objects[i].path, &obj_info.path); /* See if the object can not be present on the card */ - r = (card->ops->card_ctl)(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path); + r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path); if (r == 1) continue; /* Not on card, do not define the object */ @@ -734,7 +734,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) cert_obj.flags = certs[i].obj_flags; /* See if the cert might be present or not. */ - r = (card->ops->card_ctl)(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path); + r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path); if (r == 1) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cert can not be present,i=%d", i); continue; @@ -948,7 +948,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) label = pins[i].label; if (i == 0 && - (card->ops->card_ctl)(card, SC_CARDCTL_PIV_PIN_PREFERENCE, + sc_card_ctl(card, SC_CARDCTL_PIV_PIN_PREFERENCE, &pin_ref) == 0 && pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */ pin_info.attrs.pin.reference = pin_ref; From 445ae0919b490f0cc26f5db0ceaa46a0131f0c92 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Apr 2018 09:55:01 +0200 Subject: [PATCH 0217/4321] rename opensc-notify goi app id fixes https://github.com/OpenSC/OpenSC/issues/1309 --- src/tools/Makefile.am | 8 ++++---- ...nsc-notify.desktop.in => org.opensc.notify.desktop.in} | 0 src/ui/notify.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/tools/{org.opensc-project.opensc-notify.desktop.in => org.opensc.notify.desktop.in} (100%) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 16349db8ef..7e37f107d1 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -25,7 +25,7 @@ OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc-project.opensc-notify.desktop.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc.notify.desktop.in noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example @@ -211,10 +211,10 @@ opensc_notify_SOURCES += versioninfo-opensc-notify.rc endif applicationsdir = $(datadir)/applications -applications_DATA = org.opensc-project.opensc-notify.desktop +applications_DATA = org.opensc.notify.desktop -org.opensc-project.opensc-notify.desktop: org.opensc-project.opensc-notify.desktop.in - $(do_subst) < $(abs_srcdir)/org.opensc-project.opensc-notify.desktop.in > $@ +org.opensc.notify.desktop: org.opensc.notify.desktop.in + $(do_subst) < $(abs_srcdir)/org.opensc.notify.desktop.in > $@ clean-local: rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo diff --git a/src/tools/org.opensc-project.opensc-notify.desktop.in b/src/tools/org.opensc.notify.desktop.in similarity index 100% rename from src/tools/org.opensc-project.opensc-notify.desktop.in rename to src/tools/org.opensc.notify.desktop.in diff --git a/src/ui/notify.c b/src/ui/notify.c index 096776660f..6b9ebe1386 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -380,7 +380,7 @@ static GApplication *application = NULL; void sc_notify_init(void) { sc_notify_close(); - application = g_application_new("org.opensc-project.opensc-notify", G_APPLICATION_FLAGS_NONE); + application = g_application_new("org.opensc.notify", G_APPLICATION_FLAGS_NONE); if (application) { g_application_register(application, NULL, NULL); } From 74bdcad4e8403193b32d24fe970c5acb54156500 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Apr 2018 18:50:12 +0200 Subject: [PATCH 0218/4321] fixed description of --disable-strict --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 80ae2fe40b..8116ae5894 100644 --- a/configure.ac +++ b/configure.ac @@ -138,7 +138,7 @@ AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_opti AC_ARG_ENABLE( [strict], - [AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@disabled@:>@])], + [AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@enabled@:>@])], , [enable_strict="yes"] ) From fc64c87c5cdc7053a877c5c1a2d6a39be42f5492 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Apr 2018 17:47:44 +0200 Subject: [PATCH 0219/4321] with keep_alive, use cache only within the transaction fixes https://github.com/OpenSC/OpenSC/issues/1159 --- src/libopensc/card-entersafe.c | 3 +-- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-starcos.c | 3 +-- src/libopensc/card.c | 35 +++++++++++++++++----------------- src/libopensc/opensc.h | 1 + 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 9db0664ec7..0fa9bffa10 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -1061,8 +1061,7 @@ static int entersafe_erase_card(sc_card_t *card) r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - /* invalidate cache */ - card->cache.valid = 0; + sc_invalidate_cache(card); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xEE, 0x00, 0x00); apdu.cla=0x84; diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index c8611d15ff..f29be27ed0 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -2443,7 +2443,7 @@ epass2003_erase_card(struct sc_card *card) int r; LOG_FUNC_CALLED(card->ctx); - card->cache.valid = 0; + sc_invalidate_cache(card); r = sc_delete_file(card, sc_get_mf_path()); LOG_TEST_RET(card->ctx, r, "delete MF failed"); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 0df02f63bf..4cd0b03b1d 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -987,7 +987,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, * (or invent something else) */ if (rv == SC_ERROR_FILE_NOT_FOUND && cache_valid && df_from_cache) { - card->cache.valid = 0; + sc_invalidate_cache(card); sc_log(ctx, "iasecc_select_file() file not found, retry without cached DF"); if (file_out) { sc_file_free(*file_out); diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 450d32eb59..82e3c94e7e 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1157,8 +1157,7 @@ static int starcos_erase_card(sc_card_t *card) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - /* invalidate cache */ - card->cache.valid = 0; + sc_invalidate_cache(card); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) /* no MF to delete, ignore error */ return SC_SUCCESS; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 194634bd36..3fc3a6f6ad 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -34,10 +34,6 @@ #include "asn1.h" #include "common/compat_strlcpy.h" -/* -#define INVALIDATE_CARD_CACHE_IN_UNLOCK -*/ - #ifdef ENABLE_SM static int sc_card_sm_load(sc_card_t *card, const char *path, const char *module); static int sc_card_sm_unload(sc_card_t *card); @@ -382,9 +378,7 @@ int sc_reset(sc_card_t *card, int do_cold_reset) return r; r = card->reader->ops->reset(card->reader, do_cold_reset); - /* invalidate cache */ - memset(&card->cache, 0, sizeof(card->cache)); - card->cache.valid = 0; + sc_invalidate_cache(card); r2 = sc_mutex_unlock(card->ctx, card->mutex); if (r2 != SC_SUCCESS) { @@ -413,9 +407,7 @@ int sc_lock(sc_card_t *card) if (card->reader->ops->lock != NULL) { r = card->reader->ops->lock(card->reader); while (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { - /* invalidate cache */ - memset(&card->cache, 0, sizeof(card->cache)); - card->cache.valid = 0; + sc_invalidate_cache(card); if (was_reset++ > 4) /* TODO retry a few times */ break; r = card->reader->ops->lock(card->reader); @@ -466,12 +458,12 @@ int sc_unlock(sc_card_t *card) return SC_ERROR_INVALID_ARGUMENTS; } if (--card->lock_count == 0) { -#ifdef INVALIDATE_CARD_CACHE_IN_UNLOCK - /* invalidate cache */ - memset(&card->cache, 0, sizeof(card->cache)); - card->cache.valid = 0; - sc_log(card->ctx, "cache invalidated"); -#endif + if (card->flags & SC_CARD_FLAG_KEEP_ALIVE) { + /* Multiple processes accessing the card will most likely render + * the card cache useless. To not have a bad cache, we explicitly + * invalidate it. */ + sc_invalidate_cache(card); + } /* release reader lock */ if (card->reader->ops->unlock != NULL) r = card->reader->ops->unlock(card->reader); @@ -1233,7 +1225,16 @@ scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char return conf_block; } -void sc_print_cache(struct sc_card *card) { +void sc_invalidate_cache(struct sc_card *card) +{ + if (card) { + memset(&card->cache, 0, sizeof(card->cache)); + card->cache.valid = 0; + } +} + +void sc_print_cache(struct sc_card *card) +{ struct sc_context *ctx = NULL; if (card == NULL) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index be4f905582..5af2b86215 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1340,6 +1340,7 @@ int sc_parse_ef_gdo(struct sc_card *card, unsigned char *chn, size_t *chn_len); int sc_update_dir(struct sc_card *card, sc_app_info_t *app); +void sc_invalidate_cache(struct sc_card *card); void sc_print_cache(struct sc_card *card); struct sc_algorithm_info * sc_card_find_rsa_alg(struct sc_card *card, From 491e5a47fcd7940b28240829839b953fd94bc442 Mon Sep 17 00:00:00 2001 From: Laurent Bigonville Date: Thu, 22 Mar 2018 16:25:13 +0100 Subject: [PATCH 0220/4321] Clean up the belpic driver Remove all the code related to the old GUI and PIN PAD. This code was initially developed by Zetes and had the ability to display a dialog to request the PIN to the user. It was also able to manage some specific proprietary pin pads. As the Belgian government/fedict has now its own implementation, all these old crufts can be removed. https://github.com/OpenSC/OpenSC/issues/1296 --- src/libopensc/card-belpic.c | 1092 +---------------------------------- 1 file changed, 4 insertions(+), 1088 deletions(-) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 3642d629a5..b9c797cbbd 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -90,27 +90,6 @@ #include "internal.h" #include "log.h" -#ifdef BELPIC_PIN_PAD -#ifndef HAVE_GUI -#define HAVE_GUI -#endif -#endif - -#ifdef BELPIC_PIN_PAD -#include "winscard.h" -#include "scr.h" -#endif - -#ifdef HAVE_GUI -#include "scgui.h" -#ifndef SCR_USAGE_SIGN -#define SCR_USAGE_SIGN 2 /* in scr.h */ -#endif -#ifndef SCR_USAGE_AUTH -#define SCR_USAGE_AUTH 1 -#endif -#endif - /* To be removed */ #include static long t1, t2, tot_read = 0, tot_dur = 0, dur; @@ -176,26 +155,6 @@ static struct sc_atr_table belpic_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; -struct belpic_priv_data { - int lang; - int options; -#ifdef BELPIC_PIN_PAD - FARPROC scr_init; - FARPROC scr_verify_pin; - FARPROC scr_change_pin; - char szPinPadDll[64]; -#endif -}; - -#define DRVDATA(card) ((struct belpic_priv_data *) ((card)->drv_data)) - -/* Single Sign On */ -#ifdef HAVE_ALLOW_SSO -#define SSO_OK(drv) ((drv)->allow_sso) -#else -#define SSO_OK(drv) 0 -#endif - static struct sc_card_operations belpic_ops; static struct sc_card_driver belpic_drv = { "Belpic cards", @@ -205,414 +164,6 @@ static struct sc_card_driver belpic_drv = { }; static const struct sc_card_operations *iso_ops = NULL; -#define LNG_ENG 0 -#define LNG_DUTCH 1 -#define LNG_FRENCH 2 -#define LNG_GERMAN 3 -#define LNG_NONE 0xFFFF - -#ifdef BELPIC_PIN_PAD - -/* Option flags from the config file */ -#define PP_MSG_AUTH_PIN 0x00000001 -#define PP_MSG_WRONG_PIN 0x00000002 -#define PP_MSG_CHANGEPIN_MISMATCH 0x00000004 -#define PP_MSG_PIN_BLOCKED 0x00000008 - -/* Hardcoded pin pad reader names (PC/SC) and their pin pad lib */ -static char *pp_reader_names[] = { - "Xiring X Pass Serial", - NULL -}; -static char *pp_reader_libs[] = { - "xireid", - NULL -}; - -static BYTE aid_belpic[] = { 0xA0, 0x00, 0x00, 0x01, 0x77, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 }; -static SCR_Application scr_app_belpic = { - {aid_belpic, sizeof(aid_belpic)}, - "ID", - NULL -}; -static char *app_id_longstr[] = { - "Identity", - "Identiteit", - "Identité", - "Identität" -}; -#endif /* BELPIC_PIN_PAD */ - -#if defined(HAVE_GUI) ||defined(BELPIC_PIN_PAD) -static char *pin_usg_sig[] = { - "Signature", - "Handtekening", - "Signature", - "Signatur" -}; -static char *pin_usg_auth[] = { - "Authentication", - "Authentificatie", - "Authentification", - "Authentifizierung" -}; -#endif /* defined(HAVE_GUI) ||defined(BELPIC_PIN_PAD) */ - -#ifdef BELPIC_PIN_PAD -static char *lang_codes[4] = { - "en", - "nl", - "fr", - "de" -}; -static char *pp_msg_auth_sh[] = { - "Authentication", - "Authentificatie", - "Authentification", - "Kennzeichnung" -}; -static char *pp_msg_auth[] = { - "Enter your PIN on the reader, in order to authenticate yourself", - "Geef uw PIN in op de lezer, om u te authentificeren", - "Entrez votre PIN sur le lecteur, pour vous authentifier", - "Bitte geben Sie Ihre PIN am Kartenlesegerät ein, um sich zu authentifizieren" -}; -static char *pp_msg_sign_sh[] = { - "Signature", - "Handtekening", - "Signature", - "Signatur" -}; -static char *pp_msg_sign[] = { - "Caution: You are about to make a legally binding electronic signature with your identity card.\nPlease enter your PIN on the card reader to continue or click the Cancel button.\n\nIf you only want to log on to a web site or server, do NOT enter your PIN and click the Cancel button.", - "Let op: u gaat een wettelijk bindende electronische handtekening plaatsen met uw identiteitskaart.\nGeef uw PIN in op de kaartlezer om verder te gaan of klik op Stoppen.\n\nAls u enkel wil aanloggen op een web site of een server, geef uw PIN NIET in en klik op Stoppen.", - "Attention: vous allez apposer une signature électronique juridiquement valide avec votre carte d'identité.\nVeuillez entrer votre PIN sur le lecteur externe pour continuer ou cliquez sur Annuler.\n\nSi vous désirez seulement vous connecter à un site ou un serveur, n'entrez PAS votre PIN et cliquez sur Annuler.", - "Achtung: Mit Ihrem Personalausweis werden Sie eine rechtlich bindende elektronische Signatur setzen.\nBitte geben Sie Ihre PIN am Kartenlesgerät ein zum weitergehen oder klicken Sie auf Abbrechen.\n\nWenn Sie nur auf das Internet gehen möchten, geben Sie bitte Ihre PIN NICHT ein, sondern klicken Sie auf Abbrechen." -}; -static char *pp_msg_change_sh[] = { - "PIN change", - "PIN verandering", - "Modification du PIN ", - "PIN ändern" -}; -static char *pp_msg_change[] = { - "Change your PIN on the reader", - "Verander uw PIN op de lezer", - "Modifiez votre PIN sur le lecteur", - "Bitte ändern Sie Ihre PIN am Kartenlesegerät" -}; -static char *pp_msg_pin_mismatch[] = { - "The new PINs you entered were different.\n\nRetry or cancel?", - "De ingevoerde nieuwe PINs zijn verschillend.\n\nOpnieuw proberen of stoppen?", - "Les nouveaux PIN entrés sont différents.\n\nRéessayer ou annuler?", - "Die von Ihnen eingegebenen PINs unterscheiden sich.\n\nErneut versuchen oder abbrechen?" -}; - -#define PCSC_ERROR(ctx, desc, rv) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, desc ": %lx\n", rv); - -#endif /* BELPIC_PIN_PAD */ - -/* Language support for the GUI messages */ -#ifdef HAVE_GUI - -#ifdef WIN32 -#define BTN_KEYB_SHORTCUT "&" -#else -#define BTN_KEYB_SHORTCUT "_" -#endif - -static char *app_msg[] = { - "Identity", - "Identiteit", -#ifdef _WIN32 - "Identité", -#else - "Identite", -#endif -#ifdef _WIN32 - "Identität" -#else - "Identitat", -#endif -}; -static char *btn_msg_retry[4] = { - BTN_KEYB_SHORTCUT"Try again", - BTN_KEYB_SHORTCUT"Opnieuw proberen", - BTN_KEYB_SHORTCUT"Réessayer", - BTN_KEYB_SHORTCUT"Erneut versuchen" -}; -static char *btn_msg_cancel[4] = { - BTN_KEYB_SHORTCUT"Cancel", - BTN_KEYB_SHORTCUT"Stoppen", - BTN_KEYB_SHORTCUT"Annuler", - BTN_KEYB_SHORTCUT"Abbrechen" -}; -static char *btn_msg_ok[4] = { - BTN_KEYB_SHORTCUT"OK", - BTN_KEYB_SHORTCUT"OK", - BTN_KEYB_SHORTCUT"OK", - BTN_KEYB_SHORTCUT"OK" -}; -static char *btn_msg_close[4] = { - BTN_KEYB_SHORTCUT"Close", - BTN_KEYB_SHORTCUT"Sluiten", - BTN_KEYB_SHORTCUT"Fermer", - BTN_KEYB_SHORTCUT"Schliessen" -}; -static char *enter_pin_msg_auth[] = { - "Enter your PIN, in order to authenticate yourself", - "Geef uw PIN in, om u te authentificeren", - "Entrez votre PIN, pour vous authentifier", - "Bitte geben Sie Ihre PIN ein, um sich zu authentifizieren" -}; -static char *enter_pin_msg_sign[4] = { -#ifdef _WIN32 - "Caution: You are about to make a legally binding electronic signature with your identity card.\nPlease enter your PIN to continue or click the Cancel button.\n\nWarning: if you only want to log on to a web site or server, do NOT enter your PIN and click the Cancel button.", - "Let op: u gaat een wettelijk bindende electronische handtekening plaatsen met uw identiteitskaart.\nGeef uw PIN in om verder te gaan of klik op Stoppen.\n\nWaarschuwing: als u enkel wil aanloggen op een web site of een server, geef uw PIN NIET in en klik op Stoppen.", - "Attention: vous allez apposer une signature électronique juridiquement valide avec votre carte d'identité.\nVeuillez entrer votre PIN pour continuer ou cliquez sur Annuler.\n\nPrécaution: si vous désirez seulement vous connecter à un site ou un serveur, n'entrez PAS votre PIN et cliquez sur Annuler.", - "Achtung: Mit Ihrem Personalausweis werden Sie eine rechtlich bindende elektronische Signatur setzen.\nBitte geben Sie Ihre PIN ein zum weitergehen oder klicken Sie auf Abbrechen.\n\nWarnung: Wenn Sie nur auf das Internet gehen möchten, geben Sie bitte Ihre PIN NICHT ein, sondern klicken Sie auf Abbrechen." -#else -#ifdef __APPLE__ - "CAUTION: you are about to make a legally binding electronic signature with your identity card. Please enter your PIN to continue or press the Cancel button. If you only want to log on to a web site or a server, do NOT enter your PIN and press the Cancel button.", - "LET OP: u gaat een wettelijk bindende electronische handtekening plaatsen met uw identiteitskaart. Geef uw PIN in om verder te gaan of klik op Stoppen. Als u enkel wil aanloggen op een web site of een server, geef uw PIN NIET in en klik op Stoppen.", - "ATTENTION: vous allez apposer une signature electronique\njuridiquement valide avec votre carte d'identite.Veuillez entrer votre PIN pour continuer ou cliquez sur Annuler. Si vous desirez seulement vous connecter a un site ou un serveur, n' entrez PAS votre PIN et cliquez sur Annuler.", - "ACHTUNG: Mit Ihrem Personalausweis werden Sie eine rechtlich bindende elektronische Signatur setzen. Geben Sie Ihre PIN ein zum weitergehen oder klicken Sie auf Abbrechen. Warnung: Wenn Sie nur auf das Internet gehen mochten, geben Sie bitte Ihre PIN NICHT ein, sondern klicken Sie auf Abbrechen." -#else - "Caution: you are about to make a legally binding electronic\nsignature with your identity card.\nPlease enter your PIN to continue or press the Cancel button.\n\nIf you only want to log on to a web site or a server,\ndo NOT enter your PIN and press the Cancel button.", - "Let op: u gaat een wettelijk bindende electronische handtekening\nplaatsen met uw identiteitskaart.\nGeef uw PIN in om verder te gaan of klik op Stoppen.\n\nAls u enkel wil aanloggen op een web site\nof een server, geef uw PIN NIET in en klik op Stoppen.", - "Attention: vous allez apposer une signature electronique\njuridiquement valide avec votre carte d'identite.\nVeuillez entrer votre PIN pour continuer ou cliquez sur Annuler.\n\nSi vous desirez seulement vous connecter a un site\nou un serveur, n'entrez PAS votre PIN et cliquez sur Annuler.", - "Achtung: Mit Ihrem Personalausweis werden Sie eine rechtlich\r\nbindende elektronische Signatur setzen.\r\nGeben Sie Ihre PIN ein zum weitergehen oder klicken Sie auf Abbrechen.\r\n\r\nWarnung: Wenn Sie nur auf das Internet gehen mochten, geben\r\nSie bitte Ihre PIN NICHT ein, sondern klicken Sie auf Abbrechen." -#endif -#endif -}; -static char *wrong_pin_len_msgs[4] = { - "Wrong PIN length", - "Foute PIN lengte", - "Longueur de PIN erroné", - "Falsche PIN-Länge" -}; -static char *wrong_pin_msgs[4] = { - "Wrong PIN, %d tries left\n\nRetry or cancel?", - "Foute PIN, nog %d pogingen\n\nOpnieuw proberen of stoppen?", - "PIN erroné, %d essais restants\n\nRéessayer ou annuler?", - "Falsche PIN, %d verbleibende Versuche\n\nErneut versuchen oder abbrechen?" -}; -static char *pin_blocked_msgs[4] = { - "PIN blocked", - "PIN geblokkeerd", - "PIN bloqué ", - "PIN gesperrt" -}; - -#endif /* HAVE_GUI */ - -#ifdef BELPIC_PIN_PAD - -#define SCR_INIT_ID 100 -#define SCR_VERIFY_ID 101 -#define SCR_CHANGE_ID 102 -#define SCR_CARD_HANDLE 999 - -struct tTLV { - unsigned char *base; - unsigned char *end; - unsigned char *current; - unsigned char *next; -}; - -static void TLVInit(struct tTLV *tlv, u8 * base, size_t size) -{ - tlv->base = base; - tlv->end = base + size; - tlv->current = tlv->next = base; -} - -static void TLVNext(struct tTLV *tlv, u8 tag) -{ - assert(tlv->next + 2 < tlv->end); - tlv->current = tlv->next; - *(tlv->next++) = tag; - *(tlv->next++) = 0; -} - -static void TLVAdd(struct tTLV *tlv, u8 val) -{ - assert(tlv->next + 1 < tlv->end); - *(tlv->next++) = val; - tlv->current[1]++; -} - -static void TLVAddBuffer(struct tTLV *tlv, u8 * val, size_t size) -{ - assert(tlv->next + size < tlv->end); - memcpy(tlv->next, val, size); - tlv->current[1] = size; - tlv->next = tlv->next + size; -} - -static size_t TLVLen(struct tTLV *tlv) -{ - return tlv->next - tlv->base; -} - -static LONG SCR_SCardInit(LPCTSTR szPinPadDll, LPCTSTR szReader, DWORD version, - SCR_SupportConstants * supported) -{ - LONG rv; - unsigned char sendbuf[256]; - unsigned char recvbuf[2]; - char szTemp[32]; - DWORD dwRecvLength; - struct tTLV tlv; - - memset(szTemp, 0, sizeof(szTemp)); - memset(sendbuf, 0, sizeof(sendbuf)); - memset(recvbuf, 0, sizeof(recvbuf)); - dwRecvLength = sizeof(recvbuf); - - /* Make TLV buffer */ - TLVInit(&tlv, sendbuf, sizeof(sendbuf)); - TLVNext(&tlv, 0x01); /* Function ID */ - sprintf(szTemp, "%ld", SCR_INIT_ID); - TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp)); - TLVNext(&tlv, 0x02); /* PinPad Dll */ - TLVAddBuffer(&tlv, (u8 *) szPinPadDll, strlen(szPinPadDll)); - TLVNext(&tlv, 0x03); /* Reader Name */ - TLVAddBuffer(&tlv, (u8 *) szReader, strlen(szReader)); - TLVNext(&tlv, 0x04); /* Version */ - sprintf(szTemp, "%ld", version); - TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp)); - -#ifdef HAVE_PCSC_OLD - rv = SCardControl(SCR_CARD_HANDLE, sendbuf, TLVLen(&tlv), recvbuf, &dwRecvLength); -#else - rv = SCardControl(SCR_CARD_HANDLE, 0, sendbuf, TLVLen(&tlv), - recvbuf, dwRecvLength, &dwRecvLength); -#endif - if (dwRecvLength > 0) { - *supported = recvbuf[0]; - } else { - rv = SC_ERROR_UNKNOWN_DATA_RECEIVED; - } - - return rv; -} - -static LONG SCR_SCardPIN(long lAction, LPCTSTR szPinPadDll, const SCR_Card * pCard, BYTE pinID, - const SCR_PinUsage * pUsage, const SCR_Application * pApp, - BYTE * pCardStatus) -{ - LONG rv; - unsigned char sendbuf[256]; - unsigned char recvbuf[2]; - char szTemp[32]; - DWORD dwRecvLength; - struct tTLV tlv; - - memset(szTemp, 0, sizeof(szTemp)); - memset(recvbuf, 0, sizeof(recvbuf)); - dwRecvLength = sizeof(recvbuf); - - /* Make TLV buffer */ - TLVInit(&tlv, sendbuf, sizeof(sendbuf)); - TLVNext(&tlv, 0x01); /* Function ID */ - sprintf(szTemp, "%ld", lAction); - TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp)); - TLVNext(&tlv, 0x02); /* PinPad Dll */ - TLVAddBuffer(&tlv, (u8 *) szPinPadDll, strlen(szPinPadDll)); - TLVNext(&tlv, 0x03); /* SCR_Card Handle */ - sprintf(szTemp, "%ld", pCard->hCard); - TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp)); - if (pCard->language != NULL) { - TLVNext(&tlv, 0x04); /* SCR_Card language */ - TLVAddBuffer(&tlv, (u8 *) pCard->language, strlen(pCard->language)); - } - if (pCard->id.data != NULL) { - TLVNext(&tlv, 0x05); /* SCR_Card id */ - TLVAddBuffer(&tlv, pCard->id.data, pCard->id.length); - } - TLVNext(&tlv, 0x06); /* PinID */ - TLVAdd(&tlv, pinID); - if (pUsage != NULL) { - TLVNext(&tlv, 0x07); /* SCR_PinUsage code */ - sprintf(szTemp, "%ld", pUsage->code); - TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp)); - if (pUsage->shortString != NULL) { - TLVNext(&tlv, 0x08); /* SCR_PinUsage shortstring */ - TLVAddBuffer(&tlv, (u8 *) pUsage->shortString, strlen(pUsage->shortString)); - } - if (pUsage->longString != NULL) { - TLVNext(&tlv, 0x09); /* SCR_PinUsage longstring */ - TLVAddBuffer(&tlv, (u8 *) pUsage->longString, strlen(pUsage->longString)); - } - } - if (pApp->id.data != NULL) { - TLVNext(&tlv, 0x0A); /* SCR_Application id */ - TLVAddBuffer(&tlv, (u8 *) pApp->id.data, pApp->id.length); - } - if (pApp->shortString != NULL) { - TLVNext(&tlv, 0x0B); /* SCR_Application shortstring */ - TLVAddBuffer(&tlv, (u8 *) pApp->shortString, strlen(pApp->shortString)); - } - if (pApp->longString != NULL) { - TLVNext(&tlv, 0x0C); /* SCR_Application longstring */ - TLVAddBuffer(&tlv, (u8 *) pApp->longString, strlen(pApp->longString)); - } -#ifdef HAVE_PCSC_OLD - rv = SCardControl(SCR_CARD_HANDLE, sendbuf, TLVLen(&tlv), recvbuf, &dwRecvLength); -#else - rv = SCardControl(SCR_CARD_HANDLE, 0, sendbuf, TLVLen(&tlv), - recvbuf, dwRecvLength, &dwRecvLength); -#endif - if (dwRecvLength < 2) { - rv = SC_ERROR_UNKNOWN_DATA_RECEIVED; - } else { - memcpy(pCardStatus, recvbuf, 2); - } - - return rv; -} - -static LONG SCR_SCardVerifyPIN(LPCTSTR szPinPadDll, const SCR_Card * pCard, BYTE pinID, - const SCR_PinUsage * pUsage, const SCR_Application * pApp, - BYTE * pCardStatus) -{ - return SCR_SCardPIN(SCR_VERIFY_ID, szPinPadDll, pCard, pinID, pUsage, pApp, pCardStatus); -} - -static LONG SCR_SCardChangePIN(LPCTSTR szPinPadDll, const SCR_Card * pCard, BYTE pinID, - const SCR_Application * pApp, BYTE * pCardStatus) -{ - return SCR_SCardPIN(SCR_CHANGE_ID, szPinPadDll, pCard, pinID, NULL, pApp, pCardStatus); -} - -#endif /* BELPIC_PIN_PAD */ - -#if defined(HAVE_GUI) ||defined(BELPIC_PIN_PAD) - -static int belpic_calculate_lang(sc_card_t *card) -{ - struct belpic_priv_data *priv = DRVDATA(card); - int lang = priv->lang; - return lang; -} - -#endif /* defined(HAVE_GUI) ||defined(BELPIC_PIN_PAD) */ - -static int str2lang(sc_context_t *ctx, char *lang) -{ - if (memcmp(lang, "en", 2) == 0) - return LNG_ENG; - else if (memcmp(lang, "nl", 2) == 0) - return LNG_DUTCH; - else if (memcmp(lang, "fr", 2) == 0) - return LNG_FRENCH; - else if (memcmp(lang, "de", 2) == 0) - return LNG_GERMAN; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unknown/unsupported language code: %c%c\n", lang[0], lang[1]); - return -1; -} - static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddataloc_len) { sc_apdu_t apdu; @@ -651,258 +202,6 @@ static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddata return 0; } -#ifdef GET_LANG_FROM_CARD - -/* str is in lower case, the case of buf can be both, and buf is large enough */ -static int match_string(const char *str, const char *buf) -{ - int i = 0; - - while (str[i] != '\0') { - if (str[i] != ((buf[i] >= 'A' && buf[i] <= 'Z') ? buf[i] + 32 : buf[i])) - return 0; - i++; - } - return 1; /* match */ -} - -static int get_pref(const char *prefs, int prefs_len, const char *title, const char *key, int *len) -{ - int i = 0; - int title_len = strlen(title); - int key_len = strlen(key); - - while (prefs[i] != '\0' && i < prefs_len) - i++; - prefs_len = i; - - i = 0; - while (i < prefs_len) { - while (i < prefs_len && prefs[i] != '[') - i++; - if (i + title_len >= prefs_len) - return -1; - if (!match_string(title, prefs + i)) { - i++; - continue; - } - i += title_len; - while (i < prefs_len) { - while (i < prefs_len && (prefs[i] == '\r' || prefs[i] == '\n')) - i++; - if (i < prefs_len && prefs[i] == '[') - break; - if (i + key_len + 1 >= prefs_len) - return -2; - if (!match_string(key, prefs + i)) { - i++; - continue; - } - i += key_len; - if (prefs[i] != '=') - return -3; - *len = ++i; - while (*len < prefs_len && prefs[*len] != '\r' && prefs[*len] != '\n') - (*len)++; - *len -= i; - return i; - } - } - - return -1; -} - -static int get_language(sc_card_t *card) -{ - sc_apdu_t apdu; - u8 prefs[240], *lg_value; - u8 path[] = { 0x3F, 0x00, 0xDF, 0x01, 0x40, 0x39 }; - int r, i, len; - - /* Get the language from the card's preferences file */ - assert(card != NULL); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x08, 0x0C); - apdu.lc = sizeof(path); - apdu.data = path; - apdu.datalen = sizeof(path); - apdu.resplen = 0; - apdu.le = 0; - - r = sc_lock(card); - if (r < 0) - goto prefs_error; - - r = sc_transmit_apdu(card, &apdu); - if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Select_File[prefs_file] command failed: %d\n", r); - sc_unlock(card); - goto prefs_error; - } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Select_File[prefs_file]: card returned %d\n", r); - sc_unlock(card); - goto prefs_error; - } - - r = iso_ops->read_binary(card, 0, prefs, sizeof(prefs), 0); - sc_unlock(card); - if (r <= 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Read_Binary[prefs_file] returned %d\n", r); - goto prefs_error; - } - i = get_pref(prefs, r, "[gen]", "lg", &len); - if (i <= 0 || len < 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Couldn't find language in prefs file: %d\n", i); - goto prefs_error; - } - lg_value = prefs + i; /* language code(s) found, starts here */ - i = 0; - while (1) { - while (i <= len - 2 && (lg_value[i] == ' ' || lg_value[i] == '|')) - i++; - if (i > len - 2) - goto prefs_error; - r = str2lang(card->ctx, lg_value + i); - if (r >= 0) - return r; - i += 2; - } - - prefs_error: - /* If troubles with the card's prefs file, get the language from the OS */ -#ifdef _WIN32 - switch (GetUserDefaultLangID() & 0x00FF) { - case 0x13: - return LNG_DUTCH; - case 0x0C: - return LNG_FRENCH; - case 0x07: - return LNG_GERMAN; - default: - return LNG_ENG; - } -#endif - return LNG_ENG; /* default */ -} - -#endif /* GET_LANG_FROM_CARD */ - -static scconf_block *get_belpic_conf(sc_context_t *ctx, const char *name) -{ - scconf_block *conf_block = NULL, **blocks; - int i; - - for (i = 0; ctx->conf_blocks[i] != NULL; i++) { - blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name, NULL); - if (!blocks) - return NULL; - conf_block = blocks[0]; - free(blocks); - if (conf_block != NULL) - break; - } - - return conf_block; -} - -#ifdef BELPIC_PIN_PAD - -static void load_pin_pad_err(const char *reader_name, const char *pp_reader_lib, char *msg) -{ - char buf[300]; - void *hDlg; - - if (strlen(reader_name) + strlen(pp_reader_lib) > 200) - return; - - sprintf(buf, "Error while loading library \"%s\" for pin pad reader \"%s\": %s\n", - pp_reader_lib, reader_name, msg); - scgui_ask_message(app_msg[0], "Pin pad library error", buf, btn_msg_close[0], NULL, - reader_name); -} - -static int belpic_load_pin_pad_lib(sc_card_t *card, struct belpic_priv_data *priv_data, - const char *reader_name, const char *pp_reader_lib) -{ - LONG r; - DWORD supported; - - memset(priv_data->szPinPadDll, 0, sizeof(priv_data->szPinPadDll)); - strcpy(priv_data->szPinPadDll, pp_reader_lib); - - priv_data->scr_init = (FARPROC) SCR_SCardInit; - priv_data->scr_verify_pin = (FARPROC) SCR_SCardVerifyPIN; - priv_data->scr_change_pin = (FARPROC) SCR_SCardChangePIN; - - if (priv_data->scr_init == NULL || priv_data->scr_verify_pin == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Function not found in \"%s\" err = 0x%0x\n", - pp_reader_lib, GetLastError()); - load_pin_pad_err(reader_name, pp_reader_lib, - "unsufficient functionality found in library"); - return SC_ERROR_READER; - } - - r = priv_data->scr_init(pp_reader_lib, reader_name, 1, &supported); - if (r != SCARD_S_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SCR_Init() returned 0x%0x\n", r); - load_pin_pad_err(reader_name, pp_reader_lib, "Initialization of library failed"); - return SC_ERROR_READER; - } - if (supported) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SCR_init() returned not supported code 0x%0x\n", supported); - load_pin_pad_err(reader_name, pp_reader_lib, - "Initialization of library returned UNSUPPORTED"); - return SC_ERROR_READER; - } - return 1; -} - -static int belpic_detect_pin_pad(sc_card_t *card, struct belpic_priv_data *priv_data) -{ - int i = 0; - char *reader_name = card->reader->name, *conf_reader, *conf_lib; - scconf_block *conf_block = NULL; - char *reader_i = "reader ", *lib_i = "lib "; - int rn_len = strlen(reader_name); - - /* Hardcoded readers */ - for (i = 0; pp_reader_names[i] != NULL; i++) { - int pp_rn_len = strlen(pp_reader_names[i]); - if (rn_len >= pp_rn_len && strncmp(reader_name, pp_reader_names[i], pp_rn_len) == 0) { - return belpic_load_pin_pad_lib(card, priv_data, - reader_name, pp_reader_libs[i]); - } - } - - /* From the config file */ - conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad"); - if (conf_block == NULL) - return 0; - for (i = 0; i < 10; i++) { - reader_i[6] = (char) (0x30 + i); - conf_reader = (char *) scconf_get_str(conf_block, reader_i, NULL); - if (conf_reader != NULL && rn_len >= strlen(conf_reader) && - strncmp(reader_name, conf_reader, strlen(conf_reader)) == 0) { - lib_i[3] = (char) (0x30 + i); - conf_lib = (char *) scconf_get_str(conf_block, lib_i, NULL); - if (conf_lib != NULL) - return belpic_load_pin_pad_lib(card, priv_data, - reader_name, conf_lib); - } - } - - return 0; -} -#endif /* BELPIC_PIN_PAD */ - -static int belpic_finish(sc_card_t *card) -{ - free(DRVDATA(card)); - return 0; -} - static int belpic_match_card(sc_card_t *card) { int i; @@ -915,27 +214,14 @@ static int belpic_match_card(sc_card_t *card) static int belpic_init(sc_card_t *card) { - struct belpic_priv_data *priv = NULL; - scconf_block *conf_block; int key_size = 1024; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s", BELPIC_VERSION); -#ifdef HAVE_GUI - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with GUI support"); -#endif -#ifdef BELPIC_PIN_PAD - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with support for pin pad reader libs"); -#endif - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "\n"); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s\n", BELPIC_VERSION); if (card->type < 0) card->type = SC_CARD_TYPE_BELPIC_EID; /* Unknown card: assume it's the Belpic Card */ - priv = calloc(1, sizeof(struct belpic_priv_data)); - if (priv == NULL) - return SC_ERROR_OUT_OF_MEMORY; - card->drv_data = priv; card->cla = 0x00; if (card->type == SC_CARD_TYPE_BELPIC_EID) { u8 carddata[BELPIC_CARDDATA_RESP_LEN]; @@ -954,47 +240,8 @@ static int belpic_init(sc_card_t *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG; - /* Language prefences */ - priv->lang = -1; - conf_block = get_belpic_conf(card->ctx, "belpic_general"); - if (conf_block != NULL) { - char *lang = (char *) scconf_get_str(conf_block, "force_language", NULL); - if (lang != NULL && strlen(lang) == 2) - priv->lang = str2lang(card->ctx, lang); - } -#ifdef GET_LANG_FROM_CARD - if (priv->lang == -1) - priv->lang = get_language(card); -#endif - card->max_pin_len = BELPIC_MAX_USER_PIN_LEN; -#ifdef HAVE_GUI - r = scgui_init(); - if (r != 0) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_init() returned error %d\n", i); -#endif - -#ifdef BELPIC_PIN_PAD - r = belpic_detect_pin_pad(card, priv); - if (r == 1) - card->reader->capabilities |= SC_READER_CAP_PIN_PAD; - else if (r < 0) - return r; /* error loading/initing pin pad lib */ - - conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad"); - if (conf_block != NULL) { - if (scconf_get_bool(conf_block, "msg_auth_pin", 1)) - priv->options |= PP_MSG_AUTH_PIN; - if (scconf_get_bool(conf_block, "msg_wrong_pin", 1)) - priv->options |= PP_MSG_WRONG_PIN; - if (scconf_get_bool(conf_block, "msg_changepin_mismatch", 1)) - priv->options |= PP_MSG_CHANGEPIN_MISMATCH; - if (scconf_get_bool(conf_block, "msg_pin_blocked", 1)) - priv->options |= PP_MSG_PIN_BLOCKED; - } -#endif - return 0; } @@ -1074,192 +321,8 @@ static int belpic_read_binary(sc_card_t *card, return r; } -#ifdef BELPIC_PIN_PAD - -/* Test the result code of the pin pad reader + the card's status bytes */ -static int belpic_pp_test_res(sc_card_t *card, int r, const u8 * card_status, int *tries_left) -{ - if (r != SCARD_S_SUCCESS) { - switch (r) { - case SCARD_E_CANCELLED: - return SC_ERROR_KEYPAD_CANCELLED; - case SCARD_W_REMOVED_CARD: - return SC_ERROR_CARD_REMOVED; - case SCR_I_PIN_CHECK_FAILED: - return SC_ERROR_KEYPAD_PIN_MISMATCH; - default: - return SC_ERROR_TRANSMIT_FAILED; - } - } - if (card_status[0] == 0xEC && card_status[1] == 0xD2) - return SC_ERROR_KEYPAD_TIMEOUT; - if (card_status[0] == 0xEC && card_status[1] == 0xD6) - return SC_ERROR_KEYPAD_CANCELLED; - if (card_status[0] == 0x63) { - if ((card_status[1] & 0xF0) == 0xC0 && tries_left != NULL) - *tries_left = card_status[1] & 0x0F; - return SC_ERROR_PIN_CODE_INCORRECT; - } - return sc_check_sw(card, card_status[0], card_status[1]); -} - -/* Send the verify pin command to the pin pad reader + optionally show message */ -static int belpic_pp_verify(sc_card_t *card, SCR_Card * scr_card, - struct belpic_priv_data *priv, int pin_ref, - int pin_usage, int *tries_left) -{ - BYTE card_status[2]; - void *hDlg; - int first_time = 1, r = SC_ERROR_PIN_CODE_INCORRECT; - int lang = belpic_calculate_lang(card); - SCR_PinUsage scr_pin_usage = { - pin_usage, - pin_usage == SCR_USAGE_SIGN ? "SIG" : "AUT", - pin_usage == SCR_USAGE_SIGN ? pin_usg_sig[lang] : pin_usg_auth[lang] - }; - char *reader_name = card->reader->name; - char *pp_msg_login_sh = - (pin_usage == SCR_USAGE_SIGN ? pp_msg_sign_sh[lang] : pp_msg_auth_sh[lang]); - char *pp_msg_login = (pin_usage == SCR_USAGE_SIGN ? pp_msg_sign[lang] : pp_msg_auth[lang]); - scgui_param_t icon = (pin_usage == SCR_USAGE_SIGN ? SCGUI_SIGN_ICON : SCGUI_NO_ICON); - int mesg_on_screen = (priv->options & PP_MSG_AUTH_PIN) || - (pin_usage != SCR_USAGE_AUTH) || SSO_OK(card->ctx); - - while (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (!first_time) { - if (priv->options & PP_MSG_WRONG_PIN) { - int r1; - char msg[200]; - - sprintf(msg, wrong_pin_msgs[lang], *tries_left); - r1 = scgui_ask_message(app_msg[lang], pp_msg_login_sh, msg, - btn_msg_retry[lang], btn_msg_cancel[lang], - reader_name); - if (r1 == SCGUI_CANCEL) - return r; - else if (r1 != SCGUI_OK) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_ask_message returned %d\n", r1); - return SC_ERROR_INTERNAL; - } - } else - return r; - } - first_time = 0; - - if (mesg_on_screen) { - scgui_display_message(app_msg[lang], pp_msg_login_sh, pp_msg_login, - NULL, &hDlg, icon, reader_name); - } - r = priv->scr_verify_pin(priv->szPinPadDll, scr_card, pin_ref, - &scr_pin_usage, &scr_app_belpic, card_status); - if (mesg_on_screen) - scgui_remove_message(hDlg); - - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SCR_Verify_PIN(): res = 0x%0x, status = %2X %2X\n", - r, card_status[0], card_status[1]); - r = belpic_pp_test_res(card, r, card_status, tries_left); - } - - return r; -} - -/* Send the change pin command to the pin pad reader + show message */ -static int belpic_pp_change(sc_card_t *card, SCR_Card * scr_card, - struct belpic_priv_data *priv, int pin_ref, int *tries_left) -{ - BYTE card_status[2]; - void *hDlg; - int first_time = 1, r = SC_ERROR_KEYPAD_PIN_MISMATCH, r1; - int lang = belpic_calculate_lang(card); - char *reader_name = card->reader->name; - - while (r == SC_ERROR_KEYPAD_PIN_MISMATCH || r == SC_ERROR_PIN_CODE_INCORRECT) { - if (!first_time) { - int r1 = SCGUI_OK; - if (r == SC_ERROR_KEYPAD_PIN_MISMATCH) { - if (!(priv->options & PP_MSG_CHANGEPIN_MISMATCH)) - return r; - r1 = scgui_ask_message(app_msg[lang], pp_msg_change_sh[lang], - pp_msg_pin_mismatch[lang], - btn_msg_retry[lang], btn_msg_cancel[lang], - reader_name); - } - if (r == SC_ERROR_PIN_CODE_INCORRECT) { - char msg[200]; - - if (!(priv->options & PP_MSG_WRONG_PIN)) - return r; - sprintf(msg, wrong_pin_msgs[lang], *tries_left); - r1 = scgui_ask_message(app_msg[lang], pp_msg_change_sh[lang], - msg, btn_msg_retry[lang], - btn_msg_cancel[lang], reader_name); - } - if (r1 == SCGUI_CANCEL) - return r; - else if (r1 != SCGUI_OK) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_ask_message returned %d\n", r1); - return SC_ERROR_INTERNAL; - } - } - first_time = 0; - - scgui_display_message(app_msg[lang], pp_msg_change_sh[lang], - pp_msg_change[lang], NULL, &hDlg, SCGUI_NO_ICON, reader_name); - r = priv->scr_change_pin(priv->szPinPadDll, scr_card, pin_ref, - &scr_app_belpic, card_status); - scgui_remove_message(hDlg); - - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SCR_Change_PIN(): res = 0x%0x, status = %2X %2X\n", - r, card_status[0], card_status[1]); - r = belpic_pp_test_res(card, r, card_status, tries_left); - } - - return r; -} - -#endif /* BELPIC_PIN_PAD */ - -static int belpic_pin_cmd_usage(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left, int pin_usage) +static int belpic_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { -#ifdef BELPIC_PIN_PAD - sc_apdu_t apdu; - int r; - - struct belpic_priv_data *priv = DRVDATA(card); - int lang = belpic_calculate_lang(card); - if (card->reader->capabilities & SC_READER_CAP_PIN_PAD && priv->scr_init != NULL) { - LONG r; - SCR_Card scr_card = { - priv->pcsc_card, - lang_codes[lang], - {NULL, 0} - , - NULL - }; - - scr_app_belpic.longString = app_id_longstr[lang]; - - switch (data->cmd) { - case SC_PIN_CMD_VERIFY: - r = belpic_pp_verify(card, &scr_card, - priv, data->pin_reference, pin_usage, tries_left); - break; - case SC_PIN_CMD_CHANGE: - r = belpic_pp_change(card, &scr_card, - priv, data->pin_reference, tries_left); - break; - default: - r = SC_ERROR_NOT_SUPPORTED; - } - - if (r == SC_ERROR_AUTH_METHOD_BLOCKED && (priv->options & PP_MSG_PIN_BLOCKED)) - scgui_ask_message(app_msg[lang], " ", pin_blocked_msgs[lang], - btn_msg_close[lang], NULL, card->reader->name); - return r; - } -#endif /* BELPIC_PIN_PAD */ - data->pin1.encoding = data->pin2.encoding = BELPIC_PIN_ENCODING; data->pin1.pad_char = data->pin2.pad_char = BELPIC_PAD_CHAR; data->pin1.min_length = data->pin2.min_length = BELPIC_MIN_USER_PIN_LEN; @@ -1269,107 +332,6 @@ static int belpic_pin_cmd_usage(sc_card_t *card, struct sc_pin_cmd_data *data, return iso_ops->pin_cmd(card, data, tries_left); } -static int belpic_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) -{ - if (SSO_OK(card->ctx) && data->cmd == SC_PIN_CMD_VERIFY) - return 0; /* Don't log in right now, just say it's OK */ - else - return belpic_pin_cmd_usage(card, data, tries_left, 1); /* SCR_USAGE_AUTH = 1 */ -} - -#ifdef HAVE_GUI - -/* Called by belpic_set_security_env() when a NonRep signature will be done, - * or by belpic-compute_signature the first fime an auth signature is done - * and the allow_sso is true - */ -static int belpic_askpin_verify(sc_card_t *card, int pin_usage) -{ - struct sc_pin_cmd_data data; - sc_apdu_t apdu; - u8 pin_data[BELPIC_MAX_USER_PIN_LEN + 1]; - int pin_len; - int tries_left; - int r; - struct belpic_priv_data *priv = DRVDATA(card); - int lang = belpic_calculate_lang(card); - char *enter_pin_msg = (pin_usage == SCR_USAGE_AUTH ? - enter_pin_msg_auth[lang] : enter_pin_msg_sign[lang]); - scgui_param_t icon = (pin_usage == SCR_USAGE_AUTH ? SCGUI_NO_ICON : SCGUI_SIGN_ICON); - - data.pin1.encoding = BELPIC_PIN_ENCODING; - data.pin1.pad_char = BELPIC_PAD_CHAR; - data.pin1.min_length = BELPIC_MIN_USER_PIN_LEN; - data.pin1.max_length = BELPIC_MAX_USER_PIN_LEN; - - data.cmd = SC_PIN_CMD_VERIFY; - data.flags = 0; - data.pin_type = SC_AC_CHV; - data.pin_reference = 1; - - -#ifdef BELPIC_PIN_PAD - /* In case of a pinpad reader */ - if (card->reader->capabilities & SC_READER_CAP_PIN_PAD && priv->scr_init != NULL) { - data.pin1.data = NULL; - data.pin1.len = 0; - - return belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage); - } -#endif - - pin_len = BELPIC_MAX_USER_PIN_LEN + 1; - r = scgui_enterpin(app_msg[lang], enter_pin_msg, pin_data, &pin_len, - btn_msg_ok[lang], btn_msg_cancel[lang], wrong_pin_len_msgs[lang], icon); - if (r == SCGUI_CANCEL) - return SC_ERROR_KEYPAD_CANCELLED; - if (r != SCGUI_OK) - return SC_ERROR_INTERNAL; - - data.pin1.data = pin_data; - data.pin1.len = pin_len; - r = belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage); - - /* card->ctx->allow_sso = true: we do PIN mgmnt ourselves */ - while (r == SC_ERROR_PIN_CODE_INCORRECT && SSO_OK(card->ctx)) { - int r1; - char msg[200]; - - sprintf(msg, wrong_pin_msgs[lang], tries_left); - r1 = scgui_ask_message(app_msg[lang], pin_usg_auth[lang], msg, - btn_msg_retry[lang], btn_msg_cancel[lang], - card->reader->name); - if (r1 == SCGUI_CANCEL) - return r; - else if (r1 != SCGUI_OK) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_ask_message returned %d\n", r1); - return SC_ERROR_INTERNAL; - } - - pin_len = BELPIC_MAX_USER_PIN_LEN + 1; - r = scgui_enterpin(app_msg[lang], enter_pin_msg, pin_data, &pin_len, - btn_msg_ok[lang], btn_msg_cancel[lang], wrong_pin_len_msgs[lang], - icon); - if (r == SCGUI_CANCEL) - return SC_ERROR_KEYPAD_CANCELLED; - if (r != SCGUI_OK) - return SC_ERROR_INTERNAL; - - data.pin1.data = pin_data; - data.pin1.len = pin_len; - r = belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage); - if (tries_left == 0) - r = SC_ERROR_AUTH_METHOD_BLOCKED; - } - - if (r == SC_ERROR_AUTH_METHOD_BLOCKED && SSO_OK(card->ctx)) - scgui_ask_message(app_msg[lang], " ", pin_blocked_msgs[lang], - btn_msg_close[lang], NULL, card->reader->name); - - return r; -} -#endif /* HAVE_GUI */ - static int belpic_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { @@ -1428,58 +390,13 @@ static int belpic_set_security_env(sc_card_t *card, * the next function to be executed will be the compute_signature function. */ if (*env->key_ref == BELPIC_KEY_REF_NONREP) { -#ifdef HAVE_GUI - r = belpic_askpin_verify(card, SCR_USAGE_SIGN); - if (r != 0 && r != SC_ERROR_KEYPAD_CANCELLED) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verify PIN in SET command returned %d\n", r); - else - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verify PIN in SET command returned %d\n", r); -#else sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No GUI for NonRep key present, signature cancelled\n"); return SC_ERROR_NOT_SUPPORTED; -#endif - } - - return r; -} - -static int belpic_compute_signature(sc_card_t *card, const u8 * data, - size_t data_len, u8 * out, size_t outlen) -{ - int r; - - r = iso_ops->compute_signature(card, data, data_len, out, outlen); - -#ifdef HAVE_GUI - if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED && SSO_OK(card->ctx)) { - r = belpic_askpin_verify(card, SCR_USAGE_AUTH); - if (r == 0) - r = iso_ops->compute_signature(card, data, data_len, out, outlen); } -#endif return r; } -static int belpic_update_binary(sc_card_t *card, - unsigned int idx, const u8 *buf, size_t count, - unsigned long flags) -{ - int r; - - r = iso_ops->update_binary(card, idx, buf, count, flags); - -#ifdef HAVE_GUI - if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED && SSO_OK(card->ctx)) { - r = belpic_askpin_verify(card, SCR_USAGE_AUTH); - if (r == 0) - r = iso_ops->update_binary(card, idx, buf, count, flags); - } -#endif - - return r; -} - static struct sc_card_driver *sc_get_driver(void) { if (iso_ops == NULL) @@ -1487,15 +404,14 @@ static struct sc_card_driver *sc_get_driver(void) belpic_ops.match_card = belpic_match_card; belpic_ops.init = belpic_init; - belpic_ops.finish = belpic_finish; - belpic_ops.update_binary = belpic_update_binary; + belpic_ops.update_binary = iso_ops->update_binary; belpic_ops.select_file = belpic_select_file; belpic_ops.read_binary = belpic_read_binary; belpic_ops.pin_cmd = belpic_pin_cmd; belpic_ops.set_security_env = belpic_set_security_env; - belpic_ops.compute_signature = belpic_compute_signature; + belpic_ops.compute_signature = iso_ops->compute_signature; belpic_ops.get_challenge = iso_ops->get_challenge; belpic_ops.get_response = iso_ops->get_response; belpic_ops.check_sw = iso_ops->check_sw; From e1bc5153639e05e5dfe70f41ec0cbf9cfac8e535 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 7 Apr 2018 12:08:08 +0200 Subject: [PATCH 0221/4321] optionally try covertiy_scan with every build on master idea from https://github.com/umlaeute/Gem/blob/master/.travis.yml --- .travis.yml | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index c9a6e82c77..17dc9e00dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,19 +15,17 @@ addons: - xsltproc - gengetopt - help2man - coverity_scan: - project: - name: "OpenSC/OpenSC" - description: "Build submitted via Travis CI" - notification_email: viktor.tarasov@gmail.com - build_command: "make -j 4" - branch_pattern: coverity_scan env: global: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "UkHn7wy4im8V1nebCWbAetnDSOLRUbOlF6++ovk/7Bnso1/lnhXHelyzgRxfD/oI68wm9nnRV+RQEZ9+72Ug1CyvHxyyxxkwal/tPeHH4B/L+aGdPi0id+5OZSKIm77VP3m5s102sJMJgH7DFd03+nUd0K26p0tk8ad4j1geV4c=" + - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity.*)" + - COVERITY_SCAN_NOTIFICATION_EMAIL="viktor.tarasov@gmail.com" + - COVERITY_SCAN_BUILD_COMMAND="make -j 4" + - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" + - SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) matrix: fast_finish: true @@ -46,6 +44,8 @@ matrix: env: HOST=x86_64-w64-mingw32 - os: linux env: HOST=i686-w64-mingw32 + - os: linux + env: DO_COVERITY_SCAN=yes before_install: - if [ "$TRAVIS_OS_NAME" == "osx" ]; then @@ -56,10 +56,12 @@ before_install: fi before_script: - # we run a weekly cron job in travis on the coverity branch - # just synchronize it with master to get a new report - - if [ "${COVERITY_SCAN_BRANCH}" == 1 ]; then - git reset --hard origin/master; + - if [ "${DO_COVERITY_SCAN}" == "yes" ]; then + if ! curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash; + # coverity could not be initialized; propably quota is exhausted + # just continue with the normal CI build + true; + fi; fi - ./bootstrap - if [ -z "$HOST" ]; then @@ -77,17 +79,21 @@ before_script: fi script: - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then + - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then if [ $TRAVIS_OS_NAME == osx ]; then ./MacOSX/build; else - make; + if curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash; + make; + else + true; + fi; fi; fi - - if [ -z "$HOST" -a "${COVERITY_SCAN_BRANCH}" != 1 ]; then + - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then make check && make dist; fi - - if [ ! -z "$HOST" -a "${COVERITY_SCAN_BRANCH}" != 1 ]; then + - if [ ! -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then make install; wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss; fi From 148bc252388e581a3c998f3b5e3950ac21b9355c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 7 Apr 2018 12:11:13 +0200 Subject: [PATCH 0222/4321] fixed coverity issues - CID 145623 (#1 of 1): Resource leak (RESOURCE_LEAK) - CID 269069 (#1 of 1): Resource leak (RESOURCE_LEAK) - CID undefined (#1 of 1): Dereference before null check (REVERSE_INULL) --- src/libopensc/asn1.c | 4 +++- src/libopensc/ctx.c | 1 + src/pkcs11/framework-pkcs15.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index d70d03191a..b1be88dcf0 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -158,8 +158,10 @@ static void print_hex(const u8 * buf, size_t buflen, size_t depth) char *lines = malloc(lines_len); char *line = lines; - if (buf == NULL || buflen == 0 || lines == NULL) + if (buf == NULL || buflen == 0 || lines == NULL) { + free(lines); return; + } sc_hex_dump(buf, buflen, lines, lines_len); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 3dd0c0521f..e1ca82759f 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -808,6 +808,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) set_defaults(ctx, &opts); if (0 != list_init(&ctx->readers)) { + sc_release_context(ctx); return SC_ERROR_OUT_OF_MEMORY; } list_attributes_seeker(&ctx->readers, reader_list_seeker); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 5e42496987..b7fe88634b 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1618,7 +1618,7 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, } } - if (userType == CKU_CONTEXT_SPECIFIC && pin_info) { + if (userType == CKU_CONTEXT_SPECIFIC) { int auth_meth_saved = pin_info->auth_method; sc_log(context, "Setting SC_AC_CONTEXT_SPECIFIC"); From 647b623357c82f61043571d43ba8d1c4b1c28fb2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 7 Apr 2018 13:04:27 +0200 Subject: [PATCH 0223/4321] (hopefully) fixed .travis.yml --- .travis.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17dc9e00dc..835c251264 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,10 +56,10 @@ before_install: fi before_script: + # Optionally try to upload to Coverity Scan + # On error (propably quota is exhausted), just continue - if [ "${DO_COVERITY_SCAN}" == "yes" ]; then if ! curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash; - # coverity could not be initialized; propably quota is exhausted - # just continue with the normal CI build true; fi; fi @@ -83,11 +83,7 @@ script: if [ $TRAVIS_OS_NAME == osx ]; then ./MacOSX/build; else - if curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash; - make; - else - true; - fi; + make; fi; fi - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then From 54097c0fc024005d37d5a90896bcc28cc603d3dd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 7 Apr 2018 13:09:29 +0200 Subject: [PATCH 0224/4321] fixed .travis.yml --- .travis.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 835c251264..66dbd55706 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,13 +56,6 @@ before_install: fi before_script: - # Optionally try to upload to Coverity Scan - # On error (propably quota is exhausted), just continue - - if [ "${DO_COVERITY_SCAN}" == "yes" ]; then - if ! curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash; - true; - fi; - fi - ./bootstrap - if [ -z "$HOST" ]; then CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui; @@ -77,6 +70,9 @@ before_script: unset CXX; ./configure --host=$HOST --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; fi + # Optionally try to upload to Coverity Scan + # On error (propably quota is exhausted), just continue + - if [ "${DO_COVERITY_SCAN}" = "yes" ]; then curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash || true; fi script: - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then From 7b249084d89bbc28da951a938edde7658a6b347e Mon Sep 17 00:00:00 2001 From: Feitian Technologies Date: Wed, 11 Apr 2018 19:48:41 +0800 Subject: [PATCH 0225/4321] Improve code and fix sign bugs (#1306) 1. In epass2003_set_security_env, remove unused code, add condition check of ec and rsa 2. Line 1709 - add return check of hash_data 3. In epass2003_decipher API, the old sign using apdu.le = 256, now add condition check of rsa 4. Line 2731-2734 - After login successful, need get session status, adjust code, improve condition check of data->cmd. --- src/libopensc/card-epass2003.c | 82 +++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index f29be27ed0..6250c6a8cf 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1582,20 +1582,9 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, return SC_ERROR_INVALID_ARGUMENTS; exdata = (epass2003_exdata *)card->drv_data; - exdata->currAlg = SC_ALGORITHM_RSA; //default algorithm sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); - switch (env->operation) { - case SC_SEC_OPERATION_DECIPHER: - apdu.p2 = 0xB8; - break; - case SC_SEC_OPERATION_SIGN: - apdu.p2 = 0xB8; - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - + p = sbuf; *p++ = 0x80; /* algorithm reference */ *p++ = 0x01; @@ -1633,6 +1622,16 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, goto err; } } + else if(env->algorithm == SC_ALGORITHM_RSA) + { + exdata->currAlg = SC_ALGORITHM_RSA; + apdu.p2 = 0xB8; + sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0x\n",env->algorithm_flags); + } + else + { + sc_log(card->ctx, "%0x Alg Not Support! ", env->algorithm); + } if (se_num > 0) { r = sc_lock(card); @@ -1697,7 +1696,8 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data { if(exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA1) { - hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); + r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); + LOG_TEST_RET(card->ctx, r, "hash_data failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); apdu.data = sbuf; apdu.lc = 0x14; @@ -1705,7 +1705,8 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data } else if (exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA256) { - hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); + r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); + LOG_TEST_RET(card->ctx, r, "hash_data failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); apdu.data = sbuf; apdu.lc = 0x20; @@ -1728,15 +1729,30 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data } LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; + else if(exdata->currAlg == SC_ALGORITHM_RSA) + { + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 0; - memcpy(sbuf, data, datalen); - apdu.data = sbuf; - apdu.lc = datalen; - apdu.datalen = datalen; + memcpy(sbuf, data, datalen); + apdu.data = sbuf; + apdu.lc = datalen; + apdu.datalen = datalen; + } + else + { + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + + memcpy(sbuf, data, datalen); + apdu.data = sbuf; + apdu.lc = datalen; + apdu.datalen = datalen; + } r = sc_transmit_apdu_t(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -2680,15 +2696,19 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries data->pin1.max_tries = maxtries; } - - return r; +//reomve below code, because the old implement only return PIN retries, now modify the code and return PIN status +// return r; } - /* verify */ - if (data->cmd == SC_PIN_CMD_UNBLOCK) { + else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */ r = external_key_auth(card, (kid + 1), (unsigned char *)data->pin1.data, data->pin1.len); LOG_TEST_RET(card->ctx, r, "verify pin failed"); } + else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */ + r = update_secret_key(card, 0x04, kid, data->pin2.data, + (unsigned long)data->pin2.len); + LOG_TEST_RET(card->ctx, r, "verify pin failed"); + } else { r = external_key_auth(card, kid, (unsigned char *)data->pin1.data, data->pin1.len); @@ -2699,13 +2719,11 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries } LOG_TEST_RET(card->ctx, r, "verify pin failed"); - - if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { - /* change */ - r = update_secret_key(card, 0x04, kid, data->pin2.data, - (unsigned long)data->pin2.len); - LOG_TEST_RET(card->ctx, r, "verify pin failed"); + if (r == SC_SUCCESS) + { + data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN; } + return r; } From 29a27dd6d77595e9f9f428813d31961d53f7570c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Apr 2018 23:50:19 +0200 Subject: [PATCH 0226/4321] pkcs11-tool: Add examples section to the manual page --- doc/tools/pkcs11-tool.1.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 8db0e84a7a..6a1c5596b9 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -559,4 +559,26 @@ + + + Examples + + To list all certificates on the smart card: + pkcs11-tool --list-objects --type cert + + To read the certificate with ID KEY_ID + in DER format from smart card: + pkcs11-tool --read-object --id KEY_ID --type cert --outfile cert.der + + To convert the certificate in DER formato to PEM format, use OpenSSL + tools: + openssl x509 -inform DER -in cert.der -outform PEM > cert.pem + + To sign some data stored in file data + using the private key with ID ID and + using the RSA-PKCS mechanism: + pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig + + + From b4bc6de81bb70101eed716a67b893e5a90c3ac29 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 13 Apr 2018 18:42:31 +0200 Subject: [PATCH 0227/4321] prepare 0.18.0 --- appveyor.yml | 4 ++-- configure.ac | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dff2fe192c..de49e2fa9e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,8 +20,8 @@ install: throw "There are newer queued builds for this pull request, failing early." } - date /T & time /T - set PATH=C:\cygwin\bin;%PATH% - - set OPENPACE_VER=1.0.2 - - set ZLIB_VER_DOT=1.2.8 + - set OPENPACE_VER=1.0.3 + - set ZLIB_VER_DOT=1.2.11 - ps: $env:PACKAGE_NAME=(git describe --tags) - ps: >- If ($env:Platform -Match "x86") { diff --git a/configure.ac b/configure.ac index 8116ae5894..46e90e0df4 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ define([PRODUCT_NAME], [OpenSC]) define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [17]) +define([PACKAGE_VERSION_MINOR], [18]) define([PACKAGE_VERSION_FIX], [0]) define([PACKAGE_SUFFIX], []) @@ -43,8 +43,8 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Code changed: REVISION++) # (Oldest interface removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) -OPENSC_LT_CURRENT="5" -OPENSC_LT_OLDEST="5" +OPENSC_LT_CURRENT="6" +OPENSC_LT_OLDEST="6" OPENSC_LT_REVISION="0" OPENSC_LT_AGE="0" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" From 5abe99d228e73a3e2a0786c7029917ca502ca3e8 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Apr 2018 19:38:34 +0200 Subject: [PATCH 0228/4321] fix typos Mass-typo fixing, almost exclusively in comments and text strings. While at it also fixed a few (very few) grammar errors. --- NEWS | 2 +- doc/tools/dnie-tool.1.xml | 2 +- doc/tools/gids-tool.1.xml | 2 +- doc/tools/netkey-tool.1.xml | 6 +- doc/tools/piv-tool.1.xml | 2 +- doc/tools/pkcs11-tool.1.xml | 2 +- doc/tools/pkcs15-crypt.1.xml | 4 +- doc/tools/pkcs15-init.1.xml | 8 +-- doc/tools/pkcs15-profile.5.xml | 2 +- doc/tools/westcos-tool.1.xml | 8 +-- etc/opensc.conf.in | 10 +-- solaris/opensc.conf-dist | 4 +- src/common/README.compat_getopt | 8 +-- src/common/README.compat_strlcpy | 2 +- src/common/compat_getopt.c | 2 +- src/common/simclist.c | 4 +- src/common/simclist.h | 22 +++---- src/libopensc/apdu.c | 8 +-- src/libopensc/aux-data.h | 2 +- src/libopensc/card-acos5.c | 2 +- src/libopensc/card-asepcos.c | 10 +-- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-belpic.c | 22 +++---- src/libopensc/card-cac.c | 12 ++-- src/libopensc/card-cardos.c | 8 +-- src/libopensc/card-coolkey.c | 28 ++++----- src/libopensc/card-dnie.c | 52 ++++++++-------- src/libopensc/card-entersafe.c | 6 +- src/libopensc/card-epass2003.c | 6 +- src/libopensc/card-flex.c | 2 +- src/libopensc/card-gids.c | 6 +- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-iasecc.c | 8 +-- src/libopensc/card-incrypto34.c | 2 +- src/libopensc/card-isoApplet.c | 12 ++-- src/libopensc/card-itacns.c | 2 +- src/libopensc/card-jcop.c | 2 +- src/libopensc/card-masktech.c | 2 +- src/libopensc/card-mcrd.c | 14 ++--- src/libopensc/card-muscle.c | 8 +-- src/libopensc/card-npa.c | 8 +-- src/libopensc/card-oberthur.c | 4 +- src/libopensc/card-openpgp.c | 4 +- src/libopensc/card-piv.c | 62 +++++++++---------- src/libopensc/card-setcos.c | 10 +-- src/libopensc/card-starcos.c | 8 +-- src/libopensc/card-tcos.c | 2 +- src/libopensc/card-westcos.c | 4 +- src/libopensc/card.c | 6 +- src/libopensc/cardctl.h | 8 +-- src/libopensc/ctbcs.h | 14 ++--- src/libopensc/ctx.c | 2 +- src/libopensc/cwa-dnie.c | 24 +++---- src/libopensc/cwa14890.c | 42 ++++++------- src/libopensc/cwa14890.h | 16 ++--- src/libopensc/dir.c | 2 +- src/libopensc/iasecc-sdo.c | 24 +++---- src/libopensc/iasecc-sdo.h | 2 +- src/libopensc/iasecc-sm.c | 2 +- src/libopensc/internal-winscard.h | 2 +- src/libopensc/iso7816.c | 2 +- src/libopensc/muscle-filesystem.c | 2 +- src/libopensc/opensc.h | 36 +++++------ src/libopensc/pkcs15-cert.c | 4 +- src/libopensc/pkcs15-coolkey.c | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 6 +- src/libopensc/pkcs15-gemsafeV1.c | 4 +- src/libopensc/pkcs15-iasecc.c | 6 +- src/libopensc/pkcs15-itacns.c | 4 +- src/libopensc/pkcs15-oberthur.c | 6 +- src/libopensc/pkcs15-piv.c | 26 ++++---- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15-sec.c | 4 +- src/libopensc/pkcs15-syn.c | 2 +- src/libopensc/pkcs15.h | 4 +- src/libopensc/reader-cryptotokenkit.m | 2 +- src/libopensc/reader-ctapi.c | 6 +- src/libopensc/reader-openct.c | 2 +- src/libopensc/reader-pcsc.c | 2 +- src/libopensc/sc-ossl-compat.h | 6 +- src/libopensc/sec.c | 2 +- src/libopensc/sm.h | 4 +- src/minidriver/minidriver.c | 32 +++++----- src/minidriver/versioninfo-minidriver.rc.in | 2 +- src/pkcs11/framework-pkcs15.c | 16 ++--- src/pkcs11/mechanism.c | 4 +- src/pkcs11/pkcs11-global.c | 2 +- src/pkcs11/pkcs11-opensc.h | 4 +- src/pkcs11/pkcs11-session.c | 2 +- src/pkcs11/pkcs11-spy.c | 6 +- src/pkcs11/pkcs11.h | 2 +- src/pkcs11/sc-pkcs11.h | 4 +- src/pkcs15init/ias_adele_admin1.profile | 2 +- src/pkcs15init/ias_adele_admin2.profile | 4 +- src/pkcs15init/ias_adele_common.profile | 2 +- src/pkcs15init/iasecc.profile | 2 +- src/pkcs15init/iasecc_admin_eid.profile | 4 +- .../iasecc_generic_oberthur.profile | 2 +- src/pkcs15init/iasecc_generic_pki.profile | 4 +- src/pkcs15init/oberthur.profile | 4 +- src/pkcs15init/pkcs15-asepcos.c | 6 +- src/pkcs15init/pkcs15-authentic.c | 2 +- src/pkcs15init/pkcs15-cardos.c | 2 +- src/pkcs15init/pkcs15-epass2003.c | 2 +- src/pkcs15init/pkcs15-iasecc.c | 10 +-- src/pkcs15init/pkcs15-init.h | 2 +- src/pkcs15init/pkcs15-isoApplet.c | 6 +- src/pkcs15init/pkcs15-lib.c | 8 +-- src/pkcs15init/pkcs15-oberthur-awp.c | 10 +-- src/pkcs15init/pkcs15-oberthur.c | 8 +-- src/pkcs15init/pkcs15-starcos.c | 2 +- src/pkcs15init/pkcs15-westcos.c | 2 +- src/pkcs15init/setcos.profile | 4 +- src/scconf/README.scconf | 6 +- src/scconf/scconf.c | 2 +- src/sm/sm-eac.c | 8 +-- src/sm/sm-iso-internal.h | 2 +- src/smm/sm-card-authentic.c | 2 +- src/smm/sm-card-iasecc.c | 4 +- src/tools/cardos-tool.c | 8 +-- src/tools/dnie-tool.c | 6 +- src/tools/egk-tool-cmdline.h | 4 +- src/tools/gids-tool.c | 4 +- src/tools/netkey-tool.c | 8 +-- src/tools/npa-tool-cmdline.c | 4 +- src/tools/npa-tool-cmdline.h | 12 ++-- src/tools/npa-tool.1 | 2 +- src/tools/npa-tool.ggo.in | 2 +- src/tools/openpgp-tool.c | 2 +- src/tools/opensc-explorer.c | 2 +- src/tools/piv-tool.c | 2 +- src/tools/pkcs11-tool.c | 8 +-- src/tools/pkcs15-init.c | 10 +-- src/tools/sc-hsm-tool.c | 2 +- src/tools/versioninfo-opensc-notify.rc.in | 2 +- src/tools/westcos-tool.c | 12 ++-- src/ui/notify.c | 2 +- win32/Make.rules.mak | 2 +- win32/versioninfo.rc.in | 2 +- 140 files changed, 486 insertions(+), 486 deletions(-) diff --git a/NEWS b/NEWS index 85cc4e292b..be84ec7a4e 100644 --- a/NEWS +++ b/NEWS @@ -483,7 +483,7 @@ New in 0.12.0; 2010-12-22 card initialized by Siemens software. Removed "--split-key" option, as it is no longer needed. * Improved debugging support: debug level 3 will show everything - except of ASN1 and card matching debugging (usualy not needed). + except of ASN1 and card matching debugging (usually not needed). * Massive changes to libopensc. This library is now internal, only used by opensc-pkcs11.so and command line tools. Header files are no longer installed, library should not be used by other applications. diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index d58b25b2b7..dd79c0ef95 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -68,7 +68,7 @@ Show DNIe sw version. - Displays sofware version for in-card DNIe OS + Displays software version for in-card DNIe OS diff --git a/doc/tools/gids-tool.1.xml b/doc/tools/gids-tool.1.xml index 33d898988a..13a76b4bb3 100644 --- a/doc/tools/gids-tool.1.xml +++ b/doc/tools/gids-tool.1.xml @@ -75,7 +75,7 @@ argument - Define the new adminastrator key. + Define the new administrator key. diff --git a/doc/tools/netkey-tool.1.xml b/doc/tools/netkey-tool.1.xml index a9f5ea2909..5639324051 100644 --- a/doc/tools/netkey-tool.1.xml +++ b/doc/tools/netkey-tool.1.xml @@ -91,7 +91,7 @@ PIN format With the , , or the one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string - (i.e. 31:32:33:34:35:36). A hex-string must consists of exacly n 2-digit hexnumbers separated by n-1 colons. + (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4. @@ -112,7 +112,7 @@ current value of your global PIN. For most of the commands that netkey-tool can execute, you have - to specify one pin. One notable exeption is the nullpin command, but + to specify one pin. One notable exception is the nullpin command, but this command can only be executed once in the lifetime of a NetKey E4 card. @@ -154,7 +154,7 @@ This command can be executed only if the global PIN of your card is in nullpin-state. There's no way to return back to nullpin-state once you have changed - your global PIN. You don't need a pin to execute the nullpin-command. After a succesfull + your global PIN. You don't need a pin to execute the nullpin-command. After a successful nullpin-command netkey-tool will display your cards initial PUK-value. diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 527d527784..30e7ac7960 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -24,7 +24,7 @@ The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. - It is intened for use with test cards only. It can be used to load objects, and generate + It is intended for use with test cards only. It can be used to load objects, and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 6a1c5596b9..fedfdab02f 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -570,7 +570,7 @@ in DER format from smart card: pkcs11-tool --read-object --id KEY_ID --type cert --outfile cert.der - To convert the certificate in DER formato to PEM format, use OpenSSL + To convert the certificate in DER format to PEM format, use OpenSSL tools: openssl x509 -inform DER -in cert.der -outform PEM > cert.pem diff --git a/doc/tools/pkcs15-crypt.1.xml b/doc/tools/pkcs15-crypt.1.xml index 9200330be5..e329904911 100644 --- a/doc/tools/pkcs15-crypt.1.xml +++ b/doc/tools/pkcs15-crypt.1.xml @@ -174,9 +174,9 @@ When signing with ECDSA key this option indicates to pkcs15-crypt the signature output format. - Possible values are 'rs'(default) -- two concatanated + Possible values are 'rs'(default) -- two concatenated integers (PKCS#11), 'sequence' or 'openssl' -- DER encoded sequence - of two integeres (OpenSSL). + of two integers (OpenSSL). diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 3a0bd28cef..ad3646a210 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -315,7 +315,7 @@ It is a good idea to specify the key ID along with this command, using the option, otherwise an intrinsic ID will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribut in the 'pkcs15.profile' for the details + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details about the algorithm used to calculate intrinsic ID. For the multi-application cards the target PKCS#15 application can be specified by the hexadecimal AID value of the option. @@ -419,9 +419,9 @@ Tells pkcs15-init to store the certificate given in on the card, creating a certificate object with the ID specified via the option. - Without supplied ID an intrisic ID will be calculated from the + Without supplied ID an intrinsic ID will be calculated from the certificate's public key. Look the description of the 'pkcs15-id-style' - attribut in the 'pkcs15.profile' for the details + attribute in the 'pkcs15.profile' for the details about the algorithm used to calculate intrinsic ID. The file is assumed to contain the PEM encoded certificate. For the multi-application cards the target application can be specified @@ -460,7 +460,7 @@ It is a good idea to specify the key ID along with this command, using the option, otherwise an intrinsic ID will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribut in the 'pkcs15.profile' for the details + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details about the algorithm used to calculate intrinsic ID. For the multi-application cards the target PKCS#15 application can be specified by the hexadecimal AID value of the option. diff --git a/doc/tools/pkcs15-profile.5.xml b/doc/tools/pkcs15-profile.5.xml index a2e28d7a2f..85f939ca7c 100644 --- a/doc/tools/pkcs15-profile.5.xml +++ b/doc/tools/pkcs15-profile.5.xml @@ -31,7 +31,7 @@ The card specific profile contains additional information required during - card intialization, such as location of PIN files, key references etc. + card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index d1609967ab..d0a4cd4737 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -62,8 +62,8 @@ Finalize the card. Once finalized the default key is invalidated, so PIN and PUK cannot be changed anymore without user authentication. - Warning, un-finalized are insecure because PIN can be changed - without user authentication (knowledge of default key + Warning, un-finalized cards are insecure because the PIN can be + changed without user authentication (knowledge of default key is enough). @@ -73,8 +73,8 @@ Generate a private key on the card. The card must not have - been finalized and a PIN must be installed (ie. the file for ithe PIN must - havei been created, see option ). + been finalized and a PIN must be installed (i.e. the file for the PIN must + have been created, see option ). By default the key length is 1536 bits. User authentication is required for this operation. diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 939901e026..a1d9d8fcbc 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -51,7 +51,7 @@ app default { # disable_popups = true; # Enable default card driver - # Default card driver is explicitely enabled for the 'opensc-explorer' and 'opensc-tool'. + # Default card driver is explicitly enabled for the 'opensc-explorer' and 'opensc-tool'. # # Default: false # enable_default_driver = true; @@ -147,7 +147,7 @@ app default { # statically linked drivers that may be removed in the future. # # A special value of 'internal' will load all - # statically linked drivers. If an unknown (ie. not + # statically linked drivers. If an unknown (i.e. not # internal) driver is supplied, a separate configuration # configuration block has to be written for the driver. # Default: internal @@ -982,8 +982,8 @@ app default { # - type (generic, protected) used to distinguish the common access application # and application for which authentication to perform some operation cannot be # obtained with the common procedures (ex. object creation protected by secure messaging). - # Used by PKCS#11 module configurated to expose restricted number of slots. - # (for ex. configurated to expose only User PIN slot, User and Sign PINs slots, ...) + # Used by PKCS#11 module configured to expose restricted number of slots. + # (for ex. configured to expose only User PIN slot, User and Sign PINs slots, ...) # # - disable: do not expose application in PKCS15 framework # default 'false' @@ -1071,7 +1071,7 @@ app opensc-pkcs11 { # abusing an existing login or they may logout unnoticed. # # With this setting enabled the login state of the token is tracked and - # cached (including the PIN). Every transaction is preceeded by + # cached (including the PIN). Every transaction is preceded by # restoring the login state. After every transaction a logout is # performed. This setting by default also enables `lock_login` (see # above) to disable access for other applications during the atomic diff --git a/solaris/opensc.conf-dist b/solaris/opensc.conf-dist index 4c0bc81735..19989419d3 100644 --- a/solaris/opensc.conf-dist +++ b/solaris/opensc.conf-dist @@ -35,7 +35,7 @@ app default { # What reader drivers to load at start-up # # A special value of 'internal' will load all - # statically linked drivers. If an unknown (ie. not + # statically linked drivers. If an unknown (i.e. not # internal) driver is supplied, a separate configuration # configuration block has to be written for the driver. # Default: internal @@ -96,7 +96,7 @@ app default { # What card drivers to load at start-up # # A special value of 'internal' will load all - # statically linked drivers. If an unknown (ie. not + # statically linked drivers. If an unknown (i.e. not # internal) driver is supplied, a separate configuration # configuration block has to be written for the driver. # Default: internal diff --git a/src/common/README.compat_getopt b/src/common/README.compat_getopt index 7b4b770b89..2fdf213d36 100644 --- a/src/common/README.compat_getopt +++ b/src/common/README.compat_getopt @@ -94,14 +94,14 @@ WHY RE-INVENT THE WHEEL? ======================== I re-implemented getopt, getopt_long, and getopt_long_only because -there were noticable bugs in several versions of the GNU +there were noticeable bugs in several versions of the GNU implementations, and because the GNU versions aren't always available on some systems (*BSD, for example.) Other systems don't include any sort of standard argument parser (Win32 with Microsoft tools, for example, has no getopt.) These should do all the expected Unix- and GNU-style argument -parsing, including permution, bunching, long options with single or +parsing, including permutation, bunching, long options with single or double dashes (double dashes are required if you use my_getopt_long,) and optional arguments for both long and short options. A word with double dashes all by themselves halts argument @@ -112,11 +112,11 @@ separated by '='. As with the GNU versions, a '+' prefix to the short option specification (or the POSIXLY_CORRECT environment variable) disables -permution, a '-' prefix to the short option specification returns 1 +permutation, a '-' prefix to the short option specification returns 1 for non-options, ':' after a short option indicates a required argument, and '::' after a short option specification indicates an optional argument (which must appear in the same word.) If you'd like -to recieve ':' instead of '?' for missing option arguments, prefix the +to receive ':' instead of '?' for missing option arguments, prefix the short option specification with ':'. The original intent was to re-implement the documented behavior of diff --git a/src/common/README.compat_strlcpy b/src/common/README.compat_strlcpy index 2f7c81efc1..6169e7d5e2 100644 --- a/src/common/README.compat_strlcpy +++ b/src/common/README.compat_strlcpy @@ -1,5 +1,5 @@ strncpy() is unsafe since it does not always add a final NUL-byte. -OpenBSD developped a safer version called strlcpy(). +OpenBSD developed a safer version called strlcpy(). Use "man -l strlcpy.3" to read the manpage. diff --git a/src/common/compat_getopt.c b/src/common/compat_getopt.c index e44ebca63e..951e355458 100644 --- a/src/common/compat_getopt.c +++ b/src/common/compat_getopt.c @@ -41,7 +41,7 @@ char *my_optarg=0; /* this is the plain old UNIX getopt, with GNU-style extensions. */ /* if you're porting some piece of UNIX software, this is all you need. */ -/* this supports GNU-style permution and optional arguments */ +/* this supports GNU-style permutation and optional arguments */ int my_getopt(int argc, char * argv[], const char *opts) { diff --git a/src/common/simclist.c b/src/common/simclist.c index e22c236771..3cd3a1c037 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -119,7 +119,7 @@ #include "simclist.h" -/* minumum number of elements for sorting with quicksort instead of insertion */ +/* minimum number of elements for sorting with quicksort instead of insertion */ #define SIMCLIST_MINQUICKSORTELS 24 @@ -199,7 +199,7 @@ static simclist_inline struct list_entry_s *list_findpos(const list_t *simclist_ * 3. avoid interference with user's RNG * * Facts pro system RNG: - * 1. may be more accurate (irrelevant for SimCList randno purposes) + * 1. may be more accurate (irrelevant for SimCList random purposes) * 2. why reinvent the wheel * * Default to local RNG for user's ease of use. diff --git a/src/common/simclist.h b/src/common/simclist.h index 49ac31fde5..b6ef9f9d2a 100644 --- a/src/common/simclist.h +++ b/src/common/simclist.h @@ -106,7 +106,7 @@ typedef struct { * -# receives two references to elements a and b * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively * - * It is responsability of the function to handle possible NULL values. + * It is responsibility of the function to handle possible NULL values. */ typedef int (*element_comparator)(const void *a, const void *b); @@ -118,7 +118,7 @@ typedef int (*element_comparator)(const void *a, const void *b); * -# receives a reference to some indicator data * -# returns non-0 if the element matches the indicator, 0 otherwise * - * It is responsability of the function to handle possible NULL values in any + * It is responsibility of the function to handle possible NULL values in any * argument. */ typedef int (*element_seeker)(const void *el, const void *indicator); @@ -130,7 +130,7 @@ typedef int (*element_seeker)(const void *el, const void *indicator); * -# receives the reference to an element el * -# returns its size in bytes * - * It is responsability of the function to handle possible NULL values. + * It is responsibility of the function to handle possible NULL values. */ typedef size_t (*element_meter)(const void *el); @@ -141,7 +141,7 @@ typedef size_t (*element_meter)(const void *el); * -# receives the reference to an element el * -# returns a hash value for el * - * It is responsability of the function to handle possible NULL values. + * It is responsibility of the function to handle possible NULL values. */ typedef list_hash_t (*element_hash_computer)(const void *el); @@ -151,7 +151,7 @@ typedef list_hash_t (*element_hash_computer)(const void *el); * A serializer function is one that gets a reference to an element, * and returns a reference to a buffer that contains its serialization * along with the length of this buffer. - * It is responsability of the function to handle possible NULL values, + * It is responsibility of the function to handle possible NULL values, * returning a NULL buffer and a 0 buffer length. * * These functions have 3 goals: @@ -290,7 +290,7 @@ int list_attributes_seeker(list_t *simclist_restrict l, element_seeker seeker_fu * the list by its actual data is not free()d. With this option, every * deletion causes element data to be freed. * - * It is responsability of this function to correctly handle NULL values, if + * It is responsibility of this function to correctly handle NULL values, if * NULL elements are inserted into the list. * * @param l list to operate @@ -470,7 +470,7 @@ int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int p * expunge the first found given element from the list. * * Inspects the given list looking for the given element; if the element - * is found, it is removed. Only the first occurence is removed. + * is found, it is removed. Only the first occurrence is removed. * If a comparator function was not set, elements are compared by reference. * Otherwise, the comparator is used to match the element. * @@ -505,7 +505,7 @@ int list_delete_range(list_t *simclist_restrict l, unsigned int posstart, unsign /** * clear all the elements off of the list. * - * The element datums will not be freed. + * The element data will not be freed. * * @see list_delete_range() * @see list_size() @@ -595,7 +595,7 @@ int list_contains(const list_t *simclist_restrict l, const void *data); * user-provided list object, which must be different from both the * lists to concatenate. Attributes from the original lists are not * cloned. - * The destination list referred is threated as virgin room: if it + * The destination list referred is treated as virgin room: if it * is an existing list containing elements, memory leaks will happen. * It is OK to specify the same list twice as source, for "doubling" * it in the destination. @@ -672,7 +672,7 @@ int list_hash(const list_t *simclist_restrict l, list_hash_t *simclist_restrict #ifdef SIMCLIST_DUMPRESTORE /** - * get meta informations on a list dump on filedescriptor. + * get meta information on a list dump on filedescriptor. * * [ advanced function ] * @@ -689,7 +689,7 @@ int list_hash(const list_t *simclist_restrict l, list_hash_t *simclist_restrict int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *simclist_restrict info); /** - * get meta informations on a list dump on file. + * get meta information on a list dump on file. * * [ advanced function ] * diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 258e0f2253..a81d185dbc 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -244,7 +244,7 @@ int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf, * +-------------------------------+ * | * v - * card->reader->ops->tranmit + * card->reader->ops->transmit */ /** basic consistency check of the sc_apdu_t object @@ -350,7 +350,7 @@ sc_detect_apdu_cse(const sc_card_t *card, sc_apdu_t *apdu) if (apdu->cse == SC_APDU_CASE_2 || apdu->cse == SC_APDU_CASE_3 || apdu->cse == SC_APDU_CASE_4) { int btype = apdu->cse & SC_APDU_SHORT_MASK; - /* if either Lc or Le is bigger than the maximun for + /* if either Lc or Le is bigger than the maximum for * short APDUs and the card supports extended APDUs * use extended APDUs (unless Lc is greater than * 255 and command chaining is activated) */ @@ -443,7 +443,7 @@ sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen) if (!card->ops->get_response) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "no GET RESPONSE command"); - /* call GET RESPONSE until we have read all data requested or until the card retuns 0x9000, + /* call GET RESPONSE until we have read all data requested or until the card returns 0x9000, * whatever happens first. */ /* if there are already data in response append a new data to the end of the buffer */ @@ -524,7 +524,7 @@ sc_transmit(sc_card_t *card, sc_apdu_t *apdu) LOG_TEST_RET(ctx, r, "transmit APDU failed"); /* ok, the APDU was successfully transmitted. Now we have two special cases: - * 1. the card returned 0x6Cxx: in this case APDU will be re-trasmitted with Le set to SW2 + * 1. the card returned 0x6Cxx: in this case APDU will be re-transmitted with Le set to SW2 * (possible only if response buffer size is larger than new Le = SW2) */ if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) diff --git a/src/libopensc/aux-data.h b/src/libopensc/aux-data.h index 027fe4c489..9564bfde2e 100644 --- a/src/libopensc/aux-data.h +++ b/src/libopensc/aux-data.h @@ -1,6 +1,6 @@ /* * aux-data.h: Non PKCS#15, non ISO7816 data - * Used to pass auxiliary data from non PKCS#15, non ISO7816 appliations (like minidriver) + * Used to pass auxiliary data from non PKCS#15, non ISO7816 applications (like minidriver) * to card specific part through the standard PKCS#15 and ISO7816 frameworks * * Copyright (C) 2016 Viktor Tarasov diff --git a/src/libopensc/card-acos5.c b/src/libopensc/card-acos5.c index 3e39258561..64b1ad774f 100644 --- a/src/libopensc/card-acos5.c +++ b/src/libopensc/card-acos5.c @@ -181,7 +181,7 @@ static int acos5_list_files(sc_card_t * card, u8 * buf, size_t buflen) /* * Use CARD GET INFO to fetch the number of files under the - * curently selected DF. + * currently selected DF. */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x14, 0x01, 0x00); apdu.cla |= 0x80; diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 6a79b80e18..83e64b2d4a 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -140,7 +140,7 @@ static int set_sec_attr(sc_file_t *file, unsigned int am, unsigned int ac, { const amode_entry_t *table; - /* CHV with reference '0' is the trasport PIN + /* CHV with reference '0' is the transport PIN * and is presented as 'AUT' key with reference '0'*/ if (meth == SC_AC_CHV && ac == 0) meth = SC_AC_AUT; @@ -377,7 +377,7 @@ static int asepcos_set_security_attributes(sc_card_t *card, sc_file_t *file) u8 buf[64], *p; int r = SC_SUCCESS; - /* first check wether the security attributes in encoded form + /* first check whether the security attributes in encoded form * are already set. If present use these */ if (file->sec_attr != NULL && file->sec_attr_len != 0) return asepcos_set_sec_attributes(card, file->sec_attr, @@ -420,7 +420,7 @@ static int asepcos_set_security_attributes(sc_card_t *card, sc_file_t *file) *p++ = (st.fileid >> 8 ) & 0xff; *p++ = st.fileid & 0xff; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unknow auth method: '%d'", ent->method); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unknown auth method: '%d'", ent->method); return SC_ERROR_INTERNAL; } } @@ -746,7 +746,7 @@ static int asepcos_delete_file(sc_card_t *card, const sc_path_t *path) buf[0] = path->value[path->len-2]; buf[1] = path->value[path->len-1]; } else { - /* presumedly a DF */ + /* presumably a DF */ atype = SC_APDU_CASE_1; ftype = 0x00; } @@ -1008,7 +1008,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, } break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error: unknow cmd type"); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error: unknown cmd type"); return SC_ERROR_INTERNAL; } /* Clear the buffer - it may contain pins */ diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index a26b43ab3a..fb0b296c8a 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -467,7 +467,7 @@ static int atrust_acos_select_file(struct sc_card *card, if ( card->cache.valid && bMatch >= 0 ) { if ( pathlen - bMatch == 2 ) - /* we are in the rigth directory */ + /* we are in the right directory */ return atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], file_out); else if ( pathlen - bMatch > 2 ) { diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 1d3bb26750..8537260d10 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -2197,7 +2197,7 @@ authentic_sm_free_wrapped_apdu(struct sc_card *card, struct sc_apdu *plain, stru if (plain) { if (plain->resplen < (*sm_apdu)->resplen) - LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Unsufficient plain APDU response size"); + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Insufficient plain APDU response size"); memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen); plain->resplen = (*sm_apdu)->resplen; plain->sw1 = (*sm_apdu)->sw1; diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index b9c797cbbd..10a7ed6149 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -20,14 +20,14 @@ /* About the Belpic (Belgian Personal Identity Card) card * - * The Belpic card is a Cyberflex Java card, so you normaly communicate + * The Belpic card is a Cyberflex Java card, so you normally communicate * with an applet running on the card. In order to support a pkcs15 file * structure, an applet (the Belpic applet) has been build that emulates * this. So the card's behaviour is specific for this Belpic applet, that's * why a separate driver has been made. * * The card contains the citizen's ID data (name, address, photo, ...) and - * her keys and certs. The ID data are in a seperate directory on the card and + * her keys and certs. The ID data are in a separate directory on the card and * are not handled by this software. For the cryptographic data (keys and certs) * a pkcs#15 structure has been chosen and they can be accessed and used * by the OpenSC software. @@ -35,20 +35,20 @@ * The current situation about the cryptographic data is: there is 1 PIN * that protects 2 private keys and corresponding certs. Then there is a * CA cert and the root cert. The first key (Auth Key) can be used for - * authentication, the second one (NonRep Key) for non repudation purposes + * authentication, the second one (NonRep Key) for non repudiation purposes * (so it can be used as an alternative to manual signatures). * * There are some special things to note, which all have some consequences: * (1) the SELECT FILE command doesn't return any FCI (file length, type, ...) * (2) the NonRep key needs a VERIFY PIN before a signature can be done with it - * (3) pin pad readers had to be supported by a proprietory interface (as at - * that moment no other solution was known/avaiable/ready) + * (3) pin pad readers had to be supported by a proprietary interface (as at + * that moment no other solution was known/available/ready) * The consequences are: * * For (1): we let the SELECT FILE command return that the file length is - * a fixed large number and that each file is a transparant working EF + * a fixed large number and that each file is a transparent working EF * (except the root dir 3F 00). This way however, there is a problem with the - * sc_read_binary() function that will only stop reading untill it receivces + * sc_read_binary() function that will only stop reading until it receives * a 0. Therefore, we use the 'next_idx' trick. Or, if that might fail * and so a READ BINARY past the end of file is done, length 0 is returned * instead of an error code. @@ -58,11 +58,11 @@ * causes other problems and is less user-friendly). A GUI being popped up * by the pkcs11 lib before each NonRep signature has another important * security advantage: applications that cache the PIN can't silently do - * a NonRep signature because there will allways be the GUI. + * a NonRep signature because there will always be the GUI. * * For (3), we link dynamically against a pin pad lib (DLL) that implements the - * proprietory API for a specific pin pad. For each pin pad reader (identified - * by it's PC/SC reader name), a pin pad lib correspondends. Some reader/lib + * proprietary API for a specific pin pad. For each pin pad reader (identified + * by it's PC/SC reader name), a pin pad lib corresponds. Some reader/lib * name pairs are hardcoded, and others can be added in the config file. * Note that there's also a GUI used in this case: if a signature with the * NonRep key is done: a dialog box is shown that asks the user to enter @@ -381,7 +381,7 @@ static int belpic_set_security_env(sc_card_t *card, /* If a NonRep signature will be done, ask to enter a PIN. It would be more * logical to put the code below into the compute signature function because - * a Verify Pin call must immediately preceed a Compute Signature call. + * a Verify Pin call must immediately precede a Compute Signature call. * It's not done because the Compute Signature is completely ISO7816 compliant * so we use the iso7816_compute_signature() function, and because this function * doesn't know about the key reference. diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 113c9f77d1..3529bab1f7 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -271,7 +271,7 @@ static const cac_cuid_t cac_cac1_cuid = { }; /* - * CAC-1 general objectes defined in 4.3.1.2 of CAC Applet Developer Guide Version 1.0. + * CAC-1 general objects defined in 4.3.1.2 of CAC Applet Developer Guide Version 1.0. * doubles as a source for CAC-2 labels. */ static const cac_object_t cac_1_objects[] = { @@ -326,7 +326,7 @@ static int cac_is_cert(cac_private_data_t * priv, const sc_path_t *in_path) * an internal 4096 byte buffer is used, and a copy is returned to the * caller. that need to be freed by the caller. * - * modelled after a similiar function in card-piv.c + * modelled after a similar function in card-piv.c */ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, @@ -1066,7 +1066,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc if (cac_is_cert(priv, in_path)) { priv->object_type = CAC_OBJECT_TYPE_CERT; } - /* forget any old cacheed values */ + /* forget any old cached values */ if (priv->cache_buf) { free(priv->cache_buf); priv->cache_buf = NULL; @@ -1148,7 +1148,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc if (r) LOG_FUNC_RETURN(ctx, r); - /* CAC cards enver return FCI, fake one */ + /* CAC cards never return FCI, fake one */ file = sc_file_new(); if (file == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); @@ -1256,7 +1256,7 @@ static int cac_parse_cardurl(sc_card_t *card, cac_private_data_t *priv, cac_card sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: ski_object found"); break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: unkown object_object found (type=0x%x)", val->cardApplicationType); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: unknown object_object found (type=0x%x)", val->cardApplicationType); /* don't fail just because there is an unknown object in the CCC */ break; } @@ -1615,7 +1615,7 @@ static int cac_init(sc_card_t *card) } flags = SC_ALGORITHM_RSA_RAW; - _sc_card_add_rsa_alg(card, 1024, flags, 0); /* manditory */ + _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index e3349e7092..884b756e25 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -299,7 +299,7 @@ static const struct sc_card_error cardos_errors[] = { /* no error, maybe a note */ { 0x9000, SC_SUCCESS, NULL}, { 0x9001, SC_SUCCESS, "success, but eeprom weakness detected"}, -{ 0x9850, SC_SUCCESS, "over/underflow useing in/decrease"} +{ 0x9850, SC_SUCCESS, "over/underflow using in/decrease"} }; static int cardos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) @@ -352,7 +352,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) len = apdu.resplen; while (len != 0) { size_t tlen = 0, ilen = 0; - /* is there a file informatin block (0x6f) ? */ + /* is there a file information block (0x6f) ? */ p = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen); if (p == NULL) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "directory tag missing"); @@ -372,7 +372,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) buf[fids++] = q[1]; buflen -= 2; } else - /* not enought space left in buffer => break */ + /* not enough space left in buffer => break */ break; /* extract next offset */ q = sc_asn1_find_tag(card->ctx, p, tlen, 0x8a, &ilen); @@ -893,7 +893,7 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, /* There are two ways to create a signature, depending on the way, * the key was created: RSA_SIG and RSA_PURE_SIG. * We can use the following reasoning, to determine the correct operation: - * 1. We check for several caps flags (as set in card->caps), to pervent generating + * 1. We check for several caps flags (as set in card->caps), to prevent generating * invalid signatures with duplicated hash prefixes with some cards * 2. Use the information from AlgorithmInfo of the TokenInfo file. * This information is parsed in set_security_env and stored in a static variable. diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 4ad347372b..54a65dddbd 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -160,7 +160,7 @@ typedef struct global_platform_cplc_data { u8 ic_personalization_id[4]; } global_platform_cplc_data_t; -/* format of the coolkey_cuid, either contructed from cplc data or read from the combined object */ +/* format of the coolkey_cuid, either constructed from cplc data or read from the combined object */ typedef struct coolkey_cuid { u8 ic_fabricator[2]; u8 ic_type[2]; @@ -214,7 +214,7 @@ typedef struct coolkey_decompressed_header { u8 object_offset[2]; u8 object_count[2]; u8 token_name_length; - u8 token_name[255]; /* arbitary size up to token_name_length */ + u8 token_name[255]; /* arbitrary size up to token_name_length */ } coolkey_decompressed_header_t; /* @@ -293,11 +293,11 @@ struct coolkey_fixed_attributes_values { uint32_t cka_always_sensitive:1; uint32_t cka_extractable:1; uint32_t cka_never_extractable:1; - uint32_t reseved:8; + uint32_t reserved:8; }; * cka_class is used to determine which booleans are valid. Any attributes in the full attribute list - * takes precidence over the fixed attributes. That is if there is a CKA_ID in the full attribute list, + * takes precedence over the fixed attributes. That is if there is a CKA_ID in the full attribute list, * The cka_id in the fixed_attributes is ignored. When determining which boolean attribute is valid, the * cka_class in the fixed attributes are used, even if it is overridden by the full attribute list. * valid cka_class values and their corresponding valid bools are as follows: @@ -658,7 +658,7 @@ coolkey_get_fixed_boolean_bit(CK_ATTRIBUTE_TYPE type) return 0; /* return no bits */ } /* This table lets us return a pointer to the CKA_ID value without allocating data or - * creating a changable static that could cause thread issues */ + * creating a changeable static that could cause thread issues */ static const u8 coolkey_static_cka_id[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; @@ -860,21 +860,21 @@ struct coolkey_error_codes_st { }; static const struct coolkey_error_codes_st coolkey_error_codes[]= { - {SC_ERROR_UNKNOWN, "Reservered 0x9c00" }, + {SC_ERROR_UNKNOWN, "Reserved 0x9c00" }, {SC_ERROR_NOT_ENOUGH_MEMORY, "No memory left on card" }, {SC_ERROR_PIN_CODE_INCORRECT, "Authentication failed" }, {SC_ERROR_NOT_ALLOWED, "Operation not allowed" }, - {SC_ERROR_UNKNOWN, "Reservered 0x9c04" }, + {SC_ERROR_UNKNOWN, "Reserved 0x9c04" }, {SC_ERROR_NO_CARD_SUPPORT, "Unsupported feature" }, {SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Not authorized" }, {SC_ERROR_DATA_OBJECT_NOT_FOUND, "Object not found" }, {SC_ERROR_FILE_ALREADY_EXISTS, "Object exists" }, {SC_ERROR_NO_CARD_SUPPORT, "Incorrect Algorithm" }, - {SC_ERROR_UNKNOWN, "Reservered 0x9c0a" }, + {SC_ERROR_UNKNOWN, "Reserved 0x9c0a" }, {SC_ERROR_SM_INVALID_CHECKSUM, "Signature invalid" }, {SC_ERROR_AUTH_METHOD_BLOCKED, "Identity blocked" }, - {SC_ERROR_UNKNOWN, "Reservered 0x9c0d" }, - {SC_ERROR_UNKNOWN, "Reservered 0x9c0e" }, + {SC_ERROR_UNKNOWN, "Reserved 0x9c0d" }, + {SC_ERROR_UNKNOWN, "Reserved 0x9c0e" }, {SC_ERROR_INCORRECT_PARAMETERS, "Invalid parameter" }, {SC_ERROR_INCORRECT_PARAMETERS, "Incorrect P1" }, {SC_ERROR_INCORRECT_PARAMETERS, "Incorrect P2" }, @@ -914,7 +914,7 @@ static int coolkey_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) * an internal 4096 byte buffer is used, and a copy is returned to the * caller. that need to be freed by the caller. * - * modelled after a similiar function in card-piv.c. The coolkey version + * modelled after a similar function in card-piv.c. The coolkey version * adds the coolkey nonce to user authenticated operations. */ @@ -1134,7 +1134,7 @@ static int coolkey_read_object(sc_card_t *card, unsigned long object_id, size_t if (r < 0) { goto fail; } - /* santity check to make sure we don't overflow left */ + /* sanity check to make sure we don't overflow left */ if ((left < len) || (len == 0)) { r = SC_ERROR_INTERNAL; goto fail; @@ -1903,7 +1903,7 @@ static unsigned short coolkey_get_key_id(unsigned long object_id) { } /* - * COOLKEY cards don't select objects in the applet, objects are selected by a paramter + * COOLKEY cards don't select objects in the applet, objects are selected by a parameter * to the APDU. We create paths for the object in which the path value is the object_id * and the path type is SC_PATH_SELECT_FILE_ID (so we could cache at the PKCS #15 level if * we wanted to. @@ -2267,7 +2267,7 @@ static int coolkey_init(sc_card_t *card) /* set Token Major/minor version */ flags = SC_ALGORITHM_RSA_RAW; - _sc_card_add_rsa_alg(card, 1024, flags, 0); /* manditory */ + _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index d55920c6b4..6ba0eba5be 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -128,7 +128,7 @@ H13-H15: 0x0F 0x65 0x81 final phase: tarjeta no operativa * OpenDNIe defines two ATR's for user and finalized card state */ static struct sc_atr_table dnie_atrs[] = { - /* TODO: get ATR for uninitalized DNIe */ + /* TODO: get ATR for uninitialized DNIe */ { /** card activated; normal operation state */ "3B:7F:00:00:00:00:6A:44:4E:49:65:00:00:00:00:00:00:03:90:00", "FF:FF:00:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:FF:FF:FF", @@ -215,7 +215,7 @@ int dnie_ask_user_consent(struct sc_card * card, const char *title, const char * int n = 0; /* to iterate on to-be-sent messages */ #endif int res = SC_ERROR_INTERNAL; /* by default error :-( */ - char *msg = NULL; /* to makr errors */ + char *msg = NULL; /* to mark errors */ if ((card == NULL) || (card->ctx == NULL)) return SC_ERROR_INVALID_ARGUMENTS; @@ -248,7 +248,7 @@ int dnie_ask_user_consent(struct sc_card * card, const char *title, const char * header_ref = CFStringCreateWithCString( NULL, title, strlen(title) ); message_ref = CFStringCreateWithCString( NULL,message, strlen(message) ); - /* Displlay user notification alert */ + /* Display user notification alert */ CFUserNotificationDisplayAlert( 0, /* no timeout */ kCFUserNotificationNoteAlertLevel, /* Alert level */ @@ -398,8 +398,8 @@ static sc_card_driver_t dnie_driver = { /** * Parse configuration file for dnie parameters. * - * DNIe card driver has two main paramaters: - * - The name of the user consent Application to be used in Linux. This application shoud be any of pinentry-xxx family + * DNIe card driver has two main parameters: + * - The name of the user consent Application to be used in Linux. This application should be any of pinentry-xxx family * - A flag to indicate if user consent is to be used in this driver. If false, the user won't be prompted for confirmation on signature operations * * @See ../../etc/opensc.conf for details @@ -471,7 +471,7 @@ static int dnie_generate_key(sc_card_t * card, void *data) /** * Analyze a buffer looking for provided data pattern. * - * Comodity function for dnie_get_info() that searches a byte array + * Commodity function for dnie_get_info() that searches a byte array * in provided buffer * * @param card pointer to card info data @@ -654,7 +654,7 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) /* official driver read 0x11 bytes, but only uses 7. Manual says just 7 (for le) */ dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xb8, 0x00, 0x00, 0x07, 0, rbuf, sizeof(rbuf), NULL, 0); - apdu.cla = 0x90; /* propietary cmd */ + apdu.cla = 0x90; /* proprietary cmd */ /* send apdu */ result = sc_transmit_apdu(card, &apdu); if (result != SC_SUCCESS) { @@ -915,10 +915,10 @@ static unsigned long le2ulong(u8 * pt) /** * Uncompress data if in compressed format. * - * @param card poiner to sc_card_t structure + * @param card pointer to sc_card_t structure * @param from buffer to get data from * @param len pointer to buffer length - * @return uncompresed or original buffer; len points to new buffer length + * @return uncompressed or original buffer; len points to new buffer length * on error return null */ static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) @@ -933,7 +933,7 @@ static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) return NULL; LOG_FUNC_CALLED(card->ctx); - /* if data size not enought for compression header assume uncompressed */ + /* if data size not enough for compression header assume uncompressed */ if (*len < 8) goto compress_exit; /* evaluate compressed an uncompressed sizes (little endian format) */ @@ -1052,7 +1052,7 @@ static int dnie_fill_cache(sc_card_t * card) free(apdu.resp); LOG_FUNC_RETURN(ctx, r); /* arriving here means response error */ } - /* copy received data into buffer. realloc() if not enought space */ + /* copy received data into buffer. realloc() if not enough space */ count = apdu.resplen; buffer = realloc(buffer, len + count); if (!buffer) { @@ -1078,7 +1078,7 @@ static int dnie_fill_cache(sc_card_t * card) if (apdu.resp != tmp) free(apdu.resp); if (pt == NULL) { - sc_log(ctx, "Uncompress proccess failed"); + sc_log(ctx, "Uncompress process failed"); free(buffer); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); } @@ -1102,10 +1102,10 @@ static int dnie_fill_cache(sc_card_t * card) * * @param card pointer to sc_card_t structure * @param idx offset from card file to ask data for - * @param buf where to store readed data. must be non null + * @param buf where to store read data. must be non null * @param count number of bytes to read * @param flags. not used - * @return number of bytes readed, 0 on EOF, error code on error + * @return number of bytes read, 0 on EOF, error code on error */ static int dnie_read_binary(struct sc_card *card, unsigned int idx, @@ -1211,8 +1211,8 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa * - only handles some types: * -- SC_PATH_TYPE_FILE_ID 2-byte long file ID * -- SC_PATH_TYPE_DF_NAME named DF's - * -- SC_PATH_TYPE_PARENT jump to parent DF of current EF/DF - undocummented in DNIe manual - * -- other file types are marked as unssupported + * -- SC_PATH_TYPE_PARENT jump to parent DF of current EF/DF - undocumented in DNIe manual + * -- other file types are marked as unsupported * * - Also MF must be addressed by their Name, not their ID * So some magic is needed: @@ -1333,7 +1333,7 @@ static int dnie_select_file(struct sc_card *card, * No reason to do it, as is needed to do SM handshake... * Also: official driver reads in blocks of 20 bytes. * Why? Manual and iso-7816-4 states that only 8 bytes - * are required... so we will obbey Manual + * are required... so we will obey Manual * * @param card Pointer to card Structure * @param rnd Where to store challenge @@ -1640,7 +1640,7 @@ static int dnie_decipher(struct sc_card *card, * and applies * * @param card pointer to sc_card_t structure - * @param data data to be hased/signed + * @param data data to be hashed/signed * @param datalen length of provided data * @param out buffer to store results into * @param outlen available space in result buffer @@ -1657,7 +1657,7 @@ static int dnie_compute_signature(struct sc_card *card, struct sc_apdu apdu; u8 rbuf[MAX_RESP_BUFFER_SIZE]; /* to receive sign response */ - /* some preliminar checks */ + /* some preliminary checks */ if ((card == NULL) || (card->ctx == NULL)) return SC_ERROR_INVALID_ARGUMENTS; /* OK: start working */ @@ -1892,7 +1892,7 @@ static int dnie_card_ctl(struct sc_card *card, * the read_binary() file cache work * * Extract real file length from compressed file is done by mean of - * reading 8 first bytes for uncompressed/compressed lenght. + * reading 8 first bytes for uncompressed/compressed length. * Lengths are provided as two 4-byte little endian numbers * * Implemented just like a direct read binary apdu bypassing dnie file cache @@ -1942,7 +1942,7 @@ static int dnie_read_header(struct sc_card *card) } /** - * Access control list bytes for propietary DNIe FCI response for DF's. + * Access control list bytes for proprietary DNIe FCI response for DF's. * based in information from official DNIe Driver * Parsing code based on itacns card driver */ @@ -1953,7 +1953,7 @@ static int df_acl[] = { /* to handle DF's */ }; /** - * Access control list bytes for propietary DNIe FCI response for EF's. + * Access control list bytes for proprietary DNIe FCI response for EF's. * based in information from official DNIe Driver * Parsing code based on itacns card driver */ @@ -1968,7 +1968,7 @@ static int ef_acl[] = { /* to handle EF's */ * * Parse SelectFile's File Control information. * - First, std iso_parse_fci is called to parse std fci tags - * - Then analyze propietary tag according DNIe Manual + * - Then analyze proprietary tag according DNIe Manual * * @param card OpenSC card structure pointer * @param file currently selected EF or DF @@ -2133,7 +2133,7 @@ static int dnie_process_fci(struct sc_card *card, * Not implemented yet, as current availability for DNIe user driver * is unknown * - * @param card Pointer to Card Driver data structrure + * @param card Pointer to Card Driver data structure * @param data Pointer to Pin data structure * @return SC_SUCCESS if ok; else error code */ @@ -2191,7 +2191,7 @@ static int dnie_pin_verify(struct sc_card *card, dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x00, 0, pinlen, NULL, 0, pinbuffer, pinlen); - /* and send to card throught virtual channel */ + /* and send to card through virtual channel */ res = sc_transmit_apdu(card, &apdu); if (res != SC_SUCCESS) { LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail"); @@ -2240,7 +2240,7 @@ static int dnie_pin_cmd(struct sc_card *card, /* * some flags and settings from documentation - * No (easy) way to handle pinpad throught SM, so disable it + * No (easy) way to handle pinpad through SM, so disable it */ data->flags &= ~SC_PIN_CMD_NEED_PADDING; /* no pin padding */ data->flags &= ~SC_PIN_CMD_USE_PINPAD; /* cannot handle pinpad */ diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 0fa9bffa10..d5264349dd 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -619,7 +619,7 @@ static int entersafe_select_path(sc_card_t *card, { if ( pathlen - bMatch == 2 ) { - /* we are in the rigth directory */ + /* we are in the right directory */ return entersafe_select_fid(card, path[bMatch], path[bMatch+1], file_out); } else if ( pathlen - bMatch > 2 ) @@ -894,9 +894,9 @@ static int entersafe_internal_set_security_env(sc_card_t *card, } /** - * We don't really set the security envirment,but cache it.It will be set when + * We don't really set the security environment,but cache it.It will be set when * security operation is performed later.Because we may transport partial of - * the sign/decipher data within the security envirment apdu. + * the sign/decipher data within the security environment apdu. */ static int entersafe_set_security_env(sc_card_t *card, const sc_security_env_t *env, diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 6250c6a8cf..1b17f8a54b 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1303,7 +1303,7 @@ epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** fi } if (path[0] == 0x29) { /* TODO:0x29 accords with FID prefix in profile */ - /* Not allowed to select prvate key file, so fake fci. */ + /* Not allowed to select private key file, so fake fci. */ /* 62 16 82 02 11 00 83 02 29 00 85 02 08 00 86 08 FF 90 90 90 FF FF FF FF */ apdu.resplen = 0x18; memcpy(apdu.resp, @@ -1480,7 +1480,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l if (card->cache.valid && bMatch > 2) { if (pathlen - bMatch == 2) { - /* we are in the rigth directory */ + /* we are in the right directory */ return epass2003_select_fid(card, path[bMatch], path[bMatch + 1], file_out); } else if (pathlen - bMatch > 2) { @@ -2696,7 +2696,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries data->pin1.max_tries = maxtries; } -//reomve below code, because the old implement only return PIN retries, now modify the code and return PIN status +//remove below code, because the old implement only return PIN retries, now modify the code and return PIN status // return r; } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */ diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 1dd2769409..ac7a5703e2 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -64,7 +64,7 @@ static struct sc_atr_table flex_atrs[] = { /* 32K e-gate v4 */ { "3B:95:18:40:FF:62:04:01:01:05", NULL, "Cryptoflex 32K e-gate v4", SC_CARD_TYPE_FLEX_CRYPTO, FLAG_KEYGEN, NULL }, - /* new cryptoflex 32k card - atr looks very similiar to old 8k card */ + /* new cryptoflex 32k card - atr looks very similar to old 8k card */ { "3b:95:15:40:ff:68:01:02:45:47", NULL, "Cryptoflex 32K", SC_CARD_TYPE_FLEX_CRYPTO, FLAG_KEYGEN, NULL }, { "3B:E2:00:00:40:20:49:06", NULL, "Cryptoflex", SC_CARD_TYPE_FLEX_CRYPTO, 0, NULL }, diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index d8bcb88567..fc5d2a730c 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -117,7 +117,7 @@ static struct sc_card_driver gids_drv = { struct gids_aid { int enumtag; - size_t len_short; /* min lenght without version */ + size_t len_short; /* min length without version */ size_t len_long; /* With version and other stuff */ u8 *value; }; @@ -393,7 +393,7 @@ static int gids_read_gidsfile(sc_card_t* card, char *directory, char *filename, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); } -// check for the existance of a file +// check for the existence of a file static int gids_does_file_exists(sc_card_t *card, char* directory, char* filename) { struct gids_private_data* privatedata = (struct gids_private_data*) card->drv_data; int fileIdentifier, dataObjectIdentifier; @@ -1768,7 +1768,7 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) u8 EveryoneReadAdminWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x12,0x8C,0x03,0x03,0x20,0x00}; u8 UserReadWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x13,0x8C,0x03,0x03,0x30,0x30}; u8 AdminReadWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x14,0x8C,0x03,0x03,0x20,0x20}; - // File type=18=key file ; type = symetric key + // File type=18=key file ; type = symmetric key u8 AdminKey[] = {0x62,0x1A,0x82,0x01,0x18,0x83,0x02,0xB0,0x80,0x8C,0x04,0x87,0x00,0x20,0xFF,0xA5, 0x0B,0xA4,0x09,0x80,0x01,0x02,0x83,0x01,0x80,0x95,0x01,0xC0}; // file used to store other file references. Format undocumented. diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 883bf7c60c..3064a61f9e 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -1507,7 +1507,7 @@ gpk_generate_key(sc_card_t *card, struct sc_cardctl_gpk_genkey *args) } /* - * Store a privat key component + * Store a private key component */ static int gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 4cd0b03b1d..4f20fde6cd 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -253,7 +253,7 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) struct sc_apdu apdu; unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; - /* ISO 'select' command failes when not FCP data returned */ + /* ISO 'select' command fails when not FCP data returned */ sc_format_path("3F00", &path); path.type = SC_PATH_TYPE_FILE_ID; @@ -283,7 +283,7 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) /* Ignore the FCP of the MF, because: * - some cards do not return it; - * - there is not need of it -- create/delete of the files in MF is not invisaged. + * - there is not need of it -- create/delete of the files in MF is not envisaged. */ mf_file = sc_file_new(); if (mf_file == NULL) @@ -812,7 +812,7 @@ iasecc_emulate_fcp(struct sc_context *ctx, struct sc_apdu *apdu) /* TODO: redesign using of cache - * TODO: do not keep inermediate results in 'file_out' argument */ + * TODO: do not keep intermediate results in 'file_out' argument */ static int iasecc_select_file(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out) @@ -1747,7 +1747,7 @@ iasecc_set_security_env(struct sc_card *card, LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_PSO_DECRYPT acl"); algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_DECIPHER, CKM_RSA_PKCS); if (!algo_ref) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports DECHIPHER:RSA_PKCS"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports DECIPHER:RSA_PKCS"); cse_crt_ct[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL; cse_crt_ct[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1 */ diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 7804af4c2a..698f24c0c3 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -141,7 +141,7 @@ static const struct sc_card_error incrypto34_errors[] = { /* no error, maybe a note */ { 0x9000, SC_SUCCESS, NULL}, { 0x9001, SC_SUCCESS, "success, but eeprom weakness detected"}, -{ 0x9850, SC_SUCCESS, "over/underflow useing in/decrease"} +{ 0x9850, SC_SUCCESS, "over/underflow using in/decrease"} }; static int incrypto34_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index d9b92af913..846031742e 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -46,7 +46,7 @@ struct isoApplet_drv_data { /* Save the current algorithm reference * (ISOAPPLET_ALG_REF_ECDSA, ISOAPPLET_ALG_REF_RSA_PAD_PKCS1) - * to be able to distiguish between RSA and ECC operations. + * to be able to distinguish between RSA and ECC operations. * If ECC is being used, the signatures generated by the card * have to be modified. */ unsigned int sec_env_alg_ref; @@ -95,7 +95,7 @@ static struct isoapplet_supported_ec_curves { * * @param[in] card * @param[in] aid The applet ID. - * @param[in] aid_len The legth of aid. + * @param[in] aid_len The length of aid. * @param[out] resp The response of the applet upon selection. * @param[in,out] resp_len In: The buffer size of resp. Out: The length of the response. * @@ -125,7 +125,7 @@ isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len, u8 apdu.le = 0; rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit faiure."); + LOG_TEST_RET(ctx, rv, "APDU transmit failure."); rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Card returned error"); @@ -479,7 +479,7 @@ isoApplet_process_fci(sc_card_t *card, sc_file_t *file, } /* - * @brief Encode the EC parameters as a concatenation of TLV enrties. + * @brief Encode the EC parameters as a concatenation of TLV entries. * * The format is: * 81 - prime @@ -589,7 +589,7 @@ isoApplet_ctl_generate_key(sc_card_t *card, sc_cardctl_isoApplet_genkey_t *args) * There are two cases: * 1) The card can do ext. apdus: The data fits in one apdu. * 2) The card can't do ext. apdus: sc_transmit_apdu will handle that - the - * card will send SW_BYTES_REMAINING, OpenSC will automaticall do a + * card will send SW_BYTES_REMAINING, OpenSC will automatically do a * GET RESPONSE to get the remaining data, and will append it to the data * buffer. */ if(args->algorithm_ref == SC_ISOAPPLET_ALG_REF_EC_GEN) @@ -1032,7 +1032,7 @@ isoApplet_ctl_import_key(sc_card_t *card, sc_cardctl_isoApplet_import_key_t *arg break; default: - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Uknown algorithm refernce."); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unknown algorithm reference."); } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index f322f8950e..4cdadbfc45 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -510,7 +510,7 @@ static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) //Returned file->size should be 16. //We choose to not consider it as critical, because some cards //do not return FCI/FCP templates that include the file size. - //Notify abnormal lenght anyway. + //Notify abnormal length anyway. if (len != 16) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unexpected file length of EF_IDCarta (%lu)\n", diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index f522a59e57..d1f87cf0ee 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -434,7 +434,7 @@ static int jcop_process_fci(sc_card_t *card, sc_file_t *file, /* Files may be locked by anyone who can MODIFY. */ /* opensc seems to think LOCK ACs are only on DFs */ /* sa_to_acl(file, SC_AC_OP_LOCK, sa[0] & 0xf); */ - /* there are seperate SIGN, ENCIPHER, and DECIPHER ACs. + /* there are separate SIGN, ENCIPHER, and DECIPHER ACs. I use SIGN for SC_AC_OP_CRYPTO unless it is NEVER, in which case I use DECIPHER */ if ((sa[1] & 0xf0) == 0x10) diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index ee8f6d308b..fd53cd0b66 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -273,7 +273,7 @@ static int masktech_pin_change(sc_card_t *card, change_data.pin2.prompt = data->pin2.prompt; rv = iso_ops->pin_cmd(card, &change_data, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - chnage PIN"); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - change PIN"); return 0; } diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2923d1f535..2428c8dc92 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -42,7 +42,7 @@ static struct sc_atr_table mcrd_atrs[] = { "D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL}, {"3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6", NULL, "D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL}, - /* Certain pcsc-lite versions (1.5.3 for example on Ubuntu 10.04) incorrectly trunkate the wram ATR to the length of the cold ATR */ + /* Certain pcsc-lite versions (1.5.3 for example on Ubuntu 10.04) incorrectly truncate the warm ATR to the length of the cold ATR */ /* See opensc.conf for further information */ {"3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20", NULL, "Broken EstEID 1.1 warm", SC_CARD_TYPE_MCRD_ESTEID_V11, 0, NULL}, {"3b:fe:94:00:ff:80:b1:fa:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:43", NULL, "EstEID 1.0 cold", SC_CARD_TYPE_MCRD_ESTEID_V10, 0, NULL}, @@ -517,7 +517,7 @@ static int load_special_files(sc_card_t * card) } /* Return the SE number from the keyD for the FID. If ref_data is not - NULL the reference data is returned; this shoudl be an array of at + NULL the reference data is returned; this should be an array of at least 2 bytes. Returns -1 on error. */ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, u8 * ref_data) @@ -1189,7 +1189,7 @@ static int mcrd_restore_se(sc_card_t * card, int se_num) /* It seems that MICARDO does not fully comply with ISO, so I use - values gathered from peeking actual signing opeations using a + values gathered from peeking actual signing operations using a different system. It has been generalized [?] and modified by information coming from openpgp card implementation, EstEID 'manual' and some other sources. -mp @@ -1229,7 +1229,7 @@ static int mcrd_set_security_env(sc_card_t * card, case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_DERIVE: sc_log(card->ctx, - "Using keyref %d to dechiper\n", + "Using keyref %d to decipher\n", env->key_ref[0]); mcrd_restore_se(card, 6); mcrd_delete_ref_to_authkey(card); @@ -1263,7 +1263,7 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: sc_log(card->ctx, - "Using keyref %d to dechiper\n", + "Using keyref %d to decipher\n", env->key_ref[0]); mcrd_delete_ref_to_authkey(card); mcrd_delete_ref_to_signkey(card); @@ -1317,7 +1317,7 @@ static int mcrd_set_security_env(sc_card_t * card, fid |= env->file_ref.value[env->file_ref.len - 1]; num = get_se_num_from_keyd(card, fid, p); if (num != -1) { - /* Need to restore the security environmnet. */ + /* Need to restore the security environment. */ if (num) { r = mcrd_restore_se(card, num); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, @@ -1436,7 +1436,7 @@ static int mcrd_decipher(struct sc_card *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "Will dervie (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n", + "Will derive (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n", env->operation, crgram_len, crgram_len, env->key_ref[0], env->algorithm, env->algorithm_flags); diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 5733ab0a0a..66b39d1395 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -241,7 +241,7 @@ static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf if(buffer == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); r = msc_read_object(card, objectId, 0, buffer, file->size); - /* TODO: RETREIVE ACLS */ + /* TODO: RETRIEVE ACLS */ if(r < 0) goto update_bin_free_buffer; r = msc_delete_object(card, objectId, 0); if(r < 0) goto update_bin_free_buffer; @@ -602,7 +602,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, static int muscle_card_extract_key(sc_card_t *card, sc_cardctl_muscle_key_info_t *info) { - /* CURRENTLY DONT SUPPOT EXTRACTING PRIVATE KEYS... */ + /* CURRENTLY DONT SUPPORT EXTRACTING PRIVATE KEYS... */ switch(info->keyType) { case 1: /* RSA */ return msc_extract_rsa_public_key(card, @@ -618,7 +618,7 @@ static int muscle_card_extract_key(sc_card_t *card, sc_cardctl_muscle_key_info_t static int muscle_card_import_key(sc_card_t *card, sc_cardctl_muscle_key_info_t *info) { - /* CURRENTLY DONT SUPPOT EXTRACTING PRIVATE KEYS... */ + /* CURRENTLY DONT SUPPORT EXTRACTING PRIVATE KEYS... */ switch(info->keyType) { case 0x02: /* RSA_PRIVATE */ case 0x03: /* RSA_PRIVATE_CRT */ @@ -721,7 +721,7 @@ static int muscle_decipher(sc_card_t * card, u8 key_id; int r; - /* saniti check */ + /* sanity check */ if (priv->env.operation != SC_SEC_OPERATION_DECIPHER) return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index d1175eb498..5959359824 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -313,7 +313,7 @@ static int npa_unlock_esign(sc_card_t *card) } r = perform_chip_authentication(card, &ef_cardsecurity, &ef_cardsecurity_len); if ( SC_SUCCESS != r) { - sc_log(card->ctx, "Error verifying the chips authenticy.\n"); + sc_log(card->ctx, "Error verifying the chip's authenticity.\n"); } sc_log(card->ctx, "Proved Access rights to eSign application with configured key as ST.\n"); @@ -343,7 +343,7 @@ static int npa_init(sc_card_t * card) } card->caps |= SC_CARD_CAP_APDU_EXT | SC_CARD_CAP_RNG; - /* 1520 bytes is the minimum lenght of the communication buffer in all + /* 1520 bytes is the minimum length of the communication buffer in all * Chip/OS variants */ card->max_recv_size = 1520; card->max_send_size = 1520; @@ -382,7 +382,7 @@ static int npa_init(sc_card_t * card) /* unlock the eSign application for reading the certificates * by the PKCS#15 layer (i.e. sc_pkcs15_bind_internal) */ if (SC_SUCCESS != npa_unlock_esign(card)) - sc_log(card->ctx, "Propably not all functionality will be available.\n"); + sc_log(card->ctx, "Probably not all functionality will be available.\n"); err: return r; @@ -757,7 +757,7 @@ static int npa_logout(sc_card_t *card) if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { /* If PACE is done between reader and card, SM is transparent to us as - * it ends at the reader. With CLA=0x0C we provoque a SM error to + * it ends at the reader. With CLA=0x0C we provoke a SM error to * disable SM on the reader. */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x00, 0x00); apdu.cla = 0x0C; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 75ad10db2c..c8c11459a8 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1593,7 +1593,7 @@ auth_pin_verify_pinpad(struct sc_card *card, int pin_reference, int *tries_left) pin_cmd.flags |= SC_PIN_CMD_NEED_PADDING; /* For Oberthur card, PIN command data length has to be 0x40. - * In PCSC10 v2.06 the uppler limit of pin.max_length is 8. + * In PCSC10 v2.06 the upper limit of pin.max_length is 8. * * The standard sc_build_pin() throws an error when 'pin.len > pin.max_length' . * So, let's build our own APDU. @@ -1775,7 +1775,7 @@ auth_pin_change(struct sc_card *card, unsigned int type, else if (!data->pin1.len && !data->pin2.len) { /* Oberthur unblock style with PIN pad. */ rv = auth_pin_change_pinpad(card, data, tries_left); - LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failedi: SOPIN verify with pinpad failed"); + LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failed: SOPIN verify with pinpad failed"); } else { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed"); diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cf163bb33e..3c847d206f 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1145,7 +1145,7 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - /* ignore explicitely mentioned MF at the path's beginning */ + /* ignore explicitly mentioned MF at the path's beginning */ path_start = pgp_strip_path(card, path); /* starting with the MF ... */ @@ -1155,7 +1155,7 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) unsigned int id = bebytes2ushort(path->value + n); int r = pgp_get_blob(card, blob, id, &blob); - /* This file ID is refered when importing key&certificate via pkcs15init, like above. + /* This file ID is referred when importing key&certificate via pkcs15init, like above. * We pretend to successfully find this inexistent file. */ if (id == 0x4402 || id == 0x5f48) { if (ret == NULL) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index ef114db8f9..03f108884b 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -175,14 +175,14 @@ typedef struct piv_private_data { int tries_left; /* SC_PIN_CMD_GET_INFO tries_left from last */ unsigned int card_issues; /* card_issues flags for this card */ int object_test_verify; /* Can test this object to set verification state of card */ - int yubico_version; /* 3 byte version number of NEO or Ybuikey4 as integer */ + int yubico_version; /* 3 byte version number of NEO or Yubikey4 as integer */ } piv_private_data_t; #define PIV_DATA(card) ((piv_private_data_t*)card->drv_data) struct piv_aid { int enumtag; - size_t len_short; /* min lenght without version */ + size_t len_short; /* min length without version */ size_t len_long; /* With version and other stuff */ u8 *value; }; @@ -194,7 +194,7 @@ struct piv_aid { * i.e. "A0 00 00 03 08 00 00 01 00 02 00". * but we don't need the version number. but could get it from the PIX. * - * 800-73-3 Part 1 now referes to "01 00" i.e. going back to 800-73-1. + * 800-73-3 Part 1 now refers to "01 00" i.e. going back to 800-73-1. * The main differences between 73-1, and 73-3 are the addition of the * key History object and keys, as well as Discovery and Iris objects. * These can be discovered by trying GET DATA @@ -423,7 +423,7 @@ piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) } /* - * If ptr == NULL, just return the size of the tag and lenght and data + * If ptr == NULL, just return the size of the tag and length and data * otherwise, store tag and length at **ptr, and increment */ @@ -469,7 +469,7 @@ put_tag_and_len(unsigned int tag, size_t len, u8 **ptr) * Send a command and receive data. There is always something to send. * Used by GET DATA, PUT DATA, GENERAL AUTHENTICATE * and GENERATE ASYMMETRIC KEY PAIR. - * GET DATA may call to get the first 128 bytes to get the lenght from the tag. + * GET DATA may call to get the first 128 bytes to get the length from the tag. * * A caller may provide a buffer, and length to read. If not provided, * an internal 4096 byte buffer is used, and a copy is returned to the @@ -775,7 +775,7 @@ static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* first see if the default applcation will return a template + /* first see if the default application will return a template * that we know about. */ @@ -1316,7 +1316,7 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon p += count; put_tag_and_len(0x71, 1, &p); /* Use 01 as per NIST 800-73-3 */ - *p++ = (flags)? 0x01:0x00; /* certinfo, i.e. gziped? */ + *p++ = (flags)? 0x01:0x00; /* certinfo, i.e. gzipped? */ put_tag_and_len(0xFE,0,&p); /* LRC tag */ sc_log(card->ctx, "DEE buf %p len %"SC_FORMAT_LEN_PTRDIFF_T"u %"SC_FORMAT_LEN_SIZE_T"u", @@ -1336,10 +1336,10 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon * Note: the select file will have saved the object type for us * Write is used by piv-tool, so we will use flags: * length << 8 | 8bits: - * object xxxx0000 - * uncompresed cert xxx00001 - * compressed cert xxx10001 - * pubkey xxxx0010 + * object xxxx0000 + * uncompressed cert xxx00001 + * compressed cert xxx10001 + * pubkey xxxx0010 * * to indicate we are writing a cert and if is compressed * or if we are writing a pubkey in to the cache. @@ -1438,8 +1438,8 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, /* * Card initialization is NOT standard. - * Some cards use mutual or external authentication usings 3des or aes key. We - * will read in the key from a file either binary or hex encided. + * Some cards use mutual or external authentication using 3des or aes key. We + * will read in the key from a file either binary or hex encoded. * This is only needed during initialization/personalization of the card */ @@ -1532,7 +1532,7 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l r = SC_ERROR_OUT_OF_MEMORY; goto err; } - keybuf[fsize] = 0x00; /* incase it is text need null */ + keybuf[fsize] = 0x00; /* in case it is text need null */ if (fread(keybuf, 1, fsize, f) != fsize) { sc_log(card->ctx, " Unable to read key\n"); @@ -1639,7 +1639,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = piv_get_key(card, alg_id, &key, &keylen); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting General Auth key\n"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting General Auth key\n"); goto err; } @@ -1919,7 +1919,7 @@ static int piv_general_external_authenticate(sc_card_t *card, r = piv_get_key(card, alg_id, &key, &keylen); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error geting General Auth key\n"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting General Auth key\n"); goto err; } @@ -2127,7 +2127,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) fascn, fascnlen, guid, guidlen, gbits); if (fascn && fascnlen == 25) { - /* test if guid and the fascn starts with ;9999 (in ISO 4bit + partiy code) */ + /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { serial->len = fascnlen < SC_MAX_SERIALNR ? fascnlen : SC_MAX_SERIALNR; @@ -2204,7 +2204,7 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return piv_general_external_authenticate(card, *(opts+1), *(opts+2)); break; - case'M': + case 'M': return piv_general_mutual_authenticate(card, *(opts+1), *(opts+2)); break; @@ -2255,7 +2255,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) while (len > 0) { size_t n = len > 8 ? 8 : len; - /* NIST 800-73-3 says use 9B, previous verisons used 00 */ + /* NIST 800-73-3 says use 9B, previous versions used 00 */ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, p - sbuf, &rbuf, &rbuflen); if (r < 0) { sc_unlock(card); @@ -2523,7 +2523,7 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, /* only support single EF in current application */ /* - * PIV emulates files, and only does so becauses sc_pkcs15_* uses + * PIV emulates files, and only does so because sc_pkcs15_* uses * select_file and read_binary. The emulation adds path emulated structures * so piv_select_file will find it. * there is no dir. Only direct access to emulated files @@ -2791,7 +2791,7 @@ piv_process_history(sc_card_t *card) } } else { - sc_log(card->ctx, "Problem with Histroy object\n"); + sc_log(card->ctx, "Problem with History object\n"); goto err; } } @@ -3098,7 +3098,7 @@ static int piv_match_card_continued(sc_card_t *card) priv->tries_left = 10; /* will assume OK at start */ priv->pstate = PIV_STATE_MATCH; - /* Some objects will only be present if Histroy object says so */ + /* Some objects will only be present if History object says so */ for (i=0; i < PIV_OBJ_LAST_ENUM -1; i++) if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; @@ -3270,7 +3270,7 @@ static int piv_init(sc_card_t *card) flags = SC_ALGORITHM_RSA_RAW; - _sc_card_add_rsa_alg(card, 1024, flags, 0); /* manditory */ + _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ @@ -3288,9 +3288,9 @@ static int piv_init(sc_card_t *card) * 800-73-3 cards may have a history object and/or a discovery object * We want to process them now as this has information on what * keys and certs the card has and how the pin might be used. - * If they fail, ignore it there are optional and introdced in + * If they fail, ignore it there are optional and introduced in * NIST 800-73-3 and NIST 800-73-2 so some older cards may - * not handle the requets. + * not handle the request. */ piv_process_history(card); @@ -3373,7 +3373,7 @@ piv_check_protected_objects(sc_card_t *card) * If we can't determine the security state from this process, * set card_issues CI_CANT_USE_GETDATA_FOR_STATE * and return SC_ERROR_PIN_CODE_INCORRECT - * The curcomvention is to add a dummy Printed Info object in the card. + * The circumvention is to add a dummy Printed Info object in the card. * so we will have an object to test. * * We save the object's number to use in the future. @@ -3473,7 +3473,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) * to avoid any interference from other applications. * Sc_unlock will be called at a later time after the next card command * that should be a crypto operation. If its not then it is a error by the - * calling appication. + * calling application. */ if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { priv->context_specific = 1; @@ -3502,7 +3502,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) priv->pin_cmd_verify = 0; } - /* If verify worked, we are loged_in */ + /* If verify worked, we are logged_in */ if (data->cmd == SC_PIN_CMD_VERIFY) { if (r >= 0) priv->logged_in = SC_PIN_STATE_LOGGED_IN; @@ -3564,7 +3564,7 @@ static int piv_logout(sc_card_t *card) * processes, and they may have taken action already * and changed the AID and or may have sent a VERIFY with PIN * So test the state of the card. - * this is very similiar to what the piv_match routtine does, + * this is very similar to what the piv_match routine does, */ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) @@ -3584,10 +3584,10 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) goto err; } - /* can we detect and then select the PIV AID without losinig the login state? */ + /* can we detect and then select the PIV AID without losing the login state? */ if ((priv->card_issues & CI_DISCOVERY_USELESS) && (priv->card_issues & CI_PIV_AID_LOSE_STATE)) { - r = 0; /* do nothing, hope card was not interferred with */ + r = 0; /* do nothing, hope card was not interfered with */ goto err; } diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 4152709436..f6dc0c612c 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -405,7 +405,7 @@ static int setcos_pin_index_44(int *pins, int len, int pin) return 0; } -/* The ACs are allways for the SETEC_LCSI_ACTIVATED state, even if +/* The ACs are always for the SETEC_LCSI_ACTIVATED state, even if * we have to create the file in the SC_FILE_STATUS_INITIALISATION state. */ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) { @@ -485,7 +485,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) } } - /* Add the commands that are allways allowed */ + /* Add the commands that are always allowed */ if (bCommands_always) { bBuf[len++] = 1; bBuf[len++] = bCommands_always; @@ -499,7 +499,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) else bBuf[len++] = pins[i] & 0x07; /* pin ref */ } - /* Add ommands that require the key */ + /* Add commands that require the key */ if (bCommands_key) { bBuf[len++] = 2 | 0x20; /* indicate keyNumber present */ bBuf[len++] = bCommands_key; @@ -786,7 +786,7 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) int iOperation; const int* p_idx; - /* Check all sub-AC definitions whitin the total AC */ + /* Check all sub-AC definitions within the total AC */ while (len > 1) { /* minimum length = 2 */ int iACLen = buf[iOffset] & 0x0F; @@ -1038,7 +1038,7 @@ static int setcos_generate_store_key(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* Setup key-generation paramters */ + /* Setup key-generation parameters */ len = 0; if (data->op_type == OP_TYPE_GENERATE) sbuf[len++] = 0x92; /* algo ID: RSA CRT */ diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 82e3c94e7e..14a8289eff 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -734,7 +734,7 @@ static int starcos_select_file(sc_card_t *card, if ( card->cache.valid && bMatch >= 0 ) { if ( pathlen - bMatch == 2 ) - /* we are in the rigth directory */ + /* we are in the right directory */ return starcos_select_fid(card, path[bMatch], path[bMatch+1], file_out, 1); else if ( pathlen - bMatch > 2 ) { @@ -821,9 +821,9 @@ static u8 process_acl_entry(sc_file_t *in, unsigned int method, unsigned int in_ * \param card pointer to the sc_card object * \param file pointer to the sc_file object * \param data pointer to a sc_starcos_create_data structure - * \return SC_SUCCESS if no error occured otherwise error code + * \return SC_SUCCESS if no error occurred otherwise error code * - * This function tries to create a somewhat useable Starcos spk 2.3 acl + * This function tries to create a somewhat usable Starcos spk 2.3 acl * from the OpenSC internal acl (storing the result in the supplied * sc_starcos_create_data structure). */ @@ -1067,7 +1067,7 @@ static int starcos_create_ef(sc_card_t *card, sc_starcos_create_data *data) * \param file pointer to a sc_file object * \return SC_SUCCESS or error code * - * This function finishs the creation of a DF (or MF) and activates + * This function finishes the creation of a DF (or MF) and activates * the ACs. */ static int starcos_create_end(sc_card_t *card, sc_file_t *file) diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 6221017cb6..40eac877de 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -40,7 +40,7 @@ static struct sc_atr_table tcos_atrs[] = { { "3B:BA:14:00:81:31:86:5D:00:64:05:14:02:02:31:80:90:00:91", NULL, NULL, SC_CARD_TYPE_TCOS_V2, 0, NULL }, /* Infineon SLE66CX320P */ { "3B:BA:96:00:81:31:86:5D:00:64:05:60:02:03:31:80:90:00:66", NULL, NULL, SC_CARD_TYPE_TCOS_V2, 0, NULL }, - /* Infoneon SLE66CX322P */ + /* Infineon SLE66CX322P */ { "3B:BA:96:00:81:31:86:5D:00:64:05:7B:02:03:31:80:90:00:7D", NULL, NULL, SC_CARD_TYPE_TCOS_V2, 0, NULL }, /* Philips P5CT072 */ { "3B:BF:96:00:81:31:FE:5D:00:64:04:11:03:01:31:C0:73:F7:01:D0:00:90:00:7D", NULL, NULL, SC_CARD_TYPE_TCOS_V3, 0, NULL }, diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 3c03c666e4..f5518c8639 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -349,7 +349,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, file->ef_structure = SC_FILE_EF_CYCLIC; break; default: - type = "unknow"; + type = "unknown"; } sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " type: %s\n", type); @@ -452,7 +452,7 @@ static int _convertion_ac_methode(sc_file_t * file, int low, acl = sc_file_get_acl_entry(file, operation); if (acl == NULL) { - /* par defaut always */ + /* per default always */ *buf = 0xff; *buf_key = 0x00; return 0; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 3fc3a6f6ad..724e73b882 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -138,7 +138,7 @@ size_t sc_get_max_recv_size(const sc_card_t *card) } max_recv_size = card->max_recv_size; - /* initialize max_recv_size to a meaningfull value */ + /* initialize max_recv_size to a meaningful value */ if (card->caps & SC_CARD_CAP_APDU_EXT) { if (!max_recv_size) max_recv_size = 65536; @@ -165,7 +165,7 @@ size_t sc_get_max_send_size(const sc_card_t *card) max_send_size = card->max_send_size; - /* initialize max_send_size to a meaningfull value */ + /* initialize max_send_size to a meaningful value */ if (card->caps & SC_CARD_CAP_APDU_EXT && card->reader->active_protocol != SC_PROTO_T0) { if (!max_send_size) @@ -303,7 +303,7 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out) if (card->name == NULL) card->name = card->driver->name; - /* initialize max_send_size/max_recv_size to a meaningfull value */ + /* initialize max_send_size/max_recv_size to a meaningful value */ card->max_recv_size = sc_get_max_recv_size(card); card->max_send_size = sc_get_max_send_size(card); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index b610eacc77..6bb83289f6 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -155,7 +155,7 @@ enum { SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, SC_CARDCTL_RUTOKEN_DELETE_DO, SC_CARDCTL_RUTOKEN_GET_INFO, - /* NON STANDART */ + /* NON STANDARD */ SC_CARDCTL_RUTOKEN_GET_DO_INFO, SC_CARDCTL_RUTOKEN_GOST_ENCIPHER, SC_CARDCTL_RUTOKEN_GOST_DECIPHER, @@ -1023,7 +1023,7 @@ typedef struct sc_cardctl_isoApplet_ec_parameters { typedef struct sc_cardctl_isoApplet_genkey { u8 algorithm_ref; /* Algorithm reference sent to card */ - unsigned int priv_key_ref; /* Private key refernce sent to card */ + unsigned int priv_key_ref; /* Private key reference sent to card */ union { struct { @@ -1040,7 +1040,7 @@ typedef struct sc_cardctl_isoApplet_genkey { typedef struct sc_cardctl_isoApplet_import_key { u8 algorithm_ref; /* Algorithm reference sent to card */ - unsigned int priv_key_ref; /* Private key refernce sent to card */ + unsigned int priv_key_ref; /* Private key reference sent to card */ union { struct { @@ -1084,7 +1084,7 @@ typedef struct sc_cardctl_coolkey_attribute { typedef struct sc_cardctl_coolkey_find_object { int type; /* in parameter */ unsigned long find_id; /* in parameter */ - sc_cardctl_coolkey_attribute_t *coolkey_template; /* in paramter */ + sc_cardctl_coolkey_attribute_t *coolkey_template; /* in parameter */ int template_count; /* in parameter */ sc_cardctl_coolkey_object_t *obj; /* out parameter */ } sc_cardctl_coolkey_find_object_t; diff --git a/src/libopensc/ctbcs.h b/src/libopensc/ctbcs.h index adf4fd156f..7879eb309e 100644 --- a/src/libopensc/ctbcs.h +++ b/src/libopensc/ctbcs.h @@ -107,7 +107,7 @@ #define CTBCS_P2_INPUT_ASTERISKS 0x02 /* Echo input as asterisks */ /* - * Tags for paramaters to input, output et al. + * Tags for parameters to input, output et al. */ #define CTBCS_TAG_PROMPT 0x50 #define CTBCS_TAG_VERIFY_CMD 0x52 @@ -143,9 +143,9 @@ */ #define CTBCS_SW1_RESET_CT_OK 0x90 /* Reset CT successful */ #define CTBCS_SW2_RESET_CT_OK 0x00 -#define CTBCS_SW1_RESET_SYNC_OK 0x90 /* Synchoronous ICC, */ +#define CTBCS_SW1_RESET_SYNC_OK 0x90 /* Synchronous ICC, */ #define CTBCS_SW2_RESET_SYNC_OK 0x00 /* reset successful */ -#define CTBCS_SW1_RESET_ASYNC_OK 0x90 /* Asynchoronous ICC, */ +#define CTBCS_SW1_RESET_ASYNC_OK 0x90 /* Asynchronous ICC, */ #define CTBCS_SW2_RESET_ASYNC_OK 0x01 /* reset successful */ #define CTBCS_SW1_RESET_ERROR 0x64 /* Reset not successful */ #define CTBCS_SW2_RESET_ERROR 0x00 @@ -153,9 +153,9 @@ /* * Return codes for Request ICC */ -#define CTBCS_SW1_REQUEST_SYNC_OK 0x90 /* Synchoronous ICC, */ +#define CTBCS_SW1_REQUEST_SYNC_OK 0x90 /* Synchronous ICC, */ #define CTBCS_SW2_REQUEST_SYNC_OK 0x00 /* reset successful */ -#define CTBCS_SW1_REQUEST_ASYNC_OK 0x90 /* Asynchoronous ICC, */ +#define CTBCS_SW1_REQUEST_ASYNC_OK 0x90 /* Asynchronous ICC, */ #define CTBCS_SW2_REQUEST_ASYNC_OK 0x01 /* reset successful */ #define CTBCS_SW1_REQUEST_NO_CARD 0x62 /* No card present */ #define CTBCS_SW2_REQUEST_NO_CARD 0x00 @@ -169,9 +169,9 @@ /* * Return codes for Eject ICC */ -#define CTBCS_SW1_EJECT_OK 0x90 /* Command succesful, */ +#define CTBCS_SW1_EJECT_OK 0x90 /* Command successful, */ #define CTBCS_SW2_EJECT_OK 0x00 -#define CTBCS_SW1_EJECT_REMOVED 0x90 /* Command succesful, */ +#define CTBCS_SW1_EJECT_REMOVED 0x90 /* Command successful, */ #define CTBCS_SW2_EJECT_REMOVED 0x01 /* Card removed */ #define CTBCS_SW1_EJECT_NOT_REMOVED 0x62 /* Card not removed */ #define CTBCS_SW2_EJECT_NOT_REMOVED 0x00 diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index e1ca82759f..24d48fe21b 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -448,7 +448,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name const char *(*modversion)(void) = NULL; const char *(**tmodv)(void) = &modversion; - if (name == NULL) { /* should not occurr, but... */ + if (name == NULL) { /* should not occur, but... */ sc_log(ctx, "No module specified"); return NULL; } diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index be2154c823..7eaa7ee55d 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -314,7 +314,7 @@ int dnie_read_file(sc_card_t * card, goto dnie_read_file_end; } fsize = (*file)->size; - /* reserve enought space to read data from card */ + /* reserve enough space to read data from card */ if (fsize <= 0) { res = SC_ERROR_FILE_TOO_SMALL; msg = "provided buffer size is too small"; @@ -330,7 +330,7 @@ int dnie_read_file(sc_card_t * card, sc_log(ctx, "read_binary(): expected '%"SC_FORMAT_LEN_SIZE_T"u' bytes", fsize); res = sc_read_binary(card, 0, data, fsize, 0L); - if (res < 0) { /* read_binary returns number of bytes readed */ + if (res < 0) { /* read_binary returns number of bytes read */ res = SC_ERROR_CARD_CMD_FAILED; msg = "read_binary() failed"; goto dnie_read_file_err; @@ -361,7 +361,7 @@ int dnie_read_file(sc_card_t * card, * No validation is done except that received data is effectively a certificate * @param card Pointer to card driver structure * @param certpat path to requested certificate - * @param cert where to store resultig data + * @param cert where to store resulting data * @return SC_SUCCESS if ok, else error code */ static int dnie_read_certificate(sc_card_t * card, char *certpath, X509 ** cert) @@ -436,7 +436,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) EVP_PKEY_free(*root_ca_key); if (root_ca_rsa) RSA_free(root_ca_rsa); - sc_log(card->ctx, "Cannot set RSA valuses for CA public key"); + sc_log(card->ctx, "Cannot set RSA values for CA public key"); return SC_ERROR_INTERNAL; } @@ -457,7 +457,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) * (in CardVerifiable Certificate format) to be sent to the * card in External Authentication process * As this is local provider, just points to provided static data, - * and allways return success + * and always return success * * @param card Pointer to card driver Certificate * @param cert Where to store resulting byte array @@ -479,7 +479,7 @@ static int dnie_get_cvc_ca_cert(sc_card_t * card, u8 ** cert, size_t * length) * (in CardVerifiable Certificate format) to be sent to the * card in External Authentication process * As this is local provider, just points to provided static data, - * and allways return success + * and always return success * * @param card Pointer to card driver Certificate * @param cert Where to store resulting byte array @@ -502,7 +502,7 @@ static int dnie_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert, size_t * length) * (in CardVerifiable Certificate format) to be sent to the * card in External Authentication process * As this is local provider, just points to provided static data, - * and allways return success + * and always return success * * @param card Pointer to card driver Certificate * @param cert Where to store resulting byte array @@ -651,7 +651,7 @@ static int dnie_get_root_ca_pubkey_ref(sc_card_t * card, u8 ** buf, * Retrieve public key reference for intermediate CA to validate IFD cert. * * This is required in the process of On card external authenticate - * As this driver is for local SM authentication SC_SUCCESS is allways returned + * As this driver is for local SM authentication SC_SUCCESS is always returned * * @param card Pointer to card driver structure * @param buf where to store resulting key reference @@ -671,7 +671,7 @@ static int dnie_get_intermediate_ca_pubkey_ref(sc_card_t * card, u8 ** buf, * * This tells the card with in memory key reference is to be used * when CVC cert is sent for external auth procedure - * As this driver is for local SM authentication SC_SUCCESS is allways returned + * As this driver is for local SM authentication SC_SUCCESS is always returned * * @param card pointer to card driver structure * @param buf where to store data to be sent @@ -690,7 +690,7 @@ static int dnie_get_ifd_pubkey_ref(sc_card_t * card, u8 ** buf, size_t * len) * * This tells the card with in memory key reference is to be used * when CVC cert is sent for external auth procedure - * As this driver is for local SM authentication SC_SUCCESS is allways returned + * As this driver is for local SM authentication SC_SUCCESS is always returned * * @param card pointer to card driver structure * @param buf where to store data to be sent @@ -708,7 +708,7 @@ static int dnie_get_ifd_pubkey_ref_pin(sc_card_t * card, u8 ** buf, size_t * len /** * Retrieve key reference for ICC privkey. * - * In local SM stablishment, just retrieve key reference from static + * In local SM establishment, just retrieve key reference from static * data tables and just return success * * @param card pointer to card driver structure @@ -772,7 +772,7 @@ static int dnie_get_sn_icc(sc_card_t * card) struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa; res = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); - LOG_TEST_RET(card->ctx, res, "Error in gettting serial number"); + LOG_TEST_RET(card->ctx, res, "Error in getting serial number"); /* copy into sn_icc buffer.Remember that dnie sn has 7 bytes length */ memset(sm->icc.sn, 0, sizeof(sm->icc.sn)); memcpy(&sm->icc.sn[1], serial.value, 7); diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 9cd850cc1a..acf5238e41 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -51,7 +51,7 @@ * according to iso7816-4 sect 5.2.2. * * Notice that current implementation does not handle properly - * multibyte tag id. Just asume that tag is 1-byte length + * multibyte tag id. Just assume that tag is 1-byte length * Also, encodings for data length longer than 0x01000000 bytes * are not supported (tag 0x84) */ @@ -135,7 +135,7 @@ static int cwa_increase_ssc(sc_card_t * card) * * Adds an 0x80 at the end of buffer and as many zeroes to get len * multiple of 8 - * Buffer must be long enougth to store additional bytes + * Buffer must be long enough to store additional bytes * * @param buffer where to compose data * @param len pointer to buffer length @@ -151,10 +151,10 @@ static void cwa_iso7816_padding(u8 * buf, size_t * buflen) /** * compose a BER-TLV data in provided buffer. * - * Multybyte tag id are not supported + * Multibyte tag id are not supported * Also multibyte id 0x84 is unhandled * - * Notice that TLV is composed starting at offset lenght from + * Notice that TLV is composed starting at offset length from * the buffer. Consecutive calls to cwa_add_tlv, appends a new * TLV at the end of the buffer * @@ -176,7 +176,7 @@ static int cwa_compose_tlv(sc_card_t * card, /* preliminary checks */ if (!card || !card->ctx || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; - /* comodity vars */ + /* commodity vars */ ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -215,7 +215,7 @@ static int cwa_compose_tlv(sc_card_t * card, * Parse and APDU Response and extract specific BER-TLV data. * * NOTICE that iso7816 sect 5.2.2 states that Tag length may be 1 to n bytes - * length. In this code we'll assume allways tag lenght = 1 byte + * length. In this code we'll assume always tag length = 1 byte * * FIXME use `sc_asn1_read_tag` or similar instead * @@ -237,7 +237,7 @@ static int cwa_parse_tlv(sc_card_t * card, /* preliminary checks */ if (!card || !card->ctx) return SC_ERROR_INVALID_ARGUMENTS; - /* comodity vars */ + /* commodity vars */ ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -316,11 +316,11 @@ static int cwa_parse_tlv(sc_card_t * card, * * This routine uses Root CA public key data From Annex III of manual * to verify intermediate CA icc certificate provided by card - * if verify sucess, then extract public keys from intermediate CA + * if verify success, then extract public keys from intermediate CA * and verify icc certificate * * @param card pointer to sc_card_contex - * @param sub_ca_cert icc intermediate CA certificate readed from card + * @param sub_ca_cert icc intermediate CA certificate read from card * @param icc_ca icc certificate from card * @return SC_SUCCESS if verification is ok; else error code */ @@ -421,8 +421,8 @@ static int cwa_verify_cvc_certificate(sc_card_t * card, /** * Alternate implementation for set_security environment. * - * Used to handle raw apdu data in set_security_env() on SM stblishment - * Standard set_securiy_env() method has sc_security_env->buffer limited + * Used to handle raw apdu data in set_security_env() on SM establishment + * Standard set_security_env() method has sc_security_env->buffer limited * to 8 bytes; so cannot send some of required SM commands. * * @param card pointer to card data @@ -941,7 +941,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, } len2 = BN_bn2bin(sigbn, buf2); /* copy result to buffer */ if (len2 <= 0) { - msg = "Verify Signature: cannot conver bignum to buffer"; + msg = "Verify Signature: cannot convert bignum to buffer"; res = SC_ERROR_INTERNAL; goto verify_internal_done; } @@ -982,11 +982,11 @@ static int cwa_verify_internal_auth(sc_card_t * card, /** * Create Secure Messaging channel. * - * This is the main entry point for CWA14890 SM chanel creation. + * This is the main entry point for CWA14890 SM channel creation. * It closely follows cwa standard, with a minor modification: - * - ICC serial number is taken at the begining of SM creation + * - ICC serial number is taken at the beginning of SM creation * - ICC and IFD certificate agreement process is reversed, to allow - * card to retain key references on further proccess (this behavior + * card to retain key references on further process (this behavior * is also defined in standard) * * Based on Several documents: @@ -1029,7 +1029,7 @@ int cwa_create_secure_channel(sc_card_t * card, return SC_ERROR_INVALID_ARGUMENTS; if (!provider) return SC_ERROR_SM_NOT_INITIALIZED; - /* comodity vars */ + /* commodity vars */ ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -1085,7 +1085,7 @@ int cwa_create_secure_channel(sc_card_t * card, /* Read Intermediate CA from card */ if (!provider->cwa_get_icc_intermediate_ca_cert) { sc_log(ctx, - "Step 8.4.1.6: Skip Retrieveing ICC intermediate CA"); + "Step 8.4.1.6: Skip Retrieving ICC intermediate CA"); ca_cert = NULL; } else { sc_log(ctx, "Step 8.4.1.7: Retrieving ICC intermediate CA"); @@ -1187,7 +1187,7 @@ int cwa_create_secure_channel(sc_card_t * card, res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen); if (res != SC_SUCCESS) { msg = - "Cannot compose tlv for setting intermeditate CA key reference"; + "Cannot compose tlv for setting intermediate CA key reference"; goto csc_end; } res = cwa_set_security_env(card, 0x81, 0xB6, tlv, tlvlen); @@ -1196,7 +1196,7 @@ int cwa_create_secure_channel(sc_card_t * card, goto csc_end; } - /* Send IFD certiticate in CVC format C_CV_IFD */ + /* Send IFD certificate in CVC format C_CV_IFD */ sc_log(ctx, "Step 8.4.1.5: Send CVC IFD Certificate for ICC verification"); res = provider->cwa_get_cvc_ifd_cert(card, &cert, &certlen); @@ -1475,7 +1475,7 @@ int cwa_encode_apdu(sc_card_t * card, /* start kriptbuff with iso padding indicator */ *cryptbuf = 0x01; - /* aply TDES + CBC with kenc and iv=(0,..,0) */ + /* apply TDES + CBC with kenc and iv=(0,..,0) */ DES_ede3_cbc_encrypt(msgbuf, cryptbuf + 1, dlen, &k1, &k2, &k1, &iv, DES_ENCRYPT); /* compose data TLV and add to result buffer */ @@ -1536,7 +1536,7 @@ int cwa_encode_apdu(sc_card_t * card, /* compose and add computed MAC TLV to result buffer */ tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4; - sc_log(ctx, "Using TLV lenght: %"SC_FORMAT_LEN_SIZE_T"u", tlv_len); + sc_log(ctx, "Using TLV length: %"SC_FORMAT_LEN_SIZE_T"u", tlv_len); res = cwa_compose_tlv(card, 0x8E, tlv_len, macbuf, &apdubuf, &apdulen); if (res != SC_SUCCESS) { msg = "Encode APDU compose_tlv(0x87) failed"; diff --git a/src/libopensc/cwa14890.h b/src/libopensc/cwa14890.h index ca74cda441..5e9bd870d9 100644 --- a/src/libopensc/cwa14890.h +++ b/src/libopensc/cwa14890.h @@ -60,9 +60,9 @@ typedef struct cwa_provider_st { * * This code is called before any operation required in * standard cwa14890 SM stablisment process. It's usually - * used for adquiring/initialize data to be used in the + * used for acquiring/initialize data to be used in the * process (i.e: retrieve card serial number), to make sure - * that no extra apdu is sent during the SM stablishment procedure + * that no extra apdu is sent during the SM establishment procedure * * @param card pointer to card driver structure * @param provider pointer to SM data provider for DNIe @@ -74,8 +74,8 @@ typedef struct cwa_provider_st { /** * CWA-14890 SM stablisment post-operations. * - * This code is called after sucessfull SM chanel stablishment - * procedure, and before returning from create_sm_chanel() function + * This code is called after successful SM channel establishment + * procedure, and before returning from create_sm_channel() function * May be use for store data, trace, logs and so * * @param card pointer to card driver structure @@ -115,7 +115,7 @@ typedef struct cwa_provider_st { /** * Get RSA IFD (Terminal) private key data. * - * Notice that resulting data should be keept in memory as little + * Notice that resulting data should be kept in memory as little * as possible Erasing them once used * * @param card pointer to card driver structure @@ -131,7 +131,7 @@ typedef struct cwa_provider_st { * * But to do this, an special OpenSSL with PACE extensions is * needed. In the meantime, let's use binary buffers to get - * CVC and key references, until an CV_CERT hancling API + * CVC and key references, until an CV_CERT handling API * become available in standard OpenSSL * *@see http://openpace.sourceforge.net @@ -150,7 +150,7 @@ typedef struct cwa_provider_st { * @return SC_SUCCESS if ok; else error code */ int (*cwa_get_cvc_ca_cert) (sc_card_t * card, u8 ** cert, - size_t * lenght); + size_t * length); /** * Retrieve IFD (application) CVC certificate and length. @@ -165,7 +165,7 @@ typedef struct cwa_provider_st { * @return SC_SUCCESS if ok; else error code */ int (*cwa_get_cvc_ifd_cert) (sc_card_t * card, u8 ** cert, - size_t * lenght); + size_t * length); /** * Retrieve public key reference for Root CA to validate CVC intermediate CA certs. diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 12751bd7e4..9e6263fbaa 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -214,7 +214,7 @@ int sc_enum_apps(sc_card_t *card) size_t rec_size; /* Arbitrary set '16' as maximal number of records to check out: - * to avoid endless loop because of some uncomplete cards/drivers */ + * to avoid endless loop because of some incomplete cards/drivers */ for (rec_nr = 1; rec_nr < 16; rec_nr++) { r = sc_read_record(card, rec_nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 6054259ac1..cc6ba17348 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -344,7 +344,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru LOG_TEST_RET(ctx, size_size, "parse error: invalid SDO SE data size"); if (data_len != size + size_size + 3) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SDO SE data size"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SDO SE data size"); data += 3 + size_size; data_len = size; @@ -364,7 +364,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 1) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SE data size"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SE data size"); offs = 1 + size_size; for (; offs < data_len;) { @@ -375,7 +375,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru } if (offs != data_len) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totaly parsed"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totally parsed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -583,7 +583,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st LOG_TEST_RET(ctx, rv, "iasecc_parse_get_tlv() get and parse TLV error"); sc_log(ctx, - "iasecc_parse_docp() parse_get_tlv retuned %i; tag %X; size %"SC_FORMAT_LEN_SIZE_T"u", + "iasecc_parse_docp() parse_get_tlv returned %i; tag %X; size %"SC_FORMAT_LEN_SIZE_T"u", rv, tlv.tag, tlv.size); if (tlv.tag == IASECC_DOCP_TAG_ACLS) { @@ -606,7 +606,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st else if (tlv.tag == IASECC_DOCP_TAG_ISSUER_DATA) { sdo->docp.issuer_data = tlv; } - else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDATION) { + else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDIATION) { sdo->docp.non_repudiation = tlv; } else if (tlv.tag == IASECC_DOCP_TAG_USAGE_REMAINING) { @@ -655,7 +655,7 @@ iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_s free(tlv.value); LOG_TEST_RET(ctx, rv, "parse error: cannot parse DOCP"); } - else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDATION) { + else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDIATION) { sdo->docp.non_repudiation = tlv; } else if (tlv.tag == IASECC_DOCP_TAG_USAGE_REMAINING) { @@ -745,7 +745,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 3) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SDO data size"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SDO data size"); sc_log(ctx, "sz %"SC_FORMAT_LEN_SIZE_T"u, sz_size %"SC_FORMAT_LEN_SIZE_T"u", @@ -760,7 +760,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str } if (offs != data_len) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totaly parsed"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totally parsed"); sc_log(ctx, "docp.acls_contact.size %"SC_FORMAT_LEN_SIZE_T"u, docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", @@ -803,7 +803,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 3) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SDO data size"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SDO data size"); sc_log(ctx, "sz %"SC_FORMAT_LEN_SIZE_T"u, sz_size %"SC_FORMAT_LEN_SIZE_T"u", @@ -818,7 +818,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t } if (offs != data_len) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totaly parsed"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totally parsed"); sc_log(ctx, "docp.acls_contact.size %"SC_FORMAT_LEN_SIZE_T"u; docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", @@ -922,7 +922,7 @@ iasecc_encode_docp(struct sc_context *ctx, struct iasecc_sdo_docp *docp, unsigne LOG_TEST_RET(ctx, rv, "ECC: cannot add USAGE REMAINING to blob"); rv = iasecc_update_blob(ctx, &docp->non_repudiation, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add NON REPUDATION to blob"); + LOG_TEST_RET(ctx, rv, "ECC: cannot add NON REPUDIATION to blob"); rv = iasecc_update_blob(ctx, &docp->size, &tmp_blob, &blob_size); LOG_TEST_RET(ctx, rv, "ECC: cannot add SIZE to blob"); @@ -1212,7 +1212,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t if (*(data + offs) == IASECC_CARD_ANSWER_TAG_DATA ) { if (size > sizeof(out->data)) - LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "iasecc_sm_decode_answer() unbelivable !!!"); + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "iasecc_sm_decode_answer() unbelievable !!!"); memcpy(out->data, data + offs + size_size + 1, size); out->data_len = size; diff --git a/src/libopensc/iasecc-sdo.h b/src/libopensc/iasecc-sdo.h index 941ec5b3ae..bb9e70c7c6 100644 --- a/src/libopensc/iasecc-sdo.h +++ b/src/libopensc/iasecc-sdo.h @@ -34,7 +34,7 @@ #define IASECC_DOCP_TAG_TRIES_REMAINING 0x9B #define IASECC_DOCP_TAG_USAGE_MAXIMUM 0x9C #define IASECC_DOCP_TAG_USAGE_REMAINING 0x9D -#define IASECC_DOCP_TAG_NON_REPUDATION 0x9E +#define IASECC_DOCP_TAG_NON_REPUDIATION 0x9E #define IASECC_DOCP_TAG_SIZE 0x80 #define IASECC_DOCP_TAG_ACLS 0xA1 #define IASECC_DOCP_TAG_ACLS_CONTACT 0x8C diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index 681a767762..eed7c59bdb 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -335,7 +335,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd) rv = iasecc_sm_transmit_apdus (card, &rdata, cwa_session->mdata, &cwa_session->mdata_len); if (rv == SC_ERROR_PIN_CODE_INCORRECT) sc_log(ctx, "SM initialization failed, %i tries left", (rdata.data + rdata.length - 1)->apdu.sw2 & 0x0F); - LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() trasmit APDUs failed"); + LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() transmit APDUs failed"); rdata.free(&rdata); diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index 82a643921b..011167ddce 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -237,7 +237,7 @@ typedef LONG (PCSC_API *SCardGetAttrib_t)(SCARDHANDLE hCard, DWORD dwAttrId,\ /* structures used (but not defined) in PCSC Part 10: * "IFDs with Secure Pin Entry Capabilities" */ -/* Set structure elements aligment on bytes +/* Set structure elements alignment on bytes * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */ #if defined(__APPLE__) || defined(sun) #pragma pack(1) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index df283d2049..d9ae6c40eb 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -423,7 +423,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, case 0x86: if (SC_SUCCESS != sc_file_set_sec_attr(file, p, length)) { - sc_log(ctx, "Warning: Could not set file security prperties"); + sc_log(ctx, "Warning: Could not set file security properties"); } break; diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 602c40dda7..a89e22dd3e 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -142,7 +142,7 @@ void mscfs_check_cache(mscfs_t* fs) int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory) { u8* oid = objectId->id; - if ((pathlen & 1) != 0) /* not divisble by 2 */ + if ((pathlen & 1) != 0) /* not divisible by 2 */ return MSCFS_INVALID_ARGS; if(isDirectory) { /* Directory must be right next to root */ diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5af2b86215..c31e8fff21 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -85,7 +85,7 @@ extern "C" { /* Key derivation algorithms */ #define SC_ALGORITHM_PBKDF2 192 -/* Key encryption algoprithms */ +/* Key encryption algorithms */ #define SC_ALGORITHM_PBES2 256 #define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000 @@ -143,7 +143,7 @@ extern "C" { /* define mask of all algorithms that can do raw */ #define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_GOSTR3410_RAW | SC_ALGORITHM_ECDSA_RAW) -/* extened algorithm bits for selected mechs */ +/* extended algorithm bits for selected mechs */ #define SC_ALGORITHM_EXT_EC_F_P 0x00000001 #define SC_ALGORITHM_EXT_EC_F_2M 0x00000002 #define SC_ALGORITHM_EXT_EC_ECPARAMETERS 0x00000004 @@ -361,7 +361,7 @@ typedef struct sc_reader { struct sc_pin_cmd_pin { const char *prompt; /* Prompt to display */ - const unsigned char *data; /* PIN, if given by the appliction */ + const unsigned char *data; /* PIN, if given by the application */ int len; /* set to -1 to get pin from pin pad */ size_t min_length; /* min length of PIN */ @@ -601,7 +601,7 @@ struct sc_card_operations { int (*decipher)(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen); - /* compute_signature: Generates a digital signature on the card. Similiar + /* compute_signature: Generates a digital signature on the card. Similar * to the function decipher. */ int (*compute_signature)(struct sc_card *card, const u8 * data, size_t data_len, u8 * out, size_t outlen); @@ -679,7 +679,7 @@ typedef struct { unsigned long (*thread_id)(void); } sc_thread_context_t; -/** Stop modifing or using external resources +/** Stop modifying or using external resources * * Currently this is used to avoid freeing duplicated external resources for a * process that has been forked. For example, a child process may want to leave @@ -724,7 +724,7 @@ typedef struct sc_context { /** Sends a APDU to the card * @param card struct sc_card object to which the APDU should be send * @param apdu sc_apdu_t object of the APDU to be send - * @return SC_SUCCESS on succcess and an error code otherwise + * @return SC_SUCCESS on success and an error code otherwise */ int sc_transmit_apdu(struct sc_card *, struct sc_apdu *); @@ -788,7 +788,7 @@ typedef struct { /** version number of this structure (0 for this version) */ unsigned int ver; /** name of the application (used for finding application - * dependend configuration data). If NULL the name "default" + * dependent configuration data). If NULL the name "default" * will be used. */ const char *app_name; /** context flags */ @@ -919,7 +919,7 @@ int sc_disconnect_card(struct sc_card *card); /** * Checks if a card is present in a reader * @param reader Reader structure - * @retval If an error occured, the return value is a (negative) + * @retval If an error occurred, the return value is a (negative) * OpenSC error code. If no card is present, 0 is returned. * Otherwise, a positive value is returned, which is a * combination of flags. The flag SC_READER_CARD_PRESENT is @@ -942,9 +942,9 @@ int sc_detect_card_presence(sc_reader_t *reader); * @param event (OUT) the events that occurred. This is also ORed * from the SC_EVENT_CARD_* constants listed above. * @param timeout Amount of millisecs to wait; -1 means forever - * @retval < 0 if an error occured + * @retval < 0 if an error occurred * @retval = 0 if a an event happened - * @retval = 1 if the timeout occured + * @retval = 1 if the timeout occurred */ int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, @@ -1045,7 +1045,7 @@ int sc_read_binary(struct sc_card *card, unsigned int idx, u8 * buf, * @param buf buffer with the data * @param count number of bytes to write * @param flags flags for the WRITE BINARY command (currently not used) - * @return number of bytes writen or an error code + * @return number of bytes written or an error code */ int sc_write_binary(struct sc_card *card, unsigned int idx, const u8 * buf, size_t count, unsigned long flags); @@ -1056,7 +1056,7 @@ int sc_write_binary(struct sc_card *card, unsigned int idx, const u8 * buf, * @param buf buffer with the new data * @param count number of bytes to update * @param flags flags for the UPDATE BINARY command (currently not used) - * @return number of bytes writen or an error code + * @return number of bytes written or an error code */ int sc_update_binary(struct sc_card *card, unsigned int idx, const u8 * buf, size_t count, unsigned long flags); @@ -1067,7 +1067,7 @@ int sc_update_binary(struct sc_card *card, unsigned int idx, const u8 * buf, * @param idx index within the file for the data to be erased * @param count number of bytes to erase * @param flags flags for the ERASE BINARY command (currently not used) - * @return number of bytes writen or an error code + * @return number of bytes written or an error code */ int sc_erase_binary(struct sc_card *card, unsigned int idx, size_t count, unsigned long flags); @@ -1096,10 +1096,10 @@ int sc_read_record(struct sc_card *card, unsigned int rec_nr, u8 * buf, * Writes data to a record from the current (i.e. selected) file. * @param card struct sc_card object on which to issue the command * @param rec_nr SC_READ_RECORD_CURRENT or a record number starting from 1 - * @param buf buffer with to the data to be writen + * @param buf buffer with to the data to be written * @param count number of bytes to write * @param flags flags (may contain a short file id of a file to select) - * @retval number of bytes writen or an error value + * @retval number of bytes written or an error value */ int sc_write_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf, size_t count, unsigned long flags); @@ -1109,7 +1109,7 @@ int sc_write_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf, * @param buf buffer with to the data for the new record * @param count length of the data * @param flags flags (may contain a short file id of a file to select) - * @retval number of bytes writen or an error value + * @retval number of bytes written or an error value */ int sc_append_record(struct sc_card *card, const u8 * buf, size_t count, unsigned long flags); @@ -1117,10 +1117,10 @@ int sc_append_record(struct sc_card *card, const u8 * buf, size_t count, * Updates the data of a record from the current (i.e. selected) file. * @param card struct sc_card object on which to issue the command * @param rec_nr SC_READ_RECORD_CURRENT or a record number starting from 1 - * @param buf buffer with to the new data to be writen + * @param buf buffer with to the new data to be written * @param count number of bytes to update * @param flags flags (may contain a short file id of a file to select) - * @retval number of bytes writen or an error value + * @retval number of bytes written or an error value */ int sc_update_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf, size_t count, unsigned long flags); diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 2f27a6e5c5..6ee3e48646 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -161,7 +161,7 @@ sc_pkcs15_get_name_from_dn(struct sc_context *ctx, const u8 *dn, size_t dn_len, rdn = sc_asn1_skip_tag(ctx, &dn, &dn_len, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &rdn_len); if (rdn == NULL) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of Distiguished Name"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of Distinguished Name"); for (next_ava = rdn, next_ava_len = rdn_len; next_ava_len; ) { const u8 *ava, *dummy, *oidp; @@ -222,7 +222,7 @@ sc_pkcs15_get_name_from_dn(struct sc_context *ctx, const u8 *dn, size_t dn_len, * The extension is identified by it's oid value. * NOTE: extensions can occur in any number or any order, which is why we * can't parse them with a single pass of the asn1 decoder. - * If is_critical is supplied, then it is set to 1 if the extention is critical + * If is_critical is supplied, then it is set to 1 if the extension is critical * and 0 if it is not. * The data in the extension is extension specific. * The following are common extension values: diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 41b0ff32d3..09618fe56d 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -561,7 +561,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) memset(&obj_obj, 0, sizeof(obj_obj)); /* coolkey applets have label only on the certificates, - * but we should copy it also to the keys maching the same ID */ + * but we should copy it also to the keys matching the same ID */ coolkey_get_attribute_bytes(card, &coolkey_obj, CKA_LABEL, (u8 *)obj_obj.label, &len, sizeof(obj_obj.label)); coolkey_get_flags(card, &coolkey_obj, &obj_obj.flags); if (obj_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE) { diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index d3f886b21f..f51651f4bb 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -293,7 +293,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) if (r < 0) continue; - /* need to reverse the modulus skiping the tag */ + /* need to reverse the modulus skipping the tag */ j = kinfo[num_keyinfo].modulus_len; cp = kinfo[num_keyinfo].modulus; while (j--) @@ -328,7 +328,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) if (!gsdata) return SC_ERROR_OUT_OF_MEMORY; - /* set indcies of data in gsdata */ + /* set indices of data in gsdata */ idx1 = 0; /* start point */ idx2 = 0; /* index of last data read so far */ @@ -481,7 +481,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) prkey_info.modulus_length= prkeys[i].modulus_len; sc_format_path(prkeys[i].path, &prkey_info.path); - /*DEE need to look for them by reading and checking mudulus vs cert */ + /*DEE need to look for them by reading and checking modulus vs cert */ /* will use the default path, unless we found a key with */ /* the same modulus as the cert(s) we already added */ diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index ccc43c6bc9..a8162b9d01 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -225,7 +225,7 @@ static int gemsafe_get_cert_len(sc_card_t *card) } /* Delete additional key containers from the data structures if - * this card can't accomodate them. + * this card can't accommodate them. */ for (; i < gemsafe_cert_max; i++) { gemsafe_prkeys[i].label = NULL; @@ -325,7 +325,7 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - /* Manual says Le=0x05, but should be 0x08 to return full version numer */ + /* Manual says Le=0x05, but should be 0x08 to return full version number */ apdu.le = 0x08; apdu.lc = 0; apdu.datalen = 0; diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index d891fadef5..e5b9c824b4 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -37,7 +37,7 @@ #include "iasecc.h" #include "aux-data.h" -#define IASECC_GEMALTO_MD_APPLICAITON_NAME "CSP" +#define IASECC_GEMALTO_MD_APPLICATION_NAME "CSP" #define IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL "Default Key Container" static int @@ -137,7 +137,7 @@ _iasecc_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) for(ii=0; iidata; - if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICAITON_NAME)) + if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICATION_NAME)) continue; if (!strcmp(dobjs[ii]->label, IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL)) { @@ -151,7 +151,7 @@ _iasecc_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) struct sc_pkcs15_data_info *dinfo = (struct sc_pkcs15_data_info *)dobjs[ii]->data; int default_cont = 0; - if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICAITON_NAME)) + if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICATION_NAME)) continue; if (!strcmp(dobjs[ii]->label, IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL)) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index fea3d52a5c..eef8ac1f91 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -401,7 +401,7 @@ static int get_name_from_EF_DatiPersonali(unsigned char *EFdata, { /* * Bytes 0-5 contain the ASCII encoding of the following TLV - * strcture's total size, in base 16. + * structure's total size, in base 16. */ const unsigned int EF_personaldata_maxlen = 400; @@ -689,7 +689,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, "Could not read certificate file"); path.index = cert_offset; path.count = (certlen[1] << 8) + certlen[2]; - /* If those bytes are 00, then we are probably dealign with an + /* If those bytes are 00, then we are probably dealing with an * empty file. */ if (path.count == 0) return 0; diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 1426ba80d0..4f841edcca 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -593,7 +593,7 @@ sc_pkcs15emu_oberthur_add_pubkey(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Failed to add public key: no 'ID'"); len = *(info_blob + offs + 1) + *(info_blob + offs) * 0x100; if (!len || len > sizeof(key_info.id.value)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Failed to add public key: invalie 'ID' length"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Failed to add public key: invalid 'ID' length"); memcpy(key_info.id.value, info_blob + offs + 2, len); key_info.id.len = len; @@ -663,7 +663,7 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Failed to add certificate: no 'ID'"); len = *(info_blob + offs + 1) + *(info_blob + offs) * 0x100; if (len > sizeof(cinfo.id.value)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Failed to add certificate: invalie 'ID' length"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Failed to add certificate: invalid 'ID' length"); memcpy(cinfo.id.value, info_blob + offs + 2, len); cinfo.id.len = len; @@ -1081,7 +1081,7 @@ sc_awp_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) LOG_FUNC_RETURN(ctx, SC_SUCCESS); rv = sc_oberthur_read_file(p15card, AWP_OBJECTS_LIST_PRV, &buf, &buf_len, 1); - LOG_TEST_RET(ctx, rv, "Parse DF: read pribate objects info failed"); + LOG_TEST_RET(ctx, rv, "Parse DF: read private objects info failed"); rv = sc_oberthur_parse_privateinfo(p15card, buf, buf_len, 0); diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index e6b4e31abc..62a5812322 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -119,7 +119,7 @@ typedef struct common_key_info_st { * We need to return a GUID like value for each object * But this needs to be some what unique. * So we will use two different methods, depending - * on the size of the sereal number. + * on the size of the serial number. * If it is 25 bytes, then it was from a FASCN. If 16 bytes * its from a GUID. * If neither, we will uase the default method. @@ -153,12 +153,12 @@ static int piv_get_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_o if (id.len == 1 && serialnr.len == 25) { /* It is from a FASCN, and we need to shorten it but keep - * as much uniquness as possible. + * as much uniqueness as possible. * FASC-N is stored like a ISO 7811 Magnetic Strip Card * Using the ANSI/ISO BCD Data Format * 4 data bit + 1 parity bit (odd) least significant bit first. * It starts with the Start Sentinel 0x0b ";" - * Fields are seperated by 0x0d "=" + * Fields are separated by 0x0d "=" * Ends with End Sentinel 0x0f "?" * Its 39 characters + the LRC * http://www.dataip.co.uk/Reference/MagneticCardBCD.php @@ -323,7 +323,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) }; /* * NIST 800-73-1 lifted the restriction on - * requering pin protected certs. Thus the default is to + * requiring pin protected certs. Thus the default is to * not require this. */ /* certs will be pulled out from the cert objects */ @@ -386,7 +386,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) * but can be derived from the certificates. * the cert, pubkey and privkey are a set. * Key usages bits taken from pkcs15v1_1 Table 2 - * RSA and EC hav differents set of usage + * RSA and EC have different sets of usage */ static const pubdata pubkeys[PIV_NUM_CERTS_AND_KEYS] = { @@ -699,7 +699,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) * they are in order * We need to read the cert, get modulus and keylen * We use those for the pubkey, and priv key objects. - * If no cert, then see if pubkey (i.e. we are initilizing, + * If no cert, then see if pubkey (i.e. we are initializing, * and the pubkey is in a file,) then add pubkey and privkey * If no cert and no pubkey, skip adding them. @@ -909,7 +909,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsuported key.algorithm %d", cert_out->key->algorithm); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key.algorithm %d", cert_out->key->algorithm); ckis[i].pubkey_len = 0; /* set some value for now */ } ckis[i].pubkey_from_cert = cert_out->key; @@ -975,9 +975,9 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); /* set public keys */ - /* We may only need this during initialzation when genkey + /* We may only need this during initialization when genkey * gets the pubkey, but it can not be read from the card - * at a later time. The piv-tool can stach pubkey in file + * at a later time. The piv-tool can stash pubkey in file */ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding pub keys..."); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { @@ -1003,7 +1003,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); if (pubkeys[i].auth_id) sc_pkcs15_format_id(pubkeys[i].auth_id, &pubkey_obj.auth_id); - /* If no cert found, piv-tool may have stached the pubkey + /* If no cert found, piv-tool may have stashed the pubkey * so we can use it when generating a certificate request * The file is a OpenSSL DER EVP_KEY, which looks like * a certificate subjectPublicKeyInfo. @@ -1149,11 +1149,11 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); /* * When no cert is present and a pubkey in a file was found, - * means the caller is initilaizeing a card. A sign operation + * means the caller is initializing a card. A sign operation * will be required to sign a certificate request even if * normal usage would not allow it. Set SC_PKCS15_PRKEY_USAGE_SIGN - * TODO if code is added to allow key generation and reqest - * sign in the same session, similiar code will be needed. + * TODO if code is added to allow key generation and request + * sign in the same session, similar code will be needed. */ if (ckis[i].pubkey_from_file == 1) { diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 0be05bf7c7..11db273703 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -200,7 +200,7 @@ sc_pkcs15_decode_pubkey_direct_value(struct sc_pkcs15_card *p15card, struct sc_p LOG_TEST_RET(ctx, rv, "Failed to decode 'SPKI' direct value"); rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &info->direct.raw.value, &info->direct.raw.len); - LOG_TEST_RET(ctx, rv, "Failed to endode 'RAW' direct value"); + LOG_TEST_RET(ctx, rv, "Failed to encode 'RAW' direct value"); sc_pkcs15_free_pubkey(pubkey); } diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index fbdd7cf096..4219bbd36b 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -2,7 +2,7 @@ * pkcs15-sec.c: PKCS#15 cryptography functions * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyrigth (C) 2007 Nils Larsch + * Copyright (C) 2007 Nils Larsch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -49,7 +49,7 @@ static int select_key_file(struct sc_pkcs15_card *p15card, /* TODO: Why file_app may be NULL -- at least 3F00 has to be present? * Check validity of the following assumption. */ /* For pkcs15-emulated cards, the file_app may be NULL, - * in that case we allways assume an absolute path */ + * in that case we always assume an absolute path */ if (!prkey->path.len && prkey->path.aid.len) { /* Private key is a SDO allocated in application DF */ path = prkey->path; diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 9f03cdaa30..1899070a55 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -116,7 +116,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (!conf_block) { - /* no conf file found => try bultin drivers */ + /* no conf file found => try builtin drivers */ sc_log(ctx, "no conf file (or section), trying all builtin emulators"); for (i = 0; builtin_emulators[i].name; i++) { sc_log(ctx, "trying %s", builtin_emulators[i].name); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 6ba61c2171..74dcddf8a6 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -611,7 +611,7 @@ typedef struct sc_pkcs15_card { /* flags suitable for struct sc_pkcs15_card */ #define SC_PKCS15_CARD_FLAG_EMULATED 0x02000000 -/* X509 bits for certificate usage extansion */ +/* X509 bits for certificate usage extension */ #define SC_X509_DIGITAL_SIGNATURE 0x0001UL #define SC_X509_NON_REPUDIATION 0x0002UL #define SC_X509_KEY_ENCIPHERMENT 0x0004UL @@ -885,7 +885,7 @@ int sc_pkcs15_encode_unusedspace(struct sc_context *ctx, struct sc_pkcs15_card *p15card, u8 **buf, size_t *buflen); -/* Deduce private key attributes from cerresponding certificate */ +/* Deduce private key attributes from corresponding certificate */ int sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *, struct sc_pkcs15_object *, struct sc_pkcs15_object **); diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index ad73843a01..cf0774697f 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -183,7 +183,7 @@ static int cryptotokenkit_connect(sc_reader_t *reader) return SC_ERROR_CARD_NOT_PRESENT; /* if tksmartcard.context is set to nil, we know that the card has been - * reset or aquired by a different session */ + * reset or acquired by a different session */ priv->tksmartcard.context = @(YES); /* attempt to detect protocol in use T0/T1/RAW */ diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index 3c1db600fd..8d4c1c246e 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -141,7 +141,7 @@ static int refresh_attributes(sc_reader_t *reader) } else { if (rbuf[0] != CTBCS_P2_STATUS_ICC) { /* Should we be more tolerant here? I do not think so... */ - sc_log(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x", rbuf[0]); + sc_log(reader->ctx, "Invalid data object returned on CTBCS_P2_STATUS_ICC: 0x%x", rbuf[0]); return SC_ERROR_TRANSMIT_FAILED; } /* Fixme - should not be reached */ @@ -435,11 +435,11 @@ static int ctapi_load_module(sc_context_t *ctx, if (rbuf[0] != CTBCS_P2_STATUS_TFU) { /* Number of slots might also detected by using CTBCS_P2_STATUS_ICC. If you think that's important please do it... ;) */ - sc_log(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x", rbuf[0]); + sc_log(reader->ctx, "Invalid data object returned on CTBCS_P2_STATUS_TFU: 0x%x", rbuf[0]); } NumUnits = rbuf[1]; if (NumUnits + 4 > lr) { - sc_log(reader->ctx, "Invalid data returnd: %d functional units, size %d", NumUnits, rv); + sc_log(reader->ctx, "Invalid data returned: %d functional units, size %d", NumUnits, rv); } priv->ctapi_functional_units = 0; for(i = 0; i < NumUnits; i++) { diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index 7f586e902a..4f2d79b6a9 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -243,7 +243,7 @@ openct_reader_connect(sc_reader_t *reader) } if (rc == 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "openct_reader_connect recved no data\n"); + sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "openct_reader_connect received no data\n"); return SC_ERROR_READER; } diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index b80aa94079..eb5319cdb1 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1399,7 +1399,7 @@ static int pcsc_detect_readers(sc_context_t *ctx) } if (rv == (LONG)SCARD_E_SHARING_VIOLATION) { /* Assume that there is a card in the reader in shared mode if - * direct communcation failed */ + * direct communication failed */ rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &card_handle, diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 2c853bed91..a94d9564dc 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -1,5 +1,5 @@ /* - * sc-ossl-compat.h: OpenSC ecompatability for older OpenSSL versions + * sc-ossl-compat.h: OpenSC compatibility for older OpenSSL versions * * Copyright (C) 2016 Douglas E. Engert * @@ -30,7 +30,7 @@ extern "C" { #include #include /* - * Provide backward compatability to older versions of OpenSSL + * Provide backward compatibility to older versions of OpenSSL * while using most of OpenSSL 1.1 API * * LibreSSL is a fork of OpenSSL from 2014 @@ -51,7 +51,7 @@ extern "C" { * * EVP_CIPHER_CTX_new does a EVP_CIPHER_CTX_init * EVP_CIPHER_CTX_free does a EVP_CIPHER_CTX_cleanup - * EVP_CIPHER_CTX_cleanup does equivelent of a EVP_CIPHER_CTX_init + * EVP_CIPHER_CTX_cleanup does equivalent of a EVP_CIPHER_CTX_init * Use EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free, and EVP_CIPHER_CTX_cleanup between operations */ diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 2af61225ca..e422ac4a65 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -221,7 +221,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, * This function will copy a PIN, convert and pad it as required * * Note about the SC_PIN_ENCODING_GLP encoding: - * PIN buffers are allways 16 nibbles (8 bytes) and look like this: + * PIN buffers are always 16 nibbles (8 bytes) and look like this: * 0x2 + len + pin_in_BCD + paddingnibbles * in which the paddingnibble = 0xF * E.g. if PIN = 12345, then sbuf = {0x25, 0x12, 0x34, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF} diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index 55b918b467..7e4250c6c9 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -303,7 +303,7 @@ struct sm_card_operations { /* * @struct sm_module_operations * API to use external SM modules: - * - 'initiliaze' - get APDU(s) to initialize SM session; + * - 'initialize' - get APDU(s) to initialize SM session; * - 'get apdus' - get secured APDUs to execute particular command; * - 'finalize' - get APDU(s) to finalize SM session; * - 'module init' - initialize external module (allocate data, read configuration, ...); @@ -357,7 +357,7 @@ int sc_sm_update_apdu_response(struct sc_card *, unsigned char *, size_t, int, s int sc_sm_single_transmit(struct sc_card *, struct sc_apdu *); /** - * @brief Stops SM and frees allocated ressources. + * @brief Stops SM and frees allocated resources. * * Calls \a card->sm_ctx.ops.close() if available and \c card->sm_ctx.sm_mode * is \c SM_MODE_TRANSMIT diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index ddd1f09d70..206273fe7a 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -223,11 +223,11 @@ static void logprintf(PCARD_DATA pCardData, int level, _Printf_format_string_ co { va_list arg; VENDOR_SPECIFIC *vs; -/* Use a simplied log to get all messages including messages +/* Use a simplified log to get all messages including messages * before opensc is loaded. The file must be modifiable by all * users as we maybe called under lsa or user. Note data from * multiple process and threads may get intermingled. - * flush to get last message before ann crash + * flush to get last message before any crash * close so as the file is not left open during any wait. */ DWORD md_debug = 0; @@ -653,7 +653,7 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, BOOL ret_default) static BOOL md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) { - logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enableed?\n"); + logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enabled?\n"); return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", FALSE); } @@ -815,7 +815,7 @@ md_contguid_build_cont_guid_from_key(PCARD_DATA pCardData, struct sc_pkcs15_obje DWORD dwret = SCARD_S_SUCCESS; szGuid[0] = '\0'; - /* priorize the use of the key id over the key label as a container name */ + /* prioritize the use of the key id over the key label as a container name */ if (md_is_guid_as_id(pCardData) && prkey_info->id.len > 0 && prkey_info->id.len <= MAX_CONTAINER_NAME_LEN) { memcpy(szGuid, prkey_info->id.value, prkey_info->id.len); szGuid[prkey_info->id.len] = 0; @@ -1582,7 +1582,7 @@ md_fs_add_msroots(PCARD_DATA pCardData, struct md_file **head) * 2b. Change the index of internal p15_container according to the index from 'DATA' file. * Records from 'DATA' file are ignored is they do not have * the corresponding PKCS#15 private key object. - * 3. Initalize the content of the 'soft' 'cmapfile' from the inernal p15-containers. + * 3. Initialize the content of the 'soft' 'cmapfile' from the internal p15-containers. */ static DWORD md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) @@ -1813,7 +1813,7 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) cont->id = prkey_info->id; cont->prkey_obj = prkey_objs[ii]; - /* Try to find the friend objects: certficate and public key */ + /* Try to find the friend objects: certificate and public key */ if (!sc_pkcs15_find_cert_by_id(vs->p15card, &cont->id, &cont->cert_obj)) logprintf(pCardData, 2, "found certificate friend '%.*s'\n", (int) sizeof cont->cert_obj->label, cont->cert_obj->label); @@ -2674,7 +2674,7 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi pKeySizes->dwMaximumBitlen = 0; pKeySizes->dwIncrementalBitlen = 0; - /* dwKeySpec=0 is a special value when the key size is queried without specifing the algorithm. + /* dwKeySpec=0 is a special value when the key size is queried without specifying the algorithm. Used on old minidriver version. In this case, it is RSA */ if ((dwKeySpec == 0) || (dwKeySpec == AT_KEYEXCHANGE) || (dwKeySpec == AT_SIGNATURE)) { for (i = 0; i < count; i++) { @@ -2981,7 +2981,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p tc.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION; tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; } else { - /* can't use TDCBF_CANCEL_BUTTON since this would implicitely set TDF_ALLOW_DIALOG_CANCELLATION */ + /* can't use TDCBF_CANCEL_BUTTON since this would implicitly set TDF_ALLOW_DIALOG_CANCELLATION */ tc.dwCommonButtons = TDCBF_CLOSE_BUTTON; } @@ -4383,7 +4383,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, goto err; } - /* filter boggus input: the data to decrypt is shorter than the RSA key ? */ + /* filter bogus input: the data to decrypt is shorter than the RSA key ? */ if ( pInfo->cbData < prkey_info->modulus_length / 8) { /* according to the minidriver specs, this is the error code to return @@ -5362,8 +5362,8 @@ DWORD WINAPI CardDeriveKey(__in PCARD_DATA pCardData, if (pAgreementInfo->dwFlags & ~(KDF_USE_SECRET_AS_HMAC_KEY_FLAG | CARD_RETURN_KEY_HANDLE | CARD_BUFFER_SIZE_ONLY)) return SCARD_E_INVALID_PARAMETER; - /* according to the documenation, CARD_DERIVE_KEY_CURRENT_VERSION should be equal to 2. - In pratice it is not 2 but 1 + /* according to the documentation, CARD_DERIVE_KEY_CURRENT_VERSION should be equal to 2. + In practice it is not 2 but 1 if ( pAgreementInfo->dwVersion < CARD_DERIVE_KEY_CURRENT_VERSION && pCardData->dwVersion == CARD_DATA_CURRENT_VERSION) @@ -5473,7 +5473,7 @@ DWORD WINAPI CardDeriveKey(__in PCARD_DATA pCardData, szAlgorithm = BCRYPT_SHA1_ALGORITHM; } - /* check the values with the KDF choosen */ + /* check the values with the KDF chosen */ if (wcscmp(pAgreementInfo->pwszKDF, BCRYPT_KDF_HASH) == 0) { } else if (wcscmp(pAgreementInfo->pwszKDF, BCRYPT_KDF_HMAC) == 0) { @@ -5924,7 +5924,7 @@ DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData, if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) return SCARD_E_NO_KEY_CONTAINER; - /* the test for the existence of containers is redondant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */ + /* the test for the existence of containers is redundant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */ vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); if (!vs) return SCARD_E_INVALID_PARAMETER; @@ -6606,11 +6606,11 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags return SCARD_E_INVALID_PARAMETER; if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE)) { if( pCardData->hSCardCtx == 0) { - logprintf(pCardData, 0, "Invalide handle.\n"); + logprintf(pCardData, 0, "Invalid handle.\n"); return SCARD_E_INVALID_HANDLE; } if( pCardData->hScard == 0) { - logprintf(pCardData, 0, "Invalide handle.\n"); + logprintf(pCardData, 0, "Invalid handle.\n"); return SCARD_E_INVALID_HANDLE; } } @@ -6624,7 +6624,7 @@ DWORD WINAPI CardAcquireContext(__inout PCARD_DATA pCardData, __in DWORD dwFlags return SCARD_E_INVALID_PARAMETER; if ( pCardData->pwszCardName == NULL ) return SCARD_E_INVALID_PARAMETER; - /* <2 lenght or >=0x22 are not ISO compliant */ + /* <2 length or >=0x22 are not ISO compliant */ if (pCardData->cbAtr >= 0x22 || pCardData->cbAtr <= 0x2) return SCARD_E_INVALID_PARAMETER; /* ATR beginning by 0x00 or 0xFF are not ISO compliant */ diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index 2a91b5c33c..4844a14b00 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -1,7 +1,7 @@ #include #define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ +/* defined twice: in resource file and in source code */ #define IDI_SMARTCARD 102 #ifndef __MINGW32__ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index b7fe88634b..abc59d1437 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1327,7 +1327,7 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p pkcs15_add_object(slot, obj, NULL); } else { - sc_log(context, "Slot:%p Object %d skeeped", slot, i); + sc_log(context, "Slot:%p Object %d skipped", slot, i); continue; } @@ -1366,7 +1366,7 @@ _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data) if (obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) continue; /* PKCS#15 4.1.3 is a little vague, but implies if not PRIVATE it is readable - * even if there is an auth_id to allow writting for example. + * even if there is an auth_id to allow writing for example. * See bug issue #291 * treat pubkey and cert as readable.a */ @@ -2301,7 +2301,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile skey_info->key_type = key_type; /* PKCS#11 CKK_* */ skey_info->data.value = args.key.data; skey_info->data.len = args.key.data_len; - skey_info->value_len = args.value_len; /* callers prefered length */ + skey_info->value_len = args.value_len; /* callers preferred length */ args.key.data = NULL; } else { @@ -2640,7 +2640,7 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK /* TODO The previous code does not check for CKA_TOKEN=TRUE * PKCS#11 CreatObject examples always have it, but * PKCS#11 says the default is false. - * for backward compatability, will default to TRUE + * for backward compatibility, will default to TRUE */ /* Dont need profile id creating session only objects */ if (_token == TRUE) { @@ -3052,7 +3052,7 @@ pkcs15_skey_destroy(struct sc_pkcs11_session *session, void *object) return sc_to_cryptoki_error(rv, "C_DestroyObject"); /* Oppose to pkcs15_add_object */ - --any_obj->refcount; /* correct refcont */ + --any_obj->refcount; /* correct refcount */ list_delete(&session->slot->objects, any_obj); /* Delete object in pkcs15 */ rv = __pkcs15_delete_object(fw_data, any_obj); @@ -3136,7 +3136,7 @@ pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object) rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object); if (rv >= 0) { /* Oppose to pkcs15_add_object */ - --any_obj->refcount; /* correct refcont */ + --any_obj->refcount; /* correct refcount */ list_delete(&session->slot->objects, any_obj); /* Delete object in pkcs15 */ rv = __pkcs15_delete_object(fw_data, any_obj); @@ -3763,7 +3763,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) { /* If private key PKCS#15 object do not have 'path' attribute, * and if PKCS#11 login session is not locked, - * the compute signature could fail because of concurent access to the card + * the compute signature could fail because of concurrent access to the card * by other application that could change the current DF. * In this particular case try to 'reselect' application DF. */ @@ -4935,7 +4935,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) #ifdef ENABLE_OPENSSL /* all our software hashes are in OpenSSL */ - /* Only if card did not lists the hashs, will we + /* Only if card did not list the hashes, will we * help it a little, by adding all the OpenSSL hashes * that have PKCS#11 mechanisms. */ diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 9082d37add..5f006c8397 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -847,7 +847,7 @@ sc_pkcs11_deri(struct sc_pkcs11_session *session, /* Get the size of the data to be returned * If the card could derive a key an leave it on the card * then no data is returned. - * If the card returns the data, we will store it in the sercet key CKA_VALUE + * If the card returns the data, we will store it in the secret key CKA_VALUE */ ulDataLen = 0; @@ -867,7 +867,7 @@ sc_pkcs11_deri(struct sc_pkcs11_session *session, goto out; } - /* Now do the actuall derivation */ + /* Now do the actual derivation */ rv = operation->type->derive(operation, basekey, pMechanism->pParameter, pMechanism->ulParameterLen, diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 504026dea0..3936c23a7b 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -757,7 +757,7 @@ sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR args) /* Shall be used in threaded environment, must use operating system locking */ global_locking = default_mutex_funcs; } else if (applock && !oslock) { - /* Shall be used in threaded envirnoment, must use app provided locking */ + /* Shall be used in threaded environment, must use app provided locking */ global_locking = args; } else if (!applock && !oslock) { /* Shall not be used in threaded environment, use operating system locking */ diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index 6f0954dd67..aebc6351c9 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -4,7 +4,7 @@ /* OpenSC specific extensions */ /* * define OpenSC specific Vendor Defined extensions - * to make unique OpenSC flags, attribures, mechanisms, etc. + * to make unique OpenSC flags, attributes, mechanisms, etc. * * Netscape used NSSCK_VENDOR_NSS 0x4E534350 "NSCP" */ @@ -13,7 +13,7 @@ /* * In PKCS#11 there is no CKA_ attribute dedicated to the NON-REPUDIATION flag. - * We need this flag in PKCS#15/libopensc to make dinstinction between + * We need this flag in PKCS#15/libopensc to make distinction between * 'signature' and 'qualified signature' key slots. */ #define CKA_OPENSC_NON_REPUDIATION (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 1UL) diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index d088b2bc1d..9351e58db3 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -61,7 +61,7 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */ if (rv != CKR_OK) goto out; - /* Check that no conflictions sessions exist */ + /* Check that no conflicting sessions exist */ if (!(flags & CKF_RW_SESSION) && (slot->login_user == CKU_SO)) { rv = CKR_SESSION_READ_WRITE_SO_EXISTS; goto out; diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 275094abb9..a3fa1d8f80 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -50,7 +50,7 @@ static void *modhandle = NULL; /* Spy module output */ static FILE *spy_output = NULL; -/* Inits the spy. If successfull, po != NULL */ +/* Inits the spy. If successful, po != NULL */ static CK_RV init_spy(void) { @@ -153,7 +153,7 @@ init_spy(void) #ifdef _WIN32 if (!spy_output) { - /* try for the machine version first, as we may be runing + /* try for the machine version first, as we may be running * without a user during login */ rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\PKCS11-Spy", 0, KEY_QUERY_VALUE, &hKey ); @@ -188,7 +188,7 @@ init_spy(void) module = getenv("PKCS11SPY"); #ifdef _WIN32 if (!module) { - /* try for the machine version first, as we may be runing + /* try for the machine version first, as we may be running * without a user during login */ rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\PKCS11-Spy", diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 2c5c4f2e71..692f5e3621 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -850,7 +850,7 @@ _CK_DECLARE_FUNCTION (C_SetOperationState, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, - ck_object_handle_t authentiation_key)); + ck_object_handle_t authentication_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 4929759650..bb59b0791c 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -158,7 +158,7 @@ struct sc_pkcs11_framework_ops { CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG); /* - * In future: functions to create new objects (ie. certificates, private keys) + * In future: functions to create new objects (i.e. certificates, private keys) */ CK_RV (*init_token)(struct sc_pkcs11_slot *, void *, CK_UTF8CHAR_PTR, CK_ULONG, @@ -219,7 +219,7 @@ struct sc_pkcs11_slot { sc_timestamp_t slot_state_expires; int fw_data_idx; /* Index of framework data */ - struct sc_app_info *app_info; /* Application assosiated to slot */ + struct sc_app_info *app_info; /* Application associated to slot */ list_t logins; /* tracks all calls to C_Login if atomic operations are requested */ int flags; }; diff --git a/src/pkcs15init/ias_adele_admin1.profile b/src/pkcs15init/ias_adele_admin1.profile index af5ae8edf6..dce404b0a1 100644 --- a/src/pkcs15init/ias_adele_admin1.profile +++ b/src/pkcs15init/ias_adele_admin1.profile @@ -141,7 +141,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/ias_adele_admin2.profile b/src/pkcs15init/ias_adele_admin2.profile index a35fb1b1df..2e08140c7b 100644 --- a/src/pkcs15init/ias_adele_admin2.profile +++ b/src/pkcs15init/ias_adele_admin2.profile @@ -10,7 +10,7 @@ cardinfo { pin-encoding = ascii-numeric; pin-pad-char = 0xFF; - # Delete or not the public key when inconporating the + # Delete or not the public key when incorporating the # corresponding certificate. keep-public-key = yes; # yes/no } @@ -138,7 +138,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/ias_adele_common.profile b/src/pkcs15init/ias_adele_common.profile index 9c5b81fe15..257cb421a3 100644 --- a/src/pkcs15init/ias_adele_common.profile +++ b/src/pkcs15init/ias_adele_common.profile @@ -134,7 +134,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/iasecc.profile b/src/pkcs15init/iasecc.profile index 7b9a8548cd..398edfb9a1 100644 --- a/src/pkcs15init/iasecc.profile +++ b/src/pkcs15init/iasecc.profile @@ -52,7 +52,7 @@ PIN so-pin { reference = 2 } -# CHV5 used for Oberthur's specifique access condition "PIN or SOPIN" +# CHV5 used for Oberthur's specific access condition "PIN or SOPIN" # Any value for this pin can given, when the OpenSC tools are asking for. # Additional filesystem info. diff --git a/src/pkcs15init/iasecc_admin_eid.profile b/src/pkcs15init/iasecc_admin_eid.profile index 395720bc2f..a51b68ec0e 100644 --- a/src/pkcs15init/iasecc_admin_eid.profile +++ b/src/pkcs15init/iasecc_admin_eid.profile @@ -54,7 +54,7 @@ PIN so-pin { reference = 2 } -# CHV5 used for Oberthur's specifique access condition "PIN or SOPIN" +# CHV5 used for Oberthur's specific access condition "PIN or SOPIN" # Any value for this pin can given, when the OpenSC tools are asking for. # Additional filesystem info. @@ -141,7 +141,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/iasecc_generic_oberthur.profile b/src/pkcs15init/iasecc_generic_oberthur.profile index 2c9c093b9f..82f265bc74 100644 --- a/src/pkcs15init/iasecc_generic_oberthur.profile +++ b/src/pkcs15init/iasecc_generic_oberthur.profile @@ -136,7 +136,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/iasecc_generic_pki.profile b/src/pkcs15init/iasecc_generic_pki.profile index da5b0dec13..5f150e4f4d 100644 --- a/src/pkcs15init/iasecc_generic_pki.profile +++ b/src/pkcs15init/iasecc_generic_pki.profile @@ -54,7 +54,7 @@ PIN so-pin { reference = 2 } -# CHV5 used for Oberthur's specifique access condition "PIN or SOPIN" +# CHV5 used for Oberthur's specific access condition "PIN or SOPIN" # Any value for this pin can given, when the OpenSC tools are asking for. # Additional filesystem info. @@ -139,7 +139,7 @@ filesystem { # Private DES keys BSO private-des { size = 24; # 192 bits - # READ acl used insted of DECIPHER/ENCIPHER/CHECKSUM + # READ acl used instead of DECIPHER/ENCIPHER/CHECKSUM } # Private data diff --git a/src/pkcs15init/oberthur.profile b/src/pkcs15init/oberthur.profile index 15888b2602..57baa779fe 100644 --- a/src/pkcs15init/oberthur.profile +++ b/src/pkcs15init/oberthur.profile @@ -42,7 +42,7 @@ PIN so-pin { reference = 4 } -# CHV5 used for Oberthur's specifique access condition "PIN or SOPIN" +# CHV5 used for Oberthur's specific access condition "PIN or SOPIN" # Any value for this pin can given, when the OpenSC tools are asking for. # Additional filesystem info. @@ -84,7 +84,7 @@ filesystem { file-id = 4000; type = internal-ef; size = 24; # 192 bits - # READ acl used insted of DECRYPT/ENCRYPT/CHECKSUM + # READ acl used instead of DECRYPT/ENCRYPT/CHECKSUM ACL = UPDATE=CHV1, READ=CHV1; } diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index 7904fb5af3..41d8551c78 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -101,7 +101,7 @@ static int asepcos_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card) * - use EF(DIR) to get the DF of the OpenSC * pkcs15 application. */ - /* Check wether a transport exists and verify it if present */ + /* Check whether a transport exists and verify it if present */ p15card->opts.use_pin_cache = 1; r = asepcos_check_verify_tpin(profile, p15card); @@ -137,7 +137,7 @@ static int asepcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_context_t *ctx = p15card->card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); - /* Check wether a transport exists and verify it if present */ + /* Check whether a transport exists and verify it if present */ r = asepcos_check_verify_tpin(profile, p15card); if (r != SC_SUCCESS) return r; @@ -367,7 +367,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_CREATE); sc_file_free(tfile); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create PIN file, insufficent rights"); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create PIN file, insufficient rights"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index ccc22c84b0..af1110fafe 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -636,7 +636,7 @@ authentic_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15c LOG_TEST_RET(ctx, rv, "generate key failed"); pubkey->algorithm = SC_ALGORITHM_RSA; - //FIXME: allocate/copy/free to reduce memory likage + //FIXME: allocate/copy/free to reduce memory leakage pubkey->u.rsa.modulus = sdo->data.prvkey->u.rsa.modulus; pubkey->u.rsa.exponent = sdo->data.prvkey->u.rsa.exponent; sdo->data.prvkey = NULL; diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 1fd5e31cc2..924eeb6bd9 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -139,7 +139,7 @@ cardos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d return r; /* Create a default security environment for this DF. - * This SE autometically becomes the current SE when the + * This SE automatically becomes the current SE when the * DF is selected. */ if ((r = cardos_create_sec_env(profile, p15card->card, 0x01, 0x00)) < 0) return r; diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 9a365a4bbf..60a1ddca76 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -51,7 +51,7 @@ static int epass2003_pkcs15_init_card(struct sc_profile *profile, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_do_log(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,NULL,0,NULL, - "ePass2003 doesn't surpport SO-PIN and SO-PUK. You can unblock key with PUK. \n"); + "ePass2003 doesn't support SO-PIN and SO-PUK. You can unblock key with PUK. \n"); { /* MF */ struct sc_file *mf_file; struct sc_file *skey_file; diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index e5bc2c79d3..40156fd580 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -93,7 +93,7 @@ iasecc_pkcs15_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *pro rv = sc_pkcs15init_authenticate(profile, p15card, df, SC_AC_OP_DELETE); card->caps = caps; - LOG_TEST_RET(ctx, rv, "Cannnot authenticate SC_AC_OP_DELETE"); + LOG_TEST_RET(ctx, rv, "Cannot authenticate SC_AC_OP_DELETE"); memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; @@ -374,7 +374,7 @@ iasecc_sdo_set_key_acls_from_profile(struct sc_profile *profile, struct sc_card /* Get ACLs from profile template */ rv = sc_profile_get_file(profile, template, &file); - LOG_TEST_RET(ctx, rv, "IasEcc: cannot instanciate private key file"); + LOG_TEST_RET(ctx, rv, "IasEcc: cannot instantiate private key file"); /* Convert PKCS15 ACLs to SE ACLs */ rv = iasecc_file_convert_acls(ctx, profile, file); @@ -473,7 +473,7 @@ iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, sdo->docp.non_repudiation.value = calloc(1, 1); if (!sdo->docp.non_repudiation.value) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - sdo->docp.non_repudiation.tag = IASECC_DOCP_TAG_NON_REPUDATION; + sdo->docp.non_repudiation.tag = IASECC_DOCP_TAG_NON_REPUDIATION; sdo->docp.non_repudiation.size = 1; sdo->data.prv_key.compulsory.value = calloc(1, 1); @@ -496,7 +496,7 @@ iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, If present, this attribute has to be the same in the 'GENERATE KEY' template data. */ if (!(key_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) && (key_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) - sc_log(ctx, "Non fatal error: NON_REPUDATION can be used only for the localy generated keys"); + sc_log(ctx, "Non fatal error: NON_REPUDIATION can be used only for the locally generated keys"); if ((key_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) && (key_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN) @@ -1137,7 +1137,7 @@ iasecc_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15card return SC_ERROR_INVALID_ARGUMENTS; } - /* TODO: Check if native IAS middleware accepts the meaningfull path value. */ + /* TODO: Check if native IAS middleware accepts the meaningful path value. */ rv = sc_profile_get_parent(profile, "private-key", &file); LOG_TEST_RET(ctx, rv, "IasEcc: cannot get private key parent file"); diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 44ab63525a..968c39b349 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -367,7 +367,7 @@ extern int sc_pkcs15init_delete_object(struct sc_pkcs15_card *, struct sc_profile *, struct sc_pkcs15_object *); /* Replace an existing cert with a new one, which is assumed to be - * compatible with the correcsponding private key (e.g. the old and + * compatible with the corresponding private key (e.g. the old and * new cert should have the same public key). */ extern int sc_pkcs15init_update_certificate(struct sc_pkcs15_card *, diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 78d88e6815..cc4fa3f37d 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -345,7 +345,7 @@ isoApplet_get_curve(u8 *oid, size_t oid_len, const struct ec_curve **curve_out) * @param[in] pubkey The public key of the generated key pair * returned by the card. * - * @return SC_ERROR_INVALID_ARGURMENTS: Invalid key length. + * @return SC_ERROR_INVALID_ARGUMENTS: Invalid key length. * SC_ERROR_OUT_OF_MEMORY */ static int @@ -434,7 +434,7 @@ isoApplet_generate_key_rsa(sc_pkcs15_prkey_info_t *key_info, sc_card_t *card, * @param[in/out] pubkey The public key of the generated key pair * returned by the card. * - * @return SC_ERROR_INVALID_ARGURMENTS: Invalid key length or curve. + * @return SC_ERROR_INVALID_ARGUMENTS: Invalid key length or curve. * SC_ERROR_OUT_OF_MEMORY * SC_ERROR_INCOMPATIBLE_KEY: The data returned by the card * was unexpected and can not be @@ -736,7 +736,7 @@ isoApplet_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_ args.algorithm_ref = SC_ISOAPPLET_ALG_REF_EC_GEN; if(key->u.ec.params.der.len == 0 || key->u.ec.params.der.value == NULL) { r = sc_pkcs15_fix_ec_parameters(card->ctx, &key->u.ec.params); - LOG_TEST_RET(card->ctx, r, "EC key storing failed: Unkown curve."); + LOG_TEST_RET(card->ctx, r, "EC key storing failed: Unknown curve."); } r = isoApplet_get_curve(key->u.ec.params.der.value, key->u.ec.params.der.len, &curve); LOG_TEST_RET(card->ctx, r, "EC key generation failed: Unsupported curve"); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e98ababc24..280693761a 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -803,7 +803,7 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PUK, &puk_ainfo); r = sc_pkcs15init_qualify_pin(card, "SO PUK", args->so_puk_len, &puk_ainfo); - LOG_TEST_RET(ctx, r, "Failed to qulify SO PUK"); + LOG_TEST_RET(ctx, r, "Failed to qualify SO PUK"); if (!(pin_label = args->so_pin_label)) { if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) @@ -2617,7 +2617,7 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof if (id_out->len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); - /* Native ID style is not intrisic one */ + /* Native ID style is not intrinsic one */ if (id_style == SC_PKCS15INIT_ID_STYLE_NATIVE) LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -2643,7 +2643,7 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - /* Skip silently if key is not inintialized. */ + /* Skip silently if key is not initialized. */ if (pubkey->algorithm == SC_ALGORITHM_RSA && !pubkey->u.rsa.modulus.len) goto done; else if (pubkey->algorithm == SC_ALGORITHM_DSA && !pubkey->u.dsa.pub.data) @@ -3772,7 +3772,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p * * In the latter case, there's a problem here if e.g. the SO PIN * defined by the profile is optional, and hasn't been set. - * On the orther hands, some cards do not return access conditions + * On the other hands, some cards do not return access conditions * in their response to SELECT FILE), so the latter case has been * used in most cards while the first case was added much later. */ diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index a2696e31ae..4daf0ff0c5 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1012,7 +1012,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob * i2c_ASN1_INTEGER which is not in OpenSSL 1.1 * It was adding the tag V_ASN1_INTEGER and the one byte length back in in effect creating * a DER encoded ASN1_INTEGER - * So we can simplifty the code and make compatable with OpenSSL 1.1. This needs to be tested + * So we can simplify the code and make compatible with OpenSSL 1.1. This needs to be tested */ ci->serial.len = 0; ci->serial.value = NULL; @@ -1801,7 +1801,7 @@ awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannt get allocate new AWP file"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot get allocate new AWP file"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); @@ -1835,7 +1835,7 @@ awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannt get allocate new AWP file"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot get allocate new AWP file"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); @@ -1869,7 +1869,7 @@ awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannt get allocate new AWP file"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot get allocate new AWP file"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); @@ -1903,7 +1903,7 @@ awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannt get allocate new AWP file"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannot get allocate new AWP file"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 76f21d63e2..8ef541dd44 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -78,7 +78,7 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile if (file->size < 16) { rv = SC_ERROR_INCONSISTENT_PROFILE; - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Unsufficient size of the "COSM_TITLE"-token-info file"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Insufficient size of the "COSM_TITLE"-token-info file"); } buffer = calloc(1, file->size); @@ -138,11 +138,11 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, path.len -= 2; rv = sc_select_file(p15card->card, &path, &parent); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannnot select parent"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot select parent"); rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannnot authenticate SC_AC_OP_DELETE"); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot authenticate SC_AC_OP_DELETE"); memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; @@ -689,7 +689,7 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); /* Here, the path of private key file should be defined. - * Neverthelles, we need to instanciate private key to get the ACLs. */ + * Nevertheless, we need to instantiate private key to get the ACLs. */ rv = cosm_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot create key: failed to allocate new key object"); diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index f540abc7fa..d1c8e8b987 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -763,7 +763,7 @@ static int starcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, tkey.key_header[4] = 0x0f; /* do state transition */ else tkey.key_header[4] = 0x8f; /* no state transition */ - tkey.key_header[5] = 0x11; /* requiere local state == 1 to update key */ + tkey.key_header[5] = 0x11; /* require local state == 1 to update key */ tkey.key_header[6] = 0x33; tkey.key_header[7] = 0x00; tkey.key_header[8] = 0x09; diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 194d6deb4d..2eaac6477f 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -323,7 +323,7 @@ static int westcos_pkcs15init_finalize_card(sc_card_t *card) { int r; - /* be sure authentificate card */ + /* be sure authenticate card */ r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL); if(r) return (r); diff --git a/src/pkcs15init/setcos.profile b/src/pkcs15init/setcos.profile index cd58b73aa0..f566b0e312 100644 --- a/src/pkcs15init/setcos.profile +++ b/src/pkcs15init/setcos.profile @@ -7,7 +7,7 @@ cardinfo { pin-pad-char = 0x00; } -# Addtional default settings +# Additional default settings option default { macros { protected = *=$SOPIN, READ=NONE; @@ -20,7 +20,7 @@ option default { } } -# Addtional onepin option settings +# Additional onepin option settings option onepin { macros { protected = *=$PIN, READ=NONE; diff --git a/src/scconf/README.scconf b/src/scconf/README.scconf index f30e382304..1653789430 100644 --- a/src/scconf/README.scconf +++ b/src/scconf/README.scconf @@ -18,7 +18,7 @@ It isn't It doesn't have - anything else but data. No locking, no threads etc. -It has heirarchical data blocks, it has lists. +It has hierarchical data blocks, it has lists. Similar, but different: - .ini files. scconf is block structured, has lists and arrays @@ -132,9 +132,9 @@ const scconf_block *scconf_find_block(const scconf_context * config, const scconf_block * block, const char *item_name); This finds a block in the given context. This function doesn't descend -the heirarchy, it only finds blocks in the top level of either +the hierarchy, it only finds blocks in the top level of either the context (the root block) or of the block given in the block -paramter (if not NULL). +parameter (if not NULL). The block pointer returned points to data held by the context, hence the const qualifier. diff --git a/src/scconf/scconf.c b/src/scconf/scconf.c index 0849560d2a..aaa3fb1c00 100644 --- a/src/scconf/scconf.c +++ b/src/scconf/scconf.c @@ -147,7 +147,7 @@ const char *scconf_get_str(const scconf_block * block, const char *option, const if (!list) return def; - /* ignore non 'auto-configurated' values */ + /* ignore non 'auto-configured' values */ if (*list->data == '@' && *(list->data + strlen(list->data) - 1) == '@') return def; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index d789a51572..8317f41b55 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1185,7 +1185,7 @@ int perform_pace(sc_card_t *card, pace_input.pin_id, chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol properties " "(MSE: Set AT failed)."); goto err; } @@ -1570,7 +1570,7 @@ int perform_terminal_authentication(sc_card_t *card, cvc_cert->body->certificate_authority_reference->data, cvc_cert->body->certificate_authority_reference->length); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol properties " "(MSE: Set AT failed)."); goto err; } @@ -1609,7 +1609,7 @@ int perform_terminal_authentication(sc_card_t *card, (unsigned char *) eacsmctx->eph_pub_key->data, eacsmctx->eph_pub_key->length, auxiliary_data, auxiliary_data_len); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol properties " "(MSE: Set AT failed)."); goto err; } @@ -1834,7 +1834,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, r = eac_mse_set_at_ca(card, ctx->ca_ctx->protocol); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol properties " "(MSE: Set AT failed)."); goto err; } diff --git a/src/sm/sm-iso-internal.h b/src/sm/sm-iso-internal.h index 9d8e9d09e8..43650340a1 100644 --- a/src/sm/sm-iso-internal.h +++ b/src/sm/sm-iso-internal.h @@ -72,7 +72,7 @@ int iso_get_sm_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu * int iso_free_sm_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu); /** - * @brief Cleans up allocated ressources of the ISO SM driver + * @brief Cleans up allocated resources of the ISO SM driver * * \c iso_sm_close() is designed as SM card operation. However, have in mind * that this card operation is not called automatically for \c diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index 8b7e8ec2dc..9cb359dee7 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -80,7 +80,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, sc_log(ctx, "key_buf:%s", sc_dump_hex(key_buff, 16)); rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); - LOG_TEST_RET(ctx, rv, "GP init session: cannot derivate key"); + LOG_TEST_RET(ctx, rv, "GP init session: cannot derive key"); memcpy(keys[ii], tmp, sizeof(gp_keyset->enc)); free(tmp); diff --git a/src/smm/sm-card-iasecc.c b/src/smm/sm-card-iasecc.c index a77849d053..7e8aab99f9 100644 --- a/src/smm/sm-card-iasecc.c +++ b/src/smm/sm-card-iasecc.c @@ -248,7 +248,7 @@ sm_iasecc_get_apdu_verify_pin(struct sc_context *ctx, struct sm_info *sm_info, s rapdu->apdu.p1 = 0x00; rapdu->apdu.p2 = pin_data->pin_reference & ~IASECC_OBJECT_REF_GLOBAL; if (pin_data->pin1.len > SM_MAX_DATA_SIZE) - LOG_TEST_RET(ctx, rv, "SM get 'VERIFY PIN' APDU: invelid PIN size"); + LOG_TEST_RET(ctx, rv, "SM get 'VERIFY PIN' APDU: invalid PIN size"); memcpy((unsigned char *)rapdu->apdu.data, pin_data->pin1.data, pin_data->pin1.len); rapdu->apdu.datalen = pin_data->pin1.len; @@ -637,7 +637,7 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru if (out && out_len) { if (out_len < offs + decrypted_len) - LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "IAS/ECC decode answer(s): unsufficient output buffer size"); + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "IAS/ECC decode answer(s): insufficient output buffer size"); memcpy(out + offs, decrypted, decrypted_len); diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index c90bf0350d..d04c245cf2 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -465,7 +465,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char memcpy(&enc_input[0],&in[5],plain_lc); for (i=0; i < 8; i++) enc_input[i+plain_lc] = des_out[i]; enc_input[plain_lc+8] = 0x80; /* iso padding */ - /* calloc already cleard the remaining bytes to 00 */ + /* calloc already cleared the remaining bytes to 00 */ if (outlen < 5 + enc_input_len) { free(mac_input); @@ -485,18 +485,18 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* xor data and IV (8 bytes 00) to get input data */ for (i=0; i < 8; i++) des_in[i] = enc_input[i] ^ 00; - /* encrypt with des2 (tripple des, but using keys A-B-A) */ + /* encrypt with des2 (triple des, but using keys A-B-A) */ DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); /* copy encrypted bytes into output */ for (i=0; i < 8; i++) out[5+i] = des_out[i]; - /* encrypt other blocks (usualy one) */ + /* encrypt other blocks (usually one) */ for (j=1; j < (enc_input_len / 8); j++) { /* xor data and prev. result to get input data */ for (i=0; i < 8; i++) des_in[i] = enc_input[i+j*8] ^ des_out[i]; - /* encrypt with des2 (tripple des, but using keys A-B-A) */ + /* encrypt with des2 (triple des, but using keys A-B-A) */ DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); /* copy encrypted bytes into output */ diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index c856a7bacb..ff60e72ead 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -171,7 +171,7 @@ int main(int argc, char* argv[]) } if ( strcmp(card->name,"dnie") ) { - fprintf(stderr, "Error: Card sems not to be a DNIe\n"); + fprintf(stderr, "Error: Card seems not to be a DNIe\n"); err=-1; goto dnie_tool_end; } @@ -211,12 +211,12 @@ int main(int argc, char* argv[]) } if (opt_operation & OP_GET_IDESP) { if (data[3]==NULL) - printf("IDESP: (No disponible)\n"); + printf("IDESP: (Not available)\n"); else printf("IDESP: %s\n",data[3]); } if (opt_operation & OP_GET_VERSION) { if (data[4]==NULL) - printf("DNIe Version: (No disponible)\n"); + printf("DNIe Version: (Not available)\n"); else printf("DNIe Version: %s\n",data[4]); } if (opt_operation & OP_GET_SERIALNR) { diff --git a/src/tools/egk-tool-cmdline.h b/src/tools/egk-tool-cmdline.h index 4b8912649f..b561e653ca 100644 --- a/src/tools/egk-tool-cmdline.h +++ b/src/tools/egk-tool-cmdline.h @@ -42,8 +42,8 @@ struct gengetopt_args_info int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ - unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ - unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurrences */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurrences */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ int pd_flag; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) (default=off). */ const char *pd_help; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) help description. */ diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 58e77e1f7a..c0e44a44de 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -88,7 +88,7 @@ static const char *option_help[] = { "Define serial number", "Unblock the user PIN after an administrator authentication", "Change the administrator key", - "Define the new adminastrator key", + "Define the new administrator key", "Uses reader number [0]", "Wait for a card to be inserted", "Verbose operation. Use several times to enable debug output.", @@ -241,7 +241,7 @@ static int unblock(sc_card_t* card, const char *so_pin, const char *user_pin) { fprintf(stderr, "reset pin failed with %s\n", sc_strerror(r)); return -1; } - printf("Unblock PIN done successfuly\n"); + printf("Unblock PIN done successfully\n"); // the card should have deauthenticated the admin, but to be sure: sc_logout(card); return 0; diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 2c52d67251..b729ee8203 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -81,7 +81,7 @@ static void show_pin(sc_card_t *card, int pin) if(f->type!=SC_FILE_TYPE_WORKING_EF || f->ef_structure!=SC_FILE_EF_LINEAR_VARIABLE_TLV || f->prop_attr_len!=5 || f->prop_attr[0]!=0x01 || f->prop_attr[1]!=0x80 ){ - printf("\nInvald PIN-file: Type=%d, EF-Structure=%d, Prop-Len=%lu %02X:%02X:%02X\n", + printf("\nInvalid PIN-file: Type=%d, EF-Structure=%d, Prop-Len=%lu %02X:%02X:%02X\n", f->type, f->ef_structure, (unsigned long) f->prop_attr_len, f->prop_attr[0], f->prop_attr[1], f->prop_attr[2] ); @@ -130,7 +130,7 @@ static void show_certs(sc_card_t *card) continue; } if(f->type!=SC_FILE_TYPE_WORKING_EF || f->ef_structure!=SC_FILE_EF_TRANSPARENT){ - printf(", Invald Cert-file: Type=%d, EF-Structure=%d\n", f->type, f->ef_structure); + printf(", Invalid Cert-file: Type=%d, EF-Structure=%d\n", f->type, f->ef_structure); continue; } if((j=sc_read_binary(card,0,buf,f->size,0))<0){ @@ -219,7 +219,7 @@ static void show_card(sc_card_t *card) if(file->type!=SC_FILE_TYPE_WORKING_EF || file->ef_structure!=SC_FILE_EF_TRANSPARENT || file->size!=12 || (len=sc_read_binary(card,0,buf,12,0))!=12 || buf[0]!=0x5A || buf[1]!=0x0A ){ - printf("\nInvald Serial-Number: Type=%d, EF-Structure=%d, Size=%lu\n", + printf("\nInvalid Serial-Number: Type=%d, EF-Structure=%d, Size=%lu\n", file->type, file->ef_structure, (unsigned long) file->size ); return; @@ -488,7 +488,7 @@ int main( fprintf(stderr,"\nstore Certificate into card at position 2 and read it back into file\n"); fprintf(stderr," %s --pin1 123456 cert /tmp/cert1 2\n", argv[0]); fprintf(stderr," %s cert 2 /tmp/cert2\n", argv[0]); - fprintf(stderr,"\nBe carful - this tool may destroy your card\n"); + fprintf(stderr,"\nBe careful - this tool may destroy your card\n"); fprintf(stderr,"\nQuestions? Comments? ==> opensc-user@opensc-project.org\n"); exit(1); } diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 7a92e148cb..a269c37bbb 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -55,7 +55,7 @@ const char *gengetopt_args_info_help[] = { " -P, --private-key=FILENAME Terminal's private key", " --cvc-dir=DIRECTORY Where to look for the CVCA's certificate\n (default=`/home/fm/.local/etc/eac/cvc')", " --x509-dir=DIRECTORY Where to look for the CSCA's certificate\n (default=`/home/fm/.local/etc/eac/x509')", - " --disable-ta-checks Disable checking the validity period of CV\n certifcates (default=off)", + " --disable-ta-checks Disable checking the validity period of CV\n certificates (default=off)", " --disable-ca-checks Disable passive authentication (default=off)", "\nRead and write data groups:", " --read-dg1 Read DG 1 (Document Type) (default=off)", @@ -2085,7 +2085,7 @@ cmdline_parser_internal ( goto failure; } - /* Disable checking the validity period of CV certifcates. */ + /* Disable checking the validity period of CV certificates. */ else if (strcmp (long_options[option_index].name, "disable-ta-checks") == 0) { diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index 4c724ead06..4db3d937e9 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -42,8 +42,8 @@ struct gengetopt_args_info int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ - unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ - unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurrences */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurrences */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ char * pin_arg; /**< @brief Run PACE with (transport) eID-PIN. */ char * pin_orig; /**< @brief Run PACE with (transport) eID-PIN original value given at command line. */ @@ -68,8 +68,8 @@ struct gengetopt_args_info const char *unblock_help; /**< @brief Unblock PIN (uses PUK to activate three more retries) help description. */ char ** cv_certificate_arg; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).. */ char ** cv_certificate_orig; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important). original value given at command line. */ - unsigned int cv_certificate_min; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s minimum occurreces */ - unsigned int cv_certificate_max; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s maximum occurreces */ + unsigned int cv_certificate_min; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s minimum occurrences */ + unsigned int cv_certificate_max; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s maximum occurrences */ const char *cv_certificate_help; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important). help description. */ char * cert_desc_arg; /**< @brief Certificate description to show for Terminal Authentication. */ char * cert_desc_orig; /**< @brief Certificate description to show for Terminal Authentication original value given at command line. */ @@ -89,8 +89,8 @@ struct gengetopt_args_info char * x509_dir_arg; /**< @brief Where to look for the CSCA's certificate (default='/home/fm/.local/etc/eac/x509'). */ char * x509_dir_orig; /**< @brief Where to look for the CSCA's certificate original value given at command line. */ const char *x509_dir_help; /**< @brief Where to look for the CSCA's certificate help description. */ - int disable_ta_checks_flag; /**< @brief Disable checking the validity period of CV certifcates (default=off). */ - const char *disable_ta_checks_help; /**< @brief Disable checking the validity period of CV certifcates help description. */ + int disable_ta_checks_flag; /**< @brief Disable checking the validity period of CV certificates (default=off). */ + const char *disable_ta_checks_help; /**< @brief Disable checking the validity period of CV certificates help description. */ int disable_ca_checks_flag; /**< @brief Disable passive authentication (default=off). */ const char *disable_ca_checks_help; /**< @brief Disable passive authentication help description. */ int read_dg1_flag; /**< @brief Read DG 1 (Document Type) (default=off). */ diff --git a/src/tools/npa-tool.1 b/src/tools/npa-tool.1 index c1a655e36d..896d5abbe8 100644 --- a/src/tools/npa-tool.1 +++ b/src/tools/npa-tool.1 @@ -86,7 +86,7 @@ Where to look for the CSCA's certificate .TP \fB\-\-disable\-ta\-checks\fR Disable checking the validity period of CV -certifcates (default=off) +certificates (default=off) .TP \fB\-\-disable\-ca\-checks\fR Disable passive authentication (default=off) diff --git a/src/tools/npa-tool.ggo.in b/src/tools/npa-tool.ggo.in index 9652c89620..11b0199ef2 100644 --- a/src/tools/npa-tool.ggo.in +++ b/src/tools/npa-tool.ggo.in @@ -89,7 +89,7 @@ option "x509-dir" - default="@X509DIR@" optional option "disable-ta-checks" - - "Disable checking the validity period of CV certifcates" + "Disable checking the validity period of CV certificates" flag off option "disable-ca-checks" - "Disable passive authentication" diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 86664d1899..0d109ed234 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -531,7 +531,7 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id) /* Send APDU to card */ r = sc_transmit_apdu(card, &apdu); if (r) { - fprintf(stderr, "Transmiting APDU failed: %s\n", sc_strerror(r)); + fprintf(stderr, "Transmitting APDU failed: %s\n", sc_strerror(r)); return r; } } diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index bc1f22dc65..66ee0c6fec 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -430,7 +430,7 @@ static int pattern_match(const char *pattern, const char *string) return 0; while (*pattern != '\0' && *string != '\0') { - /* wildcard matching multple characters */ + /* wildcard matching multiple characters */ if (*pattern == '*') { for (pattern++; *string != '\0' ; string++) if (pattern_match(pattern, string)) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index bab5fb80e0..74635c8776 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -194,7 +194,7 @@ static int load_cert(const char * cert_id, const char * cert_file, cert_file, strerror(errno)); goto err; } - if (compress) { /* file is gziped already */ + if (compress) { /* file is gzipped already */ struct stat stat_buf; if (0 != stat(cert_file, &stat_buf)) { diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8940548aec..97e00c155c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3536,7 +3536,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) bytes = getEC_POINT(sess, obj, &size); /* * (We only support uncompressed for now) - * Uncompresed EC_POINT is DER OCTET STRING of "04||x||y" + * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" * So a "256" bit key has x and y of 32 bytes each * something like: "04 41 04||x||y" * Do simple size calculation based on DER encoding @@ -5406,7 +5406,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE /* This is done in NSS */ getMODULUS(session, priv_key, &mod_len); - if (mod_len < 5 || mod_len > 10000) { /* should be resonable limits */ + if (mod_len < 5 || mod_len > 10000) { /* should be reasonable limits */ fprintf(stderr, "ERR: GetAttribute(privkey, CKA_MODULUS) doesn't seem to work\n"); return session; } @@ -5495,7 +5495,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE C_UnloadModule(module); /* Now we assume the user turns of her PC and comes back tomorrow to see - * if here cert is allready made and to install it (as is done next) */ + * if here cert is already made and to install it (as is done next) */ printf("\n*** In real life, the cert req should now be sent to the CA ***\n"); @@ -5529,7 +5529,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE if (!delete_object(session)) util_fatal("Failed to delete certificate"); - printf("\n==> OK, successfull! Should work with Mozilla\n"); + printf("\n==> OK, successful! Should work with Mozilla\n"); return session; } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 985d6b1070..069197476d 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -236,7 +236,7 @@ static const char * option_help[] = { "Store public key", "Store secret key", "Store an X.509 certificate", - "Update an X.509 certificate (carefull with mail decryption certs!!)", + "Update an X.509 certificate (careful with mail decryption certs!!)", "Store a data object", "Delete object(s) (use \"help\" for more information)", "Change attribute(s) (use \"help\" for more information)", @@ -268,7 +268,7 @@ static const char * option_help[] = { "Mark certificate as a CA certificate", "Specify X.509 key usage (use \"--key-usage help\" for more information)", "Finish initialization phase of the smart card", - "Update 'lastUpdate' attribut of tokenInfo", + "Update 'lastUpdate' attribute of tokenInfo", "When storing PKCS#12 ignore CA certificates", "Store or update existing certificate", @@ -1474,7 +1474,7 @@ static int cert_is_root(sc_pkcs15_cert_t *c) } /* Check if the cert has a 'sibling' and return it's parent cert. - * Should be made more effcicient for long chains by caching the certs. + * Should be made more efficient for long chains by caching the certs. */ static int get_cert_info(sc_pkcs15_card_t *myp15card, sc_pkcs15_object_t *certobj, int *has_sibling, int *stop, sc_pkcs15_object_t **issuercert) @@ -1531,7 +1531,7 @@ static int get_cert_info(sc_pkcs15_card_t *myp15card, sc_pkcs15_object_t *certob /* Delete object(s) by ID. The 'which' param can be any combination of * SC_PKCS15INIT_TYPE_PRKEY, SC_PKCS15INIT_TYPE_PUBKEY, SC_PKCS15INIT_TYPE_CERT * and SC_PKCS15INIT_TYPE_CHAIN. In the last case, every cert in the chain is - * deleted, starting with the cert with ID 'id' and untill a CA cert is + * deleted, starting with the cert with ID 'id' and until a CA cert is * reached that certified other remaining certs on the card. */ static int do_delete_crypto_objects(sc_pkcs15_card_t *myp15card, @@ -2556,7 +2556,7 @@ parse_objects(const char *list, unsigned int action) printf("When \"data\" is specified, an --application-id must also be specified,\n"); printf(" in the other cases an \"--id\" must also be specified\n"); printf("When \"chain\" is specified, the certificate chain starting with the cert\n"); - printf(" with specified ID will be deleted, untill there's a CA cert that certifies\n"); + printf(" with specified ID will be deleted, until there's a CA cert that certifies\n"); printf(" another cert on the card\n"); } else { diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index d246b461a5..823eb2176d 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -297,7 +297,7 @@ static int createShares(const BIGNUM *s, const unsigned char t, const unsigned c * @param shares Shares used to reconstruct secret (should contain t entries) * @param t Threshold used to reconstruct the secret * @param prime Prime for finite field arithmetic - * @param s Pointer for storage of calculated secred + * @param s Pointer for storage of calculated secret */ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGNUM *prime, BIGNUM *s) { diff --git a/src/tools/versioninfo-opensc-notify.rc.in b/src/tools/versioninfo-opensc-notify.rc.in index 3c6aa7f6b6..3b01d660b9 100644 --- a/src/tools/versioninfo-opensc-notify.rc.in +++ b/src/tools/versioninfo-opensc-notify.rc.in @@ -1,7 +1,7 @@ #include #define IDC_STATIC -1 -/* defined twice: in ressource file and in source code */ +/* defined twice: in resource file and in source code */ #define IDI_SMARTCARD 102 #ifndef __MINGW32__ diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index b016ea65e3..e90845d78e 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -477,7 +477,7 @@ int main(int argc, char *argv[]) file = sc_file_new(); if(file == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } @@ -596,7 +596,7 @@ int main(int argc, char *argv[]) if(rsa == NULL || bn == NULL || mem == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) if(mem == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } @@ -638,7 +638,7 @@ int main(int argc, char *argv[]) file = sc_file_new(); if(file == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } @@ -814,7 +814,7 @@ int main(int argc, char *argv[]) b = malloc(file->size); if(b == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } @@ -864,7 +864,7 @@ int main(int argc, char *argv[]) b = malloc(file->size); if(b == NULL) { - printf("Not enougth memory.\n"); + printf("Not enough memory.\n"); goto out; } diff --git a/src/ui/notify.c b/src/ui/notify.c index 6b9ebe1386..e08722bfe1 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -127,7 +127,7 @@ static BOOL AddNotificationIcon(void) if (basename) { basename++; if (0 != strcmp(basename, "opensc-notify.exe")) { - /* Allow creation of sytem tray icon only for + /* Allow creation of system tray icon only for * "opensc-notify.exe" to avoid creation of the same icon by * multiple processes. */ delete_icon = FALSE; diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 93d58f8f4d..573e125ea0 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -106,7 +106,7 @@ CANDLEFLAGS = -dzlib="C:\zlib-dll" $(CANDLEFLAGS) # If you want support for EAC: # - Download OpenPACE and # - uncomment the line starting with OPENPACE_DEF -# - set the OPENPACE_INCL_DIR below to the OpenPACE include directory preceeded by "/I" +# - set the OPENPACE_INCL_DIR below to the OpenPACE include directory preceded by "/I" # - set the OPENPACE_LIB below to your OpenPACE lib file #OPENPACE_DEF= /DENABLE_OPENPACE !IF "$(OPENPACE_DEF)" == "/DENABLE_OPENPACE" diff --git a/win32/versioninfo.rc.in b/win32/versioninfo.rc.in index fb34084007..23cf3ed49f 100644 --- a/win32/versioninfo.rc.in +++ b/win32/versioninfo.rc.in @@ -27,7 +27,7 @@ BEGIN VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC common usage application extention" + VALUE "FileDescription", "OpenSC common usage application extension" END END BLOCK "VarFileInfo" From 2c167a99825a3db4138acff7611801ef73f2c9cd Mon Sep 17 00:00:00 2001 From: David Ward Date: Sun, 15 Apr 2018 03:37:43 -0400 Subject: [PATCH 0229/4321] Address compiler warnings when using --disable-optimization (#1325) * Handle errors as intended in sc_pkcs15emu_openpgp_add_data() If a data object can be read, but it cannot be added to the PKCS#15 framework, return from this function with an error; do not continue reading other data objects. Otherwise, do not return an error from this function when a data object cannot be read or is empty. Improve existing comments for clarity. * Address other compiler warnings when using --disable-optimization Certain variables that are not initialized when they are declared prevent the build from completing, when --disable-optimization is passed to ./configure. --- src/libopensc/iasecc-sdo.c | 6 +++--- src/libopensc/pkcs15-openpgp.c | 13 ++++++++----- src/pkcs11/openssl.c | 2 +- src/tools/pkcs11-tool.c | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index cc6ba17348..6f824821b6 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -83,7 +83,7 @@ iasecc_sdo_convert_acl(struct sc_card *card, struct iasecc_sdo *sdo, {SC_AC_OP_READ, IASECC_ACL_GET_DATA}, {0x00, 0x00} }; - unsigned char mask = 0x80, op_mask; + unsigned char mask = 0x80, op_mask = 0; int ii; LOG_FUNC_CALLED(ctx); @@ -94,10 +94,10 @@ iasecc_sdo_convert_acl(struct sc_card *card, struct iasecc_sdo *sdo, break; } } - if (ops[ii].mask == 0) + if (op_mask == 0) LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - sc_log(ctx, "OP:%i, mask:0x%X", op, ops[ii].mask); + sc_log(ctx, "OP:%i, mask:0x%X", op, op_mask); sc_log(ctx, "AMB:%X, scbs:%s", sdo->docp.amb, sc_dump_hex(sdo->docp.scbs, IASECC_MAX_SCBS)); sc_log(ctx, "docp.acls_contact:%s", sc_dump_hex(sdo->docp.acls_contact.value, sdo->docp.acls_contact.size)); diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index e68b65344c..f4e4378ceb 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -371,7 +371,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) goto failed; } - /* PKCS#15 DATA object from OpenPGP private DOs */ + /* Add PKCS#15 DATA objects from other OpenPGP card DOs. The return + * value is ignored, so this will not cause initialization to fail. + */ sc_pkcs15emu_openpgp_add_data(p15card); failed: @@ -392,7 +394,7 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) int i, r; LOG_FUNC_CALLED(ctx); - /* There is 4 private DO from 0101 to 0104 */ + /* Optional private use DOs 0101 to 0104 */ for (i = 1; i <= PGP_NUM_PRIVDO; i++) { sc_pkcs15_data_info_t dat_info; sc_pkcs15_object_t dat_obj; @@ -405,8 +407,8 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) snprintf(name, 8, "PrivDO%d", i); snprintf(path, 9, "3F00010%d", i); - /* Check if the DO can be read. - * We won't expose pkcs15 DATA object if DO is empty. + /* Check if the DO can be read and is not empty. Otherwise we + * won't expose a PKCS#15 DATA object. */ r = read_file(p15card->card, path, content, sizeof(content)); if (r <= 0 ) { @@ -428,8 +430,9 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) sc_log(ctx, "Add %s data object", name); r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info); + LOG_TEST_RET(ctx, r, "Could not add data object to framework"); } - LOG_FUNC_RETURN(ctx, r); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } static int openpgp_detect_card(sc_pkcs15_card_t *p15card) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 50b9b0a614..ec4c4851d8 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -329,7 +329,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, EVP_PKEY_CTX *pkey_ctx = NULL; EC_POINT *P; BIGNUM *X, *Y; - ASN1_OCTET_STRING *octet; + ASN1_OCTET_STRING *octet = NULL; const EC_GROUP *group = NULL; char paramset[2] = "A"; int r = -1, ret_vrf = 0; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 97e00c155c..d97683bcaa 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3234,7 +3234,7 @@ find_mechanism(CK_SLOT_ID slot, CK_FLAGS flags, count = get_mechanisms(slot, &mechs, flags); if (count) { if (list && list_len) { - unsigned ii, jj; + unsigned ii = list_len, jj; for (jj=0; jj Date: Thu, 19 Apr 2018 15:59:15 +0200 Subject: [PATCH 0230/4321] AppVeyor: let configure know that we're building with native tools --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index de49e2fa9e..d351662aed 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -87,7 +87,7 @@ build_script: } - bash -c "exec 0 Date: Sun, 22 Apr 2018 15:08:12 +0200 Subject: [PATCH 0231/4321] openpgp: don't treat OpenPGP v3 cards special in src/libopensc/pkcs15-syn.c As OpenPGP v3 cards are backward compatible with earlier versions, fix an inconsitency in src/libopensc/pkcs15-syn.c --- src/libopensc/pkcs15-syn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 1899070a55..30fd0ff84f 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -82,6 +82,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_OPENPGP_V1: case SC_CARD_TYPE_OPENPGP_V2: case SC_CARD_TYPE_OPENPGP_GNUK: + case SC_CARD_TYPE_OPENPGP_V3: case SC_CARD_TYPE_SC_HSM: case SC_CARD_TYPE_SC_HSM_SOC: case SC_CARD_TYPE_DNIE_BASE: From eb0f4e1850a7bd76f7199fdd449118c40a8cd71e Mon Sep 17 00:00:00 2001 From: David Ward Date: Sat, 14 Apr 2018 21:33:14 -0400 Subject: [PATCH 0232/4321] Slightly adjust pull request template During a pull request, it might not be possible for all components (such as the PKCS#11 module, Windows minidriver, or macOS tokend) to be tested by the same person using the same card; not everyone has access to all of the platforms supported by OpenSC. When there are no card-specific changes, each component might be tested by a different person using a different type of card. The pull request template contains a checklist with each component that needs to be tested (which can be adapted as needed). However, this checklist also includes an item for the type of card used for testing. This should certainly be included in the message, but it doesn't quite seem to belong in the checklist as a separate item, particularly when considering the multiple-card testing situation described above. It seems that the checklist is intended to track specific tasks that still need to be completed. This change slightly adjusts the template in order to handle this. (It is still just a template, and it can be adapted for each pull request as needed.) --- .github/PULL_REQUEST_TEMPLATE.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5bb125c986..e6f6596dc2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,14 +1,17 @@ ##### Checklist - [ ] Documentation is added or updated - [ ] New files have a LGPL 2.1 license statement -- [ ] Tested with the following card: - - [ ] tested PKCS#11 - - [ ] tested Windows Minidriver - - [ ] tested macOS Tokend +- [ ] PKCS#11 module is tested +- [ ] Windows minidriver is tested +- [ ] macOS tokend is tested From fff4ca901dd3a7a945702d431038a800945c1508 Mon Sep 17 00:00:00 2001 From: David Ward Date: Fri, 30 Mar 2018 19:52:20 -0400 Subject: [PATCH 0233/4321] Provide more space for card holder name in CAC token label The PKCS#15 emulation layer for the CAC uses a single PIN. Set its label to "PIN" (rather than the card type "CAC I" or "CAC II"), so that the PIN label will be omitted from the token label, providing more space for the card holder name instead. This is intended to match the behavior used for PIV cards, which was changed with commit 56c8f59b25c222cfe2b57dcf78c8bbc26eb595df. --- src/libopensc/pkcs15-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index ff87a2345c..80e7b90e0f 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -173,7 +173,7 @@ cac_map_usage(unsigned int cert_usage, int algorithm, unsigned int *pub_usage_pt static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) { static const pindata pins[] = { - { "1", NULL, "", 0x00, + { "1", "PIN", "", 0x00, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 8, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | @@ -245,7 +245,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_format_path(pins[i].path, &pin_info.path); pin_info.tries_left = -1; - label = pins[i].label? pins[i].label : cac_get_name(card->type); + label = pins[i].label; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; From bddef2485f4ed38d083687b2258d9a9f07caca88 Mon Sep 17 00:00:00 2001 From: David Ward Date: Tue, 24 Apr 2018 17:05:43 -0400 Subject: [PATCH 0234/4321] macOS: Remove unused build code for the CryptoTokenKit app extension OpenSCToken (https://github.com/frankmorgner/OpenSCToken) is now a standalone package that provides the CryptoTokenKit app extension. It includes its own 'build-package' script, which handles building the OpenSC library and statically linking against it. The 'MacOSX/' directory in OpenSC itself is only used to build the macOS tokend. Remove unused code for building a CryptoTokenKit app extension from this directory (which no longer works). This should help to avoid confusion when building OpenSC for macOS. --- MacOSX/build-package.in | 72 +++++++++++++------------------------- MacOSX/opensc-uninstall | 5 --- MacOSX/opensc.entitlements | 8 ----- MacOSX/scripts/postinstall | 4 --- 4 files changed, 24 insertions(+), 65 deletions(-) delete mode 100644 MacOSX/opensc.entitlements diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 137aa9071b..8187a45d7a 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -6,16 +6,7 @@ # You need to have the following from homebrew or macports or fink: # autoconf automake libtool pkg-config -# If you want to compile with OpenSCToken/CryptoTokenKit set the following: -#ENABLE_CRYPTOTOKENKIT="--disable-pcsc --enable-cryptotokenkit" -# When using CryptoTokenKit, code signing is required -#SIGNING_IDENTITY=BA3CE53D402E3C75246557E2890F929F4A778DDE - -if test -z "$ENABLE_CRYPTOTOKENKIT"; then - export MACOSX_DEPLOYMENT_TARGET="10.10" -else - export MACOSX_DEPLOYMENT_TARGET="10.12" -fi +export MACOSX_DEPLOYMENT_TARGET="10.10" set -ex test -x ./configure || ./bootstrap @@ -69,7 +60,6 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then --sysconfdir=$PREFIX/etc \ --enable-cvcdir=$PREFIX/etc/cvc \ --enable-x509dir=$PREFIX/etc/x509 \ - $ENABLE_CRYPTOTOKENKIT \ --disable-notify \ --disable-dependency-tracking \ --enable-shared \ @@ -96,48 +86,34 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then ./MacOSX/libtool-bundle ${BUILDPATH}/target/$PREFIX/lib/opensc-pkcs11.so ${BUILDPATH}/target/$PREFIX/lib fi -if test -z "$ENABLE_CRYPTOTOKENKIT"; then - # Check out OpenSC.tokend, if not already fetched. - if ! test -e OpenSC.tokend; then - git clone http://github.com/OpenSC/OpenSC.tokend.git - fi +# Check out OpenSC.tokend, if not already fetched. +if ! test -e OpenSC.tokend; then + git clone http://github.com/OpenSC/OpenSC.tokend.git +fi - # Create the symlink to OpenSC sources - test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src - - # Build and copy OpenSC.tokend - xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target - - #if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then - #if ! test -e terminal-notifier-1.7.1.zip; then - #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip - #fi - #if ! test -e terminal-notifier-1.7.1; then - #unzip terminal-notifier-1.7.1.zip - #fi - #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications - #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications - #fi +# Create the symlink to OpenSC sources +test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src - if ! test -e NotificationProxy; then - git clone http://github.com/frankmorgner/NotificationProxy.git - fi - xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ - mkdir -p "$BUILDPATH/target/Applications" - osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" -else - # Check out OpenSCToken, if not already fetched. - if ! test -e OpenSCToken; then - git clone http://github.com/frankmorgner/OpenSCToken.git - fi +# Build and copy OpenSC.tokend +xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target - # Build and copy OpenSCTokenApp - xcodebuild -target OpenSCTokenApp -configuration Release -project OpenSCToken/OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target +#if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then + #if ! test -e terminal-notifier-1.7.1.zip; then + #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip + #fi + #if ! test -e terminal-notifier-1.7.1; then + #unzip terminal-notifier-1.7.1.zip + #fi + #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications + #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications +#fi - codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements target/Library/OpenSC/bin/* - codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements target/Library/OpenSC/lib/*.dylib - codesign --sign "$SIGNING_IDENTITY" --force --entitlements MacOSX/opensc.entitlements --deep target/Library/OpenSC/lib/opensc-pkcs11.bundle +if ! test -e NotificationProxy; then + git clone http://github.com/frankmorgner/NotificationProxy.git fi +xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ +mkdir -p "$BUILDPATH/target/Applications" +osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" imagedir=$(mktemp -d) diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index 1a71161a49..d4331a9ad9 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -21,11 +21,6 @@ rm -rf /Library/OpenSC rm -rf /Library/Security/tokend/OpenSC.tokend rm -rf /System/Library/Security/tokend/OpenSC.tokend -if [ -e "/Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex" ] -then - pluginkit -r /Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex -fi - # delete receipts on 10.6+ for file in /var/db/receipts/org.opensc-project.mac.bom /var/db/receipts/org.opensc-project.mac.plist; do test -f $file && rm -f $file diff --git a/MacOSX/opensc.entitlements b/MacOSX/opensc.entitlements deleted file mode 100644 index 0eecdb30ae..0000000000 --- a/MacOSX/opensc.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.smartcard - - - diff --git a/MacOSX/scripts/postinstall b/MacOSX/scripts/postinstall index 27ba2a4b36..fed5aa8649 100755 --- a/MacOSX/scripts/postinstall +++ b/MacOSX/scripts/postinstall @@ -19,8 +19,4 @@ for f in /Library/OpenSC/bin/* do ln -sf $f /usr/local/bin done -if [ -e "/Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex" ] -then - pluginkit -a /Library/OpenSC/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex -fi exit 0 From 841e13c9c1fc5e39838be85afb766c97fa1c937d Mon Sep 17 00:00:00 2001 From: David Ward Date: Tue, 24 Apr 2018 20:50:29 -0400 Subject: [PATCH 0235/4321] macOS: Update description at top of MacOSX/build-package script Explicitly mention that this script builds the tokend and command line tools (as it does not build the CryptoTokenKit app extension). Add two missing packages in the list of build dependencies. --- MacOSX/build-package.in | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 8187a45d7a..22e8e8868d 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -1,10 +1,11 @@ #!/bin/bash -# Building the installer is only tested and supported on 10.9+ with Xcode 6.0.1 -# Built package targets 10.10 -# Building should also work on older versions with older revisions or slight changes, YMMV +# Build the macOS installer for the tokend and command line tools. +# +# This is only tested and supported on macOS 10.10 or later, using Xcode 6.0.1. +# Building should also work on older macOS versions with slight changes; YMMV. -# You need to have the following from homebrew or macports or fink: -# autoconf automake libtool pkg-config +# You need to install the following packages from homebrew or macports or fink: +# autoconf automake libtool pkg-config help2man gengetopt export MACOSX_DEPLOYMENT_TARGET="10.10" From 58a824527b82d0b43eb4cc56d2f7b17c5242be14 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 16 Apr 2018 14:15:08 +0200 Subject: [PATCH 0236/4321] sc-hsm: fixed default labels for GoID --- src/libopensc/pkcs15-sc-hsm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 5fbc910945..305572cb6c 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -855,7 +855,12 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) sc_pkcs15emu_sc_hsm_read_tokeninfo(p15card); if (p15card->tokeninfo->label == NULL) { - p15card->tokeninfo->label = strdup("SmartCard-HSM"); + if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID + || p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) { + p15card->tokeninfo->label = strdup("GoID"); + } else { + p15card->tokeninfo->label = strdup("SmartCard-HSM"); + } if (p15card->tokeninfo->label == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } @@ -866,7 +871,12 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) } if (p15card->tokeninfo->manufacturer_id == NULL) { - p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de"); + if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID + || p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) { + p15card->tokeninfo->manufacturer_id = strdup("Bundesdruckerei GmbH"); + } else { + p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de"); + } if (p15card->tokeninfo->manufacturer_id == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } From dd1a606d0d3e5c4dce541f45d56e4cee644ac3a3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Apr 2018 23:29:06 +0200 Subject: [PATCH 0237/4321] updated tools.xml for inclusion in wiki --- doc/tools/tools.html | 1910 ++++++++++++++++++++++++++++++++++++++++++ doc/tools/tools.xml | 13 +- 2 files changed, 1919 insertions(+), 4 deletions(-) create mode 100644 doc/tools/tools.html diff --git a/doc/tools/tools.html b/doc/tools/tools.html new file mode 100644 index 0000000000..2bcfba6d32 --- /dev/null +++ b/doc/tools/tools.html @@ -0,0 +1,1910 @@ +OpenSC Manuals

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them +
cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
dnie-tool — displays information about DNIe based security tokens
eidenv — utility for accessing visible data from + electronic identity cards
gids-tool — smart card utility for GIDS cards
netkey-tool — administrative utility for Netkey E4 cards
iasecc-tool — displays information about IAS/ECC card +
openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens
netkey-tool — administrative utility for Netkey E4 cards
openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens
opensc-tool — generic smart card utility
opensc-explorer — + generic interactive utility for accessing smart card + and similar security token functions +
piv-tool — smart card utility for HSPD-12 PIV cards
pkcs11-tool — utility for managing and using PKCS #11 security tokens
pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
pkcs15-init — smart card personalization utility
pkcs15-tool — utility for manipulating PKCS #15 data structures + on smart cards and similar security tokens
sc-hsm-tool — smart card utility for SmartCard-HSM
westcos-tool — utility for manipulating data structures + on westcos smart cards

Name

cardos-tool — displays information about Card OS-based security tokens or format them +

Synopsis

cardos-tool [OPTIONS]

Description

+ The cardos-tool utility is used to display information about +smart cards and similar security tokens based on Siemens Card/OS M4. +

Options

+

+ --card-driver name, + -c name

Use the card driver specified by name. + The default is to auto-detect the correct card driver.

+ --format, + -f +

Format the card or token.

+ --info, + -i +

Display information about the card or token.

+ --reader number, + -r number +

Specify the reader number number to use. + The default is reader 0.

+ --verbose, + -v +

Causes cardos-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc library.

+ --wait, + -w +

Causes cardos-tool to wait for the token + to be inserted into reader.

+


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

+ cryptoflex-tool is used to manipulate PKCS + data structures on Schlumberger Cryptoflex smart cards. Users + can create, list and read PINs and keys stored on the smart card. + User PIN authentication is performed for those operations that require it. +

Options

+

+ --app-df num, + -a num +

Specifies the DF to operate in

+ --create-key-files arg, + -c arg +

Creates new RSA key files for arg keys

+ --create-pin-files id, + -P id +

Creates new PIN file for CHVid

+ --exponent exp, + -e exp +

Specifies the RSA exponent, exp, + to use in key generation. The default value is 3.

+ --generate-key, + -g +

Generate a new RSA key pair

+ --key-num num, + -k num +

Specifies the key number to operate on. The default is + key number 1.

+ --list-keys, + -l +

Lists all keys stored in a public key file

+ --modulus-length length, + -m length +

Specifies the modulus length to use + in key generation. The default value is 1024.

+ --prkey-file id, + -p id +

Specifies the private key file id, id, + to use

+ --pubkey-file id, + -u id +

Specifies the public key file id, id, + to use

+ --read-key +

Reads a public key from the card, allowing the user to + extract and store or use the public key +

+ --reader num, + -r num +

Forces cryptoflex-tool to use + reader number num for operations. The default + is to use reader number 0, the first reader in the system.

+ --verbose, + -v +

Causes cryptoflex-tool to be more + verbose. Specify this flag several times to enable debug output in + the opensc library.

+ --verify-pin, + -V +

Verifies CHV1 before issuing commands

+

See also

+ pkcs15-tool(1) +


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

+ The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card. +

Options

+

+ --idesp, + -i +

Show the DNIe IDESP value.

+ --data, + -d +

Show DNIe personal information. + Reads and print DNIe number and User Name and SurName

+ --all, + -a +

Displays every available information. + This command is equivalent to -d -i -s

+ --serial, + -s +

Displays DNIe Serial Number +

+ --version, + -V +

Show DNIe sw version. + Displays software version for in-card DNIe OS

+ --pin pin, + -p pin +

Specify the user pin pin to use. + If set to env:VARIABLE, the + value of the environment variable + VARIABLE is used. + The default is do not enter pin

+ --reader number, + -r number +

Specify the reader number to use. + The default is reader 0.

+ --driver driver, + -c driver +

Specify the card driver driver to use. + Default is use driver from configuration file, or auto-detect if absent

+ --wait, + -w +

Causes dnie-tool to wait for the token to be inserted into reader.

+ --verbose, + -v +

Causes dnie-tool to be more verbose. + Specify this flag several times +to enable debug output in the opensc library.

+

See also

opensc(7)

Authors

dnie-tool was written by + Juan Antonio Martinez .


Name

eidenv — utility for accessing visible data from + electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

+ The eidenv utility is used for + accessing data from electronic identity cards (like + national eID cards) which might not be present in + PKCS#15 objects but available in custom files on the + card. The data can be printed on screen or used by + other programs via environment variables. +

Options

+

+ --exec prog, + -x prog +

Executes the given program with + data in environment variables.

+ --help, + -h +

Print help message on screen.

+ --print, + -p +

Prints all data + fields from the card, like validity + period, document number etc.

+ --reader num, + -r num +

+ Use the given reader. The default is the first reader with a card. +

+ --stats, + -t +

Prints key usage statistics + (only for Estonian ID card).

+ --version, + -v +

Prints the version + of the utility and exits.

+ --wait, + -w +

Wait for a card to be inserted

+

Authors

eidenv utility was written by + Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

+ The gids-tool utility can be used from the command line to perform + miscellaneous smart card operations on a GIDS smart card. +

Options

+

+ -X, + --initialize +

Initialize token.

+ --admin-key argument +

Define the administrator key

+ --pin argument +

Define user PIN.

+ --serial-number argument +

Define serial number.

+ -U, + --unblock +

Unblock the user PIN after an administrator + authentication.

+ -C, + --change-admin-key +

Change the administrator key.

+ --new-admin-key argument +

Define the new administrator key.

+ --reader argument, + -r argument +

Uses reader number + argument.

+ -w, + --wait +

Wait for a card to be inserted.

+ -v, + --verbose +

Verbose operation. Use several times to + enable debug output.

+

See also

+ opensc-tool(1) +


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the + command line to perform some smart card operations with NetKey E4 cards + that cannot be done easily with other OpenSC-tools, such as changing local + PINs, storing certificates into empty NetKey E4 cert-files or displaying + the initial PUK-value.

Options

+

+ --help, + -h +

Displays a short help message.

+ --pin pin-value, + -p pin-value +

Specifies the current value of the global PIN.

+ --puk pin-value, + -u pin-value +

Specifies the current value of the global PUK.

+ --pin0 pin-value, + -0 pin-value +

Specifies the current value of the local PIN0 (aka local PIN).

+ --pin1 pin-value, + -1 pin-value +

Specifies the current value of the local PIN1 (aka local PUK).

+ --reader number, + -r number +

Use smart card in specified reader. Default is reader 0.

+ -v +

Causes netkey-tool to be more verbose. This + options may be specified multiple times to increase verbosity.

+

PIN format

With the -p, -u, -0 or the -1 + one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string + (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. + Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + display information about the smart cards pins and certificates. This will not change + your card in any aspect (assumed there are no bugs in netkey-tool). + In particular the tries-left counters of the pins are investigated without doing + actual pin-verifications.

If you specify the global PIN via the --pin option, + netkey-tool will also display the initial value of the cards + global PUK. If your global PUK was changed netkey-tool will still + display its initial value. There's no way to recover a lost global PUK once it was changed. + There's also no way to display the initial value of your global PUK without knowing the + current value of your global PIN.

For most of the commands that netkey-tool can execute, you have + to specify one pin. One notable exception is the nullpin command, but + this command can only be executed once in the lifetime of a NetKey E4 card.

+

+ cert number filename +

This command will read one of your cards certificates (as specified by + number) and save this certificate into file filename + in PEM-format. Certificates on a NetKey E4 card are readable without a pin, so you don't + have to specify one.

+ cert filename number +

This command will read the first PEM-encoded certificate from file + filename and store this into your smart cards certificate file + number. Some of your smart cards certificate files might be readonly, so + this will not work with all values of number. If a certificate file is + writable you must specify a pin in order to change it. If you try to use this command + without specifying a pin, netkey-tool will tell you which one is + needed.

+ change { pin | puk | + pin0 | pin1 } new-pin +

This changes the value of the specified pin to the given new value. + You must specify either the current value of the pin or another pin to be able to do + this and if you don't specify a correct one, netkey-tool will tell + you which one is needed.

+ nullpin initial-pin +

This command can be executed only if the global PIN of your card is + in nullpin-state. There's no way to return back to nullpin-state once you have changed + your global PIN. You don't need a pin to execute the nullpin-command. After a successful + nullpin-command netkey-tool will display your cards initial + PUK-value.

+ unblock { pin | pin0 | pin1 } +

This unblocks the specified pin. You must specify another pin + to be able to do this and if you don't specify a correct one, + netkey-tool will tell you which one is needed.

+

See also

+ opensc-explorer(1) +

Authors

netkey-tool was written by + Peter Koch .


Name

iasecc-tool — displays information about IAS/ECC card +

Synopsis

iasecc-tool [OPTIONS]

Description

+ The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards. +

Options

+

+ --reader number, +

Specify the reader number number to use. + The default is reader 0.

+ --list-applications, +

Get list of the on-card applications.

+ --aid hex-aid, +

Select hex-aid before processing.

+ --list-sdos sdo-type, +

List SDOs of the given sdo-type, + present in default or selected application.

+ --verbose, + -v +

Causes cardos-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc library.

+ --wait, + -w +

Causes iasecc-tool to wait for the token + to be inserted into reader.

+


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+ The openpgp-tool utility is used for + accessing data from the OpenPGP v1.1 and v2.0 smart cards + and compatible tokens like e.g. GPF CryptoStick v1.x, + which might not be present in + PKCS#15 objects but available in custom files on the + card. The data can be printed on screen or used by + other programs via environment variables. +

Options

+

+ --exec prog, + -x prog +

+ Execute the given program with data in environment variables. +

+ --help, + -h +

+ Print help message on screen. +

+ --raw +

+ Print values in raw format, as they are stored on the card. +

+ --pretty +

+ Print values in pretty format. +

+ --user-info, + -U +

+ Show card holder information. +

+ --reader num, + -r num +

+ Use the given reader. The default is the first reader with a card. +

+ --verify pintype +

+ Verify PIN (CHV1, CHV2 or CHV3). +

+ --pin string +

+ The PIN text to verify. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used. +

+ --gen-key ID, + -G ID +

+ Generate key. Specify key ID (1, 2 or 3) to generate. +

+ --key-length bitlength, + -L bitlength +

+ Length (default 2048 bit) of the key to be generated. +

+ --version, + -V +

+ Print the version of the utility and exit. +

+ --verbose, + -v +

+ Verbose operation. Use several times to enable debug output. +

+ --wait, + -w +

+ Wait for a card to be inserted. +

+

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the + command line to perform some smart card operations with NetKey E4 cards + that cannot be done easily with other OpenSC-tools, such as changing local + PINs, storing certificates into empty NetKey E4 cert-files or displaying + the initial PUK-value.

Options

+

+ --help, + -h +

Displays a short help message.

+ --pin pin-value, + -p pin-value +

Specifies the current value of the global PIN.

+ --puk pin-value, + -u pin-value +

Specifies the current value of the global PUK.

+ --pin0 pin-value, + -0 pin-value +

Specifies the current value of the local PIN0 (aka local PIN).

+ --pin1 pin-value, + -1 pin-value +

Specifies the current value of the local PIN1 (aka local PUK).

+ --reader number, + -r number +

Use smart card in specified reader. Default is reader 0.

+ -v +

Causes netkey-tool to be more verbose. This + options may be specified multiple times to increase verbosity.

+

PIN format

With the -p, -u, -0 or the -1 + one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string + (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. + Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + display information about the smart cards pins and certificates. This will not change + your card in any aspect (assumed there are no bugs in netkey-tool). + In particular the tries-left counters of the pins are investigated without doing + actual pin-verifications.

If you specify the global PIN via the --pin option, + netkey-tool will also display the initial value of the cards + global PUK. If your global PUK was changed netkey-tool will still + display its initial value. There's no way to recover a lost global PUK once it was changed. + There's also no way to display the initial value of your global PUK without knowing the + current value of your global PIN.

For most of the commands that netkey-tool can execute, you have + to specify one pin. One notable exception is the nullpin command, but + this command can only be executed once in the lifetime of a NetKey E4 card.

+

+ cert number filename +

This command will read one of your cards certificates (as specified by + number) and save this certificate into file filename + in PEM-format. Certificates on a NetKey E4 card are readable without a pin, so you don't + have to specify one.

+ cert filename number +

This command will read the first PEM-encoded certificate from file + filename and store this into your smart cards certificate file + number. Some of your smart cards certificate files might be readonly, so + this will not work with all values of number. If a certificate file is + writable you must specify a pin in order to change it. If you try to use this command + without specifying a pin, netkey-tool will tell you which one is + needed.

+ change { pin | puk | + pin0 | pin1 } new-pin +

This changes the value of the specified pin to the given new value. + You must specify either the current value of the pin or another pin to be able to do + this and if you don't specify a correct one, netkey-tool will tell + you which one is needed.

+ nullpin initial-pin +

This command can be executed only if the global PIN of your card is + in nullpin-state. There's no way to return back to nullpin-state once you have changed + your global PIN. You don't need a pin to execute the nullpin-command. After a successful + nullpin-command netkey-tool will display your cards initial + PUK-value.

+ unblock { pin | pin0 | pin1 } +

This unblocks the specified pin. You must specify another pin + to be able to do this and if you don't specify a correct one, + netkey-tool will tell you which one is needed.

+

See also

+ opensc-explorer(1) +

Authors

netkey-tool was written by + Peter Koch .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+ The openpgp-tool utility is used for + accessing data from the OpenPGP v1.1 and v2.0 smart cards + and compatible tokens like e.g. GPF CryptoStick v1.x, + which might not be present in + PKCS#15 objects but available in custom files on the + card. The data can be printed on screen or used by + other programs via environment variables. +

Options

+

+ --exec prog, + -x prog +

+ Execute the given program with data in environment variables. +

+ --help, + -h +

+ Print help message on screen. +

+ --raw +

+ Print values in raw format, as they are stored on the card. +

+ --pretty +

+ Print values in pretty format. +

+ --user-info, + -U +

+ Show card holder information. +

+ --reader num, + -r num +

+ Use the given reader. The default is the first reader with a card. +

+ --verify pintype +

+ Verify PIN (CHV1, CHV2 or CHV3). +

+ --pin string +

+ The PIN text to verify. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used. +

+ --gen-key ID, + -G ID +

+ Generate key. Specify key ID (1, 2 or 3) to generate. +

+ --key-length bitlength, + -L bitlength +

+ Length (default 2048 bit) of the key to be generated. +

+ --version, + -V +

+ Print the version of the utility and exit. +

+ --verbose, + -v +

+ Verbose operation. Use several times to enable debug output. +

+ --wait, + -w +

+ Wait for a card to be inserted. +

+

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

+ The opensc-tool utility can be used from the command line to perform + miscellaneous smart card operations such as getting the card ATR or + sending arbitrary APDU commands to a card. +

Options

+

+ --version, +

Print the OpenSC package release version.

+ --atr, + -a +

Print the Answer To Reset (ATR) of the card. + Output is in hex byte format

+ --card-driver driver, + -c driver +

Use the given card driver. + The default is auto-detected.

+ --info, + -i +

Print information about OpenSC, such as version and enabled components.

+ --list-drivers, + -D +

List all installed card drivers.

+ --list-files, + -f +

Recursively list all files stored on card.

+ --list-readers, + -l +

List all configured readers.

+ --name, + -n +

Print the name of the inserted card (driver).

+ --reader num, + -r num +

Use the given reader number. + The default is 0, the first reader in the system.

+ --reset[=type], +

Resets the card in reader. + The default reset type is cold, but warm reset is also possible.

+ --send-apdu apdu, + -s apdu +

Sends an arbitrary APDU to the card in the format + AA:BB:CC:DD:EE:FF....

+ --serial +

Print the card serial number (normally the ICCSN). + Output is in hex byte format

+ --verbose, + -v +

Causes opensc-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc library.

+ --wait, + -w +

Wait for a card to be inserted.

+

See also

+ opensc-explorer(1) +


Name

opensc-explorer — + generic interactive utility for accessing smart card + and similar security token functions +

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

+ The opensc-explorer utility can be + used interactively to perform miscellaneous operations + such as exploring the contents of or sending arbitrary + APDU commands to a smart card or similar security token. +

Options

+ The following are the command-line options for + opensc-explorer. There are additional + interactive commands available once it is running. +

+ --card-driver driver, + -c driver +

+ Use the given card driver. The default is + auto-detected. +

+ --mf path, + -m path +

+ Select the file referenced by the given path on + startup. The default is the path to the standard master file, + 3F00. If path is empty (e.g. opensc-explorer + --mf ""), then no file is explicitly selected. +

+ --reader num, + -r num +

+ Use the given reader number. The default + is 0, the first reader in the system. +

+ --verbose, -v +

+ Causes opensc-explorer to be more + verbose. Specify this flag several times to enable + debug output in the opensc library. +

+ --wait, -w +

Wait for a card to be inserted

+

Commands

+ The following commands are supported at opensc-explorer's + interactive prompt or in script files passed via the command line parameter + SCRIPT. +

+ apdu hex-data +

Send a custom APDU command hex-data.

+ asn1 file-id +

Parse and print the ASN.1 encoded content of the file specified by + file-id.

+ cat [file-id | sfi:short-id] +

Print the contents of the currently selected EF or the contents + of a file specified by file-id or the short file id + short-id. +

+ cd {.. | file-id | aid:DF-name} +

+ Change to another DF specified by the argument passed. + If the argument given is .., then move up one level in the + file system hierarchy. + If it is file-id, which must be a DF directly + beneath the current DF, then change to that DF. + If it is an application identifier given as + aid:DF-name, + then jump to the MF of the application denoted by + DF-name. +

+ change CHVpin-ref [[old-pin] new-pin] +

Change a PIN, where pin-ref is the PIN reference.

+ Examples: +

change CHV2 00:00:00:00:00:00 "foobar"

+ Change PIN CHV2 + to the new value foobar, + giving the old value 00:00:00:00:00:00. +

change CHV2 "foobar"

+ Set PIN CHV2 + to the new value foobar. +

change CHV2

+ Change PIN CHV2 using the card reader's pinpad. +

+

+ create file-id size +

Create a new EF. file-id specifies the + id number and size is the size of the new file. +

+ debug [level] +

Set OpenSC debug level to level.

If level is omitted the current debug level will be shown.

+ delete file-id +

Remove the EF or DF specified by file-id

+ do_get hex-tag [output] +

Copy the internal card's 'tagged' data into the local file.

The local file is specified by output while the tag of + the card's data is specified by hex-tag. +

+ If output is omitted, the name of the output file will be + derived from hex-tag. +

+ do_put hex-tag input +

Update internal card's 'tagged' data.

hex-tag is the tag of the card's data. + input is the filename of the source file or the literal data presented as + a sequence of hexadecimal values or " enclosed string. +

+ echo string ... +

Print the strings given.

+ erase +

Erase the card, if the card supports it.

+ get file-id [output] +

Copy an EF to a local file. The local file is specified + by output while the card file is specified by file-id. +

+ If output is omitted, the name of the output file will be + derived from the full card path to file-id. +

+ info [file-id] +

Display attributes of a file specified by file-id. + If file-id is not supplied, + the attributes of the current file are printed.

+ ls [pattern ...] +

List files in the current DF. + If no pattern is given, then all files are listed. + If one ore more patterns are given, only files matching + at least one pattern are listed.

+ find [start-id [end-id]] +

Find all files in the current DF. + Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF).

+ find_tags [start-tag [end-tag]] +

Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF).

+ mkdir file-id size +

Create a DF. file-id specifies the id number + and size is the size of the new file.

+ put file-id input +

Copy a local file to the card. The local file is specified + by input while the card file is specified by file-id. +

+ quit +

Exit the program.

+ random count +

Generate random sequence of count bytes.

+ rm file-id +

Remove the EF or DF specified by file-id

+ unblock CHVpin-ref [puk [new pin]] +

+ Unblock the PIN denoted by pin-ref + using the PUK puk, and set potentially + change its value to new pin. +

+ PUK and PIN values can be a sequence of hexadecimal values, + "-enclosed strings, empty (""), + or absent. + If they are absent, the values are read from the card reader's pin pad. +

+ Examples: +

unblock CHV2 00:00:00:00:00:00 "foobar"

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 + and set it to the new value foobar. +

unblock CHV2 00:00:00:00:00:00 ""

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 keeping the old value. +

unblock CHV2 "" "foobar"

+ Set new value of PIN CHV2 + to foobar. +

unblock CHV2 00:00:00:00:00:00

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00. + The new PIN value is prompted by pinpad. +

unblock CHV2 ""

+ Set PIN CHV2. + The new PIN value is prompted by pinpad. +

unblock CHV2

+ Unblock PIN CHV2. + The unblock code and new PIN value are prompted by pinpad. +

+

+ update_binary file-id offs data +

Binary update of the file specified by + file-id with the literal data + data starting from offset specified + by offs.

data can be supplied as a sequencer + of the hex values or as a " enclosed string.

+ update_record file-id rec-nr rec-offs data +

Update record specified by rec-nr of the file + specified by file-id with the literal data + data starting from offset specified by + rec-offs.

data can be supplied as a sequence of the hex values or + as a " enclosed string.

+ verify key-type key-id [key] +

Present a PIN or key to the card, where + key-type can be one of CHV, + KEY, AUT or PRO. + key-id is a number representing the key or PIN reference. + key is the key or PIN to be verified, formatted as a + colon-separated list of hex values or a " enclosed string. +

+ If key is omitted, the exact action depends on the + card reader's features: if the card readers supports PIN input via a pin pad, + then the PIN will be verified using the card reader's pin pad. + If the card reader does not support PIN input, then the PIN will be asked + interactively. +

+ Examples: +

verify CHV0 31:32:33:34:00:00:00:00

+ Verify CHV2 using the hex value + 31:32:33:34:00:00:00:00 +

verify CHV1 "secret"

+ Verify CHV1 + using the string value secret. +

verify KEY2

+ Verify KEY2, + get the value from the card reader's pin pad. +

+

+ sm [open]|[close] +

Calls the card's open or close Secure Messaging handler.

+

See also

+ opensc-tool(1) +


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

+ The piv-tool utility can be used from the command line to perform + miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. + It is intended for use with test cards only. It can be used to load objects, and generate + key pairs, as well as send arbitrary APDU commands to a card after having authenticated + to the card using the card key provided by the card vendor. +

Options

+

+ --serial +

Print the card serial number derived from the CHUID object, + if any. Output is in hex byte format.

+ --name, + -n +

Print the name of the inserted card (driver)

+ --admin argument, + -A argument +

Authenticate to the card using a 2DES or 3DES key. + The argument of the form +

 {A|M}:ref:alg

+ is required, were A uses "EXTERNAL AUTHENTICATION" + and M uses "MUTUAL AUTHENTICATION". + ref is normally 9B, + and alg is 03 for 3DES. + The key is provided by the card vendor, and the environment variable + PIV_EXT_AUTH_KEY must point to a text file containing + the key in the format: + XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX +

+ --genkey argument, + -G argument +

Generate a key pair on the card and output the public key. + The argument of the form +

ref:alg

+ is required, where ref is 9A, + 9C, 9D or 9E and + alg is 06, + 07, 11 or 14 + for RSA 1024, RSA 2048, ECC 256 or ECC 384 respectively.

+ --object ContainerID, + -O ContainerID +

Load an object onto the card. + The ContainerID is as defined in NIST 800-73-n + without leading 0x. Example: CHUID object is 3000 +

+ --cert ref, + -s ref +

Load a certificate onto the card. + ref is 9A, + 9C, 9D or + 9E

+ --compresscert ref, + -Z ref +

Load a certificate that has been gzipped onto the card. + ref is 9A, + 9C, 9D or + 9E

+ --out file, + -o file +

Output file for any operation that produces output. +

+ --in file, + -i file +

Input file for any operation that requires an input file. +

+ --key-slots-discovery file +

Print properties of the key slots. Needs 'admin' authentication. +

+ --send-apdu apdu, + -s apdu +

Sends an arbitrary APDU to the card in the format + AA:BB:CC:DD:EE:FF.... + This option may be repeated.

+ --reader num, + -r num +

Use the given reader number. The default is + 0, the first reader in the system.

+ --card-driver driver, + -c driver +

Use the given card driver. + The default is auto-detected.

+ --wait, + -w +

Wait for a card to be inserted

+ --verbose, + -v +

Causes piv-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc + library.

+

See also

+ opensc-tool(1) +


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

+ The pkcs11-tool utility is used to manage the + data objects on smart cards and similar PKCS #11 security tokens. + Users can list and read PINs, keys and certificates stored on the + token. User PIN authentication is performed for those operations + that require it. +

Options

+

+ --attr-from filename +

Extract information from filename + (DER-encoded certificate file) and create the corresponding + attributes when writing an object to the token. Example: the + certificate subject name is used to create the CKA_SUBJECT + attribute.

+ --change-pin, + -c +

Change the user PIN on the token

+ --unlock-pin +

Unlock User PIN (without --login + unlock in logged in session; otherwise --login-type + has to be 'context-specific').

+ --hash, + -h +

Hash some data.

+ --hash-algorithm mechanism +

+ Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + also allow "SHA224". Default is "SHA-1". +

+ Note that the input to RSA-PKCS-PSS has to be of the size equal to + the specified hash algorithm. E.g., for SHA256 the signature input must + be exactly 32 bytes long (for mechanisms SHA256-RSA-PKCS-PSS there is no + such restriction). For RSA-OAEP, the plaintext input size mLen must be + at most keyLen - 2 - 2*hashLen. For example, for RSA 3072-bit key and + SHA384, the longest plaintext to encrypt with RSA-OAEP is (with all + sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes. +

+ --id id, + -d id +

Specify the id of the object to operate on.

+ --init-pin +

Initializes the user PIN. This option + differs from --change-pin in that it sets the user PIN + for the first time. Once set, the user PIN can be changed + using --change-pin.

+ --init-token +

Initialize a token: set the token label as + well as a Security Officer PIN (the label must be specified + using --label).

+ --input-file filename, + -i filename +

Specify the path to a file for input.

+ --keypairgen, + -k +

Generate a new key pair (public and private pair.)

+ --keygen +

Generate a new key.

+ --key-type specification +

Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1.

+ --usage-sign +

Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

+ --usage-decrypt +

Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey).

+ --usage-derive +

Specify 'derive' key usage flag (EC only).

+ --label name, + -a name +

Specify the name of the object to operate on + (or the token label when --init-token + is used).

+ --list-mechanisms, + -M +

Display a list of mechanisms supported by the token.

+ --list-objects, + -O +

Display a list of objects.

+ --list-slots, + -L +

Display a list of available slots on the token.

+ --list-token-slots, + -T +

List slots with tokens.

+ --login, + -l +

Authenticate to the token before performing + other operations. This option is not needed if a PIN is + provided on the command line.

+ --login-type +

Specify login type ('so', 'user', 'context-specific'; + default:'user').

+ --mechanism mechanism, + -m mechanism +

Use the specified mechanism + for token operations. See -M for a list + of mechanisms supported by your token. The mechanism can also be specified in + hexadecimal, e.g., 0x80001234.

+ --mgf function +

Use the specified Message Generation + Function (MGF) function + for RSA-PKCS-PSS signatures or RSA-OAEP decryptions. Supported arguments are MGF1-SHA1 + to MGF1-SHA512 if supported by the driver. + The default is based on the hash selection. +

+ --module mod +

Specify a PKCS#11 module (or library) to + load.

+ --moz-cert filename, + -z filename +

Test a Mozilla-like keypair generation + and certificate request. Specify the filename + to the certificate file.

+ --output-file filename, + -o filename +

Specify the path to a file for output.

+ --pin pin, + -p pin +

Use the given pin for + token operations. If set to + env:VARIABLE, the value of the + environment variable VARIABLE is + used. WARNING: Be careful using this option + as other users may be able to read the command line from + the system or if it is embedded in a script. If set to + env:VARIABLE, the value of the + environment variable VARIABLE is + used.

This option will also set + the --login option.

+ --puk puk +

Supply User PUK on the command line.

+ --new-pin pin +

Supply new User PIN on the command line.

+ --sensitive +

Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext).

+ --set-id id, + -e id +

Set the CKA_ID of the object.

+ --show-info, + -I +

Display general token information.

+ --sign, + -s +

Sign some data.

+ --decrypt, +

Decrypt some data.

+ --derive, +

Derive a secret key using another key and some data.

+ --derive-pass-der, +

Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations

+ --salt-len bytes +

Specify how many bytes of salt should + be used in RSA-PSS signatures. Accepts two special values: + "-1" means salt length equals to digest length, + "-2" means use maximum permissible length. + Default is digest length (-1).

+ --slot id +

Specify the id of the slot to use.

+ --slot-description description +

Specify the description of the slot to use.

+ --slot-index index +

Specify the index of the slot to use.

+ --token-label label +

Specify the label of token. + Will be used the first slot, that has the inserted token with this + label.

+ --so-pin pin +

Use the given pin as the + Security Officer PIN for some token operations (token + initialization, user PIN initialization, etc). If set to + env:VARIABLE, the value of the + environment variable VARIABLE is + used. The same warning as --pin also + applies here.

+ --test, + -t +

Perform some tests on the token. This + option is most useful when used with either --login + or --pin.

+ --test-hotplug +

Test hotplug capabilities (C_GetSlotList + + C_WaitForSlotEvent).

+ --private +

Set the CKA_PRIVATE attribute (object is only + viewable after a login).

+ --test-ec +

Test EC (best used with the --login + or --pin option).

+ --test-fork +

Test forking and calling C_Initialize() in the + child.

+ --type type, + -y type +

Specify the type of object to operate on. + Examples are cert, privkey + and pubkey.

+ --verbose, -v +

Cause pkcs11-tool to be + more verbose.

NB! This does not affect + OpenSC debugging level! To set OpenSC PKCS#11 module into debug + mode, set the OPENSC_DEBUG environment variable to a + non-zero number.

+ --read-object, + -r +

Get object's CKA_VALUE attribute (use with + --type).

+ --delete-object, + -b +

Delete an object.

+ --application-label label +

Specify the application label of the data object (use with + --type data).

+ --application-id id +

Specify the application ID of the data object (use with + --type data).

+ --issuer data +

Specify the issuer in hexadecimal format (use with + --type cert).

+ --subject data +

Specify the subject in hexadecimal format (use with + --type cert/privkey/pubkey).

+ --signature-format format +

Format for ECDSA signature: 'rs' (default), + 'sequence', 'openssl'.

+ --write-object filename, + -w filename +

Write a key or certificate object to the token. + filename points to the DER-encoded certificate or key file. +

+ --generate-random num +

Get num bytes of random data. +

+

Examples

+ To list all certificates on the smart card: +

pkcs11-tool --list-objects --type cert

+ + To read the certificate with ID KEY_ID + in DER format from smart card: +

pkcs11-tool --read-object  --id KEY_ID --type cert --outfile cert.der

+ + To convert the certificate in DER format to PEM format, use OpenSSL + tools: +

openssl x509 -inform DER -in cert.der -outform PEM > cert.pem

+ + To sign some data stored in file data + using the private key with ID ID and + using the RSA-PKCS mechanism: +

pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

+


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

+ The pkcs15-crypt utility can be used from the + command line to perform cryptographic operations such as computing + digital signatures or decrypting data, using keys stored on a PKCS#15 + compliant smart card. +

Options

+

+ --version, +

Print the OpenSC package release version.

+ --aid aid +

Specify the AID of the on-card PKCS#15 application + to bind to. The aid must be in hexadecimal + form.

+ --decipher, + -c +

Decrypt the contents of the file specified by + the --input option. The result of the + decryption operation is written to the file specified by the + --output option. If this option is not given, + the decrypted data is printed to standard output, displaying + non-printable characters using their hex notation xNN (see also + --raw).

+ --input file, + -i file +

Specifies the input file to use. Defaults to stdin if + not specified.

+ --key id, + -k id +

Selects the ID of the key to use.

+ --output file, + -o file +

Any output will be sent to the specified file. Defaults + to stdout if not specified.

+ --pin pin, + -p pin +

When the cryptographic operation requires a + PIN to access the key, pkcs15-crypt will + prompt the user for the PIN on the terminal. Using this option + allows you to specify the PIN on the command line.

Note that on most operating systems, the command line of + a process can be displayed by any user using the ps(1) + command. It is therefore a security risk to specify + secret information such as PINs on the command line. + If you specify '-' as PIN, it will be read from STDIN.

+ --pkcs1 +

By default, pkcs15-crypt + assumes that input data has been padded to the correct length + (i.e. when computing an RSA signature using a 1024 bit key, + the input must be padded to 128 bytes to match the modulus + length). When giving the --pkcs1 option, + however, pkcs15-crypt will perform the + required padding using the algorithm outlined in the + PKCS #1 standard version 1.5.

+ --raw, + -R +

Outputs raw 8 bit data.

+ --reader N, + -r N +

Selects the N-th smart + card reader configured by the system. If unspecified, + pkcs15-crypt will use the first reader + found.

+ --sha-1 +

This option tells pkcs15-crypt + that the input file is the result of an SHA1 hash operation, + rather than an MD5 hash. Again, the data must be in binary + representation.

+ --sign, + -s +

Perform digital signature operation on + the data read from a file specified using the --input + option. By default, the contents of the file are assumed to + be the result of an MD5 hash operation. + Note that pkcs15-crypt + expects the data in binary representation, not ASCII.

The digital signature is stored, in binary representation, + in the file specified by the --output option. If + this option is not given, the signature is printed on standard + output, displaying non-printable characters using their hex notation + xNN + (see also --raw).

+ --signature-format, + --f +

When signing with ECDSA key this option indicates + to pkcs15-crypt the signature output format. + Possible values are 'rs'(default) -- two concatenated + integers (PKCS#11), 'sequence' or 'openssl' -- DER encoded sequence + of two integers (OpenSSL).

+ --verbose, + -v +

Causes pkcs15-crypt to be more + verbose. Specify this flag several times to enable debug output + in the OpenSC library.

+

See also

+ pkcs15-init(1), + pkcs15-tool(1) +


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

+ The pkcs15-init utility can be used to create a PKCS #15 + structure on a smart card, and add key or certificate objects. Details of the + structure that will be created are controlled via profiles. +

+ The profile used by default is pkcs15. Alternative + profiles can be specified via the -p switch. +

PIN Usage

+ pkcs15-init can be used to create a PKCS #15 structure on + your smart card, create PINs, and install keys and certificates on the card. + This process is also called personalization. +

+ An OpenSC card can have one security officer PIN, and zero or more user PINs. + PIN stands for Personal Identification Number, and is a secret code you need + to present to the card before being allowed to perform certain operations, + such as using one of the stored RSA keys to sign a document, or modifying + the card itself. +

+ Usually, PINs are a sequence of decimal digits, but some cards will accept + arbitrary ASCII characters. Be aware however that using characters other + than digits will make the card unusable with PIN pad readers, because those + usually have keys for entering digits only. +

+ The security officer (SO) PIN is special; it is used to protect meta data + information on the card, such as the PKCS #15 structure itself. Setting + the SO PIN is optional, because the worst that can usually happen is that + someone finding your card can mess it up. To extract any of your secret + keys stored on the card, an attacker will still need your user PIN, at + least for the default OpenSC profiles. However, it is possible to create + card profiles that will allow the security officer to override user PINs. +

+ For each PIN, you can specify a PUK (also called unblock PIN). + The PUK can be used to overwrite or unlock a PIN if too many incorrect values + have been entered in a row. +

+ For some cards that use the PKCS#15 emulation, the attributes of private objects + are protected and cannot be parsed without authentication (usually with User PIN). + This authentication need to be done immediately after the card binding. + In such cases --verify-pin has to be used. +

Modes of operation

Initialization

This is the first step during card personalization, and will create the + basic files on the card. To create the initial PKCS #15 structure, invoke the + utility as +

+ pkcs15-init --create-pkcs15

+ You will then be asked for the security officer PIN and PUK. Simply + pressing return at the SO PIN prompt will skip installation of an SO PIN. +

+ If the card supports it, you should erase the contents of the card with + pkcs15-init --erase-card before creating the PKCS#15 structure. +

User PIN Installation

+ Before installing any user objects such as private keys, you need at least one + PIN to protect these objects. you can do this using +

+ pkcs15-init --store-pin --id " nn +

+ where nn is a PKCS #15 ID in hexadecimal notation. Common + values are 01, 02, etc. +

+ Entering the command above will ask you for the user's PIN and PUK. If you do + not wish to install an unblock PIN, simply press return at the PUK prompt. +

+ To set a label for this PIN object (which can be used by applications to display + a meaningful prompt to the user), use the --label command line option. +

Key generation

+ pkcs15-init lets you generate a new key and store it on the card. + You can do this using: +

+ pkcs15-init --generate-key " keyspec " --auth-id " nn +

+ where keyspec describes the algorithm and length of the + key to be created, such as rsa/512. This will create a 512 bit + RSA key. Currently, only RSA key generation is supported. Note that cards + usually support just a few different key lengths. Almost all cards will support + 512 and 1024 bit keys, some will support 768 or 2048 as well. +

+ nn is the ID of a user PIN installed previously, + e.g. 01. +

+ In addition to storing the private portion of the key on the card, + pkcs15-init will also store the the public portion of the + key as a PKCS #15 public key object. +

Private Key Upload

+ You can use a private key generated by other means and upload it to the card. + For instance, to upload a private key contained in a file named + okir.pem, which is in PEM format, you would use +

+ pkcs15-init --store-private-key okir.pem --id 45 --auth-id 01 +

+ In addition to storing the private portion of the key on the card, + pkcs15-init will also store the the public portion of the + key as a PKCS #15 public key object. +

+ Note that usage of --id option in the pkcs15-init + commands to generate or to import a new key is deprecated. + Better practice is to let the middleware to derive the identifier from the key material. + (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). + This allows easily set up relation between 'related' objects + (private/public keys and certificates). +

+ In addition to the PEM key file format, pkcs15-init also + supports DER encoded keys, and PKCS #12 files. The latter is the file format + used by Netscape Navigator (among others) when exporting certificates to + a file. A PKCS #12 file usually contains the X.509 certificate corresponding + to the private key. If that is the case, pkcs15-init will + store the certificate instead of the public key portion. +

Public Key Upload

+ You can also upload individual public keys to the card using the + --store-public-key option, which takes a filename as an + argument. This file is supposed to contain the public key. If you don't + specify a key file format using the --format option, + pkcs15-init will assume PEM format. The only other + supported public key file format is DER. +

+ Since the corresponding public keys are always uploaded automatically + when generating a new key, or when uploading a private key, you will + probably use this option only very rarely. +

Certificate Upload

+ You can upload certificates to the card using the + --store-certificate option, which takes a filename as + an argument. This file is supposed to contain the PEM encoded X.509 + certificate. +

Uploading PKCS #12 bags

+ Most browsers nowadays use PKCS #12 format files when you ask them to + export your key and certificate to a file. pkcs15-init + is capable of parsing these files, and storing their contents on the + card in a single operation. This works just like storing a private key, + except that you need to specify the file format: +

+ pkcs15-init --store-private-key okir.p12 --format pkcs12 --auth-id + 01 +

+ This will install the private key contained in the file okir.p12, + and protect it with the PIN referenced by authentication ID 01. + It will also store any X.509 certificates contained in the file, which is + usually the user certificate that goes with the key, as well as the CA certificate. +

Secret Key Upload

+ You can use a secret key generated by other means and upload it to the card. + For instance, to upload an AES-secret key generated by the system random generator + you would use +

+ pkcs15-init --store-secret-key /dev/urandom --secret-key-algorithm aes/256 --auth-id 01 +

+ By default a random ID is generated for the secret key. You may specify an ID + with the --id if needed. +

Options

+

+ --version, +

Print the OpenSC package release version.

+ --card-profile name, + -c name +

+ Tells pkcs15-init to load the specified card + profile option. You will rarely need this option. +

+ --create-pkcs15, + -C +

+ This tells pkcs15-init to create a PKCS #15 + structure on the card, and initialize any PINs. +

+ --erase-card, + -E +

+ This will erase the card prior to creating the PKCS #15 structure, + if the card supports it. If the card does not support erasing, + pkcs15-init will fail. +

+ --generate-key keyspec, + -G keyspec +

+ Tells the card to generate new key and store it on the card. + keyspec consists of an algorithm name + (currently, the only supported name is RSA), + optionally followed by a slash and the length of the key in bits. + It is a good idea to specify the key ID along with this command, + using the id option, otherwise an intrinsic ID + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the aid option. +

+ --options-file filename +

+ Tells pkcs15-init to read additional options + from filename. The file is supposed to + contain one long option per line, without the leading dashes, + for instance: +

+	pin		frank
+	puk		zappa
+

+

+ You can specify --options-file several times. +

+ --pin, + --puk + --so-pin, + --so-puk, +

+ These options can be used to specify PIN/PUK values + on the command line. If set to + env:VARIABLE, the value + of the environment variable + VARIABLE is used. Note + that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should use + these options only on a secured system, or in an + options file specified with + --options-file. +

+ --profile name, + -p name +

+ Tells pkcs15-init to load the specified general + profile. Currently, the only application profile defined is + pkcs15, but you can write your own profiles and + specify them using this option. +

+ The profile name can be combined with one or more profile + options, which slightly modify the profile's behavior. + For instance, the default OpenSC profile supports the + openpin option, which installs a single PIN during + card initialization. This PIN is then used both as the SO PIN as + well as the user PIN for all keys stored on the card. +

+ Profile name and options are separated by a + + character, as in pkcs15+onepin. +

+ --secret-key-algorithm keyspec, +

+ keyspec describes the algorithm and length of the + key to be created or downloaded, such as aes/256. + This will create a 256 bit AES key. +

+ --store-certificate filename, + -X filename +

+ Tells pkcs15-init to store the certificate given + in filename on the card, creating a certificate + object with the ID specified via the --id option. + Without supplied ID an intrinsic ID will be calculated from the + certificate's public key. Look the description of the 'pkcs15-id-style' + attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + The file is assumed to contain the PEM encoded certificate. + For the multi-application cards the target application can be specified + by the hexadecimal AID value of the aid option. +

+ --store-public-key filename +

+ Tells pkcs15-init to download the specified + public key to the card and create a public key object with the + key ID specified via the --id. By default, + the file is assumed to contain the key in PEM format. Alternative + formats can be specified using --format. +

+ --store-private-key filename, + -S filename +

+ Tells pkcs15-init to download the specified + private key to the card. This command will also create a public + key object containing the public key portion. By default, the + file is assumed to contain the key in PEM format. Alternative + formats can be specified using --format. + It is a good idea to specify the key ID along with this command, + using the --id option, otherwise an intrinsic ID + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the aid option. +

+ --store-secret-key filename, +

+ Tells pkcs15-init to download the specified + secret key to the card. The file is assumed to contain the raw key. + They key type should be specified with --secret-key-algorithm + option. + You may additionally specify the key ID along with this command, + using the --id option, otherwise a random ID is generated. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the aid option. +

+ --update-certificate filename, + -U filename +

+ Tells pkcs15-init to update the certificate + object with the ID specified via the --id option + with the certificate in filename. + The file is assumed to contain a PEM encoded certificate. +

Pay extra attention when updating mail decryption certificates, as + missing certificates can render e-mail messages unreadable! +

+ --use-default-transport-keys, + -T +

+ Tells pkcs15-init to not ask for the transport + keys and use default keys, as known by the card driver. +

+ --verbose, + -v +

+ Causes pkcs15-init to be more verbose. Specify this + flag several times to enable debug output in the OpenSC library. +

+ --use-pinpad +

Do not prompt the user; if no PINs supplied, pinpad will be used.

+

See also

+ pkcs15-profile(5) +


Name

pkcs15-tool — utility for manipulating PKCS #15 data structures + on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

+ The pkcs15-tool utility is used to manipulate + the PKCS #15 data structures on smart cards and similar security + tokens. Users can list and read PINs, keys and certificates stored + on the token. User PIN authentication is performed for those + operations that require it. +

Options

+

+ --version, +

Print the OpenSC package release version.

+ --aid aid +

Specify in a hexadecimal form the AID of the on-card PKCS#15 + application to bind to.

+ --auth-id pin, + -a pin +

Specifies the auth id of the PIN to use for the + operation. This is useful with the --change-pin operation.

+ --change-pin +

Changes a PIN or PUK stored on the token. User authentication + is required for this operation.

+ --dump, + -D +

List all card objects.

+ --list-applications +

List the on-card PKCS#15 applications

+ --list-certificates, + -c +

List all certificates stored on the token.

+ --list-data-objects, + -C +

List all data objects stored on the token. + For some cards the PKCS#15 attributes of the private data objects are + protected for reading and need the authentication with the User PIN. + In such a case the --verify-pin option has to be used. +

+ --list-keys, + -k +

List all private keys stored on the token. General + information about each private key is listed (eg. key name, id and + algorithm). Actual private key values are not displayed. + For some cards the PKCS#15 attributes of the private keys are protected for reading + and need the authentication with the User PIN. + In such a case the --verify-pin option has to be used.

+ --list-pins +

List all PINs stored on the token. General information + about each PIN is listed (eg. PIN name). Actual PIN values are not shown.

+ --list-public-keys +

List all public keys stored on the token, including + key name, id, algorithm and length information.

+ --short + -s +

Output lists in compact format.

+ --no-cache +

Disables token data caching.

+ --clear-cache +

Removes the user's cache directory. On + Windows, this option additionally removes the system's + caching directory (requires administrator + privileges).

+ --clear-cache +

Removes the user's cache directory. On + Windows, this option additionally removes the system's + caching directory (requires administrator + privileges).

+ --output filename, + -o filename +

Specifies where key output should be written. + If filename already exists, it will be overwritten. + If this option is not given, keys will be printed to standard output.

+ --raw +

Changes how --read-data-object prints the content + to standard output. By default, when --raw is not given, it will + print the content in hex notation. If --raw is set, it will print + the binary data directly. This does not affect the output that is written to the + file specified by the --output option. Data written to a file will + always be in raw binary.

+ --read-certificate cert, + -r cert +

Reads the certificate with the given id.

+ --read-data-object cert, + -R data +

Reads data object with OID, applicationName or label. + The content is printed to standard output in hex notation, unless + the --raw option is given. + If an output file is given with the --output option, + the content is additionally written to the file. + Output to the file is always written in raw binary mode, the + --raw only affects standard output behavior.

+ --read-public-key id +

Reads the public key with id id, + allowing the user to extract and store or use the public key.

+ --read-ssh-key id +

Reads the public key with id id, + writing the output in format suitable for + $HOME/.ssh/authorized_keys.

The key label, if any will be shown in the 'Comment' field.

+ --rfc4716 +

When used in conjunction with option --read-ssh-key the + output format of the public key follows rfc4716.

The default output format is a single line (openssh).

+ --reader num +

Forces pkcs15-tool to use reader + number num for operations. The default is to use + reader number 0, the first reader in the system.

+ --unblock-pin, + -u +

Unblocks a PIN stored on the token. Knowledge of the + Pin Unblock Key (PUK) is required for this operation.

+ --verbose, + -v +

Causes pkcs15-tool to be more + verbose. Specify this flag several times to enable debug output + in the OpenSC library.

+ --verify-pin +

Verify PIN after card binding and before issuing any command + (without 'auth-id' the first non-SO, non-Unblock PIN will be verified)

+ --use-pinpad +

Do not prompt the user; if no PINs supplied, pinpad will be used.

+

See also

+ pkcs15-init(1), + pkcs15-crypt(1) +


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

+ The sc-hsm-tool utility can be used from the command line to perform + extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. + It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import + Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. +

Options

+

+ --initialize, + -X +

Initialize token, removing all existing keys, certificates and files.

Use --so-pin to define SO-PIN for first initialization or to verify in subsequent + initializations.

Use --pin to define the initial user pin value.

Use --pin-retry to define the maximum number of wrong user PIN presentations.

Use with --dkek-shares to enable key wrap / unwrap.

Use with --label to define a token label

+ --create-dkek-share filename, + -C filename +

Create a DKEK share encrypted under a password and save it to the file + given as parameter.

Use --password to provide a password for encryption rather than prompting for one.

Use --pwd-shares-threshold and --pwd-shares-total to randomly generate a password and split is using a (t, n) threshold scheme.

+ --import-dkek-share filename, + -I filename +

Prompt for user password, read and decrypt DKEK share and import into SmartCard-HSM.

Use --password to provide a password for decryption rather than prompting for one.

Use --pwd-shares-total to specify the number of shares that should be entered to reconstruct the password.

+ --wrap-key filename, + -W filename +

Wrap the key referenced in --key-reference and save with it together with the key description + and certificate to the given file.

Use --pin to provide the user PIN on the command line.

+ --unwrap-key filename, + -U filename +

Read wrapped key, description and certificate from file and import into SmartCard-HSM + under the key reference given in --key-reference.

Determine the key reference using the output of pkcs15-tool -D.

Use --pin to provide a user PIN on the command line.

Use --force to remove any key, key description or certificate in the way.

+ --dkek-shares number-of-shares, + -s number-of-shares +

Define the number of DKEK shares to use for recreating the DKEK.

This is an optional parameter. Using --initialize without + --dkek-shares will disable the DKEK completely.

Using --dkek-shares with 0 shares requests the SmartCard-HSM to + generate a random DKEK. Keys wrapped with this DKEK can only be unwrapped in the + same SmartCard-HSM.

After using --initialize with one or more DKEK shares, the + SmartCard-HSM will remain in the initialized state until all DKEK shares have + been imported. During this phase no new keys can be generated or imported.

+ --so-pin value +

Define SO-PIN for initialization. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

+ --pin value +

Define user PIN for initialization, wrap or + unwrap operation. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

+ --pin-retry value +

Define number of PIN retries for user PIN during initialization. Default is 3.

+ --password value +

Define password for DKEK share encryption. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

+ --pwd-shares-threshold value +

Define threshold for number of password shares required for reconstruction.

+ --pwd-shares-total value +

Define number of password shares.

+ --force +

Force removal of existing key, description and certificate.

+ --label label, + -l label +

Define the token label to be used in --initialize.

+ --reader num, + -r num +

Use the given reader number. The default is + 0, the first reader in the system.

+ --wait, + -w +

Wait for a card to be inserted

+ --verbose, + -v +

Causes sc-hsm-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc + library.

+

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

+ opensc-tool(1) +


Name

westcos-tool — utility for manipulating data structures + on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

+ The westcos-tool utility is used to manipulate + the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, + keys and certificates stored on the card / token. User PIN authentication is + performed for those operations that require it. +

Options

+

+ --change-pin, + -n +

Changes a PIN stored on the card. + User authentication is required for this operation.

+ --certificate file, + -t file +

Write certificate file file + in PEM format to the card. + User authentication is required for this operation.

+ --finalize, + -f +

Finalize the card. Once finalized the default key is + invalidated, so PIN and PUK cannot be changed anymore without user + authentication.

Warning, un-finalized cards are insecure because the PIN can be + changed without user authentication (knowledge of default key + is enough).

+ --generate-key, + -g +

Generate a private key on the card. The card must not have + been finalized and a PIN must be installed (i.e. the file for the PIN must + have been created, see option -i). + By default the key length is 1536 bits. User authentication is required for + this operation.

+ --help, + -h +

Print help message on screen.

+ --install-pin, + -i +

Install PIN file in on the card. + You must provide a PIN value with -x.

+ --key-length length, + -l length +

Change the length of private key. + Use with -g.

+ --overwrite-key, + -o +

Overwrite the key if there is already a key on the card.

+ --pin-value value, + -x value +

Set value of PIN. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

+ --puk-value value, + -y value +

set value of PUK (or value of new PIN for change PIN + command see -n). If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

+ --read-file filename, + -j filename +

Read the file filename from the card. + The file is written on disk with name filename. + User authentication is required for this operation.

+ --reader num, + -r num +

+ Use the given reader. The default is the first reader with a card. +

+ --unblock-pin, + -u +

Unblocks a PIN stored on the card. Knowledge of the + PIN Unblock Key (PUK) is required for this operation.

+ -v +

Causes westcos-tool to be more + verbose. Specify this flag several times to enable debug output + in the OpenSC library.

+ --wait, + -w +

Wait for a card to be inserted.

+ --write-file filename, + -k filename +

Put the file with name filename + from disk to card. + On the card the file is written in filename. + User authentication is required for this operation.

+

Authors

westcos-tool was written by + Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

+ The pkcs15-init utility for PKCS #15 smart card + personalization is controlled via profiles. When starting, it will read two + such profiles at the moment, a generic application profile, and a card + specific profile. The generic profile must be specified on the command line, + while the card-specific file is selected based on the type of card detected. +

+ The generic application profile defines general information about the card + layout, such as the path of the application DF, various PKCS #15 files within + that directory, and the access conditions on these files. It also defines + general information about PIN, key and certificate objects. Currently, there + is only one such generic profile, pkcs15.profile. +

+ The card specific profile contains additional information required during + card initialization, such as location of PIN files, key references etc. + Profiles currently reside in @pkgdatadir@ +

Syntax

+ This section should contain information about the profile syntax. Will add + this soonishly. +

See also

+ pkcs15-init(1), + pkcs15-crypt(1) +

diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml index e9fe9179a1..34b993fb89 100644 --- a/doc/tools/tools.xml +++ b/doc/tools/tools.xml @@ -3,24 +3,29 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> - OpenSC + OpenSC Manuals OpenSC tools - + + + - + + + - + + From 4e83e2e1b35952af089466cc12a939c435af8b30 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Apr 2018 14:48:54 +0200 Subject: [PATCH 0238/4321] reader-pcsc: fixed default for disconnect_action Initialize it to "leave", even if no pcsc configuration block was given. --- src/libopensc/reader-pcsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index eb5319cdb1..535c437aba 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -762,7 +762,7 @@ static int pcsc_init(sc_context_t *ctx) /* PC/SC Defaults */ gpriv->provider_library = DEFAULT_PCSC_PROVIDER; gpriv->connect_exclusive = 0; - gpriv->disconnect_action = SCARD_RESET_CARD; + gpriv->disconnect_action = SCARD_LEAVE_CARD; gpriv->transaction_end_action = SCARD_LEAVE_CARD; gpriv->reconnect_action = SCARD_LEAVE_CARD; gpriv->enable_pinpad = 1; From 90a5b262d0e4d7206d071e469cb656f771e209c6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 18 Apr 2018 16:16:27 +0200 Subject: [PATCH 0239/4321] nPA: fixed matching for newer cards they have other ATRs... match if EF.CardAccess is found --- src/libopensc/card-npa.c | 52 +++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 5959359824..59dea7523f 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -68,11 +68,11 @@ static void npa_drv_data_free(struct npa_drv_data *drv_data) static struct sc_atr_table npa_atrs[] = { {"3B:8A:80:01:80:31:F8:73:F7:41:E0:82:90:00:75", "FF:FF:FF:FF:FF:FF:00:FF:00:00:FF:FF:FF:FF:00", - "German ID card (neuer Personalausweis, nPA)", SC_CARD_TYPE_NPA, 0, NULL}, + NULL, SC_CARD_TYPE_NPA, 0, NULL}, {"3B:88:80:01:00:00:00:00:00:00:00:00:09", NULL, - "German ID card (neuer Personalausweis, nPA)", SC_CARD_TYPE_NPA, 0, NULL}, + NULL, SC_CARD_TYPE_NPA, 0, NULL}, {"3B:87:80:01:80:31:B8:73:84:01:E0:19", NULL, - "German ID card (neuer Personalausweis, nPA)", SC_CARD_TYPE_NPA, 0, NULL}, + NULL, SC_CARD_TYPE_NPA, 0, NULL}, {"3B:84:80:01:00:00:90:00:95", NULL, "German ID card (Test neuer Personalausweis)", SC_CARD_TYPE_NPA_TEST, 0, NULL}, {"3B:88:80:01:00:E1:F3:5E:13:77:83:00:00", @@ -149,9 +149,31 @@ static int npa_load_options(sc_context_t *ctx, struct npa_drv_data *drv_data) static int npa_match_card(sc_card_t * card) { - if (_sc_match_atr(card, npa_atrs, &card->type) < 0) - return 0; - return 1; + int r = 0; + unsigned char *ef_cardaccess = NULL; + size_t ef_cardaccess_len = 0; + + r = _sc_match_atr(card, npa_atrs, &card->type); + if (r >= 0) { + if (NULL == card->name) { + card->name = npa_atrs[r].name; + } + r = 1; + } else { + r = 0; + } + + if (0 == r + && SC_SUCCESS == iso7816_read_binary_sfid( + card, SFID_EF_CARDACCESS, + &ef_cardaccess, &ef_cardaccess_len)) { + card->type = SC_CARD_TYPE_NPA; + r = 1; + } + + free(ef_cardaccess); + + return r; } static void npa_get_cached_pace_params(sc_card_t *card, @@ -381,8 +403,22 @@ static int npa_init(sc_card_t * card) /* unlock the eSign application for reading the certificates * by the PKCS#15 layer (i.e. sc_pkcs15_bind_internal) */ - if (SC_SUCCESS != npa_unlock_esign(card)) - sc_log(card->ctx, "Probably not all functionality will be available.\n"); + if (SC_SUCCESS == sc_enum_apps(card)) { + unsigned char esign_aid[] = { + 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, + }; + int i; + for (i = 0; i < card->app_count; i++) { + struct sc_app_info *app_info = card->app[i]; + if (sizeof esign_aid == app_info->aid.len + && 0 == memcmp(esign_aid, app_info->aid.value, sizeof esign_aid)) { + if (SC_SUCCESS != npa_unlock_esign(card)) { + sc_log(card->ctx, "Probably not all functionality will be available.\n"); + } + break; + } + } + } err: return r; From 099270092afd73141b7aa6c40e56f451ea46122b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Apr 2018 09:18:13 +0200 Subject: [PATCH 0240/4321] added documentation of some command line options --- doc/tools/cryptoflex-tool.1.xml | 12 +++++- doc/tools/opensc-tool.1.xml | 20 +++++++++ doc/tools/piv-tool.1.xml | 2 +- doc/tools/pkcs15-crypt.1.xml | 20 +++++++-- doc/tools/pkcs15-init.1.xml | 27 ++++++++---- doc/tools/pkcs15-tool.1.xml | 75 ++++++++++++++++++++++++++++++++- 6 files changed, 141 insertions(+), 15 deletions(-) diff --git a/doc/tools/cryptoflex-tool.1.xml b/doc/tools/cryptoflex-tool.1.xml index d54f1c1587..1364e449f7 100644 --- a/doc/tools/cryptoflex-tool.1.xml +++ b/doc/tools/cryptoflex-tool.1.xml @@ -121,7 +121,8 @@ - + , + Reads a public key from the card, allowing the user to extract and store or use the public key @@ -156,6 +157,15 @@ Verifies CHV1 before issuing commands + + + , + + + Causes cryptoflex-tool to + wait for a card insertion. + + diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index b2d77a2a9f..00abd45ae9 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -55,6 +55,12 @@ Use the given card driver. The default is auto-detected. + + + , + + Lists algorithms supported by card + , @@ -90,6 +96,20 @@ Print the name of the inserted card (driver). + + + conf, + conf + + Get configuration key, format: section:name:key + + + + conf, + conf + + Get configuration key, format: section:name:key:value + num, diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 30e7ac7960..034c1e1845 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -94,7 +94,7 @@ ref, - ref + ref Load a certificate onto the card. ref is 9A, diff --git a/doc/tools/pkcs15-crypt.1.xml b/doc/tools/pkcs15-crypt.1.xml index e329904911..2126f06fb2 100644 --- a/doc/tools/pkcs15-crypt.1.xml +++ b/doc/tools/pkcs15-crypt.1.xml @@ -140,11 +140,16 @@ + + + + + - This option tells pkcs15-crypt - that the input file is the result of an SHA1 hash operation, - rather than an MD5 hash. Again, the data must be in binary + These options tell pkcs15-crypt + that the input file is the result of the specified hash operation. + By default, an MD5 hash is expected. Again, the data must be in binary representation. @@ -179,6 +184,15 @@ of two integers (OpenSSL). + + + , + + + Causes pkcs15-crypt to + wait for a card insertion. + + , diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index ad3646a210..ae7dbd7dae 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -314,11 +314,11 @@ optionally followed by a slash and the length of the key in bits. It is a good idea to specify the key ID along with this command, using the option, otherwise an intrinsic ID - will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. - For the multi-application cards the target PKCS#15 application can be - specified by the hexadecimal AID value of the option. + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the option. @@ -333,10 +333,10 @@ from filename. The file is supposed to contain one long option per line, without the leading dashes, for instance: - - pin frank - puk zappa - + +pin frank +puk zappa + You can specify several times. @@ -530,6 +530,15 @@ + + + , + + + Causes pkcs15-init to + wait for a card insertion. + + diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index 5f1ba2bf79..78fe0b1ed6 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -75,11 +75,18 @@ List all card objects. + + + + + List card objects. + + - List the on-card PKCS#15 applications + List the on-card PKCS#15 applications. @@ -115,6 +122,18 @@ In such a case the option has to be used. + + + + + List all secret (symmetric) keys stored on the token. General + information about each secret key is listed (eg. key name, id and + algorithm). Actual secret key values are not displayed. + For some cards the PKCS#15 attributes of the private keys are protected for reading + and need the authentication with the User PIN. + In such a case the option has to be used. + + @@ -241,6 +260,22 @@ + + + , + , + + Test if the card needs a security update + + + + + , + , + + Update the card with a security update + + num @@ -269,6 +304,27 @@ in the OpenSC library. + + + PIN + + Specify PIN + + + + + PUK + + Specify Unblock PIN + + + + + PIN + + Specify New PIN (when changing or unblocking) + + @@ -277,6 +333,23 @@ (without 'auth-id' the first non-SO, non-Unblock PIN will be verified) + + + + + Equivalent to + with additional session PIN generation + + + + + , + + + Causes pkcs15-tool to + wait for a card insertion. + + From 537a208c2551cda183a4ebaf179e8f0c2622ab5c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Apr 2018 09:50:04 +0200 Subject: [PATCH 0241/4321] Use non unique flag for App ID When loaded as PKCS#11 module, OpenSC will reuse the application identifier for each instance. We don't want to put any burdon on the primary GApplication, so we use a non unique ID. fixes https://github.com/OpenSC/OpenSC/issues/1332 --- src/ui/notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index e08722bfe1..d66e3aff08 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -380,7 +380,7 @@ static GApplication *application = NULL; void sc_notify_init(void) { sc_notify_close(); - application = g_application_new("org.opensc.notify", G_APPLICATION_FLAGS_NONE); + application = g_application_new("org.opensc.notify", G_APPLICATION_NON_UNIQUE); if (application) { g_application_register(application, NULL, NULL); } From ac5852836dcb3beb15ec4438714c85c158bcc366 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Apr 2018 09:34:47 +0200 Subject: [PATCH 0242/4321] GIO: Check connection to DBus before notifying avoids error messages when dbus is not available. --- src/ui/notify.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index d66e3aff08..d7e6acf226 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -398,20 +398,22 @@ static void notify_gio(struct sc_context *ctx, const char *title, const char *text, const char *icon, const char *group) { - if (application) { + if (application + && g_application_get_is_registered(application) + && g_application_get_dbus_connection(application)) { GIcon *gicon = NULL; - GNotification *notification = g_notification_new (title); + GNotification *notification = g_notification_new(title); if (!notification) { return; } if (text) { - g_notification_set_body (notification, text); + g_notification_set_body(notification, text); } if (icon) { - gicon = g_themed_icon_new (icon); + gicon = g_themed_icon_new(icon); if (gicon) { - g_notification_set_icon (notification, gicon); + g_notification_set_icon(notification, gicon); } } From 2dad9a9fde252ff439d818044010ce6db92a7d46 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Apr 2018 10:35:44 +0200 Subject: [PATCH 0243/4321] gio: changed default symbols --- src/ui/notify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index d7e6acf226..39a082f0ae 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -457,10 +457,10 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, switch (id) { case NOTIFY_CARD_INSERTED: - icon = "dialog-information"; + icon = "contact-new"; break; case NOTIFY_CARD_REMOVED: - icon = "media-removed"; + icon = "media-eject"; break; case NOTIFY_PIN_GOOD: icon = "changes-allow"; From 318329d5b7fb4c69fa0601fc877f2f5656fb2c61 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Apr 2018 12:47:27 +0200 Subject: [PATCH 0244/4321] macOS: disable notifications only in PKCS#11 module basically reverts https://github.com/OpenSC/OpenSC/commit/c35eb1c9bc74e284723ffd726478720b69aed970 by applying a more selective fix for https://github.com/OpenSC/OpenSC/issues/1174 --- MacOSX/build-package.in | 1 - src/ui/notify.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 22e8e8868d..834e4a16f8 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -61,7 +61,6 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then --sysconfdir=$PREFIX/etc \ --enable-cvcdir=$PREFIX/etc/cvc \ --enable-x509dir=$PREFIX/etc/x509 \ - --disable-notify \ --disable-dependency-tracking \ --enable-shared \ --enable-static \ diff --git a/src/ui/notify.c b/src/ui/notify.c index 39a082f0ae..066ef78497 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -278,6 +278,17 @@ static void notify_proxy(struct sc_context *ctx, * we're including NotificationProxy which has similar features */ const char notificationproxy[] = "/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/NotificationProxy.app/Contents/MacOS/NotificationProxy"; + if (ctx && ctx->app_name + && (0 == strcmp(ctx->app_name, "opensc-pkcs11") + || 0 == strcmp(ctx->app_name, "onepin-opensc-pkcs11"))) { + /* some programs don't like forking when loading our PKCS#11 module, + * see https://github.com/OpenSC/OpenSC/issues/1174. + * TODO implementing an XPC service which sends the notification should + * work, though. See + * https://github.com/OpenSC/OpenSC/issues/1304#issuecomment-376656003 */ + return; + } + if (child > 0) { int status; if (0 == waitpid(child, &status, WNOHANG)) { From 99eed0aa82eaad9811c755cf960d8ae45966039e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 May 2018 23:22:45 +0200 Subject: [PATCH 0245/4321] pkcs15-init: documented remaining commandline switches fixes https://github.com/OpenSC/OpenSC/issues/1267 --- doc/tools/Makefile.am | 3 +- doc/tools/cardos-tool.1.xml | 10 +- doc/tools/cryptoflex-tool.1.xml | 11 +- doc/tools/dnie-tool.1.xml | 10 +- doc/tools/eidenv.1.xml | 11 +- doc/tools/gids-tool.1.xml | 10 +- doc/tools/iasecc-tool.1.xml | 10 +- doc/tools/netkey-tool.1.xml | 9 +- doc/tools/openpgp-tool.1.xml | 11 +- doc/tools/opensc-explorer.1.xml | 12 +- doc/tools/opensc-tool.1.xml | 10 +- doc/tools/piv-tool.1.xml | 10 +- doc/tools/pkcs15-crypt.1.xml | 12 +- doc/tools/pkcs15-init.1.xml | 415 +++++++++++++++++++++-- doc/tools/pkcs15-tool.1.xml | 11 +- doc/tools/sc-hsm-tool.1.xml | 10 +- doc/tools/tools.html | 575 ++++++++++++++++++++++++-------- doc/tools/westcos-tool.1.xml | 11 +- src/tools/pkcs15-init.c | 2 +- 19 files changed, 938 insertions(+), 215 deletions(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 83a361999f..17e4fbf125 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -2,8 +2,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = completion-template -# TODO XXX Uncomment after fixing issue #1267 -#TESTS = test-manpage.sh +TESTS = test-manpage.sh dist_noinst_DATA = $(wildcard $(srcdir)/*.xml) if ENABLE_DOC diff --git a/doc/tools/cardos-tool.1.xml b/doc/tools/cardos-tool.1.xml index 553934b1cb..9f384c8969 100644 --- a/doc/tools/cardos-tool.1.xml +++ b/doc/tools/cardos-tool.1.xml @@ -59,8 +59,14 @@ smart cards and similar security tokens based on Siemens Card/OS M4. number, number - Specify the reader number number to use. - The default is reader 0. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/cryptoflex-tool.1.xml b/doc/tools/cryptoflex-tool.1.xml index 1364e449f7..78428c61bb 100644 --- a/doc/tools/cryptoflex-tool.1.xml +++ b/doc/tools/cryptoflex-tool.1.xml @@ -134,9 +134,14 @@ num, num - Forces cryptoflex-tool to use - reader number num for operations. The default - is to use reader number 0, the first reader in the system. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index dd79c0ef95..59f68b1d1c 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -86,8 +86,14 @@ number, number - Specify the reader number to use. - The default is reader 0. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/eidenv.1.xml b/doc/tools/eidenv.1.xml index 2f72972973..75f2d0a778 100644 --- a/doc/tools/eidenv.1.xml +++ b/doc/tools/eidenv.1.xml @@ -69,9 +69,14 @@ num, num - - Use the given reader. The default is the first reader with a card. - + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/gids-tool.1.xml b/doc/tools/gids-tool.1.xml index 13a76b4bb3..7f4c076be8 100644 --- a/doc/tools/gids-tool.1.xml +++ b/doc/tools/gids-tool.1.xml @@ -82,8 +82,14 @@ argument, argument - Uses reader number - argument. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/iasecc-tool.1.xml b/doc/tools/iasecc-tool.1.xml index ba0ac0abef..59ee1b1d24 100644 --- a/doc/tools/iasecc-tool.1.xml +++ b/doc/tools/iasecc-tool.1.xml @@ -36,8 +36,14 @@ number, - Specify the reader number number to use. - The default is reader 0. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/netkey-tool.1.xml b/doc/tools/netkey-tool.1.xml index 5639324051..d5b5304b82 100644 --- a/doc/tools/netkey-tool.1.xml +++ b/doc/tools/netkey-tool.1.xml @@ -74,7 +74,14 @@ number, number - Use smart card in specified reader. Default is reader 0. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index b51225a273..380cac6bcc 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -91,9 +91,14 @@ num, num - - Use the given reader. The default is the first reader with a card. - + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 85ab0857e3..254597263f 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -68,10 +68,14 @@ num, num - - Use the given reader number. The default - is 0, the first reader in the system. - + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index 00abd45ae9..4f7cf2207d 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -115,8 +115,14 @@ num, num - Use the given reader number. - The default is 0, the first reader in the system. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 034c1e1845..397d0ac851 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -154,8 +154,14 @@ num, num - Use the given reader number. The default is - 0, the first reader in the system. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/pkcs15-crypt.1.xml b/doc/tools/pkcs15-crypt.1.xml index 2126f06fb2..f3dcf64b1d 100644 --- a/doc/tools/pkcs15-crypt.1.xml +++ b/doc/tools/pkcs15-crypt.1.xml @@ -132,10 +132,14 @@ N, N - Selects the N-th smart - card reader configured by the system. If unspecified, - pkcs15-crypt will use the first reader - found. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index ae7dbd7dae..0234de0c05 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -170,11 +170,11 @@ Note that usage of option in the pkcs15-init - commands to generate or to import a new key is deprecated. - Better practice is to let the middleware to derive the identifier from the key material. - (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). - This allows easily set up relation between 'related' objects - (private/public keys and certificates). + commands to generate or to import a new key is deprecated. + Better practice is to let the middleware to derive the identifier from the key material. + (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). + This allows easily set up relation between 'related' objects + (private/public keys and certificates). In addition to the PEM key file format, pkcs15-init also @@ -255,12 +255,12 @@ Options - - - , - - Print the OpenSC package release version. - + + + , + + Print the OpenSC package release version. + name, @@ -287,6 +287,17 @@ + + + SERIAL + + + + Specify the serial number of the card. + + + + , @@ -301,6 +312,18 @@ + + + AID + + + + This will erase the application with the application identifier + AID. + + + + keyspec, @@ -334,8 +357,8 @@ contain one long option per line, without the leading dashes, for instance: -pin frank -puk zappa + pin 1234 + puk 87654321 @@ -369,6 +392,17 @@ puk zappa + + + , + + + + Do not install a SO PIN, and do not prompt for it. + + + + name, @@ -419,13 +453,25 @@ puk zappa Tells pkcs15-init to store the certificate given in on the card, creating a certificate object with the ID specified via the option. - Without supplied ID an intrinsic ID will be calculated from the - certificate's public key. Look the description of the 'pkcs15-id-style' - attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. + Without supplied ID an intrinsic ID will be calculated from the + certificate's public key. Look the description of the 'pkcs15-id-style' + attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. The file is assumed to contain the PEM encoded certificate. - For the multi-application cards the target application can be specified - by the hexadecimal AID value of the option. + For the multi-application cards the target application can be specified + by the hexadecimal AID value of the option. + + + + + + + , + + + + + Store a new PIN/PUK on the card. @@ -459,11 +505,11 @@ puk zappa formats can be specified using . It is a good idea to specify the key ID along with this command, using the option, otherwise an intrinsic ID - will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. - For the multi-application cards the target PKCS#15 application can be - specified by the hexadecimal AID value of the option. + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the option. @@ -478,6 +524,8 @@ puk zappa secret key to the card. The file is assumed to contain the raw key. They key type should be specified with option. + + You may additionally specify the key ID along with this command, using the option, otherwise a random ID is generated. For the multi-application cards the target PKCS#15 application can be @@ -486,6 +534,18 @@ puk zappa + + + filename, + filename + + + + Store a data object. + + + + filename, @@ -495,11 +555,62 @@ puk zappa Tells pkcs15-init to update the certificate object with the ID specified via the option - with the certificate in . + with the certificate in filename. The file is assumed to contain a PEM encoded certificate. Pay extra attention when updating mail decryption certificates, as - missing certificates can render e-mail messages unreadable! + missing certificates can render e-mail messages unreadable! + + + + + + + arg, + arg + + + + Tells pkcs15-init to delete the + specified object. arg + is comma-separated list containing any of + privkey, pubkey, + secrkey, cert, + chain or data. + + + When data is specified, an + - must also be + specified, in the other cases an + must also be specified + + + When chain is specified, the + certificate chain starting with the cert with + specified ID will be deleted, until there's a CA + certificate that certifies another cert on the card + + + + + + + arg, + arg + + + + Tells pkcs15-init to change the + specified attribute. arg + is either privkey, + pubkey, secrkey, + cert or data. + You also have to specify the + of the object. + For now, you can only change the , e.g: + + pkcs15-init -A cert --id 45 -a 1 --label Jim + @@ -517,6 +628,35 @@ puk zappa + + + , + + + + + Tells pkcs15-init to perform a + card specific sanity check and possibly update + procedure. + + + + + + + num, + num + + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + + + , @@ -536,7 +676,7 @@ puk zappa Causes pkcs15-init to - wait for a card insertion. + wait for a card insertion. @@ -546,6 +686,227 @@ puk zappa Do not prompt the user; if no PINs supplied, pinpad will be used. + + + ID + + + + Specify ID of PUK to use/create + + + + + + + LABEL + + + + Specify label of PUK + + + + + + + LABEL + + + + Specify public key label (use with ) + + + + + + + LABEL + + + + Specify user cert label (use with ) + + + + + + + arg + + + + Specify application name of data object (use with ) + + + + + + + AID + + + + Specify AID of the on-card PKCS#15 application to be binded to (in hexadecimal form) + + + + + + + filename + filename, + + + + Output public portion of generated key to file + + + + + + + PASSPHRASE + + + + Specify passphrase for unlocking secret key + + + + + + + + + + + Mark certificate as a CA certificate + + + + + + + arg + arg, + + + + Specifies the X.509 key usage. + arg is comma-separated + list containing any of + digitalSignature, + nonRepudiation, + keyEncipherment, + dataEncipherment, + keyAgreement, + keyCertSign, + cRLSign. Abbreviated names are + allowed if unique (e.g. + dataEnc). + + + The alias sign is equivalent to + digitalSignature,keyCertSign,cRLSign + + + The alias decrypt is equivalent to + keyEncipherment,dataEncipherment + + + + + + + + , + + + + Finish initialization phase of the smart card + + + + + + + + + + + Update 'lastUpdate' attribute of tokenInfo + + + + + + + + + + + When storing PKCS#12 ignore CA certificates + + + + + + + + + + + Store or update existing certificate + + + + + + + + + + + Private key stored as an extractable key + + + + + + + + + + + Insecure mode: do not require a PIN for private key + + + + + + + GUID + + + + For a new key specify GUID for a MD container + + + + + + + + , + + + + Display help message + + + + diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index 78fe0b1ed6..a13eab83bd 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -280,9 +280,14 @@ num - Forces pkcs15-tool to use reader - number num for operations. The default is to use - reader number 0, the first reader in the system. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/sc-hsm-tool.1.xml b/doc/tools/sc-hsm-tool.1.xml index d560540a62..ba296bdbe1 100644 --- a/doc/tools/sc-hsm-tool.1.xml +++ b/doc/tools/sc-hsm-tool.1.xml @@ -204,8 +204,14 @@ num, num - Use the given reader number. The default is - 0, the first reader in the system. + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 2bcfba6d32..882eff0e26 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -43,7 +43,7 @@ font-style: italic; } - -->

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them + -->

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them
cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
dnie-tool — displays information about DNIe based security tokens
eidenv — utility for accessing visible data from electronic identity cards
gids-tool — smart card utility for GIDS cards
netkey-tool — administrative utility for Netkey E4 cards
iasecc-tool — displays information about IAS/ECC card
openpgp-tool — utility for accessing visible data OpenPGP smart cards @@ -70,8 +70,12 @@

Display information about the card or token.

--reader number, -r number -

Specify the reader number number to use. - The default is reader 0.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verbose, -v

Causes cardos-tool to be more verbose. @@ -80,12 +84,12 @@ -w

Causes cardos-tool to wait for the token to be inserted into reader.

-


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

+


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

cryptoflex-tool is used to manipulate PKCS data structures on Schlumberger Cryptoflex smart cards. Users can create, list and read PINs and keys stored on the smart card. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--app-df num, -a num @@ -122,15 +126,19 @@ -u id

Specifies the public key file id, id, to use

- --read-key + --read-key, + -R

Reads a public key from the card, allowing the user to extract and store or use the public key

--reader num, -r num -

Forces cryptoflex-tool to use - reader number num for operations. The default - is to use reader number 0, the first reader in the system.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verbose, -v

Causes cryptoflex-tool to be more @@ -138,12 +146,16 @@ the opensc library.

--verify-pin, -V -

Verifies CHV1 before issuing commands

-

See also

+

Verifies CHV1 before issuing commands

+ --wait, + -w +

Causes cryptoflex-tool to + wait for a card insertion.

+

See also

pkcs15-tool(1) -


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

+


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card. -

Options

+

Options

--idesp, -i @@ -173,8 +185,12 @@ The default is do not enter pin

--reader number, -r number -

Specify the reader number to use. - The default is reader 0.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--driver driver, -c driver

Specify the card driver driver to use. @@ -187,16 +203,16 @@

Causes dnie-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

See also

opensc(7)

Authors

dnie-tool was written by +

See also

opensc(7)

Authors

dnie-tool was written by Juan Antonio Martinez .


Name

eidenv — utility for accessing visible data from - electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

+ electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

The eidenv utility is used for accessing data from electronic identity cards (like national eID cards) which might not be present in PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -213,8 +229,11 @@ --reader num, -r num

- Use the given reader. The default is the first reader with a card. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--stats, -t

Prints key usage statistics @@ -226,11 +245,11 @@ --wait, -w

Wait for a card to be inserted

-

Authors

eidenv utility was written by - Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

+

Authors

eidenv utility was written by + Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

The gids-tool utility can be used from the command line to perform miscellaneous smart card operations on a GIDS smart card. -

Options

+

Options

-X, --initialize @@ -252,8 +271,12 @@

Define the new administrator key.

--reader argument, -r argument -

Uses reader number - argument.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

-w, --wait

Wait for a card to be inserted.

@@ -261,13 +284,13 @@ --verbose

Verbose operation. Use several times to enable debug output.

-

See also

+

See also

opensc-tool(1) -


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the +


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

+ the initial PUK-value.

Options

--help, -h @@ -286,15 +309,20 @@

Specifies the current value of the local PIN1 (aka local PUK).

--reader number, -r number -

Use smart card in specified reader. Default is reader 0.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

-v

Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 +

PIN format

With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -336,17 +364,21 @@

This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

-

See also

+

See also

opensc-explorer(1) -

Authors

netkey-tool was written by +

Authors

netkey-tool was written by Peter Koch .


Name

iasecc-tool — displays information about IAS/ECC card -

Synopsis

iasecc-tool [OPTIONS]

Description

+

Synopsis

iasecc-tool [OPTIONS]

Description

The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards. -

Options

+

Options

--reader number, -

Specify the reader number number to use. - The default is reader 0.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--list-applications,

Get list of the on-card applications.

--aid hex-aid, @@ -363,7 +395,7 @@

Causes iasecc-tool to wait for the token to be inserted into reader.


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+ and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -371,7 +403,7 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -399,8 +431,11 @@ --reader num, -r num

- Use the given reader. The default is the first reader with a card. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verify pintype

Verify PIN (CHV1, CHV2 or CHV3). @@ -437,12 +472,12 @@

Wait for a card to be inserted.

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the +

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

+ the initial PUK-value.

Options

--help, -h @@ -461,15 +496,20 @@

Specifies the current value of the local PIN1 (aka local PUK).

--reader number, -r number -

Use smart card in specified reader. Default is reader 0.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

-v

Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 +

PIN format

With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -511,11 +551,11 @@

This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

-

See also

+

See also

opensc-explorer(1) -

Authors

netkey-tool was written by +

Authors

netkey-tool was written by Peter Koch .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+ and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -523,7 +563,7 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -551,8 +591,11 @@ --reader num, -r num

- Use the given reader. The default is the first reader with a card. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verify pintype

Verify PIN (CHV1, CHV2 or CHV3). @@ -589,12 +632,12 @@

Wait for a card to be inserted.

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

+

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

The opensc-tool utility can be used from the command line to perform miscellaneous smart card operations such as getting the card ATR or sending arbitrary APDU commands to a card. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -606,6 +649,8 @@ -c driver

Use the given card driver. The default is auto-detected.

+ --list-algorithms, +

Lists algorithms supported by card

--info, -i

Print information about OpenSC, such as version and enabled components.

@@ -621,10 +666,20 @@ --name, -n

Print the name of the inserted card (driver).

+ --get-conf-entry conf, + -G conf +

Get configuration key, format: section:name:key

+ --set-conf-entry conf, + -S conf +

Get configuration key, format: section:name:key:value

--reader num, -r num -

Use the given reader number. - The default is 0, the first reader in the system.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--reset[=type],

Resets the card in reader. The default reset type is cold, but warm reset is also possible.

@@ -642,17 +697,17 @@ --wait, -w

Wait for a card to be inserted.

-

See also

+

See also

opensc-explorer(1)


Name

opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

+

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

The opensc-explorer utility can be used interactively to perform miscellaneous operations such as exploring the contents of or sending arbitrary APDU commands to a smart card or similar security token. -

Options

+

Options

The following are the command-line options for opensc-explorer. There are additional interactive commands available once it is running. @@ -674,9 +729,11 @@ --reader num, -r num

- Use the given reader number. The default - is 0, the first reader in the system. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verbose, -v

Causes opensc-explorer to be more @@ -685,7 +742,7 @@

--wait, -w

Wait for a card to be inserted

-

Commands

+

Commands

The following commands are supported at opensc-explorer's interactive prompt or in script files passed via the command line parameter SCRIPT. @@ -859,15 +916,15 @@

sm [open]|[close]

Calls the card's open or close Secure Messaging handler.

-

See also

+

See also

opensc-tool(1) -


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

+


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. -

Options

+

Options

--serial

Print the card serial number derived from the CHUID object, @@ -906,7 +963,7 @@ without leading 0x. Example: CHUID object is 3000

--cert ref, - -s ref + -C ref

Load a certificate onto the card. ref is 9A, 9C, 9D or @@ -935,8 +992,12 @@ This option may be repeated.

--reader num, -r num -

Use the given reader number. The default is - 0, the first reader in the system.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--card-driver driver, -c driver

Use the given card driver. @@ -949,15 +1010,15 @@

Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

See also

+

See also

opensc-tool(1) -


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

+


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--attr-from filename

Extract information from filename @@ -1182,7 +1243,7 @@ --generate-random num

Get num bytes of random data.

-

Examples

+

Examples

To list all certificates on the smart card:

pkcs11-tool --list-objects --type cert

@@ -1198,12 +1259,12 @@ using the private key with ID ID and using the RSA-PKCS mechanism:

pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

-


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

+


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 compliant smart card. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1255,14 +1316,21 @@

Outputs raw 8 bit data.

--reader N, -r N -

Selects the N-th smart - card reader configured by the system. If unspecified, - pkcs15-crypt will use the first reader - found.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

+ --md5 --sha-1 -

This option tells pkcs15-crypt - that the input file is the result of an SHA1 hash operation, - rather than an MD5 hash. Again, the data must be in binary + --sha-224 + --sha-256 + --sha-384 + --sha-512 +

These options tell pkcs15-crypt + that the input file is the result of the specified hash operation. + By default, an MD5 hash is expected. Again, the data must be in binary representation.

--sign, -s @@ -1284,22 +1352,26 @@ Possible values are 'rs'(default) -- two concatenated integers (PKCS#11), 'sequence' or 'openssl' -- DER encoded sequence of two integers (OpenSSL).

+ --wait, + -w +

Causes pkcs15-crypt to + wait for a card insertion.

--verbose, -v

Causes pkcs15-crypt to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

-

See also

+

See also

pkcs15-init(1), pkcs15-tool(1) -


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

+


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles.

The profile used by default is pkcs15. Alternative profiles can be specified via the -p switch. -

PIN Usage

+

PIN Usage

pkcs15-init can be used to create a PKCS #15 structure on your smart card, create PINs, and install keys and certificates on the card. This process is also called personalization. @@ -1331,7 +1403,7 @@ are protected and cannot be parsed without authentication (usually with User PIN). This authentication need to be done immediately after the card binding. In such cases --verify-pin has to be used. -

Modes of operation

Initialization

This is the first step during card personalization, and will create the +

Modes of operation

Initialization

This is the first step during card personalization, and will create the basic files on the card. To create the initial PKCS #15 structure, invoke the utility as

@@ -1341,7 +1413,7 @@

If the card supports it, you should erase the contents of the card with pkcs15-init --erase-card before creating the PKCS#15 structure. -

User PIN Installation

+

User PIN Installation

Before installing any user objects such as private keys, you need at least one PIN to protect these objects. you can do this using

@@ -1355,7 +1427,7 @@

To set a label for this PIN object (which can be used by applications to display a meaningful prompt to the user), use the --label command line option. -

Key generation

+

Key generation

pkcs15-init lets you generate a new key and store it on the card. You can do this using:

@@ -1373,7 +1445,7 @@ In addition to storing the private portion of the key on the card, pkcs15-init will also store the the public portion of the key as a PKCS #15 public key object. -

Private Key Upload

+

Private Key Upload

You can use a private key generated by other means and upload it to the card. For instance, to upload a private key contained in a file named okir.pem, which is in PEM format, you would use @@ -1385,11 +1457,11 @@ key as a PKCS #15 public key object.

Note that usage of --id option in the pkcs15-init - commands to generate or to import a new key is deprecated. - Better practice is to let the middleware to derive the identifier from the key material. - (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). - This allows easily set up relation between 'related' objects - (private/public keys and certificates). + commands to generate or to import a new key is deprecated. + Better practice is to let the middleware to derive the identifier from the key material. + (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). + This allows easily set up relation between 'related' objects + (private/public keys and certificates).

In addition to the PEM key file format, pkcs15-init also supports DER encoded keys, and PKCS #12 files. The latter is the file format @@ -1397,7 +1469,7 @@ a file. A PKCS #12 file usually contains the X.509 certificate corresponding to the private key. If that is the case, pkcs15-init will store the certificate instead of the public key portion. -

Public Key Upload

+

Public Key Upload

You can also upload individual public keys to the card using the --store-public-key option, which takes a filename as an argument. This file is supposed to contain the public key. If you don't @@ -1408,12 +1480,12 @@ Since the corresponding public keys are always uploaded automatically when generating a new key, or when uploading a private key, you will probably use this option only very rarely. -

Certificate Upload

+

Certificate Upload

You can upload certificates to the card using the --store-certificate option, which takes a filename as an argument. This file is supposed to contain the PEM encoded X.509 certificate. -

Uploading PKCS #12 bags

+

Uploading PKCS #12 bags

Most browsers nowadays use PKCS #12 format files when you ask them to export your key and certificate to a file. pkcs15-init is capable of parsing these files, and storing their contents on the @@ -1427,7 +1499,7 @@ and protect it with the PIN referenced by authentication ID 01. It will also store any X.509 certificates contained in the file, which is usually the user certificate that goes with the key, as well as the CA certificate. -

Secret Key Upload

+

Secret Key Upload

You can use a secret key generated by other means and upload it to the card. For instance, to upload an AES-secret key generated by the system random generator you would use @@ -1436,10 +1508,10 @@

By default a random ID is generated for the secret key. You may specify an ID with the --id if needed. -

Options

+

Options

- --version, -

Print the OpenSC package release version.

+ --version, +

Print the OpenSC package release version.

--card-profile name, -c name

@@ -1452,6 +1524,10 @@ This tells pkcs15-init to create a PKCS #15 structure on the card, and initialize any PINs.

+ --serial SERIAL +

+ Specify the serial number of the card. +

--erase-card, -E

@@ -1459,6 +1535,11 @@ if the card supports it. If the card does not support erasing, pkcs15-init will fail.

+ --erase-application AID +

+ This will erase the application with the application identifier + AID. +

--generate-key keyspec, -G keyspec

@@ -1468,11 +1549,11 @@ optionally followed by a slash and the length of the key in bits. It is a good idea to specify the key ID along with this command, using the id option, otherwise an intrinsic ID - will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. - For the multi-application cards the target PKCS#15 application can be - specified by the hexadecimal AID value of the aid option. + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the aid option.

--options-file filename

@@ -1480,10 +1561,10 @@ from filename. The file is supposed to contain one long option per line, without the leading dashes, for instance: -

-	pin		frank
-	puk		zappa
-

+

+								pin		1234
+								puk		87654321
+							

You can specify --options-file several times.

@@ -1505,6 +1586,10 @@ options file specified with --options-file.

+ --no-so-pin, +

+ Do not install a SO PIN, and do not prompt for it. +

--profile name, -p name

@@ -1535,13 +1620,18 @@ Tells pkcs15-init to store the certificate given in filename on the card, creating a certificate object with the ID specified via the --id option. - Without supplied ID an intrinsic ID will be calculated from the - certificate's public key. Look the description of the 'pkcs15-id-style' - attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. + Without supplied ID an intrinsic ID will be calculated from the + certificate's public key. Look the description of the 'pkcs15-id-style' + attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. The file is assumed to contain the PEM encoded certificate. - For the multi-application cards the target application can be specified - by the hexadecimal AID value of the aid option. + For the multi-application cards the target application can be specified + by the hexadecimal AID value of the aid option. +

+ --store-pin, + -P +

+ Store a new PIN/PUK on the card.

--store-public-key filename

@@ -1561,11 +1651,11 @@ formats can be specified using --format. It is a good idea to specify the key ID along with this command, using the --id option, otherwise an intrinsic ID - will be calculated from the key material. Look the description of - the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details - about the algorithm used to calculate intrinsic ID. - For the multi-application cards the target PKCS#15 application can be - specified by the hexadecimal AID value of the aid option. + will be calculated from the key material. Look the description of + the 'pkcs15-id-style' attribute in the 'pkcs15.profile' for the details + about the algorithm used to calculate intrinsic ID. + For the multi-application cards the target PKCS#15 application can be + specified by the hexadecimal AID value of the aid option.

--store-secret-key filename,

@@ -1573,20 +1663,61 @@ secret key to the card. The file is assumed to contain the raw key. They key type should be specified with --secret-key-algorithm option. +

You may additionally specify the key ID along with this command, using the --id option, otherwise a random ID is generated. For the multi-application cards the target PKCS#15 application can be specified by the hexadecimal AID value of the aid option.

+ --store-data filename, + -W filename +

+ Store a data object. +

--update-certificate filename, -U filename

Tells pkcs15-init to update the certificate object with the ID specified via the --id option - with the certificate in filename. + with the certificate in filename. The file is assumed to contain a PEM encoded certificate.

Pay extra attention when updating mail decryption certificates, as - missing certificates can render e-mail messages unreadable! + missing certificates can render e-mail messages unreadable! +

+ --delete-objects arg, + -D arg +

+ Tells pkcs15-init to delete the + specified object. arg + is comma-separated list containing any of + privkey, pubkey, + secrkey, cert, + chain or data. +

+ When data is specified, an + ---application-id must also be + specified, in the other cases an + --id must also be specified +

+ When chain is specified, the + certificate chain starting with the cert with + specified ID will be deleted, until there's a CA + certificate that certifies another cert on the card +

+ --change-attributes arg, + -A arg +

+ Tells pkcs15-init to change the + specified attribute. arg + is either privkey, + pubkey, secrkey, + cert or data. + You also have to specify the --id + of the object. + For now, you can only change the --label, e.g: +

+								pkcs15-init -A cert --id 45 -a 1 --label Jim
+							

--use-default-transport-keys, -T @@ -1594,24 +1725,136 @@ Tells pkcs15-init to not ask for the transport keys and use default keys, as known by the card driver.

+ --sanity-check, + -T +

+ Tells pkcs15-init to perform a + card specific sanity check and possibly update + procedure. +

+ --reader num, + -r num +

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--verbose, -v

Causes pkcs15-init to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

+ --wait, + -w +

Causes pkcs15-init to + wait for a card insertion.

--use-pinpad -

Do not prompt the user; if no PINs supplied, pinpad will be used.

-

See also

+

Do not prompt the user; if no PINs supplied, pinpad will be used.

+ --puk-id ID +

+ Specify ID of PUK to use/create +

+ --puk-label LABEL +

+ Specify label of PUK +

+ --public-key-label LABEL +

+ Specify public key label (use with --generate-key) +

+ --cert-label LABEL +

+ Specify user cert label (use with --store-private-key) +

+ --application-name arg +

+ Specify application name of data object (use with --store-data-object) +

+ --aid AID +

+ Specify AID of the on-card PKCS#15 application to be binded to (in hexadecimal form) +

+ --output-file filename + -o filename, +

+ Output public portion of generated key to file +

+ --passphrase PASSPHRASE +

+ Specify passphrase for unlocking secret key +

+ --authority +

+ Mark certificate as a CA certificate +

+ --key-usage arg + -u arg, +

+ Specifies the X.509 key usage. + arg is comma-separated + list containing any of + digitalSignature, + nonRepudiation, + keyEncipherment, + dataEncipherment, + keyAgreement, + keyCertSign, + cRLSign. Abbreviated names are + allowed if unique (e.g. + dataEnc). +

+ The alias sign is equivalent to + digitalSignature,keyCertSign,cRLSign +

+ The alias decrypt is equivalent to + keyEncipherment,dataEncipherment +

+ --finalize + -F, +

+ Finish initialization phase of the smart card +

+ --update-last-update +

+ Update 'lastUpdate' attribute of tokenInfo +

+ --ignore-ca-certificates +

+ When storing PKCS#12 ignore CA certificates +

+ --update-existing +

+ Store or update existing certificate +

+ --extractable +

+ Private key stored as an extractable key +

+ --insecure +

+ Insecure mode: do not require a PIN for private key +

+ --md-container-guid GUID +

+ For a new key specify GUID for a MD container +

+ --help + -h, +

+ Display help message +

+

See also

pkcs15-profile(5)


Name

pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

+ on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1628,8 +1871,10 @@ --dump, -D

List all card objects.

+ --list-info +

List card objects.

--list-applications -

List the on-card PKCS#15 applications

+

List the on-card PKCS#15 applications.

--list-certificates, -c

List all certificates stored on the token.

@@ -1647,6 +1892,13 @@ algorithm). Actual private key values are not displayed. For some cards the PKCS#15 attributes of the private keys are protected for reading and need the authentication with the User PIN. + In such a case the --verify-pin option has to be used.

+ --list-secret-keys +

List all secret (symmetric) keys stored on the token. General + information about each secret key is listed (eg. key name, id and + algorithm). Actual secret key values are not displayed. + For some cards the PKCS#15 attributes of the private keys are protected for reading + and need the authentication with the User PIN. In such a case the --verify-pin option has to be used.

--list-pins

List all PINs stored on the token. General information @@ -1703,10 +1955,19 @@ --rfc4716

When used in conjunction with option --read-ssh-key the output format of the public key follows rfc4716.

The default output format is a single line (openssh).

+ --test-update, + -T, +

Test if the card needs a security update

+ --update, + -U, +

Update the card with a security update

--reader num -

Forces pkcs15-tool to use reader - number num for operations. The default is to use - reader number 0, the first reader in the system.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--unblock-pin, -u

Unblocks a PIN stored on the token. Knowledge of the @@ -1716,20 +1977,33 @@

Causes pkcs15-tool to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

+ --pin PIN +

Specify PIN

+ --puk PUK +

Specify Unblock PIN

+ --new-pin PIN +

Specify New PIN (when changing or unblocking)

--verify-pin

Verify PIN after card binding and before issuing any command (without 'auth-id' the first non-SO, non-Unblock PIN will be verified)

+ --test-session-pin +

Equivalent to --verify-pin + with additional session PIN generation

+ --wait, + -w +

Causes pkcs15-tool to + wait for a card insertion.

--use-pinpad

Do not prompt the user; if no PINs supplied, pinpad will be used.

-

See also

+

See also

pkcs15-init(1), pkcs15-crypt(1) -


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

+


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. -

Options

+

Options

--initialize, -X @@ -1787,8 +2061,12 @@

Define the token label to be used in --initialize.

--reader num, -r num -

Use the given reader number. The default is - 0, the first reader in the system.

+

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--wait, -w

Wait for a card to be inserted

@@ -1797,15 +2075,15 @@

Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

+

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

opensc-tool(1)


Name

westcos-tool — utility for manipulating data structures - on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

+ on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, keys and certificates stored on the card / token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--change-pin, -n @@ -1865,8 +2143,11 @@ --reader num, -r num

- Use the given reader. The default is the first reader with a card. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

--unblock-pin, -u

Unblocks a PIN stored on the card. Knowledge of the @@ -1884,8 +2165,8 @@ from disk to card. On the card the file is written in filename. User authentication is required for this operation.

-

Authors

westcos-tool was written by - Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

+

Authors

westcos-tool was written by + Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

The pkcs15-init utility for PKCS #15 smart card personalization is controlled via profiles. When starting, it will read two such profiles at the moment, a generic application profile, and a card @@ -1901,10 +2182,10 @@ The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ -

Syntax

+

Syntax

This section should contain information about the profile syntax. Will add this soonishly. -

See also

+

See also

pkcs15-init(1), pkcs15-crypt(1)

diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index d0a4cd4737..f671d8ce35 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -151,9 +151,14 @@ num, num - - Use the given reader. The default is the first reader with a card. - + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + +
diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 069197476d..1ce79f45d0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -2574,7 +2574,7 @@ parse_objects(const char *list, unsigned int action) } } if (del_flags[n].name == NULL) { - fprintf(stderr, "Unknown argument for --delete_objects: %.*s\n", len, list); + fprintf(stderr, "Unknown argument for --delete-objects: %.*s\n", len, list); exit(0); } list += len; From 1798bbe692a8de20d5a30827b7b52df7f17ea9e4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 8 May 2018 08:25:15 +0200 Subject: [PATCH 0246/4321] manuals: added missing "Authors" section --- doc/tools/cardos-tool.1.xml | 6 + doc/tools/cryptoflex-tool.1.xml | 6 + doc/tools/dnie-tool.1.xml | 4 - doc/tools/gids-tool.1.xml | 6 + doc/tools/iasecc-tool.1.xml | 6 + doc/tools/opensc-explorer.1.xml | 810 ++++++++++++++++---------------- doc/tools/opensc-tool.1.xml | 6 + doc/tools/piv-tool.1.xml | 6 + doc/tools/pkcs11-tool.1.xml | 6 + doc/tools/pkcs15-crypt.1.xml | 6 + doc/tools/pkcs15-init.1.xml | 10 +- doc/tools/pkcs15-tool.1.xml | 6 + doc/tools/sc-hsm-tool.1.xml | 6 + doc/tools/tools.html | 516 ++++++++++---------- src/libopensc/card-piv.c | 3 +- src/tools/piv-tool.c | 2 +- 16 files changed, 742 insertions(+), 663 deletions(-) diff --git a/doc/tools/cardos-tool.1.xml b/doc/tools/cardos-tool.1.xml index 9f384c8969..626571108b 100644 --- a/doc/tools/cardos-tool.1.xml +++ b/doc/tools/cardos-tool.1.xml @@ -88,4 +88,10 @@ smart cards and similar security tokens based on Siemens Card/OS M4. + + + Authors + cardos-tool was written by + Andreas Jellinghaus aj@dungeon.inka.de. + diff --git a/doc/tools/cryptoflex-tool.1.xml b/doc/tools/cryptoflex-tool.1.xml index 78428c61bb..f34a3c00bd 100644 --- a/doc/tools/cryptoflex-tool.1.xml +++ b/doc/tools/cryptoflex-tool.1.xml @@ -185,4 +185,10 @@ + + Authors + cryptoflex-tool was written by + Juha Yrjölä juha.yrjola@iki.fi. + + diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index 59f68b1d1c..2885446cc0 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -124,10 +124,6 @@ to enable debug output in the opensc library. - - See also - opensc(7) - Authors dnie-tool was written by diff --git a/doc/tools/gids-tool.1.xml b/doc/tools/gids-tool.1.xml index 7f4c076be8..ee1a5cac4c 100644 --- a/doc/tools/gids-tool.1.xml +++ b/doc/tools/gids-tool.1.xml @@ -120,4 +120,10 @@ + + Authors + gids-tool was written by + Vincent Le Toux vincent.letoux@mysmartlogon.com. + + diff --git a/doc/tools/iasecc-tool.1.xml b/doc/tools/iasecc-tool.1.xml index 59ee1b1d24..cc7a14b326 100644 --- a/doc/tools/iasecc-tool.1.xml +++ b/doc/tools/iasecc-tool.1.xml @@ -84,4 +84,10 @@ + + + Authors + iasecc-tool was written by + Viktor Tarasov viktor.tarasov@gmail.com. + diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 254597263f..662cd80aca 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -97,408 +97,408 @@ - - Commands - - The following commands are supported at opensc-explorer's - interactive prompt or in script files passed via the command line parameter - SCRIPT. - - - - apdu hex-data - - - Send a custom APDU command hex-data. - - - - - - asn1 file-id - - Parse and print the ASN.1 encoded content of the file specified by - file-id. - - - - - cat [file-id | sfi:short-id] - - Print the contents of the currently selected EF or the contents - of a file specified by file-id or the short file id - short-id. - - - - - - cd {.. | file-id | aid:DF-name} - - - Change to another DF specified by the argument passed. - If the argument given is .., then move up one level in the - file system hierarchy. - If it is file-id, which must be a DF directly - beneath the current DF, then change to that DF. - If it is an application identifier given as - aid:DF-name, - then jump to the MF of the application denoted by - DF-name. - - - - - - change CHVpin-ref [[old-pin] new-pin] - - - Change a PIN, where pin-ref is the PIN reference. - - Examples: - - - change CHV2 00:00:00:00:00:00 "foobar" - - Change PIN CHV2 - to the new value foobar, - giving the old value 00:00:00:00:00:00. - - - - change CHV2 "foobar" - - Set PIN CHV2 - to the new value foobar. - - - - change CHV2 - - Change PIN CHV2 using the card reader's pinpad. - - - - - - - - - - create file-id size - - Create a new EF. file-id specifies the - id number and size is the size of the new file. - - - - - - debug [level] - - - Set OpenSC debug level to level. - If level is omitted the current debug level will be shown. - - - - - - delete file-id - - Remove the EF or DF specified by file-id - - - - - do_get hex-tag [output] - - - Copy the internal card's 'tagged' data into the local file. - The local file is specified by output while the tag of - the card's data is specified by hex-tag. - - - If output is omitted, the name of the output file will be - derived from hex-tag. - - - - - - - do_put hex-tag input - - - Update internal card's 'tagged' data. - hex-tag is the tag of the card's data. - input is the filename of the source file or the literal data presented as - a sequence of hexadecimal values or " enclosed string. - - - - - - - echo string ... - - - Print the strings given. - - - - - - erase - - Erase the card, if the card supports it. - - - - - get file-id [output] - - - Copy an EF to a local file. The local file is specified - by output while the card file is specified by file-id. - - - If output is omitted, the name of the output file will be - derived from the full card path to file-id. - - - - - - - info [file-id] - - Display attributes of a file specified by file-id. - If file-id is not supplied, - the attributes of the current file are printed. - - - - - ls [pattern ...] - - List files in the current DF. - If no pattern is given, then all files are listed. - If one ore more patterns are given, only files matching - at least one pattern are listed. - - - - - find [start-id [end-id]] - - Find all files in the current DF. - Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF). - - - - - find_tags [start-tag [end-tag]] - - Find all tags of data objects in the current context. - Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF). - - - - - mkdir file-id size - - Create a DF. file-id specifies the id number - and size is the size of the new file. - - - - - put file-id input - - Copy a local file to the card. The local file is specified - by input while the card file is specified by file-id. - - - - - - quit - - Exit the program. - - - - - random count - - - Generate random sequence of count bytes. - - - - - - rm file-id - - Remove the EF or DF specified by file-id - - - - - unblock CHVpin-ref [puk [new pin]] - - - - Unblock the PIN denoted by pin-ref - using the PUK puk, and set potentially - change its value to new pin. - - - PUK and PIN values can be a sequence of hexadecimal values, - "-enclosed strings, empty (""), - or absent. - If they are absent, the values are read from the card reader's pin pad. - - - Examples: - - - unblock CHV2 00:00:00:00:00:00 "foobar" - - Unblock PIN CHV2 using PUK - 00:00:00:00:00:00 - and set it to the new value foobar. - - - - unblock CHV2 00:00:00:00:00:00 "" - - Unblock PIN CHV2 using PUK - 00:00:00:00:00:00 keeping the old value. - - - - unblock CHV2 "" "foobar" - - Set new value of PIN CHV2 - to foobar. - - - - unblock CHV2 00:00:00:00:00:00 - - Unblock PIN CHV2 using PUK - 00:00:00:00:00:00. - The new PIN value is prompted by pinpad. - - - - unblock CHV2 "" - - Set PIN CHV2. - The new PIN value is prompted by pinpad. - - - - unblock CHV2 - - Unblock PIN CHV2. - The unblock code and new PIN value are prompted by pinpad. - - - - - - - - - - update_binary file-id offs data - - - Binary update of the file specified by - file-id with the literal data - data starting from offset specified - by offs. - data can be supplied as a sequencer - of the hex values or as a " enclosed string. - - - - - - update_record file-id rec-nr rec-offs data - - - Update record specified by rec-nr of the file - specified by file-id with the literal data - data starting from offset specified by - rec-offs. - data can be supplied as a sequence of the hex values or - as a " enclosed string. - - - - - - verify key-type key-id [key] - - Present a PIN or key to the card, where - key-type can be one of CHV, - KEY, AUT or PRO. - key-id is a number representing the key or PIN reference. - key is the key or PIN to be verified, formatted as a - colon-separated list of hex values or a " enclosed string. - - - If key is omitted, the exact action depends on the - card reader's features: if the card readers supports PIN input via a pin pad, - then the PIN will be verified using the card reader's pin pad. - If the card reader does not support PIN input, then the PIN will be asked - interactively. - - - Examples: - - - verify CHV0 31:32:33:34:00:00:00:00 - - Verify CHV2 using the hex value - 31:32:33:34:00:00:00:00 - - - - verify CHV1 "secret" - - Verify CHV1 - using the string value secret. - - - - verify KEY2 - - Verify KEY2, - get the value from the card reader's pin pad. - - - - - - - - - - sm [open]|[close] - - - Calls the card's open or close Secure Messaging handler. - - - - - - + + Commands + + The following commands are supported at opensc-explorer's + interactive prompt or in script files passed via the command line parameter + SCRIPT. + + + + apdu hex-data + + + Send a custom APDU command hex-data. + + + + + + asn1 file-id + + Parse and print the ASN.1 encoded content of the file specified by + file-id. + + + + + cat [file-id | sfi:short-id] + + Print the contents of the currently selected EF or the contents + of a file specified by file-id or the short file id + short-id. + + + + + + cd {.. | file-id | aid:DF-name} + + + Change to another DF specified by the argument passed. + If the argument given is .., then move up one level in the + file system hierarchy. + If it is file-id, which must be a DF directly + beneath the current DF, then change to that DF. + If it is an application identifier given as + aid:DF-name, + then jump to the MF of the application denoted by + DF-name. + + + + + + change CHVpin-ref [[old-pin] new-pin] + + + Change a PIN, where pin-ref is the PIN reference. + + Examples: + + + change CHV2 00:00:00:00:00:00 "foobar" + + Change PIN CHV2 + to the new value foobar, + giving the old value 00:00:00:00:00:00. + + + + change CHV2 "foobar" + + Set PIN CHV2 + to the new value foobar. + + + + change CHV2 + + Change PIN CHV2 using the card reader's pinpad. + + + + + + + + + + create file-id size + + Create a new EF. file-id specifies the + id number and size is the size of the new file. + + + + + + debug [level] + + + Set OpenSC debug level to level. + If level is omitted the current debug level will be shown. + + + + + + delete file-id + + Remove the EF or DF specified by file-id + + + + + do_get hex-tag [output] + + + Copy the internal card's 'tagged' data into the local file. + The local file is specified by output while the tag of + the card's data is specified by hex-tag. + + + If output is omitted, the name of the output file will be + derived from hex-tag. + + + + + + + do_put hex-tag input + + + Update internal card's 'tagged' data. + hex-tag is the tag of the card's data. + input is the filename of the source file or the literal data presented as + a sequence of hexadecimal values or " enclosed string. + + + + + + + echo string ... + + + Print the strings given. + + + + + + erase + + Erase the card, if the card supports it. + + + + + get file-id [output] + + + Copy an EF to a local file. The local file is specified + by output while the card file is specified by file-id. + + + If output is omitted, the name of the output file will be + derived from the full card path to file-id. + + + + + + + info [file-id] + + Display attributes of a file specified by file-id. + If file-id is not supplied, + the attributes of the current file are printed. + + + + + ls [pattern ...] + + List files in the current DF. + If no pattern is given, then all files are listed. + If one ore more patterns are given, only files matching + at least one pattern are listed. + + + + + find [start-id [end-id]] + + Find all files in the current DF. + Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF). + + + + + find_tags [start-tag [end-tag]] + + Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF). + + + + + mkdir file-id size + + Create a DF. file-id specifies the id number + and size is the size of the new file. + + + + + put file-id input + + Copy a local file to the card. The local file is specified + by input while the card file is specified by file-id. + + + + + + quit + + Exit the program. + + + + + random count + + + Generate random sequence of count bytes. + + + + + + rm file-id + + Remove the EF or DF specified by file-id + + + + + unblock CHVpin-ref [puk [new pin]] + + + + Unblock the PIN denoted by pin-ref + using the PUK puk, and set potentially + change its value to new pin. + + + PUK and PIN values can be a sequence of hexadecimal values, + "-enclosed strings, empty (""), + or absent. + If they are absent, the values are read from the card reader's pin pad. + + + Examples: + + + unblock CHV2 00:00:00:00:00:00 "foobar" + + Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 + and set it to the new value foobar. + + + + unblock CHV2 00:00:00:00:00:00 "" + + Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 keeping the old value. + + + + unblock CHV2 "" "foobar" + + Set new value of PIN CHV2 + to foobar. + + + + unblock CHV2 00:00:00:00:00:00 + + Unblock PIN CHV2 using PUK + 00:00:00:00:00:00. + The new PIN value is prompted by pinpad. + + + + unblock CHV2 "" + + Set PIN CHV2. + The new PIN value is prompted by pinpad. + + + + unblock CHV2 + + Unblock PIN CHV2. + The unblock code and new PIN value are prompted by pinpad. + + + + + + + + + + update_binary file-id offs data + + + Binary update of the file specified by + file-id with the literal data + data starting from offset specified + by offs. + data can be supplied as a sequencer + of the hex values or as a " enclosed string. + + + + + + update_record file-id rec-nr rec-offs data + + + Update record specified by rec-nr of the file + specified by file-id with the literal data + data starting from offset specified by + rec-offs. + data can be supplied as a sequence of the hex values or + as a " enclosed string. + + + + + + verify key-type key-id [key] + + Present a PIN or key to the card, where + key-type can be one of CHV, + KEY, AUT or PRO. + key-id is a number representing the key or PIN reference. + key is the key or PIN to be verified, formatted as a + colon-separated list of hex values or a " enclosed string. + + + If key is omitted, the exact action depends on the + card reader's features: if the card readers supports PIN input via a pin pad, + then the PIN will be verified using the card reader's pin pad. + If the card reader does not support PIN input, then the PIN will be asked + interactively. + + + Examples: + + + verify CHV0 31:32:33:34:00:00:00:00 + + Verify CHV2 using the hex value + 31:32:33:34:00:00:00:00 + + + + verify CHV1 "secret" + + Verify CHV1 + using the string value secret. + + + + verify KEY2 + + Verify KEY2, + get the value from the card reader's pin pad. + + + + + + + + + + sm [open]|[close] + + + Calls the card's open or close Secure Messaging handler. + + + + + + See also @@ -510,4 +510,10 @@ + + Authors + opensc-explorer was written by + Juha Yrjölä juha.yrjola@iki.fi. + + diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index 4f7cf2207d..7399096e94 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -175,4 +175,10 @@ + + Authors + opensc-tool was written by + Juha Yrjölä juha.yrjola@iki.fi. + + diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 397d0ac851..234c3c823c 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -201,4 +201,10 @@ + + Authors + piv-tool was written by + Douglas E. Engert deengert@gmail.com. + + diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index fedfdab02f..37093f352c 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -581,4 +581,10 @@ + + Authors + pkcs11-tool was written by + Olaf Kirch okir@suse.de. + + diff --git a/doc/tools/pkcs15-crypt.1.xml b/doc/tools/pkcs15-crypt.1.xml index f3dcf64b1d..6bc6b90e9d 100644 --- a/doc/tools/pkcs15-crypt.1.xml +++ b/doc/tools/pkcs15-crypt.1.xml @@ -224,4 +224,10 @@ + + Authors + pkcs15-crypt was written by + Juha Yrjölä juha.yrjola@iki.fi. + + diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 0234de0c05..9b520187f1 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -357,8 +357,8 @@ contain one long option per line, without the leading dashes, for instance: - pin 1234 - puk 87654321 +pin 1234 +puk 87654321 @@ -921,4 +921,10 @@ + + Authors + pkcs15-init was written by + Olaf Kirch okir@suse.de. + + diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index a13eab83bd..bb224c37e2 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -380,4 +380,10 @@ + + Authors + pkcs15-tool was written by + Juha Yrjölä juha.yrjola@iki.fi. + + diff --git a/doc/tools/sc-hsm-tool.1.xml b/doc/tools/sc-hsm-tool.1.xml index ba296bdbe1..9f130e1ee2 100644 --- a/doc/tools/sc-hsm-tool.1.xml +++ b/doc/tools/sc-hsm-tool.1.xml @@ -263,4 +263,10 @@ + + Authors + sc-hsm-tool was written by + Andreas Schwier andreas.schwier@cardcontact.de. + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 882eff0e26..8e19c4d6a3 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -43,7 +43,7 @@ font-style: italic; } - -->

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them + -->

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them
cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
dnie-tool — displays information about DNIe based security tokens
eidenv — utility for accessing visible data from electronic identity cards
gids-tool — smart card utility for GIDS cards
netkey-tool — administrative utility for Netkey E4 cards
iasecc-tool — displays information about IAS/ECC card
openpgp-tool — utility for accessing visible data OpenPGP smart cards @@ -84,12 +84,13 @@ -w

Causes cardos-tool to wait for the token to be inserted into reader.

-


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

+

Authors

cardos-tool was written by + Andreas Jellinghaus .


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

cryptoflex-tool is used to manipulate PKCS data structures on Schlumberger Cryptoflex smart cards. Users can create, list and read PINs and keys stored on the smart card. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--app-df num, -a num @@ -151,11 +152,12 @@ -w

Causes cryptoflex-tool to wait for a card insertion.

-

See also

+

See also

pkcs15-tool(1) -


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

+

Authors

cryptoflex-tool was written by + Juha Yrjölä .


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card. -

Options

+

Options

--idesp, -i @@ -203,16 +205,16 @@

Causes dnie-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

See also

opensc(7)

Authors

dnie-tool was written by +

Authors

dnie-tool was written by Juan Antonio Martinez .


Name

eidenv — utility for accessing visible data from - electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

+ electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

The eidenv utility is used for accessing data from electronic identity cards (like national eID cards) which might not be present in PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -245,11 +247,11 @@ --wait, -w

Wait for a card to be inserted

-

Authors

eidenv utility was written by - Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

+

Authors

eidenv utility was written by + Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

The gids-tool utility can be used from the command line to perform miscellaneous smart card operations on a GIDS smart card. -

Options

+

Options

-X, --initialize @@ -284,13 +286,14 @@ --verbose

Verbose operation. Use several times to enable debug output.

-

See also

+

See also

opensc-tool(1) -


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the +

Authors

gids-tool was written by + Vincent Le Toux .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

+ the initial PUK-value.

Options

--help, -h @@ -318,11 +321,11 @@ -v

Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 +

PIN format

With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -364,13 +367,13 @@

This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

-

See also

+

See also

opensc-explorer(1) -

Authors

netkey-tool was written by +

Authors

netkey-tool was written by Peter Koch .


Name

iasecc-tool — displays information about IAS/ECC card -

Synopsis

iasecc-tool [OPTIONS]

Description

+

Synopsis

iasecc-tool [OPTIONS]

Description

The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards. -

Options

+

Options

--reader number,

@@ -394,8 +397,9 @@ -w

Causes iasecc-tool to wait for the token to be inserted into reader.

-


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+

Authors

iasecc-tool was written by + Viktor Tarasov .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -403,7 +407,7 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -472,12 +476,12 @@

Wait for a card to be inserted.

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the +

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

+ the initial PUK-value.

Options

--help, -h @@ -505,11 +509,11 @@ -v

Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 +

PIN format

With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -551,11 +555,11 @@

This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

-

See also

+

See also

opensc-explorer(1) -

Authors

netkey-tool was written by +

Authors

netkey-tool was written by Peter Koch .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+ and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -563,7 +567,7 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -632,12 +636,12 @@

Wait for a card to be inserted.

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

+

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

The opensc-tool utility can be used from the command line to perform miscellaneous smart card operations such as getting the card ATR or sending arbitrary APDU commands to a card. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -697,17 +701,18 @@ --wait, -w

Wait for a card to be inserted.

-

See also

+

See also

opensc-explorer(1) -


Name

opensc-explorer — +

Authors

opensc-tool was written by + Juha Yrjölä .


Name

opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

+

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

The opensc-explorer utility can be used interactively to perform miscellaneous operations such as exploring the contents of or sending arbitrary APDU commands to a smart card or similar security token. -

Options

+

Options

The following are the command-line options for opensc-explorer. There are additional interactive commands available once it is running. @@ -742,189 +747,190 @@

--wait, -w

Wait for a card to be inserted

-

Commands

- The following commands are supported at opensc-explorer's - interactive prompt or in script files passed via the command line parameter - SCRIPT. -

- apdu hex-data -

Send a custom APDU command hex-data.

- asn1 file-id -

Parse and print the ASN.1 encoded content of the file specified by - file-id.

- cat [file-id | sfi:short-id] -

Print the contents of the currently selected EF or the contents - of a file specified by file-id or the short file id - short-id. -

- cd {.. | file-id | aid:DF-name} -

- Change to another DF specified by the argument passed. - If the argument given is .., then move up one level in the - file system hierarchy. - If it is file-id, which must be a DF directly - beneath the current DF, then change to that DF. - If it is an application identifier given as - aid:DF-name, - then jump to the MF of the application denoted by - DF-name. -

- change CHVpin-ref [[old-pin] new-pin] -

Change a PIN, where pin-ref is the PIN reference.

- Examples: -

change CHV2 00:00:00:00:00:00 "foobar"

- Change PIN CHV2 - to the new value foobar, - giving the old value 00:00:00:00:00:00. -

change CHV2 "foobar"

- Set PIN CHV2 - to the new value foobar. -

change CHV2

- Change PIN CHV2 using the card reader's pinpad. -

-

- create file-id size -

Create a new EF. file-id specifies the - id number and size is the size of the new file. -

- debug [level] -

Set OpenSC debug level to level.

If level is omitted the current debug level will be shown.

- delete file-id -

Remove the EF or DF specified by file-id

- do_get hex-tag [output] -

Copy the internal card's 'tagged' data into the local file.

The local file is specified by output while the tag of - the card's data is specified by hex-tag. -

- If output is omitted, the name of the output file will be - derived from hex-tag. -

- do_put hex-tag input -

Update internal card's 'tagged' data.

hex-tag is the tag of the card's data. - input is the filename of the source file or the literal data presented as - a sequence of hexadecimal values or " enclosed string. -

- echo string ... -

Print the strings given.

- erase -

Erase the card, if the card supports it.

- get file-id [output] -

Copy an EF to a local file. The local file is specified - by output while the card file is specified by file-id. -

- If output is omitted, the name of the output file will be - derived from the full card path to file-id. -

- info [file-id] -

Display attributes of a file specified by file-id. - If file-id is not supplied, - the attributes of the current file are printed.

- ls [pattern ...] -

List files in the current DF. - If no pattern is given, then all files are listed. - If one ore more patterns are given, only files matching - at least one pattern are listed.

- find [start-id [end-id]] -

Find all files in the current DF. - Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF).

- find_tags [start-tag [end-tag]] -

Find all tags of data objects in the current context. - Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF).

- mkdir file-id size -

Create a DF. file-id specifies the id number - and size is the size of the new file.

- put file-id input -

Copy a local file to the card. The local file is specified - by input while the card file is specified by file-id. -

- quit -

Exit the program.

- random count -

Generate random sequence of count bytes.

- rm file-id -

Remove the EF or DF specified by file-id

- unblock CHVpin-ref [puk [new pin]] -

- Unblock the PIN denoted by pin-ref - using the PUK puk, and set potentially - change its value to new pin. -

- PUK and PIN values can be a sequence of hexadecimal values, - "-enclosed strings, empty (""), - or absent. - If they are absent, the values are read from the card reader's pin pad. -

- Examples: -

unblock CHV2 00:00:00:00:00:00 "foobar"

- Unblock PIN CHV2 using PUK - 00:00:00:00:00:00 - and set it to the new value foobar. -

unblock CHV2 00:00:00:00:00:00 ""

- Unblock PIN CHV2 using PUK - 00:00:00:00:00:00 keeping the old value. -

unblock CHV2 "" "foobar"

- Set new value of PIN CHV2 - to foobar. -

unblock CHV2 00:00:00:00:00:00

- Unblock PIN CHV2 using PUK - 00:00:00:00:00:00. - The new PIN value is prompted by pinpad. -

unblock CHV2 ""

- Set PIN CHV2. - The new PIN value is prompted by pinpad. -

unblock CHV2

- Unblock PIN CHV2. - The unblock code and new PIN value are prompted by pinpad. -

-

- update_binary file-id offs data -

Binary update of the file specified by - file-id with the literal data - data starting from offset specified - by offs.

data can be supplied as a sequencer - of the hex values or as a " enclosed string.

- update_record file-id rec-nr rec-offs data -

Update record specified by rec-nr of the file - specified by file-id with the literal data - data starting from offset specified by - rec-offs.

data can be supplied as a sequence of the hex values or - as a " enclosed string.

- verify key-type key-id [key] -

Present a PIN or key to the card, where - key-type can be one of CHV, - KEY, AUT or PRO. - key-id is a number representing the key or PIN reference. - key is the key or PIN to be verified, formatted as a - colon-separated list of hex values or a " enclosed string. -

- If key is omitted, the exact action depends on the - card reader's features: if the card readers supports PIN input via a pin pad, - then the PIN will be verified using the card reader's pin pad. - If the card reader does not support PIN input, then the PIN will be asked - interactively. -

- Examples: -

verify CHV0 31:32:33:34:00:00:00:00

- Verify CHV2 using the hex value - 31:32:33:34:00:00:00:00 -

verify CHV1 "secret"

- Verify CHV1 - using the string value secret. -

verify KEY2

- Verify KEY2, - get the value from the card reader's pin pad. -

-

- sm [open]|[close] -

Calls the card's open or close Secure Messaging handler.

-

See also

+

Commands

+ The following commands are supported at opensc-explorer's + interactive prompt or in script files passed via the command line parameter + SCRIPT. +

+ apdu hex-data +

Send a custom APDU command hex-data.

+ asn1 file-id +

Parse and print the ASN.1 encoded content of the file specified by + file-id.

+ cat [file-id | sfi:short-id] +

Print the contents of the currently selected EF or the contents + of a file specified by file-id or the short file id + short-id. +

+ cd {.. | file-id | aid:DF-name} +

+ Change to another DF specified by the argument passed. + If the argument given is .., then move up one level in the + file system hierarchy. + If it is file-id, which must be a DF directly + beneath the current DF, then change to that DF. + If it is an application identifier given as + aid:DF-name, + then jump to the MF of the application denoted by + DF-name. +

+ change CHVpin-ref [[old-pin] new-pin] +

Change a PIN, where pin-ref is the PIN reference.

+ Examples: +

change CHV2 00:00:00:00:00:00 "foobar"

+ Change PIN CHV2 + to the new value foobar, + giving the old value 00:00:00:00:00:00. +

change CHV2 "foobar"

+ Set PIN CHV2 + to the new value foobar. +

change CHV2

+ Change PIN CHV2 using the card reader's pinpad. +

+

+ create file-id size +

Create a new EF. file-id specifies the + id number and size is the size of the new file. +

+ debug [level] +

Set OpenSC debug level to level.

If level is omitted the current debug level will be shown.

+ delete file-id +

Remove the EF or DF specified by file-id

+ do_get hex-tag [output] +

Copy the internal card's 'tagged' data into the local file.

The local file is specified by output while the tag of + the card's data is specified by hex-tag. +

+ If output is omitted, the name of the output file will be + derived from hex-tag. +

+ do_put hex-tag input +

Update internal card's 'tagged' data.

hex-tag is the tag of the card's data. + input is the filename of the source file or the literal data presented as + a sequence of hexadecimal values or " enclosed string. +

+ echo string ... +

Print the strings given.

+ erase +

Erase the card, if the card supports it.

+ get file-id [output] +

Copy an EF to a local file. The local file is specified + by output while the card file is specified by file-id. +

+ If output is omitted, the name of the output file will be + derived from the full card path to file-id. +

+ info [file-id] +

Display attributes of a file specified by file-id. + If file-id is not supplied, + the attributes of the current file are printed.

+ ls [pattern ...] +

List files in the current DF. + If no pattern is given, then all files are listed. + If one ore more patterns are given, only files matching + at least one pattern are listed.

+ find [start-id [end-id]] +

Find all files in the current DF. + Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF).

+ find_tags [start-tag [end-tag]] +

Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF).

+ mkdir file-id size +

Create a DF. file-id specifies the id number + and size is the size of the new file.

+ put file-id input +

Copy a local file to the card. The local file is specified + by input while the card file is specified by file-id. +

+ quit +

Exit the program.

+ random count +

Generate random sequence of count bytes.

+ rm file-id +

Remove the EF or DF specified by file-id

+ unblock CHVpin-ref [puk [new pin]] +

+ Unblock the PIN denoted by pin-ref + using the PUK puk, and set potentially + change its value to new pin. +

+ PUK and PIN values can be a sequence of hexadecimal values, + "-enclosed strings, empty (""), + or absent. + If they are absent, the values are read from the card reader's pin pad. +

+ Examples: +

unblock CHV2 00:00:00:00:00:00 "foobar"

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 + and set it to the new value foobar. +

unblock CHV2 00:00:00:00:00:00 ""

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00 keeping the old value. +

unblock CHV2 "" "foobar"

+ Set new value of PIN CHV2 + to foobar. +

unblock CHV2 00:00:00:00:00:00

+ Unblock PIN CHV2 using PUK + 00:00:00:00:00:00. + The new PIN value is prompted by pinpad. +

unblock CHV2 ""

+ Set PIN CHV2. + The new PIN value is prompted by pinpad. +

unblock CHV2

+ Unblock PIN CHV2. + The unblock code and new PIN value are prompted by pinpad. +

+

+ update_binary file-id offs data +

Binary update of the file specified by + file-id with the literal data + data starting from offset specified + by offs.

data can be supplied as a sequencer + of the hex values or as a " enclosed string.

+ update_record file-id rec-nr rec-offs data +

Update record specified by rec-nr of the file + specified by file-id with the literal data + data starting from offset specified by + rec-offs.

data can be supplied as a sequence of the hex values or + as a " enclosed string.

+ verify key-type key-id [key] +

Present a PIN or key to the card, where + key-type can be one of CHV, + KEY, AUT or PRO. + key-id is a number representing the key or PIN reference. + key is the key or PIN to be verified, formatted as a + colon-separated list of hex values or a " enclosed string. +

+ If key is omitted, the exact action depends on the + card reader's features: if the card readers supports PIN input via a pin pad, + then the PIN will be verified using the card reader's pin pad. + If the card reader does not support PIN input, then the PIN will be asked + interactively. +

+ Examples: +

verify CHV0 31:32:33:34:00:00:00:00

+ Verify CHV2 using the hex value + 31:32:33:34:00:00:00:00 +

verify CHV1 "secret"

+ Verify CHV1 + using the string value secret. +

verify KEY2

+ Verify KEY2, + get the value from the card reader's pin pad. +

+

+ sm [open]|[close] +

Calls the card's open or close Secure Messaging handler.

+

See also

opensc-tool(1) -


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

+

Authors

opensc-explorer was written by + Juha Yrjölä .


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. -

Options

+

Options

--serial

Print the card serial number derived from the CHUID object, @@ -1010,15 +1016,16 @@

Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

See also

+

See also

opensc-tool(1) -


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

+

Authors

piv-tool was written by + Douglas E. Engert .


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--attr-from filename

Extract information from filename @@ -1243,7 +1250,7 @@ --generate-random num

Get num bytes of random data.

-

Examples

+

Examples

To list all certificates on the smart card:

pkcs11-tool --list-objects --type cert

@@ -1259,12 +1266,13 @@ using the private key with ID ID and using the RSA-PKCS mechanism:

pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

-


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

+

Authors

pkcs11-tool was written by + Olaf Kirch .


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 compliant smart card. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1361,17 +1369,18 @@

Causes pkcs15-crypt to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

-

See also

+

See also

pkcs15-init(1), pkcs15-tool(1) -


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

+

Authors

pkcs15-crypt was written by + Juha Yrjölä .


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles.

The profile used by default is pkcs15. Alternative profiles can be specified via the -p switch. -

PIN Usage

+

PIN Usage

pkcs15-init can be used to create a PKCS #15 structure on your smart card, create PINs, and install keys and certificates on the card. This process is also called personalization. @@ -1403,7 +1412,7 @@ are protected and cannot be parsed without authentication (usually with User PIN). This authentication need to be done immediately after the card binding. In such cases --verify-pin has to be used. -

Modes of operation

Initialization

This is the first step during card personalization, and will create the +

Modes of operation

Initialization

This is the first step during card personalization, and will create the basic files on the card. To create the initial PKCS #15 structure, invoke the utility as

@@ -1413,7 +1422,7 @@

If the card supports it, you should erase the contents of the card with pkcs15-init --erase-card before creating the PKCS#15 structure. -

User PIN Installation

+

User PIN Installation

Before installing any user objects such as private keys, you need at least one PIN to protect these objects. you can do this using

@@ -1427,7 +1436,7 @@

To set a label for this PIN object (which can be used by applications to display a meaningful prompt to the user), use the --label command line option. -

Key generation

+

Key generation

pkcs15-init lets you generate a new key and store it on the card. You can do this using:

@@ -1445,7 +1454,7 @@ In addition to storing the private portion of the key on the card, pkcs15-init will also store the the public portion of the key as a PKCS #15 public key object. -

Private Key Upload

+

Private Key Upload

You can use a private key generated by other means and upload it to the card. For instance, to upload a private key contained in a file named okir.pem, which is in PEM format, you would use @@ -1469,7 +1478,7 @@ a file. A PKCS #12 file usually contains the X.509 certificate corresponding to the private key. If that is the case, pkcs15-init will store the certificate instead of the public key portion. -

Public Key Upload

+

Public Key Upload

You can also upload individual public keys to the card using the --store-public-key option, which takes a filename as an argument. This file is supposed to contain the public key. If you don't @@ -1480,12 +1489,12 @@ Since the corresponding public keys are always uploaded automatically when generating a new key, or when uploading a private key, you will probably use this option only very rarely. -

Certificate Upload

+

Certificate Upload

You can upload certificates to the card using the --store-certificate option, which takes a filename as an argument. This file is supposed to contain the PEM encoded X.509 certificate. -

Uploading PKCS #12 bags

+

Uploading PKCS #12 bags

Most browsers nowadays use PKCS #12 format files when you ask them to export your key and certificate to a file. pkcs15-init is capable of parsing these files, and storing their contents on the @@ -1499,7 +1508,7 @@ and protect it with the PIN referenced by authentication ID 01. It will also store any X.509 certificates contained in the file, which is usually the user certificate that goes with the key, as well as the CA certificate. -

Secret Key Upload

+

Secret Key Upload

You can use a secret key generated by other means and upload it to the card. For instance, to upload an AES-secret key generated by the system random generator you would use @@ -1508,7 +1517,7 @@

By default a random ID is generated for the secret key. You may specify an ID with the --id if needed. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1562,8 +1571,8 @@ contain one long option per line, without the leading dashes, for instance:

-								pin		1234
-								puk		87654321
+pin		1234
+puk		87654321
 							

You can specify --options-file several times. @@ -1845,16 +1854,17 @@

Display help message

-

See also

+

See also

pkcs15-profile(5) -


Name

pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

+

Authors

pkcs15-init was written by + Olaf Kirch .


Name

pkcs15-tool — utility for manipulating PKCS #15 data structures + on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1995,15 +2005,16 @@ wait for a card insertion.

--use-pinpad

Do not prompt the user; if no PINs supplied, pinpad will be used.

-

See also

+

See also

pkcs15-init(1), pkcs15-crypt(1) -


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

+

Authors

pkcs15-tool was written by + Juha Yrjölä .


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. -

Options

+

Options

--initialize, -X @@ -2075,15 +2086,16 @@

Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

+

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

opensc-tool(1) -


Name

westcos-tool — utility for manipulating data structures - on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

+

Authors

sc-hsm-tool was written by + Andreas Schwier .


Name

westcos-tool — utility for manipulating data structures + on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, keys and certificates stored on the card / token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--change-pin, -n @@ -2165,8 +2177,8 @@ from disk to card. On the card the file is written in filename. User authentication is required for this operation.

-

Authors

westcos-tool was written by - Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

+

Authors

westcos-tool was written by + Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

The pkcs15-init utility for PKCS #15 smart card personalization is controlled via profiles. When starting, it will read two such profiles at the moment, a generic application profile, and a card @@ -2182,10 +2194,10 @@ The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ -

Syntax

+

Syntax

This section should contain information about the profile syntax. Will add this soonishly. -

See also

+

See also

pkcs15-init(1), pkcs15-crypt(1)

diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 03f108884b..66b723c29a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3,8 +3,7 @@ * card-default.c: Support for cards with no driver * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2005,2006,2007,2008,2009,2010 Douglas E. Engert - * Copyright (C) 2016 Douglas E. Engert + * Copyright (C) 2005-2016 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner * diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 74635c8776..9a3645b00b 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -2,7 +2,7 @@ * piv-tool.c: Tool for accessing smart cards with libopensc * * Copyright (C) 2001 Juha Yrjölä - * Copyright (C) 2005,2010 Douglas E. Engert + * Copyright (C) 2005,2010 Douglas E. Engert * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From eb60481f89526f34478e73815ca3bd5c0238c652 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 May 2018 13:23:16 +0200 Subject: [PATCH 0247/4321] Updated NEWS for 0.18.0 --- NEWS | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ appveyor.yml | 2 +- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index be84ec7a4e..0c5d77e2c7 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,120 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.18.0; 2018-05-16 +## General Improvements +* PKCS#15 + * fixed parsing ECC parameters from TokenInfo (#1134) + * Added PKCS#15 emulator for DIN 66291 profile + * Cope with empty serial number in TokenInfo +* Build Environment + * Treat compiler warnings as errors (use `--disable-strict` to avoid) + * MacOS + * optionally use CTK in package builder + * fixed detection of OpenPACE package + * macOS High Sierra: fixed dmg creation + * fixed DNIe UI compatibility +* Windows: Use Dedicated md/pkcs11 installation folders instead of installing to System32/SysWOW64 +* fixed (possible) memory leaks for PIV, JPKI, PKCS#11, Minidriver +* fixed many issues reported via compiler warnings, coverity scan and clang's static analyzer +* beautify printed ASN.1 data, add support for ASN.1 time types +* SimpleTLV: Skip correctly two bytes after reading 2b size (#1231) +* added support for `keep_alive` commands for cards with multiple applets to be enabled via `opensc.conf` +* added support for bash completion for arguments that expect filenames +* added keyword `old` for selecting `card_drivers` via `opensc.conf` +* improved documentation manuals for OpenSC tools +* use `leave` as default for `disconnect_action` for PC/SC readers +## PKCS#11 +* Make OpenSC PKCS#11 Vendor Defined attributes, mechanisms etc unique +## Minidriver +* added CNS ATR (#1153) +* Add multiple PINs support to minidriver +* protect MD entry points with `CriticalSection` +## Tokend +* Configuration value for not propagating certificates that require user authentication (`ignore_private_certificate`) +## CryptoTokenKit +* Added support for PIN pad +* fixed codesigning of opensc tools +* Added complete support for system integration with https://github.com/frankmorgner/OpenSCToken +## OpenSC Tools +* `cardos-tool` + * List human-readable version for CardOS 5.3 +* `pkcs11-tool` + * fixed overwriting digestinfo + hash for RSA-PKCS Signature + * Enable support for RSA-PSS signatures in pkcs11-tool + * Add support for RSA-OAEP + * Fixed #1286 + * Add missing pkcs11-tool options to man page + * allow mechanism to be specified in hexadecimal + * fixed default module path on Windows to use opensc-pkcs11.dll +* `pkcs11-spy` + * Add support for RSA-OAEP + * Add support for RSA-PSS +* `pkcs15init` + * Fix rutokenS FCP parsing (#1259) +* `egk-tool` + * Read data from German Health Care Card (Elektronische Gesundheitskarte, eGK) +* `opensc-asn1` + * Parse ASN.1 from files +* `opensc-tool`/`opensc-explorer` + * Allow extended APDUs +## Authentic +* Correctly handle APDUs with more than 256 bytes (#1205) +## Coolkey +* Copy labels from certificate objects to the keys +## Common Access Card +* Fixed infinite reading of certificate +* Added support for Alt token card +## MyEID +* support for RAW RSA signature for 2048 bit keys +## IAS/ECC +* Support for new MinInt agent card +## PIV +* Get cardholder name from the first certificate if token label not specified +* implemented keep alive command (#1256) +* fixed signature creation with `CKA_ALWAYS_AUTHENTICATE` (i.e. PKCS#11 `C_Login(CKU_CONTEXT_SPECIFIC)`) +## CardOS +* fixed card name for CardOS 5 +* added ATR `"3b:d2:18:00:81:31:fe:58:c9:02:17"` +* Try forcing `max_send_size` for PSO:DEC +## DNIe +* DNIe: card also supports 1920 bits (#1247) +## GIDS +* Fix GIDS admin authentication +## epass 3000 +* Add ECC support +* Fix #1073 +* Fix #1115 +* Fix buffer underrun in decipher +* Fix #1306 +## Starcos +* added serial number for 3.4 +* fixed setting key reference for 3.4 +* added support for PIN status queries for 3.4 +## EstEID +* ECDSA/ECDH token support +* Fix crash when certificate read failed (#1176) +* Cleanup expired EstEID card ATR-s +* Fix reading EstEID certificates with T=0 (#1193) +## OpenPGP +* Added support for PIN logout and status +* factory reset is possible if LCS is supported +* Added support for OpenPGP card V3 +* fixed selecting Applet +* implemented keep alive command +* Retrieve OpenPGP applet version from OpenPGP applet on YubiKey token (#1262) +## German ID card +* fixed recognition of newer cards +## SC-HSM +* Don't block generic contactless ATR +* changed default labels of GoID +* added PIN commands for GoID 1.0 +## Starcos +* Added Support for Starcos 3.4 and 3.5 +## MioCOS +* disabled by default, use `card_drivers = old;` to enable; driver will be removed soon. +## BlueZ PKCS#15 applet +* disabled by default, use `card_drivers = old;` to enable; driver will be removed soon. + # New in 0.17.0; 2017-07-18 ## Support for new Cards * CAC (Common Access Card) diff --git a/appveyor.yml b/appveyor.yml index d351662aed..9bee08bb37 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.17.0.{build} +version: 0.18.0.{build} platform: - x86 From 9858d05589f71e9466f84c8a62e58375cf889052 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 May 2018 12:31:55 +0200 Subject: [PATCH 0248/4321] PKCS#11 testsuite (#1224) * Initial version of pkcs11 testsuite * Refactor test cases to several files, clean up awful and unused stuff * Static mechanism list based on the actual token offer * Get rid of magic numbers * Documentation * License update based on the original project * Verbose readme * Cleanup unused code, long lines and method order * Typo; More verbose errors * Use fallback mechanisms * Refactor object allocation and certificate search * PKCS11SPY mentioned, more TODO * add SHA mechanisms * Do not try to Finalize already finalized cryptoki * Add more flags and mechanisms * Do not list table for no results * Logical order of the tests (regression last) * read ALWAYS_AUTHENTICATE from correct place * ALWAYS_AUTHENTICATE for decryption * Test EC key length signature based on the actual key length * Shorten CKM_ list output, add keygen types detection * Skip decrypting on non-supported mechanisms * Fail hard if the C_Login fails * Reorganize local FLAGS_ constants * Test RSA Digest mechanisms * Correct mechanisms naming, typos * Do not attempt to do signature using empty keys * CKM_ECDSA_SHA1 support * Correct type cast when getting attributes * Report failures from all mechanisms * Standardize return values, eliminate complete fails, documentation interface * Wait for slot event test * Add switch to allow interaction with a card (WaitForSlotEvent) * At least try to verify using C_Verify, if it fails, fall back to openssl * Get rid of function_pointers * Get rid of additional newline * Share always_authenticate() function between the test cases * Refactor Encrypt&decrypt test to functions * Do not overwrite bits if they are not provided by CKA, indentation * Cleanup and Break to more functions Sign&Verify test * CKM_RSA_X_509 sign and verify with openssl padding * More TODO's * Proper abstracted padding with RSA_X_509 mechanism * Add ongoing tasks from different TODO list * Update instructions. Another todo * Variables naming * Increase mechanism list size, use different static buffers for flags and mechanism names * nonstandard mechanism CKM_SHA224_RSA_PKCS supported by some softotkens * Get rid of loop initial declarations * Loop initial declaration, typos, strict warnings * Move the p11test to the new folder to avoid problems with dynamically linked opensc.so * Update path in README * Possibility to validate the testsuite agains software tokens * Add possibility to select slot ID on command-line (when there are more cards present) * Clean up readme to reflect current options and TODOs * Do not attempt to use keys without advertised sign&verify bits to avoid false positives * Get and present more object attributes in readonly test; refactor table * New test checking if the set of attributes (usage flags) is reasonable * Test multipart signatures. There is not reasonable mechanism supporting multipart encryption * Use PKCS#11 encryption if possible (with openssl fallback) * Identify few more mechanisms (PSS) in the lest * Resize table to fit new mechanisms * Remove initial loop declaration from multipart test * Use pkcs11-tool instead of p11tool form most of the operations (master have most of the features) * Preparation for machine readable results * Refactor log variables out of the main context, try to export generic data * Do not write to non-existing FD if not logging * Export missing data into the log file in JSON * Store database in json * Sanity check * Avoid uninitialized structure fields using in state structure * Dump always_authenticate attribute too * Manual selection of slots with possibility to use slots without tokens * Do not free before finalizing * Proper cleanup of message in all cases * Proper allocation and deallocation of messages * Sanitize missing cases (memory leaks) * Suppressions for testing under valgrind * Better handling message_lengt during sign&verify (avoid invalid access) * Suppress another PCSC error * Do not use default PIN. Fail if none specified * Sanitize initialization. Skip incomplete key pairs * Add missing newline in errors * Fix condition for certificate search * Avoid several calls for attributes of zero length * Handle if the private key is not present on the card * Improve memory handling, silent GCC warning of 'unused' variable * Fail early with missing private key, cleanup the messages * Use correct padding for encryption * Cache if the card supports Verify/Encrypt and avoid trying over and over again * Loosen the condition for the Usage flags * OpenSSL 1.1.0 compatibility * Add missing mechanisms * Do not require certificates on the card and pass valid data for RSA_PKCS mechanisms * Add missing PIN argument in runtest.sh * Add OpenSSL < 1.1 comatible bits * Add SHA2 ECDSA mechanisms handling * Use public key from PKCS#11 if the certificate is missing (or compare it with certificate) * Avoid long definitions in OpenSSL compat layer * In older OpenSSL, the header file is ecdsa.h * Add missing config.h to apply compat OpenSSL layer * ASN1_STRING_get0_data() is also new in 1.1.0 * Return back RSA_X_509 mechanism * Drop bogus CKM_* in the definitions * Drop CKM_SHA224_RSA_PKCS as it is already in pkcs11.h * Update documentation * Use NDEBUG as intended * typos, cleanup * Typos, cleanup, update copyright * Additional check for OpenCryptoki, generate more key types on soft tokens * Prepare for RSA-PSS and RSA-OAEP * Use usage&result flags for the tests, gracefully ignore PSS&OAEP * pkcs11.h: Add missing definitions for PSS * PSS and OAEP tests readonly: Typos, reformat * Working version, memory leak * Tweak message lengths for OAEP and PSS * Skip tests that are not aplicable for tokens * configure.ac: New switch --enable-tests Do not attempt to build tests if cmocka is not available or --enable-tests is provided. It makes also more lightweight release builds out of the box (or with --disable-tests). * travis: Install cmocka if not available * Do not build tests on Windows and make dist pass * Try to install cmocka from apt and from brew * Do not require sudo (cmocka from apt and brew works) --- .gitignore | 1 + .travis.yml | 5 +- configure.ac | 30 + src/Makefile.am | 6 +- src/Makefile.mak | 6 +- src/libopensc/sc-ossl-compat.h | 24 + src/pkcs11/pkcs11.h | 4 +- src/tests/Makefile.am | 2 +- src/tests/p11test/Makefile.am | 30 + src/tests/p11test/Makefile.mak | 26 + src/tests/p11test/README.md | 57 ++ src/tests/p11test/cert.cfg | 6 + src/tests/p11test/p11test.c | 132 ++++ src/tests/p11test/p11test.supp | 30 + src/tests/p11test/p11test_case_common.c | 728 +++++++++++++++++ src/tests/p11test/p11test_case_common.h | 127 +++ src/tests/p11test/p11test_case_ec_sign.c | 64 ++ src/tests/p11test/p11test_case_ec_sign.h | 25 + src/tests/p11test/p11test_case_mechs.c | 138 ++++ src/tests/p11test/p11test_case_mechs.h | 24 + src/tests/p11test/p11test_case_multipart.c | 107 +++ src/tests/p11test/p11test_case_multipart.h | 26 + src/tests/p11test/p11test_case_pss_oaep.c | 874 +++++++++++++++++++++ src/tests/p11test/p11test_case_pss_oaep.h | 24 + src/tests/p11test/p11test_case_readonly.c | 699 ++++++++++++++++ src/tests/p11test/p11test_case_readonly.h | 29 + src/tests/p11test/p11test_case_usage.c | 137 ++++ src/tests/p11test/p11test_case_usage.h | 25 + src/tests/p11test/p11test_case_wait.c | 59 ++ src/tests/p11test/p11test_case_wait.h | 24 + src/tests/p11test/p11test_common.h | 89 +++ src/tests/p11test/p11test_helpers.c | 207 +++++ src/tests/p11test/p11test_helpers.h | 37 + src/tests/p11test/p11test_loader.c | 147 ++++ src/tests/p11test/p11test_loader.h | 34 + src/tests/p11test/runtest.sh | 145 ++++ win32/Make.rules.mak | 7 +- 37 files changed, 4126 insertions(+), 9 deletions(-) create mode 100644 src/tests/p11test/Makefile.am create mode 100644 src/tests/p11test/Makefile.mak create mode 100644 src/tests/p11test/README.md create mode 100644 src/tests/p11test/cert.cfg create mode 100644 src/tests/p11test/p11test.c create mode 100644 src/tests/p11test/p11test.supp create mode 100644 src/tests/p11test/p11test_case_common.c create mode 100644 src/tests/p11test/p11test_case_common.h create mode 100644 src/tests/p11test/p11test_case_ec_sign.c create mode 100644 src/tests/p11test/p11test_case_ec_sign.h create mode 100644 src/tests/p11test/p11test_case_mechs.c create mode 100644 src/tests/p11test/p11test_case_mechs.h create mode 100644 src/tests/p11test/p11test_case_multipart.c create mode 100644 src/tests/p11test/p11test_case_multipart.h create mode 100644 src/tests/p11test/p11test_case_pss_oaep.c create mode 100644 src/tests/p11test/p11test_case_pss_oaep.h create mode 100644 src/tests/p11test/p11test_case_readonly.c create mode 100644 src/tests/p11test/p11test_case_readonly.h create mode 100644 src/tests/p11test/p11test_case_usage.c create mode 100644 src/tests/p11test/p11test_case_usage.h create mode 100644 src/tests/p11test/p11test_case_wait.c create mode 100644 src/tests/p11test/p11test_case_wait.h create mode 100644 src/tests/p11test/p11test_common.h create mode 100644 src/tests/p11test/p11test_helpers.c create mode 100644 src/tests/p11test/p11test_helpers.h create mode 100644 src/tests/p11test/p11test_loader.c create mode 100644 src/tests/p11test/p11test_loader.h create mode 100755 src/tests/p11test/runtest.sh diff --git a/.gitignore b/.gitignore index d224b76e5b..638da86e45 100644 --- a/.gitignore +++ b/.gitignore @@ -128,5 +128,6 @@ src/tests/lottery src/tests/p15dump src/tests/pintest src/tests/prngtest +src/tests/p11test/p11test version.m4.ci diff --git a/.travis.yml b/.travis.yml index 66dbd55706..8974368feb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: c -sudo: false - addons: apt_packages: - binutils-mingw-w64-i686 @@ -15,6 +13,7 @@ addons: - xsltproc - gengetopt - help2man + - libcmocka-dev env: global: @@ -52,7 +51,7 @@ before_install: brew update; brew uninstall libtool; brew install libtool; - brew install gengetopt help2man; + brew install gengetopt help2man cmocka; fi before_script: diff --git a/configure.ac b/configure.ac index 46e90e0df4..98fbec56e3 100644 --- a/configure.ac +++ b/configure.ac @@ -255,6 +255,13 @@ AC_ARG_ENABLE( [enable_notify="detect"] ) +AC_ARG_ENABLE( + [tests], + [AS_HELP_STRING([--enable-tests],[Build tests in src/tests/ directory @<:@detect@:>@])], + , + [enable_tests="detect"] +) + AC_ARG_WITH( [xsl-stylesheetsdir], [AS_HELP_STRING([--with-xsl-stylesheetsdir=PATH],[docbook xsl-stylesheets for svn build @<:@detect@:>@])], @@ -511,6 +518,26 @@ if test "${enable_notify}" = "yes"; then fi fi +PKG_CHECK_MODULES( [CMOCKA], [cmocka], + [ have_cmocka="yes" ], + [ have_cmocka="no" ]) + +if test "${enable_tests}" = "detect"; then + if test "${have_cmocka}" = "yes"; then + enable_tests="yes" + else + enable_tests="no" + fi +fi + +if test "${enable_tests}" = "yes"; then + if test "${have_cmocka}" = "yes"; then + AC_DEFINE([ENABLE_TESTS], [1], [Build tests in tests/ subdirectory]) + else + AC_MSG_ERROR([Tests required, but cmocka is not available]) + fi +fi + AC_ARG_VAR([ZLIB_CFLAGS], [C compiler flags for zlib]) AC_ARG_VAR([ZLIB_LIBS], [linker flags for zlib]) if test -z "${ZLIB_LIBS}"; then @@ -997,6 +1024,7 @@ AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidrive AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"]) AM_CONDITIONAL([ENABLE_DNIE_UI], [test "${enable_dnie_ui}" = "yes"]) AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"]) +AM_CONDITIONAL([ENABLE_TESTS], [test "${ENABLE_TESTS}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) if test "${enable_pedantic}" = "yes"; then @@ -1025,6 +1053,7 @@ AC_CONFIG_FILES([ src/scconf/Makefile src/tests/Makefile src/tests/regression/Makefile + src/tests/p11test/Makefile src/tools/Makefile src/tools/versioninfo-tools.rc src/tools/versioninfo-opensc-notify.rc @@ -1082,6 +1111,7 @@ SM support: ${enable_sm} SM default module: ${DEFAULT_SM_MODULE} DNIe UI support: ${enable_dnie_ui} Notification support: ${enable_notify} +Build tests: ${enable_tests} Debug file: ${DEBUG_FILE} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} diff --git a/src/Makefile.am b/src/Makefile.am index 64d05d9303..3be8f6a958 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,12 @@ EXTRA_DIST = Makefile.mak # Order IS important SUBDIRS = common scconf ui pkcs15init sm \ - libopensc pkcs11 tools tests minidriver + libopensc pkcs11 tools minidriver if ENABLE_SM SUBDIRS += smm endif + +if ENABLE_TESTS +SUBDIRS += tests +endif diff --git a/src/Makefile.mak b/src/Makefile.mak index f6609f774e..c37792169e 100644 --- a/src/Makefile.mak +++ b/src/Makefile.mak @@ -1,7 +1,7 @@ TOPDIR = .. SUBDIRS = common scconf ui sm pkcs15init \ - libopensc pkcs11 tools tests + libopensc pkcs11 tools default: all @@ -15,6 +15,10 @@ SUBDIRS = $(SUBDIRS) minidriver SUBDIRS = $(SUBDIRS) smm !ENDIF +!IF "$(TESTS_DEF)" == "/DENABLE_TESTS" +SUBDIRS = $(SUBDIRS) tests +!ENDIF + all clean:: @for %i in ( $(SUBDIRS) ) do \ @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index a94d9564dc..9801cf525b 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -93,6 +93,7 @@ extern "C" { #define OPENSSL_malloc_init CRYPTO_malloc_init #define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) +#define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec) #define EVP_PKEY_get0_DSA(x) (x->pkey.dsa) #define X509_get_extension_flags(x) (x->ex_flags) #define X509_get_key_usage(x) (x->ex_kusage) @@ -103,6 +104,11 @@ extern "C" { #endif #endif +/* ASN1_STRING_data is deprecated in OpenSSL 1.1.0 */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) +#endif + /* * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures * One can no longer use statements like rsa->n = ... @@ -140,6 +146,9 @@ extern "C" { #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif #ifndef OPENSSL_NO_RSA static sc_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) @@ -239,6 +248,21 @@ static sc_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, co /* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */ #endif /* OPENSSL_NO_DSA */ + +#ifndef OPENSSL_NO_EC +static sc_ossl_inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} +#endif /* OPENSSL_NO_EC */ + + #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ #ifdef __cplusplus diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 692f5e3621..61a5050df6 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -776,7 +776,7 @@ typedef struct CK_RSA_PKCS_OAEP_PARAMS { typedef struct CK_RSA_PKCS_PSS_PARAMS { ck_mechanism_type_t hashAlg; - unsigned long mgf; + CK_RSA_PKCS_MGF_TYPE mgf; unsigned long sLen; } CK_RSA_PKCS_PSS_PARAMS; @@ -786,6 +786,8 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS { #define CKG_MGF1_SHA384 (0x00000003UL) #define CKG_MGF1_SHA512 (0x00000004UL) +#define CKZ_DATA_SPECIFIED (0x00000001UL) + typedef unsigned long ck_rv_t; diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 2a869d894a..99ee8aa612 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak -SUBDIRS = regression +SUBDIRS = regression p11test noinst_PROGRAMS = base64 lottery p15dump pintest prngtest AM_CPPFLAGS = -I$(top_srcdir)/src diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am new file mode 100644 index 0000000000..15de3174be --- /dev/null +++ b/src/tests/p11test/Makefile.am @@ -0,0 +1,30 @@ +include $(top_srcdir)/win32/ltrc.inc + +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = Makefile.mak + +noinst_PROGRAMS = p11test +noinst_HEADERS = p11test_loader.h p11test_case_common.h \ + p11test_case_readonly.h p11test_case_multipart.h \ + p11test_case_mechs.h p11test_case_ec_sign.h \ + p11test_case_usage.h p11test_case_wait.h \ + p11test_case_pss_oaep.h p11test_helpers.h + +AM_CPPFLAGS = -I$(top_srcdir)/src + +p11test_SOURCES = p11test.c p11test_loader.c \ + p11test_case_common.c \ + p11test_case_readonly.c \ + p11test_case_multipart.c \ + p11test_case_mechs.c \ + p11test_case_ec_sign.c \ + p11test_case_usage.c \ + p11test_case_wait.c \ + p11test_case_pss_oaep.c \ + p11test_helpers.c +p11test_CFLAGS = -DNDEBUG +p11test_LDADD = -lssl -lcrypto -lcmocka + +if WIN32 +p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc +endif diff --git a/src/tests/p11test/Makefile.mak b/src/tests/p11test/Makefile.mak new file mode 100644 index 0000000000..197830137a --- /dev/null +++ b/src/tests/p11test/Makefile.mak @@ -0,0 +1,26 @@ +TOPDIR = ..\..\.. + +TARGETS = p11test.exe + +OBJECTS = p11test_loader.obj \ + p11test_case_common.obj \ + p11test_case_readonly.obj \ + p11test_case_multipart.obj \ + p11test_case_mechs.obj \ + p11test_case_ec_sign.obj \ + p11test_case_usage.obj \ + p11test_case_wait.obj \ + p11test_case_pss_oaep.obj \ + p11test_helpers.obj \ + $(TOPDIR)\win32\versioninfo.res + +all: $(TARGETS) + +!INCLUDE $(TOPDIR)\win32\Make.rules.mak + +$(TARGETS): $(OBJECTS) $(LIBS) + +.c.exe: + cl $(COPTS) /c $< + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) + if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 diff --git a/src/tests/p11test/README.md b/src/tests/p11test/README.md new file mode 100644 index 0000000000..bcf9a58ddf --- /dev/null +++ b/src/tests/p11test/README.md @@ -0,0 +1,57 @@ +# Non-destructive PKCS#11 test suite (not only for readonly cards) + +## What are the dependencies? + +In addition to the dependencies needed by OpenSC, the test suite is +using [`cmocka`](https://cmocka.org/) unit testing framework +(`libcmocka-devel` package in Fedora/EPEL). + +## How to use? + +Build OpenSC from source: + + git clone git@github.com:Jakuje/OpenSC.git + cd OpenSC + git checkout jjelen-testsuite # not in master yet + ./bootstrap + ./configure + make -j4 + +Plug in the card/reader, change to test directory and run the test: + + cd src/tests/p11test + ./p11test -p 123456 + +It will run all tests on the first card found in PKCS#11 API +with pin `123456` and using just built OpenSC shared library from master. + +### I have more slots with different cards. + +Slot can be selected using `-s` switch on command-line. + + ./p11test -s 4 + +Slot numbers can be obtained using from `pkcs11-tool -L` (note that different +libraries might have different numbers for the slots). + +### I want to test different pkcs11 library + +You can specify different library or build from different branch +on command-line: + + ./p11test -m /usr/lib64/pkcs11/libcoolkeypk11.so + +or to debug PKCS#11 calls using `/usr/lib64/pkcs11-spy.so`: + + export PKCS11SPY="../pkcs11/.libs/opensc-pkcs11.so" + ./p11test -m ../pkcs11/.libs/pkcs11-spy.so + +You can run the test suite also on the soft tokens. The testbench for +`softhsm` and `opencryptoki` is available in the script `runtest.sh`. + +TODO: + + * Test `CKM_ECDSA_DERIVE` mechanism(s) + * Read pin from environment variable? + * Keygen write tests (optional) + * Reflect cmocka dependency in the configure diff --git a/src/tests/p11test/cert.cfg b/src/tests/p11test/cert.cfg new file mode 100644 index 0000000000..409aa93012 --- /dev/null +++ b/src/tests/p11test/cert.cfg @@ -0,0 +1,6 @@ +organization = "OpenSC" +expiration_days = 365 +email = "none@example.org" +signing_key +encryption_key + diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c new file mode 100644 index 0000000000..5e004c62d3 --- /dev/null +++ b/src/tests/p11test/p11test.c @@ -0,0 +1,132 @@ +/* + * p11test.c: Test suite for PKCS#11 API + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "p11test_helpers.h" + +#include "p11test_case_readonly.h" +#include "p11test_case_multipart.h" +#include "p11test_case_ec_sign.h" +#include "p11test_case_usage.h" +#include "p11test_case_mechs.h" +#include "p11test_case_wait.h" +#include "p11test_case_pss_oaep.h" + +#define DEFAULT_P11LIB "../../pkcs11/.libs/opensc-pkcs11.so" + +void display_usage() { + fprintf(stdout, + " Usage:\n" + " ./p11test [-m module_path] [-s slot_id] [-p pin]\n" + " -m module_path Path to tested module (e.g. /usr/lib64/opensc-pkcs11.so)\n" + " Default is "DEFAULT_P11LIB"\n" + " -p pin Application PIN\n" + " -s slot_id Slot ID with the card\n" + " -i Wait for the card before running the test (interactive)\n" + " -o File to write a log in JSON\n" + " -h This help\n" + "\n"); +} + +int main(int argc, char** argv) { + char command; + const struct CMUnitTest readonly_tests_without_initialization[] = { + /* Test card events on slot */ + cmocka_unit_test_setup_teardown(wait_test, + token_initialize, token_cleanup), + + /* Check all the mechanisms provided by the token */ + cmocka_unit_test_setup_teardown(supported_mechanisms_test, + token_setup, token_cleanup), + + /* Complex readonly test of all objects on the card */ + cmocka_unit_test_setup_teardown(readonly_tests, + user_login_setup, after_test_cleanup), + + /* Multipart signatures and encryption */ + cmocka_unit_test_setup_teardown(multipart_tests, + user_login_setup, after_test_cleanup), + + /* Regression test Sign&Verify with various data lengths */ + cmocka_unit_test_setup_teardown(ec_sign_size_test, + user_login_setup, after_test_cleanup), + + /* Verify that the Usage flags on the objects are sane */ + cmocka_unit_test_setup_teardown(usage_test, + user_login_setup, after_test_cleanup), + + /* Verify that RSA-PSS and RSA-OAEP functions if supported */ + cmocka_unit_test_setup_teardown(pss_oaep_test, + user_login_setup, after_test_cleanup), + }; + + token.library_path = NULL; + token.pin = NULL; + token.pin_length = 0; + token.interactive = 0; + token.slot_id = (unsigned long) -1; + token.log.outfile = NULL; + + while ((command = getopt(argc, argv, "?hm:s:p:io:")) != -1) { + switch (command) { + case 'o': + token.log.outfile = strdup(optarg); + break; + case 'm': + token.library_path = strdup(optarg); + break; + case 's': + token.slot_id = atol(optarg); + break; + case 'p': + token.pin = (CK_UTF8CHAR*) strdup(optarg); + token.pin_length = strlen(optarg); + break; + case 'i': + token.interactive = 1; + break; + case 'h': + case '?': + display_usage(); + return 0; + default: + break; + } + } + + if (token.library_path == NULL) { + debug_print("Falling back to the default library " DEFAULT_P11LIB); + token.library_path = strdup(DEFAULT_P11LIB); + } + + if (token.pin == NULL || token.pin_length == 0) { + printf("No PIN specified. Please, specify it on command-line using -p switch\n"); + return -1; + } + + debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %lu\n\t", + token.pin, token.pin_length); + + return cmocka_run_group_tests(readonly_tests_without_initialization, + group_setup, group_teardown); +} + diff --git a/src/tests/p11test/p11test.supp b/src/tests/p11test/p11test.supp new file mode 100644 index 0000000000..2d4473c30a --- /dev/null +++ b/src/tests/p11test/p11test.supp @@ -0,0 +1,30 @@ +{ + Suppress pcsc_detect_readers() + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:* + obj:* + fun:pcsc_detect_readers + fun:sc_ctx_detect_readers + fun:sc_context_create + fun:C_Initialize +} +{ + Suppress MessageSend() errors + Memcheck:Param + socketcall.sendto(msg) + fun:send + fun:MessageSend + fun:MessageSendWithHeader + fun:SCardConnect + fun:pcsc_detect_readers + fun:sc_ctx_detect_readers + fun:sc_context_create + fun:C_Initialize + fun:load_pkcs11_module + fun:group_setup + obj:/usr/lib64/libcmocka.so.0.3.1 + fun:_cmocka_run_group_tests +} + diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c new file mode 100644 index 0000000000..0f89cbb504 --- /dev/null +++ b/src/tests/p11test/p11test_case_common.c @@ -0,0 +1,728 @@ +/* + * p11test_case_common.c: Functions shared between test cases. + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" + +char name_buffer[11]; +char flag_buffer[11]; + +/** + * If the object enforces re-authentication, do it now. + */ +void always_authenticate(test_cert_t *o, token_info_t *info) +{ + CK_RV rv; + if (!o->always_auth) + return; + + rv = info->function_pointer->C_Login(info->session_handle, + CKU_CONTEXT_SPECIFIC, info->pin, info->pin_length); + if (rv != CKR_OK) { + fail_msg(" [ SKIP %s ] Re-authentication failed", o->id_str); + } +} + +/** + * Allocate new place for next certificate to store in the list + * and return pointer to this object + */ +test_cert_t * +add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) +{ + test_cert_t *o = NULL; + objects->count = objects->count+1; + objects->data = realloc(objects->data, objects->count * sizeof(test_cert_t)); + if (objects->data == NULL) + return NULL; + + o = &(objects->data[objects->count - 1]); + o->private_handle = CK_INVALID_HANDLE; + o->public_handle = CK_INVALID_HANDLE; + o->always_auth = 0; + o->bits = 0; + o->verify_public = 0; + o->num_mechs = 0; + o->type = -1; + o->sign = 0; + o->verify = 0; + o->decrypt = 0; + o->encrypt = 0; + o->wrap = 0; + o->unwrap = 0; + o->derive_priv = 0; + o->derive_pub = 0; + o->key_type = -1; + o->x509 = NULL; /* The "reuse" capability of d2i_X509() is strongly discouraged */ + o->key.rsa = NULL; + o->key.ec = NULL; + + /* Store the passed CKA_ID and CKA_LABEL */ + o->key_id = malloc(key_id.ulValueLen); + memcpy(o->key_id, key_id.pValue, key_id.ulValueLen); + o->key_id_size = key_id.ulValueLen; + o->id_str = convert_byte_string(o->key_id, o->key_id_size); + o->label = malloc(label.ulValueLen + 1); + strncpy(o->label, label.pValue, label.ulValueLen); + o->label[label.ulValueLen] = '\0'; + + return o; +} + +/* + * Search for certificate in the list by ID and return pointer to it + */ +test_cert_t * search_certificate(test_certs_t *objects, CK_ATTRIBUTE *id) +{ + unsigned int i = 0; + + while (i < objects->count && (objects->data[i].key_id_size != id->ulValueLen || + memcmp(objects->data[i].key_id, id->pValue, id->ulValueLen) != 0)) + i++; + + if (i == objects->count) + return NULL; + + return &(objects->data[i]); +} + +static void +add_supported_mechs(test_cert_t *o) +{ + size_t i; + + if (o->type == EVP_PK_RSA) { + if (token.num_rsa_mechs > 0 ) { + /* Get supported mechanisms by token */ + o->num_mechs = token.num_rsa_mechs; + for (i = 0; i <= token.num_rsa_mechs; i++) { + o->mechs[i].mech = token.rsa_mechs[i].mech; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = + token.rsa_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_RSA_PKCS; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY + | CKF_ENCRYPT | CKF_DECRYPT; + } + } else if (o->type == EVP_PK_EC) { + if (token.num_ec_mechs > 0 ) { + o->num_mechs = token.num_ec_mechs; + for (i = 0; i <= token.num_ec_mechs; i++) { + o->mechs[i].mech = token.ec_mechs[i].mech; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = + token.ec_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_ECDSA; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; + } + } +} + +/** + * Allocate place in the structure for every certificate found + * and store related information + */ +int callback_certificates(test_certs_t *objects, + CK_ATTRIBUTE template[], unsigned int template_size, CK_OBJECT_HANDLE object_handle) +{ + EVP_PKEY *evp = NULL; + const u_char *cp; + test_cert_t *o = NULL; + + if ((o = add_object(objects, template[0], template[2])) == NULL) + return -1; + + /* Extract public key from the certificate */ + cp = template[1].pValue; + if (d2i_X509(&(o->x509), &cp, template[1].ulValueLen) == NULL) { + fail_msg("d2i_X509"); + } else if ((evp = X509_get_pubkey(o->x509)) == NULL) { + fail_msg("X509_get_pubkey failed."); + } + + if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { + /* Extract public RSA key */ + RSA *rsa = EVP_PKEY_get0_RSA(evp); + if ((o->key.rsa = RSAPublicKey_dup(rsa)) == NULL) + fail_msg("RSAPublicKey_dup failed"); + o->type = EVP_PK_RSA; + o->bits = EVP_PKEY_bits(evp); + + } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { + /* Extract public EC key */ + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp); + if ((o->key.ec = EC_KEY_dup(ec)) == NULL) + fail_msg("EC_KEY_dup failed"); + o->type = EVP_PK_EC; + o->bits = EVP_PKEY_bits(evp); + + } else { + fprintf(stderr, "[WARN %s ]evp->type = 0x%.4X (not RSA, EC)\n", + o->id_str, EVP_PKEY_id(evp)); + } + EVP_PKEY_free(evp); + + debug_print(" [ OK %s ] Certificate with label %s loaded successfully", + o->id_str, o->label); + return 0; +} + +/** + * Pair found private keys on the card with existing certificates + */ +int callback_private_keys(test_certs_t *objects, + CK_ATTRIBUTE template[], unsigned int template_size, CK_OBJECT_HANDLE object_handle) +{ + test_cert_t *o = NULL; + char *key_id; + + /* Search for already stored certificate with same ID */ + if ((o = search_certificate(objects, &(template[3]))) == NULL) { + key_id = convert_byte_string(template[3].pValue, + template[3].ulValueLen); + fprintf(stderr, "Can't find certificate for private key with ID %s\n", key_id); + free(key_id); + + fprintf(stderr, "Let's create a bogus structure without certificate data\n"); + if ((o = add_object(objects, template[3], template[7])) == NULL) + return -1; + } + + if (o->private_handle != CK_INVALID_HANDLE) { + key_id = convert_byte_string(template[3].pValue, template[3].ulValueLen); + fprintf(stderr, "Object already filled? ID %s\n", key_id); + free(key_id); + return -1; + } + + /* Store attributes, flags and handles */ + o->private_handle = object_handle; + o->sign = (template[0].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[0].pValue) : CK_FALSE; + o->decrypt = (template[1].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[1].pValue) : CK_FALSE; + o->key_type = (template[2].ulValueLen != (CK_ULONG) -1) + ? *((CK_KEY_TYPE *) template[2].pValue) : (CK_KEY_TYPE) -1; + o->always_auth = (template[4].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; + o->unwrap = (template[5].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; + o->derive_priv = (template[6].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; + + debug_print(" [ OK %s ] Private key loaded successfully S:%d D:%d T:%02lX", + o->id_str, o->sign, o->decrypt, o->key_type); + return 0; +} + +/** + * Pair found public keys on the card with existing certificates + */ +int callback_public_keys(test_certs_t *objects, + CK_ATTRIBUTE template[], unsigned int template_size, CK_OBJECT_HANDLE object_handle) +{ + test_cert_t *o = NULL; + char *key_id; + + /* Search for already stored certificate with same ID */ + if ((o = search_certificate(objects, &(template[3]))) == NULL) { + key_id = convert_byte_string(template[3].pValue, template[3].ulValueLen); + fprintf(stderr, "Can't find certificate for public key with ID %s\n", key_id); + free(key_id); + return -1; + } + + if (o->verify_public != 0) { + key_id = convert_byte_string(template[3].pValue, template[3].ulValueLen); + fprintf(stderr, "Object already filled? ID %s\n", key_id); + free(key_id); + return -1; + } + + o->public_handle = object_handle; + o->verify = (template[0].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[0].pValue) : CK_FALSE; + o->encrypt = (template[1].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[1].pValue) : CK_FALSE; + /* store key type in case there is no corresponding private key */ + o->key_type = (template[2].ulValueLen != (CK_ULONG) -1) + ? *((CK_KEY_TYPE *) template[2].pValue) : (CK_KEY_TYPE) -1; + o->wrap = (template[8].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; + o->derive_pub = (template[9].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; + + /* check if we get the same public key as from the certificate */ + if (o->key_type == CKK_RSA) { + BIGNUM *n = NULL, *e = NULL; + n = BN_bin2bn(template[4].pValue, template[4].ulValueLen, NULL); + e = BN_bin2bn(template[5].pValue, template[5].ulValueLen, NULL); + if (o->key.rsa != NULL) { + const BIGNUM *cert_n = NULL, *cert_e = NULL; + RSA_get0_key(o->key.rsa, &cert_n, &cert_e, NULL); + if (BN_cmp(cert_n, n) != 0 || + BN_cmp(cert_e, e) != 0) { + debug_print(" [WARN %s ] Got different public key then from the certificate", + o->id_str); + BN_free(n); + BN_free(e); + return -1; + } + BN_free(n); + BN_free(e); + o->verify_public = 1; + } else { /* store the public key for future use */ + o->type = EVP_PK_RSA; + o->key.rsa = RSA_new(); + RSA_set0_key(o->key.rsa, n, e, NULL); + n = NULL; + e = NULL; + } + } else if (o->key_type == CKK_EC) { + ASN1_OBJECT *oid = NULL; + ASN1_OCTET_STRING *s = NULL; + const unsigned char *pub, *p; + BIGNUM *bn = NULL; + EC_POINT *ecpoint; + EC_GROUP *ecgroup; + int nid, pub_len; + + /* Parse the nid out of the EC_PARAMS */ + p = template[6].pValue; + oid = d2i_ASN1_OBJECT(NULL, &p, template[6].ulValueLen); + nid = OBJ_obj2nid(oid); + ASN1_OBJECT_free(oid); + ecgroup = EC_GROUP_new_by_curve_name(nid); + EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); + + p = template[7].pValue; + s = d2i_ASN1_OCTET_STRING(NULL, &p, template[7].ulValueLen); + pub = ASN1_STRING_get0_data(s); + pub_len = ASN1_STRING_length(s); + bn = BN_bin2bn(pub, pub_len, NULL); + ASN1_STRING_free(s); + if (bn == NULL) { + debug_print(" [WARN %s ] Can not convert EC_POINT from" + "PKCS#11 to BIGNUM", o->id_str); + EC_GROUP_free(ecgroup); + return -1; + } + + ecpoint = EC_POINT_bn2point(ecgroup, bn, NULL, NULL); + BN_free(bn); + if (ecpoint == NULL) { + debug_print(" [WARN %s ] Can not convert EC_POINT from" + "BIGNUM to OpenSSL format", o->id_str); + EC_GROUP_free(ecgroup); + return -1; + } + + if (o->key.ec != NULL) { + const EC_GROUP *cert_group = EC_KEY_get0_group(o->key.ec); + const EC_POINT *cert_point = EC_KEY_get0_public_key(o->key.ec); + int cert_nid = EC_GROUP_get_curve_name(cert_group); + + if (cert_nid != nid || + EC_GROUP_cmp(cert_group, ecgroup, NULL) != 0 || + EC_POINT_cmp(ecgroup, cert_point, ecpoint, NULL) != 0) { + debug_print(" [WARN %s ] Got different public" + "key then from the certificate", + o->id_str); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + return -1; + } + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + o->verify_public = 1; + } else { /* store the public key for future use */ + o->type = EVP_PK_EC; + o->key.ec = EC_KEY_new_by_curve_name(nid); + EC_KEY_set_public_key(o->key.ec, ecpoint); + EC_KEY_set_group(o->key.ec, ecgroup); + } + } else { + debug_print(" [WARN %s ] non-RSA, non-EC key. Key type: %02lX", + o->id_str, o->key_type); + return -1; + } + + add_supported_mechs(o); + + debug_print(" [ OK %s ] Public key loaded successfully V:%d E:%d T:%02lX", + o->id_str, o->verify, o->encrypt, o->key_type); + return 0; +} + +int search_objects(test_certs_t *objects, token_info_t *info, + CK_ATTRIBUTE filter[], CK_LONG filter_size, CK_ATTRIBUTE template[], CK_LONG template_size, + int (*callback)(test_certs_t *, CK_ATTRIBUTE[], unsigned int, CK_OBJECT_HANDLE)) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_ULONG object_count; + CK_OBJECT_HANDLE object_handle = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE_PTR object_handles = NULL; + unsigned long i = 0, objects_length = 0; + int j; + + /* FindObjects first + * https://wiki.oasis-open.org/pkcs11/CommonBugs + */ + rv = fp->C_FindObjectsInit(info->session_handle, filter, filter_size); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsInit: rv = 0x%.8lX\n", rv); + return -1; + } + + while(1) { + rv = fp->C_FindObjects(info->session_handle, &object_handle, 1, &object_count); + if (object_count == 0) + break; + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjects: rv = 0x%.8lX\n", rv); + return -1; + } + /* store handle */ + if (i >= objects_length) { + objects_length += 4; // do not realloc after each row + object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE_PTR)); + if (object_handles == NULL) + fail_msg("Realloc failed. Need to store object handles.\n"); + } + object_handles[i++] = object_handle; + } + objects_length = i; //terminate list of handles + + rv = fp->C_FindObjectsFinal(info->session_handle); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsFinal: rv = 0x%.8lX\n", rv); + fail_msg("Could not find certificate.\n"); + } + + for (i = 0; i < objects_length; i++) { + /* Find attributes one after another to handle errors + * https://wiki.oasis-open.org/pkcs11/CommonBugs + */ + for (j = 0; j < template_size; j++) { + template[j].pValue = NULL; + template[j].ulValueLen = 0; + + rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], + &(template[j]), 1); + if (rv == CKR_ATTRIBUTE_TYPE_INVALID) + continue; + else if (rv != CKR_OK) + fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + + /* Allocate memory to hold the data we want */ + if (template[j].ulValueLen == 0) { + continue; + } else { + template[j].pValue = malloc(template[j].ulValueLen); + if (template[j].pValue == NULL) + fail_msg("malloc failed"); + } + /* Call again to get actual attribute */ + rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], + &(template[j]), 1); + if (rv != CKR_OK) + fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + } + + callback(objects, template, template_size, object_handles[i]); + // XXX check results + for (j = 0; j < template_size; j++) + free(template[j].pValue); + } + free(object_handles); + return 0; +} + +void search_for_all_objects(test_certs_t *objects, token_info_t *info) +{ + CK_OBJECT_CLASS keyClass = CKO_CERTIFICATE; + CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY; + CK_OBJECT_CLASS publicClass = CKO_PUBLIC_KEY; + CK_ATTRIBUTE filter[] = { + {CKA_CLASS, &keyClass, sizeof(keyClass)}, + }; + CK_ULONG filter_size = 1; + CK_ATTRIBUTE attrs[] = { + { CKA_ID, NULL_PTR, 0}, + { CKA_VALUE, NULL_PTR, 0}, + { CKA_LABEL, NULL_PTR, 0}, + { CKA_CERTIFICATE_TYPE, NULL_PTR, 0}, + }; + CK_ULONG attrs_size = sizeof (attrs) / sizeof (CK_ATTRIBUTE); + CK_ATTRIBUTE private_attrs[] = { + { CKA_SIGN, NULL, 0}, // CK_BBOOL + { CKA_DECRYPT, NULL, 0}, // CK_BBOOL + { CKA_KEY_TYPE, NULL, 0}, // CKK_ + { CKA_ID, NULL, 0}, + { CKA_ALWAYS_AUTHENTICATE, NULL, 0}, // CK_BBOOL + { CKA_UNWRAP, NULL, 0}, // CK_BBOOL + { CKA_DERIVE, NULL, 0}, // CK_BBOOL + { CKA_LABEL, NULL_PTR, 0}, + }; + CK_ULONG private_attrs_size = sizeof (private_attrs) / sizeof (CK_ATTRIBUTE); + CK_ATTRIBUTE public_attrs[] = { + { CKA_VERIFY, NULL, 0}, // CK_BBOOL + { CKA_ENCRYPT, NULL, 0}, // CK_BBOOL + { CKA_KEY_TYPE, NULL, 0}, + { CKA_ID, NULL, 0}, + { CKA_MODULUS, NULL, 0}, + { CKA_PUBLIC_EXPONENT, NULL, 0}, + { CKA_EC_PARAMS, NULL, 0}, + { CKA_EC_POINT, NULL, 0}, + { CKA_WRAP, NULL, 0}, // CK_BBOOL + { CKA_DERIVE, NULL, 0}, // CK_BBOOL + }; + CK_ULONG public_attrs_size = sizeof (public_attrs) / sizeof (CK_ATTRIBUTE); + + debug_print("\nSearch for all certificates on the card"); + search_objects(objects, info, filter, filter_size, + attrs, attrs_size, callback_certificates); + + + /* do the same thing with private keys (collect handles based on the collected IDs) */ + debug_print("\nSearch for all private keys respective to the certificates"); + filter[0].pValue = &privateClass; + // search for all and pair on the fly + search_objects(objects, info, filter, filter_size, + private_attrs, private_attrs_size, callback_private_keys); + + debug_print("\nSearch for all public keys respective to the certificates"); + filter[0].pValue = &publicClass; + search_objects(objects, info, filter, filter_size, + public_attrs, public_attrs_size, callback_public_keys); +} + +void clean_all_objects(test_certs_t *objects) { + unsigned int i; + for (i = 0; i < objects->count; i++) { + free(objects->data[i].key_id); + free(objects->data[i].id_str); + free(objects->data[i].label); + X509_free(objects->data[i].x509); + if (objects->data[i].key_type == CKK_RSA && + objects->data[i].key.rsa != NULL) + RSA_free(objects->data[i].key.rsa); + else if (objects->data[i].key.ec != NULL) + EC_KEY_free(objects->data[i].key.ec); + } + free(objects->data); +} + +const char *get_mechanism_name(int mech_id) +{ + switch (mech_id) { + case CKM_RSA_PKCS: + return "RSA_PKCS"; + case CKM_SHA1_RSA_PKCS: + return "SHA1_RSA_PKCS"; + case CKM_SHA224_RSA_PKCS: + return "SHA224_RSA_PKCS"; + case CKM_SHA256_RSA_PKCS: + return "SHA256_RSA_PKCS"; + case CKM_SHA384_RSA_PKCS: + return "SHA384_RSA_PKCS"; + case CKM_SHA512_RSA_PKCS: + return "SHA512_RSA_PKCS"; + case CKM_RSA_X_509: + return "RSA_X_509"; + case CKM_ECDSA: + return "ECDSA"; + case CKM_ECDSA_SHA1: + return "ECDSA_SHA1"; + case CKM_ECDSA_SHA256: + return "ECDSA_SHA256"; + case CKM_ECDSA_SHA384: + return "ECDSA_SHA384"; + case CKM_ECDSA_SHA512: + return "ECDSA_SHA512"; + case CKM_ECDH1_DERIVE: + return "ECDH1_DERIVE"; + case CKM_ECDH1_COFACTOR_DERIVE: + return "ECDH1_COFACTOR_DERIVE"; + case CKM_EC_KEY_PAIR_GEN: + return "EC_KEY_PAIR_GEN"; + case CKM_RSA_PKCS_KEY_PAIR_GEN: + return "RSA_PKCS_KEY_PAIR_GEN"; + case CKM_MD5_RSA_PKCS: + return "MD5_RSA_PKCS"; + case CKM_RIPEMD160_RSA_PKCS: + return "RIPEMD160_RSA_PKCS"; + case CKM_RSA_PKCS_PSS: + return "RSA_PKCS_PSS"; + case CKM_SHA1_RSA_PKCS_PSS: + return "SHA1_RSA_PKCS_PSS"; + case CKM_SHA256_RSA_PKCS_PSS: + return "SHA256_RSA_PKCS_PSS"; + case CKM_SHA384_RSA_PKCS_PSS: + return "SHA384_RSA_PKCS_PSS"; + case CKM_SHA512_RSA_PKCS_PSS: + return "SHA512_RSA_PKCS_PSS"; + case CKM_SHA_1_HMAC: + return "SHA_1_HMAC"; + case CKM_SHA256_HMAC: + return "SHA256_HMAC"; + case CKM_SHA384_HMAC: + return "SHA384_HMAC"; + case CKM_SHA512_HMAC: + return "SHA512_HMAC"; + case CKM_RSA_PKCS_OAEP: + return "RSA_PKCS_OAEP"; + case CKM_SHA_1: + return "SHA_1"; + case CKM_SHA224: + return "SHA224"; + case CKM_SHA256: + return "SHA256"; + case CKM_SHA384: + return "SHA384"; + case CKM_SHA512: + return "SHA512"; + default: + sprintf(name_buffer, "0x%.8X", mech_id); + return name_buffer; + } +} + +const char *get_mgf_name(int mgf_id) +{ + switch (mgf_id) { + case CKG_MGF1_SHA1: + return "MGF1_SHA_1"; + case CKG_MGF1_SHA224: + return "MGF1_SHA224"; + case CKG_MGF1_SHA256: + return "MGF1_SHA256"; + case CKG_MGF1_SHA384: + return "MGF1_SHA384"; + case CKG_MGF1_SHA512: + return "MGF1_SHA512"; + default: + sprintf(name_buffer, "0x%.8X", mgf_id); + return name_buffer; + } +} + +const char *get_mechanism_flag_name(int mech_id) +{ + switch (mech_id) { + case CKF_HW: + return "CKF_HW"; + case CKF_ENCRYPT: + return "CKF_ENCRYPT"; + case CKF_DECRYPT: + return "CKF_DECRYPT"; + case CKF_DIGEST: + return "CKF_DIGEST"; + case CKF_SIGN: + return "CKF_SIGN"; + case CKF_SIGN_RECOVER: + return "CKF_SIGN_RECOVER"; + case CKF_VERIFY: + return "CKF_VERIFY"; + case CKF_VERIFY_RECOVER: + return "CKF_VERIFY_RECOVER"; + case CKF_GENERATE: + return "CKF_GENERATE"; + case CKF_GENERATE_KEY_PAIR: + return "CKF_GENERATE_KEY_PAIR"; + case CKF_WRAP: + return "CKF_WRAP"; + case CKF_UNWRAP: + return "CKF_UNWRAP"; + case CKF_DERIVE: + return "CKF_DERIVE"; + case CKF_EC_F_P: + return "CKF_EC_F_P"; + case CKF_EC_F_2M: + return "CKF_EC_F_2M"; + case CKF_EC_NAMEDCURVE: + return "CKF_EC_NAMEDCURVE"; + case CKF_EC_UNCOMPRESS: + return "CKF_EC_UNCOMPRESS"; + case CKF_EC_COMPRESS: + return "CKF_EC_COMPRESS"; + case CKF_EC_ECPARAMETERS: + return "CKF_EC_ECPARAMETERS"; + default: + sprintf(flag_buffer, "0x%.8X", mech_id); + return flag_buffer; + } +} + +char *convert_byte_string(unsigned char *id, unsigned long length) +{ + unsigned int i; + char *data = malloc(3 * length * sizeof(char) + 1); + for (i = 0; i < length; i++) + sprintf(&data[i*3], "%02X:", id[i]); + data[length*3-1] = '\0'; + return data; +} + +void write_data_row(token_info_t *info, int cols, ...) +{ + va_list ap; + int i, intval, type; + char *data; + + cols = cols*2; /* shut GCC up */ + va_start(ap, cols); + fprintf(info->log.fd, "\n\t["); + for (i = 1; i <= cols; i+=2) { + if (i > 1) + fprintf(info->log.fd, ","); + type = va_arg(ap, int); + if (type == 'd') { + intval = va_arg(ap, int); + fprintf(info->log.fd, "\n\t\t\"%d\"", intval); + } else if (type == 's') { + data = va_arg(ap, char*); + fprintf(info->log.fd, "\n\t\t\"%s\"", data); + } + } + fprintf(info->log.fd, "\n\t]"); + va_end(ap); +} + +int is_pss_mechanism(CK_MECHANISM_TYPE mech) +{ + return (mech == CKM_RSA_PKCS_PSS + || mech == CKM_SHA1_RSA_PKCS_PSS + || mech == CKM_SHA256_RSA_PKCS_PSS + || mech == CKM_SHA384_RSA_PKCS_PSS + || mech == CKM_SHA512_RSA_PKCS_PSS + || mech == CKM_SHA224_RSA_PKCS_PSS); +} diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h new file mode 100644 index 0000000000..b9171ab571 --- /dev/null +++ b/src/tests/p11test/p11test_case_common.h @@ -0,0 +1,127 @@ +/* + * p11test_case_common.h: Functions shared between test cases. + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef P11TEST_CASE_COMMON_H +#define P11TEST_CASE_COMMON_H + +#include +#include +#include +#include "p11test_common.h" + +typedef struct { + unsigned char *key_id; + CK_ULONG key_id_size; + char *id_str; + X509 *x509; + int type; + union { + RSA *rsa; + EC_KEY *ec; + } key; + CK_OBJECT_HANDLE private_handle; + CK_OBJECT_HANDLE public_handle; + CK_BBOOL sign; + CK_BBOOL decrypt; + CK_BBOOL verify; + CK_BBOOL encrypt; + CK_BBOOL wrap; + CK_BBOOL unwrap; + CK_BBOOL derive_priv; + CK_BBOOL derive_pub; + CK_KEY_TYPE key_type; + CK_BBOOL always_auth; + char *label; + CK_ULONG bits; + int verify_public; + test_mech_t mechs[MAX_MECHS]; + int num_mechs; +} test_cert_t; + +typedef struct { + unsigned int count; + test_cert_t *data; +} test_certs_t; + +void always_authenticate(test_cert_t *o, token_info_t *info); + +int search_objects(test_certs_t *objects, token_info_t *info, + CK_ATTRIBUTE filter[], CK_LONG filter_size, CK_ATTRIBUTE template[], CK_LONG template_size, + int (*callback)(test_certs_t *, CK_ATTRIBUTE[], unsigned int, CK_OBJECT_HANDLE)); +void search_for_all_objects(test_certs_t *objects, token_info_t *info); +void clean_all_objects(test_certs_t *objects); + +const char *get_mechanism_name(int mech_id); +const char *get_mgf_name(int mech_id); +const char *get_mechanism_flag_name(int flag_id); +char *convert_byte_string(unsigned char *id, unsigned long length); + +int is_pss_mechanism(CK_MECHANISM_TYPE mech); + +// TODO sanitize inputs + +#define P11TEST_START(info) if (info->log.fd) { \ + if (info->log.in_test) \ + fprintf(info->log.fd, "\n\t\"result\": \"unknown\"\n}"); \ + fprintf(info->log.fd, "%s\n{\n\t\"test_id\": \"%s\"", \ + info->log.first ? "" : ",", __func__); \ + info->log.in_test = 1; \ + info->log.first = 0; \ + info->log.in_data = 0; \ + } else {} + +#define _P11TEST_FINALIZE(info, result) if (info->log.fd) {\ + if (info->log.in_data) {\ + fprintf(info->log.fd, "]"); \ + } \ + if (info->log.fd && info->log.in_test) { \ + fprintf(info->log.fd, ",\n\t\"result\": \"" result "\"\n}"); \ + info->log.in_test = 0; \ + } \ + } else {} + +#define P11TEST_SKIP(info) do { _P11TEST_FINALIZE(info, "skip") skip(); } while(0); + +#define P11TEST_PASS(info) do { _P11TEST_FINALIZE(info, "pass") } while(0); + +#define P11TEST_FAIL(info, msg, ...) do { \ + if (info->log.fd && info->log.in_test) { \ + fprintf(info->log.fd, ",\n\t\"fail_reason\": \"" msg "\"", ##__VA_ARGS__); \ + } \ + _P11TEST_FINALIZE(info, "fail") \ + fail_msg(msg, ##__VA_ARGS__); \ + } while (0); + +#define P11TEST_DATA_ROW(info, cols, ...) if (info->log.fd) { \ + if (info->log.in_test == 0) \ + fail_msg("Can't add data outside of the test");\ + if (info->log.in_data == 0) {\ + fprintf(info->log.fd, ",\n\t\"data\": [");\ + info->log.in_data = 1;\ + } else { \ + fprintf(info->log.fd, ",");\ + } \ + write_data_row(info, cols, ##__VA_ARGS__); \ + } else {} + +void write_data_row(token_info_t *info, int cols, ...); + +#endif /* P11TEST_CASE_COMMON_H */ diff --git a/src/tests/p11test/p11test_case_ec_sign.c b/src/tests/p11test/p11test_case_ec_sign.c new file mode 100644 index 0000000000..eed3f33821 --- /dev/null +++ b/src/tests/p11test/p11test_case_ec_sign.c @@ -0,0 +1,64 @@ +/* + * p11test_case_ec_sign.c: Test different data lengths for EC signatures + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_ec_sign.h" + +void ec_sign_size_test(void **state) { + unsigned int i; + int min, max, j, l, errors = 0, rv; + token_info_t *info = (token_info_t *) *state; + + P11TEST_START(info); + if (token.num_ec_mechs == 0 ) { + fprintf(stderr, "Token does not support any ECC mechanisms. Skipping.\n"); + skip(); + } + + test_certs_t objects; + objects.count = 0; + objects.data = NULL; + + search_for_all_objects(&objects, info); + + debug_print("\nCheck functionality of Sign&Verify on different data lengths"); + for (i = 0; i < objects.count; i++) { + if (objects.data[i].key_type != CKK_EC) + continue; + // sanity: Test all mechanisms + min = (objects.data[i].bits + 7) / 8 - 2; + max = (objects.data[i].bits + 7) / 8 + 2; + if (objects.data[i].sign && objects.data[i].verify) { + for (j = 0; j < objects.data[i].num_mechs; j++) { + for (l = min; l < max; l++) { + rv = sign_verify_test(&(objects.data[i]), info, + &(objects.data[i].mechs[j]), l, 0); + if (rv == -1) + errors++; + } + } + } + } + clean_all_objects(&objects); + + if (errors > 0) + P11TEST_FAIL(info, "Some signatures were not verified successfully. Please review the log"); + P11TEST_PASS(info); +} + diff --git a/src/tests/p11test/p11test_case_ec_sign.h b/src/tests/p11test/p11test_case_ec_sign.h new file mode 100644 index 0000000000..299a92f25d --- /dev/null +++ b/src/tests/p11test/p11test_case_ec_sign.h @@ -0,0 +1,25 @@ +/* + * p11test_case_ec_sign.h: Test different data lengths for EC signatures + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void ec_sign_size_test(void **state); diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c new file mode 100644 index 0000000000..b8b31ee3e3 --- /dev/null +++ b/src/tests/p11test/p11test_case_mechs.c @@ -0,0 +1,138 @@ +/* + * p11test_case_mechs.c: Check mechanisms supported by token + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_mechs.h" + +void supported_mechanisms_test(void **state) { + token_info_t *info = (token_info_t *) *state; + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + + CK_RV rv; + CK_ULONG mechanism_count, i; + CK_MECHANISM_TYPE_PTR mechanism_list; + CK_MECHANISM_INFO_PTR mechanism_info; + CK_FLAGS j; + test_mech_t *mech = NULL; + + P11TEST_START(info); + rv = function_pointer->C_GetMechanismList(info->slot_id, NULL_PTR, + &mechanism_count); + if ((rv == CKR_OK) && (mechanism_count > 0)) { + mechanism_list = (CK_MECHANISM_TYPE_PTR) + malloc(mechanism_count * sizeof(CK_MECHANISM_TYPE)); + rv = function_pointer->C_GetMechanismList(info->slot_id, + mechanism_list, &mechanism_count); + if (rv != CKR_OK) { + free(mechanism_list); + function_pointer->C_Finalize(NULL_PTR); + P11TEST_FAIL(info, "Could not get mechanism list!"); + } + + mechanism_info = (CK_MECHANISM_INFO_PTR) + malloc(mechanism_count * sizeof(CK_MECHANISM_INFO)); + if (mechanism_info == NULL) + P11TEST_FAIL(info, "Couldn't malloc()"); + + for (i = 0; i < mechanism_count; i++) { + CK_MECHANISM_TYPE mechanism_type = mechanism_list[i]; + rv = function_pointer->C_GetMechanismInfo(info->slot_id, + mechanism_type, &mechanism_info[i]); + if (rv != CKR_OK) + continue; + + /* store mechanisms list for later tests */ + + /* List all known RSA mechanisms */ + if (mechanism_list[i] == CKM_RSA_X_509 + || mechanism_list[i] == CKM_RSA_PKCS + || mechanism_list[i] == CKM_MD5_RSA_PKCS + || mechanism_list[i] == CKM_RIPEMD160_RSA_PKCS + || mechanism_list[i] == CKM_SHA1_RSA_PKCS + || mechanism_list[i] == CKM_SHA224_RSA_PKCS + || mechanism_list[i] == CKM_SHA256_RSA_PKCS + || mechanism_list[i] == CKM_SHA384_RSA_PKCS + || mechanism_list[i] == CKM_SHA512_RSA_PKCS + || mechanism_list[i] == CKM_RSA_PKCS_PSS + || mechanism_list[i] == CKM_SHA1_RSA_PKCS_PSS + || mechanism_list[i] == CKM_SHA256_RSA_PKCS_PSS + || mechanism_list[i] == CKM_SHA384_RSA_PKCS_PSS + || mechanism_list[i] == CKM_SHA512_RSA_PKCS_PSS + || mechanism_list[i] == CKM_RSA_PKCS_OAEP) { + if (token.num_rsa_mechs < MAX_MECHS) { + mech = &token.rsa_mechs[token.num_rsa_mechs++]; + mech->mech = mechanism_list[i]; + mech->usage_flags = mechanism_info[i].flags; + } else + P11TEST_FAIL(info, "Too many RSA mechanisms (%d)", MAX_MECHS); + } + + /* We list all known EC mechanisms */ + if (mechanism_list[i] == CKM_ECDSA + || mechanism_list[i] == CKM_ECDSA_SHA1 + || mechanism_list[i] == CKM_ECDSA_SHA256 + || mechanism_list[i] == CKM_ECDSA_SHA384 + || mechanism_list[i] == CKM_ECDSA_SHA512) { + if (token.num_ec_mechs < MAX_MECHS) { + mech = &token.ec_mechs[token.num_ec_mechs++]; + mech->mech = mechanism_list[i]; + mech->usage_flags = mechanism_info[i].flags; + } else + P11TEST_FAIL(info, "Too many EC mechanisms (%d)", MAX_MECHS); + } + if ((mechanism_info[i].flags & CKF_GENERATE_KEY_PAIR) != 0) { + if (token.num_keygen_mechs < MAX_MECHS) { + mech = &token.keygen_mechs[token.num_keygen_mechs++]; + mech->mech = mechanism_list[i]; + mech->usage_flags = mechanism_info[i].flags; + } else + P11TEST_FAIL(info, "Too many KEYGEN mechanisms (%d)", MAX_MECHS); + } + } + + printf("[ MECHANISM ] [ KEY SIZE ] [ FLAGS ]\n"); + printf("[ CKM_* ] [ MIN][ MAX] [ ]\n"); + P11TEST_DATA_ROW(info, 4, + 's', "MECHANISM", + 's', "MIN KEY", + 's', "MAX KEY", + 's', "FLAGS"); + for (i = 0; i < mechanism_count; i++) { + printf("[%-21s] [%4lu][%4lu] [%10s]", + get_mechanism_name(mechanism_list[i]), + mechanism_info[i].ulMinKeySize, + mechanism_info[i].ulMaxKeySize, + get_mechanism_flag_name(mechanism_info[i].flags)); + P11TEST_DATA_ROW(info, 4, + 's', get_mechanism_name(mechanism_list[i]), + 'd', mechanism_info[i].ulMinKeySize, + 'd', mechanism_info[i].ulMaxKeySize, + 's', get_mechanism_flag_name(mechanism_info[i].flags)); + for (j = 1; j <= CKF_EC_COMPRESS; j = j<<1) + if ((mechanism_info[i].flags & j) != 0) + printf(" %s", get_mechanism_flag_name(j)); + printf("\n"); + } + free(mechanism_list); + free(mechanism_info); + } + P11TEST_PASS(info); +} + diff --git a/src/tests/p11test/p11test_case_mechs.h b/src/tests/p11test/p11test_case_mechs.h new file mode 100644 index 0000000000..ff3439cd4a --- /dev/null +++ b/src/tests/p11test/p11test_case_mechs.h @@ -0,0 +1,24 @@ +/* + * p11test_case_mechs.h: Check mechanisms supported by token + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" + +void supported_mechanisms_test(void **state); diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c new file mode 100644 index 0000000000..0aa45638e1 --- /dev/null +++ b/src/tests/p11test/p11test_case_multipart.c @@ -0,0 +1,107 @@ +/* + * p11test_case_multipart.c: Multipart Sign & Verify tests (RSA only) + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_multipart.h" + +void multipart_tests(void **state) { + + token_info_t *info = (token_info_t *) *state; + unsigned int i; + int used, j; + test_certs_t objects; + + objects.count = 0; + objects.data = NULL; + + P11TEST_START(info); + search_for_all_objects(&objects, info); + + debug_print("\nCheck functionality of Multipart Sign&Verify and/or Encrypt&Decrypt"); + for (i = 0; i < objects.count; i++) { + if (objects.data[i].type == EVP_PK_EC) { + debug_print(" [ SKIP %s ] EC keys do not support multi-part operations", + objects.data[i].id_str); + continue; + } + used = 0; + /* do the Sign&Verify and/or Encrypt&Decrypt */ + /* XXX some keys do not have appropriate flags, but we can use them + * or vice versa */ + //if (objects.data[i].sign && objects.data[i].verify) + for (j = 0; j < objects.data[i].num_mechs; j++) + used |= sign_verify_test(&(objects.data[i]), info, + &(objects.data[i].mechs[j]), 32, 1); + + if (!used) { + debug_print(" [ WARN %s ] Private key with unknown purpose T:%02lX", + objects.data[i].id_str, objects.data[i].key_type); + } + } + + if (objects.count == 0) { + printf(" [WARN] No objects to display\n"); + return; + } + + /* print summary */ + printf("[KEY ID] [TYPE] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [LABEL]\n"); + P11TEST_DATA_ROW(info, 3, + 's', "KEY ID", + 's', "MECHANISM", + 's', "MULTIPART SIGN&VERIFY WORKS"); + for (i = 0; i < objects.count; i++) { + if (objects.data[i].type == EVP_PK_EC) + continue; + printf("[%-6s] [%s] [%6lu] [ %s ] [%s%s] [%s]\n", + objects.data[i].id_str, + objects.data[i].key_type == CKK_RSA ? "RSA " : + objects.data[i].key_type == CKK_EC ? " EC " : " ?? ", + objects.data[i].bits, + objects.data[i].verify_public == 1 ? " ./ " : " ", + objects.data[i].sign ? "[./] " : "[ ] ", + objects.data[i].verify ? " [./] " : " [ ] ", + objects.data[i].label); + for (j = 0; j < objects.data[i].num_mechs; j++) { + test_mech_t *mech = &objects.data[i].mechs[j]; + if ((mech->usage_flags & CKF_SIGN) == 0) { + /* not applicable mechanisms are skipped */ + continue; + } + printf(" [ %-20s ] [ %s ]\n", + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " "); + if ((mech->result_flags & FLAGS_SIGN_ANY) == 0) + continue; /* do not export unknown and non-working algorithms */ + P11TEST_DATA_ROW(info, 3, + 's', objects.data[i].id_str, + 's', get_mechanism_name(mech->mech), + 's', mech->result_flags & FLAGS_SIGN_ANY ? "YES" : ""); + } + printf("\n"); + } + printf(" Public == Cert ------------^ ^ ^ ^\n"); + printf(" Sign Attribute --------------------' | |\n"); + printf(" Sign&Verify functionality ------------' |\n"); + printf(" Verify Attribute ------------------------'\n"); + + clean_all_objects(&objects); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_multipart.h b/src/tests/p11test/p11test_case_multipart.h new file mode 100644 index 0000000000..3ca6f97dd6 --- /dev/null +++ b/src/tests/p11test/p11test_case_multipart.h @@ -0,0 +1,26 @@ +/* + * p11test_case_multipart.h: Multipart Sign & Verify tests (RSA only) + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void multipart_tests(void **state); + diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c new file mode 100644 index 0000000000..d0b8392fd2 --- /dev/null +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -0,0 +1,874 @@ +/* + * p11test_case_pss_oaep.c: RSA-PSS and RSA-OAEP tests + * + * Copyright (C) 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_pss_oaep.h" +#include "libopensc/internal.h" + +#include +#include + +#define SHORT_MESSAGE_TO_SIGN "Simple message for signing & verifying. It needs to be little bit longer to fit also longer keys and allow the truncation.\n" +#define BUFFER_SIZE 4096 + +const unsigned char *global_message = (unsigned char *) SHORT_MESSAGE_TO_SIGN; +size_t global_message_length = sizeof(SHORT_MESSAGE_TO_SIGN); + +const CK_MECHANISM_TYPE * +get_oaep_mechanism_hashes(CK_MECHANISM_TYPE mech) +{ + static CK_MECHANISM_TYPE h[6]; + + switch (mech) { + case CKM_RSA_PKCS_OAEP: + h[0] = CKM_SHA_1; + h[1] = CKM_SHA224; + h[2] = CKM_SHA256; + h[3] = CKM_SHA384; + h[4] = CKM_SHA512; + h[5] = -1; + break; + + default: + h[0] = -1; + break; + } + + return h; +} +const CK_MECHANISM_TYPE * +get_pss_mechanism_hashes(CK_MECHANISM_TYPE mech) +{ + static CK_MECHANISM_TYPE h[6]; + + switch (mech) { + case CKM_RSA_PKCS_PSS: + h[0] = CKM_SHA_1; + h[1] = CKM_SHA224; + h[2] = CKM_SHA256; + h[3] = CKM_SHA384; + h[4] = CKM_SHA512; + h[5] = -1; + break; + + case CKM_SHA1_RSA_PKCS_PSS: + h[0] = CKM_SHA_1; + h[1] = -1; + break; + + case CKM_SHA224_RSA_PKCS_PSS: + h[0] = CKM_SHA224; + h[1] = -1; + break; + + case CKM_SHA256_RSA_PKCS_PSS: + h[0] = CKM_SHA256; + h[1] = -1; + break; + + case CKM_SHA384_RSA_PKCS_PSS: + h[0] = CKM_SHA384; + h[1] = -1; + break; + + case CKM_SHA512_RSA_PKCS_PSS: + h[0] = CKM_SHA512; + h[1] = -1; + break; + + default: + h[0] = -1; + break; + } + + return h; +} + +const CK_MECHANISM_TYPE * +get_mechanism_hashes(CK_MECHANISM_TYPE mech) +{ + if (mech == CKM_RSA_PKCS_OAEP) + return get_oaep_mechanism_hashes(mech); + else + return get_pss_mechanism_hashes(mech); +} + +const CK_RSA_PKCS_MGF_TYPE * +get_mgfs(void) +{ + static CK_RSA_PKCS_MGF_TYPE h[6]; + h[0] = CKG_MGF1_SHA1; + h[1] = CKG_MGF1_SHA224; + h[2] = CKG_MGF1_SHA256; + h[3] = CKG_MGF1_SHA384; + h[4] = CKG_MGF1_SHA512; + h[5] = -1; + return h; +} + +const EVP_MD *mgf_cryptoki_to_ossl(CK_RSA_PKCS_MGF_TYPE mgf) +{ + switch (mgf) { + case CKG_MGF1_SHA224: + return EVP_sha224(); + + case CKG_MGF1_SHA256: + return EVP_sha256(); + + case CKG_MGF1_SHA384: + return EVP_sha384(); + + case CKG_MGF1_SHA512: + return EVP_sha512(); + + case CKG_MGF1_SHA1: + default: + return EVP_sha1(); + + } +} + +const EVP_MD *md_cryptoki_to_ossl(CK_MECHANISM_TYPE hash) +{ + /* Digest mechanisms */ + switch (hash) { + case CKM_SHA224: + return EVP_sha224(); + + case CKM_SHA256: + return EVP_sha256(); + + case CKM_SHA384: + return EVP_sha384(); + + case CKM_SHA512: + return EVP_sha512(); + + case CKM_SHA_1: + default: + return EVP_sha1(); + + } +} + +size_t get_hash_length(CK_MECHANISM_TYPE mech) +{ + switch (mech) { + case CKM_SHA224: + return SHA224_DIGEST_LENGTH; + case CKM_SHA256: + return SHA256_DIGEST_LENGTH; + case CKM_SHA384: + return SHA384_DIGEST_LENGTH; + case CKM_SHA512: + return SHA512_DIGEST_LENGTH; + default: + case CKM_SHA_1: + return SHA_DIGEST_LENGTH; + } +} + +CK_BYTE *hash_message(const CK_BYTE *message, size_t message_length, + CK_MECHANISM_TYPE hash) +{ + switch (hash) { + case CKM_SHA224: + return SHA224(message, message_length, NULL); + + case CKM_SHA256: + return SHA256(message, message_length, NULL); + + case CKM_SHA384: + return SHA384(message, message_length, NULL); + + case CKM_SHA512: + return SHA512(message, message_length, NULL); + + case CKM_SHA_1: + default: + return SHA1(message, message_length, NULL); + + } +} + +int oaep_encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message) +{ + size_t enc_length = 0; + CK_RV rv = -1; + EVP_PKEY_CTX *pctx = NULL; + const EVP_MD *md = EVP_md_null(); + const EVP_MD *mgf1_md = EVP_md_null(); + EVP_PKEY *key = NULL; + + md = md_cryptoki_to_ossl(mech->hash); + mgf1_md = mgf_cryptoki_to_ossl(mech->mgf); + + if ((key = EVP_PKEY_new()) == NULL + || RSA_up_ref(o->key.rsa) < 1 + || EVP_PKEY_set1_RSA(key, o->key.rsa) != 1) { + fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } + + if ((pctx = EVP_PKEY_CTX_new(key, NULL)) == NULL + || EVP_PKEY_encrypt_init(pctx) != 1 + || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_OAEP_PADDING) != 1 + || EVP_PKEY_CTX_set_rsa_oaep_md(pctx, md) != 1 + || EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_md) != 1) { + fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY_CTX. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &enc_length, message, message_length) <= 0) { + fprintf(stderr, " [ ERROR %s ] Failed get signature length. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } + + *enc_message = OPENSSL_malloc(enc_length); + + rv = EVP_PKEY_encrypt(pctx, *enc_message, &enc_length, message, message_length); + if (rv <= 0) { + fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + } +out: + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(key); + return enc_length; +} + +void fill_oaep_params(CK_RSA_PKCS_OAEP_PARAMS *oaep_params, + test_mech_t *mech) +{ + oaep_params->hashAlg = mech->hash; + oaep_params->mgf = mech->mgf; + oaep_params->source = CKZ_DATA_SPECIFIED; + oaep_params->pSourceData = NULL; + oaep_params->ulSourceDataLen = 0; + +} + +int oaep_encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM enc_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; + CK_ULONG enc_message_length; + static int encrypt_support = 1; + + fill_oaep_params(&oaep_params, mech); + enc_mechanism.pParameter = &oaep_params; + enc_mechanism.ulParameterLen = sizeof(oaep_params); + + if (!encrypt_support) + goto openssl_encrypt; + + rv = fp->C_EncryptInit(info->session_handle, &enc_mechanism, + o->public_handle); + if (rv != CKR_OK) { + debug_print(" C_EncryptInit: rv = 0x%.8lX", rv); + encrypt_support = 0; /* avoid trying over and over again */ + goto openssl_encrypt; + } + + /* get the expected length */ + rv = fp->C_Encrypt(info->session_handle, message, message_length, + NULL, &enc_message_length); + if (rv != CKR_OK) { + debug_print(" C_Encrypt: rv = 0x%.8lX", rv); + goto openssl_encrypt; + } + *enc_message = malloc(enc_message_length); + if (*enc_message == NULL) { + debug_print("malloc returned null"); + return -1; + } + + /* Do the actual encryption with allocated buffer */ + rv = fp->C_Encrypt(info->session_handle, message, message_length, + *enc_message, &enc_message_length); + if (rv == CKR_OK) { + mech->result_flags |= FLAGS_DECRYPT_OPENSSL; + return enc_message_length; + } + debug_print(" C_Encrypt: rv = 0x%.8lX", rv); + +openssl_encrypt: + debug_print(" [ KEY %s ] Falling back to openssl encryption", o->id_str); + return oaep_encrypt_message_openssl(o, info, message, message_length, mech, + enc_message); +} + +int oaep_decrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *enc_message, + CK_ULONG enc_message_length, test_mech_t *mech, unsigned char **dec_message) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM dec_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; + CK_ULONG dec_message_length = BUFFER_SIZE; + + fill_oaep_params(&oaep_params, mech); + dec_mechanism.pParameter = &oaep_params; + dec_mechanism.ulParameterLen = sizeof(oaep_params); + + rv = fp->C_DecryptInit(info->session_handle, &dec_mechanism, + o->private_handle); + if (rv == CKR_KEY_TYPE_INCONSISTENT) { + debug_print(" [SKIP %s ] Not allowed to decrypt with this key?", o->id_str); + return 0; + } else if (rv != CKR_OK) { + debug_print(" C_DecryptInit: rv = 0x%.8lX\n", rv); + return -1; + } + + *dec_message = malloc(dec_message_length); + + always_authenticate(o, info); + + rv = fp->C_Decrypt(info->session_handle, enc_message, + enc_message_length, *dec_message, &dec_message_length); + if (rv != CKR_OK) { + free(*dec_message); + debug_print(" C_Decrypt: rv = 0x%.8lX\n", rv); + return -1; + } + return (int) dec_message_length; +} + +/* Perform encryption and decryption of a message using private key referenced + * in the o object with mechanism defined by mech. + * + * NONE of the reasonable mechanisms support encryption/decryption + * + * Returns + * * 1 for successful Encrypt&Decrypt sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech) +{ + CK_BYTE *message = (CK_BYTE *) SHORT_MESSAGE_TO_SIGN; + CK_BYTE *dec_message = NULL; + int dec_message_length = 0; + int message_length = 16; + unsigned char *enc_message; + int enc_message_length, rv; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 0; + } + + if (o->type != EVP_PK_RSA) { + debug_print(" [ KEY %s ] Skip non-RSA key for encryption", o->id_str); + return 0; + } + + if (mech->mech != CKM_RSA_PKCS_OAEP) { + mech->usage_flags &= ~CKF_DECRYPT; + debug_print(" [SKIP %s ] non RSA-OAEP mechanism", o->id_str); + return 0; + } + + message_length = MIN((int)global_message_length, + (int)((o->bits+7)/8 - 2*get_hash_length(mech->hash) - 2)); + + /* will not work for 1024b RSA key and SHA512 hash: It has max size -2 */ + if (message_length < 0) { + mech->usage_flags &= ~CKF_DECRYPT; + debug_print(" [SKIP %s ] Too small modulus (%ld bits)" + " or too large hash %s (%lu B) for OAEP", o->id_str, + o->bits, get_mechanism_name(mech->hash), + get_hash_length(mech->hash)); + return 0; + } + + debug_print(" [ KEY %s ] Encrypt message of length %d using CKM_%s, " + "hash CKM_%s, mgf=CKG_%s", o->id_str, (unsigned) message_length, + get_mechanism_name(mech->mech), get_mechanism_name(mech->hash), + get_mgf_name(mech->mgf)); + enc_message_length = oaep_encrypt_message(o, info, message, + (unsigned) message_length, mech, &enc_message); + if (enc_message_length <= 0) { + return -1; + } + + debug_print(" [ KEY %s ] Decrypt message", o->id_str); + dec_message_length = oaep_decrypt_message(o, info, enc_message, + enc_message_length, mech, &dec_message); + free(enc_message); + if (dec_message_length <= 0) { + return -1; + } + + if (memcmp(dec_message, message, dec_message_length) == 0 + && dec_message_length == message_length) { + debug_print(" [ OK %s ] Text decrypted successfully.", o->id_str); + mech->result_flags |= FLAGS_DECRYPT; + rv = 1; + } else { + dec_message[dec_message_length] = '\0'; + debug_print(" [ ERROR %s ] Text decryption failed. Recovered text: %s", + o->id_str, dec_message); + rv = 0; + } + free(dec_message); + return rv; +} + +static int get_max_salt_len(unsigned long bits, CK_MECHANISM_TYPE hash) +{ + return (bits + 7)/8 - get_hash_length(hash) - 2; +} + +int fill_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, + test_mech_t *mech, test_cert_t *o) +{ + pss_params->hashAlg = mech->hash; + pss_params->mgf = mech->mgf; + switch (mech->salt){ + case -2: + /* max possible ( modlen - hashlen -2 ) */ + pss_params->sLen = get_max_salt_len(o->bits,mech->hash); + break; + case -1: + /* digest length */ + /* will not work with SHA512 and 1024b keys (max is 62b!) */ + if ((int) get_hash_length(mech->hash) > get_max_salt_len(o->bits, mech->hash)) { + return -1; + } + pss_params->sLen = get_hash_length(mech->hash); + break; + case 0: + default: + pss_params->sLen = 0; + break; + } + return 1; +} + +int pss_sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **sign) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_ULONG sign_length = 0; + CK_RSA_PKCS_PSS_PARAMS pss_params; + + if (fill_pss_params(&pss_params, mech, o) != 1) { + debug_print(" [SKIP %s ] Impossible to use requested salt length", o->id_str); + return 0; + } + sign_mechanism.pParameter = &pss_params; + sign_mechanism.ulParameterLen = sizeof(pss_params); + + rv = fp->C_SignInit(info->session_handle, &sign_mechanism, + o->private_handle); + if (rv == CKR_KEY_TYPE_INCONSISTENT) { + debug_print(" [SKIP %s ] Not allowed to sign with this key?", o->id_str); + return 0; + } else if (rv == CKR_MECHANISM_INVALID) { + debug_print(" [SKIP %s ] Bad mechanism. Not supported?", o->id_str); + return 0; + } else if (rv != CKR_OK) { + debug_print(" C_SignInit: rv = 0x%.8lX\n", rv); + return -1; + } + + always_authenticate(o, info); + + /* Call C_Sign with NULL argument to find out the real size of signature */ + rv = fp->C_Sign(info->session_handle, + message, message_length, *sign, &sign_length); + if (rv != CKR_OK) { + fprintf(stderr, " C_Sign: rv = 0x%.8lX\n", rv); + return -1; + } + + *sign = malloc(sign_length); + if (*sign == NULL) { + fprintf(stderr, "%s: malloc failed", __func__); + return -1; + } + + /* Call C_Sign with allocated buffer to the actual signature */ + rv = fp->C_Sign(info->session_handle, + message, message_length, *sign, &sign_length); + + if (rv != CKR_OK) { + free(*sign); + fprintf(stderr, " C_Sign: rv = 0x%.8lX\n", rv); + return -1; + } + return sign_length; +} + +int pss_verify_message_openssl(test_cert_t *o, token_info_t *info, + CK_BYTE *message, CK_ULONG message_length, test_mech_t *mech, + unsigned char *sign, CK_ULONG sign_length) +{ + CK_RV rv = -1; + EVP_PKEY_CTX *pctx = NULL; + const CK_BYTE *my_message; + CK_ULONG my_message_length; + const EVP_MD *mgf_md = EVP_md_null(); + const EVP_MD *md = EVP_md_null(); + EVP_PKEY *key = NULL; + + md = md_cryptoki_to_ossl(mech->hash); + mgf_md = mgf_cryptoki_to_ossl(mech->mgf); + + if (mech->mech != CKM_RSA_PKCS_PSS) { + my_message = hash_message(message, message_length, mech->hash); + my_message_length = get_hash_length(mech->hash); + } else { + my_message = message; + my_message_length = message_length; + } + + if ((key = EVP_PKEY_new()) == NULL + || RSA_up_ref(o->key.rsa) < 1 + || EVP_PKEY_set1_RSA(key, o->key.rsa) != 1) { + fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } + + if ((pctx = EVP_PKEY_CTX_new(key, NULL)) == NULL + || EVP_PKEY_verify_init(pctx) != 1 + || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) != 1 + || EVP_PKEY_CTX_set_signature_md(pctx, md) != 1 + || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, mech->salt) != 1 + || EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf_md) != 1) { + fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY_CTX. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } + + rv = EVP_PKEY_verify(pctx, sign, sign_length, my_message, my_message_length); + if (rv == 1) { + debug_print(" [ OK %s ] Signature is valid.", o->id_str); + mech->result_flags |= FLAGS_SIGN_OPENSSL; + } else { + fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + goto out; + } +out: + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(key); + return rv; +} + +int pss_verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char *sign, + CK_ULONG sign_length) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_RSA_PKCS_PSS_PARAMS pss_params; + static int verify_support = 1; + + if (!verify_support) + goto openssl_verify; + + fill_pss_params(&pss_params, mech, o); + sign_mechanism.pParameter = &pss_params; + sign_mechanism.ulParameterLen = sizeof(pss_params); + + /* try C_Verify() if it is supported */ + rv = fp->C_VerifyInit(info->session_handle, &sign_mechanism, + o->public_handle); + if (rv != CKR_OK) { + debug_print(" C_VerifyInit: rv = 0x%.8lX", rv); + verify_support = 0; /* avoid trying over and over again */ + goto openssl_verify; + } + + rv = fp->C_Verify(info->session_handle, + message, message_length, sign, sign_length); + + if (rv == CKR_OK) { + mech->result_flags |= FLAGS_SIGN; + debug_print(" [ OK %s ] Verification successful", o->id_str); + return 1; + } + debug_print(" C_Verify: rv = 0x%.8lX", rv); + verify_support = 0; /* avoid trying over and over again */ + +openssl_verify: + debug_print(" [ KEY %s ] Falling back to openssl verification", o->id_str); + return pss_verify_message_openssl(o, info, message, message_length, mech, + sign, sign_length); +} + +/* Perform signature and verification of a message using private key referenced + * in the o object with mechanism defined by mech. + * + * Returns + * * 1 for successful Sign&Verify sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int pss_sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech) +{ + CK_BYTE *message = NULL; + size_t message_length = global_message_length; + CK_BYTE *sign = NULL; + CK_ULONG sign_length = 0; + int rv = 0; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 0; + } + + if (o->type != EVP_PK_RSA) { + debug_print(" [SKIP %s ] Skip non-RSA key", o->id_str); + return 0; + } + + if (!is_pss_mechanism(mech->mech)) { + mech->usage_flags &= ~CKF_SIGN; + debug_print(" [SKIP %s ] non RSA-PSS mechanism %s", o->id_str, + get_mechanism_name(mech->mech)); + return 0; + } + + if (mech->mech == CKM_RSA_PKCS_PSS) { + message = hash_message(global_message, global_message_length, + mech->hash); + message_length = get_hash_length(mech->hash); + } else { + message = (unsigned char *) SHORT_MESSAGE_TO_SIGN; + } + + debug_print(" [ KEY %s ] Signing message using CKM_%s, CKM_%s," + " CKG_%s, salt_len=%d", o->id_str, + get_mechanism_name(mech->mech), get_mechanism_name(mech->hash), + get_mgf_name(mech->mgf), mech->salt); + rv = pss_sign_message(o, info, message, message_length, mech, &sign); + if (rv <= 0) { + return rv; + } + sign_length = (unsigned long) rv; + + debug_print(" [ KEY %s ] Verify message signature", o->id_str); + rv = pss_verify_message(o, info, message, message_length, mech, + sign, sign_length); + free(sign); + return rv; +} + +/* ignore the prefilled mechanisms and list all combinations of mechanisms + * found, all resonable hash functions, MGFs and salt lengths + */ +void fill_object_pss_mechanisms(token_info_t *info, test_cert_t *o) +{ + const CK_MECHANISM_TYPE *h; + const CK_RSA_PKCS_MGF_TYPE *mgf; + int n = 0, s; + unsigned int j; + + for (j = 0; j < token.num_rsa_mechs; j++) { + test_mech_t *source_mech = &token.rsa_mechs[j]; + + /* skip non-RSA-PSS mechs early */ + if (!is_pss_mechanism(source_mech->mech) && + source_mech->mech != CKM_RSA_PKCS_OAEP) { + continue; + } + + h = get_mechanism_hashes(source_mech->mech); + for (; *h != (CK_MECHANISM_TYPE) -1; h++) { + mgf = get_mgfs(); + for (; *mgf != (CK_RSA_PKCS_MGF_TYPE) -1; mgf++) { + /* OAEP does not have salt */ + if (source_mech->mech == CKM_RSA_PKCS_OAEP) + s = 0; + else + s = -2; + + for (; s <= 0; s++) { + test_mech_t *mech = &o->mechs[n++]; + mech->mech = source_mech->mech; + mech->hash = *h; + mech->mgf = *mgf; + mech->salt = s; + mech->usage_flags = + source_mech->usage_flags; + mech->result_flags = 0; + if (n >= MAX_MECHS) + P11TEST_FAIL(info, + "Too many mechanisms (%d)", + MAX_MECHS); + } + } + } + + } + o->num_mechs = n; +} + +int have_pss_oaep_mechanisms() +{ + unsigned have = 0, i; + for (i = 0; i <= token.num_rsa_mechs; i++) { + if (is_pss_mechanism(token.rsa_mechs[i].mech) || + token.rsa_mechs[i].mech == CKM_RSA_PKCS_OAEP) { + have++; + } + } + return have; +} + +void pss_oaep_test(void **state) { + + token_info_t *info = (token_info_t *) *state; + unsigned int i; + int used, j; + test_certs_t objects; + + P11TEST_START(info); + + if (have_pss_oaep_mechanisms() == 0) { + fprintf(stderr, "Token does not support any RSA-PSS or OAEP mechanisms. Skipping.\n"); + skip(); + } + + objects.count = 0; + objects.data = NULL; + search_for_all_objects(&objects, info); + + debug_print("\nCheck functionality of Sign&Verify and/or Encrypt&Decrypt"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + /* do the Sign&Verify and/or Encrypt&Decrypt */ + used = 0; + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", + o->id_str); + continue; + } + fill_object_pss_mechanisms(info, o); + for (j = 0; j < o->num_mechs; j++) + if (o->mechs[j].mech != CKM_RSA_PKCS_OAEP) + used |= pss_sign_verify_test(o, info, + &(o->mechs[j])); + + for (j = 0; j < o->num_mechs; j++) + if (o->mechs[j].mech == CKM_RSA_PKCS_OAEP) + used |= oaep_encrypt_decrypt_test(o, info, + &(o->mechs[j])); + + if (!used) { + debug_print(" [ WARN %s ] Private key with unknown purpose T:%02lX", + o->id_str, o->key_type); + } + } + + if (objects.count == 0) { + printf(" [WARN] No objects to display\n"); + return; + } + + /* print summary */ + printf("[KEY ID] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT]\n"); + printf("[ MECHANISM ] [ HASH ] [ MGF ] [SALT] [ WORKS ] [ WORKS ]\n"); + P11TEST_DATA_ROW(info, 7, + 's', "KEY ID", + 's', "MECHANISM", + 's', "HASH", + 's', "MGF", + 's', "SALT", + 's', "SIGN&VERIFY WORKS", + 's', "ENCRYPT&DECRYPT WORKS"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + + /* Do not list non-RSA keys here */ + if (o->type != EVP_PK_RSA) + continue; + + printf("\n[%-6s] [%s]\n", + o->id_str, + o->label); + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s]\n", + o->key_type == CKK_RSA ? "RSA " : + o->key_type == CKK_EC ? " EC " : " ?? ", + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] "); + if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { + printf(" no usable attributes found ... ignored\n"); + continue; + } + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; + printf(" [ %-20s ] [%-6s] [%-11s] [%4d] [ %s ] [ %s ]\n", + get_mechanism_name(mech->mech), + get_mechanism_name(mech->hash), + get_mgf_name(mech->mgf), + mech->salt, + mech->result_flags & FLAGS_SIGN_ANY + ? "[./]" : " ", + mech->result_flags & FLAGS_DECRYPT_ANY + ? "[./]" : " "); + if ((mech->result_flags & FLAGS_SIGN_ANY) == 0 && + (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) + continue; /* skip empty rows for export */ + P11TEST_DATA_ROW(info, 7, + 's', o->id_str, + 's', get_mechanism_name(mech->mech), + 's', get_mechanism_name(mech->hash), + 's', get_mgf_name(mech->mgf), + 'd', mech->salt, + 's', mech->result_flags & FLAGS_SIGN_ANY + ? "YES" : "", + 's', mech->result_flags & FLAGS_DECRYPT_ANY + ? "YES" : ""); + } + } + printf(" Public == Cert ----------^ ^ ^ ^ ^ ^ ^\n"); + printf(" Sign Attribute -------------------------------------------' | | | | |\n"); + printf(" Sign&Verify functionality -----------------------------------' | | | |\n"); + printf(" Verify Attribute -----------------------------------------------' | | |\n"); + printf(" Encrypt Attribute ------------------------------------------------------' | |\n"); + printf(" Encrypt & Decrypt functionality -------------------------------------------' |\n"); + printf(" Decrypt Attribute ------------------------------------------------------------'\n"); + + clean_all_objects(&objects); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_pss_oaep.h b/src/tests/p11test/p11test_case_pss_oaep.h new file mode 100644 index 0000000000..ce2185352c --- /dev/null +++ b/src/tests/p11test/p11test_case_pss_oaep.h @@ -0,0 +1,24 @@ +/* + * p11test_case_pss_oaep.h: RSA-PSS and RSA-OAEP tests + * + * Copyright (C) 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" + +void pss_oaep_test(void **state); diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c new file mode 100644 index 0000000000..9815bea584 --- /dev/null +++ b/src/tests/p11test/p11test_case_readonly.c @@ -0,0 +1,699 @@ +/* + * p11test_case_readonly.c: Sign & Verify tests + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_readonly.h" + +#include +#include +#include + +#define SHORT_MESSAGE_TO_SIGN "Simple message for signing & verifying. It needs to be little bit longer to fit also longer keys and allow the truncation.\n" +#define SHORT_MESSAGE_DIGEST "\x30\x21\x30\x09\x06\x05\x2b\x0e" \ + "\x03\x02\x1a\x05\x00\x04\x14\xd9" \ + "\xdd\xa3\x76\x44\x2f\x50\xe1\xec" \ + "\xd3\x8b\xcd\x6f\xc6\xce\x4e\xfd" \ + "\xd3\x1a\x3f" +#define BUFFER_SIZE 4096 + +const unsigned char *const_message = (unsigned char *) SHORT_MESSAGE_TO_SIGN; + +static unsigned char * +rsa_x_509_pad_message(const unsigned char *message, + unsigned long *message_length, test_cert_t *o, int encrypt) +{ + int pad_message_length = (o->bits+7)/8; + unsigned char *pad_message = malloc(pad_message_length); + if (!encrypt) + RSA_padding_add_PKCS1_type_1(pad_message, pad_message_length, + message, *message_length); + else + RSA_padding_add_PKCS1_type_2(pad_message, pad_message_length, + message, *message_length); + *message_length = pad_message_length; + return pad_message; +} + +int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message) +{ + int rv, padding; + + *enc_message = malloc(RSA_size(o->key.rsa)); + if (*enc_message == NULL) { + debug_print("malloc returned null"); + return -1; + } + + /* Prepare padding for RSA_X_509 */ + padding = ((mech->mech == CKM_RSA_X_509) ? RSA_NO_PADDING : RSA_PKCS1_PADDING); + rv = RSA_public_encrypt(message_length, message, + *enc_message, o->key.rsa, padding); + if (rv < 0) { + free(*enc_message); + debug_print("RSA_public_encrypt: rv = 0x%.8X\n", rv); + return -1; + } + return rv; +} + +int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM enc_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_ULONG enc_message_length; + static int encrypt_support = 1; + + if (!encrypt_support) + goto openssl_encrypt; + + rv = fp->C_EncryptInit(info->session_handle, &enc_mechanism, + o->public_handle); + if (rv != CKR_OK) { + debug_print(" C_EncryptInit: rv = 0x%.8lX", rv); + encrypt_support = 0; /* avoid trying over and over again */ + goto openssl_encrypt; + } + + /* get the expected length */ + rv = fp->C_Encrypt(info->session_handle, message, message_length, + NULL, &enc_message_length); + if (rv != CKR_OK) { + debug_print(" C_Encrypt: rv = 0x%.8lX", rv); + goto openssl_encrypt; + } + *enc_message = malloc(enc_message_length); + if (*enc_message == NULL) { + debug_print("malloc returned null"); + return -1; + } + + /* Do the actual encryption with allocated buffer */ + rv = fp->C_Encrypt(info->session_handle, message, message_length, + *enc_message, &enc_message_length); + if (rv == CKR_OK) { + mech->result_flags |= FLAGS_SIGN; + return enc_message_length; + } + debug_print(" C_Encrypt: rv = 0x%.8lX", rv); + +openssl_encrypt: + debug_print(" [ KEY %s ] Falling back to openssl encryption", o->id_str); + return encrypt_message_openssl(o, info, message, message_length, mech, + enc_message); +} + +int decrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *enc_message, + CK_ULONG enc_message_length, test_mech_t *mech, unsigned char **dec_message) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM dec_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_ULONG dec_message_length = BUFFER_SIZE; + + rv = fp->C_DecryptInit(info->session_handle, &dec_mechanism, + o->private_handle); + if (rv == CKR_KEY_TYPE_INCONSISTENT) { + debug_print(" [SKIP %s ] Not allowed to decrypt with this key?", o->id_str); + return 0; + } else if (rv != CKR_OK) { + debug_print("C_DecryptInit: rv = 0x%.8lX\n", rv); + return -1; + } + + *dec_message = malloc(dec_message_length); + + always_authenticate(o, info); + + rv = fp->C_Decrypt(info->session_handle, enc_message, + enc_message_length, *dec_message, &dec_message_length); + if (rv != CKR_OK) { + free(*dec_message); + debug_print(" C_Decrypt: rv = 0x%.8lX\n", rv); + return -1; + } + return (int) dec_message_length; +} + +/* Perform encryption and decryption of a message using private key referenced + * in the o object with mechanism defined by mech. + * + * NONE of the reasonable mechanisms support multipart encryption/decryption + * + * Returns + * * 1 for successful Encrypt&Decrypt sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart) +{ + CK_BYTE *message = NULL; + CK_BYTE *dec_message = NULL; + int dec_message_length = 0; + unsigned char *enc_message; + int enc_message_length, rv; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 0; + } + + if (o->type != EVP_PK_RSA) { + debug_print(" [ KEY %s ] Skip non-RSA key for encryption", o->id_str); + return 0; + } + + if (mech->mech == CKM_RSA_PKCS_OAEP) { + mech->usage_flags &= ~CKF_DECRYPT; + debug_print(" [SKIP %s ] RSA-OAEP tested separately", o->id_str); + return 0; + } + + if (mech->mech != CKM_RSA_X_509 && mech->mech != CKM_RSA_PKCS) { + debug_print(" [ KEY %s ] Skip encryption for non-supported mechanism %s", + o->id_str, get_mechanism_name(mech->mech)); + return 0; + } + + if (mech->mech == CKM_RSA_X_509) + message = rsa_x_509_pad_message(const_message, + &message_length, o, 1); + else + message = (CK_BYTE *) strdup(SHORT_MESSAGE_TO_SIGN); + + debug_print(" [ KEY %s ] Encrypt message using CKM_%s", + o->id_str, get_mechanism_name(mech->mech)); + enc_message_length = encrypt_message(o, info, message, message_length, + mech, &enc_message); + if (enc_message_length <= 0) { + free(message); + return -1; + } + + debug_print(" [ KEY %s ] Decrypt message", o->id_str); + dec_message_length = decrypt_message(o, info, enc_message, + enc_message_length, mech, &dec_message); + free(enc_message); + if (dec_message_length <= 0) { + free(message); + return -1; + } + + if (memcmp(dec_message, message, dec_message_length) == 0 + && (unsigned int) dec_message_length == message_length) { + debug_print(" [ OK %s ] Text decrypted successfully.", o->id_str); + mech->result_flags |= FLAGS_DECRYPT; + rv = 1; + } else { + dec_message[dec_message_length] = '\0'; + debug_print(" [ ERROR %s ] Text decryption failed. Recovered text: %s", + o->id_str, dec_message); + rv = 0; + } + free(dec_message); + free(message); + return rv; +} + +int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **sign, + int multipart) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_ULONG sign_length = 0; + char *name; + + rv = fp->C_SignInit(info->session_handle, &sign_mechanism, + o->private_handle); + if (rv == CKR_KEY_TYPE_INCONSISTENT) { + debug_print(" [SKIP %s ] Not allowed to sign with this key?", o->id_str); + return 0; + } else if (rv == CKR_MECHANISM_INVALID) { + debug_print(" [SKIP %s ] Bad mechanism. Not supported?", o->id_str); + return 0; + } else if (rv != CKR_OK) { + debug_print(" C_SignInit: rv = 0x%.8lX\n", rv); + return -1; + } + + always_authenticate(o, info); + + if (multipart) { + int part = message_length / 3; + rv = fp->C_SignUpdate(info->session_handle, message, part); + if (rv == CKR_MECHANISM_INVALID) { + fprintf(stderr, " Multipart Signature not supported with CKM_%s\n", + get_mechanism_name(mech->mech)); + return -1; + } else if (rv != CKR_OK) { + fprintf(stderr, " C_SignUpdate: rv = 0x%.8lX\n", rv); + return -1; + } + rv = fp->C_SignUpdate(info->session_handle, message + part, message_length - part); + if (rv != CKR_OK) { + fprintf(stderr, " C_SignUpdate: rv = 0x%.8lX\n", rv); + return -1; + } + /* Call C_SignFinal with NULL argument to find out the real size of signature */ + rv = fp->C_SignFinal(info->session_handle, *sign, &sign_length); + if (rv != CKR_OK) { + fprintf(stderr, " C_SignFinal: rv = 0x%.8lX\n", rv); + return -1; + } + + *sign = malloc(sign_length); + if (*sign == NULL) { + fprintf(stderr, "%s: malloc failed", __func__); + return -1; + } + + /* Call C_SignFinal with allocated buffer to the actual signature */ + rv = fp->C_SignFinal(info->session_handle, *sign, &sign_length); + name = "C_SignFinal"; + } else { + /* Call C_Sign with NULL argument to find out the real size of signature */ + rv = fp->C_Sign(info->session_handle, + message, message_length, *sign, &sign_length); + if (rv != CKR_OK) { + fprintf(stderr, " C_Sign: rv = 0x%.8lX\n", rv); + return -1; + } + + *sign = malloc(sign_length); + if (*sign == NULL) { + fprintf(stderr, "%s: malloc failed", __func__); + return -1; + } + + /* Call C_Sign with allocated buffer to the actual signature */ + rv = fp->C_Sign(info->session_handle, + message, message_length, *sign, &sign_length); + name = "C_Sign"; + } + if (rv != CKR_OK) { + free(*sign); + fprintf(stderr, " %s: rv = 0x%.8lX\n", name, rv); + return -1; + } + return sign_length; +} + +int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char *sign, + CK_ULONG sign_length) +{ + CK_RV rv; + CK_BYTE *cmp_message = NULL; + int cmp_message_length; + + if (o->type == EVP_PK_RSA) { + int type; + + /* raw RSA mechanism */ + if (mech->mech == CKM_RSA_PKCS || mech->mech == CKM_RSA_X_509) { + CK_BYTE dec_message[BUFFER_SIZE]; + int padding = ((mech->mech == CKM_RSA_X_509) + ? RSA_NO_PADDING : RSA_PKCS1_PADDING); + int dec_message_length = RSA_public_decrypt(sign_length, sign, + dec_message, o->key.rsa, padding); + if (dec_message_length < 0) { + fprintf(stderr, "RSA_public_decrypt: rv = %d: %s\n", dec_message_length, + ERR_error_string(ERR_peek_last_error(), NULL)); + return -1; + } + if (memcmp(dec_message, message, dec_message_length) == 0 + && dec_message_length == (int) message_length) { + debug_print(" [ OK %s ] Signature is valid.", o->id_str); + mech->result_flags |= FLAGS_SIGN_OPENSSL; + return 1; + } else { + fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + return 0; + } + } + + /* Digest mechanisms */ + switch (mech->mech) { + case CKM_SHA1_RSA_PKCS: + cmp_message = SHA1(message, message_length, NULL); + cmp_message_length = SHA_DIGEST_LENGTH; + type = NID_sha1; + break; + case CKM_SHA224_RSA_PKCS: + cmp_message = SHA224(message, message_length, NULL); + cmp_message_length = SHA224_DIGEST_LENGTH; + type = NID_sha224; + break; + case CKM_SHA256_RSA_PKCS: + cmp_message = SHA256(message, message_length, NULL); + cmp_message_length = SHA256_DIGEST_LENGTH; + type = NID_sha256; + break; + case CKM_SHA384_RSA_PKCS: + cmp_message = SHA384(message, message_length, NULL); + cmp_message_length = SHA384_DIGEST_LENGTH; + type = NID_sha384; + break; + case CKM_SHA512_RSA_PKCS: + cmp_message = SHA512(message, message_length, NULL); + cmp_message_length = SHA512_DIGEST_LENGTH; + type = NID_sha512; + break; + case CKM_MD5_RSA_PKCS: + cmp_message = MD5(message, message_length, NULL); + cmp_message_length = MD5_DIGEST_LENGTH; + type = NID_md5; + break; + case CKM_RIPEMD160_RSA_PKCS: + cmp_message = RIPEMD160(message, message_length, NULL); + cmp_message_length = RIPEMD160_DIGEST_LENGTH; + type = NID_ripemd160; + break; + default: + debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); + return 0; + } + rv = RSA_verify(type, cmp_message, cmp_message_length, + sign, sign_length, o->key.rsa); + if (rv == 1) { + debug_print(" [ OK %s ] Signature is valid.", o->id_str); + mech->result_flags |= FLAGS_SIGN_OPENSSL; + } else { + fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + return -1; + } + } else if (o->type == EVP_PK_EC) { + unsigned int nlen; + ECDSA_SIG *sig = ECDSA_SIG_new(); + BIGNUM *r = NULL, *s = NULL; + if (sig == NULL) { + fprintf(stderr, "ECDSA_SIG_new: failed"); + return -1; + } + nlen = sign_length/2; + r = BN_bin2bn(&sign[0], nlen, NULL); + s = BN_bin2bn(&sign[nlen], nlen, NULL); + ECDSA_SIG_set0(sig, r, s); + switch (mech->mech) { + case CKM_ECDSA_SHA512: + cmp_message = SHA512(message, message_length, NULL); + cmp_message_length = SHA512_DIGEST_LENGTH; + break; + case CKM_ECDSA_SHA384: + cmp_message = SHA384(message, message_length, NULL); + cmp_message_length = SHA384_DIGEST_LENGTH; + break; + case CKM_ECDSA_SHA256: + cmp_message = SHA256(message, message_length, NULL); + cmp_message_length = SHA256_DIGEST_LENGTH; + break; + case CKM_ECDSA_SHA1: + cmp_message = SHA1(message, message_length, NULL); + cmp_message_length = SHA_DIGEST_LENGTH; + break; + case CKM_ECDSA: + cmp_message = message; + cmp_message_length = message_length; + break; + default: + debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); + return 0; + } + rv = ECDSA_do_verify(cmp_message, cmp_message_length, sig, o->key.ec); + if (rv == 1) { + ECDSA_SIG_free(sig); + debug_print(" [ OK %s ] EC Signature of length %lu is valid.", + o->id_str, message_length); + mech->result_flags |= FLAGS_SIGN_OPENSSL; + return 1; + } else { + ECDSA_SIG_free(sig); + fprintf(stderr, " [FAIL %s ] ECDSA_do_verify: rv = %lu: %s\n", o->id_str, + rv, ERR_error_string(ERR_peek_last_error(), NULL)); + return -1; + } + } else { + fprintf(stderr, " [ KEY %s ] Unknown type. Not verifying", o->id_str); + } + return 0; +} + +int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char *sign, + CK_ULONG sign_length, int multipart) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + static int verify_support = 1; +#ifndef NDEBUG + char *name; +#endif + + if (!verify_support) + goto openssl_verify; + + /* try C_Verify() if it is supported */ + rv = fp->C_VerifyInit(info->session_handle, &sign_mechanism, + o->public_handle); + if (rv != CKR_OK) { + debug_print(" C_VerifyInit: rv = 0x%.8lX", rv); + verify_support = 0; /* avoid trying over and over again */ + goto openssl_verify; + } + if (multipart) { + int part = message_length / 3; + /* First part */ + rv = fp->C_VerifyUpdate(info->session_handle, message, part); + if (rv != CKR_OK) { + debug_print(" C_VerifyUpdate: rv = 0x%.8lX", rv); + goto openssl_verify; + } + /* Second part */ + rv = fp->C_VerifyUpdate(info->session_handle, message + part, + message_length - part); + if (rv != CKR_OK) { + debug_print(" C_VerifyUpdate: rv = 0x%.8lX", rv); + goto openssl_verify; + } + /* Final */ + rv = fp->C_VerifyFinal(info->session_handle, + sign, sign_length); +#ifndef NDEBUG + name = "C_VerifyFinal"; +#endif + } else { + rv = fp->C_Verify(info->session_handle, + message, message_length, sign, sign_length); +#ifndef NDEBUG + name = "C_Verify"; +#endif + } + if (rv == CKR_OK) { + mech->result_flags |= FLAGS_SIGN; + debug_print(" [ OK %s ] Verification successful", o->id_str); + return 1; + } + debug_print(" %s: rv = 0x%.8lX", name, rv); + verify_support = 0; /* avoid trying over and over again */ + +openssl_verify: + debug_print(" [ KEY %s ] Falling back to openssl verification", o->id_str); + return verify_message_openssl(o, info, message, message_length, mech, + sign, sign_length); +} + +/* Perform signature and verification of a message using private key referenced + * in the o object with mechanism defined by mech. Message length can be + * specified using argument message_length. + * + * Returns + * * 1 for successful Sign&Verify sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart) +{ + CK_BYTE *message = NULL; + CK_BYTE *sign = NULL; + CK_ULONG sign_length = 0; + int rv = 0; + + if (message_length > strlen(SHORT_MESSAGE_TO_SIGN)) + fail_msg("Truncate is longer than the actual message"); + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 0; + } + + if (o->type != EVP_PK_EC && o->type != EVP_PK_RSA) { + debug_print(" [SKIP %s ] Skip non-RSA and non-EC key", o->id_str); + return 0; + } + + if (is_pss_mechanism(mech->mech)) { + mech->usage_flags &= ~CKF_SIGN; + debug_print(" [SKIP %s ] RSA-PSS tested separately", o->id_str); + return 0; + } + + if (mech->mech == CKM_RSA_X_509) /* manually add padding */ + message = rsa_x_509_pad_message(const_message, + &message_length, o, 0); + else if (mech->mech == CKM_RSA_PKCS) { + /* DigestInfo + SHA1(message) */ + message_length = 35; + message = malloc(message_length * sizeof(unsigned char)); + memcpy(message, SHORT_MESSAGE_DIGEST, message_length); + } else + message = (CK_BYTE *) strdup(SHORT_MESSAGE_TO_SIGN); + + debug_print(" [ KEY %s ] Signing message of length %lu using CKM_%s", + o->id_str, message_length, get_mechanism_name(mech->mech)); + rv = sign_message(o, info, message, message_length, mech, &sign, multipart); + if (rv <= 0) { + free(message); + return rv; + } + sign_length = (unsigned long) rv; + + debug_print(" [ KEY %s ] Verify message signature", o->id_str); + rv = verify_message(o, info, message, message_length, mech, + sign, sign_length, multipart); + free(sign); + free(message); + return rv; +} + +void readonly_tests(void **state) { + + token_info_t *info = (token_info_t *) *state; + unsigned int i; + int used, j; + test_certs_t objects; + + objects.count = 0; + objects.data = NULL; + + search_for_all_objects(&objects, info); + + P11TEST_START(info); + debug_print("\nCheck functionality of Sign&Verify and/or Encrypt&Decrypt"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + /* do the Sign&Verify and/or Encrypt&Decrypt */ + used = 0; + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", + o->id_str); + continue; + } + /* XXX some keys do not have appropriate flags, but we can use them + * or vice versa */ + //if (o->sign && o->verify) + for (j = 0; j < o->num_mechs; j++) + used |= sign_verify_test(&(objects.data[i]), info, + &(o->mechs[j]), 32, 0); + + //if (o->encrypt && o->decrypt) + for (j = 0; j < o->num_mechs; j++) + used |= encrypt_decrypt_test(&(objects.data[i]), info, + &(o->mechs[j]), 32, 0); + + if (!used) { + debug_print(" [ WARN %s ] Private key with unknown purpose T:%02lX", + o->id_str, o->key_type); + } + } + + if (objects.count == 0) { + printf(" [WARN] No objects to display\n"); + return; + } + + /* print summary */ + printf("[KEY ID] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ DERIVE ]\n"); + P11TEST_DATA_ROW(info, 4, + 's', "KEY ID", + 's', "MECHANISM", + 's', "SIGN&VERIFY WORKS", + 's', "ENCRYPT&DECRYPT WORKS"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + printf("\n[%-6s] [%s]\n", + o->id_str, + o->label); + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s]\n", + o->key_type == CKK_RSA ? "RSA " : + o->key_type == CKK_EC ? " EC " : " ?? ", + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] ", + o->wrap ? "[./]" : "[ ]", + o->unwrap ? "[./]" : "[ ]", + o->derive_pub ? "[./]" : "[ ]", + o->derive_priv ? "[./]" : "[ ]"); + if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { + printf(" no usable attributes found ... ignored\n"); + continue; + } + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; + if ((mech->usage_flags & CKF_SIGN) == 0) { + /* not applicable mechanisms are skipped */ + continue; + } + printf(" [ %-20s ] [ %s ] [ %s ] [ ] [ ]\n", + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", + mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); + if ((mech->result_flags & FLAGS_SIGN_ANY) == 0 && + (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) + continue; /* skip empty rows for export */ + P11TEST_DATA_ROW(info, 4, + 's', o->id_str, + 's', get_mechanism_name(mech->mech), + 's', mech->result_flags & FLAGS_SIGN_ANY ? "YES" : "", + 's', mech->result_flags & FLAGS_DECRYPT_ANY ? "YES" : ""); + } + } + printf(" Public == Cert -----^ ^ ^ ^ ^ ^ ^ ^----^- Attributes\n"); + printf(" Sign Attribute -------------' | | | | '---- Decrypt Attribute\n"); + printf(" Sign&Verify functionality -----' | | '------- Enc&Dec functionality\n"); + printf(" Verify Attribute -----------------' '---------- Encrypt Attribute\n"); + + clean_all_objects(&objects); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_readonly.h b/src/tests/p11test/p11test_case_readonly.h new file mode 100644 index 0000000000..8f8a757667 --- /dev/null +++ b/src/tests/p11test/p11test_case_readonly.h @@ -0,0 +1,29 @@ +/* + * p11test_case_readonly.h: Sign & Verify tests + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" + +void readonly_tests(void **state); +int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart); +int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart); + diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c new file mode 100644 index 0000000000..6973fd293e --- /dev/null +++ b/src/tests/p11test/p11test_case_usage.c @@ -0,0 +1,137 @@ +/* + * p11test_case_usage.c: Check if the usage flags are sane + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_usage.h" + +void usage_test(void **state) { + unsigned int i; + int errors = 0; + token_info_t *info = (token_info_t *) *state; + + test_certs_t objects; + objects.count = 0; + objects.data = NULL; + + P11TEST_START(info); + search_for_all_objects(&objects, info); + + debug_print("Check if the usage flags are sane.\n"); + for (i = 0; i < objects.count; i++) { + /* Ignore if there is missing private key */ + if (objects.data[i].private_handle == CK_INVALID_HANDLE) + continue; + + /* The usage flags are paired */ + if (objects.data[i].sign && !objects.data[i].verify) { + errors++; + fprintf(stderr, " [ ERROR %s ] If Sign is set, Verify should be set too.\n", + objects.data[i].id_str); + } + if (objects.data[i].decrypt && !objects.data[i].encrypt) { + errors++; + fprintf(stderr, " [ ERROR %s ] If Decrypt is set, Encrypt should be set too.\n", + objects.data[i].id_str); + } + if (objects.data[i].unwrap && !objects.data[i].wrap) { + errors++; + fprintf(stderr, " [ ERROR %s ] If Unwrap is set, Wrap should be set too.\n", + objects.data[i].id_str); + } + if (objects.data[i].derive_pub != objects.data[i].derive_priv) { + errors++; + fprintf(stderr, " [ ERROR %s ] Derive should be set on both private and public part.\n", + objects.data[i].id_str); + } + + /* We have at least one usage flag for every key group */ + if (! objects.data[i].sign && ! objects.data[i].verify && + ! objects.data[i].encrypt && ! objects.data[i].decrypt && + ! objects.data[i].wrap && ! objects.data[i].unwrap && + ! objects.data[i].derive_pub && ! objects.data[i].derive_priv) { + errors++; + fprintf(stderr, " [ ERROR %s ] Key group should have at least one usage flag.\n", + objects.data[i].id_str); + } + } + + /* print summary */ + printf("[KEY ID] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ DERIVE ] [ALWAYS_AUTH]\n"); + P11TEST_DATA_ROW(info, 14, + 's', "KEY ID", + 's', "LABEL", + 's', "TYPE", + 's', "BITS", + 's', "VERIFY PUBKEY", + 's', "SIGN", + 's', "VERIFY", + 's', "ENCRYPT", + 's', "DECRYPT", + 's', "WRAP", + 's', "UNWRAP", + 's', "DERIVE PUBLIC", + 's', "DERIVE PRIVATE", + 's', "ALWAYS AUTH"); + for (i = 0; i < objects.count; i++) { + printf("\n[%-6s] [%s]\n", + objects.data[i].id_str, + objects.data[i].label); + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s] [ %s ]\n", + objects.data[i].key_type == CKK_RSA ? "RSA " : + objects.data[i].key_type == CKK_EC ? " EC " : " ?? ", + objects.data[i].bits, + objects.data[i].verify_public == 1 ? " ./ " : " ", + objects.data[i].sign ? "[./] " : "[ ] ", + objects.data[i].verify ? " [./] " : " [ ] ", + objects.data[i].encrypt ? "[./] " : "[ ] ", + objects.data[i].decrypt ? " [./] " : " [ ] ", + objects.data[i].wrap ? "[./]" : "[ ]", + objects.data[i].unwrap ? "[./]" : "[ ]", + objects.data[i].derive_pub ? "[./]" : "[ ]", + objects.data[i].derive_priv ? "[./]" : "[ ]", + objects.data[i].always_auth ? "[./]" : "[ ]"); + P11TEST_DATA_ROW(info, 14, + 's', objects.data[i].id_str, + 's', objects.data[i].label, + 's', objects.data[i].key_type == CKK_RSA ? "RSA" : + objects.data[i].key_type == CKK_EC ? "EC" : "??", + 'd', objects.data[i].bits, + 's', objects.data[i].verify_public == 1 ? "YES" : "", + 's', objects.data[i].sign ? "YES" : "", + 's', objects.data[i].verify ? "YES" : "", + 's', objects.data[i].encrypt ? "YES" : "", + 's', objects.data[i].decrypt ? "YES" : "", + 's', objects.data[i].wrap ? "YES" : "", + 's', objects.data[i].unwrap ? "YES" : "", + 's', objects.data[i].derive_pub ? "YES" : "", + 's', objects.data[i].derive_priv ? "YES" : "", + 's', objects.data[i].always_auth ? "YES" : ""); + } + printf(" Public == Cert -----^ ^-----^ ^-----^ ^----^ ^---^\n"); + printf(" Sign & Verify Attributes ------' | | |\n"); + printf(" Encrypt & Decrypt Attributes ----------------' | |\n"); + printf(" Wrap & Unwrap Attributes ---------------------------------' |\n"); + printf(" Public and Private key Derive Attributes -----------------------------'\n"); + + clean_all_objects(&objects); + if (errors > 0) + P11TEST_FAIL(info, "Not all the usage flags were successfully verified. See the verbose log."); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_usage.h b/src/tests/p11test/p11test_case_usage.h new file mode 100644 index 0000000000..a728890d89 --- /dev/null +++ b/src/tests/p11test/p11test_case_usage.h @@ -0,0 +1,25 @@ +/* + * p11test_case_usage.h: Check if the usage flags are sane + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void usage_test(void **state); diff --git a/src/tests/p11test/p11test_case_wait.c b/src/tests/p11test/p11test_case_wait.c new file mode 100644 index 0000000000..2d88c3b02e --- /dev/null +++ b/src/tests/p11test/p11test_case_wait.c @@ -0,0 +1,59 @@ +/* + * p11test_case_wait.c: Test slot events (insert / remove) + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_wait.h" + +void wait_test(void **state) { + + token_info_t *info = (token_info_t *) *state; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_RV rv; + CK_SLOT_ID slot_id; + CK_SLOT_INFO slot_info; + int token_present = 0; + + P11TEST_START(info); + if (!info->interactive) { + fprintf(stderr, "To test wait, run in interactive mode (-i switch).\n"); + P11TEST_SKIP(info); + } + + do { + printf(" [ Waiting for slot event ... ]\n"); + + rv = fp->C_WaitForSlotEvent(0, &slot_id, NULL_PTR); + if (rv == CKR_FUNCTION_NOT_SUPPORTED) { + fprintf(stderr, "Function does not support call with blocking wait. Skipping.\n"); + skip(); + } else if (rv != CKR_OK) + P11TEST_FAIL(info, "C_WaitForSlotEvent: rv = 0x%.8lX\n", rv); + + rv = fp->C_GetSlotInfo(slot_id, &slot_info); + if (rv != CKR_OK) + P11TEST_FAIL(info, "C_GetSlotInfo: rv = 0x%.8lX\n", rv); + + token_present = ((slot_info.flags & CKF_TOKEN_PRESENT) != 0); + + printf(" [ Slot %lu ] %s\n", slot_id, slot_info.slotDescription); + printf(" Status: %s\n", + token_present ? "Token present": "No token"); + } while (!token_present); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_wait.h b/src/tests/p11test/p11test_case_wait.h new file mode 100644 index 0000000000..36f75e2a0d --- /dev/null +++ b/src/tests/p11test/p11test_case_wait.h @@ -0,0 +1,24 @@ +/* + * p11test_case_wait.h: Test slot events (insert / remove) + * + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_common.h" + +void wait_test(void **state); + diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h new file mode 100644 index 0000000000..d3ca304d83 --- /dev/null +++ b/src/tests/p11test/p11test_common.h @@ -0,0 +1,89 @@ +/* + * p11test_common.h: Test suite shared declarations for PKCS#11 API + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef P11TEST_COMMON_H +#define P11TEST_COMMON_H +#include "config.h" +#include +#include +#include +#include +#include +#include "pkcs11/pkcs11.h" +#include "libopensc/sc-ossl-compat.h" + +#define MAX_MECHS 200 + +#ifndef NDEBUG + #define debug_print(fmt, ...) \ + { fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0) +#else + #define debug_print(fmt, ...) +#endif + +#define FLAGS_SIGN 0x01 +#define FLAGS_SIGN_OPENSSL 0x02 +#define FLAGS_SIGN_ANY ( FLAGS_SIGN | FLAGS_SIGN_OPENSSL ) +#define FLAGS_DECRYPT 0x04 +#define FLAGS_DECRYPT_OPENSSL 0x08 +#define FLAGS_DECRYPT_ANY ( FLAGS_DECRYPT | FLAGS_DECRYPT_OPENSSL ) + +typedef struct { + char *outfile; + FILE *fd; + int in_test; + int first; + int in_data; + int first_data; +} log_context_t; + +typedef struct { + CK_MECHANISM_TYPE mech; + CK_MECHANISM_TYPE hash; + CK_RSA_PKCS_MGF_TYPE mgf; + int salt; + int usage_flags; + int result_flags; +} test_mech_t; + +typedef struct { + CK_FUNCTION_LIST_PTR function_pointer; + CK_SLOT_ID slot_id; + CK_SESSION_HANDLE session_handle; + CK_UTF8CHAR* pin; + size_t pin_length; + char *library_path; + unsigned int interactive; + log_context_t log; + + test_mech_t rsa_mechs[MAX_MECHS]; + size_t num_rsa_mechs; + test_mech_t ec_mechs[MAX_MECHS]; + size_t num_ec_mechs; + test_mech_t keygen_mechs[MAX_MECHS]; + size_t num_keygen_mechs; +} token_info_t; + +token_info_t token; + +#endif /* P11TEST_COMMON_H */ + diff --git a/src/tests/p11test/p11test_helpers.c b/src/tests/p11test/p11test_helpers.c new file mode 100644 index 0000000000..bdfd40d07c --- /dev/null +++ b/src/tests/p11test/p11test_helpers.c @@ -0,0 +1,207 @@ +/* + * p11test_helpers.c: Test suite for PKCS#11 API: Supporting functions + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_helpers.h" +#include "p11test_loader.h" + +int open_session(token_info_t *info) { + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + CK_RV rv; + + rv = function_pointer->C_OpenSession(info->slot_id, + CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, + &info->session_handle); + + if(rv != CKR_OK) + return 1; + + debug_print("Session was successfully created"); + return 0; +} + +int initialize_cryptoki(token_info_t *info) { + + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + CK_RV rv; + + rv = function_pointer->C_Initialize(NULL_PTR); + if(rv != CKR_OK){ + fprintf(stderr,"Could not initialize CRYPTOKI!\n"); + return 1; + } + + if(get_slot_with_card(info)) { + function_pointer->C_Finalize(NULL_PTR); + fprintf(stderr,"There is no card present in reader.\n"); + return 1; + } + + return 0; +} + +int token_initialize(void **state) { + token_info_t *info = (token_info_t *) *state; + if(initialize_cryptoki(info)) { + debug_print("CRYPTOKI couldn't be initialized"); + return 1; + } + return 0; +} + +void logfile_init(token_info_t *info) { + if (token.log.outfile == NULL) + return; + + if ((info->log.fd = fopen(token.log.outfile, "w")) == NULL) + fail_msg("Couldn't open file for test results."); + fprintf(info->log.fd, "{\n\"time\": 0,\n\"results\": ["); + info->log.in_test = 0; + info->log.first = 1; +} + +void logfile_finalize(token_info_t *info) { + if (info == NULL || info->log.fd == NULL) + return; + + /* Make sure the JSON object for test is closed */ + if (info->log.in_test) { + fprintf(info->log.fd, ",\n\t\"result\": \"unknown\"\n},"); + info->log.in_test = 0; + } + + fprintf(info->log.fd, "]\n}\n"); + fclose(info->log.fd); +} + +int group_setup(void **state) +{ + + token_info_t * info = calloc(sizeof(token_info_t), 1); + + assert_non_null(info); + + info->pin = token.pin; + info->pin_length = token.pin_length; + info->interactive = token.interactive; + info->slot_id = token.slot_id; + + if (load_pkcs11_module(info, token.library_path)) { + free(info); + fail_msg("Could not load module!\n"); + } + + logfile_init(info); + + *state = info; + return 0; +} + +int group_teardown(void **state) { + + token_info_t *info = (token_info_t *) *state; + debug_print("Clearing state after group tests!"); + // XXX do not finalize already Finalized + //if(info && info->function_pointer) + // info->function_pointer->C_Finalize(NULL_PTR); + + free(token.library_path); + free(token.pin); + + logfile_finalize(info); + free(info); + + close_pkcs11_module(); + + return 0; +} + +int prepare_token(token_info_t *info) { + if(initialize_cryptoki(info)) { + debug_print("CRYPTOKI couldn't be initialized"); + return 1; + } + + if(open_session(info)) { + debug_print("Could not open session to token!"); + return 1; + } + + return 0; +} + +int finalize_token(token_info_t *info) { + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + + info->session_handle = 0; + debug_print("Closing all sessions"); + function_pointer->C_CloseAllSessions(info->slot_id); + debug_print("Finalize CRYPTOKI"); + function_pointer->C_Finalize(NULL_PTR); + return 0; +} + +int user_login_setup(void **state) { + token_info_t *info = (token_info_t *) *state; + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + CK_RV rv; + + if (prepare_token(info)) + fail_msg("Could not prepare token.\n"); + + debug_print("Logging in to the token!"); + rv = function_pointer->C_Login(info->session_handle, CKU_USER, + token.pin, token.pin_length); + + if(rv != CKR_OK) + fail_msg("Could not login to token with user PIN '%s'\n", token.pin); + + return 0; +} + +int after_test_cleanup(void **state) { + + token_info_t *info = (token_info_t *) *state; + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + + debug_print("Logging out from token"); + function_pointer->C_Logout(info->session_handle); + + finalize_token(info); + return 0; +} + +int token_setup(void **state) { + token_info_t *info = (token_info_t *) *state; + + if(prepare_token(info)) + fail_msg("Could not prepare token.\n"); + + return 0; +} + +int token_cleanup(void **state) { + token_info_t *info = (token_info_t *) *state; + + finalize_token(info); + return 0; +} + diff --git a/src/tests/p11test/p11test_helpers.h b/src/tests/p11test/p11test_helpers.h new file mode 100644 index 0000000000..fac3850d06 --- /dev/null +++ b/src/tests/p11test/p11test_helpers.h @@ -0,0 +1,37 @@ +/* + * p11test_helpers.h: Test suite for PKCS#11 API: Supporting functions + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef P11TEST_HELPERS_H +#define P11TEST_HELPERS_H +#include "p11test_common.h" + +int group_setup(void **state); +int group_teardown(void **state); + +int user_login_setup(void **state); +int after_test_cleanup(void **state); + +int token_setup(void **state); +int token_cleanup(void **state); + +int token_initialize(void **state); +#endif //P11TEST_HELPERS_H diff --git a/src/tests/p11test/p11test_loader.c b/src/tests/p11test/p11test_loader.c new file mode 100644 index 0000000000..6dc2236c4e --- /dev/null +++ b/src/tests/p11test/p11test_loader.c @@ -0,0 +1,147 @@ +/* + * p11test_loader.c: Library loader for PKCS#11 test suite + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_loader.h" + +static void *pkcs11_so; + +int get_slot_with_card(token_info_t * info) +{ + CK_SLOT_ID_PTR slot_list; + CK_SLOT_ID slot_id; + CK_ULONG slot_count = 0; + CK_RV rv; + int error = 0; + unsigned int i; + + CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; + + /* Get slot list for memory allocation */ + rv = function_pointer->C_GetSlotList(0, NULL_PTR, &slot_count); + + if ((rv == CKR_OK) && (slot_count > 0)) { + slot_list = malloc(slot_count * sizeof (CK_SLOT_ID)); + + if (slot_list == NULL) { + fprintf(stderr, "System error: unable to allocate memory\n"); + return 1; + } + + /* Get the slot list for processing */ + rv = function_pointer->C_GetSlotList(0, slot_list, &slot_count); + if (rv != CKR_OK) { + fprintf(stderr, "GetSlotList failed: unable to get slot count.\n"); + error = 1; + goto cleanup; + } + } else { + fprintf(stderr, "GetSlotList failed: unable to get slot list.\n"); + return 1; + } + + /* Find a slot capable of specified mechanism */ + for (i = 0; i < slot_count; i++) { + CK_SLOT_INFO slot_info; + slot_id = slot_list[i]; + + rv = function_pointer->C_GetSlotInfo(slot_id, &slot_info); + if (rv != CKR_OK) + continue; + + if (info->slot_id == slot_id) { + if (info->slot_id == slot_list[i]) { /* explicitly specified slot */ + debug_print("Manually selected slot %lu (%s a token)\n", info->slot_id, + ((slot_info.flags & CKF_TOKEN_PRESENT) ? "with" : "without")); + goto cleanup; + } + } + + if (slot_info.flags & CKF_TOKEN_PRESENT) { + /* first found slot if not specified */ + if (info->slot_id == (unsigned long) -1) { + info->slot_id = slot_id; + goto cleanup; + } + } + } + error = 1; + fprintf(stderr, "No slot with card inserted or the selected slot does not exist\n"); + + cleanup: + if (slot_list) { + free(slot_list); + } + + return error; +} + +int load_pkcs11_module(token_info_t * info, const char* path_to_pkcs11_library) { + CK_RV rv; + CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR) = 0; + + if(strlen(path_to_pkcs11_library) == 0) { + fprintf(stderr, "You have to specify path to PKCS#11 library."); + return 1; + } + + pkcs11_so = dlopen(path_to_pkcs11_library, RTLD_NOW); + + if (!pkcs11_so) { + fprintf(stderr, "Error loading pkcs#11 so: %s\n", dlerror()); + return 1; + } + + C_GetFunctionList = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(pkcs11_so, "C_GetFunctionList"); + + if (!C_GetFunctionList) { + fprintf(stderr, "Could not get function list: %s\n", dlerror()); + return 1; + } + + rv = C_GetFunctionList(&info->function_pointer); + if (CKR_OK != rv) { + fprintf(stderr, "C_GetFunctionList call failed: 0x%.8lX", rv); + return 1; + } + + rv = info->function_pointer->C_Initialize(NULL_PTR); + + if (rv != CKR_OK) { + fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); + return 1; + } + + if (get_slot_with_card(info)) { + fprintf(stderr, "There is no card present in reader.\n"); + info->function_pointer->C_Finalize(NULL_PTR); + return 1; + } + + info->function_pointer->C_Finalize(NULL_PTR); + return 0; +} + +void close_pkcs11_module() { + if(pkcs11_so) + dlclose(pkcs11_so); +} + diff --git a/src/tests/p11test/p11test_loader.h b/src/tests/p11test/p11test_loader.h new file mode 100644 index 0000000000..5b0c62a3a6 --- /dev/null +++ b/src/tests/p11test/p11test_loader.h @@ -0,0 +1,34 @@ +/* + * p11test_loader.h: Library loader for PKCS#11 test suite + * + * Copyright (C) 2016 Martin Strhársky + * Copyright (C) 2016, 2017 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef P11TEST_LOADER_H +#define P11TEST_LOADER_H + +#include +#include "p11test_helpers.h" + +int load_pkcs11_module(token_info_t * info, const char* path_to_pkcs11_library); +int get_slot_with_card(token_info_t * info); +void close_pkcs11_module(); + + +#endif //P11TEST_LOADER_H diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh new file mode 100755 index 0000000000..5e6742b1b5 --- /dev/null +++ b/src/tests/p11test/runtest.sh @@ -0,0 +1,145 @@ +#!/bin/bash +# runtest.sh: Run test on existing card with possible initialization +# +# Copyright (C) 2016, 2017 Red Hat, Inc. +# +# Author: Jakub Jelen +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +#set -x +SOPIN="12345678" +PIN="123456" +export GNUTLS_PIN=$PIN +GENERATE_KEYS=1 +PKCS11_TOOL="../../tools/pkcs11-tool"; + +function generate_cert() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # Generate key pair + $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ + --module="$P11LIB" --label="$LABEL" --id=$ID + + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate $TYPE key pair" + return 1 + fi + + # check type value for the PKCS#11 URI (RHEL7 is using old "object-type") + TYPE_KEY="type" + p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \ + TYPE_KEY="object-type" + + # Generate certificate + certtool --generate-self-signed --outfile="$TYPE.cert" --template=cert.cfg \ + --provider="$P11LIB" --load-privkey "pkcs11:object=$LABEL;$TYPE_KEY=private" \ + --load-pubkey "pkcs11:object=$LABEL;$TYPE_KEY=public" + # convert to DER: + openssl x509 -inform PEM -outform DER -in "$TYPE.cert" -out "$TYPE.cert.der" + # Write certificate + #p11tool --login --write --load-certificate="$TYPE.cert" --label="$LABEL" \ + # --provider="$P11LIB" + $PKCS11_TOOL --write-object "$TYPE.cert.der" --type=cert --id=$ID \ + --label="$LABEL" --module="$P11LIB" + + rm "$TYPE.cert" "$TYPE.cert.der" + + p11tool --login --provider="$P11LIB" --list-all +} + +function card_setup() { + ECC_KEYS=1 + case $1 in + "softhsm") + P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" + echo "directories.tokendir = .tokens/" > .softhsm2.conf + mkdir ".tokens" + export SOFTHSM2_CONF=".softhsm2.conf" + # Init token + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" + ;; + "opencryptoki") + # Supports only RSA mechanisms + ECC_KEYS=0 + P11LIB="/usr/lib64/pkcs11/libopencryptoki.so" + SO_PIN=87654321 + SLOT_ID=3 # swtok slot + systemctl is-active pkcsslotd > /dev/null + if [[ "$?" -ne "0" ]]; then + echo "Opencryptoki needs pkcsslotd running" + exit 1 + fi + groups | grep pkcs11 > /dev/null + if [[ "$?" -ne "0" ]]; then + echo "Opencryptoki requires the user to be in pkcs11 group" + exit 1 + fi + echo "test_swtok" | /usr/sbin/pkcsconf -I -c $SLOT_ID -S $SO_PIN + /usr/sbin/pkcsconf -u -c $SLOT_ID -S $SO_PIN -n $PIN + ;; + "readonly") + GENERATE_KEYS=0 + if [[ ! -z "$2" && -f "$2" ]]; then + P11LIB="$2" + else + P11LIB="/usr/lib64/pkcs11/opensc-pkcs11.so" + P11LIB="../pkcs11/.libs/opensc-pkcs11.so" + fi + ;; + *) + echo "Error: Missing argument." + echo " Usage:" + echo " runtest.sh [softhsm|opencryptoki|readonly [pkcs-library.so]]" + exit 1; + ;; + esac + + if [[ $GENERATE_KEYS -eq 1 ]]; then + # Generate 1024b RSA Key pair + generate_cert "RSA:1024" "01" "RSA_auth" + # Generate 2048b RSA Key pair + generate_cert "RSA:2048" "02" "RSA2048" + if [[ $ECC_KEYS -eq 1 ]]; then + # Generate 256b ECC Key pair + generate_cert "EC:secp256r1" "03" "ECC_auth" + # Generate 521b ECC Key pair + generate_cert "EC:secp521r1" "04" "ECC521" + fi + fi +} + +function card_cleanup() { + case $1 in + "softhsm") + rm .softhsm2.conf + rm -rf ".tokens" + ;; + esac +} + +card_setup "$@" + +make p11test || exit +if [[ "$PKCS11SPY" -ne "" ]]; then + export PKCS11SPY="$P11LIB" + $VALGRIND ./p11test -m /usr/lib64/pkcs11/pkcs11-spy.so -p $PIN +else + #bash + $VALGRIND ./p11test -m "$P11LIB" -o test.json -p $PIN +fi + +card_cleanup "$@" diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 573e125ea0..18ac1ff603 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -20,6 +20,9 @@ WIXVSVER = VS2015 WIX_INCL_DIR = "/I$(WIX)\SDK\$(WIXVSVER)\inc" WIX_LIBS = "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\wcautil.lib" +# We do not build tests on windows +#TESTS_DEF = /DENABLE_TESTS + #Include support for Secure Messaging SM_DEF = /DENABLE_SM @@ -137,10 +140,10 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD /DEBUG /OPT:REF /OPT:ICF -COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /Zi +COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /Zi !ENDIF From f04a2654d97bd9e344672f637d5399ce9588ae9b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 13 Nov 2017 15:00:50 -0200 Subject: [PATCH 0249/4321] card-muscle: be more relaxed in card initialization closes https://github.com/OpenSC/OpenSC/pull/1248 --- src/libopensc/card-muscle.c | 17 +++++++++-------- src/libopensc/muscle-filesystem.c | 2 +- src/pkcs15init/pkcs15-lib.c | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 66b39d1395..9aa6766f5c 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -94,9 +94,11 @@ static int muscle_match_card(sc_card_t *card) apdu.resp = response; r = sc_transmit_apdu(card, &apdu); if (r == SC_SUCCESS && response[0] == 0x01) { - card->type = SC_CARD_TYPE_MUSCLE_V1; - return 1; + card->type = SC_CARD_TYPE_MUSCLE_V1; + } else { + card->type = SC_CARD_TYPE_MUSCLE_GENERIC; } + return 1; } return 0; } @@ -476,18 +478,17 @@ static int muscle_init(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG; /* Card type detection */ - if (_sc_match_atr(card, muscle_atrs, &card->type) < 0) { - free(priv->fs); - free(card->drv_data); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); - } - + _sc_match_atr(card, muscle_atrs, &card->type); if(card->type == SC_CARD_TYPE_MUSCLE_ETOKEN_72K) { card->caps |= SC_CARD_CAP_APDU_EXT; } if(card->type == SC_CARD_TYPE_MUSCLE_JCOP241) { card->caps |= SC_CARD_CAP_APDU_EXT; } + if (!(card->caps & SC_CARD_CAP_APDU_EXT)) { + card->max_recv_size = 255; + card->max_send_size = 255; + } if(card->type == SC_CARD_TYPE_MUSCLE_JCOP242R2_NO_EXT_APDU) { /* Tyfone JCOP v242R2 card that doesn't support extended APDUs */ } diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index a89e22dd3e..45724049ea 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -224,7 +224,7 @@ int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t ** } *file_data = NULL; } - if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath.id, 4) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath.id, 4 ))) { + if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath.id, 4) || 0 == memcmp("\x3F\x00\x50\x15", fullPath.id, 4 ) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath.id, 4))) { static mscfs_file_t ROOT_FILE; ROOT_FILE.ef = 0; ROOT_FILE.size = 0; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 280693761a..fd4e14e2dc 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3666,12 +3666,12 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p if (path && path->len) { struct sc_path tmp_path = *path; int iter; - r = SC_ERROR_OBJECT_NOT_FOUND; - for (iter = tmp_path.len/2; iter >= 0 && r == SC_ERROR_OBJECT_NOT_FOUND; iter--, tmp_path.len -= 2) + for (iter = tmp_path.len/2; iter >= 0 && r == SC_ERROR_OBJECT_NOT_FOUND; iter--, tmp_path.len -= 2) { r = sc_pkcs15_find_pin_by_type_and_reference(p15card, tmp_path.len ? &tmp_path : NULL, type, reference, &pin_obj); + } } else { r = sc_pkcs15_find_pin_by_type_and_reference(p15card, NULL, type, reference, &pin_obj); From 58b6cc05aa451ee77cea423c36099599ab95a4dd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 23 Apr 2018 08:57:59 +0200 Subject: [PATCH 0250/4321] Reordered card driver detection Workaround to not detect the MUSCLE applet as whatever other card driver selects an AID first. MUSCLE applet will always return 9000, which will confuse other card drivers. Since this bug is not going to go away any time soon, we simply detect the MUSCLE applet first and hope that other applets don't have a similar bug. --- src/libopensc/ctx.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 24d48fe21b..eb8892b2a0 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -96,20 +96,23 @@ static const struct _sc_driver_entry internal_card_drivers[] = { #endif { "rutoken", (void *(*)(void)) sc_get_rutoken_driver }, { "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver }, - { "westcos", (void *(*)(void)) sc_get_westcos_driver }, { "myeid", (void *(*)(void)) sc_get_myeid_driver }, - { "sc-hsm", (void *(*)(void)) sc_get_sc_hsm_driver }, #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) { "dnie", (void *(*)(void)) sc_get_dnie_driver }, #endif { "masktech", (void *(*)(void)) sc_get_masktech_driver }, + { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, + { "westcos", (void *(*)(void)) sc_get_westcos_driver }, -/* Here should be placed drivers that need some APDU transactions to - * recognise its cards. */ +/* Here should be placed drivers that need some APDU transactions in the + * driver's `match_card()` function. */ + /* MUSCLE card applet returns 9000 on whatever AID is selected, see + * https://github.com/JavaCardOS/MuscleCard-Applet/blob/master/musclecard/src/com/musclecard/CardEdge/CardEdge.java#L326 + * put the muscle driver first to cope with this bug. */ + { "muscle", (void *(*)(void)) sc_get_muscle_driver }, + { "sc-hsm", (void *(*)(void)) sc_get_sc_hsm_driver }, { "mcrd", (void *(*)(void)) sc_get_mcrd_driver }, { "setcos", (void *(*)(void)) sc_get_setcos_driver }, - { "muscle", (void *(*)(void)) sc_get_muscle_driver }, - { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, { "PIV-II", (void *(*)(void)) sc_get_piv_driver }, { "cac", (void *(*)(void)) sc_get_cac_driver }, { "itacns", (void *(*)(void)) sc_get_itacns_driver }, From 5d7ed3724694e344c1cc33b150bd7ede5d20c895 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Jan 2018 09:58:09 +0100 Subject: [PATCH 0251/4321] Removed configuration option `paranoid-memory` Don't pretend that we're capable of performing memory locking. The implementation of that, `sc_mem_alloc_secure()` (also removed), was almost unused anyway. --- etc/opensc.conf.in | 9 --------- src/libopensc/ctx.c | 4 ---- src/libopensc/libopensc.exports | 1 - src/libopensc/opensc.h | 2 +- src/libopensc/pkcs15.c | 2 +- src/libopensc/sc.c | 32 -------------------------------- src/pkcs11/misc.c | 2 +- 7 files changed, 3 insertions(+), 49 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index a1d9d8fcbc..9a150a4e6b 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -36,15 +36,6 @@ app default { # # profile_dir = @PROFILE_DIR@; - # Paranoid memory allocation. - # - # If set to 'true', then refuse to continue when locking of non-pageable - # memory fails. This can cause subtle failures but is more secure when - # you have a swap disk. - # Default: false - # - # paranoid_memory = false; - # Dsiable pop-ups of built-in GUI # # Default: false diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index eb8892b2a0..63d501dee9 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -367,10 +367,6 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * sc_ctx_log_to_file(ctx, NULL); } - if (scconf_get_bool (block, "paranoid-memory", - ctx->flags & SC_CTX_FLAG_PARANOID_MEMORY)) - ctx->flags |= SC_CTX_FLAG_PARANOID_MEMORY; - if (scconf_get_bool (block, "disable_popups", ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS)) ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS; diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 44ef561950..2daea3e2ae 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -130,7 +130,6 @@ sc_list_files sc_lock sc_logout sc_make_cache_dir -sc_mem_alloc_secure sc_mem_clear sc_mem_reverse sc_match_atr_block diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index c31e8fff21..bc256dcee6 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -688,6 +688,7 @@ typedef struct { * calling sc_disconnect_card. */ #define SC_CTX_FLAG_TERMINATE 0x00000001 +/** removed in 0.18.0 and later */ #define SC_CTX_FLAG_PARANOID_MEMORY 0x00000002 #define SC_CTX_FLAG_DEBUG_MEMORY 0x00000004 #define SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER 0x00000008 @@ -1324,7 +1325,6 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen); * @param len length of the memory buffer */ void sc_mem_clear(void *ptr, size_t len); -void *sc_mem_alloc_secure(sc_context_t *ctx, size_t len); int sc_mem_reverse(unsigned char *buf, size_t len); int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 892d424401..d6db6a30eb 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2569,7 +2569,7 @@ sc_pkcs15_allocate_object_content(struct sc_context *ctx, struct sc_pkcs15_objec /* Need to pass by temporary variable, * because 'value' and 'content.value' pointers can be the sames. */ - tmp_buf = (unsigned char *)sc_mem_alloc_secure(ctx, len); + tmp_buf = calloc(sizeof *tmp_buf, len); if (!tmp_buf) return SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 6c40839e39..389a2c2d33 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -826,40 +826,8 @@ int _sc_parse_atr(sc_reader_t *reader) return SC_SUCCESS; } -void *sc_mem_alloc_secure(sc_context_t *ctx, size_t len) -{ - void *pointer; - int locked = 0; - - pointer = calloc(len, sizeof(unsigned char)); - if (!pointer) - return NULL; -#ifdef HAVE_SYS_MMAN_H - /* TODO mprotect */ - /* Do not swap the memory */ - if (mlock(pointer, len) >= 0) - locked = 1; -#endif -#ifdef _WIN32 - /* Do not swap the memory */ - if (VirtualLock(pointer, len) != 0) - locked = 1; -#endif - if (!locked) { - if (ctx->flags & SC_CTX_FLAG_PARANOID_MEMORY) { - sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, failing allocation because paranoid set"); - free (pointer); - pointer = NULL; - } else { - sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, sensitive data may be paged to disk"); - } - } - return pointer; -} - void sc_mem_clear(void *ptr, size_t len) { - /* FIXME: Bug in 1.0.0-beta series crashes with 0 length */ if (len > 0) { #ifdef ENABLE_OPENSSL OPENSSL_cleanse(ptr, len); diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 3847885e84..17ab2cdde3 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -187,7 +187,7 @@ CK_RV push_login_state(struct sc_pkcs11_slot *slot, } if (pPin && ulPinLen) { - login->pPin = sc_mem_alloc_secure(context, (sizeof *pPin)*ulPinLen); + login->pPin = calloc((sizeof *pPin), ulPinLen); if (login->pPin == NULL) { goto err; } From 6ab6d7bad9090a21c2fc3157a494b86c27d4fe78 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Jan 2018 13:38:15 +0100 Subject: [PATCH 0252/4321] removed configuration option `reopen_debug_file` Simply re-open the debug file every time on Windows and don't do it everywhere else. --- etc/opensc.conf.in | 9 --------- src/libopensc/ctx.c | 16 ++++------------ src/libopensc/log.c | 23 +++++++++++++---------- src/libopensc/opensc.h | 1 - 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 9a150a4e6b..7e359569da 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -21,15 +21,6 @@ app default { # # debug_file = @DEBUG_FILE@ - # Reopen debug file at the every debug message. - # - # For Windows it's forced to 'true'. The reason is that - # in Windows file handles can not be shared between DLL-s, - # each DLL has a separate file handle table. - # - # Default: false - # reopen_debug_file = true; - # PKCS#15 initialization / personalization # profiles directory for pkcs15-init. # Default: @PROFILE_DIR_DEFAULT@ diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 63d501dee9..f6f746e2ec 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -306,12 +306,10 @@ int sc_ctx_log_to_file(sc_context_t *ctx, const char* filename) ctx->debug_file = NULL; } - if (ctx->reopen_log_file) { - if (!ctx->debug_filename) { - if (!filename) - filename = "stderr"; - ctx->debug_filename = strdup(filename); - } + if (!ctx->debug_filename) { + if (!filename) + filename = "stderr"; + ctx->debug_filename = strdup(filename); } if (!filename) @@ -343,12 +341,6 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * DWORD expanded_len; #endif -#ifdef _WIN32 - ctx->reopen_log_file = 1; -#else - ctx->reopen_log_file = scconf_get_bool(block, "reopen_debug_file", 0); -#endif - debug = scconf_get_int(block, "debug", ctx->debug); if (debug > ctx->debug) ctx->debug = debug; diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 28c53c599e..9478644d32 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -114,11 +114,14 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin if (r < 0) return; - if (ctx->reopen_log_file) { - r = sc_ctx_log_to_file(ctx, ctx->debug_filename); - if (r < 0) - return; - } +#ifdef _WIN32 + /* In Windows, file handles can not be shared between DLL-s, each DLL has a + * separate file handle table. Make sure we always have a valid file + * descriptor. */ + r = sc_ctx_log_to_file(ctx, ctx->debug_filename); + if (r < 0) + return; +#endif outf = ctx->debug_file; if (outf == NULL) @@ -130,11 +133,11 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin fprintf(outf, "\n"); fflush(outf); - if (ctx->reopen_log_file) { - if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) - fclose(ctx->debug_file); - ctx->debug_file = NULL; - } +#ifdef _WIN32 + if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) + fclose(ctx->debug_file); + ctx->debug_file = NULL; +#endif return; } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index bc256dcee6..6262bb7515 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -699,7 +699,6 @@ typedef struct sc_context { scconf_block *conf_blocks[3]; char *app_name; int debug; - int reopen_log_file; unsigned long flags; FILE *debug_file; From 4fca7d08c15cfa7c476cf067d7275c3f8895782f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Jan 2018 15:19:00 +0100 Subject: [PATCH 0253/4321] removed configuration option `force_card_driver` Use `card_drivers` or `OPENSC_DRIVER` instead --- etc/opensc.conf.in | 11 +---------- solaris/opensc.conf-dist | 9 --------- src/libopensc/ctx.c | 22 ++++------------------ 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 7e359569da..35a42667c5 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -27,7 +27,7 @@ app default { # # profile_dir = @PROFILE_DIR@; - # Dsiable pop-ups of built-in GUI + # Disable pop-ups of built-in GUI # # Default: false # disable_popups = true; @@ -170,15 +170,6 @@ app default { #st_key = ZZSTTERM00001.pkcs8; } - # Force using specific card driver - # - # If this option is present, OpenSC will use the supplied - # driver with all inserted cards. - # - # Default: autodetect - # - # force_card_driver = customcos; - # Configuration block for DNIe # # Card DNIe has an option to show an extra warning before diff --git a/solaris/opensc.conf-dist b/solaris/opensc.conf-dist index 19989419d3..77cf4f2aac 100644 --- a/solaris/opensc.conf-dist +++ b/solaris/opensc.conf-dist @@ -136,15 +136,6 @@ app default { # atr = 55:66:77:88:99:aa:bb; # } - # Force using specific card driver - # - # If this option is present, OpenSC will use the supplied - # driver with all inserted cards. - # - # Default: autodetect - # - # force_card_driver = miocos; - # Below are the framework specific configuration blocks. # PKCS #15 diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index f6f746e2ec..3de1a7bce7 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -139,7 +139,6 @@ static const struct _sc_driver_entry old_card_drivers[] = { struct _sc_ctx_options { struct _sc_driver_entry cdrv[SC_MAX_CARD_DRIVERS]; int ccount; - char *forced_card_driver; }; @@ -367,13 +366,6 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER)) ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; - val = scconf_get_str(block, "force_card_driver", NULL); - if (val) { - if (opts->forced_card_driver) - free(opts->forced_card_driver); - opts->forced_card_driver = strdup(val); - } - list = scconf_find_list(block, "card_drivers"); if (list != NULL) del_drvs(opts); @@ -835,16 +827,10 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) load_card_drivers(ctx, &opts); load_card_atrs(ctx); - if (!opts.forced_card_driver) { - char *driver = getenv("OPENSC_DRIVER"); - if(driver) { - opts.forced_card_driver = strdup(driver); - } - } - if (opts.forced_card_driver) { - if (SC_SUCCESS != sc_set_card_driver(ctx, opts.forced_card_driver)) - sc_log(ctx, "Warning: Could not load %s.", opts.forced_card_driver); - free(opts.forced_card_driver); + char *driver = getenv("OPENSC_DRIVER"); + if (driver) { + if (SC_SUCCESS != sc_set_card_driver(ctx, driver)) + sc_log(ctx, "Warning: Could not load %s.", driver); } del_drvs(&opts); sc_ctx_detect_readers(ctx); From d11e05fe1f49c792820d61ee90384c661281418f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Jan 2018 16:05:58 +0100 Subject: [PATCH 0254/4321] Generalized configuration option `ignored_readers` --- etc/opensc.conf.in | 15 ++++++++------- src/libopensc/ctx.c | 24 +++++++++++++++++++++++- src/libopensc/reader-pcsc.c | 4 +++- src/pkcs11/slot.c | 15 --------------- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 35a42667c5..98adee06c3 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -38,6 +38,14 @@ app default { # Default: false # enable_default_driver = true; + # List of readers to ignore + # If any of the strings listed below is matched in a reader name (case + # sensitive, partial matching possible), the reader is ignored by OpenSC. + # Use `opensc-tool --list-readers` to see all currently connected readers. + # + # Default: empty + # ignored_readers = "CardMan 1021", "SPR 532"; + # CT-API module configuration. reader_driver ctapi { # module @LIBDIR@@LIB_PRE@towitoko@DYN_LIB_EXT@ { @@ -1101,13 +1109,6 @@ app opensc-pkcs11 { # Default: false # zero_ckaid_for_ca_certs = true; - # List of readers to ignore - # If any of the strings listed below is matched (case sensitive) in a reader name, - # the reader is ignored by the PKCS#11 module. - # - # Default: empty - # ignored_readers = "CardMan 1021", "SPR 532"; - # Symbolic names of PINs for which slots are created # Card can contain more then one PINs or more then one on-card application with # its own PINs. Normally, to access all of them with the PKCS#11 API a slot has to be diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 3de1a7bce7..474438345d 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -39,9 +39,31 @@ #include "common/libscdl.h" #include "internal.h" +static int ignored_reader(sc_context_t *ctx, sc_reader_t *reader) +{ + if (ctx != NULL && reader != NULL && reader->name != NULL) { + size_t i; + const scconf_list *list; + + for (i = 0; ctx->conf_blocks[i]; i++) { + list = scconf_find_list(ctx->conf_blocks[i], "ignored_readers"); + while (list != NULL) { + if (strstr(reader->name, list->data) != NULL) { + sc_log(ctx, "Ignoring reader \'%s\' because of \'%s\'\n", + reader->name, list->data); + return 1; + } + list = list->next; + } + } + } + + return 0; +} + int _sc_add_reader(sc_context_t *ctx, sc_reader_t *reader) { - if (reader == NULL) { + if (reader == NULL || ignored_reader(ctx, reader)) { return SC_ERROR_INVALID_ARGUMENTS; } reader->ctx = ctx; diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 535c437aba..951877907d 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1262,7 +1262,9 @@ int pcsc_add_reader(sc_context_t *ctx, ret = _sc_add_reader(ctx, reader); - refresh_attributes(reader); + if (ret == SC_SUCCESS) { + refresh_attributes(reader); + } err1: return ret; diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 5a3c8d1f39..ffca0c1de3 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -155,21 +155,6 @@ CK_RV initialize_reader(sc_reader_t *reader) unsigned int i; CK_RV rv; - scconf_block *conf_block = NULL; - const scconf_list *list = NULL; - - conf_block = sc_get_conf_block(context, "pkcs11", NULL, 1); - if (conf_block != NULL) { - list = scconf_find_list(conf_block, "ignored_readers"); - while (list != NULL) { - if (strstr(reader->name, list->data) != NULL) { - sc_log(context, "Ignoring reader \'%s\' because of \'%s\'\n", reader->name, list->data); - return CKR_OK; - } - list = list->next; - } - } - for (i = 0; i < sc_pkcs11_conf.slots_per_card; i++) { rv = create_slot(reader); if (rv != CKR_OK) From 078e99fdca1e552f30b38e17c918bb0d58e3b479 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Jan 2018 16:17:31 +0100 Subject: [PATCH 0255/4321] Removed unused configuration option `zero_ckaid_for_ca_certs` It was used to make pkcs11-tool work with vendor defined PKCS#11 modules. If this behavior is still desired, pass the define ZERO_CKAID_FOR_CA_CERTS during the build --- etc/opensc.conf.in | 8 -------- src/pkcs11/framework-pkcs15.c | 11 ++++++----- src/pkcs11/misc.c | 6 ++---- src/pkcs11/sc-pkcs11.h | 1 - 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 98adee06c3..e5afe8341c 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -1101,14 +1101,6 @@ app opensc-pkcs11 { # Default: false # create_puk_slot = true; - # Report as 'zero' the CKA_ID attribute of CA certificate - # For the unknown reason the middleware of the manufacturer of gemalto (axalto, gemplus) - # card reports as '0' the CKA_ID of CA cartificates. - # Maybe someone else will need it. (Would be nice to know who and what for -- VTA) - # - # Default: false - # zero_ckaid_for_ca_certs = true; - # Symbolic names of PINs for which slots are created # Card can contain more then one PINs or more then one on-card application with # its own PINs. Normally, to access all of them with the PKCS#11 API a slot has to be diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index abc59d1437..167e008185 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3334,14 +3334,15 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT *(CK_CERTIFICATE_TYPE*)attr->pValue = CKC_X_509; break; case CKA_ID: - if (cert->cert_info->authority && sc_pkcs11_conf.zero_ckaid_for_ca_certs) { +#ifdef ZERO_CKAID_FOR_CA_CERTS + if (cert->cert_info->authority) { check_attribute_buffer(attr, 1); *(unsigned char*)attr->pValue = 0; + break; } - else { - check_attribute_buffer(attr, cert->cert_info->id.len); - memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len); - } +#endif + check_attribute_buffer(attr, cert->cert_info->id.len); + memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len); break; case CKA_TRUSTED: check_attribute_buffer(attr, sizeof(CK_BBOOL)); diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 17ab2cdde3..bb3197711c 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -458,7 +458,6 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf->init_sloppy = 1; conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED; conf->create_puk_slot = 0; - conf->zero_ckaid_for_ca_certs = 0; conf->create_slots_flags = SC_PKCS11_SLOT_CREATE_ALL; conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1); @@ -484,7 +483,6 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN; conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot); - conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs); create_slots_for_pins = (char *)scconf_get_str(conf_block, "create_slots_for_pins", "all"); conf->create_slots_flags = 0; @@ -503,8 +501,8 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) sc_log(ctx, "PKCS#11 options: max_virtual_slots=%d slots_per_card=%d " "hide_empty_tokens=%d lock_login=%d atomic=%d pin_unblock_style=%d " - "zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X", + "create_slots_flags=0x%X", conf->max_virtual_slots, conf->slots_per_card, conf->hide_empty_tokens, conf->lock_login, conf->atomic, conf->pin_unblock_style, - conf->zero_ckaid_for_ca_certs, conf->create_slots_flags); + conf->create_slots_flags); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index bb59b0791c..c023ee86a6 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -77,7 +77,6 @@ struct sc_pkcs11_config { unsigned char init_sloppy; unsigned int pin_unblock_style; unsigned int create_puk_slot; - unsigned int zero_ckaid_for_ca_certs; unsigned int create_slots_flags; unsigned char ignore_pin_length; }; From 36b88c3ad77483b90537926871edf19f2ce3f199 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 6 Apr 2018 13:33:09 +0200 Subject: [PATCH 0256/4321] reader-pcsc: allow fixing the length of a PIN fixes https://github.com/OpenSC/OpenSC/issues/1221 closes https://github.com/OpenSC/OpenSC/pull/1288 --- etc/opensc.conf.in | 6 ++++++ src/libopensc/reader-pcsc.c | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index e5afe8341c..f553b58db8 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -93,6 +93,12 @@ app default { # Default: true # enable_pinpad = false; # + # Some pinpad readers can only handle one exact length of the PIN. + # fixed_pinlength sets this value so that OpenSC expands the padding to + # this length. + # Default: 0 (i.e. not fixed) + # fixed_pinlength = 6; + # # Detect reader capabilities with escape commands (wrapped APDUs with # CLA=0xFF as defined by PC/SC pt. 3 and BSI TR-03119, e.g. for getting # the UID, escaped PIN commands and the reader's firmware version) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 951877907d..18d97f0c86 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -82,6 +82,7 @@ struct pcsc_global_private_data { SCARDCONTEXT pcsc_ctx; SCARDCONTEXT pcsc_wait_ctx; int enable_pinpad; + int fixed_pinlength; int enable_pace; size_t force_max_recv_size; size_t force_max_send_size; @@ -766,6 +767,7 @@ static int pcsc_init(sc_context_t *ctx) gpriv->transaction_end_action = SCARD_LEAVE_CARD; gpriv->reconnect_action = SCARD_LEAVE_CARD; gpriv->enable_pinpad = 1; + gpriv->fixed_pinlength = 0; gpriv->enable_pace = 1; gpriv->pcsc_ctx = -1; gpriv->pcsc_wait_ctx = -1; @@ -788,6 +790,8 @@ static int pcsc_init(sc_context_t *ctx) pcsc_reset_action(scconf_get_str(conf_block, "reconnect_action", "leave")); gpriv->enable_pinpad = scconf_get_bool(conf_block, "enable_pinpad", gpriv->enable_pinpad); + gpriv->fixed_pinlength = scconf_get_bool(conf_block, "fixed_pinlength", + gpriv->fixed_pinlength); gpriv->enable_pace = scconf_get_bool(conf_block, "enable_pace", gpriv->enable_pace); gpriv->force_max_send_size = scconf_get_int(conf_block, @@ -1889,10 +1893,17 @@ part10_check_pin_min_max(sc_reader_t *reader, struct sc_pin_cmd_data *data) unsigned char buffer[256]; size_t length = sizeof buffer; struct pcsc_private_data *priv = reader->drv_data; + struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) reader->ctx->reader_drv_data; struct sc_pin_cmd_pin *pin_ref = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? &data->pin1 : &data->pin2; + if (gpriv->fixed_pinlength != 0) { + pin_ref->min_length = gpriv->fixed_pinlength; + pin_ref->max_length = gpriv->fixed_pinlength; + return 0; + } + if (!priv->get_tlv_properties) return 0; From 14afdf38e371e57db39d6236f60f5458a0bdb0d8 Mon Sep 17 00:00:00 2001 From: David Ward Date: Fri, 18 May 2018 07:11:49 -0400 Subject: [PATCH 0257/4321] Do not temporarily set SC_READER_REMOVED on all readers (#1335) * reader-pcsc: Do not temporarily set SC_READER_REMOVED on all readers Fixes #1324. * reader-cryptotokenkit: Do not temporarily set SC_READER_REMOVED on all readers See #1324. --- src/libopensc/reader-cryptotokenkit.m | 51 +++++++++++++------------- src/libopensc/reader-pcsc.c | 53 +++++++++++++++------------ 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index cf0774697f..449b9f86d2 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -543,8 +543,10 @@ int cryptotokenkit_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void static int cryptotokenkit_detect_readers(sc_context_t *ctx) { size_t i; + NSUInteger j; int r; TKSmartCardSlotManager *mngr = [TKSmartCardSlotManager defaultManager]; + NSMutableArray *slotNames; LOG_FUNC_CALLED(ctx); @@ -554,38 +556,37 @@ static int cryptotokenkit_detect_readers(sc_context_t *ctx) goto err; } - /* temporarily mark all readers as removed */ - for (i=0; i < sc_ctx_get_reader_count(ctx); i++) { - sc_reader_t *reader = sc_ctx_get_reader(ctx, i); - reader->flags |= SC_READER_REMOVED; - } - sc_log(ctx, "Probing CryptoTokenKit readers"); - for (NSString *slotName in [mngr slotNames]) { - sc_reader_t *old_reader; - int found = 0; - const char *reader_name = [slotName UTF8String]; - dispatch_semaphore_t sema = dispatch_semaphore_create(0); + slotNames = [[mngr slotNames] mutableCopy]; - for (i=0; i < sc_ctx_get_reader_count(ctx) && !found; i++) { - old_reader = sc_ctx_get_reader(ctx, i); - if (old_reader == NULL) { - r = SC_ERROR_INTERNAL; - goto err; - } - if (!strcmp(old_reader->name, reader_name)) { - found = 1; - } + /* check if existing readers were returned in the list */ + for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { + sc_reader_t *reader = sc_ctx_get_reader(ctx, i); + + if (reader == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } + + for (j = 0; j < [slotNames count]; j++) { + if (!strcmp(reader->name, [slotNames[j] UTF8String])) + break; } - /* Reader already available, skip */ - if (found) { - old_reader->flags &= ~SC_READER_REMOVED; - continue; + if (j < [slotNames count]) { + /* existing reader found; remove it from the list */ + [slotNames removeObjectAtIndex:j]; + } else { + /* existing reader not found */ + reader->flags |= SC_READER_REMOVED; } + } - sc_log(ctx, "Found new CryptoTokenKit reader '%s'", reader_name); + /* add readers remaining in the list */ + for (NSString *slotName in slotNames) { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + sc_log(ctx, "Found new CryptoTokenKit reader '%s'", [slotName UTF8String]); [mngr getSlotWithName:slotName reply:^(TKSmartCardSlot *slot) { cryptotokenkit_use_reader(ctx, slot, NULL); dispatch_semaphore_signal(sema); diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 18d97f0c86..c9edad6087 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1298,12 +1298,6 @@ static int pcsc_detect_readers(sc_context_t *ctx) goto out; } - /* temporarily mark all readers as removed */ - for (i=0;i < sc_ctx_get_reader_count(ctx);i++) { - sc_reader_t *reader = sc_ctx_get_reader(ctx, i); - reader->flags |= SC_READER_REMOVED; - } - sc_log(ctx, "Probing PC/SC readers"); do { @@ -1359,28 +1353,39 @@ static int pcsc_detect_readers(sc_context_t *ctx) goto out; } - for (reader_name = reader_buf; *reader_name != '\x0'; - reader_name += strlen(reader_name) + 1) { - sc_reader_t *reader = NULL, *old_reader = NULL; - struct pcsc_private_data *priv = NULL; - int found = 0; + /* check if existing readers were returned in the list */ + for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { + sc_reader_t *reader = sc_ctx_get_reader(ctx, i); - for (i=0;i < sc_ctx_get_reader_count(ctx) && !found;i++) { - old_reader = sc_ctx_get_reader(ctx, i); - if (old_reader == NULL) { - ret = SC_ERROR_INTERNAL; - goto out; - } - if (!strcmp(old_reader->name, reader_name)) { - found = 1; - } + if (!reader) { + ret = SC_ERROR_INTERNAL; + goto out; } - /* Reader already available, skip */ - if (found) { - old_reader->flags &= ~SC_READER_REMOVED; - continue; + for (reader_name = reader_buf; *reader_name != '\x0'; + reader_name += strlen(reader_name) + 1) { + if (!strcmp(reader->name, reader_name)) + break; + } + + if (*reader_name != '\x0') { + /* existing reader found; remove it from the list */ + char *next_reader_name = reader_name + strlen(reader_name) + 1; + + memmove(reader_name, next_reader_name, + (reader_buf + reader_buf_size) - next_reader_name); + reader_buf_size -= (next_reader_name - reader_name); + } else { + /* existing reader not found */ + reader->flags |= SC_READER_REMOVED; } + } + + /* add readers remaining in the list */ + for (reader_name = reader_buf; *reader_name != '\x0'; + reader_name += strlen(reader_name) + 1) { + sc_reader_t *reader = NULL; + struct pcsc_private_data *priv = NULL; ret = pcsc_add_reader(ctx, reader_name, strlen(reader_name), &reader); if (ret != SC_SUCCESS) { From af72682072a5915ab54d1dad3d8ac3642209ead0 Mon Sep 17 00:00:00 2001 From: Florian Bezdeka <1119693+fbezdeka@users.noreply.github.com> Date: Fri, 18 May 2018 18:54:56 +0200 Subject: [PATCH 0258/4321] Fixed gcc 8 compilation errors (#1353) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following errors occured during a compilation using gcc 8: In function »gids_create_file.constprop«, inserted by »gids_save_certificate.isra.8« beicard-gids.c:1548:7: card-gids.c:465:2: Error: »strncpy« output may be truncated copying 8 bytes from a string of length 8 [-Werror=stringop-truncation] strncpy(record->filename, filename, 8); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pkcs15-oberthur.c: In function »sc_pkcs15emu_oberthur_add_prvkey«: pkcs15-oberthur.c:741:5: Error: »strncpy« output may be truncated copying 254 bytes from a string of length 254 [-Werror=stringop-truncation] strncpy(kobj.label, objs[ii]->label, sizeof(kobj.label) - 1); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- src/libopensc/card-gids.c | 3 ++- src/libopensc/pkcs15-oberthur.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index fc5d2a730c..ac3e57932c 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -33,6 +33,7 @@ Some features are undocumented like the format used to store certificates. They #include #include +#include "../common/compat_strlcpy.h" #ifdef ENABLE_OPENSSL /* openssl only needed for card administration */ @@ -462,7 +463,7 @@ static int gids_create_file(sc_card_t *card, char* directory, char* filename) { memset(masterfilebuffer + offset, 0, sizeof(gids_mf_record_t)); record = (gids_mf_record_t*) (masterfilebuffer + offset); strncpy(record->directory, directory, 8); - strncpy(record->filename, filename, 8); + strlcpy(record->filename, filename, sizeof(record->filename)); record->fileIdentifier = fileIdentifier; record->dataObjectIdentifier = dataObjectIdentifier; diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 4f841edcca..3415be7cc7 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -29,6 +29,7 @@ #include #include #include +#include "../common/compat_strlcpy.h" #include "pkcs15.h" #include "log.h" @@ -738,7 +739,7 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card, unsigned int id = path.value[path.len - 2] * 0x100 + path.value[path.len - 1]; if (id == ccont.id_cert) { - strncpy(kobj.label, objs[ii]->label, sizeof(kobj.label) - 1); + strlcpy(kobj.label, objs[ii]->label, sizeof(kobj.label)); break; } } From 62de900b1a96b6b4631c1e8f59d9f9b6fab94384 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Wed, 16 May 2018 21:30:15 +0300 Subject: [PATCH 0259/4321] build: fix --disable-sm --- src/libopensc/card-sc-hsm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index e2af52b942..a609f612af 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -451,6 +451,7 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, +#ifdef ENABLE_SM #ifdef ENABLE_OPENPACE #include "sm/sm-eac.h" #include @@ -573,6 +574,7 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) return SC_ERROR_NOT_SUPPORTED; } #endif +#endif From 01f712d5da1d4bf113cf3439cbd58a3cb7cea10b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 May 2018 23:21:14 +0200 Subject: [PATCH 0260/4321] Use explicit locking for OpenSC tools (#1344) * opensc-explorer: use explicit locking fixed https://github.com/OpenSC/OpenSC/issues/1043 * opensc-tool: use explicit locking * pkcs15-crypt: use explicit locking --- src/tools/opensc-explorer.c | 165 ++++++++++++++++++++++++++++-------- src/tools/opensc-tool.c | 38 +++++++-- src/tools/pkcs15-crypt.c | 3 +- 3 files changed, 160 insertions(+), 46 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 66ee0c6fec..298293a41a 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -262,7 +262,6 @@ static void die(int ret) { sc_file_free(current_file); if (card) { - sc_unlock(card); sc_disconnect_card(card); } if (ctx) @@ -273,7 +272,10 @@ static void die(int ret) static void select_current_path_or_die(void) { if (current_path.type || current_path.len) { - int r = sc_select_file(card, ¤t_path, NULL); + int r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, ¤t_path, NULL); + sc_unlock(card); if (r) { printf("unable to select parent DF: %s\n", sc_strerror(r)); die(1); @@ -470,7 +472,10 @@ static int do_ls(int argc, char **argv) u8 buf[256], *cur = buf; int r, count; - r = sc_list_files(card, buf, sizeof(buf)); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_list_files(card, buf, sizeof(buf)); + sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_LIST_FILES, "unable to receive file listing", current_file); return -1; @@ -507,7 +512,10 @@ static int do_ls(int argc, char **argv) } } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { printf(" %02X%02X unable to select file, %s\n", cur[0], cur[1], sc_strerror(r)); } else { @@ -565,7 +573,10 @@ static int do_find(int argc, char **argv) } } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); switch (r) { case SC_SUCCESS: file->id = (fid[0] << 8) | fid[1]; @@ -620,7 +631,10 @@ static int do_find_tags(int argc, char **argv) printf("(%04X)\r", tag); fflush(stdout); - r = sc_get_data(card, tag, rbuf, sizeof rbuf); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_get_data(card, tag, rbuf, sizeof rbuf); + sc_unlock(card); if (r >= 0) { printf(" %04X ", tag); if (tag == 0) @@ -678,7 +692,10 @@ static int do_cd(int argc, char **argv) path.len -= 2; } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { printf("unable to go up: %s\n", sc_strerror(r)); return -1; @@ -691,7 +708,10 @@ static int do_cd(int argc, char **argv) if (arg_to_path(argv[0], &path, 0) != 0) return usage(do_cd); - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select DF", current_file); return -1; @@ -724,7 +744,10 @@ static int read_and_util_print_binary_file(sc_file_t *file) if (!buf) return -1; - r = sc_read_binary(card, 0, buf, size, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_read_binary(card, 0, buf, size, 0); + sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_READ, "read failed", file); return -1; @@ -744,8 +767,11 @@ static int read_and_print_record_file(sc_file_t *file, unsigned char sfi) int rec, r; for (rec = 1; ; rec++) { - r = sc_read_record(card, rec, buf, sizeof(buf), - SC_RECORD_BY_REC_NR | sfi); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_read_record(card, rec, buf, sizeof(buf), + SC_RECORD_BY_REC_NR | sfi); + sc_unlock(card); if (r == SC_ERROR_RECORD_NOT_FOUND) return 0; if (r < 0) { @@ -794,7 +820,10 @@ static int do_cat(int argc, char **argv) if (arg_to_path(argv[0], &path, 0) != 0) return usage(do_cat); - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); @@ -839,7 +868,10 @@ static int do_info(int argc, char **argv) if (arg_to_path(argv[0], &path, 0) != 0) return usage(do_info); - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { printf("unable to select file: %s\n", sc_strerror(r)); return -1; @@ -952,7 +984,10 @@ static int create_file(sc_file_t *file) { int r; - r = sc_create_file(card, file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_create_file(card, file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_CREATE, "CREATE FILE failed", current_file); return -1; @@ -1035,7 +1070,10 @@ static int do_delete(int argc, char **argv) if (path.len != 2) return usage(do_delete); path.type = SC_PATH_TYPE_FILE_ID; - r = sc_delete_file(card, &path); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_delete_file(card, &path); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_DELETE, "DELETE FILE failed", current_file); return -1; @@ -1116,7 +1154,10 @@ static int do_verify(int argc, char **argv) data.pin1.data = buf; data.pin1.len = buflen; } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_pin_cmd(card, &data, &tries_left); + sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { @@ -1178,7 +1219,10 @@ static int do_change(int argc, char **argv) data.pin2.data = newpinlen ? newpin : NULL; data.pin2.len = newpinlen; - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_pin_cmd(card, &data, &tries_left); + sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { if (tries_left >= 0) @@ -1240,7 +1284,10 @@ static int do_unblock(int argc, char **argv) data.pin2.data = newpinlen ? newpin : NULL; data.pin2.len = newpinlen; - r = sc_pin_cmd(card, &data, NULL); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_pin_cmd(card, &data, NULL); + sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) printf("Incorrect code.\n"); @@ -1275,7 +1322,10 @@ static int do_get(int argc, char **argv) perror(filename); goto err; } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); goto err; @@ -1344,7 +1394,10 @@ static int do_update_binary(int argc, char **argv) return -1; } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); return -1; @@ -1355,7 +1408,10 @@ static int do_update_binary(int argc, char **argv) goto err; } - r = sc_update_binary(card, offs, buf, buflen, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_update_binary(card, offs, buf, buflen, 0); + sc_unlock(card); if (r < 0) { printf("Cannot update %04X; return %i\n", file->id, r); goto err; @@ -1389,7 +1445,10 @@ static int do_update_record(int argc, char **argv) printf("in: %i; %i; %s\n", rec, offs, argv[3]); - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); return -1; @@ -1416,7 +1475,10 @@ static int do_update_record(int argc, char **argv) goto err; } - r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR); + sc_unlock(card); if (r<0) { printf("Cannot update record %i; return %i\n", rec, r); goto err; @@ -1455,7 +1517,10 @@ static int do_put(int argc, char **argv) perror(filename); goto err; } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); goto err; @@ -1471,7 +1536,10 @@ static int do_put(int argc, char **argv) } if (r != c) count = c = r; - r = sc_update_binary(card, idx, buf, c, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_update_binary(card, idx, buf, c, 0); + sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_READ, "update failed", file); goto err; @@ -1520,7 +1588,10 @@ static int do_erase(int argc, char **argv) if (argc != 0) return usage(do_erase); - r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); + sc_unlock(card); if (r) { printf("Failed to erase card: %s\n", sc_strerror (r)); return -1; @@ -1542,7 +1613,10 @@ static int do_random(int argc, char **argv) return -1; } - r = sc_get_challenge(card, buffer, count); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_get_challenge(card, buffer, count); + sc_unlock(card); if (r < 0) { printf("Failed to get random bytes: %s\n", sc_strerror(r)); return -1; @@ -1563,7 +1637,10 @@ static int do_get_data(int argc, char **argv) return usage(do_get_data); tag = strtoul(argv[0], NULL, 16); - r = sc_get_data(card, tag, buffer, sizeof(buffer)); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_get_data(card, tag, buffer, sizeof(buffer)); + sc_unlock(card); if (r < 0) { printf("Failed to get data object: %s\n", sc_strerror(r)); return -1; @@ -1611,7 +1688,10 @@ static int do_put_data(int argc, char **argv) } /* Call OpenSC to do put data */ - r = sc_put_data(card, tag, buf, buflen); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_put_data(card, tag, buf, buflen); + sc_unlock(card); if (r < 0) { printf("Cannot put data to %04X; return %i\n", tag, r); return -1; @@ -1655,7 +1735,10 @@ static int do_apdu(int argc, char **argv) printf("Sending: "); util_hex_dump(stdout, buf, len, " "); printf("\n"); - r = sc_transmit_apdu(card, &apdu); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_transmit_apdu(card, &apdu); + sc_unlock(card); if (r) { fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r)); return 1; @@ -1692,7 +1775,10 @@ static int do_asn1(int argc, char **argv) puts("Invalid file path"); return -1; } - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); goto err; @@ -1717,7 +1803,10 @@ static int do_asn1(int argc, char **argv) if (!buf) { goto err; } - r = sc_read_binary(card, 0, buf, len, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_read_binary(card, 0, buf, len, 0); + sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_READ, "read failed", file); goto err; @@ -1930,7 +2019,7 @@ int main(int argc, char *argv[]) } } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, 0); if (err) goto end; @@ -1949,14 +2038,20 @@ int main(int argc, char *argv[]) } } else { sc_format_path("3F00", ¤t_path); - r = sc_select_file(card, ¤t_path, ¤t_file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, ¤t_path, ¤t_file); + sc_unlock(card); if (r) { printf("unable to select MF: %s\n", sc_strerror(r)); return 1; } } - r = sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &lcycle); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &lcycle); + sc_unlock(card); if (r && r != SC_ERROR_NOT_SUPPORTED) printf("unable to change lifecycle: %s\n", sc_strerror(r)); diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index b285b28faa..46886d39fe 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -429,7 +429,10 @@ static int print_file(sc_card_t *in_card, const sc_file_t *file, return 1; } - r = sc_read_binary(in_card, 0, buf, file->size, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_read_binary(in_card, 0, buf, file->size, 0); + sc_unlock(card); if (r > 0) util_hex_dump_asc(stdout, buf, r, 0); free(buf); @@ -439,7 +442,10 @@ static int print_file(sc_card_t *in_card, const sc_file_t *file, for (i=0; i < file->record_count; i++) { printf("Record %d\n", i); - r = sc_read_record(in_card, i, buf, 256, 0); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_read_record(in_card, i, buf, 256, 0); + sc_unlock(card); if (r > 0) util_hex_dump_asc(stdout, buf, r, 0); } @@ -453,7 +459,10 @@ static int enum_dir(sc_path_t path, int depth) int r, file_type; u8 files[SC_MAX_APDU_BUFFER_SIZE]; - r = sc_select_file(card, &path, &file); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_select_file(card, &path, &file); + sc_unlock(card); if (r) { fprintf(stderr, "SELECT FILE failed: %s\n", sc_strerror(r)); return 1; @@ -464,7 +473,10 @@ static int enum_dir(sc_path_t path, int depth) if (file_type == SC_FILE_TYPE_DF) { int i; - r = sc_list_files(card, files, sizeof(files)); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_list_files(card, files, sizeof(files)); + sc_unlock(card); if (r < 0) { fprintf(stderr, "sc_list_files() failed: %s\n", sc_strerror(r)); return 1; @@ -520,7 +532,10 @@ static int send_apdu(void) for (r = 0; r < len0; r++) printf("%02X ", buf[r]); printf("\n"); - r = sc_transmit_apdu(card, &apdu); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_transmit_apdu(card, &apdu); + sc_unlock(card); if (r) { fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r)); return 1; @@ -538,7 +553,10 @@ static void print_serial(sc_card_t *in_card) int r; sc_serial_number_t serial; - r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial); + sc_unlock(card); if (r) fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed\n"); else @@ -658,7 +676,10 @@ static int card_reset(const char *reset_type) cold_reset = !reset_type || strcmp(reset_type, "cold") == 0; - r = sc_reset(card, cold_reset); + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_reset(card, cold_reset); + sc_unlock(card); if (r) { fprintf(stderr, "sc_reset(%s) failed: %d\n", cold_reset ? "cold" : "warm", r); @@ -843,7 +864,7 @@ int main(int argc, char *argv[]) } } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); if (err) goto end; @@ -895,7 +916,6 @@ int main(int argc, char *argv[]) } end: if (card) { - sc_unlock(card); sc_disconnect_card(card); } if (ctx) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index e8ef279af0..1e62248b72 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -463,7 +463,7 @@ int main(int argc, char *argv[]) sc_ctx_log_to_file(ctx, "stderr"); } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); if (err) goto end; @@ -510,7 +510,6 @@ int main(int argc, char *argv[]) if (p15card) sc_pkcs15_unbind(p15card); if (card) { - sc_unlock(card); sc_disconnect_card(card); } if (ctx) From ae31408f818cfa79c89ca80dcf007dd5ada8de2b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 May 2018 23:15:29 +0200 Subject: [PATCH 0261/4321] fixed checking SW in iso7816_read_binary_sfid fixes https://github.com/OpenSC/OpenSC/issues/1360 --- src/libopensc/iso7816.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index d9ae6c40eb..1e889ad4e1 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1320,9 +1320,13 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, apdu.le = read; r = sc_transmit_apdu(card, &apdu); + if (r < 0) + goto err; + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r < 0 && r != SC_ERROR_FILE_END_REACHED) + goto err; /* emulate the behaviour of sc_read_binary */ - if (r >= 0) - r = apdu.resplen; + r = apdu.resplen; while(1) { if (r >= 0 && ((size_t) r) != read) { From 439a95f2d26a0d924ca9cab27fbde43cd74d1522 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 May 2018 23:49:29 +0200 Subject: [PATCH 0262/4321] If card initialization fails, return SC_ERROR_INVALID_CARD (#1251) fixes https://github.com/OpenSC/OpenSC/issues/946 --- src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-authentic.c | 9 ++++++--- src/libopensc/card-belpic.c | 2 +- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cardos.c | 23 ++++++++++++++--------- src/libopensc/card-coolkey.c | 2 +- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-gemsafeV1.c | 10 +++++----- src/libopensc/card-gids.c | 2 +- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-iasecc.c | 6 ++++-- src/libopensc/card-isoApplet.c | 6 +++--- src/libopensc/card-mcrd.c | 11 ++++++++--- src/libopensc/card-myeid.c | 12 ++++-------- src/libopensc/card-openpgp.c | 6 +++--- src/libopensc/card-piv.c | 4 +--- src/libopensc/card-rutoken.c | 4 ++++ 17 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 83e64b2d4a..51737b5b40 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -83,7 +83,7 @@ static int asepcos_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_ASEPCOS_JAVA) { int r = asepcos_select_asepcos_applet(card); if (r != SC_SUCCESS) - return r; + return SC_ERROR_INVALID_CARD; } /* Set up algorithm info. */ diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 8537260d10..45e8632b01 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -463,7 +463,7 @@ static int authentic_init(struct sc_card *card) { struct sc_context *ctx = card->ctx; - int ii, rv = SC_ERROR_NO_CARD_SUPPORT; + int ii, rv = SC_ERROR_INVALID_CARD; LOG_FUNC_CALLED(ctx); for(ii=0;authentic_known_atrs[ii].atr;ii++) { @@ -475,7 +475,7 @@ authentic_init(struct sc_card *card) } if (!authentic_known_atrs[ii].atr) - LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_CARD); card->cla = 0x00; card->drv_data = (struct authentic_private_data *) calloc(sizeof(struct authentic_private_data), 1); @@ -485,9 +485,12 @@ authentic_init(struct sc_card *card) if (card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) rv = authentic_init_oberthur_authentic_3_2(card); - if (!rv) + if (rv != SC_SUCCESS) rv = authentic_get_serialnr(card, NULL); + if (rv != SC_SUCCESS) + rv = SC_ERROR_INVALID_CARD; + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 10a7ed6149..15b8a7b7bf 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -228,7 +228,7 @@ static int belpic_init(sc_card_t *card) memset(carddata, 0, sizeof(carddata)); if((r = get_carddata(card, carddata, sizeof(carddata))) < 0) { - return r; + return SC_ERROR_INVALID_CARD; } if (carddata[BELPIC_CARDDATA_OFF_APPLETVERS] >= 0x17) { key_size = 2048; diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 3529bab1f7..d8762b032b 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1611,7 +1611,7 @@ static int cac_init(sc_card_t *card) r = cac_find_and_initialize(card, 1); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); } flags = SC_ALGORITHM_RSA_RAW; diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 884b756e25..237688de67 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -171,6 +171,7 @@ static int cardos_init(sc_card_t *card) size_t data_field_length; sc_apdu_t apdu; u8 rbuf[2]; + int r; card->name = "Atos CardOS"; card->cla = 0x00; @@ -188,9 +189,9 @@ static int cardos_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { - int r = cardos_have_2048bit_package(card); + r = cardos_have_2048bit_package(card); if (r < 0) - return r; + return SC_ERROR_INVALID_CARD; if (r == 1) rsa_2048 = 1; card->caps |= SC_CARD_CAP_APDU_EXT; @@ -208,14 +209,18 @@ static int cardos_init(sc_card_t *card) apdu.le = sizeof rbuf; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, - sc_transmit_apdu(card, &apdu), - "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, - sc_check_sw(card, apdu.sw1, apdu.sw2), - "GET DATA command returned error"); + r = sc_transmit_apdu(card, &apdu); + if (r < 0) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + SC_ERROR_INVALID_CARD, + "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r < 0) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + SC_ERROR_INVALID_CARD, + "GET DATA command returned error"); if (apdu.resplen != 2) - return SC_ERROR_WRONG_LENGTH; + return SC_ERROR_INVALID_CARD; data_field_length = ((rbuf[0] << 8) | rbuf[1]); /* strip the length of possible Lc and Le bytes */ diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 54a65dddbd..0560412df5 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2259,7 +2259,7 @@ static int coolkey_init(sc_card_t *card) r = coolkey_initialize(card); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); } card->type = SC_CARD_TYPE_COOLKEY_GENERIC; diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 1b17f8a54b..4de750bf76 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1168,7 +1168,7 @@ epass2003_init(struct sc_card *card) /* decide FIPS/Non-FIPS mode */ if (SC_SUCCESS != get_data(card, 0x86, data, datalen)) - return SC_ERROR_CARD_CMD_FAILED; + return SC_ERROR_INVALID_CARD; if (0x01 == data[2]) exdata->smtype = KEY_TYPE_AES; diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index c560772068..811e5c0543 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -180,9 +180,9 @@ static int gemsafe_init(struct sc_card *card) memcpy(exdata->aid, gemsafe_pteid_aid, sizeof(gemsafe_pteid_aid)); exdata->aid_len = sizeof(gemsafe_pteid_aid); } else if (card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) { - memcpy(exdata->aid, gemsafe_seeid_aid, sizeof(gemsafe_seeid_aid)); - exdata->aid_len = sizeof(gemsafe_seeid_aid); - } + memcpy(exdata->aid, gemsafe_seeid_aid, sizeof(gemsafe_seeid_aid)); + exdata->aid_len = sizeof(gemsafe_seeid_aid); + } /* increase lock_count here to prevent sc_unlock to select * applet twice in gp_select_applet */ @@ -192,7 +192,7 @@ static int gemsafe_init(struct sc_card *card) if (r < 0) { free(exdata); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "applet selection failed\n"); - return SC_ERROR_INTERNAL; + return SC_ERROR_INVALID_CARD; } card->lock_count--; @@ -232,7 +232,7 @@ static int gemsafe_init(struct sc_card *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; card->drv_data = exdata; - return 0; + return SC_SUCCESS; } static int gemsafe_finish(sc_card_t *card) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index ac3e57932c..9bc354b1b1 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -634,7 +634,7 @@ static int gids_init(sc_card_t * card) // cache some data in memory data = (struct gids_private_data*) calloc(1, sizeof(struct gids_private_data)); if (!data) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_MEMORY_FAILURE); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); } memset(data, 0, sizeof(struct gids_private_data)); card->drv_data = data; diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 3064a61f9e..b3dd848c21 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -206,7 +206,7 @@ gpk_init(sc_card_t *card) /* Make sure max send/receive size is 4 byte aligned and <256. */ card->max_recv_size = 252; - return 0; + return SC_SUCCESS; } /* diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 4f20fde6cd..5d25c3c2f8 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -606,7 +606,7 @@ iasecc_init(struct sc_card *card) else if (card->type == SC_CARD_TYPE_IASECC_MI) rv = iasecc_init_amos_or_sagem(card); else - LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_CARD); if (!rv) { @@ -631,8 +631,10 @@ iasecc_init(struct sc_card *card) card->sm_ctx.ops.update_binary = _iasecc_sm_update_binary; #endif - if (!rv) + if (!rv) { sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len)); + rv = SC_ERROR_INVALID_CARD; + } LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 846031742e..1ef35e2e4e 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -193,7 +193,6 @@ isoApplet_match_card(sc_card_t *card) static int isoApplet_init(sc_card_t *card) { - int r; int i; unsigned long flags = 0; unsigned long ext_flags = 0; @@ -211,8 +210,9 @@ isoApplet_init(sc_card_t *card) card->cla = 0x00; /* Obtain applet version and specific features */ - r = isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen); - LOG_TEST_RET(card->ctx, r, "Error obtaining applet version."); + if (0 > isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen)) { + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Error obtaining applet version."); + } if(rlen < 3) { assert(sizeof(rbuf) >= 3); diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2428c8dc92..ff1e2a6651 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -360,7 +360,8 @@ static int mcrd_init(sc_card_t * card) apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + if (r < 0) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); if(apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { @@ -371,7 +372,8 @@ static int mcrd_init(sc_card_t * card) apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + if (r < 0) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary @@ -386,7 +388,8 @@ static int mcrd_init(sc_card_t * card) apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + if (r < 0) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { free(card->drv_data); @@ -412,6 +415,8 @@ static int mcrd_init(sc_card_t * card) sc_format_path ("3f00", &tmppath); r = sc_select_file (card, &tmppath, NULL); + if (r < 0) + r = SC_ERROR_INVALID_CARD; /* Not needed for the fixed EstEID profile */ if (!is_esteid_card(card)) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 88eef9e972..d4b4cbd6f2 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -149,7 +149,6 @@ static int myeid_init(struct sc_card *card) myeid_private_data_t *priv; u8 appletInfo[20]; size_t appletInfoLen; - int r; myeid_card_caps_t card_caps; LOG_FUNC_CALLED(card->ctx); @@ -168,9 +167,8 @@ static int myeid_init(struct sc_card *card) appletInfoLen = 20; - r = myeid_get_info(card, appletInfo, appletInfoLen); - - LOG_TEST_RET(card->ctx, r, "Failed to get MyEID applet information."); + if (0 > myeid_get_info(card, appletInfo, appletInfoLen)) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Failed to get MyEID applet information."); priv->change_counter = appletInfo[19] | appletInfo[18] << 8; @@ -190,10 +188,8 @@ static int myeid_init(struct sc_card *card) if (card->version.fw_major >= 40) { /* Since 4.0, we can query available algorithms and key sizes. * Since 3.5.0 RSA up to 2048 and ECC up to 256 are always supported, so we check only max ECC key length. */ - r = myeid_get_card_caps(card, &card_caps); - - if (r != SC_SUCCESS) { - sc_log(card->ctx, "Failed to get card capabilities. Using default max ECC key length 256."); + if (myeid_get_card_caps(card, &card_caps) != SC_SUCCESS) { + sc_log(card->ctx, "Failed to get card capabilities. Using default max ECC key length 256."); } } diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3c847d206f..1f903231f9 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -413,13 +413,13 @@ pgp_init(sc_card_t *card) path.type = SC_PATH_TYPE_DF_NAME; if ((r = iso_ops->select_file(card, &path, &file)) < 0) { pgp_finish(card); - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } /* defensive programming check */ if (!file) { pgp_finish(card); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } if (file->namelen != 16) { @@ -427,7 +427,7 @@ pgp_init(sc_card_t *card) r = get_full_pgp_aid(card, file); if (r < 0) { pgp_finish(card); - return r; + return SC_ERROR_INVALID_CARD; } } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 66b723c29a..8f7c4ebb38 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3295,11 +3295,9 @@ static int piv_init(sc_card_t *card) piv_process_discovery(card); - r = 0; - priv->pstate=PIV_STATE_NORMAL; sc_unlock(card) ; /* obtained in piv_match */ - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index c1331ee913..86f8e03409 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -132,6 +132,10 @@ static int rutoken_init(sc_card_t *card) ret = token_init(card, "uaToken S card"); else ret = token_init(card, "Rutoken S card"); + + if (ret != SC_SUCCESS) { + ret = SC_ERROR_INVALID_CARD; + } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); } From c463985fedbf55f7d4ab5c2bee764b74993bdbf1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 May 2018 23:49:59 +0200 Subject: [PATCH 0263/4321] Removed code for obsolete cards from D-Trust (#1261) --- etc/opensc.conf.in | 13 ----------- src/libopensc/card-mcrd.c | 14 ++++-------- src/libopensc/pkcs15.c | 48 --------------------------------------- 3 files changed, 5 insertions(+), 70 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index f553b58db8..c3cfc96449 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -386,19 +386,6 @@ app default { flags = "keep_alive"; } - # Micardo driver sometimes only play together with T=0 - # In theory only the 'cold' ATR should be specified, as T=0 will - # be the preferred protocol once you boot it up with T=0, but be - # paranoid. - # - # D-Trust cards are also based on micardo and need T=0 for some reason - card_atr 3b:ff:94:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:23 { - force_protocol = t0; - } - card_atr 3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6 { - force_protocol = t0; - } - # Oberthur's AuthentIC v3.2.2 card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B { type = 11100; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index ff1e2a6651..09edd87e4e 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -39,9 +39,9 @@ static struct sc_atr_table mcrd_atrs[] = { {"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL, "Micardo 2.1/German BMI/D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, {"3b:6f:00:ff:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00", NULL, - "D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL}, + "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, {"3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6", NULL, - "D-Trust", SC_CARD_TYPE_MCRD_DTRUST, 0, NULL}, + "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, /* Certain pcsc-lite versions (1.5.3 for example on Ubuntu 10.04) incorrectly truncate the warm ATR to the length of the cold ATR */ /* See opensc.conf for further information */ {"3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20", NULL, "Broken EstEID 1.1 warm", SC_CARD_TYPE_MCRD_ESTEID_V11, 0, NULL}, @@ -1253,9 +1253,7 @@ static int mcrd_set_security_env(sc_card_t * card, return 0; } - if (card->type == SC_CARD_TYPE_MCRD_DTRUST - || card->type == SC_CARD_TYPE_MCRD_GENERIC) { - sc_log(card->ctx, "Using SC_CARD_TYPE_MCRD_DTRUST\n"); + if (card->type == SC_CARD_TYPE_MCRD_GENERIC) { /* some sanity checks */ if (env->flags & SC_SEC_ENV_ALG_PRESENT) { if (env->algorithm != SC_ALGORITHM_RSA) @@ -1303,8 +1301,7 @@ static int mcrd_set_security_env(sc_card_t * card, *p++ = 0x03; *p++ = 0x80; - if (card->type == SC_CARD_TYPE_MCRD_DTRUST - || card->type == SC_CARD_TYPE_MCRD_GENERIC) { + if (card->type == SC_CARD_TYPE_MCRD_GENERIC) { unsigned char fid; fid = env->key_ref[0]; @@ -1515,8 +1512,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, return SC_SUCCESS; } - if (card->type == SC_CARD_TYPE_MCRD_DTRUST - || card->type == SC_CARD_TYPE_MCRD_GENERIC) { + if (SC_CARD_TYPE_MCRD_GENERIC) { sc_log(card->ctx, "modify pin reference for D-Trust\n"); if (data->pin_reference == 0x02) data->pin_reference = data->pin_reference | 0x80; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index d6db6a30eb..12d6c834a9 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -439,52 +439,6 @@ fix_authentic_ddo(struct sc_pkcs15_card *p15card) } } - -static void -fix_starcos_pkcs15_card(struct sc_pkcs15_card *p15card) -{ - struct sc_context *ctx = p15card->card->ctx; - - /* set special flags based on card meta data */ - if (strcmp(p15card->card->driver->short_name,"cardos") == 0 - && p15card->tokeninfo && p15card->tokeninfo->label) { - - /* D-Trust cards (D-TRUST, D-SIGN) */ - if (strstr(p15card->tokeninfo->label,"D-TRUST") != NULL - || strstr(p15card->tokeninfo->label,"D-SIGN") != NULL) { - - /* D-TRUST Card 2.0 2cc (standard cards, which always add - * SHA1 prefix itself */ - if (strstr(p15card->tokeninfo->label, "2cc") != NULL) { - p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED; - sc_log(ctx, "D-TRUST 2cc card detected, only SHA1 works with this card"); - /* XXX: add detection when other hash than SHA1 is used with - * such a card, as this produces invalid signatures. - */ - } - - /* D-SIGN multicard 2.0 2ca (cards working with all types of hashes - * and no addition of prefix) */ - else if (strstr(p15card->tokeninfo->label, "2ca") != NULL) { - p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH; - sc_log(ctx, "D-TRUST 2ca card detected"); - } - - /* D-TRUST card 2.4 2ce (cards working with all types of hashes - * and no addition of prefix) */ - else if (strstr(p15card->tokeninfo->label, "2ce") != NULL) { - p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH; - sc_log(ctx, "D-TRUST 2ce card detected"); - } - - /* XXX: probably there are more D-Trust card in the wild, - * which also need these flags to produce valid signatures - */ - } - } -} - - static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen) { @@ -1293,8 +1247,6 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, goto error; } done: - fix_starcos_pkcs15_card(p15card); - *p15card_out = p15card; sc_unlock(card); LOG_FUNC_RETURN(ctx, SC_SUCCESS); From 58aeb625736f3480fc4a7de7cae57d4fdf97a9ec Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 May 2018 23:50:26 +0200 Subject: [PATCH 0264/4321] OPENSC_DRIVER: restrict driver list instead of forcing one (#1277) Using the forced-driver prevents parsing of additional constructions in configuration files (for example flags based on ATRs). This implementation replaces transparently the existing list defined in card_drivers. Resolves: #1266 --- src/libopensc/ctx.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 474438345d..f6022dba77 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -349,13 +349,29 @@ int sc_ctx_log_to_file(sc_context_t *ctx, const char* filename) return SC_SUCCESS; } +static void +set_drivers(struct _sc_ctx_options *opts, const scconf_list *list) +{ + const char *s_internal = "internal", *s_old = "old"; + if (list != NULL) + del_drvs(opts); + while (list != NULL) { + if (strcmp(list->data, s_internal) == 0) + add_internal_drvs(opts); + else if (strcmp(list->data, s_old) == 0) + add_old_drvs(opts); + else + add_drv(opts, list->data); + list = list->next; + } +} static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { int err = 0; const scconf_list *list; - const char *val, *s_internal = "internal", *s_old = "old"; + const char *val; int debug; #ifdef _WIN32 char expanded_val[PATH_MAX]; @@ -389,17 +405,7 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; list = scconf_find_list(block, "card_drivers"); - if (list != NULL) - del_drvs(opts); - while (list != NULL) { - if (strcmp(list->data, s_internal) == 0) - add_internal_drvs(opts); - else if (strcmp(list->data, s_old) == 0) - add_old_drvs(opts); - else - add_drv(opts, list->data); - list = list->next; - } + set_drivers(opts, list); return err; } @@ -790,6 +796,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) sc_context_t *ctx; struct _sc_ctx_options opts; int r; + char *driver; if (ctx_out == NULL || parm == NULL) return SC_ERROR_INVALID_ARGUMENTS; @@ -846,14 +853,17 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) return r; } + driver = getenv("OPENSC_DRIVER"); + if (driver) { + scconf_list *list = NULL; + scconf_list_add(&list, driver); + set_drivers(&opts, list); + scconf_list_destroy(list); + } + load_card_drivers(ctx, &opts); load_card_atrs(ctx); - char *driver = getenv("OPENSC_DRIVER"); - if (driver) { - if (SC_SUCCESS != sc_set_card_driver(ctx, driver)) - sc_log(ctx, "Warning: Could not load %s.", driver); - } del_drvs(&opts); sc_ctx_detect_readers(ctx); *ctx_out = ctx; From 8d4fbc34c3199a92e0e68a64d079638f72f2210f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 13 Apr 2018 11:49:20 +0200 Subject: [PATCH 0265/4321] coolkey: Make uninitialized cards working as expected with ESC Original patch from John Magne --- src/libopensc/card-coolkey.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 0560412df5..58c582e316 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1094,6 +1094,15 @@ static int coolkey_select_applet(sc_card_t *card) &aid[0], sizeof(aid), NULL, NULL, NULL, 0); } +/* select the gp card manager */ +static int coolkey_select_card_mgr(sc_card_t *card) +{ + u8 aid[] = { 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00 }; + return coolkey_apdu_io(card, ISO7816_CLASS, ISO7816_INS_SELECT_FILE, 4, 0, + &aid[0], sizeof(aid), NULL, NULL, NULL, 0); +} + + static void coolkey_make_cuid_from_cplc(coolkey_cuid_t *cuid, global_platform_cplc_data_t *cplc_data) { @@ -1951,7 +1960,7 @@ static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil *file_out = file; } - return SC_SUCCESS; + return SC_SUCCESS; } static int coolkey_finish(sc_card_t *card) @@ -2144,12 +2153,6 @@ static int coolkey_initialize(sc_card_t *card) if (card->drv_data) { return SC_SUCCESS; } - - /* Select a coolkey read the coolkey objects out */ - r = coolkey_select_applet(card); - if (r < 0) { - return r; - } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Coolkey Applet found"); priv = coolkey_new_private_data(); @@ -2161,6 +2164,13 @@ static int coolkey_initialize(sc_card_t *card) if (r < 0) { goto cleanup; } + + /* Select a coolkey read the coolkey objects out */ + r = coolkey_select_applet(card); + if (r < 0) { + return r; + } + priv->protocol_version_major = life_cycle.protocol_version_major; priv->protocol_version_minor = life_cycle.protocol_version_minor; priv->pin_count = life_cycle.pin_count; @@ -2211,6 +2221,14 @@ static int coolkey_initialize(sc_card_t *card) /* if we didn't pull the cuid from the combined object, then grab it now */ if (!combined_processed) { global_platform_cplc_data_t cplc_data; + /* select the card manager, because a card with applet only will have + already selected the coolkey applet */ + + r = coolkey_select_card_mgr(card); + if (r < 0) { + goto cleanup; + } + r = coolkey_get_cplc_data(card, &cplc_data); if (r < 0) { goto cleanup; From b6e08e008ef5464811dd9a7df038c0f7e41fc7c1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 17 Apr 2018 11:00:37 +0200 Subject: [PATCH 0266/4321] Move the Global Platform related commands to separate file and port existing code to that --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-coolkey.c | 12 +----- src/libopensc/card-iasecc.c | 16 ++------ src/libopensc/card-oberthur.c | 12 +----- src/libopensc/gp.c | 75 +++++++++++++++++++++++++++++++++++ src/libopensc/gp.h | 42 ++++++++++++++++++++ 7 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 src/libopensc/gp.c create mode 100644 src/libopensc/gp.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index a71256b065..01533ba0ed 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -7,7 +7,7 @@ EXTRA_DIST = Makefile.mak opensc.dll.manifest lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ internal-winscard.h p15card-helper.h pkcs15-syn.h \ - opensc.h pkcs15.h \ + opensc.h pkcs15.h gp.h \ cardctl.h asn1.h log.h simpletlv.h \ errors.h types.h compression.h itacns.h iso7816.h \ authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \ @@ -23,7 +23,7 @@ AM_OBJCFLAGS = $(AM_CFLAGS) libopensc_la_SOURCES_BASE = \ sc.c ctx.c log.c errors.c \ asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c \ - ef-gdo.c padding.c apdu.c simpletlv.c \ + ef-gdo.c padding.c apdu.c simpletlv.c gp.c \ \ pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 26760ae22d..10a3b0a9dd 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -4,7 +4,7 @@ TARGET = opensc.dll opensc_a.lib OBJECTS = \ sc.obj ctx.obj log.obj errors.obj \ asn1.obj base64.obj sec.obj card.obj iso7816.obj dir.obj ef-atr.obj \ - ef-gdo.obj padding.obj apdu.obj simpletlv.obj \ + ef-gdo.obj padding.obj apdu.obj simpletlv.obj gp.obj \ \ pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \ pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-skey.obj \ diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 58c582e316..768ff22e86 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -58,6 +58,7 @@ #include "compression.h" #endif #include "iso7816.h" +#include "gp.h" #include "../pkcs11/pkcs11.h" @@ -1094,15 +1095,6 @@ static int coolkey_select_applet(sc_card_t *card) &aid[0], sizeof(aid), NULL, NULL, NULL, 0); } -/* select the gp card manager */ -static int coolkey_select_card_mgr(sc_card_t *card) -{ - u8 aid[] = { 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00 }; - return coolkey_apdu_io(card, ISO7816_CLASS, ISO7816_INS_SELECT_FILE, 4, 0, - &aid[0], sizeof(aid), NULL, NULL, NULL, 0); -} - - static void coolkey_make_cuid_from_cplc(coolkey_cuid_t *cuid, global_platform_cplc_data_t *cplc_data) { @@ -2224,7 +2216,7 @@ static int coolkey_initialize(sc_card_t *card) /* select the card manager, because a card with applet only will have already selected the coolkey applet */ - r = coolkey_select_card_mgr(card); + r = gp_select_card_manager(card); if (r < 0) { goto cleanup; } diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 5d25c3c2f8..d23404021e 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -45,6 +45,7 @@ /* #include "sm.h" */ #include "pkcs15.h" /* #include "hash-strings.h" */ +#include "gp.h" #include "iasecc.h" @@ -90,12 +91,6 @@ static struct sc_atr_table iasecc_known_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; -static struct sc_aid GlobalPlatform_CardManager_AID = { - { 0xA0,0x00,0x00,0x00,0x03,0x00,0x00}, 7 -}; -static struct sc_aid GlobalPlatform_ISD_Default_RID = { - { 0xA0,0x00,0x00,0x01,0x51,0x00,0x00}, 7 -}; static struct sc_aid OberthurIASECC_AID = { {0xA0,0x00,0x00,0x00,0x77,0x01,0x08,0x00,0x07,0x00,0x00,0xFE,0x00,0x00,0x01,0x00}, 16 }; @@ -477,8 +472,6 @@ static int iasecc_init_oberthur(struct sc_card *card) { struct sc_context *ctx = card->ctx; - unsigned char resp[0x100]; - size_t resp_len; unsigned int flags; int rv = 0; @@ -495,10 +488,9 @@ iasecc_init_oberthur(struct sc_card *card) iasecc_parse_ef_atr(card); - resp_len = sizeof(resp); - if (iasecc_select_aid(card, &GlobalPlatform_CardManager_AID, resp, &resp_len)) { - resp_len = sizeof(resp); - iasecc_select_aid(card, &GlobalPlatform_ISD_Default_RID, resp, &resp_len); + /* if we fail to select CM, */ + if (gp_select_card_manager(card)) { + gp_select_isd_rid(card); } rv = iasecc_oberthur_match(card); diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index c8c11459a8..818a6a6cb5 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -39,6 +39,7 @@ #include "internal.h" #include "cardctl.h" #include "pkcs15.h" +#include "gp.h" #define OBERTHUR_PIN_LOCAL 0x80 #define OBERTHUR_PIN_REFERENCE_USER 0x81 @@ -157,19 +158,10 @@ auth_select_aid(struct sc_card *card) unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; struct auth_private_data *data = (struct auth_private_data *) card->drv_data; int rv, ii; - unsigned char cm[7] = {0xA0,0x00,0x00,0x00,0x03,0x00,0x00}; struct sc_path tmp_path; /* Select Card Manager (to deselect previously selected application) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); - apdu.lc = sizeof(cm); - /* apdu.le = sizeof(cm)+4; */ - apdu.data = cm; - apdu.datalen = sizeof(cm); - apdu.resplen = sizeof(apdu_resp); - apdu.resp = apdu_resp; - - rv = sc_transmit_apdu(card, &apdu); + rv = gp_select_card_manager(card); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); /* Get smart card serial number */ diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c new file mode 100644 index 0000000000..4d65b3939a --- /dev/null +++ b/src/libopensc/gp.c @@ -0,0 +1,75 @@ +/* + * gp.c: Global Platform Related functions + * + * Copyright (C) 2018 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "internal.h" + +/* The AID of the Card Manager defined by Open Platform 2.0.1 specification */ +static const struct sc_aid gp_card_manager = { + {0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00}, 7 +}; + +/* The AID of the Issuer Security Domain defined by GlobalPlatform 2.3.1 specification. */ +static const struct sc_aid gp_isd_rid = { + {0xA0, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00}, 7 +}; + + +/* Select AID */ +static int +gp_select_aid(struct sc_card *card, const struct sc_aid *aid) +{ + struct sc_apdu apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); + apdu.lc = aid->len; + apdu.data = aid->value; + apdu.datalen = aid->len; + + return sc_transmit_apdu(card, &apdu); + +} + +/* Select the Open Platform Card Manager */ +int +gp_select_card_manager(struct sc_card *card) +{ + int rv; + + LOG_FUNC_CALLED(card->ctx); + rv = gp_select_aid(card, &gp_card_manager); + LOG_FUNC_RETURN(card->ctx, rv); +} + +/* Select Global Platform Card Manager */ +int +gp_select_isd_rid(struct sc_card *card) +{ + int rv; + + LOG_FUNC_CALLED(card->ctx); + rv = gp_select_aid(card, &gp_isd_rid); + LOG_FUNC_RETURN(card->ctx, rv); +} diff --git a/src/libopensc/gp.h b/src/libopensc/gp.h new file mode 100644 index 0000000000..458936e4dc --- /dev/null +++ b/src/libopensc/gp.h @@ -0,0 +1,42 @@ +/* + * gp.h: Global Platform Related functions + * + * Copyright (C) 2018 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LIBOPENSC_GP_H +#define _LIBOPENSC_GP_H + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int gp_select_card_manager(struct sc_card *card); +int gp_select_isd_rid(struct sc_card *card); + +#ifdef __cplusplus +} +#endif + +#endif From 9b4e00b24b042cea80145bc9c7c9feada4843283 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 May 2018 14:29:21 +0200 Subject: [PATCH 0267/4321] gp.c: Properly check the SWs of the APDU when selecting AID --- src/libopensc/gp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index 4d65b3939a..49bf934f00 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -42,14 +42,23 @@ static int gp_select_aid(struct sc_card *card, const struct sc_aid *aid) { struct sc_apdu apdu; + int rv; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); apdu.lc = aid->len; apdu.data = aid->value; apdu.datalen = aid->len; - return sc_transmit_apdu(card, &apdu); + rv = sc_transmit_apdu(card, &apdu); + + if (rv < 0) + return rv; + + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (rv < 0) + return rv; + return apdu.resplen; } /* Select the Open Platform Card Manager */ @@ -59,7 +68,7 @@ gp_select_card_manager(struct sc_card *card) int rv; LOG_FUNC_CALLED(card->ctx); - rv = gp_select_aid(card, &gp_card_manager); + rv = gp_select_aid(card, &gp_card_manager); LOG_FUNC_RETURN(card->ctx, rv); } From c57c743ed09b04d70383799cf173144b84b17266 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 13 May 2018 13:02:44 +0200 Subject: [PATCH 0268/4321] configure.ac: stop including version.m4 Do not blindly override already defined variables or macros with outdated values by including version.m4 This makes sure the definitions of variables or macros defined earlier in configure.ac remain intact; e.g. it keeps the macro PRODUCT_BUGREPORT set to the GitHub URL instead of pointing to a SourceForge mail address. --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 98fbec56e3..e7bdcfdbf0 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,6 @@ define([VS_FF_PRODUCT_NAME], [OpenSC smartcard framework]) define([VS_FF_PRODUCT_UPDATES], [https://github.com/OpenSC/OpenSC/releases]) define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) -m4_include(version.m4) m4_sinclude(version.m4.ci) AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME]) From a6b596d09a7025746c554d1489da68758c5148e9 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 13 May 2018 13:11:50 +0200 Subject: [PATCH 0269/4321] version.m4: overhaul - add macro PACKAGE_VERSION_REVISION dealt with in bootstrap.ci - restrict to those macros only that are mangled by bootstrap.ci - update comments on the file's purpose and the processes around it --- version.m4 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/version.m4 b/version.m4 index e526098b25..1f7d6498c3 100644 --- a/version.m4 +++ b/version.m4 @@ -1,11 +1,6 @@ -dnl define the OpenSC version -define([PRODUCT_NAME], [OpenSC]) -define([PRODUCT_TARNAME], [opensc]) -define([PRODUCT_BUGREPORT], [opensc-devel@lists.sourceforge.net]) +dnl version.m4 - source for version.m4.ci generated by bootstrap.ci +dnl * bootstrap.ci generates version.m4.ci based on this file +dnl * if version.m4.ci exists, it is included in configure.ac define([PACKAGE_SUFFIX], []) - -define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) -define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) -define([VS_FF_COMMENTS], [Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).]) -define([VS_FF_PRODUCT_NAME], [OpenSC smartcard framework]) +define([PACKAGE_VERSION_REVISION], []) From e4cab31763a8880b6618ec130d1d91d18837d2bf Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 13 May 2018 13:20:01 +0200 Subject: [PATCH 0270/4321] bootstrap.ci: flexibilize option -R When -R is given, accept indication of -rc resp. ~rc version strings in git describe's output. --- bootstrap.ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.ci b/bootstrap.ci index 50fc1cc106..ba42565a94 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -39,7 +39,7 @@ do REVISION=$OPTARG ;; R) - REVISION=`git describe | perl -ne 'print $1 if /^[\.0-9]*-([0-9]*)-g[a-z0-9]*$/;'` + REVISION=`git describe | perl -ne 'print $1 if /^[\.0-9]*([-~]rc[0-9]+)?-([0-9]*)-g[a-z0-9]*$/;'` ;; ?) usage From 59a7478011e80eaf3f48ac4027fd3a0bb929b84a Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 13 May 2018 13:33:57 +0200 Subject: [PATCH 0271/4321] configure.ac: extend AC_INIT Define macro PRODUCT_URL and use it as additional argument to AC_INIT(). --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e7bdcfdbf0..8e8a2cff5d 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ AC_PREREQ(2.60) define([PRODUCT_NAME], [OpenSC]) define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) +define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [18]) define([PACKAGE_VERSION_FIX], [0]) @@ -20,7 +21,7 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(version.m4.ci) -AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME]) +AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) From 8b3e53c730614a565c471d56b1298b95b8d5cae2 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 19 May 2018 08:29:22 +0200 Subject: [PATCH 0272/4321] bootstrap.ci: stop playing with unused PACKAGE_VERSION_REVISION PACKAGE_VERSION_REVISION is not used outside bootstrap.ci; remove everything that deals with it. --- bootstrap.ci | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/bootstrap.ci b/bootstrap.ci index ba42565a94..93d53b7a18 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -10,8 +10,6 @@ OPTIONS: -h Show this message -s Package suffix -S Use package suffix as 'g' appended with the date of last commit - -r Package version revision - -R Use package version revision as Git commit number from 'git describe' result -b Package branch -B Use package branch as current Git branch EOF @@ -19,10 +17,9 @@ EOF SUFFIX= -REVISION= VERBOSE= KEEPVERSION= -while getopts “:hs:Sr:RK†OPTION +while getopts “:hs:SK†OPTION do case $OPTION in h) @@ -35,12 +32,6 @@ do S) SUFFIX=g`git log -1 --pretty=fuller --date=iso | grep CommitDate: | sed -E 's/^CommitDate:\s(.*)/\1/' | sed -E 's/(.*)-(.*)-(.*) (.*):(.*):(.*)\s+.*/\1\2\3\4\5\6/'` ;; - r) - REVISION=$OPTARG - ;; - R) - REVISION=`git describe | perl -ne 'print $1 if /^[\.0-9]*([-~]rc[0-9]+)?-([0-9]*)-g[a-z0-9]*$/;'` - ;; ?) usage exit @@ -56,24 +47,10 @@ fi rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmain.sh version.m4.ci -if [ -n "$SUFFIX" ] || [ -n "$REVISION" ] +if [ -n "$SUFFIX" ] then - cp -a version.m4 version.m4.tmp - - if [ -n "$SUFFIX" ] - then - echo Set package suffix "$SUFFIX" - sed 's/^define(\[PACKAGE_SUFFIX\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_SUFFIX\], \['$SUFFIX'\])/g' version.m4.tmp > version.m4.ci - cp version.m4.ci version.m4.tmp - fi - - if [ -n "$REVISION" ] - then - echo Set package revision "$REVISION" - sed 's/^define(\[PACKAGE_VERSION_REVISION\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_VERSION_REVISION\], \['$REVISION'\])/g' version.m4.tmp > version.m4.ci - fi - - rm -f version.m4.tmp + echo Set package suffix "$SUFFIX" + sed 's/^define(\[PACKAGE_SUFFIX\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_SUFFIX\], \['$SUFFIX'\])/g' < version.m4 > version.m4.ci fi ./bootstrap From 4cbdf53b8bc56f54de0da1c9a3819393a7d982e2 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 19 May 2018 08:34:53 +0200 Subject: [PATCH 0273/4321] bootstrap.ci: cleanup - remove unused code & options --- bootstrap.ci | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bootstrap.ci b/bootstrap.ci index 93d53b7a18..162282d04f 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -10,16 +10,12 @@ OPTIONS: -h Show this message -s Package suffix -S Use package suffix as 'g' appended with the date of last commit - -b Package branch - -B Use package branch as current Git branch EOF } SUFFIX= -VERBOSE= -KEEPVERSION= -while getopts “:hs:SK†OPTION +while getopts “:hs:S†OPTION do case $OPTION in h) From 882080cdf7c1ed76246a79227f424efa0ec045cb Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 19 May 2018 08:54:20 +0200 Subject: [PATCH 0274/4321] version.m4: remove unused macro PACKAGE_VERSION_REVISION --- version.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/version.m4 b/version.m4 index 1f7d6498c3..f493f837ce 100644 --- a/version.m4 +++ b/version.m4 @@ -2,5 +2,4 @@ dnl version.m4 - source for version.m4.ci generated by bootstrap.ci dnl * bootstrap.ci generates version.m4.ci based on this file dnl * if version.m4.ci exists, it is included in configure.ac define([PACKAGE_SUFFIX], []) -define([PACKAGE_VERSION_REVISION], []) From 4590d915b9e53a5b961db56f36e3503efb78c2af Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 11:51:50 +0200 Subject: [PATCH 0275/4321] bootstrap.ci: stop echoing executed commands --- bootstrap.ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.ci b/bootstrap.ci index 162282d04f..bab336c570 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -36,7 +36,7 @@ do done set -e -set -x + if [ -f Makefile ]; then make distclean fi From 45e4f546c2dfb3d6d232ca55d49b007a56d3cb44 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 May 2018 20:57:13 +0200 Subject: [PATCH 0276/4321] regenerated built files (gengetopt/help2man) includes an explicit locale for help2man to recognize umlauts. partially fixes https://github.com/OpenSC/OpenSC/issues/1365 --- src/tools/Makefile.am | 6 ++++++ src/tools/egk-tool-cmdline.c | 4 ++-- src/tools/egk-tool-cmdline.h | 4 ++-- src/tools/egk-tool.1 | 8 ++++---- src/tools/npa-tool-cmdline.c | 2 +- src/tools/npa-tool-cmdline.h | 8 ++++---- src/tools/npa-tool.1 | 10 +++++----- src/tools/opensc-asn1-cmdline.c | 4 ++-- src/tools/opensc-asn1.1 | 8 ++++---- src/tools/opensc-notify-cmdline.c | 4 +++- src/tools/opensc-notify.1 | 8 ++++---- 11 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 7e37f107d1..d83a7b56dd 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -19,6 +19,8 @@ do_subst = $(SED) \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' +HELP2MAN_LOCALE ?= C.UTF-8 + EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c @@ -109,6 +111,7 @@ npa-tool.1: $(HELP2MAN) \ --output=$@ \ --no-info \ + --locale=$(HELP2MAN_LOCALE) \ --source='$(PACKAGE_STRING)' \ $(builddir)/npa-tool$(EXEEXT) @@ -136,6 +139,7 @@ opensc-notify.1: $(HELP2MAN) \ --output=$@ \ --no-info \ + --locale=$(HELP2MAN_LOCALE) \ --source='$(PACKAGE_STRING)' \ $(builddir)/opensc-notify$(EXEEXT) @@ -163,6 +167,7 @@ egk-tool.1: $(HELP2MAN) \ --output=$@ \ --no-info \ + --locale=$(HELP2MAN_LOCALE) \ --source='$(PACKAGE_STRING)' \ $(builddir)/egk-tool$(EXEEXT) @@ -187,6 +192,7 @@ opensc-asn1.1: $(HELP2MAN) \ --output=$@ \ --no-info \ + --locale=$(HELP2MAN_LOCALE) \ --source='$(PACKAGE_STRING)' \ $(builddir)/opensc-asn1$(EXEEXT) diff --git a/src/tools/egk-tool-cmdline.c b/src/tools/egk-tool-cmdline.c index 9fc4e4bcf5..1ae79678bc 100644 --- a/src/tools/egk-tool-cmdline.c +++ b/src/tools/egk-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/local/bin/gengetopt --include-getopt --file-name=egk-tool-cmdline --output-dir=. + /usr/bin/gengetopt --include-getopt --file-name=egk-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -42,7 +42,7 @@ const char *gengetopt_args_info_help[] = { " --vd Show 'Allgemeine Versicherungsdaten' (XML) (default=off)", " --gvd Show 'Geschützte Versicherungsdaten' (XML) (default=off)", " --vsd-status Show 'Versichertenstammdaten-Status' (default=off)", - "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; diff --git a/src/tools/egk-tool-cmdline.h b/src/tools/egk-tool-cmdline.h index b561e653ca..4b8912649f 100644 --- a/src/tools/egk-tool-cmdline.h +++ b/src/tools/egk-tool-cmdline.h @@ -42,8 +42,8 @@ struct gengetopt_args_info int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ - unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurrences */ - unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurrences */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ int pd_flag; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) (default=off). */ const char *pd_help; /**< @brief Show 'Persönliche Versicherungsdaten' (XML) help description. */ diff --git a/src/tools/egk-tool.1 b/src/tools/egk-tool.1 index f88a4bfeef..1718093a33 100644 --- a/src/tools/egk-tool.1 +++ b/src/tools/egk-tool.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH EGK-TOOL "1" "Oktober 2017" "OpenSC 0.17.0" "User Commands" +.TH EGK-TOOL "1" "May 2018" "OpenSC 0.18.0" "User Commands" .SH NAME -egk-tool \- manual page for egk-tool 0.17.0 +egk-tool \- manual page for egk-tool 0.18.0 .SH SYNOPSIS .B egk-tool [\fI\,OPTIONS\/\fR]... .SH DESCRIPTION -egk\-tool 0.17.0 +egk\-tool 0.18.0 .TP \fB\-h\fR, \fB\-\-help\fR Print help and exit @@ -36,4 +36,4 @@ Show 'Versichertenstammdaten\-Status' (default=off) .SH AUTHOR Written by Frank Morgner .SH "REPORTING BUGS" -Report bugs to opensc\-devel@lists.sourceforge.net +Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index a269c37bbb..117c6cb156 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -93,7 +93,7 @@ const char *gengetopt_args_info_help[] = { " -t, --translate=FILENAME File with APDUs of HEX_STRINGs to send through\n the secure channel (default=`stdin')", " --tr-03110v201 Force compliance to BSI TR-03110 version 2.01\n (default=off)", " --disable-all-checks Disable all checking of fly-by-data\n (default=off)", - "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index 4db3d937e9..8c78362a0d 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -42,8 +42,8 @@ struct gengetopt_args_info int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ - unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurrences */ - unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurrences */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ char * pin_arg; /**< @brief Run PACE with (transport) eID-PIN. */ char * pin_orig; /**< @brief Run PACE with (transport) eID-PIN original value given at command line. */ @@ -68,8 +68,8 @@ struct gengetopt_args_info const char *unblock_help; /**< @brief Unblock PIN (uses PUK to activate three more retries) help description. */ char ** cv_certificate_arg; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).. */ char ** cv_certificate_orig; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important). original value given at command line. */ - unsigned int cv_certificate_min; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s minimum occurrences */ - unsigned int cv_certificate_max; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s maximum occurrences */ + unsigned int cv_certificate_min; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s minimum occurreces */ + unsigned int cv_certificate_max; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important).'s maximum occurreces */ const char *cv_certificate_help; /**< @brief Card Verifiable Certificate to create a certificate chain. Can be used multiple times (order is important). help description. */ char * cert_desc_arg; /**< @brief Certificate description to show for Terminal Authentication. */ char * cert_desc_orig; /**< @brief Certificate description to show for Terminal Authentication original value given at command line. */ diff --git a/src/tools/npa-tool.1 b/src/tools/npa-tool.1 index 896d5abbe8..a9704ab24a 100644 --- a/src/tools/npa-tool.1 +++ b/src/tools/npa-tool.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.4. -.TH NPA-TOOL "1" "July 2016" "OpenSC 0.16.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH NPA-TOOL "1" "May 2018" "OpenSC 0.18.0" "User Commands" .SH NAME -npa-tool \- manual page for npa-tool 0.16.0 +npa-tool \- manual page for npa-tool 0.18.0 .SH SYNOPSIS .B npa-tool [\fI\,OPTIONS\/\fR]... .SH DESCRIPTION -npa\-tool 0.16.0 +npa\-tool 0.18.0 .TP \fB\-h\fR, \fB\-\-help\fR Print help and exit @@ -202,4 +202,4 @@ Disable all checking of fly\-by\-data .SH AUTHOR Written by Frank Morgner .SH "REPORTING BUGS" -Report bugs to opensc\-devel@lists.sourceforge.net +Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/opensc-asn1-cmdline.c b/src/tools/opensc-asn1-cmdline.c index 0f3b0f68f4..cafbcd55ac 100644 --- a/src/tools/opensc-asn1-cmdline.c +++ b/src/tools/opensc-asn1-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/local/bin/gengetopt --include-getopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts + /usr/bin/gengetopt --include-getopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -35,7 +35,7 @@ const char *gengetopt_args_info_description = "Parse ASN.1 data."; const char *gengetopt_args_info_help[] = { " -h, --help Print help and exit", " -V, --version Print version and exit", - "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; diff --git a/src/tools/opensc-asn1.1 b/src/tools/opensc-asn1.1 index e56762fcf2..a12f6f8a5a 100644 --- a/src/tools/opensc-asn1.1 +++ b/src/tools/opensc-asn1.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH OPENSC-ASN1 "1" "November 2017" "OpenSC 0.17.0" "User Commands" +.TH OPENSC-ASN1 "1" "May 2018" "OpenSC 0.18.0" "User Commands" .SH NAME -opensc-asn1 \- manual page for opensc-asn1 0.17.0 +opensc-asn1 \- manual page for opensc-asn1 0.18.0 .SH SYNOPSIS .B opensc-asn1 [\fI\,OPTIONS\/\fR]... [\fI\,FILES\/\fR]... .SH DESCRIPTION -opensc\-asn1 0.17.0 +opensc\-asn1 0.18.0 .PP Parse ASN.1 data. .TP @@ -18,4 +18,4 @@ Print version and exit .SH AUTHOR Written by Frank Morgner .SH "REPORTING BUGS" -Report bugs to opensc\-devel@lists.sourceforge.net +Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index 81c4b993dd..1f87513421 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -43,7 +43,7 @@ const char *gengetopt_args_info_help[] = { " -R, --notify-card-removed See notify_card_inserted in opensc.conf\n (default=off)", " -G, --notify-pin-good See notify_pin_good in opensc.conf (default=off)", " -B, --notify-pin-bad See notify_pin_bad in opensc.conf (default=off)", - "\nReport bugs to opensc-devel@lists.sourceforge.net\n\nWritten by Frank Morgner ", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; @@ -1072,6 +1072,7 @@ cmdline_parser_internal ( int override; int initialize; + int check_required; int check_ambiguity; char *optarg; @@ -1083,6 +1084,7 @@ cmdline_parser_internal ( override = params->override; initialize = params->initialize; + check_required = params->check_required; check_ambiguity = params->check_ambiguity; if (initialize) diff --git a/src/tools/opensc-notify.1 b/src/tools/opensc-notify.1 index 3dce58c358..7628c030c9 100644 --- a/src/tools/opensc-notify.1 +++ b/src/tools/opensc-notify.1 @@ -1,12 +1,12 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH OPENSC-NOTIFY "1" "Oktober 2017" "OpenSC 0.17.0" "User Commands" +.TH OPENSC-NOTIFY "1" "May 2018" "OpenSC 0.18.0" "User Commands" .SH NAME -opensc-notify \- manual page for opensc-notify 0.17.0 +opensc-notify \- manual page for opensc-notify 0.18.0 .SH SYNOPSIS .B opensc-notify [\fI\,OPTIONS\/\fR]... .SH DESCRIPTION -opensc\-notify 0.17.0 +opensc\-notify 0.18.0 .PP If no arguments are given, monitor smart card events and send the appropriate notification. @@ -42,4 +42,4 @@ See notify_pin_bad in opensc.conf (default=off) .SH AUTHOR Written by Frank Morgner .SH "REPORTING BUGS" -Report bugs to opensc\-devel@lists.sourceforge.net +Report bugs to https://github.com/OpenSC/OpenSC/issues From 6b850994014f65b8638b19429a79562b55dcba53 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Apr 2018 13:02:30 +0200 Subject: [PATCH 0277/4321] pkcs11_enable_InitToken made global configuration option * Previously, it was dependent on ATR blocks, but it did not allow enrolling various types of cards without knowning their ATR in advance. * Improved documnetation for this option in configuration files Resolves: #1265 --- etc/opensc.conf.in | 8 ++++---- src/pkcs11/framework-pkcs15.c | 7 +++---- src/pkcs11/slot.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index c3cfc96449..956a12cedc 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -263,10 +263,6 @@ app default { # # flags = "rng", "keep_alive", "0x80000000"; - # Enable pkcs11 initialization. - # Default: no - # pkcs11_enable_InitToken = yes; - # # Context: PKCS#15 emulation layer # @@ -952,6 +948,10 @@ app default { # module = @LIBDIR@@LIB_PRE@p15emu_custom@DYN_LIB_EXT@; # } + # Enable initialization and card recognition in PKCS#11 layer. + # Default: no + # pkcs11_enable_InitToken = yes; + # some additional application parameters: # - type (generic, protected) used to distinguish the common access application # and application for which authentication to perform some operation cannot be diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 167e008185..3dba9b34c1 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1806,14 +1806,13 @@ pkcs15_initialize(struct sc_pkcs11_slot *slot, void *ptr, { struct sc_pkcs11_card *p11card = slot->p11card; struct sc_cardctl_pkcs11_init_token args; - scconf_block *atrblock = NULL; + scconf_block *conf_block = NULL; int rc, enable_InitToken = 0; CK_RV rv; sc_log(context, "Get 'enable-InitToken' card configuration option"); - atrblock = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr); - if (atrblock) - enable_InitToken = scconf_get_bool(atrblock, "pkcs11_enable_InitToken", 0); + conf_block = sc_get_conf_block(p11card->card->ctx, "framework", "pkcs15", 1); + enable_InitToken = scconf_get_bool(conf_block, "pkcs11_enable_InitToken", 0); memset(&args, 0, sizeof(args)); args.so_pin = pPin; diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index ffca0c1de3..5bfaa7eeb8 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -302,12 +302,17 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i); /* Bind 'generic' application or (emulated?) card without applications */ if (app_generic || !p11card->card->app_count) { - scconf_block *atrblock = NULL; + scconf_block *conf_block = NULL; int enable_InitToken = 0; - atrblock = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr); - if (atrblock) - enable_InitToken = scconf_get_bool(atrblock, "pkcs11_enable_InitToken", 0); + conf_block = sc_match_atr_block(p11card->card->ctx, NULL, + &p11card->reader->atr); + if (!conf_block) /* check default block */ + conf_block = sc_get_conf_block(context, + "framework", "pkcs15", 1); + + enable_InitToken = scconf_get_bool(conf_block, + "pkcs11_enable_InitToken", 0); sc_log(context, "%s: Try to bind 'generic' token.", reader->name); rv = frameworks[i]->bind(p11card, app_generic); From d7d674129ec021454b5f6285a213da912a50a39f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 16 Apr 2018 10:08:43 -0500 Subject: [PATCH 0278/4321] PIV History Object Related Changes - Fixes #1330 && is replaced by || in the test of valid key references for retired keys found in the Historic object. For retired keys, the user_consent flag was being set by default. Thus a C_Login(CKU_CONTEXT_SPECIFIC) would be required. NIST 800-73 only requires PIN_Always on the Sign Key. To extend the usefullnes of "retired keys" on non government issued PIV-like cards, code had already been added to use the certificate keyUsage flags to override the NIST defined key usage flags. The NONREPUDATION flag is now used to set the user_consent flag. So rather then always requiring C_Login(CKU_CONTEXT_SPECIFIC) for any retured key, the code only requires it for non government cards where teh certificate has NONREPUDATION. Changes to be committed: modified: card-piv.c modified: pkcs15-piv.c --- src/libopensc/card-piv.c | 2 +- src/libopensc/pkcs15-piv.c | 50 ++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 8f7c4ebb38..c8b39adf5f 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2871,7 +2871,7 @@ piv_process_history(sc_card_t *card) } keyref = sc_asn1_find_tag(card->ctx, seq, seqlen, 0x04, &keyreflen); if (!keyref || keyreflen != 1 || - (*keyref < 0x82 && *keyref > 0x95)) { + (*keyref < 0x82 || *keyref > 0x95)) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 62a5812322..1401ea4df1 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -528,83 +528,83 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) { "05", "Retired KEY MAN 1", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x82, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x82, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "06", "Retired KEY MAN 2", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x83, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x83, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "07", "Retired KEY MAN 3", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x84, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x84, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "08", "Retired KEY MAN 4", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x85, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x85, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "09", "Retired KEY MAN 5", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x86, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x86, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "10", "Retired KEY MAN 6", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x87, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x87, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "11", "Retired KEY MAN 7", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "12", "Retired KEY MAN 8", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x89, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x89, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "13", "Retired KEY MAN 9", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "14", "Retired KEY MAN 10", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8B, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8B, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "15", "Retired KEY MAN 11", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "16", "Retired KEY MAN 12", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "17", "Retired KEY MAN 13", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8E, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8E, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "18", "Retired KEY MAN 14", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x8F, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x8F, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "19", "Retired KEY MAN 15", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x90, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x90, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "20", "Retired KEY MAN 16", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x91, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x91, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "21", "Retired KEY MAN 17", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x92, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x92, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "22", "Retired KEY MAN 18", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x93, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x93, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "23", "Retired KEY MAN 19", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x94, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x94, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}, { "24", "Retired KEY MAN 20", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1} + "", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0} }; int r, i; @@ -1142,7 +1142,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); strncpy(prkey_obj.label, prkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); prkey_obj.flags = prkeys[i].obj_flags; - prkey_obj.user_consent = prkeys[i].user_consent; + prkey_obj.user_consent = prkeys[i].user_consent; /* only Sign key */ if (prkeys[i].auth_id) sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id); @@ -1165,6 +1165,10 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); case SC_ALGORITHM_RSA: if(ckis[i].cert_keyUsage_present) { prkey_info.usage |= ckis[i].priv_usage; + /* If retired key and non gov cert has NONREPUDIATION, treat as user_consent */ + if (i >= 4 && (ckis[i].priv_usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) { + prkey_obj.user_consent = 1; + } } else { prkey_info.usage |= prkeys[i].usage_rsa; } @@ -1174,6 +1178,10 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); case SC_ALGORITHM_EC: if (ckis[i].cert_keyUsage_present) { prkey_info.usage |= ckis[i].priv_usage; + /* If retired key and non gov cert has NONREPUDIATION, treat as user_consent */ + if (i >= 4 && (ckis[i].priv_usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) { + prkey_obj.user_consent = 1; + } } else { prkey_info.usage |= prkeys[i].usage_ec; } From 08ec4b85e1d25ae83ccba6115549ab4be8db9dae Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 17 Apr 2018 15:25:57 -0500 Subject: [PATCH 0279/4321] PIV Better Handling of Reset If a PIV card does not have or support a Discovery Object and is known to lose the login state when the PIV AID is selected, nothing was done in piv_card_reader_lock_obtained. If was_reset > 0 select the PIV AID to at least get the PIV AID selected. For other cards either reading the Discovery a object and/or selecting the PIV AID will make sure the PIV AID is selected. If multiple applications are using the card, this will allow the first one to select the AID, and any others that handle a reset will not cause interference wit the first. On branch History-fixes Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c8b39adf5f..01bc7939dc 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3581,19 +3581,12 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) goto err; } - /* can we detect and then select the PIV AID without losing the login state? */ - if ((priv->card_issues & CI_DISCOVERY_USELESS) - && (priv->card_issues & CI_PIV_AID_LOSE_STATE)) { - r = 0; /* do nothing, hope card was not interfered with */ - goto err; - } - /* make sure our application is active */ /* first see if AID is active AID by reading discovery object '7E' */ /* If not try selecting AID */ - /* but if x card does not support DISCOVERY object we can not use it */ + /* but if card does not support DISCOVERY object we can not use it */ if (priv->card_issues & CI_DISCOVERY_USELESS) { r = SC_ERROR_NO_CARD_SUPPORT; } else { @@ -3601,7 +3594,7 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) } if (r < 0) { - if (!(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { + if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); } else { r = 0; /* cant do anything with this card, hope there was no interference */ From 91812cf40f12028bb366c77def22e13f5814eafa Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 18 Apr 2018 21:04:00 -0500 Subject: [PATCH 0280/4321] Context Specific Login Using Pin Pad Reader Fix sc_pkcs15_verify_pin say: /* if pin cache is disabled, we can get here with no PIN data. * in this case, to avoid error or unnecessary pin prompting on pinpad, * check if the PIN has been already verified and the access condition * is still open on card. */ It then call sc_pkcs15_get_pin_info A context specific login is used in PKCS#11 to force the user to enter the PIN again and a verify command be sent to the card. (Actually it could be a different value for the PINi depending on the card) sc_pkcs15_get_pin_info will then call the card driver, but does not say why it is testing the login status.sc_pkcs15_get_pin_info may return SC_PIN_STATE_LOGGED_IN=1 and sc_pkcs15_verify_pin will then skip sending the actual verify command to the card via _sc_pkcs15_verify_pin To avoid this, sc_pkcs15_get_pin_info will set data.pin_type = pin_info->auth_method; In the case of a context specific login, this is SC_AC_CONTEXT_SPECIFIC and the card driver can take action and can return SC_PIN_STATE_LOGGED_IN=0 so the verify will be done. The PIV driver card-piv.c does this. Other drivers could do something similar. Date: MOn May 21 20:40:00 2018 -0500 On branch History-fixes Changes to be committed: modified: card-piv.c modified: pkcs15-pin.c --- src/libopensc/card-piv.c | 10 ++++++++++ src/libopensc/pkcs15-pin.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 01bc7939dc..722315bf15 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3452,6 +3452,16 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) data->pin1.tries_left = priv->tries_left; if (tries_left) *tries_left = priv->tries_left; + + /* + * If called to check on the login state for a context specific login + * return not logged in. Needed because of logic in e6f7373ef066 + */ + if (data->pin_type == SC_AC_CONTEXT_SPECIFIC) { + data->pin1.logged_in = 0; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + if (priv->logged_in == SC_PIN_STATE_LOGGED_IN) { /* Avoid status requests when the user is logged in to handle NIST * 800-73-4 Part 2: diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 4e807be907..ab94e74f0c 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -700,7 +700,7 @@ int sc_pkcs15_get_pin_info(struct sc_pkcs15_card *p15card, /* Try to update PIN info from card */ memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_GET_INFO; - data.pin_type = SC_AC_CHV; + data.pin_type = pin_info->auth_method; data.pin_reference = pin_info->attrs.pin.reference; r = sc_pin_cmd(card, &data, NULL); From 410cdf0dcc2dce62f0d4bac00619ddd77920b279 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 23 Jan 2018 13:53:23 +0100 Subject: [PATCH 0281/4321] refactored sc_get_challenge Let sc_get_challenge() do sc_lock() and loop through the card driver's get_challenge() until enough bytes were collected. The card driver's get_challenge() now returns the number of bytes collected (less or equal than requested) or an error code. - Allow more code re-use. - PIV driver now uses ASN.1 parser for reading the random bytes --- src/libopensc/card-authentic.c | 37 +++++++------------ src/libopensc/card-cac.c | 38 +++++--------------- src/libopensc/card-coolkey.c | 39 +++++--------------- src/libopensc/card-dnie.c | 54 ++++++++-------------------- src/libopensc/card-epass2003.c | 40 +++++++++------------ src/libopensc/card-isoApplet.c | 8 ++--- src/libopensc/card-muscle.c | 8 +++-- src/libopensc/card-openpgp.c | 5 +-- src/libopensc/card-piv.c | 65 ++++++++++++++-------------------- src/libopensc/card-rutoken.c | 38 ++++++++------------ src/libopensc/card.c | 28 ++++++++++++--- src/libopensc/iasecc-sm.c | 27 +------------- src/libopensc/iso7816.c | 20 ++++------- src/minidriver/minidriver.c | 2 +- src/tools/opensc-explorer.c | 3 +- 15 files changed, 149 insertions(+), 263 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 45e8632b01..9ef4b05c63 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1664,40 +1664,27 @@ authentic_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) } -/* 'GET CHALLENGE' returns always 24 bytes */ static int authentic_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len) { - struct sc_context *ctx = card->ctx; - struct sc_apdu apdu; + /* 'GET CHALLENGE' returns always 24 bytes */ unsigned char rbuf[0x18]; - int rv, nn; - - LOG_FUNC_CALLED(ctx); - if (!rnd && len) - return SC_ERROR_INVALID_ARGUMENTS; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = sizeof(rbuf); + size_t out_len; + int r; - while (len > 0) { - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, rv, "PIN cmd failed"); + LOG_FUNC_CALLED(card->ctx); - if (apdu.resplen != sizeof(rbuf)) - return sc_check_sw(card, apdu.sw1, apdu.sw2); + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); - nn = len > apdu.resplen ? apdu.resplen : len; - memcpy(rnd, apdu.resp, nn); - len -= nn; - rnd += nn; + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } + memcpy(rnd, rbuf, out_len); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, out_len); } diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d8762b032b..b509136ecc 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -849,42 +849,22 @@ static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int cac_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { + /* CAC requires 8 byte response */ u8 rbuf[8]; - u8 *rbufp = NULL; - size_t rbuflen = 0; + size_t out_len = sizeof rbuf; int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); - - r = sc_lock(card); - if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - + LOG_FUNC_CALLED(card->ctx); - /* CAC requires 8 byte response */ - while (len > 0) { - size_t n; + r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, (u8 **) &rbuf, &out_len); + LOG_TEST_RET(card->ctx, r, "Could not get challenge"); - rbufp = &rbuf[0]; - rbuflen = sizeof(rbuf); - r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, &rbufp, &rbuflen); - if (r < 0) { - sc_unlock(card); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - } - n = len > rbuflen ? rbuflen : len; - memcpy(rnd, rbufp, n); - len -= n; - rnd += n; + if (len < out_len) { + out_len = len; } + memcpy(rnd, rbuf, out_len); - r = sc_unlock(card); - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) out_len); } static int cac_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 768ff22e86..4db8446402 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1610,40 +1610,17 @@ static int coolkey_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int coolkey_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - size_t rbuflen = 0; - int r; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); - - r = sc_lock(card); - if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - - for(; len >= COOLKEY_MAX_CHUNK_SIZE; len -= COOLKEY_MAX_CHUNK_SIZE, - rnd += COOLKEY_MAX_CHUNK_SIZE) { - rbuflen = COOLKEY_MAX_CHUNK_SIZE; - r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, - 0, 0, NULL, 0, &rnd, &rbuflen, NULL, 0); - if (r != COOLKEY_MAX_CHUNK_SIZE) { - len = 0; - break; - } - } - if (len) { - r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, - 0, 0, NULL, 0, &rnd, &len, NULL, 0); - } - sc_unlock(card); + LOG_FUNC_CALLED(card->ctx); - if (r > 0) { - r= SC_SUCCESS; - } + if (len > COOLKEY_MAX_CHUNK_SIZE) + len = COOLKEY_MAX_CHUNK_SIZE; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_TEST_RET(card->ctx, + coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, 0, 0, + NULL, 0, &rnd, &len, NULL, 0), + "Could not get challenge"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) len); } static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 6ba0eba5be..cefe078893 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1340,51 +1340,27 @@ static int dnie_select_file(struct sc_card *card, * @param len requested challenge length * @return SC_SUCCESS if OK; else error code */ -#define BUFFER_SIZE 8 static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len) { - sc_apdu_t apdu; - u8 buf[MAX_RESP_BUFFER_SIZE]; - int result = SC_SUCCESS; - if ((card == NULL) || (card->ctx == NULL)) - return SC_ERROR_INVALID_ARGUMENTS; + /* As DNIe cannot handle other data length than 0x08 and 0x14 */ + u8 rbuf[8]; + size_t out_len; + int r; + LOG_FUNC_CALLED(card->ctx); - /* just a copy of iso7816::get_challenge() but call dnie_check_sw to - * look for extra error codes */ - if ( (rnd==NULL) || (len==0) ) { - /* no valid buffer provided */ - result = SC_ERROR_INVALID_ARGUMENTS; - goto dnie_get_challenge_error; - } - dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00, BUFFER_SIZE, 0, - buf, MAX_RESP_BUFFER_SIZE, NULL, 0); - /* - * As DNIe cannot handle other data length than 0x08 and 0x14, - * perform consecutive reads of 8 bytes until retrieve requested length - */ - while (len > 0) { - size_t n = len > BUFFER_SIZE ? BUFFER_SIZE : len; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = BUFFER_SIZE; - apdu.resp = buf; - apdu.resplen = MAX_RESP_BUFFER_SIZE; /* include SW's */ - result = sc_transmit_apdu(card, &apdu); - if (result != SC_SUCCESS) { - LOG_TEST_RET(card->ctx, result, "APDU transmit failed"); - } - if (apdu.resplen != BUFFER_SIZE) { - result = sc_check_sw(card, apdu.sw1, apdu.sw2); - goto dnie_get_challenge_error; - } - memcpy(rnd, apdu.resp, n); - len -= n; - rnd += n; + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } - result = SC_SUCCESS; - dnie_get_challenge_error: - LOG_FUNC_RETURN(card->ctx, result); + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); } /* diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 4de750bf76..4594e366a5 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -2573,34 +2573,26 @@ get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char return r; } - static int -epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t count) +static int +epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - sc_apdu_t apdu; u8 rbuf[16]; - size_t n; - int ret = SC_SUCCESS; /* if count == 0 */ + size_t out_len; + int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = sizeof(rbuf); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); + LOG_FUNC_CALLED(card->ctx); - while (count > 0) - { - ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); - ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Get challenge failed"); - if (apdu.resplen != sizeof(rbuf)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN); - n = count < sizeof(rbuf) ? count : sizeof(rbuf); - memcpy(rnd, rbuf, n); - count -= n; - rnd += n; - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; + } + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); } diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 1ef35e2e4e..c323d92263 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1211,17 +1211,17 @@ isoApplet_compute_signature(struct sc_card *card, static int isoApplet_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { - struct sc_context *ctx = card->ctx; int r; - LOG_FUNC_CALLED(ctx); + LOG_FUNC_CALLED(card->ctx); - if(card->caps & SC_CARD_CAP_RNG) { + if(card->caps & SC_CARD_CAP_RNG) { r = iso_ops->get_challenge(card, rnd, len); } else { r = SC_ERROR_NOT_SUPPORTED; } - LOG_FUNC_RETURN(ctx, r); + + LOG_FUNC_RETURN(card->ctx, r); } static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 9aa6766f5c..fd148e3039 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -775,8 +775,12 @@ static int muscle_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { if (len == 0) return SC_SUCCESS; - else - return msc_get_challenge(card, len, 0, NULL, rnd); + else { + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + msc_get_challenge(card, len, 0, NULL, rnd), + "GET CHALLENGE cmd failed"); + return (int) len; + } } static int muscle_check_sw(sc_card_t * card, unsigned int sw1, unsigned int sw2) { diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 1f903231f9..fe6e6e6356 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1222,16 +1222,17 @@ pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) static int pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { - struct pgp_priv_data *priv = DRVDATA(card); + struct pgp_priv_data *priv; LOG_FUNC_CALLED(card->ctx); + priv = DRVDATA(card); if (0 == (priv->ext_caps & EXT_CAP_GET_CHALLENGE)) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } if (priv->max_challenge_size > 0 && len > priv->max_challenge_size) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); + len = priv->max_challenge_size; } LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len)); diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 722315bf15..8525eedea7 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2229,54 +2229,41 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - u8 sbuf[16]; + /* Dynamic Authentication Template (Challenge) */ + u8 sbuf[] = {0x7c, 0x02, 0x81, 0x00}; u8 *rbuf = NULL; - size_t rbuflen = 0; - u8 *p, *q; + const u8 *p; + size_t rbuf_len = 0, out_len = 0; int r; + unsigned int tag, cla; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - sc_log(card->ctx, "challenge len=%"SC_FORMAT_LEN_SIZE_T"u", len); + LOG_FUNC_CALLED(card->ctx); - r = sc_lock(card); - if (r != SC_SUCCESS) - LOG_FUNC_RETURN(card->ctx, r); + /* NIST 800-73-3 says use 9B, previous verisons used 00 */ + r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); + LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed"); - p = sbuf; - *p++ = 0x7c; - *p++ = 0x02; - *p++ = 0x81; - *p++ = 0x00; + p = rbuf; + r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len); + if (r < 0 || (cla|tag) != 0x7C) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template"); + } - /* assuming 8 byte response ? */ - /* should take what the card returns */ - while (len > 0) { - size_t n = len > 8 ? 8 : len; + rbuf_len = out_len; + r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len); + if (r < 0 || (cla|tag) != 0x81) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge"); + } - /* NIST 800-73-3 says use 9B, previous versions used 00 */ - r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, p - sbuf, &rbuf, &rbuflen); - if (r < 0) { - sc_unlock(card); - LOG_FUNC_RETURN(card->ctx, r); - } - q = rbuf; - if ( (*q++ != 0x7C) - || (*q++ != rbuflen - 2) - || (*q++ != 0x81) - || (*q++ != rbuflen - 4)) { - r = SC_ERROR_INVALID_DATA; - sc_unlock(card); - LOG_FUNC_RETURN(card->ctx, r); - } - memcpy(rnd, q, n); - len -= n; - rnd += n; - free(rbuf); - rbuf = NULL; + if (len < out_len) { + out_len = len; } + memcpy(rnd, p, out_len); + + r = (int) out_len; - r = sc_unlock(card); +err: + free(rbuf); LOG_FUNC_RETURN(card->ctx, r); diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 86f8e03409..6658a3606e 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -1137,33 +1137,25 @@ static int rutoken_compute_signature(struct sc_card *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); } -static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t count) +static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { - sc_apdu_t apdu; - u8 rbuf[32]; - size_t n; - int ret = SC_SUCCESS; /* if count == 0 */ + unsigned char rbuf[32]; + size_t out_len; + int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = sizeof(rbuf); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); + LOG_FUNC_CALLED(card->ctx); - while (count > 0) - { - ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); - ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Get challenge failed"); - if (apdu.resplen != sizeof(rbuf)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN); - n = count < sizeof(rbuf) ? count : sizeof(rbuf); - memcpy(rnd, rbuf, n); - count -= n; - rnd += n; + r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, out_len); } static int rutoken_get_serial(sc_card_t *card, sc_serial_number_t *serial) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 724e73b882..5968b0bd74 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -805,16 +805,36 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { int r; - if (card == NULL) { + if (len == 0) + return SC_SUCCESS; + + if (card == NULL || rnd == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } + LOG_FUNC_CALLED(card->ctx); - if (card->ops->get_challenge == NULL) + if (card->ops == NULL || card->ops->get_challenge == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->get_challenge(card, rnd, len); - LOG_FUNC_RETURN(card->ctx, r); + r = sc_lock(card); + if (r != SC_SUCCESS) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + + while (len > 0) { + r = card->ops->get_challenge(card, rnd, len); + if (r < 0) { + sc_unlock(card); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + } + + rnd += (size_t) r; + len -= (size_t) r; + } + + sc_unlock(card); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int sc_read_record(sc_card_t *card, unsigned int rec_nr, u8 *buf, diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index eed7c59bdb..4587065035 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -260,31 +260,6 @@ iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num) LOG_FUNC_RETURN(ctx, rv); } - - -static int -iasecc_sm_get_challenge(struct sc_card *card, unsigned char *out, size_t len) -{ - struct sc_context *ctx = card->ctx; - struct sc_apdu apdu; - unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE]; - int rv; - - sc_log(ctx, "SM get challenge: length %"SC_FORMAT_LEN_SIZE_T"u", len); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0, 0); - apdu.le = len; - apdu.resplen = len; - apdu.resp = rbuf; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, rv, "Command failed"); - - memcpy(out, rbuf, apdu.resplen); - - LOG_FUNC_RETURN(ctx, apdu.resplen); -} #endif @@ -309,7 +284,7 @@ iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd) rv = iasecc_sm_se_mutual_authentication(card, se_num); LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() MUTUAL AUTHENTICATION failed"); - rv = iasecc_sm_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN); + rv = sc_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN); LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() GET CHALLENGE failed"); sc_remote_data_init(&rdata); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 1e889ad4e1..ba0680eed6 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -621,12 +621,6 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) int r; struct sc_apdu apdu; - if (len == 0) - return SC_SUCCESS; - - if (!rnd) - return SC_ERROR_INVALID_ARGUMENTS; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00); apdu.le = len; apdu.resp = rnd; @@ -635,14 +629,14 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen != len) { - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r == SC_SUCCESS) { - r = SC_ERROR_WRONG_LENGTH; - } - } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed"); - return r; + if (len < apdu.resplen) { + return (int) len; + } + + return (int) apdu.resplen; } diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 206273fe7a..82ce198096 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -3665,7 +3665,7 @@ DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData, } rv = sc_get_challenge(vs->p15card->card, *ppbChallengeData, 8); - if (rv) { + if (rv < 0) { logprintf(pCardData, 1, "Get challenge failed: %s\n", sc_strerror(rv)); pCardData->pfnCspFree(*ppbChallengeData); *ppbChallengeData = NULL; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 298293a41a..152b6a42a0 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1609,7 +1609,8 @@ static int do_random(int argc, char **argv) count = atoi(argv[0]); if (count < 0 || (size_t) count > sizeof buffer) { - printf("Number must be in range 0..256\n"); + printf("Number must be in range 0..%"SC_FORMAT_LEN_SIZE_T"u\n", + sizeof buffer); return -1; } From cbba3b82f22fca7816c4b4c89184185fbfeaa4c5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 23 Jan 2018 14:10:26 +0100 Subject: [PATCH 0282/4321] SC-HSM: Check maximum for get_challenge --- src/libopensc/card-sc-hsm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index a609f612af..3959862f38 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -225,6 +225,19 @@ static int sc_hsm_select_file(sc_card_t *card, +static int sc_hsm_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len) +{ + LOG_FUNC_CALLED(card->ctx); + + if (len > 1024) { + len = 1024; + } + + LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len)); +} + + + static int sc_hsm_match_card(struct sc_card *card) { sc_path_t path; @@ -1703,6 +1716,7 @@ static struct sc_card_driver * sc_get_driver(void) sc_hsm_ops = *iso_drv->ops; sc_hsm_ops.match_card = sc_hsm_match_card; sc_hsm_ops.select_file = sc_hsm_select_file; + sc_hsm_ops.get_challenge = sc_hsm_get_challenge; sc_hsm_ops.read_binary = sc_hsm_read_binary; sc_hsm_ops.update_binary = sc_hsm_update_binary; sc_hsm_ops.list_files = sc_hsm_list_files; From 784435d00c4e646c16dfab2613d20b5d57af972d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 16 Feb 2018 17:57:21 +0100 Subject: [PATCH 0283/4321] starcos: check for the maximum length of GET RANDOM Some cards only support fetching 8 bytes and less --- src/libopensc/card-starcos.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 14a8289eff..3be53dd151 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -792,6 +792,17 @@ static int starcos_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } +static int starcos_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len) +{ + LOG_FUNC_CALLED(card->ctx); + + if (len > 8) { + len = 8; + } + + LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len)); +} + #define STARCOS_AC_ALWAYS 0x9f #define STARCOS_AC_NEVER 0x5f #define STARCOS_PINID2STATE(a) ((((a) & 0x0f) == 0x01) ? ((a) & 0x0f) : (0x0f - ((0x0f & (a)) >> 1))) @@ -1848,6 +1859,7 @@ static struct sc_card_driver * sc_get_driver(void) starcos_ops.init = starcos_init; starcos_ops.finish = starcos_finish; starcos_ops.select_file = starcos_select_file; + starcos_ops.get_challenge = starcos_get_challenge; starcos_ops.check_sw = starcos_check_sw; starcos_ops.create_file = starcos_create_file; starcos_ops.delete_file = NULL; From 19df418fb63a6cc179725c39e2b38737f2aa315f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Apr 2018 14:52:36 +0200 Subject: [PATCH 0284/4321] fixed usage of get_challenge --- src/libopensc/cwa14890.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index acf5238e41..873af56450 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1291,7 +1291,7 @@ int cwa_create_secure_channel(sc_card_t * card, /* get challenge: retrieve 8 random bytes from card */ sc_log(ctx, "Step 8.4.1.11: Prepare External Auth: Get Challenge"); - res = card->ops->get_challenge(card, sm->icc.rnd, sizeof(sm->icc.rnd)); + res = sc_get_challenge(card, sm->icc.rnd, sizeof(sm->icc.rnd)); if (res != SC_SUCCESS) { msg = "Get Challenge failed"; goto csc_end; From 20b1d829b9ebe0fa28357843ac407026c4b39747 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Fri, 13 Apr 2018 15:04:41 +0200 Subject: [PATCH 0285/4321] Always allocate resp buffer in DNIe. --- src/libopensc/card-dnie.c | 20 ++++++++++++++------ src/libopensc/cwa14890.c | 8 +++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index cefe078893..542e461099 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -760,15 +760,23 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card, if ((*sm_apdu) != plain) { rv = cwa_decode_response(card, provider, *sm_apdu); - if (plain) { - plain->resplen = (*sm_apdu)->resplen; + if (plain && rv == SC_SUCCESS) { + if (plain->resp) { + /* copy the response into the original resp buffer */ + if ((*sm_apdu)->resplen <= plain->resplen) { + memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen); + plain->resplen = (*sm_apdu)->resplen; + } else { + sc_log(card->ctx, "Invalid initial length, needed %lu bytes but has %lu", + (*sm_apdu)->resplen, plain->resplen); + rv = SC_ERROR_BUFFER_TOO_SMALL; + } + } plain->sw1 = (*sm_apdu)->sw1; plain->sw2 = (*sm_apdu)->sw2; - if (((*sm_apdu)->data) != plain->data) - free((unsigned char *) (*sm_apdu)->data); - if ((*sm_apdu)->resp != plain->resp) - free((*sm_apdu)->resp); } + free((unsigned char *) (*sm_apdu)->data); + free((*sm_apdu)->resp); free(*sm_apdu); } *sm_apdu = NULL; diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 873af56450..a8b0664db8 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1431,11 +1431,9 @@ int cwa_encode_apdu(sc_card_t * card, sizeof(u8)); ccbuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen), sizeof(u8)); - if (!to->resp) { - /* if no response create a buffer for the encoded response */ - to->resp = calloc(MAX_RESP_BUFFER_SIZE, sizeof(u8)); - to->resplen = MAX_RESP_BUFFER_SIZE; - } + /* always create a new buffer for the encoded response */ + to->resp = calloc(MAX_RESP_BUFFER_SIZE, sizeof(u8)); + to->resplen = MAX_RESP_BUFFER_SIZE; if (!apdubuf || !ccbuf || (!from->resp && !to->resp)) { res = SC_ERROR_OUT_OF_MEMORY; goto err; From 1aa85671db0321d56bdfcd1681769325339dcf3b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 May 2018 22:26:39 +0200 Subject: [PATCH 0286/4321] added missing files to distribution fixes https://github.com/OpenSC/OpenSC/issues/1368 --- src/ui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 5a29358f20..ec9e149db9 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak noinst_LTLIBRARIES = libstrings.la libnotify.la -noinst_HEADERS = strings.h notify.h wchar_from_char_str.h +noinst_HEADERS = strings.h notify.h wchar_from_char_str.h char_str_from_wchar.h invisible_window.h AM_CPPFLAGS = -I$(top_srcdir)/src AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) From 5985bf13ee443740a70f7667fea2125a7a25afe3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 May 2018 22:31:32 +0200 Subject: [PATCH 0287/4321] ignore more files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 638da86e45..2e106fa3f5 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ tags *.obj *.exp *.res +*.ggo ChangeLog doc/tools/cardos-tool @@ -102,6 +103,10 @@ src/tools/pkcs11-tool src/tools/dnie-tool src/tools/npa-tool src/tools/sceac-example +src/tools/opensc-notify +src/tools/org.opensc.notify.desktop +src/tools/opensc-asn1 +src/tools/egk-tool win32/OpenSC.iss win32/OpenSC.wxs From 42833b612904f4bb763491269ac425167131b0b9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 24 May 2018 13:51:12 +0200 Subject: [PATCH 0288/4321] added more missing files fixes https://github.com/OpenSC/OpenSC/issues/1368 --- src/tools/Makefile.am | 2 +- win32/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index d83a7b56dd..6c99257316 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -27,7 +27,7 @@ OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc.notify.desktop.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc.notify.desktop.in exe.manifest noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example diff --git a/win32/Makefile.am b/win32/Makefile.am index 6248cfe9b3..61c31f4411 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo.rc $(srcdir)/ $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs $(srcdir)/OpenSC.ico \ $(srcdir)/dlgbmp.bmp $(srcdir)/bannrbmp.bmp $(srcdir)/versioninfo-customactions.rc EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak \ - versioninfo.rc.in winconfig.h.in OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc.in + versioninfo.rc.in winconfig.h.in OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc.in DDORes.dll_14_2302.ico dist_noinst_HEADERS = versioninfo.rc winconfig.h OpenSC.iss OpenSC.wxs OpenSC.ico dlgbmp.bmp bannrbmp.bmp if ENABLE_MINIDRIVER_SETUP_CUSTOMACTION From 0352f298cc2b66f74ddb199e2f306beb400420ee Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 15:23:33 +0200 Subject: [PATCH 0289/4321] npa-tool: fix typo in option parsing --- src/tools/npa-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 8b10d81abe..1371c6963e 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -443,7 +443,7 @@ main (int argc, char **argv) if (cmdline.cvc_dir_given) EAC_set_cvc_default_dir(cmdline.cvc_dir_arg); if (cmdline.x509_dir_given) - EAC_set_x509_default_dir(cmdline.cvc_dir_arg); + EAC_set_x509_default_dir(cmdline.x509_dir_arg); if (cmdline.break_flag) { /* The biggest number sprintf could write with "%llu is 18446744073709551615 */ From d70c140d7a1a355d4b50e7905bd13df60fd2fd62 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 22:44:38 +0200 Subject: [PATCH 0290/4321] opensc-notify: fix typo --- src/tools/opensc-notify-cmdline.c | 2 +- src/tools/opensc-notify.ggo.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index 1f87513421..96f2b373c0 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -40,7 +40,7 @@ const char *gengetopt_args_info_help[] = { " -m, --message[=STRING] Main text of the notification", "\n Mode: standard\n Manually send standard notifications.", " -I, --notify-card-inserted See notify_card_inserted in opensc.conf\n (default=off)", - " -R, --notify-card-removed See notify_card_inserted in opensc.conf\n (default=off)", + " -R, --notify-card-removed See notify_card_removed in opensc.conf\n (default=off)", " -G, --notify-pin-good See notify_pin_good in opensc.conf (default=off)", " -B, --notify-pin-bad See notify_pin_bad in opensc.conf (default=off)", "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", diff --git a/src/tools/opensc-notify.ggo.in b/src/tools/opensc-notify.ggo.in index f419835aae..765f8aa353 100644 --- a/src/tools/opensc-notify.ggo.in +++ b/src/tools/opensc-notify.ggo.in @@ -27,7 +27,7 @@ modeoption "notify-card-inserted" I flag off mode="standard" modeoption "notify-card-removed" R - "See notify_card_inserted in opensc.conf" + "See notify_card_removed in opensc.conf" flag off mode="standard" modeoption "notify-pin-good" G From 4d0e74094745fc92b94c360063287af23c30261a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 May 2018 22:30:53 +0200 Subject: [PATCH 0291/4321] card-npa: Use EF.DIR for card recognition This is also done in the official AusweisApp2 and avoids confusion with other tokens that also have an EF.CardAccess and are capable of verifying the PIN via PACE. Fixes https://github.com/OpenSC/OpenSC/issues/1360 --- src/libopensc/card-npa.c | 87 +++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 51 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 59dea7523f..47644ca0c2 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -65,22 +65,6 @@ static void npa_drv_data_free(struct npa_drv_data *drv_data) } } -static struct sc_atr_table npa_atrs[] = { - {"3B:8A:80:01:80:31:F8:73:F7:41:E0:82:90:00:75", - "FF:FF:FF:FF:FF:FF:00:FF:00:00:FF:FF:FF:FF:00", - NULL, SC_CARD_TYPE_NPA, 0, NULL}, - {"3B:88:80:01:00:00:00:00:00:00:00:00:09", NULL, - NULL, SC_CARD_TYPE_NPA, 0, NULL}, - {"3B:87:80:01:80:31:B8:73:84:01:E0:19", NULL, - NULL, SC_CARD_TYPE_NPA, 0, NULL}, - {"3B:84:80:01:00:00:90:00:95", NULL, - "German ID card (Test neuer Personalausweis)", SC_CARD_TYPE_NPA_TEST, 0, NULL}, - {"3B:88:80:01:00:E1:F3:5E:13:77:83:00:00", - "FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:FF:00", - "German ID card (Test Online-Ausweisfunktion)", SC_CARD_TYPE_NPA_ONLINE, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL} -}; - static struct sc_card_operations npa_ops; static struct sc_card_driver npa_drv = { "German ID card (neuer Personalausweis, nPA)", @@ -150,29 +134,43 @@ static int npa_load_options(sc_context_t *ctx, struct npa_drv_data *drv_data) static int npa_match_card(sc_card_t * card) { int r = 0; - unsigned char *ef_cardaccess = NULL; - size_t ef_cardaccess_len = 0; - r = _sc_match_atr(card, npa_atrs, &card->type); - if (r >= 0) { - if (NULL == card->name) { - card->name = npa_atrs[r].name; + if (0 == r && SC_SUCCESS == sc_enum_apps(card)) { + unsigned char esign_aid_0[] = { + 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, + }, esign_aid_1[] = { + 0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01, + }, esign_aid_2[] = { + 0xe8, 0x07, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x02, + }, esign_aid_3[] = { + 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, + }; + int i, found_0 = 0, found_1 = 0, found_2 = 0, found_3 = 0; + for (i = 0; i < card->app_count; i++) { + struct sc_app_info *app_info = card->app[i]; + if (sizeof esign_aid_0 == app_info->aid.len + && 0 == memcmp(esign_aid_0, app_info->aid.value, + sizeof esign_aid_0)) + found_0 = 1; + if (sizeof esign_aid_1 == app_info->aid.len + && 0 == memcmp(esign_aid_1, app_info->aid.value, + sizeof esign_aid_1)) + found_1 = 1; + if (sizeof esign_aid_2 == app_info->aid.len + && 0 == memcmp(esign_aid_2, app_info->aid.value, + sizeof esign_aid_2)) + found_2 = 1; + if (sizeof esign_aid_3 == app_info->aid.len + && 0 == memcmp(esign_aid_3, app_info->aid.value, + sizeof esign_aid_3)) + found_3 = 1; + } + if (found_0 && found_1 && found_2 && found_3) { + card->type = SC_CARD_TYPE_NPA; + r = 1; } - r = 1; - } else { - r = 0; - } - - if (0 == r - && SC_SUCCESS == iso7816_read_binary_sfid( - card, SFID_EF_CARDACCESS, - &ef_cardaccess, &ef_cardaccess_len)) { - card->type = SC_CARD_TYPE_NPA; - r = 1; } - free(ef_cardaccess); - return r; } @@ -317,7 +315,7 @@ static int npa_unlock_esign(sc_card_t *card) eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA; eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA; - /* FIXME show an alert to the user if can == NULL */ + /* FIXME show an alert to the user if CAN is NULL */ r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); if (SC_SUCCESS != r) { sc_log(card->ctx, "Error verifying CAN.\n"); @@ -403,21 +401,8 @@ static int npa_init(sc_card_t * card) /* unlock the eSign application for reading the certificates * by the PKCS#15 layer (i.e. sc_pkcs15_bind_internal) */ - if (SC_SUCCESS == sc_enum_apps(card)) { - unsigned char esign_aid[] = { - 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, - }; - int i; - for (i = 0; i < card->app_count; i++) { - struct sc_app_info *app_info = card->app[i]; - if (sizeof esign_aid == app_info->aid.len - && 0 == memcmp(esign_aid, app_info->aid.value, sizeof esign_aid)) { - if (SC_SUCCESS != npa_unlock_esign(card)) { - sc_log(card->ctx, "Probably not all functionality will be available.\n"); - } - break; - } - } + if (SC_SUCCESS != npa_unlock_esign(card)) { + sc_log(card->ctx, "Probably not all functionality will be available.\n"); } err: From c725c9c2e7db48dc5c31627dc2ecf6b5afc7a1f4 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 17 Oct 2015 18:58:29 +0200 Subject: [PATCH 0292/4321] OpenPGP: 1st go at better parsing of hist_bytes Use hist_bytes from already parsed ATR in reader->atr_info.hist_bytes instead of the raw ATR from card->atr --- src/libopensc/card-openpgp.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fe6e6e6356..f7fefd1c44 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -505,24 +505,26 @@ static int pgp_get_card_features(sc_card_t *card) { struct pgp_priv_data *priv = DRVDATA(card); - unsigned char *hist_bytes = card->atr.value; - size_t atr_len = card->atr.len; + u8 *hist_bytes = card->reader->atr_info.hist_bytes; + size_t hist_bytes_len = card->reader->atr_info.hist_bytes_len; size_t i; pgp_blob_t *blob, *blob6e, *blob73; - /* parse card capabilities from historical bytes */ - for (i = 0; (i < atr_len) && (hist_bytes[i] != 0x73); i++) - ; - /* IS07816-4 hist bytes 3rd function table */ - if ((hist_bytes[i] == 0x73) && (atr_len > i+3)) { - /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ - if (hist_bytes[i+3] & 0x40) { - card->caps |= SC_CARD_CAP_APDU_EXT; - priv->ext_caps |= EXT_CAP_APDU_EXT; + if (hist_bytes_len > 0) { + /* parse card capabilities from historical bytes */ + for (i = 0; (i < hist_bytes_len) && (hist_bytes[i] != 0x73); i++) + ; + /* IS07816-4 hist bytes 3rd function table */ + if ((hist_bytes[i] == 0x73) && (hist_bytes_len > i+3)) { + /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ + if (hist_bytes[i+3] & 0x40) { + card->caps |= SC_CARD_CAP_APDU_EXT; + priv->ext_caps |= EXT_CAP_APDU_EXT; + } + /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ + if (hist_bytes[i+3] & 0x80) + priv->ext_caps |= EXT_CAP_CHAINING; } - /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ - if (hist_bytes[i+3] & 0x80) - priv->ext_caps |= EXT_CAP_CHAINING; } if (priv->bcd_version >= OPENPGP_CARD_2_0) { From 3e3e4784766543b51887ba0d9c7f143f15cdb8cc Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 22 Apr 2018 14:38:23 +0200 Subject: [PATCH 0293/4321] OpenPGP: correctly parse hist_bytes Instead of simply searching for a trigger byte with the risk of getting garbage, correctly parse historical bytes from ATR as well as the "historical bytes" DO as compact TLV structures. In addition - prepare for additional data used in OpenPGP cards 3.x - ignore [per the spec] chaining capability fo OpenPGP cards 1.x --- src/libopensc/card-openpgp.c | 75 +++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f7fefd1c44..e5b71eab21 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -497,6 +497,41 @@ pgp_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +/** + * Internal: get features of the card: capabilities, ... + */ +static void +pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) +{ + struct pgp_priv_data *priv = DRVDATA(card); + size_t offs; + + for (offs = 0; offs < ctlv_len; offs++) { + switch (ctlv[offs]) { + case 0x73: /* IS07816-4 hist bytes 3rd function table */ + if (offs+3 < ctlv_len) { + /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ + if (ctlv[offs+3] & 0x40) { + card->caps |= SC_CARD_CAP_APDU_EXT; + priv->ext_caps |= EXT_CAP_APDU_EXT; + } + /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ + if ((ctlv[offs+3] & 0x40) && + (priv->bcd_version >= OPENPGP_CARD_3_0)) { + priv->ext_caps |= EXT_CAP_CHAINING; + } + } + break; + case 0x31: + if ((offs + 1 < ctlv_len) && + (priv->bcd_version >= OPENPGP_CARD_3_0)) { + // ToDo ... + } + break; + } + offs += ctlv[offs] & 0x0F; + } +} /** * Internal: get features of the card: capabilities, ... @@ -510,20 +545,19 @@ pgp_get_card_features(sc_card_t *card) size_t i; pgp_blob_t *blob, *blob6e, *blob73; + /* parse card capabilities from historical bytes in ATR */ if (hist_bytes_len > 0) { - /* parse card capabilities from historical bytes */ - for (i = 0; (i < hist_bytes_len) && (hist_bytes[i] != 0x73); i++) - ; - /* IS07816-4 hist bytes 3rd function table */ - if ((hist_bytes[i] == 0x73) && (hist_bytes_len > i+3)) { - /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ - if (hist_bytes[i+3] & 0x40) { - card->caps |= SC_CARD_CAP_APDU_EXT; - priv->ext_caps |= EXT_CAP_APDU_EXT; - } - /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ - if (hist_bytes[i+3] & 0x80) - priv->ext_caps |= EXT_CAP_CHAINING; + /* category indicator 0x00, 0x10 or 0x80 => compact TLV (ISO) */ + switch (hist_bytes[0]) { + case 0x00: + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + break; + case 0x80: + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-1); + break; + case 0x10: + pgp_parse_hist_bytes(card, hist_bytes+2, hist_bytes_len-2); + break; } } @@ -532,20 +566,7 @@ pgp_get_card_features(sc_card_t *card) if ((pgp_get_blob(card, priv->mf, 0x5f52, &blob) >= 0) && (blob->data != NULL) && (blob->data[0] == 0x00)) { - /* find beginning of "interesting" bytes */ - for (i = 0; (i < blob->len) && (blob->data[i] != 0x73); i++) - ; - /* IS07816-4 hist bytes 3rd function table */ - if ((blob->data[i] == 0x73) && (blob->len > i+3)) { - /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ - if (blob->data[i+3] & 0x40) { - card->caps |= SC_CARD_CAP_APDU_EXT; - priv->ext_caps |= EXT_CAP_APDU_EXT; - } - /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ - if (blob->data[i+3] & 0x80) - priv->ext_caps |= EXT_CAP_CHAINING; - } + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); /* get card status from historical bytes status indicator */ if ((blob->data[0] == 0x00) && (blob->len >= 4)) From 8d503df7541474e118339459fcb14e86cdd9e372 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 22 Apr 2018 15:11:56 +0200 Subject: [PATCH 0294/4321] OpenPGP: add missing symbolic constants for card versions --- src/libopensc/card-openpgp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e5b71eab21..95096ab66c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -85,8 +85,11 @@ enum _version { /* 2-byte BCD-alike encoded version number */ OPENPGP_CARD_1_1 = 0x0101, OPENPGP_CARD_2_0 = 0x0200, OPENPGP_CARD_2_1 = 0x0201, + OPENPGP_CARD_2_2 = 0x0202, OPENPGP_CARD_3_0 = 0x0300, OPENPGP_CARD_3_1 = 0x0301, + OPENPGP_CARD_3_2 = 0x0302, + OPENPGP_CARD_3_3 = 0x0303, }; enum _access { /* access flags for the respective DO/file */ From a884953c85f30dedd9aa79360a2226741b903ac3 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 3 Jun 2018 12:26:51 +0200 Subject: [PATCH 0295/4321] card-dnie: use size_t-specific format specifier in printf Instead ogf blindly using "%lu", use "%"SC_FORMAT_LEN_SIZE_T"u" to cope with the various implementations. This fixes a bug introduced in commit 20b1d829 --- src/libopensc/card-dnie.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 542e461099..3701fc3732 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -767,7 +767,9 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card, memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen); plain->resplen = (*sm_apdu)->resplen; } else { - sc_log(card->ctx, "Invalid initial length, needed %lu bytes but has %lu", + sc_log(card->ctx, "Invalid initial length," + " needed %"SC_FORMAT_LEN_SIZE_T"u bytes" + " but has %"SC_FORMAT_LEN_SIZE_T"u", (*sm_apdu)->resplen, plain->resplen); rv = SC_ERROR_BUFFER_TOO_SMALL; } From ad6b46ea45dbdd6f1696339df19be5eaafc7c84c Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 20:44:44 +0200 Subject: [PATCH 0296/4321] doc/tools: add DocBook sources for new tools * egk-tool.1.xml * npa-tool.1.xml * opensc-asn1.1.xml * opensc-notify.1.xml --- doc/tools/egk-tool.1.xml | 115 +++++++++ doc/tools/npa-tool.1.xml | 440 ++++++++++++++++++++++++++++++++++ doc/tools/opensc-asn1.1.xml | 64 +++++ doc/tools/opensc-notify.1.xml | 136 +++++++++++ 4 files changed, 755 insertions(+) create mode 100644 doc/tools/egk-tool.1.xml create mode 100644 doc/tools/npa-tool.1.xml create mode 100644 doc/tools/opensc-asn1.1.xml create mode 100644 doc/tools/opensc-notify.1.xml diff --git a/doc/tools/egk-tool.1.xml b/doc/tools/egk-tool.1.xml new file mode 100644 index 0000000000..df6a9cb6e1 --- /dev/null +++ b/doc/tools/egk-tool.1.xml @@ -0,0 +1,115 @@ + + + + egk-tool + 1 + OpenSC + OpenSC Tools + opensc + + + + egk-tool + displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) + + + + + + egk-tool + OPTIONS + + + + + Description + + The egk-tool utility is used to display information stored on the German elektronic health card (elektronische Gesundheitskarte, eGK). + + + + + Options + + + + + , + + Print help and exit. + + + + , + + Print version and exit. + + + + arg, + arg + + + Specify the reader to use. + Use -1 as arg + to automatically detect the reader to use. + By default, the first reader with a present card is used. + + + + + , + + + + Causes egk-tool to be more verbose. + Specify this flag several times to be more verbose. + + + + + + + Health Care Application (<abbrev>HCA</abbrev>) + + + + + Show 'Persönliche Versicherungsdaten' (XML). + + + + + + Show 'Allgemeine Versicherungsdaten' (XML). + + + + + + Show 'Geschützte Versicherungsdaten' (XML). + + + + + + Show 'Versichertenstammdaten-Status'. + + + + + + + + Authors + egk-tool was written by + Frank Morgner frankmorgner@gmail.com. + + + + diff --git a/doc/tools/npa-tool.1.xml b/doc/tools/npa-tool.1.xml new file mode 100644 index 0000000000..a3b419b81e --- /dev/null +++ b/doc/tools/npa-tool.1.xml @@ -0,0 +1,440 @@ + + + + npa-tool + 1 + OpenSC + OpenSC Tools + opensc + + + + npa-tool + displays information on the German eID card (neuer Personalausweis, nPA). + + + + + + npa-tool + OPTIONS + + + + + Description + + The npa-tool utility is used to display information + stored on the German eID card (neuer Personalausweis, nPA), + and to perform some write and verification operations. + + + + + Options + + + + + , + + Print help and exit. + + + + , + + Print version and exit. + + + + arg, + arg + + + Specify the reader to use. + Use -1 as arg + to automatically detect the reader to use. + By default, the first reader with a present card is used. + + + + + , + + + + Causes npa-tool to be more verbose. + Specify this flag several times to be more verbose. + + + + + + + Password Authenticated Connection Establishment (<abbrev>PACE</abbrev>) + + + + STRING, + STRING + + + Run PACE with (transport) eID-PIN. + + + + + STRING, + STRING + + + Run PACE with PUK. + + + + + STRING, + STRING + + + Run PACE with Card Access Number (CAN). + + + + + STRING, + STRING + + + Run PACE with Machine Readable Zone (MRZ). + Enter the MRZ without newlines. + + + + + + Specify whether to use environment variables PIN, + PUK, CAN, MRZ, + and NEWPIN. + You may want to clean your environment before enabling this. + (default=off) + + + + + + + PIN management + + + + STRING, + STRING + + + Install a new PIN. + + + + + , + + + + Resume eID-PIN (uses CAN to activate last retry). + (default=off) + + + + + , + + + + Unblock PIN (uses PUK to activate three more retries). + (default=off) + + + + + + + Terminal Authentication (<abbrev>TA</abbrev>) and Chip Authentication (<abbrev>CA</abbrev>) + + + + FILENAME, + FILENAME + + + Specify Card Verifiable (CV) certificate + to create a certificate chain. + The option can be given multiple times, in which case the + order is important. + + + + HEX_STRING + + Certificate description to show for Terminal Authentication. + + + + HEX_STRING + + Specify the Card Holder Authorization Template + (CHAT) to use. + If not given, it defaults to the terminal's CHAT. + Use 7F4C0E060904007F000703010203530103 + to trigger EAC on the CAT-C (Komfortleser). + + + + + HEX_STRING, + HEX_STRING + + + Specify the terminal's auxiliary data. + If not given, the default is determined by verification + of validity, age and community ID. + + + + + FILENAME, + FILENAME + + + Specify the terminal's private key. + + + + DIRECTORY + + Specify where to look for the certificate of the + Country Verifying Certification Authority + (CVCA). + If not given, it defaults to + /home/fm/.local/etc/eac/cvc. + + + + + DIRECTORY + + Specify where to look for the X.509 certificate. + If not given, it defaults to + /home/fm/.local/etc/eac/x509. + + + + + + Disable checking the validity period of CV certificates. + (default=off) + + + + + + Disable passive authentication. (default=off) + + + + + + + Read and write data groups + + + + Read data group 1: Document Type. + + + + Read data group 2: Issuing State. + + + + Read data group 3: Date of Expiry. + + + + Read data group 4: Given Name(s). + + + + Read data group 5: Family Name. + + + + Read data group 6: Religious/Artistic Name. + + + + Read data group 7: Academic Title. + + + + Read data group 8: Date of Birth. + + + + Read data group 9: Place of Birth. + + + + Read data group 10: Nationality. + + + + Read data group 11: Sex. + + + + Read data group 12: Optional Data. + + + + Read data group 13: Birth Name. + + + + Read data group 14. + + + + Read data group 15. + + + + Read data group 16. + + + + Read data group 17: Normal Place of Residence. + + + + Read data group 18: Community ID. + + + + Read data group 19: Residence Permit I. + + + + Read data group 20: Residence Permit II. + + + + Read data group 21: Optional Data. + + + + HEX_STRING + Write data group 17: Normal Place of Residence. + + + + HEX_STRING + Write data group 18: Community ID. + + + + HEX_STRING + Write data group 19: Residence Permit I. + + + + HEX_STRING + Write data group 20: Residence Permit II. + + + HEX_STRING + Write data group 21: Optional Data. + + + + + + Verification of validity, age and community ID + + + YYYYMMDD + + Verify chip's validity with a reference date. + + + + YYYYMMDD + + Verify age with a reference date. + + + + HEX_STRING + + Verify community ID with a reference ID. + + + + + + + Special options, not always useful + + + + , + + + + Brute force PIN, CAN or PUK. + Use together with options , + , or . + (default=off) + + + + + FILENAME, + FILENAME + + + Specify the file with APDUs of HEX_STRINGs to send + through the secure channel. + (default=`stdin') + + + + + + Force compliance to BSI TR-03110 version 2.01. (default=off) + + + + + + Disable all checking of fly-by-data. (default=off) + + + + + + + + Authors + npa-tool was written by + Frank Morgner frankmorgner@gmail.com. + + + + diff --git a/doc/tools/opensc-asn1.1.xml b/doc/tools/opensc-asn1.1.xml new file mode 100644 index 0000000000..a2f1bca7ae --- /dev/null +++ b/doc/tools/opensc-asn1.1.xml @@ -0,0 +1,64 @@ + + + + opensc-asn1 + 1 + OpenSC + OpenSC Tools + opensc + + + + opensc-asn1 + parse ASN.1 data + + + + + + opensc-asn1 + OPTIONS + FILES + + + + + Description + + The opensc-asn1 utility is used to parse ASN.1 data. + + + + + Options + + + + + , + + Print help and exit. + + + + , + + Print version and exit. + + + + + + + Authors + opensc-asn1 was written by + Frank Morgner frankmorgner@gmail.com. + + + + diff --git a/doc/tools/opensc-notify.1.xml b/doc/tools/opensc-notify.1.xml new file mode 100644 index 0000000000..ec01651a99 --- /dev/null +++ b/doc/tools/opensc-notify.1.xml @@ -0,0 +1,136 @@ + + + + opensc-notify + 1 + OpenSC + OpenSC Tools + opensc + + + + opensc-notify + monitor smart card events and send notifications + + + + + + opensc-notify + OPTIONS + + + + + Description + + The opensc-notify utility is used to + monitor smart card events and send the appropriate notification. + + + + + Options + + + + + , + + Print help and exit. + + + + , + + Print version and exit. + + + + + + Mode: customized + + Send customized notifications. + + + + + STRING, + STRING + + + Specify the title of the notification. + + + + + STRING, + STRING + + + Specify the main text of the notification. + + + + + + + Mode: standard + + Manually send standard notifications. + + + + + , + + + See notify_card_inserted + in opensc.conf (default=off). + + + + + , + + + See notify_card_removed + in opensc.conf (default=off). + + + + + , + + + See notify_pin_good + in opensc.conf (default=off). + + + + + , + + + See notify_pin_bad + in opensc.conf (default=off). + + + + + + + + Authors + opensc-notify was written by + Frank Morgner frankmorgner@gmail.com. + + + + From 98c9a1588b605c7cbb7d6ea859b1558dbb57dff8 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 20:58:50 +0200 Subject: [PATCH 0297/4321] doc/tools/tools.xml: sort, remove duplicates, add new tools --- doc/tools/tools.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml index 34b993fb89..c405910a63 100644 --- a/doc/tools/tools.xml +++ b/doc/tools/tools.xml @@ -11,15 +11,17 @@ + - - + - + + + From 5a3134556bda1e866bb4cb510d0e73975847b8a7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 21:05:55 +0200 Subject: [PATCH 0298/4321] doc/tools: slight markup improvements * get rid of hard-coded markup like e.g. { ... | ... } or [ ... ] in favour of DocBook's proper tags * use tags better matching the purpose, e.g. use instead of for directories * improve consistency in s --- doc/tools/cardos-tool.1.xml | 4 +- doc/tools/dnie-tool.1.xml | 4 +- doc/tools/iasecc-tool.1.xml | 2 +- doc/tools/netkey-tool.1.xml | 21 ++++-- doc/tools/opensc-explorer.1.xml | 122 ++++++++++++++++++++++++-------- doc/tools/opensc-tool.1.xml | 5 +- doc/tools/pkcs15-profile.5.xml | 4 +- 7 files changed, 118 insertions(+), 44 deletions(-) diff --git a/doc/tools/cardos-tool.1.xml b/doc/tools/cardos-tool.1.xml index 626571108b..12b49a9c00 100644 --- a/doc/tools/cardos-tool.1.xml +++ b/doc/tools/cardos-tool.1.xml @@ -56,8 +56,8 @@ smart cards and similar security tokens based on Siemens Card/OS M4.
- number, - number + num, + num diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index 2885446cc0..c7bc205125 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -83,8 +83,8 @@ - number, - number + num, + num diff --git a/doc/tools/iasecc-tool.1.xml b/doc/tools/iasecc-tool.1.xml index cc7a14b326..01f0a74692 100644 --- a/doc/tools/iasecc-tool.1.xml +++ b/doc/tools/iasecc-tool.1.xml @@ -34,7 +34,7 @@ - number, + num, diff --git a/doc/tools/netkey-tool.1.xml b/doc/tools/netkey-tool.1.xml index d5b5304b82..24badd9061 100644 --- a/doc/tools/netkey-tool.1.xml +++ b/doc/tools/netkey-tool.1.xml @@ -71,8 +71,8 @@ - number, - number + num, + num @@ -147,8 +147,14 @@ - change { pin | puk | - pin0 | pin1 } new-pin + change + + pin + puk + pin0 + pin1 + + new-pin This changes the value of the specified pin to the given new value. You must specify either the current value of the pin or another pin to be able to do @@ -167,7 +173,12 @@ - unblock { pin | pin0 | pin1 } + unblock + + pin + pin0 + pin1 + This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 662cd80aca..23b90966eb 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -106,7 +106,8 @@ - apdu hex-data + apdu + hex-data Send a custom APDU command hex-data. @@ -115,7 +116,8 @@ - asn1 file-id + asn1 + file-id Parse and print the ASN.1 encoded content of the file specified by file-id. @@ -123,7 +125,11 @@ - cat [file-id | sfi:short-id] + cat + + file-id + sfi:short-id + Print the contents of the currently selected EF or the contents of a file specified by file-id or the short file id @@ -133,13 +139,19 @@ - cd {.. | file-id | aid:DF-name} + cd + + .. + file-id + aid:DF-name + Change to another DF specified by the argument passed. - If the argument given is .., then move up one level in the - file system hierarchy. - If it is file-id, which must be a DF directly + If the argument given is .., + then move up one level in the file system hierarchy. + If it is file-id, + which must be a DF directly beneath the current DF, then change to that DF. If it is an application identifier given as aid:DF-name, @@ -150,7 +162,12 @@ - change CHVpin-ref [[old-pin] new-pin] + change + CHVpin-ref + + old-pin + new-pin + Change a PIN, where pin-ref is the PIN reference. @@ -185,7 +202,9 @@ - create file-id size + create + file-id + size Create a new EF. file-id specifies the id number and size is the size of the new file. @@ -194,7 +213,8 @@ - debug [level] + debug + level Set OpenSC debug level to level. @@ -204,14 +224,17 @@ - delete file-id + delete + file-id Remove the EF or DF specified by file-id - do_get hex-tag [output] + do_get + hex-tag + output Copy the internal card's 'tagged' data into the local file. @@ -227,7 +250,9 @@ - do_put hex-tag input + do_put + hex-tag + input Update internal card's 'tagged' data. @@ -240,7 +265,8 @@ - echo string ... + echo + string Print the strings given. @@ -256,7 +282,9 @@ - get file-id [output] + get + file-id + output Copy an EF to a local file. The local file is specified @@ -271,7 +299,8 @@ - info [file-id] + info + file-id Display attributes of a file specified by file-id. If file-id is not supplied, @@ -280,7 +309,8 @@ - ls [pattern ...] + ls + pattern List files in the current DF. If no pattern is given, then all files are listed. @@ -290,7 +320,11 @@ - find [start-id [end-id]] + find + + start-id + end-id + Find all files in the current DF. Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF). @@ -298,7 +332,11 @@ - find_tags [start-tag [end-tag]] + find_tags + + start-tag + end-tag + Find all tags of data objects in the current context. Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF). @@ -306,7 +344,9 @@ - mkdir file-id size + mkdir + file-id + size Create a DF. file-id specifies the id number and size is the size of the new file. @@ -314,7 +354,9 @@ - put file-id input + put + file-id + input Copy a local file to the card. The local file is specified by input while the card file is specified by file-id. @@ -330,7 +372,8 @@ - random count + random + count Generate random sequence of count bytes. @@ -339,20 +382,26 @@ - rm file-id + rm + file-id Remove the EF or DF specified by file-id - unblock CHVpin-ref [puk [new pin]] + unblock + CHVpin-ref + + puk + new-pin + Unblock the PIN denoted by pin-ref using the PUK puk, and set potentially - change its value to new pin. + change its value to new-pin. PUK and PIN values can be a sequence of hexadecimal values, @@ -414,7 +463,10 @@ - update_binary file-id offs data + update_binary + file-id + offs + data Binary update of the file specified by @@ -428,7 +480,11 @@ - update_record file-id rec-nr rec-offs data + update_record + file-id + rec-nr + rec-offs + data Update record specified by rec-nr of the file @@ -442,7 +498,9 @@ - verify key-type key-id [key] + verify + key-typekey-id + key Present a PIN or key to the card, where key-type can be one of CHV, @@ -489,10 +547,14 @@ - sm [open]|[close] + sm + + open + close + - Calls the card's open or close Secure Messaging handler. + Calls the card's open or close Secure Messaging handler. diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index 7399096e94..d92c022e3c 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -126,10 +126,11 @@ - [=type], + type, Resets the card in reader. - The default reset type is cold, but warm reset is also possible. + The default reset type is cold, + but warm reset is also possible. diff --git a/doc/tools/pkcs15-profile.5.xml b/doc/tools/pkcs15-profile.5.xml index 85f939ca7c..cf555ec0c8 100644 --- a/doc/tools/pkcs15-profile.5.xml +++ b/doc/tools/pkcs15-profile.5.xml @@ -27,12 +27,12 @@ layout, such as the path of the application DF, various PKCS #15 files within that directory, and the access conditions on these files. It also defines general information about PIN, key and certificate objects. Currently, there - is only one such generic profile, pkcs15.profile. + is only one such generic profile, pkcs15.profile. The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. - Profiles currently reside in @pkgdatadir@ + Profiles currently reside in @pkgdatadir@ From 59412aeee3f2d467deed6f478799a34e851d0e70 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 26 May 2018 22:41:54 +0200 Subject: [PATCH 0299/4321] src/tools: stop building man pages here (see doc/tools) They have been moved to doc/tools and are generated there. --- src/tools/Makefile.am | 44 ------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 6c99257316..2bdc2e391a 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -39,10 +39,6 @@ bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool endif -if ENABLE_MAN -dist_man1_MANS = npa-tool.1 opensc-notify.1 egk-tool.1 opensc-asn1.1 -endif - # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src @@ -105,16 +101,6 @@ $(NPA_TOOL_BUILT_SOURCES): $(abs_builddir)/npa-tool.ggo: npa-tool.ggo.in $(do_subst) < $(abs_srcdir)/npa-tool.ggo.in > $@ -# We only want npa-tool.1 to be generated when it has explicitly been removed. -npa-tool.1: - $(MAKE) npa-tool$(EXEEXT) - $(HELP2MAN) \ - --output=$@ \ - --no-info \ - --locale=$(HELP2MAN_LOCALE) \ - --source='$(PACKAGE_STRING)' \ - $(builddir)/npa-tool$(EXEEXT) - opensc_notify_SOURCES = opensc-notify.c $(OPENSC_NOTIFY_BUILT_SOURCES) opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) opensc_notify_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_NOTIFY_CFLAGS) @@ -133,16 +119,6 @@ $(OPENSC_NOTIFY_BUILT_SOURCES): $(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in $(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@ -# We only want opensc-notify.1 to be generated when it has explicitly been removed. -opensc-notify.1: - $(MAKE) opensc-notify$(EXEEXT) - $(HELP2MAN) \ - --output=$@ \ - --no-info \ - --locale=$(HELP2MAN_LOCALE) \ - --source='$(PACKAGE_STRING)' \ - $(builddir)/opensc-notify$(EXEEXT) - egk_tool_SOURCES = egk-tool.c $(EGK_TOOL_BUILT_SOURCES) egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) @@ -161,16 +137,6 @@ $(EGK_TOOL_BUILT_SOURCES): $(abs_builddir)/egk-tool.ggo: egk-tool.ggo.in $(do_subst) < $(abs_srcdir)/egk-tool.ggo.in > $@ -# We only want egk-tool.1 to be generated when it has explicitly been removed. -egk-tool.1: - $(MAKE) egk-tool$(EXEEXT) - $(HELP2MAN) \ - --output=$@ \ - --no-info \ - --locale=$(HELP2MAN_LOCALE) \ - --source='$(PACKAGE_STRING)' \ - $(builddir)/egk-tool$(EXEEXT) - opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c $(OPENSC_ASN1_BUILT_SOURCES) opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) opensc_asn1_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) @@ -186,16 +152,6 @@ $(OPENSC_ASN1_BUILT_SOURCES): $(abs_builddir)/opensc-asn1.ggo: opensc-asn1.ggo.in $(do_subst) < $(abs_srcdir)/opensc-asn1.ggo.in > $@ -# We only want opensc-asn1.1 to be generated when it has explicitly been removed. -opensc-asn1.1: - $(MAKE) opensc-asn1$(EXEEXT) - $(HELP2MAN) \ - --output=$@ \ - --no-info \ - --locale=$(HELP2MAN_LOCALE) \ - --source='$(PACKAGE_STRING)' \ - $(builddir)/opensc-asn1$(EXEEXT) - if WIN32 opensc_tool_SOURCES += versioninfo-tools.rc piv_tool_SOURCES += versioninfo-tools.rc From dbe2fcef2cd31fd8c1a23cf985c00689277c8125 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 27 May 2018 14:04:28 +0200 Subject: [PATCH 0300/4321] test-manpages.sh: make more robust & more easily readable Call the tools to be tested with option '--help' to avoid triggering automatic actions when no option is given. Exampleswhy the old behaviour is bad: - opensc-notify: blocks the build - opensc-explorer: tries to open the card --- doc/tools/test-manpage.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/tools/test-manpage.sh b/doc/tools/test-manpage.sh index 8fdb091372..be12d0f28d 100755 --- a/doc/tools/test-manpage.sh +++ b/doc/tools/test-manpage.sh @@ -6,7 +6,11 @@ TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0- ALL=1 for T in $TOOLS; do - SWITCHES=`${SOURCE_PATH}/src/tools/${T} 2>&1 | awk '{if (match($0,"--[a-zA-Z0-9-]*",a) != 0) print a[0]} {if (match($0," -[a-zA-Z0-9]",a) != 0) print a[0]}'` + SWITCHES=$( ${SOURCE_PATH}/src/tools/${T} --help 2>&1 \ + | grep -v "unrecognized option '--help'" \ + | awk '{if (match($0,"--[a-zA-Z0-9-]*",a) != 0) print a[0]} + {if (match($0," -[a-zA-Z0-9]",a) != 0) print a[0]}' ) + for S in $SWITCHES; do grep -q -- "$S" ${SOURCE_PATH}/doc/tools/${T}.1.xml || { echo "${T}: missing switch $S"; ALL=0; }; done From 85468868fb0f609d088f5ae40c5260911d0ecbb8 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 27 May 2018 17:49:01 +0200 Subject: [PATCH 0301/4321] man pages: add missing options to make test-manpage.sh happy --- doc/tools/cardos-tool.1.xml | 21 +++++++++++++++++++++ doc/tools/westcos-tool.1.xml | 1 + 2 files changed, 22 insertions(+) diff --git a/doc/tools/cardos-tool.1.xml b/doc/tools/cardos-tool.1.xml index 12b49a9c00..5f461414ae 100644 --- a/doc/tools/cardos-tool.1.xml +++ b/doc/tools/cardos-tool.1.xml @@ -47,6 +47,13 @@ smart cards and similar security tokens based on Siemens Card/OS M4. Format the card or token. + + + , + + + Print help message on screen. + , @@ -68,6 +75,20 @@ smart cards and similar security tokens based on Siemens Card/OS M4. + + + arg, + arg + + Specify startkey for format. + + + + arg, + arg + + Change Startkey with given APDU command. + , diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index f671d8ce35..3ddf3827fb 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -172,6 +172,7 @@ + Causes westcos-tool to be more From 184bc137cdd40fe444bf163c06e8f6d710773fcf Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Thu, 31 May 2018 10:32:19 +0200 Subject: [PATCH 0302/4321] OpenPGP: extend & sort man page Also try to consolidate the coding style a bit --- doc/tools/openpgp-tool.1.xml | 135 ++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 51 deletions(-) diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index 380cac6bcc..ca59b89ca7 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -40,114 +40,148 @@ - prog, - prog + arg - Execute the given program with data in environment variables. + Delete key indicated by arg. + arg can be 1, + 2, 3, or + all. - , - + arg, + arg - Print help message on screen. + Dump private data object (DO) + indicated by arg. + arg can be in the form + x, + 10x, or + 010x + to access DO 010x, + where x is 1, + 2, 3, or + 4. - + , + - Print values in raw format, as they are stored on the card. + Erase (i.e. reset) the card. - + prog, + prog - Print values in pretty format. + Execute the given program with data in environment variables. - , - + arg, + arg - Show card holder information. + Generate key with the ID given as arg. + arg can be one of 1, + 2, or 3. - num, - num + , + - - - Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. - - + + Print help message on screen. + - pintype + bitlength, + bitlength - - - Verify PIN (CHV1, CHV2 or CHV3). - - + + Specify the length of the key to be generated. + If not given, it defaults to 2048 bit. + string - - + The PIN text to verify. If set to env:VARIABLE, the value of the environment variable VARIABLE is used. - - + - ID, - ID + - - - Generate key. Specify key ID (1, 2 or 3) to generate. - - + + Print values in pretty format. + - bitlength, - bitlength + - - - Length (default 2048 bit) of the key to be generated. - - + + Print values in raw format, as they are stored on the card. + + + + + + num, + num + + + Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. + + + + + + , + + + + Show card holder information. + + + + + + pintype + + + Verify PIN (CHV1, CHV2 or CHV3). + @@ -156,7 +190,7 @@ - Print the version of the utility and exit. + Print the version of the utility and exit. @@ -166,7 +200,7 @@ - Verbose operation. Use several times to enable debug output. + Verbose operation. Use several times to enable debug output. @@ -176,10 +210,9 @@ - Wait for a card to be inserted. + Wait for a card to be inserted. - From cedc5a1cf65f41717150ec041467c651c7d004d9 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 18:20:25 +0200 Subject: [PATCH 0303/4321] configure.ac: remove references to help2man Now that we have proper DocBook sources for all man pages formerly generated using help2man, it is not needed anymore. --- configure.ac | 3 --- 1 file changed, 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8e8a2cff5d..32d064b38a 100644 --- a/configure.ac +++ b/configure.ac @@ -898,9 +898,6 @@ if test "${enable_man}" = "yes" -o "${enable_doc}" = "yes"; then AC_MSG_RESULT([ok]) fi -AC_ARG_VAR([HELP2MAN], - [absolute path to help2man used for man page generation of npa-tool]) -AC_PATH_PROG(HELP2MAN, help2man, not found) AC_ARG_VAR([GENGETOPT], [absolute path to gengetopt used for command line parsing of npa-tool]) AC_PATH_PROG(GENGETOPT, gengetopt, not found) From a27ade778917599f8e1daa20833a7c5662f4a665 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 18:22:48 +0200 Subject: [PATCH 0304/4321] .travis.yml: remove references to help2man Now that we have proper DocBook sources for all man pages formerly generated using help2man, it is not needed anymore. --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8974368feb..26e3db8d19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ addons: - wine - xsltproc - gengetopt - - help2man - libcmocka-dev env: @@ -51,7 +50,7 @@ before_install: brew update; brew uninstall libtool; brew install libtool; - brew install gengetopt help2man cmocka; + brew install gengetopt cmocka; fi before_script: From 008845efb305e1c23e5c2b5137e54e21168bb950 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 18:41:46 +0200 Subject: [PATCH 0305/4321] src/tools: remove legacy man pages generated using help2man Now that we have proper DocBook sources for them, they can be safely removed. --- src/tools/egk-tool.1 | 39 -------- src/tools/npa-tool.1 | 205 -------------------------------------- src/tools/opensc-asn1.1 | 21 ---- src/tools/opensc-notify.1 | 45 --------- 4 files changed, 310 deletions(-) delete mode 100644 src/tools/egk-tool.1 delete mode 100644 src/tools/npa-tool.1 delete mode 100644 src/tools/opensc-asn1.1 delete mode 100644 src/tools/opensc-notify.1 diff --git a/src/tools/egk-tool.1 b/src/tools/egk-tool.1 deleted file mode 100644 index 1718093a33..0000000000 --- a/src/tools/egk-tool.1 +++ /dev/null @@ -1,39 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH EGK-TOOL "1" "May 2018" "OpenSC 0.18.0" "User Commands" -.SH NAME -egk-tool \- manual page for egk-tool 0.18.0 -.SH SYNOPSIS -.B egk-tool -[\fI\,OPTIONS\/\fR]... -.SH DESCRIPTION -egk\-tool 0.18.0 -.TP -\fB\-h\fR, \fB\-\-help\fR -Print help and exit -.TP -\fB\-V\fR, \fB\-\-version\fR -Print version and exit -.TP -\fB\-r\fR, \fB\-\-reader\fR=\fI\,INT\/\fR -Number of the PC/SC reader to use (\fB\-1\fR for autodetect) -(default=`\-1') -.TP -\fB\-v\fR, \fB\-\-verbose\fR -Use (several times) to be more verbose -.SS "Health Care Application (HCA):" -.TP -\fB\-\-pd\fR -Show 'Persönliche Versicherungsdaten' (XML) (default=off) -.TP -\fB\-\-vd\fR -Show 'Allgemeine Versicherungsdaten' (XML) (default=off) -.TP -\fB\-\-gvd\fR -Show 'Geschützte Versicherungsdaten' (XML) (default=off) -.TP -\fB\-\-vsd\-status\fR -Show 'Versichertenstammdaten\-Status' (default=off) -.SH AUTHOR -Written by Frank Morgner -.SH "REPORTING BUGS" -Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/npa-tool.1 b/src/tools/npa-tool.1 deleted file mode 100644 index a9704ab24a..0000000000 --- a/src/tools/npa-tool.1 +++ /dev/null @@ -1,205 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH NPA-TOOL "1" "May 2018" "OpenSC 0.18.0" "User Commands" -.SH NAME -npa-tool \- manual page for npa-tool 0.18.0 -.SH SYNOPSIS -.B npa-tool -[\fI\,OPTIONS\/\fR]... -.SH DESCRIPTION -npa\-tool 0.18.0 -.TP -\fB\-h\fR, \fB\-\-help\fR -Print help and exit -.TP -\fB\-V\fR, \fB\-\-version\fR -Print version and exit -.TP -\fB\-r\fR, \fB\-\-reader\fR=\fI\,INT\/\fR -Number of the PC/SC reader to use (\fB\-1\fR for -autodetect) (default=`\-1') -.TP -\fB\-v\fR, \fB\-\-verbose\fR -Use (several times) to be more verbose -.SS "Password Authenticated Connection Establishment (PACE):" -.TP -\fB\-p\fR, \fB\-\-pin\fR[=\fI\,STRING\/\fR] -Run PACE with (transport) eID\-PIN -.TP -\fB\-u\fR, \fB\-\-puk\fR[=\fI\,STRING\/\fR] -Run PACE with PUK -.TP -\fB\-c\fR, \fB\-\-can\fR[=\fI\,STRING\/\fR] -Run PACE with CAN -.TP -\fB\-m\fR, \fB\-\-mrz\fR[=\fI\,STRING\/\fR] -Run PACE with MRZ (insert MRZ without newlines) -.TP -\fB\-\-env\fR -Whether to use environment variables PIN, PUK, -CAN, MRZ and NEWPIN. You may want to clean -your environment before enabling this. -(default=off) -.SS "PIN management:" -.TP -\fB\-N\fR, \fB\-\-new\-pin\fR[=\fI\,STRING\/\fR] -Install a new PIN -.TP -\fB\-R\fR, \fB\-\-resume\fR -Resume eID\-PIN (uses CAN to activate last -retry) (default=off) -.TP -\fB\-U\fR, \fB\-\-unblock\fR -Unblock PIN (uses PUK to activate three more -retries) (default=off) -.SS "Terminal Authentication (TA) and Chip Authentication (CA):" -.TP -\fB\-C\fR, \fB\-\-cv\-certificate\fR=\fI\,FILENAME\/\fR Card Verifiable Certificate to create a -certificate chain. Can be used multiple times -(order is important). -.TP -\fB\-\-cert\-desc\fR=\fI\,HEX_STRING\/\fR -Certificate description to show for Terminal -Authentication -.TP -\fB\-\-chat\fR=\fI\,HEX_STRING\/\fR -Card holder authorization template to use -(default is terminal's CHAT). Use -7F4C0E060904007F000703010203530103 to trigger -EAC on the CAT\-C (Komfortleser). -.TP -\fB\-A\fR, \fB\-\-auxiliary\-data\fR=\fI\,HEX_STRING\/\fR -Terminal's auxiliary data (default is -.TP -determined by verification of validity, age -and community ID). -.TP -\fB\-P\fR, \fB\-\-private\-key\fR=\fI\,FILENAME\/\fR -Terminal's private key -.TP -\fB\-\-cvc\-dir\fR=\fI\,DIRECTORY\/\fR -Where to look for the CVCA's certificate -(default=`/home/fm/.local/etc/eac/cvc') -.TP -\fB\-\-x509\-dir\fR=\fI\,DIRECTORY\/\fR -Where to look for the CSCA's certificate -(default=`/home/fm/.local/etc/eac/x509') -.TP -\fB\-\-disable\-ta\-checks\fR -Disable checking the validity period of CV -certificates (default=off) -.TP -\fB\-\-disable\-ca\-checks\fR -Disable passive authentication (default=off) -.SS "Read and write data groups:" -.TP -\fB\-\-read\-dg1\fR -Read DG 1 (Document Type) (default=off) -.TP -\fB\-\-read\-dg2\fR -Read DG 2 (Issuing State) (default=off) -.TP -\fB\-\-read\-dg3\fR -Read DG 3 (Date of Expiry) (default=off) -.TP -\fB\-\-read\-dg4\fR -Read DG 4 (Given Names) (default=off) -.TP -\fB\-\-read\-dg5\fR -Read DG 5 (Family Names) (default=off) -.TP -\fB\-\-read\-dg6\fR -Read DG 6 (Religious/Artistic Name) -(default=off) -.TP -\fB\-\-read\-dg7\fR -Read DG 7 (Academic Title) (default=off) -.TP -\fB\-\-read\-dg8\fR -Read DG 8 (Date of Birth) (default=off) -.TP -\fB\-\-read\-dg9\fR -Read DG 9 (Place of Birth) (default=off) -.TP -\fB\-\-read\-dg10\fR -Read DG 10 (Nationality) (default=off) -.TP -\fB\-\-read\-dg11\fR -Read DG 11 (Sex) (default=off) -.TP -\fB\-\-read\-dg12\fR -Read DG 12 (Optional Data) (default=off) -.TP -\fB\-\-read\-dg13\fR -Read DG 13 (Birth Name) (default=off) -.TP -\fB\-\-read\-dg14\fR -Read DG 14 (default=off) -.TP -\fB\-\-read\-dg15\fR -Read DG 15 (default=off) -.TP -\fB\-\-read\-dg16\fR -Read DG 16 (default=off) -.TP -\fB\-\-read\-dg17\fR -Read DG 17 (Normal Place of Residence) -(default=off) -.TP -\fB\-\-read\-dg18\fR -Read DG 18 (Community ID) (default=off) -.TP -\fB\-\-read\-dg19\fR -Read DG 19 (Residence Permit I) (default=off) -.TP -\fB\-\-read\-dg20\fR -Read DG 20 (Residence Permit II) -(default=off) -.TP -\fB\-\-read\-dg21\fR -Read DG 21 (Optional Data) (default=off) -.TP -\fB\-\-write\-dg17\fR=\fI\,HEX_STRING\/\fR -Write DG 17 (Normal Place of Residence) -.TP -\fB\-\-write\-dg18\fR=\fI\,HEX_STRING\/\fR -Write DG 18 (Community ID) -.TP -\fB\-\-write\-dg19\fR=\fI\,HEX_STRING\/\fR -Write DG 19 (Residence Permit I) -.TP -\fB\-\-write\-dg20\fR=\fI\,HEX_STRING\/\fR -Write DG 20 (Residence Permit II) -.TP -\fB\-\-write\-dg21\fR=\fI\,HEX_STRING\/\fR -Write DG 21 (Optional Data) -.SS "Verification of validity, age and community ID:" -.TP -\fB\-\-verify\-validity\fR=\fI\,YYYYMMDD\/\fR -Verify chip's validity with a reference date -.TP -\fB\-\-older\-than\fR=\fI\,YYYYMMDD\/\fR -Verify age with a reference date -.TP -\fB\-\-verify\-community\fR=\fI\,HEX_STRING\/\fR -Verify community ID with a reference ID -.SS "Special options, not always useful:" -.TP -\fB\-b\fR, \fB\-\-break\fR -Brute force PIN, CAN or PUK. Use together with -\fB\-p\fR, \fB\-a\fR or \fB\-u\fR (default=off) -.TP -\fB\-t\fR, \fB\-\-translate\fR=\fI\,FILENAME\/\fR -File with APDUs of HEX_STRINGs to send through -the secure channel (default=`stdin') -.TP -\fB\-\-tr\-03110v201\fR -Force compliance to BSI TR\-03110 version 2.01 -(default=off) -.TP -\fB\-\-disable\-all\-checks\fR -Disable all checking of fly\-by\-data -(default=off) -.SH AUTHOR -Written by Frank Morgner -.SH "REPORTING BUGS" -Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/opensc-asn1.1 b/src/tools/opensc-asn1.1 deleted file mode 100644 index a12f6f8a5a..0000000000 --- a/src/tools/opensc-asn1.1 +++ /dev/null @@ -1,21 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH OPENSC-ASN1 "1" "May 2018" "OpenSC 0.18.0" "User Commands" -.SH NAME -opensc-asn1 \- manual page for opensc-asn1 0.18.0 -.SH SYNOPSIS -.B opensc-asn1 -[\fI\,OPTIONS\/\fR]... [\fI\,FILES\/\fR]... -.SH DESCRIPTION -opensc\-asn1 0.18.0 -.PP -Parse ASN.1 data. -.TP -\fB\-h\fR, \fB\-\-help\fR -Print help and exit -.TP -\fB\-V\fR, \fB\-\-version\fR -Print version and exit -.SH AUTHOR -Written by Frank Morgner -.SH "REPORTING BUGS" -Report bugs to https://github.com/OpenSC/OpenSC/issues diff --git a/src/tools/opensc-notify.1 b/src/tools/opensc-notify.1 deleted file mode 100644 index 7628c030c9..0000000000 --- a/src/tools/opensc-notify.1 +++ /dev/null @@ -1,45 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH OPENSC-NOTIFY "1" "May 2018" "OpenSC 0.18.0" "User Commands" -.SH NAME -opensc-notify \- manual page for opensc-notify 0.18.0 -.SH SYNOPSIS -.B opensc-notify -[\fI\,OPTIONS\/\fR]... -.SH DESCRIPTION -opensc\-notify 0.18.0 -.PP -If no arguments are given, monitor smart card events and send the appropriate -notification. -.TP -\fB\-h\fR, \fB\-\-help\fR -Print help and exit -.TP -\fB\-V\fR, \fB\-\-version\fR -Print version and exit -.IP -Mode: customized -.IP -Send customized notifications. -\fB\-t\fR, \fB\-\-title\fR[=\fI\,STRING\/\fR] Title of the notification -\fB\-m\fR, \fB\-\-message\fR[=\fI\,STRING\/\fR] Main text of the notification -.IP -Mode: standard -.IP -Manually send standard notifications. -\fB\-I\fR, \fB\-\-notify\-card\-inserted\fR See notify_card_inserted in opensc.conf -.IP -(default=off) -.TP -\fB\-R\fR, \fB\-\-notify\-card\-removed\fR -See notify_card_inserted in opensc.conf -(default=off) -.TP -\fB\-G\fR, \fB\-\-notify\-pin\-good\fR -See notify_pin_good in opensc.conf (default=off) -.TP -\fB\-B\fR, \fB\-\-notify\-pin\-bad\fR -See notify_pin_bad in opensc.conf (default=off) -.SH AUTHOR -Written by Frank Morgner -.SH "REPORTING BUGS" -Report bugs to https://github.com/OpenSC/OpenSC/issues From c16903140da440bc57340d57ab1ba6162f42f0b2 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 19:18:49 +0200 Subject: [PATCH 0306/4321] src/tools: remove deleted man pages from Makefile.am's EXTRA_DIST --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 2bdc2e391a..261752f62f 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -27,7 +27,7 @@ OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in egk-tool.ggo.in egk-tool.1 opensc-asn1.ggo.in opensc-asn1.1 org.opensc.notify.desktop.in exe.manifest +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example From ff9df386654609150bcd4c249edfa592438d41b4 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 20:44:39 +0200 Subject: [PATCH 0307/4321] src/tools: remove HELP2MAN_LOCALE from Makefile.am --- src/tools/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 261752f62f..378bab3c3b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -19,8 +19,6 @@ do_subst = $(SED) \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' -HELP2MAN_LOCALE ?= C.UTF-8 - EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c From 76725d5f80a06dd63b189e20559c5d885abcb41d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 1 Jun 2018 21:11:02 +0200 Subject: [PATCH 0308/4321] .travis.yml: partially revert commit cb3113a --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 26e3db8d19..6e37c32133 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ before_install: brew update; brew uninstall libtool; brew install libtool; - brew install gengetopt cmocka; + brew install gengetopt help2man cmocka; fi before_script: From f2042f22705df2d55c468525ba651e20950154f9 Mon Sep 17 00:00:00 2001 From: Laurent Bigonville Date: Tue, 5 Jun 2018 16:29:05 +0200 Subject: [PATCH 0309/4321] Do not display opensc-notify in the application list opensc-notify doesn't propose a GUI that can be displayed to the users, so it doesn't make sense to display it in the application list/launcher Fixes: #1379 --- src/tools/org.opensc.notify.desktop.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/org.opensc.notify.desktop.in b/src/tools/org.opensc.notify.desktop.in index fbb22e3866..3f9a1dd103 100644 --- a/src/tools/org.opensc.notify.desktop.in +++ b/src/tools/org.opensc.notify.desktop.in @@ -5,3 +5,4 @@ Comment=Monitor smart card events to send notifications. Exec=@bindir@/opensc-notify Icon=preferences-system-notifications Categories=Security;System; +NoDisplay=true From 6dfeb9959ffd98f0cd044fa98ad3f29d676cd293 Mon Sep 17 00:00:00 2001 From: asc Date: Fri, 1 Jun 2018 19:05:56 +0200 Subject: [PATCH 0310/4321] Fix #1371 introduced by 45ad44e --- src/tools/sc-hsm-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 823eb2176d..3802eeea96 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1524,7 +1524,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p } if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) - || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) + || ((cla & SC_ASN1_TAG_CONSTRUCTED) == SC_ASN1_TAG_CONSTRUCTED) || (tag != SC_ASN1_TAG_OCTET_STRING) ){ fprintf(stderr, "Invalid wrapped key format (Key binary).\n"); return -1; From 266b811e55e0e3877c897f4ecd65a1fee12e786d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 8 Jun 2018 08:17:13 +0200 Subject: [PATCH 0311/4321] compact TLV - add generic sc_compacttlv_find_tag() function (#1374) * new function sc_compacttlv_find_tag() Add function sc_compacttlv_find_tag() to search for a tag in a compact-TLV structure. * OpenPGP: use sc_compacttlv_find_tag() While doing so, fix a typo affection OpenPGP v3.x cards --- src/libopensc/card-openpgp.c | 43 +++++++++++++++--------------------- src/libopensc/opensc.h | 12 ++++++++++ src/libopensc/sc.c | 20 +++++++++++++++++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 95096ab66c..cf0f272b42 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -507,32 +507,25 @@ static void pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) { struct pgp_priv_data *priv = DRVDATA(card); - size_t offs; - - for (offs = 0; offs < ctlv_len; offs++) { - switch (ctlv[offs]) { - case 0x73: /* IS07816-4 hist bytes 3rd function table */ - if (offs+3 < ctlv_len) { - /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ - if (ctlv[offs+3] & 0x40) { - card->caps |= SC_CARD_CAP_APDU_EXT; - priv->ext_caps |= EXT_CAP_APDU_EXT; - } - /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ - if ((ctlv[offs+3] & 0x40) && - (priv->bcd_version >= OPENPGP_CARD_3_0)) { - priv->ext_caps |= EXT_CAP_CHAINING; - } - } - break; - case 0x31: - if ((offs + 1 < ctlv_len) && - (priv->bcd_version >= OPENPGP_CARD_3_0)) { - // ToDo ... - } - break; + const u8 *ptr; + + /* IS07816-4 hist bytes: 3rd function table */ + if ((ptr = sc_compacttlv_find_tag(ctlv, ctlv_len, 0x73, NULL)) != NULL) { + /* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */ + if (ptr[2] & 0x40) { + card->caps |= SC_CARD_CAP_APDU_EXT; + priv->ext_caps |= EXT_CAP_APDU_EXT; } - offs += ctlv[offs] & 0x0F; + /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ + if ((ptr[2] & 0x80) && + (priv->bcd_version >= OPENPGP_CARD_3_0)) { + priv->ext_caps |= EXT_CAP_CHAINING; + } + } + + if ((priv->bcd_version >= OPENPGP_CARD_3_0) && + ((ptr = sc_compacttlv_find_tag(ctlv, ctlv_len, 0x31, NULL)) != NULL)) { + // ToDo ... } } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6262bb7515..25950ff552 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1357,6 +1357,18 @@ scconf_block *sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *drive */ unsigned sc_crc32(const unsigned char *value, size_t len); +/** + * Find a given tag in a compact TLV structure + * @param[in] buf input buffer holding the compact TLV structure + * @param[in] len length of the input buffer @buf in bytes + * @param[in] tag compact tag to search for - high nibble: plain tag, low nibble: length. + * If length is 0, only the plain tag is used for searching, + * in any other case, the length must also match. + * @param[out] outlen pointer where the size of the buffer returned is to be stored + * @return pointer to the tag value found within @buf, or NULL if not found/on error + */ +const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen); + /** * Used to initialize the @c sc_remote_data structure -- * reset the header of the 'remote APDUs' list, set the handlers diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 389a2c2d33..62e4a2ea3e 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -948,6 +948,26 @@ unsigned sc_crc32(const unsigned char *value, size_t len) return crc%0xffff; } +const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen) +{ + if (buf != NULL) { + size_t idx; + u8 plain_tag = tag & 0xF0; + size_t expected_len = tag & 0x0F; + + for (idx = 0; idx < len; idx++) { + if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len && + (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) { + if (outlen != NULL) + *outlen = buf[idx] & 0x0F; + return buf + (idx + 1); + } + idx += (buf[idx] & 0x0F); + } + } + return NULL; +} + /**************************** mutex functions ************************/ int sc_mutex_create(const sc_context_t *ctx, void **mutex) From da6e30b38ba5ca912f8a0c59fa411548e5ca914f Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 14:46:56 +0200 Subject: [PATCH 0312/4321] OpenPGP: clarify usage text --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 0d109ed234..3a4b9a8ce9 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -131,7 +131,7 @@ static const char *option_help[] = { "Verify PIN (CHV1, CHV2, CHV3...)", "PIN string", "Delete key (1, 2, 3 or all)", -/* d */ "Dump private data object number (i.e. PRIVATE-DO-)", +/* d */ "Dump private data object number (i.e. DO )", }; static const struct ef_name_map openpgp_data[] = { From 41d89b52fce6f77f34b6ece9f26649ed48697299 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 16:03:55 +0200 Subject: [PATCH 0313/4321] OpenPGP: treat option --del-key as an action --- src/tools/openpgp-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 3a4b9a8ce9..4ef592cabe 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -316,6 +316,7 @@ static int decode_options(int argc, char **argv) key_id = optarg[0] - '0'; else /* Arg string is 'all' */ key_id = 'a'; + actions++; break; case 'd': do_dump_idx = optarg[0] - '0'; From 1da7da5e996b4cbeb8c8fad79f915d0a6769c01a Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 15:43:52 +0200 Subject: [PATCH 0314/4321] OpenPGP: make parsing of option -d more robust * accept flexible option arguguments: 1-4, 101-104, 0101-0104, ... --- src/tools/openpgp-tool.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 4ef592cabe..0eee4fbf75 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -89,7 +89,7 @@ static const char *pin = NULL; static int opt_erase = 0; static int opt_delkey = 0; static int opt_dump_do = 0; -static u8 do_dump_idx; +static unsigned int do_dump_idx; static const char *app_name = "openpgp-tool"; @@ -247,6 +247,8 @@ static void display_data(const struct ef_name_map *mapping, char *value) static int decode_options(int argc, char **argv) { int c; + char *endptr; + unsigned long val; while ((c = getopt_long(argc, argv,"r:x:CUG:L:EhwvVd:", options, (int *) 0)) != EOF) { switch (c) { @@ -319,7 +321,13 @@ static int decode_options(int argc, char **argv) actions++; break; case 'd': - do_dump_idx = optarg[0] - '0'; + endptr = NULL; + val = strtoul(optarg, &endptr, 16); + if (endptr == NULL || endptr == optarg || *endptr != '\0') { + printf("Unable to parse DO identifier\n"); + return 1; + } + do_dump_idx = (unsigned int) (val | 0x100); opt_dump_do++; actions++; break; @@ -388,6 +396,11 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) unsigned char buffer[254]; memset(buffer, '\0', sizeof(buffer)); + if (tag < 0x101 || tag > 0x104) { + printf("Illegal DO identifier\n"); + return 1; + } + r = sc_get_data(card, tag, buffer, sizeof(buffer)); if (r < 0) { printf("Failed to get data object: %s\n", sc_strerror(r)); @@ -641,7 +654,7 @@ int main(int argc, char **argv) } if (opt_dump_do) { - exit_status |= do_dump_do(card, 0x0100 + do_dump_idx); + exit_status |= do_dump_do(card, do_dump_idx); } if (opt_genkey) From 85f4ba6c5f05a479acb1da74d0c283916151220d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 16:01:34 +0200 Subject: [PATCH 0315/4321] OpenPGP: allow calling -d multiple times Put the arguments passed to option -d into an array instead of only storing the latest value. During output, iterate over the values passed in via the option. --- src/tools/openpgp-tool.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 0eee4fbf75..fd75efe735 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -88,8 +88,8 @@ static int opt_pin = 0; static const char *pin = NULL; static int opt_erase = 0; static int opt_delkey = 0; -static int opt_dump_do = 0; -static unsigned int do_dump_idx; +static size_t opt_dump_do = 0; +static unsigned int do_dump_idx[200]; /* large enough and checked on input */ static const char *app_name = "openpgp-tool"; @@ -327,8 +327,10 @@ static int decode_options(int argc, char **argv) printf("Unable to parse DO identifier\n"); return 1; } - do_dump_idx = (unsigned int) (val | 0x100); - opt_dump_do++; + if (opt_dump_do < sizeof(do_dump_idx) / sizeof(*do_dump_idx)) { + do_dump_idx[opt_dump_do] = (unsigned int) (val | 0x100); + opt_dump_do++; + } actions++; break; default: @@ -654,7 +656,11 @@ int main(int argc, char **argv) } if (opt_dump_do) { - exit_status |= do_dump_do(card, do_dump_idx); + size_t n; + + for (n = 0; n < opt_dump_do; n++) { + exit_status |= do_dump_do(card, do_dump_idx[n]); + } } if (opt_genkey) From 4a1bf9fb21ed243643a7d9b9e606dd3b998a8b7b Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 20 May 2018 16:15:30 +0200 Subject: [PATCH 0316/4321] OpenPGP: limit output of -d in non-raw mode to real length --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index fd75efe735..25182350b5 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -435,7 +435,7 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) if (sizeof(buffer) != r) return EXIT_FAILURE; } else { - util_hex_dump_asc(stdout, buffer, sizeof(buffer), -1); + util_hex_dump_asc(stdout, buffer, r, -1); } return EXIT_SUCCESS; From ba9eebceaf157379d0f281b80cb5abab028693aa Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 5 Jun 2018 09:08:17 +0200 Subject: [PATCH 0317/4321] OpenPGP: refactor do_dump_do() - limit length of data to write even in raw mode to the real length - cluster variuable definitions - restrict scope of variables - introduce a variable length to make the purpose more obious - start preprocessor directives at column one - add comments where needed - harmonize coding style: space after "if" and casts --- src/tools/openpgp-tool.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 25182350b5..8a67579c88 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -391,11 +391,10 @@ static int do_userinfo(sc_card_t *card) static int do_dump_do(sc_card_t *card, unsigned int tag) { - int r, tmp; - FILE *fp; + int r; + size_t length; + unsigned char buffer[254]; // Private DO are specified up to 254 bytes - // Private DO are specified up to 254 bytes - unsigned char buffer[254]; memset(buffer, '\0', sizeof(buffer)); if (tag < 0x101 || tag > 0x104) { @@ -406,36 +405,40 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) r = sc_get_data(card, tag, buffer, sizeof(buffer)); if (r < 0) { printf("Failed to get data object: %s\n", sc_strerror(r)); - if(SC_ERROR_SECURITY_STATUS_NOT_SATISFIED == r) { + if (SC_ERROR_SECURITY_STATUS_NOT_SATISFIED == r) { printf("Make sure the 'verify' and 'pin' parameters are correct.\n"); } return r; } + length = (size_t) r; /* r is guaranteed to be non-negative */ - if(opt_raw) { - r = 0; - #ifndef _WIN32 + if (opt_raw) { + int tmp; + FILE *fp; + +#ifndef _WIN32 tmp = dup(fileno(stdout)); - #else +#else tmp = _dup(_fileno(stdout)); - #endif +#endif if (tmp < 0) return EXIT_FAILURE; fp = freopen(NULL, "wb", stdout); if (fp) { - r = (int)fwrite(buffer, sizeof(char), sizeof(buffer), fp); + r = (int) fwrite(buffer, sizeof(char), length, fp); } - #ifndef _WIN32 +#ifndef _WIN32 dup2(tmp, fileno(stdout)); - #else +#else _dup2(tmp, _fileno(stdout)); - #endif +#endif clearerr(stdout); close(tmp); - if (sizeof(buffer) != r) + + if (length != r) /* fail on write errors */ return EXIT_FAILURE; } else { - util_hex_dump_asc(stdout, buffer, r, -1); + util_hex_dump_asc(stdout, buffer, length, -1); } return EXIT_SUCCESS; From e6ad737430228f198ad30757d8d1dc4f065a6891 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 5 Jun 2018 09:43:31 +0200 Subject: [PATCH 0318/4321] OpenPGP: add cast forgotten in previous commit --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 8a67579c88..d495381e31 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -435,7 +435,7 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) clearerr(stdout); close(tmp); - if (length != r) /* fail on write errors */ + if (length != (size_t) r) /* fail on write errors */ return EXIT_FAILURE; } else { util_hex_dump_asc(stdout, buffer, length, -1); From 694822554e483cbf246d33ab5b85d9630891c254 Mon Sep 17 00:00:00 2001 From: Laurent Bigonville Date: Tue, 5 Jun 2018 16:49:10 +0200 Subject: [PATCH 0319/4321] dnie: Consider that everything not APPLE or WIN32 is "linux" This should fix the FTBFS on architectures like kfreebsd Fixes: #1366 --- src/libopensc/card-dnie.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 3701fc3732..a47b5f0d52 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -163,7 +163,7 @@ const char *user_consent_message="Esta a punto de realizar una firma digital\nco */ char *user_consent_msgs[] = { "SETTITLE", "SETDESC", "CONFIRM", "BYE" }; -#ifdef linux +#if !defined(__APPLE__) && !defined(_WIN32) /** * Do fgets() without interruptions. * @@ -203,7 +203,7 @@ int dnie_ask_user_consent(struct sc_card * card, const char *title, const char * CFStringRef header_ref; /* to store title */ CFStringRef message_ref; /* to store message */ #endif -#ifdef linux +#if !defined(__APPLE__) && !defined(_WIN32) pid_t pid; FILE *fin=NULL; FILE *fout=NULL; /* to handle pipes as streams */ @@ -271,7 +271,7 @@ int dnie_ask_user_consent(struct sc_card * card, const char *title, const char * if( result == kCFUserNotificationAlternateResponse ) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); -#elif linux +#else /* check that user_consent_app exists. TODO: check if executable */ res = stat(GET_DNIE_UI_CTX(card).user_consent_app, &st_file); if (res != 0) { @@ -361,8 +361,6 @@ int dnie_ask_user_consent(struct sc_card * card, const char *title, const char * /* close out channel to force client receive EOF and also die */ if (fout != NULL) fclose(fout); if (fin != NULL) fclose(fin); -#else -#error "Don't know how to handle user consent in this (rare) Operating System" #endif if (msg != NULL) sc_log(card->ctx, "%s", msg); From 23706635a8f4e762889f01695c0ab368fe238072 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Thu, 7 Jun 2018 06:41:53 +0200 Subject: [PATCH 0320/4321] cardos: create pin in mf If cardos cards are initialized by other software and there is a pinref without the msb set, also the pin verify works without that bit set. This patch changes pin initialisation so that the pin is created in mf which has the effect that pin verify works without | 0x80 to the pin ref. Signed-off-by: Andreas Kemnade --- src/pkcs15init/pkcs15-cardos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 924eeb6bd9..88909beea9 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -201,7 +201,7 @@ cardos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; - r = sc_select_file(card, &df->path, NULL); + r = sc_select_file(card, auth_info->attrs.pin.reference & 0x80 ? &df->path : sc_get_mf_path(), NULL); if (r < 0) return r; @@ -499,7 +499,7 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card, /* object address: class, id */ tlv_next(&tlv, 0x83); tlv_add(&tlv, 0x00); /* class byte: usage TEST, k=0 */ - tlv_add(&tlv, auth_info->attrs.pin.reference); + tlv_add(&tlv, auth_info->attrs.pin.reference & 0x7f); /* parameters */ tlv_next(&tlv, 0x85); From 89a8e0cb64e3b908d0c43868ab4b2d20bf665aaf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 5 Jun 2018 16:22:14 +0200 Subject: [PATCH 0321/4321] Avoid memory leaks from the failed card detections --- src/libopensc/card-sc-hsm.c | 2 +- src/pkcs11/slot.c | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 3959862f38..99050cf792 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1652,8 +1652,8 @@ static int sc_hsm_init(struct sc_card *card) if (file->prop_attr[1] & 0x04) { card->caps |= SC_CARD_CAP_SESSION_PIN; } - sc_file_free(file); } + sc_file_free(file); card->max_send_size = 1431; // 1439 buffer size - 8 byte TLV because of odd ins in UPDATE BINARY if (card->type == SC_CARD_TYPE_SC_HSM_SOC diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 5bfaa7eeb8..fe322e68e6 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -210,6 +210,7 @@ CK_RV card_removed(sc_reader_t * reader) CK_RV card_detect(sc_reader_t *reader) { struct sc_pkcs11_card *p11card = NULL; + int free_p11card = 0; int rc; CK_RV rv; unsigned int i; @@ -256,15 +257,17 @@ CK_RV card_detect(sc_reader_t *reader) p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card)); if (!p11card) return CKR_HOST_MEMORY; + free_p11card = 1; p11card->reader = reader; } if (p11card->card == NULL) { sc_log(context, "%s: Connecting ... ", reader->name); rc = sc_connect_card(reader, &p11card->card); - if (rc != SC_SUCCESS) { + if (rc != SC_SUCCESS) { sc_log(context, "%s: SC connect card error %i", reader->name, rc); - return sc_to_cryptoki_error(rc, NULL); + rv = sc_to_cryptoki_error(rc, NULL); + goto fail; } /* escape commands are only guaranteed to be working with a card @@ -293,8 +296,10 @@ CK_RV card_detect(sc_reader_t *reader) if (frameworks[i]->bind != NULL) break; /*TODO: only first framework is used: pkcs15init framework is not reachable here */ - if (frameworks[i] == NULL) - return CKR_GENERAL_ERROR; + if (frameworks[i] == NULL) { + rv = CKR_GENERAL_ERROR; + goto fail; + } p11card->framework = frameworks[i]; @@ -324,7 +329,7 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: cannot bind 'generic' token: rv 0x%lX", reader->name, rv); - return rv; + goto fail; } sc_log(context, "%s: Creating 'generic' token.", reader->name); @@ -333,7 +338,7 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: create 'generic' token error 0x%lX", reader->name, rv); - return rv; + goto fail; } } @@ -359,13 +364,24 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: create %s token error 0x%lX", reader->name, app_name, rv); - return rv; + goto fail; } } } sc_log(context, "%s: Detection ended", reader->name); return CKR_OK; + +fail: + if (free_p11card) { + if (p11card->card != NULL) + sc_disconnect_card(p11card->card); + if (p11card->framework) + p11card->framework->unbind(p11card); + free(p11card); + } + + return rv; } From 335c242ce0328c3c5480d299184cff5f0fc5420d Mon Sep 17 00:00:00 2001 From: asc Date: Thu, 7 Jun 2018 17:43:29 +0200 Subject: [PATCH 0322/4321] Filter certificates other than CKC_X_509 --- src/tests/p11test/p11test_case_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 0f89cbb504..deb2a56fee 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -156,6 +156,9 @@ int callback_certificates(test_certs_t *objects, const u_char *cp; test_cert_t *o = NULL; + if (*(CK_CERTIFICATE_TYPE *)template[3].pValue != CKC_X_509) + return 0; + if ((o = add_object(objects, template[0], template[2])) == NULL) return -1; From 52451ac438ef9135ac627808661a52579c8c9354 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Apr 2018 10:39:18 +0200 Subject: [PATCH 0323/4321] card-cac.c: Dump also the MSCUID --- src/libopensc/card-cac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index b509136ecc..f4e8baa3a0 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -73,6 +73,7 @@ /* TAGS in a TL file */ #define CAC_TAG_CERTIFICATE 0x70 #define CAC_TAG_CERTINFO 0x71 +#define CAC_TAG_MSCUID 0x72 #define CAC_TAG_CUID 0xF0 #define CAC_TAG_CC_VERSION_NUMBER 0xF1 #define CAC_TAG_GRAMMAR_VERION_NUMBER 0xF2 @@ -697,6 +698,9 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, cert_type = *val_ptr; } } + if (tag == CAC_TAG_MSCUID) { + sc_log_hex(card->ctx, "MSCUID", val_ptr, len); + } if ((val_len < len) || (tl_len < tl_head_len)) { break; } From 92df907681c1aa2c5a2a9a1018948cf2f15a92ca Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Apr 2018 10:57:17 +0200 Subject: [PATCH 0324/4321] Typo, clean up comments, dump more useful information from CCC --- src/libopensc/card-cac.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index f4e8baa3a0..d6eb642ab2 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1297,9 +1297,14 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, return r; break; case CAC_TAG_CC_VERSION_NUMBER: + /* ignore the version numbers for now */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG:CC Version = 0x%02x", *val); + break; case CAC_TAG_GRAMMAR_VERION_NUMBER: /* ignore the version numbers for now */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:Version"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG:Grammar Version = 0x%02x", *val); break; case CAC_TAG_CARDURL: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:CARDURL"); @@ -1311,9 +1316,10 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, * The following are really for file systems cards. This code only cares about CAC VM cards */ case CAC_TAG_PKCS15: - /* should verify that this is '0'. If it's not zero, we should drop out of here and - * let the PKCS 15 code handle this card */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:PKCS5"); + /* TODO should verify that this is '0'. If it's not + * zero, we should drop out of here and let the PKCS 15 + * code handle this card */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:PKCS15 = 0x%02x", *val); break; case CAC_TAG_DATA_MODEL: case CAC_TAG_CARD_APDU: @@ -1324,8 +1330,8 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:FSSpecific(0x%x)", tag); break; case CAC_TAG_ACCESS_CONTROL: - /* handle access control later */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:ACCESS Control"); + /* TODO handle access control later */ + sc_log_hex(card->ctx, "TAG:ACCESS Control", val, len); break; case CAC_TAG_NEXT_CCC: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:NEXT CCC"); From 5b420318d464554345910abcdc467855674fe792 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Apr 2018 10:57:43 +0200 Subject: [PATCH 0325/4321] Allocate private data outside and avoid memory leaks --- src/libopensc/card-cac.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d6eb642ab2..d135d380c2 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1485,11 +1485,6 @@ static int cac_process_ACA(sc_card_t *card, cac_private_data_t *priv) //r = cac_parse_ACA(card, priv, tl, tl_len, val, val_len); r = cac_find_first_pki_applet(card, &index); if (r == SC_SUCCESS) { - priv = cac_new_private_data(); - if (!priv) { - r = SC_ERROR_OUT_OF_MEMORY; - goto done; - } r = cac_populate_cac_1(card, index, priv); if (r == SC_SUCCESS) { priv->aca_path = malloc(sizeof(sc_path_t)); @@ -1544,6 +1539,14 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) r = cac_select_ACA(card); if (r == SC_SUCCESS) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "ACA found, is CAC-2 without CCC"); + if (!initialize) /* match card only */ + return r; + + if (!priv) { + priv = cac_new_private_data(); + if (!priv) + return SC_ERROR_OUT_OF_MEMORY; + } r = cac_process_ACA(card, priv); if (r == SC_SUCCESS) { card->type = SC_CARD_TYPE_CAC_II; From 426914674c18a98dce827a183a0f4875b6c95a91 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 27 Apr 2018 17:37:27 +0200 Subject: [PATCH 0326/4321] Unbreak encoding last tag in the data objects --- src/libopensc/card-cac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d135d380c2..b356bd0d44 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -652,7 +652,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, priv->cache_buf_len = tlv_len; for (tl_ptr = tl, val_ptr=val, tlv_ptr = priv->cache_buf; - tl_len > 2 && val_len > 0 && tlv_len > 0; + tl_len >= 2 /*&& val_len >= 0*/ && tlv_len > 0; val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) { /* get the tag and the length */ tl_start = tl_ptr; From 2138d5fe32ceeb95ca617c769199d08331552bd3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Apr 2018 09:16:46 +0200 Subject: [PATCH 0327/4321] One more todo based on the testing with a new libcacard --- src/libopensc/card-cac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index b356bd0d44..db4b5b4970 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -641,6 +641,14 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, goto done; } + /* XXX TODO + * we can not assume that the following structures are + * SimpleTLV unless we check properties of the applet (GET PROPERTIES) + * and make sure that "Type of Tag Supported" is 0x00. + * Otherwise the formatting is different and we need a different + * encoding to present it in PKCS#11 layer + * XXX TODO + */ switch (priv->object_type) { case CAC_OBJECT_TYPE_TLV_FILE: tlv_len = tl_len + val_len; From cde06a499c2d0ddd5e7ec3ace9175e62927a3320 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 May 2018 17:33:47 +0200 Subject: [PATCH 0328/4321] Use correct AID and Object ID --- src/libopensc/card-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index db4b5b4970..49b25c49d6 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -282,8 +282,8 @@ static const cac_object_t cac_1_objects[] = { { CAC_TO_AID(CAC_1_RID "\x02\x01") }}}, { "Benefits", 0x202, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, { CAC_TO_AID(CAC_1_RID "\x02\x02") }}}, - { "Other Benefits", 0x202, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, - { CAC_TO_AID(CAC_1_RID "\x02\x02") }}}, + { "Other Benefits", 0x203, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, + { CAC_TO_AID(CAC_1_RID "\x02\x03") }}}, { "PKI Credential", 0x2FD, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, { CAC_TO_AID(CAC_1_RID "\x02\xFD") }}}, { "PKI Certificate", 0x2FE, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, From ee7b6f403545fd7ae2ac3dae23a04ffc11d00e0c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 May 2018 09:44:07 +0200 Subject: [PATCH 0329/4321] cac: Log unknown tags --- src/libopensc/card-cac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 49b25c49d6..fc30bbe475 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -739,6 +739,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, break; default: /* Unknown object type */ + sc_log(card->ctx, "Unknown object type: %x", priv->object_type); r = SC_ERROR_INTERNAL; goto done; } From 450cff470a61941b36bf935c67b254060b54b105 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 22 May 2018 15:55:25 +0200 Subject: [PATCH 0330/4321] Inspect the Alt tokens through the ACA applet The previous solution was just guessing AIDs of the PKI objects and trying if they answer. This solution is inspecting card based on the Service Applet Table (listing all the applets on the card) and using GET PROPERTIES APDU listing all the available OIDs of the applet. This was successfully tested with standard CAC card (with different ACA AID) and uninitialized HID Alt tokens with empty certificates slots. --- src/libopensc/card-cac.c | 304 ++++++++++++++++++++++++++++++++++----- 1 file changed, 271 insertions(+), 33 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index fc30bbe475..7a624b7eb6 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -6,9 +6,10 @@ * Copyright (C) 2005,2006,2007,2008,2009,2010 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner - * Copyright (C) 2016, Red Hat, Inc. + * Copyright (C) 2016 - 2018, Red Hat, Inc. * * CAC driver author: Robert Relyea + * Further work: Jakub Jelen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -63,11 +64,13 @@ * CAC hardware and APDU constants */ #define CAC_MAX_CHUNK_SIZE 240 -#define CAC_INS_GET_CERTIFICATE 0x36 /* CAC1 command to read a certificate */ -#define CAC_INS_SIGN_DECRYPT 0x42 /* A crypto operation */ +#define CAC_INS_GET_CERTIFICATE 0x36 /* CAC1 command to read a certificate */ +#define CAC_INS_SIGN_DECRYPT 0x42 /* A crypto operation */ +#define CAC_INS_READ_FILE 0x52 /* read a TL or V file */ +#define CAC_INS_GET_ACR 0x4c +#define CAC_INS_GET_PROPERTIES 0x56 #define CAC_P1_STEP 0x80 #define CAC_P1_FINAL 0x00 -#define CAC_INS_READ_FILE 0x52 /* read a TL or V file */ #define CAC_FILE_TAG 1 #define CAC_FILE_VALUE 2 /* TAGS in a TL file */ @@ -87,9 +90,26 @@ #define CAC_TAG_STATUS_TUPLES 0xFC #define CAC_TAG_NEXT_CCC 0xFD #define CAC_TAG_ERROR_CODES 0xFE -#define CAC_APP_TYPE_GENERAL 0x01 -#define CAC_APP_TYPE_SKI 0x02 -#define CAC_APP_TYPE_PKI 0x04 +#define CAC_TAG_APPLET_FAMILY 0x01 +#define CAC_TAG_NUMBER_APPLETS 0x94 +#define CAC_TAG_APPLET_ENTRY 0x93 +#define CAC_TAG_APPLET_AID 0x92 +#define CAC_TAG_APPLET_INFORMATION 0x01 +#define CAC_TAG_NUMBER_OF_OBJECTS 0x40 +#define CAC_TAG_TV_BUFFER 0x50 +#define CAC_TAG_PKI_OBJECT 0x51 +#define CAC_TAG_OBJECT_ID 0x41 +#define CAC_TAG_BUFFER_PROPERTIES 0x42 +#define CAC_TAG_PKI_PROPERTIES 0x43 + +#define CAC_APP_TYPE_GENERAL 0x01 +#define CAC_APP_TYPE_SKI 0x02 +#define CAC_APP_TYPE_PKI 0x04 + +#define CAC_ACR_ACR 0x00 +#define CAC_ACR_APPLET_OBJECT 0x10 +#define CAC_ACR_AMP 0x20 +#define CAC_ACR_SERVICE 0x21 /* hardware data structures (returned in the CCC) */ /* part of the card_url */ @@ -142,6 +162,14 @@ typedef struct cac_object { sc_path_t path; } cac_object_t; +typedef struct { + unsigned int num_objects; + /* OID has two bytes and there is max 10 of them */ + unsigned char objects[10][2]; + /* Format is SimpleTLV? (Type of Tag Supported) */ + unsigned char simpletlv[10]; +} cac_properties_t; + /* * Flags for Current Selected Object Type * CAC files are TLV files, with TL and V separated. For generic @@ -422,6 +450,50 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } +/* + * Get ACR of currently ACA applet identified by the acr_type + * 5.3.3.5 Get ACR APDU + */ +static int +cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) +{ + u8 *out = NULL; + u8 *out_ptr; + /* XXX assuming it will not be longer than 255 B */ + size_t len = 256; + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* for simplicity we support only ACR without arguments now */ + if (acr_type != 0x00 && acr_type != 0x10 + && acr_type != 0x20 && acr_type != 0x21) { + return SC_ERROR_INVALID_ARGUMENTS; + } + + out = out_ptr = malloc(len); + + r = cac_apdu_io(card, CAC_INS_GET_ACR, acr_type, 0, NULL, 0, &out_ptr, &len); + if (len == 0) { + r = SC_ERROR_FILE_NOT_FOUND; + } + if (r < 0) + goto fail; + + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "got %"SC_FORMAT_LEN_SIZE_T"u bytes out_ptr=%p", len, out_ptr); + + *out_len = len; + *out_buf = out; + return SC_SUCCESS; + +fail: + if (out) + free(out); + *out_len = 0; + return r; +} + /* * Read a CAC TLV file. Parameters specify if the TLV file is TL (Tag/Length) file or a V (value) file */ @@ -964,7 +1036,7 @@ static int cac_rsa_op(sc_card_t *card, if (rbuflen != 0) { int n = MIN(rbuflen, outplen); memcpy(outp,rbuf, n); - /*outp += n; unused */ + /*outp += n; unused */ outplen -= n; } free(rbuf); @@ -1210,6 +1282,131 @@ static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_ return SC_SUCCESS; } +static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) +{ + u8 *rbuf = NULL; + size_t rbuflen = 0, len; + u8 *val, *val_end; + size_t i = 0; + int r; + prop->num_objects = 0; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = cac_apdu_io(card, CAC_INS_GET_PROPERTIES, 0x01, 0x00, NULL, 0, + &rbuf, &rbuflen); + if (r < 0) + return r; + + val = rbuf; + val_end = val + rbuflen; + for (; val < val_end; val += len) { + /* get the tag and the length */ + u8 tag; + if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS) + break; + + switch (tag) { + case CAC_TAG_APPLET_INFORMATION: + if (len != 5) + break; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Information: Family: 0x%0x", val[0]); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + " Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x", + val[1], val[2], val[3], val[4]); + break; + case CAC_TAG_NUMBER_OF_OBJECTS: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Num objects = %hhd", *val); + prop->num_objects = *val; + break; + + case CAC_TAG_TV_BUFFER: + if (len < 11) + break; + /* TODO parse the inner SimpleTLV structure */ + /* skipping 2B of TL encoding of inner structure */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: TV Buffer ID = 0x%02x 0x%02x", val[2], val[3]); + memcpy(&prop->objects[i], &val[2], 2); + /* skipping 4B OID (TLV) + 2B TL for the properties */ + prop->simpletlv[i] = val[6]; + i++; + break; + case CAC_TAG_PKI_OBJECT: + if (len < 11) + break; + /* TODO parse the inner SimpleTLV structure */ + /* skipping 2B of TL encoding of inner structure */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: PKI Object ID = 0x%02x 0x%02x", val[2], val[3]); + memcpy(&prop->objects[i], &val[2], 2); + /* skipping 4B OID (TLV) + 2B TL for the properties */ + prop->simpletlv[i] = val[6]; + i++; + break; + default: + /* ignore tags we don't understand */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Unknown (0x%02x)",tag ); + break; + } + } + /* sanity */ + if (i != prop->num_objects) + return SC_ERROR_INVALID_DATA; + + return SC_SUCCESS; +} + +static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int aid_len) +{ + cac_object_t new_object; + cac_properties_t prop; + size_t i; + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* Search for PKI applets. Ignore generic objects for now */ + if (aid_len < 6 || memcmp(aid, CAC_1_RID "\x01", 6) != 0) + return SC_SUCCESS; + + sc_mem_clear(&new_object.path, sizeof(sc_path_t)); + memcpy(new_object.path.aid.value, aid, aid_len); + new_object.path.aid.len = aid_len; + + /* Call without OID set will just select the AID without subseqent + * OID selection, which we need to figure out just now + */ + cac_select_file_by_type(card, &new_object.path, NULL, SC_CARD_TYPE_CAC_II); + r = cac_get_properties(card, &prop); + if (r < 0) + return SC_ERROR_INTERNAL; + + for (i = 0; i < prop.num_objects; i++) { + /* don't fail just because we have more certs than we can support */ + if (priv->cert_next >= MAX_CAC_SLOTS) + return SC_SUCCESS; + + /* OID here has always 2B */ + memcpy(new_object.path.value, &prop.objects[i], 2); + new_object.path.len = 2; + new_object.path.type = SC_PATH_TYPE_FILE_ID; + + new_object.name = cac_labels[priv->cert_next]; + new_object.fd = priv->cert_next+1; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "ACA: pki_object found, cert_next=%d (%s),", + priv->cert_next, new_object.name); + cac_add_object_to_list(&priv->pki_list, &new_object); + priv->cert_next++; + } + + return SC_SUCCESS; +} + static int cac_parse_cardurl(sc_card_t *card, cac_private_data_t *priv, cac_card_url_t *val, int len) { cac_object_t new_object; @@ -1249,7 +1446,7 @@ static int cac_parse_cardurl(sc_card_t *card, cac_private_data_t *priv, cac_card sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: ski_object found"); break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: unknown object_object found (type=0x%x)", val->cardApplicationType); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: unknown object_object found (type=0x%02x)", val->cardApplicationType); /* don't fail just because there is an unknown object in the CCC */ break; } @@ -1336,7 +1533,7 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, case CAC_TAG_STATUS_TUPLES: case CAC_TAG_REDIRECTION: case CAC_TAG_ERROR_CODES: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:FSSpecific(0x%x)", tag); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:FSSpecific(0x%02x)", tag); break; case CAC_TAG_ACCESS_CONTROL: /* TODO handle access control later */ @@ -1358,7 +1555,7 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, break; default: /* ignore tags we don't understand */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:Unknown (0x%x)",tag ); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:Unknown (0x%02x)",tag ); break; } } @@ -1389,6 +1586,56 @@ static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv) return r; } +/* Service Applet Table (Table 5-21) should list all the applets on the + * card, which is a good start if we don't have CCC + */ +static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, + u8 *val, size_t val_len) +{ + size_t len = 0; + u8 *val_end = val + val_len; + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + for (; val < val_end; val += len) { + /* get the tag and the length */ + u8 tag; + if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS) + break; + + switch (tag) { + case CAC_TAG_APPLET_FAMILY: + if (len != 5) + break; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Information: Family: 0x%02x", val[0]); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + " Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x", + val[1], val[2], val[3], val[4]); + break; + case CAC_TAG_NUMBER_APPLETS: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Num applets = %hhd", *val); + break; + case CAC_TAG_APPLET_ENTRY: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Entry"); + /* This is SimpleTLV prefixed with applet ID (1B) */ + r = cac_parse_aid(card, priv, &val[3], val[2]); + if (r < 0) + return r; + break; + default: + /* ignore tags we don't understand */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Unknown (0x%02x)", tag); + break; + } + } + return SC_SUCCESS; +} + /* select a CAC-1 pki applet by index */ static int cac_select_pki_applet(sc_card_t *card, int index) { @@ -1477,39 +1724,30 @@ static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *pr static int cac_process_ACA(sc_card_t *card, cac_private_data_t *priv) { - int r, index; - u8 *tl = NULL, *val = NULL; - size_t tl_len, val_len; - + int r; + u8 *val = NULL; + size_t val_len; - r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len); - if (r < 0) - goto done; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len); + /* Assuming ACA is already selected */ + r = cac_get_acr(card, CAC_ACR_SERVICE, &val, &val_len); if (r < 0) goto done; - /* TODO we should process the ACA file -- so far we are happy we can read it */ - //r = cac_parse_ACA(card, priv, tl, tl_len, val, val_len); - r = cac_find_first_pki_applet(card, &index); + r = cac_parse_ACA_service(card, priv, val, val_len); if (r == SC_SUCCESS) { - r = cac_populate_cac_1(card, index, priv); - if (r == SC_SUCCESS) { - priv->aca_path = malloc(sizeof(sc_path_t)); - if (!priv->aca_path) { - r = SC_ERROR_OUT_OF_MEMORY; - goto done; - } - memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t)); + priv->aca_path = malloc(sizeof(sc_path_t)); + if (!priv->aca_path) { + r = SC_ERROR_OUT_OF_MEMORY; + goto done; } + memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t)); } done: - if (tl) - free(tl); if (val) free(val); - return r; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } /* From d24c23ac0cd44f66291607df229c73fa9c4c5d44 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 May 2018 13:31:52 +0200 Subject: [PATCH 0331/4321] Use applet properties to recognize buffer formats Previously, the code handled all the data objects as SimpleTLV, which caused invalid encoding when we tried to merge TL + V buffers into single PKCS#15 buffers. This change is using GET PROPERTIES APDU after applet selection to explore objects, figure out encoding and check the status of PKI objects initialization to avoid reading them. --- src/libopensc/card-cac.c | 270 +++++++++++++++++++++++++-------------- 1 file changed, 177 insertions(+), 93 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 7a624b7eb6..5e37da0247 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -162,12 +162,16 @@ typedef struct cac_object { sc_path_t path; } cac_object_t; +#define CAC_MAX_OBJECTS 10 + typedef struct { unsigned int num_objects; - /* OID has two bytes and there is max 10 of them */ - unsigned char objects[10][2]; - /* Format is SimpleTLV? (Type of Tag Supported) */ - unsigned char simpletlv[10]; + /* OID has two bytes */ + unsigned char objects[CAC_MAX_OBJECTS][2]; + /* Format is NOT SimpleTLV? */ + unsigned char simpletlv[CAC_MAX_OBJECTS]; + /* Is certificate object and private key is initialized */ + unsigned char privatekey[CAC_MAX_OBJECTS]; } cac_properties_t; /* @@ -181,6 +185,7 @@ typedef struct { */ #define CAC_OBJECT_TYPE_CERT 1 #define CAC_OBJECT_TYPE_TLV_FILE 4 +#define CAC_OBJECT_TYPE_GENERIC 5 /* * CAC private data per card state @@ -258,7 +263,6 @@ static int cac_add_object_to_list(list_t *list, const cac_object_t *object) #define CAC_2_RID "\xA0\x00\x00\x01\x16" #define CAC_1_RID "\xA0\x00\x00\x00\x79" -#define CAC_1_CM_AID "\xA0\x00\x00\x00\x30\x00\00" static const sc_path_t cac_ACA_Path = { "", 0, @@ -713,14 +717,6 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, goto done; } - /* XXX TODO - * we can not assume that the following structures are - * SimpleTLV unless we check properties of the applet (GET PROPERTIES) - * and make sure that "Type of Tag Supported" is 0x00. - * Otherwise the formatting is different and we need a different - * encoding to present it in PKCS#11 layer - * XXX TODO - */ switch (priv->object_type) { case CAC_OBJECT_TYPE_TLV_FILE: tlv_len = tl_len + val_len; @@ -809,6 +805,11 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, goto done; } break; + case CAC_OBJECT_TYPE_GENERIC: + /* TODO + * We have some two buffers in unknown encoding that we + * need to present in PKCS#15 layer. + */ default: /* Unknown object type */ sc_log(card->ctx, "Unknown object type: %x", priv->object_type); @@ -1073,6 +1074,129 @@ static int cac_decipher(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, cac_rsa_op(card, data, datalen, out, outlen)); } +static int parse_properties_object(sc_card_t *card, u8 type, + u8 *data, size_t data_len, cac_properties_t *prop, size_t *i) +{ + size_t len; + u8 *val, *val_end, tag; + int parsed = 0; + + if (data_len < 11) + return -1; + + /* Initilize: non-PKI applet */ + prop->privatekey[*i] = 0; + + val = data; + val_end = data + data_len; + for (; val < val_end; val += len) { + /* get the tag and the length */ + if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS) + break; + + switch (tag) { + case CAC_TAG_OBJECT_ID: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Object ID = 0x%02x 0x%02x", val[0], val[1]); + memcpy(&prop->objects[*i], val, 2); + parsed++; + break; + + case CAC_TAG_BUFFER_PROPERTIES: + /* First byte is "Type of Tag Supported" */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Buffer Properties: Type of Tag Supported = 0x%02x", + val[0]); + prop->simpletlv[*i] = val[0]; + parsed++; + break; + + case CAC_TAG_PKI_PROPERTIES: + /* 4th byte is "Private Key Initialized" */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: PKI Properties: Private Key Initialized = 0x%02x", + val[2]); + prop->privatekey[*i] = val[2]; + parsed++; + break; + + default: + /* ignore tags we don't understand */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Unknown (0x%02x)",tag ); + break; + } + } + if (parsed < 2) + return SC_ERROR_INVALID_DATA; + + (*i)++; + return SC_SUCCESS; +} + +static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) +{ + u8 *rbuf = NULL; + size_t rbuflen = 0, len; + u8 *val, *val_end, tag; + size_t i = 0; + int r; + prop->num_objects = 0; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = cac_apdu_io(card, CAC_INS_GET_PROPERTIES, 0x01, 0x00, NULL, 0, + &rbuf, &rbuflen); + if (r < 0) + return r; + + val = rbuf; + val_end = val + rbuflen; + for (; val < val_end; val += len) { + /* get the tag and the length */ + if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS) + break; + + switch (tag) { + case CAC_TAG_APPLET_INFORMATION: + if (len != 5) + break; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Information: Family: 0x%0x", val[0]); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + " Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x", + val[1], val[2], val[3], val[4]); + break; + case CAC_TAG_NUMBER_OF_OBJECTS: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Num objects = %hhd", *val); + /* make sure we do not overrun buffer */ + prop->num_objects = MIN(val[0], CAC_MAX_OBJECTS); + break; + + case CAC_TAG_TV_BUFFER: + case CAC_TAG_PKI_OBJECT: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: TV/PKI Object nr. %"SC_FORMAT_LEN_SIZE_T"u (0x%02x)", i, tag); + if (i >= CAC_MAX_OBJECTS) + return SC_SUCCESS; + + parse_properties_object(card, tag, val, len, prop, &i); + break; + default: + /* ignore tags we don't understand */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Unknown (0x%02x)",tag ); + break; + } + } + /* sanity */ + if (i != prop->num_objects) + return SC_ERROR_INVALID_DATA; + + return SC_SUCCESS; +} + /* * CAC cards use SC_PATH_SELECT_OBJECT_ID rather than SC_PATH_SELECT_FILE_ID. In order to use more * of the PKCS #15 structure, we call the selection SC_PATH_SELECT_FILE_ID, but we set p1 to 2 instead @@ -1127,10 +1251,11 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc * and object type here: */ if (priv) { /* don't record anything if we haven't been initialized yet */ - priv->object_type = CAC_OBJECT_TYPE_TLV_FILE; + priv->object_type = CAC_OBJECT_TYPE_GENERIC; if (cac_is_cert(priv, in_path)) { priv->object_type = CAC_OBJECT_TYPE_CERT; } + /* forget any old cached values */ if (priv->cache_buf) { free(priv->cache_buf); @@ -1195,6 +1320,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); + if (file_out == NULL) { /* For some cards 'SELECT' can be only with request to return FCI/FCP. */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1213,7 +1339,37 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc if (r) LOG_FUNC_RETURN(ctx, r); - /* CAC cards never return FCI, fake one */ + /* This needs to come after the applet selection */ + if (priv && in_path->len) { + /* get applet properties to know if we can treat the + * buffer as SimpleLTV and if we have PKI applet. + * + * Do this only if we select applets for reading + * (not during driver initialization) + */ + cac_properties_t prop; + size_t i = -1; + + r = cac_get_properties(card, &prop); + if (r == SC_SUCCESS) { + for (i = 0; i < prop.num_objects; i++) { + sc_log(card->ctx, "Searching for our OID: 0x%02x 0x%02x = 0x%02x 0x%02x", + prop.objects[i][0], prop.objects[i][1], + in_path->value[0], in_path->value[1]); + if (memcmp(prop.objects[i], + in_path->value, 2) == 0) + break; + } + } + if (i < prop.num_objects) { + if (prop.privatekey[i]) + priv->object_type = CAC_OBJECT_TYPE_CERT; + else if (prop.simpletlv[i] == 0) + priv->object_type = CAC_OBJECT_TYPE_TLV_FILE; + } + } + + /* CAC cards never return FCI, fake one */ file = sc_file_new(); if (file == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); @@ -1282,84 +1438,6 @@ static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_ return SC_SUCCESS; } -static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) -{ - u8 *rbuf = NULL; - size_t rbuflen = 0, len; - u8 *val, *val_end; - size_t i = 0; - int r; - prop->num_objects = 0; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - r = cac_apdu_io(card, CAC_INS_GET_PROPERTIES, 0x01, 0x00, NULL, 0, - &rbuf, &rbuflen); - if (r < 0) - return r; - - val = rbuf; - val_end = val + rbuflen; - for (; val < val_end; val += len) { - /* get the tag and the length */ - u8 tag; - if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS) - break; - - switch (tag) { - case CAC_TAG_APPLET_INFORMATION: - if (len != 5) - break; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Applet Information: Family: 0x%0x", val[0]); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - " Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x", - val[1], val[2], val[3], val[4]); - break; - case CAC_TAG_NUMBER_OF_OBJECTS: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Num objects = %hhd", *val); - prop->num_objects = *val; - break; - - case CAC_TAG_TV_BUFFER: - if (len < 11) - break; - /* TODO parse the inner SimpleTLV structure */ - /* skipping 2B of TL encoding of inner structure */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: TV Buffer ID = 0x%02x 0x%02x", val[2], val[3]); - memcpy(&prop->objects[i], &val[2], 2); - /* skipping 4B OID (TLV) + 2B TL for the properties */ - prop->simpletlv[i] = val[6]; - i++; - break; - case CAC_TAG_PKI_OBJECT: - if (len < 11) - break; - /* TODO parse the inner SimpleTLV structure */ - /* skipping 2B of TL encoding of inner structure */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: PKI Object ID = 0x%02x 0x%02x", val[2], val[3]); - memcpy(&prop->objects[i], &val[2], 2); - /* skipping 4B OID (TLV) + 2B TL for the properties */ - prop->simpletlv[i] = val[6]; - i++; - break; - default: - /* ignore tags we don't understand */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Unknown (0x%02x)",tag ); - break; - } - } - /* sanity */ - if (i != prop->num_objects) - return SC_ERROR_INVALID_DATA; - - return SC_SUCCESS; -} - static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int aid_len) { cac_object_t new_object; @@ -1390,6 +1468,12 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int if (priv->cert_next >= MAX_CAC_SLOTS) return SC_SUCCESS; + /* If the private key is not initialized, we can safely + * ignore this object here + */ + if (!prop.privatekey[i]) + continue; + /* OID here has always 2B */ memcpy(new_object.path.value, &prop.objects[i], 2); new_object.path.len = 2; From aacac5723089ab3cbc5f7db4699107af2f1b147c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 May 2018 14:03:41 +0200 Subject: [PATCH 0332/4321] Another note/todo about PINs on uninitialized cards --- src/libopensc/pkcs15-cac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 80e7b90e0f..93032113c1 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -224,6 +224,9 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) } /* set pins */ + /* TODO we should not create PIN objects if it is not initialized + * (opensc-tool -s 0020000000 returns 0x6A 0x88) + */ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC adding pins..."); for (i = 0; pins[i].id; i++) { struct sc_pkcs15_auth_info pin_info; From a73b3d549bbd26ebeb48a62b38ac5bdf17a4f17f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 28 May 2018 09:28:10 +0200 Subject: [PATCH 0333/4321] Address review comments: * Refactor cac_properties_t structure to make its creation more readable * Avoid manual allocation in cac_get_acr() and clean up bogus pointers * Avoid bogus comments * Properly check lengths of retrieved values --- src/libopensc/card-cac.c | 65 ++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 5e37da0247..7346fb8bbe 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -165,13 +165,17 @@ typedef struct cac_object { #define CAC_MAX_OBJECTS 10 typedef struct { - unsigned int num_objects; /* OID has two bytes */ - unsigned char objects[CAC_MAX_OBJECTS][2]; + unsigned char oid[2]; /* Format is NOT SimpleTLV? */ - unsigned char simpletlv[CAC_MAX_OBJECTS]; + unsigned char simpletlv; /* Is certificate object and private key is initialized */ - unsigned char privatekey[CAC_MAX_OBJECTS]; + unsigned char privatekey; +} cac_properties_object_t; + +typedef struct { + unsigned int num_objects; + cac_properties_object_t objects[CAC_MAX_OBJECTS]; } cac_properties_t; /* @@ -462,7 +466,6 @@ static int cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) { u8 *out = NULL; - u8 *out_ptr; /* XXX assuming it will not be longer than 255 B */ size_t len = 256; int r; @@ -475,9 +478,7 @@ cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) return SC_ERROR_INVALID_ARGUMENTS; } - out = out_ptr = malloc(len); - - r = cac_apdu_io(card, CAC_INS_GET_ACR, acr_type, 0, NULL, 0, &out_ptr, &len); + r = cac_apdu_io(card, CAC_INS_GET_ACR, acr_type, 0, NULL, 0, &out, &len); if (len == 0) { r = SC_ERROR_FILE_NOT_FOUND; } @@ -485,7 +486,7 @@ cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) goto fail; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "got %"SC_FORMAT_LEN_SIZE_T"u bytes out_ptr=%p", len, out_ptr); + "got %"SC_FORMAT_LEN_SIZE_T"u bytes out=%p", len, out); *out_len = len; *out_buf = out; @@ -494,6 +495,7 @@ cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) fail: if (out) free(out); + *out_buf = NULL; *out_len = 0; return r; } @@ -728,7 +730,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, priv->cache_buf_len = tlv_len; for (tl_ptr = tl, val_ptr=val, tlv_ptr = priv->cache_buf; - tl_len >= 2 /*&& val_len >= 0*/ && tlv_len > 0; + tl_len >= 2 && tlv_len > 0; val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) { /* get the tag and the length */ tl_start = tl_ptr; @@ -1075,7 +1077,7 @@ static int cac_decipher(sc_card_t *card, } static int parse_properties_object(sc_card_t *card, u8 type, - u8 *data, size_t data_len, cac_properties_t *prop, size_t *i) + u8 *data, size_t data_len, cac_properties_object_t *object) { size_t len; u8 *val, *val_end, tag; @@ -1085,7 +1087,7 @@ static int parse_properties_object(sc_card_t *card, u8 type, return -1; /* Initilize: non-PKI applet */ - prop->privatekey[*i] = 0; + object->privatekey = 0; val = data; val_end = data + data_len; @@ -1098,7 +1100,7 @@ static int parse_properties_object(sc_card_t *card, u8 type, case CAC_TAG_OBJECT_ID: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Object ID = 0x%02x 0x%02x", val[0], val[1]); - memcpy(&prop->objects[*i], val, 2); + memcpy(&object->oid, val, 2); parsed++; break; @@ -1107,7 +1109,7 @@ static int parse_properties_object(sc_card_t *card, u8 type, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Buffer Properties: Type of Tag Supported = 0x%02x", val[0]); - prop->simpletlv[*i] = val[0]; + object->simpletlv = val[0]; parsed++; break; @@ -1116,7 +1118,7 @@ static int parse_properties_object(sc_card_t *card, u8 type, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: PKI Properties: Private Key Initialized = 0x%02x", val[2]); - prop->privatekey[*i] = val[2]; + object->privatekey = val[2]; parsed++; break; @@ -1130,7 +1132,6 @@ static int parse_properties_object(sc_card_t *card, u8 type, if (parsed < 2) return SC_ERROR_INVALID_DATA; - (*i)++; return SC_SUCCESS; } @@ -1181,7 +1182,9 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) if (i >= CAC_MAX_OBJECTS) return SC_SUCCESS; - parse_properties_object(card, tag, val, len, prop, &i); + if (parse_properties_object(card, tag, val, len, + &prop->objects[i]) == SC_SUCCESS) + i++; break; default: /* ignore tags we don't understand */ @@ -1354,17 +1357,17 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc if (r == SC_SUCCESS) { for (i = 0; i < prop.num_objects; i++) { sc_log(card->ctx, "Searching for our OID: 0x%02x 0x%02x = 0x%02x 0x%02x", - prop.objects[i][0], prop.objects[i][1], + prop.objects[i].oid[0], prop.objects[i].oid[1], in_path->value[0], in_path->value[1]); - if (memcmp(prop.objects[i], + if (memcmp(prop.objects[i].oid, in_path->value, 2) == 0) break; } } if (i < prop.num_objects) { - if (prop.privatekey[i]) + if (prop.objects[i].privatekey) priv->object_type = CAC_OBJECT_TYPE_CERT; - else if (prop.simpletlv[i] == 0) + else if (prop.objects[i].simpletlv == 0) priv->object_type = CAC_OBJECT_TYPE_TLV_FILE; } } @@ -1447,8 +1450,8 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* Search for PKI applets. Ignore generic objects for now */ - if (aid_len < 6 || memcmp(aid, CAC_1_RID "\x01", 6) != 0) + /* Search for PKI applets (7 B). Ignore generic objects for now */ + if (aid_len != 7 || memcmp(aid, CAC_1_RID "\x01", 6) != 0) return SC_SUCCESS; sc_mem_clear(&new_object.path, sizeof(sc_path_t)); @@ -1471,11 +1474,11 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int /* If the private key is not initialized, we can safely * ignore this object here */ - if (!prop.privatekey[i]) + if (!prop.objects[i].privatekey) continue; /* OID here has always 2B */ - memcpy(new_object.path.value, &prop.objects[i], 2); + memcpy(new_object.path.value, &prop.objects[i].oid, 2); new_object.path.len = 2; new_object.path.type = SC_PATH_TYPE_FILE_ID; @@ -1699,12 +1702,24 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, val[1], val[2], val[3], val[4]); break; case CAC_TAG_NUMBER_APPLETS: + if (len != 1) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Num applets = (bad length %"SC_FORMAT_LEN_SIZE_T"u)", + len); + break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Num applets = %hhd", *val); break; case CAC_TAG_APPLET_ENTRY: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Applet Entry"); + /* Make sure we match the outer length */ + if (val[2] != len - 3) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "bad length of internal buffer"); + break; + } /* This is SimpleTLV prefixed with applet ID (1B) */ r = cac_parse_aid(card, priv, &val[3], val[2]); if (r < 0) From f27ee858c207f4bf793b4511b0ac1a5505ce2525 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 May 2018 11:03:39 +0200 Subject: [PATCH 0334/4321] Carefully check the length of the buffers before accessing them. The lengths are static and based on the GCS-IS 2.1 specification --- src/libopensc/card-cac.c | 76 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 7346fb8bbe..7245847d3c 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1098,6 +1098,11 @@ static int parse_properties_object(sc_card_t *card, u8 type, switch (tag) { case CAC_TAG_OBJECT_ID: + if (len != 2) { + sc_log(card->ctx, "TAG: Object ID: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Object ID = 0x%02x 0x%02x", val[0], val[1]); memcpy(&object->oid, val, 2); @@ -1105,6 +1110,11 @@ static int parse_properties_object(sc_card_t *card, u8 type, break; case CAC_TAG_BUFFER_PROPERTIES: + if (len != 5) { + sc_log(card->ctx, "TAG: Buffer Properties: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } /* First byte is "Type of Tag Supported" */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Buffer Properties: Type of Tag Supported = 0x%02x", @@ -1115,6 +1125,15 @@ static int parse_properties_object(sc_card_t *card, u8 type, case CAC_TAG_PKI_PROPERTIES: /* 4th byte is "Private Key Initialized" */ + if (len != 4) { + sc_log(card->ctx, "TAG: PKI Properties: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } + if (type != CAC_TAG_PKI_OBJECT) { + sc_log(card->ctx, "TAG: PKI Properties outside of PKI Object"); + break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: PKI Properties: Private Key Initialized = 0x%02x", val[2]); @@ -1160,15 +1179,24 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) switch (tag) { case CAC_TAG_APPLET_INFORMATION: - if (len != 5) + if (len != 5) { + sc_log(card->ctx, "TAG: Applet Information: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Applet Information: Family: 0x%0x", val[0]); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, " Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x", val[1], val[2], val[3], val[4]); break; + case CAC_TAG_NUMBER_OF_OBJECTS: + if (len != 1) { + sc_log(card->ctx, "TAG: Num objects: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Num objects = %hhd", *val); /* make sure we do not overrun buffer */ @@ -1176,9 +1204,29 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) break; case CAC_TAG_TV_BUFFER: + if (len != 17) { + sc_log(card->ctx, "TAG: TV Object: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: TV Object nr. %"SC_FORMAT_LEN_SIZE_T"u", i); + if (i >= CAC_MAX_OBJECTS) + return SC_SUCCESS; + + if (parse_properties_object(card, tag, val, len, + &prop->objects[i]) == SC_SUCCESS) + i++; + break; + case CAC_TAG_PKI_OBJECT: + if (len != 17) { + sc_log(card->ctx, "TAG: PKI Object: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: TV/PKI Object nr. %"SC_FORMAT_LEN_SIZE_T"u (0x%02x)", i, tag); + "TAG: PKI Object nr. %"SC_FORMAT_LEN_SIZE_T"u", i); if (i >= CAC_MAX_OBJECTS) return SC_SUCCESS; @@ -1186,6 +1234,7 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) &prop->objects[i]) == SC_SUCCESS) i++; break; + default: /* ignore tags we don't understand */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, @@ -1343,7 +1392,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc LOG_FUNC_RETURN(ctx, r); /* This needs to come after the applet selection */ - if (priv && in_path->len) { + if (priv && in_path->len >= 2) { /* get applet properties to know if we can treat the * buffer as SimpleLTV and if we have PKI applet. * @@ -1590,14 +1639,24 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, return r; break; case CAC_TAG_CC_VERSION_NUMBER: + if (len != 1) { + sc_log(card->ctx, "TAG: CC Version: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } /* ignore the version numbers for now */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG:CC Version = 0x%02x", *val); + "TAG: CC Version = 0x%02x", *val); break; case CAC_TAG_GRAMMAR_VERION_NUMBER: + if (len != 1) { + sc_log(card->ctx, "TAG: Grammar Version: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } /* ignore the version numbers for now */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG:Grammar Version = 0x%02x", *val); + "TAG: Grammar Version = 0x%02x", *val); break; case CAC_TAG_CARDURL: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:CARDURL"); @@ -1609,10 +1668,15 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, * The following are really for file systems cards. This code only cares about CAC VM cards */ case CAC_TAG_PKCS15: + if (len != 1) { + sc_log(card->ctx, "TAG: PKCS15: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } /* TODO should verify that this is '0'. If it's not * zero, we should drop out of here and let the PKCS 15 * code handle this card */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:PKCS15 = 0x%02x", *val); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG: PKCS15 = 0x%02x", *val); break; case CAC_TAG_DATA_MODEL: case CAC_TAG_CARD_APDU: From 298afb072ebc65da3c9c7d72038ff6d64e0a02e2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 4 Jun 2018 12:34:29 +0200 Subject: [PATCH 0335/4321] Properly check length also of the applet entry --- src/libopensc/card-cac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 7245847d3c..17f25fcc83 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1779,7 +1779,7 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Applet Entry"); /* Make sure we match the outer length */ - if (val[2] != len - 3) { + if (len < 3 || val[2] != len - 3) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "bad length of internal buffer"); break; From 930d4573048f22390789f544c57dcc8eb79f8b53 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 4 Jun 2018 12:42:35 +0200 Subject: [PATCH 0336/4321] Log bad length buffers --- src/libopensc/card-cac.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 17f25fcc83..7c729a6dfe 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1757,8 +1757,12 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, switch (tag) { case CAC_TAG_APPLET_FAMILY: - if (len != 5) + if (len != 5) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Information = (bad length %" + SC_FORMAT_LEN_SIZE_T"u)", len); break; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Applet Information: Family: 0x%02x", val[0]); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, From 9dda83e48e9c38fb3a36e71d855477421f4d9c63 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 4 Jun 2018 17:53:13 +0200 Subject: [PATCH 0337/4321] cac: Verbose logging, avoid OOB reads --- src/libopensc/card-cac.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 7c729a6dfe..ac2b75cb2a 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -575,6 +575,7 @@ static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_l sc_apdu_t apdu; int r = SC_SUCCESS; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* get the size */ size = left = *out_buf ? *out_len : sizeof(buf); @@ -591,6 +592,10 @@ static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_l if (r < 0) { break; } + if (apdu.resplen == 0) { + r = SC_ERROR_INTERNAL; + break; + } /* in the old CAC-1, 0x63 means 'more data' in addition to 'pin failed' */ if (apdu.sw1 != 0x63) { /* we've either finished reading, or hit an error, break */ @@ -598,21 +603,22 @@ static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_l left -= len; break; } - next_len = MIN(left,apdu.sw2); + next_len = MIN(left, apdu.sw2); } if (r < 0) { - return r; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } r = size - left; if (*out_buf == NULL) { *out_buf = malloc(r); if (*out_buf == NULL) { - return SC_ERROR_OUT_OF_MEMORY; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, + SC_ERROR_OUT_OF_MEMORY); } memcpy(*out_buf, buf, r); } *out_len = r; - return r; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } /* Create a fake tag/length file in Simple TLV for cac1 cards based on the val_len. From 50b5eb3b69e6286f4bfe024101870e204f71377c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Jun 2018 09:39:04 +0200 Subject: [PATCH 0338/4321] Allow using up to 16 certificates --- src/libopensc/card-cac.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index ac2b75cb2a..54766d8523 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -162,7 +162,7 @@ typedef struct cac_object { sc_path_t path; } cac_object_t; -#define CAC_MAX_OBJECTS 10 +#define CAC_MAX_OBJECTS 16 typedef struct { /* OID has two bytes */ @@ -280,19 +280,25 @@ static const sc_path_t cac_CCC_Path = { { CAC_TO_AID(CAC_2_RID "\xDB\x00") } }; -#define MAX_CAC_SLOTS 10 /* arbitrary, just needs to be 'large enough' */ +#define MAX_CAC_SLOTS 16 /* arbitrary, just needs to be 'large enough' */ /* default certificate labels for the CAC card */ static const char *cac_labels[MAX_CAC_SLOTS] = { "CAC ID Certificate", "CAC Email Signature Certificate", "CAC Email Encryption Certificate", - "CAC Cert 3", "CAC Cert 4", "CAC Cert 5", "CAC Cert 6", "CAC Cert 7", "CAC Cert 8", - "CAC Cert 9" + "CAC Cert 9", + "CAC Cert 10", + "CAC Cert 11", + "CAC Cert 12", + "CAC Cert 13", + "CAC Cert 14", + "CAC Cert 15", + "CAC Cert 16" }; /* template for a cac1 pki object */ From 40b02b2582a02363fb316ed7c75fea9bdb1a22b6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Jun 2018 14:42:12 +0200 Subject: [PATCH 0339/4321] Namespace the function name, update comment --- src/libopensc/card-cac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 54766d8523..9f7b660cc3 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -280,7 +280,7 @@ static const sc_path_t cac_CCC_Path = { { CAC_TO_AID(CAC_2_RID "\xDB\x00") } }; -#define MAX_CAC_SLOTS 16 /* arbitrary, just needs to be 'large enough' */ +#define MAX_CAC_SLOTS 16 /* Maximum number of slots is 16 now */ /* default certificate labels for the CAC card */ static const char *cac_labels[MAX_CAC_SLOTS] = { "CAC ID Certificate", @@ -1088,7 +1088,7 @@ static int cac_decipher(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, cac_rsa_op(card, data, datalen, out, outlen)); } -static int parse_properties_object(sc_card_t *card, u8 type, +static int cac_parse_properties_object(sc_card_t *card, u8 type, u8 *data, size_t data_len, cac_properties_object_t *object) { size_t len; @@ -1226,7 +1226,7 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) if (i >= CAC_MAX_OBJECTS) return SC_SUCCESS; - if (parse_properties_object(card, tag, val, len, + if (cac_parse_properties_object(card, tag, val, len, &prop->objects[i]) == SC_SUCCESS) i++; break; @@ -1242,7 +1242,7 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) if (i >= CAC_MAX_OBJECTS) return SC_SUCCESS; - if (parse_properties_object(card, tag, val, len, + if (cac_parse_properties_object(card, tag, val, len, &prop->objects[i]) == SC_SUCCESS) i++; break; From f2ba0ad9be431970ffd41d8b79f2bb5b7f877ed1 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 9 Jun 2018 10:15:13 +0200 Subject: [PATCH 0340/4321] PIV: refactor to use sc_compacttlv_find_tag() --- src/libopensc/card-piv.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 8525eedea7..38aea8f0e7 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2985,9 +2985,7 @@ static int piv_match_card(sc_card_t *card) static int piv_match_card_continued(sc_card_t *card) { - int i, i7e, k; - size_t j; - u8 *p, *pe; + int i, i7e; sc_file_t aidfile; int type = -1; piv_private_data_t *priv = NULL; @@ -3042,23 +3040,21 @@ static int piv_match_card_continued(sc_card_t *card) } else if (card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ - p = card->reader->atr_info.hist_bytes; - pe = p + card->reader->atr_info.hist_bytes_len; - p++; /* skip 0x80u byte */ - while (p < pe && type == -1) { - j = *p & 0x0fu; /* length */ - if ((*p++ & 0xf0u) == 0xf0u) { /*looking for 15 */ - if ((p + j) <= pe) { - for (k = 0; piv_aids[k].len_long != 0; k++) { - if (j == piv_aids[k].len_long - && !memcmp(p, piv_aids[k].value,j)) { - type = SC_CARD_TYPE_PIV_II_HIST; - break; - } - } + size_t datalen; + const u8 *data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1, + card->reader->atr_info.hist_bytes_len - 1, + 0xF0, &datalen); + + if (data != NULL) { + int k; + + for (k = 0; piv_aids[k].len_long != 0; k++) { + if (datalen == piv_aids[k].len_long + && !memcmp(data, piv_aids[k].value, datalen)) { + type = SC_CARD_TYPE_PIV_II_HIST; + break; } } - p += j; } } } From 7c99adaaa6d247300d903b6fdeb1cb626023e353 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 9 Jun 2018 11:35:00 +0200 Subject: [PATCH 0341/4321] PIV: limit scope of some variables --- src/libopensc/card-piv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 38aea8f0e7..e2a6eeedde 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2985,8 +2985,7 @@ static int piv_match_card(sc_card_t *card) static int piv_match_card_continued(sc_card_t *card) { - int i, i7e; - sc_file_t aidfile; + int i; int type = -1; piv_private_data_t *priv = NULL; int saved_type = card->type; @@ -3100,6 +3099,8 @@ static int piv_match_card_continued(sc_card_t *card) if (i < 0) { /* Detect by selecting applet */ + sc_file_t aidfile; + i = piv_find_aid(card, &aidfile); } @@ -3111,7 +3112,8 @@ static int piv_match_card_continued(sc_card_t *card) * SC_ERROR_FILE_NOT_FOUND means we cannot use discovery * to test for active AID. */ - i7e = piv_find_discovery(card); + int i7e = piv_find_discovery(card); + if (i7e != 0 && i7e != SC_ERROR_FILE_NOT_FOUND) { priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; From 31941bc3d9b9c278786cdc754e6a51c490f5b3ad Mon Sep 17 00:00:00 2001 From: asc Date: Wed, 6 Jun 2018 16:34:17 +0200 Subject: [PATCH 0342/4321] sc-hsm: Ensure that applet returns version information (Fix #1377) --- src/libopensc/card-sc-hsm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 99050cf792..8fc07ed056 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -242,6 +242,7 @@ static int sc_hsm_match_card(struct sc_card *card) { sc_path_t path; int i, r, type = 0; + sc_file_t *file = NULL; i = _sc_match_atr(card, sc_hsm_atrs, &type); if (i >= 0 && type != SC_CARD_TYPE_SC_HSM_SOC) { @@ -250,9 +251,18 @@ static int sc_hsm_match_card(struct sc_card *card) } sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); - r = sc_hsm_select_file(card, &path, NULL); + r = sc_hsm_select_file(card, &path, &file); LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application"); + // Validate that card returns a FCP with a proprietary tag 85 with value longer than 2 byte (Fixes #1377) + if (file != NULL) { + i = file->prop_attr_len; + sc_file_free(file); + if (i < 2) { + return 0; + } + } + if (type == SC_CARD_TYPE_SC_HSM_SOC) { card->type = SC_CARD_TYPE_SC_HSM_SOC; } else { From ab16228e26c6c793d3828616b3f04298546f752f Mon Sep 17 00:00:00 2001 From: ytoku Date: Wed, 6 Jun 2018 17:12:01 +0900 Subject: [PATCH 0343/4321] gids: fix gids_delete_cert --- src/libopensc/card-gids.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 9bc354b1b1..2b0426cd8c 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1626,7 +1626,7 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { unsigned short fileIdentifier, DO; u8 masterfilebuffer[MAX_GIDS_FILE_SIZE]; size_t masterfilebuffersize = 0; - gids_mf_record_t *records = (gids_mf_record_t *) masterfilebuffer; + gids_mf_record_t *records = (gids_mf_record_t *) (masterfilebuffer+1); size_t recordcount, recordnum = (size_t) -1; size_t i; @@ -1648,7 +1648,7 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { memcpy(masterfilebuffer, privatedata->masterfile, privatedata->masterfilesize); masterfilebuffersize = privatedata->masterfilesize; - recordcount = (masterfilebuffersize / sizeof(gids_mf_record_t)); + recordcount = ((masterfilebuffersize-1) / sizeof(gids_mf_record_t)); for (i = 0; i < recordcount; i++) { if (records[i].fileIdentifier == fileIdentifier && records[i].dataObjectIdentifier == DO) { recordnum = i; @@ -1659,7 +1659,7 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); } - for (i = (recordnum+1) * sizeof(gids_mf_record_t); i < masterfilebuffersize; i++) { + for (i = 1 + (recordnum+1) * sizeof(gids_mf_record_t); i < masterfilebuffersize; i++) { masterfilebuffer[i - sizeof(gids_mf_record_t)] = masterfilebuffer[i]; } masterfilebuffersize -= sizeof(gids_mf_record_t); From 46c0bbd803b95f930d02574d288342c0e9cc2daf Mon Sep 17 00:00:00 2001 From: ytoku Date: Wed, 6 Jun 2018 17:19:53 +0900 Subject: [PATCH 0344/4321] gids: use file id instead of path in gids_delete_key_file --- src/libopensc/card-gids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 2b0426cd8c..07792d96ff 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1477,7 +1477,7 @@ static int gids_delete_key_file(sc_card_t *card, int containernum) { int r; char ch_tmp[10]; sc_path_t cpath; - snprintf(ch_tmp, sizeof(ch_tmp), "B0%02X",containernum + GIDS_FIRST_KEY_IDENTIFIER); + snprintf(ch_tmp, sizeof(ch_tmp), "IB0%02X",containernum + GIDS_FIRST_KEY_IDENTIFIER); sc_format_path(ch_tmp, &cpath); r = iso_ops->select_file(card, &cpath, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select the key file"); From 63ed8d73686338676c05afd30e6c039fa49f1fb9 Mon Sep 17 00:00:00 2001 From: ytoku Date: Tue, 19 Jun 2018 12:17:17 +0900 Subject: [PATCH 0345/4321] gids: file selection via gids_select_file --- src/libopensc/card-gids.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 07792d96ff..bdf2e1f749 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1477,9 +1477,9 @@ static int gids_delete_key_file(sc_card_t *card, int containernum) { int r; char ch_tmp[10]; sc_path_t cpath; - snprintf(ch_tmp, sizeof(ch_tmp), "IB0%02X",containernum + GIDS_FIRST_KEY_IDENTIFIER); + snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X",containernum + GIDS_FIRST_KEY_IDENTIFIER); sc_format_path(ch_tmp, &cpath); - r = iso_ops->select_file(card, &cpath, NULL); + r = gids_select_file(card, &cpath, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select the key file"); // delete current selected file memset(&cpath, 0, sizeof(cpath)); From d8cdf66d3d9909b3a827f317d44b30f5788b0780 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Jun 2018 23:15:29 +0200 Subject: [PATCH 0346/4321] fixed memory leak --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 4db8446402..ac5bddb16e 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2137,7 +2137,7 @@ static int coolkey_initialize(sc_card_t *card) /* Select a coolkey read the coolkey objects out */ r = coolkey_select_applet(card); if (r < 0) { - return r; + goto cleanup; } priv->protocol_version_major = life_cycle.protocol_version_major; From 9150d92447491c0cc3ab2d099a6de7269a8127e9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Jun 2018 23:22:00 +0200 Subject: [PATCH 0347/4321] fixed out of bounds access --- src/libopensc/card-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 8fc07ed056..dc10d3dba6 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1232,7 +1232,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa int r; size_t tilen; sc_apdu_t apdu; - u8 ibuff[50], *p; + u8 ibuff[50+0xFF], *p; LOG_FUNC_CALLED(card->ctx); From 8b3f5b7d9773d8dde2b98e407bda8e768e3e5a27 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Jun 2018 23:24:36 +0200 Subject: [PATCH 0348/4321] epass2003: fixed logical error --- src/libopensc/card-epass2003.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 4594e366a5..98f9fbaef5 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1606,12 +1606,12 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, { apdu.p2 = 0xB6; exdata->currAlg = SC_ALGORITHM_EC; - if(env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA1) + if(env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) { sbuf[2] = 0x91; exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1; } - else if (env->algorithm_flags | SC_ALGORITHM_ECDSA_HASH_SHA256) + else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { sbuf[2] = 0x92; exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256; @@ -1694,7 +1694,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data if(exdata->currAlg == SC_ALGORITHM_EC) { - if(exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA1) + if(exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) { r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash_data failed"); @@ -1703,7 +1703,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data apdu.lc = 0x14; apdu.datalen = 0x14; } - else if (exdata->ecAlgFlags | SC_ALGORITHM_ECDSA_HASH_SHA256) + else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) { r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); LOG_TEST_RET(card->ctx, r, "hash_data failed"); @@ -2250,7 +2250,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign if ((NULL == data) || (NULL == hash)) return SC_ERROR_INVALID_ARGUMENTS; - if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA1) + if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) { unsigned char data_hash[24] = { 0 }; size_t len = 0; @@ -2260,7 +2260,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign memcpy(&data_hash[20], &len, 4); memcpy(hash, data_hash, 24); } - else if(mechanismType | SC_ALGORITHM_ECDSA_HASH_SHA256) + else if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256) { unsigned char data_hash[36] = { 0 }; size_t len = 0; From 9c2afad4171d866f59e56d3d4749135a9d8781b5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Jun 2018 00:56:01 +0200 Subject: [PATCH 0349/4321] fixed copy/paste error --- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-rutoken.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 9ef4b05c63..f72c2d2095 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1674,7 +1674,7 @@ authentic_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len) LOG_FUNC_CALLED(card->ctx); - r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); if (len < (size_t) r) { diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 98f9fbaef5..88fe82753d 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -2582,7 +2582,7 @@ epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len) LOG_FUNC_CALLED(card->ctx); - r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); if (len < (size_t) r) { diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 6658a3606e..1815153d32 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -1145,7 +1145,7 @@ static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t len) LOG_FUNC_CALLED(card->ctx); - r = iso_ops->get_challenge(card, rnd, sizeof rbuf); + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); if (len < (size_t) r) { From 0789961320472609c5f5d339f0d9ece07a5c3761 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Sep 2017 15:47:08 +0200 Subject: [PATCH 0350/4321] Add a badge about card status --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c06cfc1ab4..85f98f361f 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,10 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. [![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) + +Build and test status of specific cards: + +| Cards | Status | +|-----------------------|--------| +| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| Coolkey | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | From 3998fffbdcf9a2731098bcf0f72f12511f4c0042 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 21 May 2018 10:16:38 +0200 Subject: [PATCH 0351/4321] configure: Use correct variables for testsuite --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 32d064b38a..02f9d638b5 100644 --- a/configure.ac +++ b/configure.ac @@ -531,9 +531,7 @@ if test "${enable_tests}" = "detect"; then fi if test "${enable_tests}" = "yes"; then - if test "${have_cmocka}" = "yes"; then - AC_DEFINE([ENABLE_TESTS], [1], [Build tests in tests/ subdirectory]) - else + if test "${have_cmocka}" != "yes"; then AC_MSG_ERROR([Tests required, but cmocka is not available]) fi fi @@ -1021,7 +1019,7 @@ AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidrive AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"]) AM_CONDITIONAL([ENABLE_DNIE_UI], [test "${enable_dnie_ui}" = "yes"]) AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"]) -AM_CONDITIONAL([ENABLE_TESTS], [test "${ENABLE_TESTS}" = "yes"]) +AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) if test "${enable_pedantic}" = "yes"; then From f9f3bc3ae05bfb6bd302fbec47654017c157200b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Jun 2018 18:33:59 +0200 Subject: [PATCH 0352/4321] configure: Check for cmocka header file --- configure.ac | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 02f9d638b5..700b14dc88 100644 --- a/configure.ac +++ b/configure.ac @@ -518,9 +518,14 @@ if test "${enable_notify}" = "yes"; then fi fi -PKG_CHECK_MODULES( [CMOCKA], [cmocka], - [ have_cmocka="yes" ], - [ have_cmocka="no" ]) +have_cmocka="yes" +PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.1.0],,[have_cmocka="no"]) +AC_CHECK_HEADER([setjmp.h]) +AC_CHECK_HEADER([cmocka.h],, [have_cmocka="no"], +[#include +#include +#include +]) if test "${enable_tests}" = "detect"; then if test "${have_cmocka}" = "yes"; then From f392d7426f81cf381e785a15f1646ef01ef2b7aa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Jun 2018 10:56:09 +0200 Subject: [PATCH 0353/4321] Utilize autoconf variables for cmocka usage --- src/tests/p11test/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 15de3174be..5bc56cd810 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -22,8 +22,8 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_wait.c \ p11test_case_pss_oaep.c \ p11test_helpers.c -p11test_CFLAGS = -DNDEBUG -p11test_LDADD = -lssl -lcrypto -lcmocka +p11test_CFLAGS = -DNDEBUG $(CMOCKA_CFLAGS) +p11test_LDADD = -lssl -lcrypto $(CMOCKA_LDLAGS) if WIN32 p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc From 2682741293197f7d5c9cea44f1cb4f6dc9f264e5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 20 Jun 2018 12:52:17 +0200 Subject: [PATCH 0354/4321] cac: Avoid segfaults from get_challenge() --- src/libopensc/card-cac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 9f7b660cc3..0098830c8e 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -951,12 +951,13 @@ static int cac_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { /* CAC requires 8 byte response */ u8 rbuf[8]; + u8 *rbufp = &rbuf[0]; size_t out_len = sizeof rbuf; int r; LOG_FUNC_CALLED(card->ctx); - r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, (u8 **) &rbuf, &out_len); + r = cac_apdu_io(card, 0x84, 0x00, 0x00, NULL, 0, &rbufp, &out_len); LOG_TEST_RET(card->ctx, r, "Could not get challenge"); if (len < out_len) { From 5b3da5d46220d5789b8a886a5e64999915ffa4ac Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Jun 2018 09:47:16 +0200 Subject: [PATCH 0355/4321] cac: Missing memory cleanup --- src/libopensc/card-cac.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 0098830c8e..0801a54575 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1224,8 +1224,10 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: TV Object nr. %"SC_FORMAT_LEN_SIZE_T"u", i); - if (i >= CAC_MAX_OBJECTS) + if (i >= CAC_MAX_OBJECTS) { + free(rbuf); return SC_SUCCESS; + } if (cac_parse_properties_object(card, tag, val, len, &prop->objects[i]) == SC_SUCCESS) @@ -1240,8 +1242,10 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: PKI Object nr. %"SC_FORMAT_LEN_SIZE_T"u", i); - if (i >= CAC_MAX_OBJECTS) + if (i >= CAC_MAX_OBJECTS) { + free(rbuf); return SC_SUCCESS; + } if (cac_parse_properties_object(card, tag, val, len, &prop->objects[i]) == SC_SUCCESS) @@ -1255,6 +1259,7 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) break; } } + free(rbuf); /* sanity */ if (i != prop->num_objects) return SC_ERROR_INVALID_DATA; From 1f352d4c6d583afbf52f6e254c13dca6459f7438 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Jun 2018 15:21:43 +0200 Subject: [PATCH 0356/4321] muscle: Properly clean up the applet memory footprint --- src/libopensc/muscle-filesystem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 45724049ea..887bd03acc 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -53,6 +53,7 @@ mscfs_t *mscfs_new(void) { void mscfs_free(mscfs_t *fs) { mscfs_clear_cache(fs); + free(fs); } void mscfs_clear_cache(mscfs_t* fs) { From 5dcea4440e05d1ec187ff30e2372b0681054ee02 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 5 Jan 2018 13:16:05 +0100 Subject: [PATCH 0357/4321] pkcs15-tool: added support for reading NIST ssh keys 'pkcs15-tool --read-ssh-key' is now able to read NIST ECC keys from card. Only 256, 384 and 521 field lengths are supported (same as allowed in ssh-keygen -t ecdsa). Issue #803 is partialy fixed by this patch. Openssh PKCS11 interface patches for ECC are now available, please check https://bugzilla.mindrot.org/show_bug.cgi?id=2474 --- src/tools/pkcs15-tool.c | 72 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 9fef9a68b1..018015726f 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -918,9 +918,9 @@ static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object } if (obj->label[0] != '\0') - fprintf(outf,"ssh-%s %s %.*s\n", alg, uu, (int) sizeof obj->label, obj->label); + fprintf(outf,"%s %s %.*s\n", alg, uu, (int) sizeof obj->label, obj->label); else - fprintf(outf,"ssh-%s %s\n", alg, uu); + fprintf(outf,"%s %s\n", alg, uu); } free(uu); return; @@ -982,6 +982,70 @@ static int read_ssh_key(void) return 1; } + if (pubkey->algorithm == SC_ALGORITHM_EC) { + // support only for NIST + // 'ssh-keygen -t ecdsa' allow only field lengths 256/384/521 + + static struct supported_ec_curves { + char *curve_name; + struct sc_object_id curve_oid; + size_t size; + } ec_curves[] = { + {"secp256r1", {{1, 2, 840, 10045, 3, 1, 7, -1}},256}, + {"secp384r1", {{1, 3, 132, 0, 34, -1}}, 384}, + {"secp521r1", {{1, 3, 132, 0, 35, -1}}, 521}, + {NULL, {{-1}}, 0}, + }; + char alg[20]; + /* Large enough to fit the following: + * 3 x 4B item length headers + * max 20B algorithm name, 9B curve name, max 256B key data */ + unsigned char buf[300]; + unsigned int i, len, tmp, n; + + for (n = 0,i = 0; ec_curves[i].curve_name != NULL; i++) { + if(sc_compare_oid (&ec_curves[i].curve_oid,&pubkey->u.ec.params.id)) + n = ec_curves[i].size; + } + if (!n) { + fprintf(stderr, "Unsupported curve\n"); + goto fail2; + } + if (n != pubkey->u.ec.params.field_length) { + fprintf(stderr, "Wrong field length\n"); + goto fail2; + } + + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n); + strncpy(alg, (char *) buf+4, 20); + buf[3] = len; + + len += 4; + buf[len++] = 0; + buf[len++] = 0; + buf[len++] = 0; + tmp = snprintf((char *) buf+len+1, 9, "nistp%d", n); + buf[len++] = tmp; + len += tmp; + + n = pubkey->u.ec.ecpointQ.len; + if(n > 255) { + fprintf(stderr, "Wrong public key length\n"); + goto fail2; + } + buf[len++] = 0; + buf[len++] = 0; + buf[len++] = 0; + buf[len++] = n & 0xff; + memcpy(buf+len,pubkey->u.ec.ecpointQ.value,n); + len += n; + + print_ssh_key(outf, alg, obj, buf, len); + } + if (pubkey->algorithm == SC_ALGORITHM_RSA) { unsigned char buf[2048]; uint32_t len, n; @@ -1034,7 +1098,7 @@ static int read_ssh_key(void) memcpy(buf+len,pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len); len += pubkey->u.rsa.modulus.len; - print_ssh_key(outf, "rsa", obj, buf, len); + print_ssh_key(outf, "ssh-rsa", obj, buf, len); } if (pubkey->algorithm == SC_ALGORITHM_DSA) { @@ -1125,7 +1189,7 @@ static int read_ssh_key(void) memcpy(buf+len,pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len); len += pubkey->u.dsa.pub.len; - print_ssh_key(outf, "dss", obj, buf, len); + print_ssh_key(outf, "ssh-dss", obj, buf, len); } if (outf != stdout) From d831076974f02dc7714f92526e6352ab18aee748 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Jun 2018 08:47:06 +0200 Subject: [PATCH 0358/4321] opensc-notify: use generic icon fixes https://github.com/OpenSC/OpenSC/issues/1402 --- src/tools/org.opensc.notify.desktop.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/org.opensc.notify.desktop.in b/src/tools/org.opensc.notify.desktop.in index 3f9a1dd103..20e217d6de 100644 --- a/src/tools/org.opensc.notify.desktop.in +++ b/src/tools/org.opensc.notify.desktop.in @@ -3,6 +3,6 @@ Name=OpenSC Notify Type=Application Comment=Monitor smart card events to send notifications. Exec=@bindir@/opensc-notify -Icon=preferences-system-notifications +Icon=utilities-system-monitor Categories=Security;System; NoDisplay=true From 1ca1a024dfe9400ebbf6fd3dc23cfc5006c5d89f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Jun 2018 09:23:00 +0200 Subject: [PATCH 0359/4321] card-npa: fixed memory leak fixes https://github.com/OpenSC/OpenSC/issues/1396 --- src/libopensc/card-npa.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 47644ca0c2..8a5f83c29f 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -351,6 +351,18 @@ static int npa_unlock_esign(sc_card_t *card) return r; } +static int npa_finish(sc_card_t * card) +{ + sc_sm_stop(card); + npa_drv_data_free(card->drv_data); + card->drv_data = NULL; +#ifdef ENABLE_OPENPACE + EAC_cleanup(); +#endif + + return SC_SUCCESS; +} + static int npa_init(sc_card_t * card) { int flags = SC_ALGORITHM_ECDSA_RAW; @@ -392,6 +404,7 @@ static int npa_init(sc_card_t * card) #endif card->drv_data = npa_drv_data_create(); if (!card->drv_data) { + npa_finish(card); r = SC_ERROR_OUT_OF_MEMORY; goto err; } @@ -409,18 +422,6 @@ static int npa_init(sc_card_t * card) return r; } -static int npa_finish(sc_card_t * card) -{ - sc_sm_stop(card); - npa_drv_data_free(card->drv_data); - card->drv_data = NULL; -#ifdef ENABLE_OPENPACE - EAC_cleanup(); -#endif - - return SC_SUCCESS; -} - static int npa_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) { From 2818e0f703103d1e336888b6f23039265a0a3f65 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 9 Jun 2018 18:29:28 +0200 Subject: [PATCH 0360/4321] iso7816: update & extend error codes While at it, do some space policing. --- src/libopensc/iso7816.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index ba0680eed6..c884e4004a 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -57,10 +57,15 @@ static const struct sc_card_error iso7816_errors[] = { { 0x6282, SC_ERROR_FILE_END_REACHED, "End of file/record reached before reading Le bytes" }, { 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" }, { 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" }, + { 0x6285, SC_ERROR_CARD_CMD_FAILED, "Selected file in termination state" }, + { 0x6286, SC_ERROR_CARD_CMD_FAILED, "No input data available from a sensori on the card" }, { 0x6300, SC_ERROR_CARD_CMD_FAILED, "Warning: no information given, non-volatile memory has changed" }, { 0x6381, SC_ERROR_CARD_CMD_FAILED, "Warning: file filled up by last write" }, + { 0x6400, SC_ERROR_CARD_CMD_FAILED, "Execution error" }, + { 0x6401, SC_ERROR_CARD_CMD_FAILED, "Immediate response required by the card" }, + { 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure" }, { 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" }, @@ -68,37 +73,36 @@ static const struct sc_card_error iso7816_errors[] = { { 0x6800, SC_ERROR_NO_CARD_SUPPORT, "Functions in CLA not supported" }, { 0x6881, SC_ERROR_NO_CARD_SUPPORT, "Logical channel not supported" }, { 0x6882, SC_ERROR_NO_CARD_SUPPORT, "Secure messaging not supported" }, + { 0x6883, SC_ERROR_CARD_CMD_FAILED, "Last command of the chain expected" }, + { 0x6884, SC_ERROR_NO_CARD_SUPPORT, "Command chaining not supported" }, { 0x6900, SC_ERROR_NOT_ALLOWED, "Command not allowed" }, { 0x6981, SC_ERROR_CARD_CMD_FAILED, "Command incompatible with file structure" }, - { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" }, + { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED,"Security status not satisfied" }, { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" }, { 0x6984, SC_ERROR_REF_DATA_NOT_USABLE, "Referenced data not usable" }, { 0x6985, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" }, { 0x6986, SC_ERROR_NOT_ALLOWED, "Command not allowed (no current EF)" }, { 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" }, - { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"SM data objects incorrect" }, + { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect SM data objects" }, { 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" }, { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" }, { 0x6A81, SC_ERROR_NO_CARD_SUPPORT, "Function not supported" }, - { 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File not found" }, + { 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File or application not found" }, { 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" }, { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory space in the file" }, { 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" }, { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" }, { 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" }, { 0x6A88, SC_ERROR_DATA_OBJECT_NOT_FOUND,"Referenced data not found" }, - { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS, "File already exists"}, - { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS, "DF name already exists"}, + { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS, "File already exists"}, + { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS, "DF name already exists"}, { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" }, { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Instruction code not supported or invalid" }, { 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" }, { 0x6F00, SC_ERROR_CARD_CMD_FAILED, "No precise diagnosis" }, - - - }; From 0603c3b7fcd2cda77d5f66ce370255b7bcd2d430 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 15 Jun 2018 06:55:59 +0200 Subject: [PATCH 0361/4321] iso7816: fix typo in previous commit --- src/libopensc/iso7816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index c884e4004a..718d92ff79 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -58,7 +58,7 @@ static const struct sc_card_error iso7816_errors[] = { { 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" }, { 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" }, { 0x6285, SC_ERROR_CARD_CMD_FAILED, "Selected file in termination state" }, - { 0x6286, SC_ERROR_CARD_CMD_FAILED, "No input data available from a sensori on the card" }, + { 0x6286, SC_ERROR_CARD_CMD_FAILED, "No input data available from a sensor on the card" }, { 0x6300, SC_ERROR_CARD_CMD_FAILED, "Warning: no information given, non-volatile memory has changed" }, { 0x6381, SC_ERROR_CARD_CMD_FAILED, "Warning: file filled up by last write" }, From 31cbf837386fa16280223637e797ae9a6575f466 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Fri, 22 Jun 2018 22:21:03 +0300 Subject: [PATCH 0362/4321] build: support >=libressl-2.7 --- src/libopensc/sc-ossl-compat.h | 23 +++++++++++++---------- src/tools/sc-hsm-tool.c | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 9801cf525b..8ef5a9468a 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -90,23 +90,26 @@ extern "C" { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) #define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay -#define OPENSSL_malloc_init CRYPTO_malloc_init -#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) -#define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec) -#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa) #define X509_get_extension_flags(x) (x->ex_flags) #define X509_get_key_usage(x) (x->ex_kusage) #define X509_get_extended_key_usage(x) (x->ex_xkusage) -#define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY) #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2050300fL #define X509_up_ref(cert) CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509) #endif +#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x20700000L +#define OPENSSL_malloc_init CRYPTO_malloc_init +#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) +#define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec) +#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa) +#define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY) +#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) +#endif #endif -/* ASN1_STRING_data is deprecated in OpenSSL 1.1.0 */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) +/* workaround unused value warning for a macro that does nothing */ +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L +#define OPENSSL_malloc_init() #endif /* @@ -116,7 +119,7 @@ extern "C" { * If that is not good enough, versions could be added to libopensc */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) /* based on OpenSSL-1.1.0 e_os2.h */ /* sc_ossl_inline: portable inline definition usable in public headers */ # if !defined(inline) && !defined(__cplusplus) @@ -135,7 +138,7 @@ extern "C" { # endif #endif -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2050300fL) #define RSA_bits(R) (BN_num_bits(R->n)) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 3802eeea96..8c9431ade1 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1761,7 +1761,7 @@ int main(int argc, char *argv[]) } } -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !(defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER >= 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L) OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, From 0e9565754c6517c49c50c020b21d03e136c666e7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 13:37:46 +0200 Subject: [PATCH 0363/4321] avoid uninitialized output after sc_file_dup --- src/libopensc/sc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 62e4a2ea3e..af71cafa9b 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -578,9 +578,9 @@ void sc_file_dup(sc_file_t **dest, const sc_file_t *src) const sc_acl_entry_t *e; unsigned int op; + *dest = NULL; if (!sc_file_valid(src)) return; - *dest = NULL; newf = sc_file_new(); if (newf == NULL) return; From 5f39d7ab745aeff8aa6df75ac1ed102278ad6359 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 13:45:29 +0200 Subject: [PATCH 0364/4321] use correct length of binary ATR --- src/tools/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/util.c b/src/tools/util.c index 40f77677e0..6b8743e2d0 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -102,7 +102,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, else { /* If the reader identifier looks like an ATR, try to find the reader with that card */ if (is_string_valid_atr(reader_id)) { - unsigned char atr_buf[SC_MAX_ATR_SIZE * 3]; + unsigned char atr_buf[SC_MAX_ATR_SIZE]; size_t atr_buf_len = sizeof(atr_buf); unsigned int i; From 6819759946aecd4541ec90b18deff3c7c1a5dad1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:21:05 +0200 Subject: [PATCH 0365/4321] fixed memory leak --- src/libopensc/card-iasecc.c | 24 +++++++++++++----------- src/pkcs15init/pkcs15-authentic.c | 14 ++++++++------ src/pkcs15init/pkcs15-oberthur-awp.c | 11 ++++++----- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index d23404021e..9f21812dee 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -2122,20 +2122,20 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) if (card->cache.valid && card->cache.current_df) { sc_file_dup(&save_current_df, card->cache.current_df); if (save_current_df == NULL) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file"); } if (card->cache.valid && card->cache.current_ef) { sc_file_dup(&save_current_ef, card->cache.current_ef); if (save_current_ef == NULL) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current EF file"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current EF file"); } if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && card->cache.valid && card->cache.current_df) { sc_format_path("3F00", &path); path.type = SC_PATH_TYPE_FILE_ID; rv = iasecc_select_file(card, &path, NULL); - LOG_TEST_RET(ctx, rv, "Unable to select MF"); + LOG_TEST_GOTO_ERR(ctx, rv, "Unable to select MF"); } memset(&sdo, 0, sizeof(sdo)); @@ -2146,10 +2146,10 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) sc_log(ctx, "iasecc_pin_get_policy() reference %i", sdo.sdo_ref); rv = iasecc_sdo_get_data(card, &sdo); - LOG_TEST_RET(ctx, rv, "Cannot get SDO PIN data"); + LOG_TEST_GOTO_ERR(ctx, rv, "Cannot get SDO PIN data"); if (sdo.docp.acls_contact.size == 0) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Extremely strange ... there is no ACLs"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Extremely strange ... there is no ACLs"); sc_log(ctx, "iasecc_pin_get_policy() sdo.docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", @@ -2177,13 +2177,13 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) se.reference = acl->key_ref; rv = iasecc_se_get_info(card, &se); - LOG_TEST_RET(ctx, rv, "SDO get data error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO get data error"); } if (scb & IASECC_SCB_METHOD_USER_AUTH) { rv = iasecc_se_get_crt_by_usage(card, &se, IASECC_CRT_TAG_AT, IASECC_UQB_AT_USER_PASSWORD, &acl->crts[crt_num]); - LOG_TEST_RET(ctx, rv, "no authentication template for 'USER PASSWORD'"); + LOG_TEST_GOTO_ERR(ctx, rv, "no authentication template for 'USER PASSWORD'"); sc_log(ctx, "iasecc_pin_get_policy() scb:0x%X; sdo_ref:[%i,%i,...]", scb, acl->crts[crt_num].refs[0], acl->crts[crt_num].refs[1]); crt_num++; @@ -2227,17 +2227,19 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) if (save_current_df) { sc_log(ctx, "iasecc_pin_get_policy() restore current DF"); rv = iasecc_select_file(card, &save_current_df->path, NULL); - LOG_TEST_RET(ctx, rv, "Cannot return to saved DF"); - sc_file_free(save_current_df); + LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved DF"); } if (save_current_ef) { sc_log(ctx, "iasecc_pin_get_policy() restore current EF"); rv = iasecc_select_file(card, &save_current_ef->path, NULL); - LOG_TEST_RET(ctx, rv, "Cannot return to saved EF"); - sc_file_free(save_current_ef); + LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved EF"); } +err: + sc_file_free(save_current_df); + sc_file_free(save_current_ef); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index af1110fafe..ddccd03256 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -560,20 +560,20 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p p15card->card->caps &= ~SC_CARD_CAP_USE_FCI_AC; rv = sc_pkcs15init_authenticate(profile, p15card, file_p_prvkey, SC_AC_OP_DELETE); p15card->card->caps = caps; - LOG_TEST_RET(ctx, rv, "SC_AC_OP_CRYPTO authentication failed for parent DF"); + LOG_TEST_GOTO_ERR(ctx, rv, "SC_AC_OP_CRYPTO authentication failed for parent DF"); rv = sc_card_ctl(card, SC_CARDCTL_AUTHENTIC_SDO_DELETE, sdo); - LOG_TEST_RET(ctx, rv, "SC_CARDCTL_AUTHENTIC_SDO_DELETE failed for private key"); + LOG_TEST_GOTO_ERR(ctx, rv, "SC_CARDCTL_AUTHENTIC_SDO_DELETE failed for private key"); rv = sc_card_ctl(card, SC_CARDCTL_AUTHENTIC_SDO_CREATE, sdo); } - LOG_TEST_RET(ctx, rv, "SC_CARDCTL_AUTHENTIC_SDO_CREATE failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "SC_CARDCTL_AUTHENTIC_SDO_CREATE failed"); rv = authentic_pkcs15_fix_access(p15card, file_p_prvkey, object); - LOG_TEST_RET(ctx, rv, "cannot fix access rules for private key"); + LOG_TEST_GOTO_ERR(ctx, rv, "cannot fix access rules for private key"); rv = authentic_pkcs15_fix_usage(p15card, object); - LOG_TEST_RET(ctx, rv, "cannot fix access rules for private key"); + LOG_TEST_GOTO_ERR(ctx, rv, "cannot fix access rules for private key"); /* Here fix the key's supported algorithms, if these ones will be implemented * (see src/libopensc/pkcs15-prkey.c). @@ -583,8 +583,10 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p sc_log(ctx, "sdo->file:%p", sdo->file); rv = sc_pkcs15_allocate_object_content(ctx, object, (unsigned char *)sdo, sizeof(struct sc_authentic_sdo)); - LOG_TEST_RET(ctx, rv, "Failed to allocate PrvKey SDO as object content"); + LOG_TEST_GOTO_ERR(ctx, rv, "Failed to allocate PrvKey SDO as object content"); +err: + free(sdo); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 4daf0ff0c5..f9c96373cb 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1387,25 +1387,26 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Cert Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_cert_info(p15card, obj, &icert); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot encode info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot encode info"); rv = awp_set_certificate_info(p15card, profile, info_file, &icert); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot set info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot set info"); rv = awp_update_object_list(p15card, profile, SC_PKCS15_TYPE_CERT_X509, obj_id & 0xFF); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update list"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update list"); rv = awp_update_container(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &icert.id, obj_id, &prvkey_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update container"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update container"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PrvKeyID:%04X", prvkey_id); if (prvkey_id) rv = awp_update_key_info(p15card, profile, prvkey_id, &icert); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update key info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update key info"); awp_free_cert_info(&icert); +err: sc_file_free(info_file); sc_file_free(obj_file); From c026f37677ddd88adfead615ce51258bf6a5ef09 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:27:44 +0200 Subject: [PATCH 0366/4321] warn about error in sc_enumerate_apps --- src/pkcs15init/pkcs15-lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index fd4e14e2dc..e05842b588 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -734,8 +734,8 @@ sc_pkcs15init_finalize_profile(struct sc_card *card, struct sc_profile *profile, int rv; LOG_FUNC_CALLED(ctx); - if (card->app_count < 0) - sc_enum_apps(card); + if (card->app_count < 0 && SC_SUCCESS != sc_enum_apps(card)) + sc_log(ctx, "Could not enumerate apps"); if (aid) { sc_log(ctx, "finalize profile for AID %s", sc_dump_hex(aid->value, aid->len)); From 259b7ec41c970bb88443b19fbd8675eef9a3d3f1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:29:09 +0200 Subject: [PATCH 0367/4321] check return value --- src/pkcs15init/pkcs15-oberthur.c | 2 ++ src/pkcs15init/pkcs15-westcos.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 8ef541dd44..d6f16b1601 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -183,6 +183,8 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file ddf %04X",df->id); cosm_delete_file(p15card, profile, df); + if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) + goto done; if (sc_profile_get_file(profile, "private-DF", &dir) >= 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file dir %04X",dir->id); diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 2eaac6477f..b6d98a3ca5 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -60,7 +60,8 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile, int r; /* Create the application DF */ - sc_pkcs15init_create_file(profile, p15card, df); + r = sc_pkcs15init_create_file(profile, p15card, df); + if(r) return r; r = sc_select_file(p15card->card, &df->path, NULL); if(r) return r; From ed0d829eab249b378abe1977bee4a600a14e3ec2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:51:42 +0200 Subject: [PATCH 0368/4321] removed unused check --- src/libopensc/card-mcrd.c | 2 +- src/tools/pkcs15-tool.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 09edd87e4e..16cb999222 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1377,7 +1377,7 @@ static int mcrd_compute_signature(sc_card_t * card, int r; sc_apdu_t apdu; - if (card == NULL || data == NULL || out == NULL) + if (data == NULL || out == NULL) return SC_ERROR_INVALID_ARGUMENTS; env = &priv->sec_env; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 018015726f..7601bca41a 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -823,7 +823,7 @@ static int read_public_key(void) out: if (cert) sc_pkcs15_free_certificate(cert); - else if (pubkey) + else sc_pkcs15_free_pubkey(pubkey); return r; @@ -1196,7 +1196,7 @@ static int read_ssh_key(void) fclose(outf); if (cert) sc_pkcs15_free_certificate(cert); - else if (pubkey) + else sc_pkcs15_free_pubkey(pubkey); return 0; fail: @@ -1206,7 +1206,7 @@ static int read_ssh_key(void) fclose(outf); if (cert) sc_pkcs15_free_certificate(cert); - else if (pubkey) + else sc_pkcs15_free_pubkey(pubkey); return SC_ERROR_OUT_OF_MEMORY; } From 03c52806268a79e6666b0dc8d1541bc343af73f8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:41:13 +0200 Subject: [PATCH 0369/4321] avoid NULL dereference --- src/tools/gids-tool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index c0e44a44de..cdee57459f 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -345,7 +345,9 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti if (datasize > *responselen) { return SC_ERROR_BUFFER_TOO_SMALL; } - memcpy(response, p, datasize); + if (response) { + memcpy(response, p, datasize); + } *responselen = datasize; return SC_SUCCESS; } From 6184c1fbabe87af196e7ff1a3e76630aee572669 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 14:47:05 +0200 Subject: [PATCH 0370/4321] avoid out of bounds read --- src/libopensc/card-piv.c | 2 +- src/libopensc/muscle.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index e2a6eeedde..e85dfc45f5 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -898,7 +898,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, goto err; } memcpy(*buf, tagbuf, len); /* copy first or only part */ - if (rbuflen > len) { + if (rbuflen > len + sizeof(tagbuf)) { len = read(f, *buf + sizeof(tagbuf), rbuflen - sizeof(tagbuf)); /* read rest */ if (len != rbuflen - sizeof(tagbuf)) { r = SC_ERROR_INVALID_ASN1_OBJECT; diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 311edd9016..36139be4c2 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -617,6 +617,8 @@ int msc_extract_rsa_public_key(sc_card_t *card, if(!*modulus) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); memcpy(*modulus, buffer, *modLength); *expLength = (buffer[*modLength] << 8) | buffer[*modLength + 1]; + if (*expLength > sizeof buffer) + return SC_ERROR_OUT_OF_MEMORY; r = msc_read_object(card, inputId, fileLocation, buffer, *expLength); if(r < 0) { free(*modulus); *modulus = NULL; From 971dac2f78d99df87c2c811714f3894651096acd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 15:03:41 +0200 Subject: [PATCH 0371/4321] unignore result --- src/libopensc/card-asepcos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 51737b5b40..8055073cd7 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -1019,6 +1019,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, if ((apdu.sw2 & 0xF0) == 0xC0 && tries_left != NULL) *tries_left = apdu.sw2 & 0x0F; r = SC_ERROR_PIN_CODE_INCORRECT; + return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); } From b3e3ab61c02f7e99306a5555993baba4ceb58311 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Jun 2018 15:15:38 +0200 Subject: [PATCH 0372/4321] avoid integer underflow --- src/tools/pkcs11-tool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d97683bcaa..84e6bf5d4c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4687,7 +4687,8 @@ static int test_signature(CK_SESSION_HANDLE sess) data[0] = 0x00; data[1] = 0x01; memset(data + 2, 0xFF, dataLen - 3 - dataLens[1]); - data[dataLen - 36] = 0x00; + if (dataLen >= 36) + data[dataLen - 36] = 0x00; memcpy(data + (dataLen - dataLens[1]), datas[1], dataLens[1]); datas[0] = data; dataLens[0] = dataLen; From 452e1d3b9648eef7f2e426997f9b4e21d243a560 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Jun 2018 01:15:57 +0200 Subject: [PATCH 0373/4321] fixed used of uninitialized return value --- src/libopensc/card-iasecc.c | 21 +++++++++++++++------ src/pkcs15init/pkcs15-oberthur.c | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 9f21812dee..3e0d3acd9e 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -2121,14 +2121,20 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) if (card->cache.valid && card->cache.current_df) { sc_file_dup(&save_current_df, card->cache.current_df); - if (save_current_df == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file"); + if (save_current_df == NULL) { + rv = SC_ERROR_OUT_OF_MEMORY; + sc_log(ctx, "Cannot duplicate current DF file"); + goto err; + } } if (card->cache.valid && card->cache.current_ef) { sc_file_dup(&save_current_ef, card->cache.current_ef); - if (save_current_ef == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current EF file"); + if (save_current_ef == NULL) { + rv = SC_ERROR_OUT_OF_MEMORY; + sc_log(ctx, "Cannot duplicate current EF file"); + goto err; + } } if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && card->cache.valid && card->cache.current_df) { @@ -2148,8 +2154,11 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data) rv = iasecc_sdo_get_data(card, &sdo); LOG_TEST_GOTO_ERR(ctx, rv, "Cannot get SDO PIN data"); - if (sdo.docp.acls_contact.size == 0) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Extremely strange ... there is no ACLs"); + if (sdo.docp.acls_contact.size == 0) { + rv = SC_ERROR_INVALID_DATA; + sc_log(ctx, "Extremely strange ... there is no ACLs"); + goto err; + } sc_log(ctx, "iasecc_pin_get_policy() sdo.docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index d6f16b1601..a6cfc35a8b 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -182,7 +182,7 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file ddf %04X",df->id); - cosm_delete_file(p15card, profile, df); + rv = cosm_delete_file(p15card, profile, df); if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) goto done; From 155ecc11f39eba70a5a10b30d760cd5333ffd00b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Jul 2018 22:41:24 +0200 Subject: [PATCH 0374/4321] Adjust the p11test readme after merge Resolves: #1415 --- src/tests/p11test/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/p11test/README.md b/src/tests/p11test/README.md index bcf9a58ddf..9c44fe190a 100644 --- a/src/tests/p11test/README.md +++ b/src/tests/p11test/README.md @@ -10,9 +10,8 @@ using [`cmocka`](https://cmocka.org/) unit testing framework Build OpenSC from source: - git clone git@github.com:Jakuje/OpenSC.git + git clone git@github.com:OpenSC/OpenSC.git cd OpenSC - git checkout jjelen-testsuite # not in master yet ./bootstrap ./configure make -j4 From b0a20fa7ca30dc6c6198954fadc5a7fe812834dc Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Fri, 22 Jun 2018 16:38:38 +0200 Subject: [PATCH 0375/4321] Use correct bash-completion path Recent versions of bash is leaving /etc/bash_completion.d. The correct directory is specified by pkg-config --variable completionsdir bash-completion. Fixes https://github.com/OpenSC/OpenSC/issues/1403 --- configure.ac | 4 ++++ doc/tools/Makefile.am | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 700b14dc88..6abad0b779 100644 --- a/configure.ac +++ b/configure.ac @@ -839,6 +839,10 @@ if test "${enable_cryptotokenkit}" = "yes"; then fi AC_DEFINE([ENABLE_CRYPTOTOKENKIT], [1], [Define if CryptoTokenKit is to be enabled]) fi +PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], + [completiondir="`pkg-config --variable=completionsdir bash-completion`"], + [completiondir="${sysconfdir}/bash_completion.d"]) +AC_SUBST([completiondir]) AC_SUBST(DYN_LIB_EXT) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 17e4fbf125..4e2d941cc1 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -15,7 +15,6 @@ man5_MANS = $(patsubst $(srcdir)/%.xml, %, $(wildcard $(srcdir)/*.5.xml)) endif completion_DATA = $(patsubst $(srcdir)/%.1.xml, %, $(wildcard $(srcdir)/*.1.xml)) -completiondir = $(sysconfdir)/bash_completion.d tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdir)/*.5.xml) $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< From 4db9db7403cd5c49efc97ce6eac4ab5b4cd46e66 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 27 Jun 2018 21:20:04 +0200 Subject: [PATCH 0376/4321] Add GenericName to the desktop file Add optional GenericName to org.opensc.notify.desktop. GenericName is recently widely used for menu rendering in desktop environments. --- src/tools/org.opensc.notify.desktop.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/org.opensc.notify.desktop.in b/src/tools/org.opensc.notify.desktop.in index 20e217d6de..1c8755c410 100644 --- a/src/tools/org.opensc.notify.desktop.in +++ b/src/tools/org.opensc.notify.desktop.in @@ -1,5 +1,6 @@ [Desktop Entry] Name=OpenSC Notify +GenericName=Smard card notification Type=Application Comment=Monitor smart card events to send notifications. Exec=@bindir@/opensc-notify From 88de66bb1301985b9187922a0c765dcdaed057d2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 3 Jul 2018 09:31:56 +0200 Subject: [PATCH 0377/4321] fixed `make distcheck` --- doc/tools/Makefile.am | 1 + src/tools/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 4e2d941cc1..276c7d649e 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = completion-template TESTS = test-manpage.sh +dist_noinst_SCRIPTS = test-manpage.sh dist_noinst_DATA = $(wildcard $(srcdir)/*.xml) if ENABLE_DOC diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 378bab3c3b..63cafb4839 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -177,4 +177,4 @@ org.opensc.notify.desktop: org.opensc.notify.desktop.in $(do_subst) < $(abs_srcdir)/org.opensc.notify.desktop.in > $@ clean-local: - rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo + rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop From a6b4605b863d45978ebd681c4bbaa3aaf0ab90e7 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Tue, 10 Jul 2018 14:49:42 +0200 Subject: [PATCH 0378/4321] card-piv.c: initialize variable to fix a ppc64el build failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a build failure with optimized ppc64el and new gcc builds card-piv.c: In function ‘piv_validate_general_authentication.isra.3’: card-piv.c:2390:9: error: ‘rbuflen’ may be used uninitialized in this function [-Werror=maybe-uninitialized] body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7c, &bodylen); ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index e85dfc45f5..13b0cc21c5 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2334,7 +2334,7 @@ static int piv_validate_general_authentication(sc_card_t *card, u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ u8 *rbuf = NULL; - size_t rbuflen; + size_t rbuflen = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); From 0ceef8778b51ebd0e433ca8dc318ce17ab2ee507 Mon Sep 17 00:00:00 2001 From: Sean Enck Date: Fri, 6 Jul 2018 15:29:26 -0400 Subject: [PATCH 0379/4321] Fixes #1421, when a tool has no OPTSWITHARGS it will produce invalid bash (completion) output syntax --- doc/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 276c7d649e..b2b39b6f1f 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -36,7 +36,7 @@ tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdi | sort -u | grep -- '^\-' | tr '\n' ' ')," \ | sed "s,OPTSWITHARGS,\ $(shell sed -n 's,.*.*.*,\1,pg' $< \ - | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,')," \ + | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,' | grep ^ || echo "!*")," \ | sed "s,FILEOPTS,\ $(shell sed -n 's,.*.*.*filename.*,\1,pg' $< \ | sort -u | grep -- '^\-' | tr '\n' '|' | sed 's,|$$,,' | grep ^ || echo "!*")," \ From 99fa4f4a57c6bac85bd68ea748570723da3d6023 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 1 Jul 2018 13:40:26 +0200 Subject: [PATCH 0380/4321] pkcs15-tool: harmonize non-short output for -C, -D, Make sure to have an empty line between information printed for individual objects, but not in short mode. This makes output of -D and -C more consistent. --- src/tools/pkcs15-tool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 7601bca41a..3316135777 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -570,6 +570,8 @@ static int list_data_objects(void) else { printf("\tAuth ID: %s\n", sc_pkcs15_print_id(&objs[i]->auth_id)); } + + printf("\n"); } return 0; } @@ -1672,7 +1674,7 @@ static void list_info(void) count++; } } - printf("\n"); + printf((compact) ? "\n" : "\n\n"); } static int dump(void) From e2f0e367b19c70343e60fb7a1fec7c36e2655445 Mon Sep 17 00:00:00 2001 From: Leif Erik Wagner Date: Tue, 5 Jun 2018 16:30:05 +0200 Subject: [PATCH 0381/4321] Implement RSA PSS for GoID / SmartCard-HSM --- src/libopensc/card-sc-hsm.c | 4 +++- src/libopensc/card-sc-hsm.h | 1 + src/libopensc/opensc.h | 39 ++++++++++++++++++----------------- src/libopensc/padding.c | 5 +++++ src/libopensc/pkcs15-sec.c | 12 +++++++---- src/pkcs11/framework-pkcs15.c | 27 ++++++++++++++++++++++++ src/tools/opensc-tool.c | 1 + 7 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index dc10d3dba6..0d8c91f453 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -984,6 +984,8 @@ static int sc_hsm_set_security_env(sc_card_t *card, } else { priv->algorithm = ALGO_RSA_PKCS1; } + } else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) { + priv->algorithm = ALGO_RSA_PSS; } else { if (env->operation == SC_SEC_OPERATION_DECIPHER) { priv->algorithm = ALGO_RSA_DECRYPT; @@ -1607,7 +1609,7 @@ static int sc_hsm_init(struct sc_card *card) card->drv_data = priv; } - flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_ONBOARD_KEY_GEN; + flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN; _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); diff --git a/src/libopensc/card-sc-hsm.h b/src/libopensc/card-sc-hsm.h index 0a4fb3b792..c9b3281572 100644 --- a/src/libopensc/card-sc-hsm.h +++ b/src/libopensc/card-sc-hsm.h @@ -38,6 +38,7 @@ #define ALGO_RSA_PKCS1_SHA1 0x31 /* RSA signature with SHA-1 hash and PKCS#1 V1.5 padding */ #define ALGO_RSA_PKCS1_SHA256 0x33 /* RSA signature with SHA-256 hash and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PSS 0x40 /* RSA signature with external hash and PKCS#1 PSS padding*/ #define ALGO_RSA_PSS_SHA1 0x41 /* RSA signature with SHA-1 hash and PKCS#1 PSS padding */ #define ALGO_RSA_PSS_SHA256 0x43 /* RSA signature with SHA-256 hash and PKCS#1 PSS padding */ diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 25950ff552..7f6f6554d9 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -91,34 +91,35 @@ extern "C" { #define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000 /* need usage = either sign or decrypt. keys with both? decrypt, emulate sign */ #define SC_ALGORITHM_NEED_USAGE 0x40000000 -#define SC_ALGORITHM_SPECIFIC_FLAGS 0x0001FFFF +#define SC_ALGORITHM_SPECIFIC_FLAGS 0x001FFFFF #define SC_ALGORITHM_RSA_RAW 0x00000001 /* If the card is willing to produce a cryptogram padded with the following * methods, set these flags accordingly. */ -#define SC_ALGORITHM_RSA_PADS 0x0000000E +#define SC_ALGORITHM_RSA_PADS 0x0000001E #define SC_ALGORITHM_RSA_PAD_NONE 0x00000000 #define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 +#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* If the card is willing to produce a cryptogram with the following * hash values, set these flags accordingly. */ -#define SC_ALGORITHM_RSA_HASH_NONE 0x00000010 -#define SC_ALGORITHM_RSA_HASH_SHA1 0x00000020 -#define SC_ALGORITHM_RSA_HASH_MD5 0x00000040 -#define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000080 -#define SC_ALGORITHM_RSA_HASH_RIPEMD160 0x00000100 -#define SC_ALGORITHM_RSA_HASH_SHA256 0x00000200 -#define SC_ALGORITHM_RSA_HASH_SHA384 0x00000400 -#define SC_ALGORITHM_RSA_HASH_SHA512 0x00000800 -#define SC_ALGORITHM_RSA_HASH_SHA224 0x00001000 -#define SC_ALGORITHM_RSA_HASHES 0x00001FE0 - -#define SC_ALGORITHM_GOSTR3410_RAW 0x00002000 -#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00004000 -#define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00008000 -#define SC_ALGORITHM_GOSTR3410_HASHES 0x00008000 +#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 +#define SC_ALGORITHM_RSA_HASH_SHA1 0x00000200 +#define SC_ALGORITHM_RSA_HASH_MD5 0x00000400 +#define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000800 +#define SC_ALGORITHM_RSA_HASH_RIPEMD160 0x00001000 +#define SC_ALGORITHM_RSA_HASH_SHA256 0x00002000 +#define SC_ALGORITHM_RSA_HASH_SHA384 0x00004000 +#define SC_ALGORITHM_RSA_HASH_SHA512 0x00008000 +#define SC_ALGORITHM_RSA_HASH_SHA224 0x00010000 +#define SC_ALGORITHM_RSA_HASHES 0x0001FE00 + +#define SC_ALGORITHM_GOSTR3410_RAW 0x00020000 +#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00040000 +#define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00080000 +#define SC_ALGORITHM_GOSTR3410_HASHES 0x00080000 /*TODO: -DEE Should the above be 0x0000E000 */ /* Or should the HASH_NONE be 0x00000010 and HASHES be 0x00008010 */ @@ -126,8 +127,8 @@ extern "C" { /* TODO: -DEE Will overload RSA_HASHES with EC_HASHES */ /* Not clear if these need their own bits or not */ /* The PIV card does not support and hashes */ -#define SC_ALGORITHM_ECDSA_RAW 0x00010000 -#define SC_ALGORITHM_ECDH_CDH_RAW 0x00020000 +#define SC_ALGORITHM_ECDSA_RAW 0x00100000 +#define SC_ALGORITHM_ECDH_CDH_RAW 0x00200000 #define SC_ALGORITHM_ECDSA_HASH_NONE SC_ALGORITHM_RSA_HASH_NONE #define SC_ALGORITHM_ECDSA_HASH_SHA1 SC_ALGORITHM_RSA_HASH_SHA1 #define SC_ALGORITHM_ECDSA_HASH_SHA224 SC_ALGORITHM_RSA_HASH_SHA224 diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 25ee300696..f544e57782 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -310,6 +310,11 @@ int sc_get_encoding_flags(sc_context_t *ctx, *sflags |= (caps & SC_ALGORITHM_RAW_MASK); /* adds in the one raw type */ *pflags = 0; + } else if (iflags & SC_ALGORITHM_RSA_PAD_PSS) { + if (caps & SC_ALGORITHM_RSA_PAD_PSS) + *sflags |= SC_ALGORITHM_RSA_PAD_PSS; + else + *pflags |= SC_ALGORITHM_RSA_PAD_PSS; } else { LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported algorithm"); } diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 4219bbd36b..a508cc7b53 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -420,12 +420,16 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* add the padding bytes (if necessary) */ if (pad_flags != 0) { - size_t tmplen = sizeof(buf); + if (flags & SC_ALGORITHM_RSA_PAD_PSS) { + // TODO PSS padding + } else { + size_t tmplen = sizeof(buf); - r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); + r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); - inlen = tmplen; + inlen = tmplen; + } } else if ( senv.algorithm == SC_ALGORITHM_RSA && (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3dba9b34c1..7a11fa46e9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3728,6 +3728,15 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, case CKM_SHA512_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512; break; + case CKM_RSA_PKCS_PSS: + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_NONE; + break; + case CKM_SHA1_RSA_PKCS_PSS: + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA1; + break; + case CKM_SHA256_RSA_PKCS_PSS: + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA256; + break; case CKM_RIPEMD160_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160; break; @@ -4995,6 +5004,24 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* TODO support other padding mechanisms */ + if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); + if (rc != CKR_OK) + return rc; + } + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); + if (rc != CKR_OK) + return rc; + } + } + if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_GENERATE_KEY_PAIR; mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, &mech_info, CKK_RSA, NULL, NULL); diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 46886d39fe..68c72805ea 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -591,6 +591,7 @@ static int list_algorithms(void) const id2str_t rsa_flag_names[] = { { SC_ALGORITHM_RSA_PAD_PKCS1, "pkcs1" }, { SC_ALGORITHM_RSA_PAD_ANSI, "ansi" }, + { SC_ALGORITHM_RSA_PAD_PSS, "pss" }, { SC_ALGORITHM_RSA_PAD_ISO9796, "iso9796" }, { SC_ALGORITHM_RSA_HASH_SHA1, "sha1" }, { SC_ALGORITHM_RSA_HASH_MD5, "MD5" }, From 6e0689638c07d862a244a18d9a444a80289591fe Mon Sep 17 00:00:00 2001 From: asc Date: Fri, 22 Jun 2018 18:11:08 +0200 Subject: [PATCH 0382/4321] Add checking for supported CKM_RSA_PKCS_PSS combinations --- src/pkcs11/framework-pkcs15.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 7a11fa46e9..3040df63e5 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3680,6 +3680,58 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, } + +static CK_RV +pkcs15_prkey_check_pss_param(CK_MECHANISM_PTR pMechanism, CK_ULONG hlen) +{ + CK_RSA_PKCS_PSS_PARAMS *pss_param; + + if (pMechanism->pParameter == NULL) + return CKR_OK; // Support applications that don't provide CK_RSA_PKCS_PSS_PARAMS + + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) + return CKR_MECHANISM_PARAM_INVALID; + + pss_param = (CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; + + // Hash parameter must match mechanisms or length of data supplied for CKM_RSA_PKCS_PSS + switch(pss_param->hashAlg) { + case CKM_SHA_1: + if (hlen != 20) + return CKR_MECHANISM_PARAM_INVALID; + break; + case CKM_SHA256: + if (hlen != 32) + return CKR_MECHANISM_PARAM_INVALID; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + // SmartCards typically only support MGFs based on the same hash as the + // message digest + switch(pss_param->mgf) { + case CKG_MGF1_SHA1: + if (hlen != 20) + return CKR_MECHANISM_PARAM_INVALID; + break; + case CKG_MGF1_SHA256: + if (hlen != 32) + return CKR_MECHANISM_PARAM_INVALID; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + // SmartCards typically support only a salt length equal to the hash length + if (pss_param->sLen != hlen) + return CKR_MECHANISM_PARAM_INVALID; + + return CKR_OK; +} + + + static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData, @@ -3729,12 +3781,27 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512; break; case CKM_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_NONE; break; case CKM_SHA1_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, 20); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA1; break; case CKM_SHA256_RSA_PKCS_PSS: + rv = pkcs15_prkey_check_pss_param(pMechanism, 32); + + if (rv != CKR_OK) + return rv; + flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA256; break; case CKM_RIPEMD160_RSA_PKCS: From 6f8bfc399b9619925e2cedb6a48c344f4a19cc71 Mon Sep 17 00:00:00 2001 From: asc Date: Sun, 8 Jul 2018 15:04:38 +0200 Subject: [PATCH 0383/4321] Fix usage indicator for PSS --- src/pkcs11/framework-pkcs15.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3040df63e5..fd4f28dc05 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5072,6 +5072,9 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* TODO support other padding mechanisms */ if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { + CK_FLAGS old_flags = mech_info.flags; // PSS is not available for decryption + mech_info.flags &= ~(CKF_DECRYPT|CKF_VERIFY); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) @@ -5087,6 +5090,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rc != CKR_OK) return rc; } + mech_info.flags = old_flags; } if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { From 2c0d1b9ab0bd49a5252415d6a91324977a4ba0ce Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Jul 2018 14:02:16 +0200 Subject: [PATCH 0384/4321] reset sc_card_t during card detection fixes https://github.com/OpenSC/OpenSC/issues/1417 --- src/libopensc/card.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5968b0bd74..99b8da61c2 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -261,8 +261,22 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out) } } else { + sc_card_t uninitialized = *card; sc_log(ctx, "matching built-in ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { + /* FIXME If we had a clean API description, we'd propably get a + * cleaner implementation of the driver's match_card and init, + * which should normally *not* modify the card object if + * unsuccessful. However, after years of relentless hacking, reality + * is different: The card object is changed in virtually every card + * driver so in order to prevent unwanted interaction, we reset the + * card object here and hope that the card driver at least doesn't + * allocate any internal ressources that need to be freed. If we + * had more time, we should refactor the existing code to not + * modify sc_card_t until complete success (possibly by combining + * `match_card()` and `init()`) */ + *card = uninitialized; + struct sc_card_driver *drv = ctx->card_drivers[i]; const struct sc_card_operations *ops = drv->ops; From 332535c5445185f8c9c2080d23e3b0a47b663421 Mon Sep 17 00:00:00 2001 From: Eugene Bright Date: Sun, 1 Jul 2018 03:24:30 +0300 Subject: [PATCH 0385/4321] Workaround subject and issuer fields overflow Structure `x509cert_info` fields `subject` and `issuer` are doubled in size up to 512 bytes. We have to use dynamic memory allocation to completely overcome the issue. Relates to OpenSC/OpenSC#1412. --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 84e6bf5d4c..c29d1b841b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -350,9 +350,9 @@ struct mech_info { const char * short_name; }; struct x509cert_info { - unsigned char subject[256]; + unsigned char subject[512]; int subject_len; - unsigned char issuer[256]; + unsigned char issuer[512]; int issuer_len; unsigned char serialnum[128]; int serialnum_len; From 4ec37adea8b1c2621a5793e54a4d1ad8c0b74b2d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 30 Jun 2018 14:45:01 +0200 Subject: [PATCH 0386/4321] OpenPGP: extend manufacturer list in pkcs15-openpgp.c --- src/libopensc/pkcs15-openpgp.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index f4e4378ceb..f5fd00b9b9 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -106,18 +106,25 @@ typedef struct _pgp_manuf_map { } pgp_manuf_map_t; static const pgp_manuf_map_t manuf_map[] = { - { 0x0001, "PPC Card Systems" }, - { 0x0002, "Prism" }, - { 0x0003, "OpenFortress" }, - { 0x0004, "Wewid AB" }, - { 0x0005, "ZeitControl" }, - { 0x0006, "Yubico" }, - { 0x0007, "OpenKMS" }, - { 0x0008, "LogoEmail" }, - { 0x002A, "Magrathea" }, - { 0xF517, "FSIJ" }, - { 0x0000, "test card" }, - { 0xffff, "test card" }, + { 0x0001, "PPC Card Systems" }, + { 0x0002, "Prism" }, + { 0x0003, "OpenFortress" }, + { 0x0004, "Wewid AB" }, + { 0x0005, "ZeitControl" }, + { 0x0006, "Yubico" }, + { 0x0007, "OpenKMS" }, + { 0x0008, "LogoEmail" }, + { 0x0009, "Fidesmo" }, + { 0x000A, "Dangerous Things" }, + { 0x002A, "Magrathea" }, + { 0x0042, "GnuPG e.V." }, + { 0x1337, "Warsaw Hackerspace" }, + { 0x2342, "warpzone" }, + { 0x63AF, "Trustica" }, + { 0xBD0E, "Paranoidlabs" }, + { 0xF517, "FSIJ" }, + { 0x0000, "test card" }, + { 0xffff, "test card" }, { 0, NULL } }; From 4323a3d37cc8205bdbe840c0df5a783178adaa70 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 9 Jun 2018 17:18:42 +0200 Subject: [PATCH 0387/4321] OpenPGP: add new DO D5 introduced with OpenPGP card spec v2.1 ... and make it accessible for v2.1+ cards --- src/libopensc/card-openpgp.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cf0f272b42..92a5eb4f63 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -195,7 +195,7 @@ static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, /* Gnuk only supports 1 key length (2048 bit) */ #define MAXLEN_RESP_PUBKEY_GNUK 271 -static struct do_info pgp1_objects[] = { /* OpenPGP card spec 1.1 */ +static struct do_info pgp1x_objects[] = { /* OpenPGP card spec 1.1 */ { 0x004f, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, { 0x005b, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, { 0x005e, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, @@ -244,7 +244,9 @@ static struct do_info pgp1_objects[] = { /* OpenPGP card spec 1.1 */ { 0, 0, 0, NULL, NULL }, }; -static struct do_info pgp2_objects[] = { /* OpenPGP card spec 2.0 */ +static struct do_info pgp21_objects[] = { /* OpenPGP card spec 2.1 */ + { 0x00d5, SIMPLE, READ_NEVER | WRITE_PIN3, NULL, sc_put_data }, + /* OpenPGP card spec 2.0 */ { 0x004d, CONSTRUCTED, READ_NEVER | WRITE_PIN3, NULL, sc_put_data }, { 0x004f, SIMPLE, READ_ALWAYS | WRITE_NEVER, sc_get_data, NULL }, { 0x005b, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, @@ -304,6 +306,9 @@ static struct do_info pgp2_objects[] = { /* OpenPGP card spec 2.0 */ { 0, 0, 0, NULL, NULL }, }; +static struct do_info *pgp20_objects = pgp21_objects + 1; + + #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) struct pgp_priv_data { pgp_blob_t * mf; @@ -461,11 +466,9 @@ pgp_init(sc_card_t *card) } /* set pointer to correct list of card objects */ - if (priv->bcd_version < OPENPGP_CARD_2_0) { - priv->pgp_objects = pgp1_objects; - } else { - priv->pgp_objects = pgp2_objects; - } + priv->pgp_objects = (priv->bcd_version < OPENPGP_CARD_2_0) ? pgp1x_objects + : (priv->bcd_version < OPENPGP_CARD_2_1) ? pgp20_objects + : pgp21_objects; /* change file path to MF for re-use in MF */ sc_format_path("3f00", &file->path); From 14cd6ee39e3f316bbe0ca3934bc78df5b149731c Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 9 Jun 2018 17:52:23 +0200 Subject: [PATCH 0388/4321] OpenPGP: clarify meaning of padding byte in pgp_decipher() --- src/libopensc/card-openpgp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 92a5eb4f63..226d761c23 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1835,11 +1835,11 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, LOG_FUNC_CALLED(card->ctx); - /* There's some funny padding indicator that must be - * prepended... hmm. */ + /* padding according to OpenPGP card spec 1.1, 2.x & 3.x section 7.2.9 */ if (!(temp = malloc(inlen + 1))) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - temp[0] = '\0'; + /* padding byte: 0x00 = RSA; 0x02 = AES [v2.1+ only] */ + temp[0] = 0x00; memcpy(temp + 1, in, inlen); in = temp; inlen += 1; From 9dbdf42e9e0c445acb6f0ddecc15850ac3d6f929 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 11:58:51 +0200 Subject: [PATCH 0389/4321] OpenPGP: update references to specifications --- src/libopensc/card-openpgp.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 226d761c23..35b830ddf4 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -20,11 +20,18 @@ /* * Specifications: - * http://www.g10code.de/docs/openpgp-card-1.0.pdf (obsolete) - * http://www.g10code.de/docs/openpgp-card-1.1.pdf - * http://www.g10code.de/docs/openpgp-card-2.0.pdf - * http://www.g10code.de/docs/openpgp-card-2.1.pdf (minor changes to v2.0) - * http://www.g10code.de/docs/openpgp-card-3.0.pdf (not yet supported) + * (all available from: https://gnupg.org/ftp/specs/) + * https://gnupg.org/ftp/specs/openpgp-card-1.0.pdf (obsolete) + * https://gnupg.org/ftp/specs/openpgp-card-1.1.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-2.0.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-2.1.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-2.2.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.0.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.1.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.2.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.3.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.3.0.pdf + * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.3.1.pdf */ #if HAVE_CONFIG_H @@ -441,7 +448,7 @@ pgp_init(sc_card_t *card) /* read information from AID */ if (file->namelen == 16) { - /* OpenPGP card spec 1.1 & 2.0, section 4.2.1 & 4.1.2.1 */ + /* OpenPGP card spec 1.1, 2.x & 3.x, section 4.2.1 & 4.1.2.1 */ priv->bcd_version = bebytes2ushort(file->name + 6); card->version.fw_major = card->version.hw_major = BCD2CHAR(file->name[6]); card->version.fw_minor = card->version.hw_minor = BCD2CHAR(file->name[7]); @@ -583,7 +590,7 @@ pgp_get_card_features(sc_card_t *card) /* get "extended capabilities" DO */ if ((pgp_get_blob(card, blob73, 0x00c0, &blob) >= 0) && (blob->data != NULL) && (blob->len > 0)) { - /* in v2.0 bit 0x04 in first byte means "algorithm attributes changeable" */ + /* v2.0+: bit 0x04 in first byte means "algorithm attributes changeable" */ if ((blob->data[0] & 0x04) && (priv->bcd_version >= OPENPGP_CARD_2_0)) priv->ext_caps |= EXT_CAP_ALG_ATTR_CHANGEABLE; @@ -601,18 +608,18 @@ pgp_get_card_features(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG; priv->ext_caps |= EXT_CAP_GET_CHALLENGE; } - /* in v2.0 bit 0x80 in first byte means "support Secure Messaging" */ + /* v2.0+: bit 0x80 in first byte means "support Secure Messaging" */ if ((blob->data[0] & 0x80) && (priv->bcd_version >= OPENPGP_CARD_2_0)) priv->ext_caps |= EXT_CAP_SM; if ((priv->bcd_version >= OPENPGP_CARD_2_0) && (blob->len >= 10)) { - /* max. challenge size is at bytes 3-4 */ + /* v2.0+: max. challenge size is at bytes 3-4 */ priv->max_challenge_size = bebytes2ushort(blob->data + 2); - /* max. cert size it at bytes 5-6 */ + /* v2.0+: max. cert size it at bytes 5-6 */ priv->max_cert_size = bebytes2ushort(blob->data + 4); if (priv->bcd_version < OPENPGP_CARD_3_0) { - /* max. send/receive sizes are at bytes 7-8 resp. 9-10 */ + /* v2.x: max. send/receive sizes are at bytes 7-8 resp. 9-10 */ card->max_send_size = bebytes2ushort(blob->data + 6); card->max_recv_size = bebytes2ushort(blob->data + 8); } @@ -632,7 +639,7 @@ pgp_get_card_features(sc_card_t *card) unsigned long flags; /* Is this correct? */ - /* OpenPGP card spec 1.1 & 2.0, section 7.2.9 & 7.2.10 */ + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ flags = SC_ALGORITHM_RSA_PAD_PKCS1; flags |= SC_ALGORITHM_RSA_HASH_NONE; /* Can be generated in card */ @@ -1835,7 +1842,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, LOG_FUNC_CALLED(card->ctx); - /* padding according to OpenPGP card spec 1.1, 2.x & 3.x section 7.2.9 */ + /* padding according to OpenPGP card spec 1.1 & 2.x section 7.2.9 / 3.x section 7.2.11 */ if (!(temp = malloc(inlen + 1))) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); /* padding byte: 0x00 = RSA; 0x02 = AES [v2.1+ only] */ From dea5fd95518262bb5b4ebfa914ec048647bd0795 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 12:35:37 +0200 Subject: [PATCH 0390/4321] OpenPGP: add new DOs introduced with OpenPGP card spec v3.0 & v3.3 For some files spec states CONSTRUCTED, but we treat them as SIMPLE, because we only need parts of their contents. --- src/libopensc/card-openpgp.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 35b830ddf4..d1f547068b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -251,7 +251,17 @@ static struct do_info pgp1x_objects[] = { /* OpenPGP card spec 1.1 */ { 0, 0, 0, NULL, NULL }, }; -static struct do_info pgp21_objects[] = { /* OpenPGP card spec 2.1 */ +static struct do_info pgp33_objects[] = { /* OpenPGP card spec 3.3 */ + { 0x00f9, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, + /* OpenPGP card spec 3.0 - 3.2 */ + { 0x00d6, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, + { 0x00d7, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, + { 0x00d8, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, + /* DO 7F66 is CONSTRUCTED in spec; we treat it as SIMPLE: no need to parse TLV */ + { 0x7f66, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, sc_put_data }, + /* DO 7F74 is CONSTRUCTED in spec; we treat it as SIMPLE for the time being */ + { 0x7f74, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, sc_put_data }, + /* OpenPGP card spec 2.1 & 2.2 */ { 0x00d5, SIMPLE, READ_NEVER | WRITE_PIN3, NULL, sc_put_data }, /* OpenPGP card spec 2.0 */ { 0x004d, CONSTRUCTED, READ_NEVER | WRITE_PIN3, NULL, sc_put_data }, @@ -313,7 +323,9 @@ static struct do_info pgp21_objects[] = { /* OpenPGP card spec 2.1 */ { 0, 0, 0, NULL, NULL }, }; -static struct do_info *pgp20_objects = pgp21_objects + 1; +static struct do_info *pgp30_objects = pgp33_objects + 1; +static struct do_info *pgp21_objects = pgp33_objects + 6; +static struct do_info *pgp20_objects = pgp33_objects + 7; #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) @@ -475,7 +487,9 @@ pgp_init(sc_card_t *card) /* set pointer to correct list of card objects */ priv->pgp_objects = (priv->bcd_version < OPENPGP_CARD_2_0) ? pgp1x_objects : (priv->bcd_version < OPENPGP_CARD_2_1) ? pgp20_objects - : pgp21_objects; + : (priv->bcd_version < OPENPGP_CARD_3_0) ? pgp21_objects + : (priv->bcd_version < OPENPGP_CARD_3_3) ? pgp30_objects + : pgp33_objects; /* change file path to MF for re-use in MF */ sc_format_path("3f00", &file->path); From f73005791c38c08b81c5a6da442aa0296d9f0d54 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 13:09:13 +0200 Subject: [PATCH 0391/4321] OpenPGP: improve parsing of extended capabilities --- src/libopensc/card-openpgp.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index d1f547068b..76291233a8 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -131,6 +131,15 @@ enum _card_state { CARD_STATE_ACTIVATED = 0x05 }; +enum _sm_algo { + SM_ALGO_NONE = 0, /* SM not supported */ + SM_ALGO_AES128 = 1, + SM_ALGO_AES256 = 2, + SM_ALGO_SCP11b = 3, + SM_ALGO_3DES = 256, /* 2.x: coded as 0 in DO C0 */ + SM_ALGO_UNKNOWN = 257 /* 3.x: coded as 0 in DO C0 */ +}; + typedef struct pgp_blob { struct pgp_blob * next; /* pointer to next sibling */ struct pgp_blob * parent; /* pointer to parent */ @@ -329,9 +338,10 @@ static struct do_info *pgp20_objects = pgp33_objects + 7; #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) + struct pgp_priv_data { - pgp_blob_t * mf; - pgp_blob_t * current; /* currently selected file */ + pgp_blob_t *mf; + pgp_blob_t *current; /* currently selected file */ enum _version bcd_version; struct do_info *pgp_objects; @@ -339,12 +349,15 @@ struct pgp_priv_data { enum _card_state state; /* card state */ enum _ext_caps ext_caps; /* extended capabilities */ + enum _sm_algo sm_algo; /* Secure Messaging algorithm */ + size_t max_challenge_size; size_t max_cert_size; sc_security_env_t sec_env; }; + static int get_full_pgp_aid(sc_card_t *card, sc_file_t *file) { @@ -632,11 +645,23 @@ pgp_get_card_features(sc_card_t *card) priv->max_challenge_size = bebytes2ushort(blob->data + 2); /* v2.0+: max. cert size it at bytes 5-6 */ priv->max_cert_size = bebytes2ushort(blob->data + 4); + if (priv->bcd_version < OPENPGP_CARD_3_0) { + /* v2.x: SM algorithm is at byte 2: 0 == 3DES */ + priv->sm_algo = blob->data[0]; + if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) + priv->sm_algo = SM_ALGO_3DES; + /* v2.x: max. send/receive sizes are at bytes 7-8 resp. 9-10 */ card->max_send_size = bebytes2ushort(blob->data + 6); card->max_recv_size = bebytes2ushort(blob->data + 8); } + else { + /* v3.0+: SM algorithm is at byte 2: 0 == UNKNOWN */ + priv->sm_algo = blob->data[0]; + if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) + priv->sm_algo = SM_ALGO_UNKNOWN; + } /* TODO read Extended length information from DO 7F66 in OpenPGP 3.0 and later */ } } From 3a59b0a182151725797dde465297495ecad172fc Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 14:03:06 +0200 Subject: [PATCH 0392/4321] OpenPGP: parse "extended length info" DO 7f66 on init --- src/libopensc/card-openpgp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 76291233a8..b15fc83091 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -662,7 +662,6 @@ pgp_get_card_features(sc_card_t *card) if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) priv->sm_algo = SM_ALGO_UNKNOWN; } - /* TODO read Extended length information from DO 7F66 in OpenPGP 3.0 and later */ } } @@ -693,6 +692,16 @@ pgp_get_card_features(sc_card_t *card) } } } + + if (priv->bcd_version >= OPENPGP_CARD_3_0) { + /* v3.0+: get length info from "extended length information" DO */ + if ((pgp_get_blob(card, blob6e, 0x7f66, &blob) >= 0) && + (blob->data != NULL) && (blob->len >= 8)) { + /* kludge: treat as SIMPLE DO and use appropriate offsets */ + card->max_send_size = bebytes2ushort(blob->data + 2); + card->max_recv_size = bebytes2ushort(blob->data + 6); + } + } } return SC_SUCCESS; From 3af54b2fe0612154af3f70cf4a17d5df17b000ae Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 20:11:34 +0200 Subject: [PATCH 0393/4321] OpenPGP: harmonize some comments --- src/libopensc/card-openpgp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b15fc83091..3c178e66ca 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -315,13 +315,12 @@ static struct do_info pgp33_objects[] = { /* OpenPGP card spec 3.3 */ { 0x5f48, CONSTRUCTED, READ_NEVER | WRITE_PIN3, NULL, sc_put_data }, { 0x5f50, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, { 0x5f52, SIMPLE, READ_ALWAYS | WRITE_NEVER, sc_get_data, NULL }, - /* The 7F21 is constructed DO in spec, but in practice, its content can be retrieved - * as simple DO (no need to parse TLV). */ + /* DO 7F21 is CONSTRUCTED in spec; we treat it as SIMPLE: no need to parse TLV */ { DO_CERT, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, { 0x7f48, CONSTRUCTED, READ_NEVER | WRITE_NEVER, NULL, NULL }, { 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, { DO_AUTH, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, - /* The 0xA401, 0xB601, 0xB801 are just symbolic, it does not represent any real DO. + /* The DOs 0xA401, 0xB601, 0xB801 are virtual DOs, they do not represent any real DO. * However, their R/W access condition may block the process of importing key in pkcs15init. * So we set their accesses condition as WRITE_PIN3 (writable). */ { DO_AUTH_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, From 0d6be5db269c022fa80fbef76bc3dcb387b010b2 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 10 Jun 2018 22:06:53 +0200 Subject: [PATCH 0394/4321] OpenPGP: define & set LCS (lifecycle support) as extended capability Use it in pgp_erase_card() to slightly simplify the code. --- src/libopensc/card-openpgp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3c178e66ca..a759bab34b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -121,6 +121,7 @@ enum _ext_caps { /* extended capabilities/features */ EXT_CAP_KEY_IMPORT = 0x0020, EXT_CAP_GET_CHALLENGE = 0x0040, EXT_CAP_SM = 0x0080, + EXT_CAP_LCS = 0x0100, EXT_CAP_CHAINING = 0x1000, EXT_CAP_APDU_EXT = 0x2000 }; @@ -593,6 +594,9 @@ pgp_get_card_features(sc_card_t *card) } } + /* v1.1 does not support lifecycle via ACTIVATE & TERMINATE: set default */ + priv->ext_caps &= ~EXT_CAP_LCS; + if (priv->bcd_version >= OPENPGP_CARD_2_0) { /* get card capabilities from "historical bytes" DO */ if ((pgp_get_blob(card, priv->mf, 0x5f52, &blob) >= 0) && @@ -601,8 +605,12 @@ pgp_get_card_features(sc_card_t *card) pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); /* get card status from historical bytes status indicator */ - if ((blob->data[0] == 0x00) && (blob->len >= 4)) + if ((blob->data[0] == 0x00) && (blob->len >= 4)) { priv->state = blob->data[blob->len-3]; + /* state not CARD_STATE_UNKNOWN => LCS supported */ + if (priv->state != CARD_STATE_UNKNOWN) + priv->ext_caps |= EXT_CAP_LCS; + } } } @@ -2759,8 +2767,7 @@ pgp_erase_card(sc_card_t *card) LOG_FUNC_CALLED(card->ctx); - if (priv->bcd_version < OPENPGP_CARD_2_0 - || priv->state == CARD_STATE_UNKNOWN) { + if ((priv->ext_caps & EXT_CAP_LCS) == 0) { LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT, "Card does not offer life cycle management"); } From fcecd1bdd291e559880a35af256fec420b95e13a Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 15:54:17 +0200 Subject: [PATCH 0395/4321] OpenPGP: update comments on function use: ABI or internal --- src/libopensc/card-openpgp.c | 65 +++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index a759bab34b..159a6b39cd 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -358,6 +358,9 @@ struct pgp_priv_data { }; +/** + * Internal: get OpenPGP application identifier from AID DO 004F + */ static int get_full_pgp_aid(sc_card_t *card, sc_file_t *file) { @@ -369,9 +372,10 @@ get_full_pgp_aid(sc_card_t *card, sc_file_t *file) return r; } + /** * ABI: check if card's ATR matches one of driver's - * or if the OpenPGP application is present. + * or if the OpenPGP application is present on the card. */ static int pgp_match_card(sc_card_t *card) @@ -427,7 +431,7 @@ pgp_match_card(sc_card_t *card) #define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) /** - * ABI: initialize driver. + * ABI: initialize driver & allocate private data. */ static int pgp_init(sc_card_t *card) @@ -537,8 +541,9 @@ pgp_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } + /** - * Internal: get features of the card: capabilities, ... + * Internal: parse historic bytes to get card capabilities. */ static void pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) @@ -566,6 +571,7 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) } } + /** * Internal: get features of the card: capabilities, ... */ @@ -716,7 +722,7 @@ pgp_get_card_features(sc_card_t *card) /** - * ABI: terminate driver. + * ABI: terminate driver & free private data. */ static int pgp_finish(sc_card_t *card) @@ -994,7 +1000,7 @@ pgp_read_blob(sc_card_t *card, pgp_blob_t *blob) } -/* +/** * Internal: enumerate contents of a data blob. * The OpenPGP card has a TLV encoding according ASN.1 BER-encoding rules. */ @@ -1188,7 +1194,7 @@ pgp_strip_path(sc_card_t *card, const sc_path_t *path) /** - * ABI: SELECT FILE. + * ABI: ISO 7816-4 SELECT FILE - search given file & make it the currently selected one. */ static int pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) @@ -1268,7 +1274,7 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) /** - * ABI: LIST FILES. + * ABI: ISO 7816-4 LIST FILES - enumerate all files in current DF. */ static int pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) @@ -1303,6 +1309,10 @@ pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) LOG_FUNC_RETURN(card->ctx, k); } + +/** + * ABI: ISO 7816-4 GET CHALLENGE - generate random byte sequence. + */ static int pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) { @@ -1324,7 +1334,7 @@ pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) /** - * ABI: READ BINARY. + * ABI: ISO 7816-4 READ BINARY - read data from currently selected EF. */ static int pgp_read_binary(sc_card_t *card, unsigned int idx, @@ -1360,7 +1370,7 @@ pgp_read_binary(sc_card_t *card, unsigned int idx, /** - * ABI: WRITE BINARY. + * ABI: ISO 7816-4 WRITE BINARY - write data to currently selected EF. */ static int pgp_write_binary(sc_card_t *card, unsigned int idx, @@ -1371,7 +1381,7 @@ pgp_write_binary(sc_card_t *card, unsigned int idx, /** - * Internal: get public key from card: as DF + sub-wEFs. + * Internal: get public key from card - as DF + sub-wEFs. */ static int pgp_get_pubkey(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) @@ -1403,7 +1413,7 @@ pgp_get_pubkey(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /** - * Internal: get public key from card: as one wEF. + * Internal: get public key from card - as one wEF. */ static int pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) @@ -1445,7 +1455,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /** - * ABI: GET DATA. + * ABI: ISO 7816-4 GET DATA - get contents of a DO. */ static int pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) @@ -1553,7 +1563,7 @@ pgp_put_data_plain(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_ LOG_FUNC_CALLED(card->ctx); - /* Extended Header list (004D DO) needs a variant of PUT DATA command */ + /* Extended Header list (DO 004D) needs a variant of PUT DATA command */ if (tag == 0x004D) { ins = 0xDB; p1 = 0x3F; @@ -1591,7 +1601,7 @@ pgp_put_data_plain(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_ /** - * ABI: PUT DATA. + * ABI: ISO 7816-4 PUT DATA - write contents of a DO. */ static int pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) @@ -1662,7 +1672,7 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) /** - * ABI: PIN cmd: verify/change/unblock a PIN. + * ABI: ISO 7816-9 PIN CMD - verify/change/unblock a PIN. */ static int pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) @@ -1742,6 +1752,9 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } +/** + * ABI: ISO 7816-8 LOGOUT - reset all access rights gained. + */ int pgp_logout(struct sc_card *card) { int r = SC_SUCCESS; @@ -1773,7 +1786,7 @@ int pgp_logout(struct sc_card *card) /** - * ABI: set security environment. + * ABI: ISO 7816-8 SET SECURITY ENVIRONMENT. */ static int pgp_set_security_env(sc_card_t *card, @@ -1826,7 +1839,7 @@ pgp_set_security_env(sc_card_t *card, /** - * ABI: COMPUTE DIGITAL SIGNATURE. + * ABI: ISO 7816-8 COMPUTE DIGITAL SIGNATURE. */ static int pgp_compute_signature(sc_card_t *card, const u8 *data, @@ -1882,7 +1895,7 @@ pgp_compute_signature(sc_card_t *card, const u8 *data, /** - * ABI: DECIPHER. + * ABI: ISO 7816-8 DECIPHER - perform deciphering operation. */ static int pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, @@ -2815,7 +2828,7 @@ pgp_erase_card(sc_card_t *card) /** - * ABI: card ctl: perform special card-specific operations. + * ABI: ISO 7816-9 CARD CTL - perform special card-specific operations. */ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) @@ -2852,7 +2865,7 @@ pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) /** - * Internal: delete key. + * Internal: delete key (GnuK only). */ static int gnuk_delete_key(sc_card_t *card, u8 key_id) @@ -2894,7 +2907,7 @@ gnuk_delete_key(sc_card_t *card, u8 key_id) /** - * ABI: DELETE FILE. + * ABI: ISO 7816-9 DELETE FILE - delete EF or DF given. */ static int pgp_delete_file(sc_card_t *card, const sc_path_t *path) @@ -2913,7 +2926,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path) /* save "current" blob */ blob = priv->current; - /* do try to delete MF */ + /* don't try to delete MF */ if (blob == priv->mf) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); @@ -2944,7 +2957,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path) /** - * ABI: UPDATE BINARY. + * ABI: ISO 7816-4 UPDATE BINARY - update data in current EF. */ static int pgp_update_binary(sc_card_t *card, unsigned int idx, @@ -2971,6 +2984,9 @@ pgp_update_binary(sc_card_t *card, unsigned int idx, } +/** + * ABI: card reader lock obtained - re-select card applet if necessary. + */ static int pgp_card_reader_lock_obtained(sc_card_t *card, int was_reset) { struct pgp_priv_data *priv = DRVDATA(card); /* may be null during initialization */ @@ -3007,6 +3023,9 @@ static int pgp_card_reader_lock_obtained(sc_card_t *card, int was_reset) } +/** + * API: integrate OpenPGP driver into OpenSC's driver list. + */ struct sc_card_driver * sc_get_openpgp_driver(void) { From 15125b03ab8377b4a34b93b5a77c4853058abe05 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 15:57:43 +0200 Subject: [PATCH 0396/4321] OpenPGP: use LOG_FUNC_CALLED & LOG_FUNC_RETURN symmetrically To help debugging, - replace plain return's after LOG_FUNC_CALLED() has been called with LOG_FUNC_RETURN() - use LOG_FUNC_CALLED() & LOG_FUNC_RETURN() pairs more often --- src/libopensc/card-openpgp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 159a6b39cd..6be5d67334 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -382,6 +382,8 @@ pgp_match_card(sc_card_t *card) { int i; + LOG_FUNC_CALLED(card->ctx); + i = _sc_match_atr(card, pgp_atrs, &card->type); if (i >= 0) { card->name = pgp_atrs[i].name; @@ -421,10 +423,10 @@ pgp_match_card(sc_card_t *card) snprintf(card_name, sizeof(card_name), "OpenPGP card V%u.%u", major, minor); } sc_file_free(file); - return 1; + LOG_FUNC_RETURN(card->ctx, 1); } } - return 0; + LOG_FUNC_RETURN(card->ctx, 0); } @@ -447,7 +449,7 @@ pgp_init(sc_card_t *card) priv = calloc (1, sizeof *priv); if (!priv) - return SC_ERROR_OUT_OF_MEMORY; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); card->drv_data = priv; card->cla = 0x00; @@ -471,7 +473,7 @@ pgp_init(sc_card_t *card) r = get_full_pgp_aid(card, file); if (r < 0) { pgp_finish(card); - return SC_ERROR_INVALID_CARD; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } } From 2a7a6a62fa0f027475f5a68a6a70049e5fd518f5 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 16:03:41 +0200 Subject: [PATCH 0397/4321] OpenPGP: limit scope of variable --- src/libopensc/card-openpgp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 6be5d67334..82cc05e4d1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -443,7 +443,6 @@ pgp_init(sc_card_t *card) sc_file_t *file = NULL; struct do_info *info; int r; - pgp_blob_t *child = NULL; LOG_FUNC_CALLED(card->ctx); @@ -525,8 +524,9 @@ pgp_init(sc_card_t *card) /* populate MF - add matching blobs listed in the pgp_objects table */ for (info = priv->pgp_objects; (info != NULL) && (info->id > 0); info++) { - if (((info->access & READ_MASK) != READ_NEVER) && - (info->get_fn != NULL)) { + if (((info->access & READ_MASK) != READ_NEVER) && (info->get_fn != NULL)) { + pgp_blob_t *child = NULL; + child = pgp_new_blob(card, priv->mf, info->id, sc_file_new()); /* catch out of memory condition */ From 2e1b47a79a3604a3a549b92326d724538dabcf14 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 19:34:39 +0200 Subject: [PATCH 0398/4321] OpenPGP: improve get_full_pgp_aid()'s parameter checking --- src/libopensc/card-openpgp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 82cc05e4d1..aa0efacbdb 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -364,10 +364,13 @@ struct pgp_priv_data { static int get_full_pgp_aid(sc_card_t *card, sc_file_t *file) { - int r = 0; - /* explicitly get the full aid */ - r = sc_get_data(card, 0x004F, file->name, sizeof file->name); - file->namelen = MAX(r, 0); + int r = SC_ERROR_INVALID_ARGUMENTS; + + if (file != NULL) { + /* explicitly get the full aid */ + r = sc_get_data(card, 0x004F, file->name, sizeof file->name); + file->namelen = MAX(r, 0); + } return r; } From 215fcdad15294a9c2ac56176c176bc7e3252f906 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 20:04:27 +0200 Subject: [PATCH 0399/4321] OpenPGP: include detailed version into card name ... for "standard" OpenPGP cards. This gives more detailed information to the user on the detailed specs the card adheres to. In addition it fixes a long-standing annoyance that every standard 2.x card matching the v2.0 ATR was announced as CryptoStick 1.2. This ATR is not only used in the CryptoStick 1.2, but also also in ZeitControl cards as well as NitroKeys, ... --- src/libopensc/card-openpgp.c | 42 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index aa0efacbdb..54aac09dc0 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -51,13 +51,18 @@ #include #endif /* ENABLE_OPENSSL */ +static const char default_cardname[] = "OpenPGP card"; +static const char default_cardname_v1[] = "OpenPGP card v1.x"; +static const char default_cardname_v2[] = "OpenPGP card v2.x"; +static const char default_cardname_v3[] = "OpenPGP card v3.x"; + 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 }, - { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, "CryptoStick v1.2 (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, + { "3b:fa:13:00:ff:81:31:80:45:00:31:c1:73:c0:01:00:00:90:00:b1", NULL, default_cardname_v1, SC_CARD_TYPE_OPENPGP_V1, 0, NULL }, + { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, default_cardname_v2, SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, { "3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1", NULL, "Yubikey NEO (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4", NULL, "Yubikey 4 (OpenPGP v2.1)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, - { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:f5:73:c0:01:60:00:90:00:1c", NULL, "OpenPGP card V3", SC_CARD_TYPE_OPENPGP_V3, 0, NULL }, + { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:f5:73:c0:01:60:00:90:00:1c", NULL, default_cardname_v3, SC_CARD_TYPE_OPENPGP_V3, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -376,6 +381,8 @@ get_full_pgp_aid(sc_card_t *card, sc_file_t *file) } +#define BCD2UCHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) + /** * ABI: check if card's ATR matches one of driver's * or if the OpenPGP application is present on the card. @@ -402,28 +409,30 @@ pgp_match_card(sc_card_t *card) /* OpenPGP card only supports selection *with* requested FCI */ i = iso_ops->select_file(card, &partial_aid, &file); if (SC_SUCCESS == i) { - static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; card->type = SC_CARD_TYPE_OPENPGP_BASE; - card->name = card_name; + card->name = default_cardname; + if (file->namelen != 16) (void) get_full_pgp_aid(card, file); if (file->namelen == 16) { - unsigned char major = file->name[6]; - unsigned char minor = file->name[7]; + unsigned char major = BCD2UCHAR(file->name[6]); + switch (major) { case 1: card->type = SC_CARD_TYPE_OPENPGP_V1; + card->name = default_cardname_v1; break; case 2: card->type = SC_CARD_TYPE_OPENPGP_V2; + card->name = default_cardname_v2; break; case 3: card->type = SC_CARD_TYPE_OPENPGP_V3; + card->name = default_cardname_v3; break; default: break; } - snprintf(card_name, sizeof(card_name), "OpenPGP card V%u.%u", major, minor); } sc_file_free(file); LOG_FUNC_RETURN(card->ctx, 1); @@ -433,8 +442,6 @@ pgp_match_card(sc_card_t *card) } -#define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) - /** * ABI: initialize driver & allocate private data. */ @@ -483,8 +490,19 @@ pgp_init(sc_card_t *card) if (file->namelen == 16) { /* OpenPGP card spec 1.1, 2.x & 3.x, section 4.2.1 & 4.1.2.1 */ priv->bcd_version = bebytes2ushort(file->name + 6); - card->version.fw_major = card->version.hw_major = BCD2CHAR(file->name[6]); - card->version.fw_minor = card->version.hw_minor = BCD2CHAR(file->name[7]); + card->version.fw_major = card->version.hw_major = BCD2UCHAR(file->name[6]); + card->version.fw_minor = card->version.hw_minor = BCD2UCHAR(file->name[7]); + + /* for "standard" cards, include detailed card version in card name */ + if (card->name == default_cardname_v1 || + card->name == default_cardname_v2 || + card->name == default_cardname_v3) { + static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; + + snprintf(card_name, sizeof(card_name), "OpenPGP card v%u.%u", + card->version.hw_major, card->version.hw_minor); + card->name = card_name; + } /* kludge: get card's serial number from manufacturer ID + serial number */ memcpy(card->serialnr.value, file->name + 8, 6); From 6d6efa2ded2a0cc858f59b9c2f939ba203683bca Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 16 Jun 2018 21:07:37 +0200 Subject: [PATCH 0400/4321] OpenPGP: fix FIXME in pgp_new_blob() Form a correct path instead ofmusising an array of 2 u8's. Perform proper error checking. --- src/libopensc/card-openpgp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 54aac09dc0..6607b23a3d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -903,13 +903,15 @@ pgp_new_blob(sc_card_t *card, pgp_blob_t *parent, unsigned int file_id, *p = blob; } else { - u8 id_str[2]; + char path[10] = "0000"; /* long enough */ /* no parent: set file's path = file's id */ - /* FIXME sc_format_path expects an hex string of a file - * identifier. ushort2bebytes instead delivers a two bytes binary - * string */ - sc_format_path((char *) ushort2bebytes(id_str, file_id), &blob->file->path); + if (4 != snprintf(path, sizeof(path), "%04X", file_id & 0xFFFF)) { + free(blob); + return NULL; + } + + sc_format_path(path, &blob->file->path); } /* find matching DO info: set file type depending on it */ From 7332a37abbfc4db7f8f9c17d6c0008cb435ff171 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 23 Jun 2018 17:11:17 +0200 Subject: [PATCH 0401/4321] OpenPGP: add serial number to card name --- src/libopensc/card-openpgp.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 6607b23a3d..aa6a938cd2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -488,23 +488,34 @@ pgp_init(sc_card_t *card) /* read information from AID */ if (file->namelen == 16) { + static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; + /* OpenPGP card spec 1.1, 2.x & 3.x, section 4.2.1 & 4.1.2.1 */ priv->bcd_version = bebytes2ushort(file->name + 6); card->version.fw_major = card->version.hw_major = BCD2UCHAR(file->name[6]); card->version.fw_minor = card->version.hw_minor = BCD2UCHAR(file->name[7]); - /* for "standard" cards, include detailed card version in card name */ + /* for "standard" cards, include detailed card version & serial no. in card name */ if (card->name == default_cardname_v1 || card->name == default_cardname_v2 || card->name == default_cardname_v3) { - static char card_name[SC_MAX_APDU_BUFFER_SIZE] = "OpenPGP card"; - - snprintf(card_name, sizeof(card_name), "OpenPGP card v%u.%u", - card->version.hw_major, card->version.hw_minor); - card->name = card_name; + snprintf(card_name, sizeof(card_name), + "OpenPGP card v%u.%u (%04X %08lX)", + card->version.hw_major, card->version.hw_minor, + bebytes2ushort(file->name + 8), + bebytes2ulong(file->name + 10)); + } + else if (card->name != NULL) { + /* for other cards, append serial number to the card name */ + snprintf(card_name, sizeof(card_name), + "%s (%04X %08lX)", + card->name, + bebytes2ushort(file->name + 8), + bebytes2ulong(file->name + 10)); } + card->name = card_name; - /* kludge: get card's serial number from manufacturer ID + serial number */ + /* GPG compatibility: set card's serial number to manufacturer ID + serial number */ memcpy(card->serialnr.value, file->name + 8, 6); card->serialnr.len = 6; } else { From 1eb8391b4a09641e1a795be5898d33b34bc4277e Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 24 Jun 2018 10:15:36 +0200 Subject: [PATCH 0402/4321] OpenPGP: slightly re-factor pgp_get_card_features() * length checks where needed * more & better comments --- src/libopensc/card-openpgp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index aa6a938cd2..594ff0525c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -730,13 +730,14 @@ pgp_get_card_features(sc_card_t *card) /* Can be generated in card */ flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && - (blob->data != NULL) && (blob->len >= 4)) { - if (blob->data[0] == 0x01) { /* Algorithm ID [RFC4880]: RSA */ - unsigned int keylen = bebytes2ushort(blob->data + 1); /* Measured in bit */ + /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ + if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (blob->data != NULL)) { + if (blob->len >= 3 && blob->data[0] == 0x01) { /* RSA [RFC 4880] */ + unsigned int keybits = bebytes2ushort(blob->data + 1); - _sc_card_add_rsa_alg(card, keylen, flags, 0); + _sc_card_add_rsa_alg(card, keybits, flags, 0); } + /* v3.0+: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ } } From 1c2a7f8dd26ee67959d7018be624049f0355cbf9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Jun 2018 10:38:20 +0200 Subject: [PATCH 0403/4321] HID Alt tokens have the other bunch of slots in other undocumented AID --- src/libopensc/card-cac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 0801a54575..a08c6480cf 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1518,7 +1518,8 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* Search for PKI applets (7 B). Ignore generic objects for now */ - if (aid_len != 7 || memcmp(aid, CAC_1_RID "\x01", 6) != 0) + if (aid_len != 7 || (memcmp(aid, CAC_1_RID "\x01", 6) != 0 + && memcmp(aid, CAC_1_RID "\x00", 6) != 0)) return SC_SUCCESS; sc_mem_clear(&new_object.path, sizeof(sc_path_t)); From 3480d9fc998ba86c7f62c5d1343820060dcb043c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Jun 2018 10:36:51 +0200 Subject: [PATCH 0404/4321] Log also information about unitialized slots with correct labels --- src/libopensc/card-cac.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index a08c6480cf..2060212f5c 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1539,22 +1539,26 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int if (priv->cert_next >= MAX_CAC_SLOTS) return SC_SUCCESS; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "ACA: pki_object found, cert_next=%d (%s), privkey=%d", + priv->cert_next, cac_labels[priv->cert_next], + prop.objects[i].privatekey); + /* If the private key is not initialized, we can safely - * ignore this object here + * ignore this object here, but increase the pointer to follow + * the certificate labels */ - if (!prop.objects[i].privatekey) + if (!prop.objects[i].privatekey) { + priv->cert_next++; continue; + } /* OID here has always 2B */ memcpy(new_object.path.value, &prop.objects[i].oid, 2); new_object.path.len = 2; new_object.path.type = SC_PATH_TYPE_FILE_ID; - new_object.name = cac_labels[priv->cert_next]; new_object.fd = priv->cert_next+1; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "ACA: pki_object found, cert_next=%d (%s),", - priv->cert_next, new_object.name); cac_add_object_to_list(&priv->pki_list, &new_object); priv->cert_next++; } From bf3382d4d9f921826d8bc571925d4f12cef9a7cc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Jun 2018 10:37:20 +0200 Subject: [PATCH 0405/4321] Standardize logging and include also AID --- src/libopensc/card-cac.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 2060212f5c..8ce7b74d79 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1781,9 +1781,8 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, switch (tag) { case CAC_TAG_APPLET_FAMILY: if (len != 5) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Applet Information = (bad length %" - SC_FORMAT_LEN_SIZE_T"u)", len); + sc_log(card->ctx, "TAG: Applet Information: " + "bad length %"SC_FORMAT_LEN_SIZE_T"u", len); break; } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, @@ -1794,23 +1793,23 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, break; case CAC_TAG_NUMBER_APPLETS: if (len != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Num applets = (bad length %"SC_FORMAT_LEN_SIZE_T"u)", - len); + sc_log(card->ctx, "TAG: Num applets: " + "bad length %"SC_FORMAT_LEN_SIZE_T"u", len); break; } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "TAG: Num applets = %hhd", *val); break; case CAC_TAG_APPLET_ENTRY: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Applet Entry"); /* Make sure we match the outer length */ if (len < 3 || val[2] != len - 3) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "bad length of internal buffer"); + sc_log(card->ctx, "TAG: Applet Entry: " + "bad length (%"SC_FORMAT_LEN_SIZE_T + "u) or length of internal buffer", len); break; } + sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE, + "TAG: Applet Entry: AID", &val[3], val[2]); /* This is SimpleTLV prefixed with applet ID (1B) */ r = cac_parse_aid(card, priv, &val[3], val[2]); if (r < 0) From 3a7a1ba31ff1995b5299ec7ab9947594374f10c1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 18 Jun 2018 13:57:29 +0200 Subject: [PATCH 0406/4321] Do not fail if we found unknown tag or the count does not match * The HID tokens present such undocumented tags --- src/libopensc/card-cac.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 8ce7b74d79..a4f149c915 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1254,15 +1254,18 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) default: /* ignore tags we don't understand */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Unknown (0x%02x)",tag ); + sc_log(card->ctx, "TAG: Unknown (0x%02x), len=%" + SC_FORMAT_LEN_SIZE_T"u", tag, len); break; } } free(rbuf); /* sanity */ if (i != prop->num_objects) - return SC_ERROR_INVALID_DATA; + sc_log(card->ctx, "The announced number of objects (%u) " + "did not match reality (%"SC_FORMAT_LEN_SIZE_T"u)", + prop->num_objects, i); + prop->num_objects = i; return SC_SUCCESS; } From 7c8ed4dc0334f8dfea072e7b95f8a422975677c7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 22 Jun 2018 10:22:54 +0200 Subject: [PATCH 0407/4321] Correct name in the automake --- src/tests/p11test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 5bc56cd810..1ecc09af77 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -23,7 +23,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_pss_oaep.c \ p11test_helpers.c p11test_CFLAGS = -DNDEBUG $(CMOCKA_CFLAGS) -p11test_LDADD = -lssl -lcrypto $(CMOCKA_LDLAGS) +p11test_LDADD = -lssl -lcrypto $(CMOCKA_LIBS) if WIN32 p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc From e9314adf4bcf5591d8fbd4fe038cf74b397eb3de Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Jun 2018 13:40:27 +0200 Subject: [PATCH 0408/4321] Testsuite also depends on openssl, use correct variables for linking --- configure.ac | 31 +++++++++++++++++-------------- src/tests/p11test/Makefile.am | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 6abad0b779..290b513f90 100644 --- a/configure.ac +++ b/configure.ac @@ -527,20 +527,6 @@ AC_CHECK_HEADER([cmocka.h],, [have_cmocka="no"], #include ]) -if test "${enable_tests}" = "detect"; then - if test "${have_cmocka}" = "yes"; then - enable_tests="yes" - else - enable_tests="no" - fi -fi - -if test "${enable_tests}" = "yes"; then - if test "${have_cmocka}" != "yes"; then - AC_MSG_ERROR([Tests required, but cmocka is not available]) - fi -fi - AC_ARG_VAR([ZLIB_CFLAGS], [C compiler flags for zlib]) AC_ARG_VAR([ZLIB_LIBS], [linker flags for zlib]) if test -z "${ZLIB_LIBS}"; then @@ -667,6 +653,23 @@ else OPENSSL_LIBS="" fi +if test "${enable_tests}" = "detect"; then + if test "${have_cmocka}" = "yes" -a "${have_openssl}" = "yes"; then + enable_tests="yes" + else + enable_tests="no" + fi +fi + +if test "${enable_tests}" = "yes"; then + if test "${have_cmocka}" != "yes"; then + AC_MSG_ERROR([Tests required, but cmocka is not available]) + fi + if test "${have_openssl}" != "yes"; then + AC_MSG_ERROR([Tests required, but openssl is not available]) + fi +fi + PKG_CHECK_EXISTS([libeac], [PKG_CHECK_MODULES([OPENPACE], [libeac >= 0.9])], diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 1ecc09af77..a7e88f1b48 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -23,7 +23,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_pss_oaep.c \ p11test_helpers.c p11test_CFLAGS = -DNDEBUG $(CMOCKA_CFLAGS) -p11test_LDADD = -lssl -lcrypto $(CMOCKA_LIBS) +p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) if WIN32 p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc From 1eaae6526be3340688a8cfbcc1aec314fd613730 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Jun 2018 13:42:58 +0200 Subject: [PATCH 0409/4321] pkcs15-tool: Build with current gcc The argument to strncpy is not the length of the target buffer, but the source one (excluding the null byte, which will be copied anyway). --- src/tools/pkcs15-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 3316135777..019ab8c045 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1022,7 +1022,7 @@ static int read_ssh_key(void) buf[1] = 0; buf[2] = 0; len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n); - strncpy(alg, (char *) buf+4, 20); + strncpy(alg, (char *) buf+4, 19); buf[3] = len; len += 4; From 376de5bd4c223a6dd423b657892ccbe73145e4e3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 11 Jul 2018 21:55:05 +0200 Subject: [PATCH 0410/4321] make bash completion directory configurable --- configure.ac | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 290b513f90..03517a73b2 100644 --- a/configure.ac +++ b/configure.ac @@ -269,6 +269,13 @@ AC_ARG_WITH( [xslstylesheetsdir="detect"] ) +AC_ARG_WITH( + [completiondir], + [AS_HELP_STRING([--with-completiondir=PATH],[Directory of Bash completion @<:@detect@:>@])], + [completiondir="${withval}"], + [completiondir="detect"] +) + AC_ARG_WITH( [pcsc-provider], [AS_HELP_STRING([--with-pcsc-provider=PATH],[Path to system pcsc provider @<:@system default@:>@])], @@ -842,9 +849,13 @@ if test "${enable_cryptotokenkit}" = "yes"; then fi AC_DEFINE([ENABLE_CRYPTOTOKENKIT], [1], [Define if CryptoTokenKit is to be enabled]) fi -PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], - [completiondir="`pkg-config --variable=completionsdir bash-completion`"], - [completiondir="${sysconfdir}/bash_completion.d"]) + +if test "${completiondir}" = "detect"; then + echo completion ${completiondir} + PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], + [completiondir="`pkg-config --variable=completionsdir bash-completion`"], + [completiondir="${sysconfdir}/bash_completion.d"]) +fi AC_SUBST([completiondir]) @@ -1101,6 +1112,7 @@ Product URL: ${OPENSC_VS_FF_PRODUCT_URL} User binaries: $(eval eval eval echo "${bindir}") Configuration files: $(eval eval eval echo "${sysconfdir}") +Bash completion: ${completiondir} XSL stylesheets: ${xslstylesheetsdir} man support: ${enable_man} From fbc9ff84bcfdc72d54b90f65158f5e60c204864c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 8 Apr 2018 20:15:13 -0500 Subject: [PATCH 0411/4321] Some cards may return short RSA signatures without leading zero bytes. Add leading zeros to RSA signature so it is the size of modulus. Return modulus length. Changes to be committed: modified: src/libopensc/pkcs15-sec.c --- src/libopensc/pkcs15-sec.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index a508cc7b53..6ee4fa3c74 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -456,6 +456,15 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, r = use_key(p15card, obj, &senv, sc_compute_signature, tmp, inlen, out, outlen); LOG_TEST_RET(ctx, r, "use_key() failed"); + + /* Some cards may return RSA signature as integer without leading zero bytes */ + /* Already know outlen >= modlen and r >= 0 */ + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA && (unsigned)r < modlen) { + memmove(out + modlen - r, out, r); + memset(out, 0, modlen - r); + r = modlen; + } + sc_mem_clear(buf, sizeof(buf)); LOG_FUNC_RETURN(ctx, r); From 3042a397054868b5d2dfb192fc4d748ef7e3f7a9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Jul 2018 13:16:06 +0200 Subject: [PATCH 0412/4321] removed unused variable --- src/pkcs11/framework-pkcs15.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index fd4f28dc05..2ab4b5744d 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5072,7 +5072,6 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* TODO support other padding mechanisms */ if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { - CK_FLAGS old_flags = mech_info.flags; // PSS is not available for decryption mech_info.flags &= ~(CKF_DECRYPT|CKF_VERIFY); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); @@ -5090,7 +5089,6 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rc != CKR_OK) return rc; } - mech_info.flags = old_flags; } if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { From 16275c26831af2b72285d54ec4c42a6d4a0ed41f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Jul 2018 13:31:14 +0200 Subject: [PATCH 0413/4321] fixed memory leak --- src/tools/opensc-explorer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 152b6a42a0..8dc02bc50d 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -732,7 +732,7 @@ static int do_cd(int argc, char **argv) static int read_and_util_print_binary_file(sc_file_t *file) { unsigned char *buf = NULL; - int r; + int r, ret = -1; size_t size; if (file->size) { @@ -750,15 +750,17 @@ static int read_and_util_print_binary_file(sc_file_t *file) sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_READ, "read failed", file); - return -1; + goto err; } if ((r == 0) && (card->type == SC_CARD_TYPE_BELPIC_EID)) - return -1; + goto err; util_hex_dump_asc(stdout, buf, r, 0); + ret = 0; +err: free(buf); - return 0; + return ret; } static int read_and_print_record_file(sc_file_t *file, unsigned char sfi) From 47ee3a3978eef843d74b616a99d2eae4e16258e7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 31 May 2018 19:06:17 +0200 Subject: [PATCH 0414/4321] added manual page opensc.conf(5) splits the HTML documentation into files.html and tools.html --- .gitignore | 6 +- configure.ac | 1 + doc/Makefile.am | 2 +- doc/files/Makefile.am | 32 + doc/files/files.html | 1105 ++++++++++++++ doc/files/files.xml | 10 + doc/files/opensc.conf.5.xml.in | 1647 +++++++++++++++++++++ doc/{tools => files}/pkcs15-profile.5.xml | 0 doc/tools/Makefile.am | 9 +- doc/tools/files.html | 1096 ++++++++++++++ doc/tools/tools.html | 951 +++++++----- doc/tools/tools.xml | 57 +- etc/opensc.conf.in | 11 +- src/pkcs11/openssl.c | 1 + 14 files changed, 4476 insertions(+), 452 deletions(-) create mode 100644 doc/files/Makefile.am create mode 100644 doc/files/files.html create mode 100644 doc/files/files.xml create mode 100644 doc/files/opensc.conf.5.xml.in rename doc/{tools => files}/pkcs15-profile.5.xml (100%) create mode 100644 doc/tools/files.html diff --git a/.gitignore b/.gitignore index 2e106fa3f5..8d91981e4e 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,6 @@ tags *.gz *.bz2 *.[0-9] -*.html *.gif *.css *.out @@ -77,6 +76,11 @@ doc/tools/pkcs15-tool doc/tools/sc-hsm-tool doc/tools/westcos-tool doc/tools/dnie-tool +doc/tools/egk-tool +doc/tools/npa-tool +doc/tools/opensc-asn1 +doc/tools/opensc-notify +doc/files/opensc.conf.5.xml etc/opensc.conf.win etc/opensc.conf diff --git a/configure.ac b/configure.ac index 03517a73b2..c655e76442 100644 --- a/configure.ac +++ b/configure.ac @@ -1057,6 +1057,7 @@ AC_CONFIG_FILES([ Makefile doc/Makefile doc/tools/Makefile + doc/files/Makefile etc/Makefile src/Makefile src/common/Makefile diff --git a/doc/Makefile.am b/doc/Makefile.am index d572f4296b..754720a995 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -SUBDIRS = tools +SUBDIRS = tools files dist_noinst_SCRIPTS = html.xsl man.xsl dist_noinst_DATA = api.css diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am new file mode 100644 index 0000000000..fe245247ac --- /dev/null +++ b/doc/files/Makefile.am @@ -0,0 +1,32 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +dist_noinst_DATA = pkcs15-profile.5.xml opensc.conf.5.xml.in +if ENABLE_DOC +html_DATA = files.html +endif + +if ENABLE_MAN +man5_MANS = pkcs15-profile.5 opensc.conf.5 +endif + +opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in + sed \ + -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ + -e 's|@docdir[@]|$(docdir)|g' \ + -e 's|@libdir[@]|$(libdir)|g' \ + -e 's|@DYN_LIB_EXT[@]|$(DYN_LIB_EXT)|g' \ + -e 's|@DEFAULT_PCSC_PROVIDER[@]|$(DEFAULT_PCSC_PROVIDER)|g' \ + -e 's|@PROFILE_DIR_DEFAULT[@]|$(PROFILE_DIR_DEFAULT)|g' \ + -e 's|@DEFAULT_SM_MODULE[@]|$(DEFAULT_SM_MODULE)|g' \ + < $< > opensc.conf.5.xml + $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl opensc.conf.5.xml + +files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml + $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< + +%.5: $(srcdir)/%.5.xml + sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ + | $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $< + +clean-local: + -rm -rf $(html_DATA) $(man5_MANS) opensc.conf.5.xml diff --git a/doc/files/files.html b/doc/files/files.html new file mode 100644 index 0000000000..362535dbfc --- /dev/null +++ b/doc/files/files.html @@ -0,0 +1,1105 @@ +OpenSC Manual Pages: Section 5

OpenSC Manual Pages: Section 5


Table of Contents

opensc.conf — configuration file for OpenSC
pkcs15-profile — format of profile for pkcs15-init

Name

opensc.conf — configuration file for OpenSC

Description

+ OpenSC obtains configuration data from the following sources in the following order +

  1. + command-line options +

  2. + environment variables +

  3. + Windows registry (if available) +

  4. + system-wide configuration file + (/home/fm/.local/etc/opensc.conf) +

+

+ The configuration file, opensc.conf, is composed + of blocks, which, in general, have the + following format: +

+key [, name...] {
+	block_contents
+}
+			

+ block_contents is one or more + block_items where a + block_item is one of +

  • + # comment string +

  • + key [, name...] = value; +

  • + block +

+

+ At the root level, opensc.conf should contain + one or more application specific configuration blocks: +

+app application {
+	block_contents
+}
+			

+ application + specifies one of: +

  • + default: The fall-back configuration block for all applications +

  • + opensc-pkcs11: Configuration block for the PKCS#11 module (opensc-pkcs11.so) +

  • + onepin-opensc-pkcs11: Configuration block for the PKCS#11 one-PIN-module (onepin-opensc-pkcs11.so) +

  • + cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) +

  • + tokend: Configuration block for macOS' tokend (OpenSC.tokend) +

  • + cardos-tool, + cryptoflex-tool, + dnie-tool, + egk-tool, + eidenv, + gids-tool, + iasecc-tool, + netkey-tool, + npa-tool, + openpgp-tool, + opensc-asn1, + opensc-explorer, + opensc-notify, + opensc-tool, + piv-tool, + pkcs11-tool, + pkcs15-crypt, + pkcs15-init, + pkcs15-tool, + sc-hsm-tool, + westcos-tool: + Configuration block for OpenSC tools +

+

Configuration Options

+ debug = num; +

+ Amount of debug info to print (Default: + 0). A greater value means more + debug info. +

+ The environment variable + OPENSC_DEBUG overwrites this + setting. +

+ debug_file = filename; +

+ The file to which debug output will be written + (Default: stderr). Special + values stdout and + stderr are recognized. +

+ profile_dir = filename; +

+ PKCS#15 initialization/personalization profiles + directory for + pkcs15-init(1). + + (Default: /home/fm/.local/share/opensc). +

+ If this configuration value is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ProfileDir is + checked. +

+ disable_popups = bool; +

+ Disable pop-ups of built-in GUI (Default: false). +

+ enable_default_driver = bool; +

+ Enable default card driver (Default: + false). Default card driver is + explicitly enabled for + opensc-explorer(1). + + and + opensc-tool(1). + +

+ card_drivers = name... ; +

+ Whitelist of card drivers to load at start-up. + The special value internal (the + default) will load all statically linked drivers. +

+ If an unknown (i.e. not internal or old) driver is + supplied, a separate configuration configuration + block has to be written for the driver. A special + value old will load all + statically linked drivers that may be removed in + the future. +

+ The list of supported card driver names can be + retrieved from the output of opensc-tool + --list-drivers. +

+ The environment variable + OPENSC_DRIVER overwrites this + setting. +

+ ignored_readers = name... ; +

+ List of readers to ignore (Default: empty). If any + of the comma separated strings listed is matched in + a reader name (case sensitive, partial matching + possible), the reader is ignored by OpenSC. Use + opensc-tool --list-readers to + see all currently connected readers. +

+ reader_driver name { + block_contents + } + +

+ Configuration of the smart card reader driver where name is one of: +

+

+ See the section called “Configuration of Smart Card Reader Driver”. +

+ card_driver name { + block_contents + } + +

+ Configuration of the card driver where name is one of: +

+

+ card_atr hexstring { + block_contents + } + +

+ In addition to the built-in list of known cards in + the card driver, you can configure a new card for + the driver using the card_atr + block. +

+ For details see the section called “Configuration based on ATR”. +

+ secure_messaging name { + block_contents + } + +

+ Configuration options for the secure messaging profile name: +

+ module_name = filename; +

+ Name of external SM module (Default: libsmm-local.so). +

+ module_path = filename; +

+ Directory with external SM module + (Default: /home/fm/.local/lib). +

+ If this configuration value is not + found on Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\SmDir is + checked. +

+ module_data = value; +

+ Specific data to tune the module initialization. +

+ mode = value; +

+ Secure messaging mode. Known parameters: +

  • + transmit: + In this mode the + procedure to securize + an APDU is called by + the OpenSC general APDU + transmit procedure. In + this mode all APDUs, + except the ones + filtered by the card + specific procedure, are + securized. +

  • + acl: + In this mode APDU are + securized only if + needed by the ACLs of + the command to be + executed. +

+

+ flags = value; +

+ Secure messaging type specific flags. +

+ kmc = hexstring; +

+ Default KMC of the GP Card Manager for the Oberthur's Java cards. +

+ ifd_serial = hexstring; +
+ keyset[_aid]_num_enc = + value; + keyset[_aid]_num_mac = + value; +

+ Keyset values from IAM profiles of + the Gemalto IAS/ECC cards with an + optional application identifier +

+ framework name { + block_contents + } + +

+ Internal configuration options where name is one of: +

+

+ pkcs11 { + block_contents + } + +

+ Parameters for the OpenSC PKCS11 module. +

+ For details see the section called “Configuration of PKCS#11”. +

Configuration of Smart Card Reader Driver

Configuration Options for all Reader Drivers

+ max_send_size = num; + max_recv_size = num; +

+ Limit command and response sizes + (Default: + max_send_size + = 255, + max_recv_size + = 256) . Some + Readers don't propagate their + transceive capabilities correctly. + max_send_size and max_recv_size + allow setting the limits manually, + for example to enable extended + length capabilities. +

+ enable_escape bool; +

+ Detect reader capabilities with + escape commands (wrapped APDUs with + CLA=0xFF as defined by PC/SC pt. 3 + and BSI TR-03119, e.g. for getting + the UID, escaped PIN commands and + the reader's firmware version, + Default: false) +

Configuration of CT-API Readers

+ module filename { + ports = nums; + } + +

+ Load the specified CT-API module with the specified number of ports. +

Configuration of PC/SC Readers

+ connect_exclusive = bool; +

+ Connect to reader in exclusive mode + (Default: false)? + This option has no effect in Windows' minidriver. +

+ disconnect_action = action; +

+ What to do when disconnecting from + a card (SCardDisconnect). Valid + values are + leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ transaction_end_action = action; +

+ What to do at the end of a + transaction (SCardEndTransaction). + Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ reconnect_action = action; +

+ What to do when reconnection to a + card (SCardReconnect). Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ enable_pinpad = bool; +

+ Enable pinpad if detected (PC/SC + v2.0.2 Part 10, Default: + true) +

+ fixed_pinlength = num; +

+ Some pinpad readers can only handle + one exact length of the PIN. + fixed_pinlength + sets this value so that OpenSC + expands the padding to this length + (Default: 0, + i.e. not fixed). +

+ provider_library = filename; +

+ Use specific PC/SC provider + (Default: + libpcsclite.so.1). +

Configuration of OpenCT Readers

+ readers = num; +

+ Virtual readers to allocate (Default: 2). +

Configuration Options for German ID Card

+ can = value; +

+ German ID card requires the CAN to + be verified before QES PIN. This, + however, is not part of the PKCS#15 + profile of the card. So for + verifying the QES PIN we actually + need both. The CAN may be given + here. If the CAN is not given here, + it will be prompted on the command + line or on the reader (depending on + the reader's capabilities). +

+ st_dv_certificate = filename; + st_certificate = filename; + st_key = filename; +

+ QES is only possible with a Comfort + Reader (CAT-K), which holds a + cryptographic key to authenticate + itself as signature terminal (ST). + We usually will use the reader's + capability to sign the data. + However, during developement you + may specify soft certificates and + keys for a ST. +

+ An example PKI can be found in the + example data for the + German + ID card emulator +

Configuration Options for DNIe

+ user_consent_enabled = bool; +

+ Configure the warning message when + performing a signature operation + with the DNIe. Only used if + compiled with + --enable-dnie-ui +

+ user_consent_app = filename; +

+ Specify the pinentry application to + use if warning is configured to be + displayed using pinentry (Default: + /usr/bin/pinentry). + Only used if compiled with + --enable-dnie-ui +

Configuration based on ATR

+

+ atrmask = hexstring; +

+ The mask is logically AND'd with an + card ATR prior to comparison with + the ATR reference value above. + Using this mask allows identifying + and configuring multiple ATRs as + the same card model. +

+ driver = name; +

+ When enabled, overrides all + possible settings from the card + drivers built-in card configuration + list. +

+ name = name; +

+ Set card name for card drivers that + allows it. +

+ type = num; +

+ Allows setting the exact type of + the card internally used by the + card driver. Allowed values can be + found in the source code of + cards.h. +

+ flags = value... ; +

+ Card flags as an hex value. + Multiple values are OR'd together. + Depending on card driver, this + allows fine-tuning the capabilities + in the card driver for your card. +

+ Optionally, some known parameters + can be specified as strings: +

  • + rng: + On-board random number + source +

  • + keep_alive: + Request the card driver + to send a "keep alive" + command before each + transaction to make + sure that the required + applet is still + selected. +

+

+ pkcs15emu = name; +

+ When using PKCS#15 emulation, force + the emulation driver for specific + cards. Required for external + drivers, but can be used with + built-in drivers, too. +

+ force_protocol = value; +

+ Force protocol selection for + specific cards. Known parameters: +

  • + t0 +

  • + t1 +

  • + raw +

+

+ md_read_only = bool; +

+ Mark card as read/only card in + Minidriver/BaseCSP interface + (Default: false). +

+ md_supports_X509_enrollment = bool; +

+ Indicate X509 enrollment support at + Minidriver/BaseCSP interface + (Default: false). +

+ md_guid_as_id = bool; +

+ Use the GUID generated for the key + as id in the PKCS#15 structure + (Default: false, i.e. auto generated) +

+ md_guid_as_label = bool; +

+ Use the GUID generated for the key + as label in the PKCS#15 structure + (Default: false, + i.e. no label set). +

+ md_supports_container_key_gen = bool; +

+ Card allows generating key pairs on the card (Default: false). +

+ md_supports_container_key_import = bool; +

+ Card allows importing private keys + (Default: false). +

+ md_pinpad_dlg_title = value; +

+ Window title of the PIN pad dialog + (Default: "Windows + Security"). +

+ md_pinpad_dlg_icon = filename; +

+ Filename of the icon for the PIN + pad dialog; use + "" for no icon + (Default: Built-in smart card icon). +

+ md_pinpad_dlg_main = value; +

+ Main instruction of the PIN pad + dialog (Default: "OpenSC + Smart Card Provider"). +

+ md_pinpad_dlg_content_user = value; +

+ Content of the PIN pad dialog for + role "user" (Default: + "Please verify your + fingerprint or PIN on the + card."). +

+ md_pinpad_dlg_content_user_sign = value; +

+ Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). +

+ md_pinpad_dlg_content_user_sign = name; +

+ Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). +

+ md_pinpad_dlg_content_admin = value; +

+ Content of the PIN pad dialog for + role "admin" (Default: + "Please enter your PIN to + unblock the user PIN on the + PINPAD.") +

+ md_pinpad_dlg_content_cancel = value; +

+ Content of the PIN pad dialog after + pressing "Cancel", when the reader + doesn't respond to SCardCancel +

+ md_pinpad_dlg_expanded = value; +

+ Expanded information of the PIN pad + dialog (Default: "This + window will be closed + automatically after the PIN has + been submitted on the PINPAD + (timeout typically after 30 + seconds).") +

+ md_pinpad_dlg_expanded_cancel = value; +

+ Expanded information of the PIN pad + dialog after pressing "Cancel", + when the reader doesn't respond to + SCardCancel (Default: + "Some readers only support + canceling the operation on the + PIN pad. Press Cancel or remove + the card."). +

+ md_pinpad_dlg_enable_cancel = bool; +

+ Allow the user to cancel the PIN + pad dialog (Default: + false) +

+ md_pinpad_dlg_timeout = num; +

+ Time in seconds for the progress + bar of the PIN pad dialog to tick. + 0 removes the + progress bar (Default: + 30). +

+ notify_card_inserted = value; + notify_card_inserted_text = value; +

+ Notification title and text when + card was inserted (Default: + "Smart card + detected", ATR of + the card). +

+ notify_card_removed = value; + notify_card_removed_text = value; +

+ Notification title and text when + card was removed (Default: + "Smart card + removed", name of + smart card reader). +

+ notify_pin_good = value; + notify_pin_good_text = value; +

+ Notification title and text when + PIN was verified (Default: + "PIN verified", + "Smart card is + unlocked"). +

+ notify_pin_bad = value; + notify_pin_bad_text = value; +

+ Notification title and text when + PIN was wrong (Default: + "PIN not + verified", + "Smart card is + locked"). +

+

Configuration of PKCS#15 Framework

+ use_file_caching = bool; +

+ Whether to cache the card's files (e.g. + certificates) on disk in + file_cache_dir (Default: + false). +

+ If caching is done by a system process, the + cached files may be placed inaccessible from + the user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. +

+ file_cache_dir = filename; +

+ Where to cache the card's files. The default values are: +

  • + HOME/.eid/cache/ (Unix) +

  • + USERPROFILE\.eid-cache\ (Windows) +

+

+ If caching is done by a system process, the + cached files may be placed inaccessible from + a user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. +

+ use_pin_caching = bool; +

+ Use PIN caching (Default: true)? +

+ pin_cache_counter = num; +

+ How many times to use a PIN from cache before + re-authenticating it (Default: + 10)? +

+ pin_cache_ignore_user_consent = bool; +

+ Older PKCS#11 applications not supporting + CKA_ALWAYS_AUTHENTICATE may + need to set this to get signatures to work with + some cards (Default: false). +

+ enable_pkcs15_emulation = bool; +

+ Enable pkcs15 emulation (Default: + true). +

+ try_emulation_first = bool; +

+ Prefer pkcs15 emulation code before the normal + pkcs15 processing (Default: + no). Some cards work in + emu-only mode, and do not depend on this + option. +

+ enable_builtin_emulation = bool; +

+ Enable builtin emulators (Default: + true). +

+ builtin_emulators = emulators; +

+ List of the builtin pkcs15 emulators to test + (Default: esteid, openpgp, tcos, + starcert, itacns, infocamere, postecert, + actalis, atrust-acos, gemsafeGPK, + gemsafeV1, tccardos, PIV-II) +

+ pkcs11_enable_InitToken = bool; +

+ Enable initialization and card recognition + (Default: false). +

+ emulate name { + block_contents + } + +

+ Configuration options for a PKCS#15 emulator + where name is a + short name for an external card driver. +

+ module = filename; +

+ For pkcs15 emulators loaded from an + external shared library/DLL, you need to + specify the path name of the module and + customize the card_atr example above + correctly. +

+ function = name; +

+ Get the init function name of the + emulator (Default: + sc_pkcs15_init_func_ex) +

+ application hexstring { + block_contents + } + +

+ Configuration of the on-card-application where + hexstring is the + application identifier (AID). +

+ type = name; +

+ Type of application where + name is one + of: +

  • + generic +

  • + protected +

+

+ Used to distinguish the common access + application and application for which + authentication to perform some + operation cannot be obtained with the + common procedures (ex. object creation + protected by secure messaging). Used + by PKCS#11 module configured to expose + restricted number of slots. (for ex. + configured to expose only User PIN + slot, User and Sign PINs slots, ...) +

+ model = name; +
+ disable = bool; +

+ Do not expose application in PKCS#15 + framework (Default: + false) +

Configuration of Tokend

+ score = num; +

+ Score for OpenSC.tokend + (Default: 300). The tokend with + the highest score shall be used. +

+ ignore_private_certificate = bool; +

+ Tokend ignore to read PIN protected certificate + that is set + SC_PKCS15_CO_FLAG_PRIVATE flag + (Default: true). +

Configuration of PKCS#11

+ max_virtual_slots = num; +

+ Maximum Number of virtual slots (Default: + 16). If there are more slots + than defined here, the remaining slots will be + hidden from PKCS#11. +

+ slots_per_card = num; +

+ Maximum number of slots per smart card (Default: + 4). If the card has fewer keys + than defined here, the remaining number of slots + will be empty. +

+ lock_login = bool; +

+ By default, the OpenSC PKCS#11 module will not lock + your card once you authenticate to the card via + C_Login (Default: + false). + + Thus the other users or other applications is not + prevented from connecting to the card and perform + crypto operations (which may be possible because + you have already authenticated with the card). This + setting is not very secure. +

+ Also, if your card is not locked, you can enconter + problems due to limitation of the OpenSC framework, + that still is not thoroughly tested in the multi + threads environment. +

+ Your settings will be more secure if you choose to + lock your card. Nevertheless this behavior is a + known violation of PKCS#11 specification. Now once + one application has started using your card with + C_Login, no other application + can use it, until the first is done and calls + C_Logout or + C_Finalize. In the case of many + PKCS#11 application this does not happen until you + exit the application. +

+ Thus it is impossible to use several smart card + aware applications at the same time, e.g. you + cannot run both Firefox + and Thunderbird at the + same time, if both are configured to use your smart + card. +

+ atomic = bool; +

+ By default, interacting with the OpenSC PKCS#11 + module may change the state of the token, e.g. + whether a user is logged in or not (Default: + false). +

+ Thus other users or other applications may change + or use the state of the token unknowingly. Other + applications may create signatures abusing an + existing login or they may logout unnoticed. +

+ With this setting enabled the login state of the + token is tracked and cached (including the PIN). + Every transaction is preceded by restoring the + login state. After every transaction a logout is + performed. This setting by default also enables + lock_login to disable access for + other applications during the atomic transactions. +

+ Please note that any PIN-pad should be disabled + (see enable_pinpad), because the + user would have to input his PIN for every + transaction. +

+ init_sloppy = bool; +

+ With this setting disabled, the OpenSC PKCS#11 + module will initialize the slots available when the + application calls C_GetSlotList. + With this setting enabled, the slots will also get + initialized when C_GetSlotInfo + is called (Default: true). +

+ This setting is a workaround for + Java which does not call + C_GetSlotList when configured + with a static slot instead of + slotListIndex. +

+ user_pin_unblock_style = mode; +

+ User PIN unblock style mode + is one of: +

  • + none (Default): PIN + unblock is not possible with PKCS#11 API +

  • + set_pin_in_unlogged_session: + C_SetPIN in unlogged + session: PUK is passed as the + OldPin argument of the + C_SetPIN call. +

  • + set_pin_in_specific_context: + C_SetPIN in the + CKU_SPECIFIC_CONTEXT + logged session: PUK is passed as the + OldPin argument of the + C_SetPIN call. +

  • + init_pin_in_so_session: + C_InitPIN in + CKU_SO logged session: + User PIN 'UNBLOCK' is protected by SOPIN. + (PUK == SOPIN). +

+

+ create_puk_slot = bool; +

+ Create slot for unblocking PIN with PUK (Default: + false). This way PKCS#11 API can + be used to login with PUK and change a PIN. May + cause problems with some applications like + Firefox and + Thunderbird. +

+ create_slots_for_pins = mode... ; +

+ Symbolic names of PINs for which slots are created + where mode is a list of: +

  • + all (Default): All + non-SO-PIN, non-unblocking PINs +

  • + user: The first + global or first local PIN +

  • + sign: The second PIN + (first local, second global or second + local) +

+

+ Card can contain more then one PINs or more then + one on-card application with its own PINs. + Normally, to access all of them with the PKCS#11 + API a slot has to be created for all of them. Many + slots could be annoying for some of widely used + application, like FireFox. This configuration + parameter allows to select the PIN(s) for which + PKCS#11 slot will be created. +

+ Only PINs initialised, non-SO-PIN, non-unblocking + are associated with symbolic name. +

+ For the module to simulate the opensc-onepin module + behavior the following option + create_slots_for_pins = "user"; +

Environment

+ OPENSC_CONF +

+ Filename for a user defined configuration file +

+ If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ConfigFile is + checked. +

+ OPENSC_DEBUG +

+ See + debug = num; + +

+ OPENSC_DRIVER +

+ See + card_drivers = name... ; + +

+ CARDMOD_LOW_LEVEL_DEBUG +

+ Write minidriver debug information to + C:\tmp\md.log, if set to + 1. +

+ If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\MiniDriverDebug is + checked. +

+ PIV_EXT_AUTH_KEY, + PIV_9A_KEY, + PIV_9C_KEY, + PIV_9D_KEY, + PIV_9E_KEY +

+ PIV configuration during initialization with + piv-tool. +

Files

+ /home/fm/.local/etc/opensc.conf +

+ System-wide configuration file +

+ /home/fm/.local/share/doc/opensc/opensc.conf +

+ Extended example configuration file +


Name

pkcs15-profile — format of profile for pkcs15-init

Description

+ The pkcs15-init utility for PKCS #15 smart card + personalization is controlled via profiles. When starting, it will read two + such profiles at the moment, a generic application profile, and a card + specific profile. The generic profile must be specified on the command line, + while the card-specific file is selected based on the type of card detected. +

+ The generic application profile defines general information about the card + layout, such as the path of the application DF, various PKCS #15 files within + that directory, and the access conditions on these files. It also defines + general information about PIN, key and certificate objects. Currently, there + is only one such generic profile, pkcs15.profile. +

+ The card specific profile contains additional information required during + card initialization, such as location of PIN files, key references etc. + Profiles currently reside in @pkgdatadir@ +

Syntax

+ This section should contain information about the profile syntax. Will add + this soonishly. +

See also

+ pkcs15-init(1), + pkcs15-crypt(1) +

diff --git a/doc/files/files.xml b/doc/files/files.xml new file mode 100644 index 0000000000..3a01e1a970 --- /dev/null +++ b/doc/files/files.xml @@ -0,0 +1,10 @@ + + + + + OpenSC Manual Pages: Section 5 + + + + diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in new file mode 100644 index 0000000000..4a8b2ceb43 --- /dev/null +++ b/doc/files/opensc.conf.5.xml.in @@ -0,0 +1,1647 @@ + + + + opensc.conf + 5 + OpenSC + OpenSC File Formats + opensc + + + + opensc.conf + configuration file for OpenSC + + + + Description + + OpenSC obtains configuration data from the following sources in the following order + + + command-line options + + + environment variables + + + Windows registry (if available) + + + system-wide configuration file + (@sysconfdir@/opensc.conf) + + + + + The configuration file, opensc.conf, is composed + of blocks, which, in general, have the + following format: + +key, name { + block_contents +} + + block_contents is one or more + block_items where a + block_item is one of + + + # comment string + + + key, name = value; + + + block + + + + + At the root level, opensc.conf should contain + one or more application specific configuration blocks: + +app application { + block_contents +} + + application + specifies one of: + + + default: The fall-back configuration block for all applications + + + opensc-pkcs11: Configuration block for the PKCS#11 module (opensc-pkcs11@DYN_LIB_EXT@) + + + onepin-opensc-pkcs11: Configuration block for the PKCS#11 one-PIN-module (onepin-opensc-pkcs11@DYN_LIB_EXT@) + + + cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) + + + tokend: Configuration block for macOS' tokend (OpenSC.tokend) + + + cardos-tool, + cryptoflex-tool, + dnie-tool, + egk-tool, + eidenv, + gids-tool, + iasecc-tool, + netkey-tool, + npa-tool, + openpgp-tool, + opensc-asn1, + opensc-explorer, + opensc-notify, + opensc-tool, + piv-tool, + pkcs11-tool, + pkcs15-crypt, + pkcs15-init, + pkcs15-tool, + sc-hsm-tool, + westcos-tool: + Configuration block for OpenSC tools + + + + + + + Configuration Options + + + + + + + Amount of debug info to print (Default: + 0). A greater value means more + debug info. + + + The environment variable + OPENSC_DEBUG overwrites this + setting. + + + + + + + + The file to which debug output will be written + (Default: stderr). Special + values stdout and + stderr are recognized. + + + + + + + + PKCS#15 initialization/personalization profiles + directory for + + pkcs15-init + 1. + + (Default: @PROFILE_DIR_DEFAULT@). + + + If this configuration value is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ProfileDir is + checked. + + + + + + + + Disable pop-ups of built-in GUI (Default: false). + + + + + + + + Enable default card driver (Default: + false). Default card driver is + explicitly enabled for + + opensc-explorer + 1. + + and + + opensc-tool + 1. + + + + + + + + + Whitelist of card drivers to load at start-up. + The special value internal (the + default) will load all statically linked drivers. + + + If an unknown (i.e. not internal or old) driver is + supplied, a separate configuration configuration + block has to be written for the driver. A special + value old will load all + statically linked drivers that may be removed in + the future. + + + The list of supported card driver names can be + retrieved from the output of opensc-tool + --list-drivers. + + + The environment variable + OPENSC_DRIVER overwrites this + setting. + + + + + + + + List of readers to ignore (Default: empty). If any + of the comma separated strings listed is matched in + a reader name (case sensitive, partial matching + possible), the reader is ignored by OpenSC. Use + opensc-tool --list-readers to + see all currently connected readers. + + + + + + + + + Configuration of the smart card reader driver where name is one of: + + + ctapi: See + + + + pcsc: See + + + openct: See + + + cryptotokenkit: Configuration block for CryptoTokenKit readers + + + + + See . + + + + + + + + + Configuration of the card driver where name is one of: + + + npa: See + + + dnie: See + + + Any other value: Configuration block for an externally loaded card driver + + + + + + + + + + + In addition to the built-in list of known cards in + the card driver, you can configure a new card for + the driver using the + block. + + + For details see . + + + + + + + + + Configuration options for the secure messaging profile name: + + + + + + + + Name of external SM module (Default: @DEFAULT_SM_MODULE@). + + + + + + + + Directory with external SM module + (Default: @libdir@). + + + If this configuration value is not + found on Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\SmDir is + checked. + + + + + + + + Specific data to tune the module initialization. + + + + + + + + Secure messaging mode. Known parameters: + + + transmit: + In this mode the + procedure to securize + an APDU is called by + the OpenSC general APDU + transmit procedure. In + this mode all APDUs, + except the ones + filtered by the card + specific procedure, are + securized. + + + acl: + In this mode APDU are + securized only if + needed by the ACLs of + the command to be + executed. + + + + + + + + + + Secure messaging type specific flags. + + + + + + + + Default KMC of the GP Card Manager for the Oberthur's Java cards. + + + + + + + + + + + + + + Keyset values from IAM profiles of + the Gemalto IAS/ECC cards with an + optional application identifier + + + + + + + + + + + Internal configuration options where name is one of: + + + pkcs15: See + + + tokend: See + + + + + + + + + + + Parameters for the OpenSC PKCS11 module. + + + For details see . + + + + + + + Configuration of Smart Card Reader Driver + + + Configuration Options for all Reader Drivers + + + + + + + + Limit command and response sizes + (Default: + + = 255, + + = 256) . Some + Readers don't propagate their + transceive capabilities correctly. + max_send_size and max_recv_size + allow setting the limits manually, + for example to enable extended + length capabilities. + + + + + + + + Detect reader capabilities with + escape commands (wrapped APDUs with + CLA=0xFF as defined by PC/SC pt. 3 + and BSI TR-03119, e.g. for getting + the UID, escaped PIN commands and + the reader's firmware version, + Default: false) + + + + + + + Configuration of CT-API Readers + + + + + + + Load the specified CT-API module with the specified number of ports. + + + + + + + Configuration of PC/SC Readers + + + + + + + Connect to reader in exclusive mode + (Default: false)? + This option has no effect in Windows' minidriver. + + + + + + + + What to do when disconnecting from + a card (SCardDisconnect). Valid + values are + leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. + + + + + + + + What to do at the end of a + transaction (SCardEndTransaction). + Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. + + + + + + + + What to do when reconnection to a + card (SCardReconnect). Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. + + + + + + + + Enable pinpad if detected (PC/SC + v2.0.2 Part 10, Default: + true) + + + + + + + + Some pinpad readers can only handle + one exact length of the PIN. + + sets this value so that OpenSC + expands the padding to this length + (Default: 0, + i.e. not fixed). + + + + + + + + Use specific PC/SC provider + (Default: + @DEFAULT_PCSC_PROVIDER@). + + + + + + + Configuration of OpenCT Readers + + + + + + + Virtual readers to allocate (Default: 2). + + + + + + + + + Configuration Options for German ID Card + + + + + + + German ID card requires the CAN to + be verified before QES PIN. This, + however, is not part of the PKCS#15 + profile of the card. So for + verifying the QES PIN we actually + need both. The CAN may be given + here. If the CAN is not given here, + it will be prompted on the command + line or on the reader (depending on + the reader's capabilities). + + + + + + + + + + QES is only possible with a Comfort + Reader (CAT-K), which holds a + cryptographic key to authenticate + itself as signature terminal (ST). + We usually will use the reader's + capability to sign the data. + However, during developement you + may specify soft certificates and + keys for a ST. + + + An example PKI can be found in the + example data for the + German + ID card emulator + + + + + + + Configuration Options for DNIe + + + + + + + Configure the warning message when + performing a signature operation + with the DNIe. Only used if + compiled with + + + + + + + + + Specify the pinentry application to + use if warning is configured to be + displayed using pinentry (Default: + /usr/bin/pinentry). + Only used if compiled with + + + + + + + + Configuration based on ATR + + + + + + + + The mask is logically AND'd with an + card ATR prior to comparison with + the ATR reference value above. + Using this mask allows identifying + and configuring multiple ATRs as + the same card model. + + + + + + + + When enabled, overrides all + possible settings from the card + drivers built-in card configuration + list. + + + + + + + + Set card name for card drivers that + allows it. + + + + + + + + Allows setting the exact type of + the card internally used by the + card driver. Allowed values can be + found in the source code of + cards.h. + + + + + + + + Card flags as an hex value. + Multiple values are OR'd together. + Depending on card driver, this + allows fine-tuning the capabilities + in the card driver for your card. + + + Optionally, some known parameters + can be specified as strings: + + + rng: + On-board random number + source + + + keep_alive: + Request the card driver + to send a "keep alive" + command before each + transaction to make + sure that the required + applet is still + selected. + + + + + + + + + + When using PKCS#15 emulation, force + the emulation driver for specific + cards. Required for external + drivers, but can be used with + built-in drivers, too. + + + + + + + + Force protocol selection for + specific cards. Known parameters: + + + t0 + + + t1 + + + raw + + + + + + + + + + Mark card as read/only card in + Minidriver/BaseCSP interface + (Default: false). + + + + + + + + Indicate X509 enrollment support at + Minidriver/BaseCSP interface + (Default: false). + + + + + + + + Use the GUID generated for the key + as id in the PKCS#15 structure + (Default: false, i.e. auto generated) + + + + + + + + Use the GUID generated for the key + as label in the PKCS#15 structure + (Default: false, + i.e. no label set). + + + + + + + + Card allows generating key pairs on the card (Default: false). + + + + + + + + Card allows importing private keys + (Default: false). + + + + + + + + Window title of the PIN pad dialog + (Default: "Windows + Security"). + + + + + + + + Filename of the icon for the PIN + pad dialog; use + "" for no icon + (Default: Built-in smart card icon). + + + + + + + + Main instruction of the PIN pad + dialog (Default: "OpenSC + Smart Card Provider"). + + + + + + + + Content of the PIN pad dialog for + role "user" (Default: + "Please verify your + fingerprint or PIN on the + card."). + + + + + + + + Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). + + + + + + + + Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). + + + + + + + + Content of the PIN pad dialog for + role "admin" (Default: + "Please enter your PIN to + unblock the user PIN on the + PINPAD.") + + + + + + + + Content of the PIN pad dialog after + pressing "Cancel", when the reader + doesn't respond to SCardCancel + + + + + + + + Expanded information of the PIN pad + dialog (Default: "This + window will be closed + automatically after the PIN has + been submitted on the PINPAD + (timeout typically after 30 + seconds).") + + + + + + + + Expanded information of the PIN pad + dialog after pressing "Cancel", + when the reader doesn't respond to + SCardCancel (Default: + "Some readers only support + canceling the operation on the + PIN pad. Press Cancel or remove + the card."). + + + + + + + + Allow the user to cancel the PIN + pad dialog (Default: + false) + + + + + + + + Time in seconds for the progress + bar of the PIN pad dialog to tick. + 0 removes the + progress bar (Default: + 30). + + + + + + + + + Notification title and text when + card was inserted (Default: + "Smart card + detected", ATR of + the card). + + + + + + + + + Notification title and text when + card was removed (Default: + "Smart card + removed", name of + smart card reader). + + + + + + + + + Notification title and text when + PIN was verified (Default: + "PIN verified", + "Smart card is + unlocked"). + + + + + + + + + Notification title and text when + PIN was wrong (Default: + "PIN not + verified", + "Smart card is + locked"). + + + + + + + + Configuration of PKCS#15 Framework + + + + + + + Whether to cache the card's files (e.g. + certificates) on disk in + (Default: + false). + + + If caching is done by a system process, the + cached files may be placed inaccessible from + the user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. + + + + + + + + Where to cache the card's files. The default values are: + + + + HOME/.eid/cache/ (Unix) + + + + + USERPROFILE\.eid-cache\ (Windows) + + + + + + If caching is done by a system process, the + cached files may be placed inaccessible from + a user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. + + + + + + + + Use PIN caching (Default: true)? + + + + + + + + How many times to use a PIN from cache before + re-authenticating it (Default: + 10)? + + + + + + + + Older PKCS#11 applications not supporting + CKA_ALWAYS_AUTHENTICATE may + need to set this to get signatures to work with + some cards (Default: false). + + + + + + + + Enable pkcs15 emulation (Default: + true). + + + + + + + + Prefer pkcs15 emulation code before the normal + pkcs15 processing (Default: + no). Some cards work in + emu-only mode, and do not depend on this + option. + + + + + + + + Enable builtin emulators (Default: + true). + + + + + + + + List of the builtin pkcs15 emulators to test + (Default: westcos, openpgp, infocamere, + starcert, tcos, esteid, itacns, postecert, + PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, + atrust-acos, tccardos, entersafe, pteid, + oberthur, sc-hsm, dnie, gids, iasecc, jpki, + coolkey, din66291) + + + + + + + + Enable initialization and card recognition + (Default: false). + + + + + + + + Configuration options for a PKCS#15 emulator + where name is a + short name for an external card driver. + + + + + + + + For pkcs15 emulators loaded from an + external shared library/DLL, you need to + specify the path name of the module and + customize the card_atr example above + correctly. + + + + + + + + Get the init function name of the + emulator (Default: + sc_pkcs15_init_func_ex) + + + + + + + + + + + + Configuration of the on-card-application where + hexstring is the + application identifier (AID). + + + + + + + + Type of application where + name is one + of: + + + generic + + + protected + + + + + Used to distinguish the common access + application and application for which + authentication to perform some + operation cannot be obtained with the + common procedures (ex. object creation + protected by secure messaging). Used + by PKCS#11 module configured to expose + restricted number of slots. (for ex. + configured to expose only User PIN + slot, User and Sign PINs slots, ...) + + + + + + + + + + + + + Do not expose application in PKCS#15 + framework (Default: + false) + + + + + + + + + + Configuration of Tokend + + + + + + + Score for OpenSC.tokend + (Default: 300). The tokend with + the highest score shall be used. + + + + + + + + Tokend ignore to read PIN protected certificate + that is set + SC_PKCS15_CO_FLAG_PRIVATE flag + (Default: true). + + + + + + + Configuration of PKCS#11 + + + + + + + Maximum Number of virtual slots (Default: + 16). If there are more slots + than defined here, the remaining slots will be + hidden from PKCS#11. + + + + + + + + Maximum number of slots per smart card (Default: + 4). If the card has fewer keys + than defined here, the remaining number of slots + will be empty. + + + + + + + + By default, the OpenSC PKCS#11 module will not lock + your card once you authenticate to the card via + C_Login (Default: + false). + + Thus the other users or other applications is not + prevented from connecting to the card and perform + crypto operations (which may be possible because + you have already authenticated with the card). This + setting is not very secure. + + + Also, if your card is not locked, you can enconter + problems due to limitation of the OpenSC framework, + that still is not thoroughly tested in the multi + threads environment. + + + Your settings will be more secure if you choose to + lock your card. Nevertheless this behavior is a + known violation of PKCS#11 specification. Now once + one application has started using your card with + C_Login, no other application + can use it, until the first is done and calls + C_Logout or + C_Finalize. In the case of many + PKCS#11 application this does not happen until you + exit the application. + + + Thus it is impossible to use several smart card + aware applications at the same time, e.g. you + cannot run both Firefox + and Thunderbird at the + same time, if both are configured to use your smart + card. + + + + + + + + By default, interacting with the OpenSC PKCS#11 + module may change the state of the token, e.g. + whether a user is logged in or not (Default: + false). + + + Thus other users or other applications may change + or use the state of the token unknowingly. Other + applications may create signatures abusing an + existing login or they may logout unnoticed. + + + With this setting enabled the login state of the + token is tracked and cached (including the PIN). + Every transaction is preceded by restoring the + login state. After every transaction a logout is + performed. This setting by default also enables + to disable access for + other applications during the atomic transactions. + + + Please note that any PIN-pad should be disabled + (see ), because the + user would have to input his PIN for every + transaction. + + + + + + + + With this setting disabled, the OpenSC PKCS#11 + module will initialize the slots available when the + application calls C_GetSlotList. + With this setting enabled, the slots will also get + initialized when C_GetSlotInfo + is called (Default: true). + + + This setting is a workaround for + Java which does not call + C_GetSlotList when configured + with a static slot instead of + slotListIndex. + + + + + + + + User PIN unblock style mode + is one of: + + + none (Default): PIN + unblock is not possible with PKCS#11 API + + + set_pin_in_unlogged_session: + C_SetPIN in unlogged + session: PUK is passed as the + OldPin argument of the + C_SetPIN call. + + + set_pin_in_specific_context: + C_SetPIN in the + CKU_SPECIFIC_CONTEXT + logged session: PUK is passed as the + OldPin argument of the + C_SetPIN call. + + + init_pin_in_so_session: + C_InitPIN in + CKU_SO logged session: + User PIN 'UNBLOCK' is protected by SOPIN. + (PUK == SOPIN). + + + + + + + + + + Create slot for unblocking PIN with PUK (Default: + false). This way PKCS#11 API can + be used to login with PUK and change a PIN. May + cause problems with some applications like + Firefox and + Thunderbird. + + + + + + + + Symbolic names of PINs for which slots are created + where mode is a list of: + + + all (Default): All + non-SO-PIN, non-unblocking PINs + + + user: The first + global or first local PIN + + + sign: The second PIN + (first local, second global or second + local) + + + + + Card can contain more then one PINs or more then + one on-card application with its own PINs. + Normally, to access all of them with the PKCS#11 + API a slot has to be created for all of them. Many + slots could be annoying for some of widely used + application, like FireFox. This configuration + parameter allows to select the PIN(s) for which + PKCS#11 slot will be created. + + + Only PINs initialised, non-SO-PIN, non-unblocking + are associated with symbolic name. + + + For the module to simulate the opensc-onepin module + behavior the following option + + + + + + + + + + Environment + + + + OPENSC_CONF + + + Filename for a user defined configuration file + + + If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ConfigFile is + checked. + + + + + OPENSC_DEBUG + + + See + + + + + OPENSC_DRIVER + + + See + + + + + CARDMOD_LOW_LEVEL_DEBUG + + + Write minidriver debug information to + C:\tmp\md.log, if set to + 1. + + + If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\MiniDriverDebug is + checked. + + + + + PIV_EXT_AUTH_KEY, + PIV_9A_KEY, + PIV_9C_KEY, + PIV_9D_KEY, + PIV_9E_KEY + + + PIV configuration during initialization with + piv-tool. + + + + + + + Files + + + + @sysconfdir@/opensc.conf + + + System-wide configuration file + + + + + @docdir@/opensc.conf + + + Extended example configuration file + + + + + + diff --git a/doc/tools/pkcs15-profile.5.xml b/doc/files/pkcs15-profile.5.xml similarity index 100% rename from doc/tools/pkcs15-profile.5.xml rename to doc/files/pkcs15-profile.5.xml diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index b2b39b6f1f..e52d4ffd8c 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -12,22 +12,17 @@ endif if ENABLE_MAN man1_MANS = $(patsubst $(srcdir)/%.xml, %, $(wildcard $(srcdir)/*.1.xml)) -man5_MANS = $(patsubst $(srcdir)/%.xml, %, $(wildcard $(srcdir)/*.5.xml)) endif completion_DATA = $(patsubst $(srcdir)/%.1.xml, %, $(wildcard $(srcdir)/*.1.xml)) -tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdir)/*.5.xml) +tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< %.1: $(srcdir)/%.1.xml sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ | $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $< -%.5: $(srcdir)/%.5.xml - sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ - | $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $< - %: $(srcdir)/%.1.xml @echo $< $@ @cat $(srcdir)/completion-template \ @@ -48,4 +43,4 @@ tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) $(wildcard $(srcdi > $@ clean-local: - -rm -rf $(html_DATA) $(man1_MANS) $(man5_MANS) $(completion_DATA) + -rm -rf $(html_DATA) $(man1_MANS) $(completion_DATA) diff --git a/doc/tools/files.html b/doc/tools/files.html new file mode 100644 index 0000000000..edadd9861f --- /dev/null +++ b/doc/tools/files.html @@ -0,0 +1,1096 @@ +OpenSC Manual Pages: Section 5

OpenSC Manual Pages: Section 5


Table of Contents

opensc.conf — configuration file for OpenSC
pkcs15-profile — format of profile for pkcs15-init

Name

opensc.conf — configuration file for OpenSC

Description

+ OpenSC obtains configuration data from the following sources in the following order +

  1. + command-line options +

  2. + environment variables +

  3. + Windows registry (if available) +

  4. + system-wide configuration file + (/home/fm/.local/etc/opensc.conf) +

+

+ The configuration file, opensc.conf, is composed + of blocks, which, in general, have the + following format: +

+key [, name...] {
+	block_contents
+}
+			

+ block_contents is one or more + block_items where a + block_item is one of +

  • + # comment string +

  • + key [, name...] = value; +

  • + block +

+

+ At the root level, opensc.conf should contain + one or more application specific configuration blocks: +

+app application {
+	block_contents
+}
+			

+ application + specifies one of: +

  • + default: The fall-back configuration block for all applications +

  • + opensc-pkcs11: Configuration block for the PKCS#11 module (opensc-pkcs11.so) +

  • + onepin-opensc-pkcs11: Configuration block for the PKCS#11 one-PIN-module (onepin-opensc-pkcs11.so) +

  • + cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) +

  • + tokend: Configuration block for macOS' tokend (OpenSC.tokend) +

  • + cardos-tool, + cryptoflex-tool, + dnie-tool, + egk-tool, + eidenv, + gids-tool, + iasecc-tool, + netkey-tool, + npa-tool, + openpgp-tool, + opensc-asn1, + opensc-explorer, + opensc-notify, + opensc-tool, + piv-tool, + pkcs11-tool, + pkcs15-crypt, + pkcs15-init, + pkcs15-tool, + sc-hsm-tool, + westcos-tool: + Configuration block for OpenSC tools +

+

Configuration Options

+ debug = num; +

+ Amount of debug info to print (Default: + 0). A greater value means more + debug info. +

+ The environment variable + OPENSC_DEBUG overwrites this + setting. +

+ debug_file = filename; +

+ The file to which debug output will be written + (Default: stderr). Special + values stdout and + stderr are recognized. +

+ profile_dir = filename; +

+ PKCS#15 initialization/personalization profiles + directory for + pkcs15-init(1). + + (Default: /home/fm/.local/share/opensc). +

+ If this configuration value is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ProfileDir is + checked. +

+ disable_popups = bool; +

+ Disable pop-ups of built-in GUI (Default: false). +

+ enable_default_driver = bool; +

+ Enable default card driver (Default: + false). Default card driver is + explicitly enabled for + opensc-explorer(1). + + and + opensc-tool(1). + +

+ card_drivers = name... ; +

+ Whitelist of card drivers to load at start-up. + The special value internal (the + default) will load all statically linked drivers. +

+ If an unknown (i.e. not internal or old) driver is + supplied, a separate configuration configuration + block has to be written for the driver. A special + value old will load all + statically linked drivers that may be removed in + the future. +

+ The list of supported card driver names can be + retrieved from the output of opensc-tool + --list-drivers. +

+ The environment variable + OPENSC_DRIVER overwrites this + setting. +

+ ignored_readers = name... ; +

+ List of readers to ignore (Default: empty). If any + of the comma separated strings listed is matched in + a reader name (case sensitive, partial matching + possible), the reader is ignored by OpenSC. Use + opensc-tool --list-readers to + see all currently connected readers. +

+ reader_driver name { + block_contents + } + +

+ Configuration of the card reader driver where name is one of: +

+

+ For details see the section called “reader_driver Configuration Block”. +

+ card_driver name { + block_contents + } + +

+ Configuration of the card driver where name is one of: +

+

+ card_atr hexstring { + block_contents + } + +

+ In addition to the built-in list of known cards in + the card driver, you can configure a new card for + the driver using the card_atr + block. +

+ For details see the section called “card_atr Configuration Block”. +

+ secure_messaging name { + block_contents + } + +

+ Configuration options for the secure messaging profile name: +

+ module_name = filename; +

+ Name of external SM module (Default: libsmm-local.so). +

+ module_path = filename; +

+ Directory with external SM module + (Default: /home/fm/.local/lib). +

+ If this configuration value is not + found on Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\SmDir is + checked. +

+ module_data = value; +

+ Specific data to tune the module initialization. +

+ mode = value; +

+ Secure messaging mode. Known parameters: +

  • + transmit: + In this mode the + procedure to securize + an APDU is called by + the OpenSC general APDU + transmit procedure. In + this mode all APDUs, + except the ones + filtered by the card + specific procedure, are + securized. +

  • + acl: + In this mode APDU are + securized only if + needed by the ACLs of + the command to be + executed. +

+

+ flags = value; +

+ Secure messaging type specific flags. +

+ kmc = hexstring; +

+ Default KMC of the GP Card Manager for the Oberthur's Java cards. +

+ ifd_serial = hexstring; +
+ keyset[_aid]_num_enc = + value; + keyset[_aid]_num_mac = + value; +

+ Keyset values from IAM profiles of + the Gemalto IAS/ECC cards with an + optional application identifier +

+ framework name { + block_contents + } + +

+ Internal configuration options where name is one of: +

+

+ pkcs11 { + block_contents + } + +

+ Parameters for the OpenSC PKCS11 module. +

+ For details see the section called “pkcs11 Configuration Block”. +

reader_driver Configuration Block

Configuration Options for all Reader Drivers

+ max_send_size = num; + max_recv_size = num; +

+ Limit command and response sizes + (Default: + max_send_size + = 255, + max_recv_size + = 256) . Some + Readers don't propagate their + transceive capabilities correctly. + max_send_size and max_recv_size + allow setting the limits manually, + for example to enable extended + length capabilities. +

+ enable_escape bool; +

+ Detect reader capabilities with + escape commands (wrapped APDUs with + CLA=0xFF as defined by PC/SC pt. 3 + and BSI TR-03119, e.g. for getting + the UID, escaped PIN commands and + the reader's firmware version, + Default: false) +

Special Configuration Option for CT-API Readers

+ module filename { + ports = nums; + } + +

+ Load the specified CT-API module with the specified number of ports. +

Special Configuration Options for PC/SC Readers

+ connect_exclusive = bool; +

+ Connect to reader in exclusive mode + (Default: false)? + This option has no effect in Windows' minidriver. +

+ disconnect_action = action; +

+ What to do when disconnecting from + a card (SCardDisconnect). Valid + values are + leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ transaction_end_action = action; +

+ What to do at the end of a + transaction (SCardEndTransaction). + Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ reconnect_action = action; +

+ What to do when reconnection to a + card (SCardReconnect). Valid values + are leave, + reset, + unpower (Default: + leave). + This option has no effect in Windows' minidriver. +

+ enable_pinpad = bool; +

+ Enable pinpad if detected (PC/SC + v2.0.2 Part 10, Default: + true) +

+ fixed_pinlength = num; +

+ Some pinpad readers can only handle + one exact length of the PIN. + fixed_pinlength + sets this value so that OpenSC + expands the padding to this length + (Default: 0, + i.e. not fixed). +

+ provider_library = filename; +

+ Use specific PC/SC provider + (Default: + libpcsclite.so.1). +

Special Configuration Option for OpenCT Readers

+ readers = num; +

+ Virtual readers to allocate (Default: 2). +

Special Configuration Options for German ID Card

+ can = value; +

+ German ID card requires the CAN to + be verified before QES PIN. This, + however, is not part of the PKCS#15 + profile of the card. So for + verifying the QES PIN we actually + need both. The CAN may be given + here. If the CAN is not given here, + it will be prompted on the command + line or on the reader (depending on + the reader's capabilities). +

+ st_dv_certificate = filename; + st_certificate = filename; + st_key = filename; +

+ QES is only possible with a Comfort + Reader (CAT-K), which holds a + cryptographic key to authenticate + itself as signature terminal (ST). + We usually will use the reader's + capability to sign the data. + However, during developement you + may specify soft certificates and + keys for a ST. +

+ An example PKI can be found in the + example data for the + German + ID card emulator +

Special Configuration Options for DNIe

+ user_consent_enabled = bool; +

+ Configure the warning message when + performing a signature operation + with the DNIe. Only used if + compiled with + --enable-dnie-ui +

+ user_consent_app = filename; +

+ Specify the pinentry application to + use if warning is configured to be + displayed using pinentry (Default: + /usr/bin/pinentry). + Only used if compiled with + --enable-dnie-ui +

card_atr Configuration Block

+

+ Configuration options specified by the card's ATR: +

+ atrmask = hexstring; +

+ The mask is logically AND'd with an + card ATR prior to comparison with + the ATR reference value above. + Using this mask allows identifying + and configuring multiple ATRs as + the same card model. +

+ driver = name; +

+ When enabled, overrides all + possible settings from the card + drivers built-in card configuration + list. +

+ name = name; +

+ Set card name for card drivers that + allows it. +

+ type = num; +

+ Allows setting the exact type of + the card internally used by the + card driver. Allowed values can be + found in the source code of + cards.h. +

+ flags = value... ; +

+ Card flags as an hex value. + Multiple values are OR'd together. + Depending on card driver, this + allows fine-tuning the capabilities + in the card driver for your card. +

+ Optionally, some known parameters + can be specified as strings: +

  • + rng: + On-board random number + source +

  • + keep_alive: + Request the card driver + to send a "keep alive" + command before each + transaction to make + sure that the required + applet is still + selected. +

+

+ pkcs15emu = name; +

+ When using PKCS#15 emulation, force + the emulation driver for specific + cards. Required for external + drivers, but can be used with + built-in drivers, too. +

+ force_protocol = value; +

+ Force protocol selection for + specific cards. Known parameters: +

  • + t0 +

  • + t1 +

  • + raw +

+

+ md_read_only = bool; +

+ Mark card as read/only card in + Minidriver/BaseCSP interface + (Default: false). +

+ md_supports_X509_enrollment = bool; +

+ Indicate X509 enrollment support at + Minidriver/BaseCSP interface + (Default: false). +

+ md_guid_as_id = bool; +

+ Use the GUID generated for the key + as id in the PKCS#15 structure + (Default: false, i.e. auto generated) +

+ md_guid_as_label = bool; +

+ Use the GUID generated for the key + as label in the PKCS#15 structure + (Default: false, + i.e. no label set). +

+ md_supports_container_key_gen = bool; +

+ Card allows generating key pairs on the card (Default: false). +

+ md_supports_container_key_import = bool; +

+ Card allows importing private keys + (Default: false). +

+ md_pinpad_dlg_title = value; +

+ Window title of the PIN pad dialog + (Default: "Windows + Security"). +

+ md_pinpad_dlg_icon = filename; +

+ Filename of the icon for the PIN + pad dialog; use + "" for no icon + (Default: Built-in smart card icon). +

+ md_pinpad_dlg_main = value; +

+ Main instruction of the PIN pad + dialog (Default: "OpenSC + Smart Card Provider"). +

+ md_pinpad_dlg_content_user = value; +

+ Content of the PIN pad dialog for + role "user" (Default: + "Please verify your + fingerprint or PIN on the + card."). +

+ md_pinpad_dlg_content_user_sign = value; +

+ Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). +

+ md_pinpad_dlg_content_user_sign = name; +

+ Content of the PIN pad dialog for + role "user+signature" (Default: + "Please verify your + fingerprint or PIN for the + digital signature PIN on the + card."). +

+ md_pinpad_dlg_content_admin = value; +

+ Content of the PIN pad dialog for + role "admin" (Default: + "Please enter your PIN to + unblock the user PIN on the + PINPAD.") +

+ md_pinpad_dlg_content_cancel = value; +

+ Content of the PIN pad dialog after + pressing "Cancel", when the reader + doesn't respond to SCardCancel +

+ md_pinpad_dlg_expanded = value; +

+ Expanded information of the PIN pad + dialog (Default: "This + window will be closed + automatically after the PIN has + been submitted on the PINPAD + (timeout typically after 30 + seconds).") +

+ md_pinpad_dlg_expanded_cancel = value; +

+ Expanded information of the PIN pad + dialog after pressing "Cancel", + when the reader doesn't respond to + SCardCancel (Default: + "Some readers only support + canceling the operation on the + PIN pad. Press Cancel or remove + the card."). +

+ md_pinpad_dlg_enable_cancel = bool; +

+ Allow the user to cancel the PIN + pad dialog (Default: + false) +

+ md_pinpad_dlg_timeout = num; +

+ Time in seconds for the progress + bar of the PIN pad dialog to tick. + 0 removes the + progress bar (Default: + 30). +

+ notify_card_inserted = value; + notify_card_inserted_text = value; +

+ Notification title and text when + card was inserted (Default: + "Smart card + detected", ATR of + the card). +

+ notify_card_removed = value; + notify_card_removed_text = value; +

+ Notification title and text when + card was removed (Default: + "Smart card + removed", name of + smart card reader). +

+ notify_pin_good = value; + notify_pin_good_text = value; +

+ Notification title and text when + PIN was verified (Default: + "PIN verified", + "Smart card is + unlocked"). +

+ notify_pin_bad = value; + notify_pin_bad_text = value; +

+ Notification title and text when + PIN was wrong (Default: + "PIN not + verified", + "Smart card is + locked"). +

+

framework pkcs15 Configuration Block

+ use_file_caching = bool; +

+ Whether to cache the card's files (e.g. + certificates) on disk in + file_cache_dir (Default: + false). +

+ If caching is done by a system process, the + cached files may be placed inaccessible from + the user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. +

+ file_cache_dir = filename; +

+ Where to cache the card's files. The default values are: +

  • + HOME/.eid/cache/ (Unix) +

  • + USERPROFILE\.eid-cache\ (Windows) +

+

+ If caching is done by a system process, the + cached files may be placed inaccessible from + a user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. +

+ use_pin_caching = bool; +

+ Use PIN caching (Default: true)? +

+ pin_cache_counter = num; +

+ How many times to use a PIN from cache before + re-authenticating it (Default: + 10)? +

+ pin_cache_ignore_user_consent = bool; +

+ Older PKCS#11 applications not supporting + CKA_ALWAYS_AUTHENTICATE may + need to set this to get signatures to work with + some cards (Default: false). +

+ enable_pkcs15_emulation = bool; +

+ Enable pkcs15 emulation (Default: + true). +

+ try_emulation_first = bool; +

+ Prefer pkcs15 emulation code before the normal + pkcs15 processing (Default: + no). Some cards work in + emu-only mode, and do not depend on this + option. +

+ enable_builtin_emulation = bool; +

+ Enable builtin emulators (Default: + true). +

+ builtin_emulators = emulators; +

+ List of the builtin pkcs15 emulators to test + (Default: esteid, openpgp, tcos, + starcert, itacns, infocamere, postecert, + actalis, atrust-acos, gemsafeGPK, + gemsafeV1, tccardos, PIV-II) +

+ pkcs11_enable_InitToken = bool; +

+ Enable initialization and card recognition in + PKCS#11 layer (Default: + false). +

+ emulate name { + block_contents + } + +

+ Configuration options for a PKCS#15 emulator + where name is a + short name for an external card driver. +

+ module = filename; +

+ For pkcs15 emulators loaded from an + external shared library/DLL, you need to + specify the path name of the module and + customize the card_atr example above + correctly. +

+ function = name; +

+ Get the init function name of the + emulator (Default: + sc_pkcs15_init_func_ex) +

+ application hexstring { + block_contents + } + +

+ Configuration of the on-card-application where + hexstring is the + application identifier (AID). +

+ type = name; +

+ Type of application where + name is one + of: +

  • + generic +

  • + protected +

+

+ Used to distinguish the common access + application and application for which + authentication to perform some + operation cannot be obtained with the + common procedures (ex. object creation + protected by secure messaging). Used + by PKCS#11 module configured to expose + restricted number of slots. (for ex. + configured to expose only User PIN + slot, User and Sign PINs slots, ...) +

+ model = name; +
+ disable = bool; +

+ Do not expose application in PKCS#15 + framework (Default: + false) +

framework tokend Configuration Block

+ score = num; +

+ Score for OpenSC.tokend + (Default: 300). The tokend with + the highest score shall be used. +

+ ignore_private_certificate = bool; +

+ Tokend ignore to read PIN protected certificate + that is set + SC_PKCS15_CO_FLAG_PRIVATE flag + (Default: true). +

pkcs11 Configuration Block

+ max_virtual_slots = num; +

+ Maximum Number of virtual slots (Default: + 16). If there are more slots + than defined here, the remaining slots will be + hidden from PKCS#11. +

+ slots_per_card = num; +

+ Maximum number of slots per smart card (Default: + 4). If the card has fewer keys + than defined here, the remaining number of slots + will be empty. +

+ lock_login = bool; +

+ By default, the OpenSC PKCS#11 module will not lock + your card once you authenticate to the card via + C_Login (Default: + false). + + Thus the other users or other applications is not + prevented from connecting to the card and perform + crypto operations (which may be possible because + you have already authenticated with the card). This + setting is not very secure. +

+ Also, if your card is not locked, you can enconter + problems due to limitation of the OpenSC framework, + that still is not thoroughly tested in the multi + threads environment. +

+ Your settings will be more secure if you choose to + lock your card. Nevertheless this behavior is a + known violation of PKCS#11 specification. Now once + one application has started using your card with + C_Login, no other application + can use it, until the first is done and calls + C_Logout or + C_Finalize. In the case of many + PKCS#11 application this does not happen until you + exit the application. +

+ Thus it is impossible to use several smart card + aware applications at the same time, e.g. you + cannot run both Firefox + and Thunderbird at the + same time, if both are configured to use your smart + card. +

+ atomic = bool; +

+ By default, interacting with the OpenSC PKCS#11 + module may change the state of the token, e.g. + whether a user is logged in or not (Default: + false). +

+ Thus other users or other applications may change + or use the state of the token unknowingly. Other + applications may create signatures abusing an + existing login or they may logout unnoticed. +

+ With this setting enabled the login state of the + token is tracked and cached (including the PIN). + Every transaction is preceded by restoring the + login state. After every transaction a logout is + performed. This setting by default also enables + lock_login to disable access for + other applications during the atomic transactions. +

+ Please note that any PIN-pad should be disabled + (see enable_pinpad), because the + user would have to input his PIN for every + transaction. +

+ init_sloppy = bool; +

+ With this setting disabled, the OpenSC PKCS#11 + module will initialize the slots available when the + application calls C_GetSlotList. + With this setting enabled, the slots will also get + initialized when C_GetSlotInfo + is called (Default: true). +

+ This setting is a workaround for + Java which does not call + C_GetSlotList when configured + with a static slot instead of + slotListIndex. +

+ user_pin_unblock_style = mode; +

+ User PIN unblock style mode + is one of: +

  • + none (Default): PIN + unblock is not possible with PKCS#11 API +

  • + set_pin_in_unlogged_session: + C_SetPIN in unlogged + session: PUK is passed as the + OldPin argument of the + C_SetPIN call. +

  • + set_pin_in_specific_context: + C_SetPIN in the + CKU_SPECIFIC_CONTEXT + logged session: PUK is passed as the + OldPin argument of the + C_SetPIN call. +

  • + init_pin_in_so_session: + C_InitPIN in + CKU_SO logged session: + User PIN 'UNBLOCK' is protected by SOPIN. + (PUK == SOPIN). +

+

+ create_puk_slot = bool; +

+ Create slot for unblocking PIN with PUK (Default: + false). This way PKCS#11 API can + be used to login with PUK and change a PIN. May + cause problems with some applications like + Firefox and + Thunderbird. +

+ create_slots_for_pins = mode... ; +

+ Symbolic names of PINs for which slots are created + where mode is a list of: +

  • + all (Default): All + non-SO-PIN, non-unblocking PINs +

  • + user: The first + global or first local PIN +

  • + sign: The second PIN + (first local, second global or second + local) +

+

+ Card can contain more then one PINs or more then + one on-card application with its own PINs. + Normally, to access all of them with the PKCS#11 + API a slot has to be created for all of them. Many + slots could be ennoying for some of widely used + application, like FireFox. This configuration + parameter allows to select the PIN(s) for which + PKCS#11 slot will be created. +

+ Only PINs initialised, non-SO-PIN, non-unblocking + are associated with symbolic name. +

+ For the module to simulate the opensc-onepin module + behavior the following option + create_slots_for_pins = "user"; +

Environment

+ OPENSC_CONF +

+ Filename for a user defined configuration file +

+ If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\ConfigFile is + checked. +

+ CARDMOD_LOW_LEVEL_DEBUG +

+ Write minidriver debug information to + C:\tmp\md.log, if set to + 1. +

+ If this environment variable is not found on + Windows, the registry key + HKLM\Software\OpenSC + Project\OpenSC\MiniDriverDebug is + checked. +

+ PIV_EXT_AUTH_KEY, + PIV_9A_KEY, + PIV_9C_KEY, + PIV_9D_KEY, + PIV_9E_KEY +

+ PIV configuration during initialization with + piv-tool. +

Files

+ /home/fm/.local/etc/opensc.conf +

+ System-wide configuration file +

+ /home/fm/.local/share/doc/opensc/opensc.conf +

+ Extended example configuration file +

Security


Name

pkcs15-profile — format of profile for pkcs15-init

Description

+ The pkcs15-init utility for PKCS #15 smart card + personalization is controlled via profiles. When starting, it will read two + such profiles at the moment, a generic application profile, and a card + specific profile. The generic profile must be specified on the command line, + while the card-specific file is selected based on the type of card detected. +

+ The generic application profile defines general information about the card + layout, such as the path of the application DF, various PKCS #15 files within + that directory, and the access conditions on these files. It also defines + general information about PIN, key and certificate objects. Currently, there + is only one such generic profile, pkcs15.profile. +

+ The card specific profile contains additional information required during + card initialization, such as location of PIN files, key references etc. + Profiles currently reside in @pkgdatadir@ +

Syntax

+ This section should contain information about the profile syntax. Will add + this soonishly. +

See also

+ pkcs15-init(1), + pkcs15-crypt(1) +

diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 8e19c4d6a3..a0b0dac42f 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1,4 +1,4 @@ -OpenSC Manuals

OpenSC Manuals


OpenSC tools


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them -
cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
dnie-tool — displays information about DNIe based security tokens
eidenv — utility for accessing visible data from - electronic identity cards
gids-tool — smart card utility for GIDS cards
netkey-tool — administrative utility for Netkey E4 cards
iasecc-tool — displays information about IAS/ECC card + -->

OpenSC Manual Pages: Section 1


Table of Contents

cardos-tool — displays information about Card OS-based security tokens or format them +
cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
dnie-tool — displays information about DNIe based security tokens
egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) +
eidenv — utility for accessing visible data from + electronic identity cards
gids-tool — smart card utility for GIDS cards
iasecc-tool — displays information about IAS/ECC card +
netkey-tool — administrative utility for Netkey E4 cards
npa-tool — displays information on the German eID card (neuer Personalausweis, nPA).
openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens
netkey-tool — administrative utility for Netkey E4 cards
openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens
opensc-tool — generic smart card utility
opensc-explorer — + and compatible tokens
opensc-asn1 — parse ASN.1 data +
opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -
piv-tool — smart card utility for HSPD-12 PIV cards
pkcs11-tool — utility for managing and using PKCS #11 security tokens
pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
pkcs15-init — smart card personalization utility
pkcs15-tool — utility for manipulating PKCS #15 data structures +
opensc-notify — monitor smart card events and send notifications +
opensc-tool — generic smart card utility
piv-tool — smart card utility for HSPD-12 PIV cards
pkcs11-tool — utility for managing and using PKCS #11 security tokens
pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
pkcs15-init — smart card personalization utility
pkcs15-tool — utility for manipulating PKCS #15 data structures on smart cards and similar security tokens
sc-hsm-tool — smart card utility for SmartCard-HSM
westcos-tool — utility for manipulating data structures on westcos smart cards

Name

cardos-tool — displays information about Card OS-based security tokens or format them -

Synopsis

cardos-tool [OPTIONS]

Description

+

Synopsis

cardos-tool [OPTIONS]

Description

The cardos-tool utility is used to display information about smart cards and similar security tokens based on Siemens Card/OS M4. -

Options

+

Options

--card-driver name, -c name

Use the card driver specified by name. @@ -65,17 +68,26 @@ --format, -f

Format the card or token.

+ --help, + -h +

Print help message on screen.

--info, -i

Display information about the card or token.

- --reader number, - -r number + --reader num, + -r num

Specify the reader to use. By default, the first reader with a present card is used. If num is an ATR, the reader with a matching card will be chosen.

+ --startkey arg, + -s arg +

Specify startkey for format.

+ --change-startkey arg, + -S arg +

Change Startkey with given APDU command.

--verbose, -v

Causes cardos-tool to be more verbose. @@ -84,13 +96,13 @@ -w

Causes cardos-tool to wait for the token to be inserted into reader.

-

Authors

cardos-tool was written by - Andreas Jellinghaus .


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

+

Authors

cardos-tool was written by + Andreas Jellinghaus .


Name

cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

Synopsis

cryptoflex-tool [OPTIONS]

Description

cryptoflex-tool is used to manipulate PKCS data structures on Schlumberger Cryptoflex smart cards. Users can create, list and read PINs and keys stored on the smart card. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--app-df num, -a num @@ -152,12 +164,12 @@ -w

Causes cryptoflex-tool to wait for a card insertion.

-

See also

+

See also

pkcs15-tool(1) -

Authors

cryptoflex-tool was written by - Juha Yrjölä .


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

+

Authors

cryptoflex-tool was written by + Juha Yrjölä .


Name

dnie-tool — displays information about DNIe based security tokens

Synopsis

dnie-tool [OPTIONS]

Description

The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card. -

Options

+

Options

--idesp, -i @@ -185,8 +197,8 @@ value of the environment variable VARIABLE is used. The default is do not enter pin

- --reader number, - -r number + --reader num, + -r num

Specify the reader to use. By default, the first reader with a present card is used. If @@ -205,16 +217,48 @@

Causes dnie-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

Authors

dnie-tool was written by - Juan Antonio Martinez .


Name

eidenv — utility for accessing visible data from - electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

+

Authors

dnie-tool was written by + Juan Antonio Martinez .


Name

egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) +

Synopsis

egk-tool [OPTIONS]

Description

+ The egk-tool utility is used to display information stored on the German elektronic health card (elektronische Gesundheitskarte, eGK). +

Options

+

+ --help, + -h

Print help and exit.

+ --version, + -V

Print version and exit.

+ --reader arg, + -r arg +

+ Specify the reader to use. + Use -1 as arg + to automatically detect the reader to use. + By default, the first reader with a present card is used. +

+ --verbose, + -v +

+ Causes egk-tool to be more verbose. + Specify this flag several times to be more verbose. +

+

Health Care Application (HCA)

--pd

+ Show 'Persönliche Versicherungsdaten' (XML). +

--vd

+ Show 'Allgemeine Versicherungsdaten' (XML). +

--gvd

+ Show 'Geschützte Versicherungsdaten' (XML). +

--vsd-status

+ Show 'Versichertenstammdaten-Status'. +

Authors

egk-tool was written by + Frank Morgner .


Name

eidenv — utility for accessing visible data from + electronic identity cards

Synopsis

eidenv [OPTIONS]

Description

The eidenv utility is used for accessing data from electronic identity cards (like national eID cards) which might not be present in PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

--exec prog, -x prog @@ -247,11 +291,11 @@ --wait, -w

Wait for a card to be inserted

-

Authors

eidenv utility was written by - Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

+

Authors

eidenv utility was written by + Stef Hoeben and Martin Paljak .


Name

gids-tool — smart card utility for GIDS cards

Synopsis

gids-tool [OPTIONS]

The gids-tool utility can be used from the command line to perform miscellaneous smart card operations on a GIDS smart card. -

Options

+

Options

-X, --initialize @@ -286,96 +330,15 @@ --verbose

Verbose operation. Use several times to enable debug output.

-

See also

+

See also

opensc-tool(1) -

Authors

gids-tool was written by - Vincent Le Toux .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the - command line to perform some smart card operations with NetKey E4 cards - that cannot be done easily with other OpenSC-tools, such as changing local - PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

-

- --help, - -h -

Displays a short help message.

- --pin pin-value, - -p pin-value -

Specifies the current value of the global PIN.

- --puk pin-value, - -u pin-value -

Specifies the current value of the global PUK.

- --pin0 pin-value, - -0 pin-value -

Specifies the current value of the local PIN0 (aka local PIN).

- --pin1 pin-value, - -1 pin-value -

Specifies the current value of the local PIN1 (aka local PUK).

- --reader number, - -r number -

- Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. -

- -v -

Causes netkey-tool to be more verbose. This - options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 - one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string - (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. - Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will - display information about the smart cards pins and certificates. This will not change - your card in any aspect (assumed there are no bugs in netkey-tool). - In particular the tries-left counters of the pins are investigated without doing - actual pin-verifications.

If you specify the global PIN via the --pin option, - netkey-tool will also display the initial value of the cards - global PUK. If your global PUK was changed netkey-tool will still - display its initial value. There's no way to recover a lost global PUK once it was changed. - There's also no way to display the initial value of your global PUK without knowing the - current value of your global PIN.

For most of the commands that netkey-tool can execute, you have - to specify one pin. One notable exception is the nullpin command, but - this command can only be executed once in the lifetime of a NetKey E4 card.

-

- cert number filename -

This command will read one of your cards certificates (as specified by - number) and save this certificate into file filename - in PEM-format. Certificates on a NetKey E4 card are readable without a pin, so you don't - have to specify one.

- cert filename number -

This command will read the first PEM-encoded certificate from file - filename and store this into your smart cards certificate file - number. Some of your smart cards certificate files might be readonly, so - this will not work with all values of number. If a certificate file is - writable you must specify a pin in order to change it. If you try to use this command - without specifying a pin, netkey-tool will tell you which one is - needed.

- change { pin | puk | - pin0 | pin1 } new-pin -

This changes the value of the specified pin to the given new value. - You must specify either the current value of the pin or another pin to be able to do - this and if you don't specify a correct one, netkey-tool will tell - you which one is needed.

- nullpin initial-pin -

This command can be executed only if the global PIN of your card is - in nullpin-state. There's no way to return back to nullpin-state once you have changed - your global PIN. You don't need a pin to execute the nullpin-command. After a successful - nullpin-command netkey-tool will display your cards initial - PUK-value.

- unblock { pin | pin0 | pin1 } -

This unblocks the specified pin. You must specify another pin - to be able to do this and if you don't specify a correct one, - netkey-tool will tell you which one is needed.

-

See also

- opensc-explorer(1) -

Authors

netkey-tool was written by - Peter Koch .


Name

iasecc-tool — displays information about IAS/ECC card -

Synopsis

iasecc-tool [OPTIONS]

Description

+

Authors

gids-tool was written by + Vincent Le Toux .


Name

iasecc-tool — displays information about IAS/ECC card +

Synopsis

iasecc-tool [OPTIONS]

Description

The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards. -

Options

+

Options

- --reader number, + --reader num,

Specify the reader to use. By default, the first reader with a present card is used. If @@ -397,91 +360,12 @@ -w

Causes iasecc-tool to wait for the token to be inserted into reader.

-

Authors

iasecc-tool was written by - Viktor Tarasov .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

- The openpgp-tool utility is used for - accessing data from the OpenPGP v1.1 and v2.0 smart cards - and compatible tokens like e.g. GPF CryptoStick v1.x, - which might not be present in - PKCS#15 objects but available in custom files on the - card. The data can be printed on screen or used by - other programs via environment variables. -

Options

-

- --exec prog, - -x prog -

- Execute the given program with data in environment variables. -

- --help, - -h -

- Print help message on screen. -

- --raw -

- Print values in raw format, as they are stored on the card. -

- --pretty -

- Print values in pretty format. -

- --user-info, - -U -

- Show card holder information. -

- --reader num, - -r num -

- Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. -

- --verify pintype -

- Verify PIN (CHV1, CHV2 or CHV3). -

- --pin string -

- The PIN text to verify. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used. -

- --gen-key ID, - -G ID -

- Generate key. Specify key ID (1, 2 or 3) to generate. -

- --key-length bitlength, - -L bitlength -

- Length (default 2048 bit) of the key to be generated. -

- --version, - -V -

- Print the version of the utility and exit. -

- --verbose, - -v -

- Verbose operation. Use several times to enable debug output. -

- --wait, - -w -

- Wait for a card to be inserted. -

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the +

Authors

iasecc-tool was written by + Viktor Tarasov .


Name

netkey-tool — administrative utility for Netkey E4 cards

Synopsis

netkey-tool [OPTIONS] [COMMAND]

Description

The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

Options

+ the initial PUK-value.

Options

--help, -h @@ -498,8 +382,8 @@ --pin1 pin-value, -1 pin-value

Specifies the current value of the local PIN1 (aka local PUK).

- --reader number, - -r number + --reader num, + -r num

Specify the reader to use. By default, the first reader with a present card is used. If @@ -509,11 +393,11 @@ -v

Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

-

PIN format

With the -p, -u, -0 or the -1 +

PIN format

With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

Commands

When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -539,8 +423,9 @@ writable you must specify a pin in order to change it. If you try to use this command without specifying a pin, netkey-tool will tell you which one is needed.

- change { pin | puk | - pin0 | pin1 } new-pin + change + { pin | puk | pin0 | pin1 } + new-pin

This changes the value of the specified pin to the given new value. You must specify either the current value of the pin or another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell @@ -551,15 +436,159 @@ your global PIN. You don't need a pin to execute the nullpin-command. After a successful nullpin-command netkey-tool will display your cards initial PUK-value.

- unblock { pin | pin0 | pin1 } + unblock + { pin | pin0 | pin1 }

This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

-

See also

+

See also

opensc-explorer(1) -

Authors

netkey-tool was written by - Peter Koch .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

+

Authors

netkey-tool was written by + Peter Koch .


Name

npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). +

Synopsis

npa-tool [OPTIONS]

Description

+ The npa-tool utility is used to display information + stored on the German eID card (neuer Personalausweis, nPA), + and to perform some write and verification operations. +

Options

+

+ --help, + -h

Print help and exit.

+ --version, + -V

Print version and exit.

+ --reader arg, + -r arg +

+ Specify the reader to use. + Use -1 as arg + to automatically detect the reader to use. + By default, the first reader with a present card is used. +

+ --verbose, + -v +

+ Causes npa-tool to be more verbose. + Specify this flag several times to be more verbose. +

+

Password Authenticated Connection Establishment (PACE)

+ --pin [STRING], + -p [STRING] +

+ Run PACE with (transport) eID-PIN. +

+ --puk [STRING], + -u [STRING] +

+ Run PACE with PUK. +

+ --can [STRING], + -c [STRING] +

+ Run PACE with Card Access Number (CAN). +

+ --mrz [STRING], + -m [STRING] +

+ Run PACE with Machine Readable Zone (MRZ). + Enter the MRZ without newlines. +

--env

+ Specify whether to use environment variables PIN, + PUK, CAN, MRZ, + and NEWPIN. + You may want to clean your environment before enabling this. + (default=off) +

PIN management

+ --new-pin [STRING], + -N [STRING] +

+ Install a new PIN. +

+ --resume, + -R +

+ Resume eID-PIN (uses CAN to activate last retry). + (default=off) +

+ --unblock, + -U +

+ Unblock PIN (uses PUK to activate three more retries). + (default=off) +

Terminal Authentication (TA) and Chip Authentication (CA)

+ --cv-certificate FILENAME, + -C FILENAME +

+ Specify Card Verifiable (CV) certificate + to create a certificate chain. + The option can be given multiple times, in which case the + order is important. +

--cert-desc HEX_STRING

+ Certificate description to show for Terminal Authentication. +

--chat HEX_STRING

+ Specify the Card Holder Authorization Template + (CHAT) to use. + If not given, it defaults to the terminal's CHAT. + Use 7F4C0E060904007F000703010203530103 + to trigger EAC on the CAT-C (Komfortleser). +

+ --auxiliary-data HEX_STRING, + -A HEX_STRING +

+ Specify the terminal's auxiliary data. + If not given, the default is determined by verification + of validity, age and community ID. +

+ --private-key FILENAME, + -P FILENAME +

+ Specify the terminal's private key. +

--cvc-dir DIRECTORY

+ Specify where to look for the certificate of the + Country Verifying Certification Authority + (CVCA). + If not given, it defaults to + /home/fm/.local/etc/eac/cvc. +

+ --x509-dir DIRECTORY

+ Specify where to look for the X.509 certificate. + If not given, it defaults to + /home/fm/.local/etc/eac/x509. +

--disable-ta-checks

+ Disable checking the validity period of CV certificates. + (default=off) +

--disable-ca-checks

+ Disable passive authentication. (default=off) +

Read and write data groups

--read-dg1

Read data group 1: Document Type.

--read-dg2

Read data group 2: Issuing State.

--read-dg3

Read data group 3: Date of Expiry.

--read-dg4

Read data group 4: Given Name(s).

--read-dg5

Read data group 5: Family Name.

--read-dg6

Read data group 6: Religious/Artistic Name.

--read-dg7

Read data group 7: Academic Title.

--read-dg8

Read data group 8: Date of Birth.

--read-dg9

Read data group 9: Place of Birth.

--read-dg10

Read data group 10: Nationality.

--read-dg11

Read data group 11: Sex.

--read-dg12

Read data group 12: Optional Data.

--read-dg13

Read data group 13: Birth Name.

--read-dg14

Read data group 14.

--read-dg15

Read data group 15.

--read-dg16

Read data group 16.

--read-dg17

Read data group 17: Normal Place of Residence.

--read-dg18

Read data group 18: Community ID.

--read-dg19

Read data group 19: Residence Permit I.

--read-dg20

Read data group 20: Residence Permit II.

--read-dg21

Read data group 21: Optional Data.

+ --write-dg17 HEX_STRING

Write data group 17: Normal Place of Residence.

+ --write-dg18 HEX_STRING

Write data group 18: Community ID.

+ --write-dg19 HEX_STRING

Write data group 19: Residence Permit I.

+ --write-dg20 HEX_STRING

Write data group 20: Residence Permit II.

--write-dg21 HEX_STRING

Write data group 21: Optional Data.

Verification of validity, age and community ID

--verify-validity YYYYMMDD

+ Verify chip's validity with a reference date. +

--older-than YYYYMMDD

+ Verify age with a reference date. +

--verify-community HEX_STRING

+ Verify community ID with a reference ID. +

Special options, not always useful

+ --break, + -b +

+ Brute force PIN, CAN or PUK. + Use together with options -p, + -a, or -u. + (default=off) +

+ --translate FILENAME, + -t FILENAME +

+ Specify the file with APDUs of HEX_STRINGs to send + through the secure channel. + (default=`stdin') +

--tr-03110v201

+ Force compliance to BSI TR-03110 version 2.01. (default=off) +

--disable-all-checks

+ Disable all checking of fly-by-data. (default=off) +

Authors

npa-tool was written by + Frank Morgner .


Name

openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens

Synopsis

openpgp-tool [OPTIONS]

Description

The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -567,152 +596,124 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

Options

+

Options

+ --del-key arg +

+ Delete key indicated by arg. + arg can be 1, + 2, 3, or + all. +

+ --do arg, + -d arg +

+ Dump private data object (DO) + indicated by arg. + arg can be in the form + x, + 10x, or + 010x + to access DO 010x, + where x is 1, + 2, 3, or + 4. +

+ --erase, + -E +

+ Erase (i.e. reset) the card. +

--exec prog, -x prog

- Execute the given program with data in environment variables. + Execute the given program with data in environment variables. +

+ --gen-key arg, + -G arg +

+ Generate key with the ID given as arg. + arg can be one of 1, + 2, or 3.

--help, -h

- Print help message on screen. + Print help message on screen.

- --raw + --key-length bitlength, + -L bitlength

- Print values in raw format, as they are stored on the card. + Specify the length of the key to be generated. + If not given, it defaults to 2048 bit. +

+ --pin string +

+ The PIN text to verify. If set to + env:VARIABLE, the value of + the environment variable + VARIABLE is used.

--pretty

- Print values in pretty format. + Print values in pretty format.

- --user-info, - -U + --raw

- Show card holder information. + Print values in raw format, as they are stored on the card.

--reader num, -r num

- Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. -

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

+ --user-info, + -U +

+ Show card holder information. +

--verify pintype

Verify PIN (CHV1, CHV2 or CHV3). -

- --pin string -

- The PIN text to verify. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used. -

- --gen-key ID, - -G ID -

- Generate key. Specify key ID (1, 2 or 3) to generate. -

- --key-length bitlength, - -L bitlength -

- Length (default 2048 bit) of the key to be generated. -

+

--version, -V

- Print the version of the utility and exit. + Print the version of the utility and exit.

--verbose, -v

- Verbose operation. Use several times to enable debug output. + Verbose operation. Use several times to enable debug output.

--wait, -w

- Wait for a card to be inserted. + Wait for a card to be inserted.

-

Authors

openpgp-tool utility was written by - Peter Marschall .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

- The opensc-tool utility can be used from the command line to perform - miscellaneous smart card operations such as getting the card ATR or - sending arbitrary APDU commands to a card. -

Options

+

Authors

openpgp-tool utility was written by + Peter Marschall .


Name

opensc-asn1 — parse ASN.1 data +

Synopsis

opensc-asn1 [OPTIONS] [FILES]

Description

+ The opensc-asn1 utility is used to parse ASN.1 data. +

Options

+ --help, + -h

Print help and exit.

--version, -

Print the OpenSC package release version.

- --atr, - -a -

Print the Answer To Reset (ATR) of the card. - Output is in hex byte format

- --card-driver driver, - -c driver -

Use the given card driver. - The default is auto-detected.

- --list-algorithms, -

Lists algorithms supported by card

- --info, - -i -

Print information about OpenSC, such as version and enabled components.

- --list-drivers, - -D -

List all installed card drivers.

- --list-files, - -f -

Recursively list all files stored on card.

- --list-readers, - -l -

List all configured readers.

- --name, - -n -

Print the name of the inserted card (driver).

- --get-conf-entry conf, - -G conf -

Get configuration key, format: section:name:key

- --set-conf-entry conf, - -S conf -

Get configuration key, format: section:name:key:value

- --reader num, - -r num -

- Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. -

- --reset[=type], -

Resets the card in reader. - The default reset type is cold, but warm reset is also possible.

- --send-apdu apdu, - -s apdu -

Sends an arbitrary APDU to the card in the format - AA:BB:CC:DD:EE:FF....

- --serial -

Print the card serial number (normally the ICCSN). - Output is in hex byte format

- --verbose, - -v -

Causes opensc-tool to be more verbose. - Specify this flag several times to enable debug output in the opensc library.

- --wait, - -w -

Wait for a card to be inserted.

-

See also

- opensc-explorer(1) -

Authors

opensc-tool was written by - Juha Yrjölä .


Name

opensc-explorer — + -V

Print version and exit.

+

Authors

opensc-asn1 was written by + Frank Morgner .


Name

opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

+

Synopsis

opensc-explorer [OPTIONS] [SCRIPT]

Description

The opensc-explorer utility can be used interactively to perform miscellaneous operations such as exploring the contents of or sending arbitrary APDU commands to a smart card or similar security token. -

Options

+

Options

The following are the command-line options for opensc-explorer. There are additional interactive commands available once it is running. @@ -747,34 +748,44 @@

--wait, -w

Wait for a card to be inserted

-

Commands

+

Commands

The following commands are supported at opensc-explorer's interactive prompt or in script files passed via the command line parameter SCRIPT.

- apdu hex-data + apdu + hex-data

Send a custom APDU command hex-data.

- asn1 file-id + asn1 + file-id

Parse and print the ASN.1 encoded content of the file specified by file-id.

- cat [file-id | sfi:short-id] + cat + [ file-id | sfi:short-id ]

Print the contents of the currently selected EF or the contents of a file specified by file-id or the short file id short-id.

- cd {.. | file-id | aid:DF-name} + cd + { .. | file-id | aid:DF-name }

Change to another DF specified by the argument passed. - If the argument given is .., then move up one level in the - file system hierarchy. - If it is file-id, which must be a DF directly + If the argument given is .., + then move up one level in the file system hierarchy. + If it is file-id, + which must be a DF directly beneath the current DF, then change to that DF. If it is an application identifier given as aid:DF-name, then jump to the MF of the application denoted by DF-name.

- change CHVpin-ref [[old-pin] new-pin] + change + CHVpin-ref + [ + [old-pin] + new-pin + ]

Change a PIN, where pin-ref is the PIN reference.

Examples:

change CHV2 00:00:00:00:00:00 "foobar"

@@ -788,70 +799,102 @@ Change PIN CHV2 using the card reader's pinpad.

- create file-id size + create + file-id + size

Create a new EF. file-id specifies the id number and size is the size of the new file.

- debug [level] + debug + [level]

Set OpenSC debug level to level.

If level is omitted the current debug level will be shown.

- delete file-id + delete + file-id

Remove the EF or DF specified by file-id

- do_get hex-tag [output] + do_get + hex-tag + [output]

Copy the internal card's 'tagged' data into the local file.

The local file is specified by output while the tag of the card's data is specified by hex-tag.

If output is omitted, the name of the output file will be derived from hex-tag.

- do_put hex-tag input + do_put + hex-tag + input

Update internal card's 'tagged' data.

hex-tag is the tag of the card's data. input is the filename of the source file or the literal data presented as a sequence of hexadecimal values or " enclosed string.

- echo string ... + echo + string...

Print the strings given.

erase

Erase the card, if the card supports it.

- get file-id [output] + get + file-id + [output]

Copy an EF to a local file. The local file is specified by output while the card file is specified by file-id.

If output is omitted, the name of the output file will be derived from the full card path to file-id.

- info [file-id] + info + [file-id]

Display attributes of a file specified by file-id. If file-id is not supplied, the attributes of the current file are printed.

- ls [pattern ...] + ls + [pattern...]

List files in the current DF. If no pattern is given, then all files are listed. If one ore more patterns are given, only files matching at least one pattern are listed.

- find [start-id [end-id]] + find + [ + start-id + [end-id] + ]

Find all files in the current DF. Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF).

- find_tags [start-tag [end-tag]] + find_tags + [ + start-tag + [end-tag] + ]

Find all tags of data objects in the current context. Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF).

- mkdir file-id size + mkdir + file-id + size

Create a DF. file-id specifies the id number and size is the size of the new file.

- put file-id input + put + file-id + input

Copy a local file to the card. The local file is specified by input while the card file is specified by file-id.

quit

Exit the program.

- random count + random + count

Generate random sequence of count bytes.

- rm file-id + rm + file-id

Remove the EF or DF specified by file-id

- unblock CHVpin-ref [puk [new pin]] + unblock + CHVpin-ref + [ + puk + [new-pin] + ]

Unblock the PIN denoted by pin-ref using the PUK puk, and set potentially - change its value to new pin. + change its value to new-pin.

PUK and PIN values can be a sequence of hexadecimal values, "-enclosed strings, empty (""), @@ -881,19 +924,28 @@ The unblock code and new PIN value are prompted by pinpad.

- update_binary file-id offs data + update_binary + file-id + offs + data

Binary update of the file specified by file-id with the literal data data starting from offset specified by offs.

data can be supplied as a sequencer of the hex values or as a " enclosed string.

- update_record file-id rec-nr rec-offs data + update_record + file-id + rec-nr + rec-offs + data

Update record specified by rec-nr of the file specified by file-id with the literal data data starting from offset specified by rec-offs.

data can be supplied as a sequence of the hex values or as a " enclosed string.

- verify key-type key-id [key] + verify + key-typekey-id + [key]

Present a PIN or key to the card, where key-type can be one of CHV, KEY, AUT or PRO. @@ -919,18 +971,132 @@ get the value from the card reader's pin pad.

- sm [open]|[close] -

Calls the card's open or close Secure Messaging handler.

-

See also

+ sm + { open | close } +

Calls the card's open or close Secure Messaging handler.

+

See also

opensc-tool(1) -

Authors

opensc-explorer was written by - Juha Yrjölä .


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

+

Authors

opensc-explorer was written by + Juha Yrjölä .


Name

opensc-notify — monitor smart card events and send notifications +

Synopsis

opensc-notify [OPTIONS]

Description

+ The opensc-notify utility is used to + monitor smart card events and send the appropriate notification. +

Options

+

+ --help, + -h

Print help and exit.

+ --version, + -V

Print version and exit.

+

Mode: customized

+ Send customized notifications. +

+ --title [STRING], + -t [STRING] +

+ Specify the title of the notification. +

+ --message [STRING], + -m [STRING] +

+ Specify the main text of the notification. +

Mode: standard

+ Manually send standard notifications. +

+ --notify-card-inserted, + -I

+ See notify_card_inserted + in opensc.conf (default=off). +

+ --notify-card-removed, + -R

+ See notify_card_removed + in opensc.conf (default=off). +

+ --notify-pin-good, + -G

+ See notify_pin_good + in opensc.conf (default=off). +

+ --notify-pin-bad, + -B

+ See notify_pin_bad + in opensc.conf (default=off). +

Authors

opensc-notify was written by + Frank Morgner .


Name

opensc-tool — generic smart card utility

Synopsis

opensc-tool [OPTIONS]

Description

+ The opensc-tool utility can be used from the command line to perform + miscellaneous smart card operations such as getting the card ATR or + sending arbitrary APDU commands to a card. +

Options

+

+ --version, +

Print the OpenSC package release version.

+ --atr, + -a +

Print the Answer To Reset (ATR) of the card. + Output is in hex byte format

+ --card-driver driver, + -c driver +

Use the given card driver. + The default is auto-detected.

+ --list-algorithms, +

Lists algorithms supported by card

+ --info, + -i +

Print information about OpenSC, such as version and enabled components.

+ --list-drivers, + -D +

List all installed card drivers.

+ --list-files, + -f +

Recursively list all files stored on card.

+ --list-readers, + -l +

List all configured readers.

+ --name, + -n +

Print the name of the inserted card (driver).

+ --get-conf-entry conf, + -G conf +

Get configuration key, format: section:name:key

+ --set-conf-entry conf, + -S conf +

Get configuration key, format: section:name:key:value

+ --reader num, + -r num +

+ Specify the reader to use. By default, the first + reader with a present card is used. If + num is an ATR, the + reader with a matching card will be chosen. +

+ --reset [type], +

Resets the card in reader. + The default reset type is cold, + but warm reset is also possible.

+ --send-apdu apdu, + -s apdu +

Sends an arbitrary APDU to the card in the format + AA:BB:CC:DD:EE:FF....

+ --serial +

Print the card serial number (normally the ICCSN). + Output is in hex byte format

+ --verbose, + -v +

Causes opensc-tool to be more verbose. + Specify this flag several times to enable debug output in the opensc library.

+ --wait, + -w +

Wait for a card to be inserted.

+

See also

+ opensc-explorer(1) +

Authors

opensc-tool was written by + Juha Yrjölä .


Name

piv-tool — smart card utility for HSPD-12 PIV cards

Synopsis

piv-tool [OPTIONS]

The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. -

Options

+

Options

--serial

Print the card serial number derived from the CHUID object, @@ -1016,16 +1182,16 @@

Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

See also

+

See also

opensc-tool(1) -

Authors

piv-tool was written by - Douglas E. Engert .


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

+

Authors

piv-tool was written by + Douglas E. Engert .


Name

pkcs11-tool — utility for managing and using PKCS #11 security tokens

Synopsis

pkcs11-tool [OPTIONS]

Description

The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--attr-from filename

Extract information from filename @@ -1250,7 +1416,7 @@ --generate-random num

Get num bytes of random data.

-

Examples

+

Examples

To list all certificates on the smart card:

pkcs11-tool --list-objects --type cert

@@ -1266,13 +1432,13 @@ using the private key with ID ID and using the RSA-PKCS mechanism:

pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

-

Authors

pkcs11-tool was written by - Olaf Kirch .


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

+

Authors

pkcs11-tool was written by + Olaf Kirch .


Name

pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

Synopsis

pkcs15-crypt [OPTIONS]

Description

The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 compliant smart card. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1369,18 +1535,18 @@

Causes pkcs15-crypt to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

-

See also

+

See also

pkcs15-init(1), pkcs15-tool(1) -

Authors

pkcs15-crypt was written by - Juha Yrjölä .


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

+

Authors

pkcs15-crypt was written by + Juha Yrjölä .


Name

pkcs15-init — smart card personalization utility

Synopsis

pkcs15-init [OPTIONS]

Description

The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles.

The profile used by default is pkcs15. Alternative profiles can be specified via the -p switch. -

PIN Usage

+

PIN Usage

pkcs15-init can be used to create a PKCS #15 structure on your smart card, create PINs, and install keys and certificates on the card. This process is also called personalization. @@ -1412,7 +1578,7 @@ are protected and cannot be parsed without authentication (usually with User PIN). This authentication need to be done immediately after the card binding. In such cases --verify-pin has to be used. -

Modes of operation

Initialization

This is the first step during card personalization, and will create the +

Modes of operation

Initialization

This is the first step during card personalization, and will create the basic files on the card. To create the initial PKCS #15 structure, invoke the utility as

@@ -1422,7 +1588,7 @@

If the card supports it, you should erase the contents of the card with pkcs15-init --erase-card before creating the PKCS#15 structure. -

User PIN Installation

+

User PIN Installation

Before installing any user objects such as private keys, you need at least one PIN to protect these objects. you can do this using

@@ -1436,7 +1602,7 @@

To set a label for this PIN object (which can be used by applications to display a meaningful prompt to the user), use the --label command line option. -

Key generation

+

Key generation

pkcs15-init lets you generate a new key and store it on the card. You can do this using:

@@ -1454,7 +1620,7 @@ In addition to storing the private portion of the key on the card, pkcs15-init will also store the the public portion of the key as a PKCS #15 public key object. -

Private Key Upload

+

Private Key Upload

You can use a private key generated by other means and upload it to the card. For instance, to upload a private key contained in a file named okir.pem, which is in PEM format, you would use @@ -1478,7 +1644,7 @@ a file. A PKCS #12 file usually contains the X.509 certificate corresponding to the private key. If that is the case, pkcs15-init will store the certificate instead of the public key portion. -

Public Key Upload

+

Public Key Upload

You can also upload individual public keys to the card using the --store-public-key option, which takes a filename as an argument. This file is supposed to contain the public key. If you don't @@ -1489,12 +1655,12 @@ Since the corresponding public keys are always uploaded automatically when generating a new key, or when uploading a private key, you will probably use this option only very rarely. -

Certificate Upload

+

Certificate Upload

You can upload certificates to the card using the --store-certificate option, which takes a filename as an argument. This file is supposed to contain the PEM encoded X.509 certificate. -

Uploading PKCS #12 bags

+

Uploading PKCS #12 bags

Most browsers nowadays use PKCS #12 format files when you ask them to export your key and certificate to a file. pkcs15-init is capable of parsing these files, and storing their contents on the @@ -1508,7 +1674,7 @@ and protect it with the PIN referenced by authentication ID 01. It will also store any X.509 certificates contained in the file, which is usually the user certificate that goes with the key, as well as the CA certificate. -

Secret Key Upload

+

Secret Key Upload

You can use a secret key generated by other means and upload it to the card. For instance, to upload an AES-secret key generated by the system random generator you would use @@ -1517,7 +1683,7 @@

By default a random ID is generated for the secret key. You may specify an ID with the --id if needed. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -1854,17 +2020,17 @@

Display help message

-

See also

+

See also

pkcs15-profile(5) -

Authors

pkcs15-init was written by +

Authors

pkcs15-init was written by Olaf Kirch .


Name

pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

+ on smart cards and similar security tokens

Synopsis

pkcs15-tool [OPTIONS]

Description

The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--version,

Print the OpenSC package release version.

@@ -2005,16 +2171,16 @@ wait for a card insertion.

--use-pinpad

Do not prompt the user; if no PINs supplied, pinpad will be used.

-

See also

+

See also

pkcs15-init(1), pkcs15-crypt(1) -

Authors

pkcs15-tool was written by - Juha Yrjölä .


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

+

Authors

pkcs15-tool was written by + Juha Yrjölä .


Name

sc-hsm-tool — smart card utility for SmartCard-HSM

Synopsis

sc-hsm-tool [OPTIONS]

The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. -

Options

+

Options

--initialize, -X @@ -2086,16 +2252,16 @@

Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

-

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

+

Examples

Create a DKEK share:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe

Create a DKEK share with random password split up using a (3, 5) threshold scheme:

sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

Initialize SmartCard-HSM to use a single DKEK share:

sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

Import DKEK share:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe

Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

Wrap referenced key, description and certificate:

sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

Unwrap key into same or in different SmartCard-HSM with the same DKEK:

sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

See also

opensc-tool(1) -

Authors

sc-hsm-tool was written by +

Authors

sc-hsm-tool was written by Andreas Schwier .


Name

westcos-tool — utility for manipulating data structures - on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

+ on westcos smart cards

Synopsis

westcos-tool [OPTIONS]

Description

The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, keys and certificates stored on the card / token. User PIN authentication is performed for those operations that require it. -

Options

+

Options

--change-pin, -n @@ -2164,6 +2330,7 @@ -u

Unblocks a PIN stored on the card. Knowledge of the PIN Unblock Key (PUK) is required for this operation.

+ --verbose -v

Causes westcos-tool to be more verbose. Specify this flag several times to enable debug output @@ -2177,27 +2344,5 @@ from disk to card. On the card the file is written in filename. User authentication is required for this operation.

-

Authors

westcos-tool was written by - Francois Leblanc .

OpenSC file formats


Table of Contents

pkcs15-profile — format of profile for pkcs15-init

Name

pkcs15-profile — format of profile for pkcs15-init

Description

- The pkcs15-init utility for PKCS #15 smart card - personalization is controlled via profiles. When starting, it will read two - such profiles at the moment, a generic application profile, and a card - specific profile. The generic profile must be specified on the command line, - while the card-specific file is selected based on the type of card detected. -

- The generic application profile defines general information about the card - layout, such as the path of the application DF, various PKCS #15 files within - that directory, and the access conditions on these files. It also defines - general information about PIN, key and certificate objects. Currently, there - is only one such generic profile, pkcs15.profile. -

- The card specific profile contains additional information required during - card initialization, such as location of PIN files, key references etc. - Profiles currently reside in @pkgdatadir@ -

Syntax

- This section should contain information about the profile syntax. Will add - this soonishly. -

See also

- pkcs15-init(1), - pkcs15-crypt(1) -

+

Authors

westcos-tool was written by + Francois Leblanc .

diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml index c405910a63..36d39c8cfe 100644 --- a/doc/tools/tools.xml +++ b/doc/tools/tools.xml @@ -1,40 +1,29 @@ +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> - OpenSC Manuals - - - OpenSC tools - - - - - - - - - - - - - - - - - - - - - - - + OpenSC Manual Pages: Section 1 - - - OpenSC file formats - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 956a12cedc..aa5956875c 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -284,8 +284,8 @@ app default { # # md_read_only: Mark card as read/only card in Minidriver/BaseCSP interface (Default: false) # md_supports_X509_enrollment: Indicate X509 enrollment support at Minidriver/BaseCSP interface (Default: false) - # md_guid_as_id: Use the GUID generated for the key as id in the PKCS#15 structure (Default: false - auto generated) - # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false - no label set) + # md_guid_as_id: Use the GUID generated for the key as id in the PKCS#15 structure (Default: false, i.e. auto generated) + # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false, i.e. no label set) # md_supports_container_key_gen: Card allows generating key pairs on the card (Default: false) # md_supports_container_key_import: Card allows importing private keys (Default: false) # @@ -890,11 +890,10 @@ app default { # Whether to use the cache files in the user's # home directory. # - # At the moment you have to 'teach' the card - # to the system by running command: pkcs15-tool -L + # Note: If caching is done by a system process, caching may be placed + # inaccessible from the user account. Use a global caching directory if + # you wish to share the cached information. # - # WARNING: Caching shouldn't be used in setuid root - # applications. # Default: false # use_file_caching = true; # diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index ec4c4851d8..9482e2a71a 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -28,6 +28,7 @@ #include #include #include +#include #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include #include /* for OPENSSL_NO_* */ From e226ad265ab8277362a35995b68b5472e548e9c0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Jun 2018 10:15:22 +0200 Subject: [PATCH 0415/4321] Removed unused option `hide_empty_tokens` --- etc/opensc.conf.in | 9 --------- src/pkcs11/misc.c | 8 +++----- src/pkcs11/sc-pkcs11.h | 1 - 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index aa5956875c..b7fd7d635f 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -1001,15 +1001,6 @@ app opensc-pkcs11 { # (max_virtual_slots/slots_per_card) limits the number of readers # that can be used on the system. Default is then 16/4=4 readers. - # Normally, the pkcs11 module will create - # the full number of slots defined above by - # num_slots. If there are fewer pins/keys on - # the card, the remaining keys will be empty - # (and you will be able to create new objects - # within them). - # Default: true - # hide_empty_tokens = false; - # By default, the OpenSC PKCS#11 module will not lock your card # once you authenticate to the card via C_Login. # diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index bb3197711c..ab77c0cbaa 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -452,7 +452,6 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) } else { conf->slots_per_card = 4; } - conf->hide_empty_tokens = 1; conf->atomic = 0; conf->lock_login = 0; conf->init_sloppy = 1; @@ -467,7 +466,6 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) /* contains the defaults, if there is a "pkcs11" config block */ conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots); conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card); - conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens); conf->atomic = scconf_get_bool(conf_block, "atomic", conf->atomic); if (conf->atomic) conf->lock_login = 1; @@ -497,12 +495,12 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf->create_slots_flags |= SC_PKCS11_SLOT_CREATE_ALL; op = strtok(NULL, " ,"); } - free(tmp); + free(tmp); sc_log(ctx, "PKCS#11 options: max_virtual_slots=%d slots_per_card=%d " - "hide_empty_tokens=%d lock_login=%d atomic=%d pin_unblock_style=%d " + "lock_login=%d atomic=%d pin_unblock_style=%d " "create_slots_flags=0x%X", conf->max_virtual_slots, conf->slots_per_card, - conf->hide_empty_tokens, conf->lock_login, conf->atomic, conf->pin_unblock_style, + conf->lock_login, conf->atomic, conf->pin_unblock_style, conf->create_slots_flags); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index c023ee86a6..8432458820 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -71,7 +71,6 @@ struct sc_pkcs11_config { unsigned int plug_and_play; unsigned int max_virtual_slots; unsigned int slots_per_card; - unsigned char hide_empty_tokens; unsigned char lock_login; unsigned char atomic; unsigned char init_sloppy; From c003f3825e5217cd3ef8272f4e8ebe47270a7847 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 27 Jun 2018 01:10:16 +0200 Subject: [PATCH 0416/4321] Distribute a minimal opensc.conf closes https://github.com/OpenSC/OpenSC/issues/1102 --- .gitignore | 3 +-- etc/Makefile.am | 23 ++++++++----------- etc/opensc.conf | 7 ++++++ ...{opensc.conf.in => opensc.conf.example.in} | 0 4 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 etc/opensc.conf rename etc/{opensc.conf.in => opensc.conf.example.in} (100%) diff --git a/.gitignore b/.gitignore index 8d91981e4e..dfe8ea4ffe 100644 --- a/.gitignore +++ b/.gitignore @@ -82,8 +82,7 @@ doc/tools/opensc-asn1 doc/tools/opensc-notify doc/files/opensc.conf.5.xml -etc/opensc.conf.win -etc/opensc.conf +etc/opensc.conf.example src/common/compat_getopt_main src/minidriver/opensc-minidriver.inf src/tools/cardos-tool diff --git a/etc/Makefile.am b/etc/Makefile.am index 6a0bb3d9f6..3add83b2c2 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,20 +1,21 @@ CV_CERTS = DESRCACC100001 MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -DISTCLEANFILES = opensc.conf +DISTCLEANFILES = opensc.conf.example EXTRA_DIST = $(CV_CERTS) Makefile.mak SUFFIXES = .in -dist_noinst_DATA = opensc.conf.in -nodist_noinst_DATA = opensc.conf +dist_noinst_DATA = opensc.conf.example.in +nodist_noinst_DATA = opensc.conf.example +dist_sysconf_DATA = opensc.conf # Make sure we build this every time # as there is no dependency for this. # Can be removed if MSVC is not requried. force: -opensc.conf: opensc.conf.in force +opensc.conf.example: opensc.conf.example.in force .in: @sed \ @@ -30,16 +31,12 @@ opensc.conf: opensc.conf.in force -e 's|@PROFILE_DIR_DEFAULT[@]|$(PROFILE_DIR_DEFAULT)|g' \ < $< > $@ -install-exec-hook: opensc.conf - $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" - if [ -f "$(DESTDIR)$(sysconfdir)/opensc.conf" ]; then \ - $(INSTALL_DATA) opensc.conf "$(DESTDIR)$(sysconfdir)/opensc.conf.new"; \ - else \ - $(INSTALL_DATA) opensc.conf "$(DESTDIR)$(sysconfdir)/opensc.conf"; \ - fi +install-exec-hook: opensc.conf.example + $(MKDIR_P) "$(DESTDIR)$(docdir)" + $(INSTALL_DATA) opensc.conf.example "$(DESTDIR)$(docdir)/opensc.conf"; -uninstall-hook: opensc.conf - rm -f "$(DESTDIR)$(sysconfdir)/opensc.conf.new" "$(DESTDIR)$(sysconfdir)/opensc.conf" +uninstall-hook: opensc.conf.example + rm -f "$(DESTDIR)$(docdir)/opensc.conf" if ENABLE_OPENPACE install-data-local: diff --git a/etc/opensc.conf b/etc/opensc.conf new file mode 100644 index 0000000000..eab9b44c5f --- /dev/null +++ b/etc/opensc.conf @@ -0,0 +1,7 @@ +app default { + # debug = 3; + # debug_file = opensc-debug.txt + framework pkcs15 { + # use_file_caching = true; + } +} diff --git a/etc/opensc.conf.in b/etc/opensc.conf.example.in similarity index 100% rename from etc/opensc.conf.in rename to etc/opensc.conf.example.in From a0b6643fa770e2bf797e87c14f51b4b4576d0dd3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 14 Jul 2018 04:16:39 +0200 Subject: [PATCH 0417/4321] Use hard coded default SM module (path) - avoids the need to set this default in opensc.conf - fixes loading of (unknown) local library - removes some unused defines from config.h --- configure.ac | 17 +++++------------ etc/opensc.conf.example.in | 12 ++++++------ src/libopensc/Makefile.am | 2 ++ src/libopensc/card.c | 14 ++++++++++---- src/tools/Makefile.am | 2 +- win32/winconfig.h.in | 7 +++++++ 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/configure.ac b/configure.ac index c655e76442..a02128915c 100644 --- a/configure.ac +++ b/configure.ac @@ -123,9 +123,6 @@ case "${host}" in PROFILE_DIR_DEFAULT="\$(pkgdatadir)" ;; esac -AC_DEFINE_UNQUOTED([DEBUG_FILE], ["${DEBUG_FILE}"], [Debug file]) -AC_DEFINE_UNQUOTED([PROFILE_DIR], ["${PROFILE_DIR}"], [Directory of profiles]) -AC_DEFINE_UNQUOTED([PROFILE_DIR_DEFAULT], ["${PROFILE_DIR_DEFAULT}"], [Default directory of profiles]) case "${host}" in *-mingw*) @@ -347,7 +344,6 @@ AC_MSG_RESULT([${xslstylesheetsdir}]) AC_MSG_CHECKING([git checkout]) GIT_CHECKOUT="no" if test -n "${GIT}" -a -d "${srcdir}/.git"; then - AC_DEFINE([HAVE_CONFIG_VERSION_H], [1], [extra version available in config-version.h]) GIT_CHECKOUT="yes" fi AC_MSG_RESULT([${GIT_CHECKOUT}]) @@ -881,26 +877,23 @@ if test "${enable_sm}" = "yes"; then DEFAULT_SM_MODULE="${LIB_PRE}smm-local${DYN_LIB_EXT}" case "${host}" in *-mingw*|*-winnt*|*-cygwin*) - DEFAULT_SM_MODULE_PATH="\# module_path = \"\";" + DEFAULT_SM_MODULE_PATH="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\tools" ;; *) - DEFAULT_SM_MODULE_PATH="module_path = \$(libdir);" + DEFAULT_SM_MODULE_PATH="${libdir}" ;; esac - AC_DEFINE_UNQUOTED([DEFAULT_SM_MODULE], ["${DEFAULT_SM_MODULE}"], [Default SM module]) - AC_DEFINE_UNQUOTED([DEFAULT_SM_MODULE_PATH], ["${DEFAULT_SM_MODULE_PATH}"], [Default SM module path]) fi if test "${with_pkcs11_provider}" = "detect"; then if test "${WIN32}" != "yes"; then - DEFAULT_PKCS11_PROVIDER="opensc-pkcs11${DYN_LIB_EXT}" + DEFAULT_PKCS11_PROVIDER="${libdir}/opensc-pkcs11${DYN_LIB_EXT}" else DEFAULT_PKCS11_PROVIDER="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\pkcs11\\\opensc-pkcs11.dll" fi else DEFAULT_PKCS11_PROVIDER="${with_pkcs11_provider}" fi -AC_DEFINE_UNQUOTED([DEFAULT_PKCS11_PROVIDER], ["${DEFAULT_PKCS11_PROVIDER}"], [Default PKCS11 provider]) if test "${enable_man}" = "detect"; then if test "${WIN32}" = "yes"; then @@ -1129,13 +1122,13 @@ CT-API support: ${enable_ctapi} minidriver support: ${enable_minidriver} SM support: ${enable_sm} SM default module: ${DEFAULT_SM_MODULE} +SM default path: $(eval eval eval echo "${DEFAULT_SM_MODULE_PATH}") DNIe UI support: ${enable_dnie_ui} Notification support: ${enable_notify} Build tests: ${enable_tests} -Debug file: ${DEBUG_FILE} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} -PKCS11 default provider: ${DEFAULT_PKCS11_PROVIDER} +PKCS11 default provider: $(eval eval eval echo "${DEFAULT_PKCS11_PROVIDER}") Host: ${host} Compiler: ${CC} diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index b7fd7d635f..8ba5e4ddf1 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -797,8 +797,8 @@ app default { # name of external SM module # module_name = @DEFAULT_SM_MODULE@; # directory with external SM module - # Default: defined by windows register - @DEFAULT_SM_MODULE_PATH@ + # Default: @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; # specific data to tune the module initialization # module_data = "Here can be your SM module init data"; @@ -821,7 +821,7 @@ app default { secure_messaging local_gemalto_iam { module_name = @DEFAULT_SM_MODULE@; - @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; # module_data = ""; type = acl; # transmit, acl @@ -840,7 +840,7 @@ app default { secure_messaging local_amos { module_name = @DEFAULT_SM_MODULE@; - @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; # module_data = ""; mode = acl; ifd_serial = "11:22:33:44:55:66:77:88"; @@ -850,7 +850,7 @@ app default { secure_messaging local_amos_eid { module_name = @DEFAULT_SM_MODULE@; - @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; # module_data = ""; mode = acl; ifd_serial = "11:22:33:44:55:66:77:88"; @@ -860,7 +860,7 @@ app default { secure_messaging local_adele { module_name = @DEFAULT_SM_MODULE@; - @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; # module_data = ""; type = acl; # transmit, acl diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 01533ba0ed..ad25969002 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -15,6 +15,8 @@ noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem. jpki.h sc-ossl-compat.h card-npa.h ccid-types.h reader-tr03119.h AM_CPPFLAGS = -DOPENSC_CONF_PATH=\"$(sysconfdir)/opensc.conf\" \ + -DDEFAULT_SM_MODULE_PATH=\"$(DEFAULT_SM_MODULE_PATH)\" \ + -DDEFAULT_SM_MODULE=\"$(DEFAULT_SM_MODULE)\" \ -I$(top_srcdir)/src AM_CFLAGS = $(OPENPACE_CFLAGS) $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_OPENCT_CFLAGS) \ $(OPTIONAL_PCSC_CFLAGS) $(OPTIONAL_ZLIB_CFLAGS) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 99b8da61c2..6bd0ef2f9d 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1347,6 +1347,8 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo char temp_path[PATH_MAX]; size_t temp_len; const char path_delim = '\\'; + char expanded_val[PATH_MAX]; + DWORD expanded_len; #else const char path_delim = '/'; #endif @@ -1360,16 +1362,20 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo return sc_card_sm_unload(card); #ifdef _WIN32 - if (!module_path) { + if (!module_path || strlen(module_path) == 0) { temp_len = PATH_MAX; rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\OpenSC Project\\OpenSC", temp_path, &temp_len); if (rv == SC_SUCCESS) module_path = temp_path; } + expanded_len = PATH_MAX; + expanded_len = ExpandEnvironmentStringsA(module_path, expanded_val, expanded_len); + if (0 < expanded_len && expanded_len < sizeof expanded_val) + module_path = expanded_val; #endif sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "SM module '%s' located in '%s'", in_module, module_path); - if (module_path) { + if (module_path && strlen(module_path) > 0) { int sz = strlen(in_module) + strlen(module_path) + 3; module = malloc(sz); if (module) @@ -1475,8 +1481,8 @@ sc_card_sm_check(struct sc_card *card) LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "SM configuration block not preset"); /* check if an external SM module has to be used */ - module_path = scconf_get_str(sm_conf_block, "module_path", NULL); - module_name = scconf_get_str(sm_conf_block, "module_name", NULL); + module_path = scconf_get_str(sm_conf_block, "module_path", DEFAULT_SM_MODULE_PATH); + module_name = scconf_get_str(sm_conf_block, "module_name", DEFAULT_SM_MODULE); sc_log(ctx, "SM module '%s' in '%s'", module_name, module_path); if (!module_name) LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "Invalid SM configuration: module not defined"); diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 63cafb4839..a3300ab9a4 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -39,7 +39,7 @@ endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/src +AM_CPPFLAGS = -I$(top_srcdir)/src -DDEFAULT_PKCS11_PROVIDER=\"$(DDEFAULT_PKCS11_PROVIDER)\" LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index 3aa2beec11..09842209b8 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -99,6 +99,13 @@ #define DEFAULT_PKCS11_PROVIDER "@DEFAULT_PKCS11_PROVIDER@" #endif +#ifndef DEFAULT_SM_MODULE +#define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@" +#endif +#ifndef DEFAULT_SM_MODULE_PATH +#define DEFAULT_SM_MODULE_PATH "@DEFAULT_SM_MODULE_PATH@" +#endif + #ifndef OPENSC_SCM_REVISION #define OPENSC_SCM_REVISION "@OPENSC_SCM_REVISION@" #endif From 4de0d06a93d384b91753458e7e63b5eb6a854fbb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 15 Jul 2018 00:24:40 +0200 Subject: [PATCH 0418/4321] use single quotes for passing define makes sure that the shell doesn't evaluate parts of the define --- src/libopensc/Makefile.am | 6 +++--- src/pkcs15init/Makefile.am | 2 +- src/tools/Makefile.am | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index ad25969002..a99b0c5741 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -14,9 +14,9 @@ noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem. pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ jpki.h sc-ossl-compat.h card-npa.h ccid-types.h reader-tr03119.h -AM_CPPFLAGS = -DOPENSC_CONF_PATH=\"$(sysconfdir)/opensc.conf\" \ - -DDEFAULT_SM_MODULE_PATH=\"$(DEFAULT_SM_MODULE_PATH)\" \ - -DDEFAULT_SM_MODULE=\"$(DEFAULT_SM_MODULE)\" \ +AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ + -D'DEFAULT_SM_MODULE_PATH="$(DEFAULT_SM_MODULE_PATH)"' \ + -D'DEFAULT_SM_MODULE="$(DEFAULT_SM_MODULE)"' \ -I$(top_srcdir)/src AM_CFLAGS = $(OPENPACE_CFLAGS) $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_OPENCT_CFLAGS) \ $(OPTIONAL_PCSC_CFLAGS) $(OPTIONAL_ZLIB_CFLAGS) diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 7d9d5f7214..eadf8df1c2 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -32,7 +32,7 @@ dist_pkgdata_DATA = \ openpgp.profile sc-hsm.profile \ isoApplet.profile gids.profile -AM_CPPFLAGS = -DSC_PKCS15_PROFILE_DIRECTORY=\"$(pkgdatadir)\" \ +AM_CPPFLAGS = -D'SC_PKCS15_PROFILE_DIRECTORY="$(pkgdatadir)"' \ -I$(top_srcdir)/src AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index a3300ab9a4..b35a646595 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -39,7 +39,7 @@ endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/src -DDEFAULT_PKCS11_PROVIDER=\"$(DDEFAULT_PKCS11_PROVIDER)\" +AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DDEFAULT_PKCS11_PROVIDER)"' LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ From dfe932d00ddbf4060a3ed91d5b4202a964b5b4db Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 20 Jul 2018 18:55:52 +0300 Subject: [PATCH 0419/4321] OMNIKEY 3x21 and 6121 Smart Card Reader are not pinpad readers macOS 10.13 ships with ccid driver 1.4.27 (fixed in 1.4.29) and this version identifies these readers wrongly as pinpad readers. Signed-off-by: Raul Metsma --- src/libopensc/reader-pcsc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c9edad6087..d2c2b6cb40 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1063,6 +1063,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) PCSC_TLV_STRUCTURE *pcsc_tlv; LONG rv; const char *log_disabled = "but it's disabled in configuration file"; + int id_vendor = 0, id_product = 0; LOG_FUNC_CALLED(ctx); @@ -1132,6 +1133,17 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } } + /* Some readers claim to have PinPAD support even if they have not */ + if ((reader->capabilities & SC_READER_CAP_PIN_PAD) && + part10_get_vendor_product(reader, card_handle, &id_vendor, &id_product) == SC_SUCCESS) { + /* HID Global OMNIKEY 3x21/6121 Smart Card Reader, fixed in libccid 1.4.29 (remove when last supported OS is using 1.4.29) */ + if ((id_vendor == 0x076B && id_product == 0x3031) || + (id_vendor == 0x076B && id_product == 0x6632)) { + sc_log(ctx, "%s is not pinpad reader, ignoring", reader->name); + reader->capabilities &= ~SC_READER_CAP_PIN_PAD; + } + } + /* Detect display */ if (priv->pin_properties_ioctl) { rcount = sizeof(rbuf); From 8e8193f8f5edee1d4ab4646904a524b92f899914 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Jul 2018 17:29:18 +0200 Subject: [PATCH 0420/4321] coolkey: Unbreak get_challenge with correct instruction code --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index ac5bddb16e..c537621d53 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -89,7 +89,7 @@ #define COOLKEY_INS_COMPUTE_CRYPT 0x36 #define COOLKEY_INS_COMPUTE_ECC_KEY_AGREEMENT 0x37 #define COOLKEY_INS_COMPUTE_ECC_SIGNATURE 0x38 -#define COOLKEY_INS_GET_RANDOM 0x73 +#define COOLKEY_INS_GET_RANDOM 0x72 #define COOLKEY_INS_READ_OBJECT 0x56 #define COOLKEY_INS_WRITE_OBJECT 0x54 #define COOLKEY_INS_LOGOUT 0x61 From f097d88b3aba6397bdab15e8b1a70f364b582bdb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Jul 2018 17:30:14 +0200 Subject: [PATCH 0421/4321] coolkey: Drop bogus ; --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index c537621d53..4c966f64b3 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1196,7 +1196,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, { coolkey_private_data_t * priv = COOLKEY_DATA(card); int r = 0, len; - u8 *data = NULL;; + u8 *data = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (idx > priv->obj->length) { From 2190bb927c739852266481d6517aaf3a07b52526 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Jul 2018 13:35:24 +0200 Subject: [PATCH 0422/4321] Drop support for CAC 1 This removes code related to the old CAC 1 specification, while preserving the CAC 2 functionality including CAC Alt token detection for the tokens without CCC or ACA. The detection based on SELECT APPLET APDU is improved to require also the READ BUFFER APDU working, which should fail on misbehaving Java cards. --- src/libopensc/card-cac.c | 209 +++++++++++---------------------------- 1 file changed, 58 insertions(+), 151 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index a4f149c915..4e853e5c2c 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -64,7 +64,6 @@ * CAC hardware and APDU constants */ #define CAC_MAX_CHUNK_SIZE 240 -#define CAC_INS_GET_CERTIFICATE 0x36 /* CAC1 command to read a certificate */ #define CAC_INS_SIGN_DECRYPT 0x42 /* A crypto operation */ #define CAC_INS_READ_FILE 0x52 /* read a TL or V file */ #define CAC_INS_GET_ACR 0x4c @@ -301,23 +300,23 @@ static const char *cac_labels[MAX_CAC_SLOTS] = { "CAC Cert 16" }; -/* template for a cac1 pki object */ -static const cac_object_t cac_cac1_pki_obj = { +/* template for a CAC pki object */ +static const cac_object_t cac_cac_pki_obj = { "CAC Certificate", 0x0, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, { CAC_TO_AID(CAC_1_RID "\x01\x00") } } }; -/* template for cac1 cuid */ -static const cac_cuid_t cac_cac1_cuid = { +/* template for emulated cuid */ +static const cac_cuid_t cac_cac_cuid = { { 0xa0, 0x00, 0x00, 0x00, 0x79 }, 2, 2, 0 }; /* - * CAC-1 general objects defined in 4.3.1.2 of CAC Applet Developer Guide Version 1.0. + * CAC general objects defined in 4.3.1.2 of CAC Applet Developer Guide Version 1.0. * doubles as a source for CAC-2 labels. */ -static const cac_object_t cac_1_objects[] = { +static const cac_object_t cac_objects[] = { { "Person Instance", 0x200, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, { CAC_TO_AID(CAC_1_RID "\x02\x00") }}}, { "Personnel", 0x201, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, @@ -332,7 +331,7 @@ static const cac_object_t cac_1_objects[] = { { CAC_TO_AID(CAC_1_RID "\x02\xFE") }}}, }; -static const int cac_1_object_count = sizeof(cac_1_objects)/sizeof(cac_1_objects[0]); +static const int cac_object_count = sizeof(cac_objects)/sizeof(cac_objects[0]); /* * use the object id to find our object info on the object in our CAC-1 list @@ -341,9 +340,9 @@ static const cac_object_t *cac_find_obj_by_id(unsigned short object_id) { int i; - for (i=0; i < cac_1_object_count; i++) { - if (cac_1_objects[i].fd == object_id) { - return &cac_1_objects[i]; + for (i = 0; i < cac_object_count; i++) { + if (cac_objects[i].fd == object_id) { + return &cac_objects[i]; } } return NULL; @@ -568,97 +567,6 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o return r; } -/* - * OLD cac read certificate, only use with CAC-1 card. - */ -static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_len) -{ - u8 buf[CAC_MAX_SIZE]; - u8 *out_ptr; - size_t size = 0; - size_t left = 0; - size_t len, next_len; - sc_apdu_t apdu; - int r = SC_SUCCESS; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - /* get the size */ - size = left = *out_buf ? *out_len : sizeof(buf); - out_ptr = *out_buf ? *out_buf : buf; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, CAC_INS_GET_CERTIFICATE, 0, 0 ); - next_len = MIN(left, 100); - for (; left > 0; left -= len, out_ptr += len) { - len = next_len; - apdu.resp = out_ptr; - apdu.le = len; - apdu.resplen = left; - - r = sc_transmit_apdu(card, &apdu); - if (r < 0) { - break; - } - if (apdu.resplen == 0) { - r = SC_ERROR_INTERNAL; - break; - } - /* in the old CAC-1, 0x63 means 'more data' in addition to 'pin failed' */ - if (apdu.sw1 != 0x63) { - /* we've either finished reading, or hit an error, break */ - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - left -= len; - break; - } - next_len = MIN(left, apdu.sw2); - } - if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); - } - r = size - left; - if (*out_buf == NULL) { - *out_buf = malloc(r); - if (*out_buf == NULL) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, - SC_ERROR_OUT_OF_MEMORY); - } - memcpy(*out_buf, buf, r); - } - *out_len = r; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); -} - -/* Create a fake tag/length file in Simple TLV for cac1 cards based on the val_len. - */ -int cac_cac1_get_cert_tag(sc_card_t *card, size_t val_len, u8 **tlp, size_t *tl_len_p) -{ - static const u8 cac_cac1_cert_tag[] = { CAC_TAG_CERTINFO, 1, CAC_TAG_CERTIFICATE, 0xff, 0, 0 }; - u8 *tl, *tl1, *tl2; - size_t tl_len; - int rv = SC_SUCCESS; - - tl_len = sizeof(cac_cac1_cert_tag); - tl = malloc(tl_len); - if (tl == NULL) - return SC_ERROR_OUT_OF_MEMORY; - memcpy(tl, cac_cac1_cert_tag, tl_len); - - rv = sc_simpletlv_put_tag(CAC_TAG_CERTINFO, 1, tl, tl_len, &tl1); - if (rv != SC_SUCCESS) - goto failure; - - val_len -= 1; /* one byte is CERTINFO Value */ - tl_len -= (tl1 - tl); - rv = sc_simpletlv_put_tag(CAC_TAG_CERTIFICATE, val_len, tl1, tl_len, &tl2); - if (rv != SC_SUCCESS) - goto failure; - - *tlp = tl; - *tl_len_p = (tl2 - tl); - return SC_SUCCESS; -failure: - free(tl); - return rv; -} /* * Callers of this may be expecting a certificate, @@ -705,31 +613,14 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, if (priv->object_type <= 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); - if ((card->type == SC_CARD_TYPE_CAC_I) && (priv->object_type == CAC_OBJECT_TYPE_CERT)) { - /* SPICE smart card emulator only presents CAC-1 cards with the old CAC-1 interface as - * certs. If we are a cac 1 card, use the old interface */ - r = cac_cac1_get_certificate(card, &val, &val_len); - if (r == SC_ERROR_INS_NOT_SUPPORTED) { - /* The CACv1 instruction is not recognized. Try with CACv2 */ - card->type = SC_CARD_TYPE_CAC_II; - } else if (r < 0) - goto done; + r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len); + if (r < 0) { + goto done; } - if ((card->type == SC_CARD_TYPE_CAC_I) && (priv->object_type == CAC_OBJECT_TYPE_CERT)) { - r = cac_cac1_get_cert_tag(card, val_len, &tl, &tl_len); - if (r < 0) - goto done; - } else { - r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len); - if (r < 0) { - goto done; - } - - r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len); - if (r < 0) - goto done; - } + r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len); + if (r < 0) + goto done; switch (priv->object_type) { case CAC_OBJECT_TYPE_TLV_FILE: @@ -1388,7 +1279,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc apdu.p2 = 0; /* first record, return FCI */ } else { - apdu.p2 = (type == SC_CARD_TYPE_CAC_I)? 0x00 : 0x0C; + apdu.p2 = 0x0C; } r = sc_transmit_apdu(card, &apdu); @@ -1828,48 +1719,59 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, return SC_SUCCESS; } -/* select a CAC-1 pki applet by index */ +/* select a CAC pki applet by index */ static int cac_select_pki_applet(sc_card_t *card, int index) { - sc_path_t applet_path = cac_cac1_pki_obj.path; + sc_path_t applet_path = cac_cac_pki_obj.path; applet_path.aid.value[applet_path.aid.len-1] = index; - return cac_select_file_by_type(card, &applet_path, NULL, SC_CARD_TYPE_CAC_I); + return cac_select_file_by_type(card, &applet_path, NULL, SC_CARD_TYPE_CAC_II); } /* - * Find the first existing CAC-1 applet. If none found, then this isn't a CAC-1 + * Find the first existing CAC applet. If none found, then this isn't a CAC */ static int cac_find_first_pki_applet(sc_card_t *card, int *index_out) { int r, i; - for (i=0; i < MAX_CAC_SLOTS; i++) { + for (i = 0; i < MAX_CAC_SLOTS; i++) { r = cac_select_pki_applet(card, i); if (r == SC_SUCCESS) { + /* Try to read first two bytes of the buffer to + * make sure it is not just malfunctioning card + */ + u8 params[2] = {CAC_FILE_TAG, 2}; + u8 data[2], *out_ptr = data; + size_t len = 2; + r = cac_apdu_io(card, CAC_INS_READ_FILE, 0, 0, + ¶ms[0], sizeof(params), &out_ptr, &len); + if (r != 2) + continue; + *index_out = i; - return r; + return SC_SUCCESS; } } return SC_ERROR_OBJECT_NOT_FOUND; } /* - * CAC-1 has been found, identify all the certs and general containers. - * This emulates CAC-2's CCC. + * This emulates CCC for Alt tokens, that do not come with CCC nor ACA applets */ -static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *priv) +static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t *priv) { int r, i; - cac_object_t pki_obj = cac_cac1_pki_obj; + cac_object_t pki_obj = cac_cac_pki_obj; u8 buf[100]; u8 *val; size_t val_len; /* populate PKI objects */ - for (i=index; i < MAX_CAC_SLOTS; i++) { + for (i = index; i < MAX_CAC_SLOTS; i++) { r = cac_select_pki_applet(card, i); if (r == SC_SUCCESS) { pki_obj.name = cac_labels[i]; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CAC1: pki_object found, cert_next=%d (%s),", i, pki_obj.name); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "CAC: pki_object found, cert_next=%d (%s),", i, pki_obj.name); pki_obj.path.aid.value[pki_obj.path.aid.len-1] = i; pki_obj.fd = i+1; /* don't use id of zero */ cac_add_object_to_list(&priv->pki_list, &pki_obj); @@ -1877,18 +1779,21 @@ static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *pr } /* populate non-PKI objects */ - for (i=0; i < cac_1_object_count; i++) { - r = cac_select_file_by_type(card, &cac_1_objects[i].path, NULL, SC_CARD_TYPE_CAC_I); + for (i=0; i < cac_object_count; i++) { + r = cac_select_file_by_type(card, &cac_objects[i].path, NULL, + SC_CARD_TYPE_CAC_II); if (r == SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CAC1: obj_object found, cert_next=%d (%s),", i, cac_1_objects[i].name); - cac_add_object_to_list(&priv->general_list, &cac_1_objects[i]); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "CAC: obj_object found, cert_next=%d (%s),", + i, cac_objects[i].name); + cac_add_object_to_list(&priv->general_list, &cac_objects[i]); } } /* * create a cuid to simulate the cac 2 cuid. */ - priv->cuid = cac_cac1_cuid; + priv->cuid = cac_cac_cuid; /* create a serial number by hashing the first 100 bytes of the * first certificate on the card */ r = cac_select_pki_applet(card, index); @@ -1896,9 +1801,8 @@ static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *pr return r; /* shouldn't happen unless the card has been removed or is malfunctioning */ } val = buf; - val_len = sizeof(buf); - r = cac_cac1_get_certificate(card, &val, &val_len); - if (r >= 0) { + val_len = cac_read_binary(card, 0, val, sizeof(buf), 0); + if (val_len > 0) { priv->cac_id = malloc(20); if (priv->cac_id == NULL) { return SC_ERROR_OUT_OF_MEMORY; @@ -1906,6 +1810,8 @@ static int cac_populate_cac_1(sc_card_t *card, int index, cac_private_data_t *pr #ifdef ENABLE_OPENSSL SHA1(val, val_len, priv->cac_id); priv->cac_id_len = 20; + sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE, + "cuid", priv->cac_id, priv->cac_id_len); #else sc_log(card->ctx, "OpenSSL Required"); return SC_ERROR_NOT_SUPPORTED; @@ -1994,10 +1900,10 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) } } - /* is this a CAC-1 specified in DoD "CAC Applet Developer Guide" version 1.0 September 2002 */ + /* is this a CAC Alt token without any accompanying structures */ r = cac_find_first_pki_applet(card, &index); if (r == SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "applet found, is CAC-1"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "PKI applet found, is bare CAC Alt"); if (!initialize) /* match card only */ return r; @@ -2006,12 +1912,13 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize) if (!priv) return SC_ERROR_OUT_OF_MEMORY; } - r = cac_populate_cac_1(card, index, priv); + card->drv_data = priv; /* needed for the read_binary() */ + r = cac_populate_cac_alt(card, index, priv); if (r == SC_SUCCESS) { - card->type = SC_CARD_TYPE_CAC_I; - card->drv_data = priv; + card->type = SC_CARD_TYPE_CAC_II; return r; } + card->drv_data = NULL; /* reset on failure */ } if (priv) { cac_free_private_data(priv); From 11aaf157767997cbac2706efc2260bea7c9fc87c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 12 Jul 2018 08:06:21 +0200 Subject: [PATCH 0423/4321] removed outdated solaris files --- Makefile.am | 2 - solaris/Makefile | 39 ------ solaris/README | 13 -- solaris/checkinstall.in | 9 -- solaris/opensc.conf-dist | 277 --------------------------------------- solaris/pkginfo.in | 12 -- solaris/proto | 118 ----------------- 7 files changed, 470 deletions(-) delete mode 100644 solaris/Makefile delete mode 100644 solaris/README delete mode 100755 solaris/checkinstall.in delete mode 100644 solaris/opensc.conf-dist delete mode 100644 solaris/pkginfo.in delete mode 100644 solaris/proto diff --git a/Makefile.am b/Makefile.am index 3ffc465bc0..3350b566dc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,8 +17,6 @@ SUBDIRS = etc src win32 doc MacOSX dist_noinst_SCRIPTS = bootstrap bootstrap.ci dist_noinst_DATA = README \ - solaris/Makefile solaris/README solaris/checkinstall.in \ - solaris/opensc.conf-dist solaris/pkginfo.in solaris/proto \ packaging/debian.templates/changelog \ packaging/debian.templates/compat \ packaging/debian.templates/control \ diff --git a/solaris/Makefile b/solaris/Makefile deleted file mode 100644 index 1ee69c9f8b..0000000000 --- a/solaris/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -PACKAGE=OSCopensc -PACKAGE_NAME=opensc -VERSION=CVS -PWD=pwd -CONFIGURE_PREFIX=$(PWD:sh)/.. -CONFIGURE=${CONFIGURE_PREFIX}/configure -CONFIGURE_ARGS=--prefix=/usr --sysconfdir=/etc/opensc --mandir=/usr/share/man --enable-pcsc --enable-openct -CONFIG_GUESS=${CONFIGURE_PREFIX}/config.guess -UNAME_ARCH=/usr/bin/uname -p -PLATFORM = $(CONFIG_GUESS:sh) -ARCH = $(UNAME_ARCH:sh) - -build: - @echo "Setup platform specific build directory build-${PLATFORM}" - mkdir -p build-${PLATFORM} - ( cd build-${PLATFORM}; CC=cc PCSC_CFLAGS=-I/usr/include/smartcard ${CONFIGURE} ${CONFIGURE_ARGS}; make ) - -dist: - @echo "Setup platform specific dist directory dist-${PLATFORM}" - mkdir -p dist-${PLATFORM} - @echo "Performing Installing in dist directory" - ( cd build-${PLATFORM}; make DESTDIR=`pwd`/../dist-${PLATFORM} install ) -package: - @echo "Setup package meta files" - -cp proto dist-${PLATFORM} - -sed "s|@ARCH@|${ARCH}|" dist-${PLATFORM}/checkinstall - -sed -e "s|@ARCH@|${ARCH}|" \ - -e "s|@VERSION@|${VERSION}|" \ - -e "s|@PACKAGE@|${PACKAGE}|" \ - -e "s|@PACKAGE_NAME@|${PACKAGE_NAME}|" \ - dist-${PLATFORM}/pkginfo - mkdir -p dist-${PLATFORM}/etc/opensc - -cp opensc.conf-dist dist-${PLATFORM}/etc/opensc/opensc.conf - @echo "Creating package" - ( \ - cd dist-${PLATFORM}; \ - pkgmk -o -r . -d . -f proto; \ - pkgtrans -s . ../OSCopensc-${VERSION}-${PLATFORM}.pkg ${PACKAGE} \ - ) diff --git a/solaris/README b/solaris/README deleted file mode 100644 index 2ea098daff..0000000000 --- a/solaris/README +++ /dev/null @@ -1,13 +0,0 @@ -Creating an installable package for Solaris 10 -============================================== - -The files in this directory are an attempt to ease -the building of opensc packages for Solaris 10. - -The basic steps to create a Solaris 10 package are: -# make build -# make dist -# make package - -NOTE: If you are using the GNU compiler you will - need to adjust the Makefile accordingly. diff --git a/solaris/checkinstall.in b/solaris/checkinstall.in deleted file mode 100755 index 9c198b9e40..0000000000 --- a/solaris/checkinstall.in +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -expected_platform="@ARCH@" -platform=`uname -p` -if [ ${platform} != ${expected_platform} ]; then - echo "This package must be installed on ${expected_platform}" - exit 1 -fi -exit 0 diff --git a/solaris/opensc.conf-dist b/solaris/opensc.conf-dist deleted file mode 100644 index 77cf4f2aac..0000000000 --- a/solaris/opensc.conf-dist +++ /dev/null @@ -1,277 +0,0 @@ -# Configuration file for OpenSC -# Example configuration file - -# NOTE: All key-value pairs must be terminated by a semicolon. - -# Default values for any application -# These can be overrided by an application -# specific configuration block. -app default { - # Amount of debug info to print - # - # A greater value means more debug info. - # Default: 0 - # - debug = 0; - - # The file to which debug output will be written - # - # A special value of 'stdout' is recognized. - # Default: stdout - # - # debug_file = /tmp/opensc-debug.log; - - # The file to which errors will be written - # - # A special value of 'stderr' is recognized. - # Default: stderr - # - # error_file = /tmp/opensc-errors.log; - - # Where to find the *.profile files for pkcs15init; - - profile_dir = /usr/share/opensc; - - # What reader drivers to load at start-up - # - # A special value of 'internal' will load all - # statically linked drivers. If an unknown (i.e. not - # internal) driver is supplied, a separate configuration - # configuration block has to be written for the driver. - # Default: internal - # NOTE: if "internal" keyword is used, must be the - # last entry in reader_drivers list - # - reader_drivers = openct, pcsc, ctapi; - - reader_driver ctapi { - # module /usr/local/towitoko/lib/libtowitoko.so { - # CT-API ports: - # 0..3 COM1..4 - # 4 Printer - # 5 Modem - # 6..7 LPT1..2 - # ports = 0; - # } - } - - # Define parameters specific to your readers. - # The following section shows definitions for PC/SC readers, - # but the same set of variables are applicatable to ctapi and - # openct readers, simply by using "reader_driver ctapi" and - # "reader_driver openct", respectively. - reader_driver pcsc { - # Whether to transform some APDU's from one case to another - # Possible values: - # none: Don't transform any APDU's - # case4as3: For T=0, send a case 4 APDU as case 3, - # (no Lc byte) the card will send back - # a 61xx SW, and we will follow up with a - # GetResponse command - # The SCM SCR111, Sun SCF, and e-gate readers - # seem to require this. - # case1as2: For T=0, send a case 1 APDU as case 2. - # (append an Le byte of 0) - # The Sun SCF and e-gate readers seem to - # require this - # case1as2_always: for any T=0/1, send a case 1 APDU as - # case 2. - # The Sun SCF reader may require this - # Default: none - # - apdu_masquerade = none; - # - # This sets the maximum send and receive sizes. - # Some IFD handlers do not properly handle APDUs with - # large lc or le bytes. - # - max_send_size = 252; - max_recv_size = 252; - # - # EXPERIMENTAL: Enable CCID pinpad support - # implemented (at least) in the libccid driver. - #use_ccid_pin_cmd = true; - } - - # What card drivers to load at start-up - # - # A special value of 'internal' will load all - # statically linked drivers. If an unknown (i.e. not - # internal) driver is supplied, a separate configuration - # configuration block has to be written for the driver. - # Default: internal - # NOTE: When "internal" keyword is used, must be last entry - # - # card_drivers = customcos, internal; - - # Card driver configuration blocks. - - # For all drivers, you can specify ATRs of cards that - # should be handled by this driver (in addition to the - # list of compiled-in ATRs). - # - # The supported internal card driver names are - # flex Cryptoflex/Multiflex - # setcos Setec - # etoken Aladdin eToken and other CardOS based cards - # gpk GPK 4K/8K/16K - # mcrd MICARDO 2.1 - # miocos MioCOS 1.1 - # openpgp OpenPGP card - # tcos TCOS 2.0 - # emv EMV compatible cards - - # GPK card driver additional ATR entry: - card_driver gpk { - # atr = 00:11:22; - } - - # For card drivers loaded from an external shared library/DLL, - # you need to specify the path name of the module - # - # card_driver customcos { - # The location of the driver library - # module = /usr/lib/opensc/drivers/card_customcos.so; - # atr = 00:11:22:33:44; - # atr = 55:66:77:88:99:aa:bb; - # } - - # Below are the framework specific configuration blocks. - - # PKCS #15 - framework pkcs15 { - # Whether to use the cache files in the user's - # home directory. - # - # At the moment you have to 'teach' the card to the - # system by: - # pkcs15-tool -L - # - # WARNING: Caching shouldn't be used in setuid root - # applications. - # Default: false - # - use_caching = true; - # Enable pkcs15 emulation - # Default: yes - enable_pkcs15_emulation = yes; - # Try pkcs15 emulation code first (before the normal - # pkcs15 processing). - # Default: no - try_emulation_first = no; - # Enable builtin emulators - # Default: yes - enable_builtin_emulation = yes; - # list of the builtin pkcs15 emulators to test - # possible values: esteid, openpgp, netkey, netkey, - # starcert, infocamere, postecert - builtin_emulators = esteid, openpgp, netkey, netkey, starcert, infocamere, postecert; - - # additional pkcs15 emulators (dynamic or builtin with - # a different atr etc.) - # emulate foo { - # module = builtin; - # atr = 11:22:33:44; - #} - } - - # Estonian ID card and Micardo driver currently play together with T=0 only. - # In theory only the 'cold' ATR should be specified, as T=0 will be the preferred - # protocol once you boot it up with T=0, but be paranoid. - - # Generic format: card_atr - # Only parameter currently understood is force_protocol - card_atr 3b:6e:00:ff:45:73:74:45:49:44:20:76:65:72:20:31:2e:30 { - force_protocol = t0; - } - card_atr 3b:fe:94:00:ff:80:b1:fa:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:43 { - force_protocol = t0; - } -} - -# For applications that use SCAM (pam_opensc, sia_opensc) -app scam { - framework pkcs15 { - use_caching = false; - } -} - -# Parameters for the OpenSC PKCS11 module -app opensc-pkcs11 { - pkcs11 { - # Maxmimum number of slots per smart card. - # If the card has fewer keys than defined here, - # the remaining number of slots will be empty. - # - # Note that there is currently a compile time - # maximum on the overall number of slots - # the pkcs11 module is able to handle. - num_slots = 4; - - # Normally, the pkcs11 module will create - # the full number of slots defined above by - # num_slots. If there are fewer pins/keys on - # the card, the remaining keys will be empty - # (and you will be able to create new objects - # within them). - # - # Set this option to true to hide these empty - # slots. - hide_empty_tokens = true; - - # By default, the OpenSC PKCS#11 module will - # try to lock this card once you have authenticated - # to the card via C_Login. This is done so that no - # other user can connect to the card and perform - # crypto operations (which may be possible because - # you have already authenticated with the card). - # - # However, this also means that no other application - # that _you_ run can use the card until your application - # has done a C_Logout or C_Finalize. In the case of - # Netscape or Mozilla, this does not happen until - # you exit the browser. - lock_login = true; - - # Normally, the pkcs11 module will not cache PINs - # presented via C_Login. However, some cards - # may not work properly with OpenSC; for instance - # when you have two keys on your card that get - # stored in two different directories. - # - # In this case, you can turn on PIN caching by setting - # cache_pins = true - # - # Default: false - cache_pins = false; - - # Set this value to false if you want to enfore on-card - # keypair generation - # - # Default: true - soft_keygen_allowed = true; - } -} - -# Parameters for the OpenSC PKCS11-Spy module, that logs all the -# communication between a pkcs11 module and it's calling application: -# app <--> pkcs11-spy <--> pkcs11 module -app pkcs11-spy { - spy { - # Where to log to. - # - # By default, the value of the PKCS11SPY_OUTPUT environment - # variable is used. And if that one isn't defined: stderr - # is used. - # - #output = /tmp/pkcs11-spy.log; - - # Which PKCS11 module to load. - # - # By default, the value of the PKCS11SPY environment - # variable is used. And if that one isn't defined, - # opensc-pkcs11.so is used. - # - #module = opensc-pkcs11.so; - } -} diff --git a/solaris/pkginfo.in b/solaris/pkginfo.in deleted file mode 100644 index 2e1cd1ffe1..0000000000 --- a/solaris/pkginfo.in +++ /dev/null @@ -1,12 +0,0 @@ -PKG="OSCopensc" -NAME="opensc" -VERSION="@VERSION@" -ARCH="@ARCH@" -CLASSES="none" -CATEGORY="drivers" -VENDOR="WW" -PSTAMP="26thFeb2005" -EMAIL="william@wanders.org" -ISTATES="S s 1 2 3" -RSTATES="S s 1 2 3" -BASEDIR="/" diff --git a/solaris/proto b/solaris/proto deleted file mode 100644 index 665d611b61..0000000000 --- a/solaris/proto +++ /dev/null @@ -1,118 +0,0 @@ -d none usr 0755 root sys -d none usr/share 0755 root other -d none usr/share/man 0755 root other -d none usr/share/man/man1 0755 root other -f none usr/share/man/man1/pkcs15-crypt.1 0644 root other -f none usr/share/man/man1/pkcs15-init.1 0644 root other -f none usr/share/man/man1/cryptoflex-tool.1 0644 root other -f none usr/share/man/man1/opensc-config.1 0644 root other -f none usr/share/man/man1/opensc-explorer.1 0644 root other -f none usr/share/man/man1/opensc-tool.1 0644 root other -f none usr/share/man/man1/pkcs15-tool.1 0644 root other -f none usr/share/man/man1/pkcs11-tool.1 0644 root other -f none usr/share/man/man1/cardos-info.1 0644 root other -d none usr/share/man/man3 0755 root other -f none usr/share/man/man3/sc_connect_card.3 0644 root other -f none usr/share/man/man3/sc_detect_card_presence.3 0644 root other -f none usr/share/man/man3/sc_disconnect_card.3 0644 root other -f none usr/share/man/man3/sc_establish_context.3 0644 root other -f none usr/share/man/man3/sc_file.3 0644 root other -f none usr/share/man/man3/sc_file_free.3 0644 root other -f none usr/share/man/man3/sc_file_new.3 0644 root other -f none usr/share/man/man3/sc_list_files.3 0644 root other -f none usr/share/man/man3/sc_lock.3 0644 root other -f none usr/share/man/man3/sc_read_binary.3 0644 root other -f none usr/share/man/man3/sc_read_record.3 0644 root other -f none usr/share/man/man3/sc_release_context.3 0644 root other -f none usr/share/man/man3/sc_select_file.3 0644 root other -f none usr/share/man/man3/sc_pkcs15_compute_signature.3 0644 root other -d none usr/share/man/man5 0755 root other -f none usr/share/man/man5/pkcs15-profile.5 0644 root other -d none usr/share/man/man7 0755 root other -f none usr/share/man/man7/opensc.7 0644 root other -f none usr/share/man/man7/pkcs15.7 0644 root other -d none usr/share/opensc 0755 root other -f none usr/share/opensc/opensc.conf.example 0644 root other -f none usr/share/opensc/cyberflex.profile 0644 root other -f none usr/share/opensc/flex.profile 0644 root other -f none usr/share/opensc/gpk.profile 0644 root other -f none usr/share/opensc/miocos.profile 0644 root other -f none usr/share/opensc/etoken.profile 0644 root other -f none usr/share/opensc/jcop.profile 0644 root other -f none usr/share/opensc/oberthur.profile 0644 root other -f none usr/share/opensc/starcos.profile 0644 root other -f none usr/share/opensc/pkcs15.profile 0644 root other -d none usr/lib 0755 root bin -s none usr/lib/libscconf.so.0=libscconf.so.0.0.9 -f none usr/lib/libscconf.so.0.0.9 0755 root bin -s none usr/lib/libscconf.so=libscconf.so.0.0.9 -f none usr/lib/libscconf.la 0755 root bin -f none usr/lib/libscconf.a 0644 root bin -s none usr/lib/libopensc.so.0=libopensc.so.0.0.9 -f none usr/lib/libopensc.so.0.0.9 0755 root bin -s none usr/lib/libopensc.so=libopensc.so.0.0.9 -d none usr/lib/pkgconfig 0755 root bin -f none usr/lib/pkgconfig/libopensc.pc 0644 root bin -f none usr/lib/pkgconfig/libpkcs15init.pc 0644 root bin -f none usr/lib/pkgconfig/libscconf.pc 0644 root bin -f none usr/lib/libopensc.la 0755 root bin -f none usr/lib/libopensc.a 0644 root bin -d none usr/lib/pkcs11 0755 root bin -s none usr/lib/pkcs11/libpkcs11.so.0=libpkcs11.so.0.0.9 -f none usr/lib/pkcs11/opensc-pkcs11.so 0755 root bin -f none usr/lib/pkcs11/opensc-pkcs11.la 0755 root bin -f none usr/lib/pkcs11/opensc-pkcs11.a 0644 root bin -f none usr/lib/pkcs11/libpkcs11.so.0.0.9 0755 root bin -s none usr/lib/pkcs11/libpkcs11.so=libpkcs11.so.0.0.9 -f none usr/lib/pkcs11/libpkcs11.la 0755 root bin -f none usr/lib/pkcs11/libpkcs11.a 0644 root bin -f none usr/lib/pkcs11/pkcs11-spy.so 0755 root bin -f none usr/lib/pkcs11/pkcs11-spy.la 0755 root bin -f none usr/lib/pkcs11/pkcs11-spy.a 0644 root bin -f none usr/lib/libpkcs15init.so.0.0.9 0755 root bin -s none usr/lib/libpkcs15init.so.0=libpkcs15init.so.0.0.9 -s none usr/lib/libpkcs15init.so=libpkcs15init.so.0.0.9 -f none usr/lib/libpkcs15init.la 0755 root bin -f none usr/lib/libpkcs15init.a 0644 root bin -d none usr/lib/opensc 0755 root bin -f none usr/lib/opensc/engine_opensc.so 0755 root bin -f none usr/lib/opensc/engine_opensc.la 0755 root bin -f none usr/lib/opensc/engine_opensc.a 0644 root bin -f none usr/lib/opensc/engine_pkcs11.so 0755 root bin -f none usr/lib/opensc/engine_pkcs11.la 0755 root bin -f none usr/lib/opensc/engine_pkcs11.a 0644 root bin -d none usr/include 0755 root bin -d none usr/include/opensc 0755 root bin -d none usr/include/opensc/rsaref 0755 root bin -f none usr/include/opensc/rsaref/pkcs11.h 0644 root bin -f none usr/include/opensc/rsaref/pkcs11f.h 0644 root bin -f none usr/include/opensc/rsaref/pkcs11t.h 0644 root bin -f none usr/include/opensc/rsaref/unix.h 0644 root bin -f none usr/include/opensc/rsaref/win32.h 0644 root bin -f none usr/include/opensc/scconf.h 0644 root bin -f none usr/include/opensc/opensc.h 0644 root bin -f none usr/include/opensc/pkcs15.h 0644 root bin -f none usr/include/opensc/cardctl.h 0644 root bin -f none usr/include/opensc/asn1.h 0644 root bin -f none usr/include/opensc/log.h 0644 root bin -f none usr/include/opensc/ui.h 0644 root bin -f none usr/include/opensc/errors.h 0644 root bin -f none usr/include/opensc/types.h 0644 root bin -f none usr/include/opensc/pkcs15-init.h 0644 root bin -f none usr/include/opensc/pkcs11.h 0644 root bin -d none usr/bin 0755 root bin -f none usr/bin/opensc-config 0755 root bin -f none usr/bin/opensc-tool 0755 root bin -f none usr/bin/opensc-explorer 0755 root bin -f none usr/bin/pkcs15-tool 0755 root bin -f none usr/bin/pkcs15-crypt 0755 root bin -f none usr/bin/pkcs11-tool 0755 root bin -f none usr/bin/cardos-info 0755 root bin -f none usr/bin/eidenv 0755 root bin -f none usr/bin/cryptoflex-tool 0755 root bin -f none usr/bin/pkcs15-init 0755 root bin -d none etc 0755 root sys -d none etc/opensc 0755 root sys -f none etc/opensc/opensc.conf 0644 root sys -i checkinstall=checkinstall -i pkginfo=pkginfo From 4a3a3e5df21ce3420d149e6d36c9d9c73d298077 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Jul 2018 11:23:49 +0200 Subject: [PATCH 0424/4321] opensc-notify: implement win32 message dispatching --- src/tools/opensc-notify.c | 162 +++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 5a586911e5..3a3cff783b 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -22,9 +22,7 @@ #endif #include "libopensc/log.h" -#include "opensc-notify-cmdline.h" #include "ui/notify.h" -#include #include #include #include @@ -32,14 +30,6 @@ static int run_daemon = 0; static struct sc_context *ctx = NULL; -void stop_daemon(int signo) -{ -#ifdef PCSCLITE_GOOD - sc_cancel(ctx); -#endif - run_daemon = 0; -} - #ifndef _WIN32 #include @@ -57,23 +47,17 @@ void Sleep(unsigned int Milliseconds) nanosleep(&req , &rem); } -#else -#include "ui/invisible_window.h" -static HINSTANCE g_hInstance = NULL; +#endif -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +void stop_daemon() { - if (message == WM_CLOSE) { - sc_cancel(ctx); - run_daemon = 0; - return TRUE; - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} +#ifdef PCSCLITE_GOOD + sc_cancel(ctx); #endif + run_daemon = 0; +} -void notify_daemon(void) +void notify_daemon() { int r; const unsigned int event_mask = SC_EVENT_CARD_EVENTS; @@ -85,22 +69,6 @@ void notify_daemon(void) const int timeout = 20000; struct sc_atr old_atr; void *reader_states = NULL; -#ifdef _WIN32 - LPCTSTR lpszClassName = "OPENSC_NOTIFY_CLASS"; - HWND hwnd = create_invisible_window(lpszClassName, WndProc, g_hInstance); -#elif HAVE_SIGACTION - struct sigaction new_sig, old_sig; - - /* Register signal handlers */ - new_sig.sa_handler = stop_daemon; - sigemptyset(&new_sig.sa_mask); - new_sig.sa_flags = SA_RESTART; - if ((sigaction(SIGINT, &new_sig, &old_sig) < 0) - || (sigaction(SIGTERM, &new_sig, &old_sig) < 0)) { - fprintf(stderr, "Failed to create signal handler: %s", strerror(errno)); - return; - } -#endif r = sc_establish_context(&ctx, "opensc-notify"); if (r < 0 || !ctx) { @@ -155,53 +123,103 @@ void notify_daemon(void) sc_release_context(ctx); ctx = NULL; } -#ifdef _WIN32 - delete_invisible_window(hwnd, lpszClassName, g_hInstance); -#endif } #ifdef _WIN32 -#include "ui/char_str_from_wchar.h" +#include "ui/invisible_window.h" #include +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_CLOSE || message == WM_QUIT) { + stop_daemon(); + return TRUE; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) +{ + notify_daemon(); + return 0; +} + /* This application shall be executable without a console. Therefor we're * creating a windows application that requires `WinMain()` rather than * `main()` as entry point. As benefit, we can properly handle `WM_CLOSE`. */ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd) { - LPWSTR *wargv = NULL; - char **argv = NULL; - int argc = 0, i; + LPCTSTR lpszClassName = "OPENSC_NOTIFY_CLASS"; + HWND hwnd = create_invisible_window(lpszClassName, WndProc, hInstance); - wargv = CommandLineToArgvW(GetCommandLineW(), &argc); - if (wargv == NULL) { - return 1; - } + sc_notify_init(); + run_daemon = 1; + HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); - argv = LocalAlloc(0, (sizeof *argv) * argc); - if (argv == NULL) { - goto err; - } - for (i = 0; i < argc; i++) { - argv[i] = char_str_from_wchar(wargv[i]); + MSG msg; + BOOL bRet = FALSE; + while((bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) { + if (bRet == -1) { + // handle the error and possibly exit + } else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } - g_hInstance = hInstance; + CloseHandle(hThread); + sc_notify_close(); + + delete_invisible_window(hwnd, lpszClassName, hInstance); + + return 0; +} + +#else + +#ifdef HAVE_SIGACTION +#include + +void sig_handler(int sig) { + stop_daemon(); +} + +void set_sa_handler(void) +{ + struct sigaction new_sig, old_sig; + + /* Register signal handlers */ + new_sig.sa_handler = sig_handler; + sigemptyset(&new_sig.sa_mask); + new_sig.sa_flags = SA_RESTART; + if ((sigaction(SIGINT, &new_sig, &old_sig) < 0) + || (sigaction(SIGTERM, &new_sig, &old_sig) < 0)) { + fprintf(stderr, "Failed to create signal handler: %s", strerror(errno)); + } +} #else + +void set_sa_handler(void) +{ +} +#endif + +#include "opensc-notify-cmdline.h" + int main (int argc, char **argv) { struct gengetopt_args_info cmdline; -#endif + memset(&cmdline, 0, sizeof cmdline); + + sc_notify_init(); -#ifndef _WIN32 if (cmdline_parser(argc, argv, &cmdline) != 0) goto err; - sc_notify_init(); - if (cmdline.customized_mode_counter) { sc_notify(cmdline.title_arg, cmdline.message_arg); } @@ -223,6 +241,7 @@ main (int argc, char **argv) if ((!cmdline.customized_mode_counter && !cmdline.standard_mode_counter) || cmdline.daemon_mode_counter) { + set_sa_handler(); run_daemon = 1; notify_daemon(); } else { @@ -230,27 +249,10 @@ main (int argc, char **argv) Sleep(100); } +err: sc_notify_close(); - cmdline_parser_free (&cmdline); -#else - /* FIXME the command line parser fails with our transformed argv. As quick - * fix, we only use daemon mode */ - sc_notify_init(); - run_daemon = 1; - notify_daemon(); - sc_notify_close(); -#endif -err: -#ifdef _WIN32 - if (argv) { - for (i = 0; i <= argc; i++) { - LocalFree(argv[i]); - } - LocalFree(argv); - } - LocalFree(wargv); -#endif return 0; } +#endif From 0f1fdb7872d23526256aada14a4044ea47cd9be4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Jul 2018 14:44:20 +0200 Subject: [PATCH 0425/4321] opensc-notify: add Exit button to tray icon --- src/tools/opensc-notify.c | 3 ++ src/ui/invisible_window.h | 2 +- src/ui/notify.c | 94 ++++++++++++++++++++++++++++++--------- src/ui/notify.h | 2 + 4 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 3a3cff783b..afc24353a8 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -167,6 +167,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowC TranslateMessage(&msg); DispatchMessage(&msg); } + if (msg.message == WM_COMMAND && LOWORD(msg.wParam) == WMAPP_EXIT) { + break; + } } CloseHandle(hThread); diff --git a/src/ui/invisible_window.h b/src/ui/invisible_window.h index f75056c245..bf20dfc8e3 100644 --- a/src/ui/invisible_window.h +++ b/src/ui/invisible_window.h @@ -22,7 +22,7 @@ HWND create_invisible_window(LPCTSTR lpszClassName, LRESULT (CALLBACK* WndProc)(HWND, UINT, WPARAM, LPARAM), - HINSTANCE hInstance) + HINSTANCE hInstance) { HWND hWnd = NULL; WNDCLASSEX wx = {0}; diff --git a/src/ui/notify.c b/src/ui/notify.c index 066ef78497..97db6f5444 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -75,30 +75,55 @@ void sc_notify_close(void) // {83C35893-99C6-4600-BFDB-45925C53BDD9} static const GUID myGUID = { 0x83c35893, 0x99c6, 0x4600, { 0xbf, 0xdb, 0x45, 0x92, 0x5c, 0x53, 0xbd, 0xd9 } }; HINSTANCE sc_notify_instance = NULL; -HWND hwndNotification = NULL; +HWND sc_notify_hwnd = NULL; BOOL delete_icon = TRUE; #define IDI_SMARTCARD 102 -UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1; +#define WMAPP_NOTIFYCALLBACK (WM_APP + 1) static BOOL RestoreTooltip(); +void ShowContextMenu(HWND hwnd, POINT pt); // we need commctrl v6 for LoadIconMetric() #include LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - if ((message == WM_DESTROY) - || (message == WMAPP_NOTIFYCALLBACK - && (LOWORD(lParam) == NIN_BALLOONTIMEOUT - || LOWORD(lParam) == NIN_BALLOONUSERCLICK))) { -#if 0 - DeleteNotificationIcon(); -#else - RestoreTooltip(); -#endif - return TRUE; + switch (message) { + case WM_COMMAND: + { + int const wmId = LOWORD(wParam); + // Parse the menu selection: + switch (wmId) + { + case WMAPP_EXIT: + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + } + break; + + case WMAPP_NOTIFYCALLBACK: + switch (LOWORD(lParam)) { + case NIN_BALLOONTIMEOUT: + case NIN_BALLOONUSERCLICK: + RestoreTooltip(); + break; + + case WM_CONTEXTMENU: + { + POINT const pt = { LOWORD(wParam), HIWORD(wParam) }; + ShowContextMenu(hwnd, pt); + } + break; + } + break; + + default: + return DefWindowProc(hwnd, message, wParam, lParam); } - return DefWindowProc(hwnd, message, wParam, lParam); + return 0; } static const char* lpszClassName = "NOTIFY_CLASS"; @@ -109,13 +134,14 @@ static BOOL AddNotificationIcon(void) TCHAR path[MAX_PATH]={0}; BOOL r; - hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance); - if (!hwndNotification) { + sc_notify_hwnd = create_invisible_window(lpszClassName, WndProc, + sc_notify_instance); + if (!sc_notify_hwnd) { return FALSE; } nid.cbSize = sizeof(NOTIFYICONDATA); - nid.hWnd = hwndNotification; + nid.hWnd = sc_notify_hwnd; // add the icon, setting the icon, tooltip, and callback message. // the icon will be identified with the GUID nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID; @@ -139,10 +165,11 @@ static BOOL AddNotificationIcon(void) strcpy(nid.szTip, PACKAGE_NAME); } - r = Shell_NotifyIcon(NIM_ADD, &nid); - - nid.uVersion = NOTIFYICON_VERSION_4; - r &= Shell_NotifyIcon(NIM_SETVERSION, &nid); + r = Shell_NotifyIcon(NIM_ADD, &nid); + if (TRUE == r) { + nid.uVersion = NOTIFYICON_VERSION_4; + r = Shell_NotifyIcon(NIM_SETVERSION, &nid); + } return r; } @@ -162,8 +189,9 @@ static BOOL DeleteNotificationIcon(void) r = Shell_NotifyIcon(NIM_DELETE, &nid); - r &= delete_invisible_window(hwndNotification, lpszClassName, + r &= delete_invisible_window(sc_notify_hwnd, lpszClassName, sc_notify_instance); + sc_notify_hwnd = NULL; return r; } @@ -180,6 +208,30 @@ static BOOL RestoreTooltip() return Shell_NotifyIcon(NIM_MODIFY, &nid); } +void ShowContextMenu(HWND hwnd, POINT pt) +{ + HMENU hMenu; + hMenu=CreatePopupMenu(); + + if (hMenu) { + AppendMenu(hMenu, MF_STRING, WMAPP_EXIT, "E&xit"); + + // our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away + SetForegroundWindow(hwnd); + + // respect menu drop alignment + UINT uFlags = TPM_RIGHTBUTTON; + if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) { + uFlags |= TPM_RIGHTALIGN; + } else { + uFlags |= TPM_LEFTALIGN; + } + + TrackPopupMenuEx(hMenu, uFlags, pt.x, pt.y, hwnd, NULL); + } +} + + static void notify_shell(struct sc_context *ctx, const char *title, const char *text, LPCTSTR icon_path, int icon_index) { diff --git a/src/ui/notify.h b/src/ui/notify.h index df1ad77a8f..859d8084db 100644 --- a/src/ui/notify.h +++ b/src/ui/notify.h @@ -39,6 +39,8 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr, * initialized before calling `sc_notify_init()`. If not initialized, we're * using the HINSTANCE of the EXE */ extern HINSTANCE sc_notify_instance; +/* This is the message created when the user clicks on "exit". */ +#define WMAPP_EXIT (WM_APP + 2) #endif #ifdef __cplusplus From 79fb808adfbf49fb106dc66f3ca5e8e96bd4d459 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Jul 2018 15:01:16 +0200 Subject: [PATCH 0426/4321] opensc-notify: localize exit menu entry --- src/ui/notify.c | 2 +- src/ui/strings.c | 6 ++++++ src/ui/strings.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index 97db6f5444..0c2bf06b86 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -214,7 +214,7 @@ void ShowContextMenu(HWND hwnd, POINT pt) hMenu=CreatePopupMenu(); if (hMenu) { - AppendMenu(hMenu, MF_STRING, WMAPP_EXIT, "E&xit"); + AppendMenu(hMenu, MF_STRING, WMAPP_EXIT, ui_get_str(NULL, NULL, NULL, NOTIFY_EXIT)); // our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away SetForegroundWindow(hwnd); diff --git a/src/ui/strings.c b/src/ui/strings.c index d98dbe3a6a..ecf9be8b9c 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -237,6 +237,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CANCEL: str = "Abbrechen"; break; + case NOTIFY_EXIT: + str = "Beenden"; + break; default: str = NULL; break; @@ -306,6 +309,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CANCEL: str = "Cancel"; break; + case NOTIFY_EXIT: + str = "Exit"; + break; default: str = NULL; break; diff --git a/src/ui/strings.h b/src/ui/strings.h index 49dd25ee9c..ddde3389a9 100644 --- a/src/ui/strings.h +++ b/src/ui/strings.h @@ -48,6 +48,7 @@ enum ui_str { NOTIFY_PIN_BAD, NOTIFY_PIN_BAD_TEXT, MD_PINPAD_DLG_CONTENT_USER_SIGN, + NOTIFY_EXIT, }; const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, From 0f9c7d126a22406f206f672b51af179ba5871a2c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Jul 2018 15:31:22 +0200 Subject: [PATCH 0427/4321] win32 installer: automatically start SCardSvr --- win32/OpenSC.wxs.in | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index b32eb70c04..c0fdac3901 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -56,8 +56,13 @@ - - + + + + + + + @@ -323,6 +328,7 @@ + From da40c61d13eed8f9ee3e0a064bd2002724927649 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Jul 2018 11:54:10 +0200 Subject: [PATCH 0428/4321] npa/sc-hsm: don't call EAC_cleanup() In Minidriver, when the DLL is called in multiple threads, this can lead to a deinitialization of OpenSSL's OIDs in one thread making them unavailable from other threads of the same process. As result, CVCs cannot be veriefied anymore during chip authentication. --- src/libopensc/card-npa.c | 6 ------ src/libopensc/card-sc-hsm.c | 4 ---- 2 files changed, 10 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 8a5f83c29f..99784b1723 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -356,9 +356,6 @@ static int npa_finish(sc_card_t * card) sc_sm_stop(card); npa_drv_data_free(card->drv_data); card->drv_data = NULL; -#ifdef ENABLE_OPENPACE - EAC_cleanup(); -#endif return SC_SUCCESS; } @@ -399,9 +396,6 @@ static int npa_init(sc_card_t * card) if (r != SC_SUCCESS) goto err; -#ifdef ENABLE_OPENPACE - EAC_init(); -#endif card->drv_data = npa_drv_data_create(); if (!card->drv_data) { npa_finish(card); diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 0d8c91f453..8963a56550 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1709,10 +1709,6 @@ static int sc_hsm_finish(sc_card_t * card) free(priv->EF_C_DevAut); free(priv); -#ifdef ENABLE_OPENPACE - EAC_cleanup(); -#endif - return SC_SUCCESS; } From cd557df54df175c15f9b397b1366f11cdb3d386d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 27 Jul 2018 15:50:41 +0200 Subject: [PATCH 0429/4321] md: change semantics of cancelling the PIN pad prompt md_pinpad_dlg_allow_cancel now defines whether or not the user is asked before verifying the PIN on the PIN pad. This can be denied without interaction with the PIN pad. A checkbox in the dialog allows the user to change this setting, which is saved in the registry by the path of the process. This change fixes the progress bar to match the actual configured timout. The progressbar now fills instead of running empty, which seemed less frightening for most users. This change also fixes some copy/paste errors in the documentation of opensc.conf(5). --- doc/files/files.html | 109 +++++++++++----------- doc/files/opensc.conf.5.xml.in | 99 ++++++++------------ etc/opensc.conf.example.in | 39 ++------ src/libopensc/ctx.c | 3 +- src/libopensc/opensc.h | 5 +- src/minidriver/Makefile.mak | 2 +- src/minidriver/minidriver.c | 159 ++++++++++++++++++++++++--------- src/ui/strings.c | 31 +++---- src/ui/strings.h | 3 +- win32/OpenSC.wxs.in | 2 +- 10 files changed, 227 insertions(+), 225 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index 362535dbfc..37fbb7b8a2 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -50,7 +50,11 @@

  • environment variables

  • - Windows registry (if available) + Windows registry key in + HKEY_CURRENT_USER (if available) +

  • + Windows registry key in + HKEY_LOCAL_MACHINE (if available)

  • system-wide configuration file (/home/fm/.local/etc/opensc.conf) @@ -118,7 +122,7 @@ westcos-tool: Configuration block for OpenSC tools

  • -

    Configuration Options

    +

    Configuration Options

    debug = num;

    Amount of debug info to print (Default: @@ -146,7 +150,7 @@

    If this configuration value is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\ProfileDir is checked.

    @@ -257,7 +261,7 @@

    If this configuration value is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\SmDir is checked.

    @@ -328,7 +332,7 @@ Parameters for the OpenSC PKCS11 module.

    For details see the section called “Configuration of PKCS#11”. -

    Configuration of Smart Card Reader Driver

    Configuration Options for all Reader Drivers

    +

    Configuration of Smart Card Reader Driver

    Configuration Options for all Reader Drivers

    max_send_size = num; max_recv_size = num;

    @@ -607,68 +611,53 @@

    Content of the PIN pad dialog for role "user" (Default: - "Please verify your - fingerprint or PIN on the - card."). + "Please enter your PIN on the PIN + pad.").

    md_pinpad_dlg_content_user_sign = value;

    Content of the PIN pad dialog for role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). -

    - md_pinpad_dlg_content_user_sign = name; -

    - Content of the PIN pad dialog for - role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). + "Please enter your digital signature + PIN on the PIN pad.").

    md_pinpad_dlg_content_admin = value;

    Content of the PIN pad dialog for role "admin" (Default: - "Please enter your PIN to - unblock the user PIN on the - PINPAD.") -

    - md_pinpad_dlg_content_cancel = value; -

    - Content of the PIN pad dialog after - pressing "Cancel", when the reader - doesn't respond to SCardCancel + "Please enter your PIN to unblock the + user PIN on the PIN pad.")

    md_pinpad_dlg_expanded = value;

    Expanded information of the PIN pad - dialog (Default: "This - window will be closed - automatically after the PIN has - been submitted on the PINPAD - (timeout typically after 30 - seconds).") -

    - md_pinpad_dlg_expanded_cancel = value; -

    - Expanded information of the PIN pad - dialog after pressing "Cancel", - when the reader doesn't respond to - SCardCancel (Default: - "Some readers only support - canceling the operation on the - PIN pad. Press Cancel or remove - the card."). + dialog (Default: "This window will be + closed automatically after the PIN has been + submitted on the PIN pad (timeout typically + after 30 seconds).")

    md_pinpad_dlg_enable_cancel = bool;

    Allow the user to cancel the PIN pad dialog (Default: - false) + false). + + If this value is set to + true, the user needs to + click "OK" to start the PIN verification on the + PIN pad. The user can choose the default + behavior by enabling or disabling the checkbox + of the dialog. The setting is saved by the + program's full path + (program_path) that + uses OpenSC. +

    + The registry key HKCU\Software\OpenSC + Project\OpenSC\md_pinpad_dlg_enable_cancel\program_path + overwrites this setting with a + DWORD set to either + 1 (enabled) or + 0 (disabled).

    md_pinpad_dlg_timeout = num;

    @@ -786,10 +775,12 @@ builtin_emulators = emulators;

    List of the builtin pkcs15 emulators to test - (Default: esteid, openpgp, tcos, - starcert, itacns, infocamere, postecert, - actalis, atrust-acos, gemsafeGPK, - gemsafeV1, tccardos, PIV-II) + (Default: westcos, openpgp, infocamere, + starcert, tcos, esteid, itacns, postecert, + PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, + atrust-acos, tccardos, entersafe, pteid, + oberthur, sc-hsm, dnie, gids, iasecc, jpki, + coolkey, din66291)

    pkcs11_enable_InitToken = bool;

    @@ -1029,14 +1020,14 @@ For the module to simulate the opensc-onepin module behavior the following option create_slots_for_pins = "user"; -

    Environment

    +

    Environment

    OPENSC_CONF

    Filename for a user defined configuration file

    If this environment variable is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\ConfigFile is checked.

    @@ -1060,7 +1051,7 @@

    If this environment variable is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\MiniDriverDebug is checked.

    @@ -1072,7 +1063,7 @@

    PIV configuration during initialization with piv-tool. -

    Files

    +

    Files

    /home/fm/.local/etc/opensc.conf

    System-wide configuration file @@ -1080,7 +1071,7 @@ /home/fm/.local/share/doc/opensc/opensc.conf

    Extended example configuration file -


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    +


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    The pkcs15-init utility for PKCS #15 smart card personalization is controlled via profiles. When starting, it will read two such profiles at the moment, a generic application profile, and a card @@ -1096,10 +1087,10 @@ The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ -

    Syntax

    +

    Syntax

    This section should contain information about the profile syntax. Will add this soonishly. -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-crypt(1)

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 4a8b2ceb43..b0cb4e75e7 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -25,7 +25,12 @@ environment variables
    - Windows registry (if available) + Windows registry key in + HKEY_CURRENT_USER (if available) + + + Windows registry key in + HKEY_LOCAL_MACHINE (if available) system-wide configuration file @@ -156,7 +161,7 @@ app application { If this configuration value is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\ProfileDir is checked. @@ -333,7 +338,7 @@ app application { If this configuration value is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\SmDir is checked. @@ -911,9 +916,8 @@ app application { Content of the PIN pad dialog for role "user" (Default: - "Please verify your - fingerprint or PIN on the - card."). + "Please enter your PIN on the PIN + pad.").
    @@ -923,23 +927,8 @@ app application { Content of the PIN pad dialog for role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). - - - - - - - - Content of the PIN pad dialog for - role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). + "Please enter your digital signature + PIN on the PIN pad."). @@ -949,19 +938,8 @@ app application { Content of the PIN pad dialog for role "admin" (Default: - "Please enter your PIN to - unblock the user PIN on the - PINPAD.") - - - - - - - - Content of the PIN pad dialog after - pressing "Cancel", when the reader - doesn't respond to SCardCancel + "Please enter your PIN to unblock the + user PIN on the PIN pad.") @@ -970,27 +948,10 @@ app application { Expanded information of the PIN pad - dialog (Default: "This - window will be closed - automatically after the PIN has - been submitted on the PINPAD - (timeout typically after 30 - seconds).") - - - - - - - - Expanded information of the PIN pad - dialog after pressing "Cancel", - when the reader doesn't respond to - SCardCancel (Default: - "Some readers only support - canceling the operation on the - PIN pad. Press Cancel or remove - the card."). + dialog (Default: "This window will be + closed automatically after the PIN has been + submitted on the PIN pad (timeout typically + after 30 seconds).") @@ -1000,7 +961,25 @@ app application { Allow the user to cancel the PIN pad dialog (Default: - false) + false). + + If this value is set to + true, the user needs to + click "OK" to start the PIN verification on the + PIN pad. The user can choose the default + behavior by enabling or disabling the checkbox + of the dialog. The setting is saved by the + program's full path + (program_path) that + uses OpenSC. + + + The registry key HKCU\Software\OpenSC + Project\OpenSC\md_pinpad_dlg_enable_cancel\program_path + overwrites this setting with a + DWORD set to either + 1 (enabled) or + 0 (disabled). @@ -1568,7 +1547,7 @@ app application { If this environment variable is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\ConfigFile is checked. @@ -1601,7 +1580,7 @@ app application { If this environment variable is not found on Windows, the registry key - HKLM\Software\OpenSC + Software\OpenSC Project\OpenSC\MiniDriverDebug is checked. diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 8ba5e4ddf1..d8abb8f811 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -313,21 +313,18 @@ app default { # Default: "Please enter your PIN to unblock the user PIN on the PINPAD." # md_pinpad_dlg_content_admin = "Content Admin"; # - # Content of the PIN pad dialog after pressing "Cancel", when the reader doesn't respond to SCardCancel - # md_pinpad_dlg_content_cancel = "Content Cancel"; - # # Expanded information of the PIN pad dialog # Default: "This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)." # md_pinpad_dlg_expanded = "Expanded Information"; # - # Expanded information of the PIN pad dialog after pressing "Cancel", when the reader doesn't respond to SCardCancel - # Default: "Some readers only support canceling the operation on the PIN pad. Press Cancel or remove the card." - # md_pinpad_dlg_expanded_cancel = "Expanded Information Cancel"; - # - # Allow the user to cancel the PIN pad dialog + # Allow the user to cancel the PIN pad dialog by not immediately requesting the PIN on the PIN pad # Default: false # md_pinpad_dlg_enable_cancel = true; # + # Content of the verification of the PIN pad dialog + # Default: "Automatically request PIN immediately on PIN-Pad" + # md_pinpad_dlg_verification = "Verification"; + # # Time in seconds for the progress bar of the PIN pad dialog to tick. "0" removes the progress bar. # Default: 30 # md_pinpad_dlg_timeout = 0; @@ -477,8 +474,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -503,8 +498,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -528,8 +521,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -553,8 +544,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -578,8 +567,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -603,8 +590,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -628,8 +613,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -653,8 +636,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -678,8 +659,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -703,8 +682,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -729,8 +706,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -755,8 +730,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; @@ -781,8 +754,6 @@ app default { md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_expanded_cancel = "Die Karte unterstützt das Abbrechen ausschließlich am PIN-Pad. Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen oder entfernen Sie die Karte."; - md_pinpad_dlg_allow_cancel = false; md_pinpad_dlg_timeout = 30; notify_card_inserted = "GoID erkannt"; notify_card_inserted_text = ""; diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index f6022dba77..6aefae7a85 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -165,7 +165,8 @@ struct _sc_ctx_options { int -sc_ctx_win32_get_config_value(char *name_env, char *name_reg, char *name_key, +sc_ctx_win32_get_config_value(const char *name_env, + const char *name_reg, const char *name_key, char *out, size_t *out_len) { #ifdef _WIN32 diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 7f6f6554d9..9853e48994 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -838,8 +838,9 @@ int sc_ctx_detect_readers(sc_context_t *ctx); * @param key path of register key * @return SC_SUCCESS on success and an error code otherwise. */ -int sc_ctx_win32_get_config_value(char *env, char *reg, char *key, char *out, - size_t *out_size); +int sc_ctx_win32_get_config_value(const char *env, + const char *reg, const char *key, + char *out, size_t *out_size); /** * Returns a pointer to the specified sc_reader_t object diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index c63232bc71..a2ef5b5d49 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -20,5 +20,5 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib /DELAYLOAD:bcrypt.dll + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib /DELAYLOAD:bcrypt.dll if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 82ce198096..c719c55675 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -37,6 +37,7 @@ #include #include +#include #include "cardmod.h" #include "common/compat_strlcpy.h" @@ -122,6 +123,8 @@ HINSTANCE g_inst; /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ #define IDI_SMARTCARD 102 +#define SUBKEY_ENABLE_CANCEL "Software\\OpenSC Project\\OpenSC\\md_pinpad_dlg_enable_cancel" + /* magic to determine previous pinpad authentication */ #define MAGIC_SESSION_PIN "opensc-minidriver" @@ -649,11 +652,30 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, BOOL ret_default) } -/* 'Write' mode can be enabled from the OpenSC configuration file*/ +/* 'cancellation' mode can be enabled from the OpenSC configuration file*/ static BOOL md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) { + TCHAR path[MAX_PATH]={0}; + logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enabled?\n"); + + if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { + DWORD enable_cancel; + size_t sz = sizeof enable_cancel; + + if (SC_SUCCESS == sc_ctx_win32_get_config_value(NULL, path, + SUBKEY_ENABLE_CANCEL, + (char *)(&enable_cancel), &sz)) { + switch (enable_cancel) { + case 0: + return FALSE; + case 1: + return TRUE; + } + } + } + return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", FALSE); } @@ -2821,65 +2843,85 @@ static const char *md_get_ui_str(PCARD_DATA pCardData, enum ui_str id) static HRESULT CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { LONG_PTR param; - int timeout; UNREFERENCED_PARAMETER(lParam); switch (message) { case TDN_CREATED: { PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)dwRefData)[7]; + DWORD now = timeGetTime(); + /* remove the icon from the window title */ SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + + /* store parameter like pCardData for further use if needed */ + ((LONG_PTR*)dwRefData)[11] = (LONG_PTR) now; + SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); + ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; + if (!md_is_pinpad_dlg_enable_cancel(pCardData)) { + int timeout = md_get_pinpad_dlg_timeout(pCardData); + if (timeout > 0) { + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, timeout*1000)); + } + /* disable "Close" */ SendMessage(hWnd, TDM_ENABLE_BUTTON, IDCLOSE, 0); + + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); + } else { + int timeout = md_get_pinpad_dlg_timeout(pCardData); + if (timeout > 0) { + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, 0); + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_STATE, PBST_PAUSED, 0); + } } - timeout = md_get_pinpad_dlg_timeout(pCardData); - if (timeout > 0) { - /* update the progress bar with the tick counter for the number of specified seconds */ - SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, timeout*1000)); - } - /* store parameter like pCardData for further use if needed */ - SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); - /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; - ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); } return S_OK; case TDN_TIMER: - /* tick down for 30 seconds */ - SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, 30000 - wParam, 0L); + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam, 0L); return S_OK; case TDN_BUTTON_CLICKED: - /* We ignore anything else than the Cancel button */ - if (LOWORD(wParam) != IDCANCEL) - return S_FALSE; + switch(LOWORD(wParam)) { + case IDCANCEL: + DestroyWindow(hWnd); + break; - param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; - VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - WCHAR *pszContent = wchar_from_char_str(md_get_ui_str(pCardData, - MD_PINPAD_DLG_CONTENT_CANCEL)); - WCHAR *pszExpandedInformation = wchar_from_char_str(md_get_ui_str(pCardData, - MD_PINPAD_DLG_EXPANDED_CANCEL)); - - sc_cancel(vs->ctx); - - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, - TDE_CONTENT, (LPARAM) pszContent); - SendMessage(hWnd, TDM_SET_ELEMENT_TEXT, - TDE_EXPANDED_INFORMATION, (LPARAM) pszExpandedInformation); - SendMessage(hWnd, TDM_UPDATE_ICON, TDIE_ICON_MAIN, (LPARAM)MAKEINTRESOURCE(TD_INFORMATION_ICON)); - /* remove the icon from the window title */ - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); - SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + case IDOK: + param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; + VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + + int timeout = md_get_pinpad_dlg_timeout(pCardData); + if (timeout > 0) { + DWORD start = (DWORD)((LONG_PTR*)dwRefData)[11]; + DWORD delta = timeGetTime() - start; + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(delta, delta + timeout*1000)); + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0); + } + + /* disable "OK" and "Cancel" */ + SendMessage(hWnd, TDM_ENABLE_BUTTON, IDOK, 0); + SendMessage(hWnd, TDM_ENABLE_BUTTON, IDCANCEL, 0); + + /* disable "x" */ + HMENU menu = GetSystemMenu(hWnd, FALSE); + if (menu) { + EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); + } - LocalFree(pszContent); - LocalFree(pszExpandedInformation); + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); + } + break; + + default: + return S_FALSE; } break; @@ -2905,11 +2947,12 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p const u8 *pin1, size_t pin1len, const u8 *pin2, size_t *pin2len, BOOL displayUI, DWORD role) { - LONG_PTR parameter[11]; + LONG_PTR parameter[12]; INT_PTR result = 0; HWND hWndDlg = 0; TASKDIALOGCONFIG tc = {0}; int rv = 0; + BOOL checked, user_checked; VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); /* stack the parameters */ @@ -2924,6 +2967,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p parameter[8] = (LONG_PTR)role; parameter[9] = 0; /* place holder for thread handle */ parameter[10] = 0; /* place holder for window handle */ + parameter[11] = 0; /* place holder for end of timer */ /* launch the function to perform in the same thread context */ if (!displayUI) { @@ -2947,6 +2991,8 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p MD_PINPAD_DLG_CONTROL_COLLAPSED)); tc.pszExpandedInformation = wchar_from_char_str(md_get_ui_str(pCardData, MD_PINPAD_DLG_EXPANDED)); + tc.pszVerificationText = wchar_from_char_str(md_get_ui_str(pCardData, + MD_PINPAD_DLG_VERIFICATION)); switch (role) { case ROLE_ADMIN: tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData, @@ -2977,12 +3023,14 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p tc.dwFlags |= TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER; } - if (md_is_pinpad_dlg_enable_cancel(pCardData)) { - tc.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION; - tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; - } else { + checked = !md_is_pinpad_dlg_enable_cancel(pCardData); + if (checked) { + tc.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED; /* can't use TDCBF_CANCEL_BUTTON since this would implicitly set TDF_ALLOW_DIALOG_CANCELLATION */ tc.dwCommonButtons = TDCBF_CLOSE_BUTTON; + } else { + tc.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION; + tc.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_OK_BUTTON; } tc.hMainIcon = md_get_pinpad_dlg_icon(pCardData); @@ -2995,7 +3043,30 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p tc.lpCallbackData = (LONG_PTR)parameter; tc.cbSize = sizeof(tc); - result = TaskDialogIndirect(&tc, NULL, NULL, NULL); + result = TaskDialogIndirect(&tc, NULL, NULL, &user_checked); + + if (user_checked != checked) { + TCHAR path[MAX_PATH]={0}; + if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { + HKEY hKey; + LSTATUS lstatus = RegOpenKeyExA(HKEY_CURRENT_USER, + SUBKEY_ENABLE_CANCEL, 0, KEY_WRITE, &hKey); + if (ERROR_SUCCESS != lstatus) { + lstatus = RegCreateKeyExA(HKEY_CURRENT_USER, + SUBKEY_ENABLE_CANCEL, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &hKey, NULL); + } + if (ERROR_SUCCESS == lstatus) { + DWORD enable_cancel = 0; + if (user_checked == FALSE) { + enable_cancel = 1; + } + lstatus = RegSetValueEx(hKey, path, 0, REG_DWORD, + (const BYTE*)&enable_cancel, sizeof(enable_cancel)); + RegCloseKey(hKey); + } + } + } LocalFree((WCHAR *) tc.pszWindowTitle); LocalFree((WCHAR *) tc.pszMainInstruction); diff --git a/src/ui/strings.c b/src/ui/strings.c index ecf9be8b9c..446e199ced 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -113,15 +113,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CONTENT_ADMIN: option = "md_pinpad_dlg_content_admin"; break; - case MD_PINPAD_DLG_CONTENT_CANCEL: - option = "md_pinpad_dlg_content_cancel"; - break; case MD_PINPAD_DLG_EXPANDED: option = "md_pinpad_dlg_expanded"; break; - case MD_PINPAD_DLG_EXPANDED_CANCEL: - option = "md_pinpad_dlg_expanded_cancel"; - break; case MD_PINPAD_DLG_ICON: option = "md_pinpad_dlg_icon"; break; @@ -149,6 +143,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case NOTIFY_PIN_BAD_TEXT: option = "notify_pin_bad_text"; break; + case MD_PINPAD_DLG_VERIFICATION: + option = "md_pinpad_dlg_verification"; + break; default: option = NULL; break; @@ -191,15 +188,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CONTENT_ADMIN: str = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; break; - case MD_PINPAD_DLG_CONTENT_CANCEL: - str = "Nutzen Sie das PIN-Pad, um den Vorgang abzubrechen."; - break; case MD_PINPAD_DLG_EXPANDED: str = "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PIN-Pad eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; break; - case MD_PINPAD_DLG_EXPANDED_CANCEL: - str = "Einige Kartenleser unterstützen das Abbrechen ausschließlich am PIN-Pad. Drücken Sie Cancel (Abbruch) oder entfernen Sie die Karte."; - break; case NOTIFY_CARD_INSERTED: if (p15card) { str = "Smartcard kann jetzt verwendet werden"; @@ -228,9 +219,11 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case NOTIFY_PIN_BAD_TEXT: str = "Smartcard ist gesperrt"; break; + case MD_PINPAD_DLG_VERIFICATION: + str = "Sofort PIN am PIN-Pad abfragen"; + break; case MD_PINPAD_DLG_CONTROL_COLLAPSED: - /* fall through */ case MD_PINPAD_DLG_CONTROL_EXPANDED: str = "Weitere Informationen"; break; @@ -246,7 +239,6 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, } break; case EN: - /* fall through */ default: switch (id) { case MD_PINPAD_DLG_TITLE: @@ -264,15 +256,9 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case MD_PINPAD_DLG_CONTENT_ADMIN: str = "Please enter your PIN to unblock the user PIN on the PIN pad."; break; - case MD_PINPAD_DLG_CONTENT_CANCEL: - str = "Use the PIN pad to cancel the operation."; - break; case MD_PINPAD_DLG_EXPANDED: str = "This window will be closed automatically after the PIN has been submitted on the PIN pad (timeout typically after 30 seconds)."; break; - case MD_PINPAD_DLG_EXPANDED_CANCEL: - str = "Some readers only support canceling the operation on the PIN pad. Press Cancel or remove the card."; - break; case NOTIFY_CARD_INSERTED: if (p15card) { str = "Smart card is ready to use"; @@ -301,8 +287,11 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, case NOTIFY_PIN_BAD_TEXT: str = "Smart card is locked"; break; + case MD_PINPAD_DLG_VERIFICATION: + str = "Immediately request PIN on PIN-Pad"; + break; + case MD_PINPAD_DLG_CONTROL_COLLAPSED: - /* fall through */ case MD_PINPAD_DLG_CONTROL_EXPANDED: str = "Click here for more information"; break; diff --git a/src/ui/strings.h b/src/ui/strings.h index ddde3389a9..488dd62c54 100644 --- a/src/ui/strings.h +++ b/src/ui/strings.h @@ -32,9 +32,7 @@ enum ui_str { MD_PINPAD_DLG_MAIN, MD_PINPAD_DLG_CONTENT_USER, MD_PINPAD_DLG_CONTENT_ADMIN, - MD_PINPAD_DLG_CONTENT_CANCEL, MD_PINPAD_DLG_EXPANDED, - MD_PINPAD_DLG_EXPANDED_CANCEL, MD_PINPAD_DLG_CONTROL_COLLAPSED, MD_PINPAD_DLG_CONTROL_EXPANDED, MD_PINPAD_DLG_ICON, @@ -49,6 +47,7 @@ enum ui_str { NOTIFY_PIN_BAD_TEXT, MD_PINPAD_DLG_CONTENT_USER_SIGN, NOTIFY_EXIT, + MD_PINPAD_DLG_VERIFICATION, }; const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index c0fdac3901..5ca2341605 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -71,7 +71,7 @@ - + From 9294058d5ce28a4ec44b0131f66189bc529726f4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 28 Jul 2018 16:52:29 +0200 Subject: [PATCH 0430/4321] fixed requesting DWORD with sc_ctx_win32_get_config_value the length of the value is not determined by strlen() --- src/libopensc/card.c | 6 +++-- src/libopensc/ctx.c | 53 +++++++++++++++++----------------------- src/libopensc/opensc.h | 2 +- src/pkcs15init/profile.c | 3 ++- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 6bd0ef2f9d..aeba79accb 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1363,11 +1363,13 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo #ifdef _WIN32 if (!module_path || strlen(module_path) == 0) { - temp_len = PATH_MAX; + temp_len = PATH_MAX-1; rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\OpenSC Project\\OpenSC", temp_path, &temp_len); - if (rv == SC_SUCCESS) + if (rv == SC_SUCCESS) { + temp_path[temp_len] = '\0'; module_path = temp_path; + } } expanded_len = PATH_MAX; expanded_len = ExpandEnvironmentStringsA(module_path, expanded_val, expanded_len); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 6aefae7a85..46dcce49dd 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -167,12 +167,9 @@ struct _sc_ctx_options { int sc_ctx_win32_get_config_value(const char *name_env, const char *name_reg, const char *name_key, - char *out, size_t *out_len) + void *out, size_t *out_len) { #ifdef _WIN32 - char temp[PATH_MAX + 1]; - char *value = NULL; - DWORD temp_len = PATH_MAX; long rc; HKEY hKey; @@ -180,9 +177,12 @@ sc_ctx_win32_get_config_value(const char *name_env, return SC_ERROR_INVALID_ARGUMENTS; if (name_env) { - value = getenv(name_env); - if (value) - goto done; + char *value = value = getenv(name_env); + if (strlen(value) < *out_len) + return SC_ERROR_NOT_ENOUGH_MEMORY; + memcpy(out, value, strlen(value)); + *out_len = strlen(value); + return SC_SUCCESS; } if (!name_reg) @@ -193,36 +193,26 @@ sc_ctx_win32_get_config_value(const char *name_env, rc = RegOpenKeyExA(HKEY_CURRENT_USER, name_key, 0, KEY_QUERY_VALUE, &hKey); if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - value = temp; + DWORD len = *out_len; + rc = RegQueryValueEx(hKey, name_reg, NULL, NULL, out, &len); RegCloseKey(hKey); - } - - if (!value) { - rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, name_key, 0, KEY_QUERY_VALUE, &hKey ); if (rc == ERROR_SUCCESS) { - temp_len = PATH_MAX; - rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len); - if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX)) - value = temp; - RegCloseKey(hKey); + *out_len = len; + return SC_SUCCESS; } } -done: - if (value) { - if (strlen(value) >= *out_len) - return SC_ERROR_BUFFER_TOO_SMALL; - strcpy(out, value); - *out_len = strlen(out); - return SC_SUCCESS; + rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, name_key, 0, KEY_QUERY_VALUE, &hKey); + if (rc == ERROR_SUCCESS) { + DWORD len = *out_len; + rc = RegQueryValueEx(hKey, name_reg, NULL, NULL, out, &len); + RegCloseKey(hKey); + if (rc == ERROR_SUCCESS) { + *out_len = len; + return SC_SUCCESS; + } } - memset(out, 0, *out_len); - *out_len = 0; - return SC_ERROR_OBJECT_NOT_FOUND; #else return SC_ERROR_NOT_SUPPORTED; @@ -677,13 +667,14 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks)); #ifdef _WIN32 - temp_len = PATH_MAX; + temp_len = PATH_MAX-1; r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC", temp_path, &temp_len); if (r) { sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key."); return; } + temp_path[temp_len] = '\0'; conf_path = temp_path; #else conf_path = getenv("OPENSC_CONF"); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 9853e48994..b9b960d8f6 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -840,7 +840,7 @@ int sc_ctx_detect_readers(sc_context_t *ctx); */ int sc_ctx_win32_get_config_value(const char *env, const char *reg, const char *key, - char *out, size_t *out_size); + void *out, size_t *out_size); /** * Returns a pointer to the specified sc_reader_t object diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 2ae105b3ca..107529a576 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -342,11 +342,12 @@ sc_profile_load(struct sc_profile *profile, const char *filename) if (!profile_dir) { #ifdef _WIN32 - temp_len = PATH_MAX; + temp_len = PATH_MAX - 1; res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\OpenSC Project\\OpenSC", temp_path, &temp_len); if (res) LOG_FUNC_RETURN(ctx, res); + temp_path[temp_len] = '\0'; profile_dir = temp_path; #else profile_dir = SC_PKCS15_PROFILE_DIRECTORY; From 80d44a5b993468cd92a781942b717339e8130e61 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 5 Aug 2018 12:28:50 +0200 Subject: [PATCH 0431/4321] use proper prefix in documentation --- doc/files/files.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index 37fbb7b8a2..ea5aa865ed 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -57,7 +57,7 @@ HKEY_LOCAL_MACHINE (if available)

  • system-wide configuration file - (/home/fm/.local/etc/opensc.conf) + (/usr/etc/opensc.conf)

  • The configuration file, opensc.conf, is composed @@ -146,7 +146,7 @@ directory for pkcs15-init(1). - (Default: /home/fm/.local/share/opensc). + (Default: /usr/share/opensc).

    If this configuration value is not found on Windows, the registry key @@ -257,7 +257,7 @@ module_path = filename;

    Directory with external SM module - (Default: /home/fm/.local/lib). + (Default: /usr/lib).

    If this configuration value is not found on Windows, the registry key @@ -1064,11 +1064,11 @@ PIV configuration during initialization with piv-tool.

    Files

    - /home/fm/.local/etc/opensc.conf + /usr/etc/opensc.conf

    System-wide configuration file

    - /home/fm/.local/share/doc/opensc/opensc.conf + /usr/share/doc/opensc/opensc.conf

    Extended example configuration file


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    From 849c9785e336d9b9e45318af1427a4cc16746bea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Aug 2018 15:46:53 +0200 Subject: [PATCH 0432/4321] added missing rule for opensc.conf.5.xml --- doc/files/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am index fe245247ac..100749950a 100644 --- a/doc/files/Makefile.am +++ b/doc/files/Makefile.am @@ -9,7 +9,7 @@ if ENABLE_MAN man5_MANS = pkcs15-profile.5 opensc.conf.5 endif -opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in +opensc.conf.5.xml opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in sed \ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ -e 's|@docdir[@]|$(docdir)|g' \ From f66ceab4bbc3cae529a22b5f3688076cc119bd7c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Aug 2018 15:50:51 +0200 Subject: [PATCH 0433/4321] fixed typo fixes https://github.com/OpenSC/OpenSC/issues/1443 --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b35a646595..9579c766b7 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -39,7 +39,7 @@ endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DDEFAULT_PKCS11_PROVIDER)"' +AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ From 8fe377e93b4b56060e5bbfb6f3142ceaeca744fa Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 May 2018 14:54:47 +0200 Subject: [PATCH 0434/4321] fixed out of bounds reads Thanks to Eric Sesterhenn from X41 D-SEC GmbH for reporting and suggesting security fixes. --- src/libopensc/asn1.c | 1 + src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-authentic.c | 5 ++++- src/libopensc/card-cac.c | 9 +++++++-- src/libopensc/card-coolkey.c | 2 +- src/libopensc/card-entersafe.c | 8 +++++--- src/libopensc/card-epass2003.c | 35 ++++++++++++++++++---------------- src/libopensc/card-gpk.c | 3 +++ src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-oberthur.c | 7 +++++++ src/libopensc/card-openpgp.c | 6 ++++++ src/libopensc/card-piv.c | 9 +++++---- src/libopensc/card-rtecp.c | 2 +- src/libopensc/card-setcos.c | 18 +++++++++++++++-- src/libopensc/ef-gdo.c | 2 +- src/libopensc/pkcs15-itacns.c | 1 + src/libopensc/pkcs15-tcos.c | 8 +++++--- src/tools/opensc-tool.c | 21 ++++++++++---------- 18 files changed, 95 insertions(+), 46 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index b1be88dcf0..e43c0f1362 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -103,6 +103,7 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, len = *p & 0x7f; if (*p++ & 0x80) { unsigned int a = 0; + left--; if (len > 4 || len > left) return SC_ERROR_INVALID_ASN1_OBJECT; left -= len; diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 8055073cd7..5459d98f1b 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -169,7 +169,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu while (len != 0) { unsigned int amode, tlen = 3; - if (len < 5 && p[0] != 0x80 && p[1] != 0x01) { + if (len < 5 || p[0] != 0x80 || p[1] != 0x01) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid access mode encoding"); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index f72c2d2095..9fbda94a3c 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -560,6 +560,9 @@ authentic_set_current_files(struct sc_card *card, struct sc_path *path, sc_file_dup(&card->cache.current_df, file); if (cur_df_path.len) { + if (cur_df_path.len + card->cache.current_df->path.len > sizeof card->cache.current_df->path.value + || cur_df_path.len > sizeof card->cache.current_df->path.value) + LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); memcpy(card->cache.current_df->path.value + cur_df_path.len, card->cache.current_df->path.value, card->cache.current_df->path.len); @@ -988,7 +991,7 @@ authentic_process_fci(struct sc_card *card, struct sc_file *file, } sc_log_hex(ctx, "ACL data", file->sec_attr, file->sec_attr_len); - for (ii = 0; ii < file->sec_attr_len / 2; ii++) { + for (ii = 0; ii < file->sec_attr_len / 2 && ii < sizeof ops_DF; ii++) { unsigned char op = file->type == SC_FILE_TYPE_DF ? ops_DF[ii] : ops_EF[ii]; unsigned char acl = *(file->sec_attr + ii*2); unsigned char cred_id = *(file->sec_attr + ii*2 + 1); diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 4e853e5c2c..a30a04385f 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -664,12 +664,17 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, cert_len = 0; cert_ptr = NULL; cert_type = 0; - for (tl_ptr = tl, val_ptr=val; tl_len >= 2; - val_len -= len, val_ptr += len, tl_len -= tl_head_len) { + for (tl_ptr = tl, val_ptr = val; tl_len >= 2; + val_len -= len, val_ptr += len, tl_len -= tl_head_len) { tl_start = tl_ptr; if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS) break; tl_head_len = tl_ptr - tl_start; + + /* incomplete value */ + if (val_len < len) + break; + if (tag == CAC_TAG_CERTIFICATE) { cert_len = len; cert_ptr = val_ptr; diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 4c966f64b3..3c57628b0b 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1467,7 +1467,7 @@ coolkey_find_attribute(sc_card_t *card, sc_cardctl_coolkey_attribute_t *attribut for (i=0; i < attribute_count; i++) { size_t record_len = coolkey_get_attribute_record_len(attr, object_record_type, buf_len); /* make sure we have the complete record */ - if (buf_len < record_len) { + if (buf_len < record_len || record_len < 4) { return SC_ERROR_CORRUPTED_DATA; } /* does the attribute match the one we are looking for */ diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index d5264349dd..828b03051b 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -1408,13 +1408,15 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) data->modulus = malloc(len); if (!data->modulus) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_OUT_OF_MEMORY); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY); p=rbuf; - assert(*p=='E'); + if (*p!='E') + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); p+=2+p[1]; /* N */ - assert(*p=='N'); + if (*p!='N') + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); ++p; if(*p++>0x80) { diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 88fe82753d..cbe417cf78 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -740,11 +740,11 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); } else { - unsigned char iv[8] = { 0 }; + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; unsigned char tmp[8] = { 0 }; des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); - memset(iv, 0x00, 8); + memset(iv, 0x00, sizeof iv); des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); } @@ -903,9 +903,9 @@ epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_ap * SW12(TLV)=0x99|0x02|SW1+SW2 * MAC(TLV)=0x8e|0x08|MAC */ static int -decrypt_response(struct sc_card *card, unsigned char *in, unsigned char *out, size_t * out_len) +decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned char *out, size_t * out_len) { - size_t in_len; + size_t cipher_len; size_t i; unsigned char iv[16] = { 0 }; unsigned char plaintext[4096] = { 0 }; @@ -922,37 +922,40 @@ decrypt_response(struct sc_card *card, unsigned char *in, unsigned char *out, si /* parse cipher length */ if (0x01 == in[2] && 0x82 != in[1]) { - in_len = in[1]; + cipher_len = in[1]; i = 3; } else if (0x01 == in[3] && 0x81 == in[1]) { - in_len = in[2]; + cipher_len = in[2]; i = 4; } else if (0x01 == in[4] && 0x82 == in[1]) { - in_len = in[2] * 0x100; - in_len += in[3]; + cipher_len = in[2] * 0x100; + cipher_len += in[3]; i = 5; } else { return -1; } + if (cipher_len < 2 || i+cipher_len > inlen || cipher_len > sizeof plaintext) + return -1; + /* decrypt */ if (KEY_TYPE_AES == exdata->smtype) - aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], in_len - 1, plaintext); + aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); else - des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], in_len - 1, plaintext); + des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); /* unpadding */ - while (0x80 != plaintext[in_len - 2] && (in_len - 2 > 0)) - in_len--; + while (0x80 != plaintext[cipher_len - 2] && (cipher_len - 2 > 0)) + cipher_len--; - if (2 == in_len) + if (2 == cipher_len) return -1; - memcpy(out, plaintext, in_len - 2); - *out_len = in_len - 2; + memcpy(out, plaintext, cipher_len - 2); + *out_len = cipher_len - 2; return 0; } @@ -974,7 +977,7 @@ epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apd r = sc_check_sw(card, sm->sw1, sm->sw2); if (r == SC_SUCCESS) { if (exdata->sm) { - if (0 != decrypt_response(card, sm->resp, plain->resp, &len)) + if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len)) return SC_ERROR_CARD_CMD_FAILED; } else { diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index b3dd848c21..c8d4469142 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -409,6 +409,9 @@ gpk_parse_fileinfo(sc_card_t *card, if (sp[0] == 0x85) { unsigned int ac[3], n; + if (sp + 11 + 2*3 >= end) + break; + file->id = (sp[4] << 8) | sp[5]; file->size = (sp[8] << 8) | sp[9]; file->record_length = sp[7]; diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 3e0d3acd9e..48d4cea560 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -2548,7 +2548,7 @@ iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) if (card->type == SC_CARD_TYPE_IASECC_SAGEM) { /* 5A 0A 92 50 00 20 10 10 25 00 01 3F */ /* 00 02 01 01 02 50 00 13 */ - for (ii=0; ii < rbuf[1] - offs; ii++) + for (ii=0; (ii < rbuf[1] - offs) && (ii + offs + 2 < sizeof(rbuf)); ii++) *(card->serialnr.value + ii) = ((rbuf[ii + offs + 1] & 0x0F) << 4) + ((rbuf[ii + offs + 2] & 0xF0) >> 4) ; card->serialnr.len = ii; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 818a6a6cb5..112367b570 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -476,6 +476,9 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, memcpy(&path, in_path, sizeof(struct sc_path)); + if (!auth_current_df) + return SC_ERROR_OBJECT_NOT_FOUND; + sc_log(card->ctx, "in_path; type=%d, path=%s, out %p", in_path->type, sc_print_path(in_path), file_out); sc_log(card->ctx, "current path; type=%d, path=%s", @@ -2113,6 +2116,10 @@ auth_read_binary(struct sc_card *card, unsigned int offset, bn[1].data = NULL; LOG_FUNC_CALLED(card->ctx); + + if (!auth_current_ef) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid auth_current_ef"); + sc_log(card->ctx, "offset %i; size %"SC_FORMAT_LEN_SIZE_T"u; flags 0x%lX", offset, count, flags); diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 594ff0525c..5fa3899227 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1061,6 +1061,9 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) const u8 *data = in; pgp_blob_t *new; + if (!in) + return SC_ERROR_OBJECT_NOT_VALID; + r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); if (r < 0 || data == NULL) { @@ -1069,6 +1072,9 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) return SC_ERROR_OBJECT_NOT_VALID; } + if (data + len > blob->data + blob->len) + return SC_ERROR_OBJECT_NOT_VALID; + /* undo ASN1's split of tag & class */ for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { cla <<= 8; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 13b0cc21c5..0cd3f5ad99 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -573,7 +573,7 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, * the buffer is bigger, so it will not produce "ASN1.tag too long!" */ body = rbuf; - if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + if (sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS || body == NULL) { /* only early beta cards had this problem */ sc_log(card->ctx, "***** received buffer tag MISSING "); @@ -3033,12 +3033,13 @@ static int piv_match_card_continued(sc_card_t *card) * 73 66 74 65 20 63 64 31 34 34 * will check for 73 66 74 65 */ - else if (card->reader->atr_info.hist_bytes_len >= 4 && - !(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) { + else if (card->reader->atr_info.hist_bytes_len >= 4 + && !(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) { type = SC_CARD_TYPE_PIV_II_GI_DE; } - else if (card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ + else if (card->reader->atr_info.hist_bytes_len > 0 + && card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ size_t datalen; const u8 *data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1, card->reader->atr_info.hist_bytes_len - 1, diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index a1efe22e8d..32932ae75a 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -275,7 +275,7 @@ static int rtecp_select_file(sc_card_t *card, set_acl_from_sec_attr(card, file); else r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - if (r) + if (r && !file_out) sc_file_free(file); else { diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index f6dc0c612c..98464c2e17 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -789,6 +789,8 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Check all sub-AC definitions within the total AC */ while (len > 1) { /* minimum length = 2 */ int iACLen = buf[iOffset] & 0x0F; + if ((size_t) iACLen > len) + break; iPinCount = -1; /* default no pin required */ iMethod = SC_AC_NONE; /* default no authentication required */ @@ -806,7 +808,10 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Get KeyNumber if available */ if(iKeyLen) { - int iSC = buf[iOffset+iACLen]; + int iSC; + if (len < 1+iACLen) + break; + iSC = buf[iOffset+iACLen]; switch( (iSC>>5) & 0x03 ){ case 0: @@ -825,11 +830,15 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Get PinNumber if available */ if (iACLen > (1+iParmLen+iKeyLen)) { /* check via total length if pin is present */ + if (len < 1+1+1+iParmLen) + break; iKeyRef = buf[iOffset+1+1+iParmLen]; /* PTL + AM-header + parameter-bytes */ iMethod = SC_AC_CHV; } /* Convert SETCOS command to OpenSC command group */ + if (len < 1+2) + break; switch(buf[iOffset+2]){ case 0x2A: /* crypto operation */ iOperation = SC_AC_OP_CRYPTO; @@ -863,7 +872,10 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) iPinCount = iACLen - 1; if (buf[iOffset] & 0x20) { - int iSC = buf[iOffset + iACLen]; + int iSC; + if (len < 1 + iACLen) + break; + iSC = buf[iOffset + iACLen]; switch( (iSC>>5) & 0x03 ) { case 0: @@ -884,6 +896,8 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Pin present ? */ if ( iPinCount > 0 ) { + if (len < 1 + 2) + break; iKeyRef = buf[iOffset + 2]; /* pin ref */ iMethod = SC_AC_CHV; } diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index 39dea2e502..7888fd4954 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -72,7 +72,7 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len, } p += tag_len; - left -= (p - gdo); + left = gdo_len - (p - gdo); } if (!iccsn_found && iccsn_len) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index eef8ac1f91..f0f3959092 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -550,6 +550,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Could not read EF_DatiPersonali: " "keeping generic card name"); + return SC_SUCCESS; } { diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 74bb32a6fd..7732ad08aa 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -132,7 +132,7 @@ static int insert_key( int i, rec_no=0; if(prkey_info.path.len>=2) prkey_info.path.len-=2; sc_append_file_id(&prkey_info.path, 0x5349); - if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS){ + if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS || !f->prop_attr){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select(%s) failed\n", sc_print_path(&prkey_info.path)); @@ -157,7 +157,8 @@ static int insert_key( if(buf[i]==0xB8) can_crypt++; } } else { - if(sc_select_file(card, &prkey_info.path, &f)!=SC_SUCCESS){ + if(sc_select_file(card, &prkey_info.path, &f)!=SC_SUCCESS + || !f->prop_attr || f->prop_attr_len < 2){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select(%s) failed\n", sc_print_path(&prkey_info.path)); @@ -245,7 +246,8 @@ static int insert_pin( return 1; } } else { - if(sc_select_file(card, &pin_info.path, &f)!=SC_SUCCESS){ + if(sc_select_file(card, &pin_info.path, &f)!=SC_SUCCESS + || !f->prop_attr || f->prop_attr_len < 4){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"Select(%s) failed\n", path); return 1; } diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 68c72805ea..2f121acf6a 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -457,7 +457,7 @@ static int enum_dir(sc_path_t path, int depth) { sc_file_t *file; int r, file_type; - u8 files[SC_MAX_APDU_BUFFER_SIZE]; + u8 files[SC_MAX_EXT_APDU_BUFFER_SIZE]; r = sc_lock(card); if (r == SC_SUCCESS) @@ -483,15 +483,16 @@ static int enum_dir(sc_path_t path, int depth) } if (r == 0) { printf("Empty directory\n"); - } else - for (i = 0; i < r/2; i++) { - sc_path_t tmppath; - - memset(&tmppath, 0, sizeof(tmppath)); - memcpy(&tmppath, &path, sizeof(path)); - memcpy(tmppath.value + tmppath.len, files + 2*i, 2); - tmppath.len += 2; - enum_dir(tmppath, depth + 1); + } else { + for (i = 0; i < r/2; i++) { + sc_path_t tmppath; + + memset(&tmppath, 0, sizeof(tmppath)); + memcpy(&tmppath, &path, sizeof(path)); + memcpy(tmppath.value + tmppath.len, files + 2*i, 2); + tmppath.len += 2; + enum_dir(tmppath, depth + 1); + } } } return 0; From 360e95d45ac4123255a4c796db96337f332160ad Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 May 2018 23:34:14 +0200 Subject: [PATCH 0435/4321] fixed out of bounds writes Thanks to Eric Sesterhenn from X41 D-SEC GmbH for reporting the problems. --- src/libopensc/card-cac.c | 2 +- src/libopensc/card-epass2003.c | 3 ++- src/libopensc/card-muscle.c | 7 +++++-- src/libopensc/card-tcos.c | 6 +++--- src/libopensc/pkcs15-esteid.c | 2 +- src/libopensc/pkcs15-gemsafeV1.c | 2 +- src/libopensc/pkcs15-sc-hsm.c | 14 ++++++++------ src/libopensc/sc.c | 2 +- src/tools/cryptoflex-tool.c | 5 +++-- src/tools/egk-tool.c | 2 +- src/tools/util.c | 5 +++-- 11 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index a30a04385f..756788a0fb 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -794,7 +794,7 @@ static int cac_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* seri } if (priv->cac_id_len) { serial->len = MIN(priv->cac_id_len, SC_MAX_SERIALNR); - memcpy(serial->value, priv->cac_id, priv->cac_id_len); + memcpy(serial->value, priv->cac_id, serial->len); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index cbe417cf78..65a58f6740 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -951,7 +951,7 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned while (0x80 != plaintext[cipher_len - 2] && (cipher_len - 2 > 0)) cipher_len--; - if (2 == cipher_len) + if (2 == cipher_len || *out_len < cipher_len - 2) return -1; memcpy(out, plaintext, cipher_len - 2); @@ -977,6 +977,7 @@ epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apd r = sc_check_sw(card, sm->sw1, sm->sw2); if (r == SC_SUCCESS) { if (exdata->sm) { + len = plain->resplen; if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len)) return SC_ERROR_CARD_CMD_FAILED; } diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index fd148e3039..d247efabc9 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -518,7 +518,9 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) mscfs_check_cache(priv->fs); for(x = 0; x < fs->cache.size; x++) { - u8* oid= fs->cache.array[x].objectId.id; + u8* oid = fs->cache.array[x].objectId.id; + if (bufLen < 2) + break; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "FILE: %02X%02X%02X%02X\n", oid[0],oid[1],oid[2],oid[3]); @@ -527,7 +529,8 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) buf[1] = oid[3]; if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */ buf += 2; - count+=2; + count += 2; + bufLen -= 2; } } return count; diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 40eac877de..3c86b1f483 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -408,7 +408,7 @@ static int tcos_select_file(sc_card_t *card, file->path = *in_path; for(i=2; i+1id = (d[0]<<8) | d[1]; break; case 0x84: - memcpy(file->name, d, len); - file->namelen = len; + file->namelen = MIN(sizeof file->name, len); + memcpy(file->name, d, file->namelen); break; case 0x86: sc_file_set_sec_attr(file, d, len); diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index b3cf5178fc..2b8d66b913 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -79,7 +79,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); - buff[r] = '\0'; + buff[MIN((size_t) r, (sizeof buff)-1)] = '\0'; set_string (&p15card->tokeninfo->serial_number, (const char *) buff); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index a8162b9d01..3b220f7a5b 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -208,7 +208,7 @@ static int gemsafe_get_cert_len(sc_card_t *card) * the private key. */ ind = 2; /* skip length */ - while (ibuf[ind] == 0x01) { + while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) { if (ibuf[ind+1] == 0xFE) { gemsafe_prkeys[i].ref = ibuf[ind+4]; sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d", diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 305572cb6c..1391bea153 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -837,12 +837,14 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1); LOG_TEST_RET(card->ctx, r, "Skipping optional EF.C_DevAut"); - /* save EF_C_DevAut for further use */ - ptr = realloc(priv->EF_C_DevAut, len); - if (ptr) { - memcpy(ptr, efbin, len); - priv->EF_C_DevAut = ptr; - priv->EF_C_DevAut_len = len; + if (len > 0) { + /* save EF_C_DevAut for further use */ + ptr = realloc(priv->EF_C_DevAut, len); + if (ptr) { + memcpy(ptr, efbin, len); + priv->EF_C_DevAut = ptr; + priv->EF_C_DevAut_len = len; + } } ptr = efbin; diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index af71cafa9b..53fefb3e68 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -628,7 +628,7 @@ int sc_file_set_sec_attr(sc_file_t *file, const u8 *sec_attr, return SC_ERROR_INVALID_ARGUMENTS; } - if (sec_attr == NULL) { + if (sec_attr == NULL || sec_attr_len) { if (file->sec_attr != NULL) free(file->sec_attr); file->sec_attr = NULL; diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 21b0baa16d..662a028222 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -21,6 +21,7 @@ #include "config.h" #include "libopensc/sc-ossl-compat.h" +#include "libopensc/internal.h" #include #include #include @@ -331,7 +332,7 @@ static int read_public_key(RSA *rsa) fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r)); return 2; } - bufsize = file->size; + bufsize = MIN(file->size, sizeof buf); sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); if (r < 0) { @@ -382,7 +383,7 @@ static int read_private_key(RSA *rsa) e = sc_file_get_acl_entry(file, SC_AC_OP_READ); if (e == NULL || e->method == SC_AC_NEVER) return 10; - bufsize = file->size; + bufsize = MIN(file->size, sizeof buf); sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); if (r < 0) { diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index 0a8834b6f7..31360833b5 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -149,7 +149,7 @@ int read_file(struct sc_card *card, char *str_path, unsigned char **data, size_t goto err; } - len = file ? file->size : 4096; + len = file && file->size > 0 ? file->size : 4096; p = realloc(*data, len); if (!p) { goto err; diff --git a/src/tools/util.c b/src/tools/util.c index 6b8743e2d0..e49647a472 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -339,10 +339,11 @@ const char * util_acl_to_str(const sc_acl_entry_t *e) strcpy(buf, "????"); break; } - strcat(line, buf); - strcat(line, " "); + strncat(line, buf, sizeof line); + strncat(line, " ", sizeof line); e = e->next; } + line[(sizeof line)-1] = '\0'; /* make sure it's NUL terminated */ line[strlen(line)-1] = 0; /* get rid of trailing space */ return line; } From ffe38fd87fc06879924759ca2e25eabb47ed6f0d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 27 May 2018 00:14:01 +0200 Subject: [PATCH 0436/4321] sc_asn1_read_tag: fixed tracking of consumed bytes fixes return buffers that are outside the allocated memory space --- src/libopensc/asn1.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index e43c0f1362..3262ed8026 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -65,15 +65,17 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, size_t left = buflen, len; unsigned int cla, tag, i; - if (left < 2) - return SC_ERROR_INVALID_ASN1_OBJECT; *buf = NULL; + + if (left == 0) + return SC_ERROR_INVALID_ASN1_OBJECT; if (*p == 0xff || *p == 0) { /* end of data reached */ *taglen = 0; *tag_out = SC_ASN1_TAG_EOC; return SC_SUCCESS; } + /* parse tag byte(s) * Resulted tag is presented by integer that has not to be * confused with the 'tag number' part of ASN.1 tag. @@ -86,31 +88,35 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, /* high tag number */ size_t n = SC_ASN1_TAGNUM_SIZE - 1; /* search the last tag octet */ - while (left-- != 0 && n != 0) { + do { + if (left == 0 || n == 0) + /* either an invalid tag or it doesn't fit in + * unsigned int */ + return SC_ERROR_INVALID_ASN1_OBJECT; tag <<= 8; tag |= *p; - if ((*p++ & 0x80) == 0) - break; + p++; + left--; n--; - } - if (left == 0 || n == 0) - /* either an invalid tag or it doesn't fit in - * unsigned int */ - return SC_ERROR_INVALID_ASN1_OBJECT; + } while (tag & 0x80); } /* parse length byte(s) */ - len = *p & 0x7f; - if (*p++ & 0x80) { + if (left == 0) + return SC_ERROR_INVALID_ASN1_OBJECT; + len = *p; + p++; + left--; + if (len & 0x80) { + len &= 0x7f; unsigned int a = 0; - left--; - if (len > 4 || len > left) + if (len > sizeof a || len > left) return SC_ERROR_INVALID_ASN1_OBJECT; - left -= len; for (i = 0; i < len; i++) { a <<= 8; a |= *p; p++; + left--; } len = a; } From 83f45cda2af16b65264103fbe0394fd422f0120d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 27 May 2018 00:38:37 +0200 Subject: [PATCH 0437/4321] Added bounds checking to sc_simpletlv_read_tag() - Logic is identical to sc_asn1_read_tag() - Fixes out of bounds access e.g. in cac_parse_CCC --- src/libopensc/card-setcos.c | 14 +++++++------- src/libopensc/errors.c | 2 ++ src/libopensc/errors.h | 2 ++ src/libopensc/simpletlv.c | 31 +++++++++++++++++++++---------- src/tools/util.c | 5 +++-- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 98464c2e17..a8ca012fa7 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -788,8 +788,8 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Check all sub-AC definitions within the total AC */ while (len > 1) { /* minimum length = 2 */ - int iACLen = buf[iOffset] & 0x0F; - if ((size_t) iACLen > len) + size_t iACLen = buf[iOffset] & 0x0F; + if (iACLen > len) break; iPinCount = -1; /* default no pin required */ @@ -797,8 +797,8 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) if (buf[iOffset] & 0X80) { /* AC in adaptive coding */ /* Evaluates only the command-byte, not the optional P1/P2/Option bytes */ - int iParmLen = 1; /* command-byte is always present */ - int iKeyLen = 0; /* Encryption key is optional */ + size_t iParmLen = 1; /* command-byte is always present */ + size_t iKeyLen = 0; /* Encryption key is optional */ if (buf[iOffset] & 0x20) iKeyLen++; if (buf[iOffset+1] & 0x40) iParmLen++; @@ -809,7 +809,7 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Get KeyNumber if available */ if(iKeyLen) { int iSC; - if (len < 1+iACLen) + if (len < 1+(size_t)iACLen) break; iSC = buf[iOffset+iACLen]; @@ -830,7 +830,7 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) /* Get PinNumber if available */ if (iACLen > (1+iParmLen+iKeyLen)) { /* check via total length if pin is present */ - if (len < 1+1+1+iParmLen) + if (len < 1+1+1+(size_t)iParmLen) break; iKeyRef = buf[iOffset+1+1+iParmLen]; /* PTL + AM-header + parameter-bytes */ iMethod = SC_AC_CHV; @@ -873,7 +873,7 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) if (buf[iOffset] & 0x20) { int iSC; - if (len < 1 + iACLen) + if (len < 1 + (size_t)iACLen) break; iSC = buf[iOffset + iACLen]; diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index b6c6eb4810..354e0a6e3c 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -104,6 +104,8 @@ const char *sc_strerror(int error) "Unable to load external module", "EF offset too large", "Not implemented" + "Invalid Simple TLV object", + "Premature end of Simple TLV stream", }; const int int_base = -SC_ERROR_INTERNAL; diff --git a/src/libopensc/errors.h b/src/libopensc/errors.h index 183b0758d3..e0330a9324 100644 --- a/src/libopensc/errors.h +++ b/src/libopensc/errors.h @@ -95,6 +95,8 @@ extern "C" { #define SC_ERROR_CANNOT_LOAD_MODULE -1414 #define SC_ERROR_OFFSET_TOO_LARGE -1415 #define SC_ERROR_NOT_IMPLEMENTED -1416 +#define SC_ERROR_INVALID_TLV_OBJECT -1417 +#define SC_ERROR_TLV_END_OF_CONTENTS -1418 /* Relating to PKCS #15 init stuff */ #define SC_ERROR_PKCS15INIT -1500 diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c index ab0401b5e7..67a08da232 100644 --- a/src/libopensc/simpletlv.c +++ b/src/libopensc/simpletlv.c @@ -74,27 +74,38 @@ sc_simpletlv_put_tag(u8 tag, size_t datalen, u8 *out, size_t outlen, u8 **ptr) int sc_simpletlv_read_tag(u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen) { - size_t len; + u8 tag; + size_t left = buflen, len; u8 *p = *buf; - if (buflen < 2) { - *buf = p+buflen; - return SC_ERROR_INVALID_ARGUMENTS; + *buf = NULL; + + if (left < 2) { + return SC_ERROR_INVALID_TLV_OBJECT; } + tag = *p; + p++; + len = *p; + p++; + left -= 2; - *tag_out = *p++; - len = *p++; if (len == 0xff) { /* don't crash on bad data */ - if (buflen < 4) { - *taglen = 0; - return SC_ERROR_INVALID_ARGUMENTS; + if (left < 2) { + return SC_ERROR_INVALID_TLV_OBJECT; } /* skip two bytes (the size) */ len = lebytes2ushort(p); - p+=2; + p += 2; + left -= 2; } + + *tag_out = tag; *taglen = len; *buf = p; + + if (len > left) + return SC_ERROR_TLV_END_OF_CONTENTS; + return SC_SUCCESS; } diff --git a/src/tools/util.c b/src/tools/util.c index e49647a472..a3cbff7a79 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -31,6 +31,7 @@ #include #include "util.h" #include "ui/notify.h" +#include "common/compat_strlcat.h" int is_string_valid_atr(const char *atr_str) @@ -339,8 +340,8 @@ const char * util_acl_to_str(const sc_acl_entry_t *e) strcpy(buf, "????"); break; } - strncat(line, buf, sizeof line); - strncat(line, " ", sizeof line); + strlcat(line, buf, sizeof line); + strlcat(line, " ", sizeof line); e = e->next; } line[(sizeof line)-1] = '\0'; /* make sure it's NUL terminated */ From d5d15105dd4cc91e54c86efbd75f07c6f21bb281 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Jun 2018 14:54:31 +0200 Subject: [PATCH 0438/4321] cac: Ignore end of content errors (#7) The CAC buffers are split to separate TL and V buffers so we need to ignore this error --- src/libopensc/card-cac.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 756788a0fb..a42df9288a 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -637,7 +637,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) { /* get the tag and the length */ tl_start = tl_ptr; - if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS) + r = sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len); + if (r != SC_SUCCESS && r != SC_ERROR_TLV_END_OF_CONTENTS) break; tl_head_len = (tl_ptr - tl_start); sc_simpletlv_put_tag(tag, len, tlv_ptr, tlv_len, &tlv_ptr); @@ -646,6 +647,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* don't crash on bad data */ if (val_len < len) { + sc_log(card->ctx, "Received too long value %"SC_FORMAT_LEN_SIZE_T"u, " + "while only %"SC_FORMAT_LEN_SIZE_T"u left. Truncating", len, val_len); len = val_len; } /* if we run out of return space, truncate */ @@ -667,13 +670,17 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, for (tl_ptr = tl, val_ptr = val; tl_len >= 2; val_len -= len, val_ptr += len, tl_len -= tl_head_len) { tl_start = tl_ptr; - if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS) + r = sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len); + if (r != SC_SUCCESS && r != SC_ERROR_TLV_END_OF_CONTENTS) break; tl_head_len = tl_ptr - tl_start; /* incomplete value */ - if (val_len < len) + if (val_len < len) { + sc_log(card->ctx, "Read incomplete value %"SC_FORMAT_LEN_SIZE_T"u, " + "while only %"SC_FORMAT_LEN_SIZE_T"u left", len, val_len); break; + } if (tag == CAC_TAG_CERTIFICATE) { cert_len = len; @@ -687,9 +694,6 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, if (tag == CAC_TAG_MSCUID) { sc_log_hex(card->ctx, "MSCUID", val_ptr, len); } - if ((val_len < len) || (tl_len < tl_head_len)) { - break; - } } /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { From 3e5a9a42c355f4ef64c40347d9046d0e063e589b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Jun 2018 19:50:31 -0500 Subject: [PATCH 0439/4321] Remove in PIV driver need for aid_file Remove aid_file and aidfile variables in card-piv.c. These are not needed as piv_select_aid parses the returned data from a SELECT AID command. In response to e-mail from X41 group on 6/11/2018. On branch x41-piv-2 Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 0cd3f5ad99..bfc595960d 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -147,7 +147,6 @@ enum { }; typedef struct piv_private_data { - sc_file_t *aid_file; int enumtag; int selected_obj; /* The index into the piv_objects last selected */ int return_only_cert; /* return the cert from the object */ @@ -758,10 +757,9 @@ static int piv_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, /* find the PIV AID on the card. If card->type already filled in, * then look for specific AID only - * Assumes that priv may not be present */ -static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file) +static int piv_find_aid(sc_card_t * card) { sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; @@ -842,8 +840,6 @@ static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file) if (apdu.resp[0] != 0x6f || apdu.resp[1] > apdu.resplen - 2 ) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); - card->ops->process_fci(card, aid_file, apdu.resp+2, apdu.resp[1]); - LOG_FUNC_RETURN(card->ctx, i); } @@ -2924,7 +2920,6 @@ piv_finish(sc_card_t *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (priv) { - sc_file_free(priv->aid_file); if (priv->w_buf) free(priv->w_buf); if (priv->offCardCertURL) @@ -3073,7 +3068,6 @@ static int piv_match_card_continued(sc_card_t *card) card->type = type; card->drv_data = priv; /* will free if no match, or pass on to piv_init */ - priv->aid_file = sc_file_new(); priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ priv->logged_in = SC_PIN_STATE_UNKNOWN; @@ -3100,9 +3094,7 @@ static int piv_match_card_continued(sc_card_t *card) if (i < 0) { /* Detect by selecting applet */ - sc_file_t aidfile; - - i = piv_find_aid(card, &aidfile); + i = piv_find_aid(card); } if (i >= 0) { @@ -3488,7 +3480,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) /* if access to applet is know to be reset by other driver we select_aid and try again */ if ( priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) { sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd"); - piv_find_aid(card, priv->aid_file); /* return not tested */ + piv_find_aid(card); priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ r = iso_drv->ops->pin_cmd(card, data, tries_left); From 384626533e3596f796f860a37ebb72e093939c41 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 3 Jun 2018 14:39:40 -0500 Subject: [PATCH 0440/4321] PIV Security Changes Add return code if "out" is smaller then received data. Remove extra blanks. --- src/libopensc/card-piv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index bfc595960d..324f3aecdc 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2369,15 +2369,15 @@ static int piv_validate_general_authentication(sc_card_t *card, r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref, sbuf, p - sbuf, &rbuf, &rbuflen); - if ( r >= 0) { - body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7c, &bodylen); - + if (r >= 0) { + body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7c, &bodylen); if (body) { tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &taglen); if (tag) { memcpy(out, tag, taglen); r = taglen; - } + } else + r = SC_ERROR_INVALID_DATA; } else r = SC_ERROR_INVALID_DATA; } From 5807368ed44a6feb78e6107eaa2f337d474a8d36 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 18 Jun 2018 15:23:46 +0200 Subject: [PATCH 0441/4321] fixed bad memory access --- src/libopensc/card-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index a42df9288a..4e971eedba 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1390,9 +1390,9 @@ static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_ } sc_mem_clear(path, sizeof(sc_path_t)); memcpy(path->aid.value, &val->rid, sizeof(val->rid)); - memcpy(&path->aid.value[5], &val->applicationID, sizeof(val->applicationID)); + memcpy(&path->aid.value[5], val->applicationID, sizeof(val->applicationID)); path->aid.len = sizeof(val->rid) + sizeof(val->applicationID); - memcpy(path->value, &val->objectID, sizeof(val->objectID)); + memcpy(path->value, val->objectID, sizeof(val->objectID)); path->len = sizeof(val->objectID); path->type = SC_PATH_TYPE_FILE_ID; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, From 03628449b75a93787eb2359412a3980365dda49b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 29 Jun 2018 15:58:00 +0200 Subject: [PATCH 0442/4321] iasecc: fixed unbound recursion --- src/libopensc/card-iasecc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 48d4cea560..b37b833b77 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -827,16 +827,16 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, sc_log(ctx, "iasecc_select_file() path:%s", sc_print_path(path)); sc_print_cache(card); - if (lpath.len >= 2 && lpath.value[0] == 0x3F && lpath.value[1] == 0x00) { + if (path->type != SC_PATH_TYPE_DF_NAME + && lpath.len >= 2 + && lpath.value[0] == 0x3F && lpath.value[1] == 0x00) { sc_log(ctx, "EF.ATR(aid:'%s')", card->ef_atr ? sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len) : ""); rv = iasecc_select_mf(card, file_out); LOG_TEST_RET(ctx, rv, "MF selection error"); - if (lpath.len >= 2 && lpath.value[0] == 0x3F && lpath.value[1] == 0x00) { - memmove(&lpath.value[0], &lpath.value[2], lpath.len - 2); - lpath.len -= 2; - } + memmove(&lpath.value[0], &lpath.value[2], lpath.len - 2); + lpath.len -= 2; } if (lpath.aid.len) { From 78f005533818e5920a563bb5949c1a647d786090 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 2 Jul 2018 09:53:35 +0200 Subject: [PATCH 0443/4321] fixed uninitialized use of variable --- src/libopensc/pkcs15-tcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 7732ad08aa..547de12aee 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -132,7 +132,7 @@ static int insert_key( int i, rec_no=0; if(prkey_info.path.len>=2) prkey_info.path.len-=2; sc_append_file_id(&prkey_info.path, 0x5349); - if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS || !f->prop_attr){ + if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select(%s) failed\n", sc_print_path(&prkey_info.path)); From 92a98cb3bb1719b0100b033aae1c3c1f2679e7c8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 2 Jul 2018 10:07:53 +0200 Subject: [PATCH 0444/4321] mcrd: converted assert to proper error handling --- src/libopensc/card-mcrd.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 16cb999222..52dd457d24 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -149,7 +149,8 @@ static struct df_info_s *get_df_info(sc_card_t * card) struct mcrd_priv_data *priv = DRVDATA(card); struct df_info_s *dfi; - assert(!priv->is_ef); + if(!(!priv->is_ef)) + return NULL; if (!priv->curpathlen) { sc_log(ctx, "no current path to find the df_info\n"); @@ -202,7 +203,8 @@ static int mcrd_delete_ref_to_authkey(sc_card_t * card) int r; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - assert(card != NULL); + if(!(card != NULL)) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xA4); sbuf[0] = 0x83; @@ -220,7 +222,8 @@ static int mcrd_delete_ref_to_signkey(sc_card_t * card) sc_apdu_t apdu; int r; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - assert(card != NULL); + if(!(card != NULL)) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); @@ -242,7 +245,8 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) int r; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 keyref_data[SC_ESTEID_KEYREF_FILE_RECLEN]; - assert(card != NULL); + if(!(card != NULL)) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); /* track the active keypair */ @@ -956,7 +960,8 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(!priv->curpathlen || priv->curpath[0] == MFID); + if (!(!priv->curpathlen || priv->curpath[0] == MFID)) + return SC_ERROR_INTERNAL; if (pathlen && *pathptr == 0x3FFF) { pathlen--; @@ -997,7 +1002,8 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, /* This EF or DF was already selected, but we need to get the FCI, so we have to select again. */ - assert(priv->curpathlen > 1); + if (!(priv->curpathlen > 1)) + return SC_ERROR_INTERNAL; priv->curpathlen--; priv->is_ef = 0; r = select_down(card, pathptr + pathlen - 1, 1, @@ -1022,7 +1028,8 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, priv->is_ef = 0; } if (priv->is_ef) { - assert(priv->curpathlen > 1); + if(!(priv->curpathlen > 1)) + return SC_ERROR_INTERNAL; priv->curpathlen--; priv->is_ef = 0; } @@ -1040,7 +1047,8 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(!priv->curpathlen || priv->curpath[0] == MFID); + if (!(!priv->curpathlen || priv->curpath[0] == MFID)) + return SC_ERROR_INTERNAL; if (pathlen > 1) return SC_ERROR_INVALID_ARGUMENTS; @@ -1056,7 +1064,8 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr, /* There is no current file. */ r = SC_ERROR_INTERNAL; } else { - assert(priv->curpathlen > 1); + if (!(priv->curpathlen > 1)) + return SC_ERROR_INTERNAL; priv->curpathlen--; priv->is_ef = 0; r = select_down(card, pathptr, 1, 0, file); @@ -1081,7 +1090,8 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr, priv->is_ef = 0; } if (priv->is_ef) { - assert(priv->curpathlen > 1); + if (!(priv->curpathlen > 1)) + return SC_ERROR_INTERNAL; priv->curpathlen--; priv->is_ef = 0; } @@ -1209,7 +1219,8 @@ static int mcrd_set_security_env(sc_card_t * card, u8 *p; int r, locked = 0; - assert(card != NULL && env != NULL); + if (!(card != NULL && env != NULL)) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); /* special environment handling for esteid, stolen from openpgp */ From 30fe0ad453caa34d5851cf36d3e459133dcadd3b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 3 Jul 2018 09:36:21 +0200 Subject: [PATCH 0445/4321] pgp: fixed integer underflow --- src/libopensc/card-openpgp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5fa3899227..59cf41e70d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -623,13 +623,19 @@ pgp_get_card_features(sc_card_t *card) /* category indicator 0x00, 0x10 or 0x80 => compact TLV (ISO) */ switch (hist_bytes[0]) { case 0x00: - pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + if (hist_bytes_len > 4) { + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + } break; case 0x80: - pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-1); + if (hist_bytes_len > 1) { + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-1); + } break; case 0x10: - pgp_parse_hist_bytes(card, hist_bytes+2, hist_bytes_len-2); + if (hist_bytes_len > 2) { + pgp_parse_hist_bytes(card, hist_bytes+2, hist_bytes_len-2); + } break; } } @@ -642,7 +648,9 @@ pgp_get_card_features(sc_card_t *card) if ((pgp_get_blob(card, priv->mf, 0x5f52, &blob) >= 0) && (blob->data != NULL) && (blob->data[0] == 0x00)) { - pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + if (hist_bytes_len > 4) { + pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + } /* get card status from historical bytes status indicator */ if ((blob->data[0] == 0x00) && (blob->len >= 4)) { From 0b44793900ee9ad72909242da761702e23b12167 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Jul 2018 17:51:35 +0200 Subject: [PATCH 0446/4321] tcos: use ISO7816 fci parser --- src/libopensc/card-tcos.c | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 3c86b1f483..0fad1e1509 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -343,7 +343,6 @@ static int tcos_select_file(sc_card_t *card, sc_apdu_t apdu; sc_file_t *file=NULL; u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - unsigned int i; int r, pathlen; assert(card != NULL && in_path != NULL); @@ -407,42 +406,7 @@ static int tcos_select_file(sc_card_t *card, *file_out = file; file->path = *in_path; - for(i=2; i+1size=0; - for(j=0; jsize = (file->size<<8) | d[j]; - break; - case 0x82: - file->shareable = (d[0] & 0x40) ? 1 : 0; - file->ef_structure = d[0] & 7; - switch ((d[0]>>3) & 7) { - case 0: file->type = SC_FILE_TYPE_WORKING_EF; break; - case 7: file->type = SC_FILE_TYPE_DF; break; - default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid file type %02X in file descriptor\n", d[0]); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED); - } - break; - case 0x83: - file->id = (d[0]<<8) | d[1]; - break; - case 0x84: - file->namelen = MIN(sizeof file->name, len); - memcpy(file->name, d, file->namelen); - break; - case 0x86: - sc_file_set_sec_attr(file, d, len); - break; - default: - if (len>0) sc_file_set_prop_attr(file, d, len); - } - } - file->magic = SC_FILE_MAGIC; + iso_ops->process_fci(card, file, apdu.resp, apdu.resplen); parse_sec_attr(card, file, file->sec_attr, file->sec_attr_len); From 50b000047c44b1f2c6f0134094c19519d512e5b6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Jul 2018 17:51:53 +0200 Subject: [PATCH 0447/4321] ias/ecc: disable iccsn parsing if someone wants to implement this with memory bounds checking, please raise your hands --- src/libopensc/card-iasecc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index b37b833b77..a817c99e8c 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -2504,6 +2504,12 @@ iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_le static int iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) { +#if 1 + /* the current implementation doesn't perform any bounds check when parsing + * the serial number. Hence, we disable this code until someone has time to + * fix this. */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +#else struct sc_context *ctx = card->ctx; struct sc_iin *iin = &card->serialnr.iin; struct sc_apdu apdu; @@ -2573,6 +2579,7 @@ iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) memcpy(serial, &card->serialnr, sizeof(*serial)); LOG_FUNC_RETURN(ctx, SC_SUCCESS); +#endif } From 79c0dbaa4e47ad8d9d43b327f5cc34c2f31dd873 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 9 Jul 2018 14:13:41 +0200 Subject: [PATCH 0448/4321] cac: Avoid OOB reads for inconsistent TLV structures --- src/libopensc/card-cac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 4e971eedba..eeab07e4fe 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1555,8 +1555,15 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, for (; (tl < tl_end) && (val< val_end); val += len) { /* get the tag and the length */ u8 tag; - if (sc_simpletlv_read_tag(&tl, tl_end - tl, &tag, &len) != SC_SUCCESS) + r = sc_simpletlv_read_tag(&tl, tl_end - tl, &tag, &len); + if (r != SC_SUCCESS && r != SC_ERROR_TLV_END_OF_CONTENTS) { + sc_log(card->ctx, "Failed to parse tag from buffer"); break; + } + if (val + len > val_end) { + sc_log(card->ctx, "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } switch (tag) { case CAC_TAG_CUID: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:CUID"); From 5ec26573da7e6f21364d40c5c74962ef60a07000 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Aug 2018 16:12:38 +0200 Subject: [PATCH 0449/4321] coolkey: Do not overflow allocated buffer --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 3c57628b0b..b97559cc38 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1129,7 +1129,7 @@ static int coolkey_read_object(sc_card_t *card, unsigned long object_id, size_t do { ulong2bebytes(¶ms.offset[0], offset); params.length = MIN(left, COOLKEY_MAX_CHUNK_SIZE); - len = left+2; + len = left; r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_READ_OBJECT, 0, 0, (u8 *)¶ms, sizeof(params), &out_ptr, &len, nonce, nonce_size); if (r < 0) { From 48d30ac7da99251c10c89de8b49e801f0a7522dd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Aug 2018 11:54:23 +0200 Subject: [PATCH 0450/4321] Don't overwrite existing opensc.conf fixes https://github.com/OpenSC/OpenSC/issues/1449 partially reverts c003f3825e5217cd3ef8272f4e8ebe47270a7847 --- etc/Makefile.am | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/etc/Makefile.am b/etc/Makefile.am index 3add83b2c2..cc368b6cc3 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -7,9 +7,8 @@ EXTRA_DIST = $(CV_CERTS) Makefile.mak SUFFIXES = .in -dist_noinst_DATA = opensc.conf.example.in +dist_noinst_DATA = opensc.conf opensc.conf.example.in nodist_noinst_DATA = opensc.conf.example -dist_sysconf_DATA = opensc.conf # Make sure we build this every time # as there is no dependency for this. @@ -32,10 +31,17 @@ opensc.conf.example: opensc.conf.example.in force < $< > $@ install-exec-hook: opensc.conf.example + $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" + if [ -f "$(DESTDIR)$(sysconfdir)/opensc.conf" ]; then \ + $(INSTALL_DATA) $(srcdir)/opensc.conf "$(DESTDIR)$(sysconfdir)/opensc.conf.new"; \ + else \ + $(INSTALL_DATA) $(srcdir)/opensc.conf "$(DESTDIR)$(sysconfdir)/opensc.conf"; \ + fi $(MKDIR_P) "$(DESTDIR)$(docdir)" $(INSTALL_DATA) opensc.conf.example "$(DESTDIR)$(docdir)/opensc.conf"; uninstall-hook: opensc.conf.example + rm -f "$(DESTDIR)$(sysconfdir)/opensc.conf.new" "$(DESTDIR)$(sysconfdir)/opensc.conf" rm -f "$(DESTDIR)$(docdir)/opensc.conf" if ENABLE_OPENPACE From 59d634e9e82daca8f39e61d61357d0995fb34e9a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Aug 2018 12:01:11 +0200 Subject: [PATCH 0451/4321] fixed low privilege `make distcheck` regression of b0a20fa7ca30dc6c6198954fadc5a7fe812834dc --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index 3350b566dc..a09d5a152c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,6 +13,8 @@ MAINTAINERCLEANFILES = \ $(srcdir)/packaged EXTRA_DIST = Makefile.mak +DISTCHECK_CONFIGURE_FLAGS = --with-completiondir=/tmp + SUBDIRS = etc src win32 doc MacOSX dist_noinst_SCRIPTS = bootstrap bootstrap.ci From fcf00e66cd5da51e2631b5df6c2312895fadcfdb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Aug 2018 14:27:02 +0200 Subject: [PATCH 0452/4321] Starcos: added ATR for 2nd gen. eGK fixes https://github.com/OpenSC/OpenSC/issues/1451 --- src/libopensc/card-starcos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 3be53dd151..8b4b2eb977 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -36,6 +36,7 @@ static struct sc_atr_table starcos_atrs[] = { { "3B:B7:94:00:81:31:fe:65:53:50:4b:32:33:90:00:d1", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3b:b7:18:00:c0:3e:31:fe:65:53:50:4b:32:34:90:00:25", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3b:d8:18:ff:81:b1:fe:45:1f:03:80:64:04:1a:b4:03:81:05:61", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, + { "3b:d3:96:ff:81:b1:fe:45:1f:07:80:81:05:2d", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, { "3B:9B:96:C0:0A:31:FE:45:80:67:04:1E:B5:01:00:89:4C:81:05:45", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:DB:96:FF:81:31:FE:45:80:67:05:34:B5:02:01:C0:A1:81:05:3C", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:C0:81:05:02", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, From ff8ec86f26fb64f2e1109157fb799652b9bd0d8a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Aug 2018 14:37:20 +0200 Subject: [PATCH 0453/4321] avoid looping forever in GET CHALLENGE fixes https://github.com/OpenSC/OpenSC/issues/1440 --- src/libopensc/card.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index aeba79accb..73532cc49d 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -818,6 +818,7 @@ int sc_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t len) int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { int r; + size_t retry = 10; if (len == 0) return SC_SUCCESS; @@ -835,15 +836,19 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) if (r != SC_SUCCESS) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); - while (len > 0) { + while (len > 0 && retry > 0) { r = card->ops->get_challenge(card, rnd, len); if (r < 0) { sc_unlock(card); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } - rnd += (size_t) r; - len -= (size_t) r; + if (r > 0) { + rnd += (size_t) r; + len -= (size_t) r; + } else { + retry--; + } } sc_unlock(card); From 2eae5e70f5c2daeab1926141f5078d1405776650 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 22 Aug 2018 17:54:42 +0300 Subject: [PATCH 0454/4321] Mark atr table argument as const in match_atr_table and _sc_match_atr functions This allows us to mark driver-specific atr tables as constants. --- src/libopensc/card.c | 4 ++-- src/libopensc/internal.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 73532cc49d..b4ab23954b 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1070,7 +1070,7 @@ sc_algorithm_info_t * sc_card_find_gostr3410_alg(sc_card_t *card, return sc_card_find_alg(card, SC_ALGORITHM_GOSTR3410, key_length, NULL); } -static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, struct sc_atr *atr) +static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, struct sc_atr *atr) { u8 *card_atr_bin; size_t card_atr_bin_len; @@ -1133,7 +1133,7 @@ static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, struct return -1; } -int _sc_match_atr(sc_card_t *card, struct sc_atr_table *table, int *type_out) +int _sc_match_atr(sc_card_t *card, const struct sc_atr_table *table, int *type_out) { int res; diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 33f64cfeda..9d6a77ffe4 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -125,7 +125,7 @@ scconf_block *_sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driv /* Returns an index number if a match was found, -1 otherwise. table has to * be null terminated. */ -int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *type_out); +int _sc_match_atr(struct sc_card *card, const struct sc_atr_table *table, int *type_out); int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info); int _sc_card_add_symmetric_alg(sc_card_t *card, unsigned int algorithm, From 45f407c02112ce4bd9d5c1c071e7b5fdd4f009ef Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 22 Aug 2018 18:01:51 +0300 Subject: [PATCH 0455/4321] Mark driver-specific global sc_atr_table structures as const As most of the drivers do not modify these, we can mark them as const. Two drivers that we cannot convert are dnie and masktech. section size .data 35232 -> 25472 .data.rel.ro 36928 -> 46688 --- src/libopensc/card-acos5.c | 2 +- src/libopensc/card-akis.c | 2 +- src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-belpic.c | 2 +- src/libopensc/card-cardos.c | 2 +- src/libopensc/card-dnie.c | 2 +- src/libopensc/card-entersafe.c | 2 +- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-flex.c | 2 +- src/libopensc/card-gemsafeV1.c | 2 +- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-incrypto34.c | 2 +- src/libopensc/card-itacns.c | 2 +- src/libopensc/card-jcop.c | 2 +- src/libopensc/card-jpki.c | 2 +- src/libopensc/card-mcrd.c | 2 +- src/libopensc/card-miocos.c | 2 +- src/libopensc/card-muscle.c | 2 +- src/libopensc/card-oberthur.c | 2 +- src/libopensc/card-openpgp.c | 2 +- src/libopensc/card-rtecp.c | 2 +- src/libopensc/card-rutoken.c | 2 +- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/card-setcos.c | 2 +- src/libopensc/card-starcos.c | 2 +- src/libopensc/card-tcos.c | 2 +- src/libopensc/card-westcos.c | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/libopensc/card-acos5.c b/src/libopensc/card-acos5.c index 64b1ad774f..a77ed0c6d5 100644 --- a/src/libopensc/card-acos5.c +++ b/src/libopensc/card-acos5.c @@ -27,7 +27,7 @@ #include "internal.h" #include "cardctl.h" -static struct sc_atr_table acos5_atrs[] = { +static const struct sc_atr_table acos5_atrs[] = { {"3b:be:96:00:00:41:05:20:00:00:00:00:00:00:00:00:00:90:00", NULL, NULL, SC_CARD_TYPE_ACOS5_GENERIC, 0, NULL}, {"3b:be:18:00:00:41:05:10:00:00:00:00:00:00:00:00:00:90:00", NULL, NULL, diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index c84e5513e9..747d83eb27 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -43,7 +43,7 @@ static struct sc_card_driver akis_drv = { NULL, 0, NULL }; -static struct sc_atr_table akis_atrs[] = { +static const struct sc_atr_table akis_atrs[] = { { "3b:ba:11:00:81:31:fe:4d:55:45:4b:41:45:20:56:31:2e:30:ae", NULL, NULL, SC_CARD_TYPE_AKIS_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 5459d98f1b..bac86e2da7 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -37,7 +37,7 @@ static struct sc_card_driver asepcos_drv = { NULL, 0, NULL }; -static struct sc_atr_table asepcos_atrs[] = { +static const struct sc_atr_table asepcos_atrs[] = { { "3b:d6:18:00:81:b1:80:7d:1f:03:80:51:00:61:10:30:8f", NULL, NULL, SC_CARD_TYPE_ASEPCOS_GENERIC, 0, NULL}, { "3b:d6:18:00:81:b1:fe:7d:1f:03:41:53:45:37:35:35:01", NULL, NULL, SC_CARD_TYPE_ASEPCOS_JAVA, 0, NULL}, { NULL, NULL, NULL, 0, 0, NULL } diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 9fbda94a3c..29a94382a9 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -80,7 +80,7 @@ struct authentic_private_data { struct sc_cplc cplc; }; -static struct sc_atr_table authentic_known_atrs[] = { +static const struct sc_atr_table authentic_known_atrs[] = { { "3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B", NULL, "Oberthur AuthentIC 3.2.2", SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 15b8a7b7bf..ccbca50d35 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -145,7 +145,7 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur; /* Used for a trick in select file and read binary */ static size_t next_idx = (size_t)-1; -static struct sc_atr_table belpic_atrs[] = { +static const struct sc_atr_table belpic_atrs[] = { /* Applet V1.1 */ { "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, /* Applet V1.0 with new EMV-compatible ATR */ diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 237688de67..48625923a2 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -42,7 +42,7 @@ static struct sc_card_driver cardos_drv = { NULL, 0, NULL }; -static struct sc_atr_table cardos_atrs[] = { +static const struct sc_atr_table cardos_atrs[] = { /* 4.0 */ { "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, /* Italian eID card, postecert */ diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index a47b5f0d52..2b62e23db2 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -78,7 +78,7 @@ extern int dnie_read_file( * Override APDU response error codes from iso7816.c to allow * handling of SM specific error */ -static struct sc_card_error dnie_errors[] = { +static const struct sc_card_error dnie_errors[] = { {0x6688, SC_ERROR_SM, "Cryptographic checksum invalid"}, {0x6987, SC_ERROR_SM, "Expected SM Data Object missing"}, {0x6988, SC_ERROR_SM, "SM Data Object incorrect"}, diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 828b03051b..3e42c11f87 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -30,7 +30,7 @@ #include "asn1.h" #include "cardctl.h" -static struct sc_atr_table entersafe_atrs[] = { +static const struct sc_atr_table entersafe_atrs[] = { { "3b:0f:00:65:46:53:05:19:05:71:df:00:00:00:00:00:00", "ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:00:00:00:00:00:00", diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 65a58f6740..49b593f9ec 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -46,7 +46,7 @@ #include "asn1.h" #include "cardctl.h" -static struct sc_atr_table epass2003_atrs[] = { +static const struct sc_atr_table epass2003_atrs[] = { /* This is a FIPS certified card using SCP01 security messaging. */ {"3B:9F:95:81:31:FE:9F:00:66:46:53:05:10:00:11:71:df:00:00:00:6a:82:5e", "FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:ff:00:ff:ff:00:00:00:00", diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index ac7a5703e2..da7ba7ca36 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -31,7 +31,7 @@ #define FLAG_KEYGEN 0x80000000 #define IS_CYBERFLEX(card) (card->type == SC_CARD_TYPE_FLEX_CYBER) -static struct sc_atr_table flex_atrs[] = { +static const struct sc_atr_table flex_atrs[] = { /* Cryptoflex */ /* 8k win2000 */ { "3b:95:15:40:20:68:01:02:00:00", NULL, "Cryptoflex 8K", SC_CARD_TYPE_FLEX_CRYPTO, 0, NULL }, diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 811e5c0543..97fc25b475 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -44,7 +44,7 @@ static struct sc_card_driver gemsafe_drv = { }; /* Known ATRs */ -static struct sc_atr_table gemsafe_atrs[] = { +static const struct sc_atr_table gemsafe_atrs[] = { /* standard version */ {"3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, {"3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index c8d4469142..1d67952a6e 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -86,7 +86,7 @@ static int gpk_get_info(sc_card_t *, int, int, u8 *, size_t); /* * ATRs of GPK4000 cards courtesy of libscez */ -static struct sc_atr_table gpk_atrs[] = { +static const struct sc_atr_table gpk_atrs[] = { { "3B:27:00:80:65:A2:04:01:01:37", NULL, "GPK 4K", SC_CARD_TYPE_GPK_GPK4000_s, 0, NULL }, { "3B:27:00:80:65:A2:05:01:01:37", NULL, "GPK 4K", SC_CARD_TYPE_GPK_GPK4000_sp, 0, NULL }, { "3B:27:00:80:65:A2:0C:01:01:37", NULL, "GPK 4K", SC_CARD_TYPE_GPK_GPK4000_su256, 0, NULL }, diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index a817c99e8c..526d07165e 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -70,7 +70,7 @@ static struct sc_card_driver iasecc_drv = { NULL, 0, NULL }; -static struct sc_atr_table iasecc_known_atrs[] = { +static const struct sc_atr_table iasecc_known_atrs[] = { { "3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00", "FF:FF:FF:FF:FF:FF:FF:FE:FF:FF:00:00:FF:FF:FF:FF:FF:FF:FF:FF", "IAS/ECC Gemalto", SC_CARD_TYPE_IASECC_GEMALTO, 0, NULL }, diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 698f24c0c3..e324a2a7ae 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -47,7 +47,7 @@ static struct sc_card_driver incrypto34_drv = { NULL, 0, NULL }; -static struct sc_atr_table incrypto34_atrs[] = { +static const struct sc_atr_table incrypto34_atrs[] = { { "3b:ff:18:00:ff:81:31:fe:55:00:6b:02:09:02:00:01:01:01:44:53:44:10:31:80:92", NULL, NULL, SC_CARD_TYPE_INCRYPTO34_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 4cdadbfc45..56469da8d8 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -51,7 +51,7 @@ static struct sc_card_driver itacns_drv = { /* List of ATR's for "hard" matching. */ -static struct sc_atr_table itacns_atrs[] = { +static const struct sc_atr_table itacns_atrs[] = { { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL, SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL}, { NULL, NULL, NULL, 0, 0, NULL} diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index d1f87cf0ee..d2269b14ca 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -28,7 +28,7 @@ #include "internal.h" #include "cardctl.h" -static struct sc_atr_table jcop_atrs[] = { +static const struct sc_atr_table jcop_atrs[] = { { "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06", NULL, NULL, SC_CARD_TYPE_JCOP_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 65618af506..1ab1385876 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -28,7 +28,7 @@ #include "internal.h" #include "jpki.h" -static struct sc_atr_table jpki_atrs[] = { +static const struct sc_atr_table jpki_atrs[] = { {"3b:e0:00:ff:81:31:fe:45:14", NULL, NULL, SC_CARD_TYPE_JPKI_BASE, 0, NULL}, {NULL, NULL, NULL, 0, 0, NULL} diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 52dd457d24..2bfdffe177 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -35,7 +35,7 @@ #include "cardctl.h" #include "esteid.h" -static struct sc_atr_table mcrd_atrs[] = { +static const struct sc_atr_table mcrd_atrs[] = { {"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL, "Micardo 2.1/German BMI/D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, {"3b:6f:00:ff:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00", NULL, diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index a40451a0d9..7d33e5210d 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -29,7 +29,7 @@ #include "asn1.h" #include "cardctl.h" -static struct sc_atr_table miocos_atrs[] = { +static const struct sc_atr_table miocos_atrs[] = { /* Test card with 32 kB memory */ { "3B:9D:94:40:23:00:68:10:11:4D:69:6F:43:4F:53:00:90:00", NULL, NULL, SC_CARD_TYPE_MIOCOS_GENERIC, 0, NULL }, /* Test card with 64 kB memory */ diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index d247efabc9..c91b8d5e01 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -42,7 +42,7 @@ static struct sc_card_driver muscle_drv = { NULL, 0, NULL }; -static struct sc_atr_table muscle_atrs[] = { +static const struct sc_atr_table muscle_atrs[] = { /* Tyfone JCOP 242R2 cards */ { "3b:6d:00:00:ff:54:79:66:6f:6e:65:20:32:34:32:52:32", NULL, NULL, SC_CARD_TYPE_MUSCLE_JCOP242R2_NO_EXT_APDU, 0, NULL }, /* Aladdin eToken PRO USB 72K Java */ diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 112367b570..4d08a59c68 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -55,7 +55,7 @@ #define DES_ecb_encrypt(a,b,c,d) des_ecb_encrypt(a,b,*c,d) #endif -static struct sc_atr_table oberthur_atrs[] = { +static const struct sc_atr_table oberthur_atrs[] = { { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", NULL, "Oberthur 64k v4/2.1.1", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL }, { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:02:00:82:90:00", NULL, diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 59cf41e70d..bb1705b333 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -56,7 +56,7 @@ static const char default_cardname_v1[] = "OpenPGP card v1.x"; static const char default_cardname_v2[] = "OpenPGP card v2.x"; static const char default_cardname_v3[] = "OpenPGP card v3.x"; -static struct sc_atr_table pgp_atrs[] = { +static const 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, default_cardname_v1, SC_CARD_TYPE_OPENPGP_V1, 0, NULL }, { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, default_cardname_v2, SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 32932ae75a..506e030b05 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -41,7 +41,7 @@ static struct sc_card_driver rtecp_drv = { NULL, 0, NULL }; -static struct sc_atr_table rtecp_atrs[] = { +static const struct sc_atr_table rtecp_atrs[] = { /* Rutoken ECP */ { "3B:8B:01:52:75:74:6F:6B:65:6E:20:45:43:50:A0", NULL, "Rutoken ECP", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 1815153d32..0930f8cdf5 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -84,7 +84,7 @@ static struct sc_card_driver rutoken_drv = { NULL, 0, NULL }; -static struct sc_atr_table rutoken_atrs[] = { +static const struct sc_atr_table rutoken_atrs[] = { { "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv Rutoken S */ { "3b:6f:00:ff:00:56:75:61:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv uaToken S */ { NULL, NULL, NULL, 0, 0, NULL } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 8963a56550..e831f1886b 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -60,7 +60,7 @@ struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02 /* Known ATRs for SmartCard-HSMs */ -static struct sc_atr_table sc_hsm_atrs[] = { +static const struct sc_atr_table sc_hsm_atrs[] = { /* standard version */ {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index a8ca012fa7..f0ed434303 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -33,7 +33,7 @@ #define _FINEID_BROKEN_SELECT_FLAG 1 -static struct sc_atr_table setcos_atrs[] = { +static const struct sc_atr_table setcos_atrs[] = { /* some Nokia branded SC */ { "3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_GENERIC, 0, NULL }, /* RSA SecurID 3100 */ diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 8b4b2eb977..7ad132dc12 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -31,7 +31,7 @@ #include "internal.h" #include "iso7816.h" -static struct sc_atr_table starcos_atrs[] = { +static const struct sc_atr_table starcos_atrs[] = { { "3B:B7:94:00:c0:24:31:fe:65:53:50:4b:32:33:90:00:b4", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3B:B7:94:00:81:31:fe:65:53:50:4b:32:33:90:00:d1", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, { "3b:b7:18:00:c0:3e:31:fe:65:53:50:4b:32:34:90:00:25", NULL, NULL, SC_CARD_TYPE_STARCOS_GENERIC, 0, NULL }, diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 0fad1e1509..f880295afa 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -33,7 +33,7 @@ #include "asn1.h" #include "cardctl.h" -static struct sc_atr_table tcos_atrs[] = { +static const struct sc_atr_table tcos_atrs[] = { /* Infineon SLE44 */ { "3B:BA:13:00:81:31:86:5D:00:64:05:0A:02:01:31:80:90:00:8B", NULL, NULL, SC_CARD_TYPE_TCOS_V2, 0, NULL }, /* Infineon SLE66S */ diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index f5518c8639..9bd4b57254 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -152,7 +152,7 @@ static int westcos_check_sw(sc_card_t * card, unsigned int sw1, return iso_ops->check_sw(card, sw1, sw2); } -static struct sc_atr_table westcos_atrs[] = { +static const struct sc_atr_table westcos_atrs[] = { /* westcos 2ko */ { "3F:69:00:00:00:64:01:00:00:00:80:90:00", "ff:ff:ff:ff:ff:ff:ff:00:00:00:f0:ff:ff", NULL, 0x00, 0, NULL }, /* westcos applet */ From 67fbf15741762778b4376ed18d4b7e94b00d7c3b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Aug 2018 09:51:04 +0200 Subject: [PATCH 0456/4321] fixed NULL dereference --- src/libopensc/ctx.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 46dcce49dd..626686a73f 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -178,11 +178,13 @@ sc_ctx_win32_get_config_value(const char *name_env, if (name_env) { char *value = value = getenv(name_env); - if (strlen(value) < *out_len) - return SC_ERROR_NOT_ENOUGH_MEMORY; - memcpy(out, value, strlen(value)); - *out_len = strlen(value); - return SC_SUCCESS; + if (value) { + if (strlen(value) < *out_len) + return SC_ERROR_NOT_ENOUGH_MEMORY; + memcpy(out, value, strlen(value)); + *out_len = strlen(value); + return SC_SUCCESS; + } } if (!name_reg) From 70c4813f300628e2a64ee2b78ab3f3c453ff912d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Aug 2018 09:59:45 +0200 Subject: [PATCH 0457/4321] fixed Dereference before null check --- src/libopensc/card-mcrd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2bfdffe177..6dbf62ff21 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1212,7 +1212,7 @@ static int mcrd_restore_se(sc_card_t * card, int se_num) static int mcrd_set_security_env(sc_card_t * card, const sc_security_env_t * env, int se_num) { - struct mcrd_priv_data *priv = DRVDATA(card); + struct mcrd_priv_data *priv; sc_apdu_t apdu; sc_path_t tmppath; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; @@ -1222,6 +1222,7 @@ static int mcrd_set_security_env(sc_card_t * card, if (!(card != NULL && env != NULL)) return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + priv = DRVDATA(card); /* special environment handling for esteid, stolen from openpgp */ if (is_esteid_card(card)) { From 97f0a341b05b0a3cd7520d6abe7a072091332913 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Aug 2018 10:14:25 +0200 Subject: [PATCH 0458/4321] fixed typo --- src/libopensc/errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 354e0a6e3c..5b58b7ea6c 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -103,7 +103,7 @@ const char *sc_strerror(int error) "Unsupported card", "Unable to load external module", "EF offset too large", - "Not implemented" + "Not implemented", "Invalid Simple TLV object", "Premature end of Simple TLV stream", }; From 719ec39b3e2293986d485e5205648ed67e556550 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 23 Aug 2018 13:35:24 -0500 Subject: [PATCH 0459/4321] Use sc_asn1_read_tag to read first tag of partially block (#1454) Sc_asn1_read_tag can return SC_ERROR_ASN1_END_OF_CONTENTS which indicates the tag and length are OK, but any value is not completely contained in the buffer supplied. card-piv.c can use this when reading just the beginning of a object to determine the size of a buffer needed to hold the object. --- src/libopensc/card-piv.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 324f3aecdc..61acedc818 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -479,6 +479,7 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, size_t * recvbuflen) { int r; + int r_tag ; sc_apdu_t apdu; u8 rbufinitbuf[4096]; u8 *rbuf; @@ -572,16 +573,12 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, * the buffer is bigger, so it will not produce "ASN1.tag too long!" */ body = rbuf; - if (sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + r_tag = sc_asn1_read_tag(&body, apdu.resplen, &cla_out, &tag_out, &bodylen); + sc_log(card->ctx, "r_tag:%d body:%p", r_tag, body); + if ( (r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) || body == NULL) { - /* only early beta cards had this problem */ - sc_log(card->ctx, "***** received buffer tag MISSING "); body = rbuf; - /* some readers/cards might return 6c 00 */ - if (apdu.sw1 == 0x61 || apdu.sw2 == 0x6c ) - bodylen = 12000; - else - bodylen = apdu.resplen; + bodylen = apdu.resplen; } rbuflen = body - rbuf + bodylen; @@ -856,6 +853,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, u8 **buf, size_t *buf_len) { int r; + int r_tag; int f = -1; size_t len; u8 tagbuf[16]; @@ -881,10 +879,11 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, goto err; } body = tagbuf; - if (sc_asn1_read_tag(&body, 0xfffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + r_tag = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen); + if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) || body == NULL) { sc_log(card->ctx, "DER problem"); - r = SC_ERROR_INVALID_ASN1_OBJECT; + r = SC_ERROR_FILE_NOT_FOUND; goto err; } rbuflen = body - tagbuf + bodylen; @@ -947,10 +946,12 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) rbuflen = sizeof(rbufinitbuf); r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, &rbuf, &rbuflen); if (r > 0) { + int r_tag; body = rbuf; - if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + r_tag = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen); + if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) || body == NULL) { - sc_log(card->ctx, "***** received buffer tag MISSING "); + sc_log(card->ctx, "r_tag:%d body:%p", r_tag, body); r = SC_ERROR_FILE_NOT_FOUND; goto err; } From 336b282324a9990f94da7ab18a7dbd6957bd9e58 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 25 May 2018 11:30:20 +0300 Subject: [PATCH 0460/4321] Reuse gp_select_aid Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 61 +++++++++------------------------------ src/libopensc/gp.c | 2 +- src/libopensc/gp.h | 1 + 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 6dbf62ff21..386b275857 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -34,6 +34,7 @@ #include "asn1.h" #include "cardctl.h" #include "esteid.h" +#include "gp.h" static const struct sc_atr_table mcrd_atrs[] = { {"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL, @@ -59,13 +60,13 @@ static const struct sc_atr_table mcrd_atrs[] = { {NULL, NULL, NULL, 0, 0, NULL} }; -static const unsigned char EstEID_v3_AID[] = {0xF0, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30}; -static const unsigned char EstEID_v35_AID[] = {0xD2, 0x33, 0x00, 0x00, 0x00, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x33, 0x35}; -static const unsigned char AzeDIT_v35_AID[] = {0xD0, 0x31, 0x00, 0x00, 0x00, 0x44, 0x69, 0x67, 0x69, 0x49, 0x44}; +static const struct sc_aid EstEID_v3_AID = { {0xF0, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30}, 15 }; +static const struct sc_aid EstEID_v35_AID = { {0xD2, 0x33, 0x00, 0x00, 0x00, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x33, 0x35}, 15 }; +static const struct sc_aid AzeDIT_v35_AID = { {0xD0, 0x31, 0x00, 0x00, 0x00, 0x44, 0x69, 0x67, 0x69, 0x49, 0x44}, 11 }; static struct sc_card_operations mcrd_ops; static struct sc_card_driver mcrd_drv = { - "MICARDO 2.1 / EstEID 1.0 - 3.0", + "MICARDO 2.1 / EstEID 1.0 - 3.5", "mcrd", &mcrd_ops, NULL, 0, NULL @@ -299,7 +300,6 @@ int is_esteid_card(sc_card_t *card) { static int mcrd_match_card(sc_card_t * card) { int i = 0, r = 0; - sc_apdu_t apdu; i = _sc_match_atr(card, mcrd_atrs, &card->type); if (i >= 0) { @@ -307,16 +307,9 @@ static int mcrd_match_card(sc_card_t * card) return 1; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); - apdu.lc = sizeof(EstEID_v35_AID); - apdu.data = EstEID_v35_AID; - apdu.datalen = sizeof(EstEID_v35_AID); - apdu.resplen = 0; - apdu.le = 0; - r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); - if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + LOG_FUNC_CALLED(card->ctx); + r = gp_select_aid(card, &EstEID_v35_AID); + if (r >= 0) { sc_log(card->ctx, "AID found"); card->type = SC_CARD_TYPE_MCRD_ESTEID_V30; return 1; @@ -330,7 +323,6 @@ static int mcrd_init(sc_card_t * card) struct mcrd_priv_data *priv; int r; sc_path_t tmppath; - sc_apdu_t apdu; priv = calloc(1, sizeof *priv); if (!priv) @@ -357,45 +349,18 @@ static int mcrd_init(sc_card_t * card) _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); sc_reset(card, 0); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); - apdu.lc = sizeof(EstEID_v3_AID); - apdu.data = EstEID_v3_AID; - apdu.datalen = sizeof(EstEID_v3_AID); - apdu.resplen = 0; - apdu.le = 0; - r = sc_transmit_apdu(card, &apdu); + r = gp_select_aid(card, &EstEID_v3_AID); if (r < 0) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); - if(apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); - apdu.lc = sizeof(EstEID_v35_AID); - apdu.data = EstEID_v35_AID; - apdu.datalen = sizeof(EstEID_v35_AID); - apdu.resplen = 0; - apdu.le = 0; - r = sc_transmit_apdu(card, &apdu); - if (r < 0) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + r = gp_select_aid(card, &EstEID_v35_AID); + if (r >= 0) { // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary // sc_read_binary cannot handle recursive 61 00 calls if (card->reader && card->reader->active_protocol == SC_PROTO_T0) card->max_recv_size = 255; } else { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); - apdu.lc = sizeof(AzeDIT_v35_AID); - apdu.data = AzeDIT_v35_AID; - apdu.datalen = sizeof(AzeDIT_v35_AID); - apdu.resplen = 0; - apdu.le = 0; - r = sc_transmit_apdu(card, &apdu); - if (r < 0) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "APDU transmit failed"); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); - if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { + r = gp_select_aid(card, &AzeDIT_v35_AID); + if (r < 0) { free(card->drv_data); card->drv_data = NULL; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index 49bf934f00..4a7756f21b 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -38,7 +38,7 @@ static const struct sc_aid gp_isd_rid = { /* Select AID */ -static int +int gp_select_aid(struct sc_card *card, const struct sc_aid *aid) { struct sc_apdu apdu; diff --git a/src/libopensc/gp.h b/src/libopensc/gp.h index 458936e4dc..dd4e73b624 100644 --- a/src/libopensc/gp.h +++ b/src/libopensc/gp.h @@ -32,6 +32,7 @@ extern "C" { #endif +int gp_select_aid(struct sc_card *card, const struct sc_aid *aid); int gp_select_card_manager(struct sc_card *card); int gp_select_isd_rid(struct sc_card *card); From 5b428e43233406f7c01c1866b47177659744176d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 24 May 2018 11:55:25 +0200 Subject: [PATCH 0461/4321] upload CI build artifacts to OpenSC/Nightly builds are uploaded as seperate branches to https://github.com/OpenSC/Nightly If the repository gets too big, branches can easily be removed. The repository is written via Travis CI and AppVeyor with a secure token from user https://github.com/OpenSC-CI --- .github/push_artifacts.sh | 27 +++++++++++++++++++++++++++ .travis.yml | 23 +++++++++++++++++++---- appveyor.yml | 25 +++++++++---------------- 3 files changed, 55 insertions(+), 20 deletions(-) create mode 100755 .github/push_artifacts.sh diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh new file mode 100755 index 0000000000..25b481abfa --- /dev/null +++ b/.github/push_artifacts.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -ex -o xtrace + +BUILDPATH=${PWD} +BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" + +git clone https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /dev/null 2>&1 +cd Nightly +git checkout -b "${BRANCH}" + +for file in ${BUILDPATH}/win32/Output/OpenSC*.exe ${BUILDPATH}/opensc*.tar.gz ${BUILDPATH}/OpenSC*.dmg ${BUILDPATH}/OpenSC*.msi ${BUILDPATH}/OpenSC*.zip +do + if [ -f ${file} ] + then + cp ${file} . + git add `basename ${file}` + fi +done + +git commit --message "$1" +if ! git push --quiet --set-upstream origin "${BRANCH}" +then + sleep $[ ( $RANDOM % 32 ) + 1 ]s + git pull --rebase origin "${BRANCH}" + git push --quiet --set-upstream origin "${BRANCH}" +fi diff --git a/.travis.yml b/.travis.yml index 6e37c32133..d3c90e33e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,12 @@ addons: env: global: - # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created - # via the "travis encrypt" command using the project repo's public key + # The next declaration are encrypted envirnmet variables, created via the + # "travis encrypt" command using the project repo's public key + # COVERITY_SCAN_TOKEN - secure: "UkHn7wy4im8V1nebCWbAetnDSOLRUbOlF6++ovk/7Bnso1/lnhXHelyzgRxfD/oI68wm9nnRV+RQEZ9+72Ug1CyvHxyyxxkwal/tPeHH4B/L+aGdPi0id+5OZSKIm77VP3m5s102sJMJgH7DFd03+nUd0K26p0tk8ad4j1geV4c=" + # GH_TOKEN + - secure: "cUAvpN/XUPMIN5cgWAbIOhghRoLXyw7SCydzGaJ1Ucqb9Ml2v5iuLLuN57YbZHTiWw03vy6rYVzzwMDrHX8r3oUALsv7ViJHG4PzIe7fAFZsZpHECmGsp6SEnue7m7BNy3FT8KYbiXxnxDO0SxmFXlrPAYR0WMZCWx2TENYcafs=" - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity.*)" - COVERITY_SCAN_NOTIFICATION_EMAIL="viktor.tarasov@gmail.com" - COVERITY_SCAN_BUILD_COMMAND="make -j 4" @@ -30,6 +33,7 @@ matrix: include: - compiler: clang os: osx + env: DO_PUSH_ARTIFACT=yes - compiler: gcc os: osx - compiler: clang @@ -39,9 +43,13 @@ matrix: os: linux env: ENABLE_DOC=--enable-doc - os: linux - env: HOST=x86_64-w64-mingw32 + env: + - HOST=x86_64-w64-mingw32 + - DO_PUSH_ARTIFACT=yes - os: linux - env: HOST=i686-w64-mingw32 + env: + - HOST=i686-w64-mingw32 + - DO_PUSH_ARTIFACT=yes - os: linux env: DO_COVERITY_SCAN=yes @@ -95,4 +103,11 @@ after_script: killall services.exe; fi + # keep in sync with appveyor.yml + - if [ "${DO_PUSH_ARTIFACT}" = "yes" ]; then + git config --global user.email "builds@travis-ci.org"; + git config --global user.name "Travis CI"; + .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; + fi + cache: ccache diff --git a/appveyor.yml b/appveyor.yml index 9bee08bb37..aee229c629 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,8 @@ configuration: - Light-Release environment: + GH_TOKEN: + secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY matrix: - VSVER: 14 - VSVER: 12 @@ -91,8 +93,8 @@ build_script: - bash -c "make -C etc opensc.conf" - cp win32/winconfig.h config.h - nmake /f Makefile.mak %NMAKE_EXTRA% - - cd win32 && nmake /f Makefile.mak %NMAKE_EXTRA% VSVER=%VSVER% OpenSC.msi - - move OpenSC.msi %ARTIFACT%.msi + - cd win32 && nmake /f Makefile.mak %NMAKE_EXTRA% VSVER=%VSVER% OpenSC.msi && cd .. + - move win32\OpenSC.msi %ARTIFACT%.msi - appveyor PushArtifact %ARTIFACT%.msi # put all pdb files for dump analysis, but this consumes approx 100 MB per build - md %ARTIFACT%-Debug @@ -102,6 +104,11 @@ build_script: } - appveyor PushArtifact %ARTIFACT%-Debug.zip + # keep in sync with .travis.yml + - bash -c "git config --global user.email 'no-reply@appveyor.com'" + - bash -c "git config --global user.name 'AppVeyor'" + - bash -c ".github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"" + cache: - C:\zlib -> appveyor.yml - C:\zlib-Win32 -> appveyor.yml @@ -110,17 +117,3 @@ cache: - C:\openpace-Win32 -> appveyor.yml - C:\openpace-Win64 -> appveyor.yml - cngsdk.msi -> appveyor.yml - -deploy: - - provider: GitHub - tag: $(APPVEYOR_REPO_TAG_NAME) - release: OpenSC-$(APPVEYOR_REPO_TAG_NAME) - description: 'release OpenSC $(APPVEYOR_REPO_TAG_NAME)' - auth_token: - secure: NGaTqWohBQa7fgE62rEm2sp9jkv6S9FRc3YEi3T5CpaoyIY6K89FJjqzaoPLr8vj - artifact: /OpenSC-.*\.msi/ - draft: false - prerelease: true - on: - branch: /0.16.0-rc.*/ # here branch is release tag - appveyor_repo_tag: true # deploy on tag push only From 5a25bd33ccaa82b2977da24128c2f3497100bef6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Aug 2018 09:27:13 +0200 Subject: [PATCH 0462/4321] macos: use HFS+ for backward compatibility fixes https://github.com/OpenSC/OpenSC/issues/1398 --- MacOSX/build-package.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 834e4a16f8..eefb69539d 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -132,7 +132,7 @@ osacompile -o "${imagedir}/OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.ap # Create .dmg rm -f OpenSC-@PACKAGE_VERSION@.dmg i=0 -while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" OpenSC-@PACKAGE_VERSION@.dmg +while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@.dmg do i=$[$i+1] if [ $i -gt 2 ] From 5daec17e32df9f9d284c8792bdd67b70af9589c0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Aug 2018 13:31:00 +0200 Subject: [PATCH 0463/4321] ias/ecc: ignore missing serial on card initialization fixes problem in card detection introduced in 50b000047c44b1f2c6f0134094c19519d512e5b6 --- src/libopensc/card-iasecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 526d07165e..05d13fce0b 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -615,7 +615,7 @@ iasecc_init(struct sc_card *card) LOG_TEST_RET(ctx, rv, "Select EF.ATR AID failed"); } - rv = iasecc_get_serialnr(card, NULL); + iasecc_get_serialnr(card, NULL); } #ifdef ENABLE_SM From 94f9fdf145f6f340f6c68e6743c2d618248f3c12 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Aug 2018 13:49:49 +0200 Subject: [PATCH 0464/4321] ias/ecc: fixed card detection regression of 439a95f2d --- src/libopensc/card-iasecc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 05d13fce0b..330cb0cd03 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -623,10 +623,8 @@ iasecc_init(struct sc_card *card) card->sm_ctx.ops.update_binary = _iasecc_sm_update_binary; #endif - if (!rv) { + if (!rv) sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len)); - rv = SC_ERROR_INVALID_CARD; - } LOG_FUNC_RETURN(ctx, rv); } From db438f61c13e57400c0607314abe4ad4be5191ab Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Aug 2018 13:59:03 +0200 Subject: [PATCH 0465/4321] ias/ecc: fixed GET CHALLENGE --- src/libopensc/card-iasecc.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 330cb0cd03..dcd4a83198 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -1329,6 +1329,29 @@ iasecc_create_file(struct sc_card *card, struct sc_file *file) LOG_FUNC_RETURN(ctx, rv); } +static int +iasecc_get_challenge(struct sc_card *card, u8 * rnd, size_t len) +{ + /* As IAS/ECC cannot handle other data length than 0x08 */ + u8 rbuf[8]; + size_t out_len; + int r; + + LOG_FUNC_CALLED(card->ctx); + + r = iso_ops->get_challenge(card, rbuf, sizeof rbuf); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed"); + + if (len < (size_t) r) { + out_len = len; + } else { + out_len = (size_t) r; + } + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); +} + static int iasecc_logout(struct sc_card *card) @@ -3559,7 +3582,7 @@ sc_get_driver(void) /* update_record: Untested */ iasecc_ops.select_file = iasecc_select_file; /* get_response: Untested */ - /* get_challenge: ISO7816 implementation works */ + iasecc_ops.get_challenge = iasecc_get_challenge; iasecc_ops.logout = iasecc_logout; /* restore_security_env */ iasecc_ops.set_security_env = iasecc_set_security_env; From b5a6f9aa6e5a8d0d2e7344319650af7f37a68581 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 27 Aug 2018 13:40:20 +0200 Subject: [PATCH 0466/4321] prepare 0.19.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a02128915c..137dc4813d 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [18]) +define([PACKAGE_VERSION_MINOR], [19]) define([PACKAGE_VERSION_FIX], [0]) define([PACKAGE_SUFFIX], []) From 0ab5b92dc50e9b1a93f23edfb93611e10502ac64 Mon Sep 17 00:00:00 2001 From: asc Date: Thu, 30 Aug 2018 09:35:04 +0200 Subject: [PATCH 0467/4321] Allow building tests on Ubuntu 16.04, which has libcmocka 1.0.1 (#1405) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 137dc4813d..3769757a79 100644 --- a/configure.ac +++ b/configure.ac @@ -522,7 +522,7 @@ if test "${enable_notify}" = "yes"; then fi have_cmocka="yes" -PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.1.0],,[have_cmocka="no"]) +PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.0.1],,[have_cmocka="no"]) AC_CHECK_HEADER([setjmp.h]) AC_CHECK_HEADER([cmocka.h],, [have_cmocka="no"], [#include From 0ddfd2d5216b19e6e3e996931ee96a82988420da Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 30 Aug 2018 22:05:46 +0200 Subject: [PATCH 0468/4321] deploy only when on master --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3c90e33e4..24dc40f22f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -104,7 +104,7 @@ after_script: fi # keep in sync with appveyor.yml - - if [ "${DO_PUSH_ARTIFACT}" = "yes" ]; then + - if [ "${DO_PUSH_ARTIFACT}" = "yes" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then git config --global user.email "builds@travis-ci.org"; git config --global user.name "Travis CI"; .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; diff --git a/appveyor.yml b/appveyor.yml index aee229c629..71f557c8f7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -107,7 +107,7 @@ build_script: # keep in sync with .travis.yml - bash -c "git config --global user.email 'no-reply@appveyor.com'" - bash -c "git config --global user.name 'AppVeyor'" - - bash -c ".github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"" + - bash -c "if [ -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" cache: - C:\zlib -> appveyor.yml From a3ca935b167324c5fe212857a0e996b6d544df0a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 30 Aug 2018 12:05:25 +0200 Subject: [PATCH 0469/4321] win32: use standard build of zlib fixes https://github.com/OpenSC/OpenSC/issues/1461 --- appveyor.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 71f557c8f7..c61327d52b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -67,11 +67,7 @@ build_script: xcopy C:\zlib C:\zlib-${env:OPENSSL_PF} /e /i /y /s cd C:\zlib-${env:OPENSSL_PF} (Get-Content win32/Makefile.msc).replace('-MD', '-MT') | Set-Content win32/Makefile.msc - If ($env:Platform -Match "x86") { - nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="inffas32.obj match686.obj" zlib.lib - } Else { - nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" zlib.lib - } + nmake -f win32/Makefile.msc zlib.lib } $env:NMAKE_EXTRA="ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC ZLIB_INCL_DIR=/IC:\zlib-${env:OPENSSL_PF} ZLIB_LIB=C:\zlib-${env:OPENSSL_PF}\zlib.lib ${env:NMAKE_EXTRA}" If (!(Test-Path -Path "C:\openpace-${env:OPENSSL_PF}" )) { From c79adb6c11f2707524d4d5fe3b03d81aa423351c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 08:40:37 +0200 Subject: [PATCH 0470/4321] include PACKAGE_NAME in msi instead of VSVER uploads nightly only for VS12 build --- appveyor.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c61327d52b..248a77824b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ environment: matrix: - VSVER: 14 - VSVER: 12 + DO_PUSH_ARTIFACT: yes install: - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` @@ -29,11 +30,11 @@ install: If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:OPENSSL_PF="Win32" - $env:ARTIFACT="OpenSC-win32_vs${env:VSVER}-${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}-${env:CONFIGURATION}" } Else { $env:VCVARS_PLATFORM="amd64" $env:OPENSSL_PF="Win64" - $env:ARTIFACT="OpenSC-win64_vs${env:VSVER}-${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}-${env:CONFIGURATION}" } - ps: >- If (!($env:Configuration -Like "*Light*")) { @@ -103,7 +104,7 @@ build_script: # keep in sync with .travis.yml - bash -c "git config --global user.email 'no-reply@appveyor.com'" - bash -c "git config --global user.name 'AppVeyor'" - - bash -c "if [ -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" + - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" cache: - C:\zlib -> appveyor.yml From 972f9eb35b3583a2d82c3ac18e7e7f0a6b2141a8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 13:36:33 +0200 Subject: [PATCH 0471/4321] fixed PKCS11-Spy dll default fixes https://github.com/OpenSC/OpenSC/issues/1464 --- win32/OpenSC.wxs.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 5ca2341605..dbcea01f73 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -308,7 +308,7 @@ - + From 2b60a0db0f6c39783acb55e58f5d0dcfceeecb40 Mon Sep 17 00:00:00 2001 From: asc Date: Thu, 30 Aug 2018 09:40:56 +0200 Subject: [PATCH 0472/4321] Add support for SmartCard-HSM 4K (V3.0) --- src/libopensc/card-sc-hsm.c | 38 +++++++++++++++++++---------------- src/libopensc/pkcs15-pubkey.c | 2 ++ src/libopensc/pkcs15-sc-hsm.c | 27 +++++++++++++++++++++++++ src/tools/pkcs11-tool.c | 2 ++ src/tools/sc-hsm-tool.c | 2 +- 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index e831f1886b..a2054a5135 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -64,6 +64,8 @@ static const struct sc_atr_table sc_hsm_atrs[] = { /* standard version */ {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, + {"3B:DE:18:FF:81:91:FE:1F:C3:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:1C", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, + {"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card { "3B:84:80:01:47:6f:49:44:00", @@ -1040,8 +1042,12 @@ static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, fieldsizebytes = 32; } else if (datalen <= 90) { // 320 bit curve = 40 * 2 + 10 byte maximum DER signature fieldsizebytes = 40; - } else { + } else if (datalen <= 106) { // 384 bit curve = 48 * 2 + 10 byte maximum DER signature + fieldsizebytes = 48; + } else if (datalen <= 138) { // 512 bit curve = 64 * 2 + 10 byte maximum DER signature fieldsizebytes = 64; + } else { + fieldsizebytes = 66; } sc_log(card->ctx, @@ -1094,8 +1100,7 @@ static int sc_hsm_compute_signature(sc_card_t *card, { int r; sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 rbuf[514]; sc_hsm_private_data_t *priv; if (card == NULL || data == NULL || out == NULL) { @@ -1107,19 +1112,13 @@ static int sc_hsm_compute_signature(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); } - // check if datalen exceeds the buffer size - if (datalen > SC_MAX_APDU_BUFFER_SIZE) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x68, priv->env->key_ref[0], priv->algorithm); + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x68, priv->env->key_ref[0], priv->algorithm); apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = 256; + apdu.le = 512; - memcpy(sbuf, data, datalen); - apdu.data = sbuf; + apdu.data = data; apdu.lc = datalen; apdu.datalen = datalen; r = sc_transmit_apdu(card, &apdu); @@ -1149,7 +1148,7 @@ static int sc_hsm_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len int r; size_t len; sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 rbuf[514]; sc_hsm_private_data_t *priv; if (card == NULL || crgram == NULL || out == NULL) { @@ -1158,11 +1157,11 @@ static int sc_hsm_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len LOG_FUNC_CALLED(card->ctx); priv = (sc_hsm_private_data_t *) card->drv_data; - sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x62, priv->env->key_ref[0], priv->algorithm); + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x62, priv->env->key_ref[0], priv->algorithm); apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = 256; + apdu.le = 512; apdu.data = (u8 *)crgram; apdu.lc = crgram_len; @@ -1357,7 +1356,7 @@ static int sc_hsm_wrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *par { sc_context_t *ctx = card->ctx; sc_apdu_t apdu; - u8 data[MAX_EXT_APDU_LENGTH]; + u8 data[1500]; int r; LOG_FUNC_CALLED(card->ctx); @@ -1528,7 +1527,7 @@ static int sc_hsm_init_pin(sc_card_t *card, sc_cardctl_pkcs11_init_pin_t *params static int sc_hsm_generate_keypair(sc_card_t *card, sc_cardctl_sc_hsm_keygen_info_t *keyinfo) { - u8 rbuf[1024]; + u8 rbuf[1200]; int r; sc_apdu_t apdu; @@ -1614,6 +1613,8 @@ static int sc_hsm_init(struct sc_card *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); + _sc_card_add_rsa_alg(card, 3072, flags, 0); + _sc_card_add_rsa_alg(card, 4096, flags, 0); flags = SC_ALGORITHM_ECDSA_RAW| SC_ALGORITHM_ECDH_CDH_RAW| @@ -1632,6 +1633,9 @@ static int sc_hsm_init(struct sc_card *card) _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL); _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); _sc_card_add_ec_alg(card, 320, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 512, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL); card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO; diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 11db273703..e3f6848601 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1490,6 +1490,8 @@ static struct ec_curve_info { {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224}, {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256}, {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320}, + {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384}, + {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512}, {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192}, {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256}, diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 1391bea153..044502d2b6 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -61,6 +61,15 @@ static struct ec_curve curves[] = { { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51", 32}, { (unsigned char *) "\x01", 1} }, + { + { (unsigned char *) "\x2B\x81\x04\x00\x23", 5}, // secp521r1 + { (unsigned char *) "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 66}, + { (unsigned char *) "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", 66}, + { (unsigned char *) "\x00\x51\x95\x3E\xB9\x61\x8E\x1C\x9A\x1F\x92\x9A\x21\xA0\xB6\x85\x40\xEE\xA2\xDA\x72\x5B\x99\xB3\x15\xF3\xB8\xB4\x89\x91\x8E\xF1\x09\xE1\x56\x19\x39\x51\xEC\x7E\x93\x7B\x16\x52\xC0\xBD\x3B\xB1\xBF\x07\x35\x73\xDF\x88\x3D\x2C\x34\xF1\xEF\x45\x1F\xD4\x6B\x50\x3F\x00", 66}, + { (unsigned char *) "\x04\x00\xC6\x85\x8E\x06\xB7\x04\x04\xE9\xCD\x9E\x3E\xCB\x66\x23\x95\xB4\x42\x9C\x64\x81\x39\x05\x3F\xB5\x21\xF8\x28\xAF\x60\x6B\x4D\x3D\xBA\xA1\x4B\x5E\x77\xEF\xE7\x59\x28\xFE\x1D\xC1\x27\xA2\xFF\xA8\xDE\x33\x48\xB3\xC1\x85\x6A\x42\x9B\xF9\x7E\x7E\x31\xC2\xE5\xBD\x66\x01\x18\x39\x29\x6A\x78\x9A\x3B\xC0\x04\x5C\x8A\x5F\xB4\x2C\x7D\x1B\xD9\x98\xF5\x44\x49\x57\x9B\x44\x68\x17\xAF\xBD\x17\x27\x3E\x66\x2C\x97\xEE\x72\x99\x5E\xF4\x26\x40\xC5\x50\xB9\x01\x3F\xAD\x07\x61\x35\x3C\x70\x86\xA2\x72\xC2\x40\x88\xBE\x94\x76\x9F\xD1\x66\x50", 133}, + { (unsigned char *) "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFA\x51\x86\x87\x83\xBF\x2F\x96\x6B\x7F\xCC\x01\x48\xF7\x09\xA5\xD0\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE\xBB\x6F\xB7\x1E\x91\x38\x64\x09", 66}, + { (unsigned char *) "\x01", 1} + }, { { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x03", 9}, // brainpoolP192r1 { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x30\x93\xD1\x8D\xB7\x8F\xCE\x47\x6D\xE1\xA8\x62\x97", 24}, @@ -97,6 +106,24 @@ static struct ec_curve curves[] = { { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA5\xB6\x8F\x12\xA3\x2D\x48\x2E\xC7\xEE\x86\x58\xE9\x86\x91\x55\x5B\x44\xC5\x93\x11", 40}, { (unsigned char *) "\x01", 1} }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 9}, // brainpoolP384r1 + { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x53", 48}, + { (unsigned char *) "\x7B\xC3\x82\xC6\x3D\x8C\x15\x0C\x3C\x72\x08\x0A\xCE\x05\xAF\xA0\xC2\xBE\xA2\x8E\x4F\xB2\x27\x87\x13\x91\x65\xEF\xBA\x91\xF9\x0F\x8A\xA5\x81\x4A\x50\x3A\xD4\xEB\x04\xA8\xC7\xDD\x22\xCE\x28\x26", 48}, + { (unsigned char *) "\x04\xA8\xC7\xDD\x22\xCE\x28\x26\x8B\x39\xB5\x54\x16\xF0\x44\x7C\x2F\xB7\x7D\xE1\x07\xDC\xD2\xA6\x2E\x88\x0E\xA5\x3E\xEB\x62\xD5\x7C\xB4\x39\x02\x95\xDB\xC9\x94\x3A\xB7\x86\x96\xFA\x50\x4C\x11", 48}, + { (unsigned char *) "\x04\x1D\x1C\x64\xF0\x68\xCF\x45\xFF\xA2\xA6\x3A\x81\xB7\xC1\x3F\x6B\x88\x47\xA3\xE7\x7E\xF1\x4F\xE3\xDB\x7F\xCA\xFE\x0C\xBD\x10\xE8\xE8\x26\xE0\x34\x36\xD6\x46\xAA\xEF\x87\xB2\xE2\x47\xD4\xAF\x1E\x8A\xBE\x1D\x75\x20\xF9\xC2\xA4\x5C\xB1\xEB\x8E\x95\xCF\xD5\x52\x62\xB7\x0B\x29\xFE\xEC\x58\x64\xE1\x9C\x05\x4F\xF9\x91\x29\x28\x0E\x46\x46\x21\x77\x91\x81\x11\x42\x82\x03\x41\x26\x3C\x53\x15", 97}, + { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB3\x1F\x16\x6E\x6C\xAC\x04\x25\xA7\xCF\x3A\xB6\xAF\x6B\x7F\xC3\x10\x3B\x88\x32\x02\xE9\x04\x65\x65", 48}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 9}, // brainpoolP512r1 + { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF3", 64}, + { (unsigned char *) "\x78\x30\xA3\x31\x8B\x60\x3B\x89\xE2\x32\x71\x45\xAC\x23\x4C\xC5\x94\xCB\xDD\x8D\x3D\xF9\x16\x10\xA8\x34\x41\xCA\xEA\x98\x63\xBC\x2D\xED\x5D\x5A\xA8\x25\x3A\xA1\x0A\x2E\xF1\xC9\x8B\x9A\xC8\xB5\x7F\x11\x17\xA7\x2B\xF2\xC7\xB9\xE7\xC1\xAC\x4D\x77\xFC\x94\xCA", 64}, + { (unsigned char *) "\x3D\xF9\x16\x10\xA8\x34\x41\xCA\xEA\x98\x63\xBC\x2D\xED\x5D\x5A\xA8\x25\x3A\xA1\x0A\x2E\xF1\xC9\x8B\x9A\xC8\xB5\x7F\x11\x17\xA7\x2B\xF2\xC7\xB9\xE7\xC1\xAC\x4D\x77\xFC\x94\xCA\xDC\x08\x3E\x67\x98\x40\x50\xB7\x5E\xBA\xE5\xDD\x28\x09\xBD\x63\x80\x16\xF7\x23", 64}, + { (unsigned char *) "\x04\x81\xAE\xE4\xBD\xD8\x2E\xD9\x64\x5A\x21\x32\x2E\x9C\x4C\x6A\x93\x85\xED\x9F\x70\xB5\xD9\x16\xC1\xB4\x3B\x62\xEE\xF4\xD0\x09\x8E\xFF\x3B\x1F\x78\xE2\xD0\xD4\x8D\x50\xD1\x68\x7B\x93\xB9\x7D\x5F\x7C\x6D\x50\x47\x40\x6A\x5E\x68\x8B\x35\x22\x09\xBC\xB9\xF8\x22\x7D\xDE\x38\x5D\x56\x63\x32\xEC\xC0\xEA\xBF\xA9\xCF\x78\x22\xFD\xF2\x09\xF7\x00\x24\xA5\x7B\x1A\xA0\x00\xC5\x5B\x88\x1F\x81\x11\xB2\xDC\xDE\x49\x4A\x5F\x48\x5E\x5B\xCA\x4B\xD8\x8A\x27\x63\xAE\xD1\xCA\x2B\x2F\xA8\xF0\x54\x06\x78\xCD\x1E\x0F\x3A\xD8\x08\x92", 129}, + { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x70\x55\x3E\x5C\x41\x4C\xA9\x26\x19\x41\x86\x61\x19\x7F\xAC\x10\x47\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD\xB5\x87\x96\x82\x9C\xA9\x00\x69", 64}, + { (unsigned char *) "\x01", 1} + }, { { (unsigned char *) "\x2B\x81\x04\x00\x1F", 5}, // secp192k1 { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xEE\x37", 24}, diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index c29d1b841b..aefbabf696 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -109,6 +109,8 @@ static struct ec_curve_info { {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224}, {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256}, {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320}, + {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384}, + {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512}, {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192}, {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256}, diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 8c9431ade1..9c1d7c1ba3 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -63,7 +63,7 @@ static int verbose = 0; // Some reasonable maximums #define MAX_CERT 4096 #define MAX_PRKD 256 -#define MAX_KEY 1024 +#define MAX_KEY 1500 #define MAX_WRAPPED_KEY (MAX_CERT + MAX_PRKD + MAX_KEY) #define SEED_LENGTH 16 From b572b383b2bda402b83b005ddceb4d936dffeb63 Mon Sep 17 00:00:00 2001 From: alex-nitrokey <36155797+alex-nitrokey@users.noreply.github.com> Date: Fri, 31 Aug 2018 14:38:14 +0200 Subject: [PATCH 0473/4321] Add supported algorithms for OpenPGP Card (Fixes #1432) (#1442) --- src/libopensc/card-openpgp.c | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index bb1705b333..43dc9eaffd 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -572,6 +572,38 @@ pgp_init(sc_card_t *card) /* get card_features from ATR & DOs */ pgp_get_card_features(card); + /* add supported algorithms based on specification for pkcs15-init */ + if (strcmp(card->ctx->app_name, "pkcs15-init") == 0){ + unsigned long flags; + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; // Can be generated in card + + switch (card->type) { + case SC_CARD_TYPE_OPENPGP_V3: + /* RSA 1024 was removed for v3+ */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + _sc_card_add_rsa_alg(card, 3072, flags, 0); + _sc_card_add_rsa_alg(card, 4096, flags, 0); + /* TODO add ECC + * v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ + break; + case SC_CARD_TYPE_OPENPGP_GNUK: + _sc_card_add_rsa_alg(card, 2048, flags, 0); + /* TODO add ECC for more recent Gnuk (1.2.x) + * these are not include in SC_CARD_TYPE_OPENPGP_GNUK, but + * are treated like SC_CARD_TYPE_OPENPGP_V2 + * Gnuk supports NIST, SECG and Curve25519 from version 1.2.x on */ + break; + case SC_CARD_TYPE_OPENPGP_V2: + default: + _sc_card_add_rsa_alg(card, 1024, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + _sc_card_add_rsa_alg(card, 3072, flags, 0); + _sc_card_add_rsa_alg(card, 4096, flags, 0); + break; + } + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -727,7 +759,12 @@ pgp_get_card_features(sc_card_t *card) card->max_pin_len = blob->data[1]; } - /* get supported algorithms & key lengths from "algorithm attributes" DOs */ + /* get _current_ algorithms & key lengths from "algorithm attributes" DOs + * + * All available algorithms should be already provided by pgp_init. However, if another + * algorithm is found in the "algorithm attributes" DOs, it is supported by the card as + * well and therefore added + * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { unsigned long flags; From e238f4d6fb4e330697fee29285b17220cba4c7bc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 14:30:04 +0200 Subject: [PATCH 0474/4321] don't include tag in windows artifact --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 248a77824b..7cf4319b69 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - set PATH=C:\cygwin\bin;%PATH% - set OPENPACE_VER=1.0.3 - set ZLIB_VER_DOT=1.2.11 - - ps: $env:PACKAGE_NAME=(git describe --tags) + - ps: $env:PACKAGE_NAME=(git describe --tags --abbrev=0) - ps: >- If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" From ddec3a437cb0c064c9e3ba3c1882e582c9e08f45 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 14:34:33 +0200 Subject: [PATCH 0475/4321] remove -Release in windows artifact --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7cf4319b69..49135367b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,8 +5,8 @@ platform: - x64 configuration: - - Release - - Light-Release + - + - -Light environment: GH_TOKEN: @@ -30,11 +30,11 @@ install: If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:OPENSSL_PF="Win32" - $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}-${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}${env:CONFIGURATION}" } Else { $env:VCVARS_PLATFORM="amd64" $env:OPENSSL_PF="Win64" - $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}-${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}${env:CONFIGURATION}" } - ps: >- If (!($env:Configuration -Like "*Light*")) { From 39bd1ddd58dda4d09ba69d712f51293adbe30b9f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Sep 2018 13:51:40 +0200 Subject: [PATCH 0476/4321] fixed wrong condition fixes https://github.com/OpenSC/OpenSC/issues/1465 --- src/libopensc/sc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 53fefb3e68..ea63410048 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -628,7 +628,7 @@ int sc_file_set_sec_attr(sc_file_t *file, const u8 *sec_attr, return SC_ERROR_INVALID_ARGUMENTS; } - if (sec_attr == NULL || sec_attr_len) { + if (sec_attr == NULL || sec_attr_len == 0) { if (file->sec_attr != NULL) free(file->sec_attr); file->sec_attr = NULL; From 62a2847300e767ff239a689ffcd063214cb07fe1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Sep 2018 13:55:19 +0200 Subject: [PATCH 0477/4321] add missing files.xml to distribution --- doc/files/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am index 100749950a..d12091c842 100644 --- a/doc/files/Makefile.am +++ b/doc/files/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -dist_noinst_DATA = pkcs15-profile.5.xml opensc.conf.5.xml.in +dist_noinst_DATA = pkcs15-profile.5.xml opensc.conf.5.xml.in files.xml if ENABLE_DOC html_DATA = files.html endif From 33529602653d3c623d77477cd2310343451068c2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Sep 2018 08:51:00 +0200 Subject: [PATCH 0478/4321] fixed maintainer-clean target --- win32/Makefile.am | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/win32/Makefile.am b/win32/Makefile.am index 61c31f4411..590cff84fd 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -1,11 +1,11 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo.rc $(srcdir)/winconfig.h \ - $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs $(srcdir)/OpenSC.ico \ - $(srcdir)/dlgbmp.bmp $(srcdir)/bannrbmp.bmp $(srcdir)/versioninfo-customactions.rc -EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak \ - versioninfo.rc.in winconfig.h.in OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc.in DDORes.dll_14_2302.ico -dist_noinst_HEADERS = versioninfo.rc winconfig.h OpenSC.iss OpenSC.wxs OpenSC.ico dlgbmp.bmp bannrbmp.bmp + $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs $(srcdir)/versioninfo-customactions.rc +EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak versioninfo.rc.in winconfig.h.in \ + OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc.in \ + OpenSC.ico dlgbmp.bmp bannrbmp.bmp DDORes.dll_14_2302.ico +dist_noinst_HEADERS = versioninfo.rc winconfig.h OpenSC.iss OpenSC.wxs if ENABLE_MINIDRIVER_SETUP_CUSTOMACTION lib_LTLIBRARIES = customactions@LIBRARY_BITNESS@.la From ea2024decf293dc67e45d98637604e6a3b9c478b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Sep 2018 09:42:40 +0200 Subject: [PATCH 0479/4321] appveyor: fix release build --- appveyor.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 49135367b2..9bb1c94274 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,8 +5,8 @@ platform: - x64 configuration: - - - - -Light + - Release + - Light environment: GH_TOKEN: @@ -30,14 +30,16 @@ install: If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:OPENSSL_PF="Win32" - $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}" } Else { $env:VCVARS_PLATFORM="amd64" $env:OPENSSL_PF="Win64" - $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}${env:CONFIGURATION}" + $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}" } - ps: >- - If (!($env:Configuration -Like "*Light*")) { + If ($env:Configuration -Like "*Light*") { + $env:ARTIFACT="${env:ARTIFACT}-Light" + } Else { $env:NMAKE_EXTRA="OPENSSL_DEF=/DENABLE_OPENSSL ${env:NMAKE_EXTRA}" If (!(Test-Path C:\zlib )) { appveyor DownloadFile "https://github.com/madler/zlib/archive/v${env:ZLIB_VER_DOT}.zip" -FileName zlib.zip From 012a425819ed4d1be9e96d8db36f85895f691000 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Sep 2018 22:27:09 +0200 Subject: [PATCH 0480/4321] fixed generating files documentation --- doc/files/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am index d12091c842..e046c42078 100644 --- a/doc/files/Makefile.am +++ b/doc/files/Makefile.am @@ -22,7 +22,7 @@ opensc.conf.5.xml opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl opensc.conf.5.xml files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml - $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< + $(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< %.5: $(srcdir)/%.5.xml sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ From 748234b7cc695de3a6238c0abd8d2a430e64b62d Mon Sep 17 00:00:00 2001 From: alex-nitrokey Date: Fri, 31 Aug 2018 15:56:57 +0200 Subject: [PATCH 0481/4321] Fix SM algorithm in extended capabilities --- src/libopensc/card-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 43dc9eaffd..af30a6276f 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -735,7 +735,7 @@ pgp_get_card_features(sc_card_t *card) if (priv->bcd_version < OPENPGP_CARD_3_0) { /* v2.x: SM algorithm is at byte 2: 0 == 3DES */ - priv->sm_algo = blob->data[0]; + priv->sm_algo = blob->data[1]; if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) priv->sm_algo = SM_ALGO_3DES; @@ -745,7 +745,7 @@ pgp_get_card_features(sc_card_t *card) } else { /* v3.0+: SM algorithm is at byte 2: 0 == UNKNOWN */ - priv->sm_algo = blob->data[0]; + priv->sm_algo = blob->data[1]; if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) priv->sm_algo = SM_ALGO_UNKNOWN; } From 083c18045e36fb0652c0360f2cd6885a9d7cac79 Mon Sep 17 00:00:00 2001 From: alex-nitrokey <36155797+alex-nitrokey@users.noreply.github.com> Date: Thu, 6 Sep 2018 10:57:23 +0200 Subject: [PATCH 0482/4321] Make deciphering with AUT-key possible for OpenPGP Card >v3.2 (fixes #1352) (#1446) --- src/libopensc/card-openpgp.c | 65 +++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index af30a6276f..a1ef73768c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -128,7 +128,8 @@ enum _ext_caps { /* extended capabilities/features */ EXT_CAP_SM = 0x0080, EXT_CAP_LCS = 0x0100, EXT_CAP_CHAINING = 0x1000, - EXT_CAP_APDU_EXT = 0x2000 + EXT_CAP_APDU_EXT = 0x2000, + EXT_CAP_MSE = 0x3000 }; enum _card_state { @@ -749,6 +750,11 @@ pgp_get_card_features(sc_card_t *card) if ((priv->sm_algo == SM_ALGO_NONE) && (priv->ext_caps & EXT_CAP_SM)) priv->sm_algo = SM_ALGO_UNKNOWN; } + if (priv->bcd_version >= OPENPGP_CARD_3_3 && (blob->len >= 10)) { + /* v3.3+: MSE for key numbers 2(DEC) and 3(AUT) supported */ + if (blob->data[9]) + priv->ext_caps |= EXT_CAP_MSE; + } } } @@ -1926,6 +1932,51 @@ pgp_set_security_env(sc_card_t *card, } +/** + * set MANAGE SECURITY ENVIRONMENT as documented in 7.2.18 since OpenPGP Card v3.3 + * + * "This optional command (announced in Extended Capabilities) assigns a specific key to a + * command. The DEC-key (Key-Ref 2) can be assigned to the command INTERNAL AUTHENTICATE + * and the AUT-Key (Key.Ref 3) can be linked to the command PSO:DECIPHER also." + * + * key: Key-Ref to change (2 for DEC-Key or 3 for AUT-Key) + * p2: Usage to set (0xb8 for PSO:DECIPHER or 0xa4 for INTERNAL AUTHENTICATE) + **/ +static int +pgp_set_MSE(sc_card_t *card, int key, u8 p2) +{ + struct pgp_priv_data *priv = DRVDATA(card); + sc_apdu_t apdu; + u8 apdu_case = SC_APDU_CASE_3; + u8 apdu_data[3]; + int r; + + LOG_FUNC_CALLED(card->ctx); + + // check if MSE is supported + if (!(priv->ext_caps & EXT_CAP_MSE)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + // create apdu + sc_format_apdu(card, &apdu, apdu_case, 0x22, 0x41, p2); + apdu.lc = 3; + apdu_data[0] = 0x83; + apdu_data[1] = 0x01; + apdu_data[2] = key; + apdu.data = apdu_data; + apdu.datalen = 3; + + // transmit apdu + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "Card returned error"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + + /** * ABI: ISO 7816-8 COMPUTE DIGITAL SIGNATURE. */ @@ -2041,6 +2092,13 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, apdu.resp = out; apdu.resplen = outlen; + /* For OpenPGP Card >=v3.3, key slot 3 instead of 2 can be used for deciphering, + * but this has to be set via MSE beforehand on every usage (slot 2 is used by default) + * see section 7.2.18 of the specification of OpenPGP Card v3.3 */ + if (priv->bcd_version >= OPENPGP_CARD_3_3 && env->key_ref[0] == 0x02){ + pgp_set_MSE(card, 3, 0xb8); + } + r = sc_transmit_apdu(card, &apdu); free(temp); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -2048,6 +2106,11 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "Card returned error"); + /* For OpenPGP Card >=v3.3, use key slot 2 for deciphering again (set to default) */ + if (priv->bcd_version >= OPENPGP_CARD_3_3 && env->key_ref[0] == 0x02){ + pgp_set_MSE(card, 2, 0xb8); + } + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); } From d8a2a7bf88419ccf07d0a2ae84705d17c46a194f Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Sat, 8 Sep 2018 00:16:57 +0300 Subject: [PATCH 0483/4321] reader-ctapi: ctapi_connect: remove unused variable from day 1 return value of _sc_parse_atr was ignored. --- src/libopensc/reader-ctapi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index 8d4c1c246e..4b94337f2a 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -239,7 +239,6 @@ static int ctapi_connect(sc_reader_t *reader) char rv; u8 cmd[9], rbuf[256], sad, dad; unsigned short lr; - int r; if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; @@ -265,7 +264,7 @@ static int ctapi_connect(sc_reader_t *reader) return SC_ERROR_INTERNAL; reader->atr.len = lr; memcpy(reader->atr.value, rbuf, lr); - r = _sc_parse_atr(reader); + _sc_parse_atr(reader); return 0; } From 83c0bff640d1dd41604befc5be584eab6603a94d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 10 Sep 2018 21:50:03 +0200 Subject: [PATCH 0484/4321] pgp: added new ATRs to windows installer --- win32/customactions.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index a946566af0..8fecceaed2 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -101,9 +101,13 @@ MD_REGISTRATION minidriver_registration[] = { {TEXT("CEV WESTCOS"), {0x3f,0x69,0x00,0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x80,0x90,0x00}, 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xf0,0xff,0xff}}, /* from card-openpgp.c */ - {TEXT("OpenPGP card v1.0/1.1"), {0x3b,0xfa,0x13,0x00,0xff,0x81,0x31,0x80,0x45,0x00,0x31,0xc1,0x73,0xc0,0x01,0x00,0x00,0x90,0x00,0xb1}, + {TEXT("OpenPGP card v1.x"), {0x3b,0xfa,0x13,0x00,0xff,0x81,0x31,0x80,0x45,0x00,0x31,0xc1,0x73,0xc0,0x01,0x00,0x00,0x90,0x00,0xb1}, 20, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("CryptoStick v1.2 (OpenPGP v2.0)"), {0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xc5,0x73,0xc0,0x01,0x40,0x00,0x90,0x00,0x0c}, + {TEXT("OpenPGP card v2.x"), {0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xc5,0x73,0xc0,0x01,0x40,0x00,0x90,0x00,0x0c}, + 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("Gnuk v1.0.x (OpenPGP v2.0)"), {0x3b,0xda,0x11,0xff,0x81,0xb1,0xfe,0x55,0x1f,0x03,0x00,0x31,0x84,0x73,0x80,0x01,0x80,0x00,0x90,0x00,0xe4}, + 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("OpenPGP card v3.x"), {0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xf5,0x73,0xc0,0x01,0x60,0x00,0x90,0x00,0x1c}, 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, /* from card-masktech.c */ /* note: the card name MUST be unique */ From 719d2cbe2167b6a18615da5f68354fe099382895 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Sep 2018 09:44:02 +0200 Subject: [PATCH 0485/4321] Updated NEWS --- NEWS | 105 +++++++++++++++++++++++++++++++++++++++++++++++---- appveyor.yml | 2 +- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 0c5d77e2c7..2851c5d2c9 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,94 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.19.0; 2018-09-12 +## General Improvements +* fixed multiple security problems (out of bound writes/reads, #1447): + * CVE-2018-16391 + * CVE-2018-16392 + * CVE-2018-16393 + * CVE-2018-16418 + * CVE-2018-16419 + * CVE-2018-16420 + * CVE-2018-16421 + * CVE-2018-16422 + * CVE-2018-16423 + * CVE-2018-16424 + * CVE-2018-16425 + * CVE-2018-16426 + * CVE-2018-16427 +* Improved documentation: + * New manual page for opensc.conf(5) + * Added several missing switches in manual pages and fixed formatting +* Win32 installer: + * automatically start SCardSvr + * added newer OpenPGP ATRs +* macOS installer: use HFS+ for backward compatibility +* Remove outdated solaris files +* PC/SC driver: + * Workaround OMNIKEY 3x21 and 6121 Smart Card Readers wrongly identified as pinpad readers in macOS +* Workaround cards returning short signatures without leading zeroes +* bash completion + * make location directory configurable + * Use a new correct path by default +* build: support for libressl-2.7+ +* Configuration + * Distribute minimal opensc.conf + * `pkcs11_enable_InitToken made` global configuration option + * Modify behavior of `OPENSC_DRIVER` environment variable to restrict driver list instead of forcing one driver and skipping vital parts of configuration + * Removed configuration options `zero_ckaid_for_ca_certs`, `force_card_driver`, `reopen_debug_file`, `paranoid-memory` + * Generalized configuration option `ignored_readers` +* If card initialization fails, continue card detection with other card drivers (#1251) +* Fixed long term card operations on Windows 8 and later (#1043) +* reader-pcsc: allow fixing the length of a PIN +* fixed multithreading issue on Window with OpenPACE OIDs +## PKCS#11 +* fixed crash during `C_WaitForSlotEvent` (#1335) +## Minidriver +* Allow cancelling the PIN pad prompt before starting the reader transaction. Whether to start the transaction immediately or not is user-configurable for each application +## OpenSC tools +* `opensc-notify` + * add Exit button to tray icon + * User better description (GenericName) and a generic application icon + * Do not display in the application list +* `pkcs15-tool` + * added support for reading ECDSA ssh keys +* `p11test` + * Filter certificates other than `CKC_X_509` +* `opengpg-tool` + * allow calling -d multiple times + * clarify usage text +## sc-hsm +* Implement RSA PSS +* Add support for SmartCard-HSM 4K (V3.0) +## CAC +* Remove support for CAC1 cards +* Ignore unknown tags in properties buffer +* Use GET PROPERTIES to recognize buffer formats +* Unbreak encoding last tag-len-value in the data objects +* Support HID Alt tokens without CCC + * They present certificates in OIDs of first AID and use other undocumented applets + * Inspect the tokens through the ACA applet and GET ACR APDU +## Coolkey +* Unbreak Get Challenge functionality +* Make uninitialized cards working as expected with ESC +## OpenPGP +* add serial number to card name +* include detailed version into card name +* define & set LCS (lifecycle support) as extended capability +* extend manufacturer list in pkcs15-openpgp.c +* correctly parse hist_bytes +* Make deciphering with AUT-key possible for OpenPGP Card >v3.2 (fixes #1352) +* Add supported algorithms for OpenPGP Card (Fixes #1432) +## Starcos +* added support for 2nd generation eGK (#1451) +## CardOS +* create PIN in MF (`pkcs15init`) +## German ID card +* fixed identifying unknown card as German ID card (#1360) +## PIV +* Context Specific Login Using Pin Pad Reader Fix +* Better Handling of Reset using Discovery Object + # New in 0.18.0; 2018-05-16 ## General Improvements * PKCS#15 @@ -42,7 +131,7 @@ NEWS for OpenSC -- History of user visible changes * fixed overwriting digestinfo + hash for RSA-PKCS Signature * Enable support for RSA-PSS signatures in pkcs11-tool * Add support for RSA-OAEP - * Fixed #1286 + * Fixed #1286 * Add missing pkcs11-tool options to man page * allow mechanism to be specified in hexadecimal * fixed default module path on Windows to use opensc-pkcs11.dll @@ -295,7 +384,7 @@ New in 0.16.0; 2016-05-15 first support for Gids smart card * dnie * Feitian PKI card - new ATRs + new ATRs * IsoApplet (fixes) * starcos @@ -438,7 +527,7 @@ New in 0.14.0; 2014-05-31 ECC public key encoding ECC ecpointQ * pkcs15init - introduce 'max-unblocks' PIN init parameter + introduce 'max-unblocks' PIN init parameter keep cert. blob in cert-info data file 'content' and 'prop-attrs' in the card profile in profile more AC operations are parsed @@ -460,7 +549,7 @@ New in 0.14.0; 2014-05-31 documentation for --list-token-slots * default driver do not send possibly arbitrary APDU-s to an unknown card. - by default 'default' card driver is disabled + by default 'default' card driver is disabled * sc-hsm Added support for persistent EC public keys generated from certificate signing requests @@ -498,7 +587,7 @@ New in 0.14.0; 2014-05-31 * myeid fixed file-id in myeid.profile * entersafe - fix a bug when writing public key + fix a bug when writing public key * EstEID match card only based on presence of application. * pteid @@ -613,7 +702,7 @@ New in 0.12.0; 2010-12-22 certificate for card label. * Possibility to change the default behavior for card resets via opensc.conf. - + New in 0.11.12; 2009-12-18; Andreas Jellinghaus * Document integer problem in OpenSC and implement workaround * Improve entersafe profile to support private data objects @@ -644,12 +733,12 @@ New in 0.11.7; 2009-02-26; Andreas Jellinghaus New in 0.11.6; 2008-08-27; Andreas Jellinghaus * Improved security fix: don't match for "OpenSC" in the card label. * New support for Feitian ePass3000 by Weitao Sun. -* GemSafeV1 improved to handle key_ref other than 3 by Douglas E. Engert +* GemSafeV1 improved to handle key_ref other than 3 by Douglas E. Engert New in 0.11.5; 2008-07-31; Andreas Jellinghaus * Apply security fix for cardos driver and extend pkcs15-tool to test cards for the security vulnerability and update them. -* Build system rewritten (NOTICE: configure options was modified). +* Build system rewritten (NOTICE: configure options was modified). The build system can produce outputs for *NIX, cygwin and native windows (using mingw). * ruToken now supported. diff --git a/appveyor.yml b/appveyor.yml index 9bb1c94274..ef737c068e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.18.0.{build} +version: 0.19.0.{build} platform: - x86 From 430a9b3f5a095d0ced154b55b4eb22139c5d017b Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 12 Sep 2018 13:21:40 +0300 Subject: [PATCH 0486/4321] Commit c463985fedbf55f7d4ab5c2bee764b74993bdbf1 broke EstEID PIN verify Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 386b275857..ea1a52dbfa 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1489,7 +1489,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, return SC_SUCCESS; } - if (SC_CARD_TYPE_MCRD_GENERIC) { + if (card->type == SC_CARD_TYPE_MCRD_GENERIC) { sc_log(card->ctx, "modify pin reference for D-Trust\n"); if (data->pin_reference == 0x02) data->pin_reference = data->pin_reference | 0x80; From 66fe0603639724c981900250f4c91681b828740f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Sep 2018 13:09:12 +0200 Subject: [PATCH 0487/4321] fixed gcc 8 compiler waring closes https://github.com/OpenSC/OpenSC/pull/1474 --- src/libopensc/card-gids.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index bdf2e1f749..002faee50b 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1133,7 +1133,7 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } } - snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", key_info->key_reference); + snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & key_info->key_reference)); sc_format_path(ch_tmp, &(key_info->path)); return SC_SUCCESS; } @@ -1477,7 +1477,7 @@ static int gids_delete_key_file(sc_card_t *card, int containernum) { int r; char ch_tmp[10]; sc_path_t cpath; - snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X",containernum + GIDS_FIRST_KEY_IDENTIFIER); + snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & (containernum + GIDS_FIRST_KEY_IDENTIFIER))); sc_format_path(ch_tmp, &cpath); r = gids_select_file(card, &cpath, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select the key file"); From f885ee4a17a1bbb389775988898a01547c33b4d6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Sep 2018 14:35:42 +0200 Subject: [PATCH 0488/4321] opensc.conf: Make the example syntax correct --- etc/opensc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/opensc.conf b/etc/opensc.conf index eab9b44c5f..4243d7caa9 100644 --- a/etc/opensc.conf +++ b/etc/opensc.conf @@ -1,6 +1,6 @@ app default { # debug = 3; - # debug_file = opensc-debug.txt + # debug_file = opensc-debug.txt; framework pkcs15 { # use_file_caching = true; } From 3750d7010608e8c8d6bf6fb457a75d957a0addb8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Sep 2018 13:04:12 +0200 Subject: [PATCH 0489/4321] pgp: detect gnuk with newer fw closes https://github.com/OpenSC/OpenSC/issues/1475 --- src/libopensc/card-openpgp.c | 6 +++++- win32/customactions.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index a1ef73768c..c7df20e84a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -59,7 +59,11 @@ static const char default_cardname_v3[] = "OpenPGP card v3.x"; static const 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, default_cardname_v1, SC_CARD_TYPE_OPENPGP_V1, 0, NULL }, { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, default_cardname_v2, SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, - { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, + { + "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", + "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:00", + "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL + }, { "3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1", NULL, "Yubikey NEO (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4", NULL, "Yubikey 4 (OpenPGP v2.1)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, { "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:f5:73:c0:01:60:00:90:00:1c", NULL, default_cardname_v3, SC_CARD_TYPE_OPENPGP_V3, 0, NULL }, diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 8fecceaed2..e3263fa808 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -106,7 +106,7 @@ MD_REGISTRATION minidriver_registration[] = { {TEXT("OpenPGP card v2.x"), {0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xc5,0x73,0xc0,0x01,0x40,0x00,0x90,0x00,0x0c}, 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Gnuk v1.0.x (OpenPGP v2.0)"), {0x3b,0xda,0x11,0xff,0x81,0xb1,0xfe,0x55,0x1f,0x03,0x00,0x31,0x84,0x73,0x80,0x01,0x80,0x00,0x90,0x00,0xe4}, - 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x00}}, {TEXT("OpenPGP card v3.x"), {0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xf5,0x73,0xc0,0x01,0x60,0x00,0x90,0x00,0x1c}, 21, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, /* from card-masktech.c */ From f1691fc91fc113191c3a8aaf5facd6983334ec47 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Sep 2018 13:47:21 +0200 Subject: [PATCH 0490/4321] updated NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 2851c5d2c9..0c35bfab4d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.19.0; 2018-09-12 +# New in 0.19.0; 2018-09-13 ## General Improvements * fixed multiple security problems (out of bound writes/reads, #1447): * CVE-2018-16391 From 9d16e6e177546a5809502867eb59d9334832a477 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 22 Aug 2018 19:56:47 +0300 Subject: [PATCH 0491/4321] openssl: Use define for openssl minimum version specification --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 3769757a79..66dae37bab 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,8 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(version.m4.ci) +m4_define([openssl_minimum_version], [0.9.7]) + AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_HEADERS([config.h]) @@ -610,11 +612,11 @@ fi PKG_CHECK_MODULES( [OPENSSL], - [libcrypto >= 0.9.7], + [libcrypto >= openssl_minimum_version], [have_openssl="yes"], [PKG_CHECK_MODULES( [OPENSSL], - [openssl >= 0.9.7], + [openssl >= openssl_minimum_version], [have_openssl="yes"], [AC_CHECK_LIB( [crypto], From 9fa730bb95fe01374b154020691a83c00d8b5187 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 22 Aug 2018 20:04:29 +0300 Subject: [PATCH 0492/4321] openssl: PKG_CHECK_MODULES can take a list of packages. Use this for openssl --- configure.ac | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 66dae37bab..2f9ef56ea0 100644 --- a/configure.ac +++ b/configure.ac @@ -612,21 +612,19 @@ fi PKG_CHECK_MODULES( [OPENSSL], - [libcrypto >= openssl_minimum_version], + [ + libcrypto >= openssl_minimum_version + openssl >= openssl_minimum_version + ], [have_openssl="yes"], - [PKG_CHECK_MODULES( - [OPENSSL], - [openssl >= openssl_minimum_version], - [have_openssl="yes"], - [AC_CHECK_LIB( - [crypto], - [RSA_version], - [ - have_openssl="yes" - OPENSSL_LIBS="-lcrypto" - ], - [have_openssl="no"] - )] + [AC_CHECK_LIB( + [crypto], + [RSA_version], + [ + have_openssl="yes" + OPENSSL_LIBS="-lcrypto" + ], + [have_openssl="no"] )] ) From 1f06a76b1adc0dcb40bddc3868bdccf273f7c8ab Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Wed, 22 Aug 2018 20:26:33 +0300 Subject: [PATCH 0493/4321] openssl: Bump openssl requirement to 0.9.8 --- configure.ac | 2 +- src/libopensc/card-iasecc.c | 6 ------ src/libopensc/card-oberthur.c | 8 -------- src/libopensc/sc-ossl-compat.h | 35 --------------------------------- src/pkcs11/framework-pkcs15.c | 4 ---- src/pkcs11/openssl.c | 4 ---- src/pkcs15init/pkcs15-westcos.c | 13 ------------ src/smm/sm-cwa14890.c | 5 ----- src/tools/gids-tool.c | 4 +--- src/tools/piv-tool.c | 12 +++++------ src/tools/pkcs11-tool.c | 16 +++------------ src/tools/pkcs15-init.c | 4 +--- src/tools/sc-hsm-tool.c | 5 ----- src/tools/westcos-tool.c | 13 ------------ 14 files changed, 11 insertions(+), 120 deletions(-) diff --git a/configure.ac b/configure.ac index 2f9ef56ea0..1d75e5a461 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(version.m4.ci) -m4_define([openssl_minimum_version], [0.9.7]) +m4_define([openssl_minimum_version], [0.9.8]) AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) AC_CONFIG_AUX_DIR([.]) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index dcd4a83198..254f8aa5ee 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -3152,7 +3152,6 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L static int iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len, struct iasecc_qsign_data *out) @@ -3203,7 +3202,6 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t LOG_FUNC_RETURN(ctx, SC_SUCCESS); } -#endif static int @@ -3234,11 +3232,7 @@ iasecc_compute_signature_dst(struct sc_card *card, rv = iasecc_qsign_data_sha1(card->ctx, in, in_len, &qsign_data); } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L rv = iasecc_qsign_data_sha256(card->ctx, in, in_len, &qsign_data); -#else - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "SHA256 is not supported by OpenSSL previous to v0.9.8"); -#endif } else LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_HASH_SHA1 or RSA_HASH_SHA256 algorithm"); diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 4d08a59c68..6ca49f1a42 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -47,14 +47,6 @@ #define OBERTHUR_PIN_REFERENCE_SO 0x04 #define OBERTHUR_PIN_REFERENCE_PUK 0x84 -/* keep OpenSSL 0.9.6 users happy ;-) */ -#if OPENSSL_VERSION_NUMBER < 0x00907000L -#define DES_cblock des_cblock -#define DES_key_schedule des_key_schedule -#define DES_set_key_unchecked(a,b) des_set_key_unchecked(a,*b) -#define DES_ecb_encrypt(a,b,c,d) des_ecb_encrypt(a,b,*c,d) -#endif - static const struct sc_atr_table oberthur_atrs[] = { { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", NULL, "Oberthur 64k v4/2.1.1", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL }, diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 8ef5a9468a..9185dd078d 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -41,41 +41,6 @@ extern "C" { * */ -/* - * EVP_CIPHER_CTX functions: - * EVP_CIPHER_CTX_new not in 0.9.7 - * EVP_CIPHER_CTX_free not in 0.9.7 - * EVP_CIPHER_CTX_init in 0.9.7 to 1.0.2. defined in 1.1 as EVP_CIPHER_CTX_reset - * EVP_CIPHER_CTX_cleanup in 0.9.7 to 1.0.2, defined in 1.1 as EVP_CIPHER_CTX_reset - * EVP_CIPHER_CTX_reset only in 1.1 - * - * EVP_CIPHER_CTX_new does a EVP_CIPHER_CTX_init - * EVP_CIPHER_CTX_free does a EVP_CIPHER_CTX_cleanup - * EVP_CIPHER_CTX_cleanup does equivalent of a EVP_CIPHER_CTX_init - * Use EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free, and EVP_CIPHER_CTX_cleanup between operations - */ - -#if OPENSSL_VERSION_NUMBER <= 0x009070dfL - -/* in 0.9.7 EVP_CIPHER_CTX was always allocated inline or in other structures */ - -#define EVP_CIPHER_CTX_new() ({ \ - EVP_CIPHER_CTX * tmp = NULL; \ - tmp = OPENSSL_malloc(sizeof(struct evp_cipher_ctx_st)); \ - if (tmp) { \ - EVP_CIPHER_CTX_init(tmp); \ - } \ - tmp; \ - }) - -#define EVP_CIPHER_CTX_free(x) ({ \ - if (x) { \ - EVP_CIPHER_CTX_cleanup(x); \ - OPENSSL_free(x); \ - } \ - }) -#endif /* OPENSSL_VERSION_NUMBER =< 0x00907000L */ - /* * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL * use RSA_PKCS1_OpenSSL diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 2ab4b5744d..3e881e667f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5017,10 +5017,6 @@ register_mechanisms(struct sc_pkcs11_card *p11card) */ if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { rsa_flags |= SC_ALGORITHM_RSA_HASHES; -#if OPENSSL_VERSION_NUMBER < 0x00908000L - /* turn off hashes not in openssl 0.9.8 */ - rsa_flags &= ~(SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA384 | SC_ALGORITHM_RSA_HASH_SHA512 | SC_ALGORITHM_RSA_HASH_SHA224); -#endif } #endif diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 9482e2a71a..59de1210d5 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -68,7 +68,6 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { NULL, /* free_mech_data */ }; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { CKM_SHA256, { 0, 0, CKF_DIGEST }, @@ -119,7 +118,6 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { NULL, /* mech_data */ NULL, /* free_mech_data */ }; -#endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { @@ -233,14 +231,12 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) openssl_sha1_mech.mech_data = EVP_sha1(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech)); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L openssl_sha256_mech.mech_data = EVP_sha256(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech)); openssl_sha384_mech.mech_data = EVP_sha384(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech)); openssl_sha512_mech.mech_data = EVP_sha512(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech)); -#endif openssl_md5_mech.mech_data = EVP_md5(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech)); openssl_ripemd160_mech.mech_data = EVP_ripemd160(); diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index b6d98a3ca5..81dad1fdd5 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -227,7 +227,6 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, return SC_ERROR_NOT_SUPPORTED; } -#if OPENSSL_VERSION_NUMBER>=0x00908000L rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); @@ -240,18 +239,6 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL)) -#else - mem = BIO_new(BIO_s_mem()); - - if(mem == NULL) - { - r = SC_ERROR_OUT_OF_MEMORY; - goto out; - } - - rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL); - if (!rsa) -#endif { r = SC_ERROR_UNKNOWN; goto out; diff --git a/src/smm/sm-cwa14890.c b/src/smm/sm-cwa14890.c index fc3ff4d6d8..d2752949c9 100644 --- a/src/smm/sm-cwa14890.c +++ b/src/smm/sm-cwa14890.c @@ -206,7 +206,6 @@ sm_cwa_init_session_keys(struct sc_context *ctx, struct sm_cwa_session *session_ memcpy(&session_data->session_mac[0], buff, sizeof(session_data->session_mac)); } else if (mechanism == IASECC_ALGORITHM_SYMMETRIC_SHA256) { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L xored[35] = 0x01; SHA256(xored, 36, buff); memcpy(&session_data->session_enc[0], buff, sizeof(session_data->session_enc)); @@ -214,10 +213,6 @@ sm_cwa_init_session_keys(struct sc_context *ctx, struct sm_cwa_session *session_ xored[35] = 0x02; SHA256(xored, 36, buff); memcpy(&session_data->session_mac[0], buff, sizeof(session_data->session_mac)); -#else - sc_log(ctx, "No FIPS, SHA256 is not supported"); - return SC_ERROR_INVALID_ARGUMENTS; -#endif } else { return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index cdee57459f..3ae56e7485 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -39,9 +39,7 @@ #include #include #endif -#if OPENSSL_VERSION_NUMBER >= 0x00907000L #include -#endif #include #include @@ -530,7 +528,7 @@ int main(int argc, char * argv[]) /* OpenSSL magic */ -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) OPENSSL_config(NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 9a3645b00b..6dc8213d04 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -38,12 +38,10 @@ #include #include #endif -#if OPENSSL_VERSION_NUMBER >= 0x00907000L #include -#endif #include -#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include #include #endif @@ -292,7 +290,7 @@ static int gen_key(const char * key_info) keydata = {0, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0}; unsigned long expl; u8 expc[4]; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) +#if !defined(OPENSSL_NO_EC) int nid = -1; #endif sc_hex_to_bin(key_info, buf, &buflen); @@ -316,7 +314,7 @@ static int gen_key(const char * key_info) case 0x05: keydata.key_bits = 3072; break; case 0x06: keydata.key_bits = 1024; break; case 0x07: keydata.key_bits = 2048; break; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) +#if !defined(OPENSSL_NO_EC) case 0x11: keydata.key_bits = 0; nid = NID_X9_62_prime256v1; /* We only support one curve per algid */ break; @@ -368,7 +366,7 @@ static int gen_key(const char * key_info) EVP_PKEY_assign_RSA(evpkey, newkey); } else { /* EC key */ -#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) +#if !defined(OPENSSL_NO_EC) int i; BIGNUM *x; BIGNUM *y; @@ -558,7 +556,7 @@ int main(int argc, char *argv[]) util_print_usage_and_die(app_name, options, option_help, NULL); -//#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +//#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) // OPENSSL_config(NULL); //#endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index aefbabf696..64525f6ad2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -41,16 +41,14 @@ #include #include #endif -#if OPENSSL_VERSION_NUMBER >= 0x00907000L #include -#endif #include #include #include #include #include #include -#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include #include #endif @@ -570,7 +568,7 @@ int main(int argc, char * argv[]) #endif #ifdef ENABLE_OPENSSL -#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) OPENSSL_config(NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) @@ -3310,7 +3308,7 @@ static void show_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) static CK_OBJECT_HANDLE derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE mech_mech) { -#if defined(ENABLE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) +#if defined(ENABLE_OPENSSL) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) CK_MECHANISM mech; CK_OBJECT_CLASS newkey_class= CKO_SECRET_KEY; CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET; @@ -4412,9 +4410,7 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, EVP_sha1(), EVP_md5(), EVP_ripemd160(), -#if OPENSSL_VERSION_NUMBER >= 0x00908000L EVP_sha256(), -#endif }; #endif @@ -4497,9 +4493,7 @@ static int test_signature(CK_SESSION_HANDLE sess) CKM_SHA1_RSA_PKCS, CKM_MD5_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, -#if OPENSSL_VERSION_NUMBER >= 0x00908000L CKM_SHA256_RSA_PKCS, -#endif 0xffffff }; size_t mechTypes_num = sizeof(mechTypes)/sizeof(CK_MECHANISM_TYPE); @@ -5110,11 +5104,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, EVP_PKEY_free(pkey); return 0; } -#if OPENSSL_VERSION_NUMBER >= 0x00909000L encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); -#else - encrypted_len = EVP_PKEY_encrypt(encrypted, orig_data, sizeof(orig_data), pkey); -#endif EVP_PKEY_free(pkey); if (((int) encrypted_len) <= 0) { printf("Encryption failed, returning\n"); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 1ce79f45d0..fd975b0ae8 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -40,9 +40,7 @@ #endif #include #include "libopensc/sc-ossl-compat.h" -#if OPENSSL_VERSION_NUMBER >= 0x00907000L #include -#endif #include #include #include @@ -453,7 +451,7 @@ main(int argc, char **argv) unsigned int n; int r = 0; -#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_config(NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !(defined LIBRESSL_VERSION_NUMBER) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 9c1d7c1ba3..02cdfcc6c3 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -161,12 +161,7 @@ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigne do { // Generate random prime -#if OPENSSL_VERSION_NUMBER >= 0x00908000L /* last parm is BN_GENCB which is null in our case */ BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL); -#else - BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL ); -#endif - } while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0)); // If prime < s or not reached 1000 tries if (max_rounds > 0) diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index e90845d78e..a4cd3a848a 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -589,7 +589,6 @@ int main(int argc, char *argv[]) printf("Generate key of length %d.\n", keylen); -#if OPENSSL_VERSION_NUMBER>=0x00908000L rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); @@ -602,18 +601,6 @@ int main(int argc, char *argv[]) if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, keylen, bn, NULL)) -#else - rsa = RSA_generate_key(keylen, RSA_F4, NULL, NULL); - mem = BIO_new(BIO_s_mem()); - - if(mem == NULL) - { - printf("Not enough memory.\n"); - goto out; - } - - if (!rsa) -#endif { printf("RSA_generate_key_ex return %ld\n", ERR_get_error()); goto out; From e36c1468e5605d178acfbbf1fb10ca2bbf8dc3c4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 16 Jul 2018 09:26:32 +0200 Subject: [PATCH 0494/4321] md: derive md_read_only from PKCS#15 profile --- src/minidriver/minidriver.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index c719c55675..fc57ff09b5 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -684,8 +684,22 @@ md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) static BOOL md_is_read_only(PCARD_DATA pCardData) { + BOOL ret = TRUE; + logprintf(pCardData, 2, "Is read-only?\n"); - return md_get_config_bool(pCardData, "md_read_only", TRUE); + + if (pCardData && pCardData->pvVendorSpecific) { + VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (vs->p15card && vs->p15card->tokeninfo) { + if (vs->p15card->tokeninfo->flags & SC_PKCS15_TOKEN_READONLY) { + ret = TRUE; + } else { + ret = FALSE; + } + } + } + + return md_get_config_bool(pCardData, "md_read_only", ret); } From db4ed9f4a27f6e7d36800f45fcb8ca72fb91dd5d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 15:19:21 +0200 Subject: [PATCH 0495/4321] export _sc_match_atr_block --- src/libopensc/libopensc.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 2daea3e2ae..2d9b5e439a 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -348,6 +348,7 @@ iasecc_sdo_encode_update_field _sc_card_add_ec_alg _sc_card_add_rsa_alg _sc_match_atr +_sc_match_atr_block _sc_log eac_secret_name get_pace_capabilities From 129946ca969f39ce7d7f1c8a6642f4e80e7aec4a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 16 Jul 2018 22:19:24 +0200 Subject: [PATCH 0496/4321] pkcs11: CKF_WRITE_PROTECTED based on card's read_only flag uses `md_read_only` as `read_only` for both, PKCS#11 and Minidriver --- doc/files/opensc.conf.5.xml.in | 4 ++-- etc/opensc.conf.example.in | 42 +++++++++++++++++----------------- src/minidriver/minidriver.c | 2 +- src/pkcs11/framework-pkcs15.c | 15 ++++++++++++ 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index b0cb4e75e7..f703ce7110 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -822,11 +822,11 @@ app application { - + Mark card as read/only card in - Minidriver/BaseCSP interface + PKCS#11/Minidriver/BaseCSP interface (Default: false). diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index d8abb8f811..dc3b5bd865 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -282,7 +282,7 @@ app default { # Context: minidriver # - # md_read_only: Mark card as read/only card in Minidriver/BaseCSP interface (Default: false) + # read_only: Mark card as read/only card in Minidriver/BaseCSP interface (Default: false) # md_supports_X509_enrollment: Indicate X509 enrollment support at Minidriver/BaseCSP interface (Default: false) # md_guid_as_id: Use the GUID generated for the key as id in the PKCS#15 structure (Default: false, i.e. auto generated) # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false, i.e. no label set) @@ -396,7 +396,7 @@ app default { name = "Gemalto MultiApp IAS/ECC v1.0.1"; secure_messaging = local_gemalto_iam; # secure_messaging = local_adele; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; } card_atr 3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00 { @@ -404,7 +404,7 @@ app default { driver = "iasecc"; name = "Gemalto MultiApp IAS/ECC v1.0.1"; secure_messaging = local_gemalto_iam; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; } #card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:FE { @@ -423,7 +423,7 @@ app default { # type = 25005; # driver = "iasecc"; # name = "Morpho MI IAS/ECC v1.0.1"; - # md_read_only = false; + # read_only = false; # md_supports_X509_enrollment = true; # secure_messaging = local_morpho_mi; #} @@ -431,7 +431,7 @@ app default { type = 25004; driver = "iasecc"; name = "Amos IAS/ECC v1.0.1"; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; secure_messaging = local_amos; } @@ -439,7 +439,7 @@ app default { type = 25004; driver = "iasecc"; name = "Amos IAS/ECC v1.0.1"; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; secure_messaging = local_amos_eid; } @@ -447,7 +447,7 @@ app default { # SmartCard-HSM with contact-based interface or USB-Stick card_atr 3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA { driver = "sc-hsm"; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -456,7 +456,7 @@ app default { # SmartCard-HSM with contact-less interface card_atr 3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18 { driver = "sc-hsm"; - md_read_only = false; + read_only = false; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -465,7 +465,7 @@ app default { # SmartCard-HSM with fingerprint sensor and PIN pad card_atr 3B:80:80:01:01 { force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -489,7 +489,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -512,7 +512,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -535,7 +535,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -558,7 +558,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -581,7 +581,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -604,7 +604,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -627,7 +627,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -650,7 +650,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -673,7 +673,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -697,7 +697,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -721,7 +721,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; @@ -745,7 +745,7 @@ app default { atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00"; driver = "sc-hsm"; force_protocol = "t1"; - md_read_only = false; + read_only = true; md_supports_X509_enrollment = true; md_supports_container_key_gen = true; md_guid_as_label = true; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index fc57ff09b5..3570a07b00 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -699,7 +699,7 @@ md_is_read_only(PCARD_DATA pCardData) } } - return md_get_config_bool(pCardData, "md_read_only", ret); + return md_get_config_bool(pCardData, "read_only", ret); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3e881e667f..cc4b1e80fb 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1045,6 +1045,8 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, struct pkcs15_slot_data *fw_data; struct sc_pkcs15_auth_info *pin_info = NULL; char label[(sizeof auth->label) + 10]; + int write_protected; + scconf_block *atrblock; sc_log(context, "Called"); pkcs15_init_token_info(p15card, &slot->token_info); @@ -1058,6 +1060,19 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, if (p15card->card->caps & SC_CARD_CAP_RNG && p15card->card->ops->get_challenge != NULL) slot->token_info.flags |= CKF_RNG; + if (p15card->tokeninfo && p15card->tokeninfo->flags & SC_PKCS15_TOKEN_READONLY) { + write_protected = 1; + } else { + write_protected = 0; + } + atrblock = _sc_match_atr_block(p15card->card->ctx, NULL, &p15card->card->atr); + if (atrblock) { + write_protected = scconf_get_bool(atrblock, "read_only", write_protected); + } + if (write_protected) { + slot->token_info.flags |= CKF_WRITE_PROTECTED; + } + slot->fw_data = fw_data = calloc(1, sizeof(*fw_data)); if (!fw_data) { return; From 00d1501ae666b08fb62403cfa2da2c7669f0eda5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Aug 2018 16:16:33 +0200 Subject: [PATCH 0497/4321] pkcs11: fail in C_CreateObject/C_DestroyObject if write protected --- src/pkcs11/pkcs11-object.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index bdf8845cfb..0cc77d604e 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -114,6 +114,11 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * goto out; } + if (session->slot->token_info.flags & CKF_WRITE_PROTECTED) { + rv = CKR_TOKEN_WRITE_PROTECTED; + goto out; + } + card = session->slot->p11card; if (card->framework->create_object == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; @@ -156,7 +161,7 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */ struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; CK_BBOOL is_token = FALSE; - CK_ATTRIBUTE token_attribure = {CKA_TOKEN, &is_token, sizeof(is_token)}; + CK_ATTRIBUTE token_attribute = {CKA_TOKEN, &is_token, sizeof(is_token)}; rv = sc_pkcs11_lock(); if (rv != CKR_OK) @@ -167,10 +172,16 @@ C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv != CKR_OK) goto out; - object->ops->get_attribute(session, object, &token_attribure); - if (is_token == TRUE && !(session->flags & CKF_RW_SESSION)) { - rv = CKR_SESSION_READ_ONLY; - goto out; + object->ops->get_attribute(session, object, &token_attribute); + if (is_token == TRUE) { + if (session->slot->token_info.flags & CKF_WRITE_PROTECTED) { + rv = CKR_TOKEN_WRITE_PROTECTED; + goto out; + } + if (!(session->flags & CKF_RW_SESSION)) { + rv = CKR_SESSION_READ_ONLY; + goto out; + } } if (object->ops->destroy_object == NULL) From 4fad530e9a76aaca17a5365d58ea98071b74d20e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 14 Sep 2018 08:31:44 +0200 Subject: [PATCH 0498/4321] appveyor: fixed msi naming --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ef737c068e..f9ae1da301 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,11 +30,11 @@ install: If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:OPENSSL_PF="Win32" - $env:ARTIFACT="OpenSC-win32_${env:PACKAGE_NAME}" + $env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}_win32" } Else { $env:VCVARS_PLATFORM="amd64" $env:OPENSSL_PF="Win64" - $env:ARTIFACT="OpenSC-win64_${env:PACKAGE_NAME}" + $env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}_win64" } - ps: >- If ($env:Configuration -Like "*Light*") { From 9d44adbc4e174f7cb562181a4bc5b003fbc039fb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 14 Sep 2018 10:36:50 +0200 Subject: [PATCH 0499/4321] Missing header release tarball --- src/tests/p11test/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index a7e88f1b48..bbfc96778b 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -8,7 +8,8 @@ noinst_HEADERS = p11test_loader.h p11test_case_common.h \ p11test_case_readonly.h p11test_case_multipart.h \ p11test_case_mechs.h p11test_case_ec_sign.h \ p11test_case_usage.h p11test_case_wait.h \ - p11test_case_pss_oaep.h p11test_helpers.h + p11test_case_pss_oaep.h p11test_helpers.h \ + p11test_common.h AM_CPPFLAGS = -I$(top_srcdir)/src From c69f10c2ab21c93f1bae5b4bddbba4d35cba5cab Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 17 Jun 2018 12:52:19 +0200 Subject: [PATCH 0500/4321] opensc-explorer: add command 'pin_info' Get information on a PIN or key from the card via sc_pin_cmd()'s SC_PIN_CMD_GET_INFO functionality. --- doc/tools/opensc-explorer.1.xml | 12 +++++++ src/tools/opensc-explorer.c | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 23b90966eb..30312aa764 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -352,6 +352,18 @@ and size is the size of the new file. + + + pin_info + key-typekey-id + + Get information on a PIN or key from the card, where + key-type can be one of CHV, + KEY, AUT or PRO. + key-id is a number representing the key or PIN reference. + + + put diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 8dc02bc50d..d45c597efd 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -92,6 +92,7 @@ static int do_info(int argc, char **argv); static int do_create(int argc, char **argv); static int do_mkdir(int argc, char **argv); static int do_delete(int argc, char **argv); +static int do_pininfo(int argc, char **argv); static int do_verify(int argc, char **argv); static int do_change(int argc, char **argv); static int do_unblock(int argc, char **argv); @@ -152,6 +153,9 @@ static struct command cmds[] = { { do_delete, "rm", "", "remove an EF/DF" }, + { do_pininfo, + "pin_info", "{CHV|KEY|AUT|PRO}", + "get information on PIN or key from the card" }, { do_verify, "verify", "{CHV|KEY|AUT|PRO} []", "present a PIN or key to the card" }, @@ -1083,6 +1087,60 @@ static int do_delete(int argc, char **argv) return 0; } +static int do_pininfo(int argc, char **argv) +{ + const id2str_t typeNames[] = { + { SC_AC_CHV, "CHV" }, + { SC_AC_AUT, "KEY" }, + { SC_AC_AUT, "AUT" }, + { SC_AC_PRO, "PRO" }, + { SC_AC_NONE, NULL, } + }; + int r, tries_left = -1; + size_t i; + struct sc_pin_cmd_data data; + int prefix_len = 0; + + if (argc != 1) + return usage(do_pininfo); + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_GET_INFO; + + data.pin_type = SC_AC_NONE; + for (i = 0; typeNames[i].str; i++) { + prefix_len = strlen(typeNames[i].str); + if (strncasecmp(argv[0], typeNames[i].str, prefix_len) == 0) { + data.pin_type = typeNames[i].id; + break; + } + } + if (data.pin_type == SC_AC_NONE) { + printf("Invalid type.\n"); + return usage(do_pininfo); + } + if (sscanf(argv[0] + prefix_len, "%d", &data.pin_reference) != 1) { + printf("Invalid key reference.\n"); + return usage(do_pininfo); + } + + r = sc_lock(card); + if (r == SC_SUCCESS) + r = sc_pin_cmd(card, &data, &tries_left); + sc_unlock(card); + + if (r) { + printf("Unable to get PIN info: %s\n", sc_strerror(r)); + return -1; + } + if (tries_left > 0) + printf("Logged %s, %d tries left.\n", + (data.pin1.logged_in) ? "in" : "out", tries_left); + else + printf("Logged %s\n.", (data.pin1.logged_in) ? "in" : "out"); + return 0; +} + static int do_verify(int argc, char **argv) { const id2str_t typeNames[] = { From fa2421c89d54ed408634bb6cc72c64abf492a74a Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 30 Jun 2018 19:28:29 +0200 Subject: [PATCH 0501/4321] opensc-explorer: overhaul man page - harmonize structure - add missing commands (e.g. '#') - extend description of commands - fix description of commands (e.g. 'do_put') --- doc/tools/opensc-explorer.1.xml | 353 +++++++++++++++++++++++--------- 1 file changed, 259 insertions(+), 94 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 30312aa764..bcb4569b81 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -56,12 +56,15 @@ path, path - - Select the file referenced by the given path on - startup. The default is the path to the standard master file, - 3F00. If path is empty (e.g. opensc-explorer - --mf ""), then no file is explicitly selected. - + + + Select the file referenced by the given path on startup. + The default is the path to the standard master file, + 3F00. If path + is empty (e.g. opensc-explorer --mf ""), + then no file is explicitly selected. + + @@ -81,17 +84,23 @@ , - - Causes opensc-explorer to be more - verbose. Specify this flag several times to enable - debug output in the opensc library. - + + + Cause opensc-explorer to be more + verbose. Specify this flag several times to enable + debug output in the opensc library. + + , - Wait for a card to be inserted + + + Wait for a card to be inserted. + + @@ -104,13 +113,32 @@ interactive prompt or in script files passed via the command line parameter SCRIPT. + + + # + + + + + Treat line as a comment. + Ignore anything until the end of the line introduced by + #. + + + + apdu - hex-data + data - Send a custom APDU command hex-data. + + Send a custom APDU command to the card. + data is a series of + sequences of hexadecimal values and strings enclosed + in double quotes ("..."). + @@ -119,8 +147,12 @@ asn1 file-id - Parse and print the ASN.1 encoded content of the file specified by - file-id. + + + Parse and print the ASN.1 encoded content of the working EF + specified by file-id. + + @@ -131,10 +163,15 @@ sfi:short-id - Print the contents of the currently selected EF or the contents - of a file specified by file-id or the short file id + + + Print the contents of the working EF specified by + file-id or the short file id short-id. - + If no argument is given, print the the contents + of the currently selected EF. + + @@ -146,18 +183,20 @@ aid:DF-name - + + Change to another DF specified by the argument passed. If the argument given is .., then move up one level in the file system hierarchy. - If it is file-id, + If it is a file-id, which must be a DF directly beneath the current DF, then change to that DF. If it is an application identifier given as aid:DF-name, then jump to the MF of the application denoted by DF-name. - + + @@ -170,7 +209,19 @@ - Change a PIN, where pin-ref is the PIN reference. + + Change the PIN specified by pin-ref + from the value given by old-pin and + change its value to new-pin. + + + old-pin and + new-pin can be + sequences of hexadecimal values, + strings enclosed in double quotes ("..."), + empty (""), or absent. + If absent, the values are read from the card reader's pin pad. + Examples: @@ -206,9 +257,13 @@ file-id size - Create a new EF. file-id specifies the - id number and size is the size of the new file. - + + + Create a new EF. + file-id specifies the numeric id, and + size the size of the EF to create. + + @@ -217,8 +272,13 @@ level - Set OpenSC debug level to level. - If level is omitted the current debug level will be shown. + + Set OpenSC debug level to level. + + + If level is omitted, + show the current debug level. + @@ -227,7 +287,12 @@ delete file-id - Remove the EF or DF specified by file-id + + + Remove the EF or DF specified by + file-id. + + @@ -237,13 +302,17 @@ output - Copy the internal card's 'tagged' data into the local file. - The local file is specified by output while the tag of - the card's data is specified by hex-tag. + + Copy the contents of the card's data object + (DO) + specified by hex-tag + to the local host computer's file named + output. - If output is omitted, the name of the output file will be - derived from hex-tag. + If output is not given, + the contents of hex-tag + will be displayed as hex-dump. @@ -252,13 +321,19 @@ do_put hex-tag - input + data - Update internal card's 'tagged' data. - hex-tag is the tag of the card's data. - input is the filename of the source file or the literal data presented as - a sequence of hexadecimal values or " enclosed string. + + Change the contents of the card's data object + (DO) + specified by hex-tag + to data. + + + data + can be given either as a sequence of hexadecimal values, + or as string enclosed in double quotes ("..."), @@ -269,7 +344,9 @@ string - Print the strings given. + + Print the strings given. + @@ -277,7 +354,11 @@ erase - Erase the card, if the card supports it. + + + Erase the card, if the card supports it. + + @@ -287,12 +368,17 @@ output - Copy an EF to a local file. The local file is specified - by output while the card file is specified by file-id. + + Copy an EF to a local file. + The local file is specified by + output + while the card file is specified by + file-id. - If output is omitted, the name of the output file will be - derived from the full card path to file-id. + If output is omitted, + the name of the output file will be derived from the + full card path to file-id. @@ -302,9 +388,14 @@ info file-id - Display attributes of a file specified by file-id. + + + Display attributes of a file specified by + file-id. If file-id is not supplied, - the attributes of the current file are printed. + the attributes of the current file are displayed. + + @@ -312,10 +403,16 @@ ls pattern - List files in the current DF. - If no pattern is given, then all files are listed. - If one ore more patterns are given, only files matching - at least one pattern are listed. + + + List files in the current DF. + If no pattern is given, + then all files are listed. + If one ore more patterns are given, + only files matching at least one + pattern are listed. + + @@ -326,8 +423,20 @@ end-id - Find all files in the current DF. - Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF). + + + Find all files in the current DF. + Files are found by selecting all file identifiers in the range + from start-fid + to end-fid. + + + If not given, the default value for + start-fid is 0000, + while the default for end-fid is + FFFF. + + @@ -338,8 +447,20 @@ end-tag - Find all tags of data objects in the current context. - Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF). + + + Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from + from start-tag + to end-tag. + + + If not given, the default value for + start-tag is 0000, + while the default for end-tag is + FFFF. + + @@ -348,8 +469,13 @@ file-id size - Create a DF. file-id specifies the id number - and size is the size of the new file. + + + Create a DF. + file-id specifies the numeric id, + and size the size of the DF to create. + + @@ -357,11 +483,16 @@ pin_info key-typekey-id - Get information on a PIN or key from the card, where - key-type can be one of CHV, - KEY, AUT or PRO. - key-id is a number representing the key or PIN reference. - + + + Get information on a PIN or key from the card, where + key-type can be one of + CHV, KEY, + AUT or PRO. + key-id is a number + representing the key or PIN reference. + + @@ -370,9 +501,14 @@ file-id input - Copy a local file to the card. The local file is specified - by input while the card file is specified by file-id. - + + + Copy a local file to the card. + The local file is specified by input + while the card file is specified by + file-id. + + @@ -388,7 +524,9 @@ count - Generate random sequence of count bytes. + + Generate count bytes of random data. + @@ -397,7 +535,12 @@ rm file-id - Remove the EF or DF specified by file-id + + + Remove the EF or DF specified by + file-id. + + @@ -412,14 +555,16 @@ Unblock the PIN denoted by pin-ref - using the PUK puk, and set potentially + using the PUK puk, and potentially change its value to new-pin. - PUK and PIN values can be a sequence of hexadecimal values, - "-enclosed strings, empty (""), - or absent. - If they are absent, the values are read from the card reader's pin pad. + puk and + new-pin can be + sequences of hexadecimal values, + strings enclosed in double quotes ("..."), + empty (""), or absent. + If absent, the values are read from the card reader's pin pad. Examples: @@ -481,12 +626,17 @@ data - Binary update of the file specified by + + Binary update of the file specified by file-id with the literal data data starting from offset specified - by offs. - data can be supplied as a sequencer - of the hex values or as a " enclosed string. + by offs. + + + data can be supplied as a sequence + of hexadecimal values or as a string enclosed in double quotes + ("..."). + @@ -499,12 +649,18 @@ data - Update record specified by rec-nr of the file - specified by file-id with the literal data - data starting from offset specified by - rec-offs. - data can be supplied as a sequence of the hex values or - as a " enclosed string. + + Update record specified by rec-nr + of the file specified by file-id + with the literal data data + starting from offset specified by + rec-offs. + + + data can be supplied as a sequence + of hexadecimal values or as a string enclosed in double quotes + ("..."). + @@ -514,25 +670,31 @@ key-typekey-id key - Present a PIN or key to the card, where - key-type can be one of CHV, - KEY, AUT or PRO. - key-id is a number representing the key or PIN reference. - key is the key or PIN to be verified, formatted as a - colon-separated list of hex values or a " enclosed string. + + + Present a PIN or key to the card, where + key-type can be one of + CHV, KEY, + AUT or PRO. + key-id is a number representing + the key or PIN reference. + key is the key or PIN to be verified, + formatted as a colon-separated sequence of hexadecimal values + or a string enclosed in double quotes ("..."). - If key is omitted, the exact action depends on the - card reader's features: if the card readers supports PIN input via a pin pad, + If key is omitted, the exact action + depends on the card reader's features: + if the card readers supports PIN input via a pin pad, then the PIN will be verified using the card reader's pin pad. - If the card reader does not support PIN input, then the PIN will be asked - interactively. + If the card reader does not support PIN input, + then the PIN will be asked interactively. Examples: - verify CHV0 31:32:33:34:00:00:00:00 + verify CHV2 31:32:33:34:00:00:00:00 Verify CHV2 using the hex value 31:32:33:34:00:00:00:00 @@ -566,7 +728,10 @@ - Calls the card's open or close Secure Messaging handler. + + Call the card's open or + close Secure Messaging handler. + From aed4b001451e40f466c4e4273f84f45de8e0551d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 7 Jul 2018 22:04:13 +0200 Subject: [PATCH 0502/4321] opensc-explorer: harmonize display of command arguments * consistently show ellipsis for repeatable arguments as 3 dots * embrace alternative mandatory arguments with curly braces * use hyphens instead of spaces within non-literal arguments for improved alignment with the manual page --- src/tools/opensc-explorer.c | 48 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index d45c597efd..159dfa8c12 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -121,61 +121,61 @@ struct command { static struct command cmds[] = { { do_echo, - "echo", "[ ..]", + "echo", "[ ...]", "display arguments" }, { do_ls, - "ls", "[ ..]", + "ls", "[ ...]", "list files in the current DF" }, { do_find, - "find", "[ []]", + "find", "[ []]", "find all files in the current DF" }, { do_find_tags, - "find_tags", "[ []]", + "find_tags", "[ []]", "find all tags of data objects in the current context" }, { do_cd, - "cd", "{.. | | aid:}", + "cd", "{.. | | aid:}", "change to another DF" }, { do_cat, - "cat", "[ | sfi:]" + "cat", "[ | sfi:]" , "print the contents of an EF" }, { do_info, - "info", "[]", + "info", "[]", "display attributes of card file" }, { do_create, - "create", " ", + "create", " ", "create a new EF" }, { do_mkdir, - "mkdir", " ", + "mkdir", " ", "create a new DF" }, { do_delete, - "delete", "", + "delete", "", "remove an EF/DF" }, { do_delete, - "rm", "", + "rm", "", "remove an EF/DF" }, { do_pininfo, - "pin_info", "{CHV|KEY|AUT|PRO}", + "pin_info", "{CHV|KEY|AUT|PRO}", "get information on PIN or key from the card" }, { do_verify, - "verify", "{CHV|KEY|AUT|PRO} []", + "verify", "{CHV|KEY|AUT|PRO} []", "present a PIN or key to the card" }, { do_change, - "change", "CHV [[] ]", + "change", "CHV [[] ]", "change a PIN" }, { do_unblock, - "unblock", "CHV [ []]", + "unblock", "CHV [ []]", "unblock a PIN" }, { do_put, - "put", " []", + "put", " []", "copy a local file to the card" }, { do_get, - "get", " []", + "get", " []", "copy an EF to a local file" }, { do_get_data, - "do_get", " []", + "do_get", " []", "get a data object" }, { do_put_data, - "do_put", " ", + "do_put", " ", "put a data object" }, { do_erase, "erase", "", @@ -184,19 +184,19 @@ static struct command cmds[] = { "random", "", "obtain random bytes from card" }, { do_update_record, - "update_record", " ", + "update_record", " ", "update record" }, { do_update_binary, - "update_binary", " ", + "update_binary", " ", "update binary" }, { do_apdu, - "apdu", "+", + "apdu", " ...", "send a custom apdu command" }, { do_asn1, - "asn1", "[]", + "asn1", "[]", "decode an ASN.1 file" }, { do_sm, - "sm", "open|close", + "sm", "{open|close}", "call SM 'open' or 'close' handlers, if available"}, { do_debug, "debug", "[]", From 58da74bc32fafabea27b4916b30bc5a439735791 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 7 Jul 2018 22:20:07 +0200 Subject: [PATCH 0503/4321] opensc-explorer: refactor do_put_data() slightly * increase input buffer size * avoid magic number * notify caller on error details when parsing fails --- doc/tools/opensc-explorer.1.xml | 6 +++--- src/tools/opensc-explorer.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index bcb4569b81..b379ebc64a 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -331,9 +331,9 @@ to data. - data - can be given either as a sequence of hexadecimal values, - or as string enclosed in double quotes ("..."), + data is either a + sequence of hexadecimal values or a string enclosed + in double quotes ("..."). diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 159dfa8c12..80d1b54c7d 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1730,7 +1730,7 @@ static int do_get_data(int argc, char **argv) static int do_put_data(int argc, char **argv) { unsigned int tag; - u8 buf[8192]; + u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; size_t buflen = sizeof(buf); int r; @@ -1744,8 +1744,8 @@ static int do_put_data(int argc, char **argv) /* buflen is the max length of reception buffer */ r = parse_string_or_hexdata(argv[1], buf, &buflen); if (r < 0) { - printf("unable to parse data\n"); - return -1; + printf("error parsing %s: %s\n", argv[1], sc_strerror(r)); + return r; } /* Call OpenSC to do put data */ From 1245b617d1938b2e9613efb26e3b9cdba24fc838 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 7 Jul 2018 22:27:22 +0200 Subject: [PATCH 0504/4321] opensc-explorer: refactor do_apdu() slightly * limit buffer to SC_MAX_EXT_APDU_BUFFER_SIZE * fix buffer length calculation to correctly calculate the available space * add length checks when parsing passed data into buffer --- src/tools/opensc-explorer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 80d1b54c7d..0ce297f25e 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1766,7 +1766,7 @@ static int do_put_data(int argc, char **argv) static int do_apdu(int argc, char **argv) { sc_apdu_t apdu; - u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE * 2]; + u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; size_t len, i; int r; @@ -1774,8 +1774,9 @@ static int do_apdu(int argc, char **argv) if (argc < 1) return usage(do_apdu); - for (i = 0, len = 0; i < (unsigned) argc; i++) { - size_t len0 = strlen(argv[i]); + /* loop over the args and parse them, making sure the result fits into buf[] */ + for (i = 1, len = 0; i < (unsigned) argc && len < sizeof(buf); i++) { + size_t len0 = sizeof(buf) - len; if ((r = parse_string_or_hexdata(argv[i], buf + len, &len0)) < 0) { fprintf(stderr, "error parsing %s: %s\n", argv[i], sc_strerror(r)); From 7a4a9f195191bee2ff4323749d8a34dc77cf97a5 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 8 Jul 2018 09:34:06 +0200 Subject: [PATCH 0505/4321] opensc-explorer: refactor do_put() slightly Avoid misunderstandings by renaming a variable that refers to an input file handle from 'outf' to 'inf'. --- src/tools/opensc-explorer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 0ce297f25e..9ed88690dc 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1564,7 +1564,7 @@ static int do_put(int argc, char **argv) sc_path_t path; sc_file_t *file = NULL; const char *filename; - FILE *outf = NULL; + FILE *inf = NULL; if (argc < 1 || argc > 2) return usage(do_put); @@ -1572,8 +1572,8 @@ static int do_put(int argc, char **argv) return usage(do_put); filename = (argc == 2) ? argv[1] : path_to_filename(&path, '_'); - outf = fopen(filename, "rb"); - if (outf == NULL) { + inf = fopen(filename, "rb"); + if (inf == NULL) { perror(filename); goto err; } @@ -1589,7 +1589,7 @@ static int do_put(int argc, char **argv) while (count) { int c = count > sizeof(buf) ? sizeof(buf) : count; - r = fread(buf, 1, c, outf); + r = fread(buf, 1, c, inf); if (r < 0) { perror("fread"); goto err; @@ -1616,8 +1616,8 @@ static int do_put(int argc, char **argv) err = 0; err: sc_file_free(file); - if (outf) - fclose(outf); + if (inf) + fclose(inf); select_current_path_or_die(); return -err; } From 9d501766b406d95a1dd870793162542e9eb34506 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 8 Jul 2018 10:40:06 +0200 Subject: [PATCH 0506/4321] opensc-explorer: extend 'random' to allow writing to a file Accept a file name as a second argument to the 'random' command to allow storing the generated random bytes to the file given. Forbid writing binary data to stdout in interactive mode. --- doc/tools/opensc-explorer.1.xml | 7 ++++- src/tools/opensc-explorer.c | 45 ++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index b379ebc64a..2cc04a102f 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -522,10 +522,15 @@ random count + output-file - Generate count bytes of random data. + Generate count bytes + of random data. + If output-file is given, + write the data to the host computer's file denoted + by it, otherwise show the data as hex dump. diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 9ed88690dc..da9240c025 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -181,7 +181,7 @@ static struct command cmds[] = { "erase", "", "erase card" }, { do_random, - "random", "", + "random", " []", "obtain random bytes from card" }, { do_update_record, "update_record", " ", @@ -1663,8 +1663,10 @@ static int do_random(int argc, char **argv) { unsigned char buffer[SC_MAX_EXT_APDU_BUFFER_SIZE]; int r, count; + const char *filename = NULL; + FILE *outf = NULL; - if (argc != 1) + if (argc < 1 || argc > 2) return usage(do_random); count = atoi(argv[0]); @@ -1674,6 +1676,23 @@ static int do_random(int argc, char **argv) return -1; } + if (argc == 2) { + filename = argv[1]; + + if (interactive && strcmp(filename, "-") == 0) { + fprintf(stderr, "Binary writing to stdout not supported in interactive mode\n"); + return -1; + } + + outf = (strcmp(filename, "-") == 0) + ? stdout + : fopen(filename, "wb"); + if (outf == NULL) { + perror(filename); + return -1; + } + } + r = sc_lock(card); if (r == SC_SUCCESS) r = sc_get_challenge(card, buffer, count); @@ -1683,7 +1702,27 @@ static int do_random(int argc, char **argv) return -1; } - util_hex_dump_asc(stdout, buffer, count, 0); + if (argc == 2) { + /* outf is guaranteed to be non-NULL */ + size_t written = fwrite(buffer, 1, count, outf); + + if (written < (size_t) count) + perror(filename); + if (outf == stdout) { + printf("\nTotal of %"SC_FORMAT_LEN_SIZE_T"u random bytes written\n", written); + } + else + printf("Total of %"SC_FORMAT_LEN_SIZE_T"u random bytes written to %s\n", + written, filename); + + fclose(outf); + + if (written < (size_t) count) + return -1; + } + else { + util_hex_dump_asc(stdout, buffer, count, 0); + } return 0; } From bd97c2b1392caa1d25d41691433dfbb655b18ddd Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Jul 2018 14:23:37 +0200 Subject: [PATCH 0507/4321] opensc-explorer: clarify command parsing in manual page --- doc/tools/opensc-explorer.1.xml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 2cc04a102f..491bd81b87 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -109,9 +109,18 @@ Commands - The following commands are supported at opensc-explorer's - interactive prompt or in script files passed via the command line parameter - SCRIPT. + opensc-explorer supports commands with arguments + at its interactive prompt or in script files passed via the command line + parameter SCRIPT. + + + Similar to a command shell like e.g. bash, + each input line is split into white-space separated words. + Of these words, the first one is used as the command, + while the remaining ones are treated as arguments to that command. + + + The following commands are supported: From 77297f7965b52a61eba39b5b363ab7370061f964 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Jul 2018 13:37:18 +0200 Subject: [PATCH 0508/4321] opensc-explorer: check length of argument to option --mf * fail when it is too long * replace a magic numerical constant --- src/tools/opensc-explorer.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index da9240c025..d09e41e3d7 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2126,10 +2126,14 @@ int main(int argc, char *argv[]) if (opt_startfile) { if(*opt_startfile) { - char startpath[1024]; + char startpath[SC_MAX_PATH_STRING_SIZE * 2]; char *args[] = { startpath }; - strncpy(startpath, opt_startfile, sizeof(startpath)-1); + if (strlcpy(startpath, opt_startfile, sizeof(startpath)) >= sizeof(startpath)) { + fprintf(stderr, "unable to select file %s: name too long\n", + opt_startfile); + die(1); + } r = do_cd(1, args); if (r) { printf("unable to select file %s: %s\n", From 593a90f64e58ab0d0fe490270d5b7a4b723e55ad Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Jul 2018 17:15:25 +0200 Subject: [PATCH 0509/4321] opensc-explorer: write error messages to stderr Clarify the distinction between error messages and status messages or prompts. Prepare for better non-interactive support. --- src/tools/opensc-explorer.c | 118 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index d09e41e3d7..7689066dec 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -281,7 +281,7 @@ static void select_current_path_or_die(void) r = sc_select_file(card, ¤t_path, NULL); sc_unlock(card); if (r) { - printf("unable to select parent DF: %s\n", sc_strerror(r)); + fprintf(stderr, "unable to select parent DF: %s\n", sc_strerror(r)); die(1); } } @@ -300,7 +300,7 @@ ambiguous_match(struct command *table, const char *cmd) } } if (matches > 1) { - printf("Ambiguous command: %s\n", cmd); + fprintf(stderr, "Ambiguous command: %s\n", cmd); return NULL; } return last_match; @@ -322,12 +322,12 @@ arg_to_fid(const char *arg, u8 *fid) unsigned int fid0, fid1; if (strlen(arg) != 4) { - printf("Wrong ID length.\n"); + fprintf(stderr, "Wrong ID length.\n"); return -1; } if (sscanf(arg, "%02X%02X", &fid0, &fid1) != 2) { - printf("Invalid ID.\n"); + fprintf(stderr, "Invalid ID.\n"); return -1; } @@ -351,7 +351,7 @@ arg_to_path(const char *arg, sc_path_t *path, int is_id) path->type = SC_PATH_TYPE_DF_NAME; path->len = sizeof(path->value); if ((r = sc_hex_to_bin(p, path->value, &path->len)) < 0) { - printf("Error parsing AID: %s\n", p); + fprintf(stderr, "Error parsing AID: %s\n", p); return r; } } else { @@ -368,7 +368,7 @@ arg_to_path(const char *arg, sc_path_t *path, int is_id) *path = current_path; if (path->type == SC_PATH_TYPE_DF_NAME) { if (path->len > sizeof(path->aid.value)) { - printf("Invalid length of DF_NAME path\n"); + fprintf(stderr, "Invalid length of DF_NAME path\n"); return -1; } @@ -511,7 +511,7 @@ static int do_ls(int argc, char **argv) sc_append_path_id(&path, cur, 2); } else { if (sc_path_set(&path, SC_PATH_TYPE_FILE_ID, cur, 2, 0, 0) != SC_SUCCESS) { - printf("unable to set path.\n"); + fprintf(stderr, "unable to set path.\n"); die(1); } } @@ -521,7 +521,7 @@ static int do_ls(int argc, char **argv) r = sc_select_file(card, &path, &file); sc_unlock(card); if (r) { - printf(" %02X%02X unable to select file, %s\n", cur[0], cur[1], sc_strerror(r)); + fprintf(stderr, " %02X%02X unable to select file, %s\n", cur[0], cur[1], sc_strerror(r)); } else { file->id = (cur[0] << 8) | cur[1]; print_file(file); @@ -572,7 +572,7 @@ static int do_find(int argc, char **argv) sc_append_path_id(&path, fid, sizeof fid); } else { if (sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0) != SC_SUCCESS) { - printf("unable to set path.\n"); + fprintf(stderr, "unable to set path.\n"); die(1); } } @@ -685,7 +685,7 @@ static int do_cd(int argc, char **argv) if (strcmp(argv[0], "..") == 0) { path = current_path; if (path.len < 4) { - printf("unable to go up, already in MF.\n"); + fprintf(stderr, "unable to go up, already in MF.\n"); return -1; } @@ -701,7 +701,7 @@ static int do_cd(int argc, char **argv) r = sc_select_file(card, &path, &file); sc_unlock(card); if (r) { - printf("unable to go up: %s\n", sc_strerror(r)); + fprintf(stderr, "unable to go up: %s\n", sc_strerror(r)); return -1; } sc_file_free(current_file); @@ -721,7 +721,7 @@ static int do_cd(int argc, char **argv) return -1; } if ((file->type != SC_FILE_TYPE_DF) && (card->type != SC_CARD_TYPE_BELPIC_EID)) { - printf("Error: file is not a DF.\n"); + fprintf(stderr, "Error: file is not a DF.\n"); sc_file_free(file); select_current_path_or_die(); return -1; @@ -811,7 +811,7 @@ static int do_cat(int argc, char **argv) const char *sfi_n = argv[0] + strlen(sfi_prefix); if(!current_file) { - printf("A DF must be selected to read by SFI\n"); + fprintf(stderr, "A DF must be selected to read by SFI\n"); goto err; } path = current_path; @@ -819,7 +819,7 @@ static int do_cat(int argc, char **argv) not_current = 0; sfi = atoi(sfi_n); if ((sfi < 1) || (sfi > 30)) { - printf("Invalid SFI: %s\n", sfi_n); + fprintf(stderr, "Invalid SFI: %s\n", sfi_n); return usage(do_cat); } } else { @@ -839,7 +839,7 @@ static int do_cat(int argc, char **argv) } if (file->type != SC_FILE_TYPE_WORKING_EF && !(file->type == SC_FILE_TYPE_DF && sfi)) { - printf("only working EFs may be read\n"); + fprintf(stderr, "only working EFs may be read\n"); goto err; } if (file->ef_structure == SC_FILE_EF_TRANSPARENT && !sfi) @@ -879,7 +879,7 @@ static int do_info(int argc, char **argv) r = sc_select_file(card, &path, &file); sc_unlock(card); if (r) { - printf("unable to select file: %s\n", sc_strerror(r)); + fprintf(stderr, "unable to select file: %s\n", sc_strerror(r)); return -1; } } else @@ -1116,11 +1116,11 @@ static int do_pininfo(int argc, char **argv) } } if (data.pin_type == SC_AC_NONE) { - printf("Invalid type.\n"); + fprintf(stderr, "Invalid type.\n"); return usage(do_pininfo); } if (sscanf(argv[0] + prefix_len, "%d", &data.pin_reference) != 1) { - printf("Invalid key reference.\n"); + fprintf(stderr, "Invalid key reference.\n"); return usage(do_pininfo); } @@ -1130,7 +1130,7 @@ static int do_pininfo(int argc, char **argv) sc_unlock(card); if (r) { - printf("Unable to get PIN info: %s\n", sc_strerror(r)); + fprintf(stderr, "Unable to get PIN info: %s\n", sc_strerror(r)); return -1; } if (tries_left > 0) @@ -1171,11 +1171,11 @@ static int do_verify(int argc, char **argv) } } if (data.pin_type == SC_AC_NONE) { - printf("Invalid type.\n"); + fprintf(stderr, "Invalid type.\n"); return usage(do_verify); } if (sscanf(argv[0] + prefix_len, "%d", &data.pin_reference) != 1) { - printf("Invalid key reference.\n"); + fprintf(stderr, "Invalid key reference.\n"); return usage(do_verify); } @@ -1192,13 +1192,13 @@ static int do_verify(int argc, char **argv) printf("Please enter PIN: "); r = util_getpass(&pin, &len, stdin); if (r < 0) { - printf("util_getpass error.\n"); + fprintf(stderr, "util_getpass error.\n"); return -1; } if (strlcpy((char *)buf, pin, sizeof(buf)) >= sizeof(buf)) { free(pin); - printf("PIN too long - aborting VERIFY.\n"); + fprintf(stderr, "PIN too long - aborting VERIFY.\n"); return -1; } free(pin); @@ -1208,7 +1208,7 @@ static int do_verify(int argc, char **argv) } else { r = parse_string_or_hexdata(argv[1], buf, &buflen); if (0 != r) { - printf("Invalid key value.\n"); + fprintf(stderr, "Invalid key value.\n"); return usage(do_verify); } data.pin1.data = buf; @@ -1226,7 +1226,7 @@ static int do_verify(int argc, char **argv) else printf("Incorrect code.\n"); } else - printf("Unable to verify PIN code: %s\n", sc_strerror(r)); + fprintf(stderr, "Unable to verify PIN code: %s\n", sc_strerror(r)); return -1; } printf("Code correct.\n"); @@ -1248,18 +1248,18 @@ static int do_change(int argc, char **argv) if (argc < 1 || argc > 3) return usage(do_change); if (strncasecmp(argv[0], "CHV", 3)) { - printf("Invalid type.\n"); + fprintf(stderr, "Invalid type.\n"); return usage(do_change); } if (sscanf(argv[0] + 3, "%d", &ref) != 1) { - printf("Invalid key reference.\n"); + fprintf(stderr, "Invalid key reference.\n"); return usage(do_change); } if (argc == 3) { oldpinlen = sizeof(oldpin); if (parse_string_or_hexdata(argv[1], oldpin, &oldpinlen) != 0) { - printf("Invalid key value.\n"); + fprintf(stderr, "Invalid key value.\n"); return usage(do_change); } } @@ -1267,7 +1267,7 @@ static int do_change(int argc, char **argv) if (argc >= 2) { newpinlen = sizeof(newpin); if (parse_string_or_hexdata(argv[argc-1], newpin, &newpinlen) != 0) { - printf("Invalid key value.\n"); + fprintf(stderr, "Invalid key value.\n"); return usage(do_change); } } @@ -1290,7 +1290,7 @@ static int do_change(int argc, char **argv) else printf("Incorrect code.\n"); } - printf("Unable to change PIN code: %s\n", sc_strerror(r)); + fprintf(stderr, "Unable to change PIN code: %s\n", sc_strerror(r)); return -1; } printf("PIN changed.\n"); @@ -1313,7 +1313,7 @@ static int do_unblock(int argc, char **argv) if (argc < 1 || argc > 3) return usage(do_unblock); if (strncasecmp(argv[0], "CHV", 3)) { - printf("Invalid type.\n"); + fprintf(stderr, "Invalid type.\n"); return usage(do_unblock); } if (sscanf(argv[0] + 3, "%d", &ref) != 1) { @@ -1324,7 +1324,7 @@ static int do_unblock(int argc, char **argv) if (argc > 1) { puklen = sizeof(puk); if (parse_string_or_hexdata(argv[1], puk, &puklen) != 0) { - printf("Invalid key value.\n"); + fprintf(stderr, "Invalid key value.\n"); return usage(do_unblock); } } @@ -1332,7 +1332,7 @@ static int do_unblock(int argc, char **argv) if (argc > 2) { newpinlen = sizeof(newpin); if (parse_string_or_hexdata(argv[2], newpin, &newpinlen) != 0) { - printf("Invalid key value.\n"); + fprintf(stderr, "Invalid key value.\n"); return usage(do_unblock); } } @@ -1350,8 +1350,8 @@ static int do_unblock(int argc, char **argv) sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) - printf("Incorrect code.\n"); - printf("Unable to unblock PIN code: %s\n", sc_strerror(r)); + fprintf(stderr, "Incorrect code.\n"); + fprintf(stderr, "Unable to unblock PIN code: %s\n", sc_strerror(r)); return -1; } printf("PIN unblocked.\n"); @@ -1391,7 +1391,7 @@ static int do_get(int argc, char **argv) goto err; } if (file->type != SC_FILE_TYPE_WORKING_EF) { - printf("only working EFs may be read\n"); + fprintf(stderr, "only working EFs may be read\n"); goto err; } count = file->size; @@ -1405,7 +1405,7 @@ static int do_get(int argc, char **argv) goto err; } if ((r != c) && (card->type != SC_CARD_TYPE_BELPIC_EID)) { - printf("expecting %d, got only %d bytes.\n", c, r); + fprintf(stderr, "expecting %d, got only %d bytes.\n", c, r); goto err; } if ((r == 0) && (card->type == SC_CARD_TYPE_BELPIC_EID)) @@ -1450,7 +1450,7 @@ static int do_update_binary(int argc, char **argv) r = parse_string_or_hexdata(argv[2], buf, &buflen); if (r < 0) { - printf("unable to parse data\n"); + fprintf(stderr, "unable to parse data\n"); return -1; } @@ -1464,7 +1464,7 @@ static int do_update_binary(int argc, char **argv) } if (file->ef_structure != SC_FILE_EF_TRANSPARENT) { - printf("EF structure should be SC_FILE_EF_TRANSPARENT\n"); + fprintf(stderr, "EF structure should be SC_FILE_EF_TRANSPARENT\n"); goto err; } @@ -1473,7 +1473,7 @@ static int do_update_binary(int argc, char **argv) r = sc_update_binary(card, offs, buf, buflen, 0); sc_unlock(card); if (r < 0) { - printf("Cannot update %04X; return %i\n", file->id, r); + fprintf(stderr, "Cannot update %04X; return %i\n", file->id, r); goto err; } @@ -1515,23 +1515,23 @@ static int do_update_record(int argc, char **argv) } if (file->ef_structure != SC_FILE_EF_LINEAR_VARIABLE) { - printf("EF structure should be SC_FILE_EF_LINEAR_VARIABLE\n"); + fprintf(stderr, "EF structure should be SC_FILE_EF_LINEAR_VARIABLE\n"); goto err; } else if (rec < 1 || rec > file->record_count) { - printf("Invalid record number %i\n", rec); + fprintf(stderr, "Invalid record number %i\n", rec); goto err; } r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r<0) { - printf("Cannot read record %i; return %i\n", rec, r); + fprintf(stderr, "Cannot read record %i; return %i\n", rec, r); goto err;; } buflen = sizeof(buf) - offs; i = parse_string_or_hexdata(argv[3], buf + offs, &buflen); if (!i) { - printf("unable to parse data\n"); + fprintf(stderr, "unable to parse data\n"); goto err; } @@ -1540,7 +1540,7 @@ static int do_update_record(int argc, char **argv) r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR); sc_unlock(card); if (r<0) { - printf("Cannot update record %i; return %i\n", rec, r); + fprintf(stderr, "Cannot update record %i; return %i\n", rec, r); goto err; } @@ -1605,7 +1605,7 @@ static int do_put(int argc, char **argv) goto err; } if (r != c) { - printf("expecting %d, wrote only %d bytes.\n", c, r); + fprintf(stderr, "expecting %d, wrote only %d bytes.\n", c, r); goto err; } idx += c; @@ -1653,7 +1653,7 @@ static int do_erase(int argc, char **argv) r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); sc_unlock(card); if (r) { - printf("Failed to erase card: %s\n", sc_strerror (r)); + fprintf(stderr, "Failed to erase card: %s\n", sc_strerror (r)); return -1; } return 0; @@ -1671,7 +1671,7 @@ static int do_random(int argc, char **argv) count = atoi(argv[0]); if (count < 0 || (size_t) count > sizeof buffer) { - printf("Number must be in range 0..%"SC_FORMAT_LEN_SIZE_T"u\n", + fprintf(stderr, "Number must be in range 0..%"SC_FORMAT_LEN_SIZE_T"u\n", sizeof buffer); return -1; } @@ -1698,7 +1698,7 @@ static int do_random(int argc, char **argv) r = sc_get_challenge(card, buffer, count); sc_unlock(card); if (r < 0) { - printf("Failed to get random bytes: %s\n", sc_strerror(r)); + fprintf(stderr, "Failed to get random bytes: %s\n", sc_strerror(r)); return -1; } @@ -1742,7 +1742,7 @@ static int do_get_data(int argc, char **argv) r = sc_get_data(card, tag, buffer, sizeof(buffer)); sc_unlock(card); if (r < 0) { - printf("Failed to get data object: %s\n", sc_strerror(r)); + fprintf(stderr, "Failed to get data object: %s\n", sc_strerror(r)); return -1; } @@ -1783,7 +1783,7 @@ static int do_put_data(int argc, char **argv) /* buflen is the max length of reception buffer */ r = parse_string_or_hexdata(argv[1], buf, &buflen); if (r < 0) { - printf("error parsing %s: %s\n", argv[1], sc_strerror(r)); + fprintf(stderr, "error parsing %s: %s\n", argv[1], sc_strerror(r)); return r; } @@ -1793,7 +1793,7 @@ static int do_put_data(int argc, char **argv) r = sc_put_data(card, tag, buf, buflen); sc_unlock(card); if (r < 0) { - printf("Cannot put data to %04X; return %i\n", tag, r); + fprintf(stderr, "Cannot put data to %04X; return %i\n", tag, r); return -1; } @@ -1851,7 +1851,7 @@ static int do_apdu(int argc, char **argv) r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) - printf("Failure: %s\n", sc_strerror(r)); + fprintf(stderr, "Failure: %s\n", sc_strerror(r)); else printf("Success!\n"); @@ -1873,7 +1873,7 @@ static int do_asn1(int argc, char **argv) /* select file */ if (argc) { if (arg_to_path(argv[0], &path, 0) != 0) { - puts("Invalid file path"); + fprintf(stderr, "Invalid file path\n"); return -1; } r = sc_lock(card); @@ -1890,13 +1890,13 @@ static int do_asn1(int argc, char **argv) not_current = 0; } if (file->type != SC_FILE_TYPE_WORKING_EF) { - printf("only working EFs may be read\n"); + fprintf(stderr, "only working EFs may be read\n"); goto err; } /* read */ if (file->ef_structure != SC_FILE_EF_TRANSPARENT) { - printf("only transparent file type is supported at the moment\n"); + fprintf(stderr, "only transparent file type is supported at the moment\n"); goto err; } len = file->size; @@ -1946,14 +1946,14 @@ static int do_sm(int argc, char **argv) #ifdef ENABLE_SM if (!strcmp(argv[0],"open")) { if (!card->sm_ctx.ops.open) { - printf("Not supported\n"); + fprintf(stderr, "Not supported\n"); return -1; } r = card->sm_ctx.ops.open(card); } else if (!strcmp(argv[0],"close")) { if (!card->sm_ctx.ops.close) { - printf("Not supported\n"); + fprintf(stderr, "Not supported\n"); return -1; } r = card->sm_ctx.ops.close(card); @@ -1964,7 +1964,7 @@ static int do_sm(int argc, char **argv) printf("Success!\n"); } else { - printf("Failure: %s\n", sc_strerror(r)); + fprintf(stderr, "Failure: %s\n", sc_strerror(r)); } return ret; From c817be8faa56e24afa1dbde08f19b9bcc490467c Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Jul 2018 21:05:54 +0200 Subject: [PATCH 0510/4321] opensc-explorer: refactor ambiguous_match() * most importantly: immediately return success on exact match - this allows one command to be a prefix of another one - it fixes the long-standing breakage between 'find' and 'find_tags' * fail on second prefix-only match instead of waiting until the end * check all parameters * add comments * inform caller on whether the match was ambiguous or there was no match * move printing error messages to processing loopt in main() --- src/tools/opensc-explorer.c | 40 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 7689066dec..dced848d25 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -288,21 +288,33 @@ static void select_current_path_or_die(void) } static struct command * -ambiguous_match(struct command *table, const char *cmd) +ambiguous_match(struct command *table, const char *cmd, int *ambiguous) { struct command *last_match = NULL; - int matches = 0; - for (; table->name; table++) { - if (strncasecmp(cmd, table->name, strlen(cmd)) == 0) { - last_match = table; - matches++; + if (table != NULL && cmd != NULL) { + for (; table->name; table++) { + size_t cmdlen = strlen(cmd); + + /* compare cmd with prefix of known command */ + if (strncasecmp(table->name, cmd, cmdlen) == 0) { + /* succeed immediately if lengths match too, i.e. exact match */ + if (cmdlen == strlen(table->name)) + return table; + /* fail on multiple prefix-only matches */ + if (last_match != NULL) { + if (ambiguous != NULL) + *ambiguous = 1; + return NULL; + } + /* remember latest prefix-only match */ + last_match = table; + } } } - if (matches > 1) { - fprintf(stderr, "Ambiguous command: %s\n", cmd); - return NULL; - } + /* indicate as non-ambiguous if there was no match */ + if (ambiguous != NULL && last_match == NULL) + *ambiguous = 0; return last_match; } @@ -2178,6 +2190,10 @@ int main(int argc, char *argv[]) } while (!feof(script)) { + char *line; + int cargc; + char *cargv[260]; + int multiple; struct command *cmd; char prompt[3*SC_MAX_PATH_STRING_SIZE]; @@ -2190,8 +2206,10 @@ int main(int argc, char *argv[]) continue; for (r=cargc; r < (int)DIM(cargv); r++) cargv[r] = ""; - cmd = ambiguous_match(cmds, cargv[0]); + cmd = ambiguous_match(cmds, cargv[0], &multiple); if (cmd == NULL) { + fprintf(stderr, "%s command: %s\n", + (multiple) ? "Ambiguous" : "Unknown", cargv[0]); do_help(0, NULL); } else { cmd->func(cargc-1, cargv+1); From c9db3f7385ac1e9f9bd1f4751bc8b7c603aa94fb Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 14 Jul 2018 21:46:41 +0200 Subject: [PATCH 0511/4321] opensc-explorer: allow arguments for 'help' When arguments are given, compare them like ambguous_match() does, and show the matching ones only. Add documentation of the 'help' command to the manual page. In main loop on multiple matches, show help on matching commands only. --- doc/tools/opensc-explorer.1.xml | 16 ++++++++++++++++ src/tools/opensc-explorer.c | 27 ++++++++++++++++++--------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 491bd81b87..d924a93456 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -392,6 +392,22 @@ + + + help + pattern + + + + Display the list of available commands, their options + and parameters together with a short help text. + If pattern is given, + the commands shown are limited to those matching + pattern. + + + + info diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index dced848d25..b88434638e 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1986,17 +1986,26 @@ static int do_help(int argc, char **argv) { struct command *cmd; - if (argc) - return usage(do_help); + printf("%s commands:\n", (argc) ? "Matching" : "Supported"); - printf("Supported commands:\n"); for (cmd = cmds; cmd->name; cmd++) { - int len = strlen(cmd->name) + strlen(cmd->args); - printf(" %s %s%*s %s\n", - cmd->name, cmd->args, - (len > 40) ? 0 : (40 - len), "", - cmd->help); + int i; + int match = 0; + + for (i = 0; i < argc; i++) { + if (strncmp(cmd->name, argv[i], strlen(argv[i])) == 0) + match++; + } + if (match || !argc) { + int len = strlen(cmd->name) + strlen(cmd->args); + + printf(" %s %s%*s %s\n", + cmd->name, cmd->args, + (len > 40) ? 0 : (40 - len), "", + cmd->help); + } } + return 0; } @@ -2210,7 +2219,7 @@ int main(int argc, char *argv[]) if (cmd == NULL) { fprintf(stderr, "%s command: %s\n", (multiple) ? "Ambiguous" : "Unknown", cargv[0]); - do_help(0, NULL); + do_help((multiple) ? 1 : 0, cargv); } else { cmd->func(cargc-1, cargv+1); } From ca9538761b77cb9d3e19167d58ce7c85bfad1f8c Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 22 Jul 2018 10:18:14 +0200 Subject: [PATCH 0512/4321] opensc-explorer: refactor parse_cmdline() * add comments * always terminate argv[] with a NULL element * fail if number of arguments is too large --- src/tools/opensc-explorer.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index b88434638e..20006e441c 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2015,29 +2015,36 @@ static int do_quit(int argc, char **argv) return 0; } -static int parse_cmdline(char *in, char **argv, int maxargc) +static int parse_cmdline(char *in, char **argv, int argvsize) { int argc; - for (argc = 0; argc < maxargc; argc++) { + for (argc = 0; argc < argvsize-1; argc++) { in += strspn(in, " \t\n"); - if (*in == '\0') + + if (*in == '\0') { /* end of input reached */ + argv[argc] = NULL; return argc; - if (*in == '"') { - /* Parse quoted string */ + } + if (*in == '"') { /* double-quoted string */ argv[argc] = in++; in += strcspn(in, "\""); - if (*in++ != '"') + if (*in++ != '"') { /* error: unbalanced quote */ + argv[0] = NULL; return 0; - } else { - /* White space delimited word */ + } + } + else { /* white-space delimited word */ argv[argc] = in; in += strcspn(in, " \t\n"); } if (*in != '\0') *in++ = '\0'; } - return argc; + + /* error: too many arguments - argv[] exhausted */ + argv[0] = NULL; + return 0; } static char *read_cmdline(FILE *script, char *prompt) @@ -2210,11 +2217,11 @@ int main(int argc, char *argv[]) line = read_cmdline(script, prompt); if (line == NULL) break; + cargc = parse_cmdline(line, cargv, DIM(cargv)); if ((cargc < 1) || (*cargv[0] == '#')) continue; - for (r=cargc; r < (int)DIM(cargv); r++) - cargv[r] = ""; + cmd = ambiguous_match(cmds, cargv[0], &multiple); if (cmd == NULL) { fprintf(stderr, "%s command: %s\n", From c5679bfe39f555eac4c580090e31acfb0ae8bea4 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 22 Jul 2018 11:03:23 +0200 Subject: [PATCH 0513/4321] opensc-explorer: refactor read_cmdline() * add comments * simplify #ifdef logic * increase commandline buffer in non-interactive / non-readline case --- src/tools/opensc-explorer.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 20006e441c..1126cf779e 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2049,7 +2049,7 @@ static int parse_cmdline(char *in, char **argv, int argvsize) static char *read_cmdline(FILE *script, char *prompt) { - static char buf[256]; + static char buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; static int initialized; static int interactive; @@ -2061,20 +2061,23 @@ static char *read_cmdline(FILE *script, char *prompt) using_history(); #endif } -#ifdef ENABLE_READLINE + if (interactive) { +#ifdef ENABLE_READLINE char *line = readline(prompt); - if (line && strlen(line) > 2 ) + + /* add line to history if longer than 2 characters */ + if (line != NULL && strlen(line) > 2) add_history(line); + + /* return in interactive case with readline */ return line; - } -#endif - /* Either we don't have readline or we are not running - interactively */ -#ifndef ENABLE_READLINE - if (interactive) +#else printf("%s", prompt); #endif + } + + /* either we don't have readline or we are not running interactively */ fflush(stdout); if (fgets(buf, sizeof(buf), script) == NULL) return NULL; From 9616ad4d9407611cee6028043f4dfebb1f4d40c7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 16 Sep 2018 12:51:50 +0200 Subject: [PATCH 0514/4321] opensc-explorer: fix&clarify handling of interactive mode * make 'interactive' a global variable * set it when opensc was called with the SCRIPT argument * document the behaviour in the manual page Make interactive a global variable and set it in main. --- doc/tools/opensc-explorer.1.xml | 10 +++++++++- src/tools/opensc-explorer.c | 16 +++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index d924a93456..128b486a03 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -28,10 +28,18 @@ Description The opensc-explorer utility can be - used interactively to perform miscellaneous operations + used to perform miscellaneous operations such as exploring the contents of or sending arbitrary APDU commands to a smart card or similar security token. + + If a SCRIPT is given, + opensc-explorer runs in non-interactive mode, + reading the commands from SCRIPT, + one command per line. + If no script is given, opensc-explorer + runs in interactive mode, reading commands from standard input. + diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 1126cf779e..48ca31c428 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -63,6 +63,7 @@ static sc_file_t *current_file = NULL; static sc_path_t current_path; static sc_context_t *ctx = NULL; static sc_card_t *card = NULL; +static int interactive = 1; static const struct option options[] = { { "reader", 1, NULL, 'r' }, @@ -2051,19 +2052,14 @@ static char *read_cmdline(FILE *script, char *prompt) { static char buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; static int initialized; - static int interactive; - if (!initialized) { - initialized = 1; - interactive = isatty(fileno(script)); + if (interactive) { #ifdef ENABLE_READLINE - if (interactive) + if (!initialized) { + initialized = 1; using_history(); -#endif - } + } - if (interactive) { -#ifdef ENABLE_READLINE char *line = readline(prompt); /* add line to history if longer than 2 characters */ @@ -2196,9 +2192,11 @@ int main(int argc, char *argv[]) util_print_usage_and_die(app_name, options, option_help, "[SCRIPT]"); break; case 0: + interactive = 1; script = stdin; break; case 1: + interactive = 0; if (strcmp(argv[optind], "-") == 0) { script = stdin; } From 14a31a3c42662804d0a289da74cbe3eb9e0ace75 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 8 Jul 2018 10:52:30 +0200 Subject: [PATCH 0515/4321] opensc-explorer: refactor main() * localize variables * print errors to stderr * release allocated resources * return error code on error - improve non-interactive use * do not show help on unknown commands when used non-interactively --- src/tools/opensc-explorer.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 48ca31c428..011fd3b328 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2087,9 +2087,6 @@ static char *read_cmdline(FILE *script, char *prompt) int main(int argc, char *argv[]) { int r, c, long_optind = 0, err = 0; - char *line; - int cargc; - char *cargv[260]; sc_context_param_t ctx_param; int lcycle = SC_CARDCTRL_LIFECYCLE_ADMIN; FILE *script = stdin; @@ -2163,9 +2160,9 @@ int main(int argc, char *argv[]) } r = do_cd(1, args); if (r) { - printf("unable to select file %s: %s\n", + fprintf(stderr, "unable to select file %s: %s\n", opt_startfile, sc_strerror(r)); - return -1; + die(1); } } } else { @@ -2175,8 +2172,8 @@ int main(int argc, char *argv[]) r = sc_select_file(card, ¤t_path, ¤t_file); sc_unlock(card); if (r) { - printf("unable to select MF: %s\n", sc_strerror(r)); - return 1; + fprintf(stderr, "unable to select MF: %s\n", sc_strerror(r)); + die(1); } } @@ -2227,9 +2224,11 @@ int main(int argc, char *argv[]) if (cmd == NULL) { fprintf(stderr, "%s command: %s\n", (multiple) ? "Ambiguous" : "Unknown", cargv[0]); - do_help((multiple) ? 1 : 0, cargv); + if (interactive) + do_help((multiple) ? 1 : 0, cargv); + err = -1; } else { - cmd->func(cargc-1, cargv+1); + err = cmd->func(cargc-1, cargv+1); } } end: From 3cc2670f3e5f30d0d244b2d07d9f959f3e840af7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 23 Sep 2018 11:47:51 +0200 Subject: [PATCH 0516/4321] opensc-explorer: avoid warnings on readline-less builds --- src/tools/opensc-explorer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 011fd3b328..ac5292f91b 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2051,10 +2051,11 @@ static int parse_cmdline(char *in, char **argv, int argvsize) static char *read_cmdline(FILE *script, char *prompt) { static char buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; - static int initialized; if (interactive) { #ifdef ENABLE_READLINE + static int initialized; + if (!initialized) { initialized = 1; using_history(); From c9d6c30a83ead1a53756c8800bf0ba11558e9f63 Mon Sep 17 00:00:00 2001 From: konstantinpersidskiy Date: Fri, 6 Apr 2018 01:16:15 -0700 Subject: [PATCH 0517/4321] Fix data object with empty value creation --- src/pkcs11/framework-pkcs15.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cc4b1e80fb..8d310f0272 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2600,11 +2600,6 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, } } - if (args.der_encoded.len == 0) { - rv = CKR_TEMPLATE_INCOMPLETE; - goto out; - } - rc = sc_pkcs15init_store_data_object(fw_data->p15_card, profile, &args, &data_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); From ccdb314d493c807edce59e0a5f6895cb9477ec01 Mon Sep 17 00:00:00 2001 From: konstantinpersidskiy Date: Tue, 10 Apr 2018 23:59:38 -0700 Subject: [PATCH 0518/4321] Fix C_GetAttributeValue for attr with 0 length --- src/pkcs11/framework-pkcs15.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 8d310f0272..1829cf0fb7 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4348,6 +4348,16 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, if (!out_data) return SC_ERROR_INVALID_ARGUMENTS; + if (dobj->info->data.len == 0) + /* CKA_VALUE is empty */ + { + struct sc_pkcs15_data *data = calloc(sizeof(struct sc_pkcs15_data), 1); + data->data_len = 0; + data->data = NULL; + *out_data = data; + return SC_SUCCESS; + } + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); @@ -4372,6 +4382,14 @@ data_value_to_attr(CK_ATTRIBUTE_PTR attr, struct sc_pkcs15_data *data) if (!attr || !data) return CKR_ATTRIBUTE_VALUE_INVALID; + + if (data->data_len == 0) + /* value is empty */ + { + attr->ulValueLen = data->data_len; + attr->pValue = NULL_PTR; + return CKR_OK; + } sc_log(context, "data_value_to_attr(): data(%p,len:%"SC_FORMAT_LEN_SIZE_T"u)", data, data->data_len); @@ -4453,7 +4471,8 @@ pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT if (rv == CKR_OK) rv = data_value_to_attr(attr, data); if (data) { - free(data->data); + if (data->data) + free(data->data); free(data); } if (rv != CKR_OK) From 0c3412bb37ea61efe501cab0ce080acaaca7a5e1 Mon Sep 17 00:00:00 2001 From: konstantinpersidskiy Date: Mon, 9 Apr 2018 07:18:44 -0700 Subject: [PATCH 0519/4321] Fix C_SetAttributeValue for CKA_VALUE for data obj --- src/pkcs11/framework-pkcs15.c | 38 +++++++++++++++++++---------------- src/pkcs15init/pkcs15-init.h | 1 + src/pkcs15init/pkcs15-lib.c | 36 ++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1829cf0fb7..80f9ce89f3 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3260,6 +3260,14 @@ pkcs15_set_attrib(struct sc_pkcs11_session *session, struct sc_pkcs15_object *p1 case CKA_SUBJECT: rv = SC_SUCCESS; break; + case CKA_VALUE: + if ((p15_object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_DATA_OBJECT) { + ck_rv = CKR_ATTRIBUTE_READ_ONLY; + goto set_attr_done; + } + rv = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object, + P15_ATTR_TYPE_VALUE, attr->pValue, attr->ulValueLen); + break; default: ck_rv = CKR_ATTRIBUTE_READ_ONLY; goto set_attr_done; @@ -4351,11 +4359,8 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, if (dobj->info->data.len == 0) /* CKA_VALUE is empty */ { - struct sc_pkcs15_data *data = calloc(sizeof(struct sc_pkcs15_data), 1); - data->data_len = 0; - data->data = NULL; - *out_data = data; - return SC_SUCCESS; + *out_data = NULL; + return sc_to_cryptoki_error(SC_SUCCESS, "C_GetAttributeValue"); } fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; @@ -4382,14 +4387,6 @@ data_value_to_attr(CK_ATTRIBUTE_PTR attr, struct sc_pkcs15_data *data) if (!attr || !data) return CKR_ATTRIBUTE_VALUE_INVALID; - - if (data->data_len == 0) - /* value is empty */ - { - attr->ulValueLen = data->data_len; - attr->pValue = NULL_PTR; - return CKR_OK; - } sc_log(context, "data_value_to_attr(): data(%p,len:%"SC_FORMAT_LEN_SIZE_T"u)", data, data->data_len); @@ -4467,12 +4464,19 @@ pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT free(buf); break; case CKA_VALUE: + /* if CKA_VALUE is empty, sets data to NULL */ rv = pkcs15_dobj_get_value(session, dobj, &data); - if (rv == CKR_OK) - rv = data_value_to_attr(attr, data); + if (rv == CKR_OK) { + if (data) { + rv = data_value_to_attr(attr, data); + } + else { + attr->ulValueLen = 0; + attr->pValue = NULL_PTR; + } + } if (data) { - if (data->data) - free(data->data); + free(data->data); free(data); } if (rv != CKR_OK) diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 968c39b349..0133e73b2b 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -290,6 +290,7 @@ struct sc_pkcs15init_certargs { #define P15_ATTR_TYPE_LABEL 0 #define P15_ATTR_TYPE_ID 1 +#define P15_ATTR_TYPE_VALUE 2 extern struct sc_pkcs15_object *sc_pkcs15init_new_object(int, const char *, diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e05842b588..6c5e0081b4 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3303,8 +3303,42 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot change ID attribute"); } break; + case P15_ATTR_TYPE_VALUE: + switch(df_type) { + case SC_PKCS15_DODF: { + u8 *nv; + struct sc_pkcs15_data_info *info = (struct sc_pkcs15_data_info *) object->data; + struct sc_path old_data_path = info->path; + struct sc_path new_data_path; + struct sc_pkcs15_der new_data; + new_data.len = new_len; + new_data.value = (u8 *) new_value; + + /* save new data as a new data file on token */ + r = sc_pkcs15init_store_data(p15card, profile, object, &new_data, &new_data_path); + profile->dirty = 1; + LOG_TEST_RET(ctx, r, "Failed to store new data"); + + nv = (u8 *) malloc (new_len * sizeof(u8)); + memcpy(nv, new_value, new_len * sizeof(u8)); + free(info->data.value); + /* set object members to represent new CKA_VALUE value, + new path will be written to DODF later in this function*/ + info->data.len = new_len; + info->data.value = nv; + info->path = new_data_path; + + /* delete old data file from token */ + r = sc_pkcs15init_delete_by_path(profile, p15card, &old_data_path); + + break; + } + default: + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot change value attribute"); + } + break; default: - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Only 'LABEL' or 'ID' attributes can be changed"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Only 'LABEL' or 'ID' or 'VALUE'(for data objects) attributes can be changed"); } if (profile->ops->emu_update_any_df) { From 0ae825f8d9e5964c8e54f4f2111cd0cc5e90ba53 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 25 Sep 2018 11:09:07 +0200 Subject: [PATCH 0520/4321] fixed error checking closes https://github.com/OpenSC/OpenSC/pull/1343 --- src/pkcs15init/pkcs15-lib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 6c5e0081b4..934827b4a4 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3320,6 +3320,9 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p LOG_TEST_RET(ctx, r, "Failed to store new data"); nv = (u8 *) malloc (new_len * sizeof(u8)); + if (!nv) { + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } memcpy(nv, new_value, new_len * sizeof(u8)); free(info->data.value); /* set object members to represent new CKA_VALUE value, From 496a9b571d5bdedbd9797b5495c18f05435edb45 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 25 Sep 2018 12:13:57 +0200 Subject: [PATCH 0521/4321] fixed error handling --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 934827b4a4..1f7f7fb8de 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3333,7 +3333,7 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p /* delete old data file from token */ r = sc_pkcs15init_delete_by_path(profile, p15card, &old_data_path); - + LOG_TEST_RET(ctx, r, "Failed to delete old data"); break; } default: From 551fcccb90da1e9c092dd26d676bc27e36b9a6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20M=C3=BCller?= Date: Thu, 27 Sep 2018 14:20:41 -0300 Subject: [PATCH 0522/4321] Changed outdated "STARCOS SPK 2.3" name to "STARCOS". modified: src/libopensc/pkcs15-infocamere.c modified: src/libopensc/pkcs15-starcert.c modified: src/pkcs15init/pkcs15-lib.c Changed isf_acl to also need SO PIN for CREATE. modified: src/pkcs15init/starcos.profile --- src/libopensc/pkcs15-infocamere.c | 2 +- src/libopensc/pkcs15-starcert.c | 2 +- src/pkcs15init/pkcs15-lib.c | 2 +- src/pkcs15init/starcos.profile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index 6532ffc508..71393cd12b 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -787,7 +787,7 @@ static int infocamere_detect_card(sc_pkcs15_card_t * p15card) sc_card_t *card = p15card->card; /* check if we have the correct card OS */ - if (strcmp(card->name, "STARCOS SPK 2.3") + if (strcmp(card->name, "STARCOS") && strcmp(card->name, "CardOS M4")) return SC_ERROR_WRONG_CARD; return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 1c4110a72c..2bd44958af 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -106,7 +106,7 @@ static int starcert_detect_card(sc_pkcs15_card_t *p15card) sc_card_t *card = p15card->card; /* check if we have the correct card OS */ - if (strcmp(card->name, "STARCOS SPK 2.3")) + if (strcmp(card->name, "STARCOS")) return SC_ERROR_WRONG_CARD; /* read EF_Info file */ sc_format_path("3F00FE13", &path); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 1f7f7fb8de..04370ce913 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3893,7 +3893,7 @@ do_select_parent(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = sc_select_file(p15card->card, &path, NULL); LOG_TEST_RET(ctx, r, "Cannot select parent DF"); } - else if (r == SC_SUCCESS && !strcmp(p15card->card->name, "STARCOS SPK 2.3")) { + else if (r == SC_SUCCESS && !strcmp(p15card->card->name, "STARCOS")) { /* in case of starcos spk 2.3 SELECT FILE does not * give us the ACLs => ask the profile */ sc_file_free(*parent); diff --git a/src/pkcs15init/starcos.profile b/src/pkcs15init/starcos.profile index af4d6174b7..2a2a6f2b9c 100644 --- a/src/pkcs15init/starcos.profile +++ b/src/pkcs15init/starcos.profile @@ -10,7 +10,7 @@ cardinfo { option default { macros { so-pin-flags = initialized, needs-padding, soPin; - isf_acl = WRITE=$SOPIN; + isf_acl = WRITE=$SOPIN, CREATE=$SOPIN; df_acl = *=$SOPIN; } } From f471048ef72eff3e1a5d90a0f0e56bd0e3399dd7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 29 Sep 2018 17:56:27 +0200 Subject: [PATCH 0523/4321] remove source-less doc/tools/files.html The current version, which gets re-generated from XML source, is in doc/files/. --- doc/tools/files.html | 1096 ------------------------------------------ 1 file changed, 1096 deletions(-) delete mode 100644 doc/tools/files.html diff --git a/doc/tools/files.html b/doc/tools/files.html deleted file mode 100644 index edadd9861f..0000000000 --- a/doc/tools/files.html +++ /dev/null @@ -1,1096 +0,0 @@ -OpenSC Manual Pages: Section 5

    OpenSC Manual Pages: Section 5


    Table of Contents

    opensc.conf — configuration file for OpenSC
    pkcs15-profile — format of profile for pkcs15-init

    Name

    opensc.conf — configuration file for OpenSC

    Description

    - OpenSC obtains configuration data from the following sources in the following order -

    1. - command-line options -

    2. - environment variables -

    3. - Windows registry (if available) -

    4. - system-wide configuration file - (/home/fm/.local/etc/opensc.conf) -

    -

    - The configuration file, opensc.conf, is composed - of blocks, which, in general, have the - following format: -

    -key [, name...] {
    -	block_contents
    -}
    -			

    - block_contents is one or more - block_items where a - block_item is one of -

    • - # comment string -

    • - key [, name...] = value; -

    • - block -

    -

    - At the root level, opensc.conf should contain - one or more application specific configuration blocks: -

    -app application {
    -	block_contents
    -}
    -			

    - application - specifies one of: -

    • - default: The fall-back configuration block for all applications -

    • - opensc-pkcs11: Configuration block for the PKCS#11 module (opensc-pkcs11.so) -

    • - onepin-opensc-pkcs11: Configuration block for the PKCS#11 one-PIN-module (onepin-opensc-pkcs11.so) -

    • - cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) -

    • - tokend: Configuration block for macOS' tokend (OpenSC.tokend) -

    • - cardos-tool, - cryptoflex-tool, - dnie-tool, - egk-tool, - eidenv, - gids-tool, - iasecc-tool, - netkey-tool, - npa-tool, - openpgp-tool, - opensc-asn1, - opensc-explorer, - opensc-notify, - opensc-tool, - piv-tool, - pkcs11-tool, - pkcs15-crypt, - pkcs15-init, - pkcs15-tool, - sc-hsm-tool, - westcos-tool: - Configuration block for OpenSC tools -

    -

    Configuration Options

    - debug = num; -

    - Amount of debug info to print (Default: - 0). A greater value means more - debug info. -

    - The environment variable - OPENSC_DEBUG overwrites this - setting. -

    - debug_file = filename; -

    - The file to which debug output will be written - (Default: stderr). Special - values stdout and - stderr are recognized. -

    - profile_dir = filename; -

    - PKCS#15 initialization/personalization profiles - directory for - pkcs15-init(1). - - (Default: /home/fm/.local/share/opensc). -

    - If this configuration value is not found on - Windows, the registry key - HKLM\Software\OpenSC - Project\OpenSC\ProfileDir is - checked. -

    - disable_popups = bool; -

    - Disable pop-ups of built-in GUI (Default: false). -

    - enable_default_driver = bool; -

    - Enable default card driver (Default: - false). Default card driver is - explicitly enabled for - opensc-explorer(1). - - and - opensc-tool(1). - -

    - card_drivers = name... ; -

    - Whitelist of card drivers to load at start-up. - The special value internal (the - default) will load all statically linked drivers. -

    - If an unknown (i.e. not internal or old) driver is - supplied, a separate configuration configuration - block has to be written for the driver. A special - value old will load all - statically linked drivers that may be removed in - the future. -

    - The list of supported card driver names can be - retrieved from the output of opensc-tool - --list-drivers. -

    - The environment variable - OPENSC_DRIVER overwrites this - setting. -

    - ignored_readers = name... ; -

    - List of readers to ignore (Default: empty). If any - of the comma separated strings listed is matched in - a reader name (case sensitive, partial matching - possible), the reader is ignored by OpenSC. Use - opensc-tool --list-readers to - see all currently connected readers. -

    - reader_driver name { - block_contents - } - -

    - Configuration of the card reader driver where name is one of: -

    -

    - For details see the section called “reader_driver Configuration Block”. -

    - card_driver name { - block_contents - } - -

    - Configuration of the card driver where name is one of: -

    -

    - card_atr hexstring { - block_contents - } - -

    - In addition to the built-in list of known cards in - the card driver, you can configure a new card for - the driver using the card_atr - block. -

    - For details see the section called “card_atr Configuration Block”. -

    - secure_messaging name { - block_contents - } - -

    - Configuration options for the secure messaging profile name: -

    - module_name = filename; -

    - Name of external SM module (Default: libsmm-local.so). -

    - module_path = filename; -

    - Directory with external SM module - (Default: /home/fm/.local/lib). -

    - If this configuration value is not - found on Windows, the registry key - HKLM\Software\OpenSC - Project\OpenSC\SmDir is - checked. -

    - module_data = value; -

    - Specific data to tune the module initialization. -

    - mode = value; -

    - Secure messaging mode. Known parameters: -

    • - transmit: - In this mode the - procedure to securize - an APDU is called by - the OpenSC general APDU - transmit procedure. In - this mode all APDUs, - except the ones - filtered by the card - specific procedure, are - securized. -

    • - acl: - In this mode APDU are - securized only if - needed by the ACLs of - the command to be - executed. -

    -

    - flags = value; -

    - Secure messaging type specific flags. -

    - kmc = hexstring; -

    - Default KMC of the GP Card Manager for the Oberthur's Java cards. -

    - ifd_serial = hexstring; -
    - keyset[_aid]_num_enc = - value; - keyset[_aid]_num_mac = - value; -

    - Keyset values from IAM profiles of - the Gemalto IAS/ECC cards with an - optional application identifier -

    - framework name { - block_contents - } - -

    - Internal configuration options where name is one of: -

    -

    - pkcs11 { - block_contents - } - -

    - Parameters for the OpenSC PKCS11 module. -

    - For details see the section called “pkcs11 Configuration Block”. -

    reader_driver Configuration Block

    Configuration Options for all Reader Drivers

    - max_send_size = num; - max_recv_size = num; -

    - Limit command and response sizes - (Default: - max_send_size - = 255, - max_recv_size - = 256) . Some - Readers don't propagate their - transceive capabilities correctly. - max_send_size and max_recv_size - allow setting the limits manually, - for example to enable extended - length capabilities. -

    - enable_escape bool; -

    - Detect reader capabilities with - escape commands (wrapped APDUs with - CLA=0xFF as defined by PC/SC pt. 3 - and BSI TR-03119, e.g. for getting - the UID, escaped PIN commands and - the reader's firmware version, - Default: false) -

    Special Configuration Option for CT-API Readers

    - module filename { - ports = nums; - } - -

    - Load the specified CT-API module with the specified number of ports. -

    Special Configuration Options for PC/SC Readers

    - connect_exclusive = bool; -

    - Connect to reader in exclusive mode - (Default: false)? - This option has no effect in Windows' minidriver. -

    - disconnect_action = action; -

    - What to do when disconnecting from - a card (SCardDisconnect). Valid - values are - leave, - reset, - unpower (Default: - leave). - This option has no effect in Windows' minidriver. -

    - transaction_end_action = action; -

    - What to do at the end of a - transaction (SCardEndTransaction). - Valid values - are leave, - reset, - unpower (Default: - leave). - This option has no effect in Windows' minidriver. -

    - reconnect_action = action; -

    - What to do when reconnection to a - card (SCardReconnect). Valid values - are leave, - reset, - unpower (Default: - leave). - This option has no effect in Windows' minidriver. -

    - enable_pinpad = bool; -

    - Enable pinpad if detected (PC/SC - v2.0.2 Part 10, Default: - true) -

    - fixed_pinlength = num; -

    - Some pinpad readers can only handle - one exact length of the PIN. - fixed_pinlength - sets this value so that OpenSC - expands the padding to this length - (Default: 0, - i.e. not fixed). -

    - provider_library = filename; -

    - Use specific PC/SC provider - (Default: - libpcsclite.so.1). -

    Special Configuration Option for OpenCT Readers

    - readers = num; -

    - Virtual readers to allocate (Default: 2). -

    Special Configuration Options for German ID Card

    - can = value; -

    - German ID card requires the CAN to - be verified before QES PIN. This, - however, is not part of the PKCS#15 - profile of the card. So for - verifying the QES PIN we actually - need both. The CAN may be given - here. If the CAN is not given here, - it will be prompted on the command - line or on the reader (depending on - the reader's capabilities). -

    - st_dv_certificate = filename; - st_certificate = filename; - st_key = filename; -

    - QES is only possible with a Comfort - Reader (CAT-K), which holds a - cryptographic key to authenticate - itself as signature terminal (ST). - We usually will use the reader's - capability to sign the data. - However, during developement you - may specify soft certificates and - keys for a ST. -

    - An example PKI can be found in the - example data for the - German - ID card emulator -

    Special Configuration Options for DNIe

    - user_consent_enabled = bool; -

    - Configure the warning message when - performing a signature operation - with the DNIe. Only used if - compiled with - --enable-dnie-ui -

    - user_consent_app = filename; -

    - Specify the pinentry application to - use if warning is configured to be - displayed using pinentry (Default: - /usr/bin/pinentry). - Only used if compiled with - --enable-dnie-ui -

    card_atr Configuration Block

    -

    - Configuration options specified by the card's ATR: -

    - atrmask = hexstring; -

    - The mask is logically AND'd with an - card ATR prior to comparison with - the ATR reference value above. - Using this mask allows identifying - and configuring multiple ATRs as - the same card model. -

    - driver = name; -

    - When enabled, overrides all - possible settings from the card - drivers built-in card configuration - list. -

    - name = name; -

    - Set card name for card drivers that - allows it. -

    - type = num; -

    - Allows setting the exact type of - the card internally used by the - card driver. Allowed values can be - found in the source code of - cards.h. -

    - flags = value... ; -

    - Card flags as an hex value. - Multiple values are OR'd together. - Depending on card driver, this - allows fine-tuning the capabilities - in the card driver for your card. -

    - Optionally, some known parameters - can be specified as strings: -

    • - rng: - On-board random number - source -

    • - keep_alive: - Request the card driver - to send a "keep alive" - command before each - transaction to make - sure that the required - applet is still - selected. -

    -

    - pkcs15emu = name; -

    - When using PKCS#15 emulation, force - the emulation driver for specific - cards. Required for external - drivers, but can be used with - built-in drivers, too. -

    - force_protocol = value; -

    - Force protocol selection for - specific cards. Known parameters: -

    • - t0 -

    • - t1 -

    • - raw -

    -

    - md_read_only = bool; -

    - Mark card as read/only card in - Minidriver/BaseCSP interface - (Default: false). -

    - md_supports_X509_enrollment = bool; -

    - Indicate X509 enrollment support at - Minidriver/BaseCSP interface - (Default: false). -

    - md_guid_as_id = bool; -

    - Use the GUID generated for the key - as id in the PKCS#15 structure - (Default: false, i.e. auto generated) -

    - md_guid_as_label = bool; -

    - Use the GUID generated for the key - as label in the PKCS#15 structure - (Default: false, - i.e. no label set). -

    - md_supports_container_key_gen = bool; -

    - Card allows generating key pairs on the card (Default: false). -

    - md_supports_container_key_import = bool; -

    - Card allows importing private keys - (Default: false). -

    - md_pinpad_dlg_title = value; -

    - Window title of the PIN pad dialog - (Default: "Windows - Security"). -

    - md_pinpad_dlg_icon = filename; -

    - Filename of the icon for the PIN - pad dialog; use - "" for no icon - (Default: Built-in smart card icon). -

    - md_pinpad_dlg_main = value; -

    - Main instruction of the PIN pad - dialog (Default: "OpenSC - Smart Card Provider"). -

    - md_pinpad_dlg_content_user = value; -

    - Content of the PIN pad dialog for - role "user" (Default: - "Please verify your - fingerprint or PIN on the - card."). -

    - md_pinpad_dlg_content_user_sign = value; -

    - Content of the PIN pad dialog for - role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). -

    - md_pinpad_dlg_content_user_sign = name; -

    - Content of the PIN pad dialog for - role "user+signature" (Default: - "Please verify your - fingerprint or PIN for the - digital signature PIN on the - card."). -

    - md_pinpad_dlg_content_admin = value; -

    - Content of the PIN pad dialog for - role "admin" (Default: - "Please enter your PIN to - unblock the user PIN on the - PINPAD.") -

    - md_pinpad_dlg_content_cancel = value; -

    - Content of the PIN pad dialog after - pressing "Cancel", when the reader - doesn't respond to SCardCancel -

    - md_pinpad_dlg_expanded = value; -

    - Expanded information of the PIN pad - dialog (Default: "This - window will be closed - automatically after the PIN has - been submitted on the PINPAD - (timeout typically after 30 - seconds).") -

    - md_pinpad_dlg_expanded_cancel = value; -

    - Expanded information of the PIN pad - dialog after pressing "Cancel", - when the reader doesn't respond to - SCardCancel (Default: - "Some readers only support - canceling the operation on the - PIN pad. Press Cancel or remove - the card."). -

    - md_pinpad_dlg_enable_cancel = bool; -

    - Allow the user to cancel the PIN - pad dialog (Default: - false) -

    - md_pinpad_dlg_timeout = num; -

    - Time in seconds for the progress - bar of the PIN pad dialog to tick. - 0 removes the - progress bar (Default: - 30). -

    - notify_card_inserted = value; - notify_card_inserted_text = value; -

    - Notification title and text when - card was inserted (Default: - "Smart card - detected", ATR of - the card). -

    - notify_card_removed = value; - notify_card_removed_text = value; -

    - Notification title and text when - card was removed (Default: - "Smart card - removed", name of - smart card reader). -

    - notify_pin_good = value; - notify_pin_good_text = value; -

    - Notification title and text when - PIN was verified (Default: - "PIN verified", - "Smart card is - unlocked"). -

    - notify_pin_bad = value; - notify_pin_bad_text = value; -

    - Notification title and text when - PIN was wrong (Default: - "PIN not - verified", - "Smart card is - locked"). -

    -

    framework pkcs15 Configuration Block

    - use_file_caching = bool; -

    - Whether to cache the card's files (e.g. - certificates) on disk in - file_cache_dir (Default: - false). -

    - If caching is done by a system process, the - cached files may be placed inaccessible from - the user account. Use a globally readable and - writable location if you wish to share the - cached information. Note that the cached files - may contain personal data such as name and mail - address. -

    - file_cache_dir = filename; -

    - Where to cache the card's files. The default values are: -

    • - HOME/.eid/cache/ (Unix) -

    • - USERPROFILE\.eid-cache\ (Windows) -

    -

    - If caching is done by a system process, the - cached files may be placed inaccessible from - a user account. Use a globally readable and - writable location if you wish to share the - cached information. Note that the cached files - may contain personal data such as name and mail - address. -

    - use_pin_caching = bool; -

    - Use PIN caching (Default: true)? -

    - pin_cache_counter = num; -

    - How many times to use a PIN from cache before - re-authenticating it (Default: - 10)? -

    - pin_cache_ignore_user_consent = bool; -

    - Older PKCS#11 applications not supporting - CKA_ALWAYS_AUTHENTICATE may - need to set this to get signatures to work with - some cards (Default: false). -

    - enable_pkcs15_emulation = bool; -

    - Enable pkcs15 emulation (Default: - true). -

    - try_emulation_first = bool; -

    - Prefer pkcs15 emulation code before the normal - pkcs15 processing (Default: - no). Some cards work in - emu-only mode, and do not depend on this - option. -

    - enable_builtin_emulation = bool; -

    - Enable builtin emulators (Default: - true). -

    - builtin_emulators = emulators; -

    - List of the builtin pkcs15 emulators to test - (Default: esteid, openpgp, tcos, - starcert, itacns, infocamere, postecert, - actalis, atrust-acos, gemsafeGPK, - gemsafeV1, tccardos, PIV-II) -

    - pkcs11_enable_InitToken = bool; -

    - Enable initialization and card recognition in - PKCS#11 layer (Default: - false). -

    - emulate name { - block_contents - } - -

    - Configuration options for a PKCS#15 emulator - where name is a - short name for an external card driver. -

    - module = filename; -

    - For pkcs15 emulators loaded from an - external shared library/DLL, you need to - specify the path name of the module and - customize the card_atr example above - correctly. -

    - function = name; -

    - Get the init function name of the - emulator (Default: - sc_pkcs15_init_func_ex) -

    - application hexstring { - block_contents - } - -

    - Configuration of the on-card-application where - hexstring is the - application identifier (AID). -

    - type = name; -

    - Type of application where - name is one - of: -

    • - generic -

    • - protected -

    -

    - Used to distinguish the common access - application and application for which - authentication to perform some - operation cannot be obtained with the - common procedures (ex. object creation - protected by secure messaging). Used - by PKCS#11 module configured to expose - restricted number of slots. (for ex. - configured to expose only User PIN - slot, User and Sign PINs slots, ...) -

    - model = name; -
    - disable = bool; -

    - Do not expose application in PKCS#15 - framework (Default: - false) -

    framework tokend Configuration Block

    - score = num; -

    - Score for OpenSC.tokend - (Default: 300). The tokend with - the highest score shall be used. -

    - ignore_private_certificate = bool; -

    - Tokend ignore to read PIN protected certificate - that is set - SC_PKCS15_CO_FLAG_PRIVATE flag - (Default: true). -

    pkcs11 Configuration Block

    - max_virtual_slots = num; -

    - Maximum Number of virtual slots (Default: - 16). If there are more slots - than defined here, the remaining slots will be - hidden from PKCS#11. -

    - slots_per_card = num; -

    - Maximum number of slots per smart card (Default: - 4). If the card has fewer keys - than defined here, the remaining number of slots - will be empty. -

    - lock_login = bool; -

    - By default, the OpenSC PKCS#11 module will not lock - your card once you authenticate to the card via - C_Login (Default: - false). - - Thus the other users or other applications is not - prevented from connecting to the card and perform - crypto operations (which may be possible because - you have already authenticated with the card). This - setting is not very secure. -

    - Also, if your card is not locked, you can enconter - problems due to limitation of the OpenSC framework, - that still is not thoroughly tested in the multi - threads environment. -

    - Your settings will be more secure if you choose to - lock your card. Nevertheless this behavior is a - known violation of PKCS#11 specification. Now once - one application has started using your card with - C_Login, no other application - can use it, until the first is done and calls - C_Logout or - C_Finalize. In the case of many - PKCS#11 application this does not happen until you - exit the application. -

    - Thus it is impossible to use several smart card - aware applications at the same time, e.g. you - cannot run both Firefox - and Thunderbird at the - same time, if both are configured to use your smart - card. -

    - atomic = bool; -

    - By default, interacting with the OpenSC PKCS#11 - module may change the state of the token, e.g. - whether a user is logged in or not (Default: - false). -

    - Thus other users or other applications may change - or use the state of the token unknowingly. Other - applications may create signatures abusing an - existing login or they may logout unnoticed. -

    - With this setting enabled the login state of the - token is tracked and cached (including the PIN). - Every transaction is preceded by restoring the - login state. After every transaction a logout is - performed. This setting by default also enables - lock_login to disable access for - other applications during the atomic transactions. -

    - Please note that any PIN-pad should be disabled - (see enable_pinpad), because the - user would have to input his PIN for every - transaction. -

    - init_sloppy = bool; -

    - With this setting disabled, the OpenSC PKCS#11 - module will initialize the slots available when the - application calls C_GetSlotList. - With this setting enabled, the slots will also get - initialized when C_GetSlotInfo - is called (Default: true). -

    - This setting is a workaround for - Java which does not call - C_GetSlotList when configured - with a static slot instead of - slotListIndex. -

    - user_pin_unblock_style = mode; -

    - User PIN unblock style mode - is one of: -

    • - none (Default): PIN - unblock is not possible with PKCS#11 API -

    • - set_pin_in_unlogged_session: - C_SetPIN in unlogged - session: PUK is passed as the - OldPin argument of the - C_SetPIN call. -

    • - set_pin_in_specific_context: - C_SetPIN in the - CKU_SPECIFIC_CONTEXT - logged session: PUK is passed as the - OldPin argument of the - C_SetPIN call. -

    • - init_pin_in_so_session: - C_InitPIN in - CKU_SO logged session: - User PIN 'UNBLOCK' is protected by SOPIN. - (PUK == SOPIN). -

    -

    - create_puk_slot = bool; -

    - Create slot for unblocking PIN with PUK (Default: - false). This way PKCS#11 API can - be used to login with PUK and change a PIN. May - cause problems with some applications like - Firefox and - Thunderbird. -

    - create_slots_for_pins = mode... ; -

    - Symbolic names of PINs for which slots are created - where mode is a list of: -

    • - all (Default): All - non-SO-PIN, non-unblocking PINs -

    • - user: The first - global or first local PIN -

    • - sign: The second PIN - (first local, second global or second - local) -

    -

    - Card can contain more then one PINs or more then - one on-card application with its own PINs. - Normally, to access all of them with the PKCS#11 - API a slot has to be created for all of them. Many - slots could be ennoying for some of widely used - application, like FireFox. This configuration - parameter allows to select the PIN(s) for which - PKCS#11 slot will be created. -

    - Only PINs initialised, non-SO-PIN, non-unblocking - are associated with symbolic name. -

    - For the module to simulate the opensc-onepin module - behavior the following option - create_slots_for_pins = "user"; -

    Environment

    - OPENSC_CONF -

    - Filename for a user defined configuration file -

    - If this environment variable is not found on - Windows, the registry key - HKLM\Software\OpenSC - Project\OpenSC\ConfigFile is - checked. -

    - CARDMOD_LOW_LEVEL_DEBUG -

    - Write minidriver debug information to - C:\tmp\md.log, if set to - 1. -

    - If this environment variable is not found on - Windows, the registry key - HKLM\Software\OpenSC - Project\OpenSC\MiniDriverDebug is - checked. -

    - PIV_EXT_AUTH_KEY, - PIV_9A_KEY, - PIV_9C_KEY, - PIV_9D_KEY, - PIV_9E_KEY -

    - PIV configuration during initialization with - piv-tool. -

    Files

    - /home/fm/.local/etc/opensc.conf -

    - System-wide configuration file -

    - /home/fm/.local/share/doc/opensc/opensc.conf -

    - Extended example configuration file -

    Security


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    - The pkcs15-init utility for PKCS #15 smart card - personalization is controlled via profiles. When starting, it will read two - such profiles at the moment, a generic application profile, and a card - specific profile. The generic profile must be specified on the command line, - while the card-specific file is selected based on the type of card detected. -

    - The generic application profile defines general information about the card - layout, such as the path of the application DF, various PKCS #15 files within - that directory, and the access conditions on these files. It also defines - general information about PIN, key and certificate objects. Currently, there - is only one such generic profile, pkcs15.profile. -

    - The card specific profile contains additional information required during - card initialization, such as location of PIN files, key references etc. - Profiles currently reside in @pkgdatadir@ -

    Syntax

    - This section should contain information about the profile syntax. Will add - this soonishly. -

    See also

    - pkcs15-init(1), - pkcs15-crypt(1) -

    From fb94b639bc55ddee37d52cde14fc206e66d1764b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sun, 22 Jul 2018 16:23:54 +0200 Subject: [PATCH 0524/4321] doc: Fix the pkcs11-tool example Signed-off-by: Jakub Jelen --- doc/tools/pkcs11-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 37093f352c..c609ec0e22 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -568,7 +568,7 @@ To read the certificate with ID KEY_ID in DER format from smart card: - pkcs11-tool --read-object --id KEY_ID --type cert --outfile cert.der + pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der To convert the certificate in DER format to PEM format, use OpenSSL tools: From be2cc38565c040af0a36b671d59877984678aa19 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 14 Sep 2018 14:11:18 +0200 Subject: [PATCH 0525/4321] p11test: Add missing CKM_SHA224_RSA_PKCS_PSS Signed-off-by: Jakub Jelen --- src/tests/p11test/p11test_case_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index deb2a56fee..d44b0d8e34 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -587,6 +587,8 @@ const char *get_mechanism_name(int mech_id) return "RSA_PKCS_PSS"; case CKM_SHA1_RSA_PKCS_PSS: return "SHA1_RSA_PKCS_PSS"; + case CKM_SHA224_RSA_PKCS_PSS: + return "SHA224_RSA_PKCS_PSS"; case CKM_SHA256_RSA_PKCS_PSS: return "SHA256_RSA_PKCS_PSS"; case CKM_SHA384_RSA_PKCS_PSS: From e5707b545e5a2dc33b0ca52a8bf63f36f71b3d85 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Tue, 25 Aug 2015 12:45:27 +0100 Subject: [PATCH 0526/4321] Add support for PSS padding to RSA signatures A card driver may declare support for computing the padding on the card, or else the padding will be applied locally in padding.c. All five PKCS11 PSS mechanisms are supported, for signature and verification. There are a few limits on what we choose to support, in particular I don't see a need for arbitrary combinations of MGF hash, data hash, and salt length, so I've restricted it (for the user's benefit) to the only cases that really matter, where salt_len = hash_len and the same hash is used for the MGF and data hashing. ------------------------------------------------------------------------ Reworked and extended in 2018 by Jakub Jelen against current OpenSC master, to actually work with existing PIV cards: * extended of missing mechanisms (SHA224, possibility to select MGF1) * compatibility with OpenSSL 1.1+ * Removed the ANSI padding * Formatting cleanup, error checking Based on the original work from https://github.com/NWilson/OpenSC/commit/42f3199e66 Signed-off-by: Jakub Jelen --- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-starcos.c | 4 +- src/libopensc/internal.h | 2 +- src/libopensc/opensc.h | 74 +++++++-- src/libopensc/padding.c | 257 ++++++++++++++++++++++++++---- src/libopensc/pkcs15-sec.c | 33 ++-- src/pkcs11/framework-pkcs15.c | 265 +++++++++++++++++++++++-------- src/pkcs11/mechanism.c | 31 +++- src/pkcs11/openssl.c | 151 ++++++++++++++++-- src/pkcs11/pkcs11.h | 3 +- src/pkcs11/sc-pkcs11.h | 9 +- 11 files changed, 674 insertions(+), 157 deletions(-) diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index fb0b296c8a..05ef0f4413 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -722,7 +722,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, flags = SC_ALGORITHM_RSA_HASH_NONE; tmp_len = sizeof(sbuf); r = sc_pkcs1_encode(card->ctx, flags, data, datalen, - sbuf, &tmp_len, sizeof(sbuf)); + sbuf, &tmp_len, sizeof(sbuf)*8); if (r < 0) return r; } else { diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 7ad132dc12..799c6a6808 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1545,7 +1545,7 @@ static int starcos_compute_signature(sc_card_t *card, flags = SC_ALGORITHM_RSA_HASH_NONE; } tmp_len = sizeof(sbuf); - r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)); + r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_pkcs1_encode failed"); } else { memcpy(sbuf, data, datalen); @@ -1607,7 +1607,7 @@ static int starcos_compute_signature(sc_card_t *card, flags = SC_ALGORITHM_RSA_HASH_NONE; tmp_len = sizeof(sbuf); r = sc_pkcs1_encode(card->ctx, flags, data, datalen, - sbuf, &tmp_len, sizeof(sbuf)); + sbuf, &tmp_len, sizeof(sbuf)*8); if (r < 0) return r; } else { diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 9d6a77ffe4..08d590f231 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -159,7 +159,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, * @return SC_SUCCESS on success and an error code otherwise */ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, - const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t modlen); + const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t mod_bits); /** * Get the necessary padding and sec. env. flags. * @param ctx IN sc_contex_t object diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index b9b960d8f6..a4e87d5bf2 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -93,19 +93,39 @@ extern "C" { #define SC_ALGORITHM_NEED_USAGE 0x40000000 #define SC_ALGORITHM_SPECIFIC_FLAGS 0x001FFFFF -#define SC_ALGORITHM_RSA_RAW 0x00000001 /* If the card is willing to produce a cryptogram padded with the following - * methods, set these flags accordingly. */ -#define SC_ALGORITHM_RSA_PADS 0x0000001E -#define SC_ALGORITHM_RSA_PAD_NONE 0x00000000 -#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 + * methods, set these flags accordingly. These flags are exclusive: an RSA card + * must support at least one of them, and exactly one of them must be selected + * for a given operation. */ +#define SC_ALGORITHM_RSA_RAW 0x00000001 +#define SC_ALGORITHM_RSA_PADS 0x0000001F +#define SC_ALGORITHM_RSA_PAD_NONE 0x00000001 +#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */ #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 -#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 +#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */ /* If the card is willing to produce a cryptogram with the following - * hash values, set these flags accordingly. */ -#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 + * hash values, set these flags accordingly. The interpretation of the hash + * flags depends on the algorithm and padding chosen: for RSA, the hash flags + * determine how the padding is constructed and do not describe the first + * hash applied to the document before padding begins. + * + * - For PAD_NONE, ANSI X9.31, (and ISO9796?), the hash value is therefore + * ignored. For ANSI X9.31, the input data must already have the hash + * identifier byte appended (eg 0x33 for SHA-1). + * - For PKCS1 (v1.5) the hash is recorded in the padding, and HASH_NONE is a + * valid value, meaning that the hash's DigestInfo has already been + * prepended to the data, otherwise the hash id is put on the front. + * - For PSS (PKCS#1 v2.0) the hash is used to derive the padding from the + * already-hashed message. + * + * In no case is the hash actually applied to the entire document. + * + * It's possible that the card may support different hashes for PKCS1 and PSS + * signatures; in this case the card driver has to pick the lowest-denominator + * when it sets these flags to indicate its capabilities. */ +#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */ #define SC_ALGORITHM_RSA_HASH_SHA1 0x00000200 #define SC_ALGORITHM_RSA_HASH_MD5 0x00000400 #define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000800 @@ -114,21 +134,39 @@ extern "C" { #define SC_ALGORITHM_RSA_HASH_SHA384 0x00004000 #define SC_ALGORITHM_RSA_HASH_SHA512 0x00008000 #define SC_ALGORITHM_RSA_HASH_SHA224 0x00010000 -#define SC_ALGORITHM_RSA_HASHES 0x0001FE00 - +#define SC_ALGORITHM_RSA_HASHES 0x0001FF00 + +/* This defines the hashes to be used with MGF1 in PSS padding */ +#define SC_ALGORITHM_MGF1_SHA1 0x00100000 +#define SC_ALGORITHM_MGF1_SHA256 0x00200000 +#define SC_ALGORITHM_MGF1_SHA384 0x00400000 +#define SC_ALGORITHM_MGF1_SHA512 0x00800000 +#define SC_ALGORITHM_MGF1_SHA224 0x01000000 +#define SC_ALGORITHM_MGF1_HASHES 0x01F00000 + +/* These flags are exclusive: a GOST R34.10 card must support at least one or the + * other of the methods, and exactly one of them applies to any given operation. + * Note that the GOST R34.11 hash is actually applied to the data (ie if this + * algorithm is chosen the entire unhashed document is passed in). */ #define SC_ALGORITHM_GOSTR3410_RAW 0x00020000 -#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00040000 +#define SC_ALGORITHM_GOSTR3410_HASH_NONE SC_ALGORITHM_GOSTR3410_RAW /*XXX*/ #define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00080000 -#define SC_ALGORITHM_GOSTR3410_HASHES 0x00080000 -/*TODO: -DEE Should the above be 0x0000E000 */ -/* Or should the HASH_NONE be 0x00000010 and HASHES be 0x00008010 */ - +#define SC_ALGORITHM_GOSTR3410_HASHES 0x000A0000 +/*TODO: -DEE Should the above be 0x000E0000 */ +/* Or should the HASH_NONE be 0x00000100 and HASHES be 0x00080010 */ + +/* The ECDSA flags are exclusive, and exactly one of them applies to any given + * operation. If ECDSA with a hash is specified, then the data passed in is + * the entire document, unhashed, and the hash is applied once to it before + * truncating and signing. These flags are distinct from the RSA hash flags, + * which determine the hash ids the card is willing to put in RSA message + * padding. */ /* May need more bits if card can do more hashes */ /* TODO: -DEE Will overload RSA_HASHES with EC_HASHES */ /* Not clear if these need their own bits or not */ /* The PIV card does not support and hashes */ -#define SC_ALGORITHM_ECDSA_RAW 0x00100000 #define SC_ALGORITHM_ECDH_CDH_RAW 0x00200000 +#define SC_ALGORITHM_ECDSA_RAW 0x00100000 #define SC_ALGORITHM_ECDSA_HASH_NONE SC_ALGORITHM_RSA_HASH_NONE #define SC_ALGORITHM_ECDSA_HASH_SHA1 SC_ALGORITHM_RSA_HASH_SHA1 #define SC_ALGORITHM_ECDSA_HASH_SHA224 SC_ALGORITHM_RSA_HASH_SHA224 @@ -142,7 +180,9 @@ extern "C" { SC_ALGORITHM_ECDSA_HASH_SHA512) /* define mask of all algorithms that can do raw */ -#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_GOSTR3410_RAW | SC_ALGORITHM_ECDSA_RAW) +#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | \ + SC_ALGORITHM_GOSTR3410_RAW | \ + SC_ALGORITHM_ECDSA_RAW) /* extended algorithm bits for selected mechs */ #define SC_ALGORITHM_EXT_EC_F_P 0x00000001 diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index f544e57782..53a87c352e 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -23,6 +23,12 @@ #include "config.h" #endif +#ifdef ENABLE_OPENSSL +#include +#include +#include +#endif + #include #include @@ -231,22 +237,183 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, return SC_ERROR_INTERNAL; } +#ifdef ENABLE_OPENSSL + +static const EVP_MD* hash_flag2md(unsigned int hash) +{ + switch (hash & SC_ALGORITHM_RSA_HASHES) { + case SC_ALGORITHM_RSA_HASH_SHA1: + return EVP_sha1(); + case SC_ALGORITHM_RSA_HASH_SHA224: + return EVP_sha224(); + case SC_ALGORITHM_RSA_HASH_SHA256: + return EVP_sha256(); + case SC_ALGORITHM_RSA_HASH_SHA384: + return EVP_sha384(); + case SC_ALGORITHM_RSA_HASH_SHA512: + return EVP_sha512(); + default: + return NULL; + } +} + +static const EVP_MD* mgf1_flag2md(unsigned int mgf1) +{ + switch (mgf1 & SC_ALGORITHM_MGF1_HASHES) { + case SC_ALGORITHM_MGF1_SHA1: + return EVP_sha1(); + case SC_ALGORITHM_MGF1_SHA224: + return EVP_sha224(); + case SC_ALGORITHM_MGF1_SHA256: + return EVP_sha256(); + case SC_ALGORITHM_MGF1_SHA384: + return EVP_sha384(); + case SC_ALGORITHM_MGF1_SHA512: + return EVP_sha512(); + default: + return NULL; + } +} + +/* add PKCS#1 v2.0 PSS padding */ +static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, + const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) +{ + /* hLen = sLen in our case */ + int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds; + int mgf1_hlen; + const EVP_MD* md, *mgf1_md; + EVP_MD_CTX* ctx = NULL; + u8 buf[8]; + u8 salt[EVP_MAX_MD_SIZE], mask[EVP_MAX_MD_SIZE]; + size_t mod_length = (mod_bits + 7) / 8; + + if (*out_len < mod_length) + return SC_ERROR_BUFFER_TOO_SMALL; + + md = hash_flag2md(hash); + if (md == NULL) + return SC_ERROR_NOT_SUPPORTED; + hlen = EVP_MD_size(md); + dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ + plen = mod_length - 2*hlen - 1; + if (in_len != (unsigned)hlen) + return SC_ERROR_INVALID_ARGUMENTS; + if (2 * (unsigned)hlen + 2 > mod_length) + /* RSA key too small for chosen hash (1296 bits or higher needed for + * signing SHA-512 hashes) */ + return SC_ERROR_NOT_SUPPORTED; + + if (RAND_bytes(salt, hlen) != 1) + return SC_ERROR_INTERNAL; + + /* Hash M' to create H */ + if (!(ctx = EVP_MD_CTX_create())) + goto done; + memset(buf, 0x00, 8); + if (EVP_DigestInit_ex(ctx, md, NULL) != 1 || + EVP_DigestUpdate(ctx, buf, 8) != 1 || + EVP_DigestUpdate(ctx, in, hlen) != 1 || /* mHash */ + EVP_DigestUpdate(ctx, salt, hlen) != 1) { + goto done; + } + + /* Construct padding2, salt, H, and BC in the output block */ + /* DB = PS || 0x01 || salt */ + memset(out, 0x00, plen - 1); /* emLen - sLen - hLen - 2 */ + out[plen - 1] = 0x01; + memcpy(out + plen, salt, hlen); + if (EVP_DigestFinal_ex(ctx, out + dblen, NULL) != 1) { /* H */ + goto done; + } + out[dblen + hlen] = 0xBC; + /* EM = DB* || H || 0xbc + * *the first part is masked later */ + + /* Construct the DB mask block by block and XOR it in. */ + mgf1_md = mgf1_flag2md(mgf1_hash); + if (mgf1_md == NULL) + return SC_ERROR_NOT_SUPPORTED; + mgf1_hlen = EVP_MD_size(mgf1_md); + + mgf_rounds = (dblen + mgf1_hlen - 1) / mgf1_hlen; /* round up */ + for (round = 0; round < mgf_rounds; ++round) { + buf[0] = (round&0xFF000000U) >> 24; + buf[1] = (round&0x00FF0000U) >> 16; + buf[2] = (round&0x0000FF00U) >> 8; + buf[3] = (round&0x000000FFU); + if (EVP_DigestInit_ex(ctx, mgf1_md, NULL) != 1 || + EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */ + EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */ + EVP_DigestFinal_ex(ctx, mask, NULL)) { + goto done; + } + /* this is no longer part of the MGF1, but actually + * XORing mask with DB to create maskedDB inplace */ + for (i = round * mgf1_hlen, j = 0; i < dblen && j < mgf1_hlen; ++i, ++j) { + out[i] ^= mask[j]; + } + } + + /* Set leftmost N bits in leftmost octet in maskedDB to zero + * to make sure the result is smaller than the modulus ( +1) + */ + out[0] &= (0xff >> (8 * mod_length - mod_bits + 1)); + + *out_len = mod_length; + rv = SC_SUCCESS; + +done: + OPENSSL_cleanse(salt, sizeof(salt)); + OPENSSL_cleanse(mask, sizeof(mask)); + if (ctx) { + EVP_MD_CTX_destroy(ctx); + } + return rv; +} + +static int hash_len2algo(size_t hash_len) +{ + switch (hash_len) { + case SHA_DIGEST_LENGTH: + return SC_ALGORITHM_RSA_HASH_SHA1; + case SHA224_DIGEST_LENGTH: + return SC_ALGORITHM_RSA_HASH_SHA224; + case SHA256_DIGEST_LENGTH: + return SC_ALGORITHM_RSA_HASH_SHA256; + case SHA384_DIGEST_LENGTH: + return SC_ALGORITHM_RSA_HASH_SHA384; + case SHA512_DIGEST_LENGTH: + return SC_ALGORITHM_RSA_HASH_SHA512; + } + /* Should never happen -- the mechanism and data should be already + * verified to match one of the above. If not, we will fail later + */ + return SC_ALGORITHM_RSA_HASH_NONE; +} +#endif + /* general PKCS#1 encoding function */ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, - const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_len) + const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) { int rv, i; size_t tmp_len = *out_len; const u8 *tmp = in; unsigned int hash_algo, pad_algo; + size_t mod_len = (mod_bits + 7) / 8; +#ifdef ENABLE_OPENSSL + unsigned int mgf1_hash; +#endif LOG_FUNC_CALLED(ctx); - hash_algo = flags & (SC_ALGORITHM_RSA_HASHES | SC_ALGORITHM_RSA_HASH_NONE); + hash_algo = flags & SC_ALGORITHM_RSA_HASHES; pad_algo = flags & SC_ALGORITHM_RSA_PADS; sc_log(ctx, "hash algorithm 0x%X, pad algorithm 0x%X", hash_algo, pad_algo); - if (hash_algo != SC_ALGORITHM_RSA_HASH_NONE) { + if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || !pad_algo) && + hash_algo != SC_ALGORITHM_RSA_HASH_NONE) { i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len); if (i != SC_SUCCESS) { sc_log(ctx, "Unable to add digest info 0x%x", hash_algo); @@ -268,10 +435,29 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, /* add pkcs1 bt01 padding */ rv = sc_pkcs1_add_01_padding(tmp, tmp_len, out, out_len, mod_len); LOG_FUNC_RETURN(ctx, rv); + case SC_ALGORITHM_RSA_PAD_PSS: + /* add PSS padding */ +#ifdef ENABLE_OPENSSL + mgf1_hash = flags & SC_ALGORITHM_MGF1_HASHES; + if (hash_algo == SC_ALGORITHM_RSA_HASH_NONE) { + /* this is generic RSA_PKCS1_PSS mechanism with hash + * already done outside of the module. The parameters + * were already checked so we need to adjust the hash + * algorithm to do the padding with the correct hash + * function. + */ + hash_algo = hash_len2algo(tmp_len); + } + rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash, + tmp, tmp_len, out, out_len, mod_bits); +#else + rv = SC_ERROR_NOT_SUPPORTED; +#endif + LOG_FUNC_RETURN(ctx, rv); default: - /* currently only pkcs1 padding is supported */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported padding algorithm 0x%x", pad_algo); - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + /* We shouldn't be called with an unexpected padding type, we've already + * returned SC_ERROR_NOT_SUPPORTED if the card can't be used. */ + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); } } @@ -279,42 +465,45 @@ int sc_get_encoding_flags(sc_context_t *ctx, unsigned long iflags, unsigned long caps, unsigned long *pflags, unsigned long *sflags) { - size_t i; - LOG_FUNC_CALLED(ctx); if (pflags == NULL || sflags == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); sc_log(ctx, "iFlags 0x%lX, card capabilities 0x%lX", iflags, caps); - for (i = 0; digest_info_prefix[i].algorithm != 0; i++) { - if (iflags & digest_info_prefix[i].algorithm) { - if (digest_info_prefix[i].algorithm != SC_ALGORITHM_RSA_HASH_NONE && - caps & digest_info_prefix[i].algorithm) - *sflags |= digest_info_prefix[i].algorithm; - else - *pflags |= digest_info_prefix[i].algorithm; - break; - } - } - if (iflags & SC_ALGORITHM_RSA_PAD_PKCS1) { - if (caps & SC_ALGORITHM_RSA_PAD_PKCS1) - *sflags |= SC_ALGORITHM_RSA_PAD_PKCS1; - else - *pflags |= SC_ALGORITHM_RSA_PAD_PKCS1; - } else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { - - /* Work with RSA, EC and maybe GOSTR? */ - if (!(caps & SC_ALGORITHM_RAW_MASK)) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "raw encryption is not supported"); + /* For ECDSA and GOSTR, we don't do any padding or hashing ourselves, the + * card has to support the requested operation. Similarly, for RSA with + * raw padding (raw RSA) and ISO9796, we require the card to do it for us. + * Finally, for PKCS1 (v1.5 and PSS) and ASNI X9.31 we can apply the padding + * ourselves if the card supports raw RSA. */ - *sflags |= (caps & SC_ALGORITHM_RAW_MASK); /* adds in the one raw type */ + /* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and + * ECDSA_HASH_ -> ECDSA_RAW using OpenSSL (not much benefit though). */ + + if ((caps & iflags) == iflags) { + /* Card supports the signature operation we want to do, great, let's + * go with it then. */ + *sflags = iflags; *pflags = 0; - } else if (iflags & SC_ALGORITHM_RSA_PAD_PSS) { - if (caps & SC_ALGORITHM_RSA_PAD_PSS) - *sflags |= SC_ALGORITHM_RSA_PAD_PSS; - else - *pflags |= SC_ALGORITHM_RSA_PAD_PSS; + + } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && + (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { + *sflags |= SC_ALGORITHM_RSA_PAD_PSS; + + } else if (((caps & SC_ALGORITHM_RSA_RAW) && + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) + || iflags & SC_ALGORITHM_RSA_PAD_PSS) { + /* Use the card's raw RSA capability on the padded input */ + *sflags = SC_ALGORITHM_RSA_PAD_NONE; + *pflags = iflags; + + } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { + /* A corner case - the card can partially do PKCS1, if we prepend the + * DigestInfo bit it will do the rest. */ + *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; + *pflags = iflags & SC_ALGORITHM_RSA_HASHES; + } else { LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported algorithm"); } diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 6ee4fa3c74..3e7e03b12d 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -329,7 +329,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: - modlen = prkey->modulus_length / 8; + modlen = (prkey->modulus_length + 7) / 8; break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: modlen = (prkey->modulus_length + 7) / 8 * 2; @@ -377,7 +377,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, if (modlen > tmplen) LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!"); - r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen); + /* XXX Assuming RSA key here */ + r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, prkey->modulus_length); /* no padding needed - already done */ flags &= ~SC_ALGORITHM_RSA_PADS; @@ -391,10 +392,15 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } - /* If the card doesn't support the requested algorithm, see if we - * can strip the input so a more restrictive algo can be used */ + /* If the card doesn't support the requested algorithm, we normally add the + * padding here in software and ask the card to do a raw signature. There's + * one exception to that, where we might be able to get the signature to + * succeed by stripping padding if the card only offers higher-level + * signature operations. The only thing we can strip is the DigestInfo + * block from PKCS1 padding. */ if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && - !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) { + !(alg_info->flags & SC_ALGORITHM_RSA_RAW) && + !(alg_info->flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE))) { unsigned int algo; size_t tmplen = sizeof(buf); @@ -420,19 +426,16 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* add the padding bytes (if necessary) */ if (pad_flags != 0) { - if (flags & SC_ALGORITHM_RSA_PAD_PSS) { - // TODO PSS padding - } else { - size_t tmplen = sizeof(buf); - - r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); + size_t tmplen = sizeof(buf); - inlen = tmplen; - } + /* XXX Assuming RSA key here */ + r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, + prkey->modulus_length); + SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); + inlen = tmplen; } else if ( senv.algorithm == SC_ALGORITHM_RSA && - (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { + (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { /* Add zero-padding if input is shorter than the modulus */ if (inlen < modlen) { if (modlen > sizeof(buf)) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 80f9ce89f3..a75d239f4e 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3478,7 +3478,8 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = { NULL, /* unwrap_key */ NULL, /* decrypt */ NULL, /* derive */ - NULL /* can_do */ + NULL, /* can_do */ + NULL /* init_params */ }; /* @@ -3703,53 +3704,44 @@ static CK_RV pkcs15_prkey_check_pss_param(CK_MECHANISM_PTR pMechanism, CK_ULONG hlen) { CK_RSA_PKCS_PSS_PARAMS *pss_param; - - if (pMechanism->pParameter == NULL) - return CKR_OK; // Support applications that don't provide CK_RSA_PKCS_PSS_PARAMS - - if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) - return CKR_MECHANISM_PARAM_INVALID; + int i; + const unsigned int hash_lens[5] = { 160, 256, 385, 512, 224 }; + const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256, + CKM_SHA384, CKM_SHA512, CKM_SHA224 }; pss_param = (CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; - // Hash parameter must match mechanisms or length of data supplied for CKM_RSA_PKCS_PSS - switch(pss_param->hashAlg) { - case CKM_SHA_1: - if (hlen != 20) - return CKR_MECHANISM_PARAM_INVALID; - break; - case CKM_SHA256: - if (hlen != 32) + // Hash parameter must match length of data supplied for CKM_RSA_PKCS_PSS + for (i = 0; i < 5; i++) { + if (pss_param->hashAlg == hashes[i] + && hlen != hash_lens[i]/8) return CKR_MECHANISM_PARAM_INVALID; - break; - default: - return CKR_MECHANISM_PARAM_INVALID; } + /* other aspects of pss params were already verified during SignInit */ - // SmartCards typically only support MGFs based on the same hash as the - // message digest - switch(pss_param->mgf) { - case CKG_MGF1_SHA1: - if (hlen != 20) - return CKR_MECHANISM_PARAM_INVALID; + return CKR_OK; +} + +static int mgf2flags(CK_RSA_PKCS_MGF_TYPE mgf) +{ + switch (mgf) { + case CKG_MGF1_SHA224: + return SC_ALGORITHM_MGF1_SHA224; break; case CKG_MGF1_SHA256: - if (hlen != 32) - return CKR_MECHANISM_PARAM_INVALID; - break; + return SC_ALGORITHM_MGF1_SHA256; + case CKG_MGF1_SHA384: + return SC_ALGORITHM_MGF1_SHA384; + case CKG_MGF1_SHA512: + return SC_ALGORITHM_MGF1_SHA512; + case CKG_MGF1_SHA1: + return SC_ALGORITHM_MGF1_SHA1; default: - return CKR_MECHANISM_PARAM_INVALID; + return -1; } - - // SmartCards typically support only a salt length equal to the hash length - if (pss_param->sLen != hlen) - return CKR_MECHANISM_PARAM_INVALID; - - return CKR_OK; } - static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData, @@ -3798,35 +3790,74 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, case CKM_SHA512_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512; break; + case CKM_RIPEMD160_RSA_PKCS: + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160; + break; + case CKM_RSA_X_509: + flags = SC_ALGORITHM_RSA_RAW; + break; case CKM_RSA_PKCS_PSS: - rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); + flags = SC_ALGORITHM_RSA_PAD_PSS; + /* The hash was done ouside of the module */ + flags |= SC_ALGORITHM_RSA_HASH_NONE; + /* Omited parameter can use MGF1-SHA1 ? */ + if (pMechanism->pParameter == NULL) { + flags |= SC_ALGORITHM_MGF1_SHA1; + if (ulDataLen != SHA_DIGEST_LENGTH) + return CKR_MECHANISM_PARAM_INVALID; + break; + } - if (rv != CKR_OK) + /* Check the data length matches the selected hash */ + rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); + if (rv != CKR_OK) { + sc_log(context, "Invalid data lenght for the selected " + "PSS parameters"); return rv; + } - flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_NONE; - break; - case CKM_SHA1_RSA_PKCS_PSS: - rv = pkcs15_prkey_check_pss_param(pMechanism, 20); - - if (rv != CKR_OK) - return rv; + /* The MGF parameter was already verified in SignInit() */ + flags |= mgf2flags(((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->mgf); - flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA1; + /* Assuming salt is the size of hash */ break; + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA224_RSA_PKCS_PSS: case CKM_SHA256_RSA_PKCS_PSS: - rv = pkcs15_prkey_check_pss_param(pMechanism, 32); + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + flags = SC_ALGORITHM_RSA_PAD_PSS; + /* Omited parameter can use MGF1-SHA1 and SHA1 hash ? */ + if (pMechanism->pParameter == NULL) { + flags |= SC_ALGORITHM_RSA_HASH_SHA1; + flags |= SC_ALGORITHM_MGF1_SHA1; + break; + } - if (rv != CKR_OK) - return rv; + switch (((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->hashAlg) { + case CKM_SHA_1: + flags |= SC_ALGORITHM_RSA_HASH_SHA1; + break; + case CKM_SHA224: + flags |= SC_ALGORITHM_RSA_HASH_SHA224; + break; + case CKM_SHA256: + flags |= SC_ALGORITHM_RSA_HASH_SHA256; + break; + case CKM_SHA384: + flags |= SC_ALGORITHM_RSA_HASH_SHA384; + break; + case CKM_SHA512: + flags |= SC_ALGORITHM_RSA_HASH_SHA512; + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } - flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA256; - break; - case CKM_RIPEMD160_RSA_PKCS: - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160; - break; - case CKM_RSA_X_509: - flags = SC_ALGORITHM_RSA_RAW; + /* The MGF parameter was already verified in SignInit() */ + flags |= mgf2flags(((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->mgf); + + /* Assuming salt is the size of hash */ break; case CKM_GOSTR3410: flags = SC_ALGORITHM_GOSTR3410_HASH_NONE; @@ -4074,6 +4105,76 @@ pkcs15_prkey_can_do(struct sc_pkcs11_session *session, void *obj, } +static CK_RV +pkcs15_prkey_init_params(struct sc_pkcs11_session *session, + CK_MECHANISM_PTR pMechanism) +{ + const CK_RSA_PKCS_PSS_PARAMS *pss_params; + unsigned int expected_hash = 0, i; + unsigned int expected_salt_len = 0; + const unsigned int salt_lens[5] = { 160, 256, 384, 512, 224 }; + const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256, + CKM_SHA384, CKM_SHA512, CKM_SHA224 }; + + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA224_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + if (!pMechanism->pParameter || + pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) + return CKR_MECHANISM_PARAM_INVALID; + + pss_params = (CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter; + if (pss_params->mgf < CKG_MGF1_SHA1 || pss_params->mgf > CKG_MGF1_SHA224) + return CKR_MECHANISM_PARAM_INVALID; + + /* The hashAlg field can have any value for CKM_RSA_PKCS_PSS and must be + * used again in the PSS padding; for the other mechanisms it strictly + * must match the padding declared in the mechanism. + */ + if (pMechanism->mechanism == CKM_SHA1_RSA_PKCS_PSS) { + expected_hash = CKM_SHA_1; + expected_salt_len = 160; + } else if (pMechanism->mechanism == CKM_SHA224_RSA_PKCS_PSS) { + expected_hash = CKM_SHA224; + expected_salt_len = 224; + } else if (pMechanism->mechanism == CKM_SHA256_RSA_PKCS_PSS) { + expected_hash = CKM_SHA256; + expected_salt_len = 256; + } else if (pMechanism->mechanism == CKM_SHA384_RSA_PKCS_PSS) { + expected_hash = CKM_SHA384; + expected_salt_len = 384; + } else if (pMechanism->mechanism == CKM_SHA512_RSA_PKCS_PSS) { + expected_hash = CKM_SHA512; + expected_salt_len = 512; + } else if (pMechanism->mechanism == CKM_RSA_PKCS_PSS) { + for (i = 0; i < 5; ++i) { + if (hashes[i] == pss_params->hashAlg) { + expected_hash = hashes[i]; + expected_salt_len = salt_lens[i]; + } + } + } + + if (expected_hash != pss_params->hashAlg) + return CKR_MECHANISM_PARAM_INVALID; + + /* We're strict, and only do PSS signatures with a salt length that + * matches the digest length (any shorter is rubbish, any longer + * is useless). */ + if (pss_params->sLen != expected_salt_len / 8) + return CKR_MECHANISM_PARAM_INVALID; + + /* TODO support different salt lengths */ + break; + } + return CKR_OK; +} + + struct sc_pkcs11_object_ops pkcs15_prkey_ops = { pkcs15_prkey_release, pkcs15_prkey_set_attribute, @@ -4084,8 +4185,9 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = { pkcs15_prkey_sign, NULL, /* unwrap */ pkcs15_prkey_decrypt, - pkcs15_prkey_derive, - pkcs15_prkey_can_do + pkcs15_prkey_derive, + pkcs15_prkey_can_do, + pkcs15_prkey_init_params, }; /* @@ -4322,7 +4424,8 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { NULL, /* unwrap_key */ NULL, /* decrypt */ NULL, /* derive */ - NULL /* can_do */ + NULL, /* can_do */ + NULL /* init_params */ }; @@ -4500,7 +4603,8 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = { NULL, /* unwrap_key */ NULL, /* decrypt */ NULL, /* derive */ - NULL /* can_do */ + NULL, /* can_do */ + NULL /* init_params */ }; @@ -4629,7 +4733,8 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { NULL, /* unwrap_key */ NULL, /* decrypt */ NULL, /* derive */ - NULL /* can_do */ + NULL, /* can_do */ + NULL /* init_params */ }; /* @@ -5040,6 +5145,17 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* We support PKCS1 padding in software */ /* either the card supports it or OpenSC does */ rsa_flags |= SC_ALGORITHM_RSA_PAD_PKCS1; +#ifdef ENABLE_OPENSSL + rsa_flags |= SC_ALGORITHM_RSA_PAD_PSS; +#endif + } + + if (rsa_flags & SC_ALGORITHM_RSA_PAD_ISO9796) { + /* Supported in hardware only, if the card driver declares it. */ + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL); + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; } #ifdef ENABLE_OPENSSL @@ -5098,23 +5214,40 @@ register_mechanisms(struct sc_pkcs11_card *p11card) #endif /* ENABLE_OPENSSL */ } - /* TODO support other padding mechanisms */ - if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { - mech_info.flags &= ~(CKF_DECRYPT|CKF_VERIFY); - + mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); + if (rc != CKR_OK) + return rc; + } + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); + if (rc != CKR_OK) + return rc; + } + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, mt); + if (rc != CKR_OK) + return rc; + } + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, mt); if (rc != CKR_OK) return rc; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 5f006c8397..d4ce7fef5c 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -262,11 +262,20 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani if (mt->key_type != key_type) LOG_FUNC_RETURN(context, CKR_KEY_TYPE_INCONSISTENT); + if (pMechanism->pParameter && + pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) + LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); + rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); if (rv != CKR_OK) LOG_FUNC_RETURN(context, rv); memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); + if (pMechanism->pParameter) { + memcpy(&operation->mechanism_params, pMechanism->pParameter, + pMechanism->ulParameterLen); + operation->mechanism.pParameter = &operation->mechanism_params; + } rv = mt->sign_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); @@ -387,6 +396,16 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, } } + /* Validate the mechanism parameters */ + if (key->ops->init_params) { + rv = key->ops->init_params(operation->session, &operation->mechanism); + if (rv != CKR_OK) { + /* Probably bad arguments */ + free(data); + LOG_FUNC_RETURN(context, rv); + } + } + /* If this is a signature with hash operation, * and card cannot perform itself signature with hash operation, * set up the hash operation */ @@ -636,6 +655,16 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, } } + /* Validate the mechanism parameters */ + if (key->ops->init_params) { + rv = key->ops->init_params(operation->session, &operation->mechanism); + if (rv != CKR_OK) { + /* Probably bad arguments */ + free(data); + LOG_FUNC_RETURN(context, rv); + } + } + /* If this is a verify with hash operation, set up the * hash operation */ info = (struct hash_signature_info *) operation->type->mech_data; @@ -729,7 +758,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, params, sizeof(params), - operation->mechanism.mechanism, data->md, + &operation->mechanism, data->md, data->buffer, data->buffer_len, pSignature, ulSignatureLen); done: diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 59de1210d5..e8b2461457 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -68,6 +68,23 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { NULL, /* free_mech_data */ }; +static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { + CKM_SHA224, + { 0, 0, CKF_DIGEST }, + 0, + sizeof(struct sc_pkcs11_operation), + sc_pkcs11_openssl_md_release, + sc_pkcs11_openssl_md_init, + sc_pkcs11_openssl_md_update, + sc_pkcs11_openssl_md_final, + NULL, NULL, NULL, NULL, /* sign_* */ + NULL, NULL, NULL, /* verif_* */ + NULL, NULL, /* decrypt_* */ + NULL, /* derive */ + NULL, /* mech_data */ + NULL, /* free_mech_data */ +}; + static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { CKM_SHA256, { 0, 0, CKF_DIGEST }, @@ -231,6 +248,8 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) openssl_sha1_mech.mech_data = EVP_sha1(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech)); + openssl_sha224_mech.mech_data = EVP_sha224(); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech)); openssl_sha256_mech.mech_data = EVP_sha256(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech)); openssl_sha384_mech.mech_data = EVP_sha384(); @@ -396,7 +415,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, */ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, const unsigned char *pubkey_params, int pubkey_params_len, - CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, + CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, unsigned char *data, int data_len, unsigned char *signat, int signat_len) { @@ -405,7 +424,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, EVP_PKEY *pkey = NULL; const unsigned char *pubkey_tmp = NULL; - if (mech == CKM_GOSTR3410) + if (mech->mechanism == CKM_GOSTR3410) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) return gostr3410_verify_data(pubkey, pubkey_len, @@ -429,37 +448,53 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, if (pkey == NULL) return CKR_GENERAL_ERROR; - if (md != NULL) { + if (md != NULL && (mech->mechanism == CKM_SHA1_RSA_PKCS + || mech->mechanism == CKM_SHA224_RSA_PKCS + || mech->mechanism == CKM_SHA256_RSA_PKCS + || mech->mechanism == CKM_SHA384_RSA_PKCS + || mech->mechanism == CKM_SHA512_RSA_PKCS)) { EVP_MD_CTX *md_ctx = DIGEST_CTX(md); + /* This does not really use the data argument, but the data + * are already collected in the md_ctx + */ + sc_log(context, "Trying to verify using EVP"); res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); EVP_PKEY_free(pkey); if (res == 1) return CKR_OK; - else if (res == 0) + else if (res == 0) { + sc_log(context, "EVP_VerifyFinal(): Signature invalid"); return CKR_SIGNATURE_INVALID; - else { + } else { sc_log(context, "EVP_VerifyFinal() returned %d\n", res); return CKR_GENERAL_ERROR; } - } - else { + } else { RSA *rsa; unsigned char *rsa_out = NULL, pad; int rsa_outlen = 0; - switch(mech) { + sc_log(context, "Trying to verify using low-level API"); + switch (mech->mechanism) { case CKM_RSA_PKCS: pad = RSA_PKCS1_PADDING; break; - case CKM_RSA_X_509: - pad = RSA_NO_PADDING; - break; - /* TODO support more then RSA */ - default: + case CKM_RSA_X_509: + pad = RSA_NO_PADDING; + break; + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA224_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + pad = RSA_NO_PADDING; + break; + default: EVP_PKEY_free(pkey); - return CKR_ARGUMENTS_BAD; - } + return CKR_ARGUMENTS_BAD; + } rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); @@ -473,13 +508,95 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, } rsa_outlen = RSA_public_decrypt(signat_len, signat, rsa_out, rsa, pad); - RSA_free(rsa); - if(rsa_outlen <= 0) { + if (rsa_outlen <= 0) { free(rsa_out); sc_log(context, "RSA_public_decrypt() returned %d\n", rsa_outlen); return CKR_GENERAL_ERROR; } + /* For PSS mechanisms we can not simply compare the "decrypted" + * data -- we need to verify the PSS padding is valid + */ + if (mech->mechanism == CKM_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA1_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA224_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA256_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA384_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA512_RSA_PKCS_PSS) { + CK_RSA_PKCS_PSS_PARAMS* param = NULL; + const EVP_MD *mgf_md, *pss_md; + unsigned char digest[EVP_MAX_MD_SIZE]; + + if (mech->pParameter == NULL) { + sc_log(context, "PSS mechanism requires parameter"); + return CKR_MECHANISM_PARAM_INVALID; + } + + param = (CK_RSA_PKCS_PSS_PARAMS*)mech->pParameter; + switch (param->mgf) { + case CKG_MGF1_SHA1: + mgf_md = EVP_sha1(); + break; + case CKG_MGF1_SHA224: + mgf_md = EVP_sha224(); + break; + case CKG_MGF1_SHA256: + mgf_md = EVP_sha256(); + break; + case CKG_MGF1_SHA384: + mgf_md = EVP_sha384(); + break; + case CKG_MGF1_SHA512: + mgf_md = EVP_sha512(); + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + switch (param->hashAlg) { + case CKM_SHA_1: + pss_md = EVP_sha1(); + break; + case CKM_SHA224: + pss_md = EVP_sha224(); + break; + case CKM_SHA256: + pss_md = EVP_sha256(); + break; + case CKM_SHA384: + pss_md = EVP_sha384(); + break; + case CKM_SHA512: + pss_md = EVP_sha512(); + break; + default: + return CKR_MECHANISM_PARAM_INVALID; + } + + /* for the mechanisms with hash algorithm, the data + * is already added to the hash buffer, so we need + * to finish the hash operation here + */ + if (mech->mechanism != CKM_RSA_PKCS_PSS) { + EVP_MD_CTX *md_ctx = DIGEST_CTX(md); + unsigned char *tmp = digest; + unsigned int tmp_len; + + EVP_DigestFinal(md_ctx, tmp, &tmp_len); + data = tmp; + data_len = tmp_len; + } + rv = CKR_SIGNATURE_INVALID; + if (data_len == EVP_MD_size(pss_md) && + RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, + rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) + rv = CKR_OK; + RSA_free(rsa); + sc_log(context, "Returning %lu", rv); + return rv; + } + RSA_free(rsa); + if (rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) rv = CKR_OK; else diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 61a5050df6..8219b961b8 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -480,8 +480,6 @@ struct ck_date typedef unsigned long ck_mechanism_type_t; -typedef unsigned long int ck_rsa_pkcs_mgf_type_t; - #define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) #define CKM_RSA_PKCS (1UL) #define CKM_RSA_9796 (2UL) @@ -764,6 +762,7 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned char * pPublicData; } CK_ECDH1_DERIVE_PARAMS; +typedef unsigned long ck_rsa_pkcs_mgf_type_t; typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; typedef struct CK_RSA_PKCS_OAEP_PARAMS { diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 8432458820..f0115ed04b 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -119,6 +119,9 @@ struct sc_pkcs11_object_ops { /* Check compatibility of PKCS#15 object usage and an asked PKCS#11 mechanism. */ CK_RV (*can_do)(struct sc_pkcs11_session *, void *, CK_MECHANISM_TYPE, unsigned int); + /* General validation of mechanism parameters (sign, encrypt, etc) */ + CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR); + /* Others to be added when implemented */ }; @@ -290,6 +293,10 @@ typedef struct sc_pkcs11_mechanism_type sc_pkcs11_mechanism_type_t; struct sc_pkcs11_operation { sc_pkcs11_mechanism_type_t *type; CK_MECHANISM mechanism; + union { + CK_RSA_PKCS_PSS_PARAMS pss; + CK_RSA_PKCS_OAEP_PARAMS oaep; + } mechanism_params; struct sc_pkcs11_session *session; void * priv_data; }; @@ -434,7 +441,7 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *, #ifdef ENABLE_OPENSSL CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, const unsigned char *pubkey_params, int pubkey_params_len, - CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, + CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, unsigned char *inp, int inp_len, unsigned char *signat, int signat_len); #endif From 9a853176b8d74e88d6ebef069b7e70f4ae4d6130 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sun, 22 Jul 2018 16:29:19 +0200 Subject: [PATCH 0527/4321] pkcs11-tool: Support for signature verification Signed-off-by: Jakub Jelen --- doc/tools/pkcs11-tool.1.xml | 14 ++ src/tools/pkcs11-tool.c | 273 +++++++++++++++++++++++++++--------- 2 files changed, 222 insertions(+), 65 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index c609ec0e22..fd823c06e7 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -481,6 +481,13 @@ non-zero number. + + + , + + Verify signature of some data. + + , @@ -530,6 +537,13 @@ cert/privkey/pubkey). + + + filename + + The path to the signature file for signature verification + + format diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 64525f6ad2..e3c52e2f8c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -150,6 +150,8 @@ enum { OPT_HASH_ALGORITHM, OPT_MGF, OPT_SALT, + OPT_VERIFY, + OPT_SIGNATURE_FILE, }; static const struct option options[] = { @@ -161,6 +163,7 @@ static const struct option options[] = { { "list-objects", 0, NULL, 'O' }, { "sign", 0, NULL, 's' }, + { "verify", 0, NULL, OPT_VERIFY }, { "decrypt", 0, NULL, OPT_DECRYPT }, { "hash", 0, NULL, 'h' }, { "derive", 0, NULL, OPT_DERIVE }, @@ -203,6 +206,7 @@ static const struct option options[] = { { "set-id", 1, NULL, 'e' }, { "attr-from", 1, NULL, OPT_ATTR_FROM }, { "input-file", 1, NULL, 'i' }, + { "signature-file", 1, NULL, OPT_SIGNATURE_FILE }, { "output-file", 1, NULL, 'o' }, { "signature-format", 1, NULL, 'f' }, @@ -230,6 +234,7 @@ static const char *option_help[] = { "Show objects on token", "Sign some data", + "Verify a signature of some data", "Decrypt some data", "Hash some data", "Derive a secret key using another key and some data", @@ -272,6 +277,7 @@ static const char *option_help[] = { "Set the CKA_ID of an object, = the (new) CKA_ID", "Use to create some attributes when writing an object", "Specify the input file", + "Specify the file with signature for verification", "Specify the output file", "Format for ECDSA signature : 'rs' (default), 'sequence', 'openssl'", @@ -293,6 +299,7 @@ static const char * app_name = "pkcs11-tool"; /* for utils.c */ static int verbose = 0; static const char * opt_input = NULL; static const char * opt_output = NULL; +static const char * opt_signature_file = NULL; static const char * opt_module = DEFAULT_PKCS11_PROVIDER; static int opt_slot_set = 0; static CK_SLOT_ID opt_slot = 0; @@ -331,8 +338,8 @@ static int opt_derive_pass_der = 0; static unsigned long opt_random_bytes = 0; static CK_MECHANISM_TYPE opt_hash_alg = 0; static unsigned long opt_mgf = 0; -static long salt_len = 0; -static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ +static long opt_salt_len = 0; +static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -396,6 +403,7 @@ static void show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj); static void sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +static void verify_signature(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE); static void derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); @@ -532,6 +540,7 @@ int main(int argc, char * argv[]) int do_list_mechs = 0; int do_list_objects = 0; int do_sign = 0; + int do_verify = 0; int do_decrypt = 0; int do_hash = 0; int do_derive = 0; @@ -685,6 +694,9 @@ int main(int argc, char * argv[]) case 'i': opt_input = optarg; break; + case OPT_SIGNATURE_FILE: + opt_signature_file = optarg; + break; case 'l': need_session |= NEED_SESSION_RW; opt_login = 1; @@ -700,8 +712,8 @@ int main(int argc, char * argv[]) opt_mgf = p11_name_to_mgf(optarg); break; case OPT_SALT: - salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); - salt_len_given = 1; + opt_salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); + opt_salt_len_given = 1; break; case 'o': opt_output = optarg; @@ -726,6 +738,11 @@ int main(int argc, char * argv[]) do_sign = 1; action_count++; break; + case OPT_VERIFY: + need_session |= NEED_SESSION_RO; + do_verify = 1; + action_count++; + break; case OPT_DECRYPT: need_session |= NEED_SESSION_RW; do_decrypt = 1; @@ -1037,6 +1054,16 @@ int main(int argc, char * argv[]) util_fatal("Private key not found"); } + if (do_verify) { + if (!find_object(session, CKO_PUBLIC_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0) && + !find_object(session, CKO_CERTIFICATE, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0)) + util_fatal("Public key nor certificate not found"); + } + /* before list objects, so we can see a derived key */ if (do_derive) derive_key(opt_slot, session, object); @@ -1047,6 +1074,9 @@ int main(int argc, char * argv[]) if (do_sign) sign_data(opt_slot, session, object); + if (do_verify) + verify_signature(opt_slot, session, object); + if (do_decrypt) decrypt_data(opt_slot, session, object); @@ -1636,7 +1666,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) } /* return digest length in bytes */ -static unsigned long figure_pss_salt_length(const int hash) { +static unsigned long hash_length(const int hash) { unsigned long sLen = 0; switch (hash) { case CKM_SHA_1: @@ -1662,26 +1692,16 @@ static unsigned long figure_pss_salt_length(const int hash) { return sLen; } -static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE key) +static unsigned long +parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, + CK_MECHANISM *mech, CK_RSA_PKCS_PSS_PARAMS *pss_params) { - unsigned char in_buffer[1025], sig_buffer[512]; - CK_MECHANISM mech; - CK_RSA_PKCS_PSS_PARAMS pss_params; - CK_RV rv; - CK_ULONG sig_len; - int fd, r; + unsigned long hashlen = 0; - unsigned long hashlen = 0, modlen = 0; - - if (!opt_mechanism_used) - if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) - util_fatal("Sign mechanism not supported"); + if (pss_params == NULL) + return 0; - fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); - memset(&mech, 0, sizeof(mech)); - mech.mechanism = opt_mechanism; - pss_params.hashAlg = 0; + pss_params->hashAlg = 0; if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS) util_fatal("The hash-algorithm is applicable only to " @@ -1690,93 +1710,118 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { case CKM_RSA_PKCS_PSS: - pss_params.hashAlg = opt_hash_alg; + pss_params->hashAlg = opt_hash_alg; switch (opt_hash_alg) { case CKM_SHA224: - pss_params.mgf = CKG_MGF1_SHA224; + pss_params->mgf = CKG_MGF1_SHA224; break; case CKM_SHA256: - pss_params.mgf = CKG_MGF1_SHA256; + pss_params->mgf = CKG_MGF1_SHA256; break; case CKM_SHA384: - pss_params.mgf = CKG_MGF1_SHA384; + pss_params->mgf = CKG_MGF1_SHA384; break; case CKM_SHA512: - pss_params.mgf = CKG_MGF1_SHA512; + pss_params->mgf = CKG_MGF1_SHA512; break; default: /* the PSS should use SHA-1 if not specified */ - pss_params.hashAlg = CKM_SHA_1; + pss_params->hashAlg = CKM_SHA_1; /* fallthrough */ case CKM_SHA_1: - pss_params.mgf = CKG_MGF1_SHA1; + pss_params->mgf = CKG_MGF1_SHA1; } break; case CKM_SHA1_RSA_PKCS_PSS: - pss_params.hashAlg = CKM_SHA_1; - pss_params.mgf = CKG_MGF1_SHA1; + pss_params->hashAlg = CKM_SHA_1; + pss_params->mgf = CKG_MGF1_SHA1; break; case CKM_SHA224_RSA_PKCS_PSS: - pss_params.hashAlg = CKM_SHA224; - pss_params.mgf = CKG_MGF1_SHA224; + pss_params->hashAlg = CKM_SHA224; + pss_params->mgf = CKG_MGF1_SHA224; break; case CKM_SHA256_RSA_PKCS_PSS: - pss_params.hashAlg = CKM_SHA256; - pss_params.mgf = CKG_MGF1_SHA256; + pss_params->hashAlg = CKM_SHA256; + pss_params->mgf = CKG_MGF1_SHA256; break; case CKM_SHA384_RSA_PKCS_PSS: - pss_params.hashAlg = CKM_SHA384; - pss_params.mgf = CKG_MGF1_SHA384; + pss_params->hashAlg = CKM_SHA384; + pss_params->mgf = CKG_MGF1_SHA384; break; case CKM_SHA512_RSA_PKCS_PSS: - pss_params.hashAlg = CKM_SHA512; - pss_params.mgf = CKG_MGF1_SHA512; + pss_params->hashAlg = CKM_SHA512; + pss_params->mgf = CKG_MGF1_SHA512; break; } /* One of RSA-PSS mechanisms above: They need parameters */ - if (pss_params.hashAlg) { + if (pss_params->hashAlg) { if (opt_mgf != 0) - pss_params.mgf = opt_mgf; + pss_params->mgf = opt_mgf; - hashlen = figure_pss_salt_length(pss_params.hashAlg); + hashlen = hash_length(pss_params->hashAlg); - if (salt_len_given == 1) { /* salt size explicitly given */ - if (salt_len < 0 && salt_len != -1 && salt_len != -2) - util_fatal("Salt length must be greater or equal \ -to zero, or equal to -1 (meaning: use digest size) or to -2 \ -(meaning: use maximum permissible size"); + if (opt_salt_len_given == 1) { /* salt size explicitly given */ + unsigned long modlen = 0; + if (opt_salt_len < 0 && opt_salt_len != -1 && opt_salt_len != -2) + util_fatal("Salt length must be greater or equal " + "to zero, or equal to -1 (meaning: use digest size) " + "or to -2 (meaning: use maximum permissible size"); modlen = (get_private_key_length(session, key) + 7) / 8; - switch(salt_len) { + switch (opt_salt_len) { case -1: /* salt size equals to digest size */ - pss_params.sLen = hashlen; + pss_params->sLen = hashlen; break; case -2: /* maximum permissible salt len */ - pss_params.sLen = modlen - hashlen -2; + pss_params->sLen = modlen - hashlen -2; break; default: /* use given size but its value must be >= 0 */ - pss_params.sLen = salt_len; + pss_params->sLen = opt_salt_len; break; - } /* end switch (salt_len_given) */ + } /* end switch (opt_salt_len_given) */ } else { /* use default: salt len of digest size */ - pss_params.sLen = hashlen; + pss_params->sLen = hashlen; } - mech.pParameter = &pss_params; - mech.ulParameterLen = sizeof(pss_params); + mech->pParameter = pss_params; + mech->ulParameterLen = sizeof(*pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt_len=%lu B\n", - p11_mechanism_to_name(pss_params.hashAlg), - p11_mgf_to_name(pss_params.mgf), - pss_params.sLen); + p11_mechanism_to_name(pss_params->hashAlg), + p11_mgf_to_name(pss_params->mgf), + pss_params->sLen); } + return hashlen; +} + +static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + unsigned char in_buffer[1025], sig_buffer[512]; + CK_MECHANISM mech; + CK_RSA_PKCS_PSS_PARAMS pss_params; + CK_RV rv; + CK_ULONG sig_len; + int fd, r; + unsigned long hashlen; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) + util_fatal("Sign mechanism not supported"); + + fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); + memset(&mech, 0, sizeof(mech)); + mech.mechanism = opt_mechanism; + hashlen = parse_pss_params(session, key, &mech, &pss_params); + if (hashlen == 0) + util_fatal("Invalid RSA-PSS parameters"); if (opt_input == NULL) fd = 0; @@ -1787,12 +1832,15 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ if (r < 0) util_fatal("Cannot read from %s: %m", opt_input); - if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) - util_fatal("For %s mechanism, message size (got %d bytes) must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), r, hashlen); + if (opt_mechanism == CKM_RSA_PKCS_PSS) { + if ((unsigned long)r != hashlen) + util_fatal("For %s mechanism, message size (got %d bytes) " + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), r, hashlen); + } rv = CKR_CANCEL; - if (r < (int) sizeof(in_buffer)) { + if (r < (int) sizeof(in_buffer)) { rv = p11->C_SignInit(session, &mech, key); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); @@ -1833,12 +1881,16 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ util_fatal("failed to open %s: %m", opt_output); } - if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { - if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { + if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || + opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || + opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { + if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || + !strcmp(opt_sig_format, "sequence"))) { unsigned char *seq; size_t seqlen; - if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer, sig_len, &seq, &seqlen)) { + if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer, + sig_len, &seq, &seqlen)) { util_fatal("Failed to convert signature to ASN.1 sequence format"); } @@ -1856,6 +1908,97 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ close(fd); } +static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + unsigned char in_buffer[1025], sig_buffer[512]; + CK_MECHANISM mech; + CK_RSA_PKCS_PSS_PARAMS pss_params; + CK_RV rv; + CK_ULONG sig_len; + int fd, fd2, r, r2; + unsigned long hashlen; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_VERIFY|CKF_HW, NULL, 0, &opt_mechanism)) + util_fatal("Mechanism not supported for signature verification"); + + fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); + memset(&mech, 0, sizeof(mech)); + mech.mechanism = opt_mechanism; + hashlen = parse_pss_params(session, key, &mech, &pss_params); + if (hashlen == 0) + util_fatal("Invalid RSA-PSS parameters"); + + /* Open a signature file */ + if (opt_signature_file == NULL) + util_fatal("No file with signature provided. Use --signature-file"); + else if ((fd2 = open(opt_signature_file, O_RDONLY|O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_signature_file); + + r2 = read(fd2, sig_buffer, sizeof(sig_buffer)); + if (r2 < 0) + util_fatal("Cannot read from %s: %m", opt_signature_file); + + close(fd2); + + /* Open the data file */ + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + r = read(fd, in_buffer, sizeof(in_buffer)); + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); + + if (opt_mechanism == CKM_RSA_PKCS_PSS) { + if ((unsigned long)r != hashlen) + util_fatal("For %s mechanism, message size (got %d bytes)" + " must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), r, hashlen); + } + + rv = CKR_CANCEL; + if (r < (int) sizeof(in_buffer)) { + rv = p11->C_VerifyInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_VerifyInit", rv); + + sig_len = r2; + rv = p11->C_Verify(session, in_buffer, r, sig_buffer, sig_len); + } + + if (rv != CKR_OK) { + rv = p11->C_VerifyInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_VerifyInit", rv); + + do { + rv = p11->C_VerifyUpdate(session, in_buffer, r); + if (rv != CKR_OK) + p11_fatal("C_VerifyUpdate", rv); + + r = read(fd, in_buffer, sizeof(in_buffer)); + } while (r > 0); + + sig_len = sizeof(sig_buffer); + rv = p11->C_VerifyFinal(session, sig_buffer, sig_len); + if (rv != CKR_OK) + p11_fatal("C_VerifyFinal", rv); + } + + if (fd != 0) + close(fd); + + if (rv == CKR_OK) + printf("Signature is valid\n"); + else if (rv == CKR_SIGNATURE_INVALID) + printf("Invalid signature\n"); + else + printf("Cryptoki returned erorr: %s\n", CKR2Str(rv)); +} + static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) From 424d828627d470d6b79d2a0537d32ac343f426ad Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 14 Sep 2018 17:27:11 +0200 Subject: [PATCH 0528/4321] slot: Switch cleanup steps to avoid segfaults on errors and some more sanity checking Signed-off-by: Jakub Jelen --- src/pkcs11/framework-pkcs15.c | 2 +- src/pkcs11/slot.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index a75d239f4e..85e12df660 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -365,7 +365,7 @@ pkcs15_unbind(struct sc_pkcs11_card *p11card) unlock_card(fw_data); - if (fw_data->p15_card) { + if (fw_data->p15_card && fw_data->p15_card->card) { if (idx == 0) { int rc = sc_detect_card_presence(fw_data->p15_card->card->reader); if (rc <= 0 || rc & SC_READER_CARD_CHANGED) { diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index fe322e68e6..3102bf986a 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -374,10 +374,10 @@ CK_RV card_detect(sc_reader_t *reader) fail: if (free_p11card) { - if (p11card->card != NULL) - sc_disconnect_card(p11card->card); if (p11card->framework) p11card->framework->unbind(p11card); + if (p11card->card != NULL) + sc_disconnect_card(p11card->card); free(p11card); } From e456e609a6424ece0a68bc99c3bb658343b733e4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 16:13:13 +0200 Subject: [PATCH 0529/4321] Avoid memory leaks during verification --- src/pkcs11/openssl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index e8b2461457..00b9814e4c 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -509,6 +509,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, rsa_outlen = RSA_public_decrypt(signat_len, signat, rsa_out, rsa, pad); if (rsa_outlen <= 0) { + RSA_free(rsa); free(rsa_out); sc_log(context, "RSA_public_decrypt() returned %d\n", rsa_outlen); return CKR_GENERAL_ERROR; @@ -528,6 +529,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, unsigned char digest[EVP_MAX_MD_SIZE]; if (mech->pParameter == NULL) { + RSA_free(rsa); + free(rsa_out); sc_log(context, "PSS mechanism requires parameter"); return CKR_MECHANISM_PARAM_INVALID; } @@ -550,6 +553,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, mgf_md = EVP_sha512(); break; default: + RSA_free(rsa); + free(rsa_out); return CKR_MECHANISM_PARAM_INVALID; } @@ -570,6 +575,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, pss_md = EVP_sha512(); break; default: + RSA_free(rsa); + free(rsa_out); return CKR_MECHANISM_PARAM_INVALID; } @@ -592,6 +599,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) rv = CKR_OK; RSA_free(rsa); + free(rsa_out); sc_log(context, "Returning %lu", rv); return rv; } From 83b188c950bce3846b09e7b8676c46080e239e91 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 6 Sep 2018 23:53:14 +0300 Subject: [PATCH 0530/4321] Remove long expired EstEID 1.0/1.1 card support Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 27 +++++---------------------- src/libopensc/cards.h | 2 -- src/libopensc/pkcs15-syn.c | 2 -- src/tools/eidenv.c | 2 +- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index ea1a52dbfa..c11c446253 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -43,14 +43,6 @@ static const struct sc_atr_table mcrd_atrs[] = { "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, {"3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6", NULL, "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL}, - /* Certain pcsc-lite versions (1.5.3 for example on Ubuntu 10.04) incorrectly truncate the warm ATR to the length of the cold ATR */ - /* See opensc.conf for further information */ - {"3B:FE:94:00:FF:80:B1:FA:45:1F:03:45:73:74:45:49:44:20", NULL, "Broken EstEID 1.1 warm", SC_CARD_TYPE_MCRD_ESTEID_V11, 0, NULL}, - {"3b:fe:94:00:ff:80:b1:fa:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:43", NULL, "EstEID 1.0 cold", SC_CARD_TYPE_MCRD_ESTEID_V10, 0, NULL}, - {"3b:6e:00:ff:45:73:74:45:49:44:20:76:65:72:20:31:2e:30", NULL, "EstEID 1.0 cold", SC_CARD_TYPE_MCRD_ESTEID_V10, 0, NULL}, - {"3b:de:18:ff:c0:80:b1:fe:45:1f:03:45:73:74:45:49:44:20:76:65:72:20:31:2e:30:2b", NULL, "EstEID 1.0 cold 2006", SC_CARD_TYPE_MCRD_ESTEID_V10, 0, NULL}, - {"3b:5e:11:ff:45:73:74:45:49:44:20:76:65:72:20:31:2e:30", NULL, "EstEID 1.0 warm 2006", SC_CARD_TYPE_MCRD_ESTEID_V10, 0, NULL}, - {"3b:6e:00:00:45:73:74:45:49:44:20:76:65:72:20:31:2e:30", NULL, "EstEID 1.1 cold", SC_CARD_TYPE_MCRD_ESTEID_V11, 0, NULL}, {"3B:FE:18:00:00:80:31:FE:45:45:73:74:45:49:44:20:76:65:72:20:31:2E:30:A8", NULL, "EstEID 3.0 (dev1) cold", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL}, {"3B:FE:18:00:00:80:31:FE:45:80:31:80:66:40:90:A4:56:1B:16:83:01:90:00:86", NULL, "EstEID 3.0 (dev1) warm", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL}, {"3b:fe:18:00:00:80:31:fe:45:80:31:80:66:40:90:a4:16:2a:00:83:01:90:00:e1", NULL, "EstEID 3.0 (dev2) warm", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL}, @@ -66,7 +58,7 @@ static const struct sc_aid AzeDIT_v35_AID = { {0xD0, 0x31, 0x00, 0x00, 0x00, 0x4 static struct sc_card_operations mcrd_ops; static struct sc_card_driver mcrd_drv = { - "MICARDO 2.1 / EstEID 1.0 - 3.5", + "MICARDO 2.1 / EstEID 3.0 - 3.5", "mcrd", &mcrd_ops, NULL, 0, NULL @@ -287,16 +279,11 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } -int is_esteid_card(sc_card_t *card) { - switch(card->type) { - case SC_CARD_TYPE_MCRD_ESTEID_V10: - case SC_CARD_TYPE_MCRD_ESTEID_V11: - case SC_CARD_TYPE_MCRD_ESTEID_V30: - return 1; - } - - return 0; +int is_esteid_card(sc_card_t *card) +{ + return card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 ? 1 : 0; } + static int mcrd_match_card(sc_card_t * card) { int i = 0, r = 0; @@ -333,10 +320,6 @@ static int mcrd_init(sc_card_t * card) if (is_esteid_card(card)) { - /* Reset the MULTOS card to get to a known state */ - if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V11) - sc_reset(card, 0); - /* Select the EstEID AID to get to a known state. * For some reason a reset is required as well... */ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) { diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 23e7c5d10b..5d545b3583 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -74,8 +74,6 @@ enum { /* mcrd driver */ SC_CARD_TYPE_MCRD_BASE = 5000, SC_CARD_TYPE_MCRD_GENERIC, - SC_CARD_TYPE_MCRD_ESTEID_V10, - SC_CARD_TYPE_MCRD_ESTEID_V11, SC_CARD_TYPE_MCRD_ESTEID_V30, SC_CARD_TYPE_MCRD_DTRUST, diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 30fd0ff84f..ab71dcdb14 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -75,8 +75,6 @@ static const char *exfunc_name = "sc_pkcs15_init_func_ex"; int sc_pkcs15_is_emulation_only(sc_card_t *card) { switch (card->type) { - case SC_CARD_TYPE_MCRD_ESTEID_V10: - case SC_CARD_TYPE_MCRD_ESTEID_V11: case SC_CARD_TYPE_MCRD_ESTEID_V30: case SC_CARD_TYPE_GEMSAFEV1_PTEID: case SC_CARD_TYPE_OPENPGP_V1: diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index b141f5d5a5..41df16c56a 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -408,7 +408,7 @@ int main(int argc, char **argv) } /* Check card type */ - if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V10 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V11 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) + if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) do_esteid(card); else if (card->type == SC_CARD_TYPE_BELPIC_EID) do_belpic(card); From b9e33a3c640ebf85de862a534e8b23693981fa0c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 29 Nov 2017 11:35:21 +0100 Subject: [PATCH 0531/4321] Coverity warnings card-piv.c make sure the string is null terminated before passing it to hex_to_bin routine, which expects it pkcs15-cac.c free cn_name on failure pkcs11-tool.c make sure the string is null terminated before passing it to parse_certificate(), which expects it --- src/libopensc/card-piv.c | 5 +++-- src/libopensc/pkcs15-cac.c | 1 + src/tools/pkcs11-tool.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 61acedc818..1a89017594 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1481,7 +1481,7 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l FILE *f = NULL; char * keyfilename = NULL; size_t expected_keylen; - size_t keylen; + size_t keylen, readlen; u8 * keybuf = NULL; u8 * tkey = NULL; @@ -1530,11 +1530,12 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l } keybuf[fsize] = 0x00; /* in case it is text need null */ - if (fread(keybuf, 1, fsize, f) != fsize) { + if ((readlen = fread(keybuf, 1, fsize, f)) != fsize) { sc_log(card->ctx, " Unable to read key\n"); r = SC_ERROR_WRONG_LENGTH; goto err; } + keybuf[readlen] = '\0'; tkey = malloc(expected_keylen); if (!tkey) { diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 93032113c1..f34425a5e0 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -388,6 +388,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) if (r == SC_SUCCESS) { token_name = malloc (cn_len+1); if (!token_name) { + free(cn_name); r = SC_ERROR_OUT_OF_MEMORY; goto fail; } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e3c52e2f8c..df4a0ef326 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2838,9 +2838,10 @@ static int write_object(CK_SESSION_HANDLE session) if (!(f = fopen(opt_attr_from_file, "rb"))) util_fatal("Couldn't open file \"%s\"", opt_attr_from_file); certdata_len = fread(certdata, 1, sizeof(certdata), f); + fclose(f); if (certdata_len < 0) util_fatal("Couldn't read from file \"%s\"", opt_attr_from_file); - fclose(f); + certdata[certdata_len] = '\0'; need_to_parse_certdata = 1; } if (opt_object_class == CKO_CERTIFICATE) { From e5da6b66b9b2e4d794b38d8bc52f42b98562b26a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 09:59:24 +0200 Subject: [PATCH 0532/4321] iso7816: Replace asserts with explicit length checks to make coverity happy --- src/libopensc/iso7816.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 718d92ff79..6abd2d76c5 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -841,13 +841,18 @@ iso7816_set_security_env(struct sc_card *card, if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { if (env->file_ref.len > 0xFF) return SC_ERROR_INVALID_ARGUMENTS; + if (sizeof(sbuf) - (p - sbuf) < env->file_ref.len + 2) + return SC_ERROR_OFFSET_TOO_LARGE; + *p++ = 0x81; *p++ = (u8) env->file_ref.len; - assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len); memcpy(p, env->file_ref.value, env->file_ref.len); p += env->file_ref.len; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { + if (sizeof(sbuf) - (p - sbuf) < env->key_ref_len + 2) + return SC_ERROR_OFFSET_TOO_LARGE; + if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else @@ -855,7 +860,6 @@ iso7816_set_security_env(struct sc_card *card, if (env->key_ref_len > 0xFF) return SC_ERROR_INVALID_ARGUMENTS; *p++ = env->key_ref_len & 0xFF; - assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len); memcpy(p, env->key_ref, env->key_ref_len); p += env->key_ref_len; } From 8e0078a6f9baf784923a261368769146104daf85 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 10:52:35 +0200 Subject: [PATCH 0533/4321] pkcs15-myeid: Do not confuse coverity with potential double-free --- src/pkcs15init/pkcs15-myeid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 29f9aa2220..a7da3c6c55 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -232,6 +232,7 @@ myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df for (ii = 0; create_dfs[ii]; ii++) { sc_log(ctx, "Create '%s'", create_dfs[ii]); + file = NULL; r = sc_profile_get_file(profile, create_dfs[ii], &file); sc_file_free(file); if (r) { From b8133c2545e18fdf5294a6478eeab09bec60c8e6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 11:47:44 +0200 Subject: [PATCH 0534/4321] pkcs15-myeid: Return value checking --- src/pkcs15init/pkcs15-myeid.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index a7da3c6c55..8b927d0972 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -434,7 +434,11 @@ _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, unsigned operations, unsigned mechanism, const struct sc_object_id *oid) { struct sc_supported_algo_info *algo; + struct sc_context *ctx = p15card->card->ctx; algo = sc_pkcs15_get_supported_algo(p15card, operations, mechanism); + int rv; + + LOG_FUNC_CALLED(ctx); if (!algo) { unsigned ref = 1, ii; @@ -452,7 +456,10 @@ _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, } } - sc_pkcs15_add_supported_algo_ref(object, algo); + rv = sc_pkcs15_add_supported_algo_ref(object, algo); + if (rv != SC_SUCCESS) { + sc_log(ctx, "Failed to add algorithms refs"); + } } static void From a2ab2071bb2d64804f45eb7dc7d710d613a2b02b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 12:20:39 +0200 Subject: [PATCH 0535/4321] piv: Check return value of sc_lock() --- src/libopensc/card-piv.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 1a89017594..7cbf84b20c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -922,7 +922,11 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, "#%d", enumtag); - sc_lock(card); /* do check len and get data in same transaction */ + r = sc_lock(card); /* do check len and get data in same transaction */ + if (r != SC_SUCCESS) { + sc_log(card->ctx, "sc_lock failed"); + return r; + } /* assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); */ @@ -2982,7 +2986,7 @@ static int piv_match_card(sc_card_t *card) static int piv_match_card_continued(sc_card_t *card) { - int i; + int i, r; int type = -1; piv_private_data_t *priv = NULL; int saved_type = card->type; @@ -3081,7 +3085,13 @@ static int piv_match_card_continued(sc_card_t *card) if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - sc_lock(card); + r = sc_lock(card); + if (r != SC_SUCCESS) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "sc_lock failed\n"); + piv_finish(card); + card->type = saved_type; + return 0; + } /* * detect if active AID is PIV. NIST 800-73 says Only one PIV application per card @@ -3465,7 +3475,11 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { priv->context_specific = 1; sc_log(card->ctx,"Starting CONTEXT_SPECIFIC verify"); - sc_lock(card); + r = sc_lock(card); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "sc_lock failed"); + return r; + } } priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ From 65e1cd2df713800c748be4d67a557b7c170ee250 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 13:05:15 +0200 Subject: [PATCH 0536/4321] muscle: Check return values --- src/libopensc/card-muscle.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index c91b8d5e01..be5b9f146b 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -455,6 +455,7 @@ static int _listFile(mscfs_file_t *file, int reset, void *udata) static int muscle_init(sc_card_t *card) { muscle_private_t *priv; + int r; card->name = "MuscleApplet"; card->drv_data = malloc(sizeof(muscle_private_t)); @@ -478,7 +479,10 @@ static int muscle_init(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG; /* Card type detection */ - _sc_match_atr(card, muscle_atrs, &card->type); + r = _sc_match_atr(card, muscle_atrs, &card->type); + if (r < 0) { + sc_log(card->ctx, "Failed to match the ATRs"); + } if(card->type == SC_CARD_TYPE_MUSCLE_ETOKEN_72K) { card->caps |= SC_CARD_CAP_APDU_EXT; } From a85a4a8b484f468c3ab1661b066b1b3d968b0608 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 13:18:16 +0200 Subject: [PATCH 0537/4321] pkcs15-authentic: Avoid memory leak on failure --- src/pkcs15init/pkcs15-authentic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index ddccd03256..0b6f9c1766 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -355,7 +355,6 @@ authentic_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, sc_file_free(file); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate 'sc_authentic_sdo'"); } - *out = sdo; sdo->magic = AUTHENTIC_SDO_MAGIC; sdo->docp.id = key_info->key_reference & ~AUTHENTIC_OBJECT_REF_FLAG_LOCAL; @@ -364,11 +363,16 @@ authentic_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, rv = authentic_docp_set_acls(card, file, authentic_v3_rsa_ac_ops, sizeof(authentic_v3_rsa_ac_ops)/sizeof(authentic_v3_rsa_ac_ops[0]), &sdo->docp); sc_file_free(file); - LOG_TEST_RET(ctx, rv, "Cannot set key ACLs from file"); + if (rv != SC_SUCCESS) { + free(sdo); + sc_log(ctx, "Cannot set key ACLs from file"); + LOG_FUNC_RETURN(ctx, rv); + } sc_log(ctx, "sdo(mech:%X,id:%X,acls:%s)", sdo->docp.mech, sdo->docp.id, sc_dump_hex(sdo->docp.acl_data, sdo->docp.acl_data_len)); + *out = sdo; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } From 674e5e8b3dcc9b2278c0ad98bb55315f07c7c42d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 13:24:32 +0200 Subject: [PATCH 0538/4321] ctx: Require dll parameter otherwise we are leaking it --- src/libopensc/ctx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 626686a73f..f24a61ca0a 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -452,6 +452,10 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name const char *(*modversion)(void) = NULL; const char *(**tmodv)(void) = &modversion; + if (dll == NULL) { + sc_log(ctx, "No dll parameter specified"); + return NULL; + } if (name == NULL) { /* should not occur, but... */ sc_log(ctx, "No module specified"); return NULL; @@ -481,8 +485,8 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name sc_dlclose(handle); return NULL; } - if (dll) - *dll = handle; + + *dll = handle; sc_log(ctx, "successfully loaded card driver '%s'", name); return modinit(name); } From 74105300bff78e925df908dc1fca41b9e19f50f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 13:50:05 +0200 Subject: [PATCH 0539/4321] card-iasecc: Avoid memory leaks on failure --- src/libopensc/card-iasecc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 254f8aa5ee..7eb3f5d095 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -2406,7 +2406,11 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_ sc_format_path("3F00", &path); path.type = SC_PATH_TYPE_FILE_ID; rv = iasecc_select_file(card, &path, NULL); - LOG_TEST_RET(ctx, rv, "Unable to select MF"); + if (rv != SC_SUCCESS) { + sc_file_free(save_current); + sc_log(ctx, "Unable to select MF"); + LOG_FUNC_RETURN(ctx, rv); + } } memset(&sdo, 0, sizeof(sdo)); @@ -3478,9 +3482,12 @@ iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_refer sc_log(ctx, "found empty key slot %i", idx); break; + } else if (rv != SC_SUCCESS) { + iasecc_sdo_free(card, sdo); + + sc_log(ctx, "get new key reference failed"); + LOG_FUNC_RETURN(ctx, rv); } - else - LOG_TEST_RET(ctx, rv, "get new key reference failed"); sz = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1); sc_log(ctx, From bce43e68550ec97a7cc5e724e554509e672cfc05 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 14:20:03 +0200 Subject: [PATCH 0540/4321] Remove dead code --- src/libopensc/card-epass2003.c | 5 ----- src/libopensc/card-piv.c | 6 ++++-- src/pkcs15init/pkcs15-myeid.c | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 49b593f9ec..299520d60b 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1846,11 +1846,6 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si case 0x04: file->ef_structure = SC_FILE_EF_LINEAR_FIXED; break; - case 0x03: - case 0x05: - case 0x06: - case 0x07: - break; default: break; } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 7cbf84b20c..a678b768e4 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2131,14 +2131,16 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { - serial->len = fascnlen < SC_MAX_SERIALNR ? fascnlen : SC_MAX_SERIALNR; + /* fascnlen is 25 */ + serial->len = fascnlen; memcpy (serial->value, fascn, serial->len); r = SC_SUCCESS; gbits = 0; /* set to skip using guid below */ } } if (guid && gbits) { - serial->len = guidlen < SC_MAX_SERIALNR ? guidlen : SC_MAX_SERIALNR; + /* guidlen is 16 */ + serial->len = guidlen; memcpy (serial->value, guid, serial->len); r = SC_SUCCESS; } diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 8b927d0972..10258667d0 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -750,7 +750,6 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, break; default: LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key type"); - break; } sc_log(ctx, "Generate key with ID:%s and path:%s", From 9a690a96e0fb8c9836449b0167cbb50ca4cff852 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 14:34:59 +0200 Subject: [PATCH 0541/4321] sc-hsm-tool: Avoid memory leak --- src/tools/sc-hsm-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 02cdfcc6c3..2b424cf736 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1503,13 +1503,13 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p return -1; } - if ((keybloblen = fread(keyblob, 1, sizeof(keyblob), in)) < 0) { + keybloblen = fread(keyblob, 1, sizeof(keyblob), in); + fclose(in); + if (keybloblen < 0) { perror(inf); return -1; } - fclose(in); - ptr = keyblob; if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) From 16c5a352a478642adbb5f3960d90b9c032688ed1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 14:39:51 +0200 Subject: [PATCH 0542/4321] piv-tool: Avoid memory leaks on realloc failure --- src/tools/piv-tool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 6dc8213d04..23a58ce649 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -477,6 +477,7 @@ int main(int argc, char *argv[]) const char *key_info = NULL; const char *admin_info = NULL; sc_context_param_t ctx_param; + char **old_apdus = NULL; setbuf(stderr, NULL); setbuf(stdout, NULL); @@ -493,9 +494,11 @@ int main(int argc, char *argv[]) action_count++; break; case 's': + old_apdus = opt_apdus; opt_apdus = (char **) realloc(opt_apdus, (opt_apdu_count + 1) * sizeof(char *)); if (!opt_apdus) { + free(old_apdus); err = 1; goto end; } From e920ef8eb88a70016871c287c6a7c8f111778621 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 14:44:39 +0200 Subject: [PATCH 0543/4321] opensc-explorer: Make static analyzers happy --- src/tools/opensc-explorer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index ac5292f91b..44e180432d 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1399,7 +1399,7 @@ static int do_get(int argc, char **argv) if (r == SC_SUCCESS) r = sc_select_file(card, &path, &file); sc_unlock(card); - if (r) { + if (r || file == NULL) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); goto err; } @@ -1594,7 +1594,7 @@ static int do_put(int argc, char **argv) if (r == SC_SUCCESS) r = sc_select_file(card, &path, &file); sc_unlock(card); - if (r) { + if (r || file == NULL) { check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file); goto err; } From a1dfdbbdbcc102fe9dae4a2eb161d8d015b70b2c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 15:04:53 +0200 Subject: [PATCH 0544/4321] pkcs15-oberthur-awp: Do not confuse cppcheck --- src/pkcs15init/pkcs15-oberthur-awp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index f9c96373cb..9b12f06cb1 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -284,9 +284,10 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * memset(buff, 0, list_file->record_length); rv = awp_new_container_entry(p15card, buff, list_file->record_length); - if (rv < 0) { + if (rv < 0) { free(buff); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot create container"); + sc_log(ctx, "Cannot create container"); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); } *(buff + 0) = (acc->pubkey_id >> 8) & 0xFF; From 52959df9f665195774ae1667b266044a1c34049d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 15:13:25 +0200 Subject: [PATCH 0545/4321] pkcs15-oberthur: Avoid memory leaks on failures --- src/libopensc/pkcs15-oberthur.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 3415be7cc7..8c126e46ae 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -206,8 +206,10 @@ sc_oberthur_get_certificate_authority(struct sc_pkcs15_der *der, int *out_author buf_mem.max = buf_mem.length = der->len; bio = BIO_new(BIO_s_mem()); - if(!bio) + if (!bio) { + free(buf_mem.data); return SC_ERROR_OUT_OF_MEMORY; + } BIO_set_mem_buf(bio, &buf_mem, BIO_NOCLOSE); x = d2i_X509_bio(bio, 0); From ef724e1e57ae5e56de40be6a58527716c9f62112 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 15:56:16 +0200 Subject: [PATCH 0546/4321] pkcs15-authentic: Do not confuse static analyzers --- src/pkcs15init/pkcs15-authentic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index 0b6f9c1766..a92c221cde 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -555,7 +555,10 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p | SC_PKCS15_PRKEY_ACCESS_SENSITIVE; rv = authentic_sdo_allocate_prvkey(profile, card, key_info, &sdo); - LOG_TEST_RET(ctx, rv, "IasEcc: init SDO private key failed"); + if (rv != SC_SUCCESS || sdo == NULL) { + sc_log(ctx, "IasEcc: init SDO private key failed"); + LOG_FUNC_RETURN(ctx, rv); + } rv = sc_card_ctl(card, SC_CARDCTL_AUTHENTIC_SDO_CREATE, sdo); if (rv == SC_ERROR_FILE_ALREADY_EXISTS) { From a5daaaff0c0de4e92f36c354bbbd151ee0ba698e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Sep 2018 16:24:54 +0200 Subject: [PATCH 0547/4321] piv-tool: Error checking --- src/tools/piv-tool.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 23a58ce649..f17fb162da 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -336,7 +336,7 @@ static int gen_key(const char * key_info) return r; } - evpkey = EVP_PKEY_new(); + evpkey = EVP_PKEY_new(); if (keydata.key_bits > 0) { /* RSA key */ RSA * newkey = NULL; @@ -385,7 +385,15 @@ static int gen_key(const char * key_info) r = EC_POINT_set_affine_coordinates_GFp(ecgroup, ecpoint, x, y, NULL); eckey = EC_KEY_new(); r = EC_KEY_set_group(eckey, ecgroup); + if (r == 0) { + fprintf(stderr, "EC_KEY_set_group failed\n"); + return -1; + } r = EC_KEY_set_public_key(eckey, ecpoint); + if (r == 0) { + fprintf(stderr, "EC_KEY_set_public_key failed\n"); + return -1; + } if (verbose) EC_KEY_print_fp(stdout, eckey, 0); From e4a0b099682e0665a8f31f2448aaa9c72727e11d Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Wed, 3 Oct 2018 09:40:27 +0200 Subject: [PATCH 0548/4321] openpgp-tool: remove unnecessary variable * 'opt_keylen' was only set, but never used => remove * passing the key length is not an action => do not mark it as such --- src/tools/openpgp-tool.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index d495381e31..721c1f1070 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -79,7 +79,6 @@ static int opt_userinfo = 0; static int opt_cardinfo = 0; static char *exec_program = NULL; static int opt_genkey = 0; -static int opt_keylen = 0; static u8 key_id = 0; static unsigned int key_len = 2048; static int opt_verify = 0; @@ -291,9 +290,7 @@ static int decode_options(int argc, char **argv) actions++; break; case 'L': - opt_keylen++; key_len = atoi(optarg); - actions++; break; case 'h': util_print_usage_and_die(app_name, options, option_help, NULL); From a8db9cb4f03e112ceb9d69557b18567ef578aad7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Wed, 3 Oct 2018 11:25:15 +0200 Subject: [PATCH 0549/4321] openpgp-tool: harmonize error messages * use symbolic constants for errors & success * use util_error() to show errors * print error messages to stderr --- src/tools/openpgp-tool.c | 60 +++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 721c1f1070..ad67e36047 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -321,8 +321,8 @@ static int decode_options(int argc, char **argv) endptr = NULL; val = strtoul(optarg, &endptr, 16); if (endptr == NULL || endptr == optarg || *endptr != '\0') { - printf("Unable to parse DO identifier\n"); - return 1; + util_error("Unable to parse DO identifier"); + exit(EXIT_FAILURE); } if (opt_dump_do < sizeof(do_dump_idx) / sizeof(*do_dump_idx)) { do_dump_idx[opt_dump_do] = (unsigned int) (val | 0x100); @@ -354,7 +354,7 @@ static int do_userinfo(sc_card_t *card) sc_format_path(openpgp_data[i].ef, &path); r = sc_select_file(card, &path, &file); if (r) { - fprintf(stderr, "Failed to select EF %s: %s\n", openpgp_data[i].ef, sc_strerror(r)); + util_error("failed to select EF %s: %s", openpgp_data[i].ef, sc_strerror(r)); return EXIT_FAILURE; } @@ -363,17 +363,17 @@ static int do_userinfo(sc_card_t *card) continue; if (count > sizeof(buf) - 1) { - fprintf(stderr, "Too small buffer to read the OpenPGP data\n"); + util_error("too small buffer to read the OpenPGP data"); return EXIT_FAILURE; } r = sc_read_binary(card, 0, buf, count, 0); if (r < 0) { - fprintf(stderr, "%s: read failed - %s\n", openpgp_data[i].ef, sc_strerror(r)); + util_error("failed to read %s: %s", openpgp_data[i].ef, sc_strerror(r)); return EXIT_FAILURE; } if (r != (signed)count) { - fprintf(stderr, "%s: expecting %"SC_FORMAT_LEN_SIZE_T"d, got only %d bytes\n", + util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d", openpgp_data[i].ef, count, r); return EXIT_FAILURE; } @@ -395,15 +395,15 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) memset(buffer, '\0', sizeof(buffer)); if (tag < 0x101 || tag > 0x104) { - printf("Illegal DO identifier\n"); - return 1; + util_error("illegal DO identifier %04X", tag); + return SC_ERROR_INVALID_ARGUMENTS; } r = sc_get_data(card, tag, buffer, sizeof(buffer)); if (r < 0) { - printf("Failed to get data object: %s\n", sc_strerror(r)); + util_error("failed to get data object DO %04X: %s", tag, sc_strerror(r)); if (SC_ERROR_SECURITY_STATUS_NOT_SATISFIED == r) { - printf("Make sure the 'verify' and 'pin' parameters are correct.\n"); + util_error("make sure the 'verify' and 'pin' parameters are correct"); } return r; } @@ -450,8 +450,8 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) sc_file_t *file; if (key_id < 1 || key_id > 3) { - printf("Unknown key ID %d.\n", key_id); - return 1; + util_error("unknown key ID %d", key_id); + return SC_ERROR_INVALID_ARGUMENTS; } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); key_info.keytype = key_id; @@ -460,22 +460,22 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); free(key_info.modulus); if (r < 0) { - printf("Failed to generate key. Error %s.\n", sc_strerror(r)); - return 1; + util_error("failed to generate key: %s", sc_strerror(r)); + return EXIT_FAILURE; } sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); if (r < 0) { - printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r)); - return 1; + util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); + return EXIT_FAILURE; } r = sc_read_binary(card, 0, fingerprints, 60, 0); if (r < 0) { - printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r)); - return 1; + util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); + return EXIT_FAILURE; } printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20)); - return 0; + return EXIT_SUCCESS; } int do_verify(sc_card_t *card, char *type, const char *pin) @@ -487,12 +487,12 @@ int do_verify(sc_card_t *card, char *type, const char *pin) return SC_ERROR_INVALID_ARGUMENTS; if (strncasecmp("CHV", type, 3) != 0) { - printf("Invalid PIN type. Please use CHV1, CHV2 or CHV3.\n"); + util_error("invalid PIN type. Please use CHV1, CHV2 or CHV3"); return SC_ERROR_INVALID_ARGUMENTS; } if (type[3] < '1' || type[3] > '3' || type[4] != '\0') { - printf("Invalid PIN reference. Please use CHV1, CHV2 or CHV3.\n"); + util_error("invalid PIN reference. Please use CHV1, CHV2 or CHV3"); return SC_ERROR_INVALID_PIN_REFERENCE; } @@ -538,7 +538,7 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id) /* Build APDU from binary array */ r = sc_bytes2apdu(card->ctx, buf, len0, &apdu); if (r) { - fprintf(stderr, "Failed to build APDU: %s\n", sc_strerror(r)); + util_error("failed to build APDU: %s", sc_strerror(r)); return r; } apdu.resp = rbuf; @@ -547,7 +547,7 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id) /* Send APDU to card */ r = sc_transmit_apdu(card, &apdu); if (r) { - fprintf(stderr, "Transmitting APDU failed: %s\n", sc_strerror(r)); + util_error("transmitting APDU failed: %s", sc_strerror(r)); return r; } } @@ -563,14 +563,15 @@ int do_delete_key(sc_card_t *card, u8 key_id) /* Currently, only Gnuk supports deleting keys */ if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) { - printf("Only Gnuk supports deleting keys. General OpenPGP doesn't."); + util_error("only Gnuk supports deleting keys. General OpenPGP doesn't"); return SC_ERROR_NOT_SUPPORTED; } if (key_id < 1 || (key_id > 3 && key_id != 'a')) { - printf("Error: Invalid key id %d", key_id); + util_error("invalid key id %d", key_id); return SC_ERROR_INVALID_ARGUMENTS; } + if (key_id == 1 || key_id == 'a') { sc_format_path("B601", &path); r |= sc_delete_file(card, &path); @@ -611,8 +612,7 @@ int main(int argc, char **argv) r = sc_context_create(&ctx, &ctx_param); if (r) { - util_fatal("failed to establish context: %s\n", - sc_strerror(r)); + util_fatal("failed to establish context: %s", sc_strerror(r)); return EXIT_FAILURE; } @@ -623,8 +623,7 @@ int main(int argc, char **argv) r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { - util_fatal("failed to connect to card: %s\n", - sc_strerror(r)); + util_fatal("failed to connect to card: %s", sc_strerror(r)); return EXIT_FAILURE; } @@ -634,8 +633,7 @@ int main(int argc, char **argv) (card->type != SC_CARD_TYPE_OPENPGP_V2) && (card->type != SC_CARD_TYPE_OPENPGP_V3) && (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { - util_error("not an OpenPGP card"); - fprintf(stderr, "Card type %X\n", card->type); + util_error("card type %X: not an OpenPGP card", card->type); exit_status = EXIT_FAILURE; goto out; } From 6bf67f7917f8d1eda999320aad374ae0ed907835 Mon Sep 17 00:00:00 2001 From: gabrielmuller Date: Mon, 8 Oct 2018 15:21:45 -0300 Subject: [PATCH 0550/4321] onepin option also needs PIN to CREATE I previously changed the default option but forgot to make the same change for onepin. --- src/pkcs15init/starcos.profile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/starcos.profile b/src/pkcs15init/starcos.profile index 2a2a6f2b9c..90505ca933 100644 --- a/src/pkcs15init/starcos.profile +++ b/src/pkcs15init/starcos.profile @@ -18,7 +18,7 @@ option default { option onepin { macros { so-pin-flags = initialized, needs-padding; - isf_acl = WRITE=$PIN; + isf_acl = WRITE=$PIN, CREATE=$PIN; df_acl = *=$PIN; } } From ea6f7cfe1db8724b0952c35a51b5c02858707b89 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 10 Oct 2018 14:52:01 +0200 Subject: [PATCH 0551/4321] Added memory locking for secrets (#1491) When caching a PIN in memory or using an OpenSSL private key this data should not be swapped to disk. --- src/libopensc/ctx.c | 8 +++++ src/libopensc/libopensc.exports | 2 ++ src/libopensc/opensc.h | 2 ++ src/libopensc/pkcs15.c | 19 +++++++++-- src/libopensc/sc-ossl-compat.h | 13 +++++++ src/libopensc/sc.c | 60 +++++++++++++++++++++++++++++++++ src/pkcs11/misc.c | 8 ++--- 7 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index f24a61ca0a..10a8e686a1 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -38,6 +38,7 @@ #include "common/libscdl.h" #include "internal.h" +#include "sc-ossl-compat.h" static int ignored_reader(sc_context_t *ctx, sc_reader_t *reader) { @@ -831,6 +832,13 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) return r; } +#ifdef ENABLE_OPENSSL + if (!CRYPTO_secure_malloc_initialized()) { + /* XXX What's a reasonable amount of secure heap? */ + CRYPTO_secure_malloc_init(4096, 32); + } +#endif + process_config_file(ctx, &opts); sc_log(ctx, "==================================="); /* first thing in the log */ sc_log(ctx, "opensc version: %s", sc_get_version()); diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 2d9b5e439a..62628ea420 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -131,6 +131,8 @@ sc_lock sc_logout sc_make_cache_dir sc_mem_clear +sc_mem_secure_alloc +sc_mem_secure_free sc_mem_reverse sc_match_atr_block sc_path_print diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index a4e87d5bf2..0abbf6a957 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1366,6 +1366,8 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen); * @param len length of the memory buffer */ void sc_mem_clear(void *ptr, size_t len); +void *sc_mem_secure_alloc(size_t len); +void sc_mem_secure_free(void *ptr, size_t len); int sc_mem_reverse(unsigned char *buf, size_t len); int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 12d6c834a9..14cf890fa0 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2496,8 +2496,15 @@ sc_pkcs15_make_absolute_path(const struct sc_path *parent, struct sc_path *child void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj) { if (obj->content.value && obj->content.len) { - sc_mem_clear(obj->content.value, obj->content.len); - free(obj->content.value); + if (SC_PKCS15_TYPE_AUTH & obj->type + || SC_PKCS15_TYPE_SKEY & obj->type + || SC_PKCS15_TYPE_PRKEY & obj->type) { + /* clean everything that potentially contains a secret */ + sc_mem_clear(obj->content.value, obj->content.len); + sc_mem_secure_free(obj->content.value, obj->content.len); + } else { + free(obj->content.value); + } } obj->content.value = NULL; obj->content.len = 0; @@ -2521,7 +2528,13 @@ sc_pkcs15_allocate_object_content(struct sc_context *ctx, struct sc_pkcs15_objec /* Need to pass by temporary variable, * because 'value' and 'content.value' pointers can be the sames. */ - tmp_buf = calloc(sizeof *tmp_buf, len); + if (SC_PKCS15_TYPE_AUTH & obj->type + || SC_PKCS15_TYPE_SKEY & obj->type + || SC_PKCS15_TYPE_PRKEY & obj->type) { + tmp_buf = sc_mem_secure_alloc(len); + } else { + tmp_buf = malloc(len); + } if (!tmp_buf) return SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 9185dd078d..192727f637 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -230,6 +230,19 @@ static sc_ossl_inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) } #endif /* OPENSSL_NO_EC */ +static sc_ossl_inline int CRYPTO_secure_malloc_init(size_t size, int minsize) +{ + return 0; +} + +static sc_ossl_inline int CRYPTO_secure_malloc_initialized() +{ + return 0; +} + +#else + +#include #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index ea63410048..2052998b1f 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -34,6 +34,7 @@ #include /* for OPENSSL_cleanse */ #endif + #include "internal.h" #ifdef PACKAGE_VERSION @@ -42,6 +43,19 @@ static const char *sc_version = PACKAGE_VERSION; static const char *sc_version = "(undef)"; #endif +#ifdef _WIN32 +#include +#define PAGESIZE 0 +#else +#include +#include +#include +#ifndef PAGESIZE +#define PAGESIZE 0 +#endif +#endif +static size_t page_size = PAGESIZE; + const char *sc_get_version(void) { return sc_version; @@ -826,6 +840,52 @@ int _sc_parse_atr(sc_reader_t *reader) return SC_SUCCESS; } +static void init_page_size() +{ + if (page_size == 0) { +#ifdef _WIN32 + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + page_size = system_info.dwPageSize; +#else + page_size = sysconf(_SC_PAGESIZE); + if ((long) page_size < 0) { + page_size = 0; + } +#endif + } +} + +void *sc_mem_secure_alloc(size_t len) +{ + void *p; + + init_page_size(); + if (page_size > 0) { + size_t pages = (len + page_size - 1) / page_size; + len = pages * page_size; + } + + p = malloc(len); +#ifdef _WIN32 + VirtualLock(p, len); +#else + mlock(p, len); +#endif + + return p; +} + +void sc_mem_secure_free(void *ptr, size_t len) +{ +#ifdef _WIN32 + VirtualUnlock(ptr, len); +#else + munlock(ptr, len); +#endif + free(ptr); +} + void sc_mem_clear(void *ptr, size_t len) { if (len > 0) { diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index ab77c0cbaa..e4798319a3 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -187,7 +187,7 @@ CK_RV push_login_state(struct sc_pkcs11_slot *slot, } if (pPin && ulPinLen) { - login->pPin = calloc((sizeof *pPin), ulPinLen); + login->pPin = sc_mem_secure_alloc((sizeof *pPin)*ulPinLen); if (login->pPin == NULL) { goto err; } @@ -207,7 +207,7 @@ CK_RV push_login_state(struct sc_pkcs11_slot *slot, if (login) { if (login->pPin) { sc_mem_clear(login->pPin, login->ulPinLen); - free(login->pPin); + sc_mem_secure_free(login->pPin, login->ulPinLen); } free(login); } @@ -223,7 +223,7 @@ void pop_login_state(struct sc_pkcs11_slot *slot) struct sc_pkcs11_login *login = list_get_at(&slot->logins, size-1); if (login) { sc_mem_clear(login->pPin, login->ulPinLen); - free(login->pPin); + sc_mem_secure_free(login->pPin, login->ulPinLen); free(login); } if (0 > list_delete_at(&slot->logins, size-1)) @@ -238,7 +238,7 @@ void pop_all_login_states(struct sc_pkcs11_slot *slot) struct sc_pkcs11_login *login = list_fetch(&slot->logins); while (login) { sc_mem_clear(login->pPin, login->ulPinLen); - free(login->pPin); + sc_mem_secure_free(login->pPin, login->ulPinLen); free(login); login = list_fetch(&slot->logins); } From 44d6116c59c40086d11001b44113b3266ee32a38 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 30 Sep 2018 11:57:24 +0200 Subject: [PATCH 0552/4321] OpenPGP: slight cleanups * use variables if they are already there * be a bit more explicit in logging * more consistent tag format: %04X * cleanup flag setting for _sc_card_add_rsa_alg() --- src/libopensc/card-openpgp.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c7df20e84a..ce9965b994 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -776,14 +776,10 @@ pgp_get_card_features(sc_card_t *card) * well and therefore added * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { - unsigned long flags; - - /* Is this correct? */ /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1; - flags |= SC_ALGORITHM_RSA_HASH_NONE; - /* Can be generated in card */ - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE | + SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (blob->data != NULL)) { @@ -2136,7 +2132,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ LOG_FUNC_CALLED(card->ctx); /* get old algorithm attributes */ - r = pgp_seek_blob(card, priv->mf, (0x00C0 | key_info->keytype), &algo_blob); + r = pgp_seek_blob(card, priv->mf, tag, &algo_blob); LOG_TEST_RET(card->ctx, r, "Cannot get old algorithm attributes"); old_modulus_len = bebytes2ushort(algo_blob->data + 1); /* modulus length is coded in byte 2 & 3 */ sc_log(card->ctx, @@ -2238,7 +2234,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, size_t fp_buffer_len; u8 *p; /* use this pointer to set fp_buffer content */ size_t pk_packet_len; - unsigned int tag; + unsigned int tag = 0x00C6 + key_info->key_id; pgp_blob_t *fpseq_blob; u8 *newdata; int r; @@ -2288,22 +2284,21 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, free(fp_buffer); /* store to DO */ - tag = 0x00C6 + key_info->keytype; - sc_log(card->ctx, "Write to DO %04X.", tag); - r = pgp_put_data(card, 0x00C6 + key_info->keytype, fingerprint, SHA_DIGEST_LENGTH); + sc_log(card->ctx, "Writing to DO %04X.", tag); + r = pgp_put_data(card, tag, fingerprint, SHA_DIGEST_LENGTH); LOG_TEST_RET(card->ctx, r, "Cannot write to DO."); /* update the blob containing fingerprints (00C5) */ - sc_log(card->ctx, "Update the blob containing fingerprints (00C5)"); + sc_log(card->ctx, "Updating fingerprint blob 00C5."); fpseq_blob = pgp_find_blob(card, 0x00C5); if (!fpseq_blob) { - sc_log(card->ctx, "Not found 00C5"); + sc_log(card->ctx, "Cannot find blob 00C5."); goto exit; } /* save the fingerprints sequence */ newdata = malloc(fpseq_blob->len); if (!newdata) { - sc_log(card->ctx, "Not enough memory to update fingerprints blob."); + sc_log(card->ctx, "Not enough memory to update fingerprint blob 00C5."); goto exit; } memcpy(newdata, fpseq_blob->data, fpseq_blob->len); @@ -2349,7 +2344,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - sc_log(card->ctx, "Get the blob %X.", blob_id); + sc_log(card->ctx, "Retrieving blob %04X.", blob_id); r = pgp_get_blob(card, priv->mf, blob_id, &pk_blob); LOG_TEST_RET(card->ctx, r, "Cannot get the blob."); @@ -2364,7 +2359,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, r = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &data, &len); LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey."); - sc_log(card->ctx, "Update blob content."); + sc_log(card->ctx, "Updating blob %04X's content.", blob_id); r = pgp_set_blob(pk_blob, data, len); LOG_TEST_RET(card->ctx, r, "Cannot update blob content."); LOG_FUNC_RETURN(card->ctx, r); From f1ae31aea40e9dc362b7e9ed8be1fcb594464786 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 30 Sep 2018 17:49:18 +0200 Subject: [PATCH 0553/4321] OpenPGP: expose additional algorithms only with EXT_CAP_ALG_ATTR_CHANGEABLE List additional algorithms & attributes as supported only when the card supports changing the algorithms attributes DOs and exposes this by having the EXT_CAP_ALG_ATTR_CHANGEABLE capability set. Using different algorithms and attributes requires changing the algorithm attributes DOs. If that is not supported - as indicated by a missing EXT_CAP_ALG_ATTR_CHANGEABLE capability - then only those algorithms described by the current algorithms attributes DOs' contents can be used. In addition simplify setting the flags. --- src/libopensc/card-openpgp.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ce9965b994..af23c2dec7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -577,11 +577,14 @@ pgp_init(sc_card_t *card) /* get card_features from ATR & DOs */ pgp_get_card_features(card); - /* add supported algorithms based on specification for pkcs15-init */ - if (strcmp(card->ctx->app_name, "pkcs15-init") == 0){ - unsigned long flags; - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; // Can be generated in card + /* if algorithm attributes can be changed, + * add supported algorithms based on specification for pkcs15-init */ + if ((priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) && + (strcmp(card->ctx->app_name, "pkcs15-init") == 0)) { + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ + unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE | + SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen. on card */ switch (card->type) { case SC_CARD_TYPE_OPENPGP_V3: From 772d20969ac9607a6961c9ce9574b71a95d65717 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 29 Sep 2018 19:25:36 +0200 Subject: [PATCH 0554/4321] OpenPGP: first steps to support key types beyond RSA - rename 'keytype' in some OpenPGP-specific types to 'key_id' because they key ID was what the field was used for - introduce field 'algorithm' in the structures above to indicate the key's algorithm: RSA, ... - define constant SC_OPENPGP_KEYALGO_RSA and use it - rename constants SC_OPENPGP_KEYFORMAT_* to SC_OPENPGP_KEYFORMAT_RSA_* because they are RSA specific --- src/libopensc/card-openpgp.c | 48 ++++++++++++++++----------------- src/libopensc/cardctl.h | 20 ++++++++------ src/pkcs15init/pkcs15-openpgp.c | 10 +++---- src/tools/openpgp-tool.c | 2 +- 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index af23c2dec7..4bc6a97b7d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -786,7 +786,7 @@ pgp_get_card_features(sc_card_t *card) /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (blob->data != NULL)) { - if (blob->len >= 3 && blob->data[0] == 0x01) { /* RSA [RFC 4880] */ + if (blob->len >= 3 && blob->data[0] == SC_OPENPGP_KEYALGO_RSA) { unsigned int keybits = bebytes2ushort(blob->data + 1); _sc_card_add_rsa_alg(card, keybits, flags, 0); @@ -2129,7 +2129,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ pgp_blob_t *algo_blob; unsigned int old_modulus_len; /* measured in bits */ unsigned int old_exponent_len; - const unsigned int tag = 0x00C0 | key_info->keytype; + const unsigned int tag = 0x00C0 | key_info->key_id; u8 changed = 0; int r = SC_SUCCESS; @@ -2306,7 +2306,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, } memcpy(newdata, fpseq_blob->data, fpseq_blob->len); /* move p to the portion holding the fingerprint of the current key */ - p = newdata + 20*(key_info->keytype - 1); + p = newdata + 20 * (key_info->key_id - 1); /* copy new fingerprint value */ memcpy(p, fingerprint, 20); /* set blob's data */ @@ -2384,7 +2384,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, LOG_FUNC_CALLED(card->ctx); /* store creation time */ - r = pgp_store_creationtime(card, key_info->keytype, &ctime); + r = pgp_store_creationtime(card, key_info->key_id, &ctime); LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); /* parse response. Ref: pgp_enumerate_blob() */ @@ -2439,7 +2439,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, modulus, key_info->modulus_len, - exponent, key_info->exponent_len, key_info->keytype); + exponent, key_info->exponent_len, key_info->key_id); LOG_FUNC_RETURN(card->ctx, r); } @@ -2451,7 +2451,7 @@ static int pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) { sc_algorithm_info_t *algo; - u8 id = key_info->keytype; + u8 id = key_info->key_id; LOG_FUNC_CALLED(card->ctx); @@ -2492,15 +2492,15 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) /* FIXME the compilers don't assure that the buffers set here as * apdu_data are present until the end of the function */ /* set Control Reference Template for key */ - if (key_info->keytype == SC_OPENPGP_KEY_SIGN) + if (key_info->key_id == SC_OPENPGP_KEY_SIGN) apdu_data = (unsigned char *) "\xb6"; /* as a string, apdu_data will end with '\0' (B6 00) */ - else if (key_info->keytype == SC_OPENPGP_KEY_ENCR) + else if (key_info->key_id == SC_OPENPGP_KEY_ENCR) apdu_data = (unsigned char *) "\xb8"; - else if (key_info->keytype == SC_OPENPGP_KEY_AUTH) + else if (key_info->key_id == SC_OPENPGP_KEY_AUTH) apdu_data = (unsigned char *) "\xa4"; else { - sc_log(card->ctx, "Unknown key type %X.", key_info->keytype); + sc_log(card->ctx, "Unknown key type %X.", key_info->key_id); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2690,8 +2690,8 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_FUNC_CALLED(ctx); - if (key_info->keyformat == SC_OPENPGP_KEYFORMAT_STDN - || key_info->keyformat == SC_OPENPGP_KEYFORMAT_CRTN) + if (key_info->keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN + || key_info->keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN) comp_to_add = 4; /* validate */ @@ -2704,7 +2704,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info memset(pritemplate, 0, max_prtem_len); /* get required exponent length */ - alat_blob = pgp_find_blob(card, 0x00C0 | key_info->keytype); + alat_blob = pgp_find_blob(card, 0x00C0 | key_info->key_id); if (!alat_blob) { sc_log(ctx, "Cannot read Algorithm Attributes."); LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND); @@ -2768,7 +2768,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info r = SC_ERROR_NOT_ENOUGH_MEMORY; goto out; } - switch (key_info->keytype) { + switch (key_info->key_id) { case SC_OPENPGP_KEY_SIGN: data[0] = 0xB6; break; @@ -2779,7 +2779,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info data[0] = 0xA4; break; default: - sc_log(ctx, "Unknown key type %d.", key_info->keytype); + sc_log(ctx, "Unknown key type %d.", key_info->key_id); r = SC_ERROR_INVALID_ARGUMENTS; goto out; } @@ -2821,18 +2821,18 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(ctx); /* Validate */ - if (key_info->keytype < 1 || key_info->keytype > 3) { - sc_log(ctx, "Unknown key type %d.", key_info->keytype); + if (key_info->key_id < 1 || key_info->key_id > 3) { + sc_log(ctx, "Unknown key type %d.", key_info->key_id); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } /* we just support standard key format */ switch (key_info->keyformat) { - case SC_OPENPGP_KEYFORMAT_STD: - case SC_OPENPGP_KEYFORMAT_STDN: + case SC_OPENPGP_KEYFORMAT_RSA_STD: + case SC_OPENPGP_KEYFORMAT_RSA_STDN: break; - case SC_OPENPGP_KEYFORMAT_CRT: - case SC_OPENPGP_KEYFORMAT_CRTN: + case SC_OPENPGP_KEYFORMAT_RSA_CRT: + case SC_OPENPGP_KEYFORMAT_RSA_CRTN: LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); default: @@ -2849,7 +2849,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* set algorithm attributes */ memset(&pubkey, 0, sizeof(pubkey)); - pubkey.keytype = key_info->keytype; + pubkey.key_id = key_info->key_id; if (key_info->n && key_info->n_len) { pubkey.modulus = key_info->n; pubkey.modulus_len = 8*key_info->n_len; @@ -2875,7 +2875,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) data = NULL; /* store creation time */ - r = pgp_store_creationtime(card, key_info->keytype, &key_info->creationtime); + r = pgp_store_creationtime(card, key_info->key_id, &key_info->creationtime); LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); /* Calculate and store fingerprint */ @@ -2885,7 +2885,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, key_info->n, 8*key_info->n_len, - key_info->e, 8*key_info->e_len, key_info->keytype); + key_info->e, 8*key_info->e_len, key_info->key_id); sc_log(ctx, "Update card algorithms."); pgp_update_card_algorithms(card, &pubkey); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 6bb83289f6..743481d2d9 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -942,21 +942,25 @@ typedef struct sc_cardctl_piv_genkey_info_st { #define SC_OPENPGP_KEY_ENCR 2 #define SC_OPENPGP_KEY_AUTH 3 -#define SC_OPENPGP_KEYFORMAT_STD 0 /* See 4.3.3.6 Algorithm Attributes */ -#define SC_OPENPGP_KEYFORMAT_STDN 1 /* OpenPGP card spec v2 */ -#define SC_OPENPGP_KEYFORMAT_CRT 2 -#define SC_OPENPGP_KEYFORMAT_CRTN 3 +#define SC_OPENPGP_KEYALGO_RSA 0x01 + +#define SC_OPENPGP_KEYFORMAT_RSA_STD 0 /* See 4.3.3.6 Algorithm Attributes */ +#define SC_OPENPGP_KEYFORMAT_RSA_STDN 1 /* OpenPGP card spec v2 */ +#define SC_OPENPGP_KEYFORMAT_RSA_CRT 2 +#define SC_OPENPGP_KEYFORMAT_RSA_CRTN 3 typedef struct sc_cardctl_openpgp_keygen_info { - u8 keytype; /* SC_OPENPGP_KEY_ */ - u8 *modulus; /* New-generated pubkey info responded from the card */ - size_t modulus_len; /* Length of modulus in bit */ + u8 key_id; /* SC_OPENPGP_KEY_... */ + u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ + u8 *modulus; /* New-generated pubkey info responded from the card */ + size_t modulus_len; /* Length of modulus in bit */ u8 *exponent; size_t exponent_len; } sc_cardctl_openpgp_keygen_info_t; typedef struct sc_cardctl_openpgp_keystore_info { - u8 keytype; + u8 key_id; /* SC_OPENPGP_KEY_... */ + u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ u8 keyformat; u8 *e; size_t e_len; diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 0b4412e286..34ae2dcdae 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -128,7 +128,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); - key_info.keytype = kinfo->id.value[0]; + key_info.key_id = kinfo->id.value[0]; key_info.e = rsa->exponent.data; key_info.e_len = rsa->exponent.len; key_info.p = rsa->p.data; @@ -169,15 +169,15 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card /* Default key is authentication key. We choose this because the common use * is to generate from PKCS#11 (Firefox/Thunderbird) */ sc_log(ctx, "Authentication key is to be generated."); - key_info.keytype = 3; + key_info.key_id = 3; } - if (!key_info.keytype && (kid->len > 1 || kid->value[0] > 3)) { + if (!key_info.key_id && (kid->len > 1 || kid->value[0] > 3)) { sc_log(ctx, "Key ID must be 1, 2 or 3!"); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } - if (!key_info.keytype) - key_info.keytype = kid->value[0]; + if (!key_info.key_id) + key_info.key_id = kid->value[0]; /* Prepare buffer */ key_info.modulus_len = required->modulus_length; diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index ad67e36047..1385c57bfc 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -454,7 +454,7 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) return SC_ERROR_INVALID_ARGUMENTS; } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); - key_info.keytype = key_id; + key_info.key_id = key_id; key_info.modulus_len = key_len; key_info.modulus = malloc(key_len/8); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); From c2f02f72bd07655b3e60b2f8aeb9eea3bb8f36bd Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 30 Sep 2018 10:08:47 +0200 Subject: [PATCH 0555/4321] OpenPGP: adapt data structures to support RSA alternatives * update callers to use the adapted structures. --- src/libopensc/card-openpgp.c | 96 +++++++++++++++++---------------- src/libopensc/cardctl.h | 43 ++++++++++----- src/pkcs15init/pkcs15-openpgp.c | 50 ++++++++--------- src/tools/openpgp-tool.c | 6 +-- 4 files changed, 107 insertions(+), 88 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 4bc6a97b7d..d318c53fb8 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2140,33 +2140,33 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ old_modulus_len = bebytes2ushort(algo_blob->data + 1); /* modulus length is coded in byte 2 & 3 */ sc_log(card->ctx, "Old modulus length %d, new %"SC_FORMAT_LEN_SIZE_T"u.", - old_modulus_len, key_info->modulus_len); + old_modulus_len, key_info->rsa.modulus_len); old_exponent_len = bebytes2ushort(algo_blob->data + 3); /* exponent length is coded in byte 3 & 4 */ sc_log(card->ctx, "Old exponent length %d, new %"SC_FORMAT_LEN_SIZE_T"u.", - old_exponent_len, key_info->exponent_len); + old_exponent_len, key_info->rsa.exponent_len); /* Modulus */ /* If passed modulus_len is zero, it means using old key size */ - if (key_info->modulus_len == 0) { + if (key_info->rsa.modulus_len == 0) { sc_log(card->ctx, "Use old modulus length (%d).", old_modulus_len); - key_info->modulus_len = old_modulus_len; + key_info->rsa.modulus_len = old_modulus_len; } /* To generate key with new key size */ - else if (old_modulus_len != key_info->modulus_len) { - algo_blob->data[1] = (unsigned char)(key_info->modulus_len >> 8); - algo_blob->data[2] = (unsigned char)key_info->modulus_len; + else if (old_modulus_len != key_info->rsa.modulus_len) { + algo_blob->data[1] = (unsigned char)(key_info->rsa.modulus_len >> 8); + algo_blob->data[2] = (unsigned char)key_info->rsa.modulus_len; changed = 1; } /* Exponent */ - if (key_info->exponent_len == 0) { + if (key_info->rsa.exponent_len == 0) { sc_log(card->ctx, "Use old exponent length (%d).", old_exponent_len); - key_info->exponent_len = old_exponent_len; + key_info->rsa.exponent_len = old_exponent_len; } - else if (old_exponent_len != key_info->exponent_len) { - algo_blob->data[3] = (unsigned char)(key_info->exponent_len >> 8); - algo_blob->data[4] = (unsigned char)key_info->exponent_len; + else if (old_exponent_len != key_info->rsa.exponent_len) { + algo_blob->data[3] = (unsigned char)(key_info->rsa.exponent_len >> 8); + algo_blob->data[4] = (unsigned char)key_info->rsa.exponent_len; changed = 1; } @@ -2231,8 +2231,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, sc_cardctl_openpgp_keygen_info_t *key_info) { u8 fingerprint[SHA_DIGEST_LENGTH]; - size_t mlen = key_info->modulus_len >> 3; /* 1/8 */ - size_t elen = key_info->exponent_len >> 3; /* 1/8 */ + size_t mlen = key_info->rsa.modulus_len >> 3; /* 1/8 */ + size_t elen = key_info->rsa.exponent_len >> 3; /* 1/8 */ u8 *fp_buffer = NULL; /* fingerprint buffer, not hashed */ size_t fp_buffer_len; u8 *p; /* use this pointer to set fp_buffer content */ @@ -2273,11 +2273,11 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, p += 4; *p = 1; /* RSA */ /* algorithm-specific fields */ - ushort2bebytes(++p, (unsigned short)key_info->modulus_len); + ushort2bebytes(++p, (unsigned short)key_info->rsa.modulus_len); p += 2; memcpy(p, modulus, mlen); p += mlen; - ushort2bebytes(++p, (unsigned short)key_info->exponent_len); + ushort2bebytes(++p, (unsigned short)key_info->rsa.exponent_len); p += 2; memcpy(p, exponent, elen); p = NULL; @@ -2408,21 +2408,21 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, if (tag == 0x0081) { /* set the output data */ - if (key_info->modulus) { - memcpy(key_info->modulus, part, len); + if (key_info->rsa.modulus) { + memcpy(key_info->rsa.modulus, part, len); } /* always set output for modulus_len */ - key_info->modulus_len = len*8; + key_info->rsa.modulus_len = len*8; /* remember the modulus to calculate fingerprint later */ modulus = part; } else if (tag == 0x0082) { /* set the output data */ - if (key_info->exponent) { - memcpy(key_info->exponent, part, len); + if (key_info->rsa.exponent) { + memcpy(key_info->rsa.exponent, part, len); } /* always set output for exponent_len */ - key_info->exponent_len = len*8; + key_info->rsa.exponent_len = len*8; /* remember the exponent to calculate fingerprint later */ exponent = part; } @@ -2438,8 +2438,8 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint."); /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, modulus, key_info->modulus_len, - exponent, key_info->exponent_len, key_info->key_id); + r = pgp_update_pubkey_blob(card, modulus, key_info->rsa.modulus_len, + exponent, key_info->rsa.exponent_len, key_info->key_id); LOG_FUNC_RETURN(card->ctx, r); } @@ -2465,7 +2465,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke /* get the algorithm corresponding to the key ID */ algo = card->algorithms + (id - 1); /* update new key length attribute */ - algo->key_length = (unsigned int)key_info->modulus_len; + algo->key_length = (unsigned int)key_info->rsa.modulus_len; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -2504,7 +2504,7 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->modulus_len != 2048) { + if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->rsa.modulus_len != 2048) { sc_log(card->ctx, "Gnuk does not support other key length than 2048."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2517,7 +2517,7 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) * arbitrary modulus length which for sure fits into a short APDU. * This idea is borrowed from GnuPG code. */ if (card->caps & SC_CARD_CAP_APDU_EXT - && key_info->modulus_len > 1900 + && key_info->rsa.modulus_len > 1900 && card->type != SC_CARD_TYPE_OPENPGP_GNUK) { /* We won't store to apdu variable yet, because it will be reset in * sc_format_apdu() */ @@ -2673,8 +2673,9 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info u8 *data = NULL; size_t len = 0; u8 *p = NULL; - u8 *components[] = {key_info->e, key_info->p, key_info->q, key_info->n}; - size_t componentlens[] = {key_info->e_len, key_info->p_len, key_info->q_len, key_info->n_len}; + u8 *components[] = {key_info->rsa.e, key_info->rsa.p, key_info->rsa.q, key_info->rsa.n}; + size_t componentlens[] = {key_info->rsa.e_len, key_info->rsa.p_len, + key_info->rsa.q_len, key_info->rsa.n_len}; unsigned int componenttags[] = {0x91, 0x92, 0x93, 0x97}; char *componentnames[] = { "public exponent", @@ -2690,12 +2691,12 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_FUNC_CALLED(ctx); - if (key_info->keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN - || key_info->keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN) + if (key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN + || key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN) comp_to_add = 4; /* validate */ - if (comp_to_add == 4 && (key_info->n == NULL || key_info->n_len == 0)){ + if (comp_to_add == 4 && (key_info->rsa.n == NULL || key_info->rsa.n_len == 0)){ sc_log(ctx, "Error: Modulus required!"); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2710,20 +2711,20 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND); } req_e_len = bebytes2ushort(alat_blob->data + 3) >> 3; /* 1/8 */ - assert(key_info->e_len <= req_e_len); + assert(key_info->rsa.e_len <= req_e_len); /* We need to right justify the exponent with required length, * e.g. from '01 00 01' to '00 01 00 01' */ - if (key_info->e_len < req_e_len) { + if (key_info->rsa.e_len < req_e_len) { /* create new buffer */ p = calloc(req_e_len, 1); if (!p) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - memcpy(p + req_e_len - key_info->e_len, key_info->e, key_info->e_len); - key_info->e_len = req_e_len; + memcpy(p + req_e_len - key_info->rsa.e_len, key_info->rsa.e, key_info->rsa.e_len); + key_info->rsa.e_len = req_e_len; /* set key_info->e to new buffer */ - free(key_info->e); - key_info->e = p; + free(key_info->rsa.e); + key_info->rsa.e = p; components[0] = p; componentlens[0] = req_e_len; } @@ -2826,7 +2827,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } /* we just support standard key format */ - switch (key_info->keyformat) { + switch (key_info->rsa.keyformat) { case SC_OPENPGP_KEYFORMAT_RSA_STD: case SC_OPENPGP_KEYFORMAT_RSA_STDN: break; @@ -2840,19 +2841,19 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) } /* we only support exponent of maximum 32 bits */ - if (key_info->e_len > 4) { + if (key_info->rsa.e_len > 4) { sc_log(card->ctx, "Exponent %"SC_FORMAT_LEN_SIZE_T"u-bit (>32) is not supported.", - key_info->e_len * 8); + key_info->rsa.e_len * 8); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } /* set algorithm attributes */ memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; - if (key_info->n && key_info->n_len) { - pubkey.modulus = key_info->n; - pubkey.modulus_len = 8*key_info->n_len; + if (key_info->rsa.n && key_info->rsa.n_len) { + pubkey.rsa.modulus = key_info->rsa.n; + pubkey.rsa.modulus_len = 8*key_info->rsa.n_len; /* We won't update exponent length, because smaller exponent length * will be padded later */ } @@ -2880,12 +2881,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* Calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); - r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, key_info->n, key_info->e, &pubkey); + r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, + key_info->rsa.n, key_info->rsa.e, &pubkey); LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint."); /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, key_info->n, 8*key_info->n_len, - key_info->e, 8*key_info->e_len, key_info->key_id); + r = pgp_update_pubkey_blob(card, key_info->rsa.n, 8*key_info->rsa.n_len, + key_info->rsa.e, 8*key_info->rsa.e_len, key_info->key_id); sc_log(ctx, "Update card algorithms."); pgp_update_card_algorithms(card, &pubkey); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 743481d2d9..b32ab50214 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -952,24 +952,41 @@ typedef struct sc_cardctl_piv_genkey_info_st { typedef struct sc_cardctl_openpgp_keygen_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ - u8 *modulus; /* New-generated pubkey info responded from the card */ - size_t modulus_len; /* Length of modulus in bit */ - u8 *exponent; - size_t exponent_len; + union { /* anonymous union */ + struct { + u8 *modulus; /* New-generated pubkey info responded from the card */ + size_t modulus_len; /* Length of modulus in bit */ + u8 *exponent; + size_t exponent_len; + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ + } rsa; + struct { + u8 dummy; /* placeholder */ + // TODO: replace placeholder with real attributes + } ec; + }; } sc_cardctl_openpgp_keygen_info_t; typedef struct sc_cardctl_openpgp_keystore_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ - u8 keyformat; - u8 *e; - size_t e_len; - u8 *p; - size_t p_len; - u8 *q; - size_t q_len; - u8 *n; - size_t n_len; + union { /* anonymous union */ + struct { + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ + u8 *e; + size_t e_len; + u8 *p; + size_t p_len; + u8 *q; + size_t q_len; + u8 *n; + size_t n_len; + } rsa; + struct { + u8 dummy; /* placeholder */ + // TODO: replace placeholder with real attributes + } ec; + }; time_t creationtime; } sc_cardctl_openpgp_keystore_info_t; diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 34ae2dcdae..c08508e21f 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -129,14 +129,14 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); key_info.key_id = kinfo->id.value[0]; - key_info.e = rsa->exponent.data; - key_info.e_len = rsa->exponent.len; - key_info.p = rsa->p.data; - key_info.p_len = rsa->p.len; - key_info.q = rsa->q.data; - key_info.q_len = rsa->q.len; - key_info.n = rsa->modulus.data; - key_info.n_len = rsa->modulus.len; + key_info.rsa.e = rsa->exponent.data; + key_info.rsa.e_len = rsa->exponent.len; + key_info.rsa.p = rsa->p.data; + key_info.rsa.p_len = rsa->p.len; + key_info.rsa.q = rsa->q.data; + key_info.rsa.q_len = rsa->q.len; + key_info.rsa.n = rsa->modulus.data; + key_info.rsa.n_len = rsa->modulus.len; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); LOG_FUNC_RETURN(card->ctx, r); @@ -180,16 +180,16 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card key_info.key_id = kid->value[0]; /* Prepare buffer */ - key_info.modulus_len = required->modulus_length; - key_info.modulus = calloc(required->modulus_length >> 3, 1); - if (key_info.modulus == NULL) + key_info.rsa.modulus_len = required->modulus_length; + key_info.rsa.modulus = calloc(required->modulus_length >> 3, 1); + if (key_info.rsa.modulus == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); /* The OpenPGP supports only 32-bit exponent. */ - key_info.exponent_len = 32; - key_info.exponent = calloc(key_info.exponent_len>>3, 1); /* 1/8 */ - if (key_info.exponent == NULL) { - free(key_info.modulus); + key_info.rsa.exponent_len = 32; + key_info.rsa.exponent = calloc(key_info.rsa.exponent_len>>3, 1); /* 1/8 */ + if (key_info.rsa.exponent == NULL) { + free(key_info.rsa.modulus); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } @@ -198,24 +198,24 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card goto out; sc_log(ctx, "Set output modulus info"); - pubkey->u.rsa.modulus.len = key_info.modulus_len; - pubkey->u.rsa.modulus.data = calloc(key_info.modulus_len, 1); + pubkey->u.rsa.modulus.len = key_info.rsa.modulus_len; + pubkey->u.rsa.modulus.data = calloc(key_info.rsa.modulus_len, 1); if (pubkey->u.rsa.modulus.data == NULL) goto out; - memcpy(pubkey->u.rsa.modulus.data, key_info.modulus, key_info.modulus_len); + memcpy(pubkey->u.rsa.modulus.data, key_info.rsa.modulus, key_info.rsa.modulus_len); sc_log(ctx, "Set output exponent info"); - pubkey->u.rsa.exponent.len = key_info.exponent_len; - pubkey->u.rsa.exponent.data = calloc(key_info.exponent_len>>3, 1); /* 1/8 */ + pubkey->u.rsa.exponent.len = key_info.rsa.exponent_len; + pubkey->u.rsa.exponent.data = calloc(key_info.rsa.exponent_len>>3, 1); /* 1/8 */ if (pubkey->u.rsa.exponent.data == NULL) goto out; - memcpy(pubkey->u.rsa.exponent.data, key_info.exponent, key_info.exponent_len>>3); /* 1/8 */ + memcpy(pubkey->u.rsa.exponent.data, key_info.rsa.exponent, key_info.rsa.exponent_len>>3); /* 1/8 */ out: - if (key_info.modulus) - free(key_info.modulus); - if (key_info.exponent) - free(key_info.exponent); + if (key_info.rsa.modulus) + free(key_info.rsa.modulus); + if (key_info.rsa.exponent) + free(key_info.rsa.exponent); LOG_FUNC_RETURN(ctx, r); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 1385c57bfc..3c60bec72f 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -455,10 +455,10 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); key_info.key_id = key_id; - key_info.modulus_len = key_len; - key_info.modulus = malloc(key_len/8); + key_info.rsa.modulus_len = key_len; + key_info.rsa.modulus = malloc(key_len/8); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); - free(key_info.modulus); + free(key_info.rsa.modulus); if (r < 0) { util_error("failed to generate key: %s", sc_strerror(r)); return EXIT_FAILURE; From 248ece23c60cb1b519ba29cb8315d7d03a6be6ff Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 30 Sep 2018 11:34:10 +0200 Subject: [PATCH 0556/4321] OpenPGP: bail out on non-RSA key generation/import Also add the necessary algorithm info where necessary. --- src/libopensc/card-openpgp.c | 25 +++++++++++++++++++++++++ src/pkcs15init/pkcs15-openpgp.c | 9 +++++++++ src/tools/openpgp-tool.c | 1 + 3 files changed, 35 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index d318c53fb8..01d091bbb2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2134,6 +2134,11 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ int r = SC_SUCCESS; LOG_FUNC_CALLED(card->ctx); + + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + /* get old algorithm attributes */ r = pgp_seek_blob(card, priv->mf, tag, &algo_blob); LOG_TEST_RET(card->ctx, r, "Cannot get old algorithm attributes"); @@ -2244,6 +2249,10 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, LOG_FUNC_CALLED(card->ctx); + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + if (modulus == NULL || exponent == NULL || mlen == 0 || elen == 0) { sc_log(card->ctx, "Null data (modulus or exponent)"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -2455,6 +2464,10 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke LOG_FUNC_CALLED(card->ctx); + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + if (id > card->algorithm_count) { sc_log(card->ctx, "This key ID %u is out of the card's algorithm list.", @@ -2489,6 +2502,10 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) LOG_FUNC_CALLED(card->ctx); + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + /* FIXME the compilers don't assure that the buffers set here as * apdu_data are present until the end of the function */ /* set Control Reference Template for key */ @@ -2691,6 +2708,10 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_FUNC_CALLED(ctx); + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + if (key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN || key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN) comp_to_add = 4; @@ -2821,6 +2842,10 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(ctx); + /* temporary workaround: protect v3 cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + /* Validate */ if (key_info->key_id < 1 || key_info->key_id > 3) { sc_log(ctx, "Unknown key type %d.", key_info->key_id); diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index c08508e21f..82f44e5733 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -129,6 +129,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); key_info.key_id = kinfo->id.value[0]; + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.rsa.e = rsa->exponent.data; key_info.rsa.e_len = rsa->exponent.len; key_info.rsa.p = rsa->p.data; @@ -179,7 +180,13 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card if (!key_info.key_id) key_info.key_id = kid->value[0]; + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported"); + return SC_ERROR_NOT_SUPPORTED; + } + /* Prepare buffer */ + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.rsa.modulus_len = required->modulus_length; key_info.rsa.modulus = calloc(required->modulus_length >> 3, 1); if (key_info.rsa.modulus == NULL) @@ -197,6 +204,8 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card if (r < 0) goto out; + pubkey->algorithm = SC_ALGORITHM_RSA; + sc_log(ctx, "Set output modulus info"); pubkey->u.rsa.modulus.len = key_info.rsa.modulus_len; pubkey->u.rsa.modulus.data = calloc(key_info.rsa.modulus_len, 1); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 3c60bec72f..0a6f09416e 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -455,6 +455,7 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); key_info.key_id = key_id; + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.rsa.modulus_len = key_len; key_info.rsa.modulus = malloc(key_len/8); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); From 8a564107a8a5976dd65219921929a9dcf2d2d712 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 6 Oct 2018 15:32:27 +0200 Subject: [PATCH 0557/4321] OpenPGP: introduce gpg_parse_algo_attr_blob() Introduce a central function to parse the algorithm atributes in DOs C1 - C3. --- src/libopensc/card-openpgp.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 01d091bbb2..ace0ff0a2c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -646,6 +646,39 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) } +/** + * Internal: parse an algorithm attributes DO + **/ +static int +pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_t *key_info) +{ + if (blob == NULL || blob->data == NULL || blob->len == 0 || + blob->id < 0x00c1 || blob->id > 0x00c3 || key_info == NULL) + return SC_ERROR_INCORRECT_PARAMETERS; + + key_info->key_id = blob->id - 0x00c0; /* attribute algorithm blobs are C1 - C3 */ + + switch (blob->data[0]) { + case SC_OPENPGP_KEYALGO_RSA: + if (blob->len < 5) + return SC_ERROR_INCORRECT_PARAMETERS; + + key_info->algorithm = SC_OPENPGP_KEYALGO_RSA; + key_info->rsa.modulus_len = bebytes2ushort(blob->data + 1); + key_info->rsa.exponent_len = bebytes2ushort(blob->data + 3); + + key_info->rsa.keyformat = (blob->len > 5) + ? blob->data[5] + : SC_OPENPGP_KEYFORMAT_RSA_STD; + break; + default: + return SC_ERROR_NOT_IMPLEMENTED; + } + + return SC_SUCCESS; +} + + /** * Internal: get features of the card: capabilities, ... */ From 550665b906da292a256bdc446bb46c45d2f77714 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 6 Oct 2018 17:28:15 +0200 Subject: [PATCH 0558/4321] OpenPGP: refactor pgp_get_card_features() Use pgp_parse_alog_attr_blob() to get the algorithm attribute DO's contents. --- src/libopensc/card-openpgp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ace0ff0a2c..7570b9ce50 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -812,19 +812,20 @@ pgp_get_card_features(sc_card_t *card) * well and therefore added * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { + sc_cardctl_openpgp_keygen_info_t key_info; /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ - if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (blob->data != NULL)) { - if (blob->len >= 3 && blob->data[0] == SC_OPENPGP_KEYALGO_RSA) { - unsigned int keybits = bebytes2ushort(blob->data + 1); + if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && + (pgp_parse_algo_attr_blob(blob, &key_info) >= 0)) { - _sc_card_add_rsa_alg(card, keybits, flags, 0); - } - /* v3.0+: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ + if (key_info.algorithm == SC_OPENPGP_KEYALGO_RSA) /* RFC 4880: RSA */ + _sc_card_add_rsa_alg(card, key_info.rsa.modulus_len, flags, 0); + + /* TODO v3.0+: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ } } From d517d8e18d9c7f918e38de7e613e34f6b3d21f09 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Thu, 11 Oct 2018 11:22:15 +0200 Subject: [PATCH 0559/4321] Fix minidriver padding Commit e5707b545e5a2dc33b0ca52a8bf63f36f71b3d85 broke signing using minidriver on Windows. More specifically changing #define SC_ALGORITHM_RSA_PAD_NONE from 0x00000000 to 0x00000001 caused a call to sc_pkcs1_encode() to fail as the padding algorithm was not specified anywhere in the CardSignData() implementation. It kind of worked as long as SC_ALGORITHM_RSA_PAD_NONE was 0x00000000, but the above mentioned commit broke this. Now padding algorithm has to be explicitly specified, otherwise a call to sc_pkcs1_encode() will fail. --- src/libopensc/padding.c | 2 +- src/minidriver/minidriver.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 53a87c352e..934fc67d11 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -412,7 +412,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, pad_algo = flags & SC_ALGORITHM_RSA_PADS; sc_log(ctx, "hash algorithm 0x%X, pad algorithm 0x%X", hash_algo, pad_algo); - if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || !pad_algo) && + if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || pad_algo == SC_ALGORITHM_RSA_PAD_NONE) && hash_algo != SC_ALGORITHM_RSA_HASH_NONE) { i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len); if (i != SC_SUCCESS) { diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 3570a07b00..2ffffcc104 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4728,6 +4728,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO goto err; } } + opt_hash_flags |= SC_ALGORITHM_RSA_PAD_NONE; if (pInfo->dwSigningFlags & CARD_PADDING_NONE) { From ac276b1202aa82771323d7cebb498c80e4bd01e9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 11 Oct 2018 22:50:37 +0200 Subject: [PATCH 0560/4321] starcos: fixed decipher with 2.3 (#1496) closes https://github.com/OpenSC/OpenSC/issues/765 fixes https://github.com/OpenSC/OpenSC/issues/1495 --- src/libopensc/card-starcos.c | 60 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 799c6a6808..619452c430 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1642,12 +1642,36 @@ static int starcos_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) { + int r; + size_t card_max_send_size = card->max_send_size; + size_t reader_max_send_size = card->reader->max_send_size; + size_t card_max_recv_size = card->max_recv_size; + size_t reader_max_recv_size = card->reader->max_recv_size; + + if (sc_get_max_send_size(card) < crgram_len + 1) { + /* Starcos doesn't support chaining for PSO:DEC, so we just _hope_ + * that both, the reader and the card are able to send enough data. + * (data is prefixed with 1 byte padding content indicator) */ + card->max_send_size = crgram_len + 1; + card->reader->max_send_size = crgram_len + 1; + } + + if (sc_get_max_recv_size(card) < outlen) { + /* Starcos doesn't support get response for PSO:DEC, so we just _hope_ + * that both, the reader and the card are able to receive enough data. + */ + if (0 == (card->caps & SC_CARD_CAP_APDU_EXT) + && outlen > 256) { + card->max_recv_size = 256; + card->reader->max_recv_size = 256; + } else { + card->max_recv_size = outlen; + card->reader->max_recv_size = outlen; + } + } + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { - int r; - size_t card_max_send_size = card->max_send_size; - size_t reader_max_send_size = card->reader->max_send_size; - int caps = card->caps; sc_apdu_t apdu; u8 *sbuf = malloc(crgram_len + 1); @@ -1665,34 +1689,28 @@ static int starcos_decipher(struct sc_card *card, apdu.lc = crgram_len + 1; apdu.datalen = crgram_len + 1; - if (sc_get_max_send_size(card) < crgram_len + 1) { - /* Starcos doesn't support chaining for PSO:DEC, so we just _hope_ - * that both, the reader and the card are able to send enough data. - * (data is prefixed with 1 byte padding content indicator) */ - card->max_send_size = crgram_len + 1; - card->reader->max_send_size = crgram_len + 1; - card->caps |= SC_CARD_CAP_APDU_EXT; - } - r = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, crgram_len + 1); - /* reset whatever we've modified above */ - card->max_send_size = card_max_send_size; - card->reader->max_send_size = reader_max_send_size; - card->caps = caps; - free(sbuf); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - LOG_FUNC_RETURN(card->ctx, apdu.resplen); + r = apdu.resplen; else - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); } else { - return iso_ops->decipher(card, crgram, crgram_len, out, outlen); + r = iso_ops->decipher(card, crgram, crgram_len, out, outlen); } + + /* reset whatever we've modified above */ + card->max_send_size = card_max_send_size; + card->reader->max_send_size = reader_max_send_size; + card->max_recv_size = card_max_recv_size; + card->reader->max_recv_size = reader_max_recv_size; + + LOG_FUNC_RETURN(card->ctx, r); } static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) From 55a8478ed6031fc1ecff0019ee6d463f5a10662a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 9 Oct 2018 15:10:36 +0200 Subject: [PATCH 0561/4321] cac: These functions do not have to be exposed --- src/libopensc/card-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index eeab07e4fe..bd4e03362f 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -211,7 +211,7 @@ typedef struct cac_private_data { #define CAC_DATA(card) ((cac_private_data_t*)card->drv_data) -int cac_list_compare_path(const void *a, const void *b) +static int cac_list_compare_path(const void *a, const void *b) { if (a == NULL || b == NULL) return 1; @@ -220,7 +220,7 @@ int cac_list_compare_path(const void *a, const void *b) } /* For SimCList autocopy, we need to know the size of the data elements */ -size_t cac_list_meter(const void *el) { +static size_t cac_list_meter(const void *el) { return sizeof(cac_object_t); } From f220d0b77d40256a2c79b1da046f9bd6e8c1e15c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 9 Oct 2018 15:58:12 +0200 Subject: [PATCH 0562/4321] coolkey: Improve card matching to avoid mismatches in muscle --- src/libopensc/card-coolkey.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index b97559cc38..c1c09b662d 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2225,13 +2225,32 @@ static int coolkey_initialize(sc_card_t *card) static int coolkey_match_card(sc_card_t *card) { int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* Since we send an APDU, the card's logout function may be called... * however it may be in dirty memory */ card->ops->logout = NULL; r = coolkey_select_applet(card); - return (r >= SC_SUCCESS); + if (r == SC_SUCCESS) { + sc_apdu_t apdu; + + /* The GET STATUS INS with P1 = 1 returns invalid instruction (0x6D00) + * on Coolkey applet (reserved for GetMemory function), + * while incorrect P1 (0x9C10) on Muscle applets + */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, COOLKEY_INS_GET_STATUS, 0x01, 0x00); + apdu.cla = COOLKEY_CLASS; + apdu.le = 0x00; + apdu.resplen = 0; + apdu.resp = NULL; + r = sc_transmit_apdu(card, &apdu); + if (r == SC_SUCCESS && apdu.sw1 == 0x6d && apdu.sw2 == 0x00) { + return 1; + } + return 0; + } + return 0; } From 46c99e769d358f0dd92fe65d7b797593af8c281f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 9 Oct 2018 16:01:57 +0200 Subject: [PATCH 0563/4321] ctx: Move coolkey driver up after improving the matching Fixes #1483 --- src/libopensc/ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 10a8e686a1..162a41f8bf 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -129,6 +129,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { /* Here should be placed drivers that need some APDU transactions in the * driver's `match_card()` function. */ + { "coolkey", (void *(*)(void)) sc_get_coolkey_driver }, /* MUSCLE card applet returns 9000 on whatever AID is selected, see * https://github.com/JavaCardOS/MuscleCard-Applet/blob/master/musclecard/src/com/musclecard/CardEdge/CardEdge.java#L326 * put the muscle driver first to cope with this bug. */ @@ -145,7 +146,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { #endif { "openpgp", (void *(*)(void)) sc_get_openpgp_driver }, { "jpki", (void *(*)(void)) sc_get_jpki_driver }, - { "coolkey", (void *(*)(void)) sc_get_coolkey_driver }, { "npa", (void *(*)(void)) sc_get_npa_driver }, /* The default driver should be last, as it handles all the * unrecognized cards. */ From 8c535c184f41dff417eb23069fec511f911f8ae6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 4 Oct 2018 15:59:11 +0200 Subject: [PATCH 0564/4321] removed duplicate code for adding padding Fixes padding handling of SC_ALGORITHM_RSA_PAD_NONE introduced with e5707b545e5a2dc33b0ca52a8bf63f36f71b3d85 --- src/libopensc/padding.c | 9 ++- src/minidriver/minidriver.c | 144 +++++++++++++++--------------------- 2 files changed, 64 insertions(+), 89 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 934fc67d11..75c92b651a 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -487,18 +487,19 @@ int sc_get_encoding_flags(sc_context_t *ctx, *pflags = 0; } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && - (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { + (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { *sflags |= SC_ALGORITHM_RSA_PAD_PSS; } else if (((caps & SC_ALGORITHM_RSA_RAW) && - (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) - || iflags & SC_ALGORITHM_RSA_PAD_PSS) { + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) + || iflags & SC_ALGORITHM_RSA_PAD_PSS + || iflags & SC_ALGORITHM_RSA_PAD_NONE) { /* Use the card's raw RSA capability on the padded input */ *sflags = SC_ALGORITHM_RSA_PAD_NONE; *pflags = iflags; } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && - (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { /* A corner case - the card can partially do PKCS1, if we prepend the * DigestInfo bit it will do the rest. */ *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 2ffffcc104..bc1c58d1c3 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4581,7 +4581,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO ALG_ID hashAlg; sc_pkcs15_prkey_info_t *prkey_info; BYTE dataToSign[0x200]; - int r, opt_crypt_flags = 0, opt_hash_flags = 0; + int opt_crypt_flags; size_t dataToSignLen = sizeof(dataToSign); sc_pkcs15_object_t *pkey; @@ -4663,112 +4663,86 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO memcpy(dataToSign, pInfo->pbData, pInfo->cbData); dataToSignLen = pInfo->cbData; - if (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags) { - BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; - if (CARD_PADDING_PSS == pInfo->dwPaddingType) { - logprintf(pCardData, 0, "unsupported paddingtype CARD_PADDING_PSS\n"); - dwret = SCARD_E_UNSUPPORTED_FEATURE; - goto err; - } - else if (CARD_PADDING_PKCS1 != pInfo->dwPaddingType) { - logprintf(pCardData, 0, "unsupported paddingtype\n"); - dwret = SCARD_E_INVALID_PARAMETER; - goto err; - } - - if (!pinf->pszAlgId) { - /* hashAlg = CALG_SSL3_SHAMD5; */ - logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; - } - else { - if (wcscmp(pinf->pszAlgId, L"MD5") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5; - else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA224; - else if (wcscmp(pinf->pszAlgId, L"SHA256") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256; - else if (wcscmp(pinf->pszAlgId, L"SHA384") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384; - else if (wcscmp(pinf->pszAlgId, L"SHA512") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512; - else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; - else { - logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); - dwret = SCARD_E_UNSUPPORTED_FEATURE; - goto err; - } - } - } - else { + if (0 == (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags)) { + /* When CARD_PADDING_INFO_PRESENT is not set in dwSigningFlags, this is + * the basic version of the signing structure. (If this is not the + * basic verison of the signing structure, the minidriver should return + * ERROR_REVISION_MISMATCH.) The minidriver should only do PKCS1 + * padding and use the value in aiHashAlg. */ logprintf(pCardData, 3, "CARD_PADDING_INFO_PRESENT not set\n"); + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; if (hashAlg == CALG_MD5) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; else if (hashAlg == CALG_SHA1) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; else if (hashAlg == CALG_SSL3_SHAMD5) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; else if (hashAlg == CALG_SHA_256) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; else if (hashAlg == CALG_SHA_384) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; else if (hashAlg == CALG_SHA_512) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; else if (hashAlg == (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_RIPEMD160)) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; else if (hashAlg !=0) { logprintf(pCardData, 0, "bogus aiHashAlg %i\n", hashAlg); dwret = SCARD_E_UNSUPPORTED_FEATURE; goto err; } - } - opt_hash_flags |= SC_ALGORITHM_RSA_PAD_NONE; - - if (pInfo->dwSigningFlags & CARD_PADDING_NONE) - { - /* do not add the digest info when called from CryptSignHash(CRYPT_NOHASHOID) - - Note: SC_ALGORITHM_RSA_HASH_MD5_SHA1 aka CALG_SSL3_SHAMD5 do not have a digest info to be added - CryptSignHash(CALG_SSL3_SHAMD5,CRYPT_NOHASHOID) is the same than CryptSignHash(CALG_SSL3_SHAMD5) - */ - opt_hash_flags = 0; - } - - /* From sc-minidriver_specs_v7.docx pp.76: - * 'The Base CSP/KSP performs the hashing operation on the data before passing it - * to CardSignData for signature.' - * So, the SC_ALGORITHM_RSA_HASH_* flags should not be passed to pkcs15 library - * when calculating the signature . - * - * From sc-minidriver_specs_v7.docx pp.76: - * 'If the aiHashAlg member is nonzero, it specifies the hash algorithm’s object identifier (OID) - * that is encoded in the PKCS padding.' - * So, the digest info has be included into the data to be signed. - * */ - if (opt_hash_flags) { - logprintf(pCardData, 2, "include digest info of the algorithm 0x%08X\n", opt_hash_flags); - dataToSignLen = sizeof(dataToSign); - r = sc_pkcs1_encode(vs->ctx, opt_hash_flags, pInfo->pbData, pInfo->cbData, dataToSign, &dataToSignLen, 0); - if (r) { - logprintf(pCardData, 2, "PKCS#1 encode error %s\n", sc_strerror(r)); - dwret = SCARD_E_INVALID_VALUE; - goto err; + } else { + switch (pInfo->dwPaddingType) { + case CARD_PADDING_NONE: + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_NONE; + break; + + case CARD_PADDING_PKCS1: + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; + BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; + + if (!pinf->pszAlgId) { + /* hashAlg = CALG_SSL3_SHAMD5; */ + logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + } else { + if (wcscmp(pinf->pszAlgId, L"MD5") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; + else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; + else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; + else if (wcscmp(pinf->pszAlgId, L"SHA256") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; + else if (wcscmp(pinf->pszAlgId, L"SHA384") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; + else if (wcscmp(pinf->pszAlgId, L"SHA512") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; + else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; + else { + logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } + } + break; + + default: + logprintf(pCardData, 0, "unsupported paddingtype\n"); + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } } + /* Compute output size */ if ( prkey_info->modulus_length > 0) { /* RSA */ pInfo->cbSignedData = (DWORD) prkey_info->modulus_length / 8; - opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; } else if ( prkey_info->field_length > 0) { - opt_crypt_flags = SC_ALGORITHM_ECDSA_HASH_NONE; switch(prkey_info->field_length) { case 256: /* ECDSA_P256 */ From 195d53b8a209dd0abc4fc44bc1617d8b6dd20b01 Mon Sep 17 00:00:00 2001 From: Vadim Penzin Date: Mon, 15 Oct 2018 21:21:33 +0300 Subject: [PATCH 0565/4321] Fix division by zero in SimCList when appending to an empty list. --- src/common/simclist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/simclist.c b/src/common/simclist.c index 3cd3a1c037..b18a07d719 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -419,7 +419,7 @@ static simclist_inline struct list_entry_s *list_findpos(const list_t *simclist_ /* accept 1 slot overflow for fetching head and tail sentinels */ if (posstart < -1 || posstart > (int)l->numels) return NULL; - x = (float)(posstart+1) / l->numels; + x = l->numels ? (float)(posstart+1) / l->numels : 0; if (x <= 0.25) { /* first quarter: get to posstart from head */ for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++); From 2fd8e278f5d3664555cad706d7270229c87cae56 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 17 Oct 2018 16:07:20 -0500 Subject: [PATCH 0566/4321] pkcs11/openssl.c - add missing mechanisms fixes #1497 On branch pkcs11-openssl-c Changes to be committed: modified: ../pkcs11/openssl.c --- src/pkcs11/openssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 00b9814e4c..fb9f8fea81 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -449,6 +449,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, return CKR_GENERAL_ERROR; if (md != NULL && (mech->mechanism == CKM_SHA1_RSA_PKCS + || mech->mechanism == CKM_MD5_RSA_PKCS + || mech->mechanism == CKM_RIPEMD160_RSA_PKCS || mech->mechanism == CKM_SHA224_RSA_PKCS || mech->mechanism == CKM_SHA256_RSA_PKCS || mech->mechanism == CKM_SHA384_RSA_PKCS @@ -478,6 +480,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, sc_log(context, "Trying to verify using low-level API"); switch (mech->mechanism) { case CKM_RSA_PKCS: + case CKM_MD5_RSA_PKCS: + case CKM_RIPEMD160_RSA_PKCS: pad = RSA_PKCS1_PADDING; break; case CKM_RSA_X_509: From 5095e29ae35e0fd19d8b605da8928d11db1ede50 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 17 Oct 2018 09:39:20 +0200 Subject: [PATCH 0567/4321] gio: avoid unneccessary unitialization --- src/ui/notify.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ui/notify.c b/src/ui/notify.c index 0c2bf06b86..36219c25b1 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -442,9 +442,10 @@ static GApplication *application = NULL; void sc_notify_init(void) { - sc_notify_close(); - application = g_application_new("org.opensc.notify", G_APPLICATION_NON_UNIQUE); - if (application) { + if (!application) { + application = g_application_new("org.opensc.notify", G_APPLICATION_NON_UNIQUE); + } + if (application && FALSE == g_application_get_is_registered(application)) { g_application_register(application, NULL, NULL); } } From c3bef7d5278c695f3778a629a720bdd8c3c42ce5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 24 Oct 2018 08:46:55 +0200 Subject: [PATCH 0568/4321] fixed compilation with XCode 10 fixes https://github.com/OpenSC/OpenSC/issues/1485 --- src/libopensc/internal-winscard.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index 011167ddce..edc315ca2f 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -138,6 +138,7 @@ typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST; #endif /* HAVE_SCARD_H */ +#ifndef PCSC_API #if defined(_WIN32) #define PCSC_API WINAPI #elif defined(USE_CYGWIN) @@ -145,6 +146,12 @@ typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST; #else #define PCSC_API #endif +#endif + +#ifdef __APPLE__ +#define extern +#define __attribute__(a) +#endif typedef LONG (PCSC_API *SCardEstablishContext_t)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); @@ -174,6 +181,11 @@ typedef LONG (PCSC_API *SCardListReaders_t)(SCARDCONTEXT hContext, LPCSTR mszGro typedef LONG (PCSC_API *SCardGetAttrib_t)(SCARDHANDLE hCard, DWORD dwAttrId,\ LPBYTE pbAttr, LPDWORD pcbAttrLen); +#ifdef __APPLE__ +#undef extern +#undef __attribute__ +#endif + /* Copied from pcsc-lite reader.h */ #ifndef SCARD_CTL_CODE From e2b1fb81e0e1339eebaa36fb90635e03f69d4da3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Oct 2018 17:27:28 +0100 Subject: [PATCH 0569/4321] Restore minimal CAC1 driver for legacy cards (#1502) * Add minimal CAC1 driver for legacy cards. It is using the same pkcs15 backend as the CAC2 cards as well as some of the CAC2 driver methods. The separation is made mostly for easier card matching or disabling. --- src/libopensc/Makefile.am | 3 +- src/libopensc/Makefile.mak | 3 +- src/libopensc/card-cac-common.c | 126 ++++++++ src/libopensc/card-cac-common.h | 89 +++++ src/libopensc/card-cac.c | 174 ++-------- src/libopensc/card-cac1.c | 556 ++++++++++++++++++++++++++++++++ src/libopensc/cards.h | 1 + src/libopensc/ctx.c | 1 + 8 files changed, 801 insertions(+), 152 deletions(-) create mode 100644 src/libopensc/card-cac-common.c create mode 100644 src/libopensc/card-cac-common.h create mode 100644 src/libopensc/card-cac1.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index a99b0c5741..5a17df2b1d 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -40,7 +40,8 @@ libopensc_la_SOURCES_BASE = \ card-mcrd.c card-starcos.c card-openpgp.c card-jcop.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ - card-piv.c card-cac.c card-muscle.c card-acos5.c \ + card-piv.c card-cac-common.c card-cac.c card-cac1.c \ + card-muscle.c card-acos5.c \ card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ card-rtecp.c card-westcos.c card-myeid.c \ card-itacns.c card-authentic.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 10a3b0a9dd..c498230489 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -19,7 +19,8 @@ OBJECTS = \ card-mcrd.obj card-starcos.obj card-openpgp.obj card-jcop.obj \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj \ card-entersafe.obj card-epass2003.obj card-coolkey.obj \ - card-incrypto34.obj card-cac.obj card-piv.obj card-muscle.obj \ + card-incrypto34.obj card-cac.obj card-cac1.obj card-cac-common.obj \ + card-piv.obj card-muscle.obj \ card-acos5.obj \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ card-rtecp.obj card-westcos.obj card-myeid.obj \ diff --git a/src/libopensc/card-cac-common.c b/src/libopensc/card-cac-common.c new file mode 100644 index 0000000000..b4e66e9bd3 --- /dev/null +++ b/src/libopensc/card-cac-common.c @@ -0,0 +1,126 @@ +/* + * card-cac-common.c: Code shared among CAC1 and CAC2 drivers + * + * Copyright (C) 2018, Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "internal.h" +#include "iso7816.h" +#include "card-cac-common.h" + +/* default certificate labels for the CAC card */ +const char *cac_labels[MAX_CAC_SLOTS] = { + "CAC ID Certificate", + "CAC Email Signature Certificate", + "CAC Email Encryption Certificate", + "CAC Cert 4", + "CAC Cert 5", + "CAC Cert 6", + "CAC Cert 7", + "CAC Cert 8", + "CAC Cert 9", + "CAC Cert 10", + "CAC Cert 11", + "CAC Cert 12", + "CAC Cert 13", + "CAC Cert 14", + "CAC Cert 15", + "CAC Cert 16" +}; + +const char *get_cac_label(int index) +{ + if (index < 0 || index >= MAX_CAC_SLOTS) + return NULL; + + return cac_labels[index]; +} + +static int cac_list_compare_path(const void *a, const void *b) +{ + if (a == NULL || b == NULL) + return 1; + return memcmp( &((cac_object_t *) a)->path, + &((cac_object_t *) b)->path, sizeof(sc_path_t)); +} + +/* For SimCList autocopy, we need to know the size of the data elements */ +static size_t cac_list_meter(const void *el) { + return sizeof(cac_object_t); +} + +cac_private_data_t *cac_new_private_data(void) +{ + cac_private_data_t *priv; + + priv = calloc(1, sizeof(cac_private_data_t)); + if (priv == NULL) + return NULL; + + /* Initialize PKI Applets list */ + if (list_init(&priv->pki_list) != 0 || + list_attributes_comparator(&priv->pki_list, cac_list_compare_path) != 0 || + list_attributes_copy(&priv->pki_list, cac_list_meter, 1) != 0) { + cac_free_private_data(priv); + return NULL; + } + + /* Initialize General Applets List */ + if (list_init(&priv->general_list) != 0 || + list_attributes_comparator(&priv->general_list, cac_list_compare_path) != 0 || + list_attributes_copy(&priv->general_list, cac_list_meter, 1) != 0) { + cac_free_private_data(priv); + return NULL; + } + + return priv; +} + +void cac_free_private_data(cac_private_data_t *priv) +{ + free(priv->cac_id); + free(priv->cache_buf); + free(priv->aca_path); + list_destroy(&priv->pki_list); + list_destroy(&priv->general_list); + free(priv); + return; +} + +int cac_add_object_to_list(list_t *list, const cac_object_t *object) +{ + if (list_append(list, object) < 0) + return SC_ERROR_UNKNOWN; + return SC_SUCCESS; +} + diff --git a/src/libopensc/card-cac-common.h b/src/libopensc/card-cac-common.h new file mode 100644 index 0000000000..77f1476104 --- /dev/null +++ b/src/libopensc/card-cac-common.h @@ -0,0 +1,89 @@ +/* + * card-cac-common.h: Code shared among CAC1 and CAC2 drivers + * + * Copyright (C) 2018, Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef HAVE_CARD_CAC_COMMON_H +#define HAVE_CARD_CAC_COMMON_H + +#define CAC_MAX_SIZE 4096 /* arbitrary, just needs to be 'large enough' */ + +typedef struct cac_cuid { + u8 gsc_rid[5]; + u8 manufacturer_id; + u8 card_type; + u8 card_id; +} cac_cuid_t; + +/* data structures to store meta data about CAC objects */ +typedef struct cac_object { + const char *name; + int fd; + sc_path_t path; +} cac_object_t; + +/* + * CAC private data per card state + */ +typedef struct cac_private_data { + int object_type; /* select set this so we know how to read the file */ + int cert_next; /* index number for the next certificate found in the list */ + u8 *cache_buf; /* cached version of the currently selected file */ + size_t cache_buf_len; /* length of the cached selected file */ + int cached; /* is the cached selected file valid */ + cac_cuid_t cuid; /* card unique ID from the CCC */ + u8 *cac_id; /* card serial number */ + size_t cac_id_len; /* card serial number len */ + list_t pki_list; /* list of pki containers */ + cac_object_t *pki_current; /* current pki object _ctl function */ + list_t general_list; /* list of general containers */ + cac_object_t *general_current; /* current object for _ctl function */ + sc_path_t *aca_path; /* ACA path to be selected before pin verification */ +} cac_private_data_t; + +#define CAC_DATA(card) ((cac_private_data_t*)card->drv_data) + +/* + * Set up the normal CAC paths + */ +#define CAC_1_RID "\xA0\x00\x00\x00\x79" +#define CAC_TO_AID(x) x, sizeof(x)-1 + + +#define MAX_CAC_SLOTS 16 /* Maximum number of slots is 16 now */ + +/* template for a CAC pki object */ +static const cac_object_t cac_cac_pki_obj = { + "CAC Certificate", 0x0, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, + { CAC_TO_AID(CAC_1_RID "\x01\x00") } } +}; + +/* template for emulated cuid */ +static const cac_cuid_t cac_cac_cuid = { + { 0xa0, 0x00, 0x00, 0x00, 0x79 }, + 2, 2, 0 +}; + +cac_private_data_t *cac_new_private_data(void); +void cac_free_private_data(cac_private_data_t *priv); +int cac_add_object_to_list(list_t *list, const cac_object_t *object); +const char *get_cac_label(int index); + +#endif /* HAVE_CARD_CAC_COMMON_H */ diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index bd4e03362f..41ceabb022 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -43,12 +43,7 @@ #endif #ifdef ENABLE_OPENSSL - /* openssl only needed for card administration */ -#include -#include -#include -#include -#include +#include #endif /* ENABLE_OPENSSL */ #include "internal.h" @@ -58,8 +53,8 @@ #include "compression.h" #endif #include "iso7816.h" +#include "card-cac-common.h" -#define CAC_MAX_SIZE 4096 /* arbitrary, just needs to be 'large enough' */ /* * CAC hardware and APDU constants */ @@ -147,20 +142,6 @@ typedef struct cac_card_url { u8 keyCryptoAlgorithm; /* not used for VM cards */ } cac_card_url_t; -typedef struct cac_cuid { - u8 gsc_rid[5]; - u8 manufacturer_id; - u8 card_type; - u8 card_id; -} cac_cuid_t; - -/* data structures to store meta data about CAC objects */ -typedef struct cac_object { - const char *name; - int fd; - sc_path_t path; -} cac_object_t; - #define CAC_MAX_OBJECTS 16 typedef struct { @@ -190,82 +171,10 @@ typedef struct { #define CAC_OBJECT_TYPE_TLV_FILE 4 #define CAC_OBJECT_TYPE_GENERIC 5 -/* - * CAC private data per card state - */ -typedef struct cac_private_data { - int object_type; /* select set this so we know how to read the file */ - int cert_next; /* index number for the next certificate found in the list */ - u8 *cache_buf; /* cached version of the currently selected file */ - size_t cache_buf_len; /* length of the cached selected file */ - int cached; /* is the cached selected file valid */ - cac_cuid_t cuid; /* card unique ID from the CCC */ - u8 *cac_id; /* card serial number */ - size_t cac_id_len; /* card serial number len */ - list_t pki_list; /* list of pki containers */ - cac_object_t *pki_current; /* current pki object _ctl function */ - list_t general_list; /* list of general containers */ - cac_object_t *general_current; /* current object for _ctl function */ - sc_path_t *aca_path; /* ACA path to be selected before pin verification */ -} cac_private_data_t; - -#define CAC_DATA(card) ((cac_private_data_t*)card->drv_data) - -static int cac_list_compare_path(const void *a, const void *b) -{ - if (a == NULL || b == NULL) - return 1; - return memcmp( &((cac_object_t *) a)->path, - &((cac_object_t *) b)->path, sizeof(sc_path_t)); -} - -/* For SimCList autocopy, we need to know the size of the data elements */ -static size_t cac_list_meter(const void *el) { - return sizeof(cac_object_t); -} - -static cac_private_data_t *cac_new_private_data(void) -{ - cac_private_data_t *priv; - priv = calloc(1, sizeof(cac_private_data_t)); - if (!priv) - return NULL; - list_init(&priv->pki_list); - list_attributes_comparator(&priv->pki_list, cac_list_compare_path); - list_attributes_copy(&priv->pki_list, cac_list_meter, 1); - list_init(&priv->general_list); - list_attributes_comparator(&priv->general_list, cac_list_compare_path); - list_attributes_copy(&priv->general_list, cac_list_meter, 1); - /* set other fields as appropriate */ - - return priv; -} - -static void cac_free_private_data(cac_private_data_t *priv) -{ - free(priv->cac_id); - free(priv->cache_buf); - free(priv->aca_path); - list_destroy(&priv->pki_list); - list_destroy(&priv->general_list); - free(priv); - return; -} - -static int cac_add_object_to_list(list_t *list, const cac_object_t *object) -{ - if (list_append(list, object) < 0) - return SC_ERROR_UNKNOWN; - return SC_SUCCESS; -} - /* * Set up the normal CAC paths */ -#define CAC_TO_AID(x) x, sizeof(x)-1 - #define CAC_2_RID "\xA0\x00\x00\x01\x16" -#define CAC_1_RID "\xA0\x00\x00\x00\x79" static const sc_path_t cac_ACA_Path = { "", 0, @@ -279,39 +188,6 @@ static const sc_path_t cac_CCC_Path = { { CAC_TO_AID(CAC_2_RID "\xDB\x00") } }; -#define MAX_CAC_SLOTS 16 /* Maximum number of slots is 16 now */ -/* default certificate labels for the CAC card */ -static const char *cac_labels[MAX_CAC_SLOTS] = { - "CAC ID Certificate", - "CAC Email Signature Certificate", - "CAC Email Encryption Certificate", - "CAC Cert 4", - "CAC Cert 5", - "CAC Cert 6", - "CAC Cert 7", - "CAC Cert 8", - "CAC Cert 9", - "CAC Cert 10", - "CAC Cert 11", - "CAC Cert 12", - "CAC Cert 13", - "CAC Cert 14", - "CAC Cert 15", - "CAC Cert 16" -}; - -/* template for a CAC pki object */ -static const cac_object_t cac_cac_pki_obj = { - "CAC Certificate", 0x0, { { 0 }, 0, 0, 0, SC_PATH_TYPE_DF_NAME, - { CAC_TO_AID(CAC_1_RID "\x01\x00") } } -}; - -/* template for emulated cuid */ -static const cac_cuid_t cac_cac_cuid = { - { 0xa0, 0x00, 0x00, 0x00, 0x79 }, - 2, 2, 0 -}; - /* * CAC general objects defined in 4.3.1.2 of CAC Applet Developer Guide Version 1.0. * doubles as a source for CAC-2 labels. @@ -1178,7 +1054,7 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) * * The rest is just copied from iso7816_select_file */ -static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out, int type) +static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { struct sc_context *ctx; struct sc_apdu apdu; @@ -1198,19 +1074,18 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc pathtype = in_path->type; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "path->aid=%x %x %x %x %x %x %x len=%"SC_FORMAT_LEN_SIZE_T"u, path->value = %x %x %x %x len=%"SC_FORMAT_LEN_SIZE_T"u path->type=%d (%x)", - in_path->aid.value[0], in_path->aid.value[1], - in_path->aid.value[2], in_path->aid.value[3], - in_path->aid.value[4], in_path->aid.value[5], - in_path->aid.value[6], in_path->aid.len, in_path->value[0], - in_path->value[1], in_path->value[2], in_path->value[3], - in_path->len, in_path->type, in_path->type); + "path=%s, path->value=%s path->type=%d (%x)", + sc_print_path(in_path), + sc_dump_hex(in_path->value, in_path->len), + in_path->type, in_path->type); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "file_out=%p index=%d count=%d\n", - file_out, in_path->index, in_path->count); + file_out, in_path->index, in_path->count); - /* Sigh, sc_key_select expects paths to keys to have specific formats. There is no override. - * we have to add some bytes to the path to make it happy. A better fix would be to give sc_key_file - * a flag that says 'no, really this path is fine'. We only need to do this for private keys */ + /* Sigh, iso7816_select_file expects paths to keys to have specific + * formats. There is no override. We have to add some bytes to the + * path to make it happy. + * We only need to do this for private keys. + */ if ((pathlen > 2) && (pathlen <= 4) && memcmp(path, "\x3F\x00", 2) == 0) { if (pathlen > 2) { path += 2; @@ -1356,7 +1231,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc static int cac_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - return cac_select_file_by_type(card, in_path, file_out, card->type); + return cac_select_file_by_type(card, in_path, file_out); } static int cac_finish(sc_card_t *card) @@ -1374,13 +1249,13 @@ static int cac_finish(sc_card_t *card) /* select the Card Capabilities Container on CAC-2 */ static int cac_select_CCC(sc_card_t *card) { - return cac_select_file_by_type(card, &cac_CCC_Path, NULL, SC_CARD_TYPE_CAC_II); + return cac_select_file_by_type(card, &cac_CCC_Path, NULL); } /* Select ACA in non-standard location */ static int cac_select_ACA(sc_card_t *card) { - return cac_select_file_by_type(card, &cac_ACA_Path, NULL, SC_CARD_TYPE_CAC_II); + return cac_select_file_by_type(card, &cac_ACA_Path, NULL); } static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_t *val, int len) @@ -1432,7 +1307,7 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int /* Call without OID set will just select the AID without subseqent * OID selection, which we need to figure out just now */ - cac_select_file_by_type(card, &new_object.path, NULL, SC_CARD_TYPE_CAC_II); + cac_select_file_by_type(card, &new_object.path, NULL); r = cac_get_properties(card, &prop); if (r < 0) return SC_ERROR_INTERNAL; @@ -1444,7 +1319,7 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "ACA: pki_object found, cert_next=%d (%s), privkey=%d", - priv->cert_next, cac_labels[priv->cert_next], + priv->cert_next, get_cac_label(priv->cert_next), prop.objects[i].privatekey); /* If the private key is not initialized, we can safely @@ -1460,7 +1335,7 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int memcpy(new_object.path.value, &prop.objects[i].oid, 2); new_object.path.len = 2; new_object.path.type = SC_PATH_TYPE_FILE_ID; - new_object.name = cac_labels[priv->cert_next]; + new_object.name = get_cac_label(priv->cert_next); new_object.fd = priv->cert_next+1; cac_add_object_to_list(&priv->pki_list, &new_object); priv->cert_next++; @@ -1488,7 +1363,7 @@ static int cac_parse_cardurl(sc_card_t *card, cac_private_data_t *priv, cac_card */ if (priv->cert_next >= MAX_CAC_SLOTS) break; /* don't fail just because we have more certs than we can support */ - new_object.name = cac_labels[priv->cert_next]; + new_object.name = get_cac_label(priv->cert_next); new_object.fd = priv->cert_next+1; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"CARDURL: pki_object found, cert_next=%d (%s),", priv->cert_next, new_object.name); cac_add_object_to_list(&priv->pki_list, &new_object); @@ -1629,7 +1504,7 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, if (r < 0) return r; - r = cac_select_file_by_type(card, &new_path, NULL, SC_CARD_TYPE_CAC_II); + r = cac_select_file_by_type(card, &new_path, NULL); if (r < 0) return r; @@ -1740,7 +1615,7 @@ static int cac_select_pki_applet(sc_card_t *card, int index) { sc_path_t applet_path = cac_cac_pki_obj.path; applet_path.aid.value[applet_path.aid.len-1] = index; - return cac_select_file_by_type(card, &applet_path, NULL, SC_CARD_TYPE_CAC_II); + return cac_select_file_by_type(card, &applet_path, NULL); } /* @@ -1785,7 +1660,7 @@ static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t * for (i = index; i < MAX_CAC_SLOTS; i++) { r = cac_select_pki_applet(card, i); if (r == SC_SUCCESS) { - pki_obj.name = cac_labels[i]; + pki_obj.name = get_cac_label(i); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "CAC: pki_object found, cert_next=%d (%s),", i, pki_obj.name); pki_obj.path.aid.value[pki_obj.path.aid.len-1] = i; @@ -1796,8 +1671,7 @@ static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t * /* populate non-PKI objects */ for (i=0; i < cac_object_count; i++) { - r = cac_select_file_by_type(card, &cac_objects[i].path, NULL, - SC_CARD_TYPE_CAC_II); + r = cac_select_file_by_type(card, &cac_objects[i].path, NULL); if (r == SC_SUCCESS) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "CAC: obj_object found, cert_next=%d (%s),", diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c new file mode 100644 index 0000000000..a4bdd3f138 --- /dev/null +++ b/src/libopensc/card-cac1.c @@ -0,0 +1,556 @@ +/* + * card-cac1.c: Support for legacy CAC-1 + * card-default.c: Support for cards with no driver + * + * Copyright (C) 2001, 2002 Juha Yrjölä + * Copyright (C) 2005,2006,2007,2008,2009,2010 Douglas E. Engert + * Copyright (C) 2006, Identity Alliance, Thomas Harning + * Copyright (C) 2007, EMC, Russell Larner + * Copyright (C) 2016 - 2018, Red Hat, Inc. + * + * CAC driver author: Robert Relyea + * Further work: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#ifdef ENABLE_OPENSSL +#include +#endif /* ENABLE_OPENSSL */ + +#include "internal.h" +#include "simpletlv.h" +#include "cardctl.h" +#ifdef ENABLE_ZLIB +#include "compression.h" +#endif +#include "iso7816.h" +#include "card-cac-common.h" + +/* + * CAC hardware and APDU constants + */ +#define CAC_INS_GET_CERTIFICATE 0x36 /* CAC1 command to read a certificate */ + +/* + * OLD cac read certificate, only use with CAC-1 card. + */ +static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_len) +{ + u8 buf[CAC_MAX_SIZE]; + u8 *out_ptr; + size_t size = 0; + size_t left = 0; + size_t len, next_len; + sc_apdu_t apdu; + int r = SC_SUCCESS; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* get the size */ + size = left = *out_buf ? *out_len : sizeof(buf); + out_ptr = *out_buf ? *out_buf : buf; + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, CAC_INS_GET_CERTIFICATE, 0, 0 ); + next_len = MIN(left, 100); + for (; left > 0; left -= len, out_ptr += len) { + len = next_len; + apdu.resp = out_ptr; + apdu.le = len; + apdu.resplen = left; + r = sc_transmit_apdu(card, &apdu); + if (r < 0) { + break; + } + if (apdu.resplen == 0) { + r = SC_ERROR_INTERNAL; + break; + } + /* in the old CAC-1, 0x63 means 'more data' in addition to 'pin failed' */ + if (apdu.sw1 != 0x63 || apdu.sw2 < 1) { + /* we've either finished reading, or hit an error, break */ + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + left -= len; + break; + } + next_len = MIN(left, apdu.sw2); + } + if (r < 0) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + } + r = size - left; + if (*out_buf == NULL) { + *out_buf = malloc(r); + if (*out_buf == NULL) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, + SC_ERROR_OUT_OF_MEMORY); + } + memcpy(*out_buf, buf, r); + } + *out_len = r; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + +/* + * Callers of this may be expecting a certificate, + * select file will have saved the object type for us + * as well as set that we want the cert from the object. + */ +static int cac_read_binary(sc_card_t *card, unsigned int idx, + unsigned char *buf, size_t count, unsigned long flags) +{ + cac_private_data_t * priv = CAC_DATA(card); + int r = 0; + u8 *val = NULL; + u8 *cert_ptr; + size_t val_len; + size_t len, cert_len; + u8 cert_type; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* if we didn't return it all last time, return the remainder */ + if (priv->cached) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", + idx, count); + if (idx > priv->cache_buf_len) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_END_REACHED); + } + len = MIN(count, priv->cache_buf_len-idx); + memcpy(buf, &priv->cache_buf[idx], len); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); + } + + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + "clearing cache idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", + idx, count); + free(priv->cache_buf); + priv->cache_buf = NULL; + priv->cache_buf_len = 0; + + r = cac_cac1_get_certificate(card, &val, &val_len); + if (r < 0) + goto done; + + cert_type = val[0]; + cert_ptr = val + 1; + cert_len = val_len - 1; + + /* if the info byte is 1, then the cert is compressed, decompress it */ + if ((cert_type & 0x3) == 1) { +#ifdef ENABLE_ZLIB + r = sc_decompress_alloc(&priv->cache_buf, &priv->cache_buf_len, + cert_ptr, cert_len, COMPRESSION_AUTO); +#else + sc_log(card->ctx, "CAC compression not supported, no zlib"); + r = SC_ERROR_NOT_SUPPORTED; +#endif + if (r) + goto done; + cert_ptr = val; + } else if (cert_len > 0) { + priv->cache_buf = malloc(cert_len); + if (priv->cache_buf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto done; + } + priv->cache_buf_len = cert_len; + memcpy(priv->cache_buf, cert_ptr, cert_len); + } + + /* OK we've read the data, now copy the required portion out to the callers buffer */ + priv->cached = 1; + len = MIN(count, priv->cache_buf_len-idx); + memcpy(buf, &priv->cache_buf[idx], len); + r = len; +done: + if (val) + free(val); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); +} + +/* + * CAC cards use SC_PATH_SELECT_OBJECT_ID rather than SC_PATH_SELECT_FILE_ID. In order to use more + * of the PKCS #15 structure, we call the selection SC_PATH_SELECT_FILE_ID, but we set p1 to 2 instead + * of 0. Also cac1 does not do any FCI, but it doesn't understand not selecting it. It returns invalid INS + * if it doesn't like anything about the select, so we always 'request' FCI for CAC1 + * + * The rest is just copied from iso7816_select_file + */ +static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) +{ + struct sc_context *ctx; + struct sc_apdu apdu; + unsigned char buf[SC_MAX_APDU_BUFFER_SIZE]; + unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; + int r, pathlen, pathtype; + struct sc_file *file = NULL; + cac_private_data_t * priv = CAC_DATA(card); + + assert(card != NULL && in_path != NULL); + ctx = card->ctx; + + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); + + memcpy(path, in_path->value, in_path->len); + pathlen = in_path->len; + pathtype = in_path->type; + + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "path=%s, path->value=%s path->type=%d (%x)", + sc_print_path(in_path), + sc_dump_hex(in_path->value, in_path->len), + in_path->type, in_path->type); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "file_out=%p index=%d count=%d\n", + file_out, in_path->index, in_path->count); + + /* Sigh, iso7816_select_file expects paths to keys to have specific + * formats. There is no override. We have to add some bytes to the + * path to make it happy. + * We only need to do this for private keys. + */ + if ((pathlen > 2) && (pathlen <= 4) && memcmp(path, "\x3F\x00", 2) == 0) { + if (pathlen > 2) { + path += 2; + pathlen -= 2; + } + } + + + /* CAC has multiple different type of objects that aren't PKCS #15. When we read + * them we need convert them to something PKCS #15 would understand. Find the object + * and object type here: + */ + if (priv) { /* don't record anything if we haven't been initialized yet */ + /* forget any old cached values */ + if (priv->cache_buf) { + free(priv->cache_buf); + priv->cache_buf = NULL; + } + priv->cache_buf_len = 0; + priv->cached = 0; + } + + if (in_path->aid.len) { + if (!pathlen) { + memcpy(path, in_path->aid.value, in_path->aid.len); + pathlen = in_path->aid.len; + pathtype = SC_PATH_TYPE_DF_NAME; + } else { + /* First, select the application */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"select application" ); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0); + apdu.data = in_path->aid.value; + apdu.datalen = in_path->aid.len; + apdu.lc = in_path->aid.len; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + LOG_FUNC_RETURN(ctx, r); + + } + } + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0); + + switch (pathtype) { + /* ideally we would had SC_PATH_TYPE_OBJECT_ID and add code to the iso7816 select. + * Unfortunately we'd also need to update the caching code as well. For now just + * use FILE_ID and change p1 here */ + case SC_PATH_TYPE_FILE_ID: + apdu.p1 = 2; + if (pathlen != 2) + return SC_ERROR_INVALID_ARGUMENTS; + break; + case SC_PATH_TYPE_DF_NAME: + apdu.p1 = 4; + break; + default: + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + apdu.lc = pathlen; + apdu.data = path; + apdu.datalen = pathlen; + apdu.resp = buf; + apdu.resplen = sizeof(buf); + apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256; + apdu.p2 = 0x00; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + + if (file_out == NULL) { + /* For some cards 'SELECT' can be only with request to return FCI/FCP. */ + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86) { + apdu.p2 = 0x00; + apdu.resplen = sizeof(buf); + if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS) + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + } + if (apdu.sw1 == 0x61) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, r); + } + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + LOG_FUNC_RETURN(ctx, r); + + /* CAC cards never return FCI, fake one */ + file = sc_file_new(); + if (file == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + file->path = *in_path; + file->size = CAC_MAX_SIZE; /* we don't know how big, just give a large size until we can read the file */ + + *file_out = file; + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + +} + +static int cac_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) +{ + return cac_select_file_by_type(card, in_path, file_out); +} + +static int cac_finish(sc_card_t *card) +{ + cac_private_data_t * priv = CAC_DATA(card); + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (priv) { + cac_free_private_data(priv); + } + return SC_SUCCESS; +} + + +/* select a CAC pki applet by index */ +static int cac_select_pki_applet(sc_card_t *card, int index) +{ + sc_path_t applet_path = cac_cac_pki_obj.path; + applet_path.aid.value[applet_path.aid.len-1] = index; + return cac_select_file_by_type(card, &applet_path, NULL); +} + +/* + * Find the first existing CAC applet. If none found, then this isn't a CAC + */ +static int cac_find_first_pki_applet(sc_card_t *card, int *index_out) +{ + int r, i; + + for (i = 0; i < MAX_CAC_SLOTS; i++) { + r = cac_select_pki_applet(card, i); + if (r == SC_SUCCESS) { + u8 data[2]; + sc_apdu_t apdu; + + /* Try to read first two bytes of the buffer to + * make sure it is not just malfunctioning card + */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, + CAC_INS_GET_CERTIFICATE, 0x00, 0x00); + apdu.le = 0x02; + apdu.resplen = 2; + apdu.resp = data; + r = sc_transmit_apdu(card, &apdu); + /* SW1 = 0x63 means more data in CAC1 */ + if (r == SC_SUCCESS && apdu.sw1 != 0x63) + continue; + + *index_out = i; + return SC_SUCCESS; + } + } + return SC_ERROR_OBJECT_NOT_FOUND; +} + +static int cac_populate_cac1(sc_card_t *card, int index, cac_private_data_t *priv) +{ + int r, i; + cac_object_t pki_obj = cac_cac_pki_obj; + u8 buf[100]; + u8 *val; + size_t val_len; + + /* populate PKI objects */ + for (i = index; i < MAX_CAC_SLOTS; i++) { + r = cac_select_pki_applet(card, i); + if (r == SC_SUCCESS) { + pki_obj.name = get_cac_label(i); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, + "CAC: pki_object found, cert_next=%d (%s)", + i, pki_obj.name); + pki_obj.path.aid.value[pki_obj.path.aid.len-1] = i; + pki_obj.fd = i+1; /* don't use id of zero */ + cac_add_object_to_list(&priv->pki_list, &pki_obj); + } + } + + /* + * create a cuid to simulate the cac 2 cuid. + */ + priv->cuid = cac_cac_cuid; + /* create a serial number by hashing the first 100 bytes of the + * first certificate on the card */ + r = cac_select_pki_applet(card, index); + if (r < 0) { + return r; /* shouldn't happen unless the card has been removed or is malfunctioning */ + } + val = buf; + val_len = sizeof(buf); + r = cac_cac1_get_certificate(card, &val, &val_len); + if (r >= 0) { + priv->cac_id = malloc(20); + if (priv->cac_id == NULL) { + return SC_ERROR_OUT_OF_MEMORY; + } +#ifdef ENABLE_OPENSSL + SHA1(val, val_len, priv->cac_id); + priv->cac_id_len = 20; + sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE, + "cuid", priv->cac_id, priv->cac_id_len); +#else + sc_log(card->ctx, "OpenSSL Required"); + return SC_ERROR_NOT_SUPPORTED; +#endif /* ENABLE_OPENSSL */ + } + return SC_SUCCESS; +} + +/* + * Look for a CAC card. If it exists, initialize our data structures + */ +static int cac_find_and_initialize(sc_card_t *card, int initialize) +{ + int r, index; + cac_private_data_t *priv = NULL; + + /* already initialized? */ + if (card->drv_data) { + return SC_SUCCESS; + } + + /* is this a CAC Alt token without any accompanying structures */ + r = cac_find_first_pki_applet(card, &index); + if (r == SC_SUCCESS) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "PKI applet found, is bare CAC-1"); + if (!initialize) /* match card only */ + return r; + + if (!priv) { + priv = cac_new_private_data(); + if (!priv) + return SC_ERROR_OUT_OF_MEMORY; + } + card->drv_data = priv; /* needed for the read_binary() */ + r = cac_populate_cac1(card, index, priv); + if (r == SC_SUCCESS) { + card->type = SC_CARD_TYPE_CAC_I; + return r; + } + card->drv_data = NULL; /* reset on failure */ + } + if (priv) { + cac_free_private_data(priv); + } + return r; +} + + +/* NOTE: returns a bool, 1 card matches, 0 it does not */ +static int cac_match_card(sc_card_t *card) +{ + int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* Since we send an APDU, the card's logout function may be called... + * however it may be in dirty memory */ + card->ops->logout = NULL; + + r = cac_find_and_initialize(card, 0); + return (r == SC_SUCCESS); /* never match */ +} + + +static int cac_init(sc_card_t *card) +{ + int r; + unsigned long flags; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = cac_find_and_initialize(card, 1); + if (r < 0) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + } + flags = SC_ALGORITHM_RSA_RAW; + + _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ + _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ + + card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); +} + +static struct sc_card_operations cac_ops; + +static struct sc_card_driver cac1_drv = { + "Common Access Card (CAC 1)", + "cac1", + &cac_ops, + NULL, 0, NULL +}; + +static struct sc_card_driver * sc_get_driver(void) +{ + /* Inherit most of the things from the CAC driver */ + struct sc_card_driver *cac_drv = sc_get_cac_driver(); + + cac_ops = *cac_drv->ops; + cac_ops.match_card = cac_match_card; + cac_ops.init = cac_init; + cac_ops.finish = cac_finish; + + cac_ops.select_file = cac_select_file; /* need to record object type */ + cac_ops.read_binary = cac_read_binary; + + return &cac1_drv; +} + + +struct sc_card_driver * sc_get_cac1_driver(void) +{ + return sc_get_driver(); +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 5d545b3583..f4df17fb04 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -286,6 +286,7 @@ extern sc_card_driver_t *sc_get_gids_driver(void); extern sc_card_driver_t *sc_get_jpki_driver(void); extern sc_card_driver_t *sc_get_coolkey_driver(void); extern sc_card_driver_t *sc_get_cac_driver(void); +extern sc_card_driver_t *sc_get_cac1_driver(void); extern sc_card_driver_t *sc_get_npa_driver(void); #ifdef __cplusplus diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 162a41f8bf..dff75ed8be 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -147,6 +147,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "openpgp", (void *(*)(void)) sc_get_openpgp_driver }, { "jpki", (void *(*)(void)) sc_get_jpki_driver }, { "npa", (void *(*)(void)) sc_get_npa_driver }, + { "cac1", (void *(*)(void)) sc_get_cac1_driver }, /* The default driver should be last, as it handles all the * unrecognized cards. */ { "default", (void *(*)(void)) sc_get_default_driver }, From 5f51d5d315aa7a30bc670190d99e30a0a7fb53a1 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 22 Sep 2017 15:03:31 +0300 Subject: [PATCH 0570/4321] Added implementation of C_UnwrapKey all the way from PKCS#11 interface to the card driver level. Not yet complete, but can be run with CKA_TOKEN=FALSE set in the target object. Currently unwrapping emulated with a decrypt operation in card-myeid.c. To be improved. --- src/libopensc/card-myeid.c | 34 ++++++++++++ src/libopensc/iso7816.c | 4 +- src/libopensc/libopensc.exports | 3 +- src/libopensc/opensc.h | 19 +++++++ src/libopensc/pkcs15-sec.c | 47 +++++++++++++++++ src/libopensc/pkcs15.h | 9 +++- src/libopensc/sec.c | 15 ++++++ src/pkcs11/framework-pkcs15.c | 93 ++++++++++++++++++++++++++++----- src/pkcs11/mechanism.c | 83 ++++++++++++++++++++++++++++- src/pkcs11/openssl.c | 14 +++++ src/pkcs11/pkcs11-object.c | 64 ++++++++++++++++++++++- src/pkcs11/sc-pkcs11.h | 20 ++++++- src/pkcs15init/pkcs15-init.h | 6 +++ src/pkcs15init/pkcs15-lib.c | 22 +++++--- 14 files changed, 405 insertions(+), 28 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index d4b4cbd6f2..8298f61cb2 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -227,6 +227,9 @@ static int myeid_init(struct sc_card *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; + /* if (card->version.fw_major >= 41) */ /* TODO: check the version number that actually supports these ops */ + card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY; + card->max_recv_size = 255; card->max_send_size = 255; @@ -632,6 +635,10 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * apdu.p1 = 0x41; apdu.p2 = 0xB6; break; + case SC_SEC_OPERATION_UNWRAP: + apdu.p1 = 0x41; /* emulating unwrapping with DECIPHER operation */ + apdu.p2 = 0xB8; /* TODO: set correct params when operation is implemented on card */ + break; default: return SC_ERROR_INVALID_ARGUMENTS; } @@ -1185,6 +1192,31 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, } +static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) +{ + int r; + LOG_FUNC_CALLED(card->ctx); + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +} + +static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len) +{ + int r; + u8 out[512]; + size_t outlen = 512; + + LOG_FUNC_CALLED(card->ctx); + + /* Emulate unwrapping with decipher */ + r = myeid_decipher(card, crgram, crgram_len, out, outlen); + + LOG_FUNC_RETURN(card->ctx, r); + + /*LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); */ +} + + /* Write internal data, e.g. add default pin-records to pin */ static int myeid_putdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* data_obj) { @@ -1601,6 +1633,8 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.process_fci = myeid_process_fci; myeid_ops.card_ctl = myeid_card_ctl; myeid_ops.pin_cmd = myeid_pin_cmd; + myeid_ops.wrap = myeid_wrap_key; + myeid_ops.unwrap = myeid_unwrap_key; return &myeid_drv; } diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 6abd2d76c5..f3bae4839e 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1273,7 +1273,9 @@ static struct sc_card_operations iso_ops = { NULL, /* put_data */ NULL, /* delete_record */ NULL, /* read_public_key */ - NULL /* card_reader_lock_obtained */ + NULL, /* card_reader_lock_obtained */ + NULL, /* wrap */ + NULL /* unwrap */ }; static struct sc_card_driver iso_driver = { diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 62628ea420..a40e471583 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -175,7 +175,7 @@ sc_pkcs15_encode_pubkey_dsa sc_pkcs15_encode_pubkey_rsa sc_pkcs15_encode_pubkey_ec sc_pkcs15_encode_pubkey_gostr3410 -sc_pkcs15_encode_pubkey_as_spki +sc_pkcs15_encode_pubkey_as_spki sc_pkcs15_encode_pukdf_entry sc_pkcs15_encode_tokeninfo sc_pkcs15_encode_unusedspace @@ -237,6 +237,7 @@ sc_pkcs15_remove_unusedspace sc_pkcs15_search_objects sc_pkcs15_unbind sc_pkcs15_unblock_pin +sc_pkcs15_unwrap sc_pkcs15_verify_pin sc_pkcs15_get_pin_info sc_pkcs15_verify_pin_with_session_pin diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 0abbf6a957..e626f7f73f 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -57,6 +57,8 @@ extern "C" { #define SC_SEC_OPERATION_SIGN 0x0002 #define SC_SEC_OPERATION_AUTHENTICATE 0x0003 #define SC_SEC_OPERATION_DERIVE 0x0004 +#define SC_SEC_OPERATION_WRAP 0x0005 +#define SC_SEC_OPERATION_UNWRAP 0x0006 /* sc_security_env flags */ #define SC_SEC_ENV_ALG_REF_PRESENT 0x0001 @@ -525,6 +527,17 @@ struct sc_reader_operations { /* Card (or card driver) supports generating a session PIN */ #define SC_CARD_CAP_SESSION_PIN 0x00000200 +/* Card and driver supports handling on card session objects. + * If a driver has this capability, the driver handles storage and operations + * with objects that CKA_TOKEN set to FALSE. If a driver doesn't support this, + * OpenSC handles them as in memory objects.*/ +#define SC_CARD_CAP_ONCARD_SESSION_OBJECTS 0x00000400 + +/* Card (or card driver) supports key wrapping operations */ +#define SC_CARD_CAP_WRAP_KEY 0x00000800 +/* Card (or card driver) supports key unwrapping operations */ +#define SC_CARD_CAP_UNWRAP_KEY 0x00001000 + typedef struct sc_card { struct sc_context *ctx; struct sc_reader *reader; @@ -689,6 +702,10 @@ struct sc_card_operations { unsigned char **, size_t *); int (*card_reader_lock_obtained)(struct sc_card *, int was_reset); + + int (*wrap)(struct sc_card *card, u8 *out, size_t outlen); + + int (*unwrap)(struct sc_card *card, const u8 *crgram, size_t crgram_len); }; typedef struct sc_card_driver { @@ -1192,6 +1209,8 @@ int sc_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen); int sc_compute_signature(struct sc_card *card, const u8 * data, size_t data_len, u8 * out, size_t outlen); +int sc_unwrap(struct sc_card *card, const u8 * data, + size_t data_len, u8 * out, size_t outlen); int sc_verify(struct sc_card *card, unsigned int type, int ref, const u8 *buf, size_t buflen, int *tries_left); /** diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 3e7e03b12d..140af96863 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -297,6 +297,53 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, r); } + +/* + * Unwrap a key into a key object on card. + * in holds the wrapped key data + * the target file that target_key points to must be created before calling this function + * Use pkcs15init to peform the complete unwrapping operation and create the pkcs#15 object for the new key. + */ +int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *key, + struct sc_pkcs15_object *target_key, + unsigned long flags, + const u8 * in, size_t inlen) +{ + sc_context_t *ctx = p15card->card->ctx; + int r; + sc_algorithm_info_t *alg_info = NULL; + sc_security_env_t senv; + const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) key->data; + unsigned long pad_flags = 0, sec_flags = 0; + u8 *out = 0; + size_t poutlen = 0; + + LOG_FUNC_CALLED(ctx); + + if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP))) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping"); + + if (!(key->type == SC_PKCS15_TYPE_PRKEY_RSA || + (key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) { + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,"Key type not supported"); + } + + r = format_senv(p15card, key, &senv, &alg_info); + LOG_TEST_RET(ctx, r, "Could not initialize security environment"); + senv.operation = SC_SEC_OPERATION_UNWRAP; + + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); + LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); + senv.algorithm_flags = sec_flags; + + r = use_key(p15card, key, &senv, sc_unwrap, in, inlen, out, + poutlen); + LOG_TEST_RET(ctx, r, "use_key() failed"); + + LOG_FUNC_RETURN(ctx, r); +} + /* copied from pkcs15-cardos.c */ #define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\ SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 74dcddf8a6..b4890a9e1d 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -452,6 +452,7 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t; #define SC_PKCS15_TYPE_SKEY_DES 0x302 #define SC_PKCS15_TYPE_SKEY_2DES 0x303 #define SC_PKCS15_TYPE_SKEY_3DES 0x304 +#define SC_PKCS15_TYPE_SKEY_AES 0x305 #define SC_PKCS15_TYPE_CERT 0x400 #define SC_PKCS15_TYPE_CERT_X509 0x401 @@ -660,6 +661,12 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, unsigned long flags, const u8 *in, size_t inlen, u8 *out, unsigned long *poutlen); +int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *key, + struct sc_pkcs15_object *target_key, + unsigned long flags, + const u8 * in, size_t inlen); + int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, unsigned long alg_flags, const u8 *in, @@ -687,7 +694,7 @@ int sc_pkcs15_decode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, const u8 *, size_t); int sc_pkcs15_encode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, u8 **, size_t *); -int sc_pkcs15_encode_pubkey_as_spki(struct sc_context *, +int sc_pkcs15_encode_pubkey_as_spki(struct sc_context *, struct sc_pkcs15_pubkey *, u8 **, size_t *); void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *); void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *); diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index e422ac4a65..84eb0ce72f 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -63,6 +63,21 @@ int sc_compute_signature(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } +int sc_unwrap(sc_card_t *card, + const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) +{ + int r; + + if (card == NULL || crgram == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + if (card->ops->unwrap == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + r = card->ops->unwrap(card, crgram, crgram_len); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + int sc_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 85e12df660..9e45dfeebf 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2207,7 +2207,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15_skey_info *skey_info; CK_KEY_TYPE key_type; CK_BBOOL _token = FALSE; - int rv; + int rv, rc; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2228,6 +2228,9 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile switch (key_type) { /* Only support GENERIC_SECRET for now */ case CKK_GENERIC_SECRET: + case CKK_AES: + case CKK_DES3: + case CKK_DES: break; default: return CKR_ATTRIBUTE_VALUE_INVALID; @@ -2283,7 +2286,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } /* If creating a PKCS#11 session object, i.e. one that is only in memory */ - if (_token == FALSE) { + if (_token == FALSE && (fw_data->p15_card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == 0) { /* TODO Have 3 choices as to how to create the object. * (1)create a sc_pkcs15init_store_secret_key routine like the others @@ -2303,11 +2306,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile key_obj->flags = 2; /* TODO not sure what these mean */ - skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); - if (skey_info == NULL) { + skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); + if (skey_info == NULL) { rv = CKR_HOST_MEMORY; goto out; - } + } key_obj->data = skey_info; skey_info->usage = args.usage; skey_info->native = 0; /* card can not use this */ @@ -2319,18 +2322,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile args.key.data = NULL; } else { -#if 1 - rv = CKR_FUNCTION_NOT_SUPPORTED; - goto out; -#else - /* TODO add support for secret key on the card with something like this: */ - rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); goto out; } -#endif } /* Create a new pkcs11 object for it */ @@ -3480,6 +3476,7 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = { NULL, /* derive */ NULL, /* can_do */ NULL /* init_params */ + NULL /* wrap_key */ }; /* @@ -3910,6 +3907,69 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, } +static CK_RV +pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, + CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + void *targetKey) +/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttributesLen, + void ** pUnwrappedKey)*/ +{ + struct sc_pkcs11_card *p11card = session->slot->p11card; + struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; + struct sc_pkcs11_object *targetKeyObj = (struct sc_pkcs11_object *) targetKey; + int rv, flags = 0; + + sc_log(context, "Initiating unwrapping with private key."); + + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); + + sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj, + pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj); + + if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) + return CKR_ARGUMENTS_BAD; + + /* See which of the alternative keys supports unwrap */ + while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP)) + prkey = prkey->prv_next; + + if (prkey == NULL) + return CKR_KEY_FUNCTION_NOT_PERMITTED; + + /* Select the proper padding mechanism */ + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS: + flags |= SC_ALGORITHM_RSA_PAD_PKCS1; + break; + case CKM_RSA_X_509: + flags |= SC_ALGORITHM_RSA_RAW; + break; + default: + return CKR_MECHANISM_INVALID; + } + + rv = sc_lock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + /* Call the card to do the unwrap operation */ + rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, (struct sc_pkcs15_object *) targetKeyObj, 0, + pWrappedKey, ulWrappedKeyLen); + + sc_unlock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + return CKR_OK; +} + + static CK_RV pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, @@ -4183,11 +4243,12 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = { pkcs15_any_destroy, NULL, /* get_size */ pkcs15_prkey_sign, - NULL, /* unwrap */ + pkcs15_prkey_unwrap, pkcs15_prkey_decrypt, pkcs15_prkey_derive, pkcs15_prkey_can_do, pkcs15_prkey_init_params, + NULL /* wrap_key */ }; /* @@ -4426,6 +4487,7 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { NULL, /* derive */ NULL, /* can_do */ NULL /* init_params */ + NULL /* wrap_key */ }; @@ -4605,6 +4667,7 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = { NULL, /* derive */ NULL, /* can_do */ NULL /* init_params */ + NULL /* wrap_key */ }; @@ -4735,6 +4798,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { NULL, /* derive */ NULL, /* can_do */ NULL /* init_params */ + pkcs15_skey_wrap /* wrap_key */ }; /* @@ -5084,6 +5148,9 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* That practise definitely conflicts with CKF_HW -- andre 2010-11-28 */ mech_info.flags |= CKF_VERIFY; #endif + if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY) + mech_info.flags |= CKF_UNWRAP; + mech_info.ulMinKeySize = ~0; mech_info.ulMaxKeySize = 0; ec_min_key_size = ~0; diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index d4ce7fef5c..45d6fb1511 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -830,6 +830,64 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session, return rv; } +/* + * Unwrap a wrapped key into card. A new key object is created on card. + */ +CK_RV +sc_pkcs11_unwrap(struct sc_pkcs11_session *session, + CK_MECHANISM_PTR pMechanism, + struct sc_pkcs11_object *unwrappingKey, + CK_KEY_TYPE key_type, /* type of the unwrapping key */ + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pWrappedKey, /* the wrapped key */ + CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key */ + struct sc_pkcs11_object *targetKey) +{ + struct sc_pkcs11_card *p11card; + sc_pkcs11_operation_t *operation; + sc_pkcs11_mechanism_type_t *mt; + + CK_RV rv; + + if (!session || !session->slot + || !(p11card = session->slot->p11card)) + return CKR_ARGUMENTS_BAD; + + /* See if we support this mechanism type */ + mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_UNWRAP); + if (mt == NULL) + return CKR_MECHANISM_INVALID; + + /* See if compatible with key type */ + /* TODO: what if there are several mechanisms with different key types? Should we loop through them? */ + if (mt->key_type != key_type) + return CKR_KEY_TYPE_INCONSISTENT; + + rv = session_start_operation(session, SC_PKCS11_OPERATION_UNWRAP, mt, &operation); + if (rv != CKR_OK) + return rv; + + memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); + + + /* + * TODO: does it make sense to support unwrapping to a in memory key object? + * This implementation assumes that the key should be unwrapped into a + * key object on card, regardless whether CKA_TOKEN = FALSE + * CKA_TOKEN = FALSE is considered an on card session object. + */ + + rv = operation->type->unwrap(operation, unwrappingKey, + pWrappedKey, ulWrappedKeyLen, + targetKey); + + session_stop_operation(session, SC_PKCS11_OPERATION_UNWRAP); + + return rv; +} + + + /* Derive one key from another, and return results in created object */ CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *session, @@ -990,6 +1048,29 @@ sc_pkcs11_derive(sc_pkcs11_operation_t *operation, pData, pulDataLen); } + +static CK_RV +sc_pkcs11_unwrap_operation(sc_pkcs11_operation_t *operation, + struct sc_pkcs11_object *unwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + struct sc_pkcs11_object *targetKey) +/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttresLen, + void** phUnwrappedKey)*/ +{ + return unwrappingKey->ops->unwrap_key(operation->session, + unwrappingKey, + &operation->mechanism, + pWrappedKey, ulWrappedKeyLen, + targetKey); + + /*return unwrappingKey->ops->unwrap_key(operation->session, + unwrappingKey, + &operation->mechanism, + pmechParam, ulmechParamLen, + pAttributes, ulAttresLen, + phUnwrappedKey);*/ +} + /* * Create new mechanism type for a mechanism supported by * the card @@ -1027,7 +1108,7 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, #endif } if (pInfo->flags & CKF_UNWRAP) { - /* TODO */ + mt->unwrap = sc_pkcs11_unwrap_operation; } if (pInfo->flags & CKF_DERIVE) { mt->derive = sc_pkcs11_derive; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index fb9f8fea81..1255d47f83 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -64,6 +64,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -98,6 +100,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -115,6 +119,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -132,6 +138,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -150,6 +158,8 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -168,6 +178,8 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -185,6 +197,8 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 0cc77d604e..65fc8a9322 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -47,6 +47,8 @@ static sc_pkcs11_mechanism_type_t find_mechanism = { NULL, /* decrypt_init */ NULL, /* decrypt */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; @@ -1049,7 +1051,67 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ULONG ulAttributeCount, /* # of attributes in template */ CK_OBJECT_HANDLE_PTR phKey) { /* gets handle of recovered key */ - return CKR_FUNCTION_NOT_SUPPORTED; + CK_RV rv; + CK_BBOOL can_unwrap; + CK_KEY_TYPE key_type; + CK_ATTRIBUTE unwrap_attribute = { CKA_UNWRAP, &can_unwrap, sizeof(can_unwrap) }; + CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; + struct sc_pkcs11_session *session; + struct sc_pkcs11_object *object; + struct sc_pkcs11_object *key_object; + + if (pMechanism == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_object_from_session(hSession, hUnwrappingKey, &session, &object); + if (rv != CKR_OK) { + if (rv == CKR_OBJECT_HANDLE_INVALID) + rv = CKR_KEY_HANDLE_INVALID; + goto out; + } + if (object->ops->unwrap_key == NULL_PTR) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + rv = object->ops->get_attribute(session, object, &unwrap_attribute); + if (rv != CKR_OK || !can_unwrap) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + rv = object->ops->get_attribute(session, object, &key_type_attr); + if (rv != CKR_OK) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + /* Create the target object in memory */ + rv = sc_create_object_int(hSession, pTemplate, ulAttributeCount, phKey, 0); + + if (rv != CKR_OK) + goto out; + + rv = get_object_from_session(hSession, *phKey, &session, &key_object); + if (rv != CKR_OK) { + if (rv == CKR_OBJECT_HANDLE_INVALID) + rv = CKR_KEY_HANDLE_INVALID; + goto out; + } + + rv = restore_login_state(session->slot); + if (rv == CKR_OK) + rv = sc_pkcs11_unwrap(session, pMechanism, object, key_type, + hSession, pWrappedKey, ulWrappedKeyLen, key_object); + /* TODO if (rv != CK_OK) need to destroy the object */ + rv = reset_login_state(session->slot, rv); + +out: + sc_pkcs11_unlock(); + return rv; } CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index f0115ed04b..fe6bd8c9a2 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -104,8 +104,7 @@ struct sc_pkcs11_object_ops { CK_RV (*unwrap_key)(struct sc_pkcs11_session *, void *, CK_MECHANISM_PTR, CK_BYTE_PTR pData, CK_ULONG ulDataLen, - CK_ATTRIBUTE_PTR, CK_ULONG, - void **); + void *targetKey); CK_RV (*decrypt)(struct sc_pkcs11_session *, void *, CK_MECHANISM_PTR, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, @@ -122,6 +121,11 @@ struct sc_pkcs11_object_ops { /* General validation of mechanism parameters (sign, encrypt, etc) */ CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR); + CK_RV (*wrap_key)(struct sc_pkcs11_session *, void *, + CK_MECHANISM_PTR, + void*, + CK_BYTE_PTR pData, CK_ULONG_PTR ulDataLen); + /* Others to be added when implemented */ }; @@ -237,6 +241,8 @@ enum { SC_PKCS11_OPERATION_DIGEST, SC_PKCS11_OPERATION_DECRYPT, SC_PKCS11_OPERATION_DERIVE, + SC_PKCS11_OPERATION_WRAP, + SC_PKCS11_OPERATION_UNWRAP, SC_PKCS11_OPERATION_MAX }; @@ -280,6 +286,15 @@ struct sc_pkcs11_mechanism_type { struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*wrap)(sc_pkcs11_operation_t *, + struct sc_pkcs11_object *, + struct sc_pkcs11_object *, + CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*unwrap)(sc_pkcs11_operation_t *, + struct sc_pkcs11_object *, + CK_BYTE_PTR, CK_ULONG, + struct sc_pkcs11_object *); + /* mechanism specific data */ const void * mech_data; /* free mechanism specific data */ @@ -419,6 +434,7 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); #endif CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE); CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *); CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *); diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 0133e73b2b..011485487b 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -418,6 +418,12 @@ extern int sc_pkcs15init_sanity_check(struct sc_pkcs15_card *, struct sc_profile extern int sc_pkcs15init_finalize_profile(struct sc_card *card, struct sc_profile *profile, struct sc_aid *aid); +extern int sc_pkcs15init_unwrap_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile, + struct sc_pkcs15_object *key, u8* wrapped_key, size_t wrapped_key_len, + struct sc_pkcs15init_skeyargs *keyargs, struct sc_pkcs15_object **res_obj); + + + extern struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 04370ce913..cc238221b4 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -175,6 +175,7 @@ static struct sc_pkcs15init_callbacks callbacks = { NULL, }; + static void sc_pkcs15init_empty_callback(void *ptr) { } @@ -1880,8 +1881,9 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0)) { /* Make sure the caller explicitly tells us to store * the key as extractable. */ - if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) - LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key."); + /* Commented out. I don't understand why one couldn't store a key as non extractable. -HH */ +/* if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) + LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key.");*/ } #ifdef ENABLE_OPENSSL @@ -1908,12 +1910,16 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile r = profile->ops->create_key(profile, p15card, object); LOG_TEST_RET(ctx, r, "Card specific 'create key' failed"); - if (profile->ops->store_key) { - struct sc_pkcs15_prkey key; - memset(&key, 0, sizeof(key)); - key.algorithm = keyargs->algorithm; - key.u.secret = keyargs->key; - r = profile->ops->store_key(profile, p15card, object, &key); + /* If no key data, only an empty EF is created. + * It can be used to receive an unwrapped key later. */ + if (keyargs->key.data_len > 0) { + if (profile->ops->store_key) { + struct sc_pkcs15_prkey key; + memset(&key, 0, sizeof(key)); + key.algorithm = keyargs->algorithm; + key.u.secret = keyargs->key; + r = profile->ops->store_key(profile, p15card, object, &key); + } } LOG_TEST_RET(ctx, r, "Card specific 'store key' failed"); From a10480d50ed32ddda73089e7fb5e865efd441c82 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 4 Oct 2017 14:03:16 +0300 Subject: [PATCH 0571/4321] Continued implementation of unwrap: Creation of a target key object on card to receive an unwrapped key. Setting target key path in sc_security_env_t. --- src/libopensc/card-myeid.c | 1 + src/libopensc/opensc.h | 2 ++ src/libopensc/pkcs15-sec.c | 31 +++++++++++++++++++++++++++++++ src/pkcs11/framework-pkcs15.c | 23 ++++++++++++++++++----- src/pkcs15init/pkcs15-lib.c | 1 - 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 8298f61cb2..cc36b9bfad 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -663,6 +663,7 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * *p++ = 1; *p++ = 0; } + /* TODO: handle SC_SEC_ENV_TARGET_FILE_REF_PRESENT, if this is an unwrapping operation. */ r = p - sbuf; apdu.lc = r; apdu.datalen = r; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index e626f7f73f..f512add325 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -66,6 +66,7 @@ extern "C" { #define SC_SEC_ENV_KEY_REF_PRESENT 0x0004 #define SC_SEC_ENV_KEY_REF_SYMMETRIC 0x0008 #define SC_SEC_ENV_ALG_PRESENT 0x0010 +#define SC_SEC_ENV_TARGET_FILE_REF_PRESENT 0x0020 /* PK algorithms */ #define SC_ALGORITHM_RSA 0 @@ -220,6 +221,7 @@ typedef struct sc_security_env { struct sc_path file_ref; unsigned char key_ref[8]; size_t key_ref_len; + struct sc_path target_file_ref; /* target key file in unwrap operation */ struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS]; } sc_security_env_t; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 140af96863..80f6ca5d1d 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -315,9 +315,11 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, sc_algorithm_info_t *alg_info = NULL; sc_security_env_t senv; const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) key->data; + const struct sc_pkcs15_skey_info *tkey = (const struct sc_pkcs15_skey_info *) target_key->data; unsigned long pad_flags = 0, sec_flags = 0; u8 *out = 0; size_t poutlen = 0; + sc_path_t path, target_file_id; LOG_FUNC_CALLED(ctx); @@ -333,6 +335,35 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, r, "Could not initialize security environment"); senv.operation = SC_SEC_OPERATION_UNWRAP; + memset(&path, 0, sizeof(sc_path_t)); + memset(&target_file_id, 0, sizeof(sc_path_t)); + + if (!tkey->path.len && tkey->path.aid.len) { + /* Target key is a SDO allocated in application DF */ + path = tkey->path; + } + else if (tkey->path.len == 2 && p15card->file_app != NULL) { + /* Path is relative to app. DF */ + path = p15card->file_app->path; + target_file_id = tkey->path; + sc_append_path(&path, &target_file_id); + senv.target_file_ref = target_file_id; + senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + } + else if (tkey->path.len > 2) { + path = tkey->path; + memcpy(target_file_id.value, tkey->path.value + tkey->path.len - 2, 2); + target_file_id.len = 2; + target_file_id.type = SC_PATH_TYPE_FILE_ID; + senv.target_file_ref = target_file_id; + senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + } + else { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); + } + + + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9e45dfeebf..bbca3c6cc8 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2188,7 +2188,7 @@ out: return rv; /* TODO Only Session secret key objects are supported for now - * Sesison objects have CKA_TOKEN=false + * Session objects have CKA_TOKEN=false * This is used by the C_DeriveKey with ECDH to hold the * key, and the calling application can then retrieve tha attributes as needed. * TODO If a card can support secret key objects on the card, this @@ -2204,11 +2204,13 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15init_skeyargs args; struct pkcs15_any_object *key_any_obj = NULL; struct sc_pkcs15_object *key_obj = NULL; + struct sc_pkcs15_auth_info *pin = NULL; struct sc_pkcs15_skey_info *skey_info; CK_KEY_TYPE key_type; CK_BBOOL _token = FALSE; int rv, rc; char label[SC_PKCS15_MAX_LABEL_SIZE]; + CK_BBOOL temp_object = FALSE; memset(&args, 0, sizeof(args)); fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; @@ -2225,13 +2227,22 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile if (rv != CKR_OK) return rv; + /* See if the "slot" is pin protected. If so, get the PIN id */ + if ((pin = slot_data_auth_info(slot->fw_data)) != NULL) + args.auth_id = pin->auth_id; + switch (key_type) { /* Only support GENERIC_SECRET for now */ case CKK_GENERIC_SECRET: case CKK_AES: + args.algorithm = SC_ALGORITHM_AES; + break; case CKK_DES3: + args.algorithm = SC_ALGORITHM_3DES; + break; case CKK_DES: - break; + args.algorithm = SC_ALGORITHM_DES; + break; default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -2299,6 +2310,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile rv = CKR_HOST_MEMORY; goto out; } + temp_object = TRUE; key_obj->type = SC_PKCS15_TYPE_SKEY; if (args.id.len) @@ -2337,7 +2349,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile out: free(args.key.data); /* if allocated */ - free(key_obj); + if (temp_object) + free(key_obj); /* do not free if the object was created by pkcs15init. It will be freed in C_Finalize */ return rv; } @@ -3918,7 +3931,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; - struct sc_pkcs11_object *targetKeyObj = (struct sc_pkcs11_object *) targetKey; + struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; int rv, flags = 0; sc_log(context, "Initiating unwrapping with private key."); @@ -3958,7 +3971,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(rv, "C_UnwrapKey"); /* Call the card to do the unwrap operation */ - rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, (struct sc_pkcs15_object *) targetKeyObj, 0, + rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->prv_p15obj, 0, pWrappedKey, ulWrappedKeyLen); sc_unlock(p11card->card); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index cc238221b4..cc9d26e969 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1944,7 +1944,6 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile LOG_FUNC_RETURN(ctx, r); } - /* * Store a certificate */ From 9772edc7d1b11cd4b13eae36ccb7731b83f067a2 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 8 Nov 2017 14:31:10 +0200 Subject: [PATCH 0572/4321] Handle -u option (x509-usage) when storing secret keys. --- src/tools/pkcs15-init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index fd975b0ae8..b527f684c4 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1835,6 +1835,14 @@ static int init_skeyargs(struct sc_pkcs15init_skeyargs *args) } args->label = opt_label; + if ((opt_x509_usage & SC_PKCS15INIT_X509_DATA_ENCIPHERMENT) == SC_PKCS15INIT_X509_DATA_ENCIPHERMENT) { + args->usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; + } + + if ((opt_x509_usage & SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) == SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) { + args->usage |= SC_PKCS15_PRKEY_USAGE_WRAP | SC_PKCS15_PRKEY_USAGE_UNWRAP; + } + return 0; } From 7fc6c52f81ddff4e0903d8b7d59b2c76c676a5ff Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 15:40:56 +0200 Subject: [PATCH 0573/4321] Set native=1 as default when decoding. Check supported algorithms and set PKCS#11 key type, if key supports AES. --- src/libopensc/pkcs15-skey.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c index 006dfa1100..f715e4a86a 100644 --- a/src/libopensc/pkcs15-skey.c +++ b/src/libopensc/pkcs15-skey.c @@ -1,7 +1,7 @@ /* * pkcs15-skey.c: PKCS #15 secret key functions * - * Copyright (C) 2002 Juha Yrjölä + * Copyright (C) 2002 Juha Yrjölä * Copyright (C) 2011 Viktor Tarasov * * This library is free software; you can redistribute it and/or @@ -20,6 +20,7 @@ */ #include "internal.h" #include "pkcs15.h" +#include "pkcs11/pkcs11.h" #include "asn1.h" #include #include @@ -93,7 +94,7 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_skey_info info; - int r, i; + int r, i, ii; size_t usage_len = sizeof(info.usage); size_t af_len = sizeof(info.access_flags); struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE]; @@ -106,6 +107,8 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj struct sc_asn1_pkcs15_object skey_des_obj = { obj, asn1_com_key_attr, asn1_com_skey_attr, asn1_generic_skey_attr }; + static const struct sc_object_id id_aes = { { 2, 16, 840, 1, 101, 3, 4, 1, -1 } }; + struct sc_object_id temp_oid; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_ASN1); @@ -140,13 +143,36 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj /* Fill in defaults */ memset(&info, 0, sizeof(info)); + info.native = 1; r = sc_asn1_decode(ctx, asn1_skey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - if (asn1_skey_choice[0].flags & SC_ASN1_PRESENT) + if (asn1_skey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_SKEY_GENERIC; + + /* info.key_type = CKK_AES;*/ /* defaults to CKK_AES. TODO: implement choice 15 and GenericKeyAttributes like defined in ISO7816-15 and set key type accordingly. */ + + /* Check key type. framework-pkcs15 recognizes one type per key, and AES is the only algorithm supported for + * SKEY_GENERIC type keys, so just check if this key is AES compatible. */ + + for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS && info.algo_refs[i] != 0; i++) { + for (ii = 0; ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo != 0; ii++) { + if (info.algo_refs[i] == p15card->tokeninfo->supported_algos[ii].reference) { + temp_oid = p15card->tokeninfo->supported_algos[ii].algo_id; + temp_oid.value[8] = -1; /* strip off AES subtype octet*/ + + if (sc_compare_oid(&id_aes, &temp_oid)) + if (info.key_type == 0) { + info.key_type = CKK_AES; + break; + } + } + } + } + + } else if (asn1_skey_choice[1].flags & SC_ASN1_PRESENT) obj->type = SC_PKCS15_TYPE_SKEY_DES; else if (asn1_skey_choice[2].flags & SC_ASN1_PRESENT) From 1c09fa8a22d918dc2a0505d0b1eb62b6e079c0b8 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 15:51:48 +0200 Subject: [PATCH 0574/4321] Handle AES algorithm. Doesn't set any flags, but check for AES is needed to avoid SC_ERROR_NOT_SUPPORTED. --- src/libopensc/padding.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 75c92b651a..1cb38b0db9 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -480,12 +480,12 @@ int sc_get_encoding_flags(sc_context_t *ctx, /* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and * ECDSA_HASH_ -> ECDSA_RAW using OpenSSL (not much benefit though). */ + if ((caps & iflags) == iflags) { /* Card supports the signature operation we want to do, great, let's * go with it then. */ *sflags = iflags; *pflags = 0; - } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { *sflags |= SC_ALGORITHM_RSA_PAD_PSS; @@ -505,6 +505,17 @@ int sc_get_encoding_flags(sc_context_t *ctx, *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; *pflags = iflags & SC_ALGORITHM_RSA_HASHES; + } else if ((iflags & SC_ALGORITHM_AES) == SC_ALGORITHM_AES) { /* TODO: seems like this constant does not belong to the same set of flags used form asymmetric algos. Fix this! */ + *sflags = 0; + *pflags = 0; + + } else if ((iflags & SC_ALGORITHM_AES_FLAGS) > 0) { + *sflags = iflags & SC_ALGORITHM_AES_FLAGS; + if (iflags & SC_ALGORITHM_AES_CBC_PAD) + *pflags = SC_ALGORITHM_AES_CBC_PAD; + else + *pflags = 0; + } else { LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported algorithm"); } From 9d6ac01c274d8242d4308e144c11549848e73425 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 15:56:41 +0200 Subject: [PATCH 0575/4321] pkcs15init: Handle user_consent and set new proprietary information flags in myeid_create_key(). --- src/pkcs15init/pkcs15-myeid.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 10258667d0..062d6abc23 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -41,6 +41,11 @@ unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; #define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY) +#define MYEID_PROP_INFO_1_EXCTRACTABLE 0x01; +#define MYEID_PROP_INFO_1_TRUSTED 0x02; +#define MYEID_PROP_INFO_1_WRAP_WITH_TRUSTED 0x04; +#define MYEID_PROP_INFO_2_SESSION_OBJECT 0x08; + /* For Myeid, all objects are files that can be deleted in any order */ static int myeid_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card, @@ -508,6 +513,8 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_auth_info *pkcs15_auth_info = NULL; unsigned char sec_attrs[] = {0xFF, 0xFF, 0xFF}; int r, ef_structure = 0, keybits = 0, pin_reference = -1; + unsigned char prop_info[] = {0x00, 0x00}; + int extractable = FALSE; LOG_FUNC_CALLED(card->ctx); @@ -524,9 +531,13 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, case SC_PKCS15_TYPE_SKEY_3DES: ef_structure = SC_CARDCTL_MYEID_KEY_DES; keybits = skey_info->value_len; + if ((skey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) + extractable = TRUE; break; case SC_PKCS15_TYPE_SKEY_GENERIC: keybits = skey_info->value_len; + if ((skey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) + extractable = TRUE; switch (skey_info->key_type) { case CKM_AES_ECB: ef_structure = SC_CARDCTL_MYEID_KEY_AES; @@ -534,6 +545,10 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, case CKM_DES_ECB: ef_structure = SC_CARDCTL_MYEID_KEY_DES; break; + default: + if (object->type == SC_PKCS15_TYPE_SKEY_GENERIC) + ef_structure = SC_CARDCTL_MYEID_KEY_GENERIC_SECRET; + break; } break; } @@ -605,6 +620,21 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid AuthID value for a private key."); } + /* TODO: fill all proprietary attributes here based on the object */ + + if (object->user_consent != 0 && pin_reference >= 1) + prop_info[0] |= (pin_reference << 4); + + if (extractable) + prop_info[0] |= MYEID_PROP_INFO_1_EXCTRACTABLE; + + if (object->session_object != 0) /* Object will be removed during next reset. */ + prop_info[1] |= MYEID_PROP_INFO_2_SESSION_OBJECT; + + /* TODO: add other flags, like CKA_TRUSTED and CKA_WRAP_WITH_TRUSTED */ + + r = sc_file_set_prop_attr(file, prop_info, 2); + /* Now create the key file */ r = sc_pkcs15init_create_file(profile, p15card, file); sc_file_free(file); From edd48b32006bc3a8f716a693025e579a55ac5f27 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 16:09:36 +0200 Subject: [PATCH 0576/4321] pkcs15init: - Added session_object flag to sc_pkcs15init_skeyargs to enable on-card session objects. - Corrections to handling native and extractable flags - Allow creating an empty secret key EF for receiving an unwrapped key later. --- src/pkcs15init/pkcs15-init.h | 3 ++- src/pkcs15init/pkcs15-lib.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 011485487b..08beaac12d 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -274,7 +274,8 @@ struct sc_pkcs15init_skeyargs { unsigned int access_flags; unsigned long algorithm; /* User requested algorithm */ unsigned long value_len; /* User requested length */ - + int session_object; /* If nonzero. this is a session object, which will + be cleared from card when the session is closed.*/ struct sc_pkcs15_skey key; }; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index cc9d26e969..d706a82173 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1345,9 +1345,15 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi if (keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) { key_info->access_flags &= ~SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; - key_info->native = 0; + /* The following commented out. I interpret PKCS#15 so that native only means that a key + * can be used in on card crypto. Such key can be extractable (can be wrapped), so IMO this + logic is not correct. */ + /* key_info->native = 0; */ } + if (keyargs->session_object > 0) + object->session_object = 1; + /* Select a Key ID if the user didn't specify one, * otherwise make sure it's compatible with our intended use */ r = select_id(p15card, SC_PKCS15_TYPE_SKEY, &keyargs->id); From c217b254fc4a12383afeacaa81161f40dee4daeb Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 16:10:50 +0200 Subject: [PATCH 0577/4321] MyEID: Initial implementation of key wrapping and unwrapping operations, and the related additions to myeid_set_security_env. --- src/libopensc/card-myeid.c | 158 ++++++++++++++++++++++++++++++++----- 1 file changed, 140 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index cc36b9bfad..1f9cead2e2 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -486,10 +486,13 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, /* Proprietary Information */ buf[18] = 0x85; buf[19] = 0x02; - /* AC right to clear default 0 */ - /* TODO: Implement this */ - buf[20] = 0x00; /*(SC_FILE_TYPE_INTERNAL_EF == file->type ? 0x00 : 0x80);*/ - buf[21] = 0x00; + if (file->prop_attr_len == 2 && file->prop_attr != NULL) + memcpy(&buf[20], file->prop_attr, 2); + else + { + buf[20] = 0x00; + buf[21] = 0x00; + } /* Life Cycle Status tag */ buf[22] = 0x8A; @@ -663,7 +666,13 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * *p++ = 1; *p++ = 0; } - /* TODO: handle SC_SEC_ENV_TARGET_FILE_REF_PRESENT, if this is an unwrapping operation. */ + if (env->flags & SC_SEC_ENV_TARGET_FILE_REF_PRESENT) + { + *p++ = 0x83; + *p++ = 2; + memcpy(p, env->target_file_ref.value, 2); + p+= 2; + } r = p - sbuf; apdu.lc = r; apdu.datalen = r; @@ -799,13 +808,20 @@ static int myeid_set_security_env(struct sc_card *card, if (tmp.algorithm == SC_ALGORITHM_RSA) { - tmp.algorithm_ref = 0x00; - /* potential FIXME: return an error, if an unsupported - * pad or hash was requested, although this shouldn't happen */ - if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) - tmp.algorithm_ref = 0x02; - if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) - tmp.algorithm_ref |= 0x10; + if (tmp.operation == SC_SEC_OPERATION_UNWRAP || tmp.operation == SC_SEC_OPERATION_WRAP) + { + tmp.algorithm_ref = 0x0A; + } + else + { + tmp.algorithm_ref = 0x00; + /* potential FIXME: return an error, if an unsupported + * pad or hash was requested, although this shouldn't happen */ + if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) + tmp.algorithm_ref = 0x02; + if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) + tmp.algorithm_ref |= 0x10; + } return myeid_set_security_env_rsa(card, &tmp, se_num); } @@ -815,6 +831,19 @@ static int myeid_set_security_env(struct sc_card *card, tmp.algorithm_flags = 0; return myeid_set_security_env_ec(card, &tmp, se_num); } + else if (tmp.algorithm == SC_ALGORITHM_AES) + { + if (tmp.operation == SC_SEC_OPERATION_UNWRAP || tmp.operation == SC_SEC_OPERATION_WRAP) + { + tmp.algorithm_ref = 0x0A; + } + else + { + tmp.algorithm_ref = 0x00; + } + /* from this point, there's no difference to RSA SE */ + return myeid_set_security_env_rsa(card, env, se_num); + } else { @@ -1195,10 +1224,34 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) { + struct sc_context *ctx; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - LOG_FUNC_CALLED(card->ctx); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + assert(card != NULL && out != NULL); + ctx = card->ctx; + LOG_FUNC_CALLED(ctx); + + /* INS: 0x2A PERFORM SECURITY OPERATION + P1: 0x84 Resp: Return a cryptogram + * P2: 0x00 The data field is absent */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x84, 0x00); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = outlen; + apdu.lc = 0; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(ctx, r, "compute_signature failed"); + + if (apdu.resplen > outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + + memcpy(out, apdu.resp, apdu.resplen); + LOG_FUNC_RETURN(ctx, apdu.resplen); } static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len) @@ -1206,15 +1259,84 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra int r; u8 out[512]; size_t outlen = 512; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; LOG_FUNC_CALLED(card->ctx); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + + assert(card != NULL && crgram != NULL && out != NULL); - /* Emulate unwrapping with decipher */ - r = myeid_decipher(card, crgram, crgram_len, out, outlen); + if (crgram_len > 256) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - LOG_FUNC_RETURN(card->ctx, r); + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x80 Resp: Plain value + * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ + sc_format_apdu(card, &apdu, + (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, + 0x2A, 0x80, 0x86); + + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = crgram_len; - /*LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); */ + if (crgram_len == 256) + { + apdu.le = 0; + /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ + sbuf[0] = 0x81; + memcpy(sbuf + 1, crgram, crgram_len / 2); + apdu.lc = crgram_len / 2 + 1; + } + else + { + sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ + memcpy(sbuf + 1, crgram, crgram_len); + apdu.lc = crgram_len + 1; + } + + apdu.datalen = apdu.lc; + apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + if (crgram_len == 256) + { + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, + 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = crgram_len; + /* padding indicator byte, + * 0x82 = Second half of 2048 bit cryptogram */ + sbuf[0] = 0x82; + memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); + apdu.lc = crgram_len / 2 + 1; + apdu.datalen = apdu.lc; + apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + LOG_FUNC_RETURN(card->ctx, r); + } + } + else + { + int len = apdu.resplen > outlen ? outlen : apdu.resplen; + + memcpy(out, apdu.resp, len); + LOG_FUNC_RETURN(card->ctx, r); + } + } + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } From a9ee85452ef140c206d7428e5260060321440367 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 11 Jun 2018 23:13:23 -0700 Subject: [PATCH 0578/4321] Resolved a merge conflict. Included both changes manually. --- src/libopensc/pkcs15-sec.c | 194 +++++++++++++++++++++++++++++++------ 1 file changed, 166 insertions(+), 28 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 80f6ca5d1d..85b705bd8f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -32,17 +32,39 @@ #include "internal.h" #include "pkcs15.h" +#include "pkcs11/pkcs11.h" + +static sc_path_t get_file_path(const struct sc_pkcs15_object* obj) +{ + sc_path_t path; + const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data; + const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data; + + memset (&path, 0, sizeof(path)); + + if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) { + path = prkey->path; + } + else if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) { + path = skey->path; + } + + return path; +} + static int select_key_file(struct sc_pkcs15_card *p15card, - const struct sc_pkcs15_prkey_info *prkey, + const struct sc_pkcs15_object *key, sc_security_env_t *senv) { sc_context_t *ctx = p15card->card->ctx; + sc_path_t orig_path; sc_path_t path, file_id; int r; LOG_FUNC_CALLED(ctx); + orig_path = get_file_path(key); memset(&path, 0, sizeof(sc_path_t)); memset(&file_id, 0, sizeof(sc_path_t)); @@ -50,21 +72,21 @@ static int select_key_file(struct sc_pkcs15_card *p15card, * Check validity of the following assumption. */ /* For pkcs15-emulated cards, the file_app may be NULL, * in that case we always assume an absolute path */ - if (!prkey->path.len && prkey->path.aid.len) { + if (!orig_path.len && orig_path.aid.len) { /* Private key is a SDO allocated in application DF */ - path = prkey->path; + path = orig_path; } - else if (prkey->path.len == 2 && p15card->file_app != NULL) { + else if (orig_path.len == 2 && p15card->file_app != NULL) { /* Path is relative to app. DF */ path = p15card->file_app->path; - file_id = prkey->path; + file_id = orig_path; sc_append_path(&path, &file_id); senv->file_ref = file_id; senv->flags |= SC_SEC_ENV_FILE_REF_PRESENT; } - else if (prkey->path.len > 2) { - path = prkey->path; - memcpy(file_id.value, prkey->path.value + prkey->path.len - 2, 2); + else if (orig_path.len > 2) { + path = orig_path; + memcpy(file_id.value, orig_path.value + orig_path.len - 2, 2); file_id.len = 2; file_id.type = SC_PATH_TYPE_FILE_ID; senv->file_ref = file_id; @@ -90,14 +112,14 @@ static int use_key(struct sc_pkcs15_card *p15card, { int r = SC_SUCCESS; int revalidated_cached_pin = 0; - const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data; + sc_path_t path = get_file_path(obj); r = sc_lock(p15card->card); LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed"); do { - if (prkey->path.len != 0 || prkey->path.aid.len != 0) { - r = select_key_file(p15card, prkey, senv); + if (path.len != 0 || path.aid.len != 0) { + r = select_key_file(p15card, obj, senv); if (r < 0) { sc_log(p15card->card->ctx, "Unable to select private key file"); @@ -131,6 +153,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, { sc_context_t *ctx = p15card->card->ctx; const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data; + const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data; memset(senv_out, 0, sizeof(*senv_out)); @@ -138,8 +161,8 @@ static int format_senv(struct sc_pkcs15_card *p15card, * it can get value of card specific 'AlgorithmInfo::algRef'. */ memcpy(senv_out->supported_algos, &p15card->tokeninfo->supported_algos, sizeof(senv_out->supported_algos)); - if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) - LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This is not a private key"); + if (!((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY || (obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This is not a private or secret key"); /* If the key is not native, we can't operate with it. */ if (!prkey->native) @@ -181,6 +204,19 @@ static int format_senv(struct sc_pkcs15_card *p15card, senv_out->flags |= SC_SEC_ENV_ALG_REF_PRESENT; senv_out->algorithm_ref = prkey->field_length; break; + case SC_PKCS15_TYPE_SKEY_GENERIC: + if (obj->type == SC_PKCS15_TYPE_SKEY_GENERIC && skey->key_type != CKK_AES) + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported"); + *alg_info_out = sc_card_find_alg(p15card->card, SC_ALGORITHM_AES, + skey->value_len, NULL); + if (*alg_info_out == NULL) { + sc_log(ctx, + "Card does not support AES with key length %"SC_FORMAT_LEN_SIZE_T"u", + skey->value_len); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + } + senv_out->algorithm = SC_ALGORITHM_AES; + break; /* add other crypto types here */ default: LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported"); @@ -196,7 +232,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, return SC_SUCCESS; } - + int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj, unsigned long flags, @@ -210,7 +246,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, unsigned long pad_flags = 0, sec_flags = 0; LOG_FUNC_CALLED(ctx); - + if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP))) LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for decryption"); @@ -297,7 +333,6 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, r); } - /* * Unwrap a key into a key object on card. * in holds the wrapped key data @@ -314,7 +349,8 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, int r; sc_algorithm_info_t *alg_info = NULL; sc_security_env_t senv; - const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) key->data; + const struct sc_pkcs15_prkey_info *src_prkey = (const struct sc_pkcs15_prkey_info *) key->data; + const struct sc_pkcs15_skey_info *src_skey = (const struct sc_pkcs15_skey_info *) key->data; const struct sc_pkcs15_skey_info *tkey = (const struct sc_pkcs15_skey_info *) target_key->data; unsigned long pad_flags = 0, sec_flags = 0; u8 *out = 0; @@ -323,13 +359,16 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_FUNC_CALLED(ctx); - if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP))) - LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping"); - - if (!(key->type == SC_PKCS15_TYPE_PRKEY_RSA || - (key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) { - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,"Key type not supported"); + if (key->type == SC_PKCS15_TYPE_PRKEY_RSA) { + if (!(src_prkey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP))) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping"); } + else if ((key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) { + if (!(src_skey->usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP))) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for unwrapping"); + } + else + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported"); r = format_senv(p15card, key, &senv, &alg_info); LOG_TEST_RET(ctx, r, "Could not initialize security environment"); @@ -362,19 +401,118 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); } + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); + LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); + senv.algorithm_flags = sec_flags; + + r = use_key(p15card, key, &senv, sc_unwrap, in, inlen, out, + poutlen); + LOG_TEST_RET(ctx, r, "use_key() failed"); + LOG_FUNC_RETURN(ctx, r); +} + +/* + * Wrap a key and return a cryptogram + * is the wrapping key + * is the key to be wrapped + * wrapped data is returned in + */ +int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *key, + struct sc_pkcs15_object *target_key, + unsigned long flags, + u8 * cryptogram, size_t* crgram_len) { + sc_context_t *ctx = p15card->card->ctx; + int r; + sc_algorithm_info_t *alg_info = NULL; + sc_security_env_t senv; + const struct sc_pkcs15_prkey_info *src_prkey = (const struct sc_pkcs15_prkey_info *) key->data; + const struct sc_pkcs15_skey_info *src_skey = (const struct sc_pkcs15_skey_info *) key->data; + const struct sc_pkcs15_prkey_info *target_prkey = (const struct sc_pkcs15_prkey_info *) target_key->data; + const struct sc_pkcs15_skey_info *target_skey = (const struct sc_pkcs15_skey_info *) target_key->data; + unsigned long pad_flags = 0, sec_flags = 0; + sc_path_t tkey_path; + u8 *in = 0; + u8 *out = 0; + size_t *poutlen = 0, inlen = 0; + sc_path_t path, target_file_id; + + LOG_FUNC_CALLED(ctx); + + switch (key->type) { + case SC_PKCS15_TYPE_PRKEY_RSA: + if (!(src_prkey->usage & (SC_PKCS15_PRKEY_USAGE_WRAP))) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for wrapping"); + break; + case SC_PKCS15_TYPE_SKEY_DES: + case SC_PKCS15_TYPE_SKEY_3DES: + case SC_PKCS15_TYPE_SKEY_GENERIC: + if (!(src_skey->usage & (SC_PKCS15_PRKEY_USAGE_WRAP))) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for wrapping"); + break; + default: + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Wrapping key type not supported"); + } + + if (!(target_key->type == SC_PKCS15_TYPE_PRKEY_RSA || + (key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) { + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Target key type not supported"); + } + + r = format_senv(p15card, key, &senv, &alg_info); + LOG_TEST_RET(ctx, r, "Could not initialize security environment"); + senv.operation = SC_SEC_OPERATION_WRAP; + + memset(&path, 0, sizeof (sc_path_t)); + memset(&target_file_id, 0, sizeof (sc_path_t)); + + switch (target_key->type) { + case SC_PKCS15_TYPE_PRKEY_RSA: + tkey_path = target_prkey->path; + break; + default: /* we already know it is a secret key */ + tkey_path = target_skey->path; + break; + } + + if (!path.len && path.aid.len) { + /* Target key is a SDO allocated in application DF */ + path = tkey_path; + } else if (tkey_path.len == 2 && p15card->file_app != NULL) { + /* Path is relative to app. DF */ + path = p15card->file_app->path; + target_file_id = tkey_path; + sc_append_path(&path, &target_file_id); + senv.target_file_ref = target_file_id; + senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + } else if (tkey_path.len > 2) { + path = tkey_path; + memcpy(target_file_id.value, tkey_path.value + tkey_path.len - 2, 2); + target_file_id.len = 2; + target_file_id.type = SC_PATH_TYPE_FILE_ID; + senv.target_file_ref = target_file_id; + senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + } + else { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); + } r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; - r = use_key(p15card, key, &senv, sc_unwrap, in, inlen, out, - poutlen); + out = cryptogram; + poutlen = crgram_len; + r = use_key(p15card, key, &senv, sc_wrap, in, inlen, out, + *poutlen); + /* TODO: handle SC_ERROR_BUFFER_TOO_SMALL, return size in *poutlen */ LOG_TEST_RET(ctx, r, "use_key() failed"); LOG_FUNC_RETURN(ctx, r); } + /* copied from pkcs15-cardos.c */ #define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\ SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) @@ -428,7 +566,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* revert data to sign when signing with the GOST key. * TODO: can it be confirmed by the GOST standard? * TODO: tested with RuTokenECP, has to be validated for RuToken. */ - if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) { + if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) { r = sc_mem_reverse(buf, inlen); LOG_TEST_RET(ctx, r, "Reverse memory error"); } @@ -449,7 +587,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, (prkey->usage & USAGE_ANY_DECIPHER)) ) { size_t tmplen = sizeof(buf); if (flags & SC_ALGORITHM_RSA_RAW) { - r = sc_pkcs15_decipher(p15card, obj,flags, in, inlen, out, outlen); + r = sc_pkcs15_decipher(p15card, obj, flags, in, inlen, out, outlen); LOG_FUNC_RETURN(ctx, r); } if (modlen > tmplen) @@ -465,7 +603,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, r, "Unable to add padding"); - r = sc_pkcs15_decipher(p15card, obj,flags, buf, modlen, out, outlen); + r = sc_pkcs15_decipher(p15card, obj, flags, buf, modlen, out, outlen); LOG_FUNC_RETURN(ctx, r); } From aa814fd8e80d57951ae91871e70822e4fe1e27cf Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 17 Nov 2017 16:15:12 +0200 Subject: [PATCH 0579/4321] Implemented C_Wrap into PKCS#11 interface. Added support for wrapping and unwrapping with secret keys into framework-pkcs15.c and all the way to the card driver level. --- src/libopensc/card.c | 2 +- src/libopensc/cardctl.h | 3 +- src/libopensc/libopensc.exports | 1 + src/libopensc/opensc.h | 11 +- src/libopensc/pkcs15.h | 9 +- src/libopensc/sec.c | 15 +++ src/pkcs11/framework-pkcs15.c | 225 ++++++++++++++++++++++++++++++-- src/pkcs11/mechanism.c | 71 ++++++++-- src/pkcs11/pkcs11-object.c | 68 +++++++++- src/pkcs11/sc-pkcs11.h | 3 +- 10 files changed, 380 insertions(+), 28 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index b4ab23954b..69e2eb7952 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1016,7 +1016,7 @@ int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length, return _sc_card_add_algorithm(card, &info); } -static sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, +sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, unsigned int algorithm, unsigned int key_length, void *param) { int i; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index b32ab50214..0cf5a9d55f 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -883,7 +883,8 @@ typedef struct sc_rtecp_genkey_data { SC_CARDCTL_MYEID_KEY_RSA = 0x11, SC_CARDCTL_MYEID_KEY_DES = 0x19, SC_CARDCTL_MYEID_KEY_EC = 0x22, - SC_CARDCTL_MYEID_KEY_AES = 0x29 + SC_CARDCTL_MYEID_KEY_AES = 0x29, + SC_CARDCTL_MYEID_KEY_GENERIC_SECRET = 0x41 }; struct sc_cardctl_myeid_data_obj { diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index a40e471583..1c770afebb 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -238,6 +238,7 @@ sc_pkcs15_search_objects sc_pkcs15_unbind sc_pkcs15_unblock_pin sc_pkcs15_unwrap +sc_pkcs15_wrap sc_pkcs15_verify_pin sc_pkcs15_get_pin_info sc_pkcs15_verify_pin_with_session_pin diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index f512add325..7c17b4adfa 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1211,8 +1211,6 @@ int sc_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen); int sc_compute_signature(struct sc_card *card, const u8 * data, size_t data_len, u8 * out, size_t outlen); -int sc_unwrap(struct sc_card *card, const u8 * data, - size_t data_len, u8 * out, size_t outlen); int sc_verify(struct sc_card *card, unsigned int type, int ref, const u8 *buf, size_t buflen, int *tries_left); /** @@ -1265,6 +1263,13 @@ int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr, int sc_file_set_content(sc_file_t *file, const u8 *content, size_t content_len); +/********************************************************************/ +/* Key wrapping and unwrapping */ +/********************************************************************/ +int sc_unwrap(struct sc_card *card, const u8 * data, + size_t data_len, u8 * out, size_t outlen); +int sc_wrap(struct sc_card *card, const u8 * data, + size_t data_len, u8 * out, size_t outlen); /********************************************************************/ /* sc_path_t handling functions */ @@ -1413,6 +1418,8 @@ struct sc_algorithm_info * sc_card_find_ec_alg(struct sc_card *card, unsigned int field_length, struct sc_object_id *curve_oid); struct sc_algorithm_info * sc_card_find_gostr3410_alg(struct sc_card *card, unsigned int key_length); +struct sc_algorithm_info * sc_card_find_alg(sc_card_t *card, + unsigned int algorithm, unsigned int key_length, void *param); scconf_block *sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr *atr); /** diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index b4890a9e1d..cdfb5c5614 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -452,7 +452,6 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t; #define SC_PKCS15_TYPE_SKEY_DES 0x302 #define SC_PKCS15_TYPE_SKEY_2DES 0x303 #define SC_PKCS15_TYPE_SKEY_3DES 0x304 -#define SC_PKCS15_TYPE_SKEY_AES 0x305 #define SC_PKCS15_TYPE_CERT 0x400 #define SC_PKCS15_TYPE_CERT_X509 0x401 @@ -494,6 +493,8 @@ struct sc_pkcs15_object { struct sc_pkcs15_object *next, *prev; /* used only internally */ struct sc_pkcs15_der content; + + int session_object; /* used internally. if nonzero, object is a session object. */ }; typedef struct sc_pkcs15_object sc_pkcs15_object_t; @@ -667,6 +668,12 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, unsigned long flags, const u8 * in, size_t inlen); +int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *key, + struct sc_pkcs15_object *target_key, + unsigned long flags, + u8 * cryptogram, size_t* crgram_len); + int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, unsigned long alg_flags, const u8 *in, diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 84eb0ce72f..e2ea41a807 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -78,6 +78,21 @@ int sc_unwrap(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } +int sc_wrap(sc_card_t *card, + const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) +{ + int r; + + if (card == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + if (card->ops->wrap == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + r = card->ops->wrap(card, out, outlen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + int sc_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index bbca3c6cc8..65648cd65b 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -131,6 +131,8 @@ struct pkcs15_skey_object { struct sc_pkcs15_skey *valueXXXX; }; +#define is_secret_key(obj) ((__p15_type(obj) & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) + #define skey_flags base.base.flags #define skey_p15obj base.p15_object #define is_skey(obj) ((__p15_type(obj) & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY_OBJECT) @@ -1186,6 +1188,11 @@ _pkcs15_create_typed_objects(struct pkcs15_fw_data *fw_data) if (rv < 0) return rv; + rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_SKEY_GENERIC, "Generic secret key", + __pkcs15_create_secret_key_object); + if (rv < 0) + return rv; + /* Match up related keys and certificates */ pkcs15_bind_related_objects(fw_data); sc_log(context, "found %i FW objects", fw_data->num_objects); @@ -1341,6 +1348,10 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p sc_log(context, "Slot:%p Adding cert object %d to PIN '%.*s'", slot, i, (int) sizeof pin_obj->label, pin_obj->label); pkcs15_add_object(slot, obj, NULL); } + else if (is_secret_key(obj)) { + sc_log(context, "Slot:%p Adding secret key object %d to PIN '%.*s'", slot, i, (int) sizeof pin_obj->label, pin_obj->label); + pkcs15_add_object(slot, obj, NULL); + } else { sc_log(context, "Slot:%p Object %d skipped", slot, i); continue; @@ -2232,7 +2243,6 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile args.auth_id = pin->auth_id; switch (key_type) { - /* Only support GENERIC_SECRET for now */ case CKK_GENERIC_SECRET: case CKK_AES: args.algorithm = SC_ALGORITHM_AES; @@ -2334,6 +2344,9 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile args.key.data = NULL; } else { + if(_token == FALSE) + args.session_object = 1; /* store the object on card for duration of the session. */ + rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); @@ -3925,13 +3938,11 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, void *targetKey) -/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttributesLen, - void ** pUnwrappedKey)*/ { struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; - struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; + struct pkcs15_any_object *targetKeyObj = (struct pkcs15_any_object *) targetKey; int rv, flags = 0; sc_log(context, "Initiating unwrapping with private key."); @@ -3971,7 +3982,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(rv, "C_UnwrapKey"); /* Call the card to do the unwrap operation */ - rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->prv_p15obj, 0, + rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->p15_object, 0, pWrappedKey, ulWrappedKeyLen); sc_unlock(p11card->card); @@ -3982,7 +3993,6 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, return CKR_OK; } - static CK_RV pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, CK_MECHANISM_PTR pMechanism, @@ -4779,6 +4789,12 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, check_attribute_buffer(attr, skey->info->id.len); memcpy(attr->pValue, skey->info->id.value, skey->info->id.len); break; + case CKA_EXTRACTABLE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = (((skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) + && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0 + && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0); + break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); *(CK_ULONG*)attr->pValue = skey->info->data.len; @@ -4794,6 +4810,138 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, return CKR_OK; } +static CK_RV +pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, + CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + void *targetKey) +{ + struct sc_pkcs11_card *p11card = session->slot->p11card; + struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *) obj; + struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; + int rv, flags = 0; + + sc_log(context, "Initiating unwrapping with a secret key."); + + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); + + sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj, + pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj); + + if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) + return CKR_ARGUMENTS_BAD; + + /* Check whether this key supports unwrap */ + if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP)) + skey = NULL; + + /* TODO: should we look for a compatible key automatically? prv_next not implemented yet. */ + /* skey = skey->prv_next; */ + + if (skey == NULL) + return CKR_KEY_FUNCTION_NOT_PERMITTED; + + /* Select the proper padding mechanism */ + switch (pMechanism->mechanism) { + case CKM_AES_ECB: + flags |= SC_ALGORITHM_AES; /* TODO: may need to define separate constants for ECB and CBC in opensc.h */ + break; + case CKM_AES_CBC: + flags |= SC_ALGORITHM_AES; + break; + default: + return CKR_MECHANISM_INVALID; + } + + rv = sc_lock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + /* Call the card to do the unwrap operation */ + rv = sc_pkcs15_unwrap(fw_data->p15_card, skey->prv_p15obj, targetKeyObj->prv_p15obj, flags, + pWrappedKey, ulWrappedKeyLen); + + sc_unlock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + return CKR_OK; +} + +/* + * Wrap a key using a secret key. obj = wrapping key, targetKey = key to be wrapped. + * Wrapped key data is returned in pData + */ + +static CK_RV +pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, + CK_MECHANISM_PTR pMechanism, + void *targetKey, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) + +{ + struct sc_pkcs11_card *p11card = session->slot->p11card; + struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *) obj; + struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; + int rv, flags = 0; + + sc_log(context, "Initializing wrapping with a secret key."); + + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; + + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_WrapKey"); + + sc_log(context, "wrapping %p %p %p %p %p %p, %lu", session, obj, + pMechanism, targetKey, pData, pulDataLen, pulDataLen == NULL ? 0 : *pulDataLen); + + if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL) + return CKR_ARGUMENTS_BAD; + + /* Verify that the key supports wrapping */ + if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_WRAP)) + skey = NULL; + /* TODO: browse for a key that supports, like other similar funcs */ + + + if (skey == NULL) + return CKR_KEY_FUNCTION_NOT_PERMITTED; + + /* Select the proper padding mechanism */ + switch (pMechanism->mechanism) { + case CKM_AES_ECB: + flags |= SC_ALGORITHM_AES; /* TODO: may need to define separate constants for ECB and CBC in opensc.h */ + break; + case CKM_AES_CBC: + flags |= SC_ALGORITHM_AES; + break; + default: + return CKR_MECHANISM_INVALID; + } + + rv = sc_lock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + /* Call the card to do the wrapping operation */ + rv = sc_pkcs15_wrap(fw_data->p15_card, skey->prv_p15obj, targetKeyObj->prv_p15obj, flags, + pData, pulDataLen); + + sc_unlock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_UnwrapKey"); + + return CKR_OK; +} + /* * Secret key objects, currently used only to retrieve derived session key @@ -4806,7 +4954,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { pkcs15_skey_destroy, NULL, /* get_size */ NULL, /* sign */ - NULL, /* unwrap_key */ + pkcs15_skey_unwrap, NULL, /* decrypt */ NULL, /* derive */ NULL, /* can_do */ @@ -5136,6 +5284,47 @@ static int register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, return CKR_OK; } +static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int flags, + CK_ULONG min_key_size, CK_ULONG max_key_size) +{ + int rc; + CK_MECHANISM_INFO mech_info; + sc_pkcs11_mechanism_type_t *mt; + sc_card_t* card = p11card->card; + memset(&mech_info, 0, sizeof(mech_info)); + mech_info.flags = CKF_ENCRYPT | CKF_DECRYPT; + mech_info.ulMinKeySize = min_key_size; + mech_info.ulMaxKeySize = max_key_size; + + if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY) + mech_info.flags |= CKF_UNWRAP; + if ((card->caps & SC_CARD_CAP_WRAP_KEY) == SC_CARD_CAP_WRAP_KEY) + mech_info.flags |= CKF_WRAP; + + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_ECB, &mech_info, CKK_AES, NULL, NULL); + if (!mt) + return CKR_HOST_MEMORY; + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC, &mech_info, CKK_AES, NULL, NULL); + if (!mt) + return CKR_HOST_MEMORY; + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC_PAD, &mech_info, CKK_AES, NULL, NULL); + if (!mt) + return CKR_HOST_MEMORY; + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + + return CKR_OK; +} + /* * Mechanism handling * FIXME: We should consult the card's algorithm list to @@ -5147,11 +5336,12 @@ register_mechanisms(struct sc_pkcs11_card *p11card) sc_card_t *card = p11card->card; sc_algorithm_info_t *alg_info; CK_MECHANISM_INFO mech_info; - CK_ULONG ec_min_key_size, ec_max_key_size; + CK_ULONG ec_min_key_size, ec_max_key_size, + aes_min_key_size, aes_max_key_size; unsigned long ec_ext_flags; sc_pkcs11_mechanism_type_t *mt; unsigned int num; - int rc, rsa_flags = 0, ec_flags = 0, gostr_flags = 0; + int rc, rsa_flags = 0, ec_flags = 0, gostr_flags = 0, aes_flags = 0; /* Register generic mechanisms */ sc_pkcs11_register_generic_mechanisms(p11card); @@ -5163,11 +5353,16 @@ register_mechanisms(struct sc_pkcs11_card *p11card) #endif if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY) mech_info.flags |= CKF_UNWRAP; + if ((card->caps & SC_CARD_CAP_WRAP_KEY) == SC_CARD_CAP_WRAP_KEY) + mech_info.flags |= CKF_WRAP; mech_info.ulMinKeySize = ~0; mech_info.ulMaxKeySize = 0; ec_min_key_size = ~0; ec_max_key_size = 0; + aes_min_key_size = ~0; + aes_max_key_size = 0; + ec_ext_flags = 0; /* For now, we just OR all the algorithm specific @@ -5195,6 +5390,13 @@ register_mechanisms(struct sc_pkcs11_card *p11card) case SC_ALGORITHM_GOSTR3410: gostr_flags |= alg_info->flags; break; + case SC_ALGORITHM_AES: + aes_flags |= alg_info->flags; + if (alg_info->key_length < aes_min_key_size) + aes_min_key_size = alg_info->key_length; + if (alg_info->key_length > aes_max_key_size) + aes_max_key_size = alg_info->key_length; + break; } alg_info++; } @@ -5343,6 +5545,11 @@ register_mechanisms(struct sc_pkcs11_card *p11card) return rc; } + if (aes_max_key_size > 0) { + rc = sc_pkcs11_register_aes_mechanisms(p11card, aes_flags, aes_min_key_size, aes_max_key_size); + } + + return CKR_OK; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 45d6fb1511..1ff2a96146 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -830,6 +830,49 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session, return rv; } +CK_RV +sc_pkcs11_wrap(struct sc_pkcs11_session *session, + CK_MECHANISM_PTR pMechanism, + struct sc_pkcs11_object *wrappingKey, /* wrapping key */ + CK_KEY_TYPE key_type, /* type of the wrapping key */ + struct sc_pkcs11_object *targetKey, /* the key to be wrapped */ + CK_BYTE_PTR wrappedData, + CK_ULONG_PTR wrappedDataLen) +{ + struct sc_pkcs11_card *p11card; + sc_pkcs11_operation_t *operation; + sc_pkcs11_mechanism_type_t *mt; + CK_RV rv; + + if (!session || !session->slot + || !(p11card = session->slot->p11card)) + return CKR_ARGUMENTS_BAD; + + /* See if we support this mechanism type */ + mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_UNWRAP); + if (mt == NULL) + return CKR_MECHANISM_INVALID; + + /* See if compatible with key type */ + /* TODO: what if there are several mechanisms with different key types? Should we loop through them? */ + if (mt->key_type != key_type) + return CKR_KEY_TYPE_INCONSISTENT; + + rv = session_start_operation(session, SC_PKCS11_OPERATION_WRAP, mt, &operation); + if (rv != CKR_OK) + return rv; + + memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); + + rv = operation->type->wrap(operation, wrappingKey, + targetKey, wrappedData, + wrappedDataLen); + + session_stop_operation(session, SC_PKCS11_OPERATION_UNWRAP); + + return rv; +} + /* * Unwrap a wrapped key into card. A new key object is created on card. */ @@ -838,7 +881,6 @@ sc_pkcs11_unwrap(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *unwrappingKey, CK_KEY_TYPE key_type, /* type of the unwrapping key */ - CK_SESSION_HANDLE hSession, CK_BYTE_PTR pWrappedKey, /* the wrapped key */ CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key */ struct sc_pkcs11_object *targetKey) @@ -871,7 +913,7 @@ sc_pkcs11_unwrap(struct sc_pkcs11_session *session, /* - * TODO: does it make sense to support unwrapping to a in memory key object? + * TODO: does it make sense to support unwrapping to an in memory key object? * This implementation assumes that the key should be unwrapped into a * key object on card, regardless whether CKA_TOKEN = FALSE * CKA_TOKEN = FALSE is considered an on card session object. @@ -1049,26 +1091,30 @@ sc_pkcs11_derive(sc_pkcs11_operation_t *operation, } +static CK_RV +sc_pkcs11_wrap_operation(sc_pkcs11_operation_t *operation, + struct sc_pkcs11_object *wrappingKey, + struct sc_pkcs11_object *targetKey, + CK_BYTE_PTR pWrappedData, CK_ULONG_PTR ulWrappedDataLen) +{ + return wrappingKey->ops->wrap_key(operation->session, + wrappingKey, + &operation->mechanism, + targetKey, pWrappedData, + ulWrappedDataLen); +} + static CK_RV sc_pkcs11_unwrap_operation(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *unwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, struct sc_pkcs11_object *targetKey) -/* CK_ATTRIBUTE_PTR pAttributes, CK_ULONG ulAttresLen, - void** phUnwrappedKey)*/ { return unwrappingKey->ops->unwrap_key(operation->session, unwrappingKey, &operation->mechanism, pWrappedKey, ulWrappedKeyLen, targetKey); - - /*return unwrappingKey->ops->unwrap_key(operation->session, - unwrappingKey, - &operation->mechanism, - pmechParam, ulmechParamLen, - pAttributes, ulAttresLen, - phUnwrappedKey);*/ } /* @@ -1107,6 +1153,9 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, mt->verif_final = sc_pkcs11_verify_final; #endif } + if (pInfo->flags & CKF_WRAP) { + mt->wrap = sc_pkcs11_wrap_operation; + } if (pInfo->flags & CKF_UNWRAP) { mt->unwrap = sc_pkcs11_unwrap_operation; } diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 65fc8a9322..82e65caac3 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1039,7 +1039,71 @@ CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pWrappedKey, /* receives the wrapped key */ CK_ULONG_PTR pulWrappedKeyLen) { /* receives byte size of wrapped key */ - return CKR_FUNCTION_NOT_SUPPORTED; + CK_RV rv; + CK_BBOOL can_wrap, + can_be_wrapped; + CK_KEY_TYPE key_type; + CK_ATTRIBUTE wrap_attribute = { CKA_WRAP, &can_wrap, sizeof(can_wrap) }; + CK_ATTRIBUTE extractable_attribute = { CKA_EXTRACTABLE, &can_be_wrapped, sizeof(can_be_wrapped) }; + CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; + struct sc_pkcs11_session *session; + struct sc_pkcs11_object *wrapping_object; + struct sc_pkcs11_object *key_object; + + if (pMechanism == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + /* Check if the wrapping key is OK to do wrapping */ + rv = get_object_from_session(hSession, hWrappingKey, &session, &wrapping_object); + if (rv != CKR_OK) { + if (rv == CKR_OBJECT_HANDLE_INVALID) + rv = CKR_KEY_HANDLE_INVALID; + goto out; + } + if (wrapping_object->ops->wrap_key == NULL_PTR) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + rv = wrapping_object->ops->get_attribute(session, wrapping_object, &wrap_attribute); + if (rv != CKR_OK || !can_wrap) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + rv = wrapping_object->ops->get_attribute(session, wrapping_object, &key_type_attr); + if (rv != CKR_OK) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + /* Check if the key to be wrapped exists and is extractable*/ + rv = get_object_from_session(hSession, hKey, &session, &key_object); + if (rv != CKR_OK) { + if (rv == CKR_OBJECT_HANDLE_INVALID) + rv = CKR_KEY_HANDLE_INVALID; + goto out; + } + + rv = key_object->ops->get_attribute(session, key_object, &extractable_attribute); + if (rv != CKR_OK || !can_be_wrapped) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + rv = restore_login_state(session->slot); + if (rv == CKR_OK) + rv = sc_pkcs11_wrap(session, pMechanism, wrapping_object, key_type, + key_object, pWrappedKey, pulWrappedKeyLen); + + rv = reset_login_state(session->slot, rv); + +out: + sc_pkcs11_unlock(); + return rv; } CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ @@ -1105,7 +1169,7 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = restore_login_state(session->slot); if (rv == CKR_OK) rv = sc_pkcs11_unwrap(session, pMechanism, object, key_type, - hSession, pWrappedKey, ulWrappedKeyLen, key_object); + pWrappedKey, ulWrappedKeyLen, key_object); /* TODO if (rv != CK_OK) need to destroy the object */ rv = reset_login_state(session->slot, rv); diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index fe6bd8c9a2..6876180e7a 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -434,7 +434,8 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); #endif CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE); CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); -CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *); +CK_RV sc_pkcs11_wrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *); CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *); From ae5675ca221427b42f5853d954d331e3d6a32ca7 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 13 Mar 2018 08:24:23 +0200 Subject: [PATCH 0580/4321] Fixed MSE for unwrap operation. Fixed wrong P1 when formatting APDU in myeid_unwrap_key. --- src/libopensc/card-myeid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 1f9cead2e2..5cd1ae13b4 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -660,7 +660,7 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * memcpy(p, env->file_ref.value, 2); p += 2; } - if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) + if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && env->operation != SC_SEC_OPERATION_UNWRAP) { *p++ = 0x84; *p++ = 1; @@ -1272,11 +1272,11 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x80 Resp: Plain value + * P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF. * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ sc_format_apdu(card, &apdu, (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, - 0x2A, 0x80, 0x86); + 0x2A, 0x00, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -1307,7 +1307,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra if (crgram_len == 256) { sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, - 0x2A, 0x80, 0x86); + 0x2A, 0x00, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; From a2156da04443d8b66889b67fc262799a1863de1d Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 28 Mar 2018 13:34:51 +0300 Subject: [PATCH 0581/4321] Fix encoding of SC_ASN1_CHOICE entry "parameters" in c_asn1_algorithm_info. Format only the selected entry of the choice. --- src/libopensc/pkcs15.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 14cf890fa0..4313407e72 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -312,11 +312,15 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 2, - asn1_algo_infos_parameters[ii], NULL, 0); - sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0, - NULL, NULL, 0); - sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1, - &ti->supported_algos[ii].parameters, ¶meter_len, 0); + asn1_algo_infos_parameters[ii], NULL, 1); + if (!ti->supported_algos[ii].parameters) { + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0, + NULL, NULL, 1); + } + else { + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1, + &ti->supported_algos[ii].parameters, ¶meter_len, 0); + } sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1); sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 1); From 7454133272645a3593921b0d66d1bc3f5e2e0b34 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 6 Apr 2018 13:35:03 +0300 Subject: [PATCH 0582/4321] Added flags to distinguish AES ECB and CBC modes. Added SC_ALGORIHM_UNDEFINED definition to be used with CKK_GENERIC_SECRET type keys. Added sc_sec_env_param type, which can be used to define additional parameters when settings security environment. This is now used for setting IV in symmetric crypto and target EF in key wrapping/unwrapping. --- src/libopensc/opensc.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 7c17b4adfa..75099bb837 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -68,6 +68,11 @@ extern "C" { #define SC_SEC_ENV_ALG_PRESENT 0x0010 #define SC_SEC_ENV_TARGET_FILE_REF_PRESENT 0x0020 +/* sc_security_env additional parameters */ +#define SC_SEC_ENV_MAX_PARAMS 10 +#define SC_SEC_ENV_PARAM_IV 1 +#define SC_SEC_ENV_PARAM_TARGET_FILE 2 + /* PK algorithms */ #define SC_ALGORITHM_RSA 0 #define SC_ALGORITHM_DSA 1 @@ -79,6 +84,7 @@ extern "C" { #define SC_ALGORITHM_3DES 65 #define SC_ALGORITHM_GOST 66 #define SC_ALGORITHM_AES 67 +#define SC_ALGORITHM_UNDEFINED 68 /* used with CKK_GENERIC_SECRET type keys */ /* Hash algorithms */ #define SC_ALGORITHM_MD5 128 @@ -195,6 +201,13 @@ extern "C" { #define SC_ALGORITHM_EXT_EC_UNCOMPRESES 0x00000010 #define SC_ALGORITHM_EXT_EC_COMPRESS 0x00000020 +/* symmetric algorithm flags. More algorithms to be added when implemented. */ +#define SC_ALGORITHM_AES_ECB 0x01000000 +#define SC_ALGORITHM_AES_CBC 0x02000000 +#define SC_ALGORITHM_AES_CBC_PAD 0x04000000 +#define SC_ALGORITHM_AES_FLAGS 0x0F000000 + + /* Event masks for sc_wait_for_event() */ #define SC_EVENT_CARD_INSERTED 0x0001 #define SC_EVENT_CARD_REMOVED 0x0002 @@ -212,6 +225,13 @@ struct sc_supported_algo_info { unsigned int algo_ref; }; +typedef struct sc_sec_env_param { + unsigned int param_type; + unsigned char* value; + unsigned int value_len; +} sc_sec_env_param_t; + + typedef struct sc_security_env { unsigned long flags; int operation; @@ -224,6 +244,8 @@ typedef struct sc_security_env { struct sc_path target_file_ref; /* target key file in unwrap operation */ struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS]; + /* optional parameters */ + struct sc_sec_env_param params[SC_SEC_ENV_MAX_PARAMS]; } sc_security_env_t; struct sc_algorithm_id { From 2487bc18d18040b62e08de2862fe231f4bbdf30c Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 6 Apr 2018 14:12:05 +0300 Subject: [PATCH 0583/4321] When creating symmetric keys, use CKK_ definitions (key type) rather than CKM_ definitions (mechanism) to specify the key type. --- src/pkcs15init/pkcs15-lib.c | 24 +++++++++++++++++------- src/pkcs15init/pkcs15-myeid.c | 8 ++++---- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index d706a82173..eda7071e96 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1330,13 +1330,16 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi key_info->key_reference = 0; switch (keyargs->algorithm) { case SC_ALGORITHM_DES: - key_info->key_type = CKM_DES_ECB; + key_info->key_type = CKK_DES; break; case SC_ALGORITHM_3DES: - key_info->key_type = CKM_DES3_ECB; + key_info->key_type = CKK_DES3; break; case SC_ALGORITHM_AES: - key_info->key_type = CKM_AES_ECB; + key_info->key_type = CKK_AES; + break; + default: + key_info->key_type = CKK_GENERIC_SECRET; break; } key_info->value_len = keybits; @@ -1931,11 +1934,17 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile sc_pkcs15_free_object_content(object); - /* Now update the SKDF */ - r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_SKDF, object); - LOG_TEST_RET(ctx, r, "Failed to add new secret key PKCS#15 object"); + /* Now update the SKDF, unless it is a session object. + If we have an on card session object, we have created the actual key object on card. + The card handles removing it when the session is finished or during the next reset. + We will maintain the object in the P15 structure in memory for duration of the session, + but we don't want it to be written into SKDF. */ + if (!object->session_object) { + r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_SKDF, object); + LOG_TEST_RET(ctx, r, "Failed to add new secret key PKCS#15 object"); + } - if (!r && profile->ops->emu_store_data) { + if (!r && profile->ops->emu_store_data && !object->session_object) { r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; @@ -2584,6 +2593,7 @@ key_pkcs15_algo(struct sc_pkcs15_card *p15card, unsigned int algorithm) case SC_ALGORITHM_3DES: return SC_PKCS15_TYPE_SKEY_3DES; case SC_ALGORITHM_AES: + case SC_ALGORITHM_UNDEFINED: return SC_PKCS15_TYPE_SKEY_GENERIC; } sc_log(ctx, "Unsupported key algorithm."); diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 062d6abc23..e54ed2bbe3 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -481,11 +481,11 @@ myeid_fixup_supported_algos(struct sc_profile *profile, struct sc_pkcs15_card *p switch (object->type) { case SC_PKCS15_TYPE_SKEY_GENERIC: switch (skey_info->key_type | (skey_info->value_len << 16)) { - case CKM_AES_ECB | (128 << 16): + case CKK_AES | (128 << 16): _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes128_ecb); _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes128_cbc); break; - case CKM_AES_ECB | (256 << 16): + case CKK_AES | (256 << 16): _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes256_ecb); _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes256_cbc); break; @@ -539,10 +539,10 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if ((skey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) extractable = TRUE; switch (skey_info->key_type) { - case CKM_AES_ECB: + case CKK_AES: ef_structure = SC_CARDCTL_MYEID_KEY_AES; break; - case CKM_DES_ECB: + case CKK_DES: ef_structure = SC_CARDCTL_MYEID_KEY_DES; break; default: From 550d4eb030dade20e6cffaa35787862152e00c30 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 6 Apr 2018 14:15:10 +0300 Subject: [PATCH 0584/4321] Small fixes to key wrapping and unwrapping. Handle target file ref using sc_sec_env_param type. Transmit initialization vector in symmetric key operations from PKCS#11 layer (mechanism param) to the card driver level, allow setting it in sc_set_security_env. --- src/libopensc/card-myeid.c | 46 ++++++++++++++++++++----- src/libopensc/padding.c | 2 +- src/libopensc/pkcs15-sec.c | 64 +++++++++++++++++++++++++++-------- src/libopensc/pkcs15.h | 6 ++-- src/pkcs11/framework-pkcs15.c | 27 ++++++++++----- 5 files changed, 110 insertions(+), 35 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 5cd1ae13b4..81a06f2bce 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -227,8 +227,10 @@ static int myeid_init(struct sc_card *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; - /* if (card->version.fw_major >= 41) */ /* TODO: check the version number that actually supports these ops */ - card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY; + if ((card->version.fw_major == 40 && card->version.fw_minor == 10 ) + || card->version.fw_major >= 41) + card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY + | SC_CARD_CAP_ONCARD_SESSION_OBJECTS; card->max_recv_size = 255; card->max_send_size = 255; @@ -612,6 +614,8 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 *p; int r; + size_t i; + sc_path_t *target_file; assert(card != NULL && env != NULL); LOG_FUNC_CALLED(card->ctx); @@ -639,8 +643,12 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * apdu.p2 = 0xB6; break; case SC_SEC_OPERATION_UNWRAP: - apdu.p1 = 0x41; /* emulating unwrapping with DECIPHER operation */ - apdu.p2 = 0xB8; /* TODO: set correct params when operation is implemented on card */ + apdu.p1 = 0x41; + apdu.p2 = 0xB8; + break; + case SC_SEC_OPERATION_WRAP: + apdu.p1 = 0x81; + apdu.p2 = 0xB8; break; default: return SC_ERROR_INVALID_ARGUMENTS; @@ -660,18 +668,38 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * memcpy(p, env->file_ref.value, 2); p += 2; } - if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && env->operation != SC_SEC_OPERATION_UNWRAP) + if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && env->operation != SC_SEC_OPERATION_UNWRAP && + env->operation != SC_SEC_OPERATION_WRAP) { *p++ = 0x84; *p++ = 1; *p++ = 0; } - if (env->flags & SC_SEC_ENV_TARGET_FILE_REF_PRESENT) - { + for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) + if (env->params[i].param_type == SC_SEC_ENV_PARAM_TARGET_FILE) { + target_file = (sc_path_t*) env->params[i].value; + if (env->params[i].value_len < sizeof(sc_path_t) || target_file->len != 2) { + sc_log(card->ctx, "wrong length of target file reference.\n"); + return SC_ERROR_WRONG_LENGTH; + } *p++ = 0x83; *p++ = 2; - memcpy(p, env->target_file_ref.value, 2); + memcpy(p, target_file->value, 2); p+= 2; + break; + } + + if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP) /* & SC_SEC_ENV_IV_PRESENT*/ + { + /* add IV if present */ + for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) + if (env->params[i].param_type == SC_SEC_ENV_PARAM_IV) { + *p++ = 0x87; + *p++ = (unsigned char) env->params[i].value_len; + memcpy(p, env->params[i].value, env->params[i].value_len); + p+=(unsigned char) env->params[i].value_len; + break; + } } r = p - sbuf; apdu.lc = r; @@ -842,7 +870,7 @@ static int myeid_set_security_env(struct sc_card *card, tmp.algorithm_ref = 0x00; } /* from this point, there's no difference to RSA SE */ - return myeid_set_security_env_rsa(card, env, se_num); + return myeid_set_security_env_rsa(card, &tmp, se_num); } else { diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 1cb38b0db9..cefc10c90a 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -480,12 +480,12 @@ int sc_get_encoding_flags(sc_context_t *ctx, /* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and * ECDSA_HASH_ -> ECDSA_RAW using OpenSSL (not much benefit though). */ - if ((caps & iflags) == iflags) { /* Card supports the signature operation we want to do, great, let's * go with it then. */ *sflags = iflags; *pflags = 0; + } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { *sflags |= SC_ALGORITHM_RSA_PAD_PSS; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 85b705bd8f..5bf9928951 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -34,6 +34,25 @@ #include "pkcs15.h" #include "pkcs11/pkcs11.h" +static int sec_env_add_param(sc_security_env_t* se, const sc_sec_env_param_t* p) +{ + size_t i; + + if (!se || !p) + return SC_ERROR_INCORRECT_PARAMETERS; + + for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) { + if (se->params[i].value == NULL) { + se->params[i] = *p; + + return SC_SUCCESS; + } + } + + return SC_ERROR_TOO_MANY_OBJECTS; +} + + static sc_path_t get_file_path(const struct sc_pkcs15_object* obj) { sc_path_t path; @@ -343,7 +362,8 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - const u8 * in, size_t inlen) + const u8 * in, size_t inlen, + const u8 * param, size_t paramlen) { sc_context_t *ctx = p15card->card->ctx; int r; @@ -356,6 +376,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, u8 *out = 0; size_t poutlen = 0; sc_path_t path, target_file_id; + sc_sec_env_param_t senv_param; LOG_FUNC_CALLED(ctx); @@ -379,32 +400,37 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, if (!tkey->path.len && tkey->path.aid.len) { /* Target key is a SDO allocated in application DF */ - path = tkey->path; + target_file_id = tkey->path; } else if (tkey->path.len == 2 && p15card->file_app != NULL) { /* Path is relative to app. DF */ path = p15card->file_app->path; target_file_id = tkey->path; sc_append_path(&path, &target_file_id); - senv.target_file_ref = target_file_id; - senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + target_file_id = path; } else if (tkey->path.len > 2) { path = tkey->path; memcpy(target_file_id.value, tkey->path.value + tkey->path.len - 2, 2); target_file_id.len = 2; target_file_id.type = SC_PATH_TYPE_FILE_ID; - senv.target_file_ref = target_file_id; - senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; } else { LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); } + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)}; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment"); + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; + if ((sec_flags & SC_ALGORITHM_AES_CBC & SC_ALGORITHM_AES_CBC_PAD) > 0) { + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); + } + r = use_key(p15card, key, &senv, sc_unwrap, in, inlen, out, poutlen); LOG_TEST_RET(ctx, r, "use_key() failed"); @@ -422,7 +448,8 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, size_t* crgram_len) { + u8 * cryptogram, size_t* crgram_len, + const u8 * param, size_t paramlen) { sc_context_t *ctx = p15card->card->ctx; int r; sc_algorithm_info_t *alg_info = NULL; @@ -437,6 +464,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, u8 *out = 0; size_t *poutlen = 0, inlen = 0; sc_path_t path, target_file_id; + sc_sec_env_param_t senv_param; LOG_FUNC_CALLED(ctx); @@ -476,36 +504,44 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, break; } - if (!path.len && path.aid.len) { + if (!tkey_path.len && tkey_path.aid.len) { /* Target key is a SDO allocated in application DF */ - path = tkey_path; + target_file_id = tkey_path; } else if (tkey_path.len == 2 && p15card->file_app != NULL) { /* Path is relative to app. DF */ path = p15card->file_app->path; target_file_id = tkey_path; sc_append_path(&path, &target_file_id); - senv.target_file_ref = target_file_id; - senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; + target_file_id = path; } else if (tkey_path.len > 2) { - path = tkey_path; + /*path = tkey_path;*/ memcpy(target_file_id.value, tkey_path.value + tkey_path.len - 2, 2); target_file_id.len = 2; target_file_id.type = SC_PATH_TYPE_FILE_ID; - senv.target_file_ref = target_file_id; - senv.flags |= SC_SEC_ENV_TARGET_FILE_REF_PRESENT; } else { LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); } + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)}; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment"); r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; + if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); + } + out = cryptogram; poutlen = crgram_len; r = use_key(p15card, key, &senv, sc_wrap, in, inlen, out, *poutlen); + + if (r > -1) + *poutlen = r; + /* TODO: handle SC_ERROR_BUFFER_TOO_SMALL, return size in *poutlen */ LOG_TEST_RET(ctx, r, "use_key() failed"); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index cdfb5c5614..8ad883e0e7 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -666,13 +666,15 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - const u8 * in, size_t inlen); + const u8 * in, size_t inlen, + const u8 * param, size_t paramlen); int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, size_t* crgram_len); + u8 * cryptogram, size_t* crgram_len, + const u8 * param, size_t paramlen); int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 65648cd65b..1685130710 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2244,6 +2244,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile switch (key_type) { case CKK_GENERIC_SECRET: + args.algorithm = SC_ALGORITHM_UNDEFINED; + break; case CKK_AES: args.algorithm = SC_ALGORITHM_AES; break; @@ -2673,8 +2675,9 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK * PKCS#11 says the default is false. * for backward compatibility, will default to TRUE */ - /* Dont need profile id creating session only objects */ - if (_token == TRUE) { + /* Dont need profile id creating session only objects, + except when the card supports temporary on card session objects */ + if (_token == TRUE || (p11card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == SC_CARD_CAP_ONCARD_SESSION_OBJECTS) { struct sc_aid *aid = NULL; rc = sc_lock(p11card->card); @@ -3983,7 +3986,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, /* Call the card to do the unwrap operation */ rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->p15_object, 0, - pWrappedKey, ulWrappedKeyLen); + pWrappedKey, ulWrappedKeyLen, NULL, 0); sc_unlock(p11card->card); @@ -4847,10 +4850,13 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_AES_ECB: - flags |= SC_ALGORITHM_AES; /* TODO: may need to define separate constants for ECB and CBC in opensc.h */ + flags |= SC_ALGORITHM_AES_ECB; + break; + case CKM_AES_CBC_PAD: + flags |= SC_ALGORITHM_AES_CBC_PAD; break; case CKM_AES_CBC: - flags |= SC_ALGORITHM_AES; + flags |= SC_ALGORITHM_AES_CBC; /* in this case, pMechanism->pParameter contains IV */ break; default: return CKR_MECHANISM_INVALID; @@ -4863,7 +4869,7 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, /* Call the card to do the unwrap operation */ rv = sc_pkcs15_unwrap(fw_data->p15_card, skey->prv_p15obj, targetKeyObj->prv_p15obj, flags, - pWrappedKey, ulWrappedKeyLen); + pWrappedKey, ulWrappedKeyLen, pMechanism->pParameter, pMechanism->ulParameterLen); sc_unlock(p11card->card); @@ -4916,10 +4922,13 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_AES_ECB: - flags |= SC_ALGORITHM_AES; /* TODO: may need to define separate constants for ECB and CBC in opensc.h */ + flags |= SC_ALGORITHM_AES_ECB; + break; + case CKM_AES_CBC_PAD: /* with CBC, pMechanism->pParameter contains IV */ + flags |= SC_ALGORITHM_AES_CBC_PAD; break; case CKM_AES_CBC: - flags |= SC_ALGORITHM_AES; + flags |= SC_ALGORITHM_AES_CBC; break; default: return CKR_MECHANISM_INVALID; @@ -4932,7 +4941,7 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, /* Call the card to do the wrapping operation */ rv = sc_pkcs15_wrap(fw_data->p15_card, skey->prv_p15obj, targetKeyObj->prv_p15obj, flags, - pData, pulDataLen); + pData, pulDataLen, pMechanism->pParameter, pMechanism->ulParameterLen); sc_unlock(p11card->card); From 6b8c284d3e4d8f82fb44390cd5c777f76e7d6e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Silv=C3=A9n?= Date: Wed, 18 Apr 2018 14:22:55 +0200 Subject: [PATCH 0585/4321] Fixing pointer conversion that is invalid on some architectures. --- src/libopensc/pkcs15-sec.c | 5 +++-- src/libopensc/pkcs15.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 5bf9928951..e9fd154f13 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -448,7 +448,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, size_t* crgram_len, + u8 * cryptogram, unsigned long* crgram_len, const u8 * param, size_t paramlen) { sc_context_t *ctx = p15card->card->ctx; int r; @@ -462,7 +462,8 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, sc_path_t tkey_path; u8 *in = 0; u8 *out = 0; - size_t *poutlen = 0, inlen = 0; + unsigned long *poutlen = 0; + size_t inlen = 0; sc_path_t path, target_file_id; sc_sec_env_param_t senv_param; diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 8ad883e0e7..bcbc25a6e1 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -673,7 +673,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, size_t* crgram_len, + u8 * cryptogram, unsigned long* crgram_len, const u8 * param, size_t paramlen); int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, From c891ad2aad28f4b225859f4529e1f3e4b026def7 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 8 May 2018 05:27:00 -0700 Subject: [PATCH 0586/4321] Fixed version check for key wrapping functionality. Return needed buffer size in myeid_wrap_key, if no buffer or too small buffer is provided. --- src/libopensc/card-myeid.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 81a06f2bce..5eeda7ed28 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -227,7 +227,7 @@ static int myeid_init(struct sc_card *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; - if ((card->version.fw_major == 40 && card->version.fw_minor == 10 ) + if ((card->version.fw_major == 40 && card->version.fw_minor >= 10 ) || card->version.fw_major >= 41) card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY | SC_CARD_CAP_ONCARD_SESSION_OBJECTS; @@ -1273,12 +1273,11 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, r, "compute_signature failed"); + LOG_TEST_RET(ctx, r, "wrap key failed"); - if (apdu.resplen > outlen) - LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + if (apdu.resplen <= outlen) + memcpy(out, apdu.resp, apdu.resplen); - memcpy(out, apdu.resp, apdu.resplen); LOG_FUNC_RETURN(ctx, apdu.resplen); } From f74150b53d4a9954d01058e0cd02c0eae49231fb Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 8 May 2018 05:29:11 -0700 Subject: [PATCH 0587/4321] Proprietary attribute bits in FCP had to be adjusted due to conflicts with existing attributes. The needed changes were made to both card and OpenSC code. --- src/pkcs15init/pkcs15-myeid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index e54ed2bbe3..9721c640ec 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -41,10 +41,10 @@ unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; #define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY) -#define MYEID_PROP_INFO_1_EXCTRACTABLE 0x01; -#define MYEID_PROP_INFO_1_TRUSTED 0x02; -#define MYEID_PROP_INFO_1_WRAP_WITH_TRUSTED 0x04; -#define MYEID_PROP_INFO_2_SESSION_OBJECT 0x08; +#define MYEID_PROP_INFO_2_EXCTRACTABLE 0x08; +#define MYEID_PROP_INFO_1_TRUSTED 0x04; +#define MYEID_PROP_INFO_1_WRAP_WITH_TRUSTED 0x08; +#define MYEID_PROP_INFO_2_SESSION_OBJECT 0x01; /* For Myeid, all objects are files that can be deleted in any order */ static int @@ -626,7 +626,7 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, prop_info[0] |= (pin_reference << 4); if (extractable) - prop_info[0] |= MYEID_PROP_INFO_1_EXCTRACTABLE; + prop_info[1] |= MYEID_PROP_INFO_2_EXCTRACTABLE; if (object->session_object != 0) /* Object will be removed during next reset. */ prop_info[1] |= MYEID_PROP_INFO_2_SESSION_OBJECT; From eba75ead207b9c5866bb476061dd7ab395dab736 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 8 May 2018 05:34:50 -0700 Subject: [PATCH 0588/4321] framework-pkcs15: set CKA_EXTRACTABLE into pkcs#15 secret key object's access flags when set. pkcs15-sec: Return needed buffer size correctly when an insufficient buffer is provided. --- src/libopensc/pkcs15-sec.c | 11 +++++++---- src/pkcs11/framework-pkcs15.c | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index e9fd154f13..0ed164e04d 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -540,11 +540,14 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, r = use_key(p15card, key, &senv, sc_wrap, in, inlen, out, *poutlen); - if (r > -1) - *poutlen = r; + if (r > -1) { + if (*crgram_len < (unsigned) r) { + *poutlen = r; + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); + } - /* TODO: handle SC_ERROR_BUFFER_TOO_SMALL, return size in *poutlen */ - LOG_TEST_RET(ctx, r, "use_key() failed"); + *poutlen = r; + } LOG_FUNC_RETURN(ctx, r); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1685130710..fb1f4a6300 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2302,6 +2302,10 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile case CKA_UNWRAP: args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_UNWRAP); break; + case CKA_EXTRACTABLE: + if (pkcs15_check_bool_cka(attr, 1)) + args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; + break; default: /* ignore unknown attrs, or flag error? */ continue; From 4ce7e5289b47166ab92dd50e00765250d3a0abd9 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 21 May 2018 03:37:24 -0700 Subject: [PATCH 0589/4321] Fixed setting secret key length. CKA_VALUE_LEN comes as number of bytes, so multiply it by 8 to set correct bit length to the key file. --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index eda7071e96..ea9b07e62c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1295,7 +1295,7 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi struct sc_pkcs15_object *object = NULL; const char *label; unsigned int usage; - unsigned int keybits = keyargs->value_len; + unsigned int keybits = keyargs->value_len * 8; int r = 0, key_type; LOG_FUNC_CALLED(ctx); From 861d8b308b4fece4c4af7a2bf1f5f939da703256 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 25 May 2018 06:30:58 -0700 Subject: [PATCH 0590/4321] Fixed myeid_unwrap with symmetric keys: set correct p2 and no padding indicator byte. --- src/libopensc/card-myeid.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 5eeda7ed28..6e7c595314 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1289,6 +1289,8 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra struct sc_apdu apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 p2 = 0x86; + myeid_private_data_t* priv; LOG_FUNC_CALLED(card->ctx); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); @@ -1298,12 +1300,26 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra if (crgram_len > 256) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + if (card->drv_data) + { + priv = (myeid_private_data_t*) card->drv_data; + + if (priv->sec_env) + { + if (priv->sec_env->algorithm == SC_ALGORITHM_AES || + priv->sec_env->algorithm == SC_ALGORITHM_3DES || + priv->sec_env->algorithm == SC_ALGORITHM_DES) + p2 = 0x84; /* Set correct P2 for symmetric crypto */ + } + } + /* INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF. - * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ + * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram + * P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) */ sc_format_apdu(card, &apdu, (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, - 0x2A, 0x00, 0x86); + 0x2A, 0x00, p2); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -1317,12 +1333,17 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra memcpy(sbuf + 1, crgram, crgram_len / 2); apdu.lc = crgram_len / 2 + 1; } - else + else if (p2 == 0x86) { sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ memcpy(sbuf + 1, crgram, crgram_len); apdu.lc = crgram_len + 1; } + else /* symmetric crypto, no padding indicator byte */ + { + memcpy(sbuf, crgram, crgram_len); + apdu.lc = crgram_len; + } apdu.datalen = apdu.lc; apdu.data = sbuf; From 287a63c7045b544b1a678b585788d20b24d161c6 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 29 May 2018 06:23:57 -0700 Subject: [PATCH 0591/4321] Fixes to key wrapping and unwrapping code: Set IV correctly in symmetric unwrap. Correctly distinguish symmetric and asymmetric operation when building APDUs. Check CKA_TOKEN from the pkcs15 object in framework_pkcs15. Updated some comments. --- src/libopensc/card-myeid.c | 12 ++++++++---- src/libopensc/pkcs15-sec.c | 2 +- src/pkcs11/framework-pkcs15.c | 21 +++++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 6e7c595314..e14d54095a 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -869,6 +869,10 @@ static int myeid_set_security_env(struct sc_card *card, { tmp.algorithm_ref = 0x00; } + + if ((tmp.algorithm_flags & SC_ALGORITHM_AES_CBC_PAD) == SC_ALGORITHM_AES_CBC_PAD) + tmp.algorithm_ref |= 0x80; /* set PKCS#7 padding */ + /* from this point, there's no difference to RSA SE */ return myeid_set_security_env_rsa(card, &tmp, se_num); } @@ -1267,7 +1271,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x84, 0x00); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = outlen; + apdu.le = 0; apdu.lc = 0; r = sc_transmit_apdu(card, &apdu); @@ -1325,7 +1329,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; - if (crgram_len == 256) + if (crgram_len == 256 && p2 == 0x86) { apdu.le = 0; /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ @@ -1352,10 +1356,10 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - if (crgram_len == 256) + if (crgram_len == 256 && p2 == 0x86) /* with symmetric crypto, we support only single apdu unwrap for now */ { sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, - 0x2A, 0x00, 0x86); + 0x2A, 0x00, p2); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 0ed164e04d..35b5b5d459 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -426,7 +426,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; - if ((sec_flags & SC_ALGORITHM_AES_CBC & SC_ALGORITHM_AES_CBC_PAD) > 0) { + if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index fb1f4a6300..2ec9f80aa2 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2198,12 +2198,21 @@ out: return rv; } -/* TODO Only Session secret key objects are supported for now +/* + * Secret key objects can be stored on card, if the card supports them + * * Session objects have CKA_TOKEN=false + * + * CKA_TOKEN = FALSE can mean two things: + * 1. If the card supports on card session objects, the object is stored on card for duration of the PKCS#11 session. + * Depending on card implementation, it can be automatically deleted during the card's reset. + * This kind of objects are not written to the PKCS#15 directory file. + * 2. If the card doesn't support on card session objects, a CKA_TOKEN = FALSE object is stored only in OpenSC's memory. + + * This is used by the C_DeriveKey with ECDH to hold the * key, and the calling application can then retrieve tha attributes as needed. - * TODO If a card can support secret key objects on the card, this - * code will need to be expanded. + * . */ static CK_RV pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile, @@ -2348,10 +2357,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile skey_info->data.len = args.key.data_len; skey_info->value_len = args.value_len; /* callers preferred length */ args.key.data = NULL; + key_obj->session_object = 1; } else { if(_token == FALSE) - args.session_object = 1; /* store the object on card for duration of the session. */ + args.session_object = 1; /* store the object on card for duration of the session. */ rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { @@ -4752,9 +4762,8 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, *(CK_OBJECT_CLASS*)attr->pValue = CKO_SECRET_KEY; break; case CKA_TOKEN: - /*TODO DEE change if on card skeys are supported */ check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = FALSE; + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->session_object == 0; break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); From f2c041d29024c727b37b13a3c2311fec15937322 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 4 Jun 2018 23:35:23 -0700 Subject: [PATCH 0592/4321] card-myeid: Removed NULL out buffer assertion to allow caller to query required buffer size. mechanism.c: Bug fix to sc_pkcs11_wrap. Wrong operation was stopped in end of the function. --- src/libopensc/card-myeid.c | 4 ++-- src/pkcs11/mechanism.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index e14d54095a..ca45890d29 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1261,7 +1261,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - assert(card != NULL && out != NULL); + assert(card != NULL); ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -1279,7 +1279,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, r, "wrap key failed"); - if (apdu.resplen <= outlen) + if (apdu.resplen <= outlen && out != NULL) memcpy(out, apdu.resp, apdu.resplen); LOG_FUNC_RETURN(ctx, apdu.resplen); diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 1ff2a96146..76268a9d62 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -868,7 +868,7 @@ sc_pkcs11_wrap(struct sc_pkcs11_session *session, targetKey, wrappedData, wrappedDataLen); - session_stop_operation(session, SC_PKCS11_OPERATION_UNWRAP); + session_stop_operation(session, SC_PKCS11_OPERATION_WRAP); return rv; } From e636b6437708d7bbabff7fd195476fa1809a96c1 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 8 Jun 2018 06:49:29 -0700 Subject: [PATCH 0593/4321] Fixed: Return OK by PKCS#11 convention if NULL out buffer is provided, when caller wants to query required buffer size. --- src/libopensc/pkcs15-sec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 35b5b5d459..341bfb6fac 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -543,7 +543,8 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, if (r > -1) { if (*crgram_len < (unsigned) r) { *poutlen = r; - LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); + if (out != NULL) /* if NULL, return success and required buffer length by PKCS#11 convention */ + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); } *poutlen = r; From ec297b618ffd59a4e24e4a43a8b029415fdd232e Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 11 Jun 2018 22:58:45 -0700 Subject: [PATCH 0594/4321] sc_pkcs15_wrap: Fixed checking target key type. (checked partly from wrapping key) --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 341bfb6fac..d69a18cad6 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -485,7 +485,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, } if (!(target_key->type == SC_PKCS15_TYPE_PRKEY_RSA || - (key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) { + (target_key->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY)) { LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Target key type not supported"); } From 8ebb43d440858237d5f69c2d174d97b9009ce214 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 18 Jun 2018 09:31:12 +0300 Subject: [PATCH 0595/4321] Removed #ifdef USE_PKCS15_INIT around __pkcs15_create_secret_key_object. This function is now used also when reading and parsing a card, not only when creating new objects. --- src/pkcs11/framework-pkcs15.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 2ec9f80aa2..b1b3002e13 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -794,7 +794,6 @@ __pkcs15_create_data_object(struct pkcs15_fw_data *fw_data, } -#ifdef USE_PKCS15_INIT static int __pkcs15_create_secret_key_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_object *object, struct pkcs15_any_object **skey_object) @@ -812,7 +811,6 @@ __pkcs15_create_secret_key_object(struct pkcs15_fw_data *fw_data, return 0; } -#endif static int From 84317f4e9ddd42ab2167104317ff99e8990c5e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Silv=C3=A9n?= Date: Tue, 14 Aug 2018 20:52:34 +0000 Subject: [PATCH 0596/4321] Fixing missing call to sc_unlock. --- src/pkcs11/framework-pkcs15.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index b1b3002e13..b4ec6204f6 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2661,6 +2661,7 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK CK_OBJECT_CLASS _class; CK_BBOOL _token = FALSE; int rv, rc; + CK_BBOOL p15init_create_object; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) @@ -2689,7 +2690,9 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK */ /* Dont need profile id creating session only objects, except when the card supports temporary on card session objects */ - if (_token == TRUE || (p11card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == SC_CARD_CAP_ONCARD_SESSION_OBJECTS) { + p15init_create_object = _token == TRUE || (p11card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == SC_CARD_CAP_ONCARD_SESSION_OBJECTS; + + if (p15init_create_object) { struct sc_aid *aid = NULL; rc = sc_lock(p11card->card); @@ -2735,7 +2738,9 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK rv = CKR_FUNCTION_NOT_SUPPORTED; } - if (_token == TRUE) { + if (p15init_create_object) { + // TODO: after sc_pkcs15init_unbind, user may have to enter PIN on a pin pad reader even though authentication state + // is supposed to remain open. Check why this happens. sc_pkcs15init_unbind(profile); sc_unlock(p11card->card); } From 90ec7123baaf5aa5b3c320da931c9da2605ac2d3 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 1 Oct 2018 15:27:09 +0300 Subject: [PATCH 0597/4321] Corrections and code cleanup as requested in review. Changed value to void* in sc_sec_env_param_t, because param_type defines type of the value. Fixed handling of secret key length in framework-pkcs15 and pkcs15-lib: CKA_VALUE_LEN from PKCS#11 is in bytes, PKCS#15 objects need key length in bits. Rebased on top of upstream/master and resolved merge conflicts. --- src/libopensc/card-myeid.c | 114 +++++++++++++++++++--------------- src/libopensc/opensc.h | 2 +- src/libopensc/pkcs15-sec.c | 39 ++++++------ src/libopensc/pkcs15-skey.c | 8 +-- src/pkcs11/framework-pkcs15.c | 44 ++++++------- src/pkcs11/mechanism.c | 6 ++ src/pkcs11/openssl.c | 2 + src/pkcs15init/pkcs15-lib.c | 2 +- 8 files changed, 121 insertions(+), 96 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index ca45890d29..d74f00902a 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -59,6 +59,9 @@ #define MYEID_CARD_CAP_GRIDPIN 0x10 #define MYEID_CARD_CAP_PIV_EMU 0x20 +#define MYEID_MAX_APDU_DATA_LEN 0xFF +#define MYEID_MAX_RSA_KEY_LEN 2048 + static const char *myeid_card_name = "MyEID"; static char card_name_buf[MYEID_CARD_NAME_MAX_LEN]; @@ -677,25 +680,29 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * } for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) if (env->params[i].param_type == SC_SEC_ENV_PARAM_TARGET_FILE) { - target_file = (sc_path_t*) env->params[i].value; - if (env->params[i].value_len < sizeof(sc_path_t) || target_file->len != 2) { - sc_log(card->ctx, "wrong length of target file reference.\n"); - return SC_ERROR_WRONG_LENGTH; - } - *p++ = 0x83; - *p++ = 2; - memcpy(p, target_file->value, 2); - p+= 2; - break; + target_file = (sc_path_t*) env->params[i].value; + if (env->params[i].value_len < sizeof(sc_path_t) || target_file->len != 2) { + sc_log(card->ctx, "wrong length of target file reference.\n"); + return SC_ERROR_WRONG_LENGTH; + } + *p++ = 0x83; + *p++ = 2; + memcpy(p, target_file->value, 2); + p+= 2; + break; } - if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP) /* & SC_SEC_ENV_IV_PRESENT*/ + if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP) { /* add IV if present */ for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) if (env->params[i].param_type == SC_SEC_ENV_PARAM_IV) { *p++ = 0x87; *p++ = (unsigned char) env->params[i].value_len; + if (p + env->params[i].value_len >= sbuf + SC_MAX_APDU_BUFFER_SIZE) { + sc_log(card->ctx, "IV too long.\n"); + return SC_ERROR_WRONG_LENGTH; + } memcpy(p, env->params[i].value, env->params[i].value_len); p+=(unsigned char) env->params[i].value_len; break; @@ -1288,20 +1295,21 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len) { int r; - u8 out[512]; - size_t outlen = 512; struct sc_apdu apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 p2 = 0x86; + u8 p2 = 0x86; /* init P2 for asymmetric crypto by default.*/ myeid_private_data_t* priv; + int symmetric_operation = 0; LOG_FUNC_CALLED(card->ctx); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); - assert(card != NULL && crgram != NULL && out != NULL); + if (card == NULL || crgram == NULL) { + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "One or more of required arguments was null.\n"); + } - if (crgram_len > 256) + if (crgram_len > MYEID_MAX_RSA_KEY_LEN / 8) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); if (card->drv_data) @@ -1313,40 +1321,56 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra if (priv->sec_env->algorithm == SC_ALGORITHM_AES || priv->sec_env->algorithm == SC_ALGORITHM_3DES || priv->sec_env->algorithm == SC_ALGORITHM_DES) - p2 = 0x84; /* Set correct P2 for symmetric crypto */ + symmetric_operation = 1; + } + } + + if (symmetric_operation) + { + p2 = 0x84; /* Set correct P2 for symmetric crypto */ + if (crgram_len > MYEID_MAX_APDU_DATA_LEN) + { + LOG_TEST_RET(card->ctx, SC_ERROR_WRONG_LENGTH, "Unwrapping symmetric data longer that 255 bytes is not supported\n"); } } /* INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF. * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram - * P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) */ + * P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) + If crgram_len == 256 (2048 bit RSA), we split the cryptogram in two and send two APDUs. + */ sc_format_apdu(card, &apdu, - (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, + SC_APDU_CASE_3_SHORT, 0x2A, 0x00, p2); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = crgram_len; + apdu.le = 0; - if (crgram_len == 256 && p2 == 0x86) + if (symmetric_operation) { - apdu.le = 0; - /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ - sbuf[0] = 0x81; - memcpy(sbuf + 1, crgram, crgram_len / 2); - apdu.lc = crgram_len / 2 + 1; - } - else if (p2 == 0x86) - { - sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ - memcpy(sbuf + 1, crgram, crgram_len); - apdu.lc = crgram_len + 1; + /* symmetric crypto, no padding indicator byte */ + { + memcpy(sbuf, crgram, crgram_len); + apdu.lc = crgram_len; + } } - else /* symmetric crypto, no padding indicator byte */ + else { - memcpy(sbuf, crgram, crgram_len); - apdu.lc = crgram_len; + if (crgram_len > MYEID_MAX_APDU_DATA_LEN) + { + /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ + sbuf[0] = 0x81; + memcpy(sbuf + 1, crgram, crgram_len / 2); + apdu.lc = crgram_len / 2 + 1; + } + else + { + sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ + memcpy(sbuf + 1, crgram, crgram_len); + apdu.lc = crgram_len + 1; + } } apdu.datalen = apdu.lc; @@ -1356,15 +1380,15 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - if (crgram_len == 256 && p2 == 0x86) /* with symmetric crypto, we support only single apdu unwrap for now */ + if (crgram_len > MYEID_MAX_APDU_DATA_LEN) { - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, p2); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = crgram_len; + apdu.le = 0; /* padding indicator byte, - * 0x82 = Second half of 2048 bit cryptogram */ + * 0x82 = Second half of 2048 bit cryptogram */ sbuf[0] = 0x82; memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); apdu.lc = crgram_len / 2 + 1; @@ -1374,18 +1398,6 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { - LOG_FUNC_RETURN(card->ctx, r); - } - } - else - { - int len = apdu.resplen > outlen ? outlen : apdu.resplen; - - memcpy(out, apdu.resp, len); - LOG_FUNC_RETURN(card->ctx, r); } } LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 75099bb837..a25d95cbc2 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -227,7 +227,7 @@ struct sc_supported_algo_info { typedef struct sc_sec_env_param { unsigned int param_type; - unsigned char* value; + void* value; unsigned int value_len; } sc_sec_env_param_t; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index d69a18cad6..47e8e3adc0 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -53,22 +53,24 @@ static int sec_env_add_param(sc_security_env_t* se, const sc_sec_env_param_t* p) } -static sc_path_t get_file_path(const struct sc_pkcs15_object* obj) +static int get_file_path(const struct sc_pkcs15_object* obj, sc_path_t* path) { - sc_path_t path; + if (!path) + return SC_ERROR_INCORRECT_PARAMETERS; + const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data; const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data; - memset (&path, 0, sizeof(path)); - if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) { - path = prkey->path; + *path = prkey->path; } else if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) { - path = skey->path; + *path = skey->path; } + else + return SC_ERROR_INCORRECT_PARAMETERS; - return path; + return SC_SUCCESS; } @@ -83,7 +85,7 @@ static int select_key_file(struct sc_pkcs15_card *p15card, LOG_FUNC_CALLED(ctx); - orig_path = get_file_path(key); + LOG_TEST_RET(ctx, get_file_path(key, &orig_path), "Could not get key file path."); memset(&path, 0, sizeof(sc_path_t)); memset(&file_id, 0, sizeof(sc_path_t)); @@ -131,7 +133,8 @@ static int use_key(struct sc_pkcs15_card *p15card, { int r = SC_SUCCESS; int revalidated_cached_pin = 0; - sc_path_t path = get_file_path(obj); + sc_path_t path; + LOG_TEST_RET(p15card->card->ctx, get_file_path(obj, &path), "Failed to get key file path."); r = sc_lock(p15card->card); LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed"); @@ -419,7 +422,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); } - senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)}; + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, &target_file_id, sizeof(target_file_id)}; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment"); r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); @@ -427,7 +430,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, senv.algorithm_flags = sec_flags; if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { - senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen }; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } @@ -498,11 +501,11 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, switch (target_key->type) { case SC_PKCS15_TYPE_PRKEY_RSA: - tkey_path = target_prkey->path; - break; - default: /* we already know it is a secret key */ - tkey_path = target_skey->path; - break; + tkey_path = target_prkey->path; + break; + default: /* we already know it is a secret key */ + tkey_path = target_skey->path; + break; } if (!tkey_path.len && tkey_path.aid.len) { @@ -523,7 +526,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, else { LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path"); } - senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)}; + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, &target_file_id, sizeof(target_file_id)}; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment"); r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); @@ -531,7 +534,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, senv.algorithm_flags = sec_flags; if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { - senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen }; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c index f715e4a86a..be19f3d79f 100644 --- a/src/libopensc/pkcs15-skey.c +++ b/src/libopensc/pkcs15-skey.c @@ -164,10 +164,10 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj temp_oid.value[8] = -1; /* strip off AES subtype octet*/ if (sc_compare_oid(&id_aes, &temp_oid)) - if (info.key_type == 0) { - info.key_type = CKK_AES; - break; - } + if (info.key_type == 0) { + info.key_type = CKK_AES; + break; + } } } } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index b4ec6204f6..ba63b25aff 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2353,7 +2353,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile skey_info->key_type = key_type; /* PKCS#11 CKK_* */ skey_info->data.value = args.key.data; skey_info->data.len = args.key.data_len; - skey_info->value_len = args.value_len; /* callers preferred length */ + skey_info->value_len = args.value_len * 8; /* key length comes in number of bytes, use length in bits in PKCS#15. */ args.key.data = NULL; key_obj->session_object = 1; } @@ -2361,7 +2361,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile if(_token == FALSE) args.session_object = 1; /* store the object on card for duration of the session. */ - rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); + args.value_len = args.value_len * 8; /* CKA_VALUE_LEN is number of bytes, PKCS#15 needs key length in bits */ + rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); goto out; @@ -3521,7 +3522,7 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = { NULL, /* decrypt */ NULL, /* derive */ NULL, /* can_do */ - NULL /* init_params */ + NULL, /* init_params */ NULL /* wrap_key */ }; @@ -3971,11 +3972,10 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); - sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj, - pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj); - - if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) + if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) { + sc_log(context, "One or more of mandatory arguments were NULL."); return CKR_ARGUMENTS_BAD; + } /* See which of the alternative keys supports unwrap */ while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP)) @@ -3984,6 +3984,8 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, if (prkey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); + /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_RSA_PKCS: @@ -4529,7 +4531,7 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { NULL, /* decrypt */ NULL, /* derive */ NULL, /* can_do */ - NULL /* init_params */ + NULL, /* init_params */ NULL /* wrap_key */ }; @@ -4709,7 +4711,7 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = { NULL, /* decrypt */ NULL, /* derive */ NULL, /* can_do */ - NULL /* init_params */ + NULL, /* init_params */ NULL /* wrap_key */ }; @@ -4847,11 +4849,10 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); - sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj, - pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj); - - if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) - return CKR_ARGUMENTS_BAD; + if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) { + sc_log(context, "One or more of mandatory arguments were NULL."); + return CKR_ARGUMENTS_BAD; + } /* Check whether this key supports unwrap */ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP)) @@ -4863,6 +4864,7 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, if (skey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_AES_ECB: @@ -4920,21 +4922,21 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_WrapKey"); - sc_log(context, "wrapping %p %p %p %p %p %p, %lu", session, obj, - pMechanism, targetKey, pData, pulDataLen, pulDataLen == NULL ? 0 : *pulDataLen); - - if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL) - return CKR_ARGUMENTS_BAD; + if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL) { + sc_log(context, "One or more of mandatory arguments were NULL."); + return CKR_ARGUMENTS_BAD; + } /* Verify that the key supports wrapping */ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_WRAP)) skey = NULL; /* TODO: browse for a key that supports, like other similar funcs */ - if (skey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); + /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_AES_ECB: @@ -4983,7 +4985,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { NULL, /* decrypt */ NULL, /* derive */ NULL, /* can_do */ - NULL /* init_params */ + NULL, /* init_params */ pkcs15_skey_wrap /* wrap_key */ }; diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 76268a9d62..485511203b 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1097,6 +1097,9 @@ sc_pkcs11_wrap_operation(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *targetKey, CK_BYTE_PTR pWrappedData, CK_ULONG_PTR ulWrappedDataLen) { + if (!operation || !wrappingKey || !wrappingKey->ops || !wrappingKey->ops->wrap_key) + return CKR_ARGUMENTS_BAD; + return wrappingKey->ops->wrap_key(operation->session, wrappingKey, &operation->mechanism, @@ -1110,6 +1113,9 @@ sc_pkcs11_unwrap_operation(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, struct sc_pkcs11_object *targetKey) { + if (!operation || !unwrappingKey || !unwrappingKey->ops || !unwrappingKey->ops->unwrap_key) + return CKR_ARGUMENTS_BAD; + return unwrappingKey->ops->unwrap_key(operation->session, unwrappingKey, &operation->mechanism, diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 1255d47f83..8dc5b544e1 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -83,6 +83,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ NULL, /* derive */ + NULL, /* wrap */ + NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ }; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index ea9b07e62c..eda7071e96 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1295,7 +1295,7 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi struct sc_pkcs15_object *object = NULL; const char *label; unsigned int usage; - unsigned int keybits = keyargs->value_len * 8; + unsigned int keybits = keyargs->value_len; int r = 0, key_type; LOG_FUNC_CALLED(ctx); From 7bb53423a16dc1321be008b5d0757c330f9fcd10 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Thu, 18 Oct 2018 16:56:06 +0300 Subject: [PATCH 0598/4321] Code cleanup and minor corrections according to review. pkcs15-lib: Extractable keys are now marked as native. Check return value of check_key_compatibility in more explicit way to avoid misunderstandings. --- src/libopensc/card-myeid.c | 4 ++-- src/libopensc/padding.c | 2 +- src/libopensc/pkcs15-sec.c | 19 +++++++++---------- src/libopensc/pkcs15-skey.c | 6 ++---- src/pkcs11/framework-pkcs15.c | 15 +++++++-------- src/pkcs11/mechanism.c | 6 ++---- src/pkcs11/pkcs11-object.c | 2 +- src/pkcs15init/pkcs15-lib.c | 20 +++++++------------- 8 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index d74f00902a..c652973cf0 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1358,7 +1358,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra } else { - if (crgram_len > MYEID_MAX_APDU_DATA_LEN) + if (crgram_len >= MYEID_MAX_APDU_DATA_LEN) { /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ sbuf[0] = 0x81; @@ -1380,7 +1380,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - if (crgram_len > MYEID_MAX_APDU_DATA_LEN) + if (crgram_len >= MYEID_MAX_APDU_DATA_LEN) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, p2); diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index cefc10c90a..f4e6a7e4b0 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -505,7 +505,7 @@ int sc_get_encoding_flags(sc_context_t *ctx, *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; *pflags = iflags & SC_ALGORITHM_RSA_HASHES; - } else if ((iflags & SC_ALGORITHM_AES) == SC_ALGORITHM_AES) { /* TODO: seems like this constant does not belong to the same set of flags used form asymmetric algos. Fix this! */ + } else if ((iflags & SC_ALGORITHM_AES) == SC_ALGORITHM_AES) { /* TODO: seems like this constant does not belong to the same set of flags used form asymmetric algos. Fix this! */ *sflags = 0; *pflags = 0; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 47e8e3adc0..b71e069f99 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -534,8 +534,8 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, senv.algorithm_flags = sec_flags; if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { - senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen }; - LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); + senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen }; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } out = cryptogram; @@ -544,14 +544,13 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, *poutlen); if (r > -1) { - if (*crgram_len < (unsigned) r) { - *poutlen = r; - if (out != NULL) /* if NULL, return success and required buffer length by PKCS#11 convention */ - LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); - } - - *poutlen = r; - } + if (*crgram_len < (unsigned) r) { + *poutlen = r; + if (out != NULL) /* if NULL, return success and required buffer length by PKCS#11 convention */ + LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); + } + *poutlen = r; + } LOG_FUNC_RETURN(ctx, r); } diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c index be19f3d79f..4687d8c77e 100644 --- a/src/libopensc/pkcs15-skey.c +++ b/src/libopensc/pkcs15-skey.c @@ -152,10 +152,8 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj if (asn1_skey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_SKEY_GENERIC; - /* info.key_type = CKK_AES;*/ /* defaults to CKK_AES. TODO: implement choice 15 and GenericKeyAttributes like defined in ISO7816-15 and set key type accordingly. */ - - /* Check key type. framework-pkcs15 recognizes one type per key, and AES is the only algorithm supported for - * SKEY_GENERIC type keys, so just check if this key is AES compatible. */ + /* Check key type. framework-pkcs15 recognizes one type per key, and AES is the only algorithm supported for + * SKEY_GENERIC type keys, so just check if this key is AES compatible. */ for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS && info.algo_refs[i] != 0; i++) { for (ii = 0; ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo != 0; ii++) { diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ba63b25aff..ec2d5a6b14 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -131,11 +131,10 @@ struct pkcs15_skey_object { struct sc_pkcs15_skey *valueXXXX; }; -#define is_secret_key(obj) ((__p15_type(obj) & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) +#define is_skey(obj) ((__p15_type(obj) & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) #define skey_flags base.base.flags #define skey_p15obj base.p15_object -#define is_skey(obj) ((__p15_type(obj) & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY_OBJECT) extern struct sc_pkcs11_object_ops pkcs15_cert_ops; extern struct sc_pkcs11_object_ops pkcs15_prkey_ops; @@ -1346,7 +1345,7 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p sc_log(context, "Slot:%p Adding cert object %d to PIN '%.*s'", slot, i, (int) sizeof pin_obj->label, pin_obj->label); pkcs15_add_object(slot, obj, NULL); } - else if (is_secret_key(obj)) { + else if (is_skey(obj)) { sc_log(context, "Slot:%p Adding secret key object %d to PIN '%.*s'", slot, i, (int) sizeof pin_obj->label, pin_obj->label); pkcs15_add_object(slot, obj, NULL); } @@ -2361,7 +2360,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile if(_token == FALSE) args.session_object = 1; /* store the object on card for duration of the session. */ - args.value_len = args.value_len * 8; /* CKA_VALUE_LEN is number of bytes, PKCS#15 needs key length in bits */ + args.value_len = args.value_len * 8; /* CKA_VALUE_LEN is number of bytes, PKCS#15 needs key length in bits */ rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); @@ -4768,15 +4767,15 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_TOKEN: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = skey->base.p15_object->session_object == 0; + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->session_object == 0 ? CK_TRUE : CK_FALSE; break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = (skey->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; + *(CK_BBOOL*)attr->pValue = (skey->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0 ? CK_TRUE : CK_FALSE; break; case CKA_MODIFIABLE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = (skey->base.p15_object->flags & 0x02) != 0; + *(CK_BBOOL*)attr->pValue = (skey->base.p15_object->flags & 0x02) != 0 ? CK_TRUE : CK_FALSE; /*TODO Why no definition of the flag */ break; case CKA_LABEL: @@ -4814,7 +4813,7 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = (((skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0 - && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0); + && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0) ? CK_TRUE : CK_FALSE; break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 485511203b..609416d4b6 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -844,8 +844,7 @@ sc_pkcs11_wrap(struct sc_pkcs11_session *session, sc_pkcs11_mechanism_type_t *mt; CK_RV rv; - if (!session || !session->slot - || !(p11card = session->slot->p11card)) + if (!session || !session->slot || !(p11card = session->slot->p11card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ @@ -891,8 +890,7 @@ sc_pkcs11_unwrap(struct sc_pkcs11_session *session, CK_RV rv; - if (!session || !session->slot - || !(p11card = session->slot->p11card)) + if (!session || !session->slot || !(p11card = session->slot->p11card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 82e65caac3..719386df56 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1041,7 +1041,7 @@ CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */ { /* receives byte size of wrapped key */ CK_RV rv; CK_BBOOL can_wrap, - can_be_wrapped; + can_be_wrapped; CK_KEY_TYPE key_type; CK_ATTRIBUTE wrap_attribute = { CKA_WRAP, &can_wrap, sizeof(can_wrap) }; CK_ATTRIBUTE extractable_attribute = { CKA_EXTRACTABLE, &can_be_wrapped, sizeof(can_be_wrapped) }; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index eda7071e96..a3ae08c82c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1215,7 +1215,6 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof if (keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) { key_info->access_flags &= ~SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; - key_info->native = 0; } /* Select a Key ID if the user didn't specify one, @@ -1348,10 +1347,6 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi if (keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) { key_info->access_flags &= ~SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; - /* The following commented out. I interpret PKCS#15 so that native only means that a key - * can be used in on card crypto. Such key can be extractable (can be wrapped), so IMO this - logic is not correct. */ - /* key_info->native = 0; */ } if (keyargs->session_object > 0) @@ -1461,7 +1456,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (check_key_compatibility(p15card, keygen_args->prkey_args.key.algorithm, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, - keybits, SC_ALGORITHM_ONBOARD_KEY_GEN)) + keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); if (profile->ops->generate_key == NULL) @@ -1585,7 +1580,7 @@ sc_pkcs15init_generate_secret_key(struct sc_pkcs15_card *p15card, struct sc_prof LOG_TEST_RET(ctx, r, "Invalid key size"); if (check_key_compatibility(p15card, skey_args->algorithm, NULL, 0, - keybits, SC_ALGORITHM_ONBOARD_KEY_GEN)) + keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); if (profile->ops->generate_key == NULL) @@ -1654,11 +1649,11 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil LOG_TEST_RET(ctx, keybits, "Invalid private key size"); /* Now check whether the card is able to handle this key */ - if (check_key_compatibility(p15card, key.algorithm, &key, keyargs->x509_usage, keybits, 0)) { + if (check_key_compatibility(p15card, key.algorithm, &key, keyargs->x509_usage, keybits, 0) != SC_SUCCESS) { /* Make sure the caller explicitly tells us to store * the key as extractable. */ if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) - LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key."); + LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key for crypto. Cannot store it as non extractable."); } /* Select a intrinsic Key ID if user didn't specify one */ @@ -1887,12 +1882,11 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile LOG_FUNC_CALLED(ctx); /* Now check whether the card is able to handle this key */ - if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0)) { + if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0) != SC_SUCCESS) { /* Make sure the caller explicitly tells us to store * the key as extractable. */ - /* Commented out. I don't understand why one couldn't store a key as non extractable. -HH */ -/* if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) - LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key.");*/ + if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) + LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key for crypto. Cannot store it as non extractable."); } #ifdef ENABLE_OPENSSL From f88419bc63c3f61d024eb02b69db613a75e2a530 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 30 Oct 2018 15:37:39 +0200 Subject: [PATCH 0599/4321] Removed pointless curly brackets --- src/libopensc/card-myeid.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index c652973cf0..3f3b74985c 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1351,10 +1351,8 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra if (symmetric_operation) { /* symmetric crypto, no padding indicator byte */ - { - memcpy(sbuf, crgram, crgram_len); - apdu.lc = crgram_len; - } + memcpy(sbuf, crgram, crgram_len); + apdu.lc = crgram_len; } else { From 5c7b7bb0b1baea28020a55af95710371d571865c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 31 Oct 2018 12:59:00 +0100 Subject: [PATCH 0600/4321] fixed minor XCode documentation warnings --- src/common/simclist.h | 2 +- src/libopensc/internal.h | 2 +- src/libopensc/log.h | 2 +- src/libopensc/opensc.h | 10 +++++----- src/libopensc/sm.h | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/common/simclist.h b/src/common/simclist.h index b6ef9f9d2a..1b8782bbb8 100644 --- a/src/common/simclist.h +++ b/src/common/simclist.h @@ -163,7 +163,7 @@ typedef list_hash_t (*element_hash_computer)(const void *el); * @param serialize_buffer reference to fill with the length of the buffer * @return reference to the buffer with the serialized data */ -typedef void *(*element_serializer)(const void *simclist_restrict el, uint32_t *simclist_restrict serializ_len); +typedef void *(*element_serializer)(const void *simclist_restrict el, uint32_t *simclist_restrict serialize_buffer); /** * a function for un-serializing an element. diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 08d590f231..dd079aacba 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -155,7 +155,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, * @param inlen IN length of the input * @param out OUT output buffer (in == out is allowed) * @param outlen OUT length of the output buffer - * @param modlen IN length of the modulus in bytes + * @param mod_bits IN length of the modulus in bits * @return SC_SUCCESS on success and an error code otherwise */ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, diff --git a/src/libopensc/log.h b/src/libopensc/log.h index a91d86468e..ef98a07686 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -93,7 +93,7 @@ void _sc_log(struct sc_context *ctx, const char *format, ...); * @brief Log binary data * * @param[in] ctx Context for logging - * @param[in] type Debug level + * @param[in] level Debug level * @param[in] file File name to be prepended * @param[in] line Line to be prepended * @param[in] func Function to be prepended diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 0abbf6a957..18489a8ab5 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -767,7 +767,7 @@ typedef struct sc_context { * @param apdu sc_apdu_t object of the APDU to be send * @return SC_SUCCESS on success and an error code otherwise */ -int sc_transmit_apdu(struct sc_card *, struct sc_apdu *); +int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); void sc_format_apdu(struct sc_card *, struct sc_apdu *, int, int, int, int); @@ -1040,7 +1040,7 @@ size_t sc_get_max_recv_size(const sc_card_t *card); * Takes card limitations into account such as extended length support as well * as the reader's limitation for data transfer. * - * @param card + * @param card card * * @return maximum Nc */ @@ -1449,7 +1449,7 @@ extern sc_card_driver_t *sc_get_iso7816_driver(void); /** * @brief Read a complete EF by short file identifier. * - * @param[in] card + * @param[in] card card * @param[in] sfid Short file identifier * @param[in,out] ef Where to safe the file. the buffer will be allocated * using \c realloc() and should be set to NULL, if @@ -1464,7 +1464,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, /** * @brief Write a complete EF by short file identifier. * - * @param[in] card + * @param[in] card card * @param[in] sfid Short file identifier * @param[in] ef Date to write * @param[in] ef_len Length of \a ef @@ -1477,7 +1477,7 @@ int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, /** * @brief Set verification status of a specific PIN to “not verified†* - * @param[in] card + * @param[in] card card * @param[in] pin_reference PIN reference written to P2 * * @note The appropriate directory must be selected before calling this function. diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index 7e4250c6c9..b3b1ae487c 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -362,7 +362,7 @@ int sc_sm_single_transmit(struct sc_card *, struct sc_apdu *); * Calls \a card->sm_ctx.ops.close() if available and \c card->sm_ctx.sm_mode * is \c SM_MODE_TRANSMIT * - * @param[in] card + * @param[in] card card * * @return \c SC_SUCCESS or error code if an error occurred */ From 54cb1099a0df41ddd1c858929342067c599628ba Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 31 Oct 2018 13:10:12 +0100 Subject: [PATCH 0601/4321] fixed warnings about precision loss --- src/pkcs11/framework-pkcs15.c | 96 +++++++++++++++++-------------- src/pkcs11/framework-pkcs15init.c | 5 +- src/pkcs11/mechanism.c | 83 +++++++++++++------------- src/pkcs11/misc.c | 2 +- src/pkcs11/openssl.c | 24 ++++---- src/pkcs11/pkcs11-object.c | 23 ++++---- src/pkcs11/pkcs11-session.c | 2 +- src/pkcs11/pkcs11-spy.c | 2 +- src/pkcs11/sc-pkcs11.h | 12 ++-- src/pkcs11/slot.c | 5 +- 10 files changed, 133 insertions(+), 121 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 85e12df660..0fcb157619 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -424,10 +424,13 @@ pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken) * will assure that the serial within each type of card will be * unique in pkcs11 (at least for the first 8^16 cards :-) */ if (p15card->tokeninfo->serial_number != NULL) { - int sn_start = strlen(p15card->tokeninfo->serial_number) - 16; + size_t sn_start = strlen(p15card->tokeninfo->serial_number); - if (sn_start < 0) + if (sn_start <= 16) sn_start = 0; + else + sn_start -= 16; + strcpy_bp(pToken->serialNumber, p15card->tokeninfo->serial_number + sn_start, 16); } @@ -450,7 +453,7 @@ static char * set_cka_label(CK_ATTRIBUTE_PTR attr, char *label) { char *l = (char *)attr->pValue; - int len = attr->ulValueLen; + unsigned long len = attr->ulValueLen; if (len >= SC_PKCS15_MAX_LABEL_SIZE) len = SC_PKCS15_MAX_LABEL_SIZE-1; @@ -1122,7 +1125,7 @@ pkcs15_create_slot(struct sc_pkcs11_card *p11card, struct pkcs15_fw_data *fw_dat struct sc_pkcs11_slot **out) { struct sc_pkcs11_slot *slot = NULL; - int rv; + CK_RV rv; sc_log(context, "Create slot (p11card %p, fw_data %p, auth %p, app_info %p)", p11card, fw_data, auth, app_info); rv = slot_allocate(&slot, p11card); @@ -1401,7 +1404,8 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf struct sc_pkcs15_object *auth_user_pin = NULL, *auth_sign_pin = NULL; struct sc_pkcs11_slot *slot = NULL, *sign_slot = NULL; unsigned int cs_flags = sc_pkcs11_conf.create_slots_flags; - int i, rv, idx; + CK_RV rv; + int rc, i, idx; sc_log(context, "create PKCS#15 tokens; fws:%p,%p,%p", p11card->fws_data[0], p11card->fws_data[1], p11card->fws_data[2]); sc_log(context, "create slots flags 0x%X", cs_flags); @@ -1422,9 +1426,9 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf sc_log(context, "Flags:0x%X; Auth User/Sign PINs %p/%p", cs_flags, auth_user_pin, auth_sign_pin); /* Add PKCS#15 objects of the known types to the framework data */ - rv = _pkcs15_create_typed_objects(fw_data); - if (rv < 0) - return sc_to_cryptoki_error(rv, NULL); + rc = _pkcs15_create_typed_objects(fw_data); + if (rc < 0) + return sc_to_cryptoki_error(rc, NULL); sc_log(context, "Found %d FW objects objects", fw_data->num_objects); /* Create slots for all non-unblock, non-so PINs if: @@ -1437,10 +1441,10 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf memset(auths, 0, sizeof(auths)); /* Get authentication PKCS#15 objects present in the associated on-card application */ - rv = sc_pkcs15_get_objects(fw_data->p15_card, SC_PKCS15_TYPE_AUTH_PIN, auths, SC_PKCS15_MAX_PINS); - if (rv < 0) - return sc_to_cryptoki_error(rv, NULL); - auth_count = rv; + rc = sc_pkcs15_get_objects(fw_data->p15_card, SC_PKCS15_TYPE_AUTH_PIN, auths, SC_PKCS15_MAX_PINS); + if (rc < 0) + return sc_to_cryptoki_error(rc, NULL); + auth_count = rc; sc_log(context, "Found %d authentication objects", auth_count); for (i = 0; i < auth_count; i++) { @@ -1556,7 +1560,7 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, if (sc_pkcs11_conf.pin_unblock_style == SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN) { if (ulPinLen && ulPinLen < sizeof(fw_data->user_puk)) { memcpy(fw_data->user_puk, pPin, ulPinLen); - fw_data->user_puk_len = ulPinLen; + fw_data->user_puk_len = (unsigned int) ulPinLen; } } @@ -2054,7 +2058,8 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil CK_KEY_TYPE key_type; struct sc_pkcs15_prkey_rsa *rsa = NULL; struct sc_pkcs15_prkey_gostr3410 *gost = NULL; - int rc, rv; + int rc; + CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2207,7 +2212,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15_skey_info *skey_info; CK_KEY_TYPE key_type; CK_BBOOL _token = FALSE; - int rv; + CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2309,7 +2314,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile goto out; } key_obj->data = skey_info; - skey_info->usage = args.usage; + skey_info->usage = (unsigned int) args.usage; skey_info->native = 0; /* card can not use this */ skey_info->access_flags = 0; /* looks like not needed */ skey_info->key_type = key_type; /* PKCS#11 CKK_* */ @@ -2358,7 +2363,8 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15_auth_info *pin = NULL; CK_KEY_TYPE key_type; struct sc_pkcs15_pubkey_rsa *rsa = NULL; - int rc, rv; + int rc; + CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2463,7 +2469,8 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *cert_obj = NULL; CK_CERTIFICATE_TYPE cert_type; CK_BBOOL bValue; - int rc, rv; + int rc; + CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2544,7 +2551,8 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, struct sc_pkcs15_object *data_obj = NULL; struct sc_pkcs15_auth_info *pin = NULL; CK_BBOOL bValue; - int rc, rv; + int rc; + CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); @@ -2624,7 +2632,8 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK struct sc_profile *profile = NULL; CK_OBJECT_CLASS _class; CK_BBOOL _token = FALSE; - int rv, rc; + CK_RV rv; + int rc; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) @@ -2875,7 +2884,8 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, CK_ULONG keybits = 0; char pub_label[SC_PKCS15_MAX_LABEL_SIZE]; char priv_label[SC_PKCS15_MAX_LABEL_SIZE]; - int rc, rv = CKR_OK; + int rc; + CK_RV rv = CKR_OK; sc_log(context, "Keypair generation, mech = 0x%0lx", pMechanism->mechanism); @@ -2996,7 +3006,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, sc_pkcs15init_set_p15card(profile, fw_data->p15_card); sc_log(context, "Try on-card key pair generation"); - rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile, &keygen_args, keybits, &priv_key_obj); + rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile, &keygen_args, (unsigned int) keybits, &priv_key_obj); if (rc >= 0) { id = ((struct sc_pkcs15_prkey_info *) priv_key_obj->data)->id; rc = sc_pkcs15_find_pubkey_by_id(fw_data->p15_card, &id, &pub_key_obj); @@ -3245,7 +3255,7 @@ pkcs15_set_attrib(struct sc_pkcs11_session *session, struct sc_pkcs15_object *p1 switch(attr->type) { case CKA_LABEL: rv = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object, - P15_ATTR_TYPE_LABEL, attr->pValue, attr->ulValueLen); + P15_ATTR_TYPE_LABEL, attr->pValue, (unsigned int) attr->ulValueLen); break; case CKA_ID: if (attr->ulValueLen > SC_PKCS15_MAX_ID_SIZE) { @@ -3266,7 +3276,7 @@ pkcs15_set_attrib(struct sc_pkcs11_session *session, struct sc_pkcs15_object *p1 goto set_attr_done; } rv = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object, - P15_ATTR_TYPE_VALUE, attr->pValue, attr->ulValueLen); + P15_ATTR_TYPE_VALUE, attr->pValue, (unsigned int) attr->ulValueLen); break; default: ck_rv = CKR_ATTRIBUTE_READ_ONLY; @@ -3407,7 +3417,7 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT #define ASN1_SET_TAG (SC_ASN1_SET | SC_ASN1_TAG_CONSTRUCTED) #define ASN1_SEQ_TAG (SC_ASN1_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED) -static int +static CK_RV pkcs15_cert_cmp_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr) { @@ -3751,7 +3761,8 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; - int rv, flags = 0, prkey_has_path = 0; + CK_RV rv; + int flags = 0, prkey_has_path = 0, rc; unsigned sign_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; @@ -3876,16 +3887,16 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, return CKR_MECHANISM_INVALID; } - rv = sc_lock(p11card->card); - if (rv < 0) - return sc_to_cryptoki_error(rv, "C_Sign"); + rc = sc_lock(p11card->card); + if (rc < 0) + return sc_to_cryptoki_error(rc, "C_Sign"); sc_log(context, "Selected flags %X. Now computing signature for %lu bytes. %lu bytes reserved.", flags, ulDataLen, *pulDataLen); - rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, + rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, pData, ulDataLen, pSignature, *pulDataLen); - if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) { + if (rc < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) { /* If private key PKCS#15 object do not have 'path' attribute, * and if PKCS#11 login session is not locked, * the compute signature could fail because of concurrent access to the card @@ -3893,20 +3904,20 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, * In this particular case try to 'reselect' application DF. */ if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) - rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, + rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, pData, ulDataLen, pSignature, *pulDataLen); } sc_unlock(p11card->card); - sc_log(context, "Sign complete. Result %d.", rv); + sc_log(context, "Sign complete. Result %d.", rc); - if (rv > 0) { - *pulDataLen = rv; + if (rc > 0) { + *pulDataLen = rc; return CKR_OK; } - return sc_to_cryptoki_error(rv, "C_Sign"); + return sc_to_cryptoki_error(rc, "C_Sign"); } @@ -4447,7 +4458,7 @@ pkcs15_dobj_set_attribute(struct sc_pkcs11_session *session, } -static int +static CK_RV pkcs15_dobj_get_value(struct sc_pkcs11_session *session, struct pkcs15_data_object *dobj, struct sc_pkcs15_data **out_data) @@ -4930,12 +4941,12 @@ get_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr) } -static int +static CK_RV register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) { CK_MECHANISM_INFO mech_info; sc_pkcs11_mechanism_type_t *mt; - int rc; + CK_RV rc; mech_info.flags = CKF_HW | CKF_SIGN | CKF_DECRYPT; #ifdef ENABLE_OPENSSL @@ -4978,13 +4989,13 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) } -static int register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, +static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, unsigned long ext_flags, CK_ULONG min_key_size, CK_ULONG max_key_size) { CK_MECHANISM_INFO mech_info; sc_pkcs11_mechanism_type_t *mt; CK_FLAGS ec_flags = 0; - int rc; + CK_RV rc; if (ext_flags & SC_ALGORITHM_EXT_EC_F_P) ec_flags |= CKF_EC_F_P; @@ -5074,7 +5085,8 @@ register_mechanisms(struct sc_pkcs11_card *p11card) unsigned long ec_ext_flags; sc_pkcs11_mechanism_type_t *mt; unsigned int num; - int rc, rsa_flags = 0, ec_flags = 0, gostr_flags = 0; + int rsa_flags = 0, ec_flags = 0, gostr_flags = 0; + CK_RV rc; /* Register generic mechanisms */ sc_pkcs11_register_generic_mechanisms(p11card); diff --git a/src/pkcs11/framework-pkcs15init.c b/src/pkcs11/framework-pkcs15init.c index e3038cfffe..2f352c2532 100644 --- a/src/pkcs11/framework-pkcs15init.c +++ b/src/pkcs11/framework-pkcs15init.c @@ -57,7 +57,7 @@ pkcs15init_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app { struct sc_profile *profile; struct sc_pkcs11_slot *slot; - int rc; + CK_RV rc; profile = (struct sc_profile *) p11card->fws_data[0]; @@ -130,7 +130,8 @@ pkcs15init_initialize(struct sc_pkcs11_slot *pslot, void *ptr, struct sc_profile *profile = (struct sc_profile *) p11card->fws_data[0]; struct sc_pkcs15init_initargs args; struct sc_pkcs11_slot *slot; - int rc, rv, id; + CK_RV rv; + int rc, id; memset(&args, 0, sizeof(args)); args.so_pin = pPin; diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index d4ce7fef5c..cf81826d3c 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -40,7 +40,7 @@ struct signature_data { struct hash_signature_info *info; sc_pkcs11_operation_t * md; CK_BYTE buffer[4096/8]; - unsigned int buffer_len; + unsigned int buffer_len; }; /* @@ -95,7 +95,7 @@ sc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *p11card, { sc_pkcs11_mechanism_type_t *mt; unsigned int n, count = 0; - int rv; + CK_RV rv; if (!p11card) return CKR_TOKEN_NOT_PRESENT; @@ -166,7 +166,7 @@ sc_pkcs11_md_init(struct sc_pkcs11_session *session, struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; - int rv; + CK_RV rv; LOG_FUNC_CALLED(context); if (!session || !session->slot || !(p11card = session->slot->p11card)) @@ -179,7 +179,7 @@ sc_pkcs11_md_init(struct sc_pkcs11_session *session, rv = session_start_operation(session, SC_PKCS11_OPERATION_DIGEST, mt, &operation); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); @@ -188,7 +188,7 @@ sc_pkcs11_md_init(struct sc_pkcs11_session *session, if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } CK_RV @@ -196,7 +196,7 @@ sc_pkcs11_md_update(struct sc_pkcs11_session *session, CK_BYTE_PTR pData, CK_ULONG ulDataLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_DIGEST, &op); if (rv != CKR_OK) @@ -208,7 +208,7 @@ sc_pkcs11_md_update(struct sc_pkcs11_session *session, if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } CK_RV @@ -220,7 +220,7 @@ sc_pkcs11_md_final(struct sc_pkcs11_session *session, rv = session_get_operation(session, SC_PKCS11_OPERATION_DIGEST, &op); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); /* This is a request for the digest length */ if (pData == NULL) @@ -231,7 +231,7 @@ sc_pkcs11_md_final(struct sc_pkcs11_session *session, LOG_FUNC_RETURN(context, pData == NULL ? CKR_OK : CKR_BUFFER_TOO_SMALL); session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } /* @@ -245,7 +245,7 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; - int rv; + CK_RV rv; LOG_FUNC_CALLED(context); if (!session || !session->slot || !(p11card = session->slot->p11card)) @@ -268,7 +268,7 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); if (pMechanism->pParameter) { @@ -280,7 +280,7 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } CK_RV @@ -288,12 +288,12 @@ sc_pkcs11_sign_update(struct sc_pkcs11_session *session, CK_BYTE_PTR pData, CK_ULONG ulDataLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; LOG_FUNC_CALLED(context); rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); if (op->type->sign_update == NULL) { rv = CKR_KEY_TYPE_INCONSISTENT; @@ -306,7 +306,7 @@ sc_pkcs11_sign_update(struct sc_pkcs11_session *session, if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } CK_RV @@ -314,12 +314,12 @@ sc_pkcs11_sign_final(struct sc_pkcs11_session *session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; LOG_FUNC_CALLED(context); rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); /* Bail out for signature mechanisms that don't do hashing */ if (op->type->sign_final == NULL) { @@ -333,18 +333,18 @@ sc_pkcs11_sign_final(struct sc_pkcs11_session *session, if (rv != CKR_BUFFER_TOO_SMALL && pSignature != NULL) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } CK_RV sc_pkcs11_sign_size(struct sc_pkcs11_session *session, CK_ULONG_PTR pLength) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op); if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); /* Bail out for signature mechanisms that don't do hashing */ if (op->type->sign_size == NULL) { @@ -358,7 +358,7 @@ sc_pkcs11_sign_size(struct sc_pkcs11_session *session, CK_ULONG_PTR pLength) if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } /* @@ -392,7 +392,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, else { /* Mechanism recognised but cannot be performed by pkcs#15 card, or some general error. */ free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } } @@ -402,7 +402,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, if (rv != CKR_OK) { /* Probably bad arguments */ free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } } @@ -421,7 +421,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, if (rv != CKR_OK) { sc_pkcs11_release_operation(&data->md); free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } data->info = info; } @@ -441,7 +441,7 @@ sc_pkcs11_signature_update(sc_pkcs11_operation_t *operation, data = (struct signature_data *) operation->priv_data; if (data->md) { CK_RV rv = data->md->type->md_update(data->md, pPart, ulPartLen); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } /* This signature mechanism operates on the raw data */ @@ -449,7 +449,6 @@ sc_pkcs11_signature_update(sc_pkcs11_operation_t *operation, LOG_FUNC_RETURN(context, CKR_DATA_LEN_RANGE); memcpy(data->buffer + data->buffer_len, pPart, ulPartLen); data->buffer_len += ulPartLen; - sc_log(context, "data length %u", data->buffer_len); LOG_FUNC_RETURN(context, CKR_OK); } @@ -462,7 +461,6 @@ sc_pkcs11_signature_final(sc_pkcs11_operation_t *operation, LOG_FUNC_CALLED(context); data = (struct signature_data *) operation->priv_data; - sc_log(context, "data length %u", data->buffer_len); if (data->md) { sc_pkcs11_operation_t *md = data->md; CK_ULONG len = sizeof(data->buffer); @@ -471,14 +469,13 @@ sc_pkcs11_signature_final(sc_pkcs11_operation_t *operation, if (rv == CKR_BUFFER_TOO_SMALL) rv = CKR_FUNCTION_FAILED; if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); - data->buffer_len = len; + LOG_FUNC_RETURN(context, (int) rv); + data->buffer_len = (unsigned int) len; } - sc_log(context, "%u bytes to sign", data->buffer_len); rv = data->key->ops->sign(operation->session, data->key, &operation->mechanism, data->buffer, data->buffer_len, pSignature, pulSignatureLen); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } static CK_RV @@ -521,7 +518,7 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) } } - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } static void @@ -549,7 +546,7 @@ sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechan struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; - int rv; + CK_RV rv; if (!session || !session->slot || !(p11card = session->slot->p11card)) @@ -583,7 +580,7 @@ sc_pkcs11_verif_update(struct sc_pkcs11_session *session, CK_BYTE_PTR pData, CK_ULONG ulDataLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_VERIFY, &op); if (rv != CKR_OK) @@ -608,7 +605,7 @@ sc_pkcs11_verif_final(struct sc_pkcs11_session *session, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_VERIFY, &op); if (rv != CKR_OK) @@ -635,7 +632,7 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, { struct hash_signature_info *info; struct signature_data *data; - int rv; + CK_RV rv; if (!(data = calloc(1, sizeof(*data)))) return CKR_HOST_MEMORY; @@ -651,7 +648,7 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, else { /* Mechanism cannot be performed by pkcs#15 card, or some general error. */ free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } } @@ -661,7 +658,7 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, if (rv != CKR_OK) { /* Probably bad arguments */ free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } } @@ -721,7 +718,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, CK_ATTRIBUTE attr = {CKA_VALUE, NULL, 0}; CK_ATTRIBUTE attr_key_type = {CKA_KEY_TYPE, &key_type, sizeof(key_type)}; CK_ATTRIBUTE attr_key_params = {CKA_GOSTR3410_PARAMS, ¶ms, sizeof(params)}; - int rv; + CK_RV rv; data = (struct signature_data *) operation->priv_data; @@ -756,10 +753,10 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, goto done; } - rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, + rv = sc_pkcs11_verify_data(pubkey_value, (unsigned int) attr.ulValueLen, params, sizeof(params), &operation->mechanism, data->md, - data->buffer, data->buffer_len, pSignature, ulSignatureLen); + data->buffer, data->buffer_len, pSignature, (unsigned int) ulSignatureLen); done: free(pubkey_value); @@ -815,7 +812,7 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { sc_pkcs11_operation_t *op; - int rv; + CK_RV rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_DECRYPT, &op); if (rv != CKR_OK) @@ -951,7 +948,7 @@ sc_pkcs11_decrypt_init(sc_pkcs11_operation_t *operation, else { /* Mechanism cannot be performed by pkcs#15 card, or some general error. */ free(data); - LOG_FUNC_RETURN(context, rv); + LOG_FUNC_RETURN(context, (int) rv); } } diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index e4798319a3..b9bef60dc1 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -305,7 +305,7 @@ CK_RV session_stop_operation(struct sc_pkcs11_session * session, int type) CK_RV attr_extract(CK_ATTRIBUTE_PTR pAttr, void *ptr, size_t * sizep) { - unsigned int size; + size_t size; if (sizep) { size = *sizep; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index fb9f8fea81..a24f2a3ab0 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -336,10 +336,10 @@ static void reverse(unsigned char *buf, size_t len) } } -static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, - const unsigned char *params, int params_len, - unsigned char *data, int data_len, - unsigned char *signat, int signat_len) +static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, + const unsigned char *params, unsigned int params_len, + unsigned char *data, unsigned int data_len, + unsigned char *signat, unsigned int signat_len) { EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx = NULL; @@ -413,11 +413,11 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, * If a hash function was used, we can make a big shortcut by * finishing with EVP_VerifyFinal(). */ -CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - const unsigned char *pubkey_params, int pubkey_params_len, +CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, + const unsigned char *pubkey_params, unsigned int pubkey_params_len, CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *data, int data_len, - unsigned char *signat, int signat_len) + unsigned char *data, unsigned int data_len, + unsigned char *signat, unsigned int signat_len) { int res; CK_RV rv = CKR_GENERAL_ERROR; @@ -598,9 +598,9 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, data_len = tmp_len; } rv = CKR_SIGNATURE_INVALID; - if (data_len == EVP_MD_size(pss_md) && - RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, - rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) + if (data_len == (unsigned int) EVP_MD_size(pss_md) + && RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, + rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) rv = CKR_OK; RSA_free(rsa); free(rsa_out); @@ -609,7 +609,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, } RSA_free(rsa); - if (rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) + if ((unsigned int) rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) rv = CKR_OK; else rv = CKR_SIGNATURE_INVALID; diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 0cc77d604e..a6b8422419 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -128,7 +128,8 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * out: if (use_lock) sc_pkcs11_unlock(); - LOG_FUNC_RETURN(context, rv); + + return rv; } @@ -210,7 +211,7 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */ CK_ULONG ulCount) /* attributes in template */ { - static int precedence[] = { + static CK_RV precedence[] = { CKR_OK, CKR_BUFFER_TOO_SMALL, CKR_ATTRIBUTE_TYPE_INVALID, @@ -218,11 +219,12 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ -1 }; char object_name[64]; - int j; + CK_RV j; CK_RV rv; struct sc_pkcs11_session *session; struct sc_pkcs11_object *object; - int res, res_type; + CK_RV res; + CK_RV res_type; unsigned int i; if (pTemplate == NULL_PTR || ulCount == 0) @@ -256,7 +258,7 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ * should be handled - we give them highest * precedence */ - for (j = 0; precedence[j] != -1; j++) { + for (j = 0; precedence[j] != (CK_RV) -1; j++) { if (precedence[j] == res) break; } @@ -1325,14 +1327,13 @@ CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, /* the session's handle */ /* * Helper function to compare attributes on any sort of object */ -int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK_ATTRIBUTE_PTR attr) +CK_RV sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK_ATTRIBUTE_PTR attr) { - int rv; + CK_RV rv; struct sc_pkcs11_object *object; u8 temp1[1024]; u8 *temp2 = NULL; /* dynamic allocation for large attributes */ CK_ATTRIBUTE temp_attr; - int res; object = (struct sc_pkcs11_object *)ptr; temp_attr.type = attr->type; @@ -1356,7 +1357,7 @@ int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK /* Get the attribute */ rv = object->ops->get_attribute(session, object, &temp_attr); if (rv != CKR_OK) { - res = 0; + rv = 0; goto done; } #ifdef DEBUG @@ -1367,12 +1368,12 @@ int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK dump_template(SC_LOG_DEBUG_NORMAL, foo, &temp_attr, 1); } #endif - res = temp_attr.ulValueLen == attr->ulValueLen + rv = temp_attr.ulValueLen == attr->ulValueLen && !memcmp(temp_attr.pValue, attr->pValue, attr->ulValueLen); done: if (temp2 != NULL) free(temp2); - return res; + return rv; } diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 9351e58db3..e42474469b 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -313,7 +313,7 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = push_login_state(slot, userType, pPin, ulPinLen); if (rv == CKR_OK) { - slot->login_user = userType; + slot->login_user = (int) userType; } rv = reset_login_state(slot, rv); } diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index a3fa1d8f80..92e635cc6f 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -55,7 +55,7 @@ static CK_RV init_spy(void) { const char *output, *module; - int rv = CKR_OK; + CK_RV rv = CKR_OK; #ifdef _WIN32 char temp_path[PATH_MAX], expanded_path[PATH_MAX]; DWORD temp_len, expanded_len; diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index f0115ed04b..6ed20d8ad2 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -91,7 +91,7 @@ struct sc_pkcs11_object_ops { /* Management methods */ CK_RV (*set_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR); CK_RV (*get_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR); - int (*cmp_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR); + CK_RV (*cmp_attribute)(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR); CK_RV (*destroy_object)(struct sc_pkcs11_session *, void *); CK_RV (*get_size)(struct sc_pkcs11_session *, void *); @@ -382,7 +382,7 @@ CK_RV sc_pkcs11_create_secret_key(struct sc_pkcs11_session *, CK_ATTRIBUTE_PTR, CK_ULONG, struct sc_pkcs11_object **); /* Generic object handling */ -int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *, +CK_RV sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *, void *, CK_ATTRIBUTE_PTR); /* Get attributes from template (misc.c) */ @@ -439,11 +439,11 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *, sc_pkcs11_mechanism_type_t *); #ifdef ENABLE_OPENSSL -CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - const unsigned char *pubkey_params, int pubkey_params_len, +CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, + const unsigned char *pubkey_params, unsigned int pubkey_params_len, CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *inp, int inp_len, - unsigned char *signat, int signat_len); + unsigned char *inp, unsigned int inp_len, + unsigned char *signat, unsigned int signat_len); #endif /* Load configuration defaults */ diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 3102bf986a..c374666f4d 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -447,7 +447,7 @@ CK_RV slot_get_slot(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot) CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot) { - int rv; + CK_RV rv; sc_log(context, "Slot(id=0x%lX): get token", id); rv = slot_get_slot(id, slot); @@ -473,7 +473,8 @@ CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot) CK_RV slot_token_removed(CK_SLOT_ID id) { - int rv, token_was_present; + CK_RV rv; + int token_was_present; struct sc_pkcs11_slot *slot; struct sc_pkcs11_object *object; From c70888f9ab674c468c99f72ece4a7556c1e63a30 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 31 Oct 2018 23:34:14 +0100 Subject: [PATCH 0602/4321] allow compilation with --disable-shared --- src/libopensc/card-npa.c | 1 + src/libopensc/card-npa.h | 4 ++-- src/tools/npa-tool.c | 25 +++++++++++++------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 99784b1723..c8e981f5c0 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -31,6 +31,7 @@ #include "sm/sm-eac.h" #include +static int fread_to_eof(const char *file, unsigned char **buf, size_t *buflen); #include "../tools/fread_to_eof.c" struct npa_drv_data { diff --git a/src/libopensc/card-npa.h b/src/libopensc/card-npa.h index 5cac5b0a66..9cce7a06af 100644 --- a/src/libopensc/card-npa.h +++ b/src/libopensc/card-npa.h @@ -27,13 +27,13 @@ extern "C" { #include "sm/sm-eac.h" -const unsigned char esign_chat[] = { +static const unsigned char esign_chat[] = { 0x7F, 0x4C, 0x0E, 0x06, 0x09, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x03, 0x01, 0x02, 0x03, 0x53, 0x01, 0x03, }; -const unsigned char df_esign_aid[] = { 0xa0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4e}; +static const unsigned char df_esign_aid[] = { 0xa0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4e}; /** * @brief Sends a reset retry counter APDU diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 1371c6963e..a4e14a4c5c 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -88,14 +88,15 @@ static int getline(char **lineptr, size_t *n, FILE *stream) #define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type) #define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type) +typedef ASN1_AUXILIARY_DATA ASN1_AUXILIARY_DATA_NPA_TOOL; /* 0x67 * Auxiliary authenticated data */ -ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) = +ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA_NPA_TOOL) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, 7, AuxiliaryAuthenticatedData, CVC_DISCRETIONARY_DATA_TEMPLATE) -ASN1_ITEM_TEMPLATE_END(ASN1_AUXILIARY_DATA) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) +ASN1_ITEM_TEMPLATE_END(ASN1_AUXILIARY_DATA_NPA_TOOL) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA_NPA_TOOL) /** * @brief Print binary data to a file stream @@ -285,8 +286,8 @@ int npa_translate_apdus(sc_card_t *card, FILE *input) return r; } -static int add_to_ASN1_AUXILIARY_DATA( - ASN1_AUXILIARY_DATA **auxiliary_data, +static int add_to_ASN1_AUXILIARY_DATA_NPA_TOOL( + ASN1_AUXILIARY_DATA_NPA_TOOL **auxiliary_data, int nid, const unsigned char *data, size_t data_len) { int r; @@ -298,7 +299,7 @@ static int add_to_ASN1_AUXILIARY_DATA( } if (!*auxiliary_data) { - *auxiliary_data = ASN1_AUXILIARY_DATA_new(); + *auxiliary_data = ASN1_AUXILIARY_DATA_NPA_TOOL_new(); if (!*auxiliary_data) { r = SC_ERROR_INTERNAL; goto err; @@ -372,7 +373,7 @@ main (int argc, char **argv) unsigned char *certs_chat = NULL; unsigned char *dg = NULL; size_t dg_len = 0; - ASN1_AUXILIARY_DATA *templates = NULL; + ASN1_AUXILIARY_DATA_NPA_TOOL *templates = NULL; unsigned char *ef_cardsecurity = NULL; size_t ef_cardsecurity_len = 0; @@ -671,7 +672,7 @@ main (int argc, char **argv) } } else { if (cmdline.older_than_given) { - r = add_to_ASN1_AUXILIARY_DATA(&templates, + r = add_to_ASN1_AUXILIARY_DATA_NPA_TOOL(&templates, NID_id_DateOfBirth, (unsigned char *) cmdline.older_than_arg, strlen(cmdline.older_than_arg)); @@ -679,7 +680,7 @@ main (int argc, char **argv) goto err; } if (cmdline.verify_validity_given) { - r = add_to_ASN1_AUXILIARY_DATA(&templates, + r = add_to_ASN1_AUXILIARY_DATA_NPA_TOOL(&templates, NID_id_DateOfExpiry, (unsigned char *) cmdline.verify_validity_arg, strlen(cmdline.verify_validity_arg)); @@ -693,7 +694,7 @@ main (int argc, char **argv) fprintf(stderr, "Could not parse community ID.\n"); exit(2); } - r = add_to_ASN1_AUXILIARY_DATA(&templates, + r = add_to_ASN1_AUXILIARY_DATA_NPA_TOOL(&templates, NID_id_CommunityID, community_id, community_id_len); if (r < 0) @@ -701,7 +702,7 @@ main (int argc, char **argv) } if (templates) { unsigned char *p = NULL; - auxiliary_data_len = i2d_ASN1_AUXILIARY_DATA( + auxiliary_data_len = i2d_ASN1_AUXILIARY_DATA_NPA_TOOL( templates, &p); if (0 > (int) auxiliary_data_len || auxiliary_data_len > sizeof auxiliary_data) { @@ -892,7 +893,7 @@ main (int argc, char **argv) free(privkey); free(dg); if (templates) - ASN1_AUXILIARY_DATA_free(templates); + ASN1_AUXILIARY_DATA_NPA_TOOL_free(templates); sc_sm_stop(card); sc_reset(card, 1); From 26025b2f5d816e514310429b2cd6aae7e9e30700 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Thu, 1 Nov 2018 08:46:02 +0100 Subject: [PATCH 0603/4321] pkcs15-tool: list & dump cleanups * when listing public keys, do not cut object labels in compact mode * when listing private keys in compact mode, left align labels * make hex codes at least 2 chars wide by changing "0x%X" to "0x%02X" --- src/tools/pkcs15-tool.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 019ab8c045..289a95e950 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -253,7 +253,7 @@ static void print_common_flags(const struct sc_pkcs15_object *obj) { const char *common_flags[] = {"private", "modifiable"}; unsigned int i; - printf("\tObject Flags : [0x%X]", obj->flags); + printf("\tObject Flags : [0x%02X]", obj->flags); for (i = 0; i < NELEMENTS(common_flags); i++) { if (obj->flags & (1 << i)) { printf(", %s", common_flags[i]); @@ -620,7 +620,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) printf(" Ref:0x%02X", prkey->key_reference); if (obj->auth_id.len != 0) printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id)); - printf("\n\t %-16.*s [0x%X", 16, obj->label, prkey->usage); + printf("\n\t %-18.*s [0x%02X", (int) sizeof obj->label, obj->label, prkey->usage); print_key_usages(prkey->usage); printf("]"); return; @@ -628,10 +628,10 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) printf("Private %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label); print_common_flags(obj); - printf("\tUsage : [0x%X]", prkey->usage); + printf("\tUsage : [0x%02X]", prkey->usage); print_key_usages(prkey->usage); printf("\n"); - printf("\tAccess Flags : [0x%X]", prkey->access_flags); + printf("\tAccess Flags : [0x%02X]", prkey->access_flags); print_key_access_flags(prkey->access_flags); printf("\n"); @@ -641,7 +641,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) printf("\tModLength : %lu\n", (unsigned long)prkey->modulus_length); else printf("\tFieldLength : %lu\n", (unsigned long)prkey->field_length); - printf("\tKey ref : %d (0x%X)\n", prkey->key_reference, prkey->key_reference); + printf("\tKey ref : %d (0x%02X)\n", prkey->key_reference, prkey->key_reference); printf("\tNative : %s\n", prkey->native ? "yes" : "no"); if (prkey->path.len || prkey->path.aid.len) printf("\tPath : %s\n", sc_print_path(&prkey->path)); @@ -701,7 +701,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj) printf(" Ref:0x%02X", pubkey->key_reference); if (obj->auth_id.len != 0) printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id)); - printf(" %15.*s [0x%X", (int) sizeof obj->label, obj->label, pubkey->usage); + printf(" %-18.*s [0x%02X", (int) sizeof obj->label, obj->label, pubkey->usage); print_key_usages(pubkey->usage); printf("]"); return; @@ -709,11 +709,11 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj) printf("Public %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label); print_common_flags(obj); - printf("\tUsage : [0x%X]", pubkey->usage); + printf("\tUsage : [0x%02X]", pubkey->usage); print_key_usages(pubkey->usage); printf("\n"); - printf("\tAccess Flags : [0x%X]", pubkey->access_flags); + printf("\tAccess Flags : [0x%02X]", pubkey->access_flags); print_key_access_flags(pubkey->access_flags); printf("\n"); @@ -733,7 +733,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj) } } - printf("\tKey ref : %d (0x%X)\n", pubkey->key_reference, pubkey->key_reference); + printf("\tKey ref : %d (0x%02X)\n", pubkey->key_reference, pubkey->key_reference); printf("\tNative : %s\n", pubkey->native ? "yes" : "no"); if (have_path) printf("\tPath : %s\n", sc_print_path(&pubkey->path)); @@ -840,11 +840,11 @@ static void print_skey_info(const struct sc_pkcs15_object *obj) printf("Secret %s Key [%.*s]\n", skey_types[7 & obj->type], (int) sizeof obj->label, obj->label); print_common_flags(obj); - printf("\tUsage : [0x%X]", skey->usage); + printf("\tUsage : [0x%02X]", skey->usage); print_key_usages(skey->usage); printf("\n"); - printf("\tAccess Flags : [0x%X]", skey->access_flags); + printf("\tAccess Flags : [0x%02X]", skey->access_flags); print_key_access_flags(skey->access_flags); printf("\n"); @@ -853,7 +853,7 @@ static void print_skey_info(const struct sc_pkcs15_object *obj) printf("\tSize : %lu bits\n", (unsigned long)skey->value_len); printf("\tID : %s\n", sc_pkcs15_print_id(&skey->id)); printf("\tNative : %s\n", skey->native ? "yes" : "no"); - printf("\tKey ref : %d (0x%X)\n", skey->key_reference, skey->key_reference); + printf("\tKey ref : %d (0x%02X)\n", skey->key_reference, skey->key_reference); if (skey->path.len || skey->path.aid.len) printf("\tPath : %s\n", sc_print_path(&skey->path)); From b35fb19ec46df21c35864725a6d2b1e5c55e0d0c Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 2 Nov 2018 13:28:51 +0200 Subject: [PATCH 0604/4321] Resolved conflict in pkcs15_create_secret_key --- src/pkcs11/framework-pkcs15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ec2d5a6b14..5360e54d57 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2225,7 +2225,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15_skey_info *skey_info; CK_KEY_TYPE key_type; CK_BBOOL _token = FALSE; - int rv, rc; + CK_RV rv; + int rc; char label[SC_PKCS15_MAX_LABEL_SIZE]; CK_BBOOL temp_object = FALSE; From f276f7f8f491492c0ebc74fe8ca2c39333eae3f8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 11:41:47 +0100 Subject: [PATCH 0605/4321] coverity: Add allocation check *** CID 323588: Uninitialized variables (UNINIT) /src/libopensc/sc.c: 873 in sc_mem_secure_alloc() --- src/libopensc/sc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 2052998b1f..b18c937f7a 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -867,6 +867,9 @@ void *sc_mem_secure_alloc(size_t len) } p = malloc(len); + if (p == NULL) { + return NULL; + } #ifdef _WIN32 VirtualLock(p, len); #else From 7cced08a882a5f22b217b967ff5fa60457a01051 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 11:46:37 +0100 Subject: [PATCH 0606/4321] coolkey: Check return values from list initialization (coverity) >>> CID 324484: Error handling issues (CHECKED_RETURN) >>> Calling "list_init" without checking return value (as is done elsewhere 8 out of 9 times). --- src/libopensc/card-coolkey.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index c1c09b662d..e320290dfe 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -784,18 +784,25 @@ size_t coolkey_list_meter(const void *el) { return sizeof(sc_cardctl_coolkey_object_t); } +static void coolkey_free_private_data(coolkey_private_data_t *priv); + static coolkey_private_data_t *coolkey_new_private_data(void) { coolkey_private_data_t *priv; + /* allocate priv and zero all the fields */ priv = calloc(1, sizeof(coolkey_private_data_t)); if (!priv) return NULL; + /* set other fields as appropriate */ priv->key_id = COOLKEY_INVALID_KEY; - list_init(&priv->objects_list); - list_attributes_comparator(&priv->objects_list, coolkey_compare_id); - list_attributes_copy(&priv->objects_list, coolkey_list_meter, 1); + if (list_init(&priv->objects_list) != 0 || + list_attributes_comparator(&priv->objects_list, coolkey_compare_id) != 0 || + list_attributes_copy(&priv->objects_list, coolkey_list_meter, 1) != 0) { + coolkey_free_private_data(priv); + return NULL; + } return priv; } From 7e0ef7c16c99f80bb90292ea3190eca5b426e251 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 15:02:00 +0100 Subject: [PATCH 0607/4321] framework-pkcs15.c: Reformat * Reasonable line lengths * Correct indentation * Add missing SHA224 mechanism --- src/pkcs11/framework-pkcs15.c | 40 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 0fcb157619..3f190a4947 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5171,14 +5171,14 @@ register_mechanisms(struct sc_pkcs11_card *p11card) } #ifdef ENABLE_OPENSSL - /* all our software hashes are in OpenSSL */ - /* Only if card did not list the hashes, will we - * help it a little, by adding all the OpenSSL hashes - * that have PKCS#11 mechanisms. - */ - if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { - rsa_flags |= SC_ALGORITHM_RSA_HASHES; - } + /* all our software hashes are in OpenSSL */ + /* Only if card did not list the hashes, will we + * help it a little, by adding all the OpenSSL hashes + * that have PKCS#11 mechanisms. + */ + if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { + rsa_flags |= SC_ALGORITHM_RSA_HASHES; + } #endif /* No need to Check for PKCS1 We support it in software and turned it on above so always added it */ @@ -5194,32 +5194,44 @@ register_mechanisms(struct sc_pkcs11_card *p11card) * Either the card set the hashes or we helped it above */ if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt); + if (rc != CKR_OK) + return rc; + } + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA224_RSA_PKCS, CKM_SHA224, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA256_RSA_PKCS, CKM_SHA256, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA256_RSA_PKCS, CKM_SHA256, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA384_RSA_PKCS, CKM_SHA384, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA384_RSA_PKCS, CKM_SHA384, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA512_RSA_PKCS, CKM_SHA512, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_SHA512_RSA_PKCS, CKM_SHA512, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_MD5) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_MD5_RSA_PKCS, CKM_MD5, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_MD5_RSA_PKCS, CKM_MD5, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) { - rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); + rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, + CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); if (rc != CKR_OK) return rc; } From d2671ee05b45163dbd3f7fe78ded9de7f00a5d95 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 15:03:40 +0100 Subject: [PATCH 0608/4321] framework-pkcs15.c: Add PKCS#1 mechanisms also if SC_ALGORITHM_RSA_HASH_NONE is defined --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3f190a4947..cd072fa223 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5176,7 +5176,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) * help it a little, by adding all the OpenSSL hashes * that have PKCS#11 mechanisms. */ - if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { + if (!(rsa_flags & (SC_ALGORITHM_RSA_HASHES & ~SC_ALGORITHM_RSA_HASH_NONE))) { rsa_flags |= SC_ALGORITHM_RSA_HASHES; } #endif From 8ccc39352ab14d1817e3250b517c42207a684efd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 15:35:25 +0100 Subject: [PATCH 0609/4321] p11test: Do not report incomplete key pairs --- src/tests/p11test/p11test_case_pss_oaep.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index d0b8392fd2..0194711924 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -815,6 +815,10 @@ void pss_oaep_test(void **state) { for (i = 0; i < objects.count; i++) { test_cert_t *o = &objects.data[i]; + /* Do not go through incomplete pairs */ + if (o->private_handle == CK_INVALID_HANDLE) + continue; + /* Do not list non-RSA keys here */ if (o->type != EVP_PK_RSA) continue; From 0f5d73d81641044d298d7bd1c1361e88fc2ca5d5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 15:39:56 +0100 Subject: [PATCH 0610/4321] framework-pkcs15.c: Add SHA224 mechanism for PKCS#1.5 --- src/pkcs11/framework-pkcs15.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cd072fa223..5cea38b6fa 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3792,6 +3792,9 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, case CKM_SHA1_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; break; + case CKM_SHA224_RSA_PKCS: + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA224; + break; case CKM_SHA256_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; break; From 9342f8ad0adf1b933e0a0660932bd13b1cc83826 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 Oct 2018 17:50:08 +0100 Subject: [PATCH 0611/4321] padding: Fix error checking in RSA-PSS --- src/libopensc/padding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 75c92b651a..f0e2263b80 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -345,7 +345,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, if (EVP_DigestInit_ex(ctx, mgf1_md, NULL) != 1 || EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */ EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */ - EVP_DigestFinal_ex(ctx, mask, NULL)) { + EVP_DigestFinal_ex(ctx, mask, NULL) != 1) { goto done; } /* this is no longer part of the MGF1, but actually From eaed345a767b0adf5029bffb0cc653d9f19fd919 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 3 Nov 2018 10:54:12 +0100 Subject: [PATCH 0612/4321] Add missing header file to the tarball --- src/libopensc/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 5a17df2b1d..e1e23cba03 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -12,7 +12,8 @@ noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem. errors.h types.h compression.h itacns.h iso7816.h \ authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \ pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ - jpki.h sc-ossl-compat.h card-npa.h ccid-types.h reader-tr03119.h + jpki.h sc-ossl-compat.h card-npa.h ccid-types.h reader-tr03119.h \ + card-cac-common.h AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ -D'DEFAULT_SM_MODULE_PATH="$(DEFAULT_SM_MODULE_PATH)"' \ From 13c75745103bdc35168c223c6fcc900be15954b0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 28 Sep 2018 21:31:55 +0200 Subject: [PATCH 0613/4321] PIV: less debugging - debugging pointers is useless in static log file - removed double debugging of APDUs --- src/libopensc/card-piv.c | 44 ++++++---------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a678b768e4..03c83868f1 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -535,16 +535,9 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, apdu.resplen = 0; } - sc_log(card->ctx, - "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p", - apdu.flags, apdu.le, apdu.resplen, apdu.resp); - /* with new adpu.c and chaining, this actually reads the whole object */ r = sc_transmit_apdu(card, &apdu); - sc_log(card->ctx, - "DEE r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x", - r, apdu.resplen, apdu.sw1, apdu.sw2); if (r < 0) { sc_log(card->ctx, "Transmit failed"); goto err; @@ -731,9 +724,6 @@ static int piv_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, int r; LOG_FUNC_CALLED(card->ctx); - sc_log(card->ctx, - "Got args: aid=%p, aidlen=%"SC_FORMAT_LEN_SIZE_T"u, response=%p, responselen=%"SC_FORMAT_LEN_SIZE_T"u", - aid, aidlen, response, responselen ? *responselen : 0); sc_format_apdu(card, &apdu, response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); @@ -1197,9 +1187,6 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co r = SC_ERROR_FILE_NOT_FOUND; goto err; } - sc_log(card->ctx, - "DEE rbuf=%p,rbuflen=%"SC_FORMAT_LEN_SIZE_T"u,", - rbuf, rbuflen); body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, rbuf[0], &bodylen); if (body == NULL) { /* if missing, assume its the body */ @@ -1298,7 +1285,6 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon size_t sbuflen; size_t taglen; - sc_log(card->ctx, "DEE cert len=%"SC_FORMAT_LEN_SIZE_T"u", count); taglen = put_tag_and_len(0x70, count, NULL) + put_tag_and_len(0x71, 1, NULL) + put_tag_and_len(0xFE, 0, NULL); @@ -1319,9 +1305,6 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon *p++ = (flags)? 0x01:0x00; /* certinfo, i.e. gzipped? */ put_tag_and_len(0xFE,0,&p); /* LRC tag */ - sc_log(card->ctx, "DEE buf %p len %"SC_FORMAT_LEN_PTRDIFF_T"u %"SC_FORMAT_LEN_SIZE_T"u", - sbuf, p - sbuf, sbuflen); - enumtag = piv_objects[priv->selected_obj].enumtag; r = piv_put_data(card, enumtag, sbuf, sbuflen); if (sbuf) @@ -2194,7 +2177,6 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) u8 * opts; /* A or M, key_ref, alg_id */ LOG_FUNC_CALLED(card->ctx); - sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr); if (priv == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -2603,14 +2585,12 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a goto err; } - sc_log(card->ctx, - "Discovery 0x%2.2x 0x%2.2x %p:%"SC_FORMAT_LEN_SIZE_T"u", - cla_out, tag_out, body, bodylen); - if ( cla_out+tag_out == 0x7E && body != NULL && bodylen != 0) { - aidlen = 0; - aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen); - sc_log(card->ctx, "Discovery aid=%p:%"SC_FORMAT_LEN_SIZE_T"u", - aid, aidlen); + sc_log(card->ctx, + "Discovery 0x%2.2x 0x%2.2x %p:%"SC_FORMAT_LEN_SIZE_T"u", + cla_out, tag_out, body, bodylen); + if ( cla_out+tag_out == 0x7E && body != NULL && bodylen != 0) { + aidlen = 0; + aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen); if (aid == NULL || aidlen < piv_aids[0].len_short || memcmp(aid,piv_aids[0].value,piv_aids[0].len_short) != 0) { /*TODO look at long */ sc_log(card->ctx, "Discovery object not PIV"); @@ -2619,9 +2599,6 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a } if (aid_only == 0) { pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen); - sc_log(card->ctx, - "Discovery pinp=%p:%"SC_FORMAT_LEN_SIZE_T"u", - pinp, pinplen); if (pinp && pinplen == 2) { sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); r = SC_SUCCESS; @@ -2651,8 +2628,6 @@ static int piv_process_discovery(sc_card_t *card) if (r < 0) goto err; - sc_log(card->ctx, "Discovery = %p:%"SC_FORMAT_LEN_SIZE_T"u", rbuf, - rbuflen); /* the object is now cached, see what we have */ r = piv_parse_discovery(card, rbuf, rbuflen, 0); @@ -2933,13 +2908,6 @@ piv_finish(sc_card_t *card) if (priv->offCardCertURL) free(priv->offCardCertURL); for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++) { - sc_log(card->ctx, - "DEE freeing #%d, 0x%02x %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", - i, priv->obj_cache[i].flags, - priv->obj_cache[i].obj_data, - priv->obj_cache[i].obj_len, - priv->obj_cache[i].internal_obj_data, - priv->obj_cache[i].internal_obj_len); if (priv->obj_cache[i].obj_data) free(priv->obj_cache[i].obj_data); if (priv->obj_cache[i].internal_obj_data) From 99a90298485029173f9065420d8d9e187ccf5c01 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 15 Oct 2018 13:52:24 +0200 Subject: [PATCH 0614/4321] md: use constants for AlgId comparison --- src/minidriver/minidriver.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index bc1c58d1c3..ef79d23203 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4706,19 +4706,19 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; } else { - if (wcscmp(pinf->pszAlgId, L"MD5") == 0) + if (wcscmp(pinf->pszAlgId, BCRYPT_MD5_ALGORITHM) == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; - else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0) + else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; - else if (wcscmp(pinf->pszAlgId, L"SHA256") == 0) + else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; - else if (wcscmp(pinf->pszAlgId, L"SHA384") == 0) + else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; - else if (wcscmp(pinf->pszAlgId, L"SHA512") == 0) + else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; From 263b945f624b07159344465ce29534618834366f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 15 Oct 2018 15:14:14 +0200 Subject: [PATCH 0615/4321] md: added support for PSS --- src/minidriver/minidriver.c | 78 ++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index ef79d23203..b02be8ee5a 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4699,34 +4699,66 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO case CARD_PADDING_PKCS1: opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; - BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; + BCRYPT_PKCS1_PADDING_INFO *pkcs1_pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; - if (!pinf->pszAlgId) { + if (!pkcs1_pinf->pszAlgId || wcscmp(pkcs1_pinf->pszAlgId, L"SHAMD5") == 0) { /* hashAlg = CALG_SSL3_SHAMD5; */ logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + } else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_MD5_ALGORITHM) == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; + else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; + else if (wcscmp(pkcs1_pinf->pszAlgId, L"SHA224") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; + else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; + else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; + else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; + else if (wcscmp(pkcs1_pinf->pszAlgId, L"RIPEMD160") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; + else { + logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pkcs1_pinf->pszAlgId)); + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } + break; + + case CARD_PADDING_PSS: + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PSS; + BCRYPT_PSS_PADDING_INFO *pss_pinf = (BCRYPT_PSS_PADDING_INFO *)pInfo->pPaddingInfo; + ULONG expected_salt_len; + + if (!pss_pinf->pszAlgId || wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0) { + /* hashAlg = CALG_SHA1; */ + logprintf(pCardData, 3, "Using CALG_SHA1 hashAlg\n"); + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; + expected_salt_len = 160; + } else if (wcscmp(pss_pinf->pszAlgId, L"SHA224") == 0) { + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; + expected_salt_len = 224; + } else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0) { + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; + expected_salt_len = 256; + } else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0) { + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; + expected_salt_len = 384; + } else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0) { + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; + expected_salt_len = 512; } else { - if (wcscmp(pinf->pszAlgId, BCRYPT_MD5_ALGORITHM) == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; - else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; - else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; - else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; - else if (wcscmp(pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; - else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) - opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; - else { - logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); - dwret = SCARD_E_UNSUPPORTED_FEATURE; - goto err; - } + logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pss_pinf->pszAlgId)); + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } + /* We're strict, and only do PSS signatures with a salt length that + * matches the digest length (any shorter is rubbish, any longer + * is useless). */ + if (pss_pinf->cbSalt != expected_salt_len / 8) { + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } break; From 1866c3e930a8523c74c25a025fa2220b11b4b36a Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Mon, 12 Oct 2015 23:26:54 +0200 Subject: [PATCH 0616/4321] openpgp-tool: new option --card-info to display card info --- doc/tools/openpgp-tool.1.xml | 10 ++ src/tools/openpgp-tool.c | 274 ++++++++++++++++++++++++++++------- 2 files changed, 228 insertions(+), 56 deletions(-) diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index ca59b89ca7..32283df201 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -38,6 +38,16 @@ Options + + + , + + + + Show card information. + + + arg diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 0a6f09416e..627b30ca82 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -35,6 +35,7 @@ #endif #include #include +#include #include "common/compat_getopt.h" #include "libopensc/opensc.h" @@ -52,22 +53,35 @@ #define OPT_PIN 259 #define OPT_DELKEY 260 +enum code_types { + TYPE_NULL, + TYPE_HEX, + TYPE_STRING +}; + /* define structures */ struct ef_name_map { const char *name; const char *env_name; const char *ef; - char *(*prettify_value)(char *); + enum code_types type; + size_t offset; + size_t length; /* exact length: 0 <=> potentially infinite */ + char *(*prettify_value)(u8 *, size_t); }; /* declare functions */ static void show_version(void); -static char *prettify_name(char *str); -static char *prettify_language(char *str); -static char *prettify_gender(char *str); -static void display_data(const struct ef_name_map *mapping, char *value); +static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen); +static char *prettify_version(u8 *data, size_t length); +static char *prettify_manufacturer(u8 *data, size_t length); +static char *prettify_serialnumber(u8 *data, size_t length); +static char *prettify_name(u8 *data, size_t length); +static char *prettify_language(u8 *data, size_t length); +static char *prettify_gender(u8 *data, size_t length); +static void display_data(const struct ef_name_map *mapping, u8 *data, size_t length); static int decode_options(int argc, char **argv); -static int do_userinfo(sc_card_t *card); +static int do_info(sc_card_t *card, const struct ef_name_map *map); /* define global variables */ static int actions = 0; @@ -119,7 +133,7 @@ static const char *option_help[] = { /* x */ "Execute program with data in env vars", "Print values in raw format", "Print values in pretty format", -/* C */ NULL, +/* C */ "Show card information", /* U */ "Show card holder information", /* G */ "Generate key", /* L */ "Key length (default 2048)", @@ -133,17 +147,26 @@ static const char *option_help[] = { /* d */ "Dump private data object number (i.e. DO )", }; -static const struct ef_name_map openpgp_data[] = { - { "Account", "OPENGPG_ACCOUNT", "3F00:005E", NULL }, - { "URL", "OPENPGP_URL", "3F00:5F50", NULL }, - { "Name", "OPENPGP_NAME", "3F00:0065:005B", prettify_name }, - { "Language", "OPENPGP_LANG", "3F00:0065:5F2D", prettify_language }, - { "Gender", "OPENPGP_GENDER", "3F00:0065:5F35", prettify_gender }, - { "DO 0101", "OPENPGP_DO0101", "3F00:0101", NULL }, - { "DO 0102", "OPENPGP_DO0102", "3F00:0102", NULL }, -// { "DO 0103", "OPENPGP_DO0103", "3F00:0103", NULL }, -// { "DO 0104", "OPENPGP_DO0104", "3F00:0104", NULL }, - { NULL, NULL, NULL, NULL } + +static const struct ef_name_map card_data[] = { + { "AID", "OPENPGP_AID", "3F00:004F", TYPE_HEX, 0, 16, NULL }, + { "Version", "OPENPGP_VERSION", "3F00:004F", TYPE_HEX, 6, 2, prettify_version }, + { "Manufacturer", "OPENPGP_MANUFACTURER", "3F00:004F", TYPE_HEX, 8, 2, prettify_manufacturer }, + { "Serial number", "OPENPGP_SERIALNO", "3F00:004F", TYPE_HEX, 10, 4, prettify_serialnumber }, + { NULL, NULL, NULL, TYPE_NULL, 0, 0, NULL } +}; + +static const struct ef_name_map user_data[] = { + { "Account", "OPENGPG_ACCOUNT", "3F00:005E", TYPE_STRING, 0, 0, NULL }, + { "URL", "OPENPGP_URL", "3F00:5F50", TYPE_STRING, 0, 0, NULL }, + { "Name", "OPENPGP_NAME", "3F00:0065:005B", TYPE_STRING, 0, 0, prettify_name }, + { "Language", "OPENPGP_LANG", "3F00:0065:5F2D", TYPE_STRING, 0, 0, prettify_language }, + { "Gender", "OPENPGP_GENDER", "3F00:0065:5F35", TYPE_STRING, 0, 0, prettify_gender }, + { "DO 0101", "OPENPGP_DO0101", "3F00:0101", TYPE_STRING, 0, 0, NULL }, + { "DO 0102", "OPENPGP_DO0102", "3F00:0102", TYPE_STRING, 0, 0, NULL }, +// { "DO 0103", "OPENPGP_DO0103", "3F00:0103", TYPE_STRING, 0, 0, NULL }, +// { "DO 0104", "OPENPGP_DO0104", "3F00:0104", TYPE_STRING, 0, 0, NULL }, + { NULL, NULL, NULL, TYPE_NULL, 0, 0, NULL } }; @@ -152,37 +175,133 @@ static void show_version(void) fprintf(stderr, "openpgp-tool - OpenPGP card utility version " PACKAGE_VERSION "\n" "\n" - "Copyright (c) 2012 Peter Marschall \n" + "Copyright (c) 2012-18 Peter Marschall \n" "Licensed under LGPL v2\n"); } +/* prettify hex */ +static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) +{ + if (data != NULL) { + int r = sc_bin_to_hex(data, length, buffer, buflen, ':'); + + if (r == SC_SUCCESS) { + char *ptr; + + /* upper-case the hex-ified string */ + for (ptr = buffer; *ptr != '\0'; ptr++) + *ptr = toupper(*ptr); + + return buffer; + } + } + return NULL; +} + + +#define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) + +/* prettify OpenPGP card version */ +static char *prettify_version(u8 *data, size_t length) +{ + if (data != NULL && length >= 2) { + static char result[10]; /* large enough for even 2*3 digits + separator */ + int major = BCD2CHAR(data[0]); + int minor = BCD2CHAR(data[1]); + + sprintf(result, "%d.%d", major, minor); + return result; + } + return NULL; +} + + +/* prettify manufacturer */ +static char *prettify_manufacturer(u8 *data, size_t length) +{ + if (data != NULL && length >= 2) { + unsigned int manuf = (data[0] << 8) + data[1]; + + switch (manuf) { + case 0x0001: return "PPC Card Systems"; + case 0x0002: return "Prism"; + case 0x0003: return "OpenFortress"; + case 0x0004: return "Wewid"; + case 0x0005: return "ZeitControl"; + case 0x0006: return "Yubico"; + case 0x0007: return "OpenKMS"; + case 0x0008: return "LogoEmail"; + case 0x0009: return "Fidesmo"; + case 0x000A: return "Dangerous Things"; + + case 0x002A: return "Magrathea"; + case 0x0042: return "GnuPG e.V."; + + case 0x1337: return "Warsaw Hackerspace"; + case 0x2342: return "warpzone"; /* hackerspace Muenster. */ + case 0x63AF: return "Trustica"; + case 0xBD0E: return "Paranoidlabs"; + case 0xF517: return "FSIJ"; + + /* 0x0000 and 0xFFFF are defined as test cards per spec, + 0xFF00 to 0xFFFE are assigned for use with randomly created + serial numbers. */ + case 0x0000: + case 0xffff: return "test card"; + default: return (manuf & 0xff00) == 0xff00 ? "unmanaged S/N range" : "unknown"; + } + } + return NULL; +} + + +/* prettify pure serial number */ +static char *prettify_serialnumber(u8 *data, size_t length) +{ + if (data != NULL && length >= 4) { + static char result[15]; /* large enough for even 2*3 digits + separator */ + unsigned int serial = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + + sprintf(result, "%08X", serial); + return result; + } + return NULL; +} + + /* prettify card holder's name */ -static char *prettify_name(char *str) +static char *prettify_name(u8 *data, size_t length) { - if (str != NULL) { - char *src = str; - char *dst = str; + if (data != NULL && length > 0) { + char *src = (char *) data; + char *dst = (char *) data; - while (*src != '\0') { + while (*src != '\0' && length > 0) { *dst = *src++; + length--; if (*dst == '<') { - if (*src == '<') + if (*src == '<') { src++; + length--; + } *dst = ' '; } dst++; } *dst = '\0'; + return (char *) data; } - return str; + return NULL; } /* prettify language */ -static char *prettify_language(char *str) +static char *prettify_language(u8 *data, size_t length) { - if (str != NULL) { + if (data != NULL && length > 0) { + char *str = (char *) data; + switch (strlen(str)) { case 8: memmove(str+7, str+6, 1+strlen(str+6)); str[6] = ','; @@ -201,10 +320,10 @@ static char *prettify_language(char *str) /* convert the raw ISO-5218 SEX value to an english word */ -static char *prettify_gender(char *str) +static char *prettify_gender(u8 *data, size_t length) { - if (str != NULL) { - switch (*str) { + if (data != NULL && length > 0) { + switch (*data) { case '0': return "unknown"; case '1': return "male"; case '2': return "female"; @@ -215,28 +334,63 @@ static char *prettify_gender(char *str) } -static void display_data(const struct ef_name_map *mapping, char *value) +#define INDENT 16 + +static void display_data(const struct ef_name_map *map, u8 *data, size_t length) { - if (mapping != NULL && value != NULL) { - if (mapping->prettify_value != NULL && !opt_raw) - value = mapping->prettify_value(value); + if (map != NULL && data != NULL) { + char buffer[8192]; + char *value = NULL; + + if (opt_raw) { + /* length-wise safe, but may cut off data (safe for OpenPGP cards 2.x) */ + if (length > sizeof(buffer)) + length = sizeof(buffer); + + if (map->type == TYPE_HEX) { + if (exec_program) { + value = prettify_hex(data, length, buffer, sizeof(buffer)); + } + else { + sc_hex_dump(data, length, buffer, sizeof(buffer)); + /* remove trailing newline */ + if (*buffer != '\0' && buffer[strlen(buffer)-1] == '\n') + buffer[strlen(buffer)-1] = '\0'; + value = buffer; + } + } + else { + value = (char *) data; + } + } + else { + if (map->prettify_value != NULL) + value = map->prettify_value(data, length); + else { + value = (map->type == TYPE_HEX) + ? prettify_hex(data, length, buffer, sizeof(buffer)) + : (char *) data; + } + } if (value != NULL) { if (exec_program) { - char *envvar; + char *envvar= malloc(strlen(map->env_name) + + strlen(value) + 2); - envvar = malloc(strlen(mapping->env_name) + - strlen(value) + 2); if (envvar != NULL) { - strcpy(envvar, mapping->env_name); + strcpy(envvar, map->env_name); strcat(envvar, "="); strcat(envvar, value); putenv(envvar); + /* envvar deliberately kept: see putenv(3) */ } - } else { - const char *label = mapping->name; + } + else { + const char *label = map->name; + int fill = (int) (INDENT - strlen(label)); - printf("%s:%*s%s\n", label, (int)(10-strlen(label)), "", value); + printf("%s:%*s%s\n", label, fill, "", value); } } } @@ -339,22 +493,21 @@ static int decode_options(int argc, char **argv) } -static int do_userinfo(sc_card_t *card) +static int do_info(sc_card_t *card, const struct ef_name_map *map) { int i; - /* FIXME there are no length checks on buf. */ - unsigned char buf[2048]; + u8 buf[2048]; - for (i = 0; openpgp_data[i].ef != NULL; i++) { + for (i = 0; map[i].ef != NULL; i++) { sc_path_t path; sc_file_t *file; size_t count; int r; - sc_format_path(openpgp_data[i].ef, &path); + sc_format_path(map[i].ef, &path); r = sc_select_file(card, &path, &file); if (r) { - util_error("failed to select EF %s: %s", openpgp_data[i].ef, sc_strerror(r)); + util_error("failed to select EF %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } @@ -363,24 +516,30 @@ static int do_userinfo(sc_card_t *card) continue; if (count > sizeof(buf) - 1) { - util_error("too small buffer to read the OpenPGP data"); + util_error("too small buffer to read the OpenPGP map"); return EXIT_FAILURE; } r = sc_read_binary(card, 0, buf, count, 0); if (r < 0) { - util_error("failed to read %s: %s", openpgp_data[i].ef, sc_strerror(r)); + util_error("failed to read %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } - if (r != (signed)count) { + if (r != (signed) count || (size_t) r < map[i].offset + map[i].length) { util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d", - openpgp_data[i].ef, count, r); + map[i].ef, count, r); return EXIT_FAILURE; } + if (map[i].offset > 0) { + memmove(buf, buf + map[i].offset, map[i].length); + count -= map[i].offset; + } + if (map[i].length > 0 && count > map[i].length) + count = map[i].length; + if (map[i].type == TYPE_STRING) + buf[count] = '\0'; - buf[count] = '\0'; - - display_data(openpgp_data + i, (char *) buf); + display_data(&map[i], buf, count); } return EXIT_SUCCESS; @@ -647,8 +806,11 @@ int main(int argc, char **argv) if (!actions) opt_userinfo = 1; + if (opt_cardinfo) + exit_status |= do_info(card, card_data); + if (opt_userinfo) - exit_status |= do_userinfo(card); + exit_status |= do_info(card, user_data); if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); From c9f5e05acab57a3d039f8b14aec9b2b176ee8b54 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 23 Jun 2018 20:41:20 +0200 Subject: [PATCH 0617/4321] openpgp-tool: new option --key-info to display key info --- doc/tools/openpgp-tool.1.xml | 10 ++++++ src/tools/openpgp-tool.c | 67 +++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index 32283df201..dd9e893b86 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -121,6 +121,16 @@ + + + , + + + + Show information of keys on the card. + + + bitlength, diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 627b30ca82..08cbd0f884 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -73,6 +73,8 @@ struct ef_name_map { /* declare functions */ static void show_version(void); static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen); +static char *prettify_algorithm(u8 *data, size_t length); +static char *prettify_date(u8 *data, size_t length); static char *prettify_version(u8 *data, size_t length); static char *prettify_manufacturer(u8 *data, size_t length); static char *prettify_serialnumber(u8 *data, size_t length); @@ -91,6 +93,7 @@ static int opt_raw = 0; static int verbose = 0; static int opt_userinfo = 0; static int opt_cardinfo = 0; +static int opt_keyinfo = 0; static char *exec_program = NULL; static int opt_genkey = 0; static u8 key_id = 0; @@ -114,6 +117,7 @@ static const struct option options[] = { { "pretty", no_argument, NULL, OPT_PRETTY }, { "card-info", no_argument, NULL, 'C' }, { "user-info", no_argument, NULL, 'U' }, + { "key-info", no_argument, NULL, 'K' }, { "gen-key", required_argument, NULL, 'G' }, { "key-length",required_argument, NULL, 'L' }, { "help", no_argument, NULL, 'h' }, @@ -135,6 +139,7 @@ static const char *option_help[] = { "Print values in pretty format", /* C */ "Show card information", /* U */ "Show card holder information", +/* K */ "Show key information", /* G */ "Generate key", /* L */ "Key length (default 2048)", /* h */ "Print this help message", @@ -156,6 +161,19 @@ static const struct ef_name_map card_data[] = { { NULL, NULL, NULL, TYPE_NULL, 0, 0, NULL } }; +static const struct ef_name_map key_data[] = { + { "Aut Algorithm", "OPENPGP_AUT_ALGORITHM", "3F00:006E:0073:00C3", TYPE_HEX, 0, 0, prettify_algorithm }, + { "Aut Create Date", "OPENPGP_AUT_DATE", "3F00:006E:0073:00CD", TYPE_HEX, 8, 4, prettify_date }, + { "Aut Fingerprint", "OPENPGP_AUT_FP", "3F00:006E:0073:00C5", TYPE_HEX, 40, 20, NULL }, + { "Dec Algorithm", "OPENPGP_DEC_ALGORITHM", "3F00:006E:0073:00C2", TYPE_HEX, 0, 0, prettify_algorithm }, + { "Dec Create Date", "OPENPGP_DEC_DATE", "3F00:006E:0073:00CD", TYPE_HEX, 4, 4, prettify_date }, + { "Dec Fingerprint", "OPENPGP_DEC_FP", "3F00:006E:0073:00C5", TYPE_HEX, 20, 20, NULL }, + { "Sig Algorithm", "OPENPGP_SIG_ALGORITHM", "3F00:006E:0073:00C1", TYPE_HEX, 0, 0, prettify_algorithm }, + { "Sig Create Date", "OPENPGP_SIG_DATE", "3F00:006E:0073:00CD", TYPE_HEX, 0, 4, prettify_date }, + { "Sig Fingerprint", "OPENPGP_SIG_FP", "3F00:006E:0073:00C5", TYPE_HEX, 0, 20, NULL }, + { NULL, NULL, NULL, TYPE_NULL, 0, 0, NULL } +}; + static const struct ef_name_map user_data[] = { { "Account", "OPENGPG_ACCOUNT", "3F00:005E", TYPE_STRING, 0, 0, NULL }, { "URL", "OPENPGP_URL", "3F00:5F50", TYPE_STRING, 0, 0, NULL }, @@ -200,6 +218,46 @@ static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) } +/* prettify algorithm parameters */ +static char *prettify_algorithm(u8 *data, size_t length) +{ + if (data != NULL && length >= 1) { + static char result[64]; /* large enough */ + + if (data[0] == 0x01 && length >= 5) { /* RSA */ + unsigned short modulus = (data[1] << 8) + data[2]; + snprintf(result, sizeof(result), "RSA%u", modulus); + return result; + } + else if (data[0] == 0x12) { /* ECDH */ + strcpy(result, "ECDH"); + return result; + } + else if (data[0] == 0x13) { /* ECDSA */ + strcpy(result, "ECDSA"); + return result; + } + } + return NULL; +} + + +/* prettify date/time */ +static char *prettify_date(u8 *data, size_t length) +{ + if (data != NULL && length == 4) { + time_t time = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + struct tm *tp; + static char result[64]; /* large enough */ + + tp = gmtime(&time); + strftime(result, sizeof(result), "%Y-%m-%d %T", tp); + return result; + } + return NULL; +} + + #define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) /* prettify OpenPGP card version */ @@ -403,7 +461,7 @@ static int decode_options(int argc, char **argv) char *endptr; unsigned long val; - while ((c = getopt_long(argc, argv,"r:x:CUG:L:EhwvVd:", options, (int *) 0)) != EOF) { + while ((c = getopt_long(argc, argv,"r:x:CUG:KL:EhwvVd:", options, (int *) 0)) != EOF) { switch (c) { case 'r': opt_reader = optarg; @@ -438,6 +496,10 @@ static int decode_options(int argc, char **argv) opt_userinfo++; actions++; break; + case 'K': + opt_keyinfo++; + actions++; + break; case 'G': opt_genkey++; key_id = optarg[0] - '0'; @@ -812,6 +874,9 @@ int main(int argc, char **argv) if (opt_userinfo) exit_status |= do_info(card, user_data); + if (opt_keyinfo) + exit_status |= do_info(card, key_data); + if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); } From 85258f2951e7e2e56635bfa2922497cd90a71ae7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Wed, 3 Oct 2018 11:04:12 +0200 Subject: [PATCH 0618/4321] openpgp-tool: use key type to indicate key to generate Instead of only expecting a key length, and implicitly assuming RSA as the key algorithm, introduce option --key-type to pass the key type as a string. When generating the key determine key algorithm and attributes based on the key type passed. If no key was given, default to "rsa2048". --- doc/tools/openpgp-tool.1.xml | 13 ++++--- src/tools/openpgp-tool.c | 68 +++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index dd9e893b86..bdcaf21ba2 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -133,12 +133,17 @@ - bitlength, - bitlength + keytype, + keytype - Specify the length of the key to be generated. - If not given, it defaults to 2048 bit. + Specify the type of the key to be generated. + Supported values for keytype are + rsa for RSA with 2048 bits, + rsaLENGTH + for RSA with a bit length of LENGTH. + + If not given, it defaults to rsa2048. diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 08cbd0f884..0fa9a76ad5 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -97,7 +97,7 @@ static int opt_keyinfo = 0; static char *exec_program = NULL; static int opt_genkey = 0; static u8 key_id = 0; -static unsigned int key_len = 2048; +static char *keytype = NULL; static int opt_verify = 0; static char *verifytype = NULL; static int opt_pin = 0; @@ -119,7 +119,7 @@ static const struct option options[] = { { "user-info", no_argument, NULL, 'U' }, { "key-info", no_argument, NULL, 'K' }, { "gen-key", required_argument, NULL, 'G' }, - { "key-length",required_argument, NULL, 'L' }, + { "key-type", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, @@ -141,7 +141,7 @@ static const char *option_help[] = { /* U */ "Show card holder information", /* K */ "Show key information", /* G */ "Generate key", -/* L */ "Key length (default 2048)", +/* t */ "Key type (default: rsa2048)", /* h */ "Print this help message", /* v */ "Verbose operation. Use several times to enable debug output.", /* V */ "Show version number", @@ -461,7 +461,7 @@ static int decode_options(int argc, char **argv) char *endptr; unsigned long val; - while ((c = getopt_long(argc, argv,"r:x:CUG:KL:EhwvVd:", options, (int *) 0)) != EOF) { + while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != EOF) { switch (c) { case 'r': opt_reader = optarg; @@ -505,8 +505,10 @@ static int decode_options(int argc, char **argv) key_id = optarg[0] - '0'; actions++; break; - case 'L': - key_len = atoi(optarg); + case 't': + if (keytype) + free(keytype); + keytype = strdup(optarg); break; case 'h': util_print_usage_and_die(app_name, options, option_help, NULL); @@ -662,7 +664,7 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) return EXIT_SUCCESS; } -int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) +int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) { int r; sc_cardctl_openpgp_keygen_info_t key_info; @@ -670,21 +672,54 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) sc_path_t path; sc_file_t *file; + /* validate key_id */ if (key_id < 1 || key_id > 3) { util_error("unknown key ID %d", key_id); return SC_ERROR_INVALID_ARGUMENTS; } + + /* fack back to RSA 2048 if keytype is not given */ + if (!keytype) + keytype = "RSA2048"; + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); - key_info.key_id = key_id; - key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; - key_info.rsa.modulus_len = key_len; - key_info.rsa.modulus = malloc(key_len/8); - r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); - free(key_info.rsa.modulus); - if (r < 0) { - util_error("failed to generate key: %s", sc_strerror(r)); + + /* generate key depending on keytype passed */ + if (strncasecmp("RSA", keytype, strlen("RSA")) == 0) { + size_t keylen = 2048; /* default length for RSA keys */ + const char *keylen_ptr = keytype + strlen("RSA"); + + /* try to get key length from keytype, e.g. "rsa3072" -> 3072 */ + if (strlen(keylen_ptr) > 0) { + if (strspn(keylen_ptr, "0123456789") == strlen(keylen_ptr) && + atol(keylen_ptr) >= 1024 && atol(keylen_ptr) <= 4096) { + keylen = atol(keylen_ptr); + } + else { + util_error("illegal key type: %s", keytype); + return EXIT_FAILURE; + } + } + + /* set key_info */ + key_info.key_id = key_id; + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; + key_info.rsa.modulus_len = keylen; + key_info.rsa.modulus = malloc((keylen + 7) / 8); + + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); + free(key_info.rsa.modulus); + if (r < 0) { + util_error("failed to generate key: %s", sc_strerror(r)); + return EXIT_FAILURE; + } + } + else { + //TODO: deal with EC keys + util_error("Generating non-RSA keys is not yet implemented"); return EXIT_FAILURE; } + sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); if (r < 0) { @@ -697,6 +732,7 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) return EXIT_FAILURE; } printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20)); + return EXIT_SUCCESS; } @@ -890,7 +926,7 @@ int main(int argc, char **argv) } if (opt_genkey) - exit_status |= do_genkey(card, key_id, key_len); + exit_status |= do_genkey(card, key_id, keytype); if (exec_program) { char *const largv[] = {exec_program, NULL}; From ec3830fe66749afde37baffa18b83c7306e1a9b0 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 13 Oct 2018 19:52:31 +0200 Subject: [PATCH 0619/4321] openpgp-tool: use more compatible strftime() format spec Replace the Single UNIX specific shorthand %T for %H:%M:%S with the latter to keep MingW happy. --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 0fa9a76ad5..f75bf64603 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -251,7 +251,7 @@ static char *prettify_date(u8 *data, size_t length) static char result[64]; /* large enough */ tp = gmtime(&time); - strftime(result, sizeof(result), "%Y-%m-%d %T", tp); + strftime(result, sizeof(result), "%Y-%m-%d %H:%M:%S", tp); return result; } return NULL; From afda163dc6338716759d16f9a2cb216784cb94f0 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 21 Oct 2018 18:06:37 +0200 Subject: [PATCH 0620/4321] openpgp-tool: fix typo --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index f75bf64603..272210daef 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -678,7 +678,7 @@ int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) return SC_ERROR_INVALID_ARGUMENTS; } - /* fack back to RSA 2048 if keytype is not given */ + /* fall back to RSA 2048 if keytype is not given */ if (!keytype) keytype = "RSA2048"; From 4e5805dc5d6b1a304ab2fa735caf526e59bc7fb7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 21 Oct 2018 19:39:50 +0200 Subject: [PATCH 0621/4321] openpgp-tool: don't uppercase hex string --- src/tools/openpgp-tool.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 272210daef..9f108ab87b 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -204,15 +204,8 @@ static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) if (data != NULL) { int r = sc_bin_to_hex(data, length, buffer, buflen, ':'); - if (r == SC_SUCCESS) { - char *ptr; - - /* upper-case the hex-ified string */ - for (ptr = buffer; *ptr != '\0'; ptr++) - *ptr = toupper(*ptr); - + if (r == SC_SUCCESS) return buffer; - } } return NULL; } From c6d252611b6b11a22cbb64acc98014ace210bf94 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Thu, 1 Nov 2018 11:04:29 +0100 Subject: [PATCH 0622/4321] openpgp-tool: add missing length check in prettify_name() --- src/tools/openpgp-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 9f108ab87b..d00b4450ef 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -332,7 +332,7 @@ static char *prettify_name(u8 *data, size_t length) *dst = *src++; length--; if (*dst == '<') { - if (*src == '<') { + if (length > 0 && *src == '<') { src++; length--; } From 54c9d65a482ccf17c9242ffda411e4b2f644effe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 15:34:30 +0100 Subject: [PATCH 0623/4321] CID 325861 (#1 of 1): Dereference before null check (REVERSE_INULL) --- src/pkcs11/framework-pkcs15.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 4d21619091..ef0e023962 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4923,7 +4923,7 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - struct sc_pkcs11_card *p11card = session->slot->p11card; + struct sc_pkcs11_card *p11card; struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *) obj; struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; @@ -4931,16 +4931,17 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initializing wrapping with a secret key."); - fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; - - if (!fw_data) - return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_WrapKey"); - if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL) { sc_log(context, "One or more of mandatory arguments were NULL."); return CKR_ARGUMENTS_BAD; } + p11card = session->slot->p11card; + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; + + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_WrapKey"); + /* Verify that the key supports wrapping */ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_WRAP)) skey = NULL; From 609095a4f430b229118ebcfd72ea28673c5f23cc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 15:36:00 +0100 Subject: [PATCH 0624/4321] CID 325860 (#1 of 1): Dereference before null check (REVERSE_INULL) --- src/libopensc/card-myeid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 3f3b74985c..2715d07d53 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1302,13 +1302,13 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra myeid_private_data_t* priv; int symmetric_operation = 0; - LOG_FUNC_CALLED(card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); - if (card == NULL || crgram == NULL) { - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "One or more of required arguments was null.\n"); + return SC_ERROR_INVALID_ARGUMENTS; } + LOG_FUNC_CALLED(card->ctx); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + if (crgram_len > MYEID_MAX_RSA_KEY_LEN / 8) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); From 1e7bb8365931d700f8a5d23309111a009a816df8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 15:40:57 +0100 Subject: [PATCH 0625/4321] CID 324485 (#1 of 2): Integer overflowed argument (INTEGER_OVERFLOW) --- src/libopensc/card-cac1.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index a4bdd3f138..6644ea0ccd 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -157,6 +157,10 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, r = cac_cac1_get_certificate(card, &val, &val_len); if (r < 0) goto done; + if (val_len < 1) { + r = SC_ERROR_INVALID_DATA; + goto done; + } cert_type = val[0]; cert_ptr = val + 1; From 3c0a16dc39c49a07bed7e5a4b02a2cc4cb1dcb98 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 15:45:51 +0100 Subject: [PATCH 0626/4321] CID 321790 (#1 of 1): Resource leak (RESOURCE_LEAK) --- src/tools/opensc-explorer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 44e180432d..16be202a25 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1712,6 +1712,9 @@ static int do_random(int argc, char **argv) sc_unlock(card); if (r < 0) { fprintf(stderr, "Failed to get random bytes: %s\n", sc_strerror(r)); + if (argc == 2) { + fclose(outf); + } return -1; } From c032b2f15d1c141b3fba33724c5c609f98718955 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 15:49:58 +0100 Subject: [PATCH 0627/4321] CID 320271 (#1 of 1): Dereference before null check (REVERSE_INULL) --- src/pkcs11/framework-pkcs15.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ef0e023962..4eadf66f61 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -396,8 +396,6 @@ pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken) scconf_block *conf_block = NULL; char *model = NULL; - strcpy_bp(pToken->manufacturerID, p15card->tokeninfo->manufacturer_id, 32); - conf_block = sc_get_conf_block(p15card->card->ctx, "framework", "pkcs15", 1); if (conf_block && p15card->file_app) { scconf_block **blocks = NULL; @@ -420,19 +418,23 @@ pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken) else strcpy_bp(pToken->model, "PKCS#15", sizeof(pToken->model)); - /* Take the last 16 chars of the serial number (if the are more than 16). - * _Assuming_ that the serial number is a Big Endian counter, this - * will assure that the serial within each type of card will be - * unique in pkcs11 (at least for the first 8^16 cards :-) */ - if (p15card->tokeninfo->serial_number != NULL) { - size_t sn_start = strlen(p15card->tokeninfo->serial_number); + if (p15card->tokeninfo) { + strcpy_bp(pToken->manufacturerID, p15card->tokeninfo->manufacturer_id, 32); + + /* Take the last 16 chars of the serial number (if the are more than 16). + * _Assuming_ that the serial number is a Big Endian counter, this + * will assure that the serial within each type of card will be + * unique in pkcs11 (at least for the first 8^16 cards :-) */ + if (p15card->tokeninfo->serial_number != NULL) { + size_t sn_start = strlen(p15card->tokeninfo->serial_number); - if (sn_start <= 16) - sn_start = 0; - else - sn_start -= 16; + if (sn_start <= 16) + sn_start = 0; + else + sn_start -= 16; - strcpy_bp(pToken->serialNumber, p15card->tokeninfo->serial_number + sn_start, 16); + strcpy_bp(pToken->serialNumber, p15card->tokeninfo->serial_number + sn_start, 16); + } } pToken->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; From eddea6f3c2d3dafc2c09eba6695c745a61b5186f Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Wed, 7 Nov 2018 16:13:45 +0100 Subject: [PATCH 0628/4321] fix logic of send/recv sizes in config files - they are not set if SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, ... fails - regarding max_send_size the logic is inverted --- src/libopensc/reader-pcsc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index d2c2b6cb40..ae0bb34b84 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1191,13 +1191,6 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } } - /* max send/receive sizes: with default values only short APDU supported */ - reader->max_send_size = priv->gpriv->force_max_send_size ? - priv->gpriv->force_max_send_size : - SC_READER_SHORT_APDU_MAX_SEND_SIZE; - reader->max_recv_size = priv->gpriv->force_max_recv_size ? - priv->gpriv->force_max_recv_size : - SC_READER_SHORT_APDU_MAX_RECV_SIZE; if (priv->get_tlv_properties) { /* Try to set reader max_send_size and max_recv_size based on * detected max_data */ @@ -1206,7 +1199,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) if (max_data > 0) { sc_log(ctx, "Reader supports transceiving %d bytes of data", max_data); - if (priv->gpriv->force_max_send_size) + if (!priv->gpriv->force_max_send_size) reader->max_send_size = max_data; else sc_log(ctx, "Sending is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" @@ -1276,6 +1269,14 @@ int pcsc_add_reader(sc_context_t *ctx, goto err1; } + /* max send/receive sizes: with default values only short APDU supported */ + reader->max_send_size = priv->gpriv->force_max_send_size ? + priv->gpriv->force_max_send_size : + SC_READER_SHORT_APDU_MAX_SEND_SIZE; + reader->max_recv_size = priv->gpriv->force_max_recv_size ? + priv->gpriv->force_max_recv_size : + SC_READER_SHORT_APDU_MAX_RECV_SIZE; + ret = _sc_add_reader(ctx, reader); if (ret == SC_SUCCESS) { From 027ccad439cd9b82f3c57ad05f36bf51ad6627d7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 5 Nov 2018 11:16:04 +0100 Subject: [PATCH 0629/4321] allow specifying the size of OpenSSL secure memory ... and set it for builds where we're linking OpenSSL statically (i.e. Windows and macOS) fixes https://github.com/OpenSC/OpenSC/issues/1515 --- MacOSX/build-package.in | 1 + appveyor.yml | 1 + configure.ac | 10 +++++++++- src/libopensc/ctx.c | 5 ++--- src/minidriver/minidriver.c | 3 +++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index eefb69539d..8a43843c68 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -61,6 +61,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then --sysconfdir=$PREFIX/etc \ --enable-cvcdir=$PREFIX/etc/cvc \ --enable-x509dir=$PREFIX/etc/x509 \ + --enable-openssl-secure-malloc=65536 \ --disable-dependency-tracking \ --enable-shared \ --enable-static \ diff --git a/appveyor.yml b/appveyor.yml index f9ae1da301..ee5ad25d71 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,6 +41,7 @@ install: $env:ARTIFACT="${env:ARTIFACT}-Light" } Else { $env:NMAKE_EXTRA="OPENSSL_DEF=/DENABLE_OPENSSL ${env:NMAKE_EXTRA}" + $env:NMAKE_EXTRA="OPENSSL_EXTRA_CFLAGS=/DOPENSSL_SECURE_MALLOC_SIZE=65536 ${env:NMAKE_EXTRA}" If (!(Test-Path C:\zlib )) { appveyor DownloadFile "https://github.com/madler/zlib/archive/v${env:ZLIB_VER_DOT}.zip" -FileName zlib.zip 7z x zlib.zip -oC:\ diff --git a/configure.ac b/configure.ac index 1d75e5a461..bc9136ce3e 100644 --- a/configure.ac +++ b/configure.ac @@ -172,11 +172,18 @@ AC_ARG_ENABLE( AC_ARG_ENABLE( [openssl], - [AS_HELP_STRING([--enable-openssl],[enable openssl linkage @<:@detect@:>@])], + [AS_HELP_STRING([--enable-openssl],[enable OpenSSL linkage @<:@detect@:>@])], , [enable_openssl="detect"] ) +AC_ARG_ENABLE([openssl-secure-malloc], + [AC_HELP_STRING([--openssl-secure-malloc=], + [Enable OpenSSL secure memory by specifying its size in bytes, must be a power of 2 @<:@disabled@:>@])], + [], [enable_openssl_secure_malloc=no]) +AS_IF([test $enable_openssl_secure_malloc != no], + [AC_DEFINE_UNQUOTED([OPENSSL_SECURE_MALLOC_SIZE],[$enable_openssl_secure_malloc],[Size of OpenSSL secure memory in bytes, must be a power of 2])]) + AC_ARG_ENABLE( [openpace], [AS_HELP_STRING([--enable-openpace],[enable OpenPACE linkage @<:@detect@:>@])], @@ -1115,6 +1122,7 @@ thread locking support: ${enable_thread_locking} zlib support: ${enable_zlib} readline support: ${enable_readline} OpenSSL support: ${enable_openssl} +OpenSSL secure memory: ${enable_openssl_secure_malloc} PC/SC support: ${enable_pcsc} CryptoTokenKit support: ${enable_cryptotokenkit} OpenCT support: ${enable_openct} diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index dff75ed8be..14a039b792 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -833,10 +833,9 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) return r; } -#ifdef ENABLE_OPENSSL +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) if (!CRYPTO_secure_malloc_initialized()) { - /* XXX What's a reasonable amount of secure heap? */ - CRYPTO_secure_malloc_init(4096, 32); + CRYPTO_secure_malloc_init(OPENSSL_SECURE_MALLOC_SIZE, OPENSSL_SECURE_MALLOC_SIZE/8); } #endif diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index b02be8ee5a..fd74959f14 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -6999,6 +6999,9 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, break; case DLL_PROCESS_DETACH: sc_notify_close(); +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) + CRYPTO_secure_malloc_done(); +#endif break; } return TRUE; From 447335bc1fdf6d65636aa39c7e2989e2fb6ef590 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 00:09:35 +0100 Subject: [PATCH 0630/4321] md: clean OpenSSL memory when DLL is unloaded --- src/minidriver/minidriver.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index fd74959f14..793ce476d3 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -48,6 +48,7 @@ #include "libopensc/log.h" #include "libopensc/internal.h" #include "libopensc/aux-data.h" +#include "libopensc/sc-ossl-compat.h" #include "ui/notify.h" #include "ui/strings.h" #include "ui/wchar_from_char_str.h" @@ -60,6 +61,10 @@ #endif #endif +#ifdef ENABLE_OPENPACE +#include +#endif + #if defined(__MINGW32__) #include "cardmod-mingw-compat.h" #endif @@ -6999,9 +7004,14 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, break; case DLL_PROCESS_DETACH: sc_notify_close(); + if (lpReserved == NULL) { #if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) - CRYPTO_secure_malloc_done(); + CRYPTO_secure_malloc_done(); #endif +#ifdef ENABLE_OPENPACE + EAC_cleanup(); +#endif + } break; } return TRUE; From f3a296235876a9dec0c8605f87520421f00d34f5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 00:48:17 +0100 Subject: [PATCH 0631/4321] pkcs11: perform memory cleanup on dll unload --- src/pkcs11/pkcs11-global.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 3936c23a7b..51d80120f5 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -210,7 +210,37 @@ static int slot_list_seeker(const void *el, const void *key) { return 0; } +#if defined(_WIN32) +#include "libopensc/sc-ossl-compat.h" +#ifdef ENABLE_OPENPACE +#include +#endif + +BOOL APIENTRY DllMain( HINSTANCE hinstDLL, + DWORD ul_reason_for_call, + LPVOID lpReserved +) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + sc_notify_init(); + case DLL_PROCESS_DETACH: + sc_notify_close(); + if (lpReserved == NULL) { +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) + CRYPTO_secure_malloc_done(); +#endif +#ifdef ENABLE_OPENPACE + EAC_cleanup(); +#endif + } + break; + } + return TRUE; +} +#endif CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { @@ -238,7 +268,9 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) return CKR_CRYPTOKI_ALREADY_INITIALIZED; } +#if !defined(_WIN32) sc_notify_init(); +#endif rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pInitArgs); if (rv != CKR_OK) @@ -303,7 +335,9 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) if (pReserved != NULL_PTR) return CKR_ARGUMENTS_BAD; +#if !defined(_WIN32) sc_notify_close(); +#endif if (context == NULL) return CKR_CRYPTOKI_NOT_INITIALIZED; From 2cb6f9c94fea8c397ae77bb9fc6ef866be6890e2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 6 Nov 2018 09:44:43 +0100 Subject: [PATCH 0632/4321] fixed compilation without OpenSSL closes https://github.com/OpenSC/OpenSC/pull/1518 --- src/libopensc/sm.h | 6 ------ src/pkcs11/framework-pkcs15.c | 5 +++-- src/sm/sm-eac.c | 2 ++ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index b3b1ae487c..d2d00e3747 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -35,12 +35,6 @@ extern "C" { #include #include -#ifndef SHA_DIGEST_LENGTH -#define SHA_DIGEST_LENGTH 20 -#define SHA1_DIGEST_LENGTH 20 -#define SHA256_DIGEST_LENGTH 32 -#endif - #define SM_TYPE_GP_SCP01 0x100 #define SM_TYPE_CWA14890 0x400 #define SM_TYPE_DH_RSA 0x500 diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 4eadf66f61..c4605810f4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -27,9 +27,10 @@ #include "libopensc/cardctl.h" #include "ui/notify.h" #include "common/compat_strnlen.h" - #ifdef ENABLE_OPENSSL -#include +#include +#else +#define SHA_DIGEST_LENGTH 20 #endif #include "sc-pkcs11.h" diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 8317f41b55..9ac9807ca4 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -32,6 +32,8 @@ #ifdef ENABLE_OPENSSL #include +#else +#define ssl_error(a) #endif char eac_default_flags = 0; From ee3fdc6938566dfbdecda6ca9a074c3acf973571 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 12 Nov 2018 13:55:44 +0100 Subject: [PATCH 0633/4321] fixed missing function stub --- src/libopensc/sc-ossl-compat.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 192727f637..09e7dca0d4 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -240,6 +240,10 @@ static sc_ossl_inline int CRYPTO_secure_malloc_initialized() return 0; } +static sc_ossl_inline void CRYPTO_secure_malloc_done() +{ +} + #else #include From d4e6c0c0dd9ab5f69265aedb6474bb0f5f045543 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 14 Nov 2018 12:56:04 +0100 Subject: [PATCH 0634/4321] travis: fixed installation of completion templates --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 24dc40f22f..df6d6d0d5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,7 +74,7 @@ before_script: fi; unset CC; unset CXX; - ./configure --host=$HOST --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; + ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; fi # Optionally try to upload to Coverity Scan # On error (propably quota is exhausted), just continue From abdbb9d8c09146cd0bfbb5ef8861c1f3a14a83c7 Mon Sep 17 00:00:00 2001 From: Steve Ross Date: Wed, 14 Nov 2018 11:59:43 -0600 Subject: [PATCH 0635/4321] Enable CoolKey driver to handle 2048-bit keys. For a problem description, see . In a nutshell, for a card with the CoolKey applet and 2048-bit keys, the command pkcs11-tool --test --login fails to complete all of its tests. This commit consists of a patch from @dengert. To avoid triggering an error when the data exceeds 255 bytes, this commit limits the amount of the payload sent to the CoolKey applet on the card based on the maximum amount of data that the card can receive, and overhead bytes (namely, a header and nonce) that accompany the payload. With this change, the command pkcs11-tool --test --login succeeds. --- src/libopensc/card-coolkey.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index e320290dfe..11c4e92643 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1168,12 +1168,16 @@ static int coolkey_write_object(sc_card_t *card, unsigned long object_id, size_t operation_len; size_t left = buf_len; int r; + size_t max_operation_len; + + /* set limit for the card's maximum send size and short write */ + max_operation_len = MIN(COOLKEY_MAX_CHUNK_SIZE, (card->max_send_size - sizeof(coolkey_read_object_param_t) - nonce_size)); ulong2bebytes(¶ms.head.object_id[0], object_id); do { ulong2bebytes(¶ms.head.offset[0], offset); - operation_len = MIN(left, COOLKEY_MAX_CHUNK_SIZE); + operation_len = MIN(left, max_operation_len); params.head.length = operation_len; memcpy(params.buf, buf, operation_len); r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_WRITE_OBJECT, 0, 0, From 3ec39919c3beb2df620272f7349122bfc82ab256 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 7 Nov 2018 13:57:49 +0200 Subject: [PATCH 0636/4321] pkcs15-lib: Must use keyargs->value_len instead of keyargs->key.data_len * 8 when calling check_key_compatibility(), to get correct result in key unwrap operations. In this case data_len is 0, but value_len contains the key length in bits. --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index a3ae08c82c..0ee162a341 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1882,7 +1882,7 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile LOG_FUNC_CALLED(ctx); /* Now check whether the card is able to handle this key */ - if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->key.data_len * 8, 0) != SC_SUCCESS) { + if (check_key_compatibility(p15card, keyargs->algorithm, NULL, 0, keyargs->value_len, 0) != SC_SUCCESS) { /* Make sure the caller explicitly tells us to store * the key as extractable. */ if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) From c051ef64dd1585e6a242ab9f1e7919906d4257c6 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 9 Nov 2018 09:46:06 +0200 Subject: [PATCH 0637/4321] Convert sequences of four spaces to tabs to fix indentation problems. --- src/pkcs11/framework-pkcs15.c | 179 +++++++++++++++++----------------- 1 file changed, 89 insertions(+), 90 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index c4605810f4..119770989d 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -565,8 +565,8 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED); auth = slot_data_auth(slot->fw_data); sc_log(context, - "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, - slot->token_info.flags); + "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, + slot->token_info.flags); if (auth) { pin_info = (struct sc_pkcs15_auth_info*) auth->data; @@ -788,8 +788,8 @@ __pkcs15_create_data_object(struct pkcs15_fw_data *fw_data, rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &dobj, object, &pkcs15_dobj_ops, sizeof(struct pkcs15_data_object)); if (rv >= 0) { - dobj->info = (struct sc_pkcs15_data_info *) object->data; - dobj->value = NULL; + dobj->info = (struct sc_pkcs15_data_info *) object->data; + dobj->value = NULL; } if (data_object != NULL) @@ -809,7 +809,7 @@ __pkcs15_create_secret_key_object(struct pkcs15_fw_data *fw_data, rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &skey, object, &pkcs15_skey_ops, sizeof(struct pkcs15_skey_object)); if (rv >= 0) - skey->info = (struct sc_pkcs15_skey_info *) object->data; + skey->info = (struct sc_pkcs15_skey_info *) object->data; if (skey_object != NULL) *skey_object = (struct pkcs15_any_object *) skey; @@ -907,7 +907,7 @@ __pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_ob if (c1->issuer_len == c2->subject_len && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) { sc_log(context, "Associating object %d (id %s) as issuer", - i, sc_pkcs15_print_id(&cert2->cert_info->id)); + i, sc_pkcs15_print_id(&cert2->cert_info->id)); cert->cert_issuer = (struct pkcs15_cert_object *) obj; return; } @@ -1001,7 +1001,7 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj, list_append(&slot->objects, obj); sc_log(context, "Slot:%lX Setting object handle of 0x%lx to 0x%lx", - slot->id, obj->base.handle, handle); + slot->id, obj->base.handle, handle); obj->base.handle = handle; obj->base.flags |= SC_PKCS11_OBJECT_SEEN; obj->refcount++; @@ -1980,7 +1980,7 @@ pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen } sc_log(context, "Init PIN: pin %p:%lu; unblock style %i", pPin, - ulPinLen, sc_pkcs11_conf.pin_unblock_style); + ulPinLen, sc_pkcs11_conf.pin_unblock_style); fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) @@ -2213,10 +2213,9 @@ out: return rv; * Depending on card implementation, it can be automatically deleted during the card's reset. * This kind of objects are not written to the PKCS#15 directory file. * 2. If the card doesn't support on card session objects, a CKA_TOKEN = FALSE object is stored only in OpenSC's memory. - - + * * This is used by the C_DeriveKey with ECDH to hold the - * key, and the calling application can then retrieve tha attributes as needed. + * key, and the calling application can then retrieve the attributes as needed. * . */ static CK_RV @@ -2259,17 +2258,17 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile switch (key_type) { case CKK_GENERIC_SECRET: - args.algorithm = SC_ALGORITHM_UNDEFINED; - break; + args.algorithm = SC_ALGORITHM_UNDEFINED; + break; case CKK_AES: - args.algorithm = SC_ALGORITHM_AES; - break; + args.algorithm = SC_ALGORITHM_AES; + break; case CKK_DES3: - args.algorithm = SC_ALGORITHM_3DES; - break; + args.algorithm = SC_ALGORITHM_3DES; + break; case CKK_DES: - args.algorithm = SC_ALGORITHM_DES; - break; + args.algorithm = SC_ALGORITHM_DES; + break; default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -2298,11 +2297,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile break; case CKA_VALUE: if (attr->pValue) { - args.key.data = calloc(1,attr->ulValueLen); - if (!args.key.data) + args.key.data = calloc(1,attr->ulValueLen); + if (!args.key.data) return CKR_HOST_MEMORY; - memcpy(args.key.data, attr->pValue, attr->ulValueLen); - args.key.data_len = attr->ulValueLen; + memcpy(args.key.data, attr->pValue, attr->ulValueLen); + args.key.data_len = attr->ulValueLen; } break; case CKA_DECRYPT: @@ -2330,51 +2329,51 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile /* If creating a PKCS#11 session object, i.e. one that is only in memory */ if (_token == FALSE && (fw_data->p15_card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == 0) { - /* TODO Have 3 choices as to how to create the object. - * (1)create a sc_pkcs15init_store_secret_key routine like the others - * (2)use the sc_pkcs15emu_ routines - * (3)do it inline here (Will do this for now) - */ + /* TODO Have 3 choices as to how to create the object. + * (1)create a sc_pkcs15init_store_secret_key routine like the others + * (2)use the sc_pkcs15emu_ routines + * (3)do it inline here (Will do this for now) + */ - key_obj = calloc(1, sizeof(sc_pkcs15_object_t)); - if (key_obj == NULL) { + key_obj = calloc(1, sizeof(sc_pkcs15_object_t)); + if (key_obj == NULL) { rv = CKR_HOST_MEMORY; goto out; - } - temp_object = TRUE; - key_obj->type = SC_PKCS15_TYPE_SKEY; + } + temp_object = TRUE; + key_obj->type = SC_PKCS15_TYPE_SKEY; - if (args.id.len) - memcpy(key_obj->label, args.id.value, args.id.len); + if (args.id.len) + memcpy(key_obj->label, args.id.value, args.id.len); - key_obj->flags = 2; /* TODO not sure what these mean */ + key_obj->flags = 2; /* TODO not sure what these mean */ - skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); - if (skey_info == NULL) { + skey_info = calloc(1, sizeof(sc_pkcs15_skey_info_t)); + if (skey_info == NULL) { rv = CKR_HOST_MEMORY; goto out; - } - key_obj->data = skey_info; - skey_info->usage = (unsigned int) args.usage; - skey_info->native = 0; /* card can not use this */ - skey_info->access_flags = 0; /* looks like not needed */ - skey_info->key_type = key_type; /* PKCS#11 CKK_* */ - skey_info->data.value = args.key.data; - skey_info->data.len = args.key.data_len; - skey_info->value_len = args.value_len * 8; /* key length comes in number of bytes, use length in bits in PKCS#15. */ - args.key.data = NULL; + } + key_obj->data = skey_info; + skey_info->usage = (unsigned int) args.usage; + skey_info->native = 0; /* card can not use this */ + skey_info->access_flags = 0; /* looks like not needed */ + skey_info->key_type = key_type; /* PKCS#11 CKK_* */ + skey_info->data.value = args.key.data; + skey_info->data.len = args.key.data_len; + skey_info->value_len = args.value_len * 8; /* key length comes in number of bytes, use length in bits in PKCS#15. */ + args.key.data = NULL; key_obj->session_object = 1; } else { - if(_token == FALSE) + if(_token == FALSE) args.session_object = 1; /* store the object on card for duration of the session. */ args.value_len = args.value_len * 8; /* CKA_VALUE_LEN is number of bytes, PKCS#15 needs key length in bits */ rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); - if (rc < 0) { - rv = sc_to_cryptoki_error(rc, "C_CreateObject"); - goto out; - } + if (rc < 0) { + rv = sc_to_cryptoki_error(rc, "C_CreateObject"); + goto out; + } } /* Create a new pkcs11 object for it */ @@ -2633,7 +2632,7 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, args.app_label = (char *) attr->pValue; break; case CKA_OBJECT_ID: - if (sc_asn1_decode_object_id(attr->pValue, attr->ulValueLen, &args.app_oid)) { + if (sc_asn1_decode_object_id(attr->pValue, attr->ulValueLen, &args.app_oid)) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto out; } @@ -2692,7 +2691,7 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK if (_class != CKO_SECRET_KEY) _token = TRUE; /* default if not in template */ } - else if (rv != CKR_OK) { + else if (rv != CKR_OK) { return rv; } @@ -2702,7 +2701,7 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK * for backward compatibility, will default to TRUE */ /* Dont need profile id creating session only objects, - except when the card supports temporary on card session objects */ + except when the card supports temporary on card session objects */ p15init_create_object = _token == TRUE || (p11card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == SC_CARD_CAP_ONCARD_SESSION_OBJECTS; if (p15init_create_object) { @@ -2783,8 +2782,8 @@ get_X509_usage_privk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x *x509_usage |= SC_PKCS15INIT_X509_NON_REPUDIATION; if (typ == CKA_VERIFY || typ == CKA_WRAP || typ == CKA_ENCRYPT) { sc_log(context, - "get_X509_usage_privk(): invalid typ = 0x%0lx", - typ); + "get_X509_usage_privk(): invalid typ = 0x%0lx", + typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } @@ -2811,8 +2810,8 @@ get_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x5 *x509_usage |= SC_PKCS15INIT_X509_KEY_AGREEMENT; if (typ == CKA_SIGN || typ == CKA_UNWRAP || typ == CKA_DECRYPT) { sc_log(context, - "get_X509_usage_pubk(): invalid typ = 0x%0lx", - typ); + "get_X509_usage_pubk(): invalid typ = 0x%0lx", + typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } @@ -2934,7 +2933,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, CK_RV rv = CKR_OK; sc_log(context, "Keypair generation, mech = 0x%0lx", - pMechanism->mechanism); + pMechanism->mechanism); if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN && pMechanism->mechanism != CKM_GOSTR3410_KEY_PAIR_GEN @@ -3141,7 +3140,7 @@ pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object) struct pkcs15_any_object *any_obj = (struct pkcs15_any_object*) object; struct sc_pkcs11_slot *slot = session->slot; struct sc_pkcs11_card *p11card = slot->p11card; - struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_fw_data *fw_data = NULL; struct sc_aid *aid = NULL; struct sc_profile *profile = NULL; int rv; @@ -3771,7 +3770,7 @@ pkcs15_prkey_check_pss_param(CK_MECHANISM_PTR pMechanism, CK_ULONG hlen) // Hash parameter must match length of data supplied for CKM_RSA_PKCS_PSS for (i = 0; i < 5; i++) { if (pss_param->hashAlg == hashes[i] - && hlen != hash_lens[i]/8) + && hlen != hash_lens[i]/8) return CKR_MECHANISM_PARAM_INVALID; } /* other aspects of pss params were already verified during SignInit */ @@ -3814,7 +3813,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; sc_log(context, "Initiating signing operation, mechanism 0x%lx.", - pMechanism->mechanism); + pMechanism->mechanism); fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Sign"); @@ -4124,7 +4123,7 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_DeriveKey"); sc_log(context, "derivation %p %p %p %p %lu %p %lu", session, obj, - pMechanism, pParameters, ulParametersLen, pData, *pulDataLen); + pMechanism, pParameters, ulParametersLen, pData, *pulDataLen); /* See which of the alternative keys supports derivation */ while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_DERIVE)) @@ -4137,10 +4136,10 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, prkey_has_path = 1; if (pData != NULL && *pulDataLen > 0) { /* TODO DEE only test for NULL? */ - need_unlock = 1; - rv = sc_lock(p11card->card); - if (rv < 0) - return sc_to_cryptoki_error(rv, "C_DeriveKey"); + need_unlock = 1; + rv = sc_lock(p11card->card); + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_DeriveKey"); } /* TODO DEE This may not be the place to get the parameters, @@ -4148,11 +4147,11 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, * RSA parameters would be null. */ switch (prkey->base.p15_object->type) { - case SC_PKCS15_TYPE_PRKEY_EC: + case SC_PKCS15_TYPE_PRKEY_EC: { - CK_ECDH1_DERIVE_PARAMS * ecdh_params = (CK_ECDH1_DERIVE_PARAMS *) pParameters; - ulSeedDataLen = ecdh_params->ulPublicDataLen; - pSeedData = ecdh_params->pPublicData; + CK_ECDH1_DERIVE_PARAMS * ecdh_params = (CK_ECDH1_DERIVE_PARAMS *) pParameters; + ulSeedDataLen = ecdh_params->ulPublicDataLen; + pSeedData = ecdh_params->pPublicData; } break; } @@ -4246,7 +4245,7 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, case CKM_SHA384_RSA_PKCS_PSS: case CKM_SHA512_RSA_PKCS_PSS: if (!pMechanism->pParameter || - pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) + pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) return CKR_MECHANISM_PARAM_INVALID; pss_params = (CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter; @@ -4274,9 +4273,9 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, expected_salt_len = 512; } else if (pMechanism->mechanism == CKM_RSA_PKCS_PSS) { for (i = 0; i < 5; ++i) { - if (hashes[i] == pss_params->hashAlg) { - expected_hash = hashes[i]; - expected_salt_len = salt_lens[i]; + if (hashes[i] == pss_params->hashAlg) { + expected_hash = hashes[i]; + expected_salt_len = salt_lens[i]; } } } @@ -4386,9 +4385,9 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ case CKA_LOCAL: check_attribute_buffer(attr, sizeof(CK_BBOOL)); if (pubkey->pub_info) - *(CK_BBOOL*)attr->pValue = (pubkey->pub_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) != 0; + *(CK_BBOOL*)attr->pValue = (pubkey->pub_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) != 0; else /* no pub_info structure, falling back to TRUE */ - *(CK_BBOOL*)attr->pValue = TRUE; + *(CK_BBOOL*)attr->pValue = TRUE; break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); @@ -4873,7 +4872,7 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, /* Check whether this key supports unwrap */ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP)) - skey = NULL; + skey = NULL; /* TODO: should we look for a compatible key automatically? prv_next not implemented yet. */ /* skey = skey->prv_next; */ @@ -4947,7 +4946,7 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, /* Verify that the key supports wrapping */ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_WRAP)) - skey = NULL; + skey = NULL; /* TODO: browse for a key that supports, like other similar funcs */ if (skey == NULL) @@ -5342,9 +5341,9 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int mech_info.ulMaxKeySize = max_key_size; if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY) - mech_info.flags |= CKF_UNWRAP; + mech_info.flags |= CKF_UNWRAP; if ((card->caps & SC_CARD_CAP_WRAP_KEY) == SC_CARD_CAP_WRAP_KEY) - mech_info.flags |= CKF_WRAP; + mech_info.flags |= CKF_WRAP; mt = sc_pkcs11_new_fw_mechanism(CKM_AES_ECB, &mech_info, CKK_AES, NULL, NULL); if (!mt) @@ -5398,9 +5397,9 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mech_info.flags |= CKF_VERIFY; #endif if ((card->caps & SC_CARD_CAP_UNWRAP_KEY) == SC_CARD_CAP_UNWRAP_KEY) - mech_info.flags |= CKF_UNWRAP; + mech_info.flags |= CKF_UNWRAP; if ((card->caps & SC_CARD_CAP_WRAP_KEY) == SC_CARD_CAP_WRAP_KEY) - mech_info.flags |= CKF_WRAP; + mech_info.flags |= CKF_WRAP; mech_info.ulMinKeySize = ~0; mech_info.ulMaxKeySize = 0; @@ -5563,31 +5562,31 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); + CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, mt); + CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); + CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, mt); + CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, mt); + CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, mt); if (rc != CKR_OK) return rc; } From 7f91b6e07f719023643294ca23fec437916202d5 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Fri, 9 Nov 2018 09:51:40 +0200 Subject: [PATCH 0638/4321] MyEID: add AES algorithms to tokenInfo as supported during init. It is better to do it already in init, because adding them in C_UnwrapKey operations would require SO-PIN which is inconvenient. pkcs15: added function to get a specific supported algorithm, checking also OID. This is needed because for AES there are different OIDs for each key length. --- src/libopensc/pkcs15.c | 25 +++++++++++++++++++++++ src/libopensc/pkcs15.h | 8 +++++++- src/pkcs15init/pkcs15-myeid.c | 38 ++++++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 4313407e72..f33832c977 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2574,6 +2574,31 @@ sc_pkcs15_get_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, return info; } +struct sc_supported_algo_info * +sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism, const struct sc_object_id *algo_oid) +{ + struct sc_context *ctx = p15card->card->ctx; + struct sc_supported_algo_info *info = NULL; + int ii; + + if (algo_oid == NULL) + return NULL; + + for (ii=0;iitokeninfo->supported_algos[ii].reference; ii++) + if ((p15card->tokeninfo->supported_algos[ii].operations & operation) + && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism) + && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id)) + break; + + if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference) { + info = &p15card->tokeninfo->supported_algos[ii]; + sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)", + info->reference, info->mechanism, info->operations, info->algo_ref); + } + + return info; +} + int sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index bcbc25a6e1..8d2e54110a 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -952,8 +952,14 @@ void sc_pkcs15_free_object_content(struct sc_pkcs15_object *); int sc_pkcs15_allocate_object_content(struct sc_context *, struct sc_pkcs15_object *, const unsigned char *, size_t); +/* find algorithm from card's supported algorithms by operation and mechanism */ struct sc_supported_algo_info *sc_pkcs15_get_supported_algo(struct sc_pkcs15_card *, - unsigned, unsigned); + unsigned operation, unsigned mechanism); + +/* find algorithm from card's supported algorithms by operation, mechanism and object_id */ +struct sc_supported_algo_info *sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *, + unsigned operation, unsigned mechanism, const struct sc_object_id *algo_oid); + int sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *, struct sc_supported_algo_info *); diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 9721c640ec..304b0dd717 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -46,6 +46,15 @@ unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; #define MYEID_PROP_INFO_1_WRAP_WITH_TRUSTED 0x08; #define MYEID_PROP_INFO_2_SESSION_OBJECT 0x01; +static const struct sc_object_id id_aes128_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 1, -1 } }; +static const struct sc_object_id id_aes128_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 2, -1 } }; +static const struct sc_object_id id_aes256_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 41, -1 } }; +static const struct sc_object_id id_aes256_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 42, -1 } }; + +static void +_add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, + unsigned operations, unsigned mechanism, const struct sc_object_id *oid); + /* For Myeid, all objects are files that can be deleted in any order */ static int myeid_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card, @@ -178,17 +187,22 @@ myeid_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { struct sc_path path; struct sc_file *file = NULL; - u8 rbuf[256]; + u8 rbuf[256]; int r; LOG_FUNC_CALLED(p15card->card->ctx); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT; - r = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &rbuf); + _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes128_ecb); + _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes128_cbc); + _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes256_ecb); + _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes256_cbc); + + r = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &rbuf); LOG_TEST_RET(p15card->card->ctx, r, "Get applet info failed"); - sc_format_path("3F00", &path); + sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, &file); sc_file_free(file); @@ -433,6 +447,8 @@ myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card, } /* + * Add AlgorithmInfo of a supported algorithm to supportedAlgorithms field in tokenInfo. If object != NULL, + * add reference to the algorithmInfo to the passed object. */ static void _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, @@ -440,7 +456,11 @@ _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, { struct sc_supported_algo_info *algo; struct sc_context *ctx = p15card->card->ctx; - algo = sc_pkcs15_get_supported_algo(p15card, operations, mechanism); + if (oid == NULL) { + sc_log(ctx, "Failed to add algorithms refs - invalid arguments."); + return; + } + algo = sc_pkcs15_get_specific_supported_algo(p15card, operations, mechanism, oid); int rv; LOG_FUNC_CALLED(ctx); @@ -461,7 +481,11 @@ _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, } } - rv = sc_pkcs15_add_supported_algo_ref(object, algo); + if (object != NULL) + rv = sc_pkcs15_add_supported_algo_ref(object, algo); + else + rv = SC_SUCCESS; + if (rv != SC_SUCCESS) { sc_log(ctx, "Failed to add algorithms refs"); } @@ -470,10 +494,6 @@ _add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, static void myeid_fixup_supported_algos(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object) { - static const struct sc_object_id id_aes128_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 1, -1 } }; - static const struct sc_object_id id_aes128_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 2, -1 } }; - static const struct sc_object_id id_aes256_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 41, -1 } }; - static const struct sc_object_id id_aes256_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 42, -1 } }; struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data; From aa8f666f46a8845993eaa79e0de4573c8583650d Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 14 Nov 2018 09:39:03 +0200 Subject: [PATCH 0639/4321] Removed unnecessary spaces from framework-pkc15.c as requested. pkcs15: added explicit comparison when checking return value of sc_compare_oid() to make the logic more obvious. --- src/libopensc/pkcs15.c | 2 +- src/pkcs11/framework-pkcs15.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index f33832c977..31e97cb18c 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2587,7 +2587,7 @@ sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *p15card, unsigned o for (ii=0;iitokeninfo->supported_algos[ii].reference; ii++) if ((p15card->tokeninfo->supported_algos[ii].operations & operation) && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism) - && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id)) + && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id) == 1) break; if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference) { diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 119770989d..44d352b585 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -565,8 +565,8 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED); auth = slot_data_auth(slot->fw_data); sc_log(context, - "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, - slot->token_info.flags); + "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, + slot->token_info.flags); if (auth) { pin_info = (struct sc_pkcs15_auth_info*) auth->data; @@ -1980,7 +1980,7 @@ pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen } sc_log(context, "Init PIN: pin %p:%lu; unblock style %i", pPin, - ulPinLen, sc_pkcs11_conf.pin_unblock_style); + ulPinLen, sc_pkcs11_conf.pin_unblock_style); fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) @@ -2782,8 +2782,8 @@ get_X509_usage_privk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x *x509_usage |= SC_PKCS15INIT_X509_NON_REPUDIATION; if (typ == CKA_VERIFY || typ == CKA_WRAP || typ == CKA_ENCRYPT) { sc_log(context, - "get_X509_usage_privk(): invalid typ = 0x%0lx", - typ); + "get_X509_usage_privk(): invalid typ = 0x%0lx", + typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } @@ -2810,8 +2810,8 @@ get_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x5 *x509_usage |= SC_PKCS15INIT_X509_KEY_AGREEMENT; if (typ == CKA_SIGN || typ == CKA_UNWRAP || typ == CKA_DECRYPT) { sc_log(context, - "get_X509_usage_pubk(): invalid typ = 0x%0lx", - typ); + "get_X509_usage_pubk(): invalid typ = 0x%0lx", + typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } From 764c61446ece6423eb73c8a885f6d20c7d17a593 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 9 Nov 2018 08:22:46 -0600 Subject: [PATCH 0640/4321] pkcs15-crypt - Handle keys with user_consent - Fixes #1292 This fixes problem as stated in: https://github.com/OpenSC/OpenSC/issues/1292#issuecomment-431879472 pkcs15-crypt.c will treat keys with user_consent like PKCS#11 would. SC_AC_CONTEXT_SPECIFIC is set when doing a verify so a card driver can take action if needed. card-piv.c is currently the only driver doing so. It uses this to hold the card lock so both the VERIFY and following crypto operations are in the same transaction. The card enforces this restriction. Without this additional APDUs may be sent before every transaction to test that the expected applet is selected. Unlike the circumvention of using ignore_user_consent=true and pin caching this modification allows a pin pad reader to be used for keys requiring user_consent. On branch pkcs15-context-specific Changes to be committed: modified: pkcs15-crypt.c --- src/tools/pkcs15-crypt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 1e62248b72..9182c7f5c5 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -330,7 +330,7 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) } /* Pin already verified previously */ - if (pin == prev_pin) + if (pin == prev_pin && key->user_consent == 0) return 0; pincode = get_pin(pin); @@ -339,8 +339,25 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) free(pincode); return 5; } + + /* + * Do what PKCS#11 would do for keys requiring CKA_ALWAYS_AUTHENTICATE + * and CKU_CONTEXT_SPECIFIC login to let driver know this verify will be followed by + * a crypto operation. Card drivers can test for SC_AC_CONTEXT_SPECIFIC + * to do any special handling. + */ + if (key->user_consent) { + int auth_meth_saved; + struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) pin->data; + + auth_meth_saved = pinfo->auth_method; + + pinfo->auth_method = SC_AC_CONTEXT_SPECIFIC; + r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0); + pinfo->auth_method = auth_meth_saved; + } else + r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0); - r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0); free(pincode); if (r) { fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r)); From ad83c2c5a98e3208abffb5dca3024caed5664636 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Nov 2018 12:48:58 +0100 Subject: [PATCH 0641/4321] use proper debug level for card matching --- src/libopensc/card.c | 12 ++++++------ src/libopensc/log.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 69e2eb7952..4426fb1276 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1085,7 +1085,7 @@ static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, sc_bin_to_hex(card_atr_bin, card_atr_bin_len, card_atr_hex, sizeof(card_atr_hex), ':'); card_atr_hex_len = strlen(card_atr_hex); - sc_log(ctx, "ATR : %s", card_atr_hex); + sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR : %s", card_atr_hex); for (i = 0; table[i].atr != NULL; i++) { const char *tatr = table[i].atr; @@ -1096,14 +1096,14 @@ static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, size_t fix_hex_len = card_atr_hex_len; size_t fix_bin_len = card_atr_bin_len; - sc_log(ctx, "ATR try : %s", tatr); + sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR try : %s", tatr); if (tatr_len != fix_hex_len) { - sc_log(ctx, "ignored - wrong length"); + sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ignored - wrong length"); continue; } if (matr != NULL) { - sc_log(ctx, "ATR mask: %s", matr); + sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR mask: %s", matr); matr_len = strlen(matr); if (tatr_len != matr_len) @@ -1113,7 +1113,7 @@ static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, mbin_len = sizeof(mbin); sc_hex_to_bin(matr, mbin, &mbin_len); if (mbin_len != fix_bin_len) { - sc_log(ctx, "length of atr and atr mask do not match - ignored: %s - %s", tatr, matr); + sc_debug(ctx, SC_LOG_DEBUG_MATCH, "length of atr and atr mask do not match - ignored: %s - %s", tatr, matr); continue; } for (s = 0; s < tbin_len; s++) { @@ -1381,7 +1381,7 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo if (0 < expanded_len && expanded_len < sizeof expanded_val) module_path = expanded_val; #endif - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "SM module '%s' located in '%s'", in_module, module_path); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM module '%s' located in '%s'", in_module, module_path); if (module_path && strlen(module_path) > 0) { int sz = strlen(in_module) + strlen(module_path) + 3; module = malloc(sz); diff --git a/src/libopensc/log.h b/src/libopensc/log.h index ef98a07686..303f5c61ed 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -35,8 +35,8 @@ enum { SC_LOG_DEBUG_NORMAL, /* helps developers */ SC_LOG_DEBUG_RFU1, /* RFU */ SC_LOG_DEBUG_RFU2, /* RFU */ - SC_LOG_DEBUG_ASN1, /* asn1.c only */ - SC_LOG_DEBUG_MATCH, /* card matching only */ + SC_LOG_DEBUG_ASN1, /* asn1.c */ + SC_LOG_DEBUG_MATCH, /* card matching */ }; /* You can't do #ifndef __FUNCTION__ */ From d4f039cb50d3632cdacb38c5c96d33f8f7003311 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Nov 2018 13:02:29 +0100 Subject: [PATCH 0642/4321] speed up checking out nightly branch --- .github/push_artifacts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 25b481abfa..a24d24526d 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -5,7 +5,7 @@ set -ex -o xtrace BUILDPATH=${PWD} BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" -git clone https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /dev/null 2>&1 +git clone --single-branch https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /dev/null 2>&1 cd Nightly git checkout -b "${BRANCH}" From 1ab93312cd29e4fe0939544a00c39d7de6cef9b5 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 21 Nov 2018 12:31:41 +0100 Subject: [PATCH 0643/4321] SM: fix crash if nested GET RESPONSE issued during sm session fails or returns invalid MAC. --- src/sm/sm-iso.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index b702a2f4b9..9669e07ee0 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -661,6 +661,10 @@ static int iso_add_sm(struct iso_sm_ctx *sctx, sc_card_t *card, static int iso_rm_sm(struct iso_sm_ctx *sctx, sc_card_t *card, sc_apdu_t *sm_apdu, sc_apdu_t *apdu) { + if (!sctx) + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, + "Invalid SM context. No SM processing performed."); + if (sctx->post_transmit) SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->post_transmit(card, sctx, sm_apdu), "Could not complete SM specific post transmit routine"); From 0fca7df33a7e0ee1c8364e12f40efbcfc799dd1d Mon Sep 17 00:00:00 2001 From: Shahin Hajikhorasani Date: Mon, 26 Nov 2018 00:35:35 +0330 Subject: [PATCH 0644/4321] Update reader-pcsc.c (#1537) Error handling extended in case of changing the card reader --- src/libopensc/reader-pcsc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index ae0bb34b84..ac7ab2f094 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -339,6 +339,16 @@ static int refresh_attributes(sc_reader_t *reader) reader->flags &= ~SC_READER_CARD_CHANGED; LOG_FUNC_RETURN(reader->ctx, SC_SUCCESS); } + + /* the system could not dectect any reader. It means, the prevoiusly attached reader is disconnected. */ + if (rv == (LONG)SCARD_E_NO_READERS_AVAILABLE || rv == (LONG)SCARD_E_SERVICE_STOPPED) { + if (old_flags & SC_READER_CARD_PRESENT) { + reader->flags |= SC_READER_CARD_CHANGED; + } + + SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); + } + PCSC_TRACE(reader, "SCardGetStatusChange failed", rv); return pcsc_to_opensc_error(rv); } @@ -1324,7 +1334,7 @@ static int pcsc_detect_readers(sc_context_t *ctx) } else { rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, (LPDWORD) &reader_buf_size); - if (rv == (LONG)SCARD_E_NO_SERVICE) { + if ((rv == (LONG)SCARD_E_NO_SERVICE) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) { gpriv->SCardReleaseContext(gpriv->pcsc_ctx); gpriv->pcsc_ctx = 0; gpriv->pcsc_wait_ctx = -1; From fd2343f4a24fce247133a78acdc759211f0f7e52 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 19 Nov 2018 09:34:42 +0100 Subject: [PATCH 0645/4321] cac: Dump the data model number, which is useful for the capabilities detection Signed-off-by: Jakub Jelen --- src/libopensc/card-cac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 41ceabb022..2709762cc8 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1487,12 +1487,19 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG: PKCS15 = 0x%02x", *val); break; case CAC_TAG_DATA_MODEL: + if (len != 1) { + sc_log(card->ctx, "TAG: Registered Data Model Number: " + "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len); + break; + } + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG: Registered Data Model Number (0x%02x)", *val); + break; case CAC_TAG_CARD_APDU: case CAC_TAG_CAPABILITY_TUPLES: case CAC_TAG_STATUS_TUPLES: case CAC_TAG_REDIRECTION: case CAC_TAG_ERROR_CODES: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:FSSpecific(0x%02x)", tag); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG: FSSpecific(0x%02x)", tag); break; case CAC_TAG_ACCESS_CONTROL: /* TODO handle access control later */ From f1f98f829cfc316ced237b77cfb2b0abd2124e97 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Nov 2018 09:29:53 +0100 Subject: [PATCH 0646/4321] pkcs11-tool: Unbreak signature and verification in pkcs11-tool --- src/tools/pkcs11-tool.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index df4a0ef326..ff1c00acbf 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1758,6 +1758,9 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, pss_params->hashAlg = CKM_SHA512; pss_params->mgf = CKG_MGF1_SHA512; break; + + default: /* The non-RSA-PSS algorithms do not need any parameters */ + return 0; } /* One of RSA-PSS mechanisms above: They need parameters */ @@ -1820,8 +1823,6 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; hashlen = parse_pss_params(session, key, &mech, &pss_params); - if (hashlen == 0) - util_fatal("Invalid RSA-PSS parameters"); if (opt_input == NULL) fd = 0; @@ -1832,11 +1833,10 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (r < 0) util_fatal("Cannot read from %s: %m", opt_input); - if (opt_mechanism == CKM_RSA_PKCS_PSS) { - if ((unsigned long)r != hashlen) - util_fatal("For %s mechanism, message size (got %d bytes) " - "must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), r, hashlen); + if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) { + util_fatal("For %s mechanism, message size (got %d bytes) " + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), r, hashlen); } rv = CKR_CANCEL; @@ -1927,8 +1927,6 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; hashlen = parse_pss_params(session, key, &mech, &pss_params); - if (hashlen == 0) - util_fatal("Invalid RSA-PSS parameters"); /* Open a signature file */ if (opt_signature_file == NULL) @@ -1952,11 +1950,10 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (r < 0) util_fatal("Cannot read from %s: %m", opt_input); - if (opt_mechanism == CKM_RSA_PKCS_PSS) { - if ((unsigned long)r != hashlen) - util_fatal("For %s mechanism, message size (got %d bytes)" - " must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), r, hashlen); + if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) { + util_fatal("For %s mechanism, message size (got %d bytes)" + " must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), r, hashlen); } rv = CKR_CANCEL; From b01ca2dcc9bf4a19b13e2f623f974e455390435a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 25 Nov 2018 22:08:36 +0100 Subject: [PATCH 0647/4321] added support for colors (#1534) because everyone loves colors --- doc/files/opensc.conf.5.xml.in | 10 ++ src/libopensc/ctx.c | 26 ++++ src/libopensc/libopensc.exports | 2 + src/libopensc/log.c | 202 ++++++++++++++++++++++++-------- src/libopensc/log.h | 28 ++++- src/libopensc/opensc.h | 1 + src/tools/opensc-explorer.c | 7 +- 7 files changed, 219 insertions(+), 57 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index f703ce7110..9c58877987 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -166,6 +166,16 @@ app application { checked. + + + + + + Disable colors of log messages (Default: + false if attached to a console, + true otherwise). + + diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 14a039b792..92d71785cf 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -34,6 +34,7 @@ #include #include #include +#include #endif #include "common/libscdl.h" @@ -361,6 +362,24 @@ set_drivers(struct _sc_ctx_options *opts, const scconf_list *list) } } +static int is_a_tty(FILE *fp) +{ + if (fp != NULL) { + int fd = fileno(fp); + if (fd >= 0) { +#ifdef _WIN32 + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (h != INVALID_HANDLE_VALUE) { + return GetFileType(h) == FILE_TYPE_CHAR; + } +#else + return isatty(fd); +#endif + } + } + return 0; +} + static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { @@ -395,6 +414,10 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options * ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS)) ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS; + if (scconf_get_bool (block, "disable_colors", + ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)) + ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS; + if (scconf_get_bool (block, "enable_default_driver", ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER)) ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; @@ -726,6 +749,9 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) * so at least one is NULL */ for (i = 0; ctx->conf_blocks[i]; i++) load_parameters(ctx, ctx->conf_blocks[i], opts); + + if (ctx->debug_file && !is_a_tty(ctx->debug_file)) + ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS; } int sc_ctx_detect_readers(sc_context_t *ctx) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 1c770afebb..fb78073b4e 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -89,6 +89,7 @@ sc_der_copy sc_detect_card_presence sc_disconnect_card sc_do_log +sc_do_log_color sc_do_log_noframe _sc_debug _sc_debug_hex @@ -373,3 +374,4 @@ sc_notify_init sc_notify_close sc_notify sc_notify_id +sc_color_fprintf diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 9478644d32..90435cc3c9 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -41,30 +41,40 @@ #ifdef HAVE_PTHREAD #include #endif +#ifdef _WIN32 +#include +#endif #include "internal.h" -static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, const char *format, va_list args); +static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args); void sc_do_log(sc_context_t *ctx, int level, const char *file, int line, const char *func, const char *format, ...) { va_list ap; va_start(ap, format); - sc_do_log_va(ctx, level, file, line, func, format, ap); + sc_do_log_va(ctx, level, file, line, func, 0, format, ap); + va_end(ap); +} + +void sc_do_log_color(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + sc_do_log_va(ctx, level, file, line, func, color, format, ap); va_end(ap); } void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list args) { - sc_do_log_va(ctx, level, NULL, 0, NULL, format, args); + sc_do_log_va(ctx, level, NULL, 0, NULL, 0, format, args); } -static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, const char *format, va_list args) +static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args) { - char buf[4096], *p; - int r; - size_t left; + char buf[4096]; #ifdef _WIN32 SYSTEMTIME st; #else @@ -72,74 +82,78 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin struct timeval tv; char time_string[40]; #endif - FILE *outf = NULL; - int n; if (!ctx || ctx->debug < level) return; - p = buf; - left = sizeof(buf); +#ifdef _WIN32 + /* In Windows, file handles can not be shared between DLL-s, each DLL has a + * separate file handle table. Make sure we always have a valid file + * descriptor. */ + if (sc_ctx_log_to_file(ctx, ctx->debug_filename) < 0) + return; +#endif + if (ctx->debug_file == NULL) + return; #ifdef _WIN32 GetLocalTime(&st); - r = snprintf(p, left, - "P:%lu; T:%lu %i-%02i-%02i %02i:%02i:%02i.%03i ", + sc_color_fprintf(SC_COLOR_FG_GREEN|SC_COLOR_BOLD, + ctx, ctx->debug_file, + "P:%lu; T:%lu", (unsigned long)GetCurrentProcessId(), - (unsigned long)GetCurrentThreadId(), + (unsigned long)GetCurrentThreadId()); + sc_color_fprintf(SC_COLOR_FG_GREEN, + ctx, ctx->debug_file, + " %i-%02i-%02i %02i:%02i:%02i.%03i", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); #else + sc_color_fprintf(SC_COLOR_FG_GREEN|SC_COLOR_BOLD, + ctx, ctx->debug_file, + "P:%lu; T:0x%lu", + (unsigned long)getpid(), + (unsigned long)pthread_self()); gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); strftime (time_string, sizeof(time_string), "%H:%M:%S", tm); - r = snprintf(p, left, "0x%lx %s.%03ld ", (unsigned long)pthread_self(), time_string, (long)tv.tv_usec / 1000); + sc_color_fprintf(SC_COLOR_FG_GREEN, + ctx, ctx->debug_file, + " %s.%03ld", + time_string, + (long)tv.tv_usec / 1000); #endif - p += r; - left -= r; + + sc_color_fprintf(SC_COLOR_FG_YELLOW, + ctx, ctx->debug_file, + " ["); + sc_color_fprintf(SC_COLOR_FG_YELLOW|SC_COLOR_BOLD, + ctx, ctx->debug_file, + "%s", + ctx->app_name); + sc_color_fprintf(SC_COLOR_FG_YELLOW, + ctx, ctx->debug_file, + "] "); if (file != NULL) { - r = snprintf(p, left, "[%s] %s:%d:%s: ", - ctx->app_name, file, line, func ? func : ""); - if (r < 0 || (unsigned int)r > sizeof(buf)) - return; - } - else { - r = 0; + sc_color_fprintf(SC_COLOR_FG_YELLOW, + ctx, ctx->debug_file, + "%s:%d:%s: ", + file, line, func ? func : ""); } - p += r; - left -= r; - - r = vsnprintf(p, left, format, args); - if (r < 0) - return; - -#ifdef _WIN32 - /* In Windows, file handles can not be shared between DLL-s, each DLL has a - * separate file handle table. Make sure we always have a valid file - * descriptor. */ - r = sc_ctx_log_to_file(ctx, ctx->debug_filename); - if (r < 0) - return; -#endif - - outf = ctx->debug_file; - if (outf == NULL) - return; - fprintf(outf, "%s", buf); - n = strlen(buf); - if (n == 0 || buf[n-1] != '\n') - fprintf(outf, "\n"); - fflush(outf); + if (vsnprintf(buf, sizeof buf, format, args) >= 0) { + sc_color_fprintf(color, ctx, ctx->debug_file, "%s", buf); + if (strlen(buf) == 0 || buf[strlen(buf)-1] != '\n') + sc_color_fprintf(color, ctx, ctx->debug_file, "\n"); + } + fflush(ctx->debug_file); #ifdef _WIN32 if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) fclose(ctx->debug_file); ctx->debug_file = NULL; #endif - - return; } void _sc_debug(struct sc_context *ctx, int level, const char *format, ...) @@ -147,7 +161,7 @@ void _sc_debug(struct sc_context *ctx, int level, const char *format, ...) va_list ap; va_start(ap, format); - sc_do_log_va(ctx, level, NULL, 0, NULL, format, ap); + sc_do_log_va(ctx, level, NULL, 0, NULL, 0, format, ap); va_end(ap); } @@ -156,8 +170,92 @@ void _sc_log(struct sc_context *ctx, const char *format, ...) va_list ap; va_start(ap, format); - sc_do_log_va(ctx, SC_LOG_DEBUG_NORMAL, NULL, 0, NULL, format, ap); + sc_do_log_va(ctx, SC_LOG_DEBUG_NORMAL, NULL, 0, NULL, 0, format, ap); + va_end(ap); +} + +#ifdef _WIN32 +#define set_color(sc_color, win_color, vt100_color) \ + do { if (colors & sc_color) { attr |= win_color; } } while (0) +#else +#define set_color(sc_color, win_color, vt100_color) \ + do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0) +#endif + +int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...) +{ + va_list ap; + int r; +#ifdef _WIN32 + WORD old_attr = 0; + int fd = stream ? fileno(stream) : -1; + HANDLE handle = fd >= 0 ? (HANDLE) _get_osfhandle(fd) : INVALID_HANDLE_VALUE; +#endif + + if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) { +#ifdef _WIN32 + WORD attr = 0; + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(handle, &csbi); + old_attr = csbi.wAttributes; +#endif + set_color(SC_COLOR_FG_RED, + FOREGROUND_RED, + "\x1b[31m"); + set_color(SC_COLOR_FG_GREEN, + FOREGROUND_GREEN, + "\x1b[32m"); + set_color(SC_COLOR_FG_YELLOW, + FOREGROUND_GREEN|FOREGROUND_RED, + "\x1b[33m"); + set_color(SC_COLOR_FG_BLUE, + FOREGROUND_BLUE, + "\x1b[34m"); + set_color(SC_COLOR_FG_MAGENTA, + FOREGROUND_BLUE|FOREGROUND_RED, + "\x1b[35m"); + set_color(SC_COLOR_FG_CYAN, + FOREGROUND_BLUE|FOREGROUND_GREEN, + "\x1b[36m"); + set_color(SC_COLOR_BG_RED, + FOREGROUND_RED, + "\x1b[41m"); + set_color(SC_COLOR_BG_GREEN, + BACKGROUND_GREEN, + "\x1b[42m"); + set_color(SC_COLOR_BG_YELLOW, + BACKGROUND_GREEN|BACKGROUND_RED, + "\x1b[43m"); + set_color(SC_COLOR_BG_BLUE, + BACKGROUND_BLUE, + "\x1b[44m"); + set_color(SC_COLOR_BG_MAGENTA, + BACKGROUND_BLUE|BACKGROUND_RED, + "\x1b[45m"); + set_color(SC_COLOR_BG_CYAN, + BACKGROUND_BLUE|BACKGROUND_GREEN, + "\x1b[46m"); + set_color(SC_COLOR_BOLD, + FOREGROUND_INTENSITY, + "\x1b[1m"); +#ifdef _WIN32 + SetConsoleTextAttribute(handle, attr); +#endif + } + + va_start(ap, format); + r = vfprintf(stream, format, ap); va_end(ap); + + if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) { +#ifdef _WIN32 + SetConsoleTextAttribute(handle, old_attr); +#else + fprintf(stream, "\x1b[0m"); +#endif + } + + return r; } void _sc_debug_hex(sc_context_t *ctx, int type, const char *file, int line, diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 303f5c61ed..deb2fb4760 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -39,6 +39,20 @@ enum { SC_LOG_DEBUG_MATCH, /* card matching */ }; +#define SC_COLOR_FG_RED 0x0001 +#define SC_COLOR_FG_GREEN 0x0002 +#define SC_COLOR_FG_YELLOW 0x0004 +#define SC_COLOR_FG_BLUE 0x0008 +#define SC_COLOR_FG_MAGENTA 0x0010 +#define SC_COLOR_FG_CYAN 0x0020 +#define SC_COLOR_BG_RED 0x0100 +#define SC_COLOR_BG_GREEN 0x0200 +#define SC_COLOR_BG_YELLOW 0x0400 +#define SC_COLOR_BG_BLUE 0x0800 +#define SC_COLOR_BG_MAGENTA 0x1000 +#define SC_COLOR_BG_CYAN 0x2000 +#define SC_COLOR_BOLD 0x8080 + /* You can't do #ifndef __FUNCTION__ */ #if !defined(__GNUC__) && !defined(__IBMC__) && !(defined(_MSC_VER) && (_MSC_VER >= 1300)) #define __FUNCTION__ NULL @@ -63,18 +77,26 @@ enum { void sc_do_log(struct sc_context *ctx, int level, const char *file, int line, const char *func, const char *format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 6, 7))); +void sc_do_log_color(struct sc_context *ctx, int level, const char *file, int line, + const char *func, int color, const char *format, ...) + __attribute__ ((format (SC_PRINTF_FORMAT, 7, 8))); void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list args) __attribute__ ((format (SC_PRINTF_FORMAT, 3, 0))); void _sc_debug(struct sc_context *ctx, int level, const char *format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 3, 4))); void _sc_log(struct sc_context *ctx, const char *format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 2, 3))); +int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...) + __attribute__ ((format (SC_PRINTF_FORMAT, 4, 5))); #else void sc_do_log(struct sc_context *ctx, int level, const char *file, int line, const char *func, const char *format, ...); +void sc_do_log_color(struct sc_context *ctx, int level, const char *file, int line, const char *func, int color, + const char *format, ...); void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list args); void _sc_debug(struct sc_context *ctx, int level, const char *format, ...); void _sc_log(struct sc_context *ctx, const char *format, ...); +int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...); #endif /** * @brief Log binary data to a sc context @@ -115,7 +137,7 @@ const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_FUNC_RETURN(ctx, level, r) do { \ int _ret = r; \ if (_ret <= 0) { \ - sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, \ + sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \ "returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \ } else { \ sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, \ @@ -128,7 +150,7 @@ const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_TEST_RET(ctx, level, r, text) do { \ int _ret = (r); \ if (_ret < 0) { \ - sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, \ + sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ "%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \ return _ret; \ } \ @@ -138,7 +160,7 @@ const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_TEST_GOTO_ERR(ctx, level, r, text) do { \ int _ret = (r); \ if (_ret < 0) { \ - sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, \ + sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ "%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \ goto err; \ } \ diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 43d08187a4..58e7cf66ff 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -775,6 +775,7 @@ typedef struct { #define SC_CTX_FLAG_DEBUG_MEMORY 0x00000004 #define SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER 0x00000008 #define SC_CTX_FLAG_DISABLE_POPUPS 0x00000010 +#define SC_CTX_FLAG_DISABLE_COLORS 0x00000020 typedef struct sc_context { scconf_context *conf; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 16be202a25..681695435f 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -40,6 +40,7 @@ #include "libopensc/asn1.h" #include "libopensc/cardctl.h" #include "libopensc/cards.h" +#include "libopensc/log.h" #include "common/compat_strlcpy.h" #include "common/compat_getopt.h" #include "util.h" @@ -2073,14 +2074,16 @@ static char *read_cmdline(FILE *script, char *prompt) /* return in interactive case with readline */ return line; #else - printf("%s", prompt); + sc_color_fprintf(SC_COLOR_FG_BLUE|SC_COLOR_BOLD, NULL, stdout, "%s", prompt); #endif } /* either we don't have readline or we are not running interactively */ fflush(stdout); - if (fgets(buf, sizeof(buf), script) == NULL) + if (fgets(buf, sizeof(buf), script) == NULL) { + fputc('\n', stdout); return NULL; + } if (strlen(buf) == 0) return NULL; if (buf[strlen(buf)-1] == '\n') From ee8c80af4fc7be369f16aa65dc5fb999f32c866e Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Mon, 26 Nov 2018 17:02:59 +0200 Subject: [PATCH 0648/4321] Implemented handling of CKA_ALWAYS_AUTHENTICATE attribute when importing and generating keys, mapping it to pkcs#15 userConsent field. Added command line options to pkcs11-tool and pkcs15-init tool to use the feature. --- src/pkcs11/framework-pkcs15.c | 19 ++++++++++++++++++- src/pkcs15init/pkcs15-init.h | 4 +++- src/pkcs15init/pkcs15-lib.c | 3 +++ src/tools/pkcs11-tool.c | 25 ++++++++++++++++++++++++- src/tools/pkcs15-init.c | 10 ++++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 44d352b585..d096a38054 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2153,6 +2153,9 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil case CKA_OPENSC_NON_REPUDIATION: args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION); break; + case CKA_ALWAYS_AUTHENTICATE: + args.user_consent = (int) (pkcs15_check_bool_cka(attr, 1)); + break; default: /* ignore unknown attrs, or flag error? */ continue; @@ -2318,7 +2321,10 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile break; case CKA_EXTRACTABLE: if (pkcs15_check_bool_cka(attr, 1)) - args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; + args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; + break; + case CKA_ALWAYS_AUTHENTICATE: + args.user_consent = (int) (pkcs15_check_bool_cka(attr, 1)); break; default: /* ignore unknown attrs, or flag error? */ @@ -2931,6 +2937,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, char priv_label[SC_PKCS15_MAX_LABEL_SIZE]; int rc; CK_RV rv = CKR_OK; + CK_BBOOL always_auth = CK_FALSE; sc_log(context, "Keypair generation, mech = 0x%0lx", pMechanism->mechanism); @@ -3046,6 +3053,12 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, goto kpgen_done; pub_args.x509_usage = keygen_args.prkey_args.x509_usage; + len = sizeof(always_auth); + rv = attr_find(pPrivTpl, ulPrivCnt, CKA_ALWAYS_AUTHENTICATE, &always_auth, &len); + if (rv == CKR_OK && always_auth == CK_TRUE) { + keygen_args.prkey_args.user_consent = 1; + } + /* 3.a Try on-card key pair generation */ sc_pkcs15init_set_p15card(profile, fw_data->p15_card); @@ -4832,6 +4845,10 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0 && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0) ? CK_TRUE : CK_FALSE; break; + case CKA_ALWAYS_AUTHENTICATE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent; + break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); *(CK_ULONG*)attr->pValue = skey->info->data.len; diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 08beaac12d..e01ec99640 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -228,6 +228,7 @@ struct sc_pkcs15init_prkeyargs { unsigned long x509_usage; unsigned int flags; unsigned int access_flags; + int user_consent; union { struct sc_pkcs15init_keyarg_gost_params gost; @@ -269,13 +270,14 @@ struct sc_pkcs15init_skeyargs { struct sc_pkcs15_id id; struct sc_pkcs15_id auth_id; const char * label; - unsigned long usage; + unsigned long usage; unsigned int flags; unsigned int access_flags; unsigned long algorithm; /* User requested algorithm */ unsigned long value_len; /* User requested length */ int session_object; /* If nonzero. this is a session object, which will be cleared from card when the session is closed.*/ + int user_consent; struct sc_pkcs15_skey key; }; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 0ee162a341..f47bb4c3b3 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1211,6 +1211,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof key_info->key_reference = 0; key_info->modulus_length = keybits; key_info->access_flags = keyargs->access_flags; + object->user_consent = keyargs->user_consent; /* Path is selected below */ if (keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) { @@ -1352,6 +1353,8 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi if (keyargs->session_object > 0) object->session_object = 1; + object->user_consent = keyargs->user_consent; + /* Select a Key ID if the user didn't specify one, * otherwise make sure it's compatible with our intended use */ r = select_id(p15card, SC_PKCS15_TYPE_SKEY, &keyargs->id); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ff1c00acbf..3e8b3c2db0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -152,6 +152,7 @@ enum { OPT_SALT, OPT_VERIFY, OPT_SIGNATURE_FILE, + OPT_ALWAYS_AUTH }; static const struct option options[] = { @@ -221,6 +222,7 @@ static const struct option options[] = { { "test-fork", 0, NULL, OPT_TEST_FORK }, #endif { "generate-random", 1, NULL, OPT_GENERATE_RANDOM }, + { "always-auth", 0, NULL, OPT_ALWAYS_AUTH }, { NULL, 0, NULL, 0 } }; @@ -292,6 +294,7 @@ static const char *option_help[] = { "Test forking and calling C_Initialize() in the child", #endif "Generate given amount of random data", + "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -340,6 +343,7 @@ static CK_MECHANISM_TYPE opt_hash_alg = 0; static unsigned long opt_mgf = 0; static long opt_salt_len = 0; static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ +static int opt_always_auth = 0; static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -886,7 +890,9 @@ int main(int argc, char * argv[]) do_generate_random = 1; action_count++; break; - + case OPT_ALWAYS_AUTH: + opt_always_auth = 1; + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -2380,6 +2386,12 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_pubkey_attr++; } + if (opt_always_auth != 0) { + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE, + &_true, sizeof(_true)); + n_privkey_attr++; + } + rv = p11->C_GenerateKeyPair(session, &mechanism, publicKeyTemplate, n_pubkey_attr, privateKeyTemplate, n_privkey_attr, @@ -2499,6 +2511,12 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); n_attr++; + if (opt_always_auth != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_ALWAYS_AUTHENTICATE, + &_true, sizeof(_true)); + n_attr++; + } + mechanism.mechanism = opt_mechanism; } @@ -2969,6 +2987,11 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true)); n_privkey_attr++; } + if (opt_always_auth != 0) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE, + &_true, sizeof(_true)); + n_privkey_attr++; + } #ifdef ENABLE_OPENSSL if (cert.subject_len != 0) { diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index b527f684c4..296e8cfe00 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -147,6 +147,7 @@ enum { OPT_UPDATE_EXISTING, OPT_MD_CONTAINER_GUID, OPT_VERSION, + OPT_USER_CONSENT, OPT_PIN1 = 0x10000, /* don't touch these values */ OPT_PUK1 = 0x10001, @@ -218,6 +219,7 @@ const struct option options[] = { { "wait", no_argument, NULL, 'w' }, { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, + { "user-consent", required_argument, NULL, OPT_USER_CONSENT}, /* Hidden options for testing */ { "assert-pristine", no_argument, NULL, OPT_ASSERT_PRISTINE }, @@ -283,6 +285,7 @@ static const char * option_help[] = { "Wait for card insertion", "Display this message", "Verbose operation. Use several times to enable debug output.", + "Set userConsent. Default = 0", NULL, NULL, @@ -394,6 +397,7 @@ static unsigned int opt_secret_count; static int opt_ignore_ca_certs = 0; static int opt_update_existing = 0; static int verbose = 0; +static int opt_user_consent = 0; static struct sc_pkcs15init_callbacks callbacks = { get_pin_callback, /* get_pin() */ @@ -1814,6 +1818,7 @@ static int init_prkeyargs(struct sc_pkcs15init_prkeyargs *args) args->guid = (unsigned char *)opt_md_container_guid; args->guid_len = strlen(opt_md_container_guid); } + args->user_consent = opt_user_consent; return 0; } @@ -1842,6 +1847,7 @@ static int init_skeyargs(struct sc_pkcs15init_skeyargs *args) if ((opt_x509_usage & SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) == SC_PKCS15INIT_X509_KEY_ENCIPHERMENT) { args->usage |= SC_PKCS15_PRKEY_USAGE_WRAP | SC_PKCS15_PRKEY_USAGE_UNWRAP; } + args->user_consent = opt_user_consent; return 0; } @@ -2848,6 +2854,10 @@ handle_option(const struct option *opt) case OPT_VERSION: this_action = ACTION_PRINT_VERSION; break; + case OPT_USER_CONSENT: + if (optarg != NULL) + opt_user_consent = atoi(optarg); + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } From 9e5a324903f3129f8205fab8fd15de65aca2fa05 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 4 Dec 2018 13:57:44 +0200 Subject: [PATCH 0649/4321] Edited according to PR review: CKA_ALWAYS_AUTHENTICATE only associated with private keys. Defined a custom attribute to achieve same functionality with secret keys. Updated man pages. --- doc/tools/pkcs11-tool.1.xml | 9 +++++++++ doc/tools/pkcs15-init.1.xml | 14 ++++++++++++++ src/pkcs11/framework-pkcs15.c | 6 +++--- src/pkcs11/pkcs11-opensc.h | 6 ++++++ src/tools/pkcs11-tool.c | 12 +++--------- src/tools/pkcs15-init.c | 4 ++-- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index fd823c06e7..c83aafd5b2 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -444,6 +444,15 @@ viewable after a login). + + + + + Set the CKA_ALWAYS_AUTHENTICATE attribute to a private key object. + If set, the user has to supply the PIN for each use (sign or decrypt) with the key. + + + diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 9b520187f1..88e73c7ae7 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -873,6 +873,20 @@ puk 87654321 + + + arg + + + + Specify user-consent. arg is an integer value. + If > 0, the value specifies how many times the + object can be accessed before a new authentication is required. + If zero, the object does not require re-authentication. + + + + diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index d096a38054..252d4175da 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2323,7 +2323,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile if (pkcs15_check_bool_cka(attr, 1)) args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; break; - case CKA_ALWAYS_AUTHENTICATE: + case CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT: args.user_consent = (int) (pkcs15_check_bool_cka(attr, 1)); break; default: @@ -4845,9 +4845,9 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0 && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0) ? CK_TRUE : CK_FALSE; break; - case CKA_ALWAYS_AUTHENTICATE: + case CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent; + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent == 1 ? CK_TRUE : CK_FALSE; break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index aebc6351c9..fef2f7aa42 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -20,4 +20,10 @@ #define CKA_SPKI (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 2UL) +/* In PKCS#11 CKA_ALWAYS_AUTHENTICATE attribute is only associated with private keys. + * The corresponding userConsent field in PKCS#15 is allowed for any object type. This attribute can be used + * to set userConsent=1 for other objects than private keys via PKCS#11. */ +#define CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 3UL) + + #endif diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 3e8b3c2db0..d60132c578 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -217,12 +217,12 @@ static const struct option options[] = { { "verbose", 0, NULL, 'v' }, { "private", 0, NULL, OPT_PRIVATE }, { "sensitive", 0, NULL, OPT_SENSITIVE }, + { "always-auth", 0, NULL, OPT_ALWAYS_AUTH }, { "test-ec", 0, NULL, OPT_TEST_EC }, #ifndef _WIN32 { "test-fork", 0, NULL, OPT_TEST_FORK }, #endif { "generate-random", 1, NULL, OPT_GENERATE_RANDOM }, - { "always-auth", 0, NULL, OPT_ALWAYS_AUTH }, { NULL, 0, NULL, 0 } }; @@ -289,12 +289,12 @@ static const char *option_help[] = { "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", "Set the CKA_PRIVATE attribute (object is only viewable after a login)", "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", + "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 "Test forking and calling C_Initialize() in the child", #endif - "Generate given amount of random data", - "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", + "Generate given amount of random data" }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -2511,12 +2511,6 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); n_attr++; - if (opt_always_auth != 0) { - FILL_ATTR(keyTemplate[n_attr], CKA_ALWAYS_AUTHENTICATE, - &_true, sizeof(_true)); - n_attr++; - } - mechanism.mechanism = opt_mechanism; } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 296e8cfe00..d9854a426d 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -206,6 +206,7 @@ const struct option options[] = { { "update-existing", no_argument, NULL, OPT_UPDATE_EXISTING}, { "extractable", no_argument, NULL, OPT_EXTRACTABLE }, + { "user-consent", required_argument, NULL, OPT_USER_CONSENT}, { "insecure", no_argument, NULL, OPT_INSECURE }, { "use-default-transport-keys", no_argument, NULL, 'T' }, @@ -219,7 +220,6 @@ const struct option options[] = { { "wait", no_argument, NULL, 'w' }, { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, - { "user-consent", required_argument, NULL, OPT_USER_CONSENT}, /* Hidden options for testing */ { "assert-pristine", no_argument, NULL, OPT_ASSERT_PRISTINE }, @@ -273,6 +273,7 @@ static const char * option_help[] = { "Store or update existing certificate", "Private key stored as an extractable key", + "Set userConsent. Default = 0", "Insecure mode: do not require a PIN for private key", "Do not ask for transport keys if the driver thinks it knows the key", "Do not prompt the user; if no PINs supplied, pinpad will be used", @@ -285,7 +286,6 @@ static const char * option_help[] = { "Wait for card insertion", "Display this message", "Verbose operation. Use several times to enable debug output.", - "Set userConsent. Default = 0", NULL, NULL, From 7d640e62c1fc7c2fd45ddd5a59e29e521fe8dccb Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 5 Dec 2018 10:31:18 +0200 Subject: [PATCH 0650/4321] Fixed incorrect conversion fron int to CK_BBOOL when converting PKCS#15 user consent to a PKCS#11 attribute --- src/pkcs11/framework-pkcs15.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 252d4175da..23c3ff1c22 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3670,7 +3670,7 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_ALWAYS_AUTHENTICATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = prkey->prv_p15obj->user_consent; + *(CK_BBOOL*)attr->pValue = prkey->prv_p15obj->user_consent >= 1 ? CK_TRUE : CK_FALSE; break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); @@ -4847,7 +4847,7 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent == 1 ? CK_TRUE : CK_FALSE; + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent >= 1 ? CK_TRUE : CK_FALSE; break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); From 2552fde05f78fe457bcdd15a7696caf3a495914d Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 5 Dec 2018 12:41:58 +0100 Subject: [PATCH 0651/4321] Fix some pinpad reader related issues (#1540) 1. Show pinpad reader capabilities even for uninitialised tokens. This way pinpad can be used during initialisation. 2. Make possible to create so-pin object during initialisation even if no so-pin was provided (on the command line) but pinpad reader is used and card profile contains so-pin data. --- src/pkcs11/framework-pkcs15.c | 5 +++++ src/pkcs15init/pkcs15-lib.c | 20 +++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 23c3ff1c22..c1d04dd7ba 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1140,6 +1140,11 @@ pkcs15_create_slot(struct sc_pkcs11_card *p11card, struct pkcs15_fw_data *fw_dat /* Fill in the slot/token info from pkcs15 data */ if (fw_data) pkcs15_init_slot(fw_data->p15_card, slot, auth, app_info); + else { + /* Token is not initialized, announce pinpad capability nevertheless */ + if (slot->reader->capabilities & SC_READER_CAP_PIN_PAD) + slot->token_info.flags |= CKF_PROTECTED_AUTHENTICATION_PATH; + } *out = slot; return CKR_OK; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index f47bb4c3b3..cd46fd6604 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -771,6 +771,7 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, struct sc_app_info *app; struct sc_file *df = profile->df_info->file; int r = SC_SUCCESS; + int has_so_pin = args->so_pin_len != 0; LOG_FUNC_CALLED(ctx); p15card->card = card; @@ -784,13 +785,22 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, if (card->app_count >= SC_MAX_CARD_APPS) LOG_TEST_RET(ctx, SC_ERROR_TOO_MANY_OBJECTS, "Too many applications on this card."); + /* In case of pinpad readers check if SO PIN is defined in a profile */ + if (!has_so_pin && (card->reader->capabilities & SC_READER_CAP_PIN_PAD)) { + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_ainfo); + /* If found, assume we want SO PIN */ + has_so_pin = pin_ainfo.attrs.pin.reference != -1; + } + /* If the profile requires an SO PIN, check min/max length */ - if (args->so_pin_len) { + if (has_so_pin) { const char *pin_label; - sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_ainfo); - r = sc_pkcs15init_qualify_pin(card, "SO PIN", args->so_pin_len, &pin_ainfo); - LOG_TEST_RET(ctx, r, "Failed to qualify SO PIN"); + if (args->so_pin_len) { + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_ainfo); + r = sc_pkcs15init_qualify_pin(card, "SO PIN", args->so_pin_len, &pin_ainfo); + LOG_TEST_RET(ctx, r, "Failed to qualify SO PIN"); + } /* Path encoded only for local SO PIN */ if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_LOCAL) @@ -3791,7 +3801,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p found: if (pin_obj) { - r = sc_pkcs15_verify_pin(p15card, pin_obj, pinsize ? pinbuf : NULL, pinsize); + r = sc_pkcs15_verify_pin(p15card, pin_obj, use_pinpad ? NULL : pinbuf, use_pinpad ? 0 : pinsize); LOG_TEST_RET(ctx, r, "Cannot validate pkcs15 PIN"); } From ba7704291180882dbfa18705f4169a88bc5d61ae Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Tue, 27 Nov 2018 12:53:54 +0100 Subject: [PATCH 0652/4321] Fix token label formatting PKCS#15 token label may be padded with spaces, trim it when making a PKCS#11 token label in order not to loose closing parenthesis. I would actually prefer for the token label to be "myCard (User PIN)" instead of current "User PIN (myCard)" before: $ pkcs11-tool --list-slots Available slots: Slot 0 (0x0): OMNIKEY AG CardMan 3121 00 00 token label : User PIN (myCard ... after: $ pkcs11-tool --list-slots Available slots: Slot 0 (0x0): OMNIKEY AG CardMan 3121 00 00 token label : User PIN (myCard) ... --- src/pkcs11/framework-pkcs15.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index c1d04dd7ba..cc74414199 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1091,11 +1091,18 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, pin_info = NULL; } else { - if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) + if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) { + /* Trim tokeninfo->label to make right parenthesis visible */ + char tokeninfo_label[sizeof label]; + int len; + snprintf(tokeninfo_label, sizeof(tokeninfo_label), "%s", p15card->tokeninfo->label); + for (len = strlen(tokeninfo_label) - 1; len >= 0 && tokeninfo_label[len] == ' '; len--) { + tokeninfo_label[len] = 0; + } snprintf(label, sizeof(label), "%.*s (%s)", (int) sizeof(auth->label), auth->label, - p15card->tokeninfo->label); - else + tokeninfo_label); + } else /* The PIN label is empty or says just non-useful "PIN" */ snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label); slot->token_info.flags |= CKF_LOGIN_REQUIRED; From 18dc38a6182338491c1eb4bf4d1eabbe8ebbd5ee Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Tue, 27 Nov 2018 12:53:54 +0100 Subject: [PATCH 0653/4321] Fix some pkcs15-init issues 1. pkcs15-init is using XKU but it should use cert KU to check private key usage instead. 2. Don't mark imported keys as ALWAYSSENSITIVE and NEVEREXTRACTABLE as they are not. 3. When importing keys from PKCS#12 files (with several certs inside), use consecutive IDs for additional certificates (instead of starting from 45). --- src/tools/pkcs15-init.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index d9854a426d..d98b787a18 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1004,6 +1004,19 @@ failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r)); return SC_ERROR_PKCS15INIT; } +static void sc_pkcs15_inc_id(sc_pkcs15_id_t *id) +{ + int len; + for (len = id->len - 1; len >= 0; len--) { + if (id->value[len]++ != 0xFF) + break; + } + if (len < 0 && id->len < SC_PKCS15_MAX_ID_SIZE) { + memmove(id->value + 1, id->value, id->len++); + id->value[0] = 1; + } +} + /* * Store a private key */ @@ -1042,12 +1055,14 @@ do_store_private_key(struct sc_profile *profile) /* tell openssl to cache the extensions */ X509_check_purpose(cert[0], -1, -1); - usage = X509_get_extended_key_usage(cert[0]); + usage = X509_get_key_usage(cert[0]); /* No certificate usage? Assume ordinary * user cert */ if (usage == 0) - usage = 0x1F; + usage = KU_NON_REPUDIATION + | KU_DIGITAL_SIGNATURE + | KU_KEY_ENCIPHERMENT; /* If the user requested a specific key usage on the * command line check if it includes _more_ @@ -1065,10 +1080,7 @@ do_store_private_key(struct sc_profile *profile) args.x509_usage = opt_x509_usage? opt_x509_usage : usage; } - args.access_flags |= - SC_PKCS15_PRKEY_ACCESS_SENSITIVE - | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE - | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; + args.access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE; r = sc_lock(p15card->card); if (r < 0) @@ -1096,7 +1108,7 @@ do_store_private_key(struct sc_profile *profile) return r; X509_check_purpose(cert[i], -1, -1); - cargs.x509_usage = X509_get_extended_key_usage(cert[i]); + cargs.x509_usage = X509_get_key_usage(cert[i]); cargs.label = cert_common_name(cert[i]); if (!cargs.label) @@ -1114,6 +1126,8 @@ do_store_private_key(struct sc_profile *profile) printf("Certificate #%d already present, not stored.\n", i); goto next_cert; } + sc_pkcs15_inc_id(&args.id); + cargs.id = args.id; cargs.authority = 1; } @@ -1238,10 +1252,7 @@ do_store_secret_key(struct sc_profile *profile) args.algorithm = algorithm; args.value_len = keybits; - args.access_flags |= - SC_PKCS15_PRKEY_ACCESS_SENSITIVE - | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE - | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; + args.access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE; r = sc_lock(p15card->card); if (r < 0) From cf55cdc637a2bd6c4fde76d2f038d32d87ba0c8f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Nov 2018 09:14:50 +0100 Subject: [PATCH 0654/4321] replace SC_FUNC_CALLED with LOG_FUNC_CALLED --- src/libopensc/card-asepcos.c | 6 +- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-cac.c | 4 +- src/libopensc/card-cardos.c | 2 +- src/libopensc/card-coolkey.c | 4 +- src/libopensc/card-gids.c | 10 +-- src/libopensc/card-jcop.c | 2 +- src/libopensc/card-mcrd.c | 6 +- src/libopensc/card-myeid.c | 3 +- src/libopensc/card-rutoken.c | 24 +++--- src/libopensc/card-starcos.c | 2 +- src/libopensc/card-tcos.c | 2 +- src/libopensc/card.c | 4 +- src/libopensc/ctx.c | 6 +- src/libopensc/log.h | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 2 +- src/libopensc/pkcs15-pin.c | 2 +- src/libopensc/sec.c | 14 ++-- src/pkcs15init/pkcs15-asepcos.c | 4 +- src/pkcs15init/pkcs15-cflex.c | 10 +-- src/pkcs15init/pkcs15-oberthur-awp.c | 56 +++++++------- src/sm/sm-common.c | 4 +- src/sm/sm-eac.c | 42 +++++----- src/smm/sm-card-authentic.c | 20 ++--- src/smm/sm-card-iasecc.c | 50 ++++++------ src/smm/sm-cwa14890.c | 60 +++++++-------- src/smm/sm-global-platform.c | 30 ++++---- src/smm/smm-local.c | 111 +++++++++++++-------------- 28 files changed, 240 insertions(+), 244 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index bac86e2da7..939e3f2e9f 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -267,7 +267,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path, int r; sc_path_t npath = *in_path; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (in_path->type == SC_PATH_TYPE_PATH) { /* check the current DF to avoid unnecessary re-selection of @@ -436,7 +436,7 @@ static int asepcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_le int r; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); /* call RSA ENCRYPT DECRYPT for the decipher operation */ sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x14, 0x01, 0x00); @@ -469,7 +469,7 @@ static int asepcos_compute_signature(sc_card_t *card, const u8 *data, size_t dat u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (datalen >= 256) atype = SC_APDU_CASE_4_EXT; diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 05ef0f4413..87b1df9bd7 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -767,7 +767,7 @@ static int atrust_acos_decipher(struct sc_card *card, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; assert(card != NULL && crgram != NULL && out != NULL); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (crgram_len > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 2709762cc8..8f313bb62f 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -667,7 +667,7 @@ static int cac_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* seri { cac_private_data_t * priv = CAC_DATA(card); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->serialnr.len) { *serial = card->serialnr; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); @@ -684,7 +684,7 @@ static int cac_get_ACA_path(sc_card_t *card, sc_path_t *path) { cac_private_data_t * priv = CAC_DATA(card); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (priv->aca_path) { *path = *priv->aca_path; } diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 48625923a2..a450da0fe8 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -595,7 +595,7 @@ static int cardos_construct_fcp(sc_card_t *card, const sc_file_t *file, size_t inlen = *outlen, len; int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (out == NULL || inlen < 64) return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 11c4e92643..c17e7a9679 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1359,7 +1359,7 @@ static int coolkey_get_token_info(sc_card_t *card, sc_pkcs15_tokeninfo_t * token char *manufacturer_id = NULL; char *serial_number = NULL; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); label = strdup((char *)priv->token_name); manufacturer_id = coolkey_get_manufacturer(&priv->cuid); serial_number = coolkey_cuid_to_string(&priv->cuid); @@ -1380,7 +1380,7 @@ static int coolkey_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* { coolkey_private_data_t * priv = COOLKEY_DATA(card); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); memcpy(serial->value, &priv->cuid, sizeof(priv->cuid)); serial->len = sizeof(priv->cuid); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 002faee50b..b725fac28f 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -745,7 +745,7 @@ static int gids_set_security_env(sc_card_t *card, assert(card != NULL && env != NULL); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); memset(sbuf, 0, sizeof(sbuf)); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_MANAGE_SECURITY_ENVIRONMENT, P1_DECIPHERMENT_INTERNAL_AUTHENTICATE_KEY_AGREEMENT, 0); @@ -827,7 +827,7 @@ static int gids_logout(sc_card_t *card) int r; assert(card && card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); // use the special PIN to deauthenticate sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_VERIFY, 0x00, P2_PIN_DEAUTHENTICATE); @@ -917,7 +917,7 @@ static int gids_select_file(sc_card_t *card, const struct sc_path *in_path, struct sc_context *ctx = card->ctx; struct gids_private_data *data = (struct gids_private_data *) card->drv_data; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); data->state = GIDS_STATE_NONE; data->currentDO = 0; @@ -985,7 +985,7 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, int r; int size; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (! data->currentDO || ! data->currentEFID) { LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); @@ -2016,7 +2016,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { static int gids_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); switch (cmd) { case SC_CARDCTL_GET_SERIALNR: return gids_get_serialnr(card, (sc_serial_number_t *) ptr); diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index d2269b14ca..a8dfa8d3db 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -756,7 +756,7 @@ static int jcop_decipher(sc_card_t *card, struct jcop_private_data *drvdata=DRVDATA(card); assert(card != NULL && crgram != NULL && out != NULL); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (crgram_len > 256) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); if (drvdata->invalid_senv) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index c11c446253..146b4cf02f 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1169,7 +1169,7 @@ static int mcrd_set_security_env(sc_card_t * card, if (!(card != NULL && env != NULL)) return SC_ERROR_INTERNAL; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); priv = DRVDATA(card); /* special environment handling for esteid, stolen from openpgp */ @@ -1341,7 +1341,7 @@ static int mcrd_compute_signature(sc_card_t * card, return SC_ERROR_INVALID_ARGUMENTS; env = &priv->sec_env; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (env->operation != SC_SEC_OPERATION_SIGN) return SC_ERROR_INVALID_ARGUMENTS; if (datalen > 255) @@ -1437,7 +1437,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int *tries_left) { int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); data->pin1.offset = 5; data->pin1.length_offset = 4; data->pin2.offset = 5; diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 2715d07d53..f02803e91b 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1172,7 +1172,6 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; LOG_FUNC_CALLED(card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); assert(card != NULL && crgram != NULL && out != NULL); @@ -1307,7 +1306,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra } LOG_FUNC_CALLED(card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (crgram_len > MYEID_MAX_RSA_KEY_LEN / 8) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 0930f8cdf5..5f3dc70572 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -111,7 +111,7 @@ static int rutoken_match_card(sc_card_t *card) static int token_init(sc_card_t *card, const char *card_name) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); card->name = card_name; card->caps |= SC_CARD_CAP_RNG; @@ -479,7 +479,7 @@ static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, u8 buf[64], *p = out; assert(card && card->ctx); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); assert(file && out && outlen); assert(*outlen >= (size_t)(p - out) + 2); @@ -548,7 +548,7 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) sc_SecAttrV2_t attr = { 0 }; int ret = SC_SUCCESS; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (file->type == SC_FILE_TYPE_DF) { @@ -850,7 +850,7 @@ static int rutoken_key_gen(sc_card_t *card, sc_DOHdrV2_t *pHdr) sc_apdu_t apdu; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if ( (pHdr->wDOBodyLen != SC_RUTOKEN_DEF_LEN_DO_GOST) || (pHdr->OTID.byObjectType != SC_RUTOKEN_TYPE_KEY) || @@ -883,7 +883,7 @@ static int rutoken_create_do(sc_card_t *card, sc_DO_V2_t * pDO) sc_apdu_t apdu; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if ( ((pDO->HDR.OTID.byObjectType & SC_RUTOKEN_TYPE_CHV) && (pDO->HDR.OTID.byObjectID != SC_RUTOKEN_DEF_ID_GCHV_USER) && @@ -925,7 +925,7 @@ static int rutoken_get_do_info(sc_card_t *card, sc_DO_INFO_t * pInfo) sc_apdu_t apdu; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if ((pInfo->SelType != select_first) && ((pInfo->DoId < SC_RUTOKEN_DO_ALL_MIN_ID) || (pInfo->DoId > SC_RUTOKEN_DO_NOCHV_MAX_ID_V2))) @@ -971,7 +971,7 @@ static int rutoken_delete_do(sc_card_t *card, u8 *pId) sc_apdu_t apdu; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if ((*pId < SC_RUTOKEN_DO_ALL_MIN_ID) || (*pId > SC_RUTOKEN_DO_NOCHV_MAX_ID_V2)) { @@ -1001,7 +1001,7 @@ static int rutoken_cipher_p(sc_card_t *card, const u8 * crgram, size_t crgram_le int ret; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, ": crgram_len %"SC_FORMAT_LEN_SIZE_T"u; outlen %"SC_FORMAT_LEN_SIZE_T"u", crgram_len, outlen); @@ -1088,7 +1088,7 @@ static int rutoken_compute_mac_gost(sc_card_t *card, int ret; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (!in || !out || olen != 4 || ilen == 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); do @@ -1163,7 +1163,7 @@ static int rutoken_get_serial(sc_card_t *card, sc_serial_number_t *serial) sc_apdu_t apdu; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0x81); apdu.resp = serial->value; apdu.resplen = sizeof(serial->value); @@ -1182,7 +1182,7 @@ static int rutoken_get_info(sc_card_t *card, void *buff) u8 rbuf[8]; int ret; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0x89); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -1200,7 +1200,7 @@ static int rutoken_format(sc_card_t *card, int apdu_ins) int ret; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, apdu_ins, 0x00, 0x00); apdu.cla = 0x80; ret = sc_transmit_apdu(card, &apdu); diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 619452c430..1b7b5df9ea 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1854,7 +1854,7 @@ static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, { int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); switch (card->type) { case SC_CARD_TYPE_STARCOS_V3_4: case SC_CARD_TYPE_STARCOS_V3_5: diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index f880295afa..ab8513cd2d 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -615,7 +615,7 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, tcos3=(card->type==SC_CARD_TYPE_TCOS_V3); data=(tcos_data *)card->drv_data; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "TCOS3:%d PKCS1:%d\n",tcos3, !!(data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1)); diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 4426fb1276..5d195dda35 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1362,7 +1362,7 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo return SC_ERROR_INVALID_ARGUMENTS; } ctx = card->ctx; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (!in_module) return sc_card_sm_unload(card); @@ -1459,7 +1459,7 @@ sc_card_sm_check(struct sc_card *card) scconf_block *atrblock = NULL, *sm_conf_block = NULL; int rv, ii; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_log(ctx, "card->sm_ctx.ops.open %p", card->sm_ctx.ops.open); /* get the name of card specific SM configuration section */ diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 92d71785cf..e2c8f64a84 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -906,7 +906,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) /* Used by minidriver to pass in provided handles to reader-pcsc */ int sc_ctx_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void *pcsc_card_handle) { - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (ctx->reader_driver->ops->use_reader != NULL) return ctx->reader_driver->ops->use_reader(ctx, pcsc_context_handle, pcsc_card_handle); @@ -916,7 +916,7 @@ int sc_ctx_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void *pcsc_c /* Following two are only implemented with internal PC/SC and don't consume a reader object */ int sc_cancel(sc_context_t *ctx) { - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (ctx->reader_driver->ops->cancel != NULL) return ctx->reader_driver->ops->cancel(ctx); @@ -926,7 +926,7 @@ int sc_cancel(sc_context_t *ctx) int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, int timeout, void **reader_states) { - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (ctx->reader_driver->ops->wait_for_event != NULL) return ctx->reader_driver->ops->wait_for_event(ctx, event_mask, event_reader, event, timeout, reader_states); diff --git a/src/libopensc/log.h b/src/libopensc/log.h index deb2fb4760..527281f22b 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -34,7 +34,7 @@ enum { SC_LOG_DEBUG_VERBOSE, /* helps users */ SC_LOG_DEBUG_NORMAL, /* helps developers */ SC_LOG_DEBUG_RFU1, /* RFU */ - SC_LOG_DEBUG_RFU2, /* RFU */ + SC_LOG_DEBUG_SM, /* secure messaging */ SC_LOG_DEBUG_ASN1, /* asn1.c */ SC_LOG_DEBUG_MATCH, /* card matching */ }; diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index f51651f4bb..97a6734745 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -106,7 +106,7 @@ static int my_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data * data, int saved_len = 0; u8 newpin[8]; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); memset(newpin, 0xff, sizeof(newpin)); diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index ab94e74f0c..459230b50b 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -835,7 +835,7 @@ void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card) struct sc_pkcs15_object *objs[32]; int i, r; - SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(p15card->card->ctx); r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32); for (i = 0; i < r; i++) sc_pkcs15_free_object_content(objs[i]); diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index e2ea41a807..f6d17248e2 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -40,7 +40,7 @@ int sc_decipher(sc_card_t *card, if (card == NULL || crgram == NULL || out == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->decipher == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->decipher(card, crgram, crgram_len, out, outlen); @@ -56,7 +56,7 @@ int sc_compute_signature(sc_card_t *card, if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->compute_signature == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->compute_signature(card, data, datalen, out, outlen); @@ -71,7 +71,7 @@ int sc_unwrap(sc_card_t *card, if (card == NULL || crgram == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->unwrap == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->unwrap(card, crgram, crgram_len); @@ -86,7 +86,7 @@ int sc_wrap(sc_card_t *card, if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->wrap == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->wrap(card, out, outlen); @@ -102,7 +102,7 @@ int sc_set_security_env(sc_card_t *card, if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->set_security_env == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->set_security_env(card, env, se_num); @@ -116,7 +116,7 @@ int sc_restore_security_env(sc_card_t *card, int se_num) if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->restore_security_env == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); r = card->ops->restore_security_env(card, se_num); @@ -197,7 +197,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(card->ctx); if (card->ops->pin_cmd) { r = card->ops->pin_cmd(card, data, tries_left); } else if (!(data->flags & SC_PIN_CMD_USE_PINPAD)) { diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index 41d8551c78..a130aedb43 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -136,7 +136,7 @@ static int asepcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *tfile; sc_context_t *ctx = p15card->card->ctx; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); /* Check whether a transport exists and verify it if present */ r = asepcos_check_verify_tpin(profile, p15card); if (r != SC_SUCCESS) @@ -350,7 +350,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *tfile = NULL; sc_context_t *ctx = p15card->card->ctx; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (!pin || !pin_len) return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 19579d836f..d732c87bc5 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -86,7 +86,7 @@ static int cflex_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15car sc_file_t *df = profile->df_info->file, *dir, *userpinfile = NULL; int r; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); /* Delete EF(DIR). This may not be very nice * against other applications that use this file, but * extremely useful for testing :) @@ -225,7 +225,7 @@ cflex_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df int ndummies, pin_type, puk_type, r; sc_file_t *file = NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; @@ -439,7 +439,7 @@ cflex_create_dummy_chvs(sc_profile_t *profile, sc_pkcs15_card_t *p15card, const sc_acl_entry_t *acl; int r = 0, ndummies = 0; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); /* See if the DF is supposed to be PIN protected, and if * it is, whether that CHV file actually exists. If it doesn't, * create it. @@ -530,7 +530,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *dummies[2], *file; int r, ndummies; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (file_ret) *file_ret = NULL; @@ -623,7 +623,7 @@ cflex_create_empty_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, { int r; - SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(p15card->card->ctx); *file_ret = NULL; r = cflex_create_pin_file(profile, p15card, path, ref, dummy_pin_value, sizeof(dummy_pin_value), 8, diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 9b12f06cb1..754a16a159 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -94,7 +94,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, char name[NAME_MAX_LEN]; const char *itag=NULL, *otag=NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type 0x%X; num %i; info %p; obj %p", type, num, info_out, obj_out); switch (type) { case SC_PKCS15_TYPE_CERT_X509: @@ -201,7 +201,7 @@ awp_update_blob(struct sc_context *ctx, { unsigned char *pp; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); switch (type) { case TLV_TYPE_LLV : if (!(pp = realloc(*blob, *blob_size + 2 + lv->len))) @@ -243,7 +243,7 @@ awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, int unsigned ii, marks[5] = {4,6,8,10,0}; unsigned char rand_buf[0x10]; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (len<0x34) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCORRECT_PARAMETERS, "Invalid container update size"); @@ -273,7 +273,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * int rv; unsigned char *buff = NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "container file(file-id:%X,rlen:%i,rcount:%i)", list_file->id, list_file->record_length, list_file->record_count); @@ -317,7 +317,7 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_file *clist = NULL, *file = NULL; int rv = 0; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create container(%X:%X:%X)", acc->prkey_id, acc->cert_id, acc->pubkey_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); @@ -349,7 +349,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p int rv; unsigned char *buff = NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "update container entry(type:%X,id %i,rec %i,offs %i", type, file_id, rec, offs); @@ -430,7 +430,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, int rv = 0, rec, rec_offs; unsigned char *list = NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "update container(type:%X,obj_id:%X)", type, obj_id); if (prkey_id) @@ -565,7 +565,7 @@ awp_set_certificate_info (struct sc_pkcs15_card *p15card, unsigned char *blob; const char *default_cert_label = "Certificate"; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); blob_size = 2; if (!(blob = malloc(blob_size))) { r = SC_ERROR_OUT_OF_MEMORY; @@ -640,7 +640,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil int rv; unsigned ii; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type %i, num %i", type, num); switch (type) { case SC_PKCS15_TYPE_CERT_X509: @@ -764,7 +764,7 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj struct sc_pkcs15_prkey_info *key_info; int r = 0; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); ERR_load_ERR_strings(); ERR_load_crypto_strings(); @@ -846,7 +846,7 @@ awp_set_key_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, st int r = 0, blob_size; unsigned char *blob; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file:%p, kinfo:%p, cinfo:%p", file, ki, ci); blob_size = 2; blob = malloc(blob_size); @@ -927,7 +927,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob BIO *mem = NULL; X509 *x = NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); ERR_load_ERR_strings(); ERR_load_crypto_strings(); @@ -1101,7 +1101,7 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob unsigned char *buf = NULL; size_t buflen; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (!obj || !di) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "AWP encode data failed: invalid parameters"); @@ -1168,7 +1168,7 @@ awp_set_data_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, int r = 0, blob_size; unsigned char *blob; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug (ctx, SC_LOG_DEBUG_NORMAL, "Set 'DATA' info %p", di); blob_size = 2; if (!(blob = malloc(blob_size))) { @@ -1249,7 +1249,7 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, size_t offs; int len; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); offs = 0; /* Flags */ @@ -1315,7 +1315,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, unsigned char *buf; size_t buf_len; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_PRKEY_RSA, prvkey_id & 0xFF, &info_file, &key_file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update key info failed: instantiation error"); @@ -1375,7 +1375,7 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro unsigned prvkey_id, obj_id; int rv; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); der = obj->content; path = ((struct sc_pkcs15_cert_info *)obj->data)->path; @@ -1432,7 +1432,7 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p struct sc_pkcs15_cert *p15cert = NULL; int rv; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); memset(&ikey, 0, sizeof(ikey)); memset(&icert, 0, sizeof(icert)); @@ -1516,7 +1516,7 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p unsigned obj_id; int index, rv; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); path = ((struct sc_pkcs15_pubkey_info *)obj->data)->path; der = obj->content; @@ -1565,7 +1565,7 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro unsigned obj_id, obj_type = obj->auth_id.len ? COSM_TYPE_PRIVDATA_OBJECT : SC_PKCS15_TYPE_DATA_OBJECT; int rv; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); der = obj->content; path = ((struct sc_pkcs15_data_info *)obj->data)->path; @@ -1602,7 +1602,7 @@ awp_update_df_create(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_context *ctx = p15card->card->ctx; int rv = SC_ERROR_INTERNAL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (!object) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); @@ -1640,7 +1640,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, int rv = 0, ii; unsigned char *buff=NULL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "update container entry (type:%X,file-id:%X)", type, file_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); @@ -1723,7 +1723,7 @@ awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile * unsigned char *buff=NULL; unsigned char id[2]; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type %X; obj_id %X",type, obj_id); switch (type) { @@ -1796,7 +1796,7 @@ awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro int rv = SC_ERROR_NOT_SUPPORTED; unsigned file_id; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); path = ((struct sc_pkcs15_cert_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; @@ -1830,7 +1830,7 @@ awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p int rv = SC_ERROR_NOT_SUPPORTED; unsigned file_id; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); path = ((struct sc_pkcs15_prkey_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; @@ -1864,7 +1864,7 @@ awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p int rv = SC_ERROR_NOT_SUPPORTED; unsigned file_id; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); path = ((struct sc_pkcs15_pubkey_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; @@ -1898,7 +1898,7 @@ awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro int rv = SC_ERROR_NOT_SUPPORTED; unsigned file_id; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); path = ((struct sc_pkcs15_data_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; @@ -1926,7 +1926,7 @@ awp_update_df_delete(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_context *ctx = p15card->card->ctx; int rv = SC_ERROR_INTERNAL; - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + LOG_FUNC_CALLED(ctx); if (!object) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 0a19eb203d..f9c1995aea 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -315,7 +315,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, size_t data_len, st; LOG_FUNC_CALLED(ctx); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM encrypt_des_cbc3: not_force_pad:%i,in_len:%"SC_FORMAT_LEN_SIZE_T"u", not_force_pad, in_len); if (!out || !out_len) @@ -337,7 +337,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, memcpy(data + in_len, "\x80\0\0\0\0\0\0\0", 8); data_len = in_len + (not_force_pad ? 7 : 8); data_len -= (data_len%8); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM encrypt_des_cbc3: data to encrypt (len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", data_len, sc_dump_hex(data, data_len)); diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 9ac9807ca4..c937439b5d 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -482,7 +482,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, r = SC_ERROR_INTERNAL; goto err; } - sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, "MSE command data", data_no_sequence, length); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MSE command data", data_no_sequence, length); p = realloc(*cdata, length); @@ -639,7 +639,7 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, apdu.datalen = r; apdu.lc = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen); apdu.resplen = sizeof resp; apdu.resp = resp; @@ -651,7 +651,7 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen); if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { @@ -731,7 +731,7 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, apdu.datalen = r; apdu.lc = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen); apdu.resplen = sizeof resp; apdu.resp = resp; @@ -743,7 +743,7 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen); if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { @@ -823,7 +823,7 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, apdu.datalen = r; apdu.lc = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); apdu.resplen = sizeof resp; apdu.resp = resp; @@ -835,7 +835,7 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { @@ -916,7 +916,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, apdu.datalen = r; apdu.lc = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); apdu.resplen = sizeof resp; apdu.resp = resp; @@ -928,7 +928,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { @@ -950,7 +950,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, p = r_data->auth_token->data; l = r_data->auth_token->length; if (r_data->cur_car) { - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Most recent Certificate Authority Reference", + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Most recent Certificate Authority Reference", r_data->cur_car->data, r_data->cur_car->length); *recent_car = malloc(r_data->cur_car->length); if (!*recent_car) { @@ -963,7 +963,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, } else *recent_car_len = 0; if (r_data->prev_car) { - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Previous Certificate Authority Reference", + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Previous Certificate Authority Reference", r_data->prev_car->data, r_data->prev_car->length); *prev_car = malloc(r_data->prev_car->length); if (!*prev_car) { @@ -1161,7 +1161,7 @@ int perform_pace(sc_card_t *card, } } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "EF.CardAccess", pace_output->ef_cardaccess, + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "EF.CardAccess", pace_output->ef_cardaccess, pace_output->ef_cardaccess_length); /* XXX Card capabilities should be determined by the OpenSC card driver. We @@ -1205,7 +1205,7 @@ int perform_pace(sc_card_t *card, "(General Authenticate step 1 failed)."); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length); enc_nonce->max = enc_nonce->length; sec = get_psec(card, (char *) pace_input.pin, pace_input.pin_length, @@ -1240,7 +1240,7 @@ int perform_pace(sc_card_t *card, goto err; } mdata_opp->max = mdata_opp->length; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length); if (!PACE_STEP3A_map_generator(eac_ctx, mdata_opp)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not map generator."); @@ -1266,7 +1266,7 @@ int perform_pace(sc_card_t *card, goto err; } pub_opp->max = pub_opp->length; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length); if (!PACE_STEP3B_compute_shared_secret(eac_ctx, pub_opp) @@ -1331,7 +1331,7 @@ int perform_pace(sc_card_t *card, pace_output->id_icc_length = comp_pub_opp->length; /* Flawfinder: ignore */ memcpy(pace_output->id_icc, comp_pub_opp->data, comp_pub_opp->length); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "ID ICC", pace_output->id_icc, + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID ICC", pace_output->id_icc, pace_output->id_icc_length); p = realloc(pace_output->id_pcd, comp_pub->length); if (!p) { @@ -1343,7 +1343,7 @@ int perform_pace(sc_card_t *card, pace_output->id_pcd_length = comp_pub->length; /* Flawfinder: ignore */ memcpy(pace_output->id_pcd, comp_pub->data, comp_pub->length); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd, + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID PCD", pace_output->id_pcd, pace_output->id_pcd_length); r = eac_sm_start(card, eac_ctx, pace_input.certificate_description, @@ -1527,7 +1527,7 @@ int perform_terminal_authentication(sc_card_t *card, goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "EF.CardAccess", ef_cardaccess, + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "EF.CardAccess", ef_cardaccess, ef_cardaccess_length); /* XXX Card capabilities should be determined by the OpenSC card driver. We @@ -1706,7 +1706,7 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, apdu.datalen = r; apdu.lc = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); apdu.resplen = sizeof resp; apdu.resp = resp; @@ -1718,7 +1718,7 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); + sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); if (!d2i_EAC_GEN_AUTH_CA_R(&r_data, (const unsigned char **) &apdu.resp, apdu.resplen)) { @@ -2079,7 +2079,7 @@ eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, goto err; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Authentication data verified"); + sc_debug(card->ctx, SC_LOG_DEBUG_SM, "Authentication data verified"); r = SC_SUCCESS; diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index 9cb359dee7..2776e451c2 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -66,7 +66,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, else if (gp_keyset->kmc_len == 16 || gp_keyset->kmc_len == 0) { if (gp_keyset->kmc_len == 16) memcpy(master_key, gp_keyset->kmc, 16); - sc_log(ctx, "KMC: %s", sc_dump_hex(master_key, sizeof(master_key))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "KMC: %s", sc_dump_hex(master_key, sizeof(master_key))); for (ii=0; ii<3; ii++) { key_buff[0] = key_buff[8] = 0; key_buff[1] = key_buff[9] = 0; @@ -77,7 +77,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, key_buff[6] = 0xF0, key_buff[14] = 0x0F; key_buff[7] = key_buff[15] = ii+1; - sc_log(ctx, "key_buf:%s", sc_dump_hex(key_buff, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "key_buf:%s", sc_dump_hex(key_buff, 16)); rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); LOG_TEST_RET(ctx, rv, "GP init session: cannot derive key"); @@ -91,11 +91,11 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, } if (!rv && ctx) { - sc_log_hex(ctx, "Card challenge", gp_session->card_challenge, sizeof(gp_session->card_challenge)); - sc_log_hex(ctx, "Host challenge", gp_session->host_challenge, sizeof(gp_session->host_challenge)); - sc_log_hex(ctx, "ENC", gp_keyset->enc, sizeof(gp_keyset->enc)); - sc_log_hex(ctx, "MAC", gp_keyset->mac, sizeof(gp_keyset->mac)); - sc_log_hex(ctx, "KEK", gp_keyset->kek, sizeof(gp_keyset->kek)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Card challenge", gp_session->card_challenge, sizeof(gp_session->card_challenge)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Host challenge", gp_session->host_challenge, sizeof(gp_session->host_challenge)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "ENC", gp_keyset->enc, sizeof(gp_keyset->enc)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MAC", gp_keyset->mac, sizeof(gp_keyset->mac)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "KEK", gp_keyset->kek, sizeof(gp_keyset->kek)); } return rv; @@ -110,7 +110,7 @@ sm_authentic_encode_apdu(struct sc_context *ctx, struct sm_info *sm_info) int rv = SC_ERROR_INVALID_ARGUMENTS; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM encode APDU: offset:"); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM encode APDU: offset:"); rv = sm_gp_securize_apdu(ctx, sm_info, NULL, apdu); LOG_TEST_RET(ctx, rv, "SM encode APDU: securize error"); @@ -130,9 +130,9 @@ sm_authentic_get_apdus(struct sc_context *ctx, struct sm_info *sm_info, if (!sm_info) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM get APDUs: rdata:%p, init_len:%"SC_FORMAT_LEN_SIZE_T"u", + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: rdata:%p, init_len:%"SC_FORMAT_LEN_SIZE_T"u", rdata, init_len); - sc_log(ctx, "SM get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); if (init_data) { rv = sm_gp_external_authentication(ctx, sm_info, init_data, init_len, rdata, sm_oberthur_diversify_keyset); diff --git a/src/smm/sm-card-iasecc.c b/src/smm/sm-card-iasecc.c index 7e8aab99f9..71038685f9 100644 --- a/src/smm/sm-card-iasecc.c +++ b/src/smm/sm-card-iasecc.c @@ -67,7 +67,7 @@ sm_iasecc_get_apdu_read_binary(struct sc_context *ctx, struct sm_info *sm_info, if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'READ BINARY' APDUs: offset:%"SC_FORMAT_LEN_SIZE_T"u,size:%"SC_FORMAT_LEN_SIZE_T"u", cmd_data->offs, cmd_data->count); offs = cmd_data->offs; @@ -113,7 +113,7 @@ sm_iasecc_get_apdu_update_binary(struct sc_context *ctx, struct sm_info *sm_info if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'UPDATE BINARY' APDUs: offset:%"SC_FORMAT_LEN_SIZE_T"u,size:%"SC_FORMAT_LEN_SIZE_T"u", cmd_data->offs, cmd_data->count); offs = cmd_data->offs; @@ -161,7 +161,7 @@ sm_iasecc_get_apdu_create_file(struct sc_context *ctx, struct sm_info *sm_info, if (!cmd_data || !cmd_data->data || !rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'CREATE FILE' APDU: FCP(%"SC_FORMAT_LEN_SIZE_T"u) %s", cmd_data->size, sc_dump_hex(cmd_data->data,cmd_data->size)); @@ -197,7 +197,7 @@ sm_iasecc_get_apdu_delete_file(struct sc_context *ctx, struct sm_info *sm_info, int rv; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM get 'DELETE FILE' APDU: file-id %04X", file_id); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'DELETE FILE' APDU: file-id %04X", file_id); if (!file_id) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -237,7 +237,7 @@ sm_iasecc_get_apdu_verify_pin(struct sc_context *ctx, struct sm_info *sm_info, s if (!pin_data || !rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM get 'VERIFY PIN' APDU: %u", pin_data->pin_reference); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'VERIFY PIN' APDU: %u", pin_data->pin_reference); rv = rdata->alloc(rdata, &rapdu); LOG_TEST_RET(ctx, rv, "SM get 'VERIFY PIN' APDUs: cannot allocate remote APDU"); @@ -278,7 +278,7 @@ sm_iasecc_get_apdu_reset_pin(struct sc_context *ctx, struct sm_info *sm_info, st if (!pin_data || !rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM get 'RESET PIN' APDU; reference %i", pin_data->pin_reference); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'RESET PIN' APDU; reference %i", pin_data->pin_reference); rv = rdata->alloc(rdata, &rapdu); LOG_TEST_RET(ctx, rv, "SM get 'RESET PIN' APDUs: cannot allocate remote APDU"); @@ -324,7 +324,7 @@ sm_iasecc_get_apdu_sdo_update(struct sc_context *ctx, struct sm_info *sm_info, s if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM get 'SDO UPDATE' APDU, SDO(class:0x%X,ref:%i)", update->sdo_class, update->sdo_ref); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'SDO UPDATE' APDU, SDO(class:0x%X,ref:%i)", update->sdo_class, update->sdo_ref); for (ii=0; update->fields[ii].tag && ii < IASECC_SDO_TAGS_UPDATE_MAX; ii++) { unsigned char *encoded = NULL; size_t encoded_len, offs; @@ -332,7 +332,7 @@ sm_iasecc_get_apdu_sdo_update(struct sc_context *ctx, struct sm_info *sm_info, s encoded_len = iasecc_sdo_encode_update_field(ctx, update->sdo_class, update->sdo_ref, &update->fields[ii], &encoded); LOG_TEST_RET(ctx, encoded_len, "SM get 'SDO UPDATE' APDU: encode component error"); - sc_log(ctx, "SM IAS/ECC get APDUs: encoded component '%s'", sc_dump_hex(encoded, encoded_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: encoded component '%s'", sc_dump_hex(encoded, encoded_len)); for (offs = 0; offs < encoded_len; ) { int len = (encoded_len - offs) > SM_MAX_DATA_SIZE ? SM_MAX_DATA_SIZE : (encoded_len - offs); @@ -383,7 +383,7 @@ sm_iasecc_get_apdu_generate_rsa(struct sc_context *ctx, struct sm_info *sm_info, int rv; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM get 'GENERATE RSA' APDU: SDO(class:%X,reference:%X)", sdo->sdo_class, sdo->sdo_ref); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'GENERATE RSA' APDU: SDO(class:%X,reference:%X)", sdo->sdo_class, sdo->sdo_ref); if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -443,12 +443,12 @@ sm_iasecc_get_apdu_update_rsa(struct sc_context *ctx, struct sm_info *sm_info, s LOG_FUNC_CALLED(ctx); if (cmd_data->update_prv.sdo_class) { to_update[ii++] = &cmd_data->update_prv; - sc_log(ctx, "SM get 'UPDATE RSA' APDU: SDO(class:%X,ref:%X)", cmd_data->update_prv.sdo_class, cmd_data->update_prv.sdo_ref); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'UPDATE RSA' APDU: SDO(class:%X,ref:%X)", cmd_data->update_prv.sdo_class, cmd_data->update_prv.sdo_ref); } if (cmd_data->update_pub.sdo_class) { to_update[ii++] = &cmd_data->update_pub; - sc_log(ctx, "SM get 'UPDATE RSA' APDU: SDO(class:%X,ref:%X)", cmd_data->update_pub.sdo_class, cmd_data->update_pub.sdo_ref); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get 'UPDATE RSA' APDU: SDO(class:%X,ref:%X)", cmd_data->update_pub.sdo_class, cmd_data->update_pub.sdo_ref); } for (jj=0;jj<2 && to_update[jj];jj++) { @@ -456,14 +456,14 @@ sm_iasecc_get_apdu_update_rsa(struct sc_context *ctx, struct sm_info *sm_info, s unsigned char *encoded = NULL; size_t encoded_len, offs; - sc_log(ctx, "SM IAS/ECC get APDUs: component(num %i:%i) class:%X, ref:%X", jj, ii, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: component(num %i:%i) class:%X, ref:%X", jj, ii, to_update[jj]->sdo_class, to_update[jj]->sdo_ref); encoded_len = iasecc_sdo_encode_update_field(ctx, to_update[jj]->sdo_class, to_update[jj]->sdo_ref, &to_update[jj]->fields[ii], &encoded); LOG_TEST_RET(ctx, encoded_len, "SM get 'UPDATE RSA' APDU: cannot encode key component"); - sc_log(ctx, "SM IAS/ECC get APDUs: component encoded %s", sc_dump_hex(encoded, encoded_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: component encoded %s", sc_dump_hex(encoded, encoded_len)); for (offs = 0; offs < encoded_len; ) { int len = (encoded_len - offs) > SM_MAX_DATA_SIZE ? SM_MAX_DATA_SIZE : (encoded_len - offs); @@ -511,10 +511,10 @@ sm_iasecc_get_apdus(struct sc_context *ctx, struct sm_info *sm_info, if (!sm_info) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM IAS/ECC get APDUs: init_len:%"SC_FORMAT_LEN_SIZE_T"u", + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: init_len:%"SC_FORMAT_LEN_SIZE_T"u", init_len); - sc_log(ctx, "SM IAS/ECC get APDUs: rdata:%p", rdata); - sc_log(ctx, "SM IAS/ECC get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: rdata:%p", rdata); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); rv = sm_cwa_decode_authentication_data(ctx, cwa_keyset, cwa_session, init_data); LOG_TEST_RET(ctx, rv, "SM IAS/ECC get APDUs: decode authentication data error"); @@ -522,9 +522,9 @@ sm_iasecc_get_apdus(struct sc_context *ctx, struct sm_info *sm_info, rv = sm_cwa_init_session_keys(ctx, cwa_session, cwa_session->params.crt_at.algo); LOG_TEST_RET(ctx, rv, "SM IAS/ECC get APDUs: cannot get session keys"); - sc_log(ctx, "SKENC %s", sc_dump_hex(cwa_session->session_enc, sizeof(cwa_session->session_enc))); - sc_log(ctx, "SKMAC %s", sc_dump_hex(cwa_session->session_mac, sizeof(cwa_session->session_mac))); - sc_log(ctx, "SSC %s", sc_dump_hex(cwa_session->ssc, sizeof(cwa_session->ssc))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SKENC %s", sc_dump_hex(cwa_session->session_enc, sizeof(cwa_session->session_enc))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SKMAC %s", sc_dump_hex(cwa_session->session_mac, sizeof(cwa_session->session_mac))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SSC %s", sc_dump_hex(cwa_session->ssc, sizeof(cwa_session->ssc))); switch (sm_info->cmd) { case SM_CMD_FILE_READ: @@ -586,7 +586,7 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru LOG_FUNC_CALLED(ctx); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decode answer() rdata length %i, out length %"SC_FORMAT_LEN_SIZE_T"u", rdata->length, out_len); for (rapdu = rdata->data; rapdu; rapdu = rapdu->next) { @@ -599,7 +599,7 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru unsigned char ticket[8]; size_t ticket_len = sizeof(ticket); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decode response(%"SC_FORMAT_LEN_SIZE_T"u) %s", rapdu->apdu.resplen, sc_dump_hex(rapdu->apdu.resp, rapdu->apdu.resplen)); @@ -611,12 +611,12 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru rv = sc_asn1_decode(ctx, asn1_iasecc_sm_data_object, rapdu->apdu.resp, rapdu->apdu.resplen, NULL, NULL); LOG_TEST_RET(ctx, rv, "IAS/ECC decode answer(s): ASN1 decode error"); - sc_log(ctx, "IAS/ECC decode response() SW:%02X%02X, MAC:%s", status[0], status[1], sc_dump_hex(ticket, ticket_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decode response() SW:%02X%02X, MAC:%s", status[0], status[1], sc_dump_hex(ticket, ticket_len)); if (status[0] != 0x90 || status[1] != 0x00) continue; if (asn1_iasecc_sm_data_object[0].flags & SC_ASN1_PRESENT) { - sc_log(ctx, "IAS/ECC decode answer() object present"); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decode answer() object present"); if (resp_data[0] != 0x01) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "IAS/ECC decode answer(s): invalid encrypted data format"); @@ -625,7 +625,7 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru &decrypted, &decrypted_len); LOG_TEST_RET(ctx, rv, "IAS/ECC decode answer(s): cannot decrypt card answer data"); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decrypted data(%"SC_FORMAT_LEN_SIZE_T"u) %s", decrypted_len, sc_dump_hex(decrypted, decrypted_len)); @@ -642,7 +642,7 @@ sm_iasecc_decode_card_data(struct sc_context *ctx, struct sm_info *sm_info, stru memcpy(out + offs, decrypted, decrypted_len); offs += decrypted_len; - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "IAS/ECC decode card answer(s): out_len/offs %"SC_FORMAT_LEN_SIZE_T"u/%i", out_len, offs); } diff --git a/src/smm/sm-cwa14890.c b/src/smm/sm-cwa14890.c index d2752949c9..d8f12f68a5 100644 --- a/src/smm/sm-cwa14890.c +++ b/src/smm/sm-cwa14890.c @@ -55,13 +55,13 @@ sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, DES_cblock *icv, unsigned char *buf; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "sm_cwa_get_mac() data length %i", in_len); + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() data length %i", in_len); buf = malloc(in_len + 8); if (!buf) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - sc_log(ctx, "sm_cwa_get_mac() in_data(%i) %s", in_len, sc_dump_hex(in, in_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() in_data(%i) %s", in_len, sc_dump_hex(in, in_len)); memcpy(buf, in, in_len); memcpy(buf + in_len, padding, 8); @@ -70,8 +70,8 @@ sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, DES_cblock *icv, else in_len = ((in_len + 7) / 8) * 8; - sc_log(ctx, "sm_cwa_get_mac() data to MAC(%i) %s", in_len, sc_dump_hex(buf, in_len)); - sc_log(ctx, "sm_cwa_get_mac() ICV %s", sc_dump_hex((unsigned char *)icv, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() data to MAC(%i) %s", in_len, sc_dump_hex(buf, in_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() ICV %s", sc_dump_hex((unsigned char *)icv, 8)); memcpy(&kk, key, 8); memcpy(&k2, key + 8, 8); @@ -91,8 +91,8 @@ sm_cwa_encode_external_auth_data(struct sc_context *ctx, struct sm_cwa_session * if (out_len < 16) return SC_ERROR_BUFFER_TOO_SMALL; - sc_log(ctx, "IFD.RND %s", sc_dump_hex(session_data->ifd.rnd, 8)); - sc_log(ctx, "IFD.SN %s", sc_dump_hex(session_data->ifd.sn, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.RND %s", sc_dump_hex(session_data->ifd.rnd, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.SN %s", sc_dump_hex(session_data->ifd.sn, 8)); memcpy(out + 0, session_data->icc.rnd, 8); memcpy(out + 8, session_data->icc.sn, 8); @@ -108,11 +108,11 @@ sm_cwa_encode_mutual_auth_data(struct sc_context *ctx, struct sm_cwa_session *se if (out_len < 64) return SC_ERROR_BUFFER_TOO_SMALL; - sc_log(ctx, "IFD.RND %s", sc_dump_hex(session_data->ifd.rnd, 8)); - sc_log(ctx, "IFD.SN %s", sc_dump_hex(session_data->ifd.sn, 8)); - sc_log(ctx, "IFD.K %s", sc_dump_hex(session_data->ifd.k, 32)); - sc_log(ctx, "ICC.RND %s", sc_dump_hex(session_data->icc.rnd, 8)); - sc_log(ctx, "ICC.SN %s", sc_dump_hex(session_data->icc.sn, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.RND %s", sc_dump_hex(session_data->ifd.rnd, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.SN %s", sc_dump_hex(session_data->ifd.sn, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.K %s", sc_dump_hex(session_data->ifd.k, 32)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "ICC.RND %s", sc_dump_hex(session_data->icc.rnd, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "ICC.SN %s", sc_dump_hex(session_data->icc.sn, 8)); memcpy(out + 0, session_data->ifd.rnd, 8); memcpy(out + 8, session_data->ifd.sn, 8); @@ -139,7 +139,7 @@ sm_cwa_decode_authentication_data(struct sc_context *ctx, struct sm_cwa_keyset * memset(icv, 0, sizeof(icv)); rv = sm_cwa_get_mac(ctx, keyset->mac, &icv, session_data->mdata, 0x40, &cblock, 1); LOG_TEST_RET(ctx, rv, "Decode authentication data: sm_ecc_get_mac failed"); - sc_log(ctx, "MAC:%s", sc_dump_hex(cblock, sizeof(cblock))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "MAC:%s", sc_dump_hex(cblock, sizeof(cblock))); if(memcmp(session_data->mdata + 0x40, cblock, 8)) LOG_FUNC_RETURN(ctx, SC_ERROR_SM_AUTHENTICATION_FAILED); @@ -147,7 +147,7 @@ sm_cwa_decode_authentication_data(struct sc_context *ctx, struct sm_cwa_keyset * rv = sm_decrypt_des_cbc3(ctx, keyset->enc, session_data->mdata, session_data->mdata_len, &decrypted, &decrypted_len); LOG_TEST_RET(ctx, rv, "sm_ecc_decode_auth_data() DES CBC3 decrypt error"); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_ecc_decode_auth_data() decrypted(%"SC_FORMAT_LEN_SIZE_T"u) %s", decrypted_len, sc_dump_hex(decrypted, decrypted_len)); @@ -191,17 +191,17 @@ sm_cwa_init_session_keys(struct sc_context *ctx, struct sm_cwa_session *session_ for (ii=0; ii<32; ii++) xored[ii] = session_data->ifd.k[ii] ^ session_data->icc.k[ii]; - sc_log(ctx, "K_IFD %s", sc_dump_hex(session_data->ifd.k, 32)); - sc_log(ctx, "K_ICC %s", sc_dump_hex(session_data->icc.k, 32)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "K_IFD %s", sc_dump_hex(session_data->ifd.k, 32)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "K_ICC %s", sc_dump_hex(session_data->icc.k, 32)); if (mechanism == IASECC_ALGORITHM_SYMMETRIC_SHA1) { xored[35] = 0x01; - sc_log(ctx, "XOR for SkEnc %s", sc_dump_hex(xored, 36)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "XOR for SkEnc %s", sc_dump_hex(xored, 36)); SHA1(xored, 36, buff); memcpy(&session_data->session_enc[0], buff, sizeof(session_data->session_enc)); xored[35] = 0x02; - sc_log(ctx, "XOR for SkMac %s", sc_dump_hex(xored, 36)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "XOR for SkMac %s", sc_dump_hex(xored, 36)); SHA1(xored, 36, buff); memcpy(&session_data->session_mac[0], buff, sizeof(session_data->session_mac)); } @@ -240,10 +240,10 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem int rv, offs; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM IAS/ECC initialize: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); - sc_log(ctx, "SM IAS/ECC initialize: card challenge %s", sc_dump_hex(cwa_session->card_challenge, 8)); - sc_log(ctx, "SM IAS/ECC initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df)); - sc_log(ctx, "SM IAS/ECC initialize: CRT_AT reference 0x%X", cwa_session->params.crt_at.refs[0]); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC initialize: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC initialize: card challenge %s", sc_dump_hex(cwa_session->card_challenge, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM IAS/ECC initialize: CRT_AT reference 0x%X", cwa_session->params.crt_at.refs[0]); if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -270,12 +270,12 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem LOG_FUNC_RETURN(ctx, offs); } - sc_log(ctx, "S(%i) %s", offs, sc_dump_hex(buf, offs)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "S(%i) %s", offs, sc_dump_hex(buf, offs)); rv = sm_encrypt_des_cbc3(ctx, cwa_keyset->enc, buf, offs, &encrypted, &encrypted_len, 1); LOG_TEST_RET(ctx, rv, "_encrypt_des_cbc3() failed"); - sc_log(ctx, "ENCed(%"SC_FORMAT_LEN_SIZE_T"u) %s", encrypted_len, + sc_debug(ctx, SC_LOG_DEBUG_SM, "ENCed(%"SC_FORMAT_LEN_SIZE_T"u) %s", encrypted_len, sc_dump_hex(encrypted, encrypted_len)); memcpy(buf, encrypted, encrypted_len); @@ -283,7 +283,7 @@ sm_cwa_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem rv = sm_cwa_get_mac(ctx, cwa_keyset->mac, &icv, buf, offs, &cblock, 1); LOG_TEST_RET(ctx, rv, "sm_ecc_get_mac() failed"); - sc_log(ctx, "MACed(%"SC_FORMAT_LEN_SIZE_T"u) %s", sizeof(cblock), + sc_debug(ctx, SC_LOG_DEBUG_SM, "MACed(%"SC_FORMAT_LEN_SIZE_T"u) %s", sizeof(cblock), sc_dump_hex(cblock, sizeof(cblock))); apdu->cse = SC_APDU_CASE_4_SHORT; @@ -314,7 +314,7 @@ sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_ int rv; LOG_FUNC_CALLED(ctx); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "securize APDU (cla:%X,ins:%X,p1:%X,p2:%X,data(%"SC_FORMAT_LEN_SIZE_T"u):%p)", apdu->cla, apdu->ins, apdu->p1, apdu->p2, apdu->datalen, apdu->data); @@ -323,7 +323,7 @@ sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_ rv = sm_encrypt_des_cbc3(ctx, session_data->session_enc, apdu->data, apdu->datalen, &encrypted, &encrypted_len, 0); LOG_TEST_RET(ctx, rv, "securize APDU: DES CBC3 encryption failed"); - sc_log(ctx, "encrypted data (len:%"SC_FORMAT_LEN_SIZE_T"u, %s)", + sc_debug(ctx, SC_LOG_DEBUG_SM, "encrypted data (len:%"SC_FORMAT_LEN_SIZE_T"u, %s)", encrypted_len, sc_dump_hex(encrypted, encrypted_len)); offs = 0; @@ -343,7 +343,7 @@ sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_ memcpy(edfb_data + offs, encrypted, encrypted_len); offs += encrypted_len; edfb_len = offs; - sc_log(ctx, "securize APDU: EDFB(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", + sc_debug(ctx, SC_LOG_DEBUG_SM, "securize APDU: EDFB(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", edfb_len, sc_dump_hex(edfb_data, edfb_len)); free(encrypted); @@ -371,13 +371,13 @@ sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_ /* } */ mac_len = offs; - sc_log(ctx, "securize APDU: MAC data(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", + sc_debug(ctx, SC_LOG_DEBUG_SM, "securize APDU: MAC data(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", mac_len, sc_dump_hex(mac_data, mac_len)); memset(icv, 0, sizeof(icv)); rv = sm_cwa_get_mac(ctx, session_data->session_mac, &icv, mac_data, mac_len, &cblock, 0); LOG_TEST_RET(ctx, rv, "securize APDU: MAC calculation error"); - sc_log(ctx, "securize APDU: MAC:%s", sc_dump_hex(cblock, sizeof(cblock))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "securize APDU: MAC:%s", sc_dump_hex(cblock, sizeof(cblock))); offs = 0; if (edfb_len) { @@ -395,7 +395,7 @@ sm_cwa_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sc_ sbuf[offs++] = 8; memcpy(sbuf + offs, cblock, 8); offs += 8; - sc_log(ctx, "securize APDU: SM data(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", + sc_debug(ctx, SC_LOG_DEBUG_SM, "securize APDU: SM data(len:%"SC_FORMAT_LEN_SIZE_T"u,%s)", offs, sc_dump_hex(sbuf, offs)); if (offs > sizeof(rapdu->sbuf)) diff --git a/src/smm/sm-global-platform.c b/src/smm/sm-global-platform.c index e8f10507d0..bf0fb9e5bb 100644 --- a/src/smm/sm-global-platform.c +++ b/src/smm/sm-global-platform.c @@ -63,9 +63,9 @@ sm_gp_initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_rem int rv; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM GP initialize: serial:%s", sc_dump_hex(sn.value, sn.len)); - sc_log(ctx, "SM GP initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df)); - sc_log(ctx, "SM GP initialize: KMC length %i", gp_keyset->kmc_len); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP initialize: serial:%s", sc_dump_hex(sn.value, sn.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP initialize: current_df_path %s", sc_print_path(&sm_info->current_path_df)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP initialize: KMC length %i", gp_keyset->kmc_len); if (!rdata || !rdata->alloc) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -107,13 +107,13 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) { if (ctx) - sc_log(ctx, "SM GP get session key: des_ecb3 encryption error"); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error"); free(out); return NULL; } else if (out==NULL || out_len!=16) { if (ctx) - sc_log(ctx, "SM GP get session key: des_ecb3 encryption error: out(%p,len:%i)", out, out_len); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error: out(%p,len:%i)", out, out_len); if (out) free(out); return NULL; @@ -211,7 +211,7 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_gp_session *gp_session, if (!adata || adata_len < 8) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM GP init session: auth.data %s", sc_dump_hex(adata, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: auth.data %s", sc_dump_hex(adata, 8)); gp_session->session_enc = sc_gp_get_session_key(ctx, gp_session, gp_keyset->enc); gp_session->session_mac = sc_gp_get_session_key(ctx, gp_session, gp_keyset->mac); @@ -220,19 +220,19 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_gp_session *gp_session, LOG_TEST_RET(ctx, SC_ERROR_SM_NO_SESSION_KEYS, "SM GP init session: get session keys error"); memcpy(gp_session->session_kek, gp_keyset->kek, 16); - sc_log(ctx, "SM GP init session: session ENC: %s", sc_dump_hex(gp_session->session_enc, 16)); - sc_log(ctx, "SM GP init session: session MAC: %s", sc_dump_hex(gp_session->session_mac, 16)); - sc_log(ctx, "SM GP init session: session KEK: %s", sc_dump_hex(gp_session->session_kek, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: session ENC: %s", sc_dump_hex(gp_session->session_enc, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: session MAC: %s", sc_dump_hex(gp_session->session_mac, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: session KEK: %s", sc_dump_hex(gp_session->session_kek, 16)); memset(cksum, 0, sizeof(cksum)); rv = sm_gp_get_cryptogram(gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum)); LOG_TEST_RET(ctx, rv, "SM GP init session: cannot get cryptogram"); - sc_log(ctx, "SM GP init session: cryptogram: %s", sc_dump_hex(cksum, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: cryptogram: %s", sc_dump_hex(cksum, 8)); if (memcmp(cksum, adata, adata_len)) LOG_FUNC_RETURN(ctx, SC_ERROR_SM_AUTHENTICATION_FAILED); - sc_log(ctx, "SM GP init session: card authenticated"); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: card authenticated"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -283,7 +283,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, host_cryptogram, sizeof(host_cryptogram)); LOG_TEST_RET(ctx, rv, "SM GP authentication: get host cryptogram error"); - sc_log(ctx, "SM GP authentication: host_cryptogram:%s", sc_dump_hex(host_cryptogram, 8)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP authentication: host_cryptogram:%s", sc_dump_hex(host_cryptogram, 8)); rv = rdata->alloc(rdata, &new_rapdu); LOG_TEST_RET(ctx, rv, "SM GP authentication: cannot allocate remote APDU"); @@ -321,7 +321,7 @@ sm_gp_encrypt_command_data(struct sc_context *ctx, unsigned char *session_key, if (!out || !out_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "SM GP encrypt command data error"); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP encrypt command data(len:%"SC_FORMAT_LEN_SIZE_T"u,%p)", in_len, in); if (in==NULL || in_len==0) { @@ -365,7 +365,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, LOG_FUNC_CALLED(ctx); apdu_data = (unsigned char *)apdu->data; - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP securize APDU(cse:%X,cla:%X,ins:%X,data(len:%"SC_FORMAT_LEN_SIZE_T"u,%p),lc:%"SC_FORMAT_LEN_SIZE_T"u,GP level:%X,GP index:%X", apdu->cse, apdu->cla, apdu->ins, apdu->datalen, apdu->data, apdu->lc, gp_level, gp_index); @@ -387,7 +387,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, if (encrypted_len + 8 > SC_MAX_APDU_BUFFER_SIZE) LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "SM GP securize APDU: not enough place for encrypted data"); - sc_log(ctx, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP securize APDU: encrypted length %"SC_FORMAT_LEN_SIZE_T"u", encrypted_len); } diff --git a/src/smm/smm-local.c b/src/smm/smm-local.c index e6537cc034..c923c89d97 100644 --- a/src/smm/smm-local.c +++ b/src/smm/smm-local.c @@ -65,8 +65,8 @@ sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) size_t hex_len = sizeof(hex); int rv, ii; - sc_log(ctx, "SM get KMC from config section '%s'", sm_info->config_section); - for (ii = 0; ctx->conf_blocks[ii]; ii++) { + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get KMC from config section '%s'", sm_info->config_section); + for (ii = 0; ctx->conf_blocks[ii]; ii++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section); if (blocks) { sm_conf_block = blocks[0]; @@ -83,12 +83,12 @@ sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) rv = sc_hex_to_bin(kmc, hex, &hex_len); if (rv) { - sc_log(ctx, "SM get KMC: hex to bin failed for '%s'; error %i", kmc, rv); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM get KMC: hex to bin failed for '%s'; error %i", kmc, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } - sc_log(ctx, "SM type:%X, KMC(%"SC_FORMAT_LEN_SIZE_T"u) %s", - sm_info->sm_type, hex_len, sc_dump_hex(hex, hex_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM type:%X, KMC(%"SC_FORMAT_LEN_SIZE_T"u) %s", + sm_info->sm_type, hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16 && hex_len != 48 ) return SC_ERROR_INVALID_DATA; @@ -123,7 +123,7 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) break; } - sc_log(ctx, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]); + sc_debug(ctx, SC_LOG_DEBUG_SM, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]); /* Keyset ENC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) snprintf(name, sizeof(name), "keyset_%s_%02i_enc", @@ -132,12 +132,12 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) snprintf(name, sizeof(name), "keyset_%02i_enc", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { - sc_log(ctx, "No %s value in OpenSC config", name); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } - sc_log(ctx, "keyset::enc(%"SC_FORMAT_LEN_SIZE_T"u) %s", strlen(value), - value); + sc_debug(ctx, SC_LOG_DEBUG_SM, "keyset::enc(%"SC_FORMAT_LEN_SIZE_T"u) %s", strlen(value), + value); if (strlen(value) == 16) { memcpy(cwa_keyset->enc, value, 16); } @@ -145,18 +145,18 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { - sc_log(ctx, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } - sc_log(ctx, "ENC(%"SC_FORMAT_LEN_SIZE_T"u) %s", hex_len, - sc_dump_hex(hex, hex_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "ENC(%"SC_FORMAT_LEN_SIZE_T"u) %s", hex_len, + sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->enc, hex, hex_len); } - sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16)); /* Keyset MAC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) @@ -166,12 +166,12 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) snprintf(name, sizeof(name), "keyset_%02i_mac", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { - sc_log(ctx, "No %s value in OpenSC config", name); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } - sc_log(ctx, "keyset::mac(%"SC_FORMAT_LEN_SIZE_T"u) %s", strlen(value), - value); + sc_debug(ctx, SC_LOG_DEBUG_SM, "keyset::mac(%"SC_FORMAT_LEN_SIZE_T"u) %s", strlen(value), + value); if (strlen(value) == 16) { memcpy(cwa_keyset->mac, value, 16); } @@ -179,18 +179,18 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { - sc_log(ctx, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } - sc_log(ctx, "MAC(%"SC_FORMAT_LEN_SIZE_T"u) %s", hex_len, - sc_dump_hex(hex, hex_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "MAC(%"SC_FORMAT_LEN_SIZE_T"u) %s", hex_len, + sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->mac, hex, hex_len); } - sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16)); cwa_keyset->sdo_reference = crt_at->refs[0]; @@ -203,33 +203,33 @@ sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { - sc_log(ctx, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } if (hex_len != sizeof(cwa_session->ifd.sn)) { - sc_log(ctx, - "SM get 'ifd_serial': invalid IFD serial length: %"SC_FORMAT_LEN_SIZE_T"u", - hex_len); + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, + "SM get 'ifd_serial': invalid IFD serial length: %"SC_FORMAT_LEN_SIZE_T"u", + hex_len); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(cwa_session->ifd.sn, hex, hex_len); - rv = RAND_bytes(cwa_session->ifd.rnd, 8); - if (!rv) { - sc_log(ctx, "Generate random error: %i", rv); + rv = RAND_bytes(cwa_session->ifd.rnd, 8); + if (!rv) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } - rv = RAND_bytes(cwa_session->ifd.k, 32); - if (!rv) { - sc_log(ctx, "Generate random error: %i", rv); + rv = RAND_bytes(cwa_session->ifd.k, 32); + if (!rv) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } - sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn))); - sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd))); - sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd))); + sc_debug(ctx, SC_LOG_DEBUG_SM, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k))); return SC_SUCCESS; } @@ -250,24 +250,24 @@ initialize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_dat if (!sm_info) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "Current AID: %s", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "Current AID: %s", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len)); switch (sm_info->sm_type) { - case SM_TYPE_GP_SCP01: - rv = sm_gp_config_get_keyset(ctx, sm_info); - LOG_TEST_RET(ctx, rv, "SM gp configuration error"); - - rv = sm_gp_initialize(ctx, sm_info, out); - LOG_TEST_RET(ctx, rv, "SM gp initializing error"); - break; - case SM_TYPE_CWA14890: - rv = sm_cwa_config_get_keyset(ctx, sm_info); - LOG_TEST_RET(ctx, rv, "SM iasecc configuration error"); - - rv = sm_cwa_initialize(ctx, sm_info, out); - LOG_TEST_RET(ctx, rv, "SM iasecc initializing error"); - break; - default: - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported SM type"); + case SM_TYPE_GP_SCP01: + rv = sm_gp_config_get_keyset(ctx, sm_info); + LOG_TEST_RET(ctx, rv, "SM gp configuration error"); + + rv = sm_gp_initialize(ctx, sm_info, out); + LOG_TEST_RET(ctx, rv, "SM gp initializing error"); + break; + case SM_TYPE_CWA14890: + rv = sm_cwa_config_get_keyset(ctx, sm_info); + LOG_TEST_RET(ctx, rv, "SM iasecc configuration error"); + + rv = sm_cwa_initialize(ctx, sm_info, out); + LOG_TEST_RET(ctx, rv, "SM iasecc initializing error"); + break; + default: + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported SM type"); }; LOG_FUNC_RETURN(ctx, rv); @@ -290,8 +290,8 @@ get_apdus(struct sc_context *ctx, struct sm_info *sm_info, unsigned char *init_d if (!sm_info) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_log(ctx, "SM get APDUs: out:%p", out); - sc_log(ctx, "SM get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: out:%p", out); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); if (sm_info->card_type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { rv = sm_authentic_get_apdus(ctx, sm_info, init_data, init_len, out, 1); @@ -320,8 +320,8 @@ finalize(struct sc_context *ctx, struct sm_info *sm_info, struct sc_remote_data int rv = SC_ERROR_INTERNAL; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "SM finalize: out buffer(%"SC_FORMAT_LEN_SIZE_T"u) %p", - out_len, out); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM finalize: out buffer(%"SC_FORMAT_LEN_SIZE_T"u) %p", + out_len, out); if (!sm_info || !rdata) LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -344,7 +344,6 @@ int module_init(struct sc_context *ctx, char *data) { - sc_log(ctx, "Module init data '%s'", data); return SC_SUCCESS; } @@ -357,7 +356,6 @@ module_init(struct sc_context *ctx, char *data) int module_cleanup(struct sc_context *ctx) { - sc_log(ctx, "Module cleanup: TODO"); return SC_SUCCESS; } @@ -365,7 +363,6 @@ module_cleanup(struct sc_context *ctx) int test(struct sc_context *ctx, struct sm_info *info, char *out, size_t *out_len) { - sc_log(ctx, "Test"); return SC_SUCCESS; } From 24b50a4277e94a0b654e744045b30dd730389270 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Nov 2018 09:31:29 +0100 Subject: [PATCH 0655/4321] replace sc_debug with sc_log --- src/libopensc/card-akis.c | 12 +-- src/libopensc/card-asepcos.c | 40 ++++----- src/libopensc/card-atrust-acos.c | 18 ++-- src/libopensc/card-belpic.c | 16 ++-- src/libopensc/card-cac.c | 20 ++--- src/libopensc/card-cac1.c | 4 +- src/libopensc/card-cardos.c | 32 +++---- src/libopensc/card-coolkey.c | 22 ++--- src/libopensc/card-entersafe.c | 10 +-- src/libopensc/card-flex.c | 50 +++++------ src/libopensc/card-gemsafeV1.c | 26 +++--- src/libopensc/card-gids.c | 52 +++++------ src/libopensc/card-gpk.c | 50 +++++------ src/libopensc/card-incrypto34.c | 18 ++-- src/libopensc/card-itacns.c | 8 +- src/libopensc/card-jcop.c | 18 ++-- src/libopensc/card-masktech.c | 14 +-- src/libopensc/card-mcrd.c | 2 +- src/libopensc/card-miocos.c | 14 +-- src/libopensc/card-muscle.c | 30 +++---- src/libopensc/card-openpgp.c | 2 +- src/libopensc/card-rtecp.c | 16 ++-- src/libopensc/card-rutoken.c | 42 ++++----- src/libopensc/card-sc-hsm.c | 16 ++-- src/libopensc/card-setcos.c | 16 ++-- src/libopensc/card-starcos.c | 56 ++++++------ src/libopensc/card-tcos.c | 22 ++--- src/libopensc/card-westcos.c | 46 +++++----- src/libopensc/card.c | 2 +- src/libopensc/ctbcs.c | 4 +- src/libopensc/muscle.c | 30 +++---- src/libopensc/p15card-helper.c | 10 +-- src/libopensc/pkcs15-cac.c | 24 ++--- src/libopensc/pkcs15-cache.c | 2 +- src/libopensc/pkcs15-coolkey.c | 4 +- src/libopensc/pkcs15-gemsafeGPK.c | 16 ++-- src/libopensc/pkcs15-gemsafeV1.c | 2 +- src/libopensc/pkcs15-gids.c | 4 +- src/libopensc/pkcs15-infocamere.c | 4 +- src/libopensc/pkcs15-itacns.c | 18 ++-- src/libopensc/pkcs15-openpgp.c | 10 +-- src/libopensc/pkcs15-piv.c | 48 +++++----- src/libopensc/pkcs15-postecert.c | 2 +- src/libopensc/pkcs15-tccardos.c | 2 +- src/libopensc/pkcs15-tcos.c | 36 ++++---- src/libopensc/pkcs15-westcos.c | 4 +- src/libopensc/reader-openct.c | 8 +- src/libopensc/reader-pcsc.c | 2 +- src/libopensc/reader-tr03119.c | 20 ++--- src/libopensc/sec.c | 4 +- src/pkcs15init/pkcs15-asepcos.c | 40 ++++----- src/pkcs15init/pkcs15-cardos.c | 22 ++--- src/pkcs15init/pkcs15-cflex.c | 12 +-- src/pkcs15init/pkcs15-entersafe.c | 6 +- src/pkcs15init/pkcs15-epass2003.c | 42 ++++----- src/pkcs15init/pkcs15-gpk.c | 48 +++++----- src/pkcs15init/pkcs15-incrypto34.c | 12 +-- src/pkcs15init/pkcs15-jcop.c | 6 +- src/pkcs15init/pkcs15-miocos.c | 10 +-- src/pkcs15init/pkcs15-muscle.c | 12 +-- src/pkcs15init/pkcs15-oberthur-awp.c | 128 +++++++++++++-------------- src/pkcs15init/pkcs15-oberthur.c | 54 +++++------ src/pkcs15init/pkcs15-openpgp.c | 4 +- src/pkcs15init/pkcs15-rtecp.c | 14 +-- src/pkcs15init/pkcs15-rutoken.c | 12 +-- src/pkcs15init/pkcs15-sc-hsm.c | 4 +- src/pkcs15init/pkcs15-setcos.c | 20 ++--- src/pkcs15init/pkcs15-starcos.c | 2 +- src/sm/sm-iso.c | 2 +- src/tools/egk-tool.c | 8 +- src/tools/npa-tool.c | 8 +- 71 files changed, 697 insertions(+), 697 deletions(-) diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 747d83eb27..5cd2b1e92f 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -170,7 +170,7 @@ akis_list_files(sc_card_t *card, u8 *buf, size_t buflen) while (left > 19) { if (p[0] != 0x2f && p[0] != 0x3d) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Malformatted list reply %02x", p[0]); + sc_log(card->ctx, "Malformatted list reply %02x", p[0]); return SC_ERROR_INTERNAL; } if (buflen >= 2) { @@ -204,7 +204,7 @@ akis_process_fci(sc_card_t *card, sc_file_t *file, */ p = sc_asn1_find_tag(card->ctx, buf, buflen, 0x90, &len); if (p == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Security tag missing"); + sc_log(card->ctx, "Security tag missing"); return SC_ERROR_INTERNAL; } perms = p[0]; @@ -274,7 +274,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file) type = 0x45; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "This EF structure is not supported yet"); + sc_log(card->ctx, "This EF structure is not supported yet"); return SC_ERROR_NOT_SUPPORTED; } apdu.p1 = type; @@ -286,7 +286,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file) } else if (file->type == SC_FILE_TYPE_DF) { apdu.ins = 0x10; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown file type"); + sc_log(card->ctx, "Unknown file type"); return SC_ERROR_NOT_SUPPORTED; } @@ -319,7 +319,7 @@ akis_delete_file(sc_card_t *card, const sc_path_t *path) type = 0x08; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be FID or PATH"); + sc_log(card->ctx, "File type has to be FID or PATH"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x16, type, 0x00); @@ -373,7 +373,7 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left return r; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Other pin cmds not supported yet"); + sc_log(card->ctx, "Other pin cmds not supported yet"); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 939e3f2e9f..fb5eb95783 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -65,7 +65,7 @@ static int asepcos_select_asepcos_applet(sc_card_t *card) r = sc_select_file(card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to select ASEPCOS applet"); + sc_log(card->ctx, "unable to select ASEPCOS applet"); return r; } @@ -170,7 +170,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu while (len != 0) { unsigned int amode, tlen = 3; if (len < 5 || p[0] != 0x80 || p[1] != 0x01) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid access mode encoding"); + sc_log(card->ctx, "invalid access mode encoding"); return SC_ERROR_INTERNAL; } amode = p[2]; @@ -197,7 +197,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu return r; tlen += 2 + p[4]; /* FIXME */ } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid security condition"); + sc_log(card->ctx, "invalid security condition"); return SC_ERROR_INTERNAL; } p += tlen; @@ -311,7 +311,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path, if (r == SC_SUCCESS && file != NULL && *file != NULL) { r = asepcos_parse_sec_attr(card, *file, (*file)->sec_attr, (*file)->sec_attr_len); if (r != SC_SUCCESS) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error parsing security attributes"); + sc_log(card->ctx, "error parsing security attributes"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } @@ -420,7 +420,7 @@ static int asepcos_set_security_attributes(sc_card_t *card, sc_file_t *file) *p++ = (st.fileid >> 8 ) & 0xff; *p++ = st.fileid & 0xff; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unknown auth method: '%d'", ent->method); + sc_log(card->ctx, "unknown auth method: '%d'", ent->method); return SC_ERROR_INTERNAL; } } @@ -487,7 +487,7 @@ static int asepcos_compute_signature(sc_card_t *card, const u8 *data, size_t dat r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error creating signature"); + sc_log(card->ctx, "error creating signature"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -565,7 +565,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to set security attributes"); + sc_log(card->ctx, "unable to set security attributes"); return r; } return SC_SUCCESS; @@ -611,7 +611,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to set security attributes"); + sc_log(card->ctx, "unable to set security attributes"); return r; } return asepcos_activate_file(card, file->id, 1); @@ -638,7 +638,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to set security attributes"); + sc_log(card->ctx, "unable to set security attributes"); return r; } return asepcos_activate_file(card, file->id, 1); @@ -672,7 +672,7 @@ static int asepcos_list_files(sc_card_t *card, u8 *buf, size_t blen) return r; if (tfile->prop_attr_len != 6 || tfile->prop_attr == NULL) { sc_file_free(tfile); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to parse proprietary FCI attributes"); + sc_log(card->ctx, "unable to parse proprietary FCI attributes"); return SC_ERROR_INTERNAL; } dfFID = (tfile->prop_attr[2] << 8) | tfile->prop_attr[3]; @@ -794,7 +794,7 @@ static int asepcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (apdu.resplen != 8) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unexpected response to GET DATA serial number\n"); + sc_log(card->ctx, "unexpected response to GET DATA serial number\n"); return SC_ERROR_INTERNAL; } /* cache serial number */ @@ -934,7 +934,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, /* check PIN length */ if (pdata->pin1.len < 4 || pdata->pin1.len > 16) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid PIN1 length"); + sc_log(card->ctx, "invalid PIN1 length"); return SC_ERROR_INVALID_PIN_LENGTH; } @@ -951,13 +951,13 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); + sc_log(card->ctx, "APDU transmit failed"); break; case SC_PIN_CMD_CHANGE: if (pdata->pin_type != SC_AC_CHV) return SC_ERROR_INVALID_ARGUMENTS; if (pdata->pin2.len < 4 || pdata->pin2.len > 16) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid PIN2 length"); + sc_log(card->ctx, "invalid PIN2 length"); return SC_ERROR_INVALID_PIN_LENGTH; } /* 1. step: verify the old pin */ @@ -966,7 +966,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); + sc_log(card->ctx, "APDU transmit failed"); break; } if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { @@ -979,13 +979,13 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); + sc_log(card->ctx, "APDU transmit failed"); break; case SC_PIN_CMD_UNBLOCK: if (pdata->pin_type != SC_AC_CHV) return SC_ERROR_INVALID_ARGUMENTS; if (pdata->pin2.len < 4 || pdata->pin2.len > 16) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid PIN2 length"); + sc_log(card->ctx, "invalid PIN2 length"); return SC_ERROR_INVALID_PIN_LENGTH; } /* 1. step: verify the puk */ @@ -994,7 +994,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); + sc_log(card->ctx, "APDU transmit failed"); break; } /* 2, step: unblock and change the pin */ @@ -1003,12 +1003,12 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed"); + sc_log(card->ctx, "APDU transmit failed"); break; } break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error: unknown cmd type"); + sc_log(card->ctx, "error: unknown cmd type"); return SC_ERROR_INTERNAL; } /* Clear the buffer - it may contain pins */ diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 87b1df9bd7..86102b446d 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -153,7 +153,7 @@ static int process_fci(struct sc_context *ctx, struct sc_file *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "processing FCI bytes\n"); + sc_log(ctx, "processing FCI bytes\n"); if (buflen < 2) return SC_ERROR_INTERNAL; @@ -175,7 +175,7 @@ static int process_fci(struct sc_context *ctx, struct sc_file *file, tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " bytes in file: %d\n", bytes); + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -224,8 +224,8 @@ static int process_fci(struct sc_context *ctx, struct sc_file *file, } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " type: %s\n", type); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " EF structure: %s\n", structure); + sc_log(ctx, " type: %s\n", type); + sc_log(ctx, " EF structure: %s\n", structure); } file->magic = SC_FILE_MAGIC; @@ -392,7 +392,7 @@ static int atrust_acos_select_file(struct sc_card *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", @@ -417,7 +417,7 @@ static int atrust_acos_select_file(struct sc_card *card, && card->cache.current_path.len == pathlen && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cache hit\n"); + sc_log(card->ctx, "cache hit\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } else @@ -489,7 +489,7 @@ static int atrust_acos_select_file(struct sc_card *card, { /* done: we are already in the * requested directory */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cache hit\n"); + sc_log(card->ctx, "cache hit\n"); /* copy file info (if necessary) */ if (file_out) { sc_file_t *file = sc_file_new(); @@ -802,13 +802,13 @@ static int atrust_acos_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); + sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); if (sw1 == 0x90) return SC_SUCCESS; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verification failed (remaining tries: %d)\n", + sc_log(card->ctx, "Verification failed (remaining tries: %d)\n", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index ccbca50d35..414333bbd1 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -174,7 +174,7 @@ static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddata r = sc_bytes2apdu(card->ctx, carddata_cmd, sizeof(carddata_cmd), &apdu); if(r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "bytes to APDU conversion failed: %d\n", r); + sc_log(card->ctx, "bytes to APDU conversion failed: %d\n", r); return r; } @@ -183,17 +183,17 @@ static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddata r = sc_transmit_apdu(card, &apdu); if(r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "GetCardData command failed: %d\n", r); + sc_log(card->ctx, "GetCardData command failed: %d\n", r); return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if(r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "GetCardData: card returned %d\n", r); + sc_log(card->ctx, "GetCardData: card returned %d\n", r); return r; } if(apdu.resplen < carddataloc_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "GetCardData: card returned %"SC_FORMAT_LEN_SIZE_T"u bytes rather than expected %d\n", apdu.resplen, carddataloc_len); return SC_ERROR_WRONG_LENGTH; @@ -217,7 +217,7 @@ static int belpic_init(sc_card_t *card) int key_size = 1024; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s\n", BELPIC_VERSION); + sc_log(card->ctx, "Belpic V%s\n", BELPIC_VERSION); if (card->type < 0) card->type = SC_CARD_TYPE_BELPIC_EID; /* Unknown card: assume it's the Belpic Card */ @@ -339,7 +339,7 @@ static int belpic_set_security_env(sc_card_t *card, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "belpic_set_security_env(), keyRef = 0x%0x, algo = 0x%0x\n", + sc_log(card->ctx, "belpic_set_security_env(), keyRef = 0x%0x, algo = 0x%0x\n", *env->key_ref, env->algorithm_flags); assert(card != NULL && env != NULL); @@ -357,7 +357,7 @@ static int belpic_set_security_env(sc_card_t *card, else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_MD5) sbuf[2] = 0x04; else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Set Sec Env: unsupported algo 0X%0X\n", + sc_log(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n", env->algorithm_flags); return SC_ERROR_INVALID_ARGUMENTS; } @@ -390,7 +390,7 @@ static int belpic_set_security_env(sc_card_t *card, * the next function to be executed will be the compute_signature function. */ if (*env->key_ref == BELPIC_KEY_REF_NONREP) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No GUI for NonRep key present, signature cancelled\n"); + sc_log(card->ctx, "No GUI for NonRep key present, signature cancelled\n"); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 8f313bb62f..b2c0c3cec9 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -261,7 +261,7 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n", ins, p1, p2, sendbuflen, card->max_send_size, card->max_recv_size); @@ -300,25 +300,25 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, apdu.resplen = 0; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p", apdu.flags, apdu.le, apdu.resplen, apdu.resp); /* with new adpu.c and chaining, this actually reads the whole object */ r = sc_transmit_apdu(card, &apdu); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x", r, apdu.resplen, apdu.sw1, apdu.sw2); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Transmit failed"); + sc_log(card->ctx, "Transmit failed"); goto err; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card returned error "); + sc_log(card->ctx, "Card returned error "); goto err; } @@ -465,7 +465,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if we didn't return it all last time, return the remainder */ if (priv->cached) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); if (idx > priv->cache_buf_len) { @@ -476,7 +476,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "clearing cache idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); if (priv->cache_buf) { @@ -537,7 +537,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, case CAC_OBJECT_TYPE_CERT: /* read file */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " obj= cert_file, val_len=%"SC_FORMAT_LEN_SIZE_T"u (0x%04"SC_FORMAT_LEN_SIZE_T"x)", val_len, val_len); cert_len = 0; @@ -750,7 +750,7 @@ static int cac_set_security_env(sc_card_t *card, const sc_security_env_t *env, i SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u\n", env->flags, env->operation, env->algorithm, env->algorithm_flags, env->algorithm_ref, env->key_ref[0], @@ -782,7 +782,7 @@ static int cac_rsa_op(sc_card_t *card, size_t rbuflen, outplen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, outlen); diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 6644ea0ccd..abfc408c68 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -136,7 +136,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if we didn't return it all last time, return the remainder */ if (priv->cached) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); if (idx > priv->cache_buf_len) { @@ -147,7 +147,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "clearing cache idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); free(priv->cache_buf); diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index a450da0fe8..c1ca12016c 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -96,7 +96,7 @@ static int cardos_match_card(sc_card_t *card) return 0; /* get the os version using GET DATA and compare it with * version in the ATR */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "checking cardos version ..."); + sc_log(card->ctx, "checking cardos version ..."); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x82); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -111,19 +111,19 @@ static int cardos_match_card(sc_card_t *card) /* version mismatch */ return 0; if (atr[11] <= 0x04) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos m4.01"); + sc_log(card->ctx, "found cardos m4.01"); card->type = SC_CARD_TYPE_CARDOS_M4_01; } else if (atr[11] == 0x08) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.3b"); + sc_log(card->ctx, "found cardos v4.3b"); card->type = SC_CARD_TYPE_CARDOS_M4_3; } else if (atr[11] == 0x09) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2b"); + sc_log(card->ctx, "found cardos v4.2b"); card->type = SC_CARD_TYPE_CARDOS_M4_2B; } else if (atr[11] >= 0x0B) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2c or higher"); + sc_log(card->ctx, "found cardos v4.2c or higher"); card->type = SC_CARD_TYPE_CARDOS_M4_2C; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos m4.2"); + sc_log(card->ctx, "found cardos m4.2"); } } return 1; @@ -315,13 +315,13 @@ static int cardos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < err_count; i++) { if (cardos_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( cardos_errors[i].errorstr ) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", + sc_log(card->ctx, "%s\n", cardos_errors[i].errorstr); return cardos_errors[i].errorno; } } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -351,7 +351,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "DIRECTORY command returned error"); if (apdu.resplen > 256) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "directory listing > 256 bytes, cutting"); + sc_log(card->ctx, "directory listing > 256 bytes, cutting"); } len = apdu.resplen; @@ -360,7 +360,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) /* is there a file information block (0x6f) ? */ p = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen); if (p == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "directory tag missing"); + sc_log(card->ctx, "directory tag missing"); return SC_ERROR_INTERNAL; } if (tlen == 0) @@ -368,7 +368,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) break; q = sc_asn1_find_tag(card->ctx, p, tlen, 0x86, &ilen); if (q == NULL || ilen != 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error parsing file id TLV object"); + sc_log(card->ctx, "error parsing file id TLV object"); return SC_ERROR_INTERNAL; } /* put file id in buf */ @@ -510,7 +510,7 @@ static int cardos_acl_to_bytes(sc_card_t *card, const sc_file_t *file, else byte = acl_to_byte(sc_file_get_acl_entry(file, idx[i])); if (byte < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid ACL\n"); + sc_log(card->ctx, "Invalid ACL\n"); return SC_ERROR_INVALID_ARGUMENTS; } buf[i] = byte; @@ -643,7 +643,7 @@ static int cardos_construct_fcp(sc_card_t *card, const sc_file_t *file, buf[4] |= (u8) file->record_count; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unknown EF type: %u", file->type); + sc_log(card->ctx, "unknown EF type: %u", file->type); return SC_ERROR_INVALID_ARGUMENTS; } if (file->ef_structure == SC_FILE_EF_CYCLIC || @@ -720,7 +720,7 @@ static int cardos_create_file(sc_card_t *card, sc_file_t *file) r = cardos_construct_fcp(card, file, sbuf, &len); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create FCP"); + sc_log(card->ctx, "unable to create FCP"); return r; } @@ -1045,7 +1045,7 @@ cardos_lifecycle_get(sc_card_t *card, int *mode) *mode = SC_CARDCTRL_LIFECYCLE_OTHER; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown lifecycle byte %d", rbuf[0]); + sc_log(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); r = SC_ERROR_INTERNAL; } @@ -1191,7 +1191,7 @@ static int cardos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (apdu.resplen != 32) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unexpected response to GET DATA serial" + sc_log(card->ctx, "unexpected response to GET DATA serial" " number\n"); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index c17e7a9679..4fd76f0a40 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -894,7 +894,7 @@ coolkey_number_of_error_codes = sizeof(coolkey_error_codes)/sizeof(coolkey_error static int coolkey_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); if (sw1 == 0x90) @@ -941,7 +941,7 @@ static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n", ins, p1, p2, sendbuflen, card->max_send_size, card->max_recv_size); @@ -1006,24 +1006,24 @@ static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2, apdu.resplen = 0; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p", apdu.flags, apdu.le, apdu.resplen, apdu.resp); /* with new adpu.c and chaining, this actually reads the whole object */ r = sc_transmit_apdu(card, &apdu); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x", r, apdu.resplen, apdu.sw1, apdu.sw2); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Transmit failed"); + sc_log(card->ctx, "Transmit failed"); goto err; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Transmit failed"); + sc_log(card->ctx, "Transmit failed"); goto err; } @@ -1216,7 +1216,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, /* if we've already read the data, just return it */ if (priv->obj->data) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "returning cached value idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); len = MIN(count, priv->obj->length-idx); @@ -1224,7 +1224,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "clearing cache idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); @@ -1641,7 +1641,7 @@ static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *en SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u\n", env->flags, env->operation, env->algorithm, env->algorithm_flags, env->algorithm_ref, env->key_ref[0], @@ -1700,7 +1700,7 @@ static int coolkey_rsa_op(sc_card_t *card, u8 *buf_out; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, max_out_len); @@ -1803,7 +1803,7 @@ static int coolkey_ecc_op(sc_card_t *card, u8 key_number; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, outlen); diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 3e42c11f87..fe732b3e5a 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -229,7 +229,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, len = apdu->lc; if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error."); + sc_log(card->ctx, "entersafe encryption error."); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } apdu->lc = len; @@ -238,7 +238,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, if(apdu->lc!=buffsize) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe build cipher apdu failed."); + sc_log(card->ctx, "entersafe build cipher apdu failed."); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); } @@ -643,7 +643,7 @@ static int entersafe_select_path(sc_card_t *card, { /* done: we are already in the * requested directory */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "cache hit\n"); /* copy file info (if necessary) */ if (file_out) { @@ -691,7 +691,7 @@ static int entersafe_select_file(sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", @@ -1008,7 +1008,7 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, if(data->cmd!=SC_PIN_CMD_UNBLOCK) { r = iso_ops->pin_cmd(card,data,tries_left); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verify rv:%i", r); + sc_log(card->ctx, "Verify rv:%i", r); } else { diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index da7ba7ca36..c6c8fbf09a 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -304,7 +304,7 @@ cryptoflex_process_file_attrs(sc_card_t *card, sc_file_t *file, file->type = SC_FILE_TYPE_DF; break; default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid file type: 0x%02X\n", *p); + sc_log(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } p += 2; @@ -368,7 +368,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file, file->type = SC_FILE_TYPE_WORKING_EF; break; default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid file type: 0x%02X\n", *p); + sc_log(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } @@ -415,7 +415,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file, case 0x04: break; default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid file type: 0x%02X\n", *p); + sc_log(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } switch (file->ef_structure) { @@ -515,7 +515,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_file_t *file; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called, p1=%u\n", p1); + sc_log(card->ctx, "called, p1=%u\n", p1); sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "path", buf, buflen); sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0); @@ -542,7 +542,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, if (apdu.resplen < 14) return SC_ERROR_UNKNOWN_DATA_RECEIVED; if (apdu.resp[0] == 0x6F) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unsupported: card returned FCI\n"); + sc_log(card->ctx, "unsupported: card returned FCI\n"); return SC_ERROR_UNKNOWN_DATA_RECEIVED; /* FIXME */ } file = sc_file_new(); @@ -575,7 +575,7 @@ static int flex_select_file(sc_card_t *card, const sc_path_t *path, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called, cached path=%s\n", pbuf); + sc_log(card->ctx, "called, cached path=%s\n", pbuf); switch (path->type) { case SC_PATH_TYPE_PATH: @@ -641,7 +641,7 @@ static int cryptoflex_list_files(sc_card_t *card, u8 *buf, size_t buflen) if (r) return r; if (apdu.resplen != 4) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "expected 4 bytes, got %"SC_FORMAT_LEN_SIZE_T"u.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; @@ -678,7 +678,7 @@ static int cyberflex_list_files(sc_card_t *card, u8 *buf, size_t buflen) if (r) return r; if (apdu.resplen != 6) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "expected 6 bytes, got %"SC_FORMAT_LEN_SIZE_T"u.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; @@ -698,7 +698,7 @@ static int flex_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00); @@ -783,7 +783,7 @@ cryptoflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, p[6] = 0x06; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid EF structure\n"); + sc_log(card->ctx, "Invalid EF structure\n"); return -1; } p[7] = 0xFF; /* allow Decrease and Increase */ @@ -849,7 +849,7 @@ cyberflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, break; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Creating %02x:%02x, size %"SC_FORMAT_LEN_SIZE_T"u %02"SC_FORMAT_LEN_SIZE_T"x:%02"SC_FORMAT_LEN_SIZE_T"x\n", file->id >> 8, file->id & 0xFF, @@ -878,7 +878,7 @@ cyberflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, p[4] = 0x1D; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid EF structure\n"); + sc_log(card->ctx, "Invalid EF structure\n"); return -1; } p[5] = 0x01; /* status?? */ @@ -903,7 +903,7 @@ static int flex_create_file(sc_card_t *card, sc_file_t *file) * abstracting the Cryptoflex/Cyberflex differences */ r = card->ops->construct_fci(card, file, sbuf, &sendlen); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File structure encoding failed.\n"); + sc_log(card->ctx, "File structure encoding failed.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (file->type != SC_FILE_TYPE_DF && file->ef_structure != SC_FILE_EF_TRANSPARENT) @@ -940,33 +940,33 @@ static int flex_set_security_env(sc_card_t *card, if (env->operation != SC_SEC_OPERATION_SIGN && env->operation != SC_SEC_OPERATION_DECIPHER) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto operation supplied.\n"); + sc_log(card->ctx, "Invalid crypto operation supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto algorithm supplied.\n"); + sc_log(card->ctx, "Invalid crypto algorithm supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) || (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card supports only raw RSA.\n"); + sc_log(card->ctx, "Card supports only raw RSA.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { if (env->key_ref_len != 1 || (env->key_ref[0] != 0 && env->key_ref[0] != 1)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid key reference supplied.\n"); + sc_log(card->ctx, "Invalid key reference supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } prv->rsa_key_ref = env->key_ref[0]; } if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Algorithm reference not supported.\n"); + sc_log(card->ctx, "Algorithm reference not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File reference is not 0012.\n"); + sc_log(card->ctx, "File reference is not 0012.\n"); return SC_ERROR_NOT_SUPPORTED; } return 0; @@ -988,13 +988,13 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data, size_t i, i2; if (data_len != 64 && data_len != 96 && data_len != 128 && data_len != 256) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Illegal input length: %"SC_FORMAT_LEN_SIZE_T"u\n", data_len); return SC_ERROR_INVALID_ARGUMENTS; } if (outlen < data_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Output buffer too small.\n"); + sc_log(card->ctx, "Output buffer too small.\n"); return SC_ERROR_BUFFER_TOO_SMALL; } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, prv->rsa_key_ref); @@ -1049,7 +1049,7 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data, case 96: alg_id = 0xC6; break; case 128: alg_id = 0xC8; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Illegal input length: %"SC_FORMAT_LEN_SIZE_T"u\n", data_len); return SC_ERROR_INVALID_ARGUMENTS; @@ -1057,7 +1057,7 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data, key_id = prv->rsa_key_ref + 1; /* Why? */ if (outlen < data_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Output buffer too small.\n"); + sc_log(card->ctx, "Output buffer too small.\n"); return SC_ERROR_BUFFER_TOO_SMALL; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x88, alg_id, key_id); @@ -1123,7 +1123,7 @@ static int flex_generate_key(sc_card_t *card, struct sc_cardctl_cryptoflex_genke case 1024: p2 = 0x80; break; case 2048: p2 = 0x00; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Illegal key length: %d\n", data->key_bits); + sc_log(card->ctx, "Illegal key length: %d\n", data->key_bits); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1175,7 +1175,7 @@ static int flex_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) len = tfile->size; sc_file_free(tfile); if (len != 8) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unexpected file length of EF_ICCSN (%lu)\n", + sc_log(card->ctx, "unexpected file length of EF_ICCSN (%lu)\n", (unsigned long) len); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 97fc25b475..7467b390c0 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -105,13 +105,13 @@ static int get_conf_aid(sc_card_t *card, u8 *aid, size_t *len) } if (!conf_block) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no card specific options configured, trying default AID\n"); + sc_log(ctx, "no card specific options configured, trying default AID\n"); return SC_ERROR_INTERNAL; } str_aid = scconf_get_str(conf_block, "aid", NULL); if (!str_aid) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no aid configured, trying default AID\n"); + sc_log(ctx, "no aid configured, trying default AID\n"); return SC_ERROR_INTERNAL; } return sc_hex_to_bin(str_aid, aid, len); @@ -191,7 +191,7 @@ static int gemsafe_init(struct sc_card *card) r = gp_select_applet(card, exdata->aid, exdata->aid_len); if (r < 0) { free(exdata); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "applet selection failed\n"); + sc_log(card->ctx, "applet selection failed\n"); return SC_ERROR_INVALID_CARD; } card->lock_count--; @@ -292,7 +292,7 @@ static int gemsafe_setacl(sc_card_t *card, sc_file_t *file, const u8 *data, cond = *p++; else cond = 0xff; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "DF security byte CREATE DF: %02x\n", cond); r = gemsafe_sc2acl(file, SC_AC_OP_CREATE, cond); if (r < 0) @@ -301,7 +301,7 @@ static int gemsafe_setacl(sc_card_t *card, sc_file_t *file, const u8 *data, cond = *p; else cond = 0xff; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "DF security byte CREATE EF: %02x\n", cond); /* XXX: opensc doesn't currently separate access conditions for * CREATE EF and CREATE DF, this should be changed */ @@ -315,7 +315,7 @@ static int gemsafe_setacl(sc_card_t *card, sc_file_t *file, const u8 *data, cond = *p++; else cond = 0xff; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "EF security byte UPDATE/ERASE BINARY: %02x\n", cond); r = gemsafe_sc2acl(file, SC_AC_OP_UPDATE, cond); if (r < 0) @@ -330,7 +330,7 @@ static int gemsafe_setacl(sc_card_t *card, sc_file_t *file, const u8 *data, cond = *p; else cond = 0xff; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "EF security byte READ BINARY: %02x\n", cond); r = gemsafe_sc2acl(file, SC_AC_OP_READ, cond); if (r < 0) @@ -354,7 +354,7 @@ static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file, r = iso_ops->process_fci(card, file, buf, len); if (r < 0) return r; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "processing GemSAFE V1 specific FCI information\n"); @@ -368,17 +368,17 @@ static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file, file->type = SC_FILE_TYPE_WORKING_EF; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file type: %s\n", type); + sc_log(ctx, "file type: %s\n", type); tag = sc_asn1_find_tag(ctx, p, len, 0x8C, &tlen); if (tag) { r = gemsafe_setacl(card, file, tag, strcmp(type, "DF") ? 0 : 1); if (r < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to set ACL\n"); + sc_log(ctx, "unable to set ACL\n"); return SC_ERROR_INTERNAL; } } else - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error: AM and SC bytes missing\n"); + sc_log(ctx, "error: AM and SC bytes missing\n"); return SC_SUCCESS; } @@ -443,7 +443,7 @@ static int gemsafe_set_security_env(struct sc_card *card, } } if (!(se_env.flags & SC_SEC_ENV_ALG_REF_PRESENT)) - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unknown algorithm flags '%x'\n", se_env.algorithm_flags); + sc_log(ctx, "unknown algorithm flags '%x'\n", se_env.algorithm_flags); se_env.flags &= ~SC_SEC_ENV_FILE_REF_PRESENT; return iso_ops->set_security_env(card, &se_env, se_num); @@ -462,7 +462,7 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, /* the card can sign 36 bytes of free form data */ if (data_len > 36) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "error: input data too long: %"SC_FORMAT_LEN_SIZE_T"u bytes\n", data_len); return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index b725fac28f..ba80e93176 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -170,12 +170,12 @@ static int gids_get_identifiers(sc_card_t* card, u8* masterfile, size_t masterfi if (strcmp(directory, records[i].directory) == 0 && strcmp(filename, records[i].filename) == 0) { *fileIdentifier = records[i].fileIdentifier; *dataObjectIdentifier = records[i].dataObjectIdentifier; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Identifiers of %s %s is fileIdentifier=%x, dataObjectIdentifier=%x\n", directory, filename, *fileIdentifier, *dataObjectIdentifier); return 0; } } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "file %s %s not found\n", directory, filename); + sc_log(card->ctx, "file %s %s not found\n", directory, filename); return SC_ERROR_FILE_NOT_FOUND; } @@ -214,7 +214,7 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti u8 buffer[MAX_GIDS_FILE_SIZE]; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Got args: fileIdentifier=%x, dataObjectIdentifier=%x, response=%p, responselen=%"SC_FORMAT_LEN_SIZE_T"u\n", fileIdentifier, dataObjectIdentifier, response, responselen ? *responselen : 0); @@ -251,7 +251,7 @@ static int gids_put_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE]; u8* p = buffer; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Got args: fileIdentifier=%x, dataObjectIdentifier=%x, data=%p, datalen=%"SC_FORMAT_LEN_SIZE_T"u\n", fileIdentifier, dataObjectIdentifier, data, datalen); @@ -279,7 +279,7 @@ static int gids_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Got args: aid=%p, aidlen=%"SC_FORMAT_LEN_SIZE_T"u, response=%p, responselen=%"SC_FORMAT_LEN_SIZE_T"u\n", aid, aidlen, response, responselen ? *responselen : 0); @@ -552,7 +552,7 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef *max_tries = p[0]; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Pin information for PIN 0x%x: triesleft=%d trieslimit=%d\n", pinreference, (tries_left?*tries_left:-1), (max_tries?*max_tries:-1)); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } @@ -579,7 +579,7 @@ static int gids_match_card(sc_card_t * card) if (tag != NULL) { aid = sc_asn1_find_tag(card->ctx, tag, taglen, GIDS_APPLICATION_AID_TAG, &aidlen); if (aid != NULL ) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"found AID"); + sc_log(card->ctx, "found AID"); for (i = 0; gids_aids[i].len_long != 0; i++) { if ( aidlen > gids_aids[i].len_long && memcmp(aid, gids_aids[i].value, gids_aids[i].len_long) == 0) { @@ -856,7 +856,7 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, size_t buffersize = sizeof(buffer); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Got args: key_reference=%x, response=%p, responselen=%"SC_FORMAT_LEN_SIZE_T"u\n", key_reference, response, responselen ? *responselen : 0); @@ -876,7 +876,7 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, keytemplate = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_PUBKEY_TAG, &tlen); if (keytemplate == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid public key data: missing tag"); + sc_log(card->ctx, "invalid public key data: missing tag"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -900,7 +900,7 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, r = sc_pkcs15_encode_pubkey_rsa(card->ctx, &rsa_key, response, responselen); LOG_TEST_RET(card->ctx, r, "failed to read public key: cannot encode RSA public key"); } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "it is not a known public key"); + sc_log(card->ctx, "it is not a known public key"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -1004,17 +1004,17 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, data->buffersize = sizeof(data->buffer); r = sc_decompress(data->buffer, &(data->buffersize), buffer+4, buffersize-4, COMPRESSION_ZLIB); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Zlib error: %d", r); + sc_log(card->ctx, "Zlib error: %d", r); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } if (data->buffersize != expectedsize) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "expected size: %"SC_FORMAT_LEN_SIZE_T"u real size: %"SC_FORMAT_LEN_SIZE_T"u", expectedsize, data->buffersize); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); } } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unknown compression method %d", buffer[0] + (buffer[1] <<8)); + sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] <<8)); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); } data->state = GIDS_STATE_READ_DATA_PRESENT; @@ -1123,11 +1123,11 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { // key was specified. Search if the key can be used size_t i = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER; if (i > GIDS_MAX_CONTAINER) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid key ref %d", key_info->key_reference); + sc_log(card->ctx, "invalid key ref %d", key_info->key_reference); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } if (i > recordsnum) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "container num is not allowed %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u", i, recordsnum); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); @@ -1266,8 +1266,8 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { } else { keymaprecordnum = (keymapbuffersize - 1) / sizeof(struct gids_keymap_record); if (keymaprecordnum != recordnum) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL , "Error: Unable to create the key file because the keymap and cmapfile are inconsistent"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL , + sc_log(card->ctx , "Error: Unable to create the key file because the keymap and cmapfile are inconsistent"); + sc_log(card->ctx , "keymaprecordnum = %"SC_FORMAT_LEN_SIZE_T"u recordnum = %"SC_FORMAT_LEN_SIZE_T"u", keymaprecordnum, recordnum); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); @@ -1435,11 +1435,11 @@ static int gids_import_key(sc_card_t *card, sc_pkcs15_object_t *object, sc_pkcs1 assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "GIDS supports RSA keys only (but may support ECC one day)."); + sc_log(card->ctx, "GIDS supports RSA keys only (but may support ECC one day)."); return SC_ERROR_NOT_SUPPORTED; } if (!key->u.rsa.dmp1.len || !key->u.rsa.dmq1.len || !key->u.rsa.iqmp.len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "GIDS needs dmp1 & dmq1 & iqmp"); + sc_log(card->ctx, "GIDS needs dmp1 & dmq1 & iqmp"); return SC_ERROR_NOT_SUPPORTED; } sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 0, &version, NULL, 1); @@ -1971,7 +1971,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { if (apdu.resplen != 44) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Expecting a response len of 44 - found %d",(int) apdu.resplen); + sc_log(card->ctx, "Expecting a response len of 44 - found %d",(int) apdu.resplen); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } // init crypto @@ -1985,26 +1985,26 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt data"); + sc_log(card->ctx, "unable to decrypt data"); EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); } if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to decrypt final data"); + sc_log(card->ctx, "unable to decrypt final data"); EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "data has been decrypted using the key"); + sc_log(card->ctx, "data has been decrypted using the key"); if (memcmp(buffer3, randomR1, 16) != 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R1 doesn't match"); + sc_log(card->ctx, "R1 doesn't match"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); } if (memcmp(buffer3 + 16, randomR2, 16) != 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "R2 doesn't match"); + sc_log(card->ctx, "R2 doesn't match"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); } if (buffer[39] != 0x80) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding not found"); + sc_log(card->ctx, "Padding not found"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); } EVP_CIPHER_CTX_free(ctx); diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 1d67952a6e..88590aafb4 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -534,7 +534,7 @@ gpk_select_id(sc_card_t *card, int kind, unsigned int fid, u8 fbuf[2]; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "gpk_select_id(0x%04X, kind=%u)\n", fid, kind); fbuf[0] = fid >> 8; @@ -685,7 +685,7 @@ gpk_read_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid file offset (not a multiple of %d)", + sc_log(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -700,7 +700,7 @@ gpk_write_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid file offset (not a multiple of %d)", + sc_log(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -715,7 +715,7 @@ gpk_update_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid file offset (not a multiple of %d)", + sc_log(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -785,7 +785,7 @@ gpk_verify_crycks(sc_card_t *card, sc_apdu_t *apdu, u8 *crycks) { if (apdu->resplen < 3 || memcmp(apdu->resp + apdu->resplen - 3, crycks, 3)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Invalid secure messaging reply\n"); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } @@ -808,7 +808,7 @@ gpk_create_file(sc_card_t *card, sc_file_t *file) size_t datalen, namelen; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "gpk_create_file(0x%04X)\n", file->id); /* Prepare APDU */ @@ -1014,7 +1014,7 @@ gpk_set_security_env(sc_card_t *card, if (env->flags & SC_SEC_ENV_ALG_PRESENT) algorithm = env->algorithm; if (algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Algorithm not supported.\n"); + sc_log(card->ctx, "Algorithm not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } priv->sec_algorithm = algorithm; @@ -1022,7 +1022,7 @@ gpk_set_security_env(sc_card_t *card, /* If there's a key reference, it must be 0 */ if ((env->flags & SC_SEC_ENV_KEY_REF_PRESENT) && (env->key_ref_len != 1 || env->key_ref[0] != 0)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown key referenced.\n"); + sc_log(card->ctx, "Unknown key referenced.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -1035,7 +1035,7 @@ gpk_set_security_env(sc_card_t *card, else if (env->flags & SC_ALGORITHM_RSA_PAD_ISO9796) priv->sec_padding = 2; else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding algorithm not supported.\n"); + sc_log(card->ctx, "Padding algorithm not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -1058,7 +1058,7 @@ gpk_set_security_env(sc_card_t *card, context = GPK_SIGN_RSA_MD5; priv->sec_hash_len = 16; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported signature algorithm"); + sc_log(card->ctx, "Unsupported signature algorithm"); return SC_ERROR_NOT_SUPPORTED; } break; @@ -1066,20 +1066,20 @@ gpk_set_security_env(sc_card_t *card, context = GPK_UNWRAP_RSA; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Crypto operation not supported.\n"); + sc_log(card->ctx, "Crypto operation not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } /* Get the file ID */ if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { if (env->file_ref.len != 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File reference: invalid length.\n"); + sc_log(card->ctx, "File reference: invalid length.\n"); return SC_ERROR_INVALID_ARGUMENTS; } file_id = (env->file_ref.value[0] << 8) | env->file_ref.value[1]; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File reference missing.\n"); + sc_log(card->ctx, "File reference missing.\n"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1093,11 +1093,11 @@ gpk_set_security_env(sc_card_t *card, SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to read PK sysrec"); if (r != 7 || sysrec[0] != 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "First record of file is not the sysrec"); + sc_log(card->ctx, "First record of file is not the sysrec"); return SC_ERROR_OBJECT_NOT_VALID; } if (sysrec[5] != 0x00) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Public key is not an RSA key"); + sc_log(card->ctx, "Public key is not an RSA key"); return SC_ERROR_OBJECT_NOT_VALID; } switch (sysrec[1]) { @@ -1105,7 +1105,7 @@ gpk_set_security_env(sc_card_t *card, case 0x10: priv->sec_mod_len = 768 / 8; break; case 0x11: priv->sec_mod_len = 1024 / 8; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported modulus length"); + sc_log(card->ctx, "Unsupported modulus length"); return SC_ERROR_OBJECT_NOT_VALID; } @@ -1237,7 +1237,7 @@ gpk_compute_signature(sc_card_t *card, const u8 *data, int r; if (data_len > priv->sec_mod_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Data length (%"SC_FORMAT_LEN_SIZE_T"u) does not match key modulus %u.\n", data_len, priv->sec_mod_len); return SC_ERROR_INTERNAL; @@ -1291,7 +1291,7 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen, int r; if (inlen != priv->sec_mod_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Data length (%"SC_FORMAT_LEN_SIZE_T"u) does not match key modulus %u.\n", inlen, priv->sec_mod_len); return SC_ERROR_INVALID_ARGUMENTS; @@ -1388,7 +1388,7 @@ gpk_lock(sc_card_t *card, struct sc_cardctl_gpk_lock *args) u8 data[8], crycks[3], resp[3]; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "gpk_lock(0x%04X, %u)\n", file->id, args->operation); memset(data, 0, sizeof(data)); @@ -1445,7 +1445,7 @@ gpk_pkfile_init(sc_card_t *card, struct sc_cardctl_gpk_pkinit *args) sc_apdu_t apdu; int r; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "gpk_pkfile_init(%u)\n", args->privlen); memset(&apdu, 0, sizeof(apdu)); @@ -1473,10 +1473,10 @@ gpk_generate_key(sc_card_t *card, struct sc_cardctl_gpk_genkey *args) int r; u8 buffer[256]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "gpk_generate_key(%u)\n", args->privlen); if (args->privlen != 512 && args->privlen != 1024) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Key generation not supported for key length %d", args->privlen); return SC_ERROR_NOT_SUPPORTED; @@ -1522,7 +1522,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) int r = SC_SUCCESS, outl; EVP_CIPHER_CTX * ctx; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n", + sc_log(card->ctx, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n", args->file->id, args->len, args->datalen); ctx = EVP_CIPHER_CTX_new(); @@ -1545,7 +1545,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) /* encrypt the private key material */ assert(args->datalen <= sizeof(temp)); if (!priv->key_set) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No secure messaging key set!\n"); + sc_log(card->ctx, "No secure messaging key set!\n"); return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } @@ -1624,7 +1624,7 @@ static int gpk_get_info(sc_card_t *card, int p1, int p2, u8 *buf, apdu.resplen = buflen; if ((r = sc_transmit_apdu(card, &apdu)) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed: %s", + sc_log(card->ctx, "APDU transmit failed: %s", sc_strerror(r)); sc_unlock(card); return r; diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index e324a2a7ae..79c49350dc 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -152,13 +152,13 @@ static int incrypto34_check_sw(sc_card_t *card, unsigned int sw1, unsigned int s for (i = 0; i < err_count; i++) { if (incrypto34_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( incrypto34_errors[i].errorstr ) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", + sc_log(card->ctx, "%s\n", incrypto34_errors[i].errorstr); return incrypto34_errors[i].errorno; } } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -327,7 +327,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) "%02X", file->path.value[n]); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "incrypto34_create_file(%s)\n", pbuf); + sc_log(card->ctx, "incrypto34_create_file(%s)\n", pbuf); if (file->type_attr_len == 0) { memset(type, 0, sizeof(type)); @@ -388,7 +388,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) byte = acl_to_byte( sc_file_get_acl_entry(file, idx[i])); if (byte < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid ACL\n"); + sc_log(card->ctx, "Invalid ACL\n"); r = SC_ERROR_INVALID_ARGUMENTS; goto out; } @@ -448,7 +448,7 @@ static int incrypto34_set_security_env(sc_card_t *card, if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No or invalid key reference\n"); + sc_log(card->ctx, "No or invalid key reference\n"); return SC_ERROR_INVALID_ARGUMENTS; } key_id = env->key_ref[0]; @@ -546,12 +546,12 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, * succeeds (this is not really beautiful, but currently the * only way I see) -- Nils */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n"); r = do_compute_signature(card, data, datalen, out, outlen); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "trying RSA_SIG (just the DigestInfo)\n"); /* remove padding: first try pkcs1 bt01 padding */ r = sc_pkcs1_strip_01_padding(ctx, data, datalen, buf, &tmp_len); @@ -570,7 +570,7 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, r = do_compute_signature(card, buf, tmp_len, out, outlen); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "trying to sign raw hash value\n"); r = sc_pkcs1_strip_digest_info_prefix(NULL,buf,tmp_len,buf,&buf_len); if (r != SC_SUCCESS) @@ -615,7 +615,7 @@ incrypto34_lifecycle_get(sc_card_t *card, int *mode) *mode = SC_CARDCTRL_LIFECYCLE_OTHER; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown lifecycle byte %d", rbuf[0]); + sc_log(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); r = SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 56469da8d8..73412383f5 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -108,7 +108,7 @@ static int itacns_match_cns_card(sc_card_t *card, unsigned int i) if(atr[i] != 0x10) { char version[8]; snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CNS card version %s; no official specifications " + sc_log(card->ctx, "CNS card version %s; no official specifications " "are published. Proceeding anyway.\n", version); } i++; @@ -292,7 +292,7 @@ static int itacns_set_security_env(sc_card_t *card, if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "No or invalid key reference\n"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -497,7 +497,7 @@ static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) return SC_SUCCESS; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Reading EF_IDCarta.\n"); + sc_log(card->ctx, "Reading EF_IDCarta.\n"); sc_format_path("3F0010001003", &path); @@ -512,7 +512,7 @@ static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) //do not return FCI/FCP templates that include the file size. //Notify abnormal length anyway. if (len != 16) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Unexpected file length of EF_IDCarta (%lu)\n", (unsigned long) len); } diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index a8dfa8d3db..85feddc6a2 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -624,11 +624,11 @@ static int jcop_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Only RSA algorithm supported.\n"); + sc_log(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)){ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card requires RSA padding\n"); + sc_log(card->ctx, "Card requires RSA padding\n"); return SC_ERROR_NOT_SUPPORTED; } tmp.algorithm_ref = 0x02; @@ -681,13 +681,13 @@ static int jcop_set_security_env(sc_card_t *card, apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); return r; } @@ -811,7 +811,7 @@ static int jcop_generate_key(sc_card_t *card, struct sc_cardctl_jcop_genkey *a) if (a->exponent == 0x10001) { is_f4=1; } else if (a->exponent != 3) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Invalid exponent", sc_strerror(SC_ERROR_NOT_SUPPORTED)); return SC_ERROR_NOT_SUPPORTED; } @@ -841,13 +841,13 @@ static int jcop_generate_key(sc_card_t *card, struct sc_cardctl_jcop_genkey *a) apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); return r; } @@ -860,13 +860,13 @@ static int jcop_generate_key(sc_card_t *card, struct sc_cardctl_jcop_genkey *a) r = sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); return r; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); return r; } diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index fd53cd0b66..a8d11160b4 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -72,7 +72,7 @@ static int masktech_init(sc_card_t * card) unsigned long flags; struct masktech_private_data *data; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "masktech_init()\n"); + sc_log(card->ctx, "masktech_init()\n"); /* private data kept during the live of the driver */ if (!(data = (struct masktech_private_data *) malloc(sizeof(*data)))) @@ -104,7 +104,7 @@ static int masktech_set_security_env(sc_card_t *card, int se_num) { struct masktech_private_data *private_data; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "masktech_set_security_env(), keyRef = 0x%0x, algo = 0x%0x\n", + sc_log(card->ctx, "masktech_set_security_env(), keyRef = 0x%0x, algo = 0x%0x\n", *env->key_ref, env->algorithm_flags); private_data = (struct masktech_private_data *) card->drv_data; @@ -114,7 +114,7 @@ static int masktech_set_security_env(sc_card_t *card, /* save the key reference */ if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { if (env->key_ref_len != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid key reference supplied.\n"); + sc_log(card->ctx, "Invalid key reference supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } private_data->rsa_key_ref = env->key_ref[0]; @@ -137,7 +137,7 @@ static int masktech_compute_signature(sc_card_t *card, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; assert(card != NULL && data != NULL && out != NULL); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "masktech_compute_signature()\n"); + sc_log(card->ctx, "masktech_compute_signature()\n"); /* retrieve the key reference */ private_data = (struct masktech_private_data *) card->drv_data; @@ -150,7 +150,7 @@ static int masktech_compute_signature(sc_card_t *card, /* check that it is a SHA256 with digest info*/ if ((datalen != sizeof(hdr_sha256) + 32) || (memcmp(hdr_sha256, data, sizeof(hdr_sha256)) != 0)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "It is not a SHA256 with digestinfo\n"); + sc_log(card->ctx, "It is not a SHA256 with digestinfo\n"); return SC_ERROR_NOT_SUPPORTED; } /* extract the SHA-256 hash */ @@ -176,7 +176,7 @@ static int masktech_decipher(sc_card_t *card, u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; assert(card != NULL && crgram != NULL && out != NULL); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "masktech_decipher()\n"); + sc_log(card->ctx, "masktech_decipher()\n"); if (crgram_len > SC_MAX_EXT_APDU_BUFFER_SIZE) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); @@ -343,7 +343,7 @@ static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) static int masktech_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "masktech_card_ctl()\n"); + sc_log(card->ctx, "masktech_card_ctl()\n"); switch (cmd) { case SC_CARDCTL_GET_SERIALNR: return masktech_get_serialnr(card, (sc_serial_number_t *) ptr); diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 146b4cf02f..d110aa5987 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1397,7 +1397,7 @@ static int mcrd_decipher(struct sc_card *card, if (crgram_len > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Will derive (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n", env->operation, crgram_len, crgram_len, env->key_ref[0], env->algorithm, env->algorithm_flags); diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index 7d33e5210d..a41ce15331 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -139,7 +139,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, *p++ = 0x43; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid EF structure\n"); + sc_log(card->ctx, "Invalid EF structure\n"); return SC_ERROR_INVALID_ARGUMENTS; } ops = ef_ops; @@ -149,7 +149,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, ops = key_ops; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown file type\n"); + sc_log(card->ctx, "Unknown file type\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (file->type == SC_FILE_TYPE_DF) { @@ -170,7 +170,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, else { int byte = acl_to_byte(sc_file_get_acl_entry(file, ops[i])); if (byte < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid ACL\n"); + sc_log(card->ctx, "Invalid ACL\n"); return SC_ERROR_INVALID_ARGUMENTS; } nibble = byte; @@ -237,7 +237,7 @@ static int miocos_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Only RSA algorithm supported.\n"); + sc_log(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } tmp.algorithm_ref = 0x00; @@ -414,7 +414,7 @@ static int miocos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } r = sc_select_file(card, path, NULL); @@ -452,7 +452,7 @@ static int miocos_create_ac(sc_card_t *card, sendsize = 20; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "AC type %d not supported\n", ac->type); + sc_log(card->ctx, "AC type %d not supported\n", ac->type); return SC_ERROR_NOT_SUPPORTED; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x1E, miocos_type, @@ -472,7 +472,7 @@ static int miocos_card_ctl(sc_card_t *card, unsigned long cmd, case SC_CARDCTL_MIOCOS_CREATE_AC: return miocos_create_ac(card, (struct sc_cardctl_miocos_ac_info *) arg); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "card_ctl command 0x%lX not supported\n", cmd); + sc_log(card->ctx, "card_ctl command 0x%lX not supported\n", cmd); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index be5b9f146b..bc660d2f3e 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -277,7 +277,7 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) /* Delete children */ mscfs_check_cache(fs); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "DELETING Children of: %02X%02X%02X%02X\n", oid[0],oid[1],oid[2],oid[3]); for(x = 0; x < fs->cache.size; x++) { @@ -286,7 +286,7 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) objectId = childFile->objectId; if(0 == memcmp(oid + 2, objectId.id, 2)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "DELETING: %02X%02X%02X%02X\n", objectId.id[0],objectId.id[1], objectId.id[2],objectId.id[3]); @@ -525,7 +525,7 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) u8* oid = fs->cache.array[x].objectId.id; if (bufLen < 2) break; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "FILE: %02X%02X%02X%02X\n", oid[0],oid[1],oid[2],oid[3]); if(0 == memcmp(fs->currentPath, oid, 2)) { @@ -565,7 +565,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n"); + sc_log(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } case SC_PIN_CMD_CHANGE: @@ -581,7 +581,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n"); + sc_log(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } case SC_PIN_CMD_UNBLOCK: @@ -597,11 +597,11 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n"); + sc_log(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported command\n"); + sc_log(card->ctx, "Unsupported command\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -678,34 +678,34 @@ static int muscle_set_security_env(sc_card_t *card, if (env->operation != SC_SEC_OPERATION_SIGN && env->operation != SC_SEC_OPERATION_DECIPHER) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto operation supplied.\n"); + sc_log(card->ctx, "Invalid crypto operation supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto algorithm supplied.\n"); + sc_log(card->ctx, "Invalid crypto algorithm supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } /* ADJUST FOR PKCS1 padding support for decryption only */ if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) || (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card supports only raw RSA.\n"); + sc_log(card->ctx, "Card supports only raw RSA.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { if (env->key_ref_len != 1 || (env->key_ref[0] > 0x0F)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid key reference supplied.\n"); + sc_log(card->ctx, "Invalid key reference supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } priv->rsa_key_ref = env->key_ref[0]; } if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Algorithm reference not supported.\n"); + sc_log(card->ctx, "Algorithm reference not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } /* if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File reference is not 0012.\n"); + sc_log(card->ctx, "File reference is not 0012.\n"); return SC_ERROR_NOT_SUPPORTED; } */ priv->env = *env; @@ -736,7 +736,7 @@ static int muscle_decipher(sc_card_t * card, key_id = priv->rsa_key_ref * 2; /* Private key */ if (out_len < crgram_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Output buffer too small"); + sc_log(card->ctx, "Output buffer too small"); return SC_ERROR_BUFFER_TOO_SMALL; } @@ -762,7 +762,7 @@ static int muscle_compute_signature(sc_card_t *card, const u8 *data, key_id = priv->rsa_key_ref * 2; /* Private key */ if (outlen < data_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Output buffer too small"); + sc_log(card->ctx, "Output buffer too small"); return SC_ERROR_BUFFER_TOO_SMALL; } diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7570b9ce50..f09e8a06a2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1155,7 +1155,7 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); if (r < 0 || data == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Unexpected end of contents\n"); return SC_ERROR_OBJECT_NOT_VALID; } diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 506e030b05..c86f77e060 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -149,7 +149,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 6]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 6]); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "SC_AC_OP_DELETE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_DELETE, method, key_ref); @@ -158,7 +158,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 0]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 0]); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, (file->type == SC_FILE_TYPE_DF) ? "SC_AC_OP_CREATE %i %lu\n" : "SC_AC_OP_READ %i %lu\n", @@ -176,11 +176,11 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 1]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 1]); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "SC_AC_OP_UPDATE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, method, key_ref); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "SC_AC_OP_WRITE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_WRITE, method, key_ref); @@ -379,7 +379,7 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, assert(buf); free(buf); if (r) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "APDU transmit failed: %s\n", sc_strerror(r)); + sc_log(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r)); else { if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) @@ -435,7 +435,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, int transmits_num, r; assert(card && card->ctx && newref); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "newlen = %"SC_FORMAT_LEN_SIZE_T"u\n", newlen); if (newlen > 0xFFFF) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); @@ -649,12 +649,12 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) apdu.le = 256; break; case SC_CARDCTL_LIFECYCLE_SET: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", + sc_log(card->ctx, "%s\n", "SC_CARDCTL_LIFECYCLE_SET not supported"); /* no call sc_debug (SC_FUNC_RETURN) */ return SC_ERROR_NOT_SUPPORTED; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "request = 0x%lx\n", request); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); } diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 5f3dc70572..57d7f43ff5 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -103,7 +103,7 @@ static int rutoken_match_card(sc_card_t *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (_sc_match_atr(card, rutoken_atrs, &card->type) >= 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "ATR recognized as Rutoken\n"); + sc_log(card->ctx, "ATR recognized as Rutoken\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 1); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0); @@ -202,12 +202,12 @@ static int rutoken_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < sizeof(rutoken_errors)/sizeof(rutoken_errors[0]); ++i) { if (rutoken_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( rutoken_errors[i].errorstr ) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", rutoken_errors[i].errorstr); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "sw1 = %x, sw2 = %x", sw1, sw2); + sc_log(card->ctx, "%s\n", rutoken_errors[i].errorstr); + sc_log(card->ctx, "sw1 = %x, sw2 = %x", sw1, sw2); return rutoken_errors[i].errorno; } } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -312,7 +312,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) SC_AC_NONE, SC_AC_KEY_REF_NONE); if (file->sec_attr[0] & 0x40) /* if AccessMode.6 */ { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SC_AC_OP_DELETE %i %i", + sc_log(card->ctx, "SC_AC_OP_DELETE %i %i", (int)(*(int8_t*)&file->sec_attr[1 +6]), file->sec_attr[1+7 +6*4]); sc_file_add_acl_entry(file, SC_AC_OP_DELETE, @@ -321,7 +321,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) } if (file->sec_attr[0] & 0x01) /* if AccessMode.0 */ { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, (file->type == SC_FILE_TYPE_DF) ? + sc_log(card->ctx, (file->type == SC_FILE_TYPE_DF) ? "SC_AC_OP_CREATE %i %i" : "SC_AC_OP_READ %i %i", (int)(*(int8_t*)&file->sec_attr[1 +0]), file->sec_attr[1+7 +0*4]); @@ -339,13 +339,13 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) else if (file->sec_attr[0] & 0x02) /* if AccessMode.1 */ { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SC_AC_OP_UPDATE %i %i", + sc_log(card->ctx, "SC_AC_OP_UPDATE %i %i", (int)(*(int8_t*)&file->sec_attr[1 +1]), file->sec_attr[1+7 +1*4]); sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, (int)(*(int8_t*)&file->sec_attr[1 +1]), file->sec_attr[1+7 +1*4]); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SC_AC_OP_WRITE %i %i", + sc_log(card->ctx, "SC_AC_OP_WRITE %i %i", (int)(*(int8_t*)&file->sec_attr[1 +1]), file->sec_attr[1+7 +1*4]); sc_file_add_acl_entry(file, SC_AC_OP_WRITE, @@ -460,14 +460,14 @@ static int rutoken_process_fci(struct sc_card *card, sc_file_t *file, /* Rutoken S returns buffers in little-endian. */ /* Set correct file id. */ file->id = ((file->id & 0xFF) << 8) | ((file->id >> 8) & 0xFF); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " file identifier: 0x%04X", file->id); + sc_log(card->ctx, " file identifier: 0x%04X", file->id); /* Determine file size. */ tag = sc_asn1_find_tag(card->ctx, buf, buflen, 0x80, &taglen); /* Rutoken S always returns 2 bytes. */ if (tag != NULL && taglen == 2) { file->size = (tag[1] << 8) | tag[0]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); + sc_log(card->ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); } } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); @@ -560,7 +560,7 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) conv_attr = arr_convert_attr_ef; n_conv_attr = sizeof(arr_convert_attr_ef)/sizeof(arr_convert_attr_ef[0]); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "file->type = %i", file->type); + sc_log(card->ctx, "file->type = %i", file->type); for (i = 0; i < n_conv_attr; ++i) { @@ -571,20 +571,20 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) { /* AccessMode.[conv_attr[i].sec_attr_pos] */ attr[0] |= 1 << conv_attr[i].sec_attr_pos; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "AccessMode.%"SC_FORMAT_LEN_SIZE_T"u, attr[0]=0x%x", conv_attr[i].sec_attr_pos, attr[0]); attr[1 + conv_attr[i].sec_attr_pos] = (u8)entry->method; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "method %u", (u8)entry->method); + sc_log(card->ctx, "method %u", (u8)entry->method); if (entry->method == SC_AC_CHV) { attr[1+7 + conv_attr[i].sec_attr_pos*4] = (u8)entry->key_ref; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "key_ref %u", (u8)entry->key_ref); + sc_log(card->ctx, "key_ref %u", (u8)entry->key_ref); } } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "ACL (%u) not set, set default sec_attr", + sc_log(card->ctx, "ACL (%u) not set, set default sec_attr", conv_attr[i].ac_op); memcpy(attr, default_sec_attr, sizeof(attr)); break; @@ -620,7 +620,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (!path || path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } if (path->len == sizeof(sbuf)) @@ -739,7 +739,7 @@ static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, if (puk && puklen) { ret = rutoken_verify(card, type, ref_qualifier, puk, puklen, &left); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Tries left: %i\n", left); + sc_log(card->ctx, "Tries left: %i\n", left); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Invalid 'puk' pass"); } #endif @@ -784,7 +784,7 @@ static int rutoken_set_security_env(sc_card_t *card, senv->algorithm = SC_ALGORITHM_GOST; if (env->key_ref_len != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No or invalid key reference\n"); + sc_log(card->ctx, "No or invalid key reference\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } data[2] = env->key_ref[0]; @@ -1002,7 +1002,7 @@ static int rutoken_cipher_p(sc_card_t *card, const u8 * crgram, size_t crgram_le sc_apdu_t apdu; LOG_FUNC_CALLED(card->ctx); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, ": crgram_len %"SC_FORMAT_LEN_SIZE_T"u; outlen %"SC_FORMAT_LEN_SIZE_T"u", crgram_len, outlen); @@ -1047,7 +1047,7 @@ static int rutoken_cipher_p(sc_card_t *card, const u8 * crgram, size_t crgram_le } } } while (ret == SC_SUCCESS && crgram_len != 0); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "len out cipher %"SC_FORMAT_LEN_SIZE_T"u\n", outlen - outlen_tail); if (ret == SC_SUCCESS) @@ -1259,7 +1259,7 @@ static int rutoken_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) ret = rutoken_format(card, 0x7b); /* APDU: FORMAT END */ break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cmd = %lu", cmd); + sc_log(card->ctx, "cmd = %lu", cmd); ret = SC_ERROR_NOT_SUPPORTED; break; } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index a2054a5135..52d08d48a2 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -725,12 +725,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; #ifdef ENABLE_SM if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Session PIN generation only supported in SM"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } #else - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Session PIN generation only supported in SM"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); #endif @@ -741,7 +741,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.le = 0; if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS || sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Generating session PIN failed"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -751,12 +751,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.resplen); data->pin2.len = apdu.resplen; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Buffer too small for session PIN"); } } } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Session PIN not supported for this PIN (0x%02X)", data->pin_reference); } @@ -792,7 +792,7 @@ static int sc_hsm_read_binary(sc_card_t *card, int r; if (idx > 0xffff) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0xFFFF", idx); + sc_log(ctx, "invalid EF offset: 0x%X > 0xFFFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } @@ -834,7 +834,7 @@ static int sc_hsm_write_ef(sc_card_t *card, int r; if (idx > 0xffff) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0xFFFF", idx); + sc_log(ctx, "invalid EF offset: 0x%X > 0xFFFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } @@ -946,7 +946,7 @@ static int sc_hsm_delete_file(sc_card_t *card, const sc_path_t *path) int r; if ((path->type != SC_PATH_TYPE_FILE_ID) || (path->len != 2)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID"); + sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index f0ed434303..f78fd9da70 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -130,7 +130,7 @@ static int setcos_match_card(sc_card_t *card) card->type = SC_CARD_TYPE_SETCOS_EID_V2_1; else { buf[sizeof(buf) - 1] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SetCOS EID applet %s is not supported", (char *) buf); + sc_log(card->ctx, "SetCOS EID applet %s is not supported", (char *) buf); return 0; } return 1; @@ -473,7 +473,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) break; case SC_AC_CHV: /* pin */ if ((bNumber & 0x7F) == 0 || (bNumber & 0x7F) > 7) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "SetCOS 4.4 PIN refs can only be 1..7\n"); + sc_log(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n"); return SC_ERROR_INVALID_ARGUMENTS; } bCommands_pin[setcos_pin_index_44(pins, sizeof(pins), (int) bNumber)] |= 1 << i; @@ -575,11 +575,11 @@ static int setcos_set_security_env2(sc_card_t *card, card->type == SC_CARD_TYPE_SETCOS_NIDEL || SETCOS_IS_EID_APPLET(card)) { if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "symmetric keyref not supported.\n"); + sc_log(card->ctx, "symmetric keyref not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (se_num > 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "restore security environment not supported.\n"); + sc_log(card->ctx, "restore security environment not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } } @@ -640,13 +640,13 @@ static int setcos_set_security_env2(sc_card_t *card, if (apdu.datalen != 0) { r = sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); goto err; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); goto err; } @@ -674,7 +674,7 @@ static int setcos_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Only RSA algorithm supported.\n"); + sc_log(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } switch (card->type) { @@ -687,7 +687,7 @@ static int setcos_set_security_env(sc_card_t *card, case SC_CARD_TYPE_SETCOS_EID_V2_1: break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card does not support RSA.\n"); + sc_log(card->ctx, "Card does not support RSA.\n"); return SC_ERROR_NOT_SUPPORTED; break; } diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 1b7b5df9ea..d7b865166a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -84,7 +84,7 @@ typedef struct starcos_ex_data_st { #define CHECK_NOT_SUPPORTED_V3_4(card) \ do { \ if ((card)->type == SC_CARD_TYPE_STARCOS_V3_4) { \ - sc_debug((card)->ctx, SC_LOG_DEBUG_NORMAL, \ + sc_log((card)->ctx, \ "not supported for STARCOS 3.4 cards"); \ return SC_ERROR_NOT_SUPPORTED; \ } \ @@ -189,7 +189,7 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "processing FCI bytes\n"); + sc_log(ctx, "processing FCI bytes\n"); if (buflen < 2) return SC_ERROR_INTERNAL; @@ -210,7 +210,7 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -259,9 +259,9 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " type: %s\n", type); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " EF structure: %s\n", structure); } file->magic = SC_FILE_MAGIC; @@ -275,7 +275,7 @@ static int process_fci_v3_4(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "processing %"SC_FORMAT_LEN_SIZE_T"u FCI bytes\n", buflen); if (buflen < 2) @@ -299,7 +299,7 @@ static int process_fci_v3_4(sc_context_t *ctx, sc_file_t *file, if (tag != NULL && taglen > 0 && taglen <= 16) { memcpy(file->name, tag, taglen); file->namelen = taglen; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "filename %s", + sc_log(ctx, "filename %s", sc_dump_hex(file->name, file->namelen)); } return SC_SUCCESS; @@ -311,7 +311,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "processing %"SC_FORMAT_LEN_SIZE_T"u FCP bytes\n", buflen); if (buflen < 2) @@ -326,7 +326,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -334,7 +334,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0xc5, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " bytes in file 2: %d\n", bytes); file->size = bytes; } @@ -388,9 +388,9 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, break; } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " type: %s\n", type); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " EF structure: %s\n", structure); if (taglen >= 2) { if (tag[1] != 0x41 || taglen != 5) { @@ -399,7 +399,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, /* formatted EF */ file->record_length = (tag[2] << 8) + tag[3]; file->record_count = tag[4]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, " rec_len: %d rec_cnt: %d\n\n", file->record_length, file->record_count); } @@ -408,7 +408,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (tag != NULL && taglen >= 2) { file->id = (tag[0] << 8) | tag[1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " file identifier: 0x%02X%02X\n", + sc_log(ctx, " file identifier: 0x%02X%02X\n", tag[0], tag[1]); } @@ -416,7 +416,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, if (tag != NULL && taglen > 0 && taglen <= 16) { memcpy(file->name, tag, taglen); file->namelen = taglen; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " filename %s", + sc_log(ctx, " filename %s", sc_dump_hex(file->name, file->namelen)); } @@ -440,7 +440,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, default: break; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " file status: %s\n", status); + sc_log(ctx, " file status: %s\n", status); } file->magic = SC_FILE_MAGIC; @@ -648,7 +648,7 @@ static int starcos_select_file(sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", @@ -673,7 +673,7 @@ static int starcos_select_file(sc_card_t *card, && card->cache.current_path.len == pathlen && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cache hit\n"); + sc_log(card->ctx, "cache hit\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } else @@ -757,7 +757,7 @@ static int starcos_select_file(sc_card_t *card, { /* done: we are already in the * requested directory */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "cache hit\n"); /* copy file info (if necessary) */ if (file_out) { @@ -984,7 +984,7 @@ static int starcos_create_mf(sc_card_t *card, sc_starcos_create_data *data) CHECK_NOT_SUPPORTED_V3_4(card); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "creating MF \n"); + sc_log(ctx, "creating MF \n"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); apdu.cla |= 0x80; apdu.lc = 19; @@ -1015,9 +1015,9 @@ static int starcos_create_df(sc_card_t *card, sc_starcos_create_data *data) CHECK_NOT_SUPPORTED_V3_4(card); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "creating DF\n"); + sc_log(ctx, "creating DF\n"); /* first step: REGISTER DF */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "calling REGISTER DF\n"); + sc_log(ctx, "calling REGISTER DF\n"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x52, data->data.df.size[0], data->data.df.size[1]); @@ -1030,7 +1030,7 @@ static int starcos_create_df(sc_card_t *card, sc_starcos_create_data *data) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); /* second step: CREATE DF */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "calling CREATE DF\n"); + sc_log(ctx, "calling CREATE DF\n"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x01, 0x00); apdu.cla |= 0x80; @@ -1060,7 +1060,7 @@ static int starcos_create_ef(sc_card_t *card, sc_starcos_create_data *data) CHECK_NOT_SUPPORTED_V3_4(card); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "creating EF\n"); + sc_log(ctx, "creating EF\n"); sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x03,0x00); apdu.cla |= 0x80; @@ -1378,7 +1378,7 @@ static int starcos_set_security_env(sc_card_t *card, break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "not supported for STARCOS 3.4 cards"); return SC_ERROR_NOT_SUPPORTED; } @@ -1718,14 +1718,14 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) const int err_count = sizeof(starcos_errors)/sizeof(starcos_errors[0]); int i; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); if (sw1 == 0x90) return SC_SUCCESS; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verification failed (remaining tries: %d)\n", + sc_log(card->ctx, "Verification failed (remaining tries: %d)\n", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } @@ -1734,7 +1734,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < err_count; i++) if (starcos_errors[i].SWs == ((sw1 << 8) | sw2)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", starcos_errors[i].errorstr); + sc_log(card->ctx, "%s\n", starcos_errors[i].errorstr); return starcos_errors[i].errorno; } diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index ab8513cd2d..8ab1e67951 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -309,7 +309,7 @@ static void parse_sec_attr(sc_card_t *card, op = map_operations (buf[0]); if (op == (unsigned int)-1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Unknown security command byte %02x\n", buf[0]); continue; @@ -397,7 +397,7 @@ static int tcos_select_file(sc_card_t *card, if (r || file_out == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); if (apdu.resplen < 1 || apdu.resp[0] != 0x62){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "received invalid template %02X\n", apdu.resp[0]); + sc_log(ctx, "received invalid template %02X\n", apdu.resp[0]); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED); } @@ -436,7 +436,7 @@ static int tcos_list_files(sc_card_t *card, u8 *buf, size_t buflen) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "List Dir failed"); if (apdu.resplen > buflen) return SC_ERROR_BUFFER_TOO_SMALL; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "got %"SC_FORMAT_LEN_SIZE_T"u %s-FileIDs\n", apdu.resplen / 2, p1 == 1 ? "DF" : "EF"); @@ -457,7 +457,7 @@ static int tcos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } sbuf[0] = path->value[0]; @@ -491,15 +491,15 @@ static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); } if(!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "No Key-Reference in SecEnvironment\n"); else - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Key-Reference %02X (len=%"SC_FORMAT_LEN_SIZE_T"u)\n", env->key_ref[0], env->key_ref_len); /* Key-Reference 0x80 ?? */ default_key= !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || (env->key_ref_len==1 && env->key_ref[0]==0x80); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "TCOS3:%d PKCS1:%d\n", tcos3, !!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)); @@ -520,12 +520,12 @@ static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, r=sc_transmit_apdu(card, &apdu); if (r) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "%s: APDU transmit failed", sc_strerror(r)); return r; } if (apdu.sw1==0x6A && (apdu.sw2==0x81 || apdu.sw2==0x88)) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Detected Signature-Only key\n"); if (env->operation==SC_SEC_OPERATION_SIGN && default_key) return SC_SUCCESS; } @@ -554,7 +554,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal if(((tcos_data *)card->drv_data)->next_sign){ if(datalen>48){ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to be signed is too long (TCOS supports max. 48 bytes)\n"); + sc_log(card->ctx, "Data to be signed is too long (TCOS supports max. 48 bytes)\n"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); @@ -616,7 +616,7 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, data=(tcos_data *)card->drv_data; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "TCOS3:%d PKCS1:%d\n",tcos3, !!(data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1)); diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 9bd4b57254..4af0d5f7d9 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -88,7 +88,7 @@ static int westcos_get_default_key(sc_card_t * card, struct sc_cardctl_default_key *data) { const char *default_key; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_get_default_key:data->method=%d, data->key_ref=%d\n", data->method, data->key_ref); if (data->method != SC_AC_AUT || data->key_ref != 0) @@ -295,17 +295,17 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, sc_context_t *ctx = card->ctx; size_t taglen, len = buflen; const u8 *tag = NULL, *p = buf; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "processing FCI bytes\n"); + sc_log(card->ctx, "processing FCI bytes\n"); tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (tag != NULL && taglen == 2) { file->id = (tag[0] << 8) | tag[1]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " file identifier: 0x%02X%02X\n", tag[0], tag[1]); } tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -313,7 +313,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -324,7 +324,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, unsigned char byte = tag[0]; const char *type; file->shareable = 0; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " shareable: %s\n", (file->shareable) ? "yes" : "no"); file->ef_structure = SC_FILE_EF_UNKNOWN; @@ -351,9 +351,9 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, default: type = "unknown"; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " type: %s\n", type); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, " EF structure: %d\n", file->ef_structure); } } @@ -507,7 +507,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) int buflen; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "westcos_create_file\n"); + sc_log(card->ctx, "westcos_create_file\n"); memset(buf, 0, sizeof(buf)); /* transport key */ @@ -593,7 +593,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) p1 = (file->id) / 256; p2 = (file->id) % 256; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "create file %s, id %X size %"SC_FORMAT_LEN_SIZE_T"u\n", file->path.value, file->id, file->size); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, p1, p2); @@ -614,7 +614,7 @@ static int westcos_delete_file(sc_card_t * card, const sc_path_t * path_in) sc_apdu_t apdu; if (card == NULL || path_in == NULL || path_in->len < 2) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "westcos_delete_file\n"); + sc_log(card->ctx, "westcos_delete_file\n"); if (path_in->len > 2) { r = sc_select_file(card, path_in, NULL); if (r) @@ -639,7 +639,7 @@ static int westcos_list_files(sc_card_t * card, u8 * buf, size_t buflen) sc_apdu_t apdu; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "westcos_list_files\n"); + sc_log(card->ctx, "westcos_list_files\n"); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x34, 0x00, 0x00); apdu.cla = 0x80; apdu.le = buflen; @@ -688,7 +688,7 @@ static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int pad = 0, use_pin_pad = 0, ins, p1 = 0; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_pin_cmd:data->pin_type=%X, data->cmd=%X\n", data->pin_type, data->cmd); if (tries_left) @@ -859,7 +859,7 @@ static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) priv_data_t *priv_data = NULL; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_card_ctl cmd = %lX\n", cmd); priv_data = (priv_data_t *) card->drv_data; switch (cmd) { @@ -1044,7 +1044,7 @@ static int westcos_set_security_env(sc_card_t *card, priv_data_t *priv_data = NULL; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_set_security_env\n"); priv_data = (priv_data_t *) card->drv_data; priv_data->env = *env; @@ -1082,7 +1082,7 @@ static int westcos_restore_security_env(sc_card_t *card, int se_num) { if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_restore_security_env\n"); return 0; } @@ -1105,7 +1105,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "westcos_sign_decipher outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", outlen); @@ -1161,7 +1161,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, alire = min(((keyfile->size) - idx), sizeof(buf)); if (alire <= 0) break; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "idx = %d, alire=%d\n", idx, alire); r = sc_read_binary(card, idx, buf, alire, 0); if (r < 0) @@ -1171,7 +1171,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, } while (1); BIO_set_mem_eof_return(mem, -1); if (!d2i_RSAPrivateKey_bio(mem, &rsa)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "RSA key invalid, %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; @@ -1181,7 +1181,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); if ((size_t)RSA_size(rsa) > outlen) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Buffer too small\n"); + sc_log(card->ctx, "Buffer too small\n"); r = SC_ERROR_OUT_OF_MEMORY; goto out; } @@ -1194,7 +1194,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, print_openssl_error(); #endif - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Decipher error %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; @@ -1210,7 +1210,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, print_openssl_error(); #endif - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Signature error %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; @@ -1219,7 +1219,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, #else if (RSA_sign(nid, data, data_len, out, &outlen, rsa) != 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "RSA_sign error %d \n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5d195dda35..5c3bacdcd8 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1381,7 +1381,7 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo if (0 < expanded_len && expanded_len < sizeof expanded_val) module_path = expanded_val; #endif - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM module '%s' located in '%s'", in_module, module_path); + sc_log(ctx, "SM module '%s' located in '%s'", in_module, module_path); if (module_path && strlen(module_path) > 0) { int sz = strlen(in_module) + strlen(module_path) + 3; module = malloc(sz); diff --git a/src/libopensc/ctbcs.c b/src/libopensc/ctbcs.c index 8b92212242..166358a0b3 100644 --- a/src/libopensc/ctbcs.c +++ b/src/libopensc/ctbcs.c @@ -202,7 +202,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) return r; break; default: - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Unknown PIN command %d", data->cmd); + sc_log(reader->ctx, "Unknown PIN command %d", data->cmd); return SC_ERROR_NOT_SUPPORTED; } @@ -219,7 +219,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) r = sc_transmit_apdu(card, &apdu); s = sc_mutex_destroy(reader->ctx, card->mutex); if (s != SC_SUCCESS) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to destroy mutex\n"); + sc_log(reader->ctx, "unable to destroy mutex\n"); return s; } SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 36139be4c2..1252f6e985 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -58,7 +58,7 @@ int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file) { if(apdu.resplen == 0) /* No more left */ return 0; if (apdu.resplen != 14) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "expected 14 bytes, got %"SC_FORMAT_LEN_SIZE_T"u.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; @@ -80,7 +80,7 @@ int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *da sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x56, 0x00, 0x00); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "READ: Offset: %x\tLength: %"SC_FORMAT_LEN_SIZE_T"u\n", offset, dataLength); memcpy(buffer, objectId.id, 4); @@ -106,7 +106,7 @@ int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *da SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); return dataLength; @@ -169,7 +169,7 @@ int msc_create_object(sc_card_t *card, msc_id objectId, size_t objectSize, unsig } } if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } msc_zero_object(card, objectId, objectSize); @@ -186,7 +186,7 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x54, 0x00, 0x00); apdu.lc = dataLength + 9; if (card->ctx->debug >= 2) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "WRITE: Offset: %x\tLength: %"SC_FORMAT_LEN_SIZE_T"u\n", offset, dataLength); @@ -211,7 +211,7 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons } } if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } return dataLength; @@ -250,7 +250,7 @@ int msc_delete_object(sc_card_t *card, msc_id objectId, int zero) } } if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } return 0; @@ -476,7 +476,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -488,7 +488,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -549,7 +549,7 @@ int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int alg r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -576,7 +576,7 @@ int msc_extract_key(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -682,7 +682,7 @@ int msc_compute_crypt_init(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "init: got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "init: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -732,7 +732,7 @@ int msc_compute_crypt_final( r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "final: got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "final: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); @@ -799,7 +799,7 @@ static int msc_compute_crypt_final_object( r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "final: got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "final: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } } else { @@ -967,7 +967,7 @@ int msc_import_key(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) { if (card->ctx->debug >= 2) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "keyimport: got strange SWs: 0x%02X 0x%02X\n", + sc_log(card->ctx, "keyimport: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } /* this is last ditch cleanup */ diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c index 94f9fe2834..70e4792434 100644 --- a/src/libopensc/p15card-helper.c +++ b/src/libopensc/p15card-helper.c @@ -148,32 +148,32 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { int modulus_len = 0; const prdata* key = get_prkey_by_cert(items, cert); if(!key) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: No key for this certificate"); + sc_log(p15card->card->ctx, "Error: No key for this certificate"); return SC_ERROR_INTERNAL; } if(!d2i_X509(&cert_data, (const u8**)&data, length)) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error converting certificate"); + sc_log(p15card->card->ctx, "Error converting certificate"); return SC_ERROR_INTERNAL; } pkey = X509_get_pubkey(cert_data); if(pkey == NULL) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: no public key associated with the certificate"); + sc_log(p15card->card->ctx, "Error: no public key associated with the certificate"); r = SC_ERROR_INTERNAL; goto err; } certtype = X509_certificate_type(cert_data, pkey); if(! (EVP_PK_RSA & certtype)) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: certificate is not for an RSA key"); + sc_log(p15card->card->ctx, "Error: certificate is not for an RSA key"); r = SC_ERROR_INTERNAL; goto err; } rsa = EVP_PKEY_get0_RSA(pkey); if( rsa == NULL) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: no modulus associated with the certificate"); + sc_log(p15card->card->ctx, "Error: no modulus associated with the certificate"); r = SC_ERROR_INTERNAL; goto err; } diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index f34425a5e0..4010e05b32 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -216,7 +216,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"sc_card_ctl rc=%d",r); + sc_log(card->ctx, "sc_card_ctl rc=%d",r); p15card->tokeninfo->serial_number = strdup("00000000"); } else { sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); @@ -227,7 +227,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* TODO we should not create PIN objects if it is not initialized * (opensc-tool -s 0020000000 returns 0x6A 0x88) */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC adding pins..."); + sc_log(card->ctx, "CAC adding pins..."); for (i = 0; pins[i].id; i++) { struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; @@ -249,7 +249,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) pin_info.tries_left = -1; label = pins[i].label; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC Adding pin %d label=%s",i, label); + sc_log(card->ctx, "CAC Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; @@ -292,7 +292,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) * We need to read the cert, get modulus and keylen * We use those for the pubkey, and priv key objects. */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CAC adding certs, pub and priv keys..."); + sc_log(card->ctx, "CAC adding certs, pub and priv keys..."); r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_INIT_GET_CERT_OBJECTS, &count); LOG_TEST_RET(card->ctx, r, "Can not initiate cert objects."); @@ -345,12 +345,12 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No cert found,i=%d", i); + sc_log(card->ctx, "No cert found,i=%d", i); continue; } cert_info.path.count = cert_der.len; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "cert len=%"SC_FORMAT_LEN_SIZE_T"u, cert_info.path.count=%d r=%d\n", cert_der.len, cert_info.path.count, r); sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "cert", cert_der.value, cert_der.len); @@ -366,7 +366,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* following will find the cached cert in cert_info */ r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); if (r < 0 || cert_out->key == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to read/parse the certificate r=%d",r); + sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) sc_pkcs15_free_certificate(cert_out); continue; @@ -374,7 +374,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " Failed to add cert obj r=%d",r); + sc_log(card->ctx, " Failed to add cert obj r=%d",r); sc_pkcs15_free_certificate(cert_out); continue; } @@ -411,22 +411,22 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) usage = 0xd9ULL; /* basic default usage */ } cac_map_usage(usage, cert_out->key->algorithm, &pubkey_info.usage, &prkey_info.usage, 1); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n", + sc_log(card->ctx, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n", sc_dump_hex(cert_info.id.value, cert_info.id.len), usage, pubkey_info.usage, prkey_info.usage); if (cert_out->key->algorithm != SC_ALGORITHM_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"unsupported key.algorithm %d", cert_out->key->algorithm); + sc_log(card->ctx, "unsupported key.algorithm %d", cert_out->key->algorithm); sc_pkcs15_free_certificate(cert_out); continue; } else { pubkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; prkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "adding rsa public key r=%d usage=%x",r, pubkey_info.usage); + sc_log(card->ctx, "adding rsa public key r=%d usage=%x",r, pubkey_info.usage); if (r < 0) goto fail; r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); + sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); } cert_out->key = NULL; diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index 16593931b4..62be8d0134 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -212,7 +212,7 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card, c = fwrite(buf, 1, bufsize, f); fclose(f); if (c != bufsize) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "fwrite() wrote only %"SC_FORMAT_LEN_SIZE_T"u bytes", c); unlink(fname); diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 09618fe56d..58826ed8c4 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -506,7 +506,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } /* set pins */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Coolkey adding pins..."); + sc_log(card->ctx, "Coolkey adding pins..."); for (i = 0; pins[i].id; i++) { struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; @@ -528,7 +528,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) pin_info.tries_left = -1; label = pins[i].label? pins[i].label : p15card->tokeninfo->label; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Coolkey Adding pin %d label=%s",i, label); + sc_log(card->ctx, "Coolkey Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index 97a6734745..e9a442dc45 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -114,7 +114,7 @@ static int my_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data * data, memcpy(newpin,data->pin1.data, (size_t)data->pin1.len); newpin[data->pin1.len] = 0x00; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "pin len=%d", data->pin1.len); + sc_log(card->ctx, "pin len=%d", data->pin1.len); saved_data = data->pin1.data; saved_len = data->pin1.len; @@ -253,7 +253,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) sc_file_free(file); file = NULL; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "GemSafe file found, id=%d",dfpath); + sc_log(card->ctx, "GemSafe file found, id=%d",dfpath); /* There may be more then one key in the directory. */ /* we need to find them so we can associate them with the */ @@ -280,14 +280,14 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) case 0x10: kinfo[num_keyinfo].modulus_len = 768 / 8; break; case 0x11: kinfo[num_keyinfo].modulus_len = 1024 / 8; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported modulus length"); + sc_log(card->ctx, "Unsupported modulus length"); continue; } kinfo[num_keyinfo].fileid = i; sc_pkcs15_format_id("", &kinfo[num_keyinfo].id); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"reading modulus"); + sc_log(card->ctx, "reading modulus"); r = sc_read_record(card, 2, modulus_buf, kinfo[num_keyinfo].modulus_len+1, SC_RECORD_BY_REC_NR); if (r < 0) @@ -381,7 +381,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) idx2 = idx2 + idxlen; } cert_info.value.len = seq_len1 + 4; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Found cert at offset %d", idx1); + sc_log(card->ctx, "Found cert at offset %d", idx1); cert_info.value.value = (unsigned char *) malloc(cert_info.value.len); if (!cert_info.value.value) @@ -416,7 +416,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) memcmp(cert_out->key->u.rsa.modulus.data, &kinfo[j].modulus, cert_out->key->u.rsa.modulus.len) == 0) { memcpy(&kinfo[j].id, &cert_info.id, sizeof(sc_pkcs15_id_t)); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found match"); + sc_log(card->ctx, "found match"); } } sc_pkcs15_free_certificate(cert_out); @@ -489,7 +489,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) for (j = 0; j < num_keyinfo; j++) { if (sc_pkcs15_compare_id(&kinfo[j].id, &prkey_info.id)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found key in file %d for id %s", + sc_log(card->ctx, "found key in file %d for id %s", kinfo[j].fileid, prkeys[i].id); prkey_info.path.value[0] = kinfo[j].fileid >> 8; prkey_info.path.value[1] = kinfo[j].fileid & 0xff; @@ -515,7 +515,7 @@ int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *ai sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Entering %s", __FUNCTION__); + sc_log(ctx, "Entering %s", __FUNCTION__); if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) return sc_pkcs15emu_gemsafeGPK_init(p15card); diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 3b220f7a5b..33c4f5d0c0 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -411,7 +411,7 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) */ if ( p15card->card->flags & 0x0F) { key_ref = p15card->card->flags & 0x0F; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Overriding key_ref %d with %d\n", gemsafe_prkeys[i].ref, key_ref); } else diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index a01263c5f9..263037d0ec 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -50,7 +50,7 @@ static int sc_pkcs15emu_gids_add_prkey(sc_pkcs15_card_t * p15card, sc_cardctl_gi sc_pkcs15_object_t cert_obj; int r; char ch_tmp[10]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Got args: containerIndex=%"SC_FORMAT_LEN_SIZE_T"x\n", container->containernum); @@ -100,7 +100,7 @@ static int sc_pkcs15emu_gids_add_prkey(sc_pkcs15_card_t * p15card, sc_cardctl_gi r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); LOG_TEST_RET(card->ctx, r, "Could not add certificate"); } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No certificate found"); + sc_log(card->ctx, "No certificate found"); } return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index 71393cd12b..6cb00d36b8 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -495,7 +495,7 @@ static int loadCertificate(sc_pkcs15_card_t * p15card, int i, sc_read_binary(card, 4, compCert, compLen, 0); if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Zlib error: %d", r); + sc_log(p15card->card->ctx, "Zlib error: %d", r); return SC_ERROR_INTERNAL; } @@ -579,7 +579,7 @@ static int infocamere_1400_init(sc_pkcs15_card_t * p15card) if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "%s", sc_strerror(r)); + sc_log(p15card->card->ctx, "%s", sc_strerror(r)); return SC_ERROR_WRONG_CARD; } diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index f0f3959092..c99f6cb84d 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -212,7 +212,7 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, SC_FUNC_CALLED(p15card->card->ctx, 1); if(type != SC_PKCS15_TYPE_CERT_X509) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Cannot add a certificate of a type other than X.509"); return 1; } @@ -314,7 +314,7 @@ static int itacns_add_prkey(sc_pkcs15_card_t *p15card, SC_FUNC_CALLED(p15card->card->ctx, 1); if(type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Cannot add a private key of a type other than RSA"); return 1; } @@ -527,7 +527,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32); if(rv < 0) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Data enumeration failed"); return SC_SUCCESS; } @@ -539,7 +539,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) } if(i>=32) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Could not find EF_DatiPersonali: " "keeping generic card name"); return SC_SUCCESS; @@ -547,7 +547,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) rv = sc_pkcs15_read_data_object(p15card, cinfo, &p15_personaldata); if (rv) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Could not read EF_DatiPersonali: " "keeping generic card name"); return SC_SUCCESS; @@ -557,7 +557,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) char fullname[160]; if(get_name_from_EF_DatiPersonali(p15_personaldata->data, fullname, sizeof(fullname))) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Could not parse EF_DatiPersonali: " "keeping generic card name"); sc_pkcs15_free_data_object(p15_personaldata); @@ -663,7 +663,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, /* Certificate */ if (!cert_path) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "We cannot use keys without a matching certificate"); return SC_ERROR_NOT_SUPPORTED; } @@ -673,7 +673,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, if (r == SC_ERROR_FILE_NOT_FOUND) return 0; if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Could not find certificate for %s", label); return r; } @@ -725,7 +725,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_DECRYPT; } #else /* ENABLE_OPENSSL */ - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Extended certificate info retrieved without OpenSSL. " "How is this possible?"); return SC_ERROR_INTERNAL; diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index f5fd00b9b9..91226f4b38 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -211,7 +211,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if ((r = read_file(card, "006E:0073:00C4", c4data, sizeof(c4data))) < 0) goto failed; if (r != 7) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "CHV status bytes have unexpected length (expected 7, got %d)\n", r); return SC_ERROR_OBJECT_NOT_VALID; } @@ -259,7 +259,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if ((r = read_file(card, "006E:0073:00C5", c5data, sizeof(c5data))) < 0) goto failed; if (r != 60) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "finger print bytes have unexpected length (expected 60, got %d)\n", r); return SC_ERROR_OBJECT_NOT_VALID; } @@ -279,7 +279,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if ((r = read_file(card, path_template, cxdata, sizeof(cxdata))) < 0) goto failed; if (r != 6) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Key info bytes have unexpected length (expected 6, got %d)\n", r); + sc_log(ctx, "Key info bytes have unexpected length (expected 6, got %d)\n", r); return SC_ERROR_INTERNAL; } @@ -323,7 +323,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if ((r = read_file(card, path_template, cxdata, sizeof(cxdata))) < 0) goto failed; if (r != 6) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Key info bytes have unexpected length (expected 6, got %d)\n", r); + sc_log(ctx, "Key info bytes have unexpected length (expected 6, got %d)\n", r); return SC_ERROR_INTERNAL; } @@ -385,7 +385,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) failed: if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Failed to initialize OpenPGP emulation: %s\n", sc_strerror(r)); } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 1401ea4df1..efd4407d0e 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -634,7 +634,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"sc_card_ctl rc=%d",r); + sc_log(card->ctx, "sc_card_ctl rc=%d",r); p15card->tokeninfo->serial_number = strdup("00000000"); } else { sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); @@ -645,7 +645,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) follows_nist_fascn = 1; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding objects..."); + sc_log(card->ctx, "PIV-II adding objects..."); /* set other objects */ for (i = 0; objects[i].label; i++) { @@ -705,7 +705,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) */ /* set certs */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding certs..."); + sc_log(card->ctx, "PIV-II adding certs..."); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; @@ -736,14 +736,14 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) /* See if the cert might be present or not. */ r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path); if (r == 1) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cert can not be present,i=%d", i); + sc_log(card->ctx, "Cert can not be present,i=%d", i); continue; } r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len); if (r) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No cert found,i=%d", i); + sc_log(card->ctx, "No cert found,i=%d", i); continue; } @@ -760,7 +760,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) /* following will find the cached cert in cert_info */ r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); if (r < 0 || cert_out->key == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to read/parse the certificate r=%d",r); + sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) sc_pkcs15_free_certificate(cert_out); continue; @@ -909,7 +909,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key.algorithm %d", cert_out->key->algorithm); + sc_log(card->ctx, "Unsupported key.algorithm %d", cert_out->key->algorithm); ckis[i].pubkey_len = 0; /* set some value for now */ } ckis[i].pubkey_from_cert = cert_out->key; @@ -918,13 +918,13 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " Failed to add cert obj r=%d",r); + sc_log(card->ctx, " Failed to add cert obj r=%d",r); continue; } } /* set pins */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding pins..."); + sc_log(card->ctx, "PIV-II adding pins..."); for (i = 0; pins[i].label; i++) { struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; @@ -955,7 +955,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; label = "Global PIN"; } -sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); +sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; if (i == 0 && pin_info.attrs.pin.reference == 0x80) { @@ -979,7 +979,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); * gets the pubkey, but it can not be read from the card * at a later time. The piv-tool can stash pubkey in file */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding pub keys..."); + sc_log(card->ctx, "PIV-II adding pub keys..."); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_object pubkey_obj; @@ -1012,7 +1012,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); if (ckis[i].cert_found == 0 ) { /* no cert found */ char * filename = NULL; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"No cert for this pub key i=%d",i); + sc_log(card->ctx, "No cert for this pub key i=%d",i); /* * If we used the piv-tool to generate a key, @@ -1023,18 +1023,18 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"DEE look for env %s", + sc_log(card->ctx, "DEE look for env %s", pubkeys[i].getenvname?pubkeys[i].getenvname:"NULL"); if (pubkeys[i].getenvname == NULL) continue; filename = getenv(pubkeys[i].getenvname); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"DEE look for file %s", filename?filename:"NULL"); + sc_log(card->ctx, "DEE look for file %s", filename?filename:"NULL"); if (filename == NULL) continue; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Adding pubkey from file %s",filename); + sc_log(card->ctx, "Adding pubkey from file %s",filename); r = sc_pkcs15_pubkey_from_spki_file(card->ctx, filename, &p15_key); if (r < 0) @@ -1069,7 +1069,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); ckis[i].pubkey_from_file = 1; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Unsupported key_alg %d",p15_key->algorithm); + sc_log(card->ctx, "Unsupported key_alg %d",p15_key->algorithm); continue; } pubkey_obj.emulated = p15_key; @@ -1082,7 +1082,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); pubkey_obj.emulated = ckis[i].pubkey_from_cert; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"adding pubkey for %d keyalg=%d",i, ckis[i].key_alg); + sc_log(card->ctx, "adding pubkey for %d keyalg=%d",i, ckis[i].key_alg); switch (ckis[i].key_alg) { case SC_ALGORITHM_RSA: if (ckis[i].cert_keyUsage_present) { @@ -1115,16 +1115,16 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); ckis[i].pubkey_found = 1; break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"key_alg %d not supported", ckis[i].key_alg); + sc_log(card->ctx, "key_alg %d not supported", ckis[i].key_alg); continue; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"USAGE: cert_keyUsage_present:%d usage:0x%8.8x", + sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present ,pubkey_info.usage); } /* set private keys */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "PIV-II adding private keys..."); + sc_log(card->ctx, "PIV-II adding private keys..."); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { struct sc_pkcs15_prkey_info prkey_info; struct sc_pkcs15_object prkey_obj; @@ -1158,7 +1158,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); if (ckis[i].pubkey_from_file == 1) { prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Adding SC_PKCS15_PRKEY_USAGE_SIGN"); + sc_log(card->ctx, "Adding SC_PKCS15_PRKEY_USAGE_SIGN"); } switch (ckis[i].key_alg) { @@ -1186,15 +1186,15 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label); prkey_info.usage |= prkeys[i].usage_ec; } prkey_info.field_length = ckis[i].pubkey_len; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE added key_alg %2.2x prkey_obj.flags %8.8x", + sc_log(card->ctx, "DEE added key_alg %2.2x prkey_obj.flags %8.8x", ckis[i].key_alg, prkey_obj.flags); r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); break; default: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key_alg %d", ckis[i].key_alg); + sc_log(card->ctx, "Unsupported key_alg %d", ckis[i].key_alg); r = 0; /* we just skip this one */ } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present ,prkey_info.usage); + sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present ,prkey_info.usage); if (r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); } diff --git a/src/libopensc/pkcs15-postecert.c b/src/libopensc/pkcs15-postecert.c index 14a8cc3be7..04fcfb3484 100644 --- a/src/libopensc/pkcs15-postecert.c +++ b/src/libopensc/pkcs15-postecert.c @@ -338,7 +338,7 @@ static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card) return 0; failed: - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Failed to initialize Postecert and Cnipa emulation: %s\n", sc_strerror(r)); return r; diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index 8792cf1566..70d83ed861 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -230,7 +230,7 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) | (((unsigned int) info1[info1_len-2]) << 8) | (((unsigned int) info1[info1_len-3]) << 16) | (((unsigned int) info1[info1_len-4]) << 24); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "found %d private keys\n", (int)key_num); /* set p1 to the address of the first key descriptor */ offset = info1_len - 4 - key_num * 2; diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 547de12aee..c716bf735d 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -63,17 +63,17 @@ static int insert_cert( cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0; if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Select(%s) failed\n", path); return 1; } if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "ReadBinary(%s) failed\n", path); return 2; } if(cert[0]!=0x30 || cert[1]!=0x82){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); return 3; } @@ -89,10 +89,10 @@ static int insert_cert( r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if(r!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path); + sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path); return 4; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count); + sc_log(ctx, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count); return 0; } @@ -133,12 +133,12 @@ static int insert_key( if(prkey_info.path.len>=2) prkey_info.path.len-=2; sc_append_file_id(&prkey_info.path, 0x5349); if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Select(%s) failed\n", sc_print_path(&prkey_info.path)); return 1; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Searching for Key-Ref %02X\n", key_reference); while((r=sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR))>0){ int found=0; @@ -149,7 +149,7 @@ static int insert_key( if(found) break; } if(r<=0){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No EF_KEYD-Record found\n"); + sc_log(ctx, "No EF_KEYD-Record found\n"); return 1; } for(i=0;iprop_attr || f->prop_attr_len < 2){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Select(%s) failed\n", sc_print_path(&prkey_info.path)); return 1; @@ -174,10 +174,10 @@ static int insert_key( r=sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if(r!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", path); + sc_log(ctx, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", path); return 4; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "%s: OK%s%s\n", path, can_sign ? ", Sign" : "", can_crypt ? ", Crypt" : ""); + sc_log(ctx, "%s: OK%s%s\n", path, can_sign ? ", Sign" : "", can_crypt ? ", Crypt" : ""); return 0; } @@ -224,12 +224,12 @@ static int insert_pin( if(pin_info.path.len>=2) pin_info.path.len-=2; sc_append_file_id(&pin_info.path, 0x5049); if(sc_select_file(card, &pin_info.path, NULL)!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Select(%s) failed\n", sc_print_path(&pin_info.path)); return 1; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Searching for PIN-Ref %02X\n", pin_reference); while((r=sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR))>0){ int found=0, fbz=-1; @@ -242,13 +242,13 @@ static int insert_pin( if(found) break; } if(r<=0){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No EF_PWDD-Record found\n"); + sc_log(ctx, "No EF_PWDD-Record found\n"); return 1; } } else { if(sc_select_file(card, &pin_info.path, &f)!=SC_SUCCESS || !f->prop_attr || f->prop_attr_len < 4){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"Select(%s) failed\n", path); + sc_log(ctx, "Select(%s) failed\n", path); return 1; } pin_info.tries_left=f->prop_attr[3]; @@ -257,10 +257,10 @@ static int insert_pin( r=sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if(r!=SC_SUCCESS){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "sc_pkcs15emu_add_pin_obj(%s) failed\n", path); + sc_log(ctx, "sc_pkcs15emu_add_pin_obj(%s) failed\n", path); return 4; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "%s: OK, FBZ=%d\n", path, pin_info.tries_left); + sc_log(ctx, "%s: OK, FBZ=%d\n", path, pin_info.tries_left); return 0; } @@ -508,7 +508,7 @@ int sc_pkcs15emu_tcos_init_ex( /* get the card serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); if (r < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to get ICCSN\n"); + sc_log(ctx, "unable to get ICCSN\n"); return SC_ERROR_WRONG_CARD; } sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 490e57399d..389a01a181 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -237,7 +237,7 @@ static int westcos_detect_card(sc_pkcs15_card_t * p15card) sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; const char *name = "WESTCOS"; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "westcos_detect_card (%s)", card->name); if (strncmp(card->name, name, strlen(name))) return SC_ERROR_WRONG_CARD; @@ -251,7 +251,7 @@ int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t * p15card, int r; sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "sc_pkcs15_init_func_ex westcos\n"); if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) return sc_pkcs15emu_westcos_init(p15card); diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index 4f2d79b6a9..2697d270f7 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -229,21 +229,21 @@ openct_reader_connect(sc_reader_t *reader) ct_reader_disconnect(data->h); if (!(data->h = ct_reader_connect(data->num))) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "ct_reader_connect socket failed\n"); + sc_log(reader->ctx, "ct_reader_connect socket failed\n"); return SC_ERROR_CARD_NOT_PRESENT; } rc = ct_card_request(data->h, data->slot, 0, NULL, reader->atr.value, sizeof(reader->atr.value)); if (rc < 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "openct_reader_connect read failed: %s\n", ct_strerror(rc)); return SC_ERROR_CARD_NOT_PRESENT; } if (rc == 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "openct_reader_connect received no data\n"); + sc_log(reader->ctx, "openct_reader_connect received no data\n"); return SC_ERROR_READER; } @@ -328,7 +328,7 @@ static int openct_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to transmit"); + sc_log(reader->ctx, "unable to transmit"); goto out; } sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index ac7ab2f094..da7d704258 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -528,7 +528,7 @@ static void initialize_uid(sc_reader_t *reader) sc_debug_hex(reader->ctx, SC_LOG_DEBUG_NORMAL, "UID", reader->uid.value, reader->uid.len); } else { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to get UID"); + sc_log(reader->ctx, "unable to get UID"); } } } diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index ed2eacb142..009e62a7dc 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -664,7 +664,7 @@ static int escape_perform_verify(struct sc_reader *reader, r = escape_pin_cmd_to_buf(reader->ctx, data, (unsigned char **) &apdu.data, &apdu.datalen); if (r < 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error encoding PC_to_RDR_Secure"); goto err; } @@ -672,13 +672,13 @@ static int escape_perform_verify(struct sc_reader *reader, r = reader->ops->transmit(reader, &apdu); if (r < 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error performing PC_to_RDR_Secure"); goto err; } if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error decoding PC_to_RDR_Secure"); r = SC_ERROR_NOT_SUPPORTED; goto err; @@ -723,7 +723,7 @@ static int escape_perform_pace(struct sc_reader *reader, r = escape_pace_input_to_buf(reader->ctx, input, (unsigned char **) &apdu.data, &apdu.datalen); if (r < 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error encoding EstablishPACEChannel"); goto err; } @@ -731,13 +731,13 @@ static int escape_perform_pace(struct sc_reader *reader, r = reader->ops->transmit(reader, &apdu); if (r < 0) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error performing EstablishPACEChannel"); goto err; } if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Error decoding EstablishPACEChannel"); r = SC_ERROR_NOT_SUPPORTED; goto err; @@ -945,7 +945,7 @@ void sc_detect_escape_cmds(sc_reader_t *reader) && !(reader->capabilities & SC_READER_CAP_PIN_PAD)) { ((struct sc_reader_operations *) reader->ops)->perform_verify = escape_perform_verify; - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Added escape command wrappers for PIN verification/modification to '%s'", reader->name); } @@ -953,14 +953,14 @@ void sc_detect_escape_cmds(sc_reader_t *reader) && !(reader->capabilities & SC_READER_CAP_PACE_GENERIC)) { ((struct sc_reader_operations *) reader->ops)->perform_pace = escape_perform_pace; - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "Added escape command wrappers for PACE to '%s'", reader->name); } reader->capabilities |= capabilities; } else { error++; - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "%s does not support escape commands", reader->name); } @@ -997,7 +997,7 @@ void sc_detect_escape_cmds(sc_reader_t *reader) } if (error && reader) { - sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(reader->ctx, "%d escape command%s failed, need to reset the card", error, error == 1 ? "" : "s"); if (reader->ops && reader->ops->transmit) { diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index f6d17248e2..bc4986789e 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -238,10 +238,10 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, break; } if (r == SC_ERROR_NOT_SUPPORTED) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unsupported PIN operation (%d)", + sc_log(card->ctx, "unsupported PIN operation (%d)", data->cmd); } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Use of pin pad not supported by card driver"); + sc_log(card->ctx, "Use of pin pad not supported by card driver"); r = SC_ERROR_NOT_SUPPORTED; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index a130aedb43..b70ea54fd6 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -206,7 +206,7 @@ static int asepcos_pinid_to_akn(sc_card_t *card, int fileid, int *akn) if (r != SC_SUCCESS) return r; if (nfile->prop_attr == NULL || nfile->prop_attr_len != 11) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to determine AKN"); + sc_log(card->ctx, "unable to determine AKN"); sc_file_free(nfile); return SC_ERROR_INTERNAL; } @@ -234,7 +234,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, *p++ = pinid & 0xff; /* pin length */ if (pinlen < 4 || pinlen > 16) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid PIN length"); + sc_log(card->ctx, "invalid PIN length"); return SC_ERROR_INVALID_ARGUMENTS; } *p++ = 0x00; @@ -296,7 +296,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, r = sc_create_file(card, nfile); sc_file_free(nfile); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create PIN file"); + sc_log(card->ctx, "unable to create PIN file"); return r; } /* get AKN of the newly created PIN */ @@ -367,7 +367,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_CREATE); sc_file_free(tfile); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create PIN file, insufficient rights"); + sc_log(card->ctx, "unable to create PIN file, insufficient rights"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -384,7 +384,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (r == SC_SUCCESS) pid += 2; else if (r != SC_ERROR_FILE_NOT_FOUND) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error selecting PIN file"); + sc_log(card->ctx, "error selecting PIN file"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } } while (r != SC_ERROR_FILE_NOT_FOUND); @@ -422,7 +422,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, * first USER PIN has been set we can tighten the ACLs of * the application DF. */ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "finalizing application DF"); + sc_log(card->ctx, "finalizing application DF"); r = sc_select_file(card, &df->path, NULL); if (r != SC_SUCCESS) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -432,7 +432,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_SET_SATTR, df); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to change the security attributes"); + sc_log(card->ctx, "unable to change the security attributes"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } /* finally activate the application DF (fix ACLs) */ @@ -445,7 +445,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, st.is_ef = 0; r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_ACTIVATE_FILE, &st); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to activate DF"); + sc_log(card->ctx, "unable to activate DF"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } } @@ -477,14 +477,14 @@ static int asepcos_do_authenticate(sc_profile_t *profile, sc_pkcs15_card_t *p15c sc_file_t *prkey = NULL; r = sc_profile_get_file_by_path(profile, path, &prkey); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to find file in profile"); + sc_log(p15card->card->ctx, "unable to find file in profile"); return r; } r = sc_pkcs15init_authenticate(profile, p15card, prkey, op); sc_file_free(prkey); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to authenticate"); + sc_log(p15card->card->ctx, "unable to authenticate"); return r; } return SC_SUCCESS; @@ -545,7 +545,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid, nfile->id = fileid & 0xffff; r = sc_file_set_prop_attr(nfile, buf, p - buf); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to set key prop. attributes"); + sc_log(card->ctx, "unable to set key prop. attributes"); sc_file_free(nfile); return r; } @@ -553,7 +553,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid, r = sc_create_file(card, nfile); sc_file_free(nfile); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create key file"); + sc_log(card->ctx, "unable to create key file"); return r; } return r; @@ -580,7 +580,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to determine reference for the PIN"); + sc_log(p15card->card->ctx, "unable to determine reference for the PIN"); return r; } @@ -589,7 +589,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, st.akn = auth_info->attrs.pin.reference; r = sc_card_ctl(p15card->card, SC_CARDCTL_ASEPCOS_AKN2FILEID, &st); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to determine file id of the PIN"); + sc_log(p15card->card->ctx, "unable to determine file id of the PIN"); return r; } afileid = st.fileid; @@ -640,7 +640,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = asepcos_do_create_key(p15card->card, kinfo->modulus_length, fileid, buf, p - buf); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to create private key file"); + sc_log(p15card->card->ctx, "unable to create private key file"); return r; } @@ -674,7 +674,7 @@ static int asepcos_do_store_rsa_key(sc_pkcs15_card_t *p15card, sc_profile_t *pro tpath.value[1] = kinfo->path.value[kinfo->path.len-1]; r = sc_select_file(p15card->card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to select rsa key file"); + sc_log(p15card->card->ctx, "unable to select rsa key file"); return r; } @@ -705,7 +705,7 @@ static int asepcos_do_store_rsa_key(sc_pkcs15_card_t *p15card, sc_profile_t *pro r = sc_card_ctl(p15card->card, SC_CARDCTL_ASEPCOS_CHANGE_KEY, &ckdata); if (r != SC_SUCCESS) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "unable to change key data"); + sc_log(p15card->card->ctx, "unable to change key data"); return r; } @@ -725,7 +725,7 @@ static int asepcos_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported"); + sc_log(p15card->card->ctx, "only RSA is currently supported"); return SC_ERROR_NOT_SUPPORTED; } @@ -763,7 +763,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card tpath.value[1] = kinfo->path.value[kinfo->path.len-1]; r = sc_select_file(card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to select rsa key file"); + sc_log(card->ctx, "unable to select rsa key file"); return r; } @@ -782,7 +782,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "error creating key"); + sc_log(card->ctx, "error creating key"); return SC_ERROR_INTERNAL; } diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 88909beea9..d61c21e0f3 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -263,26 +263,26 @@ cardos_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int algorithm = 0, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS supports RSA keys only."); + sc_log(ctx, "CardOS supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &algorithm) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS does not support keys " + sc_log(ctx, "CardOS does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } r = sc_select_file(p15card->card, &key_info->path, &file); if (r) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: cannot select parent DF"); + sc_log(ctx, "Failed to store key: cannot select parent DF"); return r; } r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); sc_file_free(file); if (r) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: 'UPDATE' authentication failed"); + sc_log(ctx, "Failed to store key: 'UPDATE' authentication failed"); return r; } @@ -337,7 +337,7 @@ cardos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, rsa_max_size = (sc_card_find_rsa_alg(p15card->card, 2048) != NULL) ? 2048 : 1024; keybits = key_info->modulus_length & ~7UL; if (keybits > rsa_max_size) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key, max size is %lu", + sc_log(ctx, "Unable to generate key, max size is %lu", (unsigned long) rsa_max_size); return SC_ERROR_INVALID_ARGUMENTS; } @@ -346,13 +346,13 @@ cardos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, use_ext_rsa = 1; if (cardos_key_algorithm(key_info->usage, keybits, &algorithm) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS does not support keys " + sc_log(ctx, "CardOS does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } if (sc_profile_get_file(profile, "tempfile", &temp) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define temporary file " + sc_log(ctx, "Profile doesn't define temporary file " "for key generation."); return SC_ERROR_NOT_SUPPORTED; } @@ -481,7 +481,7 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card, * "no padding required". */ maxlen = MIN(profile->pin_maxlen, sizeof(pinpadded)); if (pin_len > maxlen) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "invalid pin length: %"SC_FORMAT_LEN_SIZE_T"u (max %u)\n", pin_len, maxlen); return SC_ERROR_INVALID_ARGUMENTS; @@ -761,13 +761,13 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len, return SC_ERROR_INVALID_ARGUMENTS; data = sc_asn1_find_tag(card->ctx, data, len, 0x7f49, &ilen); if (data == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid public key data: missing tag"); + sc_log(card->ctx, "invalid public key data: missing tag"); return SC_ERROR_INTERNAL; } p = sc_asn1_find_tag(card->ctx, data, ilen, 0x81, &tlen); if (p == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid public key data: missing modulus"); + sc_log(card->ctx, "invalid public key data: missing modulus"); return SC_ERROR_INTERNAL; } pubkey->u.rsa.modulus.len = tlen; @@ -778,7 +778,7 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len, p = sc_asn1_find_tag(card->ctx, data, ilen, 0x82, &tlen); if (p == NULL) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid public key data: missing exponent"); + sc_log(card->ctx, "invalid public key data: missing exponent"); return SC_ERROR_INTERNAL; } pubkey->u.rsa.exponent.len = tlen; diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index d732c87bc5..7d347426bc 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -273,7 +273,7 @@ cflex_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_obj int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys."); + sc_log(p15card->card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -289,7 +289,7 @@ cflex_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_obj case 1024: size = 326; break; case 2048: size = 646; break; default: - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", key_info->modulus_length); r = SC_ERROR_INVALID_ARGUMENTS; @@ -331,7 +331,7 @@ cflex_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys."); + sc_log(card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* Get the public and private key file */ @@ -391,7 +391,7 @@ cflex_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys."); + sc_log(card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* Get the public and private key file */ @@ -654,7 +654,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot find private key file info " + sc_log(card->ctx, "Cannot find private key file info " "in profile (path=%s).", pbuf); return r; } @@ -664,7 +664,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card, sc_append_file_id(&path, 0x1012); r = sc_profile_get_file_by_path(profile, &path, pukf); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot find public key file info in profile."); + sc_log(card->ctx, "Cannot find public key file info in profile."); sc_file_free(*prkf); return r; } diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 468bd6a5a1..a115a01d95 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -214,7 +214,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card for(i = 0; create_efs[i]; ++i) { if (sc_profile_get_file(profile, create_efs[i], &file)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Inconsistent profile: cannot find %s", create_efs[i]); + sc_log(card->ctx, "Inconsistent profile: cannot find %s", create_efs[i]); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INCONSISTENT_PROFILE); } @@ -476,7 +476,7 @@ static int entersafe_sanity_check(sc_profile_t *profile, sc_pkcs15_card_t *p15ca SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Check and if needed update PinFlags"); + sc_log(ctx, "Check and if needed update PinFlags"); rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PINs"); nn = rv; @@ -493,7 +493,7 @@ static int entersafe_sanity_check(sc_profile_t *profile, sc_pkcs15_card_t *p15ca if (pin_attrs->reference == profile_auth.attrs.pin.reference && pin_attrs->flags != profile_auth.attrs.pin.flags) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Set flags of '%s'(flags:%X,ref:%i,id:%s) to %X", objs[ii]->label, + sc_log(ctx, "Set flags of '%s'(flags:%X,ref:%i,id:%s) to %X", objs[ii]->label, pin_attrs->flags, pin_attrs->reference, sc_pkcs15_print_id(&ainfo->auth_id), profile_auth.attrs.pin.flags); pin_attrs->flags = profile_auth.attrs.pin.flags; diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 60a1ddca76..815c7dc99c 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -172,7 +172,7 @@ static int epass2003_pkcs15_create_dir(struct sc_profile *profile, for (i = 0; create_efs[i]; ++i) { if (sc_profile_get_file(profile, create_efs[i], &file)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Inconsistent profile: cannot find %s", create_efs[i]); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, @@ -312,7 +312,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, unsigned int structure = 0xFFFFFFFF; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "type %X; num %i\n", type, + sc_log(card->ctx, "type %X; num %i\n", type, num); while (1) { switch (type) { @@ -360,7 +360,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, * the generic class (SC_PKCS15_TYPE_CERT) */ if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "File type %X not supported by card driver", type); return SC_ERROR_INVALID_ARGUMENTS; @@ -368,10 +368,10 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, type &= SC_PKCS15_TYPE_CLASS_MASK; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "template %s; num %i\n", + sc_log(card->ctx, "template %s; num %i\n", _template, num); if (sc_profile_get_file(profile, _template, &file) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Profile doesn't define %s template '%s'\n", desc, _template); return SC_ERROR_NOT_SUPPORTED; @@ -384,11 +384,11 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = structure; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "file size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X, path_len %"SC_FORMAT_LEN_SIZE_T"u\n", file->size, file->type, file->ef_structure, file->id, file->path.len); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "file path: %s", + sc_log(card->ctx, "file path: %s", sc_print_path(&(file->path))); *out = file; @@ -424,7 +424,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "index %"SC_FORMAT_LEN_SIZE_T"u; id %s\n", idx, sc_pkcs15_print_id(&key_info->id)); if (key->algorithm != SC_ALGORITHM_RSA @@ -433,7 +433,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, SC_ERROR_NOT_SUPPORTED, "store key: only support RSA"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "store key: with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); @@ -444,9 +444,9 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "create key: failed to allocate new key object"); file->size = keybits; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key path: %s", + sc_log(card->ctx, "private key path: %s", sc_print_path(&(file->path))); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key_info path: %s", + sc_log(card->ctx, "private key_info path: %s", sc_print_path(&(key_info->path))); sc_delete_file(p15card->card, &file->path); /* create */ @@ -454,7 +454,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "create key: failed to create key file"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "index %"SC_FORMAT_LEN_SIZE_T"u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n", idx, keybits); if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) { @@ -522,9 +522,9 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "create key: failed to allocate new key object"); file->size = keybits; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key path: %s", + sc_log(card->ctx, "private key path: %s", sc_print_path(&file->path)); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "private key_info path: %s", + sc_log(card->ctx, "private key_info path: %s", sc_print_path(&(key_info->path))); r = sc_pkcs15init_authenticate(profile, p15card, file, @@ -538,7 +538,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "create key: failed to create key file"); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "index %"SC_FORMAT_LEN_SIZE_T"u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n", idx, keybits); if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) { @@ -585,7 +585,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, } if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "generate key: create temporary pukf failed\n"); goto err; } @@ -594,7 +594,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100 + pukf->path.value[pukf->path.len - 1]; - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "public key size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X; path: %s", pukf->size, pukf->type, pukf->ef_structure, pukf->id, sc_print_path(&pukf->path)); @@ -609,7 +609,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, r = sc_pkcs15init_delete_by_path(profile, p15card, &pukf->path); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "generate key: failed to delete existing key file\n"); goto err; } @@ -617,7 +617,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, /* create */ r = sc_pkcs15init_create_file(profile, p15card, pukf); if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "generate key: pukf create file failed\n"); goto err; } @@ -690,7 +690,7 @@ static int epass2003_pkcs15_sanity_check(sc_profile_t * profile, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Check and if needed update PinFlags"); rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PINs"); @@ -709,7 +709,7 @@ static int epass2003_pkcs15_sanity_check(sc_profile_t * profile, if (pin_attrs->reference == profile_auth.attrs.pin.reference && pin_attrs->flags != profile_auth.attrs.pin.flags) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Set flags of '%s'(flags:%X,ref:%i,id:%s) to %X", objs[ii]->label, pin_attrs->flags, pin_attrs->reference, diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index ac9ba210c5..46bbccc92e 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -103,7 +103,7 @@ gpk_erase_card(struct sc_profile *pro, sc_pkcs15_card_t *p15card) if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; @@ -124,7 +124,7 @@ gpk_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; @@ -240,7 +240,7 @@ gpk_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, } r = sc_select_file(p15card->card, &df->path, NULL); - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "select df path: %i", r); + sc_log(p15card->card->ctx, "select df path: %i", r); if (r < 0) return r; @@ -250,7 +250,7 @@ gpk_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, pin_attrs->reference, nulpin, sizeof(nulpin), pin, pin_len, NULL); - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "change CHV %i", r); + sc_log(p15card->card->ctx, "change CHV %i", r); if (r < 0) return r; @@ -259,7 +259,7 @@ gpk_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, pin_attrs->reference + 1, nulpin, sizeof(nulpin), puk, puk_len, NULL); - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "change CHV+1 %i", r); + sc_log(p15card->card->ctx, "change CHV+1 %i", r); if (r < 0) return r; @@ -338,7 +338,7 @@ gpk_init_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, /* Create the PIN file. */ acl = sc_file_get_acl_entry(pinfile, SC_AC_OP_WRITE); if (acl->method != SC_AC_NEVER) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "PIN file most be protected by WRITE=NEVER"); sc_file_free(pinfile); return SC_ERROR_INVALID_ARGUMENTS; @@ -348,7 +348,7 @@ gpk_init_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, if (pinfile->size == 0) pinfile->size = GPK_MAX_PINS * 8; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Now create file"); + sc_log(p15card->card->ctx, "Now create file"); /* Now create the file */ if ((r = sc_pkcs15init_create_file(profile, p15card, pinfile)) < 0 || (r = sc_select_file(p15card->card, &pinfile->path, NULL)) < 0) { @@ -436,7 +436,7 @@ gpk_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_objec case SC_PKCS15_TYPE_PRKEY_DSA: algo = SC_ALGORITHM_DSA; break; default: - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported public key algorithm"); + sc_log(p15card->card->ctx, "Unsupported public key algorithm"); return SC_ERROR_NOT_SUPPORTED; } @@ -518,13 +518,13 @@ gpk_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *keyfile; int r, n; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(p15card->card->ctx, "path=%s, %"SC_FORMAT_LEN_SIZE_T"u bits\n", sc_print_path(&key_info->path), key_info->modulus_length); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "GPK supports generating only RSA keys."); + sc_log(p15card->card->ctx, "GPK supports generating only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -660,7 +660,7 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file if (usage & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) sysrec[2] &= ~0x20; if (sysrec[2] == 0x30) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Key usage should specify at least one of sign or decipher"); + sc_log(ctx, "Key usage should specify at least one of sign or decipher"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -685,13 +685,13 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file || acl->method == SC_AC_NEVER) continue; if (acl->method != SC_AC_CHV) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Authentication method not " + sc_log(ctx, "Authentication method not " "supported for private key files.\n"); r = SC_ERROR_NOT_SUPPORTED; goto out; } if (++npins >= 2) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Too many pins for PrKEY file!\n"); + sc_log(ctx, "Too many pins for PrKEY file!\n"); r = SC_ERROR_NOT_SUPPORTED; goto out; } @@ -716,7 +716,7 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file SC_RECORD_BY_REC_NR); if (r >= 0) { if (r != 7 || buffer[0] != 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "first record of public key file is not Lsys0"); + sc_log(ctx, "first record of public key file is not Lsys0"); r = SC_ERROR_OBJECT_NOT_VALID; goto out; } @@ -741,7 +741,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, unsigned int m, n, tag; int r = 0, found; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Updating public key elements\n"); + sc_log(ctx, "Updating public key elements\n"); /* If we've been given a key with public parts, write them now */ for (n = 2; n < 256; n++) { @@ -754,7 +754,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, /* Check for bad record */ if (r < 2) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "key file format error: " + sc_log(ctx, "key file format error: " "record %u too small (%u bytes)\n", n, r); return SC_ERROR_OBJECT_NOT_VALID; @@ -777,7 +777,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, } if (!found) - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "GPK unknown PK tag %u\n", tag); + sc_log(ctx, "GPK unknown PK tag %u\n", tag); } /* Write all remaining elements */ @@ -824,7 +824,7 @@ gpk_pkfile_update_private(struct sc_profile *profile, u8 data[256]; int r = 0; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Updating private key elements\n"); + sc_log(p15card->card->ctx, "Updating private key elements\n"); for (m = 0; m < part->count; m++) { pe = part->components + m; @@ -934,7 +934,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *info) { if (!rsa->modulus.len || !rsa->exponent.len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "incomplete RSA public key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -943,7 +943,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, * the only exponent supported by GPK4000 and GPK8000 */ if (rsa->exponent.len != 3 || memcmp(rsa->exponent.data, "\001\000\001", 3)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "unsupported RSA exponent"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -962,7 +962,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, if (!rsa->p.len || !rsa->q.len || !rsa->dmp1.len || !rsa->dmq1.len || !rsa->iqmp.len) { /* No or incomplete CRT information */ if (!rsa->d.len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "incomplete RSA private key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1012,7 +1012,7 @@ static int gpk_encode_dsa_key(sc_profile_t *profile, sc_card_t *card, { if (!dsa->p.len || !dsa->q.len || !dsa->g.len || !dsa->pub.len || !dsa->priv.len) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "incomplete DSA public key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1031,7 +1031,7 @@ static int gpk_encode_dsa_key(sc_profile_t *profile, sc_card_t *card, p->bits = 1024; p->bytes = 128; } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "incompatible DSA key size (%u bits)", p->bits); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1060,7 +1060,7 @@ gpk_store_pk(struct sc_profile *profile, sc_pkcs15_card_t *p15card, gpk_compute_publen(&p->_public); gpk_compute_privlen(&p->_private); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Storing pk: %u bits, pub %u bytes, priv %u bytes\n", + sc_log(ctx, "Storing pk: %u bits, pub %u bytes, priv %u bytes\n", p->bits, p->_public.size, p->_private.size); fsize = p->_public.size + p->_private.size; diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index 7ecac0bb58..1119e6b793 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -281,12 +281,12 @@ incrypto34_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int algorithm, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 supports RSA keys only."); + sc_log(card->ctx, "Incrypto34 supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } if (incrypto34_key_algorithm(key_info->usage, &algorithm) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 does not support keys " + sc_log(card->ctx, "Incrypto34 does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } @@ -314,25 +314,25 @@ incrypto34_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int algorithm, r, delete_it = 0; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 supports only RSA keys."); + sc_log(card->ctx, "Incrypto34 supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } if (incrypto34_key_algorithm(key_info->usage, &algorithm) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 does not support keys " + sc_log(card->ctx, "Incrypto34 does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } keybits = key_info->modulus_length & ~7UL; if (keybits > RSAKEY_MAX_BITS) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key, max size is %d", + sc_log(card->ctx, "Unable to generate key, max size is %d", RSAKEY_MAX_BITS); return SC_ERROR_INVALID_ARGUMENTS; } if (sc_profile_get_file(profile, "tempfile", &temp) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define temporary file " + sc_log(card->ctx, "Profile doesn't define temporary file " "for key generation."); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/pkcs15init/pkcs15-jcop.c b/src/pkcs15init/pkcs15-jcop.c index 600e19c3fc..f196851184 100644 --- a/src/pkcs15init/pkcs15-jcop.c +++ b/src/pkcs15init/pkcs15-jcop.c @@ -141,7 +141,7 @@ jcop_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_obje int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys."); + sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* The caller is supposed to have chosen a key file path for us */ @@ -215,7 +215,7 @@ jcop_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys."); + sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); @@ -252,7 +252,7 @@ jcop_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r,delete_ok=0; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys."); + sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/pkcs15init/pkcs15-miocos.c b/src/pkcs15init/pkcs15-miocos.c index 5fea3c9ae0..d6fe7304f9 100644 --- a/src/pkcs15init/pkcs15-miocos.c +++ b/src/pkcs15init/pkcs15-miocos.c @@ -75,7 +75,7 @@ miocos_new_file(struct sc_profile *profile, sc_card_t *card, * the generic class (SC_PKCS15_TYPE_CERT) */ if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "File type not supported by card driver"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -84,7 +84,7 @@ miocos_new_file(struct sc_profile *profile, sc_card_t *card, snprintf(name, sizeof(name), "template-%s", tag); if (sc_profile_get_file(profile, name, &file) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define %s template (%s)", + sc_log(card->ctx, "Profile doesn't define %s template (%s)", desc, name); return SC_ERROR_NOT_SUPPORTED; } @@ -210,7 +210,7 @@ miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (key_info->modulus_length != 1024) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); + sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create key: failed to allocate new key object"); @@ -218,7 +218,7 @@ miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, file->id = file->path.value[file->path.len - 2] * 0x100 + file->path.value[file->path.len - 1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s\n", sc_print_path(&file->path)); + sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); r = sc_pkcs15init_create_file(profile, p15card, file); sc_file_free(file); @@ -250,7 +250,7 @@ miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (rsa->modulus.len != 128) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), + sc_log(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 93d3b8f9cd..4bb178baa4 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -171,7 +171,7 @@ muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Muscle supports RSA keys only."); + sc_log(ctx, "Muscle supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } /* Verification stuff */ @@ -210,7 +210,7 @@ muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_card_ctl(p15card->card, SC_CARDCTL_MUSCLE_IMPORT_KEY, &info); if (r < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to import key"); + sc_log(ctx, "Unable to import key"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r); } return r; @@ -230,12 +230,12 @@ muscle_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Muscle supports only RSA keys (for now)."); + sc_log(card->ctx, "Muscle supports only RSA keys (for now)."); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); } keybits = key_info->modulus_length & ~7UL; if (keybits > 2048) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key, max size is %d", + sc_log(card->ctx, "Unable to generate key, max size is %d", 2048); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); } @@ -264,7 +264,7 @@ muscle_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_GENERATE_KEY, &args); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key"); + sc_log(card->ctx, "Unable to generate key"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); } @@ -275,7 +275,7 @@ muscle_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, extArgs.keyLocation = args.publicKeyLocation; r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_EXTRACT_KEY, &extArgs); if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to extract the public key"); + sc_log(card->ctx, "Unable to extract the public key"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); } diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 754a16a159..a29010f59e 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -95,7 +95,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, const char *itag=NULL, *otag=NULL; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type 0x%X; num %i; info %p; obj %p", type, num, info_out, obj_out); + sc_log(ctx, "type 0x%X; num %i; info %p; obj %p", type, num, info_out, obj_out); switch (type) { case SC_PKCS15_TYPE_CERT_X509: itag = "certificate-info"; @@ -142,18 +142,18 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, if (itag) { snprintf(name, sizeof(name),"%s-%s", COSM_TITLE, itag); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info template %s",name); + sc_log(ctx, "info template %s",name); if (sc_profile_get_file(profile, name, &ifile) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "profile does not defines template '%s'", name); + sc_log(ctx, "profile does not defines template '%s'", name); return SC_ERROR_INCONSISTENT_PROFILE; } } if (otag) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "obj template %s",otag); + sc_log(ctx, "obj template %s",otag); if (sc_profile_get_file(profile, otag, &ofile) < 0) { sc_file_free(ifile); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "profile does not defines template '%s'", name); + sc_log(ctx, "profile does not defines template '%s'", name); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -170,7 +170,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, ifile->path.value[ifile->path.len-2] |= 0x01; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "info_file(id:%04X,size:%"SC_FORMAT_LEN_SIZE_T"u,rlen:%i)", ifile->id, ifile->size, ifile->record_length); *info_out = ifile; @@ -181,7 +181,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, } if (ofile) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "obj file %04X; size %"SC_FORMAT_LEN_SIZE_T"u; ", ofile->id, ofile->size); if (obj_out) @@ -225,7 +225,7 @@ awp_update_blob(struct sc_context *ctx, *blob_size += lv->len; break; default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Invalid tlv type %i",type); + sc_log(ctx, "Invalid tlv type %i",type); return SC_ERROR_INCORRECT_PARAMETERS; } @@ -274,7 +274,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * unsigned char *buff = NULL; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "container file(file-id:%X,rlen:%i,rcount:%i)", + sc_log(ctx, "container file(file-id:%X,rlen:%i,rcount:%i)", list_file->id, list_file->record_length, list_file->record_count); buff = malloc(list_file->record_length); @@ -318,18 +318,18 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, int rv = 0; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create container(%X:%X:%X)", acc->prkey_id, acc->cert_id, acc->pubkey_id); + sc_log(ctx, "create container(%X:%X:%X)", acc->prkey_id, acc->cert_id, acc->pubkey_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Create container failed"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "contaner cfile(rcount:%i,rlength:%i)", clist->record_count, clist->record_length); + sc_log(ctx, "contaner cfile(rcount:%i,rlength:%i)", clist->record_count, clist->record_length); rv = sc_select_file(p15card->card, &clist->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Create container failed: cannot select container's list"); file->record_length = clist->record_length; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "contaner file(rcount:%i,rlength:%i)", file->record_count, file->record_length); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Append new record %i for private key", file->record_count + 1); + sc_log(ctx, "contaner file(rcount:%i,rlength:%i)", file->record_count, file->record_length); + sc_log(ctx, "Append new record %i for private key", file->record_count + 1); rv = awp_create_container_record(p15card, profile, file, acc); @@ -350,10 +350,10 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p unsigned char *buff = NULL; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "update container entry(type:%X,id %i,rec %i,offs %i", type, file_id, rec, offs); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "container file(file-id:%X,rlen:%i,rcount:%i)", + sc_log(ctx, "container file(file-id:%X,rlen:%i,rcount:%i)", list_file->id, list_file->record_length, list_file->record_count); buff = malloc(list_file->record_length); @@ -379,7 +379,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p case SC_PKCS15_TYPE_PUBKEY_RSA: case COSM_TYPE_PUBKEY_RSA: if (*(buff + offs + 4)) - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Insert public key to container that contains certificate %02X%02X", + sc_log(ctx, "Insert public key to container that contains certificate %02X%02X", *(buff + offs + 4), *(buff + offs + 5)); *(buff + offs + 0) = (file_id >> 8) & 0xFF; *(buff + offs + 1) = file_id & 0xFF; @@ -431,7 +431,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, unsigned char *list = NULL; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "update container(type:%X,obj_id:%X)", type, obj_id); + sc_log(ctx, "update container(type:%X,obj_id:%X)", type, obj_id); if (prkey_id) *prkey_id = 0; @@ -484,7 +484,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, for (rec_offs=0; !rv && rec_offs<12; rec_offs+=6) { int offs; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "rec %i; rec_offs %i", rec, rec_offs); + sc_log(ctx, "rec %i; rec_offs %i", rec, rec_offs); offs = rec*AWP_CONTAINER_RECORD_LEN + rec_offs; if (*(list + offs + 2)) { unsigned char *buff = NULL; @@ -516,7 +516,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, if (key_id->len == *(buff + id_offs) && !memcmp(key_id->value, buff + id_offs + 1, key_id->len)) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "found key file friend"); + sc_log(ctx, "found key file friend"); if (!rv) rv = awp_update_container_entry(p15card, profile, file, type, obj_id, rec + 1, rec_offs); @@ -641,7 +641,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil unsigned ii; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type %i, num %i", type, num); + sc_log(ctx, "type %i, num %i", type, num); switch (type) { case SC_PKCS15_TYPE_CERT_X509: snprintf(obj_name, NAME_MAX_LEN, "template-certificate"); @@ -666,19 +666,19 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil snprintf(lst_name, NAME_MAX_LEN,"%s-private-list", COSM_TITLE); break; default: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Not supported file type %X", type); + sc_log(ctx, "Not supported file type %X", type); return SC_ERROR_INVALID_ARGUMENTS; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "obj_name %s; num 0x%X",obj_name, num); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lst_name %s",lst_name); + sc_log(ctx, "obj_name %s; num 0x%X",obj_name, num); + sc_log(ctx, "lst_name %s",lst_name); if (sc_profile_get_file(profile, obj_name, &obj_file) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "No profile template '%s'", obj_name); + sc_log(ctx, "No profile template '%s'", obj_name); rv = SC_ERROR_NOT_SUPPORTED; goto done; } else if (sc_profile_get_file(profile, lst_name, &lst_file) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "No profile template '%s'", lst_name); + sc_log(ctx, "No profile template '%s'", lst_name); rv = SC_ERROR_NOT_SUPPORTED; goto done; } @@ -730,7 +730,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil goto done; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "ii %i, rv %i; %X; %"SC_FORMAT_LEN_SIZE_T"u", ii, rv, file->id, file->size); *(buff + ii) = COSM_LIST_TAG; @@ -740,7 +740,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil *(buff + ii + 4) = file->size & 0xFF; rv = sc_update_binary(p15card->card, ii, buff + ii, 5, 0); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "rv %i",rv); + sc_log(ctx, "rv %i",rv); if (rv < 0) goto done; @@ -770,7 +770,7 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj key_info = (struct sc_pkcs15_prkey_info *)obj->data; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "object(%s,type:%X)", obj->label, obj->type); + sc_log(ctx, "object(%s,type:%X)", obj->label, obj->type); if (obj->type == SC_PKCS15_TYPE_PUBKEY_RSA || obj->type == COSM_TYPE_PUBKEY_RSA ) ki->flags = COSM_TAG_PUBKEY_RSA; else if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA || obj->type == COSM_TYPE_PRKEY_RSA) @@ -783,14 +783,14 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj ki->label.value = (unsigned char *)strdup(obj->label); ki->label.len = strlen(obj->label); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "cosm_encode_key_info() label(%u):%s", ki->label.len, ki->label.value); /* * Oberthur saves modulus value without tag and length. */ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "pubkey->modulus.len %"SC_FORMAT_LEN_SIZE_T"u", pubkey->modulus.len); ki->modulus.value = malloc(pubkey->modulus.len); @@ -821,7 +821,7 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj memcpy(ki->id.value, key_info->id.value, key_info->id.len); ki->id.len = key_info->id.len; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_encode_key_info() label:%s",ki->label.value); + sc_log(ctx, "cosm_encode_key_info() label:%s",ki->label.value); done: ERR_load_ERR_strings(); ERR_load_crypto_strings(); @@ -847,13 +847,13 @@ awp_set_key_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, st unsigned char *blob; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file:%p, kinfo:%p, cinfo:%p", file, ki, ci); + sc_log(ctx, "file:%p, kinfo:%p, cinfo:%p", file, ki, ci); blob_size = 2; blob = malloc(blob_size); if (!blob) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP set key info failed: blob allocation error"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "label:%s",ki->label.value); + sc_log(ctx, "label:%s",ki->label.value); *blob = (ki->flags >> 8) & 0xFF; *(blob + 1) = ki->flags & 0xFF; @@ -937,7 +937,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob cert_info = (struct sc_pkcs15_cert_info *)obj->data; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Encode cert(%s,id:%s,der(%p,%"SC_FORMAT_LEN_SIZE_T"u))", obj->label, sc_pkcs15_print_id(&cert_info->id), obj->content.value, obj->content.len); @@ -1028,7 +1028,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &ci->serial.value); } /* if len == 0, and value == NULL, then the cert did not have a serial number.*/ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", ci->serial.len); + sc_log(ctx, "cert. serial encoded length %i", ci->serial.len); #else do { @@ -1048,7 +1048,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob *(ci->serial.value + 1) = encoded_len; ci->serial.len = encoded_len + 2; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", encoded_len); + sc_log(ctx, "cert. serial encoded length %i", encoded_len); } while (0); #endif @@ -1108,7 +1108,7 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob data_info = (struct sc_pkcs15_data_info *)obj->data; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Encode data(%s,id:%s,der(%p,%"SC_FORMAT_LEN_SIZE_T"u))", obj->label, sc_pkcs15_print_id(&data_info->id), obj->content.value, obj->content.len); @@ -1169,7 +1169,7 @@ awp_set_data_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, unsigned char *blob; LOG_FUNC_CALLED(ctx); - sc_debug (ctx, SC_LOG_DEBUG_NORMAL, "Set 'DATA' info %p", di); + sc_log(ctx, "Set 'DATA' info %p", di); blob_size = 2; if (!(blob = malloc(blob_size))) { r = SC_ERROR_OUT_OF_MEMORY; @@ -1319,17 +1319,17 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_PRKEY_RSA, prvkey_id & 0xFF, &info_file, &key_file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update key info failed: instantiation error"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "key id %X; info id%X", key_file->id, info_file->id); + sc_log(ctx, "key id %X; info id%X", key_file->id, info_file->id); rv = sc_pkcs15init_authenticate(profile, p15card, info_file, SC_AC_OP_READ); if (rv) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update key info failed: 'READ' authentication error"); + sc_log(ctx, "AWP update key info failed: 'READ' authentication error"); goto done; } rv = sc_select_file(p15card->card, &info_file->path, &file); if (rv) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update key info failed: cannot select info file"); + sc_log(ctx, "AWP update key info failed: cannot select info file"); goto done; } @@ -1339,7 +1339,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = sc_read_binary(p15card->card, 0, buf, file->size, 0); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update key info failed: read info file error"); + sc_log(ctx, "AWP update key info failed: read info file error"); goto done; } buf_len = rv; @@ -1347,7 +1347,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, memset(&ikey, 0, sizeof(ikey)); rv = awp_parse_key_info(ctx, buf, buf_len, &ikey); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update key info failed: parse key info error"); + sc_log(ctx, "AWP update key info failed: parse key info error"); goto done; } free(buf); @@ -1385,7 +1385,7 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "COSM new file error"); memset(&icert, 0, sizeof(icert)); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Cert Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_cert_info(p15card, obj, &icert); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot encode info"); @@ -1399,7 +1399,7 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro rv = awp_update_container(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &icert.id, obj_id, &prvkey_id); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update container"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PrvKeyID:%04X", prvkey_id); + sc_log(ctx, "PrvKeyID:%04X", prvkey_id); if (prvkey_id) rv = awp_update_key_info(p15card, profile, prvkey_id, &icert); @@ -1474,7 +1474,7 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "New private key info file error"); pubkey.algorithm = SC_ALGORITHM_RSA; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: decode public key error"); @@ -1529,7 +1529,7 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "New public key info file error"); pubkey.algorithm = SC_ALGORITHM_RSA; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: decode public key error"); @@ -1575,7 +1575,7 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "COSM new file error"); memset(&idata, 0, sizeof(idata)); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Data Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_data_info(p15card, obj, &idata); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Data' update DF failed: cannot encode info"); @@ -1641,7 +1641,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, unsigned char *buff=NULL; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "update container entry (type:%X,file-id:%X)", type, file_id); + sc_log(ctx, "update container entry (type:%X,file-id:%X)", type, file_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update contaner entry: cannot get allocate AWP file"); @@ -1656,7 +1656,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, for (rec = 1; rec <= (unsigned)file->record_count; rec++) { rv = sc_read_record(p15card->card, rec, buff, file->record_length, SC_RECORD_BY_REC_NR); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update contaner entry: read record error %i", rv); + sc_log(ctx, "AWP update contaner entry: read record error %i", rv); break; } rec_len = rv; @@ -1675,26 +1675,26 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, if (!memcmp(buff,"\0\0\0\0\0\0\0\0\0\0\0\0",12)) { rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_ERASE); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update contaner entry: 'erase' authentication error %i", rv); + sc_log(ctx, "AWP update contaner entry: 'erase' authentication error %i", rv); break; } rv = sc_delete_record(p15card->card, rec); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update contaner entry: delete record error %i", rv); + sc_log(ctx, "AWP update contaner entry: delete record error %i", rv); break; } } else { rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update contaner entry: 'update' authentication error %i", rv); + sc_log(ctx, "AWP update contaner entry: 'update' authentication error %i", rv); break; } rv = sc_update_record(p15card->card, rec, buff, rec_len, SC_RECORD_BY_REC_NR); if (rv < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update contaner entry: update record error %i", rv); + sc_log(ctx, "AWP update contaner entry: update record error %i", rv); break; } } @@ -1724,7 +1724,7 @@ awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile * unsigned char id[2]; LOG_FUNC_CALLED(ctx); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "type %X; obj_id %X",type, obj_id); + sc_log(ctx, "type %X; obj_id %X",type, obj_id); switch (type) { case SC_PKCS15_TYPE_PRKEY_RSA: @@ -1741,7 +1741,7 @@ awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile * SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCORRECT_PARAMETERS, "AWP update object list: invalid type"); } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "AWP update object list: select '%s' file", lst_name); + sc_log(ctx, "AWP update object list: select '%s' file", lst_name); rv = sc_profile_get_file(profile, lst_name, &lst_file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update object list: cannot instantiate list file"); @@ -1800,11 +1800,11 @@ awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro path = ((struct sc_pkcs15_cert_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); + sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot get allocate new AWP file"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); + sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) @@ -1834,11 +1834,11 @@ awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p path = ((struct sc_pkcs15_prkey_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); + sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot get allocate new AWP file"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); + sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) @@ -1868,11 +1868,11 @@ awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p path = ((struct sc_pkcs15_pubkey_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); + sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot get allocate new AWP file"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); + sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) @@ -1902,11 +1902,11 @@ awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro path = ((struct sc_pkcs15_data_info *) obj->data)->path; file_id = path.value[path.len-2] * 0x100 + path.value[path.len-1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file-id:%X", file_id); + sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannot get allocate new AWP file"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "info file-id:%X", info_file->id); + sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index a6cfc35a8b..aaaf25e524 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -70,7 +70,7 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile ctx = p15card->card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags); + sc_log(ctx, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags); if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) { rv = SC_ERROR_INCONSISTENT_PROFILE; SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot find "COSM_TITLE"-token-info"); @@ -100,7 +100,7 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile if (sz < file->size - 4) memset(buffer + sz, ' ', file->size - sz); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_write_tokeninfo() token label '%s'; oberthur flags 0x%X", buffer, flags); + sc_log(ctx, "cosm_write_tokeninfo() token label '%s'; oberthur flags 0x%X", buffer, flags); memset(buffer + file->size - 4, 0, 4); *(buffer + file->size - 1) = flags & 0xFF; @@ -127,7 +127,7 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, int rv = 0; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "id %04X", df->id); + sc_log(ctx, "id %04X", df->id); if (df->type==SC_FILE_TYPE_DF) { rv = sc_pkcs15init_authenticate(profile, p15card, df, SC_AC_OP_DELETE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot authenticate SC_AC_OP_DELETE"); @@ -174,20 +174,20 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) * it *after* the DF. * */ if (sc_profile_get_file(profile, "DIR", &dir) >= 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file dir %04X",dir->id); + sc_log(ctx, "erase file dir %04X",dir->id); rv = cosm_delete_file(p15card, profile, dir); sc_file_free(dir); if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) goto done; } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file ddf %04X",df->id); + sc_log(ctx, "erase file ddf %04X",df->id); rv = cosm_delete_file(p15card, profile, df); if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) goto done; if (sc_profile_get_file(profile, "private-DF", &dir) >= 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file dir %04X",dir->id); + sc_log(ctx, "erase file dir %04X",dir->id); rv = cosm_delete_file(p15card, profile, dir); sc_file_free(dir); if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) @@ -195,7 +195,7 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) } if (sc_profile_get_file(profile, "public-DF", &dir) >= 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "erase file dir %04X",dir->id); + sc_log(ctx, "erase file dir %04X",dir->id); rv = cosm_delete_file(p15card, profile, dir); sc_file_free(dir); if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND) @@ -204,7 +204,7 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) rv = sc_profile_get_file(profile, COSM_TITLE"-AppDF", &dir); if (!rv) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "delete %s; r %i", COSM_TITLE"-AppDF", rv); + sc_log(ctx, "delete %s; r %i", COSM_TITLE"-AppDF", rv); rv = cosm_delete_file(p15card, profile, dir); sc_file_free(dir); } @@ -244,7 +244,7 @@ cosm_create_dir(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Create private objects DF */ for (ii = 0; create_dfs[ii]; ii++) { if (sc_profile_get_file(profile, create_dfs[ii], &file)) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Inconsistent profile: cannot find %s", create_dfs[ii]); + sc_log(ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "Profile do not contains Oberthur AWP file"); } @@ -278,7 +278,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 }; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "pin lens %"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u", pin_len, puk_len); if (!pin || pin_len>0x40) @@ -347,12 +347,12 @@ cosm_update_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (ainfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ref %i; flags 0x%X", ainfo->attrs.pin.reference, ainfo->attrs.pin.flags); + sc_log(ctx, "ref %i; flags 0x%X", ainfo->attrs.pin.reference, ainfo->attrs.pin.flags); if (ainfo->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) { if (ainfo->attrs.pin.reference != 4) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_PIN_REFERENCE, "cosm_update_pin() invalid SOPIN reference"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update SOPIN ignored"); + sc_log(ctx, "Update SOPIN ignored"); rv = SC_SUCCESS; } else { @@ -385,9 +385,9 @@ cosm_select_pin_reference(struct sc_profile *profile, struct sc_pkcs15_card *p15 pin_attrs = &auth_info->attrs.pin; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ref %i; flags %X", pin_attrs->reference, pin_attrs->flags); + sc_log(ctx, "ref %i; flags %X", pin_attrs->reference, pin_attrs->flags); if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); + sc_log(ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -433,7 +433,7 @@ cosm_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pin_attrs = &auth_info->attrs.pin; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create '%.*s'; ref 0x%X; flags %X", (int) sizeof pin_obj->label, pin_obj->label, pin_attrs->reference, pin_attrs->flags); + sc_log(ctx, "create '%.*s'; ref 0x%X; flags %X", (int) sizeof pin_obj->label, pin_obj->label, pin_attrs->reference, pin_attrs->flags); if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pin_file) < 0) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "\""COSM_TITLE"-AppDF\" not defined"); @@ -483,7 +483,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, unsigned int structure = 0xFFFFFFFF; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cosm_new_file() type %X; num %i",type, num); + sc_log(card->ctx, "cosm_new_file() type %X; num %i",type, num); while (1) { switch (type) { case SC_PKCS15_TYPE_PRKEY_RSA: @@ -518,16 +518,16 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, * the generic class (SC_PKCS15_TYPE_CERT) */ if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type %X not supported by card driver", + sc_log(card->ctx, "File type %X not supported by card driver", type); return SC_ERROR_INVALID_ARGUMENTS; } type &= SC_PKCS15_TYPE_CLASS_MASK; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "cosm_new_file() template %s; num %i",_template, num); + sc_log(card->ctx, "cosm_new_file() template %s; num %i",_template, num); if (sc_profile_get_file(profile, _template, &file) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define %s template '%s'", + sc_log(card->ctx, "Profile doesn't define %s template '%s'", desc, _template); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); } @@ -538,7 +538,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, file->ef_structure = structure; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "cosm_new_file() file size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X", file->size, file->type, file->ef_structure, file->id); *out = file; @@ -663,7 +663,7 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, key_info->key_reference = prkf->path.value[prkf->path.len - 1] & 0xFF; key_info->path = prkf->path; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_generate_key() now delete temporary public key"); + sc_log(ctx, "cosm_generate_key() now delete temporary public key"); rv = cosm_delete_file(p15card, profile, tmpf); sc_file_free(tmpf); @@ -689,7 +689,7 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); + sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); /* Here, the path of private key file should be defined. * Nevertheless, we need to instantiate private key to get the ACLs. */ rv = cosm_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); @@ -700,7 +700,7 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, file->id = file->path.value[file->path.len - 2] * 0x100 + file->path.value[file->path.len - 1]; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s", sc_print_path(&file->path)); + sc_log(ctx, "Path of private key file to create %s", sc_print_path(&file->path)); rv = sc_select_file(p15card->card, &file->path, NULL); if (rv == 0) { @@ -741,7 +741,7 @@ cosm_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || prkey->algorithm != SC_ALGORITHM_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), + sc_log(ctx, "store key with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); rv = sc_select_file(p15card->card, &key_info->path, &file); @@ -790,11 +790,11 @@ cosm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15car SC_FUNC_CALLED(ctx, 1); switch(op) { case SC_AC_OP_ERASE: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; erase object('%.*s',type:%X)", (int) sizeof object->label, object->label, object->type); + sc_log(ctx, "Update DF; erase object('%.*s',type:%X)", (int) sizeof object->label, object->label, object->type); rv = awp_update_df_delete(p15card, profile, object); break; case SC_AC_OP_CREATE: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; create object('%.*s',type:%X)", (int) sizeof object->label, object->label, object->type); + sc_log(ctx, "Update DF; create object('%.*s',type:%X)", (int) sizeof object->label, object->label, object->type); rv = awp_update_df_create(p15card, profile, object); break; } @@ -838,7 +838,7 @@ cosm_emu_update_tokeninfo(struct sc_profile *profile, struct sc_pkcs15_card *p15 *(buf + file->size - 1) = flags % 0x100; *(buf + file->size - 2) = (flags % 0x10000) / 0x100; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update token info (label:'%s',flags:%X,p15card->flags:%X)", buf, flags, p15card->flags); + sc_log(ctx, "Update token info (label:'%s',flags:%X,p15card->flags:%X)", buf, flags, p15card->flags); rv = sc_pkcs15init_update_file(profile, p15card, file, buf, file->size); free(buf); sc_file_free(file); diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 82f44e5733..eb28d9c4ed 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -123,7 +123,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_FUNC_CALLED(card->ctx); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported"); + sc_log(card->ctx, "only RSA is currently supported"); return SC_ERROR_NOT_SUPPORTED; } @@ -181,7 +181,7 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card key_info.key_id = kid->value[0]; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported"); + sc_log(card->ctx, "only RSA is currently supported"); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index d23d07a007..bbf9f91601 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -75,7 +75,7 @@ static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name r = sc_create_file(card, file); sc_file_free(file); } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Create %s failed: %s\n", name, sc_strerror(r)); return r; } @@ -186,7 +186,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (puk_len != 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Do not enter User unblocking PIN (PUK): %s\n", + sc_log(ctx, "Do not enter User unblocking PIN (PUK): %s\n", sc_strerror(SC_ERROR_NOT_SUPPORTED)); return SC_ERROR_NOT_SUPPORTED; } @@ -198,7 +198,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (auth_info->attrs.pin.reference != RTECP_SO_PIN_REF && auth_info->attrs.pin.reference != RTECP_USER_PIN_REF) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN reference %i not found in standard" + sc_log(ctx, "PIN reference %i not found in standard" " (Rutoken ECP) PINs\n", auth_info->attrs.pin.reference); return SC_ERROR_NOT_SUPPORTED; } @@ -216,7 +216,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, acl = sc_file_get_acl_entry(file, SC_AC_OP_PIN_RESET); if (acl && acl->method == SC_AC_CHV && acl->key_ref == RTECP_SO_PIN_REF) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Allow reset of User PIN with SoPIN\n"); + sc_log(ctx, "Allow reset of User PIN with SoPIN\n"); reset_by_sopin = 1; } sc_file_free(file); @@ -321,7 +321,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, && key_info->modulus_length != SC_PKCS15_GOSTR3410_KEYSIZE)) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", key_info->modulus_length); return SC_ERROR_INVALID_ARGUMENTS; @@ -522,7 +522,7 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_free(pukey_df); } else if (card->ctx->debug >= 2) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", "Get PuKey-DF info failed"); + sc_log(card->ctx, "%s\n", "Get PuKey-DF info failed"); } if (r == SC_SUCCESS) { @@ -531,7 +531,7 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, key_len, NULL); if (r && card->ctx->debug >= 2) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", "Store public key failed"); + sc_log(card->ctx, "%s\n", "Store public key failed"); } end: assert(buf); diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 1638ef6140..856ff7c113 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -99,7 +99,7 @@ rutoken_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, pin_ref = auth_info->attrs.pin.reference; so_pin_flag = auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN; - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "PIN reference %i%s\n", + sc_log(p15card->card->ctx, "PIN reference %i%s\n", pin_ref, so_pin_flag ? " SO PIN flag" : ""); if ((pin_ref == SC_RUTOKEN_DEF_ID_GCHV_ADMIN && so_pin_flag) @@ -133,7 +133,7 @@ rutoken_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (puk_len != 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "Do not enter User unblocking PIN (PUK): %s\n", sc_strerror(SC_ERROR_NOT_SUPPORTED)); return SC_ERROR_NOT_SUPPORTED; @@ -152,11 +152,11 @@ rutoken_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return SC_SUCCESS; else { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Incorrect PIN\n"); + sc_log(ctx, "Incorrect PIN\n"); break; } } - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "PIN reference %i not found in standard (Rutoken) PINs\n", auth_info->attrs.pin.reference); return SC_ERROR_NOT_SUPPORTED; @@ -292,7 +292,7 @@ rutoken_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card) { ret = create_typical_fs(card); if (ret != SC_SUCCESS) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Failed to create typical fs: %s\n", sc_strerror(ret)); ret_end = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_FORMAT_END, NULL); @@ -300,7 +300,7 @@ rutoken_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card) ret = ret_end; } if (ret != SC_SUCCESS) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, + sc_log(card->ctx, "Failed to erase: %s\n", sc_strerror(ret)); else sc_free_apps(card); diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 26bff9608d..60b6a82dfc 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -565,7 +565,7 @@ static int sc_hsm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15 SC_FUNC_CALLED(ctx, 1); switch(op) { case SC_AC_OP_ERASE: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; erase object('%s',type:%X)", object->label, object->type); + sc_log(ctx, "Update DF; erase object('%s',type:%X)", object->label, object->type); switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: rv = sc_hsm_delete_ef(p15card, PRKD_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference); @@ -583,7 +583,7 @@ static int sc_hsm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15 break; case SC_AC_OP_UPDATE: case SC_AC_OP_CREATE: - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; create object('%s',type:%X)", object->label, object->type); + sc_log(ctx, "Update DF; create object('%s',type:%X)", object->label, object->type); switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PUBKEY: rv = SC_SUCCESS; diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 0a00627e39..768f66c595 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -101,7 +101,7 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) /* Create the MF if it doesn't exist yet */ r = sc_select_file(p15card->card, &mf->path, NULL); if (r == SC_ERROR_FILE_NOT_FOUND) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "MF doesn't exist, creating now"); + sc_log(ctx, "MF doesn't exist, creating now"); /* Fix up the file's ACLs */ r = sc_pkcs15init_fixup_file(profile, p15card, mf); @@ -119,7 +119,7 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) r = sc_select_file(p15card->card, &pinfile->path, NULL); if (r == SC_ERROR_FILE_NOT_FOUND) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Global pin file doesn't exist, creating now"); + sc_log(ctx, "Global pin file doesn't exist, creating now"); /* Fix up the file's ACLs */ r = sc_pkcs15init_fixup_file(profile, p15card, pinfile); @@ -214,8 +214,8 @@ setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_select_file(p15card->card, &pinfile->path, &pinfile); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "pinfile->status:%X", pinfile->status); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create PIN with reference:%X, flags:%X, path:%s", + sc_log(ctx, "pinfile->status:%X", pinfile->status); + sc_log(ctx, "create PIN with reference:%X, flags:%X, path:%s", auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path)); if (pinfile->status == SC_FILE_STATUS_CREATION) @@ -269,14 +269,14 @@ setcos_new_file(sc_profile_t *profile, sc_card_t *card, else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT) tag = "data"; else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported file type"); + sc_log(card->ctx, "Unsupported file type"); return SC_ERROR_INVALID_ARGUMENTS; } /* Get template from profile */ snprintf(name, sizeof(name), "template-%s", tag); if (sc_profile_get_file(profile, name, &file) < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define %s", name); + sc_log(card->ctx, "Profile doesn't define %s", name); return SC_ERROR_NOT_SUPPORTED; } @@ -334,7 +334,7 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); + sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); /* Get the private key file */ r = setcos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); @@ -351,7 +351,7 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF; - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s\n", sc_print_path(&file->path)); + sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); r = sc_select_file(p15card->card, &file->path, NULL); if (!r) { @@ -393,7 +393,7 @@ setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), + sc_log(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); @@ -486,7 +486,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (keybits != key_info->modulus_length) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, + sc_log(ctx, "key-size from card[%"SC_FORMAT_LEN_SIZE_T"u] does not match[%"SC_FORMAT_LEN_SIZE_T"u]\n", keybits, key_info->modulus_length); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PKCS15INIT, "Failed to generate key"); diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index d1c8e8b987..7298a58ee4 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -911,7 +911,7 @@ static int starcos_finalize_card(sc_card_t *card) tfile.id = 0x3f00; r = sc_card_ctl(card, SC_CARDCTL_STARCOS_CREATE_END, &tfile); if (r < 0) - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "failed to call CREATE END for the MF\n"); + sc_log(card->ctx, "failed to call CREATE END for the MF\n"); /* call CREATE END for the apps (pkcs15) DF */ tfile.type = SC_FILE_TYPE_DF; tfile.id = 0x5015; diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 9669e07ee0..b4a312e2b4 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -618,7 +618,7 @@ static int sm_decrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, goto err; } - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Decrypted APDU sw1=%02x sw2=%02x", + sc_log(card->ctx, "Decrypted APDU sw1=%02x sw2=%02x", apdu->sw1, apdu->sw2); sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Decrypted APDU response data", apdu->resp, apdu->resplen); diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index 31360833b5..af787ed879 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -103,7 +103,7 @@ static int initialize(int reader_id, int verbose, reader_count = sc_ctx_get_reader_count(*ctx); if (reader_count == 0) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n"); + sc_log(*ctx, "No reader not found.\n"); return SC_ERROR_NO_READERS_FOUND; } @@ -113,19 +113,19 @@ static int initialize(int reader_id, int verbose, *reader = sc_ctx_get_reader(*ctx, i); if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { reader_id = i; - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader" + sc_log(*ctx, "Using the first reader" " with a card: %s", (*reader)->name); break; } } if ((unsigned int) reader_id >= reader_count) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader."); + sc_log(*ctx, "No card found, using the first reader."); reader_id = 0; } } if ((unsigned int) reader_id >= reader_count) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number " + sc_log(*ctx, "Invalid reader number " "(%d), only %d available.\n", reader_id, reader_count); return SC_ERROR_NO_READERS_FOUND; } diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index a4e14a4c5c..7c29b7f32a 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -132,7 +132,7 @@ static int initialize(int reader_id, int verbose, reader_count = sc_ctx_get_reader_count(*ctx); if (reader_count == 0) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n"); + sc_log(*ctx, "No reader not found.\n"); return SC_ERROR_NO_READERS_FOUND; } @@ -142,19 +142,19 @@ static int initialize(int reader_id, int verbose, *reader = sc_ctx_get_reader(*ctx, i); if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { reader_id = i; - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader" + sc_log(*ctx, "Using the first reader" " with a card: %s", (*reader)->name); break; } } if ((unsigned int) reader_id >= reader_count) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader."); + sc_log(*ctx, "No card found, using the first reader."); reader_id = 0; } } if ((unsigned int) reader_id >= reader_count) { - sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number " + sc_log(*ctx, "Invalid reader number " "(%d), only %d available.\n", reader_id, reader_count); return SC_ERROR_NO_READERS_FOUND; } From 00a150f74ccdac71b48a8e8531c5ecd1fdd9053d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Nov 2018 23:10:49 +0100 Subject: [PATCH 0656/4321] replaced SC_FUNC_RETURN with LOG_FUNC_RETURN --- src/libopensc/card-akis.c | 6 +- src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-atrust-acos.c | 6 +- src/libopensc/card-cac.c | 36 ++++----- src/libopensc/card-cac1.c | 12 +-- src/libopensc/card-cardos.c | 12 +-- src/libopensc/card-coolkey.c | 22 +++--- src/libopensc/card-entersafe.c | 14 ++-- src/libopensc/card-flex.c | 6 +- src/libopensc/card-gids.c | 108 +++++++++++++-------------- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-incrypto34.c | 14 ++-- src/libopensc/card-itacns.c | 2 +- src/libopensc/card-jcop.c | 2 +- src/libopensc/card-masktech.c | 6 +- src/libopensc/card-mcrd.c | 12 +-- src/libopensc/card-miocos.c | 8 +- src/libopensc/card-muscle.c | 16 ++-- src/libopensc/card-npa.c | 2 +- src/libopensc/card-oberthur.c | 2 +- src/libopensc/card-rtecp.c | 26 +++---- src/libopensc/card-rutoken.c | 68 ++++++++--------- src/libopensc/card-setcos.c | 8 +- src/libopensc/card-starcos.c | 6 +- src/libopensc/card-tcos.c | 6 +- src/libopensc/card.c | 4 +- src/libopensc/iso7816.c | 4 +- src/libopensc/muscle.c | 80 ++++++++++---------- src/libopensc/p15card-helper.c | 10 +-- src/libopensc/pkcs15-cac.c | 12 +-- src/libopensc/pkcs15-coolkey.c | 4 +- src/libopensc/pkcs15-data.c | 2 +- src/libopensc/pkcs15-oberthur.c | 8 +- src/libopensc/pkcs15-pin.c | 2 +- src/libopensc/pkcs15-piv.c | 12 +-- src/libopensc/reader-ctapi.c | 2 +- src/pkcs15init/pkcs15-gpk.c | 10 +-- src/pkcs15init/pkcs15-miocos.c | 6 +- src/pkcs15init/pkcs15-oberthur-awp.c | 82 ++++++++++---------- src/pkcs15init/pkcs15-oberthur.c | 34 ++++----- src/pkcs15init/pkcs15-rtecp.c | 20 ++--- src/pkcs15init/pkcs15-setcos.c | 10 +-- src/sm/sm-eac.c | 18 ++--- 43 files changed, 362 insertions(+), 362 deletions(-) diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 5cd2b1e92f..5b88a0e229 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -102,7 +102,7 @@ select_file(sc_card_t *card, sc_apdu_t *apdu, const sc_path_t *path, file = sc_file_new(); if (file == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); r = card->ops->process_fci(card, file, apdu->resp + 2, apdu->resp[1]); if (r) { @@ -185,7 +185,7 @@ akis_list_files(sc_card_t *card, u8 *buf, size_t buflen) } r = fids; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int @@ -320,7 +320,7 @@ akis_delete_file(sc_card_t *card, const sc_path_t *path) break; default: sc_log(card->ctx, "File type has to be FID or PATH"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x16, type, 0x00); apdu.cla = 0x80; diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index fb5eb95783..fdad661823 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -313,7 +313,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path, if (r != SC_SUCCESS) sc_log(card->ctx, "error parsing security attributes"); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int asepcos_set_security_env(sc_card_t *card, diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 86102b446d..64e14f5e08 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -263,7 +263,7 @@ static int atrust_acos_select_aid(struct sc_card *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->type = SC_FILE_TYPE_DF; file->ef_structure = SC_FILE_EF_UNKNOWN; file->path.len = 0; @@ -348,7 +348,7 @@ static int atrust_acos_select_fid(struct sc_card *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->id = (id_hi << 8) + id_lo; file->path = card->cache.current_path; @@ -494,7 +494,7 @@ static int atrust_acos_select_file(struct sc_card *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->id = (path[pathlen-2] << 8) + path[pathlen-1]; file->path = card->cache.current_path; diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index b2c0c3cec9..4ffe7497d7 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -336,7 +336,7 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, } err: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -469,11 +469,11 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); if (idx > priv->cache_buf_len) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_END_REACHED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED); } len = MIN(count, priv->cache_buf_len-idx); memcpy(buf, &priv->cache_buf[idx], len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); + LOG_FUNC_RETURN(card->ctx, len); } sc_log(card->ctx, @@ -487,7 +487,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, if (priv->object_type <= 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len); if (r < 0) { @@ -617,7 +617,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, free(tl); if (val) free(val); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* CAC driver is read only */ @@ -626,7 +626,7 @@ static int cac_write_binary(sc_card_t *card, unsigned int idx, { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } /* initialize getting a list and return the number of elements in the list */ @@ -670,14 +670,14 @@ static int cac_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* seri LOG_FUNC_CALLED(card->ctx); if (card->serialnr.len) { *serial = card->serialnr; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } if (priv->cac_id_len) { serial->len = MIN(priv->cac_id_len, SC_MAX_SERIALNR); memcpy(serial->value, priv->cac_id, serial->len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } static int cac_get_ACA_path(sc_card_t *card, sc_path_t *path) @@ -688,7 +688,7 @@ static int cac_get_ACA_path(sc_card_t *card, sc_path_t *path) if (priv->aca_path) { *path = *priv->aca_path; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) @@ -741,7 +741,7 @@ static int cac_get_challenge(sc_card_t *card, u8 *rnd, size_t len) } memcpy(rnd, rbuf, out_len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) out_len); + LOG_FUNC_RETURN(card->ctx, (int) out_len); } static int cac_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) @@ -769,7 +769,7 @@ static int cac_restore_security_env(sc_card_t *card, int se_num) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -795,7 +795,7 @@ static int cac_rsa_op(sc_card_t *card, * different sets of APDU's that need to be called), so this call is really a little bit of paranoia */ r = sc_lock(card); if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); rbuf = NULL; @@ -844,7 +844,7 @@ static int cac_rsa_op(sc_card_t *card, free(rbuf); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int cac_compute_signature(sc_card_t *card, @@ -1225,7 +1225,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc file->size = CAC_MAX_SIZE; /* we don't know how big, just give a large size until we can read the file */ *file_out = file; - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -1742,7 +1742,7 @@ static int cac_process_ACA(sc_card_t *card, cac_private_data_t *priv) done: if (val) free(val); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -1847,7 +1847,7 @@ static int cac_init(sc_card_t *card) r = cac_find_and_initialize(card, 1); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } flags = SC_ALGORITHM_RSA_RAW; @@ -1857,7 +1857,7 @@ static int cac_init(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index abfc408c68..86c4fcc7b1 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -140,11 +140,11 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); if (idx > priv->cache_buf_len) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_END_REACHED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED); } len = MIN(count, priv->cache_buf_len-idx); memcpy(buf, &priv->cache_buf[idx], len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); + LOG_FUNC_RETURN(card->ctx, len); } sc_log(card->ctx, @@ -196,7 +196,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, done: if (val) free(val); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -337,7 +337,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc file->size = CAC_MAX_SIZE; /* we don't know how big, just give a large size until we can read the file */ *file_out = file; - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -515,7 +515,7 @@ static int cac_init(sc_card_t *card) r = cac_find_and_initialize(card, 1); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } flags = SC_ALGORITHM_RSA_RAW; @@ -525,7 +525,7 @@ static int cac_init(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static struct sc_card_operations cac_ops; diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index c1ca12016c..c74e3f49a2 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -392,7 +392,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) r = fids; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static void add_acl_entry(sc_file_t *file, int op, u8 byte) @@ -491,7 +491,7 @@ static int cardos_select_file(sc_card_t *card, r = iso_ops->select_file(card, in_path, file); if (r >= 0 && file) parse_sec_attr((*file), (*file)->sec_attr, (*file)->sec_attr_len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int cardos_acl_to_bytes(sc_card_t *card, const sc_file_t *file, @@ -757,7 +757,7 @@ cardos_restore_security_env(sc_card_t *card, int se_num) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -1049,7 +1049,7 @@ cardos_lifecycle_get(sc_card_t *card, int *mode) r = SC_ERROR_INTERNAL; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int @@ -1085,7 +1085,7 @@ cardos_lifecycle_set(sc_card_t *card, int *mode) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int @@ -1113,7 +1113,7 @@ cardos_put_data_oci(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 4fd76f0a40..42b76eab6e 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1041,7 +1041,7 @@ static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2, } err: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -1211,7 +1211,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (idx > priv->obj->length) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_END_REACHED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED); } /* if we've already read the data, just return it */ @@ -1221,7 +1221,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, idx, count); len = MIN(count, priv->obj->length-idx); memcpy(buf, &priv->obj->data[idx], len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); + LOG_FUNC_RETURN(card->ctx, len); } sc_log(card->ctx, @@ -1256,7 +1256,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, done: if (data) free(data); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* COOLKEY driver is read only. NOTE: The applet supports w/r operations, so it's perfectly @@ -1267,7 +1267,7 @@ static int coolkey_write_binary(sc_card_t *card, unsigned int idx, { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } /* initialize getting a list and return the number of elements in the list */ @@ -1383,7 +1383,7 @@ static int coolkey_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* LOG_FUNC_CALLED(card->ctx); memcpy(serial->value, &priv->cuid, sizeof(priv->cuid)); serial->len = sizeof(priv->cuid); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int @@ -1631,7 +1631,7 @@ static int coolkey_get_challenge(sc_card_t *card, u8 *rnd, size_t len) NULL, 0, &rnd, &len, NULL, 0), "Could not get challenge"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, (int) len); + LOG_FUNC_RETURN(card->ctx, (int) len); } static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) @@ -1661,7 +1661,7 @@ static int coolkey_restore_security_env(sc_card_t *card, int se_num) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } #define MAX_COMPUTE_BUF 200 @@ -1930,7 +1930,7 @@ static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil if (file_out) { file = sc_file_new(); if (file == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->path = *in_path; /* this could be like the FCI */ file->type = SC_PATH_TYPE_FILE_ID; @@ -2276,7 +2276,7 @@ static int coolkey_init(sc_card_t *card) r = coolkey_initialize(card); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } card->type = SC_CARD_TYPE_COOLKEY_GENERIC; @@ -2301,7 +2301,7 @@ static int coolkey_init(sc_card_t *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index fe732b3e5a..feea41ad73 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -188,10 +188,10 @@ static int entersafe_gen_random(sc_card_t *card,u8 *buff,size_t size) SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "entersafe gen random failed"); if(apdu.resplen!=size) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); memcpy(buff,rbuf,size); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,r); + LOG_FUNC_RETURN(card->ctx, r); } static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, @@ -217,7 +217,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); EVP_CIPHER_CTX_set_padding(ctx,0); if(keylen == 8) @@ -225,12 +225,12 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, else if (keylen == 16) EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv); else - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); len = apdu->lc; if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){ sc_log(card->ctx, "entersafe encryption error."); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } apdu->lc = len; @@ -544,7 +544,7 @@ static int entersafe_select_aid(sc_card_t *card, { *file_out = sc_file_new(); if(!file_out) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } } else @@ -649,7 +649,7 @@ static int entersafe_select_path(sc_card_t *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->id = (path[pathlen-2] << 8) + path[pathlen-1]; file->path = card->cache.current_path; diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index c6c8fbf09a..d94704218e 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -547,7 +547,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, } file = sc_file_new(); if (file == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); /* We abuse process_fci here even though it's not the real FCI. */ r = card->ops->process_fci(card, file, apdu.resp, apdu.resplen); @@ -699,7 +699,7 @@ static int flex_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00); if (!IS_CYBERFLEX(card)) @@ -1301,7 +1301,7 @@ static int flex_logout(sc_card_t *card) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index ba80e93176..41e662e870 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -234,10 +234,10 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize); if (!p) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } if (datasize > *responselen) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_BUFFER_TOO_SMALL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); } memcpy(response, p, datasize); *responselen = datasize; @@ -324,7 +324,7 @@ static int gids_write_gidsfile_without_cache(sc_card_t* card, u8* masterfile, si SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (datalen > MAX_GIDS_FILE_SIZE) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } r = gids_get_identifiers(card, masterfile, masterfilesize, directory, filename, &fileIdentifier, &dataObjectIdentifier); @@ -343,11 +343,11 @@ static int gids_read_masterfile(sc_card_t* card) { r = gids_get_DO(card, MF_FI, MF_DO, data->masterfile, &data->masterfilesize); if (r<0) { data->masterfilesize = sizeof(data->masterfile); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } if (data->masterfilesize < 1 || data->masterfile[0] != 1) { data->masterfilesize = sizeof(data->masterfile); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } return r; } @@ -529,7 +529,7 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef dataObjectIdentifier = GIDS_PUK_STATUS_OBJECT_IDENTIFIER; break; default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OBJECT_NOT_FOUND); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); } r = gids_get_DO(card, GIDS_APPLET_EFID, dataObjectIdentifier, buffer, &buffersize); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the masterfile"); @@ -554,7 +554,7 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef sc_log(card->ctx, "Pin information for PIN 0x%x: triesleft=%d trieslimit=%d\n", pinreference, (tries_left?*tries_left:-1), (max_tries?*max_tries:-1)); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int gids_match_card(sc_card_t * card) @@ -610,7 +610,7 @@ static int gids_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) if (SC_MAX_SERIALNR < buffersize) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } /* cache serial number */ @@ -621,7 +621,7 @@ static int gids_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) if (serial) memcpy(serial, &card->serialnr, sizeof(*serial)); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } // initialize the driver @@ -634,7 +634,7 @@ static int gids_init(sc_card_t * card) // cache some data in memory data = (struct gids_private_data*) calloc(1, sizeof(struct gids_private_data)); if (!data) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } memset(data, 0, sizeof(struct gids_private_data)); card->drv_data = data; @@ -670,7 +670,7 @@ static int gids_get_crypto_identifier_from_key_ref(sc_card_t *card, const unsign int recordsnum = (int) (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD)); int index = keyref - GIDS_FIRST_KEY_IDENTIFIER; if (index >= recordsnum) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } *cryptoidentifier = 0x00; /* initialize to zero */ if (records[index].wKeyExchangeKeySizeBits == 1024 || records[index].wSigKeySizeBits == 1024) { @@ -709,7 +709,7 @@ static int gids_get_crypto_identifier_from_key_ref(sc_card_t *card, const unsign *cryptoidentifier = GIDS_ECC_521_IDENTIFIER; return SC_SUCCESS; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } // same here @@ -774,7 +774,7 @@ static int gids_set_security_env(sc_card_t *card, } } if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; @@ -997,7 +997,7 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, r = gids_get_DO(card, data->currentEFID, data->currentDO, buffer, &(buffersize)); if (r <0) return r; if (buffersize < 4) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } if (buffer[0] == 1 && buffer[1] == 0) { size_t expectedsize = buffer[2] + buffer[3] * 0x100; @@ -1005,17 +1005,17 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, r = sc_decompress(data->buffer, &(data->buffersize), buffer+4, buffersize-4, COMPRESSION_ZLIB); if (r != SC_SUCCESS) { sc_log(card->ctx, "Zlib error: %d", r); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } if (data->buffersize != expectedsize) { sc_log(card->ctx, "expected size: %"SC_FORMAT_LEN_SIZE_T"u real size: %"SC_FORMAT_LEN_SIZE_T"u", expectedsize, data->buffersize); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } } else { sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] <<8)); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } data->state = GIDS_STATE_READ_DATA_PRESENT; } @@ -1116,7 +1116,7 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { } // use a new key number if (recordsnum > GIDS_MAX_CONTAINER) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_ENOUGH_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } key_info->key_reference = (int) (GIDS_FIRST_KEY_IDENTIFIER + recordsnum); } else { @@ -1124,13 +1124,13 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { size_t i = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER; if (i > GIDS_MAX_CONTAINER) { sc_log(card->ctx, "invalid key ref %d", key_info->key_reference); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (i > recordsnum) { sc_log(card->ctx, "container num is not allowed %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u", i, recordsnum); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } } snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & key_info->key_reference)); @@ -1197,7 +1197,7 @@ static int gids_perform_create_keyfile(sc_card_t *card, u8 keytype, u8 kid, u8 a apdu.datalen = sizeof(sign); apdu.data = sign; } else { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } r = sc_transmit_apdu(card, &apdu); @@ -1214,7 +1214,7 @@ static int gids_perform_create_keyfile(sc_card_t *card, u8 keytype, u8 kid, u8 a r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "ACTIVATE_FILE returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } // perform the creation of the keyfile and its registration in the cmapfile and keymap file @@ -1242,7 +1242,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); if (!algid) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } // masterfile & cmapfile have been refreshed in gids_perform_create_keyfile @@ -1251,7 +1251,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { // sanity check if (containernum > recordnum || containernum > GIDS_MAX_CONTAINER) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); // refresh the key map file keymapbuffersize = sizeof(keymapbuffer); @@ -1259,7 +1259,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { if (r<0) { // the keymap DO should be present if the cmapfile is not empty if (recordnum > 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } // else can be empty if not record keymapbuffersize = 0; @@ -1270,7 +1270,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { sc_log(card->ctx , "keymaprecordnum = %"SC_FORMAT_LEN_SIZE_T"u recordnum = %"SC_FORMAT_LEN_SIZE_T"u", keymaprecordnum, recordnum); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } } @@ -1307,7 +1307,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { records->wSigKeySizeBits = (unsigned short) key_info->modulus_length; keymaprecord->keytype = GIDS_KEY_TYPE_AT_SIGNATURE; } else { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } //the GIDS card must have unique container names @@ -1345,7 +1345,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the cmap file after the container creation"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } // generate a key on an existing container @@ -1367,7 +1367,7 @@ static int gids_generate_key(sc_card_t *card, sc_pkcs15_object_t *object, struct assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); if ((key_info->key_reference > GIDS_FIRST_KEY_IDENTIFIER + GIDS_MAX_CONTAINER) || (kid < GIDS_FIRST_KEY_IDENTIFIER)) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_GENERATE_ASYMECTRIC_KEY_PAIR, 0x00, 0x00); @@ -1386,7 +1386,7 @@ static int gids_generate_key(sc_card_t *card, sc_pkcs15_object_t *object, struct r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, buffer, buffersize); if (buffer) free(buffer); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } // import the key in an existing container @@ -1496,7 +1496,7 @@ static int gids_encode_certificate(sc_card_t *card, u8* source, size_t sourcesiz return SC_ERROR_BUFFER_TOO_SMALL; } if (sourcesize > 0xFFFF) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } // format is: // 2 bytes for compression version @@ -1579,18 +1579,18 @@ static int gids_delete_container_num(sc_card_t *card, size_t containernum) { // sanity check if (containernum >= recordnum || recordnum > GIDS_MAX_CONTAINER) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); // refresh the key map file keymapbuffersize = sizeof(keymapbuffer); r = gids_get_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, &keymapbuffersize); if (r<0) { // the keymap DO should be present if the cmapfile is not empty - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } keymaprecordnum = (keymapbuffersize - 1) / sizeof(struct gids_keymap_record); if (keymaprecordnum != recordnum) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } // update the key map file @@ -1615,7 +1615,7 @@ static int gids_delete_container_num(sc_card_t *card, size_t containernum) { r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the cmap file after the container creation"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } // delete a certificate associated to a container @@ -1640,7 +1640,7 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { // remove the file reference from the masterfile if (cert_info->path.len != 4) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } fileIdentifier = cert_info->path.value[0] * 0x100 + cert_info->path.value[1]; DO = cert_info->path.value[2] * 0x100 + cert_info->path.value[3]; @@ -1656,7 +1656,7 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { } } if (recordnum == (size_t) -1) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } for (i = 1 + (recordnum+1) * sizeof(gids_mf_record_t); i < masterfilebuffersize; i++) { @@ -1717,7 +1717,7 @@ static int gids_initialize_create_file(sc_card_t *card, u8* command, size_t comm r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU2 transmit failed"); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } // used by gids_initialize to set the admin key @@ -1862,7 +1862,7 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } // execute an admin authentication based on a secret key @@ -1873,7 +1873,7 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) // this data comes from the reverse of the GIDS minidriver. static int gids_authenticate_admin(sc_card_t *card, u8* key) { #ifndef ENABLE_OPENSSL - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); #else EVP_CIPHER_CTX *ctx = NULL; int r; @@ -1896,7 +1896,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { // this is CBC instead of ECB cipher = EVP_des_ede3_cbc(); if (!cipher) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } // select the admin key @@ -1938,22 +1938,22 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { // init crypto ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_free(ctx); ctx = NULL; @@ -1972,45 +1972,45 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { if (apdu.resplen != 44) { sc_log(card->ctx, "Expecting a response len of 44 - found %d",(int) apdu.resplen); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } // init crypto ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) { sc_log(card->ctx, "unable to decrypt data"); EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { sc_log(card->ctx, "unable to decrypt final data"); EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } sc_log(card->ctx, "data has been decrypted using the key"); if (memcmp(buffer3, randomR1, 16) != 0) { sc_log(card->ctx, "R1 doesn't match"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (memcmp(buffer3 + 16, randomR2, 16) != 0) { sc_log(card->ctx, "R2 doesn't match"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (buffer[39] != 0x80) { sc_log(card->ctx, "Padding not found"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } EVP_CIPHER_CTX_free(ctx); ctx = NULL; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); #endif } diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 88590aafb4..982f910114 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -1572,7 +1572,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 79c49350dc..26db4d1728 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -212,7 +212,7 @@ static int incrypto34_list_files(sc_card_t *card, u8 *buf, size_t buflen) end: r = fids; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static void add_acl_entry(sc_file_t *file, int op, u8 byte) @@ -311,7 +311,7 @@ static int incrypto34_select_file(sc_card_t *card, r = iso_ops->select_file(card, in_path, file); if (r >= 0 && file) parse_sec_attr((*file), (*file)->sec_attr, (*file)->sec_attr_len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) @@ -403,7 +403,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) /* FIXME: if this is a DF and there's an AID, set it here * using PUT_DATA_FCI */ -out: SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); +out: LOG_FUNC_RETURN(card->ctx, r); } /* @@ -424,7 +424,7 @@ static int incrypto34_restore_security_env(sc_card_t *card, int se_num) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -480,7 +480,7 @@ static int incrypto34_set_security_env(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -619,7 +619,7 @@ incrypto34_lifecycle_get(sc_card_t *card, int *mode) r = SC_ERROR_INTERNAL; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int @@ -647,7 +647,7 @@ incrypto34_put_data_oci(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 73412383f5..04bfec687e 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -478,7 +478,7 @@ static int itacns_select_file(sc_card_t *card, parse_sec_attr((*file), (*file)->sec_attr, (*file)->sec_attr_len); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index 85feddc6a2..1e5643b23b 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -610,7 +610,7 @@ static int jcop_set_security_env(sc_card_t *card, assert(card != NULL && env != NULL); if (se_num) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); if (drvdata->selected == SELECT_MF || drvdata->selected == SELECT_EFDIR) { drvdata->invalid_senv=1; diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index a8d11160b4..a696af71d6 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -309,7 +309,7 @@ static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) int rv; if (!serial) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); /* Get smart card serial number */ card->cla = 0x80; @@ -327,7 +327,7 @@ static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) if (SC_MAX_SERIALNR < apdu.resplen) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } /* cache serial number */ card->serialnr.len = apdu.resplen; @@ -337,7 +337,7 @@ static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) if (serial) memcpy(serial, &card->serialnr, sizeof(*serial)); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index d110aa5987..2d7b1cb26a 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -409,7 +409,7 @@ static int load_special_files(sc_card_t * card) return 0; /* yes. */ clear_special_files(dfi); if (!dfi) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); /* Read rule file. Note that we bypass our cache here. */ r = select_part(card, MCRD_SEL_EF, EF_Rule, NULL); @@ -427,7 +427,7 @@ static int load_special_files(sc_card_t * card) } else { rule = malloc(sizeof *rule + r); if (!rule) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); rule->recno = recno; rule->datalen = r; memcpy(rule->data, recbuf, r); @@ -458,7 +458,7 @@ static int load_special_files(sc_card_t * card) } else { keyd = malloc(sizeof *keyd + r); if (!keyd) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); keyd->recno = recno; keyd->datalen = r; memcpy(keyd->data, recbuf, r); @@ -794,7 +794,7 @@ do_select(sc_card_t * card, u8 kind, if (file) { *file = sc_file_new(); if (!*file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); (*file)->type = SC_FILE_TYPE_DF; return SC_SUCCESS; } @@ -803,7 +803,7 @@ do_select(sc_card_t * card, u8 kind, if (p2 == 0x04 && apdu.resp[0] == 0x62) { *file = sc_file_new(); if (!*file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); /* EstEID v3.0 cards are buggy and sometimes return a double 0x62 tag */ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 && apdu.resp[2] == 0x62) process_fcp(card, *file, apdu.resp + 4, apdu.resp[3]); @@ -815,7 +815,7 @@ do_select(sc_card_t * card, u8 kind, if (p2 != 0x0C && apdu.resp[0] == 0x6F) { *file = sc_file_new(); if (!*file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); if (apdu.resp[1] <= apdu.resplen) process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index a41ce15331..ab02be76a8 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -337,7 +337,7 @@ static int miocos_get_acl(sc_card_t *card, sc_file_t *file) seq = sc_asn1_skip_tag(card->ctx, &seq, &left, SC_ASN1_SEQUENCE | SC_ASN1_CONS, &left); if (seq == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to process reply"); for (i = 1; i < 15; i++) { int j; @@ -415,7 +415,7 @@ static int miocos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } r = sc_select_file(card, path, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select file to be deleted"); @@ -437,11 +437,11 @@ static int miocos_create_ac(sc_card_t *card, size_t sendsize; if (ac->max_tries > 15) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); switch (ac->type) { case SC_CARDCTL_MIOCOS_AC_PIN: if (ac->max_unblock_tries > 15) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); miocos_type = 0x01; sbuf[0] = (ac->max_tries << 4) | ac->max_tries; sbuf[1] = 0xFF; /* FIXME... */ diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index bc660d2f3e..d62317a075 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -205,7 +205,7 @@ static int muscle_read_binary(sc_card_t *card, unsigned int idx, u8* buf, size_t mscfs_file_t *file; r = mscfs_check_selection(fs, -1); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); file = &fs->cache.array[fs->currentFileIndex]; objectId = file->objectId; /* memcpy(objectId.id, file->objectId.id, 4); */ @@ -215,7 +215,7 @@ static int muscle_read_binary(sc_card_t *card, unsigned int idx, u8* buf, size_t oid[2] = oid[3] = 0; } r = msc_read_object(card, objectId, idx, buf, count); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf, size_t count, unsigned long flags) @@ -227,7 +227,7 @@ static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf u8* oid = objectId.id; r = mscfs_check_selection(fs, -1); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); file = &fs->cache.array[fs->currentFileIndex]; objectId = file->objectId; @@ -240,7 +240,7 @@ static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf if(file->size < idx + count) { int newFileSize = idx + count; u8* buffer = malloc(newFileSize); - if(buffer == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if(buffer == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); r = msc_read_object(card, objectId, 0, buffer, file->size); /* TODO: RETRIEVE ACLS */ @@ -255,7 +255,7 @@ static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf file->size = newFileSize; update_bin_free_buffer: free(buffer); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } else { r = msc_update_object(card, objectId, idx, buf, count); } @@ -378,7 +378,7 @@ static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** f /* Check if its the right type */ if(requiredType >= 0 && requiredType != file_data->ef) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } oid = file_data->objectId.id; /* Is it a file or directory */ @@ -460,7 +460,7 @@ static int muscle_init(sc_card_t *card) card->name = "MuscleApplet"; card->drv_data = malloc(sizeof(muscle_private_t)); if(!card->drv_data) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } memset(card->drv_data, 0, sizeof(muscle_private_t)); priv = MUSCLE_DATA(card); @@ -468,7 +468,7 @@ static int muscle_init(sc_card_t *card) priv->fs = mscfs_new(); if(!priv->fs) { free(card->drv_data); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } priv->fs->udata = card; priv->fs->listFile = _listFile; diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index c8e981f5c0..2c22500246 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -763,7 +763,7 @@ static int npa_pin_cmd(struct sc_card *card, } err: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int npa_logout(sc_card_t *card) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 6ca49f1a42..97db1490e3 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1348,7 +1348,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); p2 = 0; if (args->len == 24) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index c86f77e060..5fead22272 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -57,9 +57,9 @@ static int rtecp_match_card(sc_card_t *card) i = _sc_match_atr(card, rtecp_atrs, &card->type); if (i >= 0) { card->name = rtecp_atrs[i].name; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 1); + LOG_FUNC_RETURN(card->ctx, 1); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0); + LOG_FUNC_RETURN(card->ctx, 0); } static int rtecp_init(sc_card_t *card) @@ -261,7 +261,7 @@ static int rtecp_select_file(sc_card_t *card, case SC_PATH_TYPE_DF_NAME: case SC_PATH_TYPE_FROM_CURRENT: case SC_PATH_TYPE_PARENT: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } assert(iso_ops && iso_ops->select_file); file_out_copy = file_out; @@ -352,7 +352,7 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, { free(buf); free(buf_out); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } for (i = 0; i < data_len; ++i) @@ -438,7 +438,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, sc_log(card->ctx, "newlen = %"SC_FORMAT_LEN_SIZE_T"u\n", newlen); if (newlen > 0xFFFF) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); if (type == SC_AC_CHV && old && oldlen != 0) { r = sc_verify(card, type, ref_qualifier, old, oldlen, tries_left); @@ -456,7 +456,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, buf_length = (2 + sizeof(rsf_length)) + newlen + 2*(transmits_num); p = buf = (u8 *)malloc(buf_length); if (buf == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); buf_end = buf + buf_length; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); @@ -575,13 +575,13 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, ""); if (apdu.resplen <= 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); /* save first file(dir) ID */ tag = sc_asn1_find_tag(card->ctx, apdu.resp + 2, apdu.resplen - 2, 0x83, &taglen); if (!tag || taglen != sizeof(previd)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); memcpy(previd, tag, sizeof(previd)); if (len + sizeof(previd) <= buflen) @@ -593,7 +593,7 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) tag = sc_asn1_find_tag(card->ctx, apdu.resp + 2, apdu.resplen - 2, 0x82, &taglen); if (!tag || taglen != 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); if (tag[0] == 0x38) { /* Select parent DF of the current DF */ @@ -632,7 +632,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) break; case SC_CARDCTL_GET_SERIALNR: if (!serial) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0x81); apdu.resp = buf; apdu.resplen = sizeof(buf); @@ -641,7 +641,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) break; case SC_CARDCTL_RTECP_GENERATE_KEY: if (!genkey_data) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x46, 0x80, genkey_data->key_id); apdu.resp = buf; @@ -656,7 +656,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) default: sc_log(card->ctx, "request = 0x%lx\n", request); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); @@ -731,7 +731,7 @@ static int rtecp_construct_fci(sc_card_t *card, const sc_file_t *file, break; case SC_FILE_TYPE_INTERNAL_EF: default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } buf[1] = 0; sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p); diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 57d7f43ff5..6fcea6c51b 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -95,7 +95,7 @@ static int rutoken_finish(sc_card_t *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); assert(card->drv_data); free(card->drv_data); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int rutoken_match_card(sc_card_t *card) @@ -104,9 +104,9 @@ static int rutoken_match_card(sc_card_t *card) if (_sc_match_atr(card, rutoken_atrs, &card->type) >= 0) { sc_log(card->ctx, "ATR recognized as Rutoken\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 1); + LOG_FUNC_RETURN(card->ctx, 1); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0); + LOG_FUNC_RETURN(card->ctx, 0); } static int token_init(sc_card_t *card, const char *card_name) @@ -136,7 +136,7 @@ static int rutoken_init(sc_card_t *card) if (ret != SC_SUCCESS) { ret = SC_ERROR_INVALID_CARD; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static const struct sc_card_error rutoken_errors[] = { @@ -265,13 +265,13 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, ""); if (apdu.resplen <= 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); /* save first file(dir) ID */ tag = sc_asn1_find_tag(card->ctx, apdu.resp + 2, apdu.resplen - 2, 0x83, &taglen); if (!tag || taglen != sizeof(previd)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); memcpy(previd, tag, sizeof(previd)); if (len + sizeof(previd) <= buflen) @@ -283,7 +283,7 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) tag = sc_asn1_find_tag(card->ctx, apdu.resp + 2, apdu.resplen - 2, 0x82, &taglen); if (!tag || taglen != 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); if (tag[0] == 0x38) { /* Select parent DF of the current DF */ @@ -301,7 +301,7 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.data = previd; apdu.datalen = sizeof(previd); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len); + LOG_FUNC_RETURN(card->ctx, len); } static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) @@ -377,7 +377,7 @@ static int rutoken_select_file(sc_card_t *card, { case SC_PATH_TYPE_FILE_ID: if (pathlen != 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); break; case SC_PATH_TYPE_PATH: if (pathlen >= 2 && memcmp(path, "\x3F\x00", 2) == 0) @@ -392,9 +392,9 @@ static int rutoken_select_file(sc_card_t *card, case SC_PATH_TYPE_DF_NAME: case SC_PATH_TYPE_FROM_CURRENT: case SC_PATH_TYPE_PARENT: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } swap_pair(path, pathlen); apdu.lc = pathlen; @@ -417,16 +417,16 @@ static int rutoken_select_file(sc_card_t *card, SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, ""); if (apdu.resplen > 0 && apdu.resp[0] != 0x62) /* Tag 0x62 - FCP */ - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file = sc_file_new(); if (file == NULL) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->path = *in_path; if (card->ops->process_fci == NULL) { sc_file_free(file); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } if (apdu.resplen > 1 && apdu.resplen >= (size_t)apdu.resp[1] + 2) { @@ -443,7 +443,7 @@ static int rutoken_select_file(sc_card_t *card, assert(file_out); *file_out = file; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_process_fci(struct sc_card *card, sc_file_t *file, @@ -470,7 +470,7 @@ static int rutoken_process_fci(struct sc_card *card, sc_file_t *file, sc_log(card->ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); } } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, @@ -511,7 +511,7 @@ static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, break; case SC_FILE_TYPE_INTERNAL_EF: default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } buf[1] = 0; sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p); @@ -609,7 +609,7 @@ static int rutoken_create_file(sc_card_t *card, sc_file_t *file) } assert(iso_ops && iso_ops->create_file); ret = iso_ops->create_file(card, file); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) @@ -621,7 +621,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) if (!path || path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) { sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (path->len == sizeof(sbuf)) { @@ -635,7 +635,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) else /* No file ID given: means currently selected file */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2)); + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } static int rutoken_verify(sc_card_t *card, unsigned int type, int ref_qualifier, @@ -679,7 +679,7 @@ static int rutoken_verify(sc_card_t *card, unsigned int type, int ref_qualifier, if (ret == SC_ERROR_PIN_CODE_INCORRECT) *tries_left = (int)(apdu.sw2 & 0x0f); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_logout(sc_card_t *card) @@ -698,7 +698,7 @@ static int rutoken_logout(sc_card_t *card) ret = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_change_reference_data(sc_card_t *card, unsigned int type, @@ -721,7 +721,7 @@ static int rutoken_change_reference_data(sc_card_t *card, unsigned int type, ret = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, @@ -747,7 +747,7 @@ static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, ret = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_restore_security_env(sc_card_t *card, int se_num) @@ -760,7 +760,7 @@ static int rutoken_restore_security_env(sc_card_t *card, int se_num) ret = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_set_security_env(sc_card_t *card, @@ -774,18 +774,18 @@ static int rutoken_set_security_env(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (!env) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); senv = (auth_senv_t*)card->drv_data; if (!senv) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); if (env->algorithm != SC_ALGORITHM_GOST) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); senv->algorithm = SC_ALGORITHM_GOST; if (env->key_ref_len != 1) { sc_log(card->ctx, "No or invalid key reference\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } data[2] = env->key_ref[0]; /* select component */ @@ -804,13 +804,13 @@ static int rutoken_set_security_env(sc_card_t *card, apdu.p2 = 0xAA; break; default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } /* set SE */ ret = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static void rutoken_set_do_hdr(u8 *data, size_t *data_len, sc_DOHdrV2_t *hdr) @@ -1128,13 +1128,13 @@ static int rutoken_compute_signature(struct sc_card *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (!senv) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); if (senv->algorithm == SC_ALGORITHM_GOST) ret = rutoken_compute_mac_gost(card, data, datalen, out, outlen); else ret = SC_ERROR_NOT_SUPPORTED; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static int rutoken_get_challenge(sc_card_t *card, u8 *rnd, size_t len) @@ -1264,7 +1264,7 @@ static int rutoken_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) break; } } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); + LOG_FUNC_RETURN(card->ctx, ret); } static struct sc_card_driver* get_rutoken_driver(void) diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index f78fd9da70..a1facab0c9 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -1003,7 +1003,7 @@ static int setcos_putdata(struct sc_card *card, struct sc_cardctl_setcos_data_ob r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "PUT_DATA returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* Read internal data, e.g. get RSA public key */ @@ -1039,7 +1039,7 @@ static int setcos_getdata(struct sc_card *card, struct sc_cardctl_setcos_data_ob else data_obj->DataLen = apdu.resplen; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* Generate or store a key */ @@ -1090,7 +1090,7 @@ static int setcos_generate_store_key(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "STORE/GENERATE_KEY returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int setcos_activate_file(sc_card_t *card) @@ -1108,7 +1108,7 @@ static int setcos_activate_file(sc_card_t *card) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "ACTIVATE_FILE returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int setcos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index d7b865166a..1e34ef6717 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -476,7 +476,7 @@ static int starcos_select_aid(sc_card_t *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->type = SC_FILE_TYPE_DF; file->ef_structure = SC_FILE_EF_UNKNOWN; file->path.len = 0; @@ -594,7 +594,7 @@ static int starcos_select_fid(sc_card_t *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->id = (id_hi << 8) + id_lo; file->path = card->cache.current_path; @@ -763,7 +763,7 @@ static int starcos_select_file(sc_card_t *card, if (file_out) { sc_file_t *file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->id = (path[pathlen-2] << 8) + path[pathlen-1]; file->path = card->cache.current_path; diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 8ab1e67951..d9db4aede0 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -402,7 +402,7 @@ static int tcos_select_file(sc_card_t *card, } file = sc_file_new(); - if (file == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if (file == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); *file_out = file; file->path = *in_path; @@ -458,7 +458,7 @@ static int tcos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } sbuf[0] = path->value[0]; sbuf[1] = path->value[1]; @@ -488,7 +488,7 @@ static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, data=(tcos_data *)card->drv_data; if (se_num || (env->operation!=SC_SEC_OPERATION_DECIPHER && env->operation!=SC_SEC_OPERATION_SIGN)){ - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } if(!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) sc_log(ctx, diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5c3bacdcd8..ad04774d25 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -834,13 +834,13 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) r = sc_lock(card); if (r != SC_SUCCESS) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); while (len > 0 && retry > 0) { r = card->ops->get_challenge(card, rnd, len); if (r < 0) { sc_unlock(card); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } if (r > 0) { diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index f3bae4839e..f69f480edc 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -784,7 +784,7 @@ iso7816_delete_file(struct sc_card *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) { sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (path->len == 2) { @@ -1217,7 +1217,7 @@ static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, si else r = apdu.resplen; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 1252f6e985..2715a4be3a 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -302,11 +302,11 @@ int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe } else if(apdu.sw1 == 0x63) { /* Invalid auth */ if(tries) *tries = apdu.sw2 & 0x0F; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x9C && apdu.sw2 == 0x02) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x69 && apdu.sw2 == 0x83) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_AUTH_METHOD_BLOCKED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_AUTH_METHOD_BLOCKED); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_PIN_CODE_INCORRECT); @@ -347,11 +347,11 @@ int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukL } else if(apdu.sw1 == 0x63) { /* Invalid auth */ if(tries) *tries = apdu.sw2 & 0x0F; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x9C && apdu.sw2 == 0x02) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x69 && apdu.sw2 == 0x83) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_AUTH_METHOD_BLOCKED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_AUTH_METHOD_BLOCKED); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_PIN_CODE_INCORRECT); @@ -389,11 +389,11 @@ int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe } else if(apdu.sw1 == 0x63) { /* Invalid auth */ if(tries) *tries = apdu.sw2 & 0x0F; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x9C && apdu.sw2 == 0x02) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PIN_CODE_INCORRECT); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } else if(apdu.sw1 == 0x69 && apdu.sw2 == 0x83) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_AUTH_METHOD_BLOCKED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_AUTH_METHOD_BLOCKED); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_PIN_CODE_INCORRECT); @@ -441,7 +441,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short assert(dataLength < MSC_MAX_READ - 9); /* Output buffer doesn't seem to operate as desired.... nobody can read/delete */ buffer = malloc(len); - if(!buffer) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if(!buffer) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); ptr = buffer; ushort2bebytes(ptr, dataLength); ptr+=2; @@ -457,7 +457,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short if(location == 1) { u8* outputBuffer = malloc(dataLength + 2); - if(outputBuffer == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if(outputBuffer == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); apdu.le = dataLength + 2; apdu.resp = outputBuffer; apdu.resplen = dataLength + 2; @@ -479,9 +479,9 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } } else { if(apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { @@ -491,15 +491,15 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } r = msc_read_object(card, inputId, 2, outputData, dataLength); if(r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); msc_delete_object(card, inputId,0); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } } @@ -552,9 +552,9 @@ int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int alg sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } int msc_extract_key(sc_card_t *card, @@ -579,9 +579,9 @@ int msc_extract_key(sc_card_t *card, sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } int msc_extract_rsa_public_key(sc_card_t *card, @@ -596,25 +596,25 @@ int msc_extract_rsa_public_key(sc_card_t *card, int fileLocation = 1; r = msc_extract_key(card, keyLocation); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); /* Read keyType, keySize, and what should be the modulus size */ r = msc_read_object(card, inputId, fileLocation, buffer, 5); fileLocation += 5; - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); - if(buffer[0] != MSC_RSA_PUBLIC) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED); + if(buffer[0] != MSC_RSA_PUBLIC) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); *modLength = (buffer[3] << 8) | buffer[4]; /* Read the modulus and the exponent length */ if (*modLength + 2 > sizeof buffer) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); r = msc_read_object(card, inputId, fileLocation, buffer, *modLength + 2); fileLocation += *modLength + 2; - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); *modulus = malloc(*modLength); - if(!*modulus) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if(!*modulus) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(*modulus, buffer, *modLength); *expLength = (buffer[*modLength] << 8) | buffer[*modLength + 1]; if (*expLength > sizeof buffer) @@ -622,12 +622,12 @@ int msc_extract_rsa_public_key(sc_card_t *card, r = msc_read_object(card, inputId, fileLocation, buffer, *expLength); if(r < 0) { free(*modulus); *modulus = NULL; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } *exponent = malloc(*expLength); if(!*exponent) { free(*modulus); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } memcpy(*exponent, buffer, *expLength); return 0; @@ -685,9 +685,9 @@ int msc_compute_crypt_init(sc_card_t *card, sc_log(card->ctx, "init: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } int msc_compute_crypt_final( @@ -735,9 +735,9 @@ int msc_compute_crypt_final( sc_log(card->ctx, "final: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } /* Stream data to the card through file IO */ @@ -808,7 +808,7 @@ static int msc_compute_crypt_final_object( /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } int msc_compute_crypt(sc_card_t *card, @@ -839,7 +839,7 @@ int msc_compute_crypt(sc_card_t *card, outPtr, toSend, &received); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); left -= toSend; inPtr += toSend; outPtr += received; @@ -854,7 +854,7 @@ int msc_compute_crypt(sc_card_t *card, outPtr, toSend, &received); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); } else { /* Data is too big: use objects */ r = msc_compute_crypt_final_object(card, keyLocation, @@ -862,7 +862,7 @@ int msc_compute_crypt(sc_card_t *card, outPtr, toSend, &received); - if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + if(r < 0) LOG_FUNC_RETURN(card->ctx, r); } outPtr += received; @@ -912,7 +912,7 @@ int msc_import_key(sc_card_t *card, + data->dp1Length + data->dq1Length; } buffer = malloc(bufferSize); - if(!buffer) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + if(!buffer) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); p = buffer; *p = 0x00; p++; /* Encoding plain */ *p = data->keyType; p++; /* RSA_PRIVATE */ @@ -972,11 +972,11 @@ int msc_import_key(sc_card_t *card, } /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_CARD_CMD_FAILED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } #undef CPYVAL diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c index 70e4792434..e641858deb 100644 --- a/src/libopensc/p15card-helper.c +++ b/src/libopensc/p15card-helper.c @@ -61,7 +61,7 @@ int sc_pkcs15emu_initialize_objects(sc_pkcs15_card_t *p15card, p15data_items *it r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } return SC_SUCCESS; } @@ -212,7 +212,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { X509_free(cert_data); cert_data = NULL; } - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } int sc_pkcs15emu_initialize_certificates(sc_pkcs15_card_t *p15card, p15data_items* items) { @@ -307,7 +307,7 @@ int sc_pkcs15emu_initialize_pins(sc_pkcs15_card_t *p15card, p15data_items* items pin_obj.flags = pins[i].obj_flags; if(0 > (r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info))) - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } return SC_SUCCESS; } @@ -320,7 +320,7 @@ int sc_pkcs15emu_initialize_private_keys(sc_pkcs15_card_t *p15card, p15data_item for (i = 0; prkeys[i].label; i++) { r = add_private_key(p15card, &prkeys[i], 0, 0); if (r < 0) - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } return SC_SUCCESS; } @@ -333,7 +333,7 @@ int sc_pkcs15emu_initialize_public_keys(sc_pkcs15_card_t *p15card, p15data_items for (i = 0; keys[i].label; i++) { r = add_public_key(p15card, &keys[i], 0, 0); if (r < 0) - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 4010e05b32..5f4a8994d0 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -256,12 +256,12 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* get the ACA path in case it needs to be selected before PIN verify */ r = sc_card_ctl(card, SC_CARDCTL_CAC_GET_ACA_PATH, &pin_info.path); if (r < 0) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* set other objects */ @@ -274,14 +274,14 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_GET_NEXT_GENERIC_OBJECT, &obj_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); memset(&obj_obj, 0, sizeof(obj_obj)); memcpy(obj_obj.label, obj_info.app_label, sizeof(obj_obj.label)); r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS, &count); LOG_TEST_RET(card->ctx, r, "Can not finalize generic objects."); @@ -433,13 +433,13 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) fail: sc_pkcs15_free_certificate(cert_out); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); /* should not fail */ + LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); LOG_TEST_RET(card->ctx, r, "Can not finalize cert objects."); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 58826ed8c4..f0ec8f48e8 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -534,7 +534,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* set other objects */ @@ -556,7 +556,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_GET_NEXT_OBJECT, &coolkey_obj); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); memset(&obj_obj, 0, sizeof(obj_obj)); diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index d1d389d458..47573bb592 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -133,7 +133,7 @@ int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_DATA_OBJECT; obj->data = malloc(sizeof(info)); if (obj->data == NULL) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 8c126e46ae..d744d8074d 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -688,7 +688,7 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file rv = sc_pkcs15emu_add_x509_cert(p15card, &cobj, &cinfo); - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(p15card->card->ctx, rv); } @@ -903,7 +903,7 @@ sc_pkcs15emu_oberthur_add_data(struct sc_pkcs15_card *p15card, rv = sc_pkcs15emu_add_data_object(p15card, &dobj, &dinfo); - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(p15card->card->ctx, rv); } @@ -1043,8 +1043,8 @@ oberthur_detect_card(struct sc_pkcs15_card * p15card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (p15card->card->type != SC_CARD_TYPE_OBERTHUR_64K) - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_CARD); - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_WRONG_CARD); + LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 459230b50b..5237e00658 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -199,7 +199,7 @@ sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj obj->data = malloc(sizeof(info)); if (obj->data == NULL) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_SUCCESS); diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index efd4407d0e..858f914f20 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -676,7 +676,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); /* TODO * PIV key 9C requires the pin verify be done just before any * crypto operation using the key. @@ -969,7 +969,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } @@ -1095,7 +1095,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); /* should not fail */ + LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ ckis[i].pubkey_found = 1; break; @@ -1111,7 +1111,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); /* should not fail */ + LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ ckis[i].pubkey_found = 1; break; default: @@ -1196,12 +1196,12 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); } sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present ,prkey_info.usage); if (r < 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } p15card->ops.get_guid = piv_get_guid; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index 4b94337f2a..db08465b2c 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -258,7 +258,7 @@ static int ctapi_connect(sc_reader_t *reader) return SC_ERROR_TRANSMIT_FAILED; } if (lr < 2) - SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(reader->ctx, SC_ERROR_INTERNAL); lr -= 2; if (lr > SC_MAX_ATR_SIZE) return SC_ERROR_INTERNAL; diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 46bbccc92e..54cd1d461e 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -154,7 +154,7 @@ gpk_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) */ } - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } /* @@ -190,7 +190,7 @@ gpk_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (current > preferred) return SC_ERROR_TOO_MANY_OBJECTS; auth_info->attrs.pin.reference = preferred; - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 0); + LOG_FUNC_RETURN(p15card->card->ctx, 0); } /* @@ -263,7 +263,7 @@ gpk_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, if (r < 0) return r; - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } @@ -307,7 +307,7 @@ gpk_lock_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, r = gpk_lock(p15card->card, pinfile, SC_AC_OP_WRITE); sc_file_free(parent); - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } /* @@ -386,7 +386,7 @@ gpk_init_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, r = gpk_lock_pinfile(profile, p15card, pinfile); out: sc_file_free(pinfile); - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(p15card->card->ctx, r); } /* diff --git a/src/pkcs15init/pkcs15-miocos.c b/src/pkcs15init/pkcs15-miocos.c index d6fe7304f9..d1ae67b01d 100644 --- a/src/pkcs15init/pkcs15-miocos.c +++ b/src/pkcs15init/pkcs15-miocos.c @@ -187,7 +187,7 @@ miocos_create_pin(struct sc_profile *profile, sc_pkcs15_card_t *p15card, struct r = sc_card_ctl(p15card->card, SC_CARDCTL_MIOCOS_CREATE_AC, &ac_info); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Miocos create AC failed"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -223,7 +223,7 @@ miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = sc_pkcs15init_create_file(profile, p15card, file); sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -261,7 +261,7 @@ miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = miocos_update_private_key(profile, p15card->card, rsa); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } static struct sc_pkcs15init_operations sc_pkcs15init_miocos_operations = { diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index a29010f59e..fad869c686 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -190,7 +190,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_file_free(ofile); } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -231,7 +231,7 @@ awp_update_blob(struct sc_context *ctx, *blob = pp; - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -261,7 +261,7 @@ awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, int } *(buff + 14 + ii*2 + mm) = (unsigned char)'}'; - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -279,7 +279,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * buff = malloc(list_file->record_length); if (!buff) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memset(buff, 0, list_file->record_length); @@ -287,7 +287,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * if (rv < 0) { free(buff); sc_log(ctx, "Cannot create container"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } *(buff + 0) = (acc->pubkey_id >> 8) & 0xFF; @@ -305,7 +305,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * rv = sc_append_record(p15card->card, buff, list_file->record_length, SC_RECORD_BY_REC_NR); free(buff); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -336,7 +336,7 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_file_free(file); sc_file_free(clist); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -358,7 +358,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p buff = malloc(list_file->record_length); if (!buff) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memset(buff, 0, list_file->record_length); @@ -372,7 +372,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p } if (rv < 0) { free(buff); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } switch (type) { @@ -400,7 +400,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p break; default: free(buff); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCORRECT_PARAMETERS); + LOG_FUNC_RETURN(ctx, SC_ERROR_INCORRECT_PARAMETERS); } if (rec > list_file->record_count) { @@ -416,7 +416,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p } free(buff); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -540,7 +540,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_file_free(file); if (list) free(list); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -624,7 +624,7 @@ awp_set_certificate_info (struct sc_pkcs15_card *p15card, if (blob) free(blob); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -752,7 +752,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil sc_file_free(obj_file); sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -825,7 +825,7 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj done: ERR_load_ERR_strings(); ERR_load_crypto_strings(); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -911,7 +911,7 @@ awp_set_key_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, st if (blob) free(blob); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -1063,7 +1063,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob if (mem) BIO_free(mem); if (buff) OPENSSL_free(buff); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -1122,7 +1122,7 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob if (di->app.len) { di->app.value = (unsigned char *)strdup(data_info->app_label); if (!di->app.value) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } r = sc_asn1_encode_object_id(&buf, &buflen, &data_info->app_oid); @@ -1140,7 +1140,7 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob memcpy(di->oid.value + 2, buf, buflen); free(buf); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -1204,7 +1204,7 @@ awp_set_data_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, if (blob) free(blob); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -1254,7 +1254,7 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, /* Flags */ if (buf_len - offs < 2) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); ikey->flags = *(buf + offs) * 0x100 + *(buf + offs + 1); offs += 2; @@ -1262,14 +1262,14 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->label); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: label"); if (!len) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; /* Ignore Key ID */ len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: ID"); if (!len) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; while (*(buf + offs) == '0') @@ -1279,7 +1279,7 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->subject); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: subject"); if (!len) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; /* Modulus */ @@ -1291,16 +1291,16 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, len = awp_get_lv(ctx, buf, buf_len, offs, 256, &ikey->modulus); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: modulus"); if (!len) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; /* Exponent */ len = awp_get_lv(ctx, buf, buf_len, offs, 1, &ikey->exponent); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: exponent"); if (!len) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -1359,7 +1359,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_file_free(key_file); sc_file_free(info_file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1411,7 +1411,7 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_file_free(info_file); sc_file_free(obj_file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1499,7 +1499,7 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p awp_free_cert_info(&icert); awp_free_key_info(&ikey); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1549,7 +1549,7 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p err: awp_free_key_info(&ikey); sc_file_free(info_file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1591,7 +1591,7 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_file_free(info_file); sc_file_free(obj_file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1604,7 +1604,7 @@ awp_update_df_create(struct sc_pkcs15_card *p15card, struct sc_profile *profile, LOG_FUNC_CALLED(ctx); if (!object) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); switch (object->type) { case SC_PKCS15_TYPE_AUTH_PIN: @@ -1626,7 +1626,7 @@ awp_update_df_create(struct sc_pkcs15_card *p15card, struct sc_profile *profile, SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type"); } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1707,7 +1707,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, sc_file_free(clist); sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1782,7 +1782,7 @@ awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile * sc_file_free(lst); sc_file_free(lst_file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1816,7 +1816,7 @@ awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot remove object"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1850,7 +1850,7 @@ awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot remove object"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1884,7 +1884,7 @@ awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot remove object"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1915,7 +1915,7 @@ awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannot remove object"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -1928,7 +1928,7 @@ awp_update_df_delete(struct sc_pkcs15_card *p15card, struct sc_profile *profile, LOG_FUNC_CALLED(ctx); if (!object) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); switch (object->type) { case SC_PKCS15_TYPE_CERT_X509: diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index aaaf25e524..6b690867de 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -113,7 +113,7 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile err: sc_file_free(file); free(buffer); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -152,7 +152,7 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = sc_delete_file(p15card->card, &path); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -214,7 +214,7 @@ cosm_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) if (rv == SC_ERROR_FILE_NOT_FOUND) rv = 0; - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -257,7 +257,7 @@ cosm_create_dir(struct sc_profile *profile, struct sc_pkcs15_card *p15card, rv = cosm_write_tokeninfo(p15card, profile, NULL, COSM_TOKEN_FLAG_TOKEN_INITIALIZED | COSM_TOKEN_FLAG_PRN_GENERATION); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -328,7 +328,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 sc_file_free(file); } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -367,7 +367,7 @@ cosm_update_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "cosm_update_pin() failed to update tokeninfo"); } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -408,7 +408,7 @@ cosm_select_pin_reference(struct sc_profile *profile, struct sc_pkcs15_card *p15 pin_attrs->reference |= 0x80; } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -467,7 +467,7 @@ cosm_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Update PIN failed"); } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -529,7 +529,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, if (sc_profile_get_file(profile, _template, &file) < 0) { sc_log(card->ctx, "Profile doesn't define %s template '%s'", desc, _template); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } file->id |= (num & 0xFF); @@ -543,7 +543,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, file->size, file->type, file->ef_structure, file->id); *out = file; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -558,11 +558,11 @@ cosm_get_temporary_public_key_file(struct sc_card *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (!pubkey_file || !prvkey_file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); file = sc_file_new(); if (!file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->status = SC_FILE_STATUS_ACTIVATED; file->type = SC_FILE_TYPE_INTERNAL_EF; @@ -587,7 +587,7 @@ cosm_get_temporary_public_key_file(struct sc_card *card, *pubkey_file = file; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(card->ctx, rv); } @@ -669,7 +669,7 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_file_free(tmpf); sc_file_free(prkf); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -719,7 +719,7 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, err: sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } @@ -751,7 +751,7 @@ cosm_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "No authorisation to store private key"); if (key_info->id.len > sizeof(update_info.id)) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); memset(&update_info, 0, sizeof(update_info)); update_info.type = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT; @@ -765,7 +765,7 @@ cosm_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index bbf9f91601..de97f7935e 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -153,7 +153,7 @@ static int rtecp_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p else pin_ref = RTECP_USER_PIN_REF; if (auth_info->attrs.pin.reference != pin_ref) - SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_SUPPORTED); return SC_SUCCESS; } @@ -225,7 +225,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, file = sc_file_new(); if (!file) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); file->id = auth_info->attrs.pin.reference; file->size = pin_len; assert(sizeof(sec)/sizeof(sec[0]) > 2); @@ -248,7 +248,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (r == SC_SUCCESS) r = sc_change_reference_data(p15card->card, SC_AC_CHV, auth_info->attrs.pin.reference, NULL, 0, pin, pin_len, NULL); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } /* @@ -350,7 +350,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, file = sc_file_new(); if (!file) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); file->id = key_info->key_reference; r = sc_file_set_type_attr(file, (const u8*)"\x10\x00", 2); @@ -402,7 +402,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_create_file(p15card->card, file); } sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } /* @@ -462,7 +462,7 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return SC_ERROR_INVALID_ARGUMENTS; buf = calloc(1, buf_len); if (!buf) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); assert(key_len <= buf_len); if (key->algorithm == SC_ALGORITHM_RSA) { @@ -536,7 +536,7 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, end: assert(buf); free(buf); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } /* @@ -583,7 +583,7 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, { free(data.u.rsa.modulus); free(data.u.rsa.exponent); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } break; case SC_ALGORITHM_GOSTR3410: @@ -593,7 +593,7 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (!data.u.gostr3410.xy) { free(data.u.gostr3410.xy); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } break; default: @@ -618,7 +618,7 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, break; } } - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } /* diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 768f66c595..8770ed94a6 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -138,7 +138,7 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) sc_file_free(pinfile); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Select pinfile failed"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } /* @@ -158,7 +158,7 @@ setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d r = sc_create_file(p15card->card, df); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS create file failed"); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -242,7 +242,7 @@ setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_free(pinfile); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } /* @@ -367,7 +367,7 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create private key file"); sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } @@ -419,7 +419,7 @@ setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_file_free(file); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(ctx, r); } diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index c937439b5d..ee7b6f8a74 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1381,7 +1381,7 @@ int perform_pace(sc_card_t *card, if (r < 0) EAC_CTX_clear_free(eac_ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int eac_mse_set_at_ta(sc_card_t *card, int protocol, @@ -1658,7 +1658,7 @@ int perform_terminal_authentication(sc_card_t *card, BUF_MEM_clear_free(signature); if (card) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); else return r; } @@ -1806,7 +1806,7 @@ int perform_chip_authentication(sc_card_t *card, BUF_MEM_clear_free(picc_pubkey); if (card) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); else return r; } @@ -1891,7 +1891,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, BUF_MEM_clear_free(eph_pub_key); if (card) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); else return r; } @@ -2310,14 +2310,14 @@ eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, if (msesetat) EAC_MSE_C_free(msesetat); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); + LOG_FUNC_RETURN(card->ctx, r); } static int eac_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_FUNC_RETURN(card->ctx, increment_ssc(ctx->priv_data)); } @@ -2329,7 +2329,7 @@ eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, if (!card) return SC_ERROR_INVALID_ARGUMENTS; if(!ctx || !ctx->priv_data || !apdu) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); eacsmctx = ctx->priv_data; @@ -2351,13 +2351,13 @@ eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, if (!r) { ssl_error(card->ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } } } } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static void From e3dda8894e1f9a96fe86ed39fc81d5de72b314fc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Nov 2018 08:12:53 +0100 Subject: [PATCH 0657/4321] log errors in verbose --- src/libopensc/card-gids.c | 4 +-- src/pkcs15init/pkcs15-epass2003.c | 18 ++++++------- src/pkcs15init/pkcs15-oberthur-awp.c | 40 ++++++++++++++-------------- src/pkcs15init/pkcs15-oberthur.c | 12 ++++----- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 41e662e870..799b9fda0e 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1462,10 +1462,10 @@ static int gids_import_key(sc_card_t *card, sc_pkcs15_object_t *object, sc_pkcs1 sc_format_asn1_entry(asn1_key_usage_template + 1, asn1_key_value_template, NULL, 1); r = sc_asn1_encode(card->ctx, asn1_key_usage_template, &buffer, &buflen); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to encode the private key"); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "unable to encode the private key"); r = gids_put_DO(card, GIDS_APPLET_EFID, GIDS_PUT_KEY_DO, buffer, buflen); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to put the private key - key greater than 2048 bits ?"); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "unable to put the private key - key greater than 2048 bits ?"); r = SC_SUCCESS; err: sc_mem_clear(buffer, buflen); diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 815c7dc99c..1bbee4bd1a 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -519,7 +519,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, /* allocate key object */ r = cosm_new_file(profile, card, obj->type, idx, &file); //replace SC_PKCS15_TYPE_PRKEY_RSA with obj->type - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "create key: failed to allocate new key object"); file->size = keybits; sc_log(card->ctx, "private key path: %s", @@ -529,13 +529,13 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_DELETE); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key: pkcs15init_authenticate(SC_AC_OP_DELETE) failed"); sc_delete_file(p15card->card, &file->path); /* create */ r = sc_pkcs15init_create_file(profile, p15card, file); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "create key: failed to create key file"); sc_log(card->ctx, @@ -560,17 +560,17 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, path.len -= 2; r = sc_select_file(card, &path, &tfile); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key: no private object DF"); r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_CRYPTO); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key: pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed"); r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_CREATE); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed"); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA ) @@ -604,7 +604,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, if (r == SC_SUCCESS) { r = sc_pkcs15init_authenticate(profile, p15card, pukf, SC_AC_OP_DELETE); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_DELETE) failed"); r = sc_pkcs15init_delete_by_path(profile, p15card, &pukf->path); @@ -624,7 +624,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, r = sc_pkcs15init_authenticate(profile, p15card, pukf, SC_AC_OP_UPDATE); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_UPDATE) failed"); /* generate key pair */ @@ -636,7 +636,7 @@ static int epass2003_pkcs15_generate_key(struct sc_profile *profile, gendat.key_length = keybits; gendat.modulus = NULL; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat); - SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_NORMAL, r, + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "generate RSA key pair failed"); /* get the modulus */ diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index fad869c686..3b14e4c42b 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1388,22 +1388,22 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_log(ctx, "Cert Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_cert_info(p15card, obj, &icert); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot encode info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot encode info"); rv = awp_set_certificate_info(p15card, profile, info_file, &icert); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot set info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot set info"); rv = awp_update_object_list(p15card, profile, SC_PKCS15_TYPE_CERT_X509, obj_id & 0xFF); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update list"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update list"); rv = awp_update_container(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &icert.id, obj_id, &prvkey_id); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update container"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update container"); sc_log(ctx, "PrvKeyID:%04X", prvkey_id); if (prvkey_id) rv = awp_update_key_info(p15card, profile, prvkey_id, &icert); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Cert' update DF failed: cannot update key info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "'Create Cert' update DF failed: cannot update key info"); awp_free_cert_info(&icert); @@ -1452,13 +1452,13 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p cc.cert_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; rv = sc_pkcs15_read_certificate(p15card, cert_info, &p15cert); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: cannot get certificate"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot get certificate"); rv = sc_pkcs15_allocate_object_content(ctx, cert_obj, p15cert->data.value, p15cert->data.len); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: cannot allocate content"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot allocate content"); rv = awp_encode_cert_info(p15card, cert_obj, &icert); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: cannot encode cert info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot encode cert info"); sc_pkcs15_free_certificate(p15cert); p15cert = NULL; @@ -1471,25 +1471,25 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p } rv = awp_new_file(p15card, profile, key_obj->type, cc.prkey_id & 0xFF, &info_file, NULL); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "New private key info file error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "New private key info file error"); pubkey.algorithm = SC_ALGORITHM_RSA; sc_log(ctx, "PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: decode public key error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: decode public key error"); rv = awp_encode_key_info(p15card, key_obj, &pubkey.u.rsa, &ikey); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: encode info error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: encode info error"); rv = awp_set_key_info(p15card, profile, info_file, &ikey, cert_obj ? &icert : NULL); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: set info error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: set info error"); rv = awp_update_object_list(p15card, profile, key_obj->type, cc.prkey_id & 0xFF); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: update object list error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: update object list error"); rv = awp_create_container(p15card, profile, key_obj->type, &ikey.id, &cc); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: update container error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: update container error"); err: if (p15cert) @@ -1526,25 +1526,25 @@ awp_update_df_create_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p memset(&ikey, 0, sizeof(ikey)); rv = awp_new_file(p15card, profile, obj->type, index, &info_file, NULL); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "New public key info file error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "New public key info file error"); pubkey.algorithm = SC_ALGORITHM_RSA; sc_log(ctx, "PrKey Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = sc_pkcs15_decode_pubkey(ctx, &pubkey, der.value, der.len); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: decode public key error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: decode public key error"); rv = awp_encode_key_info(p15card, obj, &pubkey.u.rsa, &ikey); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: encode info error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: encode info error"); rv = awp_set_key_info(p15card, profile, info_file, &ikey, NULL); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: set info error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: set info error"); rv = awp_update_object_list(p15card, profile, obj->type, index); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: update object list error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: update object list error"); rv = awp_update_container(p15card, profile, obj->type, &ikey.id, obj_id, NULL); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update public key' DF failed: update container error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update public key' DF failed: update container error"); err: awp_free_key_info(&ikey); diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 6b690867de..10b50d0cca 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -73,18 +73,18 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile sc_log(ctx, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags); if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) { rv = SC_ERROR_INCONSISTENT_PROFILE; - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot find "COSM_TITLE"-token-info"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Cannot find "COSM_TITLE"-token-info"); } if (file->size < 16) { rv = SC_ERROR_INCONSISTENT_PROFILE; - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Insufficient size of the "COSM_TITLE"-token-info file"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Insufficient size of the "COSM_TITLE"-token-info file"); } buffer = calloc(1, file->size); if (!buffer) { rv = SC_ERROR_OUT_OF_MEMORY; - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Allocation error in cosm_write_tokeninfo()"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Allocation error in cosm_write_tokeninfo()"); } if (label) @@ -705,14 +705,14 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, rv = sc_select_file(p15card->card, &file->path, NULL); if (rv == 0) { rv = cosm_delete_file(p15card, profile, file); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to delete private key file"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Failed to delete private key file"); } else if (rv != SC_ERROR_FILE_NOT_FOUND) { - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Select private key file error"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Select private key file error"); } rv = sc_pkcs15init_create_file(profile, p15card, file); - SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to create private key file"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Failed to create private key file"); key_info->key_reference = file->path.value[file->path.len - 1]; From d4f1a26215ffaa718cbe2543d4d2eff8fae880d6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Nov 2018 08:31:11 +0100 Subject: [PATCH 0658/4321] respect SM debug level --- src/sm/sm-common.c | 8 ++++---- src/sm/sm-eac.c | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index f9c1995aea..43e1fb155b 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -278,7 +278,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, DES_cblock icv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; size_t st; - LOG_FUNC_CALLED(ctx); + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_SM); if (!out || !out_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "SM decrypt_des_cbc3: invalid input arguments"); @@ -299,7 +299,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, DES_3cbc_encrypt((DES_cblock *)(data + st), (DES_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_DECRYPT); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } @@ -314,7 +314,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, unsigned char *data; size_t data_len, st; - LOG_FUNC_CALLED(ctx); + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_SM); sc_debug(ctx, SC_LOG_DEBUG_SM, "SM encrypt_des_cbc3: not_force_pad:%i,in_len:%"SC_FORMAT_LEN_SIZE_T"u", not_force_pad, in_len); @@ -358,7 +358,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, DES_3cbc_encrypt((DES_cblock *)(data + st), (DES_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_ENCRYPT); free(data); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index ee7b6f8a74..d2e6a63a31 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1381,7 +1381,7 @@ int perform_pace(sc_card_t *card, if (r < 0) EAC_CTX_clear_free(eac_ctx); - LOG_FUNC_RETURN(card->ctx, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); } static int eac_mse_set_at_ta(sc_card_t *card, int protocol, @@ -1658,7 +1658,7 @@ int perform_terminal_authentication(sc_card_t *card, BUF_MEM_clear_free(signature); if (card) - LOG_FUNC_RETURN(card->ctx, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); else return r; } @@ -1806,7 +1806,7 @@ int perform_chip_authentication(sc_card_t *card, BUF_MEM_clear_free(picc_pubkey); if (card) - LOG_FUNC_RETURN(card->ctx, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); else return r; } @@ -1891,7 +1891,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, BUF_MEM_clear_free(eph_pub_key); if (card) - LOG_FUNC_RETURN(card->ctx, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); else return r; } @@ -2310,14 +2310,14 @@ eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, if (msesetat) EAC_MSE_C_free(msesetat); - LOG_FUNC_RETURN(card->ctx, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); } static int eac_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu) { - LOG_FUNC_RETURN(card->ctx, + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, increment_ssc(ctx->priv_data)); } @@ -2329,7 +2329,7 @@ eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, if (!card) return SC_ERROR_INVALID_ARGUMENTS; if(!ctx || !ctx->priv_data || !apdu) - LOG_FUNC_RETURN(card->ctx, + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_INVALID_ARGUMENTS); eacsmctx = ctx->priv_data; @@ -2351,13 +2351,13 @@ eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, if (!r) { ssl_error(card->ctx); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } } } } - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } static void From 907c9479e23330f4da2c2462f61fc07cfcf59406 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Nov 2018 16:51:14 +0100 Subject: [PATCH 0659/4321] replace sc_debug_hex with sc_log_hex --- src/libopensc/card-flex.c | 2 +- src/libopensc/card-mcrd.c | 2 +- src/libopensc/iso7816.c | 2 +- src/libopensc/pkcs15-cac.c | 2 +- src/libopensc/reader-pcsc.c | 4 ++-- src/sm/sm-iso.c | 26 +++++++++++++------------- src/tools/npa-tool.c | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index d94704218e..000620bb93 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -516,7 +516,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, sc_file_t *file; sc_log(card->ctx, "called, p1=%u\n", p1); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "path", buf, buflen); + sc_log_hex(card->ctx, "path", buf, buflen); sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0); apdu.resp = rbuf; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2d7b1cb26a..9c38a431e8 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -500,7 +500,7 @@ static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, len = keyd->datalen; sc_log(ctx, "keyd no %d", keyd->recno); - sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, "", p, len); + sc_log_hex(ctx, "", p, len); tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (!tag || taglen != 4 || diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index f69f480edc..900164adc0 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -412,7 +412,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, memcpy(file->name, p, length); file->namelen = length; - sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, " File name:", file->name, file->namelen); + sc_log_hex(ctx, " File name:", file->name, file->namelen); if (!file->type) file->type = SC_FILE_TYPE_DF; } diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 5f4a8994d0..57d5bdec31 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -353,7 +353,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_log(card->ctx, "cert len=%"SC_FORMAT_LEN_SIZE_T"u, cert_info.path.count=%d r=%d\n", cert_der.len, cert_info.path.count, r); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "cert", cert_der.value, cert_der.len); + sc_log_hex(card->ctx, "cert", cert_der.value, cert_der.len); /* cache it using the PKCS15 emulation objects */ /* as it does not change */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index da7d704258..817586fd82 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -525,7 +525,7 @@ static void initialize_uid(sc_reader_t *reader) && apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { reader->uid.len = apdu.resplen; memcpy(reader->uid.value, apdu.resp, reader->uid.len); - sc_debug_hex(reader->ctx, SC_LOG_DEBUG_NORMAL, "UID", + sc_log_hex(reader->ctx, "UID", reader->uid.value, reader->uid.len); } else { sc_log(reader->ctx, "unable to get UID"); @@ -2023,7 +2023,7 @@ pcsc_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) /* If PIN block building failed, we fail too */ LOG_TEST_RET(reader->ctx, r, "PC/SC v2 pinpad block building failed!"); /* If not, debug it, just for fun */ - sc_debug_hex(reader->ctx, SC_LOG_DEBUG_NORMAL, "PC/SC v2 pinpad block", sbuf, scount); + sc_log_hex(reader->ctx, "PC/SC v2 pinpad block", sbuf, scount); r = pcsc_internal_transmit(reader, sbuf, scount, rbuf, &rcount, ioctl); diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index b4a312e2b4..b9dcfc7ace 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -219,13 +219,13 @@ static int format_data(sc_card_t *card, const struct iso_sm_ctx *ctx, } pad_data_len = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to encrypt", pad_data, pad_data_len); + sc_log_hex(card->ctx, "Data to encrypt", pad_data, pad_data_len); r = ctx->encrypt(card, ctx, pad_data, pad_data_len, formatted_data); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt the data"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptogram", *formatted_data, r); + sc_log_hex(card->ctx, "Cryptogram", *formatted_data, r); if (prepend_padding_indicator) { r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data); @@ -333,7 +333,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); + sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len); break; case SC_APDU_CASE_2_EXT: if (card->reader->active_protocol == SC_PROTO_T0) { @@ -353,7 +353,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, goto err; } } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); + sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len); break; case SC_APDU_CASE_3_SHORT: case SC_APDU_CASE_3_EXT: @@ -368,7 +368,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", + sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; case SC_APDU_CASE_4_SHORT: @@ -380,7 +380,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); + sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len); } if (apdu->ins & 1) { @@ -394,7 +394,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", + sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; case SC_APDU_CASE_4_EXT: @@ -411,7 +411,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); + sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len); } if (apdu->ins & 1) { @@ -425,7 +425,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", + sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; default: @@ -455,7 +455,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, } mac_data_len = r; } - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to authenticate", mac_data, mac_data_len); + sc_log_hex(card->ctx, "Data to authenticate", mac_data, mac_data_len); r = ctx->authenticate(card, ctx, mac_data, mac_data_len, &mac); @@ -464,7 +464,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, goto err; } mac_len = r; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptographic Checksum (plain)", mac, mac_len); + sc_log_hex(card->ctx, "Cryptographic Checksum (plain)", mac, mac_len); /* format SM apdu */ @@ -497,7 +497,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, goto err; } sm_apdu->resp = resp_data; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen); + sc_log_hex(card->ctx, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen); *psm_apdu = sm_apdu; @@ -620,7 +620,7 @@ static int sm_decrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sc_log(card->ctx, "Decrypted APDU sw1=%02x sw2=%02x", apdu->sw1, apdu->sw2); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Decrypted APDU response data", + sc_log_hex(card->ctx, "Decrypted APDU response data", apdu->resp, apdu->resplen); r = SC_SUCCESS; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 7c29b7f32a..92b5280894 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -261,7 +261,7 @@ int npa_translate_apdus(sc_card_t *card, FILE *input) r = sc_bytes2apdu(card->ctx, buf, apdulen, &apdu); if (r < 0) { - sc_debug_hex(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid C-APDU", buf, apdulen); + sc_log_hex(card->ctx, "Invalid C-APDU", buf, apdulen); continue; } From a899a46b09a48db42d61e416035364bdf8f4537e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Nov 2018 21:54:14 +0100 Subject: [PATCH 0660/4321] replaced SC_TEST_RET with LOG_TEST_RET --- src/libopensc/card-acos5.c | 6 +- src/libopensc/card-akis.c | 30 ++--- src/libopensc/card-asepcos.c | 26 ++-- src/libopensc/card-atrust-acos.c | 30 ++--- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-belpic.c | 6 +- src/libopensc/card-cardos.c | 50 ++++---- src/libopensc/card-entersafe.c | 108 ++++++++-------- src/libopensc/card-flex.c | 38 +++--- src/libopensc/card-gemsafeV1.c | 10 +- src/libopensc/card-gids.c | 176 +++++++++++++-------------- src/libopensc/card-gpk.c | 80 ++++++------ src/libopensc/card-incrypto34.c | 54 ++++---- src/libopensc/card-itacns.c | 10 +- src/libopensc/card-jcop.c | 4 +- src/libopensc/card-masktech.c | 12 +- src/libopensc/card-mcrd.c | 40 +++--- src/libopensc/card-miocos.c | 16 +-- src/libopensc/card-muscle.c | 6 +- src/libopensc/card-rtecp.c | 34 +++--- src/libopensc/card-rutoken.c | 58 ++++----- src/libopensc/card-setcos.c | 22 ++-- src/libopensc/card-starcos.c | 56 ++++----- src/libopensc/card-tcos.c | 20 +-- src/libopensc/card.c | 2 +- src/libopensc/ctbcs.c | 4 +- src/libopensc/iso7816.c | 4 +- src/libopensc/muscle.c | 36 +++--- src/libopensc/pkcs15-data.c | 2 +- src/libopensc/pkcs15-esteid.c | 6 +- src/libopensc/pkcs15-gids.c | 14 +-- src/libopensc/pkcs15-itacns.c | 32 ++--- src/libopensc/pkcs15-pin.c | 6 +- src/libopensc/pkcs15-sec.c | 2 +- src/pkcs15init/pkcs15-asepcos.c | 4 +- src/pkcs15init/pkcs15-cardos.c | 2 +- src/pkcs15init/pkcs15-cflex.c | 14 +-- src/pkcs15init/pkcs15-entersafe.c | 34 +++--- src/pkcs15init/pkcs15-epass2003.c | 58 ++++----- src/pkcs15init/pkcs15-gids.c | 2 +- src/pkcs15init/pkcs15-miocos.c | 16 +-- src/pkcs15init/pkcs15-oberthur-awp.c | 116 +++++++++--------- src/pkcs15init/pkcs15-oberthur.c | 74 +++++------ src/pkcs15init/pkcs15-rtecp.c | 16 +-- src/pkcs15init/pkcs15-setcos.c | 66 +++++----- src/sm/sm-iso.c | 14 +-- 46 files changed, 709 insertions(+), 709 deletions(-) diff --git a/src/libopensc/card-acos5.c b/src/libopensc/card-acos5.c index a77ed0c6d5..0f745bed84 100644 --- a/src/libopensc/card-acos5.c +++ b/src/libopensc/card-acos5.c @@ -136,7 +136,7 @@ static int acos5_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) apdu.resplen = sizeof(rbuf); apdu.le = 6; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; @@ -186,7 +186,7 @@ static int acos5_list_files(sc_card_t * card, u8 * buf, size_t buflen) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x14, 0x01, 0x00); apdu.cla |= 0x80; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90) return SC_ERROR_INTERNAL; count = apdu.sw2; @@ -207,7 +207,7 @@ static int acos5_list_files(sc_card_t * card, u8 * buf, size_t buflen) apdu.resplen = sizeof(info); apdu.le = sizeof(info); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 5b88a0e229..9defca7f25 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -93,9 +93,9 @@ select_file(sc_card_t *card, sc_apdu_t *apdu, const sc_path_t *path, apdu->le = 256; r = sc_transmit_apdu(card, apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu->sw1, apdu->sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (file_out == NULL) return 0; @@ -126,7 +126,7 @@ akis_select_file(sc_card_t *card, const sc_path_t *path, */ r = select_file(card, &apdu, path, path->len == 2 ? 0 : 8, file_out); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select DF"); + LOG_TEST_RET(card->ctx, r, "Unable to select DF"); return 0; } else if (path->type == SC_PATH_TYPE_FILE_ID) { /* AKIS differentiates between EF and DF files @@ -136,7 +136,7 @@ akis_select_file(sc_card_t *card, const sc_path_t *path, if (r) r = select_file(card, &apdu, path, 0, file_out); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select DF"); + LOG_TEST_RET(card->ctx, r, "Unable to select DF"); return 0; } else { return iso_ops->select_file(card, path, file_out); @@ -161,9 +161,9 @@ akis_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "DIRECTORY command returned error"); + LOG_TEST_RET(card->ctx, r, "DIRECTORY command returned error"); left = apdu.resplen; p = rbuf; @@ -291,7 +291,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file) } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -329,7 +329,7 @@ akis_delete_file(sc_card_t *card, const sc_path_t *path) apdu.data = buf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -368,7 +368,7 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left apdu.lc = apdu.datalen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); return r; } @@ -389,7 +389,7 @@ akis_get_data(sc_card_t *card, unsigned int dataid, u8 *buf, size_t len) apdu.le = len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); return r; } @@ -408,7 +408,7 @@ akis_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) /* read serial number */ r = akis_get_data(card, 6, system_buffer, 0x4D); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA failed"); + LOG_TEST_RET(card->ctx, r, "GET_DATA failed"); card->serialnr.len = 12; memcpy(card->serialnr.value, system_buffer+55, 12); @@ -425,7 +425,7 @@ akis_lifecycle_get(sc_card_t *card, int *mode) u8 memory[10]; r = akis_get_data(card, 4, memory, 10); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA failed"); + LOG_TEST_RET(card->ctx, r, "GET_DATA failed"); switch(memory[6]) { case 0xA0: @@ -462,7 +462,7 @@ akis_lifecycle_set(sc_card_t *card, int *mode) apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); return r; } @@ -496,7 +496,7 @@ akis_set_security_env(sc_card_t *card, ref = env->key_ref[0]; sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xC3, ref); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); return r; } @@ -512,7 +512,7 @@ akis_logout(sc_card_t *card) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x1A, 0, 0); apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); return r; } diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index fdad661823..48436e25f0 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -252,7 +252,7 @@ static int asepcos_get_current_df_path(sc_card_t *card, sc_path_t *path) apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); return asepcos_tlvpath_to_scpath(path, apdu.resp, apdu.resplen); @@ -340,7 +340,7 @@ static int asepcos_akn_to_fileid(sc_card_t *card, sc_cardctl_asepcos_akn2fileid_ apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.resplen != 4) return SC_ERROR_INTERNAL; @@ -364,7 +364,7 @@ static int asepcos_set_sec_attributes(sc_card_t *card, const u8 *data, size_t le apdu.datalen = len; apdu.data = data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -452,7 +452,7 @@ static int asepcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_le apdu.lc = crgram_len; apdu.datalen = crgram_len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); return apdu.resplen; @@ -485,7 +485,7 @@ static int asepcos_compute_signature(sc_card_t *card, const u8 *data, size_t dat apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { sc_log(card->ctx, "error creating signature"); return sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -513,7 +513,7 @@ static int asepcos_activate_file(sc_card_t *card, int fileid, int is_ef) apdu.datalen = 2; apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -555,7 +555,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -604,7 +604,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) apdu.datalen = p - sbuf; apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -632,7 +632,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) apdu.data = file->prop_attr; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); /* set security attributes */ @@ -738,7 +738,7 @@ static int asepcos_delete_file(sc_card_t *card, const sc_path_t *path) apdu.resplen = sizeof(buf); apdu.resp = buf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { /* looks like a EF */ atype = SC_APDU_CASE_3_SHORT; @@ -759,7 +759,7 @@ static int asepcos_delete_file(sc_card_t *card, const sc_path_t *path) } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -790,7 +790,7 @@ static int asepcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (apdu.resplen != 8) { @@ -821,7 +821,7 @@ static int asepcos_change_key(sc_card_t *card, sc_cardctl_asepcos_change_key_t * apdu.data = p->data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 64e14f5e08..fb3bd70d5e 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -249,7 +249,7 @@ static int atrust_acos_select_aid(struct sc_card *card, apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* check return value */ if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 ) @@ -300,7 +300,7 @@ static int atrust_acos_select_fid(struct sc_card *card, apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.p2 == 0x00 && apdu.sw1 == 0x62 && apdu.sw2 == 0x84 ) { /* no FCI => we have a DF (see comment in process_fci()) */ @@ -310,7 +310,7 @@ static int atrust_acos_select_fid(struct sc_card *card, apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); } else if (apdu.sw1 == 0x61 || (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)) { /* SELECT returned some data (possible FCI) => * try a READ BINARY to see if a EF is selected */ @@ -322,7 +322,7 @@ static int atrust_acos_select_fid(struct sc_card *card, apdu2.le = 1; apdu2.lc = 0; r = sc_transmit_apdu(card, &apdu2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu2.sw1 == 0x69 && apdu2.sw2 == 0x86) /* no current EF is selected => we have a DF */ bIsDF = 1; @@ -476,7 +476,7 @@ static int atrust_acos_select_file(struct sc_card *card, /* first step: change directory */ r = atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); memset(&new_path, 0, sizeof(sc_path_t)); new_path.type = SC_PATH_TYPE_PATH; @@ -515,7 +515,7 @@ static int atrust_acos_select_file(struct sc_card *card, for ( i=0; ictx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } return atrust_acos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out); } @@ -574,7 +574,7 @@ static int atrust_acos_set_security_env(struct sc_card *card, apdu.lc = p - sbuf; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); return SC_SUCCESS; @@ -624,7 +624,7 @@ static int atrust_acos_set_security_env(struct sc_card *card, /* we don't know whether to use * COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */ r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { ex_data->fix_digestInfo = 0; ex_data->sec_ops = SC_SEC_OPERATION_SIGN; @@ -649,7 +649,7 @@ static int atrust_acos_set_security_env(struct sc_card *card, apdu.lc = p - sbuf; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); ex_data->fix_digestInfo = env->algorithm_flags; @@ -689,7 +689,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, apdu.lc = datalen; apdu.datalen = datalen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -704,7 +704,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; memcpy(out, apdu.resp, len); @@ -736,7 +736,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); { @@ -785,7 +785,7 @@ static int atrust_acos_decipher(struct sc_card *card, apdu.datalen = crgram_len + 1; apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -841,7 +841,7 @@ static int acos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; /* cache serial number */ @@ -882,7 +882,7 @@ static int atrust_acos_logout(struct sc_card *card) apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) /* the only possible reason for this error here is, afaik, diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 29a94382a9..0741e753cd 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1867,7 +1867,7 @@ authentic_manage_sdo_generate(struct sc_card *card, struct sc_authentic_sdo *sdo LOG_TEST_RET(ctx, rv, "authentic_sdo_create() SDO put data error"); rv = authentic_decode_pubkey_rsa(ctx, apdu.resp, apdu.resplen, &sdo->data.prvkey); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "cannot decode public key"); + LOG_TEST_RET(card->ctx, rv, "cannot decode public key"); free(data); LOG_FUNC_RETURN(ctx, rv); diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 414333bbd1..4e5b1d620e 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -268,7 +268,7 @@ static int belpic_select_file(sc_card_t *card, r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Select File APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "Select File APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) @@ -374,10 +374,10 @@ static int belpic_set_security_env(sc_card_t *card, apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Set Security Env APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "Set Security Env APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card's Set Security Env command returned error"); + LOG_TEST_RET(card->ctx, r, "Card's Set Security Env command returned error"); /* If a NonRep signature will be done, ask to enter a PIN. It would be more * logical to put the code below into the compute signature function because diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index c74e3f49a2..2d9ec683c9 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -103,7 +103,7 @@ static int cardos_match_card(sc_card_t *card) apdu.le = 256; apdu.lc = 0; rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return 0; if (apdu.resp[0] != atr[10] || @@ -143,7 +143,7 @@ static int cardos_have_2048bit_package(sc_card_t *card) apdu.lc = 0; apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if ((len = apdu.resplen) == 0) /* looks like no package has been installed */ @@ -211,12 +211,12 @@ static int cardos_init(sc_card_t *card) apdu.resplen = sizeof(rbuf); r = sc_transmit_apdu(card, &apdu); if (r < 0) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "GET DATA command returned error"); if (apdu.resplen != 2) @@ -346,9 +346,9 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "DIRECTORY command returned error"); + LOG_TEST_RET(card->ctx, r, "DIRECTORY command returned error"); if (apdu.resplen > 256) { sc_log(card->ctx, "directory listing > 256 bytes, cutting"); @@ -730,7 +730,7 @@ static int cardos_create_file(sc_card_t *card, sc_file_t *file) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } else @@ -752,10 +752,10 @@ cardos_restore_security_env(sc_card_t *card, int se_num) apdu.p1 = (card->type == SC_CARD_TYPE_CARDOS_CIE_V1 ? 0xF3 : 0x03); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -812,10 +812,10 @@ cardos_set_security_env(sc_card_t *card, apdu.data = data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); do { const struct sc_supported_algo_info* algorithm_info = env->supported_algos; @@ -865,7 +865,7 @@ do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, apdu.lc = datalen; apdu.datalen = datalen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); @@ -1024,13 +1024,13 @@ cardos_lifecycle_get(sc_card_t *card, int *mode) apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (apdu.resplen < 1) { - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Lifecycle byte not in response"); + LOG_TEST_RET(card->ctx, r, "Lifecycle byte not in response"); } r = SC_SUCCESS; @@ -1080,10 +1080,10 @@ cardos_lifecycle_set(sc_card_t *card, int *mode) apdu.resp = NULL; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1108,10 +1108,10 @@ cardos_put_data_oci(sc_card_t *card, apdu.datalen = args->len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1134,10 +1134,10 @@ cardos_put_data_seci(sc_card_t *card, apdu.datalen = args->len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -1169,9 +1169,9 @@ cardos_generate_key(sc_card_t *card, apdu.datalen = apdu.lc = sizeof(data); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GENERATE_KEY failed"); + LOG_TEST_RET(card->ctx, r, "GENERATE_KEY failed"); return r; } @@ -1187,7 +1187,7 @@ static int cardos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (apdu.resplen != 32) { @@ -1290,7 +1290,7 @@ cardos_logout(sc_card_t *card) apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } else diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index feea41ad73..d85828d7ac 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -185,7 +185,7 @@ static int entersafe_gen_random(sc_card_t *card,u8 *buff,size_t size) apdu.resplen=sizeof(rbuf); r=sc_transmit_apdu(card,&apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "entersafe gen random failed"); + LOG_TEST_RET(card->ctx, r, "entersafe gen random failed"); if(apdu.resplen!=size) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -272,7 +272,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, return SC_ERROR_INTERNAL; r=entersafe_gen_random(card,iv,sizeof(iv)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,r,"entersafe gen random failed"); + LOG_TEST_RET(card->ctx,r,"entersafe gen random failed"); /* encode the APDU in the buffer */ if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS) @@ -428,7 +428,7 @@ static int entersafe_read_binary(sc_card_t *card, apdu.resp = recvbuf; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.resplen == 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); memcpy(buf, recvbuf, apdu.resplen); @@ -455,8 +455,8 @@ static int entersafe_update_binary(sc_card_t *card, apdu.data = buf; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Card returned error"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count); } @@ -471,7 +471,7 @@ static int entersafe_process_fci(struct sc_card *card, struct sc_file *file, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); r = iso_ops->process_fci(card,file,buf,buflen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Process fci failed"); + LOG_TEST_RET(card->ctx, r, "Process fci failed"); if(file->namelen) { @@ -505,7 +505,7 @@ static int entersafe_select_fid(sc_card_t *card, r = iso_ops->select_file(card,&path,&file); if (r < 0) sc_file_free(file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* update cache */ if (file->type == SC_FILE_TYPE_DF) { @@ -550,7 +550,7 @@ static int entersafe_select_aid(sc_card_t *card, else { r = iso_ops->select_file(card,in_path,file_out); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* update cache */ card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; @@ -629,7 +629,7 @@ static int entersafe_select_path(sc_card_t *card, /* first step: change directory */ r = entersafe_select_fid(card, path[bMatch], path[bMatch+1], NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); memset(&new_path, 0, sizeof(sc_path_t)); @@ -670,7 +670,7 @@ static int entersafe_select_path(sc_card_t *card, for ( i=0; ictx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } return entersafe_select_fid(card, path[pathlen-2], path[pathlen-1], file_out); } @@ -750,7 +750,7 @@ static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data) }break; } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data * data) @@ -768,7 +768,7 @@ static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data * data) apdu.lc=apdu.datalen=sizeof(data->data.df); r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -785,7 +785,7 @@ static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data * data) apdu.lc = apdu.datalen = sizeof(data->data.ef); r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -889,7 +889,7 @@ static int entersafe_internal_set_security_env(sc_card_t *card, apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -949,7 +949,7 @@ static int entersafe_compute_with_prkey(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INTERNAL); r = entersafe_internal_set_security_env(card,card->drv_data,&p,&size); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "internal set security env failed"); + LOG_TEST_RET(card->ctx, r, "internal set security env failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x86,0x80); apdu.data=p; @@ -960,7 +960,7 @@ static int entersafe_compute_with_prkey(sc_card_t *card, apdu.le = 256; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -1022,7 +1022,7 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.data = sbuf; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } {/*change*/ @@ -1038,7 +1038,7 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.data = sbuf; r = entersafe_transmit_apdu(card, &apdu,key_maintain,sizeof(key_maintain),1,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -1060,7 +1060,7 @@ static int entersafe_erase_card(sc_card_t *card) apdu.data = sbuf; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_invalidate_cache(card); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xEE, 0x00, 0x00); @@ -1092,7 +1092,7 @@ static int entersafe_erase_card(sc_card_t *card) }break; } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -1149,8 +1149,8 @@ static int entersafe_write_small_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkc apdu.lc=apdu.datalen=p-sbuff; r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); } p=sbuff; @@ -1166,8 +1166,8 @@ static int entersafe_write_small_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkc apdu.lc=apdu.datalen=p-sbuff; r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); @@ -1195,8 +1195,8 @@ static int entersafe_write_rsa_key_factor(sc_card_t *card, apdu.lc=apdu.datalen=4; r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed(MSE)"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed(MSE)"); } {/* Write 'x'; */ @@ -1238,8 +1238,8 @@ static int entersafe_write_rsa_key_factor(sc_card_t *card, apdu.lc=apdu.datalen=data.len; r = entersafe_transmit_apdu(card,&apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); } @@ -1252,15 +1252,15 @@ static int entersafe_write_large_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkc {/* write prkey */ r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x01,rsa->p); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write p failed"); + LOG_TEST_RET(card->ctx, r, "write p failed"); r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x02,rsa->q); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write q failed"); + LOG_TEST_RET(card->ctx, r, "write q failed"); r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x03,rsa->dmp1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write dmp1 failed"); + LOG_TEST_RET(card->ctx, r, "write dmp1 failed"); r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x04,rsa->dmq1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write dmq1 failed"); + LOG_TEST_RET(card->ctx, r, "write dmq1 failed"); r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x05,rsa->iqmp); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write iqmp failed"); + LOG_TEST_RET(card->ctx, r, "write iqmp failed"); } {/* write pukey */ @@ -1281,8 +1281,8 @@ static int entersafe_write_large_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkc apdu.lc=apdu.datalen=0x46; r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(1) failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(1) failed"); /* left 192(0xC0) bytes of N */ sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x46,0x0B,0x00); @@ -1290,12 +1290,12 @@ static int entersafe_write_large_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkc apdu.lc=apdu.datalen=0xC0; r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(2) failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(2) failed"); /* E */ r = entersafe_write_rsa_key_factor(card,key_id,0x2A,0x0D,rsa->exponent); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "write exponent failed"); + LOG_TEST_RET(card->ctx, r, "write exponent failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); } @@ -1324,8 +1324,8 @@ static int entersafe_write_symmetric_key(sc_card_t *card, apdu.lc=apdu.datalen=len+2; r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); } @@ -1380,8 +1380,8 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) apdu.le=0; r=entersafe_transmit_apdu(card, &apdu, 0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe set MSE failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe set MSE failed"); /* generate key */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00); @@ -1393,8 +1393,8 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) apdu.datalen = 2; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe generate keypair failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe generate keypair failed"); /* read public key via READ PUBLIC KEY */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xE6, 0x2A, data->key_id); @@ -1403,8 +1403,8 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get pukey failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get pukey failed"); data->modulus = malloc(len); if (!data->modulus) @@ -1452,8 +1452,8 @@ static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.le=0x08; r=entersafe_transmit_apdu(card, &apdu,0,0,0,0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get SN failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get SN failed"); card->serialnr.len=serial->len=8; memcpy(card->serialnr.value,rbuf,8); @@ -1496,7 +1496,7 @@ static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) apdu.lc=apdu.datalen=9 + sizeof(rsa_key_e) + 4; ret = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Preinstall rsa failed"); + LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed"); /* create rsa item in PKF */ sbuf[0] = 0x01; /* key len extern */ @@ -1520,7 +1520,7 @@ static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) apdu.lc=apdu.datalen=9 + sizeof(rsa_key_e) + 4; ret=entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Preinstall rsa failed"); + LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); } @@ -1540,7 +1540,7 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_ ++rsa_index) { r=install_rsa(card,rsa_index); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Preinstall rsa key failed"); + LOG_TEST_RET(card->ctx, r, "Preinstall rsa key failed"); } } @@ -1563,7 +1563,7 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_ apdu.lc=apdu.datalen=0x19; r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Preinstall key maintain failed"); + LOG_TEST_RET(card->ctx, r, "Preinstall key maintain failed"); } {/* user PIN */ @@ -1584,7 +1584,7 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_ apdu.lc=apdu.datalen=0x19; r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Preinstall user PIN failed"); + LOG_TEST_RET(card->ctx, r, "Preinstall user PIN failed"); } {/* user PUK */ @@ -1605,7 +1605,7 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_ apdu.lc=apdu.datalen=0x19; r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Preinstall user PUK failed"); + LOG_TEST_RET(card->ctx, r, "Preinstall user PUK failed"); } diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 000620bb93..6c187ebfc2 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -532,9 +532,9 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, apdu.le = 0; } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (file_out == NULL) return 0; @@ -587,18 +587,18 @@ static int flex_select_file(sc_card_t *card, const sc_path_t *path, if (pathlen != 2 || memcmp(pathptr, "\x3F\x00", 2) != 0) { locked = 1; r = sc_lock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed"); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); if (!magic_done && memcmp(pathptr, "\x3F\x00", 2) != 0) { r = select_file_id(card, (const u8 *) "\x3F\x00", 2, 0, NULL); if (r) sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select Master File (MF)"); + LOG_TEST_RET(card->ctx, r, "Unable to select Master File (MF)"); } while (pathlen > 2) { r = select_file_id(card, pathptr, 2, 0, NULL); if (r) sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select DF"); + LOG_TEST_RET(card->ctx, r, "Unable to select DF"); pathptr += 2; pathlen -= 2; } @@ -709,7 +709,7 @@ static int flex_delete_file(sc_card_t *card, const sc_path_t *path) apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -809,7 +809,7 @@ cryptoflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, continue; entry = sc_file_get_acl_entry(file, ops[i]); r = acl_to_ac_nibble(entry); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Invalid ACL value"); + LOG_TEST_RET(card->ctx, r, "Invalid ACL value"); /* Do some magic to get the nibbles right */ p[8 + i/2] |= (r & 0x0F) << (((i+1) % 2) * 4); r = acl_to_keynum_nibble(entry); @@ -918,9 +918,9 @@ static int flex_create_file(sc_card_t *card, sc_file_t *file) apdu.lc = sendlen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (card->cache.valid) { u8 file_id[2]; @@ -1010,9 +1010,9 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data, for (i2 = 0; i2 < 10; i2++) sbuf[i2]=data[data_len-1-i2]; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); data_len -= 10; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, prv->rsa_key_ref); apdu.cla=0x0; @@ -1027,9 +1027,9 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data, apdu.le = apdu.resplen > 256 ? 256 : apdu.resplen; apdu.resp = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); for (i = 0; i < apdu.resplen; i++) out[i] = sbuf[apdu.resplen-1-i]; return apdu.resplen; @@ -1068,9 +1068,9 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data, apdu.resplen = outlen; apdu.resp = out; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return apdu.resplen; } @@ -1143,9 +1143,9 @@ static int flex_generate_key(sc_card_t *card, struct sc_cardctl_cryptoflex_genke sbuf[3] = (data->exponent >> 24) & 0xFF; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); data->pubkey_len = apdu.resplen; return 0; @@ -1296,10 +1296,10 @@ static int flex_logout(sc_card_t *card) apdu.cla = 0xF0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 7467b390c0..b0461d49cb 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -135,7 +135,7 @@ static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len) apdu.resplen = sizeof(buf); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -418,7 +418,7 @@ static int gemsafe_restore_security_env(struct sc_card *card, int se_num) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0x73, (u8) se_num); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -489,7 +489,7 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, apdu.datalen = data_len + 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) { @@ -503,7 +503,7 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, apdu.cla = 0x00; } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -537,7 +537,7 @@ static int gemsafe_decipher(struct sc_card *card, const u8 * crgram, apdu.lc = crgram_len; apdu.datalen = crgram_len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { int len = apdu.resplen > outlen ? outlen : apdu.resplen; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 799b9fda0e..cfee574ee3 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -229,8 +229,8 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids get data failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "gids get data failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize); if (!p) { @@ -266,8 +266,8 @@ static int gids_put_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti apdu.flags |= SC_APDU_FLAGS_CHAINING; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids put data failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "gids put data failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); return SC_SUCCESS; } @@ -295,7 +295,7 @@ static int gids_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response r = sc_transmit_apdu(card, &apdu); if (responselen) *responselen = apdu.resplen; - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids select failed"); + LOG_TEST_RET(card->ctx, r, "gids select failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -310,9 +310,9 @@ static int gids_read_gidsfile_without_cache(sc_card_t* card, u8* masterfile, siz SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); r = gids_get_identifiers(card, masterfile, masterfilesize, directory, filename, &fileIdentifier, &dataObjectIdentifier); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the identifier for the gids file"); + LOG_TEST_RET(card->ctx, r, "unable to get the identifier for the gids file"); r = gids_get_DO(card, fileIdentifier, dataObjectIdentifier, response, responselen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the data from the file"); + LOG_TEST_RET(card->ctx, r, "unable to get the data from the file"); return r; } @@ -328,9 +328,9 @@ static int gids_write_gidsfile_without_cache(sc_card_t* card, u8* masterfile, si } r = gids_get_identifiers(card, masterfile, masterfilesize, directory, filename, &fileIdentifier, &dataObjectIdentifier); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the identifier for the gids file"); + LOG_TEST_RET(card->ctx, r, "unable to get the identifier for the gids file"); r = gids_put_DO(card, fileIdentifier, dataObjectIdentifier, data, datalen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the data from the file"); + LOG_TEST_RET(card->ctx, r, "unable to get the data from the file"); return r; } @@ -360,7 +360,7 @@ static int gids_update_cardcf(sc_card_t* card, int file, int container) { int r; size_t cardcfsize = sizeof(cardcf); r = gids_read_gidsfile_without_cache(card, data->masterfile, data->masterfilesize, "", "cardcf", cardcf, &cardcfsize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the cardcf"); + LOG_TEST_RET(card->ctx, r, "unable to get the cardcf"); if (file) { short filefreshness = cardcf[4] + cardcf[5] * 0x100; @@ -375,7 +375,7 @@ static int gids_update_cardcf(sc_card_t* card, int file, int container) { cardcf[3] = (containerfreshness>>8) & 0xFF; } r = gids_write_gidsfile_without_cache(card, data->masterfile, data->masterfilesize, "", "cardcf", cardcf, 6); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cardcf file"); + LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file"); return r; } @@ -386,11 +386,11 @@ static int gids_read_gidsfile(sc_card_t* card, char *directory, char *filename, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (privatedata->masterfilesize == sizeof(privatedata->masterfile)) { r = gids_read_masterfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the masterfile"); + LOG_TEST_RET(card->ctx, r, "unable to get the masterfile"); } r = gids_read_gidsfile_without_cache(card, privatedata->masterfile, privatedata->masterfilesize, directory, filename, response, responselen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to read the file"); + LOG_TEST_RET(card->ctx, r, "unable to read the file"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); } @@ -408,11 +408,11 @@ static int gids_write_gidsfile(sc_card_t* card, char *directory, char *filename, int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); r = gids_update_cardcf(card, 1, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cache file"); + LOG_TEST_RET(card->ctx, r, "unable to update the cache file"); r = gids_write_gidsfile_without_cache(card, privatedata->masterfile, privatedata->masterfilesize, directory, filename, data, datalen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the file"); + LOG_TEST_RET(card->ctx, r, "unable to write the file"); if (strcmp(directory, "mscp") == 0 && strcmp(filename, "cmapfile") == 0) { // update the cmapfile cache privatedata->cmapfilesize = datalen; @@ -432,7 +432,7 @@ static int gids_read_cmapfile(sc_card_t* card) { if (r<0) { data->cmapfilesize = sizeof(data->cmapfile); } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the cmapfile"); + LOG_TEST_RET(card->ctx, r, "unable to get the cmapfile"); return r; } @@ -448,7 +448,7 @@ static int gids_create_file(sc_card_t *card, char* directory, char* filename) { gids_mf_record_t* record; r = gids_find_available_DO(card, privatedata->masterfile, privatedata->masterfilesize, &fileIdentifier, &dataObjectIdentifier); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to find an empty DO"); + LOG_TEST_RET(card->ctx, r, "unable to find an empty DO"); memcpy(masterfilebuffer, privatedata->masterfile, privatedata->masterfilesize); masterfilebuffersize = privatedata->masterfilesize + sizeof(gids_mf_record_t); @@ -468,10 +468,10 @@ static int gids_create_file(sc_card_t *card, char* directory, char* filename) { record->dataObjectIdentifier = dataObjectIdentifier; r = gids_update_cardcf(card, 1, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cardcf"); + LOG_TEST_RET(card->ctx, r, "unable to update the cardcf"); r = gids_put_DO(card, MF_FI, MF_DO, masterfilebuffer, masterfilebuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the masterfile"); + LOG_TEST_RET(card->ctx, r, "unable to update the masterfile"); memcpy(privatedata->masterfile, masterfilebuffer, masterfilebuffersize); privatedata->masterfilesize = masterfilebuffersize; @@ -532,7 +532,7 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); } r = gids_get_DO(card, GIDS_APPLET_EFID, dataObjectIdentifier, buffer, &buffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the masterfile"); + LOG_TEST_RET(card->ctx, r, "unable to update the masterfile"); buffersize = buffersize > sizeof(buffer) ? sizeof(buffer) : buffersize; @@ -606,7 +606,7 @@ static int gids_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) buffersize = sizeof(buffer); r = gids_read_gidsfile(card, "", "cardid", buffer, &buffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to read cardid"); + LOG_TEST_RET(card->ctx, r, "unable to read cardid"); if (SC_MAX_SERIALNR < buffersize) { @@ -870,8 +870,8 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read public key failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "gids read public key failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); buffersize = apdu.resplen; keytemplate = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_PUBKEY_TAG, &tlen); @@ -1098,9 +1098,9 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read masterfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); r = gids_read_cmapfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read cmapfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed"); recordsnum = (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD)); @@ -1209,10 +1209,10 @@ static int gids_perform_create_keyfile(sc_card_t *card, u8 keytype, u8 kid, u8 a sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "ACTIVATE_FILE returned error"); + LOG_TEST_RET(card->ctx, r, "ACTIVATE_FILE returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1335,15 +1335,15 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { keymaprecord->unknownWithFFFF = (unsigned short) (-1); keymaprecord->keyref = 0xB000 + kid; r = gids_perform_create_keyfile(card, keytype, kid, algid); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to create the key file"); + LOG_TEST_RET(card->ctx, r, "unable to create the key file"); r = gids_update_cardcf(card, 0, 1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cardcf file regarding container"); + LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file regarding container"); r = gids_put_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, keymapbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the keymap file"); + LOG_TEST_RET(card->ctx, r, "unable to write the keymap file"); r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the cmap file after the container creation"); + LOG_TEST_RET(card->ctx, r, "unable to write the cmap file after the container creation"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1376,13 +1376,13 @@ static int gids_generate_key(sc_card_t *card, sc_pkcs15_object_t *object, struct apdu.data = generatekey; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "generate key returned error"); + LOG_TEST_RET(card->ctx, r, "generate key returned error"); r = gids_read_public_key(card, 0, NULL, kid, 0, &buffer, &buffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read public key returned error"); + LOG_TEST_RET(card->ctx, r, "read public key returned error"); r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, buffer, buffersize); if (buffer) free(buffer); @@ -1480,11 +1480,11 @@ static int gids_delete_key_file(sc_card_t *card, int containernum) { snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & (containernum + GIDS_FIRST_KEY_IDENTIFIER))); sc_format_path(ch_tmp, &cpath); r = gids_select_file(card, &cpath, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select the key file"); + LOG_TEST_RET(card->ctx, r, "unable to select the key file"); // delete current selected file memset(&cpath, 0, sizeof(cpath)); r = iso_ops->delete_file(card, &cpath); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to delete the key file"); + LOG_TEST_RET(card->ctx, r, "unable to delete the key file"); return r; } @@ -1508,7 +1508,7 @@ static int gids_encode_certificate(sc_card_t *card, u8* source, size_t sourcesiz destination[3] = (sourcesize & 0xFF00) >> 8; outlen = *destinationsize - 4; r = sc_compress(destination + 4, &outlen, source, sourcesize, COMPRESSION_ZLIB); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to compress the certificate"); + LOG_TEST_RET(card->ctx, r, "unable to compress the certificate"); *destinationsize = outlen + 4; return SC_SUCCESS; } @@ -1528,13 +1528,13 @@ static int gids_save_certificate(sc_card_t *card, sc_pkcs15_object_t *certobject // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read masterfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); r= gids_read_cmapfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read cmapfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed"); // compress the certificate according to the minidriver specification r = gids_encode_certificate(card, cert_info->value.value, cert_info->value.len, certbuffer, &certbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to encode the certificate"); + LOG_TEST_RET(card->ctx, r, "unable to encode the certificate"); // save it to a minidriver file containernum = prkey_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER; @@ -1547,14 +1547,14 @@ static int gids_save_certificate(sc_card_t *card, sc_pkcs15_object_t *certobject r = gids_does_file_exists(card, "mscp", filename); if (r == SC_ERROR_FILE_NOT_FOUND) { r = gids_create_file(card, "mscp", filename); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to create the certificate file"); + LOG_TEST_RET(card->ctx, r, "gids unable to create the certificate file"); } r = gids_write_gidsfile(card, "mscp", filename, certbuffer, certbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to write the certificate data"); + LOG_TEST_RET(card->ctx, r, "gids unable to write the certificate data"); // return the path to the DO r = gids_build_certificate_path(card, containernum, !(prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT), path); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to build the certificate path"); + LOG_TEST_RET(card->ctx, r, "gids unable to build the certificate path"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -1606,14 +1606,14 @@ static int gids_delete_container_num(sc_card_t *card, size_t containernum) { // remove the key, update the key map & cmap file and signal the change r = gids_delete_key_file(card, (int) containernum); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to delete the key file"); + LOG_TEST_RET(card->ctx, r, "unable to delete the key file"); r = gids_update_cardcf(card, 0, 1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cardcf file regarding container"); + LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file regarding container"); r = gids_put_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, keymapbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the keymap file"); + LOG_TEST_RET(card->ctx, r, "unable to write the keymap file"); r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to write the cmap file after the container creation"); + LOG_TEST_RET(card->ctx, r, "unable to write the cmap file after the container creation"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -1634,9 +1634,9 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT); // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read masterfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); r= gids_read_cmapfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read cmapfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed"); // remove the file reference from the masterfile if (cert_info->path.len != 4) { @@ -1666,13 +1666,13 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { // remove the DO, update the masterfile, and signal the change r = gids_update_cardcf(card, 1, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the cache file"); + LOG_TEST_RET(card->ctx, r, "unable to update the cache file"); r = gids_put_DO(card, fileIdentifier, DO, NULL, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to delete the certificate DO"); + LOG_TEST_RET(card->ctx, r, "gids unable to delete the certificate DO"); r = gids_put_DO(card, MF_FI, MF_DO, masterfilebuffer, masterfilebuffersize); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to update the masterfile"); + LOG_TEST_RET(card->ctx, r, "gids unable to update the masterfile"); memcpy(privatedata->masterfile, masterfilebuffer, masterfilebuffersize); privatedata->masterfilesize = masterfilebuffersize; @@ -1688,13 +1688,13 @@ static int gids_delete_key(sc_card_t *card, sc_pkcs15_object_t* object) { assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read masterfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); r = gids_read_cmapfile(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids read cmapfile failed"); + LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed"); containernum = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER; r = gids_delete_container_num(card, containernum); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to delete the container"); + LOG_TEST_RET(card->ctx, r, "gids unable to delete the container"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -1708,15 +1708,15 @@ static int gids_initialize_create_file(sc_card_t *card, u8* command, size_t comm apdu.datalen = commandsize; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU1 transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU1 transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // activate file sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU2 transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU2 transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1736,7 +1736,7 @@ static int gids_set_administrator_key(sc_card_t *card, u8* key) { memcpy(adminKeyData+7, key, 24); r = gids_put_DO(card, GIDS_APPLET_EFID, GIDS_PUT_KEY_DO, adminKeyData, sizeof(adminKeyData)); sc_mem_clear(adminKeyData, sizeof(adminKeyData)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to set the admin key"); + LOG_TEST_RET(card->ctx, r, "gids unable to set the admin key"); return SC_SUCCESS; } @@ -1791,7 +1791,7 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) // avoid multiple initialization r = gids_check_that_card_is_new(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "card seems to have been already initialized"); + LOG_TEST_RET(card->ctx, r, "card seems to have been already initialized"); memset(&pindata, 0, sizeof(pindata)); // create PIN & PUK @@ -1802,38 +1802,38 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) pindata.pin_reference = 0x80; r = sc_pin_cmd(card, &pindata, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids set pin"); + LOG_TEST_RET(card->ctx, r, "gids set pin"); // create file r = gids_initialize_create_file(card, UserCreateDeleteDirAc, sizeof(UserCreateDeleteDirAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file UserCreateDeleteDirAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file UserCreateDeleteDirAc"); r = gids_initialize_create_file(card, EveryoneReadUserWriteAc, sizeof(EveryoneReadUserWriteAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file EveryoneReadUserWriteAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file EveryoneReadUserWriteAc"); r = gids_initialize_create_file(card, UserWriteExecuteAc, sizeof(UserWriteExecuteAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file UserWriteExecuteAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file UserWriteExecuteAc"); r = gids_initialize_create_file(card, EveryoneReadAdminWriteAc, sizeof(EveryoneReadAdminWriteAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file EveryoneReadAdminWriteAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file EveryoneReadAdminWriteAc"); r = gids_initialize_create_file(card, UserReadWriteAc, sizeof(UserReadWriteAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file UserReadWriteAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file UserReadWriteAc"); r = gids_initialize_create_file(card, AdminReadWriteAc, sizeof(AdminReadWriteAc)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file AdminReadWriteAc"); + LOG_TEST_RET(card->ctx, r, "gids to create the file AdminReadWriteAc"); //admin key r = gids_initialize_create_file(card, AdminKey, sizeof(AdminKey)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids to create the file AdminKey"); + LOG_TEST_RET(card->ctx, r, "gids to create the file AdminKey"); r = gids_set_administrator_key(card, param->init_code); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to set the admin key"); + LOG_TEST_RET(card->ctx, r, "gids unable to set the admin key"); // create the filesystem r = gids_put_DO(card, MF_FI, MF_DO, masterfile, sizeof(masterfile)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to save the masterfile"); + LOG_TEST_RET(card->ctx, r, "gids unable to save the masterfile"); r = gids_put_DO(card, CARDAPPS_FI, CARDAPPS_DO, cardapps, sizeof(cardapps)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to save the cardapps"); + LOG_TEST_RET(card->ctx, r, "gids unable to save the cardapps"); r = gids_put_DO(card, CARDCF_FI, CARDCF_DO, cardcf, sizeof(cardcf)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to save the cardcf"); + LOG_TEST_RET(card->ctx, r, "gids unable to save the cardcf"); r = gids_put_DO(card, CMAP_FI, CMAP_DO, NULL, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to save the cmapfile"); + LOG_TEST_RET(card->ctx, r, "gids unable to save the cmapfile"); #ifdef ENABLE_OPENSSL for (i = sizeof(param->cardid) -1; i >= 0; i--) { if (param->cardid[i]) break; @@ -1841,12 +1841,12 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) if (i < 0) { // set a random cardid if not set r = RAND_bytes(param->cardid, sizeof(param->cardid)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to set a random serial number"); + LOG_TEST_RET(card->ctx, r, "unable to set a random serial number"); } #endif r = gids_put_DO(card, CARDID_FI, CARDID_DO, param->cardid, sizeof(param->cardid)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids unable to save the cardid"); + LOG_TEST_RET(card->ctx, r, "gids unable to save the cardid"); //select applet sc_format_apdu(card, &apdu, SC_APDU_CASE_3, INS_SELECT, 0x00, 0x0C); @@ -1855,13 +1855,13 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // activate file sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1905,12 +1905,12 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.data = (const unsigned char *) "\x83\x01\x80"; apdu.datalen = 3; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // generate a challenge r = RAND_bytes(randomR1, 16); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to set computer random"); + LOG_TEST_RET(card->ctx, r, "unable to set computer random"); // send it to the card memcpy(apduSetRandom+4, randomR1, 16); @@ -1922,12 +1922,12 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.resplen = sizeof(apduSetRandomResponse); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // compute the half size of the mutual authentication secret r = RAND_bytes(z1, 7); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to set computer random"); + LOG_TEST_RET(card->ctx, r, "unable to set computer random"); // set the padding z1[7] = 0x80; @@ -1966,8 +1966,8 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.resplen = sizeof(apduSendResponseResponse); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); if (apdu.resplen != 44) { diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 982f910114..3bc3c0205d 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -504,9 +504,9 @@ gpk_select(sc_card_t *card, int kind, } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); /* Nothing we can say about it... invalidate * path cache */ @@ -623,7 +623,7 @@ gpk_select_file(sc_card_t *card, const sc_path_t *path, } else { if (!locked++) { r = sc_lock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed"); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); } /* Do we need to select the MF first? */ @@ -631,7 +631,7 @@ gpk_select_file(sc_card_t *card, const sc_path_t *path, r = gpk_select_id(card, GPK_SEL_MF, GPK_FID_MF, NULL); if (r) sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select MF"); + LOG_TEST_RET(card->ctx, r, "Unable to select MF"); /* Consume the MF FID if it's there */ if (pathptr[0] == GPK_FID_MF) { @@ -649,7 +649,7 @@ gpk_select_file(sc_card_t *card, const sc_path_t *path, r = gpk_select_id(card, GPK_SEL_DF, pathptr[0], NULL); if (r) sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select DF"); + LOG_TEST_RET(card->ctx, r, "Unable to select DF"); pathptr++; pathlen--; } @@ -870,9 +870,9 @@ gpk_create_file(sc_card_t *card, sc_file_t *file) } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); /* verify secure messaging response */ if (priv->key_set) @@ -967,9 +967,9 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen) apdu.le = 12; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (apdu.resplen != 12) { r = SC_ERROR_UNKNOWN_DATA_RECEIVED; @@ -1086,12 +1086,12 @@ gpk_set_security_env(sc_card_t *card, /* Select the PK file. The caller has already selected * the DF. */ r = gpk_select_id(card, GPK_SEL_EF, file_id, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to select PK file"); + LOG_TEST_RET(card->ctx, r, "Failed to select PK file"); /* Read the sys record of the PK file to find out the key length */ r = sc_read_record(card, 1, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to read PK sysrec"); + LOG_TEST_RET(card->ctx, r, "Failed to read PK sysrec"); if (r != 7 || sysrec[0] != 0) { sc_log(card->ctx, "First record of file is not the sysrec"); return SC_ERROR_OBJECT_NOT_VALID; @@ -1118,9 +1118,9 @@ gpk_set_security_env(sc_card_t *card, apdu.p2 = context; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -1184,9 +1184,9 @@ gpk_hash(sc_card_t *card, const u8 *data, size_t datalen) apdu.datalen = len + 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); chain = 0; } @@ -1205,7 +1205,7 @@ gpk_init_hashed(sc_card_t *card, const u8 *digest, unsigned int len) int r; r = reverse(tsegid, sizeof(tsegid), digest, len); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to reverse buffer"); + LOG_TEST_RET(card->ctx, r, "Failed to reverse buffer"); memset(&apdu, 0, sizeof(apdu)); apdu.cse = SC_APDU_CASE_3_SHORT; @@ -1216,9 +1216,9 @@ gpk_init_hashed(sc_card_t *card, const u8 *digest, unsigned int len) apdu.datalen = len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -1246,7 +1246,7 @@ gpk_compute_signature(sc_card_t *card, const u8 *data, return SC_ERROR_BUFFER_TOO_SMALL; r = gpk_init_hashed(card, data, data_len); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to send hash to card"); + LOG_TEST_RET(card->ctx, r, "Failed to send hash to card"); /* Now sign the hash. * The GPK has Internal Authenticate and PK_Sign. I am not @@ -1261,14 +1261,14 @@ gpk_compute_signature(sc_card_t *card, const u8 *data, apdu.le = priv->sec_mod_len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); /* The GPK returns the signature as little endian numbers. * Need to revert these */ r = reverse(out, outlen, cardsig, apdu.resplen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to reverse signature"); + LOG_TEST_RET(card->ctx, r, "Failed to reverse signature"); return r; } @@ -1299,7 +1299,7 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen, /* First revert the cryptogram */ r = reverse(buffer, sizeof(buffer), in, inlen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Cryptogram too large"); + LOG_TEST_RET(card->ctx, r, "Cryptogram too large"); in = buffer; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x1C, 0x00, 0x00); @@ -1312,13 +1312,13 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen, apdu.resplen = sizeof(buffer); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); /* Reverse the data we got back */ r = reverse(out, outlen, buffer, apdu.resplen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to reverse buffer"); + LOG_TEST_RET(card->ctx, r, "Failed to reverse buffer"); return r; } @@ -1363,9 +1363,9 @@ gpk_erase_card(sc_card_t *card) apdu.p2 = offset; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); priv->key_set = 0; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -1426,9 +1426,9 @@ gpk_lock(sc_card_t *card, struct sc_cardctl_gpk_lock *args) } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (priv->key_set) r = gpk_verify_crycks(card, &apdu, crycks); @@ -1456,9 +1456,9 @@ gpk_pkfile_init(sc_card_t *card, struct sc_cardctl_gpk_pkinit *args) apdu.p2 = args->privlen / 4; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -1493,16 +1493,16 @@ gpk_generate_key(sc_card_t *card, struct sc_cardctl_gpk_genkey *args) apdu.resplen = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); /* Return the public key, inverted. * The first two bytes must be stripped off. */ if (args->pubkey_len && apdu.resplen > 2) { r = reverse(args->pubkey, args->pubkey_len, buffer + 2, apdu.resplen - 2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to reverse buffer"); + LOG_TEST_RET(card->ctx, r, "Failed to reverse buffer"); args->pubkey_len = r; } @@ -1568,9 +1568,9 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) priv->key_set = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1610,7 +1610,7 @@ static int gpk_get_info(sc_card_t *card, int p1, int p2, u8 *buf, * without collecting the response :) */ r = sc_lock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed"); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); do { memset(&apdu, 0, sizeof(apdu)); @@ -1633,7 +1633,7 @@ static int gpk_get_info(sc_card_t *card, int p1, int p2, u8 *buf, sc_unlock(card); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -1663,7 +1663,7 @@ static int gpk_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; /* cache serial number */ diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 26db4d1728..649dbb50c5 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -191,12 +191,12 @@ static int incrypto34_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6a && apdu.sw2 == 0x82) goto end; /* no more files */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "DIRECTORY command returned error"); + LOG_TEST_RET(card->ctx, r, "DIRECTORY command returned error"); if (apdu.resplen >= 3 && ((rbuf[0] >= 0x01 && rbuf[0] <= 0x07) || 0x38 == rbuf[0]) @@ -419,10 +419,10 @@ static int incrypto34_restore_security_env(sc_card_t *card, int se_num) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -454,7 +454,7 @@ static int incrypto34_set_security_env(sc_card_t *card, key_id = env->key_ref[0]; r = incrypto34_restore_security_env(card, 1); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0); switch (env->operation) { @@ -475,10 +475,10 @@ static int incrypto34_set_security_env(sc_card_t *card, apdu.data = data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -513,7 +513,7 @@ static int do_compute_signature(sc_card_t *card, apdu.lc = datalen; apdu.datalen = datalen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { memcpy(out, rbuf, outlen); @@ -594,13 +594,13 @@ incrypto34_lifecycle_get(sc_card_t *card, int *mode) apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); if (apdu.resplen < 1) { - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Lifecycle byte not in response"); + LOG_TEST_RET(card->ctx, r, "Lifecycle byte not in response"); } r = SC_SUCCESS; @@ -642,10 +642,10 @@ incrypto34_put_data_oci(sc_card_t *card, apdu.datalen = args->len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -668,10 +668,10 @@ incrypto34_change_key_data(struct sc_card *card, apdu.datalen = args->len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -694,10 +694,10 @@ incrypto34_put_data_seci(sc_card_t *card, apdu.datalen = args->len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return r; } @@ -730,9 +730,9 @@ incrypto34_generate_key(sc_card_t *card, apdu.datalen = apdu.lc = sizeof(data); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GENERATE_KEY failed"); + LOG_TEST_RET(card->ctx, r, "GENERATE_KEY failed"); return r; } @@ -766,10 +766,10 @@ incrypto34_erase_files(sc_card_t *card) apdu.cla = 0xb0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error Erasing Filesystem"); + LOG_TEST_RET(card->ctx, r, "Card returned error Erasing Filesystem"); /* Creating ATR file*/ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe0, 0, 0); @@ -777,10 +777,10 @@ incrypto34_erase_files(sc_card_t *card) apdu.datalen = apdu.lc = sizeof(pCreateAtrFile); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error Creating ATR file"); + LOG_TEST_RET(card->ctx, r, "Card returned error Creating ATR file"); /* Filling ATR file*/ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xd6, 0, 0); @@ -788,10 +788,10 @@ incrypto34_erase_files(sc_card_t *card) apdu.datalen = apdu.lc = sizeof(pWriteAtr); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error Filling ATR file"); + LOG_TEST_RET(card->ctx, r, "Card returned error Filling ATR file"); /* Creating DIR-ADO file*/ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe0, 0, 0); @@ -799,10 +799,10 @@ incrypto34_erase_files(sc_card_t *card) apdu.datalen = apdu.lc = sizeof(pCreateEF_DIR_ADOFile); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error Creating DIR-ADO file"); + LOG_TEST_RET(card->ctx, r, "Card returned error Creating DIR-ADO file"); return r; diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 04bfec687e..463fdd8d3d 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -260,10 +260,10 @@ static int itacns_restore_security_env(sc_card_t *card, int se_num) apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); SC_FUNC_RETURN(card->ctx, 1, r); } @@ -302,7 +302,7 @@ static int itacns_set_security_env(sc_card_t *card, so far want 0x03. */ r = itacns_restore_security_env(card, (card->type == SC_CARD_TYPE_ITACNS_CIE_V1 ? 0x30 : 0x03)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0); switch (env->operation) { @@ -329,10 +329,10 @@ static int itacns_set_security_env(sc_card_t *card, apdu.data = data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); SC_FUNC_RETURN(card->ctx, 1, r); } diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index 1e5643b23b..99c4d9e862 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -733,7 +733,7 @@ static int jcop_compute_signature(sc_card_t *card, apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { int len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -784,7 +784,7 @@ static int jcop_decipher(sc_card_t *card, apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { int len = apdu.resplen > outlen ? outlen : apdu.resplen; diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index a696af71d6..3dfdfb34b4 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -193,7 +193,7 @@ static int masktech_decipher(sc_card_t *card, apdu.datalen = crgram_len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -222,7 +222,7 @@ static int masktech_pin_unblock(sc_card_t *card, verify_data.pin1.prompt = data->pin1.prompt; rv = iso_ops->pin_cmd(card, &verify_data, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - verify unblock PIN"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify unblock PIN"); /* Build a SC_PIN_CMD_UNBLOCK APDU */ memset(&reset_data, 0, sizeof(reset_data)); @@ -236,7 +236,7 @@ static int masktech_pin_unblock(sc_card_t *card, reset_data.pin2.prompt = data->pin2.prompt; rv = iso_ops->pin_cmd(card, &reset_data, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - reset unblock PIN"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - reset unblock PIN"); return 0; } @@ -259,7 +259,7 @@ static int masktech_pin_change(sc_card_t *card, verify_data.pin1.prompt = data->pin1.prompt; rv = iso_ops->pin_cmd(card, &verify_data, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - verify change PIN"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify change PIN"); /* Build a SC_PIN_CMD_CHANGE APDU */ memset(&change_data, 0, sizeof(change_data)); @@ -273,7 +273,7 @@ static int masktech_pin_change(sc_card_t *card, change_data.pin2.prompt = data->pin2.prompt; rv = iso_ops->pin_cmd(card, &change_data, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed - change PIN"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - change PIN"); return 0; } @@ -320,7 +320,7 @@ static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) rv = sc_transmit_apdu(card, &apdu); card->cla = 0x00; - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 9c38a431e8..7784f15bc5 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -206,7 +206,7 @@ static int mcrd_delete_ref_to_authkey(sc_card_t * card) apdu.lc = 2; apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -226,7 +226,7 @@ static int mcrd_delete_ref_to_signkey(sc_card_t * card) apdu.lc = 2; apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -245,10 +245,10 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) /* track the active keypair */ sc_format_path("0033", &path); r = sc_select_file(card, &path, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Can't select keyref info file 0x0033"); + LOG_TEST_RET(card->ctx, r, "Can't select keyref info file 0x0033"); r = sc_read_record(card, 1, keyref_data, SC_ESTEID_KEYREF_FILE_RECLEN, SC_RECORD_BY_REC_NR); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Can't read keyref info file!"); + LOG_TEST_RET(card->ctx, r, "Can't read keyref info file!"); sc_log(card->ctx, "authkey reference 0x%02x%02x\n", @@ -275,7 +275,7 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) apdu.lc = 5; apdu.datalen = 5; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -413,7 +413,7 @@ static int load_special_files(sc_card_t * card) /* Read rule file. Note that we bypass our cache here. */ r = select_part(card, MCRD_SEL_EF, EF_Rule, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "selecting EF_Rule failed"); + LOG_TEST_RET(ctx, r, "selecting EF_Rule failed"); for (recno = 1;; recno++) { u8 recbuf[256]; @@ -444,7 +444,7 @@ static int load_special_files(sc_card_t * card) sc_log(ctx, "no EF_KeyD file available\n"); return 0; /* That is okay. */ } - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "selecting EF_KeyD failed"); + LOG_TEST_RET(ctx, r, "selecting EF_KeyD failed"); for (recno = 1;; recno++) { u8 recbuf[256]; @@ -777,7 +777,7 @@ do_select(sc_card_t * card, u8 kind, apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (!file) { if (apdu.sw1 == 0x61) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0); @@ -867,7 +867,7 @@ select_down(sc_card_t * card, for (; pathlen; pathlen--, pathptr++) { if (priv->curpathlen == MAX_CURPATH) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL, + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "path too long for cache"); r = -1; /* force DF select. */ if (pathlen == 1 && !df_only) { @@ -880,7 +880,7 @@ select_down(sc_card_t * card, if (r) r = select_part(card, MCRD_SEL_DF, *pathptr, pathlen == 1 ? file : NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select DF"); + LOG_TEST_RET(card->ctx, r, "unable to select DF"); priv->curpath[priv->curpathlen] = *pathptr; priv->curpathlen++; } @@ -922,7 +922,7 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, /* MF requested: clear the cache and select it. */ priv->curpathlen = 0; r = select_part(card, MCRD_SEL_MF, pathptr[0], file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select MF"); + LOG_TEST_RET(card->ctx, r, "unable to select MF"); priv->curpath[0] = pathptr[0]; priv->curpathlen = 1; priv->is_ef = 0; @@ -970,7 +970,7 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, /* Relative addressing without a current path. So we select the MF first. */ r = select_part(card, MCRD_SEL_MF, pathptr[0], file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select MF"); + LOG_TEST_RET(card->ctx, r, "unable to select MF"); priv->curpath[0] = pathptr[0]; priv->curpathlen = 1; priv->is_ef = 0; @@ -1022,7 +1022,7 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr, /* MF requested: clear the cache and select it. */ priv->curpathlen = 0; r = select_part(card, MCRD_SEL_MF, MFID, file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select MF"); + LOG_TEST_RET(card->ctx, r, "unable to select MF"); priv->curpath[0] = MFID; priv->curpathlen = 1; priv->is_ef = 0; @@ -1032,7 +1032,7 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr, /* Relative addressing without a current path. So we select the MF first. */ r = select_part(card, MCRD_SEL_MF, pathptr[0], file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to select MF"); + LOG_TEST_RET(card->ctx, r, "unable to select MF"); priv->curpath[0] = pathptr[0]; priv->curpathlen = 1; priv->is_ef = 0; @@ -1146,7 +1146,7 @@ static int mcrd_restore_se(sc_card_t * card, int se_num) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -1282,7 +1282,7 @@ static int mcrd_set_security_env(sc_card_t * card, /* Need to restore the security environment. */ if (num) { r = mcrd_restore_se(card, num); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "mcrd_enable_se failed"); } p += 2; @@ -1299,7 +1299,7 @@ static int mcrd_set_security_env(sc_card_t * card, apdu.resplen = 0; if (se_num > 0) { r = sc_lock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed"); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); locked = 1; } if (apdu.datalen != 0) { @@ -1319,7 +1319,7 @@ static int mcrd_set_security_env(sc_card_t * card, if (se_num <= 0) return 0; sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); err: if (locked) @@ -1369,9 +1369,9 @@ static int mcrd_compute_signature(sc_card_t * card, apdu.resplen = outlen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); } diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index ab02be76a8..633d2c73cc 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -217,11 +217,11 @@ static int miocos_create_file(sc_card_t *card, sc_file_t *file) apdu.lc = buflen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89) return SC_ERROR_FILE_ALREADY_EXISTS; r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); + LOG_TEST_RET(card->ctx, r, "Card returned error"); return 0; } @@ -330,7 +330,7 @@ static int miocos_get_acl(sc_card_t *card, sc_file_t *file) apdu.resplen = sizeof(rbuf); apdu.le = sizeof(rbuf); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.resplen == 0) return sc_check_sw(card, apdu.sw1, apdu.sw2); left = apdu.resplen; @@ -338,7 +338,7 @@ static int miocos_get_acl(sc_card_t *card, sc_file_t *file) SC_ASN1_SEQUENCE | SC_ASN1_CONS, &left); if (seq == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to process reply"); + LOG_TEST_RET(card->ctx, r, "Unable to process reply"); for (i = 1; i < 15; i++) { int j; const u8 *tag; @@ -401,7 +401,7 @@ static int miocos_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resplen = buflen; apdu.le = buflen > 256 ? 256 : buflen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.resplen == 0) return sc_check_sw(card, apdu.sw1, apdu.sw2); return apdu.resplen; @@ -418,13 +418,13 @@ static int miocos_delete_file(sc_card_t *card, const sc_path_t *path) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } r = sc_select_file(card, path, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to select file to be deleted"); + LOG_TEST_RET(card->ctx, r, "Unable to select file to be deleted"); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); apdu.cla = 0xA0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -461,7 +461,7 @@ static int miocos_create_ac(sc_card_t *card, apdu.datalen = sendsize; apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index d62317a075..3cb4ec5ee9 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -748,7 +748,7 @@ static int muscle_decipher(sc_card_t * card, out, crgram_len, out_len); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card signature failed"); + LOG_TEST_RET(card->ctx, r, "Card signature failed"); return r; } @@ -774,7 +774,7 @@ static int muscle_compute_signature(sc_card_t *card, const u8 *data, out, data_len, outlen); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card signature failed"); + LOG_TEST_RET(card->ctx, r, "Card signature failed"); return r; } @@ -783,7 +783,7 @@ static int muscle_get_challenge(sc_card_t *card, u8 *rnd, size_t len) if (len == 0) return SC_SUCCESS; else { - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_TEST_RET(card->ctx, msc_get_challenge(card, len, 0, NULL, rnd), "GET CHALLENGE cmd failed"); return (int) len; diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 5fead22272..444ac22357 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -301,11 +301,11 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier, apdu.data = data; apdu.datalen = data_len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (send_logout++ == 0 && apdu.sw1 == 0x6F && apdu.sw2 == 0x86) { r = sc_logout(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Logout failed"); + LOG_TEST_RET(card->ctx, r, "Logout failed"); } else break; @@ -315,7 +315,7 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier, /* Verification failed */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, ref_qualifier); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r == SC_ERROR_PIN_CODE_INCORRECT && tries_left) @@ -332,7 +332,7 @@ static int rtecp_logout(sc_card_t *card) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x40, 0, 0); apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -442,7 +442,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, if (type == SC_AC_CHV && old && oldlen != 0) { r = sc_verify(card, type, ref_qualifier, old, oldlen, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Verify old pin failed"); + LOG_TEST_RET(card->ctx, r, "Verify old pin failed"); } max_transmit_length = sc_get_max_send_size(card); @@ -491,7 +491,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, r = sc_transmit_apdu(card, &apdu); sc_mem_clear(buf, buf_length); free(buf); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -508,9 +508,9 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x03, ref_qualifier); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unblock card failed"); + LOG_TEST_RET(card->ctx, r, "Unblock card failed"); if (newref && newlen) { u8 tmp[2], buf[SC_MAX_APDU_BUFFER_SIZE]; @@ -520,7 +520,7 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, tmp[1] = newlen & 0xFF; sc_asn1_put_tag(0x80, tmp, sizeof(tmp), p, sizeof(buf) - (p - buf), &p); r = sc_asn1_put_tag(0xA5, newref, newlen, p, sizeof(buf) - (p - buf), &p); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Invalid new PIN length"); + LOG_TEST_RET(card->ctx, r, "Invalid new PIN length"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); apdu.lc = p - buf; @@ -528,9 +528,9 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, apdu.datalen = p - buf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Set PIN failed"); + LOG_TEST_RET(card->ctx, r, "Set PIN failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -544,7 +544,7 @@ static int rtecp_create_file(sc_card_t *card, sc_file_t *file) if (file->sec_attr_len == 0) { r = set_sec_attr_from_acl(card, file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Set sec_attr from ACL failed"); + LOG_TEST_RET(card->ctx, r, "Set sec_attr from ACL failed"); } assert(iso_ops && iso_ops->create_file); r = iso_ops->create_file(card, file); @@ -567,12 +567,12 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) break; /* Next file not found */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, ""); + LOG_TEST_RET(card->ctx, r, ""); if (apdu.resplen <= 2) LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); @@ -599,9 +599,9 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) /* Select parent DF of the current DF */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x03, 0); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, ""); + LOG_TEST_RET(card->ctx, r, ""); } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0x02); apdu.lc = sizeof(previd); @@ -659,7 +659,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (!r && request == SC_CARDCTL_RTECP_GENERATE_KEY) { diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 6fcea6c51b..49cc9db2bb 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -257,12 +257,12 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resplen = sizeof(rbuf); apdu.le = 256; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) break; /* Next file not found */ ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, ""); + LOG_TEST_RET(card->ctx, ret, ""); if (apdu.resplen <= 2) LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); @@ -292,9 +292,9 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resplen = sizeof(rbuf); apdu.le = 256; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, ""); + LOG_TEST_RET(card->ctx, ret, ""); } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0x02); apdu.lc = sizeof(previd); @@ -406,7 +406,7 @@ static int rutoken_select_file(sc_card_t *card, apdu.le = 256; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); if (file_out == NULL) { if (apdu.sw1 == 0x61) @@ -414,7 +414,7 @@ static int rutoken_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, ""); + LOG_TEST_RET(card->ctx, ret, ""); if (apdu.resplen > 0 && apdu.resp[0] != 0x62) /* Tag 0x62 - FCP */ LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); @@ -605,7 +605,7 @@ static int rutoken_create_file(sc_card_t *card, sc_file_t *file) if (file->sec_attr_len == 0) { ret = set_sec_attr_from_acl(card, file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Set sec_attr from ACL failed"); + LOG_TEST_RET(card->ctx, ret, "Set sec_attr from ACL failed"); } assert(iso_ops && iso_ops->create_file); ret = iso_ops->create_file(card, file); @@ -634,7 +634,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) } else /* No file ID given: means currently selected file */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } @@ -658,9 +658,9 @@ static int rutoken_verify(sc_card_t *card, unsigned int type, int ref_qualifier, sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x40, 0x00, 0x00); apdu.cla = 0x80; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Reset access rights failed"); + LOG_TEST_RET(card->ctx, ret, "Reset access rights failed"); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, ref_qualifier); @@ -668,13 +668,13 @@ static int rutoken_verify(sc_card_t *card, unsigned int type, int ref_qualifier, apdu.datalen = data_len; apdu.data = data; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); if (ret == SC_ERROR_PIN_CODE_INCORRECT && tries_left) { sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, ref_qualifier); ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); if (ret == SC_ERROR_PIN_CODE_INCORRECT) *tries_left = (int)(apdu.sw2 & 0x0f); @@ -691,12 +691,12 @@ static int rutoken_logout(sc_card_t *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_format_path("3F00", &path); ret = rutoken_select_file(card, &path, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Select MF failed"); + LOG_TEST_RET(card->ctx, ret, "Select MF failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x40, 0x00, 0x00); apdu.cla = 0x80; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_FUNC_RETURN(card->ctx, ret); } @@ -712,14 +712,14 @@ static int rutoken_change_reference_data(sc_card_t *card, unsigned int type, if (old && oldlen) { ret = rutoken_verify(card, type, ref_qualifier, old, oldlen, tries_left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Invalid 'old' pass"); + LOG_TEST_RET(card->ctx, ret, "Invalid 'old' pass"); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); apdu.lc = newlen; apdu.datalen = newlen; apdu.data = newref; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_FUNC_RETURN(card->ctx, ret); } @@ -740,12 +740,12 @@ static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, { ret = rutoken_verify(card, type, ref_qualifier, puk, puklen, &left); sc_log(card->ctx, "Tries left: %i\n", left); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "Invalid 'puk' pass"); + LOG_TEST_RET(card->ctx, ret, "Invalid 'puk' pass"); } #endif sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2c, 0x03, ref_qualifier); ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_FUNC_RETURN(card->ctx, ret); } @@ -758,7 +758,7 @@ static int rutoken_restore_security_env(sc_card_t *card, int se_num) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 3, se_num); ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_FUNC_RETURN(card->ctx, ret); } @@ -808,7 +808,7 @@ static int rutoken_set_security_env(sc_card_t *card, } /* set SE */ ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_FUNC_RETURN(card->ctx, ret); } @@ -870,7 +870,7 @@ static int rutoken_key_gen(sc_card_t *card, sc_DOHdrV2_t *pHdr) apdu.data = data; apdu.datalen = apdu.lc = data_len; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); @@ -913,7 +913,7 @@ static int rutoken_create_do(sc_card_t *card, sc_DO_V2_t * pDO) apdu.data = data; apdu.datalen = apdu.lc = data_len; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); @@ -959,7 +959,7 @@ static int rutoken_get_do_info(sc_card_t *card, sc_DO_INFO_t * pInfo) break; } ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); @@ -985,7 +985,7 @@ static int rutoken_delete_do(sc_card_t *card, u8 *pId) apdu.datalen = sizeof(data); apdu.lc = sizeof(data); ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); @@ -1027,7 +1027,7 @@ static int rutoken_cipher_p(sc_card_t *card, const u8 * crgram, size_t crgram_le apdu.resp = buf; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); if (ret == SC_SUCCESS) { @@ -1113,7 +1113,7 @@ static int rutoken_compute_mac_gost(sc_card_t *card, else apdu.cla = 0x10; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); } while (ret == SC_SUCCESS && ilen != 0); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); @@ -1169,7 +1169,7 @@ static int rutoken_get_serial(sc_card_t *card, sc_serial_number_t *serial) apdu.resplen = sizeof(serial->value); apdu.le = 4; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); serial->len = apdu.resplen; swap_four(serial->value, serial->len); @@ -1188,7 +1188,7 @@ static int rutoken_get_info(sc_card_t *card, void *buff) apdu.resplen = sizeof(rbuf); apdu.le = sizeof(rbuf); ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); if (ret == SC_SUCCESS) memcpy(buff, apdu.resp, apdu.resplen); @@ -1204,7 +1204,7 @@ static int rutoken_format(sc_card_t *card, int apdu_ins) sc_format_apdu(card, &apdu, SC_APDU_CASE_1, apdu_ins, 0x00, 0x00); apdu.cla = 0x80; ret = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, ret, "APDU transmit failed"); ret = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret); } diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index a1facab0c9..ea085f615f 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -634,7 +634,7 @@ static int setcos_set_security_env2(sc_card_t *card, apdu.resplen = 0; if (se_num > 0) { r = sc_lock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed"); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); locked = 1; } if (apdu.datalen != 0) { @@ -656,7 +656,7 @@ static int setcos_set_security_env2(sc_card_t *card, sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num); r = sc_transmit_apdu(card, &apdu); sc_unlock(card); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); err: if (locked) @@ -952,7 +952,7 @@ static int setcos_list_files(sc_card_t *card, u8 * buf, size_t buflen) apdu.resplen = buflen; apdu.le = buflen > 256 ? 256 : buflen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (card->type == SC_CARD_TYPE_SETCOS_44 && apdu.sw1 == 0x6A && apdu.sw2 == 0x82) return 0; /* no files found */ if (apdu.resplen == 0) @@ -998,10 +998,10 @@ static int setcos_putdata(struct sc_card *card, struct sc_cardctl_setcos_data_ob apdu.data = data_obj->Data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "PUT_DATA returned error"); + LOG_TEST_RET(card->ctx, r, "PUT_DATA returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1029,10 +1029,10 @@ static int setcos_getdata(struct sc_card *card, struct sc_cardctl_setcos_data_ob apdu.resplen = data_obj->DataLen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA returned error"); + LOG_TEST_RET(card->ctx, r, "GET_DATA returned error"); if (apdu.resplen > data_obj->DataLen) r = SC_ERROR_WRONG_LENGTH; @@ -1085,10 +1085,10 @@ static int setcos_generate_store_key(sc_card_t *card, apdu.lc = len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "STORE/GENERATE_KEY returned error"); + LOG_TEST_RET(card->ctx, r, "STORE/GENERATE_KEY returned error"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1103,10 +1103,10 @@ static int setcos_activate_file(sc_card_t *card) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "ACTIVATE_FILE returned error"); + LOG_TEST_RET(card->ctx, r, "ACTIVATE_FILE returned error"); LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 1e34ef6717..c5540a4aef 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -462,7 +462,7 @@ static int starcos_select_aid(sc_card_t *card, apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* check return value */ if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 ) @@ -531,7 +531,7 @@ static int starcos_select_fid(sc_card_t *card, } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.p2 == 0x00 && apdu.sw1 == 0x62 && apdu.sw2 == 0x84 ) { /* no FCI => we have a DF (see comment in process_fci()) */ @@ -541,7 +541,7 @@ static int starcos_select_fid(sc_card_t *card, apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); } else if ((card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) && apdu.p2 == 0x4 && apdu.sw1 == 0x6a && apdu.sw2 == 0x82) { @@ -553,7 +553,7 @@ static int starcos_select_fid(sc_card_t *card, apdu.le = 256; apdu.lc = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); } else if (apdu.sw1 == 0x61 || (apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && !isMF)) { /* SELECT returned some data (possible FCI) => * try a READ BINARY to see if a EF is selected */ @@ -565,7 +565,7 @@ static int starcos_select_fid(sc_card_t *card, apdu2.le = 1; apdu2.lc = 0; r = sc_transmit_apdu(card, &apdu2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu2.sw1 == 0x69 && apdu2.sw2 == 0x86) { /* no current EF is selected => we have a DF */ bIsDF = 1; @@ -744,7 +744,7 @@ static int starcos_select_file(sc_card_t *card, /* first step: change directory */ r = starcos_select_fid(card, path[bMatch], path[bMatch+1], NULL, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); memset(&new_path, 0, sizeof(sc_path_t)); new_path.type = SC_PATH_TYPE_PATH; @@ -784,7 +784,7 @@ static int starcos_select_file(sc_card_t *card, for ( i=0; ictx, SC_LOG_DEBUG_NORMAL, r, "SELECT FILE (DF-ID) failed"); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } return starcos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out, 1); } @@ -992,7 +992,7 @@ static int starcos_create_mf(sc_card_t *card, sc_starcos_create_data *data) apdu.data = (u8 *) data->data.mf.header; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -1028,7 +1028,7 @@ static int starcos_create_df(sc_card_t *card, sc_starcos_create_data *data) apdu.data = data->data.df.header; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); /* second step: CREATE DF */ sc_log(ctx, "calling CREATE DF\n"); @@ -1039,7 +1039,7 @@ static int starcos_create_df(sc_card_t *card, sc_starcos_create_data *data) apdu.data = data->data.df.header; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -1069,7 +1069,7 @@ static int starcos_create_ef(sc_card_t *card, sc_starcos_create_data *data) apdu.data = (u8 *) data->data.ef.header; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -1101,7 +1101,7 @@ static int starcos_create_end(sc_card_t *card, sc_file_t *file) apdu.datalen = 2; apdu.data = fid; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -1168,7 +1168,7 @@ static int starcos_erase_card(sc_card_t *card) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_invalidate_cache(card); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) /* no MF to delete, ignore error */ @@ -1211,7 +1211,7 @@ static int starcos_write_key(sc_card_t *card, sc_starcos_wkey_data *data) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); if (data->key == NULL) @@ -1241,7 +1241,7 @@ static int starcos_write_key(sc_card_t *card, sc_starcos_wkey_data *data) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); offset += clen; @@ -1280,7 +1280,7 @@ static int starcos_gen_key(sc_card_t *card, sc_starcos_gen_key_data *data) apdu.lc = 2; apdu.datalen = 2; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); /* read public key via READ PUBLIC KEY */ @@ -1294,7 +1294,7 @@ static int starcos_gen_key(sc_card_t *card, sc_starcos_gen_key_data *data) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1388,7 +1388,7 @@ static int starcos_set_security_env(sc_card_t *card, apdu.lc = p - sbuf; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -1427,7 +1427,7 @@ static int starcos_set_security_env(sc_card_t *card, apdu.lc = p - sbuf; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); return SC_SUCCESS; @@ -1477,7 +1477,7 @@ static int starcos_set_security_env(sc_card_t *card, /* we don't know whether to use * COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */ r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { ex_data->fix_digestInfo = 0; ex_data->sec_ops = SC_SEC_OPERATION_SIGN; @@ -1502,7 +1502,7 @@ static int starcos_set_security_env(sc_card_t *card, apdu.lc = p - sbuf; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); ex_data->fix_digestInfo = env->algorithm_flags; @@ -1546,7 +1546,7 @@ static int starcos_compute_signature(sc_card_t *card, } tmp_len = sizeof(sbuf); r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_pkcs1_encode failed"); + LOG_TEST_RET(card->ctx, r, "sc_pkcs1_encode failed"); } else { memcpy(sbuf, data, datalen); tmp_len = datalen; @@ -1559,7 +1559,7 @@ static int starcos_compute_signature(sc_card_t *card, apdu.resplen = sizeof(rbuf); apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } else { /* set the hash value */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, @@ -1572,7 +1572,7 @@ static int starcos_compute_signature(sc_card_t *card, apdu.lc = datalen; apdu.datalen = datalen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -1587,7 +1587,7 @@ static int starcos_compute_signature(sc_card_t *card, apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -1621,7 +1621,7 @@ static int starcos_compute_signature(sc_card_t *card, apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; @@ -1778,7 +1778,7 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; /* cache serial number */ @@ -1838,7 +1838,7 @@ static int starcos_logout(sc_card_t *card) apdu.resplen = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU re-transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) /* the only possible reason for this error here is, afaik, diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index d9db4aede0..490ae31244 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -221,7 +221,7 @@ static int tcos_create_file(sc_card_t *card, sc_file_t *file) len = SC_MAX_APDU_BUFFER_SIZE; r = tcos_construct_fci(file, sbuf, &len); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "tcos_construct_fci() failed"); + LOG_TEST_RET(card->ctx, r, "tcos_construct_fci() failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); apdu.cla |= 0x80; /* this is an proprietary extension */ @@ -230,7 +230,7 @@ static int tcos_create_file(sc_card_t *card, sc_file_t *file) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -392,7 +392,7 @@ static int tcos_select_file(sc_card_t *card, } r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r || file_out == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -431,10 +431,10 @@ static int tcos_list_files(sc_card_t *card, u8 *buf, size_t buflen) apdu.resplen = sizeof(rbuf); apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); if (apdu.sw1==0x6A && (apdu.sw2==0x82 || apdu.sw2==0x88)) continue; r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "List Dir failed"); + LOG_TEST_RET(ctx, r, "List Dir failed"); if (apdu.resplen > buflen) return SC_ERROR_BUFFER_TOO_SMALL; sc_log(ctx, "got %"SC_FORMAT_LEN_SIZE_T"u %s-FileIDs\n", @@ -469,7 +469,7 @@ static int tcos_delete_file(sc_card_t *card, const sc_path_t *path) apdu.data = sbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -575,7 +575,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal apdu.lc = apdu.datalen = dlen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (tcos3 && apdu.p1==0x80 && apdu.sw1==0x6A && apdu.sw2==0x87) { int keylen=128; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A,0x80,0x86); @@ -590,7 +590,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal apdu.data = sbuf; apdu.lc = apdu.datalen = dlen; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } if (apdu.sw1==0x90 && apdu.sw2==0x00) { size_t len = apdu.resplen>outlen ? outlen : apdu.resplen; @@ -631,7 +631,7 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, memcpy(sbuf+1, crgram, crgram_len); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1==0x90 && apdu.sw2==0x00) { size_t len= (apdu.resplen>outlen) ? outlen : apdu.resplen; @@ -663,7 +663,7 @@ static int tcos_setperm(sc_card_t *card, int enable_nullpin) apdu.data = NULL; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } diff --git a/src/libopensc/card.c b/src/libopensc/card.c index ad04774d25..ecfcb7906a 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1507,7 +1507,7 @@ sc_card_sm_check(struct sc_card *card) sc_log(ctx, "module_data '%s'", module_data); rv = card->sm_ctx.module.ops.module_init(ctx, module_data); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot initialize SM module"); + LOG_TEST_RET(ctx, rv, "Cannot initialize SM module"); } /* initialize SM session in the case of 'APDU TRANSMIT' SM mode */ diff --git a/src/libopensc/ctbcs.c b/src/libopensc/ctbcs.c index 166358a0b3..a5d49d3d7d 100644 --- a/src/libopensc/ctbcs.c +++ b/src/libopensc/ctbcs.c @@ -222,7 +222,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) sc_log(reader->ctx, "unable to destroy mutex\n"); return s; } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* Check CTBCS status word */ switch (((unsigned int) apdu.sw1 << 8) | apdu.sw2) { @@ -245,7 +245,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) r = SC_ERROR_CARD_CMD_FAILED; break; } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "PIN command failed"); + LOG_TEST_RET(card->ctx, r, "PIN command failed"); /* Calling Function may expect SW1/SW2 in data-apdu set... */ if (data->apdu) { diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 900164adc0..6c27a38bb9 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1207,10 +1207,10 @@ static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, si apdu.resp = buf; apdu.resplen = len; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "GET_DATA returned error"); + LOG_TEST_RET(card->ctx, r, "GET_DATA returned error"); if (apdu.resplen > len) r = SC_ERROR_WRONG_LENGTH; diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 2715a4be3a..127f741dd1 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -93,7 +93,7 @@ int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *da apdu.resplen = dataLength; apdu.resp = data; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) return dataLength; if(apdu.sw1 == 0x9C) { @@ -120,7 +120,7 @@ int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size for(i = 0; i < dataLength; i += max_read_unit) { r = msc_partial_read_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_read_unit)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Error in partial object read"); + LOG_TEST_RET(card->ctx, r, "Error in partial object read"); } return dataLength; } @@ -134,7 +134,7 @@ int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength) memset(zeroBuffer, 0, max_write_unit); for(i = 0; i < dataLength; i += max_write_unit) { int r = msc_partial_update_object(card, objectId, i, zeroBuffer, MIN(dataLength - i, max_write_unit)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Error in zeroing file update"); + LOG_TEST_RET(card->ctx, r, "Error in zeroing file update"); } return 0; } @@ -156,7 +156,7 @@ int msc_create_object(sc_card_t *card, msc_id objectId, size_t objectSize, unsig ushort2bebytes(buffer + 10, writeAcl); ushort2bebytes(buffer + 12, deleteAcl); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) return objectSize; if(apdu.sw1 == 0x9C) { @@ -197,7 +197,7 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons apdu.data = buffer; apdu.datalen = apdu.lc; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) return dataLength; if(apdu.sw1 == 0x9C) { @@ -224,7 +224,7 @@ int msc_update_object(sc_card_t *card, msc_id objectId, int offset, const u8 *da size_t max_write_unit = MSC_MAX_SEND - 9; for(i = 0; i < dataLength; i += max_write_unit) { r = msc_partial_update_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_write_unit)); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Error in partial object update"); + LOG_TEST_RET(card->ctx, r, "Error in partial object update"); } return dataLength; } @@ -239,7 +239,7 @@ int msc_delete_object(sc_card_t *card, msc_id objectId, int zero) apdu.data = objectId.id; apdu.datalen = 4; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) return 0; if(apdu.sw1 == 0x9C) { @@ -269,7 +269,7 @@ int msc_select_applet(sc_card_t *card, u8 *appletId, size_t appletIdLength) apdu.le = 0; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) return 1; @@ -296,7 +296,7 @@ int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return 0; } else if(apdu.sw1 == 0x63) { /* Invalid auth */ @@ -341,7 +341,7 @@ int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukL if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return 0; } else if(apdu.sw1 == 0x63) { /* Invalid auth */ @@ -383,7 +383,7 @@ int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return 0; } else if(apdu.sw1 == 0x63) { /* Invalid auth */ @@ -468,7 +468,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short free(apdu.resp); } free(buffer); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(location == 1) { if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return SC_SUCCESS; @@ -542,7 +542,7 @@ int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int alg apdu.lc = 16; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return 0; } @@ -569,7 +569,7 @@ int msc_extract_key(sc_card_t *card, apdu.datalen = 1; apdu.lc = 1; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { return 0; } @@ -670,7 +670,7 @@ int msc_compute_crypt_init(sc_card_t *card, memcpy(ptr, initData, dataLength); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; *outputDataLength = receivedData; @@ -721,7 +721,7 @@ int msc_compute_crypt_final( memcpy(ptr, inputData, dataLength); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; *outputDataLength = receivedData; @@ -787,7 +787,7 @@ static int msc_compute_crypt_final_object( if(r < 0) return r; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { r = msc_read_object(card, inputId, 2, outputData, dataLength); if (r >= 0) @@ -959,7 +959,7 @@ int msc_import_key(sc_card_t *card, ushort2bebytes(p, writeAcl); p+=2; ushort2bebytes(p, use); r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { msc_delete_object(card, outputId, 0); return 0; diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index 47573bb592..b87ef5845d 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -119,7 +119,7 @@ int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card, r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); + LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 2b8d66b913..e416b18d7e 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -55,7 +55,7 @@ select_esteid_df (sc_card_t * card) sc_path_t tmppath; sc_format_path ("3F00EEEE", &tmppath); r = sc_select_file (card, &tmppath, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "esteid select DF failed"); + LOG_TEST_RET(card->ctx, r, "esteid select DF failed"); return r; } @@ -74,11 +74,11 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* Select application directory */ sc_format_path ("3f00eeee5044", &tmppath); r = sc_select_file (card, &tmppath, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "select esteid PD failed"); + LOG_TEST_RET(card->ctx, r, "select esteid PD failed"); /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); + LOG_TEST_RET(card->ctx, r, "read document number failed"); buff[MIN((size_t) r, (sizeof buff)-1)] = '\0'; set_string (&p15card->tokeninfo->serial_number, (const char *) buff); diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index 263037d0ec..d0fb9fda62 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -70,7 +70,7 @@ static int sc_pkcs15emu_gids_add_prkey(sc_pkcs15_card_t * p15card, sc_cardctl_gi prkey_obj.auth_id.value[0] = 0x80; r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to sc_pkcs15emu_add_rsa_prkey"); + LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_rsa_prkey"); memset(&pubkey_info, 0, sizeof(pubkey_info)); memset(&pubkey_obj, 0, sizeof(pubkey_obj)); @@ -86,7 +86,7 @@ static int sc_pkcs15emu_gids_add_prkey(sc_pkcs15_card_t * p15card, sc_cardctl_gi pubkey_info.id = prkey_info.id; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to sc_pkcs15emu_add_rsa_pubkey"); + LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_rsa_pubkey"); if (container->certificatepath.len > 0) { memset(&cert_info, 0, sizeof(cert_info)); @@ -122,10 +122,10 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) int has_puk; r = sc_card_ctl(card, SC_CARDCTL_GIDS_GET_ALL_CONTAINERS, &recordsnum); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the containers. Uninitialized card ?"); + LOG_TEST_RET(card->ctx, r, "unable to get the containers. Uninitialized card ?"); r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, NULL); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to get the serial number. Uninitialized card ?"); + LOG_TEST_RET(card->ctx, r, "unable to get the serial number. Uninitialized card ?"); p15card->tokeninfo->serial_number = (char*) malloc(card->serialnr.len *2 +1); if (!p15card->tokeninfo->serial_number) { @@ -197,7 +197,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to sc_pkcs15emu_add_pin_obj"); + LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj"); if (has_puk) { pin_info.auth_id.value[0] = 0x81; @@ -208,11 +208,11 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) strlcpy(pin_obj.label, "PUK", sizeof(pin_obj.label)); pin_obj.auth_id.len = 0; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to sc_pkcs15emu_add_pin_obj with PUK"); + LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj with PUK"); } r = sc_card_ctl(card, SC_CARDCTL_GIDS_GET_ALL_CONTAINERS, &recordsnum); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_card_ctl SC_CARDCTL_GIDS_GET_ALL_CONTAINERS"); + LOG_TEST_RET(card->ctx, r, "sc_card_ctl SC_CARDCTL_GIDS_GET_ALL_CONTAINERS"); for (i = 0; i < recordsnum; i++) { sc_cardctl_gids_get_container_t container; diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index c99f6cb84d..438bd52eae 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -232,14 +232,14 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, obj.flags = obj_flags; r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add X.509 certificate"); /* If we have OpenSSL, read keyUsage */ #ifdef ENABLE_OPENSSL r = sc_pkcs15_read_certificate(p15card, &info, &cert); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not read X.509 certificate"); { @@ -296,7 +296,7 @@ static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, *modulus_len_out = info.modulus_length; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add pub key"); return r; } @@ -510,7 +510,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) sizeof(obj.label)); data.path = path; rv = sc_pkcs15emu_add_data_object(p15card, &obj, &data); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, rv, + LOG_TEST_RET(p15card->card->ctx, rv, "Could not add data file"); } @@ -590,7 +590,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, sc_format_path(pubkey_path, &path); r = itacns_add_pubkey(p15card, &path, cert_id, label, pubkey_usage_flags, sec_env, 0, &modulus_length); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add public key"); } @@ -606,7 +606,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, modulus_length, prkey_usage_flags, private_path, sec_env, cert_id, SC_PKCS15_CO_FLAG_PRIVATE); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add private key"); /* PIN and PUK */ @@ -619,7 +619,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, | SC_PKCS15_PIN_FLAG_INITIALIZED; r = itacns_add_pin(p15card, pinlabel, sec_env, fake_puk_authid, pin_ref, private_path, pin_flags); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add PIN"); strlcpy(pinlabel, "PUK ", sizeof(pinlabel)); @@ -633,7 +633,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, | SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED; r = itacns_add_pin(p15card, pinlabel, fake_puk_authid, 0, pin_ref+1, private_path, pin_flags); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add PUK"); return 0; @@ -686,7 +686,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, if (cert_offset) { u8 certlen[3]; r = loadFile(p15card, &path, certlen, sizeof(certlen)); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not read certificate file"); path.index = cert_offset; path.count = (certlen[1] << 8) + certlen[2]; @@ -700,7 +700,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, &path, &cert_id, label, 0, &ext_info_ok, &ku, &xku); if (r == SC_ERROR_INVALID_ASN1_OBJECT) return 0; - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add certificate"); (*found_certificates)++; @@ -743,7 +743,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, r = itacns_add_keyset(p15card, label, sec_env, &cert_id, pubkey_path, prkey_path, pubkey_usage_flags, prkey_usage_flags, pin_ref); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add keys for this certificate"); return r; @@ -817,7 +817,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) /* Data files */ r = itacns_add_data_files(p15card); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add data files"); /*** Certificate and keys. ***/ @@ -825,7 +825,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS0", cns0_secenv, 0, "3F0011001101", "3F003F01", NULL, 0x10, &found_certs); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add CNS0"); certificate_count += found_certs; @@ -833,7 +833,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS01", 0x21, 5, "3F002FFF8228", NULL, "3F002FFF0000", 0x10, &found_certs); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add CNS01"); certificate_count += found_certs; @@ -841,7 +841,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS1", 0x10, 0, "3F0014009010", "3F00140081108010", "3F0014008110", 0x1a, &found_certs); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not add CNS1"); certificate_count += found_certs; @@ -853,7 +853,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) /* Back to Master File */ sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, NULL); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(p15card->card->ctx, r, "Could not select master file again"); return r; diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 5237e00658..07387c5a01 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -143,7 +143,7 @@ sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj r = sc_asn1_decode(ctx, asn1_auth_type, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); + LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); if (asn1_auth_type_choice[0].flags & SC_ASN1_PRESENT) { sc_log(ctx, "AuthType: PIN"); @@ -183,7 +183,7 @@ sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoded PIN(ref:%X,path:%s)", info.attrs.pin.reference, sc_print_path(&info.path)); } else if (asn1_auth_type_choice[1].flags & SC_ASN1_PRESENT) { - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "BIO authentication object not yet supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "BIO authentication object not yet supported"); } else if (asn1_auth_type_choice[2].flags & SC_ASN1_PRESENT) { sc_log(ctx, "AuthType: AuthKey"); @@ -194,7 +194,7 @@ sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj info.attrs.authkey.derived = 1; } else { - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "unknown authentication type"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unknown authentication type"); } obj->data = malloc(sizeof(info)); diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index b71e069f99..1bcf34529a 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -690,7 +690,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* XXX Assuming RSA key here */ r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, prkey->modulus_length); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); + LOG_TEST_RET(ctx, r, "Unable to add padding"); inlen = tmplen; } else if ( senv.algorithm == SC_ALGORITHM_RSA && diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index b70ea54fd6..2d69e184a5 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -80,7 +80,7 @@ static int asepcos_check_verify_tpin(sc_profile_t *profile, sc_pkcs15_card_t *p1 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_CRYPTO); p15card->card->caps |= SC_CARD_CAP_USE_FCI_AC; sc_file_free(tfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "unable to authenticate for 'CRYPTO' operation"); + LOG_TEST_RET(ctx, r, "unable to authenticate for 'CRYPTO' operation"); } return SC_SUCCESS; } @@ -780,7 +780,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card apdu.resp = rbuf; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { sc_log(card->ctx, "error creating key"); return SC_ERROR_INTERNAL; diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index d61c21e0f3..a13b73f61b 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -859,7 +859,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card) apdu.lc = 0; apdu.le = 256; r = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if ((len = apdu.resplen) == 0) /* looks like no package has been installed */ diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 7d347426bc..1cb55c1507 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -246,11 +246,11 @@ cflex_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df /* Get file definition from the profile */ if (sc_profile_get_file(profile, (pin_attrs->reference == 1)? "CHV1" : "CHV2", &file) < 0 && sc_profile_get_file(profile, "CHV", &file) < 0) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs"); + LOG_TEST_RET(ctx, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs"); ndummies = cflex_create_dummy_chvs(profile, p15card, file, SC_AC_OP_CREATE, dummies); sc_file_free(file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file"); + LOG_TEST_RET(ctx, ndummies, "Unable to create dummy CHV file"); r = cflex_create_pin_file(profile, p15card, &df->path, pin_attrs->reference, pin, pin_len, sc_profile_get_pin_retries(profile, pin_type), @@ -548,7 +548,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (sc_profile_get_file_by_path(profile, &path, &file) < 0 && sc_profile_get_file(profile, (ref == 1)? "CHV1" : "CHV2", &file) < 0 && sc_profile_get_file(profile, "CHV", &file) < 0) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs"); + LOG_TEST_RET(ctx, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs"); file->path = path; file->size = 23; @@ -568,7 +568,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, * necessary */ ndummies = cflex_create_dummy_chvs(profile, p15card, file, SC_AC_OP_UPDATE, dummies); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file"); + LOG_TEST_RET(ctx, ndummies, "Unable to create dummy CHV file"); if (!unprotected) { struct sc_pin_cmd_data pin_cmd; @@ -581,7 +581,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, pin_cmd.pin1.len = sizeof(dummy_pin_value); r = sc_pin_cmd(p15card->card, &pin_cmd, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot verify dummy PIN"); + LOG_TEST_RET(ctx, r, "Cannot verify dummy PIN"); }; @@ -593,10 +593,10 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } r = sc_pkcs15init_create_file(profile, p15card, file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to create PIN file"); + LOG_TEST_RET(ctx, r, "Failed to create PIN file"); r = sc_update_binary(p15card->card, 0, buffer, 23, 0); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to update PIN file"); + LOG_TEST_RET(ctx, r, "Failed to update PIN file"); if (r < 0 || file_ret == NULL) sc_file_free(file); diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index a115a01d95..f7b74df062 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -82,7 +82,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ret = sc_profile_get_file(profile, "MF", &mf_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get MF info failed"); + LOG_TEST_RET(card->ctx,ret,"Get MF info failed"); mf_data.type = SC_ENTERSAFE_MF_DATA; mf_data.data.df.file_id[0]=0x3F; @@ -98,7 +98,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) sc_file_free(mf_file); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &mf_data); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create MF failed"); + LOG_TEST_RET(card->ctx,ret,"Create MF failed"); } {/* EF(DIR) */ @@ -109,7 +109,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) /* get dir profile */ ret = sc_profile_get_file(profile, "dir", &dir_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get EF(DIR) info failed"); + LOG_TEST_RET(card->ctx,ret,"Get EF(DIR) info failed"); fid=dir_file->id; size=dir_file->size; sc_file_free(dir_file); @@ -126,7 +126,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) memset(ef_data.data.ef.sm,0x00,sizeof(ef_data.data.ef.sm)); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &ef_data); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create EF(DIR) failed"); + LOG_TEST_RET(card->ctx,ret,"Create EF(DIR) failed"); /* fill file by 0 */ @@ -137,7 +137,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) ret = sc_update_binary(card,0,buff,size,0); free(buff); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Initialize EF(DIR) failed"); + LOG_TEST_RET(card->ctx,ret,"Initialize EF(DIR) failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); @@ -168,7 +168,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card memcpy(df_data.data.df.aid,df->name,df->namelen); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &df_data); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Crate DF failed"); + LOG_TEST_RET(card->ctx,ret,"Crate DF failed"); } {/* GPKF */ @@ -177,7 +177,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card /* get p15_gpkf profile */ ret = sc_profile_get_file(profile, "p15_gpkf", &gpkf_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get GPKF info failed"); + LOG_TEST_RET(card->ctx,ret,"Get GPKF info failed"); ef_data.type=SC_ENTERSAFE_EF_DATA; ef_data.data.ef.file_id[0]=(gpkf_file->id>>8)&0xFF; @@ -193,7 +193,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card sc_file_free(gpkf_file); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &ef_data); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create GPKF failed"); + LOG_TEST_RET(card->ctx,ret,"Create GPKF failed"); } {/* p15 efs */ @@ -234,13 +234,13 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card sc_file_free(file); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &tmp); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create pkcs15 file failed"); + LOG_TEST_RET(card->ctx,ret,"Create pkcs15 file failed"); } } {/* Preinstall keys */ ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_PREINSTALL_KEYS, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Preinstall keys failed"); + LOG_TEST_RET(card->ctx,ret,"Preinstall keys failed"); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,ret); @@ -382,7 +382,7 @@ static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } sc_file_free(tfile); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin"); + LOG_TEST_RET(card->ctx, r, "cant verify pin"); data.key_id = (u8) kinfo->key_reference; data.usage=0x22; @@ -432,14 +432,14 @@ static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15ca r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } sc_file_free(tfile); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin"); + LOG_TEST_RET(card->ctx, r, "cant verify pin"); /* generate key pair */ gendat.key_id = (u8) kinfo->key_reference; gendat.key_length = (size_t) kinfo->modulus_length; gendat.modulus = NULL; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "EnterSafe generate RSA key pair failed"); + LOG_TEST_RET(card->ctx, r, "EnterSafe generate RSA key pair failed"); /* get the modulus via READ PUBLIC KEY */ if (pubkey) { @@ -478,11 +478,11 @@ static int entersafe_sanity_check(sc_profile_t *profile, sc_pkcs15_card_t *p15ca sc_log(ctx, "Check and if needed update PinFlags"); rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PINs"); + LOG_TEST_RET(ctx, rv, "Failed to get PINs"); nn = rv; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_auth); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PIN info"); + LOG_TEST_RET(ctx, rv, "Failed to get PIN info"); for (ii=0; iidata; @@ -506,9 +506,9 @@ static int entersafe_sanity_check(sc_profile_t *profile, sc_pkcs15_card_t *p15ca while (df != NULL && df->type != SC_PKCS15_AODF) df = df->next; if (!df) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OBJECT_NOT_FOUND, "Cannot find AODF"); + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Cannot find AODF"); rv = sc_pkcs15init_update_any_df(p15card, profile, df, 0); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Update AODF error"); + LOG_TEST_RET(ctx, rv, "Update AODF error"); } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv); diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 1bbee4bd1a..ec011eca8e 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -57,19 +57,19 @@ static int epass2003_pkcs15_init_card(struct sc_profile *profile, struct sc_file *skey_file; ret = sc_profile_get_file(profile, "MF", &mf_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get MF info failed"); ret = sc_create_file(card, mf_file); sc_file_free(mf_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create MF failed"); ret = sc_profile_get_file(profile, "SKey-MF", &skey_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get SKey info failed"); ret = sc_create_file(card, skey_file); sc_file_free(skey_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create SKey failed"); } @@ -79,11 +79,11 @@ static int epass2003_pkcs15_init_card(struct sc_profile *profile, /* get dir profile */ ret = sc_profile_get_file(profile, "DIR", &dir_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get EF(DIR) info failed"); ret = sc_create_file(card, dir_file); sc_file_free(dir_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create EF(DIR) failed"); sc_free_apps(card); @@ -110,38 +110,38 @@ static int epass2003_pkcs15_create_dir(struct sc_profile *profile, u8 so_maxtries = 0; ret = sc_profile_get_file(profile, "PKCS15-AppDF", &df_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get PKCS15-AppDF info failed"); ret = sc_create_file(card, df_file); sc_file_free(df_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create PKCS15-AppDF failed"); ret = sc_profile_get_file(profile, "SKey-AppDF", &skey_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get SKey info failed"); ret = sc_create_file(card, skey_file); sc_file_free(skey_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create SKey info failed"); ret = sc_profile_get_file(profile, "MAXPIN", &ef_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get MAXPIN info failed"); ret = sc_create_file(card, ef_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create MAXPIN failed"); ret = sc_select_file(card, &(ef_file->path), &ef_file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Select MAXPIN failed"); ret = sc_profile_get_pin_id(profile, 2, &id); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get User PIN id error!"); user_maxtries = (u8) sc_profile_get_pin_retries(profile, id); ret = sc_profile_get_pin_id(profile, 1, &id); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Get User PIN id error!"); so_maxtries = (u8) sc_profile_get_pin_retries(profile, id); @@ -150,7 +150,7 @@ static int epass2003_pkcs15_create_dir(struct sc_profile *profile, ret = sc_update_binary(card, 0, max_counter, 2, 0); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Update MAXPIN failed"); sc_file_free(ef_file); } @@ -180,7 +180,7 @@ static int epass2003_pkcs15_create_dir(struct sc_profile *profile, } ret = sc_create_file(card, file); sc_file_free(file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, ret, + LOG_TEST_RET(card->ctx, ret, "Create pkcs15 file failed"); } } @@ -240,7 +240,7 @@ static int epass2003_pkcs15_create_pin(struct sc_profile *profile, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER; r = sc_profile_get_pin_id(profile, 2, &id); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "Get User PIN id error!"); data.key_data.es_secret.EC = sc_profile_get_pin_retries(profile, id); @@ -276,7 +276,7 @@ static int epass2003_pkcs15_create_pin(struct sc_profile *profile, EPASS2003_AC_MAC_EQUAL | EPASS2003_AC_SO; r = sc_profile_get_pin_id(profile, 1, &id); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "Get User PIN id error!"); data.key_data.es_secret.EC = sc_profile_get_pin_retries(profile, id); @@ -429,7 +429,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, sc_pkcs15_print_id(&key_info->id)); if (key->algorithm != SC_ALGORITHM_RSA || key->algorithm != SC_ALGORITHM_RSA) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "store key: only support RSA"); @@ -441,7 +441,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, /* allocate key object */ r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "create key: failed to allocate new key object"); file->size = keybits; sc_log(card->ctx, "private key path: %s", @@ -451,7 +451,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, sc_delete_file(p15card->card, &file->path); /* create */ r = sc_pkcs15init_create_file(profile, p15card, file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "create key: failed to create key file"); sc_log(card->ctx, @@ -468,11 +468,11 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, path.len -= 2; r = sc_select_file(card, &path, &tfile); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "generate key: no private object DF"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "No authorisation to store private key"); sc_file_free(tfile); @@ -484,7 +484,7 @@ static int epass2003_pkcs15_store_key(struct sc_profile *profile, data.key_data.es_key.rsa = (void *)&key->u.rsa; r = sc_card_ctl(p15card->card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, + LOG_TEST_RET(card->ctx, r, "store key: cannot update private key"); sc_file_free(file); @@ -693,11 +693,11 @@ static int epass2003_pkcs15_sanity_check(sc_profile_t * profile, sc_log(ctx, "Check and if needed update PinFlags"); rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PINs"); + LOG_TEST_RET(ctx, rv, "Failed to get PINs"); nn = rv; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_auth); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to get PIN info"); + LOG_TEST_RET(ctx, rv, "Failed to get PIN info"); for (ii = 0; ii < nn; ii++) { struct sc_pkcs15_auth_info *ainfo = @@ -725,11 +725,11 @@ static int epass2003_pkcs15_sanity_check(sc_profile_t * profile, while (df != NULL && df->type != SC_PKCS15_AODF) df = df->next; if (!df) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Cannot find AODF"); rv = sc_pkcs15init_update_any_df(p15card, profile, df, 0); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Update AODF error"); + LOG_TEST_RET(ctx, rv, "Update AODF error"); } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv); diff --git a/src/pkcs15init/pkcs15-gids.c b/src/pkcs15init/pkcs15-gids.c index db013c375c..df1bc93b06 100644 --- a/src/pkcs15init/pkcs15-gids.c +++ b/src/pkcs15init/pkcs15-gids.c @@ -123,7 +123,7 @@ static int gids_save_certificate(struct sc_pkcs15_card *p15card, struct sc_pkcs1 //TODO save the certificate in the special file LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to find the private key associated to the certificate"); + LOG_TEST_RET(card->ctx, r, "unable to find the private key associated to the certificate"); LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_SAVE_CERT, &call)); } diff --git a/src/pkcs15init/pkcs15-miocos.c b/src/pkcs15init/pkcs15-miocos.c index d1ae67b01d..092f640232 100644 --- a/src/pkcs15init/pkcs15-miocos.c +++ b/src/pkcs15init/pkcs15-miocos.c @@ -185,7 +185,7 @@ miocos_create_pin(struct sc_profile *profile, sc_pkcs15_card_t *p15card, struct puk_len = 8; strncpy((char *) ac_info.unblock_value, (const char *) puk, puk_len); r = sc_card_ctl(p15card->card, SC_CARDCTL_MIOCOS_CREATE_AC, &ac_info); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Miocos create AC failed"); + LOG_TEST_RET(ctx, r, "Miocos create AC failed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -205,14 +205,14 @@ miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); if (key_info->modulus_length != 1024) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create key: failed to allocate new key object"); + LOG_TEST_RET(ctx, r, "Cannot create key: failed to allocate new key object"); memcpy(&file->path, &key_info->path, sizeof(file->path)); file->id = file->path.value[file->path.len - 2] * 0x100 @@ -244,20 +244,20 @@ miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); rsa = &key->u.rsa; if (rsa->modulus.len != 128) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); sc_log(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed"); + LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key"); + LOG_TEST_RET(ctx, r, "No authorisation to store private key"); r = miocos_update_private_key(profile, p15card->card, rsa); diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 3b14e4c42b..8bb53def15 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -245,10 +245,10 @@ awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, int LOG_FUNC_CALLED(ctx); if (len<0x34) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCORRECT_PARAMETERS, "Invalid container update size"); + LOG_TEST_RET(ctx, SC_ERROR_INCORRECT_PARAMETERS, "Invalid container update size"); rv = sc_get_challenge(p15card->card, rand_buf, sizeof(rand_buf)); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot get challenge"); + LOG_TEST_RET(ctx, rv, "Cannot get challenge"); *(buff + 12) = 0x26; *(buff + 13) = '{'; @@ -321,11 +321,11 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_log(ctx, "create container(%X:%X:%X)", acc->prkey_id, acc->cert_id, acc->pubkey_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Create container failed"); + LOG_TEST_RET(ctx, rv, "Create container failed"); sc_log(ctx, "contaner cfile(rcount:%i,rlength:%i)", clist->record_count, clist->record_length); rv = sc_select_file(p15card->card, &clist->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Create container failed: cannot select container's list"); + LOG_TEST_RET(ctx, rv, "Create container failed: cannot select container's list"); file->record_length = clist->record_length; sc_log(ctx, "contaner file(rcount:%i,rlength:%i)", file->record_count, file->record_length); @@ -388,7 +388,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p case COSM_TYPE_PRKEY_RSA: if (*(buff + offs + 2)) { free(buff); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD, "private key exists already"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_CARD, "private key exists already"); } *(buff + offs + 2) = (file_id >> 8) & 0xFF; @@ -817,7 +817,7 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj */ ki->id.value = calloc(1, key_info->id.len); if (!ki->id.value) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: ID allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: ID allocation error"); memcpy(ki->id.value, key_info->id.value, key_info->id.len); ki->id.len = key_info->id.len; @@ -851,7 +851,7 @@ awp_set_key_info (struct sc_pkcs15_card *p15card, struct sc_profile *profile, st blob_size = 2; blob = malloc(blob_size); if (!blob) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP set key info failed: blob allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP set key info failed: blob allocation error"); sc_log(ctx, "label:%s",ki->label.value); @@ -933,7 +933,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ERR_load_crypto_strings(); if (!obj || !ci) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "AWP encode cert failed: invalid parameters"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "AWP encode cert failed: invalid parameters"); cert_info = (struct sc_pkcs15_cert_info *)obj->data; @@ -948,22 +948,22 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob mem = BIO_new_mem_buf(obj->content.value, obj->content.len); if (!mem) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA, "AWP encode cert failed: invalid data"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: invalid data"); x = d2i_X509_bio(mem, NULL); if (!x) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_DATA, "AWP encode cert failed: x509 parse error"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: x509 parse error"); buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE); if (!buff) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: memory allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: memory allocation error"); /* * subject commonName. */ ptr = awp_get_commonName(x); if (!ptr) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get CommonName"); + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get CommonName"); ci->cn.value = ptr; ci->cn.len = strlen((char *)ptr); @@ -973,11 +973,11 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ptr = buff; r = i2d_X509_NAME(X509_get_subject_name(x),&ptr); if (r<=0) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get SubjectName"); + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get SubjectName"); ci->subject.value = malloc(r); if (!ci->subject.value) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: subject allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: subject allocation error"); memcpy(ci->subject.value, buff, r); ci->subject.len = r; @@ -987,11 +987,11 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ptr = buff; r = i2d_X509_NAME(X509_get_issuer_name(x),&ptr); if (r <= 0) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get IssuerName"); + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "AWP encode cert failed: cannot get IssuerName"); ci->issuer.value = malloc(r); if (!ci->issuer.value) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: issuer allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: issuer allocation error"); memcpy(ci->issuer.value, buff, r); ci->issuer.len = r; @@ -1000,7 +1000,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob */ ci->id.value = calloc(1, cert_info->id.len); if (!ci->id.value) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: ID allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode cert failed: ID allocation error"); memcpy(ci->id.value, cert_info->id.value, cert_info->id.len); ci->id.len = cert_info->id.len; @@ -1104,7 +1104,7 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob LOG_FUNC_CALLED(ctx); if (!obj || !di) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "AWP encode data failed: invalid parameters"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "AWP encode data failed: invalid parameters"); data_info = (struct sc_pkcs15_data_info *)obj->data; @@ -1126,13 +1126,13 @@ awp_encode_data_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob } r = sc_asn1_encode_object_id(&buf, &buflen, &data_info->app_oid); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "AWP encode data failed: cannot encode OID"); + LOG_TEST_RET(ctx, r, "AWP encode data failed: cannot encode OID"); di->oid.len = buflen + 2; di->oid.value = malloc(di->oid.len); if (!di->oid.value) { free(buf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP encode data failed: cannot allocate OID"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP encode data failed: cannot allocate OID"); } *(di->oid.value + 0) = 0x06; @@ -1260,14 +1260,14 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, /* Label */ len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->label); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: label"); + LOG_TEST_RET(ctx, len, "AWP parse key info failed: label"); if (!len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; /* Ignore Key ID */ len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: ID"); + LOG_TEST_RET(ctx, len, "AWP parse key info failed: ID"); if (!len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; @@ -1277,7 +1277,7 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, /* Subject */ len = awp_get_lv(ctx, buf, buf_len, offs, 2, &ikey->subject); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: subject"); + LOG_TEST_RET(ctx, len, "AWP parse key info failed: subject"); if (!len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; @@ -1289,14 +1289,14 @@ awp_parse_key_info(struct sc_context *ctx, unsigned char *buf, size_t buf_len, len = awp_get_lv(ctx, buf, buf_len, offs, 128, &ikey->modulus); else len = awp_get_lv(ctx, buf, buf_len, offs, 256, &ikey->modulus); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: modulus"); + LOG_TEST_RET(ctx, len, "AWP parse key info failed: modulus"); if (!len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); offs += len; /* Exponent */ len = awp_get_lv(ctx, buf, buf_len, offs, 1, &ikey->exponent); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, len, "AWP parse key info failed: exponent"); + LOG_TEST_RET(ctx, len, "AWP parse key info failed: exponent"); if (!len) LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -1318,7 +1318,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, LOG_FUNC_CALLED(ctx); rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_PRKEY_RSA, prvkey_id & 0xFF, &info_file, &key_file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update key info failed: instantiation error"); + LOG_TEST_RET(ctx, rv, "AWP update key info failed: instantiation error"); sc_log(ctx, "key id %X; info id%X", key_file->id, info_file->id); rv = sc_pkcs15init_authenticate(profile, p15card, info_file, SC_AC_OP_READ); @@ -1335,7 +1335,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, buf = calloc(1,file->size); if (!buf) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP update key info failed: allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update key info failed: allocation error"); rv = sc_read_binary(p15card->card, 0, buf, file->size, 0); if (rv < 0) { @@ -1353,7 +1353,7 @@ awp_update_key_info(struct sc_pkcs15_card *p15card, struct sc_profile *profile, free(buf); rv = awp_set_key_info(p15card, profile, info_file, &ikey, ci); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update key info failed: set key info error"); + LOG_TEST_RET(ctx, rv, "AWP update key info failed: set key info error"); done: sc_file_free(file); sc_file_free(key_file); @@ -1382,7 +1382,7 @@ awp_update_df_create_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; rv = awp_new_file(p15card, profile, SC_PKCS15_TYPE_CERT_X509, obj_id & 0xFF, &info_file, &obj_file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "COSM new file error"); + LOG_TEST_RET(ctx, rv, "COSM new file error"); memset(&icert, 0, sizeof(icert)); sc_log(ctx, @@ -1572,19 +1572,19 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; rv = awp_new_file(p15card, profile, obj_type, obj_id & 0xFF, &info_file, &obj_file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "COSM new file error"); + LOG_TEST_RET(ctx, rv, "COSM new file error"); memset(&idata, 0, sizeof(idata)); sc_log(ctx, "Data Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_data_info(p15card, obj, &idata); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Data' update DF failed: cannot encode info"); + LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot encode info"); rv = awp_set_data_info(p15card, profile, info_file, &idata); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Data' update DF failed: cannot set info"); + LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot set info"); rv = awp_update_object_list(p15card, profile, obj_type, obj_id & 0xFF); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'Create Data' update DF failed: cannot update list"); + LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot update list"); awp_free_data_info(&idata); @@ -1623,7 +1623,7 @@ awp_update_df_create(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = awp_update_df_create_data(p15card, profile, object); break; default: - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type"); } LOG_FUNC_RETURN(ctx, rv); @@ -1644,14 +1644,14 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, sc_log(ctx, "update container entry (type:%X,file-id:%X)", type, file_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update contaner entry: cannot get allocate AWP file"); + LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot get allocate AWP file"); rv = sc_select_file(p15card->card, &clist->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update contaner entry: cannot select container list file"); + LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot select container list file"); buff = malloc(file->record_length); if (!buff) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP update container entry: allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update container entry: allocation error"); for (rec = 1; rec <= (unsigned)file->record_count; rec++) { rv = sc_read_record(p15card->card, rec, buff, file->record_length, SC_RECORD_BY_REC_NR); @@ -1738,22 +1738,22 @@ awp_remove_from_object_list( struct sc_pkcs15_card *p15card, struct sc_profile * snprintf(lst_name, NAME_MAX_LEN,"%s-public-list", COSM_TITLE); break; default: - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCORRECT_PARAMETERS, "AWP update object list: invalid type"); + LOG_TEST_RET(ctx, SC_ERROR_INCORRECT_PARAMETERS, "AWP update object list: invalid type"); } sc_log(ctx, "AWP update object list: select '%s' file", lst_name); rv = sc_profile_get_file(profile, lst_name, &lst_file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update object list: cannot instantiate list file"); + LOG_TEST_RET(ctx, rv, "AWP update object list: cannot instantiate list file"); rv = sc_select_file(p15card->card, &lst_file->path, &lst); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update object list: cannot select list file"); + LOG_TEST_RET(ctx, rv, "AWP update object list: cannot select list file"); rv = sc_pkcs15init_authenticate(profile, p15card, lst, SC_AC_OP_READ); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP update object list: 'read' authentication failed"); + LOG_TEST_RET(ctx, rv, "AWP update object list: 'read' authentication failed"); buff = malloc(lst->size); if (!buff) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "AWP update object list: allocation error"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update object list: allocation error"); rv = sc_read_binary(p15card->card, 0, buff, lst->size, 0); if (rv != (int)lst->size) @@ -1803,18 +1803,18 @@ awp_update_df_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot get allocate new AWP file"); + LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot get allocate new AWP file"); sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: delete info file error"); + LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: delete info file error"); rv = awp_delete_from_container(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot update container"); + LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot update container"); rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete cert' update DF failed: cannot remove object"); + LOG_TEST_RET(ctx, rv, "AWP 'delete cert' update DF failed: cannot remove object"); LOG_FUNC_RETURN(ctx, rv); } @@ -1837,18 +1837,18 @@ awp_update_df_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot get allocate new AWP file"); + LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot get allocate new AWP file"); sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: delete info file error"); + LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: delete info file error"); rv = awp_delete_from_container(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot update container"); + LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot update container"); rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete prkey' update DF failed: cannot remove object"); + LOG_TEST_RET(ctx, rv, "AWP 'delete prkey' update DF failed: cannot remove object"); LOG_FUNC_RETURN(ctx, rv); } @@ -1871,18 +1871,18 @@ awp_update_df_delete_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *p sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot get allocate new AWP file"); + LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot get allocate new AWP file"); sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: delete info file error"); + LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: delete info file error"); rv = awp_delete_from_container(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot update container"); + LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot update container"); rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete pubkey' update DF failed: cannot remove object"); + LOG_TEST_RET(ctx, rv, "AWP 'delete pubkey' update DF failed: cannot remove object"); LOG_FUNC_RETURN(ctx, rv); } @@ -1905,15 +1905,15 @@ awp_update_df_delete_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro sc_log(ctx, "file-id:%X", file_id); rv = awp_new_file(p15card, profile, obj->type, file_id & 0xFF, &info_file, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannot get allocate new AWP file"); + LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: cannot get allocate new AWP file"); sc_log(ctx, "info file-id:%X", info_file->id); rv = cosm_delete_file(p15card, profile, info_file); if (rv != SC_ERROR_FILE_NOT_FOUND) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: delete info file error"); + LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: delete info file error"); rv = awp_remove_from_object_list(p15card, profile, obj->type, file_id); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'delete DATA' update DF failed: cannot remove object"); + LOG_TEST_RET(ctx, rv, "AWP 'delete DATA' update DF failed: cannot remove object"); LOG_FUNC_RETURN(ctx, rv); } @@ -1944,7 +1944,7 @@ awp_update_df_delete(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = awp_update_df_delete_data(p15card, profile, object); break; default: - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'Create' update DF failed: unsupported object type"); } SC_FUNC_RETURN(ctx, 1, rv); diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 10b50d0cca..322a74a4a5 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -130,7 +130,7 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_log(ctx, "id %04X", df->id); if (df->type==SC_FILE_TYPE_DF) { rv = sc_pkcs15init_authenticate(profile, p15card, df, SC_AC_OP_DELETE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot authenticate SC_AC_OP_DELETE"); + LOG_TEST_RET(ctx, rv, "Cannot authenticate SC_AC_OP_DELETE"); } /* Select the parent DF */ @@ -138,11 +138,11 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, path.len -= 2; rv = sc_select_file(p15card->card, &path, &parent); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot select parent"); + LOG_TEST_RET(ctx, rv, "Cannot select parent"); rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot authenticate SC_AC_OP_DELETE"); + LOG_TEST_RET(ctx, rv, "Cannot authenticate SC_AC_OP_DELETE"); memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; @@ -245,13 +245,13 @@ cosm_create_dir(struct sc_profile *profile, struct sc_pkcs15_card *p15card, for (ii = 0; create_dfs[ii]; ii++) { if (sc_profile_get_file(profile, create_dfs[ii], &file)) { sc_log(ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "Profile do not contains Oberthur AWP file"); + LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Profile do not contains Oberthur AWP file"); } rv = sc_pkcs15init_create_file(profile, p15card, file); sc_file_free(file); if (rv != SC_ERROR_FILE_ALREADY_EXISTS) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to create Oberthur AWP file"); + LOG_TEST_RET(ctx, rv, "Failed to create Oberthur AWP file"); } rv = cosm_write_tokeninfo(p15card, profile, NULL, @@ -289,7 +289,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 return SC_ERROR_OBJECT_NOT_VALID; rv = sc_select_file(card, &ainfo->path, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot select file"); + LOG_TEST_RET(ctx, rv, "Cannot select file"); sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_auth_pin); sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &profile_auth_puk); @@ -313,17 +313,17 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 } rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_CREATE_PIN, &args); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "'CREATE_PIN' card specific command failed"); + LOG_TEST_RET(ctx, rv, "'CREATE_PIN' card specific command failed"); if (!(ainfo->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) && (profile_auth_puk.tries_left > 0)) { struct sc_file *file = NULL; if (sc_profile_get_file(profile, COSM_TITLE"-puk-file", &file)) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find PUKFILE"); + LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find PUKFILE"); rv = sc_pkcs15init_update_file(profile, p15card, file, oberthur_puk, sizeof(oberthur_puk)); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to update pukfile"); + LOG_TEST_RET(ctx, rv, "Failed to update pukfile"); sc_file_free(file); } @@ -351,20 +351,20 @@ cosm_update_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (ainfo->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) { if (ainfo->attrs.pin.reference != 4) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_PIN_REFERENCE, "cosm_update_pin() invalid SOPIN reference"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_REFERENCE, "cosm_update_pin() invalid SOPIN reference"); sc_log(ctx, "Update SOPIN ignored"); rv = SC_SUCCESS; } else { rv = cosm_create_reference_data(profile, p15card, ainfo, pin, pin_len, puk, puk_len); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "cosm_update_pin() failed to change PIN"); + LOG_TEST_RET(ctx, rv, "cosm_update_pin() failed to change PIN"); rv = cosm_write_tokeninfo(p15card, profile, NULL, COSM_TOKEN_FLAG_TOKEN_INITIALIZED | COSM_TOKEN_FLAG_PRN_GENERATION | COSM_TOKEN_FLAG_LOGIN_REQUIRED | COSM_TOKEN_FLAG_USER_PIN_INITIALIZED); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "cosm_update_pin() failed to update tokeninfo"); + LOG_TEST_RET(ctx, rv, "cosm_update_pin() failed to update tokeninfo"); } LOG_FUNC_RETURN(ctx, rv); @@ -435,7 +435,7 @@ cosm_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_log(ctx, "create '%.*s'; ref 0x%X; flags %X", (int) sizeof pin_obj->label, pin_obj->label, pin_attrs->reference, pin_attrs->flags); if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pin_file) < 0) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "\""COSM_TITLE"-AppDF\" not defined"); + LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "\""COSM_TITLE"-AppDF\" not defined"); if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_LOCAL) auth_info->path = pin_file->path; @@ -444,27 +444,27 @@ cosm_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) { - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "SOPIN unblocking is not supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "SOPIN unblocking is not supported"); } else { if (pin_attrs->reference != 4) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid SOPIN reference"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid SOPIN reference"); } } else { if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) { if (pin_attrs->reference != 0x84) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid User PUK reference"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid User PUK reference"); } else { if (pin_attrs->reference != 0x81) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid User PIN reference"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid User PIN reference"); } } if (pin && pin_len) { rv = cosm_update_pin(profile, p15card, auth_info, pin, pin_len, puk, puk_len); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Update PIN failed"); + LOG_TEST_RET(ctx, rv, "Update PIN failed"); } LOG_FUNC_RETURN(ctx, rv); @@ -583,7 +583,7 @@ cosm_get_temporary_public_key_file(struct sc_card *card, rv = sc_file_add_acl_entry(file, SC_AC_OP_EXTERNAL_AUTHENTICATE, SC_AC_NONE, 0); if (rv < 0) sc_file_free(file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to add ACL entry to the temporary public key file"); + LOG_TEST_RET(ctx, rv, "Failed to add ACL entry to the temporary public key file"); *pubkey_file = file; @@ -606,31 +606,31 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported"); path = key_info->path; path.len -= 2; rv = sc_select_file(p15card->card, &path, &tmpf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot generate key: failed to select private object DF"); + LOG_TEST_RET(ctx, rv, "Cannot generate key: failed to select private object DF"); rv = sc_pkcs15init_authenticate(profile, p15card, tmpf, SC_AC_OP_CRYPTO); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot generate key: 'CRYPTO' authentication failed"); + LOG_TEST_RET(ctx, rv, "Cannot generate key: 'CRYPTO' authentication failed"); rv = sc_pkcs15init_authenticate(profile, p15card, tmpf, SC_AC_OP_CREATE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot generate key: 'CREATE' authentication failed"); + LOG_TEST_RET(ctx, rv, "Cannot generate key: 'CREATE' authentication failed"); sc_file_free(tmpf); rv = sc_select_file(p15card->card, &key_info->path, &prkf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Failed to generate key: cannot select private key file"); + LOG_TEST_RET(ctx, rv, "Failed to generate key: cannot select private key file"); /* In the private key DF create the temporary public RSA file. */ rv = cosm_get_temporary_public_key_file(p15card->card, prkf, &tmpf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Error while getting temporary public key file"); + LOG_TEST_RET(ctx, rv, "Error while getting temporary public key file"); rv = sc_pkcs15init_create_file(profile, p15card, tmpf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "cosm_generate_key() failed to create temporary public key EF"); + LOG_TEST_RET(ctx, rv, "cosm_generate_key() failed to create temporary public key EF"); memset(&args, 0, sizeof(args)); args.id_prv = prkf->id; @@ -640,23 +640,23 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, args.pubkey_len = key_info->modulus_length / 8; args.pubkey = malloc(key_info->modulus_length / 8); if (!args.pubkey) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey"); rv = sc_card_ctl(p15card->card, SC_CARDCTL_OBERTHUR_GENERATE_KEY, &args); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "cosm_generate_key() CARDCTL_OBERTHUR_GENERATE_KEY failed"); + LOG_TEST_RET(ctx, rv, "cosm_generate_key() CARDCTL_OBERTHUR_GENERATE_KEY failed"); /* extract public key */ pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = key_info->modulus_length / 8; pubkey->u.rsa.modulus.data = malloc(key_info->modulus_length / 8); if (!pubkey->u.rsa.modulus.data) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf"); /* FIXME and if the exponent length is not 3? */ pubkey->u.rsa.exponent.len = 3; pubkey->u.rsa.exponent.data = malloc(3); if (!pubkey->u.rsa.exponent.data) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate exponent buf"); + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate exponent buf"); memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len); @@ -687,13 +687,13 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); /* Here, the path of private key file should be defined. * Nevertheless, we need to instantiate private key to get the ACLs. */ rv = cosm_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot create key: failed to allocate new key object"); + LOG_TEST_RET(ctx, rv, "Cannot create key: failed to allocate new key object"); file->size = key_info->modulus_length; memcpy(&file->path, &key_info->path, sizeof(file->path)); @@ -739,16 +739,16 @@ cosm_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || prkey->algorithm != SC_ALGORITHM_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); sc_log(ctx, "store key with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); rv = sc_select_file(p15card->card, &key_info->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot store key: select key file failed"); + LOG_TEST_RET(ctx, rv, "Cannot store key: select key file failed"); rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "No authorisation to store private key"); + LOG_TEST_RET(ctx, rv, "No authorisation to store private key"); if (key_info->id.len > sizeof(update_info.id)) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -761,7 +761,7 @@ cosm_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, memcpy(update_info.id, key_info->id.value, update_info.id_len); rv = sc_card_ctl(p15card->card, SC_CARDCTL_OBERTHUR_UPDATE_KEY, &update_info); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot update private key"); + LOG_TEST_RET(ctx, rv, "Cannot update private key"); sc_file_free(file); @@ -814,7 +814,7 @@ cosm_emu_update_tokeninfo(struct sc_profile *profile, struct sc_pkcs15_card *p15 SC_FUNC_CALLED(ctx, 1); if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE, "cannot find "COSM_TITLE"-token-info"); + LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "cannot find "COSM_TITLE"-token-info"); buf = calloc(1, file->size); if (!buf) { diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index de97f7935e..35f629747d 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -95,18 +95,18 @@ static int rtecp_init(sc_profile_t *profile, sc_pkcs15_card_t *p15card) card = p15card->card; r = sc_profile_get_file(profile, "MF", &file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get MF info failed"); + LOG_TEST_RET(card->ctx, r, "Get MF info failed"); assert(file); r = sc_create_file(card, file); sc_file_free(file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Create MF failed"); + LOG_TEST_RET(card->ctx, r, "Create MF failed"); r = sc_profile_get_file(profile, "DIR", &file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get DIR file info failed"); + LOG_TEST_RET(card->ctx, r, "Get DIR file info failed"); assert(file); r = sc_create_file(card, file); sc_file_free(file); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Create DIR file failed"); + LOG_TEST_RET(card->ctx, r, "Create DIR file failed"); create_sysdf(profile, card, "Sys-DF"); create_sysdf(profile, card, "SysKey-DF"); @@ -212,7 +212,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_pkcs15init_fixup_file(profile, p15card, file); if (r < 0) sc_file_free(file); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot fixup the ACLs of PIN file"); + LOG_TEST_RET(p15card->card->ctx, r, "Cannot fixup the ACLs of PIN file"); acl = sc_file_get_acl_entry(file, SC_AC_OP_PIN_RESET); if (acl && acl->method == SC_AC_CHV && acl->key_ref == RTECP_SO_PIN_REF) { @@ -269,7 +269,7 @@ static int rtecp_select_key_reference(sc_profile_t *profile, return SC_ERROR_TOO_MANY_OBJECTS; r = sc_profile_get_file(profile, "PrKey-DF", &df); - SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get PrKey-DF info failed"); + LOG_TEST_RET(p15card->card->ctx, r, "Get PrKey-DF info failed"); assert(df); key_info->path = df->path; sc_file_free(df); @@ -341,12 +341,12 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } r = sc_profile_get_file(profile, "PKCS15-AppDF", &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get PKCS15-AppDF info failed"); + LOG_TEST_RET(ctx, r, "Get PKCS15-AppDF info failed"); r = sc_file_add_acl_entry(file, SC_AC_OP_CREATE, SC_AC_CHV, auth_id); if (r == SC_SUCCESS) r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE); sc_file_free(file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Authenticate failed"); + LOG_TEST_RET(ctx, r, "Authenticate failed"); file = sc_file_new(); if (!file) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 8770ed94a6..9381f6f2b0 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -105,17 +105,17 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) /* Fix up the file's ACLs */ r = sc_pkcs15init_fixup_file(profile, p15card, mf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF fixup failed"); + LOG_TEST_RET(ctx, r, "MF fixup failed"); mf->status = SC_FILE_STATUS_CREATION; r = sc_create_file(p15card->card, mf); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF creation failed"); + LOG_TEST_RET(ctx, r, "MF creation failed"); } - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF"); + LOG_TEST_RET(ctx, r, "Cannot select MF"); /* Create the global pin file if it doesn't exist yet */ r = sc_profile_get_file(profile, "pinfile", &pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get 'pinfile' from profile"); + LOG_TEST_RET(ctx, r, "Cannot get 'pinfile' from profile"); r = sc_select_file(p15card->card, &pinfile->path, NULL); if (r == SC_ERROR_FILE_NOT_FOUND) { @@ -125,7 +125,7 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) r = sc_pkcs15init_fixup_file(profile, p15card, pinfile); if (r < 0) sc_file_free(pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile fixup failed"); + LOG_TEST_RET(ctx, r, "Pinfile fixup failed"); /* Set life cycle state to SC_FILE_STATUS_CREATION, * which means that all ACs are ignored. */ @@ -133,10 +133,10 @@ setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) r = sc_create_file(p15card->card, pinfile); if (r < 0) sc_file_free(pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile creation failed"); + LOG_TEST_RET(ctx, r, "Pinfile creation failed"); } sc_file_free(pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Select pinfile failed"); + LOG_TEST_RET(ctx, r, "Select pinfile failed"); LOG_FUNC_RETURN(ctx, r); } @@ -153,10 +153,10 @@ setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); r = sc_pkcs15init_fixup_file(profile, p15card, df); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS file ACL fixup failed"); + LOG_TEST_RET(ctx, r, "SetCOS file ACL fixup failed"); r = sc_create_file(p15card->card, df); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS create file failed"); + LOG_TEST_RET(ctx, r, "SetCOS create file failed"); LOG_FUNC_RETURN(ctx, r); } @@ -209,10 +209,10 @@ setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Create the global pin file if it doesn't exist yet */ r = sc_profile_get_file(profile, "pinfile", &pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No 'pinfile' template in profile"); + LOG_TEST_RET(ctx, r, "No 'pinfile' template in profile"); r = sc_select_file(p15card->card, &pinfile->path, &pinfile); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'"); + LOG_TEST_RET(ctx, r, "Cannot select 'pinfile'"); sc_log(ctx, "pinfile->status:%X", pinfile->status); sc_log(ctx, "create PIN with reference:%X, flags:%X, path:%s", @@ -231,13 +231,13 @@ setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *mf = profile->mf_info->file; r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set 'pinfile' into the activated state"); + LOG_TEST_RET(ctx, r, "Cannot set 'pinfile' into the activated state"); r = sc_select_file(p15card->card, &mf->path, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF"); + LOG_TEST_RET(ctx, r, "Cannot select MF"); r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set MF into the activated state"); + LOG_TEST_RET(ctx, r, "Cannot set MF into the activated state"); } sc_file_free(pinfile); @@ -328,17 +328,17 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); /* Parameter check */ if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); /* Get the private key file */ r = setcos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get new private key file"); + LOG_TEST_RET(ctx, r, "Cannot get new private key file"); /* Take enough room for a 1024 bit key */ if (file->size < 512) @@ -356,15 +356,15 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_select_file(p15card->card, &file->path, NULL); if (!r) { r = sc_pkcs15init_delete_by_path(profile, p15card, &file->path); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to delete private key file"); + LOG_TEST_RET(ctx, r, "Failed to delete private key file"); } else if (r != SC_ERROR_FILE_NOT_FOUND) { - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Select private key file error"); + LOG_TEST_RET(ctx, r, "Select private key file error"); } /* Now create the key file */ r = sc_pkcs15init_create_file(profile, p15card, file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create private key file"); + LOG_TEST_RET(ctx, r, "Cannot create private key file"); sc_file_free(file); LOG_FUNC_RETURN(ctx, r); @@ -387,20 +387,20 @@ setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); /* Parameter check */ if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); sc_log(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed"); + LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key"); + LOG_TEST_RET(ctx, r, "No authorisation to store private key"); /* Fill in data structure */ memset(&args, 0, sizeof(args)); @@ -415,7 +415,7 @@ setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Generate/store rsa key */ r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'GENERATE_STORE_KEY' failed"); + LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed"); sc_file_free(file); @@ -439,18 +439,18 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported"); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported"); /* Parameter check */ if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); r = sc_select_file(p15card->card, &key_info->path, &file); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed"); + LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed"); /* Authenticate */ r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key"); + LOG_TEST_RET(ctx, r, "No authorisation to store private key"); /* Fill in data structure */ memset(&args, 0, sizeof(args)); @@ -461,7 +461,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Generate/store rsa key */ r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'GENERATE_STORE_KEY' failed"); + LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed"); /* Keypair generation -> collect public key info */ if (pubkey != NULL) { @@ -474,7 +474,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Get public key modulus */ r = sc_select_file(p15card->card, &file->path, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get key modulus: select key file failed"); + LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed"); data_obj.P1 = 0x01; data_obj.P2 = 0x01; @@ -482,14 +482,14 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, data_obj.DataLen = sizeof(raw_pubkey); r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed"); + LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed"); keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (keybits != key_info->modulus_length) { sc_log(ctx, "key-size from card[%"SC_FORMAT_LEN_SIZE_T"u] does not match[%"SC_FORMAT_LEN_SIZE_T"u]\n", keybits, key_info->modulus_length); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PKCS15INIT, "Failed to generate key"); + LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key"); } memcpy (pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len); } diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index b9dcfc7ace..b9c14569f5 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -644,15 +644,15 @@ static int iso_add_sm(struct iso_sm_ctx *sctx, sc_card_t *card, if ((apdu->cla & 0x0C) == 0x0C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging. Closing own SM context."); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_sm_stop(card), + LOG_TEST_RET(card->ctx, sc_sm_stop(card), "Could not close ISO SM session"); return SC_ERROR_SM_NOT_APPLIED; } if (sctx->pre_transmit) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->pre_transmit(card, sctx, apdu), + LOG_TEST_RET(card->ctx, sctx->pre_transmit(card, sctx, apdu), "Could not complete SM specific pre transmit routine"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sm_encrypt(sctx, card, apdu, sm_apdu), + LOG_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, sm_apdu), "Could not encrypt APDU"); return SC_SUCCESS; @@ -662,16 +662,16 @@ static int iso_rm_sm(struct iso_sm_ctx *sctx, sc_card_t *card, sc_apdu_t *sm_apdu, sc_apdu_t *apdu) { if (!sctx) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid SM context. No SM processing performed."); if (sctx->post_transmit) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->post_transmit(card, sctx, sm_apdu), + LOG_TEST_RET(card->ctx, sctx->post_transmit(card, sctx, sm_apdu), "Could not complete SM specific post transmit routine"); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sm_decrypt(sctx, card, sm_apdu, apdu), + LOG_TEST_RET(card->ctx, sm_decrypt(sctx, card, sm_apdu, apdu), "Could not decrypt APDU"); if (sctx->finish) - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->finish(card, sctx, apdu), + LOG_TEST_RET(card->ctx, sctx->finish(card, sctx, apdu), "Could not complete SM specific post transmit routine"); return SC_SUCCESS; From 5474370b17b7dd596b6fdb32d1efdaac013f8258 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Nov 2018 22:41:18 +0100 Subject: [PATCH 0661/4321] always log APDUs with SC_LOG_DEBUG_NORMAL --- src/libopensc/card-entersafe.c | 2 +- src/libopensc/internal.h | 5 ++--- src/libopensc/reader-cryptotokenkit.m | 4 ++-- src/libopensc/reader-ctapi.c | 4 ++-- src/libopensc/reader-openct.c | 4 ++-- src/libopensc/reader-pcsc.c | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index d85828d7ac..aa74c619c2 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -365,7 +365,7 @@ static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, r = sc_apdu_get_octets(card->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r == SC_SUCCESS) - sc_apdu_log(card->ctx, SC_LOG_DEBUG_VERBOSE, sbuf, ssize, 1); + sc_apdu_log(card->ctx, sbuf, ssize, 1); if(sbuf) free(sbuf); diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index dd079aacba..622e8fde50 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -247,13 +247,12 @@ int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf, /** * Logs APDU * @param ctx sc_context_t object - * @param level log if ctx->debug >= level * @param buf buffer with the APDU data * @param len length of the APDU * @param is_outgoing != 0 if the data is send to the card */ -#define sc_apdu_log(ctx, level, data, len, is_outgoing) \ - sc_debug_hex(ctx, level, is_outgoing != 0 ? "Outgoing APDU" : "Incoming APDU", data, len) +#define sc_apdu_log(ctx, data, len, is_outgoing) \ + sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, is_outgoing != 0 ? "Outgoing APDU" : "Incoming APDU", data, len) extern struct sc_reader_driver *sc_get_pcsc_driver(void); extern struct sc_reader_driver *sc_get_ctapi_driver(void); diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index 449b9f86d2..7bee8278b4 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -265,7 +265,7 @@ static int cryptotokenkit_transmit(sc_reader_t *reader, sc_apdu_t *apdu) if (reader->name) sc_log(reader->ctx, "reader '%s'", reader->name); - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, sbuf, ssize, 1); + sc_apdu_log(reader->ctx, sbuf, ssize, 1); [priv->tksmartcard transmitRequest: [NSData dataWithBytes: sbuf length: ssize] @@ -288,7 +288,7 @@ static int cryptotokenkit_transmit(sc_reader_t *reader, sc_apdu_t *apdu) if (r != SC_SUCCESS) goto err; - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); + sc_apdu_log(reader->ctx, rbuf, rsize, 0); r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); err: diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index db08465b2c..5ca8c04d4d 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -199,7 +199,7 @@ static int ctapi_transmit(sc_reader_t *reader, sc_apdu_t *apdu) r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r != SC_SUCCESS) goto out; - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, sbuf, ssize, 1); + sc_apdu_log(reader->ctx, sbuf, ssize, 1); r = ctapi_internal_transmit(reader, sbuf, ssize, rbuf, &rsize, apdu->control); if (r < 0) { @@ -207,7 +207,7 @@ static int ctapi_transmit(sc_reader_t *reader, sc_apdu_t *apdu) sc_log(reader->ctx, "unable to transmit"); goto out; } - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); + sc_apdu_log(reader->ctx, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); out: diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index 2697d270f7..c28e45f54c 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -323,7 +323,7 @@ static int openct_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r != SC_SUCCESS) goto out; - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, sbuf, ssize, 1); + sc_apdu_log(reader->ctx, sbuf, ssize, 1); r = openct_reader_internal_transmit(reader, sbuf, ssize, rbuf, &rsize, apdu->control); if (r < 0) { @@ -331,7 +331,7 @@ static int openct_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) sc_log(reader->ctx, "unable to transmit"); goto out; } - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); + sc_apdu_log(reader->ctx, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); out: diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 817586fd82..c1c2107e90 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -282,7 +282,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_apdu_t *apdu) goto out; if (reader->name) sc_log(reader->ctx, "reader '%s'", reader->name); - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, sbuf, ssize, 1); + sc_apdu_log(reader->ctx, sbuf, ssize, 1); r = pcsc_internal_transmit(reader, sbuf, ssize, rbuf, &rsize, apdu->control); @@ -291,7 +291,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_apdu_t *apdu) sc_log(reader->ctx, "unable to transmit"); goto out; } - sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); + sc_apdu_log(reader->ctx, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); From f2145eca79f1bc54a5c3ac9056748e58954a4899 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 30 Nov 2018 18:09:39 +0100 Subject: [PATCH 0662/4321] don't debug pointers --- src/libopensc/card.c | 4 ---- src/libopensc/pkcs15-algo.c | 4 ---- src/libopensc/pkcs15-pubkey.c | 13 ++----------- src/pkcs11/framework-pkcs15.c | 11 ----------- src/pkcs11/pkcs11-object.c | 1 - 5 files changed, 2 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index ecfcb7906a..5e03c9d8b9 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1460,7 +1460,6 @@ sc_card_sm_check(struct sc_card *card) int rv, ii; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "card->sm_ctx.ops.open %p", card->sm_ctx.ops.open); /* get the name of card specific SM configuration section */ atrblock = _sc_match_atr_block(ctx, card->driver, &card->atr); @@ -1501,10 +1500,8 @@ sc_card_sm_check(struct sc_card *card) strlcpy(card->sm_ctx.config_section, sm, sizeof(card->sm_ctx.config_section)); /* allocate resources for the external SM module */ - sc_log(ctx, "'module_init' handler %p", card->sm_ctx.module.ops.module_init); if (card->sm_ctx.module.ops.module_init) { module_data = scconf_get_str(sm_conf_block, "module_data", NULL); - sc_log(ctx, "module_data '%s'", module_data); rv = card->sm_ctx.module.ops.module_init(ctx, module_data); LOG_TEST_RET(ctx, rv, "Cannot initialize SM module"); @@ -1512,7 +1509,6 @@ sc_card_sm_check(struct sc_card *card) /* initialize SM session in the case of 'APDU TRANSMIT' SM mode */ sm_mode = scconf_get_str(sm_conf_block, "mode", NULL); - sc_log(ctx, "SM mode '%s'; 'open' handler %p", sm_mode, card->sm_ctx.ops.open); if (sm_mode && !strcasecmp("Transmit", sm_mode)) { if (!card->sm_ctx.ops.open || !card->sm_ctx.ops.get_sm_apdu || !card->sm_ctx.ops.free_sm_apdu) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "'Transmit' SM asked but not supported by card driver"); diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index c383f2d50e..378532851f 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -267,10 +267,6 @@ asn1_decode_ec_params(sc_context_t *ctx, void **paramp, struct sc_asn1_entry asn1_ec_params[4]; struct sc_ec_parameters *ecp; - sc_debug(ctx, SC_LOG_DEBUG_ASN1, - "DEE - asn1_decode_ec_params %p:%"SC_FORMAT_LEN_SIZE_T"u %d", - buf, buflen, depth); - memset(&curve, 0, sizeof(curve)); /* We only want to copy the parms if they are a namedCurve diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e3f6848601..e9b7f27e7b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -726,9 +726,6 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, if (*ecpoint_data != 0x04) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); - sc_log(ctx, "decode-EC key=%p, buf=%p, buflen=%"SC_FORMAT_LEN_SIZE_T"u", - key, buf, buflen); - key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; @@ -747,19 +744,13 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; - int r; LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key->ecpointQ.len, 1); - r = sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen); - LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); - - sc_log(ctx, - "EC key->ecpointQ=%p:%"SC_FORMAT_LEN_SIZE_T"u *buf=%p:%"SC_FORMAT_LEN_SIZE_T"u", - key->ecpointQ.value, key->ecpointQ.len, *buf, *buflen); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, + sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen)); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cc74414199..cabb068f82 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -712,7 +712,6 @@ __pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_pubkey *p15_key = NULL; int rv; - sc_log(context, "__pkcs15_create_pubkey_object() called, pubkey %p, data %p", pubkey, pubkey->data); /* Read public key from card */ /* Attempt to read pubkey from card or file. * During initialization process, the key may have been created @@ -754,7 +753,6 @@ __pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data, if (pubkey_object != NULL) *pubkey_object = (struct pkcs15_any_object *) object; - sc_log(context, "__pkcs15_create_pubkey_object() returns pubkey object %p", object); return rv; } @@ -1136,7 +1134,6 @@ pkcs15_create_slot(struct sc_pkcs11_card *p11card, struct pkcs15_fw_data *fw_dat struct sc_pkcs11_slot *slot = NULL; CK_RV rv; - sc_log(context, "Create slot (p11card %p, fw_data %p, auth %p, app_info %p)", p11card, fw_data, auth, app_info); rv = slot_allocate(&slot, p11card); if (rv != CKR_OK) return rv; @@ -1514,7 +1511,6 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf _add_pin_related_objects(sign_slot, auth_sign_pin, fw_data, NULL); } - sc_log(context, "slot %p, sign-slot %p\n", slot, sign_slot); if (!slot && sign_slot) slot = sign_slot; } @@ -4147,9 +4143,6 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_DeriveKey"); - sc_log(context, "derivation %p %p %p %p %lu %p %lu", session, obj, - pMechanism, pParameters, ulParametersLen, pData, *pulDataLen); - /* See which of the alternative keys supports derivation */ while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_DERIVE)) prkey = prkey->prv_next; @@ -4638,10 +4631,6 @@ data_value_to_attr(CK_ATTRIBUTE_PTR attr, struct sc_pkcs15_data *data) if (!attr || !data) return CKR_ATTRIBUTE_VALUE_INVALID; - sc_log(context, - "data_value_to_attr(): data(%p,len:%"SC_FORMAT_LEN_SIZE_T"u)", - data, data->data_len); - check_attribute_buffer(attr, data->data_len); memcpy(attr->pValue, data->data, data->data_len); return CKR_OK; diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index d2fb423905..ad336bf82f 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -58,7 +58,6 @@ sc_find_release(sc_pkcs11_operation_t *operation) { struct sc_pkcs11_find_operation *fop = (struct sc_pkcs11_find_operation *)operation; - sc_log(context,"freeing %d handles used %d at %p", fop->allocated_handles, fop->num_handles, fop->handles); if (fop->handles) { free(fop->handles); fop->handles = NULL; From 8fb611bb1cc519ecfa54d22007dbf4276a5b18e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 29 Nov 2018 15:27:02 +0100 Subject: [PATCH 0663/4321] Move the test into separate directory Signed-off-by: Jakub Jelen --- Makefile.am | 2 +- configure.ac | 1 + doc/tools/Makefile.am | 3 --- tests/Makefile.am | 5 +++++ {doc/tools => tests}/test-manpage.sh | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 tests/Makefile.am rename {doc/tools => tests}/test-manpage.sh (97%) diff --git a/Makefile.am b/Makefile.am index a09d5a152c..5ab3d25430 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ EXTRA_DIST = Makefile.mak DISTCHECK_CONFIGURE_FLAGS = --with-completiondir=/tmp -SUBDIRS = etc src win32 doc MacOSX +SUBDIRS = etc src win32 doc MacOSX tests dist_noinst_SCRIPTS = bootstrap bootstrap.ci dist_noinst_DATA = README \ diff --git a/configure.ac b/configure.ac index bc9136ce3e..a88bb0aaa4 100644 --- a/configure.ac +++ b/configure.ac @@ -1059,6 +1059,7 @@ AC_CONFIG_FILES([ doc/tools/Makefile doc/files/Makefile etc/Makefile + tests/Makefile src/Makefile src/common/Makefile src/ui/Makefile diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index e52d4ffd8c..9ecb1bb457 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -2,9 +2,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = completion-template -TESTS = test-manpage.sh -dist_noinst_SCRIPTS = test-manpage.sh - dist_noinst_DATA = $(wildcard $(srcdir)/*.xml) if ENABLE_DOC html_DATA = tools.html diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000000..3d51b9895a --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,5 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +dist_noinst_SCRIPTS = test-manpage.sh + +TESTS = test-manpage.sh diff --git a/doc/tools/test-manpage.sh b/tests/test-manpage.sh similarity index 97% rename from doc/tools/test-manpage.sh rename to tests/test-manpage.sh index be12d0f28d..89fab7d11c 100755 --- a/doc/tools/test-manpage.sh +++ b/tests/test-manpage.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=../../ +SOURCE_PATH=../ # find all the manual pages in src/tools TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|"` From a7a9326f35a2c46ba06fe480bf0d53b6f29edf91 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 29 Nov 2018 17:20:37 +0100 Subject: [PATCH 0664/4321] Add simple Sanity test for pkcs11-tool sign&verify operations --- tests/Makefile.am | 6 +- tests/test-pkcs11-tool-sign-verify.sh | 175 ++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 2 deletions(-) create mode 100755 tests/test-pkcs11-tool-sign-verify.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index 3d51b9895a..e88620a0cc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -dist_noinst_SCRIPTS = test-manpage.sh +dist_noinst_SCRIPTS = test-manpage.sh \ + test-pkcs11-tool-sign-verify.sh -TESTS = test-manpage.sh +TESTS = test-manpage.sh \ + test-pkcs11-tool-sign-verify.sh diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh new file mode 100755 index 0000000000..a0b5bc5253 --- /dev/null +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -0,0 +1,175 @@ +## from OpenSC/src/tests/p11test/runtest.sh +SOPIN="12345678" +PIN="123456" +PKCS11_TOOL="../src/tools/pkcs11-tool" +P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" + +ERRORS=0 +function assert() { + if [[ $1 != 0 ]]; then + echo "====> ERROR: $2" + ERRORS=1 + fi +} + +function generate_key() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # Generate key pair + $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ + --module="$P11LIB" --label="$LABEL" --id=$ID + + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate $TYPE key pair" + return 1 + fi + + # Extract public key from the card + $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ + --module="$P11LIB" + + # convert it to more digestible PEM format + if [[ ${TYPE:0:3} == "RSA" ]]; then + openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + else + openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + fi + rm $ID.der +} + +function card_setup() { + echo "directories.tokendir = .tokens/" > .softhsm2.conf + mkdir ".tokens" + export SOFTHSM2_CONF=".softhsm2.conf" + # Init token + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" + + # Generate 1024b RSA Key pair + generate_key "RSA:1024" "01" "RSA_auth" + # Generate 2048b RSA Key pair + generate_key "RSA:2048" "02" "RSA2048" + # Generate 256b ECC Key pair + # generate_key "EC:secp256r1" "03" "ECC_auth" + # Generate 521b ECC Key pair + # generate_key "EC:secp521r1" "04" "ECC521" + # TODO ECDSA keys tests +} + +function card_cleanup() { + rm .softhsm2.conf + rm -rf ".tokens" + rm 0{1,2}.pub +} + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +card_setup +echo "data to sign (max 100 bytes)" > data + +for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do + for SIGN_KEY in "01" "02"; do + METHOD="RSA-PKCS" + if [[ ! -z $HASH ]]; then + METHOD="$HASH-$METHOD" + fi + echo + echo "=======================================================" + echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" + echo "=======================================================" + $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + --input-file data --output-file data.sig + assert $? "Failed to Sign data" + + # OpenSSL verification + if [[ -z $HASH ]]; then + openssl rsautl -verify -inkey $SIGN_KEY.pub -in data.sig -pubin + else + openssl dgst -keyform PEM -verify $SIGN_KEY.pub -${HASH,,*} \ + -signature data.sig data + fi + assert $? "Failed to Verify signature using OpenSSL" + + # pkcs11-tool verification + $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ + --input-file data --signature-file data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.sig + + METHOD="$METHOD-PSS" + if [[ "$HASH" == "SHA512" ]]; then + continue; # This one is broken + fi + + echo + echo "=======================================================" + echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" + echo "=======================================================" + if [[ -z $HASH ]]; then + # hashing is done outside of the module. We chouse here SHA256 + openssl dgst -binary -sha256 data > data.hash + HASH_ALGORITM="--hash-algorithm=SHA256" + VERIFY_DGEST="-sha256" + VERIFY_OPTS="-sigopt rsa_mgf1_md:sha256" + else + # hashing is done inside of the module + cp data data.hash + HASH_ALGORITM="" + VERIFY_DGEST="-${HASH,,*}" + VERIFY_OPTS="-sigopt rsa_mgf1_md:${HASH,,*}" + fi + $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + $HASH_ALGORITM --salt-len=-1 \ + --input-file data.hash --output-file data.sig + assert $? "Failed to Sign data" + + # OpenSSL verification + openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ + -sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ + -signature data.sig data + assert $? "Failed to Verify signature using openssl" + + # pkcs11-tool verification + $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ + $HASH_ALGORITM --salt-len=-1 \ + --input-file data.hash --signature-file data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.{sig,hash} + done + + # Skip hashed algorithms (do not support encryption & decryption) + if [[ ! -z "$HASH" ]]; then + continue; + fi + METHOD="RSA-PKCS" + for ENC_KEY in "01" "02"; do + echo + echo "=======================================================" + echo "$METHOD: Encrypt & Decrypt (KEY $ENC_KEY)" + echo "=======================================================" + # OpenSSL Encryption + openssl rsautl -encrypt -inkey $ENC_KEY.pub -in data \ + -pubin -out data.crypt + assert $? "Failed to encrypt data using OpenSSL" + $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN -m $METHOD \ + --module $P11LIB --input-file data.crypt > data.decrypted + diff data{,.decrypted} + assert $? "The decrypted data do not match the original" + rm data.{crypt,decrypted} + + # TODO pkcs11-tool encryption not supported + done +done + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +card_cleanup + +exit $ERRORS From 01287e393ebeed1db7ef2f45ee133b2cd3f069ae Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 8 Dec 2018 17:38:59 +0100 Subject: [PATCH 0665/4321] framework-pkcs15: fix warning * fix -Werror=format-truncation= warning in pkcs15_init_slot() * do not only remove blanks from the end, but all spaces --- src/pkcs11/framework-pkcs15.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cabb068f82..6b9f0a5348 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -21,6 +21,7 @@ #include "config.h" #include #include +#include #include "libopensc/log.h" #include "libopensc/internal.h" #include "libopensc/asn1.h" @@ -1047,7 +1048,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, { struct pkcs15_slot_data *fw_data; struct sc_pkcs15_auth_info *pin_info = NULL; - char label[(sizeof auth->label) + 10]; + char label[sizeof(auth->label) + sizeof(p15card->tokeninfo->label) + 10]; int write_protected; scconf_block *atrblock; @@ -1091,10 +1092,11 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, else { if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) { /* Trim tokeninfo->label to make right parenthesis visible */ - char tokeninfo_label[sizeof label]; + char tokeninfo_label[sizeof(p15card->tokeninfo->label)+1]; int len; snprintf(tokeninfo_label, sizeof(tokeninfo_label), "%s", p15card->tokeninfo->label); - for (len = strlen(tokeninfo_label) - 1; len >= 0 && tokeninfo_label[len] == ' '; len--) { + tokeninfo_label[sizeof(tokeninfo_label)-1] = '\0'; + for (len = strlen(tokeninfo_label) - 1; len >= 0 && isspace(tokeninfo_label[len]); len--) { tokeninfo_label[len] = 0; } snprintf(label, sizeof(label), "%.*s (%s)", From 738c933609e0e6ed54dd1b71ff6092a8288718e9 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 13 Oct 2018 21:36:48 +0200 Subject: [PATCH 0666/4321] OpenPGP: a few cleanups for Gnuk * make sure to remain within buffer size in pgp_read_blob() * make logic more readable in pgp_get_data() --- src/libopensc/card-openpgp.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f09e8a06a2..9945e59625 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1107,7 +1107,7 @@ pgp_read_blob(sc_card_t *card, pgp_blob_t *blob) blob->id == DO_AUTH_SYM || blob->id == DO_SIGN_SYM || blob->id == DO_ENCR_SYM)) { - buf_len = MAXLEN_RESP_PUBKEY_GNUK; + buf_len = MIN(MAXLEN_RESP_PUBKEY_GNUK, sizeof(buffer)); } r = blob->info->get_fn(card, blob->id, buffer, buf_len); @@ -1606,12 +1606,18 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) r = sc_check_sw(card, apdu.sw1, apdu.sw2); - /* For Gnuk card, if there is no certificate, it returns error instead of empty data. + /* Gnuk returns an error instead of empty data if there is no certificate or private DO. * So, for this case, we ignore error and consider success */ - if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND && card->type == SC_CARD_TYPE_OPENPGP_GNUK - && (tag == DO_CERT || tag == DO_PRIV1 || tag == DO_PRIV2 || tag == DO_PRIV3 || tag == DO_PRIV4)) { - r = SC_SUCCESS; - apdu.resplen = 0; + if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && + (tag == DO_CERT || + tag == DO_PRIV1 || + tag == DO_PRIV2 || + tag == DO_PRIV3 || + tag == DO_PRIV4)) { + if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) { + r = SC_SUCCESS; + apdu.resplen = 0; + } } LOG_TEST_RET(card->ctx, r, "Card returned error"); From d3e730b621921e737f3088aa75816d6a68b2cbe0 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 28 Oct 2018 11:35:32 +0100 Subject: [PATCH 0667/4321] OpenPGP: refactor error handling in pgp_put_data_plain() * use LOG_TEST_*() macros instead of explicit coding --- src/libopensc/card-openpgp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 9945e59625..4f74aeb7fb 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1729,9 +1729,7 @@ pgp_put_data_plain(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_ LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* check response */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); - - if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + LOG_TEST_RET(card->ctx, r, "Card returned error"); LOG_FUNC_RETURN(card->ctx, (int)buf_len); } From 08b9f362c08ba7c7983faf08296a87c2dd9d11bc Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 28 Oct 2018 11:43:53 +0100 Subject: [PATCH 0668/4321] OpenPGP: refactor error handling in pgp_gen_key() * use LOG_TEST_*() macros instead of explicit coding --- src/libopensc/card-openpgp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 4f74aeb7fb..8ba51f75ad 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2606,24 +2606,22 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) sc_log(card->ctx, "Waiting for the card to generate key..."); r = sc_transmit_apdu(card, &apdu); sc_log(card->ctx, "Card has done key generation."); - if (r < 0) { - sc_log(card->ctx, "APDU transmit failed. Error %s.", sc_strerror(r)); - goto finish; - } + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); /* check response */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); /* instruct more in case of error */ if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Please verify PIN first."); - goto finish; + goto err; } + LOG_TEST_GOTO_ERR(card->ctx, r, "Card returned error"); /* parse response data and set output */ pgp_parse_and_set_pubkey_output(card, apdu.resp, apdu.resplen, key_info); pgp_update_card_algorithms(card, key_info); -finish: +err: free(apdu.resp); LOG_FUNC_RETURN(card->ctx, r); } From 7916d45857b2c00c39dc7844ac52718423c37e0b Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 28 Oct 2018 11:57:32 +0100 Subject: [PATCH 0669/4321] OpenPGP: refactor error handling in pgp_store_key() * use LOG_TEST_*() macros instead of explicit coding * harmonize use of card->ctx: saves one variable * explictly compare pointers to != NULL --- src/libopensc/card-openpgp.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 8ba51f75ad..60cbf620e6 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2870,22 +2870,21 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info static int pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) { - sc_context_t *ctx = card->ctx; sc_cardctl_openpgp_keygen_info_t pubkey; u8 *data = NULL; size_t len = 0; int r; - LOG_FUNC_CALLED(ctx); + LOG_FUNC_CALLED(card->ctx); /* temporary workaround: protect v3 cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* Validate */ if (key_info->key_id < 1 || key_info->key_id > 3) { - sc_log(ctx, "Unknown key type %d.", key_info->key_id); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + sc_log(card->ctx, "Unknown key type %d.", key_info->key_id); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } /* we just support standard key format */ switch (key_info->rsa.keyformat) { @@ -2920,27 +2919,20 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) } r = pgp_update_new_algo_attr(card, &pubkey); LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); + /* build Extended Header list */ r = pgp_build_extended_header_list(card, key_info, &data, &len); - if (r < 0) { - sc_log(ctx, "Failed to build Extended Header list."); - goto out; - } + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to build Extended Header list"); + /* write to DO */ r = pgp_put_data(card, 0x4D, data, len); - if (r < 0) { - sc_log(ctx, "Failed to write to DO."); - goto out; - } - - free(data); - data = NULL; + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to write to DO 004D"); /* store creation time */ r = pgp_store_creationtime(card, key_info->key_id, &key_info->creationtime); LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); - /* Calculate and store fingerprint */ + /* calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, key_info->rsa.n, key_info->rsa.e, &pubkey); @@ -2950,15 +2942,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) r = pgp_update_pubkey_blob(card, key_info->rsa.n, 8*key_info->rsa.n_len, key_info->rsa.e, 8*key_info->rsa.e_len, key_info->key_id); - sc_log(ctx, "Update card algorithms."); + sc_log(card->ctx, "Update card algorithms."); pgp_update_card_algorithms(card, &pubkey); -out: - if (data) { +err: + if (data != NULL) free(data); - data = NULL; - } - LOG_FUNC_RETURN(ctx, r); + LOG_FUNC_RETURN(card->ctx, r); } #endif /* ENABLE_OPENSSL */ From bf2a9bc53b6bcaee9fa85d50414aee9399a6e0bb Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 28 Oct 2018 12:04:19 +0100 Subject: [PATCH 0670/4321] OpenPGP: refactor error handling in pgp_build_extended_header_list() * use LOG_TEST_*() macros instead of explicit coding --- src/libopensc/card-openpgp.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 60cbf620e6..fb9afbc35b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2812,20 +2812,15 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_TEST_RET(ctx, r, "Failed to build TLV for 7F48."); tlv_7f48[0] |= 0x7F; r = pgp_build_tlv(ctx, 0x5f48, kdata, kdata_len, &tlv_5f48, &tlvlen_5f48); - if (r < 0) { - sc_log(ctx, "Failed to build TLV for 5F48."); - goto out; - } + LOG_TEST_GOTO_ERR(ctx, r, "Failed to build TLV for 5F48"); /* data part's length for Extended Header list */ len = 2 + tlvlen_7f48 + tlvlen_5f48; /* set data part content */ data = calloc(len, 1); - if (data == NULL) { - sc_log(ctx, "Not enough memory."); - r = SC_ERROR_NOT_ENOUGH_MEMORY; - goto out; - } + if (data == NULL) + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory."); + switch (key_info->key_id) { case SC_OPENPGP_KEY_SIGN: data[0] = 0xB6; @@ -2839,15 +2834,13 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info default: sc_log(ctx, "Unknown key type %d.", key_info->key_id); r = SC_ERROR_INVALID_ARGUMENTS; - goto out; + goto err; } memcpy(data + 2, tlv_7f48, tlvlen_7f48); memcpy(data + 2 + tlvlen_7f48, tlv_5f48, tlvlen_5f48); r = pgp_build_tlv(ctx, 0x4D, data, len, &tlvblock, &tlvlen); - if (r < 0) { - sc_log(ctx, "Cannot build TLV for Extended Header list."); - goto out; - } + LOG_TEST_GOTO_ERR(ctx, r, "Cannot build TLV for Extended Header list"); + /* set output */ if (result != NULL) { *result = tlvblock; @@ -2856,7 +2849,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info free(tlvblock); } -out: +err: free(data); free(tlv_5f48); free(tlv_7f48); From c7fc7cc134361e2a63759bd9a599ee1a6638c536 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sun, 28 Oct 2018 12:08:33 +0100 Subject: [PATCH 0671/4321] OpenPGP: refactor error handling in pgp_calculate_and_store_fingerprint() * initialize pointers to NULL * explicitly compare pointers to NULL * use LOG_TEST_*() macros instead of explicit coding --- src/libopensc/card-openpgp.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fb9afbc35b..56f6cf28b3 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2281,8 +2281,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, u8 *p; /* use this pointer to set fp_buffer content */ size_t pk_packet_len; unsigned int tag = 0x00C6 + key_info->key_id; - pgp_blob_t *fpseq_blob; - u8 *newdata; + pgp_blob_t *fpseq_blob = NULL; + u8 *newdata = NULL; int r; LOG_FUNC_CALLED(card->ctx); @@ -2307,9 +2307,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, fp_buffer_len = 3 + pk_packet_len; p = fp_buffer = calloc(fp_buffer_len, 1); - if (!p) { + if (p == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - } p[0] = 0x99; /* http://tools.ietf.org/html/rfc4880 page 71 */ ushort2bebytes(++p, (unsigned short)pk_packet_len); @@ -2341,16 +2340,15 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* update the blob containing fingerprints (00C5) */ sc_log(card->ctx, "Updating fingerprint blob 00C5."); fpseq_blob = pgp_find_blob(card, 0x00C5); - if (!fpseq_blob) { - sc_log(card->ctx, "Cannot find blob 00C5."); - goto exit; - } + if (fpseq_blob == NULL) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot find blob 00C5"); + /* save the fingerprints sequence */ newdata = malloc(fpseq_blob->len); - if (!newdata) { - sc_log(card->ctx, "Not enough memory to update fingerprint blob 00C5."); - goto exit; - } + if (newdata == NULL) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY, + "Not enough memory to update fingerprint blob 00C5"); + memcpy(newdata, fpseq_blob->data, fpseq_blob->len); /* move p to the portion holding the fingerprint of the current key */ p = newdata + 20 * (key_info->key_id - 1); @@ -2360,7 +2358,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, pgp_set_blob(fpseq_blob, newdata, fpseq_blob->len); free(newdata); -exit: +err: LOG_FUNC_RETURN(card->ctx, r); } From b1539545d0ad3116c3efe1482855eb1eaf56e451 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 11 Dec 2018 21:36:40 +0100 Subject: [PATCH 0672/4321] OpenPGP: free() unconditionally in error handling of pgp_store_key() --- src/libopensc/card-openpgp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 56f6cf28b3..3470f70783 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2937,8 +2937,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) pgp_update_card_algorithms(card, &pubkey); err: - if (data != NULL) - free(data); + free(data); LOG_FUNC_RETURN(card->ctx, r); } From 35cb70b5d664c4be417dee2cbe6b652185e6da2d Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 17 Dec 2018 18:44:23 -0800 Subject: [PATCH 0673/4321] Remove redundant logging Same information is printed a few line below in same function, the only difference is that there it takes care of case when label is NULL pointer unlike this line secondly, every function call to cosm_write_tokeninfo() in this file passes label=NULL, and then it tries to print a null pointer Fixes errors like src/libopensc/log.h:48:47: error: '%s' directive argument is null [-Werror=format-overflow=] Signed-off-by: Khem Raj --- src/pkcs15init/pkcs15-oberthur.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 322a74a4a5..98a61d5aa1 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -70,7 +70,6 @@ cosm_write_tokeninfo (struct sc_pkcs15_card *p15card, struct sc_profile *profile ctx = p15card->card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(ctx, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags); if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) { rv = SC_ERROR_INCONSISTENT_PROFILE; SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "Cannot find "COSM_TITLE"-token-info"); From 969e29e663489bad91cf16838c94a7d028b917f3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 10 Dec 2018 13:57:54 +0100 Subject: [PATCH 0674/4321] p11test: Do not talk about multipart encryption --- src/tests/p11test/p11test_case_multipart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index 0aa45638e1..d2fc637048 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -34,7 +34,7 @@ void multipart_tests(void **state) { P11TEST_START(info); search_for_all_objects(&objects, info); - debug_print("\nCheck functionality of Multipart Sign&Verify and/or Encrypt&Decrypt"); + debug_print("\nCheck functionality of Multipart Sign&Verify"); for (i = 0; i < objects.count; i++) { if (objects.data[i].type == EVP_PK_EC) { debug_print(" [ SKIP %s ] EC keys do not support multi-part operations", @@ -42,7 +42,7 @@ void multipart_tests(void **state) { continue; } used = 0; - /* do the Sign&Verify and/or Encrypt&Decrypt */ + /* do the Sign&Verify */ /* XXX some keys do not have appropriate flags, but we can use them * or vice versa */ //if (objects.data[i].sign && objects.data[i].verify) From 28deeb2a003ff496379bc1194ef14cd6202afec6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 10 Dec 2018 13:58:50 +0100 Subject: [PATCH 0675/4321] p11test: Do not report and try pairs without private key --- src/tests/p11test/p11test_case_multipart.c | 8 ++++++++ src/tests/p11test/p11test_case_readonly.c | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index d2fc637048..150462eeca 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -36,6 +36,11 @@ void multipart_tests(void **state) { debug_print("\nCheck functionality of Multipart Sign&Verify"); for (i = 0; i < objects.count; i++) { + if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + debug_print(" [ SKIP %s ] Skip missing private key", + objects.data[i].id_str); + continue; + } if (objects.data[i].type == EVP_PK_EC) { debug_print(" [ SKIP %s ] EC keys do not support multi-part operations", objects.data[i].id_str); @@ -79,6 +84,9 @@ void multipart_tests(void **state) { objects.data[i].sign ? "[./] " : "[ ] ", objects.data[i].verify ? " [./] " : " [ ] ", objects.data[i].label); + if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + continue; + } for (j = 0; j < objects.data[i].num_mechs; j++) { test_mech_t *mech = &objects.data[i].mechs[j]; if ((mech->usage_flags & CKF_SIGN) == 0) { diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 9815bea584..2c3497c8c6 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -669,6 +669,9 @@ void readonly_tests(void **state) { printf(" no usable attributes found ... ignored\n"); continue; } + if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + continue; + } for (j = 0; j < o->num_mechs; j++) { test_mech_t *mech = &o->mechs[j]; if ((mech->usage_flags & CKF_SIGN) == 0) { From ed6267512cf53c9d828bdf5fcaae83f4a065a264 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Dec 2018 10:31:20 +0100 Subject: [PATCH 0676/4321] p11test: Do not report usage on incomplete keys --- src/tests/p11test/p11test_case_usage.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index 6973fd293e..7e92866f15 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -93,6 +93,11 @@ void usage_test(void **state) { printf("\n[%-6s] [%s]\n", objects.data[i].id_str, objects.data[i].label); + + /* Ignore if there is missing private key */ + if (objects.data[i].private_handle == CK_INVALID_HANDLE) + continue; + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s] [ %s ]\n", objects.data[i].key_type == CKK_RSA ? "RSA " : objects.data[i].key_type == CKK_EC ? " EC " : " ?? ", From f0b47a51d37f1d557162ae4e828db565bcd614ee Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Dec 2018 11:16:54 +0100 Subject: [PATCH 0677/4321] p11test: Report key sizes for missing certificates --- src/tests/p11test/p11test_case_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index d44b0d8e34..650bac8154 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -305,6 +305,7 @@ int callback_public_keys(test_certs_t *objects, o->type = EVP_PK_RSA; o->key.rsa = RSA_new(); RSA_set0_key(o->key.rsa, n, e, NULL); + o->bits = RSA_bits(o->key.rsa); n = NULL; e = NULL; } @@ -370,6 +371,7 @@ int callback_public_keys(test_certs_t *objects, o->key.ec = EC_KEY_new_by_curve_name(nid); EC_KEY_set_public_key(o->key.ec, ecpoint); EC_KEY_set_group(o->key.ec, ecgroup); + o->bits = EC_GROUP_order_bits(ecgroup); } } else { debug_print(" [WARN %s ] non-RSA, non-EC key. Key type: %02lX", From 070190d72e5832e97d898bd19d84a167bd0c76ab Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Dec 2018 10:55:39 +0100 Subject: [PATCH 0678/4321] padding: Resotre the PAD_NONE if nothing else is specified Patch from Doug Engert --- src/libopensc/padding.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 047b3bc82c..3456a6265a 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -410,6 +410,8 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, hash_algo = flags & SC_ALGORITHM_RSA_HASHES; pad_algo = flags & SC_ALGORITHM_RSA_PADS; + if (pad_algo == 0) + pad_algo = SC_ALGORITHM_RSA_PAD_NONE; sc_log(ctx, "hash algorithm 0x%X, pad algorithm 0x%X", hash_algo, pad_algo); if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || pad_algo == SC_ALGORITHM_RSA_PAD_NONE) && From 26aed9441a87251b9bd94ae7016ec0d17017d947 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Dec 2018 11:56:31 +0100 Subject: [PATCH 0679/4321] padding: Do not set wrong flags if the raw capability is not available Thanks Doug Engert for pointing the issue out --- src/libopensc/padding.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 3456a6265a..4a8fc17b9c 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -492,10 +492,10 @@ int sc_get_encoding_flags(sc_context_t *ctx, (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { *sflags |= SC_ALGORITHM_RSA_PAD_PSS; - } else if (((caps & SC_ALGORITHM_RSA_RAW) && - (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) - || iflags & SC_ALGORITHM_RSA_PAD_PSS - || iflags & SC_ALGORITHM_RSA_PAD_NONE) { + } else if ((caps & SC_ALGORITHM_RSA_RAW) && + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1 + || iflags & SC_ALGORITHM_RSA_PAD_PSS + || iflags & SC_ALGORITHM_RSA_PAD_NONE)) { /* Use the card's raw RSA capability on the padded input */ *sflags = SC_ALGORITHM_RSA_PAD_NONE; *pflags = iflags; From 4d8b2c12ed1dcada1d02fc88b3886e47ef652b04 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Dec 2018 11:35:49 +0100 Subject: [PATCH 0680/4321] card-openpgp: Workaround parsing historical bytes on Yubikey to set correct capabilities --- src/libopensc/card-openpgp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3470f70783..5cc54a2ee1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -710,6 +710,17 @@ pgp_get_card_features(sc_card_t *card) pgp_parse_hist_bytes(card, hist_bytes+2, hist_bytes_len-2); } break; + default: + /* Something else is non-standard according to + * ISO7816-4 section 8 - Historical bytes, + * but used by Yubico, which should have all + * the needed capabilities*/ + if (hist_bytes_len >= 7 && + memcmp(hist_bytes, "Yubikey", 7) == 0) { + card->caps |= SC_CARD_CAP_APDU_EXT; + priv->ext_caps |= EXT_CAP_APDU_EXT + | EXT_CAP_CHAINING; + } } } From b11cc3871e381468a53b811f550553dc6abea054 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Dec 2018 01:38:54 +0100 Subject: [PATCH 0681/4321] tools: harmonize card initialization --- doc/tools/cardos-tool.1.xml | 8 +-- doc/tools/cryptoflex-tool.1.xml | 8 +-- doc/tools/dnie-tool.1.xml | 8 +-- doc/tools/egk-tool.1.xml | 8 +-- doc/tools/eidenv.1.xml | 8 +-- doc/tools/gids-tool.1.xml | 4 +- doc/tools/iasecc-tool.1.xml | 6 +-- doc/tools/netkey-tool.1.xml | 8 +-- doc/tools/npa-tool.1.xml | 8 +-- doc/tools/openpgp-tool.1.xml | 12 ++--- doc/tools/opensc-explorer.1.xml | 8 +-- doc/tools/opensc-tool.1.xml | 8 +-- doc/tools/piv-tool.1.xml | 8 +-- doc/tools/pkcs15-crypt.1.xml | 8 +-- doc/tools/pkcs15-init.1.xml | 8 +-- doc/tools/pkcs15-tool.1.xml | 6 +-- doc/tools/sc-hsm-tool.1.xml | 8 +-- doc/tools/westcos-tool.1.xml | 8 +-- src/tools/Makefile.am | 8 ++- src/tools/Makefile.mak | 8 +-- src/tools/egk-tool-cmdline.c | 46 ++++++++---------- src/tools/egk-tool-cmdline.h | 6 +-- src/tools/egk-tool.c | 76 ++++++----------------------- src/tools/egk-tool.ggo.in | 5 +- src/tools/npa-tool-cmdline.c | 35 ++----------- src/tools/npa-tool-cmdline.h | 6 +-- src/tools/npa-tool.c | 81 ++++++------------------------- src/tools/npa-tool.ggo.in | 5 +- src/tools/opensc-notify-cmdline.c | 2 +- src/tools/opensc-notify-cmdline.h | 4 +- 30 files changed, 149 insertions(+), 273 deletions(-) diff --git a/doc/tools/cardos-tool.1.xml b/doc/tools/cardos-tool.1.xml index 5f461414ae..c41e78a0fd 100644 --- a/doc/tools/cardos-tool.1.xml +++ b/doc/tools/cardos-tool.1.xml @@ -63,14 +63,14 @@ smart cards and similar security tokens based on Siemens Card/OS M4. - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/cryptoflex-tool.1.xml b/doc/tools/cryptoflex-tool.1.xml index f34a3c00bd..35d5c04878 100644 --- a/doc/tools/cryptoflex-tool.1.xml +++ b/doc/tools/cryptoflex-tool.1.xml @@ -131,14 +131,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index c7bc205125..0fbbb47e76 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -83,14 +83,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/egk-tool.1.xml b/doc/tools/egk-tool.1.xml index df6a9cb6e1..42754235a4 100644 --- a/doc/tools/egk-tool.1.xml +++ b/doc/tools/egk-tool.1.xml @@ -50,10 +50,10 @@ arg - Specify the reader to use. - Use -1 as arg - to automatically detect the reader to use. - By default, the first reader with a present card is used. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen. diff --git a/doc/tools/eidenv.1.xml b/doc/tools/eidenv.1.xml index 75f2d0a778..9ecae75c6a 100644 --- a/doc/tools/eidenv.1.xml +++ b/doc/tools/eidenv.1.xml @@ -66,14 +66,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/gids-tool.1.xml b/doc/tools/gids-tool.1.xml index ee1a5cac4c..a7d4f8be07 100644 --- a/doc/tools/gids-tool.1.xml +++ b/doc/tools/gids-tool.1.xml @@ -84,9 +84,9 @@ - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + argument is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/iasecc-tool.1.xml b/doc/tools/iasecc-tool.1.xml index 01f0a74692..7b17557162 100644 --- a/doc/tools/iasecc-tool.1.xml +++ b/doc/tools/iasecc-tool.1.xml @@ -34,13 +34,13 @@ - num, + arg, - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/netkey-tool.1.xml b/doc/tools/netkey-tool.1.xml index 24badd9061..89516c03df 100644 --- a/doc/tools/netkey-tool.1.xml +++ b/doc/tools/netkey-tool.1.xml @@ -71,14 +71,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/npa-tool.1.xml b/doc/tools/npa-tool.1.xml index a3b419b81e..8dcf07ffdf 100644 --- a/doc/tools/npa-tool.1.xml +++ b/doc/tools/npa-tool.1.xml @@ -52,10 +52,10 @@ arg - Specify the reader to use. - Use -1 as arg - to automatically detect the reader to use. - By default, the first reader with a present card is used. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen. diff --git a/doc/tools/openpgp-tool.1.xml b/doc/tools/openpgp-tool.1.xml index bdcaf21ba2..5f46be2984 100644 --- a/doc/tools/openpgp-tool.1.xml +++ b/doc/tools/openpgp-tool.1.xml @@ -179,14 +179,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen. diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 128b486a03..7fdd93cebc 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -76,14 +76,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index d92c022e3c..9252d0ce0b 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -112,14 +112,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 234c3c823c..27a052b24b 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -151,14 +151,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/pkcs15-crypt.1.xml b/doc/tools/pkcs15-crypt.1.xml index 6bc6b90e9d..6c634af469 100644 --- a/doc/tools/pkcs15-crypt.1.xml +++ b/doc/tools/pkcs15-crypt.1.xml @@ -129,14 +129,14 @@ - N, - N + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 88e73c7ae7..0983dbca12 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -644,14 +644,14 @@ puk 87654321 - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index bb224c37e2..c995a3fa59 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -278,13 +278,13 @@ - num + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/sc-hsm-tool.1.xml b/doc/tools/sc-hsm-tool.1.xml index 9f130e1ee2..deb53e9172 100644 --- a/doc/tools/sc-hsm-tool.1.xml +++ b/doc/tools/sc-hsm-tool.1.xml @@ -201,14 +201,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index 3ddf3827fb..3034f2e879 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -148,14 +148,14 @@ - num, - num + arg, + arg - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen. diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 9579c766b7..a01570f64d 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -84,10 +84,14 @@ dnie_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) gids_tool_SOURCES = gids-tool.c util.c gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) -npa_tool_SOURCES = npa-tool.c fread_to_eof.c $(NPA_TOOL_BUILT_SOURCES) +npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c $(NPA_TOOL_BUILT_SOURCES) npa_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la \ $(OPENPACE_LIBS) npa_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) $(OPENSSL_CFLAGS) +npa_tool_CFLAGS += -Wno-unused-but-set-variable +if HAVE_UNKNOWN_WARNING_OPTION +npa_tool_CFLAGS += -Wno-unknown-warning-option +endif npa-tool.c: $(abs_builddir)/npa-tool.ggo $(NPA_TOOL_BUILT_SOURCES) @@ -117,7 +121,7 @@ $(OPENSC_NOTIFY_BUILT_SOURCES): $(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in $(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@ -egk_tool_SOURCES = egk-tool.c $(EGK_TOOL_BUILT_SOURCES) +egk_tool_SOURCES = egk-tool.c util.c $(EGK_TOOL_BUILT_SOURCES) egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) egk_tool_CFLAGS += -Wno-unused-but-set-variable diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 20be4b0476..0c10a08493 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -27,14 +27,14 @@ opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIB link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj $(LIBS) +npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -egk-tool.exe: egk-tool-cmdline.obj $(LIBS) +egk-tool.exe: egk-tool-cmdline.obj util.obj $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj util.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) diff --git a/src/tools/egk-tool-cmdline.c b/src/tools/egk-tool-cmdline.c index 1ae79678bc..39f991e768 100644 --- a/src/tools/egk-tool-cmdline.c +++ b/src/tools/egk-tool-cmdline.c @@ -33,22 +33,22 @@ const char *gengetopt_args_info_versiontext = ""; const char *gengetopt_args_info_description = ""; const char *gengetopt_args_info_help[] = { - " -h, --help Print help and exit", - " -V, --version Print version and exit", - " -r, --reader=INT Number of the PC/SC reader to use (-1 for autodetect)\n (default=`-1')", - " -v, --verbose Use (several times) to be more verbose", + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -r, --reader=STRING Number of the reader to use. By default, the first\n reader with a present card is used. If the arguement\n is an ATR, the reader with a matching card will be\n chosen.", + " -v, --verbose Use (several times) to be more verbose", "\nHealth Care Application (HCA):", - " --pd Show 'Persönliche Versicherungsdaten' (XML) (default=off)", - " --vd Show 'Allgemeine Versicherungsdaten' (XML) (default=off)", - " --gvd Show 'Geschützte Versicherungsdaten' (XML) (default=off)", - " --vsd-status Show 'Versichertenstammdaten-Status' (default=off)", + " --pd Show 'Persönliche Versicherungsdaten' (XML)\n (default=off)", + " --vd Show 'Allgemeine Versicherungsdaten' (XML)\n (default=off)", + " --gvd Show 'Geschützte Versicherungsdaten' (XML)\n (default=off)", + " --vsd-status Show 'Versichertenstammdaten-Status' (default=off)", "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; typedef enum {ARG_NO , ARG_FLAG - , ARG_INT + , ARG_STRING } cmdline_parser_arg_type; static @@ -83,7 +83,7 @@ static void clear_args (struct gengetopt_args_info *args_info) { FIX_UNUSED (args_info); - args_info->reader_arg = -1; + args_info->reader_arg = NULL; args_info->reader_orig = NULL; args_info->pd_flag = 0; args_info->vd_flag = 0; @@ -190,6 +190,7 @@ static void cmdline_parser_release (struct gengetopt_args_info *args_info) { + free_string_field (&(args_info->reader_arg)); free_string_field (&(args_info->reader_orig)); @@ -1051,6 +1052,7 @@ int update_arg(void *field, char **orig_field, char *stop_char = 0; const char *val = value; int found; + char **string_field; FIX_UNUSED (field); stop_char = 0; @@ -1084,24 +1086,18 @@ int update_arg(void *field, char **orig_field, case ARG_FLAG: *((int *)field) = !*((int *)field); break; - case ARG_INT: - if (val) *((int *)field) = strtol (val, &stop_char, 0); + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } break; default: break; }; - /* check numeric conversion */ - switch(arg_type) { - case ARG_INT: - if (val && !(stop_char && *stop_char == '\0')) { - fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); - return 1; /* failure */ - } - break; - default: - ; - }; /* store the original value */ switch(arg_type) { @@ -1203,12 +1199,12 @@ cmdline_parser_internal ( cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); - case 'r': /* Number of the PC/SC reader to use (-1 for autodetect). */ + case 'r': /* Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ if (update_arg( (void *)&(args_info->reader_arg), &(args_info->reader_orig), &(args_info->reader_given), - &(local_args_info.reader_given), optarg, 0, "-1", ARG_INT, + &(local_args_info.reader_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "reader", 'r', additional_error)) diff --git a/src/tools/egk-tool-cmdline.h b/src/tools/egk-tool-cmdline.h index 4b8912649f..3fb36efaca 100644 --- a/src/tools/egk-tool-cmdline.h +++ b/src/tools/egk-tool-cmdline.h @@ -39,9 +39,9 @@ struct gengetopt_args_info { const char *help_help; /**< @brief Print help and exit help description. */ const char *version_help; /**< @brief Print version and exit help description. */ - int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ - char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ - const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ + char * reader_arg; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ + char * reader_orig; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. original value given at command line. */ + const char *reader_help; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. help description. */ unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index af787ed879..f2915ea205 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -24,6 +24,7 @@ #include "egk-tool-cmdline.h" #include "libopensc/log.h" #include "libopensc/opensc.h" +#include "util.h" #include #include #include @@ -81,59 +82,7 @@ void dump_binary(void *buf, size_t buf_len) } const unsigned char aid_hca[] = {0xD2, 0x76, 0x00, 0x00, 0x01, 0x02}; - -static int initialize(int reader_id, int verbose, - sc_context_t **ctx, sc_reader_t **reader) -{ - unsigned int i, reader_count; - int r; - - if (!ctx || !reader) - return SC_ERROR_INVALID_ARGUMENTS; - - r = sc_establish_context(ctx, ""); - if (r < 0 || !*ctx) { - fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); - return r; - } - - (*ctx)->debug = verbose; - (*ctx)->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; - - reader_count = sc_ctx_get_reader_count(*ctx); - - if (reader_count == 0) { - sc_log(*ctx, "No reader not found.\n"); - return SC_ERROR_NO_READERS_FOUND; - } - - if (reader_id < 0) { - /* Automatically try to skip to a reader with a card if reader not specified */ - for (i = 0; i < reader_count; i++) { - *reader = sc_ctx_get_reader(*ctx, i); - if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { - reader_id = i; - sc_log(*ctx, "Using the first reader" - " with a card: %s", (*reader)->name); - break; - } - } - if ((unsigned int) reader_id >= reader_count) { - sc_log(*ctx, "No card found, using the first reader."); - reader_id = 0; - } - } - - if ((unsigned int) reader_id >= reader_count) { - sc_log(*ctx, "Invalid reader number " - "(%d), only %d available.\n", reader_id, reader_count); - return SC_ERROR_NO_READERS_FOUND; - } - - *reader = sc_ctx_get_reader(*ctx, reader_id); - - return SC_SUCCESS; -} +static const char *app_name = "egk-tool"; int read_file(struct sc_card *card, char *str_path, unsigned char **data, size_t *data_len) { @@ -196,27 +145,30 @@ main (int argc, char **argv) struct gengetopt_args_info cmdline; struct sc_path path; struct sc_context *ctx; - struct sc_reader *reader = NULL; struct sc_card *card; unsigned char *data = NULL; size_t data_len = 0; int r; + sc_context_param_t ctx_param; if (cmdline_parser(argc, argv, &cmdline) != 0) exit(1); - r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader); - if (r < 0) { - fprintf(stderr, "Can't initialize reader\n"); - exit(1); - } + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = app_name; - if (sc_connect_card(reader, &card) < 0) { - fprintf(stderr, "Could not connect to card\n"); - sc_release_context(ctx); + r = sc_context_create(&ctx, &ctx_param); + if (r) { + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); exit(1); } + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + if (r) + goto err; + + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_hca, sizeof aid_hca, 0, 0); if (SC_SUCCESS != sc_select_file(card, &path, NULL)) goto err; diff --git a/src/tools/egk-tool.ggo.in b/src/tools/egk-tool.ggo.in index 9142c3e8d8..6b709461fd 100644 --- a/src/tools/egk-tool.ggo.in +++ b/src/tools/egk-tool.ggo.in @@ -2,9 +2,8 @@ package "egk-tool" purpose "@PACKAGE_SUMMARY@" option "reader" r - "Number of the PC/SC reader to use (-1 for autodetect)" - int - default="-1" + "Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen." + string optional option "verbose" v "Use (several times) to be more verbose" diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 117c6cb156..1b88a20cea 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -35,7 +35,7 @@ const char *gengetopt_args_info_description = ""; const char *gengetopt_args_info_help[] = { " -h, --help Print help and exit", " -V, --version Print version and exit", - " -r, --reader=INT Number of the PC/SC reader to use (-1 for\n autodetect) (default=`-1')", + " -r, --reader=STRING Number of the reader to use. By default, the\n first reader with a present card is used. If\n the arguement is an ATR, the reader with a\n matching card will be chosen.", " -v, --verbose Use (several times) to be more verbose", "\nPassword Authenticated Connection Establishment (PACE):", " -p, --pin[=STRING] Run PACE with (transport) eID-PIN", @@ -100,7 +100,6 @@ const char *gengetopt_args_info_help[] = { typedef enum {ARG_NO , ARG_FLAG , ARG_STRING - , ARG_INT } cmdline_parser_arg_type; static @@ -181,7 +180,7 @@ static void clear_args (struct gengetopt_args_info *args_info) { FIX_UNUSED (args_info); - args_info->reader_arg = -1; + args_info->reader_arg = NULL; args_info->reader_orig = NULL; args_info->pin_arg = NULL; args_info->pin_orig = NULL; @@ -400,7 +399,6 @@ free_string_field (char **s) /** @brief generic value variable */ union generic_value { - int int_arg; char *string_arg; const char *default_string_arg; }; @@ -448,6 +446,7 @@ static void cmdline_parser_release (struct gengetopt_args_info *args_info) { + free_string_field (&(args_info->reader_arg)); free_string_field (&(args_info->reader_orig)); free_string_field (&(args_info->pin_arg)); free_string_field (&(args_info->pin_orig)); @@ -1558,9 +1557,6 @@ int update_arg(void *field, char **orig_field, case ARG_FLAG: *((int *)field) = !*((int *)field); break; - case ARG_INT: - if (val) *((int *)field) = strtol (val, &stop_char, 0); - break; case ARG_STRING: if (val) { string_field = (char **)field; @@ -1573,17 +1569,6 @@ int update_arg(void *field, char **orig_field, break; }; - /* check numeric conversion */ - switch(arg_type) { - case ARG_INT: - if (val && !(stop_char && *stop_char == '\0')) { - fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); - return 1; /* failure */ - } - break; - default: - ; - }; /* store the original value */ switch(arg_type) { @@ -1688,8 +1673,6 @@ void update_multiple_arg(void *field, char ***orig_field, *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); switch(arg_type) { - case ARG_INT: - *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break; case ARG_STRING: *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break; default: @@ -1701,8 +1684,6 @@ void update_multiple_arg(void *field, char ***orig_field, tmp = list; switch(arg_type) { - case ARG_INT: - (*((int **)field))[i + field_given] = tmp->arg.int_arg; break; case ARG_STRING: (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break; default: @@ -1715,12 +1696,6 @@ void update_multiple_arg(void *field, char ***orig_field, } else { /* set the default value */ if (default_value && ! field_given) { switch(arg_type) { - case ARG_INT: - if (! *((int **)field)) { - *((int **)field) = (int *)malloc (sizeof (int)); - (*((int **)field))[0] = default_value->int_arg; - } - break; case ARG_STRING: if (! *((char ***)field)) { *((char ***)field) = (char **)malloc (sizeof (char *)); @@ -1863,12 +1838,12 @@ cmdline_parser_internal ( cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); - case 'r': /* Number of the PC/SC reader to use (-1 for autodetect). */ + case 'r': /* Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ if (update_arg( (void *)&(args_info->reader_arg), &(args_info->reader_orig), &(args_info->reader_given), - &(local_args_info.reader_given), optarg, 0, "-1", ARG_INT, + &(local_args_info.reader_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "reader", 'r', additional_error)) diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index 8c78362a0d..ad42cc0bdd 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -39,9 +39,9 @@ struct gengetopt_args_info { const char *help_help; /**< @brief Print help and exit help description. */ const char *version_help; /**< @brief Print version and exit help description. */ - int reader_arg; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) (default='-1'). */ - char * reader_orig; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) original value given at command line. */ - const char *reader_help; /**< @brief Number of the PC/SC reader to use (-1 for autodetect) help description. */ + char * reader_arg; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ + char * reader_orig; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. original value given at command line. */ + const char *reader_help; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. help description. */ unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 92b5280894..91bf6489c3 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -22,15 +22,16 @@ #endif #ifdef ENABLE_OPENPACE -#include "npa-tool-cmdline.h" #include "fread_to_eof.h" -#include "sm/sslutil.h" +#include "npa-tool-cmdline.h" #include "sm/sm-eac.h" +#include "sm/sslutil.h" +#include "util.h" #include +#include #include #include #include -#include #include #include #include @@ -111,59 +112,7 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA_NPA_TOOL) label, (unsigned int) len, len==1?"":"s", len==0?"":":\n", sc_dump_hex(data, len)); \ } -static int initialize(int reader_id, int verbose, - sc_context_t **ctx, sc_reader_t **reader) -{ - unsigned int i, reader_count; - int r; - - if (!ctx || !reader) - return SC_ERROR_INVALID_ARGUMENTS; - - r = sc_establish_context(ctx, ""); - if (r < 0 || !*ctx) { - fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); - return r; - } - - (*ctx)->debug = verbose; - (*ctx)->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; - - reader_count = sc_ctx_get_reader_count(*ctx); - - if (reader_count == 0) { - sc_log(*ctx, "No reader not found.\n"); - return SC_ERROR_NO_READERS_FOUND; - } - - if (reader_id < 0) { - /* Automatically try to skip to a reader with a card if reader not specified */ - for (i = 0; i < reader_count; i++) { - *reader = sc_ctx_get_reader(*ctx, i); - if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { - reader_id = i; - sc_log(*ctx, "Using the first reader" - " with a card: %s", (*reader)->name); - break; - } - } - if ((unsigned int) reader_id >= reader_count) { - sc_log(*ctx, "No card found, using the first reader."); - reader_id = 0; - } - } - - if ((unsigned int) reader_id >= reader_count) { - sc_log(*ctx, "Invalid reader number " - "(%d), only %d available.\n", reader_id, reader_count); - return SC_ERROR_NO_READERS_FOUND; - } - - *reader = sc_ctx_get_reader(*ctx, reader_id); - - return SC_SUCCESS; -} - +static const char *app_name = "npa-tool"; static void read_dg(sc_card_t *card, unsigned char sfid, const char *dg_str, unsigned char **dg, size_t *dg_len) @@ -361,7 +310,7 @@ main (int argc, char **argv) sc_context_t *ctx = NULL; sc_card_t *card = NULL; - sc_reader_t *reader = NULL; + sc_context_param_t ctx_param; int r, tr_version = EAC_TR_VERSION_2_02; struct establish_pace_channel_input pace_input; @@ -428,18 +377,20 @@ main (int argc, char **argv) eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA; - r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader); - if (r < 0) { - fprintf(stderr, "Can't initialize reader\n"); - exit(1); - } + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = app_name; - if (sc_connect_card(reader, &card) < 0) { - fprintf(stderr, "Could not connect to card\n"); - sc_release_context(ctx); + r = sc_context_create(&ctx, &ctx_param); + if (r) { + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); exit(1); } + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + if (r) + goto err; + EAC_init(); if (cmdline.cvc_dir_given) EAC_set_cvc_default_dir(cmdline.cvc_dir_arg); diff --git a/src/tools/npa-tool.ggo.in b/src/tools/npa-tool.ggo.in index 11b0199ef2..e27889ca72 100644 --- a/src/tools/npa-tool.ggo.in +++ b/src/tools/npa-tool.ggo.in @@ -2,9 +2,8 @@ package "npa-tool" purpose "@PACKAGE_SUMMARY@" option "reader" r - "Number of the PC/SC reader to use (-1 for autodetect)" - int - default="-1" + "Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen." + string optional option "verbose" v "Use (several times) to be more verbose" diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index 96f2b373c0..4870aa28c5 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -1176,7 +1176,7 @@ cmdline_parser_internal ( goto failure; break; - case 'R': /* See notify_card_inserted in opensc.conf. */ + case 'R': /* See notify_card_removed in opensc.conf. */ args_info->standard_mode_counter += 1; diff --git a/src/tools/opensc-notify-cmdline.h b/src/tools/opensc-notify-cmdline.h index f0783d6281..9bd779632c 100644 --- a/src/tools/opensc-notify-cmdline.h +++ b/src/tools/opensc-notify-cmdline.h @@ -47,8 +47,8 @@ struct gengetopt_args_info const char *message_help; /**< @brief Main text of the notification help description. */ int notify_card_inserted_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */ const char *notify_card_inserted_help; /**< @brief See notify_card_inserted in opensc.conf help description. */ - int notify_card_removed_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */ - const char *notify_card_removed_help; /**< @brief See notify_card_inserted in opensc.conf help description. */ + int notify_card_removed_flag; /**< @brief See notify_card_removed in opensc.conf (default=off). */ + const char *notify_card_removed_help; /**< @brief See notify_card_removed in opensc.conf help description. */ int notify_pin_good_flag; /**< @brief See notify_pin_good in opensc.conf (default=off). */ const char *notify_pin_good_help; /**< @brief See notify_pin_good in opensc.conf help description. */ int notify_pin_bad_flag; /**< @brief See notify_pin_bad in opensc.conf (default=off). */ From dc505be808dca81809221e739ecb9ce1ff34adbf Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Fri, 23 Nov 2018 18:51:22 +0100 Subject: [PATCH 0682/4321] openpgp-tool: use binary OR for calculating 32-bit integers from byte Also avoid potential unintended sign extension (SIGN_EXTENSION). --- src/tools/openpgp-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index d00b4450ef..24230e1c77 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -239,7 +239,7 @@ static char *prettify_algorithm(u8 *data, size_t length) static char *prettify_date(u8 *data, size_t length) { if (data != NULL && length == 4) { - time_t time = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + time_t time = (time_t) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); struct tm *tp; static char result[64]; /* large enough */ @@ -312,9 +312,9 @@ static char *prettify_serialnumber(u8 *data, size_t length) { if (data != NULL && length >= 4) { static char result[15]; /* large enough for even 2*3 digits + separator */ - unsigned int serial = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + unsigned long serial = (unsigned long) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); - sprintf(result, "%08X", serial); + sprintf(result, "%08lX", serial); return result; } return NULL; From e13c0b83ef9dddb7294c10be37367071b69209f4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 5 Dec 2018 14:12:07 -0600 Subject: [PATCH 0683/4321] PIV - Improved Card Matching for Dual CAC/PIV and PIVKEY cards. Not all PIV applets are the same. Different versions of NIST 800-73 and improperly implemented or not implemented required features of NIST 800-73 cases problems. Have a look at the card_issues listed in card-piv.c. The PIV driver has tried to detect the differences based on clues found in the ATR historical bytes and vendor version numbers for some cards. At the same time it has tried to support the possibility there are multiple applets on a card that the user may want to use at the same time from different applications. This has lead to some detection problems with Dual CAC/PIV cards. The same cards sold by the vendor may have only a PIV applet that may not be the same PIV applet that is on the Dual PIV/CAC cards. http://www.cac.mil/Portals/53/Documents/CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc defines a number of official CAC cards in active service. A table of the ATRs for these is now used to detect these cards. The PIV version of the CCC is also read to see if any CAC PKI objects are defined in the CCC, indicating it is a Dual CAC/PIV, even if the ATR is not listed. A more conservative approach to try and handle multiple applets on a card is used. Based on issues with the implementation of the PIV applet this may not be possible to do. So for many cards no additional detection will be done at the start of every transaction, and the login state can not be detected correctly. ATRs for PIVKEY are also in the match table, as these cards have a log of issues. Other PIV cards in the future or not yet tested may not be covered properly by this patch. Extra debugging was added with "PIV_MATCH" to help with these other cards. With "debug = 7;", `grep PIV_MATCH opensc-debug.log` can be used to see how a card type and card_issues are derived. On branch piv-improved-matching Changes to be committed: modified: card-piv.c modified: cards.h --- src/libopensc/card-piv.c | 335 +++++++++++++++++++++++++++++++++------ src/libopensc/cards.h | 6 + 2 files changed, 296 insertions(+), 45 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 03c83868f1..6d37ea15ed 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3,7 +3,7 @@ * card-default.c: Support for cards with no driver * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2005-2016 Douglas E. Engert + * Copyright (C) 2005-2018 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner * @@ -53,6 +53,7 @@ #ifdef ENABLE_ZLIB #include "compression.h" #endif +#include "simpletlv.h" enum { PIV_OBJ_CCC = 0, @@ -146,6 +147,16 @@ enum { PIV_STATE_INIT }; +/* ccc_flags */ +#define PIV_CCC_FOUND 0x00000001 +#define PIV_CCC_F0_PIV 0x00000002 +#define PIV_CCC_F0_CAC 0x00000004 +#define PIV_CCC_F0_JAVA 0x00000008 +#define PIV_CCC_F3_CAC_PKI 0x00000010 + +#define PIV_CCC_TAG_F0 0xF0 +#define PIV_CCC_TAG_F3 0xF3 + typedef struct piv_private_data { int enumtag; int selected_obj; /* The index into the piv_objects last selected */ @@ -174,6 +185,7 @@ typedef struct piv_private_data { unsigned int card_issues; /* card_issues flags for this card */ int object_test_verify; /* Can test this object to set verification state of card */ int yubico_version; /* 3 byte version number of NEO or Yubikey4 as integer */ + unsigned int ccc_flags; /* From CCC indicate if CAC card */ } piv_private_data_t; #define PIV_DATA(card) ((piv_private_data_t*)card->drv_data) @@ -198,6 +210,37 @@ struct piv_aid { * These can be discovered by trying GET DATA */ +/* ATRs of cards known to have PIV applet. But must still be tested for a PIV applet */ +static const struct sc_atr_table piv_atrs[] = { + /* CAC cards with PIV from: CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc */ + /* Oberthur Card Systems (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */ + { "3B:DB:96:00:80:1F:03:00:31:C0:64:77:E3:03:00:82:90.00:C1", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, + + /* Gemalto (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */ + { "3B 7D 96 00 00 80 31 80 65 B0 83 11 13 AC 83 00 90 00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL }, + + /* Gemalto (PIV Endpoint) 2 entries */ + { "3B:7D:96:00:00:80:31:80:65:B0:83:11:17:D6:83:00:90:00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL }, + + /* Oberthur Card System (PIV Endpoint) 2 entries*/ + { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:07:90:00:80", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, + + /* Giesecke & Devrient (PIV Endpoint) 2 entries */ + { "3B:7A:18:00:00:73:66:74:65:20:63:64:31:34:34", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL }, + + /* PIVKEY from Taligo */ + /* PIVKEY T600 token and T800 on Feitian eJAVA */ + { "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:00:64:2D:70:C1:72:FE:E0:FE", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + + /* PIVKEY C910 */ + { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:16:06:f2:72:7e:00:e0", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + + /* PIVKEY C980 */ + { "3B:f9:96:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:28", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + + { NULL, NULL, NULL, 0, 0, NULL } +}; + /* all have same AID */ static struct piv_aid piv_aids[] = { {SC_CARD_TYPE_PIV_II_GENERIC, /* TODO not really card type but what PIV AID is supported */ @@ -209,9 +252,10 @@ static struct piv_aid piv_aids[] = { #define CI_VERIFY_630X 0x00000001U /* VERIFY tries left returns 630X rather then 63CX */ #define CI_VERIFY_LC0_FAIL 0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */ /* will also test after first PIN verify if protected object can be used instead */ +#define CI_NO_RANDOM 0x00000004U /* can not use Challenge to get random data or no 9B key */ #define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */ #define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */ -#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */ +#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */ #define CI_PIV_AID_LOSE_STATE 0x00000040U /* PIV AID can lose the login state run with out it*/ #define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */ @@ -219,7 +263,7 @@ static struct piv_aid piv_aids[] = { #define CI_NO_RSA2048 0x00010000U /* does not have RSA 2048 */ #define CI_NO_EC384 0x00020000U /* does not have EC 384 */ - +#define CI_NO_EC 0x00040000U /* No EC at all */ /* * Flags in the piv_object: @@ -2222,9 +2266,15 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) size_t rbuf_len = 0, out_len = 0; int r; unsigned int tag, cla; + piv_private_data_t * priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); + if (priv->card_issues & CI_NO_RANDOM) { + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(card->ctx, r, "No support for random data"); + } + /* NIST 800-73-3 says use 9B, previous verisons used 00 */ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed"); @@ -2635,6 +2685,91 @@ static int piv_process_discovery(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } +/* + * parse a CCC to test if this is a Dual CAC/PIV + * We read teh CCC using the PIV API. + * Look for CAC RID=A0 00 00 00 79 + */ + static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) +{ + int r = 0; + const u8 * body; + size_t bodylen; + unsigned int cla_out, tag_out; + + u8 tag; + const u8 * end; + size_t len; + + piv_private_data_t * priv = PIV_DATA(card); + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (rbuf == NULL || rbuflen == 0) { + r = SC_ERROR_WRONG_LENGTH; + goto err; + } + + /* Outer layer is a DER tlv */ + body = rbuf; + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) { + sc_log(card->ctx, "DER problem %d",r); + r = SC_ERROR_INVALID_ASN1_OBJECT; + goto err; + } + + priv->ccc_flags |= PIV_CCC_FOUND; + + /* CCC entries are simple tlv */ + end = body + bodylen; + + for(; (body < end); body += len) { + + r = sc_simpletlv_read_tag((u8**)&body, end - body , &tag, &len); + if (r < 0) + goto err; + switch (tag) { + case PIV_CCC_TAG_F0: + if (len == 0x15) { + if (memcmp(body ,"\xA0\x00\x00\x03\08", 5) == 0) + priv->ccc_flags |= PIV_CCC_F0_PIV; + else if (memcmp(body ,"\xA0\x00\x00\x00\x79", 5) == 0) + priv->ccc_flags |= PIV_CCC_F0_CAC; + if (*(body + 6) == 0x02) + priv->ccc_flags |= PIV_CCC_F0_JAVA; + } + break; + case PIV_CCC_TAG_F3: + if (len == 0x10) { + if (memcmp(body ,"\xA0\x00\x00\x00\x79\x04", 6) == 0) + priv->ccc_flags |= PIV_CCC_F3_CAC_PKI; + } + break; + } + } + +err: + LOG_FUNC_RETURN(card->ctx, r); +} + +static int piv_process_ccc(sc_card_t *card) +{ + int r = 0; + u8 * rbuf = NULL; + size_t rbuflen = 0; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + r = piv_get_cached_data(card, PIV_OBJ_CCC, &rbuf, &rbuflen); + + if (r < 0) + goto err; + + /* the object is now cached, see what we have */ + r = piv_parse_ccc(card, rbuf, rbuflen); +err: + LOG_FUNC_RETURN(card->ctx, r); +} + static int piv_find_discovery(sc_card_t *card) { @@ -2922,7 +3057,8 @@ piv_finish(sc_card_t *card) static int piv_match_card(sc_card_t *card) { int r = 0; - + + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type); /* piv_match_card may be called with card->type, set by opensc.conf */ /* user provide card type must be one we know */ switch (card->type) { @@ -2931,7 +3067,13 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_PIVKEY: break; default: return 0; /* can not handle the card */ @@ -2950,13 +3092,14 @@ static int piv_match_card(sc_card_t *card) piv_finish(card); } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type,r); return r; } static int piv_match_card_continued(sc_card_t *card) { - int i, r; + int i, r = 0; int type = -1; piv_private_data_t *priv = NULL; int saved_type = card->type; @@ -2973,12 +3116,19 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_PIVKEY: type = card->type; break; default: return 0; /* can not handle the card */ } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); if (type == -1) { /* @@ -2997,18 +3147,6 @@ static int piv_match_card_continued(sc_card_t *card) !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) { type = SC_CARD_TYPE_PIV_II_NEO; } - /* - * https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp1239.pdf - * lists 2 ATRS with historical bytes: - * 73 66 74 65 2D 63 64 30 38 30 - * 73 66 74 65 20 63 64 31 34 34 - * will check for 73 66 74 65 - */ - else if (card->reader->atr_info.hist_bytes_len >= 4 - && !(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) { - type = SC_CARD_TYPE_PIV_II_GI_DE; - } - else if (card->reader->atr_info.hist_bytes_len > 0 && card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ size_t datalen; @@ -3029,10 +3167,17 @@ static int piv_match_card_continued(sc_card_t *card) } } } - if (type == -1) - type = SC_CARD_TYPE_PIV_II_GENERIC; + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); + + if (type == -1) { + /* use known ATRs */ + i = _sc_match_atr(card, piv_atrs, &type); + if (type == -1) + type = SC_CARD_TYPE_PIV_II_GENERIC; /* may still be CAC with PIV Endpoint */ + } } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); /* allocate and init basic fields */ priv = calloc(1, sizeof(piv_private_data_t)); @@ -3046,6 +3191,7 @@ static int piv_match_card_continued(sc_card_t *card) card->drv_data = priv; /* will free if no match, or pass on to piv_init */ priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ + /* TODO Dual CAC/PIV are bases on 800-73-1 were priv->pin_preference = 0. need to check later */ priv->logged_in = SC_PIN_STATE_UNKNOWN; priv->tries_left = 10; /* will assume OK at start */ priv->pstate = PIV_STATE_MATCH; @@ -3064,38 +3210,104 @@ static int piv_match_card_continued(sc_card_t *card) } /* - * detect if active AID is PIV. NIST 800-73 says Only one PIV application per card - * and PIV must be the default application - * This can avoid doing doing a select_aid and losing the login state on some cards + * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card + * and PIV must be the default application. + * Try to avoid doing a select_aid and losing the login state on some cards. * We may get interference on some cards by other drivers trying SELECT_AID before - * we get to see if PIV application is still active. + * we get to see if PIV application is still active * putting PIV driver first might help. - * This may fail if the wrong AID is active + * This may fail if the wrong AID is active. + * Discovery Object introduced in 800-73-3 so will return 0 if found and PIV applet active. + * Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object. + * But some other card could also return SC_ERROR_FILE_NOT_FOUND. + * Will fail for other reasons if wrong applet is selected, or bad PIV implimentation. */ - i = piv_find_discovery(card); + + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); + if (priv->card_issues & CI_DISCOVERY_USELESS) /* TODO may be in wrong place */ + i = -1; + else + i = piv_find_discovery(card); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); if (i < 0) { /* Detect by selecting applet */ i = piv_find_aid(card); } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); if (i >= 0) { + int iccc = 0; + /* We now know PIV AID is active, test CCC object 800-73-* say CCC is required */ + switch (card->type) { + /* + * For cards that may also be CAC, try and read the CCC + * CCC is required and all Dual PIV/CAC will have a CCC + * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History + */ + case SC_CARD_TYPE_PIV_II_GENERIC: /* i.e. really dont know what this is */ + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + iccc = piv_process_ccc(card); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d iccc:%d ccc_flags:%08x CI:%08x r:%d\n", + card->type, iccc, priv->ccc_flags, priv->card_issues, r); + /* ignore an error? */ + /* if CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ + if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { + switch (card->type) { + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO: + card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + } + } + break; + + /* if user forced it to be one of the CAC types, assume it is CAC */ + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + } + } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); + if (i >= 0 && (priv->card_issues & CI_DISCOVERY_USELESS) == 0) { /* - * We now know PIV AID is active, test DISCOVERY object - * Some CAC cards with PIV don't support DISCOVERY and return - * SC_ERROR_INCORRECT_PARAMETERS. Any error other then - * SC_ERROR_FILE_NOT_FOUND means we cannot use discovery + * We now know PIV AID is active, test DISCOVERY object again + * Some PIV don't support DISCOVERY and return + * SC_ERROR_INCORRECT_PARAMETERS. Any error + * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery * to test for active AID. */ int i7e = piv_find_discovery(card); - if (i7e != 0 && i7e != SC_ERROR_FILE_NOT_FOUND) { + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i7e:%d CI:%08x r:%d\n", card->type, i7e, priv->card_issues, r); + if (i7e != 0) { priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; } } - + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); if (i < 0) { /* don't match. Does not have a PIV applet. */ sc_unlock(card); @@ -3104,6 +3316,7 @@ static int piv_match_card_continued(sc_card_t *card) return 0; } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); /* Matched, caller will use or free priv and sc_lock as needed */ priv->pstate=PIV_STATE_INIT; return 1; /* match */ @@ -3124,7 +3337,7 @@ static int piv_init(sc_card_t *card) /* continue the matching get a lock and the priv */ r = piv_match_card_continued(card); if (r != 1) { - sc_log(card->ctx,"piv_match_card_continued failed"); + sc_log(card->ctx,"piv_match_card_continued failed card->type:%d", card->type); piv_finish(card); /* tell sc_connect_card to try other drivers */ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); @@ -3147,6 +3360,7 @@ static int piv_init(sc_card_t *card) * Set card_issues based on card type either set by piv_match_card or by opensc.conf */ + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); switch(card->type) { case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: @@ -3178,6 +3392,7 @@ static int piv_init(sc_card_t *card) * may be set earlier or later then in the following code. */ + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); switch(card->type) { case SC_CARD_TYPE_PIV_II_NEO: priv->card_issues |= CI_NO_EC384 @@ -3196,30 +3411,53 @@ static int piv_init(sc_card_t *card) priv->card_issues |= CI_VERIFY_LC0_FAIL; break; + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_GEMALTO: + priv->card_issues |= 0; /* could add others here */ + break; + case SC_CARD_TYPE_PIV_II_HIST: - priv->card_issues |= 0; + priv->card_issues |= 0; /* could add others here */ break; - case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_PIV_AID_LOSE_STATE - | CI_OTHER_AID_LOSE_STATE;; + | CI_NO_RANDOM + | CI_OTHER_AID_LOSE_STATE; /* TODO may need more research */ break; + case SC_CARD_TYPE_PIV_II_GENERIC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE; /* TODO may need more research */ break; + case SC_CARD_TYPE_PIV_II_PIVKEY: + priv->card_issues |= CI_VERIFY_LC0_FAIL + | CI_PIV_AID_LOSE_STATE /* be conservative */ + | CI_NO_EC384 | CI_NO_EC + | CI_NO_RANDOM; /* does not have 9B key */ + /* Discovery object returns 6A 82 so is not on card by default */ + /* TODO may need more research */ + break; + default: - priv->card_issues = 0; /* opensc.conf may have it wrong, continue anyway */ - sc_log(card->ctx, "Unknown PIV card->type %d", card->type); - card->type = SC_CARD_TYPE_PIV_II_BASE; + priv->card_issues |= CI_VERIFY_LC0_FAIL + | CI_OTHER_AID_LOSE_STATE; + /* opensc.conf may have it wrong, continue anyway */ + sc_log(card->ctx, "Unknown PIV card->type %d", card->type); + card->type = SC_CARD_TYPE_PIV_II_GENERIC; } sc_log(card->ctx, "PIV card-type=%d card_issues=0x%08x", card->type, priv->card_issues); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); + priv->enumtag = piv_aids[0].enumtag; /* PKCS#11 may try to generate session keys, and get confused @@ -3233,15 +3471,20 @@ static int piv_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ - flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + if (!(priv->card_issues & CI_NO_EC)) { + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + if (!(priv->card_issues & CI_NO_EC384)) + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + } - _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); - if (!(priv->card_issues & CI_NO_EC384)) - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + if (!(priv->card_issues & CI_NO_RANDOM)) + card->caps |= SC_CARD_CAP_RNG; - /* TODO may turn off SC_CARD_CAP_ISO7816_PIN_INFO later */ - card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; + /* May turn off SC_CARD_CAP_ISO7816_PIN_INFO later */ + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; /* * 800-73-3 cards may have a history object and/or a discovery object @@ -3565,11 +3808,13 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) r = SC_ERROR_NO_CARD_SUPPORT; } else { r = piv_find_discovery(card); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_find_discovery card->type:%d r:%d\n", card->type, r); } if (r < 0) { if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_select_aid card->type:%d r:%d\n", card->type, r); } else { r = 0; /* cant do anything with this card, hope there was no interference */ } diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index f4df17fb04..121182bb6a 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -136,7 +136,13 @@ enum { SC_CARD_TYPE_PIV_II_HIST, SC_CARD_TYPE_PIV_II_NEO, SC_CARD_TYPE_PIV_II_YUBIKEY4, + SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, SC_CARD_TYPE_PIV_II_GI_DE, + SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC, + SC_CARD_TYPE_PIV_II_GEMALTO, + SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC, + SC_CARD_TYPE_PIV_II_OBERTHUR, + SC_CARD_TYPE_PIV_II_PIVKEY, /* MuscleApplet */ SC_CARD_TYPE_MUSCLE_BASE = 15000, From 1fe1d40e3812e564ddc1667b312053354e721eb7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 8 Dec 2018 18:16:40 -0600 Subject: [PATCH 0684/4321] PIV - Improved error handling of get_challenge Random data from PIV card is obtained using GENERAL AUTHENTICATE command for a request of a Challenge from the card. "00 87 00 9B 04 7C 02 81 00" Usually 8 bytes are returned. NIST 800-73-3_PART2, "A.1 Authentication of the PIV Card Application Administrator" "Table 11. Authentication of PIV Card Application Administrator" shows an example of how to do this. Some cards (one I have: 3b:7d:96:00:00:80:31:80:65:b0:83:11:17:d6:83:00:90:00) will not allow 2 of these commands in a row. (Maybe assuming command is only used as in Table 11 and is expecting the second command.) Code was added to card-piv.c so if "6A 80" is returned, try the command one more time. For any other GENERAL AUTHENTICATE failure, SC_ERROR_NOT_SUPPORTED is returned. piv_get_challenge may be called within a loop from sc_get_challenge if more random data is needed thus causing the the 2 commands to sent in a row. On branch piv-improved-matching Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 6d37ea15ed..794472134c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2277,6 +2277,22 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) /* NIST 800-73-3 says use 9B, previous verisons used 00 */ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); + /* + * piv_get_challenge is called in a loop. + * some cards may allow 1 challenge expecting it to be part of + * NIST 800-73-3 part 2 "Authentication of PIV Card Application Administrator" + * and return "6A 80" if last command was a get_challenge. + * Now that the card returned error, we can try one more time. + */ + if (r == SC_ERROR_INCORRECT_PARAMETERS) { + if (rbuf) + free(rbuf); + rbuf_len = 0; + r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); + if (r == SC_ERROR_INCORRECT_PARAMETERS) { + r = SC_ERROR_NOT_SUPPORTED; + } + } LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed"); p = rbuf; From a78becb76e44b804389e049a3e1d35f850f93660 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 12 Dec 2018 11:33:35 -0600 Subject: [PATCH 0685/4321] PIV - Fix blanks and use returned value On branch piv-improved-matching Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 794472134c..894a4c3739 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2278,8 +2278,8 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) /* NIST 800-73-3 says use 9B, previous verisons used 00 */ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len); /* - * piv_get_challenge is called in a loop. - * some cards may allow 1 challenge expecting it to be part of + * piv_get_challenge is called in a loop. + * some cards may allow 1 challenge expecting it to be part of * NIST 800-73-3 part 2 "Authentication of PIV Card Application Administrator" * and return "6A 80" if last command was a get_challenge. * Now that the card returned error, we can try one more time. @@ -2738,9 +2738,7 @@ static int piv_process_discovery(sc_card_t *card) /* CCC entries are simple tlv */ end = body + bodylen; - for(; (body < end); body += len) { - r = sc_simpletlv_read_tag((u8**)&body, end - body , &tag, &len); if (r < 0) goto err; @@ -3188,8 +3186,8 @@ static int piv_match_card_continued(sc_card_t *card) if (type == -1) { /* use known ATRs */ i = _sc_match_atr(card, piv_atrs, &type); - if (type == -1) - type = SC_CARD_TYPE_PIV_II_GENERIC; /* may still be CAC with PIV Endpoint */ + if (i < 0) + type = SC_CARD_TYPE_PIV_II_GENERIC; /* may still be CAC with PIV Endpoint */ } } @@ -3207,7 +3205,7 @@ static int piv_match_card_continued(sc_card_t *card) card->drv_data = priv; /* will free if no match, or pass on to piv_init */ priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ - /* TODO Dual CAC/PIV are bases on 800-73-1 were priv->pin_preference = 0. need to check later */ + /* TODO Dual CAC/PIV are bases on 800-73-1 where priv->pin_preference = 0. need to check later */ priv->logged_in = SC_PIN_STATE_UNKNOWN; priv->tries_left = 10; /* will assume OK at start */ priv->pstate = PIV_STATE_MATCH; From 7fbcd6e920e09461536d6824659631d6d5f91030 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 12 Dec 2018 11:53:32 -0600 Subject: [PATCH 0686/4321] PIV - test i7e On branch piv-improved-matching Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 894a4c3739..d560508868 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3315,7 +3315,7 @@ static int piv_match_card_continued(sc_card_t *card) int i7e = piv_find_discovery(card); sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i7e:%d CI:%08x r:%d\n", card->type, i7e, priv->card_issues, r); - if (i7e != 0) { + if (i7e < 0) { priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; } From 075cac482b2723a2267c4fcd7985eb6b82effbc7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 17 Dec 2018 19:30:35 -0600 Subject: [PATCH 0687/4321] PIV - Some VA cards have LCS = 0F Terminated Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d560508868..ed804844c4 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -224,6 +224,8 @@ static const struct sc_atr_table piv_atrs[] = { /* Oberthur Card System (PIV Endpoint) 2 entries*/ { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:07:90:00:80", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, + /* Oberthur Card System with LCS 0F - Some VA cards have Terminated state */ + { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:0F:90:00:88", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* Giesecke & Devrient (PIV Endpoint) 2 entries */ { "3B:7A:18:00:00:73:66:74:65:20:63:64:31:34:34", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL }, From 54dd9f4878cf11c25bc742b0503cf6aaeeddb536 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 22 Dec 2018 20:28:09 +0100 Subject: [PATCH 0688/4321] OpenPGP: revert 4d8b2c12ed1dcada1d02fc88b3886e47ef652b04 It broke OpenPGP on Yubikey NEOs and maybe other older versions too. Reverting it restores functionality for those Yubikeys. --- src/libopensc/card-openpgp.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5cc54a2ee1..3470f70783 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -710,17 +710,6 @@ pgp_get_card_features(sc_card_t *card) pgp_parse_hist_bytes(card, hist_bytes+2, hist_bytes_len-2); } break; - default: - /* Something else is non-standard according to - * ISO7816-4 section 8 - Historical bytes, - * but used by Yubico, which should have all - * the needed capabilities*/ - if (hist_bytes_len >= 7 && - memcmp(hist_bytes, "Yubikey", 7) == 0) { - card->caps |= SC_CARD_CAP_APDU_EXT; - priv->ext_caps |= EXT_CAP_APDU_EXT - | EXT_CAP_CHAINING; - } } } From bc17e23bd6c77d1884c0ab827760b65ce5b81b86 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 22 Dec 2018 21:25:38 +0100 Subject: [PATCH 0689/4321] OpenPGP: fix spec interpretation error in hist_byte parsing Command chaining is available with OpenPGP card spec 1.1+, not only with 3.0+ --- src/libopensc/card-openpgp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3470f70783..30f5e730b1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -633,8 +633,7 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) priv->ext_caps |= EXT_CAP_APDU_EXT; } /* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */ - if ((ptr[2] & 0x80) && - (priv->bcd_version >= OPENPGP_CARD_3_0)) { + if (ptr[2] & 0x80) { priv->ext_caps |= EXT_CAP_CHAINING; } } From 1a60cd761f5dfa4bbfb0aa8ffc8a4c8a1cd01a97 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 22 Dec 2018 22:27:49 +0100 Subject: [PATCH 0690/4321] OpenPGP: fix value for EXT_CAP_MSE enum _ext_caps is a set of bit flags --- src/libopensc/card-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 30f5e730b1..fd8e85d043 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -123,7 +123,7 @@ enum _access { /* access flags for the respective DO/file */ WRITE_MASK = 0x1F00 }; -enum _ext_caps { /* extended capabilities/features */ +enum _ext_caps { /* extended capabilities/features: bit flags */ EXT_CAP_ALG_ATTR_CHANGEABLE = 0x0004, EXT_CAP_PRIVATE_DO = 0x0008, EXT_CAP_C4_CHANGEABLE = 0x0010, @@ -133,7 +133,7 @@ enum _ext_caps { /* extended capabilities/features */ EXT_CAP_LCS = 0x0100, EXT_CAP_CHAINING = 0x1000, EXT_CAP_APDU_EXT = 0x2000, - EXT_CAP_MSE = 0x3000 + EXT_CAP_MSE = 0x4000 }; enum _card_state { From 391131bb5e4ae91aed9d353d6604aaf3ef7d24e8 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 22 Dec 2018 23:01:10 +0100 Subject: [PATCH 0691/4321] OpenPGP: use "hist_bytes" DO 5F52 as args to pgp_parse_hist_bytes() Fix glitch that crept in during re-factoring. This should unbreak Yubikeys. --- src/libopensc/card-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fd8e85d043..603386c6ce 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -720,8 +720,8 @@ pgp_get_card_features(sc_card_t *card) if ((pgp_get_blob(card, priv->mf, 0x5f52, &blob) >= 0) && (blob->data != NULL) && (blob->data[0] == 0x00)) { - if (hist_bytes_len > 4) { - pgp_parse_hist_bytes(card, hist_bytes+1, hist_bytes_len-4); + if (blob->len > 4) { + pgp_parse_hist_bytes(card, blob->data+1, blob->len-4); } /* get card status from historical bytes status indicator */ From aa7118192ae967bb31b31c2adf9c6695b4860c7c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Dec 2018 11:50:49 +0100 Subject: [PATCH 0692/4321] p11test: Use function compatible with OpenSSL 1.0.2 --- src/tests/p11test/p11test_case_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 650bac8154..48206b1ff1 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -371,7 +371,7 @@ int callback_public_keys(test_certs_t *objects, o->key.ec = EC_KEY_new_by_curve_name(nid); EC_KEY_set_public_key(o->key.ec, ecpoint); EC_KEY_set_group(o->key.ec, ecgroup); - o->bits = EC_GROUP_order_bits(ecgroup); + o->bits = EC_GROUP_get_degree(ecgroup); } } else { debug_print(" [WARN %s ] non-RSA, non-EC key. Key type: %02lX", From 0a903522b81ff54057d53f2bbe0abfaadbd689bd Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 17:51:12 +0100 Subject: [PATCH 0693/4321] OpenPGP: get rid of "magic" constants in pgp_build_extended_header_list() Use defined symbolic names for well-known DOs to copy data to a correctly defined buffer 'data' using ulong2bebytes() instead of relying on "magic" constants. --- src/libopensc/card-openpgp.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 603386c6ce..b8b6b28fd4 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2819,21 +2819,20 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory."); switch (key_info->key_id) { - case SC_OPENPGP_KEY_SIGN: - data[0] = 0xB6; - break; - case SC_OPENPGP_KEY_ENCR: - data[0] = 0xB8; - break; - case SC_OPENPGP_KEY_AUTH: - data[0] = 0xA4; - break; - default: - sc_log(ctx, "Unknown key type %d.", key_info->key_id); - r = SC_ERROR_INVALID_ARGUMENTS; - goto err; + case SC_OPENPGP_KEY_SIGN: + ushort2bebytes(data, DO_SIGN); + break; + case SC_OPENPGP_KEY_ENCR: + ushort2bebytes(data, DO_ENCR); + break; + case SC_OPENPGP_KEY_AUTH: + ushort2bebytes(data, DO_AUTH); + break; + default: + sc_log(ctx, "Unknown key id %d.", key_info->key_id); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key id"); } - memcpy(data + 2, tlv_7f48, tlvlen_7f48); + memcpy(data + 2, tlv_7f48, tlvlen_7f48); memcpy(data + 2 + tlvlen_7f48, tlv_5f48, tlvlen_5f48); r = pgp_build_tlv(ctx, 0x4D, data, len, &tlvblock, &tlvlen); LOG_TEST_GOTO_ERR(ctx, r, "Cannot build TLV for Extended Header list"); From 4c51a53beda9ee6bef42a27642f1986765f92794 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 17:58:06 +0100 Subject: [PATCH 0694/4321] OpenPGP: get rid of "magic" constants in gnuk_delete_key() Use defined symbolic names for well-known DOs to copy data to a correctly defined buffer 'data' using ulong2bebytes() instead of relying on "magic" constants and C's string semantic. Also use 'sizeof(data)' instead of strange strlen() calculations. --- src/libopensc/card-openpgp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b8b6b28fd4..7af55ab40e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3066,7 +3066,7 @@ gnuk_delete_key(sc_card_t *card, u8 key_id) { sc_context_t *ctx = card->ctx; int r = SC_SUCCESS; - char *data = NULL; + u8 data[4] = { 0x4D, 0x02, 0x00, 0x00 }; LOG_FUNC_CALLED(ctx); @@ -3087,14 +3087,14 @@ gnuk_delete_key(sc_card_t *card, u8 key_id) /* rewrite Extended Header List */ sc_log(ctx, "Rewrite Extended Header List"); - if (key_id == 1) - data = "\x4D\x02\xB6"; - else if (key_id == 2) - data = "\x4D\x02\xB8"; - else if (key_id == 3) - data = "\x4D\x02\xA4"; + if (key_id == SC_OPENPGP_KEY_SIGN) + ushort2bebytes(data+2, DO_SIGN); + else if (key_id == SC_OPENPGP_KEY_ENCR) + ushort2bebytes(data+2, DO_ENCR); + else if (key_id == SC_OPENPGP_KEY_AUTH) + ushort2bebytes(data+2, DO_AUTH); - r = pgp_put_data(card, 0x4D, (const u8 *)data, strlen((const char *)data) + 1); + r = pgp_put_data(card, 0x4D, data, sizeof(data)); LOG_FUNC_RETURN(ctx, r); } From 7092d32830d7b9074217b4d49f0c3aa33c17fb16 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 18:09:49 +0100 Subject: [PATCH 0695/4321] OpenPGP: get rid of "magic" constants in pgp_gen_key() Use defined symbolic names for well-known DOs to copy data to a correctly defined buffer 'apdu_data' using ulong2bebytes() instead of relying on "magic" constants and C's string semantic. Also use 'sizeof(apdu_data)' instead of additional magic constants. --- src/libopensc/card-openpgp.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7af55ab40e..6f821fbb1b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2530,7 +2530,7 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) sc_apdu_t apdu; /* temporary variables to hold APDU params */ u8 apdu_case; - u8 *apdu_data; + u8 apdu_data[2] = { 0x00, 0x00 }; size_t apdu_le; size_t resplen = 0; int r = SC_SUCCESS; @@ -2541,18 +2541,15 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - /* FIXME the compilers don't assure that the buffers set here as - * apdu_data are present until the end of the function */ /* set Control Reference Template for key */ if (key_info->key_id == SC_OPENPGP_KEY_SIGN) - apdu_data = (unsigned char *) "\xb6"; - /* as a string, apdu_data will end with '\0' (B6 00) */ + ushort2bebytes(apdu_data, DO_SIGN); else if (key_info->key_id == SC_OPENPGP_KEY_ENCR) - apdu_data = (unsigned char *) "\xb8"; + ushort2bebytes(apdu_data, DO_ENCR); else if (key_info->key_id == SC_OPENPGP_KEY_AUTH) - apdu_data = (unsigned char *) "\xa4"; + ushort2bebytes(apdu_data, DO_AUTH); else { - sc_log(card->ctx, "Unknown key type %X.", key_info->key_id); + sc_log(card->ctx, "Unknown key id %X.", key_info->key_id); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2588,8 +2585,8 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) /* prepare APDU */ sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x80, 0); apdu.data = apdu_data; - apdu.datalen = 2; /* Data = B600 */ - apdu.lc = 2; + apdu.datalen = sizeof(apdu_data); + apdu.lc = sizeof(apdu_data); apdu.le = apdu_le; /* buffer to receive response */ From d577802ea7b938a9612c1512337a304f246d4164 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 27 Oct 2018 17:31:54 +0200 Subject: [PATCH 0696/4321] OpenPGP: emulate SC_PIN_CMD_GET_INFO command for cards not supporting it --- src/libopensc/card-openpgp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 6f821fbb1b..821b13a7ff 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1882,6 +1882,28 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "key-id should be 1, 2, 3."); } + + /* emulate SC_PIN_CMD_GET_INFO command for cards not supporting it */ + if (data->cmd == SC_PIN_CMD_GET_INFO && (card->caps & SC_CARD_CAP_ISO7816_PIN_INFO) == 0) { + u8 c4data[10]; + int r; + + r = sc_get_data(card, 0x00c4, c4data, sizeof(c4data)); + LOG_TEST_RET(card->ctx, r, "reading CHV status bytes failed"); + + if (r != 7) + LOG_TEST_RET(card->ctx, SC_ERROR_OBJECT_NOT_VALID, + "CHV status bytes have unexpected length"); + + data->pin1.tries_left = c4data[4 + (data->pin_reference & 0x0F)]; + data->pin1.max_tries = 3; + data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; + if (tries_left != NULL) + *tries_left = data->pin1.tries_left; + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); } From a6ee84f13d24818ec57ed28bc4d394234478cc00 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 12:33:16 +0100 Subject: [PATCH 0697/4321] opensc-explorer: fix 'pin_info' command Correctly treat 'data.pin1.logged_in' as tristate instead of boolean. While at it, fix visual glitch to not wrap around a stand-alone period. --- src/tools/opensc-explorer.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 681695435f..28c510a64b 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1147,11 +1147,19 @@ static int do_pininfo(int argc, char **argv) fprintf(stderr, "Unable to get PIN info: %s\n", sc_strerror(r)); return -1; } - if (tries_left > 0) - printf("Logged %s, %d tries left.\n", - (data.pin1.logged_in) ? "in" : "out", tries_left); - else - printf("Logged %s\n.", (data.pin1.logged_in) ? "in" : "out"); + switch (data.pin1.logged_in) { + case SC_PIN_STATE_LOGGED_IN: + printf("Logged in.\n"); + break; + case SC_PIN_STATE_LOGGED_OUT: + printf("Logged out.\n"); + break; + case SC_PIN_STATE_UNKNOWN: + default: + printf("Login status unkwown.\n"); + } + if (tries_left >= 0) + printf("%d tries left.\n", tries_left); return 0; } From 6f0f42c5068f951a21274a26f8abc0b9326ea245 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Dec 2018 16:49:16 +0100 Subject: [PATCH 0698/4321] fixed use of uninitialized data When card->sm_ctx.ops.free_sm_apdu gets called in sc_sm_single_transmit with a prior transmission error, then `sm_encrypt` still tries to decrypt the response and hence, accesses the previously uninitialized `resp`. --- src/sm/sm-iso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index b9c14569f5..299e87815d 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -491,7 +491,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sm_apdu->resplen = SC_MAX_APDU_BUFFER_SIZE; #endif } - resp_data = malloc(sm_apdu->resplen); + resp_data = calloc(sm_apdu->resplen); if (!resp_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; From aa940e8619d01e491b92171c427520d30a89b46d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Dec 2018 21:25:52 +0100 Subject: [PATCH 0699/4321] iso-sm: avoid allocation of big chunk of data Use unencrypted APDU's resplen to estimate the size of the required SM response buffer --- src/sm/sm-iso.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 299e87815d..1ec0818a9c 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -279,7 +279,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, u8 *p, *le = NULL, *sm_data = NULL, *fdata = NULL, *mac_data = NULL, *asn1 = NULL, *mac = NULL, *resp_data = NULL; size_t sm_data_len, fdata_len, mac_data_len, asn1_len, mac_len, le_len; - int r, cse; + int r; sc_apdu_t *sm_apdu = NULL; if (!apdu || !ctx || !card || !card->reader || !psm_apdu) { @@ -313,17 +313,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, } mac_data_len = r; - /* get le and data depending on the case of the insecure command */ - cse = apdu->cse; - if ((apdu->le/ctx->block_length + 1)*ctx->block_length + 18 > 0xff+1) - /* for encrypted APDUs we usually get authenticated status bytes (4B), - * a MAC (11B) and a cryptogram with padding indicator (3B without - * data). The cryptogram is always padded to the block size. */ - /*cse |= SC_APDU_EXT;*/ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Response data may be truncated, because it doesn't fit into a short length APDU."); - - switch (cse) { + switch (apdu->cse) { case SC_APDU_CASE_1: break; case SC_APDU_CASE_2_SHORT: @@ -476,22 +466,17 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, sm_apdu->datalen = sm_data_len; sm_apdu->lc = sm_data_len; sm_apdu->le = 0; - if (cse & SC_APDU_EXT) { + if (apdu->cse & SC_APDU_EXT) { sm_apdu->cse = SC_APDU_CASE_4_EXT; -#if OPENSC_NOT_BOGUS_ANYMORE - sm_apdu->resplen = 0xffff+1; -#else - sm_apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE; -#endif } else { sm_apdu->cse = SC_APDU_CASE_4_SHORT; -#if OPENSC_NOT_BOGUS_ANYMORE - sm_apdu->resplen = 0xff+1; -#else - sm_apdu->resplen = SC_MAX_APDU_BUFFER_SIZE; -#endif } - resp_data = calloc(sm_apdu->resplen); + /* for encrypted APDUs we usually get authenticated status bytes + * (4B), a MAC (2B without data) and a cryptogram with padding + * indicator (3B without data). The cryptogram is always padded to + * the block size. */ + sm_apdu->resplen = 9 + mac_len + (apdu->resplen/ctx->block_length + 1)*ctx->block_length; + resp_data = calloc(sm_apdu->resplen, 1); if (!resp_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; From 5c50dc58dabd08e912dd0bf3eba2d54d2cb8e758 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 Jan 2019 00:34:32 +0100 Subject: [PATCH 0700/4321] fixed 320270 Dereference after null check --- src/pkcs11/framework-pkcs15.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 6b9f0a5348..10141c46d4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1094,7 +1094,8 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, /* Trim tokeninfo->label to make right parenthesis visible */ char tokeninfo_label[sizeof(p15card->tokeninfo->label)+1]; int len; - snprintf(tokeninfo_label, sizeof(tokeninfo_label), "%s", p15card->tokeninfo->label); + snprintf(tokeninfo_label, sizeof(tokeninfo_label), "%s", + p15card->tokeninfo ? p15card->tokeninfo->label : ""); tokeninfo_label[sizeof(tokeninfo_label)-1] = '\0'; for (len = strlen(tokeninfo_label) - 1; len >= 0 && isspace(tokeninfo_label[len]); len--) { tokeninfo_label[len] = 0; @@ -1104,12 +1105,14 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, tokeninfo_label); } else /* The PIN label is empty or says just non-useful "PIN" */ - snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label); + snprintf(label, sizeof(label), "%s", + p15card->tokeninfo ? p15card->tokeninfo->label : ""); slot->token_info.flags |= CKF_LOGIN_REQUIRED; } } else { - snprintf(label, sizeof(label), "%s", p15card->tokeninfo->label); + snprintf(label, sizeof(label), "%s", + p15card->tokeninfo ? p15card->tokeninfo->label : ""); } strcpy_bp(slot->token_info.label, label, 32); From ee9abfcc71b81201f34ae07c4c5b12965ba34004 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 16 Oct 2018 15:39:21 +0200 Subject: [PATCH 0701/4321] Appveyor: use deploy_script --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index ee5ad25d71..e8b3df9a0a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -95,13 +95,15 @@ build_script: - nmake /f Makefile.mak %NMAKE_EXTRA% - cd win32 && nmake /f Makefile.mak %NMAKE_EXTRA% VSVER=%VSVER% OpenSC.msi && cd .. - move win32\OpenSC.msi %ARTIFACT%.msi - - appveyor PushArtifact %ARTIFACT%.msi # put all pdb files for dump analysis, but this consumes approx 100 MB per build - md %ARTIFACT%-Debug - ps: >- Get-ChildItem -recurse C:\projects\OpenSC -exclude vc*.pdb *.pdb | % { 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName } + +deploy_script: + - appveyor PushArtifact %ARTIFACT%.msi - appveyor PushArtifact %ARTIFACT%-Debug.zip # keep in sync with .travis.yml From b95d936e6cf960984dfcb5c6d1ead58b32e64f55 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 17 Nov 2018 13:41:24 +0100 Subject: [PATCH 0702/4321] OpenPGP: allow reading large DOs in v3 cards Set the read buffer size in pgp_read_blob() large enough to contain DOs with the maximum size defineable in the extended capabilities DO 00C0. --- src/libopensc/card-openpgp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 821b13a7ff..92631b2daa 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -222,6 +222,12 @@ static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, /* Gnuk only supports 1 key length (2048 bit) */ #define MAXLEN_RESP_PUBKEY_GNUK 271 +/* Maximal size of a DO: + * v2.0+: max. certificate size it at bytes 5-6 of Extended Capabilities DO 00C0 + * v3.0+: max. special DO size is at bytes 7-8 of Extended Capabilities DO 00C0 + * Theoretically we should have the 64k, but we currently limit to 8k. */ +#define MAX_OPENPGP_DO_SIZE 8192 + static struct do_info pgp1x_objects[] = { /* OpenPGP card spec 1.1 */ { 0x004f, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, { 0x005b, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, @@ -1089,7 +1095,7 @@ pgp_read_blob(sc_card_t *card, pgp_blob_t *blob) return blob->status; if (blob->info->get_fn) { /* readable, top-level DO */ - u8 buffer[2048]; + u8 buffer[MAX_OPENPGP_DO_SIZE]; size_t buf_len = sizeof(buffer); int r = SC_SUCCESS; From 5544418339283c12c80307e25747f7909732295c Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 18:42:51 +0100 Subject: [PATCH 0703/4321] OpenPGP: harmonize error messages used in LOG_TEST...() calls Don't terminate the messages with a period, because they are going to end up as the first argument to a format string of the form "%s: ...". I.e. they will be part of a longer string and terminated by a colon anyway. --- src/libopensc/card-openpgp.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 92631b2daa..aad79faba9 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1861,7 +1861,7 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->pin1.len == 0 && !(data->flags & SC_PIN_CMD_USE_PINPAD)) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, - "v2 cards don't support implicit old PIN for PIN change."); + "v2 cards don't support implicit old PIN for PIN change"); data->flags &= ~SC_PIN_CMD_IMPLICIT_CHANGE; } @@ -1881,12 +1881,12 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->cmd == SC_PIN_CMD_UNBLOCK && data->pin2.len == 0 && !(data->flags & SC_PIN_CMD_USE_PINPAD)) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, - "new PIN must be provided for unblock operation."); + "new PIN must be provided for unblock operation"); /* ensure pin_reference is 81, 82, 83 */ if (!(data->pin_reference == 0x81 || data->pin_reference == 0x82 || data->pin_reference == 0x83)) { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, - "key-id should be 1, 2, 3."); + "key-id should be 1, 2, 3"); } /* emulate SC_PIN_CMD_GET_INFO command for cards not supporting it */ @@ -2362,7 +2362,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* store to DO */ sc_log(card->ctx, "Writing to DO %04X.", tag); r = pgp_put_data(card, tag, fingerprint, SHA_DIGEST_LENGTH); - LOG_TEST_RET(card->ctx, r, "Cannot write to DO."); + LOG_TEST_RET(card->ctx, r, "Cannot write to DO"); /* update the blob containing fingerprints (00C5) */ sc_log(card->ctx, "Updating fingerprint blob 00C5."); @@ -2421,7 +2421,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, sc_log(card->ctx, "Retrieving blob %04X.", blob_id); r = pgp_get_blob(card, priv->mf, blob_id, &pk_blob); - LOG_TEST_RET(card->ctx, r, "Cannot get the blob."); + LOG_TEST_RET(card->ctx, r, "Cannot get the blob"); /* encode pubkey */ memset(&pubkey, 0, sizeof(pubkey)); @@ -2432,11 +2432,11 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, pubkey.u.rsa.exponent.len = exponent_len >> 3; r = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &data, &len); - LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey."); + LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); sc_log(card->ctx, "Updating blob %04X's content.", blob_id); r = pgp_set_blob(pk_blob, data, len); - LOG_TEST_RET(card->ctx, r, "Cannot update blob content."); + LOG_TEST_RET(card->ctx, r, "Cannot update blob content"); LOG_FUNC_RETURN(card->ctx, r); } @@ -2471,7 +2471,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, &cla, &tag, &len); if (part == NULL) r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; - LOG_TEST_RET(card->ctx, r, "Unexpected end of contents."); + LOG_TEST_RET(card->ctx, r, "Unexpected end of contents"); /* undo ASN1's split of tag & class */ for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { cla <<= 8; @@ -2507,7 +2507,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); r = pgp_calculate_and_store_fingerprint(card, ctime, modulus, exponent, key_info); - LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint."); + LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, modulus, key_info->rsa.modulus_len, @@ -2831,7 +2831,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info /* TLV block for 7F48 */ r = pgp_build_tlv(ctx, 0x7F48, pritemplate, tpl_len, &tlv_7f48, &tlvlen_7f48); - LOG_TEST_RET(ctx, r, "Failed to build TLV for 7F48."); + LOG_TEST_RET(ctx, r, "Failed to build TLV for 7F48"); tlv_7f48[0] |= 0x7F; r = pgp_build_tlv(ctx, 0x5f48, kdata, kdata_len, &tlv_5f48, &tlvlen_5f48); LOG_TEST_GOTO_ERR(ctx, r, "Failed to build TLV for 5F48"); @@ -2841,7 +2841,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info /* set data part content */ data = calloc(len, 1); if (data == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory."); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory"); switch (key_info->key_id) { case SC_OPENPGP_KEY_SIGN: @@ -2950,7 +2950,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) sc_log(card->ctx, "Calculate and store fingerprint"); r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, key_info->rsa.n, key_info->rsa.e, &pubkey); - LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint."); + LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, key_info->rsa.n, 8*key_info->rsa.n_len, @@ -3140,7 +3140,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path) /* sc_pkcs15init_delete_by_path() sets the path type to SC_PATH_TYPE_FILE_ID */ r = pgp_select_file(card, path, &file); - LOG_TEST_RET(card->ctx, r, "Cannot select file."); + LOG_TEST_RET(card->ctx, r, "Cannot select file"); /* save "current" blob */ blob = priv->current; From 57e66fd42e7c49c3230c2628478f2060317d8730 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 19:02:03 +0100 Subject: [PATCH 0704/4321] OpenPGP: harmonize error messages Combine sequences sc_log(..., "..."); LOG_FUNC_RETURN(...); where c_log() prints a constant string by LOG_TEST_RET(..., "..."); This change results in shorter, more concise code as well as better harmonized error messages. --- src/libopensc/card-openpgp.c | 38 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index aad79faba9..fc158ad734 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2318,10 +2318,10 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - if (modulus == NULL || exponent == NULL || mlen == 0 || elen == 0) { - sc_log(card->ctx, "Null data (modulus or exponent)"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } + if (modulus == NULL || mlen == 0) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Modulus missing"); + if (exponent == NULL || elen == 0) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Exponent missing"); /* http://tools.ietf.org/html/rfc4880 page 41, 72 */ pk_packet_len = 1 /* version number */ @@ -2581,10 +2581,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->rsa.modulus_len != 2048) { - sc_log(card->ctx, "Gnuk does not support other key length than 2048."); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } + if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->rsa.modulus_len != 2048) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "Gnuk only supports generating keys up to 2048-bit"); /* set attributes for new-generated key */ r = pgp_update_new_algo_attr(card, key_info); @@ -2775,20 +2774,18 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info comp_to_add = 4; /* validate */ - if (comp_to_add == 4 && (key_info->rsa.n == NULL || key_info->rsa.n_len == 0)){ - sc_log(ctx, "Error: Modulus required!"); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - } + if (comp_to_add == 4 && (key_info->rsa.n == NULL || key_info->rsa.n_len == 0)) + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Modulus required"); /* Cardholder private key template's data part */ memset(pritemplate, 0, max_prtem_len); /* get required exponent length */ alat_blob = pgp_find_blob(card, 0x00C0 | key_info->key_id); - if (!alat_blob) { - sc_log(ctx, "Cannot read Algorithm Attributes."); - LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND); - } + if (alat_blob == NULL) + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, + "Cannot read Algorithm Attributes"); + req_e_len = bebytes2ushort(alat_blob->data + 3) >> 3; /* 1/8 */ assert(key_info->rsa.e_len <= req_e_len); @@ -2797,7 +2794,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info if (key_info->rsa.e_len < req_e_len) { /* create new buffer */ p = calloc(req_e_len, 1); - if (!p) + if (p == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); memcpy(p + req_e_len - key_info->rsa.e_len, key_info->rsa.e, key_info->rsa.e_len); key_info->rsa.e_len = req_e_len; @@ -3018,10 +3015,9 @@ pgp_erase_card(sc_card_t *card) /* build APDU from binary array */ r = sc_bytes2apdu(card->ctx, apdu_bin, apdu_bin_len, &apdu); - if (r) { - sc_log(card->ctx, "Failed to build APDU"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - } + if (r) + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, + "Failed to build APDU"); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); From bb6b78937f1b88f753117e8fd4971545123f9fac Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Tue, 1 Jan 2019 19:22:29 +0100 Subject: [PATCH 0705/4321] OpenPGP: harmonize error messages around 'key_id' * consistently use term "Invalid key ID; must be 1, 2, or 3" in error messages about invalid key IDs instead of various alternatives. * use error type SC_ERROR_INVALID_ARGUMENTS instead of SC_ERROR_INVALID_DATA when the key_id was passed to the respective function * harmonize the checks to consistently use 'key_id < ... || key_id > ...' In addition, initialize a variable to keep clang & compilers on OSX happy. --- src/libopensc/card-openpgp.c | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fc158ad734..956605adcd 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1884,10 +1884,9 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) "new PIN must be provided for unblock operation"); /* ensure pin_reference is 81, 82, 83 */ - if (!(data->pin_reference == 0x81 || data->pin_reference == 0x82 || data->pin_reference == 0x83)) { + if (data->pin_reference < 0x81 || data->pin_reference > 0x83) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, - "key-id should be 1, 2, 3"); - } + "Invalid key ID; must be 1, 2, or 3"); /* emulate SC_PIN_CMD_GET_INFO command for cards not supporting it */ if (data->cmd == SC_PIN_CMD_GET_INFO && (card->caps & SC_CARD_CAP_ISO7816_PIN_INFO) == 0) { @@ -2268,10 +2267,10 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) u8 buf[4]; LOG_FUNC_CALLED(card->ctx); - if (key_id == 0 || key_id > 3) { - sc_log(card->ctx, "Invalid key ID %d.", key_id); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); - } + + if (key_id < 1 || key_id > 3) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); if (outtime != NULL && *outtime != 0) createtime = *outtime; @@ -2400,7 +2399,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *pk_blob; - unsigned int blob_id; + unsigned int blob_id = 0; sc_pkcs15_pubkey_t pubkey; u8 *data = NULL; size_t len; @@ -2415,8 +2414,8 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, else if (key_id == SC_OPENPGP_KEY_AUTH) blob_id = DO_AUTH_SYM; else { - sc_log(card->ctx, "Unknown key id %X.", key_id); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); } sc_log(card->ctx, "Retrieving blob %04X.", blob_id); @@ -2577,8 +2576,8 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) else if (key_info->key_id == SC_OPENPGP_KEY_AUTH) ushort2bebytes(apdu_data, DO_AUTH); else { - sc_log(card->ctx, "Unknown key id %X.", key_info->key_id); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); } if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->rsa.modulus_len != 2048) @@ -2851,8 +2850,8 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info ushort2bebytes(data, DO_AUTH); break; default: - sc_log(ctx, "Unknown key id %d.", key_info->key_id); - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key id"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); } memcpy(data + 2, tlv_7f48, tlvlen_7f48); memcpy(data + 2 + tlvlen_7f48, tlv_5f48, tlvlen_5f48); @@ -2893,10 +2892,10 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* Validate */ - if (key_info->key_id < 1 || key_info->key_id > 3) { - sc_log(card->ctx, "Unknown key type %d.", key_info->key_id); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } + if (key_info->key_id < 1 || key_info->key_id > 3) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); + /* we just support standard key format */ switch (key_info->rsa.keyformat) { case SC_OPENPGP_KEYFORMAT_RSA_STD: @@ -3091,10 +3090,9 @@ gnuk_delete_key(sc_card_t *card, u8 key_id) LOG_FUNC_CALLED(ctx); - if (key_id < 1 || key_id > 3) { - sc_log(ctx, "Key ID %d is invalid. Should be 1, 2 or 3.", key_id); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - } + if (key_id < 1 || key_id > 3) + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, + "Invalid key ID; must be 1, 2, or 3"); /* delete fingerprint */ sc_log(ctx, "Delete fingerprints"); From f453c412b6dea081d55b1e0ca9608802bbe8c034 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 2 Jan 2019 10:39:51 +0100 Subject: [PATCH 0706/4321] Simulate and test Open Source Java Card Applets Compiles jCardSim, IsoApplet, GidsApplet, ykneo-openpgp, PivApplet as described [here](https://github.com/OpenSC/OpenSC/wiki/Smart-Card-Simulation). Thanks to https://github.com/arekinath/jcardsim/ this is now also possible on Linux in combination with https://github.com/frankmorgner/vsmartcard. Travis-CI now also runs some basic personalization and PKCS#11-tests. This commit also adds caching of apt, brew and maven packages as well as the OpenSSL/OpenPACE build on macOS --- .travis.yml | 117 ++++++++++++++++++++++++++++++++++++++-- MacOSX/build-package.in | 4 +- 2 files changed, 114 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index df6d6d0d5f..53949f992b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,9 @@ addons: - xsltproc - gengetopt - libcmocka-dev + - help2man + - pcscd + - check env: global: @@ -41,7 +44,8 @@ matrix: env: ENABLE_DOC=--enable-doc - compiler: gcc os: linux - env: ENABLE_DOC=--enable-doc + env: DO_SIMULATION=yes + sudo: true - os: linux env: - HOST=x86_64-w64-mingw32 @@ -58,7 +62,8 @@ before_install: brew update; brew uninstall libtool; brew install libtool; - brew install gengetopt help2man cmocka; + brew install gengetopt help2man cmocka ccache; + export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi before_script: @@ -69,7 +74,7 @@ before_script: if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16; export DISPLAY=:99.0; - wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe; + [ -f isetup-5.5.6.exe ] || wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe; wine isetup-5.5.6.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART; fi; unset CC; @@ -80,12 +85,65 @@ before_script: # On error (propably quota is exhausted), just continue - if [ "${DO_COVERITY_SCAN}" = "yes" ]; then curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash || true; fi + - if [ "${DO_SIMULATION}" = "yes" ]; then + git clone https://github.com/frankmorgner/vsmartcard.git; + cd vsmartcard/virtualsmartcard; + autoreconf -vis && ./configure && sudo make install; + cd $TRAVIS_BUILD_DIR; + sudo /etc/init.d/pcscd restart; + + git clone https://github.com/martinpaljak/oracle_javacard_sdks.git; + export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit; + export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit; + + git clone https://github.com/arekinath/jcardsim.git; + cd jcardsim; + mvn initialize && mvn clean install; + cd $TRAVIS_BUILD_DIR; + + git clone https://github.com/philipWendland/IsoApplet.git; + javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java; + echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg; + echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg; + echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; + + git clone https://github.com/vletoux/GidsApplet.git; + javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar GidsApplet/src/com/mysmartlogon/gidsApplet/*.java; + echo "com.licel.jcardsim.card.applet.0.AID=A000000397425446590201" > gids_jcardsim.cfg; + echo "com.licel.jcardsim.card.applet.0.Class=com.mysmartlogon.gidsApplet.GidsApplet" >> gids_jcardsim.cfg; + echo "com.licel.jcardsim.card.ATR=3B80800101" >> gids_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.host=localhost" >> gids_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg; + + git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; + cd ykneo-openpgp; + ant -DJAVACARD_HOME=${JC_HOME}; + cd $TRAVIS_BUILD_DIR; + echo "com.licel.jcardsim.card.applet.0.AID=D2760001240102000000000000010000" > openpgp_jcardsim.cfg; + echo "com.licel.jcardsim.card.applet.0.Class=openpgpcard.OpenPGPApplet" >> openpgp_jcardsim.cfg; + echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.host=localhost" >> openpgp_jcardsim.cfg; + echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg; + + git clone --recursive https://github.com/arekinath/PivApplet.git; + cd PivApplet; + ant dist; + cd $TRAVIS_BUILD_DIR; + + git clone https://github.com/Yubico/yubico-piv-tool.git; + cd yubico-piv-tool; + autoreconf -vis && ./configure && sudo make install; + cd $TRAVIS_BUILD_DIR; + fi + script: - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then if [ $TRAVIS_OS_NAME == osx ]; then ./MacOSX/build; else - make; + make -j 4; fi; fi - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then @@ -96,6 +154,43 @@ script: wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss; fi + - if [ "${DO_SIMULATION}" = "yes" ]; then + set -ex; + sudo make install; + export LD_LIBRARY_PATH=/usr/local/lib; + + java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & + sleep 5; + opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100; + opensc-tool -n; + killall java; + + java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null & + sleep 5; + opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100; + opensc-tool -n; + gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; + killall java; + + java -noverify -cp ykneo-openpgp/applet/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard openpgp_jcardsim.cfg >/dev/null & + sleep 5; + opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; + opensc-tool -n; + pkcs11-tool -l -t -p 123456; + killall java; + + java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard PivApplet/test/jcardsim.cfg >/dev/null & + sleep 5; + opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f; + opensc-tool -n; + yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate > pubkey-9e.pem; + yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a selfsign-certificate -S '/CN=test' < pubkey-9e.pem > cert-9e.pem; + yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a import-certificate < cert-9e.pem; + pkcs11-tool -l -t -p 123456; + killall java; + set +ex; + fi + after_script: # kill process started during compilation to finish the build, see # https://github.com/moodlerooms/moodle-plugin-ci/issues/33 for details @@ -110,4 +205,16 @@ after_script: .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; fi -cache: ccache +cache: + apt: true + ccache: true + directories: + - $HOME/.m2/ + - $HOME/Library/Caches/Homebrew + - openssl_bin + - openpace_bin + files: + - isetup-5.5.6.exe + +before_cache: + - brew cleanup diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 8a43843c68..5f9af2f94f 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -35,7 +35,7 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then make clean make update make depend - make + make -j 4 make INSTALL_PREFIX=$BUILDPATH/openssl_bin install_sw cd .. fi @@ -73,7 +73,7 @@ if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then make clean # compile - make -j 2 + make -j 4 # copy files rm -rf ${BUILDPATH}/target From d9e253bd1b06f2dc5461c19386696164a74fc98d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 6 Jan 2019 00:04:23 +0100 Subject: [PATCH 0707/4321] reduce the number of builds a single build of clang and gcc each is enough --- .travis.yml | 79 ++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53949f992b..f1f36a8c9f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,38 @@ language: c +matrix: + include: + - compiler: clang + os: osx + env: DO_PUSH_ARTIFACT=yes + - compiler: gcc + os: linux + env: + - DO_SIMULATION=yes + - ENABLE_DOC=--enable-doc + sudo: true + - env: + - HOST=x86_64-w64-mingw32 + - DO_PUSH_ARTIFACT=yes + - env: + - HOST=i686-w64-mingw32 + - DO_PUSH_ARTIFACT=yes + - env: DO_COVERITY_SCAN=yes + +env: + global: + # The next declaration are encrypted envirnmet variables, created via the + # "travis encrypt" command using the project repo's public key + # COVERITY_SCAN_TOKEN + - secure: "UkHn7wy4im8V1nebCWbAetnDSOLRUbOlF6++ovk/7Bnso1/lnhXHelyzgRxfD/oI68wm9nnRV+RQEZ9+72Ug1CyvHxyyxxkwal/tPeHH4B/L+aGdPi0id+5OZSKIm77VP3m5s102sJMJgH7DFd03+nUd0K26p0tk8ad4j1geV4c=" + # GH_TOKEN + - secure: "cUAvpN/XUPMIN5cgWAbIOhghRoLXyw7SCydzGaJ1Ucqb9Ml2v5iuLLuN57YbZHTiWw03vy6rYVzzwMDrHX8r3oUALsv7ViJHG4PzIe7fAFZsZpHECmGsp6SEnue7m7BNy3FT8KYbiXxnxDO0SxmFXlrPAYR0WMZCWx2TENYcafs=" + - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity.*)" + - COVERITY_SCAN_NOTIFICATION_EMAIL="viktor.tarasov@gmail.com" + - COVERITY_SCAN_BUILD_COMMAND="make -j 4" + - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" + - SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) + addons: apt_packages: - binutils-mingw-w64-i686 @@ -17,46 +50,6 @@ addons: - pcscd - check -env: - global: - # The next declaration are encrypted envirnmet variables, created via the - # "travis encrypt" command using the project repo's public key - # COVERITY_SCAN_TOKEN - - secure: "UkHn7wy4im8V1nebCWbAetnDSOLRUbOlF6++ovk/7Bnso1/lnhXHelyzgRxfD/oI68wm9nnRV+RQEZ9+72Ug1CyvHxyyxxkwal/tPeHH4B/L+aGdPi0id+5OZSKIm77VP3m5s102sJMJgH7DFd03+nUd0K26p0tk8ad4j1geV4c=" - # GH_TOKEN - - secure: "cUAvpN/XUPMIN5cgWAbIOhghRoLXyw7SCydzGaJ1Ucqb9Ml2v5iuLLuN57YbZHTiWw03vy6rYVzzwMDrHX8r3oUALsv7ViJHG4PzIe7fAFZsZpHECmGsp6SEnue7m7BNy3FT8KYbiXxnxDO0SxmFXlrPAYR0WMZCWx2TENYcafs=" - - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity.*)" - - COVERITY_SCAN_NOTIFICATION_EMAIL="viktor.tarasov@gmail.com" - - COVERITY_SCAN_BUILD_COMMAND="make -j 4" - - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" - - SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) - -matrix: - fast_finish: true - include: - - compiler: clang - os: osx - env: DO_PUSH_ARTIFACT=yes - - compiler: gcc - os: osx - - compiler: clang - os: linux - env: ENABLE_DOC=--enable-doc - - compiler: gcc - os: linux - env: DO_SIMULATION=yes - sudo: true - - os: linux - env: - - HOST=x86_64-w64-mingw32 - - DO_PUSH_ARTIFACT=yes - - os: linux - env: - - HOST=i686-w64-mingw32 - - DO_PUSH_ARTIFACT=yes - - os: linux - env: DO_COVERITY_SCAN=yes - before_install: - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; @@ -205,6 +198,9 @@ after_script: .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; fi +before_cache: + - brew cleanup + cache: apt: true ccache: true @@ -215,6 +211,3 @@ cache: - openpace_bin files: - isetup-5.5.6.exe - -before_cache: - - brew cleanup From 0af46c88b7287ab5c99da0052de45412ca696bed Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 15 Oct 2018 15:17:27 +0200 Subject: [PATCH 0708/4321] added tests for Microsoft CryptoAPI imported from https://github.com/CardContact/sc-hsm-embedded --- src/tests/Makefile.mak | 7 +- src/tests/opensc-minidriver-test.c | 846 +++++++++++++++++++++++++++++ 2 files changed, 852 insertions(+), 1 deletion(-) create mode 100644 src/tests/opensc-minidriver-test.c diff --git a/src/tests/Makefile.mak b/src/tests/Makefile.mak index 608807e729..49ac651f74 100644 --- a/src/tests/Makefile.mak +++ b/src/tests/Makefile.mak @@ -1,6 +1,6 @@ TOPDIR = ..\.. -TARGETS = base64.exe p15dump.exe \ +TARGETS = base64.exe p15dump.exe opensc-minidriver-test.exe \ p15dump.exe pintest.exe # prngtest.exe lottery.exe OBJECTS = print.obj sc-test.obj $(TOPDIR)\win32\versioninfo.res @@ -12,6 +12,11 @@ all: $(TARGETS) $(TARGETS): $(OBJECTS) $(LIBS) +opensc-minidriver-test.exe: + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj bcrypt.lib ncrypt.lib crypt32.lib winscard.lib + if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + .c.exe: cl $(COPTS) /c $< link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) diff --git a/src/tests/opensc-minidriver-test.c b/src/tests/opensc-minidriver-test.c new file mode 100644 index 0000000000..5e10205b07 --- /dev/null +++ b/src/tests/opensc-minidriver-test.c @@ -0,0 +1,846 @@ +/** + * SmartCard-HSM PKCS#11 Module + * + * Copyright (c) 2017, CardContact Systems GmbH, Minden, Germany + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CardContact Systems GmbH nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL CardContact Systems GmbH BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file opensc-minidriver-test.c + * @author Andreas Schwier + * @brief Test framework for the CSP minidriver implementation + */ + +#include +#include +#include +#include +#include + +static int testscompleted = 0; +static int testsfailed = 0; +static char *reader = NULL; + + +#include +#include +#include + + + +char *SystemErrorMsg(DWORD rc) +{ + char *msg = "UNKNOWN"; + + if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, 0, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0)) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle("crypt32.dll"), rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + } + return msg; +} + + + +char *NTSTATUSErrorMsg(NTSTATUS nts) +{ + char *msg = "UNKNOWN"; + + HMODULE hmod = GetModuleHandle("ntdll.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, nts, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + return msg; +} + + + +char *SECURITY_STATUSErrorMsg(SECURITY_STATUS secstat) +{ + char *msg = "UNKNOWN"; + + HMODULE hmod = GetModuleHandle("crypt32.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, secstat, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + return msg; +} + + + +/* +char *ErrorMsg(DWORD rc) +{ + char *msg = "UNKNOWN"; + HMODULE hmod; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, 0, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("bcrypt.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("ncrypt.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("crypt32.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("ntdll.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("kernel32.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("KernelBase.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("msvcrt.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + hmod = GetModuleHandle("cryptbase.dll"); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); + + return msg; +} +*/ + + +static char *verdict(int condition) { + testscompleted++; + + if (condition) { + return "Passed"; + } else { + testsfailed++; + return "Failed"; + } +} + + + +LPVOID WINAPI CSP_ALLOC(__in SIZE_T Size) { + return calloc(1, Size); +} + + + +LPVOID WINAPI CSP_REALLOC(__in LPVOID Address, __in SIZE_T Size) { + return realloc(Address, Size); +} + + + +void WINAPI CSP_FREE(__in LPVOID Address) { + free(Address); +} + + + +int testSignRSA(NCRYPT_KEY_HANDLE hKey, DWORD padding, LPCWSTR hashAlg ) +{ + BCRYPT_KEY_HANDLE hPubKey; + SECURITY_STATUS secstat; + BCRYPT_PKCS1_PADDING_INFO p1padinfo; + BCRYPT_PSS_PADDING_INFO psspadinfo; + BCRYPT_ALG_HANDLE hSignAlg; + void *paddingInfo; + PCCERT_CONTEXT certctx; + NTSTATUS ntstat; + unsigned char cert[4096],hash[64],signature[256],pubkeyblob[1024]; + DWORD dwrc,dwlen,hashlen; + + printf(" RSA signing with %S and %s padding", hashAlg, (padding == BCRYPT_PAD_PKCS1 ? "V1.5" : "PSS")); + + memset(hash, 0xA5, sizeof(hash)); + hashlen = sizeof(hash); + + if (!wcscmp(hashAlg, BCRYPT_SHA1_ALGORITHM)) { + hashlen = 20; + } else if (!wcscmp(hashAlg, BCRYPT_SHA256_ALGORITHM)) { + hashlen = 32; + } else if (!wcscmp(hashAlg, BCRYPT_SHA384_ALGORITHM)) { + hashlen = 48; + } else if (!wcscmp(hashAlg, BCRYPT_SHA512_ALGORITHM)) { + hashlen = 64; + } else if (!wcscmp(hashAlg, BCRYPT_MD5_ALGORITHM)) { + hashlen = 16; + } + + if (padding == BCRYPT_PAD_PKCS1) { + memset(&p1padinfo, 0, sizeof(p1padinfo)); + p1padinfo.pszAlgId = hashAlg; + paddingInfo = &p1padinfo; + } else { + memset(&psspadinfo, 0, sizeof(psspadinfo)); + psspadinfo.pszAlgId = hashAlg; + psspadinfo.cbSalt = hashlen; + paddingInfo = &psspadinfo; + } + + // Export public key from smart card + secstat = NCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptOpenAlgorithmProvider failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_RSAPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptImportKeyPair failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + secstat = NCryptSignHash(hKey, paddingInfo, hash, hashlen, signature, sizeof(signature), &dwlen, padding); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptVerifySignature(hPubKey, paddingInfo, hash, hashlen, signature, dwlen, padding); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + BCryptDestroyKey(hPubKey); + + // Verify with certificate + // Get certificate for key + secstat = NCryptGetProperty(hKey, NCRYPT_CERTIFICATE_PROPERTY, cert, sizeof(cert), &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptGetProperty failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + certctx = CertCreateCertificateContext(X509_ASN_ENCODING, cert, dwlen); + + if (certctx == NULL) { + dwrc = GetLastError(); + printf("\nCertCreateCertificateContext failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc)); + return -1; + } + + if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &certctx->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &hPubKey)) { + dwrc = GetLastError(); + printf("\nCryptImportPublicKeyInfoEx2 failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc)); + return -1; + } + + secstat = NCryptSignHash(hKey, paddingInfo, hash, hashlen, signature, sizeof(signature), &dwlen, padding); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptVerifySignature(hPubKey, paddingInfo, hash, hashlen, signature, dwlen, padding); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + BCryptDestroyKey(hPubKey); + CertFreeCertificateContext(certctx); + + return 0; +} + + + +int testSignECDSA(NCRYPT_KEY_HANDLE hKey, LPCWSTR hashAlg ) +{ + BCRYPT_KEY_HANDLE hPubKey; + SECURITY_STATUS secstat; + PCCERT_CONTEXT certctx; +// BCRYPT_ALG_HANDLE hSignAlg; + NTSTATUS ntstat; + unsigned char cert[4096],hash[64],signature[256]; // ,pubkeyblob[1024]; + DWORD dwrc,dwlen,hashlen; + + printf(" ECDSA with %S", hashAlg); + + memset(hash, 0xA5, sizeof(hash)); + hashlen = sizeof(hash); + + if (!wcscmp(hashAlg, BCRYPT_SHA1_ALGORITHM)) { + hashlen = 20; + } else if (!wcscmp(hashAlg, BCRYPT_SHA256_ALGORITHM)) { + hashlen = 32; + } else if (!wcscmp(hashAlg, BCRYPT_SHA384_ALGORITHM)) { + hashlen = 48; + } else if (!wcscmp(hashAlg, BCRYPT_SHA512_ALGORITHM)) { + hashlen = 64; + } else if (!wcscmp(hashAlg, BCRYPT_MD5_ALGORITHM)) { + hashlen = 16; + } + +#if 0 + // Export public key from smart card + secstat = NCryptExportKey(hKey, 0, BCRYPT_ECCPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptExportKey failed: %08lx %s\n", ntstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0); + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptOpenAlgorithmProvider failed: %ld\n", ntstat); + return -1; + } + + ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_ECCPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0); + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptImportKeyPair failed: %ld\n", ntstat); + return -1; + } + + secstat = NCryptSignHash(hKey, NULL, hash, hashlen, signature, dwlen, &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptSignHash failed: %08lx %s\n", ntstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptVerifySignature(hPubKey, NULL, hash, hashlen, signature, dwlen, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptVerifySignature failed: %ld\n", ntstat); + return -1; + } + + BCryptDestroyKey(hPubKey); +#endif + + // Get certificate for key + secstat = NCryptGetProperty(hKey, NCRYPT_CERTIFICATE_PROPERTY, cert, sizeof(cert), &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptGetProperty failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + certctx = CertCreateCertificateContext(X509_ASN_ENCODING, cert, dwlen); + + if (certctx == NULL) { + dwrc = GetLastError(); + printf("\nCertCreateCertificateContext failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc)); + return -1; + } + + if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &certctx->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &hPubKey)) { + dwrc = GetLastError(); + printf("\nCryptImportPublicKeyInfoEx2 failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc)); + return -1; + } + + secstat = NCryptSignHash(hKey, NULL, hash, hashlen, signature, dwlen, &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptVerifySignature(hPubKey, NULL, hash, hashlen, signature, dwlen, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + BCryptDestroyKey(hPubKey); + CertFreeCertificateContext(certctx); + + return 0; +} + + + +int testDecryptRSA(NCRYPT_KEY_HANDLE hKey, DWORD padding ) +{ + BCRYPT_KEY_HANDLE hPubKey; + SECURITY_STATUS secstat; + BCRYPT_OAEP_PADDING_INFO oaeppadinfo; + BCRYPT_ALG_HANDLE hSignAlg; + void *paddingInfo; + NTSTATUS ntstat; + unsigned char secret[48],plain[256],cryptogram[256],pubkeyblob[1024]; + DWORD dwlen,secretlen; + + printf(" RSA decryption with %s padding", (padding == BCRYPT_PAD_PKCS1 ? "V1.5" : "OAEP")); + + memset(secret, 0xA5, sizeof(secret)); + secret[0] = 0x5A; + secretlen = sizeof(secret); + + if (padding == BCRYPT_PAD_PKCS1) { + paddingInfo = NULL; + } else { + memset(&oaeppadinfo, 0, sizeof(oaeppadinfo)); + oaeppadinfo.pszAlgId = BCRYPT_SHA256_ALGORITHM; + paddingInfo = &oaeppadinfo; + } + + // Export public key from smart card + secstat = NCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptOpenAlgorithmProvider failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_RSAPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptImportKeyPair failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + ntstat = BCryptEncrypt(hPubKey, secret, secretlen, paddingInfo, NULL, 0, cryptogram, sizeof(cryptogram), &dwlen, padding); + + if (ntstat != ERROR_SUCCESS) { + printf("\nBCryptEncrypt failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat)); + return -1; + } + + secstat = NCryptDecrypt(hKey, cryptogram, dwlen, paddingInfo, plain, sizeof(plain), &dwlen, padding); + + if (secstat != ERROR_SUCCESS) { + printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + BCryptDestroyKey(hPubKey); + + if ((secretlen != dwlen) || memcmp(plain, secret, secretlen)) { + printf("\nDecrypted data does not match plain data\n"); + return -1; + } + return 0; +} + + + +int cryptoTests() + +{ + NCRYPT_PROV_HANDLE hProvider; + NCRYPT_KEY_HANDLE hKey; + NCryptKeyName *keyName; + PVOID enumState = NULL; + SECURITY_STATUS secstat; + NCryptAlgorithmName *algos; + DWORD dwlen, dwi; + int rc; + + secstat = NCryptOpenStorageProvider(&hProvider, MS_SMART_CARD_KEY_STORAGE_PROVIDER, 0); + + if (secstat != ERROR_SUCCESS) { + printf("NCryptOpenStorageProvider failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + secstat = NCryptEnumAlgorithms(hProvider, NCRYPT_CIPHER_OPERATION|NCRYPT_HASH_OPERATION|NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION|NCRYPT_SECRET_AGREEMENT_OPERATION, &dwlen, &algos, 0); + + if (secstat != ERROR_SUCCESS) { + printf("NCryptEnumAlgorithms failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + for (dwi = 0; dwi < dwlen; dwi++) { + printf("%S %lx %lx %lx\n", (algos + dwi)->pszName, (algos + dwi)->dwClass, (algos + dwi)->dwAlgOperations, (algos + dwi)->dwFlags); + } + + NCryptFreeBuffer(algos); + + while (TRUE) { + secstat = NCryptEnumKeys(hProvider, NULL, &keyName, &enumState, 0); + + if (secstat != ERROR_SUCCESS) { + break; + } + + printf("%S (%S)\n", keyName->pszName, keyName->pszAlgid); + + secstat = NCryptOpenKey(hProvider, &hKey, keyName->pszName, 0, 0); + + if (secstat != ERROR_SUCCESS) { + printf("NCryptOpenKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat)); + return -1; + } + + if ((keyName->dwLegacyKeySpec == AT_KEYEXCHANGE) || (keyName->dwLegacyKeySpec == AT_SIGNATURE)) { + rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA1_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA256_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA384_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA512_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_MD5_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PSS, BCRYPT_SHA1_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignRSA(hKey, BCRYPT_PAD_PSS, BCRYPT_SHA256_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testDecryptRSA(hKey, BCRYPT_PAD_PKCS1 ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testDecryptRSA(hKey, BCRYPT_PAD_OAEP ); + printf(" - %s\n", verdict(rc == 0)); + } else { + rc = testSignECDSA(hKey, BCRYPT_SHA1_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignECDSA(hKey, BCRYPT_SHA256_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignECDSA(hKey, BCRYPT_SHA384_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignECDSA(hKey, BCRYPT_SHA512_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + + rc = testSignECDSA(hKey, BCRYPT_MD5_ALGORITHM ); + printf(" - %s\n", verdict(rc == 0)); + } + + NCryptFreeObject(hKey); + } + + NCryptFreeObject(hProvider); + + return 0; +} + + + +int listReaders() +{ + SCARDCONTEXT hSCardCtx; + DWORD cch = 0; + LPTSTR readers = NULL; + + if (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hSCardCtx) != SCARD_S_SUCCESS) { + printf("SCardEstablishContext() failed\n"); + exit(1); + } + + if (SCardListReaders(hSCardCtx, NULL, NULL, &cch) != SCARD_S_SUCCESS) { + printf("SCardListReaders() failed\n"); + exit(1); + } + + readers = malloc(cch); + reader = readers; + + if (SCardListReaders(hSCardCtx, NULL, readers, &cch) != SCARD_S_SUCCESS) { + printf("SCardListReaders() failed\n"); + exit(1); + } + + while(*readers) { + printf("%s\n", readers); + readers += strlen(readers) + 1; + } + + SCardReleaseContext(hSCardCtx); + + return 0; +} + + + +int apiTests(char *reader) +{ + HMODULE dlhandle; + PFN_CARD_ACQUIRE_CONTEXT pcac; + CARD_FREE_SPACE_INFO cardFreeSpaceInfo; + CARD_CAPABILITIES cardCapabilities; + CARD_DATA cardData; + CARD_KEY_SIZES keySizes; + CARD_FILE_INFO fileInfo; + CONTAINER_INFO containerInfo; + PIN_INFO pinInfo; + LPSTR filenames; + PBYTE pb; + DWORD readernamelen, state, protocol, atrlen; + unsigned char atr[36], cardid[16]; + DWORD dwrc,dwlen,dwparam; + BOOL flag; + + memset(&cardData, 0, sizeof(cardData)); + cardData.dwVersion = 7; + cardData.pwszCardName = L"TestCard"; + + cardData.pfnCspAlloc = CSP_ALLOC; + cardData.pfnCspReAlloc = CSP_REALLOC; + cardData.pfnCspFree = CSP_FREE; + + if (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &cardData.hSCardCtx) != SCARD_S_SUCCESS) { + printf("SCardEstablishContext() failed\n"); + exit(1); + } + + dlhandle = LoadLibrary("opensc-minidriver.dll"); + + if (!dlhandle) { + dwrc = GetLastError(); + printf("LoadLibrary failed %04x %s\n", dwrc, SystemErrorMsg(dwrc)); + exit(1); + } + + pcac = (PFN_CARD_ACQUIRE_CONTEXT)GetProcAddress(dlhandle, "CardAcquireContext"); + + readernamelen = 0; + atrlen = sizeof(atr); + + if (SCardConnect(cardData.hSCardCtx, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &cardData.hScard, &protocol) != SCARD_S_SUCCESS) { + printf("SCardStatus() failed\n"); + exit(1); + } + + if (SCardStatus(cardData.hScard, NULL, &readernamelen, &state, &protocol, atr, &atrlen) != SCARD_S_SUCCESS) { + printf("SCardStatus() failed\n"); + exit(1); + } + + cardData.pbAtr = atr; + cardData.cbAtr = atrlen; + + printf("Calling CardAcquireContext()"); + dwrc = (*pcac)(&cardData, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardQueryFreeSpace()"); + cardFreeSpaceInfo.dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION; + dwrc = (*cardData.pfnCardQueryFreeSpace)(&cardData, 0, &cardFreeSpaceInfo); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_FREE_SPACE)"); + cardFreeSpaceInfo.dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_FREE_SPACE, (PBYTE)&cardFreeSpaceInfo, sizeof(cardFreeSpaceInfo), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardQueryCapabilities()"); + cardCapabilities.dwVersion = CARD_CAPABILITIES_CURRENT_VERSION; + dwrc = (*cardData.pfnCardQueryCapabilities)(&cardData, &cardCapabilities); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_CAPABILITIES)"); + cardCapabilities.dwVersion = CARD_CAPABILITIES_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_CAPABILITIES, (PBYTE)&cardCapabilities, sizeof(cardCapabilities), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardQueryKeySizes()"); + keySizes.dwVersion = CARD_KEY_SIZES_CURRENT_VERSION; + dwrc = (*cardData.pfnCardQueryKeySizes)(&cardData, AT_SIGNATURE, 0, &keySizes); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_KEYSIZES)"); + keySizes.dwVersion = CARD_KEY_SIZES_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_KEYSIZES, (PBYTE)&keySizes, sizeof(keySizes), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_READ_ONLY)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_READ_ONLY, (PBYTE)&flag, sizeof(flag), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && flag)); + + printf("Calling CardGetProperty(CP_CARD_CACHE_MODE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_CACHE_MODE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CP_CACHE_MODE_NO_CACHE))); + + printf("Calling CardGetProperty(CP_SUPPORTS_WIN_X509_ENROLLMENT)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_SUPPORTS_WIN_X509_ENROLLMENT, (PBYTE)&flag, sizeof(flag), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && !flag)); + + printf("Calling CardGetProperty(CP_CARD_GUID)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_GUID, (PBYTE)&cardid, sizeof(cardid), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_SERIAL_NO)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_SERIAL_NO, (PBYTE)&cardid, sizeof(cardid), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_PIN_INFO)"); + pinInfo.dwVersion = PIN_INFO_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_INFO, (PBYTE)&pinInfo, sizeof(pinInfo), &dwlen, ROLE_USER); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_LIST_PINS)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_LIST_PINS, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CREATE_PIN_SET(ROLE_USER)))); + + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + + printf("Calling CardGetProperty(CP_CARD_PIN_STRENGTH_VERIFY)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_STRENGTH_VERIFY, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CARD_PIN_STRENGTH_PLAINTEXT))); + + printf("Calling CardGetProperty(CP_KEY_IMPORT_SUPPORT)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_KEY_IMPORT_SUPPORT, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + + printf("Calling CardReadFile(cardid)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, szCARD_IDENTIFIER_FILE, 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 16))); + + printf("Calling CardReadFile(cardcf)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, szCACHE_FILE, 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 6))); + + printf("Calling CardReadFile(cardapps)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, "cardapps", 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 8))); + + printf("Calling CardReadFile(mscp/cmapfile)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szCONTAINER_MAP_FILE, 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0))); + + printf("Calling CardReadFile(mscp/msroots)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szROOT_STORE_FILE, 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0))); + + printf("Calling CardGetFileInfo(mscp/cmapfile)"); + fileInfo.dwVersion = CARD_FILE_INFO_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetFileInfo)(&cardData, szBASE_CSP_DIR, szCONTAINER_MAP_FILE, &fileInfo); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0))); + + printf("Calling CardReadFile(mscp/kxc00)"); + dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szUSER_KEYEXCHANGE_CERT_PREFIX "00", 0, &pb, &dwlen); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0))); + + printf("Calling CardEnumFiles(root)"); + dwrc = (*cardData.pfnCardEnumFiles)(&cardData, NULL, &filenames, &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0))); + + printf("Calling CardGetContainerInfo(0)"); + containerInfo.dwVersion = CONTAINER_INFO_CURRENT_VERSION; + dwrc = (*cardData.pfnCardGetContainerInfo)(&cardData, 0, 0, &containerInfo); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardAuthenticatePin(wszCARD_USER_USER)"); + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "648219", 6, &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 3))); + + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); + + printf("Calling CardAuthenticatePin(wszCARD_USER_USER) - Wrong PIN"); + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "123456", 6, &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_W_WRONG_CHV) && (dwparam == 2))); + + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + + printf("Calling CardAuthenticatePin(wszCARD_USER_USER)"); + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "648219", 6, &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 3))); + + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); + + printf("Calling CardDeAuthenticate(wszCARD_USER_USER)"); + dwrc = (*cardData.pfnCardDeauthenticate)(&cardData, wszCARD_USER_USER, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + + printf("Calling CardDeleteContext()"); + dwrc = (*cardData.pfnCardDeleteContext)(&cardData); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + + SCardReleaseContext(cardData.hSCardCtx); + + return 0; +} + + + +int main(int argc, char *argv[]) + +{ + if (argc == 1) { + printf("Usage: opensc-minidriver-test [-l] [-r ] [-a] [-c]\n"); + printf(" -l list readers\n"); + printf(" -r define readers\n"); + printf(" -a run API tests\n"); + printf(" -c run crypto tests\n"); + exit(1); + } + + argc--; + argv++; + + while (argc--) { + if (!strcmp(*argv, "-l")) { + listReaders(); + } else if (!strcmp(*argv, "-r")) { + if (argc == 0) { + printf("Reader name missing in -r parameter\n"); + exit(1); + } + argv++; + argc--; + reader = *argv; + } else if (!strcmp(*argv, "-a")) { + if (reader == NULL) { + printf("Need a reader name set with -r or use -l to select first reader\n"); + exit(1); + } + apiTests(reader); + } else if (!strcmp(*argv, "-c")) { + cryptoTests(); + } else { + printf("Unknown parameter %s\n", *argv); + } + argv++; + } + + printf("Unit test finished.\n"); + printf("%d tests performed.\n", testscompleted); + printf("%d tests failed.\n", testsfailed); + + exit(testsfailed ? 1 : 0); +} From fbb4d1f84326b31d3b00f8a317389bd0d818f644 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 Jan 2019 19:23:35 +0100 Subject: [PATCH 0709/4321] tools: use consistent behavior of -v -v switches to debug output to stderr in OpenSC tools regardless of the opensc.conf setting --- src/tools/cardos-tool.c | 5 ----- src/tools/cryptoflex-tool.c | 5 ----- src/tools/dnie-tool.c | 5 ----- src/tools/gids-tool.c | 9 --------- src/tools/iasecc-tool.c | 9 --------- src/tools/netkey-tool.c | 4 ---- src/tools/openpgp-tool.c | 5 ----- src/tools/opensc-tool.c | 8 -------- src/tools/piv-tool.c | 9 --------- src/tools/pkcs15-crypt.c | 5 ----- src/tools/pkcs15-init.c | 5 ----- src/tools/pkcs15-tool.c | 5 ----- src/tools/sc-hsm-tool.c | 9 --------- src/tools/util.c | 8 ++++++++ src/tools/westcos-tool.c | 5 ----- 15 files changed, 8 insertions(+), 88 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index d04c245cf2..61232f706d 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1090,11 +1090,6 @@ int main(int argc, char *argv[]) return 1; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (opt_driver != NULL) { err = sc_set_card_driver(ctx, opt_driver); if (err) { diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 662a028222..1a9e960bc1 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -1073,11 +1073,6 @@ int main(int argc, char *argv[]) return 1; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); printf("Using card driver: %s\n", card->driver->name); diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index ff60e72ead..660d90bad2 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -149,11 +149,6 @@ int main(int argc, char* argv[]) goto dnie_tool_end; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx,"stderr"); - } - if (opt_driver != NULL) { err = sc_set_card_driver(ctx, opt_driver); if (err) { diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 3ae56e7485..0d1128ffce 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -480,9 +480,6 @@ int main(int argc, char * argv[]) const char *opt_new_key = NULL; sc_context_param_t ctx_param; - setbuf(stderr, NULL); - setbuf(stdout, NULL); - while (1) { c = getopt_long(argc, argv, "XUCr:wv", options, &long_optind); if (c == -1) @@ -553,12 +550,6 @@ int main(int argc, char * argv[]) exit(1); } - /* Only change if not in opensc.conf */ - if (verbose > 1 && ctx->debug == 0) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r != SC_SUCCESS) { if (r < 0) { diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index d8a31faa5a..6b1d0111db 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -205,9 +205,6 @@ int main(int argc, char *argv[]) int action_count = 0; sc_context_param_t ctx_param; - setbuf(stderr, NULL); - setbuf(stdout, NULL); - while (1) { c = getopt_long(argc, argv, "v", options, &long_optind); if (c == -1) @@ -247,12 +244,6 @@ int main(int argc, char *argv[]) return 1; } - /* Only change if not in opensc.conf */ - if (verbose > 1 && ctx->debug == 0) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (action_count <= 0) goto end; diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index b729ee8203..4249187b3b 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -533,10 +533,6 @@ int main( fprintf(stderr,"Establish-Context failed: %s\n", sc_strerror(r)); exit(1); } - if (debug > 1) { - ctx->debug = debug; - sc_ctx_log_to_file(ctx, "stderr"); - } if(ctx->debug>0) printf("Context for application \"%s\" created, Debug=%d\n", ctx->app_name, ctx->debug); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 24230e1c77..eb071c441e 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -867,11 +867,6 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { util_fatal("failed to connect to card: %s", sc_strerror(r)); diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 2f121acf6a..601c3d2aed 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -714,9 +714,6 @@ int main(int argc, char *argv[]) char **p; sc_context_param_t ctx_param; - setbuf(stderr, NULL); - setbuf(stdout, NULL); - while (1) { c = getopt_long(argc, argv, "inlG:S:fr:vs:Dc:aw", options, &long_optind); if (c == -1) @@ -829,11 +826,6 @@ int main(int argc, char *argv[]) ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (do_get_conf_entry) { if ((err = opensc_get_conf_entry (opt_conf_entry))) goto end; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index f17fb162da..aee4fdeb18 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -487,9 +487,6 @@ int main(int argc, char *argv[]) sc_context_param_t ctx_param; char **old_apdus = NULL; - setbuf(stderr, NULL); - setbuf(stdout, NULL); - while (1) { c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:fvs:c:w", options, &long_optind); if (c == -1) @@ -601,12 +598,6 @@ int main(int argc, char *argv[]) return 1; } - /* Only change if not in opensc.conf */ - if (verbose > 1 && ctx->debug == 0) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (action_count <= 0) goto end; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 9182c7f5c5..6d064ec317 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -475,11 +475,6 @@ int main(int argc, char *argv[]) return 1; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); if (err) goto end; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index d98b787a18..a6cce3b009 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -667,11 +667,6 @@ open_reader_and_card(char *reader) return 0; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (util_connect_card_ex(ctx, &card, reader, opt_wait, 0, verbose)) return 0; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 289a95e950..4f81b10c83 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2295,11 +2295,6 @@ int main(int argc, char *argv[]) action_count--; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); if (err) goto end; diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 2b424cf736..61d1040a87 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1675,9 +1675,6 @@ int main(int argc, char *argv[]) int opt_iter = 10000000; sc_context_param_t ctx_param; - setbuf(stderr, NULL); - setbuf(stdout, NULL); - while (1) { c = getopt_long(argc, argv, "XC:I:P:W:U:s:i:fr:wv", options, &long_optind); if (c == -1) @@ -1776,12 +1773,6 @@ int main(int argc, char *argv[]) exit(1); } - /* Only change if not in opensc.conf */ - if (verbose > 1 && ctx->debug == 0) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - r = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); if (r != SC_SUCCESS) { if (r < 0) { diff --git a/src/tools/util.c b/src/tools/util.c index a3cbff7a79..5b8492e6c8 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -56,8 +56,16 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, struct sc_card *card = NULL; int r; + setbuf(stderr, NULL); + setbuf(stdout, NULL); + sc_notify_init(); + if (verbose) { + ctx->debug = verbose; + sc_ctx_log_to_file(ctx, "stderr"); + } + if (do_wait) { unsigned int event; diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index a4cd3a848a..4bcf9fdf86 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -443,11 +443,6 @@ int main(int argc, char *argv[]) return 1; } - if (verbose > 1) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (opt_driver != NULL) { r = sc_set_card_driver(ctx, opt_driver); From 3611b5c9f23dccf1b78462a75e02101b47ba4efb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 4 Jan 2019 20:22:46 +0100 Subject: [PATCH 0710/4321] tools: fixed colors if -v is specified --- src/libopensc/ctx.c | 21 --------------------- src/libopensc/log.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index e2c8f64a84..ff83df759b 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -362,24 +362,6 @@ set_drivers(struct _sc_ctx_options *opts, const scconf_list *list) } } -static int is_a_tty(FILE *fp) -{ - if (fp != NULL) { - int fd = fileno(fp); - if (fd >= 0) { -#ifdef _WIN32 - HANDLE h = (HANDLE)_get_osfhandle(fd); - if (h != INVALID_HANDLE_VALUE) { - return GetFileType(h) == FILE_TYPE_CHAR; - } -#else - return isatty(fd); -#endif - } - } - return 0; -} - static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { @@ -749,9 +731,6 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) * so at least one is NULL */ for (i = 0; ctx->conf_blocks[i]; i++) load_parameters(ctx, ctx->conf_blocks[i], opts); - - if (ctx->debug_file && !is_a_tty(ctx->debug_file)) - ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS; } int sc_ctx_detect_readers(sc_context_t *ctx) diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 90435cc3c9..b46fe498a3 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -174,6 +174,24 @@ void _sc_log(struct sc_context *ctx, const char *format, ...) va_end(ap); } +static int is_a_tty(FILE *fp) +{ + if (fp != NULL) { + int fd = fileno(fp); + if (fd >= 0) { +#ifdef _WIN32 + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (h != INVALID_HANDLE_VALUE) { + return GetFileType(h) == FILE_TYPE_CHAR; + } +#else + return isatty(fd); +#endif + } + } + return 0; +} + #ifdef _WIN32 #define set_color(sc_color, win_color, vt100_color) \ do { if (colors & sc_color) { attr |= win_color; } } while (0) @@ -192,6 +210,9 @@ int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const ch HANDLE handle = fd >= 0 ? (HANDLE) _get_osfhandle(fd) : INVALID_HANDLE_VALUE; #endif + if (!is_a_tty(stream)) + colors = 0; + if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) { #ifdef _WIN32 WORD attr = 0; From 1eda4c1795a64f8dc861ced1adffff9a33264130 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Dec 2018 00:31:43 +0100 Subject: [PATCH 0711/4321] sc-hsm-tool: add support for initializing biometry --- doc/tools/sc-hsm-tool.1.xml | 20 ++++++++++++++++- src/libopensc/card-sc-hsm.c | 15 ++++++++++++- src/libopensc/cardctl.h | 2 ++ src/tools/sc-hsm-tool.c | 44 ++++++++++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/doc/tools/sc-hsm-tool.1.xml b/doc/tools/sc-hsm-tool.1.xml index deb53e9172..ced876aec3 100644 --- a/doc/tools/sc-hsm-tool.1.xml +++ b/doc/tools/sc-hsm-tool.1.xml @@ -151,7 +151,25 @@ Define number of PIN retries for user PIN during initialization. Default is 3. - + + + + value + + + The hexadecimal AID of of the biometric server for template 1. Switches on the use of the user PIN as session PIN. + + + + + + value + + + The hexadecimal AID of of the biometric server for template 2. Switches on the use of the user PIN as session PIN. + + + value diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 52d08d48a2..aaae65c2c5 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1233,7 +1233,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa int r; size_t tilen; sc_apdu_t apdu; - u8 ibuff[50+0xFF], *p; + u8 ibuff[64+0xFF], *p; LOG_FUNC_CALLED(card->ctx); @@ -1266,6 +1266,19 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa *p++ = (u8)params->dkek_shares; } + if (params->bio1.len) { + *p++ = 0x95; + *p++ = params->bio1.len; + memcpy(p, params->bio1.value, params->bio1.len); + p += params->bio1.len; + } + if (params->bio2.len) { + *p++ = 0x96; + *p++ = params->bio2.len; + memcpy(p, params->bio2.value, params->bio2.len); + p += params->bio2.len; + } + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00); apdu.cla = 0x80; apdu.data = ibuff; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 0cf5a9d55f..e06674371c 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -1008,6 +1008,8 @@ typedef struct sc_cardctl_sc_hsm_init_param { u8 *user_pin; /* Initial user PIN */ size_t user_pin_len; /* Length of user PIN */ u8 user_pin_retry_counter; /* Retry counter default value */ + struct sc_aid bio1; /* AID of biometric server for template 1 */ + struct sc_aid bio2; /* AID of biometric server for template 2 */ u8 options[2]; /* Initialization options */ signed char dkek_shares; /* Number of DKEK shares, 0 for card generated, -1 for none */ char *label; /* Token label to be set in EF.TokenInfo (2F03) */ diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 61d1040a87..2642c000df 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -72,6 +72,8 @@ enum { OPT_SO_PIN = 0x100, OPT_PIN, OPT_RETRY, + OPT_BIO1, + OPT_BIO2, OPT_PASSWORD, OPT_PASSWORD_SHARES_THRESHOLD, OPT_PASSWORD_SHARES_TOTAL @@ -90,6 +92,8 @@ static const struct option options[] = { { "so-pin", 1, NULL, OPT_SO_PIN }, { "pin", 1, NULL, OPT_PIN }, { "pin-retry", 1, NULL, OPT_RETRY }, + { "bio-server1", 1, NULL, OPT_BIO1 }, + { "bio-server2", 1, NULL, OPT_BIO2 }, { "password", 1, NULL, OPT_PASSWORD }, { "pwd-shares-threshold", 1, NULL, OPT_PASSWORD_SHARES_THRESHOLD }, { "pwd-shares-total", 1, NULL, OPT_PASSWORD_SHARES_TOTAL }, @@ -115,6 +119,8 @@ static const char *option_help[] = { "Define security officer PIN (SO-PIN)", "Define user PIN", "Define user PIN retry counter", + "AID of biometric server for template 1 (hex)", + "AID of biometric server for template 2 (hex)", "Define password for DKEK share", "Define threshold for number of password shares required for reconstruction", "Define number of password shares", @@ -558,7 +564,7 @@ static void print_info(sc_card_t *card, sc_file_t *file) -static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, int dkek_shares, const char *label) +static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, const char *bio1, const char *bio2, int dkek_shares, const char *label) { sc_cardctl_sc_hsm_init_param_t param; size_t len; @@ -624,8 +630,32 @@ static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, param.user_pin_retry_counter = (u8)retry_counter; + if (bio1) { + param.bio1.len = sizeof(param.bio1.value); + r = sc_hex_to_bin(bio1, param.bio1.value, ¶m.bio1.len); + if (r < 0) { + fprintf(stderr, "Error decoding AID of biometric server for template 1 (%s)\n", sc_strerror(r)); + return -1; + } + } else { + param.bio1.len = 0; + } + if (bio2) { + param.bio2.len = sizeof(param.bio2.value); + r = sc_hex_to_bin(bio2, param.bio2.value, ¶m.bio2.len); + if (r < 0) { + fprintf(stderr, "Error decoding AID of biometric server for template 2 (%s)\n", sc_strerror(r)); + return -1; + } + } else { + param.bio2.len = 0; + } + param.options[0] = 0x00; - param.options[1] = 0x01; + param.options[1] = 0x01; /* RESET RETRY COUNTER enabled */ + if (param.bio1.len || param.bio2.len) { + param.options[1] |= 0x04; /* Session-PIN enabled with clear on reset */ + } param.dkek_shares = (char)dkek_shares; param.label = (char *)label; @@ -1666,6 +1696,8 @@ int main(int argc, char *argv[]) const char *opt_pin = NULL; const char *opt_filename = NULL; const char *opt_password = NULL; + const char *opt_bio1 = NULL; + const char *opt_bio2 = NULL; int opt_retry_counter = 3; int opt_dkek_shares = -1; int opt_key_reference = -1; @@ -1723,6 +1755,12 @@ int main(int argc, char *argv[]) case OPT_RETRY: opt_retry_counter = atol(optarg); break; + case OPT_BIO1: + opt_bio1 = optarg; + break; + case OPT_BIO2: + opt_bio2 = optarg; + break; case OPT_PASSWORD_SHARES_THRESHOLD: opt_password_shares_threshold = atol(optarg); break; @@ -1789,7 +1827,7 @@ int main(int argc, char *argv[]) goto fail; } - if (do_initialize && initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares, opt_label)) + if (do_initialize && initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_bio1, opt_bio2, opt_dkek_shares, opt_label)) goto fail; if (do_create_dkek_share && create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total)) From 141ec6ab23842797f76dcb65ee867962428598ca Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 17 Dec 2018 14:14:33 +0100 Subject: [PATCH 0712/4321] added shortcut to update binary via sfid --- src/libopensc/iso7816.c | 68 +++++++++++++++++++++++++++++++++ src/libopensc/libopensc.exports | 1 + src/libopensc/opensc.h | 15 +++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 6c27a38bb9..44d39edbc7 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1428,6 +1428,74 @@ int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, return r; } +#define ISO_UPDATE_BINARY 0xD6 +int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid, + u8 *ef, size_t ef_len) +{ + int r; + size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0; + sc_apdu_t apdu; +#ifdef ENABLE_SM + struct iso_sm_ctx *iso_sm_ctx; +#endif + + if (!card) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } + +#ifdef ENABLE_SM + iso_sm_ctx = card->sm_ctx.info.cmd_data; + if (write > SC_MAX_APDU_BUFFER_SIZE-2 + || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT + && write > (((SC_MAX_APDU_BUFFER_SIZE-2 + /* for encrypted APDUs we usually get authenticated status + * bytes (4B), a MAC (11B) and a cryptogram with padding + * indicator (3B without data). The cryptogram is always + * padded to the block size. */ + -18) / iso_sm_ctx->block_length) + * iso_sm_ctx->block_length - 1))) + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, + ISO_UPDATE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + else +#endif + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, + ISO_UPDATE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + + if (write > ef_len) { + apdu.datalen = ef_len; + apdu.lc = ef_len; + } else { + apdu.datalen = write; + apdu.lc = write; + } + apdu.data = ef; + + + r = sc_transmit_apdu(card, &apdu); + /* emulate the behaviour of sc_write_binary */ + if (r >= 0) + r = apdu.datalen; + + while (1) { + if (r < 0 || ((size_t) r) > ef_len) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not update EF."); + goto err; + } + wrote += r; + apdu.data += r; + if (wrote >= ef_len) + break; + + r = sc_update_binary(card, wrote, ef, write, 0); + } + + r = SC_SUCCESS; + +err: + return r; +} + int iso7816_logout(sc_card_t *card, unsigned char pin_reference) { int r; diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index fb78073b4e..4e7dc4a70d 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -375,3 +375,4 @@ sc_notify_close sc_notify sc_notify_id sc_color_fprintf +iso7816_update_binary_sfid diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 58e7cf66ff..050244b17b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1517,7 +1517,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, * * @param[in] card card * @param[in] sfid Short file identifier - * @param[in] ef Date to write + * @param[in] ef Data to write * @param[in] ef_len Length of \a ef * * @note The appropriate directory must be selected before calling this function. @@ -1525,6 +1525,19 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, u8 *ef, size_t ef_len); +/** + * @brief Update a EF by short file identifier. + * + * @param[in] card card + * @param[in] sfid Short file identifier + * @param[in] ef Data to write + * @param[in] ef_len Length of \a ef + * + * @note The appropriate directory must be selected before calling this function. + * */ +int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid, + u8 *ef, size_t ef_len); + /** * @brief Set verification status of a specific PIN to “not verified†* From 609e2d89cfdcd19594162e469381d087bf557e5e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Dec 2018 23:06:56 +0100 Subject: [PATCH 0713/4321] added GoID Tool --- .gitignore | 33 +- src/sm/sm-eac.c | 2 + src/tools/Makefile.am | 25 +- src/tools/Makefile.mak | 7 +- src/tools/goid-tool-cmdline.c | 2189 +++++++++++++++++++++++++++++++++ src/tools/goid-tool-cmdline.h | 280 +++++ src/tools/goid-tool.c | 795 ++++++++++++ src/tools/goid-tool.ggo.in | 87 ++ win32/OpenSC.wxs.in | 4 + 9 files changed, 3387 insertions(+), 35 deletions(-) create mode 100644 src/tools/goid-tool-cmdline.c create mode 100644 src/tools/goid-tool-cmdline.h create mode 100644 src/tools/goid-tool.c create mode 100644 src/tools/goid-tool.ggo.in diff --git a/.gitignore b/.gitignore index dfe8ea4ffe..d8d2bdf056 100644 --- a/.gitignore +++ b/.gitignore @@ -59,25 +59,11 @@ tags *.ggo ChangeLog -doc/tools/cardos-tool -doc/tools/cryptoflex-tool +doc/tools/*-tool doc/tools/eidenv -doc/tools/iasecc-tool -doc/tools/netkey-tool -doc/tools/openpgp-tool doc/tools/opensc-explorer -doc/tools/opensc-tool -doc/tools/gids-tool -doc/tools/piv-tool -doc/tools/pkcs11-tool doc/tools/pkcs15-crypt doc/tools/pkcs15-init -doc/tools/pkcs15-tool -doc/tools/sc-hsm-tool -doc/tools/westcos-tool -doc/tools/dnie-tool -doc/tools/egk-tool -doc/tools/npa-tool doc/tools/opensc-asn1 doc/tools/opensc-notify doc/files/opensc.conf.5.xml @@ -85,31 +71,16 @@ doc/files/opensc.conf.5.xml etc/opensc.conf.example src/common/compat_getopt_main src/minidriver/opensc-minidriver.inf -src/tools/cardos-tool -src/tools/iasecc-tool -src/tools/openpgp-tool -src/tools/sc-hsm-tool -src/tools/westcos-tool -src/tools/pkcs15-tool +src/tools/*-tool src/tools/pkcs15-crypt src/tools/pkcs15-init -src/tools/piv-tool src/tools/eidenv src/tools/opensc-explorer -src/tools/opensc-tool -src/tools/gids-tool -src/tools/rutoken-tool src/tools/cardos-info -src/tools/cryptoflex-tool -src/tools/netkey-tool -src/tools/pkcs11-tool -src/tools/dnie-tool -src/tools/npa-tool src/tools/sceac-example src/tools/opensc-notify src/tools/org.opensc.notify.desktop src/tools/opensc-asn1 -src/tools/egk-tool win32/OpenSC.iss win32/OpenSC.wxs diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index d2e6a63a31..11ad188c1c 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1638,6 +1638,8 @@ int perform_terminal_authentication(sc_card_t *card, BUF_MEM_free(eacsmctx->auxiliary_data); eacsmctx->auxiliary_data = BUF_MEM_create_init(auxiliary_data, auxiliary_data_len); + if (!eacsmctx->id_icc) + eacsmctx->id_icc = BUF_MEM_new(); signature = TA_STEP5_sign(eacsmctx->ctx, eacsmctx->eph_pub_key, eacsmctx->id_icc, eacsmctx->auxiliary_data); if (!signature) { diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index a01570f64d..8c67fb11ad 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -21,17 +21,18 @@ do_subst = $(SED) \ EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c +GOID_TOOL_BUILT_SOURCES = goid-tool-cmdline.h goid-tool-cmdline.c OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest noinst_HEADERS = util.h fread_to_eof.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool \ - cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 + cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 goid-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool @@ -139,6 +140,24 @@ $(EGK_TOOL_BUILT_SOURCES): $(abs_builddir)/egk-tool.ggo: egk-tool.ggo.in $(do_subst) < $(abs_srcdir)/egk-tool.ggo.in > $@ +goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c $(GOID_TOOL_BUILT_SOURCES) +goid_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPENPACE_LIBS) +goid_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) +goid_tool_CFLAGS += -Wno-unused-but-set-variable +if HAVE_UNKNOWN_WARNING_OPTION +goid_tool_CFLAGS += -Wno-unknown-warning-option +endif + +goid-tool.c: $(abs_builddir)/goid-tool.ggo $(GOID_TOOL_BUILT_SOURCES) + +# We only want *cmdline* to be generated when they have explicitly been removed. +$(GOID_TOOL_BUILT_SOURCES): + $(MAKE) $(abs_builddir)/goid-tool.ggo + $(GENGETOPT) --include-getopt --file-name=goid-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/goid-tool.ggo + +$(abs_builddir)/goid-tool.ggo: goid-tool.ggo.in + $(do_subst) < $(abs_srcdir)/goid-tool.ggo.in > $@ + opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c $(OPENSC_ASN1_BUILT_SOURCES) opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) opensc_asn1_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) @@ -181,4 +200,4 @@ org.opensc.notify.desktop: org.opensc.notify.desktop.in $(do_subst) < $(abs_srcdir)/org.opensc.notify.desktop.in > $@ clean-local: - rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop + rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/goid-tool.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 0c10a08493..ddc32894dd 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -6,7 +6,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ - opensc-notify.exe egk-tool.exe opensc-asn1.exe \ + opensc-notify.exe egk-tool.exe goid-tool.exe paccess-tool.exe opensc-asn1.exe \ $(PROGRAMS_OPENSSL) OBJECTS = util.obj versioninfo-tools.res @@ -37,6 +37,11 @@ egk-tool.exe: egk-tool-cmdline.obj util.obj $(LIBS) link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj util.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 +goid-tool.exe: goid-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) cl $(COPTS) /c $*.c link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c new file mode 100644 index 0000000000..8fd6e44405 --- /dev/null +++ b/src/tools/goid-tool-cmdline.c @@ -0,0 +1,2189 @@ +/* + File autogenerated by gengetopt version 2.22.6 + generated with the following command: + /usr/bin/gengetopt --include-getopt --file-name=goid-tool-cmdline --output-dir=. + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + + +#include "goid-tool-cmdline.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: goid-tool [OPTIONS]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -r, --reader=STRING Number of the reader to use. By default, the\n first reader with a present card is used. If\n the arguement is an ATR, the reader with a\n matching card will be chosen.", + " -v, --verbose Use (several times) to be more verbose", + "\nSoCManager Applet:", + " -p, --verify-pin Verify PIN", + " -b, --verify-bio Verify finger print", + " --verify-pin-or-bio Verify PIN or finger print (user's choice)", + " --new-pin Change PIN", + " --new-bio Use (several times) to change one or more\n biometric templates", + " --info Dump Information about the SoCManager's\n configuration", + "\nPAccess Applet:", + " -c, --certificate=FILENAME Use (several times) to pass CV certificates", + " -k, --key=FILENAME Private key for the CV certificate", + " --print-cardid Print the card ID", + " --write-cardid=CARDID Write the specified card ID", + " --print-paccessid Print the PAccess ID", + " --write-paccessid=PACCESSID\n Write the specified PAccess ID", + " --read-dg=ID Read the specified data group; use several\n times to read out multiple files", + " --out-file=FILENAME Write output to a file instead of printing it;\n use once for each use of `--read-dg'", + " --write-dg=ID Write the specified data group; use several\n times to write multiple files", + " --in-file=FILENAME Read input from a file; use once for each use\n of `--write-dg'", + " --delete-dg=ID Delete the specified data group; use several\n times to delete multiple files", + " --create-dg=ID Create the specified data group; use several\n times to create multiple files", + " --new-size=SIZE File size of newly created DGs (default=`256')", + " --new-read-ac=STRING Access condition for reading newly created DGs\n (possible values=\"always\", \"never\",\n \"ta\", \"sm\" default=`sm')", + " --new-read-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", + " --new-write-ac=STRING Access condition for writing newly created DGs\n (possible values=\"always\", \"never\",\n \"ta\", \"sm\" default=`sm')", + " --new-write-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", + 0 +}; + +typedef enum {ARG_NO + , ARG_STRING + , ARG_INT +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); + +const char *cmdline_parser_new_read_ac_values[] = {"always", "never", "ta", "sm", 0}; /*< Possible values for new-read-ac. */ +const char *cmdline_parser_new_write_ac_values[] = {"always", "never", "ta", "sm", 0}; /*< Possible values for new-write-ac. */ + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->reader_given = 0 ; + args_info->verbose_given = 0 ; + args_info->verify_pin_given = 0 ; + args_info->verify_bio_given = 0 ; + args_info->verify_pin_or_bio_given = 0 ; + args_info->new_pin_given = 0 ; + args_info->new_bio_given = 0 ; + args_info->info_given = 0 ; + args_info->certificate_given = 0 ; + args_info->key_given = 0 ; + args_info->print_cardid_given = 0 ; + args_info->write_cardid_given = 0 ; + args_info->print_paccessid_given = 0 ; + args_info->write_paccessid_given = 0 ; + args_info->read_dg_given = 0 ; + args_info->out_file_given = 0 ; + args_info->write_dg_given = 0 ; + args_info->in_file_given = 0 ; + args_info->delete_dg_given = 0 ; + args_info->create_dg_given = 0 ; + args_info->new_size_given = 0 ; + args_info->new_read_ac_given = 0 ; + args_info->new_read_ac_chatbit_given = 0 ; + args_info->new_write_ac_given = 0 ; + args_info->new_write_ac_chatbit_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->reader_arg = NULL; + args_info->reader_orig = NULL; + args_info->certificate_arg = NULL; + args_info->certificate_orig = NULL; + args_info->key_arg = NULL; + args_info->key_orig = NULL; + args_info->write_cardid_arg = NULL; + args_info->write_cardid_orig = NULL; + args_info->write_paccessid_arg = NULL; + args_info->write_paccessid_orig = NULL; + args_info->read_dg_arg = NULL; + args_info->read_dg_orig = NULL; + args_info->out_file_arg = NULL; + args_info->out_file_orig = NULL; + args_info->write_dg_arg = NULL; + args_info->write_dg_orig = NULL; + args_info->in_file_arg = NULL; + args_info->in_file_orig = NULL; + args_info->delete_dg_arg = NULL; + args_info->delete_dg_orig = NULL; + args_info->create_dg_arg = NULL; + args_info->create_dg_orig = NULL; + args_info->new_size_arg = 256; + args_info->new_size_orig = NULL; + args_info->new_read_ac_arg = gengetopt_strdup ("sm"); + args_info->new_read_ac_orig = NULL; + args_info->new_read_ac_chatbit_arg = NULL; + args_info->new_read_ac_chatbit_orig = NULL; + args_info->new_write_ac_arg = gengetopt_strdup ("sm"); + args_info->new_write_ac_orig = NULL; + args_info->new_write_ac_chatbit_arg = NULL; + args_info->new_write_ac_chatbit_orig = NULL; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->reader_help = gengetopt_args_info_help[2] ; + args_info->verbose_help = gengetopt_args_info_help[3] ; + args_info->verbose_min = 0; + args_info->verbose_max = 0; + args_info->verify_pin_help = gengetopt_args_info_help[5] ; + args_info->verify_bio_help = gengetopt_args_info_help[6] ; + args_info->verify_pin_or_bio_help = gengetopt_args_info_help[7] ; + args_info->new_pin_help = gengetopt_args_info_help[8] ; + args_info->new_bio_help = gengetopt_args_info_help[9] ; + args_info->new_bio_min = 0; + args_info->new_bio_max = 0; + args_info->info_help = gengetopt_args_info_help[10] ; + args_info->certificate_help = gengetopt_args_info_help[12] ; + args_info->certificate_min = 0; + args_info->certificate_max = 0; + args_info->key_help = gengetopt_args_info_help[13] ; + args_info->print_cardid_help = gengetopt_args_info_help[14] ; + args_info->write_cardid_help = gengetopt_args_info_help[15] ; + args_info->print_paccessid_help = gengetopt_args_info_help[16] ; + args_info->write_paccessid_help = gengetopt_args_info_help[17] ; + args_info->read_dg_help = gengetopt_args_info_help[18] ; + args_info->read_dg_min = 0; + args_info->read_dg_max = 0; + args_info->out_file_help = gengetopt_args_info_help[19] ; + args_info->out_file_min = 0; + args_info->out_file_max = 0; + args_info->write_dg_help = gengetopt_args_info_help[20] ; + args_info->write_dg_min = 0; + args_info->write_dg_max = 0; + args_info->in_file_help = gengetopt_args_info_help[21] ; + args_info->in_file_min = 0; + args_info->in_file_max = 0; + args_info->delete_dg_help = gengetopt_args_info_help[22] ; + args_info->delete_dg_min = 0; + args_info->delete_dg_max = 0; + args_info->create_dg_help = gengetopt_args_info_help[23] ; + args_info->create_dg_min = 0; + args_info->create_dg_max = 0; + args_info->new_size_help = gengetopt_args_info_help[24] ; + args_info->new_read_ac_help = gengetopt_args_info_help[25] ; + args_info->new_read_ac_chatbit_help = gengetopt_args_info_help[26] ; + args_info->new_read_ac_chatbit_min = 0; + args_info->new_read_ac_chatbit_max = 0; + args_info->new_write_ac_help = gengetopt_args_info_help[27] ; + args_info->new_write_ac_chatbit_help = gengetopt_args_info_help[28] ; + args_info->new_write_ac_chatbit_min = 0; + args_info->new_write_ac_chatbit_max = 0; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + +/** @brief generic value variable */ +union generic_value { + int int_arg; + char *string_arg; + const char *default_string_arg; +}; + +/** @brief holds temporary values for multiple options */ +struct generic_list +{ + union generic_value arg; + char *orig; + struct generic_list *next; +}; + +/** + * @brief add a node at the head of the list + */ +static void add_node(struct generic_list **list) { + struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list)); + new_node->next = *list; + *list = new_node; + new_node->arg.string_arg = 0; + new_node->orig = 0; +} + +/** + * The passed arg parameter is NOT set to 0 from this function + */ +static void +free_multiple_field(unsigned int len, void *arg, char ***orig) +{ + unsigned int i; + if (arg) { + for (i = 0; i < len; ++i) + { + free_string_field(&((*orig)[i])); + } + + free (arg); + free (*orig); + *orig = 0; + } +} + +static void +free_multiple_string_field(unsigned int len, char ***arg, char ***orig) +{ + unsigned int i; + if (*arg) { + for (i = 0; i < len; ++i) + { + free_string_field(&((*arg)[i])); + free_string_field(&((*orig)[i])); + } + free_string_field(&((*arg)[0])); /* free default string */ + + free (*arg); + *arg = 0; + free (*orig); + *orig = 0; + } +} + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + free_string_field (&(args_info->reader_arg)); + free_string_field (&(args_info->reader_orig)); + free_multiple_string_field (args_info->certificate_given, &(args_info->certificate_arg), &(args_info->certificate_orig)); + free_string_field (&(args_info->key_arg)); + free_string_field (&(args_info->key_orig)); + free_string_field (&(args_info->write_cardid_arg)); + free_string_field (&(args_info->write_cardid_orig)); + free_string_field (&(args_info->write_paccessid_arg)); + free_string_field (&(args_info->write_paccessid_orig)); + free_multiple_field (args_info->read_dg_given, (void *)(args_info->read_dg_arg), &(args_info->read_dg_orig)); + args_info->read_dg_arg = 0; + free_multiple_string_field (args_info->out_file_given, &(args_info->out_file_arg), &(args_info->out_file_orig)); + free_multiple_field (args_info->write_dg_given, (void *)(args_info->write_dg_arg), &(args_info->write_dg_orig)); + args_info->write_dg_arg = 0; + free_multiple_string_field (args_info->in_file_given, &(args_info->in_file_arg), &(args_info->in_file_orig)); + free_multiple_field (args_info->delete_dg_given, (void *)(args_info->delete_dg_arg), &(args_info->delete_dg_orig)); + args_info->delete_dg_arg = 0; + free_multiple_field (args_info->create_dg_given, (void *)(args_info->create_dg_arg), &(args_info->create_dg_orig)); + args_info->create_dg_arg = 0; + free_string_field (&(args_info->new_size_orig)); + free_string_field (&(args_info->new_read_ac_arg)); + free_string_field (&(args_info->new_read_ac_orig)); + free_multiple_field (args_info->new_read_ac_chatbit_given, (void *)(args_info->new_read_ac_chatbit_arg), &(args_info->new_read_ac_chatbit_orig)); + args_info->new_read_ac_chatbit_arg = 0; + free_string_field (&(args_info->new_write_ac_arg)); + free_string_field (&(args_info->new_write_ac_orig)); + free_multiple_field (args_info->new_write_ac_chatbit_given, (void *)(args_info->new_write_ac_chatbit_arg), &(args_info->new_write_ac_chatbit_orig)); + args_info->new_write_ac_chatbit_arg = 0; + + + + clear_given (args_info); +} + +/** + * @param val the value to check + * @param values the possible values + * @return the index of the matched value: + * -1 if no value matched, + * -2 if more than one value has matched + */ +static int +check_possible_values(const char *val, const char *values[]) +{ + int i, found, last; + size_t len; + + if (!val) /* otherwise strlen() crashes below */ + return -1; /* -1 means no argument for the option */ + + found = last = 0; + + for (i = 0, len = strlen(val); values[i]; ++i) + { + if (strncmp(val, values[i], len) == 0) + { + ++found; + last = i; + if (strlen(values[i]) == len) + return i; /* exact macth no need to check more */ + } + } + + if (found == 1) /* one match: OK */ + return last; + + return (found ? -2 : -1); /* return many values or none matched */ +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + int found = -1; + if (arg) { + if (values) { + found = check_possible_values(arg, values); + } + if (found >= 0) + fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); + else + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + +static void +write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[]) +{ + int i; + + for (i = 0; i < len; ++i) + write_into_file(outfile, opt, (arg ? arg[i] : 0), values); +} + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->reader_given) + write_into_file(outfile, "reader", args_info->reader_orig, 0); + write_multiple_into_file(outfile, args_info->verbose_given, "verbose", 0, 0); + if (args_info->verify_pin_given) + write_into_file(outfile, "verify-pin", 0, 0 ); + if (args_info->verify_bio_given) + write_into_file(outfile, "verify-bio", 0, 0 ); + if (args_info->verify_pin_or_bio_given) + write_into_file(outfile, "verify-pin-or-bio", 0, 0 ); + if (args_info->new_pin_given) + write_into_file(outfile, "new-pin", 0, 0 ); + write_multiple_into_file(outfile, args_info->new_bio_given, "new-bio", 0, 0); + if (args_info->info_given) + write_into_file(outfile, "info", 0, 0 ); + write_multiple_into_file(outfile, args_info->certificate_given, "certificate", args_info->certificate_orig, 0); + if (args_info->key_given) + write_into_file(outfile, "key", args_info->key_orig, 0); + if (args_info->print_cardid_given) + write_into_file(outfile, "print-cardid", 0, 0 ); + if (args_info->write_cardid_given) + write_into_file(outfile, "write-cardid", args_info->write_cardid_orig, 0); + if (args_info->print_paccessid_given) + write_into_file(outfile, "print-paccessid", 0, 0 ); + if (args_info->write_paccessid_given) + write_into_file(outfile, "write-paccessid", args_info->write_paccessid_orig, 0); + write_multiple_into_file(outfile, args_info->read_dg_given, "read-dg", args_info->read_dg_orig, 0); + write_multiple_into_file(outfile, args_info->out_file_given, "out-file", args_info->out_file_orig, 0); + write_multiple_into_file(outfile, args_info->write_dg_given, "write-dg", args_info->write_dg_orig, 0); + write_multiple_into_file(outfile, args_info->in_file_given, "in-file", args_info->in_file_orig, 0); + write_multiple_into_file(outfile, args_info->delete_dg_given, "delete-dg", args_info->delete_dg_orig, 0); + write_multiple_into_file(outfile, args_info->create_dg_given, "create-dg", args_info->create_dg_orig, 0); + if (args_info->new_size_given) + write_into_file(outfile, "new-size", args_info->new_size_orig, 0); + if (args_info->new_read_ac_given) + write_into_file(outfile, "new-read-ac", args_info->new_read_ac_orig, cmdline_parser_new_read_ac_values); + write_multiple_into_file(outfile, args_info->new_read_ac_chatbit_given, "new-read-ac-chatbit", args_info->new_read_ac_chatbit_orig, 0); + if (args_info->new_write_ac_given) + write_into_file(outfile, "new-write-ac", args_info->new_write_ac_orig, cmdline_parser_new_write_ac_values); + write_multiple_into_file(outfile, args_info->new_write_ac_chatbit_given, "new-write-ac-chatbit", args_info->new_write_ac_chatbit_orig, 0); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +static char * +get_multiple_arg_token(const char *arg) +{ + const char *tok; + char *ret; + size_t len, num_of_escape, i, j; + + if (!arg) + return 0; + + tok = strchr (arg, ','); + num_of_escape = 0; + + /* make sure it is not escaped */ + while (tok) + { + if (*(tok-1) == '\\') + { + /* find the next one */ + tok = strchr (tok+1, ','); + ++num_of_escape; + } + else + break; + } + + if (tok) + len = (size_t)(tok - arg + 1); + else + len = strlen (arg) + 1; + + len -= num_of_escape; + + ret = (char *) malloc (len); + + i = 0; + j = 0; + while (arg[i] && (j < len-1)) + { + if (arg[i] == '\\' && + arg[ i + 1 ] && + arg[ i + 1 ] == ',') + ++i; + + ret[j++] = arg[i++]; + } + + ret[len-1] = '\0'; + + return ret; +} + +static const char * +get_multiple_arg_token_next(const char *arg) +{ + const char *tok; + + if (!arg) + return 0; + + tok = strchr (arg, ','); + + /* make sure it is not escaped */ + while (tok) + { + if (*(tok-1) == '\\') + { + /* find the next one */ + tok = strchr (tok+1, ','); + } + else + break; + } + + if (! tok || strlen(tok) == 1) + return 0; + + return tok+1; +} + +static int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc); + +int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc) +{ + int error_occurred = 0; + + if (option_given && (min > 0 || max > 0)) + { + if (min > 0 && max > 0) + { + if (min == max) + { + /* specific occurrences */ + if (option_given != (unsigned int) min) + { + fprintf (stderr, "%s: %s option occurrences must be %d\n", + prog_name, option_desc, min); + error_occurred = 1; + } + } + else if (option_given < (unsigned int) min + || option_given > (unsigned int) max) + { + /* range occurrences */ + fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n", + prog_name, option_desc, min, max); + error_occurred = 1; + } + } + else if (min > 0) + { + /* at least check */ + if (option_given < min) + { + fprintf (stderr, "%s: %s option occurrences must be at least %d\n", + prog_name, option_desc, min); + error_occurred = 1; + } + } + else if (max > 0) + { + /* at most check */ + if (option_given > max) + { + fprintf (stderr, "%s: %s option occurrences must be at most %d\n", + prog_name, option_desc, max); + error_occurred = 1; + } + } + } + + return error_occurred; +} +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ + int error_occurred = 0; + FIX_UNUSED (additional_error); + + /* checks for required options */ + if (check_multiple_option_occurrences(prog_name, args_info->verbose_given, args_info->verbose_min, args_info->verbose_max, "'--verbose' ('-v')")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->new_bio_given, args_info->new_bio_min, args_info->new_bio_max, "'--new-bio'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->certificate_given, args_info->certificate_min, args_info->certificate_max, "'--certificate' ('-c')")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->read_dg_given, args_info->read_dg_min, args_info->read_dg_max, "'--read-dg'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->out_file_given, args_info->out_file_min, args_info->out_file_max, "'--out-file'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->write_dg_given, args_info->write_dg_min, args_info->write_dg_max, "'--write-dg'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->in_file_given, args_info->in_file_min, args_info->in_file_max, "'--in-file'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->delete_dg_given, args_info->delete_dg_min, args_info->delete_dg_max, "'--delete-dg'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->create_dg_given, args_info->create_dg_min, args_info->create_dg_max, "'--create-dg'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->new_read_ac_chatbit_given, args_info->new_read_ac_chatbit_min, args_info->new_read_ac_chatbit_max, "'--new-read-ac-chatbit'")) + error_occurred = 1; + + if (check_multiple_option_occurrences(prog_name, args_info->new_write_ac_chatbit_given, args_info->new_write_ac_chatbit_min, args_info->new_write_ac_chatbit_max, "'--new-write-ac-chatbit'")) + error_occurred = 1; + + + /* checks for dependences among options */ + if (args_info->certificate_given && ! args_info->key_given) + { + fprintf (stderr, "%s: '--certificate' ('-c') option depends on option 'key'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->key_given && ! args_info->certificate_given) + { + fprintf (stderr, "%s: '--key' ('-k') option depends on option 'certificate'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->new_size_given && ! args_info->create_dg_given) + { + fprintf (stderr, "%s: '--new-size' option depends on option 'create-dg'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->new_read_ac_given && ! args_info->create_dg_given) + { + fprintf (stderr, "%s: '--new-read-ac' option depends on option 'create-dg'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->new_read_ac_chatbit_given && ! args_info->create_dg_given) + { + fprintf (stderr, "%s: '--new-read-ac-chatbit' option depends on option 'create-dg'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->new_write_ac_given && ! args_info->create_dg_given) + { + fprintf (stderr, "%s: '--new-write-ac' option depends on option 'create-dg'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + if (args_info->new_write_ac_chatbit_given && ! args_info->create_dg_given) + { + fprintf (stderr, "%s: '--new-write-ac-chatbit' option depends on option 'create-dg'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + + return error_occurred; +} + +/* + * Extracted from the glibc source tree, version 2.3.6 + * + * Licensed under the GPL as per the whole glibc source tree. + * + * This file was modified so that getopt_long can be called + * many times without risking previous memory to be spoiled. + * + * Modified by Andre Noll and Lorenzo Bettini for use in + * GNU gengetopt generated files. + * + */ + +/* + * we must include anything we need since this file is not thought to be + * inserted in a file already using getopt.h + * + * Lorenzo + */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. +*/ +/* + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `custom_optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +/* Names for the values of the `has_arg' field of `struct option'. */ +#ifndef no_argument +#define no_argument 0 +#endif + +#ifndef required_argument +#define required_argument 1 +#endif + +#ifndef optional_argument +#define optional_argument 2 +#endif + +struct custom_getopt_data { + /* + * These have exactly the same meaning as the corresponding global variables, + * except that they are used for the reentrant versions of getopt. + */ + int custom_optind; + int custom_opterr; + int custom_optopt; + char *custom_optarg; + + /* True if the internal members have been initialized. */ + int initialized; + + /* + * The next char to be scanned in the option-element in which the last option + * character we returned was found. This allows us to pick up the scan where + * we left off. If this is zero, or a null string, it means resume the scan by + * advancing to the next ARGV-element. + */ + char *nextchar; + + /* + * Describe the part of ARGV that contains non-options that have been skipped. + * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is + * the index after the last of them. + */ + int first_nonopt; + int last_nonopt; +}; + +/* + * the variables optarg, optind, opterr and optopt are renamed with + * the custom_ prefix so that they don't interfere with getopt ones. + * + * Moreover they're static so they are visible only from within the + * file where this very file will be included. + */ + +/* + * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an + * option that takes an argument, the argument value is returned here. + */ +static char *custom_optarg; + +/* + * Index in ARGV of the next element to be scanned. This is used for + * communication to and from the caller and for communication between + * successive calls to `custom_getopt'. + * + * On entry to `custom_getopt', 1 means this is the first call; initialize. + * + * When `custom_getopt' returns -1, this is the index of the first of the non-option + * elements that the caller should itself scan. + * + * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV + * has been scanned so far. + * + * 1003.2 says this must be 1 before any call. + */ +static int custom_optind = 1; + +/* + * Callers store zero here to inhibit the error message for unrecognized + * options. + */ +static int custom_opterr = 1; + +/* + * Set to an option character which was unrecognized. This must be initialized + * on some systems to avoid linking in the system's own getopt implementation. + */ +static int custom_optopt = '?'; + +/* + * Exchange two adjacent subsequences of ARGV. One subsequence is elements + * [first_nonopt,last_nonopt) which contains all the non-options that have been + * skipped so far. The other is elements [last_nonopt,custom_optind), which contains + * all the options processed since those non-options were skipped. + * `first_nonopt' and `last_nonopt' are relocated so that they describe the new + * indices of the non-options in ARGV after they are moved. + */ +static void exchange(char **argv, struct custom_getopt_data *d) +{ + int bottom = d->first_nonopt; + int middle = d->last_nonopt; + int top = d->custom_optind; + char *tem; + + /* + * Exchange the shorter segment with the far end of the longer segment. + * That puts the shorter segment into the right place. It leaves the + * longer segment in the right place overall, but it consists of two + * parts that need to be swapped next. + */ + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = + argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + /* Update records for the slots the non-options now occupy. */ + d->first_nonopt += (d->custom_optind - d->last_nonopt); + d->last_nonopt = d->custom_optind; +} + +/* Initialize the internal data when the first call is made. */ +static void custom_getopt_initialize(struct custom_getopt_data *d) +{ + /* + * Start processing options with ARGV-element 1 (since ARGV-element 0 + * is the program name); the sequence of previously skipped non-option + * ARGV-elements is empty. + */ + d->first_nonopt = d->last_nonopt = d->custom_optind; + d->nextchar = NULL; + d->initialized = 1; +} + +#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') + +/* return: zero: continue, nonzero: return given value to user */ +static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, + struct custom_getopt_data *d) +{ + /* + * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been + * moved back by the user (who may also have changed the arguments). + */ + if (d->last_nonopt > d->custom_optind) + d->last_nonopt = d->custom_optind; + if (d->first_nonopt > d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * If we have just processed some options following some + * non-options, exchange them so that the options come first. + */ + if (d->first_nonopt != d->last_nonopt && + d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->last_nonopt != d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * Skip any additional non-options and extend the range of + * non-options previously skipped. + */ + while (d->custom_optind < argc && NONOPTION_P) + d->custom_optind++; + d->last_nonopt = d->custom_optind; + /* + * The special ARGV-element `--' means premature end of options. Skip + * it like a null option, then exchange with previous non-options as if + * it were an option, then skip everything else like a non-option. + */ + if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { + d->custom_optind++; + if (d->first_nonopt != d->last_nonopt + && d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->first_nonopt == d->last_nonopt) + d->first_nonopt = d->custom_optind; + d->last_nonopt = argc; + d->custom_optind = argc; + } + /* + * If we have done all the ARGV-elements, stop the scan and back over + * any non-options that we skipped and permuted. + */ + if (d->custom_optind == argc) { + /* + * Set the next-arg-index to point at the non-options that we + * previously skipped, so the caller will digest them. + */ + if (d->first_nonopt != d->last_nonopt) + d->custom_optind = d->first_nonopt; + return -1; + } + /* + * If we have come to a non-option and did not permute it, either stop + * the scan or describe it to the caller and pass it by. + */ + if (NONOPTION_P) { + d->custom_optarg = argv[d->custom_optind++]; + return 1; + } + /* + * We have found another option-ARGV-element. Skip the initial + * punctuation. + */ + d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); + return 0; +} + +/* + * Check whether the ARGV-element is a long option. + * + * If there's a long option "fubar" and the ARGV-element is "-fu", consider + * that an abbreviation of the long option, just like "--fu", and not "-f" with + * arg "u". + * + * This distinction seems to be the most useful approach. + * + */ +static int check_long_opt(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int print_errors, struct custom_getopt_data *d) +{ + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { + if ((unsigned int) (nameend - d->nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else if (pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[d->custom_optind]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optind++; + d->custom_optopt = 0; + return '?'; + } + if (pfound) { + option_index = indfound; + d->custom_optind++; + if (*nameend) { + if (pfound->has_arg != no_argument) + d->custom_optarg = nameend + 1; + else { + if (print_errors) { + if (argv[d->custom_optind - 1][1] == '-') { + /* --option */ + fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + } else { + /* +option or -option */ + fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[d->custom_optind - 1][0], pfound->name); + } + + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == required_argument) { + if (d->custom_optind < argc) + d->custom_optarg = argv[d->custom_optind++]; + else { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], + argv[d->custom_optind - 1]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->nextchar += strlen(d->nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* + * Can't find it as a long option. If this is not getopt_long_only, or + * the option starts with '--' or is not a valid short option, then + * it's an error. Otherwise interpret it as a short option. + */ + if (print_errors) { + if (argv[d->custom_optind][1] == '-') { + /* --option */ + fprintf(stderr, + "%s: unrecognized option `--%s'\n", + argv[0], d->nextchar); + } else { + /* +option or -option */ + fprintf(stderr, + "%s: unrecognized option `%c%s'\n", + argv[0], argv[d->custom_optind][0], + d->nextchar); + } + } + d->nextchar = (char *) ""; + d->custom_optind++; + d->custom_optopt = 0; + return '?'; +} + +static int check_short_opt(int argc, char *const *argv, const char *optstring, + int print_errors, struct custom_getopt_data *d) +{ + char c = *d->nextchar++; + const char *temp = strchr(optstring, c); + + /* Increment `custom_optind' when we start to process its last character. */ + if (*d->nextchar == '\0') + ++d->custom_optind; + if (!temp || c == ':') { + if (print_errors) + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + + d->custom_optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + d->custom_optind++; + } else + d->custom_optarg = NULL; + d->nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + /* + * If we end this ARGV-element by taking the + * rest as an arg, we must advance to the next + * element now. + */ + d->custom_optind++; + } else if (d->custom_optind == argc) { + if (print_errors) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + d->custom_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* + * We already incremented `custom_optind' once; + * increment it again when taking next ARGV-elt + * as argument. + */ + d->custom_optarg = argv[d->custom_optind++]; + d->nextchar = NULL; + } + } + return c; +} + +/* + * Scan elements of ARGV for option characters given in OPTSTRING. + * + * If an element of ARGV starts with '-', and is not exactly "-" or "--", + * then it is an option element. The characters of this element + * (aside from the initial '-') are option characters. If `getopt' + * is called repeatedly, it returns successively each of the option characters + * from each of the option elements. + * + * If `getopt' finds another option character, it returns that character, + * updating `custom_optind' and `nextchar' so that the next call to `getopt' can + * resume the scan with the following option character or ARGV-element. + * + * If there are no more option characters, `getopt' returns -1. + * Then `custom_optind' is the index in ARGV of the first ARGV-element + * that is not an option. (The ARGV-elements have been permuted + * so that those that are not options now come last.) + * + * OPTSTRING is a string containing the legitimate option characters. + * If an option character is seen that is not listed in OPTSTRING, + * return '?' after printing an error message. If you set `custom_opterr' to + * zero, the error message is suppressed but we still return '?'. + * + * If a char in OPTSTRING is followed by a colon, that means it wants an arg, + * so the following text in the same ARGV-element, or the text of the following + * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that + * wants an optional arg; if there is text in the current ARGV-element, + * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. + * + * If OPTSTRING starts with `-' or `+', it requests different methods of + * handling the non-option ARGV-elements. + * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + * + * Long-named options begin with `--' instead of `-'. + * Their names may be abbreviated as long as the abbreviation is unique + * or is an exact match for some defined option. If they have an + * argument, it follows the option name in the same ARGV-element, separated + * from the option name by a `=', or else the in next ARGV-element. + * When `getopt' finds a long-named option, it returns 0 if that option's + * `flag' field is nonzero, the value of the option's `val' field + * if the `flag' field is zero. + * + * The elements of ARGV aren't really const, because we permute them. + * But we pretend they're const in the prototype to be compatible + * with other systems. + * + * LONGOPTS is a vector of `struct option' terminated by an + * element containing a name which is zero. + * + * LONGIND returns the index in LONGOPT of the long-named option found. + * It is only valid when a long-named option has been found by the most + * recent call. + * + * Return the option character from OPTS just read. Return -1 when there are + * no more options. For unrecognized options, or options missing arguments, + * `custom_optopt' is set to the option letter, and '?' is returned. + * + * The OPTS string is a list of characters which are recognized option letters, + * optionally followed by colons, specifying that that letter takes an + * argument, to be placed in `custom_optarg'. + * + * If a letter in OPTS is followed by two colons, its argument is optional. + * This behavior is specific to the GNU `getopt'. + * + * The argument `--' causes premature termination of argument scanning, + * explicitly telling `getopt' that there are no more options. If OPTS begins + * with `--', then non-option arguments are treated as arguments to the option + * '\0'. This behavior is specific to the GNU `getopt'. + */ + +static int getopt_internal_r(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + struct custom_getopt_data *d) +{ + int ret, print_errors = d->custom_opterr; + + if (optstring[0] == ':') + print_errors = 0; + if (argc < 1) + return -1; + d->custom_optarg = NULL; + + /* + * This is a big difference with GNU getopt, since optind == 0 + * means initialization while here 1 means first call. + */ + if (d->custom_optind == 0 || !d->initialized) { + if (d->custom_optind == 0) + d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ + custom_getopt_initialize(d); + } + if (d->nextchar == NULL || *d->nextchar == '\0') { + ret = shuffle_argv(argc, argv, longopts, d); + if (ret) + return ret; + } + if (longopts && (argv[d->custom_optind][1] == '-' )) + return check_long_opt(argc, argv, optstring, longopts, + longind, print_errors, d); + return check_short_opt(argc, argv, optstring, print_errors, d); +} + +static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind) +{ + int result; + /* Keep a global copy of all internal members of d */ + static struct custom_getopt_data d; + + d.custom_optind = custom_optind; + d.custom_opterr = custom_opterr; + result = getopt_internal_r(argc, argv, optstring, longopts, + longind, &d); + custom_optind = d.custom_optind; + custom_optarg = d.custom_optarg; + custom_optopt = d.custom_optopt; + return result; +} + +static int custom_getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return custom_getopt_internal(argc, argv, options, long_options, + opt_index); +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) + { + if (short_opt != '-') + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + +/** + * @brief store information about a multiple option in a temporary list + * @param list where to (temporarily) store multiple options + */ +static +int update_multiple_arg_temp(struct generic_list **list, + unsigned int *prev_given, const char *val, + const char *possible_values[], const char *default_value, + cmdline_parser_arg_type arg_type, + const char *long_opt, char short_opt, + const char *additional_error) +{ + /* store single arguments */ + char *multi_token; + const char *multi_next; + + if (arg_type == ARG_NO) { + (*prev_given)++; + return 0; /* OK */ + } + + multi_token = get_multiple_arg_token(val); + multi_next = get_multiple_arg_token_next (val); + + while (1) + { + add_node (list); + if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0, + prev_given, multi_token, possible_values, default_value, + arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) { + if (multi_token) free(multi_token); + return 1; /* failure */ + } + + if (multi_next) + { + multi_token = get_multiple_arg_token(multi_next); + multi_next = get_multiple_arg_token_next (multi_next); + } + else + break; + } + + return 0; /* OK */ +} + +/** + * @brief free the passed list (including possible string argument) + */ +static +void free_list(struct generic_list *list, short string_arg) +{ + if (list) { + struct generic_list *tmp; + while (list) + { + tmp = list; + if (string_arg && list->arg.string_arg) + free (list->arg.string_arg); + if (list->orig) + free (list->orig); + list = list->next; + free (tmp); + } + } +} + +/** + * @brief updates a multiple option starting from the passed list + */ +static +void update_multiple_arg(void *field, char ***orig_field, + unsigned int field_given, unsigned int prev_given, union generic_value *default_value, + cmdline_parser_arg_type arg_type, + struct generic_list *list) +{ + int i; + struct generic_list *tmp; + + if (prev_given && list) { + *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); + + switch(arg_type) { + case ARG_INT: + *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break; + case ARG_STRING: + *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break; + default: + break; + }; + + for (i = (prev_given - 1); i >= 0; --i) + { + tmp = list; + + switch(arg_type) { + case ARG_INT: + (*((int **)field))[i + field_given] = tmp->arg.int_arg; break; + case ARG_STRING: + (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break; + default: + break; + } + (*orig_field) [i + field_given] = list->orig; + list = list->next; + free (tmp); + } + } else { /* set the default value */ + if (default_value && ! field_given) { + switch(arg_type) { + case ARG_INT: + if (! *((int **)field)) { + *((int **)field) = (int *)malloc (sizeof (int)); + (*((int **)field))[0] = default_value->int_arg; + } + break; + case ARG_STRING: + if (! *((char ***)field)) { + *((char ***)field) = (char **)malloc (sizeof (char *)); + (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg); + } + break; + default: break; + } + if (!(*orig_field)) { + *orig_field = (char **) malloc (sizeof (char *)); + (*orig_field)[0] = 0; + } + } + } +} + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + struct generic_list * certificate_list = NULL; + struct generic_list * read_dg_list = NULL; + struct generic_list * out_file_list = NULL; + struct generic_list * write_dg_list = NULL; + struct generic_list * in_file_list = NULL; + struct generic_list * delete_dg_list = NULL; + struct generic_list * create_dg_list = NULL; + struct generic_list * new_read_ac_chatbit_list = NULL; + struct generic_list * new_write_ac_chatbit_list = NULL; + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + char *optarg; + int optind; + int opterr; + int optopt; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "reader", 1, NULL, 'r' }, + { "verbose", 0, NULL, 'v' }, + { "verify-pin", 0, NULL, 'p' }, + { "verify-bio", 0, NULL, 'b' }, + { "verify-pin-or-bio", 0, NULL, 0 }, + { "new-pin", 0, NULL, 0 }, + { "new-bio", 0, NULL, 0 }, + { "info", 0, NULL, 0 }, + { "certificate", 1, NULL, 'c' }, + { "key", 1, NULL, 'k' }, + { "print-cardid", 0, NULL, 0 }, + { "write-cardid", 1, NULL, 0 }, + { "print-paccessid", 0, NULL, 0 }, + { "write-paccessid", 1, NULL, 0 }, + { "read-dg", 1, NULL, 0 }, + { "out-file", 1, NULL, 0 }, + { "write-dg", 1, NULL, 0 }, + { "in-file", 1, NULL, 0 }, + { "delete-dg", 1, NULL, 0 }, + { "create-dg", 1, NULL, 0 }, + { "new-size", 1, NULL, 0 }, + { "new-read-ac", 1, NULL, 0 }, + { "new-read-ac-chatbit", 1, NULL, 0 }, + { "new-write-ac", 1, NULL, 0 }, + { "new-write-ac-chatbit", 1, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + custom_optarg = optarg; + custom_optind = optind; + custom_opterr = opterr; + custom_optopt = optopt; + + c = custom_getopt_long (argc, argv, "hVr:vpbc:k:", long_options, &option_index); + + optarg = custom_optarg; + optind = custom_optind; + opterr = custom_opterr; + optopt = custom_optopt; + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'r': /* Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ + + + if (update_arg( (void *)&(args_info->reader_arg), + &(args_info->reader_orig), &(args_info->reader_given), + &(local_args_info.reader_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "reader", 'r', + additional_error)) + goto failure; + + break; + case 'v': /* Use (several times) to be more verbose. */ + + local_args_info.verbose_given++; + + break; + case 'p': /* Verify PIN. */ + + + if (update_arg( 0 , + 0 , &(args_info->verify_pin_given), + &(local_args_info.verify_pin_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "verify-pin", 'p', + additional_error)) + goto failure; + + break; + case 'b': /* Verify finger print. */ + + + if (update_arg( 0 , + 0 , &(args_info->verify_bio_given), + &(local_args_info.verify_bio_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "verify-bio", 'b', + additional_error)) + goto failure; + + break; + case 'c': /* Use (several times) to pass CV certificates. */ + + if (update_multiple_arg_temp(&certificate_list, + &(local_args_info.certificate_given), optarg, 0, 0, ARG_STRING, + "certificate", 'c', + additional_error)) + goto failure; + + break; + case 'k': /* Private key for the CV certificate. */ + + + if (update_arg( (void *)&(args_info->key_arg), + &(args_info->key_orig), &(args_info->key_given), + &(local_args_info.key_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "key", 'k', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + /* Verify PIN or finger print (user's choice). */ + if (strcmp (long_options[option_index].name, "verify-pin-or-bio") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->verify_pin_or_bio_given), + &(local_args_info.verify_pin_or_bio_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "verify-pin-or-bio", '-', + additional_error)) + goto failure; + + } + /* Change PIN. */ + else if (strcmp (long_options[option_index].name, "new-pin") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->new_pin_given), + &(local_args_info.new_pin_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "new-pin", '-', + additional_error)) + goto failure; + + } + /* Use (several times) to change one or more biometric templates. */ + else if (strcmp (long_options[option_index].name, "new-bio") == 0) + { + + local_args_info.new_bio_given++; + + } + /* Dump Information about the SoCManager's configuration. */ + else if (strcmp (long_options[option_index].name, "info") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->info_given), + &(local_args_info.info_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "info", '-', + additional_error)) + goto failure; + + } + /* Print the card ID. */ + else if (strcmp (long_options[option_index].name, "print-cardid") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->print_cardid_given), + &(local_args_info.print_cardid_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "print-cardid", '-', + additional_error)) + goto failure; + + } + /* Write the specified card ID. */ + else if (strcmp (long_options[option_index].name, "write-cardid") == 0) + { + + + if (update_arg( (void *)&(args_info->write_cardid_arg), + &(args_info->write_cardid_orig), &(args_info->write_cardid_given), + &(local_args_info.write_cardid_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "write-cardid", '-', + additional_error)) + goto failure; + + } + /* Print the PAccess ID. */ + else if (strcmp (long_options[option_index].name, "print-paccessid") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->print_paccessid_given), + &(local_args_info.print_paccessid_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "print-paccessid", '-', + additional_error)) + goto failure; + + } + /* Write the specified PAccess ID. */ + else if (strcmp (long_options[option_index].name, "write-paccessid") == 0) + { + + + if (update_arg( (void *)&(args_info->write_paccessid_arg), + &(args_info->write_paccessid_orig), &(args_info->write_paccessid_given), + &(local_args_info.write_paccessid_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "write-paccessid", '-', + additional_error)) + goto failure; + + } + /* Read the specified data group; use several times to read out multiple files. */ + else if (strcmp (long_options[option_index].name, "read-dg") == 0) + { + + if (update_multiple_arg_temp(&read_dg_list, + &(local_args_info.read_dg_given), optarg, 0, 0, ARG_INT, + "read-dg", '-', + additional_error)) + goto failure; + + } + /* Write output to a file instead of printing it; use once for each use of `--read-dg'. */ + else if (strcmp (long_options[option_index].name, "out-file") == 0) + { + + if (update_multiple_arg_temp(&out_file_list, + &(local_args_info.out_file_given), optarg, 0, 0, ARG_STRING, + "out-file", '-', + additional_error)) + goto failure; + + } + /* Write the specified data group; use several times to write multiple files. */ + else if (strcmp (long_options[option_index].name, "write-dg") == 0) + { + + if (update_multiple_arg_temp(&write_dg_list, + &(local_args_info.write_dg_given), optarg, 0, 0, ARG_INT, + "write-dg", '-', + additional_error)) + goto failure; + + } + /* Read input from a file; use once for each use of `--write-dg'. */ + else if (strcmp (long_options[option_index].name, "in-file") == 0) + { + + if (update_multiple_arg_temp(&in_file_list, + &(local_args_info.in_file_given), optarg, 0, 0, ARG_STRING, + "in-file", '-', + additional_error)) + goto failure; + + } + /* Delete the specified data group; use several times to delete multiple files. */ + else if (strcmp (long_options[option_index].name, "delete-dg") == 0) + { + + if (update_multiple_arg_temp(&delete_dg_list, + &(local_args_info.delete_dg_given), optarg, 0, 0, ARG_INT, + "delete-dg", '-', + additional_error)) + goto failure; + + } + /* Create the specified data group; use several times to create multiple files. */ + else if (strcmp (long_options[option_index].name, "create-dg") == 0) + { + + if (update_multiple_arg_temp(&create_dg_list, + &(local_args_info.create_dg_given), optarg, 0, 0, ARG_INT, + "create-dg", '-', + additional_error)) + goto failure; + + } + /* File size of newly created DGs. */ + else if (strcmp (long_options[option_index].name, "new-size") == 0) + { + + + if (update_arg( (void *)&(args_info->new_size_arg), + &(args_info->new_size_orig), &(args_info->new_size_given), + &(local_args_info.new_size_given), optarg, 0, "256", ARG_INT, + check_ambiguity, override, 0, 0, + "new-size", '-', + additional_error)) + goto failure; + + } + /* Access condition for reading newly created DGs. */ + else if (strcmp (long_options[option_index].name, "new-read-ac") == 0) + { + + + if (update_arg( (void *)&(args_info->new_read_ac_arg), + &(args_info->new_read_ac_orig), &(args_info->new_read_ac_given), + &(local_args_info.new_read_ac_given), optarg, cmdline_parser_new_read_ac_values, "sm", ARG_STRING, + check_ambiguity, override, 0, 0, + "new-read-ac", '-', + additional_error)) + goto failure; + + } + /* Required access bits in certificate's CHAT for reading newly created DGs. */ + else if (strcmp (long_options[option_index].name, "new-read-ac-chatbit") == 0) + { + + if (update_multiple_arg_temp(&new_read_ac_chatbit_list, + &(local_args_info.new_read_ac_chatbit_given), optarg, 0, 0, ARG_INT, + "new-read-ac-chatbit", '-', + additional_error)) + goto failure; + + } + /* Access condition for writing newly created DGs. */ + else if (strcmp (long_options[option_index].name, "new-write-ac") == 0) + { + + + if (update_arg( (void *)&(args_info->new_write_ac_arg), + &(args_info->new_write_ac_orig), &(args_info->new_write_ac_given), + &(local_args_info.new_write_ac_given), optarg, cmdline_parser_new_write_ac_values, "sm", ARG_STRING, + check_ambiguity, override, 0, 0, + "new-write-ac", '-', + additional_error)) + goto failure; + + } + /* Required access bits in certificate's CHAT for reading newly created DGs. */ + else if (strcmp (long_options[option_index].name, "new-write-ac-chatbit") == 0) + { + + if (update_multiple_arg_temp(&new_write_ac_chatbit_list, + &(local_args_info.new_write_ac_chatbit_given), optarg, 0, 0, ARG_INT, + "new-write-ac-chatbit", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + update_multiple_arg((void *)&(args_info->certificate_arg), + &(args_info->certificate_orig), args_info->certificate_given, + local_args_info.certificate_given, 0, + ARG_STRING, certificate_list); + update_multiple_arg((void *)&(args_info->read_dg_arg), + &(args_info->read_dg_orig), args_info->read_dg_given, + local_args_info.read_dg_given, 0, + ARG_INT, read_dg_list); + update_multiple_arg((void *)&(args_info->out_file_arg), + &(args_info->out_file_orig), args_info->out_file_given, + local_args_info.out_file_given, 0, + ARG_STRING, out_file_list); + update_multiple_arg((void *)&(args_info->write_dg_arg), + &(args_info->write_dg_orig), args_info->write_dg_given, + local_args_info.write_dg_given, 0, + ARG_INT, write_dg_list); + update_multiple_arg((void *)&(args_info->in_file_arg), + &(args_info->in_file_orig), args_info->in_file_given, + local_args_info.in_file_given, 0, + ARG_STRING, in_file_list); + update_multiple_arg((void *)&(args_info->delete_dg_arg), + &(args_info->delete_dg_orig), args_info->delete_dg_given, + local_args_info.delete_dg_given, 0, + ARG_INT, delete_dg_list); + update_multiple_arg((void *)&(args_info->create_dg_arg), + &(args_info->create_dg_orig), args_info->create_dg_given, + local_args_info.create_dg_given, 0, + ARG_INT, create_dg_list); + update_multiple_arg((void *)&(args_info->new_read_ac_chatbit_arg), + &(args_info->new_read_ac_chatbit_orig), args_info->new_read_ac_chatbit_given, + local_args_info.new_read_ac_chatbit_given, 0, + ARG_INT, new_read_ac_chatbit_list); + update_multiple_arg((void *)&(args_info->new_write_ac_chatbit_arg), + &(args_info->new_write_ac_chatbit_orig), args_info->new_write_ac_chatbit_given, + local_args_info.new_write_ac_chatbit_given, 0, + ARG_INT, new_write_ac_chatbit_list); + + args_info->verbose_given += local_args_info.verbose_given; + local_args_info.verbose_given = 0; + args_info->new_bio_given += local_args_info.new_bio_given; + local_args_info.new_bio_given = 0; + args_info->certificate_given += local_args_info.certificate_given; + local_args_info.certificate_given = 0; + args_info->read_dg_given += local_args_info.read_dg_given; + local_args_info.read_dg_given = 0; + args_info->out_file_given += local_args_info.out_file_given; + local_args_info.out_file_given = 0; + args_info->write_dg_given += local_args_info.write_dg_given; + local_args_info.write_dg_given = 0; + args_info->in_file_given += local_args_info.in_file_given; + local_args_info.in_file_given = 0; + args_info->delete_dg_given += local_args_info.delete_dg_given; + local_args_info.delete_dg_given = 0; + args_info->create_dg_given += local_args_info.create_dg_given; + local_args_info.create_dg_given = 0; + args_info->new_read_ac_chatbit_given += local_args_info.new_read_ac_chatbit_given; + local_args_info.new_read_ac_chatbit_given = 0; + args_info->new_write_ac_chatbit_given += local_args_info.new_write_ac_chatbit_given; + local_args_info.new_write_ac_chatbit_given = 0; + + if (check_required) + { + error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error); + } + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + return 0; + +failure: + free_list (certificate_list, 1 ); + free_list (read_dg_list, 0 ); + free_list (out_file_list, 1 ); + free_list (write_dg_list, 0 ); + free_list (in_file_list, 1 ); + free_list (delete_dg_list, 0 ); + free_list (create_dg_list, 0 ); + free_list (new_read_ac_chatbit_list, 0 ); + free_list (new_write_ac_chatbit_list, 0 ); + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/src/tools/goid-tool-cmdline.h b/src/tools/goid-tool-cmdline.h new file mode 100644 index 0000000000..0473189c80 --- /dev/null +++ b/src/tools/goid-tool-cmdline.h @@ -0,0 +1,280 @@ +/** @file goid-tool-cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.6 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef GOID_TOOL_CMDLINE_H +#define GOID_TOOL_CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "goid-tool" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "goid-tool" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * reader_arg; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen.. */ + char * reader_orig; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. original value given at command line. */ + const char *reader_help; /**< @brief Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen. help description. */ + unsigned int verbose_min; /**< @brief Use (several times) to be more verbose's minimum occurreces */ + unsigned int verbose_max; /**< @brief Use (several times) to be more verbose's maximum occurreces */ + const char *verbose_help; /**< @brief Use (several times) to be more verbose help description. */ + const char *verify_pin_help; /**< @brief Verify PIN help description. */ + const char *verify_bio_help; /**< @brief Verify finger print help description. */ + const char *verify_pin_or_bio_help; /**< @brief Verify PIN or finger print (user's choice) help description. */ + const char *new_pin_help; /**< @brief Change PIN help description. */ + unsigned int new_bio_min; /**< @brief Use (several times) to change one or more biometric templates's minimum occurreces */ + unsigned int new_bio_max; /**< @brief Use (several times) to change one or more biometric templates's maximum occurreces */ + const char *new_bio_help; /**< @brief Use (several times) to change one or more biometric templates help description. */ + const char *info_help; /**< @brief Dump Information about the SoCManager's configuration help description. */ + char ** certificate_arg; /**< @brief Use (several times) to pass CV certificates. */ + char ** certificate_orig; /**< @brief Use (several times) to pass CV certificates original value given at command line. */ + unsigned int certificate_min; /**< @brief Use (several times) to pass CV certificates's minimum occurreces */ + unsigned int certificate_max; /**< @brief Use (several times) to pass CV certificates's maximum occurreces */ + const char *certificate_help; /**< @brief Use (several times) to pass CV certificates help description. */ + char * key_arg; /**< @brief Private key for the CV certificate. */ + char * key_orig; /**< @brief Private key for the CV certificate original value given at command line. */ + const char *key_help; /**< @brief Private key for the CV certificate help description. */ + const char *print_cardid_help; /**< @brief Print the card ID help description. */ + char * write_cardid_arg; /**< @brief Write the specified card ID. */ + char * write_cardid_orig; /**< @brief Write the specified card ID original value given at command line. */ + const char *write_cardid_help; /**< @brief Write the specified card ID help description. */ + const char *print_paccessid_help; /**< @brief Print the PAccess ID help description. */ + char * write_paccessid_arg; /**< @brief Write the specified PAccess ID. */ + char * write_paccessid_orig; /**< @brief Write the specified PAccess ID original value given at command line. */ + const char *write_paccessid_help; /**< @brief Write the specified PAccess ID help description. */ + int* read_dg_arg; /**< @brief Read the specified data group; use several times to read out multiple files. */ + char ** read_dg_orig; /**< @brief Read the specified data group; use several times to read out multiple files original value given at command line. */ + unsigned int read_dg_min; /**< @brief Read the specified data group; use several times to read out multiple files's minimum occurreces */ + unsigned int read_dg_max; /**< @brief Read the specified data group; use several times to read out multiple files's maximum occurreces */ + const char *read_dg_help; /**< @brief Read the specified data group; use several times to read out multiple files help description. */ + char ** out_file_arg; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg'. */ + char ** out_file_orig; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg' original value given at command line. */ + unsigned int out_file_min; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg''s minimum occurreces */ + unsigned int out_file_max; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg''s maximum occurreces */ + const char *out_file_help; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg' help description. */ + int* write_dg_arg; /**< @brief Write the specified data group; use several times to write multiple files. */ + char ** write_dg_orig; /**< @brief Write the specified data group; use several times to write multiple files original value given at command line. */ + unsigned int write_dg_min; /**< @brief Write the specified data group; use several times to write multiple files's minimum occurreces */ + unsigned int write_dg_max; /**< @brief Write the specified data group; use several times to write multiple files's maximum occurreces */ + const char *write_dg_help; /**< @brief Write the specified data group; use several times to write multiple files help description. */ + char ** in_file_arg; /**< @brief Read input from a file; use once for each use of `--write-dg'. */ + char ** in_file_orig; /**< @brief Read input from a file; use once for each use of `--write-dg' original value given at command line. */ + unsigned int in_file_min; /**< @brief Read input from a file; use once for each use of `--write-dg''s minimum occurreces */ + unsigned int in_file_max; /**< @brief Read input from a file; use once for each use of `--write-dg''s maximum occurreces */ + const char *in_file_help; /**< @brief Read input from a file; use once for each use of `--write-dg' help description. */ + int* delete_dg_arg; /**< @brief Delete the specified data group; use several times to delete multiple files. */ + char ** delete_dg_orig; /**< @brief Delete the specified data group; use several times to delete multiple files original value given at command line. */ + unsigned int delete_dg_min; /**< @brief Delete the specified data group; use several times to delete multiple files's minimum occurreces */ + unsigned int delete_dg_max; /**< @brief Delete the specified data group; use several times to delete multiple files's maximum occurreces */ + const char *delete_dg_help; /**< @brief Delete the specified data group; use several times to delete multiple files help description. */ + int* create_dg_arg; /**< @brief Create the specified data group; use several times to create multiple files. */ + char ** create_dg_orig; /**< @brief Create the specified data group; use several times to create multiple files original value given at command line. */ + unsigned int create_dg_min; /**< @brief Create the specified data group; use several times to create multiple files's minimum occurreces */ + unsigned int create_dg_max; /**< @brief Create the specified data group; use several times to create multiple files's maximum occurreces */ + const char *create_dg_help; /**< @brief Create the specified data group; use several times to create multiple files help description. */ + int new_size_arg; /**< @brief File size of newly created DGs (default='256'). */ + char * new_size_orig; /**< @brief File size of newly created DGs original value given at command line. */ + const char *new_size_help; /**< @brief File size of newly created DGs help description. */ + char * new_read_ac_arg; /**< @brief Access condition for reading newly created DGs (default='sm'). */ + char * new_read_ac_orig; /**< @brief Access condition for reading newly created DGs original value given at command line. */ + const char *new_read_ac_help; /**< @brief Access condition for reading newly created DGs help description. */ + int* new_read_ac_chatbit_arg; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs. */ + char ** new_read_ac_chatbit_orig; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs original value given at command line. */ + unsigned int new_read_ac_chatbit_min; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs's minimum occurreces */ + unsigned int new_read_ac_chatbit_max; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs's maximum occurreces */ + const char *new_read_ac_chatbit_help; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs help description. */ + char * new_write_ac_arg; /**< @brief Access condition for writing newly created DGs (default='sm'). */ + char * new_write_ac_orig; /**< @brief Access condition for writing newly created DGs original value given at command line. */ + const char *new_write_ac_help; /**< @brief Access condition for writing newly created DGs help description. */ + int* new_write_ac_chatbit_arg; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs. */ + char ** new_write_ac_chatbit_orig; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs original value given at command line. */ + unsigned int new_write_ac_chatbit_min; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs's minimum occurreces */ + unsigned int new_write_ac_chatbit_max; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs's maximum occurreces */ + const char *new_write_ac_chatbit_help; /**< @brief Required access bits in certificate's CHAT for reading newly created DGs help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int reader_given ; /**< @brief Whether reader was given. */ + unsigned int verbose_given ; /**< @brief Whether verbose was given. */ + unsigned int verify_pin_given ; /**< @brief Whether verify-pin was given. */ + unsigned int verify_bio_given ; /**< @brief Whether verify-bio was given. */ + unsigned int verify_pin_or_bio_given ; /**< @brief Whether verify-pin-or-bio was given. */ + unsigned int new_pin_given ; /**< @brief Whether new-pin was given. */ + unsigned int new_bio_given ; /**< @brief Whether new-bio was given. */ + unsigned int info_given ; /**< @brief Whether info was given. */ + unsigned int certificate_given ; /**< @brief Whether certificate was given. */ + unsigned int key_given ; /**< @brief Whether key was given. */ + unsigned int print_cardid_given ; /**< @brief Whether print-cardid was given. */ + unsigned int write_cardid_given ; /**< @brief Whether write-cardid was given. */ + unsigned int print_paccessid_given ; /**< @brief Whether print-paccessid was given. */ + unsigned int write_paccessid_given ; /**< @brief Whether write-paccessid was given. */ + unsigned int read_dg_given ; /**< @brief Whether read-dg was given. */ + unsigned int out_file_given ; /**< @brief Whether out-file was given. */ + unsigned int write_dg_given ; /**< @brief Whether write-dg was given. */ + unsigned int in_file_given ; /**< @brief Whether in-file was given. */ + unsigned int delete_dg_given ; /**< @brief Whether delete-dg was given. */ + unsigned int create_dg_given ; /**< @brief Whether create-dg was given. */ + unsigned int new_size_given ; /**< @brief Whether new-size was given. */ + unsigned int new_read_ac_given ; /**< @brief Whether new-read-ac was given. */ + unsigned int new_read_ac_chatbit_given ; /**< @brief Whether new-read-ac-chatbit was given. */ + unsigned int new_write_ac_given ; /**< @brief Whether new-write-ac was given. */ + unsigned int new_write_ac_chatbit_given ; /**< @brief Whether new-write-ac-chatbit was given. */ + +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + +extern const char *cmdline_parser_new_read_ac_values[]; /**< @brief Possible values for new-read-ac. */ +extern const char *cmdline_parser_new_write_ac_values[]; /**< @brief Possible values for new-write-ac. */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* GOID_TOOL_CMDLINE_H */ diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c new file mode 100644 index 0000000000..007795393c --- /dev/null +++ b/src/tools/goid-tool.c @@ -0,0 +1,795 @@ +/* + * Copyright (C) 2018 Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fread_to_eof.h" +#include +#include "goid-tool-cmdline.h" +#include "libopensc/asn1.h" +#include "libopensc/log.h" +#include "libopensc/opensc.h" +#include "sm/sm-eac.h" +#ifdef ENABLE_OPENPACE +#include +#endif +#include +#include "util.h" +#include + +const unsigned char aid_soc_manager[] = { + 0xD2, 0x76, 0x00, 0x01, 0x72, 0x53, 0x6F, 0x43, 0x4D, 0x01 +}; +static const unsigned char paccess_aid[] = { + 0xD2, 0x76, 0x00, 0x01, 0x72, 0x50, 0x41, 0x63, 0x63, 0x01, +}; +static const char *app_name = "goid-tool"; + +void +print_permissions(u8 permissions) +{ + size_t perms_printed = 0; + if (permissions & 0x80) { + printf("%s PIN", perms_printed ? " or" : "verification of"); + perms_printed++; + } + if (permissions & 0x40) { + printf("%s BIO", perms_printed ? " or" : "verification of"); + perms_printed++; + } + if (permissions & 0x20) { + printf("%s GP key", perms_printed ? " or" : "verification of"); + perms_printed++; + } + printf("\n"); +} + +void +soc_info(sc_context_t *ctx, sc_card_t *card) +{ + sc_apdu_t apdu; + unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 information_applets[SC_MAX_APDU_BUFFER_SIZE]; + size_t information_applets_len = sizeof information_applets; + int pin_initialized = 0, bio_initialized = 0; + int pin_max_retries = 0, pin_cur_retries = 0, bio_max_retries = 0, bio_cur_retries = 0; + int pin_length = 0; + u8 pin_unblock = 0, pin_change = 0, bio_unblock = 0, bio_change = 0; + size_t pin_change_len = sizeof pin_change, pin_unblock_len = sizeof pin_unblock, + bio_change_len = sizeof bio_change, bio_unblock_len = sizeof bio_unblock; + int bio_count = 0; + u8 bio_initialized_templates[2]; + size_t bio_initialized_templates_len = sizeof bio_initialized_templates; + + struct sc_asn1_entry rapdu_get_information[] = { + { "Sequence of (applet register)", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE|SC_ASN1_CONS, 0, NULL, NULL }, + { "Initialized PIN", SC_ASN1_STRUCT, SC_ASN1_APP|SC_ASN1_CONS|0x02, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Initialized BIO", SC_ASN1_STRUCT, SC_ASN1_APP|SC_ASN1_CONS|0x03, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + struct sc_asn1_entry rapdu_get_information_pin[] = { + { "Initialization state of the PIN", SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, 0, NULL, NULL }, + { "maximum remaining tries", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "current remaining tries", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "Unblock requirements Mask", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x1, 0, NULL, NULL }, + { "Change requirements Mask", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x2, 0, NULL, NULL }, + { "PIN size", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + struct sc_asn1_entry rapdu_get_information_bio[] = { + { "Initialization state of the BIO", SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, 0, NULL, NULL }, + { "maximum remaining tries", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "current remaining tries", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "Unblock requirements Mask", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x1, 0, NULL, NULL }, + { "Change requirements Mask", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x2, 0, NULL, NULL }, + { "Min minutiae", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "Max minutiae", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "number of templates", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "Bitmap of initialized templates", SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, + { "Algorithm parameters, allocation strategy", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x61, 0x00, 0x00); + + apdu.cla = 0x80; + apdu.resp = rbuf; + apdu.resplen = sizeof rbuf; + + if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { + return; + } + + sc_format_asn1_entry(rapdu_get_information + 0, information_applets, &information_applets_len, 0); + sc_format_asn1_entry(rapdu_get_information + 1, rapdu_get_information_pin, NULL, 0); + sc_format_asn1_entry(rapdu_get_information + 2, rapdu_get_information_bio, NULL, 0); + + sc_format_asn1_entry(rapdu_get_information_pin + 0, &pin_initialized, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_pin + 1, &pin_max_retries, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_pin + 2, &pin_cur_retries, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_pin + 3, &pin_unblock, &pin_unblock_len, 0); + sc_format_asn1_entry(rapdu_get_information_pin + 4, &pin_change, &pin_change_len, 0); + sc_format_asn1_entry(rapdu_get_information_pin + 5, &pin_length, NULL, 0); + + sc_format_asn1_entry(rapdu_get_information_bio + 0, &bio_initialized, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 1, &bio_max_retries, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 2, &bio_cur_retries, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 3, &bio_unblock, &bio_unblock_len, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 4, &bio_change, &bio_change_len, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 7, &bio_count, NULL, 0); + sc_format_asn1_entry(rapdu_get_information_bio + 8, bio_initialized_templates, &bio_initialized_templates_len, 0); + + if (sc_asn1_decode(ctx, rapdu_get_information, + apdu.resp, apdu.resplen, NULL, NULL) != SC_SUCCESS) { + return; + } + + if (rapdu_get_information[0].flags & SC_ASN1_PRESENT && information_applets_len > 0) { + const unsigned char *p = information_applets, *end = information_applets + information_applets_len; + unsigned int cla = 0, tag = 0; + size_t length = information_applets_len; + + if (SC_SUCCESS == sc_asn1_read_tag(&p, length, &cla, &tag, &length) + && cla == SC_ASN1_TAG_UNIVERSAL && tag == SC_ASN1_TAG_INTEGER) { + int applet_count = 0; + /* number of applets */ + if (SC_SUCCESS == sc_asn1_decode_integer(p, length, &applet_count)) { + printf("SoCManager knows %d applet%s%s\n", applet_count, + applet_count == 1 ? "" : "s", applet_count == 0 ? "" : ":"); + /* AID of client applet #x */ + for (p += length, length = end - p; + p < end; + p += length, length = end - p) { + size_t i; + if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length) + || p == NULL || cla != SC_ASN1_TAG_CONTEXT) { + break; + } + putchar('\t'); + util_hex_dump(stdout, p, length, ""); + /* align with the maximum lenght of an AID */ + for (i = length; i < 0x10 + 1; i++) + printf(" "); + + /* i now counts the number of flags that were printed */ + i = 0; + if (tag & 0x02) { + printf("%sdefault selected", i ? ", " : ""); + i++; + } + if (tag & 0x01) { + printf("%sinteracts with SoCManager", i ? ", " : ""); + i++; + } + if (tag & 0x04) { + printf("%sBIO enabled", i ? ", " : ""); + i++; + } + if (tag & 0x08) { + printf("%sPIN enabled", i ? ", " : ""); + i++; + } + printf("\n"); + } + } + } + } + + if (rapdu_get_information[1].flags & SC_ASN1_PRESENT) { + if (pin_initialized) { + printf("PIN is initialized with %d digits (%d of %d tries left).\n", + pin_length, pin_cur_retries, pin_max_retries); + } else { + printf("PIN is not initialized.\n"); + } + printf("\tChanging PIN requires "); + print_permissions(pin_change); + printf("\tUnblocking PIN requires "); + print_permissions(pin_unblock); + } + + if (rapdu_get_information[2].flags & SC_ASN1_PRESENT) { + if (bio_initialized) { + int bio_used = 0; + size_t i, j; + for (i = 0; i < sizeof bio_initialized_templates; i++) { + for (j = 0; j < 8; j++) { + if (bio_initialized_templates[i] >> j & 0x1) + bio_used++; + } + } + printf("BIO is initialized with %d of %d templates (%d of %d tries left).\n", + bio_used, bio_count, bio_cur_retries, bio_max_retries); + } else { + printf("BIO is not initialized.\n"); + } + printf("\tChanging BIO requires "); + print_permissions(bio_change); + printf("\tUnblocking BIO requires "); + print_permissions(bio_unblock); + } +} + +void +soc_verify(sc_card_t *card, unsigned char p2) +{ + sc_apdu_t apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, p2); + + if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { + return; + } +} + +void +soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) +{ + sc_apdu_t apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x00, p2); + + if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { + return; + } +} + +int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info *cmdline) +{ + int ok = 0; + sc_file_t *file = NULL; + struct sc_path path; + unsigned char soc_manager_minor = 0; + unsigned char soc_manager_major = 0; + + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_soc_manager, sizeof aid_soc_manager, 0, 0); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_select_file(card, &path, &file), "SoCManager not found."); + if (file && file->prop_attr && file->prop_attr_len) { + size_t prop_len = 0; + const u8 *prop = sc_asn1_find_tag(ctx, file->prop_attr, + file->prop_attr_len, 0xA5, &prop_len); + if (prop && prop_len) { + prop = sc_asn1_find_tag(ctx, prop, + prop_len, 0x81, &prop_len); + if (prop && prop_len == 2) { + soc_manager_major = prop[0]; + soc_manager_minor = prop[1]; + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "SoCManager version %u.%u", + soc_manager_major, soc_manager_minor); + } + } + } + + if (cmdline->info_given) { + if ((soc_manager_major == 2 && soc_manager_minor < 7) + || soc_manager_major < 2) + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_NOT_SUPPORTED, "Get Information only supported with version 2.07 and later."); + soc_info(ctx, card); + } + if (cmdline->verify_pin_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify finger print or PIN on the card."); + soc_verify(card, 0x80); + } + if (cmdline->verify_bio_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify finger print on the card."); + soc_verify(card, 0x40); + } + if (cmdline->verify_pin_or_bio_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify finger print or PIN on the card."); + soc_verify(card, 0xC0); + } + + if (cmdline->new_pin_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Initialize the PIN on the card."); + soc_change(card, 0x00, 0x80); + } + if (cmdline->new_bio_given) { + size_t i = 0; + while (i < cmdline->new_bio_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Initialize finger print template %u on the card.", + (unsigned char) i); + soc_change(card, (unsigned char) i, 0x40); + i++; + } + } + + ok = 1; + +err: + return ok; +} + +static int +paccess_construct_fci(struct sc_card *card, const sc_file_t *file, + u8 *out, size_t *outlen) +{ + u8 *p = out; + u8 buf[64]; + + if (*outlen < 2) + return SC_ERROR_BUFFER_TOO_SMALL; + *p++ = 0x62; + p++; + + buf[0] = (file->size >> 8) & 0xFF; + buf[1] = file->size & 0xFF; + sc_asn1_put_tag(0x80, buf, 2, p, *outlen - (p - out), &p); + + buf[0] = (file->id >> 8) & 0xFF; + buf[1] = file->id & 0xFF; + sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p); + + memcpy(buf, file->sec_attr, file->sec_attr_len); + sc_asn1_put_tag(0x86, buf, file->sec_attr_len, + p, *outlen - (p - out), &p); + + buf[0] = file->sid & 0xFF; + sc_asn1_put_tag(0x88, buf, 1, p, *outlen - (p - out), &p); + + out[1] = p - out - 2; + + *outlen = p - out; + return 0; +} + +int +paccess_create_file(struct sc_card *card, size_t size, int fid, u8 *sec_attr, size_t sec_attr_len, int sfid) +{ + int ok = 0; + sc_file_t *file = sc_file_new(); + if (!file) + goto err; + + file->size = size; + file->id = fid; + file->sid = sfid; + file->sec_attr = sec_attr; + file->sec_attr_len = sec_attr_len; + + card->ops->construct_fci = paccess_construct_fci; + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_create_file(card, file), "Create file failed."); + + ok = 1; +err: + return ok; +} + +int +paccess_delete_file(struct sc_card *card, int fid) +{ + int ok = 0; + u8 buf[2]; + struct sc_path path; + buf[0] = (fid >> 8) & 0xFF; + buf[1] = fid & 0xFF; + sc_path_set(&path, SC_PATH_TYPE_FILE_ID, buf, sizeof buf, 0, 0); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_delete_file(card, &path), "Delete file failed."); + ok = 1; +err: + return ok; +} + +int +paccess_get_security_attributes(struct sc_context *ctx, const char *ac, int* chatbits, size_t chatbits_len, u8 sec_attr[2]) +{ + int ok = 0; + memset(sec_attr, 0, 2); + if (!ac || 0 == strcmp(ac, "never")) { + /* nothing else to do */ + } else if (0 == strcmp(ac, "always")) { + sec_attr[0] |= 0xFF; + } else { + size_t i; + if (0 == strcmp(ac, "ta")) { + sec_attr[0] |= 0xA0; + } else if (0 == strcmp(ac, "sm")) { + sec_attr[0] |= 0xC0; + } else { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "unknown access condition."); + } + for (i = 0; i < chatbits_len; i++) { + u8 byte = chatbits[i] / 8; + u8 bit = chatbits[i] % 8 + 1; + if (byte > 5) + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "Only CHAT bits with index 0..39 are available."); + sec_attr[0] |= 0x8 | byte; + sec_attr[1] |= bit; + } + } + ok = 1; +err: + return ok; +} + +int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info *cmdline) +{ + int ok = 0, r; + sc_file_t *file = NULL; + struct sc_path path; + size_t i, ef_cardsecurity_len = 0, privkey_len = 0, *certs_lens = NULL; + unsigned char *ef_cardsecurity = NULL, *privkey = NULL, + **certs = NULL; + unsigned char auxiliary_data[] = {0x67, 0x00}; + unsigned char paccess_minor = 0; + unsigned char paccess_major = 0; + + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, paccess_aid, sizeof paccess_aid, 0, 0); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_select_file(card, &path, &file), "PAccess not found."); + if (file && file->prop_attr && file->prop_attr_len) { + const unsigned char *p, *end; + unsigned int cla = 0, tag = 0; + size_t length; + + for (p = file->prop_attr, length = file->prop_attr_len, end = file->prop_attr + file->prop_attr_len; + p < end; + p += length, length = end - p) { + if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length) + || p == NULL) { + break; + } + switch (cla | tag) { + case 0x81: + if (p && length == 2) { + paccess_major = p[0]; + paccess_minor = p[1]; + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "PAccess version %u.%u", + paccess_major, paccess_minor); + } + break; + case 0x82: + if (p && length == 1) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Number of Session Contexts %u", + p[0]); + } + break; + case 0x87: + sc_debug_hex(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Certificate Authority Reference of the primary CVCA trust anchor", + p, length); + break; + case 0x88: + sc_debug_hex(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Certificate Authority Reference of the secondary CVCA trust anchor", + p, length); + break; + case 0x1fe5: + case 0x9F65: + if (p && length == 2) { + size_t max_command_size = (p[0]<<8)|p[1]; + card->max_recv_size = max_command_size; + card->max_send_size = max_command_size; + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Maximum data length in command message %"SC_FORMAT_LEN_SIZE_T"u bytes", + max_command_size); + } + break; + } + } + } + + if (cmdline->certificate_given || cmdline->key_given) { + if (!fread_to_eof(cmdline->key_arg, + &privkey, &privkey_len)) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "Could not parse private key.\n"); + } + + certs = calloc(sizeof *certs, cmdline->certificate_given + 1); + certs_lens = calloc(sizeof *certs_lens, + cmdline->certificate_given + 1); + if (!certs || !certs_lens) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, SC_ERROR_NOT_ENOUGH_MEMORY, + "Internal error."); + } + for (i = 0; i < cmdline->certificate_given; i++) { + if (!fread_to_eof(cmdline->certificate_arg[i], + (unsigned char **) &certs[i], &certs_lens[i])) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "Could not read certificate.\n"); + } + } + +#ifdef ENABLE_OPENPACE + EAC_init(); +#endif + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + perform_terminal_authentication(card, + (const unsigned char **) certs, certs_lens, + privkey, privkey_len, + auxiliary_data, sizeof auxiliary_data), + "Terminal authentication failed."); + + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + perform_chip_authentication(card, + &ef_cardsecurity, &ef_cardsecurity_len), + "Chip authentication failed."); + } + + for (i = 0; i < cmdline->delete_dg_given; i++) { + int fid = 0x0100 | cmdline->delete_dg_arg[i]; + + if ((paccess_major == 2 && paccess_minor < 6) + || paccess_major < 2) + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_NOT_SUPPORTED, "Create File only supported with version 2.06 and later."); + if (!paccess_delete_file(card, fid)) + goto err; + } + + for (i = 0; i < cmdline->create_dg_given; i++) { + u8 sec_attr[4]; + int fid = 0x0100 | cmdline->create_dg_arg[i]; + + if ((paccess_major == 2 && paccess_minor < 6) + || paccess_major < 2) + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_NOT_SUPPORTED, "Create File only supported with version 2.06 and later."); + + if (cmdline->new_size_arg < 0) + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "`--new-size' needs a positive size.\n"); + if (!paccess_get_security_attributes(ctx, cmdline->new_read_ac_arg, + cmdline->new_read_ac_chatbit_arg, + cmdline->new_read_ac_chatbit_given, sec_attr + 0) + || !paccess_get_security_attributes(ctx, cmdline->new_write_ac_arg, + cmdline->new_write_ac_chatbit_arg, + cmdline->new_write_ac_chatbit_given, sec_attr + 2) + || !paccess_create_file(card, cmdline->new_size_arg, fid, + sec_attr, sizeof sec_attr, cmdline->create_dg_arg[i])) + goto err; + } + + if (cmdline->out_file_given > 0 && cmdline->out_file_given != cmdline->read_dg_given) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "If `--out-file' is specified, it must be used as many times as `--read-dg'.\n"); + } + + for (i = 0; i < cmdline->read_dg_given; i++) { + u8 *ef = NULL; + size_t ef_len = 0; + r = iso7816_read_binary_sfid(card, cmdline->read_dg_arg[i], + &ef, &ef_len); + if (r >= 0) { + if (cmdline->out_file_given == cmdline->read_dg_given) { + FILE *f = fopen(cmdline->out_file_arg[i], "wb"); + if (f) { + fwrite(ef, ef_len, 1, f); + fclose(f); + } else { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Error opening %s: %s\n", + cmdline->out_file_arg[i], strerror(errno)); + r = SC_ERROR_FILE_NOT_FOUND; + } + } else { + char label[32]; + snprintf(label, sizeof label, "Data Group %u", (unsigned char) cmdline->read_dg_arg[i]); + sc_debug_hex(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, label, ef, ef_len); + } + free(ef); + } + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error reading data group."); + } + + if (cmdline->print_cardid_given) { + u8 *ef = NULL; + size_t ef_len = 0; + r = iso7816_read_binary_sfid(card, 0x1E, &ef, &ef_len); + if (r >= 0) { + const u8 *p = ef; + unsigned int cla = 0, tag = 0; + if (SC_SUCCESS == sc_asn1_read_tag(&p, ef_len, + &cla, &tag, &ef_len) + && (tag | cla) == 0x7E + && SC_SUCCESS == sc_asn1_read_tag(&p, ef_len, + &cla, &tag, &ef_len) + && (tag | cla) == 0x13) { + const char *cardid = (const char *) p; + while (cardid && ef_len) { + if (isprint(*cardid)) { + printf("%c", *cardid); + } else { + printf("."); + } + cardid++; + ef_len--; + } + if (cardid) + printf("\n"); + } else { + r = SC_ERROR_INVALID_DATA; + } + } + free(ef); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error reading card ID."); + } + + if (cmdline->print_paccessid_given) { + u8 *ef = NULL; + size_t ef_len = 0; + r = iso7816_read_binary_sfid(card, 0x06, &ef, &ef_len); + if (r >= 0) { + const u8 *p = ef; + unsigned int cla = 0, tag = 0; + if (SC_SUCCESS == sc_asn1_read_tag(&p, ef_len, + &cla, &tag, &ef_len) + && (tag | cla) == 0x66 + && SC_SUCCESS == sc_asn1_read_tag((const u8 **) &p, ef_len, + &cla, &tag, &ef_len) + && (tag | cla) == 0x13) { + const char *paccessid = (const char *) p; + while (paccessid && ef_len) { + if (isprint(*paccessid)) { + printf("%c", *paccessid); + } else { + printf("."); + } + paccessid++; + ef_len--; + } + if (paccessid) + printf("\n"); + } else { + r = SC_ERROR_INVALID_DATA; + } + } + free(ef); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error reading card ID."); + } + + if (cmdline->in_file_given != cmdline->write_dg_given) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "If `--in-file' is specified, it must be used as many times as `--write-dg'.\n"); + } + + for (i = 0; i < cmdline->write_dg_given; i++) { + u8 *ef = NULL; + size_t ef_len = 0; + if (!fread_to_eof(cmdline->in_file_arg[i], + &ef, &ef_len)) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + SC_ERROR_INVALID_ARGUMENTS, "Could not read input file.\n"); + } + r = iso7816_update_binary_sfid(card, cmdline->write_dg_arg[i], ef, ef_len); + free(ef); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error writing data group."); + } + + if (cmdline->write_cardid_arg) { + size_t cardid_len = strlen(cmdline->write_cardid_arg); + u8 ef[256]; + if (cardid_len > (sizeof ef) - 4) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, SC_ERROR_INVALID_ARGUMENTS, + "Card ID too long."); + } + ef[0] = 0x7E; + ef[1] = 2 + cardid_len; + ef[2] = 0x13; + ef[3] = cardid_len; + memcpy(ef + 4, cmdline->write_cardid_arg, cardid_len); + r = iso7816_update_binary_sfid(card, 0x1E, ef, 4 + cardid_len); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error writing card ID."); + } + + if (cmdline->write_paccessid_arg) { + size_t paccessid_len = strlen(cmdline->write_paccessid_arg); + u8 ef[256]; + if (paccessid_len > (sizeof ef) - 4) { + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, SC_ERROR_INVALID_ARGUMENTS, + "Card ID too long."); + } + ef[0] = 0x66; + ef[1] = 2 + paccessid_len; + ef[2] = 0x13; + ef[3] = paccessid_len; + memcpy(ef + 4, cmdline->write_paccessid_arg, paccessid_len); + r = iso7816_update_binary_sfid(card, 0x06, ef, 4 + paccessid_len); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error writing PAccess ID."); + } + + ok = 1; + +err: + if (certs) { + for (i = 0; certs[i]; i++) { + free((unsigned char *) certs[i]); + } + free(certs); + } + free(ef_cardsecurity); + free(certs_lens); + free(privkey); + sc_file_free(file); + + return ok; +} + +int +main(int argc, char **argv) +{ + struct gengetopt_args_info cmdline; + struct sc_context *ctx = NULL; + struct sc_card *card = NULL; + int r, fail = 1; + sc_context_param_t ctx_param; + + if (cmdline_parser(argc, argv, &cmdline) != 0) + exit(1); + + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = app_name; + + r = sc_context_create(&ctx, &ctx_param); + if (r) { + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); + exit(1); + } + + if (cmdline.verbose_given > 1) { + ctx->debug = cmdline.verbose_given; + sc_ctx_log_to_file(ctx, "stderr"); + } + + r = sc_set_card_driver(ctx, "default"); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error selecting card driver."); + + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, + "Error connecting to card."); + + if (!soc_main(ctx, card, &cmdline) || !paccess_main(ctx, card, &cmdline)) + goto err; + + fail = 0; + +err: + sc_disconnect_card(card); + sc_release_context(ctx); + cmdline_parser_free (&cmdline); + + return fail; +} +/*printf("%s:%d\n", __FILE__, __LINE__);*/ diff --git a/src/tools/goid-tool.ggo.in b/src/tools/goid-tool.ggo.in new file mode 100644 index 0000000000..1faf085b02 --- /dev/null +++ b/src/tools/goid-tool.ggo.in @@ -0,0 +1,87 @@ +package "goid-tool" +purpose "@PACKAGE_SUMMARY@" + +option "reader" r + "Number of the reader to use. By default, the first reader with a present card is used. If the arguement is an ATR, the reader with a matching card will be chosen." + string optional +option "verbose" v + "Use (several times) to be more verbose" + multiple optional + +section "SoCManager Applet" +option "verify-pin" p + "Verify PIN" + optional +option "verify-bio" b + "Verify finger print" + optional +option "verify-pin-or-bio" - + "Verify PIN or finger print (user's choice)" + optional +option "new-pin" - + "Change PIN" + optional +option "new-bio" - + "Use (several times) to change one or more biometric templates" + multiple optional +option "info" - + "Dump Information about the SoCManager's configuration" + optional + +section "PAccess Applet" +option "certificate" c + "Use (several times) to pass CV certificates" + string multiple optional dependon="key" typestr="FILENAME" +option "key" k + "Private key for the CV certificate" + string optional dependon="certificate" typestr="FILENAME" +option "print-cardid" - + "Print the card ID" + optional +option "write-cardid" - + "Write the specified card ID" + string optional typestr="CARDID" +option "print-paccessid" - + "Print the PAccess ID" + optional +option "write-paccessid" - + "Write the specified PAccess ID" + string optional typestr="PACCESSID" +option "read-dg" - + "Read the specified data group; use several times to read out multiple files" + int optional multiple typestr="ID" +option "out-file" - + "Write output to a file instead of printing it; use once for each use of `--read-dg'" + string optional multiple typestr="FILENAME" +option "write-dg" - + "Write the specified data group; use several times to write multiple files" + int optional multiple typestr="ID" +option "in-file" - + "Read input from a file; use once for each use of `--write-dg'" + string optional multiple typestr="FILENAME" +option "delete-dg" - + "Delete the specified data group; use several times to delete multiple files" + int optional multiple typestr="ID" +option "create-dg" - + "Create the specified data group; use several times to create multiple files" + int optional multiple typestr="ID" +option "new-size" - + "File size of newly created DGs" + int optional dependon="create-dg" typestr="SIZE" default="256" +option "new-read-ac" - + "Access condition for reading newly created DGs" + values="always","never","ta","sm" default="sm" optional dependon="create-dg" +option "new-read-ac-chatbit" - + "Required access bits in certificate's CHAT for reading newly created DGs" + int optional dependon="create-dg" multiple typestr="INDEX" +option "new-write-ac" - + "Access condition for writing newly created DGs" + values="always","never","ta","sm" default="sm" optional dependon="create-dg" +option "new-write-ac-chatbit" - + "Required access bits in certificate's CHAT for reading newly created DGs" + int optional dependon="create-dg" multiple typestr="INDEX" + +text " +Report bugs to @PACKAGE_BUGREPORT@ + +Written by Frank Morgner " diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index dbcea01f73..754eb617c0 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -151,6 +151,9 @@ + + + @@ -362,6 +365,7 @@ + From 7d36bab7017e0ecf8f0be7a8375a8a8bd6300c33 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 7 Jan 2019 16:35:36 +0100 Subject: [PATCH 0714/4321] don't force the max buffer size with Le=0 This happens, when we know the size will be smaller, but we still use Le=0 in case of SM. --- src/libopensc/apdu.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index a81d185dbc..d32d440402 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -291,10 +291,6 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) /* data is expected */ if (apdu->resplen == 0 || apdu->resp == NULL) goto error; - /* return buffer to small */ - if ((apdu->le == 0 && apdu->resplen < SC_MAX_APDU_BUFFER_SIZE-2) - || (apdu->resplen < apdu->le)) - goto error; break; case SC_APDU_CASE_3_SHORT: /* data is sent */ @@ -314,10 +310,6 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) /* data is expected */ if (apdu->resplen == 0 || apdu->resp == NULL) goto error; - /* return buffer to small */ - if ((apdu->le == 0 && apdu->resplen < SC_MAX_APDU_BUFFER_SIZE-2) - || (apdu->resplen < apdu->le)) - goto error; /* inconsistent datalen */ if (apdu->datalen != apdu->lc) goto error; From 53dfde94a999fd335c8c8c28cbf21456ca4fbb3f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 11 Jan 2019 16:28:36 +0100 Subject: [PATCH 0715/4321] iso-sm: fixed allocating enough data regression from aa940e8619d01e491b92171c427520d30a89b46d --- src/sm/sm-iso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 1ec0818a9c..cfa2573233 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -475,7 +475,7 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, * (4B), a MAC (2B without data) and a cryptogram with padding * indicator (3B without data). The cryptogram is always padded to * the block size. */ - sm_apdu->resplen = 9 + mac_len + (apdu->resplen/ctx->block_length + 1)*ctx->block_length; + sm_apdu->resplen = 4 + 2 + mac_len + 3 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length; resp_data = calloc(sm_apdu->resplen, 1); if (!resp_data) { r = SC_ERROR_OUT_OF_MEMORY; From 08a02ed5d21afcdae76d2d18d0d643d07f581d09 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 7 Jan 2019 14:29:51 -0600 Subject: [PATCH 0716/4321] Fix PKCS#11 Object Restrictions Framework-pkcs15.c silently ignores adding objects if MAX_OBJECTS is exceeded while creating the fw_data objects. This simple fix is to change the MAX_OBJECTS from 64 to 128. A better fix would be to realloc the objects arrays as needed. __pkcs15_create_data_object and __pkcs15_create_secret_key_object now return rv like the other __pkcs15_create_*_object routines. pkcs15_dobj_get_value now calls sc_pkcs15_read_data_object just like the other pkcs15_*_get_value routines. The problem was introduced in 0c3412bb 2018-04-09 which added: `return sc_to_cryptoki_error(SC_SUCCESS, "C_GetAttributeValue");` before trying to read the data object. The MAX_OBJECT problem was discovered while trying to use a new PIV card with 24 standard cert objects and 10 other objects for a total of 106 objects. Each cert object corresponds to a cert, pubkey, private key, and the cert object itself for a possible 112 data objects. The pkcs15_dobj_get_value was found while running: running pkcs11-tool -r -y data --application-id 2.16.840.1.101.3.7.2.1.1 using git bisect to locate the bad commit. The pkcs11 data objects are created last from the pkcs15 objects which are a linked list with no limits. On branch fix-object-restrictions modified: src/pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 10141c46d4..10582ed37b 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -58,7 +58,7 @@ struct pkcs15_slot_data { } \ attr->ulValueLen = size; -#define MAX_OBJECTS 64 +#define MAX_OBJECTS 128 struct pkcs15_fw_data { struct sc_pkcs15_card * p15_card; struct pkcs15_any_object * objects[MAX_OBJECTS]; @@ -773,7 +773,7 @@ __pkcs15_create_prkey_object(struct pkcs15_fw_data *fw_data, if (prkey_object != NULL) *prkey_object = (struct pkcs15_any_object *) object; - return 0; + return rv; } @@ -794,7 +794,7 @@ __pkcs15_create_data_object(struct pkcs15_fw_data *fw_data, if (data_object != NULL) *data_object = (struct pkcs15_any_object *) dobj; - return 0; + return rv; } @@ -813,7 +813,7 @@ __pkcs15_create_secret_key_object(struct pkcs15_fw_data *fw_data, if (skey_object != NULL) *skey_object = (struct pkcs15_any_object *) skey; - return 0; + return rv; } @@ -4606,10 +4606,9 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, if (!out_data) return SC_ERROR_INVALID_ARGUMENTS; if (dobj->info->data.len == 0) - /* CKA_VALUE is empty */ + /* CKA_VALUE is empty we may need to read it */ { *out_data = NULL; - return sc_to_cryptoki_error(SC_SUCCESS, "C_GetAttributeValue"); } fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; From 87d7eb22140a7c8f36d7571f02693a9ba3145971 Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Tue, 8 Jan 2019 12:43:26 +0200 Subject: [PATCH 0717/4321] Select MyEID applet with AID in myeid_init() to ensure that it is selected before sending other commands. --- src/libopensc/card-myeid.c | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index f02803e91b..514d86aef0 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -146,13 +146,48 @@ static int myeid_match_card(struct sc_card *card) return 1; } +static int +myeid_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, size_t *out_len) +{ + struct sc_apdu apdu; + unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; + int rv; + + /* Select application (deselect previously selected application) */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); + apdu.lc = aid->len; + apdu.data = aid->value; + apdu.datalen = aid->len; + apdu.resplen = sizeof(apdu_resp); + apdu.resp = apdu_resp; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, rv, "Cannot select AID"); + + if (*out_len > 0) { + if (*out_len < apdu.resplen) + LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID - response buffer too small."); + if (out == NULL) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot select AID - invalid arguments."); + memcpy(out, apdu.resp, apdu.resplen); + *out_len = apdu.resplen; + } + + return SC_SUCCESS; +} + static int myeid_init(struct sc_card *card) { unsigned long flags = 0, ext_flags = 0; myeid_private_data_t *priv; u8 appletInfo[20]; size_t appletInfoLen; - myeid_card_caps_t card_caps; + myeid_card_caps_t card_caps; + size_t resp_len = 0; + static struct sc_aid myeid_aid = { "\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35", 0x0C }; + int rv = 0; LOG_FUNC_CALLED(card->ctx); @@ -166,6 +201,10 @@ static int myeid_init(struct sc_card *card) priv->card_state = SC_FILE_STATUS_CREATION; card->drv_data = priv; + /* Ensure that the MyEID applet is selected. */ + rv = myeid_select_aid(card, &myeid_aid, NULL, &resp_len); + LOG_TEST_RET(card->ctx, rv, "Failed to select MyEID applet."); + /* find out MyEID version */ appletInfoLen = 20; From e19fe680c4e142b19d306e2da6b21dd7e42b3104 Mon Sep 17 00:00:00 2001 From: Mat Date: Tue, 15 Jan 2019 07:32:41 +0100 Subject: [PATCH 0718/4321] Add object type "secrkey" to help of --type switch in pkcs11-tool (#1575) * Add object type "secrkey" to help of --type switch in pkcs11-tool Reading an object with pkcs11-tool requires the `--type` switch. The help for that switch is currently incomplete as it is missing the (not very friendly named" *secrkey* option used to read out a secret key object. I have added this information to the help description. * Update man page Describe secrkey option of pkcs11-tool's --type switch in man page --- doc/tools/pkcs11-tool.1.xml | 5 +++-- src/tools/pkcs11-tool.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index c83aafd5b2..d85a1a5eba 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -475,8 +475,9 @@ type Specify the type of object to operate on. - Examples are cert, privkey - and pubkey. + Valid value are cert, privkey, + pubkey, secrkey + and data. diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d60132c578..9af5ea6da8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -269,7 +269,7 @@ static const char *option_help[] = { "Specify the application ID of the data object (use with --type data)", "Specify the issuer in hexadecimal format (use with --type cert)", "Specify the subject in hexadecimal format (use with --type cert/privkey/pubkey)", - "Specify the type of object (e.g. cert, privkey, pubkey, data)", + "Specify the type of object (e.g. cert, privkey, pubkey, secrkey, data)", "Specify the ID of the object", "Specify the label of the object", "Specify the ID of the slot to use", From 3c1d425eb9a87debed3d2121b9c28c26a8070162 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:36:05 +0200 Subject: [PATCH 0719/4321] Remove unused include Signed-off-by: Raul Metsma --- src/tools/eidenv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 41df16c56a..d8a7be62e4 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -33,7 +33,6 @@ #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" -#include "libopensc/esteid.h" #include "util.h" static char *opt_reader = NULL; From c3a9837b1064fdb173a9ea8ce3f7062a440674f3 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Tue, 15 Jan 2019 11:10:45 +0200 Subject: [PATCH 0720/4321] Add mechanisms used by SoftHSM2 /Library/OpenSC/bin/pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so -M will not show any more numeric mechanisms. Source: https://www.cryptsoft.com/pkcs11doc/STANDARD/include/v240e01/pkcs11t.h --- src/pkcs11/pkcs11-display.c | 13 +++++++++++++ src/pkcs11/pkcs11.h | 13 +++++++++++++ src/tools/pkcs11-tool.c | 16 ++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 753c05fa20..c15ea025c6 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -319,6 +319,10 @@ static enum_specs ck_mec_s[] = { { CKM_DSA_KEY_PAIR_GEN , "CKM_DSA_KEY_PAIR_GEN " }, { CKM_DSA , "CKM_DSA " }, { CKM_DSA_SHA1 , "CKM_DSA_SHA1 " }, + { CKM_DSA_SHA224 , "CKM_DSA_SHA224 " }, + { CKM_DSA_SHA256 , "CKM_DSA_SHA256 " }, + { CKM_DSA_SHA384 , "CKM_DSA_SHA384 " }, + { CKM_DSA_SHA512 , "CKM_DSA_SHA512 " }, { CKM_DH_PKCS_KEY_PAIR_GEN , "CKM_DH_PKCS_KEY_PAIR_GEN " }, { CKM_DH_PKCS_DERIVE , "CKM_DH_PKCS_DERIVE " }, { CKM_X9_42_DH_KEY_PAIR_GEN , "CKM_X9_42_DH_KEY_PAIR_GEN " }, @@ -346,6 +350,7 @@ static enum_specs ck_mec_s[] = { { CKM_DES3_MAC , "CKM_DES3_MAC " }, { CKM_DES3_MAC_GENERAL , "CKM_DES3_MAC_GENERAL " }, { CKM_DES3_CBC_PAD , "CKM_DES3_CBC_PAD " }, + { CKM_DES3_CMAC , "CKM_DES3_CMAC " }, { CKM_CDMF_KEY_GEN , "CKM_CDMF_KEY_GEN " }, { CKM_CDMF_ECB , "CKM_CDMF_ECB " }, { CKM_CDMF_CBC , "CKM_CDMF_CBC " }, @@ -498,11 +503,18 @@ static enum_specs ck_mec_s[] = { { CKM_AES_CTR , "CKM_AES_CTR " }, { CKM_AES_GCM , "CKM_AES_GCM " }, { CKM_AES_CCM , "CKM_AES_CCM " }, + { CKM_AES_CMAC , "CKM_AES_CMAC " }, { CKM_AES_CTS , "CKM_AES_CTS " }, { CKM_BLOWFISH_KEY_GEN , "CKM_BLOWFISH_KEY_GEN " }, { CKM_BLOWFISH_CBC , "CKM_BLOWFISH_CBC " }, { CKM_TWOFISH_KEY_GEN , "CKM_TWOFISH_KEY_GEN " }, { CKM_TWOFISH_CBC , "CKM_TWOFISH_CBC " }, + { CKM_DES_ECB_ENCRYPT_DATA , "CKM_DES_ECB_ENCRYPT_DATA " }, + { CKM_DES_CBC_ENCRYPT_DATA , "CKM_DES_CBC_ENCRYPT_DATA " }, + { CKM_DES3_ECB_ENCRYPT_DATA , "CKM_DES3_ECB_ENCRYPT_DATA " }, + { CKM_DES3_CBC_ENCRYPT_DATA , "CKM_DES3_CBC_ENCRYPT_DATA " }, + { CKM_AES_ECB_ENCRYPT_DATA , "CKM_AES_ECB_ENCRYPT_DATA " }, + { CKM_AES_CBC_ENCRYPT_DATA , "CKM_AES_CBC_ENCRYPT_DATA " }, { CKM_GOSTR3410_KEY_PAIR_GEN , "CKM_GOSTR3410_KEY_PAIR_GEN " }, { CKM_GOSTR3410 , "CKM_GOSTR3410 " }, { CKM_GOSTR3410_WITH_GOSTR3411 , "CKM_GOSTR3410_WITH_GOSTR3411 " }, @@ -518,6 +530,7 @@ static enum_specs ck_mec_s[] = { { CKM_DSA_PARAMETER_GEN , "CKM_DSA_PARAMETER_GEN " }, { CKM_DH_PKCS_PARAMETER_GEN , "CKM_DH_PKCS_PARAMETER_GEN " }, { CKM_X9_42_DH_PARAMETER_GEN , "CKM_X9_42_DH_PARAMETER_GEN " }, + { CKM_AES_KEY_WRAP , "CKM_AES_KEY_WRAP " }, { CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED " } }; diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 8219b961b8..2384f91e06 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -498,6 +498,10 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DSA_KEY_PAIR_GEN (0x10UL) #define CKM_DSA (0x11UL) #define CKM_DSA_SHA1 (0x12UL) +#define CKM_DSA_SHA224 (0x13UL) +#define CKM_DSA_SHA256 (0x14UL) +#define CKM_DSA_SHA384 (0x15UL) +#define CKM_DSA_SHA512 (0x16UL) #define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) #define CKM_DH_PKCS_DERIVE (0x21UL) #define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) @@ -533,6 +537,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DES3_MAC (0x134UL) #define CKM_DES3_MAC_GENERAL (0x135UL) #define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC (0x138UL) #define CKM_CDMF_KEY_GEN (0x140UL) #define CKM_CDMF_ECB (0x141UL) #define CKM_CDMF_CBC (0x142UL) @@ -688,10 +693,17 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_GCM (0x1087UL) #define CKM_AES_CCM (0x1088UL) #define CKM_AES_CTS (0x1089UL) +#define CKM_AES_CMAC (0x108AUL) #define CKM_BLOWFISH_KEY_GEN (0x1090UL) #define CKM_BLOWFISH_CBC (0x1091UL) #define CKM_TWOFISH_KEY_GEN (0x1092UL) #define CKM_TWOFISH_CBC (0x1093UL) +#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) +#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) +#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) +#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) +#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) +#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) #define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) #define CKM_GOSTR3410 (0x1201UL) #define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) @@ -708,6 +720,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DSA_PARAMETER_GEN (0x2000UL) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_AES_KEY_WRAP (0x2109UL) #define CKM_VENDOR_DEFINED (1UL << 31) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9af5ea6da8..561da14910 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6048,6 +6048,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL }, { CKM_DSA, "DSA", NULL }, { CKM_DSA_SHA1, "DSA-SHA1", NULL }, + { CKM_DSA_SHA224, "DSA-SHA224", NULL }, + { CKM_DSA_SHA256, "DSA-SHA256", NULL }, + { CKM_DSA_SHA384, "DSA-SHA384", NULL }, + { CKM_DSA_SHA512, "DSA-SHA512", NULL }, { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN", NULL }, { CKM_DH_PKCS_DERIVE, "DH-PKCS-DERIVE", NULL }, { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN", NULL }, @@ -6075,6 +6079,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_DES3_MAC, "DES3-MAC", NULL }, { CKM_DES3_MAC_GENERAL, "DES3-MAC-GENERAL", NULL }, { CKM_DES3_CBC_PAD, "DES3-CBC-PAD", NULL }, + { CKM_DES3_CMAC, "DES3-CMAC", NULL }, { CKM_CDMF_KEY_GEN, "CDMF-KEY-GEN", NULL }, { CKM_CDMF_ECB, "CDMF-ECB", NULL }, { CKM_CDMF_CBC, "CDMF-CBC", NULL }, @@ -6213,13 +6218,24 @@ static struct mech_info p11_mechanisms[] = { { CKM_AES_MAC, "AES-MAC", NULL }, { CKM_AES_MAC_GENERAL, "AES-MAC-GENERAL", NULL }, { CKM_AES_CBC_PAD, "AES-CBC-PAD", NULL }, + { CKM_AES_CTR, "AES-CTR", NULL }, + { CKM_AES_GCM, "AES-GCM", NULL }, + { CKM_AES_CMAC, "AES-CMAC", NULL }, + { CKM_DES_ECB_ENCRYPT_DATA, "DES-ECB-ENCRYPT-DATA", NULL }, + { CKM_DES_CBC_ENCRYPT_DATA, "DES-CBC-ENCRYPT-DATA", NULL }, + { CKM_DES3_ECB_ENCRYPT_DATA, "DES3-ECB-ENCRYPT-DATA", NULL }, + { CKM_DES3_CBC_ENCRYPT_DATA, "DES3-CBC-ENCRYPT-DATA", NULL }, + { CKM_AES_ECB_ENCRYPT_DATA, "AES-ECB-ENCRYPT-DATA", NULL }, + { CKM_AES_CBC_ENCRYPT_DATA, "AES-CBC-ENCRYPT-DATA", NULL }, { CKM_GOSTR3410_KEY_PAIR_GEN,"GOSTR3410-KEY-PAIR-GEN", NULL }, { CKM_GOSTR3410, "GOSTR3410", NULL }, { CKM_GOSTR3410_WITH_GOSTR3411,"GOSTR3410-WITH-GOSTR3411", NULL }, { CKM_GOSTR3411, "GOSTR3411", NULL }, + { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL }, { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL }, { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL }, { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL }, + { CKM_AES_KEY_WRAP, "AES-KEY-WRAP", NULL}, { 0, NULL, NULL } }; From b8b4f7c36ff104ee31ba6def57d0adf3f5324941 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 Jan 2019 23:02:36 +0100 Subject: [PATCH 0721/4321] goid-tool: added error checking for verify/change --- src/tools/goid-tool.c | 49 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 007795393c..100b75246b 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -230,28 +230,38 @@ soc_info(sc_context_t *ctx, sc_card_t *card) } } -void +int soc_verify(sc_card_t *card, unsigned char p2) { + int ok = 0; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, p2); - - if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { - return; - } + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_transmit_apdu(card, &apdu), + "Verification failed"); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_check_sw(card, apdu.sw1, apdu.sw2), + "Verification failed"); + ok = 1; +err: + return ok; } -void +int soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) { + int ok = 0; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x00, p2); - - if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { - return; - } + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_transmit_apdu(card, &apdu), + "Changing secret failed"); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_check_sw(card, apdu.sw1, apdu.sw2), + "Verification failed"); + ok = 1; +err: + return ok; } int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info *cmdline) @@ -292,23 +302,27 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info if (cmdline->verify_pin_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print or PIN on the card."); - soc_verify(card, 0x80); + if (!soc_verify(card, 0x80)) + goto err; } if (cmdline->verify_bio_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print on the card."); - soc_verify(card, 0x40); + if (!soc_verify(card, 0x40)) + goto err; } if (cmdline->verify_pin_or_bio_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print or PIN on the card."); - soc_verify(card, 0xC0); + if (!soc_verify(card, 0xC0)) + goto err; } if (cmdline->new_pin_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Initialize the PIN on the card."); - soc_change(card, 0x00, 0x80); + if (!soc_change(card, 0x00, 0x80)) + goto err; } if (cmdline->new_bio_given) { size_t i = 0; @@ -316,7 +330,8 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Initialize finger print template %u on the card.", (unsigned char) i); - soc_change(card, (unsigned char) i, 0x40); + if (!soc_change(card, (unsigned char) i, 0x40)) + goto err; i++; } } From d806ee3245b89d95df751c8b26ff0a9267f01fc2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:01:14 +0100 Subject: [PATCH 0722/4321] fixed unsafe usage of gmtime reported by lgtm --- src/libopensc/card-openpgp.c | 10 +++++++++- src/libopensc/pkcs15.c | 15 ++++++++++----- src/tools/openpgp-tool.c | 12 +++++++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 956605adcd..ab37bb5fde 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2265,6 +2265,7 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) const size_t timestrlen = 64; char timestring[65]; u8 buf[4]; + struct tm tm; LOG_FUNC_CALLED(card->ctx); @@ -2278,7 +2279,14 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) /* set output */ *outtime = createtime = time(NULL); - strftime(timestring, timestrlen, "%c %Z", gmtime(&createtime)); +#ifdef _WIN32 + if (0 != gmtime_s(&tm, &createtime)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); +#else + if (NULL == gmtime_r(&createtime, &tm)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); +#endif + strftime(timestring, timestrlen, "%c %Z", &tm); sc_log(card->ctx, "Creation time %s.", timestring); /* Code borrowed from GnuPG */ ulong2bebytes(buf, (unsigned long)createtime); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 31e97cb18c..8c4dc7ae62 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2605,7 +2605,7 @@ sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out) #ifdef HAVE_GETTIMEOFDAY struct timeval tv; #endif - struct tm *tm_time; + struct tm tm; time_t t; if (!ctx || !out) @@ -2618,16 +2618,21 @@ sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out) #else t = time(NULL); #endif - tm_time = gmtime(&t); - if (!tm_time) - LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "gmtime failed"); + +#ifdef _WIN32 + if (0 != gmtime_s(&tm, &t)) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); +#else + if (NULL == gmtime_r(&t, &tm)) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); +#endif *out = calloc(1, 16); if (*out == NULL) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "memory failure"); /* print time in generalized time format */ - if (!strftime(*out, 16, "%Y%m%d%H%M%SZ", tm_time)) { + if (!strftime(*out, 16, "%Y%m%d%H%M%SZ", &tm)) { free(*out); LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "strftime failed"); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index eb071c441e..25174ee269 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -240,11 +240,17 @@ static char *prettify_date(u8 *data, size_t length) { if (data != NULL && length == 4) { time_t time = (time_t) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); - struct tm *tp; + struct tm tm; static char result[64]; /* large enough */ - tp = gmtime(&time); - strftime(result, sizeof(result), "%Y-%m-%d %H:%M:%S", tp); +#ifdef _WIN32 + if (0 != gmtime_s(&tm, &time)) + return NULL; +#else + if (NULL == gmtime_r(&time, &tm)) + return NULL; +#endif + strftime(result, sizeof(result), "%Y-%m-%d %H:%M:%S", &tm); return result; } return NULL; From 4b30858092bab7b53fc99d57e679ca8e527c46ff Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:05:37 +0100 Subject: [PATCH 0723/4321] pkcs11-tool: fixed argument type reported by lgtm --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 561da14910..7e1032f3b8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3995,9 +3995,9 @@ get_mechanisms(CK_SLOT_ID slot, CK_MECHANISM_TYPE_PTR *pList, CK_FLAGS flags) } #ifdef ENABLE_OPENSSL -unsigned char *BIO_copy_data(BIO *out, int *data_lenp) { +unsigned char *BIO_copy_data(BIO *out, long *data_lenp) { unsigned char *data, *tdata; - int data_len; + long data_len; data_len = BIO_get_mem_data(out, &tdata); data = malloc(data_len+1); @@ -4104,7 +4104,7 @@ static int read_object(CK_SESSION_HANDLE session) } if (clazz == CKO_PUBLIC_KEY) { #ifdef ENABLE_OPENSSL - int derlen; + long derlen; BIO *pout = BIO_new(BIO_s_mem()); if (!pout) util_fatal("out of memory"); From 110650865631287201f865e9934dbe9c53fadaa0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:26:10 +0100 Subject: [PATCH 0724/4321] removed tautologic comparison --- src/libopensc/card-cac1.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 86c4fcc7b1..969c18088c 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -240,10 +240,8 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc * We only need to do this for private keys. */ if ((pathlen > 2) && (pathlen <= 4) && memcmp(path, "\x3F\x00", 2) == 0) { - if (pathlen > 2) { - path += 2; - pathlen -= 2; - } + path += 2; + pathlen -= 2; } From 3fe198f21e589631a603a886c30611620cfbbb2c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:35:00 +0100 Subject: [PATCH 0725/4321] treat records with size_t --- src/libopensc/card-starcos.c | 2 +- src/libopensc/types.h | 4 ++-- src/pkcs15init/pkcs15-oberthur-awp.c | 23 ++++++++++++----------- src/tools/opensc-explorer.c | 12 ++++++------ src/tools/opensc-tool.c | 4 ++-- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index c5540a4aef..27a0692ec8 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -400,7 +400,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, file->record_length = (tag[2] << 8) + tag[3]; file->record_count = tag[4]; sc_log(ctx, - " rec_len: %d rec_cnt: %d\n\n", + " rec_len: %"SC_FORMAT_LEN_SIZE_T"u rec_cnt: %"SC_FORMAT_LEN_SIZE_T"u\n\n", file->record_length, file->record_count); } } diff --git a/src/libopensc/types.h b/src/libopensc/types.h index ab0ddd8e30..ea352e91a2 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -237,8 +237,8 @@ typedef struct sc_file { int sid; /* short EF identifier (1 byte) */ struct sc_acl_entry *acl[SC_MAX_AC_OPS]; /* Access Control List */ - int record_length; /* In case of fixed-length or cyclic EF */ - int record_count; /* Valid, if not transparent EF or DF */ + size_t record_length; /* In case of fixed-length or cyclic EF */ + size_t record_count; /* Valid, if not transparent EF or DF */ unsigned char *sec_attr; /* security data in proprietary format. tag '86' */ size_t sec_attr_len; diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 8bb53def15..4972ea87d0 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -171,7 +171,7 @@ awp_new_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, } sc_log(ctx, - "info_file(id:%04X,size:%"SC_FORMAT_LEN_SIZE_T"u,rlen:%i)", + "info_file(id:%04X,size:%"SC_FORMAT_LEN_SIZE_T"u,rlen:%"SC_FORMAT_LEN_SIZE_T"u)", ifile->id, ifile->size, ifile->record_length); *info_out = ifile; } @@ -236,7 +236,7 @@ awp_update_blob(struct sc_context *ctx, static int -awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, int len) +awp_new_container_entry(struct sc_pkcs15_card *p15card, unsigned char *buff, size_t len) { struct sc_context *ctx = p15card->card->ctx; int mm, rv = 0; @@ -274,7 +274,7 @@ awp_create_container_record (struct sc_pkcs15_card *p15card, struct sc_profile * unsigned char *buff = NULL; LOG_FUNC_CALLED(ctx); - sc_log(ctx, "container file(file-id:%X,rlen:%i,rcount:%i)", + sc_log(ctx, "container file(file-id:%X,rlen:%"SC_FORMAT_LEN_SIZE_T"u,rcount:%"SC_FORMAT_LEN_SIZE_T"u)", list_file->id, list_file->record_length, list_file->record_count); buff = malloc(list_file->record_length); @@ -322,14 +322,14 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); LOG_TEST_RET(ctx, rv, "Create container failed"); - sc_log(ctx, "contaner cfile(rcount:%i,rlength:%i)", clist->record_count, clist->record_length); + sc_log(ctx, "contaner cfile(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", clist->record_count, clist->record_length); rv = sc_select_file(p15card->card, &clist->path, &file); LOG_TEST_RET(ctx, rv, "Create container failed: cannot select container's list"); file->record_length = clist->record_length; - sc_log(ctx, "contaner file(rcount:%i,rlength:%i)", file->record_count, file->record_length); - sc_log(ctx, "Append new record %i for private key", file->record_count + 1); + sc_log(ctx, "contaner file(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", file->record_count, file->record_length); + sc_log(ctx, "Append new record %"SC_FORMAT_LEN_SIZE_T"u for private key", file->record_count + 1); rv = awp_create_container_record(p15card, profile, file, acc); @@ -343,7 +343,7 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, static int awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_file *list_file, int type, int file_id, - int rec, int offs) + size_t rec, int offs) { struct sc_context *ctx = p15card->card->ctx; int rv; @@ -351,9 +351,9 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p LOG_FUNC_CALLED(ctx); sc_log(ctx, - "update container entry(type:%X,id %i,rec %i,offs %i", + "update container entry(type:%X,id %i,rec %"SC_FORMAT_LEN_SIZE_T"u,offs %i", type, file_id, rec, offs); - sc_log(ctx, "container file(file-id:%X,rlen:%i,rcount:%i)", + sc_log(ctx, "container file(file-id:%X,rlen:%"SC_FORMAT_LEN_SIZE_T"u,rcount:%"SC_FORMAT_LEN_SIZE_T"u)", list_file->id, list_file->record_length, list_file->record_count); buff = malloc(list_file->record_length); @@ -427,7 +427,8 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_context *ctx = p15card->card->ctx; struct sc_file *clist = NULL, *file = NULL; struct sc_path private_path; - int rv = 0, rec, rec_offs; + int rv = 0; + size_t rec, rec_offs; unsigned char *list = NULL; LOG_FUNC_CALLED(ctx); @@ -484,7 +485,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, for (rec_offs=0; !rv && rec_offs<12; rec_offs+=6) { int offs; - sc_log(ctx, "rec %i; rec_offs %i", rec, rec_offs); + sc_log(ctx, "rec %"SC_FORMAT_LEN_SIZE_T"u; rec_offs %"SC_FORMAT_LEN_SIZE_T"u", rec, rec_offs); offs = rec*AWP_CONTAINER_RECORD_LEN + rec_offs; if (*(list + offs + 2)) { unsigned char *buff = NULL; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 28c510a64b..ea2163fb3a 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1514,7 +1514,7 @@ static int do_update_record(int argc, char **argv) u8 buf[240]; size_t buflen; int r, i, err = 1; - int rec, offs; + size_t rec, offs; sc_path_t path; sc_file_t *file; @@ -1525,7 +1525,7 @@ static int do_update_record(int argc, char **argv) rec = strtol(argv[1],NULL,10); offs = strtol(argv[2],NULL,10); - printf("in: %i; %i; %s\n", rec, offs, argv[3]); + printf("in: %"SC_FORMAT_LEN_SIZE_T"u; %"SC_FORMAT_LEN_SIZE_T"u; %s\n", rec, offs, argv[3]); r = sc_lock(card); if (r == SC_SUCCESS) @@ -1540,13 +1540,13 @@ static int do_update_record(int argc, char **argv) fprintf(stderr, "EF structure should be SC_FILE_EF_LINEAR_VARIABLE\n"); goto err; } else if (rec < 1 || rec > file->record_count) { - fprintf(stderr, "Invalid record number %i\n", rec); + fprintf(stderr, "Invalid record number %"SC_FORMAT_LEN_SIZE_T"u\n", rec); goto err; } r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r<0) { - fprintf(stderr, "Cannot read record %i; return %i\n", rec, r); + fprintf(stderr, "Cannot read record %"SC_FORMAT_LEN_SIZE_T"u; return %i\n", rec, r); goto err;; } @@ -1562,11 +1562,11 @@ static int do_update_record(int argc, char **argv) r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR); sc_unlock(card); if (r<0) { - fprintf(stderr, "Cannot update record %i; return %i\n", rec, r); + fprintf(stderr, "Cannot update record %"SC_FORMAT_LEN_SIZE_T"u; return %i\n", rec, r); goto err; } - printf("Total of %d bytes written to record %i at %i offset.\n", + printf("Total of %d bytes written to record %"SC_FORMAT_LEN_SIZE_T"u at %"SC_FORMAT_LEN_SIZE_T"u offset.\n", i, rec, offs); err = 0; diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 601c3d2aed..88250de473 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -438,10 +438,10 @@ static int print_file(sc_card_t *in_card, const sc_file_t *file, free(buf); } else { unsigned char buf[256]; - int i; + size_t i; for (i=0; i < file->record_count; i++) { - printf("Record %d\n", i); + printf("Record %"SC_FORMAT_LEN_SIZE_T"u\n", i); r = sc_lock(card); if (r == SC_SUCCESS) r = sc_read_record(in_card, i, buf, 256, 0); From 1991dcea0d2e78ec39d7b4692c69517cd8a5c274 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:37:53 +0100 Subject: [PATCH 0726/4321] removed unused comparison --- src/libopensc/card-piv.c | 44 +++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index ed804844c4..3298a68845 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2487,36 +2487,34 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, if (r < 0) goto err; - if ( r >= 0) { - body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x30, &bodylen); - - for (i = 0; i<2; i++) { - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen); - if (tag) { - bodylen -= taglen - (tag - body); - body = tag + taglen; - - if (taglen > nLen) { /* drop leading 00 if present */ - if (*tag != 0x00) { - r = SC_ERROR_INVALID_DATA; - goto err; - } - tag++; - taglen--; + body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x30, &bodylen); + + for (i = 0; i<2; i++) { + if (body) { + tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen); + if (tag) { + bodylen -= taglen - (tag - body); + body = tag + taglen; + + if (taglen > nLen) { /* drop leading 00 if present */ + if (*tag != 0x00) { + r = SC_ERROR_INVALID_DATA; + goto err; } - memcpy(out + nLen*i + nLen - taglen , tag, taglen); - } else { - r = SC_ERROR_INVALID_DATA; - goto err; + tag++; + taglen--; } - } else { + memcpy(out + nLen*i + nLen - taglen , tag, taglen); + } else { r = SC_ERROR_INVALID_DATA; goto err; } + } else { + r = SC_ERROR_INVALID_DATA; + goto err; } - r = 2 * nLen; } + r = 2 * nLen; } else { /* RSA is all set */ r = piv_validate_general_authentication(card, data, datalen, out, outlen); } From 6bf7c0d219a095dbb18ade60e67f852b54716f74 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 10:40:08 +0100 Subject: [PATCH 0727/4321] don't hide global variables --- src/tools/gids-tool.c | 5 +- src/tools/openpgp-tool.c | 36 ++++----- src/tools/pkcs15-init.c | 162 +++++++++++++++++++-------------------- src/tools/sc-hsm-tool.c | 57 +++++++------- src/tools/westcos-tool.c | 6 +- 5 files changed, 132 insertions(+), 134 deletions(-) diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 0d1128ffce..ee2051cef6 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -92,9 +92,6 @@ static const char *option_help[] = { "Verbose operation. Use several times to enable debug output.", }; -static sc_context_t *ctx = NULL; -static sc_card_t *card = NULL; - static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, const char* serial) { sc_cardctl_gids_init_param_t param; @@ -479,6 +476,8 @@ int main(int argc, char * argv[]) const char *opt_serial_number = NULL; const char *opt_new_key = NULL; sc_context_param_t ctx_param; + sc_context_t *ctx = NULL; + sc_card_t *card = NULL; while (1) { c = getopt_long(argc, argv, "XUCr:wv", options, &long_optind); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 25174ee269..1da7f1dc24 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -663,7 +663,7 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) return EXIT_SUCCESS; } -int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) +int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) { int r; sc_cardctl_openpgp_keygen_info_t key_info; @@ -671,9 +671,9 @@ int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) sc_path_t path; sc_file_t *file; - /* validate key_id */ - if (key_id < 1 || key_id > 3) { - util_error("unknown key ID %d", key_id); + /* validate in_key_id */ + if (in_key_id < 1 || in_key_id > 3) { + util_error("unknown key ID %d", in_key_id); return SC_ERROR_INVALID_ARGUMENTS; } @@ -701,7 +701,7 @@ int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) } /* set key_info */ - key_info.key_id = key_id; + key_info.key_id = in_key_id; key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.rsa.modulus_len = keylen; key_info.rsa.modulus = malloc((keylen + 7) / 8); @@ -730,17 +730,17 @@ int do_genkey(sc_card_t *card, u8 key_id, const char *keytype) util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); return EXIT_FAILURE; } - printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20)); + printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(in_key_id - 1), 20)); return EXIT_SUCCESS; } -int do_verify(sc_card_t *card, char *type, const char *pin) +int do_verify(sc_card_t *card, char *type, const char *in_pin) { struct sc_pin_cmd_data data; int tries_left; int r; - if (!type || !pin) + if (!type || !in_pin) return SC_ERROR_INVALID_ARGUMENTS; if (strncasecmp("CHV", type, 3) != 0) { @@ -757,8 +757,8 @@ int do_verify(sc_card_t *card, char *type, const char *pin) data.cmd = SC_PIN_CMD_VERIFY; data.pin_type = SC_AC_CHV; data.pin_reference = type[3] - '0'; - data.pin1.data = (unsigned char *) pin; - data.pin1.len = (int)strlen(pin); + data.pin1.data = (unsigned char *) in_pin; + data.pin1.len = (int)strlen(in_pin); r = sc_pin_cmd(card, &data, &tries_left); return r; } @@ -767,7 +767,7 @@ int do_verify(sc_card_t *card, char *type, const char *pin) * Delete key, for OpenPGP card. * This function is not complete and is reserved for future version (> 2) of OpenPGP card. **/ -int delete_key_openpgp(sc_card_t *card, u8 key_id) +int delete_key_openpgp(sc_card_t *card, u8 in_key_id) { char *del_fingerprint = "00:DA:00:C6:14:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"; char *del_creationtime = "00:DA:00:CD:04:00:00:00:00"; @@ -790,7 +790,7 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id) sc_hex_to_bin(apdustring, buf, &len0); /* Replace DO tag, subject to key ID */ - buf[3] = buf[3] + key_id; + buf[3] = buf[3] + in_key_id; /* Build APDU from binary array */ r = sc_bytes2apdu(card->ctx, buf, len0, &apdu); @@ -813,7 +813,7 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id) return r; } -int do_delete_key(sc_card_t *card, u8 key_id) +int do_delete_key(sc_card_t *card, u8 in_key_id) { sc_path_t path; int r = SC_SUCCESS; @@ -824,20 +824,20 @@ int do_delete_key(sc_card_t *card, u8 key_id) return SC_ERROR_NOT_SUPPORTED; } - if (key_id < 1 || (key_id > 3 && key_id != 'a')) { - util_error("invalid key id %d", key_id); + if (in_key_id < 1 || (in_key_id > 3 && in_key_id != 'a')) { + util_error("invalid key id %d", in_key_id); return SC_ERROR_INVALID_ARGUMENTS; } - if (key_id == 1 || key_id == 'a') { + if (in_key_id == 1 || in_key_id == 'a') { sc_format_path("B601", &path); r |= sc_delete_file(card, &path); } - if (key_id == 2 || key_id == 'a') { + if (in_key_id == 2 || in_key_id == 'a') { sc_format_path("B801", &path); r |= sc_delete_file(card, &path); } - if (key_id == 3 || key_id == 'a') { + if (in_key_id == 3 || in_key_id == 'a') { sc_format_path("A401", &path); r |= sc_delete_file(card, &path); } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index a6cce3b009..ad74f42ffb 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -353,9 +353,9 @@ struct secret { #define SC_PKCS15INIT_TYPE_DATA 16 #define SC_PKCS15INIT_TYPE_SKEY 32 -static sc_context_t * ctx = NULL; -static sc_card_t * card = NULL; -static struct sc_pkcs15_card * p15card = NULL; +static sc_context_t * g_ctx = NULL; +static sc_card_t * g_card = NULL; +static struct sc_pkcs15_card * g_p15card = NULL; static char * opt_reader = NULL; static unsigned int opt_actions; static int opt_extractable = 0, @@ -496,7 +496,7 @@ main(int argc, char **argv) sc_pkcs15init_set_callbacks(&callbacks); /* Bind the card-specific operations and load the profile */ - r = sc_pkcs15init_bind(card, opt_profile, opt_card_profile, NULL, &profile); + r = sc_pkcs15init_bind(g_card, opt_profile, opt_card_profile, NULL, &profile); if (r < 0) { printf("Couldn't bind to the card: %s\n", sc_strerror(r)); return 1; @@ -515,7 +515,7 @@ main(int argc, char **argv) if (action != ACTION_ERASE && action != ACTION_INIT && action != ACTION_ASSERT_PRISTINE - && p15card == NULL) { + && g_p15card == NULL) { /* Read the PKCS15 structure from the card */ if (opt_bind_to_aid) { struct sc_aid aid; @@ -526,16 +526,16 @@ main(int argc, char **argv) return 1; } - r = sc_pkcs15init_finalize_profile(card, profile, &aid); + r = sc_pkcs15init_finalize_profile(g_card, profile, &aid); if (r < 0) { fprintf(stderr, "Finalize profile error %s\n", sc_strerror(r)); break; } - r = sc_pkcs15_bind(card, &aid, &p15card); + r = sc_pkcs15_bind(g_card, &aid, &g_p15card); } else { - r = sc_pkcs15_bind(card, NULL, &p15card); + r = sc_pkcs15_bind(g_card, NULL, &g_p15card); } if (r) { fprintf(stderr, "PKCS#15 binding failed: %s\n", sc_strerror(r)); @@ -546,12 +546,12 @@ main(int argc, char **argv) * sure we're not messing things up */ if (verbose) - printf("Found %s\n", p15card->tokeninfo->label); + printf("Found %s\n", g_p15card->tokeninfo->label); - sc_pkcs15init_set_p15card(profile, p15card); + sc_pkcs15init_set_p15card(profile, g_p15card); if (opt_verify_pin) { - r = verify_pin(p15card, opt_authid); + r = verify_pin(g_p15card, opt_authid); if (r) { fprintf(stderr, "Failed to verify User PIN : %s\n", sc_strerror(r)); @@ -569,11 +569,11 @@ main(int argc, char **argv) break; case ACTION_ASSERT_PRISTINE: /* skip printing error message */ - if ((r = do_assert_pristine(card)) < 0) + if ((r = do_assert_pristine(g_card)) < 0) goto out; continue; case ACTION_ERASE: - r = do_erase(card, profile); + r = do_erase(g_card, profile); break; case ACTION_INIT: r = do_init_app(profile); @@ -611,7 +611,7 @@ main(int argc, char **argv) r = do_generate_skey(profile, opt_newkey); break; case ACTION_FINALIZE_CARD: - r = do_finalize_card(card, profile); + r = do_finalize_card(g_card, profile); break; case ACTION_SANITY_CHECK: r = do_sanity_check(profile); @@ -620,7 +620,7 @@ main(int argc, char **argv) profile->dirty = 1; break; case ACTION_ERASE_APPLICATION: - r = do_erase_application(card, profile); + r = do_erase_application(g_card, profile); break; default: util_fatal("Action not yet implemented\n"); @@ -641,13 +641,13 @@ main(int argc, char **argv) if (profile) { sc_pkcs15init_unbind(profile); } - if (p15card) { - sc_pkcs15_unbind(p15card); + if (g_p15card) { + sc_pkcs15_unbind(g_p15card); } - if (card) { - sc_disconnect_card(card); + if (g_card) { + sc_disconnect_card(g_card); } - sc_release_context(ctx); + sc_release_context(g_ctx); return r < 0? 1 : 0; } @@ -661,13 +661,13 @@ open_reader_and_card(char *reader) ctx_param.ver = 0; ctx_param.app_name = app_name; - r = sc_context_create(&ctx, &ctx_param); + r = sc_context_create(&g_ctx, &ctx_param); if (r) { util_error("Failed to establish context: %s\n", sc_strerror(r)); return 0; } - if (util_connect_card_ex(ctx, &card, reader, opt_wait, 0, verbose)) + if (util_connect_card_ex(g_ctx, &g_card, reader, opt_wait, 0, verbose)) return 0; return 1; @@ -855,7 +855,7 @@ do_init_app(struct sc_profile *profile) hints.flags = SC_UI_PIN_RETYPE | SC_UI_PIN_CHECK_LENGTH | SC_UI_PIN_MISMATCH_RETRY; - hints.card = card; + hints.card = g_card; hints.p15card = NULL; hints.info.pin = &info; @@ -915,11 +915,11 @@ do_init_app(struct sc_profile *profile) args.serial = (const char *) opt_serial; args.label = opt_label; - r = sc_lock(card); + r = sc_lock(g_card); if (r < 0) return r; - r = sc_pkcs15init_add_app(card, profile, &args); - sc_unlock(card); + r = sc_pkcs15init_add_app(g_card, profile, &args); + sc_unlock(g_card); return r; failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r)); @@ -943,8 +943,8 @@ do_store_pin(struct sc_profile *profile) hints.flags = SC_UI_PIN_RETYPE | SC_UI_PIN_CHECK_LENGTH | SC_UI_PIN_MISMATCH_RETRY; - hints.card = card; - hints.p15card = p15card; + hints.card = g_card; + hints.p15card = g_p15card; hints.info.pin = &info; pin_id = opt_objectid ? opt_objectid : opt_authid; @@ -988,11 +988,11 @@ do_store_pin(struct sc_profile *profile) args.puk = (u8 *) opt_pins[1]; args.puk_len = opt_pins[1]? strlen(opt_pins[1]) : 0; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_store_pin(p15card, profile, &args); - sc_unlock(p15card->card); + r = sc_pkcs15init_store_pin(g_p15card, profile, &args); + sc_unlock(g_p15card->card); return r; failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r)); @@ -1077,12 +1077,12 @@ do_store_private_key(struct sc_profile *profile) args.access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_store_private_key(p15card, profile, &args, NULL); + r = sc_pkcs15init_store_private_key(g_p15card, profile, &args, NULL); if (r < 0) { - sc_unlock(p15card->card); + sc_unlock(g_p15card->card); return r; } @@ -1126,7 +1126,7 @@ do_store_private_key(struct sc_profile *profile) cargs.authority = 1; } - r = sc_pkcs15init_store_certificate(p15card, profile, &cargs, NULL); + r = sc_pkcs15init_store_certificate(g_p15card, profile, &cargs, NULL); next_cert: free(cargs.der_encoded.value); } @@ -1135,7 +1135,7 @@ do_store_private_key(struct sc_profile *profile) if (ncerts == 0) r = do_store_public_key(profile, pkey); - sc_unlock(p15card->card); + sc_unlock(g_p15card->card); return r; } @@ -1150,7 +1150,7 @@ is_cacert_already_present(struct sc_pkcs15init_certargs *args) sc_pkcs15_cert_t *cert; int i, count, r; - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32); + r = sc_pkcs15_get_objects(g_p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32); if (r <= 0) return 0; @@ -1165,7 +1165,7 @@ is_cacert_already_present(struct sc_pkcs15init_certargs *args) /* XXX we should also match the usage field here */ /* Compare the DER representation of the certificates */ - r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); + r = sc_pkcs15_read_certificate(g_p15card, cinfo, &cert); if (r < 0 || !cert) continue; @@ -1207,11 +1207,11 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey) init_gost_params(&args.params.gost, pkey); } if (r >= 0) { - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_store_public_key(p15card, profile, &args, &dummy); - sc_unlock(p15card->card); + r = sc_pkcs15init_store_public_key(g_p15card, profile, &args, &dummy); + sc_unlock(g_p15card->card); } return r; @@ -1249,11 +1249,11 @@ do_store_secret_key(struct sc_profile *profile) args.value_len = keybits; args.access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); - sc_unlock(p15card->card); + r = sc_pkcs15init_store_secret_key(g_p15card, profile, &args, NULL); + sc_unlock(g_p15card->card); return r; } @@ -1282,11 +1282,11 @@ do_store_certificate(struct sc_profile *profile) if (r >= 0) r = do_convert_cert(&args.der_encoded, cert); if (r >= 0) { - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_store_certificate(p15card, profile, &args, NULL); - sc_unlock(p15card->card); + r = sc_pkcs15init_store_certificate(g_p15card, profile, &args, NULL); + sc_unlock(g_p15card->card); } if (args.der_encoded.value) @@ -1383,17 +1383,17 @@ do_update_certificate(struct sc_profile *profile) sc_pkcs15_format_id(opt_objectid, &id); - if (sc_pkcs15_find_cert_by_id(p15card, &id, &obj) != 0) { + if (sc_pkcs15_find_cert_by_id(g_p15card, &id, &obj) != 0) { util_error("Couldn't find the cert with ID %s\n", opt_objectid); return SC_ERROR_OBJECT_NOT_FOUND; } - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; certinfo = (sc_pkcs15_cert_info_t *) obj->data; - r = sc_pkcs15_read_certificate(p15card, certinfo, &oldcert); + r = sc_pkcs15_read_certificate(g_p15card, certinfo, &oldcert); if (r < 0) goto err; @@ -1403,14 +1403,14 @@ do_update_certificate(struct sc_profile *profile) if (r < 0) goto err; - r = sc_pkcs15init_update_certificate(p15card, profile, obj, + r = sc_pkcs15init_update_certificate(g_p15card, profile, obj, newcert_raw.value, newcert_raw.len); if (newcert_raw.value) free(newcert_raw.value); err: - sc_unlock(p15card->card); + sc_unlock(g_p15card->card); return r; } @@ -1446,13 +1446,13 @@ do_store_data_object(struct sc_profile *profile) /* der_encoded contains the plain data, nothing DER encoded */ args.der_encoded.value = data; args.der_encoded.len = datalen; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) { free(data); return r; } - r = sc_pkcs15init_store_data_object(p15card, profile, &args, NULL); - sc_unlock(p15card->card); + r = sc_pkcs15init_store_data_object(g_p15card, profile, &args, NULL); + sc_unlock(g_p15card->card); } if (data) @@ -1467,11 +1467,11 @@ static int do_sanity_check(struct sc_profile *profile) { int r; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_sanity_check(p15card, profile); - sc_unlock(p15card->card); + r = sc_pkcs15init_sanity_check(g_p15card, profile); + sc_unlock(g_p15card->card); return r; } @@ -1627,7 +1627,7 @@ do_delete_objects(struct sc_profile *profile, unsigned int myopt_delete_flags) { int r = 0, count = 0; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; @@ -1638,17 +1638,17 @@ do_delete_objects(struct sc_profile *profile, unsigned int myopt_delete_flags) if (opt_application_id != NULL) { sc_format_oid(&app_oid, opt_application_id); - r = sc_pkcs15_find_data_object_by_app_oid(p15card, &app_oid, &obj); + r = sc_pkcs15_find_data_object_by_app_oid(g_p15card, &app_oid, &obj); } else if (opt_application_name != NULL && opt_label != NULL) { - r = sc_pkcs15_find_data_object_by_name(p15card, opt_application_name, opt_label, &obj); + r = sc_pkcs15_find_data_object_by_name(g_p15card, opt_application_name, opt_label, &obj); } else { util_fatal("Specify the --application-id or --application-name and --label for the data object to be deleted\n"); } if (r >= 0) { - r = sc_pkcs15init_delete_object(p15card, profile, obj); + r = sc_pkcs15init_delete_object(g_p15card, profile, obj); if (r >= 0) count++; } @@ -1660,12 +1660,12 @@ do_delete_objects(struct sc_profile *profile, unsigned int myopt_delete_flags) util_fatal("Specify the --id for key(s) or cert(s) to be deleted\n"); sc_pkcs15_format_id(opt_objectid, &id); - r = do_delete_crypto_objects(p15card, profile, &id, myopt_delete_flags); + r = do_delete_crypto_objects(g_p15card, profile, &id, myopt_delete_flags); if (r >= 0) count += r; } - sc_unlock(p15card->card); + sc_unlock(g_p15card->card); printf("Deleted %d objects\n", count); return r; @@ -1692,23 +1692,23 @@ do_change_attributes(struct sc_profile *profile, unsigned int myopt_type) switch(myopt_type) { case SC_PKCS15INIT_TYPE_PRKEY: - if ((r = sc_pkcs15_find_prkey_by_id(p15card, &id, &obj)) != 0) + if ((r = sc_pkcs15_find_prkey_by_id(g_p15card, &id, &obj)) != 0) return r; break; case SC_PKCS15INIT_TYPE_PUBKEY: - if ((r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj)) != 0) + if ((r = sc_pkcs15_find_pubkey_by_id(g_p15card, &id, &obj)) != 0) return r; break; case SC_PKCS15INIT_TYPE_CERT: - if ((r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj)) != 0) + if ((r = sc_pkcs15_find_cert_by_id(g_p15card, &id, &obj)) != 0) return r; break; case SC_PKCS15INIT_TYPE_DATA: - if ((r = sc_pkcs15_find_data_object_by_id(p15card, &id, &obj)) != 0) + if ((r = sc_pkcs15_find_data_object_by_id(g_p15card, &id, &obj)) != 0) return r; break; case SC_PKCS15INIT_TYPE_SKEY: - if ((r = sc_pkcs15_find_skey_by_id(p15card, &id, &obj)) != 0) + if ((r = sc_pkcs15_find_skey_by_id(g_p15card, &id, &obj)) != 0) return r; break; } @@ -1722,11 +1722,11 @@ do_change_attributes(struct sc_profile *profile, unsigned int myopt_type) strlcpy(obj->label, opt_label, sizeof(obj->label)); } - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r < 0) return r; - r = sc_pkcs15init_update_any_df(p15card, profile, obj->df, 0); - sc_unlock(p15card->card); + r = sc_pkcs15init_update_any_df(g_p15card, profile, obj->df, 0); + sc_unlock(g_p15card->card); return r; } @@ -1767,10 +1767,10 @@ do_generate_key(struct sc_profile *profile, const char *spec) break; } - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r == 0) - r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits, NULL); - sc_unlock(p15card->card); + r = sc_pkcs15init_generate_key(g_p15card, profile, &keygen_args, keybits, NULL); + sc_unlock(g_p15card->card); return r; } @@ -1795,10 +1795,10 @@ do_generate_skey(struct sc_profile *profile, const char *spec) } skey_args.value_len = keybits; - r = sc_lock(p15card->card); + r = sc_lock(g_p15card->card); if (r == 0) - r = sc_pkcs15init_generate_secret_key(p15card, profile, &skey_args, NULL); - sc_unlock(p15card->card); + r = sc_pkcs15init_generate_secret_key(g_p15card, profile, &skey_args, NULL); + sc_unlock(g_p15card->card); return r; } @@ -2080,8 +2080,8 @@ get_pin_callback(struct sc_profile *profile, hints.prompt = prompt; hints.obj_label = name; hints.usage = SC_UI_USAGE_OTHER; - hints.card = card; - hints.p15card = p15card; + hints.card = g_card; + hints.p15card = g_p15card; if ((r = get_pin(&hints, &secret)) < 0) { fprintf(stderr, @@ -3176,7 +3176,7 @@ static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) hints.prompt = "User PIN required"; hints.obj_label = pin_label; hints.usage = SC_UI_USAGE_OTHER; - hints.card = card; + hints.card = g_card; hints.p15card = p15card; get_pin(&hints, &pin); diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 2642c000df..a6cacb5be0 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -137,9 +137,6 @@ typedef struct { BIGNUM * y; } secret_share_t; -static sc_context_t *ctx = NULL; -static sc_card_t *card = NULL; - @@ -195,10 +192,10 @@ static void calculatePolynomialValue(const BIGNUM *x, BIGNUM **polynomial, const BIGNUM *exponent; unsigned long exp; - BN_CTX *ctx; + BN_CTX *bn_ctx; // Create context for temporary variables of OpenSSL engine - ctx = BN_CTX_new(); + bn_ctx = BN_CTX_new(); temp = BN_new(); exponent = BN_new(); @@ -218,19 +215,19 @@ static void calculatePolynomialValue(const BIGNUM *x, BIGNUM **polynomial, const BN_set_word(exponent, exp); // temp = x^exponent mod prime - BN_mod_exp(temp, x, exponent, prime, ctx); + BN_mod_exp(temp, x, exponent, prime, bn_ctx); // exponent = temp * a = a * x^exponent mod prime - BN_mod_mul(exponent, temp, *pp, prime, ctx); + BN_mod_mul(exponent, temp, *pp, prime, bn_ctx); // add the temp value from exponent to y BN_copy(temp, y); - BN_mod_add(y, temp, exponent, prime, ctx); + BN_mod_add(y, temp, exponent, prime, bn_ctx); pp++; } BN_clear_free(temp); BN_clear_free(exponent); - BN_CTX_free(ctx); + BN_CTX_free(bn_ctx); } @@ -784,7 +781,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const char *password, int num_of_password_shares) { sc_cardctl_sc_hsm_dkek_t dkekinfo; - EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER_CTX *bn_ctx = NULL; FILE *in = NULL; u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; char *pwd = NULL; @@ -842,14 +839,14 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c free(pwd); } - ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { + bn_ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } - if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) { + if (!EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } @@ -863,7 +860,7 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, (void *)&dkekinfo); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(bn_ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -884,7 +881,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch // hex output can be used in the SCSH shell with the // decrypt_keyblob.js file sc_cardctl_sc_hsm_dkek_t dkekinfo; - EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER_CTX *bn_ctx = NULL; FILE *in = NULL; u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; char *pwd = NULL; @@ -943,14 +940,14 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch free(pwd); } - ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { + bn_ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } - if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) { + if (!EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } @@ -970,7 +967,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch printf("\n\n"); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(bn_ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -1155,7 +1152,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const char *password, int password_shares_threshold, int password_shares_total) { - EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER_CTX *c_ctx = NULL; FILE *out = NULL; u8 filebuff[64], key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; u8 dkek_share[32]; @@ -1206,14 +1203,14 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const return -1; } - ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_EncryptUpdate(ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { + c_ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(c_ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_EncryptUpdate(c_ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { fprintf(stderr, "Error encrypting DKEK share\n"); return -1; } - if (!EVP_EncryptFinal_ex(ctx, filebuff + 16 + outlen, &r)) { + if (!EVP_EncryptFinal_ex(c_ctx, filebuff + 16 + outlen, &r)) { fprintf(stderr, "Error encrypting DKEK share\n"); return -1; } @@ -1234,7 +1231,7 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const fclose(out); OPENSSL_cleanse(filebuff, sizeof(filebuff)); - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(c_ctx); printf("DKEK share created and saved to %s\n", outf); return 0; @@ -1302,7 +1299,7 @@ static int wrap_with_tag(u8 tag, u8 *indata, size_t inlen, u8 **outdata, size_t -static int wrap_key(sc_card_t *card, int keyid, const char *outf, const char *pin) +static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *outf, const char *pin) { sc_cardctl_sc_hsm_wrapped_key_t wrapped_key; struct sc_pin_cmd_data data; @@ -1706,6 +1703,8 @@ int main(int argc, char *argv[]) int opt_force = 0; int opt_iter = 10000000; sc_context_param_t ctx_param; + sc_context_t *ctx = NULL; + sc_card_t *card = NULL; while (1) { c = getopt_long(argc, argv, "XC:I:P:W:U:s:i:fr:wv", options, &long_optind); @@ -1839,7 +1838,7 @@ int main(int argc, char *argv[]) if (do_print_dkek_share && print_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_total)) goto fail; - if (do_wrap_key && wrap_key(card, opt_key_reference, opt_filename, opt_pin)) + if (do_wrap_key && wrap_key(ctx, card, opt_key_reference, opt_filename, opt_pin)) goto fail; if (do_unwrap_key && unwrap_key(card, opt_key_reference, opt_filename, opt_pin, opt_force)) diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 4bcf9fdf86..d56ba57168 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -292,13 +292,13 @@ static int unlock_pin(sc_card_t *card, return 0; } -static int cert2der(X509 *cert, u8 **value) +static int cert2der(X509 *in_cert, u8 **value) { int len; u8 *p; - len = i2d_X509(cert, NULL); + len = i2d_X509(in_cert, NULL); p = *value = malloc(len); - i2d_X509(cert, &p); + i2d_X509(in_cert, &p); return len; } From 745b8cf42046f40b51af86372dd45b63e5413f67 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 11:14:20 +0100 Subject: [PATCH 0728/4321] added include guards to compatibility headers --- src/common/compat_strlcat.h | 11 ++++++++++- src/common/compat_strlcpy.h | 11 ++++++++++- src/common/compat_strnlen.h | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/common/compat_strlcat.h b/src/common/compat_strlcat.h index d3cce7eb65..f0284acaa0 100644 --- a/src/common/compat_strlcat.h +++ b/src/common/compat_strlcat.h @@ -1,9 +1,18 @@ /** * @file - * @brief prototypes of strlcpy()/strlcat() imported from OpenBSD + * @brief prototypes of strlcat() imported from OpenBSD */ +#ifndef __COMPAT_STRLCAT_H +#define __COMPAT_STRLCAT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef HAVE_STRLCAT #include size_t strlcat(char *dst, const char *src, size_t siz); #endif + +#endif diff --git a/src/common/compat_strlcpy.h b/src/common/compat_strlcpy.h index d97e405ccc..5a6067fbc4 100644 --- a/src/common/compat_strlcpy.h +++ b/src/common/compat_strlcpy.h @@ -28,10 +28,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * @file - * @brief prototypes of strlcpy()/strlcat() imported from OpenBSD + * @brief prototypes of strlcpy() imported from OpenBSD */ +#ifndef __COMPAT_STRLCPY_H +#define __COMPAT_STRLCPY_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef HAVE_STRLCPY #include size_t strlcpy(char *dst, const char *src, size_t siz); #endif + +#endif diff --git a/src/common/compat_strnlen.h b/src/common/compat_strnlen.h index dd9bc9841a..7c04180b17 100644 --- a/src/common/compat_strnlen.h +++ b/src/common/compat_strnlen.h @@ -3,7 +3,16 @@ * @brief prototype of strnlen() from OpenBSD */ +#ifndef __COMPAT_STRNLEN_H +#define __COMPAT_STRNLEN_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef HAVE_STRNLEN #include size_t strnlen(const char *str, size_t maxlen); #endif + +#endif From 79d019fc5fa6addad87abbc86e5324f07f5a0e45 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Jan 2019 12:41:39 +0100 Subject: [PATCH 0729/4321] fixed typo closes https://github.com/OpenSC/OpenSC/issues/1576 --- src/libopensc/card-gids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index cfee574ee3..9718283d4b 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1315,7 +1315,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { if (strcmp(DEFAULT_PRIVATE_KEY_LABEL, object->label) == 0 && strlen(DEFAULT_PRIVATE_KEY_LABEL) + 3 < MAX_CONTAINER_NAME_LEN) { char addition[4] = " 00"; addition[1] += containernum % 10; - addition[2] += (containernum < 0xFF) / 10; + addition[2] += (containernum & 0xFF) / 10; strcat(object->label, addition); } From 1565f48084cd5314766729193c0083f7e30ca000 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 16:32:08 +0100 Subject: [PATCH 0730/4321] added LGTM badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85f98f361f..e6fdf25ac5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. -[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) +[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp) Build and test status of specific cards: From 4916d07ff2a370b10446fa5c4986a5de3c068caf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 16:52:46 +0100 Subject: [PATCH 0731/4321] fixed unused check --- src/libopensc/card-starcos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 27a0692ec8..6218ad553a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -697,8 +697,7 @@ static int starcos_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); if (card->type != SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5 - || (pathlen == 0 && card->cache.current_path.type != SC_PATH_TYPE_DF_NAME)) { + || card->type == SC_CARD_TYPE_STARCOS_V3_5) { /* unify path (the first FID should be MF) */ if (path[0] != 0x3f || path[1] != 0x00) { From f161c3a17861f389643b18c4e454bfdba33b40a6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 Jan 2019 10:55:24 +0100 Subject: [PATCH 0732/4321] Remove repeated words from manual pages --- doc/files/opensc.conf.5.xml.in | 2 +- doc/tools/pkcs15-init.1.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 9c58877987..df9088081b 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -215,7 +215,7 @@ app application { If an unknown (i.e. not internal or old) driver is - supplied, a separate configuration configuration + supplied, a separate configuration block has to be written for the driver. A special value old will load all statically linked drivers that may be removed in diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 0983dbca12..bed58f436d 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -148,7 +148,7 @@ In addition to storing the private portion of the key on the card, - pkcs15-init will also store the the public portion of the + pkcs15-init will also store the public portion of the key as a PKCS #15 public key object. @@ -165,7 +165,7 @@ In addition to storing the private portion of the key on the card, - pkcs15-init will also store the the public portion of the + pkcs15-init will also store the public portion of the key as a PKCS #15 public key object. From 70d690ace7a5ddc5a534e7455bdc1800e26cb807 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 24 Jan 2019 14:15:13 +0200 Subject: [PATCH 0733/4321] r value is already checked on line 113 (#1582) --- src/libopensc/pkcs15-esteid.c | 51 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index e416b18d7e..b47343d97c 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -109,34 +109,33 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) return SC_ERROR_INTERNAL; - if (i == 0) { - sc_pkcs15_cert_t *cert = NULL; - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); - if (r < 0) - return SC_ERROR_INTERNAL; - if (cert->key->algorithm == SC_ALGORITHM_EC) - field_length = cert->key->u.ec.params.field_length; - else - modulus_length = cert->key->u.rsa.modulus.len * 8; - if (r == SC_SUCCESS) { - static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; - u8 *cn_name = NULL; - size_t cn_len = 0; - sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, - cert->subject_len, &cn_oid, &cn_name, &cn_len); - if (cn_len > 0) { - char *token_name = malloc(cn_len+1); - if (token_name) { - memcpy(token_name, cn_name, cn_len); - token_name[cn_len] = '\0'; - set_string(&p15card->tokeninfo->label, (const char*)token_name); - free(token_name); - } - } - free(cn_name); - sc_pkcs15_free_certificate(cert); + if (i != 0) + continue; + + sc_pkcs15_cert_t *cert = NULL; + r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + if (r < 0) + return SC_ERROR_INTERNAL; + if (cert->key->algorithm == SC_ALGORITHM_EC) + field_length = cert->key->u.ec.params.field_length; + else + modulus_length = cert->key->u.rsa.modulus.len * 8; + static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; + u8 *cn_name = NULL; + size_t cn_len = 0; + sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, + cert->subject_len, &cn_oid, &cn_name, &cn_len); + if (cn_len > 0) { + char *token_name = malloc(cn_len+1); + if (token_name) { + memcpy(token_name, cn_name, cn_len); + token_name[cn_len] = '\0'; + set_string(&p15card->tokeninfo->label, (const char*)token_name); + free(token_name); } } + free(cn_name); + sc_pkcs15_free_certificate(cert); } /* the file with key pin info (tries left) */ From a8c84d490a76cb3caddafed022b16dda3f63e837 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Jan 2019 17:03:33 +0100 Subject: [PATCH 0734/4321] handle multiple verifications when changing secret --- src/tools/goid-tool.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 100b75246b..3eb93aa7e9 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -252,10 +252,25 @@ soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) { int ok = 0; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x00, p2); + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, p1, p2); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_transmit_apdu(card, &apdu), "Changing secret failed"); + while (apdu.sw1 == 0x91 && apdu.sw2 == 0x00) { + switch (p2) { + case 0x80: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify your PIN on the card using the same position."); + break; + case 0x40: + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify your finger print on the card using the same position."); + break; + } + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_transmit_apdu(card, &apdu), + "Changing secret failed"); + } SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_check_sw(card, apdu.sw1, apdu.sw2), "Verification failed"); From fc08d8924795e91e09d166e441ca893d4d03fdd8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 30 Jan 2019 09:27:19 +0100 Subject: [PATCH 0735/4321] goid-tool: differ PAccess and SoCManager usage --- src/tools/goid-tool-cmdline.c | 128 ++++++++++++++++++++++++---------- src/tools/goid-tool-cmdline.h | 2 + src/tools/goid-tool.c | 4 +- src/tools/goid-tool.ggo.in | 96 ++++++++++++------------- 4 files changed, 145 insertions(+), 85 deletions(-) diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index 8fd6e44405..012af87620 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -37,14 +37,15 @@ const char *gengetopt_args_info_help[] = { " -V, --version Print version and exit", " -r, --reader=STRING Number of the reader to use. By default, the\n first reader with a present card is used. If\n the arguement is an ATR, the reader with a\n matching card will be chosen.", " -v, --verbose Use (several times) to be more verbose", - "\nSoCManager Applet:", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", + "\n Mode: soc\n Options for SoCManager Applet", " -p, --verify-pin Verify PIN", " -b, --verify-bio Verify finger print", " --verify-pin-or-bio Verify PIN or finger print (user's choice)", " --new-pin Change PIN", " --new-bio Use (several times) to change one or more\n biometric templates", " --info Dump Information about the SoCManager's\n configuration", - "\nPAccess Applet:", + "\n Mode: pxs\n Options for PAccess Applet", " -c, --certificate=FILENAME Use (several times) to pass CV certificates", " -k, --key=FILENAME Private key for the CV certificate", " --print-cardid Print the card ID", @@ -62,7 +63,6 @@ const char *gengetopt_args_info_help[] = { " --new-read-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", " --new-write-ac=STRING Access condition for writing newly created DGs\n (possible values=\"always\", \"never\",\n \"ta\", \"sm\" default=`sm')", " --new-write-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", - "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; @@ -119,6 +119,8 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->new_read_ac_chatbit_given = 0 ; args_info->new_write_ac_given = 0 ; args_info->new_write_ac_chatbit_given = 0 ; + args_info->pxs_mode_counter = 0 ; + args_info->soc_mode_counter = 0 ; } static @@ -171,47 +173,47 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->verbose_help = gengetopt_args_info_help[3] ; args_info->verbose_min = 0; args_info->verbose_max = 0; - args_info->verify_pin_help = gengetopt_args_info_help[5] ; - args_info->verify_bio_help = gengetopt_args_info_help[6] ; - args_info->verify_pin_or_bio_help = gengetopt_args_info_help[7] ; - args_info->new_pin_help = gengetopt_args_info_help[8] ; - args_info->new_bio_help = gengetopt_args_info_help[9] ; + args_info->verify_pin_help = gengetopt_args_info_help[6] ; + args_info->verify_bio_help = gengetopt_args_info_help[7] ; + args_info->verify_pin_or_bio_help = gengetopt_args_info_help[8] ; + args_info->new_pin_help = gengetopt_args_info_help[9] ; + args_info->new_bio_help = gengetopt_args_info_help[10] ; args_info->new_bio_min = 0; args_info->new_bio_max = 0; - args_info->info_help = gengetopt_args_info_help[10] ; - args_info->certificate_help = gengetopt_args_info_help[12] ; + args_info->info_help = gengetopt_args_info_help[11] ; + args_info->certificate_help = gengetopt_args_info_help[13] ; args_info->certificate_min = 0; args_info->certificate_max = 0; - args_info->key_help = gengetopt_args_info_help[13] ; - args_info->print_cardid_help = gengetopt_args_info_help[14] ; - args_info->write_cardid_help = gengetopt_args_info_help[15] ; - args_info->print_paccessid_help = gengetopt_args_info_help[16] ; - args_info->write_paccessid_help = gengetopt_args_info_help[17] ; - args_info->read_dg_help = gengetopt_args_info_help[18] ; + args_info->key_help = gengetopt_args_info_help[14] ; + args_info->print_cardid_help = gengetopt_args_info_help[15] ; + args_info->write_cardid_help = gengetopt_args_info_help[16] ; + args_info->print_paccessid_help = gengetopt_args_info_help[17] ; + args_info->write_paccessid_help = gengetopt_args_info_help[18] ; + args_info->read_dg_help = gengetopt_args_info_help[19] ; args_info->read_dg_min = 0; args_info->read_dg_max = 0; - args_info->out_file_help = gengetopt_args_info_help[19] ; + args_info->out_file_help = gengetopt_args_info_help[20] ; args_info->out_file_min = 0; args_info->out_file_max = 0; - args_info->write_dg_help = gengetopt_args_info_help[20] ; + args_info->write_dg_help = gengetopt_args_info_help[21] ; args_info->write_dg_min = 0; args_info->write_dg_max = 0; - args_info->in_file_help = gengetopt_args_info_help[21] ; + args_info->in_file_help = gengetopt_args_info_help[22] ; args_info->in_file_min = 0; args_info->in_file_max = 0; - args_info->delete_dg_help = gengetopt_args_info_help[22] ; + args_info->delete_dg_help = gengetopt_args_info_help[23] ; args_info->delete_dg_min = 0; args_info->delete_dg_max = 0; - args_info->create_dg_help = gengetopt_args_info_help[23] ; + args_info->create_dg_help = gengetopt_args_info_help[24] ; args_info->create_dg_min = 0; args_info->create_dg_max = 0; - args_info->new_size_help = gengetopt_args_info_help[24] ; - args_info->new_read_ac_help = gengetopt_args_info_help[25] ; - args_info->new_read_ac_chatbit_help = gengetopt_args_info_help[26] ; + args_info->new_size_help = gengetopt_args_info_help[25] ; + args_info->new_read_ac_help = gengetopt_args_info_help[26] ; + args_info->new_read_ac_chatbit_help = gengetopt_args_info_help[27] ; args_info->new_read_ac_chatbit_min = 0; args_info->new_read_ac_chatbit_max = 0; - args_info->new_write_ac_help = gengetopt_args_info_help[27] ; - args_info->new_write_ac_chatbit_help = gengetopt_args_info_help[28] ; + args_info->new_write_ac_help = gengetopt_args_info_help[28] ; + args_info->new_write_ac_chatbit_help = gengetopt_args_info_help[29] ; args_info->new_write_ac_chatbit_min = 0; args_info->new_write_ac_chatbit_max = 0; @@ -764,34 +766,34 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro if (check_multiple_option_occurrences(prog_name, args_info->verbose_given, args_info->verbose_min, args_info->verbose_max, "'--verbose' ('-v')")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->new_bio_given, args_info->new_bio_min, args_info->new_bio_max, "'--new-bio'")) + if (args_info->soc_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_bio_given, args_info->new_bio_min, args_info->new_bio_max, "'--new-bio'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->certificate_given, args_info->certificate_min, args_info->certificate_max, "'--certificate' ('-c')")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->certificate_given, args_info->certificate_min, args_info->certificate_max, "'--certificate' ('-c')")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->read_dg_given, args_info->read_dg_min, args_info->read_dg_max, "'--read-dg'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->read_dg_given, args_info->read_dg_min, args_info->read_dg_max, "'--read-dg'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->out_file_given, args_info->out_file_min, args_info->out_file_max, "'--out-file'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->out_file_given, args_info->out_file_min, args_info->out_file_max, "'--out-file'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->write_dg_given, args_info->write_dg_min, args_info->write_dg_max, "'--write-dg'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->write_dg_given, args_info->write_dg_min, args_info->write_dg_max, "'--write-dg'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->in_file_given, args_info->in_file_min, args_info->in_file_max, "'--in-file'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->in_file_given, args_info->in_file_min, args_info->in_file_max, "'--in-file'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->delete_dg_given, args_info->delete_dg_min, args_info->delete_dg_max, "'--delete-dg'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->delete_dg_given, args_info->delete_dg_min, args_info->delete_dg_max, "'--delete-dg'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->create_dg_given, args_info->create_dg_min, args_info->create_dg_max, "'--create-dg'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->create_dg_given, args_info->create_dg_min, args_info->create_dg_max, "'--create-dg'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->new_read_ac_chatbit_given, args_info->new_read_ac_chatbit_min, args_info->new_read_ac_chatbit_max, "'--new-read-ac-chatbit'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_read_ac_chatbit_given, args_info->new_read_ac_chatbit_min, args_info->new_read_ac_chatbit_max, "'--new-read-ac-chatbit'")) error_occurred = 1; - if (check_multiple_option_occurrences(prog_name, args_info->new_write_ac_chatbit_given, args_info->new_write_ac_chatbit_min, args_info->new_write_ac_chatbit_max, "'--new-write-ac-chatbit'")) + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_write_ac_chatbit_given, args_info->new_write_ac_chatbit_min, args_info->new_write_ac_chatbit_max, "'--new-write-ac-chatbit'")) error_occurred = 1; @@ -1682,6 +1684,29 @@ void update_multiple_arg(void *field, char ***orig_field, } } +static int check_modes( + int given1[], const char *options1[], + int given2[], const char *options2[]) +{ + int i = 0, j = 0, errors = 0; + + while (given1[i] >= 0) { + if (given1[i]) { + while (given2[j] >= 0) { + if (given2[j]) { + ++errors; + fprintf(stderr, "%s: option %s conflicts with option %s\n", + package_name, options1[i], options2[j]); + } + ++j; + } + } + ++i; + } + + return errors; +} + int cmdline_parser_internal ( int argc, char **argv, struct gengetopt_args_info *args_info, @@ -1807,6 +1832,7 @@ cmdline_parser_internal ( break; case 'p': /* Verify PIN. */ + args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1819,6 +1845,7 @@ cmdline_parser_internal ( break; case 'b': /* Verify finger print. */ + args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1831,6 +1858,7 @@ cmdline_parser_internal ( break; case 'c': /* Use (several times) to pass CV certificates. */ + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&certificate_list, &(local_args_info.certificate_given), optarg, 0, 0, ARG_STRING, @@ -1840,6 +1868,7 @@ cmdline_parser_internal ( break; case 'k': /* Private key for the CV certificate. */ + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->key_arg), @@ -1856,6 +1885,7 @@ cmdline_parser_internal ( /* Verify PIN or finger print (user's choice). */ if (strcmp (long_options[option_index].name, "verify-pin-or-bio") == 0) { + args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1870,6 +1900,7 @@ cmdline_parser_internal ( /* Change PIN. */ else if (strcmp (long_options[option_index].name, "new-pin") == 0) { + args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1884,6 +1915,7 @@ cmdline_parser_internal ( /* Use (several times) to change one or more biometric templates. */ else if (strcmp (long_options[option_index].name, "new-bio") == 0) { + args_info->soc_mode_counter += 1; local_args_info.new_bio_given++; @@ -1891,6 +1923,7 @@ cmdline_parser_internal ( /* Dump Information about the SoCManager's configuration. */ else if (strcmp (long_options[option_index].name, "info") == 0) { + args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1905,6 +1938,7 @@ cmdline_parser_internal ( /* Print the card ID. */ else if (strcmp (long_options[option_index].name, "print-cardid") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( 0 , @@ -1919,6 +1953,7 @@ cmdline_parser_internal ( /* Write the specified card ID. */ else if (strcmp (long_options[option_index].name, "write-cardid") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->write_cardid_arg), @@ -1933,6 +1968,7 @@ cmdline_parser_internal ( /* Print the PAccess ID. */ else if (strcmp (long_options[option_index].name, "print-paccessid") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( 0 , @@ -1947,6 +1983,7 @@ cmdline_parser_internal ( /* Write the specified PAccess ID. */ else if (strcmp (long_options[option_index].name, "write-paccessid") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->write_paccessid_arg), @@ -1961,6 +1998,7 @@ cmdline_parser_internal ( /* Read the specified data group; use several times to read out multiple files. */ else if (strcmp (long_options[option_index].name, "read-dg") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&read_dg_list, &(local_args_info.read_dg_given), optarg, 0, 0, ARG_INT, @@ -1972,6 +2010,7 @@ cmdline_parser_internal ( /* Write output to a file instead of printing it; use once for each use of `--read-dg'. */ else if (strcmp (long_options[option_index].name, "out-file") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&out_file_list, &(local_args_info.out_file_given), optarg, 0, 0, ARG_STRING, @@ -1983,6 +2022,7 @@ cmdline_parser_internal ( /* Write the specified data group; use several times to write multiple files. */ else if (strcmp (long_options[option_index].name, "write-dg") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&write_dg_list, &(local_args_info.write_dg_given), optarg, 0, 0, ARG_INT, @@ -1994,6 +2034,7 @@ cmdline_parser_internal ( /* Read input from a file; use once for each use of `--write-dg'. */ else if (strcmp (long_options[option_index].name, "in-file") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&in_file_list, &(local_args_info.in_file_given), optarg, 0, 0, ARG_STRING, @@ -2005,6 +2046,7 @@ cmdline_parser_internal ( /* Delete the specified data group; use several times to delete multiple files. */ else if (strcmp (long_options[option_index].name, "delete-dg") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&delete_dg_list, &(local_args_info.delete_dg_given), optarg, 0, 0, ARG_INT, @@ -2016,6 +2058,7 @@ cmdline_parser_internal ( /* Create the specified data group; use several times to create multiple files. */ else if (strcmp (long_options[option_index].name, "create-dg") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&create_dg_list, &(local_args_info.create_dg_given), optarg, 0, 0, ARG_INT, @@ -2027,6 +2070,7 @@ cmdline_parser_internal ( /* File size of newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-size") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->new_size_arg), @@ -2041,6 +2085,7 @@ cmdline_parser_internal ( /* Access condition for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-read-ac") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->new_read_ac_arg), @@ -2055,6 +2100,7 @@ cmdline_parser_internal ( /* Required access bits in certificate's CHAT for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-read-ac-chatbit") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&new_read_ac_chatbit_list, &(local_args_info.new_read_ac_chatbit_given), optarg, 0, 0, ARG_INT, @@ -2066,6 +2112,7 @@ cmdline_parser_internal ( /* Access condition for writing newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-write-ac") == 0) { + args_info->pxs_mode_counter += 1; if (update_arg( (void *)&(args_info->new_write_ac_arg), @@ -2080,6 +2127,7 @@ cmdline_parser_internal ( /* Required access bits in certificate's CHAT for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-write-ac-chatbit") == 0) { + args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&new_write_ac_chatbit_list, &(local_args_info.new_write_ac_chatbit_given), optarg, 0, 0, ARG_INT, @@ -2161,6 +2209,14 @@ cmdline_parser_internal ( args_info->new_write_ac_chatbit_given += local_args_info.new_write_ac_chatbit_given; local_args_info.new_write_ac_chatbit_given = 0; + if (args_info->pxs_mode_counter && args_info->soc_mode_counter) { + int pxs_given[] = {args_info->certificate_given, args_info->key_given, args_info->print_cardid_given, args_info->write_cardid_given, args_info->print_paccessid_given, args_info->write_paccessid_given, args_info->read_dg_given, args_info->out_file_given, args_info->write_dg_given, args_info->in_file_given, args_info->delete_dg_given, args_info->create_dg_given, args_info->new_size_given, args_info->new_read_ac_given, args_info->new_read_ac_chatbit_given, args_info->new_write_ac_given, args_info->new_write_ac_chatbit_given, -1}; + const char *pxs_desc[] = {"--certificate", "--key", "--print-cardid", "--write-cardid", "--print-paccessid", "--write-paccessid", "--read-dg", "--out-file", "--write-dg", "--in-file", "--delete-dg", "--create-dg", "--new-size", "--new-read-ac", "--new-read-ac-chatbit", "--new-write-ac", "--new-write-ac-chatbit", 0}; + int soc_given[] = {args_info->verify_pin_given, args_info->verify_bio_given, args_info->verify_pin_or_bio_given, args_info->new_pin_given, args_info->new_bio_given, args_info->info_given, -1}; + const char *soc_desc[] = {"--verify-pin", "--verify-bio", "--verify-pin-or-bio", "--new-pin", "--new-bio", "--info", 0}; + error_occurred += check_modes(pxs_given, pxs_desc, soc_given, soc_desc); + } + if (check_required) { error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error); diff --git a/src/tools/goid-tool-cmdline.h b/src/tools/goid-tool-cmdline.h index 0473189c80..f684b6df6d 100644 --- a/src/tools/goid-tool-cmdline.h +++ b/src/tools/goid-tool-cmdline.h @@ -147,6 +147,8 @@ struct gengetopt_args_info unsigned int new_write_ac_given ; /**< @brief Whether new-write-ac was given. */ unsigned int new_write_ac_chatbit_given ; /**< @brief Whether new-write-ac-chatbit was given. */ + int pxs_mode_counter; /**< @brief Counter for mode pxs */ + int soc_mode_counter; /**< @brief Counter for mode soc */ } ; /** @brief The additional parameters to pass to parser functions */ diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 3eb93aa7e9..99c61c365d 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -810,7 +810,9 @@ main(int argc, char **argv) SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, "Error connecting to card."); - if (!soc_main(ctx, card, &cmdline) || !paccess_main(ctx, card, &cmdline)) + if (cmdline.soc_mode_counter && !soc_main(ctx, card, &cmdline)) + goto err; + if (cmdline.pxs_mode_counter && !paccess_main(ctx, card, &cmdline)) goto err; fail = 0; diff --git a/src/tools/goid-tool.ggo.in b/src/tools/goid-tool.ggo.in index 1faf085b02..b646166348 100644 --- a/src/tools/goid-tool.ggo.in +++ b/src/tools/goid-tool.ggo.in @@ -8,78 +8,78 @@ option "verbose" v "Use (several times) to be more verbose" multiple optional -section "SoCManager Applet" -option "verify-pin" p +defmode "soc" modedesc="Options for SoCManager Applet" +modeoption "verify-pin" p "Verify PIN" - optional -option "verify-bio" b + mode="soc" optional +modeoption "verify-bio" b "Verify finger print" - optional -option "verify-pin-or-bio" - + mode="soc" optional +modeoption "verify-pin-or-bio" - "Verify PIN or finger print (user's choice)" - optional -option "new-pin" - + mode="soc" optional +modeoption "new-pin" - "Change PIN" - optional -option "new-bio" - + mode="soc" optional +modeoption "new-bio" - "Use (several times) to change one or more biometric templates" - multiple optional -option "info" - + mode="soc" multiple optional +modeoption "info" - "Dump Information about the SoCManager's configuration" - optional + mode="soc" optional -section "PAccess Applet" -option "certificate" c +defmode "pxs" modedesc="Options for PAccess Applet" +modeoption "certificate" c "Use (several times) to pass CV certificates" - string multiple optional dependon="key" typestr="FILENAME" -option "key" k + string mode="pxs" multiple optional dependon="key" typestr="FILENAME" +modeoption "key" k "Private key for the CV certificate" - string optional dependon="certificate" typestr="FILENAME" -option "print-cardid" - + string mode="pxs" optional dependon="certificate" typestr="FILENAME" +modeoption "print-cardid" - "Print the card ID" - optional -option "write-cardid" - + mode="pxs" optional +modeoption "write-cardid" - "Write the specified card ID" - string optional typestr="CARDID" -option "print-paccessid" - + string mode="pxs" optional typestr="CARDID" +modeoption "print-paccessid" - "Print the PAccess ID" - optional -option "write-paccessid" - + mode="pxs" optional +modeoption "write-paccessid" - "Write the specified PAccess ID" - string optional typestr="PACCESSID" -option "read-dg" - + string mode="pxs" optional typestr="PACCESSID" +modeoption "read-dg" - "Read the specified data group; use several times to read out multiple files" - int optional multiple typestr="ID" -option "out-file" - + int mode="pxs" optional multiple typestr="ID" +modeoption "out-file" - "Write output to a file instead of printing it; use once for each use of `--read-dg'" - string optional multiple typestr="FILENAME" -option "write-dg" - + string mode="pxs" optional multiple typestr="FILENAME" +modeoption "write-dg" - "Write the specified data group; use several times to write multiple files" - int optional multiple typestr="ID" -option "in-file" - + int mode="pxs" optional multiple typestr="ID" +modeoption "in-file" - "Read input from a file; use once for each use of `--write-dg'" - string optional multiple typestr="FILENAME" -option "delete-dg" - + string mode="pxs" optional multiple typestr="FILENAME" +modeoption "delete-dg" - "Delete the specified data group; use several times to delete multiple files" - int optional multiple typestr="ID" -option "create-dg" - + int mode="pxs" optional multiple typestr="ID" +modeoption "create-dg" - "Create the specified data group; use several times to create multiple files" - int optional multiple typestr="ID" -option "new-size" - + int mode="pxs" optional multiple typestr="ID" +modeoption "new-size" - "File size of newly created DGs" - int optional dependon="create-dg" typestr="SIZE" default="256" -option "new-read-ac" - + int mode="pxs" optional dependon="create-dg" typestr="SIZE" default="256" +modeoption "new-read-ac" - "Access condition for reading newly created DGs" - values="always","never","ta","sm" default="sm" optional dependon="create-dg" -option "new-read-ac-chatbit" - + values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" +modeoption "new-read-ac-chatbit" - "Required access bits in certificate's CHAT for reading newly created DGs" - int optional dependon="create-dg" multiple typestr="INDEX" -option "new-write-ac" - + int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" +modeoption "new-write-ac" - "Access condition for writing newly created DGs" - values="always","never","ta","sm" default="sm" optional dependon="create-dg" -option "new-write-ac-chatbit" - + values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" +modeoption "new-write-ac-chatbit" - "Required access bits in certificate's CHAT for reading newly created DGs" - int optional dependon="create-dg" multiple typestr="INDEX" + int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" text " Report bugs to @PACKAGE_BUGREPORT@ From 83c4ebe9d6b378c97b1d628dfa7f33bb3fd00403 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 30 Jan 2019 12:59:22 +0100 Subject: [PATCH 0736/4321] goid-tool: reset authentication status --- src/tools/goid-tool.c | 50 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 99c61c365d..c2d019820c 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -43,19 +43,23 @@ static const unsigned char paccess_aid[] = { }; static const char *app_name = "goid-tool"; +#define SOCM_AUTHOBJECT_PIN 0x80 +#define SOCM_AUTHOBJECT_BIO 0x40 +#define SOCM_AUTHOBJECT_GP 0x20 + void print_permissions(u8 permissions) { size_t perms_printed = 0; - if (permissions & 0x80) { + if (permissions & SOCM_AUTHOBJECT_PIN) { printf("%s PIN", perms_printed ? " or" : "verification of"); perms_printed++; } - if (permissions & 0x40) { + if (permissions & SOCM_AUTHOBJECT_BIO) { printf("%s BIO", perms_printed ? " or" : "verification of"); perms_printed++; } - if (permissions & 0x20) { + if (permissions & SOCM_AUTHOBJECT_GP) { printf("%s GP key", perms_printed ? " or" : "verification of"); perms_printed++; } @@ -247,6 +251,25 @@ soc_verify(sc_card_t *card, unsigned char p2) return ok; } +int +soc_reset(sc_card_t *card, unsigned char p2) +{ + int ok = 0; + sc_apdu_t apdu; + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0xFF, p2); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_transmit_apdu(card, &apdu), + "Reset failed"); + if (apdu.sw1 != 0x63) { + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_check_sw(card, apdu.sw1, apdu.sw2), + "Reset failed"); + } + ok = 1; +err: + return ok; +} + int soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) { @@ -258,11 +281,11 @@ soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) "Changing secret failed"); while (apdu.sw1 == 0x91 && apdu.sw2 == 0x00) { switch (p2) { - case 0x80: + case SOCM_AUTHOBJECT_PIN: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify your PIN on the card using the same position."); break; - case 0x40: + case SOCM_AUTHOBJECT_BIO: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify your finger print on the card using the same position."); break; @@ -286,6 +309,7 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info struct sc_path path; unsigned char soc_manager_minor = 0; unsigned char soc_manager_major = 0; + unsigned char soc_reset_authobject = 0; sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_soc_manager, sizeof aid_soc_manager, 0, 0); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, @@ -317,26 +341,29 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info if (cmdline->verify_pin_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print or PIN on the card."); - if (!soc_verify(card, 0x80)) + if (!soc_verify(card, SOCM_AUTHOBJECT_PIN)) goto err; + soc_reset_authobject |= SOCM_AUTHOBJECT_PIN; } if (cmdline->verify_bio_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print on the card."); - if (!soc_verify(card, 0x40)) + if (!soc_verify(card, SOCM_AUTHOBJECT_BIO)) goto err; + soc_reset_authobject |= SOCM_AUTHOBJECT_BIO; } if (cmdline->verify_pin_or_bio_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Verify finger print or PIN on the card."); - if (!soc_verify(card, 0xC0)) + if (!soc_verify(card, SOCM_AUTHOBJECT_PIN|SOCM_AUTHOBJECT_BIO)) goto err; + soc_reset_authobject |= SOCM_AUTHOBJECT_PIN|SOCM_AUTHOBJECT_BIO; } if (cmdline->new_pin_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Initialize the PIN on the card."); - if (!soc_change(card, 0x00, 0x80)) + if (!soc_change(card, 0x00, SOCM_AUTHOBJECT_BIO)) goto err; } if (cmdline->new_bio_given) { @@ -345,7 +372,7 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Initialize finger print template %u on the card.", (unsigned char) i); - if (!soc_change(card, (unsigned char) i, 0x40)) + if (!soc_change(card, (unsigned char) i, SOCM_AUTHOBJECT_BIO)) goto err; i++; } @@ -354,6 +381,9 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info ok = 1; err: + if (soc_reset_authobject) + soc_reset(card, soc_reset_authobject); + return ok; } From 893be0d9c09ca97cb85d9f785b282a5723d322da Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 10:07:20 +0100 Subject: [PATCH 0737/4321] fixed memory leaks --- src/libopensc/card-mcrd.c | 5 ++++- src/libopensc/card-piv.c | 15 +++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 7784f15bc5..db67f37afc 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -367,8 +367,11 @@ static int mcrd_init(sc_card_t * card) sc_format_path ("3f00", &tmppath); r = sc_select_file (card, &tmppath, NULL); - if (r < 0) + if (r < 0) { + free(card->drv_data); + card->drv_data = NULL; r = SC_ERROR_INVALID_CARD; + } /* Not needed for the fixed EstEID profile */ if (!is_esteid_card(card)) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 3298a68845..0e56d455a3 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1091,12 +1091,15 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) priv->obj_cache[enumtag].internal_obj_data, priv->obj_cache[enumtag].internal_obj_len); - } else if (r == 0 || r == SC_ERROR_FILE_NOT_FOUND) { - r = SC_ERROR_FILE_NOT_FOUND; - priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID; - priv->obj_cache[enumtag].obj_len = 0; - } else if ( r < 0) { - goto err; + } else { + free(rbuf); + if (r == 0 || r == SC_ERROR_FILE_NOT_FOUND) { + r = SC_ERROR_FILE_NOT_FOUND; + priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID; + priv->obj_cache[enumtag].obj_len = 0; + } else if ( r < 0) { + goto err; + } } ok: From 2ad745371834044a921161042a058b31acce765f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 11:15:35 +0100 Subject: [PATCH 0738/4321] use const qualifier for sc_simpletlv_read/put_tag --- src/libopensc/card-cac.c | 29 ++++++++++++++++------------- src/libopensc/card-piv.c | 2 +- src/libopensc/simpletlv.c | 4 ++-- src/libopensc/simpletlv.h | 2 +- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 4ffe7497d7..634c0d27fb 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -455,8 +455,9 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, cac_private_data_t * priv = CAC_DATA(card); int r = 0; u8 *tl = NULL, *val = NULL; - u8 *tl_ptr, *val_ptr, *tlv_ptr, *tl_start; - u8 *cert_ptr; + const u8 *tl_ptr, *val_ptr, *tl_start; + u8 *tlv_ptr; + const u8 *cert_ptr; size_t tl_len, val_len, tlv_len; size_t len, tl_head_len, cert_len; u8 cert_type, tag; @@ -866,10 +867,11 @@ static int cac_decipher(sc_card_t *card, } static int cac_parse_properties_object(sc_card_t *card, u8 type, - u8 *data, size_t data_len, cac_properties_object_t *object) + const u8 *data, size_t data_len, cac_properties_object_t *object) { size_t len; - u8 *val, *val_end, tag; + const u8 *val, *val_end; + u8 tag; int parsed = 0; if (data_len < 11) @@ -947,7 +949,8 @@ static int cac_get_properties(sc_card_t *card, cac_properties_t *prop) { u8 *rbuf = NULL; size_t rbuflen = 0, len; - u8 *val, *val_end, tag; + const u8 *val, *val_end; + u8 tag; size_t i = 0; int r; prop->num_objects = 0; @@ -1286,7 +1289,7 @@ static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_ return SC_SUCCESS; } -static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int aid_len) +static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, const u8 *aid, int aid_len) { cac_object_t new_object; cac_properties_t prop; @@ -1417,12 +1420,12 @@ static int cac_parse_cuid(sc_card_t *card, cac_private_data_t *priv, cac_cuid_t } static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv); -static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl, +static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl, size_t tl_len, u8 *val, size_t val_len) { size_t len = 0; - u8 *tl_end = tl + tl_len; - u8 *val_end = val + val_len; + const u8 *tl_end = tl + tl_len; + const u8 *val_end = val + val_len; sc_path_t new_path; int r; @@ -1556,10 +1559,10 @@ static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv) * card, which is a good start if we don't have CCC */ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, - u8 *val, size_t val_len) + const u8 *val, size_t val_len) { size_t len = 0; - u8 *val_end = val + val_len; + const u8 *val_end = val + val_len; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1601,9 +1604,9 @@ static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv, break; } sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE, - "TAG: Applet Entry: AID", &val[3], val[2]); + "TAG: Applet Entry: AID", val + 3, val[2]); /* This is SimpleTLV prefixed with applet ID (1B) */ - r = cac_parse_aid(card, priv, &val[3], val[2]); + r = cac_parse_aid(card, priv, val + 3, val[2]); if (r < 0) return r; break; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 0e56d455a3..08b8960b3a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2742,7 +2742,7 @@ static int piv_process_discovery(sc_card_t *card) /* CCC entries are simple tlv */ end = body + bodylen; for(; (body < end); body += len) { - r = sc_simpletlv_read_tag((u8**)&body, end - body , &tag, &len); + r = sc_simpletlv_read_tag(&body, end - body , &tag, &len); if (r < 0) goto err; switch (tag) { diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c index 67a08da232..52090eadb7 100644 --- a/src/libopensc/simpletlv.c +++ b/src/libopensc/simpletlv.c @@ -72,11 +72,11 @@ sc_simpletlv_put_tag(u8 tag, size_t datalen, u8 *out, size_t outlen, u8 **ptr) * content. */ int -sc_simpletlv_read_tag(u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen) +sc_simpletlv_read_tag(const u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen) { u8 tag; size_t left = buflen, len; - u8 *p = *buf; + const u8 *p = *buf; *buf = NULL; diff --git a/src/libopensc/simpletlv.h b/src/libopensc/simpletlv.h index c207441fa0..a952779733 100644 --- a/src/libopensc/simpletlv.h +++ b/src/libopensc/simpletlv.h @@ -49,6 +49,6 @@ int sc_simpletlv_put_tag(u8 tag, size_t datalen, u8 *out, size_t outlen, u8 **pt * @param taglen The length of the V record * @return SC_SUCCESS on valid input */ -int sc_simpletlv_read_tag(u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen); +int sc_simpletlv_read_tag(const u8 **buf, size_t buflen, u8 *tag_out, size_t *taglen); #endif From 9e5d7bc87366a3737b680ad796f802d8f919ff9f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 12:21:47 +0100 Subject: [PATCH 0739/4321] added minimal test script for fuzzing with AFL Credits go to https://www.x41-dsec.de/lab/blog/smartcards/ --- tests/test-fuzzing-pkcs15-tool-dump.sh | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/test-fuzzing-pkcs15-tool-dump.sh diff --git a/tests/test-fuzzing-pkcs15-tool-dump.sh b/tests/test-fuzzing-pkcs15-tool-dump.sh new file mode 100644 index 0000000000..c66b030498 --- /dev/null +++ b/tests/test-fuzzing-pkcs15-tool-dump.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +if [ ! -d x41-smartcard-fuzzing ]; +then + git clone https://github.com/x41sec/x41-smartcard-fuzzing +fi + +gcc -shared -fPIC -o x41-smartcard-fuzzing/scard_override/libsccard_override.so x41-smartcard-fuzzing/scard_override/scard_override.c -ldl -I/usr/include/PCSC/ + +if [ ! -f configure ]; +then + autoreconf -vis +fi + +if [ ! -f Makefile ]; +then + make clean +fi + +#export AFL_USE_ASAN=1 +./configure CC=afl-gcc CFLAGS="-O0" LDFLAGS="-ldl" --disable-shared --disable-notify --with-pcsc-provider=$PWD/x41-smartcard-fuzzing/scard_override/libsccard_override.so +make + +mkdir -p tests/fuzzing-testcases +echo -ne "$(printf '\\x90\\x00')" > tests/fuzzing-testcases/9000 + +FUZZ_FILE=input.apdu afl-fuzz -i tests/fuzzing-testcases -o out -f input.apdu src/tools/pkcs15-tool -D From d0b499cda393e89039838e4b6b8e9b576e562943 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Jan 2019 16:30:43 +0100 Subject: [PATCH 0740/4321] reuse previous fuzzing results if possible --- tests/test-fuzzing-pkcs15-tool-dump.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/test-fuzzing-pkcs15-tool-dump.sh b/tests/test-fuzzing-pkcs15-tool-dump.sh index c66b030498..574c7f2c76 100644 --- a/tests/test-fuzzing-pkcs15-tool-dump.sh +++ b/tests/test-fuzzing-pkcs15-tool-dump.sh @@ -21,7 +21,13 @@ fi ./configure CC=afl-gcc CFLAGS="-O0" LDFLAGS="-ldl" --disable-shared --disable-notify --with-pcsc-provider=$PWD/x41-smartcard-fuzzing/scard_override/libsccard_override.so make -mkdir -p tests/fuzzing-testcases -echo -ne "$(printf '\\x90\\x00')" > tests/fuzzing-testcases/9000 +if [ ! -d tests/fuzzing-testcases ] +then + mkdir -p tests/fuzzing-testcases + echo -ne "$(printf '\\x90\\x00')" > tests/fuzzing-testcases/9000 + IN=tests/fuzzing-testcases +else + IN=- +fi -FUZZ_FILE=input.apdu afl-fuzz -i tests/fuzzing-testcases -o out -f input.apdu src/tools/pkcs15-tool -D +FUZZ_FILE=input.apdu afl-fuzz -i $IN -o out -f input.apdu src/tools/pkcs15-tool -D From 7f7bcbff5268045c26dd7f93489a4d78b3f206cb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Jan 2019 14:43:28 +0100 Subject: [PATCH 0741/4321] fixed misuse of realloc calling it with size 0 leads to a free, which eventually may lead to a double free corruption. --- src/libopensc/asn1.c | 2 ++ src/libopensc/card-sc-hsm.c | 4 ++++ src/libopensc/dir.c | 2 ++ src/libopensc/pkcs15.c | 2 ++ src/libopensc/sc.c | 6 +++--- src/pkcs15init/pkcs15-oberthur-awp.c | 2 ++ src/sm/sm-eac.c | 18 +++++++++++++----- src/sm/sm-iso.c | 9 +++++++-- 8 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 3262ed8026..dffe9920c0 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1225,6 +1225,8 @@ static int asn1_encode_se_info(sc_context_t *ctx, if (ret != SC_SUCCESS) goto err; + if (!ptrlen) + continue; p = (unsigned char *) realloc(out, outlen + ptrlen); if (!p) { ret = SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index aaae65c2c5..ac4d1e9a64 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -520,6 +520,10 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) r = sc_read_binary(card, 0, all_certs, all_certs_len, 0); if (r < 0) goto err; + if (r == 0) { + r = SC_ERROR_FILE_NOT_FOUND; + goto err; + } all_certs_len = r; diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 9e6263fbaa..b6c9b646a6 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -307,6 +307,8 @@ static int update_transparent(sc_card_t *card, sc_file_t *file) free(buf); return r; } + if (!rec_size) + continue; tmp = (u8 *) realloc(buf, buf_size + rec_size); if (!tmp) { if (rec) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 8c4dc7ae62..823b236b03 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1983,6 +1983,8 @@ sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, stru free(buf); return r; } + if (!tmpsize) + continue; p = (u8 *) realloc(buf, bufsize + tmpsize); if (!p) { free(tmp); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index b18c937f7a..19407a10ed 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -672,7 +672,7 @@ int sc_file_set_prop_attr(sc_file_t *file, const u8 *prop_attr, return SC_ERROR_INVALID_ARGUMENTS; } - if (prop_attr == NULL) { + if (prop_attr == NULL || prop_attr_len == 0) { if (file->prop_attr != NULL) free(file->prop_attr); file->prop_attr = NULL; @@ -702,7 +702,7 @@ int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr, return SC_ERROR_INVALID_ARGUMENTS; } - if (type_attr == NULL) { + if (type_attr == NULL || type_attr_len == 0) { if (file->type_attr != NULL) free(file->type_attr); file->type_attr = NULL; @@ -733,7 +733,7 @@ int sc_file_set_content(sc_file_t *file, const u8 *content, return SC_ERROR_INVALID_ARGUMENTS; } - if (content == NULL) { + if (content == NULL || content_len == 0) { if (file->encoded_content != NULL) free(file->encoded_content); file->encoded_content = NULL; diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 4972ea87d0..ab67b6c4c3 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -219,6 +219,8 @@ awp_update_blob(struct sc_context *ctx, *blob_size += 1 + lv->len; break; case TLV_TYPE_V : + if (0 == *blob_size + lv->len) + return SC_ERROR_INVALID_DATA; if (!(pp = realloc(*blob, *blob_size + lv->len))) return SC_ERROR_OUT_OF_MEMORY; memcpy(pp + *blob_size, lv->value, lv->len); diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 11ad188c1c..105787f283 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -478,7 +478,7 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, r = SC_ERROR_INTERNAL; goto err; } - if (length < 0) { + if (length <= 0) { r = SC_ERROR_INTERNAL; goto err; } @@ -1321,6 +1321,10 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } + if (comp_pub_opp->length == 0) { + r = SC_ERROR_INTERNAL; + goto err; + } p = realloc(pace_output->id_icc, comp_pub_opp->length); if (!p) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for ID ICC.\n"); @@ -1333,6 +1337,10 @@ int perform_pace(sc_card_t *card, memcpy(pace_output->id_icc, comp_pub_opp->data, comp_pub_opp->length); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID ICC", pace_output->id_icc, pace_output->id_icc_length); + if (comp_pub->length == 0) { + r = SC_ERROR_INTERNAL; + goto err; + } p = realloc(pace_output->id_pcd, comp_pub->length); if (!p) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for ID PCD.\n"); @@ -1927,7 +1935,7 @@ eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, databuf = BUF_MEM_create_init(data, datalen); encbuf = EAC_encrypt(eacsmctx->ctx, databuf); - if (!databuf || !encbuf) { + if (!databuf || !encbuf || !encbuf->length) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt data."); ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -1969,7 +1977,7 @@ eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, encbuf = BUF_MEM_create_init(enc, enclen); databuf = EAC_decrypt(eacsmctx->ctx, encbuf); - if (!encbuf || !databuf) { + if (!encbuf || !databuf || !databuf->length) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt data."); ssl_error(card->ctx); r = SC_ERROR_INTERNAL; @@ -2016,7 +2024,7 @@ eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, } macbuf = EAC_authenticate(eacsmctx->ctx, inbuf); - if (!macbuf) { + if (!macbuf || !macbuf->length) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute message authentication code (MAC)."); ssl_error(card->ctx); @@ -2105,7 +2113,7 @@ add_tag(unsigned char **asn1new, int constructed, int tag, return -1; newlen = ASN1_object_size(constructed, len, tag); - if (newlen < 0) + if (newlen <= 0) return newlen; p = OPENSSL_realloc(*asn1new, newlen); diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index cfa2573233..41b32a6b1f 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -92,7 +92,12 @@ add_padding(const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, switch (ctx->padding_indicator) { case SM_NO_PADDING: if (*padded != data) { - p = realloc(*padded, datalen); + if (datalen == 0) { + free(*padded); + p = malloc(datalen); + } else { + p = realloc(*padded, datalen); + } if (!p) return SC_ERROR_OUT_OF_MEMORY; *padded = p; @@ -146,7 +151,7 @@ static int format_le(size_t le, struct sc_asn1_entry *le_entry, { u8 *p; - if (!lebuf || !le_len) + if (!lebuf || !le_len || !*le_len) return SC_ERROR_INVALID_ARGUMENTS; p = realloc(*lebuf, *le_len); From 887340c04dea4e9b6552ee57467783bec667c11a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 Jan 2019 16:12:38 +0100 Subject: [PATCH 0742/4321] Generalized fuzzing script --- tests/Makefile.am | 1 + tests/test-fuzzing-pkcs15-tool-dump.sh | 33 ----------------- tests/test-fuzzing.sh | 51 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 33 deletions(-) delete mode 100644 tests/test-fuzzing-pkcs15-tool-dump.sh create mode 100755 tests/test-fuzzing.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index e88620a0cc..66323e9d79 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in dist_noinst_SCRIPTS = test-manpage.sh \ + test-fuzzing.sh \ test-pkcs11-tool-sign-verify.sh TESTS = test-manpage.sh \ diff --git a/tests/test-fuzzing-pkcs15-tool-dump.sh b/tests/test-fuzzing-pkcs15-tool-dump.sh deleted file mode 100644 index 574c7f2c76..0000000000 --- a/tests/test-fuzzing-pkcs15-tool-dump.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -if [ ! -d x41-smartcard-fuzzing ]; -then - git clone https://github.com/x41sec/x41-smartcard-fuzzing -fi - -gcc -shared -fPIC -o x41-smartcard-fuzzing/scard_override/libsccard_override.so x41-smartcard-fuzzing/scard_override/scard_override.c -ldl -I/usr/include/PCSC/ - -if [ ! -f configure ]; -then - autoreconf -vis -fi - -if [ ! -f Makefile ]; -then - make clean -fi - -#export AFL_USE_ASAN=1 -./configure CC=afl-gcc CFLAGS="-O0" LDFLAGS="-ldl" --disable-shared --disable-notify --with-pcsc-provider=$PWD/x41-smartcard-fuzzing/scard_override/libsccard_override.so -make - -if [ ! -d tests/fuzzing-testcases ] -then - mkdir -p tests/fuzzing-testcases - echo -ne "$(printf '\\x90\\x00')" > tests/fuzzing-testcases/9000 - IN=tests/fuzzing-testcases -else - IN=- -fi - -FUZZ_FILE=input.apdu afl-fuzz -i $IN -o out -f input.apdu src/tools/pkcs15-tool -D diff --git a/tests/test-fuzzing.sh b/tests/test-fuzzing.sh new file mode 100755 index 0000000000..2f24f57c04 --- /dev/null +++ b/tests/test-fuzzing.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -ex + +case "$1" in + "pkcs11-tool") + CMD="src/tools/pkcs11-tool --test --login --pin 123456" + ;; + "pkcs15-tool") + CMD="src/tools/pkcs15-tool --dump" + ;; + "eidenv") + CMD="src/tools/eidenv" + ;; + *) + echo "Unknown fuzzing target" + exit 1 + ;; +esac + +IN=tests/fuzzing-testcases +if [ ! -d "$IN" ] +then + mkdir -p "$IN" + echo -ne "$(printf '\\x90\\x00')" > "$IN"/9000 +fi + +# reuse output directory if possible +OUT="out-$1" +if [ -d "$OUT" ] +then + IN=- +fi + +if [ ! -d x41-smartcard-fuzzing ]; +then + git clone https://github.com/x41sec/x41-smartcard-fuzzing +fi + +gcc -shared -fPIC -o x41-smartcard-fuzzing/scard_override/libsccard_override.so x41-smartcard-fuzzing/scard_override/scard_override.c -ldl -I/usr/include/PCSC/ + +if [ ! -f configure ]; +then + autoreconf -vis +fi + +#export AFL_USE_ASAN=1 +./configure CC=afl-gcc CFLAGS="-O0" --disable-shared --disable-notify --with-pcsc-provider=$PWD/x41-smartcard-fuzzing/scard_override/libsccard_override.so +make + +FUZZ_FILE=input.apdu afl-fuzz -i "$IN" -o "$OUT" -f input.apdu $CMD From 993f6f5cc69edd78761d232223570e8aff95441a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 Jan 2019 16:13:57 +0100 Subject: [PATCH 0743/4321] Use opensc-pkcs11.so for static build of pkcs11-tool Statically link opensc-pkcs11 into pkcs11-tool with --disable-shared --- configure.ac | 3 +++ src/pkcs11/Makefile.am | 9 +++++++++ src/tools/Makefile.am | 5 +++++ src/tools/pkcs11-tool.c | 16 +++++++++++++--- win32/winconfig.h.in | 3 ++- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index a88bb0aaa4..19599dd2ba 100644 --- a/configure.ac +++ b/configure.ac @@ -1045,6 +1045,9 @@ AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"]) AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) +AM_CONDITIONAL([ENABLE_SHARED], [test "${enable_shared}" = "yes"]) +AS_IF([test "${enable_shared}" = "yes"], [AC_DEFINE([ENABLE_SHARED], [1], [Enable shared libraries])]) + if test "${enable_pedantic}" = "yes"; then enable_strict="yes"; CFLAGS="${CFLAGS} -pedantic" diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 2494491001..bc3b494070 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -4,6 +4,10 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-pkcs11.rc $(s EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest onepin-opensc-pkcs11.dll.manifest lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la onepin-opensc-pkcs11.la +if ENABLE_SHARED +else +noinst_LTLIBRARIES = libopensc-pkcs11.la +endif AM_CPPFLAGS = -I$(top_srcdir)/src @@ -31,6 +35,11 @@ opensc_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) \ -export-symbols "$(srcdir)/pkcs11.exports" \ -module -shared -avoid-version -no-undefined +libopensc_pkcs11_la_SOURCES = $(OPENSC_PKCS11_SRC) $(OPENSC_PKCS11_INC) +libopensc_pkcs11_la_CFLAGS = $(OPENSC_PKCS11_CFLAGS) +libopensc_pkcs11_la_LIBADD = $(OPENSC_PKCS11_LIBS) +libopensc_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) + onepin_opensc_pkcs11_la_SOURCES = $(OPENSC_PKCS11_SRC) $(OPENSC_PKCS11_INC) onepin_opensc_pkcs11_la_CFLAGS = -DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" $(OPENSC_PKCS11_CFLAGS) onepin_opensc_pkcs11_la_LIBADD = $(OPENSC_PKCS11_LIBS) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 8c67fb11ad..217c1a0af5 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -61,6 +61,11 @@ pkcs11_tool_SOURCES = pkcs11-tool.c util.c pkcs11_tool_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ $(OPTIONAL_OPENSSL_LIBS) +if ENABLE_SHARED +else +pkcs11_tool_LDADD += \ + $(top_builddir)/src/pkcs11/libopensc-pkcs11.la +endif pkcs15_crypt_SOURCES = pkcs15-crypt.c util.c pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) cryptoflex_tool_SOURCES = cryptoflex-tool.c util.c diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7e1032f3b8..8bf99a52c5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -71,6 +71,9 @@ extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); extern CK_RV C_UnloadModule(void *module); +#ifndef ENABLE_SHARED +extern CK_FUNCTION_LIST pkcs11_function_list; +#endif #define NEED_SESSION_RO 0x01 #define NEED_SESSION_RW 0x02 @@ -911,9 +914,16 @@ int main(int argc, char * argv[]) opt_module = expanded_val; #endif - module = C_LoadModule(opt_module, &p11); - if (module == NULL) - util_fatal("Failed to load pkcs11 module"); +#ifndef ENABLE_SHARED + if (strcmp(opt_module, DEFAULT_PKCS11_PROVIDER) == 0) + p11 = &pkcs11_function_list; + else +#endif + { + module = C_LoadModule(opt_module, &p11); + if (module == NULL) + util_fatal("Failed to load pkcs11 module"); + } rv = p11->C_Initialize(NULL); if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index 09842209b8..9f44251e1f 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -53,7 +53,8 @@ #define DEFAULT_PCSC_PROVIDER "@DEFAULT_PCSC_PROVIDER@" #endif -#define ENABLE_NOTIFY +#define ENABLE_SHARED 1 +#define ENABLE_NOTIFY 1 #define SC_PKCS15_PROFILE_DIRECTORY "C:\\Program Files\\OpenSC Project\\OpenSC\\profiles" From aed95b2f2ba24bda09c0fe25609dd498e66a2e25 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 22 Jan 2019 12:24:53 +0100 Subject: [PATCH 0744/4321] pkcs11: check inputs prevents NULL pointer dereference --- src/pkcs11/framework-pkcs15.c | 110 +++++++++++++++++++++++++----- src/pkcs11/framework-pkcs15init.c | 14 +++- src/pkcs11/mechanism.c | 2 +- src/pkcs11/misc.c | 2 +- src/pkcs11/pkcs11-object.c | 6 +- src/pkcs11/pkcs11-session.c | 21 ++++-- src/pkcs11/slot.c | 4 +- 7 files changed, 130 insertions(+), 29 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 10582ed37b..eeb6861a97 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -269,7 +269,9 @@ get_fw_data(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info, int *o struct pkcs15_fw_data *out = NULL; int idx; - for (idx=0; idx < SC_PKCS11_FRAMEWORK_DATA_MAX_NUM; idx++) { + if (!p11card) + return NULL; + for (idx=0; p11card && idx < SC_PKCS11_FRAMEWORK_DATA_MAX_NUM; idx++) { struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[idx]; struct sc_file *file_app = NULL; @@ -307,6 +309,8 @@ pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info) CK_RV ck_rv; sc_log(context, "Bind PKCS#15 '%s' application", app_info ? app_info->label : ""); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; for (idx=0; idxfws_data[idx]) break; @@ -351,7 +355,9 @@ pkcs15_unbind(struct sc_pkcs11_card *p11card) unsigned int i, idx; int rv = SC_SUCCESS; - for (idx=0; idxfws_data[idx]; if (!fw_data) @@ -1015,21 +1021,25 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj, case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_GOSTR3410: case SC_PKCS15_TYPE_PRKEY_EC: - pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); - card_fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx]; - for (i = 0; i < card_fw_data->num_objects; i++) { - struct pkcs15_any_object *obj2 = card_fw_data->objects[i]; - struct pkcs15_cert_object *cert; + if (slot->p11card != NULL) { + pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); + if (!slot->p11card) + return; + card_fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx]; + for (i = 0; i < card_fw_data->num_objects; i++) { + struct pkcs15_any_object *obj2 = card_fw_data->objects[i]; + struct pkcs15_cert_object *cert; - if (!is_cert(obj2)) - continue; + if (!is_cert(obj2)) + continue; - cert = (struct pkcs15_cert_object*) obj2; + cert = (struct pkcs15_cert_object*) obj2; - if ((struct pkcs15_any_object*)(cert->cert_prvkey) != obj) - continue; + if ((struct pkcs15_any_object*)(cert->cert_prvkey) != obj) + continue; - pkcs15_add_object(slot, obj2, NULL); + pkcs15_add_object(slot, obj2, NULL); + } } break; case SC_PKCS15_TYPE_CERT_X509: @@ -1246,6 +1256,10 @@ int slot_get_logged_in_state(struct sc_pkcs11_slot *slot) struct sc_pkcs15_object *pin_obj = NULL; struct sc_pkcs15_auth_info *pin_info; + if (slot->p11card == NULL) { + goto out; + } + fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx]; if (!fw_data) goto out; @@ -1432,7 +1446,9 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf CK_RV rv; int rc, i, idx; - sc_log(context, "create PKCS#15 tokens; fws:%p,%p,%p", p11card->fws_data[0], p11card->fws_data[1], p11card->fws_data[2]); + if (p11card) { + sc_log(context, "create PKCS#15 tokens; fws:%p,%p,%p", p11card->fws_data[0], p11card->fws_data[1], p11card->fws_data[2]); + } sc_log(context, "create slots flags 0x%X", cs_flags); /* Find out framework data corresponding to the given application */ @@ -1549,13 +1565,18 @@ static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { - struct sc_pkcs11_card *p11card = slot->p11card; + struct sc_pkcs11_card *p11card; struct pkcs15_fw_data *fw_data = NULL; struct sc_pkcs15_card *p15card = NULL; struct sc_pkcs15_object *auth_object = NULL; struct sc_pkcs15_auth_info *pin_info = NULL; int rc; + if (slot->p11card == NULL) { + return CKR_TOKEN_NOT_RECOGNIZED; + } + p11card = slot->p11card; + fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Login"); @@ -1627,6 +1648,8 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return CKR_FUNCTION_REJECTED; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD || (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) { /* pPin should be NULL in case of a pin pad reader, but @@ -1734,6 +1757,8 @@ pkcs15_logout(struct sc_pkcs11_slot *slot) CK_RV ret = CKR_OK; int rc; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Logout"); @@ -1777,6 +1802,8 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot, int login_user = slot->login_user; int rc; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_SetPin"); @@ -1854,6 +1881,8 @@ pkcs15_initialize(struct sc_pkcs11_slot *slot, void *ptr, CK_RV rv; sc_log(context, "Get 'enable-InitToken' card configuration option"); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; conf_block = sc_get_conf_block(p11card->card->ctx, "framework", "pkcs15", 1); enable_InitToken = scconf_get_bool(conf_block, "pkcs11_enable_InitToken", 0); @@ -1985,6 +2014,8 @@ pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen p11args.pin = pPin; p11args.pin_len = ulPinLen; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; rc = sc_card_ctl(p11card->card, SC_CARDCTL_PKCS11_INIT_PIN, &p11args); if (rc != SC_ERROR_NOT_SUPPORTED) { if (rc == SC_SUCCESS) @@ -2087,6 +2118,8 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2254,6 +2287,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile CK_BBOOL temp_object = FALSE; memset(&args, 0, sizeof(args)); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2426,6 +2461,8 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2532,6 +2569,8 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot, char label[SC_PKCS15_MAX_LABEL_SIZE]; memset(&args, 0, sizeof(args)); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2616,6 +2655,8 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile, memset(&args, 0, sizeof(args)); sc_init_oid(&args.app_oid); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2694,6 +2735,8 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK int rc; CK_BBOOL p15init_create_object; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_CreateObject"); @@ -2960,6 +3003,8 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, && pMechanism->mechanism != CKM_EC_KEY_PAIR_GEN) return CKR_MECHANISM_INVALID; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GenerateKeyPair"); @@ -3133,6 +3178,8 @@ pkcs15_skey_destroy(struct sc_pkcs11_session *session, void *object) struct pkcs15_fw_data *fw_data = NULL; int rv; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GenerateKeyPair"); @@ -3171,6 +3218,8 @@ pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object) struct sc_profile *profile = NULL; int rv; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_DestroyObject"); @@ -3250,6 +3299,8 @@ pkcs15_get_random(struct sc_pkcs11_slot *slot, CK_BYTE_PTR p, CK_ULONG len) struct pkcs15_fw_data *fw_data = NULL; int rc; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GenerateRandom"); @@ -3298,6 +3349,8 @@ pkcs15_set_attrib(struct sc_pkcs11_session *session, struct sc_pkcs15_object *p1 int rv = 0; CK_RV ck_rv = CKR_OK; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_SetAttributeValue"); @@ -3397,6 +3450,8 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT sc_log(context, "pkcs15_cert_get_attribute() called"); p11card = session->slot->p11card; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); @@ -3499,6 +3554,8 @@ pkcs15_cert_cmp_attribute(struct sc_pkcs11_session *session, size_t len, _len; sc_log(context, "pkcs15_cert_cmp_attribute() called"); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) { sc_log(context, "pkcs15_cert_cmp_attribute() returns SC_ERROR_INTERNAL"); @@ -3599,6 +3656,8 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, sc_log(context, "pkcs15_prkey_get_attribute() called"); p11card = session->slot->p11card; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); @@ -3840,6 +3899,8 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initiating signing operation, mechanism 0x%lx.", pMechanism->mechanism); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Sign"); @@ -4010,6 +4071,8 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initiating unwrapping with private key."); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); @@ -4071,6 +4134,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initiating decryption."); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Decrypt"); @@ -4144,6 +4209,8 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initiating derivation"); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_DeriveKey"); @@ -4219,6 +4286,8 @@ pkcs15_prkey_can_do(struct sc_pkcs11_session *session, void *obj, if (!pkinfo->algo_refs[0]) return CKR_FUNCTION_NOT_SUPPORTED; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; token_algos = &fw_data->p15_card->tokeninfo->supported_algos[0]; @@ -4373,6 +4442,8 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ p11card = session->slot->p11card; cert = pubkey->pub_genfrom; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); @@ -4600,9 +4671,12 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, { struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; - struct sc_card *card = session->slot->p11card->card; + struct sc_card *card; int rv; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; + card = session->slot->p11card->card; if (!out_data) return SC_ERROR_INVALID_ARGUMENTS; if (dobj->info->data.len == 0) @@ -4883,6 +4957,8 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Initiating unwrapping with a secret key."); + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey"); @@ -4961,6 +5037,8 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, } p11card = session->slot->p11card; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx]; if (!fw_data) diff --git a/src/pkcs11/framework-pkcs15init.c b/src/pkcs11/framework-pkcs15init.c index 2f352c2532..1883e6b985 100644 --- a/src/pkcs11/framework-pkcs15init.c +++ b/src/pkcs11/framework-pkcs15init.c @@ -32,10 +32,13 @@ */ static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info) { - struct sc_card *card = p11card->card; + struct sc_card *card; struct sc_profile *profile; int rc; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; + card = p11card->card; rc = sc_pkcs15init_bind(card, "pkcs15", NULL, NULL, &profile); if (rc == 0) p11card->fws_data[0] = profile; @@ -46,6 +49,8 @@ static CK_RV pkcs15init_unbind(struct sc_pkcs11_card *p11card) { struct sc_profile *profile; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; profile = (struct sc_profile *) p11card->fws_data[0]; sc_pkcs15init_unbind(profile); return CKR_OK; @@ -59,6 +64,8 @@ pkcs15init_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app struct sc_pkcs11_slot *slot; CK_RV rc; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; profile = (struct sc_profile *) p11card->fws_data[0]; rc = slot_allocate(&slot, p11card); @@ -127,12 +134,15 @@ pkcs15init_initialize(struct sc_pkcs11_slot *pslot, void *ptr, CK_UTF8CHAR_PTR pLabel) { struct sc_pkcs11_card *p11card = pslot->p11card; - struct sc_profile *profile = (struct sc_profile *) p11card->fws_data[0]; + struct sc_profile *profile; struct sc_pkcs15init_initargs args; struct sc_pkcs11_slot *slot; CK_RV rv; int rc, id; + if (!p11card) + return CKR_TOKEN_NOT_RECOGNIZED; + profile = (struct sc_profile *) p11card->fws_data[0]; memset(&args, 0, sizeof(args)); args.so_pin = pPin; args.so_pin_len = ulPinLen; diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 7bcab8e30b..cea5d4b947 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1211,7 +1211,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, info = calloc(1, sizeof(*info)); if (!info) - LOG_FUNC_RETURN(p11card->card->ctx, SC_ERROR_OUT_OF_MEMORY); + return CKR_HOST_MEMORY; info->mech = mech; info->sign_type = sign_type; diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index b9bef60dc1..9408080b18 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -140,7 +140,7 @@ CK_RV restore_login_state(struct sc_pkcs11_slot *slot) if (sc_pkcs11_conf.atomic && slot) { if (list_iterator_start(&slot->logins)) { struct sc_pkcs11_login *login = list_iterator_next(&slot->logins); - while (login) { + while (login && slot->p11card && slot->p11card->framework) { r = slot->p11card->framework->login(slot, login->userType, login->pPin, login->ulPinLen); if (r != CKR_OK) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index ad336bf82f..190e28665c 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1015,7 +1015,8 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the session's handle */ } slot = session->slot; - if (slot->p11card->framework->gen_keypair == NULL) + if (slot == NULL || slot->p11card == NULL || slot->p11card->framework == NULL + || slot->p11card->framework->gen_keypair == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; else { rv = restore_login_state(slot); @@ -1283,7 +1284,8 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = get_session(hSession, &session); if (rv == CKR_OK) { slot = session->slot; - if (slot->p11card->framework->get_random == NULL) + if (slot == NULL || slot->p11card == NULL || slot->p11card->framework == NULL + || slot->p11card->framework->get_random == NULL) rv = CKR_RANDOM_NO_RNG; else rv = slot->p11card->framework->get_random(slot, RandomData, ulRandomLen); diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index e42474469b..f79629ca1a 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -120,8 +120,11 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession) slot->login_user = -1; if (sc_pkcs11_conf.atomic) pop_all_login_states(slot); - else + else { + if (slot->p11card == NULL) + return CKR_TOKEN_NOT_RECOGNIZED; slot->p11card->framework->logout(slot); + } } if (list_delete(&sessions, session) != 0) @@ -289,7 +292,7 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */ } else { rv = restore_login_state(slot); - if (rv == CKR_OK) + if (rv == CKR_OK && slot->p11card && slot->p11card->framework) rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen); rv = reset_login_state(slot, rv); } @@ -307,6 +310,8 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = restore_login_state(slot); if (rv == CKR_OK) { sc_log(context, "C_Login() userType %li", userType); + if (slot->p11card == NULL) + return CKR_TOKEN_NOT_RECOGNIZED; rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen); sc_log(context, "fLogin() rv %li", rv); } @@ -347,8 +352,11 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession) slot->login_user = -1; if (sc_pkcs11_conf.atomic) pop_all_login_states(slot); - else + else { + if (!slot->p11card) + return CKR_TOKEN_NOT_RECOGNIZED; rv = slot->p11card->framework->logout(slot); + } } else rv = CKR_USER_NOT_LOGGED_IN; @@ -385,7 +393,7 @@ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) slot = session->slot; if (slot->login_user != CKU_SO) { rv = CKR_USER_NOT_LOGGED_IN; - } else if (slot->p11card->framework->init_pin == NULL) { + } else if (slot->p11card == NULL || slot->p11card->framework->init_pin == NULL) { rv = CKR_FUNCTION_NOT_SUPPORTED; } else { rv = restore_login_state(slot); @@ -430,8 +438,11 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, } rv = restore_login_state(slot); - if (rv == CKR_OK) + if (rv == CKR_OK) { + if (slot->p11card == NULL) + return CKR_TOKEN_NOT_RECOGNIZED; rv = slot->p11card->framework->change_pin(slot, pOldPin, ulOldLen, pNewPin, ulNewLen); + } rv = reset_login_state(slot, rv); out: diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index c374666f4d..44b041eeea 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -495,8 +495,8 @@ CK_RV slot_token_removed(CK_SLOT_ID id) /* Release framework stuff */ if (slot->p11card != NULL) { - if (slot->fw_data != NULL && - slot->p11card->framework != NULL && slot->p11card->framework->release_token != NULL) { + if (slot->fw_data != NULL && slot->p11card->framework != NULL + && slot->p11card->framework->release_token != NULL) { slot->p11card->framework->release_token(slot->p11card, slot->fw_data); slot->fw_data = NULL; } From 97a58cb441b9930fffb8cc2b91e88fdeb60280d2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 22 Jan 2019 16:11:52 +0100 Subject: [PATCH 0745/4321] fixed https://github.com/OpenSC/OpenSC/issues/1581 --- src/libopensc/card-piv.c | 68 +++++----------------------------------- 1 file changed, 8 insertions(+), 60 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 08b8960b3a..5eb25e9606 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -178,7 +178,6 @@ typedef struct piv_private_data { int pstate; int pin_cmd_verify; int context_specific; - int pin_cmd_noparse; unsigned int pin_cmd_verify_sw1; unsigned int pin_cmd_verify_sw2; int tries_left; /* SC_PIN_CMD_GET_INFO tries_left from last */ @@ -525,25 +524,14 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, size_t * recvbuflen) { int r; - int r_tag ; sc_apdu_t apdu; u8 rbufinitbuf[4096]; u8 *rbuf; size_t rbuflen; - unsigned int cla_out, tag_out; - const u8 *body; - size_t bodylen; - int find_len = 0; - piv_private_data_t * priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, - "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u", - ins, p1, p2, sendbuflen, card->max_send_size, - card->max_recv_size); - rbuf = rbufinitbuf; rbuflen = sizeof(rbufinitbuf); @@ -561,12 +549,6 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, recvbuf ? SC_APDU_CASE_4_SHORT: SC_APDU_CASE_3_SHORT, ins, p1, p2); apdu.flags |= SC_APDU_FLAGS_CHAINING; - /* if looking for length of object, dont try and read the rest of buffer here */ - if (rbuflen == 8 && card->reader->active_protocol == SC_PROTO_T1) { - apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP; - find_len = 1; - } - apdu.lc = sendbuflen; apdu.datalen = sendbuflen; apdu.data = sendbuf; @@ -589,53 +571,23 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, goto err; } - if (!(find_len && apdu.sw1 == 0x61)) - r = sc_check_sw(card, apdu.sw1, apdu.sw2); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); -/* TODO: - DEE look later at tag vs size read too */ if (r < 0) { - sc_log(card->ctx, "Card returned error "); + sc_log(card->ctx, "Card returned error "); goto err; } - /* - * See how much we read and make sure it is asn1 - * if not, return 0 indicating no data found - */ - - - rbuflen = 0; /* in case rseplen < 3 i.e. not parseable */ - /* we may only be using get data to test the security status of the card, so zero length is OK */ - if ( recvbuflen && recvbuf && apdu.resplen > 3 && priv->pin_cmd_noparse != 1) { - *recvbuflen = 0; - /* we should have all the tag data, so we have to tell sc_asn1_find_tag - * the buffer is bigger, so it will not produce "ASN1.tag too long!" */ - - body = rbuf; - r_tag = sc_asn1_read_tag(&body, apdu.resplen, &cla_out, &tag_out, &bodylen); - sc_log(card->ctx, "r_tag:%d body:%p", r_tag, body); - if ( (r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) - || body == NULL) { - body = rbuf; - bodylen = apdu.resplen; - } - - rbuflen = body - rbuf + bodylen; - - /* if using internal buffer, alloc new one */ - if (rbuf == rbufinitbuf) { - *recvbuf = malloc(rbuflen); + if (recvbuflen) { + if (recvbuf && *recvbuf == NULL) { + *recvbuf = malloc(apdu.resplen); if (*recvbuf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - - memcpy(*recvbuf, rbuf, rbuflen); /* copy tag too */ + memcpy(*recvbuf, rbuf, apdu.resplen); /* copy tag too */ } - } - - if (recvbuflen) { - *recvbuflen = rbuflen; + *recvbuflen = apdu.resplen; r = *recvbuflen; } @@ -995,7 +947,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) r = SC_ERROR_FILE_NOT_FOUND; goto err; } - *buf_len = r; + *buf_len = (body - rbuf) + bodylen; } else if ( r == 0 ) { r = SC_ERROR_FILE_NOT_FOUND; goto err; @@ -3599,10 +3551,8 @@ piv_check_protected_objects(sc_card_t *card) if (priv->object_test_verify == 0) { for (i = 0; i < (int)(sizeof(protected_objects)/sizeof(int)); i++) { buf_len = sizeof(buf); - priv->pin_cmd_noparse = 1; /* tell piv_general_io dont need to parse at all. */ rbuf = buf; r = piv_get_data(card, protected_objects[i], &rbuf, &buf_len); - priv->pin_cmd_noparse = 0; /* TODO may need to check sw1 and sw2 to see what really happened */ if (r >= 0 || r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { @@ -3622,10 +3572,8 @@ piv_check_protected_objects(sc_card_t *card) } else { /* use the one object we found earlier. Test is security status has changed */ buf_len = sizeof(buf); - priv->pin_cmd_noparse = 1; /* tell piv_general_io dont need to parse at all. */ rbuf = buf; r = piv_get_data(card, priv->object_test_verify, &rbuf, &buf_len); - priv->pin_cmd_noparse = 0; } if (r == SC_ERROR_FILE_NOT_FOUND) r = SC_ERROR_PIN_CODE_INCORRECT; From f486486413bb0609105a1edb9e76bf453d0470c3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 Jan 2019 17:47:32 +0100 Subject: [PATCH 0746/4321] removed unused defines --- src/pkcs11/debug.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pkcs11/debug.c b/src/pkcs11/debug.c index bb3b180639..a713fb8946 100644 --- a/src/pkcs11/debug.c +++ b/src/pkcs11/debug.c @@ -34,9 +34,6 @@ struct fmap { struct fmap * map; }; -#define NELE(x) (sizeof(x)/sizeof((x)[0])) -#define STR(x) #x -#define __(x) (x), #x #define _(x) { (x), #x, NULL, NULL } #define ul(x) { (x), #x, sc_pkcs11_print_ulong, NULL } #define ulm(x) { (x), #x, sc_pkcs11_print_ulong, map_##x } From 7a7ff5042212386eba0b96c34163735187fe5954 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 24 Jan 2019 14:24:07 +0100 Subject: [PATCH 0747/4321] fixed memory leaks during card initialization --- src/libopensc/card-authentic.c | 6 +++--- src/libopensc/card-cardos.c | 7 +++---- src/libopensc/card-dnie.c | 4 ++-- src/libopensc/card-iasecc.c | 6 +++--- src/libopensc/card-mcrd.c | 32 +++++++++++--------------------- src/libopensc/card-oberthur.c | 25 ++++++++++++++++--------- src/libopensc/card-westcos.c | 30 +++++++++++++++++------------- src/libopensc/card.c | 4 ---- 8 files changed, 55 insertions(+), 59 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 0741e753cd..d7c81b5a57 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -436,9 +436,6 @@ authentic_init_oberthur_authentic_3_2(struct sc_card *card) flags = AUTHENTIC_CARD_DEFAULT_FLAGS; - _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); - _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); - card->caps = SC_CARD_CAP_RNG; card->caps |= SC_CARD_CAP_APDU_EXT; card->caps |= SC_CARD_CAP_USE_FCI_AC; @@ -455,6 +452,9 @@ authentic_init_oberthur_authentic_3_2(struct sc_card *card) rv = authentic_select_mf(card, NULL); LOG_TEST_RET(ctx, rv, "MF selection error"); + _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); + _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 2d9ec683c9..3de45ffd8b 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -184,10 +184,6 @@ static int cardos_init(sc_card_t *card) if (card->type != SC_CARD_TYPE_CARDOS_V5_0) flags |= SC_ALGORITHM_NEED_USAGE; - _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_CARDOS_M4_2) { r = cardos_have_2048bit_package(card); if (r < 0) @@ -231,6 +227,9 @@ static int cardos_init(sc_card_t *card) /* strip the length of SW bytes */ card->max_recv_size = data_field_length - 2; + _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 (rsa_2048 == 1) { _sc_card_add_rsa_alg(card, 1280, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 2b62e23db2..902754dc06 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -857,8 +857,6 @@ static int dnie_init(struct sc_card *card) card->sm_ctx.ops.free_sm_apdu = dnie_sm_free_wrapped_apdu; card->sm_ctx.sm_mode = SM_MODE_NONE; - init_flags(card); - res=cwa_create_secure_channel(card,provider,CWA_SM_OFF); LOG_TEST_RET(card->ctx, res, "Failure creating CWA secure channel."); @@ -876,6 +874,8 @@ static int dnie_init(struct sc_card *card) } #endif + init_flags(card); + GET_DNIE_PRIV_DATA(card)->cwa_provider = provider; LOG_FUNC_RETURN(card->ctx, res); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 7eb3f5d095..9033369f08 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -411,9 +411,6 @@ iasecc_init_gemalto(struct sc_card *card) flags = IASECC_CARD_DEFAULT_FLAGS; - _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); - _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); - card->caps = SC_CARD_CAP_RNG; card->caps |= SC_CARD_CAP_APDU_EXT; card->caps |= SC_CARD_CAP_USE_FCI_AC; @@ -436,6 +433,9 @@ iasecc_init_gemalto(struct sc_card *card) sc_log(ctx, "rv %i", rv); LOG_TEST_RET(ctx, rv, "Cannot read/parse EF.ATR"); + _sc_card_add_rsa_alg(card, 1024, flags, 0x10001); + _sc_card_add_rsa_alg(card, 2048, flags, 0x10001); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index db67f37afc..7aac191a42 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -309,7 +309,6 @@ static int mcrd_init(sc_card_t * card) unsigned long flags, ext_flags; struct mcrd_priv_data *priv; int r; - sc_path_t tmppath; priv = calloc(1, sizeof *priv); if (!priv) @@ -323,13 +322,6 @@ static int mcrd_init(sc_card_t * card) /* Select the EstEID AID to get to a known state. * For some reason a reset is required as well... */ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) { - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; - /* EstEID v3.0 has 2048 bit keys */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - - flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); sc_reset(card, 0); r = gp_select_aid(card, &EstEID_v3_AID); @@ -350,6 +342,13 @@ static int mcrd_init(sc_card_t * card) } } } + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; + /* EstEID v3.0 has 2048 bit keys */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); } else { /* EstEID v1.0 and 1.1 have 1024 bit keys */ flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; @@ -365,19 +364,13 @@ static int mcrd_init(sc_card_t * card) priv->curpath[0] = MFID; priv->curpathlen = 1; - sc_format_path ("3f00", &tmppath); - r = sc_select_file (card, &tmppath, NULL); - if (r < 0) { - free(card->drv_data); - card->drv_data = NULL; - r = SC_ERROR_INVALID_CARD; - } + sc_select_file (card, sc_get_mf_path(), NULL); /* Not needed for the fixed EstEID profile */ if (!is_esteid_card(card)) load_special_files(card); - return r; + return SC_SUCCESS; } static int mcrd_finish(sc_card_t * card) @@ -1165,7 +1158,6 @@ static int mcrd_set_security_env(sc_card_t * card, { struct mcrd_priv_data *priv; sc_apdu_t apdu; - sc_path_t tmppath; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 *p; int r, locked = 0; @@ -1187,8 +1179,7 @@ static int mcrd_set_security_env(sc_card_t * card, return SC_ERROR_INVALID_ARGUMENTS; /* Make sure we always start from MF */ - sc_format_path ("3f00", &tmppath); - r = sc_select_file (card, &tmppath, NULL); + r = sc_select_file (card, sc_get_mf_path(), NULL); if (r < 0) return r; /* We now know that cache is not valid */ @@ -1453,8 +1444,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, /* the file with key pin info (tries left) 4.5 EF_PwdC */ /* XXX: cheat the file path cache by always starting fresh from MF */ - sc_format_path ("3f00", &tmppath); - r = sc_select_file (card, &tmppath, NULL); + r = sc_select_file (card, sc_get_mf_path(), NULL); if (r < 0) return SC_ERROR_INTERNAL; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 97db1490e3..675a453f15 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -226,20 +226,27 @@ auth_init(struct sc_card *card) if (auth_select_aid(card)) { sc_log(card->ctx, "Failed to initialize %s", card->name); - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize"); + rv = SC_ERROR_INVALID_CARD; + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize"); } - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796; - flags |= SC_ALGORITHM_RSA_HASH_NONE; - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - - _sc_card_add_rsa_alg(card, 512, flags, 0); - _sc_card_add_rsa_alg(card, 1024, flags, 0); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - sc_format_path("3F00", &path); rv = auth_select_file(card, &path, NULL); +err: + if (rv == SC_SUCCESS) { + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796; + flags |= SC_ALGORITHM_RSA_HASH_NONE; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + + _sc_card_add_rsa_alg(card, 512, flags, 0); + _sc_card_add_rsa_alg(card, 1024, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else { + free(card->drv_data); + card->drv_data = NULL; + } + LOG_FUNC_RETURN(card->ctx, rv); } diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 4af0d5f7d9..d16512b1f7 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -221,6 +221,23 @@ static int westcos_init(sc_card_t * card) priv_data = (priv_data_t *) card->drv_data; + default_key = + scconf_get_str(card->ctx->conf_blocks[0], "westcos_default_key", + DEFAULT_TRANSPORT_KEY); + if (default_key) { + priv_data = (priv_data_t *) (card->drv_data); + priv_data->default_key.key_reference = 0; + priv_data->default_key.key_len = + sizeof(priv_data->default_key.key_value); + r = sc_hex_to_bin(default_key, priv_data->default_key.key_value, + &(priv_data->default_key.key_len)); + if (r) { + free (priv_data); + card->drv_data = NULL; + return (r); + } + } + if (card->type & JAVACARD) { priv_data->flags |= JAVACARD; } @@ -250,19 +267,6 @@ static int westcos_init(sc_card_t * card) _sc_card_add_rsa_alg(card, 1400, flags, exponent); _sc_card_add_rsa_alg(card, 1536, flags, exponent); _sc_card_add_rsa_alg(card, 2048, flags, exponent); - default_key = - scconf_get_str(card->ctx->conf_blocks[0], "westcos_default_key", - DEFAULT_TRANSPORT_KEY); - if (default_key) { - priv_data = (priv_data_t *) (card->drv_data); - priv_data->default_key.key_reference = 0; - priv_data->default_key.key_len = - sizeof(priv_data->default_key.key_value); - r = sc_hex_to_bin(default_key, priv_data->default_key.key_value, - &(priv_data->default_key.key_len)); - if (r) - return (r); - } return 0; } diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5e03c9d8b9..51ecb2b7d0 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -970,10 +970,6 @@ int _sc_card_add_algorithm(sc_card_t *card, const sc_algorithm_info_t *info) } p = (sc_algorithm_info_t *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info)); if (!p) { - if (card->algorithms) - free(card->algorithms); - card->algorithms = NULL; - card->algorithm_count = 0; return SC_ERROR_OUT_OF_MEMORY; } card->algorithms = p; From 09a594d0f074784053e54c92c3ab32a9181ba711 Mon Sep 17 00:00:00 2001 From: Alexander Paetzelt <36155797+alex-nitrokey@users.noreply.github.com> Date: Wed, 30 Jan 2019 22:00:36 +0100 Subject: [PATCH 0748/4321] OpenPGP Card v3 ECC support (#1506) * pgp: initialize ecc keys for OPC3 * Add supported ECC algorithms by card version * Add tasks identified so far * pgp: Recognize ECC set on card * pgp: get_pubkey_pem read ECC pubkey from card * pgp: minor code changes for ECC compatibility * pgp: expand sc_cardctl_openpgp_keygen_info to hold ec info * Fix segfault problem in pkcs15-pubkey.c * pgp: enable key generation with pkcs15-init and ECC * pgp: adapt calculate_and_store_fingerprint to accept ECC * pgp: adapt rest of pgp_gen_key and subfunctions to accept ECC * pgp: add kdf parameters for ECDH fingerprint calculation * pgp: enable key import with pkcs15-init and ECC * pkcs15-pubkey: fix_ec_parameters onlz accpets explicit data or named_curve * Fix some mistakes during merge * More clean up for PR * Fix some ugly alignments * Improve code readability * Prevent unitialized variable by using FUNC_RETURN * OpenPGP: add length check * pgp: save exponent length in bits for sc_cardctl_openpgp_keystore_info_t * pgp: length checks and reallocations * pgp: oid init added * OpenPGP: slightly re-factor pgp_update_new_algo_attr() * replace loop copy with memcpy() * use ushort2bebytes() to set RSA modulus & exponent * use symbolic name SC_OPENPGP_KEYFORMAT_RSA_STD for the key import format * OpenPGP: slighly re-factor pgp_parse_and_set_pubkey_output() * check for RSA modulus & exponent lengths not being a multiple of 8 * make sure RSA modulus & exponent lengths are always set * remove a left-over RSA setting from the EC code * pgp: adding BYTES4BITS * pgp: initialization of values in pgp_build_extended_header_list based on key type * pgp: add BYTES4BITS and remove unnecessary tests * Fix broken pgp_update_new_algo_attr * pgp: fix the ecpoint_len variable --- src/libopensc/card-openpgp.c | 737 ++++++++++++++++++++++---------- src/libopensc/cardctl.h | 31 +- src/libopensc/internal.h | 2 + src/libopensc/pkcs15-openpgp.c | 34 +- src/libopensc/pkcs15-pubkey.c | 17 +- src/pkcs15init/pkcs15-openpgp.c | 232 +++++++--- src/tools/openpgp-tool.c | 7 +- 7 files changed, 743 insertions(+), 317 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ab37bb5fde..3834b21e40 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -151,6 +151,26 @@ enum _sm_algo { SM_ALGO_UNKNOWN = 257 /* 3.x: coded as 0 in DO C0 */ }; +static struct pgp_supported_ec_curves { + struct sc_object_id oid; + size_t size; + struct sc_object_id oid_binary; +} ec_curves[] = { + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, + {{0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, -1}}}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384, + {{0x2b, 0x81, 0x04, 0x00, 0x22, -1}}}, /* ansiX9p384r1 */ + {{{1, 3, 132, 0, 35, -1}}, 512, + {{0x2b, 0x81, 0x04, 0x00, 0x23, -1}}}, /* ansiX9p512r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256, + {{0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, -1}}}, /* brainpoolP256r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384, + {{0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b, -1}}}, /* brainpoolP384r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512, + {{0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, -1}}}, /* brainpoolP512r1 */ + {{{-1}}, 0, {{0x0}}} /* This entry must not be touched. */ +}; + typedef struct pgp_blob { struct pgp_blob * next; /* pointer to next sibling */ struct pgp_blob * parent; /* pointer to parent */ @@ -463,7 +483,7 @@ pgp_init(sc_card_t *card) sc_path_t path; sc_file_t *file = NULL; struct do_info *info; - int r; + int r, i; LOG_FUNC_CALLED(card->ctx); @@ -584,25 +604,35 @@ pgp_init(sc_card_t *card) pgp_get_card_features(card); /* if algorithm attributes can be changed, - * add supported algorithms based on specification for pkcs15-init */ + * add supported algorithms based on specification for pkcs15-init */ if ((priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) && (strcmp(card->ctx->app_name, "pkcs15-init") == 0)) { + unsigned long flags_rsa, flags_ecc, ext_flags; + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ - unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | - SC_ALGORITHM_RSA_HASH_NONE | - SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen. on card */ + flags_rsa = SC_ALGORITHM_RSA_PAD_PKCS1| + SC_ALGORITHM_RSA_HASH_NONE| + SC_ALGORITHM_ONBOARD_KEY_GEN; + flags_ecc = SC_ALGORITHM_ECDSA_RAW| + SC_ALGORITHM_ECDH_CDH_RAW| + SC_ALGORITHM_ECDSA_HASH_NONE| + SC_ALGORITHM_ONBOARD_KEY_GEN; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; switch (card->type) { case SC_CARD_TYPE_OPENPGP_V3: /* RSA 1024 was removed for v3+ */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - _sc_card_add_rsa_alg(card, 3072, flags, 0); - _sc_card_add_rsa_alg(card, 4096, flags, 0); - /* TODO add ECC - * v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ + _sc_card_add_rsa_alg(card, 2048, flags_rsa, 0); + _sc_card_add_rsa_alg(card, 3072, flags_rsa, 0); + _sc_card_add_rsa_alg(card, 4096, flags_rsa, 0); + /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ + for (i=0; ec_curves[i].oid.value[0] >= 0; i++) + { + _sc_card_add_ec_alg(card, ec_curves[i].size, flags_ecc, ext_flags, &ec_curves[i].oid); + } break; case SC_CARD_TYPE_OPENPGP_GNUK: - _sc_card_add_rsa_alg(card, 2048, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags_rsa, 0); /* TODO add ECC for more recent Gnuk (1.2.x) * these are not include in SC_CARD_TYPE_OPENPGP_GNUK, but * are treated like SC_CARD_TYPE_OPENPGP_V2 @@ -610,10 +640,10 @@ pgp_init(sc_card_t *card) break; case SC_CARD_TYPE_OPENPGP_V2: default: - _sc_card_add_rsa_alg(card, 1024, flags, 0); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - _sc_card_add_rsa_alg(card, 3072, flags, 0); - _sc_card_add_rsa_alg(card, 4096, flags, 0); + _sc_card_add_rsa_alg(card, 1024, flags_rsa, 0); + _sc_card_add_rsa_alg(card, 2048, flags_rsa, 0); + _sc_card_add_rsa_alg(card, 3072, flags_rsa, 0); + _sc_card_add_rsa_alg(card, 4096, flags_rsa, 0); break; } } @@ -657,6 +687,9 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) static int pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_t *key_info) { + struct sc_object_id oid; + unsigned int j; + if (blob == NULL || blob->data == NULL || blob->len == 0 || blob->id < 0x00c1 || blob->id > 0x00c3 || key_info == NULL) return SC_ERROR_INCORRECT_PARAMETERS; @@ -669,13 +702,34 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_ return SC_ERROR_INCORRECT_PARAMETERS; key_info->algorithm = SC_OPENPGP_KEYALGO_RSA; - key_info->rsa.modulus_len = bebytes2ushort(blob->data + 1); - key_info->rsa.exponent_len = bebytes2ushort(blob->data + 3); + key_info->u.rsa.modulus_len = bebytes2ushort(blob->data + 1); + key_info->u.rsa.exponent_len = bebytes2ushort(blob->data + 3); - key_info->rsa.keyformat = (blob->len > 5) + key_info->u.rsa.keyformat = (blob->len > 5) ? blob->data[5] : SC_OPENPGP_KEYFORMAT_RSA_STD; break; + case SC_OPENPGP_KEYALGO_ECDH: + case SC_OPENPGP_KEYALGO_ECDSA: + + /* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA */ + key_info->algorithm = blob->data[0]; + + sc_init_oid(&oid); + /* Create copy of oid from blob */ + for (j=0; j < (blob->len-1); j++) { + oid.value[j] = blob->data[j+1]; /* ignore first byte of blob (algo ID) */ + } + + /* compare with list of supported ec_curves */ + for (j=0; ec_curves[j].oid.value[0] >= 0; j++){ + if (sc_compare_oid(&ec_curves[j].oid_binary, &oid)){ + key_info->u.ec.oid = ec_curves[j].oid; + key_info->u.ec.key_length = ec_curves[j].size; + break; + } + } + break; default: return SC_ERROR_NOT_IMPLEMENTED; } @@ -818,19 +872,37 @@ pgp_get_card_features(sc_card_t *card) * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { sc_cardctl_openpgp_keygen_info_t key_info; - /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ - unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | - SC_ALGORITHM_RSA_HASH_NONE | - SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (pgp_parse_algo_attr_blob(blob, &key_info) >= 0)) { - if (key_info.algorithm == SC_OPENPGP_KEYALGO_RSA) /* RFC 4880: RSA */ - _sc_card_add_rsa_alg(card, key_info.rsa.modulus_len, flags, 0); + /* RSA [RFC 4880] */ + if (key_info.algorithm == SC_OPENPGP_KEYALGO_RSA){ + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / + * v3.x section 7.2.11 & 7.2.12 */ + unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE | + SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ + _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); + } + /* v3.0+: ECC [RFC 4880 & 6637] */ + else if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info.algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + + unsigned long flags, ext_flags; + + if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDH) + flags = SC_ALGORITHM_ECDH_CDH_RAW; + if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDSA) + flags = SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDSA_HASH_NONE; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - /* TODO v3.0+: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ + _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, + &key_info.u.ec.oid); + } } } @@ -1555,7 +1627,7 @@ static int pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) { struct pgp_priv_data *priv = DRVDATA(card); - pgp_blob_t *blob, *mod_blob, *exp_blob; + pgp_blob_t *blob, *mod_blob, *exp_blob, *pubkey_blob; sc_pkcs15_pubkey_t pubkey; u8 *data; size_t len; @@ -1564,19 +1636,35 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) sc_log(card->ctx, "called, tag=%04x\n", tag); 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 - || (r = pgp_read_blob(card, mod_blob)) < 0 - || (r = pgp_read_blob(card, exp_blob)) < 0) + || (r = pgp_get_blob(card, blob, 0x7F49, &blob)) < 0) LOG_TEST_RET(card->ctx, r, "error getting elements"); - memset(&pubkey, 0, sizeof(pubkey)); - pubkey.algorithm = SC_ALGORITHM_RSA; - pubkey.u.rsa.modulus.data = mod_blob->data; - pubkey.u.rsa.modulus.len = mod_blob->len; - pubkey.u.rsa.exponent.data = exp_blob->data; - pubkey.u.rsa.exponent.len = exp_blob->len; + /* RSA */ + if ((r = pgp_get_blob(card, blob, 0x0081, &mod_blob)) == 0 + && (r = pgp_get_blob(card, blob, 0x0082, &exp_blob)) == 0 + && (r = pgp_read_blob(card, mod_blob)) == 0 + && (r = pgp_read_blob(card, exp_blob)) == 0) { + + memset(&pubkey, 0, sizeof(pubkey)); + + pubkey.algorithm = SC_ALGORITHM_RSA; + pubkey.u.rsa.modulus.data = mod_blob->data; + pubkey.u.rsa.modulus.len = mod_blob->len; + pubkey.u.rsa.exponent.data = exp_blob->data; + pubkey.u.rsa.exponent.len = exp_blob->len; + } + /* ECC */ + else if ((r = pgp_get_blob(card, blob, 0x0086, &pubkey_blob)) == 0 + && (r = pgp_read_blob(card, pubkey_blob)) == 0) { + + memset(&pubkey, 0, sizeof(pubkey)); + + pubkey.algorithm = SC_ALGORITHM_EC; + pubkey.u.ec.ecpointQ.value = pubkey_blob->data; + pubkey.u.ec.ecpointQ.len = pubkey_blob->len; + } + else + LOG_TEST_RET(card->ctx, r, "error getting elements"); r = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &data, &len); LOG_TEST_RET(card->ctx, r, "public key encoding failed"); @@ -1957,7 +2045,9 @@ pgp_set_security_env(sc_card_t *card, LOG_FUNC_CALLED(card->ctx); - if ((env->flags & SC_SEC_ENV_ALG_PRESENT) && (env->algorithm != SC_ALGORITHM_RSA)) + if ((env->flags & SC_SEC_ENV_ALG_PRESENT) + && (env->algorithm != SC_ALGORITHM_RSA) + && (priv->bcd_version < OPENPGP_CARD_3_0)) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "only RSA algorithm supported"); @@ -2119,8 +2209,8 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, /* padding according to OpenPGP card spec 1.1 & 2.x section 7.2.9 / 3.x section 7.2.11 */ if (!(temp = malloc(inlen + 1))) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - /* padding byte: 0x00 = RSA; 0x02 = AES [v2.1+ only] */ - temp[0] = 0x00; + /* padding byte: 0xa6 = ECC; 0x00 = RSA; 0x02 = AES */ + (env->algorithm == SC_ALGORITHM_EC) ? (temp[0] = 0xa6) : (temp[0] = 0x00); memcpy(temp + 1, in, inlen); in = temp; inlen += 1; @@ -2191,62 +2281,64 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *algo_blob; - unsigned int old_modulus_len; /* measured in bits */ - unsigned int old_exponent_len; const unsigned int tag = 0x00C0 | key_info->key_id; - u8 changed = 0; + u8 *data; + int data_len; int r = SC_SUCCESS; + unsigned int i; LOG_FUNC_CALLED(card->ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - - /* get old algorithm attributes */ r = pgp_seek_blob(card, priv->mf, tag, &algo_blob); LOG_TEST_RET(card->ctx, r, "Cannot get old algorithm attributes"); - old_modulus_len = bebytes2ushort(algo_blob->data + 1); /* modulus length is coded in byte 2 & 3 */ - sc_log(card->ctx, - "Old modulus length %d, new %"SC_FORMAT_LEN_SIZE_T"u.", - old_modulus_len, key_info->rsa.modulus_len); - old_exponent_len = bebytes2ushort(algo_blob->data + 3); /* exponent length is coded in byte 3 & 4 */ - sc_log(card->ctx, - "Old exponent length %d, new %"SC_FORMAT_LEN_SIZE_T"u.", - old_exponent_len, key_info->rsa.exponent_len); - - /* Modulus */ - /* If passed modulus_len is zero, it means using old key size */ - if (key_info->rsa.modulus_len == 0) { - sc_log(card->ctx, "Use old modulus length (%d).", old_modulus_len); - key_info->rsa.modulus_len = old_modulus_len; - } - /* To generate key with new key size */ - else if (old_modulus_len != key_info->rsa.modulus_len) { - algo_blob->data[1] = (unsigned char)(key_info->rsa.modulus_len >> 8); - algo_blob->data[2] = (unsigned char)key_info->rsa.modulus_len; - changed = 1; - } - - /* Exponent */ - if (key_info->rsa.exponent_len == 0) { - sc_log(card->ctx, "Use old exponent length (%d).", old_exponent_len); - key_info->rsa.exponent_len = old_exponent_len; - } - else if (old_exponent_len != key_info->rsa.exponent_len) { - algo_blob->data[3] = (unsigned char)(key_info->rsa.exponent_len >> 8); - algo_blob->data[4] = (unsigned char)key_info->rsa.exponent_len; - changed = 1; - } - - /* If the key to-be-generated has different size, - * set this new value for GENERATE ASYMMETRIC KEY PAIR to work */ - if (changed) { - r = pgp_put_data(card, tag, algo_blob->data, 6); - /* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */ - LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); + + /* ECDSA and ECDH */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + data_len = key_info->u.ec.oid_len+1; + data = malloc(data_len); + if (!data) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + data[0] = key_info->algorithm; + /* oid.value is type int, therefore we need to loop over the values */ + for (i=0; i < key_info->u.ec.oid_len; i++){ + data[i+1] = key_info->u.ec.oid.value[i]; + } } + /* RSA */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + + /* We can not rely on previous key attributes anymore, as it might be ECC */ + if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0) + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + + data_len = 6; + data = malloc(data_len); + if (!data) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + data[0] = key_info->algorithm; + ushort2bebytes(data+1, key_info->u.rsa.modulus_len); + /* OpenPGP Card only accepts 32bit as exponent lenght field, + * although you can import keys with smaller exponent; + * thus we don't change rsa.exponent_len, but ignore it here */ + ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS); + /* Import-Format of private key (e,p,q) */ + data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; + } + else { + sc_log(card->ctx, "Unknown algorithm id"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + pgp_set_blob(algo_blob, data, data_len); + free(data); + r = pgp_put_data(card, tag, algo_blob->data, data_len); + /* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */ + LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); + LOG_FUNC_RETURN(card->ctx, r); } @@ -2297,19 +2389,14 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) /** - * Internal: calculate PGP fingerprints. + * Internal: calculate and store PGP fingerprints. * Reference: GnuPG, app-openpgp.c. - * modulus and exponent are passed separately from key_info - * because key_info->exponent may be null. **/ static int pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, - u8* modulus, u8* exponent, sc_cardctl_openpgp_keygen_info_t *key_info) { u8 fingerprint[SHA_DIGEST_LENGTH]; - size_t mlen = key_info->rsa.modulus_len >> 3; /* 1/8 */ - size_t elen = key_info->rsa.exponent_len >> 3; /* 1/8 */ u8 *fp_buffer = NULL; /* fingerprint buffer, not hashed */ size_t fp_buffer_len; u8 *p; /* use this pointer to set fp_buffer content */ @@ -2321,29 +2408,65 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, LOG_FUNC_CALLED(card->ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + /* constructing public-key packet length */ + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { + + if (key_info->u.rsa.modulus == NULL + || key_info->u.rsa.exponent == NULL + || (key_info->u.rsa.modulus_len) == 0 + || (key_info->u.rsa.exponent_len) == 0) { + + sc_log(card->ctx, "Null data (modulus or exponent)"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } - if (modulus == NULL || mlen == 0) - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Modulus missing"); - if (exponent == NULL || elen == 0) - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Exponent missing"); + /* https://tools.ietf.org/html/rfc4880 page 41, 72 */ + pk_packet_len = 1 /* version number */ + + 4 /* creation time */ + + 1 /* algorithm */ + + 2 /* algorithm-specific fields: RSA modulus+exponent */ + + (BYTES4BITS(key_info->u.rsa.modulus_len)) + + 2 + + (BYTES4BITS(key_info->u.rsa.exponent_len)); + + } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + if (key_info->u.ec.ecpoint == NULL || (key_info->u.ec.ecpoint_len) == 0) { + sc_log(card->ctx, "Error: ecpoint required!"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } - /* http://tools.ietf.org/html/rfc4880 page 41, 72 */ - pk_packet_len = 1 /* version number */ - + 4 /* creation time */ - + 1 /* algorithm */ - + 2 /* algorithm-specific fields: RSA modulus+exponent */ - + mlen - + 2 - + elen; + /* https://tools.ietf.org/html/rfc4880 page 41, 72 + * and https://tools.ietf.org/html/rfc6637 section 9 (page 8 and 9) */ + pk_packet_len = 1 /* version number */ + + 4 /* creation time */ + + 1 /* algorithm */ + + 1 /* oid len */ + + (key_info->u.ec.oid_len) /* oid */ + + (key_info->u.ec.ecpoint_len); /* ecpoint */ + + /* KDF parameters for ECDH */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { + /* https://tools.ietf.org/html/rfc6637#section-8 */ + pk_packet_len += 1 /* number of bytes */ + + 1 /* version number */ + + 1 /* KDF algo */ + + 1; /* KEK algo */ + } + } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + sc_log(card->ctx, "pk_packet_len is %lu", pk_packet_len); fp_buffer_len = 3 + pk_packet_len; p = fp_buffer = calloc(fp_buffer_len, 1); if (p == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + /* constructing public-key packet */ p[0] = 0x99; /* http://tools.ietf.org/html/rfc4880 page 71 */ ushort2bebytes(++p, (unsigned short)pk_packet_len); /* start pk_packet */ @@ -2351,15 +2474,57 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, *p = 4; /* Version 4 key */ ulong2bebytes(++p, (unsigned long)ctime); /* Creation time */ p += 4; - *p = 1; /* RSA */ - /* algorithm-specific fields */ - ushort2bebytes(++p, (unsigned short)key_info->rsa.modulus_len); - p += 2; - memcpy(p, modulus, mlen); - p += mlen; - ushort2bebytes(++p, (unsigned short)key_info->rsa.exponent_len); - p += 2; - memcpy(p, exponent, elen); + + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { + *p = 1; /* Algorithm ID, RSA */ + p += 1; + ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len); + p += 2; + memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len))); + p += (key_info->u.rsa.modulus_len >> 3); + ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len); + p += 2; + memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len))); + } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + /* Algorithm ID, see https://tools.ietf.org/html/rfc6637#section-5 */ + *p = key_info->algorithm + 6; + p += 1; + *p = key_info->u.ec.oid_len; + p += 1; + memcpy(p, key_info->u.ec.oid.value, key_info->u.ec.oid_len); + p += key_info->u.ec.oid_len; + memcpy(p, key_info->u.ec.ecpoint, key_info->u.ec.ecpoint_len); + + /* KDF parameters for ECDH */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { + /* https://tools.ietf.org/html/rfc6637#section-8 + * This is copied from GnuPG's ecdh_params() function in app-openpgp.c */ + p += key_info->u.ec.ecpoint_len; + *p = 0x03; /* number of bytes following */ + p += 1; + *p = 0x01; /* version of this format */ + p += 1; + if (key_info->u.ec.ecpoint_len <= 256){ /* ec bit size <= 256 */ + *p = 0x08; /* KDF algo */ + *(p+1) = 0x07; /* KEK algo */ + } + else if (key_info->u.ec.ecpoint_len <= 384) { /* ec bit size <= 384 */ + *p = 0x09; /* KDF algo */ + *(p+1) = 0x08; /* KEK algo */ + } + else { /* ec bit size = 512 */ + *p = 0x0a; /* KDF algo */ + *(p+1) = 0x09; /* KEK algo */ + } + } + } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + p = NULL; /* hash with SHA-1 */ @@ -2402,8 +2567,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, * Note that modulus_len, exponent_len is measured in bit. **/ static int -pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, - u8* exponent, size_t exponent_len, u8 key_id) +pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *pk_blob; @@ -2415,11 +2579,11 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, LOG_FUNC_CALLED(card->ctx); - if (key_id == SC_OPENPGP_KEY_SIGN) + if (key_info->key_id == SC_OPENPGP_KEY_SIGN) blob_id = DO_SIGN_SYM; - else if (key_id == SC_OPENPGP_KEY_ENCR) + else if (key_info->key_id == SC_OPENPGP_KEY_ENCR) blob_id = DO_ENCR_SYM; - else if (key_id == SC_OPENPGP_KEY_AUTH) + else if (key_info->key_id == SC_OPENPGP_KEY_AUTH) blob_id = DO_AUTH_SYM; else { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, @@ -2431,12 +2595,25 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len, LOG_TEST_RET(card->ctx, r, "Cannot get the blob"); /* encode pubkey */ - memset(&pubkey, 0, sizeof(pubkey)); - pubkey.algorithm = SC_ALGORITHM_RSA; - pubkey.u.rsa.modulus.data = modulus; - pubkey.u.rsa.modulus.len = modulus_len >> 3; /* 1/8 */ - pubkey.u.rsa.exponent.data = exponent; - pubkey.u.rsa.exponent.len = exponent_len >> 3; + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + memset(&pubkey, 0, sizeof(pubkey)); + pubkey.algorithm = SC_ALGORITHM_RSA; + pubkey.u.rsa.modulus.data = key_info->u.rsa.modulus; + pubkey.u.rsa.modulus.len = BYTES4BITS(key_info->u.rsa.modulus_len); + pubkey.u.rsa.exponent.data = key_info->u.rsa.exponent; + pubkey.u.rsa.exponent.len = BYTES4BITS(key_info->u.rsa.exponent_len); + } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + memset(&pubkey, 0, sizeof(pubkey)); + pubkey.algorithm = SC_ALGORITHM_EC; + pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpoint; + pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpoint_len; + } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); r = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &data, &len); LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); @@ -2457,8 +2634,6 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, { time_t ctime = 0; u8 *in = data; - u8 *modulus = NULL; - u8 *exponent = NULL; int r; LOG_FUNC_CALLED(card->ctx); @@ -2473,9 +2648,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, u8 *part = in; /* parse TLV structure */ - r = sc_asn1_read_tag((const u8**)&part, - data_len - (in - data), - &cla, &tag, &len); + r = sc_asn1_read_tag((const u8**)&part, data_len - (in - data), &cla, &tag, &len); if (part == NULL) r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; LOG_TEST_RET(card->ctx, r, "Unexpected end of contents"); @@ -2485,25 +2658,49 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, } tag |= cla; + /* RSA modulus */ if (tag == 0x0081) { - /* set the output data */ - if (key_info->rsa.modulus) { - memcpy(key_info->rsa.modulus, part, len); + if ((BYTES4BITS(key_info->u.rsa.modulus_len) < len) /* modulus_len is in bits */ + || key_info->u.rsa.modulus == NULL) { + + free(key_info->u.rsa.modulus); + key_info->u.rsa.modulus = malloc(len); + if (key_info->u.rsa.modulus == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } - /* always set output for modulus_len */ - key_info->rsa.modulus_len = len*8; - /* remember the modulus to calculate fingerprint later */ - modulus = part; + + /* set values */ + memcpy(key_info->u.rsa.modulus, part, len); + key_info->u.rsa.modulus_len = len * 8; /* store length in bits */ } + /* RSA public exponent */ else if (tag == 0x0082) { + if ((BYTES4BITS(key_info->u.rsa.exponent_len) < len) /* exponent_len is in bits */ + || key_info->u.rsa.exponent == NULL) { + + free(key_info->u.rsa.exponent); + key_info->u.rsa.exponent = malloc(len); + if (key_info->u.rsa.exponent == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + } + + /* set values */ + memcpy(key_info->u.rsa.exponent, part, len); + key_info->u.rsa.exponent_len = len * 8; /* store length in bits */ + } + /* ECC public key */ + else if (tag == 0x0086) { /* set the output data */ - if (key_info->rsa.exponent) { - memcpy(key_info->rsa.exponent, part, len); + /* len is ecpoint length + format byte + * see section 7.2.14 of 3.3.1 specs */ + if ((key_info->u.ec.ecpoint_len) != (len - 1) + || key_info->u.ec.ecpoint == NULL) { + free(key_info->u.ec.ecpoint); + key_info->u.ec.ecpoint = malloc(len); + if (key_info->u.ec.ecpoint == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } - /* always set output for exponent_len */ - key_info->rsa.exponent_len = len*8; - /* remember the exponent to calculate fingerprint later */ - exponent = part; + memcpy(key_info->u.ec.ecpoint, part + 1, len - 1); } /* go to next part to parse */ @@ -2513,12 +2710,11 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); - r = pgp_calculate_and_store_fingerprint(card, ctime, modulus, exponent, key_info); + r = pgp_calculate_and_store_fingerprint(card, ctime, key_info); LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); - /* update pubkey blobs (B601,B801, A401) */ + /* update pubkey blobs (B601, B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, modulus, key_info->rsa.modulus_len, - exponent, key_info->rsa.exponent_len, key_info->key_id); + r = pgp_update_pubkey_blob(card, key_info); LOG_FUNC_RETURN(card->ctx, r); } @@ -2534,8 +2730,9 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke LOG_FUNC_CALLED(card->ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + /* protect older cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA + && card->type < SC_CARD_TYPE_OPENPGP_V3) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); if (id > card->algorithm_count) { @@ -2547,17 +2744,25 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke /* get the algorithm corresponding to the key ID */ algo = card->algorithms + (id - 1); - /* update new key length attribute */ - algo->key_length = (unsigned int)key_info->rsa.modulus_len; + /* update new key attribute */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { + algo->algorithm = SC_ALGORITHM_RSA; + algo->key_length = (unsigned int)key_info->u.rsa.modulus_len; + } + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + algo->algorithm = SC_ALGORITHM_EC; + algo->key_length = (unsigned int)((key_info->u.ec.ecpoint_len)); + } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } /** * ABI (card ctl): GENERATE ASYMMETRIC KEY PAIR - * Set key_info->modulus_len to zero if want to use old key size. - * Similarly for exponent length. - * key_info->modulus_len and key_info->exponent_len will be returned with new values. **/ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) @@ -2572,8 +2777,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) LOG_FUNC_CALLED(card->ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + /* protect older cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA + && card->type < SC_CARD_TYPE_OPENPGP_V3) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* set Control Reference Template for key */ @@ -2588,7 +2794,7 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) "Invalid key ID; must be 1, 2, or 3"); } - if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->rsa.modulus_len != 2048) + if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->u.rsa.modulus_len != 2048) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Gnuk only supports generating keys up to 2048-bit"); @@ -2600,7 +2806,7 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) * arbitrary modulus length which for sure fits into a short APDU. * This idea is borrowed from GnuPG code. */ if (card->caps & SC_CARD_CAP_APDU_EXT - && key_info->rsa.modulus_len > 1900 + && key_info->u.rsa.modulus_len > 1900 && card->type != SC_CARD_TYPE_OPENPGP_GNUK) { /* We won't store to apdu variable yet, because it will be reset in * sc_format_apdu() */ @@ -2726,7 +2932,7 @@ set_taglength_tlv(u8 *buffer, unsigned int tag, size_t length) /** - * Internal: build Extended Header list (sec 4.3.3.7 - OpenPGP card spec v.2) + * Internal: build Extended Header list (sec 4.3.3.9 - OpenPGP card spec v.3) **/ static int pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info, @@ -2754,63 +2960,98 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info u8 *data = NULL; size_t len = 0; u8 *p = NULL; - u8 *components[] = {key_info->rsa.e, key_info->rsa.p, key_info->rsa.q, key_info->rsa.n}; - size_t componentlens[] = {key_info->rsa.e_len, key_info->rsa.p_len, - key_info->rsa.q_len, key_info->rsa.n_len}; - unsigned int componenttags[] = {0x91, 0x92, 0x93, 0x97}; - char *componentnames[] = { - "public exponent", - "prime p", - "prime q", - "modulus" - }; - size_t comp_to_add = 3; - size_t req_e_len = 0; /* The exponent length specified in Algorithm Attributes */ - pgp_blob_t *alat_blob; + u8 *components[4]; + size_t componentlens[4]; + unsigned int componenttags[4]; + char *componentnames[4]; + size_t comp_to_add; u8 i; int r; LOG_FUNC_CALLED(ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); - - if (key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN - || key_info->rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN) - comp_to_add = 4; - - /* validate */ - if (comp_to_add == 4 && (key_info->rsa.n == NULL || key_info->rsa.n_len == 0)) - LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Modulus required"); - - /* Cardholder private key template's data part */ - memset(pritemplate, 0, max_prtem_len); - - /* get required exponent length */ - alat_blob = pgp_find_blob(card, 0x00C0 | key_info->key_id); - if (alat_blob == NULL) - LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, - "Cannot read Algorithm Attributes"); - - req_e_len = bebytes2ushort(alat_blob->data + 3) >> 3; /* 1/8 */ - assert(key_info->rsa.e_len <= req_e_len); - - /* We need to right justify the exponent with required length, - * e.g. from '01 00 01' to '00 01 00 01' */ - if (key_info->rsa.e_len < req_e_len) { - /* create new buffer */ - p = calloc(req_e_len, 1); - if (p == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - memcpy(p + req_e_len - key_info->rsa.e_len, key_info->rsa.e, key_info->rsa.e_len); - key_info->rsa.e_len = req_e_len; - /* set key_info->e to new buffer */ - free(key_info->rsa.e); - key_info->rsa.e = p; - components[0] = p; - componentlens[0] = req_e_len; + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + + components[0] = key_info->u.rsa.e; + components[1] = key_info->u.rsa.p; + components[2] = key_info->u.rsa.q; + componentlens[0] = key_info->u.rsa.e_len; + componentlens[1] = key_info->u.rsa.p_len; + componentlens[2] = key_info->u.rsa.q_len; + componenttags[0] = 0x91; + componenttags[1] = 0x92; + componenttags[2] = 0x93; + componentnames[0] = "public exponent"; + componentnames[1] = "prime p"; + componentnames[2] = "prime q"; + comp_to_add = 3; + + /* The maximum exponent length is 32 bit, as set on card + * we use this variable to check against actual exponent_len */ + size_t max_e_len_bytes = BYTES4BITS(SC_OPENPGP_MAX_EXP_BITS); + size_t e_len_bytes = BYTES4BITS(key_info->u.rsa.e_len); + + if (key_info->u.rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN + || key_info->u.rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN){ + components[3] = key_info->u.rsa.n; + componentlens[3] = key_info->u.rsa.n_len; + componenttags[3] = 0x97; + componentnames[3] = "modulus"; + comp_to_add = 4; + } + + /* validate */ + if (comp_to_add == 4 && (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0)){ + sc_log(ctx, "Error: Modulus required!"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + /* Cardholder private key template's data part */ + memset(pritemplate, 0, max_prtem_len); + + /* maximum 32 bit exponent length allowed on OpenPGP Card */ + assert(key_info->u.rsa.e_len <= SC_OPENPGP_MAX_EXP_BITS); + + /* We need to right justify the exponent with allowed exponent length, + * e.g. from '01 00 01' to '00 01 00 01' */ + if (key_info->u.rsa.e_len < SC_OPENPGP_MAX_EXP_BITS) { + /* create new buffer */ + p = calloc(max_e_len_bytes, 1); + if (!p) + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + memcpy(p + (max_e_len_bytes - e_len_bytes), key_info->u.rsa.e, e_len_bytes); + /* set key_info->u.rsa.e to new buffer */ + free(key_info->u.rsa.e); + key_info->u.rsa.e = p; + components[0] = p; + key_info->u.rsa.e_len = SC_OPENPGP_MAX_EXP_BITS; /* we store info in bits */ + componentlens[0] = max_e_len_bytes; /* ... but in bytes for header list */ + } } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + components[0] = key_info->u.ec.privateD; + componentlens[0] = key_info->u.ec.privateD_len; + componenttags[0] = 0x92; + componentnames[0] = "private key"; + comp_to_add = 1; + + /* TODO ECC import with public key, if necessary as denoted in algorithm caps*/ + + /* validate */ + if ((key_info->u.ec.ecpoint == NULL || key_info->u.ec.ecpoint_len == 0)){ + sc_log(ctx, "Error: ecpoint required!"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + /* Cardholder private key template's data part */ + memset(pritemplate, 0, max_prtem_len); + } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* start from beginning of pritemplate */ p = pritemplate; @@ -2861,7 +3102,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key ID; must be 1, 2, or 3"); } - memcpy(data + 2, tlv_7f48, tlvlen_7f48); + memcpy(data + 2, tlv_7f48, tlvlen_7f48); memcpy(data + 2 + tlvlen_7f48, tlv_5f48, tlvlen_5f48); r = pgp_build_tlv(ctx, 0x4D, data, len, &tlvblock, &tlvlen); LOG_TEST_GOTO_ERR(ctx, r, "Cannot build TLV for Extended Header list"); @@ -2895,8 +3136,9 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(card->ctx); - /* temporary workaround: protect v3 cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) + /* protect older cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA + && card->type < SC_CARD_TYPE_OPENPGP_V3) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* Validate */ @@ -2905,7 +3147,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) "Invalid key ID; must be 1, 2, or 3"); /* we just support standard key format */ - switch (key_info->rsa.keyformat) { + switch (key_info->u.rsa.keyformat) { case SC_OPENPGP_KEYFORMAT_RSA_STD: case SC_OPENPGP_KEYFORMAT_RSA_STDN: break; @@ -2918,23 +3160,46 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - /* we only support exponent of maximum 32 bits */ - if (key_info->rsa.e_len > 4) { - sc_log(card->ctx, - "Exponent %"SC_FORMAT_LEN_SIZE_T"u-bit (>32) is not supported.", - key_info->rsa.e_len * 8); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - } - /* set algorithm attributes */ - memset(&pubkey, 0, sizeof(pubkey)); - pubkey.key_id = key_info->key_id; - if (key_info->rsa.n && key_info->rsa.n_len) { - pubkey.rsa.modulus = key_info->rsa.n; - pubkey.rsa.modulus_len = 8*key_info->rsa.n_len; - /* We won't update exponent length, because smaller exponent length - * will be padded later */ + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + /* we only support exponent of maximum 32 bits */ + if (key_info->u.rsa.e_len > SC_OPENPGP_MAX_EXP_BITS) { + sc_log(card->ctx, + "Exponent %"SC_FORMAT_LEN_SIZE_T"u-bit (>32) is not supported.", + key_info->u.rsa.e_len); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + memset(&pubkey, 0, sizeof(pubkey)); + pubkey.key_id = key_info->key_id; + pubkey.algorithm = key_info->algorithm; + if (key_info->u.rsa.n && key_info->u.rsa.n_len + && key_info->u.rsa.e && key_info->u.rsa.e_len) { + pubkey.u.rsa.modulus = key_info->u.rsa.n; + pubkey.u.rsa.modulus_len = key_info->u.rsa.n_len; + pubkey.u.rsa.exponent = key_info->u.rsa.e; + pubkey.u.rsa.exponent_len = key_info->u.rsa.e_len; + } + else + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + memset(&pubkey, 0, sizeof(pubkey)); + pubkey.key_id = key_info->key_id; + pubkey.algorithm = key_info->algorithm; + if (key_info->u.ec.ecpoint && key_info->u.ec.ecpoint_len){ + pubkey.u.ec.ecpoint = key_info->u.ec.ecpoint; + pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpoint_len; + } + else + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); } + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + r = pgp_update_new_algo_attr(card, &pubkey); LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); @@ -2952,15 +3217,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); - r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, - key_info->rsa.n, key_info->rsa.e, &pubkey); + r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, &pubkey); LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, key_info->rsa.n, 8*key_info->rsa.n_len, - key_info->rsa.e, 8*key_info->rsa.e_len, key_info->key_id); + r = pgp_update_pubkey_blob(card, &pubkey); - sc_log(card->ctx, "Update card algorithms."); + sc_log(card->ctx, "Update card algorithms"); pgp_update_card_algorithms(card, &pubkey); err: diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index e06674371c..3dbbd40f28 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -944,38 +944,45 @@ typedef struct sc_cardctl_piv_genkey_info_st { #define SC_OPENPGP_KEY_AUTH 3 #define SC_OPENPGP_KEYALGO_RSA 0x01 +#define SC_OPENPGP_KEYALGO_ECDH 0x12 +#define SC_OPENPGP_KEYALGO_ECDSA 0x13 #define SC_OPENPGP_KEYFORMAT_RSA_STD 0 /* See 4.3.3.6 Algorithm Attributes */ #define SC_OPENPGP_KEYFORMAT_RSA_STDN 1 /* OpenPGP card spec v2 */ #define SC_OPENPGP_KEYFORMAT_RSA_CRT 2 #define SC_OPENPGP_KEYFORMAT_RSA_CRTN 3 +#define SC_OPENPGP_MAX_EXP_BITS 0x20 /* maximum exponent length supported in bits */ + typedef struct sc_cardctl_openpgp_keygen_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ - union { /* anonymous union */ + union { struct { u8 *modulus; /* New-generated pubkey info responded from the card */ size_t modulus_len; /* Length of modulus in bit */ u8 *exponent; - size_t exponent_len; - u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ + size_t exponent_len; /* Length of exponent in bit */ + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ } rsa; struct { - u8 dummy; /* placeholder */ - // TODO: replace placeholder with real attributes + u8 *ecpoint; + size_t ecpoint_len; + struct sc_object_id oid; + u8 oid_len; + unsigned int key_length; } ec; - }; + } u; } sc_cardctl_openpgp_keygen_info_t; typedef struct sc_cardctl_openpgp_keystore_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ - union { /* anonymous union */ + union { struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ u8 *e; - size_t e_len; + size_t e_len; /* Length of exponent in bit */ u8 *p; size_t p_len; u8 *q; @@ -984,10 +991,12 @@ typedef struct sc_cardctl_openpgp_keystore_info { size_t n_len; } rsa; struct { - u8 dummy; /* placeholder */ - // TODO: replace placeholder with real attributes + u8 *privateD; + size_t privateD_len; + u8 *ecpoint; + size_t ecpoint_len; } ec; - }; + } u; time_t creationtime; } sc_cardctl_openpgp_keystore_info_t; diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 622e8fde50..5fd9c18579 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -118,6 +118,8 @@ unsigned short bebytes2ushort(const u8 *buf); */ unsigned short lebytes2ushort(const u8 *buf); +#define BYTES4BITS(num) (((num) + 7) / 8) /* number of bytes necessary to hold 'num' bits */ + /* Returns an scconf_block entry with matching ATR/ATRmask to the ATR specified, * NULL otherwise. Additionally, if card driver is not specified, search through * all card drivers user configured ATRs. */ diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 91226f4b38..bd3d151e90 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -268,20 +268,17 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) for (i = 0; i < 3; i++) { sc_pkcs15_prkey_info_t prkey_info; sc_pkcs15_object_t prkey_obj; - u8 cxdata[10]; + u8 cxdata[12]; char path_template[] = "006E:0073:00Cx"; int j; memset(&prkey_info, 0, sizeof(prkey_info)); memset(&prkey_obj, 0, sizeof(prkey_obj)); + memset(&cxdata, 0, sizeof(cxdata)); path_template[13] = '1' + i; /* The needed tags are C1 C2 and C3 */ if ((r = read_file(card, path_template, cxdata, sizeof(cxdata))) < 0) goto failed; - if (r != 6) { - sc_log(ctx, "Key info bytes have unexpected length (expected 6, got %d)\n", r); - return SC_ERROR_INTERNAL; - } /* check validity using finger prints */ for (j = 19; j >= 0; j--) { @@ -296,14 +293,21 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) prkey_info.usage = key_cfg[i].prkey_usage; prkey_info.native = 1; prkey_info.key_reference = i; - prkey_info.modulus_length = bebytes2ushort(cxdata + 1); strlcpy(prkey_obj.label, key_cfg[i].label, sizeof(prkey_obj.label)); prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | SC_PKCS15_CO_FLAG_MODIFIABLE; prkey_obj.auth_id.len = 1; prkey_obj.auth_id.value[0] = key_cfg[i].prkey_pin; - r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + if (cxdata[0] == SC_OPENPGP_KEYALGO_RSA && r >= 3) { + prkey_info.modulus_length = bebytes2ushort(cxdata + 1); + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + } + if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH + || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA) { + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + } + if (r < 0) return SC_ERROR_INTERNAL; } @@ -318,14 +322,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) memset(&pubkey_info, 0, sizeof(pubkey_info)); memset(&pubkey_obj, 0, sizeof(pubkey_obj)); + memset(&cxdata, 0, sizeof(cxdata)); path_template[13] = '1' + i; /* The needed tags are C1 C2 and C3 */ if ((r = read_file(card, path_template, cxdata, sizeof(cxdata))) < 0) goto failed; - if (r != 6) { - sc_log(ctx, "Key info bytes have unexpected length (expected 6, got %d)\n", r); - return SC_ERROR_INTERNAL; - } /* check validity using finger prints */ for (j = 19; j >= 0; j--) { @@ -337,14 +338,21 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (j >= 0 && cxdata[0] != 0) { pubkey_info.id.len = 1; pubkey_info.id.value[0] = i + 1; - pubkey_info.modulus_length = bebytes2ushort(cxdata + 1); pubkey_info.usage = key_cfg[i].pubkey_usage; sc_format_path(key_cfg[i].pubkey_path, &pubkey_info.path); strlcpy(pubkey_obj.label, key_cfg[i].label, sizeof(pubkey_obj.label)); pubkey_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; - r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + if (cxdata[0] == SC_OPENPGP_KEYALGO_RSA && r >= 3) { + pubkey_info.modulus_length = bebytes2ushort(cxdata + 1); + r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + } + if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH + || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA) { + r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); + } + if (r < 0) return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e9b7f27e7b..ec79d97ed7 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1074,6 +1074,8 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc u8* alg; size_t alglen; + LOG_FUNC_CALLED(ctx); + if (!key || !out) { return SC_ERROR_INVALID_ARGUMENTS; } @@ -1132,9 +1134,15 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc memcpy(pubkey->u.ec.params.der.value, key->u.ec.params.der.value, key->u.ec.params.der.len); pubkey->u.ec.params.der.len = key->u.ec.params.der.len; - pubkey->u.ec.params.named_curve = strdup(key->u.ec.params.named_curve); - if (!pubkey->u.ec.params.named_curve) - rv = SC_ERROR_OUT_OF_MEMORY; + if (key->u.ec.params.named_curve){ + pubkey->u.ec.params.named_curve = strdup(key->u.ec.params.named_curve); + if (!pubkey->u.ec.params.named_curve) + rv = SC_ERROR_OUT_OF_MEMORY; + } + else { + sc_log(ctx, "named_curve parameter missing"); + rv = SC_ERROR_NOT_SUPPORTED; + } break; default: @@ -1557,9 +1565,8 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp LOG_TEST_RET(ctx, rv, "Cannot encode object ID"); } } - else if (sc_valid_oid(&ecparams->id)) { + else LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "EC parameters has to be presented as a named curve or explicit data"); - } LOG_FUNC_RETURN(ctx, SC_SUCCESS); } diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index eb28d9c4ed..dfd4b8b849 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -26,6 +26,7 @@ #include "libopensc/opensc.h" #include "libopensc/cardctl.h" +#include "libopensc/internal.h" #include "libopensc/log.h" #include "libopensc/cards.h" #include "libopensc/asn1.h" @@ -104,7 +105,7 @@ static int openpgp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } /** - * Stores an external (RSA) on the card. + * Stores an external key on the card. * @param profile profile information for this card * @param card sc_card_t object to use * @param obj sc_pkcs15_object_t object with pkcs15 information @@ -116,45 +117,61 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, { sc_card_t *card = p15card->card; sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; - struct sc_pkcs15_prkey_rsa *rsa = &(key->u.rsa); sc_cardctl_openpgp_keystore_info_t key_info; int r; LOG_FUNC_CALLED(card->ctx); - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_log(card->ctx, "only RSA is currently supported"); - return SC_ERROR_NOT_SUPPORTED; + switch(obj->type) + { + case SC_PKCS15_TYPE_PRKEY_RSA: + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; + key_info.key_id = kinfo->id.value[0]; + key_info.u.rsa.e = key->u.rsa.exponent.data; + key_info.u.rsa.e_len = key->u.rsa.exponent.len * 8; /* use bits instead of bytes */ + key_info.u.rsa.p = key->u.rsa.p.data; + key_info.u.rsa.p_len = key->u.rsa.p.len; + key_info.u.rsa.q = key->u.rsa.q.data; + key_info.u.rsa.q_len = key->u.rsa.q.len; + key_info.u.rsa.n = key->u.rsa.modulus.data; + key_info.u.rsa.n_len = key->u.rsa.modulus.len * 8; /* use bits instead of bytes */ + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + break; + case SC_PKCS15_TYPE_PRKEY_EC: + if (card->type < SC_CARD_TYPE_OPENPGP_V3) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); + key_info.algorithm = (kinfo->id.value[0] == SC_OPENPGP_KEY_ENCR) + ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ + : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + key_info.key_id = kinfo->id.value[0]; + key_info.u.ec.privateD = key->u.ec.privateD.data; + key_info.u.ec.privateD_len = key->u.ec.privateD.len; + key_info.u.ec.ecpoint = key->u.ec.ecpointQ.value; + key_info.u.ec.ecpoint_len = key->u.ec.ecpointQ.len; + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + break; + default: + r = SC_ERROR_NOT_SUPPORTED; + sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r)); } - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); - key_info.key_id = kinfo->id.value[0]; - key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; - key_info.rsa.e = rsa->exponent.data; - key_info.rsa.e_len = rsa->exponent.len; - key_info.rsa.p = rsa->p.data; - key_info.rsa.p_len = rsa->p.len; - key_info.rsa.q = rsa->q.data; - key_info.rsa.q_len = rsa->q.len; - key_info.rsa.n = rsa->modulus.data; - key_info.rsa.n_len = rsa->modulus.len; - r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); - LOG_FUNC_RETURN(card->ctx, r); } /** - * Generates a new (RSA) key pair using an existing key file. - * @param profile IN profile information for this card + * Generates a new RSA key pair on card. * @param card IN sc_card_t object to use * @param obj IN sc_pkcs15_object_t object with pkcs15 information * @param pukkey OUT the newly created public key * @return SC_SUCCESS on success and an error code otherwise **/ -static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, - sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) +static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, + sc_pkcs15_pubkey_t *pubkey) { - sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; sc_cardctl_openpgp_keygen_info_t key_info; sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; @@ -185,46 +202,165 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card return SC_ERROR_NOT_SUPPORTED; } - /* Prepare buffer */ + key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; - key_info.rsa.modulus_len = required->modulus_length; - key_info.rsa.modulus = calloc(required->modulus_length >> 3, 1); - if (key_info.rsa.modulus == NULL) + + /* Prepare buffer */ + key_info.u.rsa.modulus_len = required->modulus_length; + key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1); + if (key_info.u.rsa.modulus == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); /* The OpenPGP supports only 32-bit exponent. */ - key_info.rsa.exponent_len = 32; - key_info.rsa.exponent = calloc(key_info.rsa.exponent_len>>3, 1); /* 1/8 */ - if (key_info.rsa.exponent == NULL) { - free(key_info.rsa.modulus); + key_info.u.rsa.exponent_len = 32; + key_info.u.rsa.exponent = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1); + if (key_info.u.rsa.exponent == NULL) { + free(key_info.u.rsa.modulus); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); - if (r < 0) - goto out; + LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed"); pubkey->algorithm = SC_ALGORITHM_RSA; - sc_log(ctx, "Set output modulus info"); - pubkey->u.rsa.modulus.len = key_info.rsa.modulus_len; - pubkey->u.rsa.modulus.data = calloc(key_info.rsa.modulus_len, 1); + pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len; + pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1); if (pubkey->u.rsa.modulus.data == NULL) - goto out; - memcpy(pubkey->u.rsa.modulus.data, key_info.rsa.modulus, key_info.rsa.modulus_len); + goto err; + memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len); sc_log(ctx, "Set output exponent info"); - pubkey->u.rsa.exponent.len = key_info.rsa.exponent_len; - pubkey->u.rsa.exponent.data = calloc(key_info.rsa.exponent_len>>3, 1); /* 1/8 */ + pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len; + pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1); if (pubkey->u.rsa.exponent.data == NULL) - goto out; - memcpy(pubkey->u.rsa.exponent.data, key_info.rsa.exponent, key_info.rsa.exponent_len>>3); /* 1/8 */ - -out: - if (key_info.rsa.modulus) - free(key_info.rsa.modulus); - if (key_info.rsa.exponent) - free(key_info.rsa.exponent); + goto err; + memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len)); + +err: + free(key_info.u.rsa.modulus); + free(key_info.u.rsa.exponent); + LOG_FUNC_RETURN(ctx, r); +} + + +/** + * Generates a new ECC key pair on card. + * @param card IN sc_card_t object to use + * @param obj IN sc_pkcs15_object_t object with pkcs15 information + * @param pukkey OUT the newly created public key + * @return SC_SUCCESS on success and an error code otherwise + **/ +static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, + sc_pkcs15_pubkey_t *pubkey) +{ + sc_context_t *ctx = card->ctx; + sc_cardctl_openpgp_keygen_info_t key_info; + sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; + sc_pkcs15_id_t *kid = &(required->id); + const struct sc_ec_parameters *info_ec = + (struct sc_ec_parameters *) required->params.data; + unsigned int i; + int r; + + LOG_FUNC_CALLED(ctx); + memset(&key_info, 0, sizeof(key_info)); + + sc_log(ctx, "Key ID to be generated: %s", sc_dump_hex(kid->value, kid->len)); + + /* Accept KeyID = 45, which is default value set by pkcs15init */ + if (kid->len == 1 && kid->value[0] == 0x45) { + /* Default key is authentication key. We choose this because the common use + * is to generate from PKCS#11 (Firefox/Thunderbird) */ + sc_log(ctx, "Authentication key is to be generated."); + key_info.key_id = 3; + } + if (!key_info.key_id && (kid->len > 1 || kid->value[0] > 3)) { + sc_log(ctx, "Key ID must be 1, 2 or 3!"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + if (!key_info.key_id) + key_info.key_id = kid->value[0]; + + + /* set algorithm id based on key reference */ + key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) + ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ + : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + + /* extract oid the way we need to import it to OpenPGP Card */ + if (info_ec->der.len > 2) + key_info.u.ec.oid_len = info_ec->der.value[1]; + else + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + + for (i=0; (i < key_info.u.ec.oid_len) && (i+2 < info_ec->der.len); i++){ + key_info.u.ec.oid.value[i] = info_ec->der.value[i+2]; + } + key_info.u.ec.oid.value[key_info.u.ec.oid_len] = -1; + + /* Prepare buffer */ + key_info.u.ec.ecpoint_len = required->field_length; + key_info.u.ec.ecpoint = malloc(key_info.u.ec.ecpoint_len); + if (key_info.u.ec.ecpoint == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + /* generate key on card */ + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed"); + + /* set pubkey according to response of card */ + sc_log(ctx, "Set output ecpoint info"); + pubkey->algorithm = SC_ALGORITHM_EC; + pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; + pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); + if (pubkey->u.ec.ecpointQ.value == NULL) + goto err; + memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpoint, key_info.u.ec.ecpoint_len); + +err: + if (key_info.u.ec.ecpoint) + free(key_info.u.ec.ecpoint); + + LOG_FUNC_RETURN(ctx, r); +} + + +/** + * Generates a new key pair using an existing key file. + * @param profile IN profile information for this card + * @param card IN sc_card_t object to use + * @param obj IN sc_pkcs15_object_t object with pkcs15 information + * @param pukkey OUT the newly created public key + * @return SC_SUCCESS on success and an error code otherwise + **/ +static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, + sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) +{ + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + int r; + + LOG_FUNC_CALLED(ctx); + + switch(obj->type) + { + case SC_PKCS15_TYPE_PRKEY_RSA: + r = openpgp_generate_key_rsa(card, obj, pubkey); + break; + case SC_PKCS15_TYPE_PRKEY_EC: + if (card->type < SC_CARD_TYPE_OPENPGP_V3) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); + return SC_ERROR_NOT_SUPPORTED; + } + r = openpgp_generate_key_ec(card, obj, pubkey); + break; + default: + r = SC_ERROR_NOT_SUPPORTED; + sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r)); + } + LOG_FUNC_RETURN(ctx, r); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 1da7f1dc24..13a1057d65 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -41,6 +41,7 @@ #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" +#include "libopensc/internal.h" #include "libopensc/cardctl.h" #include "libopensc/log.h" #include "libopensc/errors.h" @@ -703,11 +704,11 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) /* set key_info */ key_info.key_id = in_key_id; key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; - key_info.rsa.modulus_len = keylen; - key_info.rsa.modulus = malloc((keylen + 7) / 8); + key_info.u.rsa.modulus_len = keylen; + key_info.u.rsa.modulus = malloc(BYTES4BITS(keylen)); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); - free(key_info.rsa.modulus); + free(key_info.u.rsa.modulus); if (r < 0) { util_error("failed to generate key: %s", sc_strerror(r)); return EXIT_FAILURE; From 84f0a88edbae7fe4d81b796eb853069699178dc2 Mon Sep 17 00:00:00 2001 From: opensignature Date: Wed, 30 Jan 2019 22:01:24 +0100 Subject: [PATCH 0749/4321] Remove postecert and infocamere support because no longer issued (#1584) * Remove postecert and infocamere support because no longer issued * Remove wrong changes * reset NEWS * EC_POINT_set_affine_coordinates_GFp and EC_POINT_get_affine_coordinates_GFp are deprecated, use EC_POINT_set_affine_coordinates and EC_POINT_get_affine_coordinates * If OPENSSL API version is < 3 use old functions EC_POINT_[sg]et_affine_coordinates_GFp * Move the OpenSSL compatibility stuff to src/libopensc/sc-ossl-compat.h --- doc/files/files.html | 4 +- doc/files/opensc.conf.5.xml.in | 4 +- etc/opensc.conf.example.in | 2 +- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-cardos.c | 7 - src/libopensc/pkcs15-infocamere.c | 816 ------------------------------ src/libopensc/pkcs15-postecert.c | 369 -------------- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15-syn.c | 2 - src/libopensc/pkcs15-syn.h | 2 - src/libopensc/sc-ossl-compat.h | 5 + src/pkcs11/openssl.c | 3 +- src/tools/piv-tool.c | 2 +- src/tools/pkcs11-tool.c | 2 +- win32/Make.rules.mak | 2 +- 16 files changed, 20 insertions(+), 1210 deletions(-) delete mode 100644 src/libopensc/pkcs15-infocamere.c delete mode 100644 src/libopensc/pkcs15-postecert.c diff --git a/doc/files/files.html b/doc/files/files.html index ea5aa865ed..12684cd901 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -775,8 +775,8 @@ builtin_emulators = emulators;

    List of the builtin pkcs15 emulators to test - (Default: westcos, openpgp, infocamere, - starcert, tcos, esteid, itacns, postecert, + (Default: westcos, openpgp, + starcert, tcos, esteid, itacns, PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, atrust-acos, tccardos, entersafe, pteid, oberthur, sc-hsm, dnie, gids, iasecc, jpki, diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index df9088081b..33ac08bb45 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1178,8 +1178,8 @@ app application { List of the builtin pkcs15 emulators to test - (Default: westcos, openpgp, infocamere, - starcert, tcos, esteid, itacns, postecert, + (Default: westcos, openpgp, + starcert, tcos, esteid, itacns, PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, atrust-acos, tccardos, entersafe, pteid, oberthur, sc-hsm, dnie, gids, iasecc, jpki, diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index dc3b5bd865..3d54098f9b 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -904,7 +904,7 @@ app default { # enable_builtin_emulation = no; # # List of the builtin pkcs15 emulators to test - # Default: esteid, openpgp, tcos, starcert, itacns, infocamere, postecert, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; + # Default: esteid, openpgp, tcos, starcert, itacns, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; # builtin_emulators = openpgp; # additional settings per driver diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index e1e23cba03..3044f675a8 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -51,8 +51,8 @@ libopensc_la_SOURCES_BASE = \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c \ \ - pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ - pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ + pkcs15-openpgp.c pkcs15-starcert.c \ + pkcs15-tcos.c pkcs15-esteid.c pkcs15-gemsafeGPK.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index c498230489..08b6d6f337 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -30,8 +30,8 @@ OBJECTS = \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj \ \ - pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ - pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ + pkcs15-openpgp.obj pkcs15-starcert.obj \ + pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 3de45ffd8b..73b496d4ad 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -45,13 +45,6 @@ static struct sc_card_driver cardos_drv = { static const struct sc_atr_table cardos_atrs[] = { /* 4.0 */ { "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, - /* Italian eID card, postecert */ - { "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, NULL, SC_CARD_TYPE_CARDOS_CIE_V1, 0, NULL }, - /* Italian eID card, infocamere */ - { "3b:fb:98:00:ff:c1:10:31:fe:55:00:64:05:20:47:03:31:80:00:90:00:f3", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, - /* Another Italian InfocamereCard */ - { "3b:fc:98:00:ff:c1:10:31:fe:55:c8:03:49:6e:66:6f:63:61:6d:65:72:65:28", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, - { "3b:f4:98:00:ff:c1:10:31:fe:55:4d:34:63:76:b4", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL}, /* cardos m4.2 and above */ { "3b:f2:18:00:ff:c1:0a:31:fe:55:c8:06:8a", "ff:ff:0f:ff:00:ff:00:ff:ff:00:00:00:00", NULL, SC_CARD_TYPE_CARDOS_M4_2, 0, NULL }, /* CardOS 4.4 */ diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c deleted file mode 100644 index 6cb00d36b8..0000000000 --- a/src/libopensc/pkcs15-infocamere.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * PKCS15 emulation layer for 1202, 1203 and 1400 Infocamere card. - * To see how this works, run p15dump on your Infocamere card. - * - * Copyright (C) 2005, Sirio Capizzi - * Copyright (C) 2004, Antonino Iacono - * Copyright (C) 2003, Olaf Kirch - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#ifdef ENABLE_ZLIB -#include -#endif - -#include "common/compat_strlcpy.h" -#include "pkcs15.h" -#include "log.h" - -int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid, - sc_pkcs15emu_opt_t *); - -static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, - int); - -static int set_sec_env(sc_card_t * card, const sc_security_env_t * env, - int se_num) -{ - sc_security_env_t tenv = *env; - if (tenv.operation == SC_SEC_OPERATION_SIGN) - tenv.operation = SC_SEC_OPERATION_DECIPHER; - return set_security_env(card, &tenv, se_num); -} - -static int do_sign(sc_card_t * card, const u8 * in, size_t inlen, u8 * out, - size_t outlen) -{ - return card->ops->decipher(card, in, inlen, out, outlen); -} - -static void set_string(char **strp, const char *value) -{ - if (*strp) - free(*strp); - *strp = value ? strdup(value) : NULL; -} - -#if 1 -/* XXX: temporary copy of the old pkcs15emu functions, - * to be removed */ -static int sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card, - const sc_pkcs15_id_t *id, const char *label, - const sc_path_t *path, int ref, int type, - unsigned int min_length, - unsigned int max_length, - int flags, int tries_left, const char pad_char, int obj_flags) -{ - sc_pkcs15_auth_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; - info.auth_id = *id; - info.attrs.pin.min_length = min_length; - info.attrs.pin.max_length = max_length; - info.attrs.pin.stored_length = max_length; - info.attrs.pin.type = type; - info.attrs.pin.reference = ref; - info.attrs.pin.flags = flags; - info.attrs.pin.pad_char = pad_char; - info.tries_left = tries_left; - info.logged_in = SC_PIN_STATE_UNKNOWN; - - if (path) - info.path = *path; - if (type == SC_PKCS15_PIN_TYPE_BCD) - info.attrs.pin.stored_length /= 2; - - strlcpy(obj.label, label, sizeof(obj.label)); - obj.flags = obj_flags; - - return sc_pkcs15emu_add_pin_obj(p15card, &obj, &info); -} - -static int sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card, - const sc_pkcs15_id_t *id, - const char *label, - int type, unsigned int modulus_length, int usage, - const sc_path_t *path, int ref, - const sc_pkcs15_id_t *auth_id, int obj_flags) -{ - sc_pkcs15_prkey_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.id = *id; - info.modulus_length = modulus_length; - info.usage = usage; - info.native = 1; - info.key_reference = ref; - - if (path) - info.path = *path; - - obj.flags = obj_flags; - strlcpy(obj.label, label, sizeof(obj.label)); - if (auth_id != NULL) - obj.auth_id = *auth_id; - - return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info); -} - -static int sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card, - int type, int authority, const sc_path_t *path, - const sc_pkcs15_id_t *id, const char *label, int obj_flags) -{ - /* const char *label = "Certificate"; */ - sc_pkcs15_cert_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.id = *id; - info.authority = authority; - if (path) - info.path = *path; - - strlcpy(obj.label, label, sizeof(obj.label)); - obj.flags = obj_flags; - - return sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); -} -#endif - -static int infocamere_1200_init(sc_pkcs15_card_t * p15card) -{ - const int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - const int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN - | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - | SC_PKCS15_PRKEY_USAGE_ENCRYPT - | SC_PKCS15_PRKEY_USAGE_DECRYPT; - - sc_card_t *card = p15card->card; - sc_path_t path; - sc_pkcs15_id_t id, auth_id; - char serial[256]; - unsigned char certlen[2]; - int authority, change_sign = 0; - struct sc_pkcs15_cert_info cert_info; - struct sc_pkcs15_object cert_obj; - - const char *label = "User Non-repudiation Certificate"; - const char *calabel = "CA Certificate"; - const char *authlabel = "User Authentication Certificate"; - - const char *infocamere_cert_path[2] = { - "DF01C000", - "3F00000011111A02" - }; - - const char *infocamere_auth_certpath[2] = { - "11111A02", - "000011111B02" - }; - - const char *infocamere_cacert_path[2] = { - "DF01C008", - "000011114101" - }; - - const char *infocamere_auth_path[2] = { - "3F001111", - "3F0000001111" - }; - - const char *infocamere_nrepud_path[2] = { - "3F00DF01", - "3F0000001111" - }; - - const int infocamere_idpin_auth_obj[2] = { - 0x95, - 0x81 - }; - - const int infocamere_idpin_nrepud_obj[2] = { - 0x99, - 0x81 - }; - - const int infocamere_idprkey_auth_obj[2] = { - 0x9B, - 0x01 - }; - - const int infocamere_idprkey_nrepud_obj[2] = { - 0x84, - 0x01 - }; - - const char *authPIN = "Authentication PIN"; - const char *nonrepPIN = "Non-repudiation PIN"; - - const char *authPRKEY = "Authentication Key"; - const char *nonrepPRKEY = "Non repudiation Key"; - - const int flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | - SC_PKCS15_PIN_FLAG_INITIALIZED | - SC_PKCS15_PIN_FLAG_NEEDS_PADDING; - - int r; - - unsigned char chn[8]; - size_t chn_len = sizeof chn; - sc_serial_number_t iccsn; - iccsn.len = sizeof iccsn.value; - - - r = sc_parse_ef_gdo(card, iccsn.value, &iccsn.len, chn, &chn_len); - if (r < 0) - return r; - - if (!iccsn.len || chn_len < 2 || chn_len > 8) { - return SC_ERROR_WRONG_CARD; - } - - sc_bin_to_hex(iccsn.value, iccsn.len, serial, sizeof(serial), 0); - - if (! - (chn[0] == 0x12 - && (chn[1] == 0x02 || chn[1] == 0x03))) { - /* Not Infocamere Card */ - return SC_ERROR_WRONG_CARD; - } - - set_string(&p15card->tokeninfo->serial_number, serial); - - if (chn[1] == 0x02) - set_string(&p15card->tokeninfo->label, "Infocamere 1202 Card"); - else { - set_string(&p15card->tokeninfo->label, "Infocamere 1203 Card"); - change_sign = 1; - } - - set_string(&p15card->tokeninfo->manufacturer_id, "Infocamere"); - - authority = 0; - - /* Get the authentication certificate length */ - - sc_format_path(infocamere_auth_certpath[chn[1]-2], &path); - - r = sc_select_file(card, &path, NULL); - - if (r >= 0) { - - sc_read_binary(card, 0, certlen, 2, 0); - - /* Now set the certificate offset/len */ - - path.index = 2; - path.count = (certlen[1] << 8) + certlen[0]; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); - - sc_pkcs15_format_id("01", &cert_info.id); - cert_info.authority = authority; - cert_info.path = path; - strlcpy(cert_obj.label, authlabel, sizeof(cert_obj.label)); - cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; - - r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (r < 0) - return SC_ERROR_INTERNAL; - - /* XXX: the IDs for the key/pin in case of the 1203 type - * are wrong, therefore I disable them for now -- Nils */ - if (!change_sign) { - /* add authentication PIN */ - - sc_format_path(infocamere_auth_path[chn[1]-2], &path); - - sc_pkcs15_format_id("01", &id); - sc_pkcs15emu_add_pin(p15card, &id, - authPIN, &path, infocamere_idpin_auth_obj[chn[1]-2], - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 5, 8, flags, 3, 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); - - /* add authentication private key */ - - auth_id.value[0] = 1; - auth_id.len = 1; - - sc_pkcs15emu_add_prkey(p15card, &id, - authPRKEY, - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, authprkey_usage, - &path, infocamere_idprkey_auth_obj[chn[1]-2], - &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - } - - } - - /* Get the non-repudiation certificate length */ - - sc_format_path(infocamere_cert_path[chn[1]-2], &path); - - if (sc_select_file(card, &path, NULL) < 0) { - return SC_ERROR_INTERNAL; - } - - sc_read_binary(card, 0, certlen, 2, 0); - - /* Now set the certificate offset/len */ - path.index = 2; - path.count = (certlen[1] << 8) + certlen[0]; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); - - sc_pkcs15_format_id("02", &cert_info.id); - - cert_info.authority = authority; - cert_info.path = path; - strlcpy(cert_obj.label, label, sizeof(cert_obj.label)); - cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; - - r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (r < 0) - return SC_ERROR_INTERNAL; - - /* Get the CA certificate length */ - - authority = 1; - - sc_format_path(infocamere_cacert_path[chn[1]-2], &path); - - r = sc_select_file(card, &path, NULL); - - if (r >= 0) { - size_t len; - - sc_read_binary(card, 0, certlen, 2, 0); - - len = (certlen[1] << 8) + certlen[0]; - - if (len != 0) { - /* Now set the certificate offset/len */ - path.index = 2; - path.count = len; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); - - sc_pkcs15_format_id("03", &cert_info.id); - cert_info.authority = authority; - cert_info.path = path; - strlcpy(cert_obj.label, calabel, sizeof(cert_obj.label)); - cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; - - r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (r < 0) - return SC_ERROR_INTERNAL; - } - } - - /* add non repudiation PIN */ - - sc_format_path(infocamere_nrepud_path[chn[1]-2], &path); - - sc_pkcs15_format_id("02", &id); - sc_pkcs15emu_add_pin(p15card, &id, - nonrepPIN, &path, infocamere_idpin_nrepud_obj[chn[1]-2], - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); - - - /* add non repudiation private key */ - - auth_id.value[0] = 2; - auth_id.len = 1; - - sc_pkcs15emu_add_prkey(p15card, &id, nonrepPRKEY, - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, prkey_usage, - &path, infocamere_idprkey_nrepud_obj[chn[1]-2], - &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - - - /* return to MF */ - sc_format_path("3F00", &path); - r = sc_select_file(card, &path, NULL); - if (r != SC_SUCCESS) - return r; - - if (change_sign) { - /* save old signature funcs */ - set_security_env = card->ops->set_security_env; - /* set new one */ - card->ops->set_security_env = set_sec_env; - card->ops->compute_signature = do_sign; - } - - return SC_SUCCESS; -} - -static int infocamere_1400_set_sec_env(struct sc_card *card, - const struct sc_security_env *env, - int se_num) -{ - int r; - - struct sc_security_env tenv = *env; - if (tenv.operation == SC_SEC_OPERATION_SIGN) - tenv.operation = SC_SEC_OPERATION_DECIPHER; - - if ((r = - card->ops->restore_security_env(card, 0x40)) == SC_SUCCESS) - return set_security_env(card, &tenv, se_num); - else - return r; -} - -#ifdef ENABLE_ZLIB - -static const u8 ATR_1400[] = -{ 0x3b, 0xfc, 0x98, 0x00, 0xff, 0xc1, 0x10, 0x31, 0xfe, 0x55, 0xc8, - 0x03, 0x49, 0x6e, 0x66, 0x6f, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x65, - 0x28 -}; - -/* Loads certificates. - * Certificates are stored in a ZLib compressed form with - * a 4 byte header, so we extract, decompress and cache - * them. - */ -static int loadCertificate(sc_pkcs15_card_t * p15card, int i, - const char *certPath, const char *certLabel) -{ - unsigned char *compCert = NULL, *cert = NULL, size[2]; - unsigned long int compLen, len; - sc_pkcs15_cert_info_t cert_info; - sc_pkcs15_object_t cert_obj; - sc_path_t cpath; - sc_card_t *card = p15card->card; - sc_pkcs15_id_t id; - int r; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); - - sc_format_path(certPath, &cpath); - - if (sc_select_file(card, &cpath, NULL) != SC_SUCCESS) - return SC_ERROR_WRONG_CARD; - - sc_read_binary(card, 2, size, 2, 0); - - compLen = (size[0] << 8) + size[1]; - compCert = malloc(compLen * sizeof(unsigned char)); - len = 4 * compLen; /*Approximation of the uncompressed size */ - cert = malloc(len * sizeof(unsigned char)); - if (!cert || !compCert) { - free(cert); - free(compCert); - return SC_ERROR_OUT_OF_MEMORY; - } - - sc_read_binary(card, 4, compCert, compLen, 0); - - if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) { - sc_log(p15card->card->ctx, "Zlib error: %d", r); - return SC_ERROR_INTERNAL; - } - - cpath.index = 0; - cpath.count = len; - - sc_pkcs15_cache_file(p15card, &cpath, cert, len); - - id.len=1; - id.value[0] = i + 1; - - cert_info.id = id; - cert_info.path = cpath; - cert_info.authority = (i == 2); - - strlcpy(cert_obj.label, certLabel, sizeof(cert_obj.label)); - cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; - - sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - - return SC_SUCCESS; -} - - -static int infocamere_1400_init(sc_pkcs15_card_t * p15card) -{ - sc_card_t *card = p15card->card; - sc_path_t path; - sc_pkcs15_id_t id, auth_id; - unsigned char serial[16]; - int flags; - int r; - int hasAuthCert = 0; - - const char *certLabel[] = { "User Non-repudiation Certificate", - "User Authentication Certificate", - "CA Certificate" - }; - - const char *certPath[] = - { "300060000000", "300060000001", "300060000002" }; - - const char *pinLabel[] = - { "Non-repudiation PIN", "Authentication PIN" }; - int retries[] = { 3, -1 }; - - const char *keyPath[] = { "30004000001", "30004000002" }; - const char *keyLabel[] = - { "Non repudiation Key", "Authentication Key" }; - static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, - SC_PKCS15_PRKEY_USAGE_SIGN - | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - | SC_PKCS15_PRKEY_USAGE_ENCRYPT - | SC_PKCS15_PRKEY_USAGE_DECRYPT - }; - - auth_id.len = 1; - id.len = 1; - - /* OpenSC doesn't define constants to identify BSOs for - * restoring security environment, so we overload - * the set_security_env function to support restore_sec_env */ - set_security_env = card->ops->set_security_env; - card->ops->set_security_env = infocamere_1400_set_sec_env; - card->ops->compute_signature = do_sign; - p15card->opts.use_file_cache = 1; - - sc_format_path("30000001", &path); - - r = sc_select_file(card, &path, NULL); - - if (r != SC_SUCCESS) - return SC_ERROR_WRONG_CARD; - - sc_read_binary(card, 15, serial, 15, 0); - serial[15] = '\0'; - - set_string(&p15card->tokeninfo->serial_number, (char *)serial); - set_string(&p15card->tokeninfo->label, "Infocamere 1400 Card"); - set_string(&p15card->tokeninfo->manufacturer_id, "Infocamere"); - - if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) != - SC_SUCCESS) { - sc_log(p15card->card->ctx, "%s", sc_strerror(r)); - return SC_ERROR_WRONG_CARD; - } - - hasAuthCert = - loadCertificate(p15card, 1, certPath[1], - certLabel[1]) == SC_SUCCESS; - loadCertificate(p15card, 2, certPath[2], certLabel[2]); - - flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | - SC_PKCS15_PIN_FLAG_INITIALIZED | - SC_PKCS15_PIN_FLAG_NEEDS_PADDING; - - /* adding PINs & private keys */ - - sc_format_path("30004000", &path); - id.value[0] = 1; - - sc_pkcs15emu_add_pin(p15card, &id, - pinLabel[0], &path, 1, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 5, 8, flags, retries[0], 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - sc_format_path(keyPath[0], &path); - auth_id.value[0] = 1; - sc_pkcs15emu_add_prkey(p15card, &id, - keyLabel[0], - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, usage[0], - &path, 1, - &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - - - if (hasAuthCert) { - sc_format_path("30004000", &path); - id.value[0] = 2; - - sc_pkcs15emu_add_pin(p15card, &id, - pinLabel[1], &path, 2, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 5, 8, flags, retries[1], 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - sc_format_path(keyPath[1], &path); - auth_id.value[0] = 2; - sc_pkcs15emu_add_prkey(p15card, &id, - keyLabel[1], - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, usage[1], - &path, 2, - &auth_id, - SC_PKCS15_CO_FLAG_PRIVATE); - } - - /* return to MF */ - sc_format_path("3F00", &path); - r = sc_select_file(card, &path, NULL); - return r; -} - -#endif - -static const u8 ATR_1600[] = { 0x3B, 0xF4, 0x98, 0x00, 0xFF, 0xC1, 0x10, - 0x31, 0xFE, 0x55, 0x4D, 0x34, 0x63, 0x76, 0xB4 -}; - -static int infocamere_1600_init(sc_pkcs15_card_t * p15card) -{ - sc_card_t *card = p15card->card; - sc_path_t path; - sc_pkcs15_id_t id, auth_id; - unsigned char serial[17]; - int flags; - int r; - int hasAuthCert = 0; - - const char *certLabel[] = { "User Non-repudiation Certificate", - "User Authentication Certificate" - }; - - const char *certPath[] = { "200020010008", "20002001000E" }; - - const char *pinLabel[] = - { "Non-repudiation PIN", "Authentication PIN" }; - int retries[] = { 3, -1 }; - - const char *keyPath[] = { "200020010004", "20002001000A" }; - const char *keyLabel[] = - { "Non repudiation Key", "Authentication Key" }; - static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, - SC_PKCS15_PRKEY_USAGE_SIGN - | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - | SC_PKCS15_PRKEY_USAGE_ENCRYPT - | SC_PKCS15_PRKEY_USAGE_DECRYPT - }; - - auth_id.len = 1; - id.len = 1; - - /* OpenSC doesn't define constants to identify BSOs for - * restoring security environment, so we overload - * the set_security_env function to support restore_sec_env */ - set_security_env = card->ops->set_security_env; - card->ops->set_security_env = infocamere_1400_set_sec_env; - card->ops->compute_signature = do_sign; - - sc_format_path("200020012002", &path); - - r = sc_select_file(card, &path, NULL); - - if (r != SC_SUCCESS) - return SC_ERROR_WRONG_CARD; - - sc_read_binary(card, 30, serial, 16, 0); - serial[16] = '\0'; - - set_string(&p15card->tokeninfo->serial_number, (char *) serial); - set_string(&p15card->tokeninfo->label, "Infocamere 1600 Card"); - set_string(&p15card->tokeninfo->manufacturer_id, "Infocamere"); - - /* Adding certificates. - * Certificates are stored in a ZLib compressed form with - * a 4 byte header, so we extract, decompress and cache - * them. - */ - sc_format_path(certPath[0], &path); - if (sc_select_file(card, &path, NULL) != SC_SUCCESS) - return SC_ERROR_WRONG_CARD; - - id.value[0] = 1; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, 0, - &path, &id, certLabel[0], - SC_PKCS15_CO_FLAG_MODIFIABLE); - - sc_format_path(certPath[1], &path); - if (sc_select_file(card, &path, NULL) == SC_SUCCESS) { - hasAuthCert = 1; - - id.value[0] = 2; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, 1, - &path, &id, certLabel[1], - SC_PKCS15_CO_FLAG_MODIFIABLE); - } - - flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | - SC_PKCS15_PIN_FLAG_INITIALIZED | - SC_PKCS15_PIN_FLAG_NEEDS_PADDING; - - /* adding PINs & private keys */ - sc_format_path("2000", &path); - id.value[0] = 1; - - sc_pkcs15emu_add_pin(p15card, &id, - pinLabel[0], &path, 1, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 5, 8, flags, retries[0], 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - sc_format_path(keyPath[0], &path); - auth_id.value[0] = 1; - sc_pkcs15emu_add_prkey(p15card, &id, - keyLabel[0], - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, usage[0], - &path, 1, - &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - - if (hasAuthCert) { - id.value[0] = 2; - - sc_pkcs15emu_add_pin(p15card, &id, - pinLabel[1], &path, 2, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 5, 8, flags, retries[1], 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - sc_format_path(keyPath[1], &path); - auth_id.value[0] = 2; - sc_pkcs15emu_add_prkey(p15card, &id, - keyLabel[1], - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, usage[1], - &path, 2, - &auth_id, - SC_PKCS15_CO_FLAG_PRIVATE); - } - - /* return to MF */ - sc_format_path("3F00", &path); - sc_select_file(card, &path, NULL); - - return SC_SUCCESS; -} - -static int infocamere_detect_card(sc_pkcs15_card_t * p15card) -{ - sc_card_t *card = p15card->card; - - /* check if we have the correct card OS */ - if (strcmp(card->name, "STARCOS") - && strcmp(card->name, "CardOS M4")) - return SC_ERROR_WRONG_CARD; - return SC_SUCCESS; -} - -int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t * opts) -{ - - if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { - if (infocamere_detect_card(p15card)) - return SC_ERROR_WRONG_CARD; - } - - if (memcmp(p15card->card->atr.value, ATR_1600, sizeof(ATR_1600)) == 0) - return infocamere_1600_init(p15card); -#ifdef ENABLE_ZLIB - else if (memcmp(p15card->card->atr.value, ATR_1400, sizeof(ATR_1400)) == - 0) - return infocamere_1400_init(p15card); -#endif - else - return infocamere_1200_init(p15card); - -} diff --git a/src/libopensc/pkcs15-postecert.c b/src/libopensc/pkcs15-postecert.c deleted file mode 100644 index 04fcfb3484..0000000000 --- a/src/libopensc/pkcs15-postecert.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * PKCS15 emulation layer for Postecert and Cnipa card. - * To see how this works, run p15dump on your Postecert or Cnipa Card. - * - * Copyright (C) 2004, Antonino Iacono - * Copyright (C) 2003, Olaf Kirch - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "common/compat_strlcpy.h" -#include "internal.h" -#include "pkcs15.h" -#include "log.h" - -int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - -static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int); - -static int set_sec_env(sc_card_t * card, const sc_security_env_t *env, - int se_num) -{ - sc_security_env_t tenv = *env; - if (tenv.operation == SC_SEC_OPERATION_SIGN) - tenv.operation = SC_SEC_OPERATION_DECIPHER; - return set_security_env(card, &tenv, se_num); -} - -static int do_sign(sc_card_t * card, const u8 * in, size_t inlen, u8 * out, - size_t outlen) -{ - return card->ops->decipher(card, in, inlen, out, outlen); -} - -static void set_string(char **strp, const char *value) -{ - if (*strp) - free(*strp); - *strp = value ? strdup(value) : NULL; -} - -#if 1 -/* XXX: temporary copy of the old pkcs15emu functions, - * to be removed */ -static int sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card, - const sc_pkcs15_id_t *id, const char *label, - const sc_path_t *path, int ref, int type, - unsigned int min_length, - unsigned int max_length, - int flags, int tries_left, const char pad_char, int obj_flags) -{ - sc_pkcs15_auth_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.auth_id = *id; - info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; - info.attrs.pin.min_length = min_length; - info.attrs.pin.max_length = max_length; - info.attrs.pin.stored_length = max_length; - info.attrs.pin.type = type; - info.attrs.pin.reference = ref; - info.attrs.pin.flags = flags; - info.attrs.pin.pad_char = pad_char; - info.tries_left = tries_left; - info.logged_in = SC_PIN_STATE_UNKNOWN; - - if (path) - info.path = *path; - if (type == SC_PKCS15_PIN_TYPE_BCD) - info.attrs.pin.stored_length /= 2; - - strlcpy(obj.label, label, sizeof(obj.label)); - obj.flags = obj_flags; - - return sc_pkcs15emu_add_pin_obj(p15card, &obj, &info); -} - -static int sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card, - const sc_pkcs15_id_t *id, - const char *label, - int type, unsigned int modulus_length, int usage, - const sc_path_t *path, int ref, - const sc_pkcs15_id_t *auth_id, int obj_flags) -{ - sc_pkcs15_prkey_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.id = *id; - info.modulus_length = modulus_length; - info.usage = usage; - info.native = 1; - info.key_reference = ref; - - if (path) - info.path = *path; - - obj.flags = obj_flags; - strlcpy(obj.label, label, sizeof(obj.label)); - if (auth_id != NULL) - obj.auth_id = *auth_id; - - return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info); -} - -static int sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card, - int type, int authority, const sc_path_t *path, - const sc_pkcs15_id_t *id, const char *label, int obj_flags) -{ - /* const char *label = "Certificate"; */ - sc_pkcs15_cert_info_t info; - sc_pkcs15_object_t obj; - - memset(&info, 0, sizeof(info)); - memset(&obj, 0, sizeof(obj)); - - info.id = *id; - info.authority = authority; - if (path) - info.path = *path; - - strlcpy(obj.label, label, sizeof(obj.label)); - obj.flags = obj_flags; - - return sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); -} -#endif - -static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card) -{ - static int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - static int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN - | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER - | SC_PKCS15_PRKEY_USAGE_ENCRYPT - | SC_PKCS15_PRKEY_USAGE_DECRYPT; - - sc_card_t *card = p15card->card; - sc_path_t path; - sc_pkcs15_id_t id, auth_id; - unsigned char certlen[2]; - unsigned char *certi = NULL; - int index_cert[4]; - int count_cert[4]; - int flags; - int authority; - size_t i, count; - int r; - int o = 0; - - const char *label = "User Non-repudiation Certificate"; - const char *calabel = "CA Certificate"; - const char *catmslabel = "CA TimeStamper Certificate"; - const char *authlabel = "User Authentication Certificate"; - - const char *postecert_auth_cert_path = "504B0001"; - - const char *authPIN = "Authentication PIN"; - const char *nonrepPIN = "Non-repudiation PIN"; - - const char *authPRKEY = "Authentication Key"; - const char *nonrepPRKEY = "Non repudiation Key"; - - memset(index_cert, 0, sizeof(index_cert)); - memset(count_cert, 0, sizeof(count_cert)); - - /* Get the non-repudiation certificate length */ - sc_format_path(postecert_auth_cert_path, &path); - - if (sc_select_file(card, &path, NULL) < 0) { - r = SC_ERROR_WRONG_CARD; - goto failed; - } - - set_string(&p15card->tokeninfo->label, "Postecert & Cnipa Card"); - set_string(&p15card->tokeninfo->manufacturer_id, "Postecert"); - set_string(&p15card->tokeninfo->serial_number, "0000"); - - sc_read_binary(card, 0, certlen, 2, 0); - - /* Now set the certificate offset/len */ - count = (certlen[0] << 8) + certlen[1]; - if (count < 256) - return SC_ERROR_INTERNAL; - - certi = malloc(count); - - if (!certi) - return SC_ERROR_OUT_OF_MEMORY; - - sc_read_binary(card, 0, certi, count - 500, 0); - - for (i = 2; i < (count - 256); i++) { - /* this file contain more than one certificate */ - if (*(certi + i) == 0x30 && *(certi + i + 1) == 0x82 - && *(certi + i + 4) == 0x30 && *(certi + i + 5) == 0x82 - && *(certi + i + 2) > 1 && *(certi + i + 2) < 8 - && *(certi + i + 6) <= *(certi + i + 2)) { - index_cert[o] = i; - count_cert[o] = - (*(certi + i + 2) << 8) + *(certi + i + 3) + 4; - o++; - if (o >= 4) - break; - i += (*(certi + i + 2) << 8) + *(certi + i + 3); - } - } - - free(certi); - - path.index = index_cert[0]; - path.count = count_cert[0]; - - id.value[0] = 1; - id.len = 1; - - authority = 1; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, authority, - &path, &id, calabel, SC_PKCS15_CO_FLAG_MODIFIABLE); - - path.index = index_cert[1]; - path.count = count_cert[1]; - - id.value[0] = 2; - id.len = 1; - - authority = 1; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, authority, - &path, &id, catmslabel, SC_PKCS15_CO_FLAG_MODIFIABLE); - - path.index = index_cert[2]; - path.count = count_cert[2]; - - id.value[0] = 3; - id.len = 1; - - authority = 0; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, authority, - &path, &id, label, SC_PKCS15_CO_FLAG_MODIFIABLE); - - path.index = index_cert[3]; - path.count = count_cert[3]; - - id.value[0] = 4; - id.len = 1; - - sc_pkcs15emu_add_cert(p15card, - SC_PKCS15_TYPE_CERT_X509, authority, - &path, &id, authlabel, SC_PKCS15_CO_FLAG_MODIFIABLE); - - - flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | - SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING; - - /* add authentication PIN */ - sc_format_path("3F00504B", &path); - id.value[0] = 1; - sc_pkcs15emu_add_pin(p15card, &id, - authPIN, &path, 0x82, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 6, 14, flags, 3, 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - /* add authentication private key */ - id.value[0] = 4; - auth_id.value[0] = 1; - auth_id.len = 1; - sc_pkcs15emu_add_prkey(p15card, &id, - authPRKEY, - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, authprkey_usage, - &path, 0x06, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - - /* add non repudiation PIN */ - sc_format_path("3F00504B", &path); - id.value[0] = 2; - sc_pkcs15emu_add_pin(p15card, &id, - nonrepPIN, &path, 0x82, - SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - 6, 14, flags, 3, 0, - SC_PKCS15_CO_FLAG_MODIFIABLE | - SC_PKCS15_CO_FLAG_PRIVATE); - - - /* add non repudiation private key */ - id.value[0] = 3; - auth_id.value[0] = 2; - sc_pkcs15emu_add_prkey(p15card, &id, - nonrepPRKEY, - SC_PKCS15_TYPE_PRKEY_RSA, - 1024, prkey_usage, - &path, 0x01, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); - - /* return to MF */ - sc_format_path("3F00", &path); - r = sc_select_file(card, &path, NULL); - if (r != SC_SUCCESS) - return r; - - { - /* save old signature funcs */ - set_security_env = card->ops->set_security_env; - /* set new one */ - card->ops->set_security_env = set_sec_env; - card->ops->compute_signature = do_sign; - } - return 0; - -failed: - sc_log(card->ctx, - "Failed to initialize Postecert and Cnipa emulation: %s\n", - sc_strerror(r)); - return r; -} - -static int postecert_detect_card(sc_pkcs15_card_t * p15card) -{ - sc_card_t *card = p15card->card; - - /* check if we have the correct card OS */ - if (strcmp(card->name, "CardOS M4")) - return SC_ERROR_WRONG_CARD; - return SC_SUCCESS; -} - -int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t * opts) -{ - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_postecert_init(p15card); - else { - int r = postecert_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_postecert_init(p15card); - } -} diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index ec79d97ed7..775ba0a59b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1625,7 +1625,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) X = BN_new(); Y = BN_new(); if (X && Y && EC_KEY_get0_group(eckey)) - r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey), + r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey), point, X, Y, NULL); if (r == 1) { dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y); diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index ab71dcdb14..3f15eeb711 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -37,12 +37,10 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "westcos", sc_pkcs15emu_westcos_init_ex }, { "openpgp", sc_pkcs15emu_openpgp_init_ex }, - { "infocamere", sc_pkcs15emu_infocamere_init_ex }, { "starcert", sc_pkcs15emu_starcert_init_ex }, { "tcos", sc_pkcs15emu_tcos_init_ex }, { "esteid", sc_pkcs15emu_esteid_init_ex }, { "itacns", sc_pkcs15emu_itacns_init_ex }, - { "postecert", sc_pkcs15emu_postecert_init_ex }, { "PIV-II", sc_pkcs15emu_piv_init_ex }, { "cac", sc_pkcs15emu_cac_init_ex }, { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex }, diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index 202711d0b0..9944d27e05 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -31,11 +31,9 @@ extern "C" { int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 09e7dca0d4..60da619e7d 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -77,6 +77,11 @@ extern "C" { #define OPENSSL_malloc_init() #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates +#define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates +#endif + /* * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures * One can no longer use statements like rsa->n = ... diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index b24db41d99..8233746d69 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -32,6 +32,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include #include /* for OPENSSL_NO_* */ +#include "libopensc/sc-ossl-compat.h" #ifndef OPENSSL_NO_EC #include #endif /* OPENSSL_NO_EC */ @@ -401,7 +402,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub ASN1_OCTET_STRING_free(octet); P = EC_POINT_new(group); if (P && X && Y) - r = EC_POINT_set_affine_coordinates_GFp(group, + r = EC_POINT_set_affine_coordinates_GFp(group, P, X, Y, NULL); BN_free(X); BN_free(Y); diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index aee4fdeb18..b95d156833 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -33,7 +33,6 @@ /* Module only built if OPENSSL is enabled */ #include -#include "libopensc/sc-ossl-compat.h" #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include #include @@ -57,6 +56,7 @@ #include "libopensc/cardctl.h" #include "libopensc/asn1.h" #include "util.h" +#include "libopensc/sc-ossl-compat.h" static const char *app_name = "piv-tool"; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8bf99a52c5..fe1667d569 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -36,7 +36,6 @@ #ifdef ENABLE_OPENSSL #include -#include "libopensc/sc-ossl-compat.h" #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include #include @@ -62,6 +61,7 @@ #include "common/compat_strlcat.h" #include "common/compat_strlcpy.h" #include "util.h" +#include "libopensc/sc-ossl-compat.h" #ifdef _WIN32 #ifndef STDOUT_FILENO diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 18ac1ff603..b6759e5706 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -79,7 +79,7 @@ CANDLEFLAGS = -dOpenSSL="$(OPENSSL_DIR)" $(CANDLEFLAGS) !ENDIF -# If you want support for zlib (Used for PIV, infocamere and actalis): +# If you want support for zlib (Used for PIV and actalis): # - Download zlib-dll and # - uncomment the line starting with ZLIB_DEF # - set the ZLIB_INCL_DIR below to the zlib include lib proceeded by "/I" From ec176443e2b4fa14461ab71ef7ed130a8b7e6e5a Mon Sep 17 00:00:00 2001 From: Hannu Honkanen Date: Wed, 23 Jan 2019 13:34:49 +0200 Subject: [PATCH 0750/4321] Fixes an issue that appeared in 6bf9685 (PR #1540). In case use_pinpad==0 && pinsize == 0, uninitialized pinbuf was passed to sc_pkcs15_verify_pin causing problems. --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index cd46fd6604..6b4c72ed33 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3801,7 +3801,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p found: if (pin_obj) { - r = sc_pkcs15_verify_pin(p15card, pin_obj, use_pinpad ? NULL : pinbuf, use_pinpad ? 0 : pinsize); + r = sc_pkcs15_verify_pin(p15card, pin_obj, use_pinpad || pinsize == 0 ? NULL : pinbuf, use_pinpad ? 0 : pinsize); LOG_TEST_RET(ctx, r, "Cannot validate pkcs15 PIN"); } From 36c5461c997619a3ded9bd6c6cfda2c7983dff0d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:37:20 +0200 Subject: [PATCH 0751/4321] Make function more readable Signed-off-by: Raul Metsma --- src/libopensc/pkcs15-esteid.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index b47343d97c..b3c58b6888 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -37,8 +37,6 @@ #include "pkcs15.h" #include "esteid.h" -int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static void set_string (char **strp, const char *value) { @@ -240,25 +238,13 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) return SC_SUCCESS; } -static int esteid_detect_card(sc_pkcs15_card_t *p15card) -{ - if (is_esteid_card(p15card->card)) - return SC_SUCCESS; - else - return SC_ERROR_WRONG_CARD; -} - int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) return sc_pkcs15emu_esteid_init(p15card); - else { - int r = esteid_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; + if (p15card->card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) return sc_pkcs15emu_esteid_init(p15card); - } + return SC_ERROR_WRONG_CARD; } From 3dd0638623dd53389d8fa5d443bdeb824bbadd11 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 Jan 2019 10:29:13 +0100 Subject: [PATCH 0752/4321] initialize package suffix with branch and PR --- .travis.yml | 13 ++++++++++++- appveyor.yml | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1f36a8c9f..8a3f665a62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,7 +60,18 @@ before_install: fi before_script: - - ./bootstrap + - if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then + ./bootstrap; + fi + - if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then + ./bootstrap.ci -s "-pr$TRAVIS_PULL_REQUEST"; + fi + - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then + ./bootstrap.ci -s "-$TRAVIS_BRANCH"; + fi + - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then + ./bootstrap.ci -s "-$TRAVIS_BRANCH-pr$TRAVIS_PULL_REQUEST"; + fi - if [ -z "$HOST" ]; then CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui; else diff --git a/appveyor.yml b/appveyor.yml index e8b3df9a0a..8967e71950 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -87,7 +87,10 @@ build_script: } $env:NMAKE_EXTRA="OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=C:\openpace-${env:OPENSSL_PF} ${env:NMAKE_EXTRA}" } - - bash -c "exec 0 Date: Fri, 1 Feb 2019 09:10:02 +0100 Subject: [PATCH 0753/4321] Bug fix in verify_signature() when the buffer to verify is larger than 1025 bytes. In this case, the signature length given to C_VerifyFinal() was incorrect. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 561da14910..ceb6ea150e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1985,7 +1985,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, r = read(fd, in_buffer, sizeof(in_buffer)); } while (r > 0); - sig_len = sizeof(sig_buffer); + sig_len = r2; rv = p11->C_VerifyFinal(session, sig_buffer, sig_len); if (rv != CKR_OK) p11_fatal("C_VerifyFinal", rv); From ff3448fb18c007dae05c9ef543de29a311251b43 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 09:13:21 +0100 Subject: [PATCH 0754/4321] Fix build when OPENSSL_NO_RIPEMD and OPENSSL_NO_CAST are defined. --- src/tools/pkcs11-tool.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ceb6ea150e..f3432269ed 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4567,7 +4567,9 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, EVP_sha1(), EVP_sha1(), EVP_md5(), +#ifndef OPENSSL_NO_RIPEMD EVP_ripemd160(), +#endif EVP_sha256(), }; #endif @@ -4650,7 +4652,9 @@ static int test_signature(CK_SESSION_HANDLE sess) CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_MD5_RSA_PKCS, + #ifndef OPENSSL_NO_RIPEMD CKM_RIPEMD160_RSA_PKCS, + #endif CKM_SHA256_RSA_PKCS, 0xffffff }; @@ -5231,7 +5235,9 @@ static int test_unwrap(CK_SESSION_HANDLE sess) errors += wrap_unwrap(sess, EVP_des_cbc(), privKeyObject); errors += wrap_unwrap(sess, EVP_des_ede3_cbc(), privKeyObject); errors += wrap_unwrap(sess, EVP_bf_cbc(), privKeyObject); + #ifndef OPENSSL_NO_CAST errors += wrap_unwrap(sess, EVP_cast5_cfb(), privKeyObject); + #endif #endif } From 968bfa84445c74078a784931aa12efa9711de293 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 09:16:59 +0100 Subject: [PATCH 0755/4321] Add support for CKM_RSA_PKCS_OAEP in encrypt_decrypt(). --- src/tools/pkcs11-tool.c | 102 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f3432269ed..6dcad1a6d8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5256,6 +5256,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_ULONG encrypted_len, data_len; int failed; CK_RV rv; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); @@ -5268,13 +5269,104 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, EVP_PKEY_free(pkey); return 0; } - encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); - EVP_PKEY_free(pkey); - if (((int) encrypted_len) <= 0) { - printf("Encryption failed, returning\n"); - return 0; + if (mech_type == CKM_RSA_PKCS_OAEP) { + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) { + EVP_PKEY_free(pkey); + printf("EVP_PKEY_CTX_new failed, returning\n"); + return 0; + } + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("EVP_PKEY_encrypt_init failed, returning\n"); + return 0; + } + + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("set OAEP padding failed, returning\n"); + return 0; + } + size_t outlen = sizeof(encrypted); + if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, orig_data, sizeof(orig_data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("Encryption failed, returning\n"); + return 0; + } + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + encrypted_len = outlen; + + } else { + encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); + EVP_PKEY_free(pkey); + if (((int) encrypted_len) <= 0) { + printf("Encryption failed, returning\n"); + return 0; + } + } + + /* set "default" MGF and hash algorithms. We can overwrite MGF later */ + switch (mech_type) { + case CKM_RSA_PKCS_OAEP: + oaep_params.hashAlg = opt_hash_alg; + switch (opt_hash_alg) { + case CKM_SHA224: + oaep_params.mgf = CKG_MGF1_SHA224; + break; + case CKM_SHA256: + oaep_params.mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + oaep_params.mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + oaep_params.mgf = CKG_MGF1_SHA512; + break; + default: + oaep_params.hashAlg = CKM_SHA_1; + /* fall through */ + case CKM_SHA_1: + oaep_params.mgf = CKG_MGF1_SHA1; + break; + } + break; + case CKM_RSA_PKCS: + mech.pParameter = NULL; + mech.ulParameterLen = 0; + break; + default: + util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); + } + + + /* If an RSA-OAEP mechanism, it needs parameters */ + if (oaep_params.hashAlg) { + if (opt_mgf != 0) + oaep_params.mgf = opt_mgf; + + /* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */ + oaep_params.source = 0UL; /* empty encoding parameter (label) */ + oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ + oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ + + mech.pParameter = &oaep_params; + mech.ulParameterLen = sizeof(oaep_params); + + fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", + p11_mechanism_to_name(oaep_params.hashAlg), + p11_mgf_to_name(oaep_params.mgf), + oaep_params.source, + oaep_params.pSourceData, + oaep_params.ulSourceDataLen); + } + mech.mechanism = mech_type; rv = p11->C_DecryptInit(session, &mech, privKeyObject); if (rv == CKR_MECHANISM_INVALID || rv == CKR_MECHANISM_PARAM_INVALID) { From 16ca73ae4008656ff2d7ee079eb39304e15fb776 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 11:19:33 +0100 Subject: [PATCH 0756/4321] Add support for CKM_RSA_PKCS_OAEP in encrypt_decrypt(). fix mechanism value in call to util_fatal(). --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6dcad1a6d8..374ecf7ec0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5340,7 +5340,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, mech.ulParameterLen = 0; break; default: - util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); + util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(mech_type)); } From 2be799f739c20f4ff276834b91a50f32fe314718 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 11:35:25 +0100 Subject: [PATCH 0757/4321] Add support for CKM_RSA_PKCS_OAEP in encrypt_decrypt(). fix mechanism value in call to util_fatal(). fix formatting. --- src/tools/pkcs11-tool.c | 85 +++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 374ecf7ec0..74416561cb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1782,7 +1782,7 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, util_fatal("Salt length must be greater or equal " "to zero, or equal to -1 (meaning: use digest size) " "or to -2 (meaning: use maximum permissible size"); - + modlen = (get_private_key_length(session, key) + 7) / 8; switch (opt_salt_len) { case -1: /* salt size equals to digest size */ @@ -2024,7 +2024,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) util_fatal("The hash-algorithm is applicable only to " - "RSA-PKCS-OAEP mechanism"); + "RSA-PKCS-OAEP mechanism"); if (opt_input == NULL) fd = 0; @@ -2053,7 +2053,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, case CKM_SHA512: oaep_params.mgf = CKG_MGF1_SHA512; break; - default: + default: oaep_params.hashAlg = CKM_SHA_1; /* fall through */ case CKM_SHA_1: @@ -2090,7 +2090,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, oaep_params.pSourceData, oaep_params.ulSourceDataLen); - } + } rv = p11->C_DecryptInit(session, &mech, key); if (rv != CKR_OK) @@ -5270,45 +5270,45 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } if (mech_type == CKM_RSA_PKCS_OAEP) { - EVP_PKEY_CTX *ctx; - ctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ctx) { - EVP_PKEY_free(pkey); - printf("EVP_PKEY_CTX_new failed, returning\n"); - return 0; - } - if (EVP_PKEY_encrypt_init(ctx) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("EVP_PKEY_encrypt_init failed, returning\n"); - return 0; - } - - if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("set OAEP padding failed, returning\n"); - return 0; - } - size_t outlen = sizeof(encrypted); - if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, orig_data, sizeof(orig_data)) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("Encryption failed, returning\n"); - return 0; - } - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - encrypted_len = outlen; + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) { + EVP_PKEY_free(pkey); + printf("EVP_PKEY_CTX_new failed, returning\n"); + return 0; + } + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("EVP_PKEY_encrypt_init failed, returning\n"); + return 0; + } - } else { - encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); - EVP_PKEY_free(pkey); - if (((int) encrypted_len) <= 0) { - printf("Encryption failed, returning\n"); - return 0; - } - } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("set OAEP padding failed, returning\n"); + return 0; + } + size_t outlen = sizeof(encrypted); + if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, orig_data, sizeof(orig_data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("Encryption failed, returning\n"); + return 0; + } + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + encrypted_len = outlen; + + } else { + encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); + EVP_PKEY_free(pkey); + if (((int) encrypted_len) <= 0) { + printf("Encryption failed, returning\n"); + return 0; + } + } /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (mech_type) { @@ -5461,6 +5461,7 @@ static int test_decrypt(CK_SESSION_HANDLE sess) printf("No OpenSSL support, unable to validate decryption\n"); #else for (n = 0; n < num_mechs; n++) { + errors += encrypt_decrypt(sess, mechs[n], privKeyObject); } #endif From cf617da4bda4d37ede78651662010d472c244ab0 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 11:37:47 +0100 Subject: [PATCH 0758/4321] Before calling encrypt_decrypt() make sure that the mechanism is for RSA and supports decryption, otherwise skip it. --- src/tools/pkcs11-tool.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 74416561cb..2f4497f341 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5461,6 +5461,17 @@ static int test_decrypt(CK_SESSION_HANDLE sess) printf("No OpenSSL support, unable to validate decryption\n"); #else for (n = 0; n < num_mechs; n++) { + switch (mechs[n]) { + case CKM_RSA_PKCS: + case CKM_RSA_PKCS_OAEP: + case CKM_RSA_X_509: + //case CKM_RSA_PKCS_TPM_1_1: + //case CKM_RSA_PKCS_OAEP_TPM_1_1: + break; + default: + printf(" -- mechanism can't be used to decrypt, skipping\n"); + continue; + } errors += encrypt_decrypt(sess, mechs[n], privKeyObject); } From 9b7605ff3ceb6e799e106ff718465626e739486f Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 1 Feb 2019 15:27:55 +0100 Subject: [PATCH 0759/4321] Add support for CKM_RSA_PKCS_OAEP in encrypt_decrypt(). Only set the OAEP params for CKM_RSA_PKCS_OAEP, I had an issue with a variable not initialized. --- src/tools/pkcs11-tool.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2f4497f341..aa986ff4a5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5334,18 +5334,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, oaep_params.mgf = CKG_MGF1_SHA1; break; } - break; - case CKM_RSA_PKCS: - mech.pParameter = NULL; - mech.ulParameterLen = 0; - break; - default: - util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(mech_type)); - } - - - /* If an RSA-OAEP mechanism, it needs parameters */ - if (oaep_params.hashAlg) { if (opt_mgf != 0) oaep_params.mgf = opt_mgf; @@ -5354,6 +5342,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ + /* If an RSA-OAEP mechanism, it needs parameters */ mech.pParameter = &oaep_params; mech.ulParameterLen = sizeof(oaep_params); @@ -5363,10 +5352,15 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, oaep_params.source, oaep_params.pSourceData, oaep_params.ulSourceDataLen); - + break; + case CKM_RSA_PKCS: + mech.pParameter = NULL; + mech.ulParameterLen = 0; + break; + default: + util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(mech_type)); } - mech.mechanism = mech_type; rv = p11->C_DecryptInit(session, &mech, privKeyObject); if (rv == CKR_MECHANISM_INVALID || rv == CKR_MECHANISM_PARAM_INVALID) { From f030aa2c25943472fa66f601286487c2a8c98b10 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 4 Feb 2019 14:23:13 +0100 Subject: [PATCH 0760/4321] Add support for CKM_RSA_X_509 in encrypt_decrypt() and decrypt_data(). --- src/tools/pkcs11-tool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index aa986ff4a5..7dc8c8a856 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2061,6 +2061,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; } break; + case CKM_RSA_X_509: case CKM_RSA_PKCS: mech.pParameter = NULL; mech.ulParameterLen = 0; @@ -5353,6 +5354,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, oaep_params.pSourceData, oaep_params.ulSourceDataLen); break; + case CKM_RSA_X_509: case CKM_RSA_PKCS: mech.pParameter = NULL; mech.ulParameterLen = 0; From 3d09823df0029a35f9f3259a5f9a401dcbf26ee3 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 4 Feb 2019 14:26:02 +0100 Subject: [PATCH 0761/4321] Fix build when OPENSSL_NO_RIPEMD and OPENSSL_NO_CAST are defined. Fix formatting. --- src/tools/pkcs11-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7dc8c8a856..29d33b7b20 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4653,9 +4653,9 @@ static int test_signature(CK_SESSION_HANDLE sess) CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_MD5_RSA_PKCS, - #ifndef OPENSSL_NO_RIPEMD +#ifndef OPENSSL_NO_RIPEMD CKM_RIPEMD160_RSA_PKCS, - #endif +#endif CKM_SHA256_RSA_PKCS, 0xffffff }; @@ -5236,9 +5236,9 @@ static int test_unwrap(CK_SESSION_HANDLE sess) errors += wrap_unwrap(sess, EVP_des_cbc(), privKeyObject); errors += wrap_unwrap(sess, EVP_des_ede3_cbc(), privKeyObject); errors += wrap_unwrap(sess, EVP_bf_cbc(), privKeyObject); - #ifndef OPENSSL_NO_CAST +#ifndef OPENSSL_NO_CAST errors += wrap_unwrap(sess, EVP_cast5_cfb(), privKeyObject); - #endif +#endif #endif } From 928fbf2f030f10df48c0fec7ade0c2391aa9036d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 4 Feb 2019 16:00:45 +0100 Subject: [PATCH 0762/4321] goid-tool: implented PIN/FP verification for PAccess --- src/tools/goid-tool-cmdline.c | 17 +++++------ src/tools/goid-tool.c | 53 ++++++++++++++++++++++++++++++++++- src/tools/goid-tool.ggo.in | 16 +++++------ 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index 012af87620..c191234d43 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -37,11 +37,11 @@ const char *gengetopt_args_info_help[] = { " -V, --version Print version and exit", " -r, --reader=STRING Number of the reader to use. By default, the\n first reader with a present card is used. If\n the arguement is an ATR, the reader with a\n matching card will be chosen.", " -v, --verbose Use (several times) to be more verbose", - "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", - "\n Mode: soc\n Options for SoCManager Applet", " -p, --verify-pin Verify PIN", " -b, --verify-bio Verify finger print", " --verify-pin-or-bio Verify PIN or finger print (user's choice)", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", + "\n Mode: soc\n Options for SoCManager Applet", " --new-pin Change PIN", " --new-bio Use (several times) to change one or more\n biometric templates", " --info Dump Information about the SoCManager's\n configuration", @@ -173,9 +173,9 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->verbose_help = gengetopt_args_info_help[3] ; args_info->verbose_min = 0; args_info->verbose_max = 0; - args_info->verify_pin_help = gengetopt_args_info_help[6] ; - args_info->verify_bio_help = gengetopt_args_info_help[7] ; - args_info->verify_pin_or_bio_help = gengetopt_args_info_help[8] ; + args_info->verify_pin_help = gengetopt_args_info_help[4] ; + args_info->verify_bio_help = gengetopt_args_info_help[5] ; + args_info->verify_pin_or_bio_help = gengetopt_args_info_help[6] ; args_info->new_pin_help = gengetopt_args_info_help[9] ; args_info->new_bio_help = gengetopt_args_info_help[10] ; args_info->new_bio_min = 0; @@ -1832,7 +1832,6 @@ cmdline_parser_internal ( break; case 'p': /* Verify PIN. */ - args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1845,7 +1844,6 @@ cmdline_parser_internal ( break; case 'b': /* Verify finger print. */ - args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -1885,7 +1883,6 @@ cmdline_parser_internal ( /* Verify PIN or finger print (user's choice). */ if (strcmp (long_options[option_index].name, "verify-pin-or-bio") == 0) { - args_info->soc_mode_counter += 1; if (update_arg( 0 , @@ -2212,8 +2209,8 @@ cmdline_parser_internal ( if (args_info->pxs_mode_counter && args_info->soc_mode_counter) { int pxs_given[] = {args_info->certificate_given, args_info->key_given, args_info->print_cardid_given, args_info->write_cardid_given, args_info->print_paccessid_given, args_info->write_paccessid_given, args_info->read_dg_given, args_info->out_file_given, args_info->write_dg_given, args_info->in_file_given, args_info->delete_dg_given, args_info->create_dg_given, args_info->new_size_given, args_info->new_read_ac_given, args_info->new_read_ac_chatbit_given, args_info->new_write_ac_given, args_info->new_write_ac_chatbit_given, -1}; const char *pxs_desc[] = {"--certificate", "--key", "--print-cardid", "--write-cardid", "--print-paccessid", "--write-paccessid", "--read-dg", "--out-file", "--write-dg", "--in-file", "--delete-dg", "--create-dg", "--new-size", "--new-read-ac", "--new-read-ac-chatbit", "--new-write-ac", "--new-write-ac-chatbit", 0}; - int soc_given[] = {args_info->verify_pin_given, args_info->verify_bio_given, args_info->verify_pin_or_bio_given, args_info->new_pin_given, args_info->new_bio_given, args_info->info_given, -1}; - const char *soc_desc[] = {"--verify-pin", "--verify-bio", "--verify-pin-or-bio", "--new-pin", "--new-bio", "--info", 0}; + int soc_given[] = {args_info->new_pin_given, args_info->new_bio_given, args_info->info_given, -1}; + const char *soc_desc[] = {"--new-pin", "--new-bio", "--info", 0}; error_occurred += check_modes(pxs_given, pxs_desc, soc_given, soc_desc); } diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index c2d019820c..815ff86958 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -340,7 +340,7 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info } if (cmdline->verify_pin_given) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, - "Verify finger print or PIN on the card."); + "Verify PIN on the card."); if (!soc_verify(card, SOCM_AUTHOBJECT_PIN)) goto err; soc_reset_authobject |= SOCM_AUTHOBJECT_PIN; @@ -493,6 +493,26 @@ paccess_get_security_attributes(struct sc_context *ctx, const char *ac, int* cha return ok; } +#define PXS_AUTHOBJECT_PIN 0x80 +#define PXS_AUTHOBJECT_BIO 0x40 + +int +paccess_verify(sc_card_t *card, unsigned char p2) +{ + int ok = 0; + sc_apdu_t apdu; + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x24, p2); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_transmit_apdu(card, &apdu), + "Verification failed"); + SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + sc_check_sw(card, apdu.sw1, apdu.sw2), + "Verification failed"); + ok = 1; +err: + return ok; +} + int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info *cmdline) { int ok = 0, r; @@ -504,6 +524,7 @@ int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_ unsigned char auxiliary_data[] = {0x67, 0x00}; unsigned char paccess_minor = 0; unsigned char paccess_major = 0; + int pxs_reset_authobjects = 0; sc_path_set(&path, SC_PATH_TYPE_DF_NAME, paccess_aid, sizeof paccess_aid, 0, 0); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, @@ -600,6 +621,28 @@ int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_ "Chip authentication failed."); } + if (cmdline->verify_pin_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify PIN on the card."); + if (!paccess_verify(card, PXS_AUTHOBJECT_PIN)) + goto err; + pxs_reset_authobjects++; + } + if (cmdline->verify_bio_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify finger print on the card."); + if (!paccess_verify(card, PXS_AUTHOBJECT_BIO)) + goto err; + pxs_reset_authobjects++; + } + if (cmdline->verify_pin_or_bio_given) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Verify finger print or PIN on the card."); + if (!paccess_verify(card, PXS_AUTHOBJECT_PIN|PXS_AUTHOBJECT_BIO)) + goto err; + pxs_reset_authobjects++; + } + for (i = 0; i < cmdline->delete_dg_given; i++) { int fid = 0x0100 | cmdline->delete_dg_arg[i]; @@ -791,6 +834,8 @@ int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_ ok = 1; err: + if (pxs_reset_authobjects) + sc_reset(card, 0); if (certs) { for (i = 0; certs[i]; i++) { free((unsigned char *) certs[i]); @@ -844,6 +889,12 @@ main(int argc, char **argv) goto err; if (cmdline.pxs_mode_counter && !paccess_main(ctx, card, &cmdline)) goto err; + if (cmdline.soc_mode_counter == 0 && cmdline.pxs_mode_counter == 0 + && (cmdline.verify_pin_given + || cmdline.verify_bio_given + || cmdline.verify_pin_or_bio_given) + && !soc_main(ctx, card, &cmdline)) + goto err; fail = 0; diff --git a/src/tools/goid-tool.ggo.in b/src/tools/goid-tool.ggo.in index b646166348..3034e56cc0 100644 --- a/src/tools/goid-tool.ggo.in +++ b/src/tools/goid-tool.ggo.in @@ -7,17 +7,17 @@ option "reader" r option "verbose" v "Use (several times) to be more verbose" multiple optional - -defmode "soc" modedesc="Options for SoCManager Applet" -modeoption "verify-pin" p +option "verify-pin" p "Verify PIN" - mode="soc" optional -modeoption "verify-bio" b + optional +option "verify-bio" b "Verify finger print" - mode="soc" optional -modeoption "verify-pin-or-bio" - + optional +option "verify-pin-or-bio" - "Verify PIN or finger print (user's choice)" - mode="soc" optional + optional + +defmode "soc" modedesc="Options for SoCManager Applet" modeoption "new-pin" - "Change PIN" mode="soc" optional From d25fbe3cecc55857541ad773899235e227409c47 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 5 Feb 2019 11:24:33 +0100 Subject: [PATCH 0763/4321] Remove 2 useless comments in encrypt_decrypt(). --- src/tools/pkcs11-tool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 29d33b7b20..4156df20fa 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5461,8 +5461,6 @@ static int test_decrypt(CK_SESSION_HANDLE sess) case CKM_RSA_PKCS: case CKM_RSA_PKCS_OAEP: case CKM_RSA_X_509: - //case CKM_RSA_PKCS_TPM_1_1: - //case CKM_RSA_PKCS_OAEP_TPM_1_1: break; default: printf(" -- mechanism can't be used to decrypt, skipping\n"); From 9aa413bd7e9ad7298a30d517c0446308393ea9b1 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 5 Feb 2019 11:35:42 +0100 Subject: [PATCH 0764/4321] Fix CKM_RSA_X_509 encrypt_decrypt(). Improve the code for CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP. For these alogs, only CKM_SHA_1 is supported. --- src/tools/pkcs11-tool.c | 110 +++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4156df20fa..3bfcb23965 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5251,16 +5251,29 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject) { EVP_PKEY *pkey; - unsigned char orig_data[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'}; + unsigned char orig_data[512] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'}; unsigned char encrypted[512], data[512]; CK_MECHANISM mech; CK_ULONG encrypted_len, data_len; int failed; CK_RV rv; + int pad; + CK_MECHANISM_TYPE hash_alg = CKM_SHA_1; CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); + if ((mech_type == CKM_RSA_PKCS) || (mech_type == CKM_RSA_PKCS_OAEP)) { + if (opt_hash_alg == 0) { + hash_alg = CKM_SHA_1; + } else if (opt_hash_alg != CKM_SHA_1) { + printf("Only CKM_SHA_1 supported\n"); + return 0; + } else { + hash_alg = opt_hash_alg; + } + } + pkey = get_public_key(session, privKeyObject); if (pkey == NULL) return 0; @@ -5270,52 +5283,71 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, EVP_PKEY_free(pkey); return 0; } - if (mech_type == CKM_RSA_PKCS_OAEP) { - EVP_PKEY_CTX *ctx; - ctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ctx) { - EVP_PKEY_free(pkey); - printf("EVP_PKEY_CTX_new failed, returning\n"); - return 0; - } - if (EVP_PKEY_encrypt_init(ctx) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("EVP_PKEY_encrypt_init failed, returning\n"); + size_t in_len; + CK_ULONG mod_len = (get_private_key_length(session, privKeyObject) + 7) / 8; + switch (mech_type) { + case CKM_RSA_PKCS: + pad = RSA_PKCS1_PADDING; + /* Limit the input length to <= mod_len-11 */ + in_len = mod_len-11; + break; + case CKM_RSA_PKCS_OAEP: { + pad = RSA_PKCS1_OAEP_PADDING; + /* Limit the input length to <= mod_len-2-2*hlen */ + size_t len = 2+2*hash_length(hash_alg); + if (len >= mod_len) { + printf("Incompatible mechanism and key size\n"); return 0; } + in_len = mod_len-len; + break; + } + case CKM_RSA_X_509: + pad = RSA_NO_PADDING; + /* Limit the input length to the modulus length */ + in_len = mod_len; + break; + default: + printf("Unsupported mechanism, returning\n"); + return 0; + } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("set OAEP padding failed, returning\n"); - return 0; - } - size_t outlen = sizeof(encrypted); - if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, orig_data, sizeof(orig_data)) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); - printf("Encryption failed, returning\n"); - return 0; - } + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) { + EVP_PKEY_free(pkey); + printf("EVP_PKEY_CTX_new failed, returning\n"); + return 0; + } + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("EVP_PKEY_encrypt_init failed, returning\n"); + return 0; + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, pad) <= 0) { EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); - encrypted_len = outlen; + printf("set OAEP padding failed, returning\n"); + return 0; + } - } else { - encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey); + size_t out_len = sizeof(encrypted); + if (EVP_PKEY_encrypt(ctx, encrypted, &out_len, orig_data, in_len) <= 0) { + EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); - if (((int) encrypted_len) <= 0) { - printf("Encryption failed, returning\n"); - return 0; - } + printf("Encryption failed, returning\n"); + return 0; } + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + encrypted_len = out_len; /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (mech_type) { case CKM_RSA_PKCS_OAEP: - oaep_params.hashAlg = opt_hash_alg; - switch (opt_hash_alg) { + oaep_params.hashAlg = hash_alg; + switch (oaep_params.hashAlg) { case CKM_SHA224: oaep_params.mgf = CKG_MGF1_SHA224; break; @@ -5379,18 +5411,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, if (rv != CKR_OK) p11_fatal("C_Decrypt", rv); - if (mech_type == CKM_RSA_X_509) - failed = (data[0] != 0) || (data[1] != 2) || (data_len <= sizeof(orig_data) - 2) || - memcmp(orig_data, data + data_len - sizeof(orig_data), sizeof(orig_data)); - else - failed = data_len != sizeof(orig_data) || memcmp(orig_data, data, data_len); + failed = data_len != in_len || memcmp(orig_data, data, data_len); if (failed) { CK_ULONG n; printf("resulting cleartext doesn't match input\n"); printf(" Original:"); - for (n = 0; n < sizeof(orig_data); n++) + for (n = 0; n < in_len; n++) printf(" %02x", orig_data[n]); printf("\n"); printf(" Decrypted:"); From 084624f340afd66c985a2dafc8eaf93461946724 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 5 Feb 2019 12:03:51 +0100 Subject: [PATCH 0765/4321] Fix CKM_RSA_PKCS in encrypt_decrypt(). --- src/tools/pkcs11-tool.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 3bfcb23965..7b8f91e244 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5258,22 +5258,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, int failed; CK_RV rv; int pad; - CK_MECHANISM_TYPE hash_alg = CKM_SHA_1; + CK_MECHANISM_TYPE hash_alg; CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); - if ((mech_type == CKM_RSA_PKCS) || (mech_type == CKM_RSA_PKCS_OAEP)) { - if (opt_hash_alg == 0) { - hash_alg = CKM_SHA_1; - } else if (opt_hash_alg != CKM_SHA_1) { - printf("Only CKM_SHA_1 supported\n"); - return 0; - } else { - hash_alg = opt_hash_alg; - } - } - pkey = get_public_key(session, privKeyObject); if (pkey == NULL) return 0; @@ -5292,6 +5281,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, in_len = mod_len-11; break; case CKM_RSA_PKCS_OAEP: { + if (opt_hash_alg == 0) { + hash_alg = CKM_SHA_1; + } else if (opt_hash_alg != CKM_SHA_1) { + printf("Only CKM_RSA_PKCS_OAEP with CKM_SHA_1 supported\n"); + return 0; + } else { + hash_alg = opt_hash_alg; + } pad = RSA_PKCS1_OAEP_PADDING; /* Limit the input length to <= mod_len-2-2*hlen */ size_t len = 2+2*hash_length(hash_alg); From 973625773b6bef1750db94712339381a534beeae Mon Sep 17 00:00:00 2001 From: alegon01 Date: Thu, 7 Feb 2019 10:42:48 +0100 Subject: [PATCH 0766/4321] Fix encrypt_decrypt() for CKM_RSA_PKCS_OAEP. It is working fine now with OpenSsl 1.1.1a. --- src/tools/pkcs11-tool.c | 118 +++++++++++++++++++++++++++++----------- 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7b8f91e244..e1f5656b60 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5258,7 +5258,8 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, int failed; CK_RV rv; int pad; - CK_MECHANISM_TYPE hash_alg; + CK_MECHANISM_TYPE hash_alg = CKM_SHA256; + CK_RSA_PKCS_MGF_TYPE mgf; CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); @@ -5281,14 +5282,35 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, in_len = mod_len-11; break; case CKM_RSA_PKCS_OAEP: { - if (opt_hash_alg == 0) { - hash_alg = CKM_SHA_1; - } else if (opt_hash_alg != CKM_SHA_1) { - printf("Only CKM_RSA_PKCS_OAEP with CKM_SHA_1 supported\n"); - return 0; - } else { + if (opt_hash_alg != 0) { hash_alg = opt_hash_alg; } + switch (hash_alg) { + case CKM_SHA_1: + mgf = CKG_MGF1_SHA1; + break; + case CKM_SHA224: + mgf = CKG_MGF1_SHA224; + break; + default: + printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(hash_alg)); + /* fall through */ + case CKM_SHA256: + mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + mgf = CKG_MGF1_SHA512; + break; + } + if (opt_mgf != 0) { + mgf = opt_mgf; + } else { + printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(mgf)); + } + pad = RSA_PKCS1_OAEP_PADDING; /* Limit the input length to <= mod_len-2-2*hlen */ size_t len = 2+2*hash_length(hash_alg); @@ -5305,7 +5327,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, in_len = mod_len; break; default: - printf("Unsupported mechanism, returning\n"); + printf("Unsupported mechanism %s, returning\n", p11_mechanism_to_name(mech_type)); return 0; } @@ -5325,9 +5347,64 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, if (EVP_PKEY_CTX_set_rsa_padding(ctx, pad) <= 0) { EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); - printf("set OAEP padding failed, returning\n"); + printf("set padding failed, returning\n"); return 0; } + if (mech_type == CKM_RSA_PKCS_OAEP) { + const EVP_MD *md; + switch (hash_alg) { + case CKM_SHA_1: + md = EVP_sha1(); + break; + case CKM_SHA224: + md = EVP_sha224(); + break; + default: /* it should not happen, hash_alg is checked earlier */ + /* fall through */ + case CKM_SHA256: + md = EVP_sha256(); + break; + case CKM_SHA384: + md = EVP_sha384(); + break; + case CKM_SHA512: + md = EVP_sha512(); + break; + } + if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("set md failed, returning\n"); + return 0; + } + switch (mgf) { + case CKG_MGF1_SHA1: + md = EVP_sha1(); + break; + case CKG_MGF1_SHA224: + md = EVP_sha224(); + break; + default: + printf("mgf %s unknown, defaulting to CKG_MGF1_SHA256\n", p11_mgf_to_name(mgf)); + mgf = CKG_MGF1_SHA256; + /* fall through */ + case CKG_MGF1_SHA256: + md = EVP_sha256(); + break; + case CKG_MGF1_SHA384: + md = EVP_sha384(); + break; + case CKG_MGF1_SHA512: + md = EVP_sha512(); + break; + } + if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("set mgf1 md failed, returning\n"); + return 0; + } + } size_t out_len = sizeof(encrypted); if (EVP_PKEY_encrypt(ctx, encrypted, &out_len, orig_data, in_len) <= 0) { @@ -5344,28 +5421,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, switch (mech_type) { case CKM_RSA_PKCS_OAEP: oaep_params.hashAlg = hash_alg; - switch (oaep_params.hashAlg) { - case CKM_SHA224: - oaep_params.mgf = CKG_MGF1_SHA224; - break; - case CKM_SHA256: - oaep_params.mgf = CKG_MGF1_SHA256; - break; - case CKM_SHA384: - oaep_params.mgf = CKG_MGF1_SHA384; - break; - case CKM_SHA512: - oaep_params.mgf = CKG_MGF1_SHA512; - break; - default: - oaep_params.hashAlg = CKM_SHA_1; - /* fall through */ - case CKM_SHA_1: - oaep_params.mgf = CKG_MGF1_SHA1; - break; - } - if (opt_mgf != 0) - oaep_params.mgf = opt_mgf; + oaep_params.mgf = mgf; /* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */ oaep_params.source = 0UL; /* empty encoding parameter (label) */ From aca9d79f6da79c78f4df578a49481634aa4f2cfc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 7 Feb 2019 16:40:00 +0100 Subject: [PATCH 0767/4321] fixed parsing SoCManager info --- src/tools/goid-tool.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 815ff86958..fc7a320c64 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -317,17 +317,13 @@ int soc_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_info if (file && file->prop_attr && file->prop_attr_len) { size_t prop_len = 0; const u8 *prop = sc_asn1_find_tag(ctx, file->prop_attr, - file->prop_attr_len, 0xA5, &prop_len); - if (prop && prop_len) { - prop = sc_asn1_find_tag(ctx, prop, - prop_len, 0x81, &prop_len); - if (prop && prop_len == 2) { - soc_manager_major = prop[0]; - soc_manager_minor = prop[1]; - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, - "SoCManager version %u.%u", - soc_manager_major, soc_manager_minor); - } + file->prop_attr_len, 0x81, &prop_len); + if (prop && prop_len == 2) { + soc_manager_major = prop[0]; + soc_manager_minor = prop[1]; + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "SoCManager version %u.%u", + soc_manager_major, soc_manager_minor); } } From 72cdc9d82ebb8a0cb0c7bbc48fd7612a4b4cb3b1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 8 Feb 2019 15:07:13 +0100 Subject: [PATCH 0768/4321] goid-tool: fixed confusion about always/never acl --- src/tools/goid-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index fc7a320c64..6d19e7e489 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -461,9 +461,9 @@ paccess_get_security_attributes(struct sc_context *ctx, const char *ac, int* cha int ok = 0; memset(sec_attr, 0, 2); if (!ac || 0 == strcmp(ac, "never")) { - /* nothing else to do */ - } else if (0 == strcmp(ac, "always")) { sec_attr[0] |= 0xFF; + } else if (0 == strcmp(ac, "always")) { + /* nothing else to do */ } else { size_t i; if (0 == strcmp(ac, "ta")) { From be33e82b75e6e22eb4dce2ff48617f3699ba9360 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 11 Feb 2019 14:33:23 +0100 Subject: [PATCH 0769/4321] goid-tool: fixed possible memory leak internally created context needs to be freed if TA/CA is done without an existing SM context from PACE --- src/sm/sm-eac.c | 15 +++++++++++++++ src/sm/sm-iso.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 105787f283..69718758f0 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1499,6 +1499,16 @@ static int eac_external_authenticate(sc_card_t *card, return r; } +static void eac_sm_clear_free_without_ctx(const struct iso_sm_ctx *ctx) +{ + if (ctx) { + struct eac_sm_ctx *eacsmctx = ctx->priv_data; + if (eacsmctx) + eacsmctx->ctx = NULL; + eac_sm_clear_free(ctx); + } +} + #define TA_NONCE_LENGTH 8 int perform_terminal_authentication(sc_card_t *card, const unsigned char **certs, const size_t *certs_lens, @@ -1521,6 +1531,7 @@ int perform_terminal_authentication(sc_card_t *card, } if (!card->sm_ctx.info.cmd_data) { card->sm_ctx.info.cmd_data = iso_sm_ctx_create(); + card->sm_ctx.ops.close = iso_sm_close; } if (!card->sm_ctx.info.cmd_data) { r = SC_ERROR_INTERNAL; @@ -1559,6 +1570,10 @@ int perform_terminal_authentication(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } + /* when iso_sm_ctx_clear_free is called, we want everything to be freed + * except the EAC_CTX, because it is needed for performing SM *after* + * iso_sm_start was called. */ + isosmctx->clear_free = eac_sm_clear_free_without_ctx; eac_ctx = NULL; } eacsmctx = isosmctx->priv_data; diff --git a/src/sm/sm-iso.h b/src/sm/sm-iso.h index 12c6535d47..57f9ab3257 100644 --- a/src/sm/sm-iso.h +++ b/src/sm/sm-iso.h @@ -119,6 +119,8 @@ struct iso_sm_ctx *iso_sm_ctx_create(void); */ int iso_sm_start(struct sc_card *card, struct iso_sm_ctx *sctx); +int iso_sm_close(struct sc_card *card); + #ifdef __cplusplus } #endif From 04ef9dbf3b7c162a879cc3722e8ab5cc93641b20 Mon Sep 17 00:00:00 2001 From: Alex Karabanov Date: Mon, 11 Feb 2019 23:50:12 +0400 Subject: [PATCH 0770/4321] Fix build on cygwin in strict mode (#1605) --- src/libopensc/card-openpgp.c | 2 +- src/libopensc/reader-pcsc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3834b21e40..dc9e760a60 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2459,7 +2459,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - sc_log(card->ctx, "pk_packet_len is %lu", pk_packet_len); + sc_log(card->ctx, "pk_packet_len is %"SC_FORMAT_LEN_SIZE_T"u", pk_packet_len); fp_buffer_len = 3 + pk_packet_len; p = fp_buffer = calloc(fp_buffer_len, 1); diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c1c2107e90..c362bc5be8 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -726,7 +726,7 @@ static int pcsc_cancel(sc_context_t *ctx) return SC_ERROR_NOT_ALLOWED; #ifndef _WIN32 - if (gpriv->pcsc_wait_ctx != -1) { + if (gpriv->pcsc_wait_ctx != (SCARDCONTEXT)-1) { rv = gpriv->SCardCancel(gpriv->pcsc_wait_ctx); if (rv == SCARD_S_SUCCESS) { /* Also close and clear the waiting context */ @@ -1509,7 +1509,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re } #ifndef _WIN32 /* Establish a new context, assuming that it is called from a different thread with pcsc-lite */ - if (gpriv->pcsc_wait_ctx == -1) { + if (gpriv->pcsc_wait_ctx == (SCARDCONTEXT)-1) { rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &gpriv->pcsc_wait_ctx); if (rv != SCARD_S_SUCCESS) { PCSC_LOG(ctx, "SCardEstablishContext(wait) failed", rv); From 4757466f27b78e9b04551bf9292462b0bc4857a7 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Sat, 2 Feb 2019 16:09:16 +0100 Subject: [PATCH 0771/4321] OpenPGP: space police remove trailing spaces & tabs --- src/libopensc/card-openpgp.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index dc9e760a60..7ea3f7cd56 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -156,7 +156,7 @@ static struct pgp_supported_ec_curves { size_t size; struct sc_object_id oid_binary; } ec_curves[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, {{0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, -1}}}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 34, -1}}, 384, {{0x2b, 0x81, 0x04, 0x00, 0x22, -1}}}, /* ansiX9p384r1 */ @@ -635,7 +635,7 @@ pgp_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 2048, flags_rsa, 0); /* TODO add ECC for more recent Gnuk (1.2.x) * these are not include in SC_CARD_TYPE_OPENPGP_GNUK, but - * are treated like SC_CARD_TYPE_OPENPGP_V2 + * are treated like SC_CARD_TYPE_OPENPGP_V2 * Gnuk supports NIST, SECG and Curve25519 from version 1.2.x on */ break; case SC_CARD_TYPE_OPENPGP_V2: @@ -868,7 +868,7 @@ pgp_get_card_features(sc_card_t *card) * * All available algorithms should be already provided by pgp_init. However, if another * algorithm is found in the "algorithm attributes" DOs, it is supported by the card as - * well and therefore added + * well and therefore added * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { sc_cardctl_openpgp_keygen_info_t key_info; @@ -899,8 +899,8 @@ pgp_get_card_features(sc_card_t *card) flags |= SC_ALGORITHM_ECDSA_HASH_NONE; flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - - _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, + + _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, &key_info.u.ec.oid); } } @@ -1232,7 +1232,7 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); if (r < 0 || data == NULL) { - sc_log(card->ctx, + sc_log(card->ctx, "Unexpected end of contents\n"); return SC_ERROR_OBJECT_NOT_VALID; } @@ -2089,14 +2089,14 @@ pgp_set_security_env(sc_card_t *card, } -/** +/** * set MANAGE SECURITY ENVIRONMENT as documented in 7.2.18 since OpenPGP Card v3.3 * * "This optional command (announced in Extended Capabilities) assigns a specific key to a * command. The DEC-key (Key-Ref 2) can be assigned to the command INTERNAL AUTHENTICATE * and the AUT-Key (Key.Ref 3) can be linked to the command PSO:DECIPHER also." * - * key: Key-Ref to change (2 for DEC-Key or 3 for AUT-Key) + * key: Key-Ref to change (2 for DEC-Key or 3 for AUT-Key) * p2: Usage to set (0xb8 for PSO:DECIPHER or 0xa4 for INTERNAL AUTHENTICATE) **/ static int @@ -2312,7 +2312,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ /* We can not rely on previous key attributes anymore, as it might be ECC */ if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0) - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); data_len = 6; data = malloc(data_len); @@ -2412,7 +2412,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { - if (key_info->u.rsa.modulus == NULL + if (key_info->u.rsa.modulus == NULL || key_info->u.rsa.exponent == NULL || (key_info->u.rsa.modulus_len) == 0 || (key_info->u.rsa.exponent_len) == 0) { @@ -2439,7 +2439,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - /* https://tools.ietf.org/html/rfc4880 page 41, 72 + /* https://tools.ietf.org/html/rfc4880 page 41, 72 * and https://tools.ietf.org/html/rfc6637 section 9 (page 8 and 9) */ pk_packet_len = 1 /* version number */ + 4 /* creation time */ @@ -2501,7 +2501,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { - /* https://tools.ietf.org/html/rfc6637#section-8 + /* https://tools.ietf.org/html/rfc6637#section-8 * This is copied from GnuPG's ecdh_params() function in app-openpgp.c */ p += key_info->u.ec.ecpoint_len; *p = 0x03; /* number of bytes following */ @@ -2986,7 +2986,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info componentnames[1] = "prime p"; componentnames[2] = "prime q"; comp_to_add = 3; - + /* The maximum exponent length is 32 bit, as set on card * we use this variable to check against actual exponent_len */ size_t max_e_len_bytes = BYTES4BITS(SC_OPENPGP_MAX_EXP_BITS); @@ -3182,7 +3182,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) pubkey.u.rsa.exponent_len = key_info->u.rsa.e_len; } else - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH @@ -3195,7 +3195,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpoint_len; } else - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); From f37a8a5c527d82bb977766a20dcd59e1ee0ec723 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:58:14 +0200 Subject: [PATCH 0772/4321] is_esteid_card is only used card-mcrd.c Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 2 +- src/libopensc/esteid.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 7aac191a42..138536e3c4 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -279,7 +279,7 @@ static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } -int is_esteid_card(sc_card_t *card) +static int is_esteid_card(sc_card_t *card) { return card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 ? 1 : 0; } diff --git a/src/libopensc/esteid.h b/src/libopensc/esteid.h index 2fbfaeed5c..72a86c4cb7 100644 --- a/src/libopensc/esteid.h +++ b/src/libopensc/esteid.h @@ -29,5 +29,4 @@ enum { #define SC_ESTEID_KEYREF_FILE_RECLEN 21 int select_esteid_df(sc_card_t * card); -int is_esteid_card(sc_card_t *card); #endif From c2cc83754e84c74cd17c6a6b175a13bee2b95fc4 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:57:09 +0200 Subject: [PATCH 0773/4321] select_esteid_df is only used in card-mcrd.c Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 10 ++++++++++ src/libopensc/esteid.h | 1 - src/libopensc/pkcs15-esteid.c | 11 ----------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 138536e3c4..11963fcc5d 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -284,6 +284,16 @@ static int is_esteid_card(sc_card_t *card) return card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 ? 1 : 0; } +static int select_esteid_df(sc_card_t * card) +{ + int r; + sc_path_t tmppath; + sc_format_path ("3F00EEEE", &tmppath); + r = sc_select_file (card, &tmppath, NULL); + LOG_TEST_RET(card->ctx, r, "esteid select DF failed"); + return r; +} + static int mcrd_match_card(sc_card_t * card) { int i = 0, r = 0; diff --git a/src/libopensc/esteid.h b/src/libopensc/esteid.h index 72a86c4cb7..d08eb388a8 100644 --- a/src/libopensc/esteid.h +++ b/src/libopensc/esteid.h @@ -28,5 +28,4 @@ enum { #define SC_ESTEID_KEYREF_FILE_RECLEN 21 -int select_esteid_df(sc_card_t * card); #endif diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index b3c58b6888..aa7afeab90 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -46,17 +46,6 @@ set_string (char **strp, const char *value) } -int -select_esteid_df (sc_card_t * card) -{ - int r; - sc_path_t tmppath; - sc_format_path ("3F00EEEE", &tmppath); - r = sc_select_file (card, &tmppath, NULL); - LOG_TEST_RET(card->ctx, r, "esteid select DF failed"); - return r; -} - static int sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) { From b63a868e68635754048ec24431cbbedea848544b Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 12 Feb 2019 10:42:39 +0100 Subject: [PATCH 0774/4321] Fix build when EVP_PKEY_CTX_set_rsa_oaep_md is not defined. --- src/tools/pkcs11-tool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e1f5656b60..7d8542df2d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5371,12 +5371,19 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, md = EVP_sha512(); break; } +#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); printf("set md failed, returning\n"); return 0; } +#else + if (hash_alg != CKM_SHA_1) { + printf("This version of OpenSsl only supports SHA1 for OAEP, returning\n"); + return 0; + } +#endif switch (mgf) { case CKG_MGF1_SHA1: md = EVP_sha1(); From 9ae507c5f8dcc193f367e6ad536157cb679f3408 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 12 Feb 2019 14:09:26 +0100 Subject: [PATCH 0775/4321] Fix indentation. --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7d8542df2d..1ba69d135e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5379,10 +5379,10 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } #else - if (hash_alg != CKM_SHA_1) { - printf("This version of OpenSsl only supports SHA1 for OAEP, returning\n"); + if (hash_alg != CKM_SHA_1) { + printf("This version of OpenSsl only supports SHA1 for OAEP, returning\n"); return 0; - } + } #endif switch (mgf) { case CKG_MGF1_SHA1: From fdb0e6d5810f70c674f4524471d699884ee01595 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 01:15:01 +0100 Subject: [PATCH 0776/4321] Fixed Potential leak of memory --- src/common/simclist.c | 3 ++ src/libopensc/card-authentic.c | 24 +++++----- src/libopensc/card-dnie.c | 9 ++-- src/libopensc/card-iasecc.c | 10 ++-- src/libopensc/iasecc-sdo.c | 70 ++++++++++++++++------------ src/libopensc/pkcs15-actalis.c | 9 +++- src/pkcs11/framework-pkcs15.c | 3 +- src/pkcs15init/pkcs15-oberthur-awp.c | 14 +++--- src/scconf/parse.c | 8 ++-- src/tools/pkcs15-init.c | 53 +++++++++++++-------- src/tools/sc-hsm-tool.c | 8 +++- 11 files changed, 125 insertions(+), 86 deletions(-) diff --git a/src/common/simclist.c b/src/common/simclist.c index b18a07d719..03ed79bd76 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -479,6 +479,9 @@ int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int p size_t datalen = l->attrs.meter(data); lent->data = (struct list_entry_s *)malloc(datalen); if (lent->data == NULL) { + if (!(l->spareelsnum > 0)) { + free(lent); + } return -1; } memcpy(lent->data, data, datalen); diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index d7c81b5a57..2322bc94cb 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1775,28 +1775,28 @@ authentic_manage_sdo_encode(struct sc_card *card, struct sc_authentic_sdo *sdo, rv = authentic_update_blob(ctx, AUTHENTIC_TAG_DOCP_MECH, &sdo->docp.mech, sizeof(sdo->docp.mech), &data, &data_len); - LOG_TEST_RET(ctx, rv, "DOCP MECH encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "DOCP MECH encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_DOCP_ID, &sdo->docp.id, sizeof(sdo->docp.id), &data, &data_len); - LOG_TEST_RET(ctx, rv, "DOCP ID encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "DOCP ID encode error"); if (cmd == SC_CARDCTL_AUTHENTIC_SDO_CREATE) { rv = authentic_update_blob(ctx, AUTHENTIC_TAG_DOCP_ACLS, sdo->docp.acl_data, sdo->docp.acl_data_len, &data, &data_len); - LOG_TEST_RET(ctx, rv, "DOCP ACLs encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "DOCP ACLs encode error"); if (sdo->docp.security_parameter) { rv = authentic_update_blob(ctx, AUTHENTIC_TAG_DOCP_SCP, &sdo->docp.security_parameter, sizeof(sdo->docp.security_parameter), &data, &data_len); - LOG_TEST_RET(ctx, rv, "DOCP ACLs encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "DOCP ACLs encode error"); } if (sdo->docp.usage_counter[0] || sdo->docp.usage_counter[1]) { rv = authentic_update_blob(ctx, AUTHENTIC_TAG_DOCP_USAGE_COUNTER, sdo->docp.usage_counter, sizeof(sdo->docp.usage_counter), &data, &data_len); - LOG_TEST_RET(ctx, rv, "DOCP ACLs encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "DOCP ACLs encode error"); } } else if (cmd == SC_CARDCTL_AUTHENTIC_SDO_STORE) { @@ -1806,10 +1806,10 @@ authentic_manage_sdo_encode(struct sc_card *card, struct sc_authentic_sdo *sdo, || sdo->docp.mech == AUTHENTIC_MECH_CRYPTO_RSA1792 || sdo->docp.mech == AUTHENTIC_MECH_CRYPTO_RSA2048) { rv = authentic_manage_sdo_encode_prvkey(card, sdo->data.prvkey, &data, &data_len); - LOG_TEST_RET(ctx, rv, "SDO RSA encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA encode error"); } else { - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cryptographic object unsupported for encoding"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "Cryptographic object unsupported for encoding"); } } else if (cmd == SC_CARDCTL_AUTHENTIC_SDO_GENERATE) { @@ -1817,21 +1817,23 @@ authentic_manage_sdo_encode(struct sc_card *card, struct sc_authentic_sdo *sdo, rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PUBLIC_EXPONENT, sdo->data.prvkey->u.rsa.exponent.data, sdo->data.prvkey->u.rsa.exponent.len, &data, &data_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Exponent encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Exponent encode error"); } data_tag = AUTHENTIC_TAG_RSA_GENERATE_DATA; } else if (cmd != SC_CARDCTL_AUTHENTIC_SDO_DELETE) { - LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO operation"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO operation"); } rv = authentic_update_blob(ctx, data_tag, data, data_len, out, out_len); - LOG_TEST_RET(ctx, rv, "SDO DOCP encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO DOCP encode error"); + + sc_log_hex(ctx, "encoded SDO operation data", *out, *out_len); +err: free(data); - sc_log_hex(ctx, "encoded SDO operation data", *out, *out_len); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 902754dc06..0fe9350b04 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1007,7 +1007,7 @@ static int dnie_fill_cache(sc_card_t * card) size_t count = 0; size_t len = 0; u8 *buffer = NULL; - u8 *pt = NULL; + u8 *pt = NULL, *p; sc_context_t *ctx = NULL; if (!card || !card->ctx) @@ -1056,19 +1056,22 @@ static int dnie_fill_cache(sc_card_t * card) } if (r == SC_ERROR_INCORRECT_PARAMETERS) goto read_done; + free(buffer); if (apdu.resp != tmp) free(apdu.resp); LOG_FUNC_RETURN(ctx, r); /* arriving here means response error */ } /* copy received data into buffer. realloc() if not enough space */ count = apdu.resplen; - buffer = realloc(buffer, len + count); - if (!buffer) { + p = realloc(buffer, len + count); + if (!p) { + free(buffer); free((void *)apdu.data); if (apdu.resp != tmp) free(apdu.resp); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } + buffer = p; memcpy(buffer + len, apdu.resp, count); if (apdu.resp != tmp) { free(apdu.resp); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 9033369f08..f4cbbfac3b 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -3406,12 +3406,13 @@ iasecc_read_public_key(struct sc_card *card, unsigned type, sc_log(ctx, "read public kay(ref:%i;size:%i)", ref, size); + memset(&bn, 0, sizeof bn); memset(&sdo, 0, sizeof(sdo)); sdo.sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC; sdo.sdo_ref = ref & ~IASECC_OBJECT_REF_LOCAL; rv = iasecc_sdo_get_data(card, &sdo); - LOG_TEST_RET(ctx, rv, "failed to read public key: cannot get RSA SDO data"); + LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot get RSA SDO data"); if (out) *out = NULL; @@ -3420,13 +3421,13 @@ iasecc_read_public_key(struct sc_card *card, unsigned type, bn[0].data = (unsigned char *) malloc(sdo.data.pub_key.n.size); if (!bn[0].data) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate modulus"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate modulus"); bn[0].len = sdo.data.pub_key.n.size; memcpy(bn[0].data, sdo.data.pub_key.n.value, sdo.data.pub_key.n.size); bn[1].data = (unsigned char *) malloc(sdo.data.pub_key.e.size); if (!bn[1].data) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate exponent"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate exponent"); bn[1].len = sdo.data.pub_key.e.size; memcpy(bn[1].data, sdo.data.pub_key.e.value, sdo.data.pub_key.e.size); @@ -3434,11 +3435,12 @@ iasecc_read_public_key(struct sc_card *card, unsigned type, rsa_key.exponent = bn[1]; rv = sc_pkcs15_encode_pubkey_rsa(ctx, &rsa_key, out, out_len); - LOG_TEST_RET(ctx, rv, "failed to read public key: cannot encode RSA public key"); + LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot encode RSA public key"); if (out && out_len) sc_log(ctx, "encoded public key: %s", sc_dump_hex(*out, *out_len)); +err: if (bn[0].data) free(bn[0].data); if (bn[1].data) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 6f824821b6..5bc07edf42 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -558,8 +558,10 @@ iasecc_parse_keyset(struct sc_card *card, unsigned char *data, size_t data_len, if (tlv.tag == IASECC_SDO_KEYSET_TAG_COMPULSORY) keyset->compulsory = tlv; - else + else { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "parse error: non KeySet SDO tag"); + } offs += rv; } @@ -668,43 +670,48 @@ iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_s sdo->docp.tries_remaining = tlv; } else if (tlv.tag == IASECC_SDO_CHV_TAG) { - if (sdo->sdo_class != IASECC_SDO_CLASS_CHV) + if (sdo->sdo_class != IASECC_SDO_CLASS_CHV) { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: IASECC_SDO_CHV_TAG tag in non User CHV SDO"); + } rv = iasecc_parse_chv(card, tlv.value, tlv.size, &sdo->data.chv); - LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO CHV data"); - free(tlv.value); + LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO CHV data"); } else if (tlv.tag == IASECC_SDO_PUBKEY_TAG) { - if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PUBLIC) + if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PUBLIC) { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_PUBLIC_KEY tag in non PUBLIC_KEY SDO"); + } rv = iasecc_parse_pubkey(card, tlv.value, tlv.size, &sdo->data.pub_key); - LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PUBLIC KEY data"); - free(tlv.value); + LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PUBLIC KEY data"); } else if (tlv.tag == IASECC_SDO_PRVKEY_TAG) { - if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PRIVATE) + if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PRIVATE) { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_PRIVATE_KEY tag in non PRIVATE_KEY SDO"); + } rv = iasecc_parse_prvkey(card, tlv.value, tlv.size, &sdo->data.prv_key); - LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PRIVATE KEY data"); - free(tlv.value); + LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PRIVATE KEY data"); } else if (tlv.tag == IASECC_SDO_KEYSET_TAG) { - if (sdo->sdo_class != IASECC_SDO_CLASS_KEYSET) + if (sdo->sdo_class != IASECC_SDO_CLASS_KEYSET) { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_KEYSET tag in non KEYSET SDO"); + } rv = iasecc_parse_keyset(card, tlv.value, tlv.size, &sdo->data.keyset); - LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO KEYSET data"); - free(tlv.value); + LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO KEYSET data"); } else { sc_log(ctx, "iasecc_sdo_parse_data() non supported tag 0x%X", tlv.tag); + free(tlv.value); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } @@ -878,7 +885,7 @@ static int iasecc_encode_docp(struct sc_context *ctx, struct iasecc_sdo_docp *docp, unsigned char **out, size_t *out_len) { struct iasecc_extended_tlv tlv, tlv_st; - unsigned char *st_blob, *tmp_blob, *docp_blob; + unsigned char *st_blob = NULL, *tmp_blob = NULL, *docp_blob = NULL; size_t blob_size; int rv; @@ -889,63 +896,64 @@ iasecc_encode_docp(struct sc_context *ctx, struct iasecc_sdo_docp *docp, unsigne memset(&tlv, 0, sizeof(tlv)); memset(&tlv_st, 0, sizeof(tlv_st)); - st_blob = NULL; blob_size = 0; rv = iasecc_update_blob(ctx, &docp->acls_contact, &st_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add contact ACLs to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add contact ACLs to blob"); rv = iasecc_update_blob(ctx, &docp->acls_contactless, &st_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add contactless ACLs to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add contactless ACLs to blob"); tlv.tag = IASECC_DOCP_TAG_ACLS; tlv.size = blob_size; tlv.value = st_blob; - tmp_blob = NULL; blob_size = 0; rv = iasecc_update_blob(ctx, &tlv, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add ACLs template to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add ACLs template to blob"); rv = iasecc_update_blob(ctx, &docp->name, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add NAME to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add NAME to blob"); rv = iasecc_update_blob(ctx, &docp->tries_maximum, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add TRIES MAXIMUM to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add TRIES MAXIMUM to blob"); rv = iasecc_update_blob(ctx, &docp->tries_remaining, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add TRIES REMAINING to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add TRIES REMAINING to blob"); rv = iasecc_update_blob(ctx, &docp->usage_maximum, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add USAGE MAXIMUM to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add USAGE MAXIMUM to blob"); rv = iasecc_update_blob(ctx, &docp->usage_remaining, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add USAGE REMAINING to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add USAGE REMAINING to blob"); rv = iasecc_update_blob(ctx, &docp->non_repudiation, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add NON REPUDIATION to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add NON REPUDIATION to blob"); rv = iasecc_update_blob(ctx, &docp->size, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add SIZE to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add SIZE to blob"); rv = iasecc_update_blob(ctx, &docp->issuer_data, &tmp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add IDATA to blob"); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add IDATA to blob"); tlv.tag = IASECC_DOCP_TAG; tlv.size = blob_size; tlv.value = tmp_blob; - docp_blob = NULL; blob_size = 0; rv = iasecc_update_blob(ctx, &tlv, &docp_blob, &blob_size); - LOG_TEST_RET(ctx, rv, "ECC: cannot add ACLs to blob"); - - free(tmp_blob); + LOG_TEST_GOTO_ERR(ctx, rv, "ECC: cannot add ACLs to blob"); if (out && out_len) { *out = docp_blob; *out_len = blob_size; + docp_blob = NULL; } +err: + free(docp_blob); + free(tmp_blob); + free(st_blob); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 24983921aa..f4a3a7561f 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -233,9 +233,11 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) sc_read_binary(card, 4, compCert, compLen, 0); - if (uncompress(cert, &len, - compCert, compLen) != Z_OK) + if (uncompress(cert, &len, compCert, compLen) != Z_OK) { + free(cert); + free(compCert); return SC_ERROR_INTERNAL; + } cpath.index = 0; cpath.count = len; @@ -251,6 +253,9 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) j++; cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + + free(cert); + free(compCert); } } #endif diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index eeb6861a97..e94201a030 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2348,9 +2348,10 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile break; case CKA_VALUE: if (attr->pValue) { + free(args.key.data); args.key.data = calloc(1,attr->ulValueLen); if (!args.key.data) - return CKR_HOST_MEMORY; + return CKR_HOST_MEMORY; memcpy(args.key.data, attr->pValue, attr->ulValueLen); args.key.data_len = attr->ulValueLen; } diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index ab67b6c4c3..2609607f49 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1569,28 +1569,26 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro int rv; LOG_FUNC_CALLED(ctx); + memset(&idata, 0, sizeof(idata)); der = obj->content; path = ((struct sc_pkcs15_data_info *)obj->data)->path; obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; rv = awp_new_file(p15card, profile, obj_type, obj_id & 0xFF, &info_file, &obj_file); - LOG_TEST_RET(ctx, rv, "COSM new file error"); + LOG_TEST_GOTO_ERR(ctx, rv, "COSM new file error"); - memset(&idata, 0, sizeof(idata)); - sc_log(ctx, - "Data Der(%p,%"SC_FORMAT_LEN_SIZE_T"u)", der.value, der.len); rv = awp_encode_data_info(p15card, obj, &idata); - LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot encode info"); + LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot encode info"); rv = awp_set_data_info(p15card, profile, info_file, &idata); - LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot set info"); + LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot set info"); rv = awp_update_object_list(p15card, profile, obj_type, obj_id & 0xFF); - LOG_TEST_RET(ctx, rv, "'Create Data' update DF failed: cannot update list"); + LOG_TEST_GOTO_ERR(ctx, rv, "'Create Data' update DF failed: cannot update list"); +err: awp_free_data_info(&idata); - sc_file_free(info_file); sc_file_free(obj_file); diff --git a/src/scconf/parse.c b/src/scconf/parse.c index b32f0e8ef2..da83f7b49f 100644 --- a/src/scconf/parse.c +++ b/src/scconf/parse.c @@ -99,9 +99,7 @@ static scconf_item *scconf_item_add_internal(scconf_parser * parser, int type) /* if item with same key already exists, use it */ item = scconf_item_find(parser); if (item) { - if (parser->key) { - free(parser->key); - } + free(parser->key); parser->key = NULL; parser->current_item = item; return item; @@ -147,8 +145,7 @@ scconf_item *scconf_item_add(scconf_context * config, scconf_block * block, scco scconf_block_copy((const scconf_block *) data, &dst); scconf_list_copy(dst->name, &parser.name); } - scconf_item_add_internal(&parser, type); - if (parser.current_item) { + if (scconf_item_add_internal(&parser, type)) { switch (parser.current_item->type) { case SCCONF_ITEM_TYPE_COMMENT: parser.current_item->value.comment = strdup((const char *) data); @@ -167,6 +164,7 @@ scconf_item *scconf_item_add(scconf_context * config, scconf_block * block, scco } else { /* FIXME is it an error if item is NULL? */ free(parser.key); + parser.key = NULL; } return parser.current_item; } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index ad74f42ffb..f02692d12f 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1092,6 +1092,7 @@ do_store_private_key(struct sc_profile *profile) for (i = 0; i < ncerts && r >= 0; i++) { struct sc_pkcs15init_certargs cargs; char namebuf[SC_PKCS15_MAX_LABEL_SIZE-1]; + int cargs_label_needs_free = 0; if (i && opt_ignore_ca_certs) break; @@ -1108,14 +1109,20 @@ do_store_private_key(struct sc_profile *profile) cargs.label = cert_common_name(cert[i]); if (!cargs.label) cargs.label = X509_NAME_oneline(X509_get_subject_name(cert[i]), namebuf, sizeof(namebuf)); + else + cargs_label_needs_free = 1; /* Just the first certificate gets the same ID * as the private key. All others get * an ID of their own */ if (i == 0) { cargs.id = args.id; - if (opt_cert_label != 0) + if (opt_cert_label != 0) { + if (cargs_label_needs_free) + free((char *) cargs.label); cargs.label = opt_cert_label; + cargs_label_needs_free = 0; + } } else { if (is_cacert_already_present(&cargs)) { printf("Certificate #%d already present, not stored.\n", i); @@ -1128,6 +1135,8 @@ do_store_private_key(struct sc_profile *profile) r = sc_pkcs15init_store_certificate(g_p15card, profile, &cargs, NULL); next_cert: + if (cargs_label_needs_free) + free((char *) cargs.label); free(cargs.der_encoded.value); } @@ -1242,18 +1251,23 @@ do_store_secret_key(struct sc_profile *profile) } r = do_read_data_object(opt_infile, &args.key.data, &args.key.data_len, (keybits+7) / 8); - if (r < 0) + if (r < 0) { + free(args.key.data); return r; + } args.algorithm = algorithm; args.value_len = keybits; args.access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE; r = sc_lock(g_p15card->card); - if (r < 0) + if (r < 0) { + free(args.key.data); return r; + } r = sc_pkcs15init_store_secret_key(g_p15card, profile, &args, NULL); sc_unlock(g_p15card->card); + free(args.key.data); return r; } @@ -1455,8 +1469,7 @@ do_store_data_object(struct sc_profile *profile) sc_unlock(g_p15card->card); } - if (data) - free(data); + free(data); return r; } @@ -2485,17 +2498,17 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen, size_t expected) inf = fopen(name, "rb"); if (inf == NULL) { fprintf(stderr, "Unable to open '%s' for reading.\n", name); - return -1; + return SC_ERROR_FILE_NOT_FOUND; } c = fread(*out, 1, filesize, inf); fclose(inf); if (c < 0) { perror("read"); - return -1; + return SC_ERROR_FILE_NOT_FOUND; } *outlen = filesize; - return 0; + return SC_SUCCESS; } static char * @@ -3161,25 +3174,25 @@ static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) pin = (char *) opt_pins[0]; } else { - sc_ui_hints_t hints; + sc_ui_hints_t hints; - if (opt_use_pinpad) + if (opt_use_pinpad) return SC_ERROR_OBJECT_NOT_FOUND; if (pin_obj->label[0]) snprintf(pin_label, sizeof(pin_label), "User PIN [%.*s]", - (int) sizeof pin_obj->label, pin_obj->label); + (int) sizeof pin_obj->label, pin_obj->label); else snprintf(pin_label, sizeof(pin_label), "User PIN"); - memset(&hints, 0, sizeof(hints)); - hints.dialog_name = "pkcs15init.get_pin"; - hints.prompt = "User PIN required"; - hints.obj_label = pin_label; - hints.usage = SC_UI_USAGE_OTHER; - hints.card = g_card; - hints.p15card = p15card; - - get_pin(&hints, &pin); + memset(&hints, 0, sizeof(hints)); + hints.dialog_name = "pkcs15init.get_pin"; + hints.prompt = "User PIN required"; + hints.obj_label = pin_label; + hints.usage = SC_UI_USAGE_OTHER; + hints.card = g_card; + hints.p15card = p15card; + + get_pin(&hints, &pin); } r = sc_pkcs15_verify_pin(p15card, pin_obj, (unsigned char *)pin, pin ? strlen((char *) pin) : 0); diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index a6cacb5be0..9307ffd308 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1110,7 +1110,13 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas // Allocate data buffer for the generated shares shares = malloc(password_shares_total * sizeof(secret_share_t)); - createShares(secret, password_shares_threshold, password_shares_total, prime, shares); + if (!shares || 0 > createShares(secret, password_shares_threshold, password_shares_total, prime, shares)) { + printf("Error generating Shares. Please try again."); + OPENSSL_cleanse(*pwd, *pwdlen); + free(*pwd); + free(shares); + return -1; + } sp = shares; for (i = 0; i < password_shares_total; i++) { From 85485eb9b076181d47bbe8d2a332a2b4e469a849 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 13:54:27 +0100 Subject: [PATCH 0777/4321] fixed unused assignments --- src/libopensc/card-cac1.c | 1 - src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-setcos.c | 1 - src/pkcs11/framework-pkcs15.c | 2 ++ src/pkcs15init/pkcs15-myeid.c | 1 + src/sm/sm-common.c | 3 --- src/tools/iasecc-tool.c | 4 ++++ src/tools/opensc-explorer.c | 2 +- 8 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 969c18088c..8513a30e03 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -177,7 +177,6 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, #endif if (r) goto done; - cert_ptr = val; } else if (cert_len > 0) { priv->cache_buf = malloc(cert_len); if (priv->cache_buf == NULL) { diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index f4cbbfac3b..8f5be9015b 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -416,7 +416,7 @@ iasecc_init_gemalto(struct sc_card *card) card->caps |= SC_CARD_CAP_USE_FCI_AC; sc_format_path("3F00", &path); - rv = sc_select_file(card, &path, NULL); + sc_select_file(card, &path, NULL); /* Result ignored*/ rv = iasecc_parse_ef_atr(card); diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index ea085f615f..4cf328ad6a 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -792,7 +792,6 @@ static void parse_sec_attr_44(sc_file_t *file, const u8 *buf, size_t len) if (iACLen > len) break; - iPinCount = -1; /* default no pin required */ iMethod = SC_AC_NONE; /* default no authentication required */ if (buf[iOffset] & 0X80) { /* AC in adaptive coding */ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index e94201a030..c7c8f1b681 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5705,6 +5705,8 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (aes_max_key_size > 0) { rc = sc_pkcs11_register_aes_mechanisms(p11card, aes_flags, aes_min_key_size, aes_max_key_size); + if (rc != CKR_OK) + return rc; } diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 304b0dd717..095b4fe506 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -654,6 +654,7 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* TODO: add other flags, like CKA_TRUSTED and CKA_WRAP_WITH_TRUSTED */ r = sc_file_set_prop_attr(file, prop_info, 2); + LOG_TEST_RET(ctx, r, "Cannot create MyEID key file"); /* Now create the key file */ r = sc_pkcs15init_create_file(profile, p15card, file); diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 43e1fb155b..ecd6ef1297 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -162,7 +162,6 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; DES_encrypt3((DES_LONG *)tin,schedule,schedule2,schedule); - tout0=tin[0]; tout1=tin[1]; if (out != NULL) @@ -170,7 +169,6 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, l2c(tout0,out); l2c(tout1,out); } - tout0=tin0=tin1=tin[0]=tin[1]=0; /* Transform the data in tout1 so that it will match the return value that the MIT Kerberos @@ -220,7 +218,6 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, l2c(tout0,out); l2c(tout1,out); } - tout0=tin0=tin1=tin[0]=tin[1]=0; /* Transform the data in tout1 so that it will match the return value that the MIT Kerberos diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 6b1d0111db..b12a5f1886 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -265,6 +265,10 @@ int main(int argc, char *argv[]) else if (!do_list_sdos) { r = sc_pkcs15_bind(card, NULL, &p15card); } + if (r != SC_SUCCESS) { + fprintf(stderr, "Failed to bind card: %s\n", sc_strerror(r)); + goto end; + } if (do_list_sdos) { if ((err = list_sdos(opt_sdo_tag))) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index ea2163fb3a..a4edb88f29 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2104,7 +2104,7 @@ int main(int argc, char *argv[]) int r, c, long_optind = 0, err = 0; sc_context_param_t ctx_param; int lcycle = SC_CARDCTRL_LIFECYCLE_ADMIN; - FILE *script = stdin; + FILE *script; printf("OpenSC Explorer version %s\n", sc_get_version()); From b708cab0a3f65e07cef9f473a7c5153ceb7c1b66 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 13:54:38 +0100 Subject: [PATCH 0778/4321] fixed assignment of garbage value --- src/libopensc/card-oberthur.c | 71 ++++++++++++----------------------- 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 675a453f15..9c866e7f0d 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -288,82 +288,57 @@ add_acl_entry(struct sc_card *card, struct sc_file *file, unsigned int op, } -static int -tlv_get(const unsigned char *msg, int len, unsigned char tag, - unsigned char *ret, int *ret_len) -{ - int cur = 0; - - while (cur < len) { - if (*(msg+cur)==tag) { - int ii, ln = *(msg+cur+1); - - if (ln > *ret_len) - return SC_ERROR_WRONG_LENGTH; - - for (ii=0; iictx); - attr_len = sizeof(attr); - if (tlv_get(buf, buflen, 0x82, attr, &attr_len)) + attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x82, &attr_len); + if (!attr || attr_len < 1) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); type = attr[0]; - attr_len = sizeof(attr); - if (tlv_get(buf, buflen, 0x83, attr, &attr_len)) + attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x83, &attr_len); + if (!attr || attr_len < 2) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->id = attr[0]*0x100 + attr[1]; - attr_len = sizeof(attr); - if (tlv_get(buf, buflen, type==0x01 ? 0x80 : 0x85, attr, &attr_len)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - if (attr_len<2 && type != 0x04) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - + attr = sc_asn1_find_tag(card->ctx, buf, buflen, type==0x01 ? 0x80 : 0x85, &attr_len); switch (type) { case 0x01: + if (!attr || attr_len < 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->size = attr[0]*0x100 + attr[1]; break; case 0x04: + if (!attr || attr_len < 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_LINEAR_VARIABLE; file->size = attr[0]; - attr_len = sizeof(attr); - if (tlv_get(buf, buflen, 0x82, attr, &attr_len)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - if (attr_len!=5) + attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x82, &attr_len); + if (!attr || attr_len < 5) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->record_length = attr[2]*0x100+attr[3]; file->record_count = attr[4]; break; case 0x11: + if (!attr || attr_len < 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_DES; file->size = attr[0]*0x100 + attr[1]; file->size /= 8; break; case 0x12: + if (!attr || attr_len < 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; @@ -382,11 +357,15 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, } break; case 0x14: + if (!attr || attr_len < 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT; file->size = attr[0]*0x100 + attr[1]; break; case 0x38: + if (!attr || attr_len < 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); file->type = SC_FILE_TYPE_DF; file->size = attr[0]; if (SC_SUCCESS != sc_file_set_type_attr(file,attr,attr_len)) @@ -396,10 +375,8 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } - attr_len = sizeof(attr); - if (tlv_get(buf, buflen, 0x86, attr, &attr_len)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - if (attr_len<8) + attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x86, &attr_len); + if (!attr || attr_len < 8) LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); if (file->type == SC_FILE_TYPE_DF) { From 53954e9ff1d6bf3a86ea9949b803c462eff2ed33 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 20:57:00 +0100 Subject: [PATCH 0779/4321] fixed OpenSSL handling in PKCS#11 mapping prevents NULL pointer dereference --- src/pkcs11/openssl.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 8233746d69..43288ee042 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -288,7 +288,7 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) * Handle OpenSSL digest functions */ #define DIGEST_CTX(op) \ - ((EVP_MD_CTX *) (op)->priv_data) + (op ? (EVP_MD_CTX *) (op)->priv_data : NULL) static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *op) { @@ -301,7 +301,10 @@ static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *op) if (!(md_ctx = EVP_MD_CTX_create())) return CKR_HOST_MEMORY; - EVP_DigestInit(md_ctx, md); + if (!EVP_DigestInit(md_ctx, md)) { + EVP_MD_CTX_destroy(md_ctx); + return CKR_GENERAL_ERROR; + } op->priv_data = md_ctx; return CKR_OK; } @@ -309,7 +312,11 @@ static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *op) static CK_RV sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *op, CK_BYTE_PTR pData, CK_ULONG pDataLen) { - EVP_DigestUpdate(DIGEST_CTX(op), pData, pDataLen); + EVP_MD_CTX *md_ctx = DIGEST_CTX(op); + if (!md_ctx) + return CKR_ARGUMENTS_BAD; + if (!EVP_DigestUpdate(md_ctx, pData, pDataLen)) + return CKR_GENERAL_ERROR; return CKR_OK; } @@ -318,25 +325,28 @@ static CK_RV sc_pkcs11_openssl_md_final(sc_pkcs11_operation_t *op, { EVP_MD_CTX *md_ctx = DIGEST_CTX(op); + if (!md_ctx) + return CKR_ARGUMENTS_BAD; if (*pulDigestLen < (unsigned) EVP_MD_CTX_size(md_ctx)) { sc_log(context, "Provided buffer too small: %lu < %d", *pulDigestLen, EVP_MD_CTX_size(md_ctx)); *pulDigestLen = EVP_MD_CTX_size(md_ctx); return CKR_BUFFER_TOO_SMALL; } - - EVP_DigestFinal(md_ctx, pDigest, (unsigned *) pulDigestLen); + if (!EVP_DigestFinal(md_ctx, pDigest, (unsigned *) pulDigestLen)) + return CKR_GENERAL_ERROR; return CKR_OK; } static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *op) { - EVP_MD_CTX *md_ctx = DIGEST_CTX(op); - - if (md_ctx) - EVP_MD_CTX_destroy(md_ctx); - op->priv_data = NULL; + if (op) { + EVP_MD_CTX *md_ctx = DIGEST_CTX(op); + if (md_ctx) + EVP_MD_CTX_destroy(md_ctx); + op->priv_data = NULL; + } } #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) @@ -478,7 +488,11 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len * are already collected in the md_ctx */ sc_log(context, "Trying to verify using EVP"); - res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); + if (md_ctx) { + res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); + } else { + res = -1; + } EVP_PKEY_free(pkey); if (res == 1) return CKR_OK; @@ -610,7 +624,11 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned char *tmp = digest; unsigned int tmp_len; - EVP_DigestFinal(md_ctx, tmp, &tmp_len); + if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { + RSA_free(rsa); + free(rsa_out); + return CKR_GENERAL_ERROR; + } data = tmp; data_len = tmp_len; } From e4a01643a6fb4f899171065d3919c11b62a1be7d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 21:11:09 +0100 Subject: [PATCH 0780/4321] fixed possible NULL pointer dereference --- src/libopensc/card-gids.c | 20 +++++++++++--------- src/libopensc/muscle-filesystem.c | 15 +++++++++------ src/tools/pkcs15-crypt.c | 2 +- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 9718283d4b..2471c55a35 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -548,7 +548,7 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef } p = sc_asn1_find_tag(card->ctx, buffer, buffersize , GIDS_TRY_LIMIT_TAG, &datasize); if (p && datasize == 1) { - if (tries_left) + if (max_tries) *max_tries = p[0]; } @@ -928,14 +928,16 @@ static int gids_select_file(sc_card_t *card, const struct sc_path *in_path, data->currentEFID = in_path->value[1] + (in_path->value[0]<<8); data->currentDO = in_path->value[3] + (in_path->value[2]<<8); - file = sc_file_new(); - if (file == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - file->path = *in_path; - file->type = SC_FILE_TYPE_WORKING_EF; - file->ef_structure = SC_FILE_EF_TRANSPARENT; - file->size = SC_MAX_EXT_APDU_BUFFER_SIZE; - *file_out = file; + if (file_out) { + file = sc_file_new(); + if (file == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + file->path = *in_path; + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + file->size = SC_MAX_EXT_APDU_BUFFER_SIZE; + *file_out = file; + } LOG_FUNC_RETURN(ctx, SC_SUCCESS); } else if (in_path->len == 4 && in_path->value[0] == 0x3F && in_path->value[1] == 0xFF && in_path->type == SC_PATH_TYPE_PATH) { // GIDS does not allow a select with a path containing a DF diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 887bd03acc..ab5b6408aa 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -216,14 +216,17 @@ int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t ** mscfs_check_cache(fs); if(idx) *idx = -1; for(x = 0; x < fs->cache.size; x++) { - msc_id objectId; *file_data = &fs->cache.array[x]; - objectId = (*file_data)->objectId; - if(0 == memcmp(objectId.id, fullPath.id, 4)) { - if(idx) *idx = x; - break; + if (*file_data) { + msc_id objectId; + objectId = (*file_data)->objectId; + if(0 == memcmp(objectId.id, fullPath.id, 4)) { + if (idx) + *idx = x; + break; + } + *file_data = NULL; } - *file_data = NULL; } if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath.id, 4) || 0 == memcmp("\x3F\x00\x50\x15", fullPath.id, 4 ) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath.id, 4))) { static mscfs_file_t ROOT_FILE; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 6d064ec317..b9ba591aa4 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -346,7 +346,7 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) * a crypto operation. Card drivers can test for SC_AC_CONTEXT_SPECIFIC * to do any special handling. */ - if (key->user_consent) { + if (key->user_consent && pin && pin->data) { int auth_meth_saved; struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) pin->data; From 32e1995300f4459fd8751619af83b3b621da5e2d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 25 Jan 2019 22:00:10 +0100 Subject: [PATCH 0781/4321] fixed dead assignment --- src/libopensc/iasecc-sdo.c | 2 +- src/pkcs15init/pkcs15-oberthur-awp.c | 2 -- src/tools/cryptoflex-tool.c | 6 ++++-- src/tools/piv-tool.c | 4 ++++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 5bc07edf42..588fa72d79 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -840,7 +840,7 @@ iasecc_update_blob(struct sc_context *ctx, struct iasecc_extended_tlv *tlv, unsigned char **blob, size_t *blob_size) { unsigned char *pp = NULL; - int offs = 0, sz = tlv->size + 2; + int offs = 0, sz; if (tlv->size == 0) LOG_FUNC_RETURN(ctx, SC_SUCCESS); diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 2609607f49..362b8f3e4d 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1563,7 +1563,6 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro struct sc_context *ctx = p15card->card->ctx; struct sc_file *info_file=NULL, *obj_file=NULL; struct awp_data_info idata; - struct sc_pkcs15_der der; struct sc_path path; unsigned obj_id, obj_type = obj->auth_id.len ? COSM_TYPE_PRIVDATA_OBJECT : SC_PKCS15_TYPE_DATA_OBJECT; int rv; @@ -1571,7 +1570,6 @@ awp_update_df_create_data(struct sc_pkcs15_card *p15card, struct sc_profile *pro LOG_FUNC_CALLED(ctx); memset(&idata, 0, sizeof(idata)); - der = obj->content; path = ((struct sc_pkcs15_data_info *)obj->data)->path; obj_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 1a9e960bc1..6a910f9b50 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -302,8 +302,6 @@ static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa) if (dmq1 == NULL) return -1; cf2bn(p, base, dmq1); - p += base; - if (RSA_set0_factors(rsa, bn_p, q) != 1) return -1; @@ -784,6 +782,10 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(p, bnbuf, 2*base); p += 2*base; r = bn2cf(rsa_e, bnbuf); + if (r != 4) { + fprintf(stderr, "Invalid exponent value.\n"); + return 2; + } memcpy(p, bnbuf, 4); p += 4; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b95d156833..b4a7f17fd9 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -383,6 +383,10 @@ static int gen_key(const char * key_info) x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; r = EC_POINT_set_affine_coordinates_GFp(ecgroup, ecpoint, x, y, NULL); + if (r == 0) { + fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); + return -1; + } eckey = EC_KEY_new(); r = EC_KEY_set_group(eckey, ecgroup); if (r == 0) { From 8ea77a83e0949f1ad9f3515794bccb0cab9574c9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 Jan 2019 08:24:05 +0100 Subject: [PATCH 0782/4321] fixed misuse of realloc --- src/libopensc/compression.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index dd2ea4eefc..35a0b6846e 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -200,9 +200,13 @@ static int sc_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size bufferSize += num + blockSize; } if(err == Z_STREAM_END) { - buf = realloc(buf, *outLen); /* Shrink it down, if it fails, just use old data */ - if(buf) { - *out = buf; + if (*outLen) { + buf = realloc(buf, *outLen); /* Shrink it down, if it fails, just use old data */ + if(buf) { + *out = buf; + } + } else { + *out = NULL; } break; } From 01d515a0260995c555d5c35bd9fd68c5ca317822 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 Jan 2019 09:25:05 +0100 Subject: [PATCH 0783/4321] fixed use of garbage value --- src/libopensc/card-asepcos.c | 1 + src/libopensc/card-gpk.c | 1 + src/libopensc/card-mcrd.c | 1 + src/libopensc/pkcs15-itacns.c | 3 +++ src/tools/sc-hsm-tool.c | 2 +- 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 48436e25f0..b366250b2e 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -273,6 +273,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path, /* check the current DF to avoid unnecessary re-selection of * the MF (as this might invalidate a security status) */ sc_path_t tpath; + memset(&tpath, 0, sizeof tpath); r = asepcos_get_current_df_path(card, &tpath); /* workaround: as opensc can't handle paths with file id diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 3bc3c0205d..4144057c12 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -596,6 +596,7 @@ gpk_select_file(sc_card_t *card, const sc_path_t *path, if ((path->len & 1) || path->len > sizeof(pathtmp)) return SC_ERROR_INVALID_ARGUMENTS; pathptr = pathtmp; + memset(pathtmp, 0, sizeof pathtmp); for (n = 0; n < path->len; n += 2) pathptr[n>>1] = (path->value[n] << 8)|path->value[n+1]; pathlen = path->len >> 1; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 11963fcc5d..662da9badc 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1093,6 +1093,7 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) if ((path->len & 1) || path->len > sizeof(pathtmp)) return SC_ERROR_INVALID_ARGUMENTS; + memset(pathtmp, 0, sizeof pathtmp); pathptr = pathtmp; for (n = 0; n < path->len; n += 2) pathptr[n >> 1] = diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 438bd52eae..911762640c 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -685,9 +685,12 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, */ if (cert_offset) { u8 certlen[3]; + memset(certlen, 0, sizeof certlen); r = loadFile(p15card, &path, certlen, sizeof(certlen)); LOG_TEST_RET(p15card->card->ctx, r, "Could not read certificate file"); + if (r < 3) + return SC_ERROR_INVALID_DATA; path.index = cert_offset; path.count = (certlen[1] << 8) + certlen[2]; /* If those bytes are 00, then we are probably dealing with an diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 9307ffd308..fe6d98dbe3 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1278,7 +1278,7 @@ static int wrap_with_tag(u8 tag, u8 *indata, size_t inlen, u8 **outdata, size_t if (inlen > 127) { do { nlc++; - } while (inlen >= (unsigned)(1 << (nlc << 3))); + } while (inlen >= (unsigned)(1 << ((unsigned)nlc << 3))); } *outlen = 2 + nlc + inlen; From 6fdb29a470d0721c31466b42109e885909559090 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 Jan 2019 09:38:15 +0100 Subject: [PATCH 0784/4321] fixed use of uninitialized values --- src/libopensc/card-authentic.c | 6 +++--- src/tools/opensc-explorer.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 2322bc94cb..99332e55d2 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -819,7 +819,7 @@ authentic_read_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest, ret_count = 0; - int rv = SC_SUCCESS; + int rv = SC_ERROR_INVALID_ARGUMENTS; LOG_FUNC_CALLED(ctx); sc_log(ctx, @@ -865,7 +865,7 @@ authentic_write_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest; - int rv = SC_SUCCESS; + int rv = SC_ERROR_INVALID_ARGUMENTS; LOG_FUNC_CALLED(ctx); sc_log(ctx, @@ -908,7 +908,7 @@ authentic_update_binary(struct sc_card *card, unsigned int idx, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; size_t sz, rest; - int rv = SC_SUCCESS; + int rv = SC_ERROR_INVALID_ARGUMENTS; LOG_FUNC_CALLED(ctx); sc_log(ctx, diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index a4edb88f29..0da867f597 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -490,6 +490,7 @@ static int do_ls(int argc, char **argv) u8 buf[256], *cur = buf; int r, count; + memset(buf, 0, sizeof buf); r = sc_lock(card); if (r == SC_SUCCESS) r = sc_list_files(card, buf, sizeof(buf)); From c858d4b3d122f349f1ba2b57098ed04160bdee5b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 Jan 2019 09:56:50 +0100 Subject: [PATCH 0785/4321] fixed argument checking --- src/libopensc/pkcs15-cert.c | 6 ++++-- src/tools/cardos-tool.c | 5 +++++ src/tools/piv-tool.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 6ee3e48646..5a05d14c04 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -284,8 +284,10 @@ sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert, } else { *ext_val_len = MIN(*ext_val_len, val_len); - memcpy(*ext_val, val, *ext_val_len); - free(val); + if (val) { + memcpy(*ext_val, val, *ext_val_len); + free(val); + } } if (is_critical) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 61232f706d..7848885fc4 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -853,6 +853,11 @@ static int cardos_change_startkey(const char *change_startkey_apdu) u8 rbuf[256]; int r; + if (!change_startkey_apdu) { + printf("Missing change StartKey, aborting\n"); + return 1; + } + if (verbose) { printf ("Change StartKey APDU:\n"); util_hex_dump_asc(stdout, (unsigned char *)change_startkey_apdu, diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b4a7f17fd9..151022681c 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -262,7 +262,7 @@ static int admin_mode(const char* admin_info) size_t buflen = 2; - if (strlen(admin_info) == 7 && + if (admin_info && strlen(admin_info) == 7 && (admin_info[0] == 'A' || admin_info[0] == 'M') && admin_info[1] == ':' && (sc_hex_to_bin(admin_info+2, opts+1, &buflen) == 0) && From f4fccfd94e9ba187e606a29900b41bd1581a22f3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 28 Jan 2019 16:54:28 +0100 Subject: [PATCH 0786/4321] fixed undefined bitshift --- src/tools/sc-hsm-tool.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index fe6d98dbe3..b9ece5ebb9 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1272,35 +1272,20 @@ static size_t determineLength(const u8 *tlv, size_t buflen) */ static int wrap_with_tag(u8 tag, u8 *indata, size_t inlen, u8 **outdata, size_t *outlen) { - int nlc = 0; - u8 *ptr; - - if (inlen > 127) { - do { - nlc++; - } while (inlen >= (unsigned)(1 << ((unsigned)nlc << 3))); - } + int r = sc_asn1_put_tag(tag, indata, inlen, NULL, 0, NULL); + if (r < 0) + return r; + if (r == 0) + return SC_ERROR_INVALID_ASN1_OBJECT; - *outlen = 2 + nlc + inlen; - ptr = malloc(*outlen); + u8 *ptr = calloc(r, sizeof *ptr); if (ptr == NULL) { return SC_ERROR_OUT_OF_MEMORY; } - *outdata = ptr; - *ptr++ = tag; - - if (nlc) { - *ptr++ = 0x80 | nlc; - while (nlc--) { - *ptr++ = (inlen >> (nlc << 3)) & 0xFF; - } - } else { - *ptr++ = inlen & 0x7F; - } + *outlen = r; - memcpy(ptr, indata, inlen); - return SC_SUCCESS; + return sc_asn1_put_tag(tag, indata, inlen, *outdata, *outlen, NULL); } From 6e48de83c7a39ae09eac17be4e7ff4ff5488be19 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Jan 2019 11:12:07 +0100 Subject: [PATCH 0787/4321] avoid allocation of 0 bytes --- src/libopensc/card-oberthur.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 9c866e7f0d..0d4103ded0 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2120,6 +2120,8 @@ auth_read_binary(struct sc_card *card, unsigned int offset, for (jj=0; jj Date: Tue, 29 Jan 2019 11:20:14 +0100 Subject: [PATCH 0788/4321] fixed sc_decompress_zlib_alloc return code --- src/libopensc/compression.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index 35a0b6846e..0ec4e1d0ba 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -181,7 +181,7 @@ static int sc_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size if(*out) free(*out); *out = NULL; - return Z_MEM_ERROR; + return SC_ERROR_OUT_OF_MEMORY; } *out = buf; gz.next_out = buf + *outLen; From 1a61ae849f47053eb978e0b496696266e3428d36 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Jan 2019 11:26:14 +0100 Subject: [PATCH 0789/4321] fixed Null pointer argument in call to memcpy --- src/libopensc/card-cac1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 8513a30e03..90495a7a78 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -190,7 +190,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* OK we've read the data, now copy the required portion out to the callers buffer */ priv->cached = 1; len = MIN(count, priv->cache_buf_len-idx); - memcpy(buf, &priv->cache_buf[idx], len); + if (len && priv->cache_buf) + memcpy(buf, &priv->cache_buf[idx], len); r = len; done: if (val) From 20daced60575c508c81b3fbb3ea2209b138b71f7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Jan 2019 11:30:22 +0100 Subject: [PATCH 0790/4321] fixed special case of deletion in gnuk_write_certificate --- src/libopensc/card-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7ea3f7cd56..8173de7711 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1736,7 +1736,7 @@ gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* Check response */ - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Certificate writing failed"); + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } /* Ref: gnuk_put_binary_libusb.py and gnuk_token.py in Gnuk source tree */ From 7271fe610b341ab2f9f56eaf0f9eaef48b8e0e78 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 18 Feb 2019 16:03:41 +0100 Subject: [PATCH 0791/4321] Add support for the OpenSsl signature format for the signature verification. --- src/tools/pkcs11-tool.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1ba69d135e..31c5de9efe 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1946,6 +1946,42 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, close(fd2); + if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || + opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || + opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { + if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || + !strcmp(opt_sig_format, "sequence"))) { + + CK_BYTE* bytes; + CK_ULONG len; + size_t rs_len = 0; + unsigned char rs_buffer[512]; + bytes = getEC_POINT(session, key, &len); + free(bytes); + /* + * (We only support uncompressed for now) + * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" + * So a "256" bit key has x and y of 32 bytes each + * something like: "04 41 04||x||y" + * Do simple size calculation based on DER encoding + */ + if ((len - 2) <= 127) + rs_len = len - 3; + else if ((len - 3) <= 255) + rs_len = len - 4; + else + util_fatal("Key not supported"); + + if (sc_asn1_sig_value_sequence_to_rs(NULL, sig_buffer, r2, + rs_buffer, rs_len)) { + util_fatal("Failed to convert ASN.1 signature"); + } + + memcpy(sig_buffer, rs_buffer, rs_len); + r2 = rs_len; + } + } + /* Open the data file */ if (opt_input == NULL) fd = 0; From f3e6639de6655a9d3b8dbd80ba8abe960f0320f8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 Jan 2019 10:10:34 +0100 Subject: [PATCH 0792/4321] added GoID CVCA --- etc/DESCHSMCVCA00001 | Bin 0 -> 445 bytes etc/Makefile.am | 2 +- win32/OpenSC.wxs.in | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 etc/DESCHSMCVCA00001 diff --git a/etc/DESCHSMCVCA00001 b/etc/DESCHSMCVCA00001 new file mode 100644 index 0000000000000000000000000000000000000000..2848cd2be87cb671fdfbae6049d6752fe87a62a4 GIT binary patch literal 445 zcmb}UW4hV`CJjIwN8EDZGw>`Xww+^Def zclhmv?^f=yOXHd_x4E|{&-$D4RW$_-1z`_a`MlurCWYE4&eA_R2I23%l^Qr!{eS+u zA@rcyotT`LUfwRB4YuBFRzT+MzFxC`YKxd=%=d@qvd`R+_}|06t;Lb0`_j6dr|ZH` z>v((U|7qO5e&;>)hmZFvAF^@@-aG4@QBp|V57Wc9j{Kee!%a#gQTF7aa#vy9w|yZo zvLVOySu&@$qC2#($Fgei*2HDsC&=+NP4@^}-sZ@{chljQZ5Ss*n54*S6R(Cg*^lR| zZ!7K>{xad@eIvY>CG*zpM~thRj{jVAJ6Ly%J5yY=-W29`M#gvr z%s}%IVB^+iV`O1$JS@-5$QaCcAYPS?k)45^nK534jhO+=Fn7?GO{_CxPRKV3HZ(uJ z_0~kAE>kV*{}M-MGjF~4ap6NBhNDvt9$z-=fW?$Q`CF_O?0)ZkRO!#vtvQ!Jhqm&3 HQFH(R(Ez%? literal 0 HcmV?d00001 diff --git a/etc/Makefile.am b/etc/Makefile.am index cc368b6cc3..e999da774c 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,4 +1,4 @@ -CV_CERTS = DESRCACC100001 +CV_CERTS = DESRCACC100001 DESCHSMCVCA00001 MAINTAINERCLEANFILES = $(srcdir)/Makefile.in DISTCLEANFILES = opensc.conf.example diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 754eb617c0..6154e85aa0 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -304,6 +304,9 @@ + + + @@ -342,6 +345,7 @@ + From 155b197932fc1cf99d488f6ec91de6273511f19e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 5 Mar 2019 13:45:42 +0100 Subject: [PATCH 0793/4321] sc-hsm: require T=1 connection --- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/card-sc-hsm.h | 5 +++++ src/libopensc/reader-pcsc.c | 28 ++++++++++++++++++++-------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index ac4d1e9a64..eee3cd49cc 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -60,7 +60,7 @@ struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02 /* Known ATRs for SmartCard-HSMs */ -static const struct sc_atr_table sc_hsm_atrs[] = { +const struct sc_atr_table sc_hsm_atrs[] = { /* standard version */ {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, diff --git a/src/libopensc/card-sc-hsm.h b/src/libopensc/card-sc-hsm.h index c9b3281572..da57c1c0d0 100644 --- a/src/libopensc/card-sc-hsm.h +++ b/src/libopensc/card-sc-hsm.h @@ -21,6 +21,9 @@ #ifndef SC_HSM_H_ #define SC_HSM_H_ +#include "pkcs15.h" +#include "internal.h" + #define MAX_EXT_APDU_LENGTH 1014 #define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */ @@ -125,4 +128,6 @@ void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc); int sc_pkcs15emu_sc_hsm_get_curve(struct ec_curve **curve, u8 *oid, size_t oidlen); int sc_pkcs15emu_sc_hsm_get_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey); +/* Known ATRs for SmartCard-HSMs */ +extern const struct sc_atr_table sc_hsm_atrs[]; #endif /* SC_HSM_H_ */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c362bc5be8..c905c3f3f8 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -39,6 +39,7 @@ #include "common/libscdl.h" #include "internal.h" #include "internal-winscard.h" +#include "card-sc-hsm.h" #include "pace.h" @@ -430,7 +431,7 @@ static int pcsc_detect_card_presence(sc_reader_t *reader) static int check_forced_protocol(sc_reader_t *reader, DWORD *protocol) { scconf_block *atrblock = NULL; - int ok = 0; + int forced = 0; atrblock = _sc_match_atr_block(reader->ctx, NULL, &reader->atr); if (atrblock != NULL) { @@ -439,26 +440,37 @@ static int check_forced_protocol(sc_reader_t *reader, DWORD *protocol) forcestr = scconf_get_str(atrblock, "force_protocol", "unknown"); if (!strcmp(forcestr, "t0")) { *protocol = SCARD_PROTOCOL_T0; - ok = 1; + forced = 1; } else if (!strcmp(forcestr, "t1")) { *protocol = SCARD_PROTOCOL_T1; - ok = 1; + forced = 1; } else if (!strcmp(forcestr, "raw")) { *protocol = SCARD_PROTOCOL_RAW; - ok = 1; + forced = 1; } - if (ok) + if (forced) sc_log(reader->ctx, "force_protocol: %s", forcestr); } - if (!ok && reader->uid.len) { + if (!forced && reader->uid.len) { /* We identify contactless cards by their UID. Communication * defined by ISO/IEC 14443 is identical to T=1. */ *protocol = SCARD_PROTOCOL_T1; - ok = 1; + forced = 1; } - return ok; + if (!forced) { + sc_card_t card; + memset(&card, 0, sizeof card); + card.ctx = reader->ctx; + card.atr = reader->atr; + if (0 <= _sc_match_atr(&card, sc_hsm_atrs, NULL)) { + *protocol = SCARD_PROTOCOL_T1; + forced = 1; + } + } + + return forced; } From 27526de0219f42a666eaadf1e484ea96a9ba8db9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 Jan 2019 07:35:58 +0100 Subject: [PATCH 0794/4321] implemented sc_format_apdu_ex --- src/libopensc/card.c | 57 +++++++++++++++++++ src/libopensc/iso7816.c | 7 +-- src/libopensc/libopensc.exports | 1 + src/libopensc/opensc.h | 4 ++ src/libopensc/types.h | 4 ++ src/sm/sm-eac.c | 99 +++++++++------------------------ src/tools/goid-tool.c | 9 +-- src/tools/npa-tool.c | 5 +- 8 files changed, 99 insertions(+), 87 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 51ecb2b7d0..423bc09a50 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -63,6 +63,63 @@ void sc_format_apdu(sc_card_t *card, sc_apdu_t *apdu, apdu->p2 = (u8) p2; } +void sc_format_apdu_cse_lc_le(struct sc_apdu *apdu) +{ + /* TODO calculating the APDU case, Lc and Le should actually only be + * done in sc_apdu2bytes, but to gradually change OpenSC we start here. */ + + if (!apdu) + return; + if (apdu->datalen > SC_MAX_APDU_DATA_SIZE + || apdu->resplen > SC_MAX_APDU_RESP_SIZE) { + /* extended length */ + if (apdu->datalen < SC_MAX_EXT_APDU_DATA_SIZE) + apdu->lc = apdu->datalen; + if (apdu->resplen < SC_MAX_EXT_APDU_RESP_SIZE) + apdu->le = apdu->resplen; + if (apdu->resplen && !apdu->datalen) + apdu->cse = SC_APDU_CASE_2_EXT; + if (!apdu->resplen && apdu->datalen) + apdu->cse = SC_APDU_CASE_3_EXT; + if (apdu->resplen && apdu->datalen) + apdu->cse = SC_APDU_CASE_4_EXT; + } else { + /* short length */ + if (apdu->datalen < SC_MAX_APDU_DATA_SIZE) + apdu->lc = apdu->datalen; + if (apdu->resplen < SC_MAX_APDU_RESP_SIZE) + apdu->le = apdu->resplen; + if (!apdu->resplen && !apdu->datalen) + apdu->cse = SC_APDU_CASE_1; + if (apdu->resplen && !apdu->datalen) + apdu->cse = SC_APDU_CASE_2_SHORT; + if (!apdu->resplen && apdu->datalen) + apdu->cse = SC_APDU_CASE_3_SHORT; + if (apdu->resplen && apdu->datalen) + apdu->cse = SC_APDU_CASE_4_SHORT; + } +} + +void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, + u8 ins, u8 p1, u8 p2, u8 *data, size_t datalen, u8 *resp, size_t resplen) +{ + if (!apdu) { + return; + } + + memset(apdu, 0, sizeof(*apdu)); + if (card) + apdu->cla = (u8) card->cla; + apdu->ins = ins; + apdu->p1 = p1; + apdu->p2 = p2; + apdu->resp = resp; + apdu->resplen = resplen; + apdu->data = data; + apdu->datalen = datalen; + sc_format_apdu_cse_lc_le(apdu); +} + static sc_card_t * sc_card_new(sc_context_t *ctx) { sc_card_t *card; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 44d39edbc7..47f5053fe2 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -147,10 +147,7 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun return SC_ERROR_OFFSET_TOO_LARGE; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF); - apdu.le = count; - apdu.resplen = count; - apdu.resp = buf; + sc_format_apdu_ex(card, &apdu, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF, NULL, 0, buf, count); fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); @@ -1501,7 +1498,7 @@ int iso7816_logout(sc_card_t *card, unsigned char pin_reference) int r; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0xFF, pin_reference); + sc_format_apdu_ex(card, &apdu, 0x20, 0xFF, pin_reference, NULL, 0, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 4e7dc4a70d..8157f30e36 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -109,6 +109,7 @@ sc_file_set_type_attr sc_file_set_content sc_file_valid sc_format_apdu +sc_format_apdu_ex sc_bytes2apdu sc_format_asn1_entry sc_format_oid diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 050244b17b..bbf0ea191a 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -813,6 +813,10 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); void sc_format_apdu(struct sc_card *, struct sc_apdu *, int, int, int, int); +void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, + u8 ins, u8 p1, u8 p2, + u8 *data, size_t datalen, u8 *resp, size_t resplen); + int sc_check_apdu(struct sc_card *, const struct sc_apdu *); /** Transforms an APDU from binary to its @c sc_apdu_t representation diff --git a/src/libopensc/types.h b/src/libopensc/types.h index ea352e91a2..ab5cbded30 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -32,7 +32,11 @@ typedef unsigned char u8; #define SC_MAX_CARD_DRIVER_SNAME_SIZE 16 #define SC_MAX_CARD_APPS 8 #define SC_MAX_APDU_BUFFER_SIZE 261 /* takes account of: CLA INS P1 P2 Lc [255 byte of data] Le */ +#define SC_MAX_APDU_DATA_SIZE 0xFF +#define SC_MAX_APDU_RESP_SIZE (0xFF+1) #define SC_MAX_EXT_APDU_BUFFER_SIZE 65538 +#define SC_MAX_EXT_APDU_DATA_SIZE 0xFFFF +#define SC_MAX_EXT_APDU_RESP_SIZE (0xFFFF+1) #define SC_MAX_PIN_SIZE 256 /* OpenPGP card has 254 max */ #define SC_MAX_ATR_SIZE 33 #define SC_MAX_UID_SIZE 10 diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 69718758f0..88f670a18a 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -249,8 +249,6 @@ IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R) -#define maxresp SC_MAX_APDU_BUFFER_SIZE - 2 - /** @brief NPA secure messaging context */ struct eac_sm_ctx { /** @brief EAC context */ @@ -521,8 +519,6 @@ static int eac_mse(sc_card_t *card, r = SC_ERROR_INVALID_ARGUMENTS; goto err; } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ISO_MSE, p1, p2); r = format_mse_cdata(card->ctx, protocol, key_reference1, key_reference1_len, key_reference2, key_reference2_len, @@ -530,10 +526,8 @@ static int eac_mse(sc_card_t *card, chat, &d); if (r < 0) goto err; - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; - + sc_format_apdu_ex(card, &apdu, ISO_MSE, p1, p2, + d, r, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -618,11 +612,7 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; - unsigned char resp[maxresp]; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, - 0x00, 0x00); - apdu.cla = ISO_COMMAND_CHAINING; + unsigned char resp[SC_MAX_EXT_APDU_RESP_SIZE]; c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { @@ -635,14 +625,13 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; + + sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + d, r, resp, sizeof resp); + apdu.cla = ISO_COMMAND_CHAINING; sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen); - apdu.resplen = sizeof resp; - apdu.resp = resp; r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -702,11 +691,7 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; - unsigned char resp[maxresp]; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, - 0x00, 0x00); - apdu.cla = ISO_COMMAND_CHAINING; + unsigned char resp[SC_MAX_EXT_APDU_RESP_SIZE]; c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { @@ -727,14 +712,12 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; + sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + d, r, resp, sizeof resp); + apdu.cla = ISO_COMMAND_CHAINING; sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen); - apdu.resplen = sizeof resp; - apdu.resp = resp; r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -794,11 +777,7 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; - unsigned char resp[maxresp]; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, - 0x00, 0x00); - apdu.cla = ISO_COMMAND_CHAINING; + unsigned char resp[SC_MAX_EXT_APDU_RESP_SIZE]; c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { @@ -819,14 +798,12 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; + sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + d, r, resp, sizeof resp); + apdu.cla = ISO_COMMAND_CHAINING; sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - apdu.resplen = sizeof resp; - apdu.resp = resp; r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -888,10 +865,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, EAC_GEN_AUTH_PACE_R *r_data = NULL; unsigned char *d = NULL, *p; int r, l; - unsigned char resp[maxresp]; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, - 0x00, 0x00); + unsigned char resp[SC_MAX_EXT_APDU_RESP_SIZE]; c_data = EAC_GEN_AUTH_PACE_C_new(); if (!c_data) { @@ -912,14 +886,12 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; + + sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + d, r, resp, sizeof resp); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - apdu.resplen = sizeof resp; - apdu.resp = resp; r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -1420,10 +1392,7 @@ static int eac_get_challenge(sc_card_t *card, goto err; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); - apdu.le = len; - apdu.resplen = len; - apdu.resp = challenge; + sc_format_apdu_ex(card, &apdu, 0x84, 0x00, 0x00, NULL, 0, challenge, len); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1449,17 +1418,14 @@ static int eac_verify(sc_card_t *card, goto err; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, 0x2A, 0x00, 0xbe); - - apdu.data = cert; - if (0x80 & ASN1_get_object(&apdu.data, &length, &tag, &class, cert_len)) { + if (0x80 & ASN1_get_object(&cert, &length, &tag, &class, cert_len)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error decoding Certificate"); ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } - apdu.datalen = length; - apdu.lc = length; + + sc_format_apdu_ex(card, &apdu, 0x2A, 0x00, 0xbe, (unsigned char *) cert, length, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1483,11 +1449,7 @@ static int eac_external_authenticate(sc_card_t *card, goto err; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00); - - apdu.data = signature; - apdu.datalen = signature_len; - apdu.lc = signature_len; + sc_format_apdu_ex(card, &apdu, 0x82, 0x00, 0x00, signature, signature_len, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1702,10 +1664,7 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, EAC_GEN_AUTH_CA_R *r_data = NULL; unsigned char *d = NULL; int r; - unsigned char resp[maxresp]; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, ISO_GENERAL_AUTHENTICATE, - 0, 0); + unsigned char resp[SC_MAX_EXT_APDU_RESP_SIZE]; c_data = EAC_GEN_AUTH_CA_C_new(); if (!c_data) { @@ -1727,14 +1686,10 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, r = SC_ERROR_INTERNAL; goto err; } - apdu.data = d; - apdu.datalen = r; - apdu.lc = r; + sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0, 0, d, r, resp, sizeof resp); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - apdu.resplen = sizeof resp; - apdu.resp = resp; r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -2476,7 +2431,7 @@ int eac_pace_get_tries_left(sc_card_t *card, r = eac_mse_set_at_pace(card, 0, pin_id, 0, &sw1, &sw2); #else sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ISO_MSE, 0xC1, 0xA4); + sc_format_apdu_ex(card, &apdu, ISO_MSE, 0xC1, 0xA4, NULL, 0, NULL, 0); r = sc_transmit_apdu(card, &apdu); sw1 = apdu.sw1; sw2 = apdu.sw2; diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 6d19e7e489..355ce1a592 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -114,11 +114,8 @@ soc_info(sc_context_t *ctx, sc_card_t *card) { NULL , 0 , 0 , 0 , NULL , NULL } }; - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x61, 0x00, 0x00); - + sc_format_apdu_ex(card, &apdu, 0x61, 0x00, 0x00, NULL, 0, rbuf, sizeof rbuf); apdu.cla = 0x80; - apdu.resp = rbuf; - apdu.resplen = sizeof rbuf; if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { return; @@ -239,7 +236,7 @@ soc_verify(sc_card_t *card, unsigned char p2) { int ok = 0; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, p2); + sc_format_apdu_ex(card, &apdu, 0x20, 0x00, p2, NULL, 0, NULL, 0); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_transmit_apdu(card, &apdu), "Verification failed"); @@ -275,7 +272,7 @@ soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) { int ok = 0; sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, p1, p2); + sc_format_apdu_ex(card, &apdu, 0x24, p1, p2, NULL, 0, NULL, 0); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_transmit_apdu(card, &apdu), "Changing secret failed"); diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 91bf6489c3..08916eac66 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -156,11 +156,8 @@ static void verify(sc_card_t *card, const char *verify_str, sc_apdu_t apdu; int r; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ISO_VERIFY, 0x80, 0); + sc_format_apdu_ex(card, &apdu, ISO_VERIFY, 0x80, 0, data, data_len, NULL, 0); apdu.cla = 0x80; - apdu.data = data; - apdu.datalen = data_len; - apdu.lc = data_len; r = sc_transmit_apdu(card, &apdu); if (r < 0) From b1a58c7925d586c149b9bba943cc520876258da3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:11:48 +0100 Subject: [PATCH 0795/4321] removed dead code --- src/tools/goid-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 355ce1a592..3fc1be289a 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -52,7 +52,7 @@ print_permissions(u8 permissions) { size_t perms_printed = 0; if (permissions & SOCM_AUTHOBJECT_PIN) { - printf("%s PIN", perms_printed ? " or" : "verification of"); + printf("verification of PIN"); perms_printed++; } if (permissions & SOCM_AUTHOBJECT_BIO) { @@ -175,7 +175,7 @@ soc_info(sc_context_t *ctx, sc_card_t *card) /* i now counts the number of flags that were printed */ i = 0; if (tag & 0x02) { - printf("%sdefault selected", i ? ", " : ""); + printf("default selected"); i++; } if (tag & 0x01) { From e876cf62eb8955e93c76fe4083ed8a8d30aa27f8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:13:52 +0100 Subject: [PATCH 0796/4321] fixed 333711 Dereference before null check --- src/tools/gids-tool.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index ee2051cef6..63380e9a71 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -587,8 +587,7 @@ int main(int argc, char * argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; From 9abe44f03c1e0eaea5010350bf22f09d41bab797 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:17:55 +0100 Subject: [PATCH 0797/4321] fixed 333715 Dereference after null check --- src/tools/pkcs15-crypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index b9ba591aa4..6d064ec317 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -346,7 +346,7 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) * a crypto operation. Card drivers can test for SC_AC_CONTEXT_SPECIFIC * to do any special handling. */ - if (key->user_consent && pin && pin->data) { + if (key->user_consent) { int auth_meth_saved; struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) pin->data; From e8f8f0bfbb197e488817cd75574ee068b7d870d6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:31:38 +0100 Subject: [PATCH 0798/4321] fixed 333714 Uninitialized scalar variable --- src/libopensc/card-openpgp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 8173de7711..cce2c96669 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1640,10 +1640,10 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) LOG_TEST_RET(card->ctx, r, "error getting elements"); /* RSA */ - if ((r = pgp_get_blob(card, blob, 0x0081, &mod_blob)) == 0 - && (r = pgp_get_blob(card, blob, 0x0082, &exp_blob)) == 0 - && (r = pgp_read_blob(card, mod_blob)) == 0 - && (r = pgp_read_blob(card, exp_blob)) == 0) { + if ((r = pgp_get_blob(card, blob, 0x0081, &mod_blob)) >= 0 + && (r = pgp_get_blob(card, blob, 0x0082, &exp_blob)) >= 0 + && (r = pgp_read_blob(card, mod_blob)) >= 0 + && (r = pgp_read_blob(card, exp_blob)) >= 0) { memset(&pubkey, 0, sizeof(pubkey)); @@ -1654,8 +1654,8 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) pubkey.u.rsa.exponent.len = exp_blob->len; } /* ECC */ - else if ((r = pgp_get_blob(card, blob, 0x0086, &pubkey_blob)) == 0 - && (r = pgp_read_blob(card, pubkey_blob)) == 0) { + else if ((r = pgp_get_blob(card, blob, 0x0086, &pubkey_blob)) >= 0 + && (r = pgp_read_blob(card, pubkey_blob)) >= 0) { memset(&pubkey, 0, sizeof(pubkey)); From ba185954c5bc3c4f169d8f3bffaa5961abf4881e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:34:31 +0100 Subject: [PATCH 0799/4321] fixed 333709 Unchecked return value --- src/tools/pkcs11-tool.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fe1667d569..3c0572d4bc 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4615,9 +4615,12 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, if (!md_ctx) err = -1; else { - EVP_VerifyInit(md_ctx, evp_mds[evp_md_index]); - EVP_VerifyUpdate(md_ctx, verifyData, verifyDataLen); - err = EVP_VerifyFinal(md_ctx, sig1, sigLen1, pkey); + if (EVP_VerifyInit(md_ctx, evp_mds[evp_md_index]) + && EVP_VerifyUpdate(md_ctx, verifyData, verifyDataLen)) { + err = EVP_VerifyFinal(md_ctx, sig1, sigLen1, pkey); + } else { + err = -1; + } EVP_MD_CTX_destroy(md_ctx); EVP_PKEY_free(pkey); } From 8fbd0b3ee171b4436978897f8e837705cc2cfd9e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:37:01 +0100 Subject: [PATCH 0800/4321] fixed 333708 Dereference after null check --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index c7c8f1b681..09b2e456f0 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1453,7 +1453,7 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf /* Find out framework data corresponding to the given application */ fw_data = get_fw_data(p11card, app_info, &idx); - if (!fw_data) { + if (!fw_data && p11card) { sc_log(context, "Create slot for the non-binded card"); pkcs15_create_slot(p11card, NULL, NULL, app_info, &slot); return CKR_OK; From 070370895f7d918b9c1f2882a492454676b6d254 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 00:39:53 +0100 Subject: [PATCH 0801/4321] fixed 333707 Dereference before null check --- src/tools/cardos-tool.c | 3 +-- src/tools/cryptoflex-tool.c | 3 +-- src/tools/dnie-tool.c | 3 +-- src/tools/iasecc-tool.c | 3 +-- src/tools/opensc-tool.c | 7 ++----- src/tools/piv-tool.c | 3 +-- src/tools/pkcs15-tool.c | 9 +++------ src/tools/sc-hsm-tool.c | 7 ++----- 8 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 7848885fc4..f35c99e285 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1132,7 +1132,6 @@ int main(int argc, char *argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); return err; } diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 6a910f9b50..b0cd6edee2 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -1117,7 +1117,6 @@ int main(int argc, char *argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); return err; } diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index 660d90bad2..d788cd8caa 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -232,8 +232,7 @@ int main(int argc, char* argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); return err; } diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index b12a5f1886..11a68b847c 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -288,8 +288,7 @@ int main(int argc, char *argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); return err; } diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 88250de473..81b9af0fbc 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -909,10 +909,7 @@ int main(int argc, char *argv[]) action_count--; } end: - if (card) { - sc_disconnect_card(card); - } - if (ctx) - sc_release_context(ctx); + sc_disconnect_card(card); + sc_release_context(ctx); return err; } diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 151022681c..49d6d909a2 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -662,8 +662,7 @@ int main(int argc, char *argv[]) sc_unlock(card); sc_disconnect_card(card); } - if (ctx) - sc_release_context(ctx); + sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 4f81b10c83..086492027b 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2427,11 +2427,8 @@ int main(int argc, char *argv[]) action_count--; } end: - if (p15card) - sc_pkcs15_unbind(p15card); - if (card) - sc_disconnect_card(card); - if (ctx) - sc_release_context(ctx); + sc_pkcs15_unbind(p15card); + sc_disconnect_card(card); + sc_release_context(ctx); return err; } diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index b9ece5ebb9..a9d982b8dc 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1844,11 +1844,8 @@ int main(int argc, char *argv[]) fail: err = 1; end: - if (card) { - sc_disconnect_card(card); - } - if (ctx) - sc_release_context(ctx); + sc_disconnect_card(card); + sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; From 19c5ab315d5b5ff9a2cb5e1a25cd32998a7bf72a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 08:53:47 +0100 Subject: [PATCH 0802/4321] fixed uninitialized use of variable --- src/pkcs11/framework-pkcs15.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 09b2e456f0..bf27516ade 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1453,9 +1453,11 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf /* Find out framework data corresponding to the given application */ fw_data = get_fw_data(p11card, app_info, &idx); - if (!fw_data && p11card) { - sc_log(context, "Create slot for the non-binded card"); - pkcs15_create_slot(p11card, NULL, NULL, app_info, &slot); + if (!fw_data) { + if (p11card) { + sc_log(context, "Create slot for the non-binded card"); + pkcs15_create_slot(p11card, NULL, NULL, app_info, &slot); + } return CKR_OK; } sc_log(context, "Use FW data with index %i; fw_data->p15_card %p", idx, fw_data->p15_card); From b327b76134b19e2495e01abce47ca1aef2d32034 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Wed, 6 Mar 2019 10:26:05 +0100 Subject: [PATCH 0803/4321] FIX use pseudo_randomize() for a proper initialization of orig_data in encrypt_decrypt(). --- src/tools/pkcs11-tool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 31c5de9efe..a46cf8ee79 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5287,7 +5287,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject) { EVP_PKEY *pkey; - unsigned char orig_data[512] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'}; + unsigned char orig_data[512]; unsigned char encrypted[512], data[512]; CK_MECHANISM mech; CK_ULONG encrypted_len, data_len; @@ -5300,6 +5300,8 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf(" %s: ", p11_mechanism_to_name(mech_type)); + pseudo_randomize(orig_data, sizeof(orig_data)); + pkey = get_public_key(session, privKeyObject); if (pkey == NULL) return 0; From 728d099a536ab1923a217ae00408f72aa0b8ecee Mon Sep 17 00:00:00 2001 From: alegon01 Date: Wed, 6 Mar 2019 11:35:11 +0100 Subject: [PATCH 0804/4321] FIX typo OpenSSL vs OpenSsl. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a46cf8ee79..dfdd170a33 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5418,7 +5418,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } #else if (hash_alg != CKM_SHA_1) { - printf("This version of OpenSsl only supports SHA1 for OAEP, returning\n"); + printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n"); return 0; } #endif From 0d7967549751b7032f22b437106b41444aff0ba9 Mon Sep 17 00:00:00 2001 From: Scott Gayou Date: Fri, 1 Mar 2019 13:11:06 -0600 Subject: [PATCH 0805/4321] Small memory leak fix (CVE-2019-6502 in #1586) CVE-2019-6502 was assigned to what appears to be a very minor memory leak that only occurs on an error-case in a CLI tool. If util_connect_card fails, we still need to release the sc context previously allocated by sc_context_create else memory will leak. --- src/tools/eidenv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index d8a7be62e4..d96ad4e742 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -403,6 +403,7 @@ int main(int argc, char **argv) r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); if (r) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); + sc_release_context(ctx); return 1; } From b227fb8b9fd5cc44df741c013751a3fc6a559236 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 4 Feb 2019 10:45:03 +0200 Subject: [PATCH 0806/4321] Cleanup EstEID 1.0/1.1 lefovers Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 54 +++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 662da9badc..b835e030c9 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -331,39 +331,33 @@ static int mcrd_init(sc_card_t * card) if (is_esteid_card(card)) { /* Select the EstEID AID to get to a known state. * For some reason a reset is required as well... */ - if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) { - sc_reset(card, 0); - - r = gp_select_aid(card, &EstEID_v3_AID); - if (r < 0) - { - r = gp_select_aid(card, &EstEID_v35_AID); - if (r >= 0) { - // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary - // sc_read_binary cannot handle recursive 61 00 calls - if (card->reader && card->reader->active_protocol == SC_PROTO_T0) - card->max_recv_size = 255; - } else { - r = gp_select_aid(card, &AzeDIT_v35_AID); - if (r < 0) { - free(card->drv_data); - card->drv_data = NULL; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); - } + sc_reset(card, 0); + + r = gp_select_aid(card, &EstEID_v3_AID); + if (r < 0) + { + r = gp_select_aid(card, &EstEID_v35_AID); + if (r >= 0) { + // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary + // sc_read_binary cannot handle recursive 61 00 calls + if (card->reader && card->reader->active_protocol == SC_PROTO_T0) + card->max_recv_size = 255; + } else { + r = gp_select_aid(card, &AzeDIT_v35_AID); + if (r < 0) { + free(card->drv_data); + card->drv_data = NULL; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); } } - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; - /* EstEID v3.0 has 2048 bit keys */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - - flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); - } else { - /* EstEID v1.0 and 1.1 have 1024 bit keys */ - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; - _sc_card_add_rsa_alg(card, 1024, flags, 0); } + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; + /* EstEID v3.0 has 2048 bit keys */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); } else { flags = SC_ALGORITHM_RSA_RAW |SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; _sc_card_add_rsa_alg(card, 512, flags, 0); From 9e9bdac2f16f5c7ba6cda1cc29b3420702a10d03 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 28 Feb 2019 15:53:54 +0100 Subject: [PATCH 0807/4321] Handle reader going missing It might just be this specific reader going missing, and not all of them. --- src/libopensc/reader-pcsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c905c3f3f8..eddcc8d293 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -341,8 +341,8 @@ static int refresh_attributes(sc_reader_t *reader) LOG_FUNC_RETURN(reader->ctx, SC_SUCCESS); } - /* the system could not dectect any reader. It means, the prevoiusly attached reader is disconnected. */ - if (rv == (LONG)SCARD_E_NO_READERS_AVAILABLE || rv == (LONG)SCARD_E_SERVICE_STOPPED) { + /* the system could not detect the reader. It means, the prevoiusly attached reader is disconnected. */ + if (rv == (LONG)SCARD_E_UNKNOWN_READER || rv == (LONG)SCARD_E_NO_READERS_AVAILABLE || rv == (LONG)SCARD_E_SERVICE_STOPPED) { if (old_flags & SC_READER_CARD_PRESENT) { reader->flags |= SC_READER_CARD_CHANGED; } From 9ed5f63c175bf30e49500cecff97e7bb0a8d164b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Mar 2019 15:45:29 +0100 Subject: [PATCH 0808/4321] Fix smart card removal handling for older PC/SC Older PC/SC doesn't have the code SCARD_E_NO_READERS_AVAILABLE, so fix the code to handle such systems as well. --- src/libopensc/reader-pcsc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index eddcc8d293..94285448c5 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -342,7 +342,12 @@ static int refresh_attributes(sc_reader_t *reader) } /* the system could not detect the reader. It means, the prevoiusly attached reader is disconnected. */ - if (rv == (LONG)SCARD_E_UNKNOWN_READER || rv == (LONG)SCARD_E_NO_READERS_AVAILABLE || rv == (LONG)SCARD_E_SERVICE_STOPPED) { + if ( +#ifdef SCARD_E_NO_READERS_AVAILABLE + (rv == (LONG)SCARD_E_NO_READERS_AVAILABLE) || +#endif + (rv == (LONG)SCARD_E_UNKNOWN_READER) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) { + if (old_flags & SC_READER_CARD_PRESENT) { reader->flags |= SC_READER_CARD_CHANGED; } From bc4eeda5737dbd74f7c48d437f70c4f9c927406f Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Mar 2019 15:46:09 +0100 Subject: [PATCH 0809/4321] Remove readers when smart card service stops The code already removes all active cards when the service goes away, but it doesn't remove the reader. This can be a bit confusing since they will still be polled and listed. --- src/libopensc/reader-pcsc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 94285448c5..a058c71f7b 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1351,6 +1351,29 @@ static int pcsc_detect_readers(sc_context_t *ctx) } else { rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, (LPDWORD) &reader_buf_size); + + /* + * All readers have disappeared, so mark them as + * such so we don't keep polling them over and over. + */ + if ( +#ifdef SCARD_E_NO_READERS_AVAILABLE + (rv == (LONG)SCARD_E_NO_READERS_AVAILABLE) || +#endif + (rv == (LONG)SCARD_E_NO_SERVICE) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) { + + for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { + sc_reader_t *reader = sc_ctx_get_reader(ctx, i); + + if (!reader) { + ret = SC_ERROR_INTERNAL; + goto out; + } + + reader->flags |= SC_READER_REMOVED; + } + } + if ((rv == (LONG)SCARD_E_NO_SERVICE) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) { gpriv->SCardReleaseContext(gpriv->pcsc_ctx); gpriv->pcsc_ctx = 0; From 6472027848948a562fd9d02e6334e8b15dc9d396 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 19:54:35 +0100 Subject: [PATCH 0810/4321] tools: release context when card connection fails --- src/tools/cardos-tool.c | 2 +- src/tools/cryptoflex-tool.c | 2 ++ src/tools/iasecc-tool.c | 2 +- src/tools/openpgp-tool.c | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index f35c99e285..cb292c51a4 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1127,7 +1127,7 @@ int main(int argc, char *argv[]) } action_count--; } - end: +end: if (card) { sc_unlock(card); sc_disconnect_card(card); diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index b0cd6edee2..2048871f26 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -1076,6 +1076,8 @@ int main(int argc, char *argv[]) } err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + if (err) + goto end; printf("Using card driver: %s\n", card->driver->name); if (do_create_pin_file) { diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 11a68b847c..645373e19f 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -251,7 +251,7 @@ int main(int argc, char *argv[]) if (err) goto end; - if (opt_bind_to_aid) { + if (opt_bind_to_aid) { struct sc_aid aid; aid.len = sizeof(aid.value); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 13a1057d65..3e4ce52779 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -876,6 +876,7 @@ int main(int argc, char **argv) r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { + sc_release_context(ctx); util_fatal("failed to connect to card: %s", sc_strerror(r)); return EXIT_FAILURE; } From f341b758e602f28047ee18ab253391d0896f157e Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 11 Feb 2019 12:14:41 +0200 Subject: [PATCH 0811/4321] Add installer option to deselect tokend Signed-off-by: Raul Metsma --- MacOSX/Distribution.xml.in | 21 +++++++++++---------- MacOSX/build-package.in | 5 +++-- MacOSX/opensc-uninstall | 5 ++--- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index fbd4b22cd9..c42f94c990 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -1,4 +1,7 @@ + @@ -6,17 +9,15 @@ @PACKAGE_STRING@ - - - + - - - + + - - - + + OpenSC.pkg + + + OpenSC-tokend.pkg - OpenSC.pkg diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 5f9af2f94f..e9db05f884 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -96,7 +96,7 @@ fi test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src # Build and copy OpenSC.tokend -xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target +xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend #if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then #if ! test -e terminal-notifier-1.7.1.zip; then @@ -112,7 +112,7 @@ xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Token if ! test -e NotificationProxy; then git clone http://github.com/frankmorgner/NotificationProxy.git fi -xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ +xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target_tokend/Library/Security/tokend/OpenSC.tokend/Contents/Resources/ mkdir -p "$BUILDPATH/target/Applications" osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" @@ -124,6 +124,7 @@ cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin # Build package pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg +pkgbuild --root ${BUILDPATH}/target_tokend --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg # Build product productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index d4331a9ad9..62b5b0fdbc 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -22,9 +22,8 @@ rm -rf /Library/Security/tokend/OpenSC.tokend rm -rf /System/Library/Security/tokend/OpenSC.tokend # delete receipts on 10.6+ -for file in /var/db/receipts/org.opensc-project.mac.bom /var/db/receipts/org.opensc-project.mac.plist; do - test -f $file && rm -f $file -done +pkgutil --forget org.opensc-project.mac > /dev/null +pkgutil --forget org.opensc-project.tokend > /dev/null # remove this script rm -f /usr/local/bin/opensc-uninstall From 31831c300be3d1fc6387ce221c069301ecb3c087 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Tue, 12 Mar 2019 08:52:06 +0100 Subject: [PATCH 0812/4321] Remove the call to OPENSSL_init_crypto() which is not needed. I have a segmentation fault when the process exits. --- src/tools/pkcs11-tool.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index dfdd170a33..b91a660bbd 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -583,14 +583,6 @@ int main(int argc, char * argv[]) #ifdef ENABLE_OPENSSL #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) OPENSSL_config(NULL); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS - | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS - | OPENSSL_INIT_LOAD_CONFIG, - NULL); -#else /* OpenSSL magic */ OpenSSL_add_all_algorithms(); OPENSSL_malloc_init(); From d953998aa314b648b6f0785f7e062ae80067c05b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 13 Mar 2019 11:53:52 +0100 Subject: [PATCH 0813/4321] npa-tool: force default card driver --- src/tools/npa-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 08916eac66..cca9839c34 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -384,6 +384,10 @@ main (int argc, char **argv) exit(1); } + r = sc_set_card_driver(ctx, "default"); + if (r) + goto err; + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); if (r) goto err; From d4f1decd1539652be58523f19b905316bd8090c7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 3 Mar 2019 15:52:57 +0100 Subject: [PATCH 0814/4321] Make sure card's strings are Nul terminated Avoids out of bounds reads when using internal operations with the given string --- src/libopensc/dir.c | 3 ++- src/libopensc/pkcs15-data.c | 4 +++- src/libopensc/pkcs15.c | 8 ++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index b6c9b646a6..895ad65a1c 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -65,12 +65,13 @@ parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, int rec_nr) sc_app_info_t *app = NULL; struct sc_aid aid; u8 label[128], path[128], ddo[128]; - size_t label_len = sizeof(label), path_len = sizeof(path), ddo_len = sizeof(ddo); + size_t label_len = sizeof(label) - 1, path_len = sizeof(path), ddo_len = sizeof(ddo); int r; LOG_FUNC_CALLED(ctx); aid.len = sizeof(aid.value); + memset(label, 0, sizeof(label)); sc_copy_asn1_entry(c_asn1_dirrecord, asn1_dirrecord); sc_copy_asn1_entry(c_asn1_dir, asn1_dir); sc_format_asn1_entry(asn1_dir + 0, asn1_dirrecord, NULL, 0); diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index b87ef5845d..636968acb3 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -100,9 +100,11 @@ int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card, asn1_data[2]; struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL, asn1_type_data_attr }; - size_t label_len = sizeof(info.app_label); + size_t label_len = sizeof(info.app_label) - 1; int r; + memset(info.app_label, 0, sizeof(info.app_label)); + sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr); sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr); sc_copy_asn1_entry(c_asn1_data, asn1_data); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 823b236b03..85e7ecc7b4 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -131,9 +131,9 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, u8 serial[128]; size_t serial_len = sizeof(serial); u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE]; - size_t mnfid_len = sizeof(mnfid); + size_t mnfid_len = sizeof(mnfid) - 1; u8 label[SC_PKCS15_MAX_LABEL_SIZE]; - size_t label_len = sizeof(label); + size_t label_len = sizeof(label) - 1; u8 last_update[32], profile_indication[SC_PKCS15_MAX_LABEL_SIZE]; size_t lupdate_len = sizeof(last_update) - 1, pi_len = sizeof(profile_indication) - 1; size_t flags_len = sizeof(ti->flags); @@ -153,6 +153,10 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE], asn1_tokeninfo[3], asn1_twlabel[3]; memset(last_update, 0, sizeof(last_update)); + memset(label, 0, sizeof(label)); + memset(profile_indication, 0, sizeof(profile_indication)); + memset(mnfid, 0, sizeof(mnfid)); + sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel); sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs); sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo); From eb8f28db201786b4bf9a03518a7af630d45b809b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 3 Mar 2019 21:20:44 +0100 Subject: [PATCH 0815/4321] fixed error handling --- src/libopensc/pkcs15-prkey.c | 7 +++++-- src/libopensc/pkcs15-pubkey.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index d3eee98356..9f9ac7e18a 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -713,8 +713,11 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) /* get curve name */ nid = EC_GROUP_get_curve_name(grp); - if(nid != 0) - dst->params.named_curve = strdup(OBJ_nid2sn(nid)); + if(nid != 0) { + const char *sn = OBJ_nid2sn(nid); + if (sn) + dst->params.named_curve = strdup(sn); + } /* Decode EC_POINT from a octet string */ buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src), diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 775ba0a59b..b094832ccc 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1672,7 +1672,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) nid = EC_GROUP_get_curve_name(grp); if(nid != 0) { const char *name = OBJ_nid2sn(nid); - if(sizeof(name) > 0) + if (name) dst->params.named_curve = strdup(name); } From 9fa1722f73f40b5db23553090658ad886ea916cf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 3 Mar 2019 21:26:20 +0100 Subject: [PATCH 0816/4321] sc_bin_to_hex returns a Nul terminated string --- src/libopensc/pkcs15-din-66291.c | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 14 +++++++------- src/libopensc/pkcs15-openpgp.c | 2 +- src/libopensc/pkcs15-tcos.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 31894d5def..7a67e97f2c 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -251,7 +251,7 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) if (!p15card->tokeninfo->serial_number && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { char serial_hex[SC_MAX_SERIALNR*2+2]; - sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex - 1, 0); + sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex, 0); p15card->tokeninfo->serial_number = strdup(serial_hex); } diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index e9a442dc45..dca5b61205 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -224,13 +224,13 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) p15card->tokeninfo->label = strdup("GemSAFE"); p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); /* get serial number */ - r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); - if (r != SC_SUCCESS) - return SC_ERROR_INTERNAL; - r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); - if (r != SC_SUCCESS) - return SC_ERROR_INTERNAL; - p15card->tokeninfo->serial_number = strdup(buf); + r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; + r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); + if (r != SC_SUCCESS) + return SC_ERROR_INTERNAL; + p15card->tokeninfo->serial_number = strdup(buf); /* test if we have a gemsafe app df */ memset(&path, 0, sizeof(path)); diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index bd3d151e90..87d36bf1a1 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -182,7 +182,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) unsigned short manuf_id = bebytes2ushort(card->serialnr.value); int j; - sc_bin_to_hex(card->serialnr.value, card->serialnr.len, string, sizeof(string)-1, 0); + sc_bin_to_hex(card->serialnr.value, card->serialnr.len, string, sizeof(string), 0); set_string(&p15card->tokeninfo->serial_number, string); for (j = 0; manuf_map[j].name != NULL; j++) { diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index c716bf735d..04d1fe85fd 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -511,9 +511,9 @@ int sc_pkcs15emu_tcos_init_ex( sc_log(ctx, "unable to get ICCSN\n"); return SC_ERROR_WRONG_CARD; } - sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); + sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); serial[19] = '\0'; - p15card->tokeninfo->serial_number = strdup(serial); + p15card->tokeninfo->serial_number = strdup(serial); if(!detect_netkey(p15card)) return SC_SUCCESS; if(!detect_idkey(p15card)) return SC_SUCCESS; From 106b3a28b102123485ffd7dcd2fb8891b41d0c05 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 10:11:25 +0100 Subject: [PATCH 0817/4321] acos5: removed incomplete driver fixes https://github.com/OpenSC/OpenSC/issues/1204 --- src/libopensc/Makefile.am | 3 +- src/libopensc/Makefile.mak | 1 - src/libopensc/card-acos5.c | 241 ------------------------------------- src/libopensc/cards.h | 5 - src/libopensc/ctx.c | 1 - 5 files changed, 1 insertion(+), 250 deletions(-) delete mode 100644 src/libopensc/card-acos5.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 3044f675a8..f4e91b43e9 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -42,8 +42,7 @@ libopensc_la_SOURCES_BASE = \ card-oberthur.c card-belpic.c card-atrust-acos.c \ card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ card-piv.c card-cac-common.c card-cac.c card-cac1.c \ - card-muscle.c card-acos5.c \ - card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ + card-muscle.c card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ card-rtecp.c card-westcos.c card-myeid.c \ card-itacns.c card-authentic.c \ card-iasecc.c iasecc-sdo.c iasecc-sm.c card-sc-hsm.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 08b6d6f337..c928b64c98 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -21,7 +21,6 @@ OBJECTS = \ card-entersafe.obj card-epass2003.obj card-coolkey.obj \ card-incrypto34.obj card-cac.obj card-cac1.obj card-cac-common.obj \ card-piv.obj card-muscle.obj \ - card-acos5.obj \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ card-rtecp.obj card-westcos.obj card-myeid.obj \ card-itacns.obj card-authentic.obj \ diff --git a/src/libopensc/card-acos5.c b/src/libopensc/card-acos5.c deleted file mode 100644 index 0f745bed84..0000000000 --- a/src/libopensc/card-acos5.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * card-acos5.c: Support for ACS ACOS5 cards. - * - * Copyright (C) 2007 Ian A. Young - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "internal.h" -#include "cardctl.h" - -static const struct sc_atr_table acos5_atrs[] = { - {"3b:be:96:00:00:41:05:20:00:00:00:00:00:00:00:00:00:90:00", NULL, NULL, - SC_CARD_TYPE_ACOS5_GENERIC, 0, NULL}, - {"3b:be:18:00:00:41:05:10:00:00:00:00:00:00:00:00:00:90:00", NULL, NULL, - SC_CARD_TYPE_ACOS5_GENERIC, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL} -}; - -static struct sc_card_operations *iso_ops; -static struct sc_card_operations acos5_ops; -static struct sc_card_driver acos5_drv = { - "ACS ACOS5 card", - "acos5", - &acos5_ops, - NULL, 0, NULL -}; - -static int acos5_match_card(sc_card_t * card) -{ - int i; - - i = _sc_match_atr(card, acos5_atrs, &card->type); - if (i < 0) - return 0; - return 1; -} - -static int acos5_init(sc_card_t * card) -{ - card->max_recv_size = 128; - card->max_send_size = 128; - return SC_SUCCESS; -} - -static int acos5_select_file_by_path(sc_card_t * card, - const sc_path_t * in_path, - sc_file_t ** file_out) -{ - int in_len = in_path->len; - const u8 *in_pos = in_path->value; - sc_path_t path; - - memset(&path, 0, sizeof(sc_path_t)); - path.len = 2; /* one component at a time */ - path.type = SC_PATH_TYPE_FILE_ID; - - /* - * Check parameters. - */ - if (in_len % 2 != 0) - return SC_ERROR_INVALID_ARGUMENTS; - - /* - * File ID by file ID... - */ - while (in_len) { - int result; - memcpy(path.value, in_pos, 2); - result = iso_ops->select_file(card, &path, file_out); - if (result != SC_SUCCESS) - return result; - in_len -= 2; - in_pos += 2; - } - return SC_SUCCESS; -} - -static int acos5_select_file(sc_card_t * card, - const sc_path_t * in_path, sc_file_t ** file_out) -{ - switch (in_path->type) { - - case SC_PATH_TYPE_PATH: - return acos5_select_file_by_path(card, in_path, file_out); - - default: - return iso_ops->select_file(card, in_path, file_out); - } -} - -static int acos5_get_serialnr(sc_card_t * card, sc_serial_number_t * serial) -{ - int r; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - sc_apdu_t apdu; - - /* - * Check arguments. - */ - if (!serial) - return SC_ERROR_INVALID_ARGUMENTS; - - /* - * Return a cached serial number, if we have one. - */ - if (card->serialnr.len) { - memcpy(serial, &card->serialnr, sizeof(*serial)); - return SC_SUCCESS; - } - - /* - * Fetch serial number using GET CARD INFO. - */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x14, 0, 0); - apdu.cla |= 0x80; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 6; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) - return SC_ERROR_INTERNAL; - - /* - * Cache serial number. - */ - memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); - - /* - * Copy and return serial number. - */ - memcpy(serial, &card->serialnr, sizeof(*serial)); - return SC_SUCCESS; -} - -static int acos5_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) -{ - switch (cmd) { - - case SC_CARDCTL_GET_SERIALNR: - return acos5_get_serialnr(card, (sc_serial_number_t *) ptr); - - default: - return SC_ERROR_NOT_SUPPORTED; - } -} - -static int acos5_list_files(sc_card_t * card, u8 * buf, size_t buflen) -{ - sc_apdu_t apdu; - int r; - size_t count; - u8 *bufp = buf; /* pointer into buf */ - int fno = 0; /* current file index */ - - /* - * Check parameters. - */ - if (!buf || (buflen & 1)) - return SC_ERROR_INVALID_ARGUMENTS; - - /* - * Use CARD GET INFO to fetch the number of files under the - * currently selected DF. - */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x14, 0x01, 0x00); - apdu.cla |= 0x80; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90) - return SC_ERROR_INTERNAL; - count = apdu.sw2; - - while (count--) { - u8 info[8]; - - /* - * Truncate the scan if no more room left in output buffer. - */ - if (buflen == 0) - break; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x14, 0x02, - fno++); - apdu.cla |= 0x80; - apdu.resp = info; - apdu.resplen = sizeof(info); - apdu.le = sizeof(info); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) - return SC_ERROR_INTERNAL; - - *bufp++ = info[2]; - *bufp++ = info[3]; - buflen -= 2; - } - - return (bufp - buf); -} - -static struct sc_card_driver *sc_get_driver(void) -{ - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - - iso_ops = iso_drv->ops; - acos5_ops = *iso_ops; - - acos5_ops.match_card = acos5_match_card; - acos5_ops.init = acos5_init; - acos5_ops.select_file = acos5_select_file; - acos5_ops.card_ctl = acos5_card_ctl; - acos5_ops.list_files = acos5_list_files; - - return &acos5_drv; -} - -struct sc_card_driver *sc_get_acos5_driver(void) -{ - return sc_get_driver(); -} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 121182bb6a..dd78e7e298 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -153,10 +153,6 @@ enum { SC_CARD_TYPE_MUSCLE_JCOP241, SC_CARD_TYPE_MUSCLE_JCOP242R2_NO_EXT_APDU, - /* ACOS5 driver */ - SC_CARD_TYPE_ACOS5_BASE = 16000, - SC_CARD_TYPE_ACOS5_GENERIC, - /* Athena APCOS cards */ SC_CARD_TYPE_ASEPCOS_BASE = 17000, SC_CARD_TYPE_ASEPCOS_GENERIC, @@ -272,7 +268,6 @@ extern sc_card_driver_t *sc_get_atrust_acos_driver(void); extern sc_card_driver_t *sc_get_incrypto34_driver(void); extern sc_card_driver_t *sc_get_piv_driver(void); extern sc_card_driver_t *sc_get_muscle_driver(void); -extern sc_card_driver_t *sc_get_acos5_driver(void); extern sc_card_driver_t *sc_get_asepcos_driver(void); extern sc_card_driver_t *sc_get_akis_driver(void); extern sc_card_driver_t *sc_get_entersafe_driver(void); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index ff83df759b..84df68ff7c 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -110,7 +110,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { #endif { "belpic", (void *(*)(void)) sc_get_belpic_driver }, { "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver }, - { "acos5", (void *(*)(void)) sc_get_acos5_driver }, { "akis", (void *(*)(void)) sc_get_akis_driver }, #ifdef ENABLE_OPENSSL { "entersafe",(void *(*)(void)) sc_get_entersafe_driver }, From 1e0743b29ffede1cad2e482649ecf9dec5213c69 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 11:31:55 +0100 Subject: [PATCH 0818/4321] removed untested use of SC_SEC_OPERATION_AUTHENTICATE fixes https://github.com/OpenSC/OpenSC/issues/1271 --- src/libopensc/card-dnie.c | 5 ----- src/libopensc/card-itacns.c | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 0fe9350b04..905579cb53 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1520,11 +1520,6 @@ static int dnie_set_security_env(struct sc_card *card, apdu.p1 = 0x41; /* SET; internal operation */ apdu.p2 = 0xB6; /* Template for Digital Signature */ break; - case SC_SEC_OPERATION_AUTHENTICATE: - /* TODO: _set_security_env() study diffs on internal/external auth */ - apdu.p1 = 0x41; /* SET; internal operation */ - apdu.p2 = 0xA4; /* Template for Authenticate */ - break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 463fdd8d3d..db951ed469 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -312,9 +312,6 @@ static int itacns_set_security_env(sc_card_t *card, case SC_SEC_OPERATION_SIGN: apdu.p2 = 0xB6; break; - case SC_SEC_OPERATION_AUTHENTICATE: - apdu.p2 = 0xA4; - break; default: return SC_ERROR_INVALID_ARGUMENTS; } From 71b85d15e4eeca4af1e75164c793436ba5de3583 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 13:10:34 +0100 Subject: [PATCH 0819/4321] opensc.conf: Configure handling of private_certificate possible choices: ignore, protect, declassify fixes https://github.com/OpenSC/OpenSC/issues/1430 --- doc/files/opensc.conf.5.xml.in | 35 +++++++++++++++++++++++----------- etc/opensc.conf.example.in | 9 +++++++-- src/libopensc/pkcs15-cert.c | 10 ++++++++++ src/libopensc/pkcs15.c | 23 ++++++++++++++++++---- src/libopensc/pkcs15.h | 6 ++++++ 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 33ac08bb45..4493fb8781 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1142,6 +1142,30 @@ app application { some cards (Default: false). + + + + + + How to handle a PIN-protected certificate. Known + parameters: + + + protect: The certificate stays PIN-protected. + + + declassify: Allow + reading the certificate without + enforcing verification of the PIN. + + + ignore: Ignore PIN-protected certificates. + + + (Default: ignore in Tokend, + protect otherwise). + + @@ -1311,17 +1335,6 @@ app application { the highest score shall be used. - - - - - - Tokend ignore to read PIN protected certificate - that is set - SC_PKCS15_CO_FLAG_PRIVATE flag - (Default: true). - - diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 3d54098f9b..36bdf0b4af 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -873,7 +873,7 @@ app default { # (with certificate check) where $HOME is not set # Default: path in user home # file_cache_dir = /var/lib/opensc/cache - # + # Use PIN caching? # Default: true # use_pin_caching = false; @@ -886,7 +886,12 @@ app default { # may need to set this to get signatures to work with some cards. # Default: false # pin_cache_ignore_user_consent = true; - # + + # How to handle a PIN-protected certificate + # Valid values: protect, declassify, ignore. + # Default: ignore in tokend, protect otherwise + # private_certificate = declassify; + # Enable pkcs15 emulation. # Default: yes # enable_pkcs15_emulation = no; diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 5a05d14c04..1a187f4135 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -488,6 +488,16 @@ sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obje } sc_log(ctx, "Certificate path '%s'", sc_print_path(&info.path)); + switch (p15card->opts.private_certificate) { + case SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY: + sc_log(ctx, "Declassifying certificate"); + obj->flags &= ~SC_PKCS15_CO_FLAG_PRIVATE; + break; + case SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE: + sc_log(ctx, "Ignoring certificate"); + return 0; + } + obj->type = SC_PKCS15_TYPE_CERT_X509; obj->data = malloc(sizeof(info)); if (obj->data == NULL) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 85e7ecc7b4..eca16adc83 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1192,6 +1192,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, struct sc_context *ctx = card->ctx; scconf_block *conf_block = NULL; int r, emu_first, enable_emu; + const char *private_certificate; LOG_FUNC_CALLED(ctx); sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty"); @@ -1208,19 +1209,33 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; + if(0 == strcmp(ctx->app_name, "tokend")) { + private_certificate = "ignore"; + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + } else { + private_certificate = "protect"; + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + } conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); - if (conf_block) { p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache); p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache); p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); - p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", + p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", p15card->opts.pin_cache_ignore_user_consent); + private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate); + } + if (0 == strcmp(private_certificate, "protect")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + } else if (0 == strcmp(private_certificate, "ignore")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + } else if (0 == strcmp(private_certificate, "declassify")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY; } - sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d", + sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d private_certificate=%d", p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter, - p15card->opts.pin_cache_ignore_user_consent); + p15card->opts.pin_cache_ignore_user_consent, p15card->opts.private_certificate); r = sc_lock(card); if (r) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 8d2e54110a..60af524b36 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -593,6 +593,7 @@ typedef struct sc_pkcs15_card { int use_pin_cache; int pin_cache_counter; int pin_cache_ignore_user_consent; + int private_certificate; } opts; unsigned int magic; @@ -613,6 +614,11 @@ typedef struct sc_pkcs15_card { /* flags suitable for struct sc_pkcs15_card */ #define SC_PKCS15_CARD_FLAG_EMULATED 0x02000000 +/* suitable for struct sc_pkcs15_card.opts.private_certificate */ +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT 0 +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE 1 +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY 2 + /* X509 bits for certificate usage extension */ #define SC_X509_DIGITAL_SIGNATURE 0x0001UL #define SC_X509_NON_REPUDIATION 0x0002UL From 1e6d3df201a14ce781c208abb51ddf6a7f4fafd7 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:59:06 +0200 Subject: [PATCH 0820/4321] Remove un-lincenced header file Signed-off-by: Raul Metsma --- src/libopensc/Makefile.am | 2 +- src/libopensc/card-mcrd.c | 10 +++------- src/libopensc/esteid.h | 31 ------------------------------- src/libopensc/pkcs15-esteid.c | 2 +- 4 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 src/libopensc/esteid.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index f4e91b43e9..a6d7650393 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -5,7 +5,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak opensc.dll.manifest lib_LTLIBRARIES = libopensc.la -noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ +noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ internal-winscard.h p15card-helper.h pkcs15-syn.h \ opensc.h pkcs15.h gp.h \ cardctl.h asn1.h log.h simpletlv.h \ diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index b835e030c9..2cb0857dca 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -33,7 +33,6 @@ #include "internal.h" #include "asn1.h" #include "cardctl.h" -#include "esteid.h" #include "gp.h" static const struct sc_atr_table mcrd_atrs[] = { @@ -77,6 +76,7 @@ enum { #define MFID 0x3F00 #define EF_KeyD 0x0013 /* File with extra key information. */ #define EF_Rule 0x0030 /* Default ACL file. */ +#define SC_ESTEID_KEYREF_FILE_RECLEN 21 #define MAX_CURPATH 10 @@ -1351,15 +1351,11 @@ static int mcrd_compute_signature(sc_card_t * card, env->operation, datalen, datalen, env->key_ref[0], env->algorithm, env->algorithm_flags); - switch (env->key_ref[0]) { - case SC_ESTEID_AUTH: /* authentication key */ + if (env->key_ref[0] == 1) /* authentication key */ sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0, 0); - break; - default: + else sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); - - } apdu.lc = datalen; apdu.data = data; apdu.datalen = datalen; diff --git a/src/libopensc/esteid.h b/src/libopensc/esteid.h deleted file mode 100644 index d08eb388a8..0000000000 --- a/src/libopensc/esteid.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _OPENSC_ESTEID_H -#define _OPENSC_ESTEID_H - -/* personal data file record numbers */ -enum { - SC_ESTEID_PD_SURNAME = 1, - SC_ESTEID_PD_GIVEN_NAMES1, - SC_ESTEID_PD_GIVEN_NAMES2, - SC_ESTEID_PD_SEX, - SC_ESTEID_PD_CITIZENSHIP, - SC_ESTEID_PD_DATE_OF_BIRTH, - SC_ESTEID_PD_PERSONAL_ID, - SC_ESTEID_PD_DOCUMENT_NR, - SC_ESTEID_PD_EXPIRY_DATE, - SC_ESTEID_PD_PLACE_OF_BIRTH, - SC_ESTEID_PD_ISSUING_DATE, - SC_ESTEID_PD_PERMIT_TYPE, - SC_ESTEID_PD_REMARK1, - SC_ESTEID_PD_REMARK2, - SC_ESTEID_PD_REMARK3, - SC_ESTEID_PD_REMARK4 -}; - -enum { - SC_ESTEID_AUTH = 1, - SC_ESTEID_SIGN -}; - -#define SC_ESTEID_KEYREF_FILE_RECLEN 21 - -#endif diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index aa7afeab90..0e401e653f 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -35,7 +35,6 @@ #include "internal.h" #include "opensc.h" #include "pkcs15.h" -#include "esteid.h" static void set_string (char **strp, const char *value) @@ -49,6 +48,7 @@ set_string (char **strp, const char *value) static int sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) { + const size_t SC_ESTEID_PD_DOCUMENT_NR = 8; sc_card_t *card = p15card->card; unsigned char buff[128]; int r, i; From 0079d836f3e51f1c4b9e67dee026217a7c13cc47 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 8 Mar 2019 22:02:30 +0100 Subject: [PATCH 0821/4321] pkcs11: truncate oversized labels with '...' --- src/pkcs11/misc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 9408080b18..c3f5bb4e15 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -43,16 +43,26 @@ static struct sc_to_cryptoki_error_conversion sc_to_cryptoki_error_map[] = { void strcpy_bp(u8 * dst, const char *src, size_t dstsize) { - size_t c; - - if (!dst || !src || !dstsize) + if (!dst || !dstsize) return; memset((char *)dst, ' ', dstsize); - c = strlen(src) > dstsize ? dstsize : strlen(src); + if (src) { + size_t src_len = strlen(src); - memcpy((char *)dst, src, c); + if (src_len > dstsize) { + /* string will be truncated */ + memcpy((char *)dst, src, dstsize); + if (dstsize > 3) { + /* show truncation with '...' */ + /* FIXME avoid breaking an UTF-8 character on multiple bytes */ + memset((char *)dst + dstsize - 3, '.', 3); + } + } else { + memcpy((char *)dst, src, src_len); + } + } } From b7ec7f95b1b38636a1b58bd276dd68632c791209 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 8 Mar 2019 23:08:33 +0100 Subject: [PATCH 0822/4321] pkcs11: fixed token label --- src/pkcs11/framework-pkcs15.c | 58 ++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index bf27516ade..8a37917fcc 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1058,7 +1058,6 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, { struct pkcs15_slot_data *fw_data; struct sc_pkcs15_auth_info *pin_info = NULL; - char label[sizeof(auth->label) + sizeof(p15card->tokeninfo->label) + 10]; int write_protected; scconf_block *atrblock; @@ -1100,31 +1099,47 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, pin_info = NULL; } else { - if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) { - /* Trim tokeninfo->label to make right parenthesis visible */ - char tokeninfo_label[sizeof(p15card->tokeninfo->label)+1]; - int len; - snprintf(tokeninfo_label, sizeof(tokeninfo_label), "%s", - p15card->tokeninfo ? p15card->tokeninfo->label : ""); - tokeninfo_label[sizeof(tokeninfo_label)-1] = '\0'; - for (len = strlen(tokeninfo_label) - 1; len >= 0 && isspace(tokeninfo_label[len]); len--) { - tokeninfo_label[len] = 0; + size_t tokeninfo_len = 0; + if (p15card->tokeninfo) + tokeninfo_len = strlen(p15card->tokeninfo->label); + size_t pin_len = 0; + if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) + pin_len = strlen(auth->label); + + if (pin_len) { + /* Print the possibly truncated token label with at least 4 + * characters followed by the PIN label in paranthesis */ + size_t max_tokeninfo_len = 32 - pin_len - strlen("L... ()"); + if (!tokeninfo_len + || pin_len + strlen("L... ()") > 32) { + /* Token label it doesn't fit, + * print only PIN label */ + strcpy_bp(slot->token_info.label, auth->label, 32); + } else { + strcpy_bp(slot->token_info.label, + p15card->tokeninfo->label, + max_tokeninfo_len); + slot->token_info.label[max_tokeninfo_len] = ' '; + slot->token_info.label[max_tokeninfo_len+1] = '('; + slot->token_info.label[max_tokeninfo_len+2+pin_len] = ')'; + strcpy_bp(slot->token_info.label+max_tokeninfo_len+2, + auth->label, pin_len); } - snprintf(label, sizeof(label), "%.*s (%s)", - (int) sizeof(auth->label), auth->label, - tokeninfo_label); - } else - /* The PIN label is empty or says just non-useful "PIN" */ - snprintf(label, sizeof(label), "%s", - p15card->tokeninfo ? p15card->tokeninfo->label : ""); + } else { + /* PIN label is empty or just says non-useful "PIN", + * print only token label */ + strcpy_bp(slot->token_info.label, + p15card->tokeninfo ? p15card->tokeninfo->label : "", + 32); + } slot->token_info.flags |= CKF_LOGIN_REQUIRED; } } else { - snprintf(label, sizeof(label), "%s", - p15card->tokeninfo ? p15card->tokeninfo->label : ""); + strcpy_bp(slot->token_info.label, + p15card->tokeninfo ? p15card->tokeninfo->label : "", + 32); } - strcpy_bp(slot->token_info.label, label, 32); if (pin_info) { slot->token_info.ulMaxPinLen = pin_info->attrs.pin.max_length; @@ -1137,7 +1152,8 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, } slot->app_info = app_info; - sc_log(context, "Initialized token '%s' in slot 0x%lx", label, slot->id); + sc_log(context, "Initialized slot 0x%lx with token %*s", slot->id, + (int)sizeof(slot->token_info.label), slot->token_info.label); } From 2e87e4cfedecff472bd42a1a8cbe3432b20919f6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 11 Mar 2019 21:58:34 +0100 Subject: [PATCH 0823/4321] fixed issues from review --- src/pkcs11/framework-pkcs15.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 8a37917fcc..4b1f17905c 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1099,23 +1099,24 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, pin_info = NULL; } else { - size_t tokeninfo_len = 0; - if (p15card->tokeninfo) - tokeninfo_len = strlen(p15card->tokeninfo->label); size_t pin_len = 0; if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) pin_len = strlen(auth->label); if (pin_len) { + size_t tokeninfo_len = 0; + if (p15card->tokeninfo) + tokeninfo_len = strlen(p15card->tokeninfo->label); /* Print the possibly truncated token label with at least 4 * characters followed by the PIN label in paranthesis */ - size_t max_tokeninfo_len = 32 - pin_len - strlen("L... ()"); - if (!tokeninfo_len + if (tokeninfo_len == 0 || pin_len + strlen("L... ()") > 32) { - /* Token label it doesn't fit, + /* There is no token label or it doesn't fit, * print only PIN label */ strcpy_bp(slot->token_info.label, auth->label, 32); } else { + size_t max_tokeninfo_len = MIN(tokeninfo_len, + 32 - pin_len - strlen(" ()")); strcpy_bp(slot->token_info.label, p15card->tokeninfo->label, max_tokeninfo_len); @@ -1135,11 +1136,6 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, slot->token_info.flags |= CKF_LOGIN_REQUIRED; } } - else { - strcpy_bp(slot->token_info.label, - p15card->tokeninfo ? p15card->tokeninfo->label : "", - 32); - } if (pin_info) { slot->token_info.ulMaxPinLen = pin_info->attrs.pin.max_length; @@ -1149,6 +1145,9 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, /* choose reasonable defaults */ slot->token_info.ulMaxPinLen = 8; slot->token_info.ulMinPinLen = 4; + strcpy_bp(slot->token_info.label, + p15card->tokeninfo ? p15card->tokeninfo->label : "", + 32); } slot->app_info = app_info; From 4d2254a092f5be7db52cf10dfc478e22643bda9d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 4 Feb 2019 10:47:13 +0200 Subject: [PATCH 0824/4321] Only EstEID 3.5 has EC 384 keys Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 44 ++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2cb0857dca..d96fb3c591 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -333,31 +333,27 @@ static int mcrd_init(sc_card_t * card) * For some reason a reset is required as well... */ sc_reset(card, 0); - r = gp_select_aid(card, &EstEID_v3_AID); - if (r < 0) - { - r = gp_select_aid(card, &EstEID_v35_AID); - if (r >= 0) { - // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary - // sc_read_binary cannot handle recursive 61 00 calls - if (card->reader && card->reader->active_protocol == SC_PROTO_T0) - card->max_recv_size = 255; - } else { - r = gp_select_aid(card, &AzeDIT_v35_AID); - if (r < 0) { - free(card->drv_data); - card->drv_data = NULL; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); - } - } - } flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; - /* EstEID v3.0 has 2048 bit keys */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - - flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + if ((r = gp_select_aid(card, &EstEID_v3_AID)) >= 0) { + /* EstEID v3.0 has 2048 bit keys */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else if ((r = gp_select_aid(card, &EstEID_v35_AID)) >= 0) { + /* EstEID v3.5 has 2048 bit keys or EC 384 */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary + // sc_read_binary cannot handle recursive 61 00 calls + if (card->reader && card->reader->active_protocol == SC_PROTO_T0) + card->max_recv_size = 255; + } else if ((r = gp_select_aid(card, &AzeDIT_v35_AID)) >= 0) { + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else { + free(card->drv_data); + card->drv_data = NULL; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); + } } else { flags = SC_ALGORITHM_RSA_RAW |SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; _sc_card_add_rsa_alg(card, 512, flags, 0); From 6aa5410e73af2c9b4f6ea40464e016ba75dab8b1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 18 Mar 2019 13:59:11 +0100 Subject: [PATCH 0825/4321] goid-tool: live with short length APDUs --- src/tools/goid-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 3fc1be289a..19766e8b5f 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -70,8 +70,8 @@ void soc_info(sc_context_t *ctx, sc_card_t *card) { sc_apdu_t apdu; - unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 information_applets[SC_MAX_APDU_BUFFER_SIZE]; + unsigned char rbuf[SC_MAX_APDU_RESP_SIZE]; + u8 information_applets[SC_MAX_APDU_RESP_SIZE]; size_t information_applets_len = sizeof information_applets; int pin_initialized = 0, bio_initialized = 0; int pin_max_retries = 0, pin_cur_retries = 0, bio_max_retries = 0, bio_cur_retries = 0; From 8dea0a9028fad2ee1e591773d1100c64092ce17c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 18 Mar 2019 23:33:24 +0100 Subject: [PATCH 0826/4321] fix overlapping memcpy Fixes https://github.com/OpenSC/OpenSC/issues/1631 --- src/libopensc/card-gids.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 2471c55a35..27576f999a 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1915,7 +1915,6 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { LOG_TEST_RET(card->ctx, r, "unable to set computer random"); // send it to the card - memcpy(apduSetRandom+4, randomR1, 16); sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00); apdu.lc = sizeof(apduSetRandom); apdu.data = apduSetRandom; From 7ae54f490d917f8d041dcd15faa1dabd10cdde66 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 25 Mar 2019 15:28:53 +0200 Subject: [PATCH 0827/4321] Remove dead code (#1638) --- src/libopensc/card-mcrd.c | 135 +++++++------------------------------- 1 file changed, 25 insertions(+), 110 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2cb0857dca..34c0a844e5 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -473,60 +473,6 @@ static int load_special_files(sc_card_t * card) return 0; } -/* Return the SE number from the keyD for the FID. If ref_data is not - NULL the reference data is returned; this should be an array of at - least 2 bytes. Returns -1 on error. */ -static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid, - u8 * ref_data) -{ - sc_context_t *ctx = card->ctx; - struct df_info_s *dfi; - struct keyd_record_s *keyd; - size_t len, taglen; - const u8 *p, *tag; - u8 fidbuf[2]; - - fidbuf[0] = (fid >> 8) & 0xFF; - fidbuf[1] = fid & 0xFF; - - dfi = get_df_info(card); - if (!dfi || !dfi->keyd_file) { - sc_log(ctx, "EF_keyD not loaded\n"); - return -1; - } - - for (keyd = dfi->keyd_file; keyd; keyd = keyd->next) { - p = keyd->data; - len = keyd->datalen; - - sc_log(ctx, "keyd no %d", keyd->recno); - sc_log_hex(ctx, "", p, len); - - tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); - if (!tag || taglen != 4 || - !(tag[2] == fidbuf[0] && tag[3] == fidbuf[1])) - continue; - /* Found a matching record. */ - if (ref_data) { - ref_data[0] = tag[0]; - ref_data[1] = tag[1]; - } - /* Look for the SE-DO */ - tag = sc_asn1_find_tag(ctx, p, len, 0x7B, &taglen); - if (!tag || !taglen) - continue; - p = tag; - len = taglen; - /* And now look for the referenced SE. */ - tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); - if (!tag || taglen != 1) - continue; - return *tag; /* found. */ - } - sc_log(ctx, "EF_keyD for %04hx not found\n", fid); - return -1; -} - /* Process an ARR (7816-9/8.5.4) and setup the ACL. */ static void process_arr(sc_card_t * card, sc_file_t * file, const u8 * buf, size_t buflen) @@ -1212,34 +1158,32 @@ static int mcrd_set_security_env(sc_card_t * card, return 0; } - if (card->type == SC_CARD_TYPE_MCRD_GENERIC) { - /* some sanity checks */ - if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - if (env->algorithm != SC_ALGORITHM_RSA) - return SC_ERROR_INVALID_ARGUMENTS; - } - if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) - || env->key_ref_len != 1) + /* some sanity checks */ + if (env->flags & SC_SEC_ENV_ALG_PRESENT) { + if (env->algorithm != SC_ALGORITHM_RSA) return SC_ERROR_INVALID_ARGUMENTS; + } + if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) + || env->key_ref_len != 1) + return SC_ERROR_INVALID_ARGUMENTS; - switch (env->operation) { - case SC_SEC_OPERATION_DECIPHER: - sc_log(card->ctx, - "Using keyref %d to decipher\n", - env->key_ref[0]); - mcrd_delete_ref_to_authkey(card); - mcrd_delete_ref_to_signkey(card); - mcrd_set_decipher_key_ref(card, env->key_ref[0]); - break; - case SC_SEC_OPERATION_SIGN: - sc_log(card->ctx, "Using keyref %d to sign\n", - env->key_ref[0]); - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - priv->sec_env = *env; + switch (env->operation) { + case SC_SEC_OPERATION_DECIPHER: + sc_log(card->ctx, + "Using keyref %d to decipher\n", + env->key_ref[0]); + mcrd_delete_ref_to_authkey(card); + mcrd_delete_ref_to_signkey(card); + mcrd_set_decipher_key_ref(card, env->key_ref[0]); + break; + case SC_SEC_OPERATION_SIGN: + sc_log(card->ctx, "Using keyref %d to sign\n", + env->key_ref[0]); + break; + default: + return SC_ERROR_INVALID_ARGUMENTS; } + priv->sec_env = *env; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); apdu.le = 0; @@ -1259,37 +1203,8 @@ static int mcrd_set_security_env(sc_card_t * card, *p++ = 0x83; *p++ = 0x03; *p++ = 0x80; - - if (card->type == SC_CARD_TYPE_MCRD_GENERIC) { - unsigned char fid; - - fid = env->key_ref[0]; - *p = fid; - p++; - *p = 0; - p++; - } else if (is_esteid_card(card)) { - if ((env->flags & SC_SEC_ENV_FILE_REF_PRESENT) - && env->file_ref.len > 1) { - unsigned short fid; - int num; - - fid = env->file_ref.value[env->file_ref.len - 2] << 8; - fid |= env->file_ref.value[env->file_ref.len - 1]; - num = get_se_num_from_keyd(card, fid, p); - if (num != -1) { - /* Need to restore the security environment. */ - if (num) { - r = mcrd_restore_se(card, num); - LOG_TEST_RET(card->ctx, r, - "mcrd_enable_se failed"); - } - p += 2; - } - } - } else { - return SC_ERROR_INVALID_ARGUMENTS; - } + *p++ = env->key_ref[0]; + *p++ = 0; r = p - sbuf; apdu.lc = r; From fc9277b778a6bc914b2baaf9c13580baa99ddd0f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 14 Mar 2019 23:24:23 +0100 Subject: [PATCH 0828/4321] use compat_getopt_long if getopt_long is not available uses the autoconf way for replacing getopt.h fixes https://github.com/OpenSC/OpenSC/issues/1527 --- appveyor.yml | 3 +- configure.ac | 7 +- m4/m4_ax_func_getopt_long.m4 | 62 +++ src/Makefile.mak | 8 +- src/common/compat_getopt.h | 6 - src/tests/sc-test.c | 2 +- src/tools/Makefile.am | 10 +- src/tools/egk-tool-cmdline.c | 612 +---------------------------- src/tools/eidenv.c | 2 +- src/tools/goid-tool-cmdline.c | 612 +---------------------------- src/tools/netkey-tool.c | 2 +- src/tools/npa-tool-cmdline.c | 612 +---------------------------- src/tools/openpgp-tool.c | 2 +- src/tools/opensc-asn1-cmdline.c | 622 +----------------------------- src/tools/opensc-explorer.c | 2 +- src/tools/opensc-notify-cmdline.c | 612 +---------------------------- src/tools/util.h | 2 +- 17 files changed, 110 insertions(+), 3068 deletions(-) create mode 100644 m4/m4_ax_func_getopt_long.m4 diff --git a/appveyor.yml b/appveyor.yml index 8967e71950..59063ec74f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -93,8 +93,7 @@ build_script: - bash -c "exec 0 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 6 + +AU_ALIAS([ADL_FUNC_GETOPT_LONG], [AX_FUNC_GETOPT_LONG]) +AC_DEFUN([AX_FUNC_GETOPT_LONG], + [AC_PREREQ(2.49)dnl + # clean out junk possibly left behind by a previous configuration + rm -f src/getopt.h + # Check for getopt_long support + AC_CHECK_HEADERS([getopt.h]) + AC_CHECK_FUNCS([getopt_long],, + [# FreeBSD has a gnugetopt library for this + AC_CHECK_LIB([gnugetopt],[getopt_long],[AC_DEFINE([HAVE_GETOPT_LONG])], + [# use the OpenSC replacement + AC_CONFIG_LINKS([src/getopt.h:src/common/compat_getopt.h])])])]) diff --git a/src/Makefile.mak b/src/Makefile.mak index c37792169e..8dee619666 100644 --- a/src/Makefile.mak +++ b/src/Makefile.mak @@ -19,6 +19,12 @@ SUBDIRS = $(SUBDIRS) smm SUBDIRS = $(SUBDIRS) tests !ENDIF -all clean:: +all:: + copy /y common\compat_getopt.h getopt.h @for %i in ( $(SUBDIRS) ) do \ @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" + +clean:: + @for %i in ( $(SUBDIRS) ) do \ + @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" + del /Q getopt.h diff --git a/src/common/compat_getopt.h b/src/common/compat_getopt.h index 8ff5401a27..b1f36337fe 100644 --- a/src/common/compat_getopt.h +++ b/src/common/compat_getopt.h @@ -30,10 +30,6 @@ #include "config.h" #endif -#if defined(HAVE_GETOPT_H) && defined(HAVE_GETOPT_LONG) && defined(HAVE_GETOPT_LONG_ONLY) -#include -#else - /* Prevent mingw32 from including an incompatible getopt implementation */ #define __GETOPT_H__ @@ -86,6 +82,4 @@ extern int _my_getopt_internal(int argc, char * argv[], const char *shortopts, } #endif -#endif /* HAVE_GETOPT_H && HAVE_GETOPT_LONG && HAVE_GETOPT_LONG_ONLY */ - #endif /* MY_GETOPT_H_INCLUDED */ diff --git a/src/tests/sc-test.c b/src/tests/sc-test.c index 42bc1f6fd6..35b42965a8 100644 --- a/src/tests/sc-test.c +++ b/src/tests/sc-test.c @@ -10,7 +10,7 @@ #include #include -#include "common/compat_getopt.h" +#include #include "libopensc/opensc.h" #include "sc-test.h" diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 217c1a0af5..b0ad08d984 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -104,7 +104,7 @@ npa-tool.c: $(abs_builddir)/npa-tool.ggo $(NPA_TOOL_BUILT_SOURCES) # We only want *cmdline* to be generated when they have explicitly been removed. $(NPA_TOOL_BUILT_SOURCES): $(MAKE) $(abs_builddir)/npa-tool.ggo - $(GENGETOPT) --include-getopt --file-name=npa-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/npa-tool.ggo + $(GENGETOPT) --file-name=npa-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/npa-tool.ggo $(abs_builddir)/npa-tool.ggo: npa-tool.ggo.in $(do_subst) < $(abs_srcdir)/npa-tool.ggo.in > $@ @@ -122,7 +122,7 @@ opensc-notify.c: $(abs_builddir)/opensc-notify.ggo $(OPENSC_NOTIFY_BUILT_SOURCES # We only want *cmdline* to be generated when they have explicitly been removed. $(OPENSC_NOTIFY_BUILT_SOURCES): $(MAKE) $(abs_builddir)/opensc-notify.ggo - $(GENGETOPT) --include-getopt --file-name=opensc-notify-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-notify.ggo + $(GENGETOPT) --file-name=opensc-notify-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in $(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@ @@ -140,7 +140,7 @@ egk-tool.c: $(abs_builddir)/egk-tool.ggo $(EGK_TOOL_BUILT_SOURCES) # We only want *cmdline* to be generated when they have explicitly been removed. $(EGK_TOOL_BUILT_SOURCES): $(MAKE) $(abs_builddir)/egk-tool.ggo - $(GENGETOPT) --include-getopt --file-name=egk-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/egk-tool.ggo + $(GENGETOPT) --file-name=egk-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/egk-tool.ggo $(abs_builddir)/egk-tool.ggo: egk-tool.ggo.in $(do_subst) < $(abs_srcdir)/egk-tool.ggo.in > $@ @@ -158,7 +158,7 @@ goid-tool.c: $(abs_builddir)/goid-tool.ggo $(GOID_TOOL_BUILT_SOURCES) # We only want *cmdline* to be generated when they have explicitly been removed. $(GOID_TOOL_BUILT_SOURCES): $(MAKE) $(abs_builddir)/goid-tool.ggo - $(GENGETOPT) --include-getopt --file-name=goid-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/goid-tool.ggo + $(GENGETOPT) --file-name=goid-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/goid-tool.ggo $(abs_builddir)/goid-tool.ggo: goid-tool.ggo.in $(do_subst) < $(abs_srcdir)/goid-tool.ggo.in > $@ @@ -173,7 +173,7 @@ opensc-asn1.c: $(abs_builddir)/opensc-asn1.ggo $(OPENSC_ASN1_BUILT_SOURCES) # We only want *cmdline* to be generated when they have explicitly been removed. $(OPENSC_ASN1_BUILT_SOURCES): $(MAKE) $(abs_builddir)/opensc-asn1.ggo - $(GENGETOPT) --include-getopt --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-asn1.ggo --unamed-opts + $(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-asn1.ggo --unamed-opts $(abs_builddir)/opensc-asn1.ggo: opensc-asn1.ggo.in $(do_subst) < $(abs_srcdir)/opensc-asn1.ggo.in > $@ diff --git a/src/tools/egk-tool-cmdline.c b/src/tools/egk-tool-cmdline.c index 39f991e768..22851b0e43 100644 --- a/src/tools/egk-tool-cmdline.c +++ b/src/tools/egk-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/bin/gengetopt --include-getopt --file-name=egk-tool-cmdline --output-dir=. + /usr/bin/gengetopt --file-name=egk-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -21,6 +21,7 @@ #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ #endif +#include #include "egk-tool-cmdline.h" @@ -425,598 +426,6 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro return error_occurred; } -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - static char *package_name = 0; @@ -1134,11 +543,6 @@ cmdline_parser_internal ( int initialize; int check_required; int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; package_name = argv[0]; @@ -1173,17 +577,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hVr:v", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; + c = getopt_long (argc, argv, "hVr:v", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index d96ad4e742..9c0c48b6ff 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -29,7 +29,7 @@ #include #include -#include "common/compat_getopt.h" +#include #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index c191234d43..6e02034768 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/bin/gengetopt --include-getopt --file-name=goid-tool-cmdline --output-dir=. + /usr/bin/gengetopt --file-name=goid-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -21,6 +21,7 @@ #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ #endif +#include #include "goid-tool-cmdline.h" @@ -837,598 +838,6 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro return error_occurred; } -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - static char *package_name = 0; @@ -1730,11 +1139,6 @@ cmdline_parser_internal ( int initialize; int check_required; int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; package_name = argv[0]; @@ -1788,17 +1192,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hVr:vpbc:k:", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; + c = getopt_long (argc, argv, "hVr:vpbc:k:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 4249187b3b..2456f677ea 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -27,7 +27,7 @@ #include #include -#include "common/compat_getopt.h" +#include #include "libopensc/opensc.h" static struct { diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 1b88a20cea..2918888a66 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/bin/gengetopt --include-getopt --file-name=npa-tool-cmdline --output-dir=. + /usr/bin/gengetopt --file-name=npa-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -21,6 +21,7 @@ #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ #endif +#include #include "npa-tool-cmdline.h" @@ -896,598 +897,6 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro return error_occurred; } -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - static char *package_name = 0; @@ -1727,11 +1136,6 @@ cmdline_parser_internal ( int initialize; int check_required; int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; package_name = argv[0]; @@ -1812,17 +1216,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hVr:vp::u::c::m::N::RUC:A:P:bt:", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; + c = getopt_long (argc, argv, "hVr:vp::u::c::m::N::RUC:A:P:bt:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 3e4ce52779..dcff9f8c04 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -37,7 +37,7 @@ #include #include -#include "common/compat_getopt.h" +#include #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" diff --git a/src/tools/opensc-asn1-cmdline.c b/src/tools/opensc-asn1-cmdline.c index cafbcd55ac..f8b20b9440 100644 --- a/src/tools/opensc-asn1-cmdline.c +++ b/src/tools/opensc-asn1-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/bin/gengetopt --include-getopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts + /usr/bin/gengetopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -21,6 +21,7 @@ #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ #endif +#include #include "opensc-asn1-cmdline.h" @@ -292,598 +293,6 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog return EXIT_SUCCESS; } -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - static char *package_name = 0; @@ -903,11 +312,6 @@ cmdline_parser_internal ( int initialize; int check_required; int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; package_name = argv[0]; @@ -936,17 +340,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hV", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; + c = getopt_long (argc, argv, "hV", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -990,12 +384,20 @@ cmdline_parser_internal ( (this may happen with some implementations of getopt, but surely not with the one included by gengetopt) */ + i = optind; + while (i < argc) + if (argv[i++] == argv[0]) { + found_prog_name = 1; + break; + } + i = 0; args_info->inputs_num = argc - optind - found_prog_name; args_info->inputs = (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; while (optind < argc) - args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ; + if (argv[optind++] != argv[0]) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; } return 0; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 0da867f597..25c88be8e0 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -42,7 +42,7 @@ #include "libopensc/cards.h" #include "libopensc/log.h" #include "common/compat_strlcpy.h" -#include "common/compat_getopt.h" +#include #include "util.h" #define DIM(v) (sizeof(v)/sizeof((v)[0])) diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index 4870aa28c5..3fe2fcd253 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.22.6 generated with the following command: - /usr/bin/gengetopt --include-getopt --file-name=opensc-notify-cmdline --output-dir=. + /usr/bin/gengetopt --file-name=opensc-notify-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -21,6 +21,7 @@ #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ #endif +#include #include "opensc-notify-cmdline.h" @@ -342,598 +343,6 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog return EXIT_SUCCESS; } -/* - * Extracted from the glibc source tree, version 2.3.6 - * - * Licensed under the GPL as per the whole glibc source tree. - * - * This file was modified so that getopt_long can be called - * many times without risking previous memory to be spoiled. - * - * Modified by Andre Noll and Lorenzo Bettini for use in - * GNU gengetopt generated files. - * - */ - -/* - * we must include anything we need since this file is not thought to be - * inserted in a file already using getopt.h - * - * Lorenzo - */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. -*/ -/* - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `custom_optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -/* Names for the values of the `has_arg' field of `struct option'. */ -#ifndef no_argument -#define no_argument 0 -#endif - -#ifndef required_argument -#define required_argument 1 -#endif - -#ifndef optional_argument -#define optional_argument 2 -#endif - -struct custom_getopt_data { - /* - * These have exactly the same meaning as the corresponding global variables, - * except that they are used for the reentrant versions of getopt. - */ - int custom_optind; - int custom_opterr; - int custom_optopt; - char *custom_optarg; - - /* True if the internal members have been initialized. */ - int initialized; - - /* - * The next char to be scanned in the option-element in which the last option - * character we returned was found. This allows us to pick up the scan where - * we left off. If this is zero, or a null string, it means resume the scan by - * advancing to the next ARGV-element. - */ - char *nextchar; - - /* - * Describe the part of ARGV that contains non-options that have been skipped. - * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is - * the index after the last of them. - */ - int first_nonopt; - int last_nonopt; -}; - -/* - * the variables optarg, optind, opterr and optopt are renamed with - * the custom_ prefix so that they don't interfere with getopt ones. - * - * Moreover they're static so they are visible only from within the - * file where this very file will be included. - */ - -/* - * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an - * option that takes an argument, the argument value is returned here. - */ -static char *custom_optarg; - -/* - * Index in ARGV of the next element to be scanned. This is used for - * communication to and from the caller and for communication between - * successive calls to `custom_getopt'. - * - * On entry to `custom_getopt', 1 means this is the first call; initialize. - * - * When `custom_getopt' returns -1, this is the index of the first of the non-option - * elements that the caller should itself scan. - * - * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV - * has been scanned so far. - * - * 1003.2 says this must be 1 before any call. - */ -static int custom_optind = 1; - -/* - * Callers store zero here to inhibit the error message for unrecognized - * options. - */ -static int custom_opterr = 1; - -/* - * Set to an option character which was unrecognized. This must be initialized - * on some systems to avoid linking in the system's own getopt implementation. - */ -static int custom_optopt = '?'; - -/* - * Exchange two adjacent subsequences of ARGV. One subsequence is elements - * [first_nonopt,last_nonopt) which contains all the non-options that have been - * skipped so far. The other is elements [last_nonopt,custom_optind), which contains - * all the options processed since those non-options were skipped. - * `first_nonopt' and `last_nonopt' are relocated so that they describe the new - * indices of the non-options in ARGV after they are moved. - */ -static void exchange(char **argv, struct custom_getopt_data *d) -{ - int bottom = d->first_nonopt; - int middle = d->last_nonopt; - int top = d->custom_optind; - char *tem; - - /* - * Exchange the shorter segment with the far end of the longer segment. - * That puts the shorter segment into the right place. It leaves the - * longer segment in the right place overall, but it consists of two - * parts that need to be swapped next. - */ - while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = - argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - /* Update records for the slots the non-options now occupy. */ - d->first_nonopt += (d->custom_optind - d->last_nonopt); - d->last_nonopt = d->custom_optind; -} - -/* Initialize the internal data when the first call is made. */ -static void custom_getopt_initialize(struct custom_getopt_data *d) -{ - /* - * Start processing options with ARGV-element 1 (since ARGV-element 0 - * is the program name); the sequence of previously skipped non-option - * ARGV-elements is empty. - */ - d->first_nonopt = d->last_nonopt = d->custom_optind; - d->nextchar = NULL; - d->initialized = 1; -} - -#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') - -/* return: zero: continue, nonzero: return given value to user */ -static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, - struct custom_getopt_data *d) -{ - /* - * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been - * moved back by the user (who may also have changed the arguments). - */ - if (d->last_nonopt > d->custom_optind) - d->last_nonopt = d->custom_optind; - if (d->first_nonopt > d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * If we have just processed some options following some - * non-options, exchange them so that the options come first. - */ - if (d->first_nonopt != d->last_nonopt && - d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->last_nonopt != d->custom_optind) - d->first_nonopt = d->custom_optind; - /* - * Skip any additional non-options and extend the range of - * non-options previously skipped. - */ - while (d->custom_optind < argc && NONOPTION_P) - d->custom_optind++; - d->last_nonopt = d->custom_optind; - /* - * The special ARGV-element `--' means premature end of options. Skip - * it like a null option, then exchange with previous non-options as if - * it were an option, then skip everything else like a non-option. - */ - if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { - d->custom_optind++; - if (d->first_nonopt != d->last_nonopt - && d->last_nonopt != d->custom_optind) - exchange((char **) argv, d); - else if (d->first_nonopt == d->last_nonopt) - d->first_nonopt = d->custom_optind; - d->last_nonopt = argc; - d->custom_optind = argc; - } - /* - * If we have done all the ARGV-elements, stop the scan and back over - * any non-options that we skipped and permuted. - */ - if (d->custom_optind == argc) { - /* - * Set the next-arg-index to point at the non-options that we - * previously skipped, so the caller will digest them. - */ - if (d->first_nonopt != d->last_nonopt) - d->custom_optind = d->first_nonopt; - return -1; - } - /* - * If we have come to a non-option and did not permute it, either stop - * the scan or describe it to the caller and pass it by. - */ - if (NONOPTION_P) { - d->custom_optarg = argv[d->custom_optind++]; - return 1; - } - /* - * We have found another option-ARGV-element. Skip the initial - * punctuation. - */ - d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); - return 0; -} - -/* - * Check whether the ARGV-element is a long option. - * - * If there's a long option "fubar" and the ARGV-element is "-fu", consider - * that an abbreviation of the long option, just like "--fu", and not "-f" with - * arg "u". - * - * This distinction seems to be the most useful approach. - * - */ -static int check_long_opt(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - int print_errors, struct custom_getopt_data *d) -{ - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { - if ((unsigned int) (nameend - d->nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if (pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else if (pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' is ambiguous\n", - argv[0], argv[d->custom_optind]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optind++; - d->custom_optopt = 0; - return '?'; - } - if (pfound) { - option_index = indfound; - d->custom_optind++; - if (*nameend) { - if (pfound->has_arg != no_argument) - d->custom_optarg = nameend + 1; - else { - if (print_errors) { - if (argv[d->custom_optind - 1][1] == '-') { - /* --option */ - fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - } else { - /* +option or -option */ - fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[d->custom_optind - 1][0], pfound->name); - } - - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return '?'; - } - } else if (pfound->has_arg == required_argument) { - if (d->custom_optind < argc) - d->custom_optarg = argv[d->custom_optind++]; - else { - if (print_errors) { - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], - argv[d->custom_optind - 1]); - } - d->nextchar += strlen(d->nextchar); - d->custom_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->nextchar += strlen(d->nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* - * Can't find it as a long option. If this is not getopt_long_only, or - * the option starts with '--' or is not a valid short option, then - * it's an error. Otherwise interpret it as a short option. - */ - if (print_errors) { - if (argv[d->custom_optind][1] == '-') { - /* --option */ - fprintf(stderr, - "%s: unrecognized option `--%s'\n", - argv[0], d->nextchar); - } else { - /* +option or -option */ - fprintf(stderr, - "%s: unrecognized option `%c%s'\n", - argv[0], argv[d->custom_optind][0], - d->nextchar); - } - } - d->nextchar = (char *) ""; - d->custom_optind++; - d->custom_optopt = 0; - return '?'; -} - -static int check_short_opt(int argc, char *const *argv, const char *optstring, - int print_errors, struct custom_getopt_data *d) -{ - char c = *d->nextchar++; - const char *temp = strchr(optstring, c); - - /* Increment `custom_optind' when we start to process its last character. */ - if (*d->nextchar == '\0') - ++d->custom_optind; - if (!temp || c == ':') { - if (print_errors) - fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); - - d->custom_optopt = c; - return '?'; - } - if (temp[1] == ':') { - if (temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - d->custom_optind++; - } else - d->custom_optarg = NULL; - d->nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if (*d->nextchar != '\0') { - d->custom_optarg = d->nextchar; - /* - * If we end this ARGV-element by taking the - * rest as an arg, we must advance to the next - * element now. - */ - d->custom_optind++; - } else if (d->custom_optind == argc) { - if (print_errors) { - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - d->custom_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } else - /* - * We already incremented `custom_optind' once; - * increment it again when taking next ARGV-elt - * as argument. - */ - d->custom_optarg = argv[d->custom_optind++]; - d->nextchar = NULL; - } - } - return c; -} - -/* - * Scan elements of ARGV for option characters given in OPTSTRING. - * - * If an element of ARGV starts with '-', and is not exactly "-" or "--", - * then it is an option element. The characters of this element - * (aside from the initial '-') are option characters. If `getopt' - * is called repeatedly, it returns successively each of the option characters - * from each of the option elements. - * - * If `getopt' finds another option character, it returns that character, - * updating `custom_optind' and `nextchar' so that the next call to `getopt' can - * resume the scan with the following option character or ARGV-element. - * - * If there are no more option characters, `getopt' returns -1. - * Then `custom_optind' is the index in ARGV of the first ARGV-element - * that is not an option. (The ARGV-elements have been permuted - * so that those that are not options now come last.) - * - * OPTSTRING is a string containing the legitimate option characters. - * If an option character is seen that is not listed in OPTSTRING, - * return '?' after printing an error message. If you set `custom_opterr' to - * zero, the error message is suppressed but we still return '?'. - * - * If a char in OPTSTRING is followed by a colon, that means it wants an arg, - * so the following text in the same ARGV-element, or the text of the following - * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that - * wants an optional arg; if there is text in the current ARGV-element, - * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. - * - * If OPTSTRING starts with `-' or `+', it requests different methods of - * handling the non-option ARGV-elements. - * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - * - * Long-named options begin with `--' instead of `-'. - * Their names may be abbreviated as long as the abbreviation is unique - * or is an exact match for some defined option. If they have an - * argument, it follows the option name in the same ARGV-element, separated - * from the option name by a `=', or else the in next ARGV-element. - * When `getopt' finds a long-named option, it returns 0 if that option's - * `flag' field is nonzero, the value of the option's `val' field - * if the `flag' field is zero. - * - * The elements of ARGV aren't really const, because we permute them. - * But we pretend they're const in the prototype to be compatible - * with other systems. - * - * LONGOPTS is a vector of `struct option' terminated by an - * element containing a name which is zero. - * - * LONGIND returns the index in LONGOPT of the long-named option found. - * It is only valid when a long-named option has been found by the most - * recent call. - * - * Return the option character from OPTS just read. Return -1 when there are - * no more options. For unrecognized options, or options missing arguments, - * `custom_optopt' is set to the option letter, and '?' is returned. - * - * The OPTS string is a list of characters which are recognized option letters, - * optionally followed by colons, specifying that that letter takes an - * argument, to be placed in `custom_optarg'. - * - * If a letter in OPTS is followed by two colons, its argument is optional. - * This behavior is specific to the GNU `getopt'. - * - * The argument `--' causes premature termination of argument scanning, - * explicitly telling `getopt' that there are no more options. If OPTS begins - * with `--', then non-option arguments are treated as arguments to the option - * '\0'. This behavior is specific to the GNU `getopt'. - */ - -static int getopt_internal_r(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, - struct custom_getopt_data *d) -{ - int ret, print_errors = d->custom_opterr; - - if (optstring[0] == ':') - print_errors = 0; - if (argc < 1) - return -1; - d->custom_optarg = NULL; - - /* - * This is a big difference with GNU getopt, since optind == 0 - * means initialization while here 1 means first call. - */ - if (d->custom_optind == 0 || !d->initialized) { - if (d->custom_optind == 0) - d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ - custom_getopt_initialize(d); - } - if (d->nextchar == NULL || *d->nextchar == '\0') { - ret = shuffle_argv(argc, argv, longopts, d); - if (ret) - return ret; - } - if (longopts && (argv[d->custom_optind][1] == '-' )) - return check_long_opt(argc, argv, optstring, longopts, - longind, print_errors, d); - return check_short_opt(argc, argv, optstring, print_errors, d); -} - -static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind) -{ - int result; - /* Keep a global copy of all internal members of d */ - static struct custom_getopt_data d; - - d.custom_optind = custom_optind; - d.custom_opterr = custom_opterr; - result = getopt_internal_r(argc, argv, optstring, longopts, - longind, &d); - custom_optind = d.custom_optind; - custom_optarg = d.custom_optarg; - custom_optopt = d.custom_optopt; - return result; -} - -static int custom_getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return custom_getopt_internal(argc, argv, options, long_options, - opt_index); -} - static char *package_name = 0; @@ -1074,11 +483,6 @@ cmdline_parser_internal ( int initialize; int check_required; int check_ambiguity; - - char *optarg; - int optind; - int opterr; - int optopt; package_name = argv[0]; @@ -1113,17 +517,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - custom_optarg = optarg; - custom_optind = optind; - custom_opterr = opterr; - custom_optopt = optopt; - - c = custom_getopt_long (argc, argv, "hVt::m::IRGB", long_options, &option_index); - - optarg = custom_optarg; - optind = custom_optind; - opterr = custom_opterr; - optopt = custom_optopt; + c = getopt_long (argc, argv, "hVt::m::IRGB", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ diff --git a/src/tools/util.h b/src/tools/util.h index d3a155708f..26b60c29db 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -16,7 +16,7 @@ #endif #include -#include "common/compat_getopt.h" +#include #include "libopensc/opensc.h" #ifdef __cplusplus From 2f4df1b93e4573deff0fa2b2363bd9a008a47696 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 15 Mar 2019 23:54:15 +0100 Subject: [PATCH 0829/4321] tools: unified handling of gengetopt --- src/tools/Makefile.am | 79 ++++++++++--------------------------------- 1 file changed, 17 insertions(+), 62 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b0ad08d984..495078d374 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -19,16 +19,12 @@ do_subst = $(SED) \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' -EGK_TOOL_BUILT_SOURCES = egk-tool-cmdline.h egk-tool-cmdline.c -NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c -GOID_TOOL_BUILT_SOURCES = goid-tool-cmdline.h goid-tool-cmdline.c -OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c -OPENSC_ASN1_BUILT_SOURCES = opensc-asn1-cmdline.h opensc-asn1-cmdline.c - MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest -noinst_HEADERS = util.h fread_to_eof.h +noinst_HEADERS = util.h fread_to_eof.h \ + egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ + opensc-asn1-cmdline.h opensc-notify-cmdline.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool \ @@ -90,7 +86,7 @@ dnie_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) gids_tool_SOURCES = gids-tool.c util.c gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) -npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c $(NPA_TOOL_BUILT_SOURCES) +npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c npa-tool-cmdline.c npa_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la \ $(OPENPACE_LIBS) npa_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) $(OPENSSL_CFLAGS) @@ -99,17 +95,7 @@ if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option endif -npa-tool.c: $(abs_builddir)/npa-tool.ggo $(NPA_TOOL_BUILT_SOURCES) - -# We only want *cmdline* to be generated when they have explicitly been removed. -$(NPA_TOOL_BUILT_SOURCES): - $(MAKE) $(abs_builddir)/npa-tool.ggo - $(GENGETOPT) --file-name=npa-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/npa-tool.ggo - -$(abs_builddir)/npa-tool.ggo: npa-tool.ggo.in - $(do_subst) < $(abs_srcdir)/npa-tool.ggo.in > $@ - -opensc_notify_SOURCES = opensc-notify.c $(OPENSC_NOTIFY_BUILT_SOURCES) +opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) opensc_notify_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_NOTIFY_CFLAGS) opensc_notify_CFLAGS += -Wno-unused-but-set-variable @@ -117,17 +103,7 @@ if HAVE_UNKNOWN_WARNING_OPTION opensc_notify_CFLAGS += -Wno-unknown-warning-option endif -opensc-notify.c: $(abs_builddir)/opensc-notify.ggo $(OPENSC_NOTIFY_BUILT_SOURCES) - -# We only want *cmdline* to be generated when they have explicitly been removed. -$(OPENSC_NOTIFY_BUILT_SOURCES): - $(MAKE) $(abs_builddir)/opensc-notify.ggo - $(GENGETOPT) --file-name=opensc-notify-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-notify.ggo - -$(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in - $(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@ - -egk_tool_SOURCES = egk-tool.c util.c $(EGK_TOOL_BUILT_SOURCES) +egk_tool_SOURCES = egk-tool.c util.c egk-tool-cmdline.c egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) egk_tool_CFLAGS += -Wno-unused-but-set-variable @@ -135,17 +111,7 @@ if HAVE_UNKNOWN_WARNING_OPTION egk_tool_CFLAGS += -Wno-unknown-warning-option endif -egk-tool.c: $(abs_builddir)/egk-tool.ggo $(EGK_TOOL_BUILT_SOURCES) - -# We only want *cmdline* to be generated when they have explicitly been removed. -$(EGK_TOOL_BUILT_SOURCES): - $(MAKE) $(abs_builddir)/egk-tool.ggo - $(GENGETOPT) --file-name=egk-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/egk-tool.ggo - -$(abs_builddir)/egk-tool.ggo: egk-tool.ggo.in - $(do_subst) < $(abs_srcdir)/egk-tool.ggo.in > $@ - -goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c $(GOID_TOOL_BUILT_SOURCES) +goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c goid-tool-cmdline.c goid_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPENPACE_LIBS) goid_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) goid_tool_CFLAGS += -Wno-unused-but-set-variable @@ -153,30 +119,19 @@ if HAVE_UNKNOWN_WARNING_OPTION goid_tool_CFLAGS += -Wno-unknown-warning-option endif -goid-tool.c: $(abs_builddir)/goid-tool.ggo $(GOID_TOOL_BUILT_SOURCES) - -# We only want *cmdline* to be generated when they have explicitly been removed. -$(GOID_TOOL_BUILT_SOURCES): - $(MAKE) $(abs_builddir)/goid-tool.ggo - $(GENGETOPT) --file-name=goid-tool-cmdline --output-dir=$(builddir) < $(abs_builddir)/goid-tool.ggo - -$(abs_builddir)/goid-tool.ggo: goid-tool.ggo.in - $(do_subst) < $(abs_srcdir)/goid-tool.ggo.in > $@ - -opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c $(OPENSC_ASN1_BUILT_SOURCES) +opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) opensc_asn1_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) -opensc_asn1_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option - -opensc-asn1.c: $(abs_builddir)/opensc-asn1.ggo $(OPENSC_ASN1_BUILT_SOURCES) - -# We only want *cmdline* to be generated when they have explicitly been removed. -$(OPENSC_ASN1_BUILT_SOURCES): - $(MAKE) $(abs_builddir)/opensc-asn1.ggo - $(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-asn1.ggo --unamed-opts +opensc_asn1_CFLAGS += -Wno-unused-but-set-variable +if HAVE_UNKNOWN_WARNING_OPTION +opensc_asn1_CFLAGS += -Wno-unknown-warning-option +endif -$(abs_builddir)/opensc-asn1.ggo: opensc-asn1.ggo.in - $(do_subst) < $(abs_srcdir)/opensc-asn1.ggo.in > $@ +.PHONY: cmdline +cmdline: + for f in *.ggo.in; do $(do_subst) < "$$f" > "$${f%.in}"; done + for f in *.ggo; do $(GENGETOPT) --file-name="$${f%.ggo}-cmdline" --output-dir=$(builddir) < "$$f"; done + $(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < opensc-asn1.ggo --unamed-opts if WIN32 opensc_tool_SOURCES += versioninfo-tools.rc From f070c99b65850ba2f2d40192b59a70712a7902a9 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 6 Mar 2019 13:34:22 +0100 Subject: [PATCH 0830/4321] opensc-tool: do not use card driver to read ATR If card driver fails to connect to card, 'opensc-tool -a' may fail to print ATR even if ATR is available from card reader. Before use of card driver, do only card reader connect, then print ATR. Only if it is neccesary, use card driver for the rest of opensc-tool functions. --- src/tools/opensc-tool.c | 43 ++++++++++++++++++++++++++++------------- src/tools/util.c | 40 ++++++++++++++++++++++++-------------- src/tools/util.h | 2 ++ 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 81b9af0fbc..4b309e1450 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -712,6 +712,7 @@ int main(int argc, char *argv[]) const char *opt_conf_entry = NULL; const char *opt_reset_type = NULL; char **p; + struct sc_reader *reader = NULL; sc_context_param_t ctx_param; while (1) { @@ -846,6 +847,24 @@ int main(int argc, char *argv[]) goto end; action_count--; } + + err = util_connect_reader(ctx, &reader, opt_reader, opt_wait, verbose); + if (err) { + fprintf(stderr, "Failed to connect to reader: %s\n", sc_strerror(err)); + err = 1; + goto end; + } + if (do_print_atr) { + if (verbose) { + printf("Card ATR:\n"); + util_hex_dump_asc(stdout, reader->atr.value, reader->atr.len, -1); + } else { + char tmp[SC_MAX_ATR_SIZE*3]; + sc_bin_to_hex(reader->atr.value, reader->atr.len, tmp, sizeof(tmp) - 1, ':'); + fprintf(stdout,"%s\n",tmp); + } + action_count--; + } if (action_count <= 0) goto end; @@ -858,21 +877,19 @@ int main(int argc, char *argv[]) } } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); - if (err) - goto end; + if (verbose) + printf("Connecting to card in reader %s...\n", reader->name); - if (do_print_atr) { - if (verbose) { - printf("Card ATR:\n"); - util_hex_dump_asc(stdout, card->atr.value, card->atr.len, -1); - } else { - char tmp[SC_MAX_ATR_SIZE*3]; - sc_bin_to_hex(card->atr.value, card->atr.len, tmp, sizeof(tmp) - 1, ':'); - fprintf(stdout,"%s\n",tmp); - } - action_count--; + err = sc_connect_card(reader, &card); + if (err < 0) { + fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(err)); + err = 1; + goto end; } + + if (verbose) + printf("Using card driver %s.\n", card->driver->name); + if (do_print_serial) { if (verbose) printf("Card serial number:"); diff --git a/src/tools/util.c b/src/tools/util.c index 5b8492e6c8..f08931774b 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -48,12 +48,10 @@ is_string_valid_atr(const char *atr_str) return 1; } -int -util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, - const char *reader_id, int do_wait, int do_lock, int verbose) +int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, + const char *reader_id, int do_wait, int verbose) { - struct sc_reader *reader = NULL, *found = NULL; - struct sc_card *card = NULL; + struct sc_reader *found = NULL; int r; setbuf(stderr, NULL); @@ -88,7 +86,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r)); return 3; } - reader = found; + *reader = found; } else if (sc_ctx_get_reader_count(ctx) == 0) { fprintf(stderr, "No smart card readers found.\n"); @@ -99,14 +97,14 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, unsigned int i; /* Automatically try to skip to a reader with a card if reader not specified */ for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { - reader = sc_ctx_get_reader(ctx, i); - if (sc_detect_card_presence(reader) & SC_READER_CARD_PRESENT) { - fprintf(stderr, "Using reader with a card: %s\n", reader->name); + *reader = sc_ctx_get_reader(ctx, i); + if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { + fprintf(stderr, "Using reader with a card: %s\n", (*reader)->name); goto autofound; } } /* If no reader had a card, default to the first reader */ - reader = sc_ctx_get_reader(ctx, 0); + *reader = sc_ctx_get_reader(ctx, 0); } else { /* If the reader identifier looks like an ATR, try to find the reader with that card */ @@ -128,7 +126,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, continue; fprintf(stderr, "Matched ATR in reader: %s\n", rdr->name); - reader = rdr; + *reader = rdr; goto autofound; } } @@ -139,24 +137,36 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, errno = 0; num = strtol(reader_id, &endptr, 0); if (!errno && endptr && *endptr == '\0') - reader = sc_ctx_get_reader(ctx, num); + *reader = sc_ctx_get_reader(ctx, num); else - reader = sc_ctx_get_reader_by_name(ctx, reader_id); + *reader = sc_ctx_get_reader_by_name(ctx, reader_id); } } autofound: - if (!reader) { + if (!(*reader)) { fprintf(stderr, "Reader \"%s\" not found (%d reader(s) detected)\n", reader_id, sc_ctx_get_reader_count(ctx)); return 1; } - if (sc_detect_card_presence(reader) <= 0) { + if (sc_detect_card_presence(*reader) <= 0) { fprintf(stderr, "Card not present.\n"); return 3; } } + return 0; +} +int +util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, + const char *reader_id, int do_wait, int do_lock, int verbose) +{ + struct sc_reader *reader = NULL; + struct sc_card *card = NULL; + int r; + r = util_connect_reader(ctx, &reader, reader_id, do_wait, verbose); + if(r) + return r; if (verbose) printf("Connecting to card in reader %s...\n", reader->name); r = sc_connect_card(reader, &card); diff --git a/src/tools/util.h b/src/tools/util.h index 26b60c29db..21c8293e74 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -45,6 +45,8 @@ const char * util_acl_to_str(const struct sc_acl_entry *e); void util_warn(const char *fmt, ...); void util_error(const char *fmt, ...); NORETURN void util_fatal(const char *fmt, ...); + +int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, const char *reader_id, int do_wait, int verbose); /* All singing all dancing card connect routine */ int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose); int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose); From ea74308512b40359eed0b0fe2daaef0869c94604 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Thu, 21 Mar 2019 21:55:20 +0200 Subject: [PATCH 0831/4321] iso7816_read_binary: do not assume that 6282 is returned with data Instead of a double check_sw call in case there is no data, assume that a SW is properly sent by the card and do not expose SC_ERROR_FILE_END_REACHED outside of the function (like sc_pkcs15_read_file) This is to facilitate Estonian eID 2018+ that instead of properly returning 6282 with trunkated data, 9000 is returned and next READ BINARY returns 6b00 (invalid p1/p2). The change should be generally harmless for well-behaving cards. Change-Id: I7511ab4841d3bcdf8d6f4a37a9315ea4ac569b10 --- src/libopensc/iso7816.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 47f5053fe2..a9b480eaa0 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -152,10 +152,8 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); - if (apdu.resplen == 0) - LOG_FUNC_RETURN(ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r == SC_ERROR_FILE_END_REACHED) LOG_FUNC_RETURN(ctx, apdu.resplen); LOG_TEST_RET(ctx, r, "Check SW error"); From 4ba086bfd4882ba0c2d51d01c35efabab7bb5dbe Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Jan 2019 12:55:02 +0200 Subject: [PATCH 0832/4321] Use strdup and fix all casts Signed-off-by: Raul Metsma --- src/libopensc/pkcs15-esteid.c | 46 ++++++++++++----------------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 0e401e653f..88034648b1 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -30,21 +30,11 @@ #include #include "common/compat_strlcpy.h" -#include "common/compat_strlcat.h" #include "internal.h" #include "opensc.h" #include "pkcs15.h" -static void -set_string (char **strp, const char *value) -{ - if (*strp) - free (*strp); - *strp = value ? strdup (value) : NULL; -} - - static int sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) { @@ -55,8 +45,8 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) size_t field_length = 0, modulus_length = 0; sc_path_t tmppath; - set_string (&p15card->tokeninfo->label, "ID-kaart"); - set_string (&p15card->tokeninfo->manufacturer_id, "AS Sertifitseerimiskeskus"); + p15card->tokeninfo->label = strdup("ID-kaart"); + p15card->tokeninfo->manufacturer_id = strdup("AS Sertifitseerimiskeskus"); /* Select application directory */ sc_format_path ("3f00eeee5044", &tmppath); @@ -67,7 +57,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); LOG_TEST_RET(card->ctx, r, "read document number failed"); buff[MIN((size_t) r, (sizeof buff)-1)] = '\0'; - set_string (&p15card->tokeninfo->serial_number, (const char *) buff); + p15card->tokeninfo->serial_number = strdup((const char *)buff); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT @@ -81,7 +71,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) static char const *esteid_cert_paths[2] = { "3f00eeeeaace", "3f00eeeeddce"}; - static int esteid_cert_ids[2] = {1, 2}; + static u8 esteid_cert_ids[2] = {1, 2}; struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; @@ -113,15 +103,11 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, cert->subject_len, &cn_oid, &cn_name, &cn_len); if (cn_len > 0) { - char *token_name = malloc(cn_len+1); - if (token_name) { - memcpy(token_name, cn_name, cn_len); - token_name[cn_len] = '\0'; - set_string(&p15card->tokeninfo->label, (const char*)token_name); - free(token_name); - } + cn_name = realloc(cn_name, cn_len + 1); + cn_name[cn_len] = 0; + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = (char*) cn_name; } - free(cn_name); sc_pkcs15_free_certificate(cert); } @@ -133,16 +119,15 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* add pins */ for (i = 0; i < 3; i++) { - unsigned char tries_left; static const char *esteid_pin_names[3] = { "PIN1", "PIN2", "PUK" }; - static const int esteid_pin_min[3] = {4, 5, 8}; + static const unsigned int esteid_pin_min[3] = {4, 5, 8}; static const int esteid_pin_ref[3] = {1, 2, 0}; - static const int esteid_pin_authid[3] = {1, 2, 3}; - static const int esteid_pin_flags[3] = {0, 0, SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + static const u8 esteid_pin_authid[3] = {1, 2, 3}; + static const unsigned int esteid_pin_flags[3] = {0, 0, SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; @@ -151,10 +136,9 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) memset(&pin_obj, 0, sizeof(pin_obj)); /* read the number of tries left for the PIN */ - r = sc_read_record (card, i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); - if (r < 0) + r = sc_read_record (card, (unsigned int) i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); + if (r < 6) return SC_ERROR_INTERNAL; - tries_left = buff[5]; pin_info.auth_id.len = 1; pin_info.auth_id.value[0] = esteid_pin_authid[i]; @@ -166,7 +150,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) pin_info.attrs.pin.stored_length = 12; pin_info.attrs.pin.max_length = 12; pin_info.attrs.pin.pad_char = '\0'; - pin_info.tries_left = (int)tries_left; + pin_info.tries_left = buff[5]; pin_info.max_tries = 3; strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label)); @@ -185,7 +169,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* add private keys */ for (i = 0; i < 2; i++) { - static int prkey_pin[2] = {1, 2}; + static u8 prkey_pin[2] = {1, 2}; static const char *prkey_name[2] = { "Isikutuvastus", From f1e91085025559975919c4b1c99c83fc66bdcd65 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Mar 2019 00:05:52 +0100 Subject: [PATCH 0833/4321] fix cygwin build fixes https://github.com/OpenSC/OpenSC/issues/607 --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index e3697bd2a8..99806dbf56 100644 --- a/configure.ac +++ b/configure.ac @@ -106,7 +106,6 @@ case "${host}" in WIN32="yes" else AC_MSG_RESULT([Using cygwin]) - CPPFLAGS="${CPPFLAGS} -DCRYPTOKI_FORCE_WIN32" WIN_LIBPREFIX="cyg" AC_DEFINE([USE_CYGWIN], [1], [Define if you are on Cygwin]) fi From f3d8ad9f90bba65d42df43529752c04142e0ec90 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 3 Apr 2019 14:50:04 +0200 Subject: [PATCH 0834/4321] macOS: fixed propagating OpenPACE flags --- MacOSX/build-package.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index e9db05f884..044675855c 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -52,9 +52,9 @@ if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then ./configure --disable-shared --prefix=$PREFIX CRYPTO_CFLAGS="$OPENSSL_CFLAGS" CRYPTO_LIBS="$OPENSSL_LIBS" make DESTDIR=$BUILDPATH/openpace_bin install cd .. - export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" - export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" fi +export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" +export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then ./configure --prefix=$PREFIX \ From 9ba8f560378321ed50bf8681a8a6b6301dba231a Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 19 Mar 2019 11:50:17 +0200 Subject: [PATCH 0835/4321] Change u8 *data to const because sc_apdu unsigned char *data is const Name sc_format_apdu parameters for IDE help hints Signed-off-by: Raul Metsma --- src/libopensc/card.c | 2 +- src/libopensc/opensc.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 423bc09a50..df2ab3a20a 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -101,7 +101,7 @@ void sc_format_apdu_cse_lc_le(struct sc_apdu *apdu) } void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, - u8 ins, u8 p1, u8 p2, u8 *data, size_t datalen, u8 *resp, size_t resplen) + u8 ins, u8 p1, u8 p2, const u8 *data, size_t datalen, u8 *resp, size_t resplen) { if (!apdu) { return; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index bbf0ea191a..c56a0dfc63 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -811,11 +811,12 @@ typedef struct sc_context { */ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); -void sc_format_apdu(struct sc_card *, struct sc_apdu *, int, int, int, int); +void sc_format_apdu(struct sc_card *card, struct sc_apdu *apdu, + int cse, int ins, int p1, int p2); void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, u8 ins, u8 p1, u8 p2, - u8 *data, size_t datalen, u8 *resp, size_t resplen); + const u8 *data, size_t datalen, u8 *resp, size_t resplen); int sc_check_apdu(struct sc_card *, const struct sc_apdu *); From 0abe9d11c75f8d9de32e862a5a9775aa70a44cc3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 7 Mar 2019 13:42:24 +0100 Subject: [PATCH 0836/4321] pkcs11: (de-) initialize notifications on load fixes https://github.com/OpenSC/OpenSC/issues/1507 fixes https://github.com/OpenSC/pkcs11-helper/issues/16 --- src/pkcs11/Makefile.am | 4 ++-- src/pkcs11/pkcs11-global.c | 42 ++++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index bc3b494070..0d7c0439b6 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -17,12 +17,12 @@ OPENSC_PKCS11_SRC = pkcs11-global.c pkcs11-session.c pkcs11-object.c misc.c slot framework-pkcs15init.c debug.c pkcs11.exports \ pkcs11-display.c pkcs11-display.h OPENSC_PKCS11_CFLAGS = \ - $(OPTIONAL_OPENSSL_CFLAGS) $(OPENSC_PKCS11_PTHREAD_CFLAGS) + $(OPENPACE_CFLAGS) $(OPTIONAL_OPENSSL_CFLAGS) $(OPENSC_PKCS11_PTHREAD_CFLAGS) OPENSC_PKCS11_LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la \ - $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) + $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opensc-pkcs11.pc diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 51d80120f5..5353d778f1 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -37,6 +37,11 @@ #include "sc-pkcs11.h" #include "ui/notify.h" +#include "libopensc/sc-ossl-compat.h" +#ifdef ENABLE_OPENPACE +#include +#endif + #ifndef MODULE_APP_NAME #define MODULE_APP_NAME "opensc-pkcs11" #endif @@ -210,13 +215,31 @@ static int slot_list_seeker(const void *el, const void *key) { return 0; } -#if defined(_WIN32) +#ifndef _WIN32 +__attribute__((constructor)) +#endif +int module_init() +{ + sc_notify_init(); + return 1; +} -#include "libopensc/sc-ossl-compat.h" +#ifndef _WIN32 +__attribute__((destructor)) +#endif +int module_close() +{ + sc_notify_close(); +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) + CRYPTO_secure_malloc_done(); +#endif #ifdef ENABLE_OPENPACE -#include + EAC_cleanup(); #endif + return 1; +} +#ifdef _WIN32 BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved @@ -225,16 +248,13 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - sc_notify_init(); + if (!module_init()) + return FALSE; + break; case DLL_PROCESS_DETACH: - sc_notify_close(); if (lpReserved == NULL) { -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) - CRYPTO_secure_malloc_done(); -#endif -#ifdef ENABLE_OPENPACE - EAC_cleanup(); -#endif + if (!module_close()) + return FALSE; } break; } From fd20ffe6081c3bc4b0c207f16787f353cd21c61f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 4 Apr 2019 12:52:08 +0200 Subject: [PATCH 0837/4321] optimize bin/hex low parsing level functions (#1646) * optimize sc_hex_to_bin * optimize sc_bin_to_hex * added documentation closes https://github.com/OpenSC/OpenSC/pull/1643 thanks to carblue --- src/libopensc/opensc.h | 19 +++++++ src/libopensc/sc.c | 121 +++++++++++++++++++++++------------------ 2 files changed, 86 insertions(+), 54 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index c56a0dfc63..31aa1629a1 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1379,6 +1379,25 @@ const sc_path_t *sc_get_mf_path(void); /********************************************************************/ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen); +/** + * Converts an u8 array to a string representing the input as hexadecimal, + * human-readable/printable form. It's the inverse function of sc_hex_to_bin. + * + * @param in The u8 array input to be interpreted, may be NULL iff in_len==0 + * @param in_len Less or equal to the amount of bytes available from in + * @param out output buffer offered for the string representation, *MUST NOT* + * be NULL and *MUST* be sufficiently sized, see out_len + * @param out_len *MUST* be at least 1 and state the maximum of bytes available + * within out to be written, including the \0 termination byte + * that will be written unconditionally + * @param separator The character to be used to separate the u8 string + * representations. `0` will suppress separation. + * + * Example: input [0x3f], in_len=1, requiring an out_len>=3, will write to out: + * [0x33, 0x66, 0x00] which reads as "3f" + * Example: input [0x3f, 0x01], in_len=2, separator=':', req. an out_len>=6, + * writes to out: [0x33, 0x66, 0x3A, 0x30, 0x31, 0x00] which reads as "3f:01" + */ int sc_bin_to_hex(const u8 *, size_t, char *, size_t, int separator); size_t sc_right_trim(u8 *buf, size_t len); scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 19407a10ed..1e11b5404c 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -63,77 +63,90 @@ const char *sc_get_version(void) int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen) { - int err = SC_SUCCESS; - size_t left, count = 0, in_len; - + const char *sc_hex_to_bin_separators = " :"; if (in == NULL || out == NULL || outlen == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - left = *outlen; - in_len = strlen(in); - while (*in != '\0') { - int byte = 0, nybbles = 2; - - while (nybbles-- && *in && *in != ':' && *in != ' ') { - char c; - byte <<= 4; - c = *in++; - if ('0' <= c && c <= '9') - c -= '0'; - else - if ('a' <= c && c <= 'f') - c = c - 'a' + 10; - else - if ('A' <= c && c <= 'F') - c = c - 'A' + 10; - else { - err = SC_ERROR_INVALID_ARGUMENTS; - goto out; - } - byte |= c; + int byte_needs_nibble = 0; + int r = SC_SUCCESS; + size_t left = *outlen; + u8 byte = 0; + while (*in != '\0' && 0 != left) { + char c = *in++; + u8 nibble; + if ('0' <= c && c <= '9') + nibble = c - '0'; + else if ('a' <= c && c <= 'f') + nibble = c - 'a' + 10; + else if ('A' <= c && c <= 'F') + nibble = c - 'A' + 10; + else { + if (strchr(sc_hex_to_bin_separators, (int) c)) + continue; + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; } - /* Detect premature end of string before byte is complete */ - if (in_len > 1 && *in == '\0' && nybbles >= 0) { - err = SC_ERROR_INVALID_ARGUMENTS; - break; + if (byte_needs_nibble) { + byte |= nibble; + *out++ = (u8) byte; + left--; + byte_needs_nibble = 0; + } else { + byte = nibble << 4; + byte_needs_nibble = 1; } + } - if (*in == ':' || *in == ' ') - in++; - if (left <= 0) { - err = SC_ERROR_BUFFER_TOO_SMALL; + /* for ease of implementation we only accept completely hexed bytes. */ + if (byte_needs_nibble) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } + + /* skip all trailing separators to see if we missed something */ + while (*in != '\0') { + if (NULL == strchr(sc_hex_to_bin_separators, (int) *in)) break; - } - out[count++] = (u8) byte; - left--; + in++; + } + if (*in != '\0') { + r = SC_ERROR_BUFFER_TOO_SMALL; + goto err; } -out: - *outlen = count; - return err; +err: + *outlen -= left; + return r; } int sc_bin_to_hex(const u8 *in, size_t in_len, char *out, size_t out_len, - int in_sep) + int in_sep) { - unsigned int n, sep_len; - char *pos, *end, sep; - - sep = (char)in_sep; - sep_len = sep > 0 ? 1 : 0; - pos = out; - end = out + out_len; - for (n = 0; n < in_len; n++) { - if (pos + 3 + sep_len >= end) + if (in == NULL || out == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + + if (in_sep > 0) { + if (out_len < in_len*3 || out_len < 1) + return SC_ERROR_BUFFER_TOO_SMALL; + } else { + if (out_len < in_len*2 + 1) return SC_ERROR_BUFFER_TOO_SMALL; - if (n && sep_len) - *pos++ = sep; - sprintf(pos, "%02x", in[n]); - pos += 2; } - *pos = '\0'; + + const char hex[] = "0123456789abcdef"; + while (in_len) { + unsigned char value = *in++; + *out++ = hex[(value >> 4) & 0xF]; + *out++ = hex[ value & 0xF]; + in_len--; + if (in_len && in_sep > 0) + *out++ = (char)in_sep; + } + *out = '\0'; + return SC_SUCCESS; } From 4913feadb8c5d8cb2302054d76721364ff43d9f7 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 5 Apr 2019 10:38:12 +0200 Subject: [PATCH 0838/4321] Fix in encrypt_decrypt(), check for (in_len <= sizeof orig_data) --- src/tools/pkcs11-tool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b91a660bbd..d12632453c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5361,6 +5361,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } + if (in_len >= sizeof(orig_data)) { + printf("Private key size is too long\n"); + return 0; + } + EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx) { From f631b5f733c9332e6bd68649afe8b926bf378911 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 5 Apr 2019 10:39:52 +0200 Subject: [PATCH 0839/4321] Fix in encrypt_decrypt(), check for (in_len <= sizeof orig_data) --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d12632453c..a2f2a94dc3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5361,7 +5361,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } - if (in_len >= sizeof(orig_data)) { + if (in_len > sizeof(orig_data)) { printf("Private key size is too long\n"); return 0; } From 8c99e5076a829af618d0cb7ebb2b0b80e51831e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Feb 2019 19:48:34 +0100 Subject: [PATCH 0840/4321] tests: Verify the pkcs11-tool --test works Note, that it does not work now until #1600 will get resolved. Then, move the test to TESTS in the Makefile.am --- .gitignore | 3 ++ tests/Makefile.am | 9 +++- tests/common.sh | 66 +++++++++++++++++++++++++ tests/test-pkcs11-tool-sign-verify.sh | 71 +++------------------------ tests/test-pkcs11-tool-test.sh | 25 ++++++++++ 5 files changed, 109 insertions(+), 65 deletions(-) create mode 100644 tests/common.sh create mode 100755 tests/test-pkcs11-tool-test.sh diff --git a/.gitignore b/.gitignore index d8d2bdf056..551c98d68c 100644 --- a/.gitignore +++ b/.gitignore @@ -109,4 +109,7 @@ src/tests/pintest src/tests/prngtest src/tests/p11test/p11test +tests/*.log +tests/*.trs + version.m4.ci diff --git a/tests/Makefile.am b/tests/Makefile.am index 66323e9d79..b319986e9d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,12 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in dist_noinst_SCRIPTS = test-manpage.sh \ test-fuzzing.sh \ + test-pkcs11-tool-test.sh \ test-pkcs11-tool-sign-verify.sh -TESTS = test-manpage.sh \ - test-pkcs11-tool-sign-verify.sh +TESTS = \ + test-manpage.sh \ + test-pkcs11-tool-sign-verify.sh \ + test-pkcs11-tool-test.sh +XFAIL_TESTS = \ + test-pkcs11-tool-test.sh diff --git a/tests/common.sh b/tests/common.sh new file mode 100644 index 0000000000..e50eeb05e1 --- /dev/null +++ b/tests/common.sh @@ -0,0 +1,66 @@ +#!/bin/bash +## from OpenSC/src/tests/p11test/runtest.sh + +SOPIN="12345678" +PIN="123456" +PKCS11_TOOL="../src/tools/pkcs11-tool" +P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" + +ERRORS=0 +function assert() { + if [[ $1 != 0 ]]; then + echo "====> ERROR: $2" + ERRORS=1 + fi +} + +function generate_key() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # Generate key pair + $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ + --module="$P11LIB" --label="$LABEL" --id=$ID + + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate $TYPE key pair" + return 1 + fi + + # Extract public key from the card + $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ + --module="$P11LIB" + + # convert it to more digestible PEM format + if [[ ${TYPE:0:3} == "RSA" ]]; then + openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + else + openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + fi + rm $ID.der +} + +function card_setup() { + echo "directories.tokendir = .tokens/" > .softhsm2.conf + mkdir ".tokens" + export SOFTHSM2_CONF=".softhsm2.conf" + # Init token + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" + + # Generate 1024b RSA Key pair + generate_key "RSA:1024" "01" "RSA_auth" + # Generate 2048b RSA Key pair + generate_key "RSA:2048" "02" "RSA2048" + # Generate 256b ECC Key pair + # generate_key "EC:secp256r1" "03" "ECC_auth" + # Generate 521b ECC Key pair + # generate_key "EC:secp521r1" "04" "ECC521" + # TODO ECDSA keys tests +} + +function card_cleanup() { + rm .softhsm2.conf + rm -rf ".tokens" + rm 0{1,2}.pub +} diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index a0b5bc5253..e5098fda94 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -1,67 +1,6 @@ -## from OpenSC/src/tests/p11test/runtest.sh -SOPIN="12345678" -PIN="123456" -PKCS11_TOOL="../src/tools/pkcs11-tool" -P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" +#!/bin/bash -ERRORS=0 -function assert() { - if [[ $1 != 0 ]]; then - echo "====> ERROR: $2" - ERRORS=1 - fi -} - -function generate_key() { - TYPE="$1" - ID="$2" - LABEL="$3" - - # Generate key pair - $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --module="$P11LIB" --label="$LABEL" --id=$ID - - if [[ "$?" -ne "0" ]]; then - echo "Couldn't generate $TYPE key pair" - return 1 - fi - - # Extract public key from the card - $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ - --module="$P11LIB" - - # convert it to more digestible PEM format - if [[ ${TYPE:0:3} == "RSA" ]]; then - openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - else - openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - fi - rm $ID.der -} - -function card_setup() { - echo "directories.tokendir = .tokens/" > .softhsm2.conf - mkdir ".tokens" - export SOFTHSM2_CONF=".softhsm2.conf" - # Init token - softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" - - # Generate 1024b RSA Key pair - generate_key "RSA:1024" "01" "RSA_auth" - # Generate 2048b RSA Key pair - generate_key "RSA:2048" "02" "RSA2048" - # Generate 256b ECC Key pair - # generate_key "EC:secp256r1" "03" "ECC_auth" - # Generate 521b ECC Key pair - # generate_key "EC:secp521r1" "04" "ECC521" - # TODO ECDSA keys tests -} - -function card_cleanup() { - rm .softhsm2.conf - rm -rf ".tokens" - rm 0{1,2}.pub -} +source common.sh echo "=======================================================" echo "Setup SoftHSM" @@ -73,6 +12,10 @@ fi card_setup echo "data to sign (max 100 bytes)" > data + +echo "=======================================================" +echo "Test" +echo "=======================================================" for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do for SIGN_KEY in "01" "02"; do METHOD="RSA-PKCS" @@ -172,4 +115,6 @@ echo "Cleanup" echo "=======================================================" card_cleanup +rm data + exit $ERRORS diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh new file mode 100755 index 0000000000..512fdb0086 --- /dev/null +++ b/tests/test-pkcs11-tool-test.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +source common.sh + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +card_setup + +echo "=======================================================" +echo "Test" +echo "=======================================================" +$PKCS11_TOOL --test -p $PIN --module $P11LIB +assert $? "Failed running tests" + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +card_cleanup + +exit $ERRORS From 775d1205179677d837ebbacc0d1fc39b4100ac3c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Mar 2019 10:50:16 +0100 Subject: [PATCH 0841/4321] tests: Verify the ECDSA signatures work --- tests/common.sh | 7 +++--- tests/test-pkcs11-tool-sign-verify.sh | 36 ++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index e50eeb05e1..3146eb2abc 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -53,14 +53,13 @@ function card_setup() { # Generate 2048b RSA Key pair generate_key "RSA:2048" "02" "RSA2048" # Generate 256b ECC Key pair - # generate_key "EC:secp256r1" "03" "ECC_auth" + generate_key "EC:secp256r1" "03" "ECC_auth" # Generate 521b ECC Key pair - # generate_key "EC:secp521r1" "04" "ECC521" - # TODO ECDSA keys tests + generate_key "EC:secp521r1" "04" "ECC521" } function card_cleanup() { rm .softhsm2.conf rm -rf ".tokens" - rm 0{1,2}.pub + rm 0{1,2,3,4}.pub } diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index e5098fda94..299d2f4ab6 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -12,9 +12,8 @@ fi card_setup echo "data to sign (max 100 bytes)" > data - echo "=======================================================" -echo "Test" +echo "Test RSA keys" echo "=======================================================" for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do for SIGN_KEY in "01" "02"; do @@ -55,7 +54,7 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" echo "=======================================================" if [[ -z $HASH ]]; then - # hashing is done outside of the module. We chouse here SHA256 + # hashing is done outside of the module. We choose here SHA256 openssl dgst -binary -sha256 data > data.hash HASH_ALGORITM="--hash-algorithm=SHA256" VERIFY_DGEST="-sha256" @@ -110,6 +109,37 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do done done +echo "=======================================================" +echo "Test ECDSA keys" +echo "=======================================================" +for SIGN_KEY in "03" "04"; do + METHOD="ECDSA" + + echo + echo "=======================================================" + echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" + echo "=======================================================" + openssl dgst -binary -sha256 data > data.hash + $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + --input-file data.hash --output-file data.sig + assert $? "Failed to Sign data" + $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + --input-file data.hash --output-file data.sig.openssl \ + --signature-format openssl + assert $? "Failed to Sign data into OpenSSL format" + + # OpenSSL verification + openssl dgst -keyform PEM -verify $SIGN_KEY.pub -sha256 \ + -signature data.sig.openssl data + assert $? "Failed to Verify signature using OpenSSL" + + # pkcs11-tool verification + $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ + --input-file data.hash --signature-file data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.sig{,.openssl} data.hash +done + echo "=======================================================" echo "Cleanup" echo "=======================================================" From fc4d600634839291399c0fe1a2b0127132403488 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Mar 2019 17:52:31 +0100 Subject: [PATCH 0842/4321] pkcs11-tool: Allow to set CKA_ALLOWED_MECHANISMS when creating an objects Also list them in the attributes listing --- doc/tools/pkcs11-tool.1.xml | 11 ++++++ src/tools/pkcs11-tool.c | 74 ++++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index d85a1a5eba..ce9419541c 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -453,6 +453,17 @@ + + + mechanisms + + Sets the CKA_ALLOWED_MECHANISMS attribute + to a key objects when importing an object or generating + a keys. The argument accepts comma-separated list of + algorithmsm, that can be used with the given key. + + + diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 3c0572d4bc..b6b799a6ef 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -155,7 +155,8 @@ enum { OPT_SALT, OPT_VERIFY, OPT_SIGNATURE_FILE, - OPT_ALWAYS_AUTH + OPT_ALWAYS_AUTH, + OPT_ALLOWED_MECHANISMS }; static const struct option options[] = { @@ -213,6 +214,7 @@ static const struct option options[] = { { "signature-file", 1, NULL, OPT_SIGNATURE_FILE }, { "output-file", 1, NULL, 'o' }, { "signature-format", 1, NULL, 'f' }, + { "allowed-mechanisms", 1, NULL, OPT_ALLOWED_MECHANISMS }, { "test", 0, NULL, 't' }, { "test-hotplug", 0, NULL, OPT_TEST_HOTPLUG }, @@ -285,6 +287,7 @@ static const char *option_help[] = { "Specify the file with signature for verification", "Specify the output file", "Format for ECDSA signature : 'rs' (default), 'sequence', 'openssl'", + "Specify the comma-separated list of allowed mechanisms when creating an object.", "Test (best used with the --login or --pin option)", "Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)", @@ -332,6 +335,9 @@ static char * opt_issuer = NULL; static char * opt_subject = NULL; static char * opt_key_type = NULL; static char * opt_sig_format = NULL; +#define MAX_ALLOWED_MECHANISMS 20 +static CK_MECHANISM_TYPE opt_allowed_mechanisms[MAX_ALLOWED_MECHANISMS]; +static size_t opt_allowed_mechanisms_len = 0; static int opt_is_private = 0; static int opt_is_sensitive = 0; static int opt_test_hotplug = 0; @@ -496,7 +502,7 @@ get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \ } \ if (pulCount) \ *pulCount = attr.ulValueLen / sizeof(TYPE); \ - } else { \ + } else if (rv != CKR_ATTRIBUTE_TYPE_INVALID) { \ p11_warn("C_GetAttributeValue(" #ATTR ")", rv); \ } \ return (TYPE *) attr.pValue; \ @@ -534,6 +540,7 @@ VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */ VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */ VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */ +VARATTR_METHOD(ALLOWED_MECHANISMS, CK_MECHANISM_TYPE); /* getALLOWED_MECHANISMS */ int main(int argc, char * argv[]) @@ -571,6 +578,7 @@ int main(int argc, char * argv[]) int do_unlock_pin = 0; int action_count = 0; int do_generate_random = 0; + char *s = NULL; CK_RV rv; #ifdef _WIN32 @@ -896,6 +904,22 @@ int main(int argc, char * argv[]) case OPT_ALWAYS_AUTH: opt_always_auth = 1; break; + case OPT_ALLOWED_MECHANISMS: + /* Parse the mechanism list and fail early */ + s = strtok(optarg, ","); + while (s != NULL) { + if (opt_allowed_mechanisms_len > MAX_ALLOWED_MECHANISMS) { + fprintf(stderr, "Too many mechanisms provided" + " (max %d). Skipping the rest.", MAX_ALLOWED_MECHANISMS); + break; + } + + opt_allowed_mechanisms[opt_allowed_mechanisms_len] = + p11_name_to_mechanism(s); + opt_allowed_mechanisms_len++; + s = strtok(NULL, ","); + } + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -2186,6 +2210,7 @@ static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session) #define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;} +/* Generate asymmetric key pair */ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hPublicKey, CK_OBJECT_HANDLE *hPrivateKey, const char *type) { @@ -2402,6 +2427,13 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(privateKeyTemplate[n_privkey_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_privkey_attr++; + } + rv = p11->C_GenerateKeyPair(session, &mechanism, publicKeyTemplate, n_pubkey_attr, privateKeyTemplate, n_privkey_attr, @@ -2419,6 +2451,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, return 1; } +/* generate symmetric key */ static int gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey, const char *type, char *label) @@ -2538,6 +2571,13 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey n_attr++; } + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(keyTemplate[n_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_attr++; + } + rv = p11->C_GenerateKey(session, &mechanism, keyTemplate, n_attr, hSecretKey); if (rv != CKR_OK) p11_fatal("C_GenerateKey", rv); @@ -2996,6 +3036,13 @@ static int write_object(CK_SESSION_HANDLE session) &_true, sizeof(_true)); n_privkey_attr++; } + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(privkey_templ[n_privkey_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_privkey_attr++; + } + #ifdef ENABLE_OPENSSL if (cert.subject_len != 0) { @@ -3533,6 +3580,13 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); n_attrs++; + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(newkey_template[n_attrs], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_attrs++; + } + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) @@ -3631,6 +3685,7 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) static void show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { + CK_MECHANISM_TYPE_PTR mechs = NULL; CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj); CK_ULONG size = 0; unsigned char *id, *oid, *value; @@ -3836,6 +3891,21 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) printf(" Access: always authenticate\n"); + + if (!pub) { + mechs = getALLOWED_MECHANISMS(sess, obj, &size); + if (mechs && size) { + unsigned int n; + + printf(" Allowed mechanisms: "); + for (n = 0; n < size; n++) { + printf("%s%s", (n != 0 ? "," : ""), + p11_mechanism_to_name(mechs[n])); + } + printf("\n"); + } + } + suppress_warn = 0; } From 83eeafca3c17b886345b27132ca9c466eb85fd32 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Mar 2019 17:54:55 +0100 Subject: [PATCH 0843/4321] tests: Check the behavior of CKA_ALLOWED_MECHANISMS --- tests/Makefile.am | 6 ++- tests/common.sh | 12 ++++- tests/test-pkcs11-tool-allowed-mechanisms.sh | 51 ++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100755 tests/test-pkcs11-tool-allowed-mechanisms.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index b319986e9d..d1230d93a4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,6 +8,8 @@ dist_noinst_SCRIPTS = test-manpage.sh \ TESTS = \ test-manpage.sh \ test-pkcs11-tool-sign-verify.sh \ - test-pkcs11-tool-test.sh + test-pkcs11-tool-test.sh \ + test-pkcs11-tool-allowed-mechanisms.sh XFAIL_TESTS = \ - test-pkcs11-tool-test.sh + test-pkcs11-tool-test.sh \ + test-pkcs11-tool-allowed-mechanisms.sh diff --git a/tests/common.sh b/tests/common.sh index 3146eb2abc..4fa1fba00c 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -41,12 +41,16 @@ function generate_key() { rm $ID.der } -function card_setup() { +function softhsm_initialize() { echo "directories.tokendir = .tokens/" > .softhsm2.conf mkdir ".tokens" export SOFTHSM2_CONF=".softhsm2.conf" # Init token softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" +} + +function card_setup() { + softhsm_initialize # Generate 1024b RSA Key pair generate_key "RSA:1024" "01" "RSA_auth" @@ -58,8 +62,12 @@ function card_setup() { generate_key "EC:secp521r1" "04" "ECC521" } -function card_cleanup() { +function softhsm_cleanup() { rm .softhsm2.conf rm -rf ".tokens" +} + +function card_cleanup() { + softhsm_cleanup rm 0{1,2,3,4}.pub } diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh new file mode 100755 index 0000000000..25a6923529 --- /dev/null +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +source common.sh + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +softhsm_initialize +# XXX This is broken in currently released SoftHSM +# P11LIB=/home/jjelen/devel/SoftHSMv2/src/lib/.libs/libsofthsm2.so + +echo "=======================================================" +echo "Generate key-pair with CKA_ALLOWED_MECHANISMS" +echo "=======================================================" +ID="05" +MECHANISMS="RSA-PKCS,SHA1-RSA-PKCS,RSA-PKCS-PSS" +# Generate key pair +$PKCS11_TOOL --keypairgen --key-type="RSA:" --login --pin=$PIN \ + --module="$P11LIB" --label="test" --id="$ID" \ + --allowed-mechanisms="$MECHANISMS" +assert $? "Failed to Generate RSA key pair" + +# Check the attributes are visible +$PKCS11_TOOL --list-objects --login --pin=$PIN \ + --module="$P11LIB" --id=$ID > objects.list +assert $? "Failed to list objects" +grep -q "Allowed mechanisms" objects.list +assert $? "Allowed mechanisms not in the object list" +grep -q "$MECHANISMS" objects.list +assert $? "The $MECHANISMS is not in the list" + +# Make sure we are not allowed to use forbidden mechanism +echo "data to sign (max 100 bytes)" > data +$PKCS11_TOOL --id $ID -s -p $PIN -m SHA256-RSA-PKCS --module $P11LIB \ + --input-file data --output-file data.sig &> sign.log +grep -q CKR_MECHANISM_INVALID sign.log +assert $? "It was possible to sign using non-allowed mechanism" +rm -f data{,.sig} + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +softhsm_cleanup + +rm objects.list + +exit $ERRORS From 6f9b58af72307013f3f5bdeeea2415333a9aaf43 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 18 Mar 2019 23:08:58 +0100 Subject: [PATCH 0844/4321] added pkcs11-register --- .gitignore | 2 + MacOSX/Distribution.xml.in | 3 + MacOSX/build-package.in | 5 + configure.ac | 13 + src/tools/Makefile.am | 33 +- src/tools/Makefile.mak | 23 +- src/tools/pkcs11-register-cmdline.c | 586 +++++++++++++++++++++++++++ src/tools/pkcs11-register-cmdline.h | 189 +++++++++ src/tools/pkcs11-register.c | 336 +++++++++++++++ src/tools/pkcs11-register.desktop.in | 8 + src/tools/pkcs11-register.ggo.in | 28 ++ src/tools/pkcs11-register.plist.in | 14 + win32/OpenSC.wxs.in | 18 + win32/winconfig.h.in | 3 + 14 files changed, 1246 insertions(+), 15 deletions(-) create mode 100644 src/tools/pkcs11-register-cmdline.c create mode 100644 src/tools/pkcs11-register-cmdline.h create mode 100644 src/tools/pkcs11-register.c create mode 100644 src/tools/pkcs11-register.desktop.in create mode 100644 src/tools/pkcs11-register.ggo.in create mode 100644 src/tools/pkcs11-register.plist.in diff --git a/.gitignore b/.gitignore index 551c98d68c..60080e5281 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,8 @@ src/tools/cardos-info src/tools/sceac-example src/tools/opensc-notify src/tools/org.opensc.notify.desktop +src/tools/pkcs11-register +src/tools/pkcs11-register.desktop src/tools/opensc-asn1 win32/OpenSC.iss diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index c42f94c990..9443938bde 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -20,4 +20,7 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D OpenSC-tokend.pkg + + OpenSC-startup.pkg + diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 044675855c..48f4a25a81 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -122,9 +122,14 @@ imagedir=$(mktemp -d) mkdir -p ${BUILDPATH}/target/usr/local/bin cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin +# Prepare startup root +mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents +cp src/tools/pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents + # Build package pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg pkgbuild --root ${BUILDPATH}/target_tokend --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg +pkgbuild --root ${BUILDPATH}/target_startup --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg # Build product productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" diff --git a/configure.ac b/configure.ac index 99806dbf56..dd9156555b 100644 --- a/configure.ac +++ b/configure.ac @@ -260,6 +260,13 @@ AC_ARG_ENABLE( [enable_notify="detect"] ) +AC_ARG_ENABLE( + [autostart-items], + [AS_HELP_STRING([--enable-autostart-items],[enable autostart items @<:@enabled@:>@])], + , + [enable_autostart="yes"] +) + AC_ARG_ENABLE( [tests], [AS_HELP_STRING([--enable-tests],[Build tests in src/tests/ directory @<:@detect@:>@])], @@ -894,11 +901,14 @@ fi if test "${with_pkcs11_provider}" = "detect"; then if test "${WIN32}" != "yes"; then DEFAULT_PKCS11_PROVIDER="${libdir}/opensc-pkcs11${DYN_LIB_EXT}" + DEFAULT_ONEPIN_PKCS11_PROVIDER="${libdir}/onepin-opensc-pkcs11${DYN_LIB_EXT}" else DEFAULT_PKCS11_PROVIDER="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\pkcs11\\\opensc-pkcs11.dll" + DEFAULT_ONEPIN_PKCS11_PROVIDER="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\pkcs11\\\onepin-opensc-pkcs11.dll" fi else DEFAULT_PKCS11_PROVIDER="${with_pkcs11_provider}" + DEFAULT_ONEPIN_PKCS11_PROVIDER="${with_pkcs11_provider}" fi if test "${enable_man}" = "detect"; then @@ -1010,6 +1020,7 @@ AC_SUBST([OPENSC_LT_OLDEST]) AC_SUBST([WIN_LIBPREFIX]) AC_SUBST([DEFAULT_PCSC_PROVIDER]) AC_SUBST([DEFAULT_PKCS11_PROVIDER]) +AC_SUBST([DEFAULT_ONEPIN_PKCS11_PROVIDER]) AC_SUBST([OPTIONAL_ZLIB_CFLAGS]) AC_SUBST([OPTIONAL_ZLIB_LIBS]) AC_SUBST([OPTIONAL_READLINE_CFLAGS]) @@ -1044,6 +1055,7 @@ AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidrive AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"]) AM_CONDITIONAL([ENABLE_DNIE_UI], [test "${enable_dnie_ui}" = "yes"]) AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"]) +AM_CONDITIONAL([ENABLE_AUTOSTART], [test "${enable_autostart}" = "yes"]) AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) @@ -1143,6 +1155,7 @@ Build tests: ${enable_tests} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} PKCS11 default provider: $(eval eval eval echo "${DEFAULT_PKCS11_PROVIDER}") +PKCS11 onepin provider: $(eval eval eval echo "${DEFAULT_ONEPIN_PKCS11_PROVIDER}") Host: ${host} Compiler: ${CC} diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 495078d374..13865c9ce7 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -16,18 +16,19 @@ do_subst = $(SED) \ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ -e 's,[@]PACKAGE_VERSION[@],"$(PACKAGE_VERSION)",g' \ + -e 's,[@]DEFAULT_PKCS11_PROVIDER[@],"$(DEFAULT_PKCS11_PROVIDER)",g' \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in pkcs11-register.plist.in noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ opensc-asn1-cmdline.h opensc-notify-cmdline.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ - pkcs15-tool pkcs15-crypt pkcs11-tool \ + pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 goid-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ @@ -36,7 +37,7 @@ endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' +AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' -D'DEFAULT_ONEPIN_PKCS11_PROVIDER="$(DEFAULT_ONEPIN_PKCS11_PROVIDER)"' LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ @@ -127,6 +128,15 @@ if HAVE_UNKNOWN_WARNING_OPTION opensc_asn1_CFLAGS += -Wno-unknown-warning-option endif +pkcs11_register_SOURCES = pkcs11-register.c fread_to_eof.c pkcs11-register-cmdline.c +pkcs11_register_CFLAGS = -I$(top_srcdir)/src +pkcs11_register_CFLAGS += -Wno-unused-but-set-variable -Wno-unused-function +pkcs11_register_LDADD = \ + $(top_builddir)/src/common/libpkcs11.la +if HAVE_UNKNOWN_WARNING_OPTION +pkcs11_register_CFLAGS += -Wno-unknown-warning-option +endif + .PHONY: cmdline cmdline: for f in *.ggo.in; do $(do_subst) < "$$f" > "$${f%.in}"; done @@ -139,6 +149,7 @@ piv_tool_SOURCES += versioninfo-tools.rc opensc_explorer_SOURCES += versioninfo-tools.rc pkcs15_tool_SOURCES += versioninfo-tools.rc pkcs11_tool_SOURCES += versioninfo-tools.rc +pkcs11_register_SOURCES += versioninfo-tools.rc pkcs15_crypt_SOURCES += versioninfo-tools.rc cryptoflex_tool_SOURCES += versioninfo-tools.rc pkcs15_init_SOURCES += versioninfo-tools.rc @@ -156,8 +167,18 @@ endif applicationsdir = $(datadir)/applications applications_DATA = org.opensc.notify.desktop -org.opensc.notify.desktop: org.opensc.notify.desktop.in - $(do_subst) < $(abs_srcdir)/org.opensc.notify.desktop.in > $@ +if ENABLE_AUTOSTART +xdg_autostartdir = $(sysconfdir)/xdg/autostart +xdg_autostart_DATA = pkcs11-register.desktop +endif + +%.desktop: %.desktop.in + $(do_subst) < $< > $@ + +noinst_DATA = pkcs11-register.plist + +%.plist: %.plist.in + $(do_subst) < $< > $@ clean-local: - rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/goid-tool.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop + rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/goid-tool.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop pkcs11-register.desktop diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index ddc32894dd..4637a44dc6 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -7,7 +7,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ opensc-notify.exe egk-tool.exe goid-tool.exe paccess-tool.exe opensc-asn1.exe \ - $(PROGRAMS_OPENSSL) + pkcs11-register.exe $(PROGRAMS_OPENSSL) OBJECTS = util.obj versioninfo-tools.res @@ -27,24 +27,29 @@ opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIB link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) +npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -egk-tool.exe: egk-tool-cmdline.obj util.obj $(LIBS) +egk-tool.exe: egk-tool-cmdline.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj util.obj $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(OBJECTS) $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -goid-tool.exe: goid-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) +goid-tool.exe: goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj util.obj $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 -opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) +opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + +pkcs11-register.exe: pkcs11-register-cmdline.obj fread_to_eof.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib mt -manifest exe.manifest -outputresource:$@;1 .c.exe: diff --git a/src/tools/pkcs11-register-cmdline.c b/src/tools/pkcs11-register-cmdline.c new file mode 100644 index 0000000000..f7f0b00152 --- /dev/null +++ b/src/tools/pkcs11-register-cmdline.c @@ -0,0 +1,586 @@ +/* + File autogenerated by gengetopt version 2.22.6 + generated with the following command: + /usr/bin/gengetopt --file-name=pkcs11-register-cmdline --output-dir=. + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + +#include + +#include "pkcs11-register-cmdline.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: pkcs11-register [OPTIONS]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = "Install a PKCS#11 module to known applications."; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -m, --module=FILENAME Specify the module to load (default=`OpenSC's\n PKCS#11 module')", + " --skip-chrome Don't install module to Chrome (default=off)", + " --skip-firefox Don't install module to Firefox (default=off)", + " --skip-thunderbird Don't install module to Thunderbird (default=off)", + " --skip-seamonkey Don't install module to SeaMonkey (default=off)", + "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", + 0 +}; + +typedef enum {ARG_NO + , ARG_FLAG + , ARG_STRING +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->module_given = 0 ; + args_info->skip_chrome_given = 0 ; + args_info->skip_firefox_given = 0 ; + args_info->skip_thunderbird_given = 0 ; + args_info->skip_seamonkey_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->module_arg = gengetopt_strdup ("OpenSC's PKCS#11 module"); + args_info->module_orig = NULL; + args_info->skip_chrome_flag = 0; + args_info->skip_firefox_flag = 0; + args_info->skip_thunderbird_flag = 0; + args_info->skip_seamonkey_flag = 0; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->module_help = gengetopt_args_info_help[2] ; + args_info->skip_chrome_help = gengetopt_args_info_help[3] ; + args_info->skip_firefox_help = gengetopt_args_info_help[4] ; + args_info->skip_thunderbird_help = gengetopt_args_info_help[5] ; + args_info->skip_seamonkey_help = gengetopt_args_info_help[6] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + free_string_field (&(args_info->module_arg)); + free_string_field (&(args_info->module_orig)); + + + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->module_given) + write_into_file(outfile, "module", args_info->module_orig, 0); + if (args_info->skip_chrome_given) + write_into_file(outfile, "skip-chrome", 0, 0 ); + if (args_info->skip_firefox_given) + write_into_file(outfile, "skip-firefox", 0, 0 ); + if (args_info->skip_thunderbird_given) + write_into_file(outfile, "skip-thunderbird", 0, 0 ); + if (args_info->skip_seamonkey_given) + write_into_file(outfile, "skip-seamonkey", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + FIX_UNUSED (args_info); + FIX_UNUSED (prog_name); + return EXIT_SUCCESS; +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + FIX_UNUSED (default_value); + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_FLAG: + *((int *)field) = !*((int *)field); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + case ARG_FLAG: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "module", 1, NULL, 'm' }, + { "skip-chrome", 0, NULL, 0 }, + { "skip-firefox", 0, NULL, 0 }, + { "skip-thunderbird", 0, NULL, 0 }, + { "skip-seamonkey", 0, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + c = getopt_long (argc, argv, "hVm:", long_options, &option_index); + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'm': /* Specify the module to load. */ + + + if (update_arg( (void *)&(args_info->module_arg), + &(args_info->module_orig), &(args_info->module_given), + &(local_args_info.module_given), optarg, 0, "OpenSC's PKCS#11 module", ARG_STRING, + check_ambiguity, override, 0, 0, + "module", 'm', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + /* Don't install module to Chrome. */ + if (strcmp (long_options[option_index].name, "skip-chrome") == 0) + { + + + if (update_arg((void *)&(args_info->skip_chrome_flag), 0, &(args_info->skip_chrome_given), + &(local_args_info.skip_chrome_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "skip-chrome", '-', + additional_error)) + goto failure; + + } + /* Don't install module to Firefox. */ + else if (strcmp (long_options[option_index].name, "skip-firefox") == 0) + { + + + if (update_arg((void *)&(args_info->skip_firefox_flag), 0, &(args_info->skip_firefox_given), + &(local_args_info.skip_firefox_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "skip-firefox", '-', + additional_error)) + goto failure; + + } + /* Don't install module to Thunderbird. */ + else if (strcmp (long_options[option_index].name, "skip-thunderbird") == 0) + { + + + if (update_arg((void *)&(args_info->skip_thunderbird_flag), 0, &(args_info->skip_thunderbird_given), + &(local_args_info.skip_thunderbird_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "skip-thunderbird", '-', + additional_error)) + goto failure; + + } + /* Don't install module to SeaMonkey. */ + else if (strcmp (long_options[option_index].name, "skip-seamonkey") == 0) + { + + + if (update_arg((void *)&(args_info->skip_seamonkey_flag), 0, &(args_info->skip_seamonkey_given), + &(local_args_info.skip_seamonkey_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "skip-seamonkey", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/src/tools/pkcs11-register-cmdline.h b/src/tools/pkcs11-register-cmdline.h new file mode 100644 index 0000000000..8b38526ad2 --- /dev/null +++ b/src/tools/pkcs11-register-cmdline.h @@ -0,0 +1,189 @@ +/** @file pkcs11-register-cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.6 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef PKCS11_REGISTER_CMDLINE_H +#define PKCS11_REGISTER_CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "pkcs11-register" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "pkcs11-register" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * module_arg; /**< @brief Specify the module to load (default='OpenSC's PKCS#11 module'). */ + char * module_orig; /**< @brief Specify the module to load original value given at command line. */ + const char *module_help; /**< @brief Specify the module to load help description. */ + int skip_chrome_flag; /**< @brief Don't install module to Chrome (default=off). */ + const char *skip_chrome_help; /**< @brief Don't install module to Chrome help description. */ + int skip_firefox_flag; /**< @brief Don't install module to Firefox (default=off). */ + const char *skip_firefox_help; /**< @brief Don't install module to Firefox help description. */ + int skip_thunderbird_flag; /**< @brief Don't install module to Thunderbird (default=off). */ + const char *skip_thunderbird_help; /**< @brief Don't install module to Thunderbird help description. */ + int skip_seamonkey_flag; /**< @brief Don't install module to SeaMonkey (default=off). */ + const char *skip_seamonkey_help; /**< @brief Don't install module to SeaMonkey help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int module_given ; /**< @brief Whether module was given. */ + unsigned int skip_chrome_given ; /**< @brief Whether skip-chrome was given. */ + unsigned int skip_firefox_given ; /**< @brief Whether skip-firefox was given. */ + unsigned int skip_thunderbird_given ; /**< @brief Whether skip-thunderbird was given. */ + unsigned int skip_seamonkey_given ; /**< @brief Whether skip-seamonkey was given. */ + +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PKCS11_REGISTER_CMDLINE_H */ diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c new file mode 100644 index 0000000000..0df3a39913 --- /dev/null +++ b/src/tools/pkcs11-register.c @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fread_to_eof.h" +#include "pkcs11-register-cmdline.h" +#include +#include +#include + +#ifdef _WIN32 +#include +const char path_sep = '\\'; +#else +const char path_sep = '/'; +#endif + +const char *default_pkcs11_provider = DEFAULT_PKCS11_PROVIDER; +const char *default_onepin_pkcs11_provider = DEFAULT_ONEPIN_PKCS11_PROVIDER; + +int +get_profiles_ini(const char *home, const char *basedir, char **profiles_ini) +{ + size_t profiles_ini_len = 0; + char profiles_ini_path[PATH_MAX]; + if (home && basedir + && 0 <= snprintf(profiles_ini_path, sizeof profiles_ini_path, + "%s%c%s%c%s", home, path_sep, basedir, path_sep, "profiles.ini") + && fread_to_eof(profiles_ini_path, + (unsigned char **) profiles_ini, &profiles_ini_len)) { + char *p = realloc(*profiles_ini, profiles_ini_len+1); + if (p) { + p[profiles_ini_len] = '\0'; + *profiles_ini = p; + return 1; + } + } + return 0; +} + +const char * +get_next_profile_path(const char **profiles_ini, const char *home, const char *basedir) +{ + static char profile_path[PATH_MAX]; + + if (!home || !profiles_ini) + return NULL; + + while (*profiles_ini) { + const char *this_profile = strstr(*profiles_ini, "["); + if (!this_profile) { + return NULL; + } + + const char *next_profile = strstr(this_profile + 1, "["); + const char *is_relative = strstr(this_profile, "IsRelative=1"); + const char *path = strstr(this_profile, "Path="); + + /* advance profile_ini for the next iteration */ + if (next_profile) { + *profiles_ini = next_profile; + + if (next_profile < path) { + /* path belongs to the next profile */ + path = NULL; + } + if (next_profile < is_relative) { + /* IsRelative belongs to the next profile */ + is_relative = NULL; + } + } else { + *profiles_ini = NULL; + } + + if (!path) + continue; + + /* build the path to the profile */ + char *p = profile_path; + size_t p_len = sizeof profile_path; + if (is_relative) { + size_t l = strlen(home) + sizeof path_sep + strlen(basedir) + sizeof path_sep; + if (0 > snprintf(p, p_len, "%s%c%s%c", home, path_sep, basedir, path_sep)) + continue; + p_len -= l; + p += l; + } + /* adjust format to respect the maximum length of profile_path */ + char format[32]; + if (0 > snprintf(format, sizeof(format), "Path=%%%ds", (int)(p_len-1)) + || 1 != sscanf(path, format, p)) + continue; + + return profile_path; + } + + return NULL; +} + +void +add_module_pkcs11_txt(const char *profile_dir, + const char *module_path, const char *module_name) +{ + char pkcs11_txt_path[PATH_MAX]; + char *pkcs11_txt = NULL; + size_t pkcs11_txt_len = 0; + if (!profile_dir + || snprintf(pkcs11_txt_path, sizeof pkcs11_txt_path, + "%s%c%s", profile_dir, path_sep, "pkcs11.txt") < 0 + || !fread_to_eof(pkcs11_txt_path, + (unsigned char **) &pkcs11_txt, &pkcs11_txt_len)) { + goto err; + } + char *p = realloc(pkcs11_txt, pkcs11_txt_len+1); + if (!p) + goto err; + p[pkcs11_txt_len] = '\0'; + pkcs11_txt = p; + + if (!strstr(pkcs11_txt, module_path)) { + /* module is not yet present */ + FILE *f = fopen(pkcs11_txt_path, "a"); + if (f) { + if (fprintf(f, + "library=%s\n" + "name=%s\n" + "\n", module_path, module_name) >= 0) { + printf("Added %s to %s\n", module_name, pkcs11_txt_path); + } + fclose(f); + } + } +err: + free(pkcs11_txt); +} + +struct location { + const char *var; + const char *dir; +}; + +void +add_module_mozilla(const struct location *locations, size_t locations_len, + const char *module_path, const char *module_name) +{ + size_t i; + + for (i = 0; i < locations_len; i++) { + char *profiles_ini = NULL; + const char *home = getenv(locations[i].var); + if (!home) + continue; + + if (get_profiles_ini(home, locations[i].dir, &profiles_ini)) { + const char *p = profiles_ini; + + while (1) { + const char *profile_path = get_next_profile_path(&p, home, locations[i].dir); + if (!profile_path) + break; + add_module_pkcs11_txt(profile_path, module_path, module_name); + } + } + free(profiles_ini); + } +} + +#include "pkcs11/pkcs11.h" +#include "common/libpkcs11.h" + +const char * +get_module_name(const char *module_path) +{ + const char *name = NULL; + CK_FUNCTION_LIST_PTR p11 = NULL; + void *module = C_LoadModule(module_path, &p11); + if (module) { + CK_INFO info; + if (CKR_OK == p11->C_Initialize(NULL) + && CKR_OK == p11->C_GetInfo(&info)) { + static char module_name[32+sizeof " (255.255)"]; + int libraryDescription_len = 32; + + while (libraryDescription_len > 0 + && info.libraryDescription[libraryDescription_len-1] == ' ') + libraryDescription_len--; + + snprintf(module_name, sizeof module_name, + "%.*s (%d.%d)", + libraryDescription_len, info.libraryDescription, + info.libraryVersion.major, info.libraryVersion.minor); + + name = module_name; + } + p11->C_Finalize(NULL); + C_UnloadModule(module); + } + return name; +} + +void +add_module_firefox(const char *module_path, const char *module_name) +{ + struct location locations[] = { +#if defined(__APPLE__) + {"HOME", "Library/Application Support/Firefox"}, + {"HOME", "Library/Mozilla/Firefox"}, +#elif defined(_WIN32) + {"APPDATA", "Mozilla\\Firefox"}, +#else + {"HOME", ".mozilla/firefox"}, +#endif + }; + + if (0 == strcmp(module_path, default_pkcs11_provider)) + module_path = default_onepin_pkcs11_provider; + + add_module_mozilla(locations, sizeof locations/sizeof *locations, + module_path, module_name); +} + +void +add_module_thunderbird(const char *module_path, const char *module_name) +{ + struct location locations[] = { +#if defined(__APPLE__) + {"HOME", "Library/Application Support/Thunderbird"}, + {"HOME", "Library/Mozilla/Thunderbird"}, +#elif defined(_WIN32) + {"APPDATA", "Mozilla\\Thunderbird"}, +#else + {"HOME", ".thunderbird"}, + {"HOME", ".mozilla-thunderbird"}, +#endif + }; + + add_module_mozilla(locations, sizeof locations/sizeof *locations, + module_path, module_name); +} + +void +add_module_seamonkey(const char *module_path, const char *module_name) +{ + struct location locations[] = { +#if defined(__APPLE__) + {"HOME", "Library/Application Support/SeaMonkey"}, + {"HOME", "Library/Mozilla/SeaMonkey"}, +#elif defined(_WIN32) + {"APPDATA", "Mozilla\\SeaMonkey"}, +#else + {"HOME", ".mozilla/seamonkey"}, +#endif + }; + + add_module_mozilla(locations, sizeof locations/sizeof *locations, + module_path, module_name); +} + +void +add_module_chrome(const char *module_path, const char *module_name) +{ +#if defined(__APPLE__) || defined(_WIN32) + /* OS specific framework will be used by Chrome instead of PKCS#11 */ +#else + char profile_path[PATH_MAX]; + const char *home = getenv("HOME"); + if (home && 0 <= snprintf(profile_path, sizeof profile_path, + "%s%c%s", home, path_sep, ".pki/nssdb")) { + add_module_pkcs11_txt(profile_path, module_path, module_name); + } +#endif +} + +#define expand(path, expanded, len) \ + len = ExpandEnvironmentStringsA(path, \ + expanded, sizeof expanded); \ + if (0 < len && len < sizeof expanded) \ + path = expanded; + +int +main(int argc, char **argv) +{ + struct gengetopt_args_info cmdline; + + if (cmdline_parser(argc, argv, &cmdline) != 0) + return 1; + + const char *module_path = cmdline.module_arg; + if (!cmdline.module_given) + module_path = default_pkcs11_provider; +#ifdef _WIN32 + DWORD expanded_len; + char module_path_expanded[PATH_MAX], default_expanded[PATH_MAX], onepin_expanded[PATH_MAX]; + expand(module_path, module_path_expanded, expanded_len); + expand(default_pkcs11_provider, default_expanded, expanded_len); + expand(default_onepin_pkcs11_provider, onepin_expanded, expanded_len); +#endif + + const char *module_name = get_module_name(module_path); + if (!module_name) { + fprintf(stderr, "Could not load initialize %s\n", module_path); + return 1; + } + + if (!cmdline.skip_chrome_flag) + add_module_chrome(module_path, module_name); + if (!cmdline.skip_firefox_flag) + add_module_firefox(module_path, module_name); + if (!cmdline.skip_thunderbird_flag) + add_module_thunderbird(module_path, module_name); + if (!cmdline.skip_seamonkey_flag) + add_module_seamonkey(module_path, module_name); + + cmdline_parser_free (&cmdline); + + return 0; +} diff --git a/src/tools/pkcs11-register.desktop.in b/src/tools/pkcs11-register.desktop.in new file mode 100644 index 0000000000..ea6a514081 --- /dev/null +++ b/src/tools/pkcs11-register.desktop.in @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Install OpenSC PKCS#11 module +Type=Application +Exec=@bindir@/pkcs11-register +Categories=Security;System; +X-GNOME-AutoRestart=true +X-GNOME-Autostart-Phase=Initialization +NoDisplay=true diff --git a/src/tools/pkcs11-register.ggo.in b/src/tools/pkcs11-register.ggo.in new file mode 100644 index 0000000000..30c771bc77 --- /dev/null +++ b/src/tools/pkcs11-register.ggo.in @@ -0,0 +1,28 @@ +package "pkcs11-register" +purpose "@PACKAGE_SUMMARY@" +description "Install a PKCS#11 module to known applications." + +option "module" m + "Specify the module to load" + string optional default="OpenSC's PKCS#11 module" typestr="FILENAME" + +option "skip-chrome" - + "Don't install module to Chrome" + flag off + +option "skip-firefox" - + "Don't install module to Firefox" + flag off + +option "skip-thunderbird" - + "Don't install module to Thunderbird" + flag off + +option "skip-seamonkey" - + "Don't install module to SeaMonkey" + flag off + +text " +Report bugs to @PACKAGE_BUGREPORT@ + +Written by Frank Morgner " diff --git a/src/tools/pkcs11-register.plist.in b/src/tools/pkcs11-register.plist.in new file mode 100644 index 0000000000..1582ee56d1 --- /dev/null +++ b/src/tools/pkcs11-register.plist.in @@ -0,0 +1,14 @@ + + + + + Label + pkcs11-register + ProgramArguments + + @bindir@/pkcs11-register + + RunAtLoad + + + diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 6154e85aa0..7cbda4c126 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -52,6 +52,7 @@ + @@ -145,6 +146,9 @@ + + + @@ -201,6 +205,11 @@ + + + + + @@ -367,6 +376,7 @@ + @@ -421,6 +431,9 @@ + + + @@ -443,6 +456,11 @@ + + + + + diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index 9f44251e1f..94ed9b5475 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -99,6 +99,9 @@ #ifndef DEFAULT_PKCS11_PROVIDER #define DEFAULT_PKCS11_PROVIDER "@DEFAULT_PKCS11_PROVIDER@" #endif +#ifndef DEFAULT_ONEPIN_PKCS11_PROVIDER +#define DEFAULT_ONEPIN_PKCS11_PROVIDER "@DEFAULT_ONEPIN_PKCS11_PROVIDER@" +#endif #ifndef DEFAULT_SM_MODULE #define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@" From fe95520e3ee4f422cb4217b885f12cdc86e808e2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Mar 2019 19:36:20 +0100 Subject: [PATCH 0845/4321] explicitly import libpkcs11.h --- src/pkcs11/pkcs11-spy.c | 4 +--- src/pkcs11/sc-pkcs11.h | 3 --- src/tools/pkcs11-tool.c | 3 +-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 92e635cc6f..83870840cf 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -33,12 +33,10 @@ #define CRYPTOKI_EXPORTS #include "pkcs11-display.h" +#include "common/libpkcs11.h" #define __PASTE(x,y) x##y -extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); -extern CK_RV C_UnloadModule(void *module); - /* Declare all spy_* Cryptoki function */ /* Spy Module Function List */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 22e1cda690..4309b63116 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -47,9 +47,6 @@ extern "C" { #define SC_PKCS11_SLOT_FOR_PINS (SC_PKCS11_SLOT_FOR_PIN_USER | SC_PKCS11_SLOT_FOR_PIN_SIGN) -extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); -extern CK_RV C_UnloadModule(void *module); - #ifdef __cplusplus } #endif diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b6b799a6ef..da2da404bc 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -60,6 +60,7 @@ #include "libopensc/asn1.h" #include "common/compat_strlcat.h" #include "common/compat_strlcpy.h" +#include "common/libpkcs11.h" #include "util.h" #include "libopensc/sc-ossl-compat.h" @@ -69,8 +70,6 @@ #endif #endif -extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); -extern CK_RV C_UnloadModule(void *module); #ifndef ENABLE_SHARED extern CK_FUNCTION_LIST pkcs11_function_list; #endif From 159821497ca160f9e90e1720782621dfb44c463f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 20 Mar 2019 20:54:11 +0100 Subject: [PATCH 0846/4321] egk-tool: fixed verbose logging --- src/tools/egk-tool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index f2915ea205..f20de094cd 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -164,6 +164,11 @@ main (int argc, char **argv) exit(1); } + if (cmdline.verbose_given > 1) { + ctx->debug = cmdline.verbose_given; + sc_ctx_log_to_file(ctx, "stderr"); + } + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); if (r) goto err; From 9092782f940ffd3fc1badbd5033ae775b71ce6f2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Mar 2019 22:27:04 +0100 Subject: [PATCH 0847/4321] CI: only push artifacts on OpenSC/OpenSC --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a3f665a62..7c4fe41c08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -203,7 +203,7 @@ after_script: fi # keep in sync with appveyor.yml - - if [ "${DO_PUSH_ARTIFACT}" = "yes" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then + - if [ "${DO_PUSH_ARTIFACT}" = "yes" -a "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_REPO_SLUG" = "OpenSC/OpenSC" ]; then git config --global user.email "builds@travis-ci.org"; git config --global user.name "Travis CI"; .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; diff --git a/appveyor.yml b/appveyor.yml index 59063ec74f..2c49e91f2a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -111,7 +111,7 @@ deploy_script: # keep in sync with .travis.yml - bash -c "git config --global user.email 'no-reply@appveyor.com'" - bash -c "git config --global user.name 'AppVeyor'" - - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" + - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" -a \"$APPVEYOR_REPO_NAME\" = \"OpenSC/OpenSC\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" cache: - C:\zlib -> appveyor.yml From 066c30bb4ee64005be4ce11f801dafb7387cb0d7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Mar 2019 17:03:26 +0100 Subject: [PATCH 0848/4321] opensc-notify: add to autostart --- .gitignore | 2 ++ MacOSX/build-package.in | 1 + MacOSX/scripts/postinstall | 10 ++++++++++ src/tools/Makefile.am | 4 ++-- src/tools/opensc-notify.plist.in | 14 ++++++++++++++ win32/OpenSC.wxs.in | 15 +++++++++++++-- 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/tools/opensc-notify.plist.in diff --git a/.gitignore b/.gitignore index 60080e5281..425c3401b0 100644 --- a/.gitignore +++ b/.gitignore @@ -79,8 +79,10 @@ src/tools/opensc-explorer src/tools/cardos-info src/tools/sceac-example src/tools/opensc-notify +src/tools/opensc-notify.plist src/tools/org.opensc.notify.desktop src/tools/pkcs11-register +src/tools/pkcs11-register.plist src/tools/pkcs11-register.desktop src/tools/opensc-asn1 diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 48f4a25a81..c3ee291707 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -125,6 +125,7 @@ cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin # Prepare startup root mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents cp src/tools/pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents +cp src/tools/opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents # Build package pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg diff --git a/MacOSX/scripts/postinstall b/MacOSX/scripts/postinstall index fed5aa8649..17a09f3119 100755 --- a/MacOSX/scripts/postinstall +++ b/MacOSX/scripts/postinstall @@ -15,8 +15,18 @@ else mv /Library/OpenSC/etc/opensc.conf.orig /Library/OpenSC/etc/opensc.conf md5 -r /Library/OpenSC/etc/opensc.conf > /Library/OpenSC/etc/opensc.conf.md5 fi + for f in /Library/OpenSC/bin/* do ln -sf $f /usr/local/bin done + +for f in /Library/LaunchAgents/pkcs11-register.plist /Library/LaunchAgents/pkcs11-register.plist +do + if [ -e "$f" ] + then + /bin/launchctl asuser $(id -u "${USER}") /bin/launchctl load "$f" + fi +done + exit 0 diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 13865c9ce7..fb97c57afb 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -21,7 +21,7 @@ do_subst = $(SED) \ -e 's,[@]X509DIR[@],$(X509DIR),g' MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in pkcs11-register.plist.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in pkcs11-register.plist.in opensc-notify.plist.in noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ @@ -175,7 +175,7 @@ endif %.desktop: %.desktop.in $(do_subst) < $< > $@ -noinst_DATA = pkcs11-register.plist +noinst_DATA = pkcs11-register.plist opensc-notify.plist %.plist: %.plist.in $(do_subst) < $< > $@ diff --git a/src/tools/opensc-notify.plist.in b/src/tools/opensc-notify.plist.in new file mode 100644 index 0000000000..3f48dd10aa --- /dev/null +++ b/src/tools/opensc-notify.plist.in @@ -0,0 +1,14 @@ + + + + + Label + pkcs11-register + ProgramArguments + + @bindir@/opensc-notify + + RunAtLoad + + + diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 7cbda4c126..9db50a85a6 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -205,11 +205,21 @@ - + + + + + + + + + + + @@ -431,8 +441,9 @@ - + + From 3ef295705fe77ffcc2f8f9ee5860fb2fdbc83fce Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Mar 2019 23:20:13 +0100 Subject: [PATCH 0849/4321] don't use deprecated WiX option --- win32/OpenSC.wxs.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 9db50a85a6..a4badfa626 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -72,7 +72,7 @@ - + @@ -206,7 +206,7 @@ - + @@ -216,7 +216,7 @@ - + @@ -332,7 +332,7 @@ - + From be2df3b66ba905633d902eee992d776edd1c688a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 22 Mar 2019 23:36:09 +0100 Subject: [PATCH 0850/4321] WiX: count versions for installer --- win32/OpenSC.wxs.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index a4badfa626..0180620a60 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -25,7 +25,7 @@ UpgradeCode="$(var.PlatformUpgradeCode)" Language="1033" Codepage="1252" - Version="@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.0" + Version="@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" Manufacturer="@OPENSC_VS_FF_COMPANY_NAME@"> - From 34b1ebc15dd76567979ce2dc971aa57d6c20657f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 25 Mar 2019 15:48:40 +0100 Subject: [PATCH 0851/4321] win32: install opensc.dll only with the tools everything else is statically linked --- win32/OpenSC.wxs.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 0180620a60..12d039ed36 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -353,7 +353,6 @@ - @@ -380,6 +379,7 @@ + From ea8fe5e760aabd5f4538a052baa5241a435dc721 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 25 Mar 2019 16:32:43 +0100 Subject: [PATCH 0852/4321] win32 installer: changed wording --- win32/OpenSC.wxs.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 12d039ed36..82d470de2d 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -351,7 +351,7 @@ - + @@ -365,20 +365,20 @@ - + - + - + - + @@ -437,10 +437,10 @@ - + - + From 58d201de4bbdee654dfafe3b64d8db0c80673f56 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 25 Mar 2019 16:53:30 +0100 Subject: [PATCH 0853/4321] autostart is a subfeature of OpenSC tools --- Makefile.mak | 14 ++++++++++++++ win32/OpenSC.wxs.in | 10 +++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Makefile.mak b/Makefile.mak index f76f33e608..9489a5ccad 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -2,5 +2,19 @@ SUBDIRS = etc win32 src default: all +32: + CALL "C:\Program Files\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 + $(MAKE) /f Makefile.mak opensc.msi PLATFORM=x86 OPENPACE_DIR=C:\openpace-Win32_1.0.2 + MOVE win32\OpenSC.msi OpenSC_win32.msi + +64: + CALL "C:\Program Files\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 + $(MAKE) /f Makefile.mak opensc.msi OPENPACE_DIR=C:\openpace-Win64_1.0.2 + MOVE win32\OpenSC.msi OpenSC_win64.msi + +opensc.msi: + $(MAKE) /f Makefile.mak all OPENSSL_DEF=/DENABLE_OPENSSL OPENPACE_DEF=/DENABLE_OPENPACE" + @cmd /c "cd win32 && $(MAKE) /nologo /f Makefile.mak opensc.msi OPENSSL_DEF=/DENABLE_OPENSSL OPENPACE_DEF=/DENABLE_OPENPACE" + all clean:: @for %i in ( $(SUBDIRS) ) do @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 82d470de2d..09ab5336a0 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -365,7 +365,7 @@ - + @@ -436,14 +436,14 @@ + + + + - - - - From 79306833bfa952bd37aa47be7aa98e3295f8806a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Mar 2019 09:12:17 +0100 Subject: [PATCH 0854/4321] fixed typo --- MacOSX/scripts/postinstall | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MacOSX/scripts/postinstall b/MacOSX/scripts/postinstall index 17a09f3119..8293c2c3dc 100755 --- a/MacOSX/scripts/postinstall +++ b/MacOSX/scripts/postinstall @@ -21,7 +21,7 @@ do ln -sf $f /usr/local/bin done -for f in /Library/LaunchAgents/pkcs11-register.plist /Library/LaunchAgents/pkcs11-register.plist +for f in /Library/LaunchAgents/pkcs11-register.plist /Library/LaunchAgents/opensc-notify.plist do if [ -e "$f" ] then From 46930fc0c46a41c4a2e0121d7012cab6030f0dfd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Mar 2019 09:14:40 +0100 Subject: [PATCH 0855/4321] added missing outline-choice --- MacOSX/Distribution.xml.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index 9443938bde..22e5104d4d 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -13,6 +13,7 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D + OpenSC.pkg From 3935d501bf27d49943562ad0c5746047dd6d8498 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 31 Mar 2019 23:33:14 +0300 Subject: [PATCH 0856/4321] Implement Secret Key write object Signed-off-by: Raul Metsma --- src/tools/pkcs11-tool.c | 95 ++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index da2da404bc..e6158b2ca2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2469,7 +2469,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey CK_RV rv; if (type != NULL) { - if (strncmp(type, "AES:", strlen("AES:")) == 0 || strncmp(type, "aes:", strlen("aes:")) == 0) { + if (strncasecmp(type, "AES:", strlen("AES:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_AES_KEY_GEN}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); const char *size = type + strlen("AES:"); @@ -2489,7 +2489,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; } - else if (strncmp(type, "DES:", strlen("DES:")) == 0 || strncmp(type, "des:", strlen("des:")) == 0) { + else if (strncasecmp(type, "DES:", strlen("DES:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_DES_KEY_GEN}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); const char *size = type + strlen("DES:"); @@ -2509,7 +2509,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; } - else if (strncmp(type, "DES3:", strlen("DES3:")) == 0 || strncmp(type, "des3:", strlen("des3:")) == 0) { + else if (strncasecmp(type, "DES3:", strlen("DES3:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_DES3_KEY_GEN}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); const char *size = type + strlen("DES3:"); @@ -2858,17 +2858,17 @@ static int write_object(CK_SESSION_HANDLE session) unsigned char certdata[MAX_OBJECT_SIZE]; int certdata_len = 0; FILE *f; - CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, data_obj; - CK_ATTRIBUTE cert_templ[20], privkey_templ[20], pubkey_templ[20], data_templ[20]; - int n_cert_attr = 0, n_privkey_attr = 0, n_pubkey_attr = 0, n_data_attr = 0; + CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, seckey_obj, data_obj; + CK_ATTRIBUTE cert_templ[20], privkey_templ[20], pubkey_templ[20], seckey_templ[20], data_templ[20]; + int n_cert_attr = 0, n_privkey_attr = 0, n_pubkey_attr = 0, n_seckey_attr = 0, n_data_attr = 0; struct sc_object_id oid; CK_RV rv; int need_to_parse_certdata = 0; unsigned char *oid_buf = NULL; CK_OBJECT_CLASS clazz; CK_CERTIFICATE_TYPE cert_type; -#ifdef ENABLE_OPENSSL CK_KEY_TYPE type = CKK_RSA; +#ifdef ENABLE_OPENSSL struct x509cert_info cert; struct rsakey_info rsa; struct gostkey_info gost; @@ -2967,7 +2967,9 @@ static int write_object(CK_SESSION_HANDLE session) #endif } - if (opt_object_class == CKO_CERTIFICATE) { + switch(opt_object_class) + { + case CKO_CERTIFICATE: clazz = CKO_CERTIFICATE; cert_type = CKC_X_509; @@ -2995,9 +2997,8 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(cert_templ[n_cert_attr], CKA_SERIAL_NUMBER, cert.serialnum, cert.serialnum_len); n_cert_attr++; #endif - } - else - if (opt_object_class == CKO_PRIVATE_KEY) { + break; + case CKO_PRIVATE_KEY: clazz = CKO_PRIVATE_KEY; n_privkey_attr = 0; @@ -3099,9 +3100,8 @@ static int write_object(CK_SESSION_HANDLE session) #endif #endif - } - else - if (opt_object_class == CKO_PUBLIC_KEY) { + break; + case CKO_PUBLIC_KEY: clazz = CKO_PUBLIC_KEY; #ifdef ENABLE_OPENSSL pk_type = EVP_PKEY_base_id(evp_key); @@ -3199,9 +3199,54 @@ static int write_object(CK_SESSION_HANDLE session) } #endif #endif - } - else - if (opt_object_class == CKO_DATA) { + break; + case CKO_SECRET_KEY: + clazz = CKO_SECRET_KEY; + type = CKK_AES; + + if (opt_key_type != 0) { + if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0) + type = CKK_AES; + else if (strncasecmp(opt_key_type, "DES3:", strlen("DES3:")) == 0) + type = CKK_DES3; + else + util_fatal("Unknown key type %s", type); + } + + FILL_ATTR(seckey_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); + FILL_ATTR(seckey_templ[1], CKA_KEY_TYPE, &type, sizeof(type)); + FILL_ATTR(seckey_templ[2], CKA_TOKEN, &_true, sizeof(_true)); + FILL_ATTR(seckey_templ[3], CKA_VALUE, &contents, contents_len); + n_seckey_attr = 4; + + if (opt_is_private != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_PRIVATE, &_true, sizeof(_true)); + n_seckey_attr++; + } + else { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_PRIVATE, &_false, sizeof(_false)); + n_seckey_attr++; + } + + if (opt_is_sensitive != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SENSITIVE, &_true, sizeof(_true)); + n_seckey_attr++; + } + else { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SENSITIVE, &_false, sizeof(_false)); + n_seckey_attr++; + } + + if (opt_object_label != NULL) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); + n_seckey_attr++; + } + if (opt_object_id_len != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_ID, opt_object_id, opt_object_id_len); + n_seckey_attr++; + } + break; + case CKO_DATA: clazz = CKO_DATA; FILL_ATTR(data_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); FILL_ATTR(data_templ[1], CKA_TOKEN, &_true, sizeof(_true)); @@ -3241,10 +3286,11 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(data_templ[n_data_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); n_data_attr++; } - - } - else + break; + default: util_fatal("Writing of a \"%s\" type not (yet) supported", opt_object_class_str); + break; + } if (n_data_attr) { rv = p11->C_CreateObject(session, data_templ, n_data_attr, &data_obj); @@ -3281,6 +3327,15 @@ static int write_object(CK_SESSION_HANDLE session) show_object(session, privkey_obj); } + if (n_seckey_attr) { + rv = p11->C_CreateObject(session, seckey_templ, n_seckey_attr, &seckey_obj); + if (rv != CKR_OK) + p11_fatal("C_CreateObject", rv); + + printf("Created secret key:\n"); + show_object(session, seckey_obj); + } + if (oid_buf) free(oid_buf); return 1; From 91a1dd9af4e5743eb5276f587a2df50270d5aa0d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 1 Apr 2019 00:33:41 +0300 Subject: [PATCH 0857/4321] Option to delete object by index Signed-off-by: Raul Metsma --- doc/tools/pkcs11-tool.1.xml | 25 ++++++++++++++++--------- src/tools/pkcs11-tool.c | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index ce9419541c..b960f02538 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -77,9 +77,9 @@ - Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. - Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may - also allow "SHA224". Default is "SHA-1". + Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + also allow "SHA224". Default is "SHA-1". Note that the input to RSA-PKCS-PSS has to be of the size equal to @@ -396,6 +396,13 @@ Specify the index of the slot to use. + + + index + + Specify the index of the object to use. + + label @@ -444,13 +451,13 @@ viewable after a login). - + Set the CKA_ALWAYS_AUTHENTICATE attribute to a private key object. - If set, the user has to supply the PIN for each use (sign or decrypt) with the key. - + If set, the user has to supply the PIN for each use (sign or decrypt) with the key. + @@ -580,7 +587,7 @@ Write a key or certificate object to the token. filename points to the DER-encoded certificate or key file. - + @@ -588,7 +595,7 @@ num Get num bytes of random data. - + @@ -603,7 +610,7 @@ To read the certificate with ID KEY_ID in DER format from smart card: - pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der + pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der To convert the certificate in DER format to PEM format, use OpenSSL tools: diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e6158b2ca2..65295f70f3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -155,7 +155,8 @@ enum { OPT_VERIFY, OPT_SIGNATURE_FILE, OPT_ALWAYS_AUTH, - OPT_ALLOWED_MECHANISMS + OPT_ALLOWED_MECHANISMS, + OPT_OBJECT_INDEX }; static const struct option options[] = { @@ -206,6 +207,7 @@ static const struct option options[] = { { "slot", 1, NULL, OPT_SLOT }, { "slot-description", 1, NULL, OPT_SLOT_DESCRIPTION }, { "slot-index", 1, NULL, OPT_SLOT_INDEX }, + { "object-index", 1, NULL, OPT_OBJECT_INDEX }, { "token-label", 1, NULL, OPT_TOKEN_LABEL }, { "set-id", 1, NULL, 'e' }, { "attr-from", 1, NULL, OPT_ATTR_FROM }, @@ -279,6 +281,7 @@ static const char *option_help[] = { "Specify the ID of the slot to use", "Specify the description of the slot to use", "Specify the index of the slot to use", + "Specify the index of the object to use", "Specify the token label of the slot to use", "Set the CKA_ID of an object, = the (new) CKA_ID", "Use to create some attributes when writing an object", @@ -315,6 +318,8 @@ static const char * opt_slot_description = NULL; static const char * opt_token_label = NULL; static CK_ULONG opt_slot_index = 0; static int opt_slot_index_set = 0; +static CK_ULONG opt_object_index = 0; +static int opt_object_index_set = 0; static CK_MECHANISM_TYPE opt_mechanism = 0; static int opt_mechanism_used = 0; static const char * opt_file_to_write = NULL; @@ -799,6 +804,10 @@ int main(int argc, char * argv[]) opt_slot_index = (CK_ULONG) strtoul(optarg, NULL, 0); opt_slot_index_set = 1; break; + case OPT_OBJECT_INDEX: + opt_object_index = (CK_ULONG) strtoul(optarg, NULL, 0); + opt_object_index_set = 1; + break; case OPT_TOKEN_LABEL: if (opt_slot_set || opt_slot_description || opt_slot_index_set) { fprintf(stderr, "Error: Only one of --slot, --slot-label, --slot-index or --token-label can be used\n"); @@ -1153,9 +1162,10 @@ int main(int argc, char * argv[]) if (opt_object_class_str == NULL) util_fatal("You should specify type of the object to delete"); if (opt_object_id_len == 0 && opt_object_label == NULL && - opt_application_label == NULL && opt_application_id == NULL) + opt_application_label == NULL && opt_application_id == NULL && + opt_object_index_set == 0) util_fatal("You should specify at least one of the " - "object ID, object label, application label or application ID"); + "object ID, object label, application label, application ID or object index"); delete_object(session); } @@ -4398,7 +4408,7 @@ static int delete_object(CK_SESSION_HANDLE session) nn_attrs++; } - rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, 0); + rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, opt_object_index); if (rv != CKR_OK) p11_fatal("find_object_with_attributes()", rv); else if (obj==CK_INVALID_HANDLE) From fe4dae4d31d443f00da793bb05d8fb47424ddeb1 Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Wed, 20 Mar 2019 13:35:02 +0300 Subject: [PATCH 0858/4321] card-rtecp: Add Rutoken ECP SC ATR --- src/libopensc/card-rtecp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 444ac22357..5b81fcad0c 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -48,6 +48,14 @@ static const struct sc_atr_table rtecp_atrs[] = { /* Rutoken ECP (DS) */ { "3B:8B:01:52:75:74:6F:6B:65:6E:20:44:53:20:C1", NULL, "Rutoken ECP (DS)", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + /* Rutoken ECP SC T0 */ + { "3B:9C:96:00:52:75:74:6F:6B:65:6E:45:43:50:73:63", + "00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF", + "Rutoken ECP SC", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + /* Rutoken ECP SC T1 */ + { "3B:9C:94:80:11:40:52:75:74:6F:6B:65:6E:45:43:50:73:63:C3", + "00:00:00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00", + "Rutoken ECP SC", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; From aff2059ec1421f42945de79e6a9b37eedda06f04 Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Wed, 3 Apr 2019 13:11:37 +0300 Subject: [PATCH 0859/4321] card-rtecp: Fix SELECT FILE --- src/libopensc/card-rtecp.c | 41 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 5b81fcad0c..1eae6e1ce6 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -260,36 +260,41 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) static int rtecp_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - sc_file_t **file_out_copy, *file; - int r; + sc_file_t *file = NULL; + int r = SC_SUCCESS; + + if (!card || !card->ctx || !in_path) + return SC_ERROR_INVALID_ARGUMENTS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card && card->ctx && in_path); switch (in_path->type) { case SC_PATH_TYPE_DF_NAME: case SC_PATH_TYPE_FROM_CURRENT: case SC_PATH_TYPE_PARENT: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); } - assert(iso_ops && iso_ops->select_file); - file_out_copy = file_out; - r = iso_ops->select_file(card, in_path, file_out_copy); - if (r || file_out_copy == NULL) + + // Card Rutoken ECP SC T0 doesn't support SELECT FILE without return a file info. + // So here we request a file and then assign/free it depending on file_out. + r = iso_ops->select_file(card, in_path, &file); + if (r != SC_SUCCESS) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); - assert(file_out_copy); - file = *file_out_copy; - assert(file); + if (file->sec_attr && file->sec_attr_len == SC_RTECP_SEC_ATTR_SIZE) set_acl_from_sec_attr(card, file); - else - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - if (r && !file_out) - sc_file_free(file); else { - assert(file_out); - *file_out = file; + sc_file_free(file); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED); } + + if (file_out) + *file_out = file; + else + sc_file_free(file); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -784,7 +789,7 @@ struct sc_card_driver * sc_get_rtecp_driver(void) rtecp_ops.append_record = NULL; rtecp_ops.update_record = NULL; rtecp_ops.select_file = rtecp_select_file; - rtecp_ops.get_response = NULL; + /* get_response */ /* get_challenge */ rtecp_ops.verify = rtecp_verify; rtecp_ops.logout = rtecp_logout; From 2600f1ae43265fd75e0ae823888ff55a6e014c85 Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Tue, 9 Apr 2019 17:11:32 +0300 Subject: [PATCH 0860/4321] win32: Add Rutoken ECP ATRs to the minidriver --- win32/customactions.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index e3263fa808..943ca21f5a 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -161,6 +161,16 @@ MD_REGISTRATION minidriver_registration[] = { 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("STARCOS 3.5 (f)"), {0x3B,0xD9,0x96,0xFF,0x81,0x31,0xFE,0x45,0x80,0x31,0xB8,0x73,0x86,0x01,0xE0,0x81,0x05,0x22}, 18, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + + /* from card-rtecp.c */ + {TEXT("Rutoken ECP"), {0x3B,0x8B,0x01,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x20,0x45,0x43,0x50,0xA0}, + 15, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("Rutoken ECP (DS)"), {0x3B,0x8B,0x01,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x20,0x44,0x53,0x20,0xC1}, + 15, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("Rutoken ECP SC"), {0x3B,0x9C,0x96,0x00,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x45,0x43,0x50,0x73,0x63}, + 16, {0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("Rutoken ECP SC"), {0x3B,0x9C,0x94,0x80,0x11,0x40,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x45,0x43,0x50,0x73,0x63,0xC3}, + 19, {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00}}, }; From 4614beb87e8feb9f49918d31657f2f19e20a353c Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Wed, 20 Mar 2019 17:14:55 +0300 Subject: [PATCH 0861/4321] pkcs11-tool: Add keys access flags --- src/tools/pkcs11-tool.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 65295f70f3..b040100528 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -526,6 +526,11 @@ ATTR_METHOD(VERIFY, CK_BBOOL); /* getVERIFY */ ATTR_METHOD(WRAP, CK_BBOOL); /* getWRAP */ ATTR_METHOD(UNWRAP, CK_BBOOL); /* getUNWRAP */ ATTR_METHOD(DERIVE, CK_BBOOL); /* getDERIVE */ +ATTR_METHOD(SENSITIVE, CK_BBOOL); /* getSENSITIVE */ +ATTR_METHOD(ALWAYS_SENSITIVE, CK_BBOOL); /* getALWAYS_SENSITIVE */ +ATTR_METHOD(EXTRACTABLE, CK_BBOOL); /* getEXTRACTABLE */ +ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL); /* getNEVER_EXTRACTABLE */ +ATTR_METHOD(LOCAL, CK_BBOOL); /* getLOCAL */ ATTR_METHOD(OPENSC_NON_REPUDIATION, CK_BBOOL); /* getOPENSC_NON_REPUDIATION */ ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE); /* getKEY_TYPE */ ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */ @@ -3953,8 +3958,37 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("none"); printf("\n"); - if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) - printf(" Access: always authenticate\n"); + printf(" Access: "); + sepa = ""; + if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) { + printf("%salways authenticate", sepa); + sepa = ", "; + } + if (!pub || sec) { + if (getSENSITIVE(sess, obj)) { + printf("%ssensitive", sepa); + sepa = ", "; + } + if (getALWAYS_SENSITIVE(sess, obj)) { + printf("%salways sensitive", sepa); + sepa = ", "; + } + if (getEXTRACTABLE(sess, obj)) { + printf("%sextractable", sepa); + sepa = ", "; + } + if (getNEVER_EXTRACTABLE(sess, obj)) { + printf("%snever extractable", sepa); + sepa = ", "; + } + } + if (getLOCAL(sess, obj)) { + printf("%slocal", sepa); + sepa = ", "; + } + if (!*sepa) + printf("none"); + printf("\n"); if (!pub) { mechs = getALLOWED_MECHANISMS(sess, obj, &size); From 0e12b1dc711c6296155c336b904516de2443c589 Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Thu, 21 Mar 2019 15:29:32 +0300 Subject: [PATCH 0862/4321] pkcs11-tool: Generate GOSTR3410-2012 keys --- src/pkcs11/pkcs11.h | 15 ++++++ src/tools/pkcs11-tool.c | 114 +++++++++++++++++++++++++++++----------- 2 files changed, 99 insertions(+), 30 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 2384f91e06..e24734c6f3 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -361,6 +361,12 @@ typedef unsigned long ck_key_type_t; #define CKK_GOST28147 (0x32UL) #define CKK_VENDOR_DEFINED (1UL << 31) +// A mask for new GOST algorithms. +// For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html +#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) +#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM + +#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) typedef unsigned long ck_certificate_type_t; @@ -709,8 +715,17 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) #define CKM_GOSTR3410_KEY_WRAP (0x1203UL) #define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) +#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) +#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) #define CKM_GOSTR3411 (0x1210UL) #define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) +#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) +#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) +#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) #define CKM_GOST28147_KEY_GEN (0x1220UL) #define CKM_GOST28147_ECB (0x1221UL) #define CKM_GOST28147 (0x1222UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b040100528..24ab6137d0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -264,7 +264,7 @@ static const char *option_help[] = { "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", "Key pair generation", "Key generation", - "Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1 or GOSTR3410:A", + "Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1 or GOSTR3410-2012-256:B", "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", "Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)", "Specify 'derive' key usage flag (EC only)", @@ -2336,49 +2336,103 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ecparams, ecparams_size); n_pubkey_attr++; } - else if (strncmp(type, "GOSTR3410:", strlen("GOSTR3410:")) == 0 || strncmp(type, "gostr3410:", strlen("gostr3410:")) == 0) { - CK_BYTE key_paramset_encoded_oid[9]; - CK_BYTE hash_paramset_encoded_oid[9]; - const CK_BYTE GOST_PARAMSET_A_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01}; - const CK_BYTE GOST_PARAMSET_B_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02}; - const CK_BYTE GOST_PARAMSET_C_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03}; - const CK_BYTE GOST_HASH_PARAMSET_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01}; - unsigned long int gost_key_type = CKK_GOSTR3410; - CK_MECHANISM_TYPE mtypes[] = {CKM_GOSTR3410_KEY_PAIR_GEN}; + else if (strncmp(type, "GOSTR3410", strlen("GOSTR3410")) == 0 || strncmp(type, "gostr3410", strlen("gostr3410")) == 0) { + const struct sc_aid GOST2001_PARAMSET_A_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 }, 9 }; + const struct sc_aid GOST2001_PARAMSET_B_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 }, 9 }; + const struct sc_aid GOST2001_PARAMSET_C_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 }, 9 }; + const struct sc_aid GOST2012_256_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x01, 0x01 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_B_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x02 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_C_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x03 }, 11 }; + const struct sc_aid GOST_HASH2001_PARAMSET_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }, 9 }; + const struct sc_aid GOST_HASH2012_256_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 }, 10 }; + const struct sc_aid GOST_HASH2012_512_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }, 10 }; + struct sc_aid key_paramset_encoded_oid; + struct sc_aid hash_paramset_encoded_oid; + unsigned long int gost_key_type = -1; + CK_MECHANISM_TYPE mtypes[] = {-1}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); - const char *p_param_set = type + strlen("GOSTR3410:"); - - if (!opt_mechanism_used) { - if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) - util_fatal("Generate GOSTR3410 mechanism not supported"); - } + const char *p_param_set = type + strlen("GOSTR3410"); if (p_param_set == NULL) util_fatal("Unknown key type %s", type); - if (!strcmp("A", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_A_OID, sizeof(GOST_PARAMSET_A_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + if (!strcmp(":A", p_param_set) || !strcmp("-2001:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; + } + else if (!strcmp(":B", p_param_set) || !strcmp("-2001:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; + } + else if (!strcmp(":C", p_param_set) || !strcmp("-2001:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; + } else if (!strcmp("-2012-256:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_256_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-256:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; } - else if (!strcmp("B", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_B_OID, sizeof(GOST_PARAMSET_B_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + else if (!strcmp("-2012-256:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; } - else if (!strcmp("C", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_C_OID, sizeof(GOST_PARAMSET_C_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + else if (!strcmp("-2012-256:D", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-512:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; + } + else if (!strcmp("-2012-512:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; + } + else if (!strcmp("-2012-512:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; } else - util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410:A, GOSTR3410:B, GOSTR3410:C", type); + util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410-2001:{A,B,C}," + " GOSTR3410-2012-256:{A,B,C,D}, GOSTR3410-2012-512:{A,B,C}", type); + + if (!opt_mechanism_used) { + if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate GOSTR3410%s mechanism not supported", gost_key_type == CKK_GOSTR3410_512 ? "-2012-512" : ""); + } - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len); n_privkey_attr++; - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len); n_privkey_attr++; FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type)); From a5382d32fde67d3c882d7bf717307a913b78772d Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Mon, 25 Mar 2019 12:39:36 +0300 Subject: [PATCH 0863/4321] pkcs11-tool: Show GOSTR3410-2012 keys --- src/tools/pkcs11-tool.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 24ab6137d0..40ee41f1a5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -117,6 +117,10 @@ static struct ec_curve_info { {NULL, NULL, NULL, 0}, }; +static const struct sc_aid GOST_HASH2001_PARAMSET_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }, 9 }; +static const struct sc_aid GOST_HASH2012_256_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 }, 10 }; +static const struct sc_aid GOST_HASH2012_512_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }, 10 }; + enum { OPT_MODULE = 0x100, OPT_SLOT, @@ -547,6 +551,7 @@ VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ #endif VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */ +VARATTR_METHOD(GOSTR3411_PARAMS, unsigned char); /* getGOSTR3411_PARAMS */ VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */ VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */ VARATTR_METHOD(ALLOWED_MECHANISMS, CK_MECHANISM_TYPE); /* getALLOWED_MECHANISMS */ @@ -2344,9 +2349,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, const struct sc_aid GOST2012_512_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 }, 11 }; const struct sc_aid GOST2012_512_PARAMSET_B_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x02 }, 11 }; const struct sc_aid GOST2012_512_PARAMSET_C_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x03 }, 11 }; - const struct sc_aid GOST_HASH2001_PARAMSET_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }, 9 }; - const struct sc_aid GOST_HASH2012_256_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 }, 10 }; - const struct sc_aid GOST_HASH2012_512_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }, 10 }; struct sc_aid key_paramset_encoded_oid; struct sc_aid hash_paramset_encoded_oid; unsigned long int gost_key_type = -1; @@ -3843,7 +3845,22 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("; RSA \n"); break; case CKK_GOSTR3410: - printf("; GOSTR3410 \n"); + case CKK_GOSTR3410_512: + oid = getGOSTR3411_PARAMS(sess, obj, &size); + if (oid) { + if (size == GOST_HASH2001_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2001_PARAMSET_OID.value, size)) + printf("; GOSTR3410\n"); + else if (size == GOST_HASH2012_256_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2012_256_PARAMSET_OID.value, size)) + printf("; GOSTR3410-2012-256\n"); + else if (size == GOST_HASH2012_512_PARAMSET_OID.len && !memcmp(oid, GOST_HASH2012_512_PARAMSET_OID.value, size)) + printf("; GOSTR3410-2012-512\n"); + else + printf("; unknown GOSTR3410 algorithm\n"); + free(oid); + } else { + printf("; unknown GOSTR3410 algorithm\n"); + } + oid = getGOSTR3410_PARAMS(sess, obj, &size); if (oid) { unsigned int n; From 8cf1e6f769b36bdcadc3958574305b90e88c816d Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Mon, 25 Mar 2019 12:58:28 +0300 Subject: [PATCH 0864/4321] pkcs11-tool: List supported GOST mechanisms --- src/tools/pkcs11-tool.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 40ee41f1a5..393d1e30a1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6479,11 +6479,26 @@ static struct mech_info p11_mechanisms[] = { { CKM_DES3_CBC_ENCRYPT_DATA, "DES3-CBC-ENCRYPT-DATA", NULL }, { CKM_AES_ECB_ENCRYPT_DATA, "AES-ECB-ENCRYPT-DATA", NULL }, { CKM_AES_CBC_ENCRYPT_DATA, "AES-CBC-ENCRYPT-DATA", NULL }, + { CKM_GOST28147_KEY_GEN, "GOST28147-KEY-GEN", NULL }, + { CKM_GOST28147_ECB, "GOST28147-ECB", NULL }, + { CKM_GOST28147, "GOST28147", NULL }, + { CKM_GOST28147_MAC, "GOST28147-MAC", NULL }, + { CKM_GOST28147_KEY_WRAP, "GOST28147-KEY-WRAP", NULL }, { CKM_GOSTR3410_KEY_PAIR_GEN,"GOSTR3410-KEY-PAIR-GEN", NULL }, { CKM_GOSTR3410, "GOSTR3410", NULL }, + { CKM_GOSTR3410_DERIVE, "GOSTR3410-DERIVE", NULL }, { CKM_GOSTR3410_WITH_GOSTR3411,"GOSTR3410-WITH-GOSTR3411", NULL }, + { CKM_GOSTR3410_512_KEY_PAIR_GEN, "GOSTR3410-512-KEY-PAIR-GEN", NULL }, + { CKM_GOSTR3410_512, "GOSTR3410_512", NULL }, + { CKM_GOSTR3410_12_DERIVE, "GOSTR3410-12-DERIVE", NULL }, + { CKM_GOSTR3410_WITH_GOSTR3411_12_256, "GOSTR3410-WITH-GOSTR3411-12-256", NULL }, + { CKM_GOSTR3410_WITH_GOSTR3411_12_512, "GOSTR3410-WITH-GOSTR3411-12-512", NULL }, { CKM_GOSTR3411, "GOSTR3411", NULL }, { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL }, + { CKM_GOSTR3411_12_256, "GOSTR3411-12-256", NULL }, + { CKM_GOSTR3411_12_512, "GOSTR3411-12-512", NULL }, + { CKM_GOSTR3411_12_256_HMAC, "GOSTR3411-12-256-HMAC", NULL }, + { CKM_GOSTR3411_12_512_HMAC, "GOSTR3411-12-512-HMAC", NULL }, { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL }, { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL }, { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL }, From 8f2b4c79237076a4f60a969edb3573c725de3798 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 18 Apr 2019 01:40:07 +0200 Subject: [PATCH 0865/4321] macos: use hierarchical layout for installer --- MacOSX/Distribution.xml.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index 22e5104d4d..848950d133 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -11,9 +11,10 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D @PACKAGE_STRING@ - - - + + + + OpenSC.pkg From abc6cfbe68323e83f36e4cc6db771a5d8a8ed4db Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 12 Apr 2019 22:39:46 +0200 Subject: [PATCH 0866/4321] Added more CI card testing --- .travis.yml | 11 ++++++++--- README.md | 12 ++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7c4fe41c08..61e951210e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -167,6 +167,12 @@ script: sleep 5; opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100; opensc-tool -n; + pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef; + pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456; + pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456; + pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456; + pkcs15-tool -D; + pkcs11-tool -l -t -p 123456; killall java; java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null & @@ -187,9 +193,8 @@ script: sleep 5; opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f; opensc-tool -n; - yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate > pubkey-9e.pem; - yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a selfsign-certificate -S '/CN=test' < pubkey-9e.pem > cert-9e.pem; - yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a import-certificate < cert-9e.pem; + yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256; + yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048; pkcs11-tool -l -t -p 123456; killall java; set +ex; diff --git a/README.md b/README.md index e6fdf25ac5..27dfebcbee 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,11 @@ Please take a look at the documentation before trying to use OpenSC. Build and test status of specific cards: -| Cards | Status | -|-----------------------|--------| -| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | -| Coolkey | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| Cards | Status | +|---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| +| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| [Coolkey](https://github.com/dogtagpki/coolkey/tree/master/applet) | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | From 13429baed047a93719987db900f169c7a426c426 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Apr 2019 12:27:03 +0200 Subject: [PATCH 0867/4321] cac: Avoid signed/unsigned casting reported by coverity src/libopensc/card-cac.c:1707: negative_returns: "val_len" is passed to a parameter that cannot be negative. --- src/libopensc/card-cac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 634c0d27fb..d02e8318fb 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1664,7 +1664,6 @@ static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t * cac_object_t pki_obj = cac_cac_pki_obj; u8 buf[100]; u8 *val; - size_t val_len; /* populate PKI objects */ for (i = index; i < MAX_CAC_SLOTS; i++) { @@ -1701,13 +1700,14 @@ static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t * return r; /* shouldn't happen unless the card has been removed or is malfunctioning */ } val = buf; - val_len = cac_read_binary(card, 0, val, sizeof(buf), 0); - if (val_len > 0) { + r = cac_read_binary(card, 0, val, sizeof(buf), 0); + if (r > 0) { +#ifdef ENABLE_OPENSSL + size_t val_len = r; priv->cac_id = malloc(20); if (priv->cac_id == NULL) { return SC_ERROR_OUT_OF_MEMORY; } -#ifdef ENABLE_OPENSSL SHA1(val, val_len, priv->cac_id); priv->cac_id_len = 20; sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE, From e21cb5712c04b7ac5ae10ca754d952fe28679cf6 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Wed, 24 Apr 2019 14:03:35 +0200 Subject: [PATCH 0868/4321] Fix in encrypt_decrypt(), initialize the mgf --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a2f2a94dc3..d9199550f8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5287,7 +5287,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_RV rv; int pad; CK_MECHANISM_TYPE hash_alg = CKM_SHA256; - CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256; CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); From b06398c1af93e51c5acf25ff35ecd8c8af377d4a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 14:48:42 +0200 Subject: [PATCH 0869/4321] macOS: install man, doc, completion to /usr/local --- MacOSX/opensc-uninstall | 14 +++++++++++--- MacOSX/scripts/postinstall | 17 ++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index 62b5b0fdbc..390d6ed2d2 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -6,9 +6,17 @@ if [ "$(id -u)" != "0" ]; then exit 1 fi -# Remove symlinks to commands -for file in /Library/OpenSC/bin/*; do - test -L "/usr/local/bin/$(basename $file)" && rm -f "/usr/local/bin/$(basename $file)" +for f in \ + /Library/OpenSC/bin/* \ + /Library/OpenSC/etc/bash_completion.d/* \ + /Library/OpenSC/share/doc/opensc \ + /Library/OpenSC/share/man/man1/* \ + /Library/OpenSC/share/man/man5/* +do + a=/Library/OpenSC + b=/usr/local + l="${f/$a/$b}" + test -L "$l" && rm -f "$l" done # Remove pkcs11 libraries diff --git a/MacOSX/scripts/postinstall b/MacOSX/scripts/postinstall index 8293c2c3dc..ff11f83193 100755 --- a/MacOSX/scripts/postinstall +++ b/MacOSX/scripts/postinstall @@ -16,12 +16,23 @@ else md5 -r /Library/OpenSC/etc/opensc.conf > /Library/OpenSC/etc/opensc.conf.md5 fi -for f in /Library/OpenSC/bin/* +for f in \ + /Library/OpenSC/bin/* \ + /Library/OpenSC/etc/bash_completion.d/* \ + /Library/OpenSC/share/doc/opensc \ + /Library/OpenSC/share/man/man1/* \ + /Library/OpenSC/share/man/man5/* do - ln -sf $f /usr/local/bin + a=/Library/OpenSC + b=/usr/local + l="$(dirname ${f/$a/$b})" + mkdir -p $l + ln -sf $f $l done -for f in /Library/LaunchAgents/pkcs11-register.plist /Library/LaunchAgents/opensc-notify.plist +for f in \ + /Library/LaunchAgents/pkcs11-register.plist \ + /Library/LaunchAgents/opensc-notify.plist do if [ -e "$f" ] then From 98ec27e76828034aab971490027e4e3ee777eed1 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Thu, 18 Apr 2019 15:22:56 +0200 Subject: [PATCH 0870/4321] pkcs11-spy: log pParameter buffer for C_EncryptInit & C_DecryptInit --- src/pkcs11/pkcs11-spy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 83870840cf..518f3d2655 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -784,6 +784,7 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_EncryptInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); spy_dump_ulong_in("hKey", hKey); rv = po->C_EncryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -860,6 +861,7 @@ C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT } break; default: + spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); break; } spy_dump_ulong_in("hKey", hKey); From 69727c79adeda87faa69a9e7497dd33471f18512 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Thu, 18 Apr 2019 15:31:15 +0200 Subject: [PATCH 0871/4321] pkcs11.h: add CK_GCM_PARAMS structure --- src/pkcs11/pkcs11.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index e24734c6f3..61bd6dc45d 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -815,6 +815,14 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS { #define CKZ_DATA_SPECIFIED (0x00000001UL) +typedef struct CK_GCM_PARAMS { + void * pIv; + unsigned long ulIvLen; + void * pAAD; + unsigned long ulAADLen; + unsigned long ulTagBits; +} CK_GCM_PARAMS; + typedef unsigned long ck_rv_t; From ffaaf1c0d3884d01888042e34e4cce3cc9a4a83d Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Thu, 18 Apr 2019 15:31:41 +0200 Subject: [PATCH 0872/4321] pkcs11-spy: parse CKM_AES_GCM for C_EncryptInit() --- src/pkcs11/pkcs11-spy.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 518f3d2655..6bc9baaa6e 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -784,7 +784,25 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_EncryptInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); + switch (pMechanism->mechanism) { + case CKM_AES_GCM: + if (pMechanism->pParameter != NULL) { + CK_GCM_PARAMS *param = + (CK_GCM_PARAMS *) pMechanism->pParameter; + spy_dump_string_in("pIv[ulIvLen]", + param->pIv, param->ulIvLen); + spy_dump_string_in("pAAD[ulAADLen]", + param->pAAD, param->ulAADLen); + fprintf(spy_output, "pMechanism->pParameter->ulTagBits=%lu\n", param->ulTagBits); + } else { + fprintf(spy_output, "Parameters block for %s is empty...\n", + lookup_enum(MEC_T, pMechanism->mechanism)); + } + break; + default: + spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); + break; + } spy_dump_ulong_in("hKey", hKey); rv = po->C_EncryptInit(hSession, pMechanism, hKey); return retne(rv); From 3d22d04113d71f14e7807927c166e80b8c184e61 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 17 Apr 2019 21:44:44 +0300 Subject: [PATCH 0873/4321] No need link to libssl Signed-off-by: Raul Metsma --- configure.ac | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index dd9156555b..c4d461e928 100644 --- a/configure.ac +++ b/configure.ac @@ -21,8 +21,6 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(version.m4.ci) -m4_define([openssl_minimum_version], [0.9.8]) - AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_HEADERS([config.h]) @@ -625,10 +623,7 @@ fi PKG_CHECK_MODULES( [OPENSSL], - [ - libcrypto >= openssl_minimum_version - openssl >= openssl_minimum_version - ], + [libcrypto >= 0.9.8], [have_openssl="yes"], [AC_CHECK_LIB( [crypto], From 0e25c1d2a62a7bb461d34a650ab1d3b1d8d74a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 3 Apr 2019 16:21:23 +0300 Subject: [PATCH 0874/4321] MyEID: detect card from ATR historical data instead of full ATR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will simplify the matching code, and match prototype cards. Signed-off-by: Timo Teräs --- src/libopensc/card-myeid.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 514d86aef0..dab62f2286 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -75,16 +75,6 @@ static struct sc_card_driver myeid_drv = { NULL }; -static const char *myeid_atrs[] = { - "3B:F5:18:00:FF:81:31:FE:45:4D:79:45:49:44:65", - "3B:F5:18:00:00:81:31:FE:45:4D:79:45:49:44:9A", - "3B:85:80:01:4D:79:45:49:44:78", - "3B:89:80:01:09:38:33:B1:4D:79:45:49:44:4C", - "3B:F5:96:00:00:80:31:FE:45:4D:79:45:49:44:15", /* Infineon's chip */ - "3B:F5:96:00:00:81:31:FE:45:4D:79:45:49:44:14", - NULL -}; - typedef struct myeid_private_data { int card_state; @@ -123,27 +113,14 @@ static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_cap static int myeid_match_card(struct sc_card *card) { - int i, match = -1; - - for (i = 0; myeid_atrs[i] != NULL; i++) - { - u8 defatr[SC_MAX_ATR_SIZE]; - size_t len = sizeof(defatr); - const char *atrp = myeid_atrs[i]; - - if (sc_hex_to_bin(atrp, defatr, &len)) - continue; - if (len != card->atr.len) - continue; - if (memcmp(card->atr.value, defatr, len) != 0) - continue; - match = i; - break; + /* Normally the historical bytes are exactly "MyEID", but there might + * be some historic units which have a small prefix byte sequence. */ + if (card->reader->atr_info.hist_bytes_len >= 5 && + !memcmp(&card->reader->atr_info.hist_bytes[card->reader->atr_info.hist_bytes_len - 5], "MyEID", 5)) { + card->type = SC_CARD_TYPE_MYEID_GENERIC; + return 1; } - if (match == -1) - return 0; - - return 1; + return 0; } static int From 3f832ca6da9f1659c23bd74c9db62a352c96dfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 30 Mar 2019 18:25:02 +0200 Subject: [PATCH 0875/4321] MyEID: implement support for 4K RSA keys (MyEID 4.5+) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MyEID starting version 4.5 supports 4K RSA keys. The card also now supports proper APDU chainging (for sending large APDUs) and receiving large responses via GET_RESPONSE splitting. This updates the following: * detection code properly announces 3K and 4K RSA support when available * APDU chaining is used when possible * use ISO GET_RESPONSE handling for large responses * max_recv_size is set to 256 which it always was supposed to be as the old cards respond with that large responses too * use the 2K signing kludge only on cards that need it * unwrap and decipher code paths unified to the extent possible Signed-off-by: Timo Teräs --- src/libopensc/card-myeid.c | 355 +++++++++++++++------------------- src/pkcs15init/pkcs15-myeid.c | 2 +- 2 files changed, 155 insertions(+), 202 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index dab62f2286..0a11506bf3 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1,7 +1,7 @@ /* * card-myeid.c * - * Copyright (C) 2008-2009 Aventra Ltd. + * Copyright (C) 2008-2019 Aventra Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -60,7 +60,9 @@ #define MYEID_CARD_CAP_PIV_EMU 0x20 #define MYEID_MAX_APDU_DATA_LEN 0xFF -#define MYEID_MAX_RSA_KEY_LEN 2048 +#define MYEID_MAX_RSA_KEY_LEN 4096 + +#define MYEID_MAX_EXT_APDU_BUFFER_SIZE (MYEID_MAX_RSA_KEY_LEN/8+16) static const char *myeid_card_name = "MyEID"; static char card_name_buf[MYEID_CARD_NAME_MAX_LEN]; @@ -79,6 +81,7 @@ typedef struct myeid_private_data { int card_state; unsigned short change_counter; + unsigned char cap_chaining; /* the driver sets sec_env pointer in myeid_set_security_env and it is used immediately in myeid_decipher to differentiate between RSA decryption and ECDH key agreement. Note that this pointer is usually not valid @@ -161,7 +164,7 @@ static int myeid_init(struct sc_card *card) myeid_private_data_t *priv; u8 appletInfo[20]; size_t appletInfoLen; - myeid_card_caps_t card_caps; + myeid_card_caps_t card_caps; size_t resp_len = 0; static struct sc_aid myeid_aid = { "\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35", 0x0C }; int rv = 0; @@ -191,15 +194,6 @@ static int myeid_init(struct sc_card *card) priv->change_counter = appletInfo[19] | appletInfo[18] << 8; - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN; - flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; - - _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); - _sc_card_add_rsa_alg(card, 1536, flags, 0); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - memset(&card_caps, 0, sizeof(myeid_card_caps_t)); card_caps.max_ecc_key_length = 256; card_caps.max_rsa_key_length = 2048; @@ -212,6 +206,22 @@ static int myeid_init(struct sc_card *card) } } + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN; + flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; + + _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); + _sc_card_add_rsa_alg(card, 1536, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + + if (card_caps.card_supported_features & MYEID_CARD_CAP_RSA) { + if (card_caps.max_rsa_key_length >= 3072) + _sc_card_add_rsa_alg(card, 3072, flags, 0); + if (card_caps.max_rsa_key_length >= 4096) + _sc_card_add_rsa_alg(card, 4096, flags, 0); + } + /* show ECC algorithms if the applet version of the inserted card supports them */ if (card->version.fw_major >= 35) { int i; @@ -251,7 +261,10 @@ static int myeid_init(struct sc_card *card) card->caps |= SC_CARD_CAP_WRAP_KEY | SC_CARD_CAP_UNWRAP_KEY | SC_CARD_CAP_ONCARD_SESSION_OBJECTS; - card->max_recv_size = 255; + if (card->version.fw_major >= 45) + priv->cap_chaining = 1; + + card->max_recv_size = 256; card->max_send_size = 255; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); @@ -969,12 +982,10 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char * free(buf); return buflen; } -/* - MyEID does not support RAW RSA signature for 2048 bit key. - (Source: MyEID reference manual 2.1.4) - - This function uses decipher operation for calculating RAW 2048 bit signature. -*/ +/* MyEID cards before version 4.5 do not support RAW RSA signature for 2048 bit RSA keys. + * (Source: MyEID reference manual 2.1.4) + * + * This function uses decipher operation for calculating RAW 2048 bit signature. */ static int myeid_compute_raw_2048_signature(struct sc_card *card, const u8 * data, size_t datalen, u8 * out, size_t outlen) @@ -1044,8 +1055,8 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, { struct sc_context *ctx; struct sc_apdu apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 rbuf[MYEID_MAX_EXT_APDU_BUFFER_SIZE]; + u8 sbuf[MYEID_MAX_EXT_APDU_BUFFER_SIZE]; struct myeid_private_data* priv; int r; size_t field_length = 0; @@ -1071,16 +1082,17 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, } } - if ((datalen + pad_chars) > 256) + if ((datalen + pad_chars) > sizeof(sbuf)) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - if (datalen == 256 && priv->sec_env->algorithm == SC_ALGORITHM_RSA) + if (priv->sec_env->algorithm == SC_ALGORITHM_RSA && datalen == 256 && !priv->cap_chaining) return myeid_compute_raw_2048_signature(card, data, datalen, out, outlen); /* INS: 0x2A PERFORM SECURITY OPERATION * P1: 0x9E Resp: Digital Signature * P2: 0x9A Cmd: Input for Digital Signature */ sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); + apdu.flags |= SC_APDU_FLAGS_CHAINING; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; @@ -1094,7 +1106,7 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, r, "compute_signature failed"); - if (priv->sec_env->algorithm == SC_ALGORITHM_EC) { + if (priv->sec_env->algorithm == SC_ALGORITHM_EC) { r = myeid_convert_ec_signature(ctx, priv->sec_env->algorithm_ref, apdu.resp, apdu.resplen); LOG_TEST_RET(ctx, r, "compute_signature convert signature failed"); apdu.resplen = r; @@ -1177,15 +1189,101 @@ int myeid_ecdh_derive(struct sc_card *card, const u8* pubkey, size_t pubkey_len, LOG_FUNC_RETURN(card->ctx, apdu.resplen); } +static int myeid_transmit_decipher_pi_split(struct sc_card *card, struct sc_apdu *apdu, u8 *sbuf) +{ + /* MyEID before 4.5.x does not support APDU chaining. The payload + * is split to two regular APDUs and Padding Indicator field is used to + * describe which slice it is. */ + size_t crgram_len = apdu->lc - 1; + size_t crgram_half = crgram_len / 2; + size_t resplen = apdu->resplen; + unsigned char *resp = apdu->resp; + int r; + + LOG_FUNC_CALLED(card->ctx); + + /* Send 1st part, no response */ + apdu->cse = SC_APDU_CASE_3_SHORT; + apdu->data = &sbuf[0]; + apdu->datalen = apdu->lc = crgram_half + 1; + apdu->resp = 0; + apdu->resplen = 0; + apdu->le = 0; + sbuf[0] = 0x81; /* Padding Indicator, 0x81 = First half */ + + r = sc_transmit_apdu(card, apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu->sw1 != 0x90 || apdu->sw2 != 0x00) + return 0; + + /* Send 2nd part, expect response */ + apdu->cse = resplen ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT; + apdu->data = &sbuf[crgram_half]; + apdu->datalen = apdu->lc = crgram_len - crgram_half + 1; + apdu->resp = resp; + apdu->resplen = resplen; + apdu->le = resplen ? MIN(card->max_recv_size, crgram_len) : 0; + sbuf[crgram_half] = 0x82; /* Padding Indicator, 0x82 = Second half */ + + r = sc_transmit_apdu(card, apdu); + LOG_FUNC_RETURN(card->ctx, r); +} + +static int myeid_transmit_decipher(struct sc_card *card, u8 p1, u8 p2, + const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) +{ + myeid_private_data_t *priv = card->drv_data; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + int r; + + LOG_FUNC_CALLED(card->ctx); + + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x00 Resp: No response (unwrapping) + * P1: 0x80 Resp: Plain value + * P2: 0x84 Cmd: Cryptogram (no padding byte) + * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ + sc_format_apdu(card, &apdu, p1 ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, 0x2A, p1, p2); + if (p2 == 0x86) { + if (crgram_len+1 > sizeof(sbuf)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + sbuf[0] = 0; /* Padding indicator: 0x00 = No further indication */ + memcpy(sbuf + 1, crgram, crgram_len); + apdu.data = sbuf; + apdu.datalen = apdu.lc = crgram_len + 1; + } else { + apdu.data = crgram; + apdu.datalen = apdu.lc = crgram_len; + } + if (p1 != 0x00) { + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = MIN(card->max_recv_size, crgram_len); + } + + if (p2 == 0x86 && crgram_len == 256 && !priv->cap_chaining) { + r = myeid_transmit_decipher_pi_split(card, &apdu, sbuf); + } else { + apdu.flags |= SC_APDU_FLAGS_CHAINING; + r = sc_transmit_apdu(card, &apdu); + } + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "DECIPHER returned error"); + + outlen = MIN(apdu.resplen, outlen); + memcpy(out, apdu.resp, outlen); + LOG_FUNC_RETURN(card->ctx, outlen); +} static int myeid_decipher(struct sc_card *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen) { int r; myeid_private_data_t* priv; - struct sc_apdu apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; LOG_FUNC_CALLED(card->ctx); @@ -1202,77 +1300,8 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, LOG_FUNC_RETURN(card->ctx, r); } - if (crgram_len > 256) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - - /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x80 Resp: Plain value - * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ - sc_format_apdu(card, &apdu, - (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, - 0x2A, 0x80, 0x86); - - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = crgram_len; - - if (crgram_len == 256) - { - apdu.le = 0; - /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ - sbuf[0] = 0x81; - memcpy(sbuf + 1, crgram, crgram_len / 2); - apdu.lc = crgram_len / 2 + 1; - } - else - { - sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ - memcpy(sbuf + 1, crgram, crgram_len); - apdu.lc = crgram_len + 1; - } - - apdu.datalen = apdu.lc; - apdu.data = sbuf; - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { - if (crgram_len == 256) - { - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, - 0x2A, 0x80, 0x86); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = crgram_len; - /* padding indicator byte, - * 0x82 = Second half of 2048 bit cryptogram */ - sbuf[0] = 0x82; - memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); - apdu.lc = crgram_len / 2 + 1; - apdu.datalen = apdu.lc; - apdu.data = sbuf; - - r = sc_transmit_apdu(card, &apdu); - - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { - int len = apdu.resplen > outlen ? outlen : apdu.resplen; - memcpy(out, apdu.resp, len); - LOG_FUNC_RETURN(card->ctx, len); - } - } - else - { - int len = apdu.resplen > outlen ? outlen : apdu.resplen; - - memcpy(out, apdu.resp, len); - LOG_FUNC_RETURN(card->ctx, len); - } - } - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + r = myeid_transmit_decipher(card, 0x80, 0x86, crgram, crgram_len, out, outlen); + LOG_FUNC_RETURN(card->ctx, r); } @@ -1309,111 +1338,35 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len) { - int r; - struct sc_apdu apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + myeid_private_data_t* priv = card->drv_data; u8 p2 = 0x86; /* init P2 for asymmetric crypto by default.*/ - myeid_private_data_t* priv; - int symmetric_operation = 0; + int r; - if (card == NULL || crgram == NULL) { + if (card == NULL || crgram == NULL) return SC_ERROR_INVALID_ARGUMENTS; - } - LOG_FUNC_CALLED(card->ctx); LOG_FUNC_CALLED(card->ctx); if (crgram_len > MYEID_MAX_RSA_KEY_LEN / 8) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if (card->drv_data) + if (priv && priv->sec_env) { - priv = (myeid_private_data_t*) card->drv_data; - - if (priv->sec_env) - { - if (priv->sec_env->algorithm == SC_ALGORITHM_AES || - priv->sec_env->algorithm == SC_ALGORITHM_3DES || - priv->sec_env->algorithm == SC_ALGORITHM_DES) - symmetric_operation = 1; - } + if (priv->sec_env->algorithm == SC_ALGORITHM_AES || + priv->sec_env->algorithm == SC_ALGORITHM_3DES || + priv->sec_env->algorithm == SC_ALGORITHM_DES) + p2 = 0x84; } - if (symmetric_operation) - { - p2 = 0x84; /* Set correct P2 for symmetric crypto */ - if (crgram_len > MYEID_MAX_APDU_DATA_LEN) - { - LOG_TEST_RET(card->ctx, SC_ERROR_WRONG_LENGTH, "Unwrapping symmetric data longer that 255 bytes is not supported\n"); - } - } + if (p2 == 0x84 && crgram_len > MYEID_MAX_APDU_DATA_LEN) + LOG_TEST_RET(card->ctx, SC_ERROR_WRONG_LENGTH, "Unwrapping symmetric data longer that 255 bytes is not supported\n"); /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF. - * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram - * P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) - If crgram_len == 256 (2048 bit RSA), we split the cryptogram in two and send two APDUs. - */ - sc_format_apdu(card, &apdu, - SC_APDU_CASE_3_SHORT, - 0x2A, 0x00, p2); - - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 0; - - if (symmetric_operation) - { - /* symmetric crypto, no padding indicator byte */ - memcpy(sbuf, crgram, crgram_len); - apdu.lc = crgram_len; - } - else - { - if (crgram_len >= MYEID_MAX_APDU_DATA_LEN) - { - /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ - sbuf[0] = 0x81; - memcpy(sbuf + 1, crgram, crgram_len / 2); - apdu.lc = crgram_len / 2 + 1; - } - else - { - sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ - memcpy(sbuf + 1, crgram, crgram_len); - apdu.lc = crgram_len + 1; - } - } - - apdu.datalen = apdu.lc; - apdu.data = sbuf; - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { - if (crgram_len >= MYEID_MAX_APDU_DATA_LEN) - { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, - 0x2A, 0x00, p2); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 0; - /* padding indicator byte, - * 0x82 = Second half of 2048 bit cryptogram */ - sbuf[0] = 0x82; - memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); - apdu.lc = crgram_len / 2 + 1; - apdu.datalen = apdu.lc; - apdu.data = sbuf; - - r = sc_transmit_apdu(card, &apdu); - - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - } - } - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + * P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF. + * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram + * P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) */ + r = myeid_transmit_decipher(card, 0x00, p2, crgram, crgram_len, 0, 0); + LOG_FUNC_RETURN(card->ctx, r); } @@ -1482,22 +1435,22 @@ static int myeid_getdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) { + myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data; sc_apdu_t apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[MYEID_MAX_EXT_APDU_BUFFER_SIZE]; int r, len; LOG_FUNC_CALLED(card->ctx); len = 0; - if(value_len == 0 || value == NULL) + if (value_len == 0 || value == NULL) return 0; - if(value != NULL && - value[0] != 0x0 && - mode != LOAD_KEY_PUBLIC_EXPONENT && - mode != LOAD_KEY_SYMMETRIC) + if (value[0] != 0x0 && + mode != LOAD_KEY_PUBLIC_EXPONENT && + mode != LOAD_KEY_SYMMETRIC) sbuf[len++] = 0x0; - if(mode == LOAD_KEY_MODULUS && value_len >= 256) + if(mode == LOAD_KEY_MODULUS && value_len == 256 && !priv->cap_chaining) { if((value_len % 2) > 0 && value[0] == 0x00) { @@ -1517,11 +1470,10 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) apdu.lc = len; r = sc_transmit_apdu(card, &apdu); - if(r < 0) - return r; + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if(r < 0) - return r; + LOG_TEST_RET(card->ctx, r, "LOAD KEY returned error"); mode = 0x89; len = value_len - 128; @@ -1546,7 +1498,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) memset(&apdu, 0, sizeof(apdu)); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode); - + apdu.flags = SC_APDU_FLAGS_CHAINING; apdu.cla = 0x00; apdu.data = sbuf; apdu.datalen = len; @@ -1824,6 +1776,7 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.append_record = NULL; myeid_ops.update_record = NULL; myeid_ops.select_file = myeid_select_file; + myeid_ops.get_response = iso_ops->get_response; myeid_ops.create_file = myeid_create_file; myeid_ops.delete_file = myeid_delete_file; myeid_ops.list_files = myeid_list_files; diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 095b4fe506..46e1d20bde 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -36,7 +36,7 @@ #undef KEEP_AC_NONE_FOR_INIT_APPLET #define MYEID_MAX_PINS 14 -#define MYEID_MAX_RSA_KEY_LEN 2048 +#define MYEID_MAX_RSA_KEY_LEN 4096 unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; #define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY) From 3688dfe2382cfaf091fe3da17d7495013ca94e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 30 Mar 2019 18:40:54 +0200 Subject: [PATCH 0876/4321] MyEID: simplify key component loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Encode the component ID to be key type and component ID. This allows each combination to be unique and direct mapping to card component ID type in the code by just taking the low byte. This simplifies the code, and reduces confusion as there is now only one #define for each component. Signed-off-by: Timo Teräs --- src/libopensc/card-myeid.c | 50 +++++++++++++++----------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 0a11506bf3..f43add0d6b 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -30,23 +30,21 @@ #include "cardctl.h" #include "types.h" -#define LOAD_KEY_MODULUS 0x80 -#define LOAD_KEY_PUBLIC_EXPONENT 0x81 -#define LOAD_KEY_PRIME_P 0x83 -#define LOAD_KEY_PRIME_Q 0x84 -#define LOAD_KEY_DP1 0x85 -#define LOAD_KEY_DQ1 0x86 -#define LOAD_KEY_INVQ 0x87 -#define LOAD_KEY_MODE_EC_PRIV 0x87 -#define LOAD_KEY_MODE_EC_PUB 0x86 - -#define LOAD_KEY_EC_PRIVATE 0x97 -#define LOAD_KEY_EC_PUBLIC 0x96 - -#define LOAD_KEY_SYMMETRIC 0xa0 - -#define MYEID_STATE_CREATION 0x01 -#define MYEID_STATE_ACTIVATED 0x07 +/* Low byte is the MyEID card's key type specific component ID. High byte is used + * internally for key type, so myeid_loadkey() is aware of the exact component. */ +#define LOAD_KEY_MODULUS 0x0080 +#define LOAD_KEY_PUBLIC_EXPONENT 0x0081 +#define LOAD_KEY_PRIME_P 0x0083 +#define LOAD_KEY_PRIME_Q 0x0084 +#define LOAD_KEY_DP1 0x0085 +#define LOAD_KEY_DQ1 0x0086 +#define LOAD_KEY_INVQ 0x0087 +#define LOAD_KEY_EC_PUBLIC 0x1086 +#define LOAD_KEY_EC_PRIVATE 0x1087 +#define LOAD_KEY_SYMMETRIC 0x20a0 + +#define MYEID_STATE_CREATION 0x01 +#define MYEID_STATE_ACTIVATED 0x07 #define MYEID_CARD_NAME_MAX_LEN 100 @@ -1433,7 +1431,7 @@ static int myeid_getdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* LOG_FUNC_RETURN(card->ctx, r); } -static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) +static int myeid_loadkey(sc_card_t *card, unsigned mode, u8* value, int value_len) { myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data; sc_apdu_t apdu; @@ -1450,9 +1448,9 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) mode != LOAD_KEY_SYMMETRIC) sbuf[len++] = 0x0; - if(mode == LOAD_KEY_MODULUS && value_len == 256 && !priv->cap_chaining) + if (mode == LOAD_KEY_MODULUS && value_len == 256 && !priv->cap_chaining) { - if((value_len % 2) > 0 && value[0] == 0x00) + if ((value_len % 2) > 0 && value[0] == 0x00) { value_len--; memmove(value, value + 1, value_len); @@ -1480,16 +1478,6 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) memset(&sbuf, 0, SC_MAX_APDU_BUFFER_SIZE); memcpy(sbuf,value + 128, value_len - 128); } - else if(mode == LOAD_KEY_EC_PRIVATE) { - memcpy(sbuf, value, value_len); - len = value_len; - mode = LOAD_KEY_MODE_EC_PRIV; - } - else if(mode == LOAD_KEY_EC_PUBLIC) { - memcpy(sbuf, value, value_len); - len = value_len; - mode = LOAD_KEY_MODE_EC_PUB; - } else { memcpy(sbuf + len, value, value_len); @@ -1497,7 +1485,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) } memset(&apdu, 0, sizeof(apdu)); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode & 0xFF); apdu.flags = SC_APDU_FLAGS_CHAINING; apdu.cla = 0x00; apdu.data = sbuf; From bbec50bfdb97bd772429d368daa22c4dba7aa016 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 26 Mar 2019 16:14:25 +0200 Subject: [PATCH 0877/4321] Remove unused SC_PKCS15EMU_FLAGS_NO_CHECK flag Fixes #1634 Signed-off-by: Raul Metsma --- src/libopensc/pkcs15-actalis.c | 11 +++-------- src/libopensc/pkcs15-atrust-acos.c | 12 +++--------- src/libopensc/pkcs15-cac.c | 11 +++-------- src/libopensc/pkcs15-coolkey.c | 12 ++++-------- src/libopensc/pkcs15-din-66291.c | 6 ++---- src/libopensc/pkcs15-dnie.c | 3 --- src/libopensc/pkcs15-esinit.c | 11 +++-------- src/libopensc/pkcs15-esteid.c | 2 -- src/libopensc/pkcs15-gemsafeGPK.c | 11 +++-------- src/libopensc/pkcs15-gemsafeV1.c | 11 +++-------- src/libopensc/pkcs15-gids.c | 10 +++------- src/libopensc/pkcs15-iasecc.c | 3 --- src/libopensc/pkcs15-itacns.c | 14 ++++++-------- src/libopensc/pkcs15-jpki.c | 12 +++--------- src/libopensc/pkcs15-oberthur.c | 9 ++------- src/libopensc/pkcs15-openpgp.c | 11 +++-------- src/libopensc/pkcs15-piv.c | 11 +++-------- src/libopensc/pkcs15-pteid.c | 3 --- src/libopensc/pkcs15-sc-hsm.c | 14 +++++--------- src/libopensc/pkcs15-starcert.c | 12 +++--------- src/libopensc/pkcs15-tcos.c | 5 ++--- src/libopensc/pkcs15-westcos.c | 2 -- src/libopensc/pkcs15.h | 2 -- 23 files changed, 54 insertions(+), 144 deletions(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index f4a3a7561f..754f1de09f 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -320,12 +320,7 @@ int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t * p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t * opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_actalis_init(p15card); - else { - int r = actalis_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_actalis_init(p15card); - } + if (actalis_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_actalis_init(p15card); } diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index 2d6ba4a9e7..5d8baccfee 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -269,13 +269,7 @@ int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_atrust_acos_init(p15card); - else { - int r = acos_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_atrust_acos_init(p15card); - } + if (acos_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_atrust_acos_init(p15card); } diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 57d5bdec31..11271b8b3e 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -450,12 +450,7 @@ int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, LOG_FUNC_CALLED(ctx); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_cac_init(p15card); - else { - int r = cac_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_cac_init(p15card); - } + if (cac_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_cac_init(p15card); } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index f0ec8f48e8..3ffb053c37 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -724,14 +724,10 @@ sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, LOG_FUNC_CALLED(ctx); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - rv = sc_pkcs15emu_coolkey_init(p15card); - else { - rv = coolkey_detect_card(p15card); - if (rv) - LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_CARD); - rv = sc_pkcs15emu_coolkey_init(p15card); - } + rv = coolkey_detect_card(p15card); + if (rv) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_CARD); + rv = sc_pkcs15emu_coolkey_init(p15card); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 7a67e97f2c..ae1de0ecca 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -267,10 +267,8 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid SC_FUNC_CALLED(p15card->card->ctx, 1); /* Check card */ - if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { - if (!din_66291_match_p15card(p15card, aid)) - return SC_ERROR_WRONG_CARD; - } + if (!din_66291_match_p15card(p15card, aid)) + return SC_ERROR_WRONG_CARD; /* Init card */ return sc_pkcs15emu_din_66291_init(p15card); diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 00865ad481..a9e97ac076 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -282,9 +282,6 @@ int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t * p15card, LOG_FUNC_CALLED(ctx); #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) - /* if no check flag execute unconditionally */ - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - LOG_FUNC_RETURN(ctx, sc_pkcs15emu_dnie_init(p15card)); /* check for proper card */ r = dnie_match_card(p15card->card); if (r == 0) diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 2124a50543..43e6d757ae 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -84,12 +84,7 @@ int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *p15card, { SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_entersafe_init(p15card); - else { - int r = entersafe_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_entersafe_init(p15card); - } + if (entersafe_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_entersafe_init(p15card); } diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 88034648b1..7d9d328b7b 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -215,8 +215,6 @@ int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_esteid_init(p15card); if (p15card->card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) return sc_pkcs15emu_esteid_init(p15card); return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index dca5b61205..b865a2ff82 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -517,12 +517,7 @@ int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *ai sc_log(ctx, "Entering %s", __FUNCTION__); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_gemsafeGPK_init(p15card); - else { - int r = gemsafe_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_gemsafeGPK_init(p15card); - } + if (gemsafe_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_gemsafeGPK_init(p15card); } diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 33c4f5d0c0..f111ffdf33 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -441,14 +441,9 @@ int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_gemsafeV1_init(p15card); - else { - int r = gemsafe_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_gemsafeV1_init(p15card); - } + if (gemsafe_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_gemsafeV1_init(p15card); } static sc_pkcs15_df_t * diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index d0fb9fda62..e0f5565619 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -233,14 +233,10 @@ int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { - return sc_pkcs15emu_gids_init(p15card); - } else { - if (p15card->card->type != SC_CARD_TYPE_GIDS_GENERIC && p15card->card->type != SC_CARD_TYPE_GIDS_V1 && p15card->card->type != SC_CARD_TYPE_GIDS_V2) { - return SC_ERROR_WRONG_CARD; - } - return sc_pkcs15emu_gids_init(p15card); + if (p15card->card->type != SC_CARD_TYPE_GIDS_GENERIC && p15card->card->type != SC_CARD_TYPE_GIDS_V1 && p15card->card->type != SC_CARD_TYPE_GIDS_V2) { + return SC_ERROR_WRONG_CARD; } + return sc_pkcs15emu_gids_init(p15card); } #else diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index e5b9c824b4..c617badcca 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -204,9 +204,6 @@ sc_pkcs15emu_iasecc_init (struct sc_pkcs15_card *p15card, struct sc_aid *aid) int sc_pkcs15emu_iasecc_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid, struct sc_pkcs15emu_opt *opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_iasecc_init(p15card, aid); - if (iasecc_pkcs15emu_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 911762640c..09f88f9967 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -869,14 +869,12 @@ int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, SC_FUNC_CALLED(card->ctx, 1); /* Check card */ - if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { - if (! ( - (card->type > SC_CARD_TYPE_ITACNS_BASE && - card->type < SC_CARD_TYPE_ITACNS_BASE + 1000) - || card->type == SC_CARD_TYPE_CARDOS_CIE_V1) - ) - return SC_ERROR_WRONG_CARD; - } + if (! ( + (card->type > SC_CARD_TYPE_ITACNS_BASE && + card->type < SC_CARD_TYPE_ITACNS_BASE + 1000) + || card->type == SC_CARD_TYPE_CARDOS_CIE_V1) + ) + return SC_ERROR_WRONG_CARD; /* Init card */ return itacns_init(p15card); diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 1c31bea97e..44101494a1 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -226,13 +226,7 @@ int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t * p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t * opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) { - return sc_pkcs15emu_jpki_init(p15card); - } - else { - if (p15card->card->type != SC_CARD_TYPE_JPKI_BASE) - return SC_ERROR_WRONG_CARD; - - return sc_pkcs15emu_jpki_init(p15card); - } + if (p15card->card->type != SC_CARD_TYPE_JPKI_BASE) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_jpki_init(p15card); } diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index d744d8074d..917579ef6d 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -1055,14 +1055,9 @@ sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card, struct sc_aid *ai int rv; LOG_FUNC_CALLED(p15card->card->ctx); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) { + rv = oberthur_detect_card(p15card); + if (!rv) rv = sc_pkcs15emu_oberthur_init(p15card); - } - else { - rv = oberthur_detect_card(p15card); - if (!rv) - rv = sc_pkcs15emu_oberthur_init(p15card); - } LOG_FUNC_RETURN(p15card->card->ctx, rv); } diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 87d36bf1a1..87286eeac6 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -465,12 +465,7 @@ static int openpgp_detect_card(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_openpgp_init(p15card); - else { - int r = openpgp_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_openpgp_init(p15card); - } + if (openpgp_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_openpgp_init(p15card); } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 858f914f20..593112bf1f 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -1212,12 +1212,7 @@ int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_piv_init(p15card); - else { - int r = piv_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_piv_init(p15card); - } + if (piv_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_piv_init(p15card); } diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index d1b8f3bf4f..2de06c5284 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -346,9 +346,6 @@ int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc sc_context_t *ctx = p15card->card->ctx; LOG_FUNC_CALLED(ctx); - /* if no check flag execute unconditionally */ - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - LOG_FUNC_RETURN(ctx, sc_pkcs15emu_pteid_init(p15card)); /* check for proper card */ r = pteid_detect_card(p15card->card); if (r == SC_ERROR_WRONG_CARD) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 044502d2b6..bb3335f3dc 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1034,14 +1034,10 @@ int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { - return sc_pkcs15emu_sc_hsm_init(p15card); - } else { - if (p15card->card->type != SC_CARD_TYPE_SC_HSM - && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC - && p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) { - return SC_ERROR_WRONG_CARD; - } - return sc_pkcs15emu_sc_hsm_init(p15card); + if (p15card->card->type != SC_CARD_TYPE_SC_HSM + && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC + && p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) { + return SC_ERROR_WRONG_CARD; } + return sc_pkcs15emu_sc_hsm_init(p15card); } diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 2bd44958af..f6fe79f771 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -276,13 +276,7 @@ int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) { - - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_starcert_init(p15card); - else { - int r = starcert_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_starcert_init(p15card); - } + if (starcert_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_starcert_init(p15card); } diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 04d1fe85fd..b128b14e85 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -499,11 +499,10 @@ int sc_pkcs15emu_tcos_init_ex( sc_context_t *ctx = p15card->card->ctx; sc_serial_number_t serialnr; char serial[30]; - int i, r; + int r; /* check if we have the correct card OS unless SC_PKCS15EMU_FLAGS_NO_CHECK */ - i=(opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)); - if (!i && card->type!=SC_CARD_TYPE_TCOS_V2 && card->type!=SC_CARD_TYPE_TCOS_V3) return SC_ERROR_WRONG_CARD; + if (card->type!=SC_CARD_TYPE_TCOS_V2 && card->type!=SC_CARD_TYPE_TCOS_V3) return SC_ERROR_WRONG_CARD; /* get the card serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 389a01a181..1f21a1bd77 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -253,8 +253,6 @@ int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t * p15card, sc_context_t *ctx = card->ctx; sc_log(ctx, "sc_pkcs15_init_func_ex westcos\n"); - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_westcos_init(p15card); r = westcos_detect_card(p15card); if (r) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 60af524b36..53ef628a9e 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -1009,8 +1009,6 @@ typedef struct sc_pkcs15emu_opt { unsigned int flags; } sc_pkcs15emu_opt_t; -#define SC_PKCS15EMU_FLAGS_NO_CHECK 0x00000001 - extern int sc_pkcs15_bind_synthetic(struct sc_pkcs15_card *, struct sc_aid *); extern int sc_pkcs15_is_emulation_only(sc_card_t *); From 1a656f2abe27c1ea6e8d9a96179ac5e07f379b2c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 15:25:02 +0200 Subject: [PATCH 0878/4321] use OpenPACE 1.1.0 --- MacOSX/build-package.in | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index c3ee291707..a0888b945e 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -45,7 +45,7 @@ fi if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then if ! test -e openpace; then - git clone --depth=1 https://github.com/frankmorgner/openpace.git + git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.0 fi cd openpace autoreconf -vis diff --git a/appveyor.yml b/appveyor.yml index 2c49e91f2a..58fc4cd497 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,7 +23,7 @@ install: throw "There are newer queued builds for this pull request, failing early." } - date /T & time /T - set PATH=C:\cygwin\bin;%PATH% - - set OPENPACE_VER=1.0.3 + - set OPENPACE_VER=1.1.0 - set ZLIB_VER_DOT=1.2.11 - ps: $env:PACKAGE_NAME=(git describe --tags --abbrev=0) - ps: >- From 8382f243b24f4a420d32335fcfd5bcb871da78f3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 15:35:09 +0200 Subject: [PATCH 0879/4321] fixed 337891 Out-of-bounds write --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8ec9abb27b..8e70620821 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2959,7 +2959,7 @@ static int write_object(CK_SESSION_HANDLE session) int certdata_len = 0; FILE *f; CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, seckey_obj, data_obj; - CK_ATTRIBUTE cert_templ[20], privkey_templ[20], pubkey_templ[20], seckey_templ[20], data_templ[20]; + CK_ATTRIBUTE cert_templ[20], privkey_templ[30], pubkey_templ[20], seckey_templ[20], data_templ[20]; int n_cert_attr = 0, n_privkey_attr = 0, n_pubkey_attr = 0, n_seckey_attr = 0, n_data_attr = 0; struct sc_object_id oid; CK_RV rv; From 7df789ec5dc3ec13034f30dbca767af74f731f05 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 15:40:03 +0200 Subject: [PATCH 0880/4321] fixed 337490 Unchecked return value --- src/libopensc/pkcs15-actalis.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 754f1de09f..9119872727 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -220,7 +220,8 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); - sc_read_binary(card, 2, size, 2, 0); + if (SC_SUCCESS != sc_read_binary(card, 2, size, 2, 0)) + continue; compLen = (size[0] << 8) + size[1]; compCert = malloc(compLen * sizeof(unsigned char)); len = 3 * compLen; /*Approximation of the uncompressed size */ @@ -231,12 +232,11 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) return SC_ERROR_OUT_OF_MEMORY; } - sc_read_binary(card, 4, compCert, compLen, 0); - - if (uncompress(cert, &len, compCert, compLen) != Z_OK) { + if (sc_read_binary(card, 4, compCert, compLen, 0) != SC_SUCCESS + || uncompress(cert, &len, compCert, compLen) != Z_OK) { free(cert); free(compCert); - return SC_ERROR_INTERNAL; + continue; } cpath.index = 0; cpath.count = len; From c671083ee3895ccab0c1e7bc31ba9fbf80e6af51 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 16:45:36 +0200 Subject: [PATCH 0881/4321] fixed missing file --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index fb97c57afb..5ee5edfb29 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -25,7 +25,7 @@ EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.i noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ - opensc-asn1-cmdline.h opensc-notify-cmdline.h + opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ From 7449b007688ccce16eb8265cd82a69a945fd38f5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Apr 2019 23:51:37 +0200 Subject: [PATCH 0882/4321] pkcs11: avoid double initialization of notify --- src/pkcs11/pkcs11-global.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 5353d778f1..c3cf259131 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -288,10 +288,6 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) return CKR_CRYPTOKI_ALREADY_INITIALIZED; } -#if !defined(_WIN32) - sc_notify_init(); -#endif - rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pInitArgs); if (rv != CKR_OK) goto out; From 5123531e62b92550f65000722c5a58d88880f2bc Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 23 Apr 2019 15:29:22 +0300 Subject: [PATCH 0883/4321] Fix EstEID 3.4 signing opensc master requires now SC_ALGORITHM_RSA_HASH_NONE Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 73 +++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 24efdd5464..006f692029 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -82,14 +82,14 @@ enum { struct rule_record_s { struct rule_record_s *next; - int recno; + unsigned int recno; size_t datalen; u8 data[1]; }; struct keyd_record_s { struct keyd_record_s *next; - int recno; + unsigned int recno; size_t datalen; u8 data[1]; }; @@ -307,58 +307,46 @@ static int mcrd_match_card(sc_card_t * card) LOG_FUNC_CALLED(card->ctx); r = gp_select_aid(card, &EstEID_v35_AID); if (r >= 0) { - sc_log(card->ctx, "AID found"); - card->type = SC_CARD_TYPE_MCRD_ESTEID_V30; - return 1; + sc_log(card->ctx, "AID found"); + card->type = SC_CARD_TYPE_MCRD_ESTEID_V30; + return 1; } return 0; } static int mcrd_init(sc_card_t * card) { - unsigned long flags, ext_flags; - struct mcrd_priv_data *priv; - int r; - - priv = calloc(1, sizeof *priv); + unsigned long flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, ext_flags; + struct mcrd_priv_data *priv = calloc(1, sizeof *priv); if (!priv) return SC_ERROR_OUT_OF_MEMORY; card->drv_data = priv; card->cla = 0x00; card->caps = SC_CARD_CAP_RNG; - - if (is_esteid_card(card)) { - /* Select the EstEID AID to get to a known state. - * For some reason a reset is required as well... */ - sc_reset(card, 0); - - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; - if ((r = gp_select_aid(card, &EstEID_v3_AID)) >= 0) { - /* EstEID v3.0 has 2048 bit keys */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - } else if ((r = gp_select_aid(card, &EstEID_v35_AID)) >= 0) { - /* EstEID v3.5 has 2048 bit keys or EC 384 */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); - flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); - // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary - // sc_read_binary cannot handle recursive 61 00 calls - if (card->reader && card->reader->active_protocol == SC_PROTO_T0) - card->max_recv_size = 255; - } else if ((r = gp_select_aid(card, &AzeDIT_v35_AID)) >= 0) { - _sc_card_add_rsa_alg(card, 2048, flags, 0); - } else { - free(card->drv_data); - card->drv_data = NULL; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); - } - } else { - flags = SC_ALGORITHM_RSA_RAW |SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; + if (!is_esteid_card(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); + } else if (gp_select_aid(card, &EstEID_v3_AID) >= 0) { + /* EstEID v3.0 has 2048 bit keys */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else if (gp_select_aid(card, &EstEID_v35_AID) >= 0) { + /* EstEID v3.5 has 2048 bit keys or EC 384 */ + _sc_card_add_rsa_alg(card, 2048, flags, 0); + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary + // sc_read_binary cannot handle recursive 61 00 calls + if (card->reader && card->reader->active_protocol == SC_PROTO_T0) + card->max_recv_size = 255; + } else if (gp_select_aid(card, &AzeDIT_v35_AID) >= 0) { + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else { + free(card->drv_data); + card->drv_data = NULL; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_CARD); } priv->curpath[0] = MFID; @@ -394,7 +382,8 @@ static int mcrd_finish(sc_card_t * card) static int load_special_files(sc_card_t * card) { sc_context_t *ctx = card->ctx; - int r, recno; + int r; + unsigned int recno; struct df_info_s *dfi; struct rule_record_s *rule; struct keyd_record_s *keyd; @@ -759,7 +748,7 @@ do_select(sc_card_t * card, u8 kind, if (!*file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); if (apdu.resp[1] <= apdu.resplen) - process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); + process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } return SC_SUCCESS; @@ -1231,7 +1220,7 @@ static int mcrd_set_security_env(sc_card_t * card, sc_unlock(card); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); - err: +err: if (locked) sc_unlock(card); return r; From 86ba3ea489720ee250dfa80a0999e95ed6b88acf Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 16:05:58 +0200 Subject: [PATCH 0884/4321] fixed Wrong type of arguments to formatting function --- src/tools/gids-tool.c | 2 +- src/tools/pkcs11-tool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 63380e9a71..53203f22bc 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -419,7 +419,7 @@ static int print_info(sc_card_t *card) { } for (i = 0; i < cmaprecordnum; i++) { printf(" container: %d\n", i); - wprintf(L" guid: %s\n", cmaprecords[i].wszGuid); + wprintf(L" guid: %ls\n", cmaprecords[i].wszGuid); printf(" bFlags: "); if (cmaprecords[i].bFlags & CONTAINER_MAP_VALID_CONTAINER) { printf("Valid container"); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8e70620821..5f7b6315ea 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3310,7 +3310,7 @@ static int write_object(CK_SESSION_HANDLE session) else if (strncasecmp(opt_key_type, "DES3:", strlen("DES3:")) == 0) type = CKK_DES3; else - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key type: 0x%X", type); } FILL_ATTR(seckey_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); From 0bc95cb6a10713ad43e3706ceeb1e9e208e1ec50 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 16:18:33 +0200 Subject: [PATCH 0885/4321] added include guards --- src/common/libpkcs11.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/libpkcs11.h b/src/common/libpkcs11.h index c44767b94e..f7cbc95d95 100644 --- a/src/common/libpkcs11.h +++ b/src/common/libpkcs11.h @@ -18,5 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __LIBPKCS11_H +#define __LIBPKCS11_H void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); CK_RV C_UnloadModule(void *module); +#endif From f0a6a568f4aad5529bca0cfdf580744fb46f423f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Apr 2019 16:23:53 +0200 Subject: [PATCH 0886/4321] fixed Local variable hides global variable --- src/tools/openpgp-tool.c | 10 +++++----- src/tools/opensc-tool.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index dcff9f8c04..c48d87e75a 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -98,7 +98,7 @@ static int opt_keyinfo = 0; static char *exec_program = NULL; static int opt_genkey = 0; static u8 key_id = 0; -static char *keytype = NULL; +static char *opt_keytype = NULL; static int opt_verify = 0; static char *verifytype = NULL; static int opt_pin = 0; @@ -506,9 +506,9 @@ static int decode_options(int argc, char **argv) actions++; break; case 't': - if (keytype) - free(keytype); - keytype = strdup(optarg); + if (opt_keytype) + free(opt_keytype); + opt_keytype = strdup(optarg); break; case 'h': util_print_usage_and_die(app_name, options, option_help, NULL); @@ -922,7 +922,7 @@ int main(int argc, char **argv) } if (opt_genkey) - exit_status |= do_genkey(card, key_id, keytype); + exit_status |= do_genkey(card, key_id, opt_keytype); if (exec_program) { char *const largv[] = {exec_program, NULL}; diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 4b309e1450..b5f5780104 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -280,7 +280,7 @@ static int list_readers(void) reader->capabilities & SC_READER_CAP_PIN_PAD ? "PIN pad":"", reader->name); if (state & SC_READER_CARD_PRESENT && verbose) { - struct sc_card *card; + struct sc_card *c; int r; char tmp[SC_MAX_ATR_SIZE*3]; sc_bin_to_hex(reader->atr.value, reader->atr.len, tmp, sizeof(tmp) - 1, ':'); @@ -288,11 +288,11 @@ static int list_readers(void) if (state & SC_READER_CARD_EXCLUSIVE) printf(" %s [EXCLUSIVE]\n", tmp); else { - if ((r = sc_connect_card(reader, &card)) != SC_SUCCESS) { + if ((r = sc_connect_card(reader, &c)) != SC_SUCCESS) { fprintf(stderr, " failed: %s\n", sc_strerror(r)); } else { - printf(" %s %s %s\n", tmp, card->name ? card->name : "", state & SC_READER_CARD_INUSE ? "[IN USE]" : ""); - sc_disconnect_card(card); + printf(" %s %s %s\n", tmp, c->name ? c->name : "", state & SC_READER_CARD_INUSE ? "[IN USE]" : ""); + sc_disconnect_card(c); } } } From 63fd71c24588cd542ab6457375eb00877fbf2bfb Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 26 Mar 2019 16:14:25 +0200 Subject: [PATCH 0887/4321] Remove unused sc_pkcs15emu_opt_t structure Only usage was removed SC_PKCS15EMU_FLAGS_NO_CHECK flag Signed-off-by: Raul Metsma --- src/libopensc/pkcs15-actalis.c | 5 +--- src/libopensc/pkcs15-atrust-acos.c | 5 +--- src/libopensc/pkcs15-cac.c | 5 +--- src/libopensc/pkcs15-coolkey.c | 5 +--- src/libopensc/pkcs15-din-66291.c | 7 ++--- src/libopensc/pkcs15-dnie.c | 3 +- src/libopensc/pkcs15-esinit.c | 5 +--- src/libopensc/pkcs15-esteid.c | 4 +-- src/libopensc/pkcs15-gemsafeGPK.c | 5 +--- src/libopensc/pkcs15-gemsafeV1.c | 5 +--- src/libopensc/pkcs15-gids.c | 6 ++-- src/libopensc/pkcs15-iasecc.c | 2 +- src/libopensc/pkcs15-itacns.c | 5 +--- src/libopensc/pkcs15-jpki.c | 5 +--- src/libopensc/pkcs15-oberthur.c | 5 +--- src/libopensc/pkcs15-openpgp.c | 4 +-- src/libopensc/pkcs15-piv.c | 4 +-- src/libopensc/pkcs15-pteid.c | 3 +- src/libopensc/pkcs15-sc-hsm.c | 3 +- src/libopensc/pkcs15-starcert.c | 5 +--- src/libopensc/pkcs15-syn.c | 18 ++++------- src/libopensc/pkcs15-syn.h | 48 +++++++++++++++--------------- src/libopensc/pkcs15-tccardos.c | 7 +---- src/libopensc/pkcs15-tcos.c | 8 +---- src/libopensc/pkcs15-westcos.c | 5 +--- src/libopensc/pkcs15.h | 6 ---- 26 files changed, 56 insertions(+), 127 deletions(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 9119872727..e13f19a197 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -37,8 +37,6 @@ #include "libopensc/pkcs15.h" #include "libopensc/log.h" -int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int); static int set_sec_env(sc_card_t * card, const sc_security_env_t *env, @@ -317,8 +315,7 @@ static int actalis_detect_card(sc_pkcs15_card_t * p15card) } int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t * opts) + struct sc_aid *aid) { if (actalis_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index 5d8baccfee..ff4c5f9152 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -34,8 +34,6 @@ #define MANU_ID "A-Trust" #define CARD_LABEL "a.sign Premium a" -int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid, sc_pkcs15emu_opt_t *); - typedef struct cdata_st { const char *label; int authority; @@ -266,8 +264,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { if (acos_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 11271b8b3e..8c68c86696 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -45,9 +45,6 @@ /* probably should get manufacturer ID from cuid */ #define MANU_ID "Common Access Card" -int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - - typedef struct pdata_st { const char *id; @@ -443,7 +440,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 3ffb053c37..39529e3f9a 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -41,9 +41,6 @@ #include "pkcs15.h" #include "../pkcs11/pkcs11.h" -int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - - typedef struct pdata_st { const char *id; const char *label; @@ -716,7 +713,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index ae1de0ecca..241afb8a11 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -258,8 +258,7 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) return SC_SUCCESS; } -int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { if (!p15card || ! p15card->card) return SC_ERROR_INVALID_ARGUMENTS; @@ -267,8 +266,8 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid SC_FUNC_CALLED(p15card->card->ctx, 1); /* Check card */ - if (!din_66291_match_p15card(p15card, aid)) - return SC_ERROR_WRONG_CARD; + if (!din_66291_match_p15card(p15card, aid)) + return SC_ERROR_WRONG_CARD; /* Init card */ return sc_pkcs15emu_din_66291_init(p15card); diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index a9e97ac076..f4b144e4c8 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -274,8 +274,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) /* public functions for in-built module */ /****************************************/ int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t * opts) + struct sc_aid *aid) { int r=SC_SUCCESS; sc_context_t *ctx = p15card->card->ctx; diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 43e6d757ae..60c2e67799 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -29,8 +29,6 @@ #define MANU_ID "entersafe" -int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static int entersafe_detect_card( sc_pkcs15_card_t *p15card) { sc_card_t *card = p15card->card; @@ -79,8 +77,7 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 7d9d328b7b..5688cfb034 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -211,9 +211,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) return SC_SUCCESS; } -int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { if (p15card->card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) return sc_pkcs15emu_esteid_init(p15card); diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index b865a2ff82..c8d35dad88 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -35,8 +35,6 @@ #define MANU_ID "GemSAFE on GPK16000" -int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static int (*pin_cmd_save)(struct sc_card *, struct sc_pin_cmd_data *, int *tries_left); @@ -509,8 +507,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) return SC_SUCCESS; } -int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index f111ffdf33..6ced63aa7e 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -40,8 +40,6 @@ #define GEMSAFE_READ_QUANTUM 248 #define GEMSAFE_MAX_OBJLEN 28672 -int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *, struct sc_aid *,sc_pkcs15emu_opt_t *); - static int sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card, int type, int authority, @@ -438,8 +436,7 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { if (gemsafe_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index e0f5565619..68e93ca87a 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -230,8 +230,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) } int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { if (p15card->card->type != SC_CARD_TYPE_GIDS_GENERIC && p15card->card->type != SC_CARD_TYPE_GIDS_V1 && p15card->card->type != SC_CARD_TYPE_GIDS_V2) { return SC_ERROR_WRONG_CARD; @@ -242,8 +241,7 @@ int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card, #else int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { return SC_ERROR_WRONG_CARD; } diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index c617badcca..a0a9176924 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -202,7 +202,7 @@ sc_pkcs15emu_iasecc_init (struct sc_pkcs15_card *p15card, struct sc_aid *aid) int -sc_pkcs15emu_iasecc_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid, struct sc_pkcs15emu_opt *opts) +sc_pkcs15emu_iasecc_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) { if (iasecc_pkcs15emu_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 09f88f9967..57d8672df8 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -52,8 +52,6 @@ #include #endif -int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static const char path_serial[] = "10001003"; /* Manufacturers */ @@ -862,8 +860,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) return r; } -int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { sc_card_t *card = p15card->card; SC_FUNC_CALLED(card->ctx, 1); diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 44101494a1..7c420d71c7 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -33,9 +33,6 @@ #include "pkcs15.h" #include "jpki.h" -int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *, - sc_pkcs15emu_opt_t *); - static int sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) { @@ -224,7 +221,7 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, sc_pkcs15emu_opt_t * opts) + struct sc_aid *aid) { if (p15card->card->type != SC_CARD_TYPE_JPKI_BASE) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 917579ef6d..17720e7540 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -92,8 +92,6 @@ static int sc_pkcs15emu_oberthur_add_pubkey(struct sc_pkcs15_card *, unsigned, u static int sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *, unsigned); static int sc_pkcs15emu_oberthur_add_data(struct sc_pkcs15_card *, unsigned, unsigned, int); -int sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card *, struct sc_aid *, struct sc_pkcs15emu_opt *); - static int sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *, unsigned char *, size_t, int); static int sc_oberthur_parse_containers (struct sc_pkcs15_card *, unsigned char *, size_t, int); static int sc_oberthur_parse_publicinfo (struct sc_pkcs15_card *, unsigned char *, size_t, int); @@ -1049,8 +1047,7 @@ oberthur_detect_card(struct sc_pkcs15_card * p15card) int -sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card, struct sc_aid *aid, - struct sc_pkcs15emu_opt * opts) +sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card, struct sc_aid *aid) { int rv; diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 87286eeac6..c506809eba 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -33,7 +33,6 @@ #include "pkcs15.h" #include "log.h" -int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *); @@ -462,8 +461,7 @@ static int openpgp_detect_card(sc_pkcs15_card_t *p15card) return SC_ERROR_WRONG_CARD; } -int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { if (openpgp_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 593112bf1f..be29f5031c 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -40,8 +40,6 @@ #define MANU_ID "piv_II " -int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid, sc_pkcs15emu_opt_t *); - typedef struct objdata_st { const char *id; const char *label; @@ -1205,7 +1203,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); } int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index 2de06c5284..483fc40212 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -49,7 +49,6 @@ #include "pkcs15.h" static int pteid_detect_card(struct sc_card *card); -int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); static int dump_ef(sc_card_t * card, const char *path, u8 * buf, size_t * buf_len) @@ -340,7 +339,7 @@ static int pteid_detect_card(struct sc_card *card) return SC_ERROR_WRONG_CARD; } -int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts) +int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { int r=SC_SUCCESS; sc_context_t *ctx = p15card->card->ctx; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index bb3335f3dc..d1f6a77581 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1031,8 +1031,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { if (p15card->card->type != SC_CARD_TYPE_SC_HSM && p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index f6fe79f771..804e85611f 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -33,8 +33,6 @@ #define MANU_ID "Giesecke & Devrient GmbH" #define STARCERT "StarCertV2201" -int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *,sc_pkcs15emu_opt_t *); - typedef struct cdata_st { const char *label; int authority; @@ -273,8 +271,7 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { if (starcert_detect_card(p15card)) return SC_ERROR_WRONG_CARD; diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 3f15eeb711..8ecc345664 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -103,11 +103,9 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { sc_context_t *ctx = p15card->card->ctx; scconf_block *conf_block, **blocks, *blk; - sc_pkcs15emu_opt_t opts; int i, r = SC_ERROR_WRONG_CARD; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - memset(&opts, 0, sizeof(opts)); conf_block = NULL; conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); @@ -117,7 +115,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) sc_log(ctx, "no conf file (or section), trying all builtin emulators"); for (i = 0; builtin_emulators[i].name; i++) { sc_log(ctx, "trying %s", builtin_emulators[i].name); - r = builtin_emulators[i].handler(p15card, aid, &opts); + r = builtin_emulators[i].handler(p15card, aid); if (r == SC_SUCCESS) /* we got a hit */ goto out; @@ -139,7 +137,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) sc_log(ctx, "trying %s", name); for (i = 0; builtin_emulators[i].name; i++) if (!strcmp(builtin_emulators[i].name, name)) { - r = builtin_emulators[i].handler(p15card, aid, &opts); + r = builtin_emulators[i].handler(p15card, aid); if (r == SC_SUCCESS) /* we got a hit */ goto out; @@ -150,7 +148,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) sc_log(ctx, "no emulator list in config file, trying all builtin emulators"); for (i = 0; builtin_emulators[i].name; i++) { sc_log(ctx, "trying %s", builtin_emulators[i].name); - r = builtin_emulators[i].handler(p15card, aid, &opts); + r = builtin_emulators[i].handler(p15card, aid); if (r == SC_SUCCESS) /* we got a hit */ goto out; @@ -191,10 +189,9 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; - sc_pkcs15emu_opt_t opts; void *handle = NULL; int (*init_func)(sc_pkcs15_card_t *); - int (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); + int (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *); int r; const char *driver, *module_name; @@ -203,9 +200,6 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf init_func = NULL; init_func_ex = NULL; - memset(&opts, 0, sizeof(opts)); - opts.blk = conf; - module_name = scconf_get_str(conf, "module", builtin_name); if (!strcmp(module_name, "builtin")) { int i; @@ -260,12 +254,12 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf address = sc_dlsym(handle, name); if (address) - init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *)) address; + init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address; } } /* try to initialize the pkcs15 structures */ if (init_func_ex) - r = init_func_ex(p15card, aid, &opts); + r = init_func_ex(p15card, aid); else if (init_func) r = init_func(p15card); else diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index 9944d27e05..a141f79fe3 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -29,33 +29,33 @@ extern "C" { #include #include -int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); -int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); -int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts); +int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; - int (*handler)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); + int (*handler)(sc_pkcs15_card_t *, struct sc_aid *); }; #ifdef __cplusplus diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index 70d83ed861..d6d1490c95 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -41,10 +41,6 @@ #define TC_CARDOS_GLOBALPIN 0x3000 #define TC_CARDOS_PIN_MASK 0x3000 -int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *, - sc_pkcs15emu_opt_t *opts); - static int read_file(struct sc_card *card, const char *file, u8 *buf, size_t *len) { @@ -350,8 +346,7 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) } int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts) + struct sc_aid *aid) { return sc_pkcs15_tccardos_init_func(p15card); } diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index b128b14e85..1d680f1c67 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -33,11 +33,6 @@ #include "cardctl.h" #include "log.h" -int sc_pkcs15emu_tcos_init_ex( - sc_pkcs15_card_t *p15card, - struct sc_aid *, - sc_pkcs15emu_opt_t *opts); - static int insert_cert( sc_pkcs15_card_t *p15card, const char *path, @@ -492,8 +487,7 @@ static int detect_unicard( int sc_pkcs15emu_tcos_init_ex( sc_pkcs15_card_t *p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t *opts + struct sc_aid *aid ){ sc_card_t *card = p15card->card; sc_context_t *ctx = p15card->card->ctx; diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 1f21a1bd77..6b83bcf3b7 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -31,8 +31,6 @@ #include "cardctl.h" #include "common/compat_strlcpy.h" -int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *); - static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) { int i, r; @@ -245,8 +243,7 @@ static int westcos_detect_card(sc_pkcs15_card_t * p15card) } int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t * p15card, - struct sc_aid *aid, - sc_pkcs15emu_opt_t * opts) + struct sc_aid *aid) { int r; sc_card_t *card = p15card->card; diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 53ef628a9e..4e6a29f7cf 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -1003,12 +1003,6 @@ typedef struct sc_pkcs15_search_key { int sc_pkcs15_search_objects(struct sc_pkcs15_card *, sc_pkcs15_search_key_t *, struct sc_pkcs15_object **, size_t); -/* This structure is passed to the new sc_pkcs15emu_*_init functions */ -typedef struct sc_pkcs15emu_opt { - scconf_block *blk; - unsigned int flags; -} sc_pkcs15emu_opt_t; - extern int sc_pkcs15_bind_synthetic(struct sc_pkcs15_card *, struct sc_aid *); extern int sc_pkcs15_is_emulation_only(sc_card_t *); From 9ca836975ae5d6dd4d3bad9582011d6b415dcfc3 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 27 Apr 2019 17:18:26 +0200 Subject: [PATCH 0888/4321] Starcos: added another ATR for 2nd gen. eGK (TK) --- src/libopensc/card-starcos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 6218ad553a..c022b04d14 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -43,6 +43,7 @@ static const struct sc_atr_table starcos_atrs[] = { { "3B:DF:96:FF:81:31:FE:45:80:5B:44:45:2E:42:4E:4F:54:4B:31:31:31:81:05:A0", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:DF:96:FF:81:31:FE:45:80:5B:44:45:2E:42:4E:4F:54:4B:31:30:30:81:05:A0", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:E0:81:05:22", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3B:D0:97:FF:81:B1:FE:45:1F:07:2B", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; From 209be729791e6773950f628808fc07b2b8e6b1ff Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 27 Apr 2019 17:22:34 +0200 Subject: [PATCH 0889/4321] eGK: fix path for vd/gvd path was wrong, the same as for pd --- src/tools/egk-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index f20de094cd..15992968dd 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -197,7 +197,7 @@ main (int argc, char **argv) } if ((cmdline.vd_flag || cmdline.gvd_flag) - && read_file(card, "D001", &data, &data_len) + && read_file(card, "D002", &data, &data_len) && data_len >= 8) { size_t off_vd = (data[0] << 8) | data[1]; size_t end_vd = (data[2] << 8) | data[3]; From c3a9458fa818a1bcce8618eda877937795701fb8 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Tue, 30 Apr 2019 20:26:18 +0200 Subject: [PATCH 0890/4321] egk-tool: fix missed initialisation of card pointer If util_connect_card_ex() fails, sc_disconnect_card() will use a random pointer leading to segmentation faults. --- src/tools/egk-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index 15992968dd..b3a8365ec5 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -145,7 +145,7 @@ main (int argc, char **argv) struct gengetopt_args_info cmdline; struct sc_path path; struct sc_context *ctx; - struct sc_card *card; + struct sc_card *card = NULL; unsigned char *data = NULL; size_t data_len = 0; int r; From b3d4a0d69a8f56c417e6ee141b57d358f7f58163 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Thu, 7 Mar 2019 20:47:50 +0200 Subject: [PATCH 0891/4321] EstEID 2018+ driver This adds support for a minimalistic, small and fast card profile based on IAS-ECC. Based on information from https://installer.id.ee/media/id2019/TD-ID1-Chip-App.pdf and proprietary driver snoops. Thanks to @metsma and @frankmorgner. Change-Id: I2e4b4914d8a3b991d9a639728695abf4a2362ca0 --- src/libopensc/Makefile.am | 4 +- src/libopensc/card-esteid2018.c | 347 ++++++++++++++++++++++++++++++ src/libopensc/cards.h | 5 + src/libopensc/ctx.c | 1 + src/libopensc/pkcs15-esteid2018.c | 223 +++++++++++++++++++ src/libopensc/pkcs15-syn.c | 2 + src/libopensc/pkcs15-syn.h | 1 + 7 files changed, 581 insertions(+), 2 deletions(-) create mode 100644 src/libopensc/card-esteid2018.c create mode 100644 src/libopensc/pkcs15-esteid2018.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index a6d7650393..7d33fcfa3e 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -48,7 +48,7 @@ libopensc_la_SOURCES_BASE = \ card-iasecc.c iasecc-sdo.c iasecc-sm.c card-sc-hsm.c \ card-dnie.c cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ - card-npa.c \ + card-npa.c card-esteid2018.c \ \ pkcs15-openpgp.c pkcs15-starcert.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-gemsafeGPK.c \ @@ -56,7 +56,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c \ - pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c \ + pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ compression.c p15card-helper.c sm.c \ aux-data.c diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c new file mode 100644 index 0000000000..ccb2d892e4 --- /dev/null +++ b/src/libopensc/card-esteid2018.c @@ -0,0 +1,347 @@ +/* + * Driver for EstEID card issued from December 2018. + * + * Copyright (C) 2019, Martin Paljak + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "asn1.h" +#include "gp.h" +#include "internal.h" + +/* Helping defines */ +#define SIGNATURE_PAYLOAD_SIZE 0x30 + +static const struct sc_atr_table esteid_atrs[] = { + {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL}}; + +static const struct sc_aid IASECC_AID = {{0xA0, 0x00, 0x00, 0x00, 0x77, 0x01, 0x08, 0x00, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0x00}, + 16}; + +static const struct sc_path adf2 = {{0x3f, 0x00, 0xAD, 0xF2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 0, 0, SC_PATH_TYPE_PATH, {{0}, 0}}; + +static const struct sc_card_operations *iso_ops = NULL; +static struct sc_card_operations esteid_ops; + +static struct sc_card_driver esteid2018_driver = {"EstEID 2018", "esteid2018", &esteid_ops, NULL, 0, NULL}; + +struct esteid_priv_data { + sc_security_env_t sec_env; /* current security environment */ +}; + +#define DRVDATA(card) ((struct esteid_priv_data *)((card)->drv_data)) + +static int esteid_match_card(sc_card_t *card) { + int i = 0; + int r = 0; + + i = _sc_match_atr(card, esteid_atrs, &card->type); + if (i >= 0) { + r = gp_select_aid(card, &IASECC_AID); + if (r == SC_SUCCESS) { + card->name = esteid_atrs[i].name; + return 1; + } + } + return 0; +} + +static int esteid_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) { + if (sw1 == 0x6B && sw2 == 0x00) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED); + return iso_ops->check_sw(card, sw1, sw2); +} + +static int esteid_select(struct sc_card *card, unsigned char p1, unsigned char id1, unsigned char id2) { + struct sc_apdu apdu; + unsigned char sbuf[2]; + + LOG_FUNC_CALLED(card->ctx); + + // Select EF/DF + sbuf[0] = id1; + sbuf[1] = id2; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, p1, 0x0C); + if (id1 != 0x3F && id2 != 0x00) { + apdu.cse = SC_APDU_CASE_3_SHORT; + apdu.lc = 2; + apdu.data = sbuf; + apdu.datalen = 2; + } + apdu.le = 0x00; + apdu.resplen = 0; + + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "SELECT failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int esteid_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) { + unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; + int pathlen; + struct sc_file *file = NULL; + + LOG_FUNC_CALLED(card->ctx); + + // Only support full paths + if (in_path->type != SC_PATH_TYPE_PATH) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + memcpy(path, in_path->value, in_path->len); + pathlen = in_path->len; + + while (pathlen >= 2) { + if (memcmp(path, "\x3F\x00", 2) == 0) { + LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "MF select failed"); + } else if (pathlen >= 2 && path[0] == 0xAD) { + LOG_TEST_RET(card->ctx, esteid_select(card, 0x01, path[0], path[1]), "DF select failed"); + } else if (pathlen == 2) { + LOG_TEST_RET(card->ctx, esteid_select(card, 0x02, path[0], path[1]), "EF select failed"); + + if (file_out != NULL) // Just make a dummy file + { + file = sc_file_new(); + if (file == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + file->path = *in_path; + + *file_out = file; + } + } + path += 2; + pathlen -= 2; + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +// temporary hack, overload 6B00 SW processing +static int esteid_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags) { + int r; + LOG_FUNC_CALLED(card->ctx); + void *saved = card->ops->check_sw; + card->ops->check_sw = esteid_check_sw; + r = iso_ops->read_binary(card, idx, buf, count, flags); + card->ops->check_sw = saved; + LOG_FUNC_RETURN(card->ctx, r); +} + +static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { + struct esteid_priv_data *priv; + struct sc_apdu apdu; + + const unsigned char cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, 0x81}; + const unsigned char cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, 0x9F}; + const unsigned char cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, 0x81}; + + LOG_FUNC_CALLED(card->ctx); + + if (card == NULL || env == NULL || env->key_ref_len != 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + sc_log(card->ctx, "algo: %d operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); + + if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 1) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xA4); + apdu.data = cse_crt_aut; + apdu.datalen = sizeof(cse_crt_aut); + apdu.lc = sizeof(cse_crt_aut); + } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 2) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); + apdu.data = cse_crt_sig; + apdu.datalen = sizeof(cse_crt_sig); + apdu.lc = sizeof(cse_crt_sig); + } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == 1) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); + apdu.data = cse_crt_dec; + apdu.datalen = sizeof(cse_crt_dec); + apdu.lc = sizeof(cse_crt_dec); + } else { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "SET SECURITY ENV failed"); + + priv = DRVDATA(card); + priv->sec_env = *env; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) { + struct esteid_priv_data *priv = DRVDATA(card); + struct sc_security_env *env = NULL; + struct sc_apdu apdu; + u8 sbuf[SIGNATURE_PAYLOAD_SIZE] = {0}; + + LOG_FUNC_CALLED(card->ctx); + if (data == NULL || out == NULL || datalen > SIGNATURE_PAYLOAD_SIZE) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + env = &priv->sec_env; + // left-pad if necessary + memcpy(&sbuf[SIGNATURE_PAYLOAD_SIZE - datalen], data, MIN(datalen, SIGNATURE_PAYLOAD_SIZE)); + memset(sbuf, 0x00, SIGNATURE_PAYLOAD_SIZE - datalen); + datalen = SIGNATURE_PAYLOAD_SIZE; + + switch (env->key_ref[0]) { + case 1: /* authentication key */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0, 0); + break; + default: + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); + } + apdu.lc = datalen; + apdu.data = sbuf; + apdu.datalen = datalen; + apdu.le = MIN(256, outlen); + apdu.resp = out; + apdu.resplen = outlen; + + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "PSO CDS/INTERNAL AUTHENTICATE failed"); + + LOG_FUNC_RETURN(card->ctx, apdu.resplen); +} + +static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { + unsigned char get_pin_info[] = {0x4D, 0x08, 0x70, 0x06, 0xBF, 0x81, 0xFF, 0x02, 0xA0, 0x80}; + + struct sc_apdu apdu; + unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; + LOG_FUNC_CALLED(card->ctx); + + // We don't get the file information here, so we need to be ugly + if (pin_reference == 1 || pin_reference == 2) { + LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "Cannot select MF"); + } else if (pin_reference == 0x85) { + LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); + } else { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF); + get_pin_info[6] = pin_reference & 0x0F; // mask out local/global + apdu.lc = sizeof(get_pin_info); + apdu.data = get_pin_info; + apdu.datalen = sizeof(get_pin_info); + apdu.resplen = sizeof(apdu_resp); + apdu.resp = apdu_resp; + apdu.le = 256; + + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "GET DATA(pin info) failed"); + + // XXX: sc_asn1_find_tag with the following payload (to get to tag 0x9B): + // https://lapo.it/asn1js/#cB6_gQEaoBiaAQObAQOhEIwG8wAAc0MAnAbzAABzQwA + return apdu_resp[13]; +} + +static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { + int r; + struct sc_pin_cmd_data tmp; + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "PIN CMD is %d", data->cmd); + if (data->cmd == SC_PIN_CMD_GET_INFO) { + sc_log(card->ctx, "SC_PIN_CMD_GET_INFO for %d", data->pin_reference); + r = esteid_get_pin_remaining_tries(card, data->pin_reference); + LOG_TEST_RET(card->ctx, r, "GET DATA(pin info) failed"); + + data->pin1.tries_left = r; + data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks + data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { + // Verify PUK, then issue UNBLOCK + // VERIFY + memcpy(&tmp, data, sizeof(struct sc_pin_cmd_data)); + tmp.cmd = SC_PIN_CMD_VERIFY; + tmp.pin_reference = 0x02; // hardcoded, ugly + tmp.pin2.len = 0; + r = iso_ops->pin_cmd(card, &tmp, tries_left); + sc_mem_clear(&tmp, sizeof(tmp)); + LOG_TEST_RET(card->ctx, r, "VERIFY during unblock failed"); + + if (data->pin_reference == 0x85) { + LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); + } + // UNBLOCK + memcpy(&tmp, data, sizeof(struct sc_pin_cmd_data)); + tmp.cmd = SC_PIN_CMD_UNBLOCK; + tmp.pin1.len = 0; + r = iso_ops->pin_cmd(card, &tmp, tries_left); + sc_mem_clear(&tmp, sizeof(tmp)); + LOG_FUNC_RETURN(card->ctx, r); + } + + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); +} + +static int esteid_init(sc_card_t *card) { + unsigned long flags, ext_flags; + struct esteid_priv_data *priv; + + priv = calloc(1, sizeof *priv); + if (!priv) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + card->drv_data = priv; + card->max_recv_size = 233; // XXX: empirical, not documented + + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int esteid_finish(sc_card_t *card) { + if (card != NULL) + free(DRVDATA(card)); + return 0; +} + +struct sc_card_driver *sc_get_esteid2018_driver(void) { + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + + if (iso_ops == NULL) + iso_ops = iso_drv->ops; + + esteid_ops = *iso_drv->ops; + esteid_ops.match_card = esteid_match_card; + esteid_ops.init = esteid_init; + esteid_ops.finish = esteid_finish; + + esteid_ops.select_file = esteid_select_file; + esteid_ops.read_binary = esteid_read_binary; + + esteid_ops.set_security_env = esteid_set_security_env; + esteid_ops.compute_signature = esteid_compute_signature; + esteid_ops.pin_cmd = esteid_pin_cmd; + + return &esteid2018_driver; +} \ No newline at end of file diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index dd78e7e298..5b4ee05fa8 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -247,6 +247,10 @@ enum { SC_CARD_TYPE_NPA = 34000, SC_CARD_TYPE_NPA_TEST, SC_CARD_TYPE_NPA_ONLINE, + + /* EstEID cards */ + SC_CARD_TYPE_ESTEID = 35000, + SC_CARD_TYPE_ESTEID_2018, }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -289,6 +293,7 @@ extern sc_card_driver_t *sc_get_coolkey_driver(void); extern sc_card_driver_t *sc_get_cac_driver(void); extern sc_card_driver_t *sc_get_cac1_driver(void); extern sc_card_driver_t *sc_get_npa_driver(void); +extern sc_card_driver_t *sc_get_esteid2018_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 84df68ff7c..e5d8b9e691 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -126,6 +126,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "masktech", (void *(*)(void)) sc_get_masktech_driver }, { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, { "westcos", (void *(*)(void)) sc_get_westcos_driver }, + { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver }, /* Here should be placed drivers that need some APDU transactions in the * driver's `match_card()` function. */ diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c new file mode 100644 index 0000000000..243e231817 --- /dev/null +++ b/src/libopensc/pkcs15-esteid2018.c @@ -0,0 +1,223 @@ +/* + * PKCS15 emulation layer for EstEID card issued from December 2018. + * + * Copyright (C) 2019, Martin Paljak + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "common/compat_strlcpy.h" + +#include "internal.h" +#include "opensc.h" +#include "pkcs15.h" + +static void set_string(char **strp, const char *value) { + if (*strp) + free(*strp); + *strp = value ? strdup(value) : NULL; +} + +static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { + sc_card_t *card = p15card->card; + u8 buff[128]; + int r, i; + size_t field_length = 0, taglen, j; + sc_path_t tmppath; + + set_string(&p15card->tokeninfo->label, "ID-kaart"); + set_string(&p15card->tokeninfo->manufacturer_id, "IDEMIA"); + + /* Read docnr */ + sc_format_path("3F00D003", &tmppath); + LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); + r = sc_read_binary(card, 0, buff, 11, 0); + LOG_TEST_RET(card->ctx, r, "read docnr failed"); + const unsigned char *tag = sc_asn1_find_tag(card->ctx, buff, r, 0x04, &taglen); + if (tag == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + for (j = 0; j < taglen; j++) + if (!isalnum(tag[j])) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + p15card->tokeninfo->serial_number = malloc(taglen + 1); + if (!p15card->tokeninfo->serial_number) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + p15card->tokeninfo->serial_number = memcpy(p15card->tokeninfo->serial_number, tag, taglen); + p15card->tokeninfo->serial_number[taglen] = '\0'; + p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; + + /* add certificates */ + for (i = 0; i < 2; i++) { + const char *esteid_cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; + const char *esteid_cert_paths[2] = {"3f00:adf1:3401", "3f00:adf2:341f"}; + const int esteid_cert_ids[2] = {1, 2}; + + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label)); + sc_format_path(esteid_cert_paths[i], &cert_info.path); + cert_info.id.value[0] = esteid_cert_ids[i]; + cert_info.id.len = 1; + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + if (r < 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + // Read data from first cert + if (i != 0) + continue; + + sc_pkcs15_cert_t *cert = NULL; + r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + LOG_TEST_RET(card->ctx, r, "Could not read authentication certificate"); + + if (cert->key->algorithm == SC_ALGORITHM_EC) + field_length = cert->key->u.ec.params.field_length; + + static const struct sc_object_id cn_oid = {{2, 5, 4, 3, -1}}; + u8 *cn_name = NULL; + size_t cn_len = 0; + sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, cert->subject_len, &cn_oid, &cn_name, &cn_len); + if (cn_len > 0) { + char *token_name = malloc(cn_len + 1); + if (token_name) { + memcpy(token_name, cn_name, cn_len); + token_name[cn_len] = '\0'; + set_string(&p15card->tokeninfo->label, (const char *)token_name); + free(token_name); + } + } + free(cn_name); + sc_pkcs15_free_certificate(cert); + } + + /* add pins */ + for (i = 0; i < 3; i++) { + static const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; + static const int esteid_pin_min[3] = {4, 5, 8}; + static const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; + static const int esteid_pin_authid[3] = {1, 2, 3}; + static const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; + + static const int esteid_pin_flags[3] = { + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + sc_format_path(esteid_pin_path[i], &pin_info.path); + pin_info.auth_id.len = 1; + pin_info.auth_id.value[0] = esteid_pin_authid[i]; + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.reference = esteid_pin_ref[i]; + pin_info.attrs.pin.flags = esteid_pin_flags[i]; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.attrs.pin.min_length = esteid_pin_min[i]; + pin_info.attrs.pin.stored_length = 12; + pin_info.attrs.pin.max_length = 12; + pin_info.attrs.pin.pad_char = 0xFF; + pin_info.tries_left = 3; + pin_info.max_tries = 3; + + strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label)); + pin_obj.flags = esteid_pin_flags[i]; + + /* Link normal PINs with PUK */ + if (i < 2) { + pin_obj.auth_id.len = 1; + pin_obj.auth_id.value[0] = 3; + } + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + if (r < 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + struct sc_pkcs15_object *objs[3]; + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 3); + + if (r != 3) { + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + // trigger PIN counter refresh via pin_cmd + for (i = 0; i < r; i++) { + r = sc_pkcs15_get_pin_info(p15card, objs[i]); + if (r < 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + /* add private keys */ + for (i = 0; i < 2; i++) { + int prkey_pin[2] = {1, 2}; + + const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; + const char *prkey_path[2] = {"3F00:ADF1", "3F00:ADF2"}; + const int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + const int prkey_consent[2] = {0, 1}; + + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + sc_format_path(prkey_path[i], &prkey_info.path); + prkey_info.id.len = 1; + prkey_info.id.value[0] = prkey_pin[i]; + prkey_info.native = 1; + prkey_info.key_reference = i + 1; + prkey_info.field_length = field_length; + prkey_info.usage = prkey_usage[i]; + + strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label)); + prkey_obj.auth_id.len = 1; + prkey_obj.auth_id.value[0] = prkey_pin[i]; + prkey_obj.user_consent = prkey_consent[i]; + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + if (r < 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + return SC_SUCCESS; +} + +int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { + if (p15card->card->type == SC_CARD_TYPE_ESTEID_2018) + return sc_pkcs15emu_esteid2018_init(p15card); + return SC_ERROR_WRONG_CARD; +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 8ecc345664..82e120d929 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -58,6 +58,8 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "jpki", sc_pkcs15emu_jpki_init_ex }, { "coolkey", sc_pkcs15emu_coolkey_init_ex }, { "din66291", sc_pkcs15emu_din_66291_init_ex }, + { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, + { NULL, NULL } }; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index a141f79fe3..6811b3dab1 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -34,6 +34,7 @@ int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); From fc8e9bf3f3757aacbf2d6b9636d52737ea0c1828 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Fri, 22 Mar 2019 14:59:18 +0200 Subject: [PATCH 0892/4321] Address review comments and further reduce LOC and make sure the card is always handled emulated card first Change-Id: I60174c2793bb882fb73716f62a652d84e028382c --- src/libopensc/Makefile.mak | 3 +- src/libopensc/card-esteid2018.c | 66 +++++++++++-------------------- src/libopensc/pkcs15-esteid2018.c | 27 ++++++------- src/libopensc/pkcs15-syn.c | 3 +- 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index c928b64c98..487fbeb4a6 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -27,7 +27,7 @@ OBJECTS = \ card-iasecc.obj iasecc-sdo.obj iasecc-sm.obj cwa-dnie.obj cwa14890.obj \ card-sc-hsm.obj card-dnie.obj card-isoApplet.obj pkcs15-coolkey.obj \ card-masktech.obj card-gids.obj card-jpki.obj \ - card-npa.obj \ + card-npa.obj card-esteid2018.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ @@ -35,6 +35,7 @@ OBJECTS = \ pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ + pkcs15-esteid2018.obj \ compression.obj p15card-helper.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index ccb2d892e4..4ec6f92f62 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -53,6 +53,12 @@ struct esteid_priv_data { #define DRVDATA(card) ((struct esteid_priv_data *)((card)->drv_data)) +#define SC_TRANSMIT_TEST_RET(card, apdu, text) \ + do { \ + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); \ + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), text); \ + } while (0) + static int esteid_match_card(sc_card_t *card) { int i = 0; int r = 0; @@ -91,12 +97,10 @@ static int esteid_select(struct sc_card *card, unsigned char p1, unsigned char i apdu.data = sbuf; apdu.datalen = 2; } - apdu.le = 0x00; + apdu.le = 0; apdu.resplen = 0; - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "SELECT failed"); - + SC_TRANSMIT_TEST_RET(card, apdu, "SELECT failed"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -142,8 +146,8 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat // temporary hack, overload 6B00 SW processing static int esteid_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags) { int r; + int (*saved)(struct sc_card *, unsigned int, unsigned int) = card->ops->check_sw; LOG_FUNC_CALLED(card->ctx); - void *saved = card->ops->check_sw; card->ops->check_sw = esteid_check_sw; r = iso_ops->read_binary(card, idx, buf, count, flags); card->ops->check_sw = saved; @@ -154,9 +158,10 @@ static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env struct esteid_priv_data *priv; struct sc_apdu apdu; - const unsigned char cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, 0x81}; - const unsigned char cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, 0x9F}; - const unsigned char cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, 0x81}; + // XXX: could be const + unsigned char cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, 0x81}; + unsigned char cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, 0x9F}; + unsigned char cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, 0x81}; LOG_FUNC_CALLED(card->ctx); @@ -166,26 +171,15 @@ static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env sc_log(card->ctx, "algo: %d operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 1) { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xA4); - apdu.data = cse_crt_aut; - apdu.datalen = sizeof(cse_crt_aut); - apdu.lc = sizeof(cse_crt_aut); + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0); } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 2) { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); - apdu.data = cse_crt_sig; - apdu.datalen = sizeof(cse_crt_sig); - apdu.lc = sizeof(cse_crt_sig); + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == 1) { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); - apdu.data = cse_crt_dec; - apdu.datalen = sizeof(cse_crt_dec); - apdu.lc = sizeof(cse_crt_dec); + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0); } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "SET SECURITY ENV failed"); + SC_TRANSMIT_TEST_RET(card, apdu, "SET SECURITY ENV failed"); priv = DRVDATA(card); priv->sec_env = *env; @@ -210,20 +204,13 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data switch (env->key_ref[0]) { case 1: /* authentication key */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0, 0); + sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, MIN(256, outlen)); break; default: - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); + sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, MIN(256, outlen)); } - apdu.lc = datalen; - apdu.data = sbuf; - apdu.datalen = datalen; - apdu.le = MIN(256, outlen); - apdu.resp = out; - apdu.resplen = outlen; - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "PSO CDS/INTERNAL AUTHENTICATE failed"); + SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed"); LOG_FUNC_RETURN(card->ctx, apdu.resplen); } @@ -244,17 +231,10 @@ static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF); get_pin_info[6] = pin_reference & 0x0F; // mask out local/global - apdu.lc = sizeof(get_pin_info); - apdu.data = get_pin_info; - apdu.datalen = sizeof(get_pin_info); - apdu.resplen = sizeof(apdu_resp); - apdu.resp = apdu_resp; - apdu.le = 256; - - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "GET DATA(pin info) failed"); + // XXX: handling of default Le of 0x00 could be easier + sc_format_apdu_ex(card, &apdu, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, MIN(256, sizeof(apdu_resp))); + SC_TRANSMIT_TEST_RET(card, apdu, "GET DATA(pin info) failed"); // XXX: sc_asn1_find_tag with the following payload (to get to tag 0x9B): // https://lapo.it/asn1js/#cB6_gQEaoBiaAQObAQOhEIwG8wAAc0MAnAbzAABzQwA diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 243e231817..c542a54151 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -54,7 +54,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); r = sc_read_binary(card, 0, buff, 11, 0); LOG_TEST_RET(card->ctx, r, "read docnr failed"); - const unsigned char *tag = sc_asn1_find_tag(card->ctx, buff, r, 0x04, &taglen); + const unsigned char *tag = sc_asn1_find_tag(card->ctx, buff, (size_t)r, 0x04, &taglen); if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -72,7 +72,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { for (i = 0; i < 2; i++) { const char *esteid_cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; const char *esteid_cert_paths[2] = {"3f00:adf1:3401", "3f00:adf2:341f"}; - const int esteid_cert_ids[2] = {1, 2}; + const u8 esteid_cert_ids[2] = {1, 2}; struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; @@ -118,13 +118,13 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { /* add pins */ for (i = 0; i < 3; i++) { - static const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; - static const int esteid_pin_min[3] = {4, 5, 8}; - static const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; - static const int esteid_pin_authid[3] = {1, 2, 3}; - static const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; + const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; + const size_t esteid_pin_min[3] = {4, 5, 8}; + const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; + const u8 esteid_pin_authid[3] = {1, 2, 3}; + const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; - static const int esteid_pin_flags[3] = { + const unsigned int esteid_pin_flags[3] = { SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; @@ -163,15 +163,12 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } + // trigger PIN counter refresh via pin_cmd struct sc_pkcs15_object *objs[3]; r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 3); - if (r != 3) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - - // trigger PIN counter refresh via pin_cmd for (i = 0; i < r; i++) { r = sc_pkcs15_get_pin_info(p15card, objs[i]); if (r < 0) @@ -180,12 +177,12 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { /* add private keys */ for (i = 0; i < 2; i++) { - int prkey_pin[2] = {1, 2}; + const u8 prkey_pin[2] = {1, 2}; const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; const char *prkey_path[2] = {"3F00:ADF1", "3F00:ADF2"}; - const int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, - SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; const int prkey_consent[2] = {0, 1}; struct sc_pkcs15_prkey_info prkey_info; diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 82e120d929..facb0a607c 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -71,7 +71,7 @@ static const char *builtin_name = "builtin"; static const char *func_name = "sc_pkcs15_init_func"; static const char *exfunc_name = "sc_pkcs15_init_func_ex"; - +// FIXME: have a flag in card->flags to indicate the same int sc_pkcs15_is_emulation_only(sc_card_t *card) { switch (card->type) { @@ -93,6 +93,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_ESTEID_2018: return 1; default: From 5f5d40521ea9d01becceadaa79f6098f04b12de0 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Thu, 18 Apr 2019 20:22:20 +0300 Subject: [PATCH 0893/4321] Avoid 6282 reply for a successful operation Change-Id: I5d4d3103692fc6db51f13fc5338360289c26af9a --- src/libopensc/card-esteid2018.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 4ec6f92f62..d00f1c7b1f 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -204,10 +204,10 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data switch (env->key_ref[0]) { case 1: /* authentication key */ - sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, MIN(256, outlen)); + sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, MIN(256, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen))); break; default: - sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, MIN(256, outlen)); + sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, MIN(256, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen))); } SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed"); From 2829c5870fdcd855b44f6d156dc4d3949c4ed0f9 Mon Sep 17 00:00:00 2001 From: Martin Paljak Date: Sat, 20 Apr 2019 10:08:27 +0300 Subject: [PATCH 0894/4321] Address review comments Change-Id: I9aa97c8a9878dddd3e6f1a2baa877d188b9d7fe5 --- src/libopensc/card-esteid2018.c | 51 ++++++++++++++++--------------- src/libopensc/pkcs15-esteid2018.c | 8 ++--- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index d00f1c7b1f..9de32e8a3b 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -32,6 +32,9 @@ /* Helping defines */ #define SIGNATURE_PAYLOAD_SIZE 0x30 +#define PIN1_REF 0x01 +#define PIN2_REF 0x85 +#define PUK_REF 0x02 static const struct sc_atr_table esteid_atrs[] = { {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, @@ -60,16 +63,11 @@ struct esteid_priv_data { } while (0) static int esteid_match_card(sc_card_t *card) { - int i = 0; - int r = 0; - - i = _sc_match_atr(card, esteid_atrs, &card->type); - if (i >= 0) { - r = gp_select_aid(card, &IASECC_AID); - if (r == SC_SUCCESS) { - card->name = esteid_atrs[i].name; - return 1; - } + int i = _sc_match_atr(card, esteid_atrs, &card->type); + + if (i >= 0 && gp_select_aid(card, &IASECC_AID) == SC_SUCCESS) { + card->name = esteid_atrs[i].name; + return 1; } return 0; } @@ -106,7 +104,7 @@ static int esteid_select(struct sc_card *card, unsigned char p1, unsigned char i static int esteid_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) { unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - int pathlen; + size_t pathlen; struct sc_file *file = NULL; LOG_FUNC_CALLED(card->ctx); @@ -122,7 +120,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat while (pathlen >= 2) { if (memcmp(path, "\x3F\x00", 2) == 0) { LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "MF select failed"); - } else if (pathlen >= 2 && path[0] == 0xAD) { + } else if (path[0] == 0xAD) { LOG_TEST_RET(card->ctx, esteid_select(card, 0x01, path[0], path[1]), "DF select failed"); } else if (pathlen == 2) { LOG_TEST_RET(card->ctx, esteid_select(card, 0x02, path[0], path[1]), "EF select failed"); @@ -133,6 +131,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat if (file == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); file->path = *in_path; + file->size = 1536; // Dummy size, to be above 1024 *file_out = file; } @@ -190,7 +189,8 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data struct esteid_priv_data *priv = DRVDATA(card); struct sc_security_env *env = NULL; struct sc_apdu apdu; - u8 sbuf[SIGNATURE_PAYLOAD_SIZE] = {0}; + u8 sbuf[SIGNATURE_PAYLOAD_SIZE]; + int le = MIN(SC_MAX_APDU_RESP_SIZE, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen)); LOG_FUNC_CALLED(card->ctx); if (data == NULL || out == NULL || datalen > SIGNATURE_PAYLOAD_SIZE) @@ -204,41 +204,43 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data switch (env->key_ref[0]) { case 1: /* authentication key */ - sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, MIN(256, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen))); + sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, le); break; default: - sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, MIN(256, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen))); + sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, le); } SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed"); - LOG_FUNC_RETURN(card->ctx, apdu.resplen); + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); } static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { unsigned char get_pin_info[] = {0x4D, 0x08, 0x70, 0x06, 0xBF, 0x81, 0xFF, 0x02, 0xA0, 0x80}; struct sc_apdu apdu; - unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; + unsigned char apdu_resp[SC_MAX_APDU_RESP_SIZE]; LOG_FUNC_CALLED(card->ctx); // We don't get the file information here, so we need to be ugly - if (pin_reference == 1 || pin_reference == 2) { + if (pin_reference == PIN1_REF || pin_reference == PUK_REF) { LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "Cannot select MF"); - } else if (pin_reference == 0x85) { + } else if (pin_reference == PIN2_REF) { LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } get_pin_info[6] = pin_reference & 0x0F; // mask out local/global - // XXX: handling of default Le of 0x00 could be easier - sc_format_apdu_ex(card, &apdu, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, MIN(256, sizeof(apdu_resp))); + sc_format_apdu_ex(card, &apdu, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, sizeof(apdu_resp)); SC_TRANSMIT_TEST_RET(card, apdu, "GET DATA(pin info) failed"); + if (apdu.resplen < 32) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } // XXX: sc_asn1_find_tag with the following payload (to get to tag 0x9B): // https://lapo.it/asn1js/#cB6_gQEaoBiaAQObAQOhEIwG8wAAc0MAnAbzAABzQwA - return apdu_resp[13]; + return (int)apdu_resp[13]; } static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { @@ -260,17 +262,16 @@ static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tr // VERIFY memcpy(&tmp, data, sizeof(struct sc_pin_cmd_data)); tmp.cmd = SC_PIN_CMD_VERIFY; - tmp.pin_reference = 0x02; // hardcoded, ugly + tmp.pin_reference = PUK_REF; tmp.pin2.len = 0; r = iso_ops->pin_cmd(card, &tmp, tries_left); - sc_mem_clear(&tmp, sizeof(tmp)); LOG_TEST_RET(card->ctx, r, "VERIFY during unblock failed"); if (data->pin_reference == 0x85) { LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); } // UNBLOCK - memcpy(&tmp, data, sizeof(struct sc_pin_cmd_data)); + tmp = *data; tmp.cmd = SC_PIN_CMD_UNBLOCK; tmp.pin1.len = 0; r = iso_ops->pin_cmd(card, &tmp, tries_left); diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index c542a54151..af87550ab5 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -41,7 +41,7 @@ static void set_string(char **strp, const char *value) { static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { sc_card_t *card = p15card->card; - u8 buff[128]; + u8 buff[11]; int r, i; size_t field_length = 0, taglen, j; sc_path_t tmppath; @@ -49,11 +49,11 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { set_string(&p15card->tokeninfo->label, "ID-kaart"); set_string(&p15card->tokeninfo->manufacturer_id, "IDEMIA"); - /* Read docnr */ + /* Read documber number to be used as serial */ sc_format_path("3F00D003", &tmppath); LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); r = sc_read_binary(card, 0, buff, 11, 0); - LOG_TEST_RET(card->ctx, r, "read docnr failed"); + LOG_TEST_RET(card->ctx, r, "read document number failed"); const unsigned char *tag = sc_asn1_find_tag(card->ctx, buff, (size_t)r, 0x04, &taglen); if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -99,7 +99,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { if (cert->key->algorithm == SC_ALGORITHM_EC) field_length = cert->key->u.ec.params.field_length; - static const struct sc_object_id cn_oid = {{2, 5, 4, 3, -1}}; + const struct sc_object_id cn_oid = {{2, 5, 4, 3, -1}}; u8 *cn_name = NULL; size_t cn_len = 0; sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, cert->subject_len, &cn_oid, &cn_name, &cn_len); From e275b34269303261a86b884ad15749be362c3cc1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Apr 2019 13:27:35 +0200 Subject: [PATCH 0895/4321] fixed 339157 Unused value --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5f7b6315ea..655e28cb0b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5638,6 +5638,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } if (mech_type == CKM_RSA_PKCS_OAEP) { +#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) const EVP_MD *md; switch (hash_alg) { case CKM_SHA_1: @@ -5658,7 +5659,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, md = EVP_sha512(); break; } -#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); From 630bcbedd4b30f7d960c4667cc1d238324ae82a1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Apr 2019 13:29:32 +0200 Subject: [PATCH 0896/4321] fixed 337490 Unchecked return value --- src/libopensc/pkcs15-actalis.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index e13f19a197..9ded751e79 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -180,7 +180,9 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) if (r != SC_SUCCESS) return SC_ERROR_WRONG_CARD; - sc_read_binary(card, 0xC3, serial_buf, 12, 0); + r = sc_read_binary(card, 0xC3, serial_buf, 12, 0); + if (r != SC_SUCCESS) + return SC_ERROR_WRONG_CARD; serial = serial_buf; /* From 65d607af6674c35c6d32cc16ae3d3784a4ac99fb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Apr 2019 13:37:39 +0200 Subject: [PATCH 0897/4321] fixed 325860 Dereference before null check --- src/libopensc/card-myeid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index f43add0d6b..2f0ab585cc 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1336,12 +1336,13 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len) { - myeid_private_data_t* priv = card->drv_data; + myeid_private_data_t* priv; u8 p2 = 0x86; /* init P2 for asymmetric crypto by default.*/ int r; if (card == NULL || crgram == NULL) return SC_ERROR_INVALID_ARGUMENTS; + priv = card->drv_data; LOG_FUNC_CALLED(card->ctx); From e501c5ae814f3d524226d62bf79fba2159853480 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 May 2019 17:53:34 +0200 Subject: [PATCH 0898/4321] Unbreak build without OpenSSL --- src/tools/pkcs11-tool.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 655e28cb0b..d3fd717835 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5638,7 +5638,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } if (mech_type == CKM_RSA_PKCS_OAEP) { -#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) +#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md) const EVP_MD *md; switch (hash_alg) { case CKM_SHA_1: @@ -5665,12 +5665,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf("set md failed, returning\n"); return 0; } -#else - if (hash_alg != CKM_SHA_1) { - printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n"); - return 0; - } -#endif switch (mgf) { case CKG_MGF1_SHA1: md = EVP_sha1(); @@ -5698,6 +5692,12 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf("set mgf1 md failed, returning\n"); return 0; } +#else + if (hash_alg != CKM_SHA_1) { + printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n"); + return 0; + } +#endif } size_t out_len = sizeof(encrypted); From 1e59643caa9d025d037658cba67445562f41cb46 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 3 May 2019 14:46:45 +0300 Subject: [PATCH 0899/4321] Remove process_arr unused file argument and fix clang-tidy warnings Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 006f692029..8a72785e62 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -110,7 +110,7 @@ struct mcrd_priv_data { sc_security_env_t sec_env; /* current security environment */ }; -#define DRVDATA(card) ((struct mcrd_priv_data *) ((card)->drv_data)) +#define DRVDATA(card) ((struct mcrd_priv_data *) ((card)->drv_data)) // Control Reference Template Tag for Key Agreement (ISO 7816-4:2013 Table 54) static const struct sc_asn1_entry c_asn1_control[] = { @@ -403,18 +403,18 @@ static int load_special_files(sc_card_t * card) for (recno = 1;; recno++) { u8 recbuf[256]; r = sc_read_record(card, recno, recbuf, sizeof(recbuf), - SC_RECORD_BY_REC_NR); + SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; - else if (r < 0) { + if (r < 0) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } else { - rule = malloc(sizeof *rule + r); + rule = malloc(sizeof *rule + (size_t)r); if (!rule) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); rule->recno = recno; - rule->datalen = r; + rule->datalen = (size_t)r; memcpy(rule->data, recbuf, r); rule->next = dfi->rule_file; dfi->rule_file = rule; @@ -434,18 +434,18 @@ static int load_special_files(sc_card_t * card) for (recno = 1;; recno++) { u8 recbuf[256]; r = sc_read_record(card, recno, recbuf, sizeof(recbuf), - SC_RECORD_BY_REC_NR); + SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; - else if (r < 0) { + if (r < 0) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); } else { - keyd = malloc(sizeof *keyd + r); + keyd = malloc(sizeof *keyd + (size_t)r); if (!keyd) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); keyd->recno = recno; - keyd->datalen = r; + keyd->datalen = (size_t) r; memcpy(keyd->data, recbuf, r); keyd->next = dfi->keyd_file; dfi->keyd_file = keyd; @@ -459,8 +459,7 @@ static int load_special_files(sc_card_t * card) } /* Process an ARR (7816-9/8.5.4) and setup the ACL. */ -static void process_arr(sc_card_t * card, sc_file_t * file, - const u8 * buf, size_t buflen) +static void process_arr(sc_card_t * card, const u8 * buf, size_t buflen) { sc_context_t *ctx = card->ctx; struct df_info_s *dfi; @@ -479,7 +478,7 @@ static void process_arr(sc_card_t * card, sc_file_t * file, dfi = get_df_info(card); for (rule = dfi ? dfi->rule_file : NULL; rule && rule->recno != *buf; - rule = rule->next) ; + rule = rule->next) ; if (!rule) { sc_log(ctx, "referenced EF_rule record %d not found\n", *buf); return; @@ -582,7 +581,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, int bytes = (tag[0] << 8) + tag[1]; sc_log(ctx, " bytes in file: %d\n", bytes); - file->size = bytes; + file->size = (size_t)bytes; } if (tag == NULL) { tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); @@ -590,7 +589,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, int bytes = (tag[0] << 8) + tag[1]; sc_log(ctx, " bytes in file: %d\n", bytes); - file->size = bytes; + file->size = (size_t)bytes; } } @@ -641,8 +640,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, file->namelen = taglen; for (i = 0; i < taglen; i++) { - if (isalnum(tag[i]) || ispunct(tag[i]) - || isspace(tag[i])) + if (isalnum(tag[i]) || ispunct(tag[i]) || isspace(tag[i])) name[i] = tag[i]; else name[i] = '?'; @@ -673,14 +671,14 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, /* Security attributes, reference to expanded format. */ tag = sc_asn1_find_tag(ctx, p, len, 0x8B, &taglen); if (tag && taglen && !is_esteid_card(card)) { - process_arr(card, file, tag, taglen); + process_arr(card, tag, taglen); } else if ((tag = sc_asn1_find_tag(ctx, p, len, 0xA1, &taglen)) - && taglen) { + && taglen) { /* Not found, but there is a Security Attribute Template for interface mode. */ tag = sc_asn1_find_tag(ctx, tag, taglen, 0x8B, &taglen); if (tag && taglen) - process_arr(card, file, tag, taglen); + process_arr(card, tag, taglen); } file->magic = SC_FILE_MAGIC; @@ -1254,8 +1252,7 @@ static int mcrd_compute_signature(sc_card_t * card, if (env->key_ref[0] == 1) /* authentication key */ sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0, 0); else - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, - 0x2A, 0x9E, 0x9A); + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); apdu.lc = datalen; apdu.data = data; apdu.datalen = datalen; @@ -1268,7 +1265,7 @@ static int mcrd_compute_signature(sc_card_t * card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen); } static int mcrd_decipher(struct sc_card *card, @@ -1324,7 +1321,7 @@ static int mcrd_decipher(struct sc_card *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "Card returned error"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen); } /* added by -mp, to give pin information in the card driver (pkcs15emu->driver needed) */ @@ -1341,7 +1338,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, if (is_esteid_card(card) && data->cmd == SC_PIN_CMD_GET_INFO) { sc_path_t tmppath; u8 buf[16]; - int ref_to_record[] = {3,1,2}; + unsigned int ref_to_record[] = {3,1,2}; /* the file with key pin info (tries left) 4.5 EF_PwdC */ /* XXX: cheat the file path cache by always starting fresh from MF */ From 1423c6bb90f3cb9898e370debad20eb368312496 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 4 May 2019 01:53:55 +0200 Subject: [PATCH 0900/4321] CI: integrate clang-tidy (disabled) files that have warnings are currently excluded --- .travis.yml | 3 ++- configure.ac | 3 +++ src/libopensc/Makefile.am | 4 +++ src/libopensc/aux-data.c | 2 +- src/libopensc/cardctl.h | 32 ++++++++++++------------ src/libopensc/pkcs15-piv.c | 50 +++++++++++++++++++------------------- 6 files changed, 51 insertions(+), 43 deletions(-) diff --git a/.travis.yml b/.travis.yml index 61e951210e..d1723b65b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,12 +51,13 @@ addons: - check before_install: + # brew install gengetopt help2man cmocka ccache llvm; + # export PATH="/usr/local/opt/ccache/libexec:/usr/local/opt/llvm/bin:$PATH"; - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; brew uninstall libtool; brew install libtool; brew install gengetopt help2man cmocka ccache; - export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi before_script: diff --git a/configure.ac b/configure.ac index c4d461e928..0c1128459b 100644 --- a/configure.ac +++ b/configure.ac @@ -926,6 +926,9 @@ fi AC_ARG_VAR([GENGETOPT], [absolute path to gengetopt used for command line parsing of npa-tool]) AC_PATH_PROG(GENGETOPT, gengetopt, not found) +AC_ARG_VAR([CLANGTIDY], + [absolute path to clang-tidy used for static code analysis]) +AC_PATH_PROG(CLANGTIDY, clang-tidy, not found) AX_FUNC_GETOPT_LONG #AH_BOTTOM([#include "common/compat_getopt.h"]) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 7d33fcfa3e..6e2db7b1c1 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -104,3 +104,7 @@ if ENABLE_MINIDRIVER noinst_LTLIBRARIES = libopensc_static.la endif endif + +TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +check-local: + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(SOURCES) -- $(TIDY_FLAGS); fi diff --git a/src/libopensc/aux-data.c b/src/libopensc/aux-data.c index 84d539b2b8..7e96e37210 100644 --- a/src/libopensc/aux-data.c +++ b/src/libopensc/aux-data.c @@ -151,7 +151,7 @@ sc_aux_data_get_md_guid(struct sc_context *ctx, struct sc_auxiliary_data *aux_da *guid = '\0'; if (!flags) - strcpy(guid, "{"); + strncpy(guid, "{", sizeof guid); strlcat(guid, (char *)cmap_record->guid, sizeof(guid)-1); if (!flags) strlcat(guid, "}", sizeof(guid)); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 3dbbd40f28..ac1969256b 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -569,19 +569,19 @@ typedef struct sc_cardctl_muscle_key_info { u8* modValue; size_t expLength; u8* expValue; - int pLength; + size_t pLength; u8* pValue; - int qLength; + size_t qLength; u8* qValue; - int pqLength; + size_t pqLength; u8* pqValue; - int dp1Length; + size_t dp1Length; u8* dp1Value; - int dq1Length; + size_t dq1Length; u8* dq1Value; - int gLength; + size_t gLength; u8* gValue; - int yLength; + size_t yLength; u8* yValue; } sc_cardctl_muscle_key_info_t; @@ -898,25 +898,25 @@ typedef struct sc_rtecp_genkey_data { struct sc_cardctl_myeid_gen_store_key_info { int op_type; unsigned int key_type; /* value of SC_CARDCTL_MYEID_KEY_TYPE */ - unsigned int key_len_bits; + size_t key_len_bits; unsigned char *mod; - unsigned int pubexp_len; + size_t pubexp_len; unsigned char *pubexp; - unsigned int primep_len; + size_t primep_len; unsigned char *primep; - unsigned int primeq_len; + size_t primeq_len; unsigned char *primeq; - unsigned int dp1_len; + size_t dp1_len; unsigned char *dp1; - unsigned int dq1_len; + size_t dq1_len; unsigned char *dq1; - unsigned int invq_len; + size_t invq_len; unsigned char *invq; /* new for MyEID > 3.6.0 */ unsigned char *d; /* EC private key / Symmetric key */ - unsigned int d_len; /* EC / Symmetric */ + size_t d_len; /* EC / Symmetric */ unsigned char *ecpublic_point; /* EC public key */ - unsigned int ecpublic_point_len; /* EC */ + size_t ecpublic_point_len; /* EC */ }; /* diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index be29f5031c..5f615cc71d 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -52,8 +52,8 @@ typedef struct objdata_st { typedef struct cdata_st { const char *id; const char *label; - int authority; const char *path; + int authority; int obj_flags; } cdata; @@ -330,30 +330,30 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) #define PIV_NUM_CERTS_AND_KEYS 24 static const cdata certs[PIV_NUM_CERTS_AND_KEYS] = { - {"01", "Certificate for PIV Authentication", 0, "0101cece", 0}, - {"02", "Certificate for Digital Signature", 0, "0100cece", 0}, - {"03", "Certificate for Key Management", 0, "0102cece", 0}, - {"04", "Certificate for Card Authentication", 0, "0500cece", 0}, - {"05", "Retired Certificate for Key Management 1", 0, "1001cece", 0}, - {"06", "Retired Certificate for Key Management 2", 0, "1002cece", 0}, - {"07", "Retired Certificate for Key Management 3", 0, "1003cece", 0}, - {"08", "Retired Certificate for Key Management 4", 0, "1004cece", 0}, - {"09", "Retired Certificate for Key Management 5", 0, "1005cece", 0}, - {"10", "Retired Certificate for Key Management 6", 0, "1006cece", 0}, - {"11", "Retired Certificate for Key Management 7", 0, "1007cece", 0}, - {"12", "Retired Certificate for Key Management 8", 0, "1008cece", 0}, - {"13", "Retired Certificate for Key Management 9", 0, "1009cece", 0}, - {"14", "Retired Certificate for Key Management 10", 0, "100Acece", 0}, - {"15", "Retired Certificate for Key Management 11", 0, "100Bcece", 0}, - {"16", "Retired Certificate for Key Management 12", 0, "100Ccece", 0}, - {"17", "Retired Certificate for Key Management 13", 0, "100Dcece", 0}, - {"18", "Retired Certificate for Key Management 14", 0, "100Ecece", 0}, - {"19", "Retired Certificate for Key Management 15", 0, "100Fcece", 0}, - {"20", "Retired Certificate for Key Management 16", 0, "1010cece", 0}, - {"21", "Retired Certificate for Key Management 17", 0, "1011cece", 0}, - {"22", "Retired Certificate for Key Management 18", 0, "1012cece", 0}, - {"23", "Retired Certificate for Key Management 19", 0, "1013cece", 0}, - {"24", "Retired Certificate for Key Management 20", 0, "1014cece", 0} + {"01", "Certificate for PIV Authentication", "0101cece", 0, 0}, + {"02", "Certificate for Digital Signature", "0100cece", 0, 0}, + {"03", "Certificate for Key Management", "0102cece", 0, 0}, + {"04", "Certificate for Card Authentication", "0500cece", 0, 0}, + {"05", "Retired Certificate for Key Management 1", "1001cece", 0, 0}, + {"06", "Retired Certificate for Key Management 2", "1002cece", 0, 0}, + {"07", "Retired Certificate for Key Management 3", "1003cece", 0, 0}, + {"08", "Retired Certificate for Key Management 4", "1004cece", 0, 0}, + {"09", "Retired Certificate for Key Management 5", "1005cece", 0, 0}, + {"10", "Retired Certificate for Key Management 6", "1006cece", 0, 0}, + {"11", "Retired Certificate for Key Management 7", "1007cece", 0, 0}, + {"12", "Retired Certificate for Key Management 8", "1008cece", 0, 0}, + {"13", "Retired Certificate for Key Management 9", "1009cece", 0, 0}, + {"14", "Retired Certificate for Key Management 10", "100Acece", 0, 0}, + {"15", "Retired Certificate for Key Management 11", "100Bcece", 0, 0}, + {"16", "Retired Certificate for Key Management 12", "100Ccece", 0, 0}, + {"17", "Retired Certificate for Key Management 13", "100Dcece", 0, 0}, + {"18", "Retired Certificate for Key Management 14", "100Ecece", 0, 0}, + {"19", "Retired Certificate for Key Management 15", "100Fcece", 0, 0}, + {"20", "Retired Certificate for Key Management 16", "1010cece", 0, 0}, + {"21", "Retired Certificate for Key Management 17", "1011cece", 0, 0}, + {"22", "Retired Certificate for Key Management 18", "1012cece", 0, 0}, + {"23", "Retired Certificate for Key Management 19", "1013cece", 0, 0}, + {"24", "Retired Certificate for Key Management 20", "1014cece", 0, 0} }; static const pindata pins[] = { From 3c83a80b57b3f9d2ce9abb2440493991ee5e157d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 6 May 2019 23:11:20 +0200 Subject: [PATCH 0901/4321] fixed printing non primitive tag fixes undefined bitshift --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index dffe9920c0..e56044c2f8 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -395,7 +395,7 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf, } else { printf(" %s %-2u", classes[cla >> 6], - i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8)); + i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i-1)*8)); } if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL && tag == SC_ASN1_TAG_NULL && len == 0)) { From b7b501d0a51dfa91598c6ed3180b909cfde6ff32 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 10 May 2019 18:18:36 +0200 Subject: [PATCH 0902/4321] fixed issues reported by clang-analyzer --- src/common/compat_getopt.c | 5 +++-- src/common/simclist.c | 4 ++-- src/libopensc/card-atrust-acos.c | 3 +-- src/libopensc/card-entersafe.c | 3 +-- src/libopensc/card-epass2003.c | 4 +--- src/libopensc/card-iasecc.c | 3 ++- src/libopensc/card-starcos.c | 3 +-- src/libopensc/pkcs15-piv.c | 6 ++++-- src/libopensc/pkcs15-pubkey.c | 7 ++++--- src/pkcs11/framework-pkcs15.c | 5 ++++- src/sm/sm-eac.c | 31 ++++++++++++++++++------------- src/sm/sm-iso.c | 16 +++++++--------- src/tools/pkcs15-crypt.c | 4 ++-- src/tools/pkcs15-init.c | 23 +++++++++++++++++++---- 14 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/common/compat_getopt.c b/src/common/compat_getopt.c index 951e355458..bc70113599 100644 --- a/src/common/compat_getopt.c +++ b/src/common/compat_getopt.c @@ -143,7 +143,7 @@ int _my_getopt_internal(int argc, char * argv[], const char *shortopts, const struct option *longopts, int *longind, int long_only) { - char mode, colon_mode = *shortopts; + char mode, colon_mode; int shortoff = 0, opt = -1; if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+'; @@ -230,7 +230,8 @@ int _my_getopt_internal(int argc, char * argv[], const char *shortopts, argv[0], longopts[found].name); } else { my_optarg = argv[my_optind] + ++charind; - charind = 0; + /* charind not read again + * charind = 0;*/ } } else if(longopts[found].has_arg == 1) { if(++my_optind >= argc) { diff --git a/src/common/simclist.c b/src/common/simclist.c index 03ed79bd76..58be5e3ed8 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -764,10 +764,10 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *simclist_restrict de /* fix mid pointer */ err = l2->numels - l1->numels; - if ((err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ + if (dest->mid && (err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ err = (err+1)/2; for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next; - } else if (err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */ + } else if (dest->mid && err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */ err = -err/2; for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev; } diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index fb3bd70d5e..83da3923f0 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -445,8 +445,7 @@ static int atrust_acos_select_file(struct sc_card *card, { n_pathbuf[0] = 0x3f; n_pathbuf[1] = 0x00; - for (i=0; i< pathlen; i++) - n_pathbuf[i+2] = pathbuf[i]; + memcpy(n_pathbuf+2, path, pathlen); path = n_pathbuf; pathlen += 2; } diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index aa74c619c2..cb6fa15bf9 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -596,8 +596,7 @@ static int entersafe_select_path(sc_card_t *card, { n_pathbuf[0] = 0x3f; n_pathbuf[1] = 0x00; - for (i=0; i< pathlen; i++) - n_pathbuf[i+2] = pathbuf[i]; + memcpy(n_pathbuf+2, path, pathlen); path = n_pathbuf; pathlen += 2; } diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 299520d60b..26b9d79ffc 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1463,9 +1463,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l if (path[0] != 0x3f || path[1] != 0x00) { n_pathbuf[0] = 0x3f; n_pathbuf[1] = 0x00; - - for (i = 0; i < pathlen; i++) - n_pathbuf[i + 2] = pathbuf[i]; + memcpy(n_pathbuf+2, path, pathlen); path = n_pathbuf; pathlen += 2; } diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 8f5be9015b..9a4c3ce144 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -623,8 +623,9 @@ iasecc_init(struct sc_card *card) card->sm_ctx.ops.update_binary = _iasecc_sm_update_binary; #endif - if (!rv) + if (!rv && card->ef_atr && card->ef_atr->aid.len) { sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len)); + } LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index c022b04d14..a518eab90a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -704,8 +704,7 @@ static int starcos_select_file(sc_card_t *card, { n_pathbuf[0] = 0x3f; n_pathbuf[1] = 0x00; - for (i=0; i< pathlen; i++) - n_pathbuf[i+2] = pathbuf[i]; + memcpy(n_pathbuf+2, path, pathlen); path = n_pathbuf; pathlen += 2; } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 5f615cc71d..4f06993060 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -981,7 +981,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_object pubkey_obj; - struct sc_pkcs15_pubkey *p15_key; + struct sc_pkcs15_pubkey *p15_key = NULL; memset(&pubkey_info, 0, sizeof(pubkey_info)); memset(&pubkey_obj, 0, sizeof(pubkey_obj)); @@ -1035,8 +1035,10 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); sc_log(card->ctx, "Adding pubkey from file %s",filename); r = sc_pkcs15_pubkey_from_spki_file(card->ctx, filename, &p15_key); - if (r < 0) + if (r < 0) { + free(p15_key); continue; + } /* Lets also try another method. */ r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, p15_key, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index b094832ccc..84827c4ae7 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -200,8 +200,8 @@ sc_pkcs15_decode_pubkey_direct_value(struct sc_pkcs15_card *p15card, struct sc_p LOG_TEST_RET(ctx, rv, "Failed to decode 'SPKI' direct value"); rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &info->direct.raw.value, &info->direct.raw.len); - LOG_TEST_RET(ctx, rv, "Failed to encode 'RAW' direct value"); sc_pkcs15_free_pubkey(pubkey); + LOG_TEST_RET(ctx, rv, "Failed to encode 'RAW' direct value"); } LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -1428,9 +1428,10 @@ sc_pkcs15_pubkey_from_spki_sequence(struct sc_context *ctx, const unsigned char r = sc_asn1_decode(ctx, asn1_spki, buf, buflen, NULL, NULL); LOG_TEST_RET(ctx, r, "ASN.1 cannot parse subjectPublicKeyInfo"); - if(outpubkey) + if(outpubkey) { + free(*outpubkey); *outpubkey = pubkey; - else + } else free(pubkey); LOG_FUNC_RETURN(ctx, r); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 4b1f17905c..57ea18a50d 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4085,7 +4085,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; struct pkcs15_any_object *targetKeyObj = (struct pkcs15_any_object *) targetKey; - int rv, flags = 0; + int rv; sc_log(context, "Initiating unwrapping with private key."); @@ -4109,6 +4109,8 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); +#if 0 + /* FIXME https://github.com/OpenSC/OpenSC/issues/1595 */ /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_RSA_PKCS: @@ -4120,6 +4122,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, default: return CKR_MECHANISM_INVALID; } +#endif rv = sc_lock(p11card->card); diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 88f670a18a..5338019456 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1486,6 +1486,8 @@ int perform_terminal_authentication(sc_card_t *card, struct eac_sm_ctx *eacsmctx = NULL; unsigned char *ef_cardaccess = NULL; EAC_CTX *eac_ctx = NULL; + const unsigned char *chr = NULL; + size_t chr_len = 0; if (!card || !certs_lens || !certs) { r = SC_ERROR_INVALID_ARGUMENTS; @@ -1566,6 +1568,9 @@ int perform_terminal_authentication(sc_card_t *card, if (r < 0) goto err; + chr = cvc_cert->body->certificate_holder_reference->data; + chr_len = cvc_cert->body->certificate_holder_reference->length; + certs++; certs_lens++; } @@ -1590,9 +1595,7 @@ int perform_terminal_authentication(sc_card_t *card, } - r = eac_mse_set_at_ta(card, eacsmctx->ctx->ta_ctx->protocol, - cvc_cert->body->certificate_holder_reference->data, - cvc_cert->body->certificate_holder_reference->length, + r = eac_mse_set_at_ta(card, eacsmctx->ctx->ta_ctx->protocol, chr, chr_len, (unsigned char *) eacsmctx->eph_pub_key->data, eacsmctx->eph_pub_key->length, auxiliary_data, auxiliary_data_len); if (r < 0) { @@ -2345,16 +2348,18 @@ eac_sm_clear_free(const struct iso_sm_ctx *ctx) { if (ctx) { struct eac_sm_ctx *eacsmctx = ctx->priv_data; - EAC_CTX_clear_free(eacsmctx->ctx); - if (eacsmctx->certificate_description) - BUF_MEM_free(eacsmctx->certificate_description); - if (eacsmctx->id_icc) - BUF_MEM_free(eacsmctx->id_icc); - if (eacsmctx->eph_pub_key) - BUF_MEM_free(eacsmctx->eph_pub_key); - if (eacsmctx->auxiliary_data) - BUF_MEM_free(eacsmctx->auxiliary_data); - free(eacsmctx); + if (eacsmctx) { + EAC_CTX_clear_free(eacsmctx->ctx); + if (eacsmctx->certificate_description) + BUF_MEM_free(eacsmctx->certificate_description); + if (eacsmctx->id_icc) + BUF_MEM_free(eacsmctx->id_icc); + if (eacsmctx->eph_pub_key) + BUF_MEM_free(eacsmctx->eph_pub_key); + if (eacsmctx->auxiliary_data) + BUF_MEM_free(eacsmctx->auxiliary_data); + free(eacsmctx); + } } } diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 41b32a6b1f..9dbda86e3f 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -92,17 +92,15 @@ add_padding(const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, switch (ctx->padding_indicator) { case SM_NO_PADDING: if (*padded != data) { - if (datalen == 0) { - free(*padded); - p = malloc(datalen); - } else { + if (datalen != 0) { p = realloc(*padded, datalen); + if (!p) + return SC_ERROR_OUT_OF_MEMORY; + *padded = p; + memcpy(*padded, data, datalen); + } else { + *padded = NULL; } - if (!p) - return SC_ERROR_OUT_OF_MEMORY; - *padded = p; - /* Flawfinder: ignore */ - memcpy(*padded, data, datalen); } return datalen; case SM_ISO_PADDING: diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 6d064ec317..763510ed6d 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -292,7 +292,7 @@ static int decipher(struct sc_pkcs15_object *obj) static int get_key(unsigned int usage, sc_pkcs15_object_t **result) { - sc_pkcs15_object_t *key, *pin; + sc_pkcs15_object_t *key, *pin = NULL; const char *usage_name; sc_pkcs15_id_t id; int r; @@ -346,7 +346,7 @@ static int get_key(unsigned int usage, sc_pkcs15_object_t **result) * a crypto operation. Card drivers can test for SC_AC_CONTEXT_SPECIFIC * to do any special handling. */ - if (key->user_consent) { + if (key->user_consent && pin) { int auth_meth_saved; struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) pin->data; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index f02692d12f..f45f4cb6d5 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -2097,6 +2097,10 @@ get_pin_callback(struct sc_profile *profile, hints.p15card = g_p15card; if ((r = get_pin(&hints, &secret)) < 0) { + if (secret) { + sc_mem_clear(secret, strlen(secret)); + free(secret); + } fprintf(stderr, "Failed to read PIN from user: %s\n", sc_strerror(r)); @@ -3171,7 +3175,7 @@ static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) } if (opt_pins[0] != NULL) { - pin = (char *) opt_pins[0]; + pin = strdup(opt_pins[0]); } else { sc_ui_hints_t hints; @@ -3192,15 +3196,26 @@ static int verify_pin(struct sc_pkcs15_card *p15card, char *auth_id_str) hints.card = g_card; hints.p15card = p15card; - get_pin(&hints, &pin); + if ((r = get_pin(&hints, &pin)) < 0) { + if (pin) { + sc_mem_clear(pin, strlen(pin)); + free(pin); + } + fprintf(stderr, + "Failed to read PIN from user: %s\n", + sc_strerror(r)); + return r; + } } - r = sc_pkcs15_verify_pin(p15card, pin_obj, (unsigned char *)pin, pin ? strlen((char *) pin) : 0); + r = sc_pkcs15_verify_pin(p15card, pin_obj, (unsigned char *)pin, pin ? strlen(pin) : 0); if (r < 0) fprintf(stderr, "Operation failed: %s\n", sc_strerror(r)); - if (NULL == opt_pins[0]) + if (pin) { + sc_mem_clear(pin, strlen(pin)); free(pin); + } return r; } From 65a86b83310fdc86dbf9a0287b58594da28dbf5e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 May 2019 19:36:17 +0200 Subject: [PATCH 0903/4321] travis: fixed PATH on macOS --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d1723b65b6..0e4080cd5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,6 +58,7 @@ before_install: brew uninstall libtool; brew install libtool; brew install gengetopt help2man cmocka ccache; + export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi before_script: From 0fbd2663e67aae221b8558f7b47ef6b97233ae1f Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Wed, 29 May 2019 15:06:21 +0200 Subject: [PATCH 0904/4321] Add missing ulIvBits to CK_GCM_PARAMS The PKCS#11 specification text does not document the ulIvBits field. But the header file defining CK_GCM_PARAMS uses it. Since the header file is the normative version we need to add it. See also https://github.com/Pkcs11Interop/Pkcs11Interop/issues/126o and https://lists.oasis-open.org/archives/pkcs11-comment/201602/msg00001.html and https://www.oasis-open.org/committees/document.php?document_id=58032&wg_abbrev=pkcs11 --- src/pkcs11/pkcs11.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 61bd6dc45d..a3d6d8f7f6 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -818,6 +818,7 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS { typedef struct CK_GCM_PARAMS { void * pIv; unsigned long ulIvLen; + unsigned long ulIvBits; void * pAAD; unsigned long ulAADLen; unsigned long ulTagBits; From cc189585c855689d06f39c7ccd168f323018c249 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Wed, 29 May 2019 15:09:55 +0200 Subject: [PATCH 0905/4321] pkcs11-spy: display CK_GCM_PARAMS.ulIvBits field --- src/pkcs11/pkcs11-spy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 6bc9baaa6e..fc1116923d 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -791,6 +791,7 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT (CK_GCM_PARAMS *) pMechanism->pParameter; spy_dump_string_in("pIv[ulIvLen]", param->pIv, param->ulIvLen); + spy_dump_ulong_in("ulIvBits", param->ulIvBits); spy_dump_string_in("pAAD[ulAADLen]", param->pAAD, param->ulAADLen); fprintf(spy_output, "pMechanism->pParameter->ulTagBits=%lu\n", param->ulTagBits); From f2a6209c94e60bd76b9d15d8ec0f5d01bc74af9a Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Wed, 22 May 2019 18:11:59 +0200 Subject: [PATCH 0906/4321] Add SmartCard-HSM 4K ATR (#1681) --- win32/customactions.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 943ca21f5a..680d48d728 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -72,6 +72,8 @@ MD_REGISTRATION minidriver_registration[] = { 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("SmartCard-HSM-CL"), {0x3B,0x8E,0x80,0x01,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x18}, 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("SmartCard-HSM 4K"), {0x3b,0xde,0x18,0xff,0x81,0x91,0xfe,0x1f,0xc3,0x80,0x31,0x81,0x54,0x48,0x53,0x4d,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x1c}, + 24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Contactless Smart Card"), {0x3B,0x80,0x80,0x01,0x01}, 5, {0xff,0xff,0xff,0xff,0xff}}, {TEXT("GoID"), {0x3B,0x84,0x80,0x01,0x47,0x6f,0x49,0x44,0x00}, From be294d01be5f44fe87ee901cccb780f3ff34552d Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Tue, 28 May 2019 13:20:11 +0200 Subject: [PATCH 0907/4321] sc-hsm: Add configuration section for 4K --- etc/opensc.conf.example.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 36bdf0b4af..bcb7ddb470 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -462,6 +462,15 @@ app default { md_guid_as_label = true; } + # SmartCard-HSM 4k with contact-based interface or USB-Stick + card_atr 3b:de:18:ff:81:91:fe:1f:c3:80:31:81:54:48:53:4d:31:73:80:21:40:81:07:1c { + driver = "sc-hsm"; + read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + } + # SmartCard-HSM with fingerprint sensor and PIN pad card_atr 3B:80:80:01:01 { force_protocol = "t1"; From e3ff3be4fe483045664d7336a4c9ff2b778d8bbe Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Fri, 24 May 2019 14:57:23 +0200 Subject: [PATCH 0908/4321] pteid: add new ATRs One ATR have been confirmed on my personal card and also added to the official middleware: https://svn.gov.pt/projects/ccidadao/changeset/321/middleware-offline/trunk/_src/eidmw/minidriver/makemsi/pteidmdrv.inf There is another ATR I am adding blind from the official middleware: https://svn.gov.pt/projects/ccidadao/changeset/321/middleware-offline/trunk/_src/eidmw/minidriver/makemsi/pteidmdrv.inf Signed-off-by: Nuno Goncalves --- src/libopensc/card-gemsafeV1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index b0461d49cb..81dac75641 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -61,6 +61,8 @@ static const struct sc_atr_table gemsafe_atrs[] = { {"3B:7D:95:00:00:80:31:80:65:B0:83:11:C0:A9:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, {"3B:7D:95:00:00:80:31:80:65:B0:83:11:00:C8:83:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, {"3B:7D:95:00:00:80:31:80:65:B0:83:11:00:C8:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, + {"3B:FF:96:00:00:81:31:80:43:80:31:80:65:B0:85:03:00:EF:12:0F:FF:82:90:00:67", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, + {"3B:FF:96:00:00:81:31:FE:43:80:31:80:65:B0:85:04:01:20:12:0F:FF:82:90:00:D0", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, /* Swedish eID card */ {"3B:7D:96:00:00:80:31:80:65:B0:83:11:00:C8:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_SEEID, 0, NULL}, /* European Patent Office epoline card*/ From 3a665f64797c716d9281b021269168a5b8201b59 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 25 May 2019 00:28:58 +0200 Subject: [PATCH 0909/4321] allow single character strings with sc_hex_to_bin fixes https://github.com/OpenSC/OpenSC/issues/1684 fixes https://github.com/OpenSC/OpenSC/issues/1669 --- src/libopensc/sc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 1e11b5404c..c241f110fe 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -99,6 +99,14 @@ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen) } } + if (left == *outlen && 1 == byte_needs_nibble && 0 != left) { + /* no output written so far, but we have a valid nibble in the upper + * bits. Allow this special case. */ + *out = (u8) byte>>4; + left--; + byte_needs_nibble = 0; + } + /* for ease of implementation we only accept completely hexed bytes. */ if (byte_needs_nibble) { r = SC_ERROR_INVALID_ARGUMENTS; From 278960bf886d4dc7a0f27cb2c29d2b0706a66591 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 29 May 2019 14:45:42 +0200 Subject: [PATCH 0910/4321] AppVeyor: push build artifact in PRs as well --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 58fc4cd497..b9ed9a1dcb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -103,11 +103,10 @@ build_script: Get-ChildItem -recurse C:\projects\OpenSC -exclude vc*.pdb *.pdb | % { 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName } - -deploy_script: - appveyor PushArtifact %ARTIFACT%.msi - appveyor PushArtifact %ARTIFACT%-Debug.zip +deploy_script: # keep in sync with .travis.yml - bash -c "git config --global user.email 'no-reply@appveyor.com'" - bash -c "git config --global user.name 'AppVeyor'" From a2dd500624b324ca8a8284435a79e232efddad14 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 30 May 2019 08:55:03 -0500 Subject: [PATCH 0911/4321] Fix pkcs11-tool encryption error Fix #1694 Make sure data being encrypted is less then the modulus. On branch pkcs11-tool-encryption Changes to be committed: modified: ../tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d3fd717835..c7e1cc5f3c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5545,6 +5545,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf(" %s: ", p11_mechanism_to_name(mech_type)); pseudo_randomize(orig_data, sizeof(orig_data)); + orig_data[0] = 0; /* Make sure it is less then modulus */ pkey = get_public_key(session, privKeyObject); if (pkey == NULL) From 3a192e2c87430472b2777e08b724742787378831 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 9 May 2019 14:55:25 +0300 Subject: [PATCH 0912/4321] pkcs11-tool: Add extractable option to key import Signed-off-by: Raul Metsma --- doc/tools/pkcs11-tool.1.xml | 9 ++++++++- src/tools/pkcs11-tool.c | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index b960f02538..32b04114cd 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -319,6 +319,13 @@ Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext). + + + + + Set the CKA_EXTRACTABLE attribute (object can be extracted) + + id, @@ -460,7 +467,7 @@ - + mechanisms diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index c7e1cc5f3c..b564f7266a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -141,6 +141,7 @@ enum { OPT_KEY_USAGE_DERIVE, OPT_PRIVATE, OPT_SENSITIVE, + OPT_EXTRACTABLE, OPT_TEST_HOTPLUG, OPT_UNLOCK_PIN, OPT_PUK, @@ -227,6 +228,7 @@ static const struct option options[] = { { "verbose", 0, NULL, 'v' }, { "private", 0, NULL, OPT_PRIVATE }, { "sensitive", 0, NULL, OPT_SENSITIVE }, + { "extractable", 0, NULL, OPT_EXTRACTABLE }, { "always-auth", 0, NULL, OPT_ALWAYS_AUTH }, { "test-ec", 0, NULL, OPT_TEST_EC }, #ifndef _WIN32 @@ -301,6 +303,7 @@ static const char *option_help[] = { "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", "Set the CKA_PRIVATE attribute (object is only viewable after a login)", "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", + "Set the CKA_EXTRACTABLE attribute (object can be extracted)", "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 @@ -348,6 +351,7 @@ static CK_MECHANISM_TYPE opt_allowed_mechanisms[MAX_ALLOWED_MECHANISMS]; static size_t opt_allowed_mechanisms_len = 0; static int opt_is_private = 0; static int opt_is_sensitive = 0; +static int opt_is_extractable = 0; static int opt_test_hotplug = 0; static int opt_login_type = -1; static int opt_key_usage_sign = 0; @@ -883,6 +887,9 @@ int main(int argc, char * argv[]) case OPT_SENSITIVE: opt_is_sensitive = 1; break; + case OPT_EXTRACTABLE: + opt_is_extractable = 1; + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -3136,6 +3143,10 @@ static int write_object(CK_SESSION_HANDLE session) &_true, sizeof(_true)); n_privkey_attr++; } + if (opt_is_extractable != 0) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); + n_privkey_attr++; + } if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, @@ -3302,7 +3313,7 @@ static int write_object(CK_SESSION_HANDLE session) break; case CKO_SECRET_KEY: clazz = CKO_SECRET_KEY; - type = CKK_AES; + type = CKK_GENERIC_SECRET; if (opt_key_type != 0) { if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0) @@ -3336,6 +3347,14 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SENSITIVE, &_false, sizeof(_false)); n_seckey_attr++; } + if (opt_is_extractable != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); + n_seckey_attr++; + } + else { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_EXTRACTABLE, &_false, sizeof(_false)); + n_seckey_attr++; + } if (opt_object_label != NULL) { FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); From 0322401aaed5ea28adddbb79cc17cd584453b0dc Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Sat, 25 May 2019 11:50:33 +0200 Subject: [PATCH 0913/4321] gemsafeV1: remove redundant match card call to allow for opensc.conf match At the point when gemsafe_match_card is called, the card type is already known, either because of a previous match at card.c, or because it is forced at opensc.conf. With this redundant match it's not possible to force selection on opensc.conf. Signed-off-by: Nuno Goncalves --- src/libopensc/card-gemsafeV1.c | 53 ++++++++++++++++------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 81dac75641..63f8e6f2fe 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -199,36 +199,33 @@ static int gemsafe_init(struct sc_card *card) card->lock_count--; /* set the supported algorithm */ - r = gemsafe_match_card(card); - if (r > 0) { - unsigned long flags; - - flags = SC_ALGORITHM_RSA_PAD_PKCS1; - flags |= SC_ALGORITHM_RSA_PAD_ISO9796; - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - flags |= SC_ALGORITHM_RSA_HASH_NONE; - - /* GemSAFE V3 cards support SHA256 */ - if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || - card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) - flags |= SC_ALGORITHM_RSA_HASH_SHA256; + unsigned long flags; + + flags = SC_ALGORITHM_RSA_PAD_PKCS1; + flags |= SC_ALGORITHM_RSA_PAD_ISO9796; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + flags |= SC_ALGORITHM_RSA_HASH_NONE; + + /* GemSAFE V3 cards support SHA256 */ + if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || + card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) + flags |= SC_ALGORITHM_RSA_HASH_SHA256; + + _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); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + + /* fake algorithm to persuade register_mechanisms() + * to register these hashes */ + if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || + card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) { + flags = SC_ALGORITHM_RSA_HASH_SHA1; + flags |= SC_ALGORITHM_RSA_HASH_MD5; + flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; _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); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - - /* fake algorithm to persuade register_mechanisms() - * to register these hashes */ - if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID || - card->type == SC_CARD_TYPE_GEMSAFEV1_SEEID) { - flags = SC_ALGORITHM_RSA_HASH_SHA1; - flags |= SC_ALGORITHM_RSA_HASH_MD5; - flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; - flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; - - _sc_card_add_rsa_alg(card, 512, flags, 0); - } } card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; From 94388f9538e6ea1c1cd853663d8a14705398475a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 28 May 2019 17:46:44 +0200 Subject: [PATCH 0914/4321] fixed more clang-tidy warnings --- src/common/Makefile.am | 29 +++++++++++++++++----- src/common/simclist.c | 8 +++--- src/libopensc/Makefile.am | 40 +++++++++++++++++++++++++++++- src/libopensc/card-mcrd.c | 28 --------------------- src/libopensc/card-myeid.c | 10 +++++--- src/libopensc/card-npa.c | 4 ++- src/libopensc/ctx.c | 5 ++-- src/libopensc/pkcs15-atrust-acos.c | 9 +++---- src/libopensc/pkcs15-cache.c | 5 ++-- src/libopensc/pkcs15-esinit.c | 6 ++--- src/libopensc/pkcs15-gemsafeV1.c | 9 +++---- src/libopensc/pkcs15-itacns.c | 2 +- src/libopensc/pkcs15-starcert.c | 6 ++--- src/libopensc/pkcs15.c | 9 +------ src/pkcs11/Makefile.am | 9 +++++++ 15 files changed, 102 insertions(+), 77 deletions(-) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index df8c7dc5bd..746492dff9 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -8,10 +8,29 @@ dist_noinst_DATA = \ LICENSE.compat_getopt compat_getopt.txt \ compat_getopt_main.c \ README.compat_strlcpy compat_strlcpy.3 +noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h AM_CPPFLAGS = -I$(top_srcdir)/src libcompat_la_SOURCES = \ + compat_dummy.c \ + compat_strlcat.c \ + compat_strlcpy.c \ + compat_strnlen.c \ + compat_getpass.c \ + compat_getopt.c \ + compat_report_rangecheckfailure.c \ + compat___iob_func.c \ + simclist.c + +compat_getopt_main_LDADD = libcompat.la + +libpkcs11_la_SOURCES = libpkcs11.c + +libscdl_la_SOURCES = libscdl.c + +TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +TIDY_FILES = \ compat_dummy.c \ compat_strlcat.h compat_strlcat.c \ compat_strlcpy.h compat_strlcpy.c \ @@ -20,10 +39,8 @@ libcompat_la_SOURCES = \ compat_getopt.h compat_getopt.c \ compat_report_rangecheckfailure.c \ compat___iob_func.c \ - simclist.c simclist.h - -compat_getopt_main_LDADD = libcompat.la - -libpkcs11_la_SOURCES = libpkcs11.c libpkcs11.h + simclist.c simclist.h \ + libpkcs11.c libscdl.c -libscdl_la_SOURCES = libscdl.c libscdl.h +check-local: + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi diff --git a/src/common/simclist.c b/src/common/simclist.c index 58be5e3ed8..33f21e6de9 100644 --- a/src/common/simclist.c +++ b/src/common/simclist.c @@ -764,12 +764,12 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *simclist_restrict de /* fix mid pointer */ err = l2->numels - l1->numels; - if (dest->mid && (err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ + if ((err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ err = (err+1)/2; - for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next; - } else if (dest->mid && err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */ + for (cnt = 0; dest->mid && cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next; + } else if (err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */ err = -err/2; - for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev; + for (cnt = 0; dest->mid && cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev; } assert(!(list_repOk(l1) && list_repOk(l2)) || list_repOk(dest)); diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 6e2db7b1c1..49d122682f 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -106,5 +106,43 @@ endif endif TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +TIDY_FILES = \ + sc.c ctx.c errors.c \ + asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c \ + ef-gdo.c padding.c apdu.c simpletlv.c gp.c \ + \ + pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ + pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ + pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ + \ + muscle.c muscle-filesystem.c \ + \ + ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ + \ + card-setcos.c card-miocos.c card-flex.c card-gpk.c \ + card-cardos.c card-tcos.c card-default.c \ + card-mcrd.c card-starcos.c card-jcop.c \ + card-oberthur.c card-belpic.c card-atrust-acos.c \ + card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ + card-cac-common.c card-cac.c card-cac1.c \ + card-muscle.c card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ + card-rtecp.c card-westcos.c card-myeid.c \ + card-itacns.c card-authentic.c \ + card-iasecc.c iasecc-sdo.c iasecc-sm.c card-sc-hsm.c \ + cwa14890.c cwa-dnie.c \ + card-isoApplet.c card-masktech.c card-jpki.c \ + card-npa.c card-esteid2018.c \ + \ + pkcs15-openpgp.c \ + pkcs15-tcos.c pkcs15-esteid.c \ + pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c \ + pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ + pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ + pkcs15-coolkey.c pkcs15-din-66291.c \ + pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ + compression.c p15card-helper.c sm.c \ + aux-data.c \ + #$(SOURCES) + check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(SOURCES) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 8a72785e62..2a1668d591 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -987,21 +987,6 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - { - char line[256], *linep; - size_t i; - - linep = line; - linep += sprintf(linep, "ef=%d, curpath=", priv->is_ef); - - for (i = 0; i < priv->curpathlen; i++) { - sprintf(linep, "%04X", priv->curpath[i]); - linep += 4; - } - strcpy(linep, "\n"); - sc_log(card->ctx, "%s", line); - } - if (path->type == SC_PATH_TYPE_DF_NAME) { if (path->len > 16) return SC_ERROR_INVALID_ARGUMENTS; @@ -1052,19 +1037,6 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) } } - { - char line[256], *linep = line; - size_t i; - linep += - sprintf(linep, " result=%d, ef=%d, curpath=", r, - priv->is_ef); - for (i = 0; i < priv->curpathlen; i++) { - sprintf(linep, "%04X", priv->curpath[i]); - linep += 4; - } - strcpy(linep, "\n"); - sc_log(card->ctx, "%s", line); - } return r; } diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 2f0ab585cc..45d5008175 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1261,7 +1261,7 @@ static int myeid_transmit_decipher(struct sc_card *card, u8 p1, u8 p2, apdu.le = MIN(card->max_recv_size, crgram_len); } - if (p2 == 0x86 && crgram_len == 256 && !priv->cap_chaining) { + if (p2 == 0x86 && crgram_len == 256 && priv && !priv->cap_chaining) { r = myeid_transmit_decipher_pi_split(card, &apdu, sbuf); } else { apdu.flags |= SC_APDU_FLAGS_CHAINING; @@ -1272,8 +1272,12 @@ static int myeid_transmit_decipher(struct sc_card *card, u8 p1, u8 p2, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "DECIPHER returned error"); - outlen = MIN(apdu.resplen, outlen); - memcpy(out, apdu.resp, outlen); + if (out && outlen) { + outlen = MIN(apdu.resplen, outlen); + memcpy(out, apdu.resp, outlen); + } else { + outlen = 0; + } LOG_FUNC_RETURN(card->ctx, outlen); } diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 2c22500246..e477320e45 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -631,8 +631,10 @@ npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, return SC_ERROR_INTERNAL; } new_len = strlen(p); - if (new_len > EAC_MAX_PIN_LEN) + if (new_len > EAC_MAX_PIN_LEN) { + free(p); return SC_ERROR_INVALID_PIN_LENGTH; + } new = p; #else return SC_ERROR_NOT_SUPPORTED; diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index e5d8b9e691..5c241313da 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -38,6 +38,7 @@ #endif #include "common/libscdl.h" +#include "common/compat_strlcpy.h" #include "internal.h" #include "sc-ossl-compat.h" @@ -995,9 +996,7 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize) conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); cache_dir = scconf_get_str(conf_block, "file_cache_dir", NULL); if (cache_dir != NULL) { - if (bufsize <= strlen(cache_dir)) - return SC_ERROR_BUFFER_TOO_SMALL; - strcpy(buf, cache_dir); + strlcpy(buf, cache_dir, bufsize); return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index ff4c5f9152..c4b19e80cf 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -154,26 +154,23 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) return SC_ERROR_INTERNAL; if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = malloc(strlen(buf2) + 1); + p15card->tokeninfo->serial_number = strdup(buf2); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->serial_number, buf2); /* manufacturer ID */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); + p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); /* card label */ if (p15card->tokeninfo->label) free(p15card->tokeninfo->label); - p15card->tokeninfo->label = malloc(strlen(CARD_LABEL) + 1); + p15card->tokeninfo->label = strdup(CARD_LABEL); if (!p15card->tokeninfo->label) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->label, CARD_LABEL); /* set certs */ for (i = 0; certs[i].label; i++) { diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index 62be8d0134..8c83ddb6a5 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -35,6 +35,7 @@ #include "internal.h" #include "pkcs15.h" +#include "common/compat_strlcpy.h" #define RANDOM_UID_INDICATOR 0x08 static int generate_cache_filename(struct sc_pkcs15_card *p15card, @@ -94,9 +95,9 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card, "%02X", path->value[u + offs]); } - if (!buf || bufsize < strlen(dir)) + if (!buf) return SC_ERROR_BUFFER_TOO_SMALL; - strcpy(buf, dir); + strlcpy(buf, dir, bufsize); return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 60c2e67799..ea3ed19a6e 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -60,18 +60,16 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) return SC_ERROR_INTERNAL; if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = malloc(strlen(buf) + 1); + p15card->tokeninfo->serial_number = strdup(buf); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->serial_number, buf); /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); + p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 6ced63aa7e..074fedd3a4 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -306,17 +306,15 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) if (p15card->tokeninfo->label) free(p15card->tokeninfo->label); - p15card->tokeninfo->label = malloc(strlen(APPLET_NAME) + 1); + p15card->tokeninfo->label = strdup(APPLET_NAME); if (!p15card->tokeninfo->label) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->label, APPLET_NAME); if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = malloc(strlen(DRIVER_SERIAL_NUMBER) + 1); + p15card->tokeninfo->serial_number = strdup(DRIVER_SERIAL_NUMBER); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER); /* the GemSAFE applet version number */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03); @@ -338,10 +336,9 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) /* the manufacturer ID, in this case GemPlus */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); + p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); /* determine allocated key containers and length of certificates */ r = gemsafe_get_cert_len(card); diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 57d8672df8..970d93ef87 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -518,7 +518,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) * user-friendlier card name. */ memset(&dinfo, 0, sizeof(dinfo)); - strcpy(dinfo.app_label, "EF_DatiPersonali"); + strlcpy(dinfo.app_label, "EF_DatiPersonali", sizeof(dinfo.app_label)); /* Find EF_DatiPersonali */ diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 804e85611f..f6394faa2e 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -169,17 +169,15 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) return SC_ERROR_INTERNAL; if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = malloc(strlen(buf) + 1); + p15card->tokeninfo->serial_number = strdup(buf); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->serial_number, buf); /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); + p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; - strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); /* set certs */ for (i = 0; certs[i].label; i++) { diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index eca16adc83..016470796b 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -215,14 +215,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, ti->serial_number = malloc(serial_len * 2 + 1); if (ti->serial_number == NULL) return SC_ERROR_OUT_OF_MEMORY; - - ti->serial_number[0] = 0; - for (ii = 0; ii < serial_len; ii++) { - char byte[3]; - - sprintf(byte, "%02X", serial[ii]); - strcat(ti->serial_number, byte); - } + sc_bin_to_hex(serial, serial_len, ti->serial_number, serial_len * 2 + 1, 0); sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number); } diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 0d7c0439b6..9ea2064811 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -79,3 +79,12 @@ install-exec-hook: done endif + +TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(OPENSC_PKCS11_CFLAGS) +TIDY_FILES = \ + pkcs11-global.c pkcs11-session.c pkcs11-object.c slot.c \ + mechanism.c openssl.c framework-pkcs15.c \ + framework-pkcs15init.c debug.c + +check-local: + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi From 58fa53ac915fc543830dd1595998829844d096b9 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Tue, 4 Jun 2019 13:16:01 +0200 Subject: [PATCH 0915/4321] sc-hsm: Add missing secp384r1 curve parameter --- src/libopensc/pkcs15-sc-hsm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index d1f6a77581..db493c3938 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -61,6 +61,15 @@ static struct ec_curve curves[] = { { (unsigned char *) "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51", 32}, { (unsigned char *) "\x01", 1} }, + { + { (unsigned char *) "\x2B\x81\x04\x00\x22", 5}, // secp384r1 + { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF", 48}, + { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC", 48}, + { (unsigned char *) "\xB3\x31\x2F\xA7\xE2\x3E\xE7\xE4\x98\x8E\x05\x6B\xE3\xF8\x2D\x19\x18\x1D\x9C\x6E\xFE\x81\x41\x12\x03\x14\x08\x8F\x50\x13\x87\x5A\xC6\x56\x39\x8D\x8A\x2E\xD1\x9D\x2A\x85\xC8\xED\xD3\xEC\x2A\xEF", 48}, + { (unsigned char *) "\x04\xAA\x87\xCA\x22\xBE\x8B\x05\x37\x8E\xB1\xC7\x1E\xF3\x20\xAD\x74\x6E\x1D\x3B\x62\x8B\xA7\x9B\x98\x59\xF7\x41\xE0\x82\x54\x2A\x38\x55\x02\xF2\x5D\xBF\x55\x29\x6C\x3A\x54\x5E\x38\x72\x76\x0A\xB7\x36\x17\xDE\x4A\x96\x26\x2C\x6F\x5D\x9E\x98\xBF\x92\x92\xDC\x29\xF8\xF4\x1D\xBD\x28\x9A\x14\x7C\xE9\xDA\x31\x13\xB5\xF0\xB8\xC0\x0A\x60\xB1\xCE\x1D\x7E\x81\x9D\x7A\x43\x1D\x7C\x90\xEA\x0E\x5F", 97}, + { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC7\x63\x4D\x81\xF4\x37\x2D\xDF\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A\xEC\xEC\x19\x6A\xCC\xC5\x29\x73", 48}, + { (unsigned char *) "\x01", 1} + }, { { (unsigned char *) "\x2B\x81\x04\x00\x23", 5}, // secp521r1 { (unsigned char *) "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 66}, From 293760c0d0920a9ede8095762d6f48d38d71f793 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 May 2019 16:27:23 +0200 Subject: [PATCH 0916/4321] Fix derive operation detection in MyEID and sc-hsm drivers --- src/libopensc/card-myeid.c | 2 +- src/libopensc/card-sc-hsm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 45d5008175..6aca72ee49 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1295,7 +1295,7 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, if (priv->sec_env && priv->sec_env->algorithm == SC_ALGORITHM_EC && priv->sec_env->operation == SC_SEC_OPERATION_DERIVE - && priv->sec_env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) + && priv->sec_env->algorithm_flags & SC_ALGORITHM_ECDH_CDH_RAW) { r = myeid_ecdh_derive(card, crgram, crgram_len, out, outlen); priv->sec_env = NULL; /* clear after operation */ diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index eee3cd49cc..5676a4b3b9 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1009,7 +1009,7 @@ static int sc_hsm_set_security_env(sc_card_t *card, priv->algorithm = ALGO_EC_SHA224; } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { priv->algorithm = ALGO_EC_SHA256; - } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { + } else if (env->algorithm_flags & SC_ALGORITHM_ECDH_CDH_RAW) { if (env->operation == SC_SEC_OPERATION_DERIVE) { priv->algorithm = ALGO_EC_DH; } else { From 6d751e8b222cce2a366d2ed177574ba962f3a8a5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 May 2019 17:04:49 +0200 Subject: [PATCH 0917/4321] opensc.h: Add missing raw ecdh algorithm --- src/libopensc/opensc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 31aa1629a1..a65a584aff 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -191,6 +191,7 @@ extern "C" { /* define mask of all algorithms that can do raw */ #define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | \ SC_ALGORITHM_GOSTR3410_RAW | \ + SC_ALGORITHM_ECDH_CDH_RAW | \ SC_ALGORITHM_ECDSA_RAW) /* extended algorithm bits for selected mechs */ From 272e380898e3fdc7864d0651444212e48f7ff348 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 May 2019 17:26:09 +0200 Subject: [PATCH 0918/4321] Set correctly flags for ECDH derive operations --- src/minidriver/minidriver.c | 2 +- src/pkcs11/framework-pkcs15.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 793ce476d3..54e23c5dab 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4877,7 +4877,7 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, DWORD dwret; VENDOR_SPECIFIC *vs; struct sc_pkcs15_object *pkey = NULL; - int r, opt_derive_flags = 0; + int r, opt_derive_flags = SC_ALGORITHM_ECDH_CDH_RAW; u8* out = 0; unsigned long outlen = 0; PBYTE pbPublicKey = NULL; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 57ea18a50d..ed0f677dd9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4263,6 +4263,7 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, CK_ECDH1_DERIVE_PARAMS * ecdh_params = (CK_ECDH1_DERIVE_PARAMS *) pParameters; ulSeedDataLen = ecdh_params->ulPublicDataLen; pSeedData = ecdh_params->pPublicData; + flags = SC_ALGORITHM_ECDH_CDH_RAW; } break; } From 10abef92062bef98f5ccc27058774b399301c2f8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 17 May 2019 09:40:24 +0200 Subject: [PATCH 0919/4321] pkcs15-sec: Drop unused code (copied from RSA decipher) --- src/libopensc/pkcs15-sec.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 1bcf34529a..5aae73b73f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -342,13 +342,6 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, *poutlen); LOG_TEST_RET(ctx, r, "use_key() failed"); - /* Strip any padding */ - if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { - size_t s = r; - r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s); - LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding"); - } - /* If card stores derived key on card, then no data is returned * and the key must be used on the card. */ *poutlen = r; From df0bbc110ef0cb80d855ab273910c82c56e7bae4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 17 May 2019 13:36:32 +0200 Subject: [PATCH 0920/4321] pkcs11-spy: Dump EC Derive parameters --- src/pkcs11/pkcs11-display.c | 10 ++++++++ src/pkcs11/pkcs11-display.h | 1 + src/pkcs11/pkcs11-spy.c | 47 ++++++++++++++++++++++++++++++++++++- src/pkcs11/pkcs11.h | 20 +++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index c15ea025c6..6347320062 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -644,6 +644,15 @@ static enum_specs ck_sta_s[] = { { CKS_RW_SO_FUNCTIONS, "CKS_RW_SO_FUNCTIONS" } }; +static enum_specs ck_ckd_s[] = { + { CKD_NULL, "CKD_NULL" }, + { CKD_SHA1_KDF, "CKD_SHA1_KDF" }, + { CKD_SHA224_KDF, "CKD_SHA224_KDF" }, + { CKD_SHA256_KDF, "CKD_SHA256_KDF" }, + { CKD_SHA384_KDF, "CKD_SHA384_KDF" }, + { CKD_SHA512_KDF, "CKD_SHA512_KDF" }, +}; + #define SZ_SPECS sizeof(enum_specs) enum_spec ck_types[] = { @@ -654,6 +663,7 @@ enum_spec ck_types[] = { { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE"}, { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, + { CKD_T, ck_ckd_s, sizeof(ck_ckd_s) / SZ_SPECS, "CK_EC_KDF_TYPE" }, { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, }; diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 9473ce9c08..53d2e61db4 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -59,6 +59,7 @@ enum ck_type{ MGF_T, USR_T, STA_T, + CKD_T, RV_T }; diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index fc1116923d..8d54cdba55 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -1339,7 +1339,52 @@ C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_H enter("C_DeriveKey"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + fprintf(spy_output, "[in] pMechanism->type=%s\n", + lookup_enum(MEC_T, pMechanism->mechanism)); + switch (pMechanism->mechanism) { + case CKM_ECDH1_DERIVE: + case CKM_ECDH1_COFACTOR_DERIVE: + if (pMechanism->pParameter == NULL) { + fprintf(spy_output, "[in] pMechanism->pParameter = NULL\n"); + break; + } + CK_ECDH1_DERIVE_PARAMS *param = + (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] pMechanism->pParameter = {\n\tkdf=%s\n", + lookup_enum(CKD_T, param->kdf)); + fprintf(spy_output, "\tpSharedData[ulSharedDataLen] = "); + print_generic(spy_output, 0, param->pSharedData, + param->ulSharedDataLen, NULL); + fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + print_generic(spy_output, 0, param->pPublicData, + param->ulPublicDataLen, NULL); + fprintf(spy_output, "}\n"); + break; + case CKM_ECMQV_DERIVE: + if (pMechanism->pParameter == NULL) { + fprintf(spy_output, "[in] pMechanism->pParameter = NULL\n"); + break; + } + CK_ECMQV_DERIVE_PARAMS *param2 = + (CK_ECMQV_DERIVE_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] pMechanism->pParameter = {\n\tkdf=%s\n", + lookup_enum(CKD_T, param2->kdf)); + fprintf(spy_output, "\tpSharedData[ulSharedDataLen] ="); + print_generic(spy_output, 0, param2->pSharedData, + param2->ulSharedDataLen, NULL); + fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + print_generic(spy_output, 0, param2->pPublicData, + param2->ulPublicDataLen, NULL); + fprintf(spy_output, "\tulPrivateDataLen = %lu", + param2->ulPrivateDataLen); + fprintf(spy_output, "\thPrivateData = %lu", param2->hPrivateData); + fprintf(spy_output, "\tpPublicData2[ulPublicDataLen2] = "); + print_generic(spy_output, 0, param2->pPublicData2, + param2->ulPublicDataLen2, NULL); + fprintf(spy_output, "\tpublicKey = %lu", param2->publicKey); + fprintf(spy_output, "}\n"); + break; + } spy_dump_ulong_in("hBaseKey", hBaseKey); spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); rv = po->C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index a3d6d8f7f6..7673d41a99 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -780,7 +780,12 @@ struct ck_mechanism_info #define CKF_DONT_BLOCK (1UL) /* Flags for Key derivation */ -#define CKD_NULL (1UL << 0) +#define CKD_NULL (0x1UL) +#define CKD_SHA1_KDF (0x2UL) +#define CKD_SHA224_KDF (0x5UL) +#define CKD_SHA256_KDF (0x6UL) +#define CKD_SHA384_KDF (0x7UL) +#define CKD_SHA512_KDF (0x8UL) typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned long kdf; @@ -790,6 +795,19 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned char * pPublicData; } CK_ECDH1_DERIVE_PARAMS; +typedef struct CK_ECMQV_DERIVE_PARAMS { + unsigned long kdf; + unsigned long ulSharedDataLen; + unsigned char * pSharedData; + unsigned long ulPublicDataLen; + unsigned char * pPublicData; + unsigned long ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + unsigned long ulPublicDataLen2; + unsigned char * pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_ECMQV_DERIVE_PARAMS; + typedef unsigned long ck_rsa_pkcs_mgf_type_t; typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; From 86fd200462d25e653da3c345ef298540a96caf9b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2019 16:03:07 +0200 Subject: [PATCH 0921/4321] sc-hsm: Check the operation first --- src/libopensc/card-sc-hsm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 5676a4b3b9..ef2f0c17e1 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1001,7 +1001,9 @@ static int sc_hsm_set_security_env(sc_card_t *card, } break; case SC_ALGORITHM_EC: - if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_NONE) { + if (env->operation == SC_SEC_OPERATION_DERIVE) { + priv->algorithm = ALGO_EC_DH; + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_NONE) { priv->algorithm = ALGO_EC_RAW; } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) { priv->algorithm = ALGO_EC_SHA1; @@ -1009,12 +1011,8 @@ static int sc_hsm_set_security_env(sc_card_t *card, priv->algorithm = ALGO_EC_SHA224; } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { priv->algorithm = ALGO_EC_SHA256; - } else if (env->algorithm_flags & SC_ALGORITHM_ECDH_CDH_RAW) { - if (env->operation == SC_SEC_OPERATION_DERIVE) { - priv->algorithm = ALGO_EC_DH; - } else { - priv->algorithm = ALGO_EC_RAW; - } + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { + priv->algorithm = ALGO_EC_RAW; } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } From 852f057ce34a10dcf97bf2ccc2224bf6d6cf467a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2019 18:02:55 +0200 Subject: [PATCH 0922/4321] p11test: Add MD5 mechanisms pretty-print --- src/tests/p11test/p11test_case_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 48206b1ff1..34096388cd 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -597,6 +597,8 @@ const char *get_mechanism_name(int mech_id) return "SHA384_RSA_PKCS_PSS"; case CKM_SHA512_RSA_PKCS_PSS: return "SHA512_RSA_PKCS_PSS"; + case CKM_MD5_HMAC: + return "MD5_HMAC"; case CKM_SHA_1_HMAC: return "SHA_1_HMAC"; case CKM_SHA256_HMAC: @@ -607,6 +609,8 @@ const char *get_mechanism_name(int mech_id) return "SHA512_HMAC"; case CKM_RSA_PKCS_OAEP: return "RSA_PKCS_OAEP"; + case CKM_MD5: + return "MD5"; case CKM_SHA_1: return "SHA_1"; case CKM_SHA224: From 87770df65b8fdaeb5e6b9d127a84137e44804399 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2019 18:03:23 +0200 Subject: [PATCH 0923/4321] p11test: Implement simple derive tests --- src/tests/p11test/Makefile.am | 2 + src/tests/p11test/p11test.c | 5 + src/tests/p11test/p11test_case_common.c | 2 +- src/tests/p11test/p11test_case_ec_derive.c | 264 +++++++++++++++++++++ src/tests/p11test/p11test_case_ec_derive.h | 26 ++ src/tests/p11test/p11test_case_mechs.c | 7 +- src/tests/p11test/p11test_common.h | 1 + 7 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 src/tests/p11test/p11test_case_ec_derive.c create mode 100644 src/tests/p11test/p11test_case_ec_derive.h diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index bbfc96778b..13273b4014 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -9,6 +9,7 @@ noinst_HEADERS = p11test_loader.h p11test_case_common.h \ p11test_case_mechs.h p11test_case_ec_sign.h \ p11test_case_usage.h p11test_case_wait.h \ p11test_case_pss_oaep.h p11test_helpers.h \ + p11test_case_ec_derive.h \ p11test_common.h AM_CPPFLAGS = -I$(top_srcdir)/src @@ -19,6 +20,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_multipart.c \ p11test_case_mechs.c \ p11test_case_ec_sign.c \ + p11test_case_ec_derive.c \ p11test_case_usage.c \ p11test_case_wait.c \ p11test_case_pss_oaep.c \ diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 5e004c62d3..979c0e38fa 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -26,6 +26,7 @@ #include "p11test_case_readonly.h" #include "p11test_case_multipart.h" #include "p11test_case_ec_sign.h" +#include "p11test_case_ec_derive.h" #include "p11test_case_usage.h" #include "p11test_case_mechs.h" #include "p11test_case_wait.h" @@ -77,6 +78,10 @@ int main(int argc, char** argv) { /* Verify that RSA-PSS and RSA-OAEP functions if supported */ cmocka_unit_test_setup_teardown(pss_oaep_test, user_login_setup, after_test_cleanup), + + /* Verify that ECDH key derivation works */ + cmocka_unit_test_setup_teardown(derive_tests, + user_login_setup, after_test_cleanup), }; token.library_path = NULL; diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 34096388cd..58a0d0ec05 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -315,7 +315,7 @@ int callback_public_keys(test_certs_t *objects, const unsigned char *pub, *p; BIGNUM *bn = NULL; EC_POINT *ecpoint; - EC_GROUP *ecgroup; + EC_GROUP *ecgroup = NULL; int nid, pub_len; /* Parse the nid out of the EC_PARAMS */ diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c new file mode 100644 index 0000000000..a53ec66dc5 --- /dev/null +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -0,0 +1,264 @@ +/* + * p11test_case_ec_derive.c: Check the functionality of derive mechanisms + * + * Copyright (C) 2019 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_ec_derive.h" + +unsigned long pkcs11_derive(test_cert_t *o, token_info_t * info, + EC_KEY *key, test_mech_t *mech, unsigned char **secret) +{ + CK_RV rv; + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_ECDH1_DERIVE_PARAMS params = {CKD_NULL, 0, NULL_PTR, 0, NULL_PTR}; + CK_MECHANISM mechanism = { mech->mech, NULL_PTR, 0 }; + const EC_POINT *publickey = NULL; + const EC_GROUP *group = NULL; + CK_OBJECT_HANDLE newkey; + CK_OBJECT_CLASS newkey_class = CKO_SECRET_KEY; + CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET; + CK_BBOOL true = TRUE; + CK_BBOOL false = FALSE; + CK_ATTRIBUTE template[] = { + {CKA_TOKEN, &false, sizeof(false)}, /* session only object */ + {CKA_CLASS, &newkey_class, sizeof(newkey_class)}, + {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)}, + {CKA_SENSITIVE, &false, sizeof(false)}, + {CKA_EXTRACTABLE, &true, sizeof(true)}, + {CKA_ENCRYPT, &true, sizeof(true)}, + {CKA_DECRYPT, &true, sizeof(true)}, + {CKA_WRAP, &true, sizeof(true)}, + {CKA_UNWRAP, &true, sizeof(true)} + }; + CK_ATTRIBUTE get_value = {CKA_VALUE, NULL_PTR, 0}; + CK_ULONG template_len = 9; + unsigned char *pub = NULL; + size_t pub_len; + + /* Conver the public key to the octet string */ + group = EC_KEY_get0_group(key); + publickey = EC_KEY_get0_public_key(key); + pub_len = EC_POINT_point2oct(group, publickey, + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + if (pub_len == 0) { + return 0; + } + pub = malloc(pub_len); + if (pub == NULL) { + return 0; + } + pub_len = EC_POINT_point2oct(group, publickey, + POINT_CONVERSION_UNCOMPRESSED, pub, pub_len, NULL); + + params.pSharedData = NULL; + params.ulSharedDataLen = 0; + params.pPublicData = pub; + params.ulPublicDataLen = pub_len; + + mechanism.pParameter = ¶ms; + mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); + + rv = fp->C_DeriveKey(info->session_handle, &mechanism, o->private_handle, + template, template_len, &newkey); + free(pub); + if (rv != CKR_OK) { + debug_print(" C_DeriveKey: rv = 0x%.8lX\n", rv); + return 0; + } + + /* Lets read the derived data now */ + rv = fp->C_GetAttributeValue(info->session_handle, newkey, + &get_value, 1); + if (rv != CKR_OK) { + fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + return 0; + } + + get_value.pValue = malloc(get_value.ulValueLen); + if (get_value.pValue == NULL) { + fail_msg("malloc failed"); + return 0; + } + + rv = fp->C_GetAttributeValue(info->session_handle, newkey, + &get_value, 1); + if (rv != CKR_OK) { + fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + return 0; + } + + *secret = get_value.pValue; + return get_value.ulValueLen; +} + + +int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) +{ + int nid, field_size, secret_len, pkcs11_secret_len; + EC_KEY *key = NULL; + unsigned char *secret = NULL, *pkcs11_secret = NULL; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 1; + } + + if (o->type != EVP_PK_EC) { + debug_print(" [ KEY %s ] Skip non-EC key for derive", o->id_str); + return 1; + } + + debug_print(" [ KEY %s ] Trying EC derive using CKM_%s and %lu-bit key", + o->id_str, get_mechanism_name(mech->mech), o->bits); + if (o->bits == 256) + nid = NID_X9_62_prime256v1; + else if (o->bits == 384) + nid = NID_secp384r1; + else if (o->bits == 521) + nid = NID_secp521r1; + else { + debug_print(" [ KEY %s ] Skip key of unknown size", o->id_str); + return 1; + } + + /* Generate the peer private key */ + if ((key = EC_KEY_new_by_curve_name(nid)) == NULL || + EC_KEY_generate_key(key) != 1) { + debug_print(" [ KEY %s ] Failed to generate peer private key", o->id_str); + EC_KEY_free(key); + return 1; + } + + /* Calculate the size of the buffer for the shared secret */ + field_size = EC_GROUP_get_degree(EC_KEY_get0_group(key)); + secret_len = (field_size+7)/8; + + /* Allocate the memory for the shared secret */ + if ((secret = OPENSSL_malloc(secret_len)) == NULL) { + debug_print(" [ KEY %s ] Failed to generate peer private key", o->id_str); + EC_KEY_free(key); + return 1; + } + + /* Derive the shared secret locally */ + secret_len = ECDH_compute_key(secret, secret_len, + EC_KEY_get0_public_key(o->key.ec), key, NULL); + + /* Try to do the same with the card key */ + pkcs11_secret_len = pkcs11_derive(o, info, key, mech, &pkcs11_secret); + + if (secret_len == pkcs11_secret_len && memcmp(secret, pkcs11_secret, secret_len) == 0) { + mech->result_flags |= FLAGS_DERIVE; + debug_print(" [ OK %s ] Derived secrets match", o->id_str); + OPENSSL_free(secret); + free(pkcs11_secret); + return 0; + } + + debug_print(" [ KEY %s ] Derived secret does not match", o->id_str); + OPENSSL_free(secret); + free(pkcs11_secret); + return 1; +} + + +void derive_tests(void **state) { + unsigned int i; + int j; + int errors = 0; + token_info_t *info = (token_info_t *) *state; + + test_certs_t objects; + objects.count = 0; + objects.data = NULL; + + P11TEST_START(info); + search_for_all_objects(&objects, info); + + debug_print("Check if the key derivation works.\n"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + /* Ignore if there is missing private key */ + if (objects.data[i].private_handle == CK_INVALID_HANDLE) + continue; + + /* Skip the non EC keys */ + if (objects.data[i].key_type != CKK_EC) + continue; + + for (j = 0; j < o->num_mechs; j++) { + if ((o->mechs[j].usage_flags & CKF_DERIVE) == 0 + || ! o->derive_priv) + continue; + errors += test_derive(&(objects.data[i]), info, + &(o->mechs[j])); + } + } + + /* print summary */ + printf("[KEY ID] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [ PUBLIC ] [ DERIVE ]\n"); + P11TEST_DATA_ROW(info, 3, + 's', "KEY ID", + 's', "MECHANISM", + 's', "DERIVE WORKS"); + for (i = 0; i < objects.count; i++) { + if (objects.data[i].key_type != CKK_EC) + continue; + + test_cert_t *o = &objects.data[i]; + printf("\n[%-6s] [%s]\n", + o->id_str, + o->label); + printf("[ EC ] [%6lu] [ %s ] [ %s%s ]\n", + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->derive_pub ? "[./]" : "[ ]", + o->derive_priv ? "[./]" : "[ ]"); + if (!o->derive_pub && !o->derive_priv) { + printf(" no usable attributes found ... ignored\n"); + continue; + } + if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + continue; + } + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; + if ((mech->usage_flags & CKF_DERIVE) == 0) { + /* not applicable mechanisms are skipped */ + continue; + } + printf(" [ %-23s ] [ %s ]\n", + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_DERIVE ? "[./]" : " "); + if ((mech->result_flags & FLAGS_DERIVE) == 0) + continue; /* skip empty rows for export */ + P11TEST_DATA_ROW(info, 4, + 's', o->id_str, + 's', get_mechanism_name(mech->mech), + 's', mech->result_flags & FLAGS_DERIVE ? "YES" : ""); + } + } + printf(" Public == Cert -----^ ^\n"); + printf(" ECDH Derive functionality -----'\n"); + + clean_all_objects(&objects); + if (errors > 0) + P11TEST_FAIL(info, "Not all the derive mechanisms worked."); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_ec_derive.h b/src/tests/p11test/p11test_case_ec_derive.h new file mode 100644 index 0000000000..ea21cee969 --- /dev/null +++ b/src/tests/p11test/p11test_case_ec_derive.h @@ -0,0 +1,26 @@ +/* + * p11test_case_ec_derive.h: Check the functionality of derive mechanisms + * + * Copyright (C) 2019 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void derive_tests(void **state); + diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index b8b31ee3e3..22dcfc9ecc 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -89,7 +89,11 @@ void supported_mechanisms_test(void **state) { || mechanism_list[i] == CKM_ECDSA_SHA1 || mechanism_list[i] == CKM_ECDSA_SHA256 || mechanism_list[i] == CKM_ECDSA_SHA384 - || mechanism_list[i] == CKM_ECDSA_SHA512) { + || mechanism_list[i] == CKM_ECDSA_SHA512 + /* Including derive mechanisms */ + || mechanism_list[i] == CKM_ECDH1_DERIVE + || mechanism_list[i] == CKM_ECDH1_COFACTOR_DERIVE + || mechanism_list[i] == CKM_ECMQV_DERIVE) { if (token.num_ec_mechs < MAX_MECHS) { mech = &token.ec_mechs[token.num_ec_mechs++]; mech->mech = mechanism_list[i]; @@ -97,6 +101,7 @@ void supported_mechanisms_test(void **state) { } else P11TEST_FAIL(info, "Too many EC mechanisms (%d)", MAX_MECHS); } + if ((mechanism_info[i].flags & CKF_GENERATE_KEY_PAIR) != 0) { if (token.num_keygen_mechs < MAX_MECHS) { mech = &token.keygen_mechs[token.num_keygen_mechs++]; diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index d3ca304d83..2f3b238de0 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -46,6 +46,7 @@ #define FLAGS_DECRYPT 0x04 #define FLAGS_DECRYPT_OPENSSL 0x08 #define FLAGS_DECRYPT_ANY ( FLAGS_DECRYPT | FLAGS_DECRYPT_OPENSSL ) +#define FLAGS_DERIVE 0x10 typedef struct { char *outfile; From b65275d6f8275abd86f1b0c0976b1cfd324fc16c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 May 2019 15:46:41 +0200 Subject: [PATCH 0924/4321] p11test: Improve error reporting on unknown EC groups --- src/tests/p11test/p11test_case_common.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 58a0d0ec05..bd63458ac7 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -321,9 +321,24 @@ int callback_public_keys(test_certs_t *objects, /* Parse the nid out of the EC_PARAMS */ p = template[6].pValue; oid = d2i_ASN1_OBJECT(NULL, &p, template[6].ulValueLen); + if (oid == NULL) { + debug_print(" [WARN %s ] Failed to convert EC_PARAMS" + " to OpenSSL format", o->id_str); + return -1; + } nid = OBJ_obj2nid(oid); ASN1_OBJECT_free(oid); + if (nid == NID_undef) { + debug_print(" [WARN %s ] Failed to convert EC_PARAMS" + " to NID", o->id_str); + return -1; + } ecgroup = EC_GROUP_new_by_curve_name(nid); + if (ecgroup == NULL) { + debug_print(" [WARN %s ] Failed to create new EC_GROUP" + " from NID", o->id_str); + return -1; + } EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); p = template[7].pValue; @@ -334,7 +349,7 @@ int callback_public_keys(test_certs_t *objects, ASN1_STRING_free(s); if (bn == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" - "PKCS#11 to BIGNUM", o->id_str); + " PKCS#11 to BIGNUM", o->id_str); EC_GROUP_free(ecgroup); return -1; } @@ -343,7 +358,7 @@ int callback_public_keys(test_certs_t *objects, BN_free(bn); if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" - "BIGNUM to OpenSSL format", o->id_str); + " BIGNUM to OpenSSL format", o->id_str); EC_GROUP_free(ecgroup); return -1; } From 07c0a47b37761e90c4b1afaef5af41cb2d5b3d2c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 May 2019 15:49:58 +0200 Subject: [PATCH 0925/4321] card-openpgp: Fix typo in the EC Key size --- src/libopensc/card-openpgp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cce2c96669..efb6a77ed3 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -160,8 +160,8 @@ static struct pgp_supported_ec_curves { {{0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, -1}}}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 34, -1}}, 384, {{0x2b, 0x81, 0x04, 0x00, 0x22, -1}}}, /* ansiX9p384r1 */ - {{{1, 3, 132, 0, 35, -1}}, 512, - {{0x2b, 0x81, 0x04, 0x00, 0x23, -1}}}, /* ansiX9p512r1 */ + {{{1, 3, 132, 0, 35, -1}}, 521, + {{0x2b, 0x81, 0x04, 0x00, 0x23, -1}}}, /* ansiX9p521r1 */ {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256, {{0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, -1}}}, /* brainpoolP256r1 */ {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384, @@ -2516,7 +2516,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, *p = 0x09; /* KDF algo */ *(p+1) = 0x08; /* KEK algo */ } - else { /* ec bit size = 512 */ + else { /* ec bit size = 512 or 521*/ *p = 0x0a; /* KDF algo */ *(p+1) = 0x09; /* KEK algo */ } From 9197dfe5aecb2abb13d097dfb3fd9553212990da Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 Jun 2019 11:32:40 +0200 Subject: [PATCH 0926/4321] myeid: Detect also OsEID card in the MyEID driver and difference them with separate types --- src/libopensc/card-myeid.c | 29 ++++++++++++++++++++++++----- src/libopensc/cards.h | 1 + 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 6aca72ee49..db22709f6f 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -63,6 +63,7 @@ #define MYEID_MAX_EXT_APDU_BUFFER_SIZE (MYEID_MAX_RSA_KEY_LEN/8+16) static const char *myeid_card_name = "MyEID"; +static const char *oseid_card_name = "OsEID"; static char card_name_buf[MYEID_CARD_NAME_MAX_LEN]; static struct sc_card_operations myeid_ops; @@ -114,12 +115,21 @@ static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_cap static int myeid_match_card(struct sc_card *card) { + size_t len = card->reader->atr_info.hist_bytes_len; /* Normally the historical bytes are exactly "MyEID", but there might * be some historic units which have a small prefix byte sequence. */ - if (card->reader->atr_info.hist_bytes_len >= 5 && - !memcmp(&card->reader->atr_info.hist_bytes[card->reader->atr_info.hist_bytes_len - 5], "MyEID", 5)) { - card->type = SC_CARD_TYPE_MYEID_GENERIC; - return 1; + if (len >= 5) { + if (!memcmp(&card->reader->atr_info.hist_bytes[len - 5], "MyEID", 5)) { + sc_log(card->ctx, "Matched MyEID card"); + card->type = SC_CARD_TYPE_MYEID_GENERIC; + return 1; + } + /* The software implementation of MyEID is identified by OsEID bytes */ + if (!memcmp(&card->reader->atr_info.hist_bytes[len - 5], "OsEID", 5)) { + sc_log(card->ctx, "Matched OsEID card"); + card->type = SC_CARD_TYPE_MYEID_OSEID; + return 1; + } } return 0; } @@ -169,7 +179,16 @@ static int myeid_init(struct sc_card *card) LOG_FUNC_CALLED(card->ctx); - card->name = myeid_card_name; + switch (card->type) { + case SC_CARD_TYPE_MYEID_OSEID: + card->name = oseid_card_name; + break; + case SC_CARD_TYPE_MYEID_GENERIC: + card->name = myeid_card_name; + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } priv = calloc(1, sizeof(myeid_private_data_t)); diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 5b4ee05fa8..ebe783b535 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -178,6 +178,7 @@ enum { /* MyEID cards */ SC_CARD_TYPE_MYEID_BASE = 20000, SC_CARD_TYPE_MYEID_GENERIC, + SC_CARD_TYPE_MYEID_OSEID, /* GemsafeV1 cards */ SC_CARD_TYPE_GEMSAFEV1_BASE = 21000, From 1c0d26d0f0d8570e619ac1bc279914da9c2f12b5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 May 2019 12:49:18 +0200 Subject: [PATCH 0927/4321] .travis.yml Include the MyEID emulation using OsEID simulator in separate target This also avoids running the make check in the simulation runs, which generates a lot of output (from clang-tidy) --- .travis.yml | 63 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0e4080cd5e..893cbef88d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,14 @@ matrix: - compiler: gcc os: linux env: - - DO_SIMULATION=yes + - DO_SIMULATION=javacard - ENABLE_DOC=--enable-doc sudo: true + - compiler: gcc + os: linux + env: + - DO_SIMULATION=oseid + sudo: true - env: - HOST=x86_64-w64-mingw32 - DO_PUSH_ARTIFACT=yes @@ -48,12 +53,13 @@ addons: - libcmocka-dev - help2man - pcscd + - pcsc-tools - check before_install: # brew install gengetopt help2man cmocka ccache llvm; # export PATH="/usr/local/opt/ccache/libexec:/usr/local/opt/llvm/bin:$PATH"; - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then + - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew uninstall libtool; brew install libtool; @@ -62,13 +68,13 @@ before_install: fi before_script: - - if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then + - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then ./bootstrap; fi - - if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then + - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then ./bootstrap.ci -s "-pr$TRAVIS_PULL_REQUEST"; fi - - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then + - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then ./bootstrap.ci -s "-$TRAVIS_BRANCH"; fi - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then @@ -91,7 +97,7 @@ before_script: # On error (propably quota is exhausted), just continue - if [ "${DO_COVERITY_SCAN}" = "yes" ]; then curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash || true; fi - - if [ "${DO_SIMULATION}" = "yes" ]; then + - if [ "${DO_SIMULATION}" = "javacard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git; cd vsmartcard/virtualsmartcard; autoreconf -vis && ./configure && sudo make install; @@ -144,15 +150,34 @@ before_script: cd $TRAVIS_BUILD_DIR; fi + - if [ "${DO_SIMULATION}" = "oseid" ]; then + git clone https://github.com/popovec/oseid; + cd oseid/src/; + make -f Makefile.console; + mkdir tmp; + socat -d -d pty,link=tmp/OsEIDsim.socket,raw,echo=0 "exec:build/console/console ...,pty,raw,echo=0" & + sleep 1; + echo "# OsEIDsim" > tmp/reader.conf; + echo 'FRIENDLYNAME "OsEIDsim"' >> tmp/reader.conf; + echo "DEVICENAME ${TRAVIS_BUILD_DIR}/oseid/src/tmp/OsEIDsim.socket" >> tmp/reader.conf; + echo "LIBPATH ${TRAVIS_BUILD_DIR}/oseid/src/build/console/libOsEIDsim.so.0.0.1" >> tmp/reader.conf; + echo "CHANNELID 1" >> tmp/reader.conf; + sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf; + cat /etc/reader.conf.d/reader.conf; + cd $TRAVIS_BUILD_DIR; + + sudo /etc/init.d/pcscd restart; + fi + script: - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then - if [ $TRAVIS_OS_NAME == osx ]; then + if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./MacOSX/build; else make -j 4; fi; fi - - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then + - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" -a -z "$DO_SIMULATION" ]; then make check && make dist; fi - if [ ! -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then @@ -160,7 +185,7 @@ script: wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss; fi - - if [ "${DO_SIMULATION}" = "yes" ]; then + - if [ "${DO_SIMULATION}" = "javacard" ]; then set -ex; sudo make install; export LD_LIBRARY_PATH=/usr/local/lib; @@ -199,6 +224,26 @@ script: yubico-piv-tool -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048; pkcs11-tool -l -t -p 123456; killall java; + + set +ex; + fi + + - if [ "${DO_SIMULATION}" = "oseid" ]; then + set -ex; + sudo make install; + export LD_LIBRARY_PATH=/usr/local/lib; + + cd oseid/tools; + echo | ./OsEID-tool INIT; + ./OsEID-tool RSA-CREATE-KEYS; + ./OsEID-tool RSA-UPLOAD-KEYS; + ./OsEID-tool RSA-DECRYPT-TEST; + ./OsEID-tool EC-CREATE-KEYS; + ./OsEID-tool EC-UPLOAD-KEYS; + ./OsEID-tool EC-SIGN-TEST; + ./OsEID-tool EC-ECDH-TEST; + killall socat; + set +ex; fi From 368563ddd61103ec4e6aa47a69eec9fe80f51a64 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 30 May 2019 09:37:42 +0200 Subject: [PATCH 0928/4321] doc: Fix the description of switch in manual page (copy&paste error) --- doc/tools/opensc-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index 9252d0ce0b..f362a37636 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -108,7 +108,7 @@ conf, conf - Get configuration key, format: section:name:key:value + Set configuration key, format: section:name:key:value From 8c12835c9ec89244a94f4dc839e5567362c75122 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 Jun 2019 10:31:27 +0200 Subject: [PATCH 0929/4321] Update the build status also in the readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 27dfebcbee..40ba98010b 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,4 @@ Build and test status of specific cards: | [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | | [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | | [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | From 19711d0a1301f0519a1348390bb996fd2925f766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 10 Jun 2019 13:44:30 +0300 Subject: [PATCH 0930/4321] myeid: fix EC key upload, and avoid data copying Fixes regression from commit 3688dfe which did not consider that the zero prefixing tests were too generic and matched EC keys too. This simplifies the code even further and avoids data copying when possible. Proper test is now included to do data value prefixing only for the RSA keys it is needed. Closes #1701. --- src/libopensc/card-myeid.c | 42 ++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index db22709f6f..d4ed17c483 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1460,36 +1460,27 @@ static int myeid_loadkey(sc_card_t *card, unsigned mode, u8* value, int value_le myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data; sc_apdu_t apdu; u8 sbuf[MYEID_MAX_EXT_APDU_BUFFER_SIZE]; - int r, len; + int r; LOG_FUNC_CALLED(card->ctx); - len = 0; if (value_len == 0 || value == NULL) return 0; - if (value[0] != 0x0 && - mode != LOAD_KEY_PUBLIC_EXPONENT && - mode != LOAD_KEY_SYMMETRIC) - sbuf[len++] = 0x0; - if (mode == LOAD_KEY_MODULUS && value_len == 256 && !priv->cap_chaining) { if ((value_len % 2) > 0 && value[0] == 0x00) { value_len--; - memmove(value, value + 1, value_len); + value++; } - mode = 0x88; - len = 128; - memcpy(sbuf,value, 128); - + mode = 0x88; memset(&apdu, 0, sizeof(apdu)); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode); apdu.cla = 0x00; - apdu.data = sbuf; - apdu.datalen = len; - apdu.lc = len; + apdu.data = value; + apdu.datalen = 128; + apdu.lc = 128; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -1498,23 +1489,26 @@ static int myeid_loadkey(sc_card_t *card, unsigned mode, u8* value, int value_le LOG_TEST_RET(card->ctx, r, "LOAD KEY returned error"); mode = 0x89; - len = value_len - 128; - memset(&sbuf, 0, SC_MAX_APDU_BUFFER_SIZE); - memcpy(sbuf,value + 128, value_len - 128); + value += 128; + value_len -= 128; } - else + else if ((mode & 0xff00) == 0 && mode != LOAD_KEY_PUBLIC_EXPONENT && + value[0] != 0x00) { - memcpy(sbuf + len, value, value_len); - len += value_len; + /* RSA components needing leading zero byte */ + sbuf[0] = 0x0; + memcpy(&sbuf[1], value, value_len); + value = sbuf; + value_len ++; } memset(&apdu, 0, sizeof(apdu)); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode & 0xFF); apdu.flags = SC_APDU_FLAGS_CHAINING; apdu.cla = 0x00; - apdu.data = sbuf; - apdu.datalen = len; - apdu.lc = len; + apdu.data = value; + apdu.datalen = value_len; + apdu.lc = value_len; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); From 229dd32e3affd3fbe7bdaae9fea213d400435073 Mon Sep 17 00:00:00 2001 From: Peter Marschall Date: Thu, 20 Jun 2019 18:33:22 +0200 Subject: [PATCH 0931/4321] opensc-explorer: fix APDU command Do not ignore first parameter. --- src/tools/opensc-explorer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 25c88be8e0..41e620a56b 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1840,7 +1840,7 @@ static int do_apdu(int argc, char **argv) return usage(do_apdu); /* loop over the args and parse them, making sure the result fits into buf[] */ - for (i = 1, len = 0; i < (unsigned) argc && len < sizeof(buf); i++) { + for (i = 0, len = 0; i < (unsigned) argc && len < sizeof(buf); i++) { size_t len0 = sizeof(buf) - len; if ((r = parse_string_or_hexdata(argv[i], buf + len, &len0)) < 0) { From e7a8c00566bc2ff8384b7b02f73d780a201e1af6 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Wed, 19 Jun 2019 09:41:01 +0200 Subject: [PATCH 0932/4321] sc-hsm: Use CHR in CSR based on device serial number --- src/pkcs15init/pkcs15-sc-hsm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 60b6a82dfc..0bc7a9b715 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -39,6 +39,7 @@ #include "../libopensc/pkcs15.h" #include "common/compat_strlcpy.h" +#include "common/compat_strlcat.h" #include "pkcs15-init.h" #include "profile.h" @@ -247,6 +248,7 @@ static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card struct sc_pkcs15_pubkey *pubkey) { struct sc_card *card = p15card->card; + sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; sc_cardctl_sc_hsm_keygen_info_t sc_hsm_keyinfo; sc_cvc_t cvc; @@ -263,7 +265,8 @@ static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card memset(&cvc, 0, sizeof(cvc)); strlcpy(cvc.car, "UTCA00001", sizeof cvc.car); - strlcpy(cvc.chr, "UTTM00001", sizeof cvc.chr); + strlcpy(cvc.chr, priv->serialno, sizeof cvc.chr); + strlcat(cvc.chr, "00001", sizeof cvc.chr); switch(object->type) { case SC_PKCS15_TYPE_PRKEY_RSA: From 7fb72ccf7bf3ca2ff3979b7ffbb690eed41ddb5f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 14 Jun 2019 07:54:39 +0200 Subject: [PATCH 0933/4321] pkcs11: fixed slotIDs when a new slot list is requested fixes https://github.com/OpenSC/OpenSC/issues/1706 regression of 24b7507a69704f69e371834953cf78cffec104b0 --- src/pkcs11/pkcs11-global.c | 22 +++++++++++++++++++++- src/pkcs11/slot.c | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index c3cf259131..d8c0df5fed 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -451,8 +451,13 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese pSlotList==NULL_PTR? "plug-n-play":"refresh"); /* Slot list can only change in v2.20 */ - if (pSlotList == NULL_PTR) + if (pSlotList == NULL_PTR) { sc_ctx_detect_readers(context); + for (i=0; iflags &= ~SC_PKCS11_SLOT_FLAG_SEEN; + } + } card_detect_all(); @@ -483,6 +488,21 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese prev_reader = slot->reader; } + /* Slot list can only change in v2.20 */ + if (pSlotList == NULL_PTR) { + /* slot->id is derived from its location in the list virtual_slots. + * When the slot list changes, so does slot->id, so we reindex the + * slots here the same way it is done in `create_slot()` + * + * TODO use a persistent CK_SLOT_ID, e.g. by using something like + * `slot->id = sc_crc32(slot, sizeof *slot);` (this example, however, + * is currently not thread safe). */ + for (i=0; iid = (CK_SLOT_ID) list_locate(&virtual_slots, slot); + } + } + if (pSlotList == NULL_PTR) { sc_log(context, "was only a size inquiry (%lu)\n", numMatches); *pulCount = numMatches; diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 44b041eeea..c74f2c0a0e 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -115,7 +115,6 @@ CK_RV create_slot(sc_reader_t *reader) } slot->login_user = -1; - slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot); init_slot_info(&slot->slot_info, reader); sc_log(context, "Initializing slot with id 0x%lx", slot->id); @@ -126,6 +125,7 @@ CK_RV create_slot(sc_reader_t *reader) slot->slot_info.hardwareVersion.major = reader->version_major; slot->slot_info.hardwareVersion.minor = reader->version_minor; } + slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot); return CKR_OK; } From 60a2cf16c7305c2ee8981ea49bff4d3a18ee87df Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Thu, 20 Jun 2019 18:09:50 +0300 Subject: [PATCH 0934/4321] card-rtecp: Fix list_files on T0 cards Rutoken ECP SC over T0 expects Get Response after SW1=61 which is not called with zero le. --- src/libopensc/card-rtecp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 1eae6e1ce6..a256b51409 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -567,7 +567,7 @@ static int rtecp_create_file(sc_card_t *card, sc_file_t *file) static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) { sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE], previd[2]; + u8 rbuf[SC_MAX_APDU_RESP_SIZE], previd[2]; const u8 *tag; size_t taglen, len = 0; int r; @@ -578,7 +578,7 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) { apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = 256; + apdu.le = sizeof(rbuf); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) @@ -610,7 +610,11 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) if (tag[0] == 0x38) { /* Select parent DF of the current DF */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x03, 0); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x03, 0); + /* We should set le and resp buf to actually call Get Response for card on T0. */ + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = sizeof(rbuf); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); From 3c1624676d486c951cc101a32a5b20ec31e2b52f Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Mon, 1 Jul 2019 14:15:10 +0300 Subject: [PATCH 0935/4321] card-rtecp,card-rutoken: Set specific card types --- src/libopensc/card-rtecp.c | 8 ++++---- src/libopensc/card-rutoken.c | 4 ++-- src/libopensc/cards.h | 5 +++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index a256b51409..bff77be010 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -44,18 +44,18 @@ static struct sc_card_driver rtecp_drv = { static const struct sc_atr_table rtecp_atrs[] = { /* Rutoken ECP */ { "3B:8B:01:52:75:74:6F:6B:65:6E:20:45:43:50:A0", - NULL, "Rutoken ECP", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + NULL, "Rutoken ECP", SC_CARD_TYPE_RUTOKEN_ECP, 0, NULL }, /* Rutoken ECP (DS) */ { "3B:8B:01:52:75:74:6F:6B:65:6E:20:44:53:20:C1", - NULL, "Rutoken ECP (DS)", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + NULL, "Rutoken ECP (DS)", SC_CARD_TYPE_RUTOKEN_ECP, 0, NULL }, /* Rutoken ECP SC T0 */ { "3B:9C:96:00:52:75:74:6F:6B:65:6E:45:43:50:73:63", "00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF", - "Rutoken ECP SC", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + "Rutoken ECP SC", SC_CARD_TYPE_RUTOKEN_ECP_SC, 0, NULL }, /* Rutoken ECP SC T1 */ { "3B:9C:94:80:11:40:52:75:74:6F:6B:65:6E:45:43:50:73:63:C3", "00:00:00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00", - "Rutoken ECP SC", SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + "Rutoken ECP SC", SC_CARD_TYPE_RUTOKEN_ECP_SC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 49cc9db2bb..918031957f 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -85,8 +85,8 @@ static struct sc_card_driver rutoken_drv = { }; static const struct sc_atr_table rutoken_atrs[] = { - { "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv Rutoken S */ - { "3b:6f:00:ff:00:56:75:61:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv uaToken S */ + { "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_RUTOKENS, 0, NULL }, /* Aktiv Rutoken S */ + { "3b:6f:00:ff:00:56:75:61:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_RUTOKENS, 0, NULL }, /* Aktiv uaToken S */ { NULL, NULL, NULL, 0, 0, NULL } }; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index ebe783b535..55f91a7910 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -252,6 +252,11 @@ enum { /* EstEID cards */ SC_CARD_TYPE_ESTEID = 35000, SC_CARD_TYPE_ESTEID_2018, + + /* Rutoken cards */ + SC_CARD_TYPE_RUTOKENS = 36000, + SC_CARD_TYPE_RUTOKEN_ECP, + SC_CARD_TYPE_RUTOKEN_ECP_SC, }; extern sc_card_driver_t *sc_get_default_driver(void); From 6b97071bb383cdc037a4a76fa4e82b6c4a3a6434 Mon Sep 17 00:00:00 2001 From: programatix Date: Thu, 4 Jul 2019 09:58:29 +0800 Subject: [PATCH 0936/4321] Update strings.c The check condition is obviously wrong. It should check for EQUAL. The original bitwise check caused any other language to turn into DE because as long as a bit is filtered, it will hit. --- src/ui/strings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/strings.c b/src/ui/strings.c index 446e199ced..cc3418ca9e 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -157,7 +157,7 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, || !find_lang_str(p15card->tokeninfo->preferred_language, &lang)) { #ifdef _WIN32 LANGID langid = GetUserDefaultUILanguage(); - if (langid & LANG_GERMAN) { + if (langid == LANG_GERMAN) { lang = DE; } #else From 130e9bb068401ec78461777695f3e3273fcc4a13 Mon Sep 17 00:00:00 2001 From: programatix Date: Thu, 4 Jul 2019 15:18:22 +0800 Subject: [PATCH 0937/4321] Update strings.c --- src/ui/strings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/strings.c b/src/ui/strings.c index cc3418ca9e..ea1d3ba650 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -157,7 +157,7 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, || !find_lang_str(p15card->tokeninfo->preferred_language, &lang)) { #ifdef _WIN32 LANGID langid = GetUserDefaultUILanguage(); - if (langid == LANG_GERMAN) { + if ((langid & LANG_GERMAN) == LANG_GERMAN) { lang = DE; } #else From ba19a467e4b60cd51e458a15a3bcb21f14ab32bc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jul 2019 13:05:32 +0200 Subject: [PATCH 0938/4321] Rutoken Lite (#1728) * card-rtecp: Add Rutoken Lite * avoid seperate rutoken lite driver * added rutoken lite to minidriver closes #1722 --- src/libopensc/card-rtecp.c | 30 ++++- src/libopensc/cards.h | 2 + src/pkcs15init/Makefile.am | 1 + src/pkcs15init/pkcs15-lib.c | 1 + src/pkcs15init/rutoken_lite.profile | 202 ++++++++++++++++++++++++++++ win32/OpenSC.wxs.in | 4 + win32/customactions.cpp | 4 + 7 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 src/pkcs15init/rutoken_lite.profile diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index bff77be010..eae1ff655a 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -1,5 +1,5 @@ /* - * card-rtecp.c: Support for Rutoken ECP cards + * card-rtecp.c: Support for Rutoken ECP and Rutoken Lite cards * * Copyright (C) 2009 Aleksey Samsonov * @@ -35,7 +35,7 @@ static const struct sc_card_operations *iso_ops = NULL; static struct sc_card_operations rtecp_ops; static struct sc_card_driver rtecp_drv = { - "Rutoken ECP driver", + "Rutoken ECP and Lite driver", "rutoken_ecp", &rtecp_ops, NULL, 0, NULL @@ -56,6 +56,13 @@ static const struct sc_atr_table rtecp_atrs[] = { { "3B:9C:94:80:11:40:52:75:74:6F:6B:65:6E:45:43:50:73:63:C3", "00:00:00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00", "Rutoken ECP SC", SC_CARD_TYPE_RUTOKEN_ECP_SC, 0, NULL }, + /* Rutoken Lite */ + { "3B:8B:01:52:75:74:6F:6B:65:6E:6C:69:74:65:C2", + NULL, "Rutoken Lite", SC_CARD_TYPE_RUTOKEN_LITE, 0, NULL }, + /* Rutoken Lite SC*/ + { "3B:9E:96:00:52:75:74:6F:6B:65:6E:4C:69:74:65:53:43:32", + "00:00:00:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF", + "Rutoken Lite SC", SC_CARD_TYPE_RUTOKEN_LITE_SC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -76,9 +83,14 @@ static int rtecp_init(sc_card_t *card) unsigned long flags; assert(card && card->ctx); - card->caps |= SC_CARD_CAP_RNG; card->cla = 0; + if (card->type == SC_CARD_TYPE_RUTOKEN_LITE + || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0); + + card->caps |= SC_CARD_CAP_RNG; + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_NONE | SC_ALGORITHM_RSA_HASH_NONE; @@ -422,6 +434,11 @@ static int rtecp_decipher(sc_card_t *card, int r; assert(card && card->ctx && data && out); + + if (card->type == SC_CARD_TYPE_RUTOKEN_LITE + || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + /* decipher */ r = rtecp_cipher(card, data, data_len, out, out_len, 0); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -433,6 +450,11 @@ static int rtecp_compute_signature(sc_card_t *card, int r; assert(card && card->ctx && data && out); + + if (card->type == SC_CARD_TYPE_RUTOKEN_LITE + || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + /* compute digital signature */ r = rtecp_cipher(card, data, data_len, out, out_len, 1); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -811,7 +833,5 @@ struct sc_card_driver * sc_get_rtecp_driver(void) /* process_fci */ rtecp_ops.construct_fci = rtecp_construct_fci; rtecp_ops.pin_cmd = NULL; - return &rtecp_drv; } - diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 55f91a7910..39cb2a6787 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -257,6 +257,8 @@ enum { SC_CARD_TYPE_RUTOKENS = 36000, SC_CARD_TYPE_RUTOKEN_ECP, SC_CARD_TYPE_RUTOKEN_ECP_SC, + SC_CARD_TYPE_RUTOKEN_LITE, + SC_CARD_TYPE_RUTOKEN_LITE_SC, }; extern sc_card_driver_t *sc_get_default_driver(void); diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index eadf8df1c2..1ff594c0a5 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -23,6 +23,7 @@ dist_pkgdata_DATA = \ entersafe.profile \ epass2003.profile \ rutoken_ecp.profile \ + rutoken_lite.profile \ westcos.profile \ myeid.profile \ authentic.profile \ diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 6b4c72ed33..bcc54bd98c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -157,6 +157,7 @@ static struct profile_operations { { "entersafe",(void*) sc_pkcs15init_get_entersafe_ops }, { "epass2003",(void*) sc_pkcs15init_get_epass2003_ops }, { "rutoken_ecp", (void *) sc_pkcs15init_get_rtecp_ops }, + { "rutoken_lite", (void *) sc_pkcs15init_get_rtecp_ops }, { "westcos", (void *) sc_pkcs15init_get_westcos_ops }, { "myeid", (void *) sc_pkcs15init_get_myeid_ops }, { "sc-hsm", (void *) sc_pkcs15init_get_sc_hsm_ops }, diff --git a/src/pkcs15init/rutoken_lite.profile b/src/pkcs15init/rutoken_lite.profile new file mode 100644 index 0000000000..60c924e14f --- /dev/null +++ b/src/pkcs15init/rutoken_lite.profile @@ -0,0 +1,202 @@ +# +# PKCS15 profile, generic information. +# This profile is loaded before any card specific profile. +# + +cardinfo { + label = "Rutoken Lite"; + manufacturer = "Aktiv Co."; + + max-pin-length = 32; + min-pin-length = 1; + pin-encoding = ascii-numeric; +} + +# +# The following controls some aspects of the PKCS15 we put onto +# the card. +# +pkcs15 { + # Put certificates into the CDF itself? + direct-certificates = no; + # Put the DF length into the ODF file? + encode-df-length = no; + # Have a lastUpdate field in the EF(TokenInfo)? + do-last-update = yes; + + pkcs15-id-style = mozilla; +} + +# Default settings. +# This option block will always be processed. +option default { + macros { + ti-size = 128; + odf-size = 128; + aodf-size = 256; + dodf-size = 2048; + cdf-size = 2048; + prkdf-size = 2048; + pukdf-size = 2048; + } +} + +# Define reasonable limits for PINs and PUK +# Note that we do not set a file path or reference +# for the user pin; that is done dynamically. +PIN user-pin { + auth-id = 2; + reference = 2; + attempts = 5; + min-length = 4; + max-length = 32; + flags = case-sensitive, initialized; +} +PIN user-puk { + min-length = 0; + max-length = 0; +} + +PIN so-pin { + auth-id = 1; + reference = 1; + attempts = 10; + min-length = 8; + max-length = 32; + flags = case-sensitive, initialized, soPin; +} +PIN so-puk { + min-length = 0; + max-length = 0; +} + +filesystem { + EF CHV2 { + file-id = 0002; + ACL = *=NEVER, UPDATE=$SOPIN, PIN-RESET=$SOPIN; + } + + DF MF { + path = 3F00; + type = DF; + acl = *=NEVER, SELECT=NONE, DELETE=NEVER, CREATE=CHV2, READ=NONE; + + DF Sys-DF { + file-id = 1000; + + DF SysKey-DF { + file-id = 1000; + } + + DF Resrv1-DF { + file-id = 1001; + } + DF Resrv2-DF { + file-id = 1002; + } + DF Resrv3-DF { + file-id = 1003; + } + DF Resrv4-DF { + file-id = 1004; + } + } + + EF DIR { + type = EF; + file-id = 2F00; + size = 128; + acl = *=NEVER, READ=NONE, UPDATE=CHV1, WRITE=CHV1, DELETE=CHV1; + } + + # Here comes the application DF + DF PKCS15-AppDF { + type = DF; + file-id = 5000; + acl = *=NONE, DELETE=CHV2; + + EF PKCS15-ODF { + file-id = 5031; + size = $odf-size; + acl = *=NONE, DELETE=$SOPIN; + } + + EF PKCS15-TokenInfo { + file-id = 5032; + size = $ti-size; + acl = *=NONE, DELETE=CHV2; + } + + EF PKCS15-AODF { + file-id = 6005; + size = $aodf-size; + acl = *=NEVER, READ=NONE, UPDATE=$SOPIN, WRITE=$SOPIN, DELETE=$SOPIN; + } + + EF PKCS15-PrKDF { + file-id = 6002; + size = $prkdf-size; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + EF PKCS15-PuKDF { + file-id = 6001; + size = $pukdf-size; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + EF PKCS15-CDF { + file-id = 6004; + size = $cdf-size; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + EF PKCS15-DODF { + file-id = 6006; + size = $dodf-size; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # This template defines files for keys, certificates etc. + # + # When instantiating the template, each file id will be + # combined with the last octet of the object's pkcs15 id + # to form a unique file ID. + template key-domain { + EF private-key { + file-id = 0100; + structure = transparent; + acl = *=NEVER, READ=$PIN, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + EF public-key { + file-id = 0200; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # Certificate template + EF certificate { + file-id = 0300; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # data objects are stored in transparent EFs. + EF data { + file-id = 0400; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # private data objects are stored in transparent EFs. + EF privdata { + file-id = 0500; + structure = transparent; + acl = *=NEVER, READ=$PIN, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + } + } + } +} + diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 09ab5336a0..63284f3f38 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -282,6 +282,9 @@ + + + @@ -424,6 +427,7 @@ + diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 680d48d728..c7bae1e3c6 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -173,6 +173,10 @@ MD_REGISTRATION minidriver_registration[] = { 16, {0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {TEXT("Rutoken ECP SC"), {0x3B,0x9C,0x94,0x80,0x11,0x40,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x45,0x43,0x50,0x73,0x63,0xC3}, 19, {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00}}, + {TEXT("Rutoken Lite"), {0x3B,0x8B,0x01,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x6C,0x69,0x74,0x65,0xC2}, + 15, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("Rutoken Lite SC"), {0x3B,0x8B,0x01,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x6C,0x69,0x74,0x65,0xC2}, + 15, {0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, }; From 709fa98bb506cb0a098af614c5a85249320b0aeb Mon Sep 17 00:00:00 2001 From: carblue Date: Sat, 6 Jul 2019 11:12:48 +0200 Subject: [PATCH 0939/4321] opensc-tool: fix --list-algorithms for AES --- src/tools/opensc-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index b5f5780104..5234ea117c 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -582,6 +582,7 @@ static int list_algorithms(void) { SC_ALGORITHM_GOSTR3411, "gostr3411" }, { SC_ALGORITHM_PBKDF2, "pbkdf2" }, { SC_ALGORITHM_PBES2, "pbes2" }, + { SC_ALGORITHM_AES, "aes" }, { 0, NULL } }; const id2str_t alg_flag_names[] = { From 916434f3a2df8cabd9d6802b15ef8b0985f7993d Mon Sep 17 00:00:00 2001 From: Daniel Kouril Date: Mon, 15 Jul 2019 14:34:04 +0200 Subject: [PATCH 0940/4321] Fix using environmental variables on WIN32. --- src/libopensc/ctx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 5c241313da..2885056d4c 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -181,9 +181,9 @@ sc_ctx_win32_get_config_value(const char *name_env, return SC_ERROR_INVALID_ARGUMENTS; if (name_env) { - char *value = value = getenv(name_env); + char *value = getenv(name_env); if (value) { - if (strlen(value) < *out_len) + if (strlen(value) > *out_len) return SC_ERROR_NOT_ENOUGH_MEMORY; memcpy(out, value, strlen(value)); *out_len = strlen(value); From d14cf97d7a6ea6e10d7a94b2cf0fac15f6dca9b8 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 17 Jul 2019 12:32:01 +0300 Subject: [PATCH 0941/4321] Allow to create temporary objects with readonly sessions and readonly cards Fixes #1719 Signed-off-by: Raul Metsma --- src/pkcs11/pkcs11-object.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 190e28665c..a562634b27 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -96,6 +96,7 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * CK_RV rv = CKR_OK; struct sc_pkcs11_session *session; struct sc_pkcs11_card *card; + CK_BBOOL is_token = FALSE; LOG_FUNC_CALLED(context); if (pTemplate == NULL_PTR || ulCount == 0) @@ -115,11 +116,22 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * goto out; } - if (session->slot->token_info.flags & CKF_WRITE_PROTECTED) { - rv = CKR_TOKEN_WRITE_PROTECTED; + rv = attr_find(pTemplate, ulCount, CKA_TOKEN, &is_token, NULL); + if (rv != CKR_TEMPLATE_INCOMPLETE && rv != CKR_OK) { goto out; } + if (is_token == TRUE) { + if (session->slot->token_info.flags & CKF_WRITE_PROTECTED) { + rv = CKR_TOKEN_WRITE_PROTECTED; + goto out; + } + if (!(session->flags & CKF_RW_SESSION)) { + rv = CKR_SESSION_READ_ONLY; + goto out; + } + } + card = session->slot->p11card; if (card->framework->create_object == NULL) rv = CKR_FUNCTION_NOT_SUPPORTED; From 8a20b980b90d82a1d64c8e0f2d36d4fd6a0fb218 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 17 Jul 2019 12:10:01 +0200 Subject: [PATCH 0942/4321] travis.yml - install socat and ant packages. Fixes #1745 --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 893cbef88d..4164bbc0b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ matrix: env: DO_PUSH_ARTIFACT=yes - compiler: gcc os: linux + dist: trusty env: - DO_SIMULATION=javacard - ENABLE_DOC=--enable-doc @@ -55,6 +56,8 @@ addons: - pcscd - pcsc-tools - check + - ant + - socat before_install: # brew install gengetopt help2man cmocka ccache llvm; From a7766b3de36adf2c50fa463ddeb3548dbb1ff140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3=20=C3=81gila=20Bitsch?= Date: Sat, 20 Jul 2019 23:04:57 +0200 Subject: [PATCH 0943/4321] allow chaining for pkcs15-init --store-private-key EC keys when importing a private key onto a pkcs15 card, if the card does not support extended APDUs, we need to use chaining to store keys longer than 255 bytes. While for RSA keys, this check was included, it was missing for EC keys. This patch adds the SC_APDU_FLAGS_CHAINING flag to apdu.flags if data length is greater than 255 and the card caps does not include SC_CARD_CAP_APDU_EXT. Fixes #1747 --- src/libopensc/card-isoApplet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index c323d92263..430cb30db5 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -928,6 +928,10 @@ isoApplet_put_data_prkey_ec(sc_card_t *card, sc_cardctl_isoApplet_import_key_t * apdu.lc = p - sbuf; apdu.datalen = p - sbuf; apdu.data = sbuf; + if ((apdu.datalen > 255) && !(card->caps & SC_CARD_CAP_APDU_EXT)) + { + apdu.flags |= SC_APDU_FLAGS_CHAINING; + } r = sc_transmit_apdu(card, &apdu); if(r < 0) { From 91b9aea42a580d3fec96cf51380f522282a8d314 Mon Sep 17 00:00:00 2001 From: programatix Date: Thu, 20 Jun 2019 15:07:19 +0800 Subject: [PATCH 0944/4321] Update pkcs15-sec.c When card supports SC_ALGORITHM_RSA_PAD_PKCS1 but not SC_ALGORITHM_RSA_HASH_NONE, then the DigestInfo need to be removed. Current check make requires the card to not support both SC_ALGORITHM_RSA_PAD_PKCS1 and SC_ALGORITHM_RSA_HASH_NONE to have the removal done. --- src/libopensc/pkcs15-sec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 5aae73b73f..ce054f745e 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -652,7 +652,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, * block from PKCS1 padding. */ if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && !(alg_info->flags & SC_ALGORITHM_RSA_RAW) && - !(alg_info->flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE))) { + !(alg_info->flags & SC_ALGORITHM_RSA_HASH_NONE) && + (alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1)) { unsigned int algo; size_t tmplen = sizeof(buf); From 71594000861b12bc2ad2350c16e68e1d815e0fa3 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 29 Jun 2019 11:52:02 -0700 Subject: [PATCH 0945/4321] treewide: Fix compilation without deprecated OpenSSL APIs --- src/libopensc/sc-ossl-compat.h | 16 ++++++++++++++++ src/pkcs15init/pkcs15-oberthur-awp.c | 1 + 2 files changed, 17 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 60da619e7d..cda9739a33 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -41,6 +41,22 @@ extern "C" { * */ +/* + * 1.1.0 depracated ERR_load_crypto_strings(), SSL_load_error_strings(), ERR_free_strings() + * and ENGINE_load_dynamic.EVP_CIPHER_CTX_cleanup and EVP_CIPHER_CTX_init are replaced + * by EVP_CIPHER_CTX_reset. + * But for compatability with LibreSSL and older OpenSSL. OpenSC uses the older functions + */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +#define ERR_load_crypto_strings(x) {} +#define SSL_load_error_strings(x) {} +#define ERR_free_strings(x) {} +#define ENGINE_load_dynamic(x) {} +#define EVP_CIPHER_CTX_cleanup(x) EVP_CIPHER_CTX_reset(x) +#define EVP_CIPHER_CTX_init(x) EVP_CIPHER_CTX_reset(x) +#endif + + /* * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL * use RSA_PKCS1_OpenSSL diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 362b8f3e4d..186e2a2a25 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -37,6 +37,7 @@ #include "libopensc/asn1.h" #ifdef ENABLE_OPENSSL +#include "libopensc/sc-ossl-compat.h" struct awp_lv zero_lv = { 0, NULL }; struct awp_lv x30_lv = { 0x10, (unsigned char *)"0000000000000000" }; From 755ac78a0224b593f5ff27065ca20f3a62fdd1ca Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 3 Jun 2019 07:56:56 +0200 Subject: [PATCH 0946/4321] added fuzzing with libFuzzer and OSS-Fuzz makes cmocka detection not required for building tests --- configure.ac | 32 +-- src/Makefile.am | 6 +- src/libopensc/libopensc.exports | 2 + src/libopensc/pkcs15.c | 13 +- src/tests/Makefile.am | 2 +- src/tests/fuzzing/Makefile.am | 15 ++ src/tests/fuzzing/fuzz_asn1_print.c | 29 +++ src/tests/fuzzing/fuzz_asn1_sig_value.c | 64 ++++++ src/tests/fuzzing/fuzz_pkcs15_decode.c | 74 +++++++ src/tests/fuzzing/fuzz_pkcs15_reader.c | 264 ++++++++++++++++++++++++ src/tests/p11test/Makefile.am | 5 + 11 files changed, 480 insertions(+), 26 deletions(-) create mode 100644 src/tests/fuzzing/Makefile.am create mode 100644 src/tests/fuzzing/fuzz_asn1_print.c create mode 100644 src/tests/fuzzing/fuzz_asn1_sig_value.c create mode 100644 src/tests/fuzzing/fuzz_pkcs15_decode.c create mode 100644 src/tests/fuzzing/fuzz_pkcs15_reader.c diff --git a/configure.ac b/configure.ac index 0c1128459b..1472b79692 100644 --- a/configure.ac +++ b/configure.ac @@ -129,9 +129,16 @@ case "${host}" in ;; esac -AX_CHECK_COMPILE_FLAG(-Wunknown-warning-option, [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror]) +AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror]) AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"]) +AC_ARG_ENABLE( + [fuzzing], + [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CFLAGS should be set accoringly, e.g. to something like "-fsanitize=address,fuzzer"])], + , + [enable_fuzzing="no"] +) + AC_ARG_ENABLE( [strict], [AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@enabled@:>@])], @@ -266,10 +273,10 @@ AC_ARG_ENABLE( ) AC_ARG_ENABLE( - [tests], - [AS_HELP_STRING([--enable-tests],[Build tests in src/tests/ directory @<:@detect@:>@])], + [cmocka], + [AS_HELP_STRING([--enable-cmocka],[Build tests in src/tests/p11test directory @<:@detect@:>@])], , - [enable_tests="detect"] + [enable_cmocka="detect"] ) AC_ARG_WITH( @@ -664,21 +671,18 @@ else OPENSSL_LIBS="" fi -if test "${enable_tests}" = "detect"; then +if test "${enable_cmocka}" = "detect"; then if test "${have_cmocka}" = "yes" -a "${have_openssl}" = "yes"; then - enable_tests="yes" + enable_cmocka="yes" else - enable_tests="no" + enable_cmocka="no" fi fi -if test "${enable_tests}" = "yes"; then +if test "${enable_cmocka}" = "yes"; then if test "${have_cmocka}" != "yes"; then AC_MSG_ERROR([Tests required, but cmocka is not available]) fi - if test "${have_openssl}" != "yes"; then - AC_MSG_ERROR([Tests required, but openssl is not available]) - fi fi @@ -1054,9 +1058,9 @@ AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"]) AM_CONDITIONAL([ENABLE_DNIE_UI], [test "${enable_dnie_ui}" = "yes"]) AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"]) AM_CONDITIONAL([ENABLE_AUTOSTART], [test "${enable_autostart}" = "yes"]) -AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) +AM_CONDITIONAL([ENABLE_CMOCKA], [test "${enable_cmocka}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) - +AM_CONDITIONAL([ENABLE_FUZZING], [test "${enable_fuzzing}" = "yes"]) AM_CONDITIONAL([ENABLE_SHARED], [test "${enable_shared}" = "yes"]) AS_IF([test "${enable_shared}" = "yes"], [AC_DEFINE([ENABLE_SHARED], [1], [Enable shared libraries])]) @@ -1089,6 +1093,7 @@ AC_CONFIG_FILES([ src/tests/Makefile src/tests/regression/Makefile src/tests/p11test/Makefile + src/tests/fuzzing/Makefile src/tools/Makefile src/tools/versioninfo-tools.rc src/tools/versioninfo-opensc-notify.rc @@ -1149,7 +1154,6 @@ SM default module: ${DEFAULT_SM_MODULE} SM default path: $(eval eval eval echo "${DEFAULT_SM_MODULE_PATH}") DNIe UI support: ${enable_dnie_ui} Notification support: ${enable_notify} -Build tests: ${enable_tests} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} PKCS11 default provider: $(eval eval eval echo "${DEFAULT_PKCS11_PROVIDER}") diff --git a/src/Makefile.am b/src/Makefile.am index 3be8f6a958..3ce465bfdb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,12 +3,8 @@ EXTRA_DIST = Makefile.mak # Order IS important SUBDIRS = common scconf ui pkcs15init sm \ - libopensc pkcs11 tools minidriver + libopensc pkcs11 tools minidriver tests if ENABLE_SM SUBDIRS += smm endif - -if ENABLE_TESTS -SUBDIRS += tests -endif diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 8157f30e36..ee2b96085f 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -150,6 +150,8 @@ sc_pkcs15_cache_file sc_pkcs15_card_clear sc_pkcs15_card_free sc_pkcs15_card_new +sc_pkcs15_tokeninfo_new +sc_pkcs15_free_tokeninfo sc_pkcs15_change_pin sc_pkcs15_compare_id sc_pkcs15_compute_signature diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 016470796b..839ba1dffb 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1305,12 +1305,13 @@ __sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_ma /* Make sure the class mask we have makes sense */ if (class_mask == 0 - || (class_mask & ~(SC_PKCS15_SEARCH_CLASS_PRKEY | - SC_PKCS15_SEARCH_CLASS_PUBKEY | - SC_PKCS15_SEARCH_CLASS_SKEY | - SC_PKCS15_SEARCH_CLASS_CERT | - SC_PKCS15_SEARCH_CLASS_DATA | - SC_PKCS15_SEARCH_CLASS_AUTH))) { + || (class_mask & ~( + SC_PKCS15_SEARCH_CLASS_PRKEY | + SC_PKCS15_SEARCH_CLASS_PUBKEY | + SC_PKCS15_SEARCH_CLASS_SKEY | + SC_PKCS15_SEARCH_CLASS_CERT | + SC_PKCS15_SEARCH_CLASS_DATA | + SC_PKCS15_SEARCH_CLASS_AUTH))) { LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS); } diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 99ee8aa612..4e42bd232f 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak -SUBDIRS = regression p11test +SUBDIRS = regression p11test fuzzing noinst_PROGRAMS = base64 lottery p15dump pintest prngtest AM_CPPFLAGS = -I$(top_srcdir)/src diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am new file mode 100644 index 0000000000..41776a2f83 --- /dev/null +++ b/src/tests/fuzzing/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -I$(top_srcdir)/src +AM_CFLAGS = -g -O0 $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) +LIBS = \ + $(top_builddir)/src/libopensc/libopensc.la \ + $(top_builddir)/src/common/libscdl.la \ + $(top_builddir)/src/common/libcompat.la + +if ENABLE_FUZZING +noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader +endif + +fuzz_asn1_print_SOURCES = fuzz_asn1_print.c +fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c +fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c +fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c diff --git a/src/tests/fuzzing/fuzz_asn1_print.c b/src/tests/fuzzing/fuzz_asn1_print.c new file mode 100644 index 0000000000..b50cb461af --- /dev/null +++ b/src/tests/fuzzing/fuzz_asn1_print.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/asn1.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + fclose(stdout); + sc_asn1_print_tags(Data, Size); + return 0; +} diff --git a/src/tests/fuzzing/fuzz_asn1_sig_value.c b/src/tests/fuzzing/fuzz_asn1_sig_value.c new file mode 100644 index 0000000000..98914152e2 --- /dev/null +++ b/src/tests/fuzzing/fuzz_asn1_sig_value.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/asn1.h" +#include +#include + +static unsigned char *in = NULL, *out = NULL; +static size_t inlen = 0, outlen = 0; +static struct sc_context *ctx = NULL; + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (!ctx) + sc_establish_context(&ctx, "fuzz"); + + if (outlen < Size*2) { + unsigned char *p = realloc(out, Size*2); + if (p) { + out = p; + outlen = Size*2; + } + } + + if (inlen < Size) { + unsigned char *p = realloc(in, Size); + if (p) { + in = p; + } + } + memcpy(in, Data, Size); + + sc_asn1_sig_value_sequence_to_rs(ctx, + Data, Size, + out, outlen); + + unsigned char *p = NULL; + size_t plen = 0; + sc_asn1_sig_value_rs_to_sequence(ctx, + in, Size, + &p, &plen); + free(p); + + return 0; +} diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c new file mode 100644 index 0000000000..0704c66afc --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/pkcs15.h" +#include "libopensc/internal.h" +#include +#include + +static struct sc_context *ctx = NULL; +static struct sc_pkcs15_card *p15card = NULL; +static sc_card_t card = {0}; + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + int (* decode_entries[])(struct sc_pkcs15_card *, struct sc_pkcs15_object *, + const u8 **nbuf, size_t *nbufsize) = { + sc_pkcs15_decode_prkdf_entry, sc_pkcs15_decode_pukdf_entry, + sc_pkcs15_decode_skdf_entry, sc_pkcs15_decode_cdf_entry, + sc_pkcs15_decode_dodf_entry, sc_pkcs15_decode_aodf_entry + }; + size_t i; + + if (!ctx) + sc_establish_context(&ctx, "fuzz"); + if (!p15card) { + card.ctx = ctx; + p15card = sc_pkcs15_card_new(); + if (p15card) { + p15card->card = &card; + } + } + + for (i = 0; i < sizeof decode_entries/sizeof *decode_entries; i++) { + struct sc_pkcs15_object *obj; + const u8 *p = Data; + size_t len = Size; + obj = calloc(1, sizeof *obj); + while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, &len)) { + sc_pkcs15_free_object(obj); + } + sc_pkcs15_free_object(obj); + } + + struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); + sc_pkcs15_decode_pubkey(ctx, pubkey, Data, Size); + sc_pkcs15_free_pubkey(pubkey); + + struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); + sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, Data, Size); + sc_pkcs15_free_tokeninfo(tokeninfo); + + sc_pkcs15_parse_unusedspace(Data, Size, p15card); + + return 0; +} diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c new file mode 100644 index 0000000000..9aa85c995f --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/pkcs15.h" +#include "libopensc/internal.h" +#include +#include + +const char *__asan_default_options() { + return "verbosity=0:mallocator_may_return_null=1"; +} + +/* private data structures */ +struct driver_data { + const uint8_t *Data; + size_t Size; +}; + +static struct sc_reader_operations fuzz_ops = {0}; +static struct sc_reader_driver fuzz_drv = { + "Fuzzing reader", + "fuzz", + &fuzz_ops, + NULL +}; + +void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size) +{ + struct driver_data *data; + + if (chunk) + *chunk = NULL; + if (chunk_size) + *chunk_size = 0; + + if (!chunk || !chunk_size || !reader) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + data = reader->drv_data; + if (!data || !data->Data || data->Size < sizeof *chunk_size) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + + data->Size -= sizeof *chunk_size; + *chunk_size = (uint16_t) data->Data; + data->Data += sizeof *chunk_size; + *chunk = data->Data; + + if (data->Size < *chunk_size) { + *chunk_size = data->Size; + } + + sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Returning fuzzing chunk", *chunk, *chunk_size); +} + +static int fuzz_reader_release(sc_reader_t *reader) +{ + if (reader) { + free(reader->drv_data); + reader->drv_data = NULL; + } + + return SC_SUCCESS; +} + +static int fuzz_reader_connect(sc_reader_t *reader) +{ + uint16_t chunk_size; + const uint8_t *chunk; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size > reader->atr.len) + chunk_size = reader->atr.len; + else + reader->atr.len = chunk_size; + + if (chunk_size > 0) + memcpy(reader->atr.value, chunk, chunk_size); + + return SC_SUCCESS; +} + +static int fuzz_reader_disconnect(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) +{ + const uint8_t *chunk; + uint16_t chunk_size; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size >= 2) { + /* set the SW1 and SW2 status bytes (the last two bytes of + * the response */ + apdu->sw1 = (unsigned int)chunk[chunk_size - 2]; + apdu->sw2 = (unsigned int)chunk[chunk_size - 1]; + chunk_size -= 2; + /* set output length and copy the returned data if necessary */ + if (chunk_size <= apdu->resplen) + apdu->resplen = chunk_size; + + if (apdu->resplen != 0) + memcpy(apdu->resp, chunk, apdu->resplen); + } else { + apdu->sw1 = 0x6D; + apdu->sw2 = 0x00; + apdu->resplen = 0; + } + + return SC_SUCCESS; +} + +struct sc_reader_driver *sc_get_fuzz_driver(void) +{ + fuzz_ops.release = fuzz_reader_release; + fuzz_ops.connect = fuzz_reader_connect; + fuzz_ops.disconnect = fuzz_reader_disconnect; + fuzz_ops.transmit = fuzz_reader_transmit; + return &fuzz_drv; +} + +void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) +{ + sc_reader_t *reader; + struct driver_data *data; + char name[64] = {0}; + + if (!(reader = calloc(1, sizeof(*reader))) + || !(data = (calloc(1, sizeof(*data))))) { + free(reader); + return; + } + + data->Data = Data; + data->Size = Size; + + reader->driver = &fuzz_drv; + reader->ops = &fuzz_ops; + reader->drv_data = data; + snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)", + Size, Size == 1 ? "" : "s", Data); + reader->name = strdup(name); + + reader->ctx = ctx; + list_append(&ctx->readers, reader); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + struct sc_context *ctx = NULL; + struct sc_card *card = NULL; + struct sc_pkcs15_card *p15card = NULL; + struct sc_reader *reader; + struct sc_pkcs15_object *obj; + + sc_establish_context(&ctx, "fuzz"); + if (!ctx) + return 0; + /* copied from sc_release_context() */ + while (list_size(&ctx->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); + + ctx->reader_driver = sc_get_fuzz_driver(); + + fuzz_add_reader(ctx, Data, Size); + + reader = sc_ctx_get_reader(ctx, 0); + sc_connect_card(reader, &card); + sc_pkcs15_bind(card, NULL, &p15card); + + if (p15card) { + const uint8_t *in, *param; + uint16_t in_len, param_len; + fuzz_get_chunk(reader, &in, &in_len); + fuzz_get_chunk(reader, ¶m, ¶m_len); + for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { + u8 buf[0xFFFF]; + size_t i; + + int decipher_flags[] = {SC_ALGORITHM_RSA_RAW, + SC_ALGORITHM_RSA_PAD_PKCS1, SC_ALGORITHM_RSA_PAD_ANSI, + SC_ALGORITHM_RSA_PAD_ISO9796}; + for (i = 0; i < sizeof decipher_flags; i++) { + sc_pkcs15_decipher(p15card, obj, decipher_flags[i], + in, in_len, buf, sizeof buf); + } + + i = sizeof buf; + sc_pkcs15_derive(p15card, obj, 0, + in, in_len, buf, &i); + + int wrap_flags[] = {0, SC_ALGORITHM_AES_ECB, SC_ALGORITHM_AES_CBC_PAD, + SC_ALGORITHM_AES_CBC}; + for (i = 0; i < sizeof wrap_flags; i++) { + struct sc_pkcs15_object target_key; + sc_pkcs15_unwrap(p15card, obj, &target_key, wrap_flags[i], + in, in_len, param, param_len); + unsigned long l = sizeof buf; + sc_pkcs15_wrap(p15card, obj, &target_key, wrap_flags[i], + buf, &l, in, in_len); + } + + int signature_flags[] = {SC_ALGORITHM_RSA_RAW, + SC_ALGORITHM_RSA_PAD_PKCS1, SC_ALGORITHM_RSA_PAD_ANSI, + SC_ALGORITHM_RSA_PAD_ISO9796, + SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_MGF1_SHA1, + SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_MGF1_SHA256, + SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_MGF1_SHA384, + SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_MGF1_SHA512, + SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_MGF1_SHA224, + SC_ALGORITHM_ECDSA_RAW, SC_ALGORITHM_ECDSA_HASH_SHA1, + SC_ALGORITHM_ECDSA_HASH_SHA224, SC_ALGORITHM_ECDSA_HASH_SHA256, + SC_ALGORITHM_ECDSA_HASH_SHA384, SC_ALGORITHM_ECDSA_HASH_SHA512, + SC_ALGORITHM_GOSTR3410_RAW, SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411, + SC_ALGORITHM_GOSTR3410_HASHES, + }; + for (i = 0; i < sizeof signature_flags; i++) { + sc_pkcs15_compute_signature(p15card, obj, signature_flags[i], + in, in_len, buf, sizeof buf); + } + + sc_pkcs15_verify_pin(p15card, obj, in, in_len); + sc_pkcs15_change_pin(p15card, obj, in, in_len, param, param_len); + sc_pkcs15_unblock_pin(p15card, obj, in, in_len, param, param_len); + sc_pkcs15_get_pin_info(p15card, obj); + } + sc_pkcs15_unbind(p15card); + } + + sc_disconnect_card(card); + sc_release_context(ctx); + + return 0; +} diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 13273b4014..b8c3db6453 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -3,7 +3,12 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak +if ENABLE_OPENSSL +if ENABLE_CMOCKA noinst_PROGRAMS = p11test +endif +endif + noinst_HEADERS = p11test_loader.h p11test_case_common.h \ p11test_case_readonly.h p11test_case_multipart.h \ p11test_case_mechs.h p11test_case_ec_sign.h \ From 45dfc1457380c41c42f96e25ff9aff73d17955d9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 4 Jun 2019 08:23:42 +0200 Subject: [PATCH 0947/4321] fixed memory leak --- src/libopensc/asn1.c | 10 +++++----- src/libopensc/asn1.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index e56044c2f8..47b42c746a 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -2036,12 +2036,12 @@ sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size int -sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size_t inlen, +sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in, size_t inlen, unsigned char *buf, size_t buflen) { struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE]; struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE]; - unsigned char *r, *s; + unsigned char *r = NULL, *s = NULL; size_t r_len, s_len, halflen = buflen/2; int rv; @@ -2057,11 +2057,11 @@ sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size sc_format_asn1_entry(asn1_sig_value_coefficients + 1, &s, &s_len, 0); rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL); - LOG_TEST_RET(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed"); if (halflen < r_len || halflen < s_len) { rv = SC_ERROR_BUFFER_TOO_SMALL; - goto done; + goto err; } memset(buf, 0, buflen); @@ -2074,7 +2074,7 @@ sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size sc_dump_hex(buf + halflen, halflen)); rv = SC_SUCCESS; -done: +err: free(r); free(s); diff --git a/src/libopensc/asn1.h b/src/libopensc/asn1.h index 0e5cdeb080..e45de7395e 100644 --- a/src/libopensc/asn1.h +++ b/src/libopensc/asn1.h @@ -124,7 +124,7 @@ int sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size_t inlen, unsigned char **buf, size_t *buflen); int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, - unsigned char *in, size_t inlen, + const unsigned char *in, size_t inlen, unsigned char *buf, size_t buflen); #define SC_ASN1_CLASS_MASK 0x30000000 From 86c4d3384b23d83dbeaf58a4cb44c64f63f783c1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Jun 2019 04:32:54 +0200 Subject: [PATCH 0948/4321] removed undefined reference to sc_pkcs15_create --- src/libopensc/pkcs15.h | 1 - src/pkcs15init/pkcs15-lib.c | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 4e6a29f7cf..3c4ec382d7 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -770,7 +770,6 @@ int sc_pkcs15_get_bitstring_extension(struct sc_context *ctx, int sc_pkcs15_create_cdf(struct sc_pkcs15_card *card, struct sc_file *file, const struct sc_pkcs15_cert_info **certs); -int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card); int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card, const struct sc_pkcs15_id *id, diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index bcc54bd98c..830c20072f 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -872,11 +872,7 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, sc_pkcs15_free_object(pin_obj); LOG_TEST_RET(ctx, r, "Card specific create application DF failed"); - /* Store the PKCS15 information on the card - * We cannot use sc_pkcs15_create() because it makes - * all sorts of assumptions about DF and EF names, and - * doesn't work if secure messaging is required for the - * MF (which is the case with the GPK) */ + /* Store the PKCS15 information on the card */ app = (struct sc_app_info *)calloc(1, sizeof(*app)); if (app == NULL) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to allocate application info"); From b7f202221cbea713045ade580138bea6507148b4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 5 Jun 2019 06:11:27 +0200 Subject: [PATCH 0949/4321] fixed undefined reference --- src/libopensc/pkcs15.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 3c4ec382d7..d8bb1b2705 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -885,13 +885,6 @@ int sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const u8 **buf, size_t *bufsize); -int sc_pkcs15_decode_enveloped_data(struct sc_context *ctx, - struct sc_pkcs15_enveloped_data *result, - const u8 *buf, size_t buflen); -int sc_pkcs15_encode_enveloped_data(struct sc_context *ctx, - struct sc_pkcs15_enveloped_data *data, - u8 **buf, size_t *buflen); - int sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj); void sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card, From e28ada99fedf5fe495d701cd18e312bfc97815d4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Jun 2019 07:12:19 +0200 Subject: [PATCH 0950/4321] added parameter checking --- src/libopensc/pkcs15.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 839ba1dffb..1855da2c69 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1182,17 +1182,19 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, struct sc_pkcs15_card **p15card_out) { struct sc_pkcs15_card *p15card = NULL; - struct sc_context *ctx = card->ctx; + struct sc_context *ctx; scconf_block *conf_block = NULL; int r, emu_first, enable_emu; const char *private_certificate; + if (card == NULL || p15card_out == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + ctx = card->ctx; + LOG_FUNC_CALLED(ctx); sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty"); - if (p15card_out == NULL) { - return SC_ERROR_INVALID_ARGUMENTS; - } p15card = sc_pkcs15_card_new(); if (p15card == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); From 72f474f09fdbd420999e204de243ca4aeddf7476 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Jun 2019 07:54:54 +0200 Subject: [PATCH 0951/4321] use consistent parameters - in sc_pkcs15_wrap() - and sc_pkcs15_derive() --- src/libopensc/pkcs15-sec.c | 25 +++++++++---------------- src/libopensc/pkcs15.h | 4 ++-- src/minidriver/minidriver.c | 14 +++++++------- src/pkcs11/framework-pkcs15.c | 13 ++++++++++--- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index ce054f745e..42a3a6af4f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -304,7 +304,7 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj, unsigned long flags, const u8 * in, size_t inlen, u8 *out, - unsigned long *poutlen) + size_t *poutlen) { sc_context_t *ctx = p15card->card->ctx; int r; @@ -444,8 +444,8 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, unsigned long* crgram_len, - const u8 * param, size_t paramlen) { + u8 *cryptogram, size_t *crgram_len, + const u8 *param, size_t paramlen) { sc_context_t *ctx = p15card->card->ctx; int r; sc_algorithm_info_t *alg_info = NULL; @@ -456,10 +456,6 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_skey_info *target_skey = (const struct sc_pkcs15_skey_info *) target_key->data; unsigned long pad_flags = 0, sec_flags = 0; sc_path_t tkey_path; - u8 *in = 0; - u8 *out = 0; - unsigned long *poutlen = 0; - size_t inlen = 0; sc_path_t path, target_file_id; sc_sec_env_param_t senv_param; @@ -531,18 +527,15 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } - out = cryptogram; - poutlen = crgram_len; - r = use_key(p15card, key, &senv, sc_wrap, in, inlen, out, - *poutlen); + r = use_key(p15card, key, &senv, sc_wrap, NULL, 0, cryptogram, crgram_len ? *crgram_len : 0); - if (r > -1) { - if (*crgram_len < (unsigned) r) { - *poutlen = r; - if (out != NULL) /* if NULL, return success and required buffer length by PKCS#11 convention */ + if (r > -1 && crgram_len) { + if (*crgram_len < (size_t) r) { + *crgram_len = r; + if (cryptogram != NULL) /* if NULL, return success and required buffer length by PKCS#11 convention */ LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to hold the wrapped key."); } - *poutlen = r; + *crgram_len = r; } LOG_FUNC_RETURN(ctx, r); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index d8bb1b2705..f2ccc42aed 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -666,7 +666,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, unsigned long flags, - const u8 *in, size_t inlen, u8 *out, unsigned long *poutlen); + const u8 *in, size_t inlen, u8 *out, size_t *poutlen); int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, @@ -679,7 +679,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *key, struct sc_pkcs15_object *target_key, unsigned long flags, - u8 * cryptogram, unsigned long* crgram_len, + u8 * cryptogram, size_t* crgram_len, const u8 * param, size_t paramlen); int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 54e23c5dab..8a0940d0f7 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4879,9 +4879,9 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, struct sc_pkcs15_object *pkey = NULL; int r, opt_derive_flags = SC_ALGORITHM_ECDH_CDH_RAW; u8* out = 0; - unsigned long outlen = 0; + size_t outlen = 0; PBYTE pbPublicKey = NULL; - DWORD dwPublicKeySize = 0; + size_t publicKeySize = 0; struct md_dh_agreement* dh_agreement = NULL; struct md_dh_agreement* temp = NULL; BYTE i; @@ -4936,18 +4936,18 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, } /* convert the Windows public key into an OpenSC public key */ - dwPublicKeySize = pAgreementInfo->dwPublicKey - sizeof(BCRYPT_ECCKEY_BLOB) + 1; - pbPublicKey = (PBYTE) pCardData->pfnCspAlloc(dwPublicKeySize); + publicKeySize = pAgreementInfo->dwPublicKey - sizeof(BCRYPT_ECCKEY_BLOB) + 1; + pbPublicKey = (PBYTE) pCardData->pfnCspAlloc(publicKeySize); if (!pbPublicKey) { dwret = ERROR_OUTOFMEMORY; goto err; } pbPublicKey[0] = 4; - memcpy(pbPublicKey+1, pAgreementInfo->pbPublicKey + sizeof(BCRYPT_ECCKEY_BLOB), dwPublicKeySize-1); + memcpy(pbPublicKey+1, pAgreementInfo->pbPublicKey + sizeof(BCRYPT_ECCKEY_BLOB), publicKeySize-1); /* derive the key using the OpenSC functions */ - r = sc_pkcs15_derive(vs->p15card, pkey, opt_derive_flags, pbPublicKey, dwPublicKeySize, out, &outlen ); + r = sc_pkcs15_derive(vs->p15card, pkey, opt_derive_flags, pbPublicKey, publicKeySize, out, &outlen ); logprintf(pCardData, 2, "sc_pkcs15_derive returned %d\n", r); if ( r < 0) { @@ -4964,7 +4964,7 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, goto err; } - r = sc_pkcs15_derive(vs->p15card, pkey, opt_derive_flags, pbPublicKey, dwPublicKeySize, out, &outlen ); + r = sc_pkcs15_derive(vs->p15card, pkey, opt_derive_flags, pbPublicKey, publicKeySize, out, &outlen ); logprintf(pCardData, 2, "sc_pkcs15_derive returned %d\n", r); pCardData->pfnCspFree(pbPublicKey); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ed0f677dd9..3c845a71b4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4268,12 +4268,14 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, break; } + size_t len = *pulDataLen; rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags, - pSeedData, ulSeedDataLen, pData, pulDataLen); + pSeedData, ulSeedDataLen, pData, &len); if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path && need_unlock) if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags, - pSeedData, ulSeedDataLen, pData, pulDataLen); + pSeedData, ulSeedDataLen, pData, &len); + *pulDataLen = len; /* this may have been a request for size */ @@ -5049,6 +5051,7 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *) obj; struct pkcs15_skey_object *targetKeyObj = (struct pkcs15_skey_object *) targetKey; + size_t len = pulDataLen ? *pulDataLen : 0; int rv, flags = 0; sc_log(context, "Initializing wrapping with a secret key."); @@ -5098,7 +5101,11 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, /* Call the card to do the wrapping operation */ rv = sc_pkcs15_wrap(fw_data->p15_card, skey->prv_p15obj, targetKeyObj->prv_p15obj, flags, - pData, pulDataLen, pMechanism->pParameter, pMechanism->ulParameterLen); + pData, &len, pMechanism->pParameter, pMechanism->ulParameterLen); + + if (pulDataLen) { + *pulDataLen = len; + } sc_unlock(p11card->card); From 973b09f9432c6c9d074221af698d4373ede0f695 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 21 Jun 2019 12:27:46 +0200 Subject: [PATCH 0952/4321] fixed exports --- src/libopensc/libopensc.exports | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index ee2b96085f..ce041ae7a0 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -212,6 +212,7 @@ sc_pkcs15_free_prkey sc_pkcs15_free_prkey_info sc_pkcs15_free_pubkey sc_pkcs15_free_pubkey_info +sc_pkcs15_free_tokeninfo sc_pkcs15_get_application_by_type sc_pkcs15_get_name_from_dn sc_pkcs15_get_object_guid @@ -239,6 +240,7 @@ sc_pkcs15_pubkey_from_cert sc_pkcs15_remove_object sc_pkcs15_remove_unusedspace sc_pkcs15_search_objects +sc_pkcs15_tokeninfo_new sc_pkcs15_unbind sc_pkcs15_unblock_pin sc_pkcs15_unwrap From bf8d4497959e1f42bbd27d1808d538ae7ed81594 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 21 Jun 2019 14:20:03 +0200 Subject: [PATCH 0953/4321] fixed memory leak --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 9aa85c995f..009e2386ad 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -254,7 +254,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_unblock_pin(p15card, obj, in, in_len, param, param_len); sc_pkcs15_get_pin_info(p15card, obj); } - sc_pkcs15_unbind(p15card); + sc_pkcs15_card_free(p15card); } sc_disconnect_card(card); From af8f96500903f9de7278ff557ded899e6d805983 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 24 Jun 2019 16:44:12 +0200 Subject: [PATCH 0954/4321] fixed memory leak --- src/libopensc/pkcs15.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 1855da2c69..4386a51e7f 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -472,6 +472,8 @@ parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen) p15card->file_odf->path = odf_path; } if (asn1_ddo[2].flags & SC_ASN1_PRESENT) { + if (p15card->file_tokeninfo) + sc_file_free(p15card->file_tokeninfo); p15card->file_tokeninfo = sc_file_new(); if (p15card->file_tokeninfo == NULL) goto mem_err; From 93bdc8c826205637cf1dcafec24dc4f3615e0003 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 28 Jul 2019 21:27:34 -0500 Subject: [PATCH 0955/4321] Support OpenSSL when deprecated defines have been removed Fixes 1755 sc-ossl-compat.h will check if OpenSSL has been built with or without some deprecated defines. OpenSSL will provide defines for some of these if built to still support depreacted routines but not if built with "no-depracted". . This commit will define some of the needed defines if ther are not defined by OpenSSL. Thus if a distro builds OpenSSL with "no-depracted" it can still be used. On branch fix-1755 Changes to be committed: modified: src/libopensc/sc-ossl-compat.h --- src/libopensc/sc-ossl-compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index cda9739a33..5222b1f99b 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -48,12 +48,14 @@ extern "C" { * But for compatability with LibreSSL and older OpenSSL. OpenSC uses the older functions */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) +# if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L #define ERR_load_crypto_strings(x) {} #define SSL_load_error_strings(x) {} #define ERR_free_strings(x) {} #define ENGINE_load_dynamic(x) {} #define EVP_CIPHER_CTX_cleanup(x) EVP_CIPHER_CTX_reset(x) #define EVP_CIPHER_CTX_init(x) EVP_CIPHER_CTX_reset(x) +# endif #endif From 426772298a3a496ea8cbf7c234adf35ba386e04c Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 10 Jul 2019 10:31:35 +0200 Subject: [PATCH 0956/4321] pkcs15-tool: inconsistent -r option fix Option -r is used in other opensc tools to specify card reader. pkcs15-tool uses -r to specify cerfificate. This fix intorduces warning message if -r is used, and for future versions of pkcs15-tool -r is used to specify reader. --- doc/tools/pkcs15-tool.1.xml | 3 +-- src/tools/pkcs15-tool.c | 52 +++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index c995a3fa59..02b3b03b64 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -209,8 +209,7 @@ - cert, - cert + cert Reads the certificate with the given id. diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 086492027b..6a490b834e 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -107,6 +107,7 @@ enum { OPT_RAW, OPT_PRINT_VERSION, OPT_LIST_INFO, + OPT_READ_CERT, }; #define NELEMENTS(x) (sizeof(x)/sizeof((x)[0])) @@ -117,7 +118,7 @@ static const struct option options[] = { { "version", 0, NULL, OPT_PRINT_VERSION }, { "list-info", no_argument, NULL, OPT_LIST_INFO }, { "list-applications", no_argument, NULL, OPT_LIST_APPLICATIONS }, - { "read-certificate", required_argument, NULL, 'r' }, + { "read-certificate", required_argument, NULL, OPT_READ_CERT }, { "list-certificates", no_argument, NULL, 'c' }, { "read-data-object", required_argument, NULL, 'R' }, { "raw", no_argument, NULL, OPT_RAW }, @@ -2134,6 +2135,53 @@ int main(int argc, char *argv[]) if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { + case 'r': + +#if OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR == 19 + fprintf(stderr, "\nWarning, option -r is reserved to specify card reader in future versions\n"); + fprintf (stderr, "Using -r option for read-certificate operation\n\n"); + opt_cert = optarg; + do_read_cert = 1; + action_count++; + break; +#elif OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR == 20 + + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = app_name; + + if (SC_SUCCESS == sc_context_create(&ctx, &ctx_param)) { + /* attempt to connect reader, on error, -r is used for read-certificate operation */ + struct sc_reader *reader = NULL; + + err = util_connect_reader(ctx, &reader, optarg, 0, 0); + sc_release_context(ctx); + ctx = NULL; + + if (err != SC_SUCCESS ) { +#if 1 + fprintf (stderr, + "Error, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg); + exit (1); +#else + fprintf (stderr, + "\nWarning, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg); + fprintf (stderr, "Using -r option for read-certificate operation\n\n"); + opt_cert = optarg; + do_read_cert = 1; + action_count++; + break; +#endif + } + } + opt_reader = optarg; + break; +#elif (OPENSC_MAJOR > 0) || (OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR > 20) + + opt_reader = optarg; + break; +#endif + case OPT_PRINT_VERSION: do_print_version = 1; action_count++; @@ -2142,7 +2190,7 @@ int main(int argc, char *argv[]) do_list_info = 1; action_count++; break; - case 'r': + case OPT_READ_CERT: opt_cert = optarg; do_read_cert = 1; action_count++; From 8f838bc1e002d63d4ae65e92a81c5f7675fb3389 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 19 Aug 2019 16:15:05 +0200 Subject: [PATCH 0957/4321] fixed passing LIB_FUZZING_ENGINE --- configure.ac | 5 ++++- src/tests/fuzzing/Makefile.am | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1472b79692..d275cfabb1 100644 --- a/configure.ac +++ b/configure.ac @@ -134,11 +134,13 @@ AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_opti AC_ARG_ENABLE( [fuzzing], - [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CFLAGS should be set accoringly, e.g. to something like "-fsanitize=address,fuzzer"])], + [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CFLAGS and FUZZING_LIBS should be set accoringly, e.g. to something like CFLAGS="-fsanitize=address,fuzzer" FUZZING_LIBS="-fsanitize=fuzzer"])], , [enable_fuzzing="no"] ) +AC_ARG_VAR([FUZZING_LIBS], [linker flags for fuzzing]) + AC_ARG_ENABLE( [strict], [AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@enabled@:>@])], @@ -1180,6 +1182,7 @@ PCSC_CFLAGS: ${PCSC_CFLAGS} CRYPTOTOKENKIT_CFLAGS: ${CRYPTOTOKENKIT_CFLAGS} GIO2_CFLAGS: ${GIO2_CFLAGS} GIO2_LIBS: ${GIO2_LIBS} +FUZZING_LIBS: ${FUZZING_LIBS} EOF diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 41776a2f83..509e672d32 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/src AM_CFLAGS = -g -O0 $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -LIBS = \ +LIBS = $(FUZZING_LIBS) \ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la From aa489baf7450bf47b6d5dc2c8f6778b175bafd77 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Aug 2019 13:24:33 +0200 Subject: [PATCH 0958/4321] md: added missing cardos5 ATRs (#1750) fixes https://github.com/OpenSC/OpenSC/issues/1735 --- win32/customactions.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index c7bae1e3c6..9cf87f4fc2 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -137,7 +137,11 @@ MD_REGISTRATION minidriver_registration[] = { 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("CardOS 4.4"), {0x3b,0xd2,0x18,0x02,0xc1,0x0a,0x31,0xfe,0x58,0xc8,0x0d,0x51}, 12, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, - {TEXT("CardOS v5.0"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x01,0x14}, + {TEXT("CardOS v5.0 (a)"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x01,0x14}, + 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("CardOS v5.3 (b)"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x02,0x17}, + 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("CardOS v5.3 (c)"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x03,0x16}, 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("JPKI"), {0x3b,0xe0,0x00,0xff,0x81,0x31,0xfe,0x45,0x14}, 9, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, From 7d8009e429a0c932c49fa409abe33826ab163fd0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jul 2019 08:14:41 +0200 Subject: [PATCH 0959/4321] PC/SC: handle resets in SCardTransmit fixes https://github.com/OpenSC/OpenSC/issues/1725 --- src/libopensc/apdu.c | 11 ++++++++++- src/libopensc/reader-pcsc.c | 11 +++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index d32d440402..f4101269ea 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -619,9 +619,18 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) len -= plen; buf += plen; } - } else + } else { /* transmit single APDU */ r = sc_transmit(card, apdu); + } + + if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { + sc_invalidate_cache(card); + /* give card driver a chance to react on resets */ + if (card->ops->card_reader_lock_obtained) + card->ops->card_reader_lock_obtained(card, 1); + } + /* all done => release lock */ if (sc_unlock(card) != SC_SUCCESS) sc_log(card->ctx, "sc_unlock failed"); diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index a058c71f7b..18835d372f 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -132,6 +132,8 @@ struct pcsc_private_data { }; static int pcsc_detect_card_presence(sc_reader_t *reader); +static int pcsc_reconnect(sc_reader_t * reader, DWORD action); +static int pcsc_connect(sc_reader_t *reader); static DWORD pcsc_reset_action(const char *str) { @@ -244,6 +246,15 @@ static int pcsc_internal_transmit(sc_reader_t *reader, switch (rv) { case SCARD_W_REMOVED_CARD: return SC_ERROR_CARD_REMOVED; + case SCARD_E_INVALID_HANDLE: + case SCARD_E_READER_UNAVAILABLE: + pcsc_connect(reader); + /* return failure so that upper layers will be notified */ + return SC_ERROR_READER_REATTACHED; + case SCARD_W_RESET_CARD: + pcsc_reconnect(reader, SCARD_LEAVE_CARD); + /* return failure so that upper layers will be notified */ + return SC_ERROR_CARD_RESET; default: /* Translate strange errors from card removal to a proper return code */ pcsc_detect_card_presence(reader); From 2958b71c9ac14325ca00df4edbe77e8a572b3f16 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Jul 2019 09:48:52 +0200 Subject: [PATCH 0960/4321] typo --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 5eb25e9606..a6f9fb6386 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2364,7 +2364,7 @@ static int piv_validate_general_authentication(sc_card_t *card, * alg_id=06 is a place holder for all RSA keys. * Derive the real alg_id based on the size of the * the data, as we are always using raw mode. - * Non RSA keys needs some work in thia area. + * Non RSA keys needs some work in this area. */ real_alg_id = priv->alg_id; From 818aa5b69c684e7b9254494cf9529f84cad95f75 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Jul 2019 10:46:31 +0200 Subject: [PATCH 0961/4321] p11test: Avoid possible issues reported by coverity * The fail_msg() in cmocka has a way not to fail, which confuses coverity. Adding explicit retunr/exit should address this issue * Reformat some code in p11test --- src/tests/p11test/p11test_case_common.c | 35 +++++++--- src/tests/p11test/p11test_case_common.h | 15 +++-- src/tests/p11test/p11test_case_readonly.c | 4 +- src/tests/p11test/p11test_helpers.c | 82 ++++++++++++++--------- 4 files changed, 90 insertions(+), 46 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index bd63458ac7..57a7f80390 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -30,13 +30,15 @@ char flag_buffer[11]; void always_authenticate(test_cert_t *o, token_info_t *info) { CK_RV rv; - if (!o->always_auth) + if (!o->always_auth) { return; + } rv = info->function_pointer->C_Login(info->session_handle, CKU_CONTEXT_SPECIFIC, info->pin, info->pin_length); if (rv != CKR_OK) { fail_msg(" [ SKIP %s ] Re-authentication failed", o->id_str); + exit(1); } } @@ -153,7 +155,7 @@ int callback_certificates(test_certs_t *objects, CK_ATTRIBUTE template[], unsigned int template_size, CK_OBJECT_HANDLE object_handle) { EVP_PKEY *evp = NULL; - const u_char *cp; + const u_char *cp = NULL; test_cert_t *o = NULL; if (*(CK_CERTIFICATE_TYPE *)template[3].pValue != CKC_X_509) @@ -166,23 +168,29 @@ int callback_certificates(test_certs_t *objects, cp = template[1].pValue; if (d2i_X509(&(o->x509), &cp, template[1].ulValueLen) == NULL) { fail_msg("d2i_X509"); + return -1; } else if ((evp = X509_get_pubkey(o->x509)) == NULL) { fail_msg("X509_get_pubkey failed."); + return -1; } if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { /* Extract public RSA key */ RSA *rsa = EVP_PKEY_get0_RSA(evp); - if ((o->key.rsa = RSAPublicKey_dup(rsa)) == NULL) + if ((o->key.rsa = RSAPublicKey_dup(rsa)) == NULL) { fail_msg("RSAPublicKey_dup failed"); + return -1; + } o->type = EVP_PK_RSA; o->bits = EVP_PKEY_bits(evp); } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { /* Extract public EC key */ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp); - if ((o->key.ec = EC_KEY_dup(ec)) == NULL) + if ((o->key.ec = EC_KEY_dup(ec)) == NULL) { fail_msg("EC_KEY_dup failed"); + return -1; + } o->type = EVP_PK_EC; o->bits = EVP_PKEY_bits(evp); @@ -434,8 +442,10 @@ int search_objects(test_certs_t *objects, token_info_t *info, if (i >= objects_length) { objects_length += 4; // do not realloc after each row object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE_PTR)); - if (object_handles == NULL) + if (object_handles == NULL) { fail_msg("Realloc failed. Need to store object handles.\n"); + return -1; + } } object_handles[i++] = object_handle; } @@ -445,6 +455,7 @@ int search_objects(test_certs_t *objects, token_info_t *info, if (rv != CKR_OK) { fprintf(stderr, "C_FindObjectsFinal: rv = 0x%.8lX\n", rv); fail_msg("Could not find certificate.\n"); + return -1; } for (i = 0; i < objects_length; i++) { @@ -457,24 +468,30 @@ int search_objects(test_certs_t *objects, token_info_t *info, rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], &(template[j]), 1); - if (rv == CKR_ATTRIBUTE_TYPE_INVALID) + if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { continue; - else if (rv != CKR_OK) + } else if (rv != CKR_OK) { fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + return -1; + } /* Allocate memory to hold the data we want */ if (template[j].ulValueLen == 0) { continue; } else { template[j].pValue = malloc(template[j].ulValueLen); - if (template[j].pValue == NULL) + if (template[j].pValue == NULL) { fail_msg("malloc failed"); + return -1; + } } /* Call again to get actual attribute */ rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], &(template[j]), 1); - if (rv != CKR_OK) + if (rv != CKR_OK) { fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); + return -1; + } } callback(objects, template, template_size, object_handles[i]); diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index b9171ab571..369c4556c4 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -103,16 +103,19 @@ int is_pss_mechanism(CK_MECHANISM_TYPE mech); #define P11TEST_PASS(info) do { _P11TEST_FINALIZE(info, "pass") } while(0); #define P11TEST_FAIL(info, msg, ...) do { \ - if (info->log.fd && info->log.in_test) { \ - fprintf(info->log.fd, ",\n\t\"fail_reason\": \"" msg "\"", ##__VA_ARGS__); \ - } \ - _P11TEST_FINALIZE(info, "fail") \ - fail_msg(msg, ##__VA_ARGS__); \ + if (info->log.fd && info->log.in_test) { \ + fprintf(info->log.fd, ",\n\t\"fail_reason\": \"" msg "\"", ##__VA_ARGS__); \ + } \ + _P11TEST_FINALIZE(info, "fail") \ + fail_msg(msg, ##__VA_ARGS__); \ + exit(1); \ } while (0); #define P11TEST_DATA_ROW(info, cols, ...) if (info->log.fd) { \ - if (info->log.in_test == 0) \ + if (info->log.in_test == 0) {\ fail_msg("Can't add data outside of the test");\ + exit(1); \ + } \ if (info->log.in_data == 0) {\ fprintf(info->log.fd, ",\n\t\"data\": [");\ info->log.in_data = 1;\ diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 2c3497c8c6..0444a67232 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -546,8 +546,10 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, CK_ULONG sign_length = 0; int rv = 0; - if (message_length > strlen(SHORT_MESSAGE_TO_SIGN)) + if (message_length > strlen(SHORT_MESSAGE_TO_SIGN)) { fail_msg("Truncate is longer than the actual message"); + return -1; + } if (o->private_handle == CK_INVALID_HANDLE) { debug_print(" [SKIP %s ] Missing private key", o->id_str); diff --git a/src/tests/p11test/p11test_helpers.c b/src/tests/p11test/p11test_helpers.c index bdfd40d07c..9a27ab69d1 100644 --- a/src/tests/p11test/p11test_helpers.c +++ b/src/tests/p11test/p11test_helpers.c @@ -23,7 +23,9 @@ #include "p11test_helpers.h" #include "p11test_loader.h" -int open_session(token_info_t *info) { +int +open_session(token_info_t *info) +{ CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; CK_RV rv; @@ -31,56 +33,65 @@ int open_session(token_info_t *info) { CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &info->session_handle); - if(rv != CKR_OK) + if (rv != CKR_OK) { return 1; + } debug_print("Session was successfully created"); return 0; } -int initialize_cryptoki(token_info_t *info) { - +int +initialize_cryptoki(token_info_t *info) +{ CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; CK_RV rv; rv = function_pointer->C_Initialize(NULL_PTR); - if(rv != CKR_OK){ - fprintf(stderr,"Could not initialize CRYPTOKI!\n"); + if (rv != CKR_OK) { + fprintf(stderr, "Could not initialize CRYPTOKI!\n"); return 1; } - if(get_slot_with_card(info)) { + if (get_slot_with_card(info)) { function_pointer->C_Finalize(NULL_PTR); - fprintf(stderr,"There is no card present in reader.\n"); + fprintf(stderr, "There is no card present in reader.\n"); return 1; } return 0; } -int token_initialize(void **state) { +int token_initialize(void **state) +{ token_info_t *info = (token_info_t *) *state; - if(initialize_cryptoki(info)) { + if (initialize_cryptoki(info)) { debug_print("CRYPTOKI couldn't be initialized"); return 1; } return 0; } -void logfile_init(token_info_t *info) { - if (token.log.outfile == NULL) +void logfile_init(token_info_t *info) +{ + if (token.log.outfile == NULL) { return; + } - if ((info->log.fd = fopen(token.log.outfile, "w")) == NULL) + if ((info->log.fd = fopen(token.log.outfile, "w")) == NULL) { fail_msg("Couldn't open file for test results."); + exit(1); + } fprintf(info->log.fd, "{\n\"time\": 0,\n\"results\": ["); info->log.in_test = 0; info->log.first = 1; } -void logfile_finalize(token_info_t *info) { - if (info == NULL || info->log.fd == NULL) +void logfile_finalize(token_info_t *info) +{ + if (info == NULL || info->log.fd == NULL) { return; + } /* Make sure the JSON object for test is closed */ if (info->log.in_test) { @@ -94,7 +105,6 @@ void logfile_finalize(token_info_t *info) { int group_setup(void **state) { - token_info_t * info = calloc(sizeof(token_info_t), 1); assert_non_null(info); @@ -107,6 +117,7 @@ int group_setup(void **state) if (load_pkcs11_module(info, token.library_path)) { free(info); fail_msg("Could not load module!\n"); + exit(1); } logfile_init(info); @@ -115,8 +126,8 @@ int group_setup(void **state) return 0; } -int group_teardown(void **state) { - +int group_teardown(void **state) +{ token_info_t *info = (token_info_t *) *state; debug_print("Clearing state after group tests!"); // XXX do not finalize already Finalized @@ -134,13 +145,14 @@ int group_teardown(void **state) { return 0; } -int prepare_token(token_info_t *info) { - if(initialize_cryptoki(info)) { +int prepare_token(token_info_t *info) +{ + if (initialize_cryptoki(info)) { debug_print("CRYPTOKI couldn't be initialized"); return 1; } - if(open_session(info)) { + if (open_session(info)) { debug_print("Could not open session to token!"); return 1; } @@ -148,7 +160,8 @@ int prepare_token(token_info_t *info) { return 0; } -int finalize_token(token_info_t *info) { +int finalize_token(token_info_t *info) +{ CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; info->session_handle = 0; @@ -159,26 +172,31 @@ int finalize_token(token_info_t *info) { return 0; } -int user_login_setup(void **state) { +int user_login_setup(void **state) +{ token_info_t *info = (token_info_t *) *state; CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; CK_RV rv; - if (prepare_token(info)) + if (prepare_token(info)) { fail_msg("Could not prepare token.\n"); + exit(1); + } debug_print("Logging in to the token!"); rv = function_pointer->C_Login(info->session_handle, CKU_USER, token.pin, token.pin_length); - if(rv != CKR_OK) + if (rv != CKR_OK) { fail_msg("Could not login to token with user PIN '%s'\n", token.pin); + exit(1); + } return 0; } -int after_test_cleanup(void **state) { - +int after_test_cleanup(void **state) +{ token_info_t *info = (token_info_t *) *state; CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer; @@ -189,16 +207,20 @@ int after_test_cleanup(void **state) { return 0; } -int token_setup(void **state) { +int token_setup(void **state) +{ token_info_t *info = (token_info_t *) *state; - if(prepare_token(info)) + if (prepare_token(info)) { fail_msg("Could not prepare token.\n"); + exit(1); + } return 0; } -int token_cleanup(void **state) { +int token_cleanup(void **state) +{ token_info_t *info = (token_info_t *) *state; finalize_token(info); From 1a0a8e637b8fc16f22f0a8d76210ed0105bc2916 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Jul 2019 11:03:33 +0200 Subject: [PATCH 0962/4321] p11test: Check return values CID undefined (#1 of 1): Unchecked return value (CHECKED_RETURN) 10. check_return: Calling RSA_set0_key without checking return value (as is done elsewhere 7 out of 8 times). --- src/tests/p11test/p11test_case_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 57a7f80390..a90b5f875a 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -312,7 +312,10 @@ int callback_public_keys(test_certs_t *objects, } else { /* store the public key for future use */ o->type = EVP_PK_RSA; o->key.rsa = RSA_new(); - RSA_set0_key(o->key.rsa, n, e, NULL); + if (RSA_set0_key(o->key.rsa, n, e, NULL) != 1) { + fail_msg("Unable to set key params"); + return -1; + } o->bits = RSA_bits(o->key.rsa); n = NULL; e = NULL; From 9b47462a51970e3ef6841a20baa7d3a5a75de441 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Jul 2019 11:04:14 +0200 Subject: [PATCH 0963/4321] Fix portability warning from coverity CID 344928 (#1 of 1): Sizeof not portable (SIZEOF_MISMATCH) suspicious_sizeof: Passing argument object_handles of type CK_OBJECT_HANDLE_PTR and argument objects_length * 8UL /* sizeof (CK_OBJECT_HANDLE_PTR) */ to function realloc is suspicious. In this case, sizeof (CK_OBJECT_HANDLE_PTR) is equal to sizeof (CK_OBJECT_HANDLE), but this is not a portable assumption. --- src/tests/p11test/p11test_case_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index a90b5f875a..77285af777 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -444,7 +444,7 @@ int search_objects(test_certs_t *objects, token_info_t *info, /* store handle */ if (i >= objects_length) { objects_length += 4; // do not realloc after each row - object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE_PTR)); + object_handles = realloc(object_handles, objects_length * sizeof(CK_OBJECT_HANDLE)); if (object_handles == NULL) { fail_msg("Realloc failed. Need to store object handles.\n"); return -1; From fdf80761cfbcafd442834aba770a35b47e1bad87 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 5 Aug 2019 02:25:39 +0300 Subject: [PATCH 0964/4321] Remove duplicate code Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 198 ++++++-------------------------------- 1 file changed, 32 insertions(+), 166 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 2a1668d591..1c71aa3250 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -104,8 +104,8 @@ struct df_info_s { struct mcrd_priv_data { unsigned short curpath[MAX_CURPATH]; /* The currently selected path. */ - size_t curpathlen; /* Length of this path or 0 if unknown. */ int is_ef; /* True if the path points to an EF. */ + size_t curpathlen; /* Length of this path or 0 if unknown. */ struct df_info_s *df_infos; sc_security_env_t sec_env; /* current security environment */ }; @@ -131,8 +131,7 @@ static const struct sc_asn1_entry c_asn1_public[] = { }; static int load_special_files(sc_card_t * card); -static int select_part(sc_card_t * card, u8 kind, unsigned short int fid, - sc_file_t ** file); +static int select_part(sc_card_t * card, u8 kind, unsigned short int fid, sc_file_t ** file); /* Return the DF_info for the current path. If does not yet exist, create it. Returns NULL on error. */ @@ -152,8 +151,8 @@ static struct df_info_s *get_df_info(sc_card_t * card) for (dfi = priv->df_infos; dfi; dfi = dfi->next) { if (dfi->pathlen == priv->curpathlen - && !memcmp(dfi->path, priv->curpath, - dfi->pathlen * sizeof *dfi->path)) + && !memcmp(dfi->path, priv->curpath, + dfi->pathlen * sizeof *dfi->path)) return dfi; } /* Not found, create it. */ @@ -194,17 +193,10 @@ static int mcrd_delete_ref_to_authkey(sc_card_t * card) { sc_apdu_t apdu; int r; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - - if(!(card != NULL)) + u8 sbuf[2] = { 0x83, 0x00 }; + if(card == NULL) return SC_ERROR_INTERNAL; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xA4); - - sbuf[0] = 0x83; - sbuf[1] = 0x00; - apdu.data = sbuf; - apdu.lc = 2; - apdu.datalen = 2; + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xA4, sbuf, 2, NULL, 0); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -214,66 +206,10 @@ static int mcrd_delete_ref_to_signkey(sc_card_t * card) { sc_apdu_t apdu; int r; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - if(!(card != NULL)) + u8 sbuf[2] = { 0x83, 0x00 }; + if(card == NULL) return SC_ERROR_INTERNAL; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); - - sbuf[0] = 0x83; - sbuf[1] = 0x00; - apdu.data = sbuf; - apdu.lc = 2; - apdu.datalen = 2; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - -} - -static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) -{ - sc_apdu_t apdu; - sc_path_t path; - int r; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 keyref_data[SC_ESTEID_KEYREF_FILE_RECLEN]; - if(!(card != NULL)) - return SC_ERROR_INTERNAL; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); - /* track the active keypair */ - sc_format_path("0033", &path); - r = sc_select_file(card, &path, NULL); - LOG_TEST_RET(card->ctx, r, "Can't select keyref info file 0x0033"); - r = sc_read_record(card, 1, keyref_data, - SC_ESTEID_KEYREF_FILE_RECLEN, SC_RECORD_BY_REC_NR); - LOG_TEST_RET(card->ctx, r, "Can't read keyref info file!"); - - sc_log(card->ctx, - "authkey reference 0x%02x%02x\n", - keyref_data[9], keyref_data[10]); - - sc_log(card->ctx, - "signkey reference 0x%02x%02x\n", - keyref_data[19], keyref_data[20]); - - sbuf[0] = 0x83; - sbuf[1] = 0x03; - sbuf[2] = 0x80; - switch (key_reference) { - case 1: - sbuf[3] = keyref_data[9]; - sbuf[4] = keyref_data[10]; - break; - case 2: - sbuf[3] = keyref_data[19]; - sbuf[4] = keyref_data[20]; - break; - } - apdu.data = sbuf; - apdu.lc = 5; - apdu.datalen = 5; + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, sbuf, 2, NULL, 0); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -284,16 +220,6 @@ static int is_esteid_card(sc_card_t *card) return card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 ? 1 : 0; } -static int select_esteid_df(sc_card_t * card) -{ - int r; - sc_path_t tmppath; - sc_format_path ("3F00EEEE", &tmppath); - r = sc_select_file (card, &tmppath, NULL); - LOG_TEST_RET(card->ctx, r, "esteid select DF failed"); - return r; -} - static int mcrd_match_card(sc_card_t * card) { int i = 0, r = 0; @@ -496,7 +422,7 @@ static void process_arr(sc_card_t * card, const u8 * buf, size_t buflen) if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS || p == NULL) break; - left -= (p - buf); + left -= (size_t)(p - buf); tag |= cla; if (tag == 0x80 && taglen != 1) { @@ -641,7 +567,7 @@ static void process_fcp(sc_card_t * card, sc_file_t * file, for (i = 0; i < taglen; i++) { if (isalnum(tag[i]) || ispunct(tag[i]) || isspace(tag[i])) - name[i] = tag[i]; + name[i] = (const char)tag[i]; else name[i] = '?'; } @@ -1005,7 +931,7 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) pathptr = pathtmp; for (n = 0; n < path->len; n += 2) pathptr[n >> 1] = - (path->value[n] << 8) | path->value[n + 1]; + (unsigned short)((path->value[n] << 8) | path->value[n + 1]); pathlen = path->len >> 1; if (pathlen == priv->curpathlen && priv->is_ef != 2) { @@ -1040,19 +966,6 @@ mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file) return r; } -/* Crypto operations */ -static int mcrd_restore_se(sc_card_t * card, int se_num) -{ - sc_apdu_t apdu; - int r; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - return sc_check_sw(card, apdu.sw1, apdu.sw2); -} - - /* It seems that MICARDO does not fully comply with ISO, so I use values gathered from peeking actual signing operations using a different system. @@ -1064,58 +977,19 @@ static int mcrd_set_security_env(sc_card_t * card, { struct mcrd_priv_data *priv; sc_apdu_t apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[5]; u8 *p; - int r, locked = 0; + int r = 0, locked = 0; - if (!(card != NULL && env != NULL)) + if (card == NULL || env == NULL) return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); priv = DRVDATA(card); - /* special environment handling for esteid, stolen from openpgp */ - if (is_esteid_card(card)) { - /* some sanity checks */ - if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - if (env->algorithm != SC_ALGORITHM_RSA && env->algorithm != SC_ALGORITHM_EC) - return SC_ERROR_INVALID_ARGUMENTS; - } - if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) - || env->key_ref_len != 1) - return SC_ERROR_INVALID_ARGUMENTS; - - /* Make sure we always start from MF */ - r = sc_select_file (card, sc_get_mf_path(), NULL); - if (r < 0) - return r; - /* We now know that cache is not valid */ - select_esteid_df(card); - switch (env->operation) { - case SC_SEC_OPERATION_DECIPHER: - case SC_SEC_OPERATION_DERIVE: - sc_log(card->ctx, - "Using keyref %d to decipher\n", - env->key_ref[0]); - mcrd_restore_se(card, 6); - mcrd_delete_ref_to_authkey(card); - mcrd_delete_ref_to_signkey(card); - mcrd_set_decipher_key_ref(card, env->key_ref[0]); - break; - case SC_SEC_OPERATION_SIGN: - sc_log(card->ctx, "Using keyref %d to sign\n", - env->key_ref[0]); - mcrd_restore_se(card, 1); - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - priv->sec_env = *env; - return 0; - } - /* some sanity checks */ if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - if (env->algorithm != SC_ALGORITHM_RSA) + if (env->algorithm != SC_ALGORITHM_RSA && + (is_esteid_card(card) && env->algorithm != SC_ALGORITHM_EC)) return SC_ERROR_INVALID_ARGUMENTS; } if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) @@ -1124,48 +998,40 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - sc_log(card->ctx, - "Using keyref %d to decipher\n", - env->key_ref[0]); + case SC_SEC_OPERATION_DERIVE: + sc_log(card->ctx, "Using keyref %d to decipher\n", env->key_ref[0]); mcrd_delete_ref_to_authkey(card); mcrd_delete_ref_to_signkey(card); - mcrd_set_decipher_key_ref(card, env->key_ref[0]); break; case SC_SEC_OPERATION_SIGN: - sc_log(card->ctx, "Using keyref %d to sign\n", - env->key_ref[0]); + sc_log(card->ctx, "Using keyref %d to sign\n", env->key_ref[0]); break; default: return SC_ERROR_INVALID_ARGUMENTS; } priv->sec_env = *env; + if (is_esteid_card(card)) { + return 0; + } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); - apdu.le = 0; p = sbuf; + *p++ = 0x83; + *p++ = 0x03; + *p++ = 0x80; + *p++ = env->key_ref[0]; + *p++ = 0; switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - apdu.p1 = 0x41; - apdu.p2 = 0xB8; + case SC_SEC_OPERATION_DERIVE: + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB8, sbuf, 5, NULL, 0); break; case SC_SEC_OPERATION_SIGN: - apdu.p1 = 0x41; - apdu.p2 = 0xB6; + sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, sbuf, 5, NULL, 0); break; default: return SC_ERROR_INVALID_ARGUMENTS; } - *p++ = 0x83; - *p++ = 0x03; - *p++ = 0x80; - *p++ = env->key_ref[0]; - *p++ = 0; - r = p - sbuf; - apdu.lc = r; - apdu.datalen = r; - apdu.data = sbuf; - apdu.resplen = 0; if (se_num > 0) { r = sc_lock(card); LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); From 8dc67e6a6139a05eb6e8693d0c730d314b03e817 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 5 Aug 2019 01:17:58 +0200 Subject: [PATCH 0965/4321] use statement for noop --- src/libopensc/sc-ossl-compat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 5222b1f99b..075b1afd22 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -49,10 +49,10 @@ extern "C" { */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) # if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L -#define ERR_load_crypto_strings(x) {} -#define SSL_load_error_strings(x) {} -#define ERR_free_strings(x) {} -#define ENGINE_load_dynamic(x) {} +#define ERR_load_crypto_strings(x) while (0) continue +#define SSL_load_error_strings(x) while (0) continue +#define ERR_free_strings(x) while (0) continue +#define ENGINE_load_dynamic(x) while (0) continue #define EVP_CIPHER_CTX_cleanup(x) EVP_CIPHER_CTX_reset(x) #define EVP_CIPHER_CTX_init(x) EVP_CIPHER_CTX_reset(x) # endif From 0e97ef2ce3a8a336cead7a6c530df71cea1493fe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 5 Aug 2019 01:22:05 +0200 Subject: [PATCH 0966/4321] don't use sc_format_apdu_ex in default driver fixes https://github.com/OpenSC/OpenSC/issues/1731 closes https://github.com/OpenSC/OpenSC/pull/1734 --- src/libopensc/iso7816.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index a9b480eaa0..74c3b9655b 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -147,7 +147,10 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun return SC_ERROR_OFFSET_TOO_LARGE; } - sc_format_apdu_ex(card, &apdu, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF, NULL, 0, buf, count); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF); + apdu.le = count; + apdu.resplen = count; + apdu.resp = buf; fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); @@ -1496,7 +1499,7 @@ int iso7816_logout(sc_card_t *card, unsigned char pin_reference) int r; sc_apdu_t apdu; - sc_format_apdu_ex(card, &apdu, 0x20, 0xFF, pin_reference, NULL, 0, NULL, 0); + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0xFF, pin_reference); r = sc_transmit_apdu(card, &apdu); if (r < 0) From 0c563df0c1fd23f6a6fd327f08e077ff2f4704e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 5 Aug 2019 01:33:19 +0200 Subject: [PATCH 0967/4321] document sc_format_apdu_ex() --- src/libopensc/opensc.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index a65a584aff..57f2681458 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -815,6 +815,12 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); void sc_format_apdu(struct sc_card *card, struct sc_apdu *apdu, int cse, int ins, int p1, int p2); +/** Format an APDU based on the data to be sent and received. + * + * Calls \a sc_transmit_apdu() by determining the APDU case based on \a datalen + * and \a resplen. As result, no chaining or GET RESPONSE will be performed in + * sc_format_apdu(). + */ void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, u8 ins, u8 p1, u8 p2, const u8 *data, size_t datalen, u8 *resp, size_t resplen); From b6be87a348b9364ad0e3e00781017a76613e59bd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 7 Aug 2019 23:58:25 +0200 Subject: [PATCH 0968/4321] make sc_format_apdu_ex agnostic to card properties --- src/libopensc/card-esteid2018.c | 14 +++++++------- src/libopensc/card.c | 9 +++++---- src/libopensc/opensc.h | 7 ++++--- src/sm/sm-eac.c | 20 ++++++++++---------- src/tools/goid-tool.c | 6 +++--- src/tools/npa-tool.c | 2 +- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 9de32e8a3b..21618b75df 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -170,11 +170,11 @@ static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env sc_log(card->ctx, "algo: %d operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 1) { - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0); } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 2) { - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == 1) { - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0); } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } @@ -204,10 +204,10 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data switch (env->key_ref[0]) { case 1: /* authentication key */ - sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, le); + sc_format_apdu_ex(&apdu, 0x00, 0x88, 0, 0, sbuf, datalen, out, le); break; default: - sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, le); + sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, le); } SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed"); @@ -232,7 +232,7 @@ static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { } get_pin_info[6] = pin_reference & 0x0F; // mask out local/global - sc_format_apdu_ex(card, &apdu, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, sizeof(apdu_resp)); + sc_format_apdu_ex(&apdu, 0x00, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, sizeof(apdu_resp)); SC_TRANSMIT_TEST_RET(card, apdu, "GET DATA(pin info) failed"); if (apdu.resplen < 32) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -325,4 +325,4 @@ struct sc_card_driver *sc_get_esteid2018_driver(void) { esteid_ops.pin_cmd = esteid_pin_cmd; return &esteid2018_driver; -} \ No newline at end of file +} diff --git a/src/libopensc/card.c b/src/libopensc/card.c index df2ab3a20a..1cc1f3955c 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -100,16 +100,17 @@ void sc_format_apdu_cse_lc_le(struct sc_apdu *apdu) } } -void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, - u8 ins, u8 p1, u8 p2, const u8 *data, size_t datalen, u8 *resp, size_t resplen) +void sc_format_apdu_ex(struct sc_apdu *apdu, + u8 cla, u8 ins, u8 p1, u8 p2, + const u8 *data, size_t datalen, + u8 *resp, size_t resplen) { if (!apdu) { return; } memset(apdu, 0, sizeof(*apdu)); - if (card) - apdu->cla = (u8) card->cla; + apdu->cla = cla; apdu->ins = ins; apdu->p1 = p1; apdu->p2 = p2; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 57f2681458..38ad5fa85e 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -821,9 +821,10 @@ void sc_format_apdu(struct sc_card *card, struct sc_apdu *apdu, * and \a resplen. As result, no chaining or GET RESPONSE will be performed in * sc_format_apdu(). */ -void sc_format_apdu_ex(struct sc_card *card, struct sc_apdu *apdu, - u8 ins, u8 p1, u8 p2, - const u8 *data, size_t datalen, u8 *resp, size_t resplen); +void sc_format_apdu_ex(struct sc_apdu *apdu, + u8 cla, u8 ins, u8 p1, u8 p2, + const u8 *data, size_t datalen, + u8 *resp, size_t resplen); int sc_check_apdu(struct sc_card *, const struct sc_apdu *); diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 5338019456..b1d660cc78 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -526,7 +526,7 @@ static int eac_mse(sc_card_t *card, chat, &d); if (r < 0) goto err; - sc_format_apdu_ex(card, &apdu, ISO_MSE, p1, p2, + sc_format_apdu_ex(&apdu, 0x00, ISO_MSE, p1, p2, d, r, NULL, 0); r = sc_transmit_apdu(card, &apdu); @@ -626,7 +626,7 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, goto err; } - sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; @@ -712,7 +712,7 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; @@ -798,7 +798,7 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; @@ -887,7 +887,7 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, goto err; } - sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, + sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); @@ -1392,7 +1392,7 @@ static int eac_get_challenge(sc_card_t *card, goto err; } - sc_format_apdu_ex(card, &apdu, 0x84, 0x00, 0x00, NULL, 0, challenge, len); + sc_format_apdu_ex(&apdu, 0x00, 0x84, 0x00, 0x00, NULL, 0, challenge, len); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1425,7 +1425,7 @@ static int eac_verify(sc_card_t *card, goto err; } - sc_format_apdu_ex(card, &apdu, 0x2A, 0x00, 0xbe, (unsigned char *) cert, length, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x00, 0xbe, (unsigned char *) cert, length, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1449,7 +1449,7 @@ static int eac_external_authenticate(sc_card_t *card, goto err; } - sc_format_apdu_ex(card, &apdu, 0x82, 0x00, 0x00, signature, signature_len, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x82, 0x00, 0x00, signature, signature_len, NULL, 0); r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -1689,7 +1689,7 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, r = SC_ERROR_INTERNAL; goto err; } - sc_format_apdu_ex(card, &apdu, ISO_GENERAL_AUTHENTICATE, 0, 0, d, r, resp, sizeof resp); + sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0, 0, d, r, resp, sizeof resp); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); @@ -2436,7 +2436,7 @@ int eac_pace_get_tries_left(sc_card_t *card, r = eac_mse_set_at_pace(card, 0, pin_id, 0, &sw1, &sw2); #else sc_apdu_t apdu; - sc_format_apdu_ex(card, &apdu, ISO_MSE, 0xC1, 0xA4, NULL, 0, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, ISO_MSE, 0xC1, 0xA4, NULL, 0, NULL, 0); r = sc_transmit_apdu(card, &apdu); sw1 = apdu.sw1; sw2 = apdu.sw2; diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 19766e8b5f..2a4963a8fe 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -114,7 +114,7 @@ soc_info(sc_context_t *ctx, sc_card_t *card) { NULL , 0 , 0 , 0 , NULL , NULL } }; - sc_format_apdu_ex(card, &apdu, 0x61, 0x00, 0x00, NULL, 0, rbuf, sizeof rbuf); + sc_format_apdu_ex(&apdu, 0x00, 0x61, 0x00, 0x00, NULL, 0, rbuf, sizeof rbuf); apdu.cla = 0x80; if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS) { @@ -236,7 +236,7 @@ soc_verify(sc_card_t *card, unsigned char p2) { int ok = 0; sc_apdu_t apdu; - sc_format_apdu_ex(card, &apdu, 0x20, 0x00, p2, NULL, 0, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x20, 0x00, p2, NULL, 0, NULL, 0); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_transmit_apdu(card, &apdu), "Verification failed"); @@ -272,7 +272,7 @@ soc_change(sc_card_t *card, unsigned char p1, unsigned char p2) { int ok = 0; sc_apdu_t apdu; - sc_format_apdu_ex(card, &apdu, 0x24, p1, p2, NULL, 0, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x24, p1, p2, NULL, 0, NULL, 0); SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, sc_transmit_apdu(card, &apdu), "Changing secret failed"); diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index cca9839c34..aea837a7d1 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -156,7 +156,7 @@ static void verify(sc_card_t *card, const char *verify_str, sc_apdu_t apdu; int r; - sc_format_apdu_ex(card, &apdu, ISO_VERIFY, 0x80, 0, data, data_len, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, ISO_VERIFY, 0x80, 0, data, data_len, NULL, 0); apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); From d7a86d397f99cccc0afb297d2619ad0612b606b3 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 5 Aug 2019 09:38:39 +0200 Subject: [PATCH 0969/4321] opensc-tool: do not connect card if not neccesary, fix util.c errors opensc-tool: for options --version, --list-readers, -D, etc. we do not need to connect card/reader. This removes unnecessary error messages if card is not present in card reader or if reader is not available. util.c: use symbolic error codes, pass error codes to caller without change. --- src/tools/opensc-tool.c | 2 ++ src/tools/util.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 5234ea117c..c850a21d8c 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -848,6 +848,8 @@ int main(int argc, char *argv[]) goto end; action_count--; } + if (action_count <= 0) + goto end; err = util_connect_reader(ctx, &reader, opt_reader, opt_wait, verbose); if (err) { diff --git a/src/tools/util.c b/src/tools/util.c index f08931774b..5faab38595 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -72,25 +72,25 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED, &found, &event, -1, NULL); if (r < 0) { fprintf(stderr, "Error while waiting for a reader: %s\n", sc_strerror(r)); - return 3; + return r; } r = sc_ctx_detect_readers(ctx); if (r < 0) { fprintf(stderr, "Error while refreshing readers: %s\n", sc_strerror(r)); - return 3; + return r; } } fprintf(stderr, "Waiting for a card to be inserted...\n"); r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1, NULL); if (r < 0) { fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r)); - return 3; + return r; } *reader = found; } else if (sc_ctx_get_reader_count(ctx) == 0) { fprintf(stderr, "No smart card readers found.\n"); - return 1; + return SC_ERROR_NO_READERS_FOUND; } else { if (!reader_id) { @@ -146,15 +146,15 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, if (!(*reader)) { fprintf(stderr, "Reader \"%s\" not found (%d reader(s) detected)\n", reader_id, sc_ctx_get_reader_count(ctx)); - return 1; + return SC_ERROR_READER; } if (sc_detect_card_presence(*reader) <= 0) { fprintf(stderr, "Card not present.\n"); - return 3; + return SC_ERROR_CARD_NOT_PRESENT; } } - return 0; + return SC_SUCCESS; } int util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, @@ -172,7 +172,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, r = sc_connect_card(reader, &card); if (r < 0) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); - return 1; + return r; } if (verbose) @@ -183,12 +183,12 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, if (r < 0) { fprintf(stderr, "Failed to lock card: %s\n", sc_strerror(r)); sc_disconnect_card(card); - return 1; + return r; } } *cardp = card; - return 0; + return SC_SUCCESS; } int From 9099d95c775e98e4bc88a628d8597cfc2d61fd0c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 20 Aug 2019 14:21:44 +0200 Subject: [PATCH 0970/4321] fixed interface change fixes https://github.com/OpenSC/OpenSC/issues/1768 --- src/libopensc/card-mcrd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 1c71aa3250..7a443c0840 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -196,7 +196,7 @@ static int mcrd_delete_ref_to_authkey(sc_card_t * card) u8 sbuf[2] = { 0x83, 0x00 }; if(card == NULL) return SC_ERROR_INTERNAL; - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xA4, sbuf, 2, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xA4, sbuf, 2, NULL, 0); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -209,7 +209,7 @@ static int mcrd_delete_ref_to_signkey(sc_card_t * card) u8 sbuf[2] = { 0x83, 0x00 }; if(card == NULL) return SC_ERROR_INTERNAL; - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, sbuf, 2, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, sbuf, 2, NULL, 0); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -1023,10 +1023,10 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_DERIVE: - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB8, sbuf, 5, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, sbuf, 5, NULL, 0); break; case SC_SEC_OPERATION_SIGN: - sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, sbuf, 5, NULL, 0); + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, sbuf, 5, NULL, 0); break; default: return SC_ERROR_INVALID_ARGUMENTS; From b0241eefa1b47f1420456f5dbc43564d59961a54 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Palant Date: Tue, 20 Aug 2019 15:17:14 +0200 Subject: [PATCH 0971/4321] Integrated virt_CACard in CI jobs (#1757) Was: "Implement OpenSC CI without HW cards" (https://github.com/OpenSC/OpenSC/pull/1757) --- .gitlab-ci.yml | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 57 +++++++++++++++++++--- README.md | 1 + configure.ac | 1 + 4 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..d116076259 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,126 @@ +before_script: + # Avoid picking up PIV endpoint in CAC cards + - sed -e "/PIV-II/d" -i src/libopensc/ctx.c + # enable debug messages in the testsuite + - sed -e "s/^p11test_CFLAGS/#p11test_CFLAGS/g" -i src/tests/p11test/Makefile.am + - ./bootstrap + - ./configure + - make -j4 + - make check + - make install + - ldconfig /usr/local/lib + - git clone https://github.com/PL4typus/virt_cacard.git + - cd virt_cacard && export CACARD_DIR=$PWD && ./autogen.sh && ./configure && make +variables: + SOFTHSM2_CONF: softhsm2.conf + CNTNR_REGISTRY: pl4typus/opensc-images + FEDORA29_BUILD: fedora-29 + FEDORA30_BUILD: fedora-30 + UBUNTU_BUILD: ubuntu-18.04 + DEBIAN_BUILD: debian-testing + +.job_base: &base_job + artifacts: + expire_in: '1 week' + when: on_failure + paths: + - src/tests/p11test/*.log + +.job_template: &functional_test + <<: *base_job + artifacts: + expire_in: '1 week' + when: on_failure + paths: + - src/tests/p11test/*.log + - src/tests/p11test/*.json + - tests/test-suite.log + cache: + paths: + - src/tests/p11test/*.json + +.virt_cacard: &virt_cacard + only: + - virt_cacard + script: + - ./setup-softhsm2.sh + - cd ../src/tests/p11test/ + - pcscd -x + - ./p11test -s 0 -p 12345678 -o cac.json -i | tee cac.log & + - sleep 5 + - cd $CACARD_DIR + - ./virt_cacard & + - cd ../src/tests/p11test/ + - wait $(ps aux | grep '[p]11test'| awk '{print $2}') + - kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') + - if [[ -f cac_old.json ]]; then diff -u3 cac_old.json cac.json; fi + - cp cac.json cac_old.json + # cache the results for the next run + tags: + - shared + +.virt_cacard_valgrind: &virt_cacard_valgrind + only: + - virt_cacard + script: + - ./setup-softhsm2.sh + - cd ../src/tests/p11test/ + # remove the dlcose() calls to have reasonable traces + - sed '/if(pkcs11_so)/I {N;d;}' -i p11test_loader.c + - make + - pcscd -x + - valgrind --leak-check=full --trace-children=yes --suppressions=p11test.supp ./p11test -s 0 -p 12345678 -i 2>&1| tee cac.log & + - sleep 5 + - cd $CACARD_DIR + - ./virt_cacard & + - wait $(ps aux | grep '[v]algrind'| awk '{print $2}') + - kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') + - cd ../src/tests/p11test/ + - grep "definitely lost:.*0 bytes in 0 blocks" cac.log + tags: + - shared + +################################ +## Virtual CACard ## +################################ + +Fedora29 Build and Test virt_cacard: + <<: *functional_test + image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA29_BUILD:latest + <<: *virt_cacard + +Fedora30 Build and Test virt_cacard: + <<: *functional_test + image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA30_BUILD:latest + <<: *virt_cacard + +Ubuntu18.04 Build and Test virt_cacard: + <<: *functional_test + image: $CI_REGISTRY/$CNTNR_REGISTRY/$UBUNTU_BUILD:latest + <<: *virt_cacard + +Debian-testing Build and Test virt_cacard: + <<: *functional_test + image: $CI_REGISTRY/$CNTNR_REGISTRY/$DEBIAN_BUILD:latest + <<: *virt_cacard + +Fedora29 Build and Test virt_cacard with valgrind: + <<: *base_job + image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA29_BUILD:latest + <<: *virt_cacard_valgrind + +Fedora30 Build and Test virt_cacard with valgrind: + <<: *base_job + image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA30_BUILD:latest + <<: *virt_cacard_valgrind + +Ubuntu18.04 Build and Test virt_cacard with valgrind: + <<: *base_job + image: $CI_REGISTRY/$CNTNR_REGISTRY/$UBUNTU_BUILD:latest + <<: *virt_cacard_valgrind + +Debian-testing Build and Test virt_cacard with valgrind: + <<: *base_job + image: $CI_REGISTRY/$CNTNR_REGISTRY/$DEBIAN_BUILD:latest + <<: *virt_cacard_valgrind + diff --git a/.travis.yml b/.travis.yml index 4164bbc0b1..b395456fdc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,12 @@ matrix: - HOST=i686-w64-mingw32 - DO_PUSH_ARTIFACT=yes - env: DO_COVERITY_SCAN=yes + - compiler: gcc + os: linux + dist: bionic + env: + - DO_SIMULATION=cac + sudo: true env: global: @@ -48,7 +54,6 @@ addons: - gcc-mingw-w64-x86-64 - libpcsclite-dev - mingw-w64 - - wine - xsltproc - gengetopt - libcmocka-dev @@ -69,6 +74,13 @@ before_install: brew install gengetopt help2man cmocka ccache; export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi + - if [ "${DO_SIMULATION}" = "cac" ]; then + sudo apt-get install -y libglib2.0-dev libnss3-dev pkgconf libtool make autoconf autoconf-archive automake libsofthsm2-dev softhsm2 softhsm2-common help2man gnutls-bin libcmocka-dev libusb-dev libudev-dev flex libnss3-tools libssl-dev libpcsclite1; + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; + fi + - if [ -n "${HOST}" ]; then + sudo apt-get install -y wine; + fi before_script: - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then @@ -172,6 +184,23 @@ before_script: sudo /etc/init.d/pcscd restart; fi + - if [ "${DO_SIMULATION}" = "cac" ]; then + git clone https://github.com/frankmorgner/vsmartcard.git; + cd vsmartcard/virtualsmartcard; + autoreconf -vis && ./configure && make -j4 && sudo make install; + + cd $TRAVIS_BUILD_DIR; + git clone https://gitlab.freedesktop.org/spice/libcacard.git; + cd libcacard && ./autogen.sh --prefix=/usr && make -j4 && sudo make install; + + cd $TRAVIS_BUILD_DIR; + git clone https://github.com/PL4typus/virt_cacard.git; + cd virt_cacard && ./autogen.sh && ./configure && make; + + cd $TRAVIS_BUILD_DIR; + sudo /etc/init.d/pcscd restart; + fi + script: - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then if [ "${TRAVIS_OS_NAME}" = "osx" ]; then @@ -249,6 +278,20 @@ script: set +ex; fi + - if [ "${DO_SIMULATION}" = "cac" ]; then + cd $TRAVIS_BUILD_DIR; + make check && sudo make install; + export LD_LIBRARY_PATH=/usr/local/lib; + cd src/tests/p11test/; + ./p11test -s 0 -p 12345678 -i & + sleep 5; + cd $TRAVIS_BUILD_DIR/virt_cacard; + ./setup-softhsm2.sh; + export SOFTHSM2_CONF=$PWD/softhsm2.conf; + ./virt_cacard & + wait $(ps aux | grep '[p]11test'| awk '{print $2}'); + kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}'); + fi after_script: # kill process started during compilation to finish the build, see @@ -265,15 +308,15 @@ after_script: fi before_cache: - - brew cleanup + - brew cleanup cache: apt: true ccache: true directories: - - $HOME/.m2/ - - $HOME/Library/Caches/Homebrew - - openssl_bin - - openpace_bin + - $HOME/.m2/ + - $HOME/Library/Caches/Homebrew + - openssl_bin + - openpace_bin files: - - isetup-5.5.6.exe + - isetup-5.5.6.exe diff --git a/README.md b/README.md index 40ba98010b..0bd4db01c9 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Build and test status of specific cards: | Cards | Status | |---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| | CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| [virt_CACard](https://github.com/OpenSC/OpenSC/tree/virt_cacard) | [![virt_CACard](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | | [Coolkey](https://github.com/dogtagpki/coolkey/tree/master/applet) | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/build.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | | [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | | [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | diff --git a/configure.ac b/configure.ac index d275cfabb1..6196dd5446 100644 --- a/configure.ac +++ b/configure.ac @@ -1114,6 +1114,7 @@ AC_CONFIG_FILES([ MacOSX/Distribution.xml MacOSX/resources/Welcome.html ]) + AC_OUTPUT cat < Date: Mon, 26 Aug 2019 10:17:05 +0200 Subject: [PATCH 0972/4321] Add definition of CKA_OTP_* constants --- src/pkcs11/pkcs11.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 7673d41a99..1f5f282bc5 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -464,6 +464,20 @@ typedef unsigned long ck_attribute_type_t; #define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) +#define CKA_OTP_FORMAT (0x220UL) +#define CKA_OTP_LENGTH (0x221UL) +#define CKA_OTP_TIME_INTERVAL (0x222UL) +#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) +#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) +#define CKA_OTP_TIME_REQUIREMENT (0x225UL) +#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) +#define CKA_OTP_PIN_REQUIREMENT (0x227UL) +#define CKA_OTP_USER_IDENTIFIER (0x22AUL) +#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) +#define CKA_OTP_SERVICE_LOGO (0x22CUL) +#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) +#define CKA_OTP_COUNTER (0x22EUL) +#define CKA_OTP_TIME (0x22FUL) #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) #define CKA_VENDOR_DEFINED (1UL << 31) From 43a8f870e5bbe6eda5fae7ff52400a337fa64ae2 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Mon, 26 Aug 2019 10:18:04 +0200 Subject: [PATCH 0973/4321] pkcs11-spy: add support of CKA_OTP_* values --- src/pkcs11/pkcs11-display.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 6347320062..db24162ade 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -750,6 +750,20 @@ type_spec ck_attribute_specs[] = { { CKA_WRAP_WITH_TRUSTED , "CKA_WRAP_WITH_TRUSTED ", print_generic, NULL }, { CKA_WRAP_TEMPLATE , "CKA_WRAP_TEMPLATE ", print_generic, NULL }, { CKA_UNWRAP_TEMPLATE , "CKA_UNWRAP_TEMPLATE ", print_generic, NULL }, + { CKA_OTP_FORMAT , "CKA_OTP_FORMAT ", print_generic, NULL }, + { CKA_OTP_LENGTH , "CKA_OTP_LENGTH ", print_generic, NULL }, + { CKA_OTP_TIME_INTERVAL , "CKA_OTP_TIME_INTERVAL ", print_generic, NULL }, + { CKA_OTP_USER_FRIENDLY_MODE, "CKA_OTP_USER_FRIENDLY_MODE ", print_boolean, NULL }, + { CKA_OTP_CHALLENGE_REQUIREMENT, "CKA_OTP_CHALLENGE_REQUIREMENT ", print_generic, NULL }, + { CKA_OTP_TIME_REQUIREMENT, "CKA_OTP_TIME_REQUIREMENT ", print_generic, NULL }, + { CKA_OTP_COUNTER_REQUIREMENT, "CKA_OTP_COUNTER_REQUIREMENT ", print_generic, NULL }, + { CKA_OTP_PIN_REQUIREMENT, "CKA_OTP_PIN_REQUIREMENT ", print_generic, NULL }, + { CKA_OTP_COUNTER , "CKA_OTP_COUNTER ", print_generic, NULL }, + { CKA_OTP_TIME , "CKA_OTP_TIME ", print_print, NULL }, + { CKA_OTP_USER_IDENTIFIER, "CKA_OTP_USER_IDENTIFIER ", print_print, NULL }, + { CKA_OTP_SERVICE_IDENTIFIER, "CKA_OTP_SERVICE_IDENTIFIER ", print_print, NULL }, + { CKA_OTP_SERVICE_LOGO , "CKA_OTP_SERVICE_LOGO ", print_generic, NULL }, + { CKA_OTP_SERVICE_LOGO_TYPE, "CKA_OTP_SERVICE_LOGO_TYPE ", print_print, NULL }, { CKA_GOSTR3410_PARAMS , "CKA_GOSTR3410_PARAMS ", print_generic, NULL }, { CKA_GOSTR3411_PARAMS , "CKA_GOSTR3411_PARAMS ", print_generic, NULL }, { CKA_GOST28147_PARAMS , "CKA_GOST28147_PARAMS ", print_generic, NULL }, From 2240abcef124c857ee61039bcf608396e659b5d3 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Mon, 26 Aug 2019 10:37:06 +0200 Subject: [PATCH 0974/4321] spy: display -1 instead of 18446744073709551615 buf_len is a CK_ULONG (unsigned long). But if the attribute is sensitive or is not extractable or is invalid for the object then the library set the buffer length value to (CK_LONG)-1. It is more friendly to see "-1" instead of "18446744073709551615" (on 64-bits CPU) --- src/pkcs11/pkcs11-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index db24162ade..7a0c3d50c8 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -96,7 +96,7 @@ buf_spec(CK_VOID_PTR buf_addr, CK_ULONG buf_len) #if !defined(_MSC_VER) || _MSC_VER >= 1800 const size_t prwidth = sizeof(CK_VOID_PTR) * 2; - sprintf(ret, "%0*"PRIxPTR" / %lu", (int) prwidth, (uintptr_t) buf_addr, + sprintf(ret, "%0*"PRIxPTR" / %ld", (int) prwidth, (uintptr_t) buf_addr, buf_len); #else if (sizeof(CK_VOID_PTR) == 4) From 2eab2bcd744bffd92220b311924bcc24517188e6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 13:55:18 +0200 Subject: [PATCH 0975/4321] fixed out of bounds accessing array Credit to OSS-Fuzz --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 009e2386ad..105ea886ca 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -210,7 +210,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) int decipher_flags[] = {SC_ALGORITHM_RSA_RAW, SC_ALGORITHM_RSA_PAD_PKCS1, SC_ALGORITHM_RSA_PAD_ANSI, SC_ALGORITHM_RSA_PAD_ISO9796}; - for (i = 0; i < sizeof decipher_flags; i++) { + for (i = 0; i < sizeof decipher_flags/sizeof *decipher_flags; i++) { sc_pkcs15_decipher(p15card, obj, decipher_flags[i], in, in_len, buf, sizeof buf); } @@ -221,7 +221,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) int wrap_flags[] = {0, SC_ALGORITHM_AES_ECB, SC_ALGORITHM_AES_CBC_PAD, SC_ALGORITHM_AES_CBC}; - for (i = 0; i < sizeof wrap_flags; i++) { + for (i = 0; i < sizeof wrap_flags/sizeof *wrap_flags; i++) { struct sc_pkcs15_object target_key; sc_pkcs15_unwrap(p15card, obj, &target_key, wrap_flags[i], in, in_len, param, param_len); @@ -244,7 +244,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) SC_ALGORITHM_GOSTR3410_RAW, SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411, SC_ALGORITHM_GOSTR3410_HASHES, }; - for (i = 0; i < sizeof signature_flags; i++) { + for (i = 0; i < sizeof signature_flags/sizeof *signature_flags; i++) { sc_pkcs15_compute_signature(p15card, obj, signature_flags[i], in, in_len, buf, sizeof buf); } From 2bfd022180972d865d049ddad9e122470bfbc213 Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Mon, 26 Aug 2019 15:44:35 +0200 Subject: [PATCH 0976/4321] pkcs11-spy: add support of CKM_*_PSS in C_VerifyInit() In bdb1961dee1aa0e67eb23f474f9a5dcf7d4e316d the same code was added to C_SignInit(). Now it is also used in C_VerifyInit(). --- src/pkcs11/pkcs11-spy.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 8d54cdba55..df71e48380 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -1113,6 +1113,27 @@ C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_ enter("C_VerifyInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_PSS_PARAMS *param = + (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", + param->sLen); + } else { + fprintf(spy_output, "Parameters block for %s is empty...\n", + lookup_enum(MEC_T, pMechanism->mechanism)); + } + break; + } spy_dump_ulong_in("hKey", hKey); rv = po->C_VerifyInit(hSession, pMechanism, hKey); return retne(rv); From 412a6142c27a5973c61ba540e33cdc22d5608e68 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 15:17:17 +0200 Subject: [PATCH 0977/4321] fixed out of bounds access of ASN.1 Bitstring Credit to OSS-Fuzz --- src/libopensc/asn1.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 47b42c746a..296ad5ecad 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -570,16 +570,20 @@ static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf, { const u8 *in = inbuf; u8 *out = (u8 *) outbuf; - int zero_bits = *in & 0x07; - size_t octets_left = inlen - 1; int i, count = 0; + int zero_bits; + size_t octets_left; - memset(outbuf, 0, outlen); - in++; if (outlen < octets_left) return SC_ERROR_BUFFER_TOO_SMALL; if (inlen < 1) return SC_ERROR_INVALID_ASN1_OBJECT; + + zero_bits = *in & 0x07; + octets_left = inlen - 1; + in++; + memset(outbuf, 0, outlen); + while (octets_left) { /* 1st octet of input: ABCDEFGH, where A is the MSB */ /* 1st octet of output: HGFEDCBA, where A is the LSB */ From a3fc7693f3a035a8a7921cffb98432944bb42740 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 15:21:46 +0200 Subject: [PATCH 0978/4321] Fixed out of bounds access in ASN.1 Octet string Credit to OSS-Fuzz --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 296ad5ecad..77ed4d7b70 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1469,7 +1469,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, /* Strip off padding zero */ if ((entry->flags & SC_ASN1_UNSIGNED) - && obj[0] == 0x00 && objlen > 1) { + && objlen > 1 && obj[0] == 0x00) { objlen--; obj++; } From 9b4b080be788a602fa8f01ac8d7e29cdaad07902 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 15:27:15 +0200 Subject: [PATCH 0979/4321] fixed compiler warning --- src/libopensc/asn1.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 77ed4d7b70..7df3e0a25f 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -574,15 +574,14 @@ static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf, int zero_bits; size_t octets_left; - if (outlen < octets_left) - return SC_ERROR_BUFFER_TOO_SMALL; if (inlen < 1) return SC_ERROR_INVALID_ASN1_OBJECT; - + memset(outbuf, 0, outlen); zero_bits = *in & 0x07; - octets_left = inlen - 1; in++; - memset(outbuf, 0, outlen); + octets_left = inlen - 1; + if (outlen < octets_left) + return SC_ERROR_BUFFER_TOO_SMALL; while (octets_left) { /* 1st octet of input: ABCDEFGH, where A is the MSB */ From 03ea3f719c17e097b7ef08ca5e24df855fa520bb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 15:40:32 +0200 Subject: [PATCH 0980/4321] fixed memory leak Credits to OSS-Fuzz --- src/libopensc/pkcs15-din-66291.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 241afb8a11..f9c90fc46a 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -260,6 +260,8 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { + int r; + if (!p15card || ! p15card->card) return SC_ERROR_INVALID_ARGUMENTS; @@ -270,5 +272,13 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid return SC_ERROR_WRONG_CARD; /* Init card */ - return sc_pkcs15emu_din_66291_init(p15card); + r = sc_pkcs15emu_din_66291_init(p15card); + if (r != SC_SUCCESS) { + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); + sc_file_free(p15card->file_tokeninfo); + p15card->tokeninfo = NULL; + p15card->file_tokeninfo = NULL; + } + + return r; } From bdca524aa8810bcfa2ff36744be0b261db0be448 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Aug 2019 15:59:46 +0200 Subject: [PATCH 0981/4321] Fixed memory leak Credits to OSS-Fuzz --- src/libopensc/card-isoApplet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 430cb30db5..fbdc75747f 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -211,6 +211,8 @@ isoApplet_init(sc_card_t *card) /* Obtain applet version and specific features */ if (0 > isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen)) { + free(card->drv_data); + card->drv_data = NULL; LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Error obtaining applet version."); } if(rlen < 3) From 14dec11ebdd1a71c9bd90d0f528cd5ac3514ee9d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 12:57:35 +0200 Subject: [PATCH 0982/4321] travis-ci: Try to run the tests with more recent distros The javacard simulation unfortunately does not work with anything newer --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b395456fdc..79b03c8035 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ matrix: sudo: true - compiler: gcc os: linux + dist: bionic env: - DO_SIMULATION=oseid sudo: true From 2f643948f11a4599b81235ceea2d82c89b6b986f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:15:02 +0200 Subject: [PATCH 0983/4321] ctx: Avoid potential memory leaks reported by clang --- src/libopensc/ctx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 2885056d4c..40f573ed0f 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -826,6 +826,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) set_defaults(ctx, &opts); if (0 != list_init(&ctx->readers)) { + del_drvs(&opts); sc_release_context(ctx); return SC_ERROR_OUT_OF_MEMORY; } @@ -835,6 +836,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) ctx->thread_ctx = parm->thread_ctx; r = sc_mutex_create(ctx, &ctx->mutex); if (r != SC_SUCCESS) { + del_drvs(&opts); sc_release_context(ctx); return r; } @@ -861,6 +863,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) r = ctx->reader_driver->ops->init(ctx); if (r != SC_SUCCESS) { + del_drvs(&opts); sc_release_context(ctx); return r; } From 24eaa3eaa1ad4b01de23f0fe95dfdec2475e43ef Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:18:04 +0200 Subject: [PATCH 0984/4321] card-jcop: Avoid left-shift of negative values --- src/libopensc/card-jcop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index 99c4d9e862..7cce62b6f2 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -539,7 +539,9 @@ static int jcop_create_file(sc_card_t *card, sc_file_t *file) { entry = sc_file_get_acl_entry(file, ops[i]); r = acl_to_ac_nibble(entry); - sec_attr_data[i/2] |= r << ((i % 2) ? 0 : 4); + if (r >= 0) { + sec_attr_data[i/2] |= r << ((i % 2) ? 0 : 4); + } } sc_file_set_sec_attr(file, sec_attr_data, 3); From 1b32bfe4e5ec910ba89f7971af65cd5ec6245682 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:22:33 +0200 Subject: [PATCH 0985/4321] card-coolkey: Avoid potential null dereference --- src/libopensc/card-coolkey.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 42b76eab6e..0ba7f7d70f 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1448,6 +1448,9 @@ coolkey_find_attribute(sc_card_t *card, sc_cardctl_coolkey_attribute_t *attribut return r; } obj = attribute->object->data; + if (obj == NULL) { + return SC_ERROR_INTERNAL; + } } /* should be a static assert so we catch this at compile time */ From 070a37cebd39d7dbaef444acaddc485fbc16da82 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:32:46 +0200 Subject: [PATCH 0986/4321] card-authentic: Avoid potential memory leaks --- src/libopensc/card-authentic.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 99332e55d2..6db00bfccb 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1709,22 +1709,22 @@ authentic_manage_sdo_encode_prvkey(struct sc_card *card, struct sc_pkcs15_prkey rsa = prvkey->u.rsa; /* Encode private RSA key part */ rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE_P, rsa.p.data, rsa.p.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA P encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA P encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE_Q, rsa.q.data, rsa.q.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Q encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Q encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE_PQ, rsa.iqmp.data, rsa.iqmp.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA PQ encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA PQ encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE_DP1, rsa.dmp1.data, rsa.dmp1.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA DP1 encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA DP1 encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE_DQ1, rsa.dmq1.data, rsa.dmq1.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA DQ1 encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA DQ1 encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PRIVATE, blob, blob_len, &blob01, &blob01_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Private encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Private encode error"); free (blob); blob = NULL; @@ -1735,24 +1735,27 @@ authentic_manage_sdo_encode_prvkey(struct sc_card *card, struct sc_pkcs15_prkey "modulus.len:%"SC_FORMAT_LEN_SIZE_T"u blob_len:%"SC_FORMAT_LEN_SIZE_T"u", rsa.modulus.len, blob_len); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PUBLIC_MODULUS, rsa.modulus.data, rsa.modulus.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Modulus encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Modulus encode error"); sc_log(ctx, "exponent.len:%"SC_FORMAT_LEN_SIZE_T"u blob_len:%"SC_FORMAT_LEN_SIZE_T"u", rsa.exponent.len, blob_len); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PUBLIC_EXPONENT, rsa.exponent.data, rsa.exponent.len, &blob, &blob_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Exponent encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Exponent encode error"); rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA_PUBLIC, blob, blob_len, &blob01, &blob01_len); - LOG_TEST_RET(ctx, rv, "SDO RSA Private encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA Private encode error"); free (blob); + blob = NULL; + blob_len = 0; rv = authentic_update_blob(ctx, AUTHENTIC_TAG_RSA, blob01, blob01_len, out, out_len); - LOG_TEST_RET(ctx, rv, "SDO RSA encode error"); + LOG_TEST_GOTO_ERR(ctx, rv, "SDO RSA encode error"); +err: free(blob01); - + free(blob); LOG_FUNC_RETURN(ctx, rv); } From cab5d3da173db4914866ef9b13447da29fe9da32 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:33:00 +0200 Subject: [PATCH 0987/4321] iasecc-sdo: Avoid potential memory leak --- src/libopensc/iasecc-sdo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 588fa72d79..8a938505e0 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -621,6 +621,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st sdo->docp.tries_remaining = tlv; } else { + free(tlv.value); LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "iasecc_parse_get_tlv() parse error: non DOCP tag"); } From 489886724f53f1b890fd1888e45e3fb40e0603c4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:36:28 +0200 Subject: [PATCH 0988/4321] pkcs15-tccardos: Avoid negative indexing --- src/libopensc/pkcs15-tccardos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index d6d1490c95..5409e28252 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -215,7 +215,7 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) /* read EF_CardInfo1 */ r = read_file(p15card->card, "3F001003b200", info1, &info1_len); - if (r != SC_SUCCESS) + if (r != SC_SUCCESS || info1_len < 4) return SC_ERROR_WRONG_CARD; /* read EF_CardInfo2 */ r = read_file(p15card->card, "3F001003b201", info2, &info2_len); From 14e1f3c4d3140d99fe83a02623a1ea6dac8ce65b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 13:54:18 +0200 Subject: [PATCH 0989/4321] pkcs15-tccardos: Make sure we do not overrun buffers in this wild parsing --- src/libopensc/pkcs15-tccardos.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index 5409e28252..c9a643aed5 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -230,10 +230,15 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) "found %d private keys\n", (int)key_num); /* set p1 to the address of the first key descriptor */ offset = info1_len - 4 - key_num * 2; - if (offset >= sizeof info1) + if (offset >= info1_len) return SC_ERROR_INVALID_DATA; p1 = info1 + offset; p2 = info2; + + /* This is the minimum amount of data expected by the following code without + * overunning the buffer without additional condition for cert_count == 4 */ + if (info2_len < key_num * 14) + return SC_ERROR_INVALID_DATA; for (i=0; i Date: Mon, 26 Aug 2019 13:59:02 +0200 Subject: [PATCH 0990/4321] pkcs15-sc-hsm: Avoid potential memory leaks --- src/libopensc/pkcs15-sc-hsm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index db493c3938..9bcc5bab04 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -447,8 +447,12 @@ static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(struct sc_context *ctx, sc_cvc pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); pubkey->u.rsa.exponent.len = cvc->coefficientAorExponentlen; pubkey->u.rsa.exponent.data = malloc(pubkey->u.rsa.exponent.len); - if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data) + if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data) { + free(pubkey->u.rsa.modulus.data); + free(pubkey->u.rsa.exponent.data); + free(pubkey->alg_id); return SC_ERROR_OUT_OF_MEMORY; + } memcpy(pubkey->u.rsa.exponent.data, cvc->coefficientAorExponent, pubkey->u.rsa.exponent.len); memcpy(pubkey->u.rsa.modulus.data, cvc->primeOrModulus, pubkey->u.rsa.modulus.len); From cc9020f56a84bc4006366e486ea9e2317350bada Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 14:02:47 +0200 Subject: [PATCH 0991/4321] pkcs15-sc-hsm: Avoid potential memory leaks --- src/libopensc/pkcs15-sc-hsm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 9bcc5bab04..95560281cf 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -501,14 +501,23 @@ static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_ pubkey->alg_id->params = ecp; pubkey->u.ec.ecpointQ.value = malloc(cvc->publicPointlen); - if (!pubkey->u.ec.ecpointQ.value) + if (!pubkey->u.ec.ecpointQ.value) { + free(pubkey->alg_id); + free(ecp->der.value); + free(ecp); return SC_ERROR_OUT_OF_MEMORY; + } memcpy(pubkey->u.ec.ecpointQ.value, cvc->publicPoint, cvc->publicPointlen); pubkey->u.ec.ecpointQ.len = cvc->publicPointlen; pubkey->u.ec.params.der.value = malloc(ecp->der.len); - if (!pubkey->u.ec.params.der.value) + if (!pubkey->u.ec.params.der.value) { + free(pubkey->u.ec.ecpointQ.value); + free(pubkey->alg_id); + free(ecp->der.value); + free(ecp); return SC_ERROR_OUT_OF_MEMORY; + } memcpy(pubkey->u.ec.params.der.value, ecp->der.value, ecp->der.len); pubkey->u.ec.params.der.len = ecp->der.len; From 530175009c4f753569f968ad9fafdf762521ccca Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 Aug 2019 15:13:22 +0200 Subject: [PATCH 0992/4321] tests/common: Add different path to softhsm pkcs11 library to test also on different architectures --- tests/common.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/common.sh b/tests/common.sh index 4fa1fba00c..bc9747f20e 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -4,7 +4,22 @@ SOPIN="12345678" PIN="123456" PKCS11_TOOL="../src/tools/pkcs11-tool" -P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" + +softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ + /usr/lib64/pkcs11/libsofthsm2.so \ + /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" + +for LIB in $softhsm_paths; do + echo "Testing $LIB" + if [[ -f $LIB ]]; then + P11LIB=$LIB + echo "Setting P11LIB=$LIB" + break + fi +done +if [[ -z "$P11LIB" ]]; then + echo "Warning: Could not find the softhsm pkcs11 module" +fi ERRORS=0 function assert() { From a1d3e769992e3b04ebdcbae7af578f812408372b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Aug 2019 13:29:17 +0200 Subject: [PATCH 0993/4321] openpgp: handle cards with static algorithms fixes https://github.com/OpenSC/OpenSC/issues/1659 --- src/libopensc/card-openpgp.c | 92 ++++++++++++++++++++---------------- src/tools/openpgp-tool.c | 6 ++- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index efb6a77ed3..eeb208e7c5 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2292,53 +2292,63 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ r = pgp_seek_blob(card, priv->mf, tag, &algo_blob); LOG_TEST_RET(card->ctx, r, "Cannot get old algorithm attributes"); - /* ECDSA and ECDH */ - if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ - data_len = key_info->u.ec.oid_len+1; - data = malloc(data_len); - if (!data) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - - data[0] = key_info->algorithm; - /* oid.value is type int, therefore we need to loop over the values */ - for (i=0; i < key_info->u.ec.oid_len; i++){ - data[i+1] = key_info->u.ec.oid.value[i]; + if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) { + /* ECDSA and ECDH */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + data_len = key_info->u.ec.oid_len+1; + data = malloc(data_len); + if (!data) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + data[0] = key_info->algorithm; + /* oid.value is type int, therefore we need to loop over the values */ + for (i=0; i < key_info->u.ec.oid_len; i++){ + data[i+1] = key_info->u.ec.oid.value[i]; + } } - } - - /* RSA */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ - /* We can not rely on previous key attributes anymore, as it might be ECC */ - if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0) - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + /* RSA */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + + /* We can not rely on previous key attributes anymore, as it might be ECC */ + if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0) + LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + + data_len = 6; + data = malloc(data_len); + if (!data) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + data[0] = key_info->algorithm; + ushort2bebytes(data+1, key_info->u.rsa.modulus_len); + /* OpenPGP Card only accepts 32bit as exponent lenght field, + * although you can import keys with smaller exponent; + * thus we don't change rsa.exponent_len, but ignore it here */ + ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS); + /* Import-Format of private key (e,p,q) */ + data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; + } + else { + sc_log(card->ctx, "Unknown algorithm id"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } - data_len = 6; - data = malloc(data_len); - if (!data) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + pgp_set_blob(algo_blob, data, data_len); + free(data); + r = pgp_put_data(card, tag, algo_blob->data, data_len); + /* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */ + LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); + } else { + sc_cardctl_openpgp_keygen_info_t old_key_info; - data[0] = key_info->algorithm; - ushort2bebytes(data+1, key_info->u.rsa.modulus_len); - /* OpenPGP Card only accepts 32bit as exponent lenght field, - * although you can import keys with smaller exponent; - * thus we don't change rsa.exponent_len, but ignore it here */ - ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS); - /* Import-Format of private key (e,p,q) */ - data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; - } - else { - sc_log(card->ctx, "Unknown algorithm id"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + if (pgp_parse_algo_attr_blob(algo_blob, &old_key_info) != SC_SUCCESS + || old_key_info.algorithm != key_info->algorithm) + LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT, + "Requested algorithm not supported"); + /* FIXME check whether the static parameters match the requested ones. */ } - pgp_set_blob(algo_blob, data, data_len); - free(data); - r = pgp_put_data(card, tag, algo_blob->data, data_len); - /* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */ - LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); - LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index c48d87e75a..1220346b8b 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -705,10 +705,14 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) key_info.key_id = in_key_id; key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.u.rsa.modulus_len = keylen; - key_info.u.rsa.modulus = malloc(BYTES4BITS(keylen)); + key_info.u.rsa.modulus = calloc(BYTES4BITS(keylen), 1); + /* The OpenPGP supports only 32-bit exponent. */ + key_info.u.rsa.exponent_len = 32; + key_info.u.rsa.exponent = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); free(key_info.u.rsa.modulus); + free(key_info.u.rsa.exponent); if (r < 0) { util_error("failed to generate key: %s", sc_strerror(r)); return EXIT_FAILURE; From b5b0991ec0cac61509ca3cc9a5c7228602390aef Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Aug 2019 15:45:22 +0200 Subject: [PATCH 0994/4321] Travis: test openpgp key generation --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 79b03c8035..0e4ed949e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -246,6 +246,9 @@ script: sleep 5; opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; opensc-tool -n; + # FIXME decryption with key 3 currently fails + openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; + pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; pkcs11-tool -l -t -p 123456; killall java; From f5bea7263737e294ed90754fbb43b5659e22e8c8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Aug 2019 09:43:37 +0200 Subject: [PATCH 0995/4321] Add support for 4K RSA keys in CardOS 5 (#1776) fixes https://github.com/OpenSC/OpenSC/issues/1764 --- src/libopensc/card-cardos.c | 48 +++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 73b496d4ad..d0a62823be 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -27,6 +27,7 @@ #include #include +#include #include "internal.h" #include "asn1.h" @@ -233,6 +234,8 @@ static int cardos_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_CARDOS_V5_0) { /* Starting with CardOS 5, the card supports PIN query commands */ card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + _sc_card_add_rsa_alg(card, 3072, flags, 0); + _sc_card_add_rsa_alg(card, 4096, flags, 0); } return 0; @@ -870,8 +873,6 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) { int r; - u8 buf[SC_MAX_APDU_BUFFER_SIZE]; - size_t buf_len = sizeof(buf), tmp_len = buf_len; sc_context_t *ctx; int do_rsa_pure_sig = 0; int do_rsa_sig = 0; @@ -881,12 +882,6 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - if (datalen > SC_MAX_APDU_BUFFER_SIZE) - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - if (outlen < datalen) - LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); - outlen = datalen; - /* There are two ways to create a signature, depending on the way, * the key was created: RSA_SIG and RSA_PURE_SIG. * We can use the following reasoning, to determine the correct operation: @@ -939,36 +934,49 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, } if(do_rsa_sig == 1){ + u8 *buf = malloc(datalen); + u8 *stripped_data = buf; + size_t stripped_datalen = datalen; + if (!buf) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + memcpy(buf, data, datalen); + data = buf; + sc_log(ctx, "trying RSA_SIG (just the DigestInfo)"); + /* remove padding: first try pkcs1 bt01 padding */ - r = sc_pkcs1_strip_01_padding(ctx, data, datalen, buf, &tmp_len); + r = sc_pkcs1_strip_01_padding(ctx, data, datalen, stripped_data, &stripped_datalen); if (r != SC_SUCCESS) { - const u8 *p = data; /* no pkcs1 bt01 padding => let's try zero padding * This can only work if the data tbs doesn't have a * leading 0 byte. */ - tmp_len = buf_len; - while (*p == 0 && tmp_len != 0) { - ++p; - --tmp_len; + while (*stripped_data == 0 && stripped_datalen != 0) { + ++stripped_data; + --stripped_datalen; } - memcpy(buf, p, tmp_len); } if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH)) || card->caps & SC_CARD_CAP_ONLY_RAW_HASH ) { sc_log(ctx, "trying to sign raw hash value with prefix"); - r = do_compute_signature(card, buf, tmp_len, out, outlen); - if (r >= SC_SUCCESS) + r = do_compute_signature(card, stripped_data, stripped_datalen, out, outlen); + if (r >= SC_SUCCESS) { + free(buf); LOG_FUNC_RETURN(ctx, r); + } } if (card->caps & SC_CARD_CAP_ONLY_RAW_HASH) { sc_log(ctx, "Failed to sign raw hash value with prefix when forcing"); + free(buf); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } sc_log(ctx, "trying to sign stripped raw hash value (card is responsible for prefix)"); - r = sc_pkcs1_strip_digest_info_prefix(NULL,buf,tmp_len,buf,&buf_len); - if (r != SC_SUCCESS) + r = sc_pkcs1_strip_digest_info_prefix(NULL, stripped_data, stripped_datalen, stripped_data, &stripped_datalen); + if (r != SC_SUCCESS) { + free(buf); LOG_FUNC_RETURN(ctx, r); - return do_compute_signature(card, buf, buf_len, out, outlen); + } + r = do_compute_signature(card, stripped_data, stripped_datalen, out, outlen); + free(buf); + LOG_FUNC_RETURN(ctx, r); } LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); From 6f40e9c55328d54a556c785bb71f4a3ca7ef3fa1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 30 Aug 2019 10:32:53 +0200 Subject: [PATCH 0996/4321] Unbreak Travis build --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0e4ed949e2..b4f3cfdec2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -246,7 +246,6 @@ script: sleep 5; opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; opensc-tool -n; - # FIXME decryption with key 3 currently fails openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; pkcs11-tool -l -t -p 123456; From 849de1d9e36a506fc2ce1e1ac828f7018e3580c1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Aug 2019 10:57:34 +0200 Subject: [PATCH 0997/4321] fixed memory leak when parsing malformed PKCS#15 data Credits to OSS-Fuzz --- src/libopensc/pkcs15-pubkey.c | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 84827c4ae7..9cb7710ed1 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -307,7 +307,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; - LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); + LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 decoding failed"); if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { @@ -317,8 +317,10 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, assert(info.params.len == 0); info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); info.params.data = malloc(info.params.len); - if (info.params.data == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + if (info.params.data == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } assert(sizeof(*keyinfo_gostparams) == info.params.len); keyinfo_gostparams = info.params.data; keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0]; @@ -335,8 +337,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) { - sc_pkcs15_free_key_params(&info.params); - return r; + goto err; } } else { @@ -352,15 +353,24 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, obj->data = malloc(sizeof(info)); if (obj->data == NULL) { - sc_pkcs15_free_key_params(&info.params); - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + r = SC_ERROR_OUT_OF_MEMORY; + goto err; } memcpy(obj->data, &info, sizeof(info)); r = sc_pkcs15_decode_pubkey_direct_value(p15card, obj); - LOG_TEST_RET(ctx, r, "Decode public key direct value failed"); + if (r < 0) { + free(obj->data); + obj->data = NULL; + } + LOG_TEST_GOTO_ERR(ctx, r, "Decode public key direct value failed"); - return 0; +err: + if (r < 0) { + sc_pkcs15_free_pubkey_info(&info); + } + + LOG_FUNC_RETURN(ctx, r); } @@ -1217,12 +1227,9 @@ sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key) void sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *info) { - if (info->subject.value) - free(info->subject.value); - if (info->direct.spki.value) - free(info->direct.spki.value); - if (info->direct.raw.value) - free(info->direct.raw.value); + free(info->subject.value); + free(info->direct.spki.value); + free(info->direct.raw.value); sc_pkcs15_free_key_params(&info->params); free(info); } From e971ffb48eb038202015c906adfd60f6bf7113a3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Aug 2019 11:02:50 +0200 Subject: [PATCH 0998/4321] fixed memory leak Credits to OSS-Fuzz --- src/libopensc/pkcs15-din-66291.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index f9c90fc46a..b8452b9c3b 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -260,7 +260,7 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { - int r; + int r = SC_ERROR_WRONG_CARD; if (!p15card || ! p15card->card) return SC_ERROR_INVALID_ARGUMENTS; @@ -268,12 +268,13 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid SC_FUNC_CALLED(p15card->card->ctx, 1); /* Check card */ - if (!din_66291_match_p15card(p15card, aid)) - return SC_ERROR_WRONG_CARD; + if (1 == din_66291_match_p15card(p15card, aid)) { + /* Init card */ + r = sc_pkcs15emu_din_66291_init(p15card); + } - /* Init card */ - r = sc_pkcs15emu_din_66291_init(p15card); if (r != SC_SUCCESS) { + /* reset input data to default values */ sc_pkcs15_free_tokeninfo(p15card->tokeninfo); sc_file_free(p15card->file_tokeninfo); p15card->tokeninfo = NULL; From 3e110995bc4c6c09de2c7899134213318fe05342 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Aug 2019 11:12:45 +0200 Subject: [PATCH 0999/4321] fixed undefined behavior Credits to OSS-Fuzz --- src/libopensc/sc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index c241f110fe..e79eb3d691 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -205,21 +205,26 @@ unsigned long bebytes2ulong(const u8 *buf) { if (buf == NULL) return 0UL; - return (unsigned long) (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]); + return (unsigned long)buf[0] << 24 + | (unsigned long)buf[1] << 16 + | (unsigned long)buf[2] << 8 + | (unsigned long)buf[3]; } unsigned short bebytes2ushort(const u8 *buf) { if (buf == NULL) return 0U; - return (unsigned short) (buf[0] << 8 | buf[1]); + return (unsigned short)buf[0] << 8 + | (unsigned short)buf[1]; } unsigned short lebytes2ushort(const u8 *buf) { if (buf == NULL) return 0U; - return (unsigned short)buf[1] << 8 | (unsigned short)buf[0]; + return (unsigned short)buf[1] << 8 + | (unsigned short)buf[0]; } void sc_init_oid(struct sc_object_id *oid) From f6213051409cc9b81bd3fd1e4b6c331cd7914a50 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Aug 2019 11:15:29 +0200 Subject: [PATCH 1000/4321] fixed undefined behavior when parsing negative ASN.1 Integer --- src/libopensc/asn1.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 7df3e0a25f..f6698b2e28 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -707,17 +707,19 @@ static int encode_bit_field(const u8 *inbuf, size_t inlen, int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out) { - int a = 0; + int a = 0, is_negative = 0; size_t i; if (inlen > sizeof(int) || inlen == 0) return SC_ERROR_INVALID_ASN1_OBJECT; if (inbuf[0] & 0x80) - a = -1; + is_negative = 1; for (i = 0; i < inlen; i++) { a <<= 8; a |= *inbuf++; } + if (is_negative) + a *= -1; *out = a; return 0; } From 5b8095ca2ce279cbc651c08484a256138de00798 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 30 Aug 2019 09:01:39 +0200 Subject: [PATCH 1001/4321] string null-termination fix strncpy does not generate null-terminated string, fixed by memcpy. --- src/tools/pkcs15-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 6a490b834e..e901e17d0d 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1023,7 +1023,7 @@ static int read_ssh_key(void) buf[1] = 0; buf[2] = 0; len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n); - strncpy(alg, (char *) buf+4, 19); + memcpy(alg, buf+4, 20); buf[3] = len; len += 4; From 769db0297b7382b16d02a3f797e1d6f8de23e81f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 2 Sep 2019 09:39:11 +0200 Subject: [PATCH 1002/4321] fixed memory leak Credits to OSS-Fuzz --- src/libopensc/card-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index eeb208e7c5..2f73a1abc7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -498,6 +498,7 @@ pgp_init(sc_card_t *card) sc_format_path("D276:0001:2401", &path); path.type = SC_PATH_TYPE_DF_NAME; if ((r = iso_ops->select_file(card, &path, &file)) < 0) { + sc_file_free(file); pgp_finish(card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } From 64d3d81036c027a0a52e15e2b36e125b6216a181 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Sep 2019 17:00:50 +0200 Subject: [PATCH 1003/4321] fixed invalid free --- src/libopensc/pkcs15-pubkey.c | 90 ++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 9cb7710ed1..2149d3ab71 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -213,11 +213,10 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, const u8 ** buf, size_t *buflen) { struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_pubkey_info info; + struct sc_pkcs15_pubkey_info *info; int r, gostr3410_params[3]; struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; - size_t usage_len = sizeof(info.usage); - size_t af_len = sizeof(info.access_flags); + size_t usage_len, af_len; struct sc_pkcs15_der *der = &obj->content; struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE]; @@ -242,6 +241,14 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_pkcs15_object gostr3410key_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; + info = calloc(1, sizeof *info); + if (info == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + usage_len = sizeof(info->usage); + af_len = sizeof(info->access_flags); + sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); @@ -257,7 +264,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); - sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info.subject.value, &info.subject.len, 0); + sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info->subject.value, &info->subject.len, 0); sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0); sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0); @@ -266,42 +273,41 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0); - sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_rsakey_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 0); - sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0); + sc_format_asn1_entry(asn1_rsakey_attr + 1, &info->modulus_length, NULL, 0); sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 0); - sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_eckey_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0); sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_dsakey_attr + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0); - sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info->path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); - sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0); - sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0); - sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 0, &info->id, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 1, &info->usage, &usage_len, 0); + sc_format_asn1_entry(asn1_com_key_attr + 2, &info->native, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 3, &info->access_flags, &af_len, 0); + sc_format_asn1_entry(asn1_com_key_attr + 4, &info->key_reference, NULL, 0); sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 0); /* Fill in defaults */ - memset(&info, 0, sizeof(info)); - info.key_reference = -1; - info.native = 1; + info->key_reference = -1; + info->native = 1; memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen); @@ -312,17 +318,17 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; - assert(info.modulus_length == 0); - info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; - assert(info.params.len == 0); - info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); - info.params.data = malloc(info.params.len); - if (info.params.data == NULL) { + assert(info->modulus_length == 0); + info->modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; + assert(info->params.len == 0); + info->params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); + info->params.data = malloc(info->params.len); + if (info->params.data == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - assert(sizeof(*keyinfo_gostparams) == info.params.len); - keyinfo_gostparams = info.params.data; + assert(sizeof(*keyinfo_gostparams) == info->params.len); + keyinfo_gostparams = info->params.data; keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0]; keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1]; keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2]; @@ -335,39 +341,35 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, } if (!p15card->app || !p15card->app->ddo.aid.len) { - r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); + r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info->path); if (r < 0) { goto err; } } else { - info.path.aid = p15card->app->ddo.aid; + info->path.aid = p15card->app->ddo.aid; } - sc_log(ctx, "PubKey path '%s'", sc_print_path(&info.path)); + sc_log(ctx, "PubKey path '%s'", sc_print_path(&info->path)); /* OpenSC 0.11.4 and older encoded "keyReference" as a negative value. Fixed in 0.11.5 we need to add a hack, so old cards continue to work. */ - if (info.key_reference < -1) - info.key_reference += 256; + if (info->key_reference < -1) + info->key_reference += 256; - obj->data = malloc(sizeof(info)); - if (obj->data == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(obj->data, &info, sizeof(info)); + obj->data = info; + info = NULL; r = sc_pkcs15_decode_pubkey_direct_value(p15card, obj); if (r < 0) { - free(obj->data); + info = obj->data; obj->data = NULL; } LOG_TEST_GOTO_ERR(ctx, r, "Decode public key direct value failed"); err: if (r < 0) { - sc_pkcs15_free_pubkey_info(&info); + sc_pkcs15_free_pubkey_info(info); } LOG_FUNC_RETURN(ctx, r); @@ -1227,11 +1229,13 @@ sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key) void sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *info) { - free(info->subject.value); - free(info->direct.spki.value); - free(info->direct.raw.value); - sc_pkcs15_free_key_params(&info->params); - free(info); + if (info) { + free(info->subject.value); + free(info->direct.spki.value); + free(info->direct.raw.value); + sc_pkcs15_free_key_params(&info->params); + free(info); + } } From 12218d4b0b295d01b81c1e915282b06da438a7f1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Sep 2019 14:24:30 +0200 Subject: [PATCH 1004/4321] prepare 0.20.0 --- appveyor.yml | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b9ed9a1dcb..ec15bb3bd0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.19.0.{build} +version: 0.20.0.{build} platform: - x86 diff --git a/configure.ac b/configure.ac index 6196dd5446..805af85dfc 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [19]) +define([PACKAGE_VERSION_MINOR], [20]) define([PACKAGE_VERSION_FIX], [0]) define([PACKAGE_SUFFIX], []) From 2eaf422cb2bf9d2f7fde7b538d213715d35b5d3a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 6 Sep 2019 15:09:55 +0200 Subject: [PATCH 1005/4321] refactor DIN 66291 profile to avoid memory confusion --- src/libopensc/pkcs15-din-66291.c | 144 ++++++++++++++----------------- 1 file changed, 63 insertions(+), 81 deletions(-) diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index b8452b9c3b..58e41895db 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -34,68 +34,7 @@ static const unsigned char aid_CIA[] = {0xE8, 0x28, 0xBD, 0x08, 0x0F, static const unsigned char aid_ESIGN[] = {0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E}; -int din_66291_match_p15card(sc_pkcs15_card_t *p15card, struct sc_aid *aid) -{ - int ok = 0, r; - sc_path_t path; - unsigned char *tokeninfo_content = NULL; - struct sc_file *file_tokeninfo = NULL; - struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); - - if (!p15card || !tokeninfo - || (aid && (aid->len != sizeof aid_CIA - || 0 != memcmp(aid->value, aid_CIA, sizeof aid_CIA)))) - goto err; - - if (p15card->tokeninfo - && p15card->tokeninfo->profile_indication.name - && 0 == strcmp("DIN V 66291", - p15card->tokeninfo->profile_indication.name)) { - ok = 1; - goto err; - } - - /* it is possible that p15card->tokeninfo has not been touched yet */ - sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_CIA, sizeof aid_CIA, 0, 0); - if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL)) - goto err; - - sc_format_path("5032", &path); - if (SC_SUCCESS != sc_select_file(p15card->card, &path, &file_tokeninfo)) - goto err; - - tokeninfo_content = malloc(file_tokeninfo->size); - if (!tokeninfo_content) - goto err; - r = sc_read_binary(p15card->card, 0, tokeninfo_content, file_tokeninfo->size, 0); - if (r < 0) - goto err; - r = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, tokeninfo, tokeninfo_content, r); - if (r != SC_SUCCESS) - goto err; - - if (tokeninfo->profile_indication.name - && 0 == strcmp("DIN V 66291", - tokeninfo->profile_indication.name)) { - ok = 1; - /* save tokeninfo and file_tokeninfo */ - sc_pkcs15_free_tokeninfo(p15card->tokeninfo); - sc_file_free(p15card->file_tokeninfo); - p15card->tokeninfo = tokeninfo; - p15card->file_tokeninfo = file_tokeninfo; - tokeninfo = NULL; - file_tokeninfo = NULL; - } - -err: - sc_pkcs15_free_tokeninfo(tokeninfo); - sc_file_free(file_tokeninfo); - free(tokeninfo_content); - - return ok; -} - - static int +static int sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) { /* EF.C.CH.AUT @@ -116,7 +55,6 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) size_t i; struct sc_pin_cmd_data data; const unsigned char user_pin_ref = 0x02; - sc_serial_number_t serial; sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_ESIGN, sizeof aid_ESIGN, 0, 0); if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL)) @@ -247,39 +185,83 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) } } - /* get the card serial number */ - if (!p15card->tokeninfo->serial_number - && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { - char serial_hex[SC_MAX_SERIALNR*2+2]; - sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex, 0); - p15card->tokeninfo->serial_number = strdup(serial_hex); - } - return SC_SUCCESS; } int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { int r = SC_ERROR_WRONG_CARD; + sc_path_t path; + unsigned char *tokeninfo_content = NULL; + struct sc_file *file_tokeninfo = NULL; + struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); + sc_serial_number_t serial; if (!p15card || ! p15card->card) return SC_ERROR_INVALID_ARGUMENTS; SC_FUNC_CALLED(p15card->card->ctx, 1); - /* Check card */ - if (1 == din_66291_match_p15card(p15card, aid)) { - /* Init card */ - r = sc_pkcs15emu_din_66291_init(p15card); + if (!p15card || !tokeninfo + || (aid && (aid->len != sizeof aid_CIA + || 0 != memcmp(aid->value, aid_CIA, sizeof aid_CIA)))) + goto err; + + if (!p15card->tokeninfo + || !p15card->tokeninfo->profile_indication.name + || 0 != strcmp("DIN V 66291", + p15card->tokeninfo->profile_indication.name)) { + /* it is possible that p15card->tokeninfo has not been touched yet */ + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_CIA, sizeof aid_CIA, 0, 0); + if (SC_SUCCESS != sc_select_file(p15card->card, &path, NULL)) + goto err; + + sc_format_path("5032", &path); + if (SC_SUCCESS != sc_select_file(p15card->card, &path, &file_tokeninfo)) + goto err; + + tokeninfo_content = malloc(file_tokeninfo->size); + if (!tokeninfo_content) + goto err; + r = sc_read_binary(p15card->card, 0, tokeninfo_content, file_tokeninfo->size, 0); + if (r < 0) + goto err; + r = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, tokeninfo, tokeninfo_content, r); + if (r != SC_SUCCESS) + goto err; + + if (!tokeninfo->profile_indication.name + || 0 != strcmp("DIN V 66291", + tokeninfo->profile_indication.name)) { + goto err; + } } - if (r != SC_SUCCESS) { - /* reset input data to default values */ - sc_pkcs15_free_tokeninfo(p15card->tokeninfo); - sc_file_free(p15card->file_tokeninfo); - p15card->tokeninfo = NULL; - p15card->file_tokeninfo = NULL; + if (SC_SUCCESS != sc_pkcs15emu_din_66291_init(p15card)) + goto err; + + /* save tokeninfo and file_tokeninfo */ + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); + sc_file_free(p15card->file_tokeninfo); + p15card->tokeninfo = tokeninfo; + p15card->file_tokeninfo = file_tokeninfo; + tokeninfo = NULL; + file_tokeninfo = NULL; + + /* get the card serial number */ + if (!p15card->tokeninfo->serial_number + && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { + char serial_hex[SC_MAX_SERIALNR*2+2]; + sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex, 0); + p15card->tokeninfo->serial_number = strdup(serial_hex); } + r = SC_SUCCESS; + +err: + sc_pkcs15_free_tokeninfo(tokeninfo); + sc_file_free(file_tokeninfo); + free(tokeninfo_content); + return r; } From 28a93fdf55915448e8bf93831c93035c8edb0f5a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Sep 2019 09:36:48 +0200 Subject: [PATCH 1006/4321] fixed memory leak --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 2149d3ab71..96cee4eb89 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -312,7 +312,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) - return r; + goto err; LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 decoding failed"); if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; From 3b632e64a19235636ab0a93fc2a4b5a7caf078a3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 10 Jul 2019 13:43:01 -0500 Subject: [PATCH 1007/4321] Fix #1731 sc_format_apdu_cse_lc_le fails to set Le correctly Changed four places where "<" should be "<=" so Le will be set correctly Previous for 65K (extended) or 256 (short) Le is left set to 0. This then caused Le to be to be not added to APDU as Le==0 Code later converts actual Le in APDU to be set to 0 to mean 256 or 65K. SC_APDU_CASE_*_EXT are changed to SC_APDU_CASE_* so sc_detect_apdu_cse to set the cse based on card capabilities as well as data chaining. This commit is not well tested and neds review. On branch fix-1731 Changes to be committed: modified: src/libopensc/card.c --- src/libopensc/card.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 1cc1f3955c..b5a7901cbf 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -67,27 +67,28 @@ void sc_format_apdu_cse_lc_le(struct sc_apdu *apdu) { /* TODO calculating the APDU case, Lc and Le should actually only be * done in sc_apdu2bytes, but to gradually change OpenSC we start here. */ + /* Let sc_detect_apdu_cse set short or extended and test for chaining */ if (!apdu) return; if (apdu->datalen > SC_MAX_APDU_DATA_SIZE || apdu->resplen > SC_MAX_APDU_RESP_SIZE) { - /* extended length */ - if (apdu->datalen < SC_MAX_EXT_APDU_DATA_SIZE) + /* extended length or data chaining and/or get response */ + if (apdu->datalen <= SC_MAX_EXT_APDU_DATA_SIZE) apdu->lc = apdu->datalen; - if (apdu->resplen < SC_MAX_EXT_APDU_RESP_SIZE) + if (apdu->resplen <= SC_MAX_EXT_APDU_RESP_SIZE) apdu->le = apdu->resplen; if (apdu->resplen && !apdu->datalen) - apdu->cse = SC_APDU_CASE_2_EXT; + apdu->cse = SC_APDU_CASE_2; if (!apdu->resplen && apdu->datalen) - apdu->cse = SC_APDU_CASE_3_EXT; + apdu->cse = SC_APDU_CASE_3; if (apdu->resplen && apdu->datalen) - apdu->cse = SC_APDU_CASE_4_EXT; + apdu->cse = SC_APDU_CASE_4; } else { /* short length */ - if (apdu->datalen < SC_MAX_APDU_DATA_SIZE) + if (apdu->datalen <= SC_MAX_APDU_DATA_SIZE) apdu->lc = apdu->datalen; - if (apdu->resplen < SC_MAX_APDU_RESP_SIZE) + if (apdu->resplen <= SC_MAX_APDU_RESP_SIZE) apdu->le = apdu->resplen; if (!apdu->resplen && !apdu->datalen) apdu->cse = SC_APDU_CASE_1; From 25bc8fc167718119f9baf1db7018c6d10e2645c5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 16 Sep 2019 13:06:38 +0200 Subject: [PATCH 1008/4321] fix https://github.com/OpenSC/OpenSC/issues/1786 Thanks to Alexandre Gonzalo --- src/tools/pkcs11-tool.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b564f7266a..4a99c76bc2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5576,12 +5576,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } size_t in_len; + size_t max_in_len; CK_ULONG mod_len = (get_private_key_length(session, privKeyObject) + 7) / 8; switch (mech_type) { case CKM_RSA_PKCS: pad = RSA_PKCS1_PADDING; - /* Limit the input length to <= mod_len-11 */ - in_len = mod_len-11; + /* input length <= mod_len-11 */ + max_in_len = mod_len-11; + in_len = 10; break; case CKM_RSA_PKCS_OAEP: { if (opt_hash_alg != 0) { @@ -5614,18 +5616,20 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } pad = RSA_PKCS1_OAEP_PADDING; - /* Limit the input length to <= mod_len-2-2*hlen */ size_t len = 2+2*hash_length(hash_alg); if (len >= mod_len) { printf("Incompatible mechanism and key size\n"); return 0; } - in_len = mod_len-len; + /* input length <= mod_len-2-2*hlen */ + max_in_len = mod_len-len; + in_len = 10; break; } case CKM_RSA_X_509: pad = RSA_NO_PADDING; - /* Limit the input length to the modulus length */ + /* input length equals modulus length */ + max_in_len = mod_len; in_len = mod_len; break; default: @@ -5634,7 +5638,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } if (in_len > sizeof(orig_data)) { - printf("Private key size is too long\n"); + printf("Input data is too large\n"); + return 0; + } + if (in_len > max_in_len) { + printf("Input data is too large for this key\n"); return 0; } From b9810e62d6ca97375d653ca29196635759356ba3 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Thu, 12 Sep 2019 13:07:08 +0200 Subject: [PATCH 1009/4321] cardos5: fix reading of serial number The corresponding GET DATA command only returns the serial, nothing else. Tested with CardOS 5.0 and 5.3 cards. The serial number is the same as shown with other tools --- src/libopensc/card-cardos.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index d0a62823be..710e17ef33 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -1190,14 +1190,19 @@ static int cardos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; - if (apdu.resplen != 32) { + if ((apdu.resplen == 8) && (card->type == SC_CARD_TYPE_CARDOS_V5_0)) { + /* cache serial number */ + memcpy(card->serialnr.value, rbuf, 8); + card->serialnr.len = 8; + } else if (apdu.resplen == 32) { + /* cache serial number */ + memcpy(card->serialnr.value, &rbuf[10], 6); + card->serialnr.len = 6; + } else { sc_log(card->ctx, "unexpected response to GET DATA serial" " number\n"); return SC_ERROR_INTERNAL; } - /* cache serial number */ - memcpy(card->serialnr.value, &rbuf[10], 6); - card->serialnr.len = 6; /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); return SC_SUCCESS; From d4a97c69596497331190539ebc993773db07f199 Mon Sep 17 00:00:00 2001 From: Vicente Jimenez Aguilar Date: Wed, 11 Sep 2019 09:58:01 +0200 Subject: [PATCH 1010/4321] [DOC] dnie-tool -a option includes sw version --- doc/tools/dnie-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/dnie-tool.1.xml b/doc/tools/dnie-tool.1.xml index 0fbbb47e76..8c9cecc933 100644 --- a/doc/tools/dnie-tool.1.xml +++ b/doc/tools/dnie-tool.1.xml @@ -52,7 +52,7 @@ Displays every available information. - This command is equivalent to -d -i -s + This command is equivalent to -d -i -V -s From aae529547c498177feaffb40eadd612d99fc5122 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Mon, 16 Sep 2019 18:15:57 +0200 Subject: [PATCH 1011/4321] sc-hsm: Fix maximum APDU size to 4K version (Fixes #1794) --- src/libopensc/card-sc-hsm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index ef2f0c17e1..7562ebde9c 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1686,7 +1686,13 @@ static int sc_hsm_init(struct sc_card *card) } sc_file_free(file); - card->max_send_size = 1431; // 1439 buffer size - 8 byte TLV because of odd ins in UPDATE BINARY + // APDU Buffer limits + // JCOP 2.4.1r3 1462 + // JCOP 2.4.2r3 1454 + // JCOP 3 1232 + // Reiner SCT 1014 + + card->max_send_size = 1217; // 1232 buffer size - 15 byte header and TLV because of odd ins in UPDATE BINARY if (card->type == SC_CARD_TYPE_SC_HSM_SOC || card->type == SC_CARD_TYPE_SC_HSM_GOID) { card->max_recv_size = 0x0630; // SoC Proxy forces this limit From d965156fe61df9f892b1c0555198b7b37daff437 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Sep 2019 20:02:12 +0200 Subject: [PATCH 1012/4321] fuzz_pkcs15_decode: fixed use after free --- src/tests/fuzzing/fuzz_pkcs15_decode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index 0704c66afc..ef79f0d2d7 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -56,6 +56,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) obj = calloc(1, sizeof *obj); while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, &len)) { sc_pkcs15_free_object(obj); + obj = calloc(1, sizeof *obj); } sc_pkcs15_free_object(obj); } From e2491a7d7fb4d8eb9cf831ca62578397ec0d5a6f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 1 Oct 2019 11:51:55 +0200 Subject: [PATCH 1013/4321] pkcs11-tool: fixed displaying secret key attributes (#1807) fixes https://github.com/OpenSC/OpenSC/issues/1805 --- src/pkcs11/framework-pkcs15.c | 16 ++++++++++++++++ src/tools/pkcs11-tool.c | 15 ++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3c845a71b4..527c1b14af 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4948,6 +4948,22 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) == 0 && (skey->base.p15_object->flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) == 0) ? CK_TRUE : CK_FALSE; break; + case CKA_ALWAYS_SENSITIVE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = (skey->info->access_flags & SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE) != 0; + break; + case CKA_NEVER_EXTRACTABLE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = (skey->info->access_flags & SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE) != 0; + break; + case CKA_SENSITIVE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = (skey->info->access_flags & SC_PKCS15_PRKEY_ACCESS_SENSITIVE) != 0; + break; + case CKA_LOCAL: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = (skey->info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) != 0; + break; case CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT: check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent >= 1 ? CK_TRUE : CK_FALSE; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4a99c76bc2..1e8597549a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3886,11 +3886,16 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) switch (key_type) { case CKK_RSA: - if (pub) - printf("; RSA %lu bits\n", - (unsigned long) getMODULUS_BITS(sess, obj)); - else - printf("; RSA \n"); + if (sec) { + /* uninitialized secret key (type 0) */ + printf("\n"); + } else { + if (pub) + printf("; RSA %lu bits\n", + (unsigned long) getMODULUS_BITS(sess, obj)); + else + printf("; RSA \n"); + } break; case CKK_GOSTR3410: case CKK_GOSTR3410_512: From 53ff7182fbf2629b6845edee135496e8f56fafa2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 1 Oct 2019 11:52:33 +0200 Subject: [PATCH 1014/4321] pkcs11-tool: disable wrap/unwrap test (#1808) ... until https://github.com/OpenSC/OpenSC/issues/1796 is resolved --- src/tools/pkcs11-tool.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1e8597549a..a0b0fe8285 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5375,6 +5375,8 @@ static int test_verify(CK_SESSION_HANDLE sess) return errors; } +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 20 +#else #ifdef ENABLE_OPENSSL static int wrap_unwrap(CK_SESSION_HANDLE session, const EVP_CIPHER *algo, CK_OBJECT_HANDLE privKeyObject) @@ -5489,6 +5491,7 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, return 0; } #endif +#endif /* @@ -5496,6 +5499,10 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, */ static int test_unwrap(CK_SESSION_HANDLE sess) { +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 20 + /* temporarily disable test, see https://github.com/OpenSC/OpenSC/issues/1796 */ + return 0; +#else int errors = 0; CK_RV rv; CK_OBJECT_HANDLE privKeyObject; @@ -5547,6 +5554,7 @@ static int test_unwrap(CK_SESSION_HANDLE sess) } return errors; +#endif } #ifdef ENABLE_OPENSSL From d6435b0af4724d76907bda02c0e9ccf977cedc90 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 13 Sep 2019 16:39:28 +0200 Subject: [PATCH 1015/4321] pkcs15-din-66291: Fix indentation --- src/libopensc/pkcs15-din-66291.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 58e41895db..abc9a2ac44 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -248,8 +248,8 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid tokeninfo = NULL; file_tokeninfo = NULL; - /* get the card serial number */ - if (!p15card->tokeninfo->serial_number + /* get the card serial number */ + if (!p15card->tokeninfo->serial_number && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { char serial_hex[SC_MAX_SERIALNR*2+2]; sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex, 0); From 79cb7539215ae910dc63e3452fa13ad8f252c656 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 1 Oct 2019 10:56:17 +0200 Subject: [PATCH 1016/4321] cac: Free the certificate data on failure Resolves: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16819 --- src/libopensc/pkcs15-cac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 8c68c86696..d637dedf19 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -366,6 +366,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) sc_pkcs15_free_certificate(cert_out); + free(cert_info.value.value); continue; } @@ -373,6 +374,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) if (r < 0) { sc_log(card->ctx, " Failed to add cert obj r=%d",r); sc_pkcs15_free_certificate(cert_out); + free(cert_info.value.value); continue; } /* set the token name to the name of the CN of the first certificate */ From 34bd87940035dbe05ef8495c361581efbb7325eb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 1 Oct 2019 11:00:06 +0200 Subject: [PATCH 1017/4321] openpgp: Properly free the allocated file structure Resolves: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16879 --- src/libopensc/card-openpgp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 2f73a1abc7..b8cdd45205 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -513,6 +513,7 @@ pgp_init(sc_card_t *card) /* explicitly get the full aid */ r = get_full_pgp_aid(card, file); if (r < 0) { + sc_file_free(file); pgp_finish(card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } @@ -577,8 +578,10 @@ pgp_init(sc_card_t *card) sc_format_path("3f00", &file->path); /* set up the root of our fake file tree */ + /* Transfers ownership of the file to the priv->mf structure */ priv->mf = pgp_new_blob(card, NULL, 0x3f00, file); if (!priv->mf) { + sc_file_free(file); pgp_finish(card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } From 5490d73f31ada6b99d45ebdc85074b0cfc4e5b48 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 1 Oct 2019 11:11:29 +0200 Subject: [PATCH 1018/4321] card: Avoid integer overflows Resolves: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17007 --- src/libopensc/card.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index b5a7901cbf..3fe274d850 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -28,6 +28,7 @@ #include #endif #include +#include #include "reader-tr03119.h" #include "internal.h" @@ -655,6 +656,11 @@ int sc_read_binary(sc_card_t *card, unsigned int idx, LOG_TEST_RET(card->ctx, r, "sc_read_binary() failed"); } p += r; + if ((bytes_read > INT_MAX - r) || idx > UINT_MAX - r) { + /* `bytes_read + r` or `idx + r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } idx += r; bytes_read += r; count -= r; From eac516fd41c62fe7166c2054666267993d85cc3d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 1 Oct 2019 11:54:56 +0200 Subject: [PATCH 1019/4321] dir: Avoid insane allocations Resolves: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17449 --- src/libopensc/dir.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 895ad65a1c..d458000ce0 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -29,6 +29,8 @@ #include "internal.h" #include "asn1.h" +#define MAX_FILE_SIZE 65535 + struct app_entry { const u8 *aid; size_t aid_len; @@ -185,6 +187,8 @@ int sc_enum_apps(sc_card_t *card) file_size = card->ef_dir->size; if (file_size == 0) LOG_FUNC_RETURN(ctx, 0); + if (file_size > MAX_FILE_SIZE) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); buf = malloc(file_size); if (buf == NULL) From 8eb56730582f9f8d0d6f26fab1f17968035b7a94 Mon Sep 17 00:00:00 2001 From: alex-nitrokey Date: Tue, 8 Oct 2019 15:43:40 +0200 Subject: [PATCH 1020/4321] Check keyformat for RSA only inside if RSA key is to be imported --- src/libopensc/card-openpgp.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b8cdd45205..16c557d53c 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3160,23 +3160,23 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key ID; must be 1, 2, or 3"); - /* we just support standard key format */ - switch (key_info->u.rsa.keyformat) { - case SC_OPENPGP_KEYFORMAT_RSA_STD: - case SC_OPENPGP_KEYFORMAT_RSA_STDN: - break; - - case SC_OPENPGP_KEYFORMAT_RSA_CRT: - case SC_OPENPGP_KEYFORMAT_RSA_CRTN: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - - default: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - /* set algorithm attributes */ /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + /* we just support standard key format */ + switch (key_info->u.rsa.keyformat) { + case SC_OPENPGP_KEYFORMAT_RSA_STD: + case SC_OPENPGP_KEYFORMAT_RSA_STDN: + break; + + case SC_OPENPGP_KEYFORMAT_RSA_CRT: + case SC_OPENPGP_KEYFORMAT_RSA_CRTN: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + /* we only support exponent of maximum 32 bits */ if (key_info->u.rsa.e_len > SC_OPENPGP_MAX_EXP_BITS) { sc_log(card->ctx, From ca5b3977d8a7bae2b8a964e3871c5c0f468646c0 Mon Sep 17 00:00:00 2001 From: alex-nitrokey Date: Tue, 8 Oct 2019 17:11:00 +0200 Subject: [PATCH 1021/4321] Fix ecc oid handling while storing existing keys --- src/libopensc/card-openpgp.c | 2 ++ src/libopensc/cardctl.h | 2 ++ src/pkcs15init/pkcs15-openpgp.c | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 16c557d53c..54a621359e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3207,6 +3207,8 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) if (key_info->u.ec.ecpoint && key_info->u.ec.ecpoint_len){ pubkey.u.ec.ecpoint = key_info->u.ec.ecpoint; pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpoint_len; + pubkey.u.ec.oid = key_info->u.ec.oid; + pubkey.u.ec.oid_len = key_info->u.ec.oid_len; } else LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index ac1969256b..dedbc2dff6 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -995,6 +995,8 @@ typedef struct sc_cardctl_openpgp_keystore_info { size_t privateD_len; u8 *ecpoint; size_t ecpoint_len; + struct sc_object_id oid; + u8 oid_len; } ec; } u; time_t creationtime; diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index dfd4b8b849..5f30160234 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -119,6 +119,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; sc_cardctl_openpgp_keystore_info_t key_info; int r; + unsigned int i; LOG_FUNC_CALLED(card->ctx); @@ -152,6 +153,16 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.u.ec.privateD_len = key->u.ec.privateD.len; key_info.u.ec.ecpoint = key->u.ec.ecpointQ.value; key_info.u.ec.ecpoint_len = key->u.ec.ecpointQ.len; + /* extract oid the way we need to import it to OpenPGP Card */ + if (key->u.ec.params.der.len > 2) + key_info.u.ec.oid_len = key->u.ec.params.der.value[1]; + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + for (i=0; (i < key_info.u.ec.oid_len) && (i+2 < key->u.ec.params.der.len); i++){ + key_info.u.ec.oid.value[i] = key->u.ec.params.der.value[i+2]; + } + key_info.u.ec.oid.value[key_info.u.ec.oid_len] = -1; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); break; default: From 606fae5a8ec45679ea87e07346cd7bee20ee5058 Mon Sep 17 00:00:00 2001 From: alex-nitrokey Date: Wed, 9 Oct 2019 15:02:36 +0200 Subject: [PATCH 1022/4321] Use ecpointQ for better code readability --- src/libopensc/card-openpgp.c | 10 +++++----- src/libopensc/cardctl.h | 4 ++-- src/pkcs15init/pkcs15-openpgp.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 54a621359e..8b68e8b249 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3056,8 +3056,8 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info /* TODO ECC import with public key, if necessary as denoted in algorithm caps*/ /* validate */ - if ((key_info->u.ec.ecpoint == NULL || key_info->u.ec.ecpoint_len == 0)){ - sc_log(ctx, "Error: ecpoint required!"); + if ((key_info->u.ec.ecpointQ == NULL || key_info->u.ec.ecpointQ_len == 0)){ + sc_log(ctx, "Error: ecpointQ required!"); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -3204,9 +3204,9 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; pubkey.algorithm = key_info->algorithm; - if (key_info->u.ec.ecpoint && key_info->u.ec.ecpoint_len){ - pubkey.u.ec.ecpoint = key_info->u.ec.ecpoint; - pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpoint_len; + if (key_info->u.ec.ecpointQ && key_info->u.ec.ecpointQ_len){ + pubkey.u.ec.ecpoint = key_info->u.ec.ecpointQ; + pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpointQ_len; pubkey.u.ec.oid = key_info->u.ec.oid; pubkey.u.ec.oid_len = key_info->u.ec.oid_len; } diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index dedbc2dff6..9bce594b1e 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -993,8 +993,8 @@ typedef struct sc_cardctl_openpgp_keystore_info { struct { u8 *privateD; size_t privateD_len; - u8 *ecpoint; - size_t ecpoint_len; + u8 *ecpointQ; + size_t ecpointQ_len; struct sc_object_id oid; u8 oid_len; } ec; diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 5f30160234..3740e2bb6c 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -151,8 +151,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.key_id = kinfo->id.value[0]; key_info.u.ec.privateD = key->u.ec.privateD.data; key_info.u.ec.privateD_len = key->u.ec.privateD.len; - key_info.u.ec.ecpoint = key->u.ec.ecpointQ.value; - key_info.u.ec.ecpoint_len = key->u.ec.ecpointQ.len; + key_info.u.ec.ecpointQ = key->u.ec.ecpointQ.value; + key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; /* extract oid the way we need to import it to OpenPGP Card */ if (key->u.ec.params.der.len > 2) key_info.u.ec.oid_len = key->u.ec.params.der.value[1]; From c695a4e35f0c50f491a12e2627cfb124a9876c80 Mon Sep 17 00:00:00 2001 From: alex-nitrokey Date: Wed, 9 Oct 2019 17:18:21 +0200 Subject: [PATCH 1023/4321] Add support for pubkey import if announced in algorithm attributes --- src/libopensc/card-openpgp.c | 24 +++++++++++++++++++++--- src/libopensc/cardctl.h | 7 ++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 8b68e8b249..c6b5b7a6d1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -719,10 +719,20 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_ /* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA */ key_info->algorithm = blob->data[0]; + /* last byte is only set if pubkey import is supported, empty otherwise*/ + if (blob->data[blob->len] == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ + key_info->u.ec.oid_len = blob->len - 2; + key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STDPUB; + } + else { + key_info->u.ec.oid_len = blob->len - 1; + key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STD; + } + sc_init_oid(&oid); /* Create copy of oid from blob */ - for (j=0; j < (blob->len-1); j++) { - oid.value[j] = blob->data[j+1]; /* ignore first byte of blob (algo ID) */ + for (j=0; j < key_info->u.ec.oid_len; j++) { + oid.value[j] = blob->data[j+1]; /* ignore first byte (algo ID) */ } /* compare with list of supported ec_curves */ @@ -733,6 +743,7 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_ break; } } + break; default: return SC_ERROR_NOT_IMPLEMENTED; @@ -3053,7 +3064,14 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info componentnames[0] = "private key"; comp_to_add = 1; - /* TODO ECC import with public key, if necessary as denoted in algorithm caps*/ + /* import public key as well */ + if (key_info->u.ec.keyformat == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ + components[1] = key_info->u.ec.ecpointQ; + componentlens[1] = key_info->u.ec.ecpointQ_len; + componenttags[1] = 0x99; + componentnames[1] = "public key"; + comp_to_add = 2; + } /* validate */ if ((key_info->u.ec.ecpointQ == NULL || key_info->u.ec.ecpointQ_len == 0)){ diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 9bce594b1e..4b76391f68 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -952,6 +952,9 @@ typedef struct sc_cardctl_piv_genkey_info_st { #define SC_OPENPGP_KEYFORMAT_RSA_CRT 2 #define SC_OPENPGP_KEYFORMAT_RSA_CRTN 3 +#define SC_OPENPGP_KEYFORMAT_EC_STD 0 +#define SC_OPENPGP_KEYFORMAT_EC_STDPUB 0xFF + #define SC_OPENPGP_MAX_EXP_BITS 0x20 /* maximum exponent length supported in bits */ typedef struct sc_cardctl_openpgp_keygen_info { @@ -959,13 +962,14 @@ typedef struct sc_cardctl_openpgp_keygen_info { u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ union { struct { + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ u8 *modulus; /* New-generated pubkey info responded from the card */ size_t modulus_len; /* Length of modulus in bit */ u8 *exponent; size_t exponent_len; /* Length of exponent in bit */ - u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ } rsa; struct { + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_EC_... */ u8 *ecpoint; size_t ecpoint_len; struct sc_object_id oid; @@ -991,6 +995,7 @@ typedef struct sc_cardctl_openpgp_keystore_info { size_t n_len; } rsa; struct { + u8 keyformat; /* SC_OPENPGP_KEYFORMAT_EC_... */ u8 *privateD; size_t privateD_len; u8 *ecpointQ; From 3a1bd36e2018e7e4c7f78b1fa84d998a9d163616 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 Oct 2019 13:16:22 +0200 Subject: [PATCH 1024/4321] Use onepin-opensc-pkcs11.so for Chromium (#1828) * pkcs11-register: Fixed detection of already registered OpenSC Anny configuration of onepin-opensc-pkcs11.so and opensc-pkcs11.so should be enough to skip registering the default module again. * Use onepin module for generic NSS DB fixes https://github.com/OpenSC/OpenSC/issues/1818 May have the disadvantage that some other programs that use NSS don't see the signature keys. However, we currently only know for sure that Chromium is using the generic NSS DB. --- src/tools/pkcs11-register.c | 48 +++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index 0df3a39913..b34eb6b66d 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -118,7 +118,7 @@ get_next_profile_path(const char **profiles_ini, const char *home, const char *b void add_module_pkcs11_txt(const char *profile_dir, - const char *module_path, const char *module_name) + const char *module_path, const char *module_name, const char *exclude_module_path) { char pkcs11_txt_path[PATH_MAX]; char *pkcs11_txt = NULL; @@ -136,7 +136,8 @@ add_module_pkcs11_txt(const char *profile_dir, p[pkcs11_txt_len] = '\0'; pkcs11_txt = p; - if (!strstr(pkcs11_txt, module_path)) { + if (!strstr(pkcs11_txt, module_path) + && (!exclude_module_path || !strstr(pkcs11_txt, exclude_module_path))) { /* module is not yet present */ FILE *f = fopen(pkcs11_txt_path, "a"); if (f) { @@ -160,7 +161,7 @@ struct location { void add_module_mozilla(const struct location *locations, size_t locations_len, - const char *module_path, const char *module_name) + const char *module_path, const char *module_name, const char *exclude_module_path) { size_t i; @@ -177,7 +178,7 @@ add_module_mozilla(const struct location *locations, size_t locations_len, const char *profile_path = get_next_profile_path(&p, home, locations[i].dir); if (!profile_path) break; - add_module_pkcs11_txt(profile_path, module_path, module_name); + add_module_pkcs11_txt(profile_path, module_path, module_name, exclude_module_path); } } free(profiles_ini); @@ -218,7 +219,7 @@ get_module_name(const char *module_path) } void -add_module_firefox(const char *module_path, const char *module_name) +add_module_firefox(const char *module_path, const char *module_name, const char *exclude_module_path) { struct location locations[] = { #if defined(__APPLE__) @@ -231,15 +232,17 @@ add_module_firefox(const char *module_path, const char *module_name) #endif }; - if (0 == strcmp(module_path, default_pkcs11_provider)) + if (0 == strcmp(module_path, default_pkcs11_provider)) { module_path = default_onepin_pkcs11_provider; + exclude_module_path = default_pkcs11_provider; + } add_module_mozilla(locations, sizeof locations/sizeof *locations, - module_path, module_name); + module_path, module_name, exclude_module_path); } void -add_module_thunderbird(const char *module_path, const char *module_name) +add_module_thunderbird(const char *module_path, const char *module_name, const char *exclude_module_path) { struct location locations[] = { #if defined(__APPLE__) @@ -254,11 +257,11 @@ add_module_thunderbird(const char *module_path, const char *module_name) }; add_module_mozilla(locations, sizeof locations/sizeof *locations, - module_path, module_name); + module_path, module_name, exclude_module_path); } void -add_module_seamonkey(const char *module_path, const char *module_name) +add_module_seamonkey(const char *module_path, const char *module_name, const char *exclude_module_path) { struct location locations[] = { #if defined(__APPLE__) @@ -272,20 +275,26 @@ add_module_seamonkey(const char *module_path, const char *module_name) }; add_module_mozilla(locations, sizeof locations/sizeof *locations, - module_path, module_name); + module_path, module_name, exclude_module_path); } void -add_module_chrome(const char *module_path, const char *module_name) +add_module_chrome(const char *module_path, const char *module_name, const char *exclude_module_path) { #if defined(__APPLE__) || defined(_WIN32) /* OS specific framework will be used by Chrome instead of PKCS#11 */ #else char profile_path[PATH_MAX]; const char *home = getenv("HOME"); + + if (0 == strcmp(module_path, default_pkcs11_provider)) { + module_path = default_onepin_pkcs11_provider; + exclude_module_path = default_pkcs11_provider; + } + if (home && 0 <= snprintf(profile_path, sizeof profile_path, "%s%c%s", home, path_sep, ".pki/nssdb")) { - add_module_pkcs11_txt(profile_path, module_path, module_name); + add_module_pkcs11_txt(profile_path, module_path, module_name, exclude_module_path); } #endif } @@ -300,13 +309,16 @@ int main(int argc, char **argv) { struct gengetopt_args_info cmdline; + const char *exclude_module_path = NULL; if (cmdline_parser(argc, argv, &cmdline) != 0) return 1; const char *module_path = cmdline.module_arg; - if (!cmdline.module_given) + if (!cmdline.module_given) { module_path = default_pkcs11_provider; + exclude_module_path = default_onepin_pkcs11_provider; + } #ifdef _WIN32 DWORD expanded_len; char module_path_expanded[PATH_MAX], default_expanded[PATH_MAX], onepin_expanded[PATH_MAX]; @@ -322,13 +334,13 @@ main(int argc, char **argv) } if (!cmdline.skip_chrome_flag) - add_module_chrome(module_path, module_name); + add_module_chrome(module_path, module_name, exclude_module_path); if (!cmdline.skip_firefox_flag) - add_module_firefox(module_path, module_name); + add_module_firefox(module_path, module_name, exclude_module_path); if (!cmdline.skip_thunderbird_flag) - add_module_thunderbird(module_path, module_name); + add_module_thunderbird(module_path, module_name, exclude_module_path); if (!cmdline.skip_seamonkey_flag) - add_module_seamonkey(module_path, module_name); + add_module_seamonkey(module_path, module_name, exclude_module_path); cmdline_parser_free (&cmdline); From f4ac617c1953d2f3127f5001590a6eabe6c8c11f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 11 Oct 2019 13:59:29 +0300 Subject: [PATCH 1025/4321] Remove unused card type Signed-off-by: Raul Metsma --- src/libopensc/cards.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 39cb2a6787..24d73c094a 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -75,7 +75,6 @@ enum { SC_CARD_TYPE_MCRD_BASE = 5000, SC_CARD_TYPE_MCRD_GENERIC, SC_CARD_TYPE_MCRD_ESTEID_V30, - SC_CARD_TYPE_MCRD_DTRUST, /* setcos driver */ SC_CARD_TYPE_SETCOS_BASE = 6000, From 2017626ed237dbdd4683a4b9410fc610618200c5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Oct 2019 23:28:38 +0200 Subject: [PATCH 1026/4321] integrate OpenSCToken --- MacOSX/Distribution.xml.in | 42 ++++++++++++++++++++++++++++++++++++-- MacOSX/build-package.in | 41 +++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index 848950d133..3ab8cc9e73 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -9,19 +9,57 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D @PACKAGE_STRING@ - + + + OpenSC.pkg - + OpenSC-tokend.pkg + + OpenSCToken.pkg + OpenSC-startup.pkg diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index a0888b945e..5cfb23bf42 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -95,8 +95,13 @@ fi # Create the symlink to OpenSC sources test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src -# Build and copy OpenSC.tokend -xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend +if (( xcodebuild -version | sed -En 's/Xcode[[:space:]]+([0-9]+)\.[0-9]*/\1/p' < 10 )); then + # Build and copy OpenSC.tokend + xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend +else + # https://github.com/OpenSC/OpenSC.tokend/issues/33 + mkdir -p ${BUILDPATH}/target_tokend +fi #if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then #if ! test -e terminal-notifier-1.7.1.zip; then @@ -127,10 +132,42 @@ mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents cp src/tools/pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents cp src/tools/opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents +# Build OpenSCToken if possible +if test -e OpenSCToken; then + cd OpenSCToken + # make sure OpenSCToken builds with the same dependencies as before + if ! test -e OpenSC; then + git clone --depth=1 ../../OpenSC + else + cd OpenSC && git pull && cd .. + fi + if ! test -e openssl; then + git clone --depth=1 ../openssl + else + cd openssl && git pull && cd .. + fi + if ! test -e openpace; then + git clone --depth=1 ../openpace + else + cd openpace && git pull && cd .. + fi + BP=${BUILDPATH} + . ./bootstrap + BUILDPATH=${BP} + xcodebuild -target OpenSCTokenApp -configuration Debug -project OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target_token + cd .. + xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target_token/Applications/OpenSCTokenApp.app/Contents/Resources/ +else + # if no OpenSCToken is checked out, then we create a dummy package + mkdir -p ${BUILDPATH}/target_token +fi + # Build package pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg pkgbuild --root ${BUILDPATH}/target_tokend --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg +pkgbuild --root ${BUILDPATH}/target_token --identifier org.opensc-project.mac.opensctoken --version @PACKAGE_VERSION@ --install-location / OpenSCToken.pkg pkgbuild --root ${BUILDPATH}/target_startup --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg + # Build product productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" From 8ded1ae94b18af7d336c14b2084550c3096fe6a6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Oct 2019 23:28:50 +0200 Subject: [PATCH 1027/4321] travis: include pkgs to later assamble with opensctoken --- .github/push_artifacts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index a24d24526d..a4974eb9f3 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -9,7 +9,7 @@ git clone --single-branch https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /d cd Nightly git checkout -b "${BRANCH}" -for file in ${BUILDPATH}/win32/Output/OpenSC*.exe ${BUILDPATH}/opensc*.tar.gz ${BUILDPATH}/OpenSC*.dmg ${BUILDPATH}/OpenSC*.msi ${BUILDPATH}/OpenSC*.zip +for file in ${BUILDPATH}/win32/Output/OpenSC*.exe ${BUILDPATH}/opensc*.tar.gz ${BUILDPATH}/OpenSC*.dmg ${BUILDPATH}/OpenSC*.msi ${BUILDPATH}/OpenSC*.zip ${BUILDPATH}/*.pkg do if [ -f ${file} ] then From 01678e871e4bb30dd4bde7bf8b2a63c5cddb6a11 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 18 Oct 2019 00:41:10 +0200 Subject: [PATCH 1028/4321] CI: retry pushing 10 times to nightly --- .github/push_artifacts.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index a4974eb9f3..15d07868d6 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -19,9 +19,10 @@ do done git commit --message "$1" -if ! git push --quiet --set-upstream origin "${BRANCH}" -then +i=0 +while [ $i -le 10 ] && ! git push --quiet --set-upstream origin "${BRANCH}" +do sleep $[ ( $RANDOM % 32 ) + 1 ]s git pull --rebase origin "${BRANCH}" - git push --quiet --set-upstream origin "${BRANCH}" -fi + i=$(( $i + 1 )) +done From 889d598bcd242447b4bd7db22106b008b605a849 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Oct 2019 15:04:58 +0200 Subject: [PATCH 1029/4321] asn1: Initialize values to avoid comparison with garbage Reported by clang analyzer: src/libopensc/asn1.c:2115:14: warning: The right operand of '<' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult] if (halflen < r_len || halflen < s_len) { --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index f6698b2e28..df074e409e 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -2047,7 +2047,7 @@ sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE]; struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE]; unsigned char *r = NULL, *s = NULL; - size_t r_len, s_len, halflen = buflen/2; + size_t r_len = 0, s_len = 0, halflen = buflen/2; int rv; LOG_FUNC_CALLED(ctx); From 544d576b0076dcb96b78e502e2c05906486ba357 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Oct 2019 14:59:54 +0200 Subject: [PATCH 1030/4321] asn1: Do not pass null argument to memcpy Reported by clang analyzer: src/libopensc/asn1.c:1080:2: note: Null pointer passed as an argument to a 'nonnull' parameter memcpy(p, data, datalen); --- src/libopensc/asn1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index df074e409e..8caac84bff 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1029,7 +1029,9 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag, else { *p++ = datalen & 0x7F; } - memcpy(p, data, datalen); + if (datalen && data) { + memcpy(p, data, datalen); + } return SC_SUCCESS; } From 459e4ecc377353df54be12c29b214949afdaac31 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 18:11:13 +0200 Subject: [PATCH 1031/4321] piv: Avoid insane allocations in fuzzer --- src/libopensc/card-piv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a6f9fb6386..9f5a46c4a6 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -55,6 +55,8 @@ #endif #include "simpletlv.h" +#define PIV_MAX_FILE_SIZE 65535 + enum { PIV_OBJ_CCC = 0, PIV_OBJ_CHUI, @@ -960,6 +962,9 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) "buffer for #%d *buf=0x%p len=%"SC_FORMAT_LEN_SIZE_T"u", enumtag, *buf, *buf_len); if (*buf == NULL && *buf_len > 0) { + if (*buf_len > PIV_MAX_FILE_SIZE) { + goto err; + } *buf = malloc(*buf_len); if (*buf == NULL ) { r = SC_ERROR_OUT_OF_MEMORY; From 5e9e5b232cc9fed099da1136e71186f10625c5dd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 18:07:43 +0200 Subject: [PATCH 1032/4321] card-piv: Fix indentation --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 9f5a46c4a6..2408c5e30c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -949,7 +949,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) r = SC_ERROR_FILE_NOT_FOUND; goto err; } - *buf_len = (body - rbuf) + bodylen; + *buf_len = (body - rbuf) + bodylen; } else if ( r == 0 ) { r = SC_ERROR_FILE_NOT_FOUND; goto err; From ff893d22245695917e88f7b6d4488165803c5717 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 17:31:53 +0200 Subject: [PATCH 1033/4321] pkcs15: Remove unused code --- src/libopensc/pkcs15.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 4386a51e7f..7c56c0e731 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2257,7 +2257,7 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p const unsigned char *p = buf; size_t left = buflen; int r; - struct sc_path path, dummy_path; + struct sc_path path; struct sc_pkcs15_id auth_id; struct sc_asn1_entry asn1_unusedspace[] = { { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, @@ -2272,9 +2272,6 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p /* Clean the list if already present */ sc_pkcs15_free_unusedspace(p15card); - sc_format_path("3F00", &dummy_path); - dummy_path.index = dummy_path.count = 0; - sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1); sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1); sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0); From 6ef0ac6e678a4710198bc109a126fa1ad0e1d53e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 14:35:49 +0200 Subject: [PATCH 1034/4321] asn1: Correctly parse negative integers The negative integers were parsed uterly wrong, resulting in undefined shift overflows as reported by oss-fuzz. The current implementation takes negated values (properly masked) and calculates two's complement in the end, which results in correct values and correct data handling. https://oss-fuzz.com/testcase-detail/5125815506829312 --- src/libopensc/asn1.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 8caac84bff..33bd762372 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -708,18 +708,30 @@ static int encode_bit_field(const u8 *inbuf, size_t inlen, int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out) { int a = 0, is_negative = 0; - size_t i; + size_t i = 0; if (inlen > sizeof(int) || inlen == 0) return SC_ERROR_INVALID_ASN1_OBJECT; - if (inbuf[0] & 0x80) + if (inbuf[0] & 0x80) { is_negative = 1; - for (i = 0; i < inlen; i++) { + a |= 0xff^(*inbuf++); + i = 1; + } + for (; i < inlen; i++) { + if (a > (INT_MAX >> 8) || a < (INT_MIN + (1<<8))) { + return SC_ERROR_NOT_SUPPORTED; + } a <<= 8; - a |= *inbuf++; + if (is_negative) { + a |= 0xff^(*inbuf++); + } else { + a |= *inbuf++; + } + } + if (is_negative) { + /* Calculate Two's complement from previously positive number */ + a = -1 * (a + 1); } - if (is_negative) - a *= -1; *out = a; return 0; } From 62049ea18c622fe96bcbe3664f1b3f5f95f878cc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 11:05:14 +0200 Subject: [PATCH 1035/4321] Avoid memory leaks from file selection https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17106 --- src/libopensc/card-mcrd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 7a443c0840..bcd9869b64 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -836,6 +836,9 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, priv->curpathlen--; priv->is_ef = 0; } + /* Free the previously allocated file so we do not leak memory here */ + sc_file_free(*file); + *file = NULL; r = select_down(card, pathptr, pathlen, 0, file); } return r; From 630d6adf32cecaab0ee184618f56497bd50400fb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 16 Oct 2019 10:39:20 +0200 Subject: [PATCH 1036/4321] pkcs15-prkey: Avoid memory leak https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16625 --- src/libopensc/pkcs15-prkey.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 9f9ac7e18a..228a7b3dcb 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -258,6 +258,13 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen); + if (r < 0) { + /* This might have allocated something. If so, clear it now */ + if (asn1_com_prkey_attr->flags & SC_ASN1_PRESENT && + asn1_com_prkey_attr[0].flags & SC_ASN1_PRESENT) { + free(asn1_com_prkey_attr[0].parm); + } + } if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; LOG_TEST_RET(ctx, r, "PrKey DF ASN.1 decoding failed"); From 1be013d08e381b2bea21fa97fa5b3584e1245f6d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Oct 2019 16:37:24 +0200 Subject: [PATCH 1037/4321] asn1: Fix undefined shift in OID parser https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16618 --- src/libopensc/asn1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 33bd762372..ce95bbf27f 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "internal.h" #include "asn1.h" @@ -816,6 +817,11 @@ sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id) a = *p & 0x7F; inlen--; while (inlen && *p & 0x80) { + /* Limit the OID values to int size and do not overflow */ + if (a > (INT_MAX>>7)) { + sc_init_oid(id); + return SC_ERROR_NOT_SUPPORTED; + } p++; a <<= 7; a |= *p & 0x7F; From 19f4c7e428cece9e4b6d5bf8948a09aa8a09ca42 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 Oct 2019 09:16:52 +0200 Subject: [PATCH 1038/4321] card-mcrd.c: Avoid null dereference https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18477 --- src/libopensc/card-mcrd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index bcd9869b64..d7ad48d83f 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -837,8 +837,10 @@ select_file_by_path(sc_card_t * card, unsigned short *pathptr, priv->is_ef = 0; } /* Free the previously allocated file so we do not leak memory here */ - sc_file_free(*file); - *file = NULL; + if (file) { + sc_file_free(*file); + *file = NULL; + } r = select_down(card, pathptr, pathlen, 0, file); } return r; From 6ce6152284c47ba9b1d4fe8ff9d2e6a3f5ee02c7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 Oct 2019 09:22:44 +0200 Subject: [PATCH 1039/4321] pkcs15-prkey: Simplify cleaning memory after failure https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18478 --- src/libopensc/pkcs15-prkey.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 228a7b3dcb..a4f4a41015 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -260,10 +260,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen); if (r < 0) { /* This might have allocated something. If so, clear it now */ - if (asn1_com_prkey_attr->flags & SC_ASN1_PRESENT && - asn1_com_prkey_attr[0].flags & SC_ASN1_PRESENT) { - free(asn1_com_prkey_attr[0].parm); - } + free(info.subject.value); } if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; From 0d091c8e0c645b6291f5c5aff3f154848d99e95a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 23 Oct 2019 09:34:46 +0200 Subject: [PATCH 1040/4321] asn1: Avoid integer overflow https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18475 --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index ce95bbf27f..66d4184da8 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -731,7 +731,7 @@ int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out) } if (is_negative) { /* Calculate Two's complement from previously positive number */ - a = -1 * (a + 1); + a = (-1 * a) - 1; } *out = a; return 0; From cc466eea946ff2bd561bba7fec2724e462183126 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 24 Oct 2019 11:27:29 +0200 Subject: [PATCH 1041/4321] asn1: Avoid undefined shifts by adding explicit cast The error was: asn1.c:681:23: runtime error: left shift of 255 by 24 places cannot be represented in type 'int' #0 0x5e9b11 in decode_bit_field opensc/src/libopensc/asn1.c:681:23 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18487 --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 66d4184da8..c68f62c9d2 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -678,7 +678,7 @@ static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t return n; for (i = 0; i < n; i += 8) { - field |= (data[i/8] << i); + field |= ((unsigned int) data[i/8] << i); } memcpy(outbuf, &field, outlen); return 0; From 6810eb6cf13f97ff20c5c68f49bef70ae977ddea Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 24 Oct 2019 15:36:18 +0200 Subject: [PATCH 1042/4321] fuzz_pkcs15_reader: Unbreak strict builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error was fuzz_pkcs15_reader.c: In function ‘fuzz_get_chunk’: fuzz_pkcs15_reader.c:66:19: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] 66 | *chunk_size = (uint16_t) data->Data; | ^ cc1: all warnings being treated as errors --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 105ea886ca..9bac1309fb 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -63,7 +63,7 @@ void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_ } data->Size -= sizeof *chunk_size; - *chunk_size = (uint16_t) data->Data; + *chunk_size = (uint16_t) *data->Data; data->Data += sizeof *chunk_size; *chunk = data->Data; From f0310f777686d69d52c6c741fbe088e2caadb0fb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 24 Oct 2019 15:48:30 +0200 Subject: [PATCH 1043/4321] Add fuzzing status to the readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bd4db01c9..1a0593149e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. -[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp) +[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opensc.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:opensc) Build and test status of specific cards: From 532b06d07e6e0e020835f99ff29672eaaded846e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 25 Oct 2019 13:09:04 +0200 Subject: [PATCH 1044/4321] pkcs15: Avoid insane allocations and use single max constant accross the code https://oss-fuzz.com/testcase-detail/6314983763214336 --- src/libopensc/card-piv.c | 4 +--- src/libopensc/dir.c | 2 -- src/libopensc/opensc.h | 2 ++ src/libopensc/pkcs15.c | 4 ++++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 2408c5e30c..7098e64ecf 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -55,8 +55,6 @@ #endif #include "simpletlv.h" -#define PIV_MAX_FILE_SIZE 65535 - enum { PIV_OBJ_CCC = 0, PIV_OBJ_CHUI, @@ -962,7 +960,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) "buffer for #%d *buf=0x%p len=%"SC_FORMAT_LEN_SIZE_T"u", enumtag, *buf, *buf_len); if (*buf == NULL && *buf_len > 0) { - if (*buf_len > PIV_MAX_FILE_SIZE) { + if (*buf_len > MAX_FILE_SIZE) { goto err; } *buf = malloc(*buf_len); diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index d458000ce0..c2a88fd9b8 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -29,8 +29,6 @@ #include "internal.h" #include "asn1.h" -#define MAX_FILE_SIZE 65535 - struct app_entry { const u8 *aid; size_t aid_len; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 38ad5fa85e..15977d7838 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -217,6 +217,8 @@ extern "C" { #define SC_EVENT_READER_DETACHED 0x0008 #define SC_EVENT_READER_EVENTS SC_EVENT_READER_ATTACHED|SC_EVENT_READER_DETACHED +#define MAX_FILE_SIZE 65535 + struct sc_supported_algo_info { unsigned int reference; unsigned int mechanism; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 7c56c0e731..e313dcc828 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1039,6 +1039,10 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) sc_log(ctx, "EF(ODF) is empty"); goto end; } + if (len > MAX_FILE_SIZE) { + sc_log(ctx, "EF(ODF) too large"); + goto end; + } buf = malloc(len); if(buf == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); From 6522df7587eeacff1a91de29f9cf6d03f5401d59 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 25 Oct 2019 17:10:52 +0200 Subject: [PATCH 1045/4321] pkcs15: Avoid null dereference in fuzzers https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16617 --- src/libopensc/pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index e313dcc828..6802269775 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2290,7 +2290,7 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p /* If the path length is 0, it's a dummy path then don't add it. * If the path length isn't included (-1) then it's against the standard * but we'll just ignore it instead of returning an error. */ - if (path.count > 0) { + if (path.count > 0 && p15card->file_app) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path); if (r < 0) return r; From 61cd7fcdb2fdc9214b431abb631b202314dcc32f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 21 Oct 2019 15:59:16 +0200 Subject: [PATCH 1046/4321] card-mcrd: Free the allocated structures on cleanup https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18416 --- src/libopensc/card-mcrd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index d7ad48d83f..52dc61028d 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -297,6 +297,7 @@ static int mcrd_finish(sc_card_t * card) while (priv->df_infos) { struct df_info_s *tmp = priv->df_infos->next; clear_special_files(priv->df_infos); + free(priv->df_infos); priv->df_infos = tmp; } free(priv); From 3c286b3cb1b234b88335029c968320b7ff8bc493 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 26 Oct 2019 23:50:11 +0200 Subject: [PATCH 1047/4321] fixed Null-dereference READ https://oss-fuzz.com/testcase-detail/5734505646391296 Thanks to OSS-Fuzz --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index c68f62c9d2..74d6135a25 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -68,7 +68,7 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, *buf = NULL; - if (left == 0) + if (left == 0 || !p) return SC_ERROR_INVALID_ASN1_OBJECT; if (*p == 0xff || *p == 0) { /* end of data reached */ From 026b6ab43dfb52b768ad15123dc698e05c52be20 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 26 Oct 2019 23:56:19 +0200 Subject: [PATCH 1048/4321] fuzzing: validate PIN only if it's a PIN https://oss-fuzz.com/testcase-detail/5693809152753664 --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 9bac1309fb..16578bf1c1 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -249,10 +249,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) in, in_len, buf, sizeof buf); } - sc_pkcs15_verify_pin(p15card, obj, in, in_len); - sc_pkcs15_change_pin(p15card, obj, in, in_len, param, param_len); - sc_pkcs15_unblock_pin(p15card, obj, in, in_len, param, param_len); - sc_pkcs15_get_pin_info(p15card, obj); + if (obj->type == SC_PKCS15_TYPE_AUTH_PIN) { + sc_pkcs15_verify_pin(p15card, obj, in, in_len); + sc_pkcs15_change_pin(p15card, obj, in, in_len, param, param_len); + sc_pkcs15_unblock_pin(p15card, obj, in, in_len, param, param_len); + sc_pkcs15_get_pin_info(p15card, obj); + } } sc_pkcs15_card_free(p15card); } From 60581ecc8205073ed9a363eb188f301b756a874d Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Thu, 24 Oct 2019 10:25:09 +0200 Subject: [PATCH 1049/4321] remove trailing whitespace Signed-off-by: Nuno Goncalves --- src/libopensc/pkcs15-itacns.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 970d93ef87..cb9a74fe31 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -208,15 +208,15 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, #endif SC_FUNC_CALLED(p15card->card->ctx, 1); - + if(type != SC_PKCS15_TYPE_CERT_X509) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Cannot add a certificate of a type other than X.509"); return 1; } - + *ext_info_ok = 0; - + memset(&info, 0, sizeof(info)); memset(&obj, 0, sizeof(obj)); @@ -312,7 +312,7 @@ static int itacns_add_prkey(sc_pkcs15_card_t *p15card, SC_FUNC_CALLED(p15card->card->ctx, 1); if(type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Cannot add a private key of a type other than RSA"); return 1; } @@ -525,7 +525,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32); if(rv < 0) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Data enumeration failed"); return SC_SUCCESS; } @@ -537,7 +537,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) } if(i>=32) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Could not find EF_DatiPersonali: " "keeping generic card name"); return SC_SUCCESS; @@ -545,7 +545,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) rv = sc_pkcs15_read_data_object(p15card, cinfo, &p15_personaldata); if (rv) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Could not read EF_DatiPersonali: " "keeping generic card name"); return SC_SUCCESS; @@ -555,7 +555,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) char fullname[160]; if(get_name_from_EF_DatiPersonali(p15_personaldata->data, fullname, sizeof(fullname))) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Could not parse EF_DatiPersonali: " "keeping generic card name"); sc_pkcs15_free_data_object(p15_personaldata); @@ -661,7 +661,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, /* Certificate */ if (!cert_path) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "We cannot use keys without a matching certificate"); return SC_ERROR_NOT_SUPPORTED; } @@ -671,7 +671,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, if (r == SC_ERROR_FILE_NOT_FOUND) return 0; if (r != SC_SUCCESS) { - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Could not find certificate for %s", label); return r; } @@ -726,7 +726,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_DECRYPT; } #else /* ENABLE_OPENSSL */ - sc_log(p15card->card->ctx, + sc_log(p15card->card->ctx, "Extended certificate info retrieved without OpenSSL. " "How is this possible?"); return SC_ERROR_INTERNAL; From 3ac47fbea9d04bba086cf068350a73b80e2e9178 Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Thu, 24 Oct 2019 10:26:26 +0200 Subject: [PATCH 1050/4321] replace SC_FUNC_CALLED(...,1) with SC_FUNC_CALLED(..., SC_LOG_DEBUG_NORMAL) (close #1698) Signed-off-by: Nuno Goncalves --- src/libopensc/pkcs15-itacns.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index cb9a74fe31..52118e9a44 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -179,7 +179,7 @@ static int loadFile(const sc_pkcs15_card_t *p15card, const sc_path_t *path, u8 *buf, const size_t buflen) { int sc_res; - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); sc_res = sc_select_file(p15card->card, path, NULL); if(sc_res != SC_SUCCESS) @@ -207,7 +207,7 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, sc_pkcs15_cert_t *cert; #endif - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); if(type != SC_PKCS15_TYPE_CERT_X509) { sc_log(p15card->card->ctx, @@ -273,7 +273,7 @@ static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_pubkey_info_t info; sc_pkcs15_object_t obj; - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); memset(&info, 0, sizeof(info)); memset(&obj, 0, sizeof(obj)); @@ -309,7 +309,7 @@ static int itacns_add_prkey(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t info; sc_pkcs15_object_t obj; - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); if(type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_log(p15card->card->ctx, @@ -348,7 +348,7 @@ static int itacns_add_pin(sc_pkcs15_card_t *p15card, struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); memset(&pin_info, 0, sizeof(pin_info)); pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; @@ -760,7 +760,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) int found_certs; int card_is_cie_v1, cns0_secenv; - SC_FUNC_CALLED(p15card->card->ctx, 1); + SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); set_string(&p15card->tokeninfo->label, p15card->card->name); if(p15card->card->drv_data) { @@ -848,7 +848,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) /* Did we find anything? */ if (certificate_count == 0) - sc_debug(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, + sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Warning: no certificates found!"); /* Back to Master File */ @@ -863,7 +863,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { sc_card_t *card = p15card->card; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); /* Check card */ if (! ( From 49f59d9fc9505bda45fe3842d834341a68323209 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Oct 2019 17:49:47 +0100 Subject: [PATCH 1051/4321] clean up already enumerated apps --- src/libopensc/dir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index c2a88fd9b8..bd60e52291 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -162,8 +162,9 @@ int sc_enum_apps(sc_card_t *card) int r, ii, idx; LOG_FUNC_CALLED(ctx); - if (card->app_count < 0) - card->app_count = 0; + + sc_free_apps(card); + card->app_count = 0; sc_format_path("3F002F00", &path); sc_file_free(card->ef_dir); From 6c7b4bed37f30707319ec5210b049777a291e5c3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2019 09:56:50 +0100 Subject: [PATCH 1052/4321] pkcs15*: Avoid null dereference from fuzzers Thanks oss-fuzz. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18591 --- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15-data.c | 2 +- src/libopensc/pkcs15-pin.c | 2 +- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15.c | 14 ++++++++------ 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 1a187f4135..6f7c50c3de 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -479,7 +479,7 @@ sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obje return r; LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - if (!p15card->app || !p15card->app->ddo.aid.len) { + if ((!p15card->app || !p15card->app->ddo.aid.len) && p15card->file_app) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); LOG_TEST_RET(ctx, r, "Cannot make absolute path"); } diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index 636968acb3..61e18c6c17 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -123,7 +123,7 @@ int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card, return r; LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - if (!p15card->app || !p15card->app->ddo.aid.len) { + if ((!p15card->app || !p15card->app->ddo.aid.len) && p15card->file_app) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) return r; diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 07387c5a01..8b7e5ac965 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -176,7 +176,7 @@ sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj /* Give priority to AID defined in the application DDO */ if (p15card->app && p15card->app->ddo.aid.len) info.path.aid = p15card->app->ddo.aid; - else if (p15card->file_app->path.len) + else if (p15card->file_app && p15card->file_app->path.len) info.path = p15card->file_app->path; } } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 96cee4eb89..32a6e94fb4 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -340,7 +340,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_PUBKEY_DSA; } - if (!p15card->app || !p15card->app->ddo.aid.len) { + if ((!p15card->app || !p15card->app->ddo.aid.len) && p15card->file_app) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info->path); if (r < 0) { goto err; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 6802269775..e6970e8ce3 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -607,12 +607,14 @@ parse_odf(const unsigned char * buf, size_t buflen, struct sc_pkcs15_card *p15ca if (r < 0) return r; type = r; - r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path); - if (r < 0) - return r; - r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path); - if (r) - return r; + if (p15card->file_app) { + r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path); + if (r < 0) + return r; + r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path); + if (r) + return r; + } } return 0; } From 829a73c941084e7ef03518a224fa3a9fc7352413 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2019 10:08:42 +0100 Subject: [PATCH 1053/4321] card-npa: Remove dead code --- src/libopensc/card-npa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index e477320e45..a9c232e33a 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -136,7 +136,7 @@ static int npa_match_card(sc_card_t * card) { int r = 0; - if (0 == r && SC_SUCCESS == sc_enum_apps(card)) { + if (SC_SUCCESS == sc_enum_apps(card)) { unsigned char esign_aid_0[] = { 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, }, esign_aid_1[] = { From 51363d33926f2748ca7c8b8fa395678faac17edb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2019 10:28:35 +0100 Subject: [PATCH 1054/4321] cac: Make sure we do not leak memory Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18564 --- src/libopensc/card-cac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d02e8318fb..d59b4337c8 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1410,6 +1410,7 @@ static int cac_parse_cuid(sc_card_t *card, cac_private_data_t *priv, cac_cuid_t sc_dump_hex(&val->card_id, card_id_len), card_id_len); priv->cuid = *val; + free(priv->cac_id); priv->cac_id = malloc(card_id_len); if (priv->cac_id == NULL) { return SC_ERROR_OUT_OF_MEMORY; @@ -1704,6 +1705,7 @@ static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t * if (r > 0) { #ifdef ENABLE_OPENSSL size_t val_len = r; + free(priv->cac_id); priv->cac_id = malloc(20); if (priv->cac_id == NULL) { return SC_ERROR_OUT_OF_MEMORY; From 424ebf8ed13d804246ba0c8a5e2576009b3c3f7b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2019 10:53:22 +0100 Subject: [PATCH 1055/4321] pkcs15: Avoid insane allocations Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18592 --- src/libopensc/pkcs15.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index e6970e8ce3..aa5412644e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1113,6 +1113,10 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) sc_log(ctx, "EF(TokenInfo) is empty"); goto end; } + if (len > MAX_FILE_SIZE) { + sc_log(ctx, "EF(TokenInfo) too large"); + goto end; + } buf = malloc(len); if(buf == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); From a3ee8cefc8057ae9199edbafc96643b4f225654e Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 29 Oct 2019 20:21:09 +0100 Subject: [PATCH 1056/4321] Generate consistent docbook id's --- doc/html.xsl | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/html.xsl b/doc/html.xsl index a9a95ee251..734fa98350 100644 --- a/doc/html.xsl +++ b/doc/html.xsl @@ -5,6 +5,7 @@ +

    OpenSC Manual Pages: Section 5


    Table of Contents

    opensc.conf — configuration file for OpenSC
    pkcs15-profile — format of profile for pkcs15-init

    Name

    opensc.conf — configuration file for OpenSC

    Description

    + -->

    OpenSC Manual Pages: Section 5


    Table of Contents

    opensc.conf — configuration file for OpenSC
    pkcs15-profile — format of profile for pkcs15-init

    Name

    opensc.conf — configuration file for OpenSC

    Description

    OpenSC obtains configuration data from the following sources in the following order

    1. command-line options @@ -122,7 +122,7 @@ westcos-tool: Configuration block for OpenSC tools

    -

    Configuration Options

    +

    Configuration Options

    debug = num;

    Amount of debug info to print (Default: @@ -153,6 +153,12 @@ Software\OpenSC Project\OpenSC\ProfileDir is checked. +

    + disable_colors = bool; +

    + Disable colors of log messages (Default: + false if attached to a console, + true otherwise).

    disable_popups = bool;

    @@ -176,7 +182,7 @@ default) will load all statically linked drivers.

    If an unknown (i.e. not internal or old) driver is - supplied, a separate configuration configuration + supplied, a separate configuration block has to be written for the driver. A special value old will load all statically linked drivers that may be removed in @@ -227,6 +233,10 @@ npa: See the section called “Configuration Options for German ID Card”

  • dnie: See the section called “Configuration Options for DNIe” +

  • + edo: See the section called “Configuration Options for Polish eID Card” +

  • + myeid: See the section called “Configuration Options for MyEID Card”

  • Any other value: Configuration block for an externally loaded card driver

  • @@ -332,7 +342,7 @@ Parameters for the OpenSC PKCS11 module.

    For details see the section called “Configuration of PKCS#11”. -

    Configuration of Smart Card Reader Driver

    Configuration Options for all Reader Drivers

    +

    Configuration of Smart Card Reader Driver

    Configuration Options for all Reader Drivers

    max_send_size = num; max_recv_size = num;

    @@ -429,7 +439,27 @@ readers = num;

    Virtual readers to allocate (Default: 2). -

    Configuration Options for German ID Card

    +

    Configuration Options for MyEID Card

    + disable_hw_pkcs1_padding = bool; +

    + The MyEID card can internally + encapsulate the data (hash code) + into a DigestInfo ASN.1 structure + according to the selected hash + algorithm (currently only for SHA1). + DigestInfo is padded to RSA key + modulus length according to PKCS#1 + v1.5, block type 01h. Size of the + DigestInfo must not exceed 40% + of the RSA key modulus length. If + this limit is unsatisfactory (for + example someone needs RSA 1024 + with SHA512), the user can disable + this feature. In this case, the + card driver will do everything + necessary before sending the data + (hash code) to the card. +

    Configuration Options for German ID Card

    can = value;

    German ID card requires the CAN to @@ -478,6 +508,16 @@ /usr/bin/pinentry). Only used if compiled with --enable-dnie-ui +

    Configuration Options for Polish eID Card

    + can = value; +

    + CAN (Card Access Number – 6 digit number + printed on the right bottom corner of the + front side of the document) is required + to establish connection with the card. + It might be overwritten by EDO_CAN + environment variable. Currently, it is not + possible to set it in any other way.

    Configuration based on ATR

    atrmask = hexstring; @@ -554,10 +594,10 @@ raw

    - md_read_only = bool; + read_only = bool;

    Mark card as read/only card in - Minidriver/BaseCSP interface + PKCS#11/Minidriver/BaseCSP interface (Default: false).

    md_supports_X509_enrollment = bool; @@ -724,7 +764,7 @@

    Where to cache the card's files. The default values are:

    • - $XDG_CACHE_HOME/opensc/ (if defined) + $XDG_CACHE_HOME/opensc/ (If $XDG_CACHE_HOME is defined)

    • $HOME/.cache/opensc/ (Unix)

    • @@ -755,6 +795,26 @@ CKA_ALWAYS_AUTHENTICATE may need to set this to get signatures to work with some cards (Default: false). +

      + It is recommended to enable also PIN caching using + use_pin_caching option for OpenSC + to be able to provide PIN for the card when needed. +

    + private_certificate = value; +

    + How to handle a PIN-protected certificate. Known + parameters: +

    • + protect: The certificate stays PIN-protected. +

    • + declassify: Allow + reading the certificate without + enforcing verification of the PIN. +

    • + ignore: Ignore PIN-protected certificates. +

    + (Default: ignore in Tokend, + protect otherwise).

    enable_pkcs15_emulation = bool;

    @@ -777,7 +837,7 @@ builtin_emulators = emulators;

    List of the builtin pkcs15 emulators to test - (Default: westcos, openpgp, + (Default: westcos, openpgp, starcert, tcos, esteid, itacns, PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, atrust-acos, tccardos, entersafe, pteid, @@ -856,13 +916,6 @@ Score for OpenSC.tokend (Default: 300). The tokend with the highest score shall be used. -

    - ignore_private_certificate = bool; -

    - Tokend ignore to read PIN protected certificate - that is set - SC_PKCS15_CO_FLAG_PRIVATE flag - (Default: true).

    Configuration of PKCS#11

    max_virtual_slots = num;

    @@ -1022,7 +1075,7 @@ For the module to simulate the opensc-onepin module behavior the following option create_slots_for_pins = "user"; -

    Environment

    +

    Environment

    OPENSC_CONF

    Filename for a user defined configuration file @@ -1065,7 +1118,7 @@

    PIV configuration during initialization with piv-tool. -

    Files

    +

    Files

    /usr/etc/opensc.conf

    System-wide configuration file @@ -1073,7 +1126,7 @@ /usr/share/doc/opensc/opensc.conf

    Extended example configuration file -


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    +


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    The pkcs15-init utility for PKCS #15 smart card personalization is controlled via profiles. When starting, it will read two such profiles at the moment, a generic application profile, and a card @@ -1089,10 +1142,10 @@ The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ -

    Syntax

    +

    Syntax

    This section should contain information about the profile syntax. Will add this soonishly. -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-crypt(1)

    diff --git a/doc/tools/tools.html b/doc/tools/tools.html index a0b0dac42f..e370fde4be 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -43,7 +43,7 @@ font-style: italic; } - -->

    OpenSC Manual Pages: Section 1


    Table of Contents

    cardos-tool — displays information about Card OS-based security tokens or format them + -->

    OpenSC Manual Pages: Section 1


    Table of Contents

    cardos-tool — displays information about Card OS-based security tokens or format them
    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
    dnie-tool — displays information about DNIe based security tokens
    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK)
    eidenv — utility for accessing visible data from electronic identity cards
    gids-tool — smart card utility for GIDS cards
    iasecc-tool — displays information about IAS/ECC card @@ -57,14 +57,11 @@
    opensc-tool — generic smart card utility
    piv-tool — smart card utility for HSPD-12 PIV cards
    pkcs11-tool — utility for managing and using PKCS #11 security tokens
    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
    pkcs15-init — smart card personalization utility
    pkcs15-tool — utility for manipulating PKCS #15 data structures on smart cards and similar security tokens
    sc-hsm-tool — smart card utility for SmartCard-HSM
    westcos-tool — utility for manipulating data structures on westcos smart cards

    Name

    cardos-tool — displays information about Card OS-based security tokens or format them -

    Synopsis

    cardos-tool [OPTIONS]

    Description

    +

    Synopsis

    cardos-tool [OPTIONS]

    Description

    The cardos-tool utility is used to display information about smart cards and similar security tokens based on Siemens Card/OS M4. -

    Options

    +

    Options

    - --card-driver name, - -c name

    Use the card driver specified by name. - The default is to auto-detect the correct card driver.

    --format, -f

    Format the card or token.

    @@ -74,12 +71,12 @@ --info, -i

    Display information about the card or token.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --startkey arg, @@ -96,13 +93,13 @@ -w

    Causes cardos-tool to wait for the token to be inserted into reader.

    -

    Authors

    cardos-tool was written by - Andreas Jellinghaus .


    Name

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

    Synopsis

    cryptoflex-tool [OPTIONS]

    Description

    +

    Authors

    cardos-tool was written by + Andreas Jellinghaus .


    Name

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

    Synopsis

    cryptoflex-tool [OPTIONS]

    Description

    cryptoflex-tool is used to manipulate PKCS data structures on Schlumberger Cryptoflex smart cards. Users can create, list and read PINs and keys stored on the smart card. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --app-df num, -a num @@ -144,12 +141,12 @@

    Reads a public key from the card, allowing the user to extract and store or use the public key

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --verbose, @@ -164,12 +161,12 @@ -w

    Causes cryptoflex-tool to wait for a card insertion.

    -

    See also

    +

    See also

    pkcs15-tool(1) -

    Authors

    cryptoflex-tool was written by - Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    +

    Authors

    cryptoflex-tool was written by + Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card. -

    Options

    +

    Options

    --idesp, -i @@ -181,7 +178,7 @@ --all, -a

    Displays every available information. - This command is equivalent to -d -i -s

    + This command is equivalent to -d -i -V -s

    --serial, -s

    Displays DNIe Serial Number @@ -192,23 +189,28 @@ Displays software version for in-card DNIe OS

    --pin pin, -p pin -

    Specify the user pin pin to use. - If set to env:VARIABLE, the - value of the environment variable - VARIABLE is used. - The default is do not enter pin

    - --reader num, - -r num -

    - Specify the reader to use. By default, the first +

    + These options can be used to specify the PIN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    + --reader arg, + -r arg +

    + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    - --driver driver, - -c driver -

    Specify the card driver driver to use. - Default is use driver from configuration file, or auto-detect if absent

    --wait, -w

    Causes dnie-tool to wait for the token to be inserted into reader.

    @@ -217,11 +219,11 @@

    Causes dnie-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    Authors

    dnie-tool was written by +

    Authors

    dnie-tool was written by Juan Antonio Martinez .


    Name

    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) -

    Synopsis

    egk-tool [OPTIONS]

    Description

    +

    Synopsis

    egk-tool [OPTIONS]

    Description

    The egk-tool utility is used to display information stored on the German elektronic health card (elektronische Gesundheitskarte, eGK). -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    @@ -230,10 +232,10 @@ --reader arg, -r arg

    - Specify the reader to use. - Use -1 as arg - to automatically detect the reader to use. - By default, the first reader with a present card is used. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen.

    --verbose, -v @@ -241,7 +243,7 @@ Causes egk-tool to be more verbose. Specify this flag several times to be more verbose.

    -

    Health Care Application (HCA)

    --pd

    +

    Health Care Application (HCA)

    --pd

    Show 'Persönliche Versicherungsdaten' (XML).

    --vd

    Show 'Allgemeine Versicherungsdaten' (XML). @@ -249,16 +251,16 @@ Show 'Geschützte Versicherungsdaten' (XML).

    --vsd-status

    Show 'Versichertenstammdaten-Status'. -

    Authors

    egk-tool was written by +

    Authors

    egk-tool was written by Frank Morgner .


    Name

    eidenv — utility for accessing visible data from - electronic identity cards

    Synopsis

    eidenv [OPTIONS]

    Description

    + electronic identity cards

    Synopsis

    eidenv [OPTIONS]

    Description

    The eidenv utility is used for accessing data from electronic identity cards (like national eID cards) which might not be present in PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

    Options

    +

    Options

    --exec prog, -x prog @@ -272,12 +274,12 @@

    Prints all data fields from the card, like validity period, document number etc.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --stats, @@ -291,19 +293,32 @@ --wait, -w

    Wait for a card to be inserted

    -

    Authors

    eidenv utility was written by - Stef Hoeben and Martin Paljak .


    Name

    gids-tool — smart card utility for GIDS cards

    Synopsis

    gids-tool [OPTIONS]

    +

    Authors

    eidenv utility was written by + Stef Hoeben and Martin Paljak .


    Name

    gids-tool — smart card utility for GIDS cards

    Synopsis

    gids-tool [OPTIONS]

    The gids-tool utility can be used from the command line to perform miscellaneous smart card operations on a GIDS smart card. -

    Options

    +

    Options

    -X, --initialize

    Initialize token.

    --admin-key argument

    Define the administrator key

    - --pin argument -

    Define user PIN.

    + --pin pin +

    + This option can be used to specify the PIN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    --serial-number argument

    Define serial number.

    -U, @@ -318,9 +333,9 @@ --reader argument, -r argument

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + argument is an ATR, the reader with a matching card will be chosen.

    -w, @@ -330,19 +345,19 @@ --verbose

    Verbose operation. Use several times to enable debug output.

    -

    See also

    +

    See also

    opensc-tool(1) -

    Authors

    gids-tool was written by +

    Authors

    gids-tool was written by Vincent Le Toux .


    Name

    iasecc-tool — displays information about IAS/ECC card -

    Synopsis

    iasecc-tool [OPTIONS]

    Description

    +

    Synopsis

    iasecc-tool [OPTIONS]

    Description

    The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards. -

    Options

    +

    Options

    - --reader num, + --reader arg,

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --list-applications, @@ -360,44 +375,44 @@ -w

    Causes iasecc-tool to wait for the token to be inserted into reader.

    -

    Authors

    iasecc-tool was written by - Viktor Tarasov .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the +

    Authors

    iasecc-tool was written by + Viktor Tarasov .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

    Options

    + the initial PUK-value.

    Options

    --help, -h

    Displays a short help message.

    - --pin pin-value, - -p pin-value + --pin pin, + -p pin

    Specifies the current value of the global PIN.

    - --puk pin-value, - -u pin-value + --puk pin, + -u pin

    Specifies the current value of the global PUK.

    - --pin0 pin-value, - -0 pin-value + --pin0 pin, + -0 pin

    Specifies the current value of the local PIN0 (aka local PIN).

    - --pin1 pin-value, - -1 pin-value + --pin1 pin, + -1 pin

    Specifies the current value of the local PIN1 (aka local PUK).

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    -v

    Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

    -

    PIN format

    With the -p, -u, -0 or the -1 +

    PIN format

    With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

    Commands

    When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

    Commands

    When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -441,15 +456,15 @@

    This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

    -

    See also

    +

    See also

    opensc-explorer(1) -

    Authors

    netkey-tool was written by +

    Authors

    netkey-tool was written by Peter Koch .


    Name

    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). -

    Synopsis

    npa-tool [OPTIONS]

    Description

    +

    Synopsis

    npa-tool [OPTIONS]

    Description

    The npa-tool utility is used to display information stored on the German eID card (neuer Personalausweis, nPA), and to perform some write and verification operations. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    @@ -458,10 +473,10 @@ --reader arg, -r arg

    - Specify the reader to use. - Use -1 as arg - to automatically detect the reader to use. - By default, the first reader with a present card is used. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen.

    --verbose, -v @@ -469,7 +484,7 @@ Causes npa-tool to be more verbose. Specify this flag several times to be more verbose.

    -

    Password Authenticated Connection Establishment (PACE)

    +

    Password Authenticated Connection Establishment (PACE)

    --pin [STRING], -p [STRING]

    @@ -496,7 +511,7 @@ and NEWPIN. You may want to clean your environment before enabling this. (default=off) -

    PIN management

    +

    PIN management

    --new-pin [STRING], -N [STRING]

    @@ -513,7 +528,7 @@

    Unblock PIN (uses PUK to activate three more retries). (default=off) -

    Terminal Authentication (TA) and Chip Authentication (CA)

    +

    Terminal Authentication (TA) and Chip Authentication (CA)

    --cv-certificate FILENAME, -C FILENAME

    @@ -557,17 +572,17 @@ (default=off)

    --disable-ca-checks

    Disable passive authentication. (default=off) -

    Read and write data groups

    --read-dg1

    Read data group 1: Document Type.

    --read-dg2

    Read data group 2: Issuing State.

    --read-dg3

    Read data group 3: Date of Expiry.

    --read-dg4

    Read data group 4: Given Name(s).

    --read-dg5

    Read data group 5: Family Name.

    --read-dg6

    Read data group 6: Religious/Artistic Name.

    --read-dg7

    Read data group 7: Academic Title.

    --read-dg8

    Read data group 8: Date of Birth.

    --read-dg9

    Read data group 9: Place of Birth.

    --read-dg10

    Read data group 10: Nationality.

    --read-dg11

    Read data group 11: Sex.

    --read-dg12

    Read data group 12: Optional Data.

    --read-dg13

    Read data group 13: Birth Name.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17: Normal Place of Residence.

    --read-dg18

    Read data group 18: Community ID.

    --read-dg19

    Read data group 19: Residence Permit I.

    --read-dg20

    Read data group 20: Residence Permit II.

    --read-dg21

    Read data group 21: Optional Data.

    +

    Read and write data groups

    --read-dg1

    Read data group 1: Document Type.

    --read-dg2

    Read data group 2: Issuing State.

    --read-dg3

    Read data group 3: Date of Expiry.

    --read-dg4

    Read data group 4: Given Name(s).

    --read-dg5

    Read data group 5: Family Name.

    --read-dg6

    Read data group 6: Religious/Artistic Name.

    --read-dg7

    Read data group 7: Academic Title.

    --read-dg8

    Read data group 8: Date of Birth.

    --read-dg9

    Read data group 9: Place of Birth.

    --read-dg10

    Read data group 10: Nationality.

    --read-dg11

    Read data group 11: Sex.

    --read-dg12

    Read data group 12: Optional Data.

    --read-dg13

    Read data group 13: Birth Name.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17: Normal Place of Residence.

    --read-dg18

    Read data group 18: Community ID.

    --read-dg19

    Read data group 19: Residence Permit I.

    --read-dg20

    Read data group 20: Residence Permit II.

    --read-dg21

    Read data group 21: Optional Data.

    --write-dg17 HEX_STRING

    Write data group 17: Normal Place of Residence.

    --write-dg18 HEX_STRING

    Write data group 18: Community ID.

    --write-dg19 HEX_STRING

    Write data group 19: Residence Permit I.

    - --write-dg20 HEX_STRING

    Write data group 20: Residence Permit II.

    --write-dg21 HEX_STRING

    Write data group 21: Optional Data.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    + --write-dg20 HEX_STRING

    Write data group 20: Residence Permit II.

    --write-dg21 HEX_STRING

    Write data group 21: Optional Data.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    Verify chip's validity with a reference date.

    --older-than YYYYMMDD

    Verify age with a reference date.

    --verify-community HEX_STRING

    Verify community ID with a reference ID. -

    Special options, not always useful

    +

    Special options, not always useful

    --break, -b

    @@ -586,9 +601,9 @@ Force compliance to BSI TR-03110 version 2.01. (default=off)

    --disable-all-checks

    Disable all checking of fly-by-data. (default=off) -

    Authors

    npa-tool was written by +

    Authors

    npa-tool was written by Frank Morgner .


    Name

    openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

    Synopsis

    openpgp-tool [OPTIONS]

    Description

    + and compatible tokens

    Synopsis

    openpgp-tool [OPTIONS]

    Description

    The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -596,8 +611,13 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

    Options

    +

    Options

    + --card-info, + -C +

    + Show card information. +

    --del-key arg

    Delete key indicated by arg. @@ -641,19 +661,37 @@

    Print help message on screen.

    - --key-length bitlength, - -L bitlength + --key-info, + -K

    - Specify the length of the key to be generated. - If not given, it defaults to 2048 bit. + Show information of keys on the card.

    - --pin string -

    - The PIN text to verify. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used. + --key-type keytype, + -t keytype +

    + Specify the type of the key to be generated. + Supported values for keytype are + rsa for RSA with 2048 bits, + rsaLENGTH + for RSA with a bit length of LENGTH. + + If not given, it defaults to rsa2048.

    + --pin pin +

    + This option can be used to specify the PIN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    --pretty

    Print values in pretty format. @@ -662,13 +700,13 @@

    Print values in raw format, as they are stored on the card.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first - reader with a present card is used. If - num is an ATR, the - reader with a matching card will be chosen. + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen.

    --user-info, -U @@ -694,26 +732,33 @@

    Wait for a card to be inserted.

    -

    Authors

    openpgp-tool utility was written by +

    Authors

    openpgp-tool utility was written by Peter Marschall .


    Name

    opensc-asn1 — parse ASN.1 data -

    Synopsis

    opensc-asn1 [OPTIONS] [FILES]

    Description

    +

    Synopsis

    opensc-asn1 [OPTIONS] [FILES]

    Description

    The opensc-asn1 utility is used to parse ASN.1 data. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    --version, -V

    Print version and exit.

    -

    Authors

    opensc-asn1 was written by +

    Authors

    opensc-asn1 was written by Frank Morgner .


    Name

    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    +

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    The opensc-explorer utility can be - used interactively to perform miscellaneous operations + used to perform miscellaneous operations such as exploring the contents of or sending arbitrary APDU commands to a smart card or similar security token. -

    Options

    +

    + If a SCRIPT is given, + opensc-explorer runs in non-interactive mode, + reading the commands from SCRIPT, + one command per line. + If no script is given, opensc-explorer + runs in interactive mode, reading commands from standard input. +

    Options

    The following are the command-line options for opensc-explorer. There are additional interactive commands available once it is running. @@ -721,72 +766,129 @@ --card-driver driver, -c driver

    - Use the given card driver. The default is - auto-detected. + Use the given card driver. + The default is to auto-detect the correct card driver. + The literal value ? lists + all available card drivers and terminates + opensc-explorer.

    --mf path, -m path

    - Select the file referenced by the given path on - startup. The default is the path to the standard master file, - 3F00. If path is empty (e.g. opensc-explorer - --mf ""), then no file is explicitly selected. -

    - --reader num, - -r num + Select the file referenced by the given path on startup. + The default is the path to the standard master file, + 3F00. If path + is empty (e.g. opensc-explorer --mf ""), + then no file is explicitly selected. +

    + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --verbose, -v

    - Causes opensc-explorer to be more - verbose. Specify this flag several times to enable - debug output in the opensc library. -

    + Cause opensc-explorer to be more + verbose. Specify this flag several times to enable + debug output in the opensc library. +

    --wait, -w -

    Wait for a card to be inserted

    -

    Commands

    - The following commands are supported at opensc-explorer's - interactive prompt or in script files passed via the command line parameter - SCRIPT. +

    + Wait for a card to be inserted. +

    +

    Commands

    + opensc-explorer supports commands with arguments + at its interactive prompt or in script files passed via the command line + parameter SCRIPT. +

    + Similar to a command shell like e.g. bash, + each input line is split into white-space separated words. + Of these words, the first one is used as the command, + while the remaining ones are treated as arguments to that command. +

    + The following commands are supported:

    + # + ... +

    + Treat line as a comment. + Ignore anything until the end of the line introduced by + #. +

    apdu - hex-data -

    Send a custom APDU command hex-data.

    + data... +

    + Send a custom APDU command to the card. + data is a series of + sequences of hexadecimal values and strings enclosed + in double quotes ("..."). +

    asn1 file-id -

    Parse and print the ASN.1 encoded content of the file specified by - file-id.

    + [rec-no] + [offs] +

    + Parse and print the ASN.1 encoded content of the working EF + specified by file-id. + If the optional parameter + rec-no is given and the file is + a record-oriented EF, parse and print only the record + indicated by this parameter. + If the optional parameter + offs is given, start parsing + and printing the file or record at the offset indicated + by the value given. + If this parameter is not given, the default offset is + 0. +

    cat [ file-id | sfi:short-id ] -

    Print the contents of the currently selected EF or the contents - of a file specified by file-id or the short file id + [rec-no] +

    + Print the contents of the working EF specified by + file-id or the short file id short-id. -

    + If the optional second parameter + rec-no is given, + only print the record indicated by this parameter. + If no argument is given, print the the contents + of the currently selected EF. +

    cd { .. | file-id | aid:DF-name }

    Change to another DF specified by the argument passed. If the argument given is .., then move up one level in the file system hierarchy. - If it is file-id, + If it is a file-id, which must be a DF directly beneath the current DF, then change to that DF. If it is an application identifier given as aid:DF-name, then jump to the MF of the application denoted by DF-name. -

    +

    change CHVpin-ref [ [old-pin] new-pin ] -

    Change a PIN, where pin-ref is the PIN reference.

    +

    + Change the PIN specified by pin-ref + from the value given by old-pin and + change its value to new-pin. +

    + old-pin and + new-pin can be + sequences of hexadecimal values, + strings enclosed in double quotes ("..."), + empty (""), or absent. + If absent, the values are read from the card reader's pin pad. +

    Examples:

    change CHV2 00:00:00:00:00:00 "foobar"

    Change PIN CHV2 @@ -802,89 +904,196 @@ create file-id size -

    Create a new EF. file-id specifies the - id number and size is the size of the new file. -

    +

    + Create a new EF. + file-id specifies the numeric id, and + size the size of the EF to create. +

    debug [level] -

    Set OpenSC debug level to level.

    If level is omitted the current debug level will be shown.

    +

    + Set OpenSC debug level to level. +

    + If level is omitted, + show the current debug level. +

    delete file-id -

    Remove the EF or DF specified by file-id

    +

    + Remove the EF or DF specified by + file-id. +

    do_get hex-tag [output] -

    Copy the internal card's 'tagged' data into the local file.

    The local file is specified by output while the tag of - the card's data is specified by hex-tag. +

    + Copy the contents of the card's data object + (DO) + specified by hex-tag + to the local host computer's file named + output.

    - If output is omitted, the name of the output file will be - derived from hex-tag. + If output is not given, + the contents of hex-tag + will be displayed as hex-dump.

    do_put hex-tag - input -

    Update internal card's 'tagged' data.

    hex-tag is the tag of the card's data. - input is the filename of the source file or the literal data presented as - a sequence of hexadecimal values or " enclosed string. + data +

    + Change the contents of the card's data object + (DO) + specified by hex-tag + to data. +

    + data is either a + sequence of hexadecimal values or a string enclosed + in double quotes ("...").

    echo string... -

    Print the strings given.

    +

    + Print the strings given. +

    erase -

    Erase the card, if the card supports it.

    +

    + Erase the card, if the card supports it. +

    get file-id [output] -

    Copy an EF to a local file. The local file is specified - by output while the card file is specified by file-id. +

    + Copy an EF to a local file. + The local file is specified by + output + while the card file is specified by + file-id.

    - If output is omitted, the name of the output file will be - derived from the full card path to file-id. + If output is omitted, + the name of the output file will be derived from the + full card path to file-id. +

    + get_record + file-id + rec-no + [output] +

    + Copy a record of a record-oriented EF to a local file. + The local file is specified by + output + while the card file and the record are specified by + file-id and + rec-no, +

    + If output is omitted, + the name of the output file will be derived from the + full card path to file-id. + and the rec-no. +

    + help + [pattern] +

    + Display the list of available commands, their options + and parameters together with a short help text. + If pattern is given, + the commands shown are limited to those matching + pattern.

    info [file-id] -

    Display attributes of a file specified by file-id. +

    + Display attributes of a file specified by + file-id. If file-id is not supplied, - the attributes of the current file are printed.

    + the attributes of the current file are displayed. +

    ls [pattern...] -

    List files in the current DF. - If no pattern is given, then all files are listed. - If one ore more patterns are given, only files matching - at least one pattern are listed.

    +

    + List files in the current DF. + If no pattern is given, + then all files are listed. + If one ore more patterns are given, + only files matching at least one + pattern are listed. +

    find [ start-id [end-id] ] -

    Find all files in the current DF. - Files are found by selecting all file identifiers in the range from start-fid to end-fid (by default from 0000 to FFFF).

    +

    + Find all files in the current DF. + Files are found by selecting all file identifiers in the range + from start-fid + to end-fid. +

    + If not given, the default value for + start-fid is 0000, + while the default for end-fid is + FFFF. +

    find_tags [ start-tag [end-tag] ] -

    Find all tags of data objects in the current context. - Tags are found by using GET DATA in the range from start-tag to end-tag (by default from 0000 to FFFF).

    +

    + Find all tags of data objects in the current context. + Tags are found by using GET DATA in the range from + from start-tag + to end-tag. +

    + If not given, the default value for + start-tag is 0000, + while the default for end-tag is + FFFF. +

    mkdir file-id size -

    Create a DF. file-id specifies the id number - and size is the size of the new file.

    +

    + Create a DF. + file-id specifies the numeric id, + and size the size of the DF to create. +

    + pin_info + key-typekey-id +

    + Get information on a PIN or key from the card, where + key-type can be one of + CHV, KEY, + AUT or PRO. + key-id is a number + representing the key or PIN reference. +

    put file-id input -

    Copy a local file to the card. The local file is specified - by input while the card file is specified by file-id. -

    +

    + Copy a local file to the card. + The local file is specified by input + while the card file is specified by + file-id. +

    quit

    Exit the program.

    random count -

    Generate random sequence of count bytes.

    + [output-file] +

    + Generate count bytes + of random data. + If output-file is given, + write the data to the host computer's file denoted + by it, otherwise show the data as hex dump. +

    rm file-id -

    Remove the EF or DF specified by file-id

    +

    + Remove the EF or DF specified by + file-id. +

    unblock CHVpin-ref [ @@ -893,13 +1102,15 @@ ]

    Unblock the PIN denoted by pin-ref - using the PUK puk, and set potentially + using the PUK puk, and potentially change its value to new-pin.

    - PUK and PIN values can be a sequence of hexadecimal values, - "-enclosed strings, empty (""), - or absent. - If they are absent, the values are read from the card reader's pin pad. + puk and + new-pin can be + sequences of hexadecimal values, + strings enclosed in double quotes ("..."), + empty (""), or absent. + If absent, the values are read from the card reader's pin pad.

    Examples:

    unblock CHV2 00:00:00:00:00:00 "foobar"

    @@ -928,39 +1139,55 @@ file-id offs data -

    Binary update of the file specified by +

    + Binary update of the file specified by file-id with the literal data data starting from offset specified - by offs.

    data can be supplied as a sequencer - of the hex values or as a " enclosed string.

    + by offs. +

    + data can be supplied as a sequence + of hexadecimal values or as a string enclosed in double quotes + ("..."). +

    update_record file-id rec-nr rec-offs data -

    Update record specified by rec-nr of the file - specified by file-id with the literal data - data starting from offset specified by - rec-offs.

    data can be supplied as a sequence of the hex values or - as a " enclosed string.

    +

    + Update record specified by rec-nr + of the file specified by file-id + with the literal data data + starting from offset specified by + rec-offs. +

    + data can be supplied as a sequence + of hexadecimal values or as a string enclosed in double quotes + ("..."). +

    verify key-typekey-id [key] -

    Present a PIN or key to the card, where - key-type can be one of CHV, - KEY, AUT or PRO. - key-id is a number representing the key or PIN reference. - key is the key or PIN to be verified, formatted as a - colon-separated list of hex values or a " enclosed string. +

    + Present a PIN or key to the card, where + key-type can be one of + CHV, KEY, + AUT or PRO. + key-id is a number representing + the key or PIN reference. + key is the key or PIN to be verified, + formatted as a colon-separated sequence of hexadecimal values + or a string enclosed in double quotes ("...").

    - If key is omitted, the exact action depends on the - card reader's features: if the card readers supports PIN input via a pin pad, + If key is omitted, the exact action + depends on the card reader's features: + if the card readers supports PIN input via a pin pad, then the PIN will be verified using the card reader's pin pad. - If the card reader does not support PIN input, then the PIN will be asked - interactively. + If the card reader does not support PIN input, + then the PIN will be asked interactively.

    Examples: -

    verify CHV0 31:32:33:34:00:00:00:00

    +

    verify CHV2 31:32:33:34:00:00:00:00

    Verify CHV2 using the hex value 31:32:33:34:00:00:00:00

    verify CHV1 "secret"

    @@ -973,21 +1200,24 @@

    sm { open | close } -

    Calls the card's open or close Secure Messaging handler.

    -

    See also

    +

    + Call the card's open or + close Secure Messaging handler. +

    +

    See also

    opensc-tool(1) -

    Authors

    opensc-explorer was written by +

    Authors

    opensc-explorer was written by Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications -

    Synopsis

    opensc-notify [OPTIONS]

    Description

    +

    Synopsis

    opensc-notify [OPTIONS]

    Description

    The opensc-notify utility is used to monitor smart card events and send the appropriate notification. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    --version, -V

    Print version and exit.

    -

    Mode: customized

    +

    Mode: customized

    Send customized notifications.

    --title [STRING], @@ -999,7 +1229,7 @@ -m [STRING]

    Specify the main text of the notification. -

    Mode: standard

    +

    Mode: standard

    Manually send standard notifications.

    --notify-card-inserted, @@ -1021,14 +1251,14 @@ -B

    See notify_pin_bad in opensc.conf (default=off). -

    Authors

    opensc-notify was written by - Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    +

    Authors

    opensc-notify was written by + Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    The opensc-tool utility can be used from the command line to perform miscellaneous smart card operations such as getting the card ATR or sending arbitrary APDU commands to a card. -

    Options

    +

    Options

    - --version, + --version

    Print the OpenSC package release version.

    --atr, -a @@ -1036,8 +1266,12 @@ Output is in hex byte format

    --card-driver driver, -c driver -

    Use the given card driver. - The default is auto-detected.

    +

    + Use the given card driver. + The default is to auto-detect the correct card driver. + The literal value ? lists + all available card drivers. +

    --list-algorithms,

    Lists algorithms supported by card

    --info, @@ -1060,13 +1294,13 @@

    Get configuration key, format: section:name:key

    --set-conf-entry conf, -S conf -

    Get configuration key, format: section:name:key:value

    - --reader num, - -r num +

    Set configuration key, format: section:name:key:value

    + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --reset [type], @@ -1087,16 +1321,16 @@ --wait, -w

    Wait for a card to be inserted.

    -

    See also

    +

    See also

    opensc-explorer(1) -

    Authors

    opensc-tool was written by - Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    +

    Authors

    opensc-tool was written by + Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. -

    Options

    +

    Options

    --serial

    Print the card serial number derived from the CHUID object, @@ -1162,18 +1396,14 @@

    Sends an arbitrary APDU to the card in the format AA:BB:CC:DD:EE:FF.... This option may be repeated.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    - --card-driver driver, - -c driver -

    Use the given card driver. - The default is auto-detected.

    --wait, -w

    Wait for a card to be inserted

    @@ -1182,16 +1412,16 @@

    Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    See also

    +

    See also

    opensc-tool(1) -

    Authors

    piv-tool was written by - Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    +

    Authors

    piv-tool was written by + Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --attr-from filename

    Extract information from filename @@ -1211,9 +1441,9 @@

    Hash some data.

    --hash-algorithm mechanism

    - Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. - Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may - also allow "SHA224". Default is "SHA-1". + Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + also allow "SHA224". Default is "SHA-1".

    Note that the input to RSA-PKCS-PSS has to be of the size equal to the specified hash algorithm. E.g., for SHA256 the signature input must @@ -1244,13 +1474,17 @@ --keygen

    Generate a new key.

    --key-type specification -

    Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1.

    +

    Specify the type and length (bytes if symmetric) of the key to create, + for example RSA:1024, EC:prime256v1, GOSTR3410-2012-256:B, + DES:8, DES3:24, AES:16 or GENERIC:64.

    --usage-sign

    Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

    --usage-decrypt

    Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey).

    --usage-derive

    Specify 'derive' key usage flag (EC only).

    + --usage-wrap +

    Specify 'wrap' key usage flag.

    --label name, -a name

    Specify the name of the object to operate on @@ -1268,6 +1502,8 @@ --list-token-slots, -T

    List slots with tokens.

    + --list-interfaces +

    List interfaces of PKCS #11 3.0 library.

    --login, -l

    Authenticate to the token before performing @@ -1294,7 +1530,7 @@ load.

    --moz-cert filename, -z filename -

    Test a Mozilla-like keypair generation +

    Test a Mozilla-like key pair generation and certificate request. Specify the filename to the certificate file.

    --output-file filename, @@ -1319,6 +1555,8 @@

    Supply new User PIN on the command line.

    --sensitive

    Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext).

    + --extractable +

    Set the CKA_EXTRACTABLE attribute (object can be extracted)

    --set-id id, -e id

    Set the CKA_ID of the object.

    @@ -1346,6 +1584,14 @@

    Specify the description of the slot to use.

    --slot-index index

    Specify the index of the slot to use.

    + --object-index index +

    Specify the index of the object to use.

    + --use-locking +

    Tell pkcs11 module it should use OS thread locking. +

    + --test-threads options +

    Test a pkcs11 module's thread implication. (See source code). +

    --token-label label

    Specify the label of token. Will be used the first slot, that has the inserted token with this @@ -1369,6 +1615,14 @@ --private

    Set the CKA_PRIVATE attribute (object is only viewable after a login).

    + --always-auth +

    Set the CKA_ALWAYS_AUTHENTICATE attribute to a private key object. + If set, the user has to supply the PIN for each use (sign or decrypt) with the key.

    + --allowed-mechanisms mechanisms +

    Sets the CKA_ALLOWED_MECHANISMS attribute + to a key objects when importing an object or generating + a keys. The argument accepts comma-separated list of + algorithmsm, that can be used with the given key.

    --test-ec

    Test EC (best used with the --login or --pin option).

    @@ -1378,14 +1632,17 @@ --type type, -y type

    Specify the type of object to operate on. - Examples are cert, privkey - and pubkey.

    + Valid value are cert, privkey, + pubkey, secrkey + and data.

    --verbose, -v

    Cause pkcs11-tool to be more verbose.

    NB! This does not affect OpenSC debugging level! To set OpenSC PKCS#11 module into debug mode, set the OPENSC_DEBUG environment variable to a non-zero number.

    + --verify, +

    Verify signature of some data.

    --read-object, -r

    Get object's CKA_VALUE attribute (use with @@ -1405,6 +1662,8 @@ --subject data

    Specify the subject in hexadecimal format (use with --type cert/privkey/pubkey).

    + --signature-file filename +

    The path to the signature file for signature verification

    --signature-format format

    Format for ECDSA signature: 'rs' (default), 'sequence', 'openssl'.

    @@ -1412,17 +1671,21 @@ -w filename

    Write a key or certificate object to the token. filename points to the DER-encoded certificate or key file. -

    +

    --generate-random num

    Get num bytes of random data. -

    -

    Examples

    +

    + --allow-sw +

    Allow using software mechanisms that do not have the CKF_HW flag set. + May be required when using software tokens and emulators. +

    +

    Examples

    To list all certificates on the smart card:

    pkcs11-tool --list-objects --type cert

    To read the certificate with ID KEY_ID in DER format from smart card: -

    pkcs11-tool --read-object  --id KEY_ID --type cert --outfile cert.der

    +

    pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der

    To convert the certificate in DER format to PEM format, use OpenSSL tools: @@ -1432,13 +1695,13 @@ using the private key with ID ID and using the RSA-PKCS mechanism:

    pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

    -

    Authors

    pkcs11-tool was written by - Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    +

    Authors

    pkcs11-tool was written by + Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 compliant smart card. -

    Options

    +

    Options

    --version,

    Print the OpenSC package release version.

    @@ -1488,12 +1751,12 @@ --raw, -R

    Outputs raw 8 bit data.

    - --reader N, - -r N + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --md5 @@ -1535,18 +1798,18 @@

    Causes pkcs15-crypt to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

    -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-tool(1) -

    Authors

    pkcs15-crypt was written by - Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    +

    Authors

    pkcs15-crypt was written by + Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles.

    The profile used by default is pkcs15. Alternative profiles can be specified via the -p switch. -

    PIN Usage

    +

    PIN Usage

    pkcs15-init can be used to create a PKCS #15 structure on your smart card, create PINs, and install keys and certificates on the card. This process is also called personalization. @@ -1578,7 +1841,7 @@ are protected and cannot be parsed without authentication (usually with User PIN). This authentication need to be done immediately after the card binding. In such cases --verify-pin has to be used. -

    Modes of operation

    Initialization

    This is the first step during card personalization, and will create the +

    Modes of operation

    Initialization

    This is the first step during card personalization, and will create the basic files on the card. To create the initial PKCS #15 structure, invoke the utility as

    @@ -1588,7 +1851,7 @@

    If the card supports it, you should erase the contents of the card with pkcs15-init --erase-card before creating the PKCS#15 structure. -

    User PIN Installation

    +

    User PIN Installation

    Before installing any user objects such as private keys, you need at least one PIN to protect these objects. you can do this using

    @@ -1602,25 +1865,26 @@

    To set a label for this PIN object (which can be used by applications to display a meaningful prompt to the user), use the --label command line option. -

    Key generation

    +

    Key generation

    pkcs15-init lets you generate a new key and store it on the card. You can do this using:

    pkcs15-init --generate-key " keyspec " --auth-id " nn

    - where keyspec describes the algorithm and length of the - key to be created, such as rsa/512. This will create a 512 bit - RSA key. Currently, only RSA key generation is supported. Note that cards - usually support just a few different key lengths. Almost all cards will support - 512 and 1024 bit keys, some will support 768 or 2048 as well. + where keyspec describes the algorithm and the parameters + of the key to be created. For example, rsa:2048 generates a RSA key + with 2048-bit modulus. If you are generating an EC key, the curve designation must + be specified, for example ec:prime256v1. For symmetric key, + the length of key is specified in bytes, for example AES:32 + or DES3:24.

    nn is the ID of a user PIN installed previously, e.g. 01.

    In addition to storing the private portion of the key on the card, - pkcs15-init will also store the the public portion of the + pkcs15-init will also store the public portion of the key as a PKCS #15 public key object. -

    Private Key Upload

    +

    Private Key Upload

    You can use a private key generated by other means and upload it to the card. For instance, to upload a private key contained in a file named okir.pem, which is in PEM format, you would use @@ -1628,7 +1892,7 @@ pkcs15-init --store-private-key okir.pem --id 45 --auth-id 01

    In addition to storing the private portion of the key on the card, - pkcs15-init will also store the the public portion of the + pkcs15-init will also store the public portion of the key as a PKCS #15 public key object.

    Note that usage of --id option in the pkcs15-init @@ -1644,7 +1908,7 @@ a file. A PKCS #12 file usually contains the X.509 certificate corresponding to the private key. If that is the case, pkcs15-init will store the certificate instead of the public key portion. -

    Public Key Upload

    +

    Public Key Upload

    You can also upload individual public keys to the card using the --store-public-key option, which takes a filename as an argument. This file is supposed to contain the public key. If you don't @@ -1655,12 +1919,12 @@ Since the corresponding public keys are always uploaded automatically when generating a new key, or when uploading a private key, you will probably use this option only very rarely. -

    Certificate Upload

    +

    Certificate Upload

    You can upload certificates to the card using the --store-certificate option, which takes a filename as an argument. This file is supposed to contain the PEM encoded X.509 certificate. -

    Uploading PKCS #12 bags

    +

    Uploading PKCS #12 bags

    Most browsers nowadays use PKCS #12 format files when you ask them to export your key and certificate to a file. pkcs15-init is capable of parsing these files, and storing their contents on the @@ -1674,16 +1938,16 @@ and protect it with the PIN referenced by authentication ID 01. It will also store any X.509 certificates contained in the file, which is usually the user certificate that goes with the key, as well as the CA certificate. -

    Secret Key Upload

    +

    Secret Key Upload

    You can use a secret key generated by other means and upload it to the card. For instance, to upload an AES-secret key generated by the system random generator you would use

    - pkcs15-init --store-secret-key /dev/urandom --secret-key-algorithm aes/256 --auth-id 01 + pkcs15-init --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --auth-id 01

    By default a random ID is generated for the secret key. You may specify an ID with the --id if needed. -

    Options

    +

    Options

    --version,

    Print the OpenSC package release version.

    @@ -1719,9 +1983,9 @@ -G keyspec

    Tells the card to generate new key and store it on the card. - keyspec consists of an algorithm name - (currently, the only supported name is RSA), - optionally followed by a slash and the length of the key in bits. + keyspec consists of an algorithm name, + optionally followed by a colon ":", slash "/" or hyphen "-" and + the parameters of the key to be created. It is a good idea to specify the key ID along with this command, using the id option, otherwise an intrinsic ID will be calculated from the key material. Look the description of @@ -1730,36 +1994,23 @@ For the multi-application cards the target PKCS#15 application can be specified by the hexadecimal AID value of the aid option.

    - --options-file filename -

    - Tells pkcs15-init to read additional options - from filename. The file is supposed to - contain one long option per line, without the leading dashes, - for instance: -

    -pin		1234
    -puk		87654321
    -							

    + --pin pin, + --puk puk, + --so-pin sopin, + --so-puk sopuk +

    + These options can be used to specify the PIN/PUK values + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed.

    - You can specify --options-file several times. -

    - --pin, - --puk - --so-pin, - --so-puk, -

    - These options can be used to specify PIN/PUK values - on the command line. If set to - env:VARIABLE, the value - of the environment variable - VARIABLE is used. Note - that on most operation systems, any user can + Note that on most operation systems, any user can display the command line of any process on the system using utilities such as - ps(1). Therefore, you should use - these options only on a secured system, or in an - options file specified with - --options-file. + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system.

    --no-so-pin,

    @@ -1786,7 +2037,7 @@ --secret-key-algorithm keyspec,

    keyspec describes the algorithm and length of the - key to be created or downloaded, such as aes/256. + key to be created or downloaded, such as aes:256. This will create a 256 bit AES key.

    --store-certificate filename, @@ -1907,12 +2158,12 @@ card specific sanity check and possibly update procedure.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --verbose, @@ -2007,6 +2258,13 @@

    Private key stored as an extractable key

    + --user-consent arg +

    + Specify user-consent. arg is an integer value. + If > 0, the value specifies how many times the + object can be accessed before a new authentication is required. + If zero, the object does not require re-authentication. +

    --insecure

    Insecure mode: do not require a PIN for private key @@ -2020,25 +2278,25 @@

    Display help message

    -

    See also

    +

    See also

    pkcs15-profile(5) -

    Authors

    pkcs15-init was written by +

    Authors

    pkcs15-init was written by Olaf Kirch .


    Name

    pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens

    Synopsis

    pkcs15-tool [OPTIONS]

    Description

    + on smart cards and similar security tokens

    Synopsis

    pkcs15-tool [OPTIONS]

    Description

    The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --version,

    Print the OpenSC package release version.

    --aid aid

    Specify in a hexadecimal form the AID of the on-card PKCS#15 application to bind to.

    - --auth-id pin, - -a pin + --auth-id id, + -a id

    Specifies the auth id of the PIN to use for the operation. This is useful with the --change-pin operation.

    --change-pin @@ -2109,8 +2367,7 @@ the binary data directly. This does not affect the output that is written to the file specified by the --output option. Data written to a file will always be in raw binary.

    - --read-certificate cert, - -r cert + --read-certificate cert

    Reads the certificate with the given id.

    --read-data-object cert, -R data @@ -2137,11 +2394,11 @@ --update, -U,

    Update the card with a security update

    - --reader num + --reader arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --unblock-pin, @@ -2153,11 +2410,24 @@

    Causes pkcs15-tool to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

    - --pin PIN -

    Specify PIN

    - --puk PUK -

    Specify Unblock PIN

    - --new-pin PIN + --pin pin, + --new-pin newpin + --puk puk +

    + These options can be used to specify the PIN/PUK values + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    + --new-pin pin

    Specify New PIN (when changing or unblocking)

    --verify-pin

    Verify PIN after card binding and before issuing any command @@ -2171,16 +2441,16 @@ wait for a card insertion.

    --use-pinpad

    Do not prompt the user; if no PINs supplied, pinpad will be used.

    -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-crypt(1) -

    Authors

    pkcs15-tool was written by - Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    +

    Authors

    pkcs15-tool was written by + Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. -

    Options

    +

    Options

    --initialize, -X @@ -2209,19 +2479,28 @@ same SmartCard-HSM.

    After using --initialize with one or more DKEK shares, the SmartCard-HSM will remain in the initialized state until all DKEK shares have been imported. During this phase no new keys can be generated or imported.

    - --so-pin value -

    Define SO-PIN for initialization. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used.

    - --pin value -

    Define user PIN for initialization, wrap or - unwrap operation. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used.

    + --pin pin, + --so-pin sopin, +

    + These options can be used to specify the PIN values + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    --pin-retry value

    Define number of PIN retries for user PIN during initialization. Default is 3.

    + --bio-server1 value +

    The hexadecimal AID of of the biometric server for template 1. Switches on the use of the user PIN as session PIN.

    + --bio-server2 value +

    The hexadecimal AID of of the biometric server for template 2. Switches on the use of the user PIN as session PIN.

    --password value

    Define password for DKEK share encryption. If set to env:VARIABLE, the value of @@ -2236,12 +2515,12 @@ --label label, -l label

    Define the token label to be used in --initialize.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --wait, @@ -2252,16 +2531,16 @@

    Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    See also

    +

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    See also

    opensc-tool(1) -

    Authors

    sc-hsm-tool was written by +

    Authors

    sc-hsm-tool was written by Andreas Schwier .


    Name

    westcos-tool — utility for manipulating data structures - on westcos smart cards

    Synopsis

    westcos-tool [OPTIONS]

    Description

    + on westcos smart cards

    Synopsis

    westcos-tool [OPTIONS]

    Description

    The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, keys and certificates stored on the card / token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --change-pin, -n @@ -2300,30 +2579,35 @@ --overwrite-key, -o

    Overwrite the key if there is already a key on the card.

    - --pin-value value, - -x value -

    Set value of PIN. If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used.

    - --puk-value value, - -y value -

    set value of PUK (or value of new PIN for change PIN - command see -n). If set to - env:VARIABLE, the value of - the environment variable - VARIABLE is used.

    + --pin-value pin, + -x pin + --puk-value puk, + -y puk +

    + These options can be used to specify the PIN/PUK values + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + Note that on most operation systems, any user can + display the command line of any process on the + system using utilities such as + ps(1). Therefore, you should prefer + passing the codes via an environment variable + on an unsecured system. +

    --read-file filename, -j filename

    Read the file filename from the card. The file is written on disk with name filename. User authentication is required for this operation.

    - --reader num, - -r num + --reader arg, + -r arg

    - Specify the reader to use. By default, the first + Number of the reader to use. By default, the first reader with a present card is used. If - num is an ATR, the + arg is an ATR, the reader with a matching card will be chosen.

    --unblock-pin, @@ -2344,5 +2628,5 @@ from disk to card. On the card the file is written in filename. User authentication is required for this operation.

    -

    Authors

    westcos-tool was written by +

    Authors

    westcos-tool was written by Francois Leblanc .

    From 3f199915563edd5896248dcffc60e6683bb1fca0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Apr 2021 18:12:40 +0200 Subject: [PATCH 1865/4321] updated NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index d48d076532..bdb84b8bbf 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,8 @@ NEWS for OpenSC -- History of user visible changes * Fixed asking for a user pin when formatting a card (#1737) ## IAS/ECC * Added support for French CPx Healthcare cards (#2217) +## CardOS + * Added ATR for new CardOS 5.4 version (#2296) # New in 0.21.0; 2020-11-24 ## General Improvements From e93bd3983ca135f63dc8860febca3ee7f702853a Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Mon, 26 Apr 2021 17:38:44 +0000 Subject: [PATCH 1866/4321] IASECC/Gemalto: add support Add support for Gemalto's IAS ECC Dual ID One Cosmo using samples from: http://cartesapuce-discount.com/fr/cartes-a-puce-ias-ecc/146-cartes-a-puce-protiva-ias-ecc-tpc.html Some suppots were already available (ATR, init, etc.), but the select_file was missing the proper cases. --- src/libopensc/card-iasecc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 9e91fe7776..8682e143e3 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -920,6 +920,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, sc_print_cache(card); if ((!iasecc_is_cpx(card)) && + (card->type != SC_CARD_TYPE_IASECC_GEMALTO) && (path->type != SC_PATH_TYPE_DF_NAME && lpath.len >= 2 && lpath.value[0] == 0x3F && lpath.value[1] == 0x00)) { @@ -1017,6 +1018,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, card->type == SC_CARD_TYPE_IASECC_AMOS || card->type == SC_CARD_TYPE_IASECC_MI || card->type == SC_CARD_TYPE_IASECC_MI2 || + card->type == SC_CARD_TYPE_IASECC_GEMALTO || iasecc_is_cpx(card) ) { apdu.p2 = 0x04; @@ -1028,6 +1030,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, card->type == SC_CARD_TYPE_IASECC_AMOS || card->type == SC_CARD_TYPE_IASECC_MI || card->type == SC_CARD_TYPE_IASECC_MI2 || + card->type == SC_CARD_TYPE_IASECC_GEMALTO || iasecc_is_cpx(card)) { apdu.p2 = 0x04; } @@ -1042,6 +1045,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, if (card->type == SC_CARD_TYPE_IASECC_AMOS || card->type == SC_CARD_TYPE_IASECC_MI2 || card->type == SC_CARD_TYPE_IASECC_OBERTHUR || + card->type == SC_CARD_TYPE_IASECC_GEMALTO || iasecc_is_cpx(card)) { apdu.p2 = 0x04; } From a21bcf4b4124968849a1280ae71026089008df7e Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Mon, 29 Mar 2021 23:36:25 +0000 Subject: [PATCH 1867/4321] IASECC/Gemalto: register application Register application for Gemalto Dual ID ONE Cosmo. --- src/libopensc/dir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 6aa2511657..6863ff57fe 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -42,6 +42,8 @@ static const struct app_entry apps[] = { { (const u8 *) "\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E", 15, "ESIGN"}, { (const u8 *) "\xE8\x28\xBD\x08\x0F\x80\x25\x00\x00\x01\xFF\x00\x10", 13, "CPx IAS"}, { (const u8 *) "\xE8\x28\xBD\x08\x0F\x80\x25\x00\x00\x01\xFF\x00\x20", 13, "CPx IAS CL"}, + { (const u8 *) "\xE8\x28\xBD\x08\x0F\xD2\x50\x45\x43\x43\x2D\x65\x49\x44", 14, "ECC eID"}, + { (const u8 *) "\xE8\x28\xBD\x08\x0F\xD2\x50\x47\x65\x6E\x65\x72\x69\x63", 14, "ECC Generic PKI"}, }; static const struct sc_asn1_entry c_asn1_dirrecord[] = { From 19611682bdc9d37804de144dabc2da96fe7ecb28 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 1 Apr 2021 10:51:27 -0500 Subject: [PATCH 1868/4321] Fix for #2283 C_Sign fails ECDSA when card can do HASH on card Do not truncate ECDSA input to size of key if card or driver will do HASH. On branch Fix_for_2283_ECDSA Changes to be committed: modified: src/libopensc/pkcs15-sec.c --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 249cb0620e..4fa623fff6 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -737,7 +737,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, * But if card is going to do the hash, pass in all the data */ else if (senv.algorithm == SC_ALGORITHM_EC && - (senv.flags & SC_ALGORITHM_ECDSA_HASHES) == 0) { + (senv.algorithm_flags & SC_ALGORITHM_ECDSA_HASHES) == 0) { inlen = MIN(inlen, (prkey->field_length+7)/8); } From 570fc56c47524b9a23beddc0ab7426a31491c4ff Mon Sep 17 00:00:00 2001 From: Anton Logachev Date: Thu, 8 Apr 2021 18:00:30 +0300 Subject: [PATCH 1869/4321] Remove the SC_SEC_ENV_FILE_REF_PRESENT flag for Rutoken ECP cards Rutoken ECP cards have no default SE file. Previous cards ignored MSE with restoring default SE, but new cards don't. This requires SC_SEC_ENV_FILE_REF_PRESENT to be removed from env flags. --- src/libopensc/card-rtecp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 81a2d9595f..db70fba808 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -366,6 +366,19 @@ static int rtecp_logout(sc_card_t *card) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } +static int rtecp_set_security_env( struct sc_card *card, + const struct sc_security_env *env, + int se_num) +{ + struct sc_security_env se_env; + if(!env) + return SC_ERROR_INVALID_ARGUMENTS; + + se_env= *env; + se_env.flags &= ~SC_SEC_ENV_FILE_REF_PRESENT; + return iso_ops->set_security_env(card, &se_env, se_num); +} + static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, u8 *out, size_t out_len, int sign) { @@ -824,7 +837,7 @@ struct sc_card_driver * sc_get_rtecp_driver(void) rtecp_ops.verify = rtecp_verify; rtecp_ops.logout = rtecp_logout; /* restore_security_env */ - /* set_security_env */ + rtecp_ops.set_security_env = rtecp_set_security_env; rtecp_ops.decipher = rtecp_decipher; rtecp_ops.compute_signature = rtecp_compute_signature; rtecp_ops.change_reference_data = rtecp_change_reference_data; From 32004e74ceeb2ce346ef8e0cf37fbe663320ccf0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 1 May 2021 01:42:11 +0200 Subject: [PATCH 1870/4321] added missing files to distribution --- src/pkcs15init/Makefile.am | 2 +- tests/Makefile.am | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 1ff594c0a5..890020d443 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = Makefile.mak noinst_LTLIBRARIES = libpkcs15init.la -noinst_HEADERS = profile.h pkcs15-init.h pkcs15-oberthur.h +noinst_HEADERS = profile.h pkcs15-init.h pkcs15-oberthur.h pkcs15-iasecc.h dist_pkgdata_DATA = \ cyberflex.profile \ flex.profile \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 169f108e31..7213bd9cf1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,6 +2,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in dist_noinst_SCRIPTS = common.sh \ test-manpage.sh \ + test-duplicate-symbols.sh \ test-fuzzing.sh \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ From 50eaa6bf5711bf59bc30dbdf70769c6297560bde Mon Sep 17 00:00:00 2001 From: ihsinme Date: Sun, 2 May 2021 14:42:23 +0300 Subject: [PATCH 1871/4321] fix possible access outside the array. if 5000 bytes are read, then at the end of the array we will write zero beyond its boundaries, damaging the stack. Here's a simple solution. if you see the need to increase the array itself, let me know. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index dafa8c862a..7498174e73 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3234,7 +3234,7 @@ static int write_object(CK_SESSION_HANDLE session) if (opt_attr_from_file) { if (!(f = fopen(opt_attr_from_file, "rb"))) util_fatal("Couldn't open file \"%s\"", opt_attr_from_file); - certdata_len = fread(certdata, 1, sizeof(certdata), f); + certdata_len = fread(certdata, 1, sizeof(certdata) - 1, f); fclose(f); if (certdata_len < 0) util_fatal("Couldn't read from file \"%s\"", opt_attr_from_file); From 98663528cf892663286b5f04c81006bd7e847423 Mon Sep 17 00:00:00 2001 From: divinehawk Date: Mon, 3 May 2021 00:24:07 -0400 Subject: [PATCH 1872/4321] pkcs15-tool: Write data objects in binary mode --- src/tools/pkcs15-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index b2f958baac..976273bc63 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -389,7 +389,7 @@ print_data_object(const char *kind, const u8*data, size_t data_len) if (opt_outfile != NULL) { FILE *outf; - outf = fopen(opt_outfile, "w"); + outf = fopen(opt_outfile, "wb"); if (outf == NULL) { fprintf(stderr, "Error opening file '%s': %s\n", opt_outfile, strerror(errno)); From 06ac408bb412230dd3d2c175642076b689ef10fc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 1 May 2021 21:18:32 +0200 Subject: [PATCH 1873/4321] travis: Invoke distcheck to make sure all needed files are packaged --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 15e765c050..1fff3488ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -252,7 +252,7 @@ script: fi; fi - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" -a -z "$DO_SIMULATION" ]; then - make check && make dist || (cat tests/*log src/tests/unittests/*log && exit 1); + make check && make distcheck || (cat tests/*log src/tests/unittests/*log && exit 1); fi - if [ ! -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then make install; From 835cee2e5a07be062405e8c96a2a6851b7734d82 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 1 May 2021 22:16:51 +0200 Subject: [PATCH 1874/4321] tests: Add correct path to enable out-of-source build --- tests/Makefile.am | 6 ++++++ tests/common.sh | 2 +- tests/test-duplicate-symbols.sh | 2 +- tests/test-manpage.sh | 4 ++-- tests/test-pkcs11-tool-allowed-mechanisms.sh | 3 ++- tests/test-pkcs11-tool-sign-verify.sh | 3 ++- tests/test-pkcs11-tool-test-threads.sh | 3 ++- tests/test-pkcs11-tool-test.sh | 3 ++- 8 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 7213bd9cf1..1d95b30c06 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,11 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +AM_TESTS_ENVIRONMENT = \ + SOURCE_PATH='$(top_srcdir)'; \ + export SOURCE_PATH; \ + BUILD_PATH='$(top_builddir)'; \ + export BUILD_PATH; + dist_noinst_SCRIPTS = common.sh \ test-manpage.sh \ test-duplicate-symbols.sh \ diff --git a/tests/common.sh b/tests/common.sh index 64f7691fa7..aa1312eb98 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -3,7 +3,7 @@ SOPIN="12345678" PIN="123456" -PKCS11_TOOL="../src/tools/pkcs11-tool" +PKCS11_TOOL="$BUILD_PATH/src/tools/pkcs11-tool" softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ /usr/lib/softhsm/libsofthsm2.so diff --git a/tests/test-duplicate-symbols.sh b/tests/test-duplicate-symbols.sh index 9e5061d903..01c2c88b55 100755 --- a/tests/test-duplicate-symbols.sh +++ b/tests/test-duplicate-symbols.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=.. +SOURCE_PATH=${SOURCE_PATH:-../} EXPORTS=`find "${SOURCE_PATH}" -name "*exports"` diff --git a/tests/test-manpage.sh b/tests/test-manpage.sh index a8d53d4ce4..eb35aee15b 100755 --- a/tests/test-manpage.sh +++ b/tests/test-manpage.sh @@ -1,5 +1,5 @@ -#!/bin/bash -SOURCE_PATH=../ +#!/bin/bash -x +SOURCE_PATH=${SOURCE_PATH:-../} # find all the manual pages in doc/tools TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|" | grep -v goid-tool` diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 0ab4768126..60351c1224 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -1,6 +1,7 @@ #!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-../} -source common.sh +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 8aff6877c9..a563841bca 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -1,6 +1,7 @@ #!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-../} -source common.sh +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index 7ec526e2b7..6b74eb36c9 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -1,6 +1,7 @@ #!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-../} -source common.sh +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index d96e866850..015a87b506 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -1,6 +1,7 @@ #!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-../} -source common.sh +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" From d0b847c6cf3a2151cfb978664b321c169c50465b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 1 May 2021 22:17:44 +0200 Subject: [PATCH 1875/4321] tests: Remove files after disclean --- src/tools/Makefile.am | 2 +- tests/test-pkcs11-tool-allowed-mechanisms.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b0e659fe11..fe67ad01b8 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -182,4 +182,4 @@ noinst_DATA = org.opensc-project.mac.pkcs11-register.plist org.opensc-project.ma $(AM_V_GEN)$(do_subst) < $< > $@ clean-local: - rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/goid-tool.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop pkcs11-register.desktop + rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo $(abs_builddir)/opensc-asn1.ggo $(abs_builddir)/goid-tool.ggo $(abs_builddir)/egk-tool.ggo org.opensc.notify.desktop pkcs11-register.desktop org.opensc-project.mac.opensc-notify.plist org.opensc-project.mac.pkcs11-register.plist diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 60351c1224..7fa819bf6a 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -48,6 +48,6 @@ echo "Cleanup" echo "=======================================================" softhsm_cleanup -rm objects.list +rm objects.list sign.log exit $ERRORS From 613b56ee5503090b8acbb99805860f47a6081bff Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 5 May 2021 09:19:44 +0200 Subject: [PATCH 1876/4321] Add correct prefix on the clang-tidy commandline --- src/common/Makefile.am | 2 +- src/libopensc/Makefile.am | 2 +- src/pkcs11/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index c549401599..83a40e1c29 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -43,4 +43,4 @@ TIDY_FILES = \ libpkcs11.c libscdl.c check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 2cee992dda..40d77e58b2 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -147,4 +147,4 @@ TIDY_FILES = \ #$(SOURCES) check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 8aeaec5857..557a52ef2d 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -87,4 +87,4 @@ TIDY_FILES = \ framework-pkcs15init.c debug.c check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi From 2f145f58047ff8f5a0eab093d7fd71d678e21c54 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 May 2021 10:26:15 +0200 Subject: [PATCH 1877/4321] Workaround for broken Ubuntu Focal images https://travis-ci.community/t/clang-10-was-recently-broken-on-linux-unmet-dependencies-for-clang-10-clang-tidy-10-valgrind/11527 --- .travis.yml | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1fff3488ee..819d0aadd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,27 +51,29 @@ env: - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" - SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) -addons: - apt_packages: - - binutils-mingw-w64-i686 - - binutils-mingw-w64-x86-64 - - docbook-xsl - - gcc-mingw-w64-i686 - - gcc-mingw-w64-x86-64 - - libpcsclite-dev - - mingw-w64 - - xsltproc - - gengetopt - - libcmocka-dev - - help2man - - pcscd - - pcsc-tools - - check - - ant - - socat - - cmake - - clang-tidy - - softhsm2 +# Commented out because of a bug in travis images for Focal: +# https://travis-ci.community/t/clang-10-was-recently-broken-on-linux-unmet-dependencies-for-clang-10-clang-tidy-10-valgrind/11527 +#addons: +# apt_packages: +# - binutils-mingw-w64-i686 +# - binutils-mingw-w64-x86-64 +# - docbook-xsl +# - gcc-mingw-w64-i686 +# - gcc-mingw-w64-x86-64 +# - libpcsclite-dev +# - mingw-w64 +# - xsltproc +# - gengetopt +# - libcmocka-dev +# - help2man +# - pcscd +# - pcsc-tools +# - check +# - ant +# - socat +# - cmake +# - clang-tidy +# - softhsm2 before_install: # homebrew is dead slow in older images due to the many updates it would need to download and build. @@ -114,6 +116,12 @@ before_install: - if [ -n "${HOST}" ]; then sudo apt-get install -y wine; fi + - if [ "$TRAVIS_DIST" == "focal" ]; then + sudo apt-get install -yq --allow-downgrades libc6=2.31-0ubuntu9.2 libc6-dev=2.31-0ubuntu9.2; + fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo -E apt-get -yq --no-install-suggests --no-install-recommends --allow-downgrades --allow-remove-essential --allow-change-held-packages install binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 docbook-xsl gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 libpcsclite-dev mingw-w64 xsltproc gengetopt libcmocka-dev help2man pcscd pcsc-tools check ant socat cmake clang-tidy softhsm2; + fi before_script: - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then From 2ea5ed8ddd7bad2b2620e73e9af93b27382e3f4b Mon Sep 17 00:00:00 2001 From: Ludovic Rousseau Date: Wed, 5 May 2021 13:53:06 +0200 Subject: [PATCH 1878/4321] Fix 'make check' when make --jobs= is used The error was: PASS: test-duplicate-symbols.sh PASS: test-pkcs11-tool-allowed-mechanisms.sh XFAIL: test-pkcs11-tool-test.sh XFAIL: test-pkcs11-tool-test-threads.sh PASS: test-manpage.sh FAIL: test-pkcs11-tool-sign-verify.sh ============================================================================ Testsuite summary for OpenSC 0.22.0-rc1 ============================================================================ ============================================================================ See tests/test-suite.log Please report to https://github.com/OpenSC/OpenSC/issues ============================================================================ This is because more than 1 test is executed at the same time. So card_cleanup() is called at the end of one test while another test is still running. The problem is easy to replicate using "make --jobs=2". --- tests/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 1d95b30c06..aa43668d58 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,6 +15,7 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-allowed-mechanisms.sh +.NOTPARALLEL: TESTS = \ test-manpage.sh \ test-duplicate-symbols.sh \ From 35a8a1d7e14aa666c6fc14643ade32dcea280379 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Fri, 7 May 2021 10:31:51 +0300 Subject: [PATCH 1879/4321] pkcs11.h: avoid C++ comments --- src/pkcs11/pkcs11.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 0ce4f242ad..c400ac743d 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -374,8 +374,10 @@ typedef unsigned long ck_key_type_t; #define CKK_EC_MONTGOMERY (0x41UL) #define CKK_VENDOR_DEFINED (1UL << 31) -// A mask for new GOST algorithms. -// For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html +/* + * A mask for new GOST algorithms. + * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html + */ #define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) #define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM From 072c64aaedc210841bee0861ff8e058bd876ad05 Mon Sep 17 00:00:00 2001 From: Georgi Kirichkov Date: Thu, 6 May 2021 17:53:06 +0300 Subject: [PATCH 1880/4321] Adds Gemalto IDPrime v4 --- src/libopensc/card-idprime.c | 14 +++++++++++--- src/libopensc/cards.h | 1 + src/libopensc/pkcs15-idprime.c | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index ba9bb8bcc5..0769cf52a3 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -206,9 +206,13 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, if (card->type == SC_CARD_TYPE_IDPRIME_V2) { /* The key reference starts from 0x11 and increments by the key id (ASCII) */ new_object.key_reference = 0x11 + key_id; - } else { /* V3 */ - /* The key reference starts from 0xF7 and increments by the key id (ASCII) */ - new_object.key_reference = 0xF7 + key_id; + } else { + if (card->type == SC_CARD_TYPE_IDPRIME_V3) { /* V3 */ + /* The key reference starts from 0xF7 and increments by the key id (ASCII) */ + new_object.key_reference = 0xF7 + key_id; + } else { /* V4 */ + new_object.key_reference = 0x56 + key_id; + } } } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d", @@ -261,6 +265,10 @@ static int idprime_init(sc_card_t *card) card->type = SC_CARD_TYPE_IDPRIME_V3; sc_log(card->ctx, "Detected IDPrime applet version 3"); break; + case 0x04: + card->type = SC_CARD_TYPE_IDPRIME_V4; + sc_log(card->ctx, "Detected IDPrime applet version 4"); + break; default: sc_log(card->ctx, "Unknown OS version received: %d", rbuf[11]); break; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 3956c971d8..f77928154b 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -269,6 +269,7 @@ enum { SC_CARD_TYPE_IDPRIME_V1, SC_CARD_TYPE_IDPRIME_V2, SC_CARD_TYPE_IDPRIME_V3, + SC_CARD_TYPE_IDPRIME_V4, SC_CARD_TYPE_IDPRIME_GENERIC, /* eDO cards */ diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 313436226e..acbae3fd14 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -98,7 +98,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.max_length = 16; pin_info.tries_left = -1; - if (card->type == SC_CARD_TYPE_IDPRIME_V3) { + if (card->type == SC_CARD_TYPE_IDPRIME_V3 || + card->type == SC_CARD_TYPE_IDPRIME_V4) { pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_NEEDS_PADDING; pin_info.attrs.pin.stored_length = 16; pin_info.attrs.pin.pad_char = 0x00; From 5ae0ef4f41fb40b312827b963abf5372229043e2 Mon Sep 17 00:00:00 2001 From: Georgi Kirichkov Date: Thu, 6 May 2021 20:28:36 +0300 Subject: [PATCH 1881/4321] Sets card->name for IDPrime v3 and v4 cards --- src/libopensc/card-idprime.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 0769cf52a3..5ea7a8f0ca 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -307,6 +307,12 @@ static int idprime_init(sc_card_t *card) case SC_CARD_TYPE_IDPRIME_V2: card->name = "Gemalto IDPrime (OSv2)"; break; + case SC_CARD_TYPE_IDPRIME_V3: + card->name = "Gemalto IDPrime (OSv3)"; + break; + case SC_CARD_TYPE_IDPRIME_V4: + card->name = "Gemalto IDPrime (OSv4)"; + break; case SC_CARD_TYPE_IDPRIME_GENERIC: default: card->name = "Gemalto IDPrime (generic)"; From ca01d2c5e2c91bc113b3fcc40c87f3825a0dde52 Mon Sep 17 00:00:00 2001 From: Georgi Kirichkov Date: Thu, 6 May 2021 20:28:49 +0300 Subject: [PATCH 1882/4321] Code style changes --- src/libopensc/card-idprime.c | 18 +++++++++--------- src/libopensc/pkcs15-idprime.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 5ea7a8f0ca..232d725fe3 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -203,16 +203,16 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, if (start[8] >= '0' && start[8] <= '9') { key_id = start[8] - '0'; } - if (card->type == SC_CARD_TYPE_IDPRIME_V2) { - /* The key reference starts from 0x11 and increments by the key id (ASCII) */ + switch (card->type) { + case SC_CARD_TYPE_IDPRIME_V2: new_object.key_reference = 0x11 + key_id; - } else { - if (card->type == SC_CARD_TYPE_IDPRIME_V3) { /* V3 */ - /* The key reference starts from 0xF7 and increments by the key id (ASCII) */ - new_object.key_reference = 0xF7 + key_id; - } else { /* V4 */ - new_object.key_reference = 0x56 + key_id; - } + break; + case SC_CARD_TYPE_IDPRIME_V3: + new_object.key_reference = 0xF7 + key_id; + break; + case SC_CARD_TYPE_IDPRIME_V4: + new_object.key_reference = 0x56 + key_id; + break; } } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d", diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index acbae3fd14..9d8eb1113f 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -99,7 +99,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) pin_info.tries_left = -1; if (card->type == SC_CARD_TYPE_IDPRIME_V3 || - card->type == SC_CARD_TYPE_IDPRIME_V4) { + card->type == SC_CARD_TYPE_IDPRIME_V4) { pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_NEEDS_PADDING; pin_info.attrs.pin.stored_length = 16; pin_info.attrs.pin.pad_char = 0x00; From 46c50dc51d03c1f56e21daef57e28cc27195d0b0 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Wed, 5 May 2021 23:49:27 +0200 Subject: [PATCH 1883/4321] CPx: add registration for Windows/minidrivers Let's OpenSC be able to support the IAS/ECC CPx cards. Suggested-by: Doug Engert Fix: issue #2321 --- win32/customactions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 80df3ee2a2..783cf24d69 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -183,6 +183,12 @@ MD_REGISTRATION minidriver_registration[] = { 15, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {TEXT("Rutoken Lite SC"), {0x3B,0x8B,0x01,0x52,0x75,0x74,0x6F,0x6B,0x65,0x6E,0x6C,0x69,0x74,0x65,0xC2}, 15, {0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + + /* from card-iasecc.c */ + {TEXT("IAS/ECC CPx"), {0x3B,0x00,0x00,0x00,0x00,0x00,0x12,0x25,0x00,0x64,0x80,0x00,0x00,0x00,0x00,0x90,0x00}, + 17, {0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF}}, + {TEXT("IAS/ECC CPxCL"), {0x3B,0X8F,0x80,0x01,0x00,0x31,0xB8,0x64,0x00,0x00,0xEC,0xC0,0x73,0x94,0x01,0x80,0x82,0x90,0x00,0x0E}, + 20, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, }; From f0c059ede81871e4d4e388d51e2b8353cfdd9182 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Fri, 7 May 2021 02:32:56 +0200 Subject: [PATCH 1884/4321] ATRMask: better describe the rule to be applied Include some notes in order to properly define the ATR values. Suggested-by: Doug Engert Fix: issue #2321 --- win32/customactions.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 783cf24d69..f2d9ad4124 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -63,6 +63,11 @@ typedef struct _MD_REGISTRATION /* note: we could have added the minidriver registration data directly in OpenSC.wxs but coding it allows for more checks. For example, do not uninstall the minidriver for a card if a middleware is already installed */ +/* + * In order to compute the proper ATRMask, see: + * https://github.com/OpenSC/OpenSC/wiki/Adding-a-new-card-driver#windows-minidriver-support + */ + MD_REGISTRATION minidriver_registration[] = { {TEXT("ePass2003"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x66,0x46,0x53,0x05,0x01,0x00,0x11,0x71,0xdf,0x00,0x00,0x03,0x6a,0x82,0xf8}, 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, From 180737d1b640bc2bf4a498b30cdc9b790ad9e7e3 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Tue, 4 May 2021 18:59:03 +0200 Subject: [PATCH 1885/4321] tests: minidriver runtime PINCODE Let's define an environment MINIDRIVER_PIN=1234 in order to be able to reuse the tests with any cards. usage: (cmd) set MINIDRIVER_PIN=1234 When the PIN code is not defined, let's skip the tests since it may runs the number of trials out of the max attempts. Moreover, some cards may have many roles, but the tests are designed for the ROLE_USER, so let's enforce only the ROLE_USER. Fix: issue #2326 --- src/tests/opensc-minidriver-test.c | 62 ++++++++++++++++++------------ 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/tests/opensc-minidriver-test.c b/src/tests/opensc-minidriver-test.c index 5e10205b07..c7a11c5a16 100644 --- a/src/tests/opensc-minidriver-test.c +++ b/src/tests/opensc-minidriver-test.c @@ -602,7 +602,12 @@ int apiTests(char *reader) unsigned char atr[36], cardid[16]; DWORD dwrc,dwlen,dwparam; BOOL flag; + char *pinEnv = getenv("MINIDRIVER_PIN"); + if (pinEnv) + printf("Running tests using PIN=%s/len=%zd\n", pinEnv, strlen(pinEnv)); + else + printf("Running tests wihtout any PIN\n"); memset(&cardData, 0, sizeof(cardData)); cardData.dwVersion = 7; cardData.pwszCardName = L"TestCard"; @@ -703,14 +708,17 @@ int apiTests(char *reader) printf("Calling CardGetProperty(CP_CARD_LIST_PINS)"); dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_LIST_PINS, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CREATE_PIN_SET(ROLE_USER)))); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (IS_PIN_SET(dwparam, ROLE_USER)))); + /* let's continue the tests only for the ROLE_USER */ + dwparam = 0; + SET_PIN(dwparam, ROLE_USER); printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); printf("Calling CardGetProperty(CP_CARD_PIN_STRENGTH_VERIFY)"); - dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_STRENGTH_VERIFY, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_STRENGTH_VERIFY, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, ROLE_USER); printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CARD_PIN_STRENGTH_PLAINTEXT))); printf("Calling CardGetProperty(CP_KEY_IMPORT_SUPPORT)"); @@ -756,36 +764,40 @@ int apiTests(char *reader) printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); printf("Calling CardAuthenticatePin(wszCARD_USER_USER)"); - dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "648219", 6, &dwparam); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 3))); + if (pinEnv) { + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, pinEnv, (DWORD)strlen(pinEnv), &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == -1))); - printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); - dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); - printf("Calling CardAuthenticatePin(wszCARD_USER_USER) - Wrong PIN"); - dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "123456", 6, &dwparam); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_W_WRONG_CHV) && (dwparam == 2))); + printf("Calling CardAuthenticatePin(wszCARD_USER_USER) - Wrong PIN"); + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "3456", 4, &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_W_WRONG_CHV) && (dwparam == 2))); - printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); - dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); - printf("Calling CardAuthenticatePin(wszCARD_USER_USER)"); - dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "648219", 6, &dwparam); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 3))); + printf("Calling CardAuthenticatePin(wszCARD_USER_USER)"); + dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, pinEnv, (DWORD)strlen(pinEnv), &dwparam); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == -1))); - printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); - dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2))); - printf("Calling CardDeAuthenticate(wszCARD_USER_USER)"); - dwrc = (*cardData.pfnCardDeauthenticate)(&cardData, wszCARD_USER_USER, 0); - printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); + printf("Calling CardDeAuthenticate(wszCARD_USER_USER)"); + dwrc = (*cardData.pfnCardDeauthenticate)(&cardData, wszCARD_USER_USER, 0); + printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS)); - printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); - dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); - printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)"); + dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0); + printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0))); + } else { + printf(" - skip: missing set MINIDRIVER_PIN=abcd\n"); + } printf("Calling CardDeleteContext()"); dwrc = (*cardData.pfnCardDeleteContext)(&cardData); From 5256bc3d3d863578182a3dcf066aad9e70f8b1dd Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Tue, 4 May 2021 19:01:52 +0200 Subject: [PATCH 1886/4321] tests: minidriver using T0 or T1 Some cards should be used with T0 and some others with T1. Let's support both. Fix: issue #2326 --- src/tests/opensc-minidriver-test.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tests/opensc-minidriver-test.c b/src/tests/opensc-minidriver-test.c index c7a11c5a16..d139b78414 100644 --- a/src/tests/opensc-minidriver-test.c +++ b/src/tests/opensc-minidriver-test.c @@ -635,8 +635,11 @@ int apiTests(char *reader) atrlen = sizeof(atr); if (SCardConnect(cardData.hSCardCtx, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &cardData.hScard, &protocol) != SCARD_S_SUCCESS) { - printf("SCardStatus() failed\n"); - exit(1); + printf("SCardStatus(T1) failed, retry with T0\n"); + if (SCardConnect(cardData.hSCardCtx, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &cardData.hScard, &protocol) != SCARD_S_SUCCESS) { + printf("SCardStatus() failed\n"); + exit(1); + } } if (SCardStatus(cardData.hScard, NULL, &readernamelen, &state, &protocol, atr, &atrlen) != SCARD_S_SUCCESS) { From 8dfafe4fc2ac11f26b6336508bf107b6242e56c1 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 15 May 2021 13:41:36 -0500 Subject: [PATCH 1887/4321] Fix 2340 pkcs15-sec.c wrong test if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) { is the correct test. --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 4fa623fff6..b86cb77c3d 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -635,7 +635,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, * key is for signing and decryption, we need to emulate signing */ sc_log(ctx, "supported algorithm flags 0x%X, private key usage 0x%X", alg_info->flags, prkey->usage); - if (obj->type == SC_ALGORITHM_RSA) { + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) { if ((alg_info->flags & SC_ALGORITHM_NEED_USAGE) && ((prkey->usage & USAGE_ANY_SIGN) && (prkey->usage & USAGE_ANY_DECIPHER)) ) { From f1bc07dec154a2677a739bed8a4dd3c793bdcddd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 12 May 2021 17:17:32 -0500 Subject: [PATCH 1888/4321] Fix piv-tool on wondows fopen needs "rb" for fopen in two places fixes #2338 On branch piv-tool-windows Changes to be committed: modified: piv-tool.c --- src/tools/piv-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 5944399f08..85d24355f8 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -118,7 +118,7 @@ static int load_object(const char * object_id, const char * object_file) int r = -1; struct stat stat_buf; - if(!object_file || (fp=fopen(object_file, "r")) == NULL){ + if(!object_file || (fp=fopen(object_file, "rb")) == NULL){ printf("Cannot open object file, %s %s\n", (object_file)?object_file:"", strerror(errno)); goto err; @@ -184,7 +184,7 @@ static int load_cert(const char * cert_id, const char * cert_file, goto err; } - if((fp=fopen(cert_file, "r"))==NULL){ + if((fp=fopen(cert_file, "rb"))==NULL){ printf("Cannot open cert file, %s %s\n", cert_file, strerror(errno)); goto err; From 48a11c06348233bf4b5a78c70912bdc2985121e5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 18 May 2021 16:09:50 -0500 Subject: [PATCH 1889/4321] Update piv-tool man pages for AES commit 295c523e4 (William Roberts 2014-07-08 13:52:48) added support for AES keys to card-piv.c but the man page for piv-tool that uses the code was never updated. On branch piv-tool-doc Changes to be committed: modified: ../../doc/tools/piv-tool.1.xml --- doc/tools/piv-tool.1.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index 70619cce90..cc38089e21 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -53,15 +53,18 @@ argument, argument - Authenticate to the card using a 2DES or 3DES key. + Authenticate to the card using a 2DES, 3DES or AES key. The argument of the form {A|M}:ref:alg is required, were A uses "EXTERNAL AUTHENTICATION" and M uses "MUTUAL AUTHENTICATION". ref is normally 9B, - and alg is 03 for 3DES. - The key is provided by the card vendor, and the environment variable - PIV_EXT_AUTH_KEY must point to a text file containing + and alg is 03 for 3DES, + 01 for 2DES, 08 for AES-128, + 0A for AES-192 or 0C for AES-256. + The key is provided by the card vendor. The environment variable + PIV_EXT_AUTH_KEY must point to either a binary file + matching the length of the key or a text file containing the key in the format: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX From f356d301b99c53d6ca4c7013f0409df5be2a9e68 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Sat, 3 Apr 2021 19:35:24 +0200 Subject: [PATCH 1890/4321] Enable ed25519/curve25519 support for Yubikey 5 --- src/libopensc/card-openpgp.c | 15 +++++++++++++++ src/libopensc/sc.c | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 18cb206190..c2bb4d7d70 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -98,6 +98,19 @@ static pgp_ec_curves_t ec_curves_openpgp[] = { {{{-1}}, 0} /* This entry must not be touched. */ }; +/* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ +static pgp_ec_curves_t ec_curves_openpgp34[] = { + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ + {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256}, /* brainpoolP256r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384}, /* brainpoolP384r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512}, /* brainpoolP512r1 */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{-1}}, 0} /* This entry must not be touched. */ +}; + struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; /* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */ @@ -455,6 +468,8 @@ pgp_init(sc_card_t *card) /* With gnuk, we use different curves */ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) { priv->ec_curves = ec_curves_gnuk; + } else if (priv->bcd_version >= OPENPGP_CARD_3_4) { + priv->ec_curves = ec_curves_openpgp34; } else { priv->ec_curves = ec_curves_openpgp; } diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 29f6b86895..29cd44e138 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -300,10 +300,10 @@ int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *o } for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) { + if ((oid1->value[i] == -1) || (oid2->value[i] == -1)) + break; if (oid1->value[i] != oid2->value[i]) return 0; - if (oid1->value[i] == -1) - break; } return 1; From 29410c170eaea11686dc21ac94b1f250e5fcf66b Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Tue, 6 Apr 2021 17:58:23 +0200 Subject: [PATCH 1891/4321] Make OpenPGP curves to be a pointer to OpenPGP 3.4 curves list --- src/libopensc/card-openpgp.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c2bb4d7d70..f54bf517ed 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -87,8 +87,11 @@ static struct sc_card_driver pgp_drv = { }; -/* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ -static pgp_ec_curves_t ec_curves_openpgp[] = { +static pgp_ec_curves_t ec_curves_openpgp34[] = { + /* OpenPGP 3.4+ Ed25519 and Curve25519 */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ @@ -98,18 +101,7 @@ static pgp_ec_curves_t ec_curves_openpgp[] = { {{{-1}}, 0} /* This entry must not be touched. */ }; -/* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ -static pgp_ec_curves_t ec_curves_openpgp34[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ - {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256}, /* brainpoolP256r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384}, /* brainpoolP384r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512}, /* brainpoolP512r1 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */ - {{{-1}}, 0} /* This entry must not be touched. */ -}; +static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; From 23dc52c90386c7a80b6f025c48046f7079cec868 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Wed, 7 Apr 2021 19:29:07 +0200 Subject: [PATCH 1892/4321] Fixed OpenPGP logic for comparing OIDs It's better to leave oid comparison as it was before, and drop trailing zero byte after it, when reading from token. --- src/libopensc/card-openpgp.c | 10 +++++++--- src/libopensc/pkcs15-openpgp.c | 10 ++++++++++ src/libopensc/sc.c | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f54bf517ed..4fb8a9958a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -613,7 +613,7 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, /* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA || SC_OPENPGP_KEYALGO_EDDSA */ key_info->algorithm = blob->data[0]; - /* last byte is only set if pubkey import is supported, empty otherwise*/ + /* last byte is set to 0xFF if pubkey import is supported */ if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ if (blob->len < 3) return SC_ERROR_INCORRECT_PARAMETERS; @@ -621,9 +621,14 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STDPUB; } else { + /* otherwise, last byte could be 00, so let's ignore it, as + * it is not part of OID */ if (blob->len < 2) return SC_ERROR_INCORRECT_PARAMETERS; - key_info->u.ec.oid_len = blob->len - 1; + if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STD) + key_info->u.ec.oid_len = blob->len - 2; + else + key_info->u.ec.oid_len = blob->len - 1; key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STD; } @@ -1635,7 +1640,6 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use * of the curveName selection to specify a curve name as defined * in [RFC 8032] */ - r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); break; case SC_OPENPGP_KEYALGO_ECDH: diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 5c1946c0d0..812b8ed829 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -309,6 +309,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA || cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) { + /* Last byte could be Import-Format of private key, let's ignore it, + * as it is not part of OID */ + if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD || + cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB) + cxdata_len--; r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid); if (r != SC_SUCCESS) { sc_log(ctx, "Failed to parse OID for elliptic curve algorithm"); @@ -429,6 +434,11 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH || cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA || cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) { + /* Last byte could be Import-Format of private key, let's ignore it, + * as it is not part of OID */ + if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD || + cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB) + cxdata_len--; r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid); if (r != SC_SUCCESS) { sc_log(ctx, "Failed to parse OID for elliptic curve algorithm"); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 29cd44e138..29f6b86895 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -300,10 +300,10 @@ int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *o } for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) { - if ((oid1->value[i] == -1) || (oid2->value[i] == -1)) - break; if (oid1->value[i] != oid2->value[i]) return 0; + if (oid1->value[i] == -1) + break; } return 1; From fc08818f6fc6d49616f0ecc335ac7c3a06c34117 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Mon, 5 Apr 2021 18:01:16 +0200 Subject: [PATCH 1893/4321] OpenPGP: Fix read/write certs with Ed25519/X25519 public key Proper Ed25519/X25519 certs have pubkey algo with OID 1.3.101.112/110, according to RFC8410. This commit add these OIDs, and also fixes pubkey parsing/creation - according to the same RFC, it's just a bytestring, without ASN.1 wrapping. Also, according to the same RFC, EDDSA/X25519 MUST not have params, even empty. --- src/libopensc/pkcs15-algo.c | 12 +++++++++--- src/libopensc/pkcs15-pubkey.c | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 6e47c0b3bf..39539b365c 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -450,11 +450,13 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #endif #ifdef SC_ALGORITHM_EDDSA /* aka Ed25519 */ - { SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL }, + /* RFC 8410, needed to parse/create X509 certs/pubkeys */ + { SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL }, #endif #ifdef SC_ALGORITHM_XEDDSA /* aka curve25519 */ - { SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, NULL, NULL, NULL }, + /* RFC 8410, needed to parse/create X509 certs/pubkeys */ + { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL }, #endif { -1, {{ -1 }}, NULL, NULL, NULL } }; @@ -552,7 +554,11 @@ sc_asn1_encode_algorithm_id(struct sc_context *ctx, u8 **buf, size_t *len, sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->oid, NULL, 1); /* no parameters, write NULL tag */ - if (!id->params || !alg_info->encode) + /* If it's EDDSA/XEDDSA, according to RFC8410, params + * MUST be absent */ + if (id->algorithm != SC_ALGORITHM_EDDSA && + id->algorithm != SC_ALGORITHM_XEDDSA && + (!id->params || !alg_info->encode)) asn1_alg_id[1].flags |= SC_ASN1_PRESENT; r = _sc_asn1_encode(ctx, asn1_alg_id, buf, len, depth + 1); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e6a9e74399..ac8fda7bf4 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -912,6 +912,14 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; break; + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: + /* For a SPKI, the pubkey is placed directly in the BIT STRING */ + pkey.value = malloc(pubkey->u.eddsa.pubkey.len); + memcpy(pkey.value, pubkey->u.eddsa.pubkey.value, pubkey->u.eddsa.pubkey.len); + // Should be pkey.len = 0 there? + key_len = pubkey->u.eddsa.pubkey.len * 8; + break; default: r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; @@ -1507,6 +1515,12 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke } memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len); pubkey->u.ec.ecpointQ.len = pk.len; + } else if (pk_alg.algorithm == SC_ALGORITHM_EDDSA || + pk_alg.algorithm == SC_ALGORITHM_XEDDSA) { + /* EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING */ + pubkey->u.eddsa.pubkey.value = malloc(pk.len); + memcpy(pubkey->u.eddsa.pubkey.value, pk.value, pk.len); + pubkey->u.eddsa.pubkey.len = pk.len; } else { /* Public key is expected to be encapsulated into BIT STRING */ r = sc_pkcs15_decode_pubkey(ctx, pubkey, pk.value, pk.len); From 0b45e78e4fd983e68f9073944d8a2bd82d84a3bb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 17 May 2021 16:20:49 +0200 Subject: [PATCH 1894/4321] idprime: Fix RSA-PKCS mechanism with hashing on card --- src/libopensc/card-idprime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 232d725fe3..68d963ec06 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -664,11 +664,11 @@ idprime_set_security_env(struct sc_card *card, new_env.algorithm_ref = 0x65; } } else { /* RSA-PKCS */ - if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA256) { + if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) { new_env.algorithm_ref = 0x42; - } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA384) { + } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) { new_env.algorithm_ref = 0x52; - } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) { + } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) { new_env.algorithm_ref = 0x62; } else { /* RSA-PKCS without hashing */ new_env.algorithm_ref = 0x02; From e4cf0e7b39093de24e832a6d04b8d62d209c3901 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 4 May 2021 13:46:20 +0200 Subject: [PATCH 1895/4321] Basic unit test for secure messaging functions --- src/tests/unittests/Makefile.am | 8 ++++ src/tests/unittests/sm.c | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/tests/unittests/sm.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index b6bef2989f..8708e464b8 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -32,6 +32,14 @@ compression_SOURCES = compression.c compression_LDADD = $(LDADD) $(OPTIONAL_ZLIB_LIBS) endif +if ENABLE_OPENSSL +noinst_PROGRAMS += sm +TESTS += sm + +sm_SOURCES = sm.c +sm_LDADD = $(top_builddir)/src/sm/libsm.la $(LDADD) +endif + endif diff --git a/src/tests/unittests/sm.c b/src/tests/unittests/sm.c new file mode 100644 index 0000000000..75cce97dd4 --- /dev/null +++ b/src/tests/unittests/sm.c @@ -0,0 +1,69 @@ +/* + * sm.c: Unit tests for Secure Messaging + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "torture.h" +#include "libopensc/log.c" +#include "sm/sm-common.h" + +static void torture_sm_incr_ssc(void **state) +{ + unsigned char in[] = {0x00, 0x00}; + + (void)state; + + /* just make sure it does not crash */ + sm_incr_ssc(NULL, 0); + + /* zero-length input should not underflow the buffer */ + sm_incr_ssc(in, 0); + + /* shortest possible input */ + in[0] = 0x42; + sm_incr_ssc(in, 1); + assert_int_equal(in[0], 0x43); + + /* overflow to the second byte */ + in[0] = 0x00; + in[1] = 0xff; + sm_incr_ssc(in, 2); + assert_int_equal(in[0], 0x01); + assert_int_equal(in[1], 0x00); + + /* overflow */ + in[0] = 0xff; + in[1] = 0xff; + sm_incr_ssc(in, 2); + assert_int_equal(in[0], 0x00); + assert_int_equal(in[1], 0x00); +} + + +int main(void) +{ + int rc; + struct CMUnitTest tests[] = { + /* sm_incr_ssc */ + cmocka_unit_test(torture_sm_incr_ssc), + }; + + rc = cmocka_run_group_tests(tests, NULL, NULL); + return rc; +} From 12be677cb869bd1ae11180224fded86dd3686f1d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 5 May 2021 14:27:05 +0200 Subject: [PATCH 1896/4321] Drop duplicate -Werror build flag (already used unless --disable-strict) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 62afc6e27d..d88d71812d 100644 --- a/configure.ac +++ b/configure.ac @@ -133,7 +133,7 @@ esac AX_CODE_COVERAGE() -AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror]) +AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"]) AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"]) AC_ARG_ENABLE( From 07f5e63abf1c9e446f9df6c86830cbdefcc7ae3f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 May 2021 10:53:14 +0200 Subject: [PATCH 1897/4321] tests: verify secure messaging functions work as expected --- src/tests/unittests/Makefile.am | 1 - src/tests/unittests/sm.c | 189 ++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 8708e464b8..03019c324d 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -41,5 +41,4 @@ sm_LDADD = $(top_builddir)/src/sm/libsm.la $(LDADD) endif - endif diff --git a/src/tests/unittests/sm.c b/src/tests/unittests/sm.c index 75cce97dd4..d39d13c9cc 100644 --- a/src/tests/unittests/sm.c +++ b/src/tests/unittests/sm.c @@ -23,6 +23,33 @@ #include "libopensc/log.c" #include "sm/sm-common.h" +/* Setup context */ +static int setup_sc_context(void **state) +{ + sc_context_t *ctx = NULL; + int rv; + + rv = sc_establish_context(&ctx, "sm"); + assert_non_null(ctx); + assert_int_equal(rv, SC_SUCCESS); + + *state = ctx; + + return 0; +} + +/* Cleanup context */ +static int teardown_sc_context(void **state) +{ + sc_context_t *ctx = *state; + int rv; + + rv = sc_release_context(ctx); + assert_int_equal(rv, SC_SUCCESS); + + return 0; +} + static void torture_sm_incr_ssc(void **state) { unsigned char in[] = {0x00, 0x00}; @@ -55,6 +82,158 @@ static void torture_sm_incr_ssc(void **state) assert_int_equal(in[1], 0x00); } +static void torture_sm_crypt_des_cbc3(void **state) +{ + sc_context_t *ctx = *state; + /* Test vector from + * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf + * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode + */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_crypt_des_cbc3_multiblock(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + sc_context_t *ctx = *state; + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0xAF, 0xA0, 0x77, 0x1d, 0x35, 0xE1, 0xCC, 0x26}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_crypt_des_cbc3_force_pad(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + sc_context_t *ctx = *state; + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0xC6, 0xD3, 0xE1, 0x4F, 0xFB, 0xDE, 0xDF, 0xF9}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 0); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_encrypt_des_ecb3(void **state) +{ + /* Test vector from + * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf + * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode + */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00}; + unsigned char *out = NULL; /* allocates */ + int out_len = 0; + int rv; + + (void)state; + + rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_encrypt_des_ecb3_multiblock(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0x18, 0x0d, 0x91, 0xdf, 0xa1, 0x25, 0x2f, 0x81}; + unsigned char *out = NULL; /* allocates */ + int out_len = 0; + int rv; + + (void)state; + + rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} int main(void) { @@ -62,6 +241,16 @@ int main(void) struct CMUnitTest tests[] = { /* sm_incr_ssc */ cmocka_unit_test(torture_sm_incr_ssc), + /* sm_encrypt_des_cbc3 and sm_decrypt_des_cbc3 */ + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_multiblock, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_force_pad, + setup_sc_context, teardown_sc_context), + /* sm_encrypt_des_ecb3 */ + cmocka_unit_test(torture_sm_encrypt_des_ecb3), + cmocka_unit_test(torture_sm_encrypt_des_ecb3_multiblock), }; rc = cmocka_run_group_tests(tests, NULL, NULL); From 1b92501ef98f5bb785aa090163945e7a090bebf0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 May 2021 10:53:56 +0200 Subject: [PATCH 1898/4321] sm: Rewrite to use non-deprecated OpenSSL 3.0 API --- src/sm/sm-common.c | 227 ++++++++++++++++++++++++++++++++--- src/sm/sm-common.h | 4 +- src/smm/sm-cwa14890.c | 8 +- src/smm/sm-global-platform.c | 17 +-- src/tests/unittests/sm.c | 122 ++++++++++++++++++- 5 files changed, 338 insertions(+), 40 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index ecd6ef1297..d47228d879 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -40,6 +40,7 @@ #error "Need OpenSSL" #endif +#include #include #include @@ -49,6 +50,7 @@ #include "sm-common.h" +#if OPENSSL_VERSION_NUMBER < 0x30000000L /* * From crypto/des/des_locl.h of OpenSSL . */ @@ -120,18 +122,34 @@ DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, } memcpy(*iv,icv_out,sizeof(DES_cblock)); } +#else +#include + +/* The single-DES algorithm is not available in the default provider anymore + * so we need to load the legacy provider. This is not done on the application + * start, but only as needed */ +OSSL_PROVIDER *legacy_provider = NULL; +#endif DES_LONG DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, - long length, DES_key_schedule *schedule, DES_key_schedule *schedule2, + long length, unsigned char *key, const_DES_cblock *ivec) { - register DES_LONG tout0,tout1,tin0,tin1; register long l=length; - DES_LONG tin[2]; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + register DES_LONG tout0,tout1,tin0,tin1; + DES_LONG tin[2]; + DES_cblock kk, k2; + DES_key_schedule ks,ks2; + + memcpy(&kk, key, 8); + memcpy(&k2, key + 8, 8); + DES_set_key_unchecked(&kk,&ks); + DES_set_key_unchecked(&k2,&ks2); c2l(iv,tout0); c2l(iv,tout1); @@ -147,7 +165,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt1((DES_LONG *)tin,schedule, DES_ENCRYPT); + DES_encrypt1((DES_LONG *)tin, &ks, DES_ENCRYPT); tout0=tin[0]; tout1=tin[1]; } @@ -161,9 +179,8 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt3((DES_LONG *)tin,schedule,schedule2,schedule); + DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks); tout1=tin[1]; - if (out != NULL) { l2c(tout0,out); @@ -179,22 +196,87 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, | ((tout1 << 8L) & 0x00FF0000) | ((tout1 << 24L) & 0xFF000000); return(tout1); +#else + EVP_CIPHER_CTX *cctx = NULL; + unsigned char outv[8], tmpout[4]; + int tmplen; + + /* Prepare IV */ + memcpy(outv, iv, sizeof outv); + + cctx = EVP_CIPHER_CTX_new(); + if (l > 8) { + if (legacy_provider == NULL) { + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + } + if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + EVP_CIPHER_CTX_set_padding(cctx, 0); + for (; l > 8; l -= 8, in += 8) { + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + } + + /* We need to return first 4 bytes from here */ + memcpy(tmpout, outv, 4); + if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, outv, NULL)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + EVP_CIPHER_CTX_set_padding(cctx, 0); + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, l)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + if (out != NULL) { + memcpy(out, tmpout, 4); + memcpy(out+4, outv+4, 4); + } + EVP_CIPHER_CTX_free(cctx); + return ((outv[7] << 0L) & 0x000000FF) | + ((outv[6] << 8L) & 0x0000FF00) | + ((outv[5] << 16L) & 0x00FF0000) | + ((outv[4] << 24L) & 0xFF000000); +#endif } DES_LONG DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, - long length, DES_key_schedule *schedule, DES_key_schedule *schedule2, + long length, unsigned char *key, const_DES_cblock *ivec) { - register DES_LONG tout0,tout1,tin0,tin1; register long l=length; - DES_LONG tin[2]; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + register DES_LONG tout0,tout1,tin0,tin1; + DES_LONG tin[2]; + DES_cblock kk, k2; + DES_key_schedule ks,ks2; - c2l(iv,tout0); - c2l(iv,tout1); + memcpy(&kk, key, 8); + memcpy(&k2, key + 8, 8); + DES_set_key_unchecked(&kk,&ks); + DES_set_key_unchecked(&k2,&ks2); + + c2l(iv, tout0); + c2l(iv, tout1); for (; l>0; l-=8) { @@ -208,7 +290,7 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt3((DES_LONG *)tin,schedule,schedule2,schedule); + DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks); /* fix 15/10/91 eay - thanks to keithr@sco.COM */ tout0=tin[0]; tout1=tin[1]; @@ -228,6 +310,40 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, | ((tout1 << 8L) & 0x00FF0000) | ((tout1 << 24L) & 0xFF000000); return(tout1); +#else + EVP_CIPHER_CTX *cctx = NULL; + unsigned char outv[8]; + int tmplen; + + /* Prepare IV */ + memcpy(outv, iv, sizeof outv); + + cctx = EVP_CIPHER_CTX_new(); + if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, iv, NULL)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + EVP_CIPHER_CTX_set_padding(cctx, 0); + for (; l > 0; l -= 8, in += 8) { + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + if (out != NULL) { + memcpy(out, outv, sizeof outv); + } + EVP_CIPHER_CTX_free(cctx); + return ((outv[7] << 0L) & 0x000000FF) | + ((outv[6] << 8L) & 0x0000FF00) | + ((outv[5] << 16L) & 0x00FF0000) | + ((outv[4] << 24L) & 0xFF000000); +#endif } @@ -235,9 +351,14 @@ int sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, unsigned char **out, int *out_len) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L int ii; DES_cblock kk,k2; DES_key_schedule ks,ks2; +#else + EVP_CIPHER_CTX *cctx = NULL; + int tmplen; +#endif if (!out || !out_len) @@ -251,6 +372,7 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, if (!(*out)) return -1; +#if OPENSSL_VERSION_NUMBER < 0x30000000L memcpy(&kk, key, 8); memcpy(&k2, key + 8, 8); @@ -260,6 +382,27 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, for (ii=0; ii Date: Thu, 6 May 2021 10:56:04 +0200 Subject: [PATCH 1899/4321] Do not use deprecated ERR_load_ERR_strings() with OpenSSL 3.0 --- src/libopensc/pkcs15-prkey.c | 2 ++ src/pkcs15init/pkcs15-oberthur-awp.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 772179cd42..c7d2d0112c 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -527,7 +527,9 @@ sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15 key_info = (struct sc_pkcs15_prkey_info *) key_object->data; +#if OPENSSL_VERSION_NUMBER < 0x30000000L ERR_load_ERR_strings(); +#endif ERR_load_crypto_strings(); sc_log(ctx, "CertValue(%"SC_FORMAT_LEN_SIZE_T"u) %p", diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index b9991e783f..70ff580d0e 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -769,7 +769,9 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj int r = 0; LOG_FUNC_CALLED(ctx); +#if OPENSSL_VERSION_NUMBER < 0x30000000L ERR_load_ERR_strings(); +#endif ERR_load_crypto_strings(); key_info = (struct sc_pkcs15_prkey_info *)obj->data; @@ -827,7 +829,9 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj sc_log(ctx, "cosm_encode_key_info() label:%s",ki->label.value); done: +#if OPENSSL_VERSION_NUMBER < 0x30000000L ERR_load_ERR_strings(); +#endif ERR_load_crypto_strings(); LOG_FUNC_RETURN(ctx, r); } @@ -933,7 +937,9 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob LOG_FUNC_CALLED(ctx); +#if OPENSSL_VERSION_NUMBER < 0x30000000L ERR_load_ERR_strings(); +#endif ERR_load_crypto_strings(); if (!obj || !ci) From a69ab7c70c2cf753d0a3c609eb1b0288effcf72f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 May 2021 10:56:45 +0200 Subject: [PATCH 1900/4321] tests: Fix context for the asn1 test --- src/tests/unittests/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/unittests/asn1.c b/src/tests/unittests/asn1.c index 5f5d4ea3d6..799722ccaa 100644 --- a/src/tests/unittests/asn1.c +++ b/src/tests/unittests/asn1.c @@ -241,7 +241,7 @@ static int setup_sc_context(void **state) sc_context_t *ctx = NULL; int rv; - rv = sc_establish_context(&ctx, "fuzz"); + rv = sc_establish_context(&ctx, "asn1"); assert_non_null(ctx); assert_int_equal(rv, SC_SUCCESS); From a8a4bddfada6d8253046a2912f224a25f61ef7df Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 May 2021 16:58:11 +0200 Subject: [PATCH 1901/4321] p11test: Debug level from commandline This replaces the debug level defined at build time with -NDEBUG, which turned out to be quite confusing. Fixes #2304 --- src/tests/p11test/Makefile.am | 2 +- src/tests/p11test/p11test.c | 6 +++++- src/tests/p11test/p11test_case_readonly.c | 6 ------ src/tests/p11test/p11test_common.h | 13 +++++++------ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index f7cc67e33b..abc2d5a1ae 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -31,7 +31,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_pss_oaep.c \ p11test_case_interface.c \ p11test_helpers.c -p11test_CFLAGS = -DNDEBUG $(CMOCKA_CFLAGS) +p11test_CFLAGS = $(CMOCKA_CFLAGS) p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) if WIN32 diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 457a7b6340..dbac167d23 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -37,6 +37,7 @@ /* Global variable keeping information about token we are using */ token_info_t token; +int debug_flag = 0; void display_usage() { fprintf(stdout, @@ -98,7 +99,7 @@ int main(int argc, char** argv) { token.slot_id = (unsigned long) -1; token.log.outfile = NULL; - while ((command = getopt(argc, argv, "?hm:s:p:io:")) != -1) { + while ((command = getopt(argc, argv, "?hm:s:p:io:v")) != -1) { switch (command) { case 'o': token.log.outfile = strdup(optarg); @@ -120,6 +121,9 @@ int main(int argc, char** argv) { case '?': display_usage(); return 0; + case 'v': + debug_flag = 1; + break; default: break; } diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index df39ecb4f1..60ad04078f 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -498,9 +498,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_FUNCTION_LIST_PTR fp = info->function_pointer; CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; static int verify_support = 1; -#ifndef NDEBUG char *name; -#endif if (!verify_support) goto openssl_verify; @@ -531,15 +529,11 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, /* Final */ rv = fp->C_VerifyFinal(info->session_handle, sign, sign_length); -#ifndef NDEBUG name = "C_VerifyFinal"; -#endif } else { rv = fp->C_Verify(info->session_handle, message, message_length, sign, sign_length); -#ifndef NDEBUG name = "C_Verify"; -#endif } if (rv == CKR_OK) { mech->result_flags |= FLAGS_SIGN; diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index 1122e8e3da..d3eb104062 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -33,12 +33,12 @@ #define MAX_MECHS 200 -#ifndef NDEBUG - #define debug_print(fmt, ...) \ - { fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0) -#else - #define debug_print(fmt, ...) -#endif +#define debug_print(fmt, ...) \ + do { \ + if (debug_flag) { \ + fprintf(stderr, fmt "\n", ##__VA_ARGS__); \ + } \ + } while (0) #define FLAGS_SIGN 0x01 #define FLAGS_SIGN_OPENSSL 0x02 @@ -89,6 +89,7 @@ typedef struct { } token_info_t; extern token_info_t token; +extern int debug_flag; #endif /* P11TEST_COMMON_H */ From 8e4134841da57b1d49b796c36a21c519f5e3ac11 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 May 2021 17:16:46 +0200 Subject: [PATCH 1902/4321] p11test: Add new mechanisms from softhsm --- src/tests/p11test/p11test_case_common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 639e07e566..4da0382cb6 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -780,8 +780,12 @@ const char *get_mechanism_name(int mech_id) return "ECDH1_COFACTOR_DERIVE"; case CKM_EC_KEY_PAIR_GEN: return "EC_KEY_PAIR_GEN"; + case CKM_EC_EDWARDS_KEY_PAIR_GEN: + return "EC_EDWARDS_KEY_PAIR_GEN"; case CKM_RSA_PKCS_KEY_PAIR_GEN: return "RSA_PKCS_KEY_PAIR_GEN"; + case CKM_GENERIC_SECRET_KEY_GEN: + return "GENERIC_SECRET_KEY_GEN"; case CKM_MD5_RSA_PKCS: return "MD5_RSA_PKCS"; case CKM_RIPEMD160_RSA_PKCS: @@ -802,6 +806,8 @@ const char *get_mechanism_name(int mech_id) return "MD5_HMAC"; case CKM_SHA_1_HMAC: return "SHA_1_HMAC"; + case CKM_SHA224_HMAC: + return "SHA224_HMAC"; case CKM_SHA256_HMAC: return "SHA256_HMAC"; case CKM_SHA384_HMAC: From 33426df3ff28f6944ebedf6ac7ae5aaa2feb396a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 May 2021 14:50:00 +0200 Subject: [PATCH 1903/4321] p11test: Do not return on warnings for (X)EDDSA keys --- src/tests/p11test/p11test_case_common.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 4da0382cb6..695ae2ea61 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -447,7 +447,6 @@ int callback_public_keys(test_certs_t *objects, if (strcmp((char *)curve->data, "edwards25519")) { debug_print(" [WARN %s ] Unknown curve name. " " expected edwards25519, got %s", o->id_str, curve->data); - return -1; } evp_type = EVP_PKEY_ED25519; break; @@ -455,7 +454,6 @@ int callback_public_keys(test_certs_t *objects, if (strcmp((char *)curve->data, "curve25519")) { debug_print(" [WARN %s ] Unknown curve name. " " expected curve25519, got %s", o->id_str, curve->data); - return -1; } evp_type = EVP_PKEY_X25519; break; @@ -466,12 +464,13 @@ int callback_public_keys(test_certs_t *objects, ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)template[6].ulValueLen) != NULL) { int nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + switch (o->key_type) { case CKK_EC_EDWARDS: if (nid != NID_ED25519) { debug_print(" [WARN %s ] Unknown OID. " " expected NID_ED25519 (%d), got %d", o->id_str, NID_ED25519, nid); - return -1; } evp_type = EVP_PKEY_ED25519; break; @@ -479,7 +478,6 @@ int callback_public_keys(test_certs_t *objects, if (nid != NID_X25519) { debug_print(" [WARN %s ] Unknown OID. " " expected NID_X25519 (%d), got %d", o->id_str, NID_X25519, nid); - return -1; } evp_type = EVP_PKEY_X25519; break; @@ -487,7 +485,6 @@ int callback_public_keys(test_certs_t *objects, debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type); return -1; } - ASN1_OBJECT_free(obj); } else { debug_print(" [WARN %s ] Failed to convert EC_PARAMS" " to curve name or object id", o->id_str); From 465375bda2a1cec5adaeefabce42627cf5a8847b Mon Sep 17 00:00:00 2001 From: Jaime Hablutzel Date: Fri, 21 May 2021 12:28:04 -0500 Subject: [PATCH 1904/4321] Fixing command-line option names in error messages --- src/tools/pkcs11-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7498174e73..498018c8e2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -866,14 +866,14 @@ int main(int argc, char * argv[]) break; case OPT_SLOT_DESCRIPTION: if (opt_slot_set) { - fprintf(stderr, "Error: Only one of --slot, --slot-label, --slot-index or --token-label can be used\n"); + fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n"); util_print_usage_and_die(app_name, options, option_help, NULL); } opt_slot_description = optarg; break; case OPT_SLOT_INDEX: if (opt_slot_set || opt_slot_description) { - fprintf(stderr, "Error: Only one of --slot, --slot-label, --slot-index or --token-label can be used\n"); + fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n"); util_print_usage_and_die(app_name, options, option_help, NULL); } opt_slot_index = (CK_ULONG) strtoul(optarg, NULL, 0); @@ -885,7 +885,7 @@ int main(int argc, char * argv[]) break; case OPT_TOKEN_LABEL: if (opt_slot_set || opt_slot_description || opt_slot_index_set) { - fprintf(stderr, "Error: Only one of --slot, --slot-label, --slot-index or --token-label can be used\n"); + fprintf(stderr, "Error: Only one of --slot, --slot-description, --slot-index or --token-label can be used\n"); util_print_usage_and_die(app_name, options, option_help, NULL); } opt_token_label = optarg; @@ -1133,7 +1133,7 @@ int main(int argc, char * argv[]) fprintf(stderr, "Using slot with index %lu (0x%lx)\n", opt_slot_index, opt_slot); } else { fprintf(stderr, "Slot with index %lu (counting from 0) is not available.\n", opt_slot_index); - fprintf(stderr, "You must specify a valid slot with either --slot, --slot-index or --slot-label.\n"); + fprintf(stderr, "You must specify a valid slot with either --slot, --slot-description, --slot-index or --token-label.\n"); err = 1; goto end; } From ffd6e2a57673785716164e25787efcd7275b9e0b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 May 2021 11:13:20 +0200 Subject: [PATCH 1905/4321] p11test: Expect DERIVE to be set on both private and public key Basically reverts part of 485b6cf, which turned out to be wrong. Alternative to #2292 --- src/tests/p11test/p11test_case_usage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index b7df79aa13..4441027973 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -54,9 +54,9 @@ void usage_test(void **state) { fprintf(stderr, " [ ERROR %s ] If Unwrap is set, Wrap should be set too.\n", objects.data[i].id_str); } - if (objects.data[i].derive_pub) { + if (objects.data[i].derive_pub != objects.data[i].derive_priv) { errors++; - fprintf(stderr, " [ ERROR %s ] Derive should not be set on public key\n", + fprintf(stderr, " [ ERROR %s ] Derive should be set on both private and public part.\n", objects.data[i].id_str); } From fc2fecc80e845329fabc43044a1596c404cfe747 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 May 2021 11:24:51 +0200 Subject: [PATCH 1906/4321] Use const types for RSA and EC_KEY These are anyway not supposed to be modified even in older versions of openssl. Visible when building with -Wno-deprecated-declarations --- src/libopensc/cwa14890.c | 18 +++++++++--------- src/libopensc/p15card-helper.c | 2 +- src/libopensc/sc-ossl-compat.h | 1 + src/pkcs11/openssl.c | 2 +- src/tests/p11test/p11test_case_common.c | 7 ++++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index da471abf88..88f68b85e2 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -519,8 +519,8 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da * @return SC_SUCCESS if ok; else errorcode */ static int cwa_prepare_external_auth(sc_card_t * card, - RSA * icc_pubkey, - RSA * ifd_privkey, + const RSA * icc_pubkey, + const RSA * ifd_privkey, u8 * sig, size_t sig_len) { @@ -594,7 +594,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, buf3[127] = 0xBC; /* iso padding */ /* encrypt with ifd private key */ - len2 = RSA_private_decrypt(128, buf3, buf2, ifd_privkey, RSA_NO_PADDING); + len2 = RSA_private_decrypt(128, buf3, buf2, (RSA *)ifd_privkey, RSA_NO_PADDING); if (len2 < 0) { msg = "Prepare external auth: ifd_privk encrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; @@ -630,7 +630,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, } /* re-encrypt result with icc public key */ - len1 = RSA_public_encrypt(len3, buf3, buf1, icc_pubkey, RSA_NO_PADDING); + len1 = RSA_public_encrypt(len3, buf3, buf1, (RSA *)icc_pubkey, RSA_NO_PADDING); if (len1 <= 0 || (size_t) len1 != sig_len) { msg = "Prepare external auth: icc_pubk encrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; @@ -842,8 +842,8 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data) * @return SC_SUCCESS if ok; else error code */ static int cwa_verify_internal_auth(sc_card_t * card, - RSA * icc_pubkey, - RSA * ifd_privkey, + const RSA * icc_pubkey, + const RSA * ifd_privkey, u8 * ifdbuf, size_t ifdlen, u8 * sig, @@ -901,7 +901,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, */ /* decrypt data with our ifd priv key */ - len1 = RSA_private_decrypt(sig_len, sig, buf1, ifd_privkey, RSA_NO_PADDING); + len1 = RSA_private_decrypt(sig_len, sig, buf1, (RSA *)ifd_privkey, RSA_NO_PADDING); if (len1 <= 0) { msg = "Verify Signature: decrypt with ifd privk failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; @@ -911,7 +911,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, /* OK: now we have SIGMIN in buf1 */ /* check if SIGMIN data matches SIG or N.ICC-SIG */ /* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */ - len3 = RSA_public_encrypt(len1, buf1, buf3, icc_pubkey, RSA_NO_PADDING); + len3 = RSA_public_encrypt(len1, buf1, buf3, (RSA *) icc_pubkey, RSA_NO_PADDING); if (len3 <= 0) goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */ res = cwa_compare_signature(buf3, len3, ifdbuf); @@ -945,7 +945,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, } /* ok: check again with new data */ /* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */ - len3 = RSA_public_encrypt(len2, buf2, buf3, icc_pubkey, RSA_NO_PADDING); + len3 = RSA_public_encrypt(len2, buf2, buf3, (RSA *)icc_pubkey, RSA_NO_PADDING); if (len3 <= 0) { msg = "Verify Signature: cannot get valid SIG data"; res = SC_ERROR_INVALID_DATA; diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c index e641858deb..bf0ff90119 100644 --- a/src/libopensc/p15card-helper.c +++ b/src/libopensc/p15card-helper.c @@ -143,7 +143,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { int r; X509 *cert_data = NULL; EVP_PKEY *pkey = NULL; - RSA * rsa = NULL; + const RSA * rsa = NULL; int certtype = 0; int modulus_len = 0; const prdata* key = get_prkey_by_cert(items, cert); diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 339ad96ce7..ba4a0c511e 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -273,6 +273,7 @@ static sc_ossl_inline void CRYPTO_secure_malloc_done() #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 92fed189b9..4c521e081a 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -522,7 +522,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len size_t signat_len_tmp; unsigned char *signat_tmp = NULL; EVP_PKEY_CTX *ctx; - EC_KEY *eckey; + const EC_KEY *eckey; int r; sc_log(context, "Trying to verify using EVP"); diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 695ae2ea61..295a8e23a7 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -20,6 +20,7 @@ */ #include "p11test_case_common.h" +#include "../../libopensc/sc-ossl-compat.h" char name_buffer[11]; char flag_buffer[11]; @@ -208,8 +209,8 @@ int callback_certificates(test_certs_t *objects, if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { /* Extract public RSA key */ - RSA *rsa = EVP_PKEY_get0_RSA(evp); - if ((o->key.rsa = RSAPublicKey_dup(rsa)) == NULL) { + const RSA *rsa = EVP_PKEY_get0_RSA(evp); + if ((o->key.rsa = RSAPublicKey_dup((RSA *)rsa)) == NULL) { fail_msg("RSAPublicKey_dup failed"); return -1; } @@ -218,7 +219,7 @@ int callback_certificates(test_certs_t *objects, } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { /* Extract public EC key */ - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp); + const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp); if ((o->key.ec = EC_KEY_dup(ec)) == NULL) { fail_msg("EC_KEY_dup failed"); return -1; From 9d1a2143405eeb5f55da7090f97f3b48ad328e45 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Jun 2021 14:55:11 +0200 Subject: [PATCH 1907/4321] pkcs11: Undefine internal typedef and remove its usage --- src/pkcs11/pkcs11-global.c | 2 +- src/pkcs11/pkcs11-spy.c | 2 +- src/pkcs11/pkcs11.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 98b61a2041..3b42070fbe 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -810,7 +810,7 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */ */ #define NUM_INTERFACES 2 #define DEFAULT_INTERFACE 0 -ck_interface interfaces[NUM_INTERFACES] = { +CK_INTERFACE interfaces[NUM_INTERFACES] = { {"PKCS 11", (void *)&pkcs11_function_list_3_0, 0}, {"PKCS 11", (void *)&pkcs11_function_list, 0} }; diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index c03418b313..b924bd74c3 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -176,7 +176,7 @@ allocate_function_list(int v3) /* The compatibility interfaces that can be returned from Interface functions * if the V3 API is used, but the proxied module does not support V3 API */ #define NUM_INTERFACES 1 -ck_interface compat_interfaces[NUM_INTERFACES] = { +CK_INTERFACE compat_interfaces[NUM_INTERFACES] = { {"PKCS 11", NULL, 0} }; diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index c400ac743d..68cac91c83 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -1786,6 +1786,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_rv_t #undef ck_notify_t +#undef ck_interface + #undef ck_function_list #undef ck_function_list_3_0 From 9be6dc66067cfa5c1ed4e74d32c70af52d8bea29 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Jun 2021 14:55:49 +0200 Subject: [PATCH 1908/4321] pkcs11: Update the version to 3.0 (unused anywhere though) --- src/pkcs11/pkcs11.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 68cac91c83..85aa98e0e4 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -63,9 +63,9 @@ extern "C" { version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 20 -#define CRYPTOKI_VERSION_REVISION 6 +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 0 +#define CRYPTOKI_VERSION_REVISION 0 /* Compatibility interface is default, unless CRYPTOKI_GNU is From 151583ce267e937e912b866045e6ed068bb2a09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= Date: Sat, 5 Dec 2020 16:21:15 +0100 Subject: [PATCH 1909/4321] C_Initialize() must copy CK_C_INITIALIZE_ARGS C_Initialize() must make a copy of the function pointers supplied via pInitArgs, as the PKCS#11 specification makes no guarantee that the pInitArgs pointer is allowed to be dereferenced after C_Initialize() returns. Fixes issue #2170. --- src/pkcs11/pkcs11-global.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 98b61a2041..b3528aaacd 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -156,6 +156,8 @@ static CK_C_INITIALIZE_ARGS _def_locks = { #endif /* PKCS11_THREAD_LOCKING */ static CK_C_INITIALIZE_ARGS_PTR global_locking; +static CK_C_INITIALIZE_ARGS app_locking = { + NULL, NULL, NULL, NULL, 0, NULL }; static void *global_lock = NULL; #ifdef HAVE_OS_LOCKING static CK_C_INITIALIZE_ARGS_PTR default_mutex_funcs = &_def_locks; @@ -914,6 +916,8 @@ sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR args) if (args->pReserved != NULL_PTR) return CKR_ARGUMENTS_BAD; + app_locking = *args; + /* If the app tells us OS locking is okay, * use that. Otherwise use the supplied functions. */ @@ -929,13 +933,13 @@ sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR args) /* Based on PKCS#11 v2.11 11.4 */ if (applock && oslock) { /* Shall be used in threaded environment, prefer app provided locking */ - global_locking = args; + global_locking = &app_locking; } else if (!applock && oslock) { /* Shall be used in threaded environment, must use operating system locking */ global_locking = default_mutex_funcs; } else if (applock && !oslock) { /* Shall be used in threaded environment, must use app provided locking */ - global_locking = args; + global_locking = &app_locking; } else if (!applock && !oslock) { /* Shall not be used in threaded environment, use operating system locking */ global_locking = default_mutex_funcs; From aebebac432341f33d95f805ca2708fca1636e5fc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 11 Jun 2021 05:28:07 -0500 Subject: [PATCH 1910/4321] p11test: Use OPTIONAL_OPENSSL_CFLAGS Needed if building with OpenSSL in non stanard location. Changes to be committed: modified: src/tests/p11test/Makefile.am --- src/tests/p11test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index abc2d5a1ae..010d710b0c 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -31,7 +31,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_pss_oaep.c \ p11test_case_interface.c \ p11test_helpers.c -p11test_CFLAGS = $(CMOCKA_CFLAGS) +p11test_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(CMOCKA_CFLAGS) p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) if WIN32 From 2f94a6b155ea4d657546a824446794611cf58d94 Mon Sep 17 00:00:00 2001 From: Alessio Di Mauro Date: Wed, 23 Jun 2021 15:29:29 +0200 Subject: [PATCH 1911/4321] pkcs11-tool: allow setting CKA_EXTRACTABLE during keypair generation Section 4.9 of the PKCS#11 v2.40 specification [1], mentions CKA_EXTRACTABLE as a valid attribute for Private Key objects. However, when calling "pkcs11-tool" with the "--exportable" option, the attribute is not set as part of the private key template. [1]: http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/os/pkcs11-base-v2.40-errata01-os-complete.html --- src/tools/pkcs11-tool.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 498018c8e2..ffd3666c5d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2745,6 +2745,12 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } + if (opt_is_extractable != 0) { + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_EXTRACTABLE, + &_true, sizeof(_true)); + n_privkey_attr++; + } + if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, From fd6b64b91b5395022040d5d2699ecab2ceb9397a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 25 Jun 2021 23:27:16 +0200 Subject: [PATCH 1912/4321] Update NEWS with recently merged changes --- NEWS | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index bdb84b8bbf..f906687ca9 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.22.0; 2021-04-XX +# New in 0.22.0; 2021-06-XX ## General improvements * Use standard paths for file cache on Linux (#2148) and OSX (#2214) * Various issues of memory/buffer handling in legacy drivers mostly reported by oss-fuzz and coverity (tcos, oberthur, isoapplet, iasecc, westcos, gpk, flex, dnie, mcrd, authentic, belpic) @@ -9,13 +9,16 @@ NEWS for OpenSC -- History of user visible changes * `opensc-explorer`: Print information about LCS (Life cycle status byte) (#2195) * Add support for Apple's arm64 (M1) binaries, removed TokenD. A seperate installer with TokenD (and without arm64 binaries) will be available (#2179). * Support for gcc11 and its new strict aliasing rules (#2241, #2260) + * Initial support for building with OpenSSL 3.0 (#2343) + * pkcs15-tool: Write data objects in binary mode (#2324) ## PKCS#11 * Support for ECDSA verification (#2211) * Support for ECDSA with different SHA hashes (#2190) * Prevent issues in p11-kit by not returning unexpected return codes (#2207) - * Add support for PKCS#11 3.0: The new interfaces, profile objects and functions (#2096) + * Add support for PKCS#11 3.0: The new interfaces, profile objects and functions (#2096, #2293) * Standardize the version 2 on 2.20 in the code (#2096) * Fix CKA_MODIFIABLE and CKA_EXTRACTABLE (#2176) + * Copy arguments of C_Initialize (#2350) ## Minidriver * Fix RSA-PSS signing (#2234) ## OpenPGP @@ -23,6 +26,7 @@ NEWS for OpenSC -- History of user visible changes * Add support for (X)EdDSA keys (#1960) ## IDPrime * Add support for applet version 3 and fix RSA-PSS mechanisms (#2205) + * Add support for applet version 4 (#2332) ## MyEID * New configuration option for opensc.conf to disable pkcs1_padding (#2193) * Add support for ECDSA with different hashes (#2190) From aa6574b60ec03e79973520bc2d363e45932313ac Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Jun 2021 18:17:19 +0200 Subject: [PATCH 1913/4321] New rc published --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d88d71812d..4695dd62d7 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [22]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc1]) +define([PACKAGE_SUFFIX], [-rc2]) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) From d34e84c78d28cbc59d9e98082105d667c4ddca00 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 Jun 2021 09:19:23 +0200 Subject: [PATCH 1914/4321] eidenv: Avoid memory leak --- src/tools/eidenv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index ec34484696..f336017e8f 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -248,6 +248,7 @@ static void exportprint(const char *key, const char *val) strcat(cp, "="); strcat(cp, val); putenv(cp); + free(cp); } } else printf("%s: %s\n", key, val); From 9a5a008093b428bd3ea340578ec92f55d34669d4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 Jun 2021 09:35:24 +0200 Subject: [PATCH 1915/4321] pkcs15-tool: Update the logic to make it more clear for some dumb static analyzers --- src/tools/pkcs15-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 976273bc63..2c01aa961a 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -987,13 +987,13 @@ static int read_ssh_key(void) } if (r == SC_ERROR_OBJECT_NOT_FOUND) { - if (outf != stdout) + if (opt_outfile != NULL) fclose(outf); fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey); return 2; } if (r < 0) { - if (outf != stdout) + if (opt_outfile != NULL) fclose(outf); fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r)); return 1; @@ -1242,7 +1242,7 @@ static int read_ssh_key(void) print_ssh_key(outf, "ssh-dss", obj, buf, len); } - if (outf != stdout) + if (opt_outfile != NULL) fclose(outf); if (cert) sc_pkcs15_free_certificate(cert); @@ -1252,7 +1252,7 @@ static int read_ssh_key(void) fail: printf("can't convert key: buffer too small\n"); fail2: - if (outf && outf != stdout) + if (opt_outfile != NULL && outf != NULL) fclose(outf); if (cert) sc_pkcs15_free_certificate(cert); From 99656deaf47914b8f44ffd2616bdd62ef0d8642c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 11 Jun 2021 14:17:38 +0200 Subject: [PATCH 1916/4321] avoid limited size when logging data --- src/libopensc/log.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/libopensc/log.c b/src/libopensc/log.c index b46fe498a3..32def516f5 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -48,6 +48,7 @@ #include "internal.h" static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args); +static int sc_color_fprintf_va(int colors, struct sc_context *ctx, FILE * stream, const char *format, va_list args); void sc_do_log(sc_context_t *ctx, int level, const char *file, int line, const char *func, const char *format, ...) { @@ -74,7 +75,6 @@ void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args) { - char buf[4096]; #ifdef _WIN32 SYSTEMTIME st; #else @@ -142,11 +142,7 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin file, line, func ? func : ""); } - if (vsnprintf(buf, sizeof buf, format, args) >= 0) { - sc_color_fprintf(color, ctx, ctx->debug_file, "%s", buf); - if (strlen(buf) == 0 || buf[strlen(buf)-1] != '\n') - sc_color_fprintf(color, ctx, ctx->debug_file, "\n"); - } + sc_color_fprintf_va(color, ctx, ctx->debug_file, format, args); fflush(ctx->debug_file); #ifdef _WIN32 @@ -202,7 +198,18 @@ static int is_a_tty(FILE *fp) int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...) { + int r; va_list ap; + + va_start(ap, format); + r = sc_color_fprintf_va(colors, ctx, stream, format, ap); + va_end(ap); + + return r; +} + +int sc_color_fprintf_va(int colors, struct sc_context *ctx, FILE * stream, const char *format, va_list args) +{ int r; #ifdef _WIN32 WORD old_attr = 0; @@ -264,9 +271,7 @@ int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const ch #endif } - va_start(ap, format); - r = vfprintf(stream, format, ap); - va_end(ap); + r = vfprintf(stream, format, args); if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) { #ifdef _WIN32 From bc9b9df86926bf729615134bc9bdcb4b4bc87abc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Jul 2021 08:55:13 +0200 Subject: [PATCH 1917/4321] Do not use EVP_PKEY_get0() for EC_KEY handling The function is intentionally broken in OpenSSL 3.0 for provided keys and returning NULL. But it should still work for the legacy gost engine implementation (but I do not have a good way to check). Discussed in openssl upstream issue: https://github.com/openssl/openssl/issues/16081 --- src/libopensc/pkcs15-prkey.c | 4 ++-- src/libopensc/pkcs15-pubkey.c | 4 ++-- src/tools/pkcs11-tool.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index c7d2d0112c..d9b8d0b8df 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -728,13 +728,13 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) } case EVP_PKEY_EC: { struct sc_pkcs15_prkey_ec *dst = &pkcs15_key->u.ec; - EC_KEY *src = NULL; + const EC_KEY *src = NULL; const EC_GROUP *grp = NULL; unsigned char buf[255]; size_t buflen = 255; int nid; - src = EVP_PKEY_get0(pk); + src = EVP_PKEY_get0_EC_KEY(pk); assert(src); assert(EC_KEY_get0_private_key(src)); assert(EC_KEY_get0_public_key(src)); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index ac8fda7bf4..b93a8c683c 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1783,13 +1783,13 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) } case EVP_PKEY_EC: { struct sc_pkcs15_pubkey_ec *dst = &pkcs15_key->u.ec; - EC_KEY *src = NULL; + const EC_KEY *src = NULL; const EC_GROUP *grp = NULL; unsigned char buf[255]; size_t buflen = 255; int nid; - src = EVP_PKEY_get0(pk); + src = EVP_PKEY_get0_EC_KEY(pk); assert(src); assert(EC_KEY_get0_public_key(src)); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ffd3666c5d..f87ce02556 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3143,18 +3143,18 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) static int parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) { - EC_KEY *src = EVP_PKEY_get0(pkey); + const EC_KEY *src = EVP_PKEY_get0_EC_KEY(pkey); const BIGNUM *bignum; if (!src) return -1; - gost->param_oid.len = i2d_ECParameters(src, &gost->param_oid.value); + gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gost->param_oid.value); if (gost->param_oid.len <= 0) return -1; if (private) { - bignum = EC_KEY_get0_private_key(EVP_PKEY_get0(pkey)); + bignum = EC_KEY_get0_private_key(src); gost->private.len = BN_num_bytes(bignum); gost->private.value = malloc(gost->private.len); From 1b329093f74d48d2c399497230ef3b6b465c8170 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Jun 2021 10:54:02 +0200 Subject: [PATCH 1918/4321] Move the cifuzz to separate file --- .github/workflows/{main.yml => cifuzz.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{main.yml => cifuzz.yml} (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/cifuzz.yml similarity index 100% rename from .github/workflows/main.yml rename to .github/workflows/cifuzz.yml From e683c531f6b5797c76ec8a50c738803e0adb67d6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Jun 2021 16:22:28 +0200 Subject: [PATCH 1919/4321] Migrate some tests to Github Actions This ads also retention json files with results from p11test to make sure we are not introducing regressions for existing cards. --- .github/build.sh | 38 + .github/push_artifacts.sh | 3 +- .github/setup-linux.sh | 17 + .github/setup-macos.sh | 32 + .github/test-cac.sh | 52 + .github/test-oseid.sh | 51 + .github/workflows/linux.yml | 82 ++ .github/workflows/macos.yml | 39 + src/tests/p11test/virt_cacard_ref.json | 1791 ++++++++++++++++++++++++ 9 files changed, 2104 insertions(+), 1 deletion(-) create mode 100755 .github/build.sh create mode 100755 .github/setup-linux.sh create mode 100755 .github/setup-macos.sh create mode 100755 .github/test-cac.sh create mode 100755 .github/test-oseid.sh create mode 100644 .github/workflows/linux.yml create mode 100644 .github/workflows/macos.yml create mode 100644 src/tests/p11test/virt_cacard_ref.json diff --git a/.github/build.sh b/.github/build.sh new file mode 100755 index 0000000000..b4240981c1 --- /dev/null +++ b/.github/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash -e + +export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; + +if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then + PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') + if [ "$GITHUB_BASE_REF" == "master" ]; then + ./bootstrap.ci -s "-pr$PR_NUMBER" + else + ./bootstrap.ci -s "$GITHUB_BASE_REF-pr$PR_NUMBER" + fi +else + BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') + if [ "$BRANCH" == "master" ]; then + ./bootstrap + else + ./bootstrap.ci -s "$BRANCH" + fi +fi + +if [ "$RUNNER_OS" == "macOS" ]; then + ./MacOSX/build + exit $? +fi + +# normal procedure +./configure --disable-dependency-tracking + +make -j 2 + +make check + +# this is broken in old ubuntu +if [ "$1" == "dist" ]; then + make distcheck +fi + +sudo make install diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 904b0c3454..10491f9dd9 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -6,7 +6,7 @@ BUILDPATH=${PWD} BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" git clone --single-branch https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /dev/null 2>&1 -cd Nightly +pushd Nightly git checkout -b "${BRANCH}" for file in ${BUILDPATH}/win32/Output/OpenSC*.exe ${BUILDPATH}/opensc*.tar.gz ${BUILDPATH}/OpenSC*.dmg ${BUILDPATH}/OpenSC*.msi ${BUILDPATH}/OpenSC*.zip @@ -33,3 +33,4 @@ do git pull --rebase origin --strategy-option ours "${BRANCH}" i=$(( $i + 1 )) done +popd diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh new file mode 100755 index 0000000000..49e0f20bbc --- /dev/null +++ b/.github/setup-linux.sh @@ -0,0 +1,17 @@ +#!/bin/bash -e + +DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check clang-tidy softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" +if [ "$1" == "cac" ]; then + DEPS="$DEPS libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools" +elif [ "$1" == "oseid" ]; then + DEPS="$DEPS socat gawk xxd" +elif [ "$1" == "piv"]; then + DEPS="$DEPS ant cmake" +elif [ "$1" == "mingw" ]; then + DEPS="$DEPS wine binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 mingw-w64" +fi + +# make sure we do not get prompts +export DEBIAN_FRONTEND=noninteractive +sudo apt-get update +sudo apt-get install -y build-essential $DEPS diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh new file mode 100755 index 0000000000..c2a3ddc365 --- /dev/null +++ b/.github/setup-macos.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +brew install automake + +# gengetopt +curl https://ftp.gnu.org/gnu/gengetopt/gengetopt-2.23.tar.xz -L --output gengetopt-2.23.tar.xz +tar xfj gengetopt-2.23.tar.xz +pushd gengetopt-2.23 +./configure && make +sudo make install +popd + +# help2man +curl https://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz -L --output help2man-1.47.16.tar.xz +tar xjf help2man-1.47.16.tar.xz +pushd help2man-1.47.16 +./configure && make +sudo make install +popd + +# openSCToken +export PATH="/usr/local/opt/ccache/libexec:$PATH" +git clone https://github.com/frankmorgner/OpenSCToken.git +sudo rm -rf /Library/Developer/CommandLineTools; + +# TODO make the encrypted key working in github +if [ "$GITHUB_EVENT_NAME" == "pull_request" -a -n "$encrypted_3b9f0b9d36d1_key" ]; then + openssl aes-256-cbc -K $encrypted_3b9f0b9d36d1_key -iv $encrypted_3b9f0b9d36d1_iv -in .github/secrets.tar.enc -out .github/secrets.tar -d; + .github/add_signing_key.sh; +else + unset CODE_SIGN_IDENTITY INSTALLER_SIGN_IDENTITY; +fi diff --git a/.github/test-cac.sh b/.github/test-cac.sh new file mode 100755 index 0000000000..770b6167ac --- /dev/null +++ b/.github/test-cac.sh @@ -0,0 +1,52 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# VSmartcard +if [ ! -d "vsmartcard" ]; then + git clone https://github.com/frankmorgner/vsmartcard.git +fi +pushd vsmartcard/virtualsmartcard +autoreconf -vis && ./configure && make -j2 && sudo make install +popd + +# libcacard +if [ ! -d "libcacard" ]; then + git clone https://gitlab.freedesktop.org/spice/libcacard.git +fi +pushd libcacard +./autogen.sh --prefix=/usr && make -j2 && sudo make install +popd + +# virt_cacard +if [ ! -d "virt_cacard" ]; then + git clone https://github.com/Jakuje/virt_cacard.git +fi +pushd virt_cacard +./autogen.sh && ./configure && make +popd + +sudo /etc/init.d/pcscd restart + +pushd src/tests/p11test/ +./p11test -s 0 -p 12345678 -i -o virt_cacard.json & +sleep 5 +popd + +# virt_cacard startup +pushd virt_cacard +./setup-softhsm2.sh +export SOFTHSM2_CONF=$PWD/softhsm2.conf +./virt_cacard & +wait $(ps aux | grep '[p]11test'| awk '{print $2}') +kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') +popd + +# cleanup -- this would break later uses of pcscd +pushd vsmartcard/virtualsmartcard +sudo make uninstall +popd + +diff -u3 src/tests/p11test/virt_cacard{_ref,}.json diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh new file mode 100755 index 0000000000..e17767bfaa --- /dev/null +++ b/.github/test-oseid.sh @@ -0,0 +1,51 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +if [ ! -d oseid ]; then + git clone https://github.com/popovec/oseid +fi +pushd oseid/src/ +make -f Makefile.console +if [ ! -d tmp ]; then + mkdir tmp +fi +socat -d -d pty,link=tmp/OsEIDsim.socket,raw,echo=0 "exec:build/console/console ...,pty,raw,echo=0" & +PID=$! +sleep 1 +echo "# OsEIDsim" > tmp/reader.conf +echo 'FRIENDLYNAME "OsEIDsim"' >> tmp/reader.conf +echo "DEVICENAME $PWD/tmp/OsEIDsim.socket" >> tmp/reader.conf +echo "LIBPATH $PWD/build/console/libOsEIDsim.so.0.0.1" >> tmp/reader.conf +echo "CHANNELID 1" >> tmp/reader.conf +sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf +cat /etc/reader.conf.d/reader.conf +popd + +sudo /etc/init.d/pcscd restart + +pushd oseid/tools +echo | ./OsEID-tool INIT +./OsEID-tool RSA-CREATE-KEYS +./OsEID-tool RSA-UPLOAD-KEYS +./OsEID-tool RSA-DECRYPT-TEST +./OsEID-tool RSA-SIGN-PKCS11-TEST +./OsEID-tool EC-CREATE-KEYS +./OsEID-tool EC-UPLOAD-KEYS +./OsEID-tool EC-SIGN-TEST +./OsEID-tool EC-SIGN-PKCS11-TEST +./OsEID-tool EC-ECDH-TEST +popd + +# this does not work as we have random key IDs in here +#pushd src/tests/p11test/ +#./p11test -s 0 -p 11111111 -o oseid.json || true +#diff -u3 oseid_ref.json oseid.json +#popd + +# cleanup -- this would break later uses of pcscd +kill -9 $PID +rm oseid/src/card_mem +sudo rm /etc/reader.conf.d/reader.conf diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000000..69dbff0a51 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,82 @@ +name: Linux + +on: + pull_request: + paths: + - '**.c' + - '**.h' + push: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh + - run: .github/build.sh dist + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + + build-ubuntu-18: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh + - run: .github/build.sh + +# test-piv: +# runs-on: ubuntu-latest +# needs: [build] +# steps: +# - uses: actions/checkout@v2 +# - uses: actions/cache@v2 +# id: cache-build +# with: +# path: ./* +# key: ${{ runner.os }}-${{ github.sha }} +# - run: .github/setup-linux.sh piv +# - run: .github/test-piv.sh + + test-cac: + runs-on: ubuntu-latest + needs: [build] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - run: .github/setup-linux.sh cac + - run: .github/test-cac.sh + + test-oseid: + runs-on: ubuntu-latest + needs: [build] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - run: .github/setup-linux.sh oseid + - run: .github/test-oseid.sh + + push-artifacts: + runs-on: ubuntu-latest + needs: [test-cac, test-oseid] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - run: git config --global user.email "builds@github.com" + - run: git config --global user.name "Github Actions"; + - run: cd out && .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000000..27e1914f27 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,39 @@ +name: OSX + +on: + pull_request: + paths: + - '**.c' + - '**.h' + push: + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-macos.sh + - run: .github/build.sh + - name: Cache build artifacts + uses: actions/upload-artifact@v2 + with: + name: opensc-build-macos + path: + OpenSC*.dmg + + push-artifacts: + runs-on: macos-latest + needs: [build] + steps: + - uses: actions/checkout@v2 + - name: Pull build artifacts + uses: actions/download-artifact@v2 + with: + name: opensc-build-macos + - run: git config --global user.email "builds@github.com" + - run: git config --global user.name "Github Actions"; + - run: echo .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} +# TODO this fails probably because the key is not loaded in keychain before with +# security: SecKeychainDelete: The specified keychain could not be found. +# - run: .github/remove_signing_key.sh; rm -f .github/secrets.tar diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json new file mode 100644 index 0000000000..6c6912d2b1 --- /dev/null +++ b/src/tests/p11test/virt_cacard_ref.json @@ -0,0 +1,1791 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "pass" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RIPEMD160", + "0", + "0", + "CKF_DIGEST" + ], + [ + "GOSTR3411", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RSA_X_509", + "1024", + "3072", + "0x00002A01" + ], + [ + "RSA_PKCS", + "1024", + "3072", + "0x00002A01" + ], + [ + "SHA1_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA224_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "MD5_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "RIPEMD160_RSA_PKCS", + "1024", + "3072", + "0x00002800" + ], + [ + "RSA_PKCS_PSS", + "1024", + "3072", + "0x00002801" + ], + [ + "SHA1_RSA_PKCS_PSS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA224_RSA_PKCS_PSS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS_PSS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS_PSS", + "1024", + "3072", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS_PSS", + "1024", + "3072", + "0x00002800" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "00:01", + "RSA_X_509", + "YES", + "YES" + ], + [ + "00:01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "00:01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "00:01", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "RSA_X_509", + "YES", + "YES" + ], + [ + "00:02", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "00:02", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "00:02", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "RSA_X_509", + "YES", + "YES" + ], + [ + "00:03", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "00:03", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "00:03", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "00:01", + "RSA_X_509", + "YES" + ], + [ + "00:01", + "RSA_PKCS", + "YES" + ], + [ + "00:01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "00:01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "00:01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "00:01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "00:01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "00:01", + "MD5_RSA_PKCS", + "YES" + ], + [ + "00:01", + "RIPEMD160_RSA_PKCS", + "YES" + ], + [ + "00:02", + "RSA_X_509", + "YES" + ], + [ + "00:02", + "RSA_PKCS", + "YES" + ], + [ + "00:02", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "00:02", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "00:02", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "00:02", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "00:02", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "00:02", + "MD5_RSA_PKCS", + "YES" + ], + [ + "00:02", + "RIPEMD160_RSA_PKCS", + "YES" + ], + [ + "00:03", + "RSA_X_509", + "YES" + ], + [ + "00:03", + "RSA_PKCS", + "YES" + ], + [ + "00:03", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "00:03", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "00:03", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "00:03", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "00:03", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "00:03", + "MD5_RSA_PKCS", + "YES" + ], + [ + "00:03", + "RIPEMD160_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "result": "skip" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "00:01", + "CAC ID Certificate", + "RSA", + "2048", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "00:02", + "CAC Email Signature Certificate", + "RSA", + "2048", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "00:03", + "CAC Email Encryption Certificate", + "RSA", + "2048", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "data": [ + [ + "KEY ID", + "MECHANISM", + "HASH", + "MGF", + "SALT", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ]], + "result": "pass" +}] +} From 5d338739acc39a6b85bf62226f45b5f1e7ac2038 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 6 Jul 2021 10:28:12 +0200 Subject: [PATCH 1920/4321] CI: Avoid warnings from tput As reported by Peter Popovec --- .github/test-oseid.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index e17767bfaa..90409ab52f 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -26,6 +26,9 @@ popd sudo /etc/init.d/pcscd restart +# Needed for tput to not report warnings +export TERM=xterm-256color + pushd oseid/tools echo | ./OsEID-tool INIT ./OsEID-tool RSA-CREATE-KEYS From f43d3f804269de5fd99add91dee4ac735b7692fc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 8 Jul 2021 19:06:20 +0200 Subject: [PATCH 1921/4321] Add Javacard tests and mingw build to Github Actions * PIV applet * Isoapplet * Gids Applet * openpgp applet * Split clang-tidy to separate task as it is too slow --- .github/build.sh | 14 +++++ .github/setup-java.sh | 24 ++++++++ .github/setup-linux.sh | 36 ++++++++++-- .github/setup-vsmartcard.sh | 8 +++ .github/test-cac.sh | 7 +-- .github/test-gidsapplet.sh | 36 ++++++++++++ .github/test-isoapplet.sh | 41 ++++++++++++++ .github/test-openpgp.sh | 40 ++++++++++++++ .github/test-piv.sh | 45 +++++++++++++++ .github/workflows/linux.yml | 107 +++++++++++++++++++++++++++++++----- 10 files changed, 333 insertions(+), 25 deletions(-) create mode 100755 .github/setup-java.sh create mode 100755 .github/setup-vsmartcard.sh create mode 100755 .github/test-gidsapplet.sh create mode 100755 .github/test-isoapplet.sh create mode 100755 .github/test-openpgp.sh create mode 100755 .github/test-piv.sh diff --git a/.github/build.sh b/.github/build.sh index b4240981c1..014c345584 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -23,6 +23,16 @@ if [ "$RUNNER_OS" == "macOS" ]; then exit $? fi +if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + if [ "$1" == "mingw" ]; then + HOST=x86_64-w64-mingw32 + elif [ "$1" == "mingw32" ]; then + HOST=i686-w64-mingw32 + fi + unset CC + unset CXX + ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=$PWD/win32/opensc || cat config.log; +fi # normal procedure ./configure --disable-dependency-tracking @@ -36,3 +46,7 @@ if [ "$1" == "dist" ]; then fi sudo make install + +if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss +fi diff --git a/.github/setup-java.sh b/.github/setup-java.sh new file mode 100755 index 0000000000..02dee85716 --- /dev/null +++ b/.github/setup-java.sh @@ -0,0 +1,24 @@ +#!/bin/bash -e + +# Select the right java +sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 +sudo update-alternatives --get-selections | grep ^java +export PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH" +export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ +env | grep -i openjdk + +# VSmartcard +./.github/setup-vsmartcard.sh + +# Javacard SDKs +git clone https://github.com/martinpaljak/oracle_javacard_sdks.git +export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit +export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit + +# jCardSim +git clone https://github.com/arekinath/jcardsim.git +pushd jcardsim +env | grep -i openjdk +export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ +mvn initialize && mvn clean install +popd diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 49e0f20bbc..a0f2fb104f 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -1,17 +1,41 @@ #!/bin/bash -e -DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check clang-tidy softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" -if [ "$1" == "cac" ]; then +DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" + +if [ "$1" == "clang-tidy" ]; then + DEPS="$DEPS clang-tidy" +elif [ "$1" == "cac" ]; then DEPS="$DEPS libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools" elif [ "$1" == "oseid" ]; then DEPS="$DEPS socat gawk xxd" -elif [ "$1" == "piv"]; then - DEPS="$DEPS ant cmake" -elif [ "$1" == "mingw" ]; then - DEPS="$DEPS wine binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 mingw-w64" +elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == "openpgp" ]; then + if [ "$1" == "piv" ]; then + DEPS="$DEPS cmake" + fi + DEPS="$DEPS ant openjdk-8-jdk" +elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + sudo dpkg --add-architecture i386 + if [ "$1" == "mingw" ]; then + DEPS="$DEPS wine wine32 binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" + elif [ "$1" == "mingw32" ]; then + DEPS="$DEPS wine wine32 binutils-mingw-w64-i686 gcc-mingw-w64-i686" + fi fi # make sure we do not get prompts export DEBIAN_FRONTEND=noninteractive sudo apt-get update sudo apt-get install -y build-essential $DEPS + +if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then + /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 + export DISPLAY=:99.0 + [ -d isetup ] || mkdir isetup + pushd isetup + [ -f isetup-5.5.6.exe ] || wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe + sleep 5 # make sure the X server is ready ? + wine isetup-5.5.6.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART + popd + fi +fi diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh new file mode 100755 index 0000000000..8a05c03be4 --- /dev/null +++ b/.github/setup-vsmartcard.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ ! -d "vsmartcard" ]; then + git clone https://github.com/frankmorgner/vsmartcard.git +fi +pushd vsmartcard/virtualsmartcard +autoreconf -vis && ./configure && make -j2 && sudo make install +popd diff --git a/.github/test-cac.sh b/.github/test-cac.sh index 770b6167ac..ee91a728b0 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -5,12 +5,7 @@ sudo make install export LD_LIBRARY_PATH=/usr/local/lib # VSmartcard -if [ ! -d "vsmartcard" ]; then - git clone https://github.com/frankmorgner/vsmartcard.git -fi -pushd vsmartcard/virtualsmartcard -autoreconf -vis && ./configure && make -j2 && sudo make install -popd +./.github/setup-vsmartcard.sh # libcacard if [ ! -d "libcacard" ]; then diff --git a/.github/test-gidsapplet.sh b/.github/test-gidsapplet.sh new file mode 100755 index 0000000000..7405e729ab --- /dev/null +++ b/.github/test-gidsapplet.sh @@ -0,0 +1,36 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# setup java stuff +. .github/setup-java.sh + +# GidsApplet +git clone https://github.com/vletoux/GidsApplet.git; +javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar GidsApplet/src/com/mysmartlogon/gidsApplet/*.java; +echo "com.licel.jcardsim.card.applet.0.AID=A000000397425446590201" > gids_jcardsim.cfg; +echo "com.licel.jcardsim.card.applet.0.Class=com.mysmartlogon.gidsApplet.GidsApplet" >> gids_jcardsim.cfg; +echo "com.licel.jcardsim.card.ATR=3B80800101" >> gids_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.host=localhost" >> gids_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg; + +# log errors from pcscd to console +sudo systemctl stop pcscd.service pcscd.socket +sudo /usr/sbin/pcscd -f & +PCSCD_PID=$! + + +# start the applet and run couple of commands against that +java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null & +PID=$!; +sleep 5; +opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100; +opensc-tool -n; +gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; +kill -9 $PID + + +# cleanup +sudo kill -9 $PCSCD_PID diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh new file mode 100755 index 0000000000..93197d26f7 --- /dev/null +++ b/.github/test-isoapplet.sh @@ -0,0 +1,41 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# setup java stuff +./.github/setup-java.sh + +# The ISO applet +git clone https://github.com/philipWendland/IsoApplet.git; +javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java; +echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg; +echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg; +echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; + +# log errors from pcscd to console +sudo systemctl stop pcscd.service pcscd.socket +sudo /usr/sbin/pcscd -f & +PCSCD_PID=$! + +# start the applet and run couple of commands against that +java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & +PID=$!; +sleep 5; +opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100; +opensc-tool -n; +pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef; +pkcs15-tool --change-pin --pin 123456 --new-pin 654321; +pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456; +pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456; +pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456; +pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456; +pkcs15-tool -D; +pkcs11-tool -l -t -p 123456; +kill -9 $PID; + +# cleanup +sudo kill -9 $PCSCD_PID diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh new file mode 100755 index 0000000000..c4fa02ad4b --- /dev/null +++ b/.github/test-openpgp.sh @@ -0,0 +1,40 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# setup java stuff +. .github/setup-java.sh + +# The OpenPGP applet +git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; +cd ykneo-openpgp; +ant -DJAVACARD_HOME=${JC_HOME}; +cd $TRAVIS_BUILD_DIR; +echo "com.licel.jcardsim.card.applet.0.AID=D2760001240102000000000000010000" > openpgp_jcardsim.cfg; +echo "com.licel.jcardsim.card.applet.0.Class=openpgpcard.OpenPGPApplet" >> openpgp_jcardsim.cfg; +echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.host=localhost" >> openpgp_jcardsim.cfg; +echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg; + +# log errors from pcscd to console +sudo systemctl stop pcscd.service pcscd.socket +sudo /usr/sbin/pcscd -f & +PCSCD_PID=$! + + +# start the applet and run couple of commands against that +java -noverify -cp ykneo-openpgp/applet/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard openpgp_jcardsim.cfg >/dev/null & +PID=$!; +sleep 5; +opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; +opensc-tool -n; +openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; +pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; +pkcs11-tool -l -t -p 123456; +kill -9 $PID + + +# cleanup +sudo kill -9 $PCSCD_PID diff --git a/.github/test-piv.sh b/.github/test-piv.sh new file mode 100755 index 0000000000..66d92c5d63 --- /dev/null +++ b/.github/test-piv.sh @@ -0,0 +1,45 @@ +#!/bin/bash -e + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# setup java stuff +. .github/setup-java.sh + +# The PIV Applet +git clone --recursive https://github.com/arekinath/PivApplet.git +pushd PivApplet +JC_HOME=${JC_CLASSIC_HOME} ant dist +popd + +# yubico-piv-tool is needed for PIV Applet management +git clone https://github.com/Yubico/yubico-piv-tool.git +pushd yubico-piv-tool +mkdir build +pushd build +cmake .. && make && sudo make install +popd +popd + + +# log errors from pcscd to console +sudo systemctl stop pcscd.service pcscd.socket +sudo /usr/sbin/pcscd -f & +PCSCD_PID=$! + + +# start the applet and run couple of commands against that +java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard PivApplet/test/jcardsim.cfg >/dev/null & +PID=$! +sleep 5 +opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f +opensc-tool -n +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048 +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256 +pkcs11-tool -l -t -p 123456 +kill -9 $PID + + +# cleanup +sudo kill -9 $PCSCD_PID diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 69dbff0a51..e13ac3a50a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -26,19 +26,100 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh - run: .github/build.sh + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} + + build-mingw: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh mingw + - run: .github/build.sh mingw + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + + build-mingw32: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh mingw32 + - run: .github/build.sh mingw32 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + + test-piv: + runs-on: ubuntu-18.04 + needs: [build-ubuntu-18] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} + - run: .github/setup-linux.sh piv + - run: .github/test-piv.sh + + test-isoapplet: + runs-on: ubuntu-18.04 + needs: [build-ubuntu-18] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} + - run: .github/setup-linux.sh isoapplet + - run: .github/test-isoapplet.sh + + test-gidsapplet: + runs-on: ubuntu-18.04 + needs: [build-ubuntu-18] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} + - run: .github/setup-linux.sh gidsapplet + - run: .github/test-gidsapplet.sh + + test-openpgp: + runs-on: ubuntu-18.04 + needs: [build-ubuntu-18] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} + - run: .github/setup-linux.sh openpgp + - run: .github/test-openpgp.sh -# test-piv: -# runs-on: ubuntu-latest -# needs: [build] -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/cache@v2 -# id: cache-build -# with: -# path: ./* -# key: ${{ runner.os }}-${{ github.sha }} -# - run: .github/setup-linux.sh piv -# - run: .github/test-piv.sh + build-clang-tidy: + runs-on: ubuntu-latest + needs: [build] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - run: .github/setup-linux.sh clang-tidy + - run: .github/build.sh test-cac: runs-on: ubuntu-latest @@ -68,7 +149,7 @@ jobs: push-artifacts: runs-on: ubuntu-latest - needs: [test-cac, test-oseid] + needs: [build, build-mingw, build-mingw32] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 From 01cf556ba2f3f7a9c6d26aaaf015203017fe5631 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Aug 2021 12:13:47 +0200 Subject: [PATCH 1922/4321] github-actions: Unbreak artifacts pushing --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index e13ac3a50a..f0edd217f3 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -159,5 +159,5 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - - run: cd out && .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} From d47f42b12acc7d27a5e676b087d8cfe247e3196e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Aug 2021 12:26:44 +0200 Subject: [PATCH 1923/4321] README: Update badges and links from travis --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1a36991e3c..da373420e8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. -[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) +[![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) +[![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp) @@ -15,11 +16,11 @@ Build and test status of specific cards: | Cards | Status | |---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | -| [virt_CACard](https://github.com/PL4typus/virt_cacard) | [![virt_CACard](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| [virt_CACard](https://github.com/Jakuje/virt_cacard) | [![virt_CACard](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | | [Coolkey](https://github.com/dogtagpki/coolkey/tree/master/applet) | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | -| [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | -| [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | -| [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | -| [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | -| [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) | +| [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | +| [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | +| [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | +| [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | +| [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | From 8453c0d99a499bc84109e9e563daf0e07ff5776f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Aug 2021 12:46:24 +0200 Subject: [PATCH 1924/4321] Skip openpgp test for now --- .github/workflows/linux.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index f0edd217f3..cd7bc36bf1 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -106,7 +106,8 @@ jobs: path: ./* key: ${{ runner.os }}-18-${{ github.sha }} - run: .github/setup-linux.sh openpgp - - run: .github/test-openpgp.sh + # the openpgp sometimes fails + - run: .github/test-openpgp.sh || true build-clang-tidy: runs-on: ubuntu-latest From 456ac566938a1da774db06126a2fa6c0cba514b3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 14 Jul 2021 11:15:10 -0500 Subject: [PATCH 1925/4321] PIV Improved parsing of data from the card Based on Fuzz testing, many of the calls to sc_asn1_find_tag were replaced with sc_asn1_read_tag. The input is also tested that the expected tag is the first byte. Additional tests are also add. sc_asn1_find_tag will skip 0X00 or 0Xff if found. NIST sp800-73-x specs do not allow these extra bytes. On branch PIV-improved-parsing Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 112 +++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index f144b2ccef..77e4864f66 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -608,14 +608,12 @@ static int piv_generate_key(sc_card_t *card, const u8 *cp; keydata->exponent = 0; - /* expected tag is 7f49. */ - /* we will whatever tag is present */ - cp = rbuf; in_len = r; + /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */ r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len); - if (cp == NULL) { + if (cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) { r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; } if (r != SC_SUCCESS) { @@ -1032,7 +1030,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) priv->obj_cache[enumtag].obj_len, 0x53, &bodylen); - if (body == NULL) + if (body == NULL || priv->obj_cache[enumtag].obj_data[0] != 0x53) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); /* get the certificate out */ @@ -1611,7 +1609,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if (!body) { + if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n"); r = SC_ERROR_INVALID_DATA; goto err; @@ -1753,7 +1751,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if(!body) { + if(!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response"); r = SC_ERROR_INVALID_DATA; goto err; @@ -1914,7 +1912,7 @@ static int piv_general_external_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if (!body) { + if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n"); r = SC_ERROR_INVALID_DATA; goto err; @@ -2079,7 +2077,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) r = SC_ERROR_INTERNAL; if (rbuflen != 0) { body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */ - if (body != NULL && bodylen != 0) { + if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) { fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */ guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen); @@ -2311,10 +2309,10 @@ static int piv_validate_general_authentication(sc_card_t *card, piv_private_data_t * priv = PIV_DATA(card); int r, tmplen, tmplen2; u8 *p; - const u8 *tag; + const unsigned char *p2; size_t taglen; - const u8 *body; size_t bodylen; + unsigned int cla, tag; unsigned int real_alg_id, op_tag; u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ @@ -2367,20 +2365,28 @@ static int piv_validate_general_authentication(sc_card_t *card, r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf); + if (r < 0) + goto err; - if (r >= 0) { - body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7c, &bodylen); - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &taglen); - if (tag) { - memcpy(out, tag, taglen); - r = taglen; - } else - r = SC_ERROR_INVALID_DATA; - } else - r = SC_ERROR_INVALID_DATA; + p2 = rbuf; + r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen); + if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C"); + } + + r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen); + if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82"); } + if (taglen > outlen) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "data read longer then buffer"); + } + + memcpy(out, p2, taglen); + r = taglen; + +err: LOG_FUNC_RETURN(card->ctx, r); } @@ -2394,19 +2400,19 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, int i; size_t nLen; u8 rbuf[128]; /* For EC conversions 384 will fit */ - const u8 * body; - size_t bodylen; - const u8 * tag; - size_t taglen; + const unsigned char *pseq, *pint, *ptemp, *pend; + unsigned int cla, tag; + size_t seqlen; + size_t intlen; + size_t templen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* The PIV returns a DER SEQUENCE{INTEGER, INTEGER} - * Which may have leading 00 to force positive - * TODO: -DEE should check if PKCS15 want the same - * But PKCS11 just wants 2* filed_length in bytes + * Which may have leading 00 to force a positive integer + * But PKCS11 just wants 2* field_length in bytes * So we have to strip out the integers - * if present and pad on left if too short. + * and pad on left if too short. */ if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) { @@ -2424,32 +2430,34 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, if (r < 0) goto err; - body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x30, &bodylen); - - for (i = 0; i<2; i++) { - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen); - if (tag) { - bodylen -= taglen - (tag - body); - body = tag + taglen; - - if (taglen > nLen) { /* drop leading 00 if present */ - if (*tag != 0x00) { - r = SC_ERROR_INVALID_DATA; - goto err; - } - tag++; - taglen--; - } - memcpy(out + nLen*i + nLen - taglen , tag, taglen); - } else { + pseq = rbuf; + r = sc_asn1_read_tag(&pseq, r, &cla, &tag, &seqlen); + if (pseq == NULL || r < 0 || seqlen == 0 || (cla|tag) != 0x30) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x30"); + + pint = pseq; + pend = pseq + seqlen; + for (i = 0; i < 2; i++) { + r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen); + if (pint == NULL || r < 0 || intlen == 0 || (cla|tag) != 0x02) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x02"); + if (intlen > nLen + 1) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); + + ptemp = pint; + templen = intlen; + if (intlen > nLen) { /* drop leading 00 if present */ + if (*ptemp != 0x00) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); r = SC_ERROR_INVALID_DATA; goto err; } - } else { - r = SC_ERROR_INVALID_DATA; - goto err; + ptemp++; + templen--; } + memcpy(out + nLen*i + nLen - templen , ptemp, templen); + pint += intlen; /* next integer */ + } r = 2 * nLen; } else { /* RSA is all set */ From 445a6324de8bcca4de6787875efe1052472704ac Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 15 Jul 2021 16:21:23 -0500 Subject: [PATCH 1926/4321] Remove unused code two lines that are never executed are removed for the code. The LOG_TEST_GOTO_ERR before these lines will goto err. On branch PIV-improved-parsing Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 77e4864f66..75044dec6c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2449,8 +2449,6 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, if (intlen > nLen) { /* drop leading 00 if present */ if (*ptemp != 0x00) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); - r = SC_ERROR_INVALID_DATA; - goto err; } ptemp++; templen--; From c6a9b5699a39835147a5097044ba63627638b93a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 3 Aug 2021 07:07:24 -0500 Subject: [PATCH 1927/4321] PIV-improved parsing - fix two whilhspace nits On branch PIV-improved-parsing Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 75044dec6c..8835078587 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2372,7 +2372,7 @@ static int piv_validate_general_authentication(sc_card_t *card, r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen); if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C"); - } + } r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen); if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) { @@ -2453,7 +2453,7 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, ptemp++; templen--; } - memcpy(out + nLen*i + nLen - templen , ptemp, templen); + memcpy(out + nLen*i + nLen - templen, ptemp, templen); pint += intlen; /* next integer */ } From 1e43a6a1afc7d8d049fe28760ba69c21ca7841d9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Aug 2021 09:17:35 +0200 Subject: [PATCH 1928/4321] Make sure the dist creates tarball for pushing artifacts --- .github/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/build.sh b/.github/build.sh index 014c345584..4e38b4fe11 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -43,6 +43,7 @@ make check # this is broken in old ubuntu if [ "$1" == "dist" ]; then make distcheck + make dist fi sudo make install From 3048156db0fd53f1efc8367e1a44ff65f691dcc0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Aug 2021 09:21:16 +0200 Subject: [PATCH 1929/4321] Execute push-artifacts on macos --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 27e1914f27..77725d0192 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -32,7 +32,7 @@ jobs: name: opensc-build-macos - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - - run: echo .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} # TODO this fails probably because the key is not loaded in keychain before with # security: SecKeychainDelete: The specified keychain could not be found. From 68b7efb591fff5f94c6801ae7ba2b6e16515f467 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Aug 2021 12:26:50 +0200 Subject: [PATCH 1930/4321] github actions: Unbreak migw builds --- .github/build.sh | 17 +++++++++-------- .github/setup-linux.sh | 7 ++++--- .github/workflows/linux.yml | 24 +++++++++++++++--------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 4e38b4fe11..99ffbc860c 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -32,13 +32,14 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then unset CC unset CXX ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=$PWD/win32/opensc || cat config.log; + make -j 2 + # no point in running tests on mingw +else + # normal procedure + ./configure --disable-dependency-tracking + make -j 2 + make check fi -# normal procedure -./configure --disable-dependency-tracking - -make -j 2 - -make check # this is broken in old ubuntu if [ "$1" == "dist" ]; then @@ -47,7 +48,7 @@ if [ "$1" == "dist" ]; then fi sudo make install - if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then - wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss + # pack installed files + wine "C:/Program Files/Inno Setup 5/ISCC.exe" win32/OpenSC.iss fi diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index a0f2fb104f..f20ade829e 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -14,11 +14,12 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " fi DEPS="$DEPS ant openjdk-8-jdk" elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + DEPS="$DEPS wine wine32 xvfb wget" sudo dpkg --add-architecture i386 if [ "$1" == "mingw" ]; then - DEPS="$DEPS wine wine32 binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" + DEPS="$DEPS binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" elif [ "$1" == "mingw32" ]; then - DEPS="$DEPS wine wine32 binutils-mingw-w64-i686 gcc-mingw-w64-i686" + DEPS="$DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686" fi fi @@ -28,7 +29,7 @@ sudo apt-get update sudo apt-get install -y build-essential $DEPS if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then - if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then + if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 export DISPLAY=:99.0 [ -d isetup ] || mkdir isetup diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index cd7bc36bf1..89864425d7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -38,11 +38,12 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh mingw - run: .github/build.sh mingw - - uses: actions/cache@v2 - id: cache-build + - name: Cache build artifacts + uses: actions/upload-artifact@v2 with: - path: ./* - key: ${{ runner.os }}-${{ github.sha }} + name: opensc-build-mingw + path: + win32/Output/OpenSC*.exe build-mingw32: runs-on: ubuntu-latest @@ -50,11 +51,12 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - - uses: actions/cache@v2 - id: cache-build + - name: Cache build artifacts + uses: actions/upload-artifact@v2 with: - path: ./* - key: ${{ runner.os }}-${{ github.sha }} + name: opensc-build-mingw32 + path: + win32/Output/OpenSC*.exe test-piv: runs-on: ubuntu-18.04 @@ -150,7 +152,7 @@ jobs: push-artifacts: runs-on: ubuntu-latest - needs: [build, build-mingw, build-mingw32] + needs: [build, build-mingw] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 @@ -158,6 +160,10 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - name: Pull mingw build artifacts + uses: actions/download-artifact@v2 + with: + name: opensc-build-mingw - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" From b67261ab27d286cfba327b24a08e1333b6b8e631 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Aug 2021 14:48:00 +0200 Subject: [PATCH 1931/4321] Upload also tarball as a build artifact --- .github/workflows/linux.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 89864425d7..ad0e36078e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -19,6 +19,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: opensc-build + path: + opensc*.tar.gz build-ubuntu-18: runs-on: ubuntu-18.04 From 4c923c637c95411a95b396bd897f6097c30f4c47 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 6 Aug 2021 13:53:49 -0500 Subject: [PATCH 1932/4321] log.c - fix newline - Fixes:#2378 On branch Fix-new-line Changes to be committed: modified: log.c --- src/libopensc/log.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 32def516f5..b5a3f1635b 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -143,6 +143,8 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin } sc_color_fprintf_va(color, ctx, ctx->debug_file, format, args); + if (strlen(format) == 0 || format[strlen(format) - 1] != '\n') + sc_color_fprintf(color, ctx, ctx->debug_file, "\n"); fflush(ctx->debug_file); #ifdef _WIN32 From 6431f69dcc89edbe7c650ebb30018c34cdd091e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Sat, 17 Jul 2021 13:12:48 +0300 Subject: [PATCH 1933/4321] pkcs11-spy: Fix crash for pMechanism=NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some test suites are excercising pMechanism==NULL case and this causes crash when using pkcs11-spy for logging in between. Centralize logging for pMechanism and handle NULL case. Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-spy.c | 271 +++++++++++++++++++--------------------- 1 file changed, 126 insertions(+), 145 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index b924bd74c3..b4434bf0f6 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -400,6 +400,116 @@ spy_attribute_list_out(const char *name, CK_ATTRIBUTE_PTR pTemplate, print_attribute_list(spy_output, pTemplate, ulCount); } +static void +spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) +{ + if (!pMechanism) { + fprintf(spy_output, "[in] %s=(null)\n", name); + return; + } + + fprintf(spy_output, "[in] %s->type=%s\n", name, lookup_enum(MEC_T, pMechanism->mechanism)); + switch (pMechanism->mechanism) { + case CKM_AES_GCM: + if (pMechanism->pParameter != NULL) { + CK_GCM_PARAMS *param = + (CK_GCM_PARAMS *) pMechanism->pParameter; + spy_dump_string_in("pIv[ulIvLen]", + param->pIv, param->ulIvLen); + spy_dump_ulong_in("ulIvBits", param->ulIvBits); + spy_dump_string_in("pAAD[ulAADLen]", + param->pAAD, param->ulAADLen); + fprintf(spy_output, "[in] %s->pParameter->ulTagBits=%lu\n", name, param->ulTagBits); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; + case CKM_ECDH1_DERIVE: + case CKM_ECDH1_COFACTOR_DERIVE: + if (pMechanism->pParameter != NULL) { + CK_ECDH1_DERIVE_PARAMS *param = + (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter = {\n\tkdf=%s\n", name, + lookup_enum(CKD_T, param->kdf)); + fprintf(spy_output, "\tpSharedData[ulSharedDataLen] = "); + print_generic(spy_output, 0, param->pSharedData, + param->ulSharedDataLen, NULL); + fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + print_generic(spy_output, 0, param->pPublicData, + param->ulPublicDataLen, NULL); + fprintf(spy_output, "}\n"); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; + case CKM_ECMQV_DERIVE: + if (pMechanism->pParameter != NULL) { + CK_ECMQV_DERIVE_PARAMS *param = + (CK_ECMQV_DERIVE_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter = {\n\tkdf=%s\n", name, + lookup_enum(CKD_T, param->kdf)); + fprintf(spy_output, "\tpSharedData[ulSharedDataLen] ="); + print_generic(spy_output, 0, param->pSharedData, + param->ulSharedDataLen, NULL); + fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + print_generic(spy_output, 0, param->pPublicData, + param->ulPublicDataLen, NULL); + fprintf(spy_output, "\tulPrivateDataLen = %lu", + param->ulPrivateDataLen); + fprintf(spy_output, "\thPrivateData = %lu", param->hPrivateData); + fprintf(spy_output, "\tpPublicData2[ulPublicDataLen2] = "); + print_generic(spy_output, 0, param->pPublicData2, + param->ulPublicDataLen2, NULL); + fprintf(spy_output, "\tpublicKey = %lu", param->publicKey); + fprintf(spy_output, "}\n"); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; + case CKM_RSA_PKCS_OAEP: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_OAEP_PARAMS *param = + (CK_RSA_PKCS_OAEP_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hashAlg=%s\n", name, + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "[in] %s->pParameter->mgf=%s\n", name, + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "[in] %s->pParameter->source=%lu\n", name, param->source); + spy_dump_string_out("pSourceData[ulSourceDalaLen]", + param->pSourceData, param->ulSourceDataLen); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_PSS_PARAMS *param = + (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hashAlg=%s\n", name, + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "[in] %s->pParameter->mgf=%s\n", name, + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "[in] %s->pParameter->sLen=%lu\n", name, + param->sLen); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; + default: + spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); + break; + } +} + static void print_ptr_in(const char *name, CK_VOID_PTR ptr) { @@ -853,27 +963,7 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_EncryptInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - switch (pMechanism->mechanism) { - case CKM_AES_GCM: - if (pMechanism->pParameter != NULL) { - CK_GCM_PARAMS *param = - (CK_GCM_PARAMS *) pMechanism->pParameter; - spy_dump_string_in("pIv[ulIvLen]", - param->pIv, param->ulIvLen); - spy_dump_ulong_in("ulIvBits", param->ulIvBits); - spy_dump_string_in("pAAD[ulAADLen]", - param->pAAD, param->ulAADLen); - fprintf(spy_output, "pMechanism->pParameter->ulTagBits=%lu\n", param->ulTagBits); - } else { - fprintf(spy_output, "Parameters block for %s is empty...\n", - lookup_enum(MEC_T, pMechanism->mechanism)); - } - break; - default: - spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); - break; - } + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_EncryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -931,28 +1021,7 @@ C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_DecryptInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS_OAEP: - if (pMechanism->pParameter != NULL) { - CK_RSA_PKCS_OAEP_PARAMS *param = - (CK_RSA_PKCS_OAEP_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "pMechanism->pParameter->source=%lu\n", param->source); - spy_dump_string_out("pSourceData[ulSourceDalaLen]", - param->pSourceData, param->ulSourceDataLen); - } else { - fprintf(spy_output, "Parameters block for %s is empty...\n", - lookup_enum(MEC_T, pMechanism->mechanism)); - } - break; - default: - spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); - break; - } + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_DecryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1011,7 +1080,7 @@ C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) enter("C_DigestInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); rv = po->C_DigestInit(hSession, pMechanism); return retne(rv); } @@ -1077,28 +1146,7 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA enter("C_SignInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS_PSS: - case CKM_SHA1_RSA_PKCS_PSS: - case CKM_SHA256_RSA_PKCS_PSS: - case CKM_SHA384_RSA_PKCS_PSS: - case CKM_SHA512_RSA_PKCS_PSS: - if (pMechanism->pParameter != NULL) { - CK_RSA_PKCS_PSS_PARAMS *param = - (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", - param->sLen); - } else { - fprintf(spy_output, "Parameters block for %s is empty...\n", - lookup_enum(MEC_T, pMechanism->mechanism)); - } - break; - } + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_SignInit(hSession, pMechanism, hKey); return retne(rv); @@ -1153,8 +1201,7 @@ C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OB enter("C_SignRecoverInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", - lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_SignRecoverInit(hSession, pMechanism, hKey); return retne(rv); @@ -1182,28 +1229,7 @@ C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_ enter("C_VerifyInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS_PSS: - case CKM_SHA1_RSA_PKCS_PSS: - case CKM_SHA256_RSA_PKCS_PSS: - case CKM_SHA384_RSA_PKCS_PSS: - case CKM_SHA512_RSA_PKCS_PSS: - if (pMechanism->pParameter != NULL) { - CK_RSA_PKCS_PSS_PARAMS *param = - (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", - param->sLen); - } else { - fprintf(spy_output, "Parameters block for %s is empty...\n", - lookup_enum(MEC_T, pMechanism->mechanism)); - } - break; - } + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_VerifyInit(hSession, pMechanism, hKey); return retne(rv); @@ -1256,7 +1282,7 @@ C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_VerifyRecoverInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_VerifyRecoverInit(hSession, pMechanism, hKey); return retne(rv); @@ -1349,7 +1375,7 @@ C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_GenerateKey"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_attribute_list_in("pTemplate", pTemplate, ulCount); rv = po->C_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey); if (rv == CKR_OK) @@ -1368,7 +1394,7 @@ C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_GenerateKeyPair"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_attribute_list_in("pPublicKeyTemplate", pPublicKeyTemplate, ulPublicKeyAttributeCount); spy_attribute_list_in("pPrivateKeyTemplate", pPrivateKeyTemplate, ulPrivateKeyAttributeCount); rv = po->C_GenerateKeyPair(hSession, pMechanism, @@ -1391,7 +1417,7 @@ C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_WrapKey"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hWrappingKey", hWrappingKey); spy_dump_ulong_in("hKey", hKey); rv = po->C_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); @@ -1411,7 +1437,7 @@ C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_UnwrapKey"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hUnwrappingKey", hUnwrappingKey); spy_dump_string_in("pWrappedKey[ulWrappedKeyLen]", pWrappedKey, ulWrappedKeyLen); spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); @@ -1430,52 +1456,7 @@ C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_H enter("C_DeriveKey"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "[in] pMechanism->type=%s\n", - lookup_enum(MEC_T, pMechanism->mechanism)); - switch (pMechanism->mechanism) { - case CKM_ECDH1_DERIVE: - case CKM_ECDH1_COFACTOR_DERIVE: - if (pMechanism->pParameter == NULL) { - fprintf(spy_output, "[in] pMechanism->pParameter = NULL\n"); - break; - } - CK_ECDH1_DERIVE_PARAMS *param = - (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] pMechanism->pParameter = {\n\tkdf=%s\n", - lookup_enum(CKD_T, param->kdf)); - fprintf(spy_output, "\tpSharedData[ulSharedDataLen] = "); - print_generic(spy_output, 0, param->pSharedData, - param->ulSharedDataLen, NULL); - fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); - print_generic(spy_output, 0, param->pPublicData, - param->ulPublicDataLen, NULL); - fprintf(spy_output, "}\n"); - break; - case CKM_ECMQV_DERIVE: - if (pMechanism->pParameter == NULL) { - fprintf(spy_output, "[in] pMechanism->pParameter = NULL\n"); - break; - } - CK_ECMQV_DERIVE_PARAMS *param2 = - (CK_ECMQV_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] pMechanism->pParameter = {\n\tkdf=%s\n", - lookup_enum(CKD_T, param2->kdf)); - fprintf(spy_output, "\tpSharedData[ulSharedDataLen] ="); - print_generic(spy_output, 0, param2->pSharedData, - param2->ulSharedDataLen, NULL); - fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); - print_generic(spy_output, 0, param2->pPublicData, - param2->ulPublicDataLen, NULL); - fprintf(spy_output, "\tulPrivateDataLen = %lu", - param2->ulPrivateDataLen); - fprintf(spy_output, "\thPrivateData = %lu", param2->hPrivateData); - fprintf(spy_output, "\tpPublicData2[ulPublicDataLen2] = "); - print_generic(spy_output, 0, param2->pPublicData2, - param2->ulPublicDataLen2, NULL); - fprintf(spy_output, "\tpublicKey = %lu", param2->publicKey); - fprintf(spy_output, "}\n"); - break; - } + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hBaseKey", hBaseKey); spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); rv = po->C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); @@ -1696,7 +1677,7 @@ C_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK enter("C_MessageEncryptInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageEncryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1779,7 +1760,7 @@ C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK enter("C_MessageDecryptInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageDecryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1862,7 +1843,7 @@ C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OB enter("C_MessageSignInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageSignInit(hSession, pMechanism, hKey); return retne(rv); @@ -1934,7 +1915,7 @@ C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ enter("C_MessageVerifyInit"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + spy_dump_mechanism_in("pMechanism", pMechanism); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageVerifyInit(hSession, pMechanism, hKey); return retne(rv); From 1991fa24ae6a362a448205d55b7132575c660883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Tue, 3 Aug 2021 19:09:19 +0300 Subject: [PATCH 1934/4321] [merge] new output for pMechas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-spy.c | 57 ++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index b4434bf0f6..b17e54c712 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -403,23 +403,28 @@ spy_attribute_list_out(const char *name, CK_ATTRIBUTE_PTR pTemplate, static void spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) { + char param_name[64]; + if (!pMechanism) { - fprintf(spy_output, "[in] %s=(null)\n", name); + fprintf(spy_output, "[in] %s = NULL\n", name); return; } - fprintf(spy_output, "[in] %s->type=%s\n", name, lookup_enum(MEC_T, pMechanism->mechanism)); + fprintf(spy_output, "[in] %s->type = %s\n", name, lookup_enum(MEC_T, pMechanism->mechanism)); switch (pMechanism->mechanism) { case CKM_AES_GCM: if (pMechanism->pParameter != NULL) { CK_GCM_PARAMS *param = (CK_GCM_PARAMS *) pMechanism->pParameter; - spy_dump_string_in("pIv[ulIvLen]", + snprintf(param_name, sizeof(param_name), "%s->pParameter->pIv[ulIvLen]", name); + spy_dump_string_in(param_name, param->pIv, param->ulIvLen); - spy_dump_ulong_in("ulIvBits", param->ulIvBits); - spy_dump_string_in("pAAD[ulAADLen]", + snprintf(param_name, sizeof(param_name), "%s->pParameter->ulIvBits", name); + spy_dump_ulong_in(param_name, param->ulIvBits); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pAAD[ulAADLen]", name); + spy_dump_string_in(param_name, param->pAAD, param->ulAADLen); - fprintf(spy_output, "[in] %s->pParameter->ulTagBits=%lu\n", name, param->ulTagBits); + fprintf(spy_output, "[in] %s->pParameter->ulTagBits = %lu\n", name, param->ulTagBits); } else { fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); break; @@ -430,15 +435,14 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) if (pMechanism->pParameter != NULL) { CK_ECDH1_DERIVE_PARAMS *param = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter = {\n\tkdf=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); - fprintf(spy_output, "\tpSharedData[ulSharedDataLen] = "); + fprintf(spy_output, "[in] %s->pParameter->pSharedData[ulSharedDataLen] = ", name); print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); - fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + fprintf(spy_output, "[in] %s->pParameter->pPublicData[ulPublicDataLen] = ", name); print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); - fprintf(spy_output, "}\n"); } else { fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); break; @@ -448,22 +452,21 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) if (pMechanism->pParameter != NULL) { CK_ECMQV_DERIVE_PARAMS *param = (CK_ECMQV_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter = {\n\tkdf=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); - fprintf(spy_output, "\tpSharedData[ulSharedDataLen] ="); + fprintf(spy_output, "%s->pParameter->pSharedData[ulSharedDataLen] = ", name); print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); - fprintf(spy_output, "\tpPublicData[ulPublicDataLen] = "); + fprintf(spy_output, "%s->pParameter->pPublicData[ulPublicDataLen] = ", name); print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); - fprintf(spy_output, "\tulPrivateDataLen = %lu", + fprintf(spy_output, "%s->pParameter->ulPrivateDataLen = %lu", name, param->ulPrivateDataLen); - fprintf(spy_output, "\thPrivateData = %lu", param->hPrivateData); - fprintf(spy_output, "\tpPublicData2[ulPublicDataLen2] = "); + fprintf(spy_output, "%s->pParameter->hPrivateData = %lu", name, param->hPrivateData); + fprintf(spy_output, "%s->pParameter->pPublicData2[ulPublicDataLen2] = ", name); print_generic(spy_output, 0, param->pPublicData2, param->ulPublicDataLen2, NULL); - fprintf(spy_output, "\tpublicKey = %lu", param->publicKey); - fprintf(spy_output, "}\n"); + fprintf(spy_output, "%s->pParameter->publicKey = %lu", name, param->publicKey); } else { fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); break; @@ -473,12 +476,13 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) if (pMechanism->pParameter != NULL) { CK_RSA_PKCS_OAEP_PARAMS *param = (CK_RSA_PKCS_OAEP_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->hashAlg=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "[in] %s->pParameter->mgf=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "[in] %s->pParameter->source=%lu\n", name, param->source); - spy_dump_string_out("pSourceData[ulSourceDalaLen]", + fprintf(spy_output, "[in] %s->pParameter->source = %lu\n", name, param->source); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pSourceData[ulSourceDalaLen]", name); + spy_dump_string_in(param_name, param->pSourceData, param->ulSourceDataLen); } else { fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); @@ -493,11 +497,11 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) if (pMechanism->pParameter != NULL) { CK_RSA_PKCS_PSS_PARAMS *param = (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->hashAlg=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "[in] %s->pParameter->mgf=%s\n", name, + fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "[in] %s->pParameter->sLen=%lu\n", name, + fprintf(spy_output, "[in] %s->pParameter->sLen = %lu\n", name, param->sLen); } else { fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); @@ -505,7 +509,8 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) } break; default: - spy_dump_string_in("pParameter[ulParameterLen]", pMechanism->pParameter, pMechanism->ulParameterLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); break; } } From 7007eda0baa6c1a2d9ef5dfca3adddc32f86bfe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Tue, 3 Aug 2021 19:51:47 +0300 Subject: [PATCH 1935/4321] pkcs11-spy: fix random crash in print_generic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on stack state print_generic() could cause crash or spurious garbage in logs. Example crash: *** buffer overflow detected ***: pkcs11test terminated Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 15e16de387..0117228d86 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -141,7 +141,8 @@ print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P CK_ULONG i; if((CK_LONG)size != -1 && value != NULL) { - char hex[16*3+1], ascii[16+1]; + char hex[16*3+1] = {0}; + char ascii[16+1]; char *hex_ptr = hex, *ascii_ptr = ascii; int offset = 0; From 1b344a4847980ef667dc1989fa59ee5d3125f183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Wed, 4 Aug 2021 16:32:43 +0300 Subject: [PATCH 1936/4321] pkcs11-spy: Fix C_GetFunctionList() crash with NULL argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In real world ppFunctionList=NULL case is only used by PKCS#11 test suites but no need to crash them. Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-spy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index b17e54c712..74f58414e2 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -531,6 +531,8 @@ CK_RV C_GetFunctionList } enter("C_GetFunctionList"); + if (ppFunctionList == NULL) + return retne(CKR_ARGUMENTS_BAD); *ppFunctionList = pkcs11_spy; return retne(CKR_OK); } From 63a5a493a63e9c85e6eede183235ab8e11a15e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Wed, 4 Aug 2021 16:58:11 +0300 Subject: [PATCH 1937/4321] pkcs11-spy: Match formatting for C_OpenSession() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match spacing and add [in] to argument dumps. Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-spy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 74f58414e2..c1fc8bdee9 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -723,8 +723,8 @@ C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, enter("C_OpenSession"); spy_dump_ulong_in("slotID", slotID); spy_dump_ulong_in("flags", flags); - fprintf(spy_output, "pApplication=%p\n", pApplication); - fprintf(spy_output, "Notify=%p\n", (void *)Notify); + fprintf(spy_output, "[in] pApplication = %p\n", pApplication); + fprintf(spy_output, "[in] Notify = %p\n", (void *)Notify); rv = po->C_OpenSession(slotID, flags, pApplication, Notify, phSession); spy_dump_ulong_out("*phSession", *phSession); return retne(rv); From cababca4d5e71a3729a5e1b80e41eaf0fc7bc992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Wed, 4 Aug 2021 16:38:15 +0300 Subject: [PATCH 1938/4321] pkcs11-spy: Fix C_OpenSession() crash with phSession=NULL argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In real world phSession=NULL case is only used by PKCS#11 test suites but no need to crash them. Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-spy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index c1fc8bdee9..8ca16bb660 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -726,7 +726,10 @@ C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, fprintf(spy_output, "[in] pApplication = %p\n", pApplication); fprintf(spy_output, "[in] Notify = %p\n", (void *)Notify); rv = po->C_OpenSession(slotID, flags, pApplication, Notify, phSession); - spy_dump_ulong_out("*phSession", *phSession); + if (phSession) + spy_dump_ulong_out("*phSession", *phSession); + else + fprintf(spy_output, "[out] phSession = %p\n", phSession); return retne(rv); } From e97fec4d91b1abd7bcf609070f16002ed91bce69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Wed, 4 Aug 2021 16:53:22 +0300 Subject: [PATCH 1939/4321] pkcs11-spy: Fix attribute displaying crash in case pTemplate=NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In real world pTemplate=NULL case is only used by PKCS#11 test suites but no need to crash them. Signed-off-by: Vesa Jääskeläinen --- src/pkcs11/pkcs11-display.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 0117228d86..9fa24a6c1b 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -1036,6 +1036,9 @@ print_attribute_list(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) CK_ULONG j, k; int found; + if (!pTemplate) + return; + for(j = 0; j < ulCount ; j++) { found = 0; for(k = 0; k < ck_attribute_num; k++) { @@ -1067,6 +1070,9 @@ print_attribute_list_req(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) CK_ULONG j, k; int found; + if (!pTemplate) + return; + for(j = 0; j < ulCount ; j++) { found = 0; for(k = 0; k < ck_attribute_num; k++) { From c902e1992195e00ada12d71beb1029287cd72037 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 9 Aug 2021 21:16:08 +0200 Subject: [PATCH 1940/4321] prepare 0.22.0 release --- NEWS | 3 ++- configure.ac | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f906687ca9..0f82a5ddb6 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.22.0; 2021-06-XX +# New in 0.22.0; 2021-08-10 ## General improvements * Use standard paths for file cache on Linux (#2148) and OSX (#2214) * Various issues of memory/buffer handling in legacy drivers mostly reported by oss-fuzz and coverity (tcos, oberthur, isoapplet, iasecc, westcos, gpk, flex, dnie, mcrd, authentic, belpic) @@ -11,6 +11,7 @@ NEWS for OpenSC -- History of user visible changes * Support for gcc11 and its new strict aliasing rules (#2241, #2260) * Initial support for building with OpenSSL 3.0 (#2343) * pkcs15-tool: Write data objects in binary mode (#2324) + * Avoid limited size of log messages (#2352) ## PKCS#11 * Support for ECDSA verification (#2211) * Support for ECDSA with different SHA hashes (#2190) diff --git a/configure.ac b/configure.ac index 4695dd62d7..5e2e604c0b 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [22]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc2]) +define([PACKAGE_SUFFIX], []) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) @@ -46,7 +46,7 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Oldest interface changed/removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) OPENSC_LT_CURRENT="8" -OPENSC_LT_OLDEST="7" +OPENSC_LT_OLDEST="8" OPENSC_LT_REVISION="0" OPENSC_LT_AGE="0" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" From 549359e137b318e5dcb182ae5b2a4c9a4ee38b16 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 3 Aug 2021 12:53:31 +0200 Subject: [PATCH 1941/4321] jcop: Remove old driver Remove due to no recent user and developer activity, last driver modification was f761d15 and no more changes except general were made. The driver was disabled in #1175. --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-jcop.c | 934 ------------------------------------- src/libopensc/cardctl.h | 14 - src/libopensc/cards.h | 5 - src/libopensc/ctx.c | 1 - 6 files changed, 3 insertions(+), 957 deletions(-) delete mode 100644 src/libopensc/card-jcop.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 40d77e58b2..933ff78f48 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -39,7 +39,7 @@ libopensc_la_SOURCES_BASE = \ \ card-setcos.c card-miocos.c card-flex.c card-gpk.c \ card-cardos.c card-tcos.c card-default.c \ - card-mcrd.c card-starcos.c card-openpgp.c card-jcop.c \ + card-mcrd.c card-starcos.c card-openpgp.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ card-piv.c card-cac-common.c card-cac.c card-cac1.c \ @@ -122,7 +122,7 @@ TIDY_FILES = \ \ card-setcos.c card-miocos.c card-flex.c card-gpk.c \ card-cardos.c card-tcos.c card-default.c \ - card-mcrd.c card-starcos.c card-jcop.c \ + card-mcrd.c card-starcos.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ card-cac-common.c card-cac.c card-cac1.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index b41ed23dcf..2a59375f82 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -16,7 +16,7 @@ OBJECTS = \ \ card-setcos.obj card-miocos.obj card-flex.obj card-gpk.obj \ card-cardos.obj card-tcos.obj card-default.obj \ - card-mcrd.obj card-starcos.obj card-openpgp.obj card-jcop.obj \ + card-mcrd.obj card-starcos.obj card-openpgp.obj \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj \ card-entersafe.obj card-epass2003.obj card-coolkey.obj \ card-incrypto34.obj card-cac.obj card-cac1.obj card-cac-common.obj \ diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c deleted file mode 100644 index 7cce62b6f2..0000000000 --- a/src/libopensc/card-jcop.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * card-jcop.c - * - * Copyright (C) 2003 Chaskiel Grundman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "internal.h" -#include "cardctl.h" - -static const struct sc_atr_table jcop_atrs[] = { - { "3B:E6:00:FF:81:31:FE:45:4A:43:4F:50:33:31:06", NULL, NULL, SC_CARD_TYPE_JCOP_GENERIC, 0, NULL }, - { NULL, NULL, NULL, 0, 0, NULL } -}; - -static struct sc_card_operations jcop_ops; -static struct sc_card_driver jcop_drv = { - "JCOP cards with BlueZ PKCS#15 applet", - "jcop", - &jcop_ops, - NULL, 0, NULL -}; - -#define SELECT_MF 0 -#define SELECT_EFDIR 1 -#define SELECT_APPDF 2 -#define SELECT_EF 3 -#define SELECT_UNKNOWN 4 -#define SELECTING_TARGET 0xf -#define SELECTING_ABS 0x80 -#define SELECTING_VIA_APPDF 0x100 - -struct jcop_private_data -{ - sc_file_t *virtmf; - sc_file_t *virtdir; - sc_path_t aid; - int selected; - int invalid_senv; - int nfiles; - u8 *filelist; -}; -#define DRVDATA(card) ((struct jcop_private_data *) ((card)->drv_data)) - -static int jcop_finish(sc_card_t *card) -{ - struct jcop_private_data *drvdata=DRVDATA(card); - if (drvdata) { - sc_file_free(drvdata->virtmf); - sc_file_free(drvdata->virtdir); - free(drvdata); - card->drv_data=NULL; - } - - return 0; -} - -static int jcop_match_card(sc_card_t *card) -{ - int i; - - i = _sc_match_atr(card, jcop_atrs, &card->type); - if (i < 0) - return 0; - return 1; -} - -static unsigned char ef_dir_contents[128] = { - 0x61, 0x21, - 0x4f, 0xc, 0xA0, 0x0, 0x0, 0x0, 0x63, 'P', 'K', 'C', 'S', '-', '1', '5', - 0x50, 0xb, 'O', 'p', 'e', 'n', 'S', 'C', ' ', 'C', 'a', 'r', 'd', - 0x51, 0x04, 0x3f, 0x00, 0x50, 0x15 -}; - - -static int jcop_init(sc_card_t *card) -{ - struct jcop_private_data *drvdata; - sc_file_t *f; - int flags; - - drvdata=malloc(sizeof(struct jcop_private_data)); - if (!drvdata) - return SC_ERROR_OUT_OF_MEMORY; - memset(drvdata, 0, sizeof(struct jcop_private_data)); - - sc_format_path("A000:0000:6350:4B43:532D:3135", &drvdata->aid); - drvdata->aid.type = SC_PATH_TYPE_DF_NAME; - drvdata->selected=SELECT_MF; - drvdata->invalid_senv=1; - drvdata->nfiles=-1; - drvdata->filelist=NULL; - f=sc_file_new(); - if (!f){ - free(drvdata); - return SC_ERROR_OUT_OF_MEMORY; - } - - sc_format_path("3f00", &f->path); - f->type=SC_FILE_TYPE_DF; - f->shareable=0; - f->ef_structure=SC_FILE_EF_UNKNOWN; - f->size=0; - f->id=0x3f00; - f->status=SC_FILE_STATUS_ACTIVATED; - sc_file_add_acl_entry(f, SC_AC_OP_SELECT, SC_AC_NONE, 0); - sc_file_add_acl_entry(f, SC_AC_OP_LIST_FILES, SC_AC_NONE, 0); - sc_file_add_acl_entry(f, SC_AC_OP_LOCK, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_DELETE, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_CREATE, SC_AC_NEVER, 0); - - drvdata->virtmf=f; - - f=sc_file_new(); - if (!f){ - sc_file_free(drvdata->virtmf); - free(drvdata); - return SC_ERROR_OUT_OF_MEMORY; - } - - sc_format_path("3f002f00", &f->path); - f->type=SC_FILE_TYPE_WORKING_EF; - f->shareable=0; - f->ef_structure=SC_FILE_EF_TRANSPARENT; - f->size=128; - f->id=0x2f00; - f->status=SC_FILE_STATUS_ACTIVATED; - sc_file_add_acl_entry(f, SC_AC_OP_READ, SC_AC_NONE, 0); - sc_file_add_acl_entry(f, SC_AC_OP_LOCK, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_ERASE, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_UPDATE, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_WRITE, SC_AC_NEVER, 0); - sc_file_add_acl_entry(f, SC_AC_OP_CRYPTO, SC_AC_NEVER, 0); - - drvdata->virtdir=f; - - - card->drv_data = drvdata; - card->cla = 0x00; - - /* card supports host-side padding, but not raw rsa */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1; - flags |= SC_ALGORITHM_RSA_HASH_NONE; - flags |= SC_ALGORITHM_RSA_HASH_SHA1; - flags |= SC_ALGORITHM_RSA_HASH_MD5; - /* only supports keygen with 3 and F-4 exponents */ - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - _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); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - /* State that we have an RNG */ - card->caps |= SC_CARD_CAP_RNG; - - return 0; -} - -static int jcop_get_default_key(sc_card_t *card, - struct sc_cardctl_default_key *data) -{ - const char *key; - - if (data->method != SC_AC_PRO || data->key_ref > 2) - return SC_ERROR_NO_DEFAULT_KEY; - - key = "40:41:42:43:44:45:46:47:48:49:4A:4B:4C:4D:4E:4F"; - return sc_hex_to_bin(key, data->key_data, &data->len); -} - -/* since the card is actually a javacard, we're expected to use ISO - 7816-4 direct application selection instead of reading the DIR - ourselves and selecting the AppDF by path. Since opensc doesn' do - that, I fake an MF containing the AppDF and a fixed DIR pointing at - the fake AppDF. This has the added advantage of allowing - opensc-explorer to be used with this driver */ -static int jcop_select_file(sc_card_t *card, const sc_path_t *path, - sc_file_t **file) -{ - struct jcop_private_data *drvdata=DRVDATA(card); - int r,selecting; - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - sc_path_t shortpath; - sc_file_t *tfile, **fileptr; - - if (!drvdata) - return SC_ERROR_FILE_NOT_FOUND; - - /* Something about the card does not like Case 4 APDU's to be sent as - Case 3. you must send a length and accept a response. */ - - if (file) { - fileptr=file; - } else { - fileptr=&tfile; - } - - /* Selecting the MF. return a copy of the constructed MF */ - if (path->len == 2 && memcmp(path->value, "\x3F\x00", 2) == 0) { - drvdata->selected=SELECT_MF; - if (file) { - sc_file_dup(file, drvdata->virtmf); - if (*file == NULL) - return SC_ERROR_OUT_OF_MEMORY; - } - return 0; - } - /* Selecting the EF(DIR). return a copy of the constructed EF(DIR) */ - if ((path->len == 4 && - memcmp(path->value, "\x3F\x00\x2F\x00", 4) == 0) || - (drvdata->selected == SELECT_MF && path->len == 2 && - memcmp(path->value, "\x2F\x00", 2) == 0)) { - drvdata->selected=SELECT_EFDIR; - if (file) { - sc_file_dup(file, drvdata->virtdir); - if (*file == NULL) - return SC_ERROR_OUT_OF_MEMORY; - } - return 0; - } - /* selecting the PKCS15 AppDF or a file in it. Select the applet, then - pass through any remaining path components to the applet's select - command - */ - selecting=SELECT_UNKNOWN; - - if (path->len >= 4 && - memcmp(path->value, "\x3F\x00\x50\x15", 4) == 0) { - if (path->len == 4) - selecting = SELECTING_ABS | SELECT_APPDF; - else - selecting = SELECTING_ABS | SELECT_EF; - } - - if (drvdata->selected==SELECT_MF && - memcmp(path->value, "\x50\x15", 2) == 0) { - if (path->len == 2) - selecting = SELECTING_VIA_APPDF | SELECT_APPDF; - else - selecting = SELECTING_VIA_APPDF | SELECT_EF; - } - - if (selecting & (SELECTING_ABS|SELECTING_VIA_APPDF)) - { - if (file == NULL && - (selecting & SELECTING_TARGET) == SELECT_APPDF && - drvdata->selected == SELECT_APPDF) { - return 0; - } - if ((r = iso_ops->select_file(card, &drvdata->aid, fileptr)) < 0) - return r; - if (fileptr && (selecting & SELECTING_TARGET) == SELECT_APPDF) { - (*fileptr)->type = SC_FILE_TYPE_DF; - drvdata->selected=SELECT_APPDF; - goto select_ok; - } - sc_file_free(*fileptr); - *fileptr=NULL; - memset(&shortpath, 0, sizeof(sc_path_t)); - if (selecting & SELECTING_ABS) { - memcpy(&shortpath.value, &path->value[4], path->len-4); - shortpath.len=path->len-4; - } else { - memcpy(&shortpath.value, &path->value[2], path->len-2); - shortpath.len=path->len-2; - } - shortpath.type = shortpath.len == 2 ? SC_PATH_TYPE_FILE_ID : - path->type; - shortpath.index=path->index; - shortpath.count=path->count; - path=&shortpath; - } else { - /* There seems to be better debugging output if I call sc_check_sw - * with appropriate input than if I just return the appropriate - * SC_ERROR_*, so that's what I do for all errors returned by code - * related to the MF/DIR emulation - */ - if (drvdata->selected == SELECT_MF || - drvdata->selected == SELECT_EFDIR) - return sc_check_sw(card, 0x6A, 0x82); - } - - r = iso_ops->select_file(card, path, fileptr); - if (r) - return r; - drvdata->selected=SELECT_EF; - select_ok: - if (!file) { - sc_file_free(*fileptr); - } - return 0; -} - -static int jcop_read_binary(sc_card_t *card, unsigned int idx, - u8 * buf, size_t count, unsigned long flags) { - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - int r; - - if (drvdata->selected == SELECT_MF) { - return sc_check_sw(card, 0x69, 0x86); - } - if (drvdata->selected == SELECT_EFDIR) { - if (idx > 127) { - return sc_check_sw(card, 0x6A, 0x86); - } - if (idx + count > 128) { - count=128-idx; - } - r = iso_ops->select_file(card, &drvdata->aid, NULL); - if (r < 0) { /* no pkcs15 app, so return empty DIR. */ - memset(buf, 0, count); - } else { - memcpy(buf, (u8 *)(ef_dir_contents + idx), count); - } - return count; - } - return iso_ops->read_binary(card, idx, buf, count, flags); -} - -static int jcop_list_files(sc_card_t *card, u8 *buf, size_t buflen) { - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - int r; - - if (drvdata->selected == SELECT_MF) { - if (buflen < 2) - return 0; - memcpy(buf, "\x2f\x00", 2); - if (buflen < 4) - return 2; - /* AppDF only exists if applet is selectable */ - r = iso_ops->select_file(card, &drvdata->aid, NULL); - if (r < 0) { - return 2; - } else { - memcpy(buf+2, "\x50\x15", 2); - return 4; - } - } - - if (drvdata->nfiles == -1) - return SC_ERROR_NOT_ALLOWED; - if (drvdata->nfiles == 0) - return 0; - if (buflen > 2 * (size_t)drvdata->nfiles) - buflen=2*drvdata->nfiles; - memcpy(buf, drvdata->filelist, buflen); - return buflen; -} - -static int sa_to_acl(sc_file_t *file, unsigned int operation, - int nibble) { - switch (nibble & 0x7) { - case 0: - sc_file_add_acl_entry(file, operation, SC_AC_NONE, SC_AC_KEY_REF_NONE); - break; - case 1: - sc_file_add_acl_entry(file, operation, SC_AC_NEVER, SC_AC_KEY_REF_NONE); - break; - case 2: - sc_file_add_acl_entry(file, operation, SC_AC_CHV, 1); - break; - case 3: - sc_file_add_acl_entry(file, operation, SC_AC_CHV, 2); - break; - case 4: - sc_file_add_acl_entry(file, operation, SC_AC_CHV, 3); - break; - case 5: - sc_file_add_acl_entry(file, operation, SC_AC_AUT, SC_AC_KEY_REF_NONE); - break; - case 6: - sc_file_add_acl_entry(file, operation, SC_AC_PRO, SC_AC_KEY_REF_NONE); - break; - default: - sc_file_add_acl_entry(file, operation, SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE); - } - return 0; -} - - -static int jcop_process_fci(sc_card_t *card, sc_file_t *file, - const u8 *buf, size_t buflen) { - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - u8 *sa; - int r; - - /* the FCI for EF's includes a bogus length for the overall structure! */ - if (buflen == 19) - buflen=24; - r=iso_ops->process_fci(card, file, buf, buflen); - - if (r < 0) - return r; - if (file->type != SC_FILE_TYPE_DF) { - if (drvdata->nfiles) { - drvdata->nfiles=-1; - free(drvdata->filelist); - drvdata->filelist=NULL; - } - if(file->sec_attr_len >=3) { - /* The security attribute bytes are divided into nibbles and are - as follows: - READ | MODIFY || SIGN | ENCIPHER || DECIPHER | DELETE - */ - sa=file->sec_attr; - sa_to_acl(file, SC_AC_OP_READ, sa[0] >> 4); - sa_to_acl(file, SC_AC_OP_UPDATE, sa[0] & 0xf); - /* Files may be locked by anyone who can MODIFY. */ - /* opensc seems to think LOCK ACs are only on DFs */ - /* sa_to_acl(file, SC_AC_OP_LOCK, sa[0] & 0xf); */ - /* there are separate SIGN, ENCIPHER, and DECIPHER ACs. - I use SIGN for SC_AC_OP_CRYPTO unless it is NEVER, in - which case I use DECIPHER */ - if ((sa[1] & 0xf0) == 0x10) - sa_to_acl(file, SC_AC_OP_CRYPTO, sa[1] >> 4); - else - sa_to_acl(file, SC_AC_OP_CRYPTO, sa[2] >> 4); - sa_to_acl(file, SC_AC_OP_ERASE, sa[2] & 0xf); - } - } else { - /* No AC information is reported for the AppDF */ - sc_file_add_acl_entry(file, SC_AC_OP_SELECT, SC_AC_NONE, 0); - sc_file_add_acl_entry(file, SC_AC_OP_CREATE, SC_AC_CHV, 3); - sc_file_add_acl_entry(file, SC_AC_OP_DELETE, SC_AC_NONE, 0); - sc_file_add_acl_entry(file, SC_AC_OP_LIST_FILES, SC_AC_NONE, 0); - if (drvdata->nfiles) { - drvdata->nfiles=0; - free(drvdata->filelist); - drvdata->filelist=NULL; - } - /* the format of the poprietary attributes is: - 4 bytes unique id - 1 byte # files in DF - 2 bytes 1st File ID - 2 bytes 2nd File ID - ... - */ - if (file->prop_attr_len > 4) { - int nfiles; - u8 *filelist; - nfiles=file->prop_attr[4]; - if (nfiles) { - filelist=malloc(2*nfiles); - if (!filelist) - return SC_ERROR_OUT_OF_MEMORY; - memcpy(filelist, &file->prop_attr[5], 2*nfiles); - drvdata->nfiles=nfiles; - drvdata->filelist=filelist; - } - } - } - - return r; -} -static int acl_to_ac_nibble(const sc_acl_entry_t *e) -{ - if (e == NULL) - return -1; - if (e->next != NULL) /* FIXME */ - return -1; - switch (e->method) { - case SC_AC_NONE: - return 0x00; - case SC_AC_NEVER: - return 0x01; - case SC_AC_CHV: - switch (e->key_ref) { - case 1: - return 0x02; - case 2: - return 0x03; - case 3: - return 0x04; - } - return -1; - case SC_AC_AUT: - return 0x05; - case SC_AC_PRO: - return 0x06; - } - return -1; -} - - -static int jcop_create_file(sc_card_t *card, sc_file_t *file) { - struct jcop_private_data *drvdata=DRVDATA(card); - unsigned char sec_attr_data[3]; - int ops[6]; - int i, r; - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - - if (drvdata->selected == SELECT_MF || drvdata->selected == SELECT_EFDIR ) - return sc_check_sw(card, 0x69, 0x82); - - /* Can't create DFs */ - if (file->type != SC_FILE_TYPE_WORKING_EF) - return sc_check_sw(card, 0x6A, 0x80); - - ops[0] = SC_AC_OP_READ; /* read */ - ops[1] = SC_AC_OP_UPDATE; /* modify */ - ops[2] = SC_AC_OP_CRYPTO; /* sign */ - ops[3] = -1; /* encipher */ - ops[4] = SC_AC_OP_CRYPTO; /* decipher */ - ops[5] = SC_AC_OP_ERASE; /* delete */ - memset(sec_attr_data, 0, 3); - for (i = 0; i < 6; i++) { - const sc_acl_entry_t *entry; - if (ops[i] == -1) { - sec_attr_data[i/2] |= 1 << ((i % 2) ? 0 : 4); - continue; - } - - entry = sc_file_get_acl_entry(file, ops[i]); - r = acl_to_ac_nibble(entry); - if (r >= 0) { - sec_attr_data[i/2] |= r << ((i % 2) ? 0 : 4); - } - } - - sc_file_set_sec_attr(file, sec_attr_data, 3); - - r=iso_ops->create_file(card, file); - if (r > 0) - drvdata->selected=SELECT_EF; - return r; -} - - -/* We need to trap these functions so that proper errors can be returned - when one of the virtual files is selected */ -static int jcop_write_binary(sc_card_t *card, - unsigned int idx, const u8 *buf, - size_t count, unsigned long flags) { - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - - if (drvdata->selected == SELECT_MF) - return sc_check_sw(card, 0x6A, 0x86); - if (drvdata->selected == SELECT_EFDIR) - return sc_check_sw(card, 0x69, 0x82); - - return iso_ops->write_binary(card, idx, buf, count, flags); -} - - -static int jcop_update_binary(sc_card_t *card, - unsigned int idx, const u8 *buf, - size_t count, unsigned long flags) { - - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - if (drvdata->selected == SELECT_MF) - return sc_check_sw(card, 0x69, 0x86); - if (drvdata->selected == SELECT_EFDIR) - return sc_check_sw(card, 0x69, 0x82); - - return iso_ops->update_binary(card, idx, buf, count, flags); -} - -static int jcop_delete_file(sc_card_t *card, const sc_path_t *path) { - struct jcop_private_data *drvdata=DRVDATA(card); - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - const struct sc_card_operations *iso_ops = iso_drv->ops; - - if (drvdata->selected == SELECT_MF || drvdata->selected == SELECT_EFDIR ) - return sc_check_sw(card, 0x69, 0x82); - - return iso_ops->delete_file(card, path); -} - - -/* BlueZ doesn't support stored security environments. you have - to construct one with SET every time */ -static int jcop_set_security_env(sc_card_t *card, - const sc_security_env_t *env, - int se_num) -{ - sc_apdu_t apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 *p; - int r; - struct jcop_private_data *drvdata=DRVDATA(card); - - assert(card != NULL && env != NULL); - if (se_num) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if (drvdata->selected == SELECT_MF || - drvdata->selected == SELECT_EFDIR) { - drvdata->invalid_senv=1; - return 0; - } - - if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - sc_security_env_t tmp; - - tmp = *env; - tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; - tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; - if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_log(card->ctx, "Only RSA algorithm supported.\n"); - return SC_ERROR_NOT_SUPPORTED; - } - if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)){ - sc_log(card->ctx, "Card requires RSA padding\n"); - return SC_ERROR_NOT_SUPPORTED; - } - tmp.algorithm_ref = 0x02; - /* potential FIXME: return an error, if an unsupported - * pad or hash was requested, although this shouldn't happen. - */ - if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) - tmp.algorithm_ref |= 0x10; - if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_MD5) - tmp.algorithm_ref |= 0x20; - - memcpy((sc_security_env_t *) env, &tmp, sizeof(struct sc_security_env)); - } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0); - switch (env->operation) { - case SC_SEC_OPERATION_DECIPHER: - apdu.p2 = 0xB8; - break; - case SC_SEC_OPERATION_SIGN: - apdu.p2 = 0xB6; - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - apdu.le = 0; - if (!(env->flags & SC_SEC_ENV_ALG_REF_PRESENT)) - return SC_ERROR_INVALID_ARGUMENTS; - if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT)) - return SC_ERROR_INVALID_ARGUMENTS; - if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { - if (env->key_ref_len > 1 || env->key_ref[0] != 0) - return SC_ERROR_INVALID_ARGUMENTS; - } - - p = sbuf; - *p++ = 0x80; /* algorithm reference */ - *p++ = 0x01; - *p++ = env->algorithm_ref & 0xFF; - - *p++ = 0x81; - *p++ = env->file_ref.len; - memcpy(p, env->file_ref.value, env->file_ref.len); - p += env->file_ref.len; - - r = p - sbuf; - apdu.lc = r; - apdu.datalen = r; - apdu.data = sbuf; - apdu.resplen = 0; - r = sc_transmit_apdu(card, &apdu); - if (r) { - sc_log(card->ctx, - "%s: APDU transmit failed", sc_strerror(r)); - return r; - } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) { - sc_log(card->ctx, - "%s: Card returned error", sc_strerror(r)); - return r; - } - drvdata->invalid_senv=0; - return 0; -} -static int jcop_compute_signature(sc_card_t *card, - const u8 * data, size_t datalen, - u8 * out, size_t outlen) { - - - int r; - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - struct jcop_private_data *drvdata=DRVDATA(card); - - assert(card != NULL && data != NULL && out != NULL); - if (datalen > 256) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - - if (drvdata->invalid_senv) - return sc_check_sw(card, 0x69, 0x88); - - /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x9E Resp: Digital Signature - * P2: 0x9A Cmd: Input for Digital Signature */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, - 0x9A); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); /* FIXME */ - apdu.le = 256; - if (datalen == 256) { - apdu.p2 = data[0]; - memcpy(sbuf, data+1, datalen-1); - apdu.lc = datalen - 1; - apdu.datalen = datalen - 1; - } else { - memcpy(sbuf, data, datalen); - apdu.lc = datalen; - apdu.datalen = datalen; - } - - apdu.data = sbuf; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - int len = apdu.resplen > outlen ? outlen : apdu.resplen; - - memcpy(out, apdu.resp, len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len); - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); -} - - - -static int jcop_decipher(sc_card_t *card, - const u8 * crgram, size_t crgram_len, - u8 * out, size_t outlen) { - - int r; - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - struct jcop_private_data *drvdata=DRVDATA(card); - - assert(card != NULL && crgram != NULL && out != NULL); - LOG_FUNC_CALLED(card->ctx); - if (crgram_len > 256) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - if (drvdata->invalid_senv) - return sc_check_sw(card, 0x69, 0x88); - - /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x80 Resp: Plain value - * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); /* FIXME */ - apdu.le = crgram_len; - - if (crgram_len == 256) { - apdu.p2 = crgram[0]; - memcpy(sbuf, crgram+1, crgram_len-1); - apdu.lc = crgram_len - 1; - apdu.datalen = crgram_len -1; - } else { - sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ - memcpy(sbuf + 1, crgram, crgram_len); - apdu.lc = crgram_len + 1; - apdu.datalen = crgram_len + 1; - } - - apdu.data = sbuf; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - int len = apdu.resplen > outlen ? outlen : apdu.resplen; - - memcpy(out, apdu.resp, len); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len); - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); -} - -static int jcop_generate_key(sc_card_t *card, struct sc_cardctl_jcop_genkey *a) { - int r; - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 *p; - int is_f4; - struct jcop_private_data *drvdata=DRVDATA(card); - - if (drvdata->selected == SELECT_MF || drvdata->selected == SELECT_EFDIR ) - return sc_check_sw(card, 0x6A, 0x82); - - is_f4=0; - - if (a->exponent == 0x10001) { - is_f4=1; - } else if (a->exponent != 3) { - sc_log(card->ctx, - "%s: Invalid exponent", sc_strerror(SC_ERROR_NOT_SUPPORTED)); - return SC_ERROR_NOT_SUPPORTED; - } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0xB6); - - p = sbuf; - *p++ = 0x80; /* algorithm reference */ - *p++ = 0x01; - *p++ = is_f4 ? 0x6E : 0x6D; - - *p++ = 0x81; - *p++ = a->pub_file_ref.len; - memcpy(p, a->pub_file_ref.value, a->pub_file_ref.len); - p += a->pub_file_ref.len; - - *p++ = 0x81; - *p++ = a->pri_file_ref.len; - memcpy(p, a->pri_file_ref.value, a->pri_file_ref.len); - p += a->pri_file_ref.len; - - r = p - sbuf; - - apdu.lc = r; - apdu.datalen = r; - apdu.data = sbuf; - apdu.resplen = 0; - r = sc_transmit_apdu(card, &apdu); - if (r) { - sc_log(card->ctx, - "%s: APDU transmit failed", sc_strerror(r)); - return r; - } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) { - sc_log(card->ctx, - "%s: Card returned error", sc_strerror(r)); - return r; - } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x46, 0, 0); - - apdu.le = 256; - apdu.resp=rbuf; - apdu.resplen = sizeof(rbuf); - - r = sc_transmit_apdu(card, &apdu); - if (r) { - sc_log(card->ctx, - "%s: APDU transmit failed", sc_strerror(r)); - return r; - } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) { - sc_log(card->ctx, - "%s: Card returned error", sc_strerror(r)); - return r; - } - - if (rbuf[0] != 0x4) { - return SC_ERROR_INVALID_DATA; - } - if (a->pubkey_len < rbuf[1]) - return SC_ERROR_BUFFER_TOO_SMALL; - a->pubkey_len=rbuf[1] * 4; - memcpy(a->pubkey, &rbuf[2], a->pubkey_len); - - return 0; -} - -static int jcop_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) -{ - switch (cmd) { - case SC_CARDCTL_GET_DEFAULT_KEY: - return jcop_get_default_key(card, - (struct sc_cardctl_default_key *) ptr); - case SC_CARDCTL_JCOP_GENERATE_KEY: - return jcop_generate_key(card, - (struct sc_cardctl_jcop_genkey *) ptr); - } - - return SC_ERROR_NOT_SUPPORTED; -} - -static struct sc_card_driver * sc_get_driver(void) -{ - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - - jcop_ops = *iso_drv->ops; - jcop_ops.match_card = jcop_match_card; - jcop_ops.init = jcop_init; - jcop_ops.finish = jcop_finish; - /* no record oriented file services */ - jcop_ops.read_record = NULL; - jcop_ops.write_record = NULL; - jcop_ops.append_record = NULL; - jcop_ops.update_record = NULL; - jcop_ops.read_binary = jcop_read_binary; - jcop_ops.write_binary = jcop_write_binary; - jcop_ops.update_binary = jcop_update_binary; - jcop_ops.select_file = jcop_select_file; - jcop_ops.create_file = jcop_create_file; - jcop_ops.delete_file = jcop_delete_file; - jcop_ops.list_files = jcop_list_files; - jcop_ops.set_security_env = jcop_set_security_env; - jcop_ops.compute_signature = jcop_compute_signature; - jcop_ops.decipher = jcop_decipher; - jcop_ops.process_fci = jcop_process_fci; - jcop_ops.card_ctl = jcop_card_ctl; - - return &jcop_drv; -} - -struct sc_card_driver * sc_get_jcop_driver(void) -{ - return sc_get_driver(); -} - diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 6d85afb2c1..a493977b7f 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -94,12 +94,6 @@ enum { SC_CARDCTL_STARCOS_WRITE_KEY, SC_CARDCTL_STARCOS_GENERATE_KEY, - /* - * JCOP specific calls - */ - SC_CARDCTL_JCOP_BASE = _CTL_PREFIX('J', 'C', 'P'), - SC_CARDCTL_JCOP_GENERATE_KEY, - /* * Oberthur specific calls */ @@ -501,14 +495,6 @@ typedef struct sc_starcos_gen_key_data_st { u8 *modulus; } sc_starcos_gen_key_data; -struct sc_cardctl_jcop_genkey { - unsigned long exponent; - sc_path_t pub_file_ref; - sc_path_t pri_file_ref; - unsigned char * pubkey; - unsigned int pubkey_len; -}; - /* * Oberthur ex_data stuff */ diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index f77928154b..4b3ce03c35 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -108,10 +108,6 @@ enum { SC_CARD_TYPE_OPENPGP_V3, SC_CARD_TYPE_OPENPGP_GNUK, - /* jcop driver */ - SC_CARD_TYPE_JCOP_BASE = 10000, - SC_CARD_TYPE_JCOP_GENERIC, - /* oberthur driver */ SC_CARD_TYPE_OBERTHUR_BASE = 11000, SC_CARD_TYPE_OBERTHUR_GENERIC, @@ -288,7 +284,6 @@ extern sc_card_driver_t *sc_get_setcos_driver(void); extern sc_card_driver_t *sc_get_starcos_driver(void); extern sc_card_driver_t *sc_get_tcos_driver(void); extern sc_card_driver_t *sc_get_openpgp_driver(void); -extern sc_card_driver_t *sc_get_jcop_driver(void); extern sc_card_driver_t *sc_get_oberthur_driver(void); extern sc_card_driver_t *sc_get_belpic_driver(void); extern sc_card_driver_t *sc_get_atrust_acos_driver(void); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index bddfdad77d..d4844a607c 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -162,7 +162,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { static const struct _sc_driver_entry old_card_drivers[] = { { "miocos", (void *(*)(void)) sc_get_miocos_driver }, - { "jcop", (void *(*)(void)) sc_get_jcop_driver }, { NULL, NULL } }; From ac7b02eacafec3c8e63c7ec4e827b6e8ac90e2ec Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 3 Aug 2021 13:01:00 +0200 Subject: [PATCH 1942/4321] jcop: Remove pkcs15init support Remove support for JCOP/BlueZ cards due to no recent user or developer activity except general fixes. --- src/libopensc/libopensc.exports | 1 - src/pkcs15init/Makefile.am | 3 +- src/pkcs15init/Makefile.mak | 2 +- src/pkcs15init/jcop.profile | 69 ------ src/pkcs15init/pkcs15-init.h | 1 - src/pkcs15init/pkcs15-jcop.c | 357 -------------------------------- src/pkcs15init/pkcs15-lib.c | 1 - win32/OpenSC.wxs.in | 4 - 8 files changed, 2 insertions(+), 436 deletions(-) delete mode 100644 src/pkcs15init/jcop.profile delete mode 100644 src/pkcs15init/pkcs15-jcop.c diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index ea463f5e9f..73173363c4 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -300,7 +300,6 @@ sc_pkcs15init_get_cyberflex_ops sc_pkcs15init_get_gpk_ops sc_pkcs15init_get_gids_ops sc_pkcs15init_get_incrypto34_ops -sc_pkcs15init_get_jcop_ops sc_pkcs15init_get_manufacturer sc_pkcs15init_get_miocos_ops sc_pkcs15init_get_muscle_ops diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 890020d443..4b85ba4f8f 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -12,7 +12,6 @@ dist_pkgdata_DATA = \ miocos.profile \ cardos.profile \ incrypto34.profile \ - jcop.profile \ oberthur.profile \ starcos.profile \ setcos.profile \ @@ -41,7 +40,7 @@ libpkcs15init_la_SOURCES = \ pkcs15-lib.c profile.c \ pkcs15-westcos.c \ pkcs15-gpk.c pkcs15-miocos.c pkcs15-cflex.c \ - pkcs15-cardos.c pkcs15-jcop.c pkcs15-starcos.c \ + pkcs15-cardos.c pkcs15-starcos.c \ pkcs15-setcos.c pkcs15-incrypto34.c pkcs15-muscle.c \ pkcs15-asepcos.c pkcs15-rutoken.c \ pkcs15-entersafe.c pkcs15-epass2003.c \ diff --git a/src/pkcs15init/Makefile.mak b/src/pkcs15init/Makefile.mak index 1eb6857f24..c79566c544 100644 --- a/src/pkcs15init/Makefile.mak +++ b/src/pkcs15init/Makefile.mak @@ -3,7 +3,7 @@ TOPDIR = ..\.. TARGET = pkcs15init.lib OBJECTS = pkcs15-lib.obj profile.obj \ pkcs15-gpk.obj pkcs15-miocos.obj pkcs15-cflex.obj \ - pkcs15-cardos.obj pkcs15-jcop.obj pkcs15-starcos.obj \ + pkcs15-cardos.obj pkcs15-starcos.obj \ pkcs15-oberthur.obj pkcs15-oberthur-awp.obj \ pkcs15-setcos.obj pkcs15-incrypto34.obj \ pkcs15-muscle.obj pkcs15-asepcos.obj pkcs15-rutoken.obj \ diff --git a/src/pkcs15init/jcop.profile b/src/pkcs15init/jcop.profile deleted file mode 100644 index eb2ae9524d..0000000000 --- a/src/pkcs15init/jcop.profile +++ /dev/null @@ -1,69 +0,0 @@ -# -# PKCS15 r/w profile for JCOP cards -# -cardinfo { - max-pin-length = 16; - pin-encoding = ascii-numeric; - pin-pad-char = 0x00; -} - -filesystem { - DF MF { - DF PKCS15-AppDF { - acl = *=NONE, CREATE=CHV3; - EF PKCS15-AODF { - file-id = 502E; - } - EF PKCS15-PrKDF { - file-id = 502C; - } - EF PKCS15-PuKDF { - file-id = 502B; - } - EF PKCS15-CDF { - file-id = 502D; - } - EF PKCS15-DODF { - file-id = 502F; - } - template key-domain { - EF private-key { - file-id = 3000; - acl = *=NEVER, UPDATE=$PIN, CRYPTO=$PIN, - ERASE=$SOPIN; - } - EF extractable-key { - file-id = 3100; - acl = *=NEVER, READ=$PIN, UPDATE=$PIN, - ERASE=$SOPIN; - } - EF data { - file-id = 3200; - acl = *=NEVER, UPDATE=$PIN, READ=NONE, - ERASE=$SOPIN; - } - EF privdata { - file-id = 3500; - acl = *=NEVER, UPDATE=$PIN, READ=$PIN, - ERASE=$SOPIN; - } - EF public-key { - file-id = 3300; - acl = *=NEVER, UPDATE=$PIN, READ=NONE, - ERASE=$SOPIN; - } - EF certificate { - file-id = 3400; - acl = *=NEVER, UPDATE=$PIN, READ=NONE, - ERASE=$SOPIN; - } - } - EF temp-pubkey { - file-id = 0000; - acl = *=NEVER, UPDATE=$PIN, READ=NONE, - ERASE=$SOPIN; - } - } - } -} - diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index e01ec99640..8dc256bd82 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -432,7 +432,6 @@ extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cyberflex_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cardos_ops(void); -extern struct sc_pkcs15init_operations *sc_pkcs15init_get_jcop_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_starcos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_oberthur_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_setcos_ops(void); diff --git a/src/pkcs15init/pkcs15-jcop.c b/src/pkcs15init/pkcs15-jcop.c deleted file mode 100644 index 40c33d68c2..0000000000 --- a/src/pkcs15init/pkcs15-jcop.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * JCOP specific operation for PKCS15 initialization - * - * Copyright 2003 Chaskiel Grundman - * Copyright (C) 2002 Olaf Kirch - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "libopensc/opensc.h" -#include "libopensc/cardctl.h" -#include "libopensc/log.h" -#include "pkcs15-init.h" -#include "profile.h" - -#define JCOP_MAX_PINS 3 - -/* - * Erase the card - */ -static int -jcop_erase_card(struct sc_profile *pro, sc_pkcs15_card_t *p15card) { - /* later */ - return SC_ERROR_NOT_SUPPORTED; -} - - -static int -jcop_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *file) -{ - return SC_ERROR_NOT_SUPPORTED; -}; - - -/* - * Select a PIN reference - */ -static int -jcop_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, - sc_pkcs15_auth_info_t *auth_info) { - int preferred, current; - - if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) - return SC_ERROR_OBJECT_NOT_VALID; - - if ((current = auth_info->attrs.pin.reference) < 0) - current = 0; - - if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - preferred = 3; - } else { - preferred = current; - if (preferred < 1) - preferred=1; - if (preferred > 2) - return SC_ERROR_TOO_MANY_OBJECTS; - } - if (current > preferred) - return SC_ERROR_TOO_MANY_OBJECTS; - auth_info->attrs.pin.reference = preferred; - return 0; -} - -/* - * Store a PIN - */ -static int -jcop_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, - sc_pkcs15_object_t *pin_obj, - const unsigned char *pin, size_t pin_len, - const unsigned char *puk, size_t puk_len) -{ - sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; - struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin; - unsigned char nulpin[16]; - unsigned char padpin[16]; - int r; - - if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) - return SC_ERROR_OBJECT_NOT_VALID; - - if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - /* SO PIN reference must be 0 */ - if (pin_attrs->reference != 3) - return SC_ERROR_INVALID_ARGUMENTS; - } else { - if (pin_attrs->reference >= 3) - return SC_ERROR_TOO_MANY_OBJECTS; - } - if (puk != NULL && puk_len > 0) { - return SC_ERROR_NOT_SUPPORTED; - } - r = sc_select_file(p15card->card, &df->path, NULL); - if (r < 0) - return r; - - /* Current PIN is 00:00:00:00:00:00:00:00... */ - memset(nulpin, 0, sizeof(nulpin)); - memset(padpin, 0, sizeof(padpin)); - memcpy(padpin, pin, pin_len); - r = sc_change_reference_data(p15card->card, SC_AC_CHV, - pin_attrs->reference, - nulpin, sizeof(nulpin), - padpin, sizeof(padpin), NULL); - if (r < 0) - return r; - - pin_attrs->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; - return r; -} - -/* - * Create a new key file - */ -static int -jcop_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj) -{ - sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - sc_file_t *keyfile = NULL; - size_t bytes, mod_len, prv_len; - int r; - - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); - return SC_ERROR_NOT_SUPPORTED; - } - /* The caller is supposed to have chosen a key file path for us */ - if (key_info->path.len == 0 || key_info->modulus_length == 0) - return SC_ERROR_INVALID_ARGUMENTS; - - /* Get the file we're supposed to create */ - r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); - if (r < 0) - return r; - - mod_len = key_info->modulus_length / 8; - bytes = mod_len / 2; - prv_len = 2 + 5 * bytes; - keyfile->size = prv_len; - - /* Fix up PIN references in file ACL */ - r = sc_pkcs15init_fixup_file(profile, p15card, keyfile); - - if (r >= 0) - r = sc_pkcs15init_create_file(profile, p15card, keyfile); - - sc_file_free(keyfile); - return r; -} - -static void -jcop_bn2bin(unsigned char *dest, sc_pkcs15_bignum_t *bn, unsigned int size) -{ - u8 *src; - unsigned int n; - - assert(bn->len <= size); - memset(dest, 0, size); - for (n = size-bn->len, src = bn->data; n < size; n++,src++) - dest[n] = *src; -} - -/* - * Store a private key - * Private key file formats: (transparent file) - * Non-CRT: - * byte 0 0x05 - * byte 1 Modulus length (in byte/4) - * byte 2 Modulus (n) - * byte 2+x private exponent (d) - * - * CRT: - * byte 0 0x06 - * byte 1 component length (in byte/2; component length is half - * of modulus length - * byte 2 Prime (p) - * byte 2+x Prime (q) - * byte 2+2*x Exponent 1 (d mod (p-1)) - * byte 2+3*x Exponent 2 (d mod (q-1)) - * byte 2+4*x Coefficient ((p ^ -1) mod q - * - * We use the CRT format, since that's what key generation does. - * - * Numbers are stored big endian. - */ -static int -jcop_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, - sc_pkcs15_object_t *obj, - sc_pkcs15_prkey_t *key) -{ - sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - sc_file_t *keyfile; - unsigned char keybuf[1024]; - size_t size,base; - int r; - - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); - return SC_ERROR_NOT_SUPPORTED; - } - r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); - if (r < 0) - return r; - base=key_info->modulus_length / 16; - size=2+5*base; - keybuf[0]=6; - keybuf[1]=base/4; - jcop_bn2bin(&keybuf[2 + 0 * base], &key->u.rsa.p, base); - jcop_bn2bin(&keybuf[2 + 1 * base], &key->u.rsa.q, base); - jcop_bn2bin(&keybuf[2 + 2 * base], &key->u.rsa.dmp1, base); - jcop_bn2bin(&keybuf[2 + 3 * base], &key->u.rsa.dmq1, base); - jcop_bn2bin(&keybuf[2 + 4 * base], &key->u.rsa.iqmp, base); - r = sc_pkcs15init_update_file(profile, p15card, keyfile, keybuf, size); - - sc_file_free(keyfile); - return r; -} - -/* - * Generate a key pair - */ -static int -jcop_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, - sc_pkcs15_object_t *obj, - sc_pkcs15_pubkey_t *pubkey) -{ - sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - struct sc_cardctl_jcop_genkey args; - sc_file_t *temppubfile=NULL, *keyfile=NULL; - unsigned char *keybuf=NULL; - size_t mod_len, exp_len, pub_len, keybits; - int r,delete_ok=0; - - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_log(p15card->card->ctx, "JCOP supports only RSA keys."); - return SC_ERROR_NOT_SUPPORTED; - } - - r=sc_profile_get_file(profile, "temp-pubkey", &temppubfile); - if (r < 0) - goto out; - - r = sc_select_file(p15card->card, &key_info->path, &keyfile); - if (r < 0) - goto out; - - mod_len = key_info->modulus_length / 8; - exp_len = 4; - pub_len = 2 + mod_len + exp_len; - temppubfile->size = pub_len; - - r = sc_pkcs15init_fixup_file(profile, p15card, temppubfile); - if (r < 0) - goto out; - - r = sc_pkcs15init_create_file(profile, p15card, temppubfile); - if (r < 0) - goto out; - - delete_ok=1; - r = sc_pkcs15init_authenticate(profile, p15card, temppubfile, SC_AC_OP_UPDATE); - if (r < 0) - goto out; - r = sc_pkcs15init_authenticate(profile, p15card, keyfile, SC_AC_OP_UPDATE); - if (r < 0) - goto out; - - keybits = key_info->modulus_length; - - /* generate key */ - /* keysize is _not_ passed to the card at any point. it appears to - infer it from the file size */ - memset(&args, 0, sizeof(args)); - args.exponent = 0x10001; - sc_append_file_id(&args.pub_file_ref, temppubfile->id); - sc_append_file_id(&args.pri_file_ref, keyfile->id); - keybuf = malloc(keybits / 8); - if (!keybuf) { - r=SC_ERROR_OUT_OF_MEMORY; - goto out; - } - args.pubkey = keybuf; - args.pubkey_len = keybits / 8; - - r = sc_card_ctl(p15card->card, SC_CARDCTL_JCOP_GENERATE_KEY, (void *)&args); - if (r < 0) - goto out; - - /* extract public key */ - pubkey->algorithm = SC_ALGORITHM_RSA; - pubkey->u.rsa.modulus.len = keybits / 8; - pubkey->u.rsa.modulus.data = keybuf; - pubkey->u.rsa.exponent.len = 3; - pubkey->u.rsa.exponent.data = malloc(3); - if (!pubkey->u.rsa.exponent.data) { - pubkey->u.rsa.modulus.data = NULL; - r=SC_ERROR_OUT_OF_MEMORY; - goto out; - } - memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); - - out: - if (r < 0 && keybuf) - free(keybuf); - if (delete_ok) - sc_pkcs15init_rmdir(p15card, profile, temppubfile); - sc_file_free(keyfile); - sc_file_free(temppubfile); - return r; -} - - - -static struct sc_pkcs15init_operations sc_pkcs15init_jcop_operations = { - jcop_erase_card, - NULL, /* init_card */ - jcop_create_dir, - NULL, /* create_domain */ - jcop_select_pin_reference, - jcop_create_pin, - NULL, /* select_key_reference */ - jcop_create_key, - jcop_store_key, - jcop_generate_key, - NULL, NULL, /* encode private/public key */ - NULL, /* finalize_card */ - NULL, /* delete_object */ - NULL, NULL, NULL, NULL, NULL, /* pkcs15init emulation */ - NULL /* sanity_check */ -}; - -struct sc_pkcs15init_operations *sc_pkcs15init_get_jcop_ops(void) -{ - return &sc_pkcs15init_jcop_operations; -} - - diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 1269bd9c25..3ba7508f34 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -146,7 +146,6 @@ static struct profile_operations { { "cyberflex", (void *) sc_pkcs15init_get_cyberflex_ops }, { "cardos", (void *) sc_pkcs15init_get_cardos_ops }, { "etoken", (void *) sc_pkcs15init_get_cardos_ops }, /* legacy */ - { "jcop", (void *) sc_pkcs15init_get_jcop_ops }, { "starcos", (void *) sc_pkcs15init_get_starcos_ops }, { "oberthur", (void *) sc_pkcs15init_get_oberthur_ops }, { "openpgp", (void *) sc_pkcs15init_get_openpgp_ops }, diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 63284f3f38..25cca83e85 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -237,9 +237,6 @@ - - - @@ -412,7 +409,6 @@ - From 28e7f35e1e4037e642b91753878a082396c1a40c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 3 Aug 2021 15:13:46 +0200 Subject: [PATCH 1943/4321] MioCOS: Remove old driver Remove due to no user and developer activity, last relevant driver modification was 30c0943 and no more changes except general were made. The driver was disabled in #1175. --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-miocos.c | 504 ------------------------------------ src/libopensc/cardctl.h | 26 -- src/libopensc/cards.h | 5 - src/libopensc/ctx.c | 1 - 6 files changed, 3 insertions(+), 539 deletions(-) delete mode 100644 src/libopensc/card-miocos.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 933ff78f48..ab4c662d6b 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -37,7 +37,7 @@ libopensc_la_SOURCES_BASE = \ \ ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ \ - card-setcos.c card-miocos.c card-flex.c card-gpk.c \ + card-setcos.c card-flex.c card-gpk.c \ card-cardos.c card-tcos.c card-default.c \ card-mcrd.c card-starcos.c card-openpgp.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ @@ -120,7 +120,7 @@ TIDY_FILES = \ \ ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ \ - card-setcos.c card-miocos.c card-flex.c card-gpk.c \ + card-setcos.c card-flex.c card-gpk.c \ card-cardos.c card-tcos.c card-default.c \ card-mcrd.c card-starcos.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 2a59375f82..9280ed8e24 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -14,7 +14,7 @@ OBJECTS = \ \ ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj reader-tr03119.obj \ \ - card-setcos.obj card-miocos.obj card-flex.obj card-gpk.obj \ + card-setcos.obj card-flex.obj card-gpk.obj \ card-cardos.obj card-tcos.obj card-default.obj \ card-mcrd.obj card-starcos.obj card-openpgp.obj \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj \ diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c deleted file mode 100644 index ccce95aa83..0000000000 --- a/src/libopensc/card-miocos.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * card-miocos.c: Support for PKI cards by Miotec - * - * Copyright (C) 2002 Juha Yrjölä - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "internal.h" -#include "asn1.h" -#include "cardctl.h" - -static const struct sc_atr_table miocos_atrs[] = { - /* Test card with 32 kB memory */ - { "3B:9D:94:40:23:00:68:10:11:4D:69:6F:43:4F:53:00:90:00", NULL, NULL, SC_CARD_TYPE_MIOCOS_GENERIC, 0, NULL }, - /* Test card with 64 kB memory */ - { "3B:9D:94:40:23:00:68:20:01:4D:69:6F:43:4F:53:00:90:00", NULL, NULL, SC_CARD_TYPE_MIOCOS_GENERIC, 0, NULL }, - { NULL, NULL, NULL, 0, 0, NULL } -}; - -static struct sc_card_operations miocos_ops; -static struct sc_card_driver miocos_drv = { - "MioCOS 1.1", - "miocos", - &miocos_ops, - NULL, 0, NULL -}; - -static int miocos_match_card(sc_card_t *card) -{ - int i; - - i = _sc_match_atr(card, miocos_atrs, &card->type); - if (i < 0) - return 0; - return 1; -} - -static int miocos_init(sc_card_t *card) -{ - card->name = "MioCOS"; - card->cla = 0x00; - - if (1) { - unsigned long flags; - - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; - flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; - - _sc_card_add_rsa_alg(card, 1024, flags, 0); - } - - /* read_binary and friends shouldn't do more than 244 bytes - * per operation */ - card->max_send_size = 244; - card->max_recv_size = 244; - - return 0; -} - -static const struct sc_card_operations *iso_ops = NULL; - -static int acl_to_byte(const sc_acl_entry_t *e) -{ - switch (e->method) { - case SC_AC_NONE: - return 0x00; - case SC_AC_CHV: - case SC_AC_TERM: - case SC_AC_AUT: - if (e->key_ref == SC_AC_KEY_REF_NONE) - return -1; - if (e->key_ref < 1 || e->key_ref > 14) - return -1; - return e->key_ref; - case SC_AC_NEVER: - return 0x0F; - } - return 0x00; -} - -static int encode_file_structure(sc_card_t *card, const sc_file_t *file, - u8 *buf, size_t *buflen) -{ - u8 *p = buf; - const int df_ops[8] = { - SC_AC_OP_DELETE, SC_AC_OP_CREATE, - /* RFU */ -1, /* CREATE AC */ SC_AC_OP_CREATE, - /* UPDATE AC */ SC_AC_OP_CREATE, -1, -1, -1 - }; - const int ef_ops[8] = { - /* DELETE */ SC_AC_OP_UPDATE, -1, SC_AC_OP_READ, - SC_AC_OP_UPDATE, -1, -1, SC_AC_OP_INVALIDATE, - SC_AC_OP_REHABILITATE - }; - const int key_ops[8] = { - /* DELETE */ SC_AC_OP_UPDATE, -1, -1, - SC_AC_OP_UPDATE, SC_AC_OP_CRYPTO, -1, SC_AC_OP_INVALIDATE, - SC_AC_OP_REHABILITATE - }; - const int *ops; - int i; - - *p++ = file->id >> 8; - *p++ = file->id & 0xFF; - switch (file->type) { - case SC_FILE_TYPE_DF: - *p++ = 0x20; - ops = df_ops; - break; - case SC_FILE_TYPE_WORKING_EF: - switch (file->ef_structure) { - case SC_FILE_EF_TRANSPARENT: - *p++ = 0x40; - break; - case SC_FILE_EF_LINEAR_FIXED: - *p++ = 0x41; - break; - case SC_FILE_EF_CYCLIC: - *p++ = 0x43; - break; - default: - sc_log(card->ctx, "Invalid EF structure\n"); - return SC_ERROR_INVALID_ARGUMENTS; - } - ops = ef_ops; - break; - case SC_FILE_TYPE_INTERNAL_EF: - *p++ = 0x44; - ops = key_ops; - break; - default: - sc_log(card->ctx, "Unknown file type\n"); - return SC_ERROR_INVALID_ARGUMENTS; - } - if (file->type == SC_FILE_TYPE_DF) { - *p++ = 0; - *p++ = 0; - } else { - *p++ = file->size >> 8; - *p++ = file->size & 0xFF; - } - if (file->sec_attr_len == 4) { - memcpy(p, file->sec_attr, 4); - p += 4; - } else for (i = 0; i < 8; i++) { - u8 nibble; - - if (ops[i] == -1) - nibble = 0x00; - else { - int byte = acl_to_byte(sc_file_get_acl_entry(file, ops[i])); - if (byte < 0) { - sc_log(card->ctx, "Invalid ACL\n"); - return SC_ERROR_INVALID_ARGUMENTS; - } - nibble = byte; - } - if ((i & 1) == 0) - *p = nibble << 4; - else { - *p |= nibble & 0x0F; - p++; - } - } - if (file->type == SC_FILE_TYPE_WORKING_EF && - file->ef_structure != SC_FILE_EF_TRANSPARENT) - *p++ = file->record_length; - else - *p++ = 0; - if (file->status == SC_FILE_STATUS_INVALIDATED) - *p++ = 0; - else - *p++ = 0x01; - if (file->type == SC_FILE_TYPE_DF && file->namelen) { - assert(file->namelen <= 16); - memcpy(p, file->name, file->namelen); - p += file->namelen; - } - *buflen = p - buf; - - return 0; -} - -static int miocos_create_file(sc_card_t *card, sc_file_t *file) -{ - sc_apdu_t apdu; - u8 sbuf[32]; - size_t buflen; - int r; - - r = encode_file_structure(card, file, sbuf, &buflen); - if (r) - return r; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); - apdu.data = sbuf; - apdu.datalen = buflen; - apdu.lc = buflen; - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89) - return SC_ERROR_FILE_ALREADY_EXISTS; - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, "Card returned error"); - - return 0; -} - -static int miocos_set_security_env(sc_card_t *card, - const sc_security_env_t *env, - int se_num) -{ - if (env->flags & SC_SEC_ENV_ALG_PRESENT) { - sc_security_env_t tmp; - - tmp = *env; - tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; - tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; - if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_log(card->ctx, "Only RSA algorithm supported.\n"); - return SC_ERROR_NOT_SUPPORTED; - } - tmp.algorithm_ref = 0x00; - /* potential FIXME: return an error, if an unsupported - * pad or hash was requested, although this shouldn't happen. - */ - if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) - tmp.algorithm_ref = 0x02; - if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) - tmp.algorithm_ref |= 0x10; - return iso_ops->set_security_env(card, &tmp, se_num); - } - return iso_ops->set_security_env(card, env, se_num); -} - -static void add_acl_entry(sc_file_t *file, int op, u8 byte) -{ - unsigned int method, key_ref = SC_AC_KEY_REF_NONE; - - switch (byte) { - case 0: - method = SC_AC_NONE; - break; - case 15: - method = SC_AC_NEVER; - break; - default: - method = SC_AC_CHV; - key_ref = byte; - break; - } - sc_file_add_acl_entry(file, op, method, key_ref); -} - -static void parse_sec_attr(sc_file_t *file, const u8 *buf, size_t len) -{ - int i; - const int df_ops[8] = { - SC_AC_OP_DELETE, SC_AC_OP_CREATE, - -1, /* CREATE AC */ -1, /* UPDATE AC */ -1, -1, -1, -1 - }; - const int ef_ops[8] = { - SC_AC_OP_DELETE, -1, SC_AC_OP_READ, - SC_AC_OP_UPDATE, -1, -1, SC_AC_OP_INVALIDATE, - SC_AC_OP_REHABILITATE - }; - const int key_ops[8] = { - SC_AC_OP_DELETE, -1, -1, - SC_AC_OP_UPDATE, SC_AC_OP_CRYPTO, -1, SC_AC_OP_INVALIDATE, - SC_AC_OP_REHABILITATE - }; - const int *ops; - - if (len < 4) - return; - switch (file->type) { - case SC_FILE_TYPE_WORKING_EF: - ops = ef_ops; - break; - case SC_FILE_TYPE_INTERNAL_EF: - ops = key_ops; - break; - case SC_FILE_TYPE_DF: - ops = df_ops; - break; - default: - return; - } - for (i = 0; i < 8; i++) { - if (ops[i] == -1) - continue; - if ((i & 1) == 0) - add_acl_entry(file, ops[i], (u8)(buf[i / 2] >> 4)); - else - add_acl_entry(file, ops[i], (u8)(buf[i / 2] & 0x0F)); - } -} - -static int miocos_get_acl(sc_card_t *card, sc_file_t *file) -{ - sc_apdu_t apdu; - u8 rbuf[256]; - const u8 *seq = rbuf; - size_t left; - int r; - unsigned int i; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0x01); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = sizeof(rbuf); - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen == 0) - return sc_check_sw(card, apdu.sw1, apdu.sw2); - left = apdu.resplen; - seq = sc_asn1_skip_tag(card->ctx, &seq, &left, - SC_ASN1_SEQUENCE | SC_ASN1_CONS, &left); - if (seq == NULL) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - LOG_TEST_RET(card->ctx, r, "Unable to process reply"); - for (i = 1; i < 15; i++) { - int j; - const u8 *tag; - size_t taglen; - - tag = sc_asn1_skip_tag(card->ctx, &seq, &left, - SC_ASN1_CTX | i, &taglen); - if (tag == NULL || taglen == 0) - continue; - for (j = 0; j < SC_MAX_AC_OPS; j++) { - sc_acl_entry_t *e; - - e = (sc_acl_entry_t *) sc_file_get_acl_entry(file, j); - if (e == NULL) - continue; - if (e->method != SC_AC_CHV) - continue; - if (e->key_ref != i) - continue; - switch (tag[0]) { - case 0x01: - e->method = SC_AC_CHV; - break; - case 0x02: - e->method = SC_AC_AUT; - break; - default: - e->method = SC_AC_UNKNOWN; - break; - } - } - } - return 0; -} - -static int miocos_select_file(sc_card_t *card, - const sc_path_t *in_path, - sc_file_t **file) -{ - int r; - - r = iso_ops->select_file(card, in_path, file); - if (r) - return r; - if (file != NULL && *file != NULL) { - parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len); - miocos_get_acl(card, *file); - } - - return 0; -} - -static int miocos_list_files(sc_card_t *card, u8 *buf, size_t buflen) -{ - sc_apdu_t apdu; - int r; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0); - apdu.resp = buf; - apdu.resplen = buflen; - apdu.le = buflen > 256 ? 256 : buflen; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen == 0) - return sc_check_sw(card, apdu.sw1, apdu.sw2); - return apdu.resplen; -} - -static int miocos_delete_file(sc_card_t *card, const sc_path_t *path) -{ - int r; - sc_apdu_t apdu; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - r = sc_select_file(card, path, NULL); - LOG_TEST_RET(card->ctx, r, "Unable to select file to be deleted"); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); - apdu.cla = 0xA0; - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - return sc_check_sw(card, apdu.sw1, apdu.sw2); -} - -static int miocos_create_ac(sc_card_t *card, - struct sc_cardctl_miocos_ac_info *ac) -{ - sc_apdu_t apdu; - u8 sbuf[20]; - int miocos_type, r; - size_t sendsize; - - if (ac->max_tries > 15) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - switch (ac->type) { - case SC_CARDCTL_MIOCOS_AC_PIN: - if (ac->max_unblock_tries > 15) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - miocos_type = 0x01; - sbuf[0] = (ac->max_tries << 4) | ac->max_tries; - sbuf[1] = 0xFF; /* FIXME... */ - memcpy(sbuf + 2, ac->key_value, 8); - sbuf[10] = (ac->max_unblock_tries << 4) | ac->max_unblock_tries; - sbuf[11] = 0xFF; - memcpy(sbuf + 12, ac->unblock_value, 8); - sendsize = 20; - break; - default: - sc_log(card->ctx, "AC type %d not supported\n", ac->type); - return SC_ERROR_NOT_SUPPORTED; - } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x1E, miocos_type, - ac->ref); - apdu.lc = sendsize; - apdu.datalen = sendsize; - apdu.data = sbuf; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - return sc_check_sw(card, apdu.sw1, apdu.sw2); -} - -static int miocos_card_ctl(sc_card_t *card, unsigned long cmd, - void *arg) -{ - switch (cmd) { - case SC_CARDCTL_MIOCOS_CREATE_AC: - return miocos_create_ac(card, (struct sc_cardctl_miocos_ac_info *) arg); - } - sc_log(card->ctx, "card_ctl command 0x%lX not supported\n", cmd); - return SC_ERROR_NOT_SUPPORTED; -} - - -static struct sc_card_driver * sc_get_driver(void) -{ - struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); - - miocos_ops = *iso_drv->ops; - miocos_ops.match_card = miocos_match_card; - miocos_ops.init = miocos_init; - if (iso_ops == NULL) - iso_ops = iso_drv->ops; - miocos_ops.create_file = miocos_create_file; - miocos_ops.set_security_env = miocos_set_security_env; - miocos_ops.select_file = miocos_select_file; - miocos_ops.list_files = miocos_list_files; - miocos_ops.delete_file = miocos_delete_file; - miocos_ops.card_ctl = miocos_card_ctl; - - return &miocos_drv; -} - -#if 1 -struct sc_card_driver * sc_get_miocos_driver(void) -{ - return sc_get_driver(); -} -#endif diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index a493977b7f..f91dadc5f8 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -62,12 +62,6 @@ enum { SC_CARDCTL_CRYPTOFLEX_BASE = _CTL_PREFIX('C', 'F', 'X'), SC_CARDCTL_CRYPTOFLEX_GENERATE_KEY, - /* - * MioCOS specific calls - */ - SC_CARDCTL_MIOCOS_BASE = _CTL_PREFIX('M', 'I', 'O'), - SC_CARDCTL_MIOCOS_CREATE_AC, - /* * TCOS specific calls */ @@ -388,26 +382,6 @@ struct sc_cardctl_gpk_genkey { unsigned int pubkey_len; }; -enum { - SC_CARDCTL_MIOCOS_AC_PIN, - SC_CARDCTL_MIOCOS_AC_CHAL, - SC_CARDCTL_MIOCOS_AC_LOGICAL, - SC_CARDCTL_MIOCOS_AC_SMARTPIN -}; - -/* - * MioCOS AC info - */ -struct sc_cardctl_miocos_ac_info { - int type; - int ref; - int max_tries; - int enable_ac; /* only applicable to PINs */ - u8 key_value[8]; - int max_unblock_tries; /* same here */ - u8 unblock_value[8]; /* and here */ -}; - /* * Siemens CardOS PIN info */ diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 4b3ce03c35..5a9feeeaf5 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -68,10 +68,6 @@ enum { SC_CARD_TYPE_GPK_GPK8000_16K, SC_CARD_TYPE_GPK_GPK16000 = 3160, - /* miocos driver */ - SC_CARD_TYPE_MIOCOS_BASE = 4000, - SC_CARD_TYPE_MIOCOS_GENERIC, - /* mcrd driver */ SC_CARD_TYPE_MCRD_BASE = 5000, SC_CARD_TYPE_MCRD_GENERIC, @@ -278,7 +274,6 @@ extern sc_card_driver_t *sc_get_cryptoflex_driver(void); extern sc_card_driver_t *sc_get_cyberflex_driver(void); extern sc_card_driver_t *sc_get_gpk_driver(void); extern sc_card_driver_t *sc_get_gemsafeV1_driver(void); -extern sc_card_driver_t *sc_get_miocos_driver(void); extern sc_card_driver_t *sc_get_mcrd_driver(void); extern sc_card_driver_t *sc_get_setcos_driver(void); extern sc_card_driver_t *sc_get_starcos_driver(void); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index d4844a607c..1ba3c94b32 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -161,7 +161,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { }; static const struct _sc_driver_entry old_card_drivers[] = { - { "miocos", (void *(*)(void)) sc_get_miocos_driver }, { NULL, NULL } }; From 5582cd2cc34ee3af9e014a6b2f255b96c5ec7e03 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 3 Aug 2021 15:25:49 +0200 Subject: [PATCH 1944/4321] MioCOS: Remove pkcs15init support Remove support for MioCOS due to no recent user or developer activity except general fixes. --- src/libopensc/libopensc.exports | 1 - src/pkcs15init/Makefile.am | 3 +- src/pkcs15init/Makefile.mak | 2 +- src/pkcs15init/miocos.profile | 53 ------ src/pkcs15init/pkcs15-init.h | 1 - src/pkcs15init/pkcs15-lib.c | 1 - src/pkcs15init/pkcs15-miocos.c | 288 -------------------------------- win32/OpenSC.wxs.in | 4 - 8 files changed, 2 insertions(+), 351 deletions(-) delete mode 100644 src/pkcs15init/miocos.profile delete mode 100644 src/pkcs15init/pkcs15-miocos.c diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 73173363c4..6212aee773 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -301,7 +301,6 @@ sc_pkcs15init_get_gpk_ops sc_pkcs15init_get_gids_ops sc_pkcs15init_get_incrypto34_ops sc_pkcs15init_get_manufacturer -sc_pkcs15init_get_miocos_ops sc_pkcs15init_get_muscle_ops sc_pkcs15init_get_oberthur_ops sc_pkcs15init_get_pin_info diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 4b85ba4f8f..5b47e28254 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -9,7 +9,6 @@ dist_pkgdata_DATA = \ cyberflex.profile \ flex.profile \ gpk.profile \ - miocos.profile \ cardos.profile \ incrypto34.profile \ oberthur.profile \ @@ -39,7 +38,7 @@ AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) libpkcs15init_la_SOURCES = \ pkcs15-lib.c profile.c \ pkcs15-westcos.c \ - pkcs15-gpk.c pkcs15-miocos.c pkcs15-cflex.c \ + pkcs15-gpk.c pkcs15-cflex.c \ pkcs15-cardos.c pkcs15-starcos.c \ pkcs15-setcos.c pkcs15-incrypto34.c pkcs15-muscle.c \ pkcs15-asepcos.c pkcs15-rutoken.c \ diff --git a/src/pkcs15init/Makefile.mak b/src/pkcs15init/Makefile.mak index c79566c544..56cfe3b85b 100644 --- a/src/pkcs15init/Makefile.mak +++ b/src/pkcs15init/Makefile.mak @@ -2,7 +2,7 @@ TOPDIR = ..\.. TARGET = pkcs15init.lib OBJECTS = pkcs15-lib.obj profile.obj \ - pkcs15-gpk.obj pkcs15-miocos.obj pkcs15-cflex.obj \ + pkcs15-gpk.obj pkcs15-cflex.obj \ pkcs15-cardos.obj pkcs15-starcos.obj \ pkcs15-oberthur.obj pkcs15-oberthur-awp.obj \ pkcs15-setcos.obj pkcs15-incrypto34.obj \ diff --git a/src/pkcs15init/miocos.profile b/src/pkcs15init/miocos.profile deleted file mode 100644 index d42e35d046..0000000000 --- a/src/pkcs15init/miocos.profile +++ /dev/null @@ -1,53 +0,0 @@ -# -# PKCS15 r/w profile for MioCOS cards -# -cardinfo { - max-pin-length = 8; - pin-encoding = ascii-numeric; - pin-pad-char = 0x00; -} - -# Define reasonable limits for PINs and PUK -# Note that we do not set a file path or reference -# here; that is done dynamically. -PIN user-pin { - attempts = 3; -} -PIN user-puk { - attempts = 10; -} - -# Additional filesystem info. -# This is added to the file system info specified in the -# main profile. -filesystem { - DF MF { - DF PKCS15-AppDF { - EF template-private-key { - type = internal-ef; - file-id = 4B01; # This is the base FileID - size = 266; # 266 is enough for 1024-bit keys - ACL = *=NEVER, CRYPTO=$PIN, UPDATE=$PIN; - } - EF template-public-key { - file-id = 5501; - ACL = *=NEVER, READ=NONE, UPDATE=$PIN; - } - EF template-certificate { - file-id = 4301; - ACL = *=NEVER, READ=NONE, UPDATE=$PIN; - } - EF template-extractable-key { - file-id = 7000; - ACL = *=NEVER, READ=$PIN, UPDATE=$PIN; - } - } - } -} - -# Define an SO pin -# This PIN is not used yet. -#PIN sopin { -# file = sopinfile; -# reference = 0; -#} diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 8dc256bd82..77a518682b 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -428,7 +428,6 @@ extern int sc_pkcs15init_unwrap_key(struct sc_pkcs15_card *p15card, struct sc_pr extern struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void); -extern struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cryptoflex_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cyberflex_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_cardos_ops(void); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 3ba7508f34..57621aea5a 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -141,7 +141,6 @@ static struct profile_operations { } profile_operations[] = { { "rutoken", (void *) sc_pkcs15init_get_rutoken_ops }, { "gpk", (void *) sc_pkcs15init_get_gpk_ops }, - { "miocos", (void *) sc_pkcs15init_get_miocos_ops }, { "flex", (void *) sc_pkcs15init_get_cryptoflex_ops }, { "cyberflex", (void *) sc_pkcs15init_get_cyberflex_ops }, { "cardos", (void *) sc_pkcs15init_get_cardos_ops }, diff --git a/src/pkcs15init/pkcs15-miocos.c b/src/pkcs15init/pkcs15-miocos.c deleted file mode 100644 index 092f640232..0000000000 --- a/src/pkcs15init/pkcs15-miocos.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * MioCOS specific operation for PKCS15 initialization - * - * Copyright (C) 2002 Juha Yrjölä - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include -#include - -#include "libopensc/opensc.h" -#include "libopensc/cardctl.h" -#include "libopensc/log.h" -#include "pkcs15-init.h" -#include "profile.h" - -#define MIOCOS_PIN_ID_MIN 1 -#define MIOCOS_PIN_ID_MAX 15 - -/* - * Allocate a file - */ -static int -miocos_new_file(struct sc_profile *profile, sc_card_t *card, - unsigned int type, unsigned int num, - sc_file_t **out) -{ - struct sc_file *file; - struct sc_path *p; - char name[64]; - const char *tag = NULL, *desc = NULL; - - while (1) { - switch (type) { - case SC_PKCS15_TYPE_PRKEY_RSA: - desc = "RSA private key"; - tag = "private-key"; - break; - case SC_PKCS15_TYPE_PUBKEY_RSA: - desc = "RSA public key"; - tag = "public-key"; - break; - case SC_PKCS15_TYPE_PRKEY: - desc = "extractable private key"; - tag = "extractable-key"; - break; - case SC_PKCS15_TYPE_CERT: - desc = "certificate"; - tag = "certificate"; - break; - case SC_PKCS15_TYPE_DATA_OBJECT: - desc = "data object"; - tag = "data"; - break; - } - if (tag) - break; - /* If this is a specific type such as - * SC_PKCS15_TYPE_CERT_FOOBAR, fall back to - * the generic class (SC_PKCS15_TYPE_CERT) - */ - if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_log(card->ctx, - "File type not supported by card driver"); - return SC_ERROR_INVALID_ARGUMENTS; - } - type &= SC_PKCS15_TYPE_CLASS_MASK; - } - - snprintf(name, sizeof(name), "template-%s", tag); - if (sc_profile_get_file(profile, name, &file) < 0) { - sc_log(card->ctx, "Profile doesn't define %s template (%s)", - desc, name); - return SC_ERROR_NOT_SUPPORTED; - } - - /* Now construct file from template */ - file->id += num; - - p = &file->path; - *p = profile->df_info->file->path; - p->value[p->len++] = file->id >> 8; - p->value[p->len++] = file->id; - - *out = file; - return 0; -} - -static int -miocos_update_private_key(struct sc_profile *profile, sc_card_t *card, - struct sc_pkcs15_prkey_rsa *rsa) -{ - int r; - u8 buf[266]; - - memcpy(buf, "\x30\x82\x01\x06\x80\x81\x80", 7); - memcpy(buf + 7, rsa->modulus.data, 128); - memcpy(buf + 7 + 128, "\x82\x81\x80", 3); - memcpy(buf + 10 + 128, rsa->d.data, 128); - r = sc_update_binary(card, 0, buf, sizeof(buf), 0); - - return r; -} - -/* - * Initialize the Application DF - */ -static int -miocos_create_dir(struct sc_profile *profile, sc_pkcs15_card_t *p15card, - struct sc_file *df) -{ - /* Create the application DF */ - if (sc_pkcs15init_create_file(profile, p15card, profile->df_info->file)) - return 1; - - return 0; -} - -/* - * Validate PIN reference - */ -static int -miocos_select_pin_reference(struct sc_profile *profile, sc_pkcs15_card_t *p15card, - struct sc_pkcs15_auth_info *auth_info) -{ - if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) - return SC_ERROR_OBJECT_NOT_VALID; - - if (auth_info->attrs.pin.reference < MIOCOS_PIN_ID_MIN) - auth_info->attrs.pin.reference = MIOCOS_PIN_ID_MIN; - - return SC_SUCCESS; -} - -/* - * Create new PIN - */ -static int -miocos_create_pin(struct sc_profile *profile, sc_pkcs15_card_t *p15card, struct sc_file *df, - struct sc_pkcs15_object *pin_obj, - const u8 *pin, size_t pin_len, - const u8 *puk, size_t puk_len) -{ - struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; - struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin; - struct sc_pkcs15_auth_info tmpinfo; - struct sc_cardctl_miocos_ac_info ac_info; - int r; - - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - /* Ignore SOPIN */ - if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) - return SC_SUCCESS; - - auth_info->path = profile->df_info->file->path; - r = sc_select_file(p15card->card, &auth_info->path, NULL); - if (r) - return r; - memset(&ac_info, 0, sizeof(ac_info)); - ac_info.ref = pin_attrs->reference; - sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &tmpinfo); - ac_info.max_tries = tmpinfo.tries_left; - sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &tmpinfo); - ac_info.max_unblock_tries = tmpinfo.tries_left; - if (pin_len > 8) - pin_len = 8; - memcpy(ac_info.key_value, pin, pin_len); - if (puk_len > 8) - puk_len = 8; - strncpy((char *) ac_info.unblock_value, (const char *) puk, puk_len); - r = sc_card_ctl(p15card->card, SC_CARDCTL_MIOCOS_CREATE_AC, &ac_info); - LOG_TEST_RET(ctx, r, "Miocos create AC failed"); - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} - - -/* - * Create private key file - */ -static int -miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *object) -{ - struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; - struct sc_file *file; - int r; - - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - - if (key_info->modulus_length != 1024) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - - sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); - r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); - LOG_TEST_RET(ctx, r, "Cannot create key: failed to allocate new key object"); - - memcpy(&file->path, &key_info->path, sizeof(file->path)); - file->id = file->path.value[file->path.len - 2] * 0x100 - + file->path.value[file->path.len - 1]; - - sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); - - r = sc_pkcs15init_create_file(profile, p15card, file); - sc_file_free(file); - - LOG_FUNC_RETURN(ctx, r); -} - - -/* - * Store a private key - */ -static int -miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *object, - struct sc_pkcs15_prkey *key) -{ - struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; - struct sc_pkcs15_prkey_rsa *rsa; - struct sc_file *file = NULL; - int r; - - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - if (object->type != SC_PKCS15_TYPE_PRKEY_RSA - || key->algorithm != SC_ALGORITHM_RSA) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - - rsa = &key->u.rsa; - if (rsa->modulus.len != 128) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); - - sc_log(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), - sc_print_path(&key_info->path)); - - r = sc_select_file(p15card->card, &key_info->path, &file); - LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed"); - - r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - LOG_TEST_RET(ctx, r, "No authorisation to store private key"); - - r = miocos_update_private_key(profile, p15card->card, rsa); - - LOG_FUNC_RETURN(ctx, r); -} - -static struct sc_pkcs15init_operations sc_pkcs15init_miocos_operations = { - NULL, /* erase_card */ - NULL, /* init_card */ - miocos_create_dir, - NULL, /* create_domain */ - miocos_select_pin_reference, - miocos_create_pin, - NULL, /* select_key_reference */ - miocos_create_key, - miocos_store_key, - NULL, /* generate_key */ - NULL, NULL, /* encode private/public key */ - NULL, /* finalize_card */ - NULL, /* delete_object */ - NULL, NULL, NULL, NULL, NULL, /* pkcs15init emulation */ - NULL /* sanity_check */ -}; - -struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void) -{ - return &sc_pkcs15init_miocos_operations; -} diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 25cca83e85..73c97e8a51 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -231,9 +231,6 @@ - - - @@ -407,7 +404,6 @@ - From 088a8a1302f8b6ff3224bf12526f14a8722afd8f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 17 Aug 2021 12:31:56 -0500 Subject: [PATCH 1945/4321] Fix pkcs11-tool and test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test-threads.sh had the wrong parameters for one of the tests. And extra "OS" was left in the parameter pkcs11-tool when testing threads could segfault if no reader present. Error checking for slot index improved. Fixes:#2381 On branch pkcs11-tool-and-test Changes to be committed: modified: pkcs11-tool.c modified: ../../tests/test-pkcs11-tool-test-threads.sh --- src/tools/pkcs11-tool.c | 6 ++++-- tests/test-pkcs11-tool-test-threads.sh | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f87ce02556..67dfc89619 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7506,10 +7506,12 @@ static void * test_threads_run(void * pttd) /* Tn Get token from slot_index n C_GetTokenInfo, where n is 0 to 9 */ else if (*pctest == 'T' && *(pctest + 1) >= '0' && *(pctest + 1) <= '9') { fprintf(stderr, "Test thread %d C_GetTokenInfo from slot_index %d using show_token\n", ttd->tnum, (*(pctest + 1) - '0')); - if (l_slots) { + if (l_slots && (CK_ULONG)(*(pctest + 1) - '0') < l_p11_num_slots) { show_token(l_p11_slots[(*(pctest + 1) - '0')]); } else { - show_token(p11_slots[(*(pctest + 1) - '0')]); + fprintf(stderr, "Test thread %d slot not available, unable to call C_GetTokenInfo\n", ttd->tnum); + rv = CKR_TOKEN_NOT_PRESENT; + break; } } diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index 6b74eb36c9..d4c576e9a2 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -14,16 +14,16 @@ fi card_setup echo "=======================================================" -echo "Test pkcs11 threads OSILGISLT0 " +echo "Test pkcs11 threads IN " echo "=======================================================" $PKCS11_TOOL --test-threads IN -L assert $? "Failed running tests" echo "=======================================================" -echo "Test pkcs11 threads OSILGISLT0 " +echo "Test pkcs11 threads ILGISLT0 " echo "=======================================================" -$PKCS11_TOOL --test-threads OSILGISLT0 -L +$PKCS11_TOOL --test-threads ILGISLT0 -L assert $? "Failed running tests" echo "=======================================================" From 1b10f79a58f6562a0d47fd03000f9a14d153bee8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 21 Aug 2021 07:01:23 -0500 Subject: [PATCH 1946/4321] test-actions-2 vsmartcard-0.8 See if cebe05e78d51124591cf93f0506112fbe31d34fa on 8/13 is the problem vcpd polling was changed --- .github/setup-vsmartcard.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh index 8a05c03be4..825d9cf6c1 100755 --- a/.github/setup-vsmartcard.sh +++ b/.github/setup-vsmartcard.sh @@ -1,8 +1,9 @@ #!/bin/bash - +set -x if [ ! -d "vsmartcard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git fi pushd vsmartcard/virtualsmartcard +git checkout -b tag-0.8 virtualsmartcard-0.8 autoreconf -vis && ./configure && make -j2 && sudo make install popd From adbd9f099f23fa8a613291bcb72164a977094af1 Mon Sep 17 00:00:00 2001 From: William Roberts Date: Tue, 17 Aug 2021 12:05:17 -0500 Subject: [PATCH 1947/4321] pkcs11-tool: support verifying HMAC signatures Before verification would only look for CKO_PUBLIC_KEY or CKO_PRIVATE_KEY objects, however, for HMAC to work through C_Verify it needs to look for CKO_SECRET_KEY objects as well. Before: tpm2pkcs11-tool --token-label=label --login --pin=myuserpin --verify --id='393837363534333231' --input-file=data.msg --mechanism=SHA-1-HMAC --signature-file=data.sig error: Public key nor certificate not found Aborting. After: tpm2pkcs11-tool --token-label=label --login --pin=myuserpin --verify --id='393837363534333231' --input-file=data.msg --mechanism=SHA-1-HMAC --signature-file=data.sig Using signature algorithm SHA-1-HMAC Signature is valid To help promote extensibility in the future, various bits of meta data can be associated with a mechanism via the mf_info table. The new bits of metadata are MF_FLAGS and contain information to quickly acertain what type of CKA_CLASS or C_.* interfaces are supported by the mechanism. This table can be slowly populated over time so support for other mechanisms can be added and the old code paths can be removed. Signed-off-by: William Roberts --- src/tools/pkcs11-tool.c | 575 +++++++++++++++++++++++----------------- 1 file changed, 333 insertions(+), 242 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 67dfc89619..b78a57797e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #ifndef _WIN32 @@ -429,10 +430,33 @@ struct flag_info { CK_FLAGS value; const char * name; }; + +/* + * Flags for mech_info. These flags can provide meta-data for + * pkcs11 mechanisms and are tracked per mechanism. Thus for figuring + * out if sign is valid for this mechanism, one can query the mechanism + * table over having to build conditional statements. + * + * Note that the tool takes in raw 0x prefixed mechanisms that may not exist in + * the table, so we just assume MF_UNKOWN for flags. + * + * TODO these flags are only the tip of the iceberg, but can be filled out as time progresses. + */ +#define MF_UNKNOWN 0 /* Used to indicate additional informtion is not available */ +#define MF_SIGN (1 << 0) /* C_Sign interface supported */ +#define MF_VERIFY (1 << 1) /* C_verify interface supported */ +#define MF_HMAC (1 << 2) /* Is an Hashed Message Authentication Code (HMAC) */ +#define MF_MGF (1 << 3) /* Is an Mask Generation Function (MGF) */ +#define MF_CKO_SECRET_KEY (1 << 4) /* Uses a CKO_SECRET_KEY class object */ + +/* Handy intializers */ +#define MF_GENERIC_HMAC_FLAGS (MF_SIGN | MF_VERIFY | MF_HMAC | MF_CKO_SECRET_KEY) + struct mech_info { CK_MECHANISM_TYPE mech; const char * name; const char * short_name; + uint16_t mf_flags; }; struct x509cert_info { unsigned char subject[512]; @@ -497,6 +521,9 @@ static void set_id_attr(CK_SESSION_HANDLE session); static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); +static int find_object_flags(CK_SESSION_HANDLE, uint16_t flags, + CK_OBJECT_HANDLE_PTR, + const unsigned char *, size_t id_len, int obj_index); static int find_mechanism(CK_SLOT_ID, CK_FLAGS, CK_MECHANISM_TYPE_PTR, size_t, CK_MECHANISM_TYPE_PTR); static int find_slot_by_description(const char *, CK_SLOT_ID_PTR); static int find_slot_by_token_label(const char *, CK_SLOT_ID_PTR); @@ -511,6 +538,7 @@ static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t); static const char * p11_flag_names(struct flag_info *, CK_FLAGS); static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE); static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); +static uint16_t p11_mechanism_to_flags(CK_MECHANISM_TYPE mech); static const char * p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE); static CK_MECHANISM_TYPE p11_name_to_mgf(const char *); static void p11_perror(const char *, CK_RV); @@ -1221,15 +1249,41 @@ int main(int argc, char * argv[]) goto end; } + uint16_t mf_flags = MF_UNKNOWN; + if (opt_mechanism_used) { + mf_flags = p11_mechanism_to_flags(opt_mechanism); + } + if (do_sign || do_derive || do_decrypt) { - if (!find_object(session, CKO_PRIVATE_KEY, &object, + + /* + * Newer mechanisms have their details in the mechanism table, however + * if it's not known fall back to the old code always assuming it was a + * CKO_PRIVATE_KEY. + */ + if (mf_flags != MF_UNKNOWN) { + /* this function dies on error via util_fatal */ + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } else if (!find_object(session, CKO_PRIVATE_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) util_fatal("Private key not found"); } if (do_verify) { - if (!find_object(session, CKO_PUBLIC_KEY, &object, + /* + * Newer mechanisms have their details in the mechanism table, however + * if it's not known fall back to the old code always assuming it was a + * CKO_PUBLIC_KEY then a CKO_CERTIFICATE. + */ + if (mf_flags != MF_UNKNOWN) { + /* this function dies on error via util_fatal */ + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } else if (!find_object(session, CKO_PUBLIC_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0) && !find_object(session, CKO_CERTIFICATE, &object, @@ -3811,6 +3865,24 @@ done: if (count == 0) return count; } +static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, + CK_OBJECT_HANDLE_PTR ret, + const unsigned char *id, size_t id_len, int obj_index) +{ + int count; + char err_key_types[1024] = { 0 }; + + if (mf_flags & MF_CKO_SECRET_KEY) { + count = find_object(sess, CKO_SECRET_KEY, ret, id, id_len, obj_index); + if (count) + return count; + + strncat(err_key_types, "Secret", sizeof(err_key_types)-1); + } + + util_fatal("Could not find key of type: %s", err_key_types); +} + static CK_RV find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out, CK_ATTRIBUTE *attrs, CK_ULONG attrsLen, @@ -6940,249 +7012,249 @@ static void pseudo_randomize(unsigned char *data, size_t dataLen) } static struct mech_info p11_mechanisms[] = { - { CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA-PKCS-KEY-PAIR-GEN", NULL }, - { CKM_RSA_PKCS, "RSA-PKCS", NULL }, - { CKM_RSA_9796, "RSA-9796", NULL }, - { CKM_RSA_X_509, "RSA-X-509", NULL }, - { CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS", NULL }, - { CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5" }, - { CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1" }, - { CKM_SHA224_RSA_PKCS, "SHA224-RSA-PKCS", "rsa-sha224" }, - { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256" }, - { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384" }, - { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512" }, - { CKM_RIPEMD128_RSA_PKCS, "RIPEMD128-RSA-PKCS", NULL }, - { CKM_RIPEMD160_RSA_PKCS, "RIPEMD160-RSA-PKCS", "rsa-ripemd160" }, - { CKM_RSA_PKCS_OAEP, "RSA-PKCS-OAEP", NULL }, - { CKM_RSA_X9_31_KEY_PAIR_GEN,"RSA-X9-31-KEY-PAIR-GEN", NULL }, - { CKM_RSA_X9_31, "RSA-X9-31", NULL }, - { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL }, - { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL }, - { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1" }, - { CKM_SHA224_RSA_PKCS_PSS,"SHA224-RSA-PKCS-PSS", "rsa-pss-sha224" }, - { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256" }, - { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384" }, - { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512" }, - { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL }, - { CKM_DSA, "DSA", NULL }, - { CKM_DSA_SHA1, "DSA-SHA1", NULL }, - { CKM_DSA_SHA224, "DSA-SHA224", NULL }, - { CKM_DSA_SHA256, "DSA-SHA256", NULL }, - { CKM_DSA_SHA384, "DSA-SHA384", NULL }, - { CKM_DSA_SHA512, "DSA-SHA512", NULL }, - { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN", NULL }, - { CKM_DH_PKCS_DERIVE, "DH-PKCS-DERIVE", NULL }, - { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN", NULL }, - { CKM_X9_42_DH_DERIVE, "X9-42-DH-DERIVE", NULL }, - { CKM_X9_42_DH_HYBRID_DERIVE,"X9-42-DH-HYBRID-DERIVE", NULL }, - { CKM_X9_42_MQV_DERIVE, "X9-42-MQV-DERIVE", NULL }, - { CKM_RC2_KEY_GEN, "RC2-KEY-GEN", NULL }, - { CKM_RC2_ECB, "RC2-ECB", NULL }, - { CKM_RC2_CBC, "RC2-CBC", NULL }, - { CKM_RC2_MAC, "RC2-MAC", NULL }, - { CKM_RC2_MAC_GENERAL, "RC2-MAC-GENERAL", NULL }, - { CKM_RC2_CBC_PAD, "RC2-CBC-PAD", NULL }, - { CKM_RC4_KEY_GEN, "RC4-KEY-GEN", NULL }, - { CKM_RC4, "RC4", NULL }, - { CKM_DES_KEY_GEN, "DES-KEY-GEN", NULL }, - { CKM_DES_ECB, "DES-ECB", NULL }, - { CKM_DES_CBC, "DES-CBC", NULL }, - { CKM_DES_MAC, "DES-MAC", NULL }, - { CKM_DES_MAC_GENERAL, "DES-MAC-GENERAL", NULL }, - { CKM_DES_CBC_PAD, "DES-CBC-PAD", NULL }, - { CKM_DES2_KEY_GEN, "DES2-KEY-GEN", NULL }, - { CKM_DES3_KEY_GEN, "DES3-KEY-GEN", NULL }, - { CKM_DES3_ECB, "DES3-ECB", NULL }, - { CKM_DES3_CBC, "DES3-CBC", NULL }, - { CKM_DES3_MAC, "DES3-MAC", NULL }, - { CKM_DES3_MAC_GENERAL, "DES3-MAC-GENERAL", NULL }, - { CKM_DES3_CBC_PAD, "DES3-CBC-PAD", NULL }, - { CKM_DES3_CMAC, "DES3-CMAC", NULL }, - { CKM_CDMF_KEY_GEN, "CDMF-KEY-GEN", NULL }, - { CKM_CDMF_ECB, "CDMF-ECB", NULL }, - { CKM_CDMF_CBC, "CDMF-CBC", NULL }, - { CKM_CDMF_MAC, "CDMF-MAC", NULL }, - { CKM_CDMF_MAC_GENERAL, "CDMF-MAC-GENERAL", NULL }, - { CKM_CDMF_CBC_PAD, "CDMF-CBC-PAD", NULL }, - { CKM_MD2, "MD2", NULL }, - { CKM_MD2_HMAC, "MD2-HMAC", NULL }, - { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL", NULL }, - { CKM_MD5, "MD5", NULL }, - { CKM_MD5_HMAC, "MD5-HMAC", NULL }, - { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL", NULL }, - { CKM_SHA_1, "SHA-1", NULL }, - { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL }, - { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL }, - { CKM_SHA224, "SHA224", NULL }, - { CKM_SHA224_HMAC, "SHA224-HMAC", NULL }, - { CKM_SHA256, "SHA256", NULL }, - { CKM_SHA256_HMAC, "SHA256-HMAC", NULL }, - { CKM_SHA384, "SHA384", NULL }, - { CKM_SHA384_HMAC, "SHA384-HMAC", NULL }, - { CKM_SHA512, "SHA512", NULL }, - { CKM_SHA512_HMAC, "SHA512-HMAC", NULL }, - { CKM_RIPEMD128, "RIPEMD128", NULL }, - { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL }, - { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL }, - { CKM_RIPEMD160, "RIPEMD160", NULL }, - { CKM_RIPEMD160_HMAC, "RIPEMD160-HMAC", NULL }, - { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL", NULL }, - { CKM_CAST_KEY_GEN, "CAST-KEY-GEN", NULL }, - { CKM_CAST_ECB, "CAST-ECB", NULL }, - { CKM_CAST_CBC, "CAST-CBC", NULL }, - { CKM_CAST_MAC, "CAST-MAC", NULL }, - { CKM_CAST_MAC_GENERAL, "CAST-MAC-GENERAL", NULL }, - { CKM_CAST_CBC_PAD, "CAST-CBC-PAD", NULL }, - { CKM_CAST3_KEY_GEN, "CAST3-KEY-GEN", NULL }, - { CKM_CAST3_ECB, "CAST3-ECB", NULL }, - { CKM_CAST3_CBC, "CAST3-CBC", NULL }, - { CKM_CAST3_MAC, "CAST3-MAC", NULL }, - { CKM_CAST3_MAC_GENERAL, "CAST3-MAC-GENERAL", NULL }, - { CKM_CAST3_CBC_PAD, "CAST3-CBC-PAD", NULL }, - { CKM_CAST5_KEY_GEN, "CAST5-KEY-GEN", NULL }, - { CKM_CAST5_ECB, "CAST5-ECB", NULL }, - { CKM_CAST5_CBC, "CAST5-CBC", NULL }, - { CKM_CAST5_MAC, "CAST5-MAC", NULL }, - { CKM_CAST5_MAC_GENERAL, "CAST5-MAC-GENERAL", NULL }, - { CKM_CAST5_CBC_PAD, "CAST5-CBC-PAD", NULL }, - { CKM_RC5_KEY_GEN, "RC5-KEY-GEN", NULL }, - { CKM_RC5_ECB, "RC5-ECB", NULL }, - { CKM_RC5_CBC, "RC5-CBC", NULL }, - { CKM_RC5_MAC, "RC5-MAC", NULL }, - { CKM_RC5_MAC_GENERAL, "RC5-MAC-GENERAL", NULL }, - { CKM_RC5_CBC_PAD, "RC5-CBC-PAD", NULL }, - { CKM_IDEA_KEY_GEN, "IDEA-KEY-GEN", NULL }, - { CKM_IDEA_ECB, "IDEA-ECB", NULL }, - { CKM_IDEA_CBC, "IDEA-CBC", NULL }, - { CKM_IDEA_MAC, "IDEA-MAC", NULL }, - { CKM_IDEA_MAC_GENERAL, "IDEA-MAC-GENERAL", NULL }, - { CKM_IDEA_CBC_PAD, "IDEA-CBC-PAD", NULL }, - { CKM_GENERIC_SECRET_KEY_GEN,"GENERIC-SECRET-KEY-GEN", NULL }, - { CKM_CONCATENATE_BASE_AND_KEY,"CONCATENATE-BASE-AND-KEY", NULL }, - { CKM_CONCATENATE_BASE_AND_DATA,"CONCATENATE-BASE-AND-DATA", NULL }, - { CKM_CONCATENATE_DATA_AND_BASE,"CONCATENATE-DATA-AND-BASE", NULL }, - { CKM_XOR_BASE_AND_DATA, "XOR-BASE-AND-DATA", NULL }, - { CKM_EXTRACT_KEY_FROM_KEY,"EXTRACT-KEY-FROM-KEY", NULL }, - { CKM_SSL3_PRE_MASTER_KEY_GEN,"SSL3-PRE-MASTER-KEY-GEN", NULL }, - { CKM_SSL3_MASTER_KEY_DERIVE,"SSL3-MASTER-KEY-DERIVE", NULL }, - { CKM_SSL3_KEY_AND_MAC_DERIVE,"SSL3-KEY-AND-MAC-DERIVE", NULL }, - { CKM_SSL3_MASTER_KEY_DERIVE_DH,"SSL3-MASTER-KEY-DERIVE-DH", NULL }, - { CKM_TLS_PRE_MASTER_KEY_GEN,"TLS-PRE-MASTER-KEY-GEN", NULL }, - { CKM_TLS_MASTER_KEY_DERIVE,"TLS-MASTER-KEY-DERIVE", NULL }, - { CKM_TLS_KEY_AND_MAC_DERIVE,"TLS-KEY-AND-MAC-DERIVE", NULL }, - { CKM_TLS_MASTER_KEY_DERIVE_DH,"TLS-MASTER-KEY-DERIVE-DH", NULL }, - { CKM_SSL3_MD5_MAC, "SSL3-MD5-MAC", NULL }, - { CKM_SSL3_SHA1_MAC, "SSL3-SHA1-MAC", NULL }, - { CKM_MD5_KEY_DERIVATION, "MD5-KEY-DERIVATION", NULL }, - { CKM_MD2_KEY_DERIVATION, "MD2-KEY-DERIVATION", NULL }, - { CKM_SHA1_KEY_DERIVATION,"SHA1-KEY-DERIVATION", NULL }, - { CKM_PBE_MD2_DES_CBC, "PBE-MD2-DES-CBC", NULL }, - { CKM_PBE_MD5_DES_CBC, "PBE-MD5-DES-CBC", NULL }, - { CKM_PBE_MD5_CAST_CBC, "PBE-MD5-CAST-CBC", NULL }, - { CKM_PBE_MD5_CAST3_CBC, "PBE-MD5-CAST3-CBC", NULL }, - { CKM_PBE_MD5_CAST5_CBC, "PBE-MD5-CAST5-CBC", NULL }, - { CKM_PBE_SHA1_CAST5_CBC, "PBE-SHA1-CAST5-CBC", NULL }, - { CKM_PBE_SHA1_RC4_128, "PBE-SHA1-RC4-128", NULL }, - { CKM_PBE_SHA1_RC4_40, "PBE-SHA1-RC4-40", NULL }, - { CKM_PBE_SHA1_DES3_EDE_CBC,"PBE-SHA1-DES3-EDE-CBC", NULL }, - { CKM_PBE_SHA1_DES2_EDE_CBC,"PBE-SHA1-DES2-EDE-CBC", NULL }, - { CKM_PBE_SHA1_RC2_128_CBC,"PBE-SHA1-RC2-128-CBC", NULL }, - { CKM_PBE_SHA1_RC2_40_CBC,"PBE-SHA1-RC2-40-CBC", NULL }, - { CKM_PKCS5_PBKD2, "PKCS5-PBKD2", NULL }, - { CKM_PBA_SHA1_WITH_SHA1_HMAC,"PBA-SHA1-WITH-SHA1-HMAC", NULL }, - { CKM_KEY_WRAP_LYNKS, "KEY-WRAP-LYNKS", NULL }, - { CKM_KEY_WRAP_SET_OAEP, "KEY-WRAP-SET-OAEP", NULL }, - { CKM_SKIPJACK_KEY_GEN, "SKIPJACK-KEY-GEN", NULL }, - { CKM_SKIPJACK_ECB64, "SKIPJACK-ECB64", NULL }, - { CKM_SKIPJACK_CBC64, "SKIPJACK-CBC64", NULL }, - { CKM_SKIPJACK_OFB64, "SKIPJACK-OFB64", NULL }, - { CKM_SKIPJACK_CFB64, "SKIPJACK-CFB64", NULL }, - { CKM_SKIPJACK_CFB32, "SKIPJACK-CFB32", NULL }, - { CKM_SKIPJACK_CFB16, "SKIPJACK-CFB16", NULL }, - { CKM_SKIPJACK_CFB8, "SKIPJACK-CFB8", NULL }, - { CKM_SKIPJACK_WRAP, "SKIPJACK-WRAP", NULL }, - { CKM_SKIPJACK_PRIVATE_WRAP,"SKIPJACK-PRIVATE-WRAP", NULL }, - { CKM_SKIPJACK_RELAYX, "SKIPJACK-RELAYX", NULL }, - { CKM_KEA_KEY_PAIR_GEN, "KEA-KEY-PAIR-GEN", NULL }, - { CKM_KEA_KEY_DERIVE, "KEA-KEY-DERIVE", NULL }, - { CKM_FORTEZZA_TIMESTAMP, "FORTEZZA-TIMESTAMP", NULL }, - { CKM_BATON_KEY_GEN, "BATON-KEY-GEN", NULL }, - { CKM_BATON_ECB128, "BATON-ECB128", NULL }, - { CKM_BATON_ECB96, "BATON-ECB96", NULL }, - { CKM_BATON_CBC128, "BATON-CBC128", NULL }, - { CKM_BATON_COUNTER, "BATON-COUNTER", NULL }, - { CKM_BATON_SHUFFLE, "BATON-SHUFFLE", NULL }, - { CKM_BATON_WRAP, "BATON-WRAP", NULL }, - { CKM_ECDSA_KEY_PAIR_GEN, "ECDSA-KEY-PAIR-GEN", NULL }, - { CKM_ECDSA, "ECDSA", NULL }, - { CKM_ECDSA_SHA1, "ECDSA-SHA1", NULL }, - { CKM_ECDSA_SHA224, "ECDSA-SHA224", NULL }, - { CKM_ECDSA_SHA256, "ECDSA-SHA256", NULL }, - { CKM_ECDSA_SHA384, "ECDSA-SHA384", NULL }, - { CKM_ECDSA_SHA512, "ECDSA-SHA512", NULL }, - { CKM_ECDH1_DERIVE, "ECDH1-DERIVE", NULL }, - { CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL }, - { CKM_ECMQV_DERIVE, "ECMQV-DERIVE", NULL }, - { CKM_EC_EDWARDS_KEY_PAIR_GEN,"EC-EDWARDS-KEY-PAIR-GEN", NULL }, - { CKM_EC_MONTGOMERY_KEY_PAIR_GEN,"EC-MONTGOMERY-KEY-PAIR-GEN", NULL }, - { CKM_EDDSA, "EDDSA", NULL }, - { CKM_XEDDSA, "XEDDSA", NULL }, - { CKM_JUNIPER_KEY_GEN, "JUNIPER-KEY-GEN", NULL }, - { CKM_JUNIPER_ECB128, "JUNIPER-ECB128", NULL }, - { CKM_JUNIPER_CBC128, "JUNIPER-CBC128", NULL }, - { CKM_JUNIPER_COUNTER, "JUNIPER-COUNTER", NULL }, - { CKM_JUNIPER_SHUFFLE, "JUNIPER-SHUFFLE", NULL }, - { CKM_JUNIPER_WRAP, "JUNIPER-WRAP", NULL }, - { CKM_FASTHASH, "FASTHASH", NULL }, - { CKM_AES_KEY_GEN, "AES-KEY-GEN", NULL }, - { CKM_AES_ECB, "AES-ECB", NULL }, - { CKM_AES_CBC, "AES-CBC", NULL }, - { CKM_AES_MAC, "AES-MAC", NULL }, - { CKM_AES_MAC_GENERAL, "AES-MAC-GENERAL", NULL }, - { CKM_AES_CBC_PAD, "AES-CBC-PAD", NULL }, - { CKM_AES_CTR, "AES-CTR", NULL }, - { CKM_AES_GCM, "AES-GCM", NULL }, - { CKM_AES_CMAC, "AES-CMAC", NULL }, - { CKM_DES_ECB_ENCRYPT_DATA, "DES-ECB-ENCRYPT-DATA", NULL }, - { CKM_DES_CBC_ENCRYPT_DATA, "DES-CBC-ENCRYPT-DATA", NULL }, - { CKM_DES3_ECB_ENCRYPT_DATA, "DES3-ECB-ENCRYPT-DATA", NULL }, - { CKM_DES3_CBC_ENCRYPT_DATA, "DES3-CBC-ENCRYPT-DATA", NULL }, - { CKM_AES_ECB_ENCRYPT_DATA, "AES-ECB-ENCRYPT-DATA", NULL }, - { CKM_AES_CBC_ENCRYPT_DATA, "AES-CBC-ENCRYPT-DATA", NULL }, - { CKM_GOST28147_KEY_GEN, "GOST28147-KEY-GEN", NULL }, - { CKM_GOST28147_ECB, "GOST28147-ECB", NULL }, - { CKM_GOST28147, "GOST28147", NULL }, - { CKM_GOST28147_MAC, "GOST28147-MAC", NULL }, - { CKM_GOST28147_KEY_WRAP, "GOST28147-KEY-WRAP", NULL }, - { CKM_GOSTR3410_KEY_PAIR_GEN,"GOSTR3410-KEY-PAIR-GEN", NULL }, - { CKM_GOSTR3410, "GOSTR3410", NULL }, - { CKM_GOSTR3410_DERIVE, "GOSTR3410-DERIVE", NULL }, - { CKM_GOSTR3410_WITH_GOSTR3411,"GOSTR3410-WITH-GOSTR3411", NULL }, - { CKM_GOSTR3410_512_KEY_PAIR_GEN, "GOSTR3410-512-KEY-PAIR-GEN", NULL }, - { CKM_GOSTR3410_512, "GOSTR3410_512", NULL }, - { CKM_GOSTR3410_12_DERIVE, "GOSTR3410-12-DERIVE", NULL }, - { CKM_GOSTR3410_WITH_GOSTR3411_12_256, "GOSTR3410-WITH-GOSTR3411-12-256", NULL }, - { CKM_GOSTR3410_WITH_GOSTR3411_12_512, "GOSTR3410-WITH-GOSTR3411-12-512", NULL }, - { CKM_GOSTR3411, "GOSTR3411", NULL }, - { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL }, - { CKM_GOSTR3411_12_256, "GOSTR3411-12-256", NULL }, - { CKM_GOSTR3411_12_512, "GOSTR3411-12-512", NULL }, - { CKM_GOSTR3411_12_256_HMAC, "GOSTR3411-12-256-HMAC", NULL }, - { CKM_GOSTR3411_12_512_HMAC, "GOSTR3411-12-512-HMAC", NULL }, - { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL }, - { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL }, - { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL }, - { CKM_AES_KEY_WRAP, "AES-KEY-WRAP", NULL}, - { 0, NULL, NULL } + { CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA-PKCS-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_RSA_PKCS, "RSA-PKCS", NULL, MF_UNKNOWN }, + { CKM_RSA_9796, "RSA-9796", NULL, MF_UNKNOWN }, + { CKM_RSA_X_509, "RSA-X-509", NULL, MF_UNKNOWN }, + { CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS", NULL, MF_UNKNOWN }, + { CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5", MF_UNKNOWN }, + { CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1", MF_UNKNOWN }, + { CKM_SHA224_RSA_PKCS, "SHA224-RSA-PKCS", "rsa-sha224", MF_UNKNOWN }, + { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256", MF_UNKNOWN }, + { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384", MF_UNKNOWN }, + { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512", MF_UNKNOWN }, + { CKM_RIPEMD128_RSA_PKCS, "RIPEMD128-RSA-PKCS", NULL, MF_UNKNOWN }, + { CKM_RIPEMD160_RSA_PKCS, "RIPEMD160-RSA-PKCS", "rsa-ripemd160", MF_UNKNOWN }, + { CKM_RSA_PKCS_OAEP, "RSA-PKCS-OAEP", NULL, MF_UNKNOWN }, + { CKM_RSA_X9_31_KEY_PAIR_GEN,"RSA-X9-31-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_RSA_X9_31, "RSA-X9-31", NULL, MF_UNKNOWN }, + { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL, MF_UNKNOWN }, + { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL, MF_UNKNOWN }, + { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1", MF_UNKNOWN }, + { CKM_SHA224_RSA_PKCS_PSS,"SHA224-RSA-PKCS-PSS", "rsa-pss-sha224", MF_UNKNOWN }, + { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256", MF_UNKNOWN }, + { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384", MF_UNKNOWN }, + { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512", MF_UNKNOWN }, + { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_DSA, "DSA", NULL, MF_UNKNOWN }, + { CKM_DSA_SHA1, "DSA-SHA1", NULL, MF_UNKNOWN }, + { CKM_DSA_SHA224, "DSA-SHA224", NULL, MF_UNKNOWN }, + { CKM_DSA_SHA256, "DSA-SHA256", NULL, MF_UNKNOWN }, + { CKM_DSA_SHA384, "DSA-SHA384", NULL, MF_UNKNOWN }, + { CKM_DSA_SHA512, "DSA-SHA512", NULL, MF_UNKNOWN }, + { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_DH_PKCS_DERIVE, "DH-PKCS-DERIVE", NULL, MF_UNKNOWN }, + { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_X9_42_DH_DERIVE, "X9-42-DH-DERIVE", NULL, MF_UNKNOWN }, + { CKM_X9_42_DH_HYBRID_DERIVE,"X9-42-DH-HYBRID-DERIVE", NULL, MF_UNKNOWN }, + { CKM_X9_42_MQV_DERIVE, "X9-42-MQV-DERIVE", NULL, MF_UNKNOWN }, + { CKM_RC2_KEY_GEN, "RC2-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_RC2_ECB, "RC2-ECB", NULL, MF_UNKNOWN }, + { CKM_RC2_CBC, "RC2-CBC", NULL, MF_UNKNOWN }, + { CKM_RC2_MAC, "RC2-MAC", NULL, MF_UNKNOWN }, + { CKM_RC2_MAC_GENERAL, "RC2-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_RC2_CBC_PAD, "RC2-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_RC4_KEY_GEN, "RC4-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_RC4, "RC4", NULL, MF_UNKNOWN }, + { CKM_DES_KEY_GEN, "DES-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_DES_ECB, "DES-ECB", NULL, MF_UNKNOWN }, + { CKM_DES_CBC, "DES-CBC", NULL, MF_UNKNOWN }, + { CKM_DES_MAC, "DES-MAC", NULL, MF_UNKNOWN }, + { CKM_DES_MAC_GENERAL, "DES-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_DES_CBC_PAD, "DES-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_DES2_KEY_GEN, "DES2-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_DES3_KEY_GEN, "DES3-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_DES3_ECB, "DES3-ECB", NULL, MF_UNKNOWN }, + { CKM_DES3_CBC, "DES3-CBC", NULL, MF_UNKNOWN }, + { CKM_DES3_MAC, "DES3-MAC", NULL, MF_UNKNOWN }, + { CKM_DES3_MAC_GENERAL, "DES3-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_DES3_CBC_PAD, "DES3-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_DES3_CMAC, "DES3-CMAC", NULL, MF_UNKNOWN }, + { CKM_CDMF_KEY_GEN, "CDMF-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_CDMF_ECB, "CDMF-ECB", NULL, MF_UNKNOWN }, + { CKM_CDMF_CBC, "CDMF-CBC", NULL, MF_UNKNOWN }, + { CKM_CDMF_MAC, "CDMF-MAC", NULL, MF_UNKNOWN }, + { CKM_CDMF_MAC_GENERAL, "CDMF-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_CDMF_CBC_PAD, "CDMF-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_MD2, "MD2", NULL, MF_UNKNOWN }, + { CKM_MD2_HMAC, "MD2-HMAC", NULL, MF_UNKNOWN }, + { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_MD5, "MD5", NULL, MF_UNKNOWN }, + { CKM_MD5_HMAC, "MD5-HMAC", NULL, MF_UNKNOWN }, + { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_SHA_1, "SHA-1", NULL, MF_UNKNOWN }, + { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_SHA224, "SHA224", NULL, MF_UNKNOWN }, + { CKM_SHA224_HMAC, "SHA224-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_SHA256, "SHA256", NULL, MF_UNKNOWN }, + { CKM_SHA256_HMAC, "SHA256-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_SHA384, "SHA384", NULL, MF_UNKNOWN }, + { CKM_SHA384_HMAC, "SHA384-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_SHA512, "SHA512", NULL, MF_UNKNOWN }, + { CKM_SHA512_HMAC, "SHA512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_RIPEMD128, "RIPEMD128", NULL, MF_UNKNOWN }, + { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL, MF_UNKNOWN }, + { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_RIPEMD160, "RIPEMD160", NULL, MF_UNKNOWN }, + { CKM_RIPEMD160_HMAC, "RIPEMD160-HMAC", NULL, MF_UNKNOWN }, + { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_CAST_KEY_GEN, "CAST-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_CAST_ECB, "CAST-ECB", NULL, MF_UNKNOWN }, + { CKM_CAST_CBC, "CAST-CBC", NULL, MF_UNKNOWN }, + { CKM_CAST_MAC, "CAST-MAC", NULL, MF_UNKNOWN }, + { CKM_CAST_MAC_GENERAL, "CAST-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_CAST_CBC_PAD, "CAST-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_CAST3_KEY_GEN, "CAST3-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_CAST3_ECB, "CAST3-ECB", NULL, MF_UNKNOWN }, + { CKM_CAST3_CBC, "CAST3-CBC", NULL, MF_UNKNOWN }, + { CKM_CAST3_MAC, "CAST3-MAC", NULL, MF_UNKNOWN }, + { CKM_CAST3_MAC_GENERAL, "CAST3-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_CAST3_CBC_PAD, "CAST3-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_CAST5_KEY_GEN, "CAST5-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_CAST5_ECB, "CAST5-ECB", NULL, MF_UNKNOWN }, + { CKM_CAST5_CBC, "CAST5-CBC", NULL, MF_UNKNOWN }, + { CKM_CAST5_MAC, "CAST5-MAC", NULL, MF_UNKNOWN }, + { CKM_CAST5_MAC_GENERAL, "CAST5-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_CAST5_CBC_PAD, "CAST5-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_RC5_KEY_GEN, "RC5-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_RC5_ECB, "RC5-ECB", NULL, MF_UNKNOWN }, + { CKM_RC5_CBC, "RC5-CBC", NULL, MF_UNKNOWN }, + { CKM_RC5_MAC, "RC5-MAC", NULL, MF_UNKNOWN }, + { CKM_RC5_MAC_GENERAL, "RC5-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_RC5_CBC_PAD, "RC5-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_IDEA_KEY_GEN, "IDEA-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_IDEA_ECB, "IDEA-ECB", NULL, MF_UNKNOWN }, + { CKM_IDEA_CBC, "IDEA-CBC", NULL, MF_UNKNOWN }, + { CKM_IDEA_MAC, "IDEA-MAC", NULL, MF_UNKNOWN }, + { CKM_IDEA_MAC_GENERAL, "IDEA-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_IDEA_CBC_PAD, "IDEA-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_GENERIC_SECRET_KEY_GEN,"GENERIC-SECRET-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_CONCATENATE_BASE_AND_KEY,"CONCATENATE-BASE-AND-KEY", NULL, MF_UNKNOWN }, + { CKM_CONCATENATE_BASE_AND_DATA,"CONCATENATE-BASE-AND-DATA", NULL, MF_UNKNOWN }, + { CKM_CONCATENATE_DATA_AND_BASE,"CONCATENATE-DATA-AND-BASE", NULL, MF_UNKNOWN }, + { CKM_XOR_BASE_AND_DATA, "XOR-BASE-AND-DATA", NULL, MF_UNKNOWN }, + { CKM_EXTRACT_KEY_FROM_KEY,"EXTRACT-KEY-FROM-KEY", NULL, MF_UNKNOWN }, + { CKM_SSL3_PRE_MASTER_KEY_GEN,"SSL3-PRE-MASTER-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_SSL3_MASTER_KEY_DERIVE,"SSL3-MASTER-KEY-DERIVE", NULL, MF_UNKNOWN }, + { CKM_SSL3_KEY_AND_MAC_DERIVE,"SSL3-KEY-AND-MAC-DERIVE", NULL, MF_UNKNOWN }, + { CKM_SSL3_MASTER_KEY_DERIVE_DH,"SSL3-MASTER-KEY-DERIVE-DH", NULL, MF_UNKNOWN }, + { CKM_TLS_PRE_MASTER_KEY_GEN,"TLS-PRE-MASTER-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_TLS_MASTER_KEY_DERIVE,"TLS-MASTER-KEY-DERIVE", NULL, MF_UNKNOWN }, + { CKM_TLS_KEY_AND_MAC_DERIVE,"TLS-KEY-AND-MAC-DERIVE", NULL, MF_UNKNOWN }, + { CKM_TLS_MASTER_KEY_DERIVE_DH,"TLS-MASTER-KEY-DERIVE-DH", NULL, MF_UNKNOWN }, + { CKM_SSL3_MD5_MAC, "SSL3-MD5-MAC", NULL, MF_UNKNOWN }, + { CKM_SSL3_SHA1_MAC, "SSL3-SHA1-MAC", NULL, MF_UNKNOWN }, + { CKM_MD5_KEY_DERIVATION, "MD5-KEY-DERIVATION", NULL, MF_UNKNOWN }, + { CKM_MD2_KEY_DERIVATION, "MD2-KEY-DERIVATION", NULL, MF_UNKNOWN }, + { CKM_SHA1_KEY_DERIVATION,"SHA1-KEY-DERIVATION", NULL, MF_UNKNOWN }, + { CKM_PBE_MD2_DES_CBC, "PBE-MD2-DES-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_MD5_DES_CBC, "PBE-MD5-DES-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_MD5_CAST_CBC, "PBE-MD5-CAST-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_MD5_CAST3_CBC, "PBE-MD5-CAST3-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_MD5_CAST5_CBC, "PBE-MD5-CAST5-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_CAST5_CBC, "PBE-SHA1-CAST5-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_RC4_128, "PBE-SHA1-RC4-128", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_RC4_40, "PBE-SHA1-RC4-40", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_DES3_EDE_CBC,"PBE-SHA1-DES3-EDE-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_DES2_EDE_CBC,"PBE-SHA1-DES2-EDE-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_RC2_128_CBC,"PBE-SHA1-RC2-128-CBC", NULL, MF_UNKNOWN }, + { CKM_PBE_SHA1_RC2_40_CBC,"PBE-SHA1-RC2-40-CBC", NULL, MF_UNKNOWN }, + { CKM_PKCS5_PBKD2, "PKCS5-PBKD2", NULL, MF_UNKNOWN }, + { CKM_PBA_SHA1_WITH_SHA1_HMAC,"PBA-SHA1-WITH-SHA1-HMAC", NULL, MF_UNKNOWN }, + { CKM_KEY_WRAP_LYNKS, "KEY-WRAP-LYNKS", NULL, MF_UNKNOWN }, + { CKM_KEY_WRAP_SET_OAEP, "KEY-WRAP-SET-OAEP", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_KEY_GEN, "SKIPJACK-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_ECB64, "SKIPJACK-ECB64", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_CBC64, "SKIPJACK-CBC64", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_OFB64, "SKIPJACK-OFB64", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_CFB64, "SKIPJACK-CFB64", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_CFB32, "SKIPJACK-CFB32", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_CFB16, "SKIPJACK-CFB16", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_CFB8, "SKIPJACK-CFB8", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_WRAP, "SKIPJACK-WRAP", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_PRIVATE_WRAP,"SKIPJACK-PRIVATE-WRAP", NULL, MF_UNKNOWN }, + { CKM_SKIPJACK_RELAYX, "SKIPJACK-RELAYX", NULL, MF_UNKNOWN }, + { CKM_KEA_KEY_PAIR_GEN, "KEA-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_KEA_KEY_DERIVE, "KEA-KEY-DERIVE", NULL, MF_UNKNOWN }, + { CKM_FORTEZZA_TIMESTAMP, "FORTEZZA-TIMESTAMP", NULL, MF_UNKNOWN }, + { CKM_BATON_KEY_GEN, "BATON-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_BATON_ECB128, "BATON-ECB128", NULL, MF_UNKNOWN }, + { CKM_BATON_ECB96, "BATON-ECB96", NULL, MF_UNKNOWN }, + { CKM_BATON_CBC128, "BATON-CBC128", NULL, MF_UNKNOWN }, + { CKM_BATON_COUNTER, "BATON-COUNTER", NULL, MF_UNKNOWN }, + { CKM_BATON_SHUFFLE, "BATON-SHUFFLE", NULL, MF_UNKNOWN }, + { CKM_BATON_WRAP, "BATON-WRAP", NULL, MF_UNKNOWN }, + { CKM_ECDSA_KEY_PAIR_GEN, "ECDSA-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_ECDSA, "ECDSA", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA1, "ECDSA-SHA1", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA224, "ECDSA-SHA224", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA256, "ECDSA-SHA256", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA384, "ECDSA-SHA384", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA512, "ECDSA-SHA512", NULL, MF_UNKNOWN }, + { CKM_ECDH1_DERIVE, "ECDH1-DERIVE", NULL, MF_UNKNOWN }, + { CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL, MF_UNKNOWN }, + { CKM_ECMQV_DERIVE, "ECMQV-DERIVE", NULL, MF_UNKNOWN }, + { CKM_EC_EDWARDS_KEY_PAIR_GEN,"EC-EDWARDS-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_EC_MONTGOMERY_KEY_PAIR_GEN,"EC-MONTGOMERY-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_EDDSA, "EDDSA", NULL, MF_UNKNOWN }, + { CKM_XEDDSA, "XEDDSA", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_KEY_GEN, "JUNIPER-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_ECB128, "JUNIPER-ECB128", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_CBC128, "JUNIPER-CBC128", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_COUNTER, "JUNIPER-COUNTER", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_SHUFFLE, "JUNIPER-SHUFFLE", NULL, MF_UNKNOWN }, + { CKM_JUNIPER_WRAP, "JUNIPER-WRAP", NULL, MF_UNKNOWN }, + { CKM_FASTHASH, "FASTHASH", NULL, MF_UNKNOWN }, + { CKM_AES_KEY_GEN, "AES-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_AES_ECB, "AES-ECB", NULL, MF_UNKNOWN }, + { CKM_AES_CBC, "AES-CBC", NULL, MF_UNKNOWN }, + { CKM_AES_MAC, "AES-MAC", NULL, MF_UNKNOWN }, + { CKM_AES_MAC_GENERAL, "AES-MAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_AES_CBC_PAD, "AES-CBC-PAD", NULL, MF_UNKNOWN }, + { CKM_AES_CTR, "AES-CTR", NULL, MF_UNKNOWN }, + { CKM_AES_GCM, "AES-GCM", NULL, MF_UNKNOWN }, + { CKM_AES_CMAC, "AES-CMAC", NULL, MF_UNKNOWN }, + { CKM_DES_ECB_ENCRYPT_DATA, "DES-ECB-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_DES_CBC_ENCRYPT_DATA, "DES-CBC-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_DES3_ECB_ENCRYPT_DATA, "DES3-ECB-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_DES3_CBC_ENCRYPT_DATA, "DES3-CBC-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_AES_ECB_ENCRYPT_DATA, "AES-ECB-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_AES_CBC_ENCRYPT_DATA, "AES-CBC-ENCRYPT-DATA", NULL, MF_UNKNOWN }, + { CKM_GOST28147_KEY_GEN, "GOST28147-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_GOST28147_ECB, "GOST28147-ECB", NULL, MF_UNKNOWN }, + { CKM_GOST28147, "GOST28147", NULL, MF_UNKNOWN }, + { CKM_GOST28147_MAC, "GOST28147-MAC", NULL, MF_UNKNOWN }, + { CKM_GOST28147_KEY_WRAP, "GOST28147-KEY-WRAP", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_KEY_PAIR_GEN,"GOSTR3410-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410, "GOSTR3410", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_DERIVE, "GOSTR3410-DERIVE", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_WITH_GOSTR3411,"GOSTR3410-WITH-GOSTR3411", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_512_KEY_PAIR_GEN, "GOSTR3410-512-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_512, "GOSTR3410_512", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_12_DERIVE, "GOSTR3410-12-DERIVE", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_WITH_GOSTR3411_12_256, "GOSTR3410-WITH-GOSTR3411-12-256", NULL, MF_UNKNOWN }, + { CKM_GOSTR3410_WITH_GOSTR3411_12_512, "GOSTR3410-WITH-GOSTR3411-12-512", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411, "GOSTR3411", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_12_256, "GOSTR3411-12-256", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_12_512, "GOSTR3411-12-512", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_12_256_HMAC, "GOSTR3411-12-256-HMAC", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_12_512_HMAC, "GOSTR3411-12-512-HMAC", NULL, MF_UNKNOWN }, + { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL, MF_UNKNOWN }, + { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL, MF_UNKNOWN }, + { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL, MF_UNKNOWN }, + { CKM_AES_KEY_WRAP, "AES-KEY-WRAP", NULL, MF_UNKNOWN }, + { 0, NULL, NULL, MF_UNKNOWN } }; static struct mech_info p11_mgf[] = { - { CKG_MGF1_SHA1, "MGF1-SHA1", NULL }, - { CKG_MGF1_SHA224, "MGF1-SHA224", NULL }, - { CKG_MGF1_SHA256, "MGF1-SHA256", NULL }, - { CKG_MGF1_SHA384, "MGF1-SHA384", NULL }, - { CKG_MGF1_SHA512, "MGF1-SHA512", NULL }, - { 0, NULL, NULL } + { CKG_MGF1_SHA1, "MGF1-SHA1", NULL, MF_MGF }, + { CKG_MGF1_SHA224, "MGF1-SHA224", NULL, MF_MGF }, + { CKG_MGF1_SHA256, "MGF1-SHA256", NULL, MF_MGF }, + { CKG_MGF1_SHA384, "MGF1-SHA384", NULL, MF_MGF }, + { CKG_MGF1_SHA512, "MGF1-SHA512", NULL, MF_MGF }, + { 0, NULL, NULL, MF_UNKNOWN } }; static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech) @@ -7198,6 +7270,25 @@ static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech) return temp; } +uint16_t p11_mechanism_to_flags(CK_MECHANISM_TYPE mech) +{ + struct mech_info *mi; + for (mi = p11_mechanisms; mi->name; mi++) { + if (mi->mech == mech) + return mi->mf_flags; + } + + /* + * XXX: Since populating the table is underway we won't warn until its done. Existing mechanisms function + * as they used to. So guard this on verbose. + */ + if (verbose) { + util_warn("mechanism 0x%lx not found, consider adding it to mechanism table", mech); + } + + return MF_UNKNOWN; +} + static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name) { struct mech_info *mi; From d1024494bf72b8c3db5c7ca2d79b575084885f4d Mon Sep 17 00:00:00 2001 From: William Roberts Date: Tue, 17 Aug 2021 14:23:45 -0500 Subject: [PATCH 1948/4321] test: add a an HMAC C_Sign/C_Verify test This tests that a Token with a single CKO_SECRET_KEY can be used in HMAC for SHA1, SHA256, SHA284 and SHA512 hash versions. Since pkcs11 tool does not support --id setting on CKO_SECRET_KEY nor respects the --label option for C_Sign and C_Verify, one may not get the key they expect. Signed-off-by: William Roberts --- tests/common.sh | 3 +++ tests/test-pkcs11-tool-sign-verify.sh | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/common.sh b/tests/common.sh index aa1312eb98..89e2be29a6 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -76,6 +76,9 @@ function card_setup() { generate_key "EC:secp256r1" "03" "ECC_auth" # Generate 521b ECC Key pair generate_key "EC:secp521r1" "04" "ECC521" + # Generate an HMAC:SHA256 key + $PKCS11_TOOL --keypairgen --key-type="GENERIC:64" --login --pin=$PIN \ + --module="$P11LIB" --label="HMAC-SHA256" } function softhsm_cleanup() { diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index a563841bca..3a9b410248 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -144,6 +144,27 @@ for SIGN_KEY in "03" "04"; do rm data.sig{,.openssl} data.hash done +echo "=======================================================" +echo "Test GENERIC keys" +echo "=======================================================" + +echo "Hello World" > data.msg + +for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do + echo + echo "=======================================================" + echo "$MECHANISM: Sign & Verify (KEY (First Found))" + echo "=======================================================" + + $PKCS11_TOOL --login --pin=1234 --sign --mechanism=$MECHANISM \ + --input-file=data.msg --output-file=data.sig + $PKCS11_TOOL --login --pin=1234 --verify --mechanism=$MECHANISM \ + --input-file=data.msg --signature-file=data.sig + rm data.sig +done; + +rm data.msg + echo "=======================================================" echo "Cleanup" echo "=======================================================" From 5dd68056f8cd16607df17adb5c5bab5e8fb33103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=BB=D0=B8=D1=86=D1=8B=D0=BD=20?= =?UTF-8?q?=D0=9F=D0=B5=D1=82=D1=80?= Date: Mon, 12 Apr 2021 16:06:15 +0300 Subject: [PATCH 1949/4321] get hex name for unknown objects --- src/pkcs11/framework-pkcs15.c | 7 ++++- src/pkcs11/pkcs11-display.c | 4 +-- src/pkcs11/pkcs11-global.c | 28 +++++++++++++++--- src/pkcs11/pkcs11-object.c | 56 ++++++++++++++++++++++++----------- src/pkcs11/pkcs11-session.c | 25 ++++++++++++++-- src/pkcs11/pkcs11-spy.c | 45 +++++++++++++++++++++------- src/tools/pkcs15-tool.c | 2 ++ 7 files changed, 130 insertions(+), 37 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 4fc8f13ab4..d3366a97f3 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -606,7 +606,12 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO)); out: sc_pkcs11_unlock(); - sc_log(context, "C_GetTokenInfo(%lx) returns %s", slotID, lookup_enum(RV_T, rv)); + + const char *name = lookup_enum(RV_T, rv); + if (name) + sc_log(context, "C_GetTokenInfo(%lx) returns %s", slotID, name); + else + sc_log(context, "C_GetTokenInfo(%lx) returns 0x%08lX", slotID, rv); return rv; } diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 9fa24a6c1b..97b1622030 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -864,7 +864,7 @@ lookup_enum(CK_ULONG type, CK_ULONG value) void show_error( FILE *f, char *str, CK_RV rc ) { - fprintf(f, "%s returned: %ld %s", str, (unsigned long) rc, lookup_enum ( RV_T, rc )); + fprintf(f, "%s returned: %ld %s", str, (unsigned long) rc, lookup_enum (RV_T, rc )); fprintf(f, "\n"); } @@ -1102,7 +1102,7 @@ print_session_info(FILE *f, CK_SESSION_INFO *info) }; fprintf(f, " slotID: %ld\n", info->slotID ); - fprintf(f, " state: '%32.32s'\n", lookup_enum(STA_T, info->state)); + fprintf(f, " state: %0lx (%32.32s)\n", info->state, lookup_enum(STA_T, info->state)); fprintf(f, " flags: %0lx\n", info->flags ); for(i = 0; i < sizeof (ck_flags) / sizeof (*ck_flags); i++) { diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index e77eb806ae..8369d56332 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -283,6 +283,22 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, } #endif +#define SC_LOG_RV(fmt, rv)\ +do {\ + const char *name = lookup_enum(RV_T, (rv));\ + if (name)\ + sc_log(context, (fmt), name);\ + else {\ + size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ + char *buffer = malloc(needed);\ + if (buffer) {\ + sprintf(buffer, "0x%08lX", (rv));\ + sc_log(context, (fmt), buffer);\ + free(buffer);\ + }\ + }\ +} while(0) + CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { CK_RV rv; @@ -349,7 +365,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) out: if (context != NULL) - sc_log(context, "C_Initialize() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_Initialize() = %s", rv); if (rv != CKR_OK) { if (context != NULL) { @@ -613,7 +629,7 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) rv = slot_get_slot(slotID, &slot); DEBUG_VSS(slot, "C_GetSlotInfo found"); - sc_log(context, "C_GetSlotInfo() get slot rv %s", lookup_enum( RV_T, rv)); + SC_LOG_RV("C_GetSlotInfo() get slot rv %s", rv); if (rv == CKR_OK) { if (slot->reader == NULL) { rv = CKR_TOKEN_NOT_PRESENT; @@ -640,7 +656,11 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) memcpy(pInfo, &slot->slot_info, sizeof(CK_SLOT_INFO)); sc_log(context, "C_GetSlotInfo() flags 0x%lX", pInfo->flags); - sc_log(context, "C_GetSlotInfo(0x%lx) = %s", slotID, lookup_enum( RV_T, rv)); + const char *name = lookup_enum(RV_T, rv); + if (name) + sc_log(context, "C_GetSlotInfo(0x%lx) = %s", slotID, name); + else + sc_log(context, "C_GetSlotInfo(0x%lx) = 0x%08lX", slotID, rv); sc_pkcs11_unlock(); return rv; } @@ -802,7 +822,7 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */ sc_wait_for_event(context, 0, NULL, NULL, -1, &reader_states); } - sc_log(context, "C_WaitForSlotEvent() = %s", lookup_enum (RV_T, rv)); + SC_LOG_RV("C_WaitForSlotEvent() = %s", rv); sc_pkcs11_unlock(); return rv; } diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index c5cf78a2b4..f6bc7a646d 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -145,6 +145,21 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * return rv; } +#define SC_LOG_RV(fmt, rv)\ +do {\ + const char *name = lookup_enum(RV_T, (rv));\ + if (name)\ + sc_log(context, (fmt), name);\ + else {\ + size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ + char *buffer = malloc(needed);\ + if (buffer) {\ + sprintf(buffer, "0x%08lX", (rv));\ + sc_log(context, (fmt), buffer);\ + free(buffer);\ + }\ + }\ +} while(0) CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */ @@ -281,8 +296,15 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ } } -out: sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s", - hSession, hObject, lookup_enum ( RV_T, rv )); +out: + ; + const char *name = lookup_enum (RV_T, rv ); + if (name) + sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s", + hSession, hObject, name); + else + sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = 0x%lx", + hSession, hObject, rv); sc_pkcs11_unlock(); return rv; } @@ -531,7 +553,7 @@ C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = sc_pkcs11_md_init(session, pMechanism); - sc_log(context, "C_DigestInit() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_DigestInit() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -576,7 +598,7 @@ C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen); out: - sc_log(context, "C_Digest() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_Digest = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -598,7 +620,7 @@ C_DigestUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = sc_pkcs11_md_update(session, pPart, ulPartLen); - sc_log(context, "C_DigestUpdate() == %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_DigestUpdate() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -628,7 +650,7 @@ C_DigestFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen); - sc_log(context, "C_DigestFinal() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_DigestFinal() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -680,7 +702,7 @@ C_SignInit(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type); out: - sc_log(context, "C_SignInit() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_SignInit() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -728,7 +750,7 @@ C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - sc_log(context, "C_Sign() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_Sign() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -750,7 +772,7 @@ C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = sc_pkcs11_sign_update(session, pPart, ulPartLen); - sc_log(context, "C_SignUpdate() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_SignUpdate() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -792,7 +814,7 @@ C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - sc_log(context, "C_SignFinal() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_SignFinal() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -902,7 +924,7 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type); out: - sc_log(context, "C_DecryptInit() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_DecryptInit() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -930,7 +952,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = reset_login_state(session->slot, rv); } - sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_Decrypt() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -1309,7 +1331,7 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ } sc_pkcs11_unlock(); - sc_log(context, "C_GenerateRandom() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_GenerateRandom() = %s", rv); return rv; } @@ -1359,7 +1381,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type); out: - sc_log(context, "C_VerifyInit() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_VerifyInit() = %s", rv); sc_pkcs11_unlock(); return rv; #endif @@ -1394,7 +1416,7 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - sc_log(context, "C_Verify() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_Verify() = %s", rv); sc_pkcs11_unlock(); return rv; #endif @@ -1418,7 +1440,7 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv == CKR_OK) rv = sc_pkcs11_verif_update(session, pPart, ulPartLen); - sc_log(context, "C_VerifyUpdate() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_VerifyUpdate() = %s", rv); sc_pkcs11_unlock(); return rv; #endif @@ -1446,7 +1468,7 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = reset_login_state(session->slot, rv); } - sc_log(context, "C_VerifyFinal() = %s", lookup_enum ( RV_T, rv )); + SC_LOG_RV("C_VerifyFinal() = %s", rv); sc_pkcs11_unlock(); return rv; #endif diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 1732353bf7..8ba37ca7ca 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -27,6 +27,22 @@ #include "sc-pkcs11.h" +#define SC_LOG_RV(fmt, rv)\ +do {\ + const char *name = lookup_enum(RV_T, (rv));\ + if (name)\ + sc_log(context, (fmt), name);\ + else {\ + size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ + char *buffer = malloc(needed);\ + if (buffer) {\ + sprintf(buffer, "0x%08lX", (rv));\ + sc_log(context, (fmt), buffer);\ + free(buffer);\ + }\ + }\ +} while(0) + CK_RV get_session(CK_SESSION_HANDLE hSession, struct sc_pkcs11_session **session) { *session = list_seek(&sessions, &hSession); @@ -94,7 +110,7 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */ sc_log(context, "C_OpenSession handle: 0x%lx", session->handle); out: - sc_log(context, "C_OpenSession() = %s", lookup_enum(RV_T, rv)); + SC_LOG_RV("C_OpenSession() = %s", rv); sc_pkcs11_unlock(); return rv; } @@ -291,7 +307,12 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - sc_log(context, "C_GetSessionInfo(0x%lx) = %s", hSession, lookup_enum(RV_T, rv)); + ; + const char *name = lookup_enum(RV_T, rv); + if (name) + sc_log(context, "C_GetSessionInfo(0x%lx) = %s", hSession, name); + else + sc_log(context, "C_GetSessionInfo(0x%lx) = 0x%lx", hSession, rv); sc_pkcs11_unlock(); return rv; } diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 8ca16bb660..940bd058d7 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -332,7 +332,7 @@ enter(const char *function) static CK_RV retne(CK_RV rv) { - fprintf(spy_output, "Returned: %ld %s\n", (unsigned long) rv, lookup_enum ( RV_T, rv )); + fprintf(spy_output, "Returned: %ld %s\n", (unsigned long) rv, lookup_enum (RV_T, rv )); fflush(spy_output); return rv; } @@ -404,13 +404,26 @@ static void spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) { char param_name[64]; + const char *mec_name; if (!pMechanism) { fprintf(spy_output, "[in] %s = NULL\n", name); return; } - fprintf(spy_output, "[in] %s->type = %s\n", name, lookup_enum(MEC_T, pMechanism->mechanism)); + mec_name = lookup_enum(MEC_T, pMechanism->mechanism); + if (mec_name) + fprintf(spy_output, "[in] %s->type = %s\n", name, mec_name); + else { + size_t needed = snprintf(NULL, 0, "0x%08lX", pMechanism->mechanism) + 1; + char *buffer = malloc(needed); + if (buffer) { + sprintf(buffer, "0x%08lX", pMechanism->mechanism); + fprintf(spy_output, "[in] %s->type = %s\n", name, buffer); + free(buffer); + } + } + switch (pMechanism->mechanism) { case CKM_AES_GCM: if (pMechanism->pParameter != NULL) { @@ -521,6 +534,22 @@ print_ptr_in(const char *name, CK_VOID_PTR ptr) fprintf(spy_output, "[in] %s = %p\n", name, ptr); } +#define FPRINTF_LOOKUP_ENUM(fmt, category, type)\ +do {\ + const char *name = lookup_enum((category), (type));\ + if (name)\ + fprintf(spy_output, (fmt), (name));\ + else {\ + size_t needed = snprintf(NULL, 0, "0x%08lX", (type)) + 1;\ + char *buffer = malloc(needed);\ + if (buffer) {\ + sprintf(buffer, "0x%08lX", (type));\ + fprintf(spy_output, (fmt), buffer);\ + free(buffer);\ + }\ + }\ +} while(0) + CK_RV C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { @@ -657,14 +686,10 @@ C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { CK_RV rv; - const char *name = lookup_enum(MEC_T, type); enter("C_GetMechanismInfo"); spy_dump_ulong_in("slotID", slotID); - if (name) - fprintf(spy_output, "[in] type = %30s\n", name); - else - fprintf(spy_output, "[in] type = Unknown Mechanism (%08lx)\n", type); + FPRINTF_LOOKUP_ENUM("[in] type = %s", MEC_T, type); rv = po->C_GetMechanismInfo(slotID, type, pInfo); if(rv == CKR_OK) { @@ -807,8 +832,7 @@ C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, enter("C_Login"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "[in] userType = %s\n", - lookup_enum(USR_T, userType)); + FPRINTF_LOOKUP_ENUM("[in] userType = %s\n", USR_T, userType); spy_dump_string_in("pPin[ulPinLen]", pPin, ulPinLen); rv = po->C_Login(hSession, userType, pPin, ulPinLen); return retne(rv); @@ -1647,8 +1671,7 @@ C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, enter("C_LoginUser"); spy_dump_ulong_in("hSession", hSession); - fprintf(spy_output, "[in] userType = %s\n", - lookup_enum(USR_T, userType)); + FPRINTF_LOOKUP_ENUM("[in] userType = %s\n", USR_T, userType); spy_dump_string_in("pPin[ulPinLen]", pPin, ulPinLen); spy_dump_string_in("pUsername[ulUsernameLen]", pUsername, ulUsernameLen); rv = po->C_LoginUser(hSession, userType, pPin, ulPinLen, pUsername, ulUsernameLen); diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 2c01aa961a..cbf451fc9b 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1745,9 +1745,11 @@ static void list_info(void) if (sa->reference == 0 && sa->mechanism == 0 && sa->operations == 0 && sa->algo_ref == 0) break; + printf("\t\t sc_supported_algo_info[%d]:\n", i); printf("\t\t\t reference : %u (0x%02x)\n", sa->reference, sa->reference); printf("\t\t\t mechanism : [0x%02x] %s\n", sa->mechanism, lookup_enum(MEC_T, sa->mechanism)); + if (sc_valid_oid(&sa->parameters)) { printf("\t\t\t parameters: %i", sa->parameters.value[0]); for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->parameters.value[idx] != -1 ; idx++) From 98f6d77d9af795cbc059c39bda57b94c4f91564f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=BB=D0=B8=D1=86=D1=8B=D0=BD=20?= =?UTF-8?q?=D0=9F=D0=B5=D1=82=D1=80?= Date: Tue, 13 Apr 2021 13:31:04 +0300 Subject: [PATCH 1950/4321] move definition of name variable at the beginning of block. Move definition SC_LOG_RV macro to sc-pkcs11.h --- src/pkcs11/framework-pkcs15.c | 3 ++- src/pkcs11/pkcs11-global.c | 20 +++----------------- src/pkcs11/pkcs11-object.c | 21 +++------------------ src/pkcs11/pkcs11-session.c | 20 ++------------------ src/pkcs11/sc-pkcs11.h | 16 ++++++++++++++++ src/tools/pkcs15-tool.c | 2 -- 6 files changed, 26 insertions(+), 56 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index d3366a97f3..23c05f8acf 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -547,6 +547,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) struct sc_pkcs15_card *p15card = NULL; struct sc_pkcs15_object *auth; struct sc_pkcs15_auth_info *pin_info; + const char *name; CK_RV rv; sc_log(context, "C_GetTokenInfo(%lx)", slotID); @@ -607,7 +608,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) out: sc_pkcs11_unlock(); - const char *name = lookup_enum(RV_T, rv); + name = lookup_enum(RV_T, rv); if (name) sc_log(context, "C_GetTokenInfo(%lx) returns %s", slotID, name); else diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 8369d56332..b18d014a5d 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -283,22 +283,6 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, } #endif -#define SC_LOG_RV(fmt, rv)\ -do {\ - const char *name = lookup_enum(RV_T, (rv));\ - if (name)\ - sc_log(context, (fmt), name);\ - else {\ - size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ - char *buffer = malloc(needed);\ - if (buffer) {\ - sprintf(buffer, "0x%08lX", (rv));\ - sc_log(context, (fmt), buffer);\ - free(buffer);\ - }\ - }\ -} while(0) - CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { CK_RV rv; @@ -607,6 +591,7 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { struct sc_pkcs11_slot *slot = NULL; sc_timestamp_t now; + const char *name; CK_RV rv; if (pInfo == NULL_PTR) @@ -656,7 +641,8 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) memcpy(pInfo, &slot->slot_info, sizeof(CK_SLOT_INFO)); sc_log(context, "C_GetSlotInfo() flags 0x%lX", pInfo->flags); - const char *name = lookup_enum(RV_T, rv); + + name = lookup_enum(RV_T, rv); if (name) sc_log(context, "C_GetSlotInfo(0x%lx) = %s", slotID, name); else diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index f6bc7a646d..a3ed9964de 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -145,22 +145,6 @@ CK_RV sc_create_object_int(CK_SESSION_HANDLE hSession, /* the session's handle * return rv; } -#define SC_LOG_RV(fmt, rv)\ -do {\ - const char *name = lookup_enum(RV_T, (rv));\ - if (name)\ - sc_log(context, (fmt), name);\ - else {\ - size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ - char *buffer = malloc(needed);\ - if (buffer) {\ - sprintf(buffer, "0x%08lX", (rv));\ - sc_log(context, (fmt), buffer);\ - free(buffer);\ - }\ - }\ -} while(0) - CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ @@ -254,6 +238,7 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_RV res; CK_RV res_type; unsigned int i; + const char *name; if (pTemplate == NULL_PTR || ulCount == 0) return CKR_ARGUMENTS_BAD; @@ -297,14 +282,14 @@ C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - ; - const char *name = lookup_enum (RV_T, rv ); + name = lookup_enum (RV_T, rv ); if (name) sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s", hSession, hObject, name); else sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = 0x%lx", hSession, hObject, rv); + sc_pkcs11_unlock(); return rv; } diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 8ba37ca7ca..402859705f 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -27,22 +27,6 @@ #include "sc-pkcs11.h" -#define SC_LOG_RV(fmt, rv)\ -do {\ - const char *name = lookup_enum(RV_T, (rv));\ - if (name)\ - sc_log(context, (fmt), name);\ - else {\ - size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ - char *buffer = malloc(needed);\ - if (buffer) {\ - sprintf(buffer, "0x%08lX", (rv));\ - sc_log(context, (fmt), buffer);\ - free(buffer);\ - }\ - }\ -} while(0) - CK_RV get_session(CK_SESSION_HANDLE hSession, struct sc_pkcs11_session **session) { *session = list_seek(&sessions, &hSession); @@ -267,6 +251,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; int logged_out; + const char *name; if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD; @@ -307,8 +292,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ } out: - ; - const char *name = lookup_enum(RV_T, rv); + name = lookup_enum(RV_T, rv); if (name) sc_log(context, "C_GetSessionInfo(0x%lx) = %s", hSession, name); else diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 3c6b92ba44..ee1fe85308 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -226,6 +226,22 @@ struct sc_pkcs11_slot { }; typedef struct sc_pkcs11_slot sc_pkcs11_slot_t; +#define SC_LOG_RV(fmt, rv)\ +do {\ + const char *name = lookup_enum(RV_T, (rv));\ + if (name)\ + sc_log(context, (fmt), name);\ + else {\ + size_t needed = snprintf(NULL, 0, "0x%08lX", (rv)) + 1;\ + char *buffer = malloc(needed);\ + if (buffer) {\ + sprintf(buffer, "0x%08lX", (rv));\ + sc_log(context, (fmt), buffer);\ + free(buffer);\ + }\ + }\ +} while(0) + /* Debug virtual slots. S is slot to be highlighted or NULL * C is a comment format string and args It will be preceded by "VSS " */ #define DEBUG_VSS(S, ...) do { sc_log(context,"VSS " __VA_ARGS__); _debug_virtual_slots(S); } while (0) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index cbf451fc9b..2c01aa961a 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1745,11 +1745,9 @@ static void list_info(void) if (sa->reference == 0 && sa->mechanism == 0 && sa->operations == 0 && sa->algo_ref == 0) break; - printf("\t\t sc_supported_algo_info[%d]:\n", i); printf("\t\t\t reference : %u (0x%02x)\n", sa->reference, sa->reference); printf("\t\t\t mechanism : [0x%02x] %s\n", sa->mechanism, lookup_enum(MEC_T, sa->mechanism)); - if (sc_valid_oid(&sa->parameters)) { printf("\t\t\t parameters: %i", sa->parameters.value[0]); for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->parameters.value[idx] != -1 ; idx++) From 58bc34405a98f8a85447c46962d6a42700880a31 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 21 Aug 2021 01:38:48 +0200 Subject: [PATCH 1951/4321] prepare package signing for macOS --- .github/secrets.tar.enc | Bin 15376 -> 0 bytes .github/secrets.tar.gpg | Bin 0 -> 5275 bytes .github/setup-macos.sh | 4 ++-- .github/workflows/macos.yml | 10 +++++++--- 4 files changed, 9 insertions(+), 5 deletions(-) delete mode 100644 .github/secrets.tar.enc create mode 100644 .github/secrets.tar.gpg diff --git a/.github/secrets.tar.enc b/.github/secrets.tar.enc deleted file mode 100644 index cbe0806e78685bae2545c8cdc19529172c241026..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15376 zcmV+rJnzFW74R_`L(Cb>cmnHc6=%$KL&`VPpXI1uNM`*eFKhqvEojEWK|ML#O`73< zMOb-t;XvdI<|XazMb;jqZ7_Qof~z2<-!|P{FjlcE1(=-Du)v|nL+qi1uabK<8nO=u zF4foSDg%S4C5`o38MgFKF(~*ae6;8LKij7QhZ|2^0;h>(PRE(lWKvyWpU{Sm<`ZXG zXQIxd-v&;DZ`XGwsi(!~WwczRu<;HS`wL7;B}UA9ez&6~8Eq2KX-6_f3KtQsbDVtm z69Hg%%vu`%7KxvwCRHN3#+3IZQ`FZBL+o8V+G>a5ezGKvCjL?CI%5^KsX+1s%1Br$ zPm#%~g7W!Poi&L|tN3~X=gVOx*~<(TL4&@~_fE#F@hBR%`s1FFUj8awgtA8nqE-2&P#Ijmv}o zitPCXg_Dnr%a+hwmnkUEXezbQOcn=2Ht>=%d7w04p^(Cmkn@@v7omA9aU7x;0h;1F z3`|avj9*lPxoaLp!9umtqwu@WDcCr4H$FS7 zDvHgQcafrgwPSJ~?A^GpmTlY!!%@*Wk!#_$ukobd{ej4j$^esrydr0MQcxekxo>(I zKQT#sS?zji3X&WcCpl`QW^sWF_=}7A9#-qyHJ@H+cK-6aOj@UaNhx{nrA2r{1j6Be z&`1CWg6~&Ceiu0PWo%NjaF-5?w;|N*afaNLpo=L&!7)4z;Id{GZ)n=O zmV*0fK8+7YOgvuY39hn`r*Kc8zJfR16VLY7yxm2E;kj=_IzoB zfRgXKLu{#(!;|1-$e#PIm5CTMEiOd>FtZHayg@Ew!%uJ73Dlb8#)}Q2HA1`DE}f!W z%?y&-Xe_u==S${?VspE_fmv`81Y~(RW6g5>6|6dEn*$O35N694HcJVi-c7;eeiuNIp(PdLg;40%wN!oi$xjbCJArEu`Giyto|%tMj)fyW6jqmo?lH_Uz^eZk4$@9XBG zn2+Jh2{P>@_DdjzoV@-3iuY`RhL+BJWv@2Kb56p=XTD2*p$lj9 zyN|Mc)!J*M8kaq!YV{X<$$VPystZl;_Lh?u=}uR%qH-#uIbv$ROI&^y)6n`F6t=-0 zA}cdUVx@MMY@!jl=uRNn=epwz)>_Xe+Qus;*aO*URRtEDo?wUcTz`w$Py zeOHiyI9B`xQ-?i);3tHqia$qnkg5_8mW;63n#Ej_V%$4uZB@v^=^r6|@MoGEIbf?W zZBgLWv$sDtScQa4_FGguvRKH4312D>Oc0J7}38Ny!vXpRJjH5cO?CW z2LOJKnggpVLUQE6<-%tg3osfG(aSXEPFmig&bW3^+YwiC@h3WYlWha}3wx07Al@|u zf$3N1m_1PrU)4gR(5{;>g;a{nyFHM|lMZmRi5hE^arr-oyIRzI)9Ph?pbbRoTJ&0j z1C@mcwhk7V{3ZknVCl0MV3KIqM~^EobEo4zgT%=vMq@)3?MK-eT3>4NhUaP7lDA#H z&`rQA0C>7*w$r~qfpdmmcQ2v;reNJem|Zi70tY&&mQRie3^6_v@Pr1czcQ*1LS<5| zx%O?Y051*Lz*T>d&u}YBT2Bxui$I`0u){Uo5)C2i|EsXLbYnJR)T%vicktbZ$7-f< z4m}vIV{;}QiIc9ki=20Cmx3Ud!z=XDKZHDstkP(#tg=IpYl4a!Y0yw3ibX-pB#|Tu zjxx0jCI3#*;!Lk_=Y;vuJh#Mf+JK%fnJXk=K(uMZf{$v!t^MiVa!Y-D0Fp}^1BdRN zpf(O8lfpbAJA#3P_&aaYFXSNN%o7IP0R5J>tdV1Is5sa#%2lrQBkp$4=wdyrUq3T5a-?WsB^fqxt+5%_W$ zS}3i&h5C3END~}u#i)gRUvedST*;-Ty~_J!U*bYH&0k~Dy`+~!hVa0OHfP}Dfk_i4 zOjhjzW&$by=%Ju8qGEUC)IsjP3~QhLz9+zW3)GW^M(F;0OxIN}xEdh9aTFk*8sfvH z`=g^2aEq-EV*kUfGi_RC^eSDh!}RIr7UuBn3piNVt`4JLAjWH#&T7I4Re!y{t~4)S zHK@*6EMH}j*ds8yE8=PyyJ*4Q6mVTFuIDvOjFOYC<3FD%Yq>g{l*@I5{@XRn4don? z+y7Vr+x3@SwK=ATdPTK0(!7SzU|!jGFC?(e2_}o1cU3Og8p5MWi}NCk`xR26tRSUwZ_>G(n;X#Kgy+NTRMp!gapOtayIvyE^W01rSOOWvw)cr>~@qY&VRITdV zk-Ms^5HyUEtgQ2yhleNVFE>_;4USkM`kxPri@Dw&VKl7!nS7f0vDN}joL+?zu*wx{ zgY{@-4FQRQOj&5upzBoVcbAz|=)NoXT_~EKe3T}axgS>+Smq(D)(xq*Qe;5WP#mjs;3izv%G)S(S zp}EJ1F|HxI%68aeR#dH@^qVuw31fTQVXtCG2{8Ttr8X7ca80yDhK%?B=$r;KvIk3B zW%_}GbXn1TG(*`W?rK{7o5`Sm1eZ!g69Lh;ZtU?BxQv#KeE2NW6LUlGxKHwUe+pcx z5HnZWK=+4CVwFkbBS^{a;N!!b(hjYuOWy4ehQ`LT>NQa}fewJpx5K!8y5joPJs;1J z_)CDs#$Dfe@V-_y5&E{pbYh7g*UCx@XV;Lst9i)rlrFQ7UN9bpA8#e;L??zFfDjn> z>M1l!W--p?i~fUUbLuSWY(_fBb*t4w8Bu{N9r3IoG!hp)9nsi?ya!bS31u8k{s;yjtMRal3Ekt)>VnR5Rlf& z9AN*X3i4bsEhJkivD5I_1=*(?ECaW(lPj6qFWi!(IqL<5;8j9`=M~ua&sv?!c1B~& z^&s#t>Y=GU#+$EqpT!C7+?~dGo{2BsCMbU~Hi2BXTszGo``Y<-9{cs?(@jYHi|Y2` ze8H}kvrYBCEW2EL#&Oqw{oYBN!sV)vB*@rbU4n#_l}(yXK#$UKuWX@s$Y5}1D6!Vg zN#%MnNgS^oMlZruF5D11=Ko+5dObt)TiqDpRM7-j@&MRh?}Hsl*3FTJh-HA%j06L_ z5ugA-<+%O;kCF=1q74Sgi8xdY(Uw9@1-ADk-l?AgY0;32%K>5aLgwh`Z@q^3v4?l-5ija>UtBDgUIo(%XWit#6j7v)SMK z_8oY?Z=J@8`^Q9^Q$_;-MJM*(h@&12-ey{>Nr9F8hLE`>)pvt6WjRSd3O@ZWbs5nV z7U*1JVEm-0pv$mCbMorTU>$NtY|2M5JvM4YZSqx+md+8QIX%|m?DV89HSD`?a?$Qx znd1P_!vmdm!iSn9oA9Q6NPMse8|NJT?MC3L1_#rk^)F2|`sBK7vqxsq(hA%xS0d49Uc-|6w!on3DM(}7)j`Q6Ak!l}EGJhmmJ<=(RgXRJ)pZi{EG4^(Mm~MhkAx$rc zmW}Au(Q3VWzO8{v|x-_+XW#>1{Scv5hnbD2VgC4T2v&ATqwh9P@UULr-|sUF6pQ2g*|?bwHYFLc% z2yELWnQq%KzcYPpBVD3=;jf;C%^0DN3H>Ar1M46Vn(k;LD=*Vv%6z>1EhQSWVe7$&d2*uaNmqz5d)GSvFiJ zaO}_9JX<|>PfbK-XZus9GxuFiK=!cZTZX2H$ljdX9dE{AA4kzh%EveNz7`e>jFBzA zlL$jBtsux7aMaY@0^pZLM}&ji@UG_TI*$=NPB5(&ru~^xGW=u@3E^_EwB$m)l?hH z<;iL?qx*A%T7}U}_LS=?zfX` z4I&tS{whJaY!u}cx!sj5M^YEvTmjb-GK9#+ReNrg0-c0I+siktfBT)TT6}_z`5a7Y zn#o!flk*WE7C#oY`OK3Y;XTo^ywNBi2vkcpMM>I?zvSHIBTuV5kW+_;N+z8s<5J{{>Qc*o5yJf9b@ zIqtIfoN@UZOduwS8x3F*y=O_tkVTFo-W%&z5cC)@hauMH&@-J~J|y!P8O+Zn`)GC0 z1Mwc^9jgdE4(UWVbo$ucCja<%?|0NmUWw?wpApl{yU??6JVtRPuFPBi71W_6@%J|!!%X3I9DCkn=Zr-lkv zppJL>b(%B~9loF!)KYQ`G|&6o`11;gh#%qy4qv4RVLuX|4dKV`M>6hoq`LLM@$6WH zvB6s|%GPGBpyvMu&8{dk#=Q7iCQ3FAh|`6$hXaBRO-%o47$DzT=JencMYV_X>OGB) zXtJ$=8$*|xQnLS0Vtug!w!7khu|9osE+c@+!ke)o=30A;2d=JJkVb|fx z!k*t8#YFg-Q6T{=Z$|p9m?YCSWZ9=Q{I?tv1E?P!5KDgQ z*{s-Z@b>Pe#VFeHs9e7D>f9$i@L50mDaPFLz`KVTjdr+zk&Zp-zSyW^AGW>BGUZ3W zzU0sAELnzYagO_I93ApAqq;OS--LIy-OMcKM1zLaa17P9WzpyTq_c!L9F2IYV^qcF z(;}t9;pzu@Mf9c&R`uRh3a2h~-QAw3b1|HIp^*bW6fhWL$2Fb;O4_%m)?7tZ>nllp zMD;?_&XMIgdm-t%z&&|L(Sz9ho81!=Flj5Sq03 zSIQbYs-S<%?%W)$zktj2t_W=J5AM(otkx*Lg0lLnagUWiOHaZUk?>>PHE;aJYWC8Z# z?xBI_fnDRV6MGEJbJ0E{6d%oZB43O0&}KC4K26wh-$$LWh3O);TxWqfPVqs*@=pO8 zb|R?9B$7cIZ&DOQaP?OeB+^#9-3jTW$5-kae9)tT1I|V`KV9$zeY@}^kHvh0k(-E- z8AB({`bCm*fa{kjI;^>6e_!2vCf>ksBm>*|@bKKT)vruHl}uo85Fb=#fWCj^SHaXS z(ZWhai71k+;;fQ+UogT!>gTlJ|&wTpQhz+S#JsXZI8IzmVBm($jOk^^=0ygE#(gE$m z7VOHkh4~6e?qM}C7FSUu3i5QqSAfG|=S7Zm-ivtubC@_7@&epZ7Ilz8cmCCybweMo zxh+0&_TC-UHl%8FGsb(jI{|Io9ZQT-#E7RdOKmQ3{y8Dz766=4qjf^Qyo6M|V`vo# z^K4LNyT<>>E>m-H+zERl3ma2uy)eO#1206Qsm1pu4`nBR!8w#ht(F+sr=$dzrh7&NYjduo1ndsfjKQ^6W2>Y>j?MKB0UeWn(nJmTz-Rv@AgQ&cxMWXb}-s?3orzuyeQTJUz(!g!4vEo2D#>5tn} zso8*OX~}>@Q2=*Oq?;gYTxYES{deZwLG0173X1>>GDTp8e6bVEnsErCjNyAqBo6YTok#tiE=>LaW=kGda zjwhj-d{B29=mdPG4a4Yn@>)H%zeLAWzJPNF{SEyJu$|AN0Zz?tmwuu;j0?}3>f+`q z>6ky&-9Ncn(dbfv|AIh%d{F1Xd+{k^6W|dF^6cBY;SMvfW7X>b`TIuw@5$51}I@CWzYU#fo1>G)@KJ z8k19T4TkgE>yExu^zMg)o+TshmW&pP+>m-uvt-g7y(k_i-LwGU_=a<|+vVb8?lQ#C ztbutIz=#pIw9(F?9M$6%9U!ZAuK0t43kqyTosJ$Xtew60MAS9Fy#Gk>9k((ic~l7q zmAj}xLUrcj4JDtRhJaDjCybl0;n4^um_h580)GejRe($tH#S>zS>TbV6_NpE={2MG zroE#ne|~cBT}5h*jNbt}zK%F!{@n5C+0nc(w)r^4oF+#sgYZr{3-vdvlAxzN?B`Aa z%Z~gHg`^KQ1F)(~KQ^sXm*dLDV_*NJA>OHWA-p?fF0B-neokI*QqgF%tFj&kA^!nu z$F%k(dbwEhV13bGr1LoZRN74jJ>0ShnKBWjth0lFrbzvOxU-bnA!{OS_OxZ2iFfmi zd$_s@`Xb^lO_zQNgo!*WeZ;9J;3Tc*A$mtoVG{^na$=p{W1b5mC;#r&8&U~g{3w(l z8u+1~_r6D(O8!h=d3qHYwm_vwlA#h&r+W$Wzkt2i6bL4cZSk01Z;~U7xWCk|?HUtr zgo`Yqr{xGttqERMBdVrqiNp_3>;j&JHjr;NB3&L@N3)lvaZEzI_Qmh^PAuDdH%qc8 zxe=p*i8)z2qKHkRRS&}zpnipDB{jedLs6(?`48V1-zn~Jmm_rMycCT;wzFCC*-P@10IOH0RCdqSTHybg0dhPE*RkW%eBS|kOE)|RUU zpl}7dtS!!T{bidc^$t`|*Xv-t9}iKf<54Txas)T?f}KGzNFV^1<9<_pG=zjDd-fQ+ zy~C^sloM#PN%_uAy#z_Z)@h_)eKODSv>5SnUIp?ycW0T6F|jY(X#yJBX((h~N=6q5 zrG76NBEUgzdk@qiv0Yqm=3ou`T=JY?G8cLKUpd2S-4W1rez(v%!;6v(Q;DXRO)W+P zgB}@1a33nSC?h6plxvX3m^>zbKe@>3Xzk^>EvA$D7Gs^aDl%ejR5!yZExJo0ILI%I zLP(og356u1!fM29K4NJ}kh`t;#l)rwoa~&wj0GV@eW#9!8CpK*O952a0}AL<{_{W- z3W>kfloun3(17*6WYgCXc`%~zL^;i37-I2ZZ>6Rg@NA1)~zp~X5Jl!W&G4b^G z9{p>)$%$2NuE>6;UOkkx`1vD}tt}+wTp#c2oo|zFK~`mdg~eZP47~F)^9uLS*p&gb zJa-o|hklEs6?NY6H7@0bLyfmYsSTQob3uPLUC|!~xkXes@j(_T!CPJzhU&?wBfj!A zoh@7(%#uhx%3%4wr?0*iNSxzZ)gUEi@K$E=E59oTI)RZlqnQOHLZ=Ygim3F05Rzm8X*L<=Y}P0SN#Ep7j8STK1yACP6Cx3p#*S7;Tx#^OX>Hfq2-^0on$SS1u+~ZSyY7NAM6kz`nYF_CN`jfg5E_Kp_ep;`*D<||0@r0`9 z`WdQ1Qb0&Vhy(2DxcQUHMo#XnBKtI~xN%{GvHKO-CvGs5)T>O8Q`Wnde9F+u?dGee zSV!GKQW~z76iQ>ylCJ>F@W5+v9d#;eWVsX%5(`}^_HCx$|64({bW{ywZ7@7ba@Z;X zErWGJ;2H&+0Yh)J1`ne}$7lNC3g9jE=>>cku1P?Ym|OemZ>E2ui)onPuZlU3Y1k2zW~%W7*vNCo>7e-nL9hZXPs}6g19+JW^e1SE_9aV$yd! z)uW{tz&cc!!a#hU_Q9UaQ2Xw?B;8aAR~&fv7|Ilu4MpxG=O2ATrdIs> zla~0ezn97C*RU3Ny*;94b70GPKpv$-f+xsbE}kxJkRt8#X`?As;%{AFO(YRh9>$fR zBUN0AC(RK{iM4JuBqE+f51=N;KYY6pvMcK zMi~o%PO*xSqd8;A*VW6fckE7v{oCu1PHs(Acb3L{Hc*vkIC&UW^}k@_!Z}X0?*(tm z-C^l{+W~^d-^M==_2me4`Qj^bkl6i3(W3i(M0TF+y5%-P$-^d*;mEGL=4fbPZlH;H zC3vt`#5BgM{gltH*rYC^B?2U9$cz0GBnCOo3#MWGu5E4vD~3=iAvrzio6(htmFaCS zVge4ax|$=04PgxT>%b}hwN>RJg}M{5L6lZi5rmxOS(pLzT~6~RQek^jYu3l$l4^ky z4lJC*@G}9PCPI6iehmymAJT(?9@a@AkH$%`j&BFD%YJwHQ55<&AT zQF14t^6}`^Xr{yz$Y0whEz39(OQsda5npRM!aFJG#vU9yrQdL8Cm25K3plUXw<@Ug z@iV7aibu(zPhZFo+VMzLFj{Q0pjO2z^O{n};;ypE?M5kKx2L@Mv?d3PZ7cPx6?;R^ z)c^JeJ5Te}N%)eS|;gTN&pfJL5_#@5*kt1m~ZRlt+`iLmC z_=*`6C$1rlMQO~pKAc3{&o1+O_$;LSPW(&7+!F~-V#DyqNq&lN+SURf&LIRt5nGl7 zZG-w*d<&W+x73tzOCNs-v!l>C`Cv!oq&s0Xj>i1*x%CX-B3IBwagE9R!=F-*an5+{ zes-svPGOHvw6eU_ousOk%H(pZjv=jYa+r7P>71KIzU8)odc`{#V#ak54ZorJ*!cR~ z_&m(_zw=L_4a=Jv^n?|l&=KF660&;fJv(!Xi7d<80?+LoIE8b^28)}q@>38`0X%u` z?MTv+ana>}v|sW0rNTUm42e2n^BFg*oOd#}#joC3+jIhrWkGWqi$`Jb_g`1s*n@xP zklzv$pcj{lXI{F9GX|C(JrhNtgEm`+E8lN{A+f8+2)53lm#b?Rm)<-t`<4Pn?q9Qu zXMT%)jf6_h@_9*U>+?D(O+*IIJ_Zh|=Y(pu`+<%htZKlC#>>1w-rDoo*V%OKAA$`v zMO4m!cV)*c7Q}}8#QeQjlV4TE{MQlkzL5j6b=tEoW;LVu2rIlQelydlRHj(FllT`BV1=%TO1LxlAZC>|JFFF8zAe1 zSQa%9kuWRpo+J)OMhuLiA$C7^t ztjKeIJGYF$5%7)BEIH9cHPJoNr3bHUdZ>h;M5l?n)xbDhGqmVj`q!r>wxe4K6Z6+)^SNw^0*Z{!x4wh55JK&dlf*!66FGcgSnowN1c zQnPWia&%NEKN_2p(9I~iNG22X1FATbt_t;RdT8G3=|pd{cHuoHK>XsPJ<%!%@%KYu zJ)3$ZlC(NOePgzCnMzyFR2HJAvO`f1GyR)Ts3&+~3{bF3duBQ|RUDZ{fMO2^OSvzm zqc$!(5d+Bq-)N`bmZisC1V!+;*x%Gi72a$iM57rL@;yK(dgn}Ptll%!i>TR(0QaSz zM{Y&;EViiJ4Fy?kR3P$m^5R}%T0EAO9&Cv@fq9&GOnFO4SJ9lOnAARUB9V}vI(0M1nuVs+aEfxw*5B=@;!zk-r zVXCQ5SnPQqoO;tRyJkbe6IJ|PTAPv919F*sJg@<{PmWnJWsGzrkI)nocabTKWUB@Q zoc3=H6beC~B*oWkOne7jz`|_7(Un@Z49cJl3y+}BMEytt^UV2Prz_ghexS zTO8U`5WxMU46dMB9aZU_f|zSkg{`^GrQsUIH2%qf#-OK^&cIEh+5FQu{KrOlcl^sj zzVti!MQ^G8+HEkTJP(O98)()@HLQ<2+X^i0Km^@nOFeEpc>yIL1LL~8Mdw5GOfTpm zDRtnq?{q&{KAiV_uq`}6prG-l1yABD*ct$pTAbx^(Pewf?X3fnC$?y>0|+py*Vvnk z)h$eceq<@am#C$$l7SkY-Pl2#Uo*nWsVsoEPc>z+beZm)RjeL06W~xgHOQDc;lUY^ zXoru$2|dl|h0uAF%obDCgf;`Q{SfMl5{UWDm>5gGWbQcQMBS~!e;i-*mJs0!Q?jjn z8?xKUDCMe*SlH<{Mbk;(jWOI|X%S)PzYezk(RHJ-&td8X9S4Pg?yvHD*SLzz?!kLF zF6AlVx}8u5PWZ&ceGU1U=FV$-P((-8U;02^WDP#;ZVGu-yF0%J$zR{fqKNHQ1;ayO zq`D=IuIR&kX%3%KSCzK8vCqJ!Z+ukUdEpDl00>{)fBq`Yb&<8Q(*0glw^)fB6nW|O zFZoyCTv+TsFl=g`P&PI}pu!?Fy;hR!lwguRd@4MwQ!mo{=PNUS)r4#tN)VZl9KLdH z{Rk*nNS>1En5F(hrGy6;f}~av)TgT!7bQ#4{F(A#OuHz2GDs9Ryq<15iVxG2v)aI4 z56OxX`S%0kIFyjrt_Qml#9bKHVFJ6A7z4aCaAx2{-|=Op$K+W1G3y(owH52ZQmzUR z7jzCS1C3hUyLi~Wu9`%v{{;onGncR8`NwyPpGXxzu6kbd`A#cE&p!_Mlk z)9n#=zbGAP_oTCob+lgkMKG*OrfPYt=vD6Z0D@5dtY@Z)Uo?-3b*o{B%oyGIJ9>)HuxTgMnd?YF7R)z)D?Y6>3f@6;_2aOIvQH)BZ^lare=-kIKQs#2cti%c ztl&@&(E6@Gi783#9lVY8SDAUP)Ec1bSoiqRgbN$!jb~{pRKyzA5rc2)gxjTcj?`GH zxthsV)rRlD{jE$Q4X;TuRUR=#H+?e$YLHnY_a?uJ19Sk>{CS6Bcc zTc=xY7#~>UI6DX~jz9e@dnrC9A@hRC zZD9*?Apc#TL^K8%IT+rs>G&F53ZKzL+bOWiCEY->T_IaN$^yAyk?m}my~%aO>gSYRV#l}~ZaZt8pv`>5f9S7^H2 zg*yL&_F`{%NU7{9Uo|$a#7OFkcR1x8S;UCFs?IffQlJ#J&X=B3Ie8&i&se6`iYQh( zTrH}B!%~Nm^LqzPC1+`_`<+u4d~rZ8s^FnjFf?HT`Bf(}1-{Lz3iUKlvkTZG`m?90 z&?PvU0Jt68)+ES6DiDfz!ut>-&1xvMpLLRuYlNXR%gx>GG)oZiaea?Hs@J@h2tr7M zid>Ukhw`lbqT(siQvQ?6q{=h>6gbo}axqk|d2V7aQHKJ6R2c{GDJcv{NG8aOl3>xH zX;}4xGJB~_#KKp98ZYE#=zYq(iwXN^VpWZF4P4aGwrJb+Gm#ne@NE{^e9XAMj>S12 zZ(gee9nS8b9v<2j5=zXLx+E`Gyg7?hA-75kR{#vwDR5Zh;y9uXZSbY2_$?zd_KD(r zK&}}HG&~gzly#6-_tug=q$U~w$gmcGWZfK$z9~HA)ha5l10;^j(haE*q_Z2w$scT& z|8cEpWb_vv{71fbJP5HVMS*B?G6^&QqfgyUQT<)|(c^tDdVUX+WXQsLT4bvnH(lp{ zJ?97u91}Yl_R^aPtH%oB@Uqr<_jdqoM93@soUsTK5q0w6^IB{%;~&_-vL;B7g2X6fFo?2PN(sR^0?=vJfFU94 zb~15F>U{5ln1IBbA&Tk}Jyi(?#wLhI`L3h4K7dQcE6-v<x`kks10UbVD@P1BFUN0Kw^cPDMNN|KHUH-S=uD(}Z;z!9lm&o*RpWH?dOCk-W# z#f%ozu8R}Hd?$3yB>aa`)S@4#9~^J%nE~(kp0O~19#Qj0jN=P5A#&tsYf5rJ*BC8p zOIPoJaxY_aUP#J%KV3KS2~TgAewVgBO9ODC)Fc(gY?E#jQhW|BFsGY9EPp56LXTJJ zuHC&*EUWzc@V!KE3JSFjeJ0aA)|D-pD&u}mEljtxKBB%p>&~`96iW6DL-rE7_G`%x z8zawUlPAA_bcg3iwi0tn!oc7J2FCo#+bkNZ~u{ zhaK>106#C#E)03X!Di?=;y z9`35<+)Q6xOgQy3rzqI&9nd@A++HyCHCb9kZMm#9a$0=)FsuQc*67m=WeJLb89NU7 z2()^Ka81!oUdJ;k}(rGYBoh{KEMeX{$o00#~J=CU{Vm59p07?-G7= zga*Ou`gLS27-@v%Ht>dmyQ)DkRtRhM%knxz)#1t_d|-BEvv8Dp-jj+ZAx8kR)Vc;%l_K4X^1lU&}pwzRRvBMDNN9V#!h0gk`+$& zGm2<-S`58`xeEU!DfY@5$?%_)>4rcUeyoITH|>gP(Z6#rH$skcNvT6T_AQsUtU!>2 zvJF=>NK5r<0^EC5}OeAh5pf)7uy`}t5&S~LEn=@IJVb8{D z-#!(t___c&=*RQ)iG52Dq-?ylfK4G?Dsn9mYPOrn-^#qp+5=()(}5OPiU>QR2cj^N z;mHCQ1R$yqOnb3la^pk2qha>k!UII~xTagW?c1#MlOp{ewi+OL`@&PB4qW}lw$#{-4dvVQ z`-n`jCHz|1}hRym-Y>$0ua{SQ~~z_RKjX^3pGY*Rhsfe42QI z20+-3_-P_Yz(I7ot6-rNHVN)a?@li~h`$!leJge^{d^@F3~SrsXQ+DD;~ZxnsQ;Zc zfn6aYDyhBS^Z{Q*takeHD+*JxI>^_zWW?~>hkM}xm5xgBXYRD1ap&aerot$}j-?26 zN*+yL!_jD=g{h8NNH`9O}j0 zM4u=W#6Mr;5T$w{GrBOsq~^yC%Tl<(9Eiq%t2i={ZTRY?cUBq_MDc$E3#sl5AH>d{ z>5YG1YG+dkR(!J34fG+V7mSw)yp#bYSAj3H%)Mul&UT-NAQB+YKE#alCLXkF89gFC zvZ!hPX-ls1&zU$pHT)XjCSq10jgULt`N7V;XCC2M{248&b)#w3?Bdx&!th@pa{* usS3x>2*F>@w_QWP;=8uz>IsDgQ~T_`%$plOXrHt6u^+6XrpNd3j@``t4AsN{ diff --git a/.github/secrets.tar.gpg b/.github/secrets.tar.gpg new file mode 100644 index 0000000000000000000000000000000000000000..3bef84180cbea1d2ea6e7d2656876a33dc3e5ae0 GIT binary patch literal 5275 zcmV;M6lCj+4Fm}T0_n9@J_RIq)8x|Z0S2F0{&!+vdLz&F5G=>J{4JjjFZUSnu8~h} zp$@bd@o z04lV6XEeSIXW$u==ItI%UjRTGVEFF*WZ^vF`evf_IaL z(vcd$ocsF=q)&2jxZZN-hwbF3iO*8n%w>hKMtE@;1|SO!okpW_ok#ZI1tph;ji9Rk%0sDX9oNIeQ*_bTCScwff?I>m1Ja;>(novs2|AcB#Z zFCGmD+LF#)Od+*#gyTfS{hHSd{d=-!^NSqb96bCm+E(fFt?bf}MD{WO z@0s_SS3-j21~%_@;D`K+{nE^FsoOFB?M8A!-qe|^$*E;8GHX&NUGz9O$-KX&kx)q6 z7%wj=SR5#<0L;Qgs`n2pl-k0*4;MSq>K7*hO8?T@=K36?RpN} zcGo|Du8?;pu$LsOmG?u_8|KMFngOQLcD3VmS%6dRt&ZSBsU7+?+a>%lZ33m>hg#3i zm5J)m2%8eR0JRGSFuYZT;E2930gBpTVyO#FOy!aMR?RxFApuWa^{Xi|Z9MA(hJthy0I%h*_=0Y zA!RtP;5KblbNTxiL<%txAfSz-%(a|fH0F)(0A~+xQ1|#aWoyDmZyXlV&5$DJ{lZfH97Nmq zB+1as3qS3n5L4RsbOmSil1=?Vl;s8{o%y^T_sni;-Q~@C$?(%r(E_gASC@jg!tf7M z)_r5uzlcQtRwGZUFdUG>zx@v|m;v(j!X}*SRB(Xohhn8AmIWs*)Aw{q~2B4Hv4 z%kSUS9N@LuSM(U%WtCmG@hLmNtgh4eQ+fsNH&Ntj5U$RrHYgZ{Db zUEUU}g4tZgTf%AD(Lm@bkg~O?W0fLtFw_BDfeF7_CWe%kgtFHGT0a<9Epe{;- zY>q3vjzft$@?1m2ql8j7o5PGlw@#%Vnip7WXdrP#7(}XeUT*WN;wy5ga%<#JXW5(I z%l*vhyGy3NmIMX113PYJ4O1qj16u?WaMF+YtqN)G9<=cT z%`mu$$~>o$puE?nZmI3hUyupe;dj~_X4wH`%YdF3X^)2?bI-7bf~+bKg_2~I<$70M z@yt8f67NA*Mh8&ai^6DdiTCI5w7%D-BQNaqAoTz!GfJ?z{eoYKvj%$&R(wut6q)n9 z#%imK4sq%TFXVL+n}qs@CF7*@9X-K`1L^pF-OnmMnXH-Dn7if+#~BptBiGSmgGpC* z=2t@4CwV6SgFWkp6z@woW|juR9?R5zAq)j#!*skfV=KPhh$z)1A37D+(N^ZITXZ?a zfFe)%Ivd==<;TKn?|Y$XVPJm&F^v&m${0qGEJ;2f! zC*^?fsEeLvLz~ezYElS81|7}`!Fg7T0^0$YZB8VOnU;{$FwzD=#asCoy?H&k57k(U zS$JUn-1LsV+2nZHNPi8nE6*_R04l?5mC}O$5~u9ERLDj8m#MLO+4to`I~`${INiu{ zapZ04k_j4X_OsJ-7wb9lOM!{N7dBX&P+JDj1Z| z28@l?WYSei+c*9UDk1pwM|xI&oAH85Jiy4$R;eI z6ah^c_Vj+d%gXa?#0_dG+*s?=* zvVnNxKRer)P5o^kird#ecahIA8kWumuvumYhzDX4jpC`nyZXvh1YaHPpVrg9q{q{+ z{b1Tw*oh@X&;GO9Dwc%>h#Zk{=V}ef!e|llX-}Dh7?7$rB-r@zS}r} zxqSY1=Od&wBR04?Yv%Gg^I}FGb!a+#f^sOrFwp)*`8@laCj8v=&x^(Oe4-Bg8<5JJ zS5&SLOp4<4bvv*y0mOPu^Oy4%(?R>A_*y}}?lMqzw)dPRivGB7uy4W`1IPtncVepp zx|yV)IX)jBZW(2c{p69#WRU4As40d~RET%YgXV(Ep>*%qOP4Ac0tQlN-Xe6ekSpfZ zoZF`9JeTop$-sfG{4&pGy7Ts}XS38vWS$!Uuw?6L&tpdpSThTm7nSyjj?A<|Z`M`w zW3xHyDszXZ3Rxt_G~Qd3qU`d(TK94zgET-|d~$@E=hB~UMegzxYSP45b{Jl}5>os6 zdx6mVG9SZmXSzuoPNy(&suFCo=&v+3@?t`r5fnQjm;rABO47t{SBw^a#Qt&Xqm&ALV}-PrA1KFq|GxCH@>rRdfi=qk! zFC~B1@99Jcv|#x`Ep}Ou(fXT2MV9{Txz!{Dtuz_0b)bosJLHw1+NIwm2U zf0CgTKKlR*=&F~G&BYlfd0$w#>0e zy8nipH|cl3zNqmX)c;hhsuuviK^&XajJ)u+swqC+(?CkJHaKYOm1CCo@f&V>WqsV> znY&@+sBa^PK;hluGj>_}2bgKbQ=b)>v0x8%qY-0nCYDH3v7jTO@g>*x3)PLCHQV&D zz9Dk(=nGwKo3l`jJnFQ~->qZZ2J)$NjWi2ikVQxe(m(2<;$ATmS<51HJUYQ>CQ zxu8apP5+YN3v2~6#IRh*C{EDvv{44iwGf=SjDfQy;XFHXCvUYC2h!m z)2~p4ppYHiVS_`b-zAFA!7^|KcS|^La$-1zX~X*BLBgj6|NV|byl{SDSy!+`?eGDB zXZhlmA8BF}KRJnH?;m|HgKZbaNwzPFjFBiP?e#Yc4LEI<`6FGqZl$dp|LZglic-vE zfSvB){ZJBn?3C_`Gwn#mr=uh; zmf$y`XXj3^HwhV$%gv1XcO#^}e=j8j@NW<>qAzO(sGd!RAnK1g$asT=y5wB8Jw z@eW}u3J2P!3iecl}o0|}M5pnh~CPYLv1>0@uV_9uj0g9VKtkeGk2AMoeO!fL%9*eia z-{bDOwB$ZOLL(=2(H2I|xC;hr*OK_k9JR0fS+EWiq3FqQjju1v;v4jw%w2O)+wpi` z#ZPySW&b}yjJUg_HBT}dK>kKSng%ayEjX1Ye`n2t6D&d@;#u5wn~W#o#Cg-OMSonm zLj@$6&S0VeL%d5T>m?NZqWWZ5neJw$H5$}u1vmBbq>zx&QkWscEn^5 zX|kohe3Jg1VzSK>VdMbi8G>~xl{Bq_eM_&wpWh-Z;8X!xZ@T$@GskNZNC0Xu(YJrl zlrjS!V|q0EQq`@pR6bx;gFo)OEtzf`snf7r|0M~MmfM8hzlHS$MZJGOm~%qW^}}4$ zCIw5U$Jr_A$n=Ky$M8tke(bNIg1ZX5J5(jp$13Ty!{Wa=Sd!*?RY9;QQ2rb(kQs0M zh?9qN9P01{bKx?G>W6*?HXePoSm5vLU0UhaTAZzbRhzr-D9# z?HNn)jF2!xbDJ-<4JV1v|f@Wv#ZNI{&-v!ZijnWxF#dXBS}7`(re0_n8dl_U)% zvVSG3>D~Y@w8r;DS}a+Sjqwu?ay4;Ueh!}SNcPzEe^H$#B)1wS=}HJ~xkDE9b=qS* z4uV8li%jF8;PNU|0{jeHU9rnUu%)Uw-KvQ(kp9WsuVpQ5BQrIWf@PwDN_!U*bw+0s z*4+6_tOs83>1Jzg|He_pLtT>Yf7Y24#aGOM>gQ^#Y`6gKFLIuvr2ipxnoJ){FMosCwB zx^{K7cMle%@^Z2wZVns)1YvG!%epqjjdz=2MIFGg6`(#&6YhF*1vu@Cm3xeHfN0*@ zeoS6kz!5`e26XPM&Qhe>!YnaFuKO}iX=vWVAShzc|05)0micI+!_{4KVoK?Cj`6M) z%z&`*@p(UpCUOp-BDG9gLM$Z$w6Av-APHLnOcQs0>eZ-sB*1E-YCfxoo+Yl_9rcxHkNdj zOKX7*=_(5;PVi{TB|tA1>j>b8%0{5IxS#LUuQ+@PWj3L1Mj2Vbi2z~D`y+@B-oMl1 zro3^PC!g?Jbt^Mlv5lFql8l9p>01~u4Gr3>0Hyf*PjF$Z)~YIxq=2G1gM}$cpU)pd z8^6%0(beb9yp9LX+xrG>jT-wyr;qyL3ACVGxe0q2N}#*7F;%LY1yjU-P9t{lUs@Q| zxfeo`(}scaQ|2ueGhT3jrN*Pr<<~y6Wd`+pofTc1UP1^O(r|4%9)GEINSoSbF@oHU zN2#B}6=v!CPEz-gh`tb%;Se zv)o~CFOk{`D+y{N7kc9jaj~6R?|b!2^qNygL+KNo(@Z8azNGbW{badi@I?JK_pw;a@fSrbIm h@)SK|u&ulhS*X~D(^|4MJ Date: Sun, 22 Aug 2021 21:03:27 +0200 Subject: [PATCH 1952/4321] actions: monitor macos specific changes --- .github/workflows/macos.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2df1911989..bb3d2437d5 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -5,6 +5,8 @@ on: paths: - '**.c' - '**.h' + - '**.m' + - .github/workflows/macos.yml push: jobs: From fe04f5a611201cfb2decb33224c1044e33f20663 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 22 Aug 2021 21:04:17 +0200 Subject: [PATCH 1953/4321] actions: monitor linux workflow changes --- .github/workflows/linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ad0e36078e..c4729d9292 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -5,6 +5,7 @@ on: paths: - '**.c' - '**.h' + - .github/workflows/linux.yml push: jobs: From b4e41c6c1242170329855a6fd9375f8e95a1639d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 22 Aug 2021 21:18:14 +0200 Subject: [PATCH 1954/4321] actions: monitor cifuzz changes --- .github/workflows/cifuzz.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 5cf5630c57..9b6c34f03f 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -4,6 +4,7 @@ on: paths: - '**.c' - '**.h' + - .github/workflows/cifuzz.yml jobs: Fuzzing: runs-on: ubuntu-latest From 5e5f85ed1c8ae4b0a142af1538cedde9a208da08 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Aug 2021 21:18:37 +0200 Subject: [PATCH 1955/4321] CI: monitor commands in scripts --- .github/build.sh | 2 +- .github/setup-java.sh | 2 +- .github/setup-linux.sh | 2 +- .github/setup-macos.sh | 2 +- .github/setup-vsmartcard.sh | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 99ffbc860c..67e2b026ef 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/bash -ex -o xtrace export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 02dee85716..4eed5084e3 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/bash -ex -o xtrace # Select the right java sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index f20ade829e..7ccc4e6df4 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/bash -ex -o xtrace DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index 74dbb59f60..f2da2f7de6 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -ex -o xtrace brew install automake diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh index 825d9cf6c1..be6116df8e 100755 --- a/.github/setup-vsmartcard.sh +++ b/.github/setup-vsmartcard.sh @@ -1,5 +1,5 @@ -#!/bin/bash -set -x +#!/bin/bash -ex -o xtrace + if [ ! -d "vsmartcard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git fi From 23f22fd36e60f34143ec364478a51215a5272f76 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Aug 2021 21:19:21 +0200 Subject: [PATCH 1956/4321] ci: corrected position of workflow for deleting macos keys --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index bb3d2437d5..d8a2874a38 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -28,6 +28,7 @@ jobs: name: opensc-build-macos path: OpenSC*.dmg + - run: .github/remove_signing_key.sh; rm -f .github/secrets.tar push-artifacts: runs-on: macos-latest @@ -42,4 +43,3 @@ jobs: - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} - - run: .github/remove_signing_key.sh; rm -f .github/secrets.tar From 282440d32317c3e4ac6db3eff15097703d01c309 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Aug 2021 21:23:33 +0200 Subject: [PATCH 1957/4321] ci: add signing keys when NOT in PR fixes logical error during migration from travis to gh actions --- .github/setup-macos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index f2da2f7de6..dcc96232d4 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -24,7 +24,7 @@ git clone https://github.com/frankmorgner/OpenSCToken.git sudo rm -rf /Library/Developer/CommandLineTools; # TODO make the encrypted key working in github -if [ "$GITHUB_EVENT_NAME" == "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then +if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then gpg --quiet --batch --yes --decrypt --passphrase="$PASS_SECRETS_TAR_ENC" --output .github/secrets.tar .github/secrets.tar.gpg .github/add_signing_key.sh; else From 27751b976dd70f04b67d43c235f6c0af7dc3aacd Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Aug 2021 00:24:48 +0200 Subject: [PATCH 1958/4321] ci: fixed macos cleanup --- .github/cleanup-macos.sh | 5 +++++ .github/setup-macos.sh | 1 - .github/workflows/macos.yml | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100755 .github/cleanup-macos.sh diff --git a/.github/cleanup-macos.sh b/.github/cleanup-macos.sh new file mode 100755 index 0000000000..7423903bb4 --- /dev/null +++ b/.github/cleanup-macos.sh @@ -0,0 +1,5 @@ +#!/bin/bash -ex -o xtrace + +if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then + .github/remove_signing_key.sh +fi diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index dcc96232d4..6a5359ea11 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -23,7 +23,6 @@ export PATH="/usr/local/opt/ccache/libexec:$PATH" git clone https://github.com/frankmorgner/OpenSCToken.git sudo rm -rf /Library/Developer/CommandLineTools; -# TODO make the encrypted key working in github if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then gpg --quiet --batch --yes --decrypt --passphrase="$PASS_SECRETS_TAR_ENC" --output .github/secrets.tar .github/secrets.tar.gpg .github/add_signing_key.sh; diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d8a2874a38..0468c9a73c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -28,7 +28,9 @@ jobs: name: opensc-build-macos path: OpenSC*.dmg - - run: .github/remove_signing_key.sh; rm -f .github/secrets.tar + - run: .github/cleanup-macos.sh + env: + PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} push-artifacts: runs-on: macos-latest From b5393ea8f0953b77c9771079733d5007194b1583 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Aug 2021 09:39:34 +0200 Subject: [PATCH 1959/4321] ci: unify shell flags --- .github/build.sh | 4 +++- .github/cleanup-macos.sh | 4 +++- .github/setup-java.sh | 4 +++- .github/setup-linux.sh | 4 +++- .github/setup-macos.sh | 4 +++- .github/setup-vsmartcard.sh | 4 +++- .github/test-cac.sh | 4 +++- .github/test-gidsapplet.sh | 4 +++- .github/test-isoapplet.sh | 4 +++- .github/test-openpgp.sh | 4 +++- .github/test-oseid.sh | 4 +++- .github/test-piv.sh | 4 +++- 12 files changed, 36 insertions(+), 12 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 67e2b026ef..96c6ae29bc 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; diff --git a/.github/cleanup-macos.sh b/.github/cleanup-macos.sh index 7423903bb4..0a0fbaf799 100755 --- a/.github/cleanup-macos.sh +++ b/.github/cleanup-macos.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then .github/remove_signing_key.sh diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 4eed5084e3..c801fad709 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace # Select the right java sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 7ccc4e6df4..2028db1e85 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index 6a5359ea11..dbaa955149 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace brew install automake diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh index be6116df8e..0fd22b7bb9 100755 --- a/.github/setup-vsmartcard.sh +++ b/.github/setup-vsmartcard.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex -o xtrace +#!/bin/bash + +set -ex -o xtrace if [ ! -d "vsmartcard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git diff --git a/.github/test-cac.sh b/.github/test-cac.sh index ee91a728b0..b55006322d 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install diff --git a/.github/test-gidsapplet.sh b/.github/test-gidsapplet.sh index 7405e729ab..ca546180ca 100755 --- a/.github/test-gidsapplet.sh +++ b/.github/test-gidsapplet.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 93197d26f7..212ea6e74e 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh index c4fa02ad4b..c017104518 100755 --- a/.github/test-openpgp.sh +++ b/.github/test-openpgp.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index 90409ab52f..dd6f60be7b 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 66d92c5d63..0e7a37cdd9 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -1,4 +1,6 @@ -#!/bin/bash -e +#!/bin/bash + +set -ex -o xtrace # install the opensc sudo make install From e5917350542c9dc2b8410157b4c0e5f645ce5c49 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 26 Aug 2021 16:16:59 +0200 Subject: [PATCH 1960/4321] ci: pass code signing credentials in for build --- .github/workflows/macos.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0468c9a73c..a3ad468a79 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -16,12 +16,13 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-macos.sh env: - CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} - DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} - INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} - run: .github/build.sh + env: + CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} + DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} + INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} - name: Cache build artifacts uses: actions/upload-artifact@v2 with: @@ -30,6 +31,7 @@ jobs: OpenSC*.dmg - run: .github/cleanup-macos.sh env: + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} push-artifacts: From 1078812b5c3f04f4ab16ec0aee3cc3bf5ee12342 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 28 Apr 2021 17:04:00 +0200 Subject: [PATCH 1961/4321] sc_pkcs15_compute_signature: allow arbitrary length input --- src/libopensc/pkcs15-sec.c | 42 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index b86cb77c3d..5018599893 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -581,8 +581,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, sc_security_env_t senv; sc_algorithm_info_t *alg_info; const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data; - u8 buf[1024], *tmp; - size_t modlen; + u8 *buf = NULL, *tmp; + size_t modlen = 0, buflen = 0; unsigned long pad_flags = 0, sec_flags = 0; LOG_FUNC_CALLED(ctx); @@ -612,9 +612,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } /* Probably never happens, but better make sure */ - if (inlen > sizeof(buf) || outlen < modlen) + if (outlen < modlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + buflen = inlen + 256; + buf = sc_mem_secure_alloc(buflen); + if (buf == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(buf, in, inlen); /* revert data to sign when signing with the GOST key. @@ -622,7 +626,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, * TODO: tested with RuTokenECP, has to be validated for RuToken. */ if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) { r = sc_mem_reverse(buf, inlen); - LOG_TEST_RET(ctx, r, "Reverse memory error"); + LOG_TEST_GOTO_ERR(ctx, r, "Reverse memory error"); } tmp = buf; @@ -639,13 +643,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, if ((alg_info->flags & SC_ALGORITHM_NEED_USAGE) && ((prkey->usage & USAGE_ANY_SIGN) && (prkey->usage & USAGE_ANY_DECIPHER)) ) { - size_t tmplen = sizeof(buf); + size_t tmplen = buflen; if (flags & SC_ALGORITHM_RSA_RAW) { r = sc_pkcs15_decipher(p15card, obj, flags, in, inlen, out, outlen); - LOG_FUNC_RETURN(ctx, r); + goto err; } if (modlen > tmplen) - LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!"); /* XXX Assuming RSA key here */ r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, prkey->modulus_length); @@ -655,10 +659,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* instead use raw rsa */ flags |= SC_ALGORITHM_RSA_RAW; - LOG_TEST_RET(ctx, r, "Unable to add padding"); + LOG_TEST_GOTO_ERR(ctx, r, "Unable to add padding"); r = sc_pkcs15_decipher(p15card, obj, flags, buf, modlen, out, outlen); - LOG_FUNC_RETURN(ctx, r); + goto err; } @@ -673,12 +677,12 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, !(alg_info->flags & SC_ALGORITHM_RSA_HASH_NONE) && (alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1)) { unsigned int algo; - size_t tmplen = sizeof(buf); + size_t tmplen = buflen; r = sc_pkcs1_strip_digest_info_prefix(&algo, tmp, inlen, tmp, &tmplen); if (r != SC_SUCCESS || algo == SC_ALGORITHM_RSA_HASH_NONE) { - sc_mem_clear(buf, sizeof(buf)); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + r = SC_ERROR_INVALID_DATA; + goto err; } flags &= ~SC_ALGORITHM_RSA_HASH_NONE; flags |= algo; @@ -700,8 +704,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); if (r != SC_SUCCESS) { - sc_mem_clear(buf, sizeof(buf)); - LOG_FUNC_RETURN(ctx, r); + goto err; } /* senv now has flags card or driver will do */ senv.algorithm_flags = sec_flags; @@ -711,19 +714,19 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* add the padding bytes (if necessary) */ if (pad_flags != 0) { - size_t tmplen = sizeof(buf); + size_t tmplen = buflen; /* XXX Assuming RSA key here */ r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, prkey->modulus_length); - LOG_TEST_RET(ctx, r, "Unable to add padding"); + LOG_TEST_GOTO_ERR(ctx, r, "Unable to add padding"); inlen = tmplen; } else if ( senv.algorithm == SC_ALGORITHM_RSA && (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { /* Add zero-padding if input is shorter than the modulus */ if (inlen < modlen) { - if (modlen > sizeof(buf)) + if (modlen > buflen) return SC_ERROR_BUFFER_TOO_SMALL; memmove(tmp+modlen-inlen, tmp, inlen); memset(tmp, 0, modlen-inlen); @@ -744,7 +747,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, r = use_key(p15card, obj, &senv, sc_compute_signature, tmp, inlen, out, outlen); - LOG_TEST_RET(ctx, r, "use_key() failed"); + LOG_TEST_GOTO_ERR(ctx, r, "use_key() failed"); /* Some cards may return RSA signature as integer without leading zero bytes */ /* Already know outlen >= modlen and r >= 0 */ @@ -754,7 +757,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, r = modlen; } - sc_mem_clear(buf, sizeof(buf)); +err: + sc_mem_secure_free(buf, buflen); LOG_FUNC_RETURN(ctx, r); } From 042f2d17bcabce16b96646aeb174ee671f984eea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Apr 2021 00:04:39 +0200 Subject: [PATCH 1962/4321] pkcs11: allow arbitrary length for signing --- src/pkcs11/mechanism.c | 91 ++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index c5959b36b8..0c64db85ce 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -38,11 +38,51 @@ struct hash_signature_info { struct signature_data { struct sc_pkcs11_object *key; struct hash_signature_info *info; - sc_pkcs11_operation_t * md; - CK_BYTE buffer[4096/8]; + sc_pkcs11_operation_t *md; + CK_BYTE *buffer; unsigned int buffer_len; }; +static struct signature_data * +new_signature_data() +{ + return calloc(1, sizeof(struct signature_data)); +} + +static void +signature_data_release(struct signature_data *data) +{ + if (!data) + return; + sc_pkcs11_release_operation(&data->md); + sc_mem_secure_free(data->buffer, data->buffer_len); + free(data); +} + +static CK_RV +signature_data_buffer_append(struct signature_data *data, + const CK_BYTE *in, unsigned int in_len) +{ + if (!data) + return CKR_ARGUMENTS_BAD; + if (in_len == 0) + return CKR_OK; + + unsigned int new_len = data->buffer_len + in_len; + CK_BYTE *new_buffer = sc_mem_secure_alloc(new_len); + if (!new_buffer) + return CKR_HOST_MEMORY; + + if (data->buffer_len != 0) + memcpy(new_buffer, data->buffer, data->buffer_len); + memcpy(new_buffer+data->buffer_len, in, in_len); + + sc_mem_secure_free(data->buffer, data->buffer_len); + data->buffer = new_buffer; + data->buffer_len = new_len; + return CKR_OK; +} + /* * Register a mechanism */ @@ -374,7 +414,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, int can_do_it = 0; LOG_FUNC_CALLED(context); - if (!(data = calloc(1, sizeof(*data)))) + if (!(data = new_signature_data())) LOG_FUNC_RETURN(context, CKR_HOST_MEMORY); data->info = NULL; data->key = key; @@ -391,7 +431,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, } else { /* Mechanism recognised but cannot be performed by pkcs#15 card, or some general error. */ - free(data); + signature_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } } @@ -401,7 +441,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, rv = key->ops->init_params(operation->session, &operation->mechanism); if (rv != CKR_OK) { /* Probably bad arguments */ - free(data); + signature_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } } @@ -420,7 +460,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, rv = info->hash_type->md_init(data->md); if (rv != CKR_OK) { sc_pkcs11_release_operation(&data->md); - free(data); + signature_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } data->info = info; @@ -435,21 +475,19 @@ sc_pkcs11_signature_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { struct signature_data *data; + CK_RV rv; LOG_FUNC_CALLED(context); sc_log(context, "data part length %li", ulPartLen); data = (struct signature_data *) operation->priv_data; if (data->md) { - CK_RV rv = data->md->type->md_update(data->md, pPart, ulPartLen); + rv = data->md->type->md_update(data->md, pPart, ulPartLen); LOG_FUNC_RETURN(context, (int) rv); } /* This signature mechanism operates on the raw data */ - if (data->buffer_len + ulPartLen > sizeof(data->buffer)) - LOG_FUNC_RETURN(context, CKR_DATA_LEN_RANGE); - memcpy(data->buffer + data->buffer_len, pPart, ulPartLen); - data->buffer_len += ulPartLen; - LOG_FUNC_RETURN(context, CKR_OK); + rv = signature_data_buffer_append(data, pPart, ulPartLen); + LOG_FUNC_RETURN(context, (int) rv); } static CK_RV @@ -463,14 +501,17 @@ sc_pkcs11_signature_final(sc_pkcs11_operation_t *operation, data = (struct signature_data *) operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; - CK_ULONG len = sizeof(data->buffer); + CK_BYTE hash[64]; + CK_ULONG len = sizeof(hash); - rv = md->type->md_final(md, data->buffer, &len); + rv = md->type->md_final(md, hash, &len); if (rv == CKR_BUFFER_TOO_SMALL) rv = CKR_FUNCTION_FAILED; if (rv != CKR_OK) LOG_FUNC_RETURN(context, (int) rv); - data->buffer_len = (unsigned int) len; + rv = signature_data_buffer_append(data, hash, len); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); } rv = data->key->ops->sign(operation->session, data->key, &operation->mechanism, @@ -527,14 +568,9 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) static void sc_pkcs11_signature_release(sc_pkcs11_operation_t *operation) { - struct signature_data *data; - - data = (struct signature_data *) operation->priv_data; - if (!data) + if (!operation) return; - sc_pkcs11_release_operation(&data->md); - memset(data, 0, sizeof(*data)); - free(data); + signature_data_release(operation->priv_data); } #ifdef ENABLE_OPENSSL @@ -643,7 +679,7 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, struct signature_data *data; CK_RV rv; - if (!(data = calloc(1, sizeof(*data)))) + if (!(data = new_signature_data())) return CKR_HOST_MEMORY; data->info = NULL; @@ -708,11 +744,8 @@ sc_pkcs11_verify_update(sc_pkcs11_operation_t *operation, } /* This verification mechanism operates on the raw data */ - if (data->buffer_len + ulPartLen > sizeof(data->buffer)) - return CKR_DATA_LEN_RANGE; - memcpy(data->buffer + data->buffer_len, pPart, ulPartLen); - data->buffer_len += ulPartLen; - return CKR_OK; + CK_RV rv = signature_data_buffer_append(data, pPart, ulPartLen); + LOG_FUNC_RETURN(context, (int) rv); } static CK_RV @@ -1056,7 +1089,7 @@ sc_pkcs11_decrypt_init(sc_pkcs11_operation_t *operation, struct signature_data *data; CK_RV rv; - if (!(data = calloc(1, sizeof(*data)))) + if (!(data = new_signature_data())) return CKR_HOST_MEMORY; data->key = key; From 5503b8e261705eb92d5b6bef453e8906ed6b7eec Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 29 Apr 2021 12:25:26 +0200 Subject: [PATCH 1963/4321] use __FILE_NAME__ instead of __FILE__ if possible ... to strip the path --- src/libopensc/log.h | 22 ++++++++++++++-------- src/pkcs11/sc-pkcs11.h | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 4648643d32..790a846289 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -59,9 +59,15 @@ enum { #define __FUNCTION__ NULL #endif +#ifdef __FILE_NAME__ +#define FILENAME __FILE_NAME__ +#else +#define FILENAME __FILE__ +#endif + #if defined(__GNUC__) -#define sc_debug(ctx, level, format, args...) sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, format , ## args) -#define sc_log(ctx, format, args...) sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, __FILE__, __LINE__, __FUNCTION__, format , ## args) +#define sc_debug(ctx, level, format, args...) sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args) +#define sc_log(ctx, format, args...) sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args) #else #define sc_debug _sc_debug #define sc_log _sc_log @@ -109,7 +115,7 @@ int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const ch * @param[in] len Length of \a data */ #define sc_debug_hex(ctx, level, label, data, len) \ - _sc_debug_hex(ctx, level, __FILE__, __LINE__, __FUNCTION__, label, data, len) + _sc_debug_hex(ctx, level, FILENAME, __LINE__, __FUNCTION__, label, data, len) #define sc_log_hex(ctx, label, data, len) \ sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, label, data, len) /** @@ -131,17 +137,17 @@ void sc_hex_dump(const u8 *buf, size_t len, char *out, size_t outlen); const char * sc_dump_hex(const u8 * in, size_t count); const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_FUNC_CALLED(ctx, level) do { \ - sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, "called\n"); \ + sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \ } while (0) #define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL) #define SC_FUNC_RETURN(ctx, level, r) do { \ int _ret = r; \ if (_ret <= 0) { \ - sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \ + sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \ "returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \ } else { \ - sc_do_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, \ + sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \ "returning with: %d\n", _ret); \ } \ return _ret; \ @@ -151,7 +157,7 @@ const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_TEST_RET(ctx, level, r, text) do { \ int _ret = (r); \ if (_ret < 0) { \ - sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ + sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ "%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \ return _ret; \ } \ @@ -161,7 +167,7 @@ const char * sc_dump_oid(const struct sc_object_id *oid); #define SC_TEST_GOTO_ERR(ctx, level, r, text) do { \ int _ret = (r); \ if (_ret < 0) { \ - sc_do_log_color(ctx, level, __FILE__, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ + sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \ "%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \ goto err; \ } \ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index ee1fe85308..815deffe1a 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -375,7 +375,7 @@ CK_RV sc_to_cryptoki_error(int rc, const char *ctx); void sc_pkcs11_print_attrs(int level, const char *file, unsigned int line, const char *function, const char *info, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); #define dump_template(level, info, pTemplate, ulCount) \ - sc_pkcs11_print_attrs(level, __FILE__, __LINE__, __FUNCTION__, \ + sc_pkcs11_print_attrs(level, FILENAME, __LINE__, __FUNCTION__, \ info, pTemplate, ulCount) /* Slot and card handling functions */ From 789f16159c28ea417fd56ec0c63e99ef5746ba17 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 30 Apr 2021 14:09:52 +0200 Subject: [PATCH 1964/4321] introduce sc_mem_secure_clear_free() --- src/libopensc/opensc.h | 4 ++++ src/libopensc/pkcs15.c | 3 +-- src/pkcs11/mechanism.c | 4 ++-- src/pkcs11/misc.c | 9 +++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 45fe9aaa9b..6adde39c75 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1539,6 +1539,10 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen); void sc_mem_clear(void *ptr, size_t len); void *sc_mem_secure_alloc(size_t len); void sc_mem_secure_free(void *ptr, size_t len); +#define sc_mem_secure_clear_free(ptr, len) do { \ + sc_mem_clear(ptr, len); \ + sc_mem_secure_free(ptr, len); \ +} while (0); int sc_mem_reverse(unsigned char *buf, size_t len); int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 812061bc7c..dc5cfaafc6 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2557,8 +2557,7 @@ void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj) || SC_PKCS15_TYPE_SKEY & obj->type || SC_PKCS15_TYPE_PRKEY & obj->type) { /* clean everything that potentially contains a secret */ - sc_mem_clear(obj->content.value, obj->content.len); - sc_mem_secure_free(obj->content.value, obj->content.len); + sc_mem_secure_clear_free(obj->content.value, obj->content.len); } else { free(obj->content.value); } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 0c64db85ce..e41992fe36 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -55,7 +55,7 @@ signature_data_release(struct signature_data *data) if (!data) return; sc_pkcs11_release_operation(&data->md); - sc_mem_secure_free(data->buffer, data->buffer_len); + sc_mem_secure_clear_free(data->buffer, data->buffer_len); free(data); } @@ -77,7 +77,7 @@ signature_data_buffer_append(struct signature_data *data, memcpy(new_buffer, data->buffer, data->buffer_len); memcpy(new_buffer+data->buffer_len, in, in_len); - sc_mem_secure_free(data->buffer, data->buffer_len); + sc_mem_secure_clear_free(data->buffer, data->buffer_len); data->buffer = new_buffer; data->buffer_len = new_len; return CKR_OK; diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index c3f5bb4e15..75660ed804 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -216,8 +216,7 @@ CK_RV push_login_state(struct sc_pkcs11_slot *slot, err: if (login) { if (login->pPin) { - sc_mem_clear(login->pPin, login->ulPinLen); - sc_mem_secure_free(login->pPin, login->ulPinLen); + sc_mem_secure_clear_free(login->pPin, login->ulPinLen); } free(login); } @@ -232,8 +231,7 @@ void pop_login_state(struct sc_pkcs11_slot *slot) if (size > 0) { struct sc_pkcs11_login *login = list_get_at(&slot->logins, size-1); if (login) { - sc_mem_clear(login->pPin, login->ulPinLen); - sc_mem_secure_free(login->pPin, login->ulPinLen); + sc_mem_secure_clear_free(login->pPin, login->ulPinLen); free(login); } if (0 > list_delete_at(&slot->logins, size-1)) @@ -247,8 +245,7 @@ void pop_all_login_states(struct sc_pkcs11_slot *slot) if (sc_pkcs11_conf.atomic && slot) { struct sc_pkcs11_login *login = list_fetch(&slot->logins); while (login) { - sc_mem_clear(login->pPin, login->ulPinLen); - sc_mem_secure_free(login->pPin, login->ulPinLen); + sc_mem_secure_clear_free(login->pPin, login->ulPinLen); free(login); login = list_fetch(&slot->logins); } From e59d6520616548242f7c2edcf947d1b634b8e957 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Aug 2021 21:44:52 +0200 Subject: [PATCH 1965/4321] clear memory when finishing signature computation --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 5018599893..93e24d3b67 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -758,7 +758,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } err: - sc_mem_secure_free(buf, buflen); + sc_mem_secure_clear_free(buf, buflen); LOG_FUNC_RETURN(ctx, r); } From 6d580ac9010b2873576e45da9e2726547c915913 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Aug 2021 21:47:13 +0200 Subject: [PATCH 1966/4321] fixed possible memory leak thanks, jakub for spotting this --- src/libopensc/pkcs15-sec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 93e24d3b67..9c44907c9f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -726,8 +726,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { /* Add zero-padding if input is shorter than the modulus */ if (inlen < modlen) { - if (modlen > buflen) - return SC_ERROR_BUFFER_TOO_SMALL; + if (modlen > buflen) { + r = SC_ERROR_BUFFER_TOO_SMALL; + goto err; + } memmove(tmp+modlen-inlen, tmp, inlen); memset(tmp, 0, modlen-inlen); } From 4aed6772fb0e718014d6e6c6987128748715db88 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Aug 2021 22:27:38 +0200 Subject: [PATCH 1967/4321] ci: no need to focus on non-PRs secrets are only available for collaborators, so just fire everything up --- .github/cleanup-macos.sh | 2 +- .github/setup-macos.sh | 2 +- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/cleanup-macos.sh b/.github/cleanup-macos.sh index 0a0fbaf799..c1f5e32749 100755 --- a/.github/cleanup-macos.sh +++ b/.github/cleanup-macos.sh @@ -2,6 +2,6 @@ set -ex -o xtrace -if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then +if [ -n "$PASS_SECRETS_TAR_ENC" ]; then .github/remove_signing_key.sh fi diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index dbaa955149..ae71a014b7 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -25,7 +25,7 @@ export PATH="/usr/local/opt/ccache/libexec:$PATH" git clone https://github.com/frankmorgner/OpenSCToken.git sudo rm -rf /Library/Developer/CommandLineTools; -if [ "$GITHUB_EVENT_NAME" != "pull_request" -a -n "$PASS_SECRETS_TAR_ENC" ]; then +if [ -n "$PASS_SECRETS_TAR_ENC" ]; then gpg --quiet --batch --yes --decrypt --passphrase="$PASS_SECRETS_TAR_ENC" --output .github/secrets.tar .github/secrets.tar.gpg .github/add_signing_key.sh; else diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c4729d9292..56c278edad 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -174,4 +174,4 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" - if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} + if: ${{ secrets.GH_TOKEN != '' }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a3ad468a79..0f0b00c113 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -46,4 +46,4 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" - if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }} + if: ${{ secrets.GH_TOKEN != '' }} From 9191cee9f31e6054d2cf4fc896d8d3e32a73f2d2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 30 Aug 2021 22:42:34 +0200 Subject: [PATCH 1968/4321] workaround invalid syntax, exit push_artifacts early instead --- .github/push_artifacts.sh | 4 ++++ .github/workflows/linux.yml | 1 - .github/workflows/macos.yml | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 10491f9dd9..61d9f0702b 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -2,6 +2,10 @@ set -ex -o xtrace +if [ -z "$GH_TOKEN" ]; then + exit 0 +fi + BUILDPATH=${PWD} BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 56c278edad..96983d1dd2 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -174,4 +174,3 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" - if: ${{ secrets.GH_TOKEN != '' }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0f0b00c113..1db3767487 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -46,4 +46,3 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" - if: ${{ secrets.GH_TOKEN != '' }} From 59bd3c1d4c6c75acb7c34635760daf3214b5cde1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 31 Aug 2021 12:49:28 +0200 Subject: [PATCH 1969/4321] ci: only push artifacts with opensc/opensc --- .github/workflows/linux.yml | 1 + .github/workflows/macos.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 96983d1dd2..cc4588f4d9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -174,3 +174,4 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + if: ${{ github.repository == 'OpenSC/OpenSC' }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 1db3767487..b7762bfd0b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -46,3 +46,4 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + if: ${{ github.repository == 'OpenSC/OpenSC' }} From f44564b2e9cdc9baf67914f1e5b7c2da6f007862 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 18 Aug 2021 10:09:17 +0200 Subject: [PATCH 1970/4321] Disable old cards drivers Currently disabled card drivers due to no recent user or developer activity: - akis - asepcos - atrust-acos - flex - gpk - incrypto34 - westcos --- src/libopensc/ctx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 1ba3c94b32..74ed2df4ab 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -95,13 +95,8 @@ struct _sc_driver_entry { static const struct _sc_driver_entry internal_card_drivers[] = { { "cardos", (void *(*)(void)) sc_get_cardos_driver }, - { "flex", (void *(*)(void)) sc_get_cryptoflex_driver }, { "cyberflex", (void *(*)(void)) sc_get_cyberflex_driver }, -#ifdef ENABLE_OPENSSL - { "gpk", (void *(*)(void)) sc_get_gpk_driver }, -#endif { "gemsafeV1", (void *(*)(void)) sc_get_gemsafeV1_driver }, - { "asepcos", (void *(*)(void)) sc_get_asepcos_driver }, { "starcos", (void *(*)(void)) sc_get_starcos_driver }, { "tcos", (void *(*)(void)) sc_get_tcos_driver }, #ifdef ENABLE_OPENSSL @@ -110,8 +105,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "iasecc", (void *(*)(void)) sc_get_iasecc_driver }, #endif { "belpic", (void *(*)(void)) sc_get_belpic_driver }, - { "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver }, - { "akis", (void *(*)(void)) sc_get_akis_driver }, #ifdef ENABLE_OPENSSL { "entersafe",(void *(*)(void)) sc_get_entersafe_driver }, #ifdef ENABLE_SM @@ -125,8 +118,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "dnie", (void *(*)(void)) sc_get_dnie_driver }, #endif { "masktech", (void *(*)(void)) sc_get_masktech_driver }, - { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, - { "westcos", (void *(*)(void)) sc_get_westcos_driver }, { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver }, { "idprime", (void *(*)(void)) sc_get_idprime_driver }, #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) @@ -161,6 +152,15 @@ static const struct _sc_driver_entry internal_card_drivers[] = { }; static const struct _sc_driver_entry old_card_drivers[] = { + { "akis", (void *(*)(void)) sc_get_akis_driver }, + { "asepcos", (void *(*)(void)) sc_get_asepcos_driver }, + { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, + { "flex", (void *(*)(void)) sc_get_cryptoflex_driver }, +#ifdef ENABLE_OPENSSL + { "gpk", (void *(*)(void)) sc_get_gpk_driver }, +#endif + { "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver }, + { "westcos", (void *(*)(void)) sc_get_westcos_driver }, { NULL, NULL } }; From 05090d8bd23f108039dcf662daa64375a5734bcd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 5 Aug 2021 11:39:20 +0200 Subject: [PATCH 1971/4321] Add boilerplate for disabling old pkcs15 emulators Filtering of enabled pkcs15 emulators according to conf file. Currently disabled: - westcos - gemsafeGPK - atrust-acos --- doc/files/opensc.conf.5.xml.in | 13 +-- etc/opensc.conf.example.in | 6 +- src/libopensc/Makefile.am | 6 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/pkcs15-emulator-filter.c | 122 +++++++++++++++++++++++++ src/libopensc/pkcs15-emulator-filter.h | 28 ++++++ src/libopensc/pkcs15-syn.c | 57 ++++++++---- src/libopensc/types.h | 1 + 8 files changed, 205 insertions(+), 30 deletions(-) create mode 100644 src/libopensc/pkcs15-emulator-filter.c create mode 100644 src/libopensc/pkcs15-emulator-filter.h diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index adf9dda6eb..ae52109b27 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1269,12 +1269,13 @@ app application { List of the builtin pkcs15 emulators to test - (Default: westcos, openpgp, - starcert, tcos, esteid, itacns, - PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, - atrust-acos, tccardos, entersafe, pteid, - oberthur, sc-hsm, dnie, gids, iasecc, jpki, - coolkey, din66291) + (Default: internal) + + + Special value of 'internal' will try all not disabled builtin pkcs15 emulators. + + + Special value of 'old' will try all disabled pkcs15 emulators.
    diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 99034fdb9b..ec9bc8d57d 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -929,8 +929,10 @@ app default { # enable_builtin_emulation = no; # # List of the builtin pkcs15 emulators to test - # Default: esteid, openpgp, tcos, starcert, itacns, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; - # builtin_emulators = openpgp; + # Special value of 'internal' will try all not disabled builtin pkcs15 emulators. + # Special value of 'old' will try all disabled pkcs15 emulators. + # Default: internal; + # builtin_emulators = old, internal; # additional settings per driver # diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index ab4c662d6b..1303c034a7 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -6,7 +6,7 @@ EXTRA_DIST = Makefile.mak opensc.dll.manifest lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ - internal-winscard.h p15card-helper.h pkcs15-syn.h \ + internal-winscard.h p15card-helper.h pkcs15-syn.h pkcs15-emulator-filter.h \ opensc.h pkcs15.h gp.h \ cardctl.h asn1.h log.h simpletlv.h \ errors.h types.h compression.h itacns.h iso7816.h \ @@ -31,7 +31,7 @@ libopensc_la_SOURCES_BASE = \ \ pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ - pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ + pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c pkcs15-emulator-filter.c \ \ muscle.c muscle-filesystem.c \ \ @@ -114,7 +114,7 @@ TIDY_FILES = \ \ pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ - pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ + pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c pkcs15-emulator-filter.c \ \ muscle.c muscle-filesystem.c \ \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 9280ed8e24..2689724532 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -8,7 +8,7 @@ OBJECTS = \ \ pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \ pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-skey.obj \ - pkcs15-sec.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \ + pkcs15-sec.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj pkcs15-emulator-filter.obj \ \ muscle.obj muscle-filesystem.obj \ \ diff --git a/src/libopensc/pkcs15-emulator-filter.c b/src/libopensc/pkcs15-emulator-filter.c new file mode 100644 index 0000000000..d282b20acb --- /dev/null +++ b/src/libopensc/pkcs15-emulator-filter.c @@ -0,0 +1,122 @@ +/* + * pkcs15-emulator-filter.c: PKCS #15 emulator filter + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "internal.h" +#include "pkcs15-syn.h" +#include "pkcs15-emulator-filter.h" + +static int add_emul(struct _sc_pkcs15_emulators* filtered_emulators, + struct sc_pkcs15_emulator_handler* emul_handler) +{ + struct sc_pkcs15_emulator_handler** lst; + int *cp, max, i; + + if (!filtered_emulators || !emul_handler || !emul_handler->name || !emul_handler->handler) + return SC_ERROR_INVALID_ARGUMENTS; + + lst = filtered_emulators->list_of_handlers; + cp = &filtered_emulators->ccount; + max = SC_MAX_PKCS15_EMULATORS; + + if (*cp > max) + return SC_ERROR_INVALID_ARGUMENTS; + if (*cp == max) + return SC_ERROR_TOO_MANY_OBJECTS; + + for (i = 0; i < *cp; i++) { + if (!lst[i]) + return SC_ERROR_OBJECT_NOT_VALID; + if (!strcmp(lst[i]->name, emul_handler->name)) + return SC_SUCCESS; + } + + lst[*cp] = emul_handler; + (*cp)++; + return SC_SUCCESS; +} + +static int add_emul_list(struct _sc_pkcs15_emulators* filtered_emulators, + struct sc_pkcs15_emulator_handler* emulators) +{ + struct sc_pkcs15_emulator_handler* lst; + int i, r; + + if (!filtered_emulators || !emulators) + return SC_ERROR_INVALID_ARGUMENTS; + + lst = emulators; + for(i = 0; lst[i].name; i++) { + if ((r = add_emul(filtered_emulators, &lst[i]))) + return r; + } + return SC_SUCCESS; +} + +int set_emulators(struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, + struct sc_pkcs15_emulator_handler* internal, struct sc_pkcs15_emulator_handler* old) +{ + const scconf_list *item; + int *cp, i, r, count; + + if (!filtered_emulators || !list || !internal || !old) + return SC_ERROR_INVALID_ARGUMENTS; + + cp = &filtered_emulators->ccount; + r = SC_SUCCESS; + + for (item = list; item; item = item->next) { + if (!item->data) + continue; + + if (!strcmp(item->data, "internal")) { + if ((r = add_emul_list(filtered_emulators, internal))) + goto out; + } else if (!strcmp(item->data, "old")) { + if ((r = add_emul_list(filtered_emulators, old))) + goto out; + } else { + count = *cp; + for (i = 0; internal[i].name; i++) { + if (!strcmp(internal[i].name, item->data)) { + if ((r = add_emul(filtered_emulators, &internal[i]))) + goto out; + break; + } + } + for (i = 0; old[i].name && count == *cp; i++) { + if (!strcmp(old[i].name, item->data)) { + if ((r = add_emul(filtered_emulators, &old[i]))) + goto out; + break; + } + } + } + } +out: + if (r == SC_SUCCESS || r == SC_ERROR_TOO_MANY_OBJECTS) { + filtered_emulators->list_of_handlers[*cp] = NULL; + } + return r; +} diff --git a/src/libopensc/pkcs15-emulator-filter.h b/src/libopensc/pkcs15-emulator-filter.h new file mode 100644 index 0000000000..c943050585 --- /dev/null +++ b/src/libopensc/pkcs15-emulator-filter.h @@ -0,0 +1,28 @@ +/* + * pkcs15-emulator-filter.h: PKCS #15 emulator filter + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +struct _sc_pkcs15_emulators { + struct sc_pkcs15_emulator_handler *list_of_handlers[SC_MAX_PKCS15_EMULATORS + 1]; + int ccount; +}; + +int set_emulators(struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, + struct sc_pkcs15_emulator_handler* builtin, struct sc_pkcs15_emulator_handler* old); diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index d4e03df866..ecee04c2e9 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -33,9 +33,9 @@ #include "asn1.h" #include "pkcs15.h" #include "pkcs15-syn.h" +#include "pkcs15-emulator-filter.h" struct sc_pkcs15_emulator_handler builtin_emulators[] = { - { "westcos", sc_pkcs15emu_westcos_init_ex }, { "openpgp", sc_pkcs15emu_openpgp_init_ex }, { "starcert", sc_pkcs15emu_starcert_init_ex }, { "tcos", sc_pkcs15emu_tcos_init_ex }, @@ -44,10 +44,8 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "PIV-II", sc_pkcs15emu_piv_init_ex }, { "cac", sc_pkcs15emu_cac_init_ex }, { "idprime", sc_pkcs15emu_idprime_init_ex }, - { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex }, { "gemsafeV1", sc_pkcs15emu_gemsafeV1_init_ex }, { "actalis", sc_pkcs15emu_actalis_init_ex }, - { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex}, { "tccardos", sc_pkcs15emu_tccardos_init_ex }, { "entersafe", sc_pkcs15emu_entersafe_init_ex }, { "pteid", sc_pkcs15emu_pteid_init_ex }, @@ -61,10 +59,16 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "din66291", sc_pkcs15emu_din_66291_init_ex }, { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, { "cardos", sc_pkcs15emu_cardos_init_ex }, - { NULL, NULL } }; +struct sc_pkcs15_emulator_handler old_emulators[] = { + { "westcos", sc_pkcs15emu_westcos_init_ex }, + { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex }, + { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex}, + { NULL, NULL } +}; + static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *); static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type); @@ -132,25 +136,34 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) } else { /* we have a conf file => let's use it */ int builtin_enabled; - const scconf_list *list, *item; + const scconf_list *list; builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1); list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */ if (builtin_enabled && list) { - /* get the list of enabled emulation drivers */ - for (item = list; item; item = item->next) { - /* go through the list of builtin drivers */ - const char *name = item->data; - - sc_log(ctx, "trying %s", name); - for (i = 0; builtin_emulators[i].name; i++) - if (!strcmp(builtin_emulators[i].name, name)) { - r = builtin_emulators[i].handler(p15card, aid); - if (r == SC_SUCCESS) - /* we got a hit */ - goto out; - } + /* filter enabled emulation drivers from conf file */ + struct _sc_pkcs15_emulators filtered_emulators; + struct sc_pkcs15_emulator_handler** lst; + int ret; + + filtered_emulators.ccount = 0; + ret = set_emulators(&filtered_emulators, list, builtin_emulators, old_emulators); + if (ret == SC_SUCCESS || ret == SC_ERROR_TOO_MANY_OBJECTS) { + lst = filtered_emulators.list_of_handlers; + + if (ret == SC_ERROR_TOO_MANY_OBJECTS) + sc_log(ctx, "number of filtered emulators exceeded %d", SC_MAX_PKCS15_EMULATORS); + + for (i = 0; lst[i]; i++) { + sc_log(ctx, "trying %s", lst[i]->name); + r = lst[i]->handler(p15card, aid); + if (r == SC_SUCCESS) + /* we got a hit */ + goto out; + } + } else { + sc_log(ctx, "failed to filter enabled card emulators: %s", sc_strerror(ret)); } } else if (builtin_enabled) { @@ -222,6 +235,14 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf break; } } + if (init_func_ex == NULL) { + for (i = 0; old_emulators[i].name; i++) { + if (!strcmp(old_emulators[i].name, module_name)) { + init_func_ex = old_emulators[i].handler; + break; + } + } + } } else { const char *(*get_version)(void); const char *name = NULL; diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 575b40e3f2..e0a615f3fc 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -49,6 +49,7 @@ typedef unsigned char u8; #define SC_MAX_SDO_ACLS 8 #define SC_MAX_CRTS_IN_SE 12 #define SC_MAX_SE_NUM 8 +#define SC_MAX_PKCS15_EMULATORS 48 /* When changing this value, pay attention to the initialization of the ASN1 * static variables that use this macro, like, for example, From 91240fefc630b1122ca7f777eace4fb872017b9d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 5 Aug 2021 16:01:26 +0200 Subject: [PATCH 1972/4321] Update documentation for disabling pkcs15 emulators --- doc/files/files.html | 11 +++++------ doc/files/opensc.conf.5.xml.in | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index f536af6e51..f0c877e1c2 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -837,12 +837,11 @@ builtin_emulators = emulators;

    List of the builtin pkcs15 emulators to test - (Default: westcos, openpgp, - starcert, tcos, esteid, itacns, - PIV-II, cac, gemsafeGPK, gemsafeV1, actalis, - atrust-acos, tccardos, entersafe, pteid, - oberthur, sc-hsm, dnie, gids, iasecc, jpki, - coolkey, din66291) + (Default: internal) +

    + Special value internal will try all not disabled builtin pkcs15 emulators. +

    + Special value of old will try all disabled pkcs15 emulators.

    pkcs11_enable_InitToken = bool;

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index ae52109b27..467b10e07a 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1272,10 +1272,10 @@ app application { (Default: internal) - Special value of 'internal' will try all not disabled builtin pkcs15 emulators. + Special value of internal will try all not disabled builtin pkcs15 emulators. - Special value of 'old' will try all disabled pkcs15 emulators. + Special value of old will try all disabled pkcs15 emulators. From 0bc9a58c09f54bf142ec997cfd62046c2b68abac Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Aug 2021 15:32:42 +0200 Subject: [PATCH 1973/4321] Add unit tests for filtering pkcs15 emulators Basic unit tests for filtering enabled emulators according to conf file --- src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/Makefile.mak | 5 +- src/tests/unittests/pkcs15-emulator-filter.c | 490 +++++++++++++++++++ 3 files changed, 496 insertions(+), 4 deletions(-) create mode 100644 src/tests/unittests/pkcs15-emulator-filter.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 03019c324d..5b200bc8d3 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -6,8 +6,8 @@ include $(top_srcdir)/aminclude_static.am clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean -noinst_PROGRAMS = asn1 simpletlv cachedir -TESTS = asn1 simpletlv cachedir +noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter +TESTS = asn1 simpletlv cachedir pkcs15filter noinst_HEADERS = torture.h @@ -23,6 +23,7 @@ LDADD = $(top_builddir)/src/libopensc/libopensc.la \ asn1_SOURCES = asn1.c simpletlv_SOURCES = simpletlv.c cachedir_SOURCES = cachedir.c +pkcs15filter_SOURCES = pkcs15-emulator-filter.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak index 41762fdbf6..83d52b59e1 100644 --- a/src/tests/unittests/Makefile.mak +++ b/src/tests/unittests/Makefile.mak @@ -1,9 +1,10 @@ TOPDIR = ..\..\.. -TARGETS = asn1 compression +TARGETS = asn1 compression pkcs15filter OBJECTS = asn1.obj \ - compression.obj + compression.obj \ + pkcs15-emulator-filter.obj $(TOPDIR)\win32\versioninfo.res all: $(TARGETS) diff --git a/src/tests/unittests/pkcs15-emulator-filter.c b/src/tests/unittests/pkcs15-emulator-filter.c new file mode 100644 index 0000000000..c8c6341711 --- /dev/null +++ b/src/tests/unittests/pkcs15-emulator-filter.c @@ -0,0 +1,490 @@ +/* + * pkcs15-emulator-filter.c: Unit tests for PKCS15 emulator filter + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "torture.h" +#include "libopensc/pkcs15-emulator-filter.c" + +int func(sc_pkcs15_card_t *card, struct sc_aid *aid) { + (void) card; + (void) aid; + return SC_SUCCESS; +} + +struct sc_pkcs15_emulator_handler builtin[] = { + { "openpgp", &func }, + { "starcert", &func }, + { NULL, NULL } +}; +struct sc_pkcs15_emulator_handler old[] = { + { "westcos", &func }, + { "cardos", &func }, + { "jcop", &func }, + { NULL, NULL } +}; + +/* add_emul */ +static void torture_null_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &builtin[0] }, 1 }; + int rv; + + rv = add_emul(NULL, &builtin[0]); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + rv = add_emul(&filtered_emulators, NULL); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +static void torture_name_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int rv; + filtered_emulators.ccount = 0; + + rv = add_emul(&filtered_emulators, &builtin[0]); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(filtered_emulators.ccount, 1); +} + +static void torture_name_already_in_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &builtin[0] }, 1 }; + int rv; + + rv = add_emul(&filtered_emulators, &builtin[0]); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(filtered_emulators.ccount, 1); +} + +static void torture_full_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = add_emul(&filtered_emulators, &old[0]); + assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); + assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &builtin[0]); +} + +static void torture_overfilled_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS + 1; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS + 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = add_emul(&filtered_emulators, &old[0]); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS + 1); +} + +static void torture_invalid_handler_name_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + struct sc_pkcs15_emulator_handler handler = { NULL, &func }; + int rv; + filtered_emulators.ccount = 0; + + rv = add_emul(&filtered_emulators, &handler); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +static void torture_invalid_handler_func_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + struct sc_pkcs15_emulator_handler handler = { "name", NULL }; + int rv; + filtered_emulators.ccount = 0; + + rv = add_emul(&filtered_emulators, &handler); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +static void torture_invalid_emulator_list_add_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { NULL }, 1 }; + struct sc_pkcs15_emulator_handler handler = { "name", &func }; + int rv; + + rv = add_emul(&filtered_emulators, &handler); + assert_int_equal(rv, SC_ERROR_OBJECT_NOT_VALID); +} + +/* add_emul_list */ +static void torture_null_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &builtin[0] }, 1 }; + int rv; + + rv = add_emul_list(NULL, builtin); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + rv = add_emul_list(&filtered_emulators, NULL); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +static void torture_internal_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = 0; + + rv = add_emul_list(&filtered_emulators, builtin); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_int_equal(filtered_emulators.ccount, i); +} + +static void torture_internal_already_name_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &builtin[0] }, 1 }; + int i, rv; + + rv = add_emul_list(&filtered_emulators, builtin); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_int_equal(filtered_emulators.ccount, i); +} + +static void torture_internal_already_name2_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &old[0] }, 1 }; + int i, rv; + + rv = add_emul_list(&filtered_emulators, builtin); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i + 1]); + } + assert_int_equal(filtered_emulators.ccount, i + 1); +} + +static void torture_full_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[1]; + } + + rv = add_emul_list(&filtered_emulators, builtin); + assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); +} + +static void torture_one_to_full_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS - 1; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS - 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = add_emul_list(&filtered_emulators, old); + assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); + assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[0]); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); + assert_ptr_not_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS], &old[0]); +} + +static void torture_overfilled_add_emul_list(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS + 1; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS + 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = add_emul_list(&filtered_emulators, old); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &builtin[0]); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS + 1); +} + +/* set_emulators */ +static void torture_non_existing(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int rv; + scconf_list list = { NULL, "non" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + assert_null(filtered_emulators.list_of_handlers[0]); +} + +static void torture_internal_only(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + scconf_list list = { NULL, "internal" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_int_equal(filtered_emulators.ccount, 2); + assert_null(filtered_emulators.list_of_handlers[2]); + assert_null(builtin[i].name); +} + +static void torture_old_only(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + scconf_list list = { NULL, "old" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; old[i].name; i++) { + assert_ptr_equal(&old[i], filtered_emulators.list_of_handlers[i]); + } + assert_null(filtered_emulators.list_of_handlers[i]); + assert_null(old[i].name); +} + +static void torture_internal_name(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int rv; + scconf_list list = { NULL, strdup(builtin[0].name) }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + assert_ptr_equal(&builtin[0], filtered_emulators.list_of_handlers[0]); + assert_null(filtered_emulators.list_of_handlers[1]); +} + +static void torture_old_name(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int rv; + scconf_list list = { NULL, strdup(old[0].name) }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + assert_ptr_equal(&old[0], filtered_emulators.list_of_handlers[0]); + assert_null(filtered_emulators.list_of_handlers[1]); +} + +static void torture_internal_and_name(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + scconf_list list2 = { NULL, "cardos" }; + scconf_list list1 = { &list2, "internal" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_ptr_equal(&old[1], filtered_emulators.list_of_handlers[i]); + assert_null(filtered_emulators.list_of_handlers[i + 1]); +} + +static void torture_name_and_internal(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int rv; + scconf_list list2 = { NULL, "internal" }; + scconf_list list1 = { &list2, "starcert" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + assert_ptr_equal(&builtin[1], filtered_emulators.list_of_handlers[0]); + assert_ptr_equal(&builtin[0], filtered_emulators.list_of_handlers[1]); + assert_null(filtered_emulators.list_of_handlers[2]); +} + +static void torture_internal_and_nonexisting(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv;; + scconf_list list2 = { NULL, "non" }; + scconf_list list1 = { &list2, "internal" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_null(filtered_emulators.list_of_handlers[i]); + assert_null(builtin[i].name); +} + +static void torture_nonexisting_and_internal(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + scconf_list list2 = { NULL, "internal" }; + scconf_list list1 = { &list2, "non" }; + filtered_emulators.ccount = 0; + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + for (i = 0; builtin[i].name; i++) { + assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); + } + assert_null(filtered_emulators.list_of_handlers[i]); + assert_null(builtin[i].name); +} + +static void torture_null_set_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators = { { &builtin[0] }, 1 }; + int rv; + scconf_list list1 = { NULL, "internal" }; + + rv = set_emulators(NULL, &list1, builtin, old); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + rv = set_emulators(&filtered_emulators, NULL, builtin, old); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + rv = set_emulators(&filtered_emulators, &list1, NULL, old); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + rv = set_emulators(&filtered_emulators, &list1, builtin, NULL); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +static void torture_full_set_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS; + scconf_list list1 = { NULL, "old" }; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); + assert_non_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1]); + assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); +} + +static void torture_one_to_full_set_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS - 1; + scconf_list list1 = { NULL, "old" }; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS - 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); + assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[0]); + assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); +} + +static void torture_one_to_full2_set_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS - 1; + scconf_list list1 = { NULL, strdup(old[1].name) }; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS - 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_SUCCESS); + assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[1]); + assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); + assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); +} + +static void torture_overfilled_set_emul(void **state) +{ + struct _sc_pkcs15_emulators filtered_emulators; + int i, rv; + filtered_emulators.ccount = SC_MAX_PKCS15_EMULATORS + 1; + scconf_list list1 = { NULL, strdup(old[1].name) }; + for (i = 0; i < SC_MAX_PKCS15_EMULATORS + 1; i++) { + filtered_emulators.list_of_handlers[i] = &builtin[0]; + } + + rv = set_emulators(&filtered_emulators, &list1, builtin, old); + assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + /* add_emul */ + cmocka_unit_test(torture_null_add_emul), + cmocka_unit_test(torture_name_add_emul), + cmocka_unit_test(torture_name_already_in_add_emul), + cmocka_unit_test(torture_full_add_emul), + cmocka_unit_test(torture_overfilled_add_emul), + cmocka_unit_test(torture_invalid_handler_name_add_emul), + cmocka_unit_test(torture_invalid_handler_func_add_emul), + cmocka_unit_test(torture_invalid_emulator_list_add_emul), + /* add_emul_list */ + cmocka_unit_test(torture_null_add_emul_list), + cmocka_unit_test(torture_internal_add_emul_list), + cmocka_unit_test(torture_internal_already_name_add_emul_list), + cmocka_unit_test(torture_internal_already_name2_add_emul_list), + cmocka_unit_test(torture_full_add_emul_list), + cmocka_unit_test(torture_one_to_full_add_emul_list), + cmocka_unit_test(torture_overfilled_add_emul_list), + /* set_emulators */ + cmocka_unit_test(torture_non_existing), + cmocka_unit_test(torture_internal_only), + cmocka_unit_test(torture_old_only), + cmocka_unit_test(torture_internal_name), + cmocka_unit_test(torture_old_name), + cmocka_unit_test(torture_internal_and_name), + cmocka_unit_test(torture_name_and_internal), + cmocka_unit_test(torture_internal_and_nonexisting), + cmocka_unit_test(torture_nonexisting_and_internal), + cmocka_unit_test(torture_null_set_emul), + cmocka_unit_test(torture_full_set_emul), + cmocka_unit_test(torture_one_to_full_set_emul), + cmocka_unit_test(torture_one_to_full2_set_emul), + cmocka_unit_test(torture_overfilled_set_emul), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} From da29c3c3209e8c25b2c4a6fd00c9f7df5ba94263 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 18 Aug 2021 14:55:31 +0200 Subject: [PATCH 1974/4321] Disable pkcs15 emulators for Actalis and TC CardOS Emulators detect card according to string "CardOS M4", which was changed in card-cardos.c (eee4964), but they were not modified since than accordingly. --- src/libopensc/pkcs15-syn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index ecee04c2e9..1f3c8b2209 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -45,8 +45,6 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "cac", sc_pkcs15emu_cac_init_ex }, { "idprime", sc_pkcs15emu_idprime_init_ex }, { "gemsafeV1", sc_pkcs15emu_gemsafeV1_init_ex }, - { "actalis", sc_pkcs15emu_actalis_init_ex }, - { "tccardos", sc_pkcs15emu_tccardos_init_ex }, { "entersafe", sc_pkcs15emu_entersafe_init_ex }, { "pteid", sc_pkcs15emu_pteid_init_ex }, { "oberthur", sc_pkcs15emu_oberthur_init_ex }, @@ -66,6 +64,8 @@ struct sc_pkcs15_emulator_handler old_emulators[] = { { "westcos", sc_pkcs15emu_westcos_init_ex }, { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex }, { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex}, + { "actalis", sc_pkcs15emu_actalis_init_ex }, + { "tccardos", sc_pkcs15emu_tccardos_init_ex }, { NULL, NULL } }; From 146e3e13d1e811b4f5cc522888985880f481dc95 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 26 Aug 2021 15:32:20 +0200 Subject: [PATCH 1975/4321] Improve logging for filtering pkcs15 emulators Warnings for exceeding maximum count of filtered emulators and for trying to add non-existing emulator. --- src/libopensc/pkcs15-emulator-filter.c | 10 ++++-- src/libopensc/pkcs15-emulator-filter.h | 2 +- src/libopensc/pkcs15-syn.c | 4 +-- src/tests/unittests/pkcs15-emulator-filter.c | 34 ++++++++++---------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/libopensc/pkcs15-emulator-filter.c b/src/libopensc/pkcs15-emulator-filter.c index d282b20acb..eba69b7245 100644 --- a/src/libopensc/pkcs15-emulator-filter.c +++ b/src/libopensc/pkcs15-emulator-filter.c @@ -74,12 +74,14 @@ static int add_emul_list(struct _sc_pkcs15_emulators* filtered_emulators, return SC_SUCCESS; } -int set_emulators(struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, +int set_emulators(sc_context_t *ctx, struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, struct sc_pkcs15_emulator_handler* internal, struct sc_pkcs15_emulator_handler* old) { const scconf_list *item; int *cp, i, r, count; + LOG_FUNC_CALLED(ctx); + if (!filtered_emulators || !list || !internal || !old) return SC_ERROR_INVALID_ARGUMENTS; @@ -112,11 +114,15 @@ int set_emulators(struct _sc_pkcs15_emulators* filtered_emulators, const scconf_ break; } } + if (count == *cp) + sc_log(ctx, "Warning: Trying to add non-existing emulator '%s'.", item->data); } } out: if (r == SC_SUCCESS || r == SC_ERROR_TOO_MANY_OBJECTS) { filtered_emulators->list_of_handlers[*cp] = NULL; + if (r == SC_ERROR_TOO_MANY_OBJECTS) + sc_log(ctx, "Warning: Number of filtered emulators exceeded %d.", SC_MAX_PKCS15_EMULATORS); } - return r; + LOG_FUNC_RETURN(ctx, r); } diff --git a/src/libopensc/pkcs15-emulator-filter.h b/src/libopensc/pkcs15-emulator-filter.h index c943050585..29346786d2 100644 --- a/src/libopensc/pkcs15-emulator-filter.h +++ b/src/libopensc/pkcs15-emulator-filter.h @@ -24,5 +24,5 @@ struct _sc_pkcs15_emulators { int ccount; }; -int set_emulators(struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, +int set_emulators(sc_context_t *ctx, struct _sc_pkcs15_emulators* filtered_emulators, const scconf_list *list, struct sc_pkcs15_emulator_handler* builtin, struct sc_pkcs15_emulator_handler* old); diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 1f3c8b2209..c93ca7560f 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -148,12 +148,12 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid) int ret; filtered_emulators.ccount = 0; - ret = set_emulators(&filtered_emulators, list, builtin_emulators, old_emulators); + ret = set_emulators(ctx, &filtered_emulators, list, builtin_emulators, old_emulators); if (ret == SC_SUCCESS || ret == SC_ERROR_TOO_MANY_OBJECTS) { lst = filtered_emulators.list_of_handlers; if (ret == SC_ERROR_TOO_MANY_OBJECTS) - sc_log(ctx, "number of filtered emulators exceeded %d", SC_MAX_PKCS15_EMULATORS); + sc_log(ctx, "trying first %d emulators from conf file", SC_MAX_PKCS15_EMULATORS); for (i = 0; lst[i]; i++) { sc_log(ctx, "trying %s", lst[i]->name); diff --git a/src/tests/unittests/pkcs15-emulator-filter.c b/src/tests/unittests/pkcs15-emulator-filter.c index c8c6341711..531ef7dd1a 100644 --- a/src/tests/unittests/pkcs15-emulator-filter.c +++ b/src/tests/unittests/pkcs15-emulator-filter.c @@ -239,7 +239,7 @@ static void torture_non_existing(void **state) scconf_list list = { NULL, "non" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list, builtin, old); assert_int_equal(rv, SC_SUCCESS); assert_null(filtered_emulators.list_of_handlers[0]); } @@ -251,7 +251,7 @@ static void torture_internal_only(void **state) scconf_list list = { NULL, "internal" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list, builtin, old); assert_int_equal(rv, SC_SUCCESS); for (i = 0; builtin[i].name; i++) { assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); @@ -268,7 +268,7 @@ static void torture_old_only(void **state) scconf_list list = { NULL, "old" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list, builtin, old); assert_int_equal(rv, SC_SUCCESS); for (i = 0; old[i].name; i++) { assert_ptr_equal(&old[i], filtered_emulators.list_of_handlers[i]); @@ -284,7 +284,7 @@ static void torture_internal_name(void **state) scconf_list list = { NULL, strdup(builtin[0].name) }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list, builtin, old); assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(&builtin[0], filtered_emulators.list_of_handlers[0]); assert_null(filtered_emulators.list_of_handlers[1]); @@ -297,7 +297,7 @@ static void torture_old_name(void **state) scconf_list list = { NULL, strdup(old[0].name) }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list, builtin, old); assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(&old[0], filtered_emulators.list_of_handlers[0]); assert_null(filtered_emulators.list_of_handlers[1]); @@ -311,7 +311,7 @@ static void torture_internal_and_name(void **state) scconf_list list1 = { &list2, "internal" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_SUCCESS); for (i = 0; builtin[i].name; i++) { assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); @@ -328,7 +328,7 @@ static void torture_name_and_internal(void **state) scconf_list list1 = { &list2, "starcert" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(&builtin[1], filtered_emulators.list_of_handlers[0]); assert_ptr_equal(&builtin[0], filtered_emulators.list_of_handlers[1]); @@ -343,7 +343,7 @@ static void torture_internal_and_nonexisting(void **state) scconf_list list1 = { &list2, "internal" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_SUCCESS); for (i = 0; builtin[i].name; i++) { assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); @@ -360,7 +360,7 @@ static void torture_nonexisting_and_internal(void **state) scconf_list list1 = { &list2, "non" }; filtered_emulators.ccount = 0; - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_SUCCESS); for (i = 0; builtin[i].name; i++) { assert_ptr_equal(&builtin[i], filtered_emulators.list_of_handlers[i]); @@ -375,13 +375,13 @@ static void torture_null_set_emul(void **state) int rv; scconf_list list1 = { NULL, "internal" }; - rv = set_emulators(NULL, &list1, builtin, old); + rv = set_emulators(NULL, NULL, &list1, builtin, old); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); - rv = set_emulators(&filtered_emulators, NULL, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, NULL, builtin, old); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); - rv = set_emulators(&filtered_emulators, &list1, NULL, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, NULL, old); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); - rv = set_emulators(&filtered_emulators, &list1, builtin, NULL); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, NULL); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); } @@ -395,7 +395,7 @@ static void torture_full_set_emul(void **state) filtered_emulators.list_of_handlers[i] = &builtin[0]; } - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); assert_non_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1]); assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); @@ -412,7 +412,7 @@ static void torture_one_to_full_set_emul(void **state) filtered_emulators.list_of_handlers[i] = &builtin[0]; } - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[0]); assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); @@ -429,7 +429,7 @@ static void torture_one_to_full2_set_emul(void **state) filtered_emulators.list_of_handlers[i] = &builtin[0]; } - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[1]); assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); @@ -446,7 +446,7 @@ static void torture_overfilled_set_emul(void **state) filtered_emulators.list_of_handlers[i] = &builtin[0]; } - rv = set_emulators(&filtered_emulators, &list1, builtin, old); + rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); } From 3c5cd24d183f915966d8e7735ed2cefe8aee932a Mon Sep 17 00:00:00 2001 From: Per Nilsson Date: Fri, 9 Apr 2021 10:11:07 +0200 Subject: [PATCH 1976/4321] Use LoadLibrarEx with LOAD_WITH_ALTERED_SEARCH_PATH for absolute paths --- src/common/libscdl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/libscdl.c b/src/common/libscdl.c index bc1d6b877a..24298f6ca7 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -26,9 +26,11 @@ #ifdef _WIN32 #include +#include void *sc_dlopen(const char *filename) { - return (void *)LoadLibraryA(filename); + DWORD flags = PathIsRelativeA(filename) ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH; + return (void *)LoadLibraryExA(filename, NULL, flags); } void *sc_dlsym(void *handle, const char *symbol) From df0fd52e8667b9fed2642198571b5dd791ebe3aa Mon Sep 17 00:00:00 2001 From: Per Nilsson Date: Fri, 9 Apr 2021 11:12:16 +0200 Subject: [PATCH 1977/4321] Link with shlwapi --- src/common/libscdl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 24298f6ca7..443e55a797 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -27,6 +27,7 @@ #ifdef _WIN32 #include #include +#pragma comment(lib, "shlwapi") void *sc_dlopen(const char *filename) { DWORD flags = PathIsRelativeA(filename) ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH; From 25668451389d48bbf075369ada43a2f8ba64e3e5 Mon Sep 17 00:00:00 2001 From: Per Nilsson Date: Tue, 22 Jun 2021 14:18:54 +0200 Subject: [PATCH 1978/4321] Add shlwapi.lib to makefile instead --- src/common/libscdl.c | 2 +- src/libopensc/Makefile.mak | 2 +- src/minidriver/Makefile.mak | 2 +- src/pkcs11/Makefile.mak | 6 +++--- src/smm/Makefile.mak | 2 +- src/tools/Makefile.mak | 16 ++++++++-------- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 443e55a797..81feab3309 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -27,7 +27,7 @@ #ifdef _WIN32 #include #include -#pragma comment(lib, "shlwapi") + void *sc_dlopen(const char *filename) { DWORD flags = PathIsRelativeA(filename) ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH; diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 2689724532..b9bfc70f21 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -57,7 +57,7 @@ opensc.dll: $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type lib$*.exports >> $*.def - link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib + link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib shlwapi.lib if EXIST opensc.dll.manifest mt -manifest opensc.dll.manifest -outputresource:opensc.dll;2 opensc_a.lib: $(OBJECTS) diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index a2ef5b5d49..abde6e20ea 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -20,5 +20,5 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib /DELAYLOAD:bcrypt.dll + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib shlwapi.lib /DELAYLOAD:bcrypt.dll if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index a420fa2aae..753c8004ca 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -26,15 +26,15 @@ all: $(TARGET1) $(TARGET2) $(TARGET3) !INCLUDE $(TOPDIR)\win32\Make.rules.mak $(TARGET1): $(OBJECTS) $(LIBS) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib if EXIST $(TARGET1).manifest mt -manifest $(TARGET1).manifest -outputresource:$(TARGET1);2 $(TARGET2): $(OBJECTS) $(LIBS) del pkcs11-global.obj cl $(CODE_OPTIMIZATION) $(COPTS) /DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" /c pkcs11-global.c - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib if EXIST $(TARGET2).manifest mt -manifest $(TARGET2).manifest -outputresource:$(TARGET2);2 $(TARGET3): $(OBJECTS3) $(LIBS3) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib + link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib if EXIST $(TARGET3).manifest mt -manifest $(TARGET3).manifest -outputresource:$(TARGET3);2 diff --git a/src/smm/Makefile.mak b/src/smm/Makefile.mak index a0dbbdc647..b8cc25319c 100644 --- a/src/smm/Makefile.mak +++ b/src/smm/Makefile.mak @@ -24,7 +24,7 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type $*.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib shlwapi.lib if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 !ELSE diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 38e5ba4e7e..b016b126bc 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -24,40 +24,40 @@ $(TARGETS): $(OBJECTS) $(LIBS) opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 egk-tool.exe: egk-tool-cmdline.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(OBJECTS) $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(OBJECTS) $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 goid-tool.exe: goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 pkcs11-register.exe: pkcs11-register-cmdline.obj fread_to_eof.obj $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 pkcs15-tool.exe: pkcs15-tool.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 From 29d3b69e0538dea61be04f5ae25e76361c121bf6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 08:44:15 +0200 Subject: [PATCH 1979/4321] github actions: Improve PIV testing Current test using PivApplet/bin/:jcardsim/target/jcardsim-3.0.5 only creates 2 private keys. These are never seen by a PIV client, as the way private keys are found is via a certificate which contains the public key (SPKI) which contains the type of key, RSA or ECC and the size or curve OID. This change creates the public key and self signed certificate for the two keys so pkcs11-tool can list and test the crypto. Based on a change from Doug Engert in https://github.com/OpenSC/OpenSC/pull/2053 Broken into separate steps to prevent concurrency issue in yubico-piv-tool and make potential debugging easier --- .github/test-piv.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 0e7a37cdd9..dc05c5928b 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -37,8 +37,16 @@ PID=$! sleep 5 opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f opensc-tool -n -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048 -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256 + +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048 | tee 9e.pub +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify -aselfsign < 9e.pub | tee 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -aimport-certificate <9e.cert + +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256 | tee 9a.pub +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -aimport-certificate < 9e.cert + +pkcs11-tool -l -O -p 123456 pkcs11-tool -l -t -p 123456 kill -9 $PID From 60cd9355d30ba673451374517e5b91ce9464acb2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 16:26:36 +0200 Subject: [PATCH 1980/4321] github actions: Add ix86 compilation target to catch 32bit issues --- .github/build.sh | 4 ++++ .github/setup-linux.sh | 11 ++++++++++- .github/workflows/linux.yml | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/build.sh b/.github/build.sh index 96c6ae29bc..8f1e182513 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -37,6 +37,10 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then make -j 2 # no point in running tests on mingw else + if [ "$1" == "ix86" ]; then + export CFLAGS="-m32" + export LDFLAGS="-m32" + fi # normal procedure ./configure --disable-dependency-tracking make -j 2 diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 2028db1e85..8a173e4172 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -2,7 +2,16 @@ set -ex -o xtrace -DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git" +# Generic dependencies +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake pkg-config openssl git" + +# 64bit or 32bit dependencies +if [ "$1" == "ix86" ]; then + sudo dpkg --add-architecture i386 + DEPS="$DEPS gcc-multilib zlib1g-dev:i386 libssl-dev:i386 libcmocka-dev:i386 libreadline-dev:i386 libpcsclite-dev:i386" +else + DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev" +fi if [ "$1" == "clang-tidy" ]; then DEPS="$DEPS clang-tidy" diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index cc4588f4d9..8c40bf5e02 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -27,6 +27,13 @@ jobs: path: opensc*.tar.gz + build-ix86: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh ix86 + - run: .github/build.sh ix86 + build-ubuntu-18: runs-on: ubuntu-18.04 steps: From 73d4760ce0068200ed3ffcfba150ca60c4b864ef Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 17:58:00 +0200 Subject: [PATCH 1981/4321] github actions: Install 32b softhsm --- .github/build.sh | 5 ++++- .github/setup-linux.sh | 6 +++--- tests/common.sh | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 8f1e182513..cf0f8f8b3b 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -44,7 +44,10 @@ else # normal procedure ./configure --disable-dependency-tracking make -j 2 - make check + # 32b build has some issues to find openssl correctly + if [ "$1" != "ix86" ]; then + make check + fi fi # this is broken in old ubuntu diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 8a173e4172..ad57bc5b45 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -3,14 +3,14 @@ set -ex -o xtrace # Generic dependencies -DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake pkg-config openssl git" +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config openssl git" # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then sudo dpkg --add-architecture i386 - DEPS="$DEPS gcc-multilib zlib1g-dev:i386 libssl-dev:i386 libcmocka-dev:i386 libreadline-dev:i386 libpcsclite-dev:i386" + DEPS="$DEPS gcc-multilib libpcsclite-dev:i386 libcmocka-dev:i386 libssl-dev:i386 zlib1g-dev:i386 libreadline-dev:i386 softhsm2:i386" else - DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev" + DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2" fi if [ "$1" == "clang-tidy" ]; then diff --git a/tests/common.sh b/tests/common.sh index 89e2be29a6..9466c8fd6d 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -8,6 +8,7 @@ PKCS11_TOOL="$BUILD_PATH/src/tools/pkcs11-tool" softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ /usr/lib/softhsm/libsofthsm2.so /usr/lib64/pkcs11/libsofthsm2.so \ + /usr/lib/i386-linux-gnu/softhsm/libsofthsm2.so \ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" for LIB in $softhsm_paths; do From 4e5552fb3bab80f6ca7356fdc14a63574c627416 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 19 Aug 2021 11:42:43 +0200 Subject: [PATCH 1982/4321] .github: Share code handling pcscd restarts and cleanup --- .github/restart-pcscd.sh | 16 ++++++++++++++++ .github/test-cac.sh | 3 ++- .github/test-gidsapplet.sh | 11 +++-------- .github/test-isoapplet.sh | 11 ++++------- .github/test-openpgp.sh | 11 +++-------- .github/test-piv.sh | 10 ++-------- 6 files changed, 30 insertions(+), 32 deletions(-) create mode 100644 .github/restart-pcscd.sh diff --git a/.github/restart-pcscd.sh b/.github/restart-pcscd.sh new file mode 100644 index 0000000000..53a13ba4c8 --- /dev/null +++ b/.github/restart-pcscd.sh @@ -0,0 +1,16 @@ +#!/bin/bash -e + +# This file is made to be sourced into other test scripts and not executed +# manually because it sets trap to restore pcscd to working state + +function pcscd_cleanup { + sudo pkill pcscd + sudo systemctl start pcscd.socket +} + +# register cleanup handler +trap pcscd_cleanup EXIT + +# stop the pcscd service and run it from console to see possible errors +sudo systemctl stop pcscd.service pcscd.socket +sudo /usr/sbin/pcscd -f & diff --git a/.github/test-cac.sh b/.github/test-cac.sh index b55006322d..f3b53aee49 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -25,7 +25,8 @@ pushd virt_cacard ./autogen.sh && ./configure && make popd -sudo /etc/init.d/pcscd restart +# prepare pcscd +. .github/restart-pcscd.sh pushd src/tests/p11test/ ./p11test -s 0 -p 12345678 -i -o virt_cacard.json & diff --git a/.github/test-gidsapplet.sh b/.github/test-gidsapplet.sh index ca546180ca..baa60b8083 100755 --- a/.github/test-gidsapplet.sh +++ b/.github/test-gidsapplet.sh @@ -18,10 +18,9 @@ echo "com.licel.jcardsim.card.ATR=3B80800101" >> gids_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.host=localhost" >> gids_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg; -# log errors from pcscd to console -sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f & -PCSCD_PID=$! + +# prepare pcscd +. .github/restart-pcscd.sh # start the applet and run couple of commands against that @@ -32,7 +31,3 @@ opensc-tool --card-driver default --send-apdu 80b80000190bA000000397425446590201 opensc-tool -n; gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; kill -9 $PID - - -# cleanup -sudo kill -9 $PCSCD_PID diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 212ea6e74e..2ba4014605 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -18,10 +18,10 @@ echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; -# log errors from pcscd to console -sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f & -PCSCD_PID=$! + +# prepare pcscd +. .github/restart-pcscd.sh + # start the applet and run couple of commands against that java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & @@ -38,6 +38,3 @@ pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-i pkcs15-tool -D; pkcs11-tool -l -t -p 123456; kill -9 $PID; - -# cleanup -sudo kill -9 $PCSCD_PID diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh index c017104518..9264523faa 100755 --- a/.github/test-openpgp.sh +++ b/.github/test-openpgp.sh @@ -20,10 +20,9 @@ echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.host=localhost" >> openpgp_jcardsim.cfg; echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg; -# log errors from pcscd to console -sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f & -PCSCD_PID=$! + +# prepare pcscd +. .github/restart-pcscd.sh # start the applet and run couple of commands against that @@ -36,7 +35,3 @@ openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; pkcs11-tool -l -t -p 123456; kill -9 $PID - - -# cleanup -sudo kill -9 $PCSCD_PID diff --git a/.github/test-piv.sh b/.github/test-piv.sh index dc05c5928b..2cc9ff9719 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -25,10 +25,8 @@ popd popd -# log errors from pcscd to console -sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f & -PCSCD_PID=$! +# prepare pcscd +. .github/restart-pcscd.sh # start the applet and run couple of commands against that @@ -49,7 +47,3 @@ yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -aimport-certific pkcs11-tool -l -O -p 123456 pkcs11-tool -l -t -p 123456 kill -9 $PID - - -# cleanup -sudo kill -9 $PCSCD_PID From 5888a2703c5e87d945db2a9e7a592bc59a1c3e86 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 19 Aug 2021 11:58:23 +0200 Subject: [PATCH 1983/4321] .github: Try to wait for pcscd up to 30 seconds --- .github/restart-pcscd.sh | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/restart-pcscd.sh b/.github/restart-pcscd.sh index 53a13ba4c8..569d7c8019 100644 --- a/.github/restart-pcscd.sh +++ b/.github/restart-pcscd.sh @@ -3,14 +3,31 @@ # This file is made to be sourced into other test scripts and not executed # manually because it sets trap to restore pcscd to working state +# register cleanup handler function pcscd_cleanup { + echo "Process terminated: resetting pcscd" sudo pkill pcscd sudo systemctl start pcscd.socket } - -# register cleanup handler trap pcscd_cleanup EXIT + # stop the pcscd service and run it from console to see possible errors sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f & +sudo /usr/sbin/pcscd -f | sed -e 's/^/pcscd: /;' & + + +# Try to wait up to 30 seconds for pcscd to come up and create PID file +for ((i=1;i<=30;i++)); do + echo "Waiting for pcscd to start: $i s" + if [ -f "/var/run/pcscd/pcscd.pid" ]; then + break + fi + sleep 1 +done + + +# if it did not come up, warn, but continue +if [ ! -f "/var/run/pcscd/pcscd.pid" ]; then + echo "WARNING: The pcscd pid file does not exist ... trying anyway" +fi From defc0c8320082d171b07b81432eb6b9c2ec9e933 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 19 Aug 2021 12:10:03 +0200 Subject: [PATCH 1984/4321] .github: Fix directory structure --- .github/test-openpgp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh index 9264523faa..d1b3ab0217 100755 --- a/.github/test-openpgp.sh +++ b/.github/test-openpgp.sh @@ -11,9 +11,9 @@ export LD_LIBRARY_PATH=/usr/local/lib # The OpenPGP applet git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; -cd ykneo-openpgp; +pushd ykneo-openpgp; ant -DJAVACARD_HOME=${JC_HOME}; -cd $TRAVIS_BUILD_DIR; +popd echo "com.licel.jcardsim.card.applet.0.AID=D2760001240102000000000000010000" > openpgp_jcardsim.cfg; echo "com.licel.jcardsim.card.applet.0.Class=openpgpcard.OpenPGPApplet" >> openpgp_jcardsim.cfg; echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg; From 54392313321bc236d6502787a990b148121e51b7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 17:25:38 +0200 Subject: [PATCH 1985/4321] tests: Simplify CAC setup to prevent hangs --- .github/test-cac.sh | 23 ++++++++++------------- src/tests/p11test/virt_cacard_ref.json | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/test-cac.sh b/.github/test-cac.sh index f3b53aee49..ee30039b30 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -17,29 +17,26 @@ pushd libcacard ./autogen.sh --prefix=/usr && make -j2 && sudo make install popd +# prepare pcscd +. .github/restart-pcscd.sh + # virt_cacard if [ ! -d "virt_cacard" ]; then git clone https://github.com/Jakuje/virt_cacard.git fi pushd virt_cacard ./autogen.sh && ./configure && make +./setup-softhsm2.sh +export SOFTHSM2_CONF=$PWD/softhsm2.conf +# register cleanup function on exit +trap "pkill -9 virt_cacard" EXIT +./virt_cacard 2>&1 | sed -e 's/^/virt_cacard: /;' & popd -# prepare pcscd -. .github/restart-pcscd.sh - +# run the tests pushd src/tests/p11test/ -./p11test -s 0 -p 12345678 -i -o virt_cacard.json & sleep 5 -popd - -# virt_cacard startup -pushd virt_cacard -./setup-softhsm2.sh -export SOFTHSM2_CONF=$PWD/softhsm2.conf -./virt_cacard & -wait $(ps aux | grep '[p]11test'| awk '{print $2}') -kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') +./p11test -s 0 -p 12345678 -o virt_cacard.json popd # cleanup -- this would break later uses of pcscd diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index 6c6912d2b1..ee451eaf07 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -3,7 +3,7 @@ "results": [ { "test_id": "wait_test", - "result": "pass" + "result": "skip" }, { "test_id": "supported_mechanisms_test", From 93eeb603a4e99dfcc2b9937862a5a1d1f00f78be Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 17:26:32 +0200 Subject: [PATCH 1986/4321] tests: Avoid calling systemctl comands when the systemd is not handling the system (for example in containers) --- .github/restart-pcscd.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/restart-pcscd.sh b/.github/restart-pcscd.sh index 569d7c8019..eaa2dab56d 100644 --- a/.github/restart-pcscd.sh +++ b/.github/restart-pcscd.sh @@ -7,14 +7,20 @@ function pcscd_cleanup { echo "Process terminated: resetting pcscd" sudo pkill pcscd - sudo systemctl start pcscd.socket + if which systemctl; then + sudo systemctl start pcscd.socket + fi } trap pcscd_cleanup EXIT # stop the pcscd service and run it from console to see possible errors -sudo systemctl stop pcscd.service pcscd.socket -sudo /usr/sbin/pcscd -f | sed -e 's/^/pcscd: /;' & +if which systemctl; then + sudo systemctl stop pcscd.service pcscd.socket +else + sudo pkill pcscd || echo "no pcscd process was running" +fi +sudo /usr/sbin/pcscd -f 2>&1 | sed -e 's/^/pcscd: /;' & # Try to wait up to 30 seconds for pcscd to come up and create PID file From 1e7c36a5c9347d3a1eaac8afb0f11cafc8c21d2f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 20:05:49 +0200 Subject: [PATCH 1987/4321] .github: Add missing dependency --- .github/setup-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index ad57bc5b45..9fec49134d 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -23,7 +23,7 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " if [ "$1" == "piv" ]; then DEPS="$DEPS cmake" fi - DEPS="$DEPS ant openjdk-8-jdk" + DEPS="$DEPS ant openjdk-8-jdk maven" elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then DEPS="$DEPS wine wine32 xvfb wget" sudo dpkg --add-architecture i386 From 646b1d0baedf9af456278905f5e18ab8bb05ebef Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 20:06:05 +0200 Subject: [PATCH 1988/4321] .github: Try harder to prevent interactive prompts --- .github/setup-linux.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 9fec49134d..481aa07119 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -36,6 +36,7 @@ fi # make sure we do not get prompts export DEBIAN_FRONTEND=noninteractive +export DEBCONF_NONINTERACTIVE_SEEN=true sudo apt-get update sudo apt-get install -y build-essential $DEPS From bf4c83886d6eff48d1c9e2e8ef3666eabe8404f4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 20:06:51 +0200 Subject: [PATCH 1989/4321] .github: Do not fail on existing directories --- .github/setup-java.sh | 8 ++++++-- .github/test-piv.sh | 12 +++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index c801fad709..0319ad11c5 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -13,12 +13,16 @@ env | grep -i openjdk ./.github/setup-vsmartcard.sh # Javacard SDKs -git clone https://github.com/martinpaljak/oracle_javacard_sdks.git +if [ ! -d "oracle_javacard_sdks" ]; then + git clone https://github.com/martinpaljak/oracle_javacard_sdks.git +fi export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit # jCardSim -git clone https://github.com/arekinath/jcardsim.git +if [ ! -d "jcardsim" ]; then + git clone https://github.com/arekinath/jcardsim.git +fi pushd jcardsim env | grep -i openjdk export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 2cc9ff9719..9fa4eb54e9 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -10,15 +10,21 @@ export LD_LIBRARY_PATH=/usr/local/lib . .github/setup-java.sh # The PIV Applet -git clone --recursive https://github.com/arekinath/PivApplet.git +if [ ! -d "PivApplet" ]; then + git clone --recursive https://github.com/arekinath/PivApplet.git +fi pushd PivApplet JC_HOME=${JC_CLASSIC_HOME} ant dist popd # yubico-piv-tool is needed for PIV Applet management -git clone https://github.com/Yubico/yubico-piv-tool.git +if [ ! -d "yubico-piv-tool" ]; then + git clone https://github.com/Yubico/yubico-piv-tool.git +fi pushd yubico-piv-tool -mkdir build +if [ ! -d "build" ]; then + mkdir build +fi pushd build cmake .. && make && sudo make install popd From 7b39f3cac99fbc23b4640cdf8e0487f3f24f61a3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 24 Aug 2021 11:49:04 +0200 Subject: [PATCH 1990/4321] .github: Clarify comment --- .github/test-piv.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 9fa4eb54e9..c4ab409e50 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -6,7 +6,7 @@ set -ex -o xtrace sudo make install export LD_LIBRARY_PATH=/usr/local/lib -# setup java stuff +# setup java stuff and virutal smartcard . .github/setup-java.sh # The PIV Applet From a97c9077a0c28f245d9d0bbb215ba96962eb52ce Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 1 Sep 2021 11:40:33 +0200 Subject: [PATCH 1991/4321] .github: openpgp works now --- .github/workflows/linux.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 8c40bf5e02..3ec0a9e044 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -122,8 +122,7 @@ jobs: path: ./* key: ${{ runner.os }}-18-${{ github.sha }} - run: .github/setup-linux.sh openpgp - # the openpgp sometimes fails - - run: .github/test-openpgp.sh || true + - run: .github/test-openpgp.sh build-clang-tidy: runs-on: ubuntu-latest From 053420fc55cf134ca1ded687e572f755d28eaf44 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 1 Sep 2021 14:26:43 +0200 Subject: [PATCH 1992/4321] .github: Try my jcardsim fork with fix for tests https://github.com/licel/jcardsim/pull/174 --- .github/setup-java.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 0319ad11c5..6981790bb1 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -21,7 +21,7 @@ export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit # jCardSim if [ ! -d "jcardsim" ]; then - git clone https://github.com/arekinath/jcardsim.git + git clone https://github.com/Jakuje/jcardsim.git fi pushd jcardsim env | grep -i openjdk From 8fc650e71089a64f4df1c0a3a919ab53c2ec515d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 19 Aug 2021 11:43:23 +0200 Subject: [PATCH 1993/4321] Removed unused CI configurations --- .gitlab-ci.yml | 126 ---------------- .travis.yml | 386 ------------------------------------------------- 2 files changed, 512 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index d116076259..0000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,126 +0,0 @@ -before_script: - # Avoid picking up PIV endpoint in CAC cards - - sed -e "/PIV-II/d" -i src/libopensc/ctx.c - # enable debug messages in the testsuite - - sed -e "s/^p11test_CFLAGS/#p11test_CFLAGS/g" -i src/tests/p11test/Makefile.am - - ./bootstrap - - ./configure - - make -j4 - - make check - - make install - - ldconfig /usr/local/lib - - git clone https://github.com/PL4typus/virt_cacard.git - - cd virt_cacard && export CACARD_DIR=$PWD && ./autogen.sh && ./configure && make -variables: - SOFTHSM2_CONF: softhsm2.conf - CNTNR_REGISTRY: pl4typus/opensc-images - FEDORA29_BUILD: fedora-29 - FEDORA30_BUILD: fedora-30 - UBUNTU_BUILD: ubuntu-18.04 - DEBIAN_BUILD: debian-testing - -.job_base: &base_job - artifacts: - expire_in: '1 week' - when: on_failure - paths: - - src/tests/p11test/*.log - -.job_template: &functional_test - <<: *base_job - artifacts: - expire_in: '1 week' - when: on_failure - paths: - - src/tests/p11test/*.log - - src/tests/p11test/*.json - - tests/test-suite.log - cache: - paths: - - src/tests/p11test/*.json - -.virt_cacard: &virt_cacard - only: - - virt_cacard - script: - - ./setup-softhsm2.sh - - cd ../src/tests/p11test/ - - pcscd -x - - ./p11test -s 0 -p 12345678 -o cac.json -i | tee cac.log & - - sleep 5 - - cd $CACARD_DIR - - ./virt_cacard & - - cd ../src/tests/p11test/ - - wait $(ps aux | grep '[p]11test'| awk '{print $2}') - - kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') - - if [[ -f cac_old.json ]]; then diff -u3 cac_old.json cac.json; fi - - cp cac.json cac_old.json - # cache the results for the next run - tags: - - shared - -.virt_cacard_valgrind: &virt_cacard_valgrind - only: - - virt_cacard - script: - - ./setup-softhsm2.sh - - cd ../src/tests/p11test/ - # remove the dlcose() calls to have reasonable traces - - sed '/if(pkcs11_so)/I {N;d;}' -i p11test_loader.c - - make - - pcscd -x - - valgrind --leak-check=full --trace-children=yes --suppressions=p11test.supp ./p11test -s 0 -p 12345678 -i 2>&1| tee cac.log & - - sleep 5 - - cd $CACARD_DIR - - ./virt_cacard & - - wait $(ps aux | grep '[v]algrind'| awk '{print $2}') - - kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}') - - cd ../src/tests/p11test/ - - grep "definitely lost:.*0 bytes in 0 blocks" cac.log - tags: - - shared - -################################ -## Virtual CACard ## -################################ - -Fedora29 Build and Test virt_cacard: - <<: *functional_test - image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA29_BUILD:latest - <<: *virt_cacard - -Fedora30 Build and Test virt_cacard: - <<: *functional_test - image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA30_BUILD:latest - <<: *virt_cacard - -Ubuntu18.04 Build and Test virt_cacard: - <<: *functional_test - image: $CI_REGISTRY/$CNTNR_REGISTRY/$UBUNTU_BUILD:latest - <<: *virt_cacard - -Debian-testing Build and Test virt_cacard: - <<: *functional_test - image: $CI_REGISTRY/$CNTNR_REGISTRY/$DEBIAN_BUILD:latest - <<: *virt_cacard - -Fedora29 Build and Test virt_cacard with valgrind: - <<: *base_job - image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA29_BUILD:latest - <<: *virt_cacard_valgrind - -Fedora30 Build and Test virt_cacard with valgrind: - <<: *base_job - image: $CI_REGISTRY/$CNTNR_REGISTRY/$FEDORA30_BUILD:latest - <<: *virt_cacard_valgrind - -Ubuntu18.04 Build and Test virt_cacard with valgrind: - <<: *base_job - image: $CI_REGISTRY/$CNTNR_REGISTRY/$UBUNTU_BUILD:latest - <<: *virt_cacard_valgrind - -Debian-testing Build and Test virt_cacard with valgrind: - <<: *base_job - image: $CI_REGISTRY/$CNTNR_REGISTRY/$DEBIAN_BUILD:latest - <<: *virt_cacard_valgrind - diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 819d0aadd5..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,386 +0,0 @@ -language: c - -matrix: - include: - - compiler: clang - os: osx - osx_image: xcode9.4 - env: DO_PUSH_ARTIFACT=yes - - compiler: clang - os: osx - osx_image: xcode12.2 - env: DO_PUSH_ARTIFACT=yes - - compiler: clang - os: linux - dist: focal - - compiler: gcc - os: linux - dist: bionic - env: - - DO_SIMULATION=javacard - - ENABLE_DOC=--enable-doc - - compiler: gcc - os: linux - dist: focal - env: - - DO_SIMULATION=oseid - - env: - - HOST=x86_64-w64-mingw32 - - DO_PUSH_ARTIFACT=yes - - env: - - HOST=i686-w64-mingw32 - - DO_PUSH_ARTIFACT=yes - - env: DO_COVERITY_SCAN=yes - - compiler: gcc - os: linux - dist: bionic - env: - - DO_SIMULATION=cac - -env: - global: - # The next declaration are encrypted environment variables, created via the - # "travis encrypt" command using the project repo's public key - # COVERITY_SCAN_TOKEN - - secure: "UkHn7wy4im8V1nebCWbAetnDSOLRUbOlF6++ovk/7Bnso1/lnhXHelyzgRxfD/oI68wm9nnRV+RQEZ9+72Ug1CyvHxyyxxkwal/tPeHH4B/L+aGdPi0id+5OZSKIm77VP3m5s102sJMJgH7DFd03+nUd0K26p0tk8ad4j1geV4c=" - # GH_TOKEN - - secure: "cUAvpN/XUPMIN5cgWAbIOhghRoLXyw7SCydzGaJ1Ucqb9Ml2v5iuLLuN57YbZHTiWw03vy6rYVzzwMDrHX8r3oUALsv7ViJHG4PzIe7fAFZsZpHECmGsp6SEnue7m7BNy3FT8KYbiXxnxDO0SxmFXlrPAYR0WMZCWx2TENYcafs=" - - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity.*)" - - COVERITY_SCAN_NOTIFICATION_EMAIL="viktor.tarasov@gmail.com" - - COVERITY_SCAN_BUILD_COMMAND="make -j 4" - - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG" - - SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) - -# Commented out because of a bug in travis images for Focal: -# https://travis-ci.community/t/clang-10-was-recently-broken-on-linux-unmet-dependencies-for-clang-10-clang-tidy-10-valgrind/11527 -#addons: -# apt_packages: -# - binutils-mingw-w64-i686 -# - binutils-mingw-w64-x86-64 -# - docbook-xsl -# - gcc-mingw-w64-i686 -# - gcc-mingw-w64-x86-64 -# - libpcsclite-dev -# - mingw-w64 -# - xsltproc -# - gengetopt -# - libcmocka-dev -# - help2man -# - pcscd -# - pcsc-tools -# - check -# - ant -# - socat -# - cmake -# - clang-tidy -# - softhsm2 - -before_install: - # homebrew is dead slow in older images due to the many updates it would need to download and build. - # here, we build the additional dependencies manually to get around this - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - curl https://ftp.gnu.org/gnu/gengetopt/gengetopt-2.23.tar.xz -L --output gengetopt-2.23.tar.xz; - tar xfj gengetopt-2.23.tar.xz; - pushd gengetopt-2.23; - ./configure && make; - sudo make install; - popd; - curl https://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz -L --output help2man-1.47.16.tar.xz; - tar xjf help2man-1.47.16.tar.xz; - pushd help2man-1.47.16; - ./configure && make; - sudo make install; - popd; - export PATH="/usr/local/opt/ccache/libexec:$PATH"; - git clone https://github.com/frankmorgner/OpenSCToken.git; - sudo rm -rf /Library/Developer/CommandLineTools; - fi - - if [ "$TRAVIS_OS_NAME" = "osx" -a "$TRAVIS_PULL_REQUEST" = "false" -a -n "$encrypted_3b9f0b9d36d1_key" ]; then - openssl aes-256-cbc -K $encrypted_3b9f0b9d36d1_key -iv $encrypted_3b9f0b9d36d1_iv -in .github/secrets.tar.enc -out .github/secrets.tar -d; - .github/add_signing_key.sh; - else - unset CODE_SIGN_IDENTITY INSTALLER_SIGN_IDENTITY; - fi - - if [ "${DO_SIMULATION}" = "javacard" ]; then - sudo apt-get install -y openjdk-8-jdk; - sudo update-java-alternatives -s java-1.8.0-openjdk-amd64; - sudo update-alternatives --get-selections | grep ^java; - export PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH"; - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/; - env | grep -i openjdk; - fi - - if [ "${DO_SIMULATION}" = "cac" ]; then - sudo apt-get install -y libglib2.0-dev libnss3-dev pkgconf libtool make autoconf autoconf-archive automake libsofthsm2-dev softhsm2 softhsm2-common help2man gnutls-bin libcmocka-dev libusb-dev libudev-dev flex libnss3-tools libssl-dev libpcsclite1; - export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; - fi - - if [ -n "${HOST}" ]; then - sudo apt-get install -y wine; - fi - - if [ "$TRAVIS_DIST" == "focal" ]; then - sudo apt-get install -yq --allow-downgrades libc6=2.31-0ubuntu9.2 libc6-dev=2.31-0ubuntu9.2; - fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --allow-downgrades --allow-remove-essential --allow-change-held-packages install binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 docbook-xsl gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 libpcsclite-dev mingw-w64 xsltproc gengetopt libcmocka-dev help2man pcscd pcsc-tools check ant socat cmake clang-tidy softhsm2; - fi - -before_script: - - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then - ./bootstrap; - fi - - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then - ./bootstrap.ci -s "-pr$TRAVIS_PULL_REQUEST"; - fi - - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then - ./bootstrap.ci -s "-$TRAVIS_BRANCH"; - fi - - if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then - ./bootstrap.ci -s "-$TRAVIS_BRANCH-pr$TRAVIS_PULL_REQUEST"; - fi - - if [ -z "$HOST" ]; then - CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui; - else - if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16; - export DISPLAY=:99.0; - [ -d isetup ] || mkdir isetup; - pushd isetup; - [ -f isetup-5.5.6.exe ] || wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe; - wine isetup-5.5.6.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART; - popd; - fi; - unset CC; - unset CXX; - ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=${TRAVIS_BUILD_DIR}/win32/opensc || cat config.log; - fi - # Optionally try to upload to Coverity Scan - # On error (probably quota is exhausted), just continue - - if [ "${DO_COVERITY_SCAN}" = "yes" ]; then curl -s 'https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh' | bash || true; fi - - - if [ "${DO_SIMULATION}" = "javacard" ]; then - set -ex; - git clone https://github.com/frankmorgner/vsmartcard.git; - cd vsmartcard/virtualsmartcard; - autoreconf -vis && ./configure && sudo make install; - cd $TRAVIS_BUILD_DIR; - sudo systemctl stop pcscd.service pcscd.socket; - - git clone https://github.com/martinpaljak/oracle_javacard_sdks.git; - export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit; - export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit; - - git clone https://github.com/arekinath/jcardsim.git; - cd jcardsim; - env | grep -i openjdk; - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/; - mvn initialize && mvn clean install; - cd $TRAVIS_BUILD_DIR; - - git clone https://github.com/philipWendland/IsoApplet.git; - javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java; - echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg; - echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg; - echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; - - git clone https://github.com/vletoux/GidsApplet.git; - javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar GidsApplet/src/com/mysmartlogon/gidsApplet/*.java; - echo "com.licel.jcardsim.card.applet.0.AID=A000000397425446590201" > gids_jcardsim.cfg; - echo "com.licel.jcardsim.card.applet.0.Class=com.mysmartlogon.gidsApplet.GidsApplet" >> gids_jcardsim.cfg; - echo "com.licel.jcardsim.card.ATR=3B80800101" >> gids_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.host=localhost" >> gids_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg; - - git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; - cd ykneo-openpgp; - ant -DJAVACARD_HOME=${JC_HOME}; - cd $TRAVIS_BUILD_DIR; - echo "com.licel.jcardsim.card.applet.0.AID=D2760001240102000000000000010000" > openpgp_jcardsim.cfg; - echo "com.licel.jcardsim.card.applet.0.Class=openpgpcard.OpenPGPApplet" >> openpgp_jcardsim.cfg; - echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.host=localhost" >> openpgp_jcardsim.cfg; - echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg; - - git clone --recursive https://github.com/arekinath/PivApplet.git; - cd PivApplet; - JC_HOME=${JC_CLASSIC_HOME} ant dist; - cd $TRAVIS_BUILD_DIR; - - git clone https://github.com/Yubico/yubico-piv-tool.git; - cd yubico-piv-tool; - mkdir build; cd build; - cmake .. && make && sudo make install; - cd $TRAVIS_BUILD_DIR; - set +ex; - fi - - - if [ "${DO_SIMULATION}" = "oseid" ]; then - git clone https://github.com/popovec/oseid; - cd oseid/src/; - make -f Makefile.console; - mkdir tmp; - socat -d -d pty,link=tmp/OsEIDsim.socket,raw,echo=0 "exec:build/console/console ...,pty,raw,echo=0" & - PID=$!; - sleep 1; - echo "# OsEIDsim" > tmp/reader.conf; - echo 'FRIENDLYNAME "OsEIDsim"' >> tmp/reader.conf; - echo "DEVICENAME ${TRAVIS_BUILD_DIR}/oseid/src/tmp/OsEIDsim.socket" >> tmp/reader.conf; - echo "LIBPATH ${TRAVIS_BUILD_DIR}/oseid/src/build/console/libOsEIDsim.so.0.0.1" >> tmp/reader.conf; - echo "CHANNELID 1" >> tmp/reader.conf; - sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf; - cat /etc/reader.conf.d/reader.conf; - cd $TRAVIS_BUILD_DIR; - - sudo /etc/init.d/pcscd restart; - fi - - - if [ "${DO_SIMULATION}" = "cac" ]; then - git clone https://github.com/frankmorgner/vsmartcard.git; - cd vsmartcard/virtualsmartcard; - autoreconf -vis && ./configure && make -j4 && sudo make install; - - cd $TRAVIS_BUILD_DIR; - git clone https://gitlab.freedesktop.org/spice/libcacard.git; - cd libcacard && ./autogen.sh --prefix=/usr && make -j4 && sudo make install; - - cd $TRAVIS_BUILD_DIR; - git clone https://github.com/PL4typus/virt_cacard.git; - cd virt_cacard && ./autogen.sh && ./configure && make; - - cd $TRAVIS_BUILD_DIR; - sudo /etc/init.d/pcscd restart; - fi - -script: - - if [ "${DO_COVERITY_SCAN}" != "yes" ]; then - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then - ./MacOSX/build; - else - make -j 4; - fi; - fi - - if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" -a -z "$DO_SIMULATION" ]; then - make check && make distcheck || (cat tests/*log src/tests/unittests/*log && exit 1); - fi - - if [ ! -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then - make install; - wine "C:/Program Files (x86)/Inno Setup 5/ISCC.exe" win32/OpenSC.iss; - fi - - - if [ "${DO_SIMULATION}" = "javacard" ]; then - set -ex; - sudo make install; - export LD_LIBRARY_PATH=/usr/local/lib; - - sudo /usr/sbin/pcscd -f & - PCSCD_PID=$!; - - java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & - PID=$!; - sleep 5; - opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100; - opensc-tool -n; - pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef; - pkcs15-tool --change-pin --pin 123456 --new-pin 654321; - pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456; - pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456; - pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456; - pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456; - pkcs15-tool -D; - pkcs11-tool -l -t -p 123456; - kill -9 $PID; - - java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null & - PID=$!; - sleep 5; - opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100; - opensc-tool -n; - gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; - kill -9 $PID; - - java -noverify -cp ykneo-openpgp/applet/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard openpgp_jcardsim.cfg >/dev/null & - PID=$!; - sleep 5; - opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; - opensc-tool -n; - openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; - pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; - pkcs11-tool -l -t -p 123456; - kill -9 $PID; - - java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard PivApplet/test/jcardsim.cfg >/dev/null & - PID=$!; - sleep 5; - opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f; - opensc-tool -n; - yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048; - yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256; - pkcs11-tool -l -t -p 123456; - kill -9 $PID; - - sudo kill -9 $PCSCD_PID; - - set +ex; - fi - - - if [ "${DO_SIMULATION}" = "oseid" ]; then - set -ex; - sudo make install; - export LD_LIBRARY_PATH=/usr/local/lib; - - cd oseid/tools; - echo | ./OsEID-tool INIT; - ./OsEID-tool RSA-CREATE-KEYS; - ./OsEID-tool RSA-UPLOAD-KEYS; - ./OsEID-tool RSA-DECRYPT-TEST; - ./OsEID-tool RSA-SIGN-PKCS11-TEST; - ./OsEID-tool EC-CREATE-KEYS; - ./OsEID-tool EC-UPLOAD-KEYS; - ./OsEID-tool EC-SIGN-TEST; - ./OsEID-tool EC-SIGN-PKCS11-TEST; - ./OsEID-tool EC-ECDH-TEST; - kill -9 $PID; - - set +ex; - fi - - if [ "${DO_SIMULATION}" = "cac" ]; then - cd $TRAVIS_BUILD_DIR; - make check && sudo make install || (cat tests/*log src/tests/unittests/*log && exit 1); - export LD_LIBRARY_PATH=/usr/local/lib; - cd src/tests/p11test/; - ./p11test -s 0 -p 12345678 -i & - sleep 5; - cd $TRAVIS_BUILD_DIR/virt_cacard; - ./setup-softhsm2.sh; - export SOFTHSM2_CONF=$PWD/softhsm2.conf; - ./virt_cacard & - wait $(ps aux | grep '[p]11test'| awk '{print $2}'); - kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}'); - fi - -after_script: - # kill process started during compilation to finish the build, see - # https://github.com/moodlerooms/moodle-plugin-ci/issues/33 for details - - if [ ! -z "$HOST" ]; then - killall services.exe; - fi - - # keep in sync with appveyor.yml - - if [ "${DO_PUSH_ARTIFACT}" = "yes" -a "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_REPO_SLUG" = "OpenSC/OpenSC" ]; then - git config --global user.email "builds@travis-ci.org"; - git config --global user.name "Travis CI"; - .github/push_artifacts.sh "Travis CI build ${TRAVIS_JOB_NUMBER}"; - fi - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - .github/remove_signing_key.sh; - rm -f .github/secrets.tar; - fi - -cache: - apt: true - ccache: true - directories: - - $HOME/.m2/ - - openssl_bin - - openpace_bin - - isetup From c1be55aabf0ff9618b2230790f5e5c0bc0803eb2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 14:28:18 +0200 Subject: [PATCH 1994/4321] pkcs11-tool: Fix typo in the comment --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b78a57797e..f5dd2f048f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7549,7 +7549,7 @@ static void * test_threads_run(void * pttd) ttd->rv = rv; fprintf(stderr, "Test thread %d C_Initialize returned %s\n", ttd->tnum, CKR2Str(rv)); } - /* CL C_Initialize with CKF_OS_LOCKING_OK */ + /* IL C_Initialize with CKF_OS_LOCKING_OK */ else if (*(pctest + 1) == 'L') { fprintf(stderr, "Test thread %d C_Initialize CKF_OS_LOCKING_OK \n", ttd->tnum); rv = p11->C_Initialize(&c_initialize_args_OS); From eb34f61d144f02f1bcf02e33803b580c08fed59d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 11 Aug 2021 12:21:38 +0200 Subject: [PATCH 1995/4321] tools: Avoid maybe-uninitialized warnings from gcc11 Fixes: #2382 --- src/tools/opensc-explorer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index d251495c64..e48f3189bd 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2030,9 +2030,9 @@ static int do_put_data(int argc, char **argv) static int do_apdu(int argc, char **argv) { sc_apdu_t apdu; - u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; - size_t len, i; + size_t len = 0, i; int r; if (argc < 1) From 53aa0f65a45171806100577cf5038646a0db63f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 14:29:02 +0200 Subject: [PATCH 1996/4321] tests: Use explicit pkcs11 library in thread test Previously, the system-installed opensc was used, but there is no guarantee that it exists when running tests. Use the locally built library, even though there will probably not be any slots. Using softhsm causes a lot of failures as it looks like this is not well handled in there. --- tests/test-pkcs11-tool-test-threads.sh | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index d4c576e9a2..c2ef1a98c8 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -3,32 +3,20 @@ SOURCE_PATH=${SOURCE_PATH:-../} source $SOURCE_PATH/tests/common.sh -echo "=======================================================" -echo "Setup SoftHSM" -echo "=======================================================" -if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" - exit 77; -fi - -card_setup +# Test our PKCS #11 module here +P11LIB="../src/pkcs11/.libs/opensc-pkcs11.so" echo "=======================================================" echo "Test pkcs11 threads IN " echo "=======================================================" -$PKCS11_TOOL --test-threads IN -L +$PKCS11_TOOL --test-threads IN -L --module="$P11LIB" assert $? "Failed running tests" echo "=======================================================" echo "Test pkcs11 threads ILGISLT0 " echo "=======================================================" -$PKCS11_TOOL --test-threads ILGISLT0 -L +$PKCS11_TOOL --test-threads ILGISLT0 -L --module="$P11LIB" assert $? "Failed running tests" -echo "=======================================================" -echo "Cleanup" -echo "=======================================================" -card_cleanup - exit $ERRORS From 3127ad2431071dcd2bbdd6cf5f1faf50baa855a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Aug 2021 16:30:40 +0200 Subject: [PATCH 1997/4321] p11test: Fix invalid format string on 32b architectures --- src/tests/p11test/p11test.c | 2 +- src/tests/p11test/p11test_case_pss_oaep.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index dbac167d23..49de6a93ea 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -139,7 +139,7 @@ int main(int argc, char** argv) { return -1; } - debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %lu\n\t", + debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %zu\n\t", token.pin, token.pin_length); return cmocka_run_group_tests(readonly_tests_without_initialization, diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 1d876a5b51..5a6ae9d019 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -402,7 +402,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m if (message_length < 0) { mech->usage_flags &= ~CKF_DECRYPT; debug_print(" [SKIP %s ] Too small modulus (%ld bits)" - " or too large hash %s (%lu B) for OAEP", o->id_str, + " or too large hash %s (%zu B) for OAEP", o->id_str, o->bits, get_mechanism_name(mech->hash), get_hash_length(mech->hash)); return 0; From 8bdd7595718cf733dc9abcff11bbfcef32b65e4c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 11 Aug 2021 17:43:50 +0200 Subject: [PATCH 1998/4321] pkcs11-tool: Add SHA256 test --- src/tools/pkcs11-tool.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f5dd2f048f..a0e4a351f0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5056,17 +5056,20 @@ static int test_digest(CK_SESSION_HANDLE session) CKM_MD5, CKM_SHA_1, CKM_RIPEMD160, + CKM_SHA256, 0xffffff }; unsigned char *digests[] = { (unsigned char *) "\x7a\x08\xb0\x7e\x84\x64\x17\x03\xe5\xf2\xc8\x36\xaa\x59\xa1\x70", (unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", - (unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd" + (unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd", + (unsigned char *) "\x9c\xfe\x7f\xaf\xf7\x5\x42\x98\xca\x87\x55\x7e\x15\xa1\x2\x62\xde\x8d\x3e\xee\x77\x82\x74\x17\xfb\xdf\xea\x1c\x41\xb9\xec\x23", }; CK_ULONG digestLens[] = { 16, 20, - 20 + 20, + 32, }; rv = p11->C_GetSessionInfo(session, &sessionInfo); From 8fc822aedca2f837c072f65bc16a73deeacc13c5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 11 Aug 2021 17:44:18 +0200 Subject: [PATCH 1999/4321] pkcs11: Do not add MD5 and RIPEMD160 algorithms in FIPS mode With OpenSSL in FIPS mode, they will fail later, causing unexpected issues. --- src/pkcs11/framework-pkcs15.c | 4 ++-- src/pkcs11/openssl.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 23c05f8acf..e31acd1370 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6266,13 +6266,13 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rc != CKR_OK) return rc; } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_MD5) { + if (!FIPS_mode() && rsa_flags & SC_ALGORITHM_RSA_HASH_MD5) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_MD5_RSA_PKCS, CKM_MD5, mt); if (rc != CKR_OK) return rc; } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) { + if (!FIPS_mode() && rsa_flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); if (rc != CKR_OK) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 4c521e081a..1c8011b1d7 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -269,10 +269,12 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech)); openssl_sha512_mech.mech_data = EVP_sha512(); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech)); - openssl_md5_mech.mech_data = EVP_md5(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech)); - openssl_ripemd160_mech.mech_data = EVP_ripemd160(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech)); + if (!FIPS_mode()) { + openssl_md5_mech.mech_data = EVP_md5(); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech)); + openssl_ripemd160_mech.mech_data = EVP_ripemd160(); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech)); + } openssl_gostr3411_mech.mech_data = EVP_get_digestbynid(NID_id_GostR3411_94); sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech)); } From eb8a381cd87dd91ad5e9cf66cc709325c52ab9bb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 11 Aug 2021 19:28:30 +0200 Subject: [PATCH 2000/4321] pkcs11-tool: Skip unsupported digests in FIPS mode --- src/tools/pkcs11-tool.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a0e4a351f0..73c17c2a64 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5054,15 +5054,15 @@ static int test_digest(CK_SESSION_HANDLE session) CK_MECHANISM_TYPE mechTypes[] = { CKM_MD5, - CKM_SHA_1, CKM_RIPEMD160, + CKM_SHA_1, CKM_SHA256, 0xffffff }; unsigned char *digests[] = { (unsigned char *) "\x7a\x08\xb0\x7e\x84\x64\x17\x03\xe5\xf2\xc8\x36\xaa\x59\xa1\x70", - (unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", (unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd", + (unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", (unsigned char *) "\x9c\xfe\x7f\xaf\xf7\x5\x42\x98\xca\x87\x55\x7e\x15\xa1\x2\x62\xde\x8d\x3e\xee\x77\x82\x74\x17\xfb\xdf\xea\x1c\x41\xb9\xec\x23", }; CK_ULONG digestLens[] = { @@ -5146,8 +5146,12 @@ static int test_digest(CK_SESSION_HANDLE session) for (j = 0; j < 10; j++) data[10 * i + j] = (unsigned char) (0x30 + j); - - for (i = 0; mechTypes[i] != 0xffffff; i++) { +#ifdef ENABLE_OPENSSL + i = (FIPS_mode() ? 2 : 0); +#else + i = 0; +#endif + for (; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; rv = p11->C_DigestInit(session, &ck_mech); From 465d0d776dcec7a1ca54d017331bd7170fab0b80 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 17:25:07 +0200 Subject: [PATCH 2001/4321] pkcs11-tool: Support extractable and private flags when generating secret keys Fixes: #2393 --- src/tools/pkcs11-tool.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 73c17c2a64..abb1b16aee 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2941,6 +2941,22 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey n_attr++; } + if (opt_is_extractable != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); + n_attr++; + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_false, sizeof(_false)); + n_attr++; + } + + if (opt_is_private != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_PRIVATE, &_true, sizeof(_true)); + n_attr++; + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_PRIVATE, &_false, sizeof(_false)); + n_attr++; + } + FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); n_attr++; FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); From a6e9488cd523d1c8e5fd81a858d2e0e7e64537a7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 20:09:36 +0200 Subject: [PATCH 2002/4321] Ignore test artifacts --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 747974b1bd..12e1170e62 100644 --- a/.gitignore +++ b/.gitignore @@ -123,5 +123,6 @@ src/tests/unittests/*.trs src/tests/unittests/asn1 src/tests/unittests/compression src/tests/unittests/simpletlv +src/tests/unittests/sm version.m4.ci From 2a4a609cdec6d6bae8603e291a7f5b00de4f4242 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:17:56 +0200 Subject: [PATCH 2003/4321] sm: Avoid memory leaks on errors of OpenSSL 3.0 code --- src/sm/sm-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index d47228d879..4f9f6094a6 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -534,18 +534,21 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, #else cctx = EVP_CIPHER_CTX_new(); if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { + free(*out) EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) { + free(*out) EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len = tmplen; if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { + free(*out) EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } From de75600fd2fc955972727f8c496a6e5221fd1382 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 22:26:06 +0200 Subject: [PATCH 2004/4321] sm: Initialize tmplen --- src/sm/sm-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 4f9f6094a6..8628532882 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -313,7 +313,7 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, #else EVP_CIPHER_CTX *cctx = NULL; unsigned char outv[8]; - int tmplen; + int tmplen = 0; /* Prepare IV */ memcpy(outv, iv, sizeof outv); From 134f6dd5da58ccadde4a66087b3c257d151aec31 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:23:57 +0200 Subject: [PATCH 2005/4321] openpgp: Avoid memory leak --- src/libopensc/card-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 4fb8a9958a..e986226669 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2315,6 +2315,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, */ /* fall through */ default: + free(temp); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } From e8c07dc2b31e735d984131cfca7199aedb750da5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:26:09 +0200 Subject: [PATCH 2006/4321] p11test: Fix copy&paste error --- src/tests/p11test/p11test_case_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 295a8e23a7..c0ab4a4cec 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -164,7 +164,7 @@ add_supported_mechs(test_cert_t *o) } else if (o->type == EVP_PKEY_X25519) { if (token.num_montgomery_mechs > 0 ) { o->num_mechs = token.num_montgomery_mechs; - for (i = 0; i < token.num_ed_mechs; i++) { + for (i = 0; i < token.num_montgomery_mechs; i++) { o->mechs[i].mech = token.montgomery_mechs[i].mech; o->mechs[i].result_flags = 0; o->mechs[i].usage_flags = From c486755f558978bf13cb9e9106da20902bafe711 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:30:26 +0200 Subject: [PATCH 2007/4321] idprime: Avoid uninitialized key_reference on unknown card versions --- src/libopensc/card-idprime.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 68d963ec06..1b7c00b3d4 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -211,6 +211,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.key_reference = 0xF7 + key_id; break; case SC_CARD_TYPE_IDPRIME_V4: + default: new_object.key_reference = 0x56 + key_id; break; } From 6556e25c1522f3d542f07072164e8476590df342 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:34:44 +0200 Subject: [PATCH 2008/4321] pkcs11-spy: Avoid NULL pointer dereference --- src/pkcs11/pkcs11-spy.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 940bd058d7..1da2069eae 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -1636,7 +1636,11 @@ C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, if (po->version.major < 3) { fprintf(spy_output, "[compat]\n"); } - spy_dump_string_in("pInterfaceName", pInterfaceName, strlen((char *)pInterfaceName)); + if (pInterfaceName != NULL) { + spy_dump_string_in("pInterfaceName", pInterfaceName, strlen((char *)pInterfaceName)); + } else { + fprintf(spy_output, "[in] pInterfaceName = NULL\n"); + } if (pVersion != NULL) { fprintf(spy_output, "[in] pVersion = %d.%d\n", pVersion->major, pVersion->minor); } else { From dc9a152aa855c4dd5e6786ea36463bd24e1fe761 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 21:36:48 +0200 Subject: [PATCH 2009/4321] libopensc: Avoid NULL pointer dereference with wrong arguments --- src/libopensc/sec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index c7fae266ae..49913c6fe5 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -37,7 +37,10 @@ int sc_decipher(sc_card_t *card, { int r; - if (card == NULL || crgram == NULL || out == NULL) { + if (card == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + if (crgram == NULL || out == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } LOG_FUNC_CALLED(card->ctx); From 3983eb55a69d67ba07aa9b11d1ee9ee98ea57235 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 22:08:03 +0200 Subject: [PATCH 2010/4321] pkcs11-tool: Avoid referencing variable in a structure that goes out of scope --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index abb1b16aee..0c8f2197b3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2518,6 +2518,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, {CKA_PRIVATE, &_true, sizeof(_true)}, {CKA_SENSITIVE, &_true, sizeof(_true)}, }; + unsigned long int gost_key_type = -1; int n_privkey_attr = 4; unsigned char *ecparams = NULL; size_t ecparams_size; @@ -2653,7 +2654,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, const struct sc_aid GOST2012_512_PARAMSET_C_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x03 }, 11 }; struct sc_aid key_paramset_encoded_oid; struct sc_aid hash_paramset_encoded_oid; - unsigned long int gost_key_type = -1; CK_MECHANISM_TYPE mtypes[] = {-1}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); const char *p_param_set = type + strlen("GOSTR3410"); From 5f9d04acd0c5830cfe4908d40444e4540eee6df4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 22:19:12 +0200 Subject: [PATCH 2011/4321] p11test: Avoid double free on error --- src/tests/p11test/p11test_case_readonly.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 60ad04078f..c4e4ae3b6e 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -68,6 +68,7 @@ int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message *enc_message, o->key.rsa, padding); if (rv < 0) { free(*enc_message); + *enc_message = NULL; debug_print("RSA_public_encrypt: rv = 0x%.8X\n", rv); return -1; } From 2495e90d752aadc56efca2da299626b9cf150133 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 22:19:28 +0200 Subject: [PATCH 2012/4321] tests: Avoid memory leak from tests --- src/tests/unittests/asn1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/unittests/asn1.c b/src/tests/unittests/asn1.c index 799722ccaa..f6c3744843 100644 --- a/src/tests/unittests/asn1.c +++ b/src/tests/unittests/asn1.c @@ -587,6 +587,7 @@ static void torture_asn1_encode_simple(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(outlen, sizeof(expected)); assert_memory_equal(expected, outptr, sizeof(expected)); + free(outptr); /* Context is not needed */ rv = sc_asn1_encode(NULL, asn1, &outptr, &outlen); From 1a8c5beef12f80be473283513de2d9ba67c98bee Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 22:22:38 +0200 Subject: [PATCH 2013/4321] p11test: Avoid memory leak on error --- src/tests/p11test/p11test_case_ec_derive.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 070ed6fb1d..4a5c85431e 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -186,6 +186,7 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) rc = EVP_PKEY_get_raw_public_key(pkey, pub, &pub_len); if (rc != 1) { debug_print(" [ KEY %s ] EVP_PKEY_get_raw_public_key failed", o->id_str); + free(pub); EVP_PKEY_free(pkey); free(secret); return 1; @@ -196,6 +197,7 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) if (secret_len == pkcs11_secret_len && memcmp(secret, pkcs11_secret, secret_len) == 0) { mech->result_flags |= FLAGS_DERIVE; debug_print(" [ OK %s ] Derived secrets match", o->id_str); + free(pub); EVP_PKEY_free(pkey); free(secret); free(pkcs11_secret); From e963651c59b1ea7ae01408c4e7e763c2feaf3a50 Mon Sep 17 00:00:00 2001 From: Mladen Milinkovic Date: Sun, 9 May 2021 22:23:21 +0200 Subject: [PATCH 2014/4321] idprime: idprime_process_index() will read objects bigger than 256 bytes --- src/libopensc/card-idprime.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 1b7c00b3d4..7d0adae968 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -168,18 +168,22 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, goto done; } - r = iso_ops->read_binary(card, 0, buf, length, 0); - if (r < 1) { - r = SC_ERROR_WRONG_LENGTH; - goto done; - } + r = 0; + do { + if (length == r) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0); + if (got < 1) { + r = SC_ERROR_WRONG_LENGTH; + goto done; + } + /* First byte shows the number of entries, each of them 21 bytes long */ + num_entries = buf[0]; + r += got; + } while(r < num_entries * 21 + 1); - /* First byte shows the number of entries, each of them 21 bytes long */ - num_entries = buf[0]; - if (r < num_entries*21 + 1) { - r = SC_ERROR_INVALID_DATA; - goto done; - } new_object.fd = 0; for (i = 0; i < num_entries; i++) { u8 *start = &buf[i*21+1]; From 08ab1b747cceb1f46730481cced3141dc7018bc5 Mon Sep 17 00:00:00 2001 From: Mladen Milinkovic Date: Tue, 11 May 2021 12:21:57 +0200 Subject: [PATCH 2015/4321] idprime: implement get_challenge and flag RNG support --- src/libopensc/card-idprime.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 7d0adae968..c20f82f11a 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -339,6 +339,8 @@ static int idprime_init(sc_card_t *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + card->caps |= SC_CARD_CAP_RNG; + LOG_FUNC_RETURN(card->ctx, 0); } @@ -818,6 +820,38 @@ idprime_decipher(struct sc_card *card, LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } +static int +idprime_get_challenge(struct sc_card *card, u8 *rnd, size_t len) +{ + u8 rbuf[16]; + size_t out_len; + struct sc_apdu apdu; + int r; + + LOG_FUNC_CALLED(card->ctx); + + if (len <= 8) { + /* official closed driver always calls this regardless the length */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x01); + apdu.le = apdu.resplen = 8; + } else { + /* this was discovered accidentally - all 16 bytes seem random */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00); + apdu.le = apdu.resplen = 16; + } + apdu.resp = rbuf; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed"); + + out_len = len < apdu.resplen ? len : apdu.resplen; + memcpy(rnd, rbuf, out_len); + + LOG_FUNC_RETURN(card->ctx, (int) out_len); +} static struct sc_card_driver * sc_get_driver(void) { @@ -837,6 +871,8 @@ static struct sc_card_driver * sc_get_driver(void) idprime_ops.compute_signature = idprime_compute_signature; idprime_ops.decipher = idprime_decipher; + idprime_ops.get_challenge = idprime_get_challenge; + return &idprime_drv; } From 683cbe004ce6469839e33f225d1f0b0b04f7c538 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Jun 2021 11:00:17 +0200 Subject: [PATCH 2016/4321] Detect hotplug events for both reader and card The tools util_connect_reader() with wait option worked only for readers inserted without the card and then the code would wait for separate card insert event. This is not always handy as USB tokens are getting more common and there is no distinction between reader and card (and no possibility to remove the card from reader. The code is adjusted in pscs driver to emit both reader & card events in case the card is present in the hotplug reader and this is handled in the tools. --- src/libopensc/reader-pcsc.c | 4 ++++ src/tools/util.c | 21 +++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 13f3882420..052f668592 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1801,6 +1801,10 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re /* no other event has been detected, yet */ *event_reader = gpriv->attached_reader; *event = SC_EVENT_READER_ATTACHED; + /* If the card is present in the reader, report also this event */ + if (gpriv->attached_reader->flags & SC_READER_CARD_PRESENT) { + *event |= SC_EVENT_CARD_INSERTED; + } r = SC_SUCCESS; } gpriv->attached_reader = NULL; diff --git a/src/tools/util.c b/src/tools/util.c index ade86fb173..bf37597c08 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -65,11 +65,12 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, } if (do_wait) { - unsigned int event; + unsigned int event = 0; if (sc_ctx_get_reader_count(ctx) == 0) { fprintf(stderr, "Waiting for a reader to be attached...\n"); - r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED, &found, &event, -1, NULL); + r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED|SC_EVENT_CARD_INSERTED, + &found, &event, -1, NULL); if (r < 0) { fprintf(stderr, "Error while waiting for a reader: %s\n", sc_strerror(r)); return r; @@ -80,13 +81,17 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, return r; } } - fprintf(stderr, "Waiting for a card to be inserted...\n"); - r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1, NULL); - if (r < 0) { - fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r)); - return r; + if (event & SC_EVENT_CARD_INSERTED) { + *reader = found; + } else { + fprintf(stderr, "Waiting for a card to be inserted...\n"); + r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1, NULL); + if (r < 0) { + fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r)); + return r; + } + *reader = found; } - *reader = found; } else if (sc_ctx_get_reader_count(ctx) == 0) { fprintf(stderr, "No smart card readers found.\n"); From 097acbc72b538911a2da30d50817edbfdd4c56f7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 27 Aug 2021 10:03:33 +0200 Subject: [PATCH 2017/4321] p11test: Add missing switch to the usage --- src/tests/p11test/p11test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 49de6a93ea..8c621e9f48 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -49,6 +49,7 @@ void display_usage() { " -s slot_id Slot ID with the card\n" " -i Wait for the card before running the test (interactive)\n" " -o File to write a log in JSON\n" + " -v Verbose log output\n" " -h This help\n" "\n"); } From dbd49bc9867d6c6f8ef54109adb428c8ca92614d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 27 Aug 2021 10:48:23 +0200 Subject: [PATCH 2018/4321] pkcs11-tool: Print human-redable profile names --- src/tools/pkcs11-tool.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0c8f2197b3..24a2884071 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -541,6 +541,7 @@ static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); static uint16_t p11_mechanism_to_flags(CK_MECHANISM_TYPE mech); static const char * p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE); static CK_MECHANISM_TYPE p11_name_to_mgf(const char *); +static const char * p11_profile_to_name(CK_ULONG); static void p11_perror(const char *, CK_RV); static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); @@ -4636,7 +4637,7 @@ static void show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("Profile object %u\n", (unsigned int) obj); printf(" profile_id: "); if ((id = getPROFILE_ID(sess, obj)) != 0) { - printf("'%lu'\n", id); + printf("%s (%lu)\n", p11_profile_to_name(id), id); } else { printf("\n"); } @@ -7280,6 +7281,16 @@ static struct mech_info p11_mgf[] = { { 0, NULL, NULL, MF_UNKNOWN } }; +static struct mech_info p11_profile[] = { + { CKP_INVALID_ID, "CKP_INVALID_ID", NULL, MF_UNKNOWN }, + { CKP_BASELINE_PROVIDER, "CKP_BASELINE_PROVIDER", NULL, MF_UNKNOWN }, + { CKP_EXTENDED_PROVIDER, "CKP_EXTENDED_PROVIDER", NULL, MF_UNKNOWN }, + { CKP_AUTHENTICATION_TOKEN, "CKP_AUTHENTICATION_TOKEN", NULL, MF_UNKNOWN }, + { CKP_PUBLIC_CERTIFICATES_TOKEN, "CKP_PUBLIC_CERTIFICATES_TOKEN", NULL, MF_UNKNOWN }, + { CKP_VENDOR_DEFINED, "CKP_VENDOR_DEFINED", NULL, MF_UNKNOWN }, + { 0, NULL, NULL, MF_UNKNOWN } +}; + static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech) { static char temp[64]; @@ -7352,6 +7363,19 @@ static const char *p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf) return temp; } +static const char *p11_profile_to_name(CK_ULONG profile) +{ + static char temp[64]; + struct mech_info *mi; + + for (mi = p11_profile; mi->name; mi++) { + if (mi->mech == profile) + return mi->name; + } + snprintf(temp, sizeof(temp), "profile-0x%lX", (unsigned long) profile); + return temp; +} + static const char * CKR2Str(CK_ULONG res) { switch (res) { From cf042ef6d37800cf54ab7c1db35776964d0cc512 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 27 Aug 2021 11:48:43 +0200 Subject: [PATCH 2019/4321] p11test: Test also longer messages for EdDSA --- src/tests/p11test/p11test_case_ec_sign.c | 30 +++++++++++----- src/tests/p11test/p11test_case_readonly.c | 42 ++++++++++++++++------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_sign.c b/src/tests/p11test/p11test_case_ec_sign.c index 8aedd8c63c..d27e6c6eec 100644 --- a/src/tests/p11test/p11test_case_ec_sign.c +++ b/src/tests/p11test/p11test_case_ec_sign.c @@ -22,12 +22,12 @@ void ec_sign_size_test(void **state) { unsigned int i; - int min, max, j, l, errors = 0, rv; + int min, max, inc, j, l, errors = 0, rv; token_info_t *info = (token_info_t *) *state; P11TEST_START(info); - if (token.num_ec_mechs == 0 ) { - fprintf(stderr, "Token does not support any ECC mechanisms. Skipping.\n"); + if (token.num_ec_mechs == 0 && token.num_ed_mechs == 0) { + fprintf(stderr, "Token does not support any ECC signature mechanisms. Skipping.\n"); P11TEST_SKIP(info); } @@ -39,14 +39,29 @@ void ec_sign_size_test(void **state) { debug_print("\nCheck functionality of Sign&Verify on different data lengths"); for (i = 0; i < objects.count; i++) { - if (objects.data[i].key_type != CKK_EC) + switch (objects.data[i].key_type) { + case CKK_EC: + /* This tests just couple of sizes around the curve length + * to verify they are properly truncated on input */ + min = (objects.data[i].bits + 7) / 8 - 2; + max = (objects.data[i].bits + 7) / 8 + 2; + inc = 1; + break; + case CKK_EC_EDWARDS: + /* Tests larger inputs for EdDSA. Previously, we had hardcoded limit of 512 + * https://github.com/OpenSC/OpenSC/issues/2300 */ + min = 128; + max = 1024; + inc = 128; + break; + default: continue; + } + // sanity: Test all mechanisms - min = (objects.data[i].bits + 7) / 8 - 2; - max = (objects.data[i].bits + 7) / 8 + 2; if (objects.data[i].sign && objects.data[i].verify) { for (j = 0; j < objects.data[i].num_mechs; j++) { - for (l = min; l < max; l++) { + for (l = min; l < max; l += inc) { rv = sign_verify_test(&(objects.data[i]), info, &(objects.data[i].mechs[j]), l, 0); if (rv == -1) @@ -61,4 +76,3 @@ void ec_sign_size_test(void **state) { P11TEST_FAIL(info, "Some signatures were not verified successfully. Please review the log"); P11TEST_PASS(info); } - diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index c4e4ae3b6e..f0a6fe1c7e 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -25,15 +25,32 @@ #include #include -#define SHORT_MESSAGE_TO_SIGN "Simple message for signing & verifying. It needs to be little bit longer to fit also longer keys and allow the truncation.\n" -#define SHORT_MESSAGE_DIGEST "\x30\x21\x30\x09\x06\x05\x2b\x0e" \ - "\x03\x02\x1a\x05\x00\x04\x14\xd9" \ - "\xdd\xa3\x76\x44\x2f\x50\xe1\xec" \ - "\xd3\x8b\xcd\x6f\xc6\xce\x4e\xfd" \ - "\xd3\x1a\x3f" +#define MESSAGE_TO_SIGN "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ + "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" +#define MESSAGE_DIGEST "\x30\x21\x30\x09\x06\x05\x2b\x0e" \ + "\x03\x02\x1a\x05\x00\x04\x14\xd9" \ + "\xdd\xa3\x76\x44\x2f\x50\xe1\xec" \ + "\xd3\x8b\xcd\x6f\xc6\xce\x4e\xfd" \ + "\xd3\x1a\x3f" #define BUFFER_SIZE 4096 -const unsigned char *const_message = (unsigned char *) SHORT_MESSAGE_TO_SIGN; +const unsigned char *const_message = (unsigned char *) MESSAGE_TO_SIGN; static unsigned char * rsa_x_509_pad_message(const unsigned char *message, @@ -201,7 +218,7 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, message = rsa_x_509_pad_message(const_message, &message_length, o, 1); else - message = (CK_BYTE *) strdup(SHORT_MESSAGE_TO_SIGN); + message = (CK_BYTE *) strdup(MESSAGE_TO_SIGN); debug_print(" [ KEY %s ] Encrypt message using CKM_%s", o->id_str, get_mechanism_name(mech->mech)); @@ -568,8 +585,9 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, CK_ULONG sign_length = 0; int rv = 0; - if (message_length > strlen(SHORT_MESSAGE_TO_SIGN)) { - fail_msg("Truncate is longer than the actual message"); + if (message_length > strlen(MESSAGE_TO_SIGN)) { + fail_msg("Truncate (%lu) is longer than the actual message (%lu)", + message_length, strlen(MESSAGE_TO_SIGN)); return -1; } @@ -596,9 +614,9 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, /* DigestInfo + SHA1(message) */ message_length = 35; message = malloc(message_length * sizeof(unsigned char)); - memcpy(message, SHORT_MESSAGE_DIGEST, message_length); + memcpy(message, MESSAGE_DIGEST, message_length); } else - message = (CK_BYTE *) strdup(SHORT_MESSAGE_TO_SIGN); + message = (CK_BYTE *) strdup(MESSAGE_TO_SIGN); debug_print(" [ KEY %s ] Signing message of length %lu using CKM_%s", o->id_str, message_length, get_mechanism_name(mech->mech)); From 0531499d0e8f05e8c842d2689b701530483a25e0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 20 Aug 2021 20:07:53 +0200 Subject: [PATCH 2020/4321] Describe how to run tests in container environment closest to Github Actions --- CONTRIBUTING.md | 10 +++++ containers/README.md | 55 ++++++++++++++++++++++++ containers/opensc-build/Containerfile | 12 ++++++ containers/opensc-test-cac/Containerfile | 13 ++++++ containers/opensc-test-piv/Containerfile | 13 ++++++ 5 files changed, 103 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 containers/README.md create mode 100644 containers/opensc-build/Containerfile create mode 100644 containers/opensc-test-cac/Containerfile create mode 100644 containers/opensc-test-piv/Containerfile diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..3b063e3ba3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Testing locally + +To learn how to run the tests from Github actions locally in containers, see +[`containers`](https://github.com/OpenSC/OpenSC/master/containers/). + +# Release process + +The release process is described in [OpenSC wiki](https://github.com/OpenSC/OpenSC/wiki/OpenSC-Release-Howto) + +TODO tarball signing: https://github.com/OpenSC/OpenSC/issues/1129 diff --git a/containers/README.md b/containers/README.md new file mode 100644 index 0000000000..ac71b50a7f --- /dev/null +++ b/containers/README.md @@ -0,0 +1,55 @@ +# Testing locally using containers + +You can run the tests executed in github actions in containers locally. This can +be handy to test some modification of the code or the CI pipeline. + +First, we need to prepare the container image. This already runs setup and +mounts current working directory to the container: + +``` +$ podman build -v $PWD:/src -t opensc-build containers/opensc-build +``` + +Now, you can jump into the container with preinstalled dependencies to build +OpenSC: + +``` +$ podman run -v $PWD:/src -ti opensc-build +``` +If you want to run the build manually, investigate some issues, you can start +with shell +``` +$ podman run -v $PWD:/src -ti opensc-build /bin/bash +# .github/build.sh +``` +To debug some issues with gdb, the container needs some more capabilities. +With the following configuration, I am able to run gdb to debug possible +issues: +``` +$ podman run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $PWD:/src -ti opensc-build /bin/bash +# .github/build.sh +# apt install -y libtool-bin gdb +# libtool --mode=execute gdb --args ./src/tools/pkcs11-tool --test-threads IN -L --module=/usr/lib/softhsm/libsofthsm2.so +``` + +Similarly for tests, you can build a container for example for CAC testing: +``` +$ podman build -v $PWD:/src -t opensc-cac containers/opensc-test-cac +``` +and then run the tests: +``` +$ podman run -v $PWD:/src -ti opensc-cac +``` + +The javacard tests are very similar. This can be used to build a container for +PIV testing: +``` +$ podman build -v $PWD:/src -t opensc-piv containers/opensc-test-piv +``` +and then run the tests: +``` +$ podman run -v $PWD:/src -ti opensc-piv +``` +(if you are using Docker, you will need to replace "podman" with "docker" and +maybe change the generic Containerfile name to Dockerfile, but otherwise it +should work the same way) diff --git a/containers/opensc-build/Containerfile b/containers/opensc-build/Containerfile new file mode 100644 index 0000000000..8793c89bf6 --- /dev/null +++ b/containers/opensc-build/Containerfile @@ -0,0 +1,12 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh +CMD /src/.github/build.sh dist diff --git a/containers/opensc-test-cac/Containerfile b/containers/opensc-test-cac/Containerfile new file mode 100644 index 0000000000..6d6065ed5d --- /dev/null +++ b/containers/opensc-test-cac/Containerfile @@ -0,0 +1,13 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh cac +RUN /src/.github/build.sh +CMD /src/.github/test-cac.sh diff --git a/containers/opensc-test-piv/Containerfile b/containers/opensc-test-piv/Containerfile new file mode 100644 index 0000000000..a83f377ccc --- /dev/null +++ b/containers/opensc-test-piv/Containerfile @@ -0,0 +1,13 @@ +FROM ubuntu:18.04 +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh piv +RUN /src/.github/build.sh +CMD /src/.github/test-piv.sh From 82588d8f45edcf41053202d3b9ae59ec49fe95f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 1 Sep 2021 10:23:38 +0200 Subject: [PATCH 2021/4321] pkcs11: Add a todo note --- src/pkcs11/framework-pkcs15.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index e31acd1370..521fbecfef 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5960,6 +5960,11 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags mech_info.ulMinKeySize = min_key_size; mech_info.ulMaxKeySize = max_key_size; +#ifdef ENABLE_OPENSSL + /* TODO verification using EDDSA + mech_info.flags |= CKF_VERIFY; + */ +#endif if (flags & SC_ALGORITHM_EDDSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_EDDSA, &mech_info, CKK_EC_EDWARDS, NULL, NULL); if (!mt) From a6a44721daeb20ee5e35087c2451940b189b4331 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 3 Sep 2021 07:59:52 +0200 Subject: [PATCH 2022/4321] CONTRIBUTING: Use relative link --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3b063e3ba3..2fbea403dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Testing locally To learn how to run the tests from Github actions locally in containers, see -[`containers`](https://github.com/OpenSC/OpenSC/master/containers/). +[`containers`](containers/README.md). # Release process From 876898bff82f352ec3cdd7ef83a29ce1666ad94d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Sep 2021 13:06:15 +0200 Subject: [PATCH 2023/4321] Add mingw container for testing --- containers/opensc-mingw/Containerfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 containers/opensc-mingw/Containerfile diff --git a/containers/opensc-mingw/Containerfile b/containers/opensc-mingw/Containerfile new file mode 100644 index 0000000000..7e1fe607d7 --- /dev/null +++ b/containers/opensc-mingw/Containerfile @@ -0,0 +1,12 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh mingw +CMD /src/.github/build.sh mingw From f0afd1711d8c83f3460269ea6f30cc321f19130b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Sep 2021 13:50:49 +0200 Subject: [PATCH 2024/4321] .github: Default to verbose make --- .github/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index cf0f8f8b3b..fa29e621ae 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -34,7 +34,7 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then unset CC unset CXX ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=$PWD/win32/opensc || cat config.log; - make -j 2 + make -j 2 V=1 # no point in running tests on mingw else if [ "$1" == "ix86" ]; then @@ -43,7 +43,7 @@ else fi # normal procedure ./configure --disable-dependency-tracking - make -j 2 + make -j 2 V=1 # 32b build has some issues to find openssl correctly if [ "$1" != "ix86" ]; then make check From a00ead5bcaeef9761287572f7b62065d62c211d9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Sep 2021 12:56:41 +0200 Subject: [PATCH 2025/4321] libopensc: Unbreak build with mingw Related to #2294 --- src/libopensc/Makefile.am | 2 +- src/pkcs11/Makefile.am | 4 ++++ src/tools/Makefile.am | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 1303c034a7..d544a98a8e 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -87,7 +87,7 @@ libopensc_la_LIBADD = $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) \ $(top_builddir)/src/sm/libsmeac.la \ $(top_builddir)/src/common/libcompat.la if WIN32 -libopensc_la_LIBADD += -lws2_32 +libopensc_la_LIBADD += -lws2_32 -lshlwapi endif libopensc_static_la_LIBADD = $(libopensc_la_LIBADD) libopensc_la_LDFLAGS = $(AM_LDFLAGS) \ diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 557a52ef2d..0c583fc1c4 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -23,6 +23,9 @@ OPENSC_PKCS11_LIBS = \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la \ $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) +if WIN32 +OPENSC_PKCS11_LIBS += -lshlwapi +endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opensc-pkcs11.pc @@ -61,6 +64,7 @@ pkcs11_spy_la_LDFLAGS = $(AM_LDFLAGS) \ if WIN32 opensc_pkcs11_la_SOURCES += versioninfo-pkcs11.rc pkcs11_spy_la_SOURCES += versioninfo-pkcs11-spy.rc +pkcs11_spy_la_LIBADD += -lshlwapi endif if WIN32 diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index fe67ad01b8..de11c36fc0 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -145,6 +145,7 @@ cmdline: $(AM_V_GEN)$(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < opensc-asn1.ggo --unamed-opts if WIN32 +LIBS += -lshlwapi opensc_tool_SOURCES += versioninfo-tools.rc piv_tool_SOURCES += versioninfo-tools.rc opensc_explorer_SOURCES += versioninfo-tools.rc From 7a6032d39e4373c24cb813b6140a0a0b4d9baea3 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 12 Sep 2021 21:24:14 +0200 Subject: [PATCH 2026/4321] Fix typos found by codespell --- NEWS | 2 +- src/pkcs15init/pkcs15-entersafe.c | 2 +- src/sm/sm-common.c | 2 +- src/tests/opensc-minidriver-test.c | 2 +- src/tools/pkcs11-tool.c | 12 ++++++------ tests/test-pkcs11-tool-allowed-mechanisms.sh | 2 +- tests/test-pkcs11-tool-sign-verify.sh | 2 +- tests/test-pkcs11-tool-test.sh | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 0f82a5ddb6..a9215cdaec 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,7 @@ NEWS for OpenSC -- History of user visible changes * Add threading test to `pkcs11-tool` (#2067) * Add support to generate generic secret keys (#2140) * `opensc-explorer`: Print information about LCS (Life cycle status byte) (#2195) - * Add support for Apple's arm64 (M1) binaries, removed TokenD. A seperate installer with TokenD (and without arm64 binaries) will be available (#2179). + * Add support for Apple's arm64 (M1) binaries, removed TokenD. A separate installer with TokenD (and without arm64 binaries) will be available (#2179). * Support for gcc11 and its new strict aliasing rules (#2241, #2260) * Initial support for building with OpenSSL 3.0 (#2343) * pkcs15-tool: Write data objects in binary mode (#2324) diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 99cd5c9e2d..7c3b195462 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -168,7 +168,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card memcpy(df_data.data.df.aid,df->name,df->namelen); ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &df_data); - LOG_TEST_RET(card->ctx,ret,"Crate DF failed"); + LOG_TEST_RET(card->ctx,ret,"Create DF failed"); } {/* GPKF */ diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 8628532882..4ea26345ef 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -469,7 +469,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } -/* This function expects the data to be a multilpe of DES block size */ +/* This function expects the data to be a multiple of DES block size */ int sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, const unsigned char *in, size_t in_len, diff --git a/src/tests/opensc-minidriver-test.c b/src/tests/opensc-minidriver-test.c index d139b78414..5abad1b6b6 100644 --- a/src/tests/opensc-minidriver-test.c +++ b/src/tests/opensc-minidriver-test.c @@ -607,7 +607,7 @@ int apiTests(char *reader) if (pinEnv) printf("Running tests using PIN=%s/len=%zd\n", pinEnv, strlen(pinEnv)); else - printf("Running tests wihtout any PIN\n"); + printf("Running tests without any PIN\n"); memset(&cardData, 0, sizeof(cardData)); cardData.dwVersion = 7; cardData.pwszCardName = L"TestCard"; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 24a2884071..881768f165 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -442,14 +442,14 @@ struct flag_info { * * TODO these flags are only the tip of the iceberg, but can be filled out as time progresses. */ -#define MF_UNKNOWN 0 /* Used to indicate additional informtion is not available */ +#define MF_UNKNOWN 0 /* Used to indicate additional information is not available */ #define MF_SIGN (1 << 0) /* C_Sign interface supported */ #define MF_VERIFY (1 << 1) /* C_verify interface supported */ #define MF_HMAC (1 << 2) /* Is an Hashed Message Authentication Code (HMAC) */ #define MF_MGF (1 << 3) /* Is an Mask Generation Function (MGF) */ #define MF_CKO_SECRET_KEY (1 << 4) /* Uses a CKO_SECRET_KEY class object */ -/* Handy intializers */ +/* Handy initializers */ #define MF_GENERIC_HMAC_FLAGS (MF_SIGN | MF_VERIFY | MF_HMAC | MF_CKO_SECRET_KEY) struct mech_info { @@ -562,7 +562,7 @@ static DWORD WINAPI test_threads_run(_In_ LPVOID pttd); #else static void * test_threads_run(void * pttd); #endif -#endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */ +#endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */ static void generate_random(CK_SESSION_HANDLE session); static CK_RV find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out, CK_ATTRIBUTE *attrs, CK_ULONG attrsLen, CK_ULONG obj_index); @@ -1389,7 +1389,7 @@ int main(int argc, char * argv[]) #if defined(_WIN32) || defined(HAVE_PTHREAD) if (do_test_threads) test_threads_cleanup(); -#endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */ +#endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */ if (p11) p11->C_Finalize(NULL_PTR); @@ -7574,7 +7574,7 @@ static void * test_threads_run(void * pttd) /* call selected C_* routines with different options */ pctest = ttd-> tests; - /* series of two chatacter commands */ + /* series of two character commands */ while (pctest && *pctest && *(pctest + 1)) { ttd->state = state++; @@ -7777,4 +7777,4 @@ static void test_threads() test_threads_start(i); } } -#endif /* defined(_WIN32) || defiend(HAVE_PTHREAD) */ +#endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */ diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 7fa819bf6a..2cb822d3b5 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -7,7 +7,7 @@ echo "=======================================================" echo "Setup SoftHSM" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi # The Ubuntu has old softhsm version not supporting this feature diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 3a9b410248..a2a501d3c1 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -7,7 +7,7 @@ echo "=======================================================" echo "Setup SoftHSM" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi card_setup diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 015a87b506..8b41288370 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -7,7 +7,7 @@ echo "=======================================================" echo "Setup SoftHSM" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi From e4fdbebee333e80301a399e46df15c9838112f94 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 18 Sep 2021 16:08:44 -0500 Subject: [PATCH 2027/4321] sm-common.c - missing semicolons On branch sm-common-semicolons Changes to be committed: modified: ../sm/sm-common.c --- src/sm/sm-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 4ea26345ef..f9d6998567 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -534,21 +534,21 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, #else cctx = EVP_CIPHER_CTX_new(); if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { - free(*out) + free(*out); EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) { - free(*out) + free(*out); EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len = tmplen; if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { - free(*out) + free(*out); EVP_CIPHER_CTX_free(cctx); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } From dd4afa02878ba0247dae8e56f36a86d6d87d11ff Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Sat, 11 Sep 2021 13:36:02 +0000 Subject: [PATCH 2028/4321] openpgp-tool: fix buffer overflow on serials with MSb set Fixes the following crash: $ openpgp-tool --card-info Using reader with a card: Linux Foundation Multifunction Composite Gadget - vincent [python-usb-f-ccid] 00 00 AID: d2:76:00:01:24:01:03:41:ff:65:a4:9b:68:64:00:00 Version: 3.41 Manufacturer: unmanaged S/N range *** buffer overflow detected ***: terminated Abandon (core dumped) "a4:9b:68:64" from the AID being the serial, and: (gdb) print (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) $12 = -1533319068 but (gdb) print (unsigned long) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) $13 = 18446744072176232548 Avoid the shifts and cast altogether. --- src/tools/openpgp-tool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 92127a7500..7b4d6eb5fd 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -325,9 +325,7 @@ static char *prettify_serialnumber(u8 *data, size_t length) { if (data != NULL && length >= 4) { static char result[15]; /* large enough for even 2*3 digits + separator */ - unsigned long serial = (unsigned long) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); - - sprintf(result, "%08lX", serial); + sprintf(result, "%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); return result; } return NULL; From d2fddc4f75fd0e05038ceb4d92f1a7171772523a Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Tue, 14 Sep 2021 11:38:54 +0000 Subject: [PATCH 2029/4321] .gitignore: Add entries for existing unittests. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 12e1170e62..b135fe6fcc 100644 --- a/.gitignore +++ b/.gitignore @@ -121,7 +121,9 @@ tests/*.trs src/tests/unittests/*.log src/tests/unittests/*.trs src/tests/unittests/asn1 +src/tests/unittests/cachedir src/tests/unittests/compression +src/tests/unittests/pkcs15filter src/tests/unittests/simpletlv src/tests/unittests/sm From 34967686e3f478b16d0a2a9dcb535dddad9eb5e1 Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Mon, 13 Sep 2021 23:03:04 +0000 Subject: [PATCH 2030/4321] tools: Split openpgp-tool's prettify_* functions into another file. No change to source code other than the relocation. In preparation for unit testing. --- src/tools/Makefile.am | 5 +- src/tools/Makefile.mak | 5 + src/tools/openpgp-tool-helpers.c | 222 +++++++++++++++++++++++++++++++ src/tools/openpgp-tool-helpers.h | 38 ++++++ src/tools/openpgp-tool.c | 207 +--------------------------- 5 files changed, 270 insertions(+), 207 deletions(-) create mode 100644 src/tools/openpgp-tool-helpers.c create mode 100644 src/tools/openpgp-tool-helpers.h diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index de11c36fc0..b7aade285d 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -25,7 +25,8 @@ EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.i noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ - opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h + opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h \ + openpgp-tool-helpers.h noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ @@ -77,7 +78,7 @@ netkey_tool_SOURCES = netkey-tool.c netkey_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) westcos_tool_SOURCES = westcos-tool.c util.c westcos_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) -openpgp_tool_SOURCES = openpgp-tool.c util.c +openpgp_tool_SOURCES = openpgp-tool.c util.c openpgp-tool-helpers.c openpgp_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) iasecc_tool_SOURCES = iasecc-tool.c util.c iasecc_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index b016b126bc..a19a7b55cb 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -57,6 +57,11 @@ pkcs15-tool.exe: pkcs15-tool.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib mt -manifest exe.manifest -outputresource:$@;1 +openpgp-tool.exe: openpgp-tool-helpers.obj $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj openpgp-tool-helpers.obj $(OBJECTS) $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib + mt -manifest exe.manifest -outputresource:$@;1 + .c.exe: cl $(COPTS) /c $< link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib diff --git a/src/tools/openpgp-tool-helpers.c b/src/tools/openpgp-tool-helpers.c new file mode 100644 index 0000000000..b8b022290d --- /dev/null +++ b/src/tools/openpgp-tool-helpers.c @@ -0,0 +1,222 @@ +/* + * openpgp-tool-helpers.c: OpenPGP card utility + * + * Copyright (C) 2012-2020 Peter Marschall + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include "openpgp-tool-helpers.h" +#include "util.h" + + +/* prettify hex */ +char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) +{ + if (data != NULL) { + int r = sc_bin_to_hex(data, length, buffer, buflen, ':'); + + if (r == SC_SUCCESS) + return buffer; + } + return NULL; +} + + +/* prettify algorithm parameters */ +char *prettify_algorithm(u8 *data, size_t length) +{ + if (data != NULL && length >= 1) { + static char result[64]; /* large enough */ + + if (data[0] == 0x01 && length >= 5) { /* RSA */ + unsigned short modulus = (data[1] << 8) + data[2]; + snprintf(result, sizeof(result), "RSA%u", modulus); + return result; + } + else if (data[0] == 0x12) { /* ECDH */ + strcpy(result, "ECDH"); + return result; + } + else if (data[0] == 0x13) { /* ECDSA */ + strcpy(result, "ECDSA"); + return result; + } + } + return NULL; +} + + +/* prettify date/time */ +char *prettify_date(u8 *data, size_t length) +{ + if (data != NULL && length == 4) { + time_t time = (time_t) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); + struct tm tm; + static char result[64]; /* large enough */ + +#ifdef _WIN32 + if (0 != gmtime_s(&tm, &time)) + return NULL; +#else + if (NULL == gmtime_r(&time, &tm)) + return NULL; +#endif + strftime(result, sizeof(result), "%Y-%m-%d %H:%M:%S", &tm); + return result; + } + return NULL; +} + + +#define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) + +/* prettify OpenPGP card version */ +char *prettify_version(u8 *data, size_t length) +{ + if (data != NULL && length >= 2) { + static char result[10]; /* large enough for even 2*3 digits + separator */ + int major = BCD2CHAR(data[0]); + int minor = BCD2CHAR(data[1]); + + sprintf(result, "%d.%d", major, minor); + return result; + } + return NULL; +} + + +/* prettify manufacturer */ +char *prettify_manufacturer(u8 *data, size_t length) +{ + if (data != NULL && length >= 2) { + unsigned int manuf = (data[0] << 8) + data[1]; + + switch (manuf) { + case 0x0001: return "PPC Card Systems"; + case 0x0002: return "Prism"; + case 0x0003: return "OpenFortress"; + case 0x0004: return "Wewid"; + case 0x0005: return "ZeitControl"; + case 0x0006: return "Yubico"; + case 0x0007: return "OpenKMS"; + case 0x0008: return "LogoEmail"; + case 0x0009: return "Fidesmo"; + case 0x000A: return "Dangerous Things"; + case 0x000B: return "Feitian Technologies"; + + case 0x002A: return "Magrathea"; + case 0x0042: return "GnuPG e.V."; + + case 0x1337: return "Warsaw Hackerspace"; + case 0x2342: return "warpzone"; /* hackerspace Muenster. */ + case 0x4354: return "Confidential Technologies"; /* cotech.de */ + case 0x5443: return "TIF-IT e.V."; + case 0x63AF: return "Trustica"; + case 0xBA53: return "c-base e.V."; + case 0xBD0E: return "Paranoidlabs"; + case 0xF517: return "FSIJ"; + case 0xF5EC: return "F-Secure"; + + /* 0x0000 and 0xFFFF are defined as test cards per spec, + 0xFF00 to 0xFFFE are assigned for use with randomly created + serial numbers. */ + case 0x0000: + case 0xffff: return "test card"; + default: return (manuf & 0xff00) == 0xff00 ? "unmanaged S/N range" : "unknown"; + } + } + return NULL; +} + + +/* prettify pure serial number */ +char *prettify_serialnumber(u8 *data, size_t length) +{ + if (data != NULL && length >= 4) { + static char result[15]; /* large enough for even 2*3 digits + separator */ + sprintf(result, "%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + return result; + } + return NULL; +} + + +/* prettify card holder's name */ +char *prettify_name(u8 *data, size_t length) +{ + if (data != NULL && length > 0) { + char *src = (char *) data; + char *dst = (char *) data; + + while (*src != '\0' && length > 0) { + *dst = *src++; + length--; + if (*dst == '<') { + if (length > 0 && *src == '<') { + src++; + length--; + } + *dst = ' '; + } + dst++; + } + *dst = '\0'; + return (char *) data; + } + return NULL; +} + + +/* prettify language */ +char *prettify_language(u8 *data, size_t length) +{ + if (data != NULL && length > 0) { + char *str = (char *) data; + + switch (strlen(str)) { + case 8: memmove(str+7, str+6, 1+strlen(str+6)); + str[6] = ','; + /* fall through */ + case 6: memmove(str+5, str+4, 1+strlen(str+4)); + str[4] = ','; + /* fall through */ + case 4: memmove(str+3, str+2, 1+strlen(str+2)); + str[2] = ','; + /* fall through */ + case 2: return str; + } + } + return NULL; +} + + +/* convert the raw ISO-5218 SEX value to an english word */ +char *prettify_gender(u8 *data, size_t length) +{ + if (data != NULL && length > 0) { + switch (*data) { + case '0': return "unknown"; + case '1': return "male"; + case '2': return "female"; + case '9': return "not announced"; + } + } + return NULL; +} diff --git a/src/tools/openpgp-tool-helpers.h b/src/tools/openpgp-tool-helpers.h new file mode 100644 index 0000000000..ec3b426c81 --- /dev/null +++ b/src/tools/openpgp-tool-helpers.h @@ -0,0 +1,38 @@ +/* + * openpgp-tool-helpers.h: OpenPGP card utility + * + * Copyright (C) 2012-2020 Peter Marschall + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef OPENPGP_TOOL_HELPERS_H +#define OPENPGP_TOOL_HELPERS_H + +#include "util.h" + + +char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen); +char *prettify_algorithm(u8 *data, size_t length); +char *prettify_date(u8 *data, size_t length); +char *prettify_version(u8 *data, size_t length); +char *prettify_manufacturer(u8 *data, size_t length); +char *prettify_serialnumber(u8 *data, size_t length); +char *prettify_name(u8 *data, size_t length); +char *prettify_language(u8 *data, size_t length); +char *prettify_gender(u8 *data, size_t length); + + +#endif /* OPENPGP_TOOL_HELPERS_H */ diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 7b4d6eb5fd..de62866fa1 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -49,6 +49,8 @@ #include "libopensc/log.h" #include "libopensc/card-openpgp.h" +#include "openpgp-tool-helpers.h" + #define OPT_RAW 256 #define OPT_PRETTY 257 #define OPT_VERIFY 258 @@ -74,15 +76,6 @@ struct ef_name_map { /* declare functions */ static void show_version(void); -static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen); -static char *prettify_algorithm(u8 *data, size_t length); -static char *prettify_date(u8 *data, size_t length); -static char *prettify_version(u8 *data, size_t length); -static char *prettify_manufacturer(u8 *data, size_t length); -static char *prettify_serialnumber(u8 *data, size_t length); -static char *prettify_name(u8 *data, size_t length); -static char *prettify_language(u8 *data, size_t length); -static char *prettify_gender(u8 *data, size_t length); static void display_data(const struct ef_name_map *mapping, u8 *data, size_t length); static int decode_options(int argc, char **argv); static int do_info(sc_card_t *card, const struct ef_name_map *map); @@ -200,202 +193,6 @@ static void show_version(void) } -/* prettify hex */ -static char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) -{ - if (data != NULL) { - int r = sc_bin_to_hex(data, length, buffer, buflen, ':'); - - if (r == SC_SUCCESS) - return buffer; - } - return NULL; -} - - -/* prettify algorithm parameters */ -static char *prettify_algorithm(u8 *data, size_t length) -{ - if (data != NULL && length >= 1) { - static char result[64]; /* large enough */ - - if (data[0] == 0x01 && length >= 5) { /* RSA */ - unsigned short modulus = (data[1] << 8) + data[2]; - snprintf(result, sizeof(result), "RSA%u", modulus); - return result; - } - else if (data[0] == 0x12) { /* ECDH */ - strcpy(result, "ECDH"); - return result; - } - else if (data[0] == 0x13) { /* ECDSA */ - strcpy(result, "ECDSA"); - return result; - } - } - return NULL; -} - - -/* prettify date/time */ -static char *prettify_date(u8 *data, size_t length) -{ - if (data != NULL && length == 4) { - time_t time = (time_t) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); - struct tm tm; - static char result[64]; /* large enough */ - -#ifdef _WIN32 - if (0 != gmtime_s(&tm, &time)) - return NULL; -#else - if (NULL == gmtime_r(&time, &tm)) - return NULL; -#endif - strftime(result, sizeof(result), "%Y-%m-%d %H:%M:%S", &tm); - return result; - } - return NULL; -} - - -#define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) - -/* prettify OpenPGP card version */ -static char *prettify_version(u8 *data, size_t length) -{ - if (data != NULL && length >= 2) { - static char result[10]; /* large enough for even 2*3 digits + separator */ - int major = BCD2CHAR(data[0]); - int minor = BCD2CHAR(data[1]); - - sprintf(result, "%d.%d", major, minor); - return result; - } - return NULL; -} - - -/* prettify manufacturer */ -static char *prettify_manufacturer(u8 *data, size_t length) -{ - if (data != NULL && length >= 2) { - unsigned int manuf = (data[0] << 8) + data[1]; - - switch (manuf) { - case 0x0001: return "PPC Card Systems"; - case 0x0002: return "Prism"; - case 0x0003: return "OpenFortress"; - case 0x0004: return "Wewid"; - case 0x0005: return "ZeitControl"; - case 0x0006: return "Yubico"; - case 0x0007: return "OpenKMS"; - case 0x0008: return "LogoEmail"; - case 0x0009: return "Fidesmo"; - case 0x000A: return "Dangerous Things"; - case 0x000B: return "Feitian Technologies"; - - case 0x002A: return "Magrathea"; - case 0x0042: return "GnuPG e.V."; - - case 0x1337: return "Warsaw Hackerspace"; - case 0x2342: return "warpzone"; /* hackerspace Muenster. */ - case 0x4354: return "Confidential Technologies"; /* cotech.de */ - case 0x5443: return "TIF-IT e.V."; - case 0x63AF: return "Trustica"; - case 0xBA53: return "c-base e.V."; - case 0xBD0E: return "Paranoidlabs"; - case 0xF517: return "FSIJ"; - case 0xF5EC: return "F-Secure"; - - /* 0x0000 and 0xFFFF are defined as test cards per spec, - 0xFF00 to 0xFFFE are assigned for use with randomly created - serial numbers. */ - case 0x0000: - case 0xffff: return "test card"; - default: return (manuf & 0xff00) == 0xff00 ? "unmanaged S/N range" : "unknown"; - } - } - return NULL; -} - - -/* prettify pure serial number */ -static char *prettify_serialnumber(u8 *data, size_t length) -{ - if (data != NULL && length >= 4) { - static char result[15]; /* large enough for even 2*3 digits + separator */ - sprintf(result, "%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); - return result; - } - return NULL; -} - - -/* prettify card holder's name */ -static char *prettify_name(u8 *data, size_t length) -{ - if (data != NULL && length > 0) { - char *src = (char *) data; - char *dst = (char *) data; - - while (*src != '\0' && length > 0) { - *dst = *src++; - length--; - if (*dst == '<') { - if (length > 0 && *src == '<') { - src++; - length--; - } - *dst = ' '; - } - dst++; - } - *dst = '\0'; - return (char *) data; - } - return NULL; -} - - -/* prettify language */ -static char *prettify_language(u8 *data, size_t length) -{ - if (data != NULL && length > 0) { - char *str = (char *) data; - - switch (strlen(str)) { - case 8: memmove(str+7, str+6, 1+strlen(str+6)); - str[6] = ','; - /* fall through */ - case 6: memmove(str+5, str+4, 1+strlen(str+4)); - str[4] = ','; - /* fall through */ - case 4: memmove(str+3, str+2, 1+strlen(str+2)); - str[2] = ','; - /* fall through */ - case 2: return str; - } - } - return NULL; -} - - -/* convert the raw ISO-5218 SEX value to an english word */ -static char *prettify_gender(u8 *data, size_t length) -{ - if (data != NULL && length > 0) { - switch (*data) { - case '0': return "unknown"; - case '1': return "male"; - case '2': return "female"; - case '9': return "not announced"; - } - } - return NULL; -} - - #define INDENT 16 static void display_data(const struct ef_name_map *map, u8 *data, size_t length) From 3680e78109ff26320be6745c529d53649868b060 Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Tue, 14 Sep 2021 11:35:28 +0000 Subject: [PATCH 2031/4321] tools: Constify openpgp-tool's prettify_* functions' arguments. prettify_name: Use a separate buffer to hold the result. This adds a limit to the name length, chosen arbitrarily at 99 bytes (+ null). prettify_language: Use a separate buffer to hold the result. No functional change expected. --- src/tools/openpgp-tool-helpers.c | 49 ++++++++++++++++---------------- src/tools/openpgp-tool-helpers.h | 18 ++++++------ src/tools/openpgp-tool.c | 2 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/tools/openpgp-tool-helpers.c b/src/tools/openpgp-tool-helpers.c index b8b022290d..c5f862faff 100644 --- a/src/tools/openpgp-tool-helpers.c +++ b/src/tools/openpgp-tool-helpers.c @@ -27,7 +27,7 @@ /* prettify hex */ -char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) +char *prettify_hex(const u8 *data, size_t length, char *buffer, size_t buflen) { if (data != NULL) { int r = sc_bin_to_hex(data, length, buffer, buflen, ':'); @@ -40,7 +40,7 @@ char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen) /* prettify algorithm parameters */ -char *prettify_algorithm(u8 *data, size_t length) +char *prettify_algorithm(const u8 *data, size_t length) { if (data != NULL && length >= 1) { static char result[64]; /* large enough */ @@ -64,7 +64,7 @@ char *prettify_algorithm(u8 *data, size_t length) /* prettify date/time */ -char *prettify_date(u8 *data, size_t length) +char *prettify_date(const u8 *data, size_t length) { if (data != NULL && length == 4) { time_t time = (time_t) (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); @@ -88,7 +88,7 @@ char *prettify_date(u8 *data, size_t length) #define BCD2CHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) /* prettify OpenPGP card version */ -char *prettify_version(u8 *data, size_t length) +char *prettify_version(const u8 *data, size_t length) { if (data != NULL && length >= 2) { static char result[10]; /* large enough for even 2*3 digits + separator */ @@ -103,7 +103,7 @@ char *prettify_version(u8 *data, size_t length) /* prettify manufacturer */ -char *prettify_manufacturer(u8 *data, size_t length) +char *prettify_manufacturer(const u8 *data, size_t length) { if (data != NULL && length >= 2) { unsigned int manuf = (data[0] << 8) + data[1]; @@ -147,7 +147,7 @@ char *prettify_manufacturer(u8 *data, size_t length) /* prettify pure serial number */ -char *prettify_serialnumber(u8 *data, size_t length) +char *prettify_serialnumber(const u8 *data, size_t length) { if (data != NULL && length >= 4) { static char result[15]; /* large enough for even 2*3 digits + separator */ @@ -159,11 +159,14 @@ char *prettify_serialnumber(u8 *data, size_t length) /* prettify card holder's name */ -char *prettify_name(u8 *data, size_t length) +char *prettify_name(const u8 *data, size_t length) { if (data != NULL && length > 0) { + static char result[100]; /* should be large enough */ char *src = (char *) data; - char *dst = (char *) data; + char *dst = result; + if (length > sizeof(result) - 1) + length = sizeof(result) - 1; while (*src != '\0' && length > 0) { *dst = *src++; @@ -178,37 +181,35 @@ char *prettify_name(u8 *data, size_t length) dst++; } *dst = '\0'; - return (char *) data; + return result; } return NULL; } /* prettify language */ -char *prettify_language(u8 *data, size_t length) +char *prettify_language(const u8 *data, size_t length) { if (data != NULL && length > 0) { - char *str = (char *) data; - - switch (strlen(str)) { - case 8: memmove(str+7, str+6, 1+strlen(str+6)); - str[6] = ','; - /* fall through */ - case 6: memmove(str+5, str+4, 1+strlen(str+4)); - str[4] = ','; - /* fall through */ - case 4: memmove(str+3, str+2, 1+strlen(str+2)); - str[2] = ','; - /* fall through */ - case 2: return str; + static char result[12]; /* 8 chars, 3 separators, 1 null */ + char *src = (char *) data; + size_t used_length = strnlen(src, length) >> 1; + int i = 0; + + while (used_length) { + used_length--; + result[i++] = *src++; + result[i++] = *src++; + result[i++] = used_length ? ',' : '\0'; } + return result; } return NULL; } /* convert the raw ISO-5218 SEX value to an english word */ -char *prettify_gender(u8 *data, size_t length) +char *prettify_gender(const u8 *data, size_t length) { if (data != NULL && length > 0) { switch (*data) { diff --git a/src/tools/openpgp-tool-helpers.h b/src/tools/openpgp-tool-helpers.h index ec3b426c81..1c47b6e207 100644 --- a/src/tools/openpgp-tool-helpers.h +++ b/src/tools/openpgp-tool-helpers.h @@ -24,15 +24,15 @@ #include "util.h" -char *prettify_hex(u8 *data, size_t length, char *buffer, size_t buflen); -char *prettify_algorithm(u8 *data, size_t length); -char *prettify_date(u8 *data, size_t length); -char *prettify_version(u8 *data, size_t length); -char *prettify_manufacturer(u8 *data, size_t length); -char *prettify_serialnumber(u8 *data, size_t length); -char *prettify_name(u8 *data, size_t length); -char *prettify_language(u8 *data, size_t length); -char *prettify_gender(u8 *data, size_t length); +char *prettify_hex(const u8 *data, size_t length, char *buffer, size_t buflen); +char *prettify_algorithm(const u8 *data, size_t length); +char *prettify_date(const u8 *data, size_t length); +char *prettify_version(const u8 *data, size_t length); +char *prettify_manufacturer(const u8 *data, size_t length); +char *prettify_serialnumber(const u8 *data, size_t length); +char *prettify_name(const u8 *data, size_t length); +char *prettify_language(const u8 *data, size_t length); +char *prettify_gender(const u8 *data, size_t length); #endif /* OPENPGP_TOOL_HELPERS_H */ diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index de62866fa1..9cf8982330 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -71,7 +71,7 @@ struct ef_name_map { enum code_types type; size_t offset; size_t length; /* exact length: 0 <=> potentially infinite */ - char *(*prettify_value)(u8 *, size_t); + char *(*prettify_value)(const u8 *, size_t); }; /* declare functions */ From 65781d6c3765d1c1210f25823f1829c43e62b94a Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Tue, 14 Sep 2021 23:36:39 +0000 Subject: [PATCH 2032/4321] tools: Add EDDSA support in openpgp-tool's prettify_algorithm. --- src/tools/openpgp-tool-helpers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/openpgp-tool-helpers.c b/src/tools/openpgp-tool-helpers.c index c5f862faff..082b0e474b 100644 --- a/src/tools/openpgp-tool-helpers.c +++ b/src/tools/openpgp-tool-helpers.c @@ -58,6 +58,10 @@ char *prettify_algorithm(const u8 *data, size_t length) strcpy(result, "ECDSA"); return result; } + else if (data[0] == 0x16) { /* EDDSA */ + strcpy(result, "EDDSA"); + return result; + } } return NULL; } From daebea56120f3d1bc12ba7c1dab5f5787d432f7c Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Tue, 14 Sep 2021 11:37:52 +0000 Subject: [PATCH 2033/4321] tests: Add tests for openpgp-tool prettify_* functions. --- .gitignore | 1 + src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/openpgp-tool.c | 168 +++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 src/tests/unittests/openpgp-tool.c diff --git a/.gitignore b/.gitignore index b135fe6fcc..cf497a070f 100644 --- a/.gitignore +++ b/.gitignore @@ -123,6 +123,7 @@ src/tests/unittests/*.trs src/tests/unittests/asn1 src/tests/unittests/cachedir src/tests/unittests/compression +src/tests/unittests/openpgp-tool src/tests/unittests/pkcs15filter src/tests/unittests/simpletlv src/tests/unittests/sm diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 5b200bc8d3..da670dd500 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -6,8 +6,8 @@ include $(top_srcdir)/aminclude_static.am clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean -noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter -TESTS = asn1 simpletlv cachedir pkcs15filter +noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool +TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool noinst_HEADERS = torture.h @@ -24,6 +24,7 @@ asn1_SOURCES = asn1.c simpletlv_SOURCES = simpletlv.c cachedir_SOURCES = cachedir.c pkcs15filter_SOURCES = pkcs15-emulator-filter.c +openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/openpgp-tool.c b/src/tests/unittests/openpgp-tool.c new file mode 100644 index 0000000000..9b944f7eee --- /dev/null +++ b/src/tests/unittests/openpgp-tool.c @@ -0,0 +1,168 @@ +/* + * openpgp-tool.c: Test various functions of openpgp-tool + * + * Copyright (C) 2021 Vincent Pelletier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "torture.h" + +#include "tools/openpgp-tool-helpers.h" + +struct expectation { + const char *data; + size_t length; + const char *output; +}; + +static void torture_prettify(void **state, const struct expectation *cur, char *(prettify_func)(const u8 *data, size_t length)) +{ + char *output; + + while (cur->data != NULL) { + output = prettify_func((u8 *) cur->data, cur->length); + if (cur->output == NULL) + assert_null(output); + else { + assert_non_null(output); + assert_string_equal(output, cur->output); + } + cur++; + } +} + +const struct expectation expectations_algorithm[] = { + { "", 0, NULL }, + { "\x12\x2b\x06\x01\x04\x01\x97\x55\x01\x05\x01", 11, "ECDH" }, + { "\x01\x08\x00\x00\x20\x00", 6, "RSA2048" }, + { NULL, 0, NULL } +}; + +static void torture_prettify_algorithm(void **state) +{ + torture_prettify(state, expectations_algorithm, prettify_algorithm); +} + +const struct expectation expectations_date[] = { + { "\x01\x02\x03", 3, NULL }, + { "\x12\x34\x56\x78", 4, "1979-09-05 22:51:36" }, + { "\x7f\xff\xff\xff", 4, "2038-01-19 03:14:07" }, + /* XXX: probably not a feature */ + { "\x80\x00\x00\x00", 4, "1901-12-13 20:45:52" }, + { NULL, 0, NULL } +}; + +static void torture_prettify_date(void **state) +{ + torture_prettify(state, expectations_date, prettify_date); +} + +const struct expectation expectations_version[] = { + { "\x01", 1, NULL }, + { "\x03\x41", 2, "3.41" }, + { NULL, 0, NULL } +}; + +static void torture_prettify_version(void **state) +{ + torture_prettify(state, expectations_version, prettify_version); +} + +const struct expectation expectations_manufacturer[] = { + { "\x01", 1, NULL }, + { "\xf5\x17", 2, "FSIJ" }, + { "\xff\x00", 2, "unmanaged S/N range" }, + { "\xff\x7f", 2, "unmanaged S/N range" }, + { "\xff\xfe", 2, "unmanaged S/N range" }, + { "\xff\xff", 2, "test card" }, + /* Number picked by a fair dice roll among unregistered numbers */ + { "\x81\x88", 2, "unknown" }, + { NULL, 0, NULL } +}; + +static void torture_prettify_manufacturer(void **state) +{ + torture_prettify(state, expectations_manufacturer, prettify_manufacturer); +} + +const struct expectation expectations_serialnumber[] = { + { "\x00\x00\x00", 3, NULL }, + { "\x12\x34\x56\x78", 4, "12345678" }, + { "\x80\x00\x00\x00", 4, "80000000" }, + { NULL, 0, NULL } +}; + +static void torture_prettify_serialnumber(void **state) +{ + torture_prettify(state, expectations_serialnumber, prettify_serialnumber); +} + +const struct expectation expectations_name[] = { + { "", 0, NULL }, + { "John Doe", 8, "John Doe" }, + { "John Date: Thu, 29 Jul 2021 17:13:01 +0200 Subject: [PATCH 2034/4321] fix Key Lenght for ST2021 --- src/libopensc/card-itacns.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index bf085cafbc..52e144f194 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -105,7 +105,7 @@ static int itacns_match_cns_card(sc_card_t *card, unsigned int i) DRVDATA(card)->cns_version = atr[i]; } /* Warn if the version is not 1.0. */ - if(atr[i] != 0x10) { + if(atr[i] != 0x10 && atr[i] != 0x11) { char version[8]; snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); sc_log(card->ctx, "CNS card version %s; no official specifications " @@ -219,8 +219,13 @@ static int itacns_init(sc_card_t *card) | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASHES ; + _sc_card_add_rsa_alg(card, 1024, flags, 0); + if (DRVDATA(card)->cns_version == 0x11) { + card->caps |= SC_CARD_CAP_APDU_EXT; + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } return SC_SUCCESS; } From 1dc9ab91fe7c84a079bedca41c752cb619eb8f2e Mon Sep 17 00:00:00 2001 From: 0xdebe Date: Thu, 29 Jul 2021 17:13:16 +0200 Subject: [PATCH 2035/4321] fix Modulus Lenght for ST2021 --- src/libopensc/pkcs15-itacns.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 9c9b40a591..875b12276d 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -283,7 +283,16 @@ static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, * This is hard-coded, unless unforeseen versions of the CNS * turn up sometime. */ - info.modulus_length = 1024; + + /* This is the unforseen version :D */ + if (((itacns_drv_data_t *) p15card->card->drv_data)->cns_version == 0x11) { + info.modulus_length = 2048; + } + else { + info.modulus_length = 1024; + } + + *modulus_len_out = info.modulus_length; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info); @@ -590,6 +599,10 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, /* This is hard-coded, for the time being. */ int modulus_length = 1024; + /* it's a ST2021? */ + if (((itacns_drv_data_t *) p15card->card->drv_data)->cns_version == 0x11) { + modulus_length = 2048; + } /* Public key; not really needed */ /* FIXME: set usage according to the certificate. */ From eb94d0416da63d757ab17709ab6b68cd13ce316c Mon Sep 17 00:00:00 2001 From: 0xdebe Date: Sat, 31 Jul 2021 16:25:58 +0200 Subject: [PATCH 2036/4321] fix modulus len --- src/libopensc/card-itacns.c | 2 +- src/libopensc/pkcs15-itacns.c | 43 ++++++++++++----------------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 52e144f194..b26f9d3317 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -104,7 +104,7 @@ static int itacns_match_cns_card(sc_card_t *card, unsigned int i) if(card->driver) { DRVDATA(card)->cns_version = atr[i]; } - /* Warn if the version is not 1.0. */ + /* Warn if version is not 1.X. */ if(atr[i] != 0x10 && atr[i] != 0x11) { char version[8]; snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 875b12276d..afdf459c4e 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -189,7 +189,7 @@ static int loadFile(const sc_pkcs15_card_t *p15card, const sc_path_t *path, static int itacns_add_cert(sc_pkcs15_card_t *p15card, int type, int authority, const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label, int obj_flags, - int *ext_info_ok, int *key_usage, int *x_key_usage) + int *ext_info_ok, int *key_usage, int *x_key_usage, int *modulus_len) { int r; /* const char *label = "Certificate"; */ @@ -237,6 +237,11 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, const u8 *throwaway = cert->data.value; x509 = d2i_X509(NULL, &throwaway, cert->data.len); } + + if (cert->key && cert->key->algorithm == SC_ALGORITHM_RSA) { + *modulus_len = cert->key->u.rsa.modulus.len * 8; + } + sc_pkcs15_free_certificate(cert); if (!x509) return SC_SUCCESS; X509_check_purpose(x509, -1, 0); @@ -260,7 +265,7 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label, - int usage, int ref, int obj_flags, int *modulus_len_out) + int usage, int ref, int obj_flags, int modulus_len) { int r; sc_pkcs15_pubkey_info_t info; @@ -279,22 +284,8 @@ static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, strlcpy(obj.label, label, sizeof(obj.label)); obj.flags = obj_flags; - /* - * This is hard-coded, unless unforeseen versions of the CNS - * turn up sometime. - */ - - /* This is the unforseen version :D */ - if (((itacns_drv_data_t *) p15card->card->drv_data)->cns_version == 0x11) { - info.modulus_length = 2048; - } - else { - info.modulus_length = 1024; - } + info.modulus_length = modulus_len; - - - *modulus_len_out = info.modulus_length; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info); LOG_TEST_RET(p15card->card->ctx, r, "Could not add pub key"); @@ -589,7 +580,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, const char *label, int sec_env, sc_pkcs15_id_t *cert_id, const char *pubkey_path, const char *prkey_path, unsigned int pubkey_usage_flags, unsigned int prkey_usage_flags, - u8 pin_ref) + u8 pin_ref, int modulus_len) { int r; sc_path_t path; @@ -597,19 +588,13 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, char pinlabel[16]; int fake_puk_authid, pin_flags; - /* This is hard-coded, for the time being. */ - int modulus_length = 1024; - /* it's a ST2021? */ - if (((itacns_drv_data_t *) p15card->card->drv_data)->cns_version == 0x11) { - modulus_length = 2048; - } /* Public key; not really needed */ /* FIXME: set usage according to the certificate. */ if (pubkey_path) { sc_format_path(pubkey_path, &path); r = itacns_add_pubkey(p15card, &path, cert_id, label, - pubkey_usage_flags, sec_env, 0, &modulus_length); + pubkey_usage_flags, sec_env, 0, modulus_len); LOG_TEST_RET(p15card->card->ctx, r, "Could not add public key"); } @@ -623,7 +608,7 @@ static int itacns_add_keyset(sc_pkcs15_card_t *p15card, private_path = &path; } r = itacns_add_prkey(p15card, cert_id, label, SC_PKCS15_TYPE_PRKEY_RSA, - modulus_length, + modulus_len, prkey_usage_flags, private_path, sec_env, cert_id, SC_PKCS15_CO_FLAG_PRIVATE); LOG_TEST_RET(p15card->card->ctx, r, @@ -674,7 +659,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, sc_path_t path; sc_pkcs15_id_t cert_id; int ext_info_ok; - int ku = 0, xku = 0; + int ku = 0, xku = 0, modulus_len = 0; int pubkey_usage_flags = 0, prkey_usage_flags = 0; cert_id.len = 1; @@ -720,7 +705,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, } r = itacns_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, 0, - &path, &cert_id, label, 0, &ext_info_ok, &ku, &xku); + &path, &cert_id, label, 0, &ext_info_ok, &ku, &xku, &modulus_len); if (r == SC_ERROR_INVALID_ASN1_OBJECT) return 0; LOG_TEST_RET(p15card->card->ctx, r, @@ -765,7 +750,7 @@ static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, r = itacns_add_keyset(p15card, label, sec_env, &cert_id, pubkey_path, prkey_path, pubkey_usage_flags, prkey_usage_flags, - pin_ref); + pin_ref, modulus_len); LOG_TEST_RET(p15card->card->ctx, r, "Could not add keys for this certificate"); From 548a2036328a288d24a48797498c3f76d6e351ef Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 15 Sep 2021 10:41:10 +0200 Subject: [PATCH 2037/4321] Allow compilation with older PC/SC This was mostly done in 9ed5f63, but this instance of the code SCARD_E_NO_READERS_AVAILABLE was overlooked. --- src/libopensc/reader-pcsc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 052f668592..99887852d7 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -182,8 +182,10 @@ static int pcsc_to_opensc_error(LONG rv) return SC_ERROR_CARD_UNRESPONSIVE; case SCARD_E_SHARING_VIOLATION: return SC_ERROR_READER_LOCKED; +#ifdef SCARD_E_NO_READERS_AVAILABLE case SCARD_E_NO_READERS_AVAILABLE: return SC_ERROR_NO_READERS_FOUND; +#endif case SCARD_E_UNKNOWN_READER: return SC_ERROR_READER_DETACHED; From a1d64c013099d7a35334419e73b531834b05da0b Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Sep 2021 13:22:47 +0200 Subject: [PATCH 2038/4321] dos2unix These two files have CRLF Windows line endings, while all other files have LF Unix line endings. Change to LF for consistency. --- src/smm/sm-common.exports | 5 ++--- src/smm/smm-local.exports | 12 ++++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/smm/sm-common.exports b/src/smm/sm-common.exports index 35d4cdb090..f54389bd33 100644 --- a/src/smm/sm-common.exports +++ b/src/smm/sm-common.exports @@ -1,3 +1,2 @@ -sm_cwa_get_mac -sm_cwa_securize_apdu - +sm_cwa_get_mac +sm_cwa_securize_apdu diff --git a/src/smm/smm-local.exports b/src/smm/smm-local.exports index 7c131b8bf9..98d9c15fb2 100644 --- a/src/smm/smm-local.exports +++ b/src/smm/smm-local.exports @@ -1,6 +1,6 @@ -initialize -get_apdus -finalize -module_cleanup -module_init -test +initialize +get_apdus +finalize +module_cleanup +module_init +test From 9279e04806783342c4a526243979fab0bd81a69d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:43:32 +0200 Subject: [PATCH 2039/4321] Fix typos found by codespell --- doc/tools/opensc-explorer.1.xml | 2 +- src/libopensc/asn1.c | 2 +- src/libopensc/card-openpgp.c | 4 ++-- src/libopensc/card-piv.c | 4 ++-- src/libopensc/card-setcos.c | 2 +- src/libopensc/card-starcos.c | 2 +- src/libopensc/cwa-dnie.c | 2 +- src/libopensc/cwa14890.c | 2 +- src/libopensc/pkcs15-sec.c | 2 +- src/pkcs11/framework-pkcs15.c | 4 ++-- win32/winconfig.h.in | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 30aed11298..1f0d4243ea 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -485,7 +485,7 @@ List files in the current DF. If no pattern is given, then all files are listed. - If one ore more patterns are given, + If one or more patterns are given, only files matching at least one pattern are listed. diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 0ceeedf2f6..257952fccf 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1689,7 +1689,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, size_t left = len, objlen; sc_debug(ctx, SC_LOG_DEBUG_ASN1, - "%*.*scalled, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n", + "%*.*s""called, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n", depth, depth, "", left, depth, choice ? ", choice" : ""); if (!p) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e986226669..e72dfbe15d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -806,7 +806,7 @@ pgp_get_card_features(sc_card_t *card) for (i = 0x00c1; i <= 0x00c3; i++) { sc_cardctl_openpgp_keygen_info_t key_info; - sc_log(card->ctx, "Parsing algorithm attribues DO %zX" , i); + sc_log(card->ctx, "Parsing algorithm attributes DO %zX" , i); /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && @@ -2275,7 +2275,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, } pklen = r; - /* Calculate lenght of Public Key DO (0x7F49) */ + /* Calculate length of Public Key DO (0x7F49) */ r = sc_asn1_put_tag(0x7f49, NULL, pklen, NULL, 0, NULL); if (r <= 0) { free(temp); diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 8835078587..0819c9157b 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1927,7 +1927,7 @@ static int piv_general_external_authenticate(sc_card_t *card, goto err; } - /* Store this to sanity check that plaintext length and cyphertext lengths match */ + /* Store this to sanity check that plaintext length and ciphertext lengths match */ /* TODO is this required */ tmplen = challenge_len; @@ -3748,7 +3748,7 @@ static int piv_logout(sc_card_t *card) /* * Called when a sc_lock gets a reader lock and PCSC SCardBeginTransaction - * If SCardBeginTransaction may pass back tha a card reset was seen since + * If SCardBeginTransaction may pass back that a card reset was seen since * the last transaction completed. * There may have been one or more resets, by other card drivers in different * processes, and they may have taken action already diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 859f72fd20..5d72dc126c 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -436,7 +436,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) /* Set file creation status */ sc_file_set_prop_attr(file, &bFileStatus, 1); - /* Build ACI from local structure = get AC for each operation group */ + /* Build ACL from local structure = get AC for each operation group */ if (file->sec_attr_len == 0) { const int* p_idx; int i; diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 85d118118b..22ca49ba01 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -137,7 +137,7 @@ static const char * starcos_ef_pwdd = "3F000015"; static const char * starcos_ef_keyd = "3F000013"; /** - * Parses supported securiy mechanisms record data. + * Parses supported security mechanisms record data. * It returns SC_SUCCESS and the ctrl_ref_template structure data on success */ static int starcos_parse_supported_sec_mechanisms(struct sc_card *card, const unsigned char * buf, size_t buflen, starcos_ctrl_ref_template * ctrl_ref_template) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 927b5871c9..b8e39b305f 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -612,7 +612,7 @@ static int dnie_read_certificate(sc_card_t * card, char *certpath, X509 ** cert) * Just created in case this will be modified. * * @param card Pointer to card driver structure - * @param data The data for the channel will be assined here + * @param data The data for the channel will be assigned here * @return SC_SUCCESS if ok; else error code */ static int dnie_get_channel_data(sc_card_t * card, dnie_channel_data_t ** data) { diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 88f68b85e2..3ca3f2f2e4 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -108,7 +108,7 @@ static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag) * @param card smart card info structure * @return SC_SUCCESS if ok; else error code * - * TODO: to further study: what about using bignum arithmetics? + * TODO: to further study: what about using bignum arithmetic? */ static int cwa_increase_ssc(sc_card_t * card) { diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 9c44907c9f..b8c4751379 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -691,7 +691,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } - /* ECDSA sofware hash has already been done, or is not needed, or card will do hash */ + /* ECDSA software hash has already been done, or is not needed, or card will do hash */ /* if card can not do the hash, will use SC_ALGORITHM_ECDSA_RAW */ if (obj->type == SC_PKCS15_TYPE_PRKEY_EC) { if ((alg_info->flags & SC_ALGORITHM_ECDSA_RAW) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 521fbecfef..74fe7b3c49 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -834,7 +834,7 @@ __pkcs15_create_data_object(struct pkcs15_fw_data *fw_data, return rv; } -/* Note, that this is not actuall PKCS #15 object, but just bogus +/* Note, that this is not an actual PKCS #15 object, but just a bogus * structure to create PKCS #11 object. There is no corresponding * PKCS #15 object. */ static int @@ -1194,7 +1194,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, ")", 32 - max_tokeninfo_len-2-pin_len); } } else { - /* PIN label is empty or just says non-useful "PIN", + /* PIN label is empty or just says useless "PIN", * print only token label */ strcpy_bp(slot->token_info.label, p15card->tokeninfo ? p15card->tokeninfo->label : "", diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index fa682c5bcc..de053c016d 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -33,7 +33,7 @@ #ifndef R_OK #define R_OK 4 /* test whether readable. */ #define W_OK 2 /* test whether writable. */ -#define X_OK 1 /* test whether execubale. */ +#define X_OK 1 /* test whether executable. */ #define F_OK 0 /* test whether exist. */ #endif From 2c526d65face1e66345e06a284cdd9d8e0cfd773 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:43:59 +0200 Subject: [PATCH 2040/4321] Add codespell to CI to find typos early --- .github/workflows/codespell.yml | 18 ++++++++++++++++++ CONTRIBUTING.md | 20 ++++++++++++++++++++ codespell_ignore_words.txt | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 .github/workflows/codespell.yml create mode 100644 codespell_ignore_words.txt diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000000..32d2809942 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,18 @@ +--- +name: Codespell + +on: + pull_request: + push: + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: codespell-project/actions-codespell@master + with: + skip: compat_* + ignore_words_file: codespell_ignore_words.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2fbea403dd..f1fc4feca5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,26 @@ To learn how to run the tests from Github actions locally in containers, see [`containers`](containers/README.md). +# Spelling + +One of the GitHub actions checks spelling using +[codespell](https://github.com/codespell-project/codespell). +If you need to ignore some words, such as variable names or +words in languages other than English, add them to file +`codespell_ignore_words.txt`. + +Note that [codespell](https://github.com/codespell-project/codespell#usage) +expects words to be lower case: +> **Important note:** The list passed to -I is case-sensitive +> based on how it is listed in the codespell dictionaries. + +After installing +[codespell](https://github.com/codespell-project/codespell#installation), +you can run it from the command line as: +```sh +codespell -I codespell_ignore_words.txt +``` + # Release process The release process is described in [OpenSC wiki](https://github.com/OpenSC/OpenSC/wiki/OpenSC-Release-Howto) diff --git a/codespell_ignore_words.txt b/codespell_ignore_words.txt new file mode 100644 index 0000000000..35bebfe400 --- /dev/null +++ b/codespell_ignore_words.txt @@ -0,0 +1,22 @@ +ans +ba +comandos +componentes +datas +direccion +ede +fase +feld +gost +hist +ist +keypair +nmake +oder +parm +parms +requiere +responde +sie +signatur +standarts From b2a84f2e1ec15bd38e410811544685d91189e778 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Sep 2021 22:27:25 +0200 Subject: [PATCH 2041/4321] Fix LGTM.com warning: Comparison result is always the same Comparison is always true because r <= -1. Indeed in this branch: !(r > 0) && !(r== 0) => r < 0 --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 0819c9157b..c0aaf9c2c7 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -994,7 +994,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) r = SC_ERROR_FILE_NOT_FOUND; priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID; priv->obj_cache[enumtag].obj_len = 0; - } else if ( r < 0) { + } else { goto err; } } From e585fa079d7ca9bf9bf96dc325be25dec5e1fded Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 15 Sep 2021 22:41:59 +0200 Subject: [PATCH 2042/4321] Fix LGTM.com warning: Comparison result is always the same Comparison is always true because r <= -1. Indeed in this branch we already have: r < 0 --- src/pkcs15init/pkcs15-isoApplet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 8d2fec3adc..41b4dcfd42 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -576,7 +576,7 @@ isoApplet_generate_key_ec(const sc_pkcs15_prkey_info_t *key_info, sc_card_t *car pubkey->u.ec.params.der.value = NULL; pubkey->u.ec.params.der.len = 0; } - if(r < 0 && pubkey->u.ec.ecpointQ.value) + if(pubkey->u.ec.ecpointQ.value) { free(pubkey->u.ec.ecpointQ.value); pubkey->u.ec.ecpointQ.value = NULL; From cc9476f8977130054ef512f3aafa689415157699 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 11 Sep 2021 17:30:58 +0200 Subject: [PATCH 2043/4321] muscle: Remove dead code Dead code since d672fde4499fef4380cc3d8b88e496986687ec03 Thanks lgtm.com --- src/libopensc/card-muscle.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 67ccaa39f8..7dfe9ddbbe 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -299,9 +299,6 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) oid[2] = oid[3] = 0; /* ??? objectId = objectId >> 16; */ } - if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4)) - || (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) { - } r = msc_delete_object(card, id, 1); /* Check if its the root... this file generally is virtual * So don't return an error if it fails */ From 765d8c05a81179440fe5afc4beac482a3a9ac85f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 11 Sep 2021 17:50:47 +0200 Subject: [PATCH 2044/4321] Add lgtm configuration This helps to label the source code files and prevents some errors we do do not care about. --- .lgtm.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .lgtm.yml diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 0000000000..1795956542 --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,21 @@ +path_classifiers: + test: + - tests/ + - src/tests/ + generated: + - "src/tools/*-cmdline.*" + library: + - src/libopensc/ + - src/common/ + - src/minidriver/ + - src/pkcs11/ + - src/pkcs15init/ + - src/scconf/ + - src/sm/ + - src/smm/ + tools: + - src/tools/ +queries: + # This reports all the uses of the DES, but this is needed for + # interoperability with cards not supporting AES + - exclude: cpp/weak-cryptographic-algorithm From 974463ec7ed2ff88ff221e432a18bdc597c4667e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 11 Sep 2021 18:20:28 +0200 Subject: [PATCH 2045/4321] Try to exclude javascript analysis --- .lgtm.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.lgtm.yml b/.lgtm.yml index 1795956542..3798874734 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -19,3 +19,8 @@ queries: # This reports all the uses of the DES, but this is needed for # interoperability with cards not supporting AES - exclude: cpp/weak-cryptographic-algorithm +extraction: + javascript: + index: + filters: + exclude: **/ From f7906173276bf2b91eb0d80ecb58c7c9ac15fd43 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Sep 2021 11:19:47 +0200 Subject: [PATCH 2046/4321] pkcs11: Pass the unwrap flags to pkcs15 layer Fixes: #1595 --- src/pkcs11/framework-pkcs15.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 74fe7b3c49..3c77ad55db 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4279,7 +4279,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; struct pkcs15_any_object *targetKeyObj = (struct pkcs15_any_object *) targetKey; - int rv; + int rv, flags = 0; sc_log(context, "Initiating unwrapping with private key."); @@ -4305,8 +4305,6 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); -#if 0 - /* FIXME https://github.com/OpenSC/OpenSC/issues/1595 */ /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_RSA_PKCS: @@ -4318,7 +4316,6 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, default: return CKR_MECHANISM_INVALID; } -#endif rv = sc_lock(p11card->card); @@ -4326,7 +4323,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(rv, "C_UnwrapKey"); /* Call the card to do the unwrap operation */ - rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->p15_object, 0, + rv = sc_pkcs15_unwrap(fw_data->p15_card, prkey->prv_p15obj, targetKeyObj->p15_object, flags, pWrappedKey, ulWrappedKeyLen, NULL, 0); sc_unlock(p11card->card); From 9498c0aedb72cd3154648fd83c783eb11885a28f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Sep 2021 11:55:24 +0200 Subject: [PATCH 2047/4321] Add OsEID containerfile --- containers/opensc-test-oseid/Containerfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 containers/opensc-test-oseid/Containerfile diff --git a/containers/opensc-test-oseid/Containerfile b/containers/opensc-test-oseid/Containerfile new file mode 100644 index 0000000000..4938143e96 --- /dev/null +++ b/containers/opensc-test-oseid/Containerfile @@ -0,0 +1,13 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh oseid +RUN /src/.github/build.sh +CMD /src/.github/test-oseid.sh From 5aefe4554f1289cdd6833324583355c89c59f042 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 15 Sep 2021 09:59:05 +0200 Subject: [PATCH 2048/4321] NEWS: Fix typo --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a9215cdaec..965203b3e4 100644 --- a/NEWS +++ b/NEWS @@ -262,7 +262,7 @@ New separate CAC1 driver using the old CAC specification (#1502) * added support for reading ECDSA ssh keys * `p11test` * Filter certificates other than `CKC_X_509` -* `opengpg-tool` +* `openpgp-tool` * allow calling -d multiple times * clarify usage text ## sc-hsm From 764056ab6245ff81e6fab0f6aa0218aac90035f2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Jul 2021 19:15:36 +0200 Subject: [PATCH 2049/4321] Avoid black/whitelist terms in documentation and comments --- doc/files/files.html | 2 +- doc/files/opensc.conf.5.xml.in | 2 +- etc/opensc.conf.example.in | 2 +- src/libopensc/iso7816.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index f0c877e1c2..a07c0b2858 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -177,7 +177,7 @@

    card_drivers = name... ;

    - Whitelist of card drivers to load at start-up. + Allowlist of card drivers to load at start-up. The special value internal (the default) will load all statically linked drivers.

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 467b10e07a..17006d53a8 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -209,7 +209,7 @@ app application { rep="repeat">name; - Whitelist of card drivers to load at start-up. + Allowlist of card drivers to load at start-up. The special value internal (the default) will load all statically linked drivers. diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index ec9bc8d57d..499531731b 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -133,7 +133,7 @@ app default { # max_recv_size = 65536; } - # Whitelist of card drivers to load at start-up + # Allowlist of card drivers to load at start-up # # The supported internal card driver names can be retrieved # from the output of: diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 504c4711d3..55edb676fd 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1165,8 +1165,8 @@ iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_l /* Many cards do support PIN status queries, but some cards don't and * mistakenly count the command as a failed PIN attempt, so for now we - * whitelist cards with this flag. In future this may be reduced to a - * blacklist, subject to testing more cards. */ + * allow cards with this flag. In future this may be reduced to a + * blocklist, subject to testing more cards. */ if (data->cmd == SC_PIN_CMD_GET_INFO && !(card->caps & SC_CARD_CAP_ISO7816_PIN_INFO)) { sc_log(card->ctx, "Card does not support PIN status queries"); From 6b5699c32f81a17b3ffa8f939a8ce71e39de2c85 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 13:33:26 +0200 Subject: [PATCH 2050/4321] pkcs11: Unbreak detection of unenrolled cards This was broken since 58b03b68, which tried to sanitize some states, but caused C_GetTokenInfo returning CKR_TOKEN_NOT_RECOGNIZED instead of empty token information. Note, that this has effect only if the configuration options enable_default_driver and pkcs11_enable_InitToken are turned on. Otherwise it still returns CKR_TOKEN_NOT_RECOGNIZED. --- src/pkcs11/framework-pkcs15.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3c77ad55db..5a3cb99e37 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -544,9 +544,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { struct sc_pkcs11_slot *slot; struct pkcs15_fw_data *fw_data = NULL; - struct sc_pkcs15_card *p15card = NULL; struct sc_pkcs15_object *auth; - struct sc_pkcs15_auth_info *pin_info; const char *name; CK_RV rv; @@ -578,12 +576,6 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) rv = sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetTokenInfo"); goto out; } - p15card = fw_data->p15_card; - if (!p15card) { - rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo"); - goto out; - } - /* User PIN flags are cleared before re-calculation */ slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED); auth = slot_data_auth(slot->fw_data); @@ -591,8 +583,17 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, slot->token_info.flags); if (auth) { + struct sc_pkcs15_card *p15card = NULL; + struct sc_pkcs15_auth_info *pin_info = NULL; + pin_info = (struct sc_pkcs15_auth_info*) auth->data; + p15card = fw_data->p15_card; + if (!p15card) { + rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo"); + goto out; + } + sc_pkcs15_get_pin_info(p15card, auth); if (pin_info->tries_left >= 0) { From 6bfdceeabc9a8687e2034a05200e13bd2b79c040 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 14:41:17 +0200 Subject: [PATCH 2051/4321] .github: Test with master version of vsmartcard --- .github/setup-vsmartcard.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh index 0fd22b7bb9..a9049d24a5 100755 --- a/.github/setup-vsmartcard.sh +++ b/.github/setup-vsmartcard.sh @@ -6,6 +6,5 @@ if [ ! -d "vsmartcard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git fi pushd vsmartcard/virtualsmartcard -git checkout -b tag-0.8 virtualsmartcard-0.8 autoreconf -vis && ./configure && make -j2 && sudo make install popd From 82ec025ba16030daf2fc6326a82d0c7a82dac694 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 14:44:08 +0200 Subject: [PATCH 2052/4321] .github: Better test if systemd is available --- .github/restart-pcscd.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/restart-pcscd.sh b/.github/restart-pcscd.sh index eaa2dab56d..65963ca495 100644 --- a/.github/restart-pcscd.sh +++ b/.github/restart-pcscd.sh @@ -7,7 +7,7 @@ function pcscd_cleanup { echo "Process terminated: resetting pcscd" sudo pkill pcscd - if which systemctl; then + if which systemctl && systemctl is-system-running; then sudo systemctl start pcscd.socket fi } @@ -15,7 +15,7 @@ trap pcscd_cleanup EXIT # stop the pcscd service and run it from console to see possible errors -if which systemctl; then +if which systemctl && systemctl is-system-running; then sudo systemctl stop pcscd.service pcscd.socket else sudo pkill pcscd || echo "no pcscd process was running" From 4ba1198ef82148d9bdc5f6bf570c113eaac00c1a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 14:46:16 +0200 Subject: [PATCH 2053/4321] .github: Do not break on existing directories --- .github/test-isoapplet.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 2ba4014605..8c45693c34 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -10,7 +10,9 @@ export LD_LIBRARY_PATH=/usr/local/lib ./.github/setup-java.sh # The ISO applet -git clone https://github.com/philipWendland/IsoApplet.git; +if [ ! -d IsoApplet ]; then + git clone https://github.com/philipWendland/IsoApplet.git; +fi javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java; echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg; echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg; From 06630633efe2cd7e781ce3a6b68c8e8047802955 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 15:10:47 +0200 Subject: [PATCH 2054/4321] .github: Reference the upstream PR fixing unstable jcarsim test --- .github/setup-java.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 6981790bb1..679cca3156 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -14,6 +14,7 @@ env | grep -i openjdk # Javacard SDKs if [ ! -d "oracle_javacard_sdks" ]; then + # https://github.com/licel/jcardsim/pull/174 git clone https://github.com/martinpaljak/oracle_javacard_sdks.git fi export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit From 13d841e1c6f7317b6bb7f419fad9440d0afdc146 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 15:11:20 +0200 Subject: [PATCH 2055/4321] .github: Run p11tests for isoapplet --- .github/test-isoapplet.sh | 9 + src/tests/p11test/isoapplet_ref.json | 364 +++++++++++++++++++++++++++ 2 files changed, 373 insertions(+) create mode 100644 src/tests/p11test/isoapplet_ref.json diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 8c45693c34..c4eaaff682 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -39,4 +39,13 @@ pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-i pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456; pkcs15-tool -D; pkcs11-tool -l -t -p 123456; + +# run the tests +pushd src/tests/p11test/ +sleep 5 +./p11test -s 0 -p 123456 -o isoapplet.json || true # ec_sign_size_test is failing here +popd + kill -9 $PID; + +diff -u3 src/tests/p11test/isoapplet{_ref,}.json diff --git a/src/tests/p11test/isoapplet_ref.json b/src/tests/p11test/isoapplet_ref.json new file mode 100644 index 0000000000..787e2f7980 --- /dev/null +++ b/src/tests/p11test/isoapplet_ref.json @@ -0,0 +1,364 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RIPEMD160", + "0", + "0", + "CKF_DIGEST" + ], + [ + "GOSTR3411", + "0", + "0", + "CKF_DIGEST" + ], + [ + "ECDSA_SHA224", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA256", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA384", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA512", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA1", + "192", + "384", + "0x01902801" + ], + [ + "EC_KEY_PAIR_GEN", + "192", + "384", + "0x01910001" + ], + [ + "RSA_PKCS", + "2048", + "2048", + "0x00002A01" + ], + [ + "SHA1_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA224_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "MD5_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RIPEMD160_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "2048", + "2048", + "CKF_GENERATE_KEY_PAIR" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "RSA_PKCS", + "", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "fail_reason": "Some signatures were not verified successfully. Please review the log", + "result": "fail" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "01", + "Private Key", + "RSA", + "2048", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "02", + "Private Key", + "RSA", + "2048", + "", + "", + "", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "03", + "Private Key", + "EC", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "result": "unknown" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ]], + "result": "pass" +}] +} From 7c5f3d3fa5c0f5860b9e4cba75da2fd4646f989b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 15:47:24 +0200 Subject: [PATCH 2056/4321] .github: Avoid rebuilding jcardsim over and over again This is useful for container builds, but we should be able to cache it in github too as it is not changing too frequently. --- .github/setup-java.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 679cca3156..00394718aa 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -27,5 +27,7 @@ fi pushd jcardsim env | grep -i openjdk export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ -mvn initialize && mvn clean install +if [ ! -f target/jcardsim-3.0.5-SNAPSHOT.jar ]; then + mvn initialize && mvn clean install +fi popd From 98384f6b8824fd1758dcf60ede003758b9e0bcc1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 16:22:40 +0200 Subject: [PATCH 2057/4321] .github: Remove bogus semicolumns --- .github/test-isoapplet.sh | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index c4eaaff682..0f9106e84f 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -11,14 +11,14 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git; + git clone https://github.com/philipWendland/IsoApplet.git fi -javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java; -echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg; -echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg; -echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg; -echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg; -echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; +javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java +echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg +echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg +echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg +echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg +echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg # prepare pcscd @@ -27,18 +27,18 @@ echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg; # start the applet and run couple of commands against that java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & -PID=$!; -sleep 5; -opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100; -opensc-tool -n; -pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef; -pkcs15-tool --change-pin --pin 123456 --new-pin 654321; -pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456; -pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456; -pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456; -pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456; -pkcs15-tool -D; -pkcs11-tool -l -t -p 123456; +PID=$! +sleep 5 +opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100 +opensc-tool -n +pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef +pkcs15-tool --change-pin --pin 123456 --new-pin 654321 +pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456 +pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456 +pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456 +pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456 +pkcs15-tool -D +pkcs11-tool -l -t -p 123456 # run the tests pushd src/tests/p11test/ @@ -46,6 +46,6 @@ sleep 5 ./p11test -s 0 -p 123456 -o isoapplet.json || true # ec_sign_size_test is failing here popd -kill -9 $PID; +kill -9 $PID diff -u3 src/tests/p11test/isoapplet{_ref,}.json From 854d1ef350126c5871b3acfe72d7a52e04ac0c4c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Sep 2021 16:22:59 +0200 Subject: [PATCH 2058/4321] .github: Reproducer for initialized card detection --- .github/test-isoapplet.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 0f9106e84f..e23313498c 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -29,6 +29,26 @@ echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null & PID=$! sleep 5 + +# Does OpenSC see the uninitialized card? +pkcs11-tool -L | tee opensc.log +# report as "token not recognized" +grep "(token not recognized)" opensc.log + +# Does OpenSC see the uninitialized card with options for InitToken? +cat >opensc.conf < Date: Mon, 25 Oct 2021 10:49:55 +0200 Subject: [PATCH 2059/4321] Fix detection of 512 bit signtures (Fixes #2421) --- src/libopensc/card-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 126dfaf0bd..ee35f0d165 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1046,7 +1046,7 @@ static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, fieldsizebytes = 40; } else if (datalen <= 106) { // 384 bit curve = 48 * 2 + 10 byte maximum DER signature fieldsizebytes = 48; - } else if (datalen <= 138) { // 512 bit curve = 64 * 2 + 10 byte maximum DER signature + } else if (datalen <= 137) { // 512 bit curve = 64 * 2 + 9 byte maximum DER signature fieldsizebytes = 64; } else { fieldsizebytes = 66; From e5846333f8e915c68f05ccf0cdb1f74752af736d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 3 Oct 2021 17:54:38 +0200 Subject: [PATCH 2060/4321] fuzzing: Build test programs for fuzz targets when fuzzing is not enabled For testing purposes, fuzzers take files as input which feed LLVMFuzzerTestOneInput function. --- src/tests/fuzzing/Makefile.am | 15 ++++++---- src/tests/fuzzing/fuzzer.c | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 src/tests/fuzzing/fuzzer.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 509e672d32..33a929d0ef 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -1,15 +1,18 @@ AM_CPPFLAGS = -I$(top_srcdir)/src AM_CFLAGS = -g -O0 $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) -LIBS = $(FUZZING_LIBS) \ +LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la -if ENABLE_FUZZING noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader + +ADDITIONAL_SRC = +if !ENABLE_FUZZING +ADDITIONAL_SRC += fuzzer.c endif -fuzz_asn1_print_SOURCES = fuzz_asn1_print.c -fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c -fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c -fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c +fuzz_asn1_print_SOURCES = fuzz_asn1_print.c $(ADDITIONAL_SRC) +fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) +fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) +fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/fuzzer.c b/src/tests/fuzzing/fuzzer.c new file mode 100644 index 0000000000..6051599b43 --- /dev/null +++ b/src/tests/fuzzing/fuzzer.c @@ -0,0 +1,54 @@ +/* + * fuzz_scconf_parse.c: Fuzz target for scconf_parse + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); + +int main (int argc, char **argv) +{ + printf("Testing one input:\n"); + FILE *fd = NULL; + size_t len = 0; + unsigned char *buffer = NULL; + + if (argc < 2) { + fprintf(stderr, "No arguments, passing NULL\n"); + len = 0; + } else { + fd = fopen(argv[1], "r"); + fseek(fd, 0, SEEK_END); + len = ftell(fd); + rewind(fd); + buffer = (unsigned char*) malloc(len); + if (fread(buffer, 1, len, fd) != len) { + fprintf(stderr, "fread failed\n"); + } + fclose(fd); + } + + LLVMFuzzerTestOneInput(buffer, len); + if (buffer) + free(buffer); + printf("Done!\n"); + return 0; +} From 9cfd23062bc19366b8b4605485d71d898a2f7f91 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Oct 2021 14:08:47 +0200 Subject: [PATCH 2061/4321] fuzzing: Define FUZZING_ENABLED for closing stdout while fuzzing In case that called function print out some data --- configure.ac | 3 +++ src/tests/fuzzing/fuzz_asn1_print.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index 5e2e604c0b..d85b8fa218 100644 --- a/configure.ac +++ b/configure.ac @@ -703,6 +703,9 @@ if test "${enable_cmocka}" = "yes"; then fi fi +if test "${enable_fuzzing}" = "yes"; then + AC_DEFINE([FUZZING_ENABLED], [1], [Define if fuzzing is enabled]) +fi PKG_CHECK_EXISTS([libeac], [PKG_CHECK_MODULES([OPENPACE], [libeac >= 0.9])], diff --git a/src/tests/fuzzing/fuzz_asn1_print.c b/src/tests/fuzzing/fuzz_asn1_print.c index b50cb461af..974923476c 100644 --- a/src/tests/fuzzing/fuzz_asn1_print.c +++ b/src/tests/fuzzing/fuzz_asn1_print.c @@ -23,7 +23,9 @@ #include "libopensc/asn1.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef FUZZING_ENABLED fclose(stdout); +#endif sc_asn1_print_tags(Data, Size); return 0; } From c57e8671ef52beffa7cea5e1cac39a2a5d726e8a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Oct 2021 14:32:11 +0200 Subject: [PATCH 2062/4321] fuzz_pkcs15_reader.c: Fix type --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 100b9fca49..b6bdd8138b 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -236,7 +236,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) /* see `pkcs15_create_secret_key` in * `src/pkcs11/framework-pkc15.c` for creating a temporary * secret key for wrapping/unwrapping */ - unsigned long l = sizeof buf; + size_t l = sizeof buf; struct sc_pkcs15_object target_key; struct sc_pkcs15_skey_info skey_info; uint16_t len; From 5a46bde46876239147927f144b4a53ef5d5f4051 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Oct 2021 16:18:28 +0200 Subject: [PATCH 2063/4321] fuzzing: Add fuzzer for scconf_parse_string function --- src/tests/fuzzing/Makefile.am | 4 +- src/tests/fuzzing/fuzz_scconf_parse_string.c | 40 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzz_scconf_parse_string.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 33a929d0ef..e7aa18d4fe 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -5,7 +5,8 @@ LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la -noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader +noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ + fuzz_scconf_parse_string ADDITIONAL_SRC = if !ENABLE_FUZZING @@ -16,3 +17,4 @@ fuzz_asn1_print_SOURCES = fuzz_asn1_print.c $(ADDITIONAL_SRC) fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c $(ADDITIONAL_SRC) +fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/fuzz_scconf_parse_string.c b/src/tests/fuzzing/fuzz_scconf_parse_string.c new file mode 100644 index 0000000000..0d2d2b150e --- /dev/null +++ b/src/tests/fuzzing/fuzz_scconf_parse_string.c @@ -0,0 +1,40 @@ +/* + * fuzz_scconf_parse_string.c: Fuzz target for scconf_parse_string + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "scconf/scconf.h" +#include "libopensc/internal.h" + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + scconf_context *ctx = scconf_new(NULL); + + if (!ctx) + return 1; + const char *buf = (const char *)data; + scconf_parse_string(ctx, buf); + + scconf_free(ctx); + return 0; +} From 9a4cc393be025cfba0c02101aecafed97d397daf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Oct 2021 16:31:01 +0200 Subject: [PATCH 2064/4321] fuzzing: Add corpus for fuzz_scconf_parse_string.c --- .../7fa282cd0203fdc8966be091e48584fe94e3f272 | 1125 +++++++++++++++++ .../fa7e8cb717af33932718d96a3c785268311d9c6f | 10 + 2 files changed, 1135 insertions(+) create mode 100644 src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 create mode 100644 src/tests/fuzzing/corpus/fuzz_scconf_parse_string/fa7e8cb717af33932718d96a3c785268311d9c6f diff --git a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 new file mode 100644 index 0000000000..28e0ad5f39 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 @@ -0,0 +1,1125 @@ +app default { + # Amount of debug info to print + debug = 3; + + # The file to which debug output will be written + debug_file = @DEBUG_FILE@ + + # PKCS#15 initialization / personalization + # profiles directory for pkcs15-init. + + # + profile_dir = @PROFILE_DIR@; + + # Disable pop-ups of built-in GUI + # + # Default: false + disable_popups = true; + + # Enable default card driver + # Default card driver is explicitly enabled for the 'opensc-explorer' and 'opensc-tool'. + # + # Default: false + enable_default_driver = true; + + # List of readers to ignore + # If any of the strings listed below is matched in a reader name (case + # sensitive, partial matching possible), the reader is ignored by OpenSC. + # Use `opensc-tool --list-readers` to see all currently connected readers. + # + + ignored_readers = "CardMan 1021", "SPR 532"; + + # CT-API module configuration. + reader_driver ctapi { + module @LIBDIR@@LIB_PRE@towitoko@DYN_LIB_EXT@ { + CT-API ports: + 0..3 COM1..4 + 4 Printer + 5 Modem + 6..7 LPT1..2 + ports = 0; + } + } + + # The following section shows definitions for PC/SC readers. + reader_driver pcsc { + # Limit command and response sizes. Some Readers don't propagate their + # transceive capabilities correctly. max_send_size and max_recv_size + # allow setting the limits manually, for example to enable extended + # length capabilities. + # Default: max_send_size = 255, max_recv_size = 256; + max_send_size = 65535; + max_recv_size = 65536; + # + # Connect to reader in exclusive mode? + # Default: false + connect_exclusive = true; + + # What to do when disconnecting from a card (SCardDisconnect) + # Valid values: leave, reset, unpower. + + disconnect_action = reset; + # + # What to do at the end of a transaction (SCardEndTransaction) + # Valid values: leave, reset, unpower. + # Default: leave + transaction_end_action = reset; + # + # What to do when reconnection to a card (SCardReconnect) + # Valid values: leave, reset, unpower. + # Note that this affects only the internal reconnect (after a SCARD_W_RESET_CARD). + # A forced reset via sc_reset() always does a full powerup. + # Default: leave + reconnect_action = reset; + # + # Enable pinpad if detected (PC/SC v2.0.2 Part 10) + # Default: true + + + enable_pinpad = false; + # + # Some pinpad readers can only handle one exact length of the PIN. + # fixed_pinlength sets this value so that OpenSC expands the padding to + # this length. + # Default: 0 (i.e. not fixed) + fixed_pinlength = 6; + # + # Detect reader capabilities with escape commands (wrapped APDUs with + # CLA=0xFF as defined by PC/SC pt. 3 and BSI TR-03119, e.g. for getting + # the UID, escaped PIN commands and the reader's firmware version) + # Default: false + enable_escape = true; + # + # Use specific pcsc provider. + # Default: @DEFAULT_PCSC_PROVIDER@ + provider_library = @DEFAULT_PCSC_PROVIDER@ + } + + # Options for OpenCT support + reader_driver openct { + # Virtual readers to allocate. + # Default: 2 + readers = 5; + # + # Limit command and response sizes. + # Default: n/a + max_send_size = 255; + max_recv_size = 256; + } + + # Options for CryptoTokenKit support + reader_driver cryptotokenkit { + # Limit command and response sizes. Some Readers don't propagate their + # transceive capabilities correctly. max_send_size and max_recv_size + # allow setting the limits manually, for example to enable extended + # length capabilities. + # Default: autodetect + max_send_size = 65535; + max_recv_size = 65536; + } + + # Whitelist of card drivers to load at start-up + # + # The supported internal card driver names can be retrieved + # from the output of: + # $ opensc-tool --list-drivers + # + # A special value of 'old' will load all + # statically linked drivers that may be removed in the future. + # + # A special value of 'internal' will load all + # statically linked drivers. If an unknown (i.e. not + # internal) driver is supplied, a separate configuration + # configuration block has to be written for the driver. + # Default: internal + # NOTE: When "internal" keyword is used, must be last entry + # + card_drivers = old, internal; + + # Card driver configuration blocks. + + # For card drivers loaded from an external shared library/DLL, + # you need to specify the path name of the module + # + card_driver customcos { + # The location of the driver library + module = @LIBDIR@@LIB_PRE@card_customcos@DYN_LIB_EXT@; + } + + card_driver npa { + # German ID card requires the CAN to be verified before QES PIN. This, + # however, is not part of the PKCS#15 profile of the card. So for + # verifying the QES PIN we actually need both. The CAN may be given + # here. If the CAN is not given here, it will be prompted on the + # command line or on the reader (depending on the reader's + # capabilities). + # + can = 222222; + + # QES is only possible with a Comfort Reader (CAT-K), which holds a + # cryptographic key to authenticate itself as signature terminal (ST). + # We usually will use the reader's capability to sign the data. + # However, during development you may specify soft certificates and + # keys for a ST below. + # The following example EAC PKI can be found in vicc's example data: + # https://github.com/frankmorgner/vsmartcard/tree/master/virtualsmartcard/npa-example-data + # + st_dv_certificate = ZZSTDVCA00001.cvcert; + st_certificate = ZZSTTERM00001.cvcert; + st_key = ZZSTTERM00001.pkcs8; + } + + # Configuration block for DNIe + # + # Card DNIe has an option to show an extra warning before + # issuing a signature. + + card_driver dnie { + # Disable / enable warning message when performing a + # signature operation with the DNIe. + # Only used if compiled with --enable-dnie-ui + user_consent_enabled = yes; + + # Specify the pinentry application to use if warning + # is configured to be displayed using pinentry. + # Default: /usr/bin/pinentry + # Only used if compiled with --enable-dnie-ui + user_consent_app = "/usr/bin/pinentry"; + } + + card_driver edo { + # CAN is required to establish connection + # with the card. It might be overridden by + # EDO_CAN environment variable. Currently, + # it is not possible to set it in any other way. + # + can = 123456; + } + + # In addition to the built-in list of known cards in the + # card driver, you can configure a new card for the driver + # using the card_atr block. The goal is to centralize + # everything related to a certain card to card_atr. + # + # The supported internal card driver names can be retrieved + # from the output of: + # $ opensc-tool --list-drivers + + # Generic format: card_atr + + # New card entry for the flex card driver + card_atr 3b:f0:0d:ca:fe { + # All parameters for the context are + # optional unless specified otherwise. + + # Context: global, card driver + # + # ATR mask value + # + # The mask is logically AND'd with an + # card ATR prior to comparison with the + # ATR reference value above. Using mask + # allows identifying and configuring + # multiple ATRs as the same card model. + atrmask = "ff:ff:ff:ff:ff"; + + # Context: card driver + # + # Specify used card driver (REQUIRED). + # + # When enabled, overrides all possible + # settings from the card drivers built-in + # card configuration list. + driver = "flex"; + + # Set card name for card drivers that allows it. + name = "My CryptoFlex card"; + + # Card type as an integer value. + # + # Depending on card driver, this allows + # tuning the behaviour of the card driver + # for your card. + type = "2002"; + + # Card flags as an hex value. + # Multiple values are OR'd together. + # + # Depending on card driver, this allows + # fine-tuning the capabilities in + # the card driver for your card. + # + # Optionally, some known parameters + # can be specified as strings: + # + # rng - On-board random number source + # keep_alive - Request the card driver to send a "keep alive" command before each transaction to make sure that the required applet is still selected. + # + flags = "rng", "keep_alive", "0x80000000"; + + # + # Context: PKCS#15 emulation layer + # + # When using PKCS#15 emulation, force + # the emulation driver for specific cards. + # + # Required for external drivers, but can + # be used with built-in drivers, too. + pkcs15emu = "custom"; + + # + # Context: reader driver + # + # Force protocol selection for specific cards. + # Known parameters: t0, t1, raw + force_protocol = "t0"; + + # Context: minidriver + # + # read_only: Mark card as read/only card in Minidriver/BaseCSP interface (Default: false) + # md_supports_X509_enrollment: Indicate X509 enrollment support at Minidriver/BaseCSP interface (Default: false) + # md_guid_as_id: Use the GUID generated for the key as id in the PKCS#15 structure (Default: false, i.e. auto generated) + # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false, i.e. no label set) + # md_supports_container_key_gen: Card allows generating key pairs on the card (Default: false) + # md_supports_container_key_import: Card allows importing private keys (Default: false) + # + # Window title of the PIN pad dialog + # Default: "Windows Security" + md_pinpad_dlg_title = "Title"; + # + # Filename of the icon for the PIN pad dialog; use "" for no icon + # Default: Built-in smart card icon + md_pinpad_dlg_icon = ""; + # + # Main instruction of the PIN pad dialog + # Default: "OpenSC Smart Card Provider" + md_pinpad_dlg_main = "Main"; + # + # Content of the PIN pad dialog for role "user" + # Default: "Please verify your fingerprint or PIN on the card." + md_pinpad_dlg_content_user = "Content User"; + + # Content of the PIN pad dialog for role "user+signature" + # Default: "Please verify your fingerprint or PIN for the digital signature PIN on the card." + md_pinpad_dlg_content_user_sign = "Content User+Sign"; + + # Content of the PIN pad dialog for role "admin" + # Default: "Please enter your PIN to unblock the user PIN on the PINPAD." + md_pinpad_dlg_content_admin = "Content Admin"; + # + # Expanded information of the PIN pad dialog + # Default: "This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)." + md_pinpad_dlg_expanded = "Expanded Information"; + # + # Allow the user to cancel the PIN pad dialog by not immediately requesting the PIN on the PIN pad + # Default: false + md_pinpad_dlg_enable_cancel = true; + # + # Content of the verification of the PIN pad dialog + # Default: "Automatically request PIN immediately on PIN-Pad" + md_pinpad_dlg_verification = "Verification"; + # + # Time in seconds for the progress bar of the PIN pad dialog to tick. "0" removes the progress bar. + # Default: 30 + md_pinpad_dlg_timeout = 0; + + # Notification title and text when card was inserted + # Default: "Smart card detected" + # notify_card_inserted = "inserted title"; + # Default: ATR of the card + notify_card_inserted_text = "inserted text"; + # + # Notification title and text when card was removed + # Default: "Smart card removed" + # notify_card_removed = "card removed"; + # Default: Name of smart card reader + notify_card_removed_text = "removed text"; + # + # Notification title and text when PIN was verified + # Default: "PIN verified" + # notify_pin_good = "good PIN"; + # Default: "Smart card is unlocked" + notify_pin_good_text = "good text"; + # + # Notification title and text when PIN was wrong + # Default: "PIN not verified" + # notify_pin_bad = "bad PIN"; + # Default: "Smart card is locked" + notify_pin_bad_text = "bad text"; + } + + # Yubikey is known to have the PIV applet and the OpenPGP applet. OpenSC + # can handle both to access keys and certificates, but only one at a time. + card_atr 3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4 { + name = "Yubikey 4"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } + card_atr 3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1 { + name = "Yubikey Neo"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } + card_atr 3b:8c:80:01:59:75:62:69:6b:65:79:4e:45:4f:72:33:58 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00"; + name = "Yubikey Neo"; + # Select the PKI applet to use ("PIV-II" or "openpgp") + driver = "PIV-II"; + # Recover from other applications accessing a different applet + flags = "keep_alive"; + } + + # Oberthur's AuthentIC v3.2.2 + card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B { + type = 11100; + driver = "authentic"; + name = "AuthentIC v3.1"; + + # Name of SM configuration sub-section + # secure_messaging = local_authentic; + } + + # IAS/ECC cards + card_atr 3B:7F:96:00:00:00:31:B9:64:40:70:14:10:73:94:01:80:82:90:00 { + type = 25001; + driver = "iasecc"; + name = "Gemalto MultiApp IAS/ECC v1.0.1"; + secure_messaging = local_gemalto_iam; + # secure_messaging = local_adele; + read_only = false; + md_supports_X509_enrollment = true; + } + card_atr 3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00 { + type = 25001; + driver = "iasecc"; + name = "Gemalto MultiApp IAS/ECC v1.0.1"; + secure_messaging = local_gemalto_iam; + read_only = false; + md_supports_X509_enrollment = true; + } + #card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:FE { + # type = 25002; + # driver = "iasecc"; + # name = "Oberthur IAS/ECC v1.0.1"; + # # No 'admin' application for this card -- no secure messaging + #} + #card_atr 3B:7F:18:00:00:00:31:B8:64:50:23:EC:C1:73:94:01:80:82:90:00 { + # type = 25003; + # driver = "iasecc"; + # name = "Morpho YpsID S3 IAS/ECC"; + # # secure_messaging = local_morpho_YpsID_S3; + #} + #card_atr 3B:DF:96:00:80:31:FE:45:00:31:B8:64:04:1F:EC:C1:73:94:01:80:82:90:00:EC { + # type = 25005; + # driver = "iasecc"; + # name = "Morpho MI IAS/ECC v1.0.1"; + # read_only = false; + # md_supports_X509_enrollment = true; + # secure_messaging = local_morpho_mi; + #} + card_atr 3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3 { + type = 25004; + driver = "iasecc"; + name = "Amos IAS/ECC v1.0.1"; + read_only = false; + md_supports_X509_enrollment = true; + secure_messaging = local_amos; + } + card_atr 3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38 { + type = 25004; + driver = "iasecc"; + name = "Amos IAS/ECC v1.0.1"; + read_only = false; + md_supports_X509_enrollment = true; + secure_messaging = local_amos_eid; + } + + # SmartCard-HSM with contact-based interface or USB-Stick + card_atr 3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA { + driver = "sc-hsm"; + read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + } + + # SmartCard-HSM with contact-less interface + card_atr 3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18 { + driver = "sc-hsm"; + read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + } + + # SmartCard-HSM 4k with contact-based interface or USB-Stick + card_atr 3b:de:18:ff:81:91:fe:1f:c3:80:31:81:54:48:53:4d:31:73:80:21:40:81:07:1c { + driver = "sc-hsm"; + read_only = false; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + } + + # SmartCard-HSM with fingerprint sensor and PIN pad + card_atr 3B:80:80:01:01 { + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:84:80:01:47:6f:49:44:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:85:80:01:47:6f:49:44:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:86:80:01:47:6f:49:44:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:87:80:01:47:6f:49:44:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:88:80:01:47:6f:49:44:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:89:80:01:47:6f:49:44:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8A:80:01:47:6f:49:44:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8B:80:01:47:6f:49:44:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8C:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8D:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8E:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + # GoID with fingerprint sensor and PIN pad + card_atr 3B:8F:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00"; + driver = "sc-hsm"; + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + secure_messaging local_authentic { + # name of external SM module + # module_name = @DEFAULT_SM_MODULE@; + # directory with external SM module + # Default: @DEFAULT_SM_MODULE_PATH@ + # module_path = @DEFAULT_SM_MODULE_PATH@; + + # specific data to tune the module initialization + # module_data = "Here can be your SM module init data"; + + # SM mode: + # 'transmit' -- in this mode the procedure to securize an APDU is called by the OpenSC general + # APDU transmit procedure. + # In this mode all APDUs, except the ones filtered by the card specific procedure, + # are securized. + # 'acl' -- in this mode APDU are securized only if needed by the ACLs of the command to be executed. + # + mode = transmit; + + # SM type specific flags + flags = 0x78; # 0x78 -- level 3, channel 0 + + # Default KMC of the GP Card Manager for the Oberthur's Java cards + kmc = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"; + } + + secure_messaging local_gemalto_iam { + module_name = @DEFAULT_SM_MODULE@; + # module_path = @DEFAULT_SM_MODULE_PATH@; + # module_data = ""; + type = acl; # transmit, acl + + ifd_serial = "11:22:33:44:55:66:77:88"; + + # Keyset values from IAM profiles of the Gemalto IAS/ECC cards + keyset_02_enc = "RW_PRIV_ENC_TEST"; + keyset_02_mac = "RW_PRIV_MAC_TEST"; + + keyset_E828BD080FD2504543432D654944_01_enc = "RO_ENC_TEST_KEY_"; + keyset_E828BD080FD2504543432D654944_01_mac = "RO_MAC_TEST_KEY_"; + + keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST"; + keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST"; + } + + secure_messaging local_amos { + module_name = @DEFAULT_SM_MODULE@; + # module_path = @DEFAULT_SM_MODULE_PATH@; + # module_data = ""; + mode = acl; + ifd_serial = "11:22:33:44:55:66:77:88"; + keyset_02_enc = "ENCROECHANTILLON"; + keyset_02_mac = "MACROECHANTILLON"; + } + + secure_messaging local_amos_eid { + module_name = @DEFAULT_SM_MODULE@; + # module_path = @DEFAULT_SM_MODULE_PATH@; + # module_data = ""; + mode = acl; + ifd_serial = "11:22:33:44:55:66:77:88"; + keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST"; + keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST"; + } + + secure_messaging local_adele { + module_name = @DEFAULT_SM_MODULE@; + # module_path = @DEFAULT_SM_MODULE_PATH@; + # module_data = ""; + type = acl; # transmit, acl + + ifd_serial = "11:22:33:44:55:66:77:88"; + + # Keyset values from 'Adele' profiles of the IAS/ECC cards + keyset_01_enc = "EMENCECHANTILLON"; + keyset_01_mac = "EMMACECHANTILLON"; + + keyset_02_enc = "AAENCECHANTILLON"; + keyset_02_mac = "AAMACECHANTILLON"; + + keyset_E828BD080FD2500000040301_02_enc = "E2ENCECHANTILLON"; + keyset_E828BD080FD2500000040301_02_mac = "E2MACECHANTILLON"; + + keyset_D2500000044164E86C650101_02_enc = "E1ENCECHANTILLON"; + keyset_D2500000044164E86C650101_02_mac = "E1MACECHANTILLON"; + + keyset_D2500000044164E86C650101_03_enc = "SIENCECHANTILLON"; + keyset_D2500000044164E86C650101_03_mac = "SIMACECHANTILLON"; + } + + # Below are the framework specific configuration blocks. + + # PKCS #15 + framework pkcs15 { + # Whether to use the cache files in the user's + # home directory. + # + # Note: If caching is done by a system process, caching may be placed + # inaccessible from the user account. Use a global caching directory if + # you wish to share the cached information. + # + # Default: false + use_file_caching = true; + # + # set a path for caching + # so you do not use the env variables and for pam_pkcs11 + # (with certificate check) where $HOME is not set + # Default: path in user home + # file_cache_dir = /var/lib/opensc/cache + + # Use PIN caching? + # Default: true + use_pin_caching = false; + # + # How many times to use a PIN from cache before re-authenticating it? + # Default: 10 + pin_cache_counter = 3; + # + # Older PKCS#11 applications not supporting CKA_ALWAYS_AUTHENTICATE + # may need to set this to get signatures to work with some cards. + # Default: false + # It is recommended to enable also use_pin_caching to allow OpenSC + # to pass the pin to the card when needed. + pin_cache_ignore_user_consent = true; + + # How to handle a PIN-protected certificate + # Valid values: protect, declassify, ignore. + # Default: ignore in tokend, protect otherwise + private_certificate = declassify; + + # Enable pkcs15 emulation. + # Default: yes + enable_pkcs15_emulation = no; + # + # Prefer pkcs15 emulation code before + # the normal pkcs15 processing. + # Some cards (like esteid and pteid) work in emu-only mode, + # and do not depend on this option. + # + # Default: no + try_emulation_first = yes; + + # Enable builtin emulators. + # Default: yes + enable_builtin_emulation = no; + # + # List of the builtin pkcs15 emulators to test + # Special value of 'internal' will try all not disabled builtin pkcs15 emulators. + # Special value of 'old' will try all disabled pkcs15 emulators. + # Default: internal; + builtin_emulators = old, internal; + + # additional settings per driver + # + # For pkcs15 emulators loaded from an external shared + # library/DLL, you need to specify the path name of the module + # and customize the card_atr example above correctly. + # + emulate custom { + # The location of the driver library + module = @LIBDIR@@LIB_PRE@p15emu_custom@DYN_LIB_EXT@; + } + + # Enable initialization and card recognition in PKCS#11 layer. + # Default: no + # pkcs11_enable_InitToken = yes; + + # some additional application parameters: + # - type (generic, protected) used to distinguish the common access application + # and application for which authentication to perform some operation cannot be + # obtained with the common procedures (ex. object creation protected by secure messaging). + # Used by PKCS#11 module configured to expose restricted number of slots. + # (for ex. configured to expose only User PIN slot, User and Sign PINs slots, ...) + # + # - disable: do not expose application in PKCS15 framework + # default 'false' + application E828BD080FD25047656E65726963 { + type = generic; + model = "ECC Generic PKI"; + # disable = true + } + + application E828BD080FD2500000040301 { + type = generic; + model = "Adèle Générique"; + } + + application E828BD080FD2504543432D654944 { + type = protected; + model = "ECC eID"; + } + + application E828BD080FD2500000040201 { + type = protected; + model = "Adèle Admin-2"; + } + } +} + +# Parameters for the OpenSC PKCS11 module +app opensc-pkcs11 { + pkcs11 { + # Maximum Number of virtual slots. + # If there are more slots than defined here, + # the remaining slots will be hidden from PKCS#11. + # Default: 16 + max_virtual_slots = 32; + + # Maximum number of slots per smart card. + # If the card has fewer keys than defined here, + # the remaining number of slots will be empty. + # Default: 4 + slots_per_card = 2; + + # (max_virtual_slots/slots_per_card) limits the number of readers + # that can be used on the system. Default is then 16/4=4 readers. + + # By default, the OpenSC PKCS#11 module will not lock your card + # once you authenticate to the card via C_Login. + # + # Thus the other users or other applications is not prevented + # from connecting to the card and perform crypto operations + # (which may be possible because you have already authenticated + # with the card). This setting is not very secure. + # + # Also, if your card is not locked, you can enconter problems + # due to limitation of the OpenSC framework, that still is not + # thoroughly tested in the multi threads environment. + # + # Your settings will be more secure if you choose to lock your + # card. Nevertheless this behavior is a known violation of PKCS#11 + # specification. Now once one application has started using your + # card with C_Login, no other application can use it, until + # the first is done and calls C_Logout or C_Finalize. In the case + # of many PKCS#11 application this does not happen until you exit + # the application. + # Thus it is impossible to use several smart card aware applications + # at the same time, e.g. you cannot run both Firefox and Thunderbird at + # the same time, if both are configured to use your smart card. + # + # Default: false + lock_login = true; + + # By default, interacting with the OpenSC PKCS#11 module may change the + # state of the token, e.g. whether a user is logged in or not. + # + # Thus other users or other applications may change or use the state of + # the token unknowingly. Other applications may create signatures + # abusing an existing login or they may logout unnoticed. + # + # With this setting enabled the login state of the token is tracked and + # cached (including the PIN). Every transaction is preceded by + # restoring the login state. After every transaction a logout is + # performed. This setting by default also enables `lock_login` (see + # above) to disable access for other applications during the atomic + # transactions. + # + # Please note that any PIN-pad should be disabled (see `enable_pinpad` + # above), because the user would have to input his PIN for every + # transaction. + # + # Default: false + atomic = true; + + # With this setting disabled, the OpenSC PKCS#11 module will initialize + # the slots available when the application calls `C_GetSlotList`. With + # this setting enabled, the slots will also get initialized when + # C_GetSlotInfo is called. + # + # This setting is a workaround for Java which does not call + # `C_GetSlotList` when configured with a static `slot` instead of + # `slotListIndex`. + # + # Default: true + init_sloppy = false; + + # User PIN unblock style + # none: PIN unblock is not possible with PKCS#11 API; + # set_pin_in_unlogged_session: C_SetPIN() in unlogged session: + # PUK is passed as the 'OldPin' argument of the C_SetPIN() call. + # set_pin_in_specific_context: C_SetPIN() in the CKU_SPECIFIC_CONTEXT logged session: + # PUK is passed as the 'OldPin' argument of the C_SetPIN() call. + # init_pin_in_so_session: C_InitPIN() in CKU_SO logged session: + # User PIN 'UNBLOCK' is protected by SOPIN. (PUK == SOPIN). + # # Actually this style works only for the PKCS15 contents without SOPIN. + # # For those with SOPIN, this mode will be useful for the cards without + # # modes 00 and 01 of ISO command 'RESET RETRY COUNTER'. --vt + # + # Default: none + user_pin_unblock_style = set_pin_in_unlogged_session; + + # Create slot for unblocking PIN with PUK + # This way PKCS#11 API can be used to login with PUK and + # change a PIN. + # Warning: causes problems with some applications like + # firefox and thunderbird. Thus turned off by default + # + # Default: false + create_puk_slot = true; + + # Symbolic names of PINs for which slots are created + # Card can contain more then one PINs or more then one on-card application with + # its own PINs. Normally, to access all of them with the PKCS#11 API a slot has to be + # created for all of them. Many slots could be ennoying for some of widely used application, + # like FireFox. This configuration parameter allows one to select the PIN(s) + # for which PKCS#11 slot will be created. + # Actually recognised following symbolic names: + # 'user', 'sign', 'all' + # Only PINs initialised, non-SoPIN, non-unblocking are associated with symbolic name. + # 'user' is identified as first global or first local PIN. + # 'sign' is identified as second PIN: first local, second global or second local. + # 'all' slot created for all non-sopin, non-unblocking PINs, + # optionally for PUK (see option 'create_puk_slot') + # + # Default: all + create_slots_for_pins = "user,sign"; + create_slots_for_pins = "sign"; + # + # For the module to simulate the opensc-onepin module behavior the following option + # must be set: + create_slots_for_pins = "user" + } +} + +app onepin-opensc-pkcs11 { + pkcs11 { + slots_per_card = 1; + } +} + +# Used by OpenSC.tokend on Mac OS X only +app tokend { + # The file to which debug log will be written + # Default: /tmp/opensc-tokend.log + # + # debug_file = /Library/Logs/OpenSC.tokend.log + + framework tokend { + # Score for OpenSC.tokend + # The tokend with the highest score shall be used. + # Default: 300 + # + score = 10; + + # Tokend ignore to read PIN protected certificate that is set SC_PKCS15_CO_FLAG_PRIVATE flag. + # Default: true + # + ignore_private_certificate = false; + } +} + +# Used by OpenSC minidriver on Windows only +app cardmod { +} + diff --git a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/fa7e8cb717af33932718d96a3c785268311d9c6f b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/fa7e8cb717af33932718d96a3c785268311d9c6f new file mode 100644 index 0000000000..1f2d3bf3bc --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/fa7e8cb717af33932718d96a3c785268311d9c6f @@ -0,0 +1,10 @@ +app default { + debug = 0; + debug_file = stdout; + framework pkcs15 { + enable_builtin_emulation = yes; + builtin_emulators = old, jpki, dnie, gids, PIV-II; + + } +} + From 74a63d22271d174409856d5083418911eb5e61ff Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Oct 2021 16:33:34 +0200 Subject: [PATCH 2065/4321] fuzzing: Fix flags for enabling fuzzing --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d85b8fa218..ca149aa9f4 100644 --- a/configure.ac +++ b/configure.ac @@ -138,7 +138,7 @@ AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_opti AC_ARG_ENABLE( [fuzzing], - [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CFLAGS and FUZZING_LIBS should be set accordingly, e.g. to something like CFLAGS="-fsanitize=address,fuzzer" FUZZING_LIBS="-fsanitize=fuzzer"])], + [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CC, CFLAGS and FUZZING_LIBS should be set accordingly, e.g. to something like CC="clang" CFLAGS="-fsanitize=fuzzer-no-link" FUZZING_LIBS="-fsanitize=fuzzer"])], , [enable_fuzzing="no"] ) From a943155d99053efdef0cc8e531aa6ac272c0b704 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 7 Oct 2021 18:16:48 +0200 Subject: [PATCH 2066/4321] fuzz_scconf_parse_string: Fix buffer ending and max input size --- .../497025125e0dfab0b9e16155ce16d6e25ec8ec6d | 183 +++ .../7fa282cd0203fdc8966be091e48584fe94e3f272 | 1125 ----------------- src/tests/fuzzing/fuzz_scconf_parse_string.c | 15 +- 3 files changed, 195 insertions(+), 1128 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d delete mode 100644 src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 diff --git a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d new file mode 100644 index 0000000000..1193203c07 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d @@ -0,0 +1,183 @@ +app default { + debug = 3; + # Disable pop-ups of built-in GUI + disable_popups = true; + enable_default_driver = true; + + ignored_readers = "CardMan 1021", "SPR 532"; + + # The following section shows definitions for PC/SC readers. + reader_driver pcsc { + max_send_size = 65535; + max_recv_size = 65536; + connect_exclusive = true; + disconnect_action = reset; + transaction_end_action = reset; + reconnect_action = reset; + enable_pinpad = false; + fixed_pinlength = 6; + enable_escape = true; + provider_library = @DEFAULT_PCSC_PROVIDER@ + } + + reader_driver openct { + readers = 5; + + max_send_size = 255; + max_recv_size = 256; + } + + reader_driver cryptotokenkit { + max_send_size = 65535; + max_recv_size = 65536; + } + + card_drivers = old, internal; + card_driver customcos { + module = @LIBDIR@@LIB_PRE@card_customcos@DYN_LIB_EXT@; + } + + card_driver npa { + can = 222222; + st_dv_certificate = ZZSTDVCA00001.cvcert; + st_certificate = ZZSTTERM00001.cvcert; + st_key = ZZSTTERM00001.pkcs8; + } + card_atr 3b:8c:80:01:59:75:62:69:6b:65:79:4e:45:4f:72:33:58 { + atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00"; + name = "Yubikey Neo"; + driver = "PIV-II"; + flags = "keep_alive"; + } + + card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B { + type = 11100; + driver = "authentic"; + name = "AuthentIC v3.1"; + secure_messaging = local_authentic; + } + card_atr 3B:7F:96:00:00:00:31:B9:64:40:70:14:10:73:94:01:80:82:90:00 { + type = 25001; + driver = "iasecc"; + name = "Gemalto MultiApp IAS/ECC v1.0.1"; + secure_messaging = local_gemalto_iam; + secure_messaging = local_adele; + read_only = false; + md_supports_X509_enrollment = true; + } + card_atr 3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00 { + type = 25001; + driver = "iasecc"; + name = "Gemalto MultiApp IAS/ECC v1.0.1"; + secure_messaging = local_gemalto_iam; + read_only = false; + md_supports_X509_enrollment = true; + } + card_atr 3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3 { + type = 25004; + driver = "iasecc"; + name = "Amos IAS/ECC v1.0.1"; + read_only = false; + md_supports_X509_enrollment = true; + secure_messaging = local_amos; + } + # SmartCard-HSM with fingerprint sensor and PIN pad + card_atr 3B:80:80:01:01 { + force_protocol = "t1"; + read_only = true; + md_supports_X509_enrollment = true; + md_supports_container_key_gen = true; + md_guid_as_label = true; + md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; + md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; + md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; + md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; + md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; + md_pinpad_dlg_timeout = 30; + notify_card_inserted = "GoID erkannt"; + notify_card_inserted_text = ""; + notify_card_removed = "GoID entfernt"; + notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; + notify_pin_good_text = "GoID ist entsperrt"; + notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; + notify_pin_bad_text = "GoID ist gesperrt"; + } + + secure_messaging local_authentic { + module_path = @DEFAULT_SM_MODULE_PATH@; + mode = transmit; + flags = 0x78; + kmc = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"; + } + + secure_messaging local_gemalto_iam { + module_name = @DEFAULT_SM_MODULE@; + type = acl; # transmit, acl + + ifd_serial = "11:22:33:44:55:66:77:88"; + keyset_02_enc = "RW_PRIV_ENC_TEST"; + keyset_02_mac = "RW_PRIV_MAC_TEST"; + keyset_E828BD080FD2504543432D654944_01_enc = "RO_ENC_TEST_KEY_"; + keyset_E828BD080FD2504543432D654944_01_mac = "RO_MAC_TEST_KEY_"; + keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST"; + keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST"; + } + + framework pkcs15 { + use_file_caching = true; + use_pin_caching = false; + pin_cache_counter = 3; + pin_cache_ignore_user_consent = true; + private_certificate = declassify; + enable_pkcs15_emulation = no; + try_emulation_first = yes; + enable_builtin_emulation = no; + builtin_emulators = old, internal; + emulate custom { + module = @LIBDIR@@LIB_PRE@p15emu_custom@DYN_LIB_EXT@; + } + application E828BD080FD25047656E65726963 { + type = generic; + model = "ECC Generic PKI"; + } + + application E828BD080FD2500000040301 { + type = generic; + model = "Adèle Générique"; + } + } +} + +app opensc-pkcs11 { + pkcs11 { + max_virtual_slots = 32; + slots_per_card = 2; + lock_login = true; + atomic = true; + init_sloppy = false; + user_pin_unblock_style = set_pin_in_unlogged_session; + create_puk_slot = true; + create_slots_for_pins = "user,sign"; + create_slots_for_pins = "sign"; + create_slots_for_pins = "user" + } +} + +app onepin-opensc-pkcs11 { + pkcs11 { + slots_per_card = 1; + } +} + +# Used by OpenSC.tokend on Mac OS X only +app tokend { + framework tokend { + score = 10; + ignore_private_certificate = false; + } +} + +# Used by OpenSC minidriver on Windows only +app cardmod { +} + diff --git a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 deleted file mode 100644 index 28e0ad5f39..0000000000 --- a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/7fa282cd0203fdc8966be091e48584fe94e3f272 +++ /dev/null @@ -1,1125 +0,0 @@ -app default { - # Amount of debug info to print - debug = 3; - - # The file to which debug output will be written - debug_file = @DEBUG_FILE@ - - # PKCS#15 initialization / personalization - # profiles directory for pkcs15-init. - - # - profile_dir = @PROFILE_DIR@; - - # Disable pop-ups of built-in GUI - # - # Default: false - disable_popups = true; - - # Enable default card driver - # Default card driver is explicitly enabled for the 'opensc-explorer' and 'opensc-tool'. - # - # Default: false - enable_default_driver = true; - - # List of readers to ignore - # If any of the strings listed below is matched in a reader name (case - # sensitive, partial matching possible), the reader is ignored by OpenSC. - # Use `opensc-tool --list-readers` to see all currently connected readers. - # - - ignored_readers = "CardMan 1021", "SPR 532"; - - # CT-API module configuration. - reader_driver ctapi { - module @LIBDIR@@LIB_PRE@towitoko@DYN_LIB_EXT@ { - CT-API ports: - 0..3 COM1..4 - 4 Printer - 5 Modem - 6..7 LPT1..2 - ports = 0; - } - } - - # The following section shows definitions for PC/SC readers. - reader_driver pcsc { - # Limit command and response sizes. Some Readers don't propagate their - # transceive capabilities correctly. max_send_size and max_recv_size - # allow setting the limits manually, for example to enable extended - # length capabilities. - # Default: max_send_size = 255, max_recv_size = 256; - max_send_size = 65535; - max_recv_size = 65536; - # - # Connect to reader in exclusive mode? - # Default: false - connect_exclusive = true; - - # What to do when disconnecting from a card (SCardDisconnect) - # Valid values: leave, reset, unpower. - - disconnect_action = reset; - # - # What to do at the end of a transaction (SCardEndTransaction) - # Valid values: leave, reset, unpower. - # Default: leave - transaction_end_action = reset; - # - # What to do when reconnection to a card (SCardReconnect) - # Valid values: leave, reset, unpower. - # Note that this affects only the internal reconnect (after a SCARD_W_RESET_CARD). - # A forced reset via sc_reset() always does a full powerup. - # Default: leave - reconnect_action = reset; - # - # Enable pinpad if detected (PC/SC v2.0.2 Part 10) - # Default: true - - - enable_pinpad = false; - # - # Some pinpad readers can only handle one exact length of the PIN. - # fixed_pinlength sets this value so that OpenSC expands the padding to - # this length. - # Default: 0 (i.e. not fixed) - fixed_pinlength = 6; - # - # Detect reader capabilities with escape commands (wrapped APDUs with - # CLA=0xFF as defined by PC/SC pt. 3 and BSI TR-03119, e.g. for getting - # the UID, escaped PIN commands and the reader's firmware version) - # Default: false - enable_escape = true; - # - # Use specific pcsc provider. - # Default: @DEFAULT_PCSC_PROVIDER@ - provider_library = @DEFAULT_PCSC_PROVIDER@ - } - - # Options for OpenCT support - reader_driver openct { - # Virtual readers to allocate. - # Default: 2 - readers = 5; - # - # Limit command and response sizes. - # Default: n/a - max_send_size = 255; - max_recv_size = 256; - } - - # Options for CryptoTokenKit support - reader_driver cryptotokenkit { - # Limit command and response sizes. Some Readers don't propagate their - # transceive capabilities correctly. max_send_size and max_recv_size - # allow setting the limits manually, for example to enable extended - # length capabilities. - # Default: autodetect - max_send_size = 65535; - max_recv_size = 65536; - } - - # Whitelist of card drivers to load at start-up - # - # The supported internal card driver names can be retrieved - # from the output of: - # $ opensc-tool --list-drivers - # - # A special value of 'old' will load all - # statically linked drivers that may be removed in the future. - # - # A special value of 'internal' will load all - # statically linked drivers. If an unknown (i.e. not - # internal) driver is supplied, a separate configuration - # configuration block has to be written for the driver. - # Default: internal - # NOTE: When "internal" keyword is used, must be last entry - # - card_drivers = old, internal; - - # Card driver configuration blocks. - - # For card drivers loaded from an external shared library/DLL, - # you need to specify the path name of the module - # - card_driver customcos { - # The location of the driver library - module = @LIBDIR@@LIB_PRE@card_customcos@DYN_LIB_EXT@; - } - - card_driver npa { - # German ID card requires the CAN to be verified before QES PIN. This, - # however, is not part of the PKCS#15 profile of the card. So for - # verifying the QES PIN we actually need both. The CAN may be given - # here. If the CAN is not given here, it will be prompted on the - # command line or on the reader (depending on the reader's - # capabilities). - # - can = 222222; - - # QES is only possible with a Comfort Reader (CAT-K), which holds a - # cryptographic key to authenticate itself as signature terminal (ST). - # We usually will use the reader's capability to sign the data. - # However, during development you may specify soft certificates and - # keys for a ST below. - # The following example EAC PKI can be found in vicc's example data: - # https://github.com/frankmorgner/vsmartcard/tree/master/virtualsmartcard/npa-example-data - # - st_dv_certificate = ZZSTDVCA00001.cvcert; - st_certificate = ZZSTTERM00001.cvcert; - st_key = ZZSTTERM00001.pkcs8; - } - - # Configuration block for DNIe - # - # Card DNIe has an option to show an extra warning before - # issuing a signature. - - card_driver dnie { - # Disable / enable warning message when performing a - # signature operation with the DNIe. - # Only used if compiled with --enable-dnie-ui - user_consent_enabled = yes; - - # Specify the pinentry application to use if warning - # is configured to be displayed using pinentry. - # Default: /usr/bin/pinentry - # Only used if compiled with --enable-dnie-ui - user_consent_app = "/usr/bin/pinentry"; - } - - card_driver edo { - # CAN is required to establish connection - # with the card. It might be overridden by - # EDO_CAN environment variable. Currently, - # it is not possible to set it in any other way. - # - can = 123456; - } - - # In addition to the built-in list of known cards in the - # card driver, you can configure a new card for the driver - # using the card_atr block. The goal is to centralize - # everything related to a certain card to card_atr. - # - # The supported internal card driver names can be retrieved - # from the output of: - # $ opensc-tool --list-drivers - - # Generic format: card_atr - - # New card entry for the flex card driver - card_atr 3b:f0:0d:ca:fe { - # All parameters for the context are - # optional unless specified otherwise. - - # Context: global, card driver - # - # ATR mask value - # - # The mask is logically AND'd with an - # card ATR prior to comparison with the - # ATR reference value above. Using mask - # allows identifying and configuring - # multiple ATRs as the same card model. - atrmask = "ff:ff:ff:ff:ff"; - - # Context: card driver - # - # Specify used card driver (REQUIRED). - # - # When enabled, overrides all possible - # settings from the card drivers built-in - # card configuration list. - driver = "flex"; - - # Set card name for card drivers that allows it. - name = "My CryptoFlex card"; - - # Card type as an integer value. - # - # Depending on card driver, this allows - # tuning the behaviour of the card driver - # for your card. - type = "2002"; - - # Card flags as an hex value. - # Multiple values are OR'd together. - # - # Depending on card driver, this allows - # fine-tuning the capabilities in - # the card driver for your card. - # - # Optionally, some known parameters - # can be specified as strings: - # - # rng - On-board random number source - # keep_alive - Request the card driver to send a "keep alive" command before each transaction to make sure that the required applet is still selected. - # - flags = "rng", "keep_alive", "0x80000000"; - - # - # Context: PKCS#15 emulation layer - # - # When using PKCS#15 emulation, force - # the emulation driver for specific cards. - # - # Required for external drivers, but can - # be used with built-in drivers, too. - pkcs15emu = "custom"; - - # - # Context: reader driver - # - # Force protocol selection for specific cards. - # Known parameters: t0, t1, raw - force_protocol = "t0"; - - # Context: minidriver - # - # read_only: Mark card as read/only card in Minidriver/BaseCSP interface (Default: false) - # md_supports_X509_enrollment: Indicate X509 enrollment support at Minidriver/BaseCSP interface (Default: false) - # md_guid_as_id: Use the GUID generated for the key as id in the PKCS#15 structure (Default: false, i.e. auto generated) - # md_guid_as_label: Use the GUID generated for the key as label in the PKCS#15 structure (Default: false, i.e. no label set) - # md_supports_container_key_gen: Card allows generating key pairs on the card (Default: false) - # md_supports_container_key_import: Card allows importing private keys (Default: false) - # - # Window title of the PIN pad dialog - # Default: "Windows Security" - md_pinpad_dlg_title = "Title"; - # - # Filename of the icon for the PIN pad dialog; use "" for no icon - # Default: Built-in smart card icon - md_pinpad_dlg_icon = ""; - # - # Main instruction of the PIN pad dialog - # Default: "OpenSC Smart Card Provider" - md_pinpad_dlg_main = "Main"; - # - # Content of the PIN pad dialog for role "user" - # Default: "Please verify your fingerprint or PIN on the card." - md_pinpad_dlg_content_user = "Content User"; - - # Content of the PIN pad dialog for role "user+signature" - # Default: "Please verify your fingerprint or PIN for the digital signature PIN on the card." - md_pinpad_dlg_content_user_sign = "Content User+Sign"; - - # Content of the PIN pad dialog for role "admin" - # Default: "Please enter your PIN to unblock the user PIN on the PINPAD." - md_pinpad_dlg_content_admin = "Content Admin"; - # - # Expanded information of the PIN pad dialog - # Default: "This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)." - md_pinpad_dlg_expanded = "Expanded Information"; - # - # Allow the user to cancel the PIN pad dialog by not immediately requesting the PIN on the PIN pad - # Default: false - md_pinpad_dlg_enable_cancel = true; - # - # Content of the verification of the PIN pad dialog - # Default: "Automatically request PIN immediately on PIN-Pad" - md_pinpad_dlg_verification = "Verification"; - # - # Time in seconds for the progress bar of the PIN pad dialog to tick. "0" removes the progress bar. - # Default: 30 - md_pinpad_dlg_timeout = 0; - - # Notification title and text when card was inserted - # Default: "Smart card detected" - # notify_card_inserted = "inserted title"; - # Default: ATR of the card - notify_card_inserted_text = "inserted text"; - # - # Notification title and text when card was removed - # Default: "Smart card removed" - # notify_card_removed = "card removed"; - # Default: Name of smart card reader - notify_card_removed_text = "removed text"; - # - # Notification title and text when PIN was verified - # Default: "PIN verified" - # notify_pin_good = "good PIN"; - # Default: "Smart card is unlocked" - notify_pin_good_text = "good text"; - # - # Notification title and text when PIN was wrong - # Default: "PIN not verified" - # notify_pin_bad = "bad PIN"; - # Default: "Smart card is locked" - notify_pin_bad_text = "bad text"; - } - - # Yubikey is known to have the PIV applet and the OpenPGP applet. OpenSC - # can handle both to access keys and certificates, but only one at a time. - card_atr 3b:f8:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:34:d4 { - name = "Yubikey 4"; - # Select the PKI applet to use ("PIV-II" or "openpgp") - driver = "PIV-II"; - # Recover from other applications accessing a different applet - flags = "keep_alive"; - } - card_atr 3b:fc:13:00:00:81:31:fe:15:59:75:62:69:6b:65:79:4e:45:4f:72:33:e1 { - name = "Yubikey Neo"; - # Select the PKI applet to use ("PIV-II" or "openpgp") - driver = "PIV-II"; - # Recover from other applications accessing a different applet - flags = "keep_alive"; - } - card_atr 3b:8c:80:01:59:75:62:69:6b:65:79:4e:45:4f:72:33:58 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00"; - name = "Yubikey Neo"; - # Select the PKI applet to use ("PIV-II" or "openpgp") - driver = "PIV-II"; - # Recover from other applications accessing a different applet - flags = "keep_alive"; - } - - # Oberthur's AuthentIC v3.2.2 - card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B { - type = 11100; - driver = "authentic"; - name = "AuthentIC v3.1"; - - # Name of SM configuration sub-section - # secure_messaging = local_authentic; - } - - # IAS/ECC cards - card_atr 3B:7F:96:00:00:00:31:B9:64:40:70:14:10:73:94:01:80:82:90:00 { - type = 25001; - driver = "iasecc"; - name = "Gemalto MultiApp IAS/ECC v1.0.1"; - secure_messaging = local_gemalto_iam; - # secure_messaging = local_adele; - read_only = false; - md_supports_X509_enrollment = true; - } - card_atr 3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00 { - type = 25001; - driver = "iasecc"; - name = "Gemalto MultiApp IAS/ECC v1.0.1"; - secure_messaging = local_gemalto_iam; - read_only = false; - md_supports_X509_enrollment = true; - } - #card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:FE { - # type = 25002; - # driver = "iasecc"; - # name = "Oberthur IAS/ECC v1.0.1"; - # # No 'admin' application for this card -- no secure messaging - #} - #card_atr 3B:7F:18:00:00:00:31:B8:64:50:23:EC:C1:73:94:01:80:82:90:00 { - # type = 25003; - # driver = "iasecc"; - # name = "Morpho YpsID S3 IAS/ECC"; - # # secure_messaging = local_morpho_YpsID_S3; - #} - #card_atr 3B:DF:96:00:80:31:FE:45:00:31:B8:64:04:1F:EC:C1:73:94:01:80:82:90:00:EC { - # type = 25005; - # driver = "iasecc"; - # name = "Morpho MI IAS/ECC v1.0.1"; - # read_only = false; - # md_supports_X509_enrollment = true; - # secure_messaging = local_morpho_mi; - #} - card_atr 3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3 { - type = 25004; - driver = "iasecc"; - name = "Amos IAS/ECC v1.0.1"; - read_only = false; - md_supports_X509_enrollment = true; - secure_messaging = local_amos; - } - card_atr 3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38 { - type = 25004; - driver = "iasecc"; - name = "Amos IAS/ECC v1.0.1"; - read_only = false; - md_supports_X509_enrollment = true; - secure_messaging = local_amos_eid; - } - - # SmartCard-HSM with contact-based interface or USB-Stick - card_atr 3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA { - driver = "sc-hsm"; - read_only = false; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - } - - # SmartCard-HSM with contact-less interface - card_atr 3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18 { - driver = "sc-hsm"; - read_only = false; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - } - - # SmartCard-HSM 4k with contact-based interface or USB-Stick - card_atr 3b:de:18:ff:81:91:fe:1f:c3:80:31:81:54:48:53:4d:31:73:80:21:40:81:07:1c { - driver = "sc-hsm"; - read_only = false; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - } - - # SmartCard-HSM with fingerprint sensor and PIN pad - card_atr 3B:80:80:01:01 { - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - - # GoID with fingerprint sensor and PIN pad - card_atr 3B:84:80:01:47:6f:49:44:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:85:80:01:47:6f:49:44:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:86:80:01:47:6f:49:44:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:87:80:01:47:6f:49:44:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:88:80:01:47:6f:49:44:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:89:80:01:47:6f:49:44:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8A:80:01:47:6f:49:44:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8B:80:01:47:6f:49:44:00:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8C:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8D:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8E:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - - # GoID with fingerprint sensor and PIN pad - card_atr 3B:8F:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00 { - atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00"; - driver = "sc-hsm"; - force_protocol = "t1"; - read_only = true; - md_supports_X509_enrollment = true; - md_supports_container_key_gen = true; - md_guid_as_label = true; - md_pinpad_dlg_main = "Fingerabdruck oder PIN eingeben"; - md_pinpad_dlg_content_user = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN auf der Karte."; - md_pinpad_dlg_content_user_sign = "Bitte verifizieren Sie Ihren Fingarabdruck oder Ihre PIN für die digitale Signatur auf der Karte."; - md_pinpad_dlg_content_admin = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein."; - md_pinpad_dlg_expanded = "Dieses Fenster wird automatisch geschlossen, wenn die PIN oder der Fingerabdruck verifiziert wurde (Timeout nach 30 Sekunden). Nutzen Sie das PIN-Pad, um die Eingabe abzubrechen."; - md_pinpad_dlg_timeout = 30; - notify_card_inserted = "GoID erkannt"; - notify_card_inserted_text = ""; - notify_card_removed = "GoID entfernt"; - notify_pin_good = "Fingerabdruck bzw. PIN verifiziert"; - notify_pin_good_text = "GoID ist entsperrt"; - notify_pin_bad = "Fingerabdruck bzw. PIN nicht verifiziert"; - notify_pin_bad_text = "GoID ist gesperrt"; - } - - secure_messaging local_authentic { - # name of external SM module - # module_name = @DEFAULT_SM_MODULE@; - # directory with external SM module - # Default: @DEFAULT_SM_MODULE_PATH@ - # module_path = @DEFAULT_SM_MODULE_PATH@; - - # specific data to tune the module initialization - # module_data = "Here can be your SM module init data"; - - # SM mode: - # 'transmit' -- in this mode the procedure to securize an APDU is called by the OpenSC general - # APDU transmit procedure. - # In this mode all APDUs, except the ones filtered by the card specific procedure, - # are securized. - # 'acl' -- in this mode APDU are securized only if needed by the ACLs of the command to be executed. - # - mode = transmit; - - # SM type specific flags - flags = 0x78; # 0x78 -- level 3, channel 0 - - # Default KMC of the GP Card Manager for the Oberthur's Java cards - kmc = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"; - } - - secure_messaging local_gemalto_iam { - module_name = @DEFAULT_SM_MODULE@; - # module_path = @DEFAULT_SM_MODULE_PATH@; - # module_data = ""; - type = acl; # transmit, acl - - ifd_serial = "11:22:33:44:55:66:77:88"; - - # Keyset values from IAM profiles of the Gemalto IAS/ECC cards - keyset_02_enc = "RW_PRIV_ENC_TEST"; - keyset_02_mac = "RW_PRIV_MAC_TEST"; - - keyset_E828BD080FD2504543432D654944_01_enc = "RO_ENC_TEST_KEY_"; - keyset_E828BD080FD2504543432D654944_01_mac = "RO_MAC_TEST_KEY_"; - - keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST"; - keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST"; - } - - secure_messaging local_amos { - module_name = @DEFAULT_SM_MODULE@; - # module_path = @DEFAULT_SM_MODULE_PATH@; - # module_data = ""; - mode = acl; - ifd_serial = "11:22:33:44:55:66:77:88"; - keyset_02_enc = "ENCROECHANTILLON"; - keyset_02_mac = "MACROECHANTILLON"; - } - - secure_messaging local_amos_eid { - module_name = @DEFAULT_SM_MODULE@; - # module_path = @DEFAULT_SM_MODULE_PATH@; - # module_data = ""; - mode = acl; - ifd_serial = "11:22:33:44:55:66:77:88"; - keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST"; - keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST"; - } - - secure_messaging local_adele { - module_name = @DEFAULT_SM_MODULE@; - # module_path = @DEFAULT_SM_MODULE_PATH@; - # module_data = ""; - type = acl; # transmit, acl - - ifd_serial = "11:22:33:44:55:66:77:88"; - - # Keyset values from 'Adele' profiles of the IAS/ECC cards - keyset_01_enc = "EMENCECHANTILLON"; - keyset_01_mac = "EMMACECHANTILLON"; - - keyset_02_enc = "AAENCECHANTILLON"; - keyset_02_mac = "AAMACECHANTILLON"; - - keyset_E828BD080FD2500000040301_02_enc = "E2ENCECHANTILLON"; - keyset_E828BD080FD2500000040301_02_mac = "E2MACECHANTILLON"; - - keyset_D2500000044164E86C650101_02_enc = "E1ENCECHANTILLON"; - keyset_D2500000044164E86C650101_02_mac = "E1MACECHANTILLON"; - - keyset_D2500000044164E86C650101_03_enc = "SIENCECHANTILLON"; - keyset_D2500000044164E86C650101_03_mac = "SIMACECHANTILLON"; - } - - # Below are the framework specific configuration blocks. - - # PKCS #15 - framework pkcs15 { - # Whether to use the cache files in the user's - # home directory. - # - # Note: If caching is done by a system process, caching may be placed - # inaccessible from the user account. Use a global caching directory if - # you wish to share the cached information. - # - # Default: false - use_file_caching = true; - # - # set a path for caching - # so you do not use the env variables and for pam_pkcs11 - # (with certificate check) where $HOME is not set - # Default: path in user home - # file_cache_dir = /var/lib/opensc/cache - - # Use PIN caching? - # Default: true - use_pin_caching = false; - # - # How many times to use a PIN from cache before re-authenticating it? - # Default: 10 - pin_cache_counter = 3; - # - # Older PKCS#11 applications not supporting CKA_ALWAYS_AUTHENTICATE - # may need to set this to get signatures to work with some cards. - # Default: false - # It is recommended to enable also use_pin_caching to allow OpenSC - # to pass the pin to the card when needed. - pin_cache_ignore_user_consent = true; - - # How to handle a PIN-protected certificate - # Valid values: protect, declassify, ignore. - # Default: ignore in tokend, protect otherwise - private_certificate = declassify; - - # Enable pkcs15 emulation. - # Default: yes - enable_pkcs15_emulation = no; - # - # Prefer pkcs15 emulation code before - # the normal pkcs15 processing. - # Some cards (like esteid and pteid) work in emu-only mode, - # and do not depend on this option. - # - # Default: no - try_emulation_first = yes; - - # Enable builtin emulators. - # Default: yes - enable_builtin_emulation = no; - # - # List of the builtin pkcs15 emulators to test - # Special value of 'internal' will try all not disabled builtin pkcs15 emulators. - # Special value of 'old' will try all disabled pkcs15 emulators. - # Default: internal; - builtin_emulators = old, internal; - - # additional settings per driver - # - # For pkcs15 emulators loaded from an external shared - # library/DLL, you need to specify the path name of the module - # and customize the card_atr example above correctly. - # - emulate custom { - # The location of the driver library - module = @LIBDIR@@LIB_PRE@p15emu_custom@DYN_LIB_EXT@; - } - - # Enable initialization and card recognition in PKCS#11 layer. - # Default: no - # pkcs11_enable_InitToken = yes; - - # some additional application parameters: - # - type (generic, protected) used to distinguish the common access application - # and application for which authentication to perform some operation cannot be - # obtained with the common procedures (ex. object creation protected by secure messaging). - # Used by PKCS#11 module configured to expose restricted number of slots. - # (for ex. configured to expose only User PIN slot, User and Sign PINs slots, ...) - # - # - disable: do not expose application in PKCS15 framework - # default 'false' - application E828BD080FD25047656E65726963 { - type = generic; - model = "ECC Generic PKI"; - # disable = true - } - - application E828BD080FD2500000040301 { - type = generic; - model = "Adèle Générique"; - } - - application E828BD080FD2504543432D654944 { - type = protected; - model = "ECC eID"; - } - - application E828BD080FD2500000040201 { - type = protected; - model = "Adèle Admin-2"; - } - } -} - -# Parameters for the OpenSC PKCS11 module -app opensc-pkcs11 { - pkcs11 { - # Maximum Number of virtual slots. - # If there are more slots than defined here, - # the remaining slots will be hidden from PKCS#11. - # Default: 16 - max_virtual_slots = 32; - - # Maximum number of slots per smart card. - # If the card has fewer keys than defined here, - # the remaining number of slots will be empty. - # Default: 4 - slots_per_card = 2; - - # (max_virtual_slots/slots_per_card) limits the number of readers - # that can be used on the system. Default is then 16/4=4 readers. - - # By default, the OpenSC PKCS#11 module will not lock your card - # once you authenticate to the card via C_Login. - # - # Thus the other users or other applications is not prevented - # from connecting to the card and perform crypto operations - # (which may be possible because you have already authenticated - # with the card). This setting is not very secure. - # - # Also, if your card is not locked, you can enconter problems - # due to limitation of the OpenSC framework, that still is not - # thoroughly tested in the multi threads environment. - # - # Your settings will be more secure if you choose to lock your - # card. Nevertheless this behavior is a known violation of PKCS#11 - # specification. Now once one application has started using your - # card with C_Login, no other application can use it, until - # the first is done and calls C_Logout or C_Finalize. In the case - # of many PKCS#11 application this does not happen until you exit - # the application. - # Thus it is impossible to use several smart card aware applications - # at the same time, e.g. you cannot run both Firefox and Thunderbird at - # the same time, if both are configured to use your smart card. - # - # Default: false - lock_login = true; - - # By default, interacting with the OpenSC PKCS#11 module may change the - # state of the token, e.g. whether a user is logged in or not. - # - # Thus other users or other applications may change or use the state of - # the token unknowingly. Other applications may create signatures - # abusing an existing login or they may logout unnoticed. - # - # With this setting enabled the login state of the token is tracked and - # cached (including the PIN). Every transaction is preceded by - # restoring the login state. After every transaction a logout is - # performed. This setting by default also enables `lock_login` (see - # above) to disable access for other applications during the atomic - # transactions. - # - # Please note that any PIN-pad should be disabled (see `enable_pinpad` - # above), because the user would have to input his PIN for every - # transaction. - # - # Default: false - atomic = true; - - # With this setting disabled, the OpenSC PKCS#11 module will initialize - # the slots available when the application calls `C_GetSlotList`. With - # this setting enabled, the slots will also get initialized when - # C_GetSlotInfo is called. - # - # This setting is a workaround for Java which does not call - # `C_GetSlotList` when configured with a static `slot` instead of - # `slotListIndex`. - # - # Default: true - init_sloppy = false; - - # User PIN unblock style - # none: PIN unblock is not possible with PKCS#11 API; - # set_pin_in_unlogged_session: C_SetPIN() in unlogged session: - # PUK is passed as the 'OldPin' argument of the C_SetPIN() call. - # set_pin_in_specific_context: C_SetPIN() in the CKU_SPECIFIC_CONTEXT logged session: - # PUK is passed as the 'OldPin' argument of the C_SetPIN() call. - # init_pin_in_so_session: C_InitPIN() in CKU_SO logged session: - # User PIN 'UNBLOCK' is protected by SOPIN. (PUK == SOPIN). - # # Actually this style works only for the PKCS15 contents without SOPIN. - # # For those with SOPIN, this mode will be useful for the cards without - # # modes 00 and 01 of ISO command 'RESET RETRY COUNTER'. --vt - # - # Default: none - user_pin_unblock_style = set_pin_in_unlogged_session; - - # Create slot for unblocking PIN with PUK - # This way PKCS#11 API can be used to login with PUK and - # change a PIN. - # Warning: causes problems with some applications like - # firefox and thunderbird. Thus turned off by default - # - # Default: false - create_puk_slot = true; - - # Symbolic names of PINs for which slots are created - # Card can contain more then one PINs or more then one on-card application with - # its own PINs. Normally, to access all of them with the PKCS#11 API a slot has to be - # created for all of them. Many slots could be ennoying for some of widely used application, - # like FireFox. This configuration parameter allows one to select the PIN(s) - # for which PKCS#11 slot will be created. - # Actually recognised following symbolic names: - # 'user', 'sign', 'all' - # Only PINs initialised, non-SoPIN, non-unblocking are associated with symbolic name. - # 'user' is identified as first global or first local PIN. - # 'sign' is identified as second PIN: first local, second global or second local. - # 'all' slot created for all non-sopin, non-unblocking PINs, - # optionally for PUK (see option 'create_puk_slot') - # - # Default: all - create_slots_for_pins = "user,sign"; - create_slots_for_pins = "sign"; - # - # For the module to simulate the opensc-onepin module behavior the following option - # must be set: - create_slots_for_pins = "user" - } -} - -app onepin-opensc-pkcs11 { - pkcs11 { - slots_per_card = 1; - } -} - -# Used by OpenSC.tokend on Mac OS X only -app tokend { - # The file to which debug log will be written - # Default: /tmp/opensc-tokend.log - # - # debug_file = /Library/Logs/OpenSC.tokend.log - - framework tokend { - # Score for OpenSC.tokend - # The tokend with the highest score shall be used. - # Default: 300 - # - score = 10; - - # Tokend ignore to read PIN protected certificate that is set SC_PKCS15_CO_FLAG_PRIVATE flag. - # Default: true - # - ignore_private_certificate = false; - } -} - -# Used by OpenSC minidriver on Windows only -app cardmod { -} - diff --git a/src/tests/fuzzing/fuzz_scconf_parse_string.c b/src/tests/fuzzing/fuzz_scconf_parse_string.c index 0d2d2b150e..a53c385d3b 100644 --- a/src/tests/fuzzing/fuzz_scconf_parse_string.c +++ b/src/tests/fuzzing/fuzz_scconf_parse_string.c @@ -25,14 +25,23 @@ #include "scconf/scconf.h" #include "libopensc/internal.h" +#include +#define MAX_SIZE 5500 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - scconf_context *ctx = scconf_new(NULL); + scconf_context *ctx = NULL; + char buf[MAX_SIZE]; - if (!ctx) + if (size == 0 || size > MAX_SIZE) + return 0; + + if (!(ctx = scconf_new(NULL))) return 1; - const char *buf = (const char *)data; + + memcpy(buf, data, size); + buf[size - 1] = '\0'; + scconf_parse_string(ctx, buf); scconf_free(ctx); From 1dceff47dda034b3039d1304191b7c707247a6de Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 15 Oct 2021 16:01:36 +0200 Subject: [PATCH 2067/4321] scconf: Fix check for buffer size buf_addch() store values on bp->bufcur and bp->bufcur + 1 but check size of the buffer only for bp->bufcur. --- src/scconf/sclex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scconf/sclex.c b/src/scconf/sclex.c index 44b1a47205..144b8db36f 100644 --- a/src/scconf/sclex.c +++ b/src/scconf/sclex.c @@ -56,7 +56,7 @@ static void buf_init(BUFHAN * bp, FILE * fp, const char *saved_string) static void buf_addch(BUFHAN * bp, char ch) { - if (bp->bufcur >= bp->bufmax) { + if (bp->bufcur + 1 >= bp->bufmax) { char *p = (char *) realloc(bp->buf, bp->bufmax + 256); if (!p) return; From 2e022aeaa1e7b504e867d745d7d52696d4ec7c84 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 15 Oct 2021 16:04:34 +0200 Subject: [PATCH 2068/4321] scconf: Avoid adding list into non-list item Issue found by calling scconf_string_parse() with "name =\n\n\nvalue,value;" as an input string. scconf_parse_token() interprets more newline characters as item with type SCCONF_ITEM_TYPE_COMMENT. After that when parsing TOKEN_TYPE_STRING, if parser->state is STATE_VALUE, scconf_list_add() adds list into that item. During freeing scconf_context structure, above described item is freed as SCCONF_ITEM_TYPE_COMMENT and created list causes memory leak. To fix this, scconf_parse_token() checks type of item before adding into list. When parsing is done, scconf_parse_reset_state() frees values in parser->name and parser->key. --- src/scconf/parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scconf/parse.c b/src/scconf/parse.c index 0a58b79c10..a050c6f5e2 100644 --- a/src/scconf/parse.c +++ b/src/scconf/parse.c @@ -298,7 +298,7 @@ void scconf_parse_token(scconf_parser * parser, int token_type, const char *toke /* name */ parser->state |= STATE_SET; scconf_list_add(&parser->name, stoken); - } else if (parser->state == STATE_VALUE) { + } else if (parser->state == STATE_VALUE && parser->current_item->type == SCCONF_ITEM_TYPE_VALUE) { /* value */ parser->state |= STATE_SET; scconf_list_add(&parser->current_item->value.list, @@ -421,6 +421,8 @@ int scconf_parse_string(scconf_context * config, const char *string) r = 1; } + scconf_parse_reset_state(&p); + if (r <= 0) config->errmsg = buffer; return r; From 89f86239e64b63bbd6c45f891d6079a242287921 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 20 Oct 2021 15:17:40 +0200 Subject: [PATCH 2069/4321] fuzzing: fix description of fuzzer.c file --- src/tests/fuzzing/fuzzer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzzer.c b/src/tests/fuzzing/fuzzer.c index 6051599b43..ff80f1a241 100644 --- a/src/tests/fuzzing/fuzzer.c +++ b/src/tests/fuzzing/fuzzer.c @@ -1,5 +1,5 @@ /* - * fuzz_scconf_parse.c: Fuzz target for scconf_parse + * fuzzer.c: Standalone main for fuzz target * * Copyright (C) 2021 Red Hat, Inc. * From 9f4eae63aea7c5c0a55ceeb2450de5b9620e640e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 2 Nov 2021 15:33:55 +0100 Subject: [PATCH 2070/4321] fuzz_scconf_parse_string: Use malloc for string buffer --- src/tests/fuzzing/fuzz_scconf_parse_string.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/tests/fuzzing/fuzz_scconf_parse_string.c b/src/tests/fuzzing/fuzz_scconf_parse_string.c index a53c385d3b..0a0cdca57e 100644 --- a/src/tests/fuzzing/fuzz_scconf_parse_string.c +++ b/src/tests/fuzzing/fuzz_scconf_parse_string.c @@ -25,25 +25,26 @@ #include "scconf/scconf.h" #include "libopensc/internal.h" +#include #include -#define MAX_SIZE 5500 - int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { scconf_context *ctx = NULL; - char buf[MAX_SIZE]; + char *buf = NULL; - if (size == 0 || size > MAX_SIZE) + if (!(buf = malloc(size + 1))) return 0; - - if (!(ctx = scconf_new(NULL))) - return 1; + if (!(ctx = scconf_new(NULL))) { + free(buf); + return 0; + } memcpy(buf, data, size); - buf[size - 1] = '\0'; + buf[size] = '\0'; scconf_parse_string(ctx, buf); scconf_free(ctx); + free(buf); return 0; } From 45c92bbcbd95d7efae67bf3bf2576ecd3bfc1529 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 9 Nov 2021 17:21:48 +0100 Subject: [PATCH 2071/4321] fixed handling of GET RESPONSE Upon reading a few number of bytes with GET DATA, Yubikey 4 responds with these bytes *and* 61XX indicating that there is even more data available (although it has not been requested). In `sc_get_response()` we need to check early whether or not additional bytes are needed, otherwise an unnecessary GET RESPONSE will be triggered. --- src/libopensc/apdu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index b52183ea26..e73aea6064 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -455,6 +455,10 @@ sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen) unsigned char resp[256]; size_t resp_len = le; + /* we have all the data the caller requested even if the card has more data */ + if (buflen == 0) + break; + /* call GET RESPONSE to get more date from the card; * note: GET RESPONSE returns the left amount of data (== SW2) */ memset(resp, 0, sizeof(resp)); @@ -478,10 +482,6 @@ sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen) buf += le; buflen -= le; - /* we have all the data the caller requested even if the card has more data */ - if (buflen == 0) - break; - minlen -= le; if (rv != 0) le = minlen = (size_t)rv; @@ -521,18 +521,20 @@ sc_transmit(sc_card_t *card, sc_apdu_t *apdu) * 1. the card returned 0x6Cxx: in this case APDU will be re-transmitted with Le set to SW2 * (possible only if response buffer size is larger than new Le = SW2) */ - if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) + if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) { r = sc_set_le_and_transmit(card, apdu, olen); - LOG_TEST_RET(ctx, r, "cannot re-transmit APDU "); + LOG_TEST_RET(ctx, r, "cannot re-transmit APDU "); + } /* 2. the card returned 0x61xx: more data can be read from the card * using the GET RESPONSE command (mostly used in the T0 protocol). * Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as * much data as possible using GET RESPONSE. */ - if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) + if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) { r = sc_get_response(card, apdu, olen); - LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'"); + LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'"); + } LOG_FUNC_RETURN(ctx, SC_SUCCESS); } From 24315fa2fee2128b2937f1f54cd8ab79df3087fe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Nov 2021 16:31:59 +0100 Subject: [PATCH 2072/4321] opensc-tool: clearify on the usage of --send-apdu closes https://github.com/OpenSC/OpenSC/issues/2432 closes https://github.com/OpenSC/OpenSC/issues/2369 --- doc/tools/opensc-tool.1.xml | 15 +++++++++++++-- src/tools/opensc-tool.c | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/tools/opensc-tool.1.xml b/doc/tools/opensc-tool.1.xml index 43acf612c3..bf9cf039ee 100644 --- a/doc/tools/opensc-tool.1.xml +++ b/doc/tools/opensc-tool.1.xml @@ -141,8 +141,19 @@ apdu, apdu - Sends an arbitrary APDU to the card in the format - AA:BB:CC:DD:EE:FF.... + + + Sends an arbitrary APDU to the card in the format + AA:BB:CC:DD:EE:FF.... Use this option + multiple times to send more than one APDU. + + + The built-in card drivers may send additional APDUs + for detection and initialization. To avoid this + behavior, you may additionally specify + default. + + diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index bbed4d9d09..9b4600cbc6 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -87,7 +87,7 @@ static const char *option_help[] = { "Lists readers", "Lists all installed card drivers", "Recursively lists files stored on card", - "Sends an APDU in format AA:BB:CC:DD:EE:FF...", + "Sends an APDU (may need '-c default')", "Uses reader number [0]", "Does card reset of type [cold]", "Forces the use of driver [auto-detect; '?' for list]", From 233db1fc3578d9634d4c19664dd5b25adc876cbe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Nov 2021 16:47:38 +0100 Subject: [PATCH 2073/4321] opensc-tool: align help to 80 characters --- src/tools/opensc-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 9b4600cbc6..d00eb30ecd 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -82,18 +82,18 @@ static const char *option_help[] = { "Prints the ATR bytes of the card", "Prints the card serial number", "Identify the card and print its name", - "Get configuration key, format: section:name:key", - "Set configuration key, format: section:name:key:value", + "Get configuration, e.g. section:name:key", + "Set configuration, e.g. section:name:key:val", "Lists readers", "Lists all installed card drivers", "Recursively lists files stored on card", "Sends an APDU (may need '-c default')", "Uses reader number [0]", "Does card reset of type [cold]", - "Forces the use of driver [auto-detect; '?' for list]", + "Forces a card driver (use '?' for list)", "Lists algorithms supported by card", "Wait for a card to be inserted", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static sc_context_t *ctx = NULL; From 5f04d4905d65202e2c64e43b836433ee96cffcd7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Nov 2021 16:57:55 +0100 Subject: [PATCH 2074/4321] tools: shorten help text on -v --- src/tools/cardos-tool.c | 2 +- src/tools/cryptoflex-tool.c | 2 +- src/tools/dnie-tool.c | 2 +- src/tools/gids-tool.c | 2 +- src/tools/iasecc-tool.c | 2 +- src/tools/openpgp-tool.c | 2 +- src/tools/opensc-explorer.c | 2 +- src/tools/piv-tool.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- src/tools/pkcs15-init.c | 2 +- src/tools/pkcs15-tool.c | 2 +- src/tools/sc-hsm-tool.c | 2 +- src/tools/westcos-tool.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index fcf275d996..a2dc6b297c 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -68,7 +68,7 @@ static const char *option_help[] = { "Change Startkey with given APDU command", "Uses reader number [0]", "Wait for a card to be inserted", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static sc_context_t *ctx = NULL; diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 2048871f26..ad09f4df49 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -82,7 +82,7 @@ static const char *option_help[] = { "Modulus length to use in key generation [1024]", "Uses reader ", "Wait for card insertion", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static sc_context_t *ctx = NULL; diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index eea5fd1434..cafe854318 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -75,7 +75,7 @@ static const char *option_help[] = { "Show DNIe number, Name, and SurName", "Show DNIe serial number", "Display all the information available", - "Verbose operation. Use several times to enable debug output." + "Verbose operation, may be used several times", }; /* Get DNIe device extra information */ diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 1c9602b043..eb4ccc733b 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -87,7 +87,7 @@ static const char *option_help[] = { "Define the new administrator key", "Uses reader number [0]", "Wait for a card to be inserted", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, const char* serial) diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 645373e19f..301ad89d0a 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -68,7 +68,7 @@ static const char *option_help[] = { "List the on-card PKCS#15 applications", "List the SDOs with the tag in the current ADF", "Wait for card insertion", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", NULL }; diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 9cf8982330..1f3be0fb94 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -138,7 +138,7 @@ static const char *option_help[] = { /* G */ "Generate key", /* t */ "Key type (default: rsa2048)", /* h */ "Print this help message", -/* v */ "Verbose operation. Use several times to enable debug output.", +/* v */ "Verbose operation, may be used several times", /* V */ "Show version number", /* E */ "Erase (reset) the card", "Verify PIN (CHV1, CHV2, CHV3...)", diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index e48f3189bd..9ec4daa173 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -87,7 +87,7 @@ static const char *option_help[] = { "Forces the use of driver [auto-detect; '?' for list]", "Selects path on start-up, or none if empty [3F00]", "Wait for card insertion", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 85d24355f8..dec2820f97 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -99,7 +99,7 @@ static const char *option_help[] = { "Sends an APDU in format AA:BB:CC:DD:EE:FF...", "Uses reader number [0]", "Wait for a card to be inserted", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static sc_context_t *ctx = NULL; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index d7ce7b9578..c0db1abbaf 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -106,7 +106,7 @@ static const char *option_help[] = { "Uses password (PIN) (use - for reading PIN from STDIN)", "Specify AID of the on-card PKCS#15 application to be binded to (in hexadecimal form)", "Wait for card insertion", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; static sc_context_t *ctx = NULL; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e148433567..e411baedc0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -279,7 +279,7 @@ static const char * option_help[] = { "For a new key specify GUID for a MD container", "Wait for card insertion", "Display this message", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", NULL, NULL, diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 2c01aa961a..f4900be4e8 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -193,7 +193,7 @@ static const char *option_help[] = { "The auth ID of the PIN to use", "Specify AID of the on-card PKCS#15 application to bind to (in hexadecimal form)", "Wait for card insertion", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", "Do not prompt the user; if no PINs supplied, pinpad will be used.", NULL, NULL diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 2c0d0e45e2..4104e4e2e0 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -129,7 +129,7 @@ static const char *option_help[] = { "Force replacement of key and certificate", "Uses reader number [0]", "Wait for a card to be inserted", - "Verbose operation. Use several times to enable debug output.", + "Verbose operation, may be used several times", }; typedef struct { diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 7e57615a4f..2e98ea3abf 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -79,7 +79,7 @@ static const char *option_help[] = { "Read file ", "Write file (ex 0002 write file 0002 to 0002)", "This message", - "Verbose operation. Use several times to enable debug output." + "Verbose operation, may be used several times", }; From e8486b4fa0331989225a2933c57297e427e2d59d Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Fri, 22 Oct 2021 09:52:36 +0200 Subject: [PATCH 2075/4321] Implement C_CreateObject() for EC keys Most of the code was already there, only a little glue code was needed... --- src/pkcs11/framework-pkcs15.c | 51 ++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 5a3cb99e37..7e327712c5 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2217,6 +2217,7 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil CK_KEY_TYPE key_type; struct sc_pkcs15_prkey_rsa *rsa = NULL; struct sc_pkcs15_prkey_gostr3410 *gost = NULL; + struct sc_pkcs15_prkey_ec *ec = NULL; int rc; CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; @@ -2258,8 +2259,8 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil return CKR_ATTRIBUTE_VALUE_INVALID; case CKK_EC: args.key.algorithm = SC_ALGORITHM_EC; - /* TODO: -DEE Do not have PKCS15 card with EC to test this */ - /* fall through */ + ec = &args.key.u.ec; + break; default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -2297,6 +2298,17 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil case CKA_VALUE: if (key_type == CKK_GOSTR3410) bn = &gost->d; + if (key_type == CKK_EC) + bn = &ec->privateD; + break; + case CKA_EC_PARAMS: + ec->params.der.value = calloc(1, attr->ulValueLen); + ec->params.der.len = attr->ulValueLen; + rv = attr_extract(attr, ec->params.der.value, &ec->params.der.len); + if (rv != CKR_OK) + goto out; + if (sc_pkcs15_fix_ec_parameters(p11card->card->ctx, &ec->params) != SC_SUCCESS) + return CKR_ATTRIBUTE_VALUE_INVALID; break; case CKA_SIGN: args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_SIGN); @@ -2349,6 +2361,12 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil goto out; } } + else if (key_type == CKK_EC) { + if (!ec->privateD.len || !ec->params.field_length) { + sc_log(context, "Template to store the EC private key is incomplete"); + return CKR_TEMPLATE_INCOMPLETE; + } + } rc = sc_pkcs15init_store_private_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { @@ -2573,6 +2591,7 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile struct sc_pkcs15_auth_info *pin = NULL; CK_KEY_TYPE key_type; struct sc_pkcs15_pubkey_rsa *rsa = NULL; + struct sc_pkcs15_pubkey_ec *ec = NULL; int rc; CK_RV rv; char label[SC_PKCS15_MAX_LABEL_SIZE]; @@ -2600,6 +2619,9 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile rsa = &args.key.u.rsa; break; case CKK_EC: + args.key.algorithm = SC_ALGORITHM_EC; + ec = &args.key.u.ec; + break; case CKK_EC_EDWARDS: case CKK_EC_MONTGOMERY: /* TODO: -DEE Do not have real pkcs15 card with EC */ @@ -2644,6 +2666,19 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile case CKA_WRAP: args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_WRAP); break; + case CKA_EC_POINT: + if (key_type == CKK_EC) { + if (sc_pkcs15_decode_pubkey_ec(p11card->card->ctx, ec, attr->pValue, attr->ulValueLen) < 0) + return CKR_ATTRIBUTE_VALUE_INVALID; + } + break; + case CKA_EC_PARAMS: + ec->params.der.value = calloc(1, attr->ulValueLen); + ec->params.der.len = attr->ulValueLen; + rv = attr_extract(attr, ec->params.der.value, &ec->params.der.len); + if (rv != CKR_OK) + return CKR_ATTRIBUTE_VALUE_INVALID; + break; default: /* ignore unknown attrs, or flag error? */ continue; @@ -2657,8 +2692,16 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } } - if (!rsa->modulus.len || !rsa->exponent.len) - return CKR_TEMPLATE_INCOMPLETE; + if (key_type == CKK_RSA) { + if (!rsa->modulus.len || !rsa->exponent.len) + return CKR_TEMPLATE_INCOMPLETE; + } + else if (key_type == CKK_EC) { + if (!ec->ecpointQ.len || !ec->params.der.value) { + sc_log(context, "Template to store the EC public key is incomplete"); + return CKR_TEMPLATE_INCOMPLETE; + } + } rc = sc_pkcs15init_store_public_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) From 0f30997b6d555e981777087995285efbf6a30359 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 27 Oct 2021 10:25:55 +0200 Subject: [PATCH 2076/4321] Fix signature verification for CKM_ECDSA_SHAx only cards Cards that support CKM_ECDSA_SHAx only don't do the hashing in C_VerifyUpdate(). All the processing is done in the final C_VerifyFinal() call instead. --- src/pkcs11/openssl.c | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 1c8011b1d7..bc4aed1e4c 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -520,15 +520,74 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len sc_log(context, "EVP_VerifyFinal() returned %d\n", res); return CKR_GENERAL_ERROR; } - } else if (md == NULL && mech->mechanism == CKM_ECDSA) { + } else /* If plain CKM_ECDSA (without any hashing) is used or card supports + * on-card CKM_ECDSA_SHAx only we land here. Since for CKM_ECDSA_SHAx no + * hashing happened in C_VerifyUpdate() we do it here instead. + */ + if (md == NULL && (mech->mechanism == CKM_ECDSA + || mech->mechanism == CKM_ECDSA_SHA1 + || mech->mechanism == CKM_ECDSA_SHA224 + || mech->mechanism == CKM_ECDSA_SHA256 + || mech->mechanism == CKM_ECDSA_SHA384 + || mech->mechanism == CKM_ECDSA_SHA512)) { size_t signat_len_tmp; unsigned char *signat_tmp = NULL; + unsigned int mdbuf_len; + unsigned char *mdbuf = NULL; EVP_PKEY_CTX *ctx; const EC_KEY *eckey; int r; sc_log(context, "Trying to verify using EVP"); + /* If needed, hash input first + */ + if (mech->mechanism == CKM_ECDSA_SHA1 + || mech->mechanism == CKM_ECDSA_SHA224 + || mech->mechanism == CKM_ECDSA_SHA256 + || mech->mechanism == CKM_ECDSA_SHA384 + || mech->mechanism == CKM_ECDSA_SHA512) { + EVP_MD_CTX *mdctx; + const EVP_MD *md; + switch (mech->mechanism) { + case CKM_ECDSA_SHA1: + md = EVP_sha1(); + break; + case CKM_ECDSA_SHA224: + md = EVP_sha224(); + break; + case CKM_ECDSA_SHA256: + md = EVP_sha256(); + break; + case CKM_ECDSA_SHA384: + md = EVP_sha384(); + break; + case CKM_ECDSA_SHA512: + md = EVP_sha512(); + break; + default: + return CKR_GENERAL_ERROR; + } + mdbuf_len = EVP_MD_size(md); + mdbuf = calloc(1, mdbuf_len); + if (mdbuf == NULL) + return CKR_DEVICE_MEMORY; + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + free(mdbuf); + return CKR_GENERAL_ERROR; + } + if (!EVP_DigestInit(mdctx, md) + || !EVP_DigestUpdate(mdctx, data, data_len) + || !EVP_DigestFinal(mdctx, mdbuf, &mdbuf_len)) { + EVP_MD_CTX_free(mdctx); + free(mdbuf); + return CKR_GENERAL_ERROR; + } + EVP_MD_CTX_free(mdctx); + data = mdbuf; + data_len = mdbuf_len; + } + res = 0; r = sc_asn1_sig_value_rs_to_sequence(NULL, signat, signat_len, &signat_tmp, &signat_len_tmp); @@ -540,6 +599,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); free(signat_tmp); + free(mdbuf); if (res == 1) return CKR_OK; From 88eeb8923d8a1b2848f85650fe2b804b3a53e648 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 27 Oct 2021 10:26:35 +0200 Subject: [PATCH 2077/4321] Fix IsoApplet CKM_ECDSA_SHA1 implementation and include some more ECDSA tests in IsoApplet test suite --- .github/test-isoapplet.sh | 17 +++++++++++++++++ src/libopensc/card-isoApplet.c | 5 ++--- src/tests/p11test/isoapplet_ref.json | 24 ------------------------ 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index e23313498c..5a4e03a02e 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -12,6 +12,8 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then git clone https://github.com/philipWendland/IsoApplet.git + # enable IsoApplet key import patch + sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i IsoApplet/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java fi javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg @@ -66,6 +68,21 @@ sleep 5 ./p11test -s 0 -p 123456 -o isoapplet.json || true # ec_sign_size_test is failing here popd +# random data to be signed +dd if=/dev/random of=/tmp/data.bin bs=300 count=1 +# sign & verify using secp256r1 key +pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 3 -i /tmp/data.bin -o /tmp/data.sig +pkcs11-tool --verify -m ECDSA-SHA1 -d 3 -i /tmp/data.bin --signature-file /tmp/data.sig +# import, sign & verify using another secp256r1 key +openssl ecparam -name secp256r1 -genkey -noout -out /tmp/ECprivKey.pem +openssl ec -in /tmp/ECprivKey.pem -pubout -out /tmp/ECpubKey.pem +pkcs11-tool -l -p 123456 -w /tmp/ECprivKey.pem -y privkey -d 4 +pkcs11-tool -l -p 123456 -w /tmp/ECpubKey.pem -y pubkey -d 4 +pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 4 -i /tmp/data.bin -o /tmp/data.sig +pkcs11-tool --verify -m ECDSA-SHA1 -d 4 -i /tmp/data.bin --signature-file /tmp/data.sig +# cleanup +rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig + kill -9 $PID diff -u3 src/tests/p11test/isoapplet{_ref,}.json diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 00743fef4c..d7656f8eea 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -234,7 +234,6 @@ isoApplet_init(sc_card_t *card) * should be kept in sync with the explicit parameters in the pkcs15-init * driver. */ flags = 0; - flags |= SC_ALGORITHM_ECDSA_RAW; flags |= SC_ALGORITHM_ECDSA_HASH_SHA1; flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_UNCOMPRESES; @@ -1116,14 +1115,14 @@ isoApplet_set_security_env(sc_card_t *card, break; case SC_ALGORITHM_EC: - if( env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW ) + if( env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1 ) { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; drvdata->sec_env_ec_field_length = env->algorithm_ref; } else { - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports raw ECDSA."); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports ECDSA with on-card SHA1."); } break; diff --git a/src/tests/p11test/isoapplet_ref.json b/src/tests/p11test/isoapplet_ref.json index 787e2f7980..b70f607588 100644 --- a/src/tests/p11test/isoapplet_ref.json +++ b/src/tests/p11test/isoapplet_ref.json @@ -62,30 +62,6 @@ "0", "CKF_DIGEST" ], - [ - "ECDSA_SHA224", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA256", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA384", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA512", - "192", - "384", - "0x00002800" - ], [ "ECDSA_SHA1", "192", From 2d183fe66262588941e7fb77f9f84264be1120ba Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 27 Oct 2021 12:37:33 +0200 Subject: [PATCH 2078/4321] Add JCOP4 NQ-Applet support --- src/libopensc/Makefile.am | 8 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-nqApplet.c | 553 ++++++++++++++++++++++++++++++++ src/libopensc/cards.h | 6 +- src/libopensc/ctx.c | 1 + src/libopensc/pkcs15-nqApplet.c | 233 ++++++++++++++ src/libopensc/pkcs15-syn.c | 2 + src/libopensc/pkcs15-syn.h | 1 + 8 files changed, 801 insertions(+), 7 deletions(-) create mode 100644 src/libopensc/card-nqApplet.c create mode 100644 src/libopensc/pkcs15-nqApplet.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index d544a98a8e..0f138a4776 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -50,14 +50,14 @@ libopensc_la_SOURCES_BASE = \ card-dnie.c cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c \ + card-edo.c card-nqApplet.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-gemsafeGPK.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ - pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c \ + pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ compression.c p15card-helper.c sm.c \ aux-data.c @@ -133,14 +133,14 @@ TIDY_FILES = \ cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c \ + card-edo.c card-nqApplet.c \ \ pkcs15-openpgp.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c \ pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ - pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c \ + pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ compression.c p15card-helper.c sm.c \ aux-data.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index b9bfc70f21..df27c032a3 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -28,7 +28,7 @@ OBJECTS = \ card-sc-hsm.obj card-dnie.obj card-isoApplet.obj pkcs15-coolkey.obj \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj card-esteid2018.obj card-idprime.obj \ - card-edo.obj \ + card-edo.obj card-nqApplet.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ @@ -36,7 +36,7 @@ OBJECTS = \ pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ - pkcs15-esteid2018.obj pkcs15-idprime.obj \ + pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ compression.obj p15card-helper.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c new file mode 100644 index 0000000000..331ae6dd93 --- /dev/null +++ b/src/libopensc/card-nqApplet.c @@ -0,0 +1,553 @@ +/* + * Support for the JCOP4 Cards with NQ-Applet + * + * Copyright (C) 2020 jozsefd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "asn1.h" +#include "cardctl.h" +#include "internal.h" +#include "log.h" + +#define APPLET_VERSION_LEN 2 +#define APPLET_MEMTYPE_LEN 1 +#define APPLET_SERIALNR_LEN 8 + +/* card constants */ +static const struct sc_atr_table nqapplet_atrs[] = +{ + { "3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL }, + { NULL, NULL, NULL, 0, 0, NULL } +}; + +static const u8 nqapplet_aid[] = {0xd2, 0x76, 0x00, 0x01, 0x80, 0xBA, 0x01, 0x44, 0x02, 0x01, 0x00}; + +static struct sc_card_operations nqapplet_operations; +static struct sc_card_operations *iso_operations = NULL; + +#define KEY_REFERENCE_NO_KEY 0x00 +#define KEY_REFERENCE_AUTH_KEY 0x01 +#define KEY_REFERENCE_ENCR_KEY 0x02 + +struct nqapplet_driver_data +{ + u8 version_minor; + u8 version_major; + u8 key_reference; + u8 serial_nr[APPLET_SERIALNR_LEN]; +}; +typedef struct nqapplet_driver_data * nqapplet_driver_data_ptr; + +static struct sc_card_driver nqapplet_driver = +{ + "NQ-Applet", // name + "nqapplet", // short name + &nqapplet_operations, // operations + NULL, // atr table + 0, // nr of atr + NULL // dll? +}; + +static const struct sc_card_error nqapplet_errors[] = +{ + { 0x6700, SC_ERROR_WRONG_LENGTH, "Invalid LC or LE"}, + { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" }, //TODO MK/DK?? + { 0x6985, SC_ERROR_NOT_ALLOWED, "Invalid PIN or key" }, + { 0x6986, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" }, + { 0x6A80, SC_ERROR_INVALID_ARGUMENTS, "Invalid parameters" }, + { 0x6A82, SC_ERROR_OBJECT_NOT_FOUND, "Data object not found"}, + { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory" }, + { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS, "Invalid P1 or P2" }, + { 0x6A88, SC_ERROR_INVALID_ARGUMENTS, "Wrong key ID" }, + { 0x6D00, SC_ERROR_FILE_NOT_FOUND, "Applet not found" } +}; + +/* convenience functions */ + +static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor, u8 * serial_nr, size_t cb_serial_nr) +{ + nqapplet_driver_data_ptr data = calloc(1, sizeof(struct nqapplet_driver_data)); + if (data == NULL) + { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + + data->version_major = version_major; + data->version_minor = version_minor; + data->key_reference = KEY_REFERENCE_NO_KEY; + memcpy(data->serial_nr, serial_nr, min(cb_serial_nr, sizeof(data->serial_nr))); + card->drv_data = (void*)data; + return SC_SUCCESS; +} + +/** + * SELECT NQ-Applet, on success it returns the applet version and card serial nr. + * + * @param[in] card + * @param[out,opt] version_major Version major of the applet + * @param[out,opt] version_minor Version minor of the applet + * @param[out,opt] serial_nr Buffer to receive serial number octets + * @param[in] cb_serial_nr Size of buffer in octets + * @param[out,opt] serial_nr_len The actual number of octet copied into serial_nr buffer + * + * @return SC_SUCCESS: The applet is present and selected. + * + */ +static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor, u8 *serial_nr, size_t cb_serial_nr, size_t *serial_nr_len) +{ + int rv; + sc_context_t *ctx = card->ctx; + sc_apdu_t apdu; + u8 buffer[APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN+2]; + size_t cb_buffer = sizeof(buffer); + size_t cb_aid = sizeof(nqapplet_aid); + + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); + apdu.lc = cb_aid; + apdu.data = nqapplet_aid; + apdu.datalen = cb_aid; + apdu.resp = buffer; + apdu.resplen = cb_buffer; + apdu.le = cb_buffer; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, rv, "APDU transmit failure."); + + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, rv, "Card returned error"); + + if ( version_major != NULL ) + { + *version_major = buffer[0]; + } + if ( version_minor != NULL ) + { + *version_minor = buffer[1]; + } + if ( serial_nr != NULL && cb_serial_nr > 0 && serial_nr_len != NULL ) + { + size_t cb = MIN(APPLET_SERIALNR_LEN, cb_serial_nr); + memcpy(serial_nr, buffer+3, cb); + *serial_nr_len = cb; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + + +/* driver operations API */ +static int nqapplet_match_card(struct sc_card *card) +{ + int rv = _sc_match_atr(card, nqapplet_atrs, &card->type); + return (rv >= 0); +} + +static int nqapplet_init(struct sc_card *card) +{ + u8 version_major; + u8 version_minor; + u8 serial_nr[APPLET_SERIALNR_LEN]; + size_t cb_serial_nr = sizeof(serial_nr); + unsigned long rsa_flags = 0; + + LOG_FUNC_CALLED(card->ctx); + int rv = select_nqapplet(card, &version_major, &version_minor, serial_nr, cb_serial_nr, &cb_serial_nr); + if ( rv != SC_SUCCESS ) + { + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Cannot select NQ-Applet."); + } + + rv = init_driver_data(card, version_major, version_minor, serial_nr, cb_serial_nr); + LOG_TEST_RET(card->ctx, rv, "Failed to initialize driver data."); + + card->max_send_size = 255; + card->max_recv_size = 256; + card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; + rsa_flags |= SC_ALGORITHM_RSA_RAW; + _sc_card_add_rsa_alg(card, 3072, rsa_flags, 0); + + card->serialnr.len = MIN(sizeof(card->serialnr.value), cb_serial_nr); + memcpy(card->serialnr.value, serial_nr, card->serialnr.len); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int nqapplet_finish(struct sc_card *card) +{ + nqapplet_driver_data_ptr data = (nqapplet_driver_data_ptr)card->drv_data; + + LOG_FUNC_CALLED(card->ctx); + if (data != NULL) + { + free(data); + card->drv_data=NULL; + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp) +{ + struct sc_apdu apdu; + int rv; + size_t resplen; + + LOG_FUNC_CALLED(card->ctx); + resplen = MIN(sc_get_max_recv_size(card), *cb_resp); + + sc_format_apdu_ex(&apdu, 0x80, 0xC0, 0x00, 0x00, NULL, 0, resp, resplen); + apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + if (apdu.resplen == 0) + { + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } + + *cb_resp = apdu.resplen; + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + rv = SC_SUCCESS; + } + else if (apdu.sw1 == 0x61) + { + rv = apdu.sw2 == 0 ? 256 : apdu.sw2; + } + else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) + { + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int nqapplet_get_challenge(struct sc_card *card, u8 * buf, size_t count) +{ + int r; + struct sc_apdu apdu; + + LOG_FUNC_CALLED(card->ctx); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00); + apdu.le = count; + apdu.resp = buf; + apdu.resplen = count; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed"); + + if (count < apdu.resplen) + { + return (int) count; + } + + return (int) apdu.resplen; +} + +static int nqapplet_logout(struct sc_card *card) +{ + LOG_FUNC_CALLED(card->ctx); + + int rv = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); + if ( rv != SC_SUCCESS ) + { + LOG_TEST_RET(card->ctx, rv, "Failed to logout"); + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) +{ + /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, this function only checks the intended parameters */ + nqapplet_driver_data_ptr data; + + assert(card != NULL && env != NULL); + LOG_FUNC_CALLED(card->ctx); + + data = (nqapplet_driver_data_ptr)card->drv_data; + data->key_reference = KEY_REFERENCE_NO_KEY; + u8 key_reference = KEY_REFERENCE_NO_KEY; + + if(se_num != 0) + { + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Storing of security environment is not supported"); + } + if ( env->key_ref_len == 1 ) + { + key_reference = env->key_ref[0]; + } + + switch (env->operation) + { + case SC_SEC_OPERATION_DECIPHER: + if ( key_reference != KEY_REFERENCE_AUTH_KEY && key_reference != KEY_REFERENCE_ENCR_KEY ) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); + } + data->key_reference = key_reference; + break; + case SC_SEC_OPERATION_SIGN: + if ( key_reference != KEY_REFERENCE_AUTH_KEY ) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); + } + data->key_reference = key_reference; + break; + default: + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported sec. operation."); + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_data, u8 * out, size_t outlen) +{ + int rv; + struct sc_apdu apdu; + u8 p1 = 0x80; + u8 p2 = 0x86; + nqapplet_driver_data_ptr drv_data; + + assert(card != NULL && data != NULL && out != NULL); + LOG_FUNC_CALLED(card->ctx); + + drv_data = (nqapplet_driver_data_ptr)card->drv_data; + + if ( drv_data->key_reference == KEY_REFERENCE_AUTH_KEY ) + { + p1 = 0x9E; + p2 = 0x9A; + } + else if ( drv_data->key_reference != KEY_REFERENCE_ENCR_KEY ) + { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); + } + + /* the applet supports only 3072 RAW RSA input must be 384 bytes out at least 384 octets */ + sc_format_apdu_ex(&apdu, 0x80, 0x2A, p1, p2, data, cb_data, out, outlen); + apdu.le = 256; + apdu.flags |= SC_APDU_FLAGS_CHAINING; + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + rv = apdu.resplen; + } + else if (apdu.sw1 == 0x61) + { + rv = apdu.sw2 == 0 ? 256 : apdu.sw2; + } + else + { + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, size_t cb_data, u8 * out, size_t outlen) +{ + int rv; + struct sc_apdu apdu; + nqapplet_driver_data_ptr drv_data; + + assert(card != NULL && data != NULL && out != NULL); + LOG_FUNC_CALLED(card->ctx); + drv_data = (nqapplet_driver_data_ptr)card->drv_data; + + if ( drv_data->key_reference != KEY_REFERENCE_AUTH_KEY ) + { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); + } + + /* the applet supports only 3072 RAW RSA input must be 384 bytes out at least 384 octets */ + sc_format_apdu_ex(&apdu, 0x80, 0x2A, 0x9E, 0x9A, data, cb_data, out, outlen); + apdu.le = 256; + apdu.flags |= SC_APDU_FLAGS_CHAINING; + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + rv = apdu.resplen; + } + else if (apdu.sw1 == 0x61) + { + rv = apdu.sw2 == 0 ? 256 : apdu.sw2; + } + else + { + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int nqapplet_check_sw(struct sc_card *card,unsigned int sw1,unsigned int sw2) +{ + const int nqapplet_error_count = sizeof(nqapplet_errors)/sizeof(struct sc_card_error); + int i; + + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "Checking sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); + + for (i = 0; i < nqapplet_error_count; i++) + { + if (nqapplet_errors[i].SWs == ((sw1 << 8) | sw2)) + { + LOG_TEST_RET(card->ctx, nqapplet_errors[i].errorno, nqapplet_errors[i].errorstr); + } + } + + return iso_operations->check_sw(card, sw1, sw2); +} + +static int nqapplet_get_data(struct sc_card *card, unsigned int id, u8 *resp, size_t cb_resp) +{ + struct sc_apdu apdu; + int rv; + + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu_ex(&apdu, 0x80, 0xB0, 0x00, (u8)id, NULL, 0, resp, cb_resp); + apdu.le = 256; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + rv = apdu.resplen; + } + else if (apdu.sw1 == 0x61) + { + rv = apdu.sw2 == 0 ? 256 : apdu.sw2; + } + else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) + { + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int nqapplet_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) +{ + LOG_FUNC_CALLED(card->ctx); + + /* the applet does not support SELECT EF/DF except for SELECT APPLET. + In order to enable opensc-explorer add support for virtually selecting MF only */ + if (in_path->type == SC_PATH_TYPE_PATH && in_path->len == 2 && memcmp(in_path->value, "\x3F\x00", 2) == 0 ) { + if ( file_out != NULL ) { + struct sc_file *file = sc_file_new(); + if (file == NULL) + { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + file->path = *in_path; + *file_out = file; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + } + //TODO allow selecting Applet AID + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +} + +static int nqapplet_card_ctl(sc_card_t* card, unsigned long cmd, void* ptr) +{ + switch (cmd) + { + case SC_CARDCTL_GET_SERIALNR: + if (card->serialnr.len) { + sc_serial_number_t* serial = (sc_serial_number_t*)ptr; + memcpy(serial->value, card->serialnr.value, card->serialnr.len); + serial->len = card->serialnr.len; + return SC_SUCCESS; + } + default: + return SC_ERROR_NOT_SUPPORTED; + } +} + + +struct sc_card_driver * sc_get_nqApplet_driver(void) +{ + sc_card_driver_t * iso_driver = sc_get_iso7816_driver(); + + if( iso_operations == NULL ) + { + iso_operations = iso_driver->ops; + } + + nqapplet_operations = *iso_driver->ops; + + /* supported operations */ + nqapplet_operations.match_card = nqapplet_match_card; + nqapplet_operations.init = nqapplet_init; + nqapplet_operations.finish = nqapplet_finish; + nqapplet_operations.get_response = nqapplet_get_response; + nqapplet_operations.get_challenge = nqapplet_get_challenge; + nqapplet_operations.logout = nqapplet_logout; + nqapplet_operations.set_security_env = nqapplet_set_security_env; + nqapplet_operations.decipher = nqapplet_decipher; + nqapplet_operations.compute_signature = nqapplet_compute_signature; + nqapplet_operations.check_sw = nqapplet_check_sw; + nqapplet_operations.get_data = nqapplet_get_data; + nqapplet_operations.select_file = nqapplet_select_file; + + /* unsupported operations */ + nqapplet_operations.read_binary = NULL; + nqapplet_operations.write_binary = NULL; + nqapplet_operations.update_binary = NULL; + nqapplet_operations.erase_binary = NULL; + nqapplet_operations.read_record = NULL; + nqapplet_operations.write_record = NULL; + nqapplet_operations.append_record = NULL; + nqapplet_operations.update_record = NULL; + + nqapplet_operations.verify = NULL; + nqapplet_operations.restore_security_env = NULL; + nqapplet_operations.change_reference_data = NULL; + nqapplet_operations.reset_retry_counter = NULL; + nqapplet_operations.create_file = NULL; + nqapplet_operations.delete_file = NULL; + nqapplet_operations.list_files = NULL; + nqapplet_operations.process_fci = NULL; + nqapplet_operations.construct_fci = NULL; + nqapplet_operations.put_data = NULL; + nqapplet_operations.delete_record = NULL; + nqapplet_operations.read_public_key = NULL; + nqapplet_operations.card_ctl = nqapplet_card_ctl; + + /* let iso driver handle these operations + nqapplet_operations.pin_cmd; + nqapplet_operations.card_reader_lock_obtained; + nqapplet_operations.wrap; + nqapplet_operations.unwrap; + */ + + return &nqapplet_driver; +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 5a9feeeaf5..a508fa6d29 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -265,7 +265,10 @@ enum { SC_CARD_TYPE_IDPRIME_GENERIC, /* eDO cards */ - SC_CARD_TYPE_EDO = 38000 + SC_CARD_TYPE_EDO = 38000, + + /* JCOP4 cards with NQ-Applet */ + SC_CARD_TYPE_NQ_APPLET = 39000 }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -309,6 +312,7 @@ extern sc_card_driver_t *sc_get_npa_driver(void); extern sc_card_driver_t *sc_get_esteid2018_driver(void); extern sc_card_driver_t *sc_get_idprime_driver(void); extern sc_card_driver_t *sc_get_edo_driver(void); +extern sc_card_driver_t *sc_get_nqApplet_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 74ed2df4ab..5bdc4095b3 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -145,6 +145,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "jpki", (void *(*)(void)) sc_get_jpki_driver }, { "npa", (void *(*)(void)) sc_get_npa_driver }, { "cac1", (void *(*)(void)) sc_get_cac1_driver }, + { "nqapplet", (void *(*)(void)) sc_get_nqApplet_driver }, /* The default driver should be last, as it handles all the * unrecognized cards. */ { "default", (void *(*)(void)) sc_get_default_driver }, diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c new file mode 100644 index 0000000000..7cd5f5df5c --- /dev/null +++ b/src/libopensc/pkcs15-nqApplet.c @@ -0,0 +1,233 @@ +/* + * PKCS15 emulation for JCOP4 Cards with NQ-Applet + * + * Copyright (C) 2020 jozsefd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "common/compat_strlcpy.h" +#include "log.h" +#include "pkcs15.h" +#include "cards.h" + +static const char name_Card[] = "NQ-Applet"; +static const char name_Vendor[] = "JCOP4"; + +static int get_nqapplet_certificate(sc_card_t * card, u8 data_id, struct sc_pkcs15_der * cert_info) +{ + int rv; + u8 buffer[3072]; + size_t cb_buffer = sizeof(buffer); + LOG_FUNC_CALLED(card->ctx); + + rv = sc_get_data(card, data_id, buffer, cb_buffer); + LOG_TEST_RET(card->ctx, rv, "GET DATA failed"); + if ( rv == 0 ) + { + LOG_TEST_RET(card->ctx, SC_ERROR_FILE_NOT_FOUND, "No certificate data returned"); + } + + if ( cert_info != NULL ) + { + if ( cert_info->value != NULL ) + { + free(cert_info->value); + } + cert_info->value = malloc(rv); + if ( cert_info->value != NULL ) + { + cert_info->len = rv; + memcpy(cert_info->value, buffer, rv); + } + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int add_nqapplet_pin(sc_pkcs15_card_t *p15card, const char * id, u8 reference) +{ + int rv; + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + sc_card_t * card = p15card->card; + + LOG_FUNC_CALLED(card->ctx); + + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + sc_pkcs15_format_id(id, &pin_info.auth_id); + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.reference = reference; + pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_UTF8; + pin_info.attrs.pin.min_length = 6; + pin_info.attrs.pin.stored_length = 6; + pin_info.attrs.pin.max_length = 6; + pin_info.attrs.pin.pad_char = '\0'; + pin_info.tries_left = -1; //TODO + pin_info.max_tries = 3; + + strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label)); + pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; + + rv = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_pin_obj failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int add_nqapplet_certificate(sc_pkcs15_card_t *p15card, const char * id, const char * name, u8 data_id) +{ + int rv; + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + sc_card_t * card = p15card->card; + + LOG_FUNC_CALLED(card->ctx); + + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + sc_pkcs15_format_id(id, &cert_info.id); + cert_info.authority = 0; + rv = get_nqapplet_certificate(card, data_id, &cert_info.value); + LOG_TEST_RET(card->ctx, rv, "Failed to get certificate"); + + strlcpy(cert_obj.label, name, sizeof(cert_obj.label)); + cert_obj.flags = 0; + + rv = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_x509_cert failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int add_nqapplet_private_key(sc_pkcs15_card_t *p15card, const char * id, int reference, const char * name, const char * pin_id, unsigned int usage) +{ + int rv; + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + sc_card_t * card = p15card->card; + + LOG_FUNC_CALLED(card->ctx); + + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + sc_pkcs15_format_id(id, &prkey_info.id); + prkey_info.usage = usage; + prkey_info.native = 1; + prkey_info.key_reference = reference; + prkey_info.modulus_length = 3072; + + strlcpy(prkey_obj.label, name, sizeof(prkey_obj.label)); + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); + + rv = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_rsa_prkey failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) +{ + int rv; + sc_card_t * card = p15card->card; + + LOG_FUNC_CALLED(card->ctx); + + // 1) User PIN + rv = add_nqapplet_pin(p15card, "1", 0x01); + LOG_TEST_RET(card->ctx, rv, "Failed to add PIN 1"); + + // 2.1) CH.Auth + rv = add_nqapplet_certificate(p15card, "1", "C.CH.Auth", 0x00); + LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); + + // 2.2) PrK.CH.Auth + rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT); + LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); + + // 2.1) CH.Auth + rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); + LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. certificate"); + + // 2.2) PrK.CH.Auth + rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); + LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + + +int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + int rv = SC_ERROR_WRONG_CARD; + sc_context_t * ctx; + sc_card_t * card; + + if (!p15card || ! p15card->card || !p15card->card->ctx) return SC_ERROR_INVALID_ARGUMENTS; + + card = p15card->card; + ctx = card->ctx; + + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + + if (card->type!=SC_CARD_TYPE_NQ_APPLET) { + sc_log(p15card->card->ctx, "Unsupported card type: %d", card->type); + return SC_ERROR_WRONG_CARD; + } + + rv = add_nqapplet_objects(p15card); + LOG_TEST_RET(ctx, rv, "Failed to add PKCS15"); + + if ( aid != NULL ) { + struct sc_file *file = sc_file_new(); + if (file != NULL) + { + /* PKCS11 depends on the file_app object, provide MF */ + sc_format_path("3f00", &file->path); + sc_file_free(p15card->file_app); + p15card->file_app = file; + } + } + + if ( p15card->tokeninfo != NULL ) { + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); + } + + p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); + if ( p15card->tokeninfo == NULL ) + { + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "unable to create tokeninfo struct"); + } + else + { + char serial_hex[SC_MAX_SERIALNR*2+2]; + + sc_bin_to_hex(card->serialnr.value, card->serialnr.len , serial_hex, sizeof(serial_hex), 0); + p15card->tokeninfo->serial_number = strdup(serial_hex); + p15card->tokeninfo->label = strdup(name_Card); + p15card->tokeninfo->manufacturer_id = strdup(name_Vendor); + p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; + } + + return SC_SUCCESS; +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index c93ca7560f..f4ed6087ac 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -57,6 +57,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "din66291", sc_pkcs15emu_din_66291_init_ex }, { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, { "cardos", sc_pkcs15emu_cardos_init_ex }, + { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, { NULL, NULL } }; @@ -104,6 +105,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_ESTEID_2018: case SC_CARD_TYPE_CARDOS_V5_0: case SC_CARD_TYPE_CARDOS_V5_3: + case SC_CARD_TYPE_NQ_APPLET: return 1; default: diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index a15e0d95cf..36c0018c15 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -55,6 +55,7 @@ int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_idprime_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_cardos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From 07fd976978fcd4b6ba61f722eaefeadb56f4171f Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 27 Oct 2021 23:46:18 +0200 Subject: [PATCH 2079/4321] Fix linux compilation errors --- src/libopensc/card-nqApplet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 331ae6dd93..e1c919e114 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -92,7 +92,7 @@ static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor, data->version_major = version_major; data->version_minor = version_minor; data->key_reference = KEY_REFERENCE_NO_KEY; - memcpy(data->serial_nr, serial_nr, min(cb_serial_nr, sizeof(data->serial_nr))); + memcpy(data->serial_nr, serial_nr, MIN(cb_serial_nr, sizeof(data->serial_nr))); card->drv_data = (void*)data; return SC_SUCCESS; } @@ -487,9 +487,9 @@ static int nqapplet_card_ctl(sc_card_t* card, unsigned long cmd, void* ptr) serial->len = card->serialnr.len; return SC_SUCCESS; } - default: - return SC_ERROR_NOT_SUPPORTED; + break; } + return SC_ERROR_NOT_SUPPORTED; } From 6afb7951ae785d634f21021ebf591bd6774f561c Mon Sep 17 00:00:00 2001 From: jozsefd Date: Thu, 28 Oct 2021 00:38:07 +0200 Subject: [PATCH 2080/4321] Amend comments and source formatting --- src/libopensc/card-nqApplet.c | 15 +- src/libopensc/pkcs15-nqApplet.c | 277 ++++++++++++++++---------------- 2 files changed, 150 insertions(+), 142 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index e1c919e114..ee15e57e36 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -1,7 +1,7 @@ /* * Support for the JCOP4 Cards with NQ-Applet * - * Copyright (C) 2020 jozsefd + * Copyright (C) 2021 jozsefd * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -61,8 +61,8 @@ static struct sc_card_driver nqapplet_driver = "nqapplet", // short name &nqapplet_operations, // operations NULL, // atr table - 0, // nr of atr - NULL // dll? + 0, // nr of atr + NULL // dll? }; static const struct sc_card_error nqapplet_errors[] = @@ -281,7 +281,8 @@ static int nqapplet_logout(struct sc_card *card) int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) { - /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, this function only checks the intended parameters */ + /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, + this function checks the intended parameters and sets card_data.key_reference */ nqapplet_driver_data_ptr data; assert(card != NULL && env != NULL); @@ -344,7 +345,8 @@ static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_da LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); } - /* the applet supports only 3072 RAW RSA input must be 384 bytes out at least 384 octets */ + /* the applet supports only 3072 RAW RSA, input buffer size must be 384 octets, + output buffer size must be at least 384 octets */ sc_format_apdu_ex(&apdu, 0x80, 0x2A, p1, p2, data, cb_data, out, outlen); apdu.le = 256; apdu.flags |= SC_APDU_FLAGS_CHAINING; @@ -382,7 +384,8 @@ static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, siz LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); } - /* the applet supports only 3072 RAW RSA input must be 384 bytes out at least 384 octets */ + /* the applet supports only 3072 RAW RSA, input buffer size must be 384 octets, + output buffer size must be at least 384 octets */ sc_format_apdu_ex(&apdu, 0x80, 0x2A, 0x9E, 0x9A, data, cb_data, out, outlen); apdu.le = 256; apdu.flags |= SC_APDU_FLAGS_CHAINING; diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 7cd5f5df5c..9683cc0b2c 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -1,7 +1,7 @@ /* * PKCS15 emulation for JCOP4 Cards with NQ-Applet * - * Copyright (C) 2020 jozsefd + * Copyright (C) 2021 jozsefd * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,205 +29,210 @@ static const char name_Card[] = "NQ-Applet"; static const char name_Vendor[] = "JCOP4"; -static int get_nqapplet_certificate(sc_card_t * card, u8 data_id, struct sc_pkcs15_der * cert_info) +static int get_nqapplet_certificate(sc_card_t *card, u8 data_id, struct sc_pkcs15_der *cert_info) { - int rv; - u8 buffer[3072]; - size_t cb_buffer = sizeof(buffer); + int rv; + u8 buffer[3072]; + size_t cb_buffer = sizeof(buffer); LOG_FUNC_CALLED(card->ctx); - rv = sc_get_data(card, data_id, buffer, cb_buffer); - LOG_TEST_RET(card->ctx, rv, "GET DATA failed"); - if ( rv == 0 ) - { - LOG_TEST_RET(card->ctx, SC_ERROR_FILE_NOT_FOUND, "No certificate data returned"); - } - - if ( cert_info != NULL ) - { - if ( cert_info->value != NULL ) - { - free(cert_info->value); - } - cert_info->value = malloc(rv); - if ( cert_info->value != NULL ) - { - cert_info->len = rv; - memcpy(cert_info->value, buffer, rv); - } - } - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + rv = sc_get_data(card, data_id, buffer, cb_buffer); + LOG_TEST_RET(card->ctx, rv, "GET DATA failed"); + if (rv == 0) + { + LOG_TEST_RET(card->ctx, SC_ERROR_FILE_NOT_FOUND, "No certificate data returned"); + } + + if (cert_info != NULL) + { + if (cert_info->value != NULL) + { + free(cert_info->value); + } + cert_info->value = malloc(rv); + if (cert_info->value != NULL) + { + cert_info->len = rv; + memcpy(cert_info->value, buffer, rv); + } + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int add_nqapplet_pin(sc_pkcs15_card_t *p15card, const char * id, u8 reference) +static int add_nqapplet_pin(sc_pkcs15_card_t *p15card, const char *id, u8 reference) { - int rv; - struct sc_pkcs15_auth_info pin_info; - struct sc_pkcs15_object pin_obj; - sc_card_t * card = p15card->card; + int rv; + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + sc_card_t *card = p15card->card; LOG_FUNC_CALLED(card->ctx); - memset(&pin_info, 0, sizeof(pin_info)); - memset(&pin_obj, 0, sizeof(pin_obj)); - - sc_pkcs15_format_id(id, &pin_info.auth_id); - pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; - pin_info.attrs.pin.reference = reference; - pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | SC_PKCS15_PIN_AUTH_TYPE_PIN; - pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_UTF8; - pin_info.attrs.pin.min_length = 6; - pin_info.attrs.pin.stored_length = 6; - pin_info.attrs.pin.max_length = 6; - pin_info.attrs.pin.pad_char = '\0'; - pin_info.tries_left = -1; //TODO - pin_info.max_tries = 3; - - strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label)); - pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; - - rv = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_pin_obj failed"); - - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + sc_pkcs15_format_id(id, &pin_info.auth_id); + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.reference = reference; + pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_UTF8; + pin_info.attrs.pin.min_length = 6; + pin_info.attrs.pin.stored_length = 6; + pin_info.attrs.pin.max_length = 6; + pin_info.attrs.pin.pad_char = '\0'; + pin_info.tries_left = -1; //TODO + pin_info.max_tries = 3; + + strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label)); + pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; + + rv = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_pin_obj failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int add_nqapplet_certificate(sc_pkcs15_card_t *p15card, const char * id, const char * name, u8 data_id) +static int add_nqapplet_certificate(sc_pkcs15_card_t *p15card, const char *id, const char *name, u8 data_id) { - int rv; - struct sc_pkcs15_cert_info cert_info; - struct sc_pkcs15_object cert_obj; - sc_card_t * card = p15card->card; + int rv; + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + sc_card_t *card = p15card->card; LOG_FUNC_CALLED(card->ctx); - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); - sc_pkcs15_format_id(id, &cert_info.id); + sc_pkcs15_format_id(id, &cert_info.id); cert_info.authority = 0; - rv = get_nqapplet_certificate(card, data_id, &cert_info.value); - LOG_TEST_RET(card->ctx, rv, "Failed to get certificate"); + rv = get_nqapplet_certificate(card, data_id, &cert_info.value); + LOG_TEST_RET(card->ctx, rv, "Failed to get certificate"); - strlcpy(cert_obj.label, name, sizeof(cert_obj.label)); + strlcpy(cert_obj.label, name, sizeof(cert_obj.label)); cert_obj.flags = 0; - rv = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_x509_cert failed"); + rv = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_x509_cert failed"); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int add_nqapplet_private_key(sc_pkcs15_card_t *p15card, const char * id, int reference, const char * name, const char * pin_id, unsigned int usage) +static int add_nqapplet_private_key(sc_pkcs15_card_t *p15card, const char *id, int reference, const char *name, const char *pin_id, unsigned int usage) { - int rv; - struct sc_pkcs15_prkey_info prkey_info; - struct sc_pkcs15_object prkey_obj; - sc_card_t * card = p15card->card; + int rv; + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + sc_card_t *card = p15card->card; LOG_FUNC_CALLED(card->ctx); - memset(&prkey_info, 0, sizeof(prkey_info)); - memset(&prkey_obj, 0, sizeof(prkey_obj)); + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); - sc_pkcs15_format_id(id, &prkey_info.id); - prkey_info.usage = usage; - prkey_info.native = 1; - prkey_info.key_reference = reference; - prkey_info.modulus_length = 3072; + sc_pkcs15_format_id(id, &prkey_info.id); + prkey_info.usage = usage; + prkey_info.native = 1; + prkey_info.key_reference = reference; + prkey_info.modulus_length = 3072; - strlcpy(prkey_obj.label, name, sizeof(prkey_obj.label)); - prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; - sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); + strlcpy(prkey_obj.label, name, sizeof(prkey_obj.label)); + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); - rv = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_rsa_prkey failed"); + rv = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_rsa_prkey failed"); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) { - int rv; - sc_card_t * card = p15card->card; + int rv; + sc_card_t *card = p15card->card; LOG_FUNC_CALLED(card->ctx); - // 1) User PIN - rv = add_nqapplet_pin(p15card, "1", 0x01); - LOG_TEST_RET(card->ctx, rv, "Failed to add PIN 1"); + // 1) User PIN + rv = add_nqapplet_pin(p15card, "1", 0x01); + LOG_TEST_RET(card->ctx, rv, "Failed to add PIN 1"); - // 2.1) CH.Auth - rv = add_nqapplet_certificate(p15card, "1", "C.CH.Auth", 0x00); - LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); + // 2.1) CH.Auth + rv = add_nqapplet_certificate(p15card, "1", "C.CH.Auth", 0x00); + LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); - // 2.2) PrK.CH.Auth - rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT); - LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); + // 2.2) PrK.CH.Auth + rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT); + LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); - // 2.1) CH.Auth - rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); - LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. certificate"); + // 2.1) CH.Auth + rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); + LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. certificate"); - // 2.2) PrK.CH.Auth - rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); - LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); + // 2.2) PrK.CH.Auth + rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); + LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { int rv = SC_ERROR_WRONG_CARD; - sc_context_t * ctx; - sc_card_t * card; + sc_context_t *ctx; + sc_card_t *card; - if (!p15card || ! p15card->card || !p15card->card->ctx) return SC_ERROR_INVALID_ARGUMENTS; + if (!p15card || !p15card->card || !p15card->card->ctx) + { + return SC_ERROR_INVALID_ARGUMENTS; + } card = p15card->card; ctx = card->ctx; - - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); - - if (card->type!=SC_CARD_TYPE_NQ_APPLET) { - sc_log(p15card->card->ctx, "Unsupported card type: %d", card->type); - return SC_ERROR_WRONG_CARD; - } - - rv = add_nqapplet_objects(p15card); - LOG_TEST_RET(ctx, rv, "Failed to add PKCS15"); - - if ( aid != NULL ) { - struct sc_file *file = sc_file_new(); - if (file != NULL) - { - /* PKCS11 depends on the file_app object, provide MF */ - sc_format_path("3f00", &file->path); - sc_file_free(p15card->file_app); - p15card->file_app = file; - } + + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + + if (card->type != SC_CARD_TYPE_NQ_APPLET) + { + sc_log(p15card->card->ctx, "Unsupported card type: %d", card->type); + return SC_ERROR_WRONG_CARD; + } + + rv = add_nqapplet_objects(p15card); + LOG_TEST_RET(ctx, rv, "Failed to add PKCS15"); + + if (aid != NULL) + { + struct sc_file *file = sc_file_new(); + if (file != NULL) + { + /* PKCS11 depends on the file_app object, provide MF */ + sc_format_path("3f00", &file->path); + sc_file_free(p15card->file_app); + p15card->file_app = file; + } } - if ( p15card->tokeninfo != NULL ) { + if (p15card->tokeninfo != NULL) + { sc_pkcs15_free_tokeninfo(p15card->tokeninfo); } - p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); - if ( p15card->tokeninfo == NULL ) - { + p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); + if (p15card->tokeninfo == NULL) + { LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "unable to create tokeninfo struct"); } - else - { - char serial_hex[SC_MAX_SERIALNR*2+2]; + else + { + char serial_hex[SC_MAX_SERIALNR * 2 + 2]; - sc_bin_to_hex(card->serialnr.value, card->serialnr.len , serial_hex, sizeof(serial_hex), 0); + sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial_hex, sizeof(serial_hex), 0); p15card->tokeninfo->serial_number = strdup(serial_hex); p15card->tokeninfo->label = strdup(name_Card); p15card->tokeninfo->manufacturer_id = strdup(name_Vendor); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; } - return SC_SUCCESS; + return SC_SUCCESS; } From 799f178548ca3690bb0b2456a2c43899177b9463 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Fri, 29 Oct 2021 11:40:00 +0200 Subject: [PATCH 2081/4321] Fix buflen size in sc_pkcs15_compute_signature --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index b8c4751379..24c5242b43 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -615,7 +615,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, if (outlen < modlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); - buflen = inlen + 256; + buflen = inlen + modlen; buf = sc_mem_secure_alloc(buflen); if (buf == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); From 6c1ff4c23819ffc311731a47787d94d38030decc Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 2 Nov 2021 17:49:34 +0100 Subject: [PATCH 2082/4321] Remove unnecessary check before free() --- src/libopensc/pkcs15-nqApplet.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 9683cc0b2c..0cb94d4ae1 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -45,10 +45,7 @@ static int get_nqapplet_certificate(sc_card_t *card, u8 data_id, struct sc_pkcs1 if (cert_info != NULL) { - if (cert_info->value != NULL) - { - free(cert_info->value); - } + free(cert_info->value); cert_info->value = malloc(rv); if (cert_info->value != NULL) { From d24afc2dfb3701f6a4fc06e65e4652570858af39 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 2 Nov 2021 17:50:06 +0100 Subject: [PATCH 2083/4321] Use sc_format_apdu_ex instead of sc_format_apdu --- src/libopensc/card-nqApplet.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index ee15e57e36..bc791bdfc1 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -121,13 +121,7 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor LOG_FUNC_CALLED(card->ctx); - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = cb_aid; - apdu.data = nqapplet_aid; - apdu.datalen = cb_aid; - apdu.resp = buffer; - apdu.resplen = cb_buffer; - apdu.le = cb_buffer; + sc_format_apdu_ex(&apdu, 0x00, 0xA4, 0x04, 0x00, nqapplet_aid, cb_aid, buffer, cb_buffer); rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, rv, "APDU transmit failure."); From 907a8efa7ee24bad52c109f0fbf82fda39c0fd82 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 10:11:54 +0100 Subject: [PATCH 2084/4321] Add checking of the response length --- src/libopensc/card-nqApplet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index bc791bdfc1..1cfcce61f6 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -129,6 +129,10 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Card returned error"); + if ( apdu.resplen < APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN ) { + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); + } + if ( version_major != NULL ) { *version_major = buffer[0]; From 1c492eb10d37002a9382c91fe1ed2ed005912a9b Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 10:40:25 +0100 Subject: [PATCH 2085/4321] Remove field serial_nr from nqapplet_driver_data --- src/libopensc/card-nqApplet.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 1cfcce61f6..c4ce6442b0 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -51,7 +51,6 @@ struct nqapplet_driver_data u8 version_minor; u8 version_major; u8 key_reference; - u8 serial_nr[APPLET_SERIALNR_LEN]; }; typedef struct nqapplet_driver_data * nqapplet_driver_data_ptr; @@ -81,7 +80,7 @@ static const struct sc_card_error nqapplet_errors[] = /* convenience functions */ -static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor, u8 * serial_nr, size_t cb_serial_nr) +static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor) { nqapplet_driver_data_ptr data = calloc(1, sizeof(struct nqapplet_driver_data)); if (data == NULL) @@ -92,7 +91,6 @@ static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor, data->version_major = version_major; data->version_minor = version_minor; data->key_reference = KEY_REFERENCE_NO_KEY; - memcpy(data->serial_nr, serial_nr, MIN(cb_serial_nr, sizeof(data->serial_nr))); card->drv_data = (void*)data; return SC_SUCCESS; } @@ -174,7 +172,7 @@ static int nqapplet_init(struct sc_card *card) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Cannot select NQ-Applet."); } - rv = init_driver_data(card, version_major, version_minor, serial_nr, cb_serial_nr); + rv = init_driver_data(card, version_major, version_minor); LOG_TEST_RET(card->ctx, rv, "Failed to initialize driver data."); card->max_send_size = 255; From 214f477d5fb040f427d029e2724f35fc900011e1 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 10:47:09 +0100 Subject: [PATCH 2086/4321] Remove asserts --- src/libopensc/card-nqApplet.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index c4ce6442b0..c6956c8ba5 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -281,7 +281,6 @@ int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env this function checks the intended parameters and sets card_data.key_reference */ nqapplet_driver_data_ptr data; - assert(card != NULL && env != NULL); LOG_FUNC_CALLED(card->ctx); data = (nqapplet_driver_data_ptr)card->drv_data; @@ -326,7 +325,6 @@ static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_da u8 p2 = 0x86; nqapplet_driver_data_ptr drv_data; - assert(card != NULL && data != NULL && out != NULL); LOG_FUNC_CALLED(card->ctx); drv_data = (nqapplet_driver_data_ptr)card->drv_data; @@ -371,7 +369,6 @@ static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, siz struct sc_apdu apdu; nqapplet_driver_data_ptr drv_data; - assert(card != NULL && data != NULL && out != NULL); LOG_FUNC_CALLED(card->ctx); drv_data = (nqapplet_driver_data_ptr)card->drv_data; From f338d46b0b640dbb6757e9dab61d0d34a041abcf Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 10:57:58 +0100 Subject: [PATCH 2087/4321] Fix braces formatting --- src/libopensc/card-nqApplet.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index c6956c8ba5..fe33fcd8a6 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -127,7 +127,8 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Card returned error"); - if ( apdu.resplen < APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN ) { + if ( apdu.resplen < APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN ) + { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); } @@ -299,13 +300,15 @@ int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - if ( key_reference != KEY_REFERENCE_AUTH_KEY && key_reference != KEY_REFERENCE_ENCR_KEY ) { + if ( key_reference != KEY_REFERENCE_AUTH_KEY && key_reference != KEY_REFERENCE_ENCR_KEY ) + { LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); } data->key_reference = key_reference; break; case SC_SEC_OPERATION_SIGN: - if ( key_reference != KEY_REFERENCE_AUTH_KEY ) { + if ( key_reference != KEY_REFERENCE_AUTH_KEY ) + { LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); } data->key_reference = key_reference; @@ -455,8 +458,10 @@ static int nqapplet_select_file(struct sc_card *card, const struct sc_path *in_p /* the applet does not support SELECT EF/DF except for SELECT APPLET. In order to enable opensc-explorer add support for virtually selecting MF only */ - if (in_path->type == SC_PATH_TYPE_PATH && in_path->len == 2 && memcmp(in_path->value, "\x3F\x00", 2) == 0 ) { - if ( file_out != NULL ) { + if (in_path->type == SC_PATH_TYPE_PATH && in_path->len == 2 && memcmp(in_path->value, "\x3F\x00", 2) == 0 ) + { + if ( file_out != NULL ) + { struct sc_file *file = sc_file_new(); if (file == NULL) { @@ -477,7 +482,8 @@ static int nqapplet_card_ctl(sc_card_t* card, unsigned long cmd, void* ptr) switch (cmd) { case SC_CARDCTL_GET_SERIALNR: - if (card->serialnr.len) { + if (card->serialnr.len) + { sc_serial_number_t* serial = (sc_serial_number_t*)ptr; memcpy(serial->value, card->serialnr.value, card->serialnr.len); serial->len = card->serialnr.len; From eb088b10eced22ad970bd969c756c38a8360cc8d Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 11:09:37 +0100 Subject: [PATCH 2088/4321] Fix comments --- src/libopensc/pkcs15-nqApplet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 0cb94d4ae1..8a8e14abc7 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -154,7 +154,7 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) rv = add_nqapplet_pin(p15card, "1", 0x01); LOG_TEST_RET(card->ctx, rv, "Failed to add PIN 1"); - // 2.1) CH.Auth + // 2.1) C.CH.Auth rv = add_nqapplet_certificate(p15card, "1", "C.CH.Auth", 0x00); LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); @@ -162,11 +162,11 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT); LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); - // 2.1) CH.Auth + // 3.1) C.CH.Encr rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. certificate"); - // 2.2) PrK.CH.Auth + // 3.2) PrK.CH.Encr rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); From edca4a873ed1d4ef65f0639124bb0986447028b0 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 11:11:58 +0100 Subject: [PATCH 2089/4321] Removed flag SC_PKCS15_PRKEY_USAGE_ENCRYPT --- src/libopensc/pkcs15-nqApplet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 8a8e14abc7..e55d18c6e7 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -159,7 +159,7 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); // 2.2) PrK.CH.Auth - rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT); + rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT); LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); // 3.1) C.CH.Encr From 8bf172284f61008bd1288b843a8b9fc5d712c6ff Mon Sep 17 00:00:00 2001 From: jozsefd Date: Wed, 3 Nov 2021 11:24:37 +0100 Subject: [PATCH 2090/4321] Change vendor to NXP --- src/libopensc/pkcs15-nqApplet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index e55d18c6e7..238c793fb1 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -27,7 +27,7 @@ #include "cards.h" static const char name_Card[] = "NQ-Applet"; -static const char name_Vendor[] = "JCOP4"; +static const char name_Vendor[] = "NXP"; static int get_nqapplet_certificate(sc_card_t *card, u8 data_id, struct sc_pkcs15_der *cert_info) { From 25d3a9dabe95fde07c5256803de1ff2465051083 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 16 Nov 2021 10:16:34 +0100 Subject: [PATCH 2091/4321] Fix coding issues, add comment for nqapplet_logout --- src/libopensc/card-nqApplet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index fe33fcd8a6..85a8a21c72 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -266,7 +266,7 @@ static int nqapplet_get_challenge(struct sc_card *card, u8 * buf, size_t count) static int nqapplet_logout(struct sc_card *card) { LOG_FUNC_CALLED(card->ctx); - + /* selecting NQ-Applet again will reset the applet status and unauthorize PINs */ int rv = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); if ( rv != SC_SUCCESS ) { @@ -281,12 +281,12 @@ int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, this function checks the intended parameters and sets card_data.key_reference */ nqapplet_driver_data_ptr data; + u8 key_reference = KEY_REFERENCE_NO_KEY; LOG_FUNC_CALLED(card->ctx); data = (nqapplet_driver_data_ptr)card->drv_data; data->key_reference = KEY_REFERENCE_NO_KEY; - u8 key_reference = KEY_REFERENCE_NO_KEY; if(se_num != 0) { @@ -519,6 +519,7 @@ struct sc_card_driver * sc_get_nqApplet_driver(void) nqapplet_operations.check_sw = nqapplet_check_sw; nqapplet_operations.get_data = nqapplet_get_data; nqapplet_operations.select_file = nqapplet_select_file; + nqapplet_operations.card_ctl = nqapplet_card_ctl; /* unsupported operations */ nqapplet_operations.read_binary = NULL; @@ -542,7 +543,6 @@ struct sc_card_driver * sc_get_nqApplet_driver(void) nqapplet_operations.put_data = NULL; nqapplet_operations.delete_record = NULL; nqapplet_operations.read_public_key = NULL; - nqapplet_operations.card_ctl = nqapplet_card_ctl; /* let iso driver handle these operations nqapplet_operations.pin_cmd; From c1046f1bdef2ef1fd3797f6ab5c45e6cae1346c9 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 16 Nov 2021 10:22:52 +0100 Subject: [PATCH 2092/4321] Remove unnecessary code --- src/libopensc/pkcs15-nqApplet.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 238c793fb1..beec9bf397 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -102,12 +102,10 @@ static int add_nqapplet_certificate(sc_pkcs15_card_t *p15card, const char *id, c memset(&cert_obj, 0, sizeof(cert_obj)); sc_pkcs15_format_id(id, &cert_info.id); - cert_info.authority = 0; rv = get_nqapplet_certificate(card, data_id, &cert_info.value); LOG_TEST_RET(card->ctx, rv, "Failed to get certificate"); strlcpy(cert_obj.label, name, sizeof(cert_obj.label)); - cert_obj.flags = 0; rv = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); LOG_TEST_RET(card->ctx, rv, "sc_pkcs15emu_add_x509_cert failed"); @@ -210,10 +208,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) } } - if (p15card->tokeninfo != NULL) - { - sc_pkcs15_free_tokeninfo(p15card->tokeninfo); - } + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); if (p15card->tokeninfo == NULL) From 1a36ce7586e50de149aa05a9cde638df1b4f746f Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 16 Nov 2021 13:03:14 +0100 Subject: [PATCH 2093/4321] Apply OpenSC:ci .clang-format --- src/libopensc/card-nqApplet.c | 291 ++++++++++++++------------------ src/libopensc/pkcs15-nqApplet.c | 41 ++--- 2 files changed, 140 insertions(+), 192 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 85a8a21c72..d08f22365c 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -26,72 +26,65 @@ #include "internal.h" #include "log.h" -#define APPLET_VERSION_LEN 2 -#define APPLET_MEMTYPE_LEN 1 +#define APPLET_VERSION_LEN 2 +#define APPLET_MEMTYPE_LEN 1 #define APPLET_SERIALNR_LEN 8 /* card constants */ -static const struct sc_atr_table nqapplet_atrs[] = -{ - { "3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL }, - { NULL, NULL, NULL, 0, 0, NULL } -}; +static const struct sc_atr_table nqapplet_atrs[] = { + {"3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL}}; static const u8 nqapplet_aid[] = {0xd2, 0x76, 0x00, 0x01, 0x80, 0xBA, 0x01, 0x44, 0x02, 0x01, 0x00}; static struct sc_card_operations nqapplet_operations; static struct sc_card_operations *iso_operations = NULL; -#define KEY_REFERENCE_NO_KEY 0x00 -#define KEY_REFERENCE_AUTH_KEY 0x01 -#define KEY_REFERENCE_ENCR_KEY 0x02 +#define KEY_REFERENCE_NO_KEY 0x00 +#define KEY_REFERENCE_AUTH_KEY 0x01 +#define KEY_REFERENCE_ENCR_KEY 0x02 -struct nqapplet_driver_data -{ +struct nqapplet_driver_data { u8 version_minor; u8 version_major; u8 key_reference; }; -typedef struct nqapplet_driver_data * nqapplet_driver_data_ptr; - -static struct sc_card_driver nqapplet_driver = -{ - "NQ-Applet", // name - "nqapplet", // short name - &nqapplet_operations, // operations - NULL, // atr table - 0, // nr of atr - NULL // dll? +typedef struct nqapplet_driver_data *nqapplet_driver_data_ptr; + +static struct sc_card_driver nqapplet_driver = { + "NQ-Applet", // name + "nqapplet", // short name + &nqapplet_operations, // operations + NULL, // atr table + 0, // nr of atr + NULL // dll? }; -static const struct sc_card_error nqapplet_errors[] = -{ - { 0x6700, SC_ERROR_WRONG_LENGTH, "Invalid LC or LE"}, - { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" }, //TODO MK/DK?? - { 0x6985, SC_ERROR_NOT_ALLOWED, "Invalid PIN or key" }, - { 0x6986, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" }, - { 0x6A80, SC_ERROR_INVALID_ARGUMENTS, "Invalid parameters" }, - { 0x6A82, SC_ERROR_OBJECT_NOT_FOUND, "Data object not found"}, - { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory" }, - { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS, "Invalid P1 or P2" }, - { 0x6A88, SC_ERROR_INVALID_ARGUMENTS, "Wrong key ID" }, - { 0x6D00, SC_ERROR_FILE_NOT_FOUND, "Applet not found" } -}; +static const struct sc_card_error nqapplet_errors[] = { + {0x6700, SC_ERROR_WRONG_LENGTH, "Invalid LC or LE"}, + {0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied"}, // TODO MK/DK?? + {0x6985, SC_ERROR_NOT_ALLOWED, "Invalid PIN or key"}, + {0x6986, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied"}, + {0x6A80, SC_ERROR_INVALID_ARGUMENTS, "Invalid parameters"}, + {0x6A82, SC_ERROR_OBJECT_NOT_FOUND, "Data object not found"}, + {0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory"}, + {0x6A86, SC_ERROR_INCORRECT_PARAMETERS, "Invalid P1 or P2"}, + {0x6A88, SC_ERROR_INVALID_ARGUMENTS, "Wrong key ID"}, + {0x6D00, SC_ERROR_FILE_NOT_FOUND, "Applet not found"}}; /* convenience functions */ static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor) { nqapplet_driver_data_ptr data = calloc(1, sizeof(struct nqapplet_driver_data)); - if (data == NULL) - { + if (data == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } data->version_major = version_major; data->version_minor = version_minor; data->key_reference = KEY_REFERENCE_NO_KEY; - card->drv_data = (void*)data; + card->drv_data = (void *)data; return SC_SUCCESS; } @@ -106,14 +99,15 @@ static int init_driver_data(sc_card_t *card, u8 version_major, u8 version_minor) * @param[out,opt] serial_nr_len The actual number of octet copied into serial_nr buffer * * @return SC_SUCCESS: The applet is present and selected. - * + * */ -static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor, u8 *serial_nr, size_t cb_serial_nr, size_t *serial_nr_len) +static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor, u8 *serial_nr, + size_t cb_serial_nr, size_t *serial_nr_len) { int rv; sc_context_t *ctx = card->ctx; sc_apdu_t apdu; - u8 buffer[APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN+2]; + u8 buffer[APPLET_VERSION_LEN + APPLET_MEMTYPE_LEN + APPLET_SERIALNR_LEN + 2]; size_t cb_buffer = sizeof(buffer); size_t cb_aid = sizeof(nqapplet_aid); @@ -127,30 +121,25 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Card returned error"); - if ( apdu.resplen < APPLET_VERSION_LEN+APPLET_MEMTYPE_LEN+APPLET_SERIALNR_LEN ) - { + if (apdu.resplen < APPLET_VERSION_LEN + APPLET_MEMTYPE_LEN + APPLET_SERIALNR_LEN) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); } - if ( version_major != NULL ) - { + if (version_major != NULL) { *version_major = buffer[0]; } - if ( version_minor != NULL ) - { + if (version_minor != NULL) { *version_minor = buffer[1]; } - if ( serial_nr != NULL && cb_serial_nr > 0 && serial_nr_len != NULL ) - { + if (serial_nr != NULL && cb_serial_nr > 0 && serial_nr_len != NULL) { size_t cb = MIN(APPLET_SERIALNR_LEN, cb_serial_nr); - memcpy(serial_nr, buffer+3, cb); + memcpy(serial_nr, buffer + 3, cb); *serial_nr_len = cb; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - /* driver operations API */ static int nqapplet_match_card(struct sc_card *card) { @@ -167,9 +156,9 @@ static int nqapplet_init(struct sc_card *card) unsigned long rsa_flags = 0; LOG_FUNC_CALLED(card->ctx); - int rv = select_nqapplet(card, &version_major, &version_minor, serial_nr, cb_serial_nr, &cb_serial_nr); - if ( rv != SC_SUCCESS ) - { + int rv = + select_nqapplet(card, &version_major, &version_minor, serial_nr, cb_serial_nr, &cb_serial_nr); + if (rv != SC_SUCCESS) { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Cannot select NQ-Applet."); } @@ -178,10 +167,10 @@ static int nqapplet_init(struct sc_card *card) card->max_send_size = 255; card->max_recv_size = 256; - card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; + card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO; rsa_flags |= SC_ALGORITHM_RSA_RAW; _sc_card_add_rsa_alg(card, 3072, rsa_flags, 0); - + card->serialnr.len = MIN(sizeof(card->serialnr.value), cb_serial_nr); memcpy(card->serialnr.value, serial_nr, card->serialnr.len); @@ -193,10 +182,9 @@ static int nqapplet_finish(struct sc_card *card) nqapplet_driver_data_ptr data = (nqapplet_driver_data_ptr)card->drv_data; LOG_FUNC_CALLED(card->ctx); - if (data != NULL) - { + if (data != NULL) { free(data); - card->drv_data=NULL; + card->drv_data = NULL; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -211,34 +199,28 @@ static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp resplen = MIN(sc_get_max_recv_size(card), *cb_resp); sc_format_apdu_ex(&apdu, 0x80, 0xC0, 0x00, 0x00, NULL, 0, resp, resplen); - apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP; + apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.resplen == 0) - { + if (apdu.resplen == 0) { LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } *cb_resp = apdu.resplen; - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { rv = SC_SUCCESS; - } - else if (apdu.sw1 == 0x61) - { + } else if (apdu.sw1 == 0x61) { rv = apdu.sw2 == 0 ? 256 : apdu.sw2; - } - else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) - { + } else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) { rv = sc_check_sw(card, apdu.sw1, apdu.sw2); } LOG_FUNC_RETURN(card->ctx, rv); } -static int nqapplet_get_challenge(struct sc_card *card, u8 * buf, size_t count) +static int nqapplet_get_challenge(struct sc_card *card, u8 *buf, size_t count) { int r; struct sc_apdu apdu; @@ -255,12 +237,11 @@ static int nqapplet_get_challenge(struct sc_card *card, u8 * buf, size_t count) r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed"); - if (count < apdu.resplen) - { - return (int) count; + if (count < apdu.resplen) { + return (int)count; } - - return (int) apdu.resplen; + + return (int)apdu.resplen; } static int nqapplet_logout(struct sc_card *card) @@ -268,59 +249,56 @@ static int nqapplet_logout(struct sc_card *card) LOG_FUNC_CALLED(card->ctx); /* selecting NQ-Applet again will reset the applet status and unauthorize PINs */ int rv = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); - if ( rv != SC_SUCCESS ) - { + if (rv != SC_SUCCESS) { LOG_TEST_RET(card->ctx, rv, "Failed to logout"); } - + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int nqapplet_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) { - /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, + /* Note: the NQ-Applet does not have APDU for SET SECURITY ENV, this function checks the intended parameters and sets card_data.key_reference */ nqapplet_driver_data_ptr data; u8 key_reference = KEY_REFERENCE_NO_KEY; - + LOG_FUNC_CALLED(card->ctx); data = (nqapplet_driver_data_ptr)card->drv_data; data->key_reference = KEY_REFERENCE_NO_KEY; - if(se_num != 0) - { - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Storing of security environment is not supported"); + if (se_num != 0) { + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, + "Storing of security environment is not supported"); } - if ( env->key_ref_len == 1 ) - { + if (env->key_ref_len == 1) { key_reference = env->key_ref[0]; } - - switch (env->operation) - { - case SC_SEC_OPERATION_DECIPHER: - if ( key_reference != KEY_REFERENCE_AUTH_KEY && key_reference != KEY_REFERENCE_ENCR_KEY ) - { - LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); - } - data->key_reference = key_reference; - break; - case SC_SEC_OPERATION_SIGN: - if ( key_reference != KEY_REFERENCE_AUTH_KEY ) - { - LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); - } - data->key_reference = key_reference; - break; - default: - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported sec. operation."); + + switch (env->operation) { + case SC_SEC_OPERATION_DECIPHER: + if (key_reference != KEY_REFERENCE_AUTH_KEY && key_reference != KEY_REFERENCE_ENCR_KEY) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, + "Decipher operation is only supported with AUTH and ENCR keys."); + } + data->key_reference = key_reference; + break; + case SC_SEC_OPERATION_SIGN: + if (key_reference != KEY_REFERENCE_AUTH_KEY) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, + "Sign operation is only supported with AUTH key."); + } + data->key_reference = key_reference; + break; + default: + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported sec. operation."); } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_data, u8 * out, size_t outlen) +static int nqapplet_decipher(struct sc_card *card, const u8 *data, size_t cb_data, u8 *out, size_t outlen) { int rv; struct sc_apdu apdu; @@ -331,15 +309,13 @@ static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_da LOG_FUNC_CALLED(card->ctx); drv_data = (nqapplet_driver_data_ptr)card->drv_data; - - if ( drv_data->key_reference == KEY_REFERENCE_AUTH_KEY ) - { + + if (drv_data->key_reference == KEY_REFERENCE_AUTH_KEY) { p1 = 0x9E; p2 = 0x9A; - } - else if ( drv_data->key_reference != KEY_REFERENCE_ENCR_KEY ) - { - LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Decipher operation is only supported with AUTH and ENCR keys."); + } else if (drv_data->key_reference != KEY_REFERENCE_ENCR_KEY) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, + "Decipher operation is only supported with AUTH and ENCR keys."); } /* the applet supports only 3072 RAW RSA, input buffer size must be 384 octets, @@ -350,23 +326,19 @@ static int nqapplet_decipher(struct sc_card *card, const u8 * data, size_t cb_da rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { rv = apdu.resplen; - } - else if (apdu.sw1 == 0x61) - { + } else if (apdu.sw1 == 0x61) { rv = apdu.sw2 == 0 ? 256 : apdu.sw2; - } - else - { + } else { rv = sc_check_sw(card, apdu.sw1, apdu.sw2); } LOG_FUNC_RETURN(card->ctx, rv); } -static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, size_t cb_data, u8 * out, size_t outlen) +static int nqapplet_compute_signature(struct sc_card *card, const u8 *data, size_t cb_data, u8 *out, + size_t outlen) { int rv; struct sc_apdu apdu; @@ -374,10 +346,10 @@ static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, siz LOG_FUNC_CALLED(card->ctx); drv_data = (nqapplet_driver_data_ptr)card->drv_data; - - if ( drv_data->key_reference != KEY_REFERENCE_AUTH_KEY ) - { - LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, "Sign operation is only supported with AUTH key."); + + if (drv_data->key_reference != KEY_REFERENCE_AUTH_KEY) { + LOG_TEST_RET(card->ctx, SC_ERROR_INCOMPATIBLE_KEY, + "Sign operation is only supported with AUTH key."); } /* the applet supports only 3072 RAW RSA, input buffer size must be 384 octets, @@ -388,34 +360,27 @@ static int nqapplet_compute_signature(struct sc_card *card, const u8 * data, siz rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { rv = apdu.resplen; - } - else if (apdu.sw1 == 0x61) - { + } else if (apdu.sw1 == 0x61) { rv = apdu.sw2 == 0 ? 256 : apdu.sw2; - } - else - { + } else { rv = sc_check_sw(card, apdu.sw1, apdu.sw2); } LOG_FUNC_RETURN(card->ctx, rv); } -static int nqapplet_check_sw(struct sc_card *card,unsigned int sw1,unsigned int sw2) +static int nqapplet_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) { - const int nqapplet_error_count = sizeof(nqapplet_errors)/sizeof(struct sc_card_error); + const int nqapplet_error_count = sizeof(nqapplet_errors) / sizeof(struct sc_card_error); int i; LOG_FUNC_CALLED(card->ctx); sc_log(card->ctx, "Checking sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); - - for (i = 0; i < nqapplet_error_count; i++) - { - if (nqapplet_errors[i].SWs == ((sw1 << 8) | sw2)) - { + + for (i = 0; i < nqapplet_error_count; i++) { + if (nqapplet_errors[i].SWs == ((sw1 << 8) | sw2)) { LOG_TEST_RET(card->ctx, nqapplet_errors[i].errorno, nqapplet_errors[i].errorstr); } } @@ -436,35 +401,29 @@ static int nqapplet_get_data(struct sc_card *card, unsigned int id, u8 *resp, si rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - { + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { rv = apdu.resplen; - } - else if (apdu.sw1 == 0x61) - { + } else if (apdu.sw1 == 0x61) { rv = apdu.sw2 == 0 ? 256 : apdu.sw2; - } - else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) - { + } else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82) { rv = sc_check_sw(card, apdu.sw1, apdu.sw2); } LOG_FUNC_RETURN(card->ctx, rv); } -static int nqapplet_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) +static int nqapplet_select_file(struct sc_card *card, const struct sc_path *in_path, + struct sc_file **file_out) { LOG_FUNC_CALLED(card->ctx); /* the applet does not support SELECT EF/DF except for SELECT APPLET. In order to enable opensc-explorer add support for virtually selecting MF only */ - if (in_path->type == SC_PATH_TYPE_PATH && in_path->len == 2 && memcmp(in_path->value, "\x3F\x00", 2) == 0 ) - { - if ( file_out != NULL ) - { + if (in_path->type == SC_PATH_TYPE_PATH && in_path->len == 2 && + memcmp(in_path->value, "\x3F\x00", 2) == 0) { + if (file_out != NULL) { struct sc_file *file = sc_file_new(); - if (file == NULL) - { + if (file == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } file->path = *in_path; @@ -472,19 +431,17 @@ static int nqapplet_select_file(struct sc_card *card, const struct sc_path *in_p LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } } - //TODO allow selecting Applet AID + // TODO allow selecting Applet AID LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } -static int nqapplet_card_ctl(sc_card_t* card, unsigned long cmd, void* ptr) +static int nqapplet_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) { - switch (cmd) - { + switch (cmd) { case SC_CARDCTL_GET_SERIALNR: - if (card->serialnr.len) - { - sc_serial_number_t* serial = (sc_serial_number_t*)ptr; + if (card->serialnr.len) { + sc_serial_number_t *serial = (sc_serial_number_t *)ptr; memcpy(serial->value, card->serialnr.value, card->serialnr.len); serial->len = card->serialnr.len; return SC_SUCCESS; @@ -494,13 +451,11 @@ static int nqapplet_card_ctl(sc_card_t* card, unsigned long cmd, void* ptr) return SC_ERROR_NOT_SUPPORTED; } - -struct sc_card_driver * sc_get_nqApplet_driver(void) +struct sc_card_driver *sc_get_nqApplet_driver(void) { - sc_card_driver_t * iso_driver = sc_get_iso7816_driver(); + sc_card_driver_t *iso_driver = sc_get_iso7816_driver(); - if( iso_operations == NULL ) - { + if (iso_operations == NULL) { iso_operations = iso_driver->ops; } diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index beec9bf397..4f9ac41c27 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -21,10 +21,10 @@ #include #include +#include "cards.h" #include "common/compat_strlcpy.h" #include "log.h" #include "pkcs15.h" -#include "cards.h" static const char name_Card[] = "NQ-Applet"; static const char name_Vendor[] = "NXP"; @@ -38,17 +38,14 @@ static int get_nqapplet_certificate(sc_card_t *card, u8 data_id, struct sc_pkcs1 rv = sc_get_data(card, data_id, buffer, cb_buffer); LOG_TEST_RET(card->ctx, rv, "GET DATA failed"); - if (rv == 0) - { + if (rv == 0) { LOG_TEST_RET(card->ctx, SC_ERROR_FILE_NOT_FOUND, "No certificate data returned"); } - if (cert_info != NULL) - { + if (cert_info != NULL) { free(cert_info->value); cert_info->value = malloc(rv); - if (cert_info->value != NULL) - { + if (cert_info->value != NULL) { cert_info->len = rv; memcpy(cert_info->value, buffer, rv); } @@ -71,13 +68,14 @@ static int add_nqapplet_pin(sc_pkcs15_card_t *p15card, const char *id, u8 refere sc_pkcs15_format_id(id, &pin_info.auth_id); pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; pin_info.attrs.pin.reference = reference; - pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | + SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | SC_PKCS15_PIN_AUTH_TYPE_PIN; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_UTF8; pin_info.attrs.pin.min_length = 6; pin_info.attrs.pin.stored_length = 6; pin_info.attrs.pin.max_length = 6; pin_info.attrs.pin.pad_char = '\0'; - pin_info.tries_left = -1; //TODO + pin_info.tries_left = -1; // TODO pin_info.max_tries = 3; strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label)); @@ -113,7 +111,8 @@ static int add_nqapplet_certificate(sc_pkcs15_card_t *p15card, const char *id, c LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int add_nqapplet_private_key(sc_pkcs15_card_t *p15card, const char *id, int reference, const char *name, const char *pin_id, unsigned int usage) +static int add_nqapplet_private_key(sc_pkcs15_card_t *p15card, const char *id, int reference, + const char *name, const char *pin_id, unsigned int usage) { int rv; struct sc_pkcs15_prkey_info prkey_info; @@ -157,7 +156,8 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. certificate"); // 2.2) PrK.CH.Auth - rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT); + rv = add_nqapplet_private_key(p15card, "1", 0x01, "PrK.CH.Auth", "1", + SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT); LOG_TEST_RET(card->ctx, rv, "Failed to add Auth. private key"); // 3.1) C.CH.Encr @@ -177,8 +177,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) sc_context_t *ctx; sc_card_t *card; - if (!p15card || !p15card->card || !p15card->card->ctx) - { + if (!p15card || !p15card->card || !p15card->card->ctx) { return SC_ERROR_INVALID_ARGUMENTS; } @@ -187,8 +186,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); - if (card->type != SC_CARD_TYPE_NQ_APPLET) - { + if (card->type != SC_CARD_TYPE_NQ_APPLET) { sc_log(p15card->card->ctx, "Unsupported card type: %d", card->type); return SC_ERROR_WRONG_CARD; } @@ -196,11 +194,9 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) rv = add_nqapplet_objects(p15card); LOG_TEST_RET(ctx, rv, "Failed to add PKCS15"); - if (aid != NULL) - { + if (aid != NULL) { struct sc_file *file = sc_file_new(); - if (file != NULL) - { + if (file != NULL) { /* PKCS11 depends on the file_app object, provide MF */ sc_format_path("3f00", &file->path); sc_file_free(p15card->file_app); @@ -211,12 +207,9 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) sc_pkcs15_free_tokeninfo(p15card->tokeninfo); p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); - if (p15card->tokeninfo == NULL) - { + if (p15card->tokeninfo == NULL) { LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "unable to create tokeninfo struct"); - } - else - { + } else { char serial_hex[SC_MAX_SERIALNR * 2 + 2]; sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial_hex, sizeof(serial_hex), 0); From 621bbe6778c4b3da8aede5490d483d67f1e57e81 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 16 Nov 2021 13:19:51 +0100 Subject: [PATCH 2094/4321] Add missing include --- src/libopensc/card-nqApplet.c | 1 + src/libopensc/pkcs15-nqApplet.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index d08f22365c..b19743257e 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -21,6 +21,7 @@ #include #include +#include "opensc.h" #include "asn1.h" #include "cardctl.h" #include "internal.h" diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 4f9ac41c27..f5fe0c7bae 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -21,6 +21,7 @@ #include #include +#include "opensc.h" #include "cards.h" #include "common/compat_strlcpy.h" #include "log.h" From 7d71808c987e490ff6cfad22072cbdf6c7f2d92d Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 21 Mar 2021 07:55:27 +0100 Subject: [PATCH 2095/4321] pkcs11-tool: symmetric encrypt/decrypt supported mechanisms: AES-ECB, AES-CBC, AES-CBC-PAD support for initialization vector Tested - softhsm2, (test-pkcs11-tool-sym-crypt-test.sh) modified: doc/tools/pkcs11-tool.1.xml modified: src/tools/pkcs11-tool.c modified: tests/Makefile.am new file: tests/test-pkcs11-tool-sym-crypt-test.sh --- doc/tools/pkcs11-tool.1.xml | 22 +++ src/tools/pkcs11-tool.c | 179 ++++++++++++++++++++++- tests/Makefile.am | 6 +- tests/test-pkcs11-tool-sym-crypt-test.sh | 139 ++++++++++++++++++ 4 files changed, 339 insertions(+), 7 deletions(-) create mode 100755 tests/test-pkcs11-tool-sym-crypt-test.sh diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index a0f1ed4ce0..70d95380b6 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -373,6 +373,12 @@ Decrypt some data. + + + , + + Encrypt some data. + , @@ -646,6 +652,15 @@ + + + data + + Initialization vector for symmetric ciphers. + The data is hexadecimal number, i.e. "000013aa7bffa0". + + + @@ -668,6 +683,13 @@ using the private key with ID ID and using the RSA-PKCS mechanism: pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig + + To encrypt file using the AES key with ID 85 and using mechanism AES-CBC with padding: + +pkcs11-tool --encrypt --id 85 -m AES-CBC-PAD \ + --iv "00000000000000000000000000000000" \ + -i file.txt -o encrypted_file.data + diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 881768f165..6c476c9429 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -164,6 +164,7 @@ enum { OPT_DERIVE, OPT_DERIVE_PASS_DER, OPT_DECRYPT, + OPT_ENCRYPT, OPT_TEST_FORK, #if defined(_WIN32) || defined(HAVE_PTHREAD) OPT_TEST_THREADS, @@ -181,7 +182,8 @@ enum { OPT_ALLOWED_MECHANISMS, OPT_OBJECT_INDEX, OPT_ALLOW_SW, - OPT_LIST_INTERFACES + OPT_LIST_INTERFACES, + OPT_IV }; static const struct option options[] = { @@ -196,6 +198,7 @@ static const struct option options[] = { { "sign", 0, NULL, 's' }, { "verify", 0, NULL, OPT_VERIFY }, { "decrypt", 0, NULL, OPT_DECRYPT }, + { "encrypt", 0, NULL, OPT_ENCRYPT }, { "hash", 0, NULL, 'h' }, { "derive", 0, NULL, OPT_DERIVE }, { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER }, @@ -262,6 +265,7 @@ static const struct option options[] = { #endif { "generate-random", 1, NULL, OPT_GENERATE_RANDOM }, { "allow-sw", 0, NULL, OPT_ALLOW_SW }, + { "iv", 1, NULL, OPT_IV }, { NULL, 0, NULL, 0 } }; @@ -278,6 +282,7 @@ static const char *option_help[] = { "Sign some data", "Verify a signature of some data", "Decrypt some data", + "Encrypt some data", "Hash some data", "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", @@ -344,6 +349,7 @@ static const char *option_help[] = { #endif "Generate given amount of random data", "Allow using software mechanisms (without CKF_HW)", + "Initialization vector", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -401,6 +407,7 @@ static long opt_salt_len = 0; static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ static int opt_always_auth = 0; static CK_FLAGS opt_allow_sw = CKF_HW; +static const char * opt_iv = NULL; static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -509,11 +516,13 @@ static void show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj); static void sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void verify_signature(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +static void encrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE); static void derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *); static int gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, const char *, char *); + static int write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); static int delete_object(CK_SESSION_HANDLE session); @@ -547,6 +556,7 @@ static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); static int test_card_detection(int); static int hex_to_bin(const char *in, CK_BYTE *out, size_t *outlen); +static CK_BYTE_PTR get_iv(const char * iv_input, size_t *iv_size); static void pseudo_randomize(unsigned char *data, size_t dataLen); static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session); static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session); @@ -669,6 +679,7 @@ int main(int argc, char * argv[]) int do_sign = 0; int do_verify = 0; int do_decrypt = 0; + int do_encrypt = 0; int do_hash = 0; int do_derive = 0; int do_gen_keypair = 0; @@ -871,6 +882,11 @@ int main(int argc, char * argv[]) do_decrypt = 1; action_count++; break; + case OPT_ENCRYPT: + need_session |= NEED_SESSION_RW; + do_encrypt = 1; + action_count++; + break; case 'f': opt_sig_format = optarg; break; @@ -1063,6 +1079,9 @@ int main(int argc, char * argv[]) do_list_interfaces = 1; action_count++; break; + case OPT_IV: + opt_iv = optarg; + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -1193,8 +1212,8 @@ int main(int argc, char * argv[]) if (do_list_mechs) list_mechs(opt_slot); - if (do_sign || do_decrypt) { - CK_TOKEN_INFO info; + if (do_sign || do_decrypt || do_encrypt) { + CK_TOKEN_INFO info; get_token_info(opt_slot, &info); if (!(info.flags & CKF_TOKEN_INITIALIZED)) @@ -1255,7 +1274,7 @@ int main(int argc, char * argv[]) mf_flags = p11_mechanism_to_flags(opt_mechanism); } - if (do_sign || do_derive || do_decrypt) { + if (do_sign || do_derive) { /* * Newer mechanisms have their details in the mechanism table, however @@ -1273,6 +1292,40 @@ int main(int argc, char * argv[]) util_fatal("Private key not found"); } + if (do_decrypt) { + /* + * Newer mechanisms have their details in the mechanism table, however + * if it's not known fall back to the old code always assuming it was a + * CKO_PUBLIC_KEY then a CKO_CERTIFICATE. + */ + if (mf_flags != MF_UNKNOWN) { + /* this function dies on error via util_fatal */ + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } else if (!find_object(session, CKO_PRIVATE_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Private/secret key not found"); + } + + if (do_encrypt) { + /* + * Newer mechanisms have their details in the mechanism table, however + * if it's not known fall back to the old code always assuming it was a + * CKO_PUBLIC_KEY then a CKO_CERTIFICATE. + */ + if (mf_flags != MF_UNKNOWN) { + /* this function dies on error via util_fatal */ + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } else if (!find_object(session, CKO_SECRET_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Secret key not found"); + } + if (do_verify) { /* * Newer mechanisms have their details in the mechanism table, however @@ -1309,6 +1362,9 @@ int main(int argc, char * argv[]) if (do_decrypt) decrypt_data(opt_slot, session, object); + if (do_encrypt) + encrypt_data(opt_slot, session, object); + if (do_hash) hash_data(opt_slot, session); @@ -2332,6 +2388,8 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_ULONG in_len, out_len; int fd, r; + CK_BYTE_PTR iv = NULL; + size_t iv_size = 0; if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_DECRYPT|opt_allow_sw, NULL, 0, &opt_mechanism)) @@ -2383,9 +2441,17 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; case CKM_RSA_X_509: case CKM_RSA_PKCS: + case CKM_AES_ECB: mech.pParameter = NULL; mech.ulParameterLen = 0; break; + case CKM_AES_CBC: + case CKM_AES_CBC_PAD: + iv_size = 16; + iv = get_iv(opt_iv, &iv_size); + mech.pParameter = iv; + mech.ulParameterLen = iv_size; + break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } @@ -2435,14 +2501,90 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (fd < 0) util_fatal("failed to open %s: %m", opt_output); } - r = write(fd, out_buffer, out_len); if (r < 0) util_fatal("Failed to write to %s: %m", opt_output); if (fd != 1) close(fd); + + free(iv); } +static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + unsigned char in_buffer[1024], out_buffer[1024]; + CK_MECHANISM mech; + CK_RV rv; + CK_ULONG in_len, out_len; + int fd, r; + CK_BYTE_PTR iv = NULL; + size_t iv_size = 0; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_ENCRYPT | opt_allow_sw, NULL, 0, &opt_mechanism)) + util_fatal("Encrypt mechanism not supported"); + + fprintf(stderr, "Using encrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); + memset(&mech, 0, sizeof(mech)); + mech.mechanism = opt_mechanism; + + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + r = read(fd, in_buffer, sizeof(in_buffer)); + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); + in_len = r; + + switch (opt_mechanism) { + case CKM_AES_ECB: + mech.pParameter = NULL; + mech.ulParameterLen = 0; + break; + case CKM_AES_CBC: + case CKM_AES_CBC_PAD: + iv_size = 16; + iv = get_iv(opt_iv, &iv_size); + mech.pParameter = iv; + mech.ulParameterLen = iv_size; + break; + default: + util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); + } + + rv = p11->C_EncryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_EncryptInit", rv); + if (getALWAYS_AUTHENTICATE(session, key)) + login(session, CKU_CONTEXT_SPECIFIC); + + out_len = sizeof(out_buffer); + rv = p11->C_Encrypt(session, in_buffer, in_len, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_Encrypt", rv); + + if (fd != 0) + close(fd); + + if (opt_output == NULL) { + fd = 1; + } else { + fd = open(opt_output, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR); + if (fd < 0) + util_fatal("failed to open %s: %m", opt_output); + } + + r = write(fd, out_buffer, out_len); + if (r < 0) + util_fatal("Failed to write to %s: %m", opt_output); + if (fd != 1) + close(fd); + + free(iv); +} static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session) { @@ -7024,6 +7166,33 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen) return 1; } +static CK_BYTE_PTR get_iv(const char *iv_input, size_t *iv_size) +{ + CK_BYTE_PTR iv; + size_t size = *iv_size; + + /* no IV supplied on command line */ + if (!iv_input) { + *iv_size = 0; + return NULL; + } + + iv = calloc(sizeof(CK_BYTE), *iv_size); + if (!iv) { + fprintf(stderr, "Warning, out of memory, IV will not be used.\n"); + *iv_size = 0; + return NULL; + } + + if (!hex_to_bin(iv_input, iv, &size)) + return iv; /* only part from IV string is used as IV, msg printed in hex_to_bin() */ + + if (*iv_size != size) + fprintf(stderr, "Warning: IV string is too short, padding with zero bytes to length\n"); + + return iv; +} + static void pseudo_randomize(unsigned char *data, size_t dataLen) { size_t i = 0; diff --git a/tests/Makefile.am b/tests/Makefile.am index aa43668d58..deca1ca9ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,7 +13,8 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-sign-verify.sh \ - test-pkcs11-tool-allowed-mechanisms.sh + test-pkcs11-tool-allowed-mechanisms.sh \ + test-pkcs11-tool-sym-crypt-test.sh .NOTPARALLEL: TESTS = \ @@ -22,7 +23,8 @@ TESTS = \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ - test-pkcs11-tool-allowed-mechanisms.sh + test-pkcs11-tool-allowed-mechanisms.sh \ + test-pkcs11-tool-sym-crypt-test.sh XFAIL_TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-test.sh diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh new file mode 100755 index 0000000000..f2565ebeb2 --- /dev/null +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +source common.sh + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +# The Ubuntu has old softhsm version not supporting this feature +grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 + +softhsm_initialize + +#echo "=======================================================" +#echo "Generate AES key" +#echo "=======================================================" +#ID1="85" +# Generate key +#$PKCS11_TOOL --keygen --key-type="aes:32" --login --pin=$PIN \ +# --module="$P11LIB" --label="gen_aes256" --id="$ID1" +#assert $? "Failed to Generate AES key" + +echo "=======================================================" +echo "import AES key" +echo "=======================================================" +ID2="86" +echo -n "pppppppppppppppp" > aes_128.key +# import key +softhsm2-util --import aes_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_128 --id "$ID2" +assert $? "Fail, unable to import key" + +$PKCS11_TOOL --module="$P11LIB" --list-objects -l --pin=$PIN 2>/dev/null |tee > objects.list +assert $? "Failed to list objects" + +VECTOR="00000000000000000000000000000000" +echo "=======================================================" +echo " AES-CBC-PAD" +echo " OpenSSL encrypt, pkcs11-tool decrypt" +echo " pkcs11-tool encrypt, compare to openssl encrypt" +echo "=======================================================" + +echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data +openssl enc -aes-128-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" +assert $? "Fail, OpenSSL" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ + --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC-PAD - wrong decrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC-PAD - wrong encrypt" + + +echo "=======================================================" +echo " AES-ECB, AES-CBC - must fail, because the length of " +echo " the input is not multiple od block size " +echo "=======================================================" +! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail, AES-ECB must not work if the input is not a multiple of the block size" +! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail, AES-CBC must not work if the input is not a multiple of the block size" + +echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data + +echo "=======================================================" +echo " AES-ECB" +echo " OpenSSL encrypt, pkcs11-tool decrypt" +echo " pkcs11-tool encrypt, compare to openssl encrypt" +echo "=======================================================" + +openssl enc -aes-128-ecb -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -K "70707070707070707070707070707070" +assert $? "Fail/OpenSSL" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-ECB --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null +assert $? "Fail, AES-ECB - wrong decrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-ECB - wrong encrypt" + +echo "=======================================================" +echo " AES-CBC" +echo " OpenSSL encrypt, pkcs11-tool decrypt" +echo " pkcs11-tool encrypt, compare to openssl encrypt" +echo "=======================================================" + +openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" +assert $? "Fail/OpenSSL" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong decrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong encrypt" + +VECTOR="000102030405060708090a0b0c0d0e0f" +echo "=======================================================" +echo " AES-CBC, another IV" +echo " OpenSSL encrypt, pkcs11-tool decrypt" +echo " pkcs11-tool encrypt, compare to openssl encrypt" +echo "=======================================================" + +openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" +assert $? "Fail/Openssl" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong decrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong encrypt" + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +softhsm_cleanup + +rm objects.list +rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data +exit $ERRORS From 9136878cce3242d7d6321d21dc8ede43039d5e4a Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 21 Mar 2021 17:22:46 +0100 Subject: [PATCH 2096/4321] pkcs11-tool: unwrap operation support for unwrapping GENERIC SECRET / AES key Tested: softhsm, RSA-PKCS mechanism. Tested: MyEID 4.5.5, only partial test due to missing support for symmetric encryption/decryption modified: doc/tools/pkcs11-tool.1.xml modified: src/tools/pkcs11-tool.c modified: tests/Makefile.am new file: tests/test-pkcs11-tool-unwrap-test.sh --- doc/tools/pkcs11-tool.1.xml | 18 +++ src/tools/pkcs11-tool.c | 158 +++++++++++++++++++++++++- tests/Makefile.am | 6 +- tests/test-pkcs11-tool-unwrap-test.sh | 77 +++++++++++++ 4 files changed, 256 insertions(+), 3 deletions(-) create mode 100755 tests/test-pkcs11-tool-unwrap-test.sh diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 70d95380b6..0d83733db3 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -379,6 +379,12 @@ Encrypt some data. + + + , + + Unwrap key. + , @@ -690,6 +696,18 @@ pkcs11-tool --encrypt --id 85 -m AES-CBC-PAD \ --iv "00000000000000000000000000000000" \ -i file.txt -o encrypted_file.data + + Use the key with ID 22 and mechanism RSA-PKCS to unwrap key from file + aes_wrapped.key. After a successful unwrap operation, + a new AES key is created on token. ID of this key is set to 90 and label of this + key is set to unwrapped-key + Note: for the MyEID card, the AES key size must be present in key + specification i.e. AES:16 + +pkcs11-tool --unwrap --mechanism RSA-PKCS --id 22 \ + -i aes_wrapped.key --key-type AES: \ + --application-id 90 --applicatin-label unwrapped-key + diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6c476c9429..8224494de9 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -165,6 +165,7 @@ enum { OPT_DERIVE_PASS_DER, OPT_DECRYPT, OPT_ENCRYPT, + OPT_UNWRAP, OPT_TEST_FORK, #if defined(_WIN32) || defined(HAVE_PTHREAD) OPT_TEST_THREADS, @@ -199,6 +200,7 @@ static const struct option options[] = { { "verify", 0, NULL, OPT_VERIFY }, { "decrypt", 0, NULL, OPT_DECRYPT }, { "encrypt", 0, NULL, OPT_ENCRYPT }, + { "unwrap", 0, NULL, OPT_UNWRAP }, { "hash", 0, NULL, 'h' }, { "derive", 0, NULL, OPT_DERIVE }, { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER }, @@ -283,6 +285,7 @@ static const char *option_help[] = { "Verify a signature of some data", "Decrypt some data", "Encrypt some data", + "Unwrap key", "Hash some data", "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", @@ -522,6 +525,7 @@ static void derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *); static int gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, const char *, char *); +static int unwrap_key(CK_SESSION_HANDLE session); static int write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); @@ -680,6 +684,7 @@ int main(int argc, char * argv[]) int do_verify = 0; int do_decrypt = 0; int do_encrypt = 0; + int do_unwrap = 0; int do_hash = 0; int do_derive = 0; int do_gen_keypair = 0; @@ -887,6 +892,11 @@ int main(int argc, char * argv[]) do_encrypt = 1; action_count++; break; + case OPT_UNWRAP: + need_session |= NEED_SESSION_RW; + do_unwrap = 1; + action_count++; + break; case 'f': opt_sig_format = optarg; break; @@ -1212,7 +1222,7 @@ int main(int argc, char * argv[]) if (do_list_mechs) list_mechs(opt_slot); - if (do_sign || do_decrypt || do_encrypt) { + if (do_sign || do_decrypt || do_encrypt || do_unwrap) { CK_TOKEN_INFO info; get_token_info(opt_slot, &info); @@ -1346,6 +1356,9 @@ int main(int argc, char * argv[]) util_fatal("Public key nor certificate not found"); } + if (do_unwrap) + unwrap_key(session); + /* before list objects, so we can see a derived key */ if (do_derive) derive_key(opt_slot, session, object); @@ -3144,6 +3157,149 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey return 1; } +static int +unwrap_key(CK_SESSION_HANDLE session) +{ + CK_MECHANISM mechanism; + CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY; + CK_BBOOL _true = TRUE; + CK_BBOOL _false = FALSE; + CK_KEY_TYPE key_type = CKK_AES; + CK_ULONG key_length; + const char *length; + CK_ATTRIBUTE keyTemplate[20] = { + {CKA_CLASS, &secret_key_class, sizeof(secret_key_class)}, + {CKA_TOKEN, &_true, sizeof(_true)}, + }; + CK_OBJECT_HANDLE hSecretKey; + int n_attr = 2; + CK_RV rv; + int r, fd; + unsigned char in_buffer[1024]; + CK_ULONG wrapped_key_length; + CK_BYTE_PTR pWrappedKey; + CK_BYTE_PTR iv = NULL; + size_t iv_size = 0; + CK_OBJECT_HANDLE hUnwrappingKey; + + if (!find_object(session, CKO_PRIVATE_KEY, &hUnwrappingKey, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &hUnwrappingKey, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Private/secret key not found"); + + if (!opt_mechanism_used) + util_fatal("Unable to unwrap, no mechanism specified\n"); + + mechanism.mechanism = opt_mechanism; + mechanism.pParameter = NULL_PTR; + mechanism.ulParameterLen = 0; + + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + r = read(fd, in_buffer, sizeof(in_buffer)); + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); + wrapped_key_length = r; + if (fd != 0) + close(fd); + pWrappedKey = in_buffer; + + if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { + iv_size = 16; + iv = get_iv(opt_iv, &iv_size); + mechanism.pParameter = iv; + mechanism.ulParameterLen = iv_size; + } + + if (opt_key_type != NULL) { + if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0) { + length = opt_key_type + strlen("AES:"); + key_type = CKK_AES; + + } else if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) == 0) { + length = opt_key_type + strlen("GENERIC:"); + key_type = CKK_GENERIC_SECRET; + + } else { + util_fatal("Unsupported key type %s", opt_key_type); + } + + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + n_attr++; + + if (opt_is_sensitive != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); + n_attr++; + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); + n_attr++; + } + + if (opt_key_usage_default || opt_key_usage_decrypt) { + FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); + n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); + n_attr++; + } + if (opt_key_usage_wrap) { + FILL_ATTR(keyTemplate[n_attr], CKA_WRAP, &_true, sizeof(_true)); + n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true)); + n_attr++; + } + + if (opt_is_extractable != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); + n_attr++; + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_false, sizeof(_true)); + n_attr++; + } + /* softhsm2 does not allow to attribute CKA_VALUE_LEN, but MyEID card must have this attribute + specified. We set CKA_VALUE_LEN only if the user sets it in the key specification. */ + key_length = (unsigned long)atol(length); + if (key_length != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); + n_attr++; + } + } + + if (opt_application_label != NULL) { + FILL_ATTR(keyTemplate[n_attr], CKA_LABEL, opt_application_label, strlen(opt_application_label)); + n_attr++; + } + + if (opt_application_id != NULL) { + CK_BYTE object_id[100]; + size_t id_len; + + id_len = sizeof(object_id); + if (hex_to_bin(opt_application_id, object_id, &id_len)) { + FILL_ATTR(keyTemplate[n_attr], CKA_ID, object_id, id_len); + n_attr++; + } + } + + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_attr++; + } + rv = p11->C_UnwrapKey(session, &mechanism, hUnwrappingKey, + pWrappedKey, wrapped_key_length, keyTemplate, n_attr, &hSecretKey); + if (rv != CKR_OK) + p11_fatal("C_UnwrapKey", rv); + + free(iv); + printf("Key unwrapped\n"); + show_object(session, hSecretKey); + return 1; +} + #ifdef ENABLE_OPENSSL static void parse_certificate(struct x509cert_info *cert, diff --git a/tests/Makefile.am b/tests/Makefile.am index deca1ca9ea..13cf9f4e70 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,7 +14,8 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ - test-pkcs11-tool-sym-crypt-test.sh + test-pkcs11-tool-sym-crypt-test.sh\ + test-pkcs11-tool-unwrap-test.sh .NOTPARALLEL: TESTS = \ @@ -24,7 +25,8 @@ TESTS = \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ - test-pkcs11-tool-sym-crypt-test.sh + test-pkcs11-tool-sym-crypt-test.sh\ + test-pkcs11-tool-unwrap-test.sh XFAIL_TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-test.sh diff --git a/tests/test-pkcs11-tool-unwrap-test.sh b/tests/test-pkcs11-tool-unwrap-test.sh new file mode 100755 index 0000000000..1df8118aff --- /dev/null +++ b/tests/test-pkcs11-tool-unwrap-test.sh @@ -0,0 +1,77 @@ +#!/bin/bash +source common.sh + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +# The Ubuntu has old softhsm version not supporting this feature +grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +softhsm_initialize + +#echo "=======================================================" +#echo "Generate RSA key" +#echo "=======================================================" +ID1="85" +ID2="95" +ID3="96" +# Generate key +$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --keypairgen --key-type="rsa:1024" --id "$ID1" --usage-wrap +assert $? "Failed to Generate RSA key" +# export public key +$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --read-object --type pubkey --id="$ID1" -o rsa_pub.key +assert $? "Failed to export public key" +# create AES key +KEY="70707070707070707070707070707070" + +echo -n $KEY|xxd -p -r > aes_plain_key +# wrap AES key +openssl rsautl -encrypt -pubin --keyform der -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key +assert $? "Failed wrap AES key" + +# unwrap key by pkcs11 interface +$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --unwrap --mechanism RSA-PKCS --id "$ID1" -i aes_wrapped_key --key-type GENERIC: \ + --extractable --application-id "$ID3" --application-label "unwrap-generic-ex" 2>/dev/null +assert $? "Unwrap failed" +# because key is extractable, there is no problem to compare key value with original key +$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --id "$ID3" --read-object --type secrkey --output-file generic_extracted_key +assert $? "unable to read key value" +cmp generic_extracted_key aes_plain_key >/dev/null 2>/dev/null +assert $? "extracted key does not match the input key" + +# unwrap AES key, not extractable +$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --unwrap --mechanism RSA-PKCS --id "$ID1" -i aes_wrapped_key --key-type AES: \ + --application-id "$ID2" --application-label "unwrap-aes" 2>/dev/null +assert $? "Unwrap failed" + +# To check if AES key was correctly unwrapped (non extractable), we need to encrypt some data by pkcs11 interface and by openssl +# (with same key). If result is same, key was correctly unwrapped. +VECTOR="00000000000000000000000000000000" +echo "=======================================================" +echo " AES-CBC" +echo " OpenSSL encrypt, pkcs11-tool encrypt, compare" +echo "=======================================================" + +echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data + +openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K $KEY +assert $? "Fail/Openssl" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong encrypt" + + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +softhsm_cleanup + +rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key + +exit $ERRORS From 812c08d2c2d1e27b97bece231260d1322ed12a9c Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 26 Mar 2021 07:29:34 +0100 Subject: [PATCH 2097/4321] pkcs11-tool: wrap operation support for key wrap operation Tested: softhsm, GENERIC SECRET wrapped by RSA-PKCS mechanism modified: doc/tools/pkcs11-tool.1.xml modified: src/tools/pkcs11-tool.c modified: tests/Makefile.am renamed: tests/test-pkcs11-tool-unwrap-test.sh -> tests/test-pkcs11-tool-unwrap-wrap-test.sh --- doc/tools/pkcs11-tool.1.xml | 6 ++ src/tools/pkcs11-tool.c | 77 ++++++++++++++++++- tests/Makefile.am | 4 +- ...h => test-pkcs11-tool-unwrap-wrap-test.sh} | 26 ++++--- 4 files changed, 100 insertions(+), 13 deletions(-) rename tests/{test-pkcs11-tool-unwrap-test.sh => test-pkcs11-tool-unwrap-wrap-test.sh} (80%) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 0d83733db3..7cf0f4e0be 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -385,6 +385,12 @@ Unwrap key. + + + , + + Wrap key. + , diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8224494de9..be695a6969 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -166,6 +166,7 @@ enum { OPT_DECRYPT, OPT_ENCRYPT, OPT_UNWRAP, + OPT_WRAP, OPT_TEST_FORK, #if defined(_WIN32) || defined(HAVE_PTHREAD) OPT_TEST_THREADS, @@ -201,6 +202,7 @@ static const struct option options[] = { { "decrypt", 0, NULL, OPT_DECRYPT }, { "encrypt", 0, NULL, OPT_ENCRYPT }, { "unwrap", 0, NULL, OPT_UNWRAP }, + { "wrap", 0, NULL, OPT_WRAP }, { "hash", 0, NULL, 'h' }, { "derive", 0, NULL, OPT_DERIVE }, { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER }, @@ -286,6 +288,7 @@ static const char *option_help[] = { "Decrypt some data", "Encrypt some data", "Unwrap key", + "Wrap key", "Hash some data", "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", @@ -526,6 +529,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *); static int gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, const char *, char *); static int unwrap_key(CK_SESSION_HANDLE session); +static int wrap_key(CK_SESSION_HANDLE session); static int write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); @@ -685,6 +689,7 @@ int main(int argc, char * argv[]) int do_decrypt = 0; int do_encrypt = 0; int do_unwrap = 0; + int do_wrap = 0; int do_hash = 0; int do_derive = 0; int do_gen_keypair = 0; @@ -897,6 +902,11 @@ int main(int argc, char * argv[]) do_unwrap = 1; action_count++; break; + case OPT_WRAP: + need_session |= NEED_SESSION_RW; + do_wrap = 1; + action_count++; + break; case 'f': opt_sig_format = optarg; break; @@ -1222,7 +1232,7 @@ int main(int argc, char * argv[]) if (do_list_mechs) list_mechs(opt_slot); - if (do_sign || do_decrypt || do_encrypt || do_unwrap) { + if (do_sign || do_decrypt || do_encrypt || do_unwrap || do_wrap) { CK_TOKEN_INFO info; get_token_info(opt_slot, &info); @@ -1359,6 +1369,9 @@ int main(int argc, char * argv[]) if (do_unwrap) unwrap_key(session); + if (do_wrap) + wrap_key(session); + /* before list objects, so we can see a derived key */ if (do_derive) derive_key(opt_slot, session, object); @@ -3300,6 +3313,68 @@ unwrap_key(CK_SESSION_HANDLE session) return 1; } +static int +wrap_key(CK_SESSION_HANDLE session) +{ + CK_BYTE pWrappedKey[4096]; + CK_ULONG pulWrappedKeyLen = sizeof(pWrappedKey); + CK_MECHANISM mechanism; + CK_OBJECT_HANDLE hWrappingKey; // wrapping key + CK_OBJECT_HANDLE hkey; // key to be wrapped + CK_RV rv; + CK_BYTE hkey_id; + size_t hkey_id_len; + int fd, r; + CK_BYTE_PTR iv = NULL; + size_t iv_size = 0; + + if (NULL == opt_application_id) + util_fatal("Use --application-id to specify secret key (to be wrapped)"); + if (!opt_mechanism_used) + util_fatal("Unable to wrap, no mechanism specified\n"); + + mechanism.mechanism = opt_mechanism; + mechanism.pParameter = NULL_PTR; + mechanism.ulParameterLen = 0; + if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { + iv_size = 16; + iv = get_iv(opt_iv, &iv_size); + mechanism.pParameter = iv; + mechanism.ulParameterLen = iv_size; + } + + hkey_id_len = sizeof(hkey_id); + if (!hex_to_bin(opt_application_id, &hkey_id, &hkey_id_len)) + util_fatal("Invalid application-id \"%s\"\n", opt_application_id); + + if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? &hkey_id : NULL, hkey_id_len, 0)) + util_fatal("Secret key (to be wrapped) not found"); + + if (!find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &hWrappingKey, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Public/secret key (wrapping key) not found"); + + rv = p11->C_WrapKey(session, &mechanism, hWrappingKey, hkey, pWrappedKey, &pulWrappedKeyLen); + if (rv != CKR_OK) + p11_fatal("C_WrapKey", rv); + printf("Key wrapped\n"); + + if (opt_output == NULL) + fd = 1; + else if ((fd = open(opt_output, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR)) < 0) + util_fatal("failed to open %s: %m", opt_output); + + r = write(fd, pWrappedKey, pulWrappedKeyLen); + + if (r < 0) + util_fatal("Failed to write to %s: %m", opt_output); + if (fd != 1) + close(fd); + free(iv); + return 1; +} #ifdef ENABLE_OPENSSL static void parse_certificate(struct x509cert_info *cert, diff --git a/tests/Makefile.am b/tests/Makefile.am index 13cf9f4e70..d378e2ee00 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ test-pkcs11-tool-sym-crypt-test.sh\ - test-pkcs11-tool-unwrap-test.sh + test-pkcs11-tool-unwrap-wrap-test.sh .NOTPARALLEL: TESTS = \ @@ -26,7 +26,7 @@ TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ test-pkcs11-tool-sym-crypt-test.sh\ - test-pkcs11-tool-unwrap-test.sh + test-pkcs11-tool-unwrap-wrap-test.sh XFAIL_TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-test.sh diff --git a/tests/test-pkcs11-tool-unwrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh similarity index 80% rename from tests/test-pkcs11-tool-unwrap-test.sh rename to tests/test-pkcs11-tool-unwrap-wrap-test.sh index 1df8118aff..7aedd24213 100755 --- a/tests/test-pkcs11-tool-unwrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -12,18 +12,19 @@ fi grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 softhsm_initialize -#echo "=======================================================" -#echo "Generate RSA key" -#echo "=======================================================" +echo "=======================================================" +echo " Unwrap test" +echo "=======================================================" ID1="85" ID2="95" ID3="96" -# Generate key +# Generate RSA key (this key is used to unwrap/wrap operation) $PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --keypairgen --key-type="rsa:1024" --id "$ID1" --usage-wrap assert $? "Failed to Generate RSA key" # export public key $PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --read-object --type pubkey --id="$ID1" -o rsa_pub.key assert $? "Failed to export public key" + # create AES key KEY="70707070707070707070707070707070" @@ -50,11 +51,6 @@ assert $? "Unwrap failed" # To check if AES key was correctly unwrapped (non extractable), we need to encrypt some data by pkcs11 interface and by openssl # (with same key). If result is same, key was correctly unwrapped. VECTOR="00000000000000000000000000000000" -echo "=======================================================" -echo " AES-CBC" -echo " OpenSSL encrypt, pkcs11-tool encrypt, compare" -echo "=======================================================" - echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K $KEY @@ -66,12 +62,22 @@ assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong encrypt" +echo "=======================================================" +echo " Wrap test" +echo "=======================================================" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --wrap --mechanism RSA-PKCS --id "$ID1" --application-id "$ID3" --output-file wraped.key +assert $? "Fail, unable to wrap" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --mechanism RSA-PKCS --id "$ID1" --input-file wraped.key --output-file plain_wraped.key +assert $? "Fail, unable to decrypt wrapped key" +cmp plain_wraped.key aes_plain_key >/dev/null 2>/dev/null +assert $? "wrapped key after decipher does not match the original key" echo "=======================================================" echo "Cleanup" echo "=======================================================" softhsm_cleanup -rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key +rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wraped.key plain_wraped.key exit $ERRORS From 0de0fa21c0a29181744b8599ebf1694bd2a516d8 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 13 Apr 2021 12:56:30 +0200 Subject: [PATCH 2098/4321] pkcs11-tool: encrypt/decrypt - removed fixed limit for data size Use C_DecryptUpdate/C_EncryptUpdate for large input files. modified: src/tools/pkcs11-tool.c modified: tests/test-pkcs11-tool-sym-crypt-test.sh --- src/tools/pkcs11-tool.c | 178 +++++++++++++++-------- tests/test-pkcs11-tool-sym-crypt-test.sh | 28 +++- 2 files changed, 136 insertions(+), 70 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index be695a6969..0cb1e700fa 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2404,7 +2404,6 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, printf("Cryptoki returned error: %s\n", CKR2Str(rv)); } - static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { @@ -2413,7 +2412,8 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_RV rv; CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_ULONG in_len, out_len; - int fd, r; + int fd_in, fd_out; + int r; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; @@ -2430,15 +2430,6 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("The hash-algorithm is applicable only to " "RSA-PKCS-OAEP mechanism"); - if (opt_input == NULL) - fd = 0; - else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) - util_fatal("Cannot open %s: %m", opt_input); - - r = read(fd, in_buffer, sizeof(in_buffer)); - if (r < 0) - util_fatal("Cannot read from %s: %m", opt_input); - in_len = r; /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { @@ -2505,33 +2496,66 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } - rv = p11->C_DecryptInit(session, &mech, key); - if (rv != CKR_OK) - p11_fatal("C_DecryptInit", rv); - if (getALWAYS_AUTHENTICATE(session, key)) - login(session,CKU_CONTEXT_SPECIFIC); + if (opt_input == NULL) + fd_in = 0; + else if ((fd_in = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); - out_len = sizeof(out_buffer); - rv = p11->C_Decrypt(session, in_buffer, in_len, out_buffer, &out_len); - if (rv != CKR_OK) - p11_fatal("C_Decrypt", rv); + if (opt_output == NULL) { + fd_out = 1; + } else { + fd_out = open(opt_output, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR); + if (fd_out < 0) + util_fatal("failed to open %s: %m", opt_output); + } - if (fd != 0) - close(fd); + r = read(fd_in, in_buffer, sizeof(in_buffer)); + in_len = r; - if (opt_output == NULL) { - fd = 1; + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); + + rv = CKR_CANCEL; + if (r < (int) sizeof(in_buffer)) { + out_len = sizeof(out_buffer); + rv = p11->C_DecryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_DecryptInit", rv); + if (getALWAYS_AUTHENTICATE(session, key)) + login(session, CKU_CONTEXT_SPECIFIC); + rv = p11->C_Decrypt(session, in_buffer, in_len, out_buffer, &out_len); } - else { - fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR); - if (fd < 0) - util_fatal("failed to open %s: %m", opt_output); + if (rv != CKR_OK) { + rv = p11->C_DecryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_DecryptInit", rv); + if (getALWAYS_AUTHENTICATE(session, key)) + login(session, CKU_CONTEXT_SPECIFIC); + do { + out_len = sizeof(out_buffer); + rv = p11->C_DecryptUpdate(session, in_buffer, in_len, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_DecryptUpdate", rv); + r = write(fd_out, out_buffer, out_len); + if (r != (int) out_len) + util_fatal("Cannot write to %s: %m", opt_output); + r = read(fd_in, in_buffer, sizeof(in_buffer)); + in_len = r; + } while (r > 0); + out_len = sizeof(out_buffer); + rv = p11->C_DecryptFinal(session, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_DecryptFinal", rv); } - r = write(fd, out_buffer, out_len); - if (r < 0) - util_fatal("Failed to write to %s: %m", opt_output); - if (fd != 1) - close(fd); + if (out_len) { + r = write(fd_out, out_buffer, out_len); + if (r != (int) out_len) + util_fatal("Cannot write to %s: %m", opt_output); + } + if (fd_in != 0) + close(fd_in); + if (fd_out != 1) + close(fd_out); free(iv); } @@ -2543,7 +2567,8 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_MECHANISM mech; CK_RV rv; CK_ULONG in_len, out_len; - int fd, r; + int fd_in, fd_out; + int r; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; @@ -2555,16 +2580,6 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; - if (opt_input == NULL) - fd = 0; - else if ((fd = open(opt_input, O_RDONLY | O_BINARY)) < 0) - util_fatal("Cannot open %s: %m", opt_input); - - r = read(fd, in_buffer, sizeof(in_buffer)); - if (r < 0) - util_fatal("Cannot read from %s: %m", opt_input); - in_len = r; - switch (opt_mechanism) { case CKM_AES_ECB: mech.pParameter = NULL; @@ -2581,37 +2596,72 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } - rv = p11->C_EncryptInit(session, &mech, key); - if (rv != CKR_OK) - p11_fatal("C_EncryptInit", rv); - if (getALWAYS_AUTHENTICATE(session, key)) - login(session, CKU_CONTEXT_SPECIFIC); - - out_len = sizeof(out_buffer); - rv = p11->C_Encrypt(session, in_buffer, in_len, out_buffer, &out_len); - if (rv != CKR_OK) - p11_fatal("C_Encrypt", rv); - - if (fd != 0) - close(fd); + if (opt_input == NULL) + fd_in = 0; + else if ((fd_in = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); if (opt_output == NULL) { - fd = 1; + fd_out = 1; } else { - fd = open(opt_output, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR); - if (fd < 0) + fd_out = open(opt_output, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR); + if (fd_out < 0) util_fatal("failed to open %s: %m", opt_output); } - r = write(fd, out_buffer, out_len); + r = read(fd_in, in_buffer, sizeof(in_buffer)); + in_len = r; + if (r < 0) - util_fatal("Failed to write to %s: %m", opt_output); - if (fd != 1) - close(fd); + util_fatal("Cannot read from %s: %m", opt_input); + + rv = CKR_CANCEL; + if (r < (int) sizeof(in_buffer)) { + out_len = sizeof(out_buffer); + rv = p11->C_EncryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_EncryptInit", rv); + if (getALWAYS_AUTHENTICATE(session, key)) + login(session, CKU_CONTEXT_SPECIFIC); + out_len = sizeof(out_buffer); + rv = p11->C_Encrypt(session, in_buffer, in_len, out_buffer, &out_len); + } + if (rv != CKR_OK) { + rv = p11->C_EncryptInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_EncryptInit", rv); + if (getALWAYS_AUTHENTICATE(session, key)) + login(session, CKU_CONTEXT_SPECIFIC); + do { + out_len = sizeof(out_buffer); + rv = p11->C_EncryptUpdate(session, in_buffer, in_len, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_EncryptUpdate", rv); + r = write(fd_out, out_buffer, out_len); + if (r != (int) out_len) + util_fatal("Cannot write to %s: %m", opt_output); + r = read(fd_in, in_buffer, sizeof(in_buffer)); + in_len = r; + } while (r > 0); + out_len = sizeof(out_buffer); + rv = p11->C_EncryptFinal(session, out_buffer, &out_len); + if (rv != CKR_OK) + p11_fatal("C_EncryptFinal", rv); + } + if (out_len) { + r = write(fd_out, out_buffer, out_len); + if (r != (int) out_len) + util_fatal("Cannot write to %s: %m", opt_output); + } + if (fd_in != 0) + close(fd_in); + if (fd_out != 1) + close(fd_out); free(iv); } + static void hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session) { unsigned char buffer[64]; diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index f2565ebeb2..76daca78ba 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -42,26 +42,42 @@ echo " OpenSSL encrypt, pkcs11-tool decrypt" echo " pkcs11-tool encrypt, compare to openssl encrypt" echo "=======================================================" -echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data +echo "C_Encrypt" +dd if=/dev/urandom bs=200 count=1 >aes_plain.data 2>/dev/null +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +openssl enc -aes-128-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC-PAD (C_Encrypt) - wrong encrypt" +echo "C_Decrypt" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ + --input-file aes_ciphertext_pkcs11.data --output-file aes_plain_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_pkcs11.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC-PAD (C_Decrypt) - wrong decrypt" + +echo "C_DecryptUpdate" +dd if=/dev/urandom bs=8131 count=3 >aes_plain.data 2>/dev/null openssl enc -aes-128-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" assert $? "Fail, OpenSSL" $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null -assert $? "Fail/pkcs11-tool decrypt" +assert $? "Fail/pkcs11-tool (C_DecryptUpdate) decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC-PAD - wrong decrypt" - +echo "C_EncryptUpdate" $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null -assert $? "Fail, AES-CBC-PAD - wrong encrypt" - +assert $? "Fail, AES-CBC-PAD (C_EncryptUpdate) - wrong encrypt" echo "=======================================================" echo " AES-ECB, AES-CBC - must fail, because the length of " echo " the input is not multiple od block size " echo "=======================================================" +echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data ! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail, AES-ECB must not work if the input is not a multiple of the block size" ! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ @@ -135,5 +151,5 @@ echo "=======================================================" softhsm_cleanup rm objects.list -rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data +rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain_pkcs11.data exit $ERRORS From 8b94d04dbbe383c485d341333f8f59494645ea1a Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 24 Aug 2021 16:38:42 +0200 Subject: [PATCH 2099/4321] github actions: pkcs11-tool - wrap/unwrap tests (using OsEID simulator) modified: .github/test-oseid.sh --- .github/test-oseid.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index dd6f60be7b..f74e381163 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -42,6 +42,7 @@ echo | ./OsEID-tool INIT ./OsEID-tool EC-SIGN-TEST ./OsEID-tool EC-SIGN-PKCS11-TEST ./OsEID-tool EC-ECDH-TEST +./OsEID-tool UNWRAP-WRAP-TEST popd # this does not work as we have random key IDs in here From 212ce000527f2f33ff9571934e756f7fbe8d8d48 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 Nov 2021 19:13:40 +0100 Subject: [PATCH 2100/4321] Fix spell errors --- tests/test-pkcs11-tool-sym-crypt-test.sh | 2 +- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index 76daca78ba..b55fc0515c 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -6,7 +6,7 @@ echo "=======================================================" echo "Setup SoftHSM" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi # The Ubuntu has old softhsm version not supporting this feature diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 7aedd24213..d347288bc7 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -5,7 +5,7 @@ echo "=======================================================" echo "Setup SoftHSM" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNINIG: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi # The Ubuntu has old softhsm version not supporting this feature @@ -66,11 +66,11 @@ echo "=======================================================" echo " Wrap test" echo "=======================================================" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --wrap --mechanism RSA-PKCS --id "$ID1" --application-id "$ID3" --output-file wraped.key +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --wrap --mechanism RSA-PKCS --id "$ID1" --application-id "$ID3" --output-file wrapped.key assert $? "Fail, unable to wrap" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --mechanism RSA-PKCS --id "$ID1" --input-file wraped.key --output-file plain_wraped.key +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --mechanism RSA-PKCS --id "$ID1" --input-file wrapped.key --output-file plain_wrapped.key assert $? "Fail, unable to decrypt wrapped key" -cmp plain_wraped.key aes_plain_key >/dev/null 2>/dev/null +cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null assert $? "wrapped key after decipher does not match the original key" echo "=======================================================" @@ -78,6 +78,6 @@ echo "Cleanup" echo "=======================================================" softhsm_cleanup -rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wraped.key plain_wraped.key +rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wrapped.key plain_wrapped.key exit $ERRORS From 38da7e1062d4eb3beefa50a2c4838b8ac4ae7066 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 17 Nov 2021 18:42:35 +0100 Subject: [PATCH 2101/4321] pkcs15-idprime: Stop iterator in case of failure For getting objects, idprime_card_ctl() starts iterator in list_t in card->drv_data. In case of fail, iterator is not set to stopped and variable iter_active in list_t remains 1. Then during memory release in sc_disconnect_card() list_t is not freed. Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=39268 --- src/libopensc/pkcs15-idprime.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 9d8eb1113f..eb447f320e 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -269,8 +269,10 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) cert_out->key = NULL; fail: sc_pkcs15_free_certificate(cert_out); - if (r < 0) + if (r < 0) { + (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ + } } r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); From 1c9e2595d1204ed7ed1443eda6b9950348b46422 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Nov 2021 13:32:09 +0100 Subject: [PATCH 2102/4321] lgtm: Drop file clasification to resume analysis it looks like *any* file classification excludes the files from analysis, which was clearly not the intention --- .lgtm.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.lgtm.yml b/.lgtm.yml index 3798874734..676cc5cc2f 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -4,17 +4,6 @@ path_classifiers: - src/tests/ generated: - "src/tools/*-cmdline.*" - library: - - src/libopensc/ - - src/common/ - - src/minidriver/ - - src/pkcs11/ - - src/pkcs15init/ - - src/scconf/ - - src/sm/ - - src/smm/ - tools: - - src/tools/ queries: # This reports all the uses of the DES, but this is needed for # interoperability with cards not supporting AES From e06ea1812e510c4337f5b037eabe01c033aaef61 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 27 Nov 2021 07:39:39 -0600 Subject: [PATCH 2103/4321] OpenSSL FIPS_mode not defined in 3.0.0 When trying to test with OpenSSL-3.0.0 the use of `FIPS_mode()` in two places pkcs11-tool.c and framework-pkcs11.c causes a run time error like: "./pkcs11-tool: symbol lookup error: /opt/ossl-3.0.0/lib/opensc-pkcs11.so: undefined symbol: FIPS_mode" sc-ossl-sc-ossl-compat.h was modified to use `OSSL_PROVIDER_available(NULL, "fips")` which is is in OpenSSL 3.0.0 This patch is based on https://github.com/OpenSC/OpenSC/pull/2438 https://github.com/OpenSC/OpenSC/commit/1272521059eadf19e3b58b275efb4b41465804df but #2438 contains many other changes and and may not be commited for some time. Date: Sat Nov 27 07:39:39 2021 -0600 Changes to be committed: modified: src/libopensc/sc-ossl-compat.h --- src/libopensc/sc-ossl-compat.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index ba4a0c511e..782bb99429 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -96,8 +96,11 @@ extern "C" { #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include #define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates #define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp EVP_PKEY_CTX_set1_rsa_keygen_pubexp +#define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") #endif /* From 5fce75102affeb52cabc3fd04450bda0c455a00c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 24 Nov 2021 10:58:15 +0100 Subject: [PATCH 2104/4321] pkcs15-init: Set algorithm after parsing spec Otherwise it remains -1 as initialized --- src/tools/pkcs15-init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e411baedc0..3a36d21dd1 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1793,13 +1793,14 @@ do_generate_skey(struct sc_profile *profile, const char *spec) if ((r = init_skeyargs(&skey_args)) < 0) return r; - skey_args.algorithm = algorithm; algorithm = parse_alg_spec(alg_types_sym, spec, &keybits, 0); if (algorithm < 0) { util_error("Invalid symmetric key spec: \"%s\"", spec); return SC_ERROR_INVALID_ARGUMENTS; } + + skey_args.algorithm = algorithm; skey_args.value_len = keybits; r = sc_lock(g_p15card->card); From c79a499a4082146792511d425d2fba66c211fc51 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 23 Nov 2021 14:59:45 +0100 Subject: [PATCH 2105/4321] fuzz_scconf_parse_string: Limit maximum size of input data Too long input is not necessary for parser testing. Huge test cases containing mostly opening brackets caused stack-overflow while freeing the memory of chained blocks. Test case containing a too-long list of values caused timeout. Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40676 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41434 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41450 --- src/tests/fuzzing/fuzz_scconf_parse_string.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/fuzzing/fuzz_scconf_parse_string.c b/src/tests/fuzzing/fuzz_scconf_parse_string.c index 0a0cdca57e..ee41d84618 100644 --- a/src/tests/fuzzing/fuzz_scconf_parse_string.c +++ b/src/tests/fuzzing/fuzz_scconf_parse_string.c @@ -28,10 +28,15 @@ #include #include +#define MAX_SIZE 16000 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { scconf_context *ctx = NULL; char *buf = NULL; + if (size > MAX_SIZE) + return 0; + if (!(buf = malloc(size + 1))) return 0; if (!(ctx = scconf_new(NULL))) { From 9d6ddaef13472cb7aaafc1b418937493f44bc422 Mon Sep 17 00:00:00 2001 From: Diego Koenegras Date: Tue, 30 Nov 2021 10:59:59 +0100 Subject: [PATCH 2106/4321] Added belpic v1.8 applet ATR --- src/libopensc/card-belpic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index fad4b600cc..2ce5674577 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -146,6 +146,8 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur; static size_t next_idx = (size_t)-1; static const struct sc_atr_table belpic_atrs[] = { + /* Applet V1.8 */ + { "3B:7F:96:00:00:80:31:80:65:B0:85:04:01:20:12:0F:FF:82:90:00", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, /* Applet V1.1 */ { "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, /* Applet V1.0 with new EMV-compatible ATR */ From 75dbe58b4a7857cd67925fa8a38bc81bf37d7e1a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 26 Nov 2021 14:45:08 +0100 Subject: [PATCH 2107/4321] .github: Workaround broken Github image Fixes: #2456 Related: https://github.com/actions/virtual-environments/issues/4589 --- .github/setup-linux.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 481aa07119..27d9f076e7 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -25,6 +25,12 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " fi DEPS="$DEPS ant openjdk-8-jdk maven" elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + # The Github's Ubuntu images since 20211122.1 are broken + # https://github.com/actions/virtual-environments/issues/4589 + sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 + + # Note, that this list is somehow magic and adding libwine, libwine:i386 or wine64 + # will make the following sections break without any useful logs. See GH#2458 DEPS="$DEPS wine wine32 xvfb wget" sudo dpkg --add-architecture i386 if [ "$1" == "mingw" ]; then From 33a22c8b1d2f1f6fc6f776324994faf6b25ba2af Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Nov 2021 21:13:26 +0100 Subject: [PATCH 2108/4321] Run the CI also if the CI scripts change --- .github/workflows/linux.yml | 3 +++ .github/workflows/macos.yml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 3ec0a9e044..4aecd5ee7e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,6 +6,9 @@ on: - '**.c' - '**.h' - .github/workflows/linux.yml + - .github/setup-linux.sh + - .github/build.sh + - .github/push-artifacts.sh push: jobs: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index b7762bfd0b..2a932773b8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -7,6 +7,10 @@ on: - '**.h' - '**.m' - .github/workflows/macos.yml + - .github/setup-macos.sh + - .github/cleanup-macos.sh + - .github/build.sh + - .github/push-artifacts.sh push: jobs: From 9ac92952b6dd062f95fd334d89663bd664dd8644 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Sun, 4 Apr 2021 10:46:04 +0200 Subject: [PATCH 2109/4321] OpenPGP 3.4+: Get list of supported algorithms from Algorithm Information OpenPGP Card 3.4+ supports getting list of algos from the new Algoritm Information DO https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf, 4.4.3.11 If at least one algo is in this list, use it, and ignore hardcoded. Tested on Yubikey 5 NFC with FW 5.2.4. Handled few problems with Yubikey not following the spec. Also, fixed problem with algorithm find, which will return EC algorithm with the same key size, even if curve is not the same. --- src/libopensc/card-openpgp.c | 211 ++++++++++++++++++++++------------- 1 file changed, 132 insertions(+), 79 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e72dfbe15d..6476263967 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -137,6 +137,7 @@ static pgp_blob_t *pgp_new_blob(sc_card_t *, pgp_blob_t *, unsigned int, sc_file static void pgp_free_blob(pgp_blob_t *); static int pgp_get_pubkey(sc_card_t *, unsigned int, u8 *, size_t); static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, u8 *, size_t); +static int pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob); static pgp_do_info_t pgp1x_objects[] = { /* OpenPGP card spec 1.1 */ @@ -196,7 +197,7 @@ static pgp_do_info_t pgp34_objects[] = { /**** OpenPGP card spec 3.4 ****/ { 0x00de, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, { 0x00de, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, /* DO FA is CONSTRUCTED in spec; we treat it as SIMPLE for the time being */ - { 0x00fa, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, + { 0x00fa, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, sc_get_data, NULL }, /* DO FB is CONSTRUCTED in spec; we treat it as SIMPLE for the time being */ { 0x00fb, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, /* DO FC is CONSTRUCTED in spec; we treat it as SIMPLE for the time being */ @@ -497,7 +498,9 @@ pgp_init(sc_card_t *card) } /* get card_features from ATR & DOs */ - pgp_get_card_features(card); + if (pgp_get_card_features(card)) { + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } /* if algorithm attributes can be changed, * add supported algorithms based on specification for pkcs15-init */ @@ -662,6 +665,80 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +int _pgp_handle_curve25519(sc_card_t *card, + sc_cardctl_openpgp_keygen_info_t key_info, size_t do_num) +{ + if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) + return 0; + + /* CKM_XEDDSA supports both Sign and Derive, but + * OpenPGP card supports only derivation using these + * keys as far as I know */ + _sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length, + SC_ALGORITHM_ECDH_CDH_RAW, 0, &key_info.u.ec.oid); + sc_log(card->ctx, "DO %zX: Added XEDDSA algorithm (%d), mod_len = %d", + do_num, SC_ALGORITHM_XEDDSA, key_info.u.ec.key_length); + return 1; +} + +int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, size_t do_num) +{ + unsigned long flags = 0, ext_flags = 0; + + /* RSA [RFC 4880] */ + switch (key_info.algorithm) { + case SC_OPENPGP_KEYALGO_RSA: + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / + * v3.x section 7.2.11 & 7.2.12 */ + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE | + SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ + + _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); + sc_log(card->ctx, "DO %zX: Added RSA algorithm, mod_len = %" + SC_FORMAT_LEN_SIZE_T"u", + do_num, key_info.u.rsa.modulus_len); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + case SC_OPENPGP_KEYALGO_ECDH: + /* The montgomery curve (curve25519) needs to go through + * different paths, otherwise we handle it as a normal EC key */ + if (_pgp_handle_curve25519(card, key_info, do_num)) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + /* fall through */ + case SC_OPENPGP_KEYALGO_ECDSA: + /* v3.0+: ECC [RFC 4880 & 6637] */ + /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ + + /* Allow curve to be used by both ECDH and ECDSA. + * pgp_init set these flags the same way */ + flags = SC_ALGORITHM_ECDH_CDH_RAW; + flags |= SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDSA_HASH_NONE; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; + + _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, + &key_info.u.ec.oid); + sc_log(card->ctx, "DO %zX: Added EC algorithm (%d), mod_len = %d" , + do_num, key_info.algorithm, key_info.u.ec.key_length); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + case SC_OPENPGP_KEYALGO_EDDSA: + /* Handle Yubikey bug, that in DO FA curve25519 has EDDSA algo */ + if (_pgp_handle_curve25519(card, key_info, do_num)) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, + SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid); + + sc_log(card->ctx, "DO %zX: Added EDDSA algorithm (%d), mod_len = %d" , + do_num, key_info.algorithm, key_info.u.ec.key_length); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + default: + sc_log(card->ctx, "DO %zX: Unknown algorithm ID (%d)" , + do_num, key_info.algorithm); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } +} + /** * Internal: get features of the card: capabilities, ... @@ -673,7 +750,7 @@ pgp_get_card_features(sc_card_t *card) u8 *hist_bytes = card->reader->atr_info.hist_bytes; size_t hist_bytes_len = card->reader->atr_info.hist_bytes_len; size_t i; - pgp_blob_t *blob, *blob6e, *blob73; + pgp_blob_t *blob, *blob6e, *blob73, *blobfa; LOG_FUNC_CALLED(card->ctx); @@ -797,6 +874,42 @@ pgp_get_card_features(sc_card_t *card) card->max_pin_len = blob->data[1]; } + if (priv->bcd_version >= OPENPGP_CARD_3_0) { + /* v3.0+: get length info from "extended length information" DO */ + if ((pgp_get_blob(card, blob6e, 0x7f66, &blob) >= 0) && + (blob->data != NULL) && (blob->len >= 8)) { + /* kludge: treat as SIMPLE DO and use appropriate offsets */ + card->max_send_size = bebytes2ushort(blob->data + 2); + card->max_recv_size = bebytes2ushort(blob->data + 6); + } + } + + if (priv->bcd_version >= OPENPGP_CARD_3_4) { + int handled_algos = 0; + /* Parse supported algorithms from Algorithm Information DO + * see OpenPGP card spec 3.4 section 4.4.3.11 */ + if (pgp_get_blob(card, priv->mf, 0x00fa, &blobfa) >= 0) { + pgp_blob_t *child; + pgp_enumerate_blob(card, blobfa); + /* There will be multiple childs with the same ID, but + * different algos, so we need to iterate over all of them */ + for (child = blobfa->files; child; child = child->next) { + if ((child->id < 0x00c1) || (child->id > 0x00c3)) + continue; + sc_cardctl_openpgp_keygen_info_t key_info; + if (pgp_parse_algo_attr_blob(card, child, &key_info) >= 0) { + _pgp_add_algo(card, key_info, 0x00fa); + /* Set it if we have at lest one known algo in DO FA */ + handled_algos = 1; + } + } + } + if (handled_algos) { + sc_log(card->ctx, "Algo list populated from Algorithm Information DO"); + LOG_FUNC_RETURN(card->ctx, 1); + } + } + /* get _current_ algorithms & key lengths from "algorithm attributes" DOs * * All available algorithms should be already provided by pgp_init. However, if another @@ -811,82 +924,13 @@ pgp_get_card_features(sc_card_t *card) /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (pgp_parse_algo_attr_blob(card, blob, &key_info) >= 0)) { - unsigned long flags = 0, ext_flags = 0; - - /* RSA [RFC 4880] */ - switch (key_info.algorithm) { - case SC_OPENPGP_KEYALGO_RSA: - /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / - * v3.x section 7.2.11 & 7.2.12 */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | - SC_ALGORITHM_RSA_HASH_NONE | - SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ - - _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); - sc_log(card->ctx, "DO %zX: Added RSA algorithm, mod_len = %" - SC_FORMAT_LEN_SIZE_T"u", - i, key_info.u.rsa.modulus_len); - break; - case SC_OPENPGP_KEYALGO_ECDH: - /* The montgomery curve (curve25519) needs to go through - * different paths, otherwise we handle it as a normal EC key */ - if (sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) { - /* CKM_XEDDSA supports both Sign and Derive, but - * OpenPGP card supports only derivation using these - * keys as far as I know */ - _sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_ECDH_CDH_RAW, 0, &key_info.u.ec.oid); - - sc_log(card->ctx, "DO %zX: Added XEDDSA algorithm (%d), mod_len = %d" , - i, key_info.algorithm, key_info.u.ec.key_length); - break; - } - /* fall through */ - case SC_OPENPGP_KEYALGO_ECDSA: - /* v3.0+: ECC [RFC 4880 & 6637] */ - /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ - flags = 0, ext_flags = 0; - - if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDH) - flags = SC_ALGORITHM_ECDH_CDH_RAW; - if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDSA) - flags = SC_ALGORITHM_ECDSA_RAW; - flags |= SC_ALGORITHM_ECDSA_HASH_NONE; - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - - _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, - &key_info.u.ec.oid); - sc_log(card->ctx, "DO %zX: Added EC algorithm (%d), mod_len = %d" , - i, key_info.algorithm, key_info.u.ec.key_length); - break; - case SC_OPENPGP_KEYALGO_EDDSA: - _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid); - - sc_log(card->ctx, "DO %zX: Added EDDSA algorithm (%d), mod_len = %d" , - i, key_info.algorithm, key_info.u.ec.key_length); - break; - default: - sc_log(card->ctx, "DO %zX: Unknown algorithm ID (%d)" , - i, key_info.algorithm); - break; - } + _pgp_add_algo(card, key_info, i); } } - if (priv->bcd_version >= OPENPGP_CARD_3_0) { - /* v3.0+: get length info from "extended length information" DO */ - if ((pgp_get_blob(card, blob6e, 0x7f66, &blob) >= 0) && - (blob->data != NULL) && (blob->len >= 8)) { - /* kludge: treat as SIMPLE DO and use appropriate offsets */ - card->max_send_size = bebytes2ushort(blob->data + 2); - card->max_recv_size = bebytes2ushort(blob->data + 6); - } - } } - return SC_SUCCESS; + LOG_FUNC_RETURN(card->ctx, 0); } @@ -1200,20 +1244,29 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); - if (r < 0 || data == NULL) { - sc_log(card->ctx, - "Unexpected end of contents\n"); + if (data == NULL) { + sc_log(card->ctx, "Unexpected end of contents"); return SC_ERROR_OBJECT_NOT_VALID; } - - if (data + len > blob->data + blob->len) + if (r == SC_ERROR_INVALID_ASN1_OBJECT) { + sc_log(card->ctx, "Invalid ASN.1 object"); return SC_ERROR_OBJECT_NOT_VALID; + } /* undo ASN1's split of tag & class */ for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { cla <<= 8; } tag |= cla; + /* Check for length mismatch */ + if ((r == SC_ERROR_ASN1_END_OF_CONTENTS) || + (data + len > blob->data + blob->len)) { + // Check if it is not known Yubikey 5 issue + if ((tag != blob->id) || (tag != 0xfa)) { + sc_log(card->ctx, "Unexpected end of contents"); + return SC_ERROR_OBJECT_NOT_VALID; + } + } /* Awful hack for composite DOs that have * a TLV with the DO's id encompassing the From bf4a3aaf945b62e2fa1298aec0f5c815a1630c54 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Sun, 4 Apr 2021 15:14:49 +0200 Subject: [PATCH 2110/4321] Fix find for EC algos returning wrong algo If we're finding EC algo, and curve is not matched, another algo with the same key length shoud not be returned. --- src/libopensc/card.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index f2c6ca5ae4..7b1d6f18de 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1154,16 +1154,13 @@ sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card, if (info->algorithm != algorithm) continue; - if (param) { - if (info->algorithm == SC_ALGORITHM_EC || - info->algorithm == SC_ALGORITHM_EDDSA || - info->algorithm == SC_ALGORITHM_XEDDSA) - if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id)) - return info; - } - if (info->key_length != key_length) - continue; - return info; + if (param && (info->algorithm == SC_ALGORITHM_EC || + info->algorithm == SC_ALGORITHM_EDDSA || + info->algorithm == SC_ALGORITHM_XEDDSA)) { + if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id)) + return info; + } else if (info->key_length == key_length) + return info; } return NULL; } From e11a78f9104311fc8e6df873510152fe66d37a5f Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Tue, 6 Apr 2021 18:42:02 +0200 Subject: [PATCH 2111/4321] Some changes in DO FA handling: - Now it's checked independent from DO 6E - If no algos can be parsed from DO FA, code will fallback to other ways - Indentation fixes --- src/libopensc/card-openpgp.c | 148 ++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 6476263967..c3cce0939d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -685,58 +685,61 @@ int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, si { unsigned long flags = 0, ext_flags = 0; - /* RSA [RFC 4880] */ + /* [RFC 4880], [draft-ietf-openpgp-crypto-refresh] */ switch (key_info.algorithm) { - case SC_OPENPGP_KEYALGO_RSA: - /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / - * v3.x section 7.2.11 & 7.2.12 */ - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | - SC_ALGORITHM_RSA_HASH_NONE | - SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ - - _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); - sc_log(card->ctx, "DO %zX: Added RSA algorithm, mod_len = %" - SC_FORMAT_LEN_SIZE_T"u", - do_num, key_info.u.rsa.modulus_len); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - case SC_OPENPGP_KEYALGO_ECDH: - /* The montgomery curve (curve25519) needs to go through - * different paths, otherwise we handle it as a normal EC key */ - if (_pgp_handle_curve25519(card, key_info, do_num)) - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - /* fall through */ - case SC_OPENPGP_KEYALGO_ECDSA: - /* v3.0+: ECC [RFC 4880 & 6637] */ - /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ - - /* Allow curve to be used by both ECDH and ECDSA. - * pgp_init set these flags the same way */ - flags = SC_ALGORITHM_ECDH_CDH_RAW; - flags |= SC_ALGORITHM_ECDSA_RAW; - flags |= SC_ALGORITHM_ECDSA_HASH_NONE; - flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; - ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - - _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, - &key_info.u.ec.oid); - sc_log(card->ctx, "DO %zX: Added EC algorithm (%d), mod_len = %d" , - do_num, key_info.algorithm, key_info.u.ec.key_length); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - case SC_OPENPGP_KEYALGO_EDDSA: - /* Handle Yubikey bug, that in DO FA curve25519 has EDDSA algo */ - if (_pgp_handle_curve25519(card, key_info, do_num)) - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid); + case SC_OPENPGP_KEYALGO_RSA: + /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / + * v3.x section 7.2.11 & 7.2.12 */ + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE | + SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ + + _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); + sc_log(card->ctx, "DO %zX: Added RSA algorithm, mod_len = %" + SC_FORMAT_LEN_SIZE_T"u", + do_num, key_info.u.rsa.modulus_len); + break; + case SC_OPENPGP_KEYALGO_ECDH: + /* The montgomery curve (curve25519) needs to go through + * different paths, otherwise we handle it as a normal EC key */ + if (_pgp_handle_curve25519(card, key_info, do_num)) + break; + /* fall through */ + case SC_OPENPGP_KEYALGO_ECDSA: + /* v3.0+: ECC [RFC 4880 & 6637] */ + /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ + + /* Allow curve to be used by both ECDH and ECDSA. + * pgp_init set these flags the same way */ + flags = SC_ALGORITHM_ECDH_CDH_RAW; + flags |= SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDSA_HASH_NONE; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - sc_log(card->ctx, "DO %zX: Added EDDSA algorithm (%d), mod_len = %d" , - do_num, key_info.algorithm, key_info.u.ec.key_length); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - default: - sc_log(card->ctx, "DO %zX: Unknown algorithm ID (%d)" , - do_num, key_info.algorithm); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, + &key_info.u.ec.oid); + sc_log(card->ctx, "DO %zX: Added EC algorithm (%d), mod_len = %d" , + do_num, key_info.algorithm, key_info.u.ec.key_length); + break; + case SC_OPENPGP_KEYALGO_EDDSA: + /* Handle Yubikey bug, that in DO FA curve25519 has EDDSA algo */ + if (_pgp_handle_curve25519(card, key_info, do_num)) + break; + _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, + SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid); + + sc_log(card->ctx, "DO %zX: Added EDDSA algorithm (%d), mod_len = %d" , + do_num, key_info.algorithm, key_info.u.ec.key_length); + break; + default: + sc_log(card->ctx, "DO %zX: Unknown algorithm ID (%d)" , + do_num, key_info.algorithm); + /* return "false" if we do not understand algo */ + return 0; } + /* return true */ + return 1; } @@ -751,6 +754,7 @@ pgp_get_card_features(sc_card_t *card) size_t hist_bytes_len = card->reader->atr_info.hist_bytes_len; size_t i; pgp_blob_t *blob, *blob6e, *blob73, *blobfa; + int handled_algos = 0; LOG_FUNC_CALLED(card->ctx); @@ -802,6 +806,24 @@ pgp_get_card_features(sc_card_t *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; } + if (priv->bcd_version >= OPENPGP_CARD_3_4) { + /* Parse supported algorithms from Algorithm Information DO + * see OpenPGP card spec 3.4 section 4.4.3.11 */ + if (pgp_get_blob(card, priv->mf, 0x00fa, &blobfa) >= 0) { + pgp_blob_t *child; + pgp_enumerate_blob(card, blobfa); + /* There will be multiple childs with the same ID, but + * different algos, so we need to iterate over all of them */ + for (child = blobfa->files; child; child = child->next) { + if ((child->id < 0x00c1) || (child->id > 0x00c3)) + continue; + sc_cardctl_openpgp_keygen_info_t key_info; + if (pgp_parse_algo_attr_blob(card, child, &key_info) >= 0) + handled_algos += _pgp_add_algo(card, key_info, 0x00fa); + } + } + } + /* v1.1 & v2.x: special DOs are limited to 254 bytes */ priv->max_specialDO_size = 254; @@ -884,30 +906,10 @@ pgp_get_card_features(sc_card_t *card) } } - if (priv->bcd_version >= OPENPGP_CARD_3_4) { - int handled_algos = 0; - /* Parse supported algorithms from Algorithm Information DO - * see OpenPGP card spec 3.4 section 4.4.3.11 */ - if (pgp_get_blob(card, priv->mf, 0x00fa, &blobfa) >= 0) { - pgp_blob_t *child; - pgp_enumerate_blob(card, blobfa); - /* There will be multiple childs with the same ID, but - * different algos, so we need to iterate over all of them */ - for (child = blobfa->files; child; child = child->next) { - if ((child->id < 0x00c1) || (child->id > 0x00c3)) - continue; - sc_cardctl_openpgp_keygen_info_t key_info; - if (pgp_parse_algo_attr_blob(card, child, &key_info) >= 0) { - _pgp_add_algo(card, key_info, 0x00fa); - /* Set it if we have at lest one known algo in DO FA */ - handled_algos = 1; - } - } - } - if (handled_algos) { - sc_log(card->ctx, "Algo list populated from Algorithm Information DO"); - LOG_FUNC_RETURN(card->ctx, 1); - } + /* if we found at least one usable algo, let's skip other ways to find them */ + if (handled_algos > 0) { + sc_log(card->ctx, "Algo list populated from Algorithm Information DO"); + LOG_FUNC_RETURN(card->ctx, 1); } /* get _current_ algorithms & key lengths from "algorithm attributes" DOs From 21347deb3d1f1ac6bca355211c95bc4f9697afbf Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Tue, 6 Apr 2021 18:59:05 +0200 Subject: [PATCH 2112/4321] Fix pass of handling_algos if DO 6E is not available --- src/libopensc/card-openpgp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c3cce0939d..b26e1edff1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -907,9 +907,9 @@ pgp_get_card_features(sc_card_t *card) } /* if we found at least one usable algo, let's skip other ways to find them */ - if (handled_algos > 0) { + if (handled_algos) { sc_log(card->ctx, "Algo list populated from Algorithm Information DO"); - LOG_FUNC_RETURN(card->ctx, 1); + LOG_FUNC_RETURN(card->ctx, handled_algos); } /* get _current_ algorithms & key lengths from "algorithm attributes" DOs @@ -932,7 +932,7 @@ pgp_get_card_features(sc_card_t *card) } - LOG_FUNC_RETURN(card->ctx, 0); + LOG_FUNC_RETURN(card->ctx, handled_algos); } From d4b589044946e17eaab3c0d01187fa98a0295cc8 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Wed, 7 Apr 2021 20:56:27 +0200 Subject: [PATCH 2113/4321] Fix error check in pgp_enumerate_blob --- src/libopensc/card-openpgp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b26e1edff1..937ee74fd1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1246,14 +1246,16 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), &cla, &tag, &len); - if (data == NULL) { - sc_log(card->ctx, "Unexpected end of contents"); - return SC_ERROR_OBJECT_NOT_VALID; - } if (r == SC_ERROR_INVALID_ASN1_OBJECT) { sc_log(card->ctx, "Invalid ASN.1 object"); return SC_ERROR_OBJECT_NOT_VALID; } + /* Check for unknown error, or empty data */ + if (((r < 0) && (r != SC_ERROR_ASN1_END_OF_CONTENTS)) || + (data == NULL)) { + sc_log(card->ctx, "Unexpected end of contents"); + return SC_ERROR_OBJECT_NOT_VALID; + } /* undo ASN1's split of tag & class */ for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) { From ede23473b49958af4d5a2d1a8a1eb72aaf5884a2 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Sat, 10 Apr 2021 09:15:00 +0200 Subject: [PATCH 2114/4321] Fixed returning multiple mechanisms After parsing DO FA, algorithm info could have both X25519 and older EC curves. This leads to register of two mechanisms with same type, CKM_ECDH1_DERIVE, but different key types. This could lead to a situation, that C_DeriveKey will throw an error, while user is trying to derive using X25519 key. This commit fixes this, to have a list of key types, and registering the second mechanism will just add key type to list in the existing mechanism, and updates it's mech_info. --- src/libopensc/card-openpgp.c | 4 +- src/pkcs11/mechanism.c | 96 ++++++++++++++++++++++++++++-------- src/pkcs11/openssl.c | 16 +++--- src/pkcs11/pkcs11-object.c | 2 +- src/pkcs11/sc-pkcs11.h | 14 +++--- 5 files changed, 95 insertions(+), 37 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 937ee74fd1..5ec4463756 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -707,7 +707,6 @@ int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, si /* fall through */ case SC_OPENPGP_KEYALGO_ECDSA: /* v3.0+: ECC [RFC 4880 & 6637] */ - /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ /* Allow curve to be used by both ECDH and ECDSA. * pgp_init set these flags the same way */ @@ -723,6 +722,7 @@ int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, si do_num, key_info.algorithm, key_info.u.ec.key_length); break; case SC_OPENPGP_KEYALGO_EDDSA: + /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ /* Handle Yubikey bug, that in DO FA curve25519 has EDDSA algo */ if (_pgp_handle_curve25519(card, key_info, do_num)) break; @@ -812,7 +812,7 @@ pgp_get_card_features(sc_card_t *card) if (pgp_get_blob(card, priv->mf, 0x00fa, &blobfa) >= 0) { pgp_blob_t *child; pgp_enumerate_blob(card, blobfa); - /* There will be multiple childs with the same ID, but + /* There will be multiple children with the same ID, but * different algos, so we need to iterate over all of them */ for (child = blobfa->files; child; child = child->next) { if ((child->id < 0x00c1) || (child->id > 0x00c3)) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index e41992fe36..269f9724f5 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -83,6 +83,14 @@ signature_data_buffer_append(struct signature_data *data, return CKR_OK; } +void _update_mech_info(CK_MECHANISM_INFO_PTR mech_info, CK_MECHANISM_INFO_PTR new_mech_info) { + if (new_mech_info->ulMaxKeySize > mech_info->ulMaxKeySize) + mech_info->ulMaxKeySize = new_mech_info->ulMaxKeySize; + if (new_mech_info->ulMinKeySize < mech_info->ulMinKeySize) + mech_info->ulMinKeySize = new_mech_info->ulMinKeySize; + mech_info->flags |= new_mech_info->flags; +} + /* * Register a mechanism */ @@ -90,11 +98,42 @@ CK_RV sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, sc_pkcs11_mechanism_type_t *mt) { + sc_pkcs11_mechanism_type_t *existing_mt; sc_pkcs11_mechanism_type_t **p; + int i; if (mt == NULL) return CKR_HOST_MEMORY; + if ((existing_mt = sc_pkcs11_find_mechanism(p11card, mt->mech, mt->mech_info.flags))) { + for (i = 0; i < MAX_KEY_TYPES; i++) { + if (existing_mt->key_types[i] == mt->key_types[0]) { + /* Mechanism already registered with the same key_type, + * just update it's info */ + _update_mech_info(&existing_mt->mech_info, &mt->mech_info); + free(mt); + return CKR_OK; + } + if (existing_mt->key_types[i] < 0) { + /* There is a free slot for new key type, let's add it and + * update mechanism info */ + _update_mech_info(&existing_mt->mech_info, &mt->mech_info); + /* XXX Should be changed to loop over mt->key_types, if + * we allow to register mechanism with multiple key types + * in one operation */ + existing_mt->key_types[i] = mt->key_types[0]; + if (i + 1 < MAX_KEY_TYPES) { + existing_mt->key_types[i + 1] = -1; + } + free(mt); + return CKR_OK; + } + } + sc_log(p11card->card->ctx, "Too much key types in mechanism 0x%lx, more than %d", mt->mech, MAX_KEY_TYPES); + free(mt); + return CKR_BUFFER_TOO_SMALL; + } + p = (sc_pkcs11_mechanism_type_t **) realloc(p11card->mechanisms, (p11card->nmechanisms + 2) * sizeof(*p)); if (p == NULL) @@ -105,6 +144,19 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, return CKR_OK; } + +CK_RV +_validate_key_type(sc_pkcs11_mechanism_type_t *mech, CK_KEY_TYPE key_type) { + int i; + for (i = 0; i < MAX_KEY_TYPES; i++) { + if (mech->key_types[i] < 0) + break; + if ((CK_KEY_TYPE)mech->key_types[i] == key_type) + return CKR_OK; + } + return CKR_KEY_TYPE_INCONSISTENT; +} + /* * Look up a mechanism */ @@ -280,7 +332,7 @@ sc_pkcs11_md_final(struct sc_pkcs11_session *session, */ CK_RV sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, - struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) + struct sc_pkcs11_object *key, CK_KEY_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; @@ -299,8 +351,9 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani LOG_FUNC_RETURN(context, CKR_MECHANISM_INVALID); /* See if compatible with key type */ - if (mt->key_type != key_type) - LOG_FUNC_RETURN(context, CKR_KEY_TYPE_INCONSISTENT); + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); if (pMechanism->pParameter && pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) @@ -580,7 +633,7 @@ sc_pkcs11_signature_release(sc_pkcs11_operation_t *operation) */ CK_RV sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, - struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) + struct sc_pkcs11_object *key, CK_KEY_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; @@ -597,8 +650,9 @@ sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechan return CKR_MECHANISM_INVALID; /* See if compatible with key type */ - if (mt->key_type != key_type) - return CKR_KEY_TYPE_INCONSISTENT; + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); rv = session_start_operation(session, SC_PKCS11_OPERATION_VERIFY, mt, &operation); if (rv != CKR_OK) @@ -815,7 +869,7 @@ CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, - CK_MECHANISM_TYPE key_type) + CK_KEY_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; @@ -832,8 +886,9 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session, return CKR_MECHANISM_INVALID; /* See if compatible with key type */ - if (mt->key_type != key_type) - return CKR_KEY_TYPE_INCONSISTENT; + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); rv = session_start_operation(session, SC_PKCS11_OPERATION_DECRYPT, mt, &operation); if (rv != CKR_OK) @@ -906,9 +961,9 @@ sc_pkcs11_wrap(struct sc_pkcs11_session *session, return CKR_MECHANISM_INVALID; /* See if compatible with key type */ - /* TODO: what if there are several mechanisms with different key types? Should we loop through them? */ - if (mt->key_type != key_type) - return CKR_KEY_TYPE_INCONSISTENT; + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); rv = session_start_operation(session, SC_PKCS11_OPERATION_WRAP, mt, &operation); if (rv != CKR_OK) @@ -952,9 +1007,9 @@ sc_pkcs11_unwrap(struct sc_pkcs11_session *session, return CKR_MECHANISM_INVALID; /* See if compatible with key type */ - /* TODO: what if there are several mechanisms with different key types? Should we loop through them? */ - if (mt->key_type != key_type) - return CKR_KEY_TYPE_INCONSISTENT; + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); rv = session_start_operation(session, SC_PKCS11_OPERATION_UNWRAP, mt, &operation); if (rv != CKR_OK) @@ -1014,9 +1069,9 @@ sc_pkcs11_deri(struct sc_pkcs11_session *session, return CKR_MECHANISM_INVALID; /* See if compatible with key type */ - if (mt->key_type != key_type) - return CKR_KEY_TYPE_INCONSISTENT; - + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int) rv); rv = session_start_operation(session, SC_PKCS11_OPERATION_DERIVE, mt, &operation); if (rv != CKR_OK) @@ -1192,7 +1247,8 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, return mt; mt->mech = mech; mt->mech_info = *pInfo; - mt->key_type = key_type; + mt->key_types[0] = (int)key_type; + mt->key_types[1] = -1; mt->mech_data = priv_data; mt->free_mech_data = free_priv_data; mt->obj_size = sizeof(sc_pkcs11_operation_t); @@ -1275,7 +1331,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; - new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_type, info, free_info); + new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_types[0], info, free_info); if (!new_type) { free_info(info); return CKR_HOST_MEMORY; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index bc4aed1e4c..adcf880d29 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -53,7 +53,7 @@ static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *); static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { CKM_SHA_1, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -72,7 +72,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { CKM_SHA224, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -91,7 +91,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { CKM_SHA256, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -110,7 +110,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { CKM_SHA384, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -129,7 +129,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { CKM_SHA512, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -148,7 +148,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { CKM_GOSTR3411, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -167,7 +167,7 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { static sc_pkcs11_mechanism_type_t openssl_md5_mech = { CKM_MD5, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, @@ -186,7 +186,7 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = { static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { CKM_RIPEMD160, { 0, 0, CKF_DIGEST }, - 0, + { -1 }, sizeof(struct sc_pkcs11_operation), sc_pkcs11_openssl_md_release, sc_pkcs11_openssl_md_init, diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index a3ed9964de..3f7eb1b395 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -31,7 +31,7 @@ static void sc_find_release(sc_pkcs11_operation_t *operation); static sc_pkcs11_mechanism_type_t find_mechanism = { 0, /* mech */ {0,0,0}, /* mech_info */ - 0, /* key_type */ + { -1 }, /* key_types */ sizeof(struct sc_pkcs11_find_operation), /* obj_size */ sc_find_release, /* release */ NULL, /* md_init */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 815deffe1a..32520741d1 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -264,11 +264,13 @@ enum { SC_PKCS11_OPERATION_MAX }; +#define MAX_KEY_TYPES 2 + /* This describes a PKCS11 mechanism */ struct sc_pkcs11_mechanism_type { - CK_MECHANISM_TYPE mech; /* algorithm: md5, sha1, ... */ - CK_MECHANISM_INFO mech_info; /* mechanism info */ - CK_MECHANISM_TYPE key_type; /* for sign/decipher ops */ + CK_MECHANISM_TYPE mech; /* algorithm: md5, sha1, ... */ + CK_MECHANISM_INFO mech_info; /* mechanism info */ + int key_types[MAX_KEY_TYPES]; /* for sign/decipher ops */ unsigned int obj_size; /* General management */ @@ -440,17 +442,17 @@ CK_RV sc_pkcs11_md_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR); CK_RV sc_pkcs11_md_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); CK_RV sc_pkcs11_md_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_sign_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, - struct sc_pkcs11_object *, CK_MECHANISM_TYPE); + struct sc_pkcs11_object *, CK_KEY_TYPE); CK_RV sc_pkcs11_sign_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); CK_RV sc_pkcs11_sign_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_sign_size(struct sc_pkcs11_session *, CK_ULONG_PTR); #ifdef ENABLE_OPENSSL CK_RV sc_pkcs11_verif_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, - struct sc_pkcs11_object *, CK_MECHANISM_TYPE); + struct sc_pkcs11_object *, CK_KEY_TYPE); CK_RV sc_pkcs11_verif_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); #endif -CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE); +CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE); CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_wrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *); From 2cc7b10b80081171854cbf9183e012a0c1a1a5e3 Mon Sep 17 00:00:00 2001 From: Yaroslav Isakov Date: Fri, 3 Dec 2021 20:37:34 +0100 Subject: [PATCH 2115/4321] Fix comments from review --- src/pkcs11/mechanism.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 269f9724f5..2dbe945fb3 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -120,7 +120,7 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, _update_mech_info(&existing_mt->mech_info, &mt->mech_info); /* XXX Should be changed to loop over mt->key_types, if * we allow to register mechanism with multiple key types - * in one operation */ + * in one operation */ existing_mt->key_types[i] = mt->key_types[0]; if (i + 1 < MAX_KEY_TYPES) { existing_mt->key_types[i + 1] = -1; @@ -129,7 +129,7 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, return CKR_OK; } } - sc_log(p11card->card->ctx, "Too much key types in mechanism 0x%lx, more than %d", mt->mech, MAX_KEY_TYPES); + sc_log(p11card->card->ctx, "Too many key types in mechanism 0x%lx, more than %d", mt->mech, MAX_KEY_TYPES); free(mt); return CKR_BUFFER_TOO_SMALL; } From f6a29ba6477d35b55ec0d274c543cf233838de3c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 7 Dec 2021 22:30:40 +0100 Subject: [PATCH 2116/4321] pkcs11-register: Skip Firefox on Windows and macOS Firefox added integration of OS specific client certificates in version [72](https://www.mozilla.org/en-US/firefox/72.0/releasenotes/)/[75](https://www.mozilla.org/en-US/firefox/75.0/releasenotes/). This feature [was enabled by default](https://blog.mozilla.org/security/2021/07/28/making-client-certificates-available-by-default-in-firefox-90/) in version [90](https://www.mozilla.org/en-US/firefox/90.0/releasenotes/). Since pkcs11-register is executed by default on Windows/macOS startup it may be possible to see an OpenSC token twice in Firefox, i.e. via registering onepin-opensc-pkcs11 and via minidriver/CTK through osclientcerts. We now change the default behavior to avoid such conflicts. Closes https://github.com/OpenSC/OpenSC/issues/2446 --- configure.ac | 13 +++++++++++++ src/tools/Makefile.am | 1 + src/tools/pkcs11-register.ggo.in | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ca149aa9f4..d113cb43ec 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,19 @@ case "${host}" in ;; esac +dnl with Firefox's osclientcerts.so we skip registering our PKCS#11 module on Windows and macOS by default +case "${host}" in + *-*-darwin*) + PKCS11_REGISTER_SKIP_FIREFOX="on" + ;; + *-mingw*|*-winnt*|*-cygwin*) + PKCS11_REGISTER_SKIP_FIREFOX="on" + ;; + *) + PKCS11_REGISTER_SKIP_FIREFOX="off" + ;; +esac + AX_CODE_COVERAGE() AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"]) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b7aade285d..2aef4572ba 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -17,6 +17,7 @@ do_subst = $(SED) \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ -e 's,[@]PACKAGE_VERSION[@],"$(PACKAGE_VERSION)",g' \ -e 's,[@]DEFAULT_PKCS11_PROVIDER[@],"$(DEFAULT_PKCS11_PROVIDER)",g' \ + -e 's,[@]PKCS11_REGISTER_SKIP_FIREFOX[@],$(PKCS11_REGISTER_SKIP_FIREFOX),g' \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' diff --git a/src/tools/pkcs11-register.ggo.in b/src/tools/pkcs11-register.ggo.in index 30c771bc77..7d463536cb 100644 --- a/src/tools/pkcs11-register.ggo.in +++ b/src/tools/pkcs11-register.ggo.in @@ -12,7 +12,7 @@ option "skip-chrome" - option "skip-firefox" - "Don't install module to Firefox" - flag off + flag @PKCS11_REGISTER_SKIP_FIREFOX@ option "skip-thunderbird" - "Don't install module to Thunderbird" From f33a53d05f8b5a1680047be2a7278387337fd5b6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 11 Dec 2021 23:28:44 +0100 Subject: [PATCH 2117/4321] starcos: added one more ATR of eGK fixes https://github.com/OpenSC/OpenSC/issues/2460 --- src/libopensc/card-starcos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 22ca49ba01..f2c471e73a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -44,6 +44,7 @@ static const struct sc_atr_table starcos_atrs[] = { { "3B:DF:96:FF:81:31:FE:45:80:5B:44:45:2E:42:4E:4F:54:4B:31:30:30:81:05:A0", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:E0:81:05:22", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:D0:97:FF:81:B1:FE:45:1F:07:2B", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, + { "3B:D0:96:FF:81:B1:FE:45:1F:07:2A", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, { "3b:df:96:ff:81:31:fe:45:80:5b:44:45:2e:42:41:5f:53:43:33:35:32:81:05:b5", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; From 846ee3736c2d699d2119c0871d240b8af77bf1db Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 13 Dec 2021 11:05:55 +0100 Subject: [PATCH 2118/4321] Add support for SHA3* in pkcs11-tool. --- src/pkcs11/pkcs11.h | 20 +++++++ src/tools/pkcs11-tool.c | 115 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 85aa98e0e4..54055e2b20 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -552,6 +552,14 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_SHA512_RSA_PKCS_PSS (0x45UL) #define CKM_SHA224_RSA_PKCS (0x46UL) #define CKM_SHA224_RSA_PKCS_PSS (0x47UL) +#define CKM_SHA3_256_RSA_PKCS (0x60UL) +#define CKM_SHA3_384_RSA_PKCS (0x61UL) +#define CKM_SHA3_512_RSA_PKCS (0x62UL) +#define CKM_SHA3_256_RSA_PKCS_PSS (0x63UL) +#define CKM_SHA3_384_RSA_PKCS_PSS (0x64UL) +#define CKM_SHA3_512_RSA_PKCS_PSS (0x65UL) +#define CKM_SHA3_224_RSA_PKCS (0x66UL) +#define CKM_SHA3_224_RSA_PKCS_PSS (0x67UL) #define CKM_RC2_KEY_GEN (0x100UL) #define CKM_RC2_ECB (0x101UL) #define CKM_RC2_CBC (0x102UL) @@ -610,15 +618,19 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_SHA3_256 (0x2B0UL) #define CKM_SHA3_256_HMAC (0x2B1UL) #define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL) +#define CKM_SHA3_256_KEY_GEN (0x2B3UL) #define CKM_SHA3_224 (0x2B5UL) #define CKM_SHA3_224_HMAC (0x2B6UL) #define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL) +#define CKM_SHA3_224_KEY_GEN (0x2B8UL) #define CKM_SHA3_384 (0x2C0UL) #define CKM_SHA3_384_HMAC (0x2C1UL) #define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL) +#define CKM_SHA3_384_KEY_GEN (0x2C3UL) #define CKM_SHA3_512 (0x2D0UL) #define CKM_SHA3_512_HMAC (0x2D1UL) #define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL) +#define CKM_SHA3_512_KEY_GEN (0x2D3UL) #define CKM_CAST_KEY_GEN (0x300UL) #define CKM_CAST_ECB (0x301UL) #define CKM_CAST_CBC (0x302UL) @@ -721,6 +733,10 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_ECDSA_SHA256 (0x1044UL) #define CKM_ECDSA_SHA384 (0x1045UL) #define CKM_ECDSA_SHA512 (0x1046UL) +#define CKM_ECDSA_SHA3_224 (0x1047UL) +#define CKM_ECDSA_SHA3_256 (0x1048UL) +#define CKM_ECDSA_SHA3_384 (0x1049UL) +#define CKM_ECDSA_SHA3_512 (0x104AUL) #define CKM_ECDH1_DERIVE (0x1050UL) #define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) #define CKM_ECMQV_DERIVE (0x1052UL) @@ -878,6 +894,10 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS { #define CKG_MGF1_SHA256 (0x00000002UL) #define CKG_MGF1_SHA384 (0x00000003UL) #define CKG_MGF1_SHA512 (0x00000004UL) +#define CKG_MGF1_SHA3_224 (0x00000006UL) +#define CKG_MGF1_SHA3_256 (0x00000007UL) +#define CKG_MGF1_SHA3_384 (0x00000008UL) +#define CKG_MGF1_SHA3_512 (0x00000009UL) #define CKZ_DATA_SPECIFIED (0x00000001UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0cb1e700fa..6ac7d03179 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2045,15 +2045,19 @@ static unsigned long hash_length(const int hash) { sLen = 20; break; case CKM_SHA224: + case CKM_SHA3_224: sLen = 28; break; case CKM_SHA256: + case CKM_SHA3_256: sLen = 32; break; case CKM_SHA384: + case CKM_SHA3_384: sLen = 48; break; case CKM_SHA512: + case CKM_SHA3_512: sLen = 64; break; default: @@ -2097,6 +2101,18 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, case CKM_SHA512: pss_params->mgf = CKG_MGF1_SHA512; break; + case CKM_SHA3_224: + pss_params->mgf = CKG_MGF1_SHA3_224; + break; + case CKM_SHA3_256: + pss_params->mgf = CKG_MGF1_SHA3_256; + break; + case CKM_SHA3_384: + pss_params->mgf = CKG_MGF1_SHA3_384; + break; + case CKM_SHA3_512: + pss_params->mgf = CKG_MGF1_SHA3_512; + break; default: /* the PSS should use SHA-1 if not specified */ pss_params->hashAlg = CKM_SHA_1; @@ -2131,6 +2147,26 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, pss_params->mgf = CKG_MGF1_SHA512; break; + case CKM_SHA3_224_RSA_PKCS_PSS: + pss_params->hashAlg = CKM_SHA3_224; + pss_params->mgf = CKG_MGF1_SHA3_224; + break; + + case CKM_SHA3_256_RSA_PKCS_PSS: + pss_params->hashAlg = CKM_SHA3_256; + pss_params->mgf = CKG_MGF1_SHA3_256; + break; + + case CKM_SHA3_384_RSA_PKCS_PSS: + pss_params->hashAlg = CKM_SHA3_384; + pss_params->mgf = CKG_MGF1_SHA3_384; + break; + + case CKM_SHA3_512_RSA_PKCS_PSS: + pss_params->hashAlg = CKM_SHA3_512; + pss_params->mgf = CKG_MGF1_SHA3_512; + break; + default: /* The non-RSA-PSS algorithms do not need any parameters */ return 0; } @@ -2254,8 +2290,10 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || - opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || - opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { + opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || + opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224 || + opt_mechanism == CKM_ECDSA_SHA3_224 || opt_mechanism == CKM_ECDSA_SHA3_256 || + opt_mechanism == CKM_ECDSA_SHA3_384 || opt_mechanism == CKM_ECDSA_SHA3_512) { if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { unsigned char *seq; @@ -2314,7 +2352,9 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || - opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { + opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224 || + opt_mechanism == CKM_ECDSA_SHA3_224 || opt_mechanism == CKM_ECDSA_SHA3_256 || + opt_mechanism == CKM_ECDSA_SHA3_384 || opt_mechanism == CKM_ECDSA_SHA3_512) { if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { @@ -2442,6 +2482,18 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, case CKM_SHA224: oaep_params.mgf = CKG_MGF1_SHA224; break; + case CKM_SHA3_224: + oaep_params.mgf = CKG_MGF1_SHA3_224; + break; + case CKM_SHA3_256: + oaep_params.mgf = CKG_MGF1_SHA3_256; + break; + case CKM_SHA3_384: + oaep_params.mgf = CKG_MGF1_SHA3_384; + break; + case CKM_SHA3_512: + oaep_params.mgf = CKG_MGF1_SHA3_512; + break; default: oaep_params.hashAlg = CKM_SHA256; /* fall through */ @@ -6517,6 +6569,18 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, case CKM_SHA512: mgf = CKG_MGF1_SHA512; break; + case CKM_SHA3_224: + mgf = CKG_MGF1_SHA3_224; + break; + case CKM_SHA3_256: + mgf = CKG_MGF1_SHA3_256; + break; + case CKM_SHA3_384: + mgf = CKG_MGF1_SHA3_384; + break; + case CKM_SHA3_512: + mgf = CKG_MGF1_SHA3_512; + break; } if (opt_mgf != 0) { mgf = opt_mgf; @@ -6595,6 +6659,18 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, case CKM_SHA512: md = EVP_sha512(); break; + case CKM_SHA3_224: + md = EVP_sha3_224(); + break; + case CKM_SHA3_256: + md = EVP_sha3_256(); + break; + case CKM_SHA3_384: + md = EVP_sha3_384(); + break; + case CKM_SHA3_512: + md = EVP_sha3_512(); + break; } if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { EVP_PKEY_CTX_free(ctx); @@ -6622,6 +6698,18 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, case CKG_MGF1_SHA512: md = EVP_sha512(); break; + case CKG_MGF1_SHA3_224: + md = EVP_sha3_224(); + break; + case CKG_MGF1_SHA3_256: + md = EVP_sha3_256(); + break; + case CKG_MGF1_SHA3_384: + md = EVP_sha3_384(); + break; + case CKG_MGF1_SHA3_512: + md = EVP_sha3_512(); + break; } if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) <= 0) { EVP_PKEY_CTX_free(ctx); @@ -7497,6 +7585,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256", MF_UNKNOWN }, { CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384", MF_UNKNOWN }, { CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512", MF_UNKNOWN }, + { CKM_SHA3_224_RSA_PKCS, "SHA3-224-RSA-PKCS", "rsa-sha3-224", MF_UNKNOWN }, + { CKM_SHA3_256_RSA_PKCS, "SHA3-256-RSA-PKCS", "rsa-sha3-256", MF_UNKNOWN }, + { CKM_SHA3_384_RSA_PKCS, "SHA3-384-RSA-PKCS", "rsa-sha3-384", MF_UNKNOWN }, + { CKM_SHA3_512_RSA_PKCS, "SHA3-512-RSA-PKCS", "rsa-sha3-512", MF_UNKNOWN }, { CKM_RIPEMD128_RSA_PKCS, "RIPEMD128-RSA-PKCS", NULL, MF_UNKNOWN }, { CKM_RIPEMD160_RSA_PKCS, "RIPEMD160-RSA-PKCS", "rsa-ripemd160", MF_UNKNOWN }, { CKM_RSA_PKCS_OAEP, "RSA-PKCS-OAEP", NULL, MF_UNKNOWN }, @@ -7509,6 +7601,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256", MF_UNKNOWN }, { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384", MF_UNKNOWN }, { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512", MF_UNKNOWN }, + { CKM_SHA3_224_RSA_PKCS_PSS,"SHA3-224-RSA-PKCS-PSS", "rsa-pss-sha3-224", MF_UNKNOWN }, + { CKM_SHA3_256_RSA_PKCS_PSS,"SHA3-256-RSA-PKCS-PSS", "rsa-pss-sha3-256", MF_UNKNOWN }, + { CKM_SHA3_384_RSA_PKCS_PSS,"SHA3-384-RSA-PKCS-PSS", "rsa-pss-sha3-384", MF_UNKNOWN }, + { CKM_SHA3_512_RSA_PKCS_PSS,"SHA3-512-RSA-PKCS-PSS", "rsa-pss-sha3-512", MF_UNKNOWN }, { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL, MF_UNKNOWN }, { CKM_DSA, "DSA", NULL, MF_UNKNOWN }, { CKM_DSA_SHA1, "DSA-SHA1", NULL, MF_UNKNOWN }, @@ -7567,6 +7663,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA384_HMAC, "SHA384-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA512, "SHA512", NULL, MF_UNKNOWN }, { CKM_SHA512_HMAC, "SHA512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_SHA3_224, "SHA3-224", NULL, MF_UNKNOWN }, + { CKM_SHA3_256, "SHA3-256", NULL, MF_UNKNOWN }, + { CKM_SHA3_384, "SHA3-384", NULL, MF_UNKNOWN }, + { CKM_SHA3_512, "SHA3-512", NULL, MF_UNKNOWN }, { CKM_RIPEMD128, "RIPEMD128", NULL, MF_UNKNOWN }, { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL, MF_UNKNOWN }, { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL, MF_UNKNOWN }, @@ -7666,6 +7766,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_ECDSA_SHA256, "ECDSA-SHA256", NULL, MF_UNKNOWN }, { CKM_ECDSA_SHA384, "ECDSA-SHA384", NULL, MF_UNKNOWN }, { CKM_ECDSA_SHA512, "ECDSA-SHA512", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA3_224, "ECDSA-SHA3-224", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA3_256, "ECDSA-SHA3-256", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA3_384, "ECDSA-SHA3-384", NULL, MF_UNKNOWN }, + { CKM_ECDSA_SHA3_512, "ECDSA-SHA3-512", NULL, MF_UNKNOWN }, { CKM_ECDH1_DERIVE, "ECDH1-DERIVE", NULL, MF_UNKNOWN }, { CKM_ECDH1_COFACTOR_DERIVE,"ECDH1-COFACTOR-DERIVE", NULL, MF_UNKNOWN }, { CKM_ECMQV_DERIVE, "ECMQV-DERIVE", NULL, MF_UNKNOWN }, @@ -7728,6 +7832,11 @@ static struct mech_info p11_mgf[] = { { CKG_MGF1_SHA256, "MGF1-SHA256", NULL, MF_MGF }, { CKG_MGF1_SHA384, "MGF1-SHA384", NULL, MF_MGF }, { CKG_MGF1_SHA512, "MGF1-SHA512", NULL, MF_MGF }, + { CKG_MGF1_SHA3_224, "MGF1-SHA3_224", NULL, MF_MGF }, + { CKG_MGF1_SHA3_256, "MGF1-SHA3_256", NULL, MF_MGF }, + { CKG_MGF1_SHA3_384, "MGF1-SHA3_384", NULL, MF_MGF }, + { CKG_MGF1_SHA3_512, "MGF1-SHA3_512", NULL, MF_MGF }, + { 0, NULL, NULL, MF_UNKNOWN } }; From 2364980534750e3a946b43cbd6d55063c014f3fb Mon Sep 17 00:00:00 2001 From: Frida Flodin Date: Wed, 6 Oct 2021 09:05:48 +0000 Subject: [PATCH 2119/4321] Fix detect_card_presence return value In opensc.h the documentation states that the function detect_card_presence should return 0 if no card is present, which is reasonable. This was not the case before since more flags could be set even if SC_READER_CARD_PRESENT is not. This was probably missed before since more flags has been added since this function was first written. Signed-off-by: Frida Flodin --- src/libopensc/reader-pcsc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 99887852d7..54d8cf30c7 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -476,7 +476,12 @@ static int pcsc_detect_card_presence(sc_reader_t *reader) rv = refresh_attributes(reader); if (rv != SC_SUCCESS) LOG_FUNC_RETURN(reader->ctx, rv); - LOG_FUNC_RETURN(reader->ctx, reader->flags); + + // Return 0 if the card is not present + if (reader->flags & SC_READER_CARD_PRESENT) + LOG_FUNC_RETURN(reader->ctx, reader->flags); + else + LOG_FUNC_RETURN(reader->ctx, 0); } static int check_forced_protocol(sc_reader_t *reader, DWORD *protocol) From 348552e03508895ac483a4e1497b350b9822e0dd Mon Sep 17 00:00:00 2001 From: Frida Flodin Date: Wed, 6 Oct 2021 09:05:52 +0000 Subject: [PATCH 2120/4321] Handle when reader is detached on macOS refresh_attributes returns SC_SUCCESS if we can't detect the reader. The same should happen if the reader is unknown/detached. This was found when detaching reader on macOS. Then we don't get SCARD_E_UNKNOWN_READER from SCardGetStatusChange. We notice it later from that the state of the reader is SCARD_STATE_UNKNOWN. This resulted in C_WaitForSlotEvent not noticing that the reader, and thus the card, was removed. Signed-off-by: Frida Flodin --- src/libopensc/reader-pcsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 54d8cf30c7..40f994a514 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -415,7 +415,8 @@ static int refresh_attributes(sc_reader_t *reader) * XXX: We'll hit it again, as no readers are removed currently. */ reader->flags &= ~(SC_READER_CARD_PRESENT); - return SC_ERROR_READER_DETACHED; + sc_log(reader->ctx, "Reader unknown: %s", sc_strerror(SC_ERROR_READER_DETACHED)); + SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } reader->flags &= ~(SC_READER_CARD_CHANGED|SC_READER_CARD_INUSE|SC_READER_CARD_EXCLUSIVE); From 738588fd2b1c69794ba9ebe7bdb898486e001ecb Mon Sep 17 00:00:00 2001 From: Frida Flodin Date: Wed, 6 Oct 2021 09:05:56 +0000 Subject: [PATCH 2121/4321] Fix incorrect use of SC_READER_CARD_CHANGED Looking in opensc.h the flag SC_READER_CARD_CHANGED should be set if the card was exchanged. In other words if a card is present but it is not the same card as before. It looks like SC_READER_CARD_CHANGED was misinterpreted as a flag for when the card was removed and thus that the status has changed. Signed-off-by: Frida Flodin --- src/libopensc/reader-pcsc.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 40f994a514..664042a199 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -393,10 +393,7 @@ static int refresh_attributes(sc_reader_t *reader) || rv == (LONG)SCARD_E_NO_READERS_AVAILABLE #endif || rv == (LONG)SCARD_E_SERVICE_STOPPED) { - if (old_flags & SC_READER_CARD_PRESENT) { - reader->flags |= SC_READER_CARD_CHANGED; - } - + reader->flags &= ~(SC_READER_CARD_PRESENT); SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } @@ -459,8 +456,6 @@ static int refresh_attributes(sc_reader_t *reader) } } else { reader->flags &= ~SC_READER_CARD_PRESENT; - if (old_flags & SC_READER_CARD_PRESENT) - reader->flags |= SC_READER_CARD_CHANGED; } sc_log(reader->ctx, "card %s%s", reader->flags & SC_READER_CARD_PRESENT ? "present" : "absent", From 2630de7d6c0648dc4c91abef0adf61926534515d Mon Sep 17 00:00:00 2001 From: Frida Flodin Date: Wed, 6 Oct 2021 09:05:59 +0000 Subject: [PATCH 2122/4321] Sanity check detect_card_presence return value The return value from detect_card_presence should be 0 if no card is present. Therefore the flag SC_READER_CARD_PRESENT is not allowed to be 0 if detect_card_presence has non-zero return value. Signed-off-by: Frida Flodin --- src/libopensc/sc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 29f6b86895..40b9646fe2 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -337,6 +337,12 @@ int sc_detect_card_presence(sc_reader_t *reader) LOG_FUNC_RETURN(reader->ctx, SC_ERROR_NOT_SUPPORTED); r = reader->ops->detect_card_presence(reader); + + // Check that we get sane return value from backend + // detect_card_presence should return 0 if no card is present. + if (r && !(r & SC_READER_CARD_PRESENT)) + LOG_FUNC_RETURN(reader->ctx, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(reader->ctx, r); } From 8799851917c5a571b708a4f7ad9122e0cd655181 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 5 Oct 2021 09:56:55 +0200 Subject: [PATCH 2123/4321] doc: Fix formatting of pkcs15-init manpage --- doc/tools/pkcs15-init.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 91b3b29e06..37d6a41839 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -133,7 +133,7 @@ You can do this using: - pkcs15-init --generate-key " keyspec " --auth-id " nn + pkcs15-init --generate-key "keyspec" --auth-id "nn" where keyspec describes the algorithm and the parameters From 1608cc0ff74bc51c93acb524affaf46d35907760 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Oct 2021 09:31:56 +0200 Subject: [PATCH 2124/4321] p11test: Avoid reallocation with every object --- src/tests/p11test/p11test_case_common.c | 18 ++++++++++++++---- src/tests/p11test/p11test_case_common.h | 3 +++ src/tests/p11test/p11test_case_ec_derive.c | 5 ++--- src/tests/p11test/p11test_case_ec_sign.c | 7 +++---- src/tests/p11test/p11test_case_multipart.c | 3 +-- src/tests/p11test/p11test_case_pss_oaep.c | 4 ++-- src/tests/p11test/p11test_case_readonly.c | 3 +-- src/tests/p11test/p11test_case_usage.c | 5 ++--- 8 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index c0ab4a4cec..a6635ed237 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -25,6 +25,13 @@ char name_buffer[11]; char flag_buffer[11]; +void test_certs_init(test_certs_t *objects) +{ + objects->alloc_count = 0; + objects->count = 0; + objects->data = NULL; +} + /** * If the object enforces re-authentication, do it now. */ @@ -51,10 +58,13 @@ test_cert_t * add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) { test_cert_t *o = NULL; - objects->count = objects->count+1; - objects->data = realloc(objects->data, objects->count * sizeof(test_cert_t)); - if (objects->data == NULL) - return NULL; + objects->count = objects->count + 1; + if (objects->count > objects->alloc_count) { + objects->alloc_count += 8; + objects->data = realloc(objects->data, objects->alloc_count * sizeof(test_cert_t)); + if (objects->data == NULL) + return NULL; + } o = &(objects->data[objects->count - 1]); o->private_handle = CK_INVALID_HANDLE; diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 6d083b2243..bd0240bd4c 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -58,10 +58,13 @@ typedef struct { } test_cert_t; typedef struct { + unsigned int alloc_count; unsigned int count; test_cert_t *data; } test_certs_t; +void test_certs_init(test_certs_t *objects); + void always_authenticate(test_cert_t *o, token_info_t *info); int search_objects(test_certs_t *objects, token_info_t *info, diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 4a5c85431e..6368828e5f 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -321,10 +321,9 @@ void derive_tests(void **state) { int j; int errors = 0; token_info_t *info = (token_info_t *) *state; - test_certs_t objects; - objects.count = 0; - objects.data = NULL; + + test_certs_init(&objects); P11TEST_START(info); search_for_all_objects(&objects, info); diff --git a/src/tests/p11test/p11test_case_ec_sign.c b/src/tests/p11test/p11test_case_ec_sign.c index d27e6c6eec..86b62d6487 100644 --- a/src/tests/p11test/p11test_case_ec_sign.c +++ b/src/tests/p11test/p11test_case_ec_sign.c @@ -24,6 +24,9 @@ void ec_sign_size_test(void **state) { unsigned int i; int min, max, inc, j, l, errors = 0, rv; token_info_t *info = (token_info_t *) *state; + test_certs_t objects; + + test_certs_init(&objects); P11TEST_START(info); if (token.num_ec_mechs == 0 && token.num_ed_mechs == 0) { @@ -31,10 +34,6 @@ void ec_sign_size_test(void **state) { P11TEST_SKIP(info); } - test_certs_t objects; - objects.count = 0; - objects.data = NULL; - search_for_all_objects(&objects, info); debug_print("\nCheck functionality of Sign&Verify on different data lengths"); diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index 38f1053b9c..cee051cf36 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -28,8 +28,7 @@ void multipart_tests(void **state) { int used, j; test_certs_t objects; - objects.count = 0; - objects.data = NULL; + test_certs_init(&objects); P11TEST_START(info); search_for_all_objects(&objects, info); diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 5a6ae9d019..b80047afd6 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -757,6 +757,8 @@ void pss_oaep_test(void **state) { int used, j; test_certs_t objects; + test_certs_init(&objects); + P11TEST_START(info); if (have_pss_oaep_mechanisms() == 0) { @@ -764,8 +766,6 @@ void pss_oaep_test(void **state) { skip(); } - objects.count = 0; - objects.data = NULL; search_for_all_objects(&objects, info); debug_print("\nCheck functionality of Sign&Verify and/or Encrypt&Decrypt"); diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index f0a6fe1c7e..3f41f2f190 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -642,8 +642,7 @@ void readonly_tests(void **state) { int used, j; test_certs_t objects; - objects.count = 0; - objects.data = NULL; + test_certs_init(&objects); search_for_all_objects(&objects, info); diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index 4441027973..8617c973e2 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -24,10 +24,9 @@ void usage_test(void **state) { unsigned int i; int errors = 0; token_info_t *info = (token_info_t *) *state; - test_certs_t objects; - objects.count = 0; - objects.data = NULL; + + test_certs_init(&objects); P11TEST_START(info); search_for_all_objects(&objects, info); From 9ab268abe3164d0d37b224986b352bdeb57239e7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Oct 2021 09:38:22 +0200 Subject: [PATCH 2125/4321] p11test: Simplify objects handling in reports --- src/tests/p11test/p11test_case_ec_derive.c | 2 +- src/tests/p11test/p11test_case_multipart.c | 30 ++++----- src/tests/p11test/p11test_case_readonly.c | 11 +++- src/tests/p11test/p11test_case_usage.c | 72 +++++++++++----------- 4 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 6368828e5f..3fab5397d7 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -397,7 +397,7 @@ void derive_tests(void **state) { mech->result_flags & FLAGS_DERIVE ? "[./]" : " "); if ((mech->result_flags & FLAGS_DERIVE) == 0) continue; /* skip empty rows for export */ - P11TEST_DATA_ROW(info, 4, + P11TEST_DATA_ROW(info, 3, 's', o->id_str, 's', get_mechanism_name(mech->mech), 's', mech->result_flags & FLAGS_DERIVE ? "YES" : ""); diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index cee051cf36..fcf1947530 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -72,24 +72,24 @@ void multipart_tests(void **state) { 's', "MECHANISM", 's', "MULTIPART SIGN&VERIFY WORKS"); for (i = 0; i < objects.count; i++) { - if (objects.data[i].type == EVP_PK_EC) + test_cert_t *o = &objects.data[i]; + + if (o->key_type != CKK_RSA) continue; + printf("[%-6s] [%s] [%6lu] [ %s ] [%s%s] [%s]\n", - objects.data[i].id_str, - (objects.data[i].key_type == CKK_RSA ? "RSA " : - objects.data[i].key_type == CKK_EC ? " EC " : - objects.data[i].key_type == CKK_EC_EDWARDS ? "EC_E" : - objects.data[i].key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), - objects.data[i].bits, - objects.data[i].verify_public == 1 ? " ./ " : " ", - objects.data[i].sign ? "[./] " : "[ ] ", - objects.data[i].verify ? " [./] " : " [ ] ", - objects.data[i].label); - if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + o->id_str, + "RSA ", + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->label); + if (o->private_handle == CK_INVALID_HANDLE) { continue; } - for (j = 0; j < objects.data[i].num_mechs; j++) { - test_mech_t *mech = &objects.data[i].mechs[j]; + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; if ((mech->usage_flags & CKF_SIGN) == 0) { /* not applicable mechanisms are skipped */ continue; @@ -100,7 +100,7 @@ void multipart_tests(void **state) { if ((mech->result_flags & FLAGS_SIGN_ANY) == 0) continue; /* do not export unknown and non-working algorithms */ P11TEST_DATA_ROW(info, 3, - 's', objects.data[i].id_str, + 's', o->id_str, 's', get_mechanism_name(mech->mech), 's', mech->result_flags & FLAGS_SIGN_ANY ? "YES" : ""); } diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 3f41f2f190..75a744522d 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -690,6 +690,13 @@ void readonly_tests(void **state) { 's', "ENCRYPT&DECRYPT WORKS"); for (i = 0; i < objects.count; i++) { test_cert_t *o = &objects.data[i]; + + if (o->key_type != CKK_RSA && + o->key_type != CKK_EC && + o->key_type != CKK_EC_EDWARDS && + o->key_type != CKK_EC_MONTGOMERY) + continue; + printf("\n[%-6s] [%s]\n", o->id_str, o->label); @@ -712,12 +719,12 @@ void readonly_tests(void **state) { printf(" no usable attributes found ... ignored\n"); continue; } - if (objects.data[i].private_handle == CK_INVALID_HANDLE) { + if (o->private_handle == CK_INVALID_HANDLE) { continue; } for (j = 0; j < o->num_mechs; j++) { test_mech_t *mech = &o->mechs[j]; - if ((mech->usage_flags & CKF_SIGN) == 0) { + if ((mech->usage_flags & (CKF_SIGN|CKF_DECRYPT)) == 0) { /* not applicable mechanisms are skipped */ continue; } diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index 8617c973e2..9fbfb13341 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -89,48 +89,50 @@ void usage_test(void **state) { 's', "DERIVE PRIVATE", 's', "ALWAYS AUTH"); for (i = 0; i < objects.count; i++) { - printf("\n[%-6s] [%s]\n", - objects.data[i].id_str, - objects.data[i].label); + test_cert_t *o = &objects.data[i]; + + printf("\n[%-6s] [%s]\n", o->id_str, o->label); /* Ignore if there is missing private key */ if (objects.data[i].private_handle == CK_INVALID_HANDLE) continue; printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s] [ %s ]\n", - (objects.data[i].key_type == CKK_RSA ? "RSA " : - objects.data[i].key_type == CKK_EC ? " EC " : - objects.data[i].key_type == CKK_EC_EDWARDS ? "EC_E" : - objects.data[i].key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), - objects.data[i].bits, - objects.data[i].verify_public == 1 ? " ./ " : " ", - objects.data[i].sign ? "[./] " : "[ ] ", - objects.data[i].verify ? " [./] " : " [ ] ", - objects.data[i].encrypt ? "[./] " : "[ ] ", - objects.data[i].decrypt ? " [./] " : " [ ] ", - objects.data[i].wrap ? "[./]" : "[ ]", - objects.data[i].unwrap ? "[./]" : "[ ]", - objects.data[i].derive_pub ? "[./]" : "[ ]", - objects.data[i].derive_priv ? "[./]" : "[ ]", - objects.data[i].always_auth ? "[./]" : "[ ]"); + (o->key_type == CKK_RSA ? "RSA " : + o->key_type == CKK_EC ? " EC " : + o->key_type == CKK_EC_EDWARDS ? "EC_E" : + o->key_type == CKK_EC_MONTGOMERY ? "EC_M" : + o->key_type == CKK_AES ? "AES " : " ?? "), + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] ", + o->wrap ? "[./]" : "[ ]", + o->unwrap ? "[./]" : "[ ]", + o->derive_pub ? "[./]" : "[ ]", + o->derive_priv ? "[./]" : "[ ]", + o->always_auth ? "[./]" : "[ ]"); P11TEST_DATA_ROW(info, 14, - 's', objects.data[i].id_str, - 's', objects.data[i].label, - 's', (objects.data[i].key_type == CKK_RSA ? "RSA" : - objects.data[i].key_type == CKK_EC ? "EC" : - objects.data[i].key_type == CKK_EC_EDWARDS ? "EC_E" : - objects.data[i].key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), - 'd', objects.data[i].bits, - 's', objects.data[i].verify_public == 1 ? "YES" : "", - 's', objects.data[i].sign ? "YES" : "", - 's', objects.data[i].verify ? "YES" : "", - 's', objects.data[i].encrypt ? "YES" : "", - 's', objects.data[i].decrypt ? "YES" : "", - 's', objects.data[i].wrap ? "YES" : "", - 's', objects.data[i].unwrap ? "YES" : "", - 's', objects.data[i].derive_pub ? "YES" : "", - 's', objects.data[i].derive_priv ? "YES" : "", - 's', objects.data[i].always_auth ? "YES" : ""); + 's', o->id_str, + 's', o->label, + 's', (o->key_type == CKK_RSA ? "RSA" : + o->key_type == CKK_EC ? "EC" : + o->key_type == CKK_EC_EDWARDS ? "EC_E" : + o->key_type == CKK_EC_MONTGOMERY ? "EC_M" : + o->key_type == CKK_AES ? "AES" : " ?? "), + 'd', o->bits, + 's', o->verify_public == 1 ? "YES" : "", + 's', o->sign ? "YES" : "", + 's', o->verify ? "YES" : "", + 's', o->encrypt ? "YES" : "", + 's', o->decrypt ? "YES" : "", + 's', o->wrap ? "YES" : "", + 's', o->unwrap ? "YES" : "", + 's', o->derive_pub ? "YES" : "", + 's', o->derive_priv ? "YES" : "", + 's', o->always_auth ? "YES" : ""); } printf(" Public == Cert -----^ ^-----^ ^-----^ ^----^ ^---^\n"); printf(" Sign & Verify Attributes ------' | | |\n"); From 9a292d3b36a710a37cf0b969d0f23e96554e0d45 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Oct 2021 09:39:10 +0200 Subject: [PATCH 2126/4321] pkcs11-tool: More verbose errors when generating keys --- src/tools/pkcs11-tool.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6ac7d03179..39e3765987 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2808,7 +2808,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Generate RSA mechanism not supported"); if (size == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key pair type %s, expecting RSA:", type); key_length = (unsigned long)atol(size); if (key_length != 0) modulusBits = key_length; @@ -2930,7 +2930,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, const char *p_param_set = type + strlen("GOSTR3410"); if (p_param_set == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key pair type %s, expecting GOSTR3410:", type); if (!strcmp(":A", p_param_set) || !strcmp("-2001:A", p_param_set)) { gost_key_type = CKK_GOSTR3410; @@ -2992,7 +2992,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; } else - util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410-2001:{A,B,C}," + util_fatal("Unknown key pair type %s, valid key types for mechanism GOSTR3410 are GOSTR3410-2001:{A,B,C}," " GOSTR3410-2012-256:{A,B,C,D}, GOSTR3410-2012-512:{A,B,C}", type); if (!opt_mechanism_used) { @@ -3029,7 +3029,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } } else { - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key pair type %s", type); } mechanism.mechanism = opt_mechanism; @@ -3131,7 +3131,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Generate Key mechanism not supported\n"); if (size == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key type %s, expecting AES:", type); key_length = (unsigned long)atol(size); if (key_length == 0) key_length = 32; @@ -3151,7 +3151,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Generate Key mechanism not supported\n"); if (size == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key type %s, expecting DES:", type); key_length = (unsigned long)atol(size); if (key_length == 0) key_length = 8; @@ -3171,7 +3171,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Generate Key mechanism not supported\n"); if (size == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key type %s, expecting DES3:", type); key_length = (unsigned long)atol(size); if (key_length == 0) key_length = 16; @@ -3191,7 +3191,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey util_fatal("Generate Key mechanism not supported\n"); if (size == NULL) - util_fatal("Unknown key type %s", type); + util_fatal("Unknown key type %s, expecting GENERIC:", type); key_length = (unsigned long)atol(size); if (key_length == 0) key_length = 32; From a3f0dbca2475603e58c222b09eee00e73fa7b636 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Oct 2021 16:27:44 +0200 Subject: [PATCH 2127/4321] p11test: Add support for symmetric keys --- src/pkcs11/pkcs11.h | 19 +- src/tests/p11test/Makefile.am | 2 + src/tests/p11test/p11test.c | 12 +- src/tests/p11test/p11test_case_common.c | 167 +++++++++++- src/tests/p11test/p11test_case_common.h | 2 + src/tests/p11test/p11test_case_mechs.c | 28 ++ src/tests/p11test/p11test_case_readonly.c | 8 +- src/tests/p11test/p11test_case_readonly.h | 10 + src/tests/p11test/p11test_case_secret.c | 313 ++++++++++++++++++++++ src/tests/p11test/p11test_case_secret.h | 26 ++ src/tests/p11test/p11test_common.h | 6 + src/tests/p11test/runtest.sh | 25 ++ 12 files changed, 607 insertions(+), 11 deletions(-) create mode 100644 src/tests/p11test/p11test_case_secret.c create mode 100644 src/tests/p11test/p11test_case_secret.h diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 54055e2b20..78b5b72789 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -761,6 +761,10 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_CCM (0x1088UL) #define CKM_AES_CTS (0x1089UL) #define CKM_AES_CMAC (0x108AUL) +#define CKM_AES_CMAC_GENERAL (0x108BUL) +#define CKM_AES_XCBC_MAC (0x108CUL) +#define CKM_AES_XCBC_MAC_96 (0x108DUL) +#define CKM_AES_GMAC (0x108EUL) #define CKM_BLOWFISH_KEY_GEN (0x1090UL) #define CKM_BLOWFISH_CBC (0x1091UL) #define CKM_TWOFISH_KEY_GEN (0x1092UL) @@ -796,11 +800,17 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DSA_PARAMETER_GEN (0x2000UL) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_AES_OFB (0x2104UL) +#define CKM_AES_CFB64 (0x2105UL) +#define CKM_AES_CFB8 (0x2106UL) +#define CKM_AES_CFB128 (0x2107UL) #define CKM_AES_KEY_WRAP (0x2109UL) +#define CKM_AES_KEY_WRAP_PAD (0x210AUL) #define CKM_XEDDSA (0x4029UL) -#define CKM_VENDOR_DEFINED (1UL << 31) +#define CKM_VENDOR_DEFINED (1UL << 31) + struct ck_mechanism { ck_mechanism_type_t mechanism; @@ -926,6 +936,13 @@ typedef struct CK_XEDDSA_PARAMS { typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR; +typedef struct CK_AES_CTR_PARAMS { + unsigned long ulCounterBits; + unsigned char cb[16]; +} CK_AES_CTR_PARAMS; + +typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR; + typedef unsigned long ck_rv_t; diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 010d710b0c..008d56e594 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -15,6 +15,7 @@ noinst_HEADERS = p11test_loader.h p11test_case_common.h \ p11test_case_usage.h p11test_case_wait.h \ p11test_case_pss_oaep.h p11test_helpers.h \ p11test_case_ec_derive.h p11test_case_interface.h \ + p11test_case_secret.h \ p11test_common.h AM_CPPFLAGS = -I$(top_srcdir)/src @@ -30,6 +31,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_wait.c \ p11test_case_pss_oaep.c \ p11test_case_interface.c \ + p11test_case_secret.c \ p11test_helpers.c p11test_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(CMOCKA_CFLAGS) p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 8c621e9f48..680ced84bc 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -32,6 +32,7 @@ #include "p11test_case_wait.h" #include "p11test_case_pss_oaep.h" #include "p11test_case_interface.h" +#include "p11test_case_secret.h" #define DEFAULT_P11LIB "../../pkcs11/.libs/opensc-pkcs11.so" @@ -91,14 +92,15 @@ int main(int argc, char** argv) { /* Verify that ECDH key derivation works */ cmocka_unit_test_setup_teardown(derive_tests, user_login_setup, after_test_cleanup), + + /* Verify that basic operations with secret keys work */ + cmocka_unit_test_setup_teardown(secret_tests, + user_login_setup, after_test_cleanup), }; - token.library_path = NULL; - token.pin = NULL; - token.pin_length = 0; - token.interactive = 0; + /* Make sure it is initialized to sensible values */ + memset(&token, 0, sizeof(token_info_t)); token.slot_id = (unsigned long) -1; - token.log.outfile = NULL; while ((command = getopt(argc, argv, "?hm:s:p:io:v")) != -1) { switch (command) { diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index a6635ed237..7d019aeddd 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -70,6 +70,7 @@ add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) o->private_handle = CK_INVALID_HANDLE; o->public_handle = CK_INVALID_HANDLE; o->always_auth = 0; + o->extractable = 0; o->bits = 0; o->verify_public = 0; o->num_mechs = 0; @@ -86,6 +87,7 @@ add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) o->x509 = NULL; /* The "reuse" capability of d2i_X509() is strongly discouraged */ o->key.rsa = NULL; o->key.ec = NULL; + o->value = NULL; /* Store the passed CKA_ID and CKA_LABEL */ o->key_id = malloc(key_id.ulValueLen); @@ -127,6 +129,8 @@ add_supported_mechs(test_cert_t *o) o->num_mechs = token.num_rsa_mechs; for (i = 0; i < token.num_rsa_mechs; i++) { o->mechs[i].mech = token.rsa_mechs[i].mech; + o->mechs[i].params = token.rsa_mechs[i].params; + o->mechs[i].params_len = token.rsa_mechs[i].params_len; o->mechs[i].result_flags = 0; o->mechs[i].usage_flags = token.rsa_mechs[i].usage_flags; @@ -135,6 +139,8 @@ add_supported_mechs(test_cert_t *o) /* Use the default list */ o->num_mechs = 1; o->mechs[0].mech = CKM_RSA_PKCS; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT; @@ -144,6 +150,8 @@ add_supported_mechs(test_cert_t *o) o->num_mechs = token.num_ec_mechs; for (i = 0; i < token.num_ec_mechs; i++) { o->mechs[i].mech = token.ec_mechs[i].mech; + o->mechs[i].params = token.ec_mechs[i].params; + o->mechs[i].params_len = token.ec_mechs[i].params_len; o->mechs[i].result_flags = 0; o->mechs[i].usage_flags = token.ec_mechs[i].usage_flags; @@ -152,6 +160,8 @@ add_supported_mechs(test_cert_t *o) /* Use the default list */ o->num_mechs = 1; o->mechs[0].mech = CKM_ECDSA; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } @@ -160,6 +170,8 @@ add_supported_mechs(test_cert_t *o) o->num_mechs = token.num_ed_mechs; for (i = 0; i < token.num_ed_mechs; i++) { o->mechs[i].mech = token.ed_mechs[i].mech; + o->mechs[i].params = token.ed_mechs[i].params; + o->mechs[i].params_len = token.ed_mechs[i].params_len; o->mechs[i].result_flags = 0; o->mechs[i].usage_flags = token.ed_mechs[i].usage_flags; @@ -168,6 +180,8 @@ add_supported_mechs(test_cert_t *o) /* Use the default list */ o->num_mechs = 1; o->mechs[0].mech = CKM_EDDSA; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } @@ -176,6 +190,8 @@ add_supported_mechs(test_cert_t *o) o->num_mechs = token.num_montgomery_mechs; for (i = 0; i < token.num_montgomery_mechs; i++) { o->mechs[i].mech = token.montgomery_mechs[i].mech; + o->mechs[i].params = token.montgomery_mechs[i].params; + o->mechs[i].params_len = token.montgomery_mechs[i].params_len; o->mechs[i].result_flags = 0; o->mechs[i].usage_flags = token.montgomery_mechs[i].usage_flags; @@ -184,9 +200,31 @@ add_supported_mechs(test_cert_t *o) /* Use the default list */ o->num_mechs = 1; o->mechs[0].mech = CKM_ECDH1_DERIVE; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_DERIVE; } + /* Nothing in the above enum can be used for secret keys */ + } else if (o->key_type == CKK_AES) { + if (token.num_aes_mechs > 0 ) { + o->num_mechs = token.num_aes_mechs; + for (i = 0; i < token.num_aes_mechs; i++) { + o->mechs[i].mech = token.aes_mechs[i].mech; + o->mechs[i].params = token.aes_mechs[i].params; + o->mechs[i].params_len = token.aes_mechs[i].params_len; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = token.aes_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_AES_CBC; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_ENCRYPT|CKF_DECRYPT|CKF_WRAP|CKF_UNWRAP; + } } } @@ -290,6 +328,8 @@ int callback_private_keys(test_certs_t *objects, ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; o->derive_priv = (template[6].ulValueLen != (CK_ULONG) -1) ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; + o->extractable = (template[8].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; debug_print(" [ OK %s ] Private key loaded successfully S:%d D:%d T:%02lX", o->id_str, o->sign, o->decrypt, o->key_type); @@ -571,6 +611,59 @@ int callback_public_keys(test_certs_t *objects, return 0; } +/** + * Store any secret keys + */ +int callback_secret_keys(test_certs_t *objects, + CK_ATTRIBUTE template[], unsigned int template_size, CK_OBJECT_HANDLE object_handle) +{ + test_cert_t *o = NULL; + + if ((o = add_object(objects, template[1], template[13])) == NULL) + return -1; + + /* TODO generic secret + * there is also no respective EVP_* for AES keys in OpenSSL ... + o->type = ??; */ + + /* Store attributes, flags and handles */ + o->private_handle = object_handle; + /* For verification/encryption, we use the same key */ + o->public_handle = object_handle; + o->key_type = (template[0].ulValueLen != (CK_ULONG) -1) + ? *((CK_KEY_TYPE *) template[0].pValue) : (CK_KEY_TYPE) -1; + o->sign = (template[3].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[3].pValue) : CK_FALSE; + o->sign = (template[4].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; + o->decrypt = (template[5].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; + o->decrypt = (template[6].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; + o->derive_priv = (template[7].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[7].pValue) : CK_FALSE; + o->wrap = (template[8].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; + o->unwrap = (template[9].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; + o->extractable = (template[12].ulValueLen != (CK_ULONG) -1) + ? *((CK_BBOOL *) template[12].pValue) : CK_FALSE; + + if (template[10].ulValueLen > 0) { + /* pass the pointer to our structure */ + o->value = template[10].pValue; + template[10].pValue = NULL; + } + + o->bits = template[11].ulValueLen > 0 ? *((CK_ULONG *) template[11].pValue)*8 : 0; + + add_supported_mechs(o); + + debug_print(" [ OK %s ] Secret key loaded successfully T:%02lX", o->id_str, o->key_type); + return 0; +} + + int search_objects(test_certs_t *objects, token_info_t *info, CK_ATTRIBUTE filter[], CK_LONG filter_size, CK_ATTRIBUTE template[], CK_LONG template_size, int (*callback)(test_certs_t *, CK_ATTRIBUTE[], unsigned int, CK_OBJECT_HANDLE)) @@ -632,7 +725,8 @@ int search_objects(test_certs_t *objects, token_info_t *info, rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], &(template[j]), 1); - if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { + if (rv == CKR_ATTRIBUTE_TYPE_INVALID || + rv == CKR_ATTRIBUTE_SENSITIVE) { continue; } else if (rv != CKR_OK) { fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); @@ -674,6 +768,7 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) CK_OBJECT_CLASS keyClass = CKO_CERTIFICATE; CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY; CK_OBJECT_CLASS publicClass = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY; CK_ATTRIBUTE filter[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, }; @@ -694,6 +789,7 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) { CKA_UNWRAP, NULL, 0}, // CK_BBOOL { CKA_DERIVE, NULL, 0}, // CK_BBOOL { CKA_LABEL, NULL_PTR, 0}, + { CKA_EXTRACTABLE, NULL, 0}, // CK_BBOOL }; CK_ULONG private_attrs_size = sizeof (private_attrs) / sizeof (CK_ATTRIBUTE); CK_ATTRIBUTE public_attrs[] = { @@ -709,6 +805,23 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) { CKA_DERIVE, NULL, 0}, // CK_BBOOL }; CK_ULONG public_attrs_size = sizeof (public_attrs) / sizeof (CK_ATTRIBUTE); + CK_ATTRIBUTE secret_attrs[] = { + { CKA_KEY_TYPE, NULL, 0}, + { CKA_ID, NULL, 0}, + { CKA_TOKEN, NULL, 0}, // CK_BBOOL + { CKA_SIGN, NULL, 0}, // CK_BBOOL + { CKA_VERIFY, NULL, 0}, // CK_BBOOL + { CKA_ENCRYPT, NULL, 0}, // CK_BBOOL + { CKA_DECRYPT, NULL, 0}, // CK_BBOOL + { CKA_DERIVE, NULL, 0}, // CK_BBOOL + { CKA_WRAP, NULL, 0}, // CK_BBOOL + { CKA_UNWRAP, NULL, 0}, // CK_BBOOL + { CKA_VALUE, NULL, 0}, + { CKA_VALUE_LEN, NULL, 0}, + { CKA_EXTRACTABLE, NULL, 0}, // CK_BBOOL + { CKA_LABEL, NULL_PTR, 0}, + }; + CK_ULONG secret_attrs_size = sizeof (secret_attrs) / sizeof (CK_ATTRIBUTE); debug_print("\nSearch for all certificates on the card"); search_objects(objects, info, filter, filter_size, @@ -726,6 +839,11 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) filter[0].pValue = &publicClass; search_objects(objects, info, filter, filter_size, public_attrs, public_attrs_size, callback_public_keys); + + debug_print("\nSearch for all secret keys"); + filter[0].pValue = &secretClass; + search_objects(objects, info, filter, filter_size, secret_attrs, secret_attrs_size, + callback_secret_keys); } void clean_all_objects(test_certs_t *objects) { @@ -734,6 +852,7 @@ void clean_all_objects(test_certs_t *objects) { free(objects->data[i].key_id); free(objects->data[i].id_str); free(objects->data[i].label); + free(objects->data[i].value); X509_free(objects->data[i].x509); if (objects->data[i].key_type == CKK_RSA && objects->data[i].key.rsa != NULL) { @@ -848,6 +967,52 @@ const char *get_mechanism_name(int mech_id) return "SHA3_384"; case CKM_SHA3_512: return "SHA3_512"; + case CKM_AES_ECB: + return "AES_ECB"; + case CKM_AES_ECB_ENCRYPT_DATA: + return "AES_ECB_ENCRYPT_DATA"; + case CKM_AES_KEY_GEN: + return "AES_KEY_GEN"; + case CKM_AES_CBC: + return "AES_CBC"; + case CKM_AES_CBC_ENCRYPT_DATA: + return "AES_CBC_ENCRYPT_DATA"; + case CKM_AES_CBC_PAD: + return "AES_CBC_PAD"; + case CKM_AES_MAC: + return "AES_MAC"; + case CKM_AES_MAC_GENERAL: + return "AES_MAC_GENERAL"; + case CKM_AES_CFB64: + return "AES_CFB64"; + case CKM_AES_CFB8: + return "AES_CFB8"; + case CKM_AES_CFB128: + return "AES_CFB128"; + case CKM_AES_OFB: + return "AES_OFB"; + case CKM_AES_CTR: + return "AES_CTR"; + case CKM_AES_GCM: + return "AES_GCM"; + case CKM_AES_CCM: + return "AES_CCM"; + case CKM_AES_CTS: + return "AES_CTS"; + case CKM_AES_CMAC: + return "AES_CMAC"; + case CKM_AES_CMAC_GENERAL: + return "AES_CMAC_GENERAL"; + case CKM_DES3_CMAC: + return "DES3_CMAC"; + case CKM_DES3_CMAC_GENERAL: + return "DES3_CMAC_GENERAL"; + case CKM_AES_XCBC_MAC: + return "AES_XCBC_MAC"; + case CKM_AES_XCBC_MAC_96: + return "AES_XCBC_MAC_96"; + case CKM_AES_KEY_WRAP: + return "AES_KEY_WRAP"; default: sprintf(name_buffer, "0x%.8X", mech_id); return name_buffer; diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index bd0240bd4c..ec690eeb71 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -50,8 +50,10 @@ typedef struct { CK_BBOOL derive_pub; CK_KEY_TYPE key_type; CK_BBOOL always_auth; + CK_BBOOL extractable; char *label; CK_ULONG bits; + char *value; int verify_public; test_mech_t mechs[MAX_MECHS]; int num_mechs; diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index 42423a76e6..e1f9024a32 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -123,6 +123,34 @@ void supported_mechanisms_test(void **state) { P11TEST_FAIL(info, "Too many montgomery EC mechanisms (%d)", MAX_MECHS); } + /* We list all known secret key mechanisms */ + if (mechanism_list[i] == CKM_AES_ECB || + mechanism_list[i] == CKM_AES_ECB_ENCRYPT_DATA || + mechanism_list[i] == CKM_AES_CBC || + mechanism_list[i] == CKM_AES_CBC_ENCRYPT_DATA || + mechanism_list[i] == CKM_AES_CBC_PAD || + mechanism_list[i] == CKM_AES_MAC || + mechanism_list[i] == CKM_AES_MAC_GENERAL || + mechanism_list[i] == CKM_AES_CFB64 || + mechanism_list[i] == CKM_AES_CFB8 || + mechanism_list[i] == CKM_AES_CFB128 || + mechanism_list[i] == CKM_AES_OFB || + mechanism_list[i] == CKM_AES_CTR || + mechanism_list[i] == CKM_AES_GCM || + mechanism_list[i] == CKM_AES_CCM || + mechanism_list[i] == CKM_AES_CTS || + mechanism_list[i] == CKM_AES_CMAC || + mechanism_list[i] == CKM_AES_CMAC_GENERAL || + mechanism_list[i] == CKM_AES_XCBC_MAC || + mechanism_list[i] == CKM_AES_XCBC_MAC_96) { + if (token.num_aes_mechs < MAX_MECHS) { + mech = &token.aes_mechs[token.num_aes_mechs++]; + mech->mech = mechanism_list[i]; + mech->usage_flags = mechanism_info[i].flags; + } else + P11TEST_FAIL(info, "Too many AES mechanisms (%d)", MAX_MECHS); + } + if ((mechanism_info[i].flags & CKF_GENERATE_KEY_PAIR) != 0) { if (token.num_keygen_mechs < MAX_MECHS) { mech = &token.keygen_mechs[token.num_keygen_mechs++]; diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 75a744522d..4e240ac90e 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -97,7 +97,7 @@ int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM enc_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM enc_mechanism = { mech->mech, mech->params, mech->params_len }; CK_ULONG enc_message_length; static int encrypt_support = 1; @@ -145,7 +145,7 @@ int decrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *enc_message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM dec_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM dec_mechanism = { mech->mech, mech->params, mech->params_len }; CK_ULONG dec_message_length = BUFFER_SIZE; rv = fp->C_DecryptInit(info->session_handle, &dec_mechanism, @@ -261,7 +261,7 @@ int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; CK_ULONG sign_length = 0; char *name; @@ -514,7 +514,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; static int verify_support = 1; char *name; diff --git a/src/tests/p11test/p11test_case_readonly.h b/src/tests/p11test/p11test_case_readonly.h index 8f8a757667..3859d3ba96 100644 --- a/src/tests/p11test/p11test_case_readonly.h +++ b/src/tests/p11test/p11test_case_readonly.h @@ -27,3 +27,13 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, CK_ULONG message_length, int multipart); +int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char *sign, + CK_ULONG sign_length, int multipart); +int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **sign, + int multipart); +int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, + CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message); +int decrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *enc_message, + CK_ULONG enc_message_length, test_mech_t *mech, unsigned char **dec_message); diff --git a/src/tests/p11test/p11test_case_secret.c b/src/tests/p11test/p11test_case_secret.c new file mode 100644 index 0000000000..48fe5b9176 --- /dev/null +++ b/src/tests/p11test/p11test_case_secret.c @@ -0,0 +1,313 @@ +/* + * p11test_case_secret.c: Check the functionality of operations with secret keys + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_secret.h" +#include "p11test_case_readonly.h" + +#define MESSAGE_TO_SIGN "Simple message for signing & verifying. " \ + "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" + +const unsigned char *short_message = (unsigned char *) MESSAGE_TO_SIGN; + +static unsigned char * +pkcs7_pad_message(const unsigned char *message, unsigned long message_length, + unsigned long block_len, unsigned long *out_len) +{ + int pad_length = block_len - (message_length % block_len); + unsigned char *pad_message = malloc(message_length + pad_length); + if (pad_message == NULL) { + return NULL; + } + memcpy(pad_message, message, message_length); + memset(pad_message + message_length, pad_length, pad_length); + *out_len = message_length + pad_length; + return pad_message; +} + +/* Perform encryption and decryption of a message using secret key referenced + * in the o object with mechanism defined by mech. + * + * NONE of the reasonable mechanisms support multipart encryption/decryption + * + * Returns + * * 1 for successful Encrypt&Decrypt sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int test_secret_encrypt_decrypt(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart) +{ + CK_BYTE *message = NULL; + CK_BYTE *dec_message = NULL; + CK_BYTE iv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + CK_AES_CTR_PARAMS ctr_params = { 64, {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CK_BYTE aad[] = {0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + CK_GCM_PARAMS gcm_params = { + .pIv = (void *)iv, + .ulIvLen = 16, + .ulIvBits = 64, + .pAAD = aad, /* TODO: SoftHSM crashes without AAD */ + .ulAADLen = sizeof(aad), + .ulTagBits = 128, + }; + int dec_message_length = 0; + unsigned char *enc_message = NULL; + int enc_message_length, rv; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing secret key", o->id_str); + return 0; + } + + if (o->key_type != CKK_AES) { + debug_print(" [ KEY %s ] Skip non-AES key for encryption", o->id_str); + return 0; + } + + /* The CBC mechanisms require parameter with IV */ + mech->params = &iv; + mech->params_len = sizeof(iv); + if (mech->mech == CKM_AES_CBC || mech->mech == CKM_AES_ECB) { + /* This mechanism requires the blocks to be aligned to block size */ + message = pkcs7_pad_message(short_message, message_length, 16, &message_length); + } else if (mech->mech == CKM_AES_CBC_PAD || mech->mech == CKM_AES_CTS) { + message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); + } else if (mech->mech == CKM_AES_CTR) { + /* The CTR requires counter block + counter bits */ + mech->params = &ctr_params; + mech->params_len = sizeof(ctr_params); + message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); + } else if (mech->mech == CKM_AES_GCM) { + /* The GCM requires GCM parameter */ + mech->params = &gcm_params; + mech->params_len = sizeof(gcm_params); + message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); + } else { + debug_print(" [SKIP %s ] Unknown mechanism", o->id_str); + return 0; + } + + debug_print(" [ KEY %s ] Encrypt message using CKM_%s", + o->id_str, get_mechanism_name(mech->mech)); + enc_message_length = encrypt_message(o, info, message, message_length, + mech, &enc_message); + if (enc_message_length <= 0) { + mech->params = NULL; + mech->params_len = 0; + free(enc_message); + free(message); + return -1; + } + + debug_print(" [ KEY %s ] Decrypt message", o->id_str); + dec_message_length = decrypt_message(o, info, enc_message, + enc_message_length, mech, &dec_message); + free(enc_message); + if (dec_message_length <= 0) { + mech->params = NULL; + mech->params_len = 0; + free(message); + return -1; + } + + if (memcmp(dec_message, message, dec_message_length) == 0 + && (unsigned int) dec_message_length == message_length) { + debug_print(" [ OK %s ] Text decrypted successfully.", o->id_str); + mech->result_flags |= FLAGS_DECRYPT; + rv = 1; + } else { + dec_message[dec_message_length] = '\0'; + debug_print(" [ ERROR %s ] Text decryption failed. Recovered text: %s", + o->id_str, dec_message); + rv = 0; + } + mech->params = NULL; + mech->params_len = 0; + free(dec_message); + free(message); + return rv; +} + + +/* Perform signature and verification of a message using secret key referenced + * in the o object with mechanism defined by mech. Message length can be + * specified using argument message_length. + * + * Returns + * * 1 for successful Sign&Verify sequence + * * 0 for skipped test (unsupported mechanism, key, ...) + * * -1 otherwise. + * Serious errors terminate the execution. + */ +int test_secret_sign_verify(test_cert_t *o, token_info_t *info, test_mech_t *mech, + CK_ULONG message_length, int multipart) +{ + CK_BYTE *message = NULL; + CK_ULONG sig_len = 42; + CK_BYTE *sign = NULL; + CK_ULONG sign_length = 0; + int rv = 0; + + if (message_length > strlen(MESSAGE_TO_SIGN)) { + fail_msg("Truncate (%lu) is longer than the actual message (%lu)", + message_length, strlen(MESSAGE_TO_SIGN)); + return -1; + } + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing secret key handle", o->id_str); + return 0; + } + + if (o->key_type != CKK_AES) { + debug_print(" [SKIP %s ] Skip non-AES key", o->id_str); + return 0; + } + + if (mech->mech == CKM_AES_CMAC) { + message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); + } else if (mech->mech == CKM_AES_CMAC_GENERAL) { + message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); + /* This mechanism requires parameter denoting the requested output length */ + mech->params = &sig_len; + mech->params_len = sizeof(sig_len); + } else { + debug_print(" [SKIP %s ] Unknown mechanism", o->id_str); + return 0; + } + + debug_print(" [ KEY %s ] Signing message of length %lu using CKM_%s", + o->id_str, message_length, get_mechanism_name(mech->mech)); + rv = sign_message(o, info, message, message_length, mech, &sign, multipart); + if (rv <= 0) { + mech->params = NULL; + mech->params_len = 0; + free(message); + return rv; + } + sign_length = (unsigned long) rv; + + debug_print(" [ KEY %s ] Verify message signature", o->id_str); + rv = verify_message(o, info, message, message_length, mech, + sign, sign_length, multipart); + mech->params = NULL; + mech->params_len = 0; + free(sign); + free(message); + return rv; +} + +void secret_tests(void **state) +{ + unsigned int i; + int j; + int errors = 0; + token_info_t *info = (token_info_t *) *state; + test_certs_t objects; + + test_certs_init(&objects); + + P11TEST_START(info); + search_for_all_objects(&objects, info); + + debug_print("Check operations on secret keys.\n"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + /* Ignore if there is missing private key */ + if (o->private_handle == CK_INVALID_HANDLE) + continue; + + for (j = 0; j < o->num_mechs; j++) { + if (o->key_type == CKK_AES) { + if (o->mechs[j].usage_flags & CKF_SIGN) { + errors += test_secret_sign_verify(&(objects.data[i]), + info, &(o->mechs[j]), 42, 0); + } + if (o->mechs[j].usage_flags & CKF_DECRYPT) { + errors += test_secret_encrypt_decrypt(&(objects.data[i]), + info, &(o->mechs[j]), 42, 0); + } + } + } + } + + /* print summary */ + printf("[KEY ID] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [SIGN&VERIFY] [ENC&DECRYPT]\n"); + P11TEST_DATA_ROW(info, 4, + 's', "KEY ID", + 's', "MECHANISM", + 's', "SIGN&VERIFY WORKS", + 's', "ENCRYPT&DECRYPT WORKS"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + + if (o->key_type != CKK_AES) + continue; + + printf("\n[%-6s] [%s]\n", + o->id_str, + o->label); + printf("[ %s ] [%6lu] [%s%s] [%s%s]\n", + "AES ", + o->bits, + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] "); + if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { + printf(" no usable attributes found ... ignored\n"); + continue; + } + if (o->private_handle == CK_INVALID_HANDLE) { + continue; + } + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; + if ((mech->usage_flags & (CKF_SIGN|CKF_DECRYPT)) == 0) { + /* not applicable mechanisms are skipped */ + continue; + } + printf(" [ %-11s ] [ %s ] [ %s ]\n", + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", + mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); + if ((mech->result_flags & FLAGS_SIGN_ANY) == 0 && + (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) + continue; /* skip empty rows for export */ + P11TEST_DATA_ROW(info, 4, + 's', o->id_str, + 's', get_mechanism_name(mech->mech), + 's', mech->result_flags & FLAGS_SIGN_ANY ? "YES" : "", + 's', mech->result_flags & FLAGS_DECRYPT_ANY ? "YES" : ""); + } + } + printf(" Sign Attribute ----^ ^ ^ ^ ^ ^---- Decrypt Attribute\n"); + printf(" Sign&Verify works ----' | | '------- Enc&Dec works\n"); + printf(" Verify Attribute --------' '---------- Encrypt Attribute\n"); + + clean_all_objects(&objects); + if (errors > 0) + P11TEST_FAIL(info, "Not all the derive mechanisms worked."); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_secret.h b/src/tests/p11test/p11test_case_secret.h new file mode 100644 index 0000000000..753c644f4f --- /dev/null +++ b/src/tests/p11test/p11test_case_secret.h @@ -0,0 +1,26 @@ +/* + * p11test_case_secret.h: Check the functionality of operations with secret keys + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void secret_tests(void **state); + diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index d3eb104062..450856723e 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -59,9 +59,13 @@ typedef struct { typedef struct { CK_MECHANISM_TYPE mech; + /* RSA-PSS parameters */ CK_MECHANISM_TYPE hash; CK_RSA_PKCS_MGF_TYPE mgf; int salt; + /* generic parameters used for example for secret keys */ + void *params; + unsigned long params_len; int usage_flags; int result_flags; } test_mech_t; @@ -84,6 +88,8 @@ typedef struct { size_t num_ed_mechs; test_mech_t montgomery_mechs[MAX_MECHS]; size_t num_montgomery_mechs; + test_mech_t aes_mechs[MAX_MECHS]; + size_t num_aes_mechs; test_mech_t keygen_mechs[MAX_MECHS]; size_t num_keygen_mechs; } token_info_t; diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index 5041ad1033..fd875eab4b 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -25,6 +25,23 @@ export GNUTLS_PIN=$PIN GENERATE_KEYS=1 PKCS11_TOOL="../../tools/pkcs11-tool"; +function generate_sym() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # Generate key + $PKCS11_TOOL --keygen --key-type="$TYPE" --login --pin=$PIN \ + --extractable --module="$P11LIB" --label="$LABEL" --id=$ID + + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate $TYPE key pair" + return 1 + fi + + p11tool --login --provider="$P11LIB" --list-all +} + function generate_cert() { TYPE="$1" ID="$2" @@ -69,6 +86,7 @@ function generate_cert() { function card_setup() { ECC_KEYS=1 EDDSA=1 + SECRET=1 case $1 in "softhsm") P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" @@ -82,6 +100,7 @@ function card_setup() { # Supports only RSA mechanisms ECC_KEYS=0 EDDSA=0 + SECRET=0 P11LIB="/usr/lib64/pkcs11/libopencryptoki.so" SO_PIN=87654321 SLOT_ID=3 # swtok slot @@ -133,6 +152,12 @@ function card_setup() { #generate_cert "EC:curve25519" "06" "Curve25519" 0 # not supported by softhsm either fi + if [[ $SECRET -eq 1 ]]; then + # Generate AES 128 key + generate_sym "aes:16" "07" "AES128 key" + # Generate AES 256 key + generate_sym "aes:32" "08" "AES256 key" + fi fi } From df9570fdbf21e23760e5a361d8a6330d5f621d55 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 12 Oct 2021 16:28:41 +0200 Subject: [PATCH 2128/4321] p11test: Do not set bogus flag on encryption --- src/tests/p11test/p11test_case_readonly.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 4e240ac90e..c670933f04 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -129,7 +129,6 @@ int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, rv = fp->C_Encrypt(info->session_handle, message, message_length, *enc_message, &enc_message_length); if (rv == CKR_OK) { - mech->result_flags |= FLAGS_SIGN; return enc_message_length; } debug_print(" C_Encrypt: rv = 0x%.8lX", rv); From d26d4e2938b94b01dd2c43516b7214e69ed821f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Oct 2021 11:39:48 +0200 Subject: [PATCH 2129/4321] p11test: Align tables and drop unused fields --- src/tests/p11test/p11test_case_ec_derive.c | 10 +++++----- src/tests/p11test/p11test_case_readonly.c | 14 +++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 3fab5397d7..bed5761d57 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -358,7 +358,7 @@ void derive_tests(void **state) { /* print summary */ printf("[KEY ID] [LABEL]\n"); - printf("[ TYPE ] [ SIZE ] [ PUBLIC ] [ DERIVE ]\n"); + printf("[ TYPE ] [ SIZE ] [ PUBLIC ] [ DERIVE ]\n"); P11TEST_DATA_ROW(info, 3, 's', "KEY ID", 's', "MECHANISM", @@ -372,7 +372,7 @@ void derive_tests(void **state) { printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[ %s ] [%6lu] [ %s ] [ %s%s ]\n", + printf("[ %s ] [%6lu] [ %s ] [ %s%s ]\n", (o->key_type == CKK_EC ? " EC " : o->key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), o->bits, @@ -392,7 +392,7 @@ void derive_tests(void **state) { /* not applicable mechanisms are skipped */ continue; } - printf(" [ %-23s ] [ %s ]\n", + printf(" [ %-22s ] [ %s ]\n", get_mechanism_name(mech->mech), mech->result_flags & FLAGS_DERIVE ? "[./]" : " "); if ((mech->result_flags & FLAGS_DERIVE) == 0) @@ -403,8 +403,8 @@ void derive_tests(void **state) { 's', mech->result_flags & FLAGS_DERIVE ? "YES" : ""); } } - printf(" Public == Cert -----^ ^\n"); - printf(" ECDH Derive functionality -----'\n"); + printf(" Public == Cert -----^ ^\n"); + printf(" ECDH Derive functionality -------'\n"); clean_all_objects(&objects); if (errors > 0) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index c670933f04..853e0db582 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -681,7 +681,7 @@ void readonly_tests(void **state) { /* print summary */ printf("[KEY ID] [LABEL]\n"); - printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ DERIVE ]\n"); + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT]\n"); P11TEST_DATA_ROW(info, 4, 's', "KEY ID", 's', "MECHANISM", @@ -699,7 +699,7 @@ void readonly_tests(void **state) { printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s]\n", + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s]\n", (o->key_type == CKK_RSA ? "RSA " : o->key_type == CKK_EC ? " EC " : o->key_type == CKK_EC_EDWARDS ? "EC_E" : @@ -709,11 +709,7 @@ void readonly_tests(void **state) { o->sign ? "[./] " : "[ ] ", o->verify ? " [./] " : " [ ] ", o->encrypt ? "[./] " : "[ ] ", - o->decrypt ? " [./] " : " [ ] ", - o->wrap ? "[./]" : "[ ]", - o->unwrap ? "[./]" : "[ ]", - o->derive_pub ? "[./]" : "[ ]", - o->derive_priv ? "[./]" : "[ ]"); + o->decrypt ? " [./] " : " [ ] "); if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { printf(" no usable attributes found ... ignored\n"); continue; @@ -727,7 +723,7 @@ void readonly_tests(void **state) { /* not applicable mechanisms are skipped */ continue; } - printf(" [ %-20s ] [ %s ] [ %s ] [ ] [ ]\n", + printf(" [ %-20s ] [ %s ] [ %s ]\n", get_mechanism_name(mech->mech), mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); @@ -741,7 +737,7 @@ void readonly_tests(void **state) { 's', mech->result_flags & FLAGS_DECRYPT_ANY ? "YES" : ""); } } - printf(" Public == Cert -----^ ^ ^ ^ ^ ^ ^ ^----^- Attributes\n"); + printf(" Public == Cert -----^ ^ ^ ^ ^ ^ ^\n"); printf(" Sign Attribute -------------' | | | | '---- Decrypt Attribute\n"); printf(" Sign&Verify functionality -----' | | '------- Enc&Dec functionality\n"); printf(" Verify Attribute -----------------' '---------- Encrypt Attribute\n"); From 34a2a1c52d15da1c36adb489004bfc142fce6cf6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Oct 2021 10:44:46 +0200 Subject: [PATCH 2130/4321] doc: Add missing switch documentation --- doc/tools/pkcs15-init.1.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 37d6a41839..f11366b806 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -678,6 +678,17 @@ + + + LABEL + + + + Specify label for a PIN, key, certificate or data object when creating a new objects. When deleting objects, this can be used to delete object by label. + + + + LABEL From 4e93da6578bd68aadb5ee571d8617e277cc40a78 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Oct 2021 15:07:57 +0200 Subject: [PATCH 2131/4321] pkcs11: Report CKA_VALUE_LEN based on the SKDF parameters when available --- src/pkcs11/framework-pkcs15.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 7e327712c5..75e859b408 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5357,7 +5357,11 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_VALUE_LEN: check_attribute_buffer(attr, sizeof(CK_ULONG)); - *(CK_ULONG*)attr->pValue = skey->info->data.len; + if (skey->info->data.len) { /* Available only if the CKA_VALUE is present -- probably never */ + *(CK_ULONG*)attr->pValue = skey->info->data.len; + } else { /* From standard secret key SKDF keyLen attribute (in bits) */ + *(CK_ULONG*)attr->pValue = skey->info->value_len/8; + } break; case CKA_VALUE: check_attribute_buffer(attr, skey->info->data.len); From c479f36ea7fcfe4c7a97fbaddd5f1f45b052014f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Oct 2021 15:16:11 +0200 Subject: [PATCH 2132/4321] containers: Add missing :z option and its explanation in documentation --- containers/README.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/containers/README.md b/containers/README.md index ac71b50a7f..aaeb29bfe6 100644 --- a/containers/README.md +++ b/containers/README.md @@ -7,26 +7,26 @@ First, we need to prepare the container image. This already runs setup and mounts current working directory to the container: ``` -$ podman build -v $PWD:/src -t opensc-build containers/opensc-build +$ podman build -v $PWD:/src:z -t opensc-build containers/opensc-build ``` Now, you can jump into the container with preinstalled dependencies to build OpenSC: ``` -$ podman run -v $PWD:/src -ti opensc-build +$ podman run -v $PWD:/src:z -ti opensc-build ``` If you want to run the build manually, investigate some issues, you can start with shell ``` -$ podman run -v $PWD:/src -ti opensc-build /bin/bash +$ podman run -v $PWD:/src:z -ti opensc-build /bin/bash # .github/build.sh ``` To debug some issues with gdb, the container needs some more capabilities. With the following configuration, I am able to run gdb to debug possible issues: ``` -$ podman run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $PWD:/src -ti opensc-build /bin/bash +$ podman run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $PWD:/src:z -ti opensc-build /bin/bash # .github/build.sh # apt install -y libtool-bin gdb # libtool --mode=execute gdb --args ./src/tools/pkcs11-tool --test-threads IN -L --module=/usr/lib/softhsm/libsofthsm2.so @@ -34,22 +34,30 @@ $ podman run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $PWD:/src Similarly for tests, you can build a container for example for CAC testing: ``` -$ podman build -v $PWD:/src -t opensc-cac containers/opensc-test-cac +$ podman build -v $PWD:/src:z -t opensc-cac containers/opensc-test-cac ``` and then run the tests: ``` -$ podman run -v $PWD:/src -ti opensc-cac +$ podman run -v $PWD:/src:z -ti opensc-cac ``` The javacard tests are very similar. This can be used to build a container for PIV testing: ``` -$ podman build -v $PWD:/src -t opensc-piv containers/opensc-test-piv +$ podman build -v $PWD:/src:z -t opensc-piv containers/opensc-test-piv ``` and then run the tests: ``` -$ podman run -v $PWD:/src -ti opensc-piv +$ podman run -v $PWD:/src:z -ti opensc-piv ``` -(if you are using Docker, you will need to replace "podman" with "docker" and + +## Footnotes and explanations + +If you are using Docker, you will need to replace "podman" with "docker" and maybe change the generic Containerfile name to Dockerfile, but otherwise it -should work the same way) +should work the same way. + +The `:z` option to the volume argument is needed on SELinux-enabled systems to +allow podman accessing your files. On the first invocation, podman will relabel +the directory to be accessible from the container. On any follow-up invocations +it will make sure the new files have expected labels. From ac8dc4d19ead474d957aa9eea91db429616c58d0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:38:31 +0100 Subject: [PATCH 2133/4321] p11test: Initial support for key wrapping --- src/tests/p11test/Makefile.am | 3 +- src/tests/p11test/p11test.c | 5 + src/tests/p11test/p11test_case_mechs.c | 2 + src/tests/p11test/p11test_case_readonly.c | 6 + src/tests/p11test/p11test_case_wrap.c | 399 ++++++++++++++++++++++ src/tests/p11test/p11test_case_wrap.h | 27 ++ src/tests/p11test/p11test_common.h | 14 +- src/tests/p11test/runtest.sh | 6 +- 8 files changed, 453 insertions(+), 9 deletions(-) create mode 100644 src/tests/p11test/p11test_case_wrap.c create mode 100644 src/tests/p11test/p11test_case_wrap.h diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index 008d56e594..c88968ef94 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -15,7 +15,7 @@ noinst_HEADERS = p11test_loader.h p11test_case_common.h \ p11test_case_usage.h p11test_case_wait.h \ p11test_case_pss_oaep.h p11test_helpers.h \ p11test_case_ec_derive.h p11test_case_interface.h \ - p11test_case_secret.h \ + p11test_case_wrap.h p11test_case_secret.h \ p11test_common.h AM_CPPFLAGS = -I$(top_srcdir)/src @@ -31,6 +31,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_wait.c \ p11test_case_pss_oaep.c \ p11test_case_interface.c \ + p11test_case_wrap.c \ p11test_case_secret.c \ p11test_helpers.c p11test_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(CMOCKA_CFLAGS) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 680ced84bc..1db23bfb6b 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -32,6 +32,7 @@ #include "p11test_case_wait.h" #include "p11test_case_pss_oaep.h" #include "p11test_case_interface.h" +#include "p11test_case_wrap.h" #include "p11test_case_secret.h" #define DEFAULT_P11LIB "../../pkcs11/.libs/opensc-pkcs11.so" @@ -96,6 +97,10 @@ int main(int argc, char** argv) { /* Verify that basic operations with secret keys work */ cmocka_unit_test_setup_teardown(secret_tests, user_login_setup, after_test_cleanup), + + /* Verify that key wrapping and unwrapping works */ + cmocka_unit_test_setup_teardown(wrap_tests, + user_login_setup, after_test_cleanup), }; /* Make sure it is initialized to sensible values */ diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index e1f9024a32..01204a29e2 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -139,6 +139,8 @@ void supported_mechanisms_test(void **state) { mechanism_list[i] == CKM_AES_GCM || mechanism_list[i] == CKM_AES_CCM || mechanism_list[i] == CKM_AES_CTS || + mechanism_list[i] == CKM_AES_KEY_WRAP || + mechanism_list[i] == CKM_AES_KEY_WRAP_PAD || mechanism_list[i] == CKM_AES_CMAC || mechanism_list[i] == CKM_AES_CMAC_GENERAL || mechanism_list[i] == CKM_AES_XCBC_MAC || diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 853e0db582..858b81b43c 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -73,6 +73,12 @@ int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message { int rv, padding; + /* this works only for RSA keys */ + if (o->key_type != CKK_RSA) { + debug_print("skip non-RSA key"); + return -1; + } + *enc_message = malloc(RSA_size(o->key.rsa)); if (*enc_message == NULL) { debug_print("malloc returned null"); diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c new file mode 100644 index 0000000000..99042ed34d --- /dev/null +++ b/src/tests/p11test/p11test_case_wrap.c @@ -0,0 +1,399 @@ +/* + * p11test_case_wrap.c: Check the functionality of wrap mechanisms + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "p11test_case_wrap.h" + +#include +#include + +/* returns the new length of message after stripping the pkcs7 padding */ +static int +strip_pkcs7_padding(const unsigned char *message, unsigned long message_length, + unsigned long block_len) +{ + unsigned char pad_length = message[message_length - 1]; + + if (pad_length > block_len) { + return 0; + } + + return message_length - pad_length; +} + +static int test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mech) +{ + CK_FUNCTION_LIST_PTR fp = info->function_pointer; + CK_MECHANISM mechanism = { mech->mech, NULL_PTR, 0 }; + /* SoftHSM supports only SHA1 with OAEP encryption */ + CK_RSA_PKCS_OAEP_PARAMS oaep_params = {CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL, 0}; + CK_BYTE iv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + CK_AES_CTR_PARAMS ctr_params = { 64, {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CK_BYTE aad[] = {0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + CK_GCM_PARAMS gcm_params = { + .pIv = (void *)iv, + .ulIvLen = 16, + .ulIvBits = 64, + .pAAD = aad, /* TODO: SoftHSM crashes without AAD */ + .ulAADLen = sizeof(aad), + .ulTagBits = 128, + }; + //unsigned char key[16]; + CK_BYTE *wrapped = NULL; + CK_ULONG wrapped_len = 0; + CK_BYTE *plain = NULL; + CK_ULONG plain_len = 0; + CK_RV rv; + + if (o->private_handle == CK_INVALID_HANDLE) { + debug_print(" [SKIP %s ] Missing private key", o->id_str); + return 1; + } + + if (o->key_type != CKK_RSA && o->key_type != CKK_AES) { + debug_print(" [ KEY %s ] Skip non-RSA and non-AES key for wrapping", o->id_str); + return 1; + } + + debug_print(" [ KEY %s ] Wrap a key [%s] using CKM_%s", o->id_str, key->id_str, + get_mechanism_name(mech->mech)); + /* RSA mechanisms */ + if (mech->mech == CKM_RSA_X_509) { + if (o->bits < key->bits) { + debug_print(" [SKIP %s ] The wrapping key too small", o->id_str); + return 1; + } + } else if (mech->mech == CKM_RSA_PKCS) { + if (o->bits - 11 < key->bits) { + debug_print(" [SKIP %s ] The wrapping key too small", o->id_str); + return 1; + } + } else if (mech->mech == CKM_RSA_PKCS_OAEP) { + if (o->bits - 2 - 2*SHA_DIGEST_LENGTH < key->bits) { + debug_print(" [SKIP %s ] The wrapping key too small", o->id_str); + return 1; + } + mech->params = &oaep_params; + mech->params_len = sizeof(oaep_params); + /* AES mechanisms */ + } else if (mech->mech == CKM_AES_CBC || mech->mech == CKM_AES_CBC_PAD || mech->mech == CKM_AES_ECB) { + mech->params = &iv; + mech->params_len = sizeof(iv); + } else if (mech->mech == CKM_AES_CTR) { + mech->params = &ctr_params; + mech->params_len = sizeof(ctr_params); + } else if (mech->mech == CKM_AES_GCM) { + mech->params = &gcm_params; + mech->params_len = sizeof(gcm_params); + } else if (mech->mech == CKM_AES_KEY_WRAP || mech->mech == CKM_AES_KEY_WRAP_PAD) { + /* Nothing special ... */ + } else { + debug_print(" [ KEY %s ] Unknown wrapping mechanism %s", + o->id_str, get_mechanism_name(mech->mech)); + return 1; + } + + /* Get the wrapped size */ + mechanism.pParameter = mech->params; + mechanism.ulParameterLen = mech->params_len; + rv = fp->C_WrapKey(info->session_handle, &mechanism, o->public_handle, key->private_handle, + wrapped, &wrapped_len); + if (rv != CKR_OK) { + mech->params = NULL; + mech->params_len = 0; + fprintf(stderr, " C_WrapKey: rv = 0x%.8lX\n", rv); + return -1; + } + wrapped = malloc(wrapped_len); + if (wrapped == NULL) { + mech->params = NULL; + mech->params_len = 0; + fprintf(stderr, "%s: malloc failed", __func__); + return -1; + } + /* Wrap the key using public RSA key through PKCS#11 */ + rv = fp->C_WrapKey(info->session_handle, &mechanism, o->public_handle, key->private_handle, + wrapped, &wrapped_len); + if (rv != CKR_OK) { + mech->params = NULL; + mech->params_len = 0; + fprintf(stderr, " C_WrapKey: rv = 0x%.8lX\n", rv); + free(wrapped); + return -1; + } + + if (mech->mech == CKM_AES_KEY_WRAP || mech->mech == CKM_AES_KEY_WRAP_PAD) { + /* good enough for now -- I dont know how to check these */ + goto out; + } + /* OK, we have wrapped key. Now, check it is really the key on the card. + * We need to decipher the wrapped key with the wrapping key, which + * should be generally the reverse operation to the wrapping for the + * simple wrapping mechanisms and which should give us a plain key. + */ + rv = decrypt_message(o, info, wrapped, wrapped_len, mech, &plain); + free(wrapped); + mech->params = NULL; + mech->params_len = 0; + if (rv <= 0) { + debug_print(" [ KEY %s ] Unable to decrypt the wrapped key", o->id_str); + return -1; + } + plain_len = rv; + /* + * Then we need need to check it against something to make sure we have + * the right key. There are two ways: + * 1) The key is publicly readable through CKA_VALUE (not the case most of the time) + * 2) We encrypt something with a assumed key and decrypt it with the card key + */ + if (key->value) { +/* + if (plain_len == key->bits/8 && memcmp(plain, key->value, plain_len) == 0) { + debug_print(" [ OK %s ] Wrapped key recovered correctly", o->id_str); + } else { + fprintf(stderr, " [ ERROR %s ] Wrapped key does not match\n", o->id_str); + return -1; + } + } else {*/ + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + const EVP_CIPHER *cipher = NULL; + unsigned char plaintext[42]; + int plaintext_len = sizeof(plaintext); + unsigned char ciphertext[100]; + int ciphertext_len = sizeof(ciphertext); + test_mech_t aes_mech = {.mech = CKM_AES_CBC, .params = &iv, .params_len = sizeof(iv)}; + unsigned char *check = NULL; + int check_len = 0; + int rv, len; + + /* First, do the encryption dance with OpenSSL */ + if (ctx == NULL) { + fprintf(stderr, " EVP_CIPHER_CTX_new failed\n"); + return -1; + } + + rv = RAND_bytes(plaintext, plaintext_len); + if (rv != 1) { + fprintf(stderr, " RAND_bytes failed\n"); + return -1; + } + + if (key->key_type != CKK_AES) { + debug_print(" [SKIP %s ] Only AES for now", o->id_str); + return 1; + } + if (plain_len == 32) { + cipher = EVP_aes_256_cbc(); + } else if (plain_len == 16) { + cipher = EVP_aes_128_cbc(); + } else { + fprintf(stderr, " Invalid key length %lu", plain_len); + return -1; + } + rv = EVP_EncryptInit_ex(ctx, cipher, NULL, plain, iv); + if (rv != 1) { + fprintf(stderr, " EVP_EncryptInit_ex failed\n"); + return -1; + } + rv = EVP_EncryptUpdate(ctx, ciphertext, &ciphertext_len, plaintext, plaintext_len); + if (rv != 1) { + fprintf(stderr, " EVP_EncryptUpdate failed\n"); + return -1; + } + rv = EVP_EncryptFinal_ex(ctx, ciphertext + ciphertext_len, &len); + if (rv != 1) { + fprintf(stderr, " EVP_EncryptFinal_ex failed\n"); + return -1; + } + ciphertext_len += len; + /* Now, decrypt with the PKCS#11 */ + check_len = decrypt_message(key, info, ciphertext, ciphertext_len, &aes_mech, &check); + + check_len = strip_pkcs7_padding(check, check_len, 16); + if (check_len <= 0) { + fprintf(stderr, " Failed to strip PKCS#7 padding\n"); + return -1; + } + if (check_len == plaintext_len && memcmp(plaintext, check, plaintext_len) == 0) { + debug_print(" [ OK %s ] Decrypted message matches", o->id_str); + } else { + printf(" [ ERROR %s ] Decrypted message does not match (%d, %d)\n", o->id_str, + check_len, plaintext_len); + printf("\nplaintext:\n"); + for (int i = 0; i < plaintext_len; i++) { + printf(":%x", plaintext[i]); + } + printf("\ncheck:\n"); + for (int i = 0; i < check_len; i++) { + printf(":%x", check[i]); + } + printf("\n"); + return -1; + } + } + +out: + debug_print(" [ OK %s ] Key wrapping works.", o->id_str); + if (key->key_type == CKK_AES) { + mech->result_flags |= FLAGS_WRAP_SYM; + } else { + mech->result_flags |= FLAGS_WRAP; + } + return 0; +} + +void wrap_tests(void **state) +{ + unsigned int i; + int j; + int errors = 0; + token_info_t *info = (token_info_t *) *state; + test_certs_t objects; + test_cert_t *aes_key = NULL, *aes2_key = NULL; + test_cert_t *rsa_key = NULL, *rsa2_key = NULL; + + test_certs_init(&objects); + + P11TEST_START(info); + search_for_all_objects(&objects, info); + + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + if (aes_key == NULL && o->key_type == CKK_AES && o->extractable) { + aes_key = o; + } else if (aes2_key == NULL && o->key_type == CKK_AES && o->extractable) { + aes2_key = o; + } else if (rsa_key == NULL && o->key_type == CKK_RSA && o->extractable) { + rsa_key = o; + } else if (rsa2_key == NULL && o->key_type == CKK_RSA && o->extractable) { + rsa2_key = o; + } + } + + debug_print("Check if the wrap operation works.\n"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + /* Ignore if there is missing private key */ + if (o->private_handle == CK_INVALID_HANDLE) + continue; + + for (j = 0; j < o->num_mechs; j++) { + /* + if ((o->mechs[j].usage_flags & CKF_WRAP) == 0 || !o->wrap) + continue; + if ((o->mechs[j].usage_flags & CKF_UNWRAP) == 0 || !o->unwrap) + continue; + */ + if ((o->mechs[j].usage_flags & (CKF_WRAP|CKF_UNWRAP)) == 0) + continue; + + switch (o->key_type) { + case CKK_RSA: + /* We probably can not wrap one key with itself */ + if (rsa_key && o != rsa_key) { + errors += test_wrap(o, info, rsa_key, &(o->mechs[j])); + } else if (rsa2_key && o != rsa2_key) { + errors += test_wrap(o, info, rsa2_key, &(o->mechs[j])); + } + if (aes_key) { + errors += test_wrap(o, info, aes_key, &(o->mechs[j])); + } + break; + case CKK_AES: + /* We probably can not wrap one key with itself */ + if (aes_key && o != aes_key) { + errors += test_wrap(o, info, aes_key, &(o->mechs[j])); + } else if (aes2_key && o != aes2_key) { + errors += test_wrap(o, info, aes2_key, &(o->mechs[j])); + } + if (rsa_key) { + errors += test_wrap(o, info, rsa_key, &(o->mechs[j])); + } + break; + default: + /* Other keys do not support derivation */ + break; + } + } + } + + /* print summary */ + printf("[KEY ID] [EXTRACTABLE] [LABEL]\n"); + printf("[ TYPE ] [ SIZE ] [ WRAP ] [UNWRAP]\n"); + P11TEST_DATA_ROW(info, 4, + 's', "KEY ID", + 's', "MECHANISM", + 's', "WRAP WORKS", + 's', "UNWRAP WORKS"); + for (i = 0; i < objects.count; i++) { + test_cert_t *o = &objects.data[i]; + if (o->key_type != CKK_RSA && o->key_type != CKK_AES) + continue; + + printf("\n[%-6s] [ %s ] [%s]\n", + o->id_str, + o->extractable ? "./" : " ", + o->label); + printf("[ %s ] [%6lu] [ [%s] ] [ [%s] ]\n", + (o->key_type == CKK_RSA ? "RSA " : + o->key_type == CKK_AES ? "AES " : " ?? "), + o->bits, + o->wrap ? "./" : " ", + o->unwrap ? "./" : " "); + /* the attributes are sometimes confusing + if (!o->wrap && !o->unwrap) { + printf(" no usable attributes found ... ignored\n"); + continue; + } */ + if (o->private_handle == CK_INVALID_HANDLE) { + continue; + } + for (j = 0; j < o->num_mechs; j++) { + test_mech_t *mech = &o->mechs[j]; + if ((mech->usage_flags & (CKF_WRAP | CKF_UNWRAP)) == 0) { + /* not applicable mechanisms are skipped */ + continue; + } + printf(" [ %-24s ] [%s][%s] [%s][%s]\n", + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_WRAP_SYM ? "./" : " ", + mech->result_flags & FLAGS_WRAP ? "./" : " ", + mech->result_flags & FLAGS_UNWRAP_SYM ? "./" : " ", + mech->result_flags & FLAGS_UNWRAP ? "./" : " "); + if ((mech->result_flags & (FLAGS_WRAP | FLAGS_UNWRAP)) == 0) + continue; /* skip empty rows for export */ + P11TEST_DATA_ROW(info, 6, + 's', o->id_str, + 's', get_mechanism_name(mech->mech), + 's', mech->result_flags & FLAGS_WRAP_SYM ? "YES" : "", + 's', mech->result_flags & FLAGS_WRAP ? "YES" : "", + 's', mech->result_flags & FLAGS_UNWRAP_SYM ? "YES" : "", + 's', mech->result_flags & FLAGS_UNWRAP ? "YES" : ""); + } + } + printf(" Wrapping symmetric key works --^ ^ ^ ^- Unwrapping asymmetric key works\n"); + printf(" Wrapping asymmetric key works -----' '------- Unwrapping symmetric key works\n"); + + clean_all_objects(&objects); + if (errors > 0) + P11TEST_FAIL(info, "Not all the wrap/unwrap mechanisms worked."); + P11TEST_PASS(info); +} diff --git a/src/tests/p11test/p11test_case_wrap.h b/src/tests/p11test/p11test_case_wrap.h new file mode 100644 index 0000000000..2e861a2b7a --- /dev/null +++ b/src/tests/p11test/p11test_case_wrap.h @@ -0,0 +1,27 @@ +/* + * p11test_case_wrap.h: Check the functionality of wrap mechanisms + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Jakub Jelen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "p11test_case_common.h" +#include "p11test_case_readonly.h" + +void wrap_tests(void **state); + + diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index 450856723e..0f921b83cb 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -40,13 +40,17 @@ } \ } while (0) -#define FLAGS_SIGN 0x01 -#define FLAGS_SIGN_OPENSSL 0x02 +#define FLAGS_SIGN 0x001 +#define FLAGS_SIGN_OPENSSL 0x002 #define FLAGS_SIGN_ANY ( FLAGS_SIGN | FLAGS_SIGN_OPENSSL ) -#define FLAGS_DECRYPT 0x04 -#define FLAGS_DECRYPT_OPENSSL 0x08 +#define FLAGS_DECRYPT 0x004 +#define FLAGS_DECRYPT_OPENSSL 0x008 #define FLAGS_DECRYPT_ANY ( FLAGS_DECRYPT | FLAGS_DECRYPT_OPENSSL ) -#define FLAGS_DERIVE 0x10 +#define FLAGS_DERIVE 0x010 +#define FLAGS_WRAP 0x020 +#define FLAGS_WRAP_SYM 0x040 +#define FLAGS_UNWRAP 0x080 +#define FLAGS_UNWRAP_SYM 0x100 typedef struct { char *outfile; diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index fd875eab4b..84e18cf6d2 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -50,7 +50,7 @@ function generate_cert() { # Generate key pair $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --module="$P11LIB" --label="$LABEL" --id=$ID + --extractable --module="$P11LIB" --label="$LABEL" --id=$ID if [[ "$?" -ne "0" ]]; then echo "Couldn't generate $TYPE key pair" @@ -175,9 +175,9 @@ make p11test || exit if [[ "$PKCS11SPY" != "" ]]; then export PKCS11SPY="$P11LIB" $VALGRIND ./p11test -m ../../pkcs11/.libs/pkcs11-spy.so -p $PIN &> /tmp/spy.log + echo "Output stored in /tmp/spy.log" else - #bash - $VALGRIND ./p11test -m "$P11LIB" -o test.json -p $PIN + $VALGRIND ./p11test -v -m "$P11LIB" -o test.json -p $PIN fi card_cleanup "$@" From 77491706a80b80715adddcff50742c2e6a8f64bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:39:36 +0100 Subject: [PATCH 2134/4321] p11test: Make the openssl support more configurable --- src/tests/p11test/p11test.c | 2 ++ src/tests/p11test/p11test_case_readonly.c | 12 +++++------- src/tests/p11test/p11test_case_secret.c | 4 ++++ src/tests/p11test/p11test_common.h | 3 +++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 1db23bfb6b..4c73a1758b 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -106,6 +106,8 @@ int main(int argc, char** argv) { /* Make sure it is initialized to sensible values */ memset(&token, 0, sizeof(token_info_t)); token.slot_id = (unsigned long) -1; + token.verify_support = 1; + token.encrypt_support = 1; while ((command = getopt(argc, argv, "?hm:s:p:io:v")) != -1) { switch (command) { diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 858b81b43c..7b42e3c40d 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -105,16 +105,15 @@ int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_FUNCTION_LIST_PTR fp = info->function_pointer; CK_MECHANISM enc_mechanism = { mech->mech, mech->params, mech->params_len }; CK_ULONG enc_message_length; - static int encrypt_support = 1; - if (!encrypt_support) + if (!info->encrypt_support) goto openssl_encrypt; rv = fp->C_EncryptInit(info->session_handle, &enc_mechanism, o->public_handle); if (rv != CKR_OK) { debug_print(" C_EncryptInit: rv = 0x%.8lX", rv); - encrypt_support = 0; /* avoid trying over and over again */ + info->encrypt_support = 0; /* avoid trying over and over again */ goto openssl_encrypt; } @@ -520,10 +519,9 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; - static int verify_support = 1; char *name; - if (!verify_support) + if (!info->verify_support) goto openssl_verify; /* try C_Verify() if it is supported */ @@ -531,7 +529,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, o->public_handle); if (rv != CKR_OK) { debug_print(" C_VerifyInit: rv = 0x%.8lX", rv); - verify_support = 0; /* avoid trying over and over again */ + info->verify_support = 0; /* avoid trying over and over again */ goto openssl_verify; } if (multipart) { @@ -564,7 +562,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, return 1; } debug_print(" %s: rv = 0x%.8lX", name, rv); - verify_support = 0; /* avoid trying over and over again */ + info->verify_support = 0; /* avoid trying over and over again */ openssl_verify: debug_print(" [ KEY %s ] Falling back to openssl verification", o->id_str); diff --git a/src/tests/p11test/p11test_case_secret.c b/src/tests/p11test/p11test_case_secret.c index 48fe5b9176..84cf4a463d 100644 --- a/src/tests/p11test/p11test_case_secret.c +++ b/src/tests/p11test/p11test_case_secret.c @@ -230,6 +230,10 @@ void secret_tests(void **state) P11TEST_START(info); search_for_all_objects(&objects, info); + /* Make sure to try the pkcs11 functions */ + info->verify_support = 1; + info->encrypt_support = 1; + debug_print("Check operations on secret keys.\n"); for (i = 0; i < objects.count; i++) { test_cert_t *o = &objects.data[i]; diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index 0f921b83cb..f30e889198 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -84,6 +84,9 @@ typedef struct { unsigned int interactive; log_context_t log; + int verify_support; + int encrypt_support; + test_mech_t rsa_mechs[MAX_MECHS]; size_t num_rsa_mechs; test_mech_t ec_mechs[MAX_MECHS]; From 8bf399ec0ce6c1cf71f642430e226b6ea971523d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:40:31 +0100 Subject: [PATCH 2135/4321] p11test: Automate setup for MyEID card --- src/tests/p11test/runtest.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index 84e18cf6d2..ae5e97b1ef 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -24,6 +24,7 @@ PIN="123456" export GNUTLS_PIN=$PIN GENERATE_KEYS=1 PKCS11_TOOL="../../tools/pkcs11-tool"; +PKCS15_INIT="../../tools/pkcs15-init"; function generate_sym() { TYPE="$1" @@ -126,10 +127,22 @@ function card_setup() { P11LIB="../pkcs11/.libs/opensc-pkcs11.so" fi ;; + "myeid") + GENERATE_KEYS=0 # we generate them directly here + P11LIB="../pkcs11/.libs/opensc-pkcs11.so" + PKCS15_INIT --erase-card --so-pin $SOPIN + PKCS15_INIT -C --pin $PIN --puk $SOPIN --so-pin $SOPIN --so-puk $SOPIN + PKCS15_INIT -P -a 1 -l "Basic PIN" --pin $PIN --puk $PIN + INIT=$PKCS15_INIT --auth-id 01 --so-pin $SOPIN --pin $PIN + INIT --generate-key ec:prime256v1 --id 01 --label="EC key" + INIT --generate-key rsa:2048 --id 02 --label="RSA key" --key-usage=sign,decrypt + INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES key" --key-usage=sign,decrypt + PKCS15_INIT -F + ;; *) echo "Error: Missing argument." echo " Usage:" - echo " runtest.sh [softhsm|opencryptoki|readonly [pkcs-library.so]]" + echo " runtest.sh [softhsm|opencryptoki|myeid|readonly [pkcs-library.so]]" exit 1; ;; esac From f6d28c4d171083c99b6ed5068be6be9dcaf4abfb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:41:03 +0100 Subject: [PATCH 2136/4321] Add new missing pkcs11 definitions --- src/pkcs11/pkcs11.h | 9 +++++++++ src/tests/p11test/p11test_case_common.c | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 78b5b72789..05710d12af 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -581,6 +581,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_DES3_MAC (0x134UL) #define CKM_DES3_MAC_GENERAL (0x135UL) #define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC_GENERAL (0x137UL) #define CKM_DES3_CMAC (0x138UL) #define CKM_CDMF_KEY_GEN (0x140UL) #define CKM_CDMF_ECB (0x141UL) @@ -827,6 +828,14 @@ struct ck_mechanism_info }; #define CKF_HW (1UL << 0) + +#define CKF_MESSAGE_ENCRYPT (1UL << 1) +#define CKF_MESSAGE_DECRYPT (1UL << 2) +#define CKF_MESSAGE_SIGN (1UL << 3) +#define CKF_MESSAGE_VERIFY (1UL << 4) +#define CKF_MULTI_MESSAGE (1UL << 5) +#define CKF_FIND_OBJECTS (1UL << 6) + #define CKF_ENCRYPT (1UL << 8) #define CKF_DECRYPT (1UL << 9) #define CKF_DIGEST (1UL << 10) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 7d019aeddd..d7084c0787 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -1007,12 +1007,22 @@ const char *get_mechanism_name(int mech_id) return "DES3_CMAC"; case CKM_DES3_CMAC_GENERAL: return "DES3_CMAC_GENERAL"; + case CKM_DES3_ECB: + return "DES3_ECB"; + case CKM_DES3_CBC: + return "DES3_CBC"; + case CKM_DES3_CBC_PAD: + return "DES3_CBC_PAD"; + case CKM_DES3_CBC_ENCRYPT_DATA: + return "DES3_CBC_ENCRYPT_DATA"; case CKM_AES_XCBC_MAC: return "AES_XCBC_MAC"; case CKM_AES_XCBC_MAC_96: return "AES_XCBC_MAC_96"; case CKM_AES_KEY_WRAP: return "AES_KEY_WRAP"; + case CKM_AES_KEY_WRAP_PAD: + return "AES_KEY_WRAP_PAD"; default: sprintf(name_buffer, "0x%.8X", mech_id); return name_buffer; @@ -1043,6 +1053,16 @@ const char *get_mechanism_flag_name(int mech_id) switch (mech_id) { case CKF_HW: return "CKF_HW"; + case CKF_MESSAGE_ENCRYPT: + return "CKF_MESSAGE_ENCRYPT"; + case CKF_MESSAGE_DECRYPT: + return "CKF_MESSAGE_DECRYPT"; + case CKF_MESSAGE_SIGN: + return "CKF_MESSAGE_SIGN"; + case CKF_MESSAGE_VERIFY: + return "CKF_MESSAGE_VERIFY"; + case CKF_MULTI_MESSAGE: + return "CKF_MULTI_MESSAGE"; case CKF_ENCRYPT: return "CKF_ENCRYPT"; case CKF_DECRYPT: From 152b988c5a91eb4761734012d8fb7d0a53e3d830 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:41:21 +0100 Subject: [PATCH 2137/4321] p11test: Reformat --- src/tests/p11test/p11test.c | 1 - src/tests/p11test/p11test_case_readonly.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c index 4c73a1758b..777f6b6c3a 100644 --- a/src/tests/p11test/p11test.c +++ b/src/tests/p11test/p11test.c @@ -155,4 +155,3 @@ int main(int argc, char** argv) { return cmocka_run_group_tests(readonly_tests_without_initialization, group_setup, group_teardown); } - diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 7b42e3c40d..4bca8f542a 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -243,8 +243,8 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return -1; } - if (memcmp(dec_message, message, dec_message_length) == 0 - && (unsigned int) dec_message_length == message_length) { + if ((unsigned int) dec_message_length == message_length && + memcmp(dec_message, message, dec_message_length) == 0) { debug_print(" [ OK %s ] Text decrypted successfully.", o->id_str); mech->result_flags |= FLAGS_DECRYPT; rv = 1; From 4c042ad82fb96a7d6f4cb18e905640799d510a46 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Nov 2021 21:52:57 +0100 Subject: [PATCH 2138/4321] p11test: Update isoapplet and virt_cacard results for new tests --- src/tests/p11test/isoapplet_ref.json | 22 ++++++++++++++++++++++ src/tests/p11test/virt_cacard_ref.json | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/tests/p11test/isoapplet_ref.json b/src/tests/p11test/isoapplet_ref.json index b70f607588..8a922b6ce4 100644 --- a/src/tests/p11test/isoapplet_ref.json +++ b/src/tests/p11test/isoapplet_ref.json @@ -336,5 +336,27 @@ "DERIVE WORKS" ]], "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" }] } diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index ee451eaf07..ef74118bbb 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -1787,5 +1787,27 @@ "DERIVE WORKS" ]], "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" }] } From 23711b6136e64fe7d0364336d9194828c3b2c5b3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Dec 2021 11:56:02 +0100 Subject: [PATCH 2139/4321] .github: Upload test logs --- .github/workflows/linux.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 4aecd5ee7e..3fa1559c8b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -23,12 +23,18 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} - - name: Upload artifacts + - name: Upload build artifacts uses: actions/upload-artifact@v2 with: name: opensc-build path: opensc*.tar.gz + - name: Upload test logs + uses: actions/upload-artifact@v2 + with: + name: ubuntu-test-logs + path: + tests/*.log build-ix86: runs-on: ubuntu-latest @@ -48,6 +54,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-18-${{ github.sha }} + - name: Upload test logs + uses: actions/upload-artifact@v2 + with: + name: ubuntu-18-test-logs + path: + tests/*.log build-mingw: runs-on: ubuntu-latest From 61ec20d6da89399d2e23585708995b4a2003ffdb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 Dec 2021 14:48:38 +0100 Subject: [PATCH 2140/4321] doc: Cleanup pkcs15-tool manual page --- doc/tools/pkcs15-tool.1.xml | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/doc/tools/pkcs15-tool.1.xml b/doc/tools/pkcs15-tool.1.xml index 076b220e20..7d173ea0fc 100644 --- a/doc/tools/pkcs15-tool.1.xml +++ b/doc/tools/pkcs15-tool.1.xml @@ -38,7 +38,7 @@ - , + Print the OpenSC package release version. @@ -152,7 +152,7 @@ - + , Output lists in compact format. @@ -175,16 +175,6 @@ privileges). - - - - - Removes the user's cache directory. On - Windows, this option additionally removes the system's - caching directory (requires administrator - privileges). - - filename, @@ -216,7 +206,7 @@ - cert, + data, data Reads data object with OID, applicationName or label. @@ -262,7 +252,7 @@ , - , + Test if the card needs a security update @@ -270,7 +260,7 @@ , - , + Update the card with a security update @@ -311,7 +301,7 @@ pin, - newpin + newpin, puk From 75c3d1bffbd36f6692ba6efd1c71964bd2801b7e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 21 Dec 2021 14:46:23 +0100 Subject: [PATCH 2141/4321] Add ix86 build containerfile --- containers/opensc-build-ix86/Containerfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 containers/opensc-build-ix86/Containerfile diff --git a/containers/opensc-build-ix86/Containerfile b/containers/opensc-build-ix86/Containerfile new file mode 100644 index 0000000000..803b240fe2 --- /dev/null +++ b/containers/opensc-build-ix86/Containerfile @@ -0,0 +1,12 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh ix86 +CMD /src/.github/build.sh ix86 From 719c1cfe82133c47120690ddfc3c56e0f4b6bcd7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 21 Dec 2021 15:03:50 +0100 Subject: [PATCH 2142/4321] Try the actions/virtual-environments#4589 workaround also for ix86 build --- .github/setup-linux.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 27d9f076e7..f63e194515 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -25,10 +25,6 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " fi DEPS="$DEPS ant openjdk-8-jdk maven" elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then - # The Github's Ubuntu images since 20211122.1 are broken - # https://github.com/actions/virtual-environments/issues/4589 - sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 - # Note, that this list is somehow magic and adding libwine, libwine:i386 or wine64 # will make the following sections break without any useful logs. See GH#2458 DEPS="$DEPS wine wine32 xvfb wget" @@ -40,6 +36,12 @@ elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then fi fi +# The Github's Ubuntu images since 20211122.1 are broken +# https://github.com/actions/virtual-environments/issues/4589 +if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then + sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 +fi + # make sure we do not get prompts export DEBIAN_FRONTEND=noninteractive export DEBCONF_NONINTERACTIVE_SEEN=true From c96ec18ffd27d609f6b1fed9adfc905724ea29cc Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 13 Dec 2021 14:45:46 +0100 Subject: [PATCH 2143/4321] pkcs11-tool: fix build when HAVE_PTHREAD is not defined. --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 39e3765987..33804a38ce 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -263,8 +263,8 @@ static const struct option options[] = { #ifndef _WIN32 { "test-fork", 0, NULL, OPT_TEST_FORK }, #endif - { "use-locking", 0, NULL, OPT_USE_LOCKING }, #if defined(_WIN32) || defined(HAVE_PTHREAD) + { "use-locking", 0, NULL, OPT_USE_LOCKING }, { "test-threads", 1, NULL, OPT_TEST_THREADS }, #endif { "generate-random", 1, NULL, OPT_GENERATE_RANDOM }, @@ -1050,10 +1050,10 @@ int main(int argc, char * argv[]) action_count++; break; #endif +#if defined(_WIN32) || defined(HAVE_PTHREAD) case OPT_USE_LOCKING: c_initialize_args_ptr = &c_initialize_args_OS; break; -#if defined(_WIN32) || defined(HAVE_PTHREAD) case OPT_TEST_THREADS: do_test_threads = 1; if (test_threads_num < MAX_TEST_THREADS) { From 665e5c786afa1999f325fab921315e9905e1c5e7 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 27 Dec 2021 13:52:23 +0100 Subject: [PATCH 2144/4321] OAEP (RFC8017) padding check/removal If the card does not support OAEP, but RSA RAW operation is available, OAEP padding check/removal is now supported by the software. --- src/libopensc/internal.h | 4 + src/libopensc/padding.c | 137 +++++++++++++++++++++++++++++++++- src/libopensc/pkcs15-sec.c | 9 ++- src/pkcs11/framework-pkcs15.c | 2 +- 4 files changed, 149 insertions(+), 3 deletions(-) diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index e7ac63ccf2..1f7e99ef49 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -170,6 +170,10 @@ int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len u8 *out_dat, size_t *out_len); int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len); +#ifdef ENABLE_OPENSSL +int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, + unsigned long flags); +#endif /** * PKCS1 encodes the given data. diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index e4940ea2b5..a0cd18b74d 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -184,6 +184,139 @@ sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out LOG_FUNC_RETURN(ctx, len - n); } +#ifdef ENABLE_OPENSSL +static int mgf1(u8 *mask, size_t len, u8 *seed, size_t seedLen, const EVP_MD *dgst) +{ + int i; + size_t outlen = 0; + u8 cnt[4]; + EVP_MD_CTX *md_ctx = NULL; + int mdlen; + u8 md[EVP_MAX_MD_SIZE]; + int rv = 1; + + if (!(md_ctx = EVP_MD_CTX_new())) + goto out; + + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + goto out; + + for (i = 0; outlen < len; i++) { + cnt[0] = (u8) ((i >> 24) & 255); + cnt[1] = (u8) ((i >> 16) & 255); + cnt[2] = (u8) ((i >> 8) & 255); + cnt[3] = (u8) ((i >> 0) & 255); + if (!EVP_DigestInit_ex(md_ctx, dgst, NULL) + || !EVP_DigestUpdate(md_ctx, seed, seedLen) + || !EVP_DigestUpdate(md_ctx, cnt, 4)) + goto out; + if (outlen + mdlen <= len) { + if (!EVP_DigestFinal_ex(md_ctx, mask + outlen, NULL)) + goto out; + outlen += mdlen; + } else { + if (!EVP_DigestFinal_ex(md_ctx, md, NULL)) + goto out; + memcpy(mask + outlen, md, len - outlen); + outlen = len; + } + } + rv = 0; + out: + OPENSSL_cleanse(md, sizeof(md)); + if (md_ctx) + EVP_MD_CTX_free(md_ctx); + return rv; +} + +/* forward declarations */ +static const EVP_MD *mgf1_flag2md(unsigned int mgf1); +static const EVP_MD *hash_flag2md(unsigned int hash); + +/* check/remove OAEP - RFC 8017 padding */ +int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigned long flags) +{ + size_t i,j; + size_t mdlen, dblen; + u8 seed[EVP_MAX_MD_SIZE]; + const EVP_MD *mgf1_md, *hash_md; + u8 db[512]; /* up to RSA 4096 */ + u8 label[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *md_ctx; + unsigned int hash_len = 0; + + LOG_FUNC_CALLED(ctx); + if (data == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + + /* + * https://www.rfc-editor.org/rfc/pdfrfc/rfc8017.txt.pdf, page 26, 3.a. + * there is no implementation for label "L" (empty string for now) + */ + hash_md = hash_flag2md(flags); + if (!hash_md) + return SC_ERROR_NOT_SUPPORTED; + + memset(label, 0, sizeof(label)); + if ((md_ctx = EVP_MD_CTX_new())) { + if (!EVP_DigestInit_ex(md_ctx, hash_md, NULL) + || !EVP_DigestUpdate(md_ctx, label, 0) + || !EVP_DigestFinal_ex(md_ctx, label, &hash_len)) + hash_len = 0; + EVP_MD_CTX_free(md_ctx); + } + if (!hash_len) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + + mgf1_md = mgf1_flag2md(flags); + if (!mgf1_md) + return SC_ERROR_NOT_SUPPORTED; + + mdlen = EVP_MD_size(mgf1_md); + + if (len < 2 * mdlen + 2) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + + if (*data != 0) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + + dblen = len - 1 - mdlen; + if (dblen > sizeof(db)) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + + if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + for (i = 0; i < mdlen; i++) + seed[i] ^= data[i + 1]; + + if (mgf1(db, dblen, seed, mdlen, mgf1_md)) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + for (i = 0; i < dblen; i++) { + db[i] ^= data[i + mdlen + 1]; + /* clear lHash' if same as lHash */ + if (i < hash_len) + db[i] ^= label[i]; + } + /* if the padding is correct, it is a concatenation: + * 00...00 || 01 || plaintext + * check padding but do not leak information about error: + */ + for (j = 0, i = 0; i < dblen;) { + j += db[i++] + 1; + if (i > mdlen) { + if (j == i + 1) { + /* OK correct padding found */ + len = dblen - i; + memcpy(data, db + i, len); + LOG_FUNC_RETURN(ctx, len); + } + } + } + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); +} +#endif + /* add/remove DigestInfo prefix */ static int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm, const u8 *in, size_t in_len, u8 *out, size_t *out_len) @@ -497,11 +630,13 @@ int sc_get_encoding_flags(sc_context_t *ctx, } else if ((caps & SC_ALGORITHM_RSA_RAW) && (iflags & SC_ALGORITHM_RSA_PAD_PKCS1 || iflags & SC_ALGORITHM_RSA_PAD_PSS +#ifdef ENABLE_OPENSSL + || iflags & SC_ALGORITHM_RSA_PAD_OAEP +#endif || iflags & SC_ALGORITHM_RSA_PAD_NONE)) { /* Use the card's raw RSA capability on the padded input */ *sflags = SC_ALGORITHM_RSA_PAD_NONE; *pflags = iflags; - /* TODO emulate the OAEP decryption */ } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 24c5242b43..0234176078 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -312,7 +312,14 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s); LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding"); } - +#ifdef ENABLE_OPENSSL + if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) + { + size_t s = r; + r = sc_pkcs1_strip_oaep_padding(ctx, out, s, flags); + LOG_TEST_RET(ctx, r, "Invalid OAEP padding"); + } +#endif LOG_FUNC_RETURN(ctx, r); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 75e859b408..c01f9f7630 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6251,7 +6251,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) rsa_flags |= SC_ALGORITHM_RSA_PAD_PKCS1; #ifdef ENABLE_OPENSSL rsa_flags |= SC_ALGORITHM_RSA_PAD_PSS; - /* TODO support OAEP decryption & encryption using OpenSSL */ + rsa_flags |= SC_ALGORITHM_RSA_PAD_OAEP; #endif } From 4653d7072df8e6a2940787cf7049170d4621ea2e Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 3 Jan 2022 20:07:56 +0100 Subject: [PATCH 2145/4321] virt_cacard_ref.json update: OAEP decrypt modified: src/tests/p11test/virt_cacard_ref.json --- src/tests/p11test/virt_cacard_ref.json | 141 +++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index ef74118bbb..d715c1c642 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -151,6 +151,12 @@ "1024", "3072", "0x00002800" + ], + [ + "RSA_PKCS_OAEP", + "1024", + "3072", + "0x00000201" ]], "result": "pass" }, @@ -966,6 +972,51 @@ "YES", "" ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], [ "00:02", "RSA_PKCS_PSS", @@ -1371,6 +1422,51 @@ "YES", "" ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], [ "00:03", "RSA_PKCS_PSS", @@ -1775,6 +1871,51 @@ "-1", "YES", "" + ], + [ + "00:03", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "00:03", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "00:03", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "00:03", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "00:03", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" ]], "result": "pass" }, From 0a7be07a715aa2589250d4fe3a0f953f5b5e4976 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Oct 2021 00:27:09 +0200 Subject: [PATCH 2146/4321] nPA: simplify/unbreak card detection Some cards don't accept selection from MF (P1=08), but only relative selection (P1=02). This breaks the default implementation of sc_enum_apps() for those cards. Use a default EF.DIR for detection and initializing the card's apps. --- src/libopensc/card-npa.c | 102 +++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 5fe505598e..b5ec070ebf 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -136,51 +136,33 @@ static int npa_load_options(sc_context_t *ctx, struct npa_drv_data *drv_data) return r; } +unsigned char dir_content_ref[] = { + 0x61, 0x32, 0x4F, 0x0F, 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, + 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, 0x50, 0x0F, 0x43, 0x49, 0x41, + 0x20, 0x7A, 0x75, 0x20, 0x44, 0x46, 0x2E, 0x65, 0x53, 0x69, 0x67, 0x6E, + 0x51, 0x00, 0x73, 0x0C, 0x4F, 0x0A, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, + 0x53, 0x49, 0x47, 0x4E, 0x61, 0x09, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x02, + 0x47, 0x10, 0x01, 0x61, 0x0B, 0x4F, 0x09, 0xE8, 0x07, 0x04, 0x00, 0x7F, + 0x00, 0x07, 0x03, 0x02, 0x61, 0x0C, 0x4F, 0x0A, 0xA0, 0x00, 0x00, 0x01, + 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, +}; + static int npa_match_card(sc_card_t * card) { - int r = 0; - - if (SC_SUCCESS == sc_enum_apps(card)) { - unsigned char esign_aid_0[] = { - 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, - }, esign_aid_1[] = { - 0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01, - }, esign_aid_2[] = { - 0xe8, 0x07, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x02, - }, esign_aid_3[] = { - 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, - }; - int i, found_0 = 0, found_1 = 0, found_2 = 0, found_3 = 0; - for (i = 0; i < card->app_count; i++) { - struct sc_app_info *app_info = card->app[i]; - if (sizeof esign_aid_0 == app_info->aid.len - && 0 == memcmp(esign_aid_0, app_info->aid.value, - sizeof esign_aid_0)) - found_0 = 1; - if (sizeof esign_aid_1 == app_info->aid.len - && 0 == memcmp(esign_aid_1, app_info->aid.value, - sizeof esign_aid_1)) - found_1 = 1; - if (sizeof esign_aid_2 == app_info->aid.len - && 0 == memcmp(esign_aid_2, app_info->aid.value, - sizeof esign_aid_2)) - found_2 = 1; - if (sizeof esign_aid_3 == app_info->aid.len - && 0 == memcmp(esign_aid_3, app_info->aid.value, - sizeof esign_aid_3)) - found_3 = 1; - } - if (found_0 && found_1 && found_2 && found_3) { - card->type = SC_CARD_TYPE_NPA; - r = 1; - } - } + unsigned char dir_content[sizeof dir_content_ref]; + unsigned char id[] = {0x2F, 0x00}; + sc_apdu_t select_ef_dir; - if (r == 0) { - sc_free_apps(card); - } + sc_format_apdu_ex(&select_ef_dir, 0x00, 0xA4, 0x02, 0x0C, id, sizeof id, NULL, 0); - return r; + if (SC_SUCCESS == sc_select_file(card, sc_get_mf_path(), NULL) + && SC_SUCCESS == sc_transmit_apdu(card, &select_ef_dir) + && select_ef_dir.sw1 == 0x90 && select_ef_dir.sw2 == 0x00 + && sizeof dir_content == sc_read_binary(card, 0, dir_content, sizeof dir_content, 0) + && 0 == memcmp(dir_content_ref, dir_content, sizeof dir_content)) + return 1; + + return 0; } static void npa_get_cached_pace_params(sc_card_t *card, @@ -369,6 +351,42 @@ static int npa_finish(sc_card_t * card) return SC_SUCCESS; } +static void npa_init_apps(sc_card_t * card) +{ + /* this initializes the internal structures with the data from + * `dir_content_ref` */ + const u8 *aids[] = { + (const u8 *) "\xa0\x00\x00\x02\x47\x10\x01", + (const u8 *) "\xe8\x07\x04\x00\x7f\x00\x07\x03\x02", + (const u8 *) "\xa0\x00\x00\x01\x67\x45\x53\x49\x47\x4e", + }; + const size_t lens[] = {7, 9, 10}; + size_t i; + + sc_free_apps(card); + card->app_count = 0; + + for (i = 0; i < 3; i++) { + const u8 *aid = aids[i]; + size_t aid_len = lens[i]; + struct sc_app_info *app = calloc(1, sizeof *app); + if (NULL == app) + continue; + + app->aid.len = aid_len; + memcpy(app->aid.value, aid, aid_len); + + app->path.len = aid_len; + memcpy(app->path.value, aid, aid_len); + app->path.type = SC_PATH_TYPE_DF_NAME; + + app->rec_nr = -1; + + card->app[card->app_count] = app; + card->app_count++; + } +} + static int npa_init(sc_card_t * card) { int flags = SC_ALGORITHM_ECDSA_RAW; @@ -415,6 +433,8 @@ static int npa_init(sc_card_t * card) if (r != SC_SUCCESS) goto err; + npa_init_apps(card); + /* unlock the eSign application for reading the certificates * by the PKCS#15 layer (i.e. sc_pkcs15_bind_internal) */ if (SC_SUCCESS != npa_unlock_esign(card)) { From 8f2a653419d767ac31c687eb884b84727f922d27 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 26 Oct 2021 00:58:29 +0200 Subject: [PATCH 2147/4321] iso7816: don't let sc_read_binary into the way of iso7816_read_binary_sfid fixes ignoring 6282 due to automatic retry of reading the requested number of bytes in sc_read_binary --- src/libopensc/iso7816.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 55edb676fd..3c54266db1 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1378,7 +1378,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0 && r != SC_ERROR_FILE_END_REACHED) goto err; - /* emulate the behaviour of sc_read_binary */ + /* emulate the behaviour of iso7816_read_binary */ r = apdu.resplen; while(1) { @@ -1401,7 +1401,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, } *ef = p; - r = sc_read_binary(card, *ef_len, + r = iso7816_read_binary(card, *ef_len, *ef + *ef_len, read, 0); } From de8fa080de797d0792154f3047e7587c0298f216 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 13 Dec 2021 08:29:50 +0100 Subject: [PATCH 2148/4321] npa-tool: add error message if OpenPACE is missing --- src/tools/npa-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 65ab73a02e..7db77fe70d 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -859,9 +859,13 @@ main (int argc, char **argv) return -r; } #else + +#include + int main (int argc, char **argv) { + fprintf(stderr, "OpenPACE is needed for npa-tool"); return 1; } #endif From 7dc966b561834b574e784c8e96cca387fa6d7e83 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 14 Dec 2021 00:33:31 +0100 Subject: [PATCH 2149/4321] avoid strict aliasing problems --- src/sm/sm-eac.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 8c12119a30..397375fae2 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1164,8 +1164,9 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - r = eac_gen_auth_1_encrypted_nonce(card, (u8 **) &enc_nonce->data, - &enc_nonce->length); + p = (u8 *) enc_nonce->data; + r = eac_gen_auth_1_encrypted_nonce(card, &p, &enc_nonce->length); + enc_nonce->data = (char *) p; if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get encrypted nonce from card " "(General Authenticate step 1 failed)."); @@ -1198,8 +1199,10 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } + p = (u8 *) mdata_opp->data; r = eac_gen_auth_2_map_nonce(card, (u8 *) mdata->data, mdata->length, - (u8 **) &mdata_opp->data, &mdata_opp->length); + &p, &mdata_opp->length); + mdata_opp->data = (char *) p; if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange mapping data with card " "(General Authenticate step 2 failed)."); @@ -1224,8 +1227,10 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } + p = (u8 *) pub_opp->data; r = eac_gen_auth_3_perform_key_agreement(card, (u8 *) pub->data, pub->length, - (u8 **) &pub_opp->data, &pub_opp->length); + &p, &pub_opp->length); + pub_opp->data = (char *) p; if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange ephemeral public key with card " "(General Authenticate step 3 failed)."); @@ -1251,10 +1256,12 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } + p = (u8 *) token_opp->data; r = eac_gen_auth_4_mutual_authentication(card, (u8 *) token->data, token->length, - (u8 **) &token_opp->data, &token_opp->length, + &p, &token_opp->length, &pace_output->recent_car, &pace_output->recent_car_length, &pace_output->previous_car, &pace_output->previous_car_length); + token_opp->data = (char *) p; if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not exchange authentication token with card " From 86b5f94c3bdd4fba8aa416675d7f2888d401ed14 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 30 Dec 2021 12:35:33 +0100 Subject: [PATCH 2150/4321] The hex_to_bin() is replaced by sc_hex_to_bin() It is not advisable to have two functions that perform the same operation. The hex_to_bin() is used only in pkcs11-tool, but some cases generates wrong output. This function is removed in favor of the sc_hex_to_bin() function. Fixes: #2465 --- src/tools/pkcs11-tool.c | 77 +++++++---------------------------------- 1 file changed, 13 insertions(+), 64 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 33804a38ce..fb78a1d194 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -563,7 +563,6 @@ static void p11_perror(const char *, CK_RV); static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); static int test_card_detection(int); -static int hex_to_bin(const char *in, CK_BYTE *out, size_t *outlen); static CK_BYTE_PTR get_iv(const char * iv_input, size_t *iv_size); static void pseudo_randomize(unsigned char *data, size_t dataLen); static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session); @@ -799,7 +798,7 @@ int main(int argc, char * argv[]) need_session |= NEED_SESSION_RW; do_set_id = 1; new_object_id_len = sizeof(new_object_id); - if (!hex_to_bin(optarg, new_object_id, &new_object_id_len)) { + if (sc_hex_to_bin(optarg, new_object_id, &new_object_id_len)) { fprintf(stderr, "Invalid ID \"%s\"\n", optarg); util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -827,7 +826,7 @@ int main(int argc, char * argv[]) break; case 'd': opt_object_id_len = sizeof(opt_object_id); - if (!hex_to_bin(optarg, opt_object_id, &opt_object_id_len)) { + if (sc_hex_to_bin(optarg, opt_object_id, &opt_object_id_len)) { fprintf(stderr, "Invalid ID \"%s\"\n", optarg); util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -2889,7 +2888,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, ecparams = malloc(ecparams_size); if (!ecparams) util_fatal("Allocation error", 0); - if (!hex_to_bin(ec_curve_infos[ii].ec_params, ecparams, &ecparams_size)) { + if (sc_hex_to_bin(ec_curve_infos[ii].ec_params, ecparams, &ecparams_size)) { fprintf(stderr, "Cannot convert \"%s\"\n", ec_curve_infos[ii].ec_params); util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -3393,7 +3392,7 @@ unwrap_key(CK_SESSION_HANDLE session) size_t id_len; id_len = sizeof(object_id); - if (hex_to_bin(opt_application_id, object_id, &id_len)) { + if (!sc_hex_to_bin(opt_application_id, object_id, &id_len)) { FILL_ATTR(keyTemplate[n_attr], CKA_ID, object_id, id_len); n_attr++; } @@ -3424,7 +3423,7 @@ wrap_key(CK_SESSION_HANDLE session) CK_OBJECT_HANDLE hWrappingKey; // wrapping key CK_OBJECT_HANDLE hkey; // key to be wrapped CK_RV rv; - CK_BYTE hkey_id; + CK_BYTE hkey_id[100]; size_t hkey_id_len; int fd, r; CK_BYTE_PTR iv = NULL; @@ -3446,10 +3445,10 @@ wrap_key(CK_SESSION_HANDLE session) } hkey_id_len = sizeof(hkey_id); - if (!hex_to_bin(opt_application_id, &hkey_id, &hkey_id_len)) + if (sc_hex_to_bin(opt_application_id, hkey_id, &hkey_id_len)) util_fatal("Invalid application-id \"%s\"\n", opt_application_id); - if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? &hkey_id : NULL, hkey_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, 0)) util_fatal("Secret key (to be wrapped) not found"); if (!find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, @@ -7482,59 +7481,6 @@ static void p11_perror(const char *msg, CK_RV rv) { fprintf(stderr, " ERR: %s failed: %s (0x%0x)\n", msg, CKR2Str(rv), (unsigned int) rv); } - -static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen) -{ - size_t left, count = 0; - int nybbles = 2; - - if (in == NULL || *in == '\0') { - *outlen = 0; - return 1; - } - - left = *outlen; - - if (strlen(in) % 2) - nybbles = 1; // any leading zero in output should be in most-significant byte, not last one! - while (*in != '\0') { - int byte = 0; - - while (nybbles-- && *in && *in != ':') { - char c; - byte <<= 4; - c = *in++; - if ('0' <= c && c <= '9') - c -= '0'; - else - if ('a' <= c && c <= 'f') - c = c - 'a' + 10; - else - if ('A' <= c && c <= 'F') - c = c - 'A' + 10; - else { - fprintf(stderr, "hex_to_bin(): invalid char '%c' in hex string\n", c); - *outlen = 0; - return 0; - } - byte |= c; - } - if (*in == ':') - in++; - if (left <= 0) { - fprintf(stderr, "hex_to_bin(): hex string too long"); - *outlen = 0; - return 0; - } - out[count++] = (unsigned char) byte; - left--; - nybbles = 2; - } - - *outlen = count; - return 1; -} - static CK_BYTE_PTR get_iv(const char *iv_input, size_t *iv_size) { CK_BYTE_PTR iv; @@ -7553,11 +7499,14 @@ static CK_BYTE_PTR get_iv(const char *iv_input, size_t *iv_size) return NULL; } - if (!hex_to_bin(iv_input, iv, &size)) - return iv; /* only part from IV string is used as IV, msg printed in hex_to_bin() */ + if (sc_hex_to_bin(iv_input, iv, &size)) { + fprintf(stderr, "Warning, unable to parse IV, IV will not be used.\n"); + *iv_size = 0; + return NULL; + } if (*iv_size != size) - fprintf(stderr, "Warning: IV string is too short, padding with zero bytes to length\n"); + fprintf(stderr, "Warning: IV string is too short, IV will be padded from the right by zeros.\n"); return iv; } From 8672660ca784ca1cea868b1f6d75c9449da67782 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 5 Jan 2022 12:42:26 +0100 Subject: [PATCH 2151/4321] sc_hex_to_bin(): Disallow odd number of chars between separators. --- src/libopensc/sc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 40b9646fe2..f6afcd1c2c 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -82,8 +82,13 @@ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen) else if ('A' <= c && c <= 'F') nibble = c - 'A' + 10; else { - if (strchr(sc_hex_to_bin_separators, (int) c)) + if (strchr(sc_hex_to_bin_separators, (int) c)) { + if (byte_needs_nibble) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } continue; + } r = SC_ERROR_INVALID_ARGUMENTS; goto err; } From 7870a8653d7e4e29fa9c583e134a47b71d4f370f Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 3 Jan 2022 16:01:43 +0100 Subject: [PATCH 2152/4321] unittests: test for sc_hex_to_bin() new file: src/tests/unittests/hextobin.c --- src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/hextobin.c | 125 ++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/tests/unittests/hextobin.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index da670dd500..f17a6c31a8 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -6,8 +6,8 @@ include $(top_srcdir)/aminclude_static.am clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean -noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool -TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool +noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin +TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin noinst_HEADERS = torture.h @@ -25,6 +25,7 @@ simpletlv_SOURCES = simpletlv.c cachedir_SOURCES = cachedir.c pkcs15filter_SOURCES = pkcs15-emulator-filter.c openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c +hextobin_SOURCES = hextobin.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/hextobin.c b/src/tests/unittests/hextobin.c new file mode 100644 index 0000000000..bd913e5c19 --- /dev/null +++ b/src/tests/unittests/hextobin.c @@ -0,0 +1,125 @@ +/* + * hextobin.c: Test suite for sc_hex_to_bin() + * + * Copyright (C) 2022 Peter Popovec + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "libopensc/opensc.h" + +#define LEN 30 + +#define C_END -1 +#define C_ERROR -3 + +struct tst { + int result_len; + const char *input; + const char *output; +}; +int main() +{ + struct tst *t; + struct tst test[] = { + {1, "0", "\x00"}, + {1, " 0", "\x00"}, + {1, "00", "\x00"}, + {1, ":00", "\x00"}, + {1, ":0", "\x00"}, + {1, "d", "\x0d"}, + {1, ":a", "\x0a"}, + {1, "01", "\x01"}, + {1, " 09", "\x09"}, + {1, ":0a", "\x0a"}, + {1, " :0b :", "\x0b"}, + {1, "10", "\x10"}, + {1, " 90", "\x90"}, + {1, ":a0", "\xa0"}, + {1, " :B0 :", "\xb0"}, + {1, " 11:", "\x11"}, + {1, " :11:", "\x11"}, + {1, ":a1", "\xa1"}, + {2, "01:10", "\x01\x10"}, + {2, "10:10", "\x10\x10"}, + {2, " 12ab", "\x12\xab"}, + {3, "10:20:30", "\x10\x20\x30"}, + {3, "1020:30", "\x10\x20\x30"}, + {3, "1020: :30", "\x10\x20\x30"}, + {3, "102030", "\x10\x20\x30"}, + {3, ":102030", "\x10\x20\x30"}, + {3, ":102030:", "\x10\x20\x30"}, + {3, ":102030::", "\x10\x20\x30"}, + {3, "b2:11 :22", "\xb2\x11\x22"}, + {3, "b2 11 22", "\xb2\x11\x22"}, + {9, "10:203040:5060708090", "\x10\x20\x30\x40\x50\x60\x70\x80\x90"}, + {0, "::::", ""}, + {0, ":", ""}, + {0, " ", ""}, + {0, "", ""}, + {C_ERROR, " :0 :", ""}, + {C_ERROR, " :b :", ""}, + {C_ERROR, " :c ", ""}, + {C_ERROR, "1:10", ""}, + {C_ERROR, " :b:2 :", ""}, + {C_ERROR, " ::1:2:a:b", ""}, + {C_ERROR, "1:1", ""}, + {C_ERROR, " :1 1:", ""}, + {C_ERROR, "0:0 :", ""}, + {C_ERROR, "1:234:56", ""}, /* odd number of characters between delimiters (234) */ + {C_ERROR, " :b:211 :", ""}, + {C_ERROR, "02030", ""}, /* one char missing (to have full byte) */ + {C_ERROR, "111", ""}, + {C_ERROR, "b:211 :2", ""}, + {C_ERROR, "G", ""}, + {C_ERROR, " z", ""}, + {C_ERROR, ":a1:1", ""}, + {C_END, "", ""} + }; + uint8_t res[LEN]; + size_t len; + int rv, r; + + for (t = test; t->result_len != C_END; t++) { + r = t->result_len; + len = LEN; + rv = sc_hex_to_bin(t->input, res, &len); + if (rv) { + if (r != C_ERROR) { + fprintf(stderr, "fail at string %s (return code %d, %d\n", t->input, + rv, r); + return 1; + } + } else { + if (r == C_ERROR) { + fprintf(stderr, "fail at string %s (return code %d, %d)\n", + t->input, rv, r); + return 2; + } + if ((int)len != r) { + fprintf(stderr, "fail at string %s (length %zu %d)\n", t->input, + len, r); + return 3; + } + if (memcmp(t->output, res, len)) { + fprintf(stderr, "fail at string %s (return value)\n", t->input); + return 4; + } + } + } + return 0; +} From 05ec8c7fe785a2b9aeaac1164adb349df42b7f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pekkarinen?= Date: Fri, 10 Dec 2021 13:54:26 +0200 Subject: [PATCH 2153/4321] Fix maybe uninitialized errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix maybe uninitialized errors PR: https://github.com/OpenSC/OpenSC/pull/2466 Signed-off-by: José Pekkarinen --- src/libopensc/pkcs15-coolkey.c | 12 ++++++------ src/pkcs15init/pkcs15-asepcos.c | 2 +- src/tools/opensc-explorer.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 586475ddee..15684cef08 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -147,9 +147,9 @@ coolkey_find_matching_cert(sc_card_t *card, sc_cardctl_coolkey_object_t *in_obj, static int coolkey_get_attribute_ulong(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, CK_ULONG *value) { - const u8 *val; - size_t val_len; - u8 data_type; + const u8 *val = NULL; + size_t val_len = 0; + u8 data_type = 0; int r; r = coolkey_get_attribute(card, obj, type, &val, &val_len, &data_type); @@ -168,8 +168,8 @@ static int coolkey_get_attribute_boolean(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE attr_type) { int r; - const u8 *val; - size_t val_len; + const u8 *val = NULL; + size_t val_len = 0; r = coolkey_get_attribute(card, obj, attr_type, &val, &val_len, NULL); if (r < 0) { @@ -186,7 +186,7 @@ static int coolkey_get_attribute_bytes(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, u8 *data, size_t *data_len, size_t max_data_len) { const u8 *val; - size_t val_len; + size_t val_len = 0; int r; r = coolkey_get_attribute(card, obj, type, &val, &val_len, NULL); diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index d7122012d6..bc0efb5ce6 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -221,7 +221,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, { sc_file_t *nfile = NULL; u8 buf[64], sbuf[64], *p = buf, *q = sbuf; - int r, akn; + int r, akn = 0; if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 9ec4daa173..04efdf8f30 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2472,7 +2472,7 @@ int main(int argc, char *argv[]) char *line; int cargc; char *cargv[260]; - int multiple; + int multiple = 0; struct command *cmd; char prompt[3*SC_MAX_PATH_STRING_SIZE]; From 126104b203771c6816c1ea7e9815b551e83e221e Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sat, 8 Jan 2022 14:31:11 +0100 Subject: [PATCH 2154/4321] error code mapping: SC_ERROR_WRONG_PADDING -> CKR_ENCRYPTED_DATA_INVALID modified: src/pkcs11/misc.c --- src/pkcs11/misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 75660ed804..642338b4bb 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -115,6 +115,8 @@ static CK_RV sc_to_cryptoki_error_common(int rc) return CKR_DEVICE_MEMORY; case SC_ERROR_MEMORY_FAILURE: /* EEPROM has failed */ return CKR_DEVICE_ERROR; + case SC_ERROR_WRONG_PADDING: + return CKR_ENCRYPTED_DATA_INVALID; } return CKR_GENERAL_ERROR; } From 470243f1230f3763a7935e0b9408241fa27707f2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 8 Sep 2021 18:21:11 +0200 Subject: [PATCH 2155/4321] p11test: Rewrite to use EVP interfaces on the way to OSSL 3.0 --- src/tests/p11test/p11test_case_common.c | 110 +++++++++++-------- src/tests/p11test/p11test_case_common.h | 11 +- src/tests/p11test/p11test_case_ec_derive.c | 8 +- src/tests/p11test/p11test_case_pss_oaep.c | 66 +++++++----- src/tests/p11test/p11test_case_readonly.c | 120 ++++++++------------- 5 files changed, 158 insertions(+), 157 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index d7084c0787..b987a774a0 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -85,9 +85,7 @@ add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) o->derive_pub = 0; o->key_type = -1; o->x509 = NULL; /* The "reuse" capability of d2i_X509() is strongly discouraged */ - o->key.rsa = NULL; - o->key.ec = NULL; - o->value = NULL; + o->key = NULL; /* Store the passed CKA_ID and CKA_LABEL */ o->key_id = malloc(key_id.ulValueLen); @@ -256,30 +254,20 @@ int callback_certificates(test_certs_t *objects, } if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { - /* Extract public RSA key */ - const RSA *rsa = EVP_PKEY_get0_RSA(evp); - if ((o->key.rsa = RSAPublicKey_dup((RSA *)rsa)) == NULL) { - fail_msg("RSAPublicKey_dup failed"); - return -1; - } + o->key = evp; o->type = EVP_PK_RSA; o->bits = EVP_PKEY_bits(evp); } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { - /* Extract public EC key */ - const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp); - if ((o->key.ec = EC_KEY_dup(ec)) == NULL) { - fail_msg("EC_KEY_dup failed"); - return -1; - } + o->key = evp; o->type = EVP_PK_EC; o->bits = EVP_PKEY_bits(evp); } else { + EVP_PKEY_free(evp); fprintf(stderr, "[WARN %s ]evp->type = 0x%.4X (not RSA, EC)\n", o->id_str, EVP_PKEY_id(evp)); } - EVP_PKEY_free(evp); debug_print(" [ OK %s ] Certificate with label %s loaded successfully", o->id_str, o->label); @@ -378,28 +366,66 @@ int callback_public_keys(test_certs_t *objects, BIGNUM *n = NULL, *e = NULL; n = BN_bin2bn(template[4].pValue, template[4].ulValueLen, NULL); e = BN_bin2bn(template[5].pValue, template[5].ulValueLen, NULL); - if (o->key.rsa != NULL) { + if (o->key != NULL) { + int rv; +#if 1 +// OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *cert_n = NULL, *cert_e = NULL; - RSA_get0_key(o->key.rsa, &cert_n, &cert_e, NULL); - if (BN_cmp(cert_n, n) != 0 || - BN_cmp(cert_e, e) != 0) { - debug_print(" [WARN %s ] Got different public key then from the certificate", + RSA *rsa = EVP_PKEY_get0_RSA(o->key); + RSA_get0_key(rsa, &cert_n, &cert_e, NULL); +#else +//TODO This looks broken in in current OpenSSL 3.0 + BIGNUM *cert_n = NULL, *cert_e = NULL; + if ((EVP_PKEY_get_bn_param(o->key, OSSL_PKEY_PARAM_RSA_N, &cert_n) != 1) || + (EVP_PKEY_get_bn_param(o->key, OSSL_PKEY_PARAM_RSA_E, &cert_e) != 1)) { + debug_print(" [WARN %s ] Failed to get RSA key parameters", o->id_str); + BN_free(cert_n); BN_free(n); BN_free(e); return -1; } +#endif + rv = BN_cmp(cert_n, n) != 0 || BN_cmp(cert_e, e) != 0; + if (rv != 0) { + o->verify_public = 1; + } else { + debug_print(" [WARN %s ] Got different public key then from the certificate", + o->id_str); + } +#if 0 +// OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(cert_n); + BN_free(cert_e); +#endif BN_free(n); BN_free(e); - o->verify_public = 1; } else { /* store the public key for future use */ o->type = EVP_PK_RSA; - o->key.rsa = RSA_new(); - if (RSA_set0_key(o->key.rsa, n, e, NULL) != 1) { + o->key = EVP_PKEY_new(); +#if 1 +// OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa = RSA_new(); + if (RSA_set0_key(rsa, n, e, NULL) != 1 || + EVP_PKEY_set1_RSA(o->key, rsa)) +#else +//TODO This looks broken in in current OpenSSL 3.0 + if ((EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_N, n) != 1) || + (EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_E, e) != 1)) +#endif + { fail_msg("Unable to set key params"); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + BN_free(n); + BN_free(e); +#endif return -1; } - o->bits = RSA_bits(o->key.rsa); + o->bits = EVP_PKEY_bits(o->key); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + BN_free(n); + BN_free(e); +#endif n = NULL; e = NULL; } @@ -457,9 +483,10 @@ int callback_public_keys(test_certs_t *objects, return -1; } - if (o->key.ec != NULL) { - const EC_GROUP *cert_group = EC_KEY_get0_group(o->key.ec); - const EC_POINT *cert_point = EC_KEY_get0_public_key(o->key.ec); + if (o->key != NULL) { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(o->key); + const EC_GROUP *cert_group = EC_KEY_get0_group(ec); + const EC_POINT *cert_point = EC_KEY_get0_public_key(ec); int cert_nid = EC_GROUP_get_curve_name(cert_group); if (cert_nid != nid || @@ -477,10 +504,12 @@ int callback_public_keys(test_certs_t *objects, o->verify_public = 1; } else { /* store the public key for future use */ o->type = EVP_PK_EC; - o->key.ec = EC_KEY_new_by_curve_name(nid); - EC_KEY_set_public_key(o->key.ec, ecpoint); - EC_KEY_set_group(o->key.ec, ecgroup); + o->key = EVP_PKEY_new(); + EC_KEY *ec = EC_KEY_new_by_curve_name(nid); + EC_KEY_set_public_key(ec, ecpoint); + EC_KEY_set_group(ec, ecgroup); o->bits = EC_GROUP_get_degree(ecgroup); + EVP_PKEY_set1_EC_KEY(o->key, ec); } } else if (o->key_type == CKK_EC_EDWARDS || o->key_type == CKK_EC_MONTGOMERY) { @@ -561,13 +590,13 @@ int callback_public_keys(test_certs_t *objects, ASN1_STRING_free(os); return -1; } - if (o->key.pkey != NULL) { + if (o->key != NULL) { unsigned char *pub = NULL; size_t publen = 0; /* TODO check EVP_PKEY type */ - if (EVP_PKEY_get_raw_public_key(o->key.pkey, NULL, &publen) != 1) { + if (EVP_PKEY_get_raw_public_key(o->key, NULL, &publen) != 1) { debug_print(" [WARN %s ] Can not get size of the key", o->id_str); ASN1_STRING_free(os); return -1; @@ -579,7 +608,7 @@ int callback_public_keys(test_certs_t *objects, return -1; } - if (EVP_PKEY_get_raw_public_key(o->key.pkey, pub, &publen) != 1 || + if (EVP_PKEY_get_raw_public_key(o->key, pub, &publen) != 1 || publen != (size_t)os->length || memcmp(pub, os->data, publen) != 0) { debug_print(" [WARN %s ] Got different public" @@ -594,7 +623,7 @@ int callback_public_keys(test_certs_t *objects, o->verify_public = 1; } else { /* store the public key for future use */ o->type = evp_type; - o->key.pkey = key; + o->key = key; o->bits = 255; } ASN1_STRING_free(os); @@ -854,15 +883,8 @@ void clean_all_objects(test_certs_t *objects) { free(objects->data[i].label); free(objects->data[i].value); X509_free(objects->data[i].x509); - if (objects->data[i].key_type == CKK_RSA && - objects->data[i].key.rsa != NULL) { - RSA_free(objects->data[i].key.rsa); - } else if (objects->data[i].key_type == CKK_EC && - objects->data[i].key.ec != NULL) { - EC_KEY_free(objects->data[i].key.ec); - } else if (objects->data[i].key_type == CKK_EC_EDWARDS && - objects->data[i].key.pkey != NULL) { - EVP_PKEY_free(objects->data[i].key.pkey); + if (objects->data[i].key != NULL) { + EVP_PKEY_free(objects->data[i].key); } } free(objects->data); diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index ec690eeb71..9bcf8b8bab 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -25,6 +25,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +#endif #include "p11test_common.h" typedef struct { @@ -33,11 +36,7 @@ typedef struct { char *id_str; X509 *x509; int type; - union { - RSA *rsa; - EC_KEY *ec; - EVP_PKEY *pkey; - } key; + EVP_PKEY *key; CK_OBJECT_HANDLE private_handle; CK_OBJECT_HANDLE public_handle; CK_BBOOL sign; @@ -133,4 +132,4 @@ int is_pss_mechanism(CK_MECHANISM_TYPE mech); void write_data_row(token_info_t *info, int cols, ...); -#endif /* P11TEST_CASE_COMMON_H */ +#endif /* P11TEST_CASE_COMMON_H */ \ No newline at end of file diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index bed5761d57..d545c7d528 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -143,7 +143,7 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) return 1; } - rc = EVP_PKEY_derive_set_peer(pctx, o->key.pkey); + rc = EVP_PKEY_derive_set_peer(pctx, o->key); if (rc != 1) { debug_print(" [ KEY %s ] EVP_PKEY_derive_set_peer failed", o->id_str); EVP_PKEY_CTX_free(pctx); @@ -215,7 +215,7 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) { int nid, field_size; - EC_KEY *key = NULL; + EC_KEY *key = NULL, *pkey = NULL; const EC_POINT *publickey = NULL; const EC_GROUP *group = NULL; unsigned char *secret = NULL, *pkcs11_secret = NULL; @@ -263,10 +263,10 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) EC_KEY_free(key); return 1; } - + pkey = EVP_PKEY_get0_EC_KEY(o->key); /* Derive the shared secret locally */ secret_len = ECDH_compute_key(secret, secret_len, - EC_KEY_get0_public_key(o->key.ec), key, NULL); + EC_KEY_get0_public_key(pkey), key, NULL); /* Try to do the same with the card key */ diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index b80047afd6..f0afdc8b35 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -188,24 +188,47 @@ size_t get_hash_length(CK_MECHANISM_TYPE mech) CK_BYTE *hash_message(const CK_BYTE *message, size_t message_length, CK_MECHANISM_TYPE hash) { + CK_BYTE *out = NULL; + switch (hash) { case CKM_SHA224: - return SHA224(message, message_length, NULL); + out = malloc(SHA224_DIGEST_LENGTH); + if (out == NULL) + return NULL; + EVP_Digest(message, message_length, out, NULL, EVP_sha224(), NULL); + break; case CKM_SHA256: - return SHA256(message, message_length, NULL); + out = malloc(SHA256_DIGEST_LENGTH); + if (out == NULL) + return NULL; + EVP_Digest(message, message_length, out, NULL, EVP_sha256(), NULL); + break; case CKM_SHA384: - return SHA384(message, message_length, NULL); + out = malloc(SHA384_DIGEST_LENGTH); + if (out == NULL) + return NULL; + EVP_Digest(message, message_length, out, NULL, EVP_sha384(), NULL); + break; case CKM_SHA512: - return SHA512(message, message_length, NULL); + out = malloc(SHA512_DIGEST_LENGTH); + if (out == NULL) + return NULL; + EVP_Digest(message, message_length, out, NULL, EVP_sha512(), NULL); + break; case CKM_SHA_1: default: - return SHA1(message, message_length, NULL); + out = malloc(SHA_DIGEST_LENGTH); + if (out == NULL) + return NULL; + EVP_Digest(message, message_length, out, NULL, EVP_sha1(), NULL); + break; } + return out; } int oaep_encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, @@ -216,20 +239,11 @@ int oaep_encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *me EVP_PKEY_CTX *pctx = NULL; const EVP_MD *md = EVP_md_null(); const EVP_MD *mgf1_md = EVP_md_null(); - EVP_PKEY *key = NULL; md = md_cryptoki_to_ossl(mech->hash); mgf1_md = mgf_cryptoki_to_ossl(mech->mgf); - if ((key = EVP_PKEY_new()) == NULL - || RSA_up_ref(o->key.rsa) < 1 - || EVP_PKEY_set1_RSA(key, o->key.rsa) != 1) { - fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY. Error: %s\n", - o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); - goto out; - } - - if ((pctx = EVP_PKEY_CTX_new(key, NULL)) == NULL + if ((pctx = EVP_PKEY_CTX_new(o->key, NULL)) == NULL || EVP_PKEY_encrypt_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_OAEP_PADDING) != 1 || EVP_PKEY_CTX_set_rsa_oaep_md(pctx, md) != 1 @@ -254,7 +268,6 @@ int oaep_encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *me } out: EVP_PKEY_CTX_free(pctx); - EVP_PKEY_free(key); return enc_length; } @@ -536,31 +549,23 @@ int pss_verify_message_openssl(test_cert_t *o, token_info_t *info, CK_RV rv = -1; EVP_PKEY_CTX *pctx = NULL; const CK_BYTE *my_message; + CK_BYTE *free_message = NULL; CK_ULONG my_message_length; const EVP_MD *mgf_md = EVP_md_null(); const EVP_MD *md = EVP_md_null(); - EVP_PKEY *key = NULL; md = md_cryptoki_to_ossl(mech->hash); mgf_md = mgf_cryptoki_to_ossl(mech->mgf); if (mech->mech != CKM_RSA_PKCS_PSS) { - my_message = hash_message(message, message_length, mech->hash); + my_message = free_message = hash_message(message, message_length, mech->hash); my_message_length = get_hash_length(mech->hash); } else { my_message = message; my_message_length = message_length; } - if ((key = EVP_PKEY_new()) == NULL - || RSA_up_ref(o->key.rsa) < 1 - || EVP_PKEY_set1_RSA(key, o->key.rsa) != 1) { - fprintf(stderr, " [ ERROR %s ] Failed to initialize EVP_PKEY. Error: %s\n", - o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); - goto out; - } - - if ((pctx = EVP_PKEY_CTX_new(key, NULL)) == NULL + if ((pctx = EVP_PKEY_CTX_new(o->key, NULL)) == NULL || EVP_PKEY_verify_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) != 1 || EVP_PKEY_CTX_set_signature_md(pctx, md) != 1 @@ -580,9 +585,9 @@ int pss_verify_message_openssl(test_cert_t *o, token_info_t *info, o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); goto out; } + free(free_message); out: EVP_PKEY_CTX_free(pctx); - EVP_PKEY_free(key); return rv; } @@ -684,6 +689,9 @@ int pss_sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech) debug_print(" [ KEY %s ] Verify message signature", o->id_str); rv = pss_verify_message(o, info, message, message_length, mech, sign, sign_length); + if (mech->mech == CKM_RSA_PKCS_PSS) { + free(message); + } free(sign); return rv; } @@ -875,4 +883,4 @@ void pss_oaep_test(void **state) { clean_all_objects(&objects); P11TEST_PASS(info); -} +} \ No newline at end of file diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 4bca8f542a..2fd3a939f5 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -71,15 +71,11 @@ rsa_x_509_pad_message(const unsigned char *message, int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_ULONG message_length, test_mech_t *mech, unsigned char **enc_message) { - int rv, padding; + int rv = -1, padding; + size_t outlen = 0; + EVP_PKEY_CTX *ctx = NULL; - /* this works only for RSA keys */ - if (o->key_type != CKK_RSA) { - debug_print("skip non-RSA key"); - return -1; - } - - *enc_message = malloc(RSA_size(o->key.rsa)); + *enc_message = malloc(EVP_PKEY_size(o->key)); if (*enc_message == NULL) { debug_print("malloc returned null"); return -1; @@ -87,15 +83,19 @@ int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message /* Prepare padding for RSA_X_509 */ padding = ((mech->mech == CKM_RSA_X_509) ? RSA_NO_PADDING : RSA_PKCS1_PADDING); - rv = RSA_public_encrypt(message_length, message, - *enc_message, o->key.rsa, padding); - if (rv < 0) { + + ctx = EVP_PKEY_CTX_new(o->key, NULL); + if (!ctx || (rv = EVP_PKEY_encrypt_init(ctx)) <= 0 || + (rv = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0 || + (rv = EVP_PKEY_encrypt(ctx, *enc_message, &outlen, message, message_length)) <= 0) { free(*enc_message); *enc_message = NULL; - debug_print("RSA_public_encrypt: rv = 0x%.8X\n", rv); + EVP_PKEY_CTX_free(ctx); + debug_print("OpenSSL encrypt failed: rv = 0x%.8X\n", rv); return -1; } - return rv; + EVP_PKEY_CTX_free(ctx); + return outlen; } int encrypt_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, @@ -202,7 +202,7 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, } if (o->type != EVP_PK_RSA) { - debug_print(" [ KEY %s ] Skip non-RSA key for encryption", o->id_str); + debug_print(" [SKIP %s ] Skip non-RSA key for encryption", o->id_str); return 0; } @@ -353,85 +353,57 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, int cmp_message_length; if (o->type == EVP_PK_RSA) { - int type; - - /* raw RSA mechanism */ - if (mech->mech == CKM_RSA_PKCS || mech->mech == CKM_RSA_X_509) { - CK_BYTE dec_message[BUFFER_SIZE]; - int padding = ((mech->mech == CKM_RSA_X_509) - ? RSA_NO_PADDING : RSA_PKCS1_PADDING); - int dec_message_length = RSA_public_decrypt(sign_length, sign, - dec_message, o->key.rsa, padding); - if (dec_message_length < 0) { - fprintf(stderr, "RSA_public_decrypt: rv = %d: %s\n", dec_message_length, - ERR_error_string(ERR_peek_last_error(), NULL)); - return -1; - } - if (memcmp(dec_message, message, dec_message_length) == 0 - && dec_message_length == (int) message_length) { - debug_print(" [ OK %s ] Signature is valid.", o->id_str); - mech->result_flags |= FLAGS_SIGN_OPENSSL; - return 1; - } else { - fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", - o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); - return 0; - } - } + EVP_PKEY_CTX *ctx = NULL; + const EVP_MD *md = NULL; + int padding = RSA_PKCS1_PADDING; /* Digest mechanisms */ switch (mech->mech) { + case CKM_RSA_X_509: + padding = RSA_NO_PADDING; + break; case CKM_SHA1_RSA_PKCS: - cmp_message = SHA1(message, message_length, NULL); - cmp_message_length = SHA_DIGEST_LENGTH; - type = NID_sha1; + md = EVP_sha1(); break; case CKM_SHA224_RSA_PKCS: - cmp_message = SHA224(message, message_length, NULL); - cmp_message_length = SHA224_DIGEST_LENGTH; - type = NID_sha224; + md = EVP_sha224(); break; case CKM_SHA256_RSA_PKCS: - cmp_message = SHA256(message, message_length, NULL); - cmp_message_length = SHA256_DIGEST_LENGTH; - type = NID_sha256; + md = EVP_sha256(); break; case CKM_SHA384_RSA_PKCS: - cmp_message = SHA384(message, message_length, NULL); - cmp_message_length = SHA384_DIGEST_LENGTH; - type = NID_sha384; + md = EVP_sha384(); break; case CKM_SHA512_RSA_PKCS: - cmp_message = SHA512(message, message_length, NULL); - cmp_message_length = SHA512_DIGEST_LENGTH; - type = NID_sha512; + md = EVP_sha512(); break; case CKM_MD5_RSA_PKCS: - cmp_message = MD5(message, message_length, NULL); - cmp_message_length = MD5_DIGEST_LENGTH; - type = NID_md5; + md = EVP_md5(); break; case CKM_RIPEMD160_RSA_PKCS: - cmp_message = RIPEMD160(message, message_length, NULL); - cmp_message_length = RIPEMD160_DIGEST_LENGTH; - type = NID_ripemd160; + md = EVP_ripemd160(); break; default: debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); return 0; } - rv = RSA_verify(type, cmp_message, cmp_message_length, - sign, sign_length, o->key.rsa); - if (rv == 1) { - debug_print(" [ OK %s ] Signature is valid.", o->id_str); - mech->result_flags |= FLAGS_SIGN_OPENSSL; - } else { + + ctx = EVP_PKEY_CTX_new(o->key, NULL); + if (!ctx || (rv = EVP_PKEY_verify_init(ctx)) <= 0 || + (rv = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0 || + (md && (rv = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) || + (rv = EVP_PKEY_verify(ctx, sign, sign_length, message, message_length)) != 1) { fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + EVP_PKEY_CTX_free(ctx); return -1; } + EVP_PKEY_CTX_free(ctx); + debug_print(" [ OK %s ] Signature is valid.", o->id_str); + return 1; } else if (o->type == EVP_PK_EC) { unsigned int nlen; + EC_KEY *ec = NULL; ECDSA_SIG *sig = ECDSA_SIG_new(); BIGNUM *r = NULL, *s = NULL; if (sig == NULL) { @@ -444,19 +416,19 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, ECDSA_SIG_set0(sig, r, s); switch (mech->mech) { case CKM_ECDSA_SHA512: - cmp_message = SHA512(message, message_length, NULL); + EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha512(), NULL); cmp_message_length = SHA512_DIGEST_LENGTH; break; case CKM_ECDSA_SHA384: - cmp_message = SHA384(message, message_length, NULL); + EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha384(), NULL); cmp_message_length = SHA384_DIGEST_LENGTH; break; case CKM_ECDSA_SHA256: - cmp_message = SHA256(message, message_length, NULL); + EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha256(), NULL); cmp_message_length = SHA256_DIGEST_LENGTH; break; case CKM_ECDSA_SHA1: - cmp_message = SHA1(message, message_length, NULL); + EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha1(), NULL); cmp_message_length = SHA_DIGEST_LENGTH; break; case CKM_ECDSA: @@ -467,7 +439,8 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); return 0; } - rv = ECDSA_do_verify(cmp_message, cmp_message_length, sig, o->key.ec); + ec = EVP_PKEY_get0_EC_KEY(o->key); + rv = ECDSA_do_verify(cmp_message, cmp_message_length, sig, ec); if (rv == 1) { ECDSA_SIG_free(sig); debug_print(" [ OK %s ] EC Signature of length %lu is valid.", @@ -484,7 +457,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, /* need to be created even though we do not do any MD */ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); - rv = EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, o->key.pkey); + rv = EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, o->key); if (rv != 1) { fprintf(stderr, " [FAIL %s ] EVP_DigestVerifyInit: rv = %lu: %s\n", o->id_str, rv, ERR_error_string(ERR_peek_last_error(), NULL)); @@ -589,8 +562,7 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, int rv = 0; if (message_length > strlen(MESSAGE_TO_SIGN)) { - fail_msg("Truncate (%lu) is longer than the actual message (%lu)", - message_length, strlen(MESSAGE_TO_SIGN)); + fail_msg("Truncate is longer than the actual message"); return -1; } From 9217b0b48c0129f17428f3c4c2dbf8424ac9f0a9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 9 Sep 2021 12:34:28 +0200 Subject: [PATCH 2156/4321] p11test: Rewrite p11test_case_common according to OpenSSL 3.0 --- src/tests/p11test/p11test_case_common.c | 95 +++++++++++++++++++------ src/tests/p11test/p11test_case_common.h | 1 + 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index b987a774a0..e16f4d6ee1 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -332,6 +332,11 @@ int callback_public_keys(test_certs_t *objects, { test_cert_t *o = NULL; char *key_id; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *bld = NULL; +#endif /* Search for already stored certificate with same ID */ if ((o = search_certificate(objects, &(template[3]))) == NULL) { @@ -368,33 +373,29 @@ int callback_public_keys(test_certs_t *objects, e = BN_bin2bn(template[5].pValue, template[5].ulValueLen, NULL); if (o->key != NULL) { int rv; -#if 1 -// OPENSSL_VERSION_NUMBER < 0x30000000L +#if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *cert_n = NULL, *cert_e = NULL; RSA *rsa = EVP_PKEY_get0_RSA(o->key); RSA_get0_key(rsa, &cert_n, &cert_e, NULL); #else -//TODO This looks broken in in current OpenSSL 3.0 BIGNUM *cert_n = NULL, *cert_e = NULL; if ((EVP_PKEY_get_bn_param(o->key, OSSL_PKEY_PARAM_RSA_N, &cert_n) != 1) || (EVP_PKEY_get_bn_param(o->key, OSSL_PKEY_PARAM_RSA_E, &cert_e) != 1)) { - debug_print(" [WARN %s ] Failed to get RSA key parameters", - o->id_str); + fprintf(stderr, "Failed to extract RSA key parameters"); BN_free(cert_n); BN_free(n); BN_free(e); - return -1; + return -1; } #endif - rv = BN_cmp(cert_n, n) != 0 || BN_cmp(cert_e, e) != 0; - if (rv != 0) { + rv = BN_cmp(cert_n, n) == 0 && BN_cmp(cert_e, e) == 0; + if (rv == 1) { o->verify_public = 1; } else { debug_print(" [WARN %s ] Got different public key then from the certificate", o->id_str); } -#if 0 -// OPENSSL_VERSION_NUMBER >= 0x30000000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(cert_n); BN_free(cert_e); #endif @@ -403,13 +404,11 @@ int callback_public_keys(test_certs_t *objects, } else { /* store the public key for future use */ o->type = EVP_PK_RSA; o->key = EVP_PKEY_new(); -#if 1 -// OPENSSL_VERSION_NUMBER < 0x30000000L +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA *rsa = RSA_new(); if (RSA_set0_key(rsa, n, e, NULL) != 1 || EVP_PKEY_set1_RSA(o->key, rsa)) #else -//TODO This looks broken in in current OpenSSL 3.0 if ((EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_N, n) != 1) || (EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_E, e) != 1)) #endif @@ -422,12 +421,6 @@ int callback_public_keys(test_certs_t *objects, return -1; } o->bits = EVP_PKEY_bits(o->key); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - BN_free(n); - BN_free(e); -#endif - n = NULL; - e = NULL; } } else if (o->key_type == CKK_EC) { ASN1_OBJECT *oid = NULL; @@ -473,8 +466,11 @@ int callback_public_keys(test_certs_t *objects, EC_GROUP_free(ecgroup); return -1; } - +#if OPENSSL_VERSION_NUMBER < 0x30000000L ecpoint = EC_POINT_bn2point(ecgroup, bn, NULL, NULL); +#else + ecpoint = EC_POINT_hex2point(ecgroup, BN_bn2hex(bn), NULL, NULL); +#endif BN_free(bn); if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" @@ -484,11 +480,37 @@ int callback_public_keys(test_certs_t *objects, } if (o->key != NULL) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *ec = EVP_PKEY_get0_EC_KEY(o->key); const EC_GROUP *cert_group = EC_KEY_get0_group(ec); const EC_POINT *cert_point = EC_KEY_get0_public_key(ec); int cert_nid = EC_GROUP_get_curve_name(cert_group); - +#else + EC_GROUP *cert_group = NULL; + char curve_name[80]; size_t curve_name_len = 0; + int cert_nid = 0; + if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len) != 1 || + (cert_nid = OBJ_txt2nid(curve_name)) == NID_undef || + (cert_group = EC_GROUP_new_by_curve_name(cert_nid)) == NULL) { + fprintf(stderr, "Can not get EC_GROUP from EVP_PKEY"); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + EC_GROUP_free(cert_group); + return -1; + } + EC_POINT *cert_point = EC_POINT_new(cert_group); + unsigned char pubkey[80]; size_t pubkey_len = 0; + if (!cert_point || + EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1 || + EC_POINT_oct2point(cert_group, cert_point, pubkey, pubkey_len, NULL) != 1) { + fprintf(stderr, "Can not get EC_POINT from EVP_PKEY"); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + EC_POINT_free(cert_point); + EC_GROUP_free(cert_group); + return -1; + } +#endif if (cert_nid != nid || EC_GROUP_cmp(cert_group, ecgroup, NULL) != 0 || EC_POINT_cmp(ecgroup, cert_point, ecpoint, NULL) != 0) { @@ -505,11 +527,40 @@ int callback_public_keys(test_certs_t *objects, } else { /* store the public key for future use */ o->type = EVP_PK_EC; o->key = EVP_PKEY_new(); + o->bits = EC_GROUP_get_degree(ecgroup); +#if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *ec = EC_KEY_new_by_curve_name(nid); EC_KEY_set_public_key(ec, ecpoint); EC_KEY_set_group(ec, ecgroup); - o->bits = EC_GROUP_get_degree(ecgroup); EVP_PKEY_set1_EC_KEY(o->key, ec); +#else + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); + char curve_name[80]; size_t curve_name_len = 0; + unsigned char pubkey[80]; size_t pubkey_len = 0; + if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len)|| + EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { + debug_print(" [WARN %s ] Can not get params from EVP_PKEY", o->id_str); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + return -1; + } + OSSL_PARAM_BLD *param_bld; + OSSL_PARAM *params = NULL; + param_bld = OSSL_PARAM_BLD_new(); + if (param_bld != NULL && + OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", curve_name, curve_name_len) && + OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pubkey, pubkey_len)) { + params = OSSL_PARAM_BLD_to_param(param_bld); + } + if (ctx == NULL || params == NULL || + EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + debug_print(" [WARN %s ] Can not set params for EVP_PKEY", o->id_str); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + return -1; + } +#endif } } else if (o->key_type == CKK_EC_EDWARDS || o->key_type == CKK_EC_MONTGOMERY) { diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 9bcf8b8bab..7d05a9676b 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -27,6 +27,7 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include +# include #endif #include "p11test_common.h" From c264b62e95a88dd9d0ea1481cfdbaaa07859db5a Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 26 Oct 2021 18:48:17 +0200 Subject: [PATCH 2157/4321] p11test: Build keys in callback_public_keys() --- src/tests/p11test/p11test_case_common.c | 64 ++++++++++++++++++------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index e16f4d6ee1..79a05c0e3b 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -403,23 +403,41 @@ int callback_public_keys(test_certs_t *objects, BN_free(e); } else { /* store the public key for future use */ o->type = EVP_PK_RSA; - o->key = EVP_PKEY_new(); #if OPENSSL_VERSION_NUMBER < 0x30000000L + o->key = EVP_PKEY_new(); RSA *rsa = RSA_new(); if (RSA_set0_key(rsa, n, e, NULL) != 1 || - EVP_PKEY_set1_RSA(o->key, rsa)) + EVP_PKEY_set1_RSA(o->key, rsa) != 1) { + fail_msg("Unable to set key params"); + return -1; + } #else - if ((EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_N, n) != 1) || - (EVP_PKEY_set_bn_param(o->key, OSSL_PKEY_PARAM_RSA_E, e) != 1)) -#endif - { + if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + EVP_PKEY_CTX_free(ctx); + BN_free(n); + BN_free(e); + OSSL_PARAM_BLD_free(bld); fail_msg("Unable to set key params"); -#if OPENSSL_VERSION_NUMBER < 0x30000000L + return -1; + } + OSSL_PARAM_BLD_free(bld); + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); BN_free(n); BN_free(e); -#endif + OSSL_PARAM_free(params); + fail_msg("Unable to store key"); return -1; } + OSSL_PARAM_free(params); + BN_free(n); + BN_free(e); +#endif o->bits = EVP_PKEY_bits(o->key); } } else if (o->key_type == CKK_EC) { @@ -487,7 +505,9 @@ int callback_public_keys(test_certs_t *objects, int cert_nid = EC_GROUP_get_curve_name(cert_group); #else EC_GROUP *cert_group = NULL; + EC_POINT *cert_point = NULL; char curve_name[80]; size_t curve_name_len = 0; + unsigned char pubkey[80]; size_t pubkey_len = 0; int cert_nid = 0; if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len) != 1 || (cert_nid = OBJ_txt2nid(curve_name)) == NID_undef || @@ -498,8 +518,7 @@ int callback_public_keys(test_certs_t *objects, EC_GROUP_free(cert_group); return -1; } - EC_POINT *cert_point = EC_POINT_new(cert_group); - unsigned char pubkey[80]; size_t pubkey_len = 0; + cert_point = EC_POINT_new(cert_group); if (!cert_point || EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1 || EC_POINT_oct2point(cert_group, cert_point, pubkey, pubkey_len, NULL) != 1) { @@ -534,7 +553,7 @@ int callback_public_keys(test_certs_t *objects, EC_KEY_set_group(ec, ecgroup); EVP_PKEY_set1_EC_KEY(o->key, ec); #else - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); + ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); char curve_name[80]; size_t curve_name_len = 0; unsigned char pubkey[80]; size_t pubkey_len = 0; if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len)|| @@ -544,22 +563,31 @@ int callback_public_keys(test_certs_t *objects, EC_POINT_free(ecpoint); return -1; } - OSSL_PARAM_BLD *param_bld; - OSSL_PARAM *params = NULL; - param_bld = OSSL_PARAM_BLD_new(); - if (param_bld != NULL && - OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", curve_name, curve_name_len) && - OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pubkey, pubkey_len)) { - params = OSSL_PARAM_BLD_to_param(param_bld); + + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, curve_name_len) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + debug_print(" [WARN %s ] Can not set params from EVP_PKEY", o->id_str); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + OSSL_PARAM_BLD_free(bld); + EVP_PKEY_CTX_free(ctx); + return -1; } + OSSL_PARAM_BLD_free(bld); + if (ctx == NULL || params == NULL || EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { debug_print(" [WARN %s ] Can not set params for EVP_PKEY", o->id_str); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); + EVP_PKEY_CTX_free(ctx); return -1; } + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); #endif } } else if (o->key_type == CKK_EC_EDWARDS From e596510ef21da1ad7a5a5cb0e09b50087c6769ed Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 13 Sep 2021 17:03:22 +0200 Subject: [PATCH 2158/4321] p11test: Derive ec key with EVP_PKEY API in case_derive --- src/tests/p11test/p11test_case_ec_derive.c | 116 +++++++++++++++------ 1 file changed, 83 insertions(+), 33 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index d545c7d528..4bf655a5e5 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -214,13 +214,19 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) { - int nid, field_size; - EC_KEY *key = NULL, *pkey = NULL; - const EC_POINT *publickey = NULL; - const EC_GROUP *group = NULL; unsigned char *secret = NULL, *pkcs11_secret = NULL; unsigned char *pub = NULL; size_t pub_len = 0, secret_len = 0, pkcs11_secret_len = 0; + int rv = 1; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + int nid = 0; + const EC_GROUP *group = NULL; + const EC_POINT *publickey = NULL; + EC_KEY *key = NULL; +#endif + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *evp_pkey = NULL; if (o->private_handle == CK_INVALID_HANDLE) { debug_print(" [SKIP %s ] Missing private key", o->id_str); @@ -234,6 +240,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) debug_print(" [ KEY %s ] Trying EC derive using CKM_%s and %lu-bit key", o->id_str, get_mechanism_name(mech->mech), o->bits); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (o->bits == 256) nid = NID_X9_62_prime256v1; else if (o->bits == 384) @@ -244,75 +251,118 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) debug_print(" [ KEY %s ] Skip key of unknown size", o->id_str); return 1; } +#endif - /* Generate the peer private key */ - if ((key = EC_KEY_new_by_curve_name(nid)) == NULL || - EC_KEY_generate_key(key) != 1) { - debug_print(" [ KEY %s ] Failed to generate peer private key", o->id_str); - EC_KEY_free(key); +/* Generate the peer private key */ + if ((pctx = EVP_PKEY_CTX_new(o->key, NULL)) == NULL) { + debug_print(" [ KEY %s ] EVP_PKEY_CTX_new_id failed", o->id_str); return 1; } - /* Calculate the size of the buffer for the shared secret */ - field_size = EC_GROUP_get_degree(EC_KEY_get0_group(key)); - secret_len = (field_size+7)/8; + if (EVP_PKEY_keygen_init(pctx) != 1) { + debug_print(" [ KEY %s ] EVP_PKEY_keygen_init failed", o->id_str); + EVP_PKEY_CTX_free(pctx); + return 1; + } + if (EVP_PKEY_keygen(pctx, &evp_pkey) != 1) { + debug_print(" [ KEY %s ] EVP_PKEY_keygen failed", o->id_str); + EVP_PKEY_CTX_free(pctx); + return 1; + } + EVP_PKEY_CTX_free(pctx); + +/* Start with key derivation in OpenSSL*/ + pctx = EVP_PKEY_CTX_new(evp_pkey, NULL); + if (pctx == NULL || + EVP_PKEY_derive_init(pctx) != 1 || + EVP_PKEY_derive_set_peer(pctx, o->key) != 1) { + debug_print(" [ KEY %s ] Can not derive key", o->id_str); + EVP_PKEY_free(evp_pkey); + return 1; + } + + /* Get buffer length */ + if (EVP_PKEY_derive(pctx, NULL, &secret_len) != 1) { + debug_print(" [ KEY %s ] EVP_PKEY_derive failed", o->id_str); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(evp_pkey); + return 1; + } /* Allocate the memory for the shared secret */ - if ((secret = OPENSSL_malloc(secret_len)) == NULL) { + if ((secret = malloc(secret_len)) == NULL) { debug_print(" [ KEY %s ] Failed to allocate memory for secret", o->id_str); - EC_KEY_free(key); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(evp_pkey); return 1; } - pkey = EVP_PKEY_get0_EC_KEY(o->key); - /* Derive the shared secret locally */ - secret_len = ECDH_compute_key(secret, secret_len, - EC_KEY_get0_public_key(pkey), key, NULL); - + + if (EVP_PKEY_derive(pctx, secret, &secret_len) != 1) { + debug_print(" [ KEY %s ] EVP_PKEY_derive failed", o->id_str); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(evp_pkey); + return 1; + } + EVP_PKEY_CTX_free(pctx); + /* Try to do the same with the card key */ - /* Convert the public key to the octet string */ - group = EC_KEY_get0_group(key); + /* Get length of pub */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + group = EC_GROUP_new_by_curve_name(nid); + key = EVP_PKEY_get0_EC_KEY(evp_pkey); publickey = EC_KEY_get0_public_key(key); + pub_len = EC_POINT_point2oct(group, publickey, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); +#else + EVP_PKEY_get_octet_string_param(evp_pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &pub_len); +#endif + /* Allocate memory for public key*/ if (pub_len == 0) { debug_print(" [ KEY %s ] Failed to allocate memory for secret", o->id_str); - EC_KEY_free(key); OPENSSL_free(secret); + EVP_PKEY_free(evp_pkey); return 1; } + pub = malloc(pub_len); if (pub == NULL) { debug_print(" [ OK %s ] Failed to allocate memory", o->id_str); - EC_KEY_free(key); OPENSSL_free(secret); + EVP_PKEY_free(evp_pkey); return 1; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L pub_len = EC_POINT_point2oct(group, publickey, POINT_CONVERSION_UNCOMPRESSED, pub, pub_len, NULL); + if (pub_len == 0) { - debug_print(" [ KEY %s ] Failed to allocate memory for secret", o->id_str); - EC_KEY_free(key); +#else + if (EVP_PKEY_get_octet_string_param(evp_pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, pub, pub_len, NULL) != 1) { +#endif + debug_print(" [ KEY %s ] Can not get public key", o->id_str); + EVP_PKEY_free(evp_pkey); OPENSSL_free(secret); free(pub); return 1; } + EVP_PKEY_free(evp_pkey); pkcs11_secret_len = pkcs11_derive(o, info, pub, pub_len, mech, &pkcs11_secret); - free(pub); if (secret_len == pkcs11_secret_len && memcmp(secret, pkcs11_secret, secret_len) == 0) { mech->result_flags |= FLAGS_DERIVE; debug_print(" [ OK %s ] Derived secrets match", o->id_str); - OPENSSL_free(secret); - free(pkcs11_secret); - return 0; + rv = 0; + } else { + debug_print(" [ KEY %s ] Derived secret does not match", o->id_str); } - debug_print(" [ KEY %s ] Derived secret does not match", o->id_str); + free(pub); OPENSSL_free(secret); free(pkcs11_secret); - return 1; + return rv; } @@ -336,8 +386,8 @@ void derive_tests(void **state) { continue; for (j = 0; j < o->num_mechs; j++) { - if ((o->mechs[j].usage_flags & CKF_DERIVE) == 0 - || ! o->derive_priv) + if ((o->mechs[j].usage_flags & CKF_DERIVE) == 0 || + ! o->derive_priv) continue; switch (o->key_type) { From 165ba30ce065d1f12b1263aecb314d35f5bb6f3e Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 13 Sep 2021 18:15:26 +0200 Subject: [PATCH 2159/4321] p11test: do not use deprecated RSA padding functions from OpenSSL --- src/tests/p11test/p11test_case_readonly.c | 63 +++++++++++++++++------ 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 2fd3a939f5..827a6ca8ee 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -24,6 +24,7 @@ #include #include #include +#include #define MESSAGE_TO_SIGN "Simple message for signing & verifying. " \ "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ @@ -48,7 +49,7 @@ "\xdd\xa3\x76\x44\x2f\x50\xe1\xec" \ "\xd3\x8b\xcd\x6f\xc6\xce\x4e\xfd" \ "\xd3\x1a\x3f" -#define BUFFER_SIZE 4096 +#define BUFFER_SIZE 4096 const unsigned char *const_message = (unsigned char *) MESSAGE_TO_SIGN; @@ -57,13 +58,35 @@ rsa_x_509_pad_message(const unsigned char *message, unsigned long *message_length, test_cert_t *o, int encrypt) { int pad_message_length = (o->bits+7)/8; - unsigned char *pad_message = malloc(pad_message_length); - if (!encrypt) - RSA_padding_add_PKCS1_type_1(pad_message, pad_message_length, - message, *message_length); - else - RSA_padding_add_PKCS1_type_2(pad_message, pad_message_length, - message, *message_length); + unsigned char *pad_message = NULL; + size_t padding_len = pad_message_length - (*message_length) - 3; + + if (pad_message_length - (*message_length) <= 11) { + debug_print("Can not pad message - buffer to small"); + return NULL; + } + if ((pad_message = malloc(pad_message_length)) == NULL) { + fprintf(stderr, "System error: unable to allocate memory\n"); + return NULL; + } + + pad_message[0] = 0x00; + pad_message[pad_message_length - 1] = 0x00; + if (!encrypt) { + pad_message[1] = 0x01; + memset(pad_message + 2, 0xff, padding_len); + } else { + pad_message[1] = 0x02; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (RAND_bytes_ex(NULL, pad_message + 2, padding_len, 0) != 1) { +#else + if (RAND_bytes(pad_message + 2, padding_len) != 1) { +#endif + debug_print("Can not generate random bytes."); + } + } + memcpy(pad_message + 2 + padding_len, message, (*message_length) * sizeof(unsigned char)); + *message_length = pad_message_length; return pad_message; } @@ -218,11 +241,16 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (mech->mech == CKM_RSA_X_509) - message = rsa_x_509_pad_message(const_message, - &message_length, o, 1); - else + if (mech->mech == CKM_RSA_X_509) { + if ((message = rsa_x_509_pad_message(const_message, + &message_length, o, 1)) == NULL) { + debug_print(" [SKIP %s ] Could not pad message", o->id_str); + return -1; + } + } else { message = (CK_BYTE *) strdup(MESSAGE_TO_SIGN); + } + debug_print(" [ KEY %s ] Encrypt message using CKM_%s", o->id_str, get_mechanism_name(mech->mech)); @@ -582,10 +610,13 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (mech->mech == CKM_RSA_X_509) /* manually add padding */ - message = rsa_x_509_pad_message(const_message, - &message_length, o, 0); - else if (mech->mech == CKM_RSA_PKCS) { + if (mech->mech == CKM_RSA_X_509) { /* manually add padding */ + if ((message = rsa_x_509_pad_message(const_message, + &message_length, o, 0)) == NULL) { + debug_print(" [SKIP %s ] Could not pad message", o->id_str); + return -1; + } + } else if (mech->mech == CKM_RSA_PKCS) { /* DigestInfo + SHA1(message) */ message_length = 35; message = malloc(message_length * sizeof(unsigned char)); From 8428a92eef663402ae318d56ffa768ddacf41418 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 21 Sep 2021 16:30:24 +0200 Subject: [PATCH 2160/4321] p11test: Encryption and verify in p11test_case_readonly() --- src/tests/p11test/p11test_case_readonly.c | 80 ++++++++++++++--------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 827a6ca8ee..e71aa9c899 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -98,7 +98,8 @@ int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message size_t outlen = 0; EVP_PKEY_CTX *ctx = NULL; - *enc_message = malloc(EVP_PKEY_size(o->key)); + outlen = EVP_PKEY_size(o->key); + *enc_message = malloc(outlen); if (*enc_message == NULL) { debug_print("malloc returned null"); return -1; @@ -114,7 +115,8 @@ int encrypt_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message free(*enc_message); *enc_message = NULL; EVP_PKEY_CTX_free(ctx); - debug_print("OpenSSL encrypt failed: rv = 0x%.8X\n", rv); + fprintf(stderr, " [ ERROR %s ] OpenSSL encrypt failed: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); return -1; } EVP_PKEY_CTX_free(ctx); @@ -381,14 +383,29 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, int cmp_message_length; if (o->type == EVP_PK_RSA) { - EVP_PKEY_CTX *ctx = NULL; const EVP_MD *md = NULL; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *ctx = NULL; int padding = RSA_PKCS1_PADDING; /* Digest mechanisms */ switch (mech->mech) { case CKM_RSA_X_509: padding = RSA_NO_PADDING; + /* fall through */ + case CKM_RSA_PKCS: + if ((ctx = EVP_PKEY_CTX_new(o->key, NULL)) == NULL || + (rv = EVP_PKEY_verify_init(ctx)) <= 0 || + (rv = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0 || + (rv = EVP_PKEY_verify(ctx, sign, sign_length, message, message_length)) != 1) { + fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", + o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); + EVP_PKEY_CTX_free(ctx); + return -1; + } + mech->result_flags |= FLAGS_SIGN_OPENSSL; + debug_print(" [ OK %s ] Signature is valid.", o->id_str); + return 1; break; case CKM_SHA1_RSA_PKCS: md = EVP_sha1(); @@ -416,47 +433,48 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, return 0; } - ctx = EVP_PKEY_CTX_new(o->key, NULL); - if (!ctx || (rv = EVP_PKEY_verify_init(ctx)) <= 0 || - (rv = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0 || - (md && (rv = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) || - (rv = EVP_PKEY_verify(ctx, sign, sign_length, message, message_length)) != 1) { + if ((mdctx = EVP_MD_CTX_create()) == NULL || + (rv = EVP_DigestVerifyInit(mdctx, NULL, md, NULL, o->key) <= 0) || + (rv = EVP_DigestVerify(mdctx, sign, sign_length, message, message_length)) != 1) { fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); - EVP_PKEY_CTX_free(ctx); + EVP_MD_CTX_free(mdctx); return -1; } - EVP_PKEY_CTX_free(ctx); + mech->result_flags |= FLAGS_SIGN_OPENSSL; debug_print(" [ OK %s ] Signature is valid.", o->id_str); return 1; } else if (o->type == EVP_PK_EC) { unsigned int nlen; - EC_KEY *ec = NULL; ECDSA_SIG *sig = ECDSA_SIG_new(); BIGNUM *r = NULL, *s = NULL; - if (sig == NULL) { - fprintf(stderr, "ECDSA_SIG_new: failed"); + EVP_PKEY_CTX *ctx = NULL; + ctx = EVP_PKEY_CTX_new(o->key, NULL); + + if (!sig || !ctx) { + fprintf(stderr, "Verification failed"); return -1; } nlen = sign_length/2; r = BN_bin2bn(&sign[0], nlen, NULL); s = BN_bin2bn(&sign[nlen], nlen, NULL); ECDSA_SIG_set0(sig, r, s); + switch (mech->mech) { case CKM_ECDSA_SHA512: - EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha512(), NULL); + cmp_message = SHA512(message, message_length, NULL); cmp_message_length = SHA512_DIGEST_LENGTH; break; case CKM_ECDSA_SHA384: - EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha384(), NULL); + cmp_message = SHA384(message, message_length, NULL); cmp_message_length = SHA384_DIGEST_LENGTH; break; case CKM_ECDSA_SHA256: - EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha256(), NULL); + cmp_message = SHA256(message, message_length, NULL); cmp_message_length = SHA256_DIGEST_LENGTH; break; case CKM_ECDSA_SHA1: - EVP_Digest(message, message_length, cmp_message, NULL, EVP_sha1(), NULL); + cmp_message = SHA1(message, message_length, NULL); cmp_message_length = SHA_DIGEST_LENGTH; break; case CKM_ECDSA: @@ -467,17 +485,22 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); return 0; } - ec = EVP_PKEY_get0_EC_KEY(o->key); - rv = ECDSA_do_verify(cmp_message, cmp_message_length, sig, ec); + int sig_asn1_len = 0; + unsigned char *sig_asn1 = NULL; + sig_asn1_len = i2d_ECDSA_SIG(sig, &sig_asn1); + + if (EVP_PKEY_verify_init(ctx) != 1) { + fprintf(stderr, "EVP_PKEY_verify_init\n"); + } + + rv = EVP_PKEY_verify(ctx, sig_asn1, sig_asn1_len, cmp_message, cmp_message_length); if (rv == 1) { - ECDSA_SIG_free(sig); debug_print(" [ OK %s ] EC Signature of length %lu is valid.", o->id_str, message_length); mech->result_flags |= FLAGS_SIGN_OPENSSL; return 1; } else { - ECDSA_SIG_free(sig); - fprintf(stderr, " [FAIL %s ] ECDSA_do_verify: rv = %lu: %s\n", o->id_str, + fprintf(stderr, " [FAIL %s ] EVP_PKEY_verify: rv = %lu: %s\n", o->id_str, rv, ERR_error_string(ERR_peek_last_error(), NULL)); return -1; } @@ -559,7 +582,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, } if (rv == CKR_OK) { mech->result_flags |= FLAGS_SIGN; - debug_print(" [ OK %s ] Verification successful", o->id_str); + debug_print(" [ OK %s ] [PKCS11] Verification successful", o->id_str); return 1; } debug_print(" %s: rv = 0x%.8lX", name, rv); @@ -610,13 +633,10 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (mech->mech == CKM_RSA_X_509) { /* manually add padding */ - if ((message = rsa_x_509_pad_message(const_message, - &message_length, o, 0)) == NULL) { - debug_print(" [SKIP %s ] Could not pad message", o->id_str); - return -1; - } - } else if (mech->mech == CKM_RSA_PKCS) { + if (mech->mech == CKM_RSA_X_509) /* manually add padding */ + message = rsa_x_509_pad_message(const_message, + &message_length, o, 0); + else if (mech->mech == CKM_RSA_PKCS) { /* DigestInfo + SHA1(message) */ message_length = 35; message = malloc(message_length * sizeof(unsigned char)); From f214e655be5ebc11e096824f20ad2d22bd7ce07b Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 17 Sep 2021 12:58:09 +0200 Subject: [PATCH 2161/4321] pkcs15-westcos.c: Non-deprecated way of key generation in OpenSSL3.0 Key generation and conversion to BIO --- src/pkcs15init/pkcs15-westcos.c | 54 +++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 81dad1fdd5..3111c75140 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -32,6 +32,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + #include +#endif #endif #include "libopensc/sc-ossl-compat.h" @@ -217,42 +220,57 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, long lg; u8 *p; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - RSA *rsa = NULL; BIGNUM *bn = NULL; BIO *mem = NULL; - + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *pctx = NULL; sc_file_t *prkf = NULL; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_ENCODER_CTX *ectx = NULL; + int selection = 0; +#endif + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { return SC_ERROR_NOT_SUPPORTED; } - rsa = RSA_new(); - bn = BN_new(); + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); mem = BIO_new(BIO_s_mem()); - - if(rsa == NULL || bn == NULL || mem == NULL) - { + bn = BN_new(); + if (pctx == NULL || key == NULL || mem == NULL || bn == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } - if(!BN_set_word(bn, RSA_F4) || - !RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL)) - { + if (BN_set_word(bn, RSA_F4) != 1 || + EVP_PKEY_keygen_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || +#else + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || +#endif + EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; } - RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); - - if(pubkey != NULL) - { - if(!i2d_RSAPublicKey_bio(mem, rsa)) + if(pubkey != NULL) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if(!i2d_RSAPublicKey_bio(mem, EVP_PKEY_get0_RSA(key))) +#else + selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + ectx = OSSL_ENCODER_CTX_new_for_pkey(key, selection, "DER", "PublicKeyInfo", NULL); + if(ectx == NULL || OSSL_ENCODER_to_bio(ectx, mem) != 1) +#endif { r = SC_ERROR_UNKNOWN; goto out; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_ENCODER_CTX_free(ectx); +#endif lg = BIO_get_mem_data(mem, &p); @@ -265,7 +283,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, (void) BIO_reset(mem); - if(!i2d_RSAPrivateKey_bio(mem, rsa)) + if (!i2d_PrivateKey_bio(mem, key)) { r = SC_ERROR_UNKNOWN; goto out; @@ -299,10 +317,8 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, BIO_free(mem); if(bn) BN_free(bn); - if(rsa) - RSA_free(rsa); + EVP_PKEY_free(key); sc_file_free(prkf); - return r; #endif } From d4e0f4b983982ac4ac61d9b4412c54afb3a44dcb Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 1 Nov 2021 11:44:31 +0100 Subject: [PATCH 2162/4321] pkcs15-westcos.c: Add alias for OpenSSL 3.0 compatibility --- src/pkcs15init/pkcs15-westcos.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 3111c75140..1e20b17f31 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -246,11 +246,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, if (BN_set_word(bn, RSA_F4) != 1 || EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || -#if OPENSSL_VERSION_NUMBER < 0x30000000L EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || -#else - EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || -#endif EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; From 772750ec076f19067ae61607aa28d46e05f631a2 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 17 Sep 2021 15:38:51 +0200 Subject: [PATCH 2163/4321] pkcs15-prkey.c: Use non-deprecated getters in sc_pkcs15_convert_prkey not tested --- src/libopensc/pkcs15-prkey.c | 171 +++++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 29 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index d9b8d0b8df..9c51e9e91c 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -36,6 +36,11 @@ #include #include #include +#include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +#endif #ifndef OPENSSL_NO_EC #include #endif @@ -676,91 +681,199 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) switch (pk_type) { case EVP_PKEY_RSA: { struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa; - RSA *src = EVP_PKEY_get1_RSA(pk); - const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1 = NULL; + RSA *src = NULL; + if (!(src = EVP_PKEY_get1_RSA(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; RSA_get0_key(src, &src_n, &src_e, &src_d); RSA_get0_factors(src, &src_p, &src_q); RSA_get0_crt_params(src, &src_dmp1, &src_dmq1, &src_iqmp); - +#else + BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1 = NULL; + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &src_n) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_E, &src_e) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_D, &src_d) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_FACTOR1, &src_p) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_FACTOR2, &src_q) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_EXPONENT1, &src_dmp1) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_EXPONENT2, &src_dmq1) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &src_iqmp) != 1) { + BN_free(src_n); BN_free(src_e); BN_free(src_d); + BN_free(src_p); BN_free(src_q); + BN_free(src_dmp1); BN_free(src_dmq1); + return SC_ERROR_UNKNOWN; + } +#endif pkcs15_key->algorithm = SC_ALGORITHM_RSA; - if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) - || !sc_pkcs15_convert_bignum(&dst->exponent, src_e) - || !sc_pkcs15_convert_bignum(&dst->d, src_d) - || !sc_pkcs15_convert_bignum(&dst->p, src_p) - || !sc_pkcs15_convert_bignum(&dst->q, src_q)) + if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || + !sc_pkcs15_convert_bignum(&dst->exponent, src_e) || + !sc_pkcs15_convert_bignum(&dst->d, src_d) || + !sc_pkcs15_convert_bignum(&dst->p, src_p) || + !sc_pkcs15_convert_bignum(&dst->q, src_q)) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(src_n); BN_free(src_e); BN_free(src_d); + BN_free(src_p); BN_free(src_q); + BN_free(src_iqmp); BN_free(src_dmp1); BN_free(src_dmq1); +#else + RSA_free(src); +#endif return SC_ERROR_NOT_SUPPORTED; + } if (src_iqmp && src_dmp1 && src_dmq1) { sc_pkcs15_convert_bignum(&dst->iqmp, src_iqmp); sc_pkcs15_convert_bignum(&dst->dmp1, src_dmp1); sc_pkcs15_convert_bignum(&dst->dmq1, src_dmq1); } +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_free(src); +#else + BN_free(src_n); BN_free(src_e); BN_free(src_d); + BN_free(src_p); BN_free(src_q); + BN_free(src_iqmp); BN_free(src_dmp1); BN_free(src_dmq1); +#endif break; } + case EVP_PKEY_DSA: { struct sc_pkcs15_prkey_dsa *dst = &pkcs15_key->u.dsa; - DSA *src = EVP_PKEY_get1_DSA(pk); +#if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key; + DSA *src = NULL; + if (!(src = EVP_PKEY_get1_DSA(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; DSA_get0_key(src, &src_pub_key, &src_priv_key); DSA_get0_pqg(src, &src_p, &src_q, &src_g); - +#else + BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key = NULL; + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &src_q) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &src_g) != 1) { + BN_free(src_p); BN_free(src_q); + BN_free(src_priv_key); BN_free(src_pub_key); + return SC_ERROR_UNKNOWN; + } +#endif pkcs15_key->algorithm = SC_ALGORITHM_DSA; sc_pkcs15_convert_bignum(&dst->pub, src_pub_key); sc_pkcs15_convert_bignum(&dst->p, src_p); sc_pkcs15_convert_bignum(&dst->q, src_q); sc_pkcs15_convert_bignum(&dst->g, src_g); sc_pkcs15_convert_bignum(&dst->priv, src_priv_key); +#if OPENSSL_VERSION_NUMBER < 0x30000000L DSA_free(src); +#else + BN_free(src_pub_key); BN_free(src_p); BN_free(src_q); + BN_free(src_g); BN_free(src_priv_key); +#endif break; } + #if !defined(OPENSSL_NO_EC) case NID_id_GostR3410_2001: { struct sc_pkcs15_prkey_gostr3410 *dst = &pkcs15_key->u.gostr3410; - EC_KEY *src = EVP_PKEY_get0(pk); - - assert(src); pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410; - assert(EC_KEY_get0_private_key(src)); - sc_pkcs15_convert_bignum(&dst->d, EC_KEY_get0_private_key(src)); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *src_priv_key = NULL; + EC_KEY *src = NULL; + if (!(src = EVP_PKEY_get0(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; + if (!(src_priv_key = EC_KEY_get0_private_key(src))) + return SC_ERROR_INTERNAL; +#else + BIGNUM *src_priv_key = NULL; + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1) { + return SC_ERROR_UNKNOWN; + } +#endif + sc_pkcs15_convert_bignum(&dst->d, src_priv_key); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY_free(src); +#else + BN_free(src_priv_key); +#endif break; } + case EVP_PKEY_EC: { struct sc_pkcs15_prkey_ec *dst = &pkcs15_key->u.ec; - const EC_KEY *src = NULL; - const EC_GROUP *grp = NULL; unsigned char buf[255]; size_t buflen = 255; int nid; + pkcs15_key->algorithm = SC_ALGORITHM_EC; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const EC_KEY *src = NULL; + const EC_GROUP *grp = NULL; + const BIGNUM *src_priv_key = NULL; + const EC_POINT *src_pub_key = NULL; + if (!(src = EVP_PKEY_get0_EC_KEY(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; + if (!(src_priv_key = EC_KEY_get0_private_key(src)) || + !(src_pub_key = EC_KEY_get0_public_key(src)) || + !(grp = EC_KEY_get0_group(src))) + return SC_ERROR_INCOMPATIBLE_KEY; + nid = EC_GROUP_get_curve_name(grp); +#else + EC_GROUP *grp = NULL; + BIGNUM *src_priv_key = NULL; + char *grp_name = NULL; size_t grp_name_len = 0; - src = EVP_PKEY_get0_EC_KEY(pk); - assert(src); - assert(EC_KEY_get0_private_key(src)); - assert(EC_KEY_get0_public_key(src)); + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1) { + return SC_ERROR_UNKNOWN; + } - pkcs15_key->algorithm = SC_ALGORITHM_EC; + EVP_PKEY_get_group_name(pk, NULL, 0, &grp_name_len); + if ((grp_name = malloc(grp_name_len)) == NULL) { + BN_free(src_priv_key); + return SC_ERROR_OUT_OF_MEMORY; + } - if (!sc_pkcs15_convert_bignum(&dst->privateD, EC_KEY_get0_private_key(src))) - return SC_ERROR_INCOMPATIBLE_KEY; + if (EVP_PKEY_get_group_name(pk, grp_name, grp_name_len, NULL) != 1 || + (nid = OBJ_sn2nid(grp_name)) == 0 || + (grp = EC_GROUP_new_by_curve_name(nid)) == NULL) { + BN_free(src_priv_key); + free(grp_name); + return SC_ERROR_UNKNOWN; + } +#endif - grp = EC_KEY_get0_group(src); - if(grp == 0) + if (!sc_pkcs15_convert_bignum(&dst->privateD, src_priv_key)) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(src_priv_key); + free(grp_name); + EC_GROUP_free(grp); +#endif return SC_ERROR_INCOMPATIBLE_KEY; + } - /* get curve name */ - nid = EC_GROUP_get_curve_name(grp); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if(nid != 0) { const char *sn = OBJ_nid2sn(nid); if (sn) dst->params.named_curve = strdup(sn); } +#else + dst->params.named_curve = strdup(grp_name); + free(grp_name); +#endif +#if OPENSSL_VERSION_NUMBER < 0x30000000L /* Decode EC_POINT from a octet string */ - buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src), + buflen = EC_POINT_point2oct(grp, src_pub_key, POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL); if (!buflen) return SC_ERROR_INCOMPATIBLE_KEY; +#else + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, NULL) != 1) { + return SC_ERROR_INCOMPATIBLE_KEY; + } +#endif /* copy the public key */ dst->ecpointQ.value = malloc(buflen); From 52171c469a31fe10583f192fc2b866d68be41496 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 21 Sep 2021 12:11:51 +0200 Subject: [PATCH 2164/4321] pkcs15-pubkey.c: Non-deprecated getters in sc_pkcs15_convert_pubkey() --- src/libopensc/pkcs15-pubkey.c | 187 +++++++++++++++++++++++++++------- 1 file changed, 151 insertions(+), 36 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index b93a8c683c..af0f318a4d 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -40,6 +40,10 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +#endif #ifndef OPENSSL_NO_EC #include #endif @@ -1717,50 +1721,141 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) switch (pk_type) { case EVP_PKEY_RSA: { struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa; - RSA *src = EVP_PKEY_get1_RSA(pk); - const BIGNUM *src_n, *src_e; - + /* Get parameters */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *src_n, *src_e = NULL; + RSA *src = NULL; + if (!(src = EVP_PKEY_get1_RSA(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; RSA_get0_key(src, &src_n, &src_e, NULL); - + if (!src_n || !src_e) { + free(src); + return SC_ERROR_INTERNAL; + } +#else + BIGNUM *src_n, *src_e = NULL; + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &src_n) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_E, &src_e) != 1) { + BN_free(src_n); + return SC_ERROR_INTERNAL; + } +#endif + /* Convert */ pkcs15_key->algorithm = SC_ALGORITHM_RSA; - if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || !sc_pkcs15_convert_bignum(&dst->exponent, src_e)) + if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || + !sc_pkcs15_convert_bignum(&dst->exponent, src_e)) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(src); +#else + BN_free(src_n); BN_free(src_e); +#endif return SC_ERROR_INVALID_DATA; + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_free(src); +#else + BN_free(src_n); BN_free(src_e); +#endif break; } case EVP_PKEY_DSA: { struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa; - DSA *src = EVP_PKEY_get1_DSA(pk); - const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; - + /* Get parameters */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g = NULL; + DSA *src = NULL; + if (!(src = EVP_PKEY_get1_DSA(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; DSA_get0_key(src, &src_pub_key, &src_priv_key); DSA_get0_pqg(src, &src_p, &src_q, &src_g); - + if (!src_pub_key || !src_priv_key || !src_p || !src_q || !src_g) { + DSA_free(src); + return SC_ERROR_INTERNAL; + } +#else + BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; + if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &src_q) != 1 || + EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &src_g) != 1) { + BN_free(src_p); BN_free(src_q); + BN_free(src_priv_key); BN_free(src_pub_key); + return SC_ERROR_INTERNAL; + } +#endif + /* Convert */ pkcs15_key->algorithm = SC_ALGORITHM_DSA; - sc_pkcs15_convert_bignum(&dst->pub, src_pub_key); - sc_pkcs15_convert_bignum(&dst->p, src_p); - sc_pkcs15_convert_bignum(&dst->q, src_q); - sc_pkcs15_convert_bignum(&dst->g, src_g); + if (!sc_pkcs15_convert_bignum(&dst->pub, src_pub_key) || + !sc_pkcs15_convert_bignum(&dst->p, src_p) || + !sc_pkcs15_convert_bignum(&dst->q, src_q) || + !sc_pkcs15_convert_bignum(&dst->g, src_g)) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + DSA_free(src); +#else + BN_free(src_p); BN_free(src_q); + BN_free(src_priv_key); BN_free(src_pub_key); +#endif + return SC_ERROR_INVALID_DATA; + } +#if OPENSSL_VERSION_NUMBER < 0x30000000L DSA_free(src); +#else + BN_free(src_p); BN_free(src_q); + BN_free(src_priv_key); BN_free(src_pub_key); +#endif break; } #if !defined(OPENSSL_NO_EC) case NID_id_GostR3410_2001: { struct sc_pkcs15_pubkey_gostr3410 *dst = &pkcs15_key->u.gostr3410; - EC_KEY *eckey = EVP_PKEY_get0(pk); - const EC_POINT *point; BIGNUM *X, *Y; int r = 0; - - assert(eckey); - point = EC_KEY_get0_public_key(eckey); - if (!point) +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const EC_KEY *eckey = NULL; + const EC_POINT *point = NULL; + const EC_GROUP *group = NULL; + if (!(eckey = EVP_PKEY_get0(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; + if (!(point = EC_KEY_get0_public_key(eckey)) || + !(group = EC_KEY_get0_group(eckey))) + return SC_ERROR_INTERNAL; +#else + EC_POINT *point = NULL; + EC_GROUP *group = NULL; + int nid = 0; + unsigned char *pub = NULL; size_t pub_len = 0; + char *group_name = NULL; size_t group_name_len = 0; + EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len); + EVP_PKEY_get_group_name(pk, NULL, 0, &group_name_len); + if (!(pub = malloc(pub_len)) || !(group_name = malloc(group_name_len))) { + free(pub); + return SC_ERROR_OUT_OF_MEMORY; + } + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY, pub, pub_len, NULL) != 1 || + EVP_PKEY_get_group_name(pk, group_name, group_name_len, NULL) != 1) { + free(pub); + free(group_name); + return SC_ERROR_INTERNAL; + } + if ((nid = OBJ_sn2nid(group_name) == 0) || + !(group = EC_GROUP_new_by_curve_name(nid)) || + !(point = EC_POINT_new(group)) || + EC_POINT_oct2point(group, point, pub, pub_len, NULL) != 1) { + free(pub); + free(group_name); + EC_POINT_free(point); + EC_GROUP_free(group); return SC_ERROR_INTERNAL; + } + free(pub); + free(group_name); +#endif X = BN_new(); Y = BN_new(); - if (X && Y && EC_KEY_get0_group(eckey)) - r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey), - point, X, Y, NULL); + if (X && Y && group) + r = EC_POINT_get_affine_coordinates_GFp(group, point, X, Y, NULL); if (r == 1) { dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y); dst->xy.data = malloc(dst->xy.len); @@ -1777,38 +1872,58 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) } BN_free(X); BN_free(Y); + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EC_GROUP_free(group); + EC_POINT_free(point); +#endif if (r != 1) return SC_ERROR_INTERNAL; break; } case EVP_PKEY_EC: { struct sc_pkcs15_pubkey_ec *dst = &pkcs15_key->u.ec; + pkcs15_key->algorithm = SC_ALGORITHM_EC; + unsigned char buf[255]; size_t buflen = 255; +#if OPENSSL_VERSION_NUMBER < 0x30000000L const EC_KEY *src = NULL; const EC_GROUP *grp = NULL; - unsigned char buf[255]; - size_t buflen = 255; - int nid; - - src = EVP_PKEY_get0_EC_KEY(pk); - assert(src); - assert(EC_KEY_get0_public_key(src)); + const EC_POINT *point = NULL; + int nid = 0; - pkcs15_key->algorithm = SC_ALGORITHM_EC; - grp = EC_KEY_get0_group(src); - if(grp == 0) + if (!(src = EVP_PKEY_get0_EC_KEY(pk))) + return SC_ERROR_INCOMPATIBLE_KEY; + if (!(point = EC_KEY_get0_public_key(src)) || + !(grp = EC_KEY_get0_group(src))) { return SC_ERROR_INCOMPATIBLE_KEY; + } /* Decode EC_POINT from a octet string */ - buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src), + buflen = EC_POINT_point2oct(grp, point, POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL); /* get curve name */ nid = EC_GROUP_get_curve_name(grp); if(nid != 0) { - const char *name = OBJ_nid2sn(nid); - if (name) - dst->params.named_curve = strdup(name); + const char *group_name = OBJ_nid2sn(nid); + if (group_name) + dst->params.named_curve = strdup(group_name); + } +#else + char *group_name = NULL; size_t group_name_len = 0; + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, NULL) != 1) + return SC_ERROR_INTERNAL; + EVP_PKEY_get_group_name(pk, NULL, 0, &group_name_len); + if (group_name_len != 0) { + if (!(group_name = malloc(group_name_len)) || + EVP_PKEY_get_group_name(pk, group_name, group_name_len, NULL)) { + free(group_name); + return SC_ERROR_INTERNAL; + } } + dst->params.named_curve = strdup(group_name); + free(group_name); +#endif /* copy the public key */ if (buflen > 0) { From d97c66541ce2145259f26e27ffefd06a4a3ca465 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 1 Nov 2021 14:31:43 +0100 Subject: [PATCH 2165/4321] cwa14890.c: EVP_PKEY RSA encrypt/decrypt --- src/libopensc/cwa14890.c | 146 ++++++++++++++++++++++++++++++--------- 1 file changed, 113 insertions(+), 33 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 3ca3f2f2e4..9e3ba290f6 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -43,6 +43,11 @@ #include #include "cwa14890.h" #include "cwa-dnie.h" +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +# include +#endif #define MAX_RESP_BUFFER_SIZE 2048 @@ -512,15 +517,15 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da * * @param card pointer to st_card_t card data information * @param icc_pubkey public key of card - * @param ifd_privkey private RSA key of ifd + * @param ifd_privkey private key of ifd * @param sn_icc card serial number * @param sig signature buffer * @param sig_len signature buffer length * @return SC_SUCCESS if ok; else errorcode */ static int cwa_prepare_external_auth(sc_card_t * card, - const RSA * icc_pubkey, - const RSA * ifd_privkey, + EVP_PKEY *icc_pubkey, + EVP_PKEY *ifd_privkey, u8 * sig, size_t sig_len) { @@ -545,18 +550,30 @@ static int cwa_prepare_external_auth(sc_card_t * card, */ char *msg = NULL; /* to store error messages */ int res = SC_SUCCESS; - u8 *buf1; /* where to encrypt with icc pub key */ - u8 *buf2; /* where to encrypt with ifd pub key */ - u8 *buf3; /* where to compose message to be encrypted */ - int len1, len2, len3; - u8 *sha_buf; /* to compose message to be sha'd */ - u8 *sha_data; /* sha signature data */ + u8 *buf1 = NULL; /* where to encrypt with icc pub key */ + u8 *buf2 = NULL; /* where to encrypt with ifd pub key */ + u8 *buf3 = NULL; /* where to compose message to be encrypted */ + size_t len1, len2, len3; + u8 *sha_buf = NULL; /* to compose message to be sha'd */ + u8 *sha_data = NULL; /* sha signature data */ BIGNUM *bn = NULL; BIGNUM *bnsub = NULL; BIGNUM *bnres = NULL; sc_context_t *ctx = NULL; - const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d; struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa; + EVP_PKEY_CTX *pctx = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d = NULL; + RSA *rsa_ifd_privkey = EVP_PKEY_get0_RSA(ifd_privkey); + if (!rsa_ifd_privkey) { + res = SC_ERROR_INTERNAL; + msg = "Can not extract RSA object ifd priv"; + goto prepare_external_auth_end; + } +#else + BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d = NULL; +#endif /* safety check */ if (!card || !card->ctx) @@ -594,12 +611,18 @@ static int cwa_prepare_external_auth(sc_card_t * card, buf3[127] = 0xBC; /* iso padding */ /* encrypt with ifd private key */ - len2 = RSA_private_decrypt(128, buf3, buf2, (RSA *)ifd_privkey, RSA_NO_PADDING); - if (len2 < 0) { + pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL); + if (!pctx || + EVP_PKEY_decrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_decrypt(pctx, buf2, &len2, buf3, 128) != 1) { msg = "Prepare external auth: ifd_privk encrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; + EVP_PKEY_CTX_free(pctx); goto prepare_external_auth_end; } + EVP_PKEY_CTX_free(pctx); + pctx = NULL; /* evaluate value of minsig and store into buf3 */ bn = BN_bin2bn(buf2, len2, NULL); @@ -609,7 +632,18 @@ static int cwa_prepare_external_auth(sc_card_t * card, res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; } - RSA_get0_key(ifd_privkey, &ifd_privkey_n, &ifd_privkey_e, &ifd_privkey_d); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, &ifd_privkey_e, &ifd_privkey_d); +#else + if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1 || + EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_E, &ifd_privkey_e) != 1 || + EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_D, &ifd_privkey_d) != 1) { + msg = "Prepare external auth: BN get param failed"; + res = SC_ERROR_INTERNAL; + goto prepare_external_auth_end; + } +#endif + res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */ if (res == 0) { /* 1:success 0 fail */ msg = "Prepare external auth: BN sigmin evaluation failed"; @@ -630,12 +664,18 @@ static int cwa_prepare_external_auth(sc_card_t * card, } /* re-encrypt result with icc public key */ - len1 = RSA_public_encrypt(len3, buf3, buf1, (RSA *)icc_pubkey, RSA_NO_PADDING); - if (len1 <= 0 || (size_t) len1 != sig_len) { + pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL); + if (!pctx || + EVP_PKEY_encrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_encrypt(pctx, buf1, &len1, buf3, 128) != 1 || + (size_t) len1 != sig_len) { msg = "Prepare external auth: icc_pubk encrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; + EVP_PKEY_CTX_free(pctx); goto prepare_external_auth_end; } + EVP_PKEY_CTX_free(pctx); /* process done: copy result into cwa_internal buffer and return success */ memcpy(sig, buf1, len1); @@ -842,8 +882,8 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data) * @return SC_SUCCESS if ok; else error code */ static int cwa_verify_internal_auth(sc_card_t * card, - const RSA * icc_pubkey, - const RSA * ifd_privkey, + EVP_PKEY *icc_pubkey, + EVP_PKEY *ifd_privkey, u8 * ifdbuf, size_t ifdlen, u8 * sig, @@ -854,14 +894,24 @@ static int cwa_verify_internal_auth(sc_card_t * card, u8 *buf1 = NULL; /* to decrypt with our private key */ u8 *buf2 = NULL; /* to try SIGNUM==SIG */ u8 *buf3 = NULL; /* to try SIGNUM==N.ICC-SIG */ - int len1 = 0; - int len2 = 0; - int len3 = 0; + size_t len1, len2, len3 = 0; BIGNUM *bn = NULL; BIGNUM *sigbn = NULL; sc_context_t *ctx = NULL; - const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d; struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa; + EVP_PKEY_CTX *pctx = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d = NULL; + RSA *rsa_icc_pubkey = EVP_PKEY_get0_RSA(icc_pubkey); + if (!rsa_icc_pubkey) { + res = SC_ERROR_INTERNAL; + msg = "Can not extract RSA object icc pub"; + goto verify_internal_done; + } +#else + BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d = NULL; +#endif if (!card || !card->ctx) return SC_ERROR_INVALID_ARGUMENTS; @@ -901,19 +951,34 @@ static int cwa_verify_internal_auth(sc_card_t * card, */ /* decrypt data with our ifd priv key */ - len1 = RSA_private_decrypt(sig_len, sig, buf1, (RSA *)ifd_privkey, RSA_NO_PADDING); - if (len1 <= 0) { + pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL); + if (!pctx || + EVP_PKEY_decrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_decrypt(pctx, buf1, &len1, sig, sig_len) != 1) { msg = "Verify Signature: decrypt with ifd privk failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; + EVP_PKEY_CTX_free(pctx); goto verify_internal_done; } + EVP_PKEY_CTX_free(pctx); + pctx = NULL; /* OK: now we have SIGMIN in buf1 */ /* check if SIGMIN data matches SIG or N.ICC-SIG */ /* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */ - len3 = RSA_public_encrypt(len1, buf1, buf3, (RSA *) icc_pubkey, RSA_NO_PADDING); - if (len3 <= 0) + pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL); + if (!pctx || + EVP_PKEY_encrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1)) { + EVP_PKEY_CTX_free(pctx); goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */ + } + + EVP_PKEY_CTX_free(pctx); + pctx = NULL; + res = cwa_compare_signature(buf3, len3, ifdbuf); if (res == SC_SUCCESS) goto verify_internal_ok; @@ -930,7 +995,17 @@ static int cwa_verify_internal_auth(sc_card_t * card, res = SC_ERROR_OUT_OF_MEMORY; goto verify_internal_done; } - RSA_get0_key(icc_pubkey, &icc_pubkey_n, &icc_pubkey_e, &icc_pubkey_d); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, &icc_pubkey_e, &icc_pubkey_d); +#else + if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1 || + EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_E, &icc_pubkey_e) != 1 || + EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_D, &icc_pubkey_d) != 1) { + msg = "Verify Signature: BN get param failed"; + res = SC_ERROR_INTERNAL; + goto verify_internal_ok; + } +#endif res = BN_sub(sigbn, icc_pubkey_n, bn); /* eval N.ICC-SIG */ if (!res) { msg = "Verify Signature: evaluation of N.ICC-SIG failed"; @@ -945,12 +1020,19 @@ static int cwa_verify_internal_auth(sc_card_t * card, } /* ok: check again with new data */ /* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */ - len3 = RSA_public_encrypt(len2, buf2, buf3, (RSA *)icc_pubkey, RSA_NO_PADDING); - if (len3 <= 0) { + pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL); + if (!pctx || + EVP_PKEY_encrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_encrypt(pctx, buf3, &len3, buf2, len2) != 1) { msg = "Verify Signature: cannot get valid SIG data"; res = SC_ERROR_INVALID_DATA; + EVP_PKEY_CTX_free(pctx); goto verify_internal_done; } + EVP_PKEY_CTX_free(pctx); + pctx = NULL; + res = cwa_compare_signature(buf3, len3, ifdbuf); if (res != SC_SUCCESS) { msg = "Verify Signature: cannot get valid SIG data"; @@ -1276,8 +1358,8 @@ int cwa_create_secure_channel(sc_card_t * card, /* verify received signature */ sc_log(ctx, "Verify Internal Auth command response"); - res = cwa_verify_internal_auth(card, EVP_PKEY_get0_RSA(icc_pubkey), /* evaluated icc public key */ - EVP_PKEY_get0_RSA(ifd_privkey), /* evaluated from DGP's Manual Annex 3 Data */ + res = cwa_verify_internal_auth(card, icc_pubkey, /* evaluated icc public key */ + ifd_privkey, /* evaluated from DGP's Manual Annex 3 Data */ rndbuf, /* RND.IFD || SN.IFD */ 16, /* rndbuf length; should be 16 */ sig, 128 @@ -1296,9 +1378,7 @@ int cwa_create_secure_channel(sc_card_t * card, } /* compose signature data for external auth */ - res = cwa_prepare_external_auth(card, - EVP_PKEY_get0_RSA(icc_pubkey), - EVP_PKEY_get0_RSA(ifd_privkey), sig, 128); + res = cwa_prepare_external_auth(card, icc_pubkey, ifd_privkey, sig, 128); if (res != SC_SUCCESS) { msg = "Prepare external auth failed"; goto csc_end; From 31885ebd086e2f1560137be09b470c94624f8803 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 1 Nov 2021 14:41:18 +0100 Subject: [PATCH 2166/4321] cwa14890.c: EVP_PKEY DES encrypt/decrypt DES_ede3_cbc_encrypt() perform C=E(ks3,D(ks2,E(ks1,M))), where ks3 = ks1 in that case, EVP_Encrypt* with EVP_des_ede_cbc() performs two key triple DES in CBC. --- src/libopensc/cwa14890.c | 150 ++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 41 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 9e3ba290f6..8db6df4582 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -49,6 +49,10 @@ # include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PROVIDER *legacy_provider = NULL; +#endif + #define MAX_RESP_BUFFER_SIZE 2048 /** @@ -1456,8 +1460,6 @@ int cwa_encode_apdu(sc_card_t * card, u8 *ccbuf = NULL; /* where to store data to eval cryptographic checksum CC */ size_t cclen = 0; u8 macbuf[8]; /* to store and compute CC */ - DES_key_schedule k1; - DES_key_schedule k2; char *msg = NULL; size_t i, j; /* for xor loops */ @@ -1467,6 +1469,10 @@ int cwa_encode_apdu(sc_card_t * card, u8 *msgbuf = NULL; /* to encrypt apdu data */ u8 *cryptbuf = NULL; + EVP_CIPHER_CTX *cctx = NULL; + unsigned char *key = NULL; + int tmplen = 0; + /* mandatory check */ if (!card || !card->ctx || !provider) return SC_ERROR_INVALID_ARGUMENTS; @@ -1534,30 +1540,36 @@ int cwa_encode_apdu(sc_card_t * card, *(ccbuf + cclen++) = to->p2; cwa_iso7816_padding(ccbuf, &cclen); /* pad header (4 bytes pad) */ + if (!(cctx = EVP_CIPHER_CTX_new())) { + res = SC_ERROR_INTERNAL; + goto err; + } + /* if no data, skip data encryption step */ if (from->lc != 0) { - size_t dlen = from->lc; - - /* prepare keys */ - DES_cblock iv = { 0, 0, 0, 0, 0, 0, 0, 0 }; - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[0]), - &k1); - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[8]), - &k2); + unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int dlen = from->lc; + size_t len = dlen; /* pad message */ memcpy(msgbuf, from->data, dlen); - cwa_iso7816_padding(msgbuf, &dlen); + cwa_iso7816_padding(msgbuf, &len); + dlen = len; /* start kriptbuff with iso padding indicator */ *cryptbuf = 0x01; - /* apply TDES + CBC with kenc and iv=(0,..,0) */ - DES_ede3_cbc_encrypt(msgbuf, cryptbuf + 1, dlen, &k1, &k2, &k1, - &iv, DES_ENCRYPT); + key = sm_session->session_enc; + + if (EVP_EncryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || + EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || + EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { + msg = "Error in encrypting APDU"; + goto encode_end; + } + dlen += tmplen; + /* compose data TLV and add to result buffer */ - res = - cwa_compose_tlv(card, 0x87, dlen + 1, cryptbuf, &ccbuf, - &cclen); + res = cwa_compose_tlv(card, 0x87, dlen + 1, cryptbuf, &ccbuf, &cclen); if (res != SC_SUCCESS) { msg = "Error in compose tag 8x87 TLV"; goto encode_end; @@ -1593,22 +1605,45 @@ int cwa_encode_apdu(sc_card_t * card, msg = "Error in computing SSC"; goto encode_end; } - /* set up keys for mac computing */ - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[0]),&k1); - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[8]),&k2); memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */ + + tmplen = 0; + key = sm_session->session_mac; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); +#endif + + if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; + goto encode_end; + } + for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */ /* compute DES */ - DES_ecb_encrypt((const_DES_cblock *) macbuf, - (DES_cblock *) macbuf, &k1, DES_ENCRYPT); + if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf , 8) != 1) { + msg = "Error in DES ECB encryption"; + goto encode_end; + } /* XOR with next data and repeat */ for (j = 0; j < 8; j++) macbuf[j] ^= ccbuf[i + j]; } + if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, NULL) != 1) { + msg = "Error in DES ECB encryption"; + goto encode_end; + } + /* and apply 3DES to result */ - DES_ecb2_encrypt((const_DES_cblock *) macbuf, (DES_cblock *) macbuf, - &k1, &k2, DES_ENCRYPT); + if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + msg = "Error in 3DEC ECB encryption"; + goto encode_end; + } /* compose and add computed MAC TLV to result buffer */ tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4; @@ -1635,6 +1670,8 @@ int cwa_encode_apdu(sc_card_t * card, if (from->resp != to->resp) free(to->resp); encode_end_apdu_valid: + if (cctx) + EVP_CIPHER_CTX_free(cctx); if (msg) sc_log(ctx, "%s", msg); free(msgbuf); @@ -1672,13 +1709,18 @@ int cwa_decode_response(sc_card_t * card, size_t cclen = 0; /* ccbuf len */ u8 macbuf[8]; /* where to calculate mac */ size_t resplen = 0; /* respbuf length */ - DES_key_schedule k1; - DES_key_schedule k2; int res = SC_SUCCESS; char *msg = NULL; /* to store error messages */ sc_context_t *ctx = NULL; struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa; + EVP_CIPHER_CTX *cctx = NULL; + unsigned char *key = NULL; + int tmplen = 0; + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + return SC_ERROR_INTERNAL; + /* mandatory check */ if (!card || !card->ctx || !provider) return SC_ERROR_INVALID_ARGUMENTS; @@ -1798,22 +1840,43 @@ int cwa_decode_response(sc_card_t * card, msg = "Error in computing SSC"; goto response_decode_end; } - /* set up keys for mac computing */ - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[0]), &k1); - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_mac[8]), &k2); + /* set up key for mac computing */ + key = sm_session->session_mac; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); +#endif + + if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; + goto response_decode_end; + } memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */ for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */ /* compute DES */ - DES_ecb_encrypt((const_DES_cblock *) macbuf, - (DES_cblock *) macbuf, &k1, DES_ENCRYPT); + if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) { + msg = "Error in DES ECB encryption"; + goto response_decode_end; + } /* XOR with data and repeat */ for (j = 0; j < 8; j++) macbuf[j] ^= ccbuf[i + j]; } + if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + msg = "Error in DES ECB encryption"; + goto response_decode_end; + } + /* finally apply 3DES to result */ - DES_ecb2_encrypt((const_DES_cblock *) macbuf, (DES_cblock *) macbuf, - &k1, &k2, DES_ENCRYPT); + if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + msg = "Error in 3DEC ECB encryption"; + goto response_decode_end; + } /* check evaluated mac with provided by apdu response */ @@ -1843,7 +1906,8 @@ int cwa_decode_response(sc_card_t * card, /* if encoded data, decode and store into apdu response */ else if (e_tlv->buf) { /* encoded data */ - DES_cblock iv = { 0, 0, 0, 0, 0, 0, 0, 0 }; + unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int dlen = apdu->resplen; /* check data len */ if ((e_tlv->len < 9) || ((e_tlv->len - 1) % 8) != 0) { msg = "Invalid length for Encoded data TLV"; @@ -1857,15 +1921,18 @@ int cwa_decode_response(sc_card_t * card, goto response_decode_end; } /* prepare keys to decode */ - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[0]), - &k1); - DES_set_key_unchecked((const_DES_cblock *) & (sm_session->session_enc[8]), - &k2); + key = sm_session->session_enc; + /* decrypt into response buffer * by using 3DES CBC by mean of kenc and iv={0,...0} */ - DES_ede3_cbc_encrypt(&e_tlv->data[1], apdu->resp, e_tlv->len - 1, - &k1, &k2, &k1, &iv, DES_DECRYPT); - apdu->resplen = e_tlv->len - 1; + if (EVP_DecryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || + EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], e_tlv->len - 1) || + EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen)) { + msg = "Can not decrypt 3DES CBC"; + goto response_decode_end; + } + apdu->resplen = dlen + tmplen; + /* remove iso padding from response length */ for (; (apdu->resplen > 0) && *(apdu->resp + apdu->resplen - 1) == 0x00; apdu->resplen--) ; /* empty loop */ @@ -1886,6 +1953,7 @@ int cwa_decode_response(sc_card_t * card, res = SC_SUCCESS; response_decode_end: + EVP_CIPHER_CTX_free(cctx); if (buffer) free(buffer); if (ccbuf) From 15893649cbb4649ce9f04384de6fcdcdbfe39b44 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 4 Oct 2021 16:46:38 +0200 Subject: [PATCH 2167/4321] cwa-dnie.c: Compose public and private key For OpenSSL 3.0 use OSSL_PARAM and EVP_PKEY API --- src/libopensc/cwa-dnie.c | 113 ++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index b8e39b305f..b336641c57 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -44,6 +44,10 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +#endif #define MAX_RESP_BUFFER_SIZE 2048 @@ -675,10 +679,26 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce */ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) { - int res=SC_SUCCESS; - RSA *root_ca_rsa=NULL; - BIGNUM *root_ca_rsa_n, *root_ca_rsa_e; + int res = SC_SUCCESS; + BIGNUM *root_ca_rsa_n, *root_ca_rsa_e = NULL; dnie_channel_data_t *data; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *root_ca_rsa = NULL; + root_ca_rsa = RSA_new(); + *root_ca_key = EVP_PKEY_new(); + if (!root_ca_rsa || !*root_ca_key) { +#else + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx) { +#endif + sc_log(card->ctx, "Cannot create data for root CA public key"); + return SC_ERROR_OUT_OF_MEMORY; + } + LOG_FUNC_CALLED(card->ctx); /* obtain the data channel info for the card */ @@ -686,33 +706,51 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) LOG_TEST_RET(card->ctx, res, "Error getting the card channel data"); /* compose root_ca_public key with data provided by Dnie Manual */ - *root_ca_key = EVP_PKEY_new(); - root_ca_rsa = RSA_new(); - if (!*root_ca_key || !root_ca_rsa) { - sc_log(card->ctx, "Cannot create data for root CA public key"); - return SC_ERROR_OUT_OF_MEMORY; - } - root_ca_rsa_n = BN_bin2bn(data->icc_root_ca.modulus.value, data->icc_root_ca.modulus.len, NULL); root_ca_rsa_e = BN_bin2bn(data->icc_root_ca.exponent.value, data->icc_root_ca.exponent.len, NULL); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) { BN_free(root_ca_rsa_n); BN_free(root_ca_rsa_e); if (*root_ca_key) EVP_PKEY_free(*root_ca_key); - if (root_ca_rsa) - RSA_free(root_ca_rsa); + RSA_free(root_ca_rsa); sc_log(card->ctx, "Cannot set RSA values for CA public key"); return SC_ERROR_INTERNAL; } - res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa); if (!res) { + RSA_free(root_ca_rsa); +#else + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", root_ca_rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", root_ca_rsa_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + sc_log(card->ctx, "Cannot set RSA values for CA public key"); + return SC_ERROR_INTERNAL; + } + OSSL_PARAM_BLD_free(bld); + + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, root_ca_key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); +#endif + BN_free(root_ca_rsa_n); + BN_free(root_ca_rsa_e); if (*root_ca_key) EVP_PKEY_free(*root_ca_key); /*implies root_ca_rsa free() */ sc_log(card->ctx, "Cannot compose root CA public key"); return SC_ERROR_INTERNAL; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); +#endif LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -823,22 +861,31 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, u8 * public_exponent, int public_exponent_len, u8 * private_exponent, int private_exponent_len) { - RSA *ifd_rsa=NULL; BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL; - int res=SC_SUCCESS; - - LOG_FUNC_CALLED(card->ctx); - /* compose ifd_private key with data provided in Annex 3 of DNIe Manual */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *ifd_rsa = RSA_new(); *ifd_privkey = EVP_PKEY_new(); - ifd_rsa = RSA_new(); - if (!*ifd_privkey || !ifd_rsa) { + int res = SC_ERROR_INTERNAL; + if (!ifd_rsa || !*ifd_privkey) { +#else + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx) { +#endif sc_log(card->ctx, "Cannot create data for IFD private key"); return SC_ERROR_OUT_OF_MEMORY; } + + LOG_FUNC_CALLED(card->ctx); + + /* compose ifd_private key with data provided in Annex 3 of DNIe Manual */ ifd_rsa_n = BN_bin2bn(modulus, modulus_len, NULL); ifd_rsa_e = BN_bin2bn(public_exponent, public_exponent_len, NULL); ifd_rsa_d = BN_bin2bn(private_exponent, private_exponent_len, NULL); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) { BN_free(ifd_rsa_n); BN_free(ifd_rsa_e); @@ -851,11 +898,37 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa); if (!res) { + RSA_free(ifd_rsa); +#else + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", ifd_rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", ifd_rsa_e) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "d", ifd_rsa_d) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + sc_log(card->ctx, "Cannot set RSA values for CA public key"); + return SC_ERROR_INTERNAL; + } + OSSL_PARAM_BLD_free(bld); + + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEY_PARAMETERS, params) != 1) { + EVP_PKEY_CTX_free(ctx); +#endif + BN_free(ifd_rsa_n); + BN_free(ifd_rsa_e); + BN_free(ifd_rsa_d); if (*ifd_privkey) EVP_PKEY_free(*ifd_privkey); /* implies ifd_rsa free() */ sc_log(card->ctx, "Cannot compose IFD private key"); return SC_ERROR_INTERNAL; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); +#endif LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } From 8c74e46238b36a8252ab06a7d2be00ab165ed513 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 1 Oct 2021 16:15:11 +0200 Subject: [PATCH 2168/4321] card-westcos.c: EVP_PKEY API for RSA and DES --- src/libopensc/card-westcos.c | 50 ++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index afcc5f146b..9c0b952f5f 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -663,7 +663,10 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, { int r; #ifdef ENABLE_OPENSSL - DES_key_schedule ks1, ks2; + EVP_CIPHER_CTX *cctx = NULL; + int tmplen = 0; + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + return SC_ERROR_INTERNAL; #endif u8 buf[8]; if ((*len) < sizeof(buf)) @@ -673,9 +676,14 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, if (r) return r; #ifdef ENABLE_OPENSSL - DES_set_key((const_DES_cblock *) & key[0], &ks1); - DES_set_key((const_DES_cblock *) & key[8], &ks2); - DES_ecb2_encrypt((const_DES_cblock *)buf, (DES_cblock*)result, &ks1, &ks2, DES_ENCRYPT); + if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx,0) != 1 || + EVP_EncryptUpdate(cctx, result, &tmplen, buf, *len) != 1) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } + *len = tmplen; + EVP_CIPHER_CTX_free(cctx); return SC_SUCCESS; #else return SC_ERROR_NOT_SUPPORTED; @@ -1103,8 +1111,9 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, u8 buf[180]; priv_data_t *priv_data = NULL; int pad; - RSA *rsa = NULL; + EVP_PKEY_CTX *ctx = NULL; BIO *mem = BIO_new(BIO_s_mem()); + EVP_PKEY *pkey = NULL; #endif if (card == NULL) @@ -1175,29 +1184,33 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, idx += r; } while (1); BIO_set_mem_eof_return(mem, -1); - if (!d2i_RSAPrivateKey_bio(mem, &rsa)) { + if (!(pkey = d2i_PrivateKey_bio(mem, NULL))) { sc_log(card->ctx, "RSA key invalid, %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; } - /* pkcs11 reset openssl functions */ - RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); - - if ((size_t)RSA_size(rsa) > outlen) { + if ((size_t)EVP_PKEY_size(pkey) > outlen) { sc_log(card->ctx, "Buffer too small\n"); r = SC_ERROR_OUT_OF_MEMORY; goto out; } + + if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { + sc_log(card->ctx, "Can not establish context\n"); + r = SC_ERROR_UNKNOWN; + goto out; + } + #if 1 if (mode) { /* decipher */ - r = RSA_private_decrypt(data_len, data, out, rsa, pad); - if (r == -1) { + if (EVP_PKEY_decrypt_init(ctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1 || + (r = EVP_PKEY_decrypt(ctx, out, NULL, data, data_len)) != 1) { #ifdef DEBUG_SSL print_openssl_error(); - #endif sc_log(card->ctx, "Decipher error %lu\n", ERR_get_error()); @@ -1207,13 +1220,12 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, } else { /* sign */ - - r = RSA_private_encrypt(data_len, data, out, rsa, pad); - if (r == -1) { + if (EVP_PKEY_encrypt_init(ctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1 || + (r = EVP_PKEY_encrypt(ctx, out, NULL, data, data_len)) != 1) { #ifdef DEBUG_SSL print_openssl_error(); - #endif sc_log(card->ctx, "Signature error %lu\n", ERR_get_error()); @@ -1235,8 +1247,8 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, out: if (mem) BIO_free(mem); - if (rsa) - RSA_free(rsa); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); out2: #endif /* ENABLE_OPENSSL */ sc_file_free(keyfile); From 955a51d0ed6eb1b290f3abe7a2408ba0455d4ac3 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:05:47 +0200 Subject: [PATCH 2169/4321] pkcs11-tool: Deprecated RSA param getters parse_rsa_pkey() Use of EVP_PKEY_get_bn_param() instead --- src/tools/pkcs11-tool.c | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fb78a1d194..2940b95ff4 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -49,6 +49,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +#endif #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include #include @@ -3585,11 +3588,11 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) static int parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA *r; const BIGNUM *r_n, *r_e, *r_d; const BIGNUM *r_p, *r_q; const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; - r = EVP_PKEY_get1_RSA(pkey); if (!r) { if (private) @@ -3599,25 +3602,59 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) } RSA_get0_key(r, &r_n, &r_e, NULL); +#else + BIGNUM *r_n, *r_e, *r_d; + BIGNUM *r_p, *r_q; + BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) { + if (private) + util_fatal("OpenSSL error during RSA private key parsing"); + else + util_fatal("OpenSSL error during RSA public key parsing"); + } +#endif RSA_GET_BN(rsa, modulus, r_n); RSA_GET_BN(rsa, public_exponent, r_e); if (private) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_get0_key(r, NULL, NULL, &r_d); + RSA_get0_factors(r, &r_p, &r_q); + RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp); +#else + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_d) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_p) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT3, &r_iqmp) != 1) { + util_fatal("OpenSSL error during RSA private key parsing"); + } +#endif RSA_GET_BN(rsa, private_exponent, r_d); - RSA_get0_factors(r, &r_p, &r_q); RSA_GET_BN(rsa, prime_1, r_p); RSA_GET_BN(rsa, prime_2, r_q); - RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp); RSA_GET_BN(rsa, exponent_1, r_dmp1); RSA_GET_BN(rsa, exponent_2, r_dmq1); RSA_GET_BN(rsa, coefficient, r_iqmp); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_clear_free(r_d); + BN_clear_free(r_p); + BN_clear_free(r_q); + BN_clear_free(r_dmp1); + BN_clear_free(r_dmq1); + BN_clear_free(r_iqmp); +#endif } - +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_free(r); - +#else + BN_free(r_n); + BN_free(r_e); +#endif return 0; } From 8c671efe3dc229f9031cc3640b8f9a5f99b40c12 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:07:01 +0200 Subject: [PATCH 2170/4321] pkcs11-tool: Deprecated EC param get in parse_gost_pkey() Group, public, private key --- src/tools/pkcs11-tool.c | 63 +++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2940b95ff4..7d6517b56a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3662,17 +3662,30 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) static int parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) { - EC_KEY *src = EVP_PKEY_get0(pkey); unsigned char *pder; - const BIGNUM *bignum; BIGNUM *X, *Y; - const EC_POINT *point; int nid, rv; - +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *bignum; + const EC_GROUP *group; + const EC_POINT *point; + EC_KEY *src = EVP_PKEY_get0(pkey); if (!src) return -1; + group = EC_KEY_get0_group(src); + nid = EC_GROUP_get_curve_name(group); +#else + unsigned char *pubkey = NULL; + size_t pubkey_len = 0; + BIGNUM *bignum = NULL; + EC_GROUP *group = NULL; + EC_POINT *point = NULL; + char name[256]; size_t len = 0; + if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1) + return -1; - nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0(pkey))); + nid = OBJ_txt2nid(name); +#endif rv = i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL); if (rv < 0) return -1; @@ -3686,22 +3699,45 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) gost->param_oid.len = rv; if (private) { - bignum = EC_KEY_get0_private_key(EVP_PKEY_get0(pkey)); - +#if OPENSSL_VERSION_NUMBER < 0x30000000L + bignum = EC_KEY_get0_private_key(src); +#else + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bignum) != 1) + return -1; +#endif gost->private.len = BN_num_bytes(bignum); gost->private.value = malloc(gost->private.len); - if (!gost->private.value) + if (!gost->private.value) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(bignum); +#endif return -1; + } BN_bn2bin(bignum, gost->private.value); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(bignum); +#endif } else { X = BN_new(); Y = BN_new(); +#if OPENSSL_VERSION_NUMBER < 0x30000000L point = EC_KEY_get0_public_key(src); +#else + group = EC_GROUP_new_by_curve_name(nid); + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pubkey_len); + if (!(pubkey = malloc(pubkey_len)) || + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey, pubkey_len, NULL) != 1 || + !(point = EC_POINT_new(group)) || + EC_POINT_oct2point(group, point, pubkey, pubkey_len, NULL) != 1) { + EC_GROUP_free(group); + EC_POINT_free(point); + return -1; + } +#endif rv = -1; - if (X && Y && point && EC_KEY_get0_group(src)) - rv = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(src), - point, X, Y, NULL); + if (X && Y && point && group) + rv = EC_POINT_get_affine_coordinates(group, point, X, Y, NULL); if (rv == 1) { gost->public.len = BN_num_bytes(X) + BN_num_bytes(Y); gost->public.value = malloc(gost->public.len); @@ -3715,10 +3751,13 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) } BN_free(X); BN_free(Y); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EC_GROUP_free(group); + EC_POINT_free(point); +#endif if (rv != 1) return -1; } - return 0; } From 0e5ab7a60684fd7aae9674f15169dea68aec1bc7 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:08:25 +0200 Subject: [PATCH 2171/4321] pkcs11-tool: Deprecated EC param getters in parse_ec_pkey() --- src/tools/pkcs11-tool.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7d6517b56a..139ab76016 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3764,34 +3764,54 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) static int parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L const EC_KEY *src = EVP_PKEY_get0_EC_KEY(pkey); const BIGNUM *bignum; - if (!src) return -1; - gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gost->param_oid.value); - if (gost->param_oid.len <= 0) +#else + BIGNUM *bignum = NULL; + gost->param_oid.len = i2d_KeyParams(pkey, &gost->param_oid.value); +#endif + if (gost->param_oid.len <= 0) { return -1; + } if (private) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L bignum = EC_KEY_get0_private_key(src); - +#else + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bignum) != 1) { + return -1; + } +#endif gost->private.len = BN_num_bytes(bignum); gost->private.value = malloc(gost->private.len); - if (!gost->private.value) + if (!gost->private.value) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(bignum); +#endif return -1; + } BN_bn2bin(bignum, gost->private.value); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BN_free(bignum); +#endif } else { unsigned char buf[512], *point; - int point_len, header_len; + size_t point_len, header_len; const int MAX_HEADER_LEN = 3; +#if OPENSSL_VERSION_NUMBER < 0x30000000L const EC_GROUP *ecgroup = EC_KEY_get0_group(src); const EC_POINT *ecpoint = EC_KEY_get0_public_key(src); if (!ecgroup || !ecpoint) return -1; point_len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), NULL); +#else + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, sizeof(buf), &point_len); +#endif gost->public.value = malloc(MAX_HEADER_LEN+point_len); if (!gost->public.value) return -1; From 9d38e831579813723aa73ef60def22c98d8f55d0 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:09:40 +0200 Subject: [PATCH 2172/4321] pkcs11-tool: Deprecated param getters in derive_ec_key() --- src/tools/pkcs11-tool.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 139ab76016..993ab24408 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4618,9 +4618,6 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; BIO *bio_in = NULL; - EC_KEY *eckey = NULL; - const EC_GROUP *ecgroup = NULL; - const EC_POINT *ecpoint = NULL; unsigned char *buf = NULL; size_t buf_size = 0; CK_ULONG key_len = 0; @@ -4628,6 +4625,16 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE unsigned char * der = NULL; unsigned char * derp = NULL; size_t der_size = 0; + EVP_PKEY *pkey = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *eckey = NULL; + const EC_GROUP *ecgroup = NULL; + const EC_POINT *ecpoint = NULL; +#else + EC_GROUP *ecgroup = NULL; + char name[256]; size_t len = 0; + int nid = 0; +#endif printf("Using derive algorithm 0x%8.8lx %s\n", opt_mechanism, p11_mechanism_to_name(mech_mech)); memset(&mech, 0, sizeof(mech)); @@ -4638,15 +4645,24 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (BIO_read_filename(bio_in, opt_input) <= 0) util_fatal("Cannot open %s: %m", opt_input); - eckey = d2i_EC_PUBKEY_bio(bio_in, NULL); - if (!eckey) + pkey = d2i_PUBKEY_bio(bio_in, NULL); + + if (!pkey) util_fatal("Cannot read EC key from %s", opt_input); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + eckey = EVP_PKEY_get0_EC_KEY(pkey); ecpoint = EC_KEY_get0_public_key(eckey); ecgroup = EC_KEY_get0_group(eckey); if (!ecpoint || !ecgroup) util_fatal("Failed to parse other EC key from %s", opt_input); +#else + if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 + || (nid = OBJ_txt2nid(name)) == NID_undef + || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) + util_fatal("Failed to parse other EC key from %s", opt_input); +#endif /* both eckeys must be same curve */ key_len = (EC_GROUP_get_degree(ecgroup) + 7) / 8; @@ -4660,11 +4676,23 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE n_attrs++; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) util_fatal("malloc() failure\n"); buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); +#else + EC_GROUP_free(ecgroup); + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); + if ((buf = (unsigned char *)malloc(buf_size)) == NULL) + util_fatal("malloc() failure\n"); + + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buf_size, NULL) != 1) { + free(buf); + util_fatal("Failed to parse other EC key from %s", opt_input); + } +#endif if (opt_derive_pass_der) { octet = ASN1_OCTET_STRING_new(); @@ -4679,7 +4707,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE } BIO_free(bio_in); - EC_KEY_free(eckey); + EVP_PKEY_free(pkey); memset(&ecdh_parms, 0, sizeof(ecdh_parms)); ecdh_parms.kdf = CKD_NULL; From e70d59b099aa449c0cc22a98d6c83222c99e4e63 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:11:34 +0200 Subject: [PATCH 2173/4321] pkcs11-tool: Build evp_pkey in read_object() from params --- src/tools/pkcs11-tool.c | 60 +++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 993ab24408..fb23a1249a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -51,6 +51,7 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include +# include #endif #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include @@ -5399,20 +5400,25 @@ static int read_object(CK_SESSION_HANDLE session) if (clazz == CKO_PUBLIC_KEY) { #ifdef ENABLE_OPENSSL long derlen; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *bld = NULL; +#endif BIO *pout = BIO_new(BIO_s_mem()); if (!pout) util_fatal("out of memory"); type = getKEY_TYPE(session, obj); if (type == CKK_RSA) { - RSA *rsa; BIGNUM *rsa_n = NULL; BIGNUM *rsa_e = NULL; - - - rsa = RSA_new(); - if (rsa == NULL) +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa = RSA_new(); + if (!rsa) util_fatal("out of memory"); +#endif if ((value = getMODULUS(session, obj, &len))) { if (!(rsa_n = BN_bin2bn(value, len, NULL))) @@ -5427,13 +5433,43 @@ static int read_object(CK_SESSION_HANDLE session) free(value); } else util_fatal("cannot obtain PUBLIC_EXPONENT"); - +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) util_fatal("cannot set RSA values"); if (!i2d_RSA_PUBKEY_bio(pout, rsa)) util_fatal("cannot convert RSA public key to DER"); RSA_free(rsa); +#else + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx) + util_fatal("out of memory"); + + if (!(bld = OSSL_PARAM_BLD_new()) + || OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 + || OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 + || !(params = OSSL_PARAM_BLD_to_param(bld)) != 1) { + OSSL_PARAM_BLD_free(bld); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + util_fatal("cannot set RSA values"); + } + OSSL_PARAM_BLD_free(bld); + + if (EVP_PKEY_fromdata_init(ctx) != 1 + || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + util_fatal("cannot set RSA values"); + } + OSSL_PARAM_free(params); + if (i2d_PUBKEY_bio(pout, pkey) != 1) { + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot convert RSA public key to DER"); + } + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); +#endif #if !defined(OPENSSL_NO_EC) } else if (type == CKK_EC) { EC_KEY *ec; @@ -5448,7 +5484,11 @@ static int read_object(CK_SESSION_HANDLE session) if ((params = getEC_PARAMS(session, obj, &len))) { const unsigned char *a = params; +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (!d2i_ECParameters(&ec, &a, (long)len)) +#else + if (!(pkey = d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len))) +#endif util_fatal("cannot parse EC_PARAMS"); free(params); } else @@ -5460,17 +5500,21 @@ static int read_object(CK_SESSION_HANDLE session) os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (os) { a = os->data; - success = o2i_ECPublicKey(&ec, &a, os->length); + success = o2i_ECPublicKey(&ec, &a, os->length); // no idea what to do with it ASN1_STRING_free(os); } if (!success) { /* Workaround for broken PKCS#11 modules */ a = value; - success = o2i_ECPublicKey(&ec, &a, len); + success = o2i_ECPublicKey(&ec, &a, len); // no idea what to do with it } free(value); if (!success) util_fatal("cannot obtain and parse EC_POINT"); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (!i2d_EC_PUBKEY_bio(pout, ec)) +#else + if (!i2d_PUBKEY_bio(pout, pkey)) +#endif util_fatal("cannot convert EC public key to DER"); EC_KEY_free(ec); #endif From 2281c01dc86f97eeb3542486b0152c5dc4fc2288 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 16:12:56 +0200 Subject: [PATCH 2174/4321] pkcs11-tool: Build RSA key in get_public_key() --- src/tools/pkcs11-tool.c | 54 ++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fb23a1249a..edb6f558da 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5877,9 +5877,15 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv unsigned char *pubkey; const unsigned char *pubkey_c; CK_ULONG pubkeyLen; - EVP_PKEY *pkey; - RSA *rsa; + EVP_PKEY *pkey = NULL; BIGNUM *rsa_n, *rsa_e; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa; +#else + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; +#endif id = NULL; id = getID(session, privKeyObject, &idLen); @@ -5896,17 +5902,22 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv free(id); switch(getKEY_TYPE(session, pubkeyObject)) { - case CKK_RSA: - pkey = EVP_PKEY_new(); + case CKK_RSA:; +#if OPENSSL_VERSION_NUMBER < 0x30000000L rsa = RSA_new(); - mod = getMODULUS(session, pubkeyObject, &modLen); - exp = getPUBLIC_EXPONENT(session, pubkeyObject, &expLen); - if ( !pkey || !rsa || !mod || !exp) { - fprintf(stderr, "public key not extractable\n"); + pkey = EVP_PKEY_new(); + if (!rsa || !pkey) { + fprintf(stderr, "public key not extractable\n"); if (pkey) EVP_PKEY_free(pkey); if (rsa) RSA_free(rsa); + } +#endif + mod = getMODULUS(session, pubkeyObject, &modLen); + exp = getPUBLIC_EXPONENT(session, pubkeyObject, &expLen); + if (!mod || !exp) { + fprintf(stderr, "public key not extractable\n"); if (mod) free(mod); if (exp) @@ -5915,12 +5926,33 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv } rsa_n = BN_bin2bn(mod, modLen, NULL); rsa_e = BN_bin2bn(exp, expLen, NULL); + free(mod); + free(exp); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) return NULL; - EVP_PKEY_assign_RSA(pkey, rsa); - free(mod); - free(exp); +#else + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + fprintf(stderr, "public key not extractable\n"); + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(params); + return NULL; + } + OSSL_PARAM_BLD_free(bld); + + if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || + EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + fprintf(stderr, "public key not extractable\n"); + OSSL_PARAM_free(params); + return NULL; + } + OSSL_PARAM_free(params); +#endif return pkey; case CKK_DSA: case CKK_ECDSA: From 21733e73d06eb9ff350c3afe92581ef139176398 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 18 Oct 2021 15:20:22 +0200 Subject: [PATCH 2175/4321] pkcs11-tool: read_object() for EC keys using non-deprecated API There is no direct replacement for o2i_ECPublicKey() with EVP_PKEY, but it internally calls EC_KEY_oct2key(), which calls EC_POINT_oct2point() with params from given EC key. After EC_POINT_oct2point(), it sets EC key to EVP_PKEY. --- src/tools/pkcs11-tool.c | 108 ++++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index edb6f558da..66f1acaf4e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5400,12 +5400,13 @@ static int read_object(CK_SESSION_HANDLE session) if (clazz == CKO_PUBLIC_KEY) { #ifdef ENABLE_OPENSSL long derlen; -#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY *pkey = NULL; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM *params = NULL; OSSL_PARAM_BLD *bld = NULL; #endif + BIO *pout = BIO_new(BIO_s_mem()); if (!pout) util_fatal("out of memory"); @@ -5419,7 +5420,6 @@ static int read_object(CK_SESSION_HANDLE session) if (!rsa) util_fatal("out of memory"); #endif - if ((value = getMODULUS(session, obj, &len))) { if (!(rsa_n = BN_bin2bn(value, len, NULL))) util_fatal("cannot parse MODULUS"); @@ -5444,20 +5444,18 @@ static int read_object(CK_SESSION_HANDLE session) ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); if (!ctx) util_fatal("out of memory"); - - if (!(bld = OSSL_PARAM_BLD_new()) - || OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 - || OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 - || !(params = OSSL_PARAM_BLD_to_param(bld)) != 1) { + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); util_fatal("cannot set RSA values"); } OSSL_PARAM_BLD_free(bld); - - if (EVP_PKEY_fromdata_init(ctx) != 1 - || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); util_fatal("cannot set RSA values"); @@ -5472,24 +5470,34 @@ static int read_object(CK_SESSION_HANDLE session) #endif #if !defined(OPENSSL_NO_EC) } else if (type == CKK_EC) { - EC_KEY *ec; CK_BYTE *params; const unsigned char *a; + size_t a_len = 0; ASN1_OCTET_STRING *os; - EC_KEY *success = NULL; + int success = 0; + EC_POINT *point = NULL; - ec = EC_KEY_new(); - if (ec == NULL) - util_fatal("out of memory"); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const EC_GROUP *group = NULL; + EC_KEY *ec = EC_KEY_new(); + pkey = EVP_PKEY_new(); +#else + EC_GROUP *group = NULL; + char group_name[80]; + OSSL_PARAM *old = NULL, *new = NULL, *p = NULL; + OSSL_PARAM_BLD *bld = NULL; +#endif if ((params = getEC_PARAMS(session, obj, &len))) { const unsigned char *a = params; #if OPENSSL_VERSION_NUMBER < 0x30000000L if (!d2i_ECParameters(&ec, &a, (long)len)) + util_fatal("cannot parse EC_PARAMS"); + EVP_PKEY_assign_EC_KEY(pkey, ec); #else - if (!(pkey = d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len))) -#endif + if (!d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len)) util_fatal("cannot parse EC_PARAMS"); +#endif free(params); } else util_fatal("cannot obtain EC_PARAMS"); @@ -5498,25 +5506,73 @@ static int read_object(CK_SESSION_HANDLE session) /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); +#else + if (EVP_PKEY_get_group_name(pkey, group_name, sizeof(group_name), NULL) != 1) + util_fatal("cannot obtain EC_PARAMS"); + group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); +#endif + point = EC_POINT_new(group); if (os) { a = os->data; - success = o2i_ECPublicKey(&ec, &a, os->length); // no idea what to do with it - ASN1_STRING_free(os); + a_len = os->length; + success = EC_POINT_oct2point(group, point, a, a_len, NULL); } if (!success) { /* Workaround for broken PKCS#11 modules */ + ASN1_STRING_free(os); a = value; - success = o2i_ECPublicKey(&ec, &a, len); // no idea what to do with it + a_len = len; + if (!EC_POINT_oct2point(group, point, a, len, NULL)) { + free(value); + util_fatal("cannot obtain and parse EC_POINT"); + } } - free(value); - if (!success) - util_fatal("cannot obtain and parse EC_POINT"); + #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (!i2d_EC_PUBKEY_bio(pout, ec)) + if (success) + ASN1_STRING_free(os); + free(value); + EC_KEY_set_public_key(EVP_PKEY_get0_EC_KEY(pkey), point); #else - if (!i2d_PUBKEY_bio(pout, pkey)) + if (!(bld = OSSL_PARAM_BLD_new()) || + EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &old) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", a, a_len) != 1 || + !(new = OSSL_PARAM_BLD_to_param(bld)) || + !(p = OSSL_PARAM_merge(old, new))) { + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); + OSSL_PARAM_free(p); + if (success) + ASN1_STRING_free(os); + free(value); + util_fatal("cannot set OSSL_PARAM"); + } + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); + if (success) + ASN1_STRING_free(os); + free(value); + + if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) || + EVP_PKEY_fromdata_init(ctx) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot set CTX"); + } + EVP_PKEY_free(pkey); + pkey = NULL; + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot create EVP_PKEY"); + } + #endif + if (!i2d_PUBKEY_bio(pout, pkey)) util_fatal("cannot convert EC public key to DER"); - EC_KEY_free(ec); #endif #ifdef EVP_PKEY_ED25519 } else if (type == CKK_EC_EDWARDS) { From c3dcab8b237d42961c0dc12ab2105f3df9073116 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 25 Oct 2021 15:47:44 +0200 Subject: [PATCH 2176/4321] pkcs11-tool: load legacy provider for RIPEMD160 in test --- src/tools/pkcs11-tool.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 66f1acaf4e..53e7c7d75f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -52,6 +52,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include # include +#include #endif #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include @@ -71,6 +72,10 @@ #include "util.h" #include "libopensc/sc-ossl-compat.h" +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +OSSL_PROVIDER *legacy_provider = NULL; +#endif + #ifdef _WIN32 #ifndef STDOUT_FILENO #define STDOUT_FILENO 1 @@ -5766,7 +5771,6 @@ static int test_digest(CK_SESSION_HANDLE session) CK_ULONG hashLen1, hashLen2; CK_MECHANISM_TYPE firstMechType; CK_SESSION_INFO sessionInfo; - CK_MECHANISM_TYPE mechTypes[] = { CKM_MD5, CKM_RIPEMD160, @@ -5868,6 +5872,11 @@ static int test_digest(CK_SESSION_HANDLE session) #endif for (; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) { + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + } +#endif rv = p11->C_DigestInit(session, &ck_mech); if (rv == CKR_MECHANISM_INVALID) @@ -6065,6 +6074,11 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, EVP_sha256(), }; #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) { + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + } +#endif rv = p11->C_SignInit(session, ck_mech, privKeyObject); /* mechanism not implemented, don't test */ From bc0f2c798b67a2b0a4928dd06c241dedda5fa831 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 9 Nov 2021 11:39:21 +0100 Subject: [PATCH 2177/4321] pkcs11-tool: Change condition for EVP_PKEY_CTX_set_rsa_oaep_md For OpenSSL 3.0 EVP_PKEY_CTX_set_rsa_oaep_md() is self-standing function, for older versions it is macro first defined in OpenSSl 1.0.2. Checking by version will also work for OpenSSL 3.0. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 53e7c7d75f..5ab7a85681 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6908,7 +6908,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, return 0; } if (mech_type == CKM_RSA_PKCS_OAEP) { -#if defined(EVP_PKEY_CTX_set_rsa_oaep_md) && defined(EVP_PKEY_CTX_set_rsa_mgf1_md) +#if OPENSSL_VERSION_NUMBER >= 0x10002000L const EVP_MD *md; switch (hash_alg) { case CKM_SHA_1: From a9d2a7b7654b30044bf06f4eadc474006d4ff277 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 11 Oct 2021 12:14:29 +0200 Subject: [PATCH 2178/4321] cardos-tool: Rewrite DES encryption and decryption on way to OpenSSL3.0 --- src/tools/cardos-tool.c | 125 +++++++++++++++++++++++++++++++++++----- 1 file changed, 112 insertions(+), 13 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index a2dc6b297c..06fd09f311 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -36,12 +36,20 @@ #ifdef ENABLE_OPENSSL #include #include +#include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #endif #include "libopensc/opensc.h" #include "libopensc/cards.h" #include "util.h" +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PROVIDER *legacy_provider = NULL; +#endif + static const char *app_name = "cardos-tool"; static int opt_wait = 0; @@ -393,9 +401,11 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char int plain_lc; /* data size in orig APDU */ unsigned int mac_input_len, enc_input_len; unsigned char *mac_input, *enc_input; - DES_key_schedule ks_a, ks_b; - DES_cblock des_in,des_out; + DES_cblock des_in, des_out; unsigned int i,j; + EVP_CIPHER_CTX *cctx = NULL; + int tmplen = 0; + unsigned char key1[8], key2[8]; if (keylen != 16) { printf("key has wrong size, need 16 bytes, got %"SC_FORMAT_LEN_SIZE_T"d. aborting.\n", @@ -427,27 +437,92 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char memcpy(&mac_input[4],&in[5],plain_lc); /* calloc already did the ansi padding: rest is 00 */ - /* prepare des key using first 8 bytes of key */ - DES_set_key((const_DES_cblock*) &key[0], &ks_a); - /* prepare des key using second 8 bytes of key */ - DES_set_key((const_DES_cblock*) &key[8], &ks_b); - + /* prepare des ctx */ + memcpy(key1, key, 8); + memcpy(key2, key + 8, 8); + cctx = EVP_CIPHER_CTX_new(); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); +#endif + if (!cctx || + !EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key1, NULL) || + !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } + /* first block: XOR with IV and encrypt with key A IV is 8 bytes 00 */ for (i=0; i < 8; i++) des_in[i] = mac_input[i]^00; - DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); + if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } /* all other blocks: XOR with prev. result and encrypt with key A */ for (j=1; j < (mac_input_len / 8); j++) { for (i=0; i < 8; i++) des_in[i] = mac_input[i+j*8]^des_out[i]; - DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); + if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } + } + if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; } /* now decrypt with key B and encrypt with key A again */ /* (a noop if key A and B are the same, e.g. 8 bytes ff */ + if (!EVP_DecryptInit_ex(cctx, EVP_des_ecb(), NULL, key2, NULL) || + !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } for (i=0; i < 8; i++) des_in[i] = des_out[i]; - DES_ecb_encrypt(&des_in, &des_out, &ks_b, 0); + if (!EVP_DecryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } + if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } + + if (!EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key1, NULL) || + !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } for (i=0; i < 8; i++) des_in[i] = des_out[i]; - DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); + if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } + if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } /* now we want to enc: * orig APDU data plus mac (8 bytes) plus iso padding (1-8 bytes) */ @@ -480,12 +555,28 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char out[4] = enc_input_len; /* lc */ /* encrypt first block */ + cctx = EVP_CIPHER_CTX_new(); + if (!cctx || + !EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) || + !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + printf("Can not setup context, aborting\n"); + free(mac_input); + free(enc_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } /* xor data and IV (8 bytes 00) to get input data */ for (i=0; i < 8; i++) des_in[i] = enc_input[i] ^ 00; /* encrypt with des2 (triple des, but using keys A-B-A) */ - DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); + if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + free(enc_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } /* copy encrypted bytes into output */ for (i=0; i < 8; i++) out[5+i] = des_out[i]; @@ -496,11 +587,19 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char for (i=0; i < 8; i++) des_in[i] = enc_input[i+j*8] ^ des_out[i]; /* encrypt with des2 (triple des, but using keys A-B-A) */ - DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); + if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + printf("Can not encrypt, aborting\n"); + free(mac_input); + free(enc_input); + EVP_CIPHER_CTX_free(cctx); + return 0; + } /* copy encrypted bytes into output */ for (i=0; i < 8; i++) out[5+8*j+i] = des_out[i]; } + + EVP_CIPHER_CTX_free(cctx); if (verbose) { printf ("Unencrypted APDU:\n"); util_hex_dump_asc(stdout, in, inlen, -1); From 060f1997b227192a83b6b957f5dc8489e9fbc3d7 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Mon, 11 Oct 2021 15:57:08 +0200 Subject: [PATCH 2179/4321] pkcs15-init: Rewrite group get according to OpenSSC 3.0 --- src/tools/pkcs15-init.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 3a36d21dd1..39b5e06ea0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -52,6 +52,10 @@ #include #include #include /* for OPENSSL_NO_EC */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +#endif #ifndef OPENSSL_NO_EC #include #endif /* OPENSSL_NO_EC */ @@ -1340,7 +1344,10 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, r = SC_ERROR_INVALID_ARGUMENTS; if (oldpk_type == newpk_type) { -#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (EVP_PKEY_eq(oldpk, newpk)) + r = 0; +#elif OPENSSL_VERSION_NUMBER >= 0x10002000L if (EVP_PKEY_cmp(oldpk, newpk) == 1) r = 0; #else @@ -1870,16 +1877,27 @@ static void init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey) { #if !defined(OPENSSL_NO_EC) +#if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *key; +#else + char name[256]; size_t name_len = 0; +#endif + int nid = 0; assert(pkey); if (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { + assert(params); +#if OPENSSL_VERSION_NUMBER < 0x30000000L key = EVP_PKEY_get0(pkey); assert(key); - assert(params); assert(EC_KEY_get0_group(key)); - assert(EC_GROUP_get_curve_name(EC_KEY_get0_group(key)) > 0); - switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(key))) { + EC_GROUP_get_curve_name(EC_KEY_get0_group(key)); +#else + assert(EVP_PKEY_get_group_name(pkey, name ,sizeof(name), &name_len)); + nid = OBJ_txt2nid(name); +#endif + assert(nid > 0); + switch (nid) { case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_A; break; From 08ab72d50d15219479be412d6f030d76c0ab498c Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 12 Oct 2021 12:00:11 +0200 Subject: [PATCH 2180/4321] cryptoflex-tool: EVP_PKEY API in store_key() gen_d() now only sets value to d param. Setting of parameters in key is done in parse_private_key(). Use of EVP_PKEY keys. --- src/tools/cryptoflex-tool.c | 282 ++++++++++++++++++++++++++++-------- 1 file changed, 225 insertions(+), 57 deletions(-) diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index ad09f4df49..e4484a7dd6 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -27,6 +27,12 @@ #include #include #include +#include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +# include +#endif #include "libopensc/pkcs15.h" #include "common/compat_strlcpy.h" @@ -196,12 +202,18 @@ static int bn2cf(const BIGNUM *num, u8 *buf) return r; } -static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa) +static int parse_public_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) { const u8 *p = key; BIGNUM *n, *e; int base; - +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa = NULL; +#else + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *bld = NULL; +#endif base = (keysize - 7) / 5; if (base != 32 && base != 48 && base != 64 && base != 128) { fprintf(stderr, "Invalid public key.\n"); @@ -219,17 +231,44 @@ static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa) if (e == NULL) return -1; cf2bn(p, 4, e); - if (RSA_set0_key(rsa, n, e, NULL) != 1) - return -1; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (!(rsa = RSA_new()) || + !(pkey = EVP_PKEY_new()) || + RSA_set0_key(rsa, n, e, NULL) != 1 || + EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + RSA_free(rsa); + EVP_PKEY_free(pkey); + return -1; + } +#else + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_free(bld); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return -1; + } + OSSL_PARAM_BLD_free(bld); + + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + return -1;; + } + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); +#endif return 0; } -static int gen_d(RSA *rsa) +static int gen_d(BIGNUM *rsa_d_new, const BIGNUM *rsa_p, const BIGNUM *rsa_q, const BIGNUM *rsa_n, const BIGNUM *rsa_e) { BN_CTX *bnctx; BIGNUM *r0, *r1, *r2; - const BIGNUM *rsa_p, *rsa_q, *rsa_n, *rsa_e, *rsa_d; - BIGNUM *rsa_n_new, *rsa_e_new, *rsa_d_new; bnctx = BN_CTX_new(); if (bnctx == NULL) @@ -238,8 +277,6 @@ static int gen_d(RSA *rsa) r0 = BN_CTX_get(bnctx); r1 = BN_CTX_get(bnctx); r2 = BN_CTX_get(bnctx); - RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); - RSA_get0_factors(rsa, &rsa_p, &rsa_q); BN_sub(r1, rsa_p, BN_value_one()); BN_sub(r2, rsa_q, BN_value_one()); @@ -249,24 +286,31 @@ static int gen_d(RSA *rsa) return -1; } - /* RSA_set0_key will free previous value, and replace with new value - * Thus the need to copy the contents of rsa_n and rsa_e - */ - rsa_n_new = BN_dup(rsa_n); - rsa_e_new = BN_dup(rsa_e); - if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d_new) != 1) - return -1; - BN_CTX_end(bnctx); BN_CTX_free(bnctx); return 0; } -static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa) +static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) { const u8 *p = key; BIGNUM *bn_p, *q, *dmp1, *dmq1, *iqmp; int base; + BIGNUM *rsa_d = NULL; + int rv = 0; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const BIGNUM *rsa_n, *rsa_e; + BIGNUM *rsa_n_new, *rsa_e_new ; + RSA *rsa = NULL; + if (!(rsa = EVP_PKEY_get0_RSA(pkey))) + return -1; +#else + OSSL_PARAM *params = NULL, *pkey_params = NULL, *new_params = NULL; + const OSSL_PARAM *e = NULL, *n = NULL; + BIGNUM *rsa_n, *rsa_e; + OSSL_PARAM_BLD *bld = NULL; + EVP_PKEY_CTX *ctx = NULL; +#endif base = (keysize - 3) / 5; if (base != 32 && base != 48 && base != 64 && base != 128) { @@ -302,18 +346,69 @@ static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa) if (dmq1 == NULL) return -1; cf2bn(p, base, dmq1); - - if (RSA_set0_factors(rsa, bn_p, q) != 1) + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); + + if (RSA_set0_factors(rsa, bn_p, q) != 1 || + RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1 || + gen_d(rsa_d, bn_p, q, rsa_n, rsa_e) != 0) + return -1; + + /* RSA_set0_key will free previous value, and replace with new value + * Thus the need to copy the contents of rsa_n and rsa_e + */ + rsa_n_new = BN_dup(rsa_n); + rsa_e_new = BN_dup(rsa_e); + if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d) != 1) return -1; - if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1) +#else + /* Extract parameters from pkey */ + if (EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &pkey_params) != 1) { return -1; - if (gen_d(rsa)) + } + e = OSSL_PARAM_locate_const(pkey_params, "e"); + n = OSSL_PARAM_locate_const(pkey_params, "n"); + if (!e || !n) { + OSSL_PARAM_free(pkey_params); return -1; + } + OSSL_PARAM_get_BN(e, &rsa_e); + OSSL_PARAM_get_BN(n, &rsa_n); + gen_d(rsa_d, bn_p, q, rsa_n, rsa_e); + /* Merge params*/ + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "d", rsa_d) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-factor1", bn_p) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-factor2", q) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent1", dmp1) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent2", dmq1) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-coefficient1", iqmp) != 1 || + !(new_params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_free(pkey_params); + OSSL_PARAM_BLD_free(bld); + return -1; + } + OSSL_PARAM_BLD_free(bld); + if (!(params = OSSL_PARAM_merge(pkey_params, new_params))) { + OSSL_PARAM_free(pkey_params); + OSSL_PARAM_free(new_params); + return -1; + } - return 0; + /* Create pkey from params */ + if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || + EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) + rv = -1; + OSSL_PARAM_free(pkey_params); + OSSL_PARAM_free(new_params); + EVP_PKEY_CTX_free(ctx); +#endif + return rv; } -static int read_public_key(RSA *rsa) +static int read_public_key(EVP_PKEY *pkey) { int r; sc_path_t path; @@ -355,11 +450,11 @@ static int read_public_key(RSA *rsa) printf("Key number %d not found.\n", opt_key_num); return 2; } - return parse_public_key(p, keysize, rsa); + return parse_public_key(p, keysize, pkey); } -static int read_private_key(RSA *rsa) +static int read_private_key(EVP_PKEY *pkey) { int r; sc_path_t path; @@ -406,22 +501,21 @@ static int read_private_key(RSA *rsa) printf("Key number %d not found.\n", opt_key_num); return 2; } - return parse_private_key(p, keysize, rsa); + return parse_private_key(p, keysize, pkey); } static int read_key(void) { - RSA *rsa = RSA_new(); + EVP_PKEY *pkey = NULL; u8 buf[1024], *p = buf; u8 b64buf[2048]; int r; - if (rsa == NULL) - return -1; - r = read_public_key(rsa); + r = read_public_key(pkey); if (r) return r; - r = i2d_RSA_PUBKEY(rsa, &p); + + r = i2d_PUBKEY(pkey, &p); if (r <= 0) { fprintf(stderr, "Error encoding public key.\n"); return -1; @@ -433,13 +527,13 @@ static int read_key(void) } printf("-----BEGIN PUBLIC KEY-----\n%s-----END PUBLIC KEY-----\n", b64buf); - r = read_private_key(rsa); + r = read_private_key(pkey); if (r == 10) return 0; else if (r) return r; p = buf; - r = i2d_RSAPrivateKey(rsa, &p); + r = i2d_PrivateKey(pkey, &p); if (r <= 0) { fprintf(stderr, "Error encoding private key.\n"); return -1; @@ -630,11 +724,17 @@ static int create_key_files(void) return 0; } -static int read_rsa_privkey(RSA **rsa_out) +static int read_rsa_privkey(EVP_PKEY **pkey_out) { - RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; BIO *in = NULL; int r; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA *rsa = NULL; + pkey = EVP_PKEY_new(); +#else + OSSL_DECODER_CTX *dctx; +#endif in = BIO_new(BIO_s_file()); if (opt_prkeyf == NULL) { @@ -646,25 +746,37 @@ static int read_rsa_privkey(RSA **rsa_out) perror(opt_prkeyf); return 2; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); if (rsa == NULL) { fprintf(stderr, "Unable to load private key.\n"); return 2; } + EVP_PKEY_assign_RSA(pkey, rsa); +#else + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA", OSSL_KEYMGMT_SELECT_KEYPAIR, NULL, NULL); + OSSL_DECODER_from_bio(dctx, in); +#endif BIO_free(in); - *rsa_out = rsa; + *pkey_out = pkey; return 0; } -static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) +static int encode_private_key(EVP_PKEY *pkey, u8 *key, size_t *keysize) { u8 buf[1024], *p = buf; u8 bnbuf[256]; int base = 0; int r; + int rv = 0; +#if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp; + RSA *rsa = EVP_PKEY_get1_RSA(pkey); +#else + BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_dmp1 = NULL, *rsa_dmq1 = NULL, *rsa_iqmp = NULL; +#endif - switch (RSA_bits(rsa)) { + switch (EVP_PKEY_bits(pkey)) { case 512: base = 32; break; @@ -686,12 +798,22 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) *p++ = (5 * base + 3) & 0xFF; *p++ = opt_key_num; +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_get0_factors(rsa, &rsa_p, &rsa_q); +#else + if (EVP_PKEY_get_bn_param(pkey, "rsa-factor1", &rsa_p) != 1 || + EVP_PKEY_get_bn_param(pkey, "rsa-factor2", &rsa_q) != 1) { + fprintf(stderr, "Invalid private key.\n"); + rv = 2; + goto end; + } +#endif r = bn2cf(rsa_p, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, base); p += base; @@ -699,17 +821,28 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) r = bn2cf(rsa_q, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, base); p += base; +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp); - +#else + if (EVP_PKEY_get_bn_param(pkey, "rsa-exponent1", &rsa_dmp1) != 1 || + EVP_PKEY_get_bn_param(pkey, "rsa-exponent2", &rsa_dmq1) != 1 || + EVP_PKEY_get_bn_param(pkey, "rsa-coefficient1", &rsa_iqmp) != 1) { + fprintf(stderr, "Invalid private key.\n"); + rv = 2; + goto end; + } +#endif r = bn2cf(rsa_iqmp, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, base); p += base; @@ -717,7 +850,8 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) r = bn2cf(rsa_dmp1, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, base); p += base; @@ -725,7 +859,8 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) r = bn2cf(rsa_dmq1, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, base); p += base; @@ -733,18 +868,34 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(key, buf, p - buf); *keysize = p - buf; - return 0; +end: +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(rsa); +#else + BN_free(rsa_p); + BN_free(rsa_q); + BN_free(rsa_dmp1); + BN_free(rsa_dmq1); + BN_free(rsa_iqmp); +#endif + return rv; } -static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) +static int encode_public_key(EVP_PKEY *pkey, u8 *key, size_t *keysize) { u8 buf[1024], *p = buf; u8 bnbuf[256]; int base = 0; int r; + int rv = 0; +#if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *rsa_n, *rsa_e; + RSA *rsa = NULL; +#else + BIGNUM *rsa_n = NULL, *rsa_e = NULL; +#endif - switch (RSA_bits(rsa)) { + switch (EVP_PKEY_bits(pkey)) { case 512: base = 32; break; @@ -766,11 +917,21 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) *p++ = (5 * base + 7) & 0xFF; *p++ = opt_key_num; +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); +#else + if (EVP_PKEY_get_bn_param(pkey, "n", &rsa_n) != 1 || + EVP_PKEY_get_bn_param(pkey, "e", &rsa_e) != 1) { + fprintf(stderr, "Invalid public key.\n"); + rv = 2; + goto end; + } +#endif r = bn2cf(rsa_n, bnbuf); if (r != 2*base) { fprintf(stderr, "Invalid public key.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, 2*base); p += 2*base; @@ -784,15 +945,22 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) r = bn2cf(rsa_e, bnbuf); if (r != 4) { fprintf(stderr, "Invalid exponent value.\n"); - return 2; + rv = 2; + goto end; } memcpy(p, bnbuf, 4); p += 4; memcpy(key, buf, p - buf); *keysize = p - buf; - - return 0; +end: +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(rsa); +#else + BN_free(rsa_n); + BN_free(rsa_e); +#endif + return rv; } static int update_public_key(const u8 *key, size_t keysize) @@ -844,17 +1012,17 @@ static int update_private_key(const u8 *key, size_t keysize) static int store_key(void) { u8 prv[1024], pub[1024]; - size_t prvsize, pubsize; + size_t prvsize = 0, pubsize = 0; int r; - RSA *rsa; + EVP_PKEY *pkey = NULL; - r = read_rsa_privkey(&rsa); + r = read_rsa_privkey(&pkey); if (r) return r; - r = encode_private_key(rsa, prv, &prvsize); + r = encode_private_key(pkey, prv, &prvsize); if (r) return r; - r = encode_public_key(rsa, pub, &pubsize); + r = encode_public_key(pkey, pub, &pubsize); if (r) return r; if (verbose) From 3ecca8b308d31f34eea0fa80416f777148a79bec Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 15 Oct 2021 13:21:43 +0200 Subject: [PATCH 2181/4321] piv-tool: RSA and EC keys setting ingen_key() In OpenSSL 3.0 with use of OSSL_PARAM and creating EVP_PKEY with EVP_PKEY_fromdata(). --- src/tools/piv-tool.c | 89 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index dec2820f97..ffeae2e31d 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -38,6 +38,10 @@ #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +# include +#endif #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #include #include @@ -333,17 +337,24 @@ static int gen_key(const char * key_info) return r; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L evpkey = EVP_PKEY_new(); +#endif if (keydata.key_bits > 0) { /* RSA key */ - RSA * newkey = NULL; BIGNUM *newkey_n, *newkey_e; - +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA * newkey = NULL; newkey = RSA_new(); if (newkey == NULL) { fprintf(stderr, "gen_key RSA_new failed %d\n",r); return -1; } +#else + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; +#endif newkey_n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, NULL); expl = keydata.exponent; expc[3] = (u8) expl & 0xff; @@ -352,6 +363,7 @@ static int gen_key(const char * key_info) expc[0] = (u8) (expl >>24) & 0xff; newkey_e = BN_bin2bn(expc, 4, NULL); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { fprintf(stderr, "gen_key unable to set RSA values"); return -1; @@ -361,15 +373,48 @@ static int gen_key(const char * key_info) RSA_print_fp(stdout, newkey,0); EVP_PKEY_assign_RSA(evpkey, newkey); +#else + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", newkey_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_free(bld); + return -1; + } + params = OSSL_PARAM_BLD_to_param(bld); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx || + EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + fprintf(stderr, "gen_key unable to gen RSA"); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return -1; + } + if (verbose) + EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); +#endif } else { /* EC key */ #if !defined(OPENSSL_NO_EC) int i; BIGNUM *x; BIGNUM *y; - EC_KEY * eckey = NULL; EC_GROUP * ecgroup = NULL; EC_POINT * ecpoint = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY * eckey = NULL; +#else + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + size_t len = 0; + unsigned char * buf = NULL; + const char *group_name; +#endif ecgroup = EC_GROUP_new_by_curve_name(nid); EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); @@ -384,6 +429,7 @@ static int gen_key(const char * key_info) fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); return -1; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EC_KEY_new(); r = EC_KEY_set_group(eckey, ecgroup); if (r == 0) { @@ -401,6 +447,43 @@ static int gen_key(const char * key_info) EVP_PKEY_assign_EC_KEY(evpkey, eckey); #else + group_name = OBJ_nid2sn(nid); + len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL); + if (!(buf = malloc(len))) { + fprintf(stderr, "EC_KEY_set_public_key out of memory\n"); + return -1; + } + if (EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, buf, len, NULL) == 0) { + fprintf(stderr, "EC_KEY_set_public_key failed\n"); + free(buf); + return -1; + } + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, sizeof(group_name)) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_free(bld); + free(buf); + return -1; + } + free(buf); + OSSL_PARAM_BLD_free(bld); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + if (!ctx || + EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + fprintf(stderr, "gen_key unable to gen EC key"); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return -1; + } + if (verbose) + EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); + + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); +#endif fprintf(stderr, "This build of OpenSSL does not support EC keys\n"); r = 1; #endif /* OPENSSL_NO_EC */ From bb7c833348606054dfbee1ff84f18621afa792d7 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 15 Oct 2021 13:58:11 +0200 Subject: [PATCH 2182/4321] westcos-tool: RSA key generation and getters using EVP_PKEY API --- src/tools/westcos-tool.c | 54 +++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 2e98ea3abf..14861dc108 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) sc_context_t *ctx = NULL; sc_file_t *file = NULL; sc_path_t path; - RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; BIGNUM *bn = NULL; BIO *mem = NULL; static const char *pin = NULL; @@ -578,32 +578,36 @@ int main(int argc, char *argv[]) struct sc_pkcs15_pubkey key; struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa); u8 *pdata; + EVP_PKEY_CTX *pctx = NULL; memset(&key, 0, sizeof(key)); key.algorithm = SC_ALGORITHM_RSA; printf("Generate key of length %d.\n", keylen); - rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); - if(rsa == NULL || bn == NULL || mem == NULL) + if(bn == NULL || mem == NULL || pctx == NULL) { printf("Not enough memory.\n"); + if (pctx) + EVP_PKEY_CTX_free(pctx); goto out; } - if(!BN_set_word(bn, RSA_F4) || - !RSA_generate_key_ex(rsa, keylen, bn, NULL)) + if (EVP_PKEY_keygen_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, keylen) != 1 || + EVP_PKEY_keygen(pctx, &pkey) != 1) { - printf("RSA_generate_key_ex return %ld\n", ERR_get_error()); + printf("Key generation failed.\n"); + EVP_PKEY_CTX_free(pctx); goto out; } + EVP_PKEY_CTX_free(pctx); - RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); - - if(!i2d_RSAPrivateKey_bio(mem, rsa)) + if(!i2d_PrivateKey_bio(mem, pkey)) { printf("i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error()); goto out; @@ -667,17 +671,39 @@ int main(int argc, char *argv[]) if(r) goto out; { +#if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *rsa_n, *rsa_e; - + RSA *rsa = NULL; + rsa = EVP_PKEY_get1_RSA(pkey); RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); +#else + BIGNUM *rsa_n = NULL, *rsa_e = NULL; + if (EVP_PKEY_get_bn_param(pkey, "n", &rsa_n) != 1 || + EVP_PKEY_get_bn_param(pkey, "e", &rsa_e) != 1) + { + BN_free(rsa_n); + } +#endif - if (!do_convert_bignum(&dst->modulus, rsa_n) - || !do_convert_bignum(&dst->exponent, rsa_e)) + if (!do_convert_bignum(&dst->modulus, rsa_n) || + !do_convert_bignum(&dst->exponent, rsa_e)) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(rsa); +#else + BN_free(rsa_n); + BN_free(rsa_e); +#endif free(dst->modulus.data); free(dst->exponent.data); goto out; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(rsa); +#else + BN_free(rsa_n); + BN_free(rsa_e); +#endif } r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); @@ -893,8 +919,8 @@ int main(int argc, char *argv[]) BIO_free(mem); if(bn) BN_free(bn); - if(rsa) - RSA_free(rsa); + if(pkey) + EVP_PKEY_free(pkey); if(file) sc_file_free(file); From b7aafb8355de54aaa8beab2d749b38a06fb9035b Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 29 Oct 2021 10:20:54 +0200 Subject: [PATCH 2183/4321] openssl.c: Build key with EVP_PKEY_fromdata in gostr3410_verify_data --- src/pkcs11/openssl.c | 58 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index adcf880d29..8f83cca5e7 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -31,6 +31,10 @@ #include #include #include /* for OPENSSL_NO_* */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif #include "libopensc/sc-ossl-compat.h" #ifndef OPENSSL_NO_EC #include @@ -369,13 +373,24 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub EC_POINT *P; BIGNUM *X, *Y; ASN1_OCTET_STRING *octet = NULL; - const EC_GROUP *group = NULL; char paramset[2] = "A"; int r = -1, ret_vrf = 0; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + const EC_GROUP *group = NULL; +#else + EC_GROUP *group = NULL; + char group_name[256]; + OSSL_PARAM *old_params = NULL, *new_params = NULL, *p = NULL; + OSSL_PARAM_BLD *bld = NULL; + unsigned char *buf = NULL; + size_t buf_len = 0; + EVP_PKEY *new_pkey = NULL; +#endif pkey = EVP_PKEY_new(); if (!pkey) return CKR_HOST_MEMORY; + r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001); if (r == 1) { pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); @@ -395,8 +410,13 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub r = EVP_PKEY_paramgen_init(pkey_ctx); if (r == 1) r = EVP_PKEY_paramgen(pkey_ctx, &pkey); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (r == 1 && EVP_PKEY_get0(pkey) != NULL) group = EC_KEY_get0_group(EVP_PKEY_get0(pkey)); +#else + EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, group_name, sizeof(group_name), NULL); + group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); +#endif r = -1; if (group) octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey, (long)pubkey_len); @@ -412,8 +432,44 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub P, X, Y, NULL); BN_free(X); BN_free(Y); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (r == 1 && EVP_PKEY_get0(pkey) && P) r = EC_KEY_set_public_key(EVP_PKEY_get0(pkey), P); +#else + EC_GROUP_free(group); + + buf_len = EC_POINT_point2oct(group, P, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL); + if (!(buf = malloc(buf_len))) + r = -1; + if (r == 1 && P) + r = EC_POINT_point2oct(group, P, POINT_CONVERSION_COMPRESSED, buf, buf_len, NULL); + + if (EVP_PKEY_todata(pkey, EVP_PKEY_KEYPAIR, &old_params) != 1 || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, buf_len) != 1 || + !(new_params = OSSL_PARAM_BLD_to_param(bld)) || + !(p = OSSL_PARAM_merge(old_params, new_params))) { + r = -1; + } + free(buf); + OSSL_PARAM_BLD_free(bld); + + if (r == 1) { + if (EVP_PKEY_fromdata_init(pkey_ctx) != 1 || + EVP_PKEY_fromdata(pkey_ctx, &new_pkey, EVP_PKEY_KEYPAIR, p) != 1) { + r = -1; + } + } + OSSL_PARAM_free(old_params); + OSSL_PARAM_free(new_params); + OSSL_PARAM_free(p); + + if (r == 1) { + EVP_PKEY_free(pkey); + pkey = new_pkey; + } +#endif EC_POINT_free(P); } if (r == 1) { From 010ccf3bf364810c4b3cc2dc8733f9fe18d84769 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 29 Oct 2021 10:30:10 +0200 Subject: [PATCH 2184/4321] openssl.c: Chech key type with EVP_PKEY_base_id() --- src/pkcs11/openssl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 8f83cca5e7..7d14849129 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -548,7 +548,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len sc_log(context, "Trying to verify using EVP"); if (md_ctx) { - if (EVP_PKEY_get0_EC_KEY(pkey)) { + if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) { unsigned char *signat_tmp = NULL; size_t signat_len_tmp; int r; @@ -591,7 +591,6 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned int mdbuf_len; unsigned char *mdbuf = NULL; EVP_PKEY_CTX *ctx; - const EC_KEY *eckey; int r; sc_log(context, "Trying to verify using EVP"); @@ -647,9 +646,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len res = 0; r = sc_asn1_sig_value_rs_to_sequence(NULL, signat, signat_len, &signat_tmp, &signat_len_tmp); - eckey = EVP_PKEY_get0_EC_KEY(pkey); ctx = EVP_PKEY_CTX_new(pkey, NULL); - if (r == 0 && eckey && ctx && 1 == EVP_PKEY_verify_init(ctx)) + if (r == 0 && EVP_PKEY_base_id(pkey) == EVP_PKEY_EC && ctx && EVP_PKEY_verify_init(ctx) == 1) res = EVP_PKEY_verify(ctx, signat_tmp, signat_len_tmp, data, data_len); EVP_PKEY_CTX_free(ctx); From 632285869b9abf363f1b8b148cb31541b56be552 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 29 Oct 2021 10:38:01 +0200 Subject: [PATCH 2185/4321] openssl.c: Recover signature data with EVP_PKEY API --- src/pkcs11/openssl.c | 45 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 7d14849129..7ea9d76e13 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -663,9 +663,11 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len return CKR_GENERAL_ERROR; } else { - RSA *rsa; unsigned char *rsa_out = NULL, pad; - int rsa_outlen = 0; + size_t rsa_outlen = 0; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) + return CKR_DEVICE_MEMORY; sc_log(context, "Trying to verify using low-level API"); switch (mech->mechanism) { @@ -687,28 +689,32 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len break; default: EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); return CKR_ARGUMENTS_BAD; } - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - if (rsa == NULL) - return CKR_DEVICE_MEMORY; + if ( EVP_PKEY_verify_recover_init(ctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + return CKR_GENERAL_ERROR; + } - rsa_out = calloc(1, RSA_size(rsa)); + rsa_outlen = EVP_PKEY_size(pkey); + rsa_out = calloc(1, rsa_outlen); if (rsa_out == NULL) { - RSA_free(rsa); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); return CKR_DEVICE_MEMORY; } - - rsa_outlen = RSA_public_decrypt(signat_len, signat, rsa_out, rsa, pad); - if (rsa_outlen <= 0) { - RSA_free(rsa); + if (EVP_PKEY_verify_recover(ctx, rsa_out, &rsa_outlen, signat, signat_len) != 1) { free(rsa_out); - sc_log(context, "RSA_public_decrypt() returned %d\n", rsa_outlen); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + sc_log(context, "RSA_public_decrypt() returned %d\n", (int) rsa_outlen); return CKR_GENERAL_ERROR; } - + EVP_PKEY_CTX_free(ctx); /* For PSS mechanisms we can not simply compare the "decrypted" * data -- we need to verify the PSS padding is valid */ @@ -723,7 +729,6 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned char digest[EVP_MAX_MD_SIZE]; if (mech->pParameter == NULL) { - RSA_free(rsa); free(rsa_out); sc_log(context, "PSS mechanism requires parameter"); return CKR_MECHANISM_PARAM_INVALID; @@ -747,7 +752,6 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len mgf_md = EVP_sha512(); break; default: - RSA_free(rsa); free(rsa_out); return CKR_MECHANISM_PARAM_INVALID; } @@ -769,7 +773,6 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len pss_md = EVP_sha512(); break; default: - RSA_free(rsa); free(rsa_out); return CKR_MECHANISM_PARAM_INVALID; } @@ -784,7 +787,6 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned int tmp_len; if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { - RSA_free(rsa); free(rsa_out); return CKR_GENERAL_ERROR; } @@ -793,22 +795,19 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len } rv = CKR_SIGNATURE_INVALID; if (data_len == (unsigned int) EVP_MD_size(pss_md) - && RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, - rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) + /*&& RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, + rsa_out, EVP_MD_size(pss_md))*/ == 1) rv = CKR_OK; - RSA_free(rsa); free(rsa_out); sc_log(context, "Returning %lu", rv); return rv; } - RSA_free(rsa); if ((unsigned int) rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) rv = CKR_OK; else rv = CKR_SIGNATURE_INVALID; - free(rsa_out); } return rv; From f1593aa80ef86dcbd35f215171a1fb85e583b4e1 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Fri, 29 Oct 2021 10:39:11 +0200 Subject: [PATCH 2186/4321] openssl.c: Verification of PSS mechanisms with EVP_PKEY API --- src/pkcs11/openssl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 7ea9d76e13..4b8a86ccaf 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -794,10 +794,25 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len data_len = tmp_len; } rv = CKR_SIGNATURE_INVALID; - if (data_len == (unsigned int) EVP_MD_size(pss_md) - /*&& RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, - rsa_out, EVP_MD_size(pss_md))*/ == 1) + + if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || + EVP_PKEY_verify_init(ctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) != 1 || + EVP_PKEY_CTX_set_signature_md(ctx, pss_md) != 1 || + EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, param->sLen) != 1 || + EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf_md) != 1) { + sc_log(context, "Failed to initialize EVP_PKEY_CTX"); + free(rsa_out); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + return rv; + } + + if (data_len == (unsigned int) EVP_MD_size(pss_md) && + EVP_PKEY_verify(ctx, signat, signat_len, data, data_len) == 1) rv = CKR_OK; + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); free(rsa_out); sc_log(context, "Returning %lu", rv); return rv; @@ -807,7 +822,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len rv = CKR_OK; else rv = CKR_SIGNATURE_INVALID; - + free(rsa_out); } return rv; From bd5b25fa6ee096332f5e4313d4964e319459f39d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 27 Oct 2021 12:03:16 +0200 Subject: [PATCH 2187/4321] Add test for build with OpenSSL 3.0 --- .github/build.sh | 20 +++++++-- .github/setup-linux.sh | 12 ++++- .github/setup-openssl.sh | 19 ++++++++ .github/workflows/linux.yml | 50 +++++++++++++++++++++ containers/opensc-build-ossl3/Containerfile | 12 +++++ 5 files changed, 109 insertions(+), 4 deletions(-) create mode 100755 .github/setup-openssl.sh create mode 100644 containers/opensc-build-ossl3/Containerfile diff --git a/.github/build.sh b/.github/build.sh index fa29e621ae..399bc7f1a8 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -2,7 +2,11 @@ set -ex -o xtrace -export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; +if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then + export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig; +else + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; +fi if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') @@ -42,7 +46,13 @@ else export LDFLAGS="-m32" fi # normal procedure - ./configure --disable-dependency-tracking + + if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then + # without -Werror, because of rest of deprecated API + ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2 -g -O2" + else + ./configure --disable-dependency-tracking + fi make -j 2 V=1 # 32b build has some issues to find openssl correctly if [ "$1" != "ix86" ]; then @@ -52,7 +62,11 @@ fi # this is broken in old ubuntu if [ "$1" == "dist" ]; then - make distcheck + if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then + make distcheck DISTCHECK_CONFIGURE_FLAGS="--disable-strict CFLAGS=\"-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2 -g -O2\"" + else + make distcheck + fi make dist fi diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index f63e194515..ac10c8b766 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -3,7 +3,12 @@ set -ex -o xtrace # Generic dependencies -DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config openssl git" +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git" + +# Add openssl or install openssl3.0 +if [ "$1" != "ossl3" -a "$2" != "ossl3" ]; then + DEPS="$DEPS openssl" +fi # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then @@ -48,6 +53,11 @@ export DEBCONF_NONINTERACTIVE_SEEN=true sudo apt-get update sudo apt-get install -y build-essential $DEPS +# install openssl 3.0 if needed +if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then + ./.github/setup-openssl.sh +fi + if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 diff --git a/.github/setup-openssl.sh b/.github/setup-openssl.sh new file mode 100755 index 0000000000..04c17db4c8 --- /dev/null +++ b/.github/setup-openssl.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -ex -o xtrace + +sudo apt-get remove -y openssl libssl-dev java8-runtime-headless default-jre-headless + +if [ ! -d "openssl" ]; then + git clone https://github.com/openssl/openssl +fi +pushd openssl +git checkout openssl-3.0 +./Configure --prefix=/usr/local linux-x86_64 +make -j $(nproc) +sudo make install +popd + +# update dynamic linker to find the libraries in non-standard path +echo "/usr/local/lib64" | sudo tee /etc/ld.so.conf.d/openssl.conf +sudo ldconfig diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 3fa1559c8b..a70ef76d87 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -178,6 +178,56 @@ jobs: - run: .github/setup-linux.sh oseid - run: .github/test-oseid.sh + ########################## + ## OpenSSL 3.0 pipeline ## + ########################## + build-openssl-3: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh ossl3 + - run: .github/build.sh dist ossl3 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-ossl3 + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: opensc-build + path: + opensc*.tar.gz + + test-cac-openssl-3: + runs-on: ubuntu-latest + needs: [build-openssl-3] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-ossl3 + - run: .github/setup-linux.sh cac ossl3 + - run: .github/test-cac.sh + + test-oseid-openssl-3: + runs-on: ubuntu-latest + needs: [build-openssl-3] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-ossl3 + - run: .github/setup-linux.sh oseid ossl3 + - run: .github/test-oseid.sh + + #################### + ## Push artifacts ## + #################### push-artifacts: runs-on: ubuntu-latest needs: [build, build-mingw] diff --git a/containers/opensc-build-ossl3/Containerfile b/containers/opensc-build-ossl3/Containerfile new file mode 100644 index 0000000000..a71e79df8e --- /dev/null +++ b/containers/opensc-build-ossl3/Containerfile @@ -0,0 +1,12 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh ossl3 +CMD /src/.github/build.sh dist ossl3 From 1459c14766485d5f170e996fd1a86e3e16988feb Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 16 Nov 2021 18:47:25 +0100 Subject: [PATCH 2188/4321] Add containers for test-oseid and test-cac with OpenSSL 3.0 --- containers/opensc-test-cac-ossl3/Containerfile | 13 +++++++++++++ containers/opensc-test-oseid-ossl3/Containerfile | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 containers/opensc-test-cac-ossl3/Containerfile create mode 100644 containers/opensc-test-oseid-ossl3/Containerfile diff --git a/containers/opensc-test-cac-ossl3/Containerfile b/containers/opensc-test-cac-ossl3/Containerfile new file mode 100644 index 0000000000..47fc47ffd0 --- /dev/null +++ b/containers/opensc-test-cac-ossl3/Containerfile @@ -0,0 +1,13 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh cac ossl3 +RUN /src/.github/build.sh ossl3 +CMD /src/.github/test-cac.sh diff --git a/containers/opensc-test-oseid-ossl3/Containerfile b/containers/opensc-test-oseid-ossl3/Containerfile new file mode 100644 index 0000000000..6dbbd3b161 --- /dev/null +++ b/containers/opensc-test-oseid-ossl3/Containerfile @@ -0,0 +1,13 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh oseid ossl3 +RUN /src/.github/build.sh ossl3 +CMD /src/.github/test-oseid.sh From c79bc27d3d30baf5cc1a6f9a19411fb0b7974f05 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 10:36:23 +0100 Subject: [PATCH 2189/4321] card-westcos.c: Encrypt final data --- src/libopensc/card-westcos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 9c0b952f5f..bd7fa4a235 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -683,6 +683,10 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, return SC_ERROR_INTERNAL; } *len = tmplen; + if (EVP_EncryptFinal_ex(cctx, result + tmplen, &tmplen) != 1) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } EVP_CIPHER_CTX_free(cctx); return SC_SUCCESS; #else From 4e52ba93107da14618506d242231da43f9fdd56f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 10:59:34 +0100 Subject: [PATCH 2190/4321] card-westcos.c: Remove un unnecessary code --- src/libopensc/card-westcos.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index bd7fa4a235..6d8a18c269 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -1108,7 +1108,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, const u8 * data, size_t data_len, u8 * out, size_t outlen) { - int r; + int r = SC_SUCCESS; sc_file_t *keyfile = NULL; #ifdef ENABLE_OPENSSL int idx = 0; @@ -1118,6 +1118,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, EVP_PKEY_CTX *ctx = NULL; BIO *mem = BIO_new(BIO_s_mem()); EVP_PKEY *pkey = NULL; + size_t tmplen = 0; #endif if (card == NULL) @@ -1207,11 +1208,10 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, goto out; } -#if 1 if (mode) { /* decipher */ if (EVP_PKEY_decrypt_init(ctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1 || - (r = EVP_PKEY_decrypt(ctx, out, NULL, data, data_len)) != 1) { + EVP_PKEY_decrypt(ctx, out, &tmplen, data, data_len) != 1) { #ifdef DEBUG_SSL print_openssl_error(); @@ -1226,7 +1226,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, else { /* sign */ if (EVP_PKEY_encrypt_init(ctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1 || - (r = EVP_PKEY_encrypt(ctx, out, NULL, data, data_len)) != 1) { + EVP_PKEY_encrypt(ctx, out, &tmplen, data, data_len) != 1) { #ifdef DEBUG_SSL print_openssl_error(); @@ -1238,16 +1238,6 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, } } -#else - if (RSA_sign(nid, data, data_len, out, &outlen, rsa) != 1) { - sc_log(card->ctx, - "RSA_sign error %d \n", ERR_get_error()); - r = SC_ERROR_UNKNOWN; - goto out; - } - r = outlen; - -#endif out: if (mem) BIO_free(mem); From 74cc9298bc38fa66f1e00c616a577559068d1822 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 11:40:01 +0100 Subject: [PATCH 2191/4321] cwa-dnie.c: Avoid memory leaks --- src/libopensc/cwa-dnie.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index b336641c57..6d5278b95c 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -868,6 +868,10 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, *ifd_privkey = EVP_PKEY_new(); int res = SC_ERROR_INTERNAL; if (!ifd_rsa || !*ifd_privkey) { + if (ifd_rsa) + RSA_free(ifd_rsa); + if (*ifd_privkey) + EVP_PKEY_free(*ifd_privkey); #else OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; @@ -908,6 +912,9 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, OSSL_PARAM_BLD_free(bld); OSSL_PARAM_free(params); EVP_PKEY_CTX_free(ctx); + BN_free(ifd_rsa_n); + BN_free(ifd_rsa_e); + BN_free(ifd_rsa_d); sc_log(card->ctx, "Cannot set RSA values for CA public key"); return SC_ERROR_INTERNAL; } From 89b3fd7be8e58972c9d430773091fa730524ccbf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:02:47 +0100 Subject: [PATCH 2192/4321] Check loading of legacy provider for failure --- src/libopensc/cwa14890.c | 8 ++++++++ src/tools/cardos-tool.c | 9 ++++++++- src/tools/pkcs11-tool.c | 12 +++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 8db6df4582..55eb635cf9 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1614,6 +1614,10 @@ int cwa_encode_apdu(sc_card_t * card, #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + msg = "Failed to load legacy provider"; + goto encode_end; + } #endif if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || @@ -1846,6 +1850,10 @@ int cwa_decode_response(sc_card_t * card, #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + msg = "Failed to load legacy provider"; + goto response_decode_end; + } #endif if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 06fd09f311..04da622be7 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -440,11 +440,18 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* prepare des ctx */ memcpy(key1, key, 8); memcpy(key2, key + 8, 8); - cctx = EVP_CIPHER_CTX_new(); + #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + printf("Failed to load legacy provider, aborting\n"); + free(mac_input); + return 0; + } #endif + + cctx = EVP_CIPHER_CTX_new(); if (!cctx || !EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key1, NULL) || !EVP_CIPHER_CTX_set_padding(cctx, 0)) { diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5ab7a85681..505f69c4df 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5873,8 +5873,11 @@ static int test_digest(CK_SESSION_HANDLE session) for (; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) { + if (!legacy_provider) legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + printf("Failed to load legacy provider\n"); + break; } #endif @@ -6074,9 +6077,12 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, EVP_sha256(), }; #endif -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(OPENSSL_NO_RIPEMD) + if (!legacy_provider) legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + printf("Failed to load legacy provider"); + return errors; } #endif From 37910cb7167c4476163a881601690c8f05d63a68 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:22:27 +0100 Subject: [PATCH 2193/4321] p11test: Replace EC_POINT_bn2point with EC_POINT_hex2point EC_POINT_hex2point is not available in OpenSSL 3.0 --- src/tests/p11test/p11test_case_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 79a05c0e3b..ce3b3bedfe 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -484,12 +484,10 @@ int callback_public_keys(test_certs_t *objects, EC_GROUP_free(ecgroup); return -1; } -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ecpoint = EC_POINT_bn2point(ecgroup, bn, NULL, NULL); -#else + ecpoint = EC_POINT_hex2point(ecgroup, BN_bn2hex(bn), NULL, NULL); -#endif BN_free(bn); + if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " BIGNUM to OpenSSL format", o->id_str); From 7915ec06cc3526ee03b65f52f63614552b3300bd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:31:08 +0100 Subject: [PATCH 2194/4321] p11test: Use normal free in p11test_case_ec_derive --- src/tests/p11test/p11test_case_ec_derive.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 4bf655a5e5..ec8aecf277 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -301,6 +301,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) debug_print(" [ KEY %s ] EVP_PKEY_derive failed", o->id_str); EVP_PKEY_CTX_free(pctx); EVP_PKEY_free(evp_pkey); + free(secret); return 1; } EVP_PKEY_CTX_free(pctx); @@ -321,7 +322,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) /* Allocate memory for public key*/ if (pub_len == 0) { debug_print(" [ KEY %s ] Failed to allocate memory for secret", o->id_str); - OPENSSL_free(secret); + free(secret); EVP_PKEY_free(evp_pkey); return 1; } @@ -329,7 +330,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) pub = malloc(pub_len); if (pub == NULL) { debug_print(" [ OK %s ] Failed to allocate memory", o->id_str); - OPENSSL_free(secret); + free(secret); EVP_PKEY_free(evp_pkey); return 1; } @@ -343,7 +344,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) #endif debug_print(" [ KEY %s ] Can not get public key", o->id_str); EVP_PKEY_free(evp_pkey); - OPENSSL_free(secret); + free(secret); free(pub); return 1; } @@ -360,7 +361,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) } free(pub); - OPENSSL_free(secret); + free(secret); free(pkcs11_secret); return rv; } From 3b5c347c4b49b8e1f83573f017e8d65b399fb961 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:40:45 +0100 Subject: [PATCH 2195/4321] p11test: Simplify hashing with EVP_Digest --- src/tests/p11test/p11test_case_pss_oaep.c | 38 +++++++++++------------ 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index f0afdc8b35..b88f821879 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -189,44 +189,42 @@ CK_BYTE *hash_message(const CK_BYTE *message, size_t message_length, CK_MECHANISM_TYPE hash) { CK_BYTE *out = NULL; + const EVP_MD *md = NULL; + size_t digest_len = 0; switch (hash) { case CKM_SHA224: - out = malloc(SHA224_DIGEST_LENGTH); - if (out == NULL) - return NULL; - EVP_Digest(message, message_length, out, NULL, EVP_sha224(), NULL); + digest_len = SHA224_DIGEST_LENGTH; + md = EVP_sha224(); break; case CKM_SHA256: - out = malloc(SHA256_DIGEST_LENGTH); - if (out == NULL) - return NULL; - EVP_Digest(message, message_length, out, NULL, EVP_sha256(), NULL); + digest_len = SHA256_DIGEST_LENGTH; + md = EVP_sha256(); break; case CKM_SHA384: - out = malloc(SHA384_DIGEST_LENGTH); - if (out == NULL) - return NULL; - EVP_Digest(message, message_length, out, NULL, EVP_sha384(), NULL); + digest_len = SHA384_DIGEST_LENGTH; + md = EVP_sha384(); break; case CKM_SHA512: - out = malloc(SHA512_DIGEST_LENGTH); - if (out == NULL) - return NULL; - EVP_Digest(message, message_length, out, NULL, EVP_sha512(), NULL); + digest_len = SHA512_DIGEST_LENGTH; + md = EVP_sha512(); break; case CKM_SHA_1: default: - out = malloc(SHA_DIGEST_LENGTH); - if (out == NULL) - return NULL; - EVP_Digest(message, message_length, out, NULL, EVP_sha1(), NULL); + digest_len = SHA_DIGEST_LENGTH; + md = EVP_sha1(); break; + } + out = malloc(digest_len); + if (!out || + EVP_Digest(message, message_length, out, NULL, md, NULL) != 1) { + free(out); + return NULL; } return out; } From 42320eda0c808225a35232e02742aa538385b7b6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:42:33 +0100 Subject: [PATCH 2196/4321] p11test: Remove trailing whitespace --- src/tests/p11test/p11test_case_readonly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index e71aa9c899..c6b659c5aa 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -49,7 +49,7 @@ "\xdd\xa3\x76\x44\x2f\x50\xe1\xec" \ "\xd3\x8b\xcd\x6f\xc6\xce\x4e\xfd" \ "\xd3\x1a\x3f" -#define BUFFER_SIZE 4096 +#define BUFFER_SIZE 4096 const unsigned char *const_message = (unsigned char *) MESSAGE_TO_SIGN; From fe5901ca439d3406e6041ba0956712c9c0099350 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 12 Nov 2021 12:48:20 +0100 Subject: [PATCH 2197/4321] p11test: Change RAND_bytes_ex() back to RAND_bytes() --- src/tests/p11test/p11test_case_readonly.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index c6b659c5aa..b7112928c7 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -77,11 +77,7 @@ rsa_x_509_pad_message(const unsigned char *message, memset(pad_message + 2, 0xff, padding_len); } else { pad_message[1] = 0x02; -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (RAND_bytes_ex(NULL, pad_message + 2, padding_len, 0) != 1) { -#else if (RAND_bytes(pad_message + 2, padding_len) != 1) { -#endif debug_print("Can not generate random bytes."); } } From 70397452bf2568cc1ecbb6a7a86e9b17cc8746c4 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 16 Nov 2021 15:13:31 +0100 Subject: [PATCH 2198/4321] p11test: Add legacy provider to p11test_case_readonly --- src/tests/p11test/p11test_case_readonly.c | 39 ++++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index b7112928c7..bcb408d20c 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -25,6 +25,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# include +#endif #define MESSAGE_TO_SIGN "Simple message for signing & verifying. " \ "It needs to be little bit longer to fit also longer keys and allow the truncation.\n" \ @@ -51,6 +54,10 @@ "\xd3\x1a\x3f" #define BUFFER_SIZE 4096 +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +OSSL_PROVIDER *legacy_provider = NULL; +#endif + const unsigned char *const_message = (unsigned char *) MESSAGE_TO_SIGN; static unsigned char * @@ -294,7 +301,14 @@ int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; CK_ULONG sign_length = 0; char *name; - +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); + return 0; + } +#endif rv = fp->C_SignInit(info->session_handle, &sign_mechanism, o->private_handle); if (rv == CKR_KEY_TYPE_INCONSISTENT) { @@ -304,8 +318,8 @@ int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, debug_print(" [SKIP %s ] Bad mechanism. Not supported?", o->id_str); return 0; } else if (rv != CKR_OK) { - debug_print(" C_SignInit: rv = 0x%.8lX\n", rv); - return -1; + debug_print(" [SKIP %s ] Not allowed to sign with this key?", o->id_str); + return 0; } always_authenticate(o, info); @@ -422,6 +436,14 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, md = EVP_md5(); break; case CKM_RIPEMD160_RSA_PKCS: +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!legacy_provider) + legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); + return 0; + } +#endif md = EVP_ripemd160(); break; default: @@ -429,7 +451,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, return 0; } - if ((mdctx = EVP_MD_CTX_create()) == NULL || + if ((mdctx = EVP_MD_CTX_new()) == NULL || (rv = EVP_DigestVerifyInit(mdctx, NULL, md, NULL, o->key) <= 0) || (rv = EVP_DigestVerify(mdctx, sign, sign_length, message, message_length)) != 1) { fprintf(stderr, " [ ERROR %s ] Signature is not valid. Error: %s\n", @@ -538,10 +560,11 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; + CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + static int verify_support = 0; char *name; - if (!info->verify_support) + if (!verify_support) goto openssl_verify; /* try C_Verify() if it is supported */ @@ -549,7 +572,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, o->public_handle); if (rv != CKR_OK) { debug_print(" C_VerifyInit: rv = 0x%.8lX", rv); - info->verify_support = 0; /* avoid trying over and over again */ + verify_support = 0; /* avoid trying over and over again */ goto openssl_verify; } if (multipart) { @@ -582,7 +605,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, return 1; } debug_print(" %s: rv = 0x%.8lX", name, rv); - info->verify_support = 0; /* avoid trying over and over again */ + verify_support = 0; /* avoid trying over and over again */ openssl_verify: debug_print(" [ KEY %s ] Falling back to openssl verification", o->id_str); From cd16bb21ecf1258488c6992fadc3ebbaaed1016f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 15 Nov 2021 14:20:19 +0100 Subject: [PATCH 2199/4321] pkcs15-prkey.c: Fix param getters --- src/libopensc/pkcs15-prkey.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 9c51e9e91c..8b09048bd7 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -683,7 +683,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa; #if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1 = NULL; + const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1; RSA *src = NULL; if (!(src = EVP_PKEY_get1_RSA(pk))) return SC_ERROR_INCOMPATIBLE_KEY; @@ -692,7 +692,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) RSA_get0_factors(src, &src_p, &src_q); RSA_get0_crt_params(src, &src_dmp1, &src_dmq1, &src_iqmp); #else - BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1 = NULL; + BIGNUM *src_n = NULL, *src_e = NULL, *src_d = NULL, *src_p = NULL, *src_q= NULL, *src_iqmp = NULL, *src_dmp1 = NULL, *src_dmq1 = NULL; if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &src_n) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_E, &src_e) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_D, &src_d) != 1 || @@ -748,7 +748,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) DSA_get0_key(src, &src_pub_key, &src_priv_key); DSA_get0_pqg(src, &src_p, &src_q, &src_g); #else - BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key = NULL; + BIGNUM *src_pub_key = NULL, *src_p = NULL, *src_q , *src_g = NULL, *src_priv_key = NULL; if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || @@ -822,23 +822,22 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) #else EC_GROUP *grp = NULL; BIGNUM *src_priv_key = NULL; - char *grp_name = NULL; size_t grp_name_len = 0; + char grp_name[256]; if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1) { return SC_ERROR_UNKNOWN; } - EVP_PKEY_get_group_name(pk, NULL, 0, &grp_name_len); - if ((grp_name = malloc(grp_name_len)) == NULL) { + if (EVP_PKEY_get_group_name(pk, grp_name, sizeof(grp_name), NULL) != 1) { BN_free(src_priv_key); - return SC_ERROR_OUT_OF_MEMORY; + return SC_ERROR_UNKNOWN; } - - if (EVP_PKEY_get_group_name(pk, grp_name, grp_name_len, NULL) != 1 || - (nid = OBJ_sn2nid(grp_name)) == 0 || - (grp = EC_GROUP_new_by_curve_name(nid)) == NULL) { + if ((nid = OBJ_sn2nid(grp_name)) == 0) { + BN_free(src_priv_key); + return SC_ERROR_UNKNOWN; + } + if ((grp = EC_GROUP_new_by_curve_name(nid)) == NULL) { BN_free(src_priv_key); - free(grp_name); return SC_ERROR_UNKNOWN; } #endif @@ -846,7 +845,6 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) if (!sc_pkcs15_convert_bignum(&dst->privateD, src_priv_key)) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(src_priv_key); - free(grp_name); EC_GROUP_free(grp); #endif return SC_ERROR_INCOMPATIBLE_KEY; @@ -860,7 +858,6 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) } #else dst->params.named_curve = strdup(grp_name); - free(grp_name); #endif #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -870,11 +867,11 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) if (!buflen) return SC_ERROR_INCOMPATIBLE_KEY; #else - if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, NULL) != 1) { + /* Decode EC_POINT from a octet string */ + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, &buflen) != 1) { return SC_ERROR_INCOMPATIBLE_KEY; } #endif - /* copy the public key */ dst->ecpointQ.value = malloc(buflen); if (!dst->ecpointQ.value) From 98435a61963e20f9c52134a4106ccef3052b086d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 15 Nov 2021 15:07:18 +0100 Subject: [PATCH 2200/4321] pkcs15-pubkey.c: Fix param getters --- src/libopensc/pkcs15-pubkey.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index af0f318a4d..84c9fc3ff9 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1723,7 +1723,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa; /* Get parameters */ #if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *src_n, *src_e = NULL; + const BIGNUM *src_n, *src_e; RSA *src = NULL; if (!(src = EVP_PKEY_get1_RSA(pk))) return SC_ERROR_INCOMPATIBLE_KEY; @@ -1733,7 +1733,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) return SC_ERROR_INTERNAL; } #else - BIGNUM *src_n, *src_e = NULL; + BIGNUM *src_n = NULL, *src_e = NULL; if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &src_n) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_E, &src_e) != 1) { BN_free(src_n); @@ -1774,7 +1774,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) return SC_ERROR_INTERNAL; } #else - BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; + BIGNUM *src_pub_key = NULL, *src_priv_key = NULL, *src_p = NULL, *src_q = NULL, *src_g = NULL; if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || @@ -1910,19 +1910,17 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) dst->params.named_curve = strdup(group_name); } #else - char *group_name = NULL; size_t group_name_len = 0; + char group_name[256]; if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, NULL) != 1) return SC_ERROR_INTERNAL; - EVP_PKEY_get_group_name(pk, NULL, 0, &group_name_len); - if (group_name_len != 0) { - if (!(group_name = malloc(group_name_len)) || - EVP_PKEY_get_group_name(pk, group_name, group_name_len, NULL)) { - free(group_name); - return SC_ERROR_INTERNAL; - } - } + if (EVP_PKEY_get_group_name(pk, group_name, sizeof(group_name), NULL) != 1) + return SC_ERROR_INTERNAL; dst->params.named_curve = strdup(group_name); - free(group_name); + + /* Decode EC_POINT from a octet string */ + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, &buflen) != 1) { + return SC_ERROR_INCOMPATIBLE_KEY; + } #endif /* copy the public key */ From 730dca273f969a57c6d3b44000af865a87d9068b Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 16 Nov 2021 15:44:48 +0100 Subject: [PATCH 2201/4321] pkcs15-init: Add alias for EVP_PKEY_eq --- src/libopensc/sc-ossl-compat.h | 4 ++++ src/tools/pkcs15-init.c | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 782bb99429..7762f77dd5 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -103,6 +103,10 @@ extern "C" { #define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") #endif +#if OPENSSL_VERSION_NUMBER < 0x30000000L +#define EVP_PKEY_eq EVP_PKEY_cmp +#endif + /* * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures * One can no longer use statements like rsa->n = ... diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 39b5e06ea0..e965569aa9 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1344,11 +1344,8 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, r = SC_ERROR_INVALID_ARGUMENTS; if (oldpk_type == newpk_type) { -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (EVP_PKEY_eq(oldpk, newpk)) - r = 0; -#elif OPENSSL_VERSION_NUMBER >= 0x10002000L - if (EVP_PKEY_cmp(oldpk, newpk) == 1) +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (EVP_PKEY_eq(oldpk, newpk) == 1) r = 0; #else if ((oldpk_type == EVP_PKEY_DSA) && From ccdbb7145ed968c7d32df5f41d5cd67354c2f5d1 Mon Sep 17 00:00:00 2001 From: xhanulik Date: Tue, 16 Nov 2021 15:49:08 +0100 Subject: [PATCH 2202/4321] pkcs15-westcos.c: Change alias for EVP_PKEY_CTX_set_rsa_keygen_pubexp --- src/libopensc/sc-ossl-compat.h | 2 +- src/pkcs15init/pkcs15-westcos.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 7762f77dd5..aaabdcd288 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -99,12 +99,12 @@ extern "C" { #include #define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates #define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates -#define EVP_PKEY_CTX_set_rsa_keygen_pubexp EVP_PKEY_CTX_set1_rsa_keygen_pubexp #define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") #endif #if OPENSSL_VERSION_NUMBER < 0x30000000L #define EVP_PKEY_eq EVP_PKEY_cmp +#define EVP_PKEY_CTX_set1_rsa_keygen_pubexp EVP_PKEY_CTX_set_rsa_keygen_pubexp #endif /* diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 1e20b17f31..63a96656db 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -246,7 +246,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, if (BN_set_word(bn, RSA_F4) != 1 || EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || - EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; From 6dff6fc2bd8840e954977488c1d98f34227da47d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 22 Nov 2021 12:36:45 +0100 Subject: [PATCH 2203/4321] Remove unnecessary CFLAGS --- .github/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 399bc7f1a8..3248db1864 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -49,7 +49,7 @@ else if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then # without -Werror, because of rest of deprecated API - ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2 -g -O2" + ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2" else ./configure --disable-dependency-tracking fi @@ -63,7 +63,7 @@ fi # this is broken in old ubuntu if [ "$1" == "dist" ]; then if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - make distcheck DISTCHECK_CONFIGURE_FLAGS="--disable-strict CFLAGS=\"-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2 -g -O2\"" + make distcheck DISTCHECK_CONFIGURE_FLAGS="--disable-strict CFLAGS=\"-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2\"" else make distcheck fi From b4d365b3f63e172bc4ba31ae67274436f2b56acf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 10:53:43 +0100 Subject: [PATCH 2204/4321] card-westcos.c: Update length after encryption --- src/libopensc/card-westcos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 6d8a18c269..b1e85b1c20 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -676,7 +676,7 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, if (r) return r; #ifdef ENABLE_OPENSSL - if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx,0) != 1 || EVP_EncryptUpdate(cctx, result, &tmplen, buf, *len) != 1) { EVP_CIPHER_CTX_free(cctx); @@ -687,6 +687,7 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, EVP_CIPHER_CTX_free(cctx); return SC_ERROR_INTERNAL; } + *len += tmplen; EVP_CIPHER_CTX_free(cctx); return SC_SUCCESS; #else From f12f683326f80a95fd393e00dead02fd3626812e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 13:22:21 +0100 Subject: [PATCH 2205/4321] cwa-dnie.c: Avoid memory leaks --- src/libopensc/cwa-dnie.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 6d5278b95c..6d32473f36 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -687,6 +687,10 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) root_ca_rsa = RSA_new(); *root_ca_key = EVP_PKEY_new(); if (!root_ca_rsa || !*root_ca_key) { + if (root_ca_rsa) + RSA_free(root_ca_rsa); + if (*root_ca_key) + EVP_PKEY_free(*root_ca_key); #else EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = NULL; @@ -703,6 +707,14 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) /* obtain the data channel info for the card */ res = dnie_get_channel_data(card, &data); + if (res < 0) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(root_ca_rsa); + EVP_PKEY_free(*root_ca_key); +#else + EVP_PKEY_CTX_free(ctx); +#endif + } LOG_TEST_RET(card->ctx, res, "Error getting the card channel data"); /* compose root_ca_public key with data provided by Dnie Manual */ @@ -713,8 +725,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) { BN_free(root_ca_rsa_n); BN_free(root_ca_rsa_e); - if (*root_ca_key) - EVP_PKEY_free(*root_ca_key); + EVP_PKEY_free(*root_ca_key); RSA_free(root_ca_rsa); sc_log(card->ctx, "Cannot set RSA values for CA public key"); return SC_ERROR_INTERNAL; @@ -742,11 +753,11 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) #endif BN_free(root_ca_rsa_n); BN_free(root_ca_rsa_e); - if (*root_ca_key) - EVP_PKEY_free(*root_ca_key); /*implies root_ca_rsa free() */ + EVP_PKEY_free(*root_ca_key); sc_log(card->ctx, "Cannot compose root CA public key"); return SC_ERROR_INTERNAL; } + #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); @@ -864,9 +875,13 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA *ifd_rsa = RSA_new(); - *ifd_privkey = EVP_PKEY_new(); int res = SC_ERROR_INTERNAL; + RSA *ifd_rsa = NULL; + + LOG_FUNC_CALLED(card->ctx); + ifd_rsa = RSA_new(); + *ifd_privkey = EVP_PKEY_new(); + if (!ifd_rsa || !*ifd_privkey) { if (ifd_rsa) RSA_free(ifd_rsa); @@ -875,15 +890,17 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, #else OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + EVP_PKEY_CTX *ctx = NULL; + + LOG_FUNC_CALLED(card->ctx); + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!ctx) { #endif sc_log(card->ctx, "Cannot create data for IFD private key"); return SC_ERROR_OUT_OF_MEMORY; } - LOG_FUNC_CALLED(card->ctx); - /* compose ifd_private key with data provided in Annex 3 of DNIe Manual */ ifd_rsa_n = BN_bin2bn(modulus, modulus_len, NULL); ifd_rsa_e = BN_bin2bn(public_exponent, public_exponent_len, NULL); From 1af5ff6b4d9e21d86dcb1079f4d1c4998b0c9216 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 13:35:47 +0100 Subject: [PATCH 2206/4321] cwa14890.c: Reword error message --- src/libopensc/cwa14890.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 55eb635cf9..0bbf7b16bf 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -614,13 +614,13 @@ static int cwa_prepare_external_auth(sc_card_t * card, memcpy(buf3 + 1 + 74 + 32, sha_data, SHA_DIGEST_LENGTH); buf3[127] = 0xBC; /* iso padding */ - /* encrypt with ifd private key */ + /* decrypt with ifd private key */ pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL); if (!pctx || EVP_PKEY_decrypt_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || EVP_PKEY_decrypt(pctx, buf2, &len2, buf3, 128) != 1) { - msg = "Prepare external auth: ifd_privk encrypt failed"; + msg = "Prepare external auth: ifd_privk decrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; EVP_PKEY_CTX_free(pctx); goto prepare_external_auth_end; From c45d4c8f56fa3498448ac9fd1f43f6c19f19fd66 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 13:52:27 +0100 Subject: [PATCH 2207/4321] cwa14890.c: Replace EVP_des_ede with EVP_des_ede_ecb --- src/libopensc/cwa14890.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 0bbf7b16bf..8354ecc810 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1642,7 +1642,7 @@ int cwa_encode_apdu(sc_card_t * card, } /* and apply 3DES to result */ - if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in 3DEC ECB encryption"; @@ -1879,7 +1879,7 @@ int cwa_decode_response(sc_card_t * card, } /* finally apply 3DES to result */ - if (EVP_EncryptInit_ex(cctx, EVP_des_ede(), NULL, key, NULL) != 1 || + if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in 3DEC ECB encryption"; From d60acb1b8d0e2764c8dcfa433959df26a68ff28f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:07:50 +0100 Subject: [PATCH 2208/4321] Simplify check for legacy provider --- src/libopensc/cwa14890.c | 16 ++++++++-------- src/tools/cardos-tool.c | 10 +++++----- src/tools/pkcs11-tool.c | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 8354ecc810..971281b4b7 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1612,11 +1612,11 @@ int cwa_encode_apdu(sc_card_t * card, key = sm_session->session_mac; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - msg = "Failed to load legacy provider"; - goto encode_end; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + msg = "Failed to load legacy provider"; + goto encode_end; + } } #endif @@ -1848,11 +1848,11 @@ int cwa_decode_response(sc_card_t * card, key = sm_session->session_mac; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - msg = "Failed to load legacy provider"; - goto response_decode_end; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + msg = "Failed to load legacy provider"; + goto response_decode_end; + } } #endif diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 04da622be7..c1544e8e60 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -442,12 +442,12 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char memcpy(key2, key + 8, 8); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - printf("Failed to load legacy provider, aborting\n"); - free(mac_input); - return 0; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + printf("Failed to load legacy provider, aborting\n"); + free(mac_input); + return 0; + } } #endif diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 505f69c4df..8e858fd99b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5873,11 +5873,11 @@ static int test_digest(CK_SESSION_HANDLE session) for (; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - printf("Failed to load legacy provider\n"); - break; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + printf("Failed to load legacy provider\n"); + break; + } } #endif From dbed21b51504b0a0c9f7f617d79f98033e0789e8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:10:11 +0100 Subject: [PATCH 2209/4321] p11test: Simplify check for legacy provider in p11test_case_readonly --- src/tests/p11test/p11test_case_readonly.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index bcb408d20c..06d192a51f 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -302,11 +302,11 @@ int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_ULONG sign_length = 0; char *name; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); - return 0; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); + return 0; + } } #endif rv = fp->C_SignInit(info->session_handle, &sign_mechanism, @@ -437,11 +437,11 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, break; case CKM_RIPEMD160_RSA_PKCS: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); - return 0; + if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); + return 0; + } } #endif md = EVP_ripemd160(); From f8c1353004df1af1e51c76f2b173ec3cc2c3fd7a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:26:24 +0100 Subject: [PATCH 2210/4321] p11test: Remove unnecessary NULL check in p11test_case_common --- src/tests/p11test/p11test_case_common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index ce3b3bedfe..07fccb0b8b 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -960,9 +960,7 @@ void clean_all_objects(test_certs_t *objects) { free(objects->data[i].label); free(objects->data[i].value); X509_free(objects->data[i].x509); - if (objects->data[i].key != NULL) { - EVP_PKEY_free(objects->data[i].key); - } + EVP_PKEY_free(objects->data[i].key); } free(objects->data); } From ea6ed8edf9a501204009afa8e69d25b9eb59421d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:27:12 +0100 Subject: [PATCH 2211/4321] p11test: Add missing newline --- src/tests/p11test/p11test_case_common.h | 2 +- src/tests/p11test/p11test_case_pss_oaep.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 7d05a9676b..45ba3deb9e 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -133,4 +133,4 @@ int is_pss_mechanism(CK_MECHANISM_TYPE mech); void write_data_row(token_info_t *info, int cols, ...); -#endif /* P11TEST_CASE_COMMON_H */ \ No newline at end of file +#endif /* P11TEST_CASE_COMMON_H */ diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index b88f821879..78277e15e0 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -881,4 +881,4 @@ void pss_oaep_test(void **state) { clean_all_objects(&objects); P11TEST_PASS(info); -} \ No newline at end of file +} From 6b549ce00eae9d4ef4ae2c5e3080e6ccfd19f8dd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:35:01 +0100 Subject: [PATCH 2212/4321] p11test: Fix indentation in p11test_case_ec_derive --- src/tests/p11test/p11test_case_ec_derive.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index ec8aecf277..9f13b3e9d6 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -253,7 +253,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) } #endif -/* Generate the peer private key */ + /* Generate the peer private key */ if ((pctx = EVP_PKEY_CTX_new(o->key, NULL)) == NULL) { debug_print(" [ KEY %s ] EVP_PKEY_CTX_new_id failed", o->id_str); return 1; @@ -272,7 +272,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) } EVP_PKEY_CTX_free(pctx); -/* Start with key derivation in OpenSSL*/ + /* Start with key derivation in OpenSSL*/ pctx = EVP_PKEY_CTX_new(evp_pkey, NULL); if (pctx == NULL || EVP_PKEY_derive_init(pctx) != 1 || From 9d0597a37e39aaaedd674bf2cbefe5fc43489fb4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 26 Nov 2021 14:40:19 +0100 Subject: [PATCH 2213/4321] p11test: Turn verify_support on 1 by default --- src/tests/p11test/p11test_case_readonly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 06d192a51f..1562c14577 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -561,7 +561,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; - static int verify_support = 0; + static int verify_support = 1; char *name; if (!verify_support) From de176f55960f61fabb121d4b4152bf2c0219d235 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 3 Dec 2021 13:43:31 +0100 Subject: [PATCH 2214/4321] Fix macros for compatibility with 1.1.0 --- src/libopensc/sc-ossl-compat.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index aaabdcd288..b6acaaf4de 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -48,14 +48,26 @@ extern "C" { * But for compatibility with LibreSSL and older OpenSSL. OpenSC uses the older functions */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) -# if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L +# if !(defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT >= 0x10100000L) +# ifndef ERR_load_crypto_strings #define ERR_load_crypto_strings(x) while (0) continue +# endif +# ifndef SSL_load_error_strings #define SSL_load_error_strings(x) while (0) continue +# endif +# ifndef ERR_free_strings #define ERR_free_strings(x) while (0) continue +# endif +# ifndef ENGINE_load_dynamic #define ENGINE_load_dynamic(x) while (0) continue +# endif +# ifndef EVP_CIPHER_CTX_cleanup #define EVP_CIPHER_CTX_cleanup(x) EVP_CIPHER_CTX_reset(x) +# endif +# ifndef EVP_CIPHER_CTX_init #define EVP_CIPHER_CTX_init(x) EVP_CIPHER_CTX_reset(x) # endif +# endif #endif From f3f44624733e7013006839b7f762bb65588df2bf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 3 Dec 2021 15:08:27 +0100 Subject: [PATCH 2215/4321] Add deprecated macros EVP_PK_* --- src/libopensc/sc-ossl-compat.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index b6acaaf4de..2e0620cc0b 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -112,6 +112,20 @@ extern "C" { #define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates #define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates #define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") + +/* As defined in openssl/include/openssl/evp.h */ +# ifndef EVP_PK_RSA +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 +# endif #endif #if OPENSSL_VERSION_NUMBER < 0x30000000L From 0348814237e737eaeee8ed9e1a80d58635b1e5fd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 3 Dec 2021 17:28:22 +0100 Subject: [PATCH 2216/4321] Check whether FIPS_mode macro exists --- src/libopensc/sc-ossl-compat.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 2e0620cc0b..3c58568d32 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -108,10 +108,13 @@ extern "C" { #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include #define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates #define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates + +# ifndef FIPS_mode +#include #define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") +# endif /* As defined in openssl/include/openssl/evp.h */ # ifndef EVP_PK_RSA From 686c0447140340f5b6e9d68669deda07bfa00f94 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 3 Dec 2021 19:35:08 +0100 Subject: [PATCH 2217/4321] Rewrite deprecated DES_* typedefs --- src/libopensc/sm.h | 4 ++ src/sm/sm-common.c | 90 ++++++++++++++++++------------------ src/sm/sm-common.h | 8 ++-- src/smm/sm-cwa14890.c | 12 ++--- src/smm/sm-global-platform.c | 10 ++-- src/smm/sm-module.h | 4 +- src/tools/cardos-tool.c | 2 +- 7 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index d2d00e3747..fb5637e3cc 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -88,6 +88,10 @@ extern "C" { #define SM_GP_SECURITY_MAC 0x01 #define SM_GP_SECURITY_ENC 0x03 +/* As in OpenSSL include/openssl/des.h */ +typedef unsigned char sm_des_cblock[8]; +typedef /* const */ unsigned char sm_const_des_cblock[8]; + /* Global Platform (SCP01) data types */ /* * @struct sm_type_params_gp diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index f9d6998567..733e9d7601 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -54,30 +54,30 @@ /* * From crypto/des/des_locl.h of OpenSSL . */ -#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ - l|=((DES_LONG)(*((c)++)))<< 8L, \ - l|=((DES_LONG)(*((c)++)))<<16L, \ - l|=((DES_LONG)(*((c)++)))<<24L) +#define c2l(c,l) (l =((unsigned int)(*((c)++))) , \ + l|=((unsigned int)(*((c)++)))<< 8L, \ + l|=((unsigned int)(*((c)++)))<<16L, \ + l|=((unsigned int)(*((c)++)))<<24L) #define c2ln(c,l1,l2,n) { \ c+=n; \ l1=l2=0; \ switch (n) { \ - case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + case 8: l2 =((unsigned int)(*(--(c))))<<24L; \ /* fall through */ \ - case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + case 7: l2|=((unsigned int)(*(--(c))))<<16L; \ /* fall through */ \ - case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + case 6: l2|=((unsigned int)(*(--(c))))<< 8L; \ /* fall through */ \ - case 5: l2|=((DES_LONG)(*(--(c)))); \ + case 5: l2|=((unsigned int)(*(--(c)))); \ /* fall through */ \ - case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + case 4: l1 =((unsigned int)(*(--(c))))<<24L; \ /* fall through */ \ - case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + case 3: l1|=((unsigned int)(*(--(c))))<<16L; \ /* fall through */ \ - case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + case 2: l1|=((unsigned int)(*(--(c))))<< 8L; \ /* fall through */ \ - case 1: l1|=((DES_LONG)(*(--(c)))); \ + case 1: l1|=((unsigned int)(*(--(c)))); \ } \ } @@ -91,13 +91,13 @@ * Inspired by or taken from OpenSSL crypto/des/cbc3_enc.c */ static void -DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, - DES_key_schedule *ks1, DES_key_schedule *ks2, DES_cblock *iv, +DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, sm_des_cblock *iv, int enc) { int off=((int)length-1)/8; long l8=((length+7)/8)*8; - DES_cblock icv_out; + sm_des_cblock icv_out; memset(&icv_out, 0, sizeof(icv_out)); if (enc == DES_ENCRYPT) { @@ -107,12 +107,12 @@ DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, (unsigned char*)output,l8,ks2,iv,!enc); DES_cbc_encrypt((unsigned char*)output, (unsigned char*)output,l8,ks1,iv,enc); - if ((unsigned)length >= sizeof(DES_cblock)) - memcpy(icv_out,output[off],sizeof(DES_cblock)); + if ((unsigned)length >= sizeof(sm_des_cblock)) + memcpy(icv_out,output[off],sizeof(sm_des_cblock)); } else { - if ((unsigned)length >= sizeof(DES_cblock)) - memcpy(icv_out,input[off],sizeof(DES_cblock)); + if ((unsigned)length >= sizeof(sm_des_cblock)) + memcpy(icv_out,input[off],sizeof(sm_des_cblock)); DES_cbc_encrypt((unsigned char*)input, (unsigned char*)output,l8,ks1,iv,enc); DES_cbc_encrypt((unsigned char*)output, @@ -120,7 +120,7 @@ DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, DES_cbc_encrypt((unsigned char*)output, (unsigned char*)output,length,ks1,iv,enc); } - memcpy(*iv,icv_out,sizeof(DES_cblock)); + memcpy(*iv,icv_out,sizeof(sm_des_cblock)); } #else #include @@ -132,18 +132,18 @@ OSSL_PROVIDER *legacy_provider = NULL; #endif -DES_LONG -DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, +unsigned int +DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, - const_DES_cblock *ivec) + sm_const_des_cblock *ivec) { register long l=length; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; #if OPENSSL_VERSION_NUMBER < 0x30000000L - register DES_LONG tout0,tout1,tin0,tin1; - DES_LONG tin[2]; - DES_cblock kk, k2; + register unsigned int tout0,tout1,tin0,tin1; + unsigned int tin[2]; + sm_des_cblock kk, k2; DES_key_schedule ks,ks2; memcpy(&kk, key, 8); @@ -165,7 +165,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt1((DES_LONG *)tin, &ks, DES_ENCRYPT); + DES_encrypt1((unsigned int *)tin, &ks, DES_ENCRYPT); tout0=tin[0]; tout1=tin[1]; } @@ -179,7 +179,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks); + DES_encrypt3((unsigned int *)tin, &ks, &ks2, &ks); tout1=tin[1]; if (out != NULL) { @@ -256,18 +256,18 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output, } -DES_LONG -DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, +unsigned int +DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, - const_DES_cblock *ivec) + sm_const_des_cblock *ivec) { register long l=length; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; #if OPENSSL_VERSION_NUMBER < 0x30000000L - register DES_LONG tout0,tout1,tin0,tin1; - DES_LONG tin[2]; - DES_cblock kk, k2; + register unsigned int tout0,tout1,tin0,tin1; + unsigned int tin[2]; + sm_des_cblock kk, k2; DES_key_schedule ks,ks2; memcpy(&kk, key, 8); @@ -290,7 +290,7 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; - DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks); + DES_encrypt3((unsigned int *)tin, &ks, &ks2, &ks); /* fix 15/10/91 eay - thanks to keithr@sco.COM */ tout0=tin[0]; tout1=tin[1]; @@ -353,7 +353,7 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, { #if OPENSSL_VERSION_NUMBER < 0x30000000L int ii; - DES_cblock kk,k2; + sm_des_cblock kk,k2; DES_key_schedule ks,ks2; #else EVP_CIPHER_CTX *cctx = NULL; @@ -380,8 +380,8 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, DES_set_key_unchecked(&k2,&ks2); for (ii=0; iisession.cwa; struct sc_apdu *apdu = &rapdu->apdu; unsigned char sbuf[0x400]; - DES_cblock cblock, icv; + sm_des_cblock cblock, icv; unsigned char *encrypted = NULL, edfb_data[0x200], mac_data[0x200]; size_t encrypted_len, edfb_len = 0, mac_len = 0, offs; int rv; diff --git a/src/smm/sm-global-platform.c b/src/smm/sm-global-platform.c index e2f8206906..334c73ee18 100644 --- a/src/smm/sm-global-platform.c +++ b/src/smm/sm-global-platform.c @@ -129,7 +129,7 @@ sm_gp_get_cryptogram(unsigned char *session_key, unsigned char *out, int out_len) { unsigned char block[24]; - DES_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + sm_des_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; if (out_len!=8) return SC_ERROR_INVALID_ARGUMENTS; @@ -147,8 +147,8 @@ sm_gp_get_cryptogram(unsigned char *session_key, int -sm_gp_get_mac(unsigned char *key, DES_cblock *icv, - unsigned char *in, int in_len, DES_cblock *out) +sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, + unsigned char *in, int in_len, sm_des_cblock *out) { int len; unsigned char *block; @@ -244,7 +244,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, struct sc_apdu *apdu = NULL; unsigned char host_cryptogram[8], raw_apdu[SC_MAX_APDU_BUFFER_SIZE]; struct sm_gp_session *gp_session = &sm_info->session.gp; - DES_cblock mac; + sm_des_cblock mac; int rv, offs = 0; LOG_FUNC_CALLED(ctx); @@ -344,7 +344,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, struct sm_gp_session *gp_session = &sm_info->session.gp; unsigned gp_level = sm_info->session.gp.params.level; unsigned gp_index = sm_info->session.gp.params.index; - DES_cblock mac; + sm_des_cblock mac; unsigned char *encrypted = NULL; size_t encrypted_len = 0; int rv; diff --git a/src/smm/sm-module.h b/src/smm/sm-module.h index 0275fc1b65..c12734a36d 100644 --- a/src/smm/sm-module.h +++ b/src/smm/sm-module.h @@ -34,8 +34,8 @@ extern "C" { #include "sm/sm-common.h" /* Global Platform definitions */ -int sm_gp_get_mac(unsigned char *key, DES_cblock *icv, unsigned char *in, int in_len, - DES_cblock *out); +int sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, unsigned char *in, int in_len, + sm_des_cblock *out); int sm_gp_get_cryptogram(unsigned char *session_key, unsigned char *left, unsigned char *right, unsigned char *out, int out_len); int sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index c1544e8e60..2a3470247c 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -401,7 +401,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char int plain_lc; /* data size in orig APDU */ unsigned int mac_input_len, enc_input_len; unsigned char *mac_input, *enc_input; - DES_cblock des_in, des_out; + unsigned char des_in[8], des_out[8]; unsigned int i,j; EVP_CIPHER_CTX *cctx = NULL; int tmplen = 0; From 0b2fed934fef17ebbf3249b37fe1eef72aade840 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 6 Dec 2021 15:32:41 +0100 Subject: [PATCH 2218/4321] cwa14890.c: Add initialization for variables --- src/libopensc/cwa14890.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 971281b4b7..6e0ddeece4 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -576,7 +576,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, goto prepare_external_auth_end; } #else - BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d = NULL; + BIGNUM *ifd_privkey_n = NULL, *ifd_privkey_e = NULL, *ifd_privkey_d = NULL; #endif /* safety check */ @@ -914,7 +914,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, goto verify_internal_done; } #else - BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d = NULL; + BIGNUM *icc_pubkey_n = NULL, *icc_pubkey_e = NULL, *icc_pubkey_d = NULL; #endif if (!card || !card->ctx) From 5c65115a066e753198ef1f477e4e297454ae41ac Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 6 Dec 2021 15:33:45 +0100 Subject: [PATCH 2219/4321] pkcs15-pubkey.c: Add initialization for variables --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 84c9fc3ff9..4d5b2d9f13 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1763,7 +1763,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa; /* Get parameters */ #if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g = NULL; + const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; DSA *src = NULL; if (!(src = EVP_PKEY_get1_DSA(pk))) return SC_ERROR_INCOMPATIBLE_KEY; From 97a5a5b16247bd507ddfef542299510733397165 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 6 Dec 2021 15:34:12 +0100 Subject: [PATCH 2220/4321] pkcs11-tool: Add initialization for variables --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8e858fd99b..ace84419e2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3609,9 +3609,9 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) RSA_get0_key(r, &r_n, &r_e, NULL); #else - BIGNUM *r_n, *r_e, *r_d; - BIGNUM *r_p, *r_q; - BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; + BIGNUM *r_n = NULL, *r_e = NULL, *r_d = NULL; + BIGNUM *r_p = NULL, *r_q = NULL; + BIGNUM *r_dmp1 = NULL, *r_dmq1 = NULL, *r_iqmp = NULL; if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) { if (private) From a923e0787ae399e6165a98ac4cac0c3740a716c4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 21 Dec 2021 14:04:20 +0100 Subject: [PATCH 2221/4321] cwa-dnie: Add initialization for variables --- src/libopensc/cwa-dnie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 6d32473f36..d31d3c322a 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -680,7 +680,7 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) { int res = SC_SUCCESS; - BIGNUM *root_ca_rsa_n, *root_ca_rsa_e = NULL; + BIGNUM *root_ca_rsa_n = NULL, *root_ca_rsa_e = NULL; dnie_channel_data_t *data; #if OPENSSL_VERSION_NUMBER < 0x30000000L RSA *root_ca_rsa = NULL; From b866006ca854cb1e171d0af93aeec46e8fb184ac Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 6 Dec 2021 16:28:39 +0100 Subject: [PATCH 2222/4321] Fix loading of legacy provider to retain fallbacks Make provider variables static to avoid multiple definitions --- src/libopensc/cwa14890.c | 6 +++--- src/sm/sm-common.c | 9 ++++++--- src/tests/p11test/p11test_case_readonly.c | 4 ++-- src/tools/cardos-tool.c | 4 ++-- src/tools/pkcs11-tool.c | 18 +++++++++--------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 6e0ddeece4..1b9785804e 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -50,7 +50,7 @@ #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L - OSSL_PROVIDER *legacy_provider = NULL; + static OSSL_PROVIDER *legacy_provider = NULL; #endif #define MAX_RESP_BUFFER_SIZE 2048 @@ -1613,7 +1613,7 @@ int cwa_encode_apdu(sc_card_t * card, #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { msg = "Failed to load legacy provider"; goto encode_end; } @@ -1849,7 +1849,7 @@ int cwa_decode_response(sc_card_t * card, #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { msg = "Failed to load legacy provider"; goto response_decode_end; } diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 733e9d7601..58d0e43181 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -128,7 +128,7 @@ DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, /* The single-DES algorithm is not available in the default provider anymore * so we need to load the legacy provider. This is not done on the application * start, but only as needed */ -OSSL_PROVIDER *legacy_provider = NULL; +static OSSL_PROVIDER *legacy_provider = NULL; #endif @@ -206,8 +206,11 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, cctx = EVP_CIPHER_CTX_new(); if (l > 8) { - if (legacy_provider == NULL) { - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (!legacy_provider) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + } } if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { EVP_CIPHER_CTX_free(cctx); diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 1562c14577..624bd6a54d 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -303,7 +303,7 @@ int sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, char *name; #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); return 0; } @@ -438,7 +438,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, case CKM_RIPEMD160_RSA_PKCS: #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { debug_print(" [SKIP %s ] Failed to load legacy provider", o->id_str); return 0; } diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 2a3470247c..4e6dd55480 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -47,7 +47,7 @@ #include "util.h" #if OPENSSL_VERSION_NUMBER >= 0x30000000L - OSSL_PROVIDER *legacy_provider = NULL; + static OSSL_PROVIDER *legacy_provider = NULL; #endif static const char *app_name = "cardos-tool"; @@ -443,7 +443,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { printf("Failed to load legacy provider, aborting\n"); free(mac_input); return 0; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ace84419e2..30e1d969bb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -73,7 +73,7 @@ #include "libopensc/sc-ossl-compat.h" #if OPENSSL_VERSION_NUMBER >= 0x30000000L -OSSL_PROVIDER *legacy_provider = NULL; + static OSSL_PROVIDER *legacy_provider = NULL; #endif #ifdef _WIN32 @@ -5870,16 +5870,16 @@ static int test_digest(CK_SESSION_HANDLE session) #else i = 0; #endif - for (; mechTypes[i] != 0xffffff; i++) { - ck_mech.mechanism = mechTypes[i]; #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"))) { + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { printf("Failed to load legacy provider\n"); - break; + return errors; } } #endif + for (; mechTypes[i] != 0xffffff; i++) { + ck_mech.mechanism = mechTypes[i]; rv = p11->C_DigestInit(session, &ck_mech); if (rv == CKR_MECHANISM_INVALID) @@ -6078,11 +6078,11 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, }; #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(OPENSSL_NO_RIPEMD) - if (!legacy_provider) - legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); if (!legacy_provider) { - printf("Failed to load legacy provider"); - return errors; + if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { + printf("Failed to load legacy provider"); + return errors; + } } #endif From c7de893a109b821d60d887924e978ed0e88dd26a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 8 Dec 2021 13:03:26 +0100 Subject: [PATCH 2223/4321] Fix macro fo FIPS_mode --- src/libopensc/sc-ossl-compat.h | 3 +-- src/pkcs11/framework-pkcs15.c | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 3c58568d32..f885f85bb9 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -112,8 +112,7 @@ extern "C" { #define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates # ifndef FIPS_mode -#include -#define FIPS_mode() OSSL_PROVIDER_available(NULL, "fips") +#define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL) # endif /* As defined in openssl/include/openssl/evp.h */ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index c01f9f7630..69b8299f7b 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -30,6 +30,9 @@ #include "common/compat_strnlen.h" #ifdef ENABLE_OPENSSL #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #else #define SHA_DIGEST_LENGTH 20 #endif From e6a2b420b9fc2f572a8124c2dc89881366a5fea8 Mon Sep 17 00:00:00 2001 From: rickyepoderi Date: Wed, 15 Dec 2021 09:27:39 +0100 Subject: [PATCH 2224/4321] card-dnie: Several fixes to make it work with both versions --- src/libopensc/cwa-dnie.c | 19 +++++++---- src/libopensc/cwa14890.c | 70 ++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index d31d3c322a..e7440bd9e3 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -735,8 +735,8 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) RSA_free(root_ca_rsa); #else if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", root_ca_rsa_n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", root_ca_rsa_e) != 1 || + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, root_ca_rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, root_ca_rsa_e) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { OSSL_PARAM_BLD_free(bld); OSSL_PARAM_free(params); @@ -761,6 +761,8 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); + BN_free(root_ca_rsa_n); + BN_free(root_ca_rsa_e); #endif LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -872,7 +874,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, u8 * public_exponent, int public_exponent_len, u8 * private_exponent, int private_exponent_len) { - BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL; + BIGNUM *ifd_rsa_n = NULL, *ifd_rsa_e = NULL, *ifd_rsa_d = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L int res = SC_ERROR_INTERNAL; @@ -922,9 +924,9 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, RSA_free(ifd_rsa); #else if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", ifd_rsa_n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", ifd_rsa_e) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "d", ifd_rsa_d) != 1 || + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, ifd_rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, ifd_rsa_e) != 1 || + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, ifd_rsa_d) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { OSSL_PARAM_BLD_free(bld); OSSL_PARAM_free(params); @@ -938,7 +940,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, OSSL_PARAM_BLD_free(bld); if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEY_PARAMETERS, params) != 1) { + EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEYPAIR, params) != 1) { EVP_PKEY_CTX_free(ctx); #endif BN_free(ifd_rsa_n); @@ -952,6 +954,9 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, #if OPENSSL_VERSION_NUMBER >= 0x30000000L OSSL_PARAM_free(params); EVP_PKEY_CTX_free(ctx); + BN_free(ifd_rsa_n); + BN_free(ifd_rsa_e); + BN_free(ifd_rsa_d); #endif LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 1b9785804e..6441c4ed6e 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -557,7 +557,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, u8 *buf1 = NULL; /* where to encrypt with icc pub key */ u8 *buf2 = NULL; /* where to encrypt with ifd pub key */ u8 *buf3 = NULL; /* where to compose message to be encrypted */ - size_t len1, len2, len3; + size_t len1 = 128, len2 = 128, len3 = 128; u8 *sha_buf = NULL; /* to compose message to be sha'd */ u8 *sha_data = NULL; /* sha signature data */ BIGNUM *bn = NULL; @@ -568,15 +568,15 @@ static int cwa_prepare_external_auth(sc_card_t * card, EVP_PKEY_CTX *pctx = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d = NULL; - RSA *rsa_ifd_privkey = EVP_PKEY_get0_RSA(ifd_privkey); + const BIGNUM *ifd_privkey_n = NULL; + const RSA *rsa_ifd_privkey = EVP_PKEY_get0_RSA(ifd_privkey); if (!rsa_ifd_privkey) { res = SC_ERROR_INTERNAL; msg = "Can not extract RSA object ifd priv"; goto prepare_external_auth_end; } #else - BIGNUM *ifd_privkey_n = NULL, *ifd_privkey_e = NULL, *ifd_privkey_d = NULL; + BIGNUM *ifd_privkey_n = NULL; #endif /* safety check */ @@ -637,15 +637,13 @@ static int cwa_prepare_external_auth(sc_card_t * card, goto prepare_external_auth_end; } #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, &ifd_privkey_e, &ifd_privkey_d); + RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, NULL, NULL); #else - if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1 || - EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_E, &ifd_privkey_e) != 1 || - EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_D, &ifd_privkey_d) != 1) { + if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1) { msg = "Prepare external auth: BN get param failed"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; - } + } #endif res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */ @@ -709,6 +707,11 @@ static int cwa_prepare_external_auth(sc_card_t * card, if (sha_data) { free(sha_data); } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (ifd_privkey_n) { + BN_clear_free(ifd_privkey_n); + } +#endif if (res != SC_SUCCESS) sc_log(ctx, "%s", msg); @@ -898,7 +901,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, u8 *buf1 = NULL; /* to decrypt with our private key */ u8 *buf2 = NULL; /* to try SIGNUM==SIG */ u8 *buf3 = NULL; /* to try SIGNUM==N.ICC-SIG */ - size_t len1, len2, len3 = 0; + size_t len1 = 128, len2 = 128, len3 = 128; BIGNUM *bn = NULL; BIGNUM *sigbn = NULL; sc_context_t *ctx = NULL; @@ -906,15 +909,15 @@ static int cwa_verify_internal_auth(sc_card_t * card, EVP_PKEY_CTX *pctx = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d = NULL; - RSA *rsa_icc_pubkey = EVP_PKEY_get0_RSA(icc_pubkey); + const BIGNUM *icc_pubkey_n = NULL; + const RSA *rsa_icc_pubkey = EVP_PKEY_get0_RSA(icc_pubkey); if (!rsa_icc_pubkey) { res = SC_ERROR_INTERNAL; msg = "Can not extract RSA object icc pub"; goto verify_internal_done; } #else - BIGNUM *icc_pubkey_n = NULL, *icc_pubkey_e = NULL, *icc_pubkey_d = NULL; + BIGNUM *icc_pubkey_n = NULL; #endif if (!card || !card->ctx) @@ -975,7 +978,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, if (!pctx || EVP_PKEY_encrypt_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || - EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1)) { + EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1) != 1) { EVP_PKEY_CTX_free(pctx); goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */ } @@ -1000,15 +1003,13 @@ static int cwa_verify_internal_auth(sc_card_t * card, goto verify_internal_done; } #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, &icc_pubkey_e, &icc_pubkey_d); + RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, NULL, NULL); #else - if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1 || - EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_E, &icc_pubkey_e) != 1 || - EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_D, &icc_pubkey_d) != 1) { + if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1) { msg = "Verify Signature: BN get param failed"; res = SC_ERROR_INTERNAL; goto verify_internal_ok; - } + } #endif res = BN_sub(sigbn, icc_pubkey_n, bn); /* eval N.ICC-SIG */ if (!res) { @@ -1058,6 +1059,10 @@ static int cwa_verify_internal_auth(sc_card_t * card, BN_free(bn); if (sigbn) BN_free(sigbn); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (icc_pubkey_n) + BN_clear_free(icc_pubkey_n); +#endif if (res != SC_SUCCESS) sc_log(ctx, "%s", msg); LOG_FUNC_RETURN(ctx, res); @@ -1561,11 +1566,13 @@ int cwa_encode_apdu(sc_card_t * card, key = sm_session->session_enc; if (EVP_EncryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { msg = "Error in encrypting APDU"; + res = SC_ERROR_INTERNAL; goto encode_end; - } + } dlen += tmplen; /* compose data TLV and add to result buffer */ @@ -1615,6 +1622,7 @@ int cwa_encode_apdu(sc_card_t * card, if (!legacy_provider) { if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { msg = "Failed to load legacy provider"; + res = SC_ERROR_INTERNAL; goto encode_end; } } @@ -1623,6 +1631,7 @@ int cwa_encode_apdu(sc_card_t * card, if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto encode_end; } @@ -1630,22 +1639,26 @@ int cwa_encode_apdu(sc_card_t * card, /* compute DES */ if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf , 8) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto encode_end; } /* XOR with next data and repeat */ for (j = 0; j < 8; j++) macbuf[j] ^= ccbuf[i + j]; } - if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, NULL) != 1) { + if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto encode_end; } /* and apply 3DES to result */ if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in 3DEC ECB encryption"; + res = SC_ERROR_INTERNAL; goto encode_end; } @@ -1851,6 +1864,7 @@ int cwa_decode_response(sc_card_t * card, if (!legacy_provider) { if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { msg = "Failed to load legacy provider"; + res = SC_ERROR_INTERNAL; goto response_decode_end; } } @@ -1859,6 +1873,7 @@ int cwa_decode_response(sc_card_t * card, if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto response_decode_end; } @@ -1867,6 +1882,7 @@ int cwa_decode_response(sc_card_t * card, /* compute DES */ if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto response_decode_end; } /* XOR with data and repeat */ @@ -1875,14 +1891,17 @@ int cwa_decode_response(sc_card_t * card, } if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; goto response_decode_end; } /* finally apply 3DES to result */ if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in 3DEC ECB encryption"; + res = SC_ERROR_INTERNAL; goto response_decode_end; } @@ -1934,8 +1953,10 @@ int cwa_decode_response(sc_card_t * card, /* decrypt into response buffer * by using 3DES CBC by mean of kenc and iv={0,...0} */ if (EVP_DecryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || - EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], e_tlv->len - 1) || - EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen)) { + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], e_tlv->len - 1) != 1 || + EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) { + res = SC_ERROR_INTERNAL; msg = "Can not decrypt 3DES CBC"; goto response_decode_end; } @@ -1945,8 +1966,7 @@ int cwa_decode_response(sc_card_t * card, for (; (apdu->resplen > 0) && *(apdu->resp + apdu->resplen - 1) == 0x00; apdu->resplen--) ; /* empty loop */ if (*(apdu->resp + apdu->resplen - 1) != 0x80) { /* check padding byte */ - msg = - "Decrypted TLV has no 0x80 iso padding indicator!"; + msg = "Decrypted TLV has no 0x80 iso padding indicator!"; res = SC_ERROR_INVALID_DATA; goto response_decode_end; } From e07b5fc1f43efaa146438d0d9ed395ce176f9411 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 22 Dec 2021 11:11:51 +0100 Subject: [PATCH 2225/4321] cwa-dnie.c: Fix indentation --- src/libopensc/cwa-dnie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index e7440bd9e3..81092c6b9c 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -941,7 +941,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, if (EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEYPAIR, params) != 1) { - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(ctx); #endif BN_free(ifd_rsa_n); BN_free(ifd_rsa_e); From 7d3b6f6941874bc39159eb03c68662751d8c7090 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 22 Dec 2021 15:00:24 +0100 Subject: [PATCH 2226/4321] p11test: Initialize value --- src/tests/p11test/p11test_case_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 07fccb0b8b..e432f8f4ed 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -86,6 +86,7 @@ add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) o->key_type = -1; o->x509 = NULL; /* The "reuse" capability of d2i_X509() is strongly discouraged */ o->key = NULL; + o->value = NULL; /* Store the passed CKA_ID and CKA_LABEL */ o->key_id = malloc(key_id.ulValueLen); From cfdba6dce4bf2fb093afad1f1943da8a50261ae7 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 22 Dec 2021 15:12:52 +0100 Subject: [PATCH 2227/4321] Remove p15card-helper pkcs15-helper.h is not included in other source files. It is mentioned in 9946e23, that it is no longer used. --- src/libopensc/Makefile.am | 6 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/p15card-helper.c | 358 --------------------------------- src/libopensc/p15card-helper.h | 137 ------------- 4 files changed, 4 insertions(+), 499 deletions(-) delete mode 100644 src/libopensc/p15card-helper.c delete mode 100644 src/libopensc/p15card-helper.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 0f138a4776..cd5bafb468 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -6,7 +6,7 @@ EXTRA_DIST = Makefile.mak opensc.dll.manifest lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ - internal-winscard.h p15card-helper.h pkcs15-syn.h pkcs15-emulator-filter.h \ + internal-winscard.h pkcs15-syn.h pkcs15-emulator-filter.h \ opensc.h pkcs15.h gp.h \ cardctl.h asn1.h log.h simpletlv.h \ errors.h types.h compression.h itacns.h iso7816.h \ @@ -59,7 +59,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - compression.c p15card-helper.c sm.c \ + compression.c sm.c \ aux-data.c if ENABLE_CRYPTOTOKENKIT @@ -142,7 +142,7 @@ TIDY_FILES = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - compression.c p15card-helper.c sm.c \ + compression.c sm.c \ aux-data.c \ #$(SOURCES) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index df27c032a3..cafd2c28e7 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -37,7 +37,7 @@ OBJECTS = \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ - compression.obj p15card-helper.obj sm.obj \ + compression.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c deleted file mode 100644 index bf0ff90119..0000000000 --- a/src/libopensc/p15card-helper.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * p15card-helper.c: Utility library to assist in PKCS#15 emulation on Non-filesystem cards - * - * Copyright (C) 2006, Identity Alliance, Thomas Harning - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef ENABLE_OPENSSL /* empty file without openssl */ -#include -#include -#include -#include -#include -#include - -#include "internal.h" -#include "p15card-helper.h" -#include "opensc.h" -#include "types.h" -#include "log.h" -#include "pkcs15.h" - -int sc_pkcs15emu_initialize_objects(sc_pkcs15_card_t *p15card, p15data_items *items) { - sc_card_t* card = p15card->card; - const objdata* objects = items->objects; - int i, r; - if(!objects) return SC_SUCCESS; - for (i = 0; objects[i].label; i++) { - struct sc_pkcs15_data_info obj_info; - struct sc_pkcs15_object obj_obj; - - memset(&obj_info, 0, sizeof(obj_info)); - memset(&obj_obj, 0, sizeof(obj_obj)); - sc_pkcs15_format_id(objects[i].id, &obj_info.id); - sc_format_path(objects[i].path, &obj_info.path); - strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - r = sc_format_oid(&obj_info.app_oid, objects[i].aoid); - if (r != SC_SUCCESS) - return r; - - strncpy(obj_obj.label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - obj_obj.flags = objects[i].obj_flags; - - r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, - &obj_obj, &obj_info); - if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); - } - return SC_SUCCESS; -} - -static const prdata* get_prkey_by_cert(p15data_items* items, const cdata* cert) { - const prdata* keys; - if(!items->private_keys) - return NULL; - for(keys = items->private_keys; keys->id; keys++) { - if(0 == strcmp(cert->id, keys->id)) - return keys; - } - return NULL; -} - -static int add_private_key(sc_pkcs15_card_t *p15card, const prdata* key, int usage, int modulus_length) { - struct sc_pkcs15_prkey_info prkey_info; - struct sc_pkcs15_object prkey_obj; - - memset(&prkey_info, 0, sizeof(prkey_info)); - memset(&prkey_obj, 0, sizeof(prkey_obj)); - - sc_pkcs15_format_id(key->id, &prkey_info.id); - - prkey_info.native = 1; - prkey_info.key_reference = key->ref; - - if(!modulus_length) modulus_length = key->modulus_len; - prkey_info.modulus_length= modulus_length; - - sc_format_path(key->path, &prkey_info.path); - - strncpy(prkey_obj.label, key->label, SC_PKCS15_MAX_LABEL_SIZE - 1); - - prkey_obj.flags = key->obj_flags; - - /* Setup key usage */ - if(!usage) usage = key->usage; - prkey_info.usage = usage; - - if (key->auth_id) - sc_pkcs15_format_id(key->auth_id, &prkey_obj.auth_id); - - return sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); -} - -static int add_public_key(sc_pkcs15_card_t *p15card, const pubdata *key, int usage, int modulus_length) { - struct sc_pkcs15_pubkey_info pubkey_info; - struct sc_pkcs15_object pubkey_obj; - - memset(&pubkey_info, 0, sizeof(pubkey_info)); - memset(&pubkey_obj, 0, sizeof(pubkey_obj)); - - sc_pkcs15_format_id(key->id, &pubkey_info.id); - if(!usage) usage = key->usage; - pubkey_info.usage = usage; - pubkey_info.native = 1; - pubkey_info.key_reference = key->ref; - if(!modulus_length) modulus_length = key->modulus_len; - pubkey_info.modulus_length= modulus_length; - /* we really don't know how many bits or module length, - * we will assume 1024 for now - */ - sc_format_path(key->path, &pubkey_info.path); - - strncpy(pubkey_obj.label, key->label, SC_PKCS15_MAX_LABEL_SIZE - 1); - - pubkey_obj.flags = key->obj_flags; - - if (key->auth_id) - sc_pkcs15_format_id(key->auth_id, &pubkey_obj.auth_id); - - return sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); -} - -/* int default_cert_handle(sc_pkcs15_card_t *p15card, p15data_items* items, cdata* cert, u8* data, size_t length) { */ -CERT_HANDLE_FUNCTION(default_cert_handle) { - /* Certificate data exists, parse it */ - int r; - X509 *cert_data = NULL; - EVP_PKEY *pkey = NULL; - const RSA * rsa = NULL; - int certtype = 0; - int modulus_len = 0; - const prdata* key = get_prkey_by_cert(items, cert); - if(!key) { - sc_log(p15card->card->ctx, "Error: No key for this certificate"); - return SC_ERROR_INTERNAL; - } - - if(!d2i_X509(&cert_data, (const u8**)&data, length)) { - sc_log(p15card->card->ctx, "Error converting certificate"); - return SC_ERROR_INTERNAL; - } - - pkey = X509_get_pubkey(cert_data); - - if(pkey == NULL) { - sc_log(p15card->card->ctx, "Error: no public key associated with the certificate"); - r = SC_ERROR_INTERNAL; - goto err; - } - - certtype = X509_certificate_type(cert_data, pkey); - if(! (EVP_PK_RSA & certtype)) { - sc_log(p15card->card->ctx, "Error: certificate is not for an RSA key"); - r = SC_ERROR_INTERNAL; - goto err; - } - rsa = EVP_PKEY_get0_RSA(pkey); - if( rsa == NULL) { - sc_log(p15card->card->ctx, "Error: no modulus associated with the certificate"); - r = SC_ERROR_INTERNAL; - goto err; - } - - modulus_len = RSA_bits(rsa); - - /* printf("Key Size: %d bits\n\n", modulus_len); */ - /* cached_cert->modulusLength = modulus_len; */ - - if(key->label) { - int usage = 0; - if (certtype & EVP_PKT_SIGN) { - usage |= SC_PKCS15_PRKEY_USAGE_SIGN; - usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - } - - if (certtype & EVP_PKT_ENC) { - usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT; - usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT; - } - if (certtype & EVP_PKT_EXCH) { - usage |= SC_PKCS15_PRKEY_USAGE_WRAP; - usage |= SC_PKCS15_PRKEY_USAGE_UNWRAP; - } - r = add_private_key(p15card, key, usage, modulus_len); - if (r < 0) - goto err; - } - r = SC_SUCCESS; -err: - if(pkey) { - EVP_PKEY_free(pkey); - pkey = NULL; - } - if(cert_data) { - X509_free(cert_data); - cert_data = NULL; - } - LOG_FUNC_RETURN(p15card->card->ctx, r); -} - -int sc_pkcs15emu_initialize_certificates(sc_pkcs15_card_t *p15card, p15data_items* items) { - /* set certs */ - sc_card_t* card = p15card->card; - const cdata* certs = items->certs; - int onFailResume = items->cert_continue; - int i, r; - if(!certs) return SC_SUCCESS; - for (i = 0; certs[i].label; i++) { - struct sc_pkcs15_cert_info cert_info; - struct sc_pkcs15_object cert_obj; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); - - sc_pkcs15_format_id(certs[i].id, &cert_info.id); - cert_info.authority = certs[i].authority; - sc_format_path(certs[i].path, &cert_info.path); - - strncpy(cert_obj.label, certs[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - cert_obj.flags = certs[i].obj_flags; - - if(items->cert_load) { - u8* cert_buffer = NULL; - size_t cert_length = 0; - int should_free = 0; - if(SC_SUCCESS != sc_select_file(card, &cert_info.path, NULL)) { - if(onFailResume) - continue; - else - break; - } - if(SC_SUCCESS != (r = items->cert_load(card, &cert_buffer, &cert_length, &should_free))) { - if(onFailResume) - continue; - else - break; - } - /* Handle cert */ - /* If no cert handler, add.. if cert handler succeeds.. add */ - if(!items->cert_handle || SC_SUCCESS == (r = items->cert_handle(p15card, items, &certs[i], cert_buffer, cert_length))) { - r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - } - if(should_free) - free(cert_buffer); - if(SC_SUCCESS != r) { - if(onFailResume) - continue; - else - break; - } - } else { /* Automatically add */ - if(SC_SUCCESS != sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info)) { - if(onFailResume) - continue; - else - break; - } - } - } - return SC_SUCCESS; -} - -int sc_pkcs15emu_initialize_pins(sc_pkcs15_card_t *p15card, p15data_items* items) { - /* set pins */ - int i,r; - const pindata* pins = items->pins; - if(!pins) return SC_SUCCESS; - for (i = 0; pins[i].label; i++) { - struct sc_pkcs15_auth_info pin_info; - struct sc_pkcs15_object pin_obj; - - memset(&pin_info, 0, sizeof(pin_info)); - memset(&pin_obj, 0, sizeof(pin_obj)); - - pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; - sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id); - - pin_info.attrs.pin.reference = pins[i].ref; - pin_info.attrs.pin.flags = pins[i].flags; - pin_info.attrs.pin.type = pins[i].type; - pin_info.attrs.pin.min_length = pins[i].minlen; - pin_info.attrs.pin.stored_length = pins[i].storedlen; - pin_info.attrs.pin.max_length = pins[i].maxlen; - pin_info.attrs.pin.pad_char = pins[i].pad_char; - - sc_format_path(pins[i].path, &pin_info.path); - pin_info.tries_left = -1; - - strncpy(pin_obj.label, pins[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - pin_obj.flags = pins[i].obj_flags; - - if(0 > (r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info))) - LOG_FUNC_RETURN(p15card->card->ctx, r); - } - return SC_SUCCESS; -} - -int sc_pkcs15emu_initialize_private_keys(sc_pkcs15_card_t *p15card, p15data_items* items) { - const prdata *prkeys = items->private_keys; - int i, r; - if(!prkeys) return SC_SUCCESS; - /* set private keys */ - for (i = 0; prkeys[i].label; i++) { - r = add_private_key(p15card, &prkeys[i], 0, 0); - if (r < 0) - LOG_FUNC_RETURN(p15card->card->ctx, r); - } - return SC_SUCCESS; -} - -int sc_pkcs15emu_initialize_public_keys(sc_pkcs15_card_t *p15card, p15data_items *items) { - const pubdata *keys = items->public_keys; - int i, r; - if(!keys) return SC_SUCCESS; - /* set public keys */ - for (i = 0; keys[i].label; i++) { - r = add_public_key(p15card, &keys[i], 0, 0); - if (r < 0) - LOG_FUNC_RETURN(p15card->card->ctx, r); - } - return SC_SUCCESS; - -} - -int sc_pkcs15emu_initialize_all(sc_pkcs15_card_t *p15card, p15data_items* items) { - int r; - if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_objects(p15card, items))) - return r; - if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_certificates(p15card, items))) - return r; - if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_pins(p15card, items))) - return r; - - if(items->forced_private && (SC_SUCCESS != (r = sc_pkcs15emu_initialize_private_keys(p15card, items)))) - return r; - if(items->forced_public && (SC_SUCCESS != (r = sc_pkcs15emu_initialize_public_keys(p15card, items)))) - return r; - return SC_SUCCESS; -} - -#endif /* ENABLE_OPENSSL */ diff --git a/src/libopensc/p15card-helper.h b/src/libopensc/p15card-helper.h deleted file mode 100644 index ce3ea7291c..0000000000 --- a/src/libopensc/p15card-helper.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * p15card-helper.h: Utility library to assist in PKCS#15 emulation on Non-filesystem cards - * - * Copyright (C) 2006, Identity Alliance, Thomas Harning - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef P15CARD_HELPER_H -#define P15CARD_HELPER_H - -#include "libopensc/pkcs15.h" - - -#define USAGE_NONREP SC_PKCS15_PRKEY_USAGE_NONREPUDIATION | \ - SC_PKCS15_PRKEY_USAGE_SIGN -#define USAGE_DS SC_PKCS15_PRKEY_USAGE_SIGN -#define USAGE_CRYPTO SC_PKCS15_PRKEY_USAGE_ENCRYPT | \ - SC_PKCS15_PRKEY_USAGE_DECRYPT | \ - SC_PKCS15_PRKEY_USAGE_WRAP | \ - SC_PKCS15_PRKEY_USAGE_UNWRAP -#define USAGE_KE SC_PKCS15_PRKEY_USAGE_ENCRYPT | \ - SC_PKCS15_PRKEY_USAGE_DECRYPT | \ - SC_PKCS15_PRKEY_USAGE_WRAP | \ - SC_PKCS15_PRKEY_USAGE_UNWRAP -#define USAGE_AUT SC_PKCS15_PRKEY_USAGE_ENCRYPT | \ - SC_PKCS15_PRKEY_USAGE_DECRYPT | \ - SC_PKCS15_PRKEY_USAGE_WRAP | \ - SC_PKCS15_PRKEY_USAGE_UNWRAP | \ - SC_PKCS15_PRKEY_USAGE_SIGN - - -typedef struct objdata_st { - const char *id; - const char *label; - const char *aoid; - int authority; - const char *path; - int obj_flags; -} objdata; - -typedef struct cdata_st { - const char *id; - const char *label; - int authority; - const char *path; - int obj_flags; -} cdata; - -typedef struct pdata_st { - const char *id; - const char *label; - const char *path; - int ref; - int type; - unsigned int maxlen; - unsigned int minlen; - unsigned int storedlen; - int flags; - int tries_left; - const char pad_char; - int obj_flags; -} pindata; - -typedef struct pubdata_st { - const char *id; - const char *label; - unsigned int modulus_len; - int usage; - const char *path; - int ref; - const char *auth_id; - int obj_flags; -} pubdata; - -typedef struct prdata_st { - const char *id; - const char *label; - unsigned int modulus_len; - int usage; - const char *path; - int ref; - const char *auth_id; - int obj_flags; -} prdata; - -typedef struct keyinfo_st { - int fileid; - sc_pkcs15_id_t id; - unsigned int modulus_len; - u8 modulus[1024/8]; -} keyinfo; - -typedef struct p15data_items p15data_items; - -typedef int (*cert_load_function)(sc_card_t *card, u8** data, size_t* length, int* shouldFree); -#define CERT_LOAD_FUNCTION(x) int x(sc_card_t *card, u8** data, size_t*length, int *shouldFree) -typedef int (*cert_handle_function)(sc_pkcs15_card_t *p15card, p15data_items* items, const cdata* cert, u8* data, size_t length); -#define CERT_HANDLE_FUNCTION(x) int x(sc_pkcs15_card_t *p15card, p15data_items* items, const cdata* cert, u8* data, size_t length) - -struct p15data_items { - const objdata* objects; - const cdata* certs; - const pindata* pins; - const pubdata* public_keys; - const prdata* private_keys; - - cert_load_function cert_load; - cert_handle_function cert_handle; - int cert_continue; /* Continue after cert failure */ - int forced_private; /* Should add all private keys w/o cert-management */ - int forced_public; /* Should add public keys (generally not needed..) */ -}; - -CERT_HANDLE_FUNCTION(default_cert_handle); - -int sc_pkcs15emu_initialize_objects(sc_pkcs15_card_t *p15card, p15data_items* items); -int sc_pkcs15emu_initialize_certificates(sc_pkcs15_card_t *p15card, p15data_items* items); -int sc_pkcs15emu_initialize_pins(sc_pkcs15_card_t *p15card, p15data_items *items); -int sc_pkcs15emu_initialize_private_keys(sc_pkcs15_card_t *p15card, p15data_items *items); -int sc_pkcs15emu_initialize_public_keys(sc_pkcs15_card_t *p15card, p15data_items *items); -int sc_pkcs15emu_initialize_all(sc_pkcs15_card_t *p15card, p15data_items *items); - -#endif - From 78c66a54ab5f7161afcf772b8584181e2639fe65 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 16 Jan 2022 21:19:22 +0100 Subject: [PATCH 2228/4321] Update the minimal version of OpenSSL to 1.1.1 No older version is longer supported by the OpenSSL team. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d113cb43ec..d137e47ed9 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(version.m4.ci) -m4_define([openssl_minimum_version], [1.0.1]) +m4_define([openssl_minimum_version], [1.1.1]) AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) AC_CONFIG_AUX_DIR([.]) From 3c4f7808a2ddab44894be1cce8794d4d8b78be7d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 18 Jan 2022 09:52:54 +0100 Subject: [PATCH 2229/4321] CI: add Coverity Scan action The GitHub action is unofficial, but very simple https://github.com/vapier/coverity-scan-action --- .github/workflows/coverity.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/coverity.yml diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 0000000000..f56805a447 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,22 @@ +name: Coverity CI + +# We only want to test master or explicitly via coverity branch +on: + push: + branches: [master, coverity] + + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh + - run: ./bootstrap + - run: ./configure --disable-dependency-tracking + - uses: vapier/coverity-scan-action@v0 + with: + project: OpenSC%2FOpenSC + token: ${{ secrets.COVERITY_SCAN_TOKEN }} + email: 'viktor.tarasov@gmail.com' + command: 'make' From 683c64e423ecb7f32b3a2de65b2f9a9eb541cc17 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 18 Jan 2022 13:50:43 +0100 Subject: [PATCH 2230/4321] move codespell file to .github directory --- .../codespell_ignore_words.txt | 0 .github/workflows/codespell.yml | 2 +- CONTRIBUTING.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename codespell_ignore_words.txt => .github/codespell_ignore_words.txt (100%) diff --git a/codespell_ignore_words.txt b/.github/codespell_ignore_words.txt similarity index 100% rename from codespell_ignore_words.txt rename to .github/codespell_ignore_words.txt diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 32d2809942..20debc29b0 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -15,4 +15,4 @@ jobs: - uses: codespell-project/actions-codespell@master with: skip: compat_* - ignore_words_file: codespell_ignore_words.txt + ignore_words_file: .github/codespell_ignore_words.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1fc4feca5..98b8d0ad4f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ After installing [codespell](https://github.com/codespell-project/codespell#installation), you can run it from the command line as: ```sh -codespell -I codespell_ignore_words.txt +codespell -I .github/codespell_ignore_words.txt ``` # Release process From 3b35a0bdb87e4aa7454dafbfffd7617b8d5e34e1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 18 Jan 2022 13:59:09 +0100 Subject: [PATCH 2231/4321] move version.m4 to m4 directory --- bootstrap.ci | 4 ++-- configure.ac | 2 +- version.m4 => m4/version.m4 | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename version.m4 => m4/version.m4 (100%) diff --git a/bootstrap.ci b/bootstrap.ci index bab336c570..6a3a27792f 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -41,12 +41,12 @@ if [ -f Makefile ]; then make distclean fi -rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmain.sh version.m4.ci +rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmain.sh m4/version.m4.ci if [ -n "$SUFFIX" ] then echo Set package suffix "$SUFFIX" - sed 's/^define(\[PACKAGE_SUFFIX\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_SUFFIX\], \['$SUFFIX'\])/g' < version.m4 > version.m4.ci + sed 's/^define(\[PACKAGE_SUFFIX\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_SUFFIX\], \['$SUFFIX'\])/g' < m4/version.m4 > m4/version.m4.ci fi ./bootstrap diff --git a/configure.ac b/configure.ac index d137e47ed9..77cd62f14a 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ define([VS_FF_PRODUCT_NAME], [OpenSC smartcard framework]) define([VS_FF_PRODUCT_UPDATES], [https://github.com/OpenSC/OpenSC/releases]) define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) -m4_sinclude(version.m4.ci) +m4_sinclude(m4/version.m4.ci) m4_define([openssl_minimum_version], [1.1.1]) diff --git a/version.m4 b/m4/version.m4 similarity index 100% rename from version.m4 rename to m4/version.m4 From b9937d68927b5855669e67333c352746a4956823 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 18 Jan 2022 13:54:06 +0100 Subject: [PATCH 2232/4321] move appveyor.yml to .appveyor.yml --- appveyor.yml => .appveyor.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename appveyor.yml => .appveyor.yml (100%) diff --git a/appveyor.yml b/.appveyor.yml similarity index 100% rename from appveyor.yml rename to .appveyor.yml From 062cb0c83f5df74d4ad20ae72448332de48f5599 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 20 Jan 2022 16:57:12 +0100 Subject: [PATCH 2233/4321] unittests: added missing openssl flags --- src/tests/unittests/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index f17a6c31a8..5fe6db5c61 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -13,6 +13,7 @@ noinst_HEADERS = torture.h AM_CFLAGS = -I$(top_srcdir)/src/ \ $(CODE_COVERAGE_CFLAGS) \ + $(OPTIONAL_OPENSSL_CFLAGS) \ $(CMOCKA_CFLAGS) AM_CPPFLAGS =$(CODE_COVERAGE_CPPFLAGS) LDADD = $(top_builddir)/src/libopensc/libopensc.la \ From 302ad70471efa279b033d4d5511d979ec5d965fe Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 20 Jan 2022 17:01:46 +0100 Subject: [PATCH 2234/4321] added compatibility with LibreSSL --- src/libopensc/sc-ossl-compat.h | 7 +++++++ src/tests/p11test/p11test_case_common.c | 14 ++++++++++++++ src/tests/p11test/p11test_case_ec_derive.c | 4 ++++ src/tests/p11test/p11test_case_readonly.c | 9 +++++++-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index f885f85bb9..ec694ad48d 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -105,6 +105,13 @@ extern "C" { /* workaround unused value warning for a macro that does nothing */ #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L #define OPENSSL_malloc_init() +#define FIPS_mode() (0) +#define EVP_sha3_224() (NULL) +#define EVP_sha3_256() (NULL) +#define EVP_sha3_384() (NULL) +#define EVP_sha3_512() (NULL) +#define EVP_PKEY_new_raw_public_key(t, e, p, l) (NULL) +#define EVP_PKEY_get_raw_public_key(p, pu, l) (0) #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index e432f8f4ed..f091dbcc10 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -164,6 +164,7 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } +#ifdef EVP_PKEY_ED25519 } else if (o->type == EVP_PKEY_ED25519) { if (token.num_ed_mechs > 0 ) { o->num_mechs = token.num_ed_mechs; @@ -184,6 +185,8 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } +#endif +#ifdef EVP_PKEY_X25519 } else if (o->type == EVP_PKEY_X25519) { if (token.num_montgomery_mechs > 0 ) { o->num_mechs = token.num_montgomery_mechs; @@ -204,6 +207,7 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_DERIVE; } +#endif /* Nothing in the above enum can be used for secret keys */ } else if (o->key_type == CKK_AES) { if (token.num_aes_mechs > 0 ) { @@ -601,6 +605,7 @@ int callback_public_keys(test_certs_t *objects, a = template[6].pValue; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)template[6].ulValueLen) != NULL) { switch (o->key_type) { +#ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: if (strcmp((char *)curve->data, "edwards25519")) { debug_print(" [WARN %s ] Unknown curve name. " @@ -608,6 +613,8 @@ int callback_public_keys(test_certs_t *objects, } evp_type = EVP_PKEY_ED25519; break; +#endif +#ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: if (strcmp((char *)curve->data, "curve25519")) { debug_print(" [WARN %s ] Unknown curve name. " @@ -615,16 +622,20 @@ int callback_public_keys(test_certs_t *objects, } evp_type = EVP_PKEY_X25519; break; +#endif default: debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type); return -1; } ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)template[6].ulValueLen) != NULL) { +#if defined(EVP_PKEY_ED25519) || defined (EVP_PKEY_X25519) int nid = OBJ_obj2nid(obj); +#endif ASN1_OBJECT_free(obj); switch (o->key_type) { +#ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: if (nid != NID_ED25519) { debug_print(" [WARN %s ] Unknown OID. " @@ -632,6 +643,8 @@ int callback_public_keys(test_certs_t *objects, } evp_type = EVP_PKEY_ED25519; break; +#endif +#ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: if (nid != NID_X25519) { debug_print(" [WARN %s ] Unknown OID. " @@ -639,6 +652,7 @@ int callback_public_keys(test_certs_t *objects, } evp_type = EVP_PKEY_X25519; break; +#endif default: debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type); return -1; diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 9f13b3e9d6..f7a5f92f9e 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -89,6 +89,7 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) { +#ifdef EVP_PKEY_X25519 unsigned char *secret = NULL, *pkcs11_secret = NULL; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; /* This is peer key */ @@ -210,6 +211,9 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) free(secret); free(pkcs11_secret); return 1; +#else + return 0; +#endif } int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 624bd6a54d..2aefdc7a70 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -522,6 +522,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, rv, ERR_error_string(ERR_peek_last_error(), NULL)); return -1; } +#ifdef EVP_PKEY_ED25519 } else if (o->type == EVP_PKEY_ED25519) { /* need to be created even though we do not do any MD */ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); @@ -547,7 +548,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, EVP_MD_CTX_free(ctx); return -1; } - +#endif } else { fprintf(stderr, " [ KEY %s ] Unknown type. Not verifying\n", o->id_str); } @@ -641,7 +642,11 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (o->type != EVP_PK_EC && o->type != EVP_PK_RSA && o->type != EVP_PKEY_ED25519) { + if (o->type != EVP_PK_EC && o->type != EVP_PK_RSA +#ifdef EVP_PKEY_ED25519 + && o->type != EVP_PKEY_ED25519 +#endif + ) { debug_print(" [SKIP %s ] Skip non-RSA and non-EC key", o->id_str); return 0; } From ba3eb17cd650b7c8f3c144da67a660c20494214b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 20 Jan 2022 17:03:45 +0100 Subject: [PATCH 2235/4321] macOS CI: setup help2man/gengetopt via brew --- .github/setup-macos.sh | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index ae71a014b7..3743d94b3b 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -2,23 +2,7 @@ set -ex -o xtrace -brew install automake - -# gengetopt -curl https://ftp.gnu.org/gnu/gengetopt/gengetopt-2.23.tar.xz -L --output gengetopt-2.23.tar.xz -tar xfj gengetopt-2.23.tar.xz -pushd gengetopt-2.23 -./configure && make -sudo make install -popd - -# help2man -curl https://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz -L --output help2man-1.47.16.tar.xz -tar xjf help2man-1.47.16.tar.xz -pushd help2man-1.47.16 -./configure && make -sudo make install -popd +brew install automake gengetopt help2man # openSCToken export PATH="/usr/local/opt/ccache/libexec:$PATH" From ba1a0d226eecb8bcbd420d6e3883bf12238cb8df Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 20 Jan 2022 17:39:50 +0100 Subject: [PATCH 2236/4321] CI: added LibreSSL build --- .github/setup-libressl.sh | 22 ++++++++++++++ .github/setup-linux.sh | 7 ++++- .github/workflows/linux.yml | 35 ++++++++++++++++++++++ tests/test-pkcs11-tool-unwrap-wrap-test.sh | 2 +- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100755 .github/setup-libressl.sh diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh new file mode 100755 index 0000000000..298d837170 --- /dev/null +++ b/.github/setup-libressl.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -ex -o xtrace + +V=libressl-3.4.2 + +sudo apt-get remove -y openssl libssl-dev java8-runtime-headless default-jre-headless + +if [ ! -d "$V" ]; then + # letsencrypt CA does not seem to be included in CI runner + wget --no-check-certificate https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$V.tar.gz + tar xzf $V.tar.gz +fi +pushd $V +./configure --prefix=/usr/local +make -j $(nproc) +sudo make install +popd + +# update dynamic linker to find the libraries in non-standard path +echo "/usr/local/lib64" | sudo tee /etc/ld.so.conf.d/openssl.conf +sudo ldconfig diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index ac10c8b766..d1f898bd96 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -6,7 +6,7 @@ set -ex -o xtrace DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git" # Add openssl or install openssl3.0 -if [ "$1" != "ossl3" -a "$2" != "ossl3" ]; then +if [ "$1" != "ossl3" -a "$2" != "ossl3" -a ]; then DEPS="$DEPS openssl" fi @@ -58,6 +58,11 @@ if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then ./.github/setup-openssl.sh fi +# install libressl if needed +if [ "$1" == "libressl" -o "$2" == "libressl" ]; then + ./.github/setup-libressl.sh +fi + if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a70ef76d87..1c621eca22 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -225,6 +225,41 @@ jobs: - run: .github/setup-linux.sh oseid ossl3 - run: .github/test-oseid.sh + ########################### + ## LibreSSL 3.0 pipeline ## + ########################### + build-libressl: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh libressl + - run: .github/build.sh dist libressl + - uses: actions/upload-artifact@v2 + if: failure() + with: + name: logs + path: | + tests/test-suite.log + config.log + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-libressl + + test-cac-libressl: + runs-on: ubuntu-latest + needs: [build-libressl] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-libressl + - run: .github/setup-linux.sh cac libressl + - run: .github/test-cac.sh + #################### ## Push artifacts ## #################### diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index d347288bc7..a785bb7aac 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -30,7 +30,7 @@ KEY="70707070707070707070707070707070" echo -n $KEY|xxd -p -r > aes_plain_key # wrap AES key -openssl rsautl -encrypt -pubin --keyform der -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key +openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key assert $? "Failed wrap AES key" # unwrap key by pkcs11 interface From c94100a33d1006d7640bfac5caa19d879cd587c4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 24 Jan 2022 15:20:39 +0100 Subject: [PATCH 2237/4321] CI: enable oseid test with libressl --- .github/workflows/linux.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1c621eca22..9803ce170f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -260,6 +260,19 @@ jobs: - run: .github/setup-linux.sh cac libressl - run: .github/test-cac.sh + test-oseid-libressl: + runs-on: ubuntu-latest + needs: [build-libressl] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }}-libressl + - run: .github/setup-linux.sh oseid libressl + - run: .github/test-oseid.sh + #################### ## Push artifacts ## #################### From bb096caedd20261fffa6f3aa6f4249a4585d4d77 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 7 Sep 2021 13:49:43 -0500 Subject: [PATCH 2238/4321] epass2003 - Create OpenSC ACLs from file FCI read from card Fix #2397 On branch epass2003-init Changes to be committed: modified: card-epass2003.c --- src/libopensc/card-epass2003.c | 89 +++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index fc39d564fa..c936969f38 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -169,6 +169,42 @@ static const struct sc_card_error epass2003_errors[] = { { 0x9000,SC_SUCCESS, NULL } }; +typedef struct sec_attr_to_acl_entries { + unsigned int file_type; /* file->type */ + unsigned int file_ef_structure; /* file->ef_structure */ + int indx; /* index in epass2003 iversion of sec_attr */ + /* use the follow for sc_file_add_entry */ + int op; /* SC_AC_OP_* */ +} sec_attr_to_acl_entries_t; + +/* Known combinations of file type and methods. More can be added as needed */ +static const sec_attr_to_acl_entries_t sec_attr_to_acl_entry[] = { + {SC_FILE_TYPE_DF, 0, 0, SC_AC_OP_LIST_FILES}, + {SC_FILE_TYPE_DF, 0, 1, SC_AC_OP_CREATE}, + {SC_FILE_TYPE_DF, 0, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 2, SC_AC_OP_WRITE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 2, SC_AC_OP_WRITE}, + {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_BSO, 0, 0, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_BSO, 0, 3, SC_AC_OP_DELETE}, +}; + static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out); int epass2003_refresh(struct sc_card *card); @@ -1806,6 +1842,51 @@ acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS); } +/* Use epass2003 sec_attr to add acl entries */ +int +sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) +{ + int i; + int found = 0; + + unsigned int method; + unsigned long keyref; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + switch (file->sec_attr[indx]) { + case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE): + method = SC_AC_NONE; + keyref = SC_AC_KEY_REF_NONE; + break; + case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER): + method = SC_AC_CHV; + keyref = 1; + break; + default: + sc_log(card->ctx,"Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[indx], indx); + method = SC_AC_NEVER; + keyref = SC_AC_KEY_REF_NONE; + + break; + } + + for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) { + const sec_attr_to_acl_entries_t *e = &sec_attr_to_acl_entry[i]; + + if (indx == e->indx && file->type == e->file_type + && file->ef_structure == e->file_ef_structure) { + /* may add multiple entries */ + sc_file_add_acl_entry(file, e->op, method, keyref); + found++; + } + } + if (found != 1) { + sc_log(card->ctx,"found %d entries ", found); + } + + return 0; +} static int epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, size_t buflen) @@ -1914,8 +1995,13 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si sc_file_set_prop_attr(file, tag, taglen); tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen); - if (tag != NULL && taglen) + if (tag != NULL && taglen) { + unsigned int i; sc_file_set_sec_attr(file, tag, taglen); + for (i = 0; i< taglen; i++) + if (tag[i] != 0xff) /* skip unused entries */ + sec_attr_to_entry(card, file, i); + } tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen); if (tag != NULL && taglen == 1) { @@ -2033,6 +2119,7 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, if (file->sec_attr_len) { memcpy(buf, file->sec_attr, file->sec_attr_len); sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p); + } else { sc_log(card->ctx, "SC_FILE_ACL"); From d85e2d612ffad059f9dfcefbdf2af875e8cc9ff8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 7 Sep 2021 14:18:40 -0500 Subject: [PATCH 2239/4321] epass2003 add acls for keys --- src/libopensc/card-epass2003.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index c936969f38..e362eddd75 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -203,6 +203,22 @@ static const sec_attr_to_acl_entries_t sec_attr_to_acl_entry[] = { {SC_FILE_TYPE_BSO, 0, 0, SC_AC_OP_UPDATE}, {SC_FILE_TYPE_BSO, 0, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 2, SC_AC_OP_CRYPTO}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT, 2, SC_AC_OP_CRYPTO}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 3, SC_AC_OP_DELETE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT, 3, SC_AC_OP_DELETE}, + + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC, 0, SC_AC_OP_READ}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC, 1, SC_AC_OP_UPDATE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 2, SC_AC_OP_CRYPTO}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC, 2, SC_AC_OP_CRYPTO}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 3, SC_AC_OP_DELETE}, + {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC, 3, SC_AC_OP_DELETE}, }; static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); From afab2e6fadc20c925c2f32a8c059316583d6a562 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 10 Sep 2021 10:34:49 -0500 Subject: [PATCH 2240/4321] pkcs15init segfault pkcs15init/pkcs15-lib.c in sc_pkcs15init_add_app had: /* FIXME: what to do if sc_pkcs15init_update_dir failed? */ This fixes the problem. Fixes: #2398 in that it will not segfault. On branch epass2003-init Changes to be committed: modified: ../pkcs15init/pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 57621aea5a..ee1a200604 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -912,9 +912,20 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, if (r >= 0) { r = sc_pkcs15init_update_tokeninfo(p15card, profile); } else { - /* FIXME: what to do if sc_pkcs15init_update_dir failed? */ - free(app->label); - free(app); /* unused */ + /* FIXED: what to do if sc_pkcs15init_update_dir failed? */ + /* sc_pkcs15init_update_dir may add app to card->app[] */ + int found = 0; + int i; + for (i = 0; i < card->app_count; i++) { + if (card->app[i] == app) { + found = 1; + break; + } + } + if (found == 0) { /* not in card->app[] free it */ + free(app->label); + free(app); /* unused */ + } } } else { From 21cfd72f1b878e3ba5feeec7914291513d519644 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 20 Jan 2022 12:28:57 +0100 Subject: [PATCH 2241/4321] Coverity Scan fix, CID 374838: Resource leaks (RESOURCE_LEAK) modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 30e1d969bb..6ae6f39637 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7778,6 +7778,7 @@ static CK_BYTE_PTR get_iv(const char *iv_input, size_t *iv_size) if (sc_hex_to_bin(iv_input, iv, &size)) { fprintf(stderr, "Warning, unable to parse IV, IV will not be used.\n"); *iv_size = 0; + free(iv); return NULL; } From ca01aa7a8edc8280a5ceadebb472c2e3c198d8c2 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 20 Jan 2022 12:26:19 +0100 Subject: [PATCH 2242/4321] Coverity Scan fix, CID 374840: Null pointer dereferences (REVERSE_INULL) modified: src/pkcs11/slot.c --- src/pkcs11/slot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index ea8a3ac2a5..86cb3b884b 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -69,13 +69,15 @@ static struct sc_pkcs11_slot * reader_reclaim_slot(sc_reader_t *reader) CK_UTF8CHAR slotDescription[64]; CK_UTF8CHAR manufacturerID[32]; + if (reader == NULL) + return NULL; strcpy_bp(slotDescription, reader->name, 64); strcpy_bp(manufacturerID, reader->vendor, 32); /* Locate a slot related to the reader */ for (i = 0; ireader == NULL && reader != NULL + if (slot->reader == NULL && 0 == memcmp(slot->slot_info.slotDescription, slotDescription, 64) && 0 == memcmp(slot->slot_info.manufacturerID, manufacturerID, 32) && slot->slot_info.hardwareVersion.major == reader->version_major From 929e51bef89488236ddbe9d2725033a102e4135e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Jan 2022 18:46:42 +0100 Subject: [PATCH 2243/4321] pkcs11: Free memory on exit during verify operation --- src/pkcs11/openssl.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 4b8a86ccaf..04339e1997 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -621,19 +621,24 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len md = EVP_sha512(); break; default: + EVP_PKEY_free(pkey); return CKR_GENERAL_ERROR; } mdbuf_len = EVP_MD_size(md); mdbuf = calloc(1, mdbuf_len); - if (mdbuf == NULL) + if (mdbuf == NULL) { + EVP_PKEY_free(pkey); return CKR_DEVICE_MEMORY; + } if ((mdctx = EVP_MD_CTX_new()) == NULL) { free(mdbuf); + EVP_PKEY_free(pkey); return CKR_GENERAL_ERROR; } if (!EVP_DigestInit(mdctx, md) || !EVP_DigestUpdate(mdctx, data, data_len) || !EVP_DigestFinal(mdctx, mdbuf, &mdbuf_len)) { + EVP_PKEY_free(pkey); EVP_MD_CTX_free(mdctx); free(mdbuf); return CKR_GENERAL_ERROR; @@ -666,8 +671,10 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned char *rsa_out = NULL, pad; size_t rsa_outlen = 0; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ctx) + if (!ctx) { + EVP_PKEY_free(pkey); return CKR_DEVICE_MEMORY; + } sc_log(context, "Trying to verify using low-level API"); switch (mech->mechanism) { @@ -730,6 +737,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len if (mech->pParameter == NULL) { free(rsa_out); + EVP_PKEY_free(pkey); sc_log(context, "PSS mechanism requires parameter"); return CKR_MECHANISM_PARAM_INVALID; } @@ -753,6 +761,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len break; default: free(rsa_out); + EVP_PKEY_free(pkey); return CKR_MECHANISM_PARAM_INVALID; } @@ -774,6 +783,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len break; default: free(rsa_out); + EVP_PKEY_free(pkey); return CKR_MECHANISM_PARAM_INVALID; } @@ -788,6 +798,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { free(rsa_out); + EVP_PKEY_free(pkey); return CKR_GENERAL_ERROR; } data = tmp; @@ -816,6 +827,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len free(rsa_out); sc_log(context, "Returning %lu", rv); return rv; + } else { + EVP_PKEY_free(pkey); } if ((unsigned int) rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) From 37a766402fa8be685df7ac2614de7836372d91bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Jan 2022 18:49:40 +0100 Subject: [PATCH 2244/4321] p11test: Free memory on error --- src/tests/p11test/p11test_case_pss_oaep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 78277e15e0..fc231ccc0f 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -680,13 +680,14 @@ int pss_sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech) get_mgf_name(mech->mgf), mech->salt); rv = pss_sign_message(o, info, message, message_length, mech, &sign); if (rv <= 0) { - return rv; + goto out; } sign_length = (unsigned long) rv; debug_print(" [ KEY %s ] Verify message signature", o->id_str); rv = pss_verify_message(o, info, message, message_length, mech, sign, sign_length); +out: if (mech->mech == CKM_RSA_PKCS_PSS) { free(message); } From 266de4f5b3b577f8bca47be024061abe65fd8159 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sat, 1 Jan 2022 14:04:42 +0100 Subject: [PATCH 2245/4321] Fixes: "salt-len" is not passed to openssl (PSS signature verify). Also implements support for autorecovery of salt length from signature. --- src/pkcs11/openssl.c | 12 +++++++++++- src/tools/pkcs11-tool.c | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 04339e1997..c9081763f3 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -23,6 +23,7 @@ #ifdef ENABLE_OPENSSL /* empty file without openssl */ #include +#include #include #include #include @@ -502,6 +503,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len CK_RV rv = CKR_GENERAL_ERROR; EVP_PKEY *pkey = NULL; const unsigned char *pubkey_tmp = NULL; + int sLen; if (mech->mechanism == CKM_GOSTR3410) { @@ -806,11 +808,19 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len } rv = CKR_SIGNATURE_INVALID; + /* special mode - autodetect sLen from signature */ + /* https://github.com/openssl/openssl/blob/master/crypto/rsa/rsa_pss.c */ + /* there is no way to pass negative value here, we using maximal value for this */ + if (((CK_ULONG) 1 ) << (sizeof(CK_ULONG) * CHAR_BIT -1) == param->sLen) + sLen = -2; + else + sLen = param->sLen; + if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || EVP_PKEY_verify_init(ctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) != 1 || EVP_PKEY_CTX_set_signature_md(ctx, pss_md) != 1 || - EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, param->sLen) != 1 || + EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sLen) != 1 || EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf_md) != 1) { sc_log(context, "Failed to initialize EVP_PKEY_CTX"); free(rsa_out); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6ae6f39637..d7de6b2e21 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2199,7 +2199,8 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, pss_params->sLen = hashlen; break; case -2: /* maximum permissible salt len */ - pss_params->sLen = modlen - hashlen -2; + case -3: + pss_params->sLen = modlen - hashlen - 2; break; default: /* use given size but its value must be >= 0 */ pss_params->sLen = opt_salt_len; From 75c9c5ccf1ee27ed28321338762110ac8a8cd6ea Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 4 Jan 2022 16:26:11 +0100 Subject: [PATCH 2246/4321] pkcs11-tool: support for salt length (PSS signature) --- doc/tools/pkcs11-tool.1.xml | 4 +++- src/tools/pkcs11-tool.c | 22 +++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 7cf0f4e0be..d0244e8212 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -412,7 +412,9 @@ Specify how many bytes of salt should be used in RSA-PSS signatures. Accepts two special values: "-1" means salt length equals to digest length, - "-2" means use maximum permissible length. + "-2" or "-3" means use maximum permissible length. + For verify operation "-2" means that the salt length is automatically recovered from signature. + The value "-2" for the verify operation is supported for opensc pkcs#11 module only. Default is digest length (-1). diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d7de6b2e21..e9d7e993a8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifndef _WIN32 #include @@ -2188,10 +2189,6 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, if (opt_salt_len_given == 1) { /* salt size explicitly given */ unsigned long modlen = 0; - if (opt_salt_len < 0 && opt_salt_len != -1 && opt_salt_len != -2) - util_fatal("Salt length must be greater or equal " - "to zero, or equal to -1 (meaning: use digest size) " - "or to -2 (meaning: use maximum permissible size"); modlen = (get_private_key_length(session, key) + 7) / 8; switch (opt_salt_len) { @@ -2203,6 +2200,11 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, pss_params->sLen = modlen - hashlen - 2; break; default: /* use given size but its value must be >= 0 */ + if (opt_salt_len < 0) + util_fatal("Salt length must be greater or equal " + "to zero, or equal to -1 (meaning: use digest size) " + "or to -2 or -3 (meaning: use maximum permissible size"); + pss_params->sLen = opt_salt_len; break; } /* end switch (opt_salt_len_given) */ @@ -2346,7 +2348,17 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; hashlen = parse_pss_params(session, key, &mech, &pss_params); - + if (hashlen && opt_salt_len_given) { + if (opt_salt_len == -2) { + /* openssl allow us to set sLen to -2 for autodetecting salt length + * here maximal CK_ULONG value is used to pass this special code + * to openssl. For non OpenSC PKCS#11 module this is minimal limitation + * because there is no need to use extra long salt length. + */ + pss_params.sLen = ((CK_ULONG) 1 ) << (sizeof(CK_ULONG) * CHAR_BIT -1); + fprintf(stderr, "Warning, requesting salt length recovery from signature (supported only in in opensc pkcs11 module).\n"); + } + } /* Open a signature file */ if (opt_signature_file == NULL) util_fatal("No file with signature provided. Use --signature-file"); From 73f47ef501a13b1ac9c1362e3942dc000f188cc7 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 5 Jan 2022 09:47:18 +0100 Subject: [PATCH 2247/4321] PSS signature: use the "salt-length" defined in the pMechanism. Fixes #2474 --- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-starcos.c | 4 +-- src/libopensc/internal.h | 2 +- src/libopensc/padding.c | 40 +++++++++++++++++++------- src/libopensc/pkcs15-sec.c | 6 ++-- src/libopensc/pkcs15.h | 2 +- src/minidriver/minidriver.c | 2 +- src/pkcs11/framework-pkcs15.c | 21 ++------------ src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- 10 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 86bbf7ab86..ecc1b23abc 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -721,7 +721,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, flags = SC_ALGORITHM_RSA_HASH_NONE; tmp_len = sizeof(sbuf); r = sc_pkcs1_encode(card->ctx, flags, data, datalen, - sbuf, &tmp_len, sizeof(sbuf)*8); + sbuf, &tmp_len, sizeof(sbuf)*8, NULL); if (r < 0) return r; } else { diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index f2c471e73a..80c5823f9a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1732,7 +1732,7 @@ static int starcos_compute_signature(sc_card_t *card, flags = SC_ALGORITHM_RSA_HASH_NONE; } tmp_len = sizeof(sbuf); - r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8); + r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8, NULL); LOG_TEST_RET(card->ctx, r, "sc_pkcs1_encode failed"); } else { memcpy(sbuf, data, datalen); @@ -1794,7 +1794,7 @@ static int starcos_compute_signature(sc_card_t *card, flags = SC_ALGORITHM_RSA_HASH_NONE; tmp_len = sizeof(sbuf); r = sc_pkcs1_encode(card->ctx, flags, data, datalen, - sbuf, &tmp_len, sizeof(sbuf)*8); + sbuf, &tmp_len, sizeof(sbuf)*8, NULL); if (r < 0) return r; } else { diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 1f7e99ef49..5deb3c999d 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -187,7 +187,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, * @return SC_SUCCESS on success and an error code otherwise */ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, - const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t mod_bits); + const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t mod_bits, void *pMechanism); /** * Get the necessary padding and sec. env. flags. * @param ctx IN sc_contex_t object diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index a0cd18b74d..a1259ad130 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -33,7 +33,7 @@ #include #include "internal.h" - +#include "pkcs11/pkcs11.h" /* TODO doxygen comments */ /* @@ -408,9 +408,11 @@ static const EVP_MD* mgf1_flag2md(unsigned int mgf1) } } +/* large enough up to RSA 4096 */ +#define PSS_MAX_SALT_SIZE 512 /* add PKCS#1 v2.0 PSS padding */ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, - const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) + const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits, size_t sLen) { /* hLen = sLen in our case */ int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds; @@ -418,7 +420,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, const EVP_MD* md, *mgf1_md; EVP_MD_CTX* ctx = NULL; u8 buf[8]; - u8 salt[EVP_MAX_MD_SIZE], mask[EVP_MAX_MD_SIZE]; + u8 salt[PSS_MAX_SALT_SIZE], mask[EVP_MAX_MD_SIZE]; size_t mod_length = (mod_bits + 7) / 8; if (*out_len < mod_length) @@ -429,15 +431,16 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, return SC_ERROR_NOT_SUPPORTED; hlen = EVP_MD_size(md); dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ - plen = mod_length - 2*hlen - 1; + plen = mod_length - sLen - hlen - 1; if (in_len != (unsigned)hlen) return SC_ERROR_INVALID_ARGUMENTS; - if (2 * (unsigned)hlen + 2 > mod_length) + if (sLen + (unsigned)hlen + 2 > mod_length) /* RSA key too small for chosen hash (1296 bits or higher needed for * signing SHA-512 hashes) */ return SC_ERROR_NOT_SUPPORTED; - - if (RAND_bytes(salt, hlen) != 1) + if (sLen > PSS_MAX_SALT_SIZE) + return SC_ERROR_INVALID_ARGUMENTS; + if (RAND_bytes(salt, sLen) != 1) return SC_ERROR_INTERNAL; /* Hash M' to create H */ @@ -447,7 +450,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, if (EVP_DigestInit_ex(ctx, md, NULL) != 1 || EVP_DigestUpdate(ctx, buf, 8) != 1 || EVP_DigestUpdate(ctx, in, hlen) != 1 || /* mHash */ - EVP_DigestUpdate(ctx, salt, hlen) != 1) { + EVP_DigestUpdate(ctx, salt, sLen) != 1) { goto done; } @@ -455,7 +458,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, /* DB = PS || 0x01 || salt */ memset(out, 0x00, plen - 1); /* emLen - sLen - hLen - 2 */ out[plen - 1] = 0x01; - memcpy(out + plen, salt, hlen); + memcpy(out + plen, salt, sLen); if (EVP_DigestFinal_ex(ctx, out + dblen, NULL) != 1) { /* H */ goto done; } @@ -528,7 +531,7 @@ static int hash_len2algo(size_t hash_len) /* general PKCS#1 encoding function */ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, - const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) + const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits, void *pMechanism) { int rv, i; size_t tmp_len = *out_len; @@ -536,6 +539,8 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, unsigned int hash_algo, pad_algo; size_t mod_len = (mod_bits + 7) / 8; #ifdef ENABLE_OPENSSL + size_t sLen; + const EVP_MD* md; unsigned int mgf1_hash; #endif @@ -583,8 +588,21 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, */ hash_algo = hash_len2algo(tmp_len); } + /* sLen is by default same as hash length */ + if (!(md = hash_flag2md(hash_algo))) + return SC_ERROR_NOT_SUPPORTED; + sLen = EVP_MD_size(md); + /* if application provide sLen, use it */ + if (pMechanism != NULL) { + CK_MECHANISM *mech = (CK_MECHANISM *)pMechanism; + CK_RSA_PKCS_PSS_PARAMS *pss_params; + if (mech->pParameter && sizeof(CK_RSA_PKCS_PSS_PARAMS) == mech->ulParameterLen) { + pss_params = mech->pParameter; + sLen = pss_params->sLen; + } + } rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash, - tmp, tmp_len, out, out_len, mod_bits); + tmp, tmp_len, out, out_len, mod_bits, sLen); #else rv = SC_ERROR_NOT_SUPPORTED; #endif diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 0234176078..ffbeead895 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -581,7 +581,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj, unsigned long flags, const u8 *in, size_t inlen, - u8 *out, size_t outlen) + u8 *out, size_t outlen, void *pMechanism) { sc_context_t *ctx = p15card->card->ctx; int r; @@ -659,7 +659,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!"); /* XXX Assuming RSA key here */ - r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, prkey->modulus_length); + r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, prkey->modulus_length, pMechanism); /* no padding needed - already done */ flags &= ~SC_ALGORITHM_RSA_PADS; @@ -725,7 +725,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, /* XXX Assuming RSA key here */ r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, - prkey->modulus_length); + prkey->modulus_length, pMechanism); LOG_TEST_GOTO_ERR(ctx, r, "Unable to add padding"); inlen = tmplen; } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 5aa60e8b3a..bb2e031491 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -700,7 +700,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card, int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, unsigned long alg_flags, const u8 *in, - size_t inlen, u8 *out, size_t outlen); + size_t inlen, u8 *out, size_t outlen, void *pMechanism); int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *, const struct sc_pkcs15_object *, struct sc_pkcs15_pubkey **); diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 0c089feab7..c4f92e9390 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4920,7 +4920,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO goto err; } - r = sc_pkcs15_compute_signature(vs->p15card, pkey, opt_crypt_flags, dataToSign, dataToSignLen, pbuf, lg); + r = sc_pkcs15_compute_signature(vs->p15card, pkey, opt_crypt_flags, dataToSign, dataToSignLen, pbuf, lg, NULL); logprintf(pCardData, 2, "sc_pkcs15_compute_signature return %d\n", r); if(r < 0) { logprintf(pCardData, 2, "sc_pkcs15_compute_signature error %s\n", sc_strerror(r)); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 69b8299f7b..e55600b0fd 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4245,7 +4245,6 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, /* The MGF parameter was already verified in SignInit() */ flags |= mgf2flags(((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->mgf); - /* Assuming salt is the size of hash */ break; case CKM_GOSTR3410: flags = SC_ALGORITHM_GOSTR3410_HASH_NONE; @@ -4290,7 +4289,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, "Selected flags %X. Now computing signature for %lu bytes. %lu bytes reserved.", flags, ulDataLen, *pulDataLen); rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, - pData, ulDataLen, pSignature, *pulDataLen); + pData, ulDataLen, pSignature, *pulDataLen, pMechanism); if (rc < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) { /* If private key PKCS#15 object do not have 'path' attribute, * and if PKCS#11 login session is not locked, @@ -4300,7 +4299,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, */ if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, - pData, ulDataLen, pSignature, *pulDataLen); + pData, ulDataLen, pSignature, *pulDataLen, pMechanism); } sc_unlock(p11card->card); @@ -4631,8 +4630,6 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, { const CK_RSA_PKCS_PSS_PARAMS *pss_params; unsigned int expected_hash = 0, i; - unsigned int expected_salt_len = 0; - const unsigned int salt_lens[5] = { 160, 256, 384, 512, 224 }; const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256, CKM_SHA384, CKM_SHA512, CKM_SHA224 }; const CK_RSA_PKCS_OAEP_PARAMS *oaep_params; @@ -4658,24 +4655,18 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, */ if (pMechanism->mechanism == CKM_SHA1_RSA_PKCS_PSS) { expected_hash = CKM_SHA_1; - expected_salt_len = 160; } else if (pMechanism->mechanism == CKM_SHA224_RSA_PKCS_PSS) { expected_hash = CKM_SHA224; - expected_salt_len = 224; } else if (pMechanism->mechanism == CKM_SHA256_RSA_PKCS_PSS) { expected_hash = CKM_SHA256; - expected_salt_len = 256; } else if (pMechanism->mechanism == CKM_SHA384_RSA_PKCS_PSS) { expected_hash = CKM_SHA384; - expected_salt_len = 384; } else if (pMechanism->mechanism == CKM_SHA512_RSA_PKCS_PSS) { expected_hash = CKM_SHA512; - expected_salt_len = 512; } else if (pMechanism->mechanism == CKM_RSA_PKCS_PSS) { for (i = 0; i < 5; ++i) { if (hashes[i] == pss_params->hashAlg) { expected_hash = hashes[i]; - expected_salt_len = salt_lens[i]; } } } @@ -4683,13 +4674,6 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, if (expected_hash != pss_params->hashAlg) return CKR_MECHANISM_PARAM_INVALID; - /* We're strict, and only do PSS signatures with a salt length that - * matches the digest length (any shorter is rubbish, any longer - * is useless). */ - if (pss_params->sLen != expected_salt_len / 8) - return CKR_MECHANISM_PARAM_INVALID; - - /* TODO support different salt lengths */ break; case CKM_RSA_PKCS_OAEP: if (!pMechanism->pParameter || @@ -4708,7 +4692,6 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session, default: return CKR_MECHANISM_PARAM_INVALID; } - /* TODO support different salt lengths */ /* TODO is there something more to check */ break; } diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index b6bdd8138b..54c56d0a46 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -277,7 +277,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) }; for (i = 0; i < sizeof signature_flags/sizeof *signature_flags; i++) { sc_pkcs15_compute_signature(p15card, obj, signature_flags[i], - in, in_len, buf, sizeof buf); + in, in_len, buf, sizeof buf, NULL); } if (obj->type == SC_PKCS15_TYPE_AUTH_PIN) { diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index c0db1abbaf..133cb2c14b 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -237,7 +237,7 @@ static int sign(struct sc_pkcs15_object *obj) return SC_ERROR_NOT_SUPPORTED; } - r = sc_pkcs15_compute_signature(p15card, obj, opt_crypt_flags, buf, c, out, len); + r = sc_pkcs15_compute_signature(p15card, obj, opt_crypt_flags, buf, c, out, len, NULL); if (r < 0) { fprintf(stderr, "Compute signature failed: %s\n", sc_strerror(r)); return 1; From 6f870b6d10f2089b042a95b22611adc801212319 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 6 Jan 2022 08:12:08 +0100 Subject: [PATCH 2248/4321] virt_cacard_ref.json update: PSS, salt length modified: src/tests/p11test/virt_cacard_ref.json --- src/tests/p11test/virt_cacard_ref.json | 3332 ++++++++++++++++++++---- 1 file changed, 2881 insertions(+), 451 deletions(-) diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index d715c1c642..1092eb0f3f 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -572,7 +572,7 @@ "RSA_PKCS_PSS", "SHA_1", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], @@ -580,7 +580,7 @@ "00:01", "RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA224", + "MGF1_SHA_1", "-1", "YES", "" @@ -589,8 +589,8 @@ "00:01", "RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA256", - "-1", + "MGF1_SHA_1", + "0", "YES", "" ], @@ -598,8 +598,8 @@ "00:01", "RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA384", - "-1", + "MGF1_SHA224", + "-2", "YES", "" ], @@ -607,7 +607,7 @@ "00:01", "RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA512", + "MGF1_SHA224", "-1", "YES", "" @@ -615,25 +615,25 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", + "SHA_1", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA224", - "-1", + "SHA_1", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA224", + "SHA_1", "MGF1_SHA256", "-1", "YES", @@ -642,26 +642,26 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", - "-1", + "SHA_1", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA512", - "-1", + "SHA_1", + "MGF1_SHA384", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", + "SHA_1", + "MGF1_SHA384", "-1", "YES", "" @@ -669,26 +669,26 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA224", - "-1", + "SHA_1", + "MGF1_SHA384", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA256", - "-1", + "SHA_1", + "MGF1_SHA512", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA384", + "SHA_1", + "MGF1_SHA512", "-1", "YES", "" @@ -696,26 +696,26 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA256", + "SHA_1", "MGF1_SHA512", - "-1", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA384", + "SHA224", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA224", + "SHA224", + "MGF1_SHA_1", "-1", "YES", "" @@ -723,26 +723,26 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA256", - "-1", + "SHA224", + "MGF1_SHA_1", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA384", - "-1", + "SHA224", + "MGF1_SHA224", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA512", + "SHA224", + "MGF1_SHA224", "-1", "YES", "" @@ -750,25 +750,25 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-1", + "SHA224", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA224", - "-1", + "SHA224", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA512", + "SHA224", "MGF1_SHA256", "-1", "YES", @@ -777,133 +777,133 @@ [ "00:01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA384", - "-1", + "SHA224", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA512", - "-1", + "SHA224", + "MGF1_SHA384", + "-2", "YES", "" ], [ "00:01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", "-1", "YES", "" ], [ "00:01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", - "-1", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", "YES", "" ], [ "00:01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "-1", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", "YES", "" ], [ "00:01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", "-1", "YES", "" ], [ "00:01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA224", "MGF1_SHA512", - "-1", + "0", "YES", "" ], [ "00:01", - "SHA256_RSA_PKCS_PSS", + "RSA_PKCS_PSS", "SHA256", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ "00:01", - "SHA256_RSA_PKCS_PSS", + "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA224", + "MGF1_SHA_1", "-1", "YES", "" ], [ "00:01", - "SHA256_RSA_PKCS_PSS", + "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA256", - "-1", + "MGF1_SHA_1", + "0", "YES", "" ], [ "00:01", - "SHA256_RSA_PKCS_PSS", + "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA384", - "-1", + "MGF1_SHA224", + "-2", "YES", "" ], [ "00:01", - "SHA256_RSA_PKCS_PSS", + "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ "00:01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA224", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "RSA_PKCS_PSS", + "SHA256", "MGF1_SHA256", "-1", "YES", @@ -911,330 +911,321 @@ ], [ "00:01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA384", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA512", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", "YES", "" ], [ "00:01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", "-1", "YES", "" ], [ "00:01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA224", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", "YES", "" ], [ "00:01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA256", - "-1", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", "YES", "" ], [ "00:01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA384", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", "-1", "YES", "" ], [ "00:01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "RSA_PKCS_PSS", + "SHA256", "MGF1_SHA512", - "-1", + "0", "YES", "" ], [ "00:01", - "RSA_PKCS_OAEP", - "SHA_1", + "RSA_PKCS_PSS", + "SHA384", "MGF1_SHA_1", - "0", - "", - "YES" + "-2", + "YES", + "" ], [ "00:01", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA224", - "0", - "", - "YES" + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" ], [ "00:01", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA256", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", "0", - "", - "YES" + "YES", + "" ], [ "00:01", - "RSA_PKCS_OAEP", + "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA384", - "0", - "", - "YES" + "MGF1_SHA224", + "-2", + "YES", + "" ], [ "00:01", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "00:02", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "SHA384", + "MGF1_SHA224", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA_1", + "SHA384", "MGF1_SHA224", - "-1", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA_1", + "SHA384", "MGF1_SHA256", - "-1", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", + "SHA384", + "MGF1_SHA256", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA512", - "-1", + "SHA384", + "MGF1_SHA256", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", + "SHA384", + "MGF1_SHA384", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA224", + "SHA384", + "MGF1_SHA384", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA256", - "-1", + "SHA384", + "MGF1_SHA384", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", - "-1", + "SHA384", + "MGF1_SHA512", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA224", + "SHA384", "MGF1_SHA512", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-1", + "SHA384", + "MGF1_SHA512", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA224", - "-1", + "SHA512", + "MGF1_SHA_1", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA256", + "SHA512", + "MGF1_SHA_1", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA384", - "-1", + "SHA512", + "MGF1_SHA_1", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA512", - "-1", + "SHA512", + "MGF1_SHA224", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", + "SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA224", - "-1", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA256", - "-1", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA384", + "SHA512", + "MGF1_SHA256", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA512", - "-1", + "SHA512", + "MGF1_SHA256", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA_1", - "-1", + "MGF1_SHA384", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA224", + "MGF1_SHA384", "-1", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA256", - "-1", + "MGF1_SHA384", + "0", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA384", - "-1", + "MGF1_SHA512", + "-2", "YES", "" ], [ - "00:02", + "00:01", "RSA_PKCS_PSS", "SHA512", "MGF1_SHA512", @@ -1243,297 +1234,2736 @@ "" ], [ - "00:02", + "00:01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:01", "SHA1_RSA_PKCS_PSS", "SHA_1", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ - "00:02", + "00:01", "SHA1_RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA224", + "MGF1_SHA_1", "-1", "YES", "" ], [ - "00:02", + "00:01", "SHA1_RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA256", - "-1", + "MGF1_SHA_1", + "0", "YES", "" ], [ - "00:02", + "00:01", "SHA1_RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA384", - "-1", + "MGF1_SHA224", + "-2", "YES", "" ], [ - "00:02", + "00:01", "SHA1_RSA_PKCS_PSS", "SHA_1", - "MGF1_SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ - "00:02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-1", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", "YES", "" ], [ - "00:02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA224", - "-1", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", "YES", "" ], [ - "00:02", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", "MGF1_SHA256", "-1", "YES", "" ], [ - "00:02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA384", - "-1", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", "YES", "" ], [ - "00:02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA512", - "-1", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", "YES", "" ], [ - "00:02", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", "-1", "YES", "" ], [ - "00:02", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "00:01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "00:02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", "-1", "YES", "" ], [ - "00:02", - "SHA384_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA256", - "-1", + "MGF1_SHA512", + "-2", "YES", "" ], [ - "00:02", - "SHA384_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA384", + "MGF1_SHA512", "-1", "YES", "" ], [ - "00:02", - "SHA384_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA384", "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", "-1", "YES", "" ], [ - "00:02", - "SHA512_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA512", "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ - "00:02", - "SHA512_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA512", "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", "-1", "YES", "" ], [ - "00:02", - "SHA512_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA512", "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", "-1", "YES", "" ], [ - "00:02", - "SHA512_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA512", "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "00:03", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", "-1", "YES", "" ], [ - "00:02", - "SHA512_RSA_PKCS_PSS", + "00:03", + "RSA_PKCS_PSS", "SHA512", "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", "-1", "YES", "" ], [ - "00:02", - "RSA_PKCS_OAEP", + "00:03", + "SHA1_RSA_PKCS_PSS", "SHA_1", "MGF1_SHA_1", "0", - "", - "YES" + "YES", + "" ], [ - "00:02", - "RSA_PKCS_OAEP", - "SHA224", + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", "MGF1_SHA224", "0", - "", - "YES" + "YES", + "" ], [ - "00:02", - "RSA_PKCS_OAEP", - "SHA256", + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", "MGF1_SHA256", "0", - "", - "YES" + "YES", + "" ], [ - "00:02", - "RSA_PKCS_OAEP", - "SHA384", + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", "MGF1_SHA384", "0", - "", - "YES" + "YES", + "" ], [ - "00:02", - "RSA_PKCS_OAEP", - "SHA512", + "00:03", + "SHA1_RSA_PKCS_PSS", + "SHA_1", "MGF1_SHA512", - "0", - "", - "YES" + "-2", + "YES", + "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "00:03", + "SHA1_RSA_PKCS_PSS", "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "00:03", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA512", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA224", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA224", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA256", "-1", "YES", @@ -1541,134 +3971,134 @@ ], [ "00:03", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA512", - "-1", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA256_RSA_PKCS_PSS", "SHA256", - "MGF1_SHA_1", + "MGF1_SHA384", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA256_RSA_PKCS_PSS", "SHA256", - "MGF1_SHA224", - "-1", + "MGF1_SHA384", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA256_RSA_PKCS_PSS", "SHA256", - "MGF1_SHA256", - "-1", + "MGF1_SHA512", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA256_RSA_PKCS_PSS", "SHA256", - "MGF1_SHA384", + "MGF1_SHA512", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA256_RSA_PKCS_PSS", "SHA256", "MGF1_SHA512", - "-1", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA384_RSA_PKCS_PSS", "SHA384", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA384_RSA_PKCS_PSS", "SHA384", - "MGF1_SHA224", + "MGF1_SHA_1", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA384_RSA_PKCS_PSS", "SHA384", - "MGF1_SHA256", - "-1", + "MGF1_SHA_1", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA384_RSA_PKCS_PSS", "SHA384", - "MGF1_SHA384", - "-1", + "MGF1_SHA224", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", + "SHA384_RSA_PKCS_PSS", "SHA384", - "MGF1_SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA224", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA512", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA256", "-1", "YES", @@ -1676,134 +4106,134 @@ ], [ "00:03", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA384", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:03", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA512", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", "YES", "" ], [ "00:03", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", "-1", "YES", "" ], [ "00:03", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", "YES", "" ], [ "00:03", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "-1", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", "YES", "" ], [ "00:03", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", "-1", "YES", "" ], [ "00:03", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA512", - "-1", + "0", "YES", "" ], [ "00:03", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA_1", - "-1", + "-2", "YES", "" ], [ "00:03", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA224", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", "-1", "YES", "" ], [ "00:03", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA256", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", "YES", "" ], [ "00:03", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA384", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", "YES", "" ], [ "00:03", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA512", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", "-1", "YES", "" ], [ "00:03", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", "YES", "" ], [ "00:03", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA224", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", "YES", "" ], [ "00:03", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA256", "-1", "YES", @@ -1811,19 +4241,19 @@ ], [ "00:03", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA384", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", "YES", "" ], [ "00:03", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA512", - "-1", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", "YES", "" ], @@ -1831,7 +4261,7 @@ "00:03", "SHA512_RSA_PKCS_PSS", "SHA512", - "MGF1_SHA_1", + "MGF1_SHA384", "-1", "YES", "" @@ -1840,8 +4270,8 @@ "00:03", "SHA512_RSA_PKCS_PSS", "SHA512", - "MGF1_SHA224", - "-1", + "MGF1_SHA384", + "0", "YES", "" ], @@ -1849,8 +4279,8 @@ "00:03", "SHA512_RSA_PKCS_PSS", "SHA512", - "MGF1_SHA256", - "-1", + "MGF1_SHA512", + "-2", "YES", "" ], @@ -1858,7 +4288,7 @@ "00:03", "SHA512_RSA_PKCS_PSS", "SHA512", - "MGF1_SHA384", + "MGF1_SHA512", "-1", "YES", "" @@ -1868,7 +4298,7 @@ "SHA512_RSA_PKCS_PSS", "SHA512", "MGF1_SHA512", - "-1", + "0", "YES", "" ], From 0672265f19187eb24c27f812a1d7c1c5ab4c1998 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Sat, 29 Jan 2022 22:33:43 +0200 Subject: [PATCH 2249/4321] pkcs11.h: do not use generic 'interface' variable Conflicts with Windows basetyps.h macro. Reported-By: Selva Nair Signed-off-by: Alon Bar-Lev --- src/pkcs11/pkcs11.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 05710d12af..1ea46d3c74 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -1256,7 +1256,7 @@ _CK_DECLARE_FUNCTION (C_GetInterfaceList, _CK_DECLARE_FUNCTION (C_GetInterface, (unsigned char *interface_name, struct ck_version *version, - struct ck_interface **interface, + struct ck_interface **interface_ptr, ck_flags_t flags)); _CK_DECLARE_FUNCTION (C_LoginUser, From b71ca16b28c4e1a8d35a326f65bed29a8dec2183 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 23 Jan 2022 12:12:02 +0100 Subject: [PATCH 2250/4321] scconf: End with error for too nested blocks Freeing cause stack-overflow because of huge number of nested calls. The parser ends with an error when the nested blocks limit is exceeded. Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40676 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41434 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41450 --- src/scconf/internal.h | 4 ++++ src/scconf/parse.c | 10 ++++++++++ src/scconf/sclex.c | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/src/scconf/internal.h b/src/scconf/internal.h index bff94a2092..a795784ef3 100644 --- a/src/scconf/internal.h +++ b/src/scconf/internal.h @@ -33,6 +33,8 @@ extern "C" { #define TOKEN_TYPE_STRING 2 #define TOKEN_TYPE_PUNCT 3 +#define DEPTH_LIMIT 16 + typedef struct _scconf_parser { scconf_context *config; @@ -49,11 +51,13 @@ typedef struct _scconf_parser { unsigned int error:1; unsigned int warnings:1; char emesg[256]; + size_t nested_blocks; } scconf_parser; extern int scconf_lex_parse(scconf_parser * parser, const char *filename); extern int scconf_lex_parse_string(scconf_parser * parser, const char *config_string); +extern void scconf_skip_block(scconf_parser * parser); extern void scconf_parse_token(scconf_parser * parser, int token_type, const char *token); #ifdef __cplusplus diff --git a/src/scconf/parse.c b/src/scconf/parse.c index a050c6f5e2..e02daf4296 100644 --- a/src/scconf/parse.c +++ b/src/scconf/parse.c @@ -241,6 +241,12 @@ static void scconf_parse_reset_state(scconf_parser * parser) } } +void scconf_skip_block(scconf_parser * parser) +{ + scconf_parse_error(parser, "too many nested blocks"); + scconf_parse_reset_state(parser); +} + void scconf_parse_token(scconf_parser * parser, int token_type, const char *token) { scconf_item *item; @@ -320,10 +326,12 @@ void scconf_parse_token(scconf_parser * parser, int token_type, const char *toke scconf_parse_error_not_expect(parser, "{"); break; } + parser->nested_blocks++; scconf_block_add_internal(parser); scconf_parse_reset_state(parser); break; case '}': + parser->nested_blocks--; if (parser->state != 0) { if ((parser->state & STATE_VALUE) == 0 || (parser->state & STATE_SET) == 0) { @@ -381,6 +389,7 @@ int scconf_parse(scconf_context * config) p.config = config; p.block = config->root; p.line = 1; + p.nested_blocks = 0; if (!scconf_lex_parse(&p, config->filename)) { snprintf(buffer, sizeof(buffer), @@ -409,6 +418,7 @@ int scconf_parse_string(scconf_context * config, const char *string) p.config = config; p.block = config->root; p.line = 1; + p.nested_blocks = 0; if (!scconf_lex_parse_string(&p, string)) { snprintf(buffer, sizeof(buffer), diff --git a/src/scconf/sclex.c b/src/scconf/sclex.c index 144b8db36f..ff6cc1777c 100644 --- a/src/scconf/sclex.c +++ b/src/scconf/sclex.c @@ -144,6 +144,12 @@ static int scconf_lex_engine(scconf_parser * parser, BUFHAN * bp) continue; case ',': case '{': + if (parser->nested_blocks >= DEPTH_LIMIT) { + /* reached the limit, this whole block */ + scconf_skip_block(parser); + continue; + } + /* fall through */ case '}': case '=': case ';': From 43e44361699e39397588ec418652c55d0ad0e3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Roberto=20Teodoro?= Date: Thu, 3 Feb 2022 10:42:04 -0300 Subject: [PATCH 2251/4321] Default value of SOURCE_PATH in tests was duplicatingn '/'s. Fixed it. --- tests/test-duplicate-symbols.sh | 2 +- tests/test-manpage.sh | 2 +- tests/test-pkcs11-tool-allowed-mechanisms.sh | 2 +- tests/test-pkcs11-tool-sign-verify.sh | 2 +- tests/test-pkcs11-tool-test-threads.sh | 2 +- tests/test-pkcs11-tool-test.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-duplicate-symbols.sh b/tests/test-duplicate-symbols.sh index 01c2c88b55..6cecc51e4a 100755 --- a/tests/test-duplicate-symbols.sh +++ b/tests/test-duplicate-symbols.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} EXPORTS=`find "${SOURCE_PATH}" -name "*exports"` diff --git a/tests/test-manpage.sh b/tests/test-manpage.sh index eb35aee15b..152c2c8712 100755 --- a/tests/test-manpage.sh +++ b/tests/test-manpage.sh @@ -1,5 +1,5 @@ #!/bin/bash -x -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} # find all the manual pages in doc/tools TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|" | grep -v goid-tool` diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 2cb822d3b5..33c18e61ae 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} source $SOURCE_PATH/tests/common.sh diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index a2a501d3c1..9de0879920 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} source $SOURCE_PATH/tests/common.sh diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index c2ef1a98c8..bf2a060eeb 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} source $SOURCE_PATH/tests/common.sh diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 8b41288370..0ab5f19bfe 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -1,5 +1,5 @@ #!/bin/bash -SOURCE_PATH=${SOURCE_PATH:-../} +SOURCE_PATH=${SOURCE_PATH:-..} source $SOURCE_PATH/tests/common.sh From f1cac4700b8062998131d640c46f6f3ac50d0fa5 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 10 Jan 2022 14:19:55 +0100 Subject: [PATCH 2252/4321] OAEP decrypt: support for optional "label" For OAEP encryption, RFC8017 allow us to use an optional "label" to be associated with the message. This "label" is represented in PKCS#11 as optional encoding parameter in CK_RSA_PKCS_OAEP_PARAMS. This patch introduces the ability to use this optional "label". Fixes #2363 --- src/libopensc/internal.h | 2 +- src/libopensc/padding.c | 9 +++------ src/libopensc/pkcs15-sec.c | 20 ++++++++++++++++---- src/libopensc/pkcs15.h | 2 +- src/minidriver/minidriver.c | 4 ++-- src/pkcs11/framework-pkcs15.c | 4 ++-- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 5deb3c999d..44378a4e48 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -172,7 +172,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len); #ifdef ENABLE_OPENSSL int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, - unsigned long flags); + unsigned long flags, uint8_t *param, size_t paramlen); #endif /** diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index a1259ad130..826e726783 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -235,7 +235,7 @@ static const EVP_MD *mgf1_flag2md(unsigned int mgf1); static const EVP_MD *hash_flag2md(unsigned int hash); /* check/remove OAEP - RFC 8017 padding */ -int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigned long flags) +int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigned long flags, uint8_t *param, size_t paramlen) { size_t i,j; size_t mdlen, dblen; @@ -250,10 +250,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne if (data == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); - /* - * https://www.rfc-editor.org/rfc/pdfrfc/rfc8017.txt.pdf, page 26, 3.a. - * there is no implementation for label "L" (empty string for now) - */ + /* https://www.rfc-editor.org/rfc/pdfrfc/rfc8017.txt.pdf, page 26, 3.a. */ hash_md = hash_flag2md(flags); if (!hash_md) return SC_ERROR_NOT_SUPPORTED; @@ -261,7 +258,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne memset(label, 0, sizeof(label)); if ((md_ctx = EVP_MD_CTX_new())) { if (!EVP_DigestInit_ex(md_ctx, hash_md, NULL) - || !EVP_DigestUpdate(md_ctx, label, 0) + || !EVP_DigestUpdate(md_ctx, param, paramlen) || !EVP_DigestFinal_ex(md_ctx, label, &hash_len)) hash_len = 0; EVP_MD_CTX_free(md_ctx); diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index ffbeead895..054e60811f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -280,7 +280,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj, unsigned long flags, - const u8 * in, size_t inlen, u8 *out, size_t outlen) + const u8 * in, size_t inlen, u8 *out, size_t outlen, void *pMechanism) { sc_context_t *ctx = p15card->card->ctx; int r; @@ -316,7 +316,19 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) { size_t s = r; - r = sc_pkcs1_strip_oaep_padding(ctx, out, s, flags); + uint8_t *param = NULL; + size_t paramlen = 0; + if (pMechanism != NULL) { + CK_MECHANISM *mech = (CK_MECHANISM *)pMechanism; + if (mech->pParameter && sizeof(CK_RSA_PKCS_OAEP_PARAMS) == mech->ulParameterLen) { + CK_RSA_PKCS_OAEP_PARAMS * oaep_params = mech->pParameter; + if (oaep_params->source == CKZ_DATA_SPECIFIED) { + param = oaep_params->pSourceData; + paramlen = (size_t)oaep_params->ulSourceDataLen; + } + } + } + r = sc_pkcs1_strip_oaep_padding(ctx, out, s, flags, param, paramlen); LOG_TEST_RET(ctx, r, "Invalid OAEP padding"); } #endif @@ -652,7 +664,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, (prkey->usage & USAGE_ANY_DECIPHER)) ) { size_t tmplen = buflen; if (flags & SC_ALGORITHM_RSA_RAW) { - r = sc_pkcs15_decipher(p15card, obj, flags, in, inlen, out, outlen); + r = sc_pkcs15_decipher(p15card, obj, flags, in, inlen, out, outlen, NULL); goto err; } if (modlen > tmplen) @@ -668,7 +680,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, LOG_TEST_GOTO_ERR(ctx, r, "Unable to add padding"); - r = sc_pkcs15_decipher(p15card, obj, flags, buf, modlen, out, outlen); + r = sc_pkcs15_decipher(p15card, obj, flags, buf, modlen, out, outlen, NULL); goto err; } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index bb2e031491..b5cdaed90c 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -676,7 +676,7 @@ void sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo); int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, unsigned long flags, - const u8 *in, size_t inlen, u8 *out, size_t outlen); + const u8 *in, size_t inlen, u8 *out, size_t outlen, void *pMechanism); int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *prkey_obj, diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index c4f92e9390..5e52778357 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4572,7 +4572,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, if (alg_info->flags & SC_ALGORITHM_RSA_RAW) { logprintf(pCardData, 2, "sc_pkcs15_decipher: using RSA-RAW mechanism\n"); - r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags, pbuf, pInfo->cbData, pbuf2, pInfo->cbData); + r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags, pbuf, pInfo->cbData, pbuf2, pInfo->cbData, NULL); logprintf(pCardData, 2, "sc_pkcs15_decipher returned %d\n", r); if (r > 0) { @@ -4608,7 +4608,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, else if (alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1) { logprintf(pCardData, 2, "sc_pkcs15_decipher: using RSA_PAD_PKCS1 mechanism\n"); r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags | SC_ALGORITHM_RSA_PAD_PKCS1, - pbuf, pInfo->cbData, pbuf2, pInfo->cbData); + pbuf, pInfo->cbData, pbuf2, pInfo->cbData, NULL); logprintf(pCardData, 2, "sc_pkcs15_decipher returned %d\n", r); if (r > 0) { /* No padding info, or padding info none */ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index e55600b0fd..2c00273fb2 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4462,12 +4462,12 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(rv, "C_Decrypt"); rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags, - pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted)); + pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism); if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags, - pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted)); + pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism); sc_unlock(p11card->card); diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 54c56d0a46..b1f1c85d32 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -223,7 +223,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) SC_ALGORITHM_RSA_PAD_ISO9796}; for (i = 0; i < sizeof decipher_flags/sizeof *decipher_flags; i++) { sc_pkcs15_decipher(p15card, obj, decipher_flags[i], - in, in_len, buf, sizeof buf); + in, in_len, buf, sizeof buf, NULL); } i = sizeof buf; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 133cb2c14b..d4017a5463 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -284,7 +284,7 @@ static int decipher(struct sc_pkcs15_object *obj) return SC_ERROR_NOT_SUPPORTED; } - r = sc_pkcs15_decipher(p15card, obj, opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1, buf, c, out, len); + r = sc_pkcs15_decipher(p15card, obj, opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1, buf, c, out, len, NULL); if (r < 0) { fprintf(stderr, "Decrypt failed: %s\n", sc_strerror(r)); return 1; From 870f21a931772327ba514662abb8f54cc08f9673 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 10 Jan 2022 14:43:50 +0100 Subject: [PATCH 2253/4321] pkcs11-tool: test for oaep decrypt using optional "label" "pkcs11-tool -l -t" now attempts to use optional "label" in OAEP decipher. --- src/tools/pkcs11-tool.c | 47 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e9d7e993a8..63a59310b0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6796,7 +6796,8 @@ static int test_unwrap(CK_SESSION_HANDLE sess) #ifdef ENABLE_OPENSSL static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech_type, - CK_OBJECT_HANDLE privKeyObject) + CK_OBJECT_HANDLE privKeyObject, + char *param, unsigned long param_len) { EVP_PKEY *pkey; unsigned char orig_data[512]; @@ -7005,6 +7006,18 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf("set mgf1 md failed, returning\n"); return 0; } + if (param_len != 0 && param != NULL) { + /* label is in ownership of openssl, do not free this ptr! */ + char *label = malloc(param_len); + memcpy(label, param, param_len); + + if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label, param_len) <= 0) { + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + printf("set OAEP label failed, returning\n"); + return 0; + } + } #else if (hash_alg != CKM_SHA_1) { printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n"); @@ -7030,21 +7043,28 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, oaep_params.hashAlg = hash_alg; oaep_params.mgf = mgf; - /* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */ oaep_params.source = 0UL; /* empty encoding parameter (label) */ oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ - /* If an RSA-OAEP mechanism, it needs parameters */ + fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, ", + p11_mechanism_to_name(oaep_params.hashAlg), + p11_mgf_to_name(oaep_params.mgf)); + + if (param != NULL && param_len > 0) { + oaep_params.source = CKZ_DATA_SPECIFIED; + oaep_params.pSourceData = param; + oaep_params.ulSourceDataLen = param_len; + fprintf(stderr, "encoding parameter (Label) present, length %ld\n", param_len); + } else { + fprintf(stderr, "encoding parameter (Label) not present\n"); + } + mech.pParameter = &oaep_params; mech.ulParameterLen = sizeof(oaep_params); - fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", - p11_mechanism_to_name(oaep_params.hashAlg), - p11_mgf_to_name(oaep_params.mgf), - oaep_params.source, - oaep_params.pSourceData, - oaep_params.ulSourceDataLen); + + break; case CKM_RSA_X_509: case CKM_RSA_PKCS: @@ -7163,16 +7183,17 @@ static int test_decrypt(CK_SESSION_HANDLE sess) #else for (n = 0; n < num_mechs; n++) { switch (mechs[n]) { - case CKM_RSA_PKCS: case CKM_RSA_PKCS_OAEP: + /* one more OAEP test with param .. */ + errors += encrypt_decrypt(sess, mechs[n], privKeyObject, "ABC", 3); + /* fall through */ + case CKM_RSA_PKCS: case CKM_RSA_X_509: + errors += encrypt_decrypt(sess, mechs[n], privKeyObject, NULL, 0); break; default: printf(" -- mechanism can't be used to decrypt, skipping\n"); - continue; } - - errors += encrypt_decrypt(sess, mechs[n], privKeyObject); } #endif } From ec75651a2deebf8b67458231af10010d4d2ac6ad Mon Sep 17 00:00:00 2001 From: Ludvig Michaelsson Date: Tue, 25 Jan 2022 08:56:22 +0100 Subject: [PATCH 2254/4321] pkcs11-tool: consistent handling of secret key attributes When support for unwrapping secret keys was added in 9136878 (as part of #2268), the `--usage-decrypt` and `--usage-wrap` options were used to toggle the `CKA_{ENCRYPT,DECRYPT}` and `CKA_{WRAP,UNWRAP}` attributes in the object template passed to the module. In contrast, when a secret key object is generated (`--keygen`) or created (`--write-object`), the same attributes are unconditionally set to true or omitted respectively, regardless of any specified `--usage-*` option. To make this handling consistent, use the approach introduced by the unwrap command and let the user specify the attributes, defaulting to only setting `CKA_{ENCRYPT,DECRYPT}` if no usage was specified. The documentation was amended to reflect the behavior of `--usage-decrypt`. --- doc/tools/pkcs11-tool.1.xml | 8 +++++++- src/tools/pkcs11-tool.c | 38 ++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index d0244e8212..7ff1a88978 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -162,7 +162,13 @@ - Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey). + + Specify 'decrypt' key usage flag. + + For RSA keys, sets DECRYPT in privkey and ENCRYPT in pubkey. For secret + keys, sets both DECRYPT and ENCRYPT. + + diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 63a59310b0..497b5c335b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -321,7 +321,7 @@ static const char *option_help[] = { "Key generation", "Specify the type and length (bytes if symmetric) of the key to create, for example rsa:1024, EC:prime256v1, EC:ed25519, EC:curve25519, GOSTR3410-2012-256:B, AES:16 or GENERIC:64", "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", - "Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)", + "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", "Specify 'derive' key usage flag (EC only)", "Specify 'wrap' key usage flag", "Write an object (key, cert, data) to the card", @@ -3249,14 +3249,20 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey n_attr++; } - FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); - n_attr++; - FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); - n_attr++; - FILL_ATTR(keyTemplate[n_attr], CKA_WRAP, &_true, sizeof(_true)); - n_attr++; - FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true)); - n_attr++; + if (opt_key_usage_default || opt_key_usage_decrypt) { + FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); + n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); + n_attr++; + } + + if (opt_key_usage_wrap) { + FILL_ATTR(keyTemplate[n_attr], CKA_WRAP, &_true, sizeof(_true)); + n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true)); + n_attr++; + } + FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); n_attr++; @@ -4254,6 +4260,20 @@ static int write_object(CK_SESSION_HANDLE session) n_seckey_attr++; } + if (opt_key_usage_default || opt_key_usage_decrypt) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_ENCRYPT, &_true, sizeof(_true)); + n_seckey_attr++; + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_DECRYPT, &_true, sizeof(_true)); + n_seckey_attr++; + } + + if (opt_key_usage_wrap) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_WRAP, &_true, sizeof(_true)); + n_seckey_attr++; + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_UNWRAP, &_true, sizeof(_true)); + n_seckey_attr++; + } + if (opt_object_label != NULL) { FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); n_seckey_attr++; From 3149ba208966a146322d2805ca0695a2c282b0f3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 7 Feb 2022 17:22:49 +0100 Subject: [PATCH 2255/4321] added input checking for sc_der_copy fixes coverity scan 13698 Dereference after null check --- src/libopensc/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 257952fccf..8fb3992457 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -2061,7 +2061,7 @@ _sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, int sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src) { - if (!dst) + if (!dst || !src) return SC_ERROR_INVALID_ARGUMENTS; memset(dst, 0, sizeof(*dst)); if (src->len) { From be3dcd821e731d458c10a5fdd0d28474a8f20a78 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 8 Feb 2022 10:53:07 +0100 Subject: [PATCH 2256/4321] check output length of SCardControl fixes coverity scan 367426 Out-of-bounds access --- src/libopensc/reader-pcsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 664042a199..d1706f83bb 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1165,7 +1165,8 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) return; } - if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) { + if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0 + || feature_len > sizeof(feature_buf.buf)) { sc_log(ctx, "Inconsistent TLV from reader!"); return; } From b458a959529796f91857b7da83190f578bc8c5b6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 8 Feb 2022 12:48:17 +0100 Subject: [PATCH 2257/4321] pkcs15-init: Fixed detection of GOST private keys in OpenSSL 3.0 fixes coverity scan 374950 Logically dead code --- src/tools/pkcs15-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e965569aa9..f75e3f743b 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1879,7 +1879,7 @@ init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey #else char name[256]; size_t name_len = 0; #endif - int nid = 0; + int nid = NID_undef; assert(pkey); if (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { @@ -1888,7 +1888,7 @@ init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey key = EVP_PKEY_get0(pkey); assert(key); assert(EC_KEY_get0_group(key)); - EC_GROUP_get_curve_name(EC_KEY_get0_group(key)); + nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key)); #else assert(EVP_PKEY_get_group_name(pkey, name ,sizeof(name), &name_len)); nid = OBJ_txt2nid(name); From 1b7964a92e58850abf2c7bb335f148da49318eae Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 20 Jan 2022 17:29:36 +0100 Subject: [PATCH 2258/4321] Free allocated spki value In case of unsupported algorithm or other failure of adding pubkey the value is not freed Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=42232 --- src/libopensc/pkcs15-cac.c | 7 ++++++- src/libopensc/pkcs15-coolkey.c | 1 + src/libopensc/pkcs15-idprime.c | 5 ++++- src/libopensc/pkcs15-sc-hsm.c | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 05056ea9c5..9952135477 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -334,15 +334,20 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) if (cert_out->key->algorithm != SC_ALGORITHM_RSA) { sc_log(card->ctx, "unsupported key.algorithm %d", cert_out->key->algorithm); sc_pkcs15_free_certificate(cert_out); + free(pubkey_info.direct.spki.value); continue; } else { pubkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; prkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); sc_log(card->ctx, "adding rsa public key r=%d usage=%x",r, pubkey_info.usage); - if (r < 0) + if (r < 0) { + free(pubkey_info.direct.spki.value); goto fail; + } r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + if (r < 0) + goto fail; sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 15684cef08..fb2390e124 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -643,6 +643,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) obj_type = SC_PKCS15_TYPE_PUBKEY_EC; pubkey_info.field_length = key->u.ec.params.field_length; } else { + free(pubkey_info.direct.spki.value); goto fail; } /* set the obj values */ diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index eb447f320e..2fce1b984b 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -252,14 +252,17 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) if (cert_out->key->algorithm != SC_ALGORITHM_RSA) { sc_log(card->ctx, "unsupported key.algorithm %d", cert_out->key->algorithm); sc_pkcs15_free_certificate(cert_out); + free(pubkey_info.direct.spki.value); continue; } else { pubkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; prkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; sc_log(card->ctx, "adding rsa public key r=%d usage=%x",r, pubkey_info.usage); r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); - if (r < 0) + if (r < 0) { + free(pubkey_info.direct.spki.value); goto fail; + } sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index c99c54ee07..7cb751b5be 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -622,6 +622,8 @@ static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, u8 *efbin, pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_VERIFY; r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); } + if (r < 0) + free(pubkey_info.direct.spki.value); LOG_TEST_RET(ctx, r, "Could not add public key"); sc_pkcs15emu_sc_hsm_free_cvc(&cvc); From 4332510a83a655678241e764cead65942a92c8ec Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 09:41:40 +0100 Subject: [PATCH 2259/4321] pkcs15-cac: Stop iterator in case of failure In case of fail, iterator is not set to stopped and variable iter_active in list_t remains 1. Then during memory release in sc_disconnect_card() list_t is not freed. --- src/libopensc/pkcs15-cac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 9952135477..c6e3fc72b2 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -354,8 +354,10 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) cert_out->key = NULL; fail: sc_pkcs15_free_certificate(cert_out); - if (r < 0) + if (r < 0) { + (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ + } } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); From e926cd637a78bd8e75c65f4d8d835a6aeba93f3b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 4 Feb 2022 11:49:23 +0100 Subject: [PATCH 2260/4321] Clear p15card in sc_pkcs15emu_*_init in case of failure --- src/libopensc/pkcs15-actalis.c | 1 + src/libopensc/pkcs15-atrust-acos.c | 16 ++++++++++------ src/libopensc/pkcs15-cac.c | 3 +++ src/libopensc/pkcs15-coolkey.c | 2 ++ src/libopensc/pkcs15-din-66291.c | 4 +++- src/libopensc/pkcs15-dnie.c | 1 + src/libopensc/pkcs15-esinit.c | 5 ++++- src/libopensc/pkcs15-esteid.c | 15 +++++++++------ src/libopensc/pkcs15-esteid2018.c | 15 ++++++++++----- src/libopensc/pkcs15-gemsafeGPK.c | 23 ++++++++++++++++++----- src/libopensc/pkcs15-gemsafeV1.c | 25 ++++++++++++++++++------- src/libopensc/pkcs15-gids.c | 18 +++++++++++++----- src/libopensc/pkcs15-idprime.c | 14 +++++++++----- src/libopensc/pkcs15-itacns.c | 16 ++++++++++------ src/libopensc/pkcs15-jpki.c | 16 ++++++++++++---- src/libopensc/pkcs15-nqApplet.c | 10 +++++++--- src/libopensc/pkcs15-oberthur.c | 18 +++++++++++------- src/libopensc/pkcs15-openpgp.c | 10 +++++++--- src/libopensc/pkcs15-piv.c | 1 + src/libopensc/pkcs15-pteid.c | 1 + src/libopensc/pkcs15-sc-hsm.c | 22 +++++++++++++++++----- src/libopensc/pkcs15-starcert.c | 14 +++++++++----- src/libopensc/pkcs15-tccardos.c | 28 ++++++++++++++++++++-------- src/libopensc/pkcs15-tcos.c | 1 + src/libopensc/pkcs15-westcos.c | 1 + 25 files changed, 198 insertions(+), 82 deletions(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 8b87a6285c..05bbcac6df 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -223,6 +223,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) if (!cert || !compCert) { free(cert); free(compCert); + sc_pkcs15_card_clear(p15card); return SC_ERROR_OUT_OF_MEMORY; } diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index d8e2910309..56cb86ad81 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -161,13 +161,13 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) - return SC_ERROR_INTERNAL; + goto err; /* card label */ free(p15card->tokeninfo->label); p15card->tokeninfo->label = strdup(CARD_LABEL); if (!p15card->tokeninfo->label) - return SC_ERROR_INTERNAL; + goto err; /* set certs */ for (i = 0; certs[i].label; i++) { @@ -189,7 +189,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* set pins */ for (i = 0; pins[i].label; i++) { @@ -217,7 +217,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* set private keys */ for (i = 0; prkeys[i].label; i++) { @@ -241,19 +241,23 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* select the application DF */ sc_format_path("DF71", &path); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS || !file) - return SC_ERROR_INTERNAL; + goto err; /* set the application DF */ sc_file_free(p15card->file_app); p15card->file_app = file; return SC_SUCCESS; + +err: + sc_pkcs15_card_clear(p15card); + return SC_ERROR_INTERNAL; } int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index c6e3fc72b2..1b66ee58e0 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -356,11 +356,14 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ } } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); + if (r < 0) + sc_pkcs15_card_clear(p15card); LOG_TEST_RET(card->ctx, r, "Can not finalize cert objects."); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index fb2390e124..93758bf69c 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -681,6 +681,8 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count); + if (r < 0) + sc_pkcs15_card_clear(p15card); LOG_TEST_RET(card->ctx, r, "Can not finalize objects."); /* Iterate over all the created objects and fill missing labels */ diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 116b136592..b1ec2d752c 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -106,8 +106,10 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) pin_obj.auth_id.len = 1; } - if (0 > sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info)) + if (0 > sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info)) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } } for (i = 0; i < 2; i++) { diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 92a602c53f..62f0feeee6 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -201,6 +201,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) rv = parse_odf(buf, len, p15card); if (rv != SC_SUCCESS) { sc_log(ctx, "Decoding of ODF failed: %d", rv); + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index cd36b3b134..3c16764766 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -66,8 +66,11 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); - if (!p15card->tokeninfo->manufacturer_id) + if (!p15card->tokeninfo->manufacturer_id) { + free(p15card->tokeninfo->serial_number); + p15card->tokeninfo->serial_number = NULL; return SC_ERROR_INTERNAL; + } return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 991dadf55f..db3de03b0f 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -85,14 +85,14 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label)); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; if (i != 0) continue; sc_pkcs15_cert_t *cert = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; if (cert->key->algorithm == SC_ALGORITHM_EC) field_length = cert->key->u.ec.params.field_length; else @@ -115,7 +115,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) sc_format_path ("3f000016", &tmppath); r = sc_select_file (card, &tmppath, NULL); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; /* add pins */ for (i = 0; i < 3; i++) { @@ -138,7 +138,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* read the number of tries left for the PIN */ r = sc_read_record (card, (unsigned int) i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); if (r < 6) - return SC_ERROR_INTERNAL; + goto err; pin_info.auth_id.len = 1; pin_info.auth_id.value[0] = esteid_pin_authid[i]; @@ -164,7 +164,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* add private keys */ @@ -205,10 +205,13 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) else r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } return SC_SUCCESS; +err: + sc_pkcs15_card_clear(p15card); + return SC_ERROR_INTERNAL; } int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 3c58f08941..3a18a8c190 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -81,7 +81,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { cert_info.id.len = 1; r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + goto err; // Read data from first cert if (i != 0) @@ -89,6 +89,8 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { sc_pkcs15_cert_t *cert = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + if (r < 0) + sc_pkcs15_card_clear(p15card); LOG_TEST_RET(card->ctx, r, "Could not read authentication certificate"); if (cert->key->algorithm == SC_ALGORITHM_EC) @@ -155,19 +157,19 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + goto err; } // trigger PIN counter refresh via pin_cmd struct sc_pkcs15_object *objs[3]; r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 3); if (r != 3) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + goto err; } for (i = 0; i < r; i++) { r = sc_pkcs15_get_pin_info(p15card, objs[i]); if (r < 0) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + goto err; } /* add private keys */ @@ -202,10 +204,13 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + goto err; } return SC_SUCCESS; +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index ff52a2e312..82429081cc 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -223,11 +223,15 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); - if (r != SC_SUCCESS) + if (r != SC_SUCCESS) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); - if (r != SC_SUCCESS) + if (r != SC_SUCCESS) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } set_string(&p15card->tokeninfo->serial_number, buf); /* test if we have a gemsafe app df */ @@ -243,8 +247,10 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) r = sc_select_file(card, &path, &file); } - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_WRONG_CARD; + } /* we will use dfpath in all other references */ dfpath = file->id; @@ -307,6 +313,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) path.value[3] = dfpath & 0xff; if (sc_select_file(card, &path, &file) < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_WRONG_CARD; } @@ -398,6 +405,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) { free(gsdata); + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; } @@ -406,6 +414,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); if (r < 0) { free(gsdata); + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; } @@ -457,8 +466,10 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) pin_obj.flags = pins[i].obj_flags; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } } /* needs work, as we may want to add more then one key */ @@ -501,8 +512,10 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id); r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } } return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 7379b6b38d..c12ef49db8 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -312,8 +312,11 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = strdup(DRIVER_SERIAL_NUMBER); - if (!p15card->tokeninfo->serial_number) + if (!p15card->tokeninfo->serial_number) { + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = NULL; return SC_ERROR_INTERNAL; + } /* the GemSAFE applet version number */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03); @@ -325,23 +328,29 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); + if (r < 0) + sc_pkcs15_card_clear(p15card); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) - return SC_ERROR_INTERNAL; - if (r != SC_SUCCESS) + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || r != SC_SUCCESS) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } /* the manufacturer ID, in this case GemPlus */ free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); - if (!p15card->tokeninfo->manufacturer_id) + if (!p15card->tokeninfo->manufacturer_id) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } /* determine allocated key containers and length of certificates */ r = gemsafe_get_cert_len(card); - if (r != SC_SUCCESS) + if (r != SC_SUCCESS) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } /* set certs */ sc_log(p15card->card->ctx, "Setting certificates"); @@ -420,8 +429,10 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) sc_log(p15card->card->ctx, "Selecting application DF"); sc_format_path(GEMSAFE_APP_PATH, &path); r = sc_select_file(card, &path, &file); - if (r != SC_SUCCESS || !file) + if (r != SC_SUCCESS || !file) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } /* set the application DF */ sc_file_free(p15card->file_app); p15card->file_app = file; diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index 5ab46ee020..04b57f4e74 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -136,8 +136,11 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) if (p15card->tokeninfo->label == NULL) { p15card->tokeninfo->label = strdup("GIDS card"); - if (p15card->tokeninfo->label == NULL) + if (p15card->tokeninfo->label == NULL) { + free(p15card->tokeninfo->serial_number); + p15card->tokeninfo->serial_number = NULL; LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } } if ((p15card->tokeninfo->manufacturer_id != NULL) && !strcmp("(unknown)", p15card->tokeninfo->manufacturer_id)) { @@ -147,8 +150,10 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) if (p15card->tokeninfo->manufacturer_id == NULL) { p15card->tokeninfo->manufacturer_id = strdup("www.mysmartlogon.com"); - if (p15card->tokeninfo->manufacturer_id == NULL) + if (p15card->tokeninfo->manufacturer_id == NULL) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } } if (p15card->card->type == SC_CARD_TYPE_GIDS_V2) { p15card->tokeninfo->version = 2; @@ -198,7 +203,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj"); + LOG_TEST_GOTO_ERR(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj"); if (has_puk) { pin_info.auth_id.value[0] = 0x81; @@ -209,11 +214,11 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) strlcpy(pin_obj.label, "PUK", sizeof(pin_obj.label)); pin_obj.auth_id.len = 0; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - LOG_TEST_RET(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj with PUK"); + LOG_TEST_GOTO_ERR(card->ctx, r, "unable to sc_pkcs15emu_add_pin_obj with PUK"); } r = sc_card_ctl(card, SC_CARDCTL_GIDS_GET_ALL_CONTAINERS, &recordsnum); - LOG_TEST_RET(card->ctx, r, "sc_card_ctl SC_CARDCTL_GIDS_GET_ALL_CONTAINERS"); + LOG_TEST_GOTO_ERR(card->ctx, r, "sc_card_ctl SC_CARDCTL_GIDS_GET_ALL_CONTAINERS"); for (i = 0; i < recordsnum; i++) { sc_cardctl_gids_get_container_t container; @@ -228,6 +233,9 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) sc_pkcs15emu_gids_add_prkey(p15card, &container); } return SC_SUCCESS; +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); } int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 2fce1b984b..ab9b2cf3c2 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -110,8 +110,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add pin object"); /* * get token name if provided @@ -133,7 +132,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) */ sc_log(card->ctx, "IDPrime adding certs, pub and priv keys..."); r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_INIT_GET_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not initiate cert objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not initiate cert objects."); for (i = 0; i < count; i++) { struct sc_pkcs15_prkey_info prkey_info; @@ -146,7 +145,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_cert_t *cert_out = NULL; r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, &prkey_info); - LOG_TEST_RET(card->ctx, r, "Can not get next object"); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object"); memset(&cert_info, 0, sizeof(cert_info)); memset(&pubkey_info, 0, sizeof(pubkey_info)); @@ -274,14 +273,19 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ } } r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not finalize cert objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize cert objects."); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); } int sc_pkcs15emu_idprime_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index afdf459c4e..eec17c1b49 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -825,7 +825,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) /* Data files */ r = itacns_add_data_files(p15card); - LOG_TEST_RET(p15card->card->ctx, r, + LOG_TEST_GOTO_ERR(p15card->card->ctx, r, "Could not add data files"); /*** Certificate and keys. ***/ @@ -833,7 +833,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS0", cns0_secenv, 0, "3F0011001101", "3F003F01", NULL, 0x10, &found_certs); - LOG_TEST_RET(p15card->card->ctx, r, + LOG_TEST_GOTO_ERR(p15card->card->ctx, r, "Could not add CNS0"); certificate_count += found_certs; @@ -841,7 +841,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS01", 0x21, 5, "3F002FFF8228", NULL, "3F002FFF0000", 0x10, &found_certs); - LOG_TEST_RET(p15card->card->ctx, r, + LOG_TEST_GOTO_ERR(p15card->card->ctx, r, "Could not add CNS01"); certificate_count += found_certs; @@ -849,7 +849,7 @@ static int itacns_init(sc_pkcs15_card_t *p15card) r = itacns_check_and_add_keyset(p15card, "CNS1", 0x10, 0, "3F0014009010", "3F00140081108010", "3F0014008110", 0x1a, &found_certs); - LOG_TEST_RET(p15card->card->ctx, r, + LOG_TEST_GOTO_ERR(p15card->card->ctx, r, "Could not add CNS1"); certificate_count += found_certs; @@ -861,10 +861,14 @@ static int itacns_init(sc_pkcs15_card_t *p15card) /* Back to Master File */ sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, NULL); - LOG_TEST_RET(p15card->card->ctx, r, + LOG_TEST_GOTO_ERR(p15card->card->ctx, r, "Could not select master file again"); - return r; + LOG_FUNC_RETURN(p15card->card->ctx, r); + +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(p15card->card->ctx, r); } int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index ead719f378..da2f8997e5 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -90,8 +90,10 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) cert_info.authority = jpki_cert_authority[i]; cert_obj.flags = jpki_cert_flags[i]; rc = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (rc < 0) + if (rc < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } } @@ -146,8 +148,10 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) pin_obj.flags = jpki_pin_flags[i]; rc = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (rc < 0) + if (rc < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } } /* add private keys */ @@ -182,8 +186,10 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; rc = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - if (rc < 0) + if (rc < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } } /* add public keys */ @@ -213,8 +219,10 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) pubkey_info.path.type = SC_PATH_TYPE_FILE_ID; rc = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); - if (rc < 0) + if (rc < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index f5fe0c7bae..c3c7e14113 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -193,7 +193,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) } rv = add_nqapplet_objects(p15card); - LOG_TEST_RET(ctx, rv, "Failed to add PKCS15"); + LOG_TEST_GOTO_ERR(ctx, rv, "Failed to add PKCS15"); if (aid != NULL) { struct sc_file *file = sc_file_new(); @@ -209,7 +209,8 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); if (p15card->tokeninfo == NULL) { - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "unable to create tokeninfo struct"); + rv = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, rv, "unable to create tokeninfo struct"); } else { char serial_hex[SC_MAX_SERIALNR * 2 + 2]; @@ -220,5 +221,8 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; } - return SC_SUCCESS; + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 6487656b97..efa4c8883d 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -1033,7 +1033,7 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) sc_format_path(AWP_PIN_DF, &path); rv = sc_select_file(card, &path, NULL); - LOG_TEST_RET(ctx, rv, "Oberthur init failed: cannot select PIN dir"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: cannot select PIN dir"); tries_left = -1; rv = sc_verify(card, SC_AC_CHV, sopin_reference, (unsigned char *)"", 0, &tries_left); @@ -1042,7 +1042,7 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) rv = sc_verify(card, SC_AC_CHV, sopin_reference, (unsigned char *)"", 0, &tries_left); } if (rv && rv != SC_ERROR_PIN_CODE_INCORRECT) - LOG_TEST_RET(ctx, rv, "Invalid state of SO-PIN"); + LOG_TEST_GOTO_ERR(ctx, rv, "Invalid state of SO-PIN"); /* add PIN */ memset(&auth_info, 0, sizeof(auth_info)); @@ -1071,7 +1071,7 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) sc_log(ctx, "Add PIN(%s,auth_id:%s,reference:%i)", obj.label, sc_pkcs15_print_id(&auth_info.auth_id), auth_info.attrs.pin.reference); rv = sc_pkcs15emu_add_pin_obj(p15card, &obj, &auth_info); - LOG_TEST_RET(ctx, rv, "Oberthur init failed: cannot add PIN object"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: cannot add PIN object"); tries_left = -1; rv = sc_verify(card, SC_AC_CHV, 0x81, (unsigned char *)"", 0, &tries_left); @@ -1115,10 +1115,10 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) sc_log(ctx, "Add PIN(%s,auth_id:%s,reference:%i)", obj.label, sc_pkcs15_print_id(&auth_info.auth_id), auth_info.attrs.pin.reference); rv = sc_pkcs15emu_add_pin_obj(p15card, &obj, &auth_info); - LOG_TEST_RET(ctx, rv, "Oberthur init failed: cannot add PIN object"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: cannot add PIN object"); } else if (rv != SC_ERROR_DATA_OBJECT_NOT_FOUND) { - LOG_TEST_RET(ctx, rv, "Oberthur init failed: cannot verify PIN"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: cannot verify PIN"); } for (ii=0; oberthur_infos[ii].name; ii++) { @@ -1126,17 +1126,21 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) free(oberthur_infos[ii].content); rv = sc_oberthur_read_file(p15card, oberthur_infos[ii].path, &oberthur_infos[ii].content, &oberthur_infos[ii].len, 1); - LOG_TEST_RET(ctx, rv, "Oberthur init failed: read oberthur file error"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: read oberthur file error"); sc_log(ctx, "Oberthur init: parse %s file, content length %"SC_FORMAT_LEN_SIZE_T"u", oberthur_infos[ii].name, oberthur_infos[ii].len); rv = oberthur_infos[ii].parser(p15card, oberthur_infos[ii].content, oberthur_infos[ii].len, oberthur_infos[ii].postpone_allowed); - LOG_TEST_RET(ctx, rv, "Oberthur init failed: parse error"); + LOG_TEST_GOTO_ERR(ctx, rv, "Oberthur init failed: parse error"); } LOG_FUNC_RETURN(ctx, SC_SUCCESS); + +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 812b8ed829..9d00b75858 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -388,8 +388,10 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) cxdata[0], r); } - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } } } @@ -510,8 +512,10 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) cxdata[0], r); } - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; + } } } @@ -553,9 +557,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) sc_log(card->ctx, "Failed to initialize OpenPGP emulation: %s\n", sc_strerror(r)); + sc_pkcs15_card_clear(p15card); } sc_file_free(file); - LOG_FUNC_RETURN(ctx, r); } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index eab6cd065a..1789cd8357 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -1217,6 +1217,7 @@ sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { sc_pkcs15_free_pubkey(ckis[i].pubkey_from_cert); } + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index 6960e36de6..1f4ca4531e 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -194,6 +194,7 @@ static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card) rv = parse_odf(buf, len, p15card); if (rv != SC_SUCCESS) { sc_log(ctx, "Decoding of ODF failed: %d", rv); + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 7cb751b5be..9d58271bbd 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -932,13 +932,17 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) } else { p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de"); } - if (p15card->tokeninfo->manufacturer_id == NULL) + if (p15card->tokeninfo->manufacturer_id == NULL) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } } appinfo->label = strdup(p15card->tokeninfo->label); - if (appinfo->label == NULL) + if (appinfo->label == NULL) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } len = strnlen(devcert.chr, sizeof devcert.chr); /* Strip last 5 digit sequence number from CHR */ assert(len >= 8); @@ -946,8 +950,10 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = calloc(len + 1, 1); - if (p15card->tokeninfo->serial_number == NULL) + if (p15card->tokeninfo->serial_number == NULL) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } memcpy(p15card->tokeninfo->serial_number, devcert.chr, len); *(p15card->tokeninfo->serial_number + len) = 0; @@ -979,8 +985,10 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE|SC_PKCS15_CO_FLAG_MODIFIABLE; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, r); + } memset(&pin_info, 0, sizeof(pin_info)); memset(&pin_obj, 0, sizeof(pin_obj)); @@ -1003,8 +1011,10 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) + if (r < 0) { + sc_pkcs15_card_clear(p15card); LOG_FUNC_RETURN(card->ctx, r); + } if (card->type == SC_CARD_TYPE_SC_HSM_SOC @@ -1033,6 +1043,8 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) filelistlength = sc_list_files(card, filelist, sizeof(filelist)); + if (filelistlength < 0) + sc_pkcs15_card_clear(p15card); LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier"); for (i = 0; i < filelistlength; i += 2) { diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 92e7e8e9d9..8897872908 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -175,7 +175,7 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); if (!p15card->tokeninfo->manufacturer_id) - return SC_ERROR_INTERNAL; + goto err; /* set certs */ for (i = 0; certs[i].label; i++) { @@ -197,7 +197,7 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* set pins */ for (i = 0; pins[i].label; i++) { @@ -226,7 +226,7 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* set private keys */ for (i = 0; prkeys[i].label; i++) { @@ -250,19 +250,23 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) - return SC_ERROR_INTERNAL; + goto err; } /* select the application DF */ sc_format_path("3F00DF01", &path); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS || !file) - return SC_ERROR_INTERNAL; + goto err; /* set the application DF */ sc_file_free(p15card->file_app); p15card->file_app = file; return SC_SUCCESS; + +err: + sc_pkcs15_card_clear(p15card); + return SC_ERROR_INTERNAL; } int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index dd8ad839d1..08d2fc12d3 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -325,26 +325,38 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card) return SC_ERROR_OUT_OF_MEMORY; /* set the manufacturer ID */ set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); - if (p15card->tokeninfo->manufacturer_id == NULL) - return SC_ERROR_OUT_OF_MEMORY; + if (p15card->tokeninfo->manufacturer_id == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } /* set the serial number */ r = sc_parse_ef_gdo(card, iccsn.value, &iccsn.len, NULL, 0); - if (r != SC_SUCCESS || iccsn.len < 5+8) - return SC_ERROR_INTERNAL; + if (r != SC_SUCCESS || iccsn.len < 5+8) { + r = SC_ERROR_INTERNAL; + goto err; + } sc_bin_to_hex(iccsn.value + 5, 8, hex_buf, sizeof(hex_buf), 0); set_string(&p15card->tokeninfo->serial_number, hex_buf); - if (p15card->tokeninfo->serial_number == NULL) - return SC_ERROR_OUT_OF_MEMORY; + if (p15card->tokeninfo->serial_number == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } /* select the application DF */ sc_format_path(TC_CARDOS_APP_DF, &path); r = sc_select_file(card, &path, &file); - if (r != SC_SUCCESS || file == NULL) - return SC_ERROR_INTERNAL; + if (r != SC_SUCCESS || file == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } /* set the application DF */ sc_file_free(p15card->file_app); p15card->file_app = file; return SC_SUCCESS; + +err: + sc_pkcs15_card_clear(p15card); + return r; } int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 74ae0cb92f..a78b9aee56 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -543,5 +543,6 @@ int sc_pkcs15emu_tcos_init_ex( if(!detect_signtrust(p15card)) return SC_SUCCESS; if(!detect_datev(p15card)) return SC_SUCCESS; + sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 9277061b80..492e1bce39 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -223,6 +223,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) } r = 0; out: + sc_pkcs15_card_clear(p15card); return r; } From dc706f99f803a44f574ddc843653f61ea02cca61 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 7 Feb 2022 10:32:36 +0100 Subject: [PATCH 2261/4321] Move ownership of buffer to pubkey object --- src/libopensc/pkcs15-cac.c | 2 ++ src/libopensc/pkcs15-idprime.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 1b66ee58e0..e9f3ea3d35 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -345,6 +345,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) free(pubkey_info.direct.spki.value); goto fail; } + pubkey_info.direct.spki.value = NULL; /* moved to the pubkey object on p15card */ + pubkey_info.direct.spki.len = 0; r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) goto fail; diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index ab9b2cf3c2..a71af3651f 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -262,6 +262,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) free(pubkey_info.direct.spki.value); goto fail; } + pubkey_info.direct.spki.value = NULL; /* moved to the pubkey object on p15card */ + pubkey_info.direct.spki.len = 0; sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) From eeec9a918ebc475a27b32fa9c296316e49acab71 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 10 Feb 2022 15:11:05 +0100 Subject: [PATCH 2262/4321] pkcs15: Fix clearing of p15card --- src/libopensc/pkcs15-cac.c | 28 ++++++++++++++-------------- src/libopensc/pkcs15-coolkey.c | 23 +++++++++++++---------- src/libopensc/pkcs15-esteid.c | 4 ++-- src/libopensc/pkcs15-idprime.c | 3 +-- src/libopensc/pkcs15-openpgp.c | 20 ++++++++++++-------- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index e9f3ea3d35..d65b732611 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -170,18 +170,17 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* get the ACA path in case it needs to be selected before PIN verify */ r = sc_card_ctl(card, SC_CARDCTL_CAC_GET_ACA_PATH, &pin_info.path); - if (r < 0) { - LOG_FUNC_RETURN(card->ctx, r); - } + if (r < 0) + goto err; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + goto err; } /* set other objects */ r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_INIT_GET_GENERIC_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not initiate generic objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not initiate generic objects."); for (i = 0; i < count; i++) { struct sc_pkcs15_data_info obj_info; @@ -189,17 +188,17 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_GET_NEXT_GENERIC_OBJECT, &obj_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + goto err; memset(&obj_obj, 0, sizeof(obj_obj)); memcpy(obj_obj.label, obj_info.app_label, sizeof(obj_obj.label)); r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + goto err; } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not finalize generic objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize generic objects."); /* * certs, pubkeys and priv keys are related and we assume @@ -209,7 +208,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) */ sc_log(card->ctx, "CAC adding certs, pub and priv keys..."); r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_INIT_GET_CERT_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not initiate cert objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not initiate cert objects."); for (i = 0; i < count; i++) { struct sc_pkcs15_data_info obj_info; @@ -358,17 +357,18 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); - sc_pkcs15_card_clear(p15card); - LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ + goto err; } } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); - if (r < 0) - sc_pkcs15_card_clear(p15card); - LOG_TEST_RET(card->ctx, r, "Can not finalize cert objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize cert objects."); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); } int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 93758bf69c..51f434deed 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -493,7 +493,6 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) * anyway */ p15card->opts.use_pin_cache = 0; - /* get the token info from the card */ r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_GET_TOKEN_INFO, p15card->tokeninfo); if (r < 0) { @@ -531,13 +530,14 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) pin_obj.flags = pins[i].obj_flags; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); + if (r < 0) { + goto err; + } } /* set other objects */ r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_INIT_GET_OBJECTS, &count); - LOG_TEST_RET(card->ctx, r, "Can not initiate objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not initiate objects."); sc_log(card->ctx, "Iterating over %d objects", count); for (i = 0; i < count; i++) { @@ -554,9 +554,9 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) size_t len; r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_GET_NEXT_OBJECT, &coolkey_obj); - if (r < 0) - LOG_FUNC_RETURN(card->ctx, r); - + if (r < 0) { + goto err; + } sc_log(card->ctx, "Loading object %d", i); memset(&obj_obj, 0, sizeof(obj_obj)); /* coolkey applets have label only on the certificates, @@ -681,9 +681,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count); - if (r < 0) - sc_pkcs15_card_clear(p15card); - LOG_TEST_RET(card->ctx, r, "Can not finalize objects."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize objects."); /* Iterate over all the created objects and fill missing labels */ for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { @@ -715,6 +713,11 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + +err: + sc_pkcs15_card_clear(p15card); + + LOG_FUNC_RETURN(card->ctx, r); } int diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index db3de03b0f..5a01f245b9 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -51,11 +51,11 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) /* Select application directory */ sc_format_path ("3f00eeee5044", &tmppath); r = sc_select_file (card, &tmppath, NULL); - LOG_TEST_RET(card->ctx, r, "select esteid PD failed"); + LOG_TEST_GOTO_ERR(card->ctx, r, "select esteid PD failed"); /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); - LOG_TEST_RET(card->ctx, r, "read document number failed"); + LOG_TEST_GOTO_ERR(card->ctx, r, "read document number failed"); buff[MIN((size_t) r, (sizeof buff)-1)] = '\0'; set_string(&p15card->tokeninfo->serial_number, (const char *)buff); diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index a71af3651f..2e09d8e9ab 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -275,8 +275,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); - sc_pkcs15_card_clear(p15card); - LOG_FUNC_RETURN(card->ctx, r); /* should not fail */ + goto err; } } diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 9d00b75858..78255d3b61 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -212,7 +212,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (r != 7) { sc_log(ctx, "CHV status bytes have unexpected length (expected 7, got %d)\n", r); - return SC_ERROR_OBJECT_NOT_VALID; + r = SC_ERROR_OBJECT_NOT_VALID; + goto failed; } /* Add PIN codes */ @@ -246,8 +247,10 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) - return SC_ERROR_INTERNAL; + if (r < 0) { + r = SC_ERROR_INTERNAL; + goto failed; + } } /* Get private key finger prints from DO 006E/0073/00C5: @@ -261,7 +264,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (r < 60) { sc_log(ctx, "finger print bytes have unexpected length (expected 60, got %d)\n", r); - return SC_ERROR_OBJECT_NOT_VALID; + r = SC_ERROR_OBJECT_NOT_VALID; + goto failed; } sc_log(ctx, "Adding private keys"); @@ -389,8 +393,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } if (r < 0) { - sc_pkcs15_card_clear(p15card); - return SC_ERROR_INTERNAL; + r = SC_ERROR_INTERNAL; + goto failed; } } } @@ -513,8 +517,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) } if (r < 0) { - sc_pkcs15_card_clear(p15card); - return SC_ERROR_INTERNAL; + r = SC_ERROR_INTERNAL; + goto failed; } } } From a3edb484f74bc008517c474e43d939b26ad5d38a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 10 Feb 2022 15:26:18 +0100 Subject: [PATCH 2263/4321] pkcs15: Add backup for file and pin cache --- src/libopensc/pkcs15-actalis.c | 5 ++++- src/libopensc/pkcs15-coolkey.c | 2 ++ src/libopensc/pkcs15-dnie.c | 25 +++++++++++++++++-------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 05bbcac6df..a3fc27b305 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -141,6 +141,8 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) int r; #ifdef ENABLE_ZLIB + int use_file_cache_backup = p15card->opts.use_file_cache; + int i = 0, j = 0; const char *certLabel[] = { "User Non-repudiation Certificate", /* "User Non-repudiation Certificate" */ @@ -165,7 +167,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) const char *authPRKEY = "Authentication Key"; /* const char *nonrepPRKEY = "Non repudiation Key"; */ - + p15card->opts.use_file_cache = 1; /* Get Serial number */ @@ -224,6 +226,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) free(cert); free(compCert); sc_pkcs15_card_clear(p15card); + p15card->opts.use_file_cache = use_file_cache_backup; return SC_ERROR_OUT_OF_MEMORY; } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 51f434deed..b29e11e418 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -461,6 +461,7 @@ coolkey_get_public_key(sc_pkcs15_card_t *p15card, sc_cardctl_coolkey_object_t *o static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) { + int use_pin_cache_backup = p15card->opts.use_pin_cache; static const pindata pins[] = { { "1", NULL, "", 0x00, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, @@ -716,6 +717,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) err: sc_pkcs15_card_clear(p15card); + p15card->opts.use_pin_cache = use_pin_cache_backup; LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 62f0feeee6..0decdd05ee 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -143,6 +143,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) size_t len = sizeof(buf); int rv; struct sc_pkcs15_cert_info *p15_info = NULL; + int use_pin_cache_backup = p15card->opts.use_pin_cache; sc_context_t *ctx = p15card->card->ctx; LOG_FUNC_CALLED(ctx); @@ -171,38 +172,42 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) /* Set root path of this application */ sc_file_free(p15card->file_app); p15card->file_app = sc_file_new(); - if (NULL == p15card->file_app) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + if (NULL == p15card->file_app) { + rv = SC_ERROR_NOT_ENOUGH_MEMORY; + goto err; + } sc_format_path("3F00", &p15card->file_app->path); /* Load TokenInfo */ rv = dump_ef(p15card->card, "3F0050155032", buf, &len); if (rv != SC_SUCCESS) { sc_log(ctx, "Reading of EF.TOKENINFO failed: %d", rv); - LOG_FUNC_RETURN(ctx, rv); + goto err; } rv = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, p15card->tokeninfo, buf, len); if (rv != SC_SUCCESS) { sc_log(ctx, "Decoding of EF.TOKENINFO failed: %d", rv); - LOG_FUNC_RETURN(ctx, rv); + goto err; } /* Only accept the original stuff */ - if (strcmp(p15card->tokeninfo->manufacturer_id, "DGP-FNMT") != 0) - LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_CARD); + if (strcmp(p15card->tokeninfo->manufacturer_id, "DGP-FNMT") != 0) { + rv = SC_ERROR_WRONG_CARD; + goto err; + } /* Load ODF */ rv = dump_ef(p15card->card, "3F0050155031", buf, &len); if (rv != SC_SUCCESS) { sc_log(ctx, "Reading of ODF failed: %d", rv); - LOG_FUNC_RETURN(ctx, rv); + goto err; } rv = parse_odf(buf, len, p15card); if (rv != SC_SUCCESS) { sc_log(ctx, "Decoding of ODF failed: %d", rv); sc_pkcs15_card_clear(p15card); - LOG_FUNC_RETURN(ctx, rv); + goto err; } /* Decode EF.PrKDF, EF.PuKDF and EF.CDF */ @@ -271,6 +276,10 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) } LOG_FUNC_RETURN(ctx, SC_SUCCESS); + +err: + p15card->opts.use_pin_cache = use_pin_cache_backup; + LOG_FUNC_RETURN(ctx, rv); } #endif From 1a0135fcf7ae13f91b5e86b07fe014584c2320dc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 10 Feb 2022 16:35:19 +0100 Subject: [PATCH 2264/4321] pkcs15: Use set_string --- src/libopensc/pkcs15-atrust-acos.c | 11 +++++------ src/libopensc/pkcs15-din-66291.c | 3 ++- src/libopensc/pkcs15-esinit.c | 7 +++---- src/libopensc/pkcs15-gemsafeV1.c | 9 +++------ src/libopensc/pkcs15-nqApplet.c | 7 ++++--- src/libopensc/pkcs15-starcert.c | 8 ++++---- src/libopensc/pkcs15-westcos.c | 11 +++++------ 7 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index 56cb86ad81..6be9c7a64e 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -27,6 +27,7 @@ #include #include +#include "internal.h" #include "common/compat_strlcpy.h" #include "libopensc/pkcs15.h" #include "libopensc/cardctl.h" @@ -152,20 +153,18 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) r = sc_bin_to_hex(buf, 8, buf2, sizeof(buf2), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = strdup(buf2); + + set_string(&p15card->tokeninfo->serial_number, buf2); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; /* manufacturer ID */ - free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); + set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); if (!p15card->tokeninfo->manufacturer_id) goto err; /* card label */ - free(p15card->tokeninfo->label); - p15card->tokeninfo->label = strdup(CARD_LABEL); + set_string(&p15card->tokeninfo->label, CARD_LABEL); if (!p15card->tokeninfo->label) goto err; diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index b1ec2d752c..ef35c04eb8 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -23,6 +23,7 @@ #include #endif +#include "internal.h" #include "common/compat_strlcpy.h" #include "log.h" #include "pkcs15.h" @@ -256,7 +257,7 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid && SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serial)) { char serial_hex[SC_MAX_SERIALNR*2+2]; sc_bin_to_hex(serial.value, serial.len , serial_hex, sizeof serial_hex, 0); - p15card->tokeninfo->serial_number = strdup(serial_hex); + set_string(&p15card->tokeninfo->serial_number, serial_hex); } r = SC_SUCCESS; diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 3c16764766..81f88a471c 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -58,14 +58,13 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = strdup(buf); + + set_string(&p15card->tokeninfo->serial_number, buf); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ - free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); + set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); if (!p15card->tokeninfo->manufacturer_id) { free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = NULL; diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index c12ef49db8..add4c3e689 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -305,13 +305,11 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) sc_log(p15card->card->ctx, "Setting pkcs15 parameters"); - free(p15card->tokeninfo->label); - p15card->tokeninfo->label = strdup(APPLET_NAME); + set_string(&p15card->tokeninfo->label, APPLET_NAME); if (!p15card->tokeninfo->label) return SC_ERROR_INTERNAL; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = strdup(DRIVER_SERIAL_NUMBER); + set_string(&p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER); if (!p15card->tokeninfo->serial_number) { free(p15card->tokeninfo->label); p15card->tokeninfo->label = NULL; @@ -338,8 +336,7 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) } /* the manufacturer ID, in this case GemPlus */ - free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); + set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); if (!p15card->tokeninfo->manufacturer_id) { sc_pkcs15_card_clear(p15card); return SC_ERROR_INTERNAL; diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index c3c7e14113..ec15f0e521 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -21,6 +21,7 @@ #include #include +#include "internal.h" #include "opensc.h" #include "cards.h" #include "common/compat_strlcpy.h" @@ -215,9 +216,9 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) char serial_hex[SC_MAX_SERIALNR * 2 + 2]; sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial_hex, sizeof(serial_hex), 0); - p15card->tokeninfo->serial_number = strdup(serial_hex); - p15card->tokeninfo->label = strdup(name_Card); - p15card->tokeninfo->manufacturer_id = strdup(name_Vendor); + set_string(&p15card->tokeninfo->serial_number, serial_hex); + set_string(&p15card->tokeninfo->label, name_Card); + set_string(&p15card->tokeninfo->manufacturer_id, name_Vendor); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; } diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 8897872908..75c409503f 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -26,6 +26,7 @@ #include #include +#include "internal.h" #include "common/compat_strlcpy.h" #include "pkcs15.h" #include "cardctl.h" @@ -167,13 +168,12 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card) r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = strdup(buf); + + set_string(&p15card->tokeninfo->serial_number, buf); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ - free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = strdup(MANU_ID); + set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID); if (!p15card->tokeninfo->manufacturer_id) goto err; diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 492e1bce39..6c1660d0be 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -43,10 +43,9 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) r = sc_select_file(card, &path, NULL); if (r) goto out; - free(p15card->tokeninfo->label); - p15card->tokeninfo->label = strdup("westcos"); - free(p15card->tokeninfo->manufacturer_id); - p15card->tokeninfo->manufacturer_id = strdup("CEV"); + + set_string(&p15card->tokeninfo->label, "westcos"); + set_string(&p15card->tokeninfo->manufacturer_id, "CEV"); /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); @@ -55,8 +54,8 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r) goto out; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = strdup(buf); + + set_string(&p15card->tokeninfo->serial_number, buf); sc_format_path("AAAA", &path); r = sc_select_file(card, &path, NULL); if (r) From 6a7be63e38783b6086ced7950ed834bce46f3657 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 18 Feb 2022 11:17:29 +0100 Subject: [PATCH 2265/4321] Log errors --- src/libopensc/pkcs15-cac.c | 14 +++++--------- src/libopensc/pkcs15-coolkey.c | 8 ++------ src/libopensc/pkcs15-dnie.c | 28 +++++++++------------------- src/libopensc/pkcs15-esteid2018.c | 17 ++++++----------- src/libopensc/pkcs15-idprime.c | 2 +- 5 files changed, 23 insertions(+), 46 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index d65b732611..fceca06ac2 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -170,12 +170,10 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) /* get the ACA path in case it needs to be selected before PIN verify */ r = sc_card_ctl(card, SC_CARDCTL_CAC_GET_ACA_PATH, &pin_info.path); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get ACA path."); r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add pin object."); } /* set other objects */ @@ -187,15 +185,13 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object obj_obj; r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_GET_NEXT_GENERIC_OBJECT, &obj_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next generic object."); memset(&obj_obj, 0, sizeof(obj_obj)); memcpy(obj_obj.label, obj_info.app_label, sizeof(obj_obj.label)); r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize generic object."); } r = (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS, &count); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize generic objects."); @@ -357,7 +353,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, &count); - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add object."); } } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index b29e11e418..3062bea6ad 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -531,9 +531,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) pin_obj.flags = pins[i].obj_flags; r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) { - goto err; - } + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add pin object."); } /* set other objects */ @@ -555,9 +553,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) size_t len; r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_GET_NEXT_OBJECT, &coolkey_obj); - if (r < 0) { - goto err; - } + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object from card."); sc_log(card->ctx, "Loading object %d", i); memset(&obj_obj, 0, sizeof(obj_obj)); /* coolkey applets have label only on the certificates, diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 0decdd05ee..87bf449c30 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -174,41 +174,30 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) p15card->file_app = sc_file_new(); if (NULL == p15card->file_app) { rv = SC_ERROR_NOT_ENOUGH_MEMORY; - goto err; + LOG_TEST_GOTO_ERR(ctx, rv, "Can not create file."); } sc_format_path("3F00", &p15card->file_app->path); /* Load TokenInfo */ rv = dump_ef(p15card->card, "3F0050155032", buf, &len); - if (rv != SC_SUCCESS) { - sc_log(ctx, "Reading of EF.TOKENINFO failed: %d", rv); - goto err; - } + LOG_TEST_GOTO_ERR(ctx, rv, "Reading of EF.TOKENINFO failed."); + rv = sc_pkcs15_parse_tokeninfo(p15card->card->ctx, p15card->tokeninfo, buf, len); - if (rv != SC_SUCCESS) { - sc_log(ctx, "Decoding of EF.TOKENINFO failed: %d", rv); - goto err; - } + LOG_TEST_GOTO_ERR(ctx, rv, "Decoding of EF.TOKENINFO failed."); /* Only accept the original stuff */ if (strcmp(p15card->tokeninfo->manufacturer_id, "DGP-FNMT") != 0) { rv = SC_ERROR_WRONG_CARD; - goto err; + LOG_TEST_GOTO_ERR(ctx, rv, "Wrong card."); } /* Load ODF */ rv = dump_ef(p15card->card, "3F0050155031", buf, &len); - if (rv != SC_SUCCESS) { - sc_log(ctx, "Reading of ODF failed: %d", rv); - goto err; - } + LOG_TEST_GOTO_ERR(ctx, rv, "Reading of ODF failed."); + rv = parse_odf(buf, len, p15card); - if (rv != SC_SUCCESS) { - sc_log(ctx, "Decoding of ODF failed: %d", rv); - sc_pkcs15_card_clear(p15card); - goto err; - } + LOG_TEST_GOTO_ERR(ctx, rv, "Decoding of ODF failed."); /* Decode EF.PrKDF, EF.PuKDF and EF.CDF */ for (df = p15card->df_list; df != NULL; df = df->next) { @@ -278,6 +267,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card) LOG_FUNC_RETURN(ctx, SC_SUCCESS); err: + sc_pkcs15_card_clear(p15card); p15card->opts.use_pin_cache = use_pin_cache_backup; LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 3a18a8c190..c341ba9585 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -80,8 +80,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { cert_info.id.value[0] = esteid_cert_ids[i]; cert_info.id.len = 1; r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add cert oebjct"); // Read data from first cert if (i != 0) @@ -89,9 +88,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { sc_pkcs15_cert_t *cert = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); - if (r < 0) - sc_pkcs15_card_clear(p15card); - LOG_TEST_RET(card->ctx, r, "Could not read authentication certificate"); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not read authentication certificate"); if (cert->key->algorithm == SC_ALGORITHM_EC) field_length = cert->key->u.ec.params.field_length; @@ -156,20 +153,19 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add pin object"); } // trigger PIN counter refresh via pin_cmd struct sc_pkcs15_object *objs[3]; r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 3); if (r != 3) { + sc_log(card->ctx, "Can not get auth objects"); goto err; } for (i = 0; i < r; i++) { r = sc_pkcs15_get_pin_info(p15card, objs[i]); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not get pin object"); } /* add private keys */ @@ -203,8 +199,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); - if (r < 0) - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add private key object"); } return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 2e09d8e9ab..9fd41e2016 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -275,7 +275,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_free_certificate(cert_out); if (r < 0) { (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, &count); - goto err; + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add object."); } } From 0f7082ea46562b15221f428860b993e0519c6cbd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 16 Feb 2022 11:59:27 +0100 Subject: [PATCH 2266/4321] Fix usage of pointer after realloc --- src/sm/sm-iso.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 5baded77c6..2c3f6bcabd 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -181,13 +181,14 @@ static int format_le(size_t le, struct sc_asn1_entry *le_entry, static int prefix_buf(u8 prefix, u8 *buf, size_t buflen, u8 **cat) { - u8 *p; + u8 *p = NULL; + int ptr_same = *cat == buf; p = realloc(*cat, buflen + 1); if (!p) return SC_ERROR_OUT_OF_MEMORY; - if (*cat == buf) { + if (ptr_same) { memmove(p + 1, p, buflen); } else { /* Flawfinder: ignore */ From c438a5083293eab1ac5c62a87470262393cf0e86 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 21 Feb 2022 14:02:32 +0100 Subject: [PATCH 2267/4321] base64: Initialize variables --- src/libopensc/base64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/base64.c b/src/libopensc/base64.c index 4fe7989765..1aa1c941ee 100644 --- a/src/libopensc/base64.c +++ b/src/libopensc/base64.c @@ -150,8 +150,8 @@ int sc_base64_encode(const u8 *in, size_t len, u8 *out, size_t outlen, size_t li int sc_base64_decode(const char *in, u8 *out, size_t outlen) { - int len = 0, r, skip; - unsigned int i; + int len = 0, r = 0, skip = 0; + unsigned int i = 0; while ((r = from_base64(in, &i, &skip)) > 0) { int finished = 0, s = 16; From 258257eef0bc1092e01adb099a5b57e4272dd17e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 22 Dec 2021 00:06:40 +0100 Subject: [PATCH 2268/4321] update to new version of OpenPACE --- .appveyor.yml | 2 +- MacOSX/build-package.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 88b627e3d9..37c452403b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,7 +12,7 @@ environment: GH_TOKEN: secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY PATH: C:\cygwin\bin;%PATH% - OPENPACE_VER: 1.1.1 + OPENPACE_VER: 1.1.2 ZLIB_VER_DOT: 1.2.11 matrix: # not compatible with OpenSSL 1.1.1: diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 370e4b0df4..509fe0dfd4 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -63,7 +63,7 @@ export OBJCFLAGS=$CFLAGS if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then if ! test -e openpace; then - git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.1 + git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.2 fi cd openpace autoreconf -vis From 91e3f01dda21b4379d7c5ba26e47762797567854 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 22 Dec 2021 00:55:06 +0100 Subject: [PATCH 2269/4321] use openpace's object wrappers fixes https://github.com/OpenSC/OpenSC/issues/2354 --- configure.ac | 1 + src/sm/sm-eac.c | 5 +++++ src/tools/npa-tool.c | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/configure.ac b/configure.ac index 77cd62f14a..db27ae5c42 100644 --- a/configure.ac +++ b/configure.ac @@ -737,6 +737,7 @@ AC_MSG_CHECKING([for EAC_CTX_init_pace]) AC_TRY_LINK_FUNC(EAC_CTX_init_pace, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_WARN([Cannot link against libeac]) have_openpace="no" ]) +AC_CHECK_FUNCS([EAC_OBJ_nid2obj]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 397375fae2..d35bf2ab52 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -59,6 +59,7 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) #include #include #include +#include #include #include #include @@ -414,7 +415,11 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, } if (protocol) { +#ifndef HAVE_EAC_OBJ_NID2OBJ data->cryptographic_mechanism_reference = OBJ_nid2obj(protocol); +#else + data->cryptographic_mechanism_reference = EAC_OBJ_nid2obj(protocol); +#endif if (!data->cryptographic_mechanism_reference) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting Cryptographic mechanism reference of MSE:Set AT data"); r = SC_ERROR_INTERNAL; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 7db77fe70d..78a661d167 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -28,6 +28,7 @@ #include "sm/sslutil.h" #include "util.h" #include +#include #include #include #include @@ -258,7 +259,11 @@ static int add_to_ASN1_AUXILIARY_DATA_NPA_TOOL( goto err; } +#ifndef HAVE_EAC_OBJ_NID2OBJ template->type = OBJ_nid2obj(nid); +#else + template->type = EAC_OBJ_nid2obj(nid); +#endif if (!template->type) { r = SC_ERROR_INTERNAL; goto err; From 0e7bc541c09efa06b3c879ca0ca878d0ea54315e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 22 Dec 2021 10:30:58 +0100 Subject: [PATCH 2270/4321] iso7816: relax error handling when reading by sfid assume success if we were able to read at least some amount of data --- src/libopensc/iso7816.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 3c54266db1..8f0499eadd 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1386,11 +1386,13 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, *ef_len += r; break; } - if (r == 0 || r == SC_ERROR_FILE_END_REACHED) - break; - if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF."); - goto err; + if (r <= 0) { + if (*ef_len > 0) + break; + else { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF."); + goto err; + } } *ef_len += r; From ae2e4df6ae025e588600516a88e3deea325a7333 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 22 Dec 2021 10:38:25 +0100 Subject: [PATCH 2271/4321] npa-tool: some more hints about MRTDs --- doc/tools/npa-tool.1.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/tools/npa-tool.1.xml b/doc/tools/npa-tool.1.xml index 8dcf07ffdf..229504abd1 100644 --- a/doc/tools/npa-tool.1.xml +++ b/doc/tools/npa-tool.1.xml @@ -28,6 +28,11 @@ stored on the German eID card (neuer Personalausweis, nPA), and to perform some write and verification operations. + + Extended Access Control version 2 is performed according to ICAO Doc + 9303 or BSI TR-03110 so that other identity cards and machine + readable travel documents (MRTDs) may be read as well. + From e899b3ac33a04cf4cc01618f9877a213a3f47979 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 22 Dec 2021 16:27:24 +0100 Subject: [PATCH 2272/4321] call EAC_init() when needed EAC_init() should be called before actually using OpenPACE. Move EAC_init() to sm-eac.c so that it is not in responsibility of the card driver anymore. The card driver, however, still needs to call EAC_init() if it uses any OpenPACE specific code. Note that mulitple calls of EAC_init() are allowed and don't add any overhead. --- src/libopensc/card-edo.c | 12 ------------ src/sm/sm-eac.c | 2 ++ src/tools/goid-tool.c | 3 --- src/tools/sceac-example.c | 5 ----- 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-edo.c b/src/libopensc/card-edo.c index e00d4e88d7..3306f9c060 100644 --- a/src/libopensc/card-edo.c +++ b/src/libopensc/card-edo.c @@ -59,16 +59,6 @@ static struct { }; -static void edo_eac_init() { - extern void EAC_init(void); - static int initialized = 0; - if (!initialized) { - EAC_init(); - initialized = 1; - } -} - - static int edo_match_card(sc_card_t* card) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (_sc_match_atr(card, edo_atrs, &card->type) >= 0) { @@ -291,8 +281,6 @@ static int edo_set_security_env(struct sc_card* card, const struct sc_security_e static int edo_init(sc_card_t* card) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - edo_eac_init(); - memset(&card->sm_ctx, 0, sizeof card->sm_ctx); card->max_send_size = SC_MAX_APDU_RESP_SIZE; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index d35bf2ab52..8f8c3b30ef 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1141,6 +1141,7 @@ int perform_pace(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "EF.CardAccess", pace_output->ef_cardaccess, pace_output->ef_cardaccess_length); + EAC_init(); eac_ctx = EAC_CTX_new(); if (!eac_ctx || !EAC_CTX_init_ef_cardaccess(pace_output->ef_cardaccess, @@ -1525,6 +1526,7 @@ int perform_terminal_authentication(sc_card_t *card, * seems valid. */ card->caps |= SC_CARD_CAP_APDU_EXT; + EAC_init(); eac_ctx = EAC_CTX_new(); if (!eac_ctx || !EAC_CTX_init_ef_cardaccess(ef_cardaccess, diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 17a551abb6..e6a3bd041d 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -598,9 +598,6 @@ int paccess_main(struct sc_context *ctx, sc_card_t *card, struct gengetopt_args_ } } -#ifdef ENABLE_OPENPACE - EAC_init(); -#endif SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, perform_terminal_authentication(card, (const unsigned char **) certs, certs_lens, diff --git a/src/tools/sceac-example.c b/src/tools/sceac-example.c index 2a1521426f..15f1b526d6 100644 --- a/src/tools/sceac-example.c +++ b/src/tools/sceac-example.c @@ -80,10 +80,6 @@ main (int argc, char **argv) exit(1); } - /* initialize OpenPACE */ - EAC_init(); - - /* Now we try to change the PIN. Therefore we need to establish a SM channel * with PACE. * @@ -135,7 +131,6 @@ main (int argc, char **argv) sc_reset(card, 1); sc_disconnect_card(card); sc_release_context(ctx); - EAC_cleanup(); return -r; } From 305cee54d1ede6e3e8fd62b9efb21d2cf92a8d3f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 Feb 2022 12:25:18 +0100 Subject: [PATCH 2273/4321] rewrite to fix coverity warning (false positive) fixes coverity 376511 String not null terminated --- src/tools/pkcs15-tool.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index f4900be4e8..abd77e491b 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1002,12 +1002,13 @@ static int read_ssh_key(void) if (pubkey->algorithm == SC_ALGORITHM_EDDSA) { // SSH supports only ed25519 key now - char alg[20]; + const char alg[] = "ssh-ed25519"; /* Large enough to fit the following: * 2 x 4B item length headers * max 11B algorithm name, 32B key data */ unsigned char buf[64]; - unsigned int len, n; + unsigned int n; + int len; n = pubkey->u.eddsa.pubkey.len; if (n != 32) { @@ -1015,12 +1016,12 @@ static int read_ssh_key(void) goto fail2; } + len = strlen(alg); buf[0] = 0; buf[1] = 0; buf[2] = 0; - len = snprintf((char *) buf+4, 20, "ssh-ed25519"); - memcpy(alg, buf+4, 20); buf[3] = len; + memcpy(buf+4, alg, len); len += 4; buf[len++] = 0; @@ -1051,7 +1052,8 @@ static int read_ssh_key(void) * 3 x 4B item length headers * max 20B algorithm name, 9B curve name, max 256B key data */ unsigned char buf[300]; - unsigned int i, len, tmp, n; + unsigned int i, tmp, n; + int len; for (n = 0,i = 0; ec_curves[i].curve_name != NULL; i++) { if(sc_compare_oid (&ec_curves[i].curve_oid,&pubkey->u.ec.params.id)) @@ -1066,14 +1068,18 @@ static int read_ssh_key(void) goto fail2; } + len = snprintf(alg, sizeof alg, "ecdsa-sha2-nistp%d", n); + if (len < 0) { + fprintf(stderr, "failed to write algorithm\n"); + goto fail2; + } buf[0] = 0; buf[1] = 0; buf[2] = 0; - len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n); - memcpy(alg, buf+4, 20); buf[3] = len; - + memcpy(buf+4, alg, len); len += 4; + buf[len++] = 0; buf[len++] = 0; buf[len++] = 0; From 17af54a0a426e2963fb6eb2b8928be6676ab5337 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 Feb 2022 14:17:00 +0100 Subject: [PATCH 2274/4321] cryptoflex-tool: fixed returning value regression of 08ab72d50 fixes coverity CID 374952 (#1 of 1): Parse warning (PW.PARAM_SET_BUT_NOT_USED) --- src/tools/cryptoflex-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index e4484a7dd6..d28dd9ba02 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -265,7 +265,7 @@ static int parse_public_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) return 0; } -static int gen_d(BIGNUM *rsa_d_new, const BIGNUM *rsa_p, const BIGNUM *rsa_q, const BIGNUM *rsa_n, const BIGNUM *rsa_e) +static int gen_d(BIGNUM **rsa_d_new, const BIGNUM *rsa_p, const BIGNUM *rsa_q, const BIGNUM *rsa_n, const BIGNUM *rsa_e) { BN_CTX *bnctx; BIGNUM *r0, *r1, *r2; @@ -281,7 +281,7 @@ static int gen_d(BIGNUM *rsa_d_new, const BIGNUM *rsa_p, const BIGNUM *rsa_q, co BN_sub(r1, rsa_p, BN_value_one()); BN_sub(r2, rsa_q, BN_value_one()); BN_mul(r0, r1, r2, bnctx); - if ((rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) { + if ((*rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) { fprintf(stderr, "BN_mod_inverse() failed.\n"); return -1; } @@ -352,7 +352,7 @@ static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) if (RSA_set0_factors(rsa, bn_p, q) != 1 || RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1 || - gen_d(rsa_d, bn_p, q, rsa_n, rsa_e) != 0) + gen_d(&rsa_d, bn_p, q, rsa_n, rsa_e) != 0) return -1; /* RSA_set0_key will free previous value, and replace with new value @@ -375,7 +375,7 @@ static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) } OSSL_PARAM_get_BN(e, &rsa_e); OSSL_PARAM_get_BN(n, &rsa_n); - gen_d(rsa_d, bn_p, q, rsa_n, rsa_e); + gen_d(&rsa_d, bn_p, q, rsa_n, rsa_e); /* Merge params*/ if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_BN(bld, "d", rsa_d) != 1 || From 3a8263f92bbc98c274f2893281a06f031ba27b06 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 Feb 2022 14:22:14 +0100 Subject: [PATCH 2275/4321] fixed coverity CID 374950 (#1 of 1): Logically dead code (DEADCODE) regression of f214e655b --- src/pkcs15init/pkcs15-westcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 63a96656db..bc1130c878 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -238,7 +238,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); mem = BIO_new(BIO_s_mem()); bn = BN_new(); - if (pctx == NULL || key == NULL || mem == NULL || bn == NULL) { + if (pctx == NULL || mem == NULL || bn == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } From cacc881ed8fe612a9d60b862edb27070d4c6ba94 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 Feb 2022 14:27:14 +0100 Subject: [PATCH 2276/4321] fixed CID 374849 (#1 of 1): Unchecked return value (CHECKED_RETURN) --- src/libopensc/card-epass2003.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index e362eddd75..7efa339746 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -433,8 +433,8 @@ openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length, } EVP_MD_CTX_init(ctx); - EVP_DigestInit_ex(ctx, digest, NULL); - if (!EVP_DigestUpdate(ctx, input, length)) { + if (!EVP_DigestInit_ex(ctx, digest, NULL) + || !EVP_DigestUpdate(ctx, input, length)) { r = SC_ERROR_INTERNAL; goto err; } From a06abbf5a767a97a9627d5f786dd0d404c6cb8a0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 23 Feb 2022 15:19:59 +0100 Subject: [PATCH 2277/4321] pcsc: don't use a shorthand array of interpreting tlv data fixes CID 367426 (#1 of 1): Out-of-bounds access (ARRAY_VS_SINGLETON) note that structure padding could still happen inside PCSC_TLV_STRUCTURE. However, we're keeping consistency with libccid, which, too, doesn't use `__attribute__((packed))` for this --- src/libopensc/reader-pcsc.c | 84 ++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index d1706f83bb..0882e2aef3 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1135,19 +1135,8 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) sc_context_t *ctx = reader->ctx; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data; struct pcsc_private_data *priv = reader->drv_data; - DWORD rcount, feature_len, i; - PCSC_TLV_STRUCTURE *pcsc_tlv; - union { - PCSC_TLV_STRUCTURE msg; - u8 buf[256]; - } feature_buf; - union { -#ifdef PIN_PROPERTIES_v5 - PIN_PROPERTIES_STRUCTURE_v5 capsv5; -#endif - PIN_PROPERTIES_STRUCTURE caps; - u8 buf[SC_MAX_APDU_BUFFER_SIZE]; - } rbuf; + DWORD rcount, i; + u8 buf[256]; LONG rv; const char *log_disabled = "but it's disabled in configuration file"; int id_vendor = 0, id_product = 0; @@ -1159,44 +1148,41 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) if (gpriv->SCardControl == NULL) return; - rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf.buf, sizeof(feature_buf.buf), &feature_len); + rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, buf, sizeof(buf), &rcount); if (rv != SCARD_S_SUCCESS) { PCSC_TRACE(reader, "SCardControl failed", rv); return; } - if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0 - || feature_len > sizeof(feature_buf.buf)) { + if ((rcount % sizeof(PCSC_TLV_STRUCTURE)) != 0 + || rcount > sizeof buf) { sc_log(ctx, "Inconsistent TLV from reader!"); return; } - /* get the number of elements instead of the complete size */ - feature_len /= sizeof(PCSC_TLV_STRUCTURE); - - pcsc_tlv = &feature_buf.msg; - for (i = 0; i < feature_len; i++) { - sc_log(ctx, "Reader feature %02x found", pcsc_tlv[i].tag); - if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT) { - priv->verify_ioctl = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_START) { - priv->verify_ioctl_start = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_FINISH) { - priv->verify_ioctl_finish = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT) { - priv->modify_ioctl = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_START) { - priv->modify_ioctl_start = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) { - priv->modify_ioctl_finish = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) { - priv->pin_properties_ioctl = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_GET_TLV_PROPERTIES) { - priv->get_tlv_properties = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_EXECUTE_PACE) { - priv->pace_ioctl = ntohl(pcsc_tlv[i].value); + for (i = 0; i < rcount; i += sizeof(PCSC_TLV_STRUCTURE)) { + PCSC_TLV_STRUCTURE *pcsc_tlv = (PCSC_TLV_STRUCTURE *)(buf+i); + sc_log(ctx, "Reader feature %02x found", pcsc_tlv->tag); + if (pcsc_tlv->tag == FEATURE_VERIFY_PIN_DIRECT) { + priv->verify_ioctl = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_VERIFY_PIN_START) { + priv->verify_ioctl_start = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_VERIFY_PIN_FINISH) { + priv->verify_ioctl_finish = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_MODIFY_PIN_DIRECT) { + priv->modify_ioctl = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_MODIFY_PIN_START) { + priv->modify_ioctl_start = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_MODIFY_PIN_FINISH) { + priv->modify_ioctl_finish = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_IFD_PIN_PROPERTIES) { + priv->pin_properties_ioctl = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_GET_TLV_PROPERTIES) { + priv->get_tlv_properties = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_EXECUTE_PACE) { + priv->pace_ioctl = ntohl(pcsc_tlv->value); } else { - sc_log(ctx, "Reader feature %02x is not supported", pcsc_tlv[i].tag); + sc_log(ctx, "Reader feature %02x is not supported", pcsc_tlv->tag); } } @@ -1234,13 +1220,13 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) /* Detect display */ if (priv->pin_properties_ioctl) { - rcount = sizeof(rbuf.buf); + rcount = sizeof(buf); rv = gpriv->SCardControl(card_handle, priv->pin_properties_ioctl, - NULL, 0, rbuf.buf, sizeof(rbuf.buf), &rcount); + NULL, 0, buf, sizeof(buf), &rcount); if (rv == SCARD_S_SUCCESS) { #ifdef PIN_PROPERTIES_v5 if (rcount == sizeof(PIN_PROPERTIES_STRUCTURE_v5)) { - PIN_PROPERTIES_STRUCTURE_v5 *caps = &rbuf.capsv5; + PIN_PROPERTIES_STRUCTURE_v5 *caps = (PIN_PROPERTIES_STRUCTURE_v5 *) &buf; if (caps->wLcdLayout > 0) { sc_log(ctx, "Reader has a display: %04X", caps->wLcdLayout); reader->capabilities |= SC_READER_CAP_DISPLAY; @@ -1249,7 +1235,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } #endif if (rcount == sizeof(PIN_PROPERTIES_STRUCTURE)) { - PIN_PROPERTIES_STRUCTURE *caps = &rbuf.caps; + PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *) buf; if (caps->wLcdLayout > 0) { sc_log(ctx, "Reader has a display: %04X", caps->wLcdLayout); reader->capabilities |= SC_READER_CAP_DISPLAY; @@ -1308,13 +1294,13 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } if(gpriv->SCardGetAttrib != NULL) { - rcount = sizeof(rbuf.buf); + rcount = sizeof(buf); if (gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_NAME, - rbuf.buf, &rcount) == SCARD_S_SUCCESS + buf, &rcount) == SCARD_S_SUCCESS && rcount > 0) { /* add NUL termination, just in case... */ - rbuf.buf[(sizeof rbuf.buf)-1] = '\0'; - reader->vendor = strdup((char *) rbuf.buf); + buf[(sizeof buf)-1] = '\0'; + reader->vendor = strdup((char *) buf); } rcount = sizeof i; From e90dec08cf1ed2cad8861ecfd16ec7a2a3927e20 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 16:01:00 +0100 Subject: [PATCH 2278/4321] gpk: Remove DSA support Remove gpk_encode_dsa_key() and support for DSA algorithm --- src/libopensc/card-gpk.c | 5 ---- src/pkcs15init/pkcs15-gpk.c | 58 ------------------------------------- 2 files changed, 63 deletions(-) diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 983ab5b5de..34bfaa727f 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -186,11 +186,6 @@ gpk_init(sc_card_t *card) priv->offset_shift = 0; priv->offset_mask = 0; } - if (info[12] & 0x10) { - /* DSA supported - add algo information. - * It's highly unlikely we'll ever see this. - */ - } if (info[12] & 0x08) { priv->locked = 1; } diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 54cd1d461e..5b6e89ffb0 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -81,9 +81,6 @@ static int gpk_pkfile_create(sc_profile_t *, sc_pkcs15_card_t *, sc_file_t *); static int gpk_encode_rsa_key(sc_profile_t *, sc_card_t *, struct sc_pkcs15_prkey_rsa *, struct pkdata *, struct sc_pkcs15_prkey_info *); -static int gpk_encode_dsa_key(sc_profile_t *, sc_card_t *, - struct sc_pkcs15_prkey_dsa *, struct pkdata *, - struct sc_pkcs15_prkey_info *); static int gpk_store_pk(struct sc_profile *, sc_pkcs15_card_t *, sc_file_t *, struct pkdata *); static int gpk_init_pinfile(sc_profile_t *, sc_pkcs15_card_t *, sc_file_t *); @@ -433,8 +430,6 @@ gpk_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_objec switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: algo = SC_ALGORITHM_RSA; break; - case SC_PKCS15_TYPE_PRKEY_DSA: - algo = SC_ALGORITHM_DSA; break; default: sc_log(p15card->card->ctx, "Unsupported public key algorithm"); return SC_ERROR_NOT_SUPPORTED; @@ -489,10 +484,6 @@ gpk_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, &data, key_info); break; - case SC_ALGORITHM_DSA: - r = gpk_encode_dsa_key(profile, p15card->card, &key->u.dsa, - &data, key_info); - break; default: return SC_ERROR_NOT_SUPPORTED; } @@ -617,7 +608,6 @@ gpk_pkfile_keyalgo(unsigned int algo, unsigned char *p) { switch (algo) { case SC_ALGORITHM_RSA: *p = 0x00; return 0; - case SC_ALGORITHM_DSA: *p = 0x01; return 0; } return SC_ERROR_NOT_SUPPORTED; } @@ -1000,54 +990,6 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, return 0; } -/* - * Encode a DSA key. - * Confusingly, the GPK manual says that the GPK8000 can handle - * DSA with 512 as well as 1024 bits, but all byte sizes shown - * in the tables are 512 bits only... - */ -static int gpk_encode_dsa_key(sc_profile_t *profile, sc_card_t *card, - struct sc_pkcs15_prkey_dsa *dsa, struct pkdata *p, - sc_pkcs15_prkey_info_t *info) -{ - if (!dsa->p.len || !dsa->q.len || !dsa->g.len - || !dsa->pub.len || !dsa->priv.len) { - sc_log(card->ctx, - "incomplete DSA public key"); - return SC_ERROR_INVALID_ARGUMENTS; - } - - memset(p, 0, sizeof(*p)); - p->algo = SC_ALGORITHM_RSA; - p->usage = info->usage; - p->bytes = dsa->q.len; - p->bits = dsa->q.len << 3; - - /* Make sure the key is either 512 or 1024 bits */ - if (p->bytes <= 64) { - p->bits = 512; - p->bytes = 64; - } else if (p->bytes <= 128) { - p->bits = 1024; - p->bytes = 128; - } else { - sc_log(card->ctx, - "incompatible DSA key size (%u bits)", p->bits); - return SC_ERROR_INVALID_ARGUMENTS; - } - - /* Set up the list of public elements */ - gpk_add_bignum(&p->_public, 0x09, &dsa->p, 0); - gpk_add_bignum(&p->_public, 0x0a, &dsa->q, 0); - gpk_add_bignum(&p->_public, 0x0b, &dsa->g, 0); - gpk_add_bignum(&p->_public, 0x0c, &dsa->pub, 0); - - /* Set up the list of private elements */ - gpk_add_bignum(&p->_private, 0x0d, &dsa->priv, 0); - - return 0; -} - static int gpk_store_pk(struct sc_profile *profile, sc_pkcs15_card_t *p15card, sc_file_t *file, struct pkdata *p) From 8571519b567d2e2a0199d0b0e17702d076aa17e3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 16:17:17 +0100 Subject: [PATCH 2279/4321] pkcs15-oberthur.c: Remove support for DSA in cosm_new_file() It is never called with `type` argument of value SC_PKCS15_TYPE_PUBKEY_DSA --- src/pkcs15init/pkcs15-oberthur.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 98a61d5aa1..047683bf3c 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -497,10 +497,6 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, _template = "template-public-key"; structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; break; - case SC_PKCS15_TYPE_PUBKEY_DSA: - desc = "DSA public key"; - _template = "template-public-key"; - break; case SC_PKCS15_TYPE_CERT: desc = "certificate"; _template = "template-certificate"; From 0c1c3df7338498616bbd4dbb5f64e1b3d5048e5b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 16:21:34 +0100 Subject: [PATCH 2280/4321] pkcs15-epass2003.c: Remove template for DSA public key --- src/pkcs15init/pkcs15-epass2003.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 44fc9c2dd6..74d8ba2639 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -336,10 +336,6 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, _template = "public-key"; structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; break; - case SC_PKCS15_TYPE_PUBKEY_DSA: - desc = "DSA public key"; - _template = "public-key"; - break; case SC_PKCS15_TYPE_PRKEY: desc = "extractable private key"; _template = "extractable-key"; From db49a7661e214bb5686accec6683788e1c56fe76 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 16:59:57 +0100 Subject: [PATCH 2281/4321] pkcs15-lib.c: Remove support for DSA SC_ALGORITHM_DSA --- src/pkcs15init/pkcs15-lib.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index ee1a200604..0d66a3b985 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1759,12 +1759,6 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile keybits = sc_pkcs15init_keybits(&key.u.rsa.modulus); type = SC_PKCS15_TYPE_PUBKEY_RSA; break; -#ifdef SC_PKCS15_TYPE_PUBKEY_DSA - case SC_ALGORITHM_DSA: - keybits = sc_pkcs15init_keybits(&key.u.dsa.q); - type = SC_PKCS15_TYPE_PUBKEY_DSA; - break; -#endif case SC_ALGORITHM_GOSTR3410: keybits = SC_PKCS15_GOSTR3410_KEYSIZE; type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; @@ -2546,7 +2540,6 @@ prkey_fixup(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key) switch (key->algorithm) { case SC_ALGORITHM_RSA: return prkey_fixup_rsa(p15card, &key->u.rsa); - case SC_ALGORITHM_DSA: case SC_ALGORITHM_GOSTR3410: /* for now */ return 0; @@ -2563,8 +2556,6 @@ prkey_bits(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key) switch (key->algorithm) { case SC_ALGORITHM_RSA: return sc_pkcs15init_keybits(&key->u.rsa.modulus); - case SC_ALGORITHM_DSA: - return sc_pkcs15init_keybits(&key->u.dsa.q); case SC_ALGORITHM_GOSTR3410: if (sc_pkcs15init_keybits(&key->u.gostr3410.d) > SC_PKCS15_GOSTR3410_KEYSIZE) { sc_log(ctx, @@ -2595,8 +2586,6 @@ key_pkcs15_algo(struct sc_pkcs15_card *p15card, unsigned int algorithm) switch (algorithm) { case SC_ALGORITHM_RSA: return SC_PKCS15_TYPE_PRKEY_RSA; - case SC_ALGORITHM_DSA: - return SC_PKCS15_TYPE_PRKEY_DSA; case SC_ALGORITHM_GOSTR3410: return SC_PKCS15_TYPE_PRKEY_GOSTR3410; case SC_ALGORITHM_EC: @@ -2680,8 +2669,6 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof /* Skip silently if key is not initialized. */ if (pubkey->algorithm == SC_ALGORITHM_RSA && !pubkey->u.rsa.modulus.len) goto done; - else if (pubkey->algorithm == SC_ALGORITHM_DSA && !pubkey->u.dsa.pub.data) - goto done; else if (pubkey->algorithm == SC_ALGORITHM_GOSTR3410 && !pubkey->u.gostr3410.xy.data) goto done; @@ -2697,8 +2684,6 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof case SC_PKCS15INIT_ID_STYLE_MOZILLA: if (pubkey->algorithm == SC_ALGORITHM_RSA) SHA1(pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len, id.value); - else if (pubkey->algorithm == SC_ALGORITHM_DSA) - SHA1(pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len, id.value); else if (pubkey->algorithm == SC_ALGORITHM_EC) /* ID should be SHA1 of the X coordinate according to PKCS#15 v1.1 */ /* skip the 04 tag and get the X component */ From b7855bddad3abc13bda5b565a1a2c9fd95e6668f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 17:26:05 +0100 Subject: [PATCH 2282/4321] profile.c: Remove DSA access flags --- src/pkcs15init/profile.c | 4 +--- src/pkcs15init/profile.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 3a6dd6eab1..f476c3f256 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -50,7 +50,6 @@ #include "profile.h" #define DEF_PRKEY_RSA_ACCESS 0x1D -#define DEF_PRKEY_DSA_ACCESS 0x12 #define DEF_PUBKEY_ACCESS 0x12 #define TEMPLATE_FILEID_MIN_DIFF 0x20 @@ -309,9 +308,8 @@ sc_profile_new(void) p15card->file_unusedspace = init_file(SC_FILE_TYPE_WORKING_EF); } - /* Assume card does RSA natively, but no DSA */ + /* Assume card does RSA natively */ pro->rsa_access_flags = DEF_PRKEY_RSA_ACCESS; - pro->dsa_access_flags = DEF_PRKEY_DSA_ACCESS; pro->pin_encoding = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; pro->pin_minlen = 4; pro->pin_maxlen = 8; diff --git a/src/pkcs15init/profile.h b/src/pkcs15init/profile.h index f9f1077625..ad538ed621 100644 --- a/src/pkcs15init/profile.h +++ b/src/pkcs15init/profile.h @@ -120,7 +120,6 @@ struct sc_profile { unsigned int pin_attempts; unsigned int puk_attempts; unsigned int rsa_access_flags; - unsigned int dsa_access_flags; struct { unsigned int direct_certificates; From 30e1fd879bb963a6f302c7f800d1b4f4faa5cbd8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 17:28:29 +0100 Subject: [PATCH 2283/4321] pkcs15init: Update for no DSA support --- src/pkcs15init/isoApplet.profile | 2 +- src/pkcs15init/pkcs15-entersafe.c | 2 +- src/pkcs15init/pkcs15-starcos.c | 2 +- src/pkcs15init/pkcs15.profile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/isoApplet.profile b/src/pkcs15init/isoApplet.profile index a8c2f7a919..728c9c29b6 100644 --- a/src/pkcs15init/isoApplet.profile +++ b/src/pkcs15init/isoApplet.profile @@ -14,7 +14,7 @@ cardinfo { pkcs15 { # Method to calculate ID of the crypto objects - # mozilla: SHA1(modulus) for RSA, SHA1(pub) for DSA + # mozilla: SHA1(modulus) for RSA # rfc2459: SHA1(SequenceASN1 of public key components as ASN1 integers) # native: 'E' + number_of_present_objects_of_the_same_type # default value: 'native' diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 7c3b195462..44f2f9e3c0 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -356,7 +356,7 @@ static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if ( key->algorithm != SC_ALGORITHM_RSA ) { - /* ignore DSA keys */ + /* ignore non-RSA keys */ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); } diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index 7298a58ee4..b24dc5c9fb 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -798,7 +798,7 @@ static int starcos_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_starcos_wkey_data tkey; if (key->algorithm != SC_ALGORITHM_RSA) - /* ignore DSA keys */ + /* ignore non-RSA keys */ return SC_ERROR_INVALID_ARGUMENTS; /* create sc_starcos_wkey_data */ diff --git a/src/pkcs15init/pkcs15.profile b/src/pkcs15init/pkcs15.profile index c98319fd63..b199438030 100644 --- a/src/pkcs15init/pkcs15.profile +++ b/src/pkcs15init/pkcs15.profile @@ -24,7 +24,7 @@ pkcs15 { do-last-update = yes; # Method to calculate ID of the crypto objects # native: 'E' + number_of_present_objects_of_the_same_type - # mozilla: SHA1(modulus) for RSA, SHA1(pub) for DSA + # mozilla: SHA1(modulus) for RSA # rfc2459: SHA1(SequenceASN1 of public key components as ASN1 integers) # default value: 'native' pkcs15-id-style = mozilla; From 5d39a270c61939251b6123ea318de0e240525891 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 17:52:32 +0100 Subject: [PATCH 2284/4321] cardctl.h: Remove macros for DSA --- src/libopensc/cardctl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index f633f3de20..760b6c5e9b 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -481,8 +481,6 @@ enum SC_CARDCTL_OBERTHUR_KEY_TYPE { SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC = 0xA1, SC_CARDCTL_OBERTHUR_KEY_RSA_SFM, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, - SC_CARDCTL_OBERTHUR_KEY_DSA_PUBLIC, - SC_CARDCTL_OBERTHUR_KEY_DSA_PRIVATE, SC_CARDCTL_OBERTHUR_KEY_EC_CRT, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC }; From f7cdbe8f3a1a531f7f169544338aa8dabfed1250 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 17:56:17 +0100 Subject: [PATCH 2285/4321] card-dnie.c: Remove support for DSA --- src/libopensc/card-dnie.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index a487463607..2c36ddf5c3 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1444,7 +1444,6 @@ static int dnie_set_security_env(struct sc_card *card, case SC_ALGORITHM_RSA: result = SC_SUCCESS; break; - case SC_ALGORITHM_DSA: case SC_ALGORITHM_EC: case SC_ALGORITHM_GOSTR3410: default: From d75669c7cf42252561044509b99a00ed913fbd81 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 18:10:05 +0100 Subject: [PATCH 2286/4321] muscle.c: Remove DSA macros --- src/libopensc/muscle.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 15f78b4036..1f8ef33e86 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -30,8 +30,6 @@ #define MSC_RSA_PUBLIC 0x01 #define MSC_RSA_PRIVATE 0x02 #define MSC_RSA_PRIVATE_CRT 0x03 -#define MSC_DSA_PUBLIC 0x04 -#define MSC_DSA_PRIVATE 0x05 static msc_id inputId = { { 0xFF, 0xFF, 0xFF, 0xFF } }; static msc_id outputId = { { 0xFF, 0xFF, 0xFF, 0xFE } }; From bd484ad9763467094eee546975ae1391c454ba98 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 18:14:50 +0100 Subject: [PATCH 2287/4321] pkcs15-algo.c: Remove DSA from algorithm table --- src/libopensc/pkcs15-algo.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 39539b365c..a16daffe1f 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -358,9 +358,6 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #ifdef SC_ALGORITHM_MD5 { SC_ALGORITHM_MD5, {{ 1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL }, #endif -#ifdef SC_ALGORITHM_DSA - { SC_ALGORITHM_DSA, {{ 1, 2, 840, 10040, 4, 3, -1}}, NULL, NULL, NULL }, -#endif #ifdef SC_ALGORITHM_RSA /* really rsaEncryption */ { SC_ALGORITHM_RSA, {{ 1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL }, #endif From cb2232d1e3cebdf14e9a605fe4214ecd53e28600 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 18:16:10 +0100 Subject: [PATCH 2288/4321] pkcs15-cert.c: Remove support for DSA --- src/libopensc/pkcs15-cert.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 6c67fc9cbc..972076d4c5 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -573,9 +573,6 @@ sc_pkcs15_alg_flags_from_algorithm(int algorithm) SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP | SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - case SC_ALGORITHM_DSA: - return SC_PKCS15_PRKEY_USAGE_VERIFY| SC_PKCS15_PRKEY_USAGE_SIGN | - SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; #ifdef SC_ALGORITHM_DH case SC_ALGORITHM_DH: return SC_PKCS15_PRKEY_USAGE_DERIVE ; From 4e88b8481629d8ba6127a73e3dd92455b6957e30 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 20:21:50 +0100 Subject: [PATCH 2289/4321] pkcs15-prkey.c: Remove DSA support --- src/libopensc/pkcs15-prkey.c | 126 ++--------------------------------- 1 file changed, 4 insertions(+), 122 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 8b09048bd7..d6046a45a2 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include @@ -124,31 +123,6 @@ static const struct sc_asn1_entry c_asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410 { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_DSAKEY_I_P_ATTR_SIZE 2 -static const struct sc_asn1_entry c_asn1_dsakey_i_p_attr[C_ASN1_DSAKEY_I_P_ATTR_SIZE] = { - { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -#define C_ASN1_DSAKEY_VALUE_ATTR_SIZE 3 -static const struct sc_asn1_entry c_asn1_dsakey_value_attr[C_ASN1_DSAKEY_VALUE_ATTR_SIZE] = { - { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { "pathProtected",SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL}, - { NULL, 0, 0, 0, NULL, NULL } -}; - -#define C_ASN1_DSAKEY_ATTR_SIZE 2 -static const struct sc_asn1_entry c_asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE] = { - { "value", SC_ASN1_CHOICE, 0, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -#define C_ASN1_PRK_DSA_ATTR_SIZE 2 -static const struct sc_asn1_entry c_asn1_prk_dsa_attr[C_ASN1_PRK_DSA_ATTR_SIZE] = { - { "privateDSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - /* * The element fieldSize is a proprietary extension to ISO 7816-15, providing to the middleware * the size of the underlying ECC field. This value is required for determine a proper size for @@ -168,11 +142,10 @@ static const struct sc_asn1_entry c_asn1_prk_ecc_attr[C_ASN1_PRK_ECC_ATTR] = { { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_PRKEY_SIZE 5 +#define C_ASN1_PRKEY_SIZE 4 static const struct sc_asn1_entry c_asn1_prkey[C_ASN1_PRKEY_SIZE] = { { "privateRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, { "privateECCKey", SC_ASN1_PKCS15_OBJECT, 0 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, - { "privateDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, { "privateGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 4 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; @@ -192,10 +165,6 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_entry asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE]; - struct sc_asn1_entry asn1_prk_dsa_attr[C_ASN1_PRK_DSA_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_i_p_attr[C_ASN1_DSAKEY_I_P_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_value_attr[C_ASN1_DSAKEY_VALUE_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE]; struct sc_asn1_entry asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR]; @@ -203,7 +172,6 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_entry asn1_prkey[C_ASN1_PRKEY_SIZE]; struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE]; struct sc_asn1_pkcs15_object rsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr}; - struct sc_asn1_pkcs15_object dsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_dsa_attr}; struct sc_asn1_pkcs15_object gostr3410_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_gostr3410_attr}; struct sc_asn1_pkcs15_object ecc_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_ecc_attr }; @@ -212,10 +180,6 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); - sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr); - sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr); sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr); sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); sc_copy_asn1_entry(c_asn1_prk_ecc_attr, asn1_prk_ecc_attr); @@ -226,22 +190,15 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prkey + 1, &ecc_prkey_obj, NULL, 0); - sc_format_asn1_entry(asn1_prkey + 2, &dsa_prkey_obj, NULL, 0); - sc_format_asn1_entry(asn1_prkey + 3, &gostr3410_prkey_obj, NULL, 0); + sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 0); - sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_ecc_attr + 0, asn1_ecckey_attr, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_attr + 0, asn1_dsakey_value_attr, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_value_attr + 0, &info.path, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_value_attr + 1, asn1_dsakey_i_p_attr, NULL, 0); - sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0, &info.path, NULL, 0); - sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); @@ -279,12 +236,6 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_PRKEY_EC; } else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) { - obj->type = SC_PKCS15_TYPE_PRKEY_DSA; - /* If the value was indirect-protected, mark the path */ - if (asn1_dsakey_i_p_attr[0].flags & SC_ASN1_PRESENT) - info.path.type = SC_PATH_TYPE_PATH_PROT; - } - else if (asn1_prkey[3].flags & SC_ASN1_PRESENT) { /* FIXME proper handling of gost parameters without the need of * allocating data here. this would also make sc_pkcs15_free_key_params * obsolete */ @@ -307,7 +258,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, } else { r = SC_ERROR_INVALID_ASN1_OBJECT; - LOG_TEST_GOTO_ERR(ctx, r, "Neither RSA or DSA or GOSTR3410 or ECC key in PrKDF entry."); + LOG_TEST_GOTO_ERR(ctx, r, "Neither RSA or GOSTR3410 or ECC key in PrKDF entry."); } if (!p15card->app || !p15card->app->ddo.aid.len) { @@ -387,10 +338,6 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, const struct sc_pkcs15_objec struct sc_asn1_entry asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE]; - struct sc_asn1_entry asn1_prk_dsa_attr[C_ASN1_PRK_DSA_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_value_attr[C_ASN1_DSAKEY_VALUE_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_i_p_attr[C_ASN1_DSAKEY_I_P_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE]; struct sc_asn1_entry asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR]; @@ -401,10 +348,6 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, const struct sc_pkcs15_objec (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr }; - struct sc_asn1_pkcs15_object dsa_prkey_obj = { - (struct sc_pkcs15_object *) obj, asn1_com_key_attr, - asn1_com_prkey_attr, asn1_prk_dsa_attr - }; struct sc_asn1_pkcs15_object gostr3410_prkey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_prkey_attr, @@ -425,10 +368,6 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, const struct sc_pkcs15_objec sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); - sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr); - sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr); sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr); sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); sc_copy_asn1_entry(c_asn1_prk_ecc_attr, asn1_prk_ecc_attr); @@ -450,21 +389,8 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, const struct sc_pkcs15_objec sc_format_asn1_entry(asn1_ecckey_attr + 0, &prkey->path, NULL, 1); sc_format_asn1_entry(asn1_ecckey_attr + 1, &prkey->field_length, NULL, 1); break; - case SC_PKCS15_TYPE_PRKEY_DSA: - sc_format_asn1_entry(asn1_prkey + 2, &dsa_prkey_obj, NULL, 1); - sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_value_attr, NULL, 1); - if (prkey->path.type != SC_PATH_TYPE_PATH_PROT) { - /* indirect: just add the path */ - sc_format_asn1_entry(asn1_dsakey_value_attr + 0, &prkey->path, NULL, 1); - } - else { - /* indirect-protected */ - sc_format_asn1_entry(asn1_dsakey_value_attr + 1, asn1_dsakey_i_p_attr, NULL, 1); - sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0, &prkey->path, NULL, 1); - } - break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: - sc_format_asn1_entry(asn1_prkey + 3, &gostr3410_prkey_obj, NULL, 1); + sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 1); sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 1); sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &prkey->path, NULL, 1); if (prkey->params.len == sizeof(*keyinfo_gostparams)) { @@ -604,13 +530,6 @@ sc_pkcs15_free_prkey(struct sc_pkcs15_prkey *key) free(key->u.rsa.dmp1.data); free(key->u.rsa.dmq1.data); break; - case SC_ALGORITHM_DSA: - free(key->u.dsa.pub.data); - free(key->u.dsa.p.data); - free(key->u.dsa.q.data); - free(key->u.dsa.g.data); - free(key->u.dsa.priv.data); - break; case SC_ALGORITHM_GOSTR3410: free(key->u.gostr3410.d.data); break; @@ -737,43 +656,6 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) break; } - case EVP_PKEY_DSA: { - struct sc_pkcs15_prkey_dsa *dst = &pkcs15_key->u.dsa; -#if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key; - DSA *src = NULL; - if (!(src = EVP_PKEY_get1_DSA(pk))) - return SC_ERROR_INCOMPATIBLE_KEY; - - DSA_get0_key(src, &src_pub_key, &src_priv_key); - DSA_get0_pqg(src, &src_p, &src_q, &src_g); -#else - BIGNUM *src_pub_key = NULL, *src_p = NULL, *src_q , *src_g = NULL, *src_priv_key = NULL; - if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &src_q) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &src_g) != 1) { - BN_free(src_p); BN_free(src_q); - BN_free(src_priv_key); BN_free(src_pub_key); - return SC_ERROR_UNKNOWN; - } -#endif - pkcs15_key->algorithm = SC_ALGORITHM_DSA; - sc_pkcs15_convert_bignum(&dst->pub, src_pub_key); - sc_pkcs15_convert_bignum(&dst->p, src_p); - sc_pkcs15_convert_bignum(&dst->q, src_q); - sc_pkcs15_convert_bignum(&dst->g, src_g); - sc_pkcs15_convert_bignum(&dst->priv, src_priv_key); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - DSA_free(src); -#else - BN_free(src_pub_key); BN_free(src_p); BN_free(src_q); - BN_free(src_g); BN_free(src_priv_key); -#endif - break; - } - #if !defined(OPENSSL_NO_EC) case NID_id_GostR3410_2001: { struct sc_pkcs15_prkey_gostr3410 *dst = &pkcs15_key->u.gostr3410; From 0d9c51d45c97bd8cb93385a33be5e1e7816f1a13 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 20:33:48 +0100 Subject: [PATCH 2290/4321] pkcs15-pubkey.c: Remove DSA support --- src/libopensc/pkcs15-pubkey.c | 197 ++-------------------------------- 1 file changed, 8 insertions(+), 189 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 4d5b2d9f13..5c45104bcb 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -37,7 +37,6 @@ #ifdef ENABLE_OPENSSL #include #include -#include #include #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -119,18 +118,6 @@ static const struct sc_asn1_entry c_asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE] { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_DSAKEY_ATTR_SIZE 2 -static const struct sc_asn1_entry c_asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE] = { - { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -#define C_ASN1_DSA_TYPE_ATTR_SIZE 2 -static const struct sc_asn1_entry c_asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE] = { - { "publicDSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - #define C_ASN1_GOST3410KEY_ATTR_SIZE 5 static const struct sc_asn1_entry c_asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE] = { { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, @@ -146,10 +133,9 @@ static const struct sc_asn1_entry c_asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYP { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_PUBKEY_CHOICE_SIZE 5 +#define C_ASN1_PUBKEY_CHOICE_SIZE 4 static const struct sc_asn1_entry c_asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE] = { { "publicRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, - { "publicDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL }, { "publicGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 4 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL }, { "publicECKey", SC_ASN1_PKCS15_OBJECT, 0 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL }, /*TODO: -DEE not clear EC is needed here as look like it is for pukdf */ @@ -228,8 +214,6 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_entry asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE]; struct sc_asn1_entry asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE]; struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE]; @@ -238,8 +222,6 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, asn1_com_pubkey_attr, asn1_rsa_type_attr }; struct sc_asn1_pkcs15_object eckey_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_ec_type_attr }; - struct sc_asn1_pkcs15_object dsakey_obj = { obj, asn1_com_key_attr, - asn1_com_pubkey_attr, asn1_dsa_type_attr }; struct sc_asn1_pkcs15_object gostr3410key_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; @@ -259,8 +241,6 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_copy_asn1_entry(c_asn1_ec_type_attr, asn1_ec_type_attr); sc_copy_asn1_entry(c_asn1_eckey_value_choice, asn1_eckey_value_choice); sc_copy_asn1_entry(c_asn1_eckey_attr, asn1_eckey_attr); - sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr); sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); @@ -269,9 +249,8 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info->subject.value, &info->subject.len, 0); sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0); - sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0); - sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 0); - sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 0); + sc_format_asn1_entry(asn1_pubkey_choice + 1, &gostr3410key_obj, NULL, 0); + sc_format_asn1_entry(asn1_pubkey_choice + 2, &eckey_obj, NULL, 0); sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0); @@ -288,10 +267,6 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0); - sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0); - - sc_format_asn1_entry(asn1_dsakey_attr + 0, &info->path, NULL, 0); - sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info->path, NULL, 0); @@ -318,7 +293,7 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 decoding failed"); if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; - } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { + } else if (asn1_pubkey_choice[1].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; assert(info->modulus_length == 0); info->modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; @@ -335,11 +310,11 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1]; keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2]; } - else if (asn1_pubkey_choice[3].flags & SC_ASN1_PRESENT) { + else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_EC; } else { - obj->type = SC_PKCS15_TYPE_PUBKEY_DSA; + goto err; } if (!p15card->app || !p15card->app->ddo.aid.len) { @@ -394,8 +369,6 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje struct sc_asn1_entry asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE]; struct sc_asn1_entry asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE]; - struct sc_asn1_entry asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE]; struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE]; @@ -408,9 +381,6 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje struct sc_asn1_pkcs15_object eckey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_ec_type_attr }; - struct sc_asn1_pkcs15_object dsakey_obj = { (struct sc_pkcs15_object *) obj, - asn1_com_key_attr, - asn1_com_pubkey_attr, asn1_dsa_type_attr }; struct sc_asn1_pkcs15_object gostr3410key_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; @@ -427,8 +397,6 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje sc_copy_asn1_entry(c_asn1_ec_type_attr, asn1_ec_type_attr); sc_copy_asn1_entry(c_asn1_eckey_value_choice, asn1_eckey_value_choice); sc_copy_asn1_entry(c_asn1_eckey_attr, asn1_eckey_attr); - sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr); sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); @@ -471,15 +439,8 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 1); sc_format_asn1_entry(asn1_rsakey_attr + 1, &pubkey->modulus_length, NULL, 1); break; - case SC_PKCS15_TYPE_PUBKEY_DSA: - sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 1); - - sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 1); - - sc_format_asn1_entry(asn1_dsakey_attr + 0, &pubkey->path, NULL, 1); - break; case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: - sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 1); + sc_format_asn1_entry(asn1_pubkey_choice + 1, &gostr3410key_obj, NULL, 1); sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 1); @@ -495,7 +456,7 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje } break; case SC_PKCS15_TYPE_PUBKEY_EC: - sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 1); + sc_format_asn1_entry(asn1_pubkey_choice + 2, &eckey_obj, NULL, 1); sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 1); @@ -563,15 +524,6 @@ static struct sc_asn1_entry c_asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIE { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_DSA_PUB_COEFFICIENTS_SIZE 5 -static struct sc_asn1_entry c_asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE] = { - { "publicKey",SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, - { "paramP", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, - { "paramQ", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, - { "paramG", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL }, -}; - #define C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE 2 static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE] = { { "xy", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL }, @@ -637,56 +589,6 @@ sc_pkcs15_encode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, } -int -sc_pkcs15_decode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key, - const u8 *buf, size_t buflen) -{ - struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; - struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE]; - int r; - - LOG_FUNC_CALLED(ctx); - sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); - sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients); - - sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, &key->pub.data, &key->pub.len, 0); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, &key->g.data, &key->g.len, 0); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, &key->p.data, &key->p.len, 0); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, &key->q.data, &key->q.len, 0); - - r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL); - LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} - - -int -sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key, - u8 **buf, size_t *buflen) -{ - struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; - struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE]; - int r; - - LOG_FUNC_CALLED(ctx); - sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); - sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients); - - sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, key->pub.data, &key->pub.len, 1); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, key->g.data, &key->g.len, 1); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, key->p.data, &key->p.len, 1); - sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, key->q.data, &key->q.len, 1); - - r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen); - LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} - - int sc_pkcs15_decode_pubkey_gostr3410(sc_context_t *ctx, struct sc_pkcs15_pubkey_gostr3410 *key, const u8 *buf, size_t buflen) @@ -825,8 +727,6 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, { if (key->algorithm == SC_ALGORITHM_RSA) return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len); - if (key->algorithm == SC_ALGORITHM_DSA) - return sc_pkcs15_encode_pubkey_dsa(ctx, &key->u.dsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_encode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); if (key->algorithm == SC_ALGORITHM_EC) @@ -953,8 +853,6 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, { if (key->algorithm == SC_ALGORITHM_RSA) return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len); - if (key->algorithm == SC_ALGORITHM_DSA) - return sc_pkcs15_decode_pubkey_dsa(ctx, &key->u.dsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_decode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); if (key->algorithm == SC_ALGORITHM_EC) @@ -995,9 +893,6 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj case SC_PKCS15_TYPE_PUBKEY_RSA: algorithm = SC_ALGORITHM_RSA; break; - case SC_PKCS15_TYPE_PUBKEY_DSA: - algorithm = SC_ALGORITHM_DSA; - break; case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: algorithm = SC_ALGORITHM_GOSTR3410; break; @@ -1120,15 +1015,6 @@ sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prv if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &prvkey->u.rsa.exponent); break; - case SC_ALGORITHM_DSA: - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &prvkey->u.dsa.pub); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &prvkey->u.dsa.p); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &prvkey->u.dsa.q); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &prvkey->u.dsa.g); - break; case SC_ALGORITHM_GOSTR3410: break; case SC_ALGORITHM_EC: @@ -1210,15 +1096,6 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc if (!rv) rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &key->u.rsa.exponent); break; - case SC_ALGORITHM_DSA: - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &key->u.dsa.pub); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &key->u.dsa.p); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &key->u.dsa.q); - if (!rv) - rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &key->u.dsa.g); - break; case SC_ALGORITHM_GOSTR3410: break; case SC_ALGORITHM_EC: @@ -1293,16 +1170,6 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) if (key->u.rsa.exponent.data) free(key->u.rsa.exponent.data); break; - case SC_ALGORITHM_DSA: - if (key->u.dsa.pub.data) - free(key->u.dsa.pub.data); - if (key->u.dsa.g.data) - free(key->u.dsa.g.data); - if (key->u.dsa.p.data) - free(key->u.dsa.p.data); - if (key->u.dsa.q.data) - free(key->u.dsa.q.data); - break; case SC_ALGORITHM_GOSTR3410: if (key->u.gostr3410.xy.data) free(key->u.gostr3410.xy.data); @@ -1756,54 +1623,6 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) RSA_free(src); #else BN_free(src_n); BN_free(src_e); -#endif - break; - } - case EVP_PKEY_DSA: { - struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa; - /* Get parameters */ -#if OPENSSL_VERSION_NUMBER < 0x30000000L - const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; - DSA *src = NULL; - if (!(src = EVP_PKEY_get1_DSA(pk))) - return SC_ERROR_INCOMPATIBLE_KEY; - DSA_get0_key(src, &src_pub_key, &src_priv_key); - DSA_get0_pqg(src, &src_p, &src_q, &src_g); - if (!src_pub_key || !src_priv_key || !src_p || !src_q || !src_g) { - DSA_free(src); - return SC_ERROR_INTERNAL; - } -#else - BIGNUM *src_pub_key = NULL, *src_priv_key = NULL, *src_p = NULL, *src_q = NULL, *src_g = NULL; - if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, &src_pub_key) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &src_p) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &src_q) != 1 || - EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &src_g) != 1) { - BN_free(src_p); BN_free(src_q); - BN_free(src_priv_key); BN_free(src_pub_key); - return SC_ERROR_INTERNAL; - } -#endif - /* Convert */ - pkcs15_key->algorithm = SC_ALGORITHM_DSA; - if (!sc_pkcs15_convert_bignum(&dst->pub, src_pub_key) || - !sc_pkcs15_convert_bignum(&dst->p, src_p) || - !sc_pkcs15_convert_bignum(&dst->q, src_q) || - !sc_pkcs15_convert_bignum(&dst->g, src_g)) { -#if OPENSSL_VERSION_NUMBER < 0x30000000L - DSA_free(src); -#else - BN_free(src_p); BN_free(src_q); - BN_free(src_priv_key); BN_free(src_pub_key); -#endif - return SC_ERROR_INVALID_DATA; - } -#if OPENSSL_VERSION_NUMBER < 0x30000000L - DSA_free(src); -#else - BN_free(src_p); BN_free(src_q); - BN_free(src_priv_key); BN_free(src_pub_key); #endif break; } From fd04ff2f73202c442d2019edc1c6f49cd3aaf952 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 20:58:09 +0100 Subject: [PATCH 2291/4321] pkcs15.h: Remove support for DSA Structures for DSA keys, macros and encoding/decoding function --- src/libopensc/libopensc.exports | 2 -- src/libopensc/pkcs15.h | 26 -------------------------- 2 files changed, 28 deletions(-) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 6212aee773..44fa8e96a8 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -158,7 +158,6 @@ sc_pkcs15_decode_cdf_entry sc_pkcs15_decode_dodf_entry sc_pkcs15_decode_prkdf_entry sc_pkcs15_decode_pubkey -sc_pkcs15_decode_pubkey_dsa sc_pkcs15_decode_pubkey_rsa sc_pkcs15_decode_pubkey_ec sc_pkcs15_decode_pubkey_gostr3410 @@ -172,7 +171,6 @@ sc_pkcs15_encode_dodf_entry sc_pkcs15_encode_odf sc_pkcs15_encode_prkdf_entry sc_pkcs15_encode_pubkey -sc_pkcs15_encode_pubkey_dsa sc_pkcs15_encode_pubkey_rsa sc_pkcs15_encode_pubkey_ec sc_pkcs15_encode_pubkey_eddsa diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index b5cdaed90c..52b268ee1e 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -192,24 +192,6 @@ struct sc_pkcs15_prkey_rsa { sc_pkcs15_bignum_t dmq1; }; -struct sc_pkcs15_pubkey_dsa { - sc_pkcs15_bignum_t pub; - sc_pkcs15_bignum_t p; - sc_pkcs15_bignum_t q; - sc_pkcs15_bignum_t g; -}; - -struct sc_pkcs15_prkey_dsa { - /* public components */ - sc_pkcs15_bignum_t pub; - sc_pkcs15_bignum_t p; - sc_pkcs15_bignum_t q; - sc_pkcs15_bignum_t g; - - /* private key */ - sc_pkcs15_bignum_t priv; -}; - struct sc_pkcs15_gost_parameters { struct sc_object_id key; struct sc_object_id hash; @@ -253,7 +235,6 @@ struct sc_pkcs15_pubkey { /* Decoded key */ union { struct sc_pkcs15_pubkey_rsa rsa; - struct sc_pkcs15_pubkey_dsa dsa; struct sc_pkcs15_pubkey_ec ec; struct sc_pkcs15_pubkey_eddsa eddsa; struct sc_pkcs15_pubkey_gostr3410 gostr3410; @@ -267,7 +248,6 @@ struct sc_pkcs15_prkey { union { struct sc_pkcs15_prkey_rsa rsa; - struct sc_pkcs15_prkey_dsa dsa; struct sc_pkcs15_prkey_ec ec; struct sc_pkcs15_prkey_eddsa eddsa; struct sc_pkcs15_prkey_gostr3410 gostr3410; @@ -448,7 +428,6 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t; #define SC_PKCS15_TYPE_PRKEY 0x100 #define SC_PKCS15_TYPE_PRKEY_RSA 0x101 -#define SC_PKCS15_TYPE_PRKEY_DSA 0x102 #define SC_PKCS15_TYPE_PRKEY_GOSTR3410 0x103 #define SC_PKCS15_TYPE_PRKEY_EC 0x104 #define SC_PKCS15_TYPE_PRKEY_EDDSA 0x105 @@ -456,7 +435,6 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t; #define SC_PKCS15_TYPE_PUBKEY 0x200 #define SC_PKCS15_TYPE_PUBKEY_RSA 0x201 -#define SC_PKCS15_TYPE_PUBKEY_DSA 0x202 #define SC_PKCS15_TYPE_PUBKEY_GOSTR3410 0x203 #define SC_PKCS15_TYPE_PUBKEY_EC 0x204 #define SC_PKCS15_TYPE_PUBKEY_EDDSA 0x205 @@ -708,10 +686,6 @@ int sc_pkcs15_decode_pubkey_rsa(struct sc_context *, struct sc_pkcs15_pubkey_rsa *, const u8 *, size_t); int sc_pkcs15_encode_pubkey_rsa(struct sc_context *, struct sc_pkcs15_pubkey_rsa *, u8 **, size_t *); -int sc_pkcs15_decode_pubkey_dsa(struct sc_context *, - struct sc_pkcs15_pubkey_dsa *, const u8 *, size_t); -int sc_pkcs15_encode_pubkey_dsa(struct sc_context *, - struct sc_pkcs15_pubkey_dsa *, u8 **, size_t *); int sc_pkcs15_decode_pubkey_gostr3410(struct sc_context *, struct sc_pkcs15_pubkey_gostr3410 *, const u8 *, size_t); int sc_pkcs15_encode_pubkey_gostr3410(struct sc_context *, From 3e9a3ba19a8b06004414ed1fa8052c5dab395112 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 21:00:48 +0100 Subject: [PATCH 2292/4321] sc-ossl-compat.h: Remove DSA support --- src/libopensc/sc-ossl-compat.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index ec694ad48d..f0d5527984 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -96,7 +96,6 @@ extern "C" { #define OPENSSL_malloc_init CRYPTO_malloc_init #define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) #define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec) -#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa) #define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY) #define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) #endif @@ -125,14 +124,12 @@ extern "C" { /* As defined in openssl/include/openssl/evp.h */ # ifndef EVP_PK_RSA # define EVP_PK_RSA 0x0001 -# define EVP_PK_DSA 0x0002 # define EVP_PK_DH 0x0004 # define EVP_PK_EC 0x0008 # define EVP_PKT_SIGN 0x0010 # define EVP_PKT_ENC 0x0020 # define EVP_PKT_EXCH 0x0040 # define EVP_PKS_RSA 0x0100 -# define EVP_PKS_DSA 0x0200 # define EVP_PKS_EC 0x0400 # endif #endif @@ -176,9 +173,6 @@ extern "C" { #ifndef OPENSSL_NO_RSA #include #endif -#ifndef OPENSSL_NO_DSA -#include -#endif #ifndef OPENSSL_NO_EC #include #endif @@ -259,28 +253,6 @@ static sc_ossl_inline void RSA_get0_crt_params(const RSA *r, #endif /* OPENSSL_NO_RSA */ -#ifndef OPENSSL_NO_DSA -static sc_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; -} - -static sc_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) -{ - if (pub_key != NULL) - *pub_key = d->pub_key; - if (priv_key != NULL) - *priv_key = d->priv_key; -} - -/* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */ -#endif /* OPENSSL_NO_DSA */ - #ifndef OPENSSL_NO_EC static sc_ossl_inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) From a7efc5f9e00dfb3a99503424efc3e194099c7a70 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 28 Jan 2022 17:38:00 +0100 Subject: [PATCH 2293/4321] opensc-tool: Remove DSA from algorithms --- src/tools/opensc-tool.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index d00eb30ecd..d97e11e2b0 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -555,7 +555,6 @@ static int list_algorithms(void) const id2str_t alg_type_names[] = { { SC_ALGORITHM_RSA, "rsa" }, - { SC_ALGORITHM_DSA, "dsa" }, { SC_ALGORITHM_EC, "ec" }, { SC_ALGORITHM_EDDSA, "eddsa" }, { SC_ALGORITHM_GOSTR3410, "gostr3410" }, From 20bf4d38deca9d7985507e0deb2e3ee6b3f8ee04 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 28 Jan 2022 17:42:23 +0100 Subject: [PATCH 2294/4321] pkcs15-init: Remove DSA support --- src/tools/pkcs15-init.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index f75e3f743b..c9c549a089 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -731,7 +730,6 @@ static const struct alg_spec alg_types_sym[] = { static const struct alg_spec alg_types_asym[] = { { "rsa", SC_ALGORITHM_RSA, 1024 }, - { "dsa", SC_ALGORITHM_DSA, 1024 }, { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, { NULL, -1, 0 } @@ -1348,12 +1346,7 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, if (EVP_PKEY_eq(oldpk, newpk) == 1) r = 0; #else - if ((oldpk_type == EVP_PKEY_DSA) && - !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->p, EVP_PKEY_get0_DSA(newpk)->p) && - !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->q, EVP_PKEY_get0_DSA(newpk)->q) && - !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->g, EVP_PKEY_get0_DSA(newpk)->g)) - r = 0; - else if ((oldpk_type == EVP_PKEY_RSA) && + if ((oldpk_type == EVP_PKEY_RSA) && !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->n, EVP_PKEY_get0_RSA(newpk)->n) && !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->e, EVP_PKEY_get0_RSA(newpk)->e)) r = 0; From 73008b842b4156661fd3e5638aa8eafb867b8fbe Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 28 Jan 2022 17:48:36 +0100 Subject: [PATCH 2295/4321] pkcs15-tool: Remove DSA support --- src/tools/pkcs15-tool.c | 93 +---------------------------------------- 1 file changed, 1 insertion(+), 92 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index abd77e491b..02c8c71265 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -221,7 +221,7 @@ struct _access_rule_text { {0, NULL}, }; -static const char *key_types[] = { "", "RSA", "DSA", "GOSTR3410", "EC", "EDDSA", "XEDDSA", "" }; +static const char *key_types[] = { "", "RSA", "GOSTR3410", "EC", "EDDSA", "XEDDSA", "", "" }; static void print_access_rules(const struct sc_pkcs15_accessrule *rules, int num) @@ -1157,97 +1157,6 @@ static int read_ssh_key(void) print_ssh_key(outf, "ssh-rsa", obj, buf, len); } - if (pubkey->algorithm == SC_ALGORITHM_DSA) { - unsigned char buf[2048]; - uint32_t len; - uint32_t n; - - if (!pubkey->u.dsa.p.data || !pubkey->u.dsa.p.len || - !pubkey->u.dsa.q.data || !pubkey->u.dsa.q.len || - !pubkey->u.dsa.g.data || !pubkey->u.dsa.g.len || - !pubkey->u.dsa.pub.data || !pubkey->u.dsa.pub.len) { - fprintf(stderr, "Failed to decode DSA key.\n"); - goto fail2; - } - - buf[0]=0; - buf[1]=0; - buf[2]=0; - buf[3]=7; - - len = sprintf((char *) buf+4,"ssh-dss"); - len+=4; - - if (sizeof(buf)-len < 5+pubkey->u.dsa.p.len) - goto fail; - - n = pubkey->u.dsa.p.len; - if (pubkey->u.dsa.p.data[0] & 0x80) - n++; - - buf[len++]=(n >>24) & 0xff; - buf[len++]=(n >>16) & 0xff; - buf[len++]=(n >>8) & 0xff; - buf[len++]=(n) & 0xff; - if (pubkey->u.dsa.p.data[0] & 0x80) - buf[len++]= 0; - - memcpy(buf+len,pubkey->u.dsa.p.data, pubkey->u.dsa.p.len); - len += pubkey->u.dsa.p.len; - - if (sizeof(buf)-len < 5+pubkey->u.dsa.q.len) - goto fail; - - n = pubkey->u.dsa.q.len; - if (pubkey->u.dsa.q.data[0] & 0x80) - n++; - - buf[len++]=(n >>24) & 0xff; - buf[len++]=(n >>16) & 0xff; - buf[len++]=(n >>8) & 0xff; - buf[len++]=(n) & 0xff; - if (pubkey->u.dsa.q.data[0] & 0x80) - buf[len++]= 0; - - memcpy(buf+len,pubkey->u.dsa.q.data, pubkey->u.dsa.q.len); - len += pubkey->u.dsa.q.len; - - if (sizeof(buf)-len < 5+pubkey->u.dsa.g.len) - goto fail; - n = pubkey->u.dsa.g.len; - if (pubkey->u.dsa.g.data[0] & 0x80) - n++; - - buf[len++]=(n >>24) & 0xff; - buf[len++]=(n >>16) & 0xff; - buf[len++]=(n >>8) & 0xff; - buf[len++]=(n) & 0xff; - if (pubkey->u.dsa.g.data[0] & 0x80) - buf[len++]= 0; - - memcpy(buf+len,pubkey->u.dsa.g.data, pubkey->u.dsa.g.len); - len += pubkey->u.dsa.g.len; - - if (sizeof(buf)-len < 5+pubkey->u.dsa.pub.len) - goto fail; - - n = pubkey->u.dsa.pub.len; - if (pubkey->u.dsa.pub.data[0] & 0x80) - n++; - - buf[len++]=(n >>24) & 0xff; - buf[len++]=(n >>16) & 0xff; - buf[len++]=(n >>8) & 0xff; - buf[len++]=(n) & 0xff; - if (pubkey->u.dsa.pub.data[0] & 0x80) - buf[len++]= 0; - - memcpy(buf+len,pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len); - len += pubkey->u.dsa.pub.len; - - print_ssh_key(outf, "ssh-dss", obj, buf, len); - } - if (opt_outfile != NULL) fclose(outf); if (cert) From e2230f0e0cba56a913ea4ec87a839b1e6bbca93e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 28 Jan 2022 17:59:55 +0100 Subject: [PATCH 2296/4321] print.c: Remove print for DSA objects --- src/tests/print.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/tests/print.c b/src/tests/print.c index 7f0cb0148c..9c923a2f70 100644 --- a/src/tests/print.c +++ b/src/tests/print.c @@ -236,14 +236,6 @@ void sc_test_print_object(const struct sc_pkcs15_object *obj) printer = print_pubkey; kind = "Public RSA key"; break; - case SC_PKCS15_TYPE_PRKEY_DSA: - printer = print_prkey; - kind = "Private DSA key"; - break; - case SC_PKCS15_TYPE_PUBKEY_DSA: - printer = print_pubkey; - kind = "Public DSA key"; - break; case SC_PKCS15_TYPE_CERT_X509: printer = print_cert_x509; kind = "X.509 Certificate"; From 9b3b9b36f82e6915123f81e4634fb9896b21041c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 17:56:37 +0100 Subject: [PATCH 2297/4321] opensc.h: Remove DSA PK algorithm macro --- src/libopensc/opensc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6adde39c75..6c3332ecc0 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -75,8 +75,7 @@ extern "C" { /* PK algorithms */ #define SC_ALGORITHM_RSA 0 -#define SC_ALGORITHM_DSA 1 -#define SC_ALGORITHM_EC 2 +#define SC_ALGORITHM_EC 2 #define SC_ALGORITHM_GOSTR3410 3 #define SC_ALGORITHM_EDDSA 4 #define SC_ALGORITHM_XEDDSA 5 From 58de175c4771bd09a68c8778e1881e392f40cf15 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 31 Jan 2022 14:48:07 +0100 Subject: [PATCH 2298/4321] Remove DSA from doc --- doc/tools/pkcs15-init.1.xml | 2 +- doc/tools/tools.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index f11366b806..5dfdb2a914 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -173,7 +173,7 @@ Note that usage of option in the pkcs15-init commands to generate or to import a new key is deprecated. Better practice is to let the middleware to derive the identifier from the key material. - (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). + (SHA1(modulus) for RSA, ...). This allows easily set up relation between 'related' objects (private/public keys and certificates). diff --git a/doc/tools/tools.html b/doc/tools/tools.html index e370fde4be..34afb591eb 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1898,7 +1898,7 @@ Note that usage of --id option in the pkcs15-init commands to generate or to import a new key is deprecated. Better practice is to let the middleware to derive the identifier from the key material. - (SHA1(modulus) for RSA, SHA1(pub) for DSA, ...). + (SHA1(modulus) for RSA, ...). This allows easily set up relation between 'related' objects (private/public keys and certificates).

    From 8e794aafc9a33c4d2306212565c648284fd8a95a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Mar 2022 11:43:33 +0100 Subject: [PATCH 2299/4321] pkcs15-tool.c: Fix order key types --- src/tools/pkcs15-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 02c8c71265..6e44ece5bc 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -221,7 +221,7 @@ struct _access_rule_text { {0, NULL}, }; -static const char *key_types[] = { "", "RSA", "GOSTR3410", "EC", "EDDSA", "XEDDSA", "", "" }; +static const char *key_types[] = { "", "RSA", "", "GOSTR3410", "EC", "EDDSA", "XEDDSA", "" }; static void print_access_rules(const struct sc_pkcs15_accessrule *rules, int num) From 3509b846fde11985e845a7bd034a7567b8e554c2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 23 Feb 2022 09:31:08 +0100 Subject: [PATCH 2300/4321] Register copy of passed mechanism Add function for copying mechanism and mechanism private data. The copy is stored on p11card, whereas the original mt is freed after sc_pkcs11_register_mechanism(). --- src/pkcs11/framework-pkcs15.c | 53 ++++++++++++++++++----------------- src/pkcs11/mechanism.c | 51 +++++++++++++++++++++++++++++---- src/pkcs11/openssl.c | 8 ++++++ src/pkcs11/pkcs11-object.c | 1 + src/pkcs11/sc-pkcs11.h | 3 +- 5 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 2c00273fb2..9c4eb79b9b 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5790,16 +5790,17 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (flags & SC_ALGORITHM_GOSTR3410_HASH_NONE) { mt = sc_pkcs11_new_fw_mechanism(CKM_GOSTR3410, - &mech_info, CKK_GOSTR3410, NULL, NULL); + &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); + free(mt); if (rc != CKR_OK) return rc; } if (flags & SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411) { mt = sc_pkcs11_new_fw_mechanism(CKM_GOSTR3410_WITH_GOSTR3411, - &mech_info, CKK_GOSTR3410, NULL, NULL); + &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5809,7 +5810,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR; mt = sc_pkcs11_new_fw_mechanism(CKM_GOSTR3410_KEY_PAIR_GEN, - &mech_info, CKK_GOSTR3410, NULL, NULL); + &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5849,7 +5850,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, /* add mechs card or driver support */ if (flags & SC_ALGORITHM_ECDSA_RAW) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; if (flags & SC_ALGORITHM_ECDSA_HASH_NONE) { @@ -5901,7 +5902,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } if (flags & SC_ALGORITHM_ECDSA_HASH_SHA1) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA1, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA1, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5910,7 +5911,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } if (flags & SC_ALGORITHM_ECDSA_HASH_SHA224) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA224, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA224, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5919,7 +5920,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } if (flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA256, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA256, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5928,7 +5929,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } if (flags & SC_ALGORITHM_ECDSA_HASH_SHA384) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA384, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA384, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5937,7 +5938,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } if (flags & SC_ALGORITHM_ECDSA_HASH_SHA512) { - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA512, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA512, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5951,14 +5952,14 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mech_info.flags &= ~(CKF_SIGN | CKF_VERIFY); mech_info.flags |= CKF_DERIVE; - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_COFACTOR_DERIVE, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_COFACTOR_DERIVE, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5969,7 +5970,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR; mech_info.flags |= ec_flags; - mt = sc_pkcs11_new_fw_mechanism(CKM_EC_KEY_PAIR_GEN, &mech_info, CKK_EC, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_EC_KEY_PAIR_GEN, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -5997,7 +5998,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags */ #endif if (flags & SC_ALGORITHM_EDDSA_RAW) { - mt = sc_pkcs11_new_fw_mechanism(CKM_EDDSA, &mech_info, CKK_EC_EDWARDS, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_EDDSA, &mech_info, CKK_EC_EDWARDS, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6008,7 +6009,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR; mt = sc_pkcs11_new_fw_mechanism(CKM_EC_EDWARDS_KEY_PAIR_GEN, - &mech_info, CKK_EC_EDWARDS, NULL, NULL); + &mech_info, CKK_EC_EDWARDS, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6031,7 +6032,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag mech_info.ulMaxKeySize = max_key_size; if (flags & SC_ALGORITHM_XEDDSA_RAW) { - mt = sc_pkcs11_new_fw_mechanism(CKM_XEDDSA, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_XEDDSA, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6045,7 +6046,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag mech_info.flags |= CKF_DERIVE; /* Montgomery curves derive function is defined only for CKM_ECDH1_DERIVE mechanism */ - mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6055,7 +6056,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR; - mt = sc_pkcs11_new_fw_mechanism(CKM_EC_MONTGOMERY_KEY_PAIR_GEN, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_EC_MONTGOMERY_KEY_PAIR_GEN, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6083,21 +6084,21 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if ((card->caps & SC_CARD_CAP_WRAP_KEY) == SC_CARD_CAP_WRAP_KEY) mech_info.flags |= CKF_WRAP; - mt = sc_pkcs11_new_fw_mechanism(CKM_AES_ECB, &mech_info, CKK_AES, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_ECB, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; - mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC, &mech_info, CKK_AES, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; - mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC_PAD, &mech_info, CKK_AES, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC_PAD, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); @@ -6227,7 +6228,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* Check if we support raw RSA */ if (rsa_flags & SC_ALGORITHM_RSA_RAW) { - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; @@ -6243,7 +6244,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_ISO9796) { /* Supported in hardware only, if the card driver declares it. */ - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; @@ -6262,7 +6263,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* No need to Check for PKCS1 We support it in software and turned it on above so always added it */ if (rsa_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; @@ -6320,7 +6321,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { CK_FLAGS old_flags = mech_info.flags; mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; @@ -6361,7 +6362,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_OAEP) { CK_FLAGS old_flags = mech_info.flags; mech_info.flags &= ~(CKF_SIGN|CKF_VERIFY|CKF_SIGN_RECOVER|CKF_VERIFY_RECOVER); - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) { return rc; @@ -6371,7 +6372,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) { mech_info.flags = CKF_GENERATE_KEY_PAIR; - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, &mech_info, CKK_RSA, NULL, NULL); + mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, &mech_info, CKK_RSA, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt); diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 2dbe945fb3..386862b722 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -91,14 +91,40 @@ void _update_mech_info(CK_MECHANISM_INFO_PTR mech_info, CK_MECHANISM_INFO_PTR ne mech_info->flags |= new_mech_info->flags; } +/* + * Copy a mechanism + */ +static CK_RV +sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, + sc_pkcs11_mechanism_type_t **new_mt) +{ + *new_mt = calloc(1, sizeof(sc_pkcs11_mechanism_type_t)); + if (!(*new_mt)) + return CKR_HOST_MEMORY; + + memcpy(*new_mt, mt, sizeof(sc_pkcs11_mechanism_type_t)); + /* mech_data needs specific function for making copy*/ + if (mt->copy_mech_data + && mt->copy_mech_data(mt->mech_data, (void **) &(*new_mt)->mech_data) != CKR_OK) { + free(*new_mt); + return CKR_HOST_MEMORY; + } + + return CKR_OK; +} + /* * Register a mechanism + * Check whether the mechanism is already in p11card, + * if not, make a copy of the given mechanism and store it + * in p11card. */ CK_RV sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, sc_pkcs11_mechanism_type_t *mt) { sc_pkcs11_mechanism_type_t *existing_mt; + sc_pkcs11_mechanism_type_t *copy_mt = NULL; sc_pkcs11_mechanism_type_t **p; int i; @@ -111,7 +137,6 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, /* Mechanism already registered with the same key_type, * just update it's info */ _update_mech_info(&existing_mt->mech_info, &mt->mech_info); - free(mt); return CKR_OK; } if (existing_mt->key_types[i] < 0) { @@ -125,12 +150,10 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, if (i + 1 < MAX_KEY_TYPES) { existing_mt->key_types[i + 1] = -1; } - free(mt); return CKR_OK; } } sc_log(p11card->card->ctx, "Too many key types in mechanism 0x%lx, more than %d", mt->mech, MAX_KEY_TYPES); - free(mt); return CKR_BUFFER_TOO_SMALL; } @@ -138,8 +161,12 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, (p11card->nmechanisms + 2) * sizeof(*p)); if (p == NULL) return CKR_HOST_MEMORY; + if (sc_pkcs11_copy_mechanism(mt, ©_mt) != CKR_OK) { + free(p); + return CKR_HOST_MEMORY; + } p11card->mechanisms = p; - p[p11card->nmechanisms++] = mt; + p[p11card->nmechanisms++] = copy_mt; p[p11card->nmechanisms] = NULL; return CKR_OK; } @@ -1238,7 +1265,8 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, CK_MECHANISM_INFO_PTR pInfo, CK_KEY_TYPE key_type, const void *priv_data, - void (*free_priv_data)(const void *priv_data)) + void (*free_priv_data)(const void *priv_data), + CK_RV (*copy_priv_data)(const void *mech_data, void **new_data)) { sc_pkcs11_mechanism_type_t *mt; @@ -1251,6 +1279,7 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, mt->key_types[1] = -1; mt->mech_data = priv_data; mt->free_mech_data = free_priv_data; + mt->copy_mech_data = copy_priv_data; mt->obj_size = sizeof(sc_pkcs11_operation_t); mt->release = sc_pkcs11_signature_release; @@ -1300,6 +1329,16 @@ void free_info(const void *info) free((void *) info); } +CK_RV copy_hash_signature_info(const void *mech_data, void **new_data) +{ + *new_data = calloc(1, sizeof(struct hash_signature_info)); + if (!new_data) + return CKR_HOST_MEMORY; + + memcpy(*new_data, mech_data, sizeof(struct hash_signature_info)); + return CKR_OK; +} + /* * Register a sign+hash algorithm derived from an algorithm supported * by the token + a software hash mechanism @@ -1331,7 +1370,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; - new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_types[0], info, free_info); + new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_types[0], info, free_info, copy_hash_signature_info); if (!new_type) { free_info(info); return CKR_HOST_MEMORY; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index c9081763f3..5f78b57ba7 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -72,6 +72,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { @@ -91,6 +92,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { @@ -110,6 +112,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { @@ -129,6 +132,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { @@ -148,6 +152,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { @@ -167,6 +172,7 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_md5_mech = { @@ -186,6 +192,7 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { @@ -205,6 +212,7 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static void * dup_mem(void *in, size_t in_len) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 3f7eb1b395..2e8caae117 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -51,6 +51,7 @@ static sc_pkcs11_mechanism_type_t find_mechanism = { NULL, /* unwrap */ NULL, /* mech_data */ NULL, /* free_mech_data */ + NULL, /* copy_mech_data */ }; static void diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 32520741d1..b34d2f07d9 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -319,6 +319,7 @@ struct sc_pkcs11_mechanism_type { const void * mech_data; /* free mechanism specific data */ void (*free_mech_data)(const void *mech_data); + CK_RV (*copy_mech_data)(const void *mech_data, void **new_data); }; typedef struct sc_pkcs11_mechanism_type sc_pkcs11_mechanism_type_t; @@ -463,7 +464,7 @@ sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *, CK_MECHANISM_TYPE, unsigned int); sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR, CK_KEY_TYPE, - const void *, void (*)(const void *)); + const void *, void (*)(const void *), CK_RV (*)(const void *, void **)); sc_pkcs11_operation_t *sc_pkcs11_new_operation(sc_pkcs11_session_t *, sc_pkcs11_mechanism_type_t *); void sc_pkcs11_release_operation(sc_pkcs11_operation_t **); From 4fbe43c835f09267cb58ab0c8bffb3a244e01147 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 25 Feb 2022 18:14:45 +0100 Subject: [PATCH 2301/4321] Return registered mechanism structure For further use in sc_pkcs11_register_sign_and_hash_mechanism() --- src/pkcs11/framework-pkcs15.c | 90 +++++++++++++++++------------------ src/pkcs11/mechanism.c | 7 ++- src/pkcs11/openssl.c | 16 +++---- src/pkcs11/sc-pkcs11.h | 2 +- 4 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9c4eb79b9b..09d339705d 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5793,7 +5793,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); free(mt); if (rc != CKR_OK) return rc; @@ -5803,7 +5803,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5813,7 +5813,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) &mech_info, CKK_GOSTR3410, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5826,7 +5826,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, unsigned long ext_flags, CK_ULONG min_key_size, CK_ULONG max_key_size) { CK_MECHANISM_INFO mech_info; - sc_pkcs11_mechanism_type_t *mt; + sc_pkcs11_mechanism_type_t *mt, *registered_mt; CK_FLAGS ec_flags = 0; CK_RV rc; @@ -5854,7 +5854,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; if (flags & SC_ALGORITHM_ECDSA_HASH_NONE) { - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); if (rc != CKR_OK) return rc; } @@ -5865,35 +5865,35 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (flags & SC_ALGORITHM_ECDSA_RAW) { if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA1)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA1, CKM_SHA_1, mt); + CKM_ECDSA_SHA1, CKM_SHA_1, registered_mt); if (rc != CKR_OK) return rc; } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA224)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA224, CKM_SHA224, mt); + CKM_ECDSA_SHA224, CKM_SHA224, registered_mt); if (rc != CKR_OK) return rc; } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA256)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA256, CKM_SHA256, mt); + CKM_ECDSA_SHA256, CKM_SHA256, registered_mt); if (rc != CKR_OK) return rc; } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA384)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA384, CKM_SHA384, mt); + CKM_ECDSA_SHA384, CKM_SHA384, registered_mt); if (rc != CKR_OK) return rc; } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA512)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA512, CKM_SHA512, mt); + CKM_ECDSA_SHA512, CKM_SHA512, registered_mt); if (rc != CKR_OK) return rc; } @@ -5905,7 +5905,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA1, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5914,7 +5914,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA224, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5923,7 +5923,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA256, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5932,7 +5932,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA384, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5941,7 +5941,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA512, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5955,14 +5955,14 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_COFACTOR_DERIVE, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -5973,7 +5973,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, mt = sc_pkcs11_new_fw_mechanism(CKM_EC_KEY_PAIR_GEN, &mech_info, CKK_EC, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6001,7 +6001,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags mt = sc_pkcs11_new_fw_mechanism(CKM_EDDSA, &mech_info, CKK_EC_EDWARDS, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6012,7 +6012,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags &mech_info, CKK_EC_EDWARDS, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6035,7 +6035,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag mt = sc_pkcs11_new_fw_mechanism(CKM_XEDDSA, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6049,7 +6049,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6059,7 +6059,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag mt = sc_pkcs11_new_fw_mechanism(CKM_EC_MONTGOMERY_KEY_PAIR_GEN, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6087,21 +6087,21 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int mt = sc_pkcs11_new_fw_mechanism(CKM_AES_ECB, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; mt = sc_pkcs11_new_fw_mechanism(CKM_AES_CBC_PAD, &mech_info, CKK_AES, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; @@ -6122,7 +6122,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) CK_ULONG ec_min_key_size, ec_max_key_size, aes_min_key_size, aes_max_key_size; unsigned long ec_ext_flags; - sc_pkcs11_mechanism_type_t *mt; + sc_pkcs11_mechanism_type_t *mt, *registered_mt; unsigned int num; int rsa_flags = 0, ec_flags = 0, eddsa_flags = 0, xeddsa_flags = 0; int ec_found = 0, gostr_flags = 0, aes_flags = 0; @@ -6229,7 +6229,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* Check if we support raw RSA */ if (rsa_flags & SC_ALGORITHM_RSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; @@ -6245,7 +6245,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_ISO9796) { /* Supported in hardware only, if the card driver declares it. */ mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } @@ -6264,7 +6264,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* No need to Check for PKCS1 We support it in software and turned it on above so always added it */ if (rsa_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); if (rc != CKR_OK) return rc; @@ -6275,43 +6275,43 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt); + CKM_SHA1_RSA_PKCS, CKM_SHA_1, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA224_RSA_PKCS, CKM_SHA224, mt); + CKM_SHA224_RSA_PKCS, CKM_SHA224, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA256_RSA_PKCS, CKM_SHA256, mt); + CKM_SHA256_RSA_PKCS, CKM_SHA256, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA384_RSA_PKCS, CKM_SHA384, mt); + CKM_SHA384_RSA_PKCS, CKM_SHA384, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA512_RSA_PKCS, CKM_SHA512, mt); + CKM_SHA512_RSA_PKCS, CKM_SHA512, registered_mt); if (rc != CKR_OK) return rc; } if (!FIPS_mode() && rsa_flags & SC_ALGORITHM_RSA_HASH_MD5) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_MD5_RSA_PKCS, CKM_MD5, mt); + CKM_MD5_RSA_PKCS, CKM_MD5, registered_mt); if (rc != CKR_OK) return rc; } if (!FIPS_mode() && rsa_flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); + CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, registered_mt); if (rc != CKR_OK) return rc; } @@ -6322,37 +6322,37 @@ register_mechanisms(struct sc_pkcs11_card *p11card) CK_FLAGS old_flags = mech_info.flags; mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); if (rc != CKR_OK) return rc; if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); + CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, mt); + CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); + CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, mt); + CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, registered_mt); if (rc != CKR_OK) return rc; } if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, mt); + CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, registered_mt); if (rc != CKR_OK) return rc; } @@ -6363,7 +6363,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) CK_FLAGS old_flags = mech_info.flags; mech_info.flags &= ~(CKF_SIGN|CKF_VERIFY|CKF_SIGN_RECOVER|CKF_VERIFY_RECOVER); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) { return rc; } @@ -6375,7 +6375,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, &mech_info, CKK_RSA, NULL, NULL, NULL); if (!mt) return CKR_HOST_MEMORY; - rc = sc_pkcs11_register_mechanism(p11card, mt); + rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); if (rc != CKR_OK) return rc; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 386862b722..d7da0b570e 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -121,7 +121,7 @@ sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, */ CK_RV sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, - sc_pkcs11_mechanism_type_t *mt) + sc_pkcs11_mechanism_type_t *mt, sc_pkcs11_mechanism_type_t **result_mt) { sc_pkcs11_mechanism_type_t *existing_mt; sc_pkcs11_mechanism_type_t *copy_mt = NULL; @@ -168,6 +168,9 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, p11card->mechanisms = p; p[p11card->nmechanisms++] = copy_mt; p[p11card->nmechanisms] = NULL; + /* Return registered mechanism for further use */ + if (result_mt) + *result_mt = copy_mt; return CKR_OK; } @@ -1376,7 +1379,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, return CKR_HOST_MEMORY; } - rv = sc_pkcs11_register_mechanism(p11card, new_type); + rv = sc_pkcs11_register_mechanism(p11card, new_type, NULL); if (CKR_OK != rv) { new_type->free_mech_data(new_type->mech_data); free(new_type); diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 5f78b57ba7..538e22e35b 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -273,23 +273,23 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) #endif /* !defined(OPENSSL_NO_ENGINE) */ openssl_sha1_mech.mech_data = EVP_sha1(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech), NULL); openssl_sha224_mech.mech_data = EVP_sha224(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech), NULL); openssl_sha256_mech.mech_data = EVP_sha256(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech), NULL); openssl_sha384_mech.mech_data = EVP_sha384(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech), NULL); openssl_sha512_mech.mech_data = EVP_sha512(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech), NULL); if (!FIPS_mode()) { openssl_md5_mech.mech_data = EVP_md5(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech), NULL); openssl_ripemd160_mech.mech_data = EVP_ripemd160(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech), NULL); } openssl_gostr3411_mech.mech_data = EVP_get_digestbynid(NID_id_GostR3411_94); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech)); + sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech), NULL); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index b34d2f07d9..6a9ae1eedc 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -434,7 +434,7 @@ CK_RV attr_extract(CK_ATTRIBUTE_PTR, void *, size_t *); /* Generic Mechanism functions */ CK_RV sc_pkcs11_register_mechanism(struct sc_pkcs11_card *, - sc_pkcs11_mechanism_type_t *); + sc_pkcs11_mechanism_type_t *, sc_pkcs11_mechanism_type_t **); CK_RV sc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_get_mechanism_info(struct sc_pkcs11_card *, CK_MECHANISM_TYPE, From a4cd75c6b8873f70254e398264d5a02be8018441 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 25 Feb 2022 18:34:36 +0100 Subject: [PATCH 2302/4321] Free mechanism after registering In case of success, copy is stored on p11card. --- src/pkcs11/framework-pkcs15.c | 27 ++++++++++++++++++++++++++- src/pkcs11/mechanism.c | 15 +++++++++++---- src/pkcs11/sc-pkcs11.h | 1 + 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 09d339705d..f5e18930ef 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5794,7 +5794,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - free(mt); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5804,6 +5804,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5814,6 +5815,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5855,6 +5857,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, return CKR_HOST_MEMORY; if (flags & SC_ALGORITHM_ECDSA_HASH_NONE) { rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5906,6 +5909,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5915,6 +5919,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5924,6 +5929,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5933,6 +5939,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5942,6 +5949,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5956,6 +5964,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -5963,6 +5972,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -5974,6 +5984,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6002,6 +6013,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6013,6 +6025,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6036,6 +6049,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6050,6 +6064,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6060,6 +6075,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6088,6 +6104,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6095,6 +6112,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6102,6 +6120,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6230,6 +6249,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6246,6 +6266,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* Supported in hardware only, if the card driver declares it. */ mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } @@ -6265,6 +6286,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6323,6 +6345,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; @@ -6364,6 +6387,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mech_info.flags &= ~(CKF_SIGN|CKF_VERIFY|CKF_SIGN_RECOVER|CKF_VERIFY_RECOVER); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) { return rc; } @@ -6376,6 +6400,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); if (rc != CKR_OK) return rc; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index d7da0b570e..b90a43c461 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1315,6 +1315,16 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, return mt; } +void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t *mt) +{ + if (!mt) + return; + if (mt->free_mech_data) + mt->free_mech_data(mt->mech_data); + free(mt); + mt = NULL; +} + /* * Register generic mechanisms */ @@ -1380,10 +1390,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, } rv = sc_pkcs11_register_mechanism(p11card, new_type, NULL); - if (CKR_OK != rv) { - new_type->free_mech_data(new_type->mech_data); - free(new_type); - } + sc_pkcs11_free_mechanism(new_type); return rv; } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 6a9ae1eedc..13e3a5adbe 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -465,6 +465,7 @@ sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *, sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR, CK_KEY_TYPE, const void *, void (*)(const void *), CK_RV (*)(const void *, void **)); +void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t *mt); sc_pkcs11_operation_t *sc_pkcs11_new_operation(sc_pkcs11_session_t *, sc_pkcs11_mechanism_type_t *); void sc_pkcs11_release_operation(sc_pkcs11_operation_t **); From ac8e93de82cd8fdd7395b7326fd2186ffc2a34f5 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 25 Feb 2022 18:41:55 +0100 Subject: [PATCH 2303/4321] Free duplicated mechanisms --- src/pkcs11/openssl.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 538e22e35b..d029d56b77 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -226,6 +226,7 @@ static void * dup_mem(void *in, size_t in_len) void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) { + sc_pkcs11_mechanism_type_t *mt = NULL; #if !defined(OPENSSL_NO_ENGINE) ENGINE *e; /* crypto locking removed in 1.1 */ @@ -273,23 +274,47 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) #endif /* !defined(OPENSSL_NO_ENGINE) */ openssl_sha1_mech.mech_data = EVP_sha1(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech), NULL); + mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + openssl_sha224_mech.mech_data = EVP_sha224(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech), NULL); + mt = dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + openssl_sha256_mech.mech_data = EVP_sha256(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech), NULL); + mt = dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + openssl_sha384_mech.mech_data = EVP_sha384(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech), NULL); + mt = dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + openssl_sha512_mech.mech_data = EVP_sha512(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech), NULL); + mt = dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + if (!FIPS_mode()) { openssl_md5_mech.mech_data = EVP_md5(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech), NULL); + mt = dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + openssl_ripemd160_mech.mech_data = EVP_ripemd160(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech), NULL); + mt = dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + } openssl_gostr3411_mech.mech_data = EVP_get_digestbynid(NID_id_GostR3411_94); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech), NULL); + mt = dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(mt); + } From f03fad48d2bbe0a9f21cadee4d3d7010e1d1c064 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Feb 2022 13:32:35 +0100 Subject: [PATCH 2304/4321] Check input params before copying --- src/pkcs11/mechanism.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index b90a43c461..b85b19cc80 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -98,6 +98,8 @@ static CK_RV sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, sc_pkcs11_mechanism_type_t **new_mt) { + int rv; + *new_mt = calloc(1, sizeof(sc_pkcs11_mechanism_type_t)); if (!(*new_mt)) return CKR_HOST_MEMORY; @@ -105,9 +107,9 @@ sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, memcpy(*new_mt, mt, sizeof(sc_pkcs11_mechanism_type_t)); /* mech_data needs specific function for making copy*/ if (mt->copy_mech_data - && mt->copy_mech_data(mt->mech_data, (void **) &(*new_mt)->mech_data) != CKR_OK) { + && (rv = mt->copy_mech_data(mt->mech_data, (void **) &(*new_mt)->mech_data)) != CKR_OK) { free(*new_mt); - return CKR_HOST_MEMORY; + return rv; } return CKR_OK; @@ -1344,8 +1346,11 @@ void free_info(const void *info) CK_RV copy_hash_signature_info(const void *mech_data, void **new_data) { + if (mech_data == NULL || new_data == NULL) + return CKR_ARGUMENTS_BAD; + *new_data = calloc(1, sizeof(struct hash_signature_info)); - if (!new_data) + if (!(*new_data)) return CKR_HOST_MEMORY; memcpy(*new_data, mech_data, sizeof(struct hash_signature_info)); From 252e422b962eed09c783800c011e9f6975f63e82 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Feb 2022 21:09:23 +0100 Subject: [PATCH 2305/4321] Return appropriate error code if copying fails --- src/pkcs11/mechanism.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index b85b19cc80..0e4fc358c7 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -128,7 +128,7 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, sc_pkcs11_mechanism_type_t *existing_mt; sc_pkcs11_mechanism_type_t *copy_mt = NULL; sc_pkcs11_mechanism_type_t **p; - int i; + int i, rv; if (mt == NULL) return CKR_HOST_MEMORY; @@ -163,9 +163,9 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, (p11card->nmechanisms + 2) * sizeof(*p)); if (p == NULL) return CKR_HOST_MEMORY; - if (sc_pkcs11_copy_mechanism(mt, ©_mt) != CKR_OK) { + if ((rv = sc_pkcs11_copy_mechanism(mt, ©_mt)) != CKR_OK) { free(p); - return CKR_HOST_MEMORY; + return rv; } p11card->mechanisms = p; p[p11card->nmechanisms++] = copy_mt; From 60b2fc8856df5ce51fed0c14a88cebef502f1b75 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Feb 2022 21:10:17 +0100 Subject: [PATCH 2306/4321] Remove NULL assignment --- src/pkcs11/mechanism.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 0e4fc358c7..ae56b05eec 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1324,7 +1324,6 @@ void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t *mt) if (mt->free_mech_data) mt->free_mech_data(mt->mech_data); free(mt); - mt = NULL; } /* From bec4f63c5b8308d7fdca842c5c0b62c3491d106a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Nov 2021 18:21:06 +0100 Subject: [PATCH 2307/4321] fuzzing: Fuzzer for parsing & testing pkcs15init --- src/tests/fuzzing/Makefile.am | 8 +- src/tests/fuzzing/fuzz_pkcs15init.c | 528 ++++++++++++++++++++++++++++ 2 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 src/tests/fuzzing/fuzz_pkcs15init.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index e7aa18d4fe..8cccdd4822 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -1,12 +1,13 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src +AM_CPPFLAGS = -I$(top_srcdir)/src -D'SC_PKCS15_PROFILE_DIRECTORY="$(pkgdatadir)"' AM_CFLAGS = -g -O0 $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ + $(top_builddir)/src/pkcs15init/libpkcs15init.la \ $(top_builddir)/src/common/libcompat.la noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ - fuzz_scconf_parse_string + fuzz_scconf_parse_string fuzz_pkcs15init ADDITIONAL_SRC = if !ENABLE_FUZZING @@ -18,3 +19,6 @@ fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c $(ADDITIONAL_SRC) fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) +fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c $(ADDITIONAL_SRC) +fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) +fuzz_pkcs15init_LDFLAGS = -static diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c new file mode 100644 index 0000000000..08285e9013 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -0,0 +1,528 @@ +/* + * fuzz_pkcs15init.c: Fuzzer for functions processing pkcs15 init + * + * Copyright (C) 2021 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pkcs15init/pkcs15-lib.c" +#include "scconf/scconf.h" +#include "pkcs15init/pkcs15-init.h" +#include "pkcs15init/profile.c" +#include "pkcs15init/profile.h" +#include "libopensc/internal.h" + +#include +#include + + + +/* Taken from fuzz_pkcs15_reader.c */ +struct driver_data { + const uint8_t *Data; + size_t Size; +}; + +static struct sc_reader_operations fuzz_ops = {0}; +static struct sc_reader_driver fuzz_drv = { + "Fuzzing reader", + "fuzz", + &fuzz_ops, + NULL +}; + +void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size) +{ + struct driver_data *data; + uint16_t c_size; + const uint8_t *c; + + if (chunk) + *chunk = NULL; + if (chunk_size) + *chunk_size = 0; + + if (!chunk || !chunk_size || !reader) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + data = reader->drv_data; + if (!data || !data->Data || data->Size < sizeof c_size) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + /* parse the length of the returned data on two bytes */ + c_size = *((uint16_t *) data->Data); + /* consume two bytes from the fuzzing data */ + data->Size -= sizeof c_size; + data->Data += sizeof c_size; + + if (data->Size < c_size) { + c_size = data->Size; + } + + /* consume the bytes from the fuzzing data */ + c = data->Data; + data->Size -= c_size; + data->Data += c_size; + + sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Returning fuzzing chunk", c, c_size); + + *chunk = c; + *chunk_size = c_size; +} + +static int fuzz_reader_release(sc_reader_t *reader) +{ + if (reader) { + free(reader->drv_data); + reader->drv_data = NULL; + } + + return SC_SUCCESS; +} + +static int fuzz_reader_connect(sc_reader_t *reader) +{ + uint16_t chunk_size; + const uint8_t *chunk; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size > SC_MAX_ATR_SIZE) + chunk_size = SC_MAX_ATR_SIZE; + else + reader->atr.len = chunk_size; + + if (chunk_size > 0) + memcpy(reader->atr.value, chunk, chunk_size); + + return SC_SUCCESS; +} + +static int fuzz_reader_disconnect(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) +{ + const uint8_t *chunk; + uint16_t chunk_size; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size >= 2) { + /* set the SW1 and SW2 status bytes (the last two bytes of + * the response */ + apdu->sw1 = (unsigned int)chunk[chunk_size - 2]; + apdu->sw2 = (unsigned int)chunk[chunk_size - 1]; + chunk_size -= 2; + /* set output length and copy the returned data if necessary */ + if (chunk_size <= apdu->resplen) + apdu->resplen = chunk_size; + + if (apdu->resplen != 0) + memcpy(apdu->resp, chunk, apdu->resplen); + } else { + apdu->sw1 = 0x6D; + apdu->sw2 = 0x00; + apdu->resplen = 0; + } + + return SC_SUCCESS; +} + +struct sc_reader_driver *sc_get_fuzz_driver(void) +{ + fuzz_ops.release = fuzz_reader_release; + fuzz_ops.connect = fuzz_reader_connect; + fuzz_ops.disconnect = fuzz_reader_disconnect; + fuzz_ops.transmit = fuzz_reader_transmit; + return &fuzz_drv; +} + +void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) +{ + sc_reader_t *reader; + struct driver_data *data; + char name[64] = {0}; + + if (!(reader = calloc(1, sizeof(*reader))) + || !(data = (calloc(1, sizeof(*data))))) { + free(reader); + return; + } + + data->Data = Data; + data->Size = Size; + + reader->driver = &fuzz_drv; + reader->ops = &fuzz_ops; + reader->drv_data = data; + snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)", + Size, Size == 1 ? "" : "s", Data); + reader->name = strdup(name); + + reader->ctx = ctx; + list_append(&ctx->readers, reader); +} + +int fuzz_profile_load(struct sc_profile *profile, const uint8_t *data, size_t size) +{ + int rv = 0; + scconf_context *conf = NULL; + conf = scconf_new(NULL); + if (!conf) + return 0; + + if ((rv = scconf_parse_string(conf, (char *)data)) < 0) { + scconf_free(conf); + return rv; + } + + rv = process_conf(profile, conf); + scconf_free(conf); + return rv; +} + +void fuzz_pkcs15init_bind(struct sc_card *card, struct sc_profile **result, + const uint8_t *data, size_t size) +{ + struct sc_profile *profile = NULL; + const char *driver = card->driver->short_name; + struct sc_pkcs15init_operations * (* func)(void) = NULL; + int r = 0; + *result = NULL; + + r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN); + if (r < 0 && r != SC_ERROR_NOT_SUPPORTED) { + return; + } + + profile = sc_profile_new(); + profile->card = card; + + for (int i = 0; profile_operations[i].name; i++) { + if (!strcasecmp(driver, profile_operations[i].name)) { + func = (struct sc_pkcs15init_operations *(*)(void)) profile_operations[i].func; + break; + } + } + if (func) { + profile->ops = func(); + } else { + sc_profile_free(profile); + return; + } + profile->name = strdup("Fuzz profile"); + + r = sc_pkcs15init_read_info(card, profile); + if (r < 0) { + sc_profile_free(profile); + return; + } + + if (fuzz_profile_load(profile, data, size) < 0) { + sc_profile_free(profile); + return; + } + + if (sc_profile_finish(profile, NULL) < 0) { + sc_profile_free(profile); + return; + } + *result = profile; +} + +int fuzz_get_reader_data(const uint8_t *from, size_t from_size, const uint8_t **to, size_t *to_size) +{ + size_t i = 0; + while(i < from_size - 1 && from[i] != '\0') + i++; + + if (from[i] != '\0') + return 0; + + *to_size = from_size - (i + 1); + *to = from + (i + 1); + return 1; +} + +void do_init_app(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_card_t *card, + unsigned char *so_pin, unsigned char *so_puk) +{ + struct sc_pkcs15init_initargs init_args; + sc_pkcs15_auth_info_t info; + int so_puk_disabled = 0; + + memset(&init_args, 0, sizeof(init_args)); + sc_pkcs15init_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &info); + if ((info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED) && + (info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)) + so_puk_disabled = 1; + + sc_pkcs15init_get_pin_info(profile, SC_PKCS15INIT_SO_PUK, &info); + + init_args.so_pin = so_pin; + init_args.so_pin_len = 8; + + if (!so_puk_disabled) { + init_args.so_puk = so_puk; + init_args.so_puk_len = 8; + } + + sc_pkcs15init_add_app(card, profile, &init_args); +} + +void do_store_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_card_t *card, + unsigned char *pin, unsigned char *so_pin) +{ + struct sc_pkcs15init_pinargs pin_args; + char pin_id[SC_PKCS15_MAX_ID_SIZE] = "1\0"; + sc_pkcs15init_set_p15card(profile, p15card); + + memcpy(pin, "1234555678\0", 11); /* Set new pin */ + memset(&pin_args, 0, sizeof(pin_args)); + + sc_pkcs15_format_id(pin_id, &pin_args.auth_id); + pin_args.pin = pin; + pin_args.pin_len = 6; + pin_args.label = "Basic PIN"; + + pin_args.puk = so_pin; + pin_args.puk_len = 8; + + sc_pkcs15init_store_pin(p15card, profile, &pin_args); +} + +void do_store_data_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_card_t *card, + uint8_t *buf, size_t len) +{ + struct sc_pkcs15init_dataargs args; + char value[SC_MAX_OBJECT_ID_OCTETS]; + + memcpy(value, buf, SC_MAX_OBJECT_ID_OCTETS); + + memset(&args, 0, sizeof(args)); + sc_init_oid(&args.app_oid); + args.label = "label"; + args.app_label = "pkcs15-init"; + + sc_format_oid(&args.app_oid, value); + + args.der_encoded.value = buf; + args.der_encoded.len = len; + sc_pkcs15init_store_data_object(p15card, profile, &args, NULL); +} + +void do_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_card_t *card) +{ + struct sc_pkcs15init_keygen_args keygen_args; + int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC }; + unsigned int keybits[] = { 1024, 0 }; + + memset(&keygen_args, 0, sizeof(keygen_args)); + sc_pkcs15_format_id("01", &(keygen_args.prkey_args.auth_id)); + keygen_args.prkey_args.access_flags |= + SC_PKCS15_PRKEY_ACCESS_SENSITIVE + | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE + | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE + | SC_PKCS15_PRKEY_ACCESS_LOCAL; + + for (int i = 1; i < 2; i++) { + keygen_args.prkey_args.key.algorithm = algorithms[i]; + if (algorithms[i] == SC_ALGORITHM_EC) /* strdup called also in parse_alg_spec() */ + keygen_args.prkey_args.key.u.ec.params.named_curve = strdup("prime256v1"); + sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits[i], NULL); + } +} + +void do_generate_skey(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_card_t *card) +{ + struct sc_pkcs15init_skeyargs skey_args; + int algorithms[] = { SC_ALGORITHM_DES, SC_ALGORITHM_3DES, SC_ALGORITHM_AES }; + unsigned int keybits[] = { 64, 192, 128 }; + + /* init keygen_args*/ + memset(&skey_args, 0, sizeof(skey_args)); + skey_args.label = "label"; + skey_args.usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; + skey_args.user_consent = 0; + + for (int i = 0; i < 3; i++) { + skey_args.algorithm = algorithms[i]; + skey_args.value_len = keybits[i]; + sc_pkcs15init_generate_secret_key(p15card, profile, &skey_args, NULL); + } +} + +void do_store_secret_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, + sc_card_t *card, uint8_t *buf) +{ + struct sc_pkcs15init_skeyargs args; + int algorithms[] = { SC_ALGORITHM_AES, SC_ALGORITHM_DES, SC_ALGORITHM_3DES }; + unsigned int keybits[] = { 128, 64, 192 }; + + memset(&args, 0, sizeof(args)); + args.access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE | SC_PKCS15_PRKEY_ACCESS_SENSITIVE; + args.usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; + sc_pkcs15_format_id("02", &(args.auth_id)); + + for (int i = 0; i < 3; i++) { + size_t keybytes = (keybits[i] + 7) / 8; + args.key.data = malloc(keybytes); + memcpy(args.key.data, buf, keybytes); + args.key.data_len = keybytes; + args.algorithm = algorithms[i]; + args.value_len = keybits[i]; + + sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); + if (args.key.data) + free(args.key.data); + } +} + +void do_erase(struct sc_profile *profile, sc_card_t *card) +{ + struct sc_pkcs15_card *p15card; + + p15card = sc_pkcs15_card_new(); + p15card->card = card; + + sc_pkcs15init_erase_card(p15card, profile, NULL); + sc_pkcs15_card_free(p15card); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + sc_context_t *ctx = NULL; + sc_card_t *card = NULL; + struct sc_pkcs15_card *p15card = NULL; + struct sc_profile *profile = NULL; + struct sc_reader *reader = NULL; + const uint8_t *reader_data = NULL; + size_t reader_data_size = 0; + uint8_t *buf = NULL; + uint16_t len = size < 256 ? size : 256; + unsigned char *pin = NULL; + unsigned char *so_pin = NULL; + unsigned char *puk = NULL; + unsigned char *so_puk = NULL; + struct sc_pkcs15_card *tmp_p15_data = NULL; + + if (size == 0) + return 0; + + if (!fuzz_get_reader_data(data, size, &reader_data, &reader_data_size)) { + return 0; + } + + /* Establish context for fuzz app*/ + sc_establish_context(&ctx, "fuzz"); + if (!ctx) + return 0; + + /* Erase possible readers from ctx */ + while (list_size(&ctx->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); + + /* Create virtual reader */ + ctx->reader_driver = sc_get_fuzz_driver(); + fuzz_add_reader(ctx, reader_data, reader_data_size); + reader = sc_ctx_get_reader(ctx, 0); + + /* Connect card to reader */ + if (sc_connect_card(reader, &card)) { // last op with card in open_reader_and_card + sc_release_context(ctx); + return 0; + } + + /* Load profile and bind with card */ + fuzz_pkcs15init_bind(card, &profile, data, size - reader_data_size); + + if(!profile) + goto end; + + pin = malloc(11); + so_pin = malloc(9); + puk = malloc(9); + so_puk = malloc(9); + memcpy(pin, "123456\0", 7); + memcpy(so_pin, "12345678\0", 9); + memcpy(puk, "12345678\0", 9); + memcpy(so_puk, "12345678\0", 9); + + buf = malloc(len * sizeof(char)); + memcpy(buf, data, len); + + /* test pkcs15-init functionality*/ + do_init_app(profile, p15card, card, so_pin, so_puk); + + if (!sc_pkcs15_bind(card, NULL, &p15card)) { /* First and only sc_pkcs15_bind calling, is omitted in next cases*/ + do_store_pin(profile, p15card, card, pin, so_pin); + } + + /* sc_pkcs15_bind failed, no point in testing next cases */ + if (!p15card) + goto end_release; + + do_store_data_object(profile, p15card, card, buf, len); + do_generate_key(profile, p15card, card); + do_generate_skey(profile, p15card, card); + do_store_secret_key(profile, p15card, card, buf); + + sc_pkcs15init_finalize_card(card, profile); + sc_pkcs15init_sanity_check(p15card, profile); + + do_erase(profile, card); + +end_release: + free(pin); + free(puk); + free(so_pin); + free(so_puk); + free(buf); + +end: + if (profile) { + tmp_p15_data = profile->p15_data; + sc_pkcs15init_unbind(profile); + if (tmp_p15_data != p15card) + sc_pkcs15_unbind(tmp_p15_data); + } + if (p15card) { + sc_pkcs15_unbind(p15card); + } + if (card) + sc_disconnect_card(card); + sc_release_context(ctx); + + return 0; +} From 3a3efe765e0c5d4828eec9eb7a2580c18db9a69e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 27 Jan 2022 13:58:32 +0100 Subject: [PATCH 2308/4321] fuzzing: Put reader functions into separate file --- src/tests/fuzzing/Makefile.am | 4 +- src/tests/fuzzing/fuzz_pkcs15_reader.c | 157 +---------------------- src/tests/fuzzing/fuzz_pkcs15init.c | 159 +---------------------- src/tests/fuzzing/fuzzer_reader.c | 171 +++++++++++++++++++++++++ src/tests/fuzzing/fuzzer_reader.h | 25 ++++ 5 files changed, 200 insertions(+), 316 deletions(-) create mode 100644 src/tests/fuzzing/fuzzer_reader.c create mode 100644 src/tests/fuzzing/fuzzer_reader.h diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 8cccdd4822..576dc037c6 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -17,8 +17,8 @@ endif fuzz_asn1_print_SOURCES = fuzz_asn1_print.c $(ADDITIONAL_SRC) fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) -fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c $(ADDITIONAL_SRC) +fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c fuzzer_reader.c fuzzer_reader.h $(ADDITIONAL_SRC) fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) -fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c $(ADDITIONAL_SRC) +fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c fuzzer_reader.h $(ADDITIONAL_SRC) fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) fuzz_pkcs15init_LDFLAGS = -static diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index b1f1c85d32..e758e26d5a 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -20,168 +20,13 @@ #include "config.h" #endif +#include "fuzzer_reader.h" #include "libopensc/pkcs15.h" -#include "libopensc/internal.h" -#include -#include const char *__asan_default_options() { return "verbosity=0:mallocator_may_return_null=1"; } -/* private data structures */ -struct driver_data { - const uint8_t *Data; - size_t Size; -}; - -static struct sc_reader_operations fuzz_ops = {0}; -static struct sc_reader_driver fuzz_drv = { - "Fuzzing reader", - "fuzz", - &fuzz_ops, - NULL -}; - -void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size) -{ - struct driver_data *data; - uint16_t c_size; - const uint8_t *c; - - if (chunk) - *chunk = NULL; - if (chunk_size) - *chunk_size = 0; - - if (!chunk || !chunk_size || !reader) { - sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); - return; - } - data = reader->drv_data; - if (!data || !data->Data || data->Size < sizeof c_size) { - sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); - return; - } - - /* parse the length of the returned data on two bytes */ - c_size = *((uint16_t *) data->Data); - /* consume two bytes from the fuzzing data */ - data->Size -= sizeof c_size; - data->Data += sizeof c_size; - - if (data->Size < c_size) { - c_size = data->Size; - } - - /* consume the bytes from the fuzzing data */ - c = data->Data; - data->Size -= c_size; - data->Data += c_size; - - sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, - "Returning fuzzing chunk", c, c_size); - - *chunk = c; - *chunk_size = c_size; -} - -static int fuzz_reader_release(sc_reader_t *reader) -{ - if (reader) { - free(reader->drv_data); - reader->drv_data = NULL; - } - - return SC_SUCCESS; -} - -static int fuzz_reader_connect(sc_reader_t *reader) -{ - uint16_t chunk_size; - const uint8_t *chunk; - - fuzz_get_chunk(reader, &chunk, &chunk_size); - - if (chunk_size > SC_MAX_ATR_SIZE) - chunk_size = SC_MAX_ATR_SIZE; - else - reader->atr.len = chunk_size; - - if (chunk_size > 0) - memcpy(reader->atr.value, chunk, chunk_size); - - return SC_SUCCESS; -} - -static int fuzz_reader_disconnect(sc_reader_t *reader) -{ - return SC_SUCCESS; -} - -static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) -{ - const uint8_t *chunk; - uint16_t chunk_size; - - fuzz_get_chunk(reader, &chunk, &chunk_size); - - if (chunk_size >= 2) { - /* set the SW1 and SW2 status bytes (the last two bytes of - * the response */ - apdu->sw1 = (unsigned int)chunk[chunk_size - 2]; - apdu->sw2 = (unsigned int)chunk[chunk_size - 1]; - chunk_size -= 2; - /* set output length and copy the returned data if necessary */ - if (chunk_size <= apdu->resplen) - apdu->resplen = chunk_size; - - if (apdu->resplen != 0) - memcpy(apdu->resp, chunk, apdu->resplen); - } else { - apdu->sw1 = 0x6D; - apdu->sw2 = 0x00; - apdu->resplen = 0; - } - - return SC_SUCCESS; -} - -struct sc_reader_driver *sc_get_fuzz_driver(void) -{ - fuzz_ops.release = fuzz_reader_release; - fuzz_ops.connect = fuzz_reader_connect; - fuzz_ops.disconnect = fuzz_reader_disconnect; - fuzz_ops.transmit = fuzz_reader_transmit; - return &fuzz_drv; -} - -void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) -{ - sc_reader_t *reader; - struct driver_data *data; - char name[64] = {0}; - - if (!(reader = calloc(1, sizeof(*reader))) - || !(data = (calloc(1, sizeof(*data))))) { - free(reader); - return; - } - - data->Data = Data; - data->Size = Size; - - reader->driver = &fuzz_drv; - reader->ops = &fuzz_ops; - reader->drv_data = data; - snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)", - Size, Size == 1 ? "" : "s", Data); - reader->name = strdup(name); - - reader->ctx = ctx; - list_append(&ctx->readers, reader); -} - int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { struct sc_context *ctx = NULL; diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 08285e9013..425d4aa8dd 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -23,169 +23,12 @@ #include "config.h" #endif +#include "fuzzer_reader.h" #include "pkcs15init/pkcs15-lib.c" #include "scconf/scconf.h" #include "pkcs15init/pkcs15-init.h" #include "pkcs15init/profile.c" #include "pkcs15init/profile.h" -#include "libopensc/internal.h" - -#include -#include - - - -/* Taken from fuzz_pkcs15_reader.c */ -struct driver_data { - const uint8_t *Data; - size_t Size; -}; - -static struct sc_reader_operations fuzz_ops = {0}; -static struct sc_reader_driver fuzz_drv = { - "Fuzzing reader", - "fuzz", - &fuzz_ops, - NULL -}; - -void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size) -{ - struct driver_data *data; - uint16_t c_size; - const uint8_t *c; - - if (chunk) - *chunk = NULL; - if (chunk_size) - *chunk_size = 0; - - if (!chunk || !chunk_size || !reader) { - sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); - return; - } - data = reader->drv_data; - if (!data || !data->Data || data->Size < sizeof c_size) { - sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); - return; - } - /* parse the length of the returned data on two bytes */ - c_size = *((uint16_t *) data->Data); - /* consume two bytes from the fuzzing data */ - data->Size -= sizeof c_size; - data->Data += sizeof c_size; - - if (data->Size < c_size) { - c_size = data->Size; - } - - /* consume the bytes from the fuzzing data */ - c = data->Data; - data->Size -= c_size; - data->Data += c_size; - - sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, - "Returning fuzzing chunk", c, c_size); - - *chunk = c; - *chunk_size = c_size; -} - -static int fuzz_reader_release(sc_reader_t *reader) -{ - if (reader) { - free(reader->drv_data); - reader->drv_data = NULL; - } - - return SC_SUCCESS; -} - -static int fuzz_reader_connect(sc_reader_t *reader) -{ - uint16_t chunk_size; - const uint8_t *chunk; - - fuzz_get_chunk(reader, &chunk, &chunk_size); - - if (chunk_size > SC_MAX_ATR_SIZE) - chunk_size = SC_MAX_ATR_SIZE; - else - reader->atr.len = chunk_size; - - if (chunk_size > 0) - memcpy(reader->atr.value, chunk, chunk_size); - - return SC_SUCCESS; -} - -static int fuzz_reader_disconnect(sc_reader_t *reader) -{ - return SC_SUCCESS; -} - -static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) -{ - const uint8_t *chunk; - uint16_t chunk_size; - - fuzz_get_chunk(reader, &chunk, &chunk_size); - - if (chunk_size >= 2) { - /* set the SW1 and SW2 status bytes (the last two bytes of - * the response */ - apdu->sw1 = (unsigned int)chunk[chunk_size - 2]; - apdu->sw2 = (unsigned int)chunk[chunk_size - 1]; - chunk_size -= 2; - /* set output length and copy the returned data if necessary */ - if (chunk_size <= apdu->resplen) - apdu->resplen = chunk_size; - - if (apdu->resplen != 0) - memcpy(apdu->resp, chunk, apdu->resplen); - } else { - apdu->sw1 = 0x6D; - apdu->sw2 = 0x00; - apdu->resplen = 0; - } - - return SC_SUCCESS; -} - -struct sc_reader_driver *sc_get_fuzz_driver(void) -{ - fuzz_ops.release = fuzz_reader_release; - fuzz_ops.connect = fuzz_reader_connect; - fuzz_ops.disconnect = fuzz_reader_disconnect; - fuzz_ops.transmit = fuzz_reader_transmit; - return &fuzz_drv; -} - -void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) -{ - sc_reader_t *reader; - struct driver_data *data; - char name[64] = {0}; - - if (!(reader = calloc(1, sizeof(*reader))) - || !(data = (calloc(1, sizeof(*data))))) { - free(reader); - return; - } - - data->Data = Data; - data->Size = Size; - - reader->driver = &fuzz_drv; - reader->ops = &fuzz_ops; - reader->drv_data = data; - snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)", - Size, Size == 1 ? "" : "s", Data); - reader->name = strdup(name); - - reader->ctx = ctx; - list_append(&ctx->readers, reader); -} int fuzz_profile_load(struct sc_profile *profile, const uint8_t *data, size_t size) { diff --git a/src/tests/fuzzing/fuzzer_reader.c b/src/tests/fuzzing/fuzzer_reader.c new file mode 100644 index 0000000000..7d7a579b39 --- /dev/null +++ b/src/tests/fuzzing/fuzzer_reader.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "fuzzer_reader.h" + +/* private data structures */ +struct driver_data { + const uint8_t *Data; + size_t Size; +}; + +static struct sc_reader_operations fuzz_ops = {0}; +static struct sc_reader_driver fuzz_drv = { + "Fuzzing reader", + "fuzz", + &fuzz_ops, + NULL +}; + +void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size) +{ + struct driver_data *data; + uint16_t c_size; + const uint8_t *c; + + if (chunk) + *chunk = NULL; + if (chunk_size) + *chunk_size = 0; + + if (!chunk || !chunk_size || !reader) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + data = reader->drv_data; + if (!data || !data->Data || data->Size < sizeof c_size) { + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + return; + } + /* parse the length of the returned data on two bytes */ + c_size = *((uint16_t *) data->Data); + /* consume two bytes from the fuzzing data */ + data->Size -= sizeof c_size; + data->Data += sizeof c_size; + + if (data->Size < c_size) { + c_size = data->Size; + } + + /* consume the bytes from the fuzzing data */ + c = data->Data; + data->Size -= c_size; + data->Data += c_size; + + sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, + "Returning fuzzing chunk", c, c_size); + + *chunk = c; + *chunk_size = c_size; +} + +static int fuzz_reader_release(sc_reader_t *reader) +{ + if (reader) { + free(reader->drv_data); + reader->drv_data = NULL; + } + + return SC_SUCCESS; +} + +static int fuzz_reader_connect(sc_reader_t *reader) +{ + uint16_t chunk_size; + const uint8_t *chunk; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size > SC_MAX_ATR_SIZE) + chunk_size = SC_MAX_ATR_SIZE; + else + reader->atr.len = chunk_size; + + if (chunk_size > 0) + memcpy(reader->atr.value, chunk, chunk_size); + + return SC_SUCCESS; +} + +static int fuzz_reader_disconnect(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) +{ + const uint8_t *chunk; + uint16_t chunk_size; + + fuzz_get_chunk(reader, &chunk, &chunk_size); + + if (chunk_size >= 2) { + /* set the SW1 and SW2 status bytes (the last two bytes of + * the response */ + apdu->sw1 = (unsigned int)chunk[chunk_size - 2]; + apdu->sw2 = (unsigned int)chunk[chunk_size - 1]; + chunk_size -= 2; + /* set output length and copy the returned data if necessary */ + if (chunk_size <= apdu->resplen) + apdu->resplen = chunk_size; + + if (apdu->resplen != 0) + memcpy(apdu->resp, chunk, apdu->resplen); + } else { + apdu->sw1 = 0x6D; + apdu->sw2 = 0x00; + apdu->resplen = 0; + } + + return SC_SUCCESS; +} + +struct sc_reader_driver *sc_get_fuzz_driver(void) +{ + fuzz_ops.release = fuzz_reader_release; + fuzz_ops.connect = fuzz_reader_connect; + fuzz_ops.disconnect = fuzz_reader_disconnect; + fuzz_ops.transmit = fuzz_reader_transmit; + return &fuzz_drv; +} + +void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) +{ + sc_reader_t *reader; + struct driver_data *data; + char name[64] = {0}; + + if (!(reader = calloc(1, sizeof(*reader))) + || !(data = (calloc(1, sizeof(*data))))) { + free(reader); + return; + } + + data->Data = Data; + data->Size = Size; + + reader->driver = &fuzz_drv; + reader->ops = &fuzz_ops; + reader->drv_data = data; + snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)", + Size, Size == 1 ? "" : "s", Data); + reader->name = strdup(name); + + reader->ctx = ctx; + list_append(&ctx->readers, reader); +} diff --git a/src/tests/fuzzing/fuzzer_reader.h b/src/tests/fuzzing/fuzzer_reader.h new file mode 100644 index 0000000000..6267f9acda --- /dev/null +++ b/src/tests/fuzzing/fuzzer_reader.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 Frank Morgner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "libopensc/internal.h" +#include +#include + +void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size); +struct sc_reader_driver *sc_get_fuzz_driver(void); +void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size); From 58744abf2bb933b10729d36e5b43e469f6529f32 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 20 Dec 2021 11:54:19 +0100 Subject: [PATCH 2309/4321] fuzzing: Add description for generating apdu corpus --- src/tests/fuzzing/README.md | 113 ++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/tests/fuzzing/README.md diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md new file mode 100644 index 0000000000..1ebd735dc7 --- /dev/null +++ b/src/tests/fuzzing/README.md @@ -0,0 +1,113 @@ +# Fuzzing + +## Corpus semantics + +The corpus files for the `fuzz_pkcs15_reader` are interpreted by the virtual +reader as follows: + + * first two bytes denote the block length N as unsigned integer. The endianness + depends on the architecture + * the following block of the length N + +The first block is always the ATR of the card, which is very frequently used +for card detection. + +All the other following blocks are used as replies from the emulated card. + +Example block: +``` +0f 00 + -- length indicator saying next block is 15 bytes long +3b f5 96 00 00 81 31 fe 45 4d 79 45 49 44 14 + -- the 15 bytes block (in this case ATR) + +29 00 + -- the second block length of 41 bytes +6f 25 81 02 7f ff 82 01 38 83 02 50 15 86 03 11 +1f ff 85 02 00 02 8a 01 01 84 0c a0 00 00 00 63 +50 4b 43 53 2d 31 35 90 00 + -- 41 bytes data block (APDU response) +``` + +### How to generate corpus files from existing cards + +Modify the `src/libopensc/reader-pcsc.c` and uncomment the following line: +``` +#define APDU_LOG_FILE "apdulog" +``` +and rebuild OpenSC. Then run any opensc tool talking to the card. For example +``` +./src/tools/pkcs11-tool -L --module ./src/pkcs11/.libs/opensc-pkcs11.so +``` +Any APDU returned from the card is now logged into the file `apdulog` in the +format expected by the `fuzz_pkcs15_reader` fuzzer. It is also prefixed with +the ATR of the connected card as expected by the fuzzer. This file can be used +as a starting point which gets through the card detection, but does not go into +all the operations the fuzzer attempts later. + +### The pkcs15init fuzzer + +The pkcs15init fuzzer consist of two separate parts. The first one is parsing +of the profile file, which is separated from the rest of the input with a NULL +byte (0x00). The rest is interpreted as in case of the `fuzz_pkcs15_reader`. + +When creating corpus for this fuzzer, stuff get more messy because: + + * The first part is the profile file + * The `pkcs15-init` can do only one operation at time so we need to skip the + card init when concatenating the APDU traces + +So at first, erase the card and move away the apdulog: +``` +./src/tools/pkcs15-init --erase-card --so-pin 12345678 +$ mv apdulog /tmp/apdu_erase +``` +Then prepare the separate files for each operation in the fuzzer: +``` +$ ./src/tools/pkcs15-init -C --pin 123456 --puk 12345678 --so-pin 12345678 --so-puk 12345678 +$ mv apdulog /tmp/apdu_create +$ ./src/tools/pkcs15-init -P -a 1 -l "Basic PIN" --pin 1234555678 --puk 12345678 +$ mv apdulog /tmp/apdu_create_pin +$ ./src/tools/pkcs15-init --store-data /path/to/any_file --label label +$ mv apdulog /tmp/apdu_store_data +$ ./src/tools/pkcs15-init --generate-key rsa:1024 --auth-id 01 --so-pin 12345678 --pin 1234555678 +$ mv apdulog /tmp/apdu_generate_rsa +$ ./src/tools/pkcs15-init --generate-key ec:prime256v1 --auth-id 01 --so-pin 12345678 --pin 123455678 +$ mv apdulog /tmp/apdu_generate_ecdsa +$ ./src/tools/pkcs15-init -F +$ mv apdulog /tmp/apdu_finalize +``` + +Now, construct the corpus file: +* insert profile and zero byte as delimiter +* apdu create can be used as it is +* from apdu\_create_pin remove part for connecting card +* from apdu\_store_data remove some central parts, since testing data is smaller than data used in apdu +* apdu_generate_* and apdu\_finalize need to skip connecting card and `sc_pcks15_bind()` +* symmetric key generation is not supported on the card, lets fill that part with some dummy values from generating RSA keys +* apdu\_erase needs to skip part for connecting card + +``` +SKIP=1257 +( \ + cat file.profile; printf "\x00"; \ + cat tmp/apdu_create; \ + dd if=tmp/apdu_create_pin bs=1 skip=421; \ + dd if=tmp/apdu_store_data bs=1 skip=1257 count=1675; \ + dd if=tmp/apdu_store_data bs=1 skip=3020; \ + dd if=tmp/apdu_generate_rsa bs=1 skip=$SKIP; \ + dd if=tmp/apdu_generate_ecdsa bs=1 skip=$SKIP; \ + dd if=tmp/apdu_generate_rsa bs=1 skip=$SKIP count=5304; \ + dd if=tmp/apdu_generate_rsa bs=1 skip=$SKIP count=5304; \ + dd if=tmp/apdu_generate_rsa bs=1 skip=$SKIP count=5304; \ + dd if=tmp/apdu_finalize bs=1 skip=$SKIP; \ + dd if=tmp/apdu_erase bs=1 skip=421; \ +) > tmp/testcase +``` + +Now, lets try to feed the data into the fuzzer: +``` +OPENSC_DEBUG=9 ./src/tests/fuzzing/fuzz_pkcs15init_profile /tmp/testcase +``` +The debug log should show the card detection, which goes through and then some +pkcs15init operations. From 6aba21ecf347bed70c713156c452c40572d48e41 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 2 Jan 2022 16:47:12 +0100 Subject: [PATCH 2310/4321] fuzzing: Add corpus for fuzz_pkcs15init --- .../6ce966ee0f311e1a63f2bb693caeba1b0fd1160e | Bin 0 -> 39465 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15init/6ce966ee0f311e1a63f2bb693caeba1b0fd1160e diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15init/6ce966ee0f311e1a63f2bb693caeba1b0fd1160e b/src/tests/fuzzing/corpus/fuzz_pkcs15init/6ce966ee0f311e1a63f2bb693caeba1b0fd1160e new file mode 100644 index 0000000000000000000000000000000000000000..69b559cb1922755dde15cc298229745558ff3a2c GIT binary patch literal 39465 zcmeHQYiu0V6`mQ}fnA)Evsgqq3%itJ0M!ecE*}a==JiD`< znRQq~L}J>|Mtww3XjQ3IpdcPUS}Gw#tNuVmYSmV)TG1c;0QE%`7f88Ua@>mL zm!0YcXtrZd*^`Y3T-uIRq(!oeLMuwFYJ(Ikw@ADiEtE^pU5p1^lS!<>;mH1E!nSr% zn*^_6vi9aiek`|kD4D2O)q2S)_;r`M*aGTC=4jP-Epn4z+`yWYtEn1%+qAmd-;)?7 z1FYXY(ZWqoh^=U~;K0ngp`GOw%H>qGUcto;C1G^dqGlCSg*}!FEzEmHM~9LJk{~fI zmy(iW+s;1dP6`eP;n*JWoC+)!7wLP%DG?u<2?g$>q*nI{v~-|9R^YO6{k7SG2O8dw zlM+xkv?@^7M>SbK^+40U!#ZrujgqqOQM#$rO{N3Y!B%+l%@Y~Xq!my^QQ zsXA+(z-5KSx|#ZWoFaim6)d|@w{gg^oK#oAZPcL3*|isyD0G5DQ~_&qbdX$;zk*y% zV5fFbcc)X@S#zleAlNB-U=b{Or)O2@PQOv3p&=^Hy=B|B2Fdick@S@nr&zb^-g?+b zmrPBM^zq_aeHSmvO^<~7x}`#9AbXwYJ59e-2d&YO>4`K-4xMa3^(+OPJC&MK1&KUB z0$~kc2kCC=dh5k_MOw1zwom3PyN)a3OS^*Aax|pM#gykaYziAHq~_QoInmdnz7N>* zn#SkU&=$!q+bPVFeXveq+54=92R4Y-R-m3o0dJz26oI3zVijD+6A(mYLkA!9Pm3`B zRm1D1w@;2u^pUCjNN#vy`$V223>(&~(WbmM;W^CWO18DzgCRgB%kBfnl>M@0m+z&; zK2oK$=%v8G&;t9wbSBGHuuJG!i5M|pXCp61leK)GR%$*Dn&G8Z-QNT1f&#QpHgkP8 z+zwrU92IJWDezJ2)jDX!t62q_@<1+_ESol=g9FBZ1q{7Vn#pFN)M{N^h&4`U`*92` z_T9P%YK#tEb7x!ksMXt4cx}pyae?^MxHAWsui}nbY&u}ZBlTL-`+(Bn+Va7?J=g@B zf@cDKxCC}vLI6+(fl_gE+ zBE-?oLfDjTLa3BQ0q#Ue8^!q423nLp4a^@`0}x{nPQ%BaAK3zn7~NcG>crsoq`3h@bWwDG`We2!oN;BO2J1%HxU@uFWGm=`Fhx}|GY9h+ z;{5@@MKEhpY*eiZ#2q$b3%vlgLsu?T(i{pY9ju3~D`t3nt@i|u7LbQ!(sjcnteclH zg1|~FYflfzeStLfS&8(e%#7|G=Zj1oAtN~(C$Uy57t#wy!lg&{!7F61CdUYuQL#=| z9gH4hq#2g;l;|X+64;IfI!Q7XXaJv8gi;`iym?eyjS&YHS`giU z0!Pe2Q+{piAIzGA16u|M;G%yplN;<$5B4`Z6yy;K)Gl<(6dlrfR0mlTcZ^R5N*1Ex zDM1Jt77k>|n*GR~pka)WpkSR0M0jaiy)y*hVDM_G~ z+epb8@t74hBp%vw@5DxeAE$CbBOE7kXnYT^WMIG)Od(rzxRPena{87q>5en3O9@-7 zA%rBX?Qji2Sk-A)-|>nB``pe4E5PS?^rrJRPfppO^sXPU1A zyi5#E7@#la+=W|0OJCPKIk7%r*mtaM=IKN7VT`#SC5ed#cKe~llkxXykuJ4kYG!&z zKG#x8B#RHL#P~_})JvNaT(dx#cqaLSo z{FDroaF7G=4PRg+O~E``aH+opxpJphE}jz$Ks8|t%0lQP^(8p^#F0WfZN+pI zIxI$vf^Ss6n0PTs!<*R5hqdw3AQay-kV0-3<_J?or(&@)6)Zi7buCh?S1JvHDeVSH zMUKtos#o^l6o}~>7!7*)m~n?Mk^jU(K*a)-O4UZ8xF~o}2~ZhQnM5o#8o(eTP;;*r z3Dsd?9V)$#EU=rVIB{!_rWZ{*e>)6q0)v6~CvDy0Rx0LLQndPf8A>o>KfsRim_pUg*M{DH zRMQTnKghE?QLEN#&Si&;`;X7-n;tMGS0CtF6YrfFIMWY9~TEz)Kh1PZg>urv7 zkSY2aFz@hG0=um%=fS0Xw67CLZ)hi@{O7rc$V4@Aa$|Buj*Ye)vlB`$<;aIvEaJoSbqWr@2FZ_{a4Hx%j`RvJ(_AFnh- zC3IQXbG@kSZq@TDsC;teMdxSCOgf#(nCbKYT;0)J6sNAZSI~8H$oy>Ys%cuNyJf#Y zwwK`f4Sp-N%UJf32?8H~>>~4mE<;`u$ioMq59Dj)Del{5)v> zEPsI(l@62+kU13&lnwv~@1MmUk;jiqKDA!>0E;0?OIV}Y?KTTnVU>-mc(3M9wGQj^L=l$%hl660Hi1Em9wgR}d%6QzsT zeI7*@%1tOYq38lNpm4x-py=YD(dI6_qKl&%JZ5uNzko2cy@!{WKs{u1YxDZb2aIt@ zpsrkrPaW|D>b&-iOCHWV{>RGkZFl|ZtN*y+3u{*El}Fw>uQGbb$!>Y|wrj3k^S|%j zQLEl*k|SFB_FsBWJpH$0e_DQD@5M0bQtcH%CSDr*f6bRVr60U8Oo< zsnZ4iEuutNd#j?dg)o|J9$EZ5$7017wYd6FwRgoP&!aJ0Nzw-hVZ{UQdwyk zN{M&nD%A-Kp`dV}bii?-Zepsev>=CtZz?Mdj#4~?9X*Juyk!h6icu7!a7Iywab*i= z3o5b*9*Nc0M1+)c47Xe+U zyrtv`@vcln(S@Q5ZVbv66kYJ!TXTh1I8OFm{zF*p zlmE%CX1YI}9oU!|IL)8zYMSQxy@@TBS1ypru?hKEusZ)NSfe-kS+M%Y@Uvj~rZ4gt I^hdS-0|WKf-v9sr literal 0 HcmV?d00001 From e48902f146494b5a27bf8a193ef2e08d0be7c3a2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Dec 2021 10:36:20 +0100 Subject: [PATCH 2311/4321] profile.c: Check if cmd is not NULL --- src/pkcs15init/profile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index f476c3f256..584667c456 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1968,6 +1968,10 @@ process_block(struct state *cur, struct block *info, cmd = item->key; if (item->type == SCCONF_ITEM_TYPE_COMMENT) continue; + if (!cmd) { + parse_error(cur, "Command can not be processed."); + return SC_ERROR_SYNTAX_ERROR; + } if (item->type == SCCONF_ITEM_TYPE_BLOCK) { scconf_list *nlist; From 35734aebc8868f353eed4a19d48a8f86a0d8a53b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 12 Dec 2021 19:02:29 +0100 Subject: [PATCH 2312/4321] profile.c: Skip values without name --- src/pkcs15init/profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 584667c456..eab0ade695 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1715,7 +1715,7 @@ process_macros(struct state *cur, struct block *info, for (item = blk->items; item; item = item->next) { name = item->key; - if (item->type != SCCONF_ITEM_TYPE_VALUE) + if (item->type != SCCONF_ITEM_TYPE_VALUE || !name) continue; #ifdef DEBUG_PROFILE printf("Defining %s\n", name); From 45bb8c961daa5e91eaa6a2072b3b6ace9787a388 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Dec 2021 13:41:54 +0100 Subject: [PATCH 2313/4321] profile.c: Check for files --- src/pkcs15init/profile.c | 80 +++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index eab0ade695..e1a69d1002 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1252,6 +1252,11 @@ do_file_type(struct state *cur, int argc, char **argv) { unsigned int type; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + if (map_str2int(cur, argv[0], &type, fileTypeNames)) return 1; cur->file->file->type = type; @@ -1261,8 +1266,15 @@ do_file_type(struct state *cur, int argc, char **argv) static int do_file_path(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; - struct sc_path *path = &file->path; + struct sc_file *file = NULL; + struct sc_path *path = NULL; + + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ @@ -1279,8 +1291,15 @@ static int do_fileid(struct state *cur, int argc, char **argv) { struct file_info *fi; - struct sc_file *df, *file = cur->file->file; - struct sc_path temp, *path = &file->path; + struct sc_file *df, *file = NULL; + struct sc_path temp, *path = NULL; + + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ @@ -1314,6 +1333,11 @@ do_structure(struct state *cur, int argc, char **argv) { unsigned int ef_structure; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + if (map_str2int(cur, argv[0], &ef_structure, fileStructureNames)) return 1; cur->file->file->ef_structure = ef_structure; @@ -1325,6 +1349,11 @@ do_size(struct state *cur, int argc, char **argv) { unsigned int size; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + if (get_uint_eval(cur, argc, argv, &size)) return 1; cur->file->file->size = size; @@ -1336,6 +1365,11 @@ do_reclength(struct state *cur, int argc, char **argv) { unsigned int reclength; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + if (get_uint(cur, argv[0], &reclength)) return 1; cur->file->file->record_length = reclength; @@ -1345,10 +1379,16 @@ do_reclength(struct state *cur, int argc, char **argv) static int do_content(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; + struct sc_file *file = NULL; size_t len = (strlen(argv[0]) + 1) / 2; int rv = 0; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + file->encoded_content = malloc(len); if (!file->encoded_content) return 1; @@ -1360,10 +1400,16 @@ do_content(struct state *cur, int argc, char **argv) static int do_prop_attr(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; + struct sc_file *file = NULL; size_t len = (strlen(argv[0]) + 1) / 2; int rv = 0; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + file->prop_attr = malloc(len); if (!file->prop_attr) return 1; @@ -1375,11 +1421,17 @@ do_prop_attr(struct state *cur, int argc, char **argv) static int do_aid(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; + struct sc_file *file = NULL; const char *name = argv[0]; unsigned int len; int res = 0; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + if (*name == '=') { len = strlen(++name); if (len > sizeof(file->name)) { @@ -1399,11 +1451,17 @@ do_aid(struct state *cur, int argc, char **argv) static int do_exclusive_aid(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; + struct sc_file *file = NULL; const char *name = argv[0]; unsigned int len; int res = 0; + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } + file = cur->file->file; + #ifdef DEBUG_PROFILE printf("do_exclusive_aid(): exclusive-aid '%s'\n", name); printf("do_exclusive_aid(): current file '%s' (path:%s)\n", cur->file->ident, sc_print_path(&file->path)); @@ -1456,9 +1514,13 @@ do_profile_extension(struct state *cur, int argc, char **argv) static int do_acl(struct state *cur, int argc, char **argv) { - struct sc_file *file = cur->file->file; + struct sc_file *file = NULL; char oper[64], *what = NULL; + if (!cur->file) + goto bad; + file = cur->file->file; + memset(oper, 0, sizeof(oper)); while (argc--) { unsigned int op, method, id; From 11f271e49af67acab8aff1c49b709c8d7d72fa2f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Dec 2021 14:16:27 +0100 Subject: [PATCH 2314/4321] profile.c: Check file type and path len before creating fi_id and ffi_id Otherwise unchecked access to fi_path.value/ffi_path.value leads to read out of borders. --- src/pkcs15init/profile.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index e1a69d1002..381b536bb5 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1057,19 +1057,34 @@ template_sanity_check(struct state *cur, struct sc_profile *templ) for (fi = templ->ef_list; fi; fi = fi->next) { struct sc_path fi_path = fi->file->path; - int fi_id = fi_path.value[fi_path.len - 2] * 0x100 - + fi_path.value[fi_path.len - 1]; + int fi_id; if (fi->file->type == SC_FILE_TYPE_BSO) continue; + + if (fi_path.len < 2) { + parse_error(cur, "Template insane: file-path length should not less than 2"); + return 1; + } + + fi_id = fi_path.value[fi_path.len - 2] * 0x100 + + fi_path.value[fi_path.len - 1]; + for (ffi = templ->ef_list; ffi; ffi = ffi->next) { struct sc_path ffi_path = ffi->file->path; - int dlt, ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100 - + ffi_path.value[ffi_path.len - 1]; + int dlt, ffi_id; if (ffi->file->type == SC_FILE_TYPE_BSO) continue; + if (ffi_path.len < 2) { + parse_error(cur, "Template insane: file-path length should not less than 2"); + return 1; + } + + ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100 + + ffi_path.value[ffi_path.len - 1]; + dlt = fi_id > ffi_id ? fi_id - ffi_id : ffi_id - fi_id; if (strcmp(ffi->ident, fi->ident)) { if (dlt >= TEMPLATE_FILEID_MIN_DIFF) From 8a6e4948566d00876eda35a8ee9810115534c1f4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 20 Jan 2022 16:06:10 +0100 Subject: [PATCH 2315/4321] profile.c: Check pointer before accessing it When profile->p15_spec is NULL --- src/pkcs15init/profile.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 381b536bb5..6c996be903 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1224,12 +1224,24 @@ new_file(struct state *cur, const char *name, unsigned int type) if (strncasecmp(name, "PKCS15-", 7)) { file = init_file(type); } else if (!strcasecmp(name+7, "TokenInfo")) { + if (!profile->p15_spec) { + parse_error(cur, "no pkcs15 spec in profile"); + return NULL; + } file = profile->p15_spec->file_tokeninfo; dont_free = 1; } else if (!strcasecmp(name+7, "ODF")) { + if (!profile->p15_spec) { + parse_error(cur, "no pkcs15 spec in profile"); + return NULL; + } file = profile->p15_spec->file_odf; dont_free = 1; } else if (!strcasecmp(name+7, "UnusedSpace")) { + if (!profile->p15_spec) { + parse_error(cur, "no pkcs15 spec in profile"); + return NULL; + } file = profile->p15_spec->file_unusedspace; dont_free = 1; } else if (!strcasecmp(name+7, "AppDF")) { From 32d7b0bbe4ea753cc2d4171b11abd918efe87f99 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 2 Jan 2022 18:48:01 +0100 Subject: [PATCH 2316/4321] pkcs15.c: Set length when duplicating structure --- src/libopensc/pkcs15.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index dc5cfaafc6..5562b3f041 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -910,6 +910,7 @@ sc_dup_app_info(const struct sc_app_info *info) return NULL; } memcpy(out->ddo.value, info->ddo.value, info->ddo.len); + out->ddo.len = info->ddo.len; return out; } From 8b11780b4788e9a304c5e743b50c1c608eee4d41 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Jan 2022 16:44:52 +0100 Subject: [PATCH 2317/4321] pkcs15.c: Fix variable out of scope --- src/libopensc/pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 5562b3f041..957a29de83 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -306,6 +306,7 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref); struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE]; struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE]; + u8 serial[128]; sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs); sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo); @@ -340,7 +341,6 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 1); if (ti->serial_number != NULL) { - u8 serial[128]; serial_len = 0; if (strlen(ti->serial_number)/2 > sizeof(serial)) return SC_ERROR_BUFFER_TOO_SMALL; From f77732aa8a51bdc8eb77b303fb7f713db67b49d8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 4 Jan 2022 15:53:04 +0100 Subject: [PATCH 2318/4321] pkcs15-init: Release allocated sc_pkcs15_card after erasing card `do_erase()` function calls `sc_pkcs15init_erase_card()`, that gets pointer to sc_pkcs15_card as argument, but after calling `sc_pkcs15_bind()` overwrites this pointer with newly allocated sc_pkcs15_card, which is then stored in profile->p15_data --- src/tools/pkcs15-init.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index c9c549a089..3bd22f87c7 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -450,7 +450,8 @@ main(int argc, char **argv) { struct sc_profile *profile = NULL; unsigned int n; - int r = 0; + int r = 0; + struct sc_pkcs15_card *tmp_p15_data = NULL; #if OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_config(NULL); @@ -635,8 +636,13 @@ main(int argc, char **argv) } out: + /* After erasing card profile->p15_data might change */ if (profile) { + tmp_p15_data = profile->p15_data; sc_pkcs15init_unbind(profile); + if (tmp_p15_data != g_p15card) { + sc_pkcs15_unbind(tmp_p15_data); + } } if (g_p15card) { sc_pkcs15_unbind(g_p15card); From 8b2aaac9b2435134c5d234acef1be739fd1019ba Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 11 Jan 2022 14:40:59 +0100 Subject: [PATCH 2319/4321] pkcs15-muscle.c: Free file in case of failure --- src/pkcs15init/pkcs15-muscle.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 4bb178baa4..9545e9b799 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -72,8 +72,10 @@ muscle_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d sc_format_path("3F00", &path); if ((r = sc_select_file(p15card->card, &path, &file)) < 0) return r; - if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE)) < 0) + if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE)) < 0) { + sc_file_free(file); return r; + } /* Create the application DF */ if ((r = sc_pkcs15init_create_file(profile, p15card, df)) < 0) return r; From 2420852ee0706c4d1a49c3ba5ae4e3d277199bb5 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Jan 2022 15:08:40 +0100 Subject: [PATCH 2320/4321] pkcs15-myeid.c: Free file --- src/pkcs15init/pkcs15-myeid.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index e069919236..c6052989cc 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -176,6 +176,7 @@ myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) { data_obj.DataLen = sizeof (data); r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); + sc_file_free(mf); LOG_FUNC_RETURN(p15card->card->ctx, r); } @@ -810,6 +811,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, r, "Cannot generate key: failed to select key file"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_GENERATE); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "No authorisation to generate private key"); /* Fill in data structure */ @@ -826,6 +829,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Generate the key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); /* Key pair generation -> collect public key info */ @@ -842,6 +847,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Get public key modulus */ r = sc_select_file(card, &file->path, NULL); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed"); data_obj.P1 = 0x01; @@ -850,6 +857,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get RSA key modulus: 'MYEID_GETDATA' failed"); if ((data_obj.DataLen * 8) != key_info->modulus_length) @@ -867,6 +876,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->algorithm = SC_ALGORITHM_EC; r = sc_select_file(card, &file->path, NULL); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get public key: select key file failed"); data_obj.P1 = 0x01; @@ -875,24 +886,33 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get EC public key: 'MYEID_GETDATA' failed"); dataptr = data_obj.Data; r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen); if (dataptr == NULL) r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure."); - if (taglen == 0) + if (taglen == 0) { + if (r < 0) + sc_file_free(file); LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } if (pubkey->u.ec.ecpointQ.value) free(pubkey->u.ec.ecpointQ.value); pubkey->u.ec.ecpointQ.value = malloc(taglen); - if (pubkey->u.ec.ecpointQ.value == NULL) + if (pubkey->u.ec.ecpointQ.value == NULL) { + sc_file_free(file); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } memcpy(pubkey->u.ec.ecpointQ.value, dataptr, taglen); pubkey->u.ec.ecpointQ.len = taglen; @@ -906,9 +926,13 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->u.ec.params.der.len = 0; pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve); - if (!pubkey->u.ec.params.named_curve) + if (!pubkey->u.ec.params.named_curve) { + sc_file_free(file); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); + if (r < 0) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot fix EC parameters"); } } From ac8d87751607fcc8669bd63891ecaad1a466f718 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 30 Nov 2021 11:00:53 +0100 Subject: [PATCH 2321/4321] pkcs15-lib: Add check for storing pin --- src/pkcs15init/pkcs15-lib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 0d66a3b985..97d89a2c4d 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1046,7 +1046,13 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi /* Now store the PINs */ sc_log(ctx, "Store PIN(%.*s,authID:%s)", (int) sizeof pin_obj->label, pin_obj->label, sc_pkcs15_print_id(&auth_info->auth_id)); - r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); + if (profile->ops->create_pin) + r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); + else { + sc_pkcs15_free_object(pin_obj); + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store PIN operation is not supported"); + } + if (r < 0) sc_pkcs15_free_object(pin_obj); LOG_TEST_RET(ctx, r, "Card specific create PIN failed."); From dbe4af17713b7a7b0c036f86486dc21e639e955f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 12 Dec 2021 17:54:30 +0100 Subject: [PATCH 2322/4321] pkcs15-lib: Add return values when select_key_reference is not supported --- src/pkcs15init/pkcs15-lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 97d89a2c4d..50b1bebe21 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1388,8 +1388,10 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi LOG_TEST_GOTO_ERR(ctx, r, "Failed to select secret key object path"); /* See if we need to select a key reference for this object */ - if (profile->ops->select_key_reference) + if (profile->ops->select_key_reference) { + r = SC_ERROR_NOT_SUPPORTED; LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "SKey keyreference selection not supported"); + } *res_obj = object; object = NULL; From 5202602e101d02d9c8106b421f731423a6d8e39f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 24 Jan 2022 17:21:41 +0100 Subject: [PATCH 2323/4321] pkcs15-lib.c.: Free ecparams In sc_pkcs15init_init_prkdf() allocate sc_ec_parameters and do not use the struct from variable on stack. --- src/pkcs15init/pkcs15-lib.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 50b1bebe21..7cf8791b37 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -175,8 +175,16 @@ static struct sc_pkcs15init_callbacks callbacks = { }; -static void sc_pkcs15init_empty_callback(void *ptr) +static void sc_pkcs15init_free_ec_params(void *ptr) { + struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)ptr; + if (ecparams) { + if (ecparams->der.value) + free(ecparams->der.value); + if (ecparams->named_curve) + free(ecparams->named_curve); + free(ecparams); + } } /* @@ -1263,8 +1271,16 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof } else if (key->algorithm == SC_ALGORITHM_EC) { struct sc_ec_parameters *ecparams = &keyargs->key.u.ec.params; - key_info->params.data = &keyargs->key.u.ec.params; - key_info->params.free_params = sc_pkcs15init_empty_callback; + struct sc_ec_parameters *new_ecparams = malloc(sizeof(struct sc_ec_parameters)); + new_ecparams->named_curve = ecparams->named_curve; + new_ecparams->der.value = ecparams->der.value; + new_ecparams->der.len = ecparams->der.len; + new_ecparams->type = ecparams->type; + new_ecparams->field_length = ecparams->field_length; + new_ecparams->id = ecparams->id; + + key_info->params.data = new_ecparams; + key_info->params.free_params = sc_pkcs15init_free_ec_params; key_info->field_length = ecparams->field_length; key_info->modulus_length = 0; } @@ -1300,6 +1316,8 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof r = SC_SUCCESS; err: + if (key->algorithm == SC_ALGORITHM_EC) + free(key_info->params.data); if (object) sc_pkcs15init_free_object(object); LOG_FUNC_RETURN(ctx, r); From 0773f4098ad424582af9f367fd7627fcdefba66e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 2 Jan 2022 17:13:21 +0100 Subject: [PATCH 2324/4321] pkcs15-lib.c: Fix memory leaks --- src/pkcs15init/pkcs15-lib.c | 193 ++++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 72 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 7cf8791b37..bd1291c7c5 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -844,7 +844,7 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, pin_attrs->flags, pin_attrs->reference, sc_print_path(&pin_ainfo.path)); r = sc_pkcs15_add_object(p15card, pin_obj); - LOG_TEST_RET(ctx, r, "Failed to add 'SOPIN' AUTH object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add 'SOPIN' AUTH object"); } } @@ -854,15 +854,18 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, r = profile->ops->init_card(profile, p15card); if (r < 0 && pin_obj) { sc_pkcs15_remove_object(p15card, pin_obj); - sc_pkcs15_free_object(pin_obj); } - LOG_TEST_RET(ctx, r, "Card specific init failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific init failed"); } /* Create the application directory */ - if (profile->ops->create_dir) + if (profile->ops->create_dir) { r = profile->ops->create_dir(profile, p15card, df); - LOG_TEST_RET(ctx, r, "Create 'DIR' error"); + if (r < 0 && pin_obj) { + sc_pkcs15_remove_object(p15card, pin_obj); + } + LOG_TEST_GOTO_ERR(ctx, r, "Create 'DIR' error"); + } /* Store SO PIN */ if (pin_obj && profile->ops->create_pin) @@ -874,14 +877,13 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, /* Remove 'virtual' AUTH object . */ sc_pkcs15_remove_object(p15card, pin_obj); - if (r < 0) - sc_pkcs15_free_object(pin_obj); - LOG_TEST_RET(ctx, r, "Card specific create application DF failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific create application DF failed"); /* Store the PKCS15 information on the card */ app = (struct sc_app_info *)calloc(1, sizeof(*app)); - if (app == NULL) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to allocate application info"); + if (app == NULL) { + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to allocate application info"); + } app->path = p15card->file_app->path; if (p15card->file_app->namelen <= SC_MAX_AID_SIZE) { @@ -939,10 +941,15 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, else { free(app->label); free(app); /* unused */ + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add pin object."); } sc_pkcs15init_write_info(p15card, profile, pin_obj); LOG_FUNC_RETURN(ctx, r); +err: + if (pin_obj) + sc_pkcs15_free_object(pin_obj); + LOG_FUNC_RETURN(ctx, r); } @@ -995,19 +1002,20 @@ sc_pkcs15init_store_puk(struct sc_pkcs15_card *p15card, /* Now store the PINs */ if (profile->ops->create_pin) r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); - else { - sc_pkcs15_free_object(pin_obj); - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "In Old API store PUK object is not supported"); - } + else + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "In Old API store PUK object is not supported"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to create PIN"); - if (r >= 0) - r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); - else - sc_pkcs15_free_object(pin_obj); + r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); + LOG_TEST_GOTO_ERR(ctx, r, "Add pin object error"); profile->dirty = 1; LOG_FUNC_RETURN(ctx, r); +err: + if (pin_obj) + sc_pkcs15_free_object(pin_obj); + LOG_FUNC_RETURN(ctx, r); } @@ -1056,19 +1064,13 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi sc_log(ctx, "Store PIN(%.*s,authID:%s)", (int) sizeof pin_obj->label, pin_obj->label, sc_pkcs15_print_id(&auth_info->auth_id)); if (profile->ops->create_pin) r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); - else { - sc_pkcs15_free_object(pin_obj); - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store PIN operation is not supported"); - } + else + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "Store PIN operation is not supported"); - if (r < 0) - sc_pkcs15_free_object(pin_obj); - LOG_TEST_RET(ctx, r, "Card specific create PIN failed."); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific create PIN failed."); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); - if (r < 0) - sc_pkcs15_free_object(pin_obj); - LOG_TEST_RET(ctx, r, "Failed to add PIN object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add PIN object"); if (args->puk_id.len) r = sc_pkcs15init_store_puk(p15card, profile, args); @@ -1076,6 +1078,10 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi profile->dirty = 1; LOG_FUNC_RETURN(ctx, r); +err: + if (pin_obj) + sc_pkcs15_free_object(pin_obj); + LOG_FUNC_RETURN(ctx, r); } @@ -1200,7 +1206,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof struct sc_pkcs15_object **res_obj) { struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_prkey_info *key_info; + struct sc_pkcs15_prkey_info *key_info = NULL; struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; struct sc_pkcs15_object *object = NULL; const char *label; @@ -1312,9 +1318,8 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof } *res_obj = object; - object = NULL; r = SC_SUCCESS; - + LOG_FUNC_RETURN(ctx, r); err: if (key->algorithm == SC_ALGORITHM_EC) free(key_info->params.data); @@ -1521,13 +1526,18 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args, &keygen_args->prkey_args.key, keybits, &object); + if (r < 0) { + free(keygen_args->prkey_args.key.u.ec.params.der.value); + free(keygen_args->prkey_args.key.u.ec.params.named_curve); + } + LOG_TEST_RET(ctx, r, "Set up private key object error"); key_info = (struct sc_pkcs15_prkey_info *) object->data; r = _pkcd15init_set_aux_md_data(p15card, &key_info->aux_data, keygen_args->prkey_args.guid, keygen_args->prkey_args.guid_len); - LOG_TEST_RET(ctx, r, "Failed to set aux MD data"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to set aux MD data"); /* Set up the PuKDF info. The public key will be filled in * by the card driver's generate_key function called below. @@ -1541,20 +1551,28 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_GOSTR3410) { pubkey_args.params.gost = keygen_args->prkey_args.params.gost; r = sc_copy_gost_params(&(pubkey_args.key.u.gostr3410.params), &(keygen_args->prkey_args.key.u.gostr3410.params)); - LOG_TEST_RET(ctx, r, "Cannot allocate GOST parameters"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate GOST parameters"); } else if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_EC) { pubkey_args.key.u.ec.params = keygen_args->prkey_args.key.u.ec.params; r = sc_copy_ec_params(&pubkey_args.key.u.ec.params, &keygen_args->prkey_args.key.u.ec.params); - LOG_TEST_RET(ctx, r, "Cannot allocate EC parameters"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC parameters"); } /* Generate the private key on card */ r = profile->ops->create_key(profile, p15card, object); - LOG_TEST_RET(ctx, r, "Cannot generate key: create key failed"); + if (r < 0) { + free(pubkey_args.key.u.ec.params.der.value); + free(pubkey_args.key.u.ec.params.named_curve); + } + LOG_TEST_GOTO_ERR(ctx, r, "Cannot generate key: create key failed"); r = profile->ops->generate_key(profile, p15card, object, &pubkey_args.key); - LOG_TEST_RET(ctx, r, "Failed to generate key"); + if (r < 0) { + free(pubkey_args.key.u.ec.params.der.value); + free(pubkey_args.key.u.ec.params.named_curve); + } + LOG_TEST_GOTO_ERR(ctx, r, "Failed to generate key"); /* update PrKDF entry */ if (!caller_supplied_id) { @@ -1564,7 +1582,11 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr * if intrinsic ID can be calculated -- overwrite the native one */ memset(&iid, 0, sizeof(iid)); r = sc_pkcs15init_select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key); - LOG_TEST_RET(ctx, r, "Select intrinsic ID error"); + if (r < 0) { + free(pubkey_args.key.u.ec.params.der.value); + free(pubkey_args.key.u.ec.params.named_curve); + } + LOG_TEST_GOTO_ERR(ctx, r, "Select intrinsic ID error"); if (iid.len) key_info->id = iid; @@ -1573,8 +1595,14 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr pubkey = &pubkey_args.key; if (!pubkey->alg_id) { pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id)); - if (!pubkey->alg_id) + if (!pubkey->alg_id) { + if (r < 0) { + free(pubkey_args.key.u.ec.params.der.value); + free(pubkey_args.key.u.ec.params.named_curve); + sc_pkcs15_free_object(object); + } LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sc_init_oid(&pubkey->alg_id->oid); pubkey->alg_id->algorithm = pubkey->algorithm; @@ -1582,28 +1610,35 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr pubkey_args.id = key_info->id; r = sc_pkcs15_encode_pubkey(ctx, pubkey, &object->content.value, &object->content.len); - LOG_TEST_RET(ctx, r, "Failed to encode public key"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to encode public key"); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object); - LOG_TEST_RET(ctx, r, "Failed to add generated private key object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add generated private key object"); if (!r && profile->ops->emu_store_data) { r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; - LOG_TEST_RET(ctx, r, "Card specific 'store data' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store data' failed"); } r = sc_pkcs15init_store_public_key(p15card, profile, &pubkey_args, NULL); - LOG_TEST_RET(ctx, r, "Failed to store public key"); + if (r < 0) + sc_pkcs15_remove_object(p15card, object); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to store public key"); if (res_obj) *res_obj = object; + object = NULL; sc_pkcs15_erase_pubkey(&pubkey_args.key); profile->dirty = 1; - +err: + if (pubkey) + sc_pkcs15_erase_pubkey(&pubkey_args.key); + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1642,30 +1677,33 @@ sc_pkcs15init_generate_secret_key(struct sc_pkcs15_card *p15card, struct sc_prof /* Set up the SKDF object */ r = sc_pkcs15init_init_skdf(p15card, profile, skey_args, &object); - LOG_TEST_RET(ctx, r, "Set up secret key object error"); + LOG_TEST_GOTO_ERR(ctx, r, "Set up secret key object error"); /* Generate the secret key on card */ r = profile->ops->create_key(profile, p15card, object); - LOG_TEST_RET(ctx, r, "Cannot generate key: create key failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot generate key: create key failed"); r = profile->ops->generate_key(profile, p15card, object, NULL); - LOG_TEST_RET(ctx, r, "Failed to generate key"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to generate key"); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_SKDF, object); - LOG_TEST_RET(ctx, r, "Failed to add generated secret key object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add generated secret key object"); if (!r && profile->ops->emu_store_data) { r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; - LOG_TEST_RET(ctx, r, "Card specific 'store data' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store data' failed"); } if (res_obj) *res_obj = object; + object = NULL; profile->dirty = 1; - +err: + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1718,40 +1756,43 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil LOG_TEST_RET(ctx, r, "Failed to initialize private key object"); r = sc_pkcs15init_encode_prvkey_content(p15card, &key, object); - LOG_TEST_RET(ctx, r, "Failed to encode public key"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to encode public key"); key_info = (struct sc_pkcs15_prkey_info *) object->data; r = _pkcd15init_set_aux_md_data(p15card, &key_info->aux_data, keyargs->guid, keyargs->guid_len); - LOG_TEST_RET(ctx, r, "Failed to set aux MD data"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to set aux MD data"); if (profile->ops->create_key) r = profile->ops->create_key(profile, p15card, object); - LOG_TEST_RET(ctx, r, "Card specific 'create key' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'create key' failed"); if (profile->ops->store_key) r = profile->ops->store_key(profile, p15card, object, &key); - LOG_TEST_RET(ctx, r, "Card specific 'store key' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store key' failed"); sc_pkcs15_free_object_content(object); r = sc_pkcs15init_encode_prvkey_content(p15card, &key, object); - LOG_TEST_RET(ctx, r, "Failed to encode public key"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to encode public key"); /* Now update the PrKDF */ r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object); - LOG_TEST_RET(ctx, r, "Failed to add new private key PKCS#15 object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add new private key PKCS#15 object"); if (!r && profile->ops->emu_store_data) { r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; - LOG_TEST_RET(ctx, r, "Card specific 'store data' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store data' failed"); } if (r >= 0 && res_obj) *res_obj = object; profile->dirty = 1; - + LOG_FUNC_RETURN(ctx, r); +err: + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1893,16 +1934,16 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile /* Update the PuKDF */ if (r >= 0) r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PUKDF, object); + LOG_TEST_GOTO_ERR(ctx, r, "Add object error"); if (r >= 0 && res_obj) *res_obj = object; profile->dirty = 1; - + LOG_FUNC_RETURN(ctx, r); err: - if (r < 0) - sc_pkcs15init_free_object(object); - + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1950,7 +1991,7 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile if (profile->ops->create_key) r = profile->ops->create_key(profile, p15card, object); - LOG_TEST_RET(ctx, r, "Card specific 'create key' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'create key' failed"); /* If no key data, only an empty EF is created. * It can be used to receive an unwrapped key later. */ @@ -1963,7 +2004,7 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile r = profile->ops->store_key(profile, p15card, object, &key); } } - LOG_TEST_RET(ctx, r, "Card specific 'store key' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store key' failed"); sc_pkcs15_free_object_content(object); @@ -1974,21 +2015,24 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile but we don't want it to be written into SKDF. */ if (!object->session_object) { r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_SKDF, object); - LOG_TEST_RET(ctx, r, "Failed to add new secret key PKCS#15 object"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to add new secret key PKCS#15 object"); } if (!r && profile->ops->emu_store_data && !object->session_object) { r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; - LOG_TEST_RET(ctx, r, "Card specific 'store data' failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store data' failed"); } if (r >= 0 && res_obj) *res_obj = object; + object = NULL; profile->dirty = 1; - +err: + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -2167,17 +2211,21 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card, sc_der_copy(&data_object_info->data, &args->der_encoded); r = sc_pkcs15init_store_data(p15card, profile, object, &args->der_encoded, &data_object_info->path); - LOG_TEST_RET(ctx, r, "Store 'DATA' object error"); + LOG_TEST_GOTO_ERR(ctx, r, "Store 'DATA' object error"); /* Now update the DDF */ r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_DODF, object); - LOG_TEST_RET(ctx, r, "'DODF' update error"); + LOG_TEST_GOTO_ERR(ctx, r, "'DODF' update error"); if (r >= 0 && res_obj) *res_obj = object; + object = NULL; profile->dirty = 1; +err: + if (object) + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -3977,20 +4025,21 @@ sc_pkcs15init_create_file(struct sc_profile *profile, struct sc_pkcs15_card *p15 LOG_TEST_RET(ctx, r, "Cannot create file: select parent error"); r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE); - LOG_TEST_RET(ctx, r, "Cannot create file: 'CREATE' authentication failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot create file: 'CREATE' authentication failed"); /* Fix up the file's ACLs */ r = sc_pkcs15init_fixup_file(profile, p15card, file); - LOG_TEST_RET(ctx, r, "Cannot create file: file fixup failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot create file: file fixup failed"); /* ensure we are in the correct lifecycle */ r = sc_pkcs15init_set_lifecycle(p15card->card, SC_CARDCTRL_LIFECYCLE_ADMIN); if (r != SC_ERROR_NOT_SUPPORTED) - LOG_TEST_RET(ctx, r, "Cannot create file: failed to set lifecycle 'ADMIN'"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot create file: failed to set lifecycle 'ADMIN'"); r = sc_create_file(p15card->card, file); - LOG_TEST_RET(ctx, r, "Create file failed"); + LOG_TEST_GOTO_ERR(ctx, r, "Create file failed"); +err: sc_file_free(parent); LOG_FUNC_RETURN(ctx, r); } From 53fd03f63ec35d526524621178e00027ec0cef29 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Feb 2022 18:00:53 +0100 Subject: [PATCH 2325/4321] pkcs15-lib.c: Set return value --- src/pkcs15init/pkcs15-lib.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index bd1291c7c5..f663b9b010 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -849,7 +849,6 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, } /* Perform card-specific initialization */ - if (profile->ops->init_card) { r = profile->ops->init_card(profile, p15card); if (r < 0 && pin_obj) { @@ -882,7 +881,8 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, /* Store the PKCS15 information on the card */ app = (struct sc_app_info *)calloc(1, sizeof(*app)); if (app == NULL) { - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to allocate application info"); + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Failed to allocate application info"); } app->path = p15card->file_app->path; @@ -1000,10 +1000,13 @@ sc_pkcs15init_store_puk(struct sc_pkcs15_card *p15card, auth_info->auth_id = args->puk_id; /* Now store the PINs */ - if (profile->ops->create_pin) + if (profile->ops->create_pin) { r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); - else - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "In Old API store PUK object is not supported"); + } + else { + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(ctx, r, "In Old API store PUK object is not supported"); + } LOG_TEST_GOTO_ERR(ctx, r, "Failed to create PIN"); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); @@ -1062,10 +1065,12 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi /* Now store the PINs */ sc_log(ctx, "Store PIN(%.*s,authID:%s)", (int) sizeof pin_obj->label, pin_obj->label, sc_pkcs15_print_id(&auth_info->auth_id)); - if (profile->ops->create_pin) + if (profile->ops->create_pin) { r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); - else - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "Store PIN operation is not supported"); + } else { + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(ctx, r, "Store PIN operation is not supported"); + } LOG_TEST_GOTO_ERR(ctx, r, "Card specific create PIN failed."); @@ -1238,8 +1243,10 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof LOG_TEST_GOTO_ERR(ctx, r, "Unsupported key type"); object = sc_pkcs15init_new_object(key_type, label, &keyargs->auth_id, NULL); - if (object == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate new PrKey object"); + if (object == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate new PrKey object"); + } key_info = (struct sc_pkcs15_prkey_info *) object->data; key_info->usage = usage; @@ -1366,8 +1373,10 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi LOG_TEST_GOTO_ERR(ctx, r, "Unsupported key type"); object = sc_pkcs15init_new_object(key_type, label, &keyargs->auth_id, NULL); - if (object == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate new SKey object"); + if (object == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate new SKey object"); + } key_info = (struct sc_pkcs15_skey_info *) object->data; key_info->usage = usage; @@ -1413,7 +1422,7 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi /* See if we need to select a key reference for this object */ if (profile->ops->select_key_reference) { r = SC_ERROR_NOT_SUPPORTED; - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "SKey keyreference selection not supported"); + LOG_TEST_GOTO_ERR(ctx, r, "SKey keyreference selection not supported"); } *res_obj = object; From ae4fb20f19f755115f68b598f1c0461595840865 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Feb 2022 18:02:32 +0100 Subject: [PATCH 2326/4321] profile.c: Fix error message --- src/pkcs15init/profile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 6c996be903..13ef881e75 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1063,7 +1063,7 @@ template_sanity_check(struct state *cur, struct sc_profile *templ) continue; if (fi_path.len < 2) { - parse_error(cur, "Template insane: file-path length should not less than 2"); + parse_error(cur, "Template insane: file-path length should not be less than 2 bytes"); return 1; } @@ -1078,7 +1078,7 @@ template_sanity_check(struct state *cur, struct sc_profile *templ) continue; if (ffi_path.len < 2) { - parse_error(cur, "Template insane: file-path length should not less than 2"); + parse_error(cur, "Template insane: file-path length should not be less than 2 bytes"); return 1; } From c63b553c6f9c98e3089b35c1043ab5577698cb4f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Feb 2022 18:05:49 +0100 Subject: [PATCH 2327/4321] fuzz_pkcs15init.c: Check pointers --- src/tests/fuzzing/fuzz_pkcs15init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 425d4aa8dd..722a60eb2a 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -317,12 +317,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) so_pin = malloc(9); puk = malloc(9); so_puk = malloc(9); + buf = malloc(len * sizeof(char)); + if (!pin || !so_pin || !puk || !so_puk || !buf) + goto end_release; + memcpy(pin, "123456\0", 7); memcpy(so_pin, "12345678\0", 9); memcpy(puk, "12345678\0", 9); memcpy(so_puk, "12345678\0", 9); - - buf = malloc(len * sizeof(char)); memcpy(buf, data, len); /* test pkcs15-init functionality*/ From d67e42b73516d488cd306b1c3d2adbe17c0ca3b2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Feb 2022 19:03:25 +0100 Subject: [PATCH 2328/4321] fuzz_pkcs15init.c: Generic fixes --- src/tests/fuzzing/Makefile.am | 6 ++++-- src/tests/fuzzing/fuzz_pkcs15init.c | 9 +++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 576dc037c6..9a2270c865 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -9,6 +9,8 @@ LIBS = $(FUZZING_LIBS)\ noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ fuzz_scconf_parse_string fuzz_pkcs15init +noinst_HEADERS = fuzzer_reader.h + ADDITIONAL_SRC = if !ENABLE_FUZZING ADDITIONAL_SRC += fuzzer.c @@ -17,8 +19,8 @@ endif fuzz_asn1_print_SOURCES = fuzz_asn1_print.c $(ADDITIONAL_SRC) fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) -fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c fuzzer_reader.c fuzzer_reader.h $(ADDITIONAL_SRC) +fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) -fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c fuzzer_reader.h $(ADDITIONAL_SRC) +fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) fuzz_pkcs15init_LDFLAGS = -static diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 722a60eb2a..a92d592817 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -1,7 +1,7 @@ /* * fuzz_pkcs15init.c: Fuzzer for functions processing pkcs15 init * - * Copyright (C) 2021 Red Hat, Inc. + * Copyright (C) 2022 Red Hat, Inc. * * Author: Veronika Hanulikova * @@ -258,9 +258,6 @@ void do_erase(struct sc_profile *profile, sc_card_t *card) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { -#ifdef FUZZING_ENABLED - fclose(stdout); -#endif sc_context_t *ctx = NULL; sc_card_t *card = NULL; struct sc_pkcs15_card *p15card = NULL; @@ -276,6 +273,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) unsigned char *so_puk = NULL; struct sc_pkcs15_card *tmp_p15_data = NULL; +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + if (size == 0) return 0; From c3789173c1874452318d7fc1c97c385eb225ee9c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 8 Feb 2022 20:17:16 +0100 Subject: [PATCH 2329/4321] pkcs15init: Copy ecparams into new objects By creating new object in sc_pkcs15init_init_prkdf(), ecparams will be copied into new allocated structure and freed with object in sc_pkcs15_free_object(). Name of the curve in pkcs15-init.c needs to be freed separately after sc_pkcs15init_generate_key() ends. --- src/pkcs15init/pkcs15-lib.c | 68 +++++++++++++++++++++++-------------- src/tools/pkcs15-init.c | 3 ++ 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index f663b9b010..138eac7f7f 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1283,14 +1283,25 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof keyinfo_gostparams->gost28147 = keyargs->params.gost.gost28147; } else if (key->algorithm == SC_ALGORITHM_EC) { + /* keyargs->key.u.ec.params.der.value is allocated in keyargs, which is on stack */ struct sc_ec_parameters *ecparams = &keyargs->key.u.ec.params; struct sc_ec_parameters *new_ecparams = malloc(sizeof(struct sc_ec_parameters)); - new_ecparams->named_curve = ecparams->named_curve; - new_ecparams->der.value = ecparams->der.value; - new_ecparams->der.len = ecparams->der.len; - new_ecparams->type = ecparams->type; - new_ecparams->field_length = ecparams->field_length; - new_ecparams->id = ecparams->id; + key_info->params.data = NULL; + if (!new_ecparams) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); + } + /* copy ecparams into allocated one + * it will be freed with the corresponding object */ + memcpy(new_ecparams, ecparams, sizeof(struct sc_ec_parameters)); + new_ecparams->named_curve = strdup(ecparams->named_curve); + new_ecparams->der.value = malloc(ecparams->der.len); + if (!new_ecparams->der.value) { + r = SC_ERROR_OUT_OF_MEMORY; + free(new_ecparams); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); + } + memcpy(new_ecparams->der.value, ecparams->der.value, ecparams->der.len); key_info->params.data = new_ecparams; key_info->params.free_params = sc_pkcs15init_free_ec_params; @@ -1328,8 +1339,11 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof r = SC_SUCCESS; LOG_FUNC_RETURN(ctx, r); err: - if (key->algorithm == SC_ALGORITHM_EC) + if (key->algorithm == SC_ALGORITHM_EC && key_info->params.data) { + free(((struct sc_ec_parameters *) key_info->params.data)->named_curve); + free(((struct sc_ec_parameters *) key_info->params.data)->der.value); free(key_info->params.data); + } if (object) sc_pkcs15init_free_object(object); LOG_FUNC_RETURN(ctx, r); @@ -1505,21 +1519,22 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr struct sc_pkcs15_prkey_info *key_info = NULL; struct sc_pkcs15_pubkey *pubkey = NULL; int r, caller_supplied_id = 0; + int algorithm = keygen_args->prkey_args.key.algorithm; LOG_FUNC_CALLED(ctx); /* check supported key size */ r = check_keygen_params_consistency(p15card->card, - keygen_args->prkey_args.key.algorithm, &keygen_args->prkey_args, + algorithm, &keygen_args->prkey_args, &keybits); LOG_TEST_RET(ctx, r, "Invalid key size"); - if (check_key_compatibility(p15card, keygen_args->prkey_args.key.algorithm, + if (check_key_compatibility(p15card, algorithm, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); if (profile->ops->generate_key == NULL) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported"); if (keygen_args->prkey_args.id.len) { caller_supplied_id = 1; @@ -1527,20 +1542,15 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr /* Make sure that private key's ID is the unique inside the PKCS#15 application */ r = sc_pkcs15_find_prkey_by_id(p15card, &keygen_args->prkey_args.id, NULL); if (!r) - LOG_TEST_RET(ctx, SC_ERROR_NON_UNIQUE_ID, "Non unique ID of the private key object"); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NON_UNIQUE_ID, "Non unique ID of the private key object"); else if (r != SC_ERROR_OBJECT_NOT_FOUND) - LOG_TEST_RET(ctx, r, "Find private key error"); + LOG_TEST_GOTO_ERR(ctx, r, "Find private key error"); } /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args, &keygen_args->prkey_args.key, keybits, &object); - if (r < 0) { - free(keygen_args->prkey_args.key.u.ec.params.der.value); - free(keygen_args->prkey_args.key.u.ec.params.named_curve); - } - - LOG_TEST_RET(ctx, r, "Set up private key object error"); + LOG_TEST_GOTO_ERR(ctx, r, "Set up private key object error"); key_info = (struct sc_pkcs15_prkey_info *) object->data; @@ -1557,12 +1567,13 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr pubkey_args.usage = keygen_args->prkey_args.usage; pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage; - if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_GOSTR3410) { + if (algorithm == SC_ALGORITHM_GOSTR3410) { pubkey_args.params.gost = keygen_args->prkey_args.params.gost; r = sc_copy_gost_params(&(pubkey_args.key.u.gostr3410.params), &(keygen_args->prkey_args.key.u.gostr3410.params)); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate GOST parameters"); } - else if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_EC) { + else if (algorithm == SC_ALGORITHM_EC) { + /* needs to be freed in case of failure when pubkey is not set yet */ pubkey_args.key.u.ec.params = keygen_args->prkey_args.key.u.ec.params; r = sc_copy_ec_params(&pubkey_args.key.u.ec.params, &keygen_args->prkey_args.key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC parameters"); @@ -1570,14 +1581,15 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr /* Generate the private key on card */ r = profile->ops->create_key(profile, p15card, object); - if (r < 0) { + if (r < 0 && algorithm == SC_ALGORITHM_EC) { + /* pubkey->alg_id->algorithm is not set yet, needs to be freed independently */ free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); } LOG_TEST_GOTO_ERR(ctx, r, "Cannot generate key: create key failed"); r = profile->ops->generate_key(profile, p15card, object, &pubkey_args.key); - if (r < 0) { + if (r < 0 && algorithm == SC_ALGORITHM_EC) { free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); } @@ -1591,7 +1603,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr * if intrinsic ID can be calculated -- overwrite the native one */ memset(&iid, 0, sizeof(iid)); r = sc_pkcs15init_select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key); - if (r < 0) { + if (r < 0 && algorithm == SC_ALGORITHM_EC) { free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); } @@ -1605,12 +1617,12 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (!pubkey->alg_id) { pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id)); if (!pubkey->alg_id) { - if (r < 0) { + if (algorithm == SC_ALGORITHM_EC) { free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); - sc_pkcs15_free_object(object); } - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Can not allocate memory for algorithm id"); } sc_init_oid(&pubkey->alg_id->oid); @@ -1643,11 +1655,15 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr sc_pkcs15_erase_pubkey(&pubkey_args.key); profile->dirty = 1; + err: if (pubkey) sc_pkcs15_erase_pubkey(&pubkey_args.key); if (object) sc_pkcs15_free_object(object); + if (algorithm == SC_ALGORITHM_EC) + /* allocated in check_keygen_params_consistency() */ + free(keygen_args->prkey_args.key.u.ec.params.der.value); LOG_FUNC_RETURN(ctx, r); } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 3bd22f87c7..5b2e17604b 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1781,6 +1781,9 @@ do_generate_key(struct sc_profile *profile, const char *spec) if (r == 0) r = sc_pkcs15init_generate_key(g_p15card, profile, &keygen_args, keybits, NULL); sc_unlock(g_p15card->card); + if (algorithm == SC_ALGORITHM_EC) + /* allocated in parse_alg_spec() */ + free(keygen_args.prkey_args.key.u.ec.params.named_curve); return r; } From 4c487abeddc20ec9f7c16a5f8be785ebd3c57a64 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 10 Feb 2022 10:21:54 +0100 Subject: [PATCH 2330/4321] fuzz_pkcs15init: Free named_curve --- src/tests/fuzzing/fuzz_pkcs15init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index a92d592817..73fea31683 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -197,6 +197,8 @@ void do_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (algorithms[i] == SC_ALGORITHM_EC) /* strdup called also in parse_alg_spec() */ keygen_args.prkey_args.key.u.ec.params.named_curve = strdup("prime256v1"); sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits[i], NULL); + if (algorithms[i] == SC_ALGORITHM_EC) + free(keygen_args.prkey_args.key.u.ec.params.named_curve); } } From 2b9da90b5112e21aa42c1fe22f56966d2ee02d9e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 10 Feb 2022 14:35:09 +0100 Subject: [PATCH 2331/4321] pkcs15-libs.c: Set return value for LOG_TEST_GOTO_ERR --- src/pkcs15init/pkcs15-lib.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 138eac7f7f..95e3d30413 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1533,18 +1533,23 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); - if (profile->ops->generate_key == NULL) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported"); + if (profile->ops->generate_key == NULL) { + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(ctx, r, "Key generation not supported"); + } if (keygen_args->prkey_args.id.len) { caller_supplied_id = 1; /* Make sure that private key's ID is the unique inside the PKCS#15 application */ r = sc_pkcs15_find_prkey_by_id(p15card, &keygen_args->prkey_args.id, NULL); - if (!r) - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_NON_UNIQUE_ID, "Non unique ID of the private key object"); - else if (r != SC_ERROR_OBJECT_NOT_FOUND) + if (!r) { + r = SC_ERROR_NON_UNIQUE_ID; + LOG_TEST_GOTO_ERR(ctx, r, "Non unique ID of the private key object"); + } + else if (r != SC_ERROR_OBJECT_NOT_FOUND) { LOG_TEST_GOTO_ERR(ctx, r, "Find private key error"); + } } /* Set up the PrKDF object */ @@ -1622,7 +1627,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr free(pubkey_args.key.u.ec.params.named_curve); } r = SC_ERROR_OUT_OF_MEMORY; - LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Can not allocate memory for algorithm id"); + LOG_TEST_GOTO_ERR(ctx, r, "Can not allocate memory for algorithm id"); } sc_init_oid(&pubkey->alg_id->oid); From 328290ec72163f0082962a79a0e26788380be145 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 23 Feb 2022 10:34:10 +0100 Subject: [PATCH 2332/4321] pkcs15-myeid.c: Fix memory leaks --- src/pkcs15init/pkcs15-myeid.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index c6052989cc..5e3368491d 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -168,6 +168,8 @@ myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) { /* ACLs are not actives if file is not in the operational state */ if (mf->status == SC_FILE_STATUS_ACTIVATED) r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE); + if (r < 0) + sc_file_free(mf); LOG_TEST_RET(ctx, r, "'DELETE' authentication failed on MF"); data_obj.P1 = 0x01; @@ -847,8 +849,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Get public key modulus */ r = sc_select_file(card, &file->path, NULL); - if (r < 0) - sc_file_free(file); + sc_file_free(file); + file = NULL; LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed"); data_obj.P1 = 0x01; @@ -857,8 +859,6 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); - if (r < 0) - sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get RSA key modulus: 'MYEID_GETDATA' failed"); if ((data_obj.DataLen * 8) != key_info->modulus_length) @@ -876,8 +876,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->algorithm = SC_ALGORITHM_EC; r = sc_select_file(card, &file->path, NULL); - if (r < 0) - sc_file_free(file); + sc_file_free(file); + file = NULL; LOG_TEST_RET(ctx, r, "Cannot get public key: select key file failed"); data_obj.P1 = 0x01; @@ -886,33 +886,24 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); - if (r < 0) - sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot get EC public key: 'MYEID_GETDATA' failed"); dataptr = data_obj.Data; r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen); if (dataptr == NULL) r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; - if (r < 0) - sc_file_free(file); LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure."); - if (taglen == 0) { - if (r < 0) - sc_file_free(file); + if (taglen == 0) LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - } if (pubkey->u.ec.ecpointQ.value) free(pubkey->u.ec.ecpointQ.value); pubkey->u.ec.ecpointQ.value = malloc(taglen); - if (pubkey->u.ec.ecpointQ.value == NULL) { - sc_file_free(file); + if (pubkey->u.ec.ecpointQ.value == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - } memcpy(pubkey->u.ec.ecpointQ.value, dataptr, taglen); pubkey->u.ec.ecpointQ.len = taglen; @@ -926,13 +917,10 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->u.ec.params.der.len = 0; pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve); - if (!pubkey->u.ec.params.named_curve) { - sc_file_free(file); + if (!pubkey->u.ec.params.named_curve) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - } + r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); - if (r < 0) - sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot fix EC parameters"); } } From 1060d0d6405cc3414d29e3378546ed9e91a0419f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 23 Feb 2022 15:01:14 +0100 Subject: [PATCH 2333/4321] pkcs15-lib.c: Fix more leaks --- src/pkcs15init/pkcs15-lib.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 95e3d30413..78dea25297 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -945,7 +945,7 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, } sc_pkcs15init_write_info(p15card, profile, pin_obj); - LOG_FUNC_RETURN(ctx, r); + pin_obj = NULL; err: if (pin_obj) sc_pkcs15_free_object(pin_obj); @@ -1002,19 +1002,19 @@ sc_pkcs15init_store_puk(struct sc_pkcs15_card *p15card, /* Now store the PINs */ if (profile->ops->create_pin) { r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to create PIN"); } else { r = SC_ERROR_NOT_SUPPORTED; LOG_TEST_GOTO_ERR(ctx, r, "In Old API store PUK object is not supported"); } - LOG_TEST_GOTO_ERR(ctx, r, "Failed to create PIN"); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); LOG_TEST_GOTO_ERR(ctx, r, "Add pin object error"); profile->dirty = 1; - LOG_FUNC_RETURN(ctx, r); + pin_obj = NULL; err: if (pin_obj) sc_pkcs15_free_object(pin_obj); @@ -1067,12 +1067,11 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi sc_log(ctx, "Store PIN(%.*s,authID:%s)", (int) sizeof pin_obj->label, pin_obj->label, sc_pkcs15_print_id(&auth_info->auth_id)); if (profile->ops->create_pin) { r = sc_pkcs15init_create_pin(p15card, profile, pin_obj, args); + LOG_TEST_GOTO_ERR(ctx, r, "Card specific create PIN failed."); } else { r = SC_ERROR_NOT_SUPPORTED; LOG_TEST_GOTO_ERR(ctx, r, "Store PIN operation is not supported"); } - - LOG_TEST_GOTO_ERR(ctx, r, "Card specific create PIN failed."); r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, pin_obj); LOG_TEST_GOTO_ERR(ctx, r, "Failed to add PIN object"); @@ -1082,7 +1081,7 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi profile->dirty = 1; - LOG_FUNC_RETURN(ctx, r); + pin_obj = NULL; err: if (pin_obj) sc_pkcs15_free_object(pin_obj); @@ -1295,9 +1294,15 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof * it will be freed with the corresponding object */ memcpy(new_ecparams, ecparams, sizeof(struct sc_ec_parameters)); new_ecparams->named_curve = strdup(ecparams->named_curve); + if (!new_ecparams->named_curve) { + r = SC_ERROR_OUT_OF_MEMORY; + free(new_ecparams); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); + } new_ecparams->der.value = malloc(ecparams->der.len); if (!new_ecparams->der.value) { r = SC_ERROR_OUT_OF_MEMORY; + free(new_ecparams->named_curve); free(new_ecparams); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); } @@ -1336,10 +1341,11 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof } *res_obj = object; + object = NULL; r = SC_SUCCESS; - LOG_FUNC_RETURN(ctx, r); + err: - if (key->algorithm == SC_ALGORITHM_EC && key_info->params.data) { + if (r < 0 && key->algorithm == SC_ALGORITHM_EC && key_info->params.data) { free(((struct sc_ec_parameters *) key_info->params.data)->named_curve); free(((struct sc_ec_parameters *) key_info->params.data)->der.value); free(key_info->params.data); @@ -1530,8 +1536,10 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (check_key_compatibility(p15card, algorithm, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, - keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot generate key with the given parameters"); + keybits, SC_ALGORITHM_ONBOARD_KEY_GEN) != SC_SUCCESS) { + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot generate key with the given parameters"); + } if (profile->ops->generate_key == NULL) { r = SC_ERROR_NOT_SUPPORTED; @@ -1968,9 +1976,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile if (r >= 0 && res_obj) *res_obj = object; + object = NULL; profile->dirty = 1; - LOG_FUNC_RETURN(ctx, r); + err: if (object) sc_pkcs15_free_object(object); From bee06eded10b5225c74758b50edfa7050de5ba71 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 25 Feb 2022 20:46:25 +0100 Subject: [PATCH 2334/4321] pkcs15-lib.c: Free file in do_select_parent() --- src/pkcs15init/pkcs15-lib.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 78dea25297..08ac2e44b0 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4025,9 +4025,17 @@ do_select_parent(struct sc_profile *profile, struct sc_pkcs15_card *p15card, } r = sc_pkcs15init_create_file(profile, p15card, *parent); + if (r < 0) { + sc_file_free(*parent); + *parent = NULL; + } LOG_TEST_RET(ctx, r, "Cannot create parent DF"); r = sc_select_file(p15card->card, &path, NULL); + if (r < 0) { + sc_file_free(*parent); + *parent = NULL; + } LOG_TEST_RET(ctx, r, "Cannot select parent DF"); } else if (r == SC_SUCCESS && !strcmp(p15card->card->name, "STARCOS")) { @@ -4041,6 +4049,7 @@ do_select_parent(struct sc_profile *profile, struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, r); } } + LOG_FUNC_RETURN(ctx, r); } From bbacd77067cb8a49dd53f1d63cbeba757c8a338d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Feb 2022 11:32:33 +0100 Subject: [PATCH 2335/4321] pkcs15-lib.c: Free DER value in check_keygen_params_consistency() --- src/pkcs15init/pkcs15-lib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 08ac2e44b0..52ac813efa 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2492,6 +2492,10 @@ check_keygen_params_consistency(struct sc_card *card, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } + if (alg == SC_ALGORITHM_EC && prkey) + /* allocated in sc_pkcs15_fix_ec_parameters */ + free(prkey->key.u.ec.params.der.value); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } From 97a30c320055da4da7fd97d6a01afee15e6846b7 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Feb 2022 20:41:58 +0100 Subject: [PATCH 2336/4321] pkcs15-lib.c: Remove unnecessary return --- src/pkcs15init/pkcs15-lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 52ac813efa..54906c0368 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1825,9 +1825,10 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil if (r >= 0 && res_obj) *res_obj = object; + object = NULL; profile->dirty = 1; - LOG_FUNC_RETURN(ctx, r); + err: if (object) sc_pkcs15_free_object(object); From 5f8abf14335540963e2648f51c6b33fa8b8ee279 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Mar 2022 10:08:42 +0100 Subject: [PATCH 2337/4321] pkcs15-lib.c: Remove unnecessary NULL checks --- src/pkcs15init/pkcs15-lib.c | 44 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 54906c0368..4ef10fc108 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -946,9 +946,9 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, sc_pkcs15init_write_info(p15card, profile, pin_obj); pin_obj = NULL; + err: - if (pin_obj) - sc_pkcs15_free_object(pin_obj); + sc_pkcs15_free_object(pin_obj); LOG_FUNC_RETURN(ctx, r); } @@ -1015,9 +1015,9 @@ sc_pkcs15init_store_puk(struct sc_pkcs15_card *p15card, profile->dirty = 1; pin_obj = NULL; + err: - if (pin_obj) - sc_pkcs15_free_object(pin_obj); + sc_pkcs15_free_object(pin_obj); LOG_FUNC_RETURN(ctx, r); } @@ -1082,9 +1082,9 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi profile->dirty = 1; pin_obj = NULL; + err: - if (pin_obj) - sc_pkcs15_free_object(pin_obj); + sc_pkcs15_free_object(pin_obj); LOG_FUNC_RETURN(ctx, r); } @@ -1350,8 +1350,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof free(((struct sc_ec_parameters *) key_info->params.data)->der.value); free(key_info->params.data); } - if (object) - sc_pkcs15init_free_object(object); + sc_pkcs15init_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1450,8 +1449,7 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi r = SC_SUCCESS; err: - if (object) - sc_pkcs15init_free_object(object); + sc_pkcs15init_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1665,15 +1663,13 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr *res_obj = object; object = NULL; - sc_pkcs15_erase_pubkey(&pubkey_args.key); + sc_pkcs15_erase_pubkey(pubkey); profile->dirty = 1; err: - if (pubkey) - sc_pkcs15_erase_pubkey(&pubkey_args.key); - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_erase_pubkey(pubkey); + sc_pkcs15_free_object(object); if (algorithm == SC_ALGORITHM_EC) /* allocated in check_keygen_params_consistency() */ free(keygen_args->prkey_args.key.u.ec.params.der.value); @@ -1739,9 +1735,9 @@ sc_pkcs15init_generate_secret_key(struct sc_pkcs15_card *p15card, struct sc_prof object = NULL; profile->dirty = 1; + err: - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1830,8 +1826,7 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil profile->dirty = 1; err: - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -1982,8 +1977,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile profile->dirty = 1; err: - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -2070,9 +2064,9 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile object = NULL; profile->dirty = 1; + err: - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -2264,8 +2258,7 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card, profile->dirty = 1; err: - if (object) - sc_pkcs15_free_object(object); + sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } @@ -2833,6 +2826,7 @@ sc_pkcs15init_select_intrinsic_id(struct sc_pkcs15_card *p15card, struct sc_prof done: memcpy(id_out, &id, sizeof(*id_out)); rv = id_out->len; + err: if (id_data) free(id_data); From 741ad259bd7d4ed862b8021bb6742eb65c498ffe Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Mar 2022 10:35:59 +0100 Subject: [PATCH 2338/4321] pkcs15-lib.c: Simplify copying ecparams --- src/pkcs15init/pkcs15-lib.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 4ef10fc108..19c03c5219 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1216,6 +1216,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof const char *label; unsigned int usage; int r = 0, key_type; + struct sc_ec_parameters *new_ecparams = NULL; LOG_FUNC_CALLED(ctx); if (!res_obj || !keybits) { @@ -1284,8 +1285,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof else if (key->algorithm == SC_ALGORITHM_EC) { /* keyargs->key.u.ec.params.der.value is allocated in keyargs, which is on stack */ struct sc_ec_parameters *ecparams = &keyargs->key.u.ec.params; - struct sc_ec_parameters *new_ecparams = malloc(sizeof(struct sc_ec_parameters)); - key_info->params.data = NULL; + new_ecparams = calloc(1, sizeof(struct sc_ec_parameters)); if (!new_ecparams) { r = SC_ERROR_OUT_OF_MEMORY; LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); @@ -1293,17 +1293,11 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof /* copy ecparams into allocated one * it will be freed with the corresponding object */ memcpy(new_ecparams, ecparams, sizeof(struct sc_ec_parameters)); + new_ecparams->named_curve = strdup(ecparams->named_curve); - if (!new_ecparams->named_curve) { - r = SC_ERROR_OUT_OF_MEMORY; - free(new_ecparams); - LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); - } new_ecparams->der.value = malloc(ecparams->der.len); - if (!new_ecparams->der.value) { + if (!new_ecparams->named_curve || !new_ecparams->der.value) { r = SC_ERROR_OUT_OF_MEMORY; - free(new_ecparams->named_curve); - free(new_ecparams); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); } memcpy(new_ecparams->der.value, ecparams->der.value, ecparams->der.len); @@ -1342,13 +1336,15 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof *res_obj = object; object = NULL; + new_ecparams = NULL; r = SC_SUCCESS; err: - if (r < 0 && key->algorithm == SC_ALGORITHM_EC && key_info->params.data) { - free(((struct sc_ec_parameters *) key_info->params.data)->named_curve); - free(((struct sc_ec_parameters *) key_info->params.data)->der.value); - free(key_info->params.data); + if (new_ecparams) { + free(new_ecparams->named_curve); + free(new_ecparams->der.value); + free(new_ecparams); + key_info->params.data = NULL; } sc_pkcs15init_free_object(object); LOG_FUNC_RETURN(ctx, r); From 3d1acdf7d82eb2c532b525cc8d9229d6d0bdf72c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 1 Mar 2022 14:21:06 +0100 Subject: [PATCH 2339/4321] pkcs15-init.c: Free prkey --- src/pkcs15init/pkcs15-lib.c | 4 +++- src/tools/pkcs15-init.c | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 19c03c5219..2e7aeb281f 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1666,9 +1666,11 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr err: sc_pkcs15_erase_pubkey(pubkey); sc_pkcs15_free_object(object); - if (algorithm == SC_ALGORITHM_EC) + if (algorithm == SC_ALGORITHM_EC) { /* allocated in check_keygen_params_consistency() */ free(keygen_args->prkey_args.key.u.ec.params.der.value); + keygen_args->prkey_args.key.u.ec.params.der.value = NULL; + } LOG_FUNC_RETURN(ctx, r); } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 5b2e17604b..76a92dedee 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1781,9 +1781,7 @@ do_generate_key(struct sc_profile *profile, const char *spec) if (r == 0) r = sc_pkcs15init_generate_key(g_p15card, profile, &keygen_args, keybits, NULL); sc_unlock(g_p15card->card); - if (algorithm == SC_ALGORITHM_EC) - /* allocated in parse_alg_spec() */ - free(keygen_args.prkey_args.key.u.ec.params.named_curve); + sc_pkcs15_free_prkey(&keygen_args.prkey_args.key); return r; } From 348f65ce230fb926686eb181101726bc93b38973 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 9 Mar 2022 17:27:01 +0100 Subject: [PATCH 2340/4321] fixed coverity 376621 Uninitialized scalar variable --- src/pkcs15init/profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 13ef881e75..9566c3791d 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1543,12 +1543,12 @@ do_acl(struct state *cur, int argc, char **argv) { struct sc_file *file = NULL; char oper[64], *what = NULL; + memset(oper, 0, sizeof(oper)); if (!cur->file) goto bad; file = cur->file->file; - memset(oper, 0, sizeof(oper)); while (argc--) { unsigned int op, method, id; From fac9bbe562df6722c521c044d6bbbd13fe437724 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 9 Mar 2022 17:37:28 +0100 Subject: [PATCH 2341/4321] fixed coverity 376619 Uninitialized pointer read --- src/pkcs11/framework-pkcs15.c | 2 +- src/pkcs11/mechanism.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index f5e18930ef..1706068917 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5828,7 +5828,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, unsigned long ext_flags, CK_ULONG min_key_size, CK_ULONG max_key_size) { CK_MECHANISM_INFO mech_info; - sc_pkcs11_mechanism_type_t *mt, *registered_mt; + sc_pkcs11_mechanism_type_t *mt = NULL, *registered_mt = NULL; CK_FLAGS ec_flags = 0; CK_RV rc; diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index ae56b05eec..00a112c850 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1368,9 +1368,13 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, { sc_pkcs11_mechanism_type_t *hash_type, *new_type; struct hash_signature_info *info; - CK_MECHANISM_INFO mech_info = sign_type->mech_info; + CK_MECHANISM_INFO mech_info; CK_RV rv; + if (!sign_type) + return CKR_MECHANISM_INVALID; + mech_info = sign_type->mech_info; + if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST))) return CKR_MECHANISM_INVALID; From cf583886eae6a511363ba84531fa6967526a3875 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 9 Mar 2022 17:42:03 +0100 Subject: [PATCH 2342/4321] fixed coverity 376512 Uninitialized scalar variable --- src/tools/opensc-explorer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 04efdf8f30..be5fb77632 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1908,7 +1908,9 @@ static int do_random(int argc, char **argv) if (argc == 2) { /* outf is guaranteed to be non-NULL */ - size_t written = fwrite(buffer, 1, count, outf); + size_t written = 0; + if (count > 0) + written = fwrite(buffer, 1, count, outf); if (written < (size_t) count) perror(filename); From 6b8cabd2106ab448c820aab07f8b001db164b1f0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 9 Mar 2022 18:15:03 +0100 Subject: [PATCH 2343/4321] fixed coverity 374853 Unchecked return value --- src/tests/fuzzing/fuzz_pkcs15_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index e758e26d5a..0d7911eacc 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -52,9 +52,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) reader = sc_ctx_get_reader(ctx, 0); sc_connect_card(reader, &card); - sc_pkcs15_bind(card, NULL, &p15card); - if (p15card) { + if (SC_SUCCESS == sc_pkcs15_bind(card, NULL, &p15card) + && p15card) { const uint8_t *in, *param; uint16_t in_len, param_len; fuzz_get_chunk(reader, &in, &in_len); From 5e1aa4a82332c48ac1bfbc0e9bab88f5fe81a985 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 9 Mar 2022 18:27:59 +0100 Subject: [PATCH 2344/4321] fuzzer: added error checking --- src/tests/fuzzing/fuzzer.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/tests/fuzzing/fuzzer.c b/src/tests/fuzzing/fuzzer.c index ff80f1a241..a186ebb57d 100644 --- a/src/tests/fuzzing/fuzzer.c +++ b/src/tests/fuzzing/fuzzer.c @@ -28,27 +28,40 @@ int main (int argc, char **argv) { printf("Testing one input:\n"); FILE *fd = NULL; - size_t len = 0; + long int len = 0; unsigned char *buffer = NULL; + int r = 1; if (argc < 2) { fprintf(stderr, "No arguments, passing NULL\n"); len = 0; } else { - fd = fopen(argv[1], "r"); - fseek(fd, 0, SEEK_END); - len = ftell(fd); + if ((fd = fopen(argv[1], "r")) == NULL + || fseek(fd, 0, SEEK_END) != 0 + || (len = ftell(fd)) < 0) { + fprintf(stderr, "fopen/fseek failed\n"); + goto err; + } rewind(fd); - buffer = (unsigned char*) malloc(len); - if (fread(buffer, 1, len, fd) != len) { + if ((buffer = (unsigned char*) malloc(len)) == NULL) { + fprintf(stderr, "malloc failed\n"); + goto err; + } + + if (fread(buffer, 1, len, fd) != (size_t)len) { fprintf(stderr, "fread failed\n"); + goto err; } - fclose(fd); } LLVMFuzzerTestOneInput(buffer, len); + r = 0; + +err: + if (fd) + fclose(fd); if (buffer) free(buffer); printf("Done!\n"); - return 0; + return r; } From 42d9d5d5e86254edb879c7b38f5506424279575a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Mar 2022 09:50:40 +0100 Subject: [PATCH 2345/4321] fuzzer: add input checking fixes coverity 376620 Dereference before null check --- src/tests/fuzzing/fuzz_pkcs15init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 73fea31683..ce2022006d 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -52,9 +52,13 @@ void fuzz_pkcs15init_bind(struct sc_card *card, struct sc_profile **result, const uint8_t *data, size_t size) { struct sc_profile *profile = NULL; - const char *driver = card->driver->short_name; + const char *driver; struct sc_pkcs15init_operations * (* func)(void) = NULL; int r = 0; + + if (!card || !card->driver || !result) + return; + *result = NULL; r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN); @@ -63,7 +67,10 @@ void fuzz_pkcs15init_bind(struct sc_card *card, struct sc_profile **result, } profile = sc_profile_new(); + if (!profile) + return; profile->card = card; + driver = card->driver->short_name; for (int i = 0; profile_operations[i].name; i++) { if (!strcasecmp(driver, profile_operations[i].name)) { From f49aec093075560fa5240bd6696d5554f844043f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Mar 2022 10:20:17 +0100 Subject: [PATCH 2346/4321] more documentation on sc_get_challenge() --- src/libopensc/opensc.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6c3332ecc0..604db92f79 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -720,6 +720,16 @@ struct sc_card_operations { int (*select_file)(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out); int (*get_response)(struct sc_card *card, size_t *count, u8 *buf); + /** + * Get random data from the card + * + * Implementation of this call back is optional and may be NULL. + * + * @param card struct sc_card object on which to issue the command + * @param buf buffer to be filled with random data + * @param count number of random bytes to initialize + * @return number of random bytes successfully initialized (i.e. `count` or less bytes) or an error code + */ int (*get_challenge)(struct sc_card *card, u8 * buf, size_t count); /* @@ -1319,7 +1329,7 @@ int sc_put_data(struct sc_card *, unsigned int, const u8 *, size_t); /** * Gets challenge from the card (normally random data). * @param card struct sc_card object on which to issue the command - * @param rndout buffer for the returned random challenge + * @param rndout buffer for the returned random challenge. Note that the buffer may be only partially initialized on error. * @param len length of the challenge * @return SC_SUCCESS on success and an error code otherwise */ From 2d0ddf9fc521820af88099f309c7848230684da4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Mar 2022 10:39:56 +0100 Subject: [PATCH 2347/4321] fixed coverity 374839 Dereference after null check --- src/tests/fuzzing/fuzzer_reader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzzer_reader.c b/src/tests/fuzzing/fuzzer_reader.c index 7d7a579b39..78ea6e8e63 100644 --- a/src/tests/fuzzing/fuzzer_reader.c +++ b/src/tests/fuzzing/fuzzer_reader.c @@ -44,7 +44,8 @@ void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_ *chunk_size = 0; if (!chunk || !chunk_size || !reader) { - sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); + if (reader) + sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments"); return; } data = reader->drv_data; From 2192a2a0668a0675c6633e2d5a4f6c8f624160e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 17 Mar 2022 11:57:40 +0100 Subject: [PATCH 2348/4321] npa-tool: added newline to error message --- src/tools/npa-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 78a661d167..134d643438 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -870,7 +870,7 @@ main (int argc, char **argv) int main (int argc, char **argv) { - fprintf(stderr, "OpenPACE is needed for npa-tool"); + fprintf(stderr, "OpenPACE is needed for npa-tool\n"); return 1; } #endif From e96dbe9a59b30f00eefa823b731c85e89d5aa960 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 13 Mar 2022 23:00:03 +0100 Subject: [PATCH 2349/4321] Check pkcs15 profile before initialization of DFs Fixes an out of bounds write in pkcs15-init https://oss-fuzz.com/testcase-detail/5974179147546624 --- src/pkcs15init/profile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 9566c3791d..ce55dbaa95 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1247,7 +1247,8 @@ new_file(struct state *cur, const char *name, unsigned int type) } else if (!strcasecmp(name+7, "AppDF")) { file = init_file(SC_FILE_TYPE_DF); } else { - if (map_str2int(cur, name+7, &df_type, pkcs15DfNames)) + if (map_str2int(cur, name+7, &df_type, pkcs15DfNames) + || df_type >= SC_PKCS15_DF_TYPE_COUNT) return NULL; file = init_file(SC_FILE_TYPE_WORKING_EF); From a2aeff856a8a22c743f2dc7ce8232346511ee493 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Mar 2022 08:35:48 +0100 Subject: [PATCH 2350/4321] myeid: add erroro handling for missing ACL fixes NULL pointer dereference https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45458 --- src/libopensc/card-myeid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 94e26ac93b..1483a80315 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -333,6 +333,8 @@ static const struct sc_card_operations *iso_ops = NULL; static int acl_to_byte(const struct sc_acl_entry *e) { + if (NULL == e) + return 0x00; switch (e->method) { case SC_AC_NONE: return 0x00; From 24b182c3769f6418e20b938b6dadcac01784f7b8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Mar 2022 08:48:41 +0100 Subject: [PATCH 2351/4321] =?UTF-8?q?fixed=20Null-dereference=20READ=20?= =?UTF-8?q?=C2=B7=20sc=5Fprofile=5Fget=5Ffile=5Finstance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45402 --- src/pkcs15init/profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index ce55dbaa95..bdb40e0e19 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -572,7 +572,7 @@ sc_profile_get_file_instance(struct sc_profile *profile, const char *name, if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND); sc_file_dup(&file, fi->file); - sc_log(ctx, "ident '%s'; parent '%s'", fi->ident, fi->parent->ident); + sc_log(ctx, "ident '%s'; parent '%s'", fi->ident, fi->parent ? fi->parent->ident : "(null)"); if (file == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); sc_log(ctx, "file (type:%X, path:'%s')", file->type, sc_print_path(&file->path)); From 4db93abfb7c6db89cf05577e971ce5d8544b502c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Mar 2022 08:55:50 +0100 Subject: [PATCH 2352/4321] =?UTF-8?q?fixed=20Null-dereference=20READ=20?= =?UTF-8?q?=C2=B7=20strlcpy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45399 --- src/pkcs15init/pkcs15-sc-hsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 1c7e7dfbf6..fa57ce1dd4 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -266,7 +266,8 @@ static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card strlcpy(cvc.car, "UTCA00001", sizeof cvc.car); cvc.carLen = strlen(cvc.car); - strlcpy(cvc.chr, priv->serialno, sizeof cvc.chr); + if (priv->serialno) + strlcpy(cvc.chr, priv->serialno, sizeof cvc.chr); strlcat(cvc.chr, "00001", sizeof cvc.chr); cvc.chrLen = strlen(cvc.chr); From 39b9b0721bfcea2a0e75ee6a1445d3df3d21129e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 14 Mar 2022 11:15:54 +0100 Subject: [PATCH 2353/4321] Use valid mt in sc_pkcs11_register_sign_and_hash_mechanism() The `mt` is created via sc_pkcs11_new_fw_mechanism(), but before sc_pkcs11_register_sign_and_hash_mechanism() does not have to be registered. --- src/pkcs11/framework-pkcs15.c | 84 ++++++++++++++++++++--------------- src/pkcs11/mechanism.c | 13 +++--- src/pkcs11/openssl.c | 16 +++---- src/pkcs11/sc-pkcs11.h | 2 +- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1706068917..0903ccb502 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5794,7 +5794,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5804,7 +5804,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5815,7 +5815,7 @@ register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5857,48 +5857,58 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, return CKR_HOST_MEMORY; if (flags & SC_ALGORITHM_ECDSA_HASH_NONE) { rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } #ifdef ENABLE_OPENSSL /* if card supports RAW add sign_and_hash using RAW for mechs card does not support */ - + sc_pkcs11_mechanism_type_t *sign_type = mt ? mt : registered_mt; if (flags & SC_ALGORITHM_ECDSA_RAW) { if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA1)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA1, CKM_SHA_1, registered_mt); - if (rc != CKR_OK) + CKM_ECDSA_SHA1, CKM_SHA_1, sign_type); + if (rc != CKR_OK) { + sc_pkcs11_free_mechanism(&mt); return rc; + } } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA224)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA224, CKM_SHA224, registered_mt); - if (rc != CKR_OK) + CKM_ECDSA_SHA224, CKM_SHA224, sign_type); + if (rc != CKR_OK) { + sc_pkcs11_free_mechanism(&mt); return rc; + } } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA256)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA256, CKM_SHA256, registered_mt); - if (rc != CKR_OK) + CKM_ECDSA_SHA256, CKM_SHA256, sign_type); + if (rc != CKR_OK) { + sc_pkcs11_free_mechanism(&mt); return rc; + } } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA384)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA384, CKM_SHA384, registered_mt); - if (rc != CKR_OK) + CKM_ECDSA_SHA384, CKM_SHA384, sign_type); + if (rc != CKR_OK) { + sc_pkcs11_free_mechanism(&mt); return rc; + } } if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA512)) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, - CKM_ECDSA_SHA512, CKM_SHA512, registered_mt); - if (rc != CKR_OK) + CKM_ECDSA_SHA512, CKM_SHA512, sign_type); + if (rc != CKR_OK) { + sc_pkcs11_free_mechanism(&mt); return rc; + } } } #endif @@ -5909,7 +5919,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5919,7 +5929,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5929,7 +5939,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5939,7 +5949,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5949,7 +5959,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5964,7 +5974,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -5972,7 +5982,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -5984,7 +5994,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6013,7 +6023,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6025,7 +6035,7 @@ static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6049,7 +6059,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6064,7 +6074,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6075,7 +6085,7 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6104,7 +6114,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6112,7 +6122,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6120,7 +6130,7 @@ static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6249,7 +6259,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6266,7 +6276,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) /* Supported in hardware only, if the card driver declares it. */ mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } @@ -6286,7 +6296,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rsa_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6345,7 +6355,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, ®istered_mt); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; @@ -6387,7 +6397,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) mech_info.flags &= ~(CKF_SIGN|CKF_VERIFY|CKF_SIGN_RECOVER|CKF_VERIFY_RECOVER); mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) { return rc; } @@ -6400,7 +6410,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (!mt) return CKR_HOST_MEMORY; rc = sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (rc != CKR_OK) return rc; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 00a112c850..fc4a378a0c 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1317,13 +1317,14 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, return mt; } -void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t *mt) +void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t **mt) { - if (!mt) + if (!mt || !(*mt)) return; - if (mt->free_mech_data) - mt->free_mech_data(mt->mech_data); - free(mt); + if ((*mt)->free_mech_data) + (*mt)->free_mech_data((*mt)->mech_data); + free(*mt); + *mt = NULL; } /* @@ -1398,7 +1399,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, } rv = sc_pkcs11_register_mechanism(p11card, new_type, NULL); - sc_pkcs11_free_mechanism(new_type); + sc_pkcs11_free_mechanism(&new_type); return rv; } diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index d029d56b77..a6ea9e4722 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -276,44 +276,44 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) openssl_sha1_mech.mech_data = EVP_sha1(); mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); openssl_sha224_mech.mech_data = EVP_sha224(); mt = dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); openssl_sha256_mech.mech_data = EVP_sha256(); mt = dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); openssl_sha384_mech.mech_data = EVP_sha384(); mt = dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); openssl_sha512_mech.mech_data = EVP_sha512(); mt = dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); if (!FIPS_mode()) { openssl_md5_mech.mech_data = EVP_md5(); mt = dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); openssl_ripemd160_mech.mech_data = EVP_ripemd160(); mt = dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); } openssl_gostr3411_mech.mech_data = EVP_get_digestbynid(NID_id_GostR3411_94); mt = dup_mem(&openssl_gostr3411_mech, sizeof openssl_gostr3411_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(mt); + sc_pkcs11_free_mechanism(&mt); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 13e3a5adbe..de106257f6 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -465,7 +465,7 @@ sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *, sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR, CK_KEY_TYPE, const void *, void (*)(const void *), CK_RV (*)(const void *, void **)); -void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t *mt); +void sc_pkcs11_free_mechanism(sc_pkcs11_mechanism_type_t **mt); sc_pkcs11_operation_t *sc_pkcs11_new_operation(sc_pkcs11_session_t *, sc_pkcs11_mechanism_type_t *); void sc_pkcs11_release_operation(sc_pkcs11_operation_t **); From 65892da2360fe74e872c54ae8137fc96773341b4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 14 Mar 2022 19:34:23 +0100 Subject: [PATCH 2354/4321] Remove unused sc_pkcs11_mechanism_type_t from hash_signature_info The sign_type is assigned to hash_signature_info struct in sc_pkcs11_register_sign_and_hash_mechanism() but then it is never used. The sign_type can be either registered (and then it is also release with p11card) or not (memory leak). --- src/pkcs11/mechanism.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index fc4a378a0c..a9c7e4d1de 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -31,7 +31,6 @@ struct hash_signature_info { CK_MECHANISM_TYPE hash_mech; CK_MECHANISM_TYPE sign_mech; sc_pkcs11_mechanism_type_t *hash_type; - sc_pkcs11_mechanism_type_t *sign_type; }; /* Also used for verification and decryption data */ @@ -1387,7 +1386,6 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, return CKR_HOST_MEMORY; info->mech = mech; - info->sign_type = sign_type; info->hash_type = hash_type; info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; From 0d1f6f70d65ae6ae625f53d2209fe928db3185c0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 30 Mar 2022 15:58:07 +0200 Subject: [PATCH 2355/4321] win32: Use newest version of zlib Only on Windows, we're linking statically against zlib. All other systems should update their zlib version on their own keeping ABI stability. Zlib 1.2.12 Fixes a deflate bug when using the Z_FIXED strategy that can result in out-of-bound accesses, see https://zlib.net/ --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 37c452403b..c3b4131c13 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -13,7 +13,7 @@ environment: secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY PATH: C:\cygwin\bin;%PATH% OPENPACE_VER: 1.1.2 - ZLIB_VER_DOT: 1.2.11 + ZLIB_VER_DOT: 1.2.12 matrix: # not compatible with OpenSSL 1.1.1: # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 From b2e17b3d1eeb8fcd58aeb44f50b976260353e06b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 31 Mar 2022 00:02:33 +0200 Subject: [PATCH 2356/4321] Appveyor: fixed cache dependency to .appveyor.yml --- .appveyor.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index c3b4131c13..e2b7a5ea48 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -120,10 +120,10 @@ deploy_script: - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" -a \"$APPVEYOR_REPO_NAME\" = \"OpenSC/OpenSC\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" cache: - - C:\zlib -> appveyor.yml - - C:\zlib-Win32 -> appveyor.yml - - C:\zlib-Win64 -> appveyor.yml - - C:\openpace -> appveyor.yml - - C:\openpace-Win32 -> appveyor.yml - - C:\openpace-Win64 -> appveyor.yml - - cpdksetup.exe -> appveyor.yml + - C:\zlib -> .appveyor.yml + - C:\zlib-Win32 -> .appveyor.yml + - C:\zlib-Win64 -> .appveyor.yml + - C:\openpace -> .appveyor.yml + - C:\openpace-Win32 -> .appveyor.yml + - C:\openpace-Win64 -> .appveyor.yml + - cpdksetup.exe -> .appveyor.yml From cff378a47305cd7e3520a5063239a0ae542658dc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 2 Feb 2022 16:03:20 +0100 Subject: [PATCH 2357/4321] Add more algos for pubkey decode in fuzz_pkcs15_decode `sc_pkcs15_decode_pubkey()` uses `key->algorithm` to decide next steps. --- src/tests/fuzzing/fuzz_pkcs15_decode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index ef79f0d2d7..4340840db2 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -37,6 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_decode_skdf_entry, sc_pkcs15_decode_cdf_entry, sc_pkcs15_decode_dodf_entry, sc_pkcs15_decode_aodf_entry }; + int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC, SC_ALGORITHM_GOSTR3410, SC_ALGORITHM_EDDSA }; size_t i; if (!ctx) @@ -61,9 +62,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_free_object(obj); } - struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); - sc_pkcs15_decode_pubkey(ctx, pubkey, Data, Size); - sc_pkcs15_free_pubkey(pubkey); + for (i = 0; i < 4; i++) { + struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); + pubkey->algorithm = algorithms[i]; + sc_pkcs15_decode_pubkey(ctx, pubkey, Data, Size); + sc_pkcs15_free_pubkey(pubkey); + } struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, Data, Size); From 5e952bca7a10a26eb679000e54e2533be09848d3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 2 Feb 2022 17:43:35 +0100 Subject: [PATCH 2358/4321] Add reader into fuzz_pkcs15_decode Binding with p15card can lead to new paths in code during fuzzing (decode functions use p15card->app). Each decoding function gets its own data buffer - data generation adapts to each function. --- src/tests/fuzzing/Makefile.am | 2 +- src/tests/fuzzing/fuzz_pkcs15_decode.c | 124 ++++++++++++++++--------- 2 files changed, 81 insertions(+), 45 deletions(-) diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 9a2270c865..8f849d4915 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -18,7 +18,7 @@ endif fuzz_asn1_print_SOURCES = fuzz_asn1_print.c $(ADDITIONAL_SRC) fuzz_asn1_sig_value_SOURCES = fuzz_asn1_sig_value.c $(ADDITIONAL_SRC) -fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c $(ADDITIONAL_SRC) +fuzz_pkcs15_decode_SOURCES = fuzz_pkcs15_decode.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_pkcs15_reader_SOURCES = fuzz_pkcs15_reader.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index 4340840db2..28bf0c79af 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -20,60 +20,96 @@ #include "config.h" #endif +#include "fuzzer_reader.h" #include "libopensc/pkcs15.h" #include "libopensc/internal.h" -#include -#include -static struct sc_context *ctx = NULL; -static struct sc_pkcs15_card *p15card = NULL; -static sc_card_t card = {0}; int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - int (* decode_entries[])(struct sc_pkcs15_card *, struct sc_pkcs15_object *, - const u8 **nbuf, size_t *nbufsize) = { - sc_pkcs15_decode_prkdf_entry, sc_pkcs15_decode_pukdf_entry, - sc_pkcs15_decode_skdf_entry, sc_pkcs15_decode_cdf_entry, - sc_pkcs15_decode_dodf_entry, sc_pkcs15_decode_aodf_entry - }; - int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC, SC_ALGORITHM_GOSTR3410, SC_ALGORITHM_EDDSA }; - size_t i; + size_t i = 0; + struct sc_reader *reader = NULL; + const uint8_t *buf; + uint16_t buf_len; + static struct sc_context *ctx = NULL; + static struct sc_pkcs15_card *p15card = NULL; + static sc_card_t *card = NULL; + struct sc_pkcs15_tokeninfo *tokeninfo = NULL; + int (* decode_entries[])(struct sc_pkcs15_card *, struct sc_pkcs15_object *, + const u8 **nbuf, size_t *nbufsize) = { + sc_pkcs15_decode_prkdf_entry, sc_pkcs15_decode_pukdf_entry, + sc_pkcs15_decode_skdf_entry, sc_pkcs15_decode_cdf_entry, + sc_pkcs15_decode_dodf_entry, sc_pkcs15_decode_aodf_entry + }; + int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC, SC_ALGORITHM_GOSTR3410, SC_ALGORITHM_EDDSA }; - if (!ctx) - sc_establish_context(&ctx, "fuzz"); - if (!p15card) { - card.ctx = ctx; - p15card = sc_pkcs15_card_new(); - if (p15card) { - p15card->card = &card; - } - } + /* Establish context for fuzz app*/ + sc_establish_context(&ctx, "fuzz"); + if (!ctx) + return 0; - for (i = 0; i < sizeof decode_entries/sizeof *decode_entries; i++) { - struct sc_pkcs15_object *obj; - const u8 *p = Data; - size_t len = Size; - obj = calloc(1, sizeof *obj); - while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, &len)) { - sc_pkcs15_free_object(obj); - obj = calloc(1, sizeof *obj); - } - sc_pkcs15_free_object(obj); - } + /* Erase possible readers from ctx */ + while (list_size(&ctx->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); - for (i = 0; i < 4; i++) { - struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); - pubkey->algorithm = algorithms[i]; - sc_pkcs15_decode_pubkey(ctx, pubkey, Data, Size); - sc_pkcs15_free_pubkey(pubkey); - } + /* Create virtual reader */ + ctx->reader_driver = sc_get_fuzz_driver(); + fuzz_add_reader(ctx, Data, Size); + reader = sc_ctx_get_reader(ctx, 0); - struct sc_pkcs15_tokeninfo *tokeninfo = sc_pkcs15_tokeninfo_new(); - sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, Data, Size); - sc_pkcs15_free_tokeninfo(tokeninfo); + /* Connect card to reader */ + if (sc_connect_card(reader, &card)) { + sc_release_context(ctx); + return 0; + } - sc_pkcs15_parse_unusedspace(Data, Size, p15card); + sc_pkcs15_bind(card, NULL, &p15card); + if (!p15card) + goto err; - return 0; + for (i = 0; i < sizeof decode_entries/sizeof *decode_entries; i++) { + struct sc_pkcs15_object *obj; + const u8 *p = NULL; + size_t len = 0; + if (!(obj = calloc(1, sizeof *obj))) + goto err; + fuzz_get_chunk(reader, &buf, &buf_len); + p = buf; + len = (size_t) buf_len; + while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, (size_t *) &len)) { + sc_pkcs15_free_object(obj); + if (!(obj = calloc(1, sizeof *obj))) + goto err; + } + sc_pkcs15_free_object(obj); + } + + fuzz_get_chunk(reader, &buf, &buf_len); + for (i = 0; i < 4; i++) { + struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); + if (!pubkey) + goto err; + pubkey->algorithm = algorithms[i]; + sc_pkcs15_decode_pubkey(ctx, pubkey, buf, buf_len); + sc_pkcs15_free_pubkey(pubkey); + } + + fuzz_get_chunk(reader, &buf, &buf_len); + tokeninfo = sc_pkcs15_tokeninfo_new(); + sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, buf, buf_len); + sc_pkcs15_free_tokeninfo(tokeninfo); + + fuzz_get_chunk(reader, &buf, &buf_len); + sc_pkcs15_parse_unusedspace(buf, buf_len, p15card); + + sc_pkcs15_card_free(p15card); + +err: + sc_disconnect_card(card); + sc_release_context(ctx); + return 0; } From eb84432f751eac002c51fcfd18bfb2161c64d21b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 2 Feb 2022 19:30:45 +0100 Subject: [PATCH 2359/4321] Add fuzzer for encoding objects Initialize the card and iterate over objects stored on p15card - try to encode into buffer. --- src/tests/fuzzing/Makefile.am | 4 +- src/tests/fuzzing/fuzz_pkcs15_encode.c | 101 +++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzz_pkcs15_encode.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 8f849d4915..aeb569b161 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -7,7 +7,8 @@ LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/common/libcompat.la noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ - fuzz_scconf_parse_string fuzz_pkcs15init + fuzz_scconf_parse_string fuzz_pkcs15init \ + fuzz_pkcs15_encode noinst_HEADERS = fuzzer_reader.h @@ -24,3 +25,4 @@ fuzz_scconf_parse_string_SOURCES = fuzz_scconf_parse_string.c $(ADDITIONAL_SRC) fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) fuzz_pkcs15init_LDFLAGS = -static +fuzz_pkcs15_encode_SOURCES = fuzz_pkcs15_encode.c fuzzer_reader.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c new file mode 100644 index 0000000000..3f1137cd39 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c @@ -0,0 +1,101 @@ +/* + * fuzz_pkcs15_encode.c: Fuzzer for encoding functions + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fuzzer_reader.h" +#include "libopensc/pkcs15.h" +#include "libopensc/internal.h" + + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + struct sc_context *ctx = NULL; + struct sc_card *card = NULL; + struct sc_pkcs15_card *p15card = NULL; + struct sc_reader *reader; + struct sc_pkcs15_object *obj; + unsigned char *unused_space = NULL; + size_t unused_space_len = 0; + + sc_establish_context(&ctx, "fuzz"); + if (!ctx) + return 0; + /* copied from sc_release_context() */ + while (list_size(&ctx->readers)) { + c_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); + + ctx->reader_driver = sc_get_fuzz_driver(); + + fuzz_add_reader(ctx, Data, Size); + + reader = sc_ctx_get_reader(ctx, 0); + sc_connect_card(reader, &card); + sc_pkcs15_bind(card, NULL, &p15card); + if (!p15card) + goto end; + + for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { + u8 *buf = NULL; + size_t buf_len = 0; + struct sc_pkcs15_object *key_object = NULL; + sc_pkcs15_pubkey_t *pkey = NULL; + switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { + case SC_PKCS15_TYPE_PUBKEY: + sc_pkcs15_encode_pukdf_entry(ctx, obj, &buf, &buf_len); + sc_pkcs15_read_pubkey(p15card, obj, &pkey); + sc_pkcs15_free_pubkey(pkey); + break; + case SC_PKCS15_TYPE_PRKEY: + sc_pkcs15_encode_prkdf_entry(ctx, obj, &buf, &buf_len); + break; + case SC_PKCS15_TYPE_DATA_OBJECT: + sc_pkcs15_encode_dodf_entry(ctx, obj, &buf, &buf_len); + break; + case SC_PKCS15_TYPE_SKEY: + sc_pkcs15_encode_skdf_entry(ctx, obj, &buf, &buf_len); + break; + case SC_PKCS15_TYPE_AUTH: + sc_pkcs15_encode_aodf_entry(ctx, obj, &buf, &buf_len); + break; + case SC_PKCS15_TYPE_CERT: + sc_pkcs15_encode_cdf_entry(ctx, obj, &buf, &buf_len); + sc_pkcs15_prkey_attrs_from_cert(p15card, obj, &key_object); + break; + } + free(buf); + } + sc_pkcs15_encode_unusedspace(ctx, p15card, &unused_space, &unused_space_len); + free(unused_space); + + sc_pkcs15_card_free(p15card); +err: + sc_disconnect_card(card); + sc_release_context(ctx); + + return 0; +} From f21c2ae21c1813dd8ab7332b597e0e7bef0edf2c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 13 Feb 2022 18:33:05 +0100 Subject: [PATCH 2360/4321] Export sc_pkcs15_encode_skdf_entry --- src/libopensc/libopensc.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 44fa8e96a8..73b2a6e186 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -177,6 +177,7 @@ sc_pkcs15_encode_pubkey_eddsa sc_pkcs15_encode_pubkey_gostr3410 sc_pkcs15_encode_pubkey_as_spki sc_pkcs15_encode_pukdf_entry +sc_pkcs15_encode_skdf_entry sc_pkcs15_encode_tokeninfo sc_pkcs15_encode_unusedspace sc_pkcs15_erase_pubkey From 1dbd02123c8fbe75cd503223e74145fbed317d4a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 27 Feb 2022 19:30:33 +0100 Subject: [PATCH 2361/4321] Add corpus for fuzzer for encoding --- .../741a0aae7b5b08c0ad2822ede5b3364302b28b31 | Bin 0 -> 2651 bytes .../7cf8e9b31dcee040ee438441aca2aecb523ed5e9 | Bin 0 -> 26449 bytes .../830e1bf4c7f0c539e9686bc1517d6f87907d4bf8 | Bin 0 -> 10960 bytes .../9ad3fc3cb11967be927bad9263d326783c450e37 | Bin 0 -> 3641 bytes .../b2b75c07a2c427c15ecd40ce47a9814279745b7d | Bin 0 -> 3507 bytes .../cb50689bf49ccb45a2af690848517305dcf1e429 | Bin 0 -> 3153 bytes .../de913ba454f894cfc38a16dd122ad673d32ac480 | Bin 0 -> 1423 bytes 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/741a0aae7b5b08c0ad2822ede5b3364302b28b31 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/7cf8e9b31dcee040ee438441aca2aecb523ed5e9 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/830e1bf4c7f0c539e9686bc1517d6f87907d4bf8 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/9ad3fc3cb11967be927bad9263d326783c450e37 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/b2b75c07a2c427c15ecd40ce47a9814279745b7d create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/cb50689bf49ccb45a2af690848517305dcf1e429 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/de913ba454f894cfc38a16dd122ad673d32ac480 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/741a0aae7b5b08c0ad2822ede5b3364302b28b31 b/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/741a0aae7b5b08c0ad2822ede5b3364302b28b31 new file mode 100644 index 0000000000000000000000000000000000000000..201f37c792b16fa8b1522d9d8dddcef51dbb12f7 GIT binary patch literal 2651 zcmdUxX;9Ni8i)V?1QUU9$Q`2+M?sWe2!VwA3IP$3aE^$C2nfm%ZzKqE1S4`836p@~ zP(TrMjZT6bA_x;fIfO+#5S3XVItt1q2859X9jk`Te%P=3p{w3{s=MBPe%;m8>VVZO z7XXrQU&-DiG7$|0(9Vt!AcD1gL<10DX)Na|z(K`S_(cE!7^=W!fcJ$Vnw*FgN5M0_z^^dmppuFcQ2M7o{t^m-0Se_&YM+3k&1d&BhStKWmR>&flEP~6T zm9j{F8Cqrnd`tE2f0`&PTk*|AQ5GR&k&-M@mPIPENcC?B1iUmHAONt45Q~92!Qs%w z8vuN#OCf)!z<2szd?1Ub^MCFn2PiK}r~*d}4ugjlFmmDDp$m6GHXsKK!q~th0D>pU zB!U^4M8+FgIGH*dnG&2xM&^!0b0cG-nJEsBvv4pb;}XEw0{s5qSz5O^J_N+8Z%|kF zuDk(D!>qpa%yR9BvC#NK>uod+LcIn?V zoq56U%;rv)SJ%%`kcTQn5o7)XX&%khDn(`l4I5F-oTvC%$Cqi3-k*K;AGh_mW3Yc8 zN1I6Aaq50&D9K^S4Xf3eo_puS-2Lo=NwQbFW^AZ9Jl1lxK;_jl>cggIpA8!>J=)hl zTKeaU$4kyxr;o-s&r37u2}gGRl+Y)+M_Q-t9Y)v|eRam@_RfhXmAUSj6G2}2c}S#= zHWBwoj`hF?%Air&wg`dJa)(rghqPSsm?+(R9IM>(n*aVpyjzv=z`}xH`5Z*M#-&&hg!(J{-m7>!Uj9YRZhqx;KYK}4|w1p@4 zxJT>^4x?65EsfXbqu%N9G%SYo!`>uiQqip~D|%a-pNDR37T4P+ol!a8vc}$z*(1CT zQEUVSAQ2Vr$cKk)QQuHqm%L%yo}&8-dB_f}JdAM!{+=en9>iRtB9sjIaf4h+{&8(x0>)j@kTDim7dYAcp(f)U;?I;TS|bS5 z7lP@h18-c4>H`vjE5@@7Z?`NtoBZ=_6{5ZBNqStw4b zTYKkvcUrZ(ZsKb^)fLiL^-aD{pU3kgi6NT(v!a29-pC_e*AjdMe9Mt%{0nIuGd1|8 zgHer%oV{}&F9d0qmigxUKDsPg_ac0k&k%vYNS$9|K`k&P1 zef0_8)k<#ps{u1v*JBnRkH}yejRpqm>q~o`(S;B(%$4;LRuI*32@}=4<5Ck#4Hk@6 z<{2kmrQR$`IeE%I!jnpmpq^cS4%FVp3drlz8(48x`}YqA3?k7=gE+;EnwdKWu?&{^ zlCxoKoq^mLLvyS5tNC~n6Jwv0(Jkeyz-CyA>N=jVF=!jR^k`b5Y7X>ehL_=Vy_fpb zCyWw834uT;bz<_9xfxI#!Qvt*Kk1`4uw6JkTg<4Rm@2AJSElc--+-sQo0^p(Yu6+B zg=_Ym)3kgE0K+^dV9_ZgIFv?N)S`_{*-ga`y|wY)wC1HK)+Ov>&)can{1K7~!OEg- zo#C;XCWOxhW${OH#V>KxinEM3E{p|(!C0&?u0qk)O#6^6$vrU1{~XAY^YT!l&@2CS z*kW$(w48feD%{uT80EVX8Ncu&CW9?KU%g)KJ@tCJ6t?w^COb?E4 zQOBH!_kAvke$-s)9cQ^!XlL|}+VaVX@4~xl9Fsz-EO{_nJ#}h+S5&-IzH#AGhD!WX z>tc$$sGz>Ac(%lUT(j_HbA|c&MNC=Vw5|YxP(jX}af+#K04N~9W z5zo={z9)RoIq&~}pL20J&okFvd(X4h-s|4?+G~xd0Kq{bfFH++PA41z7y$H*0e}G4 z{Xu{j029F8kM1@|g~J~R^aTNgLI8n4Ko}6d0LvE$i~;xp5wa0(1F_@JWG(~JQ6NZQ z1Yv**z63D)=WEfNpRZMOf4+9e`}x}M=dn0{8jJI{#^MG*m_R@P7#T_DyG?3^E7_tTTo4&X9b8{;+;Z3+syjto83mn0zaN+5wYT z_>D14zm>p#{5xZqeJep23zHc8L+1YBn*NZQ{>DZ>Ebuof_YZab!vcRuO@Cvf7(nsg z*!y4K_0O=T`U%#+U->wu+2)Mv%@Wxp`oXp`1{DSO;7jJiJ`I&~GKFcYHwz4iMgNB>6b_czAiCyihJ~ z2pFazMCvIkyxb5@F38v4)(Hecu!41Hoc-Ah|sV zIs!6NkWA1XIuM8o4}j=#!1k#KD9Cp&hQ@BPm;#9j;7sgofBm7Wn*|3x1ox|!@LJli z_#y`}gb)Ev6AXuorKQcPs?I7d%Brj(qs9v1fRGcSbMSCLI5{A^+?*VoR|wHLVV{1v zg-HMFfgljJpL(QMba8Svb2N7}a-mc-va&X#{4^w`lo%&BuM{VTxFjc3j8{w&;t!<$ z<&y#70dW36OaSb26cEgf0#X`q@=0)tPaJTo$u09=C;2g3CR2fkDrwA>8U+mowo~qf z-_dH3ZZg`}k9)1&{}CSv9yfpNgk>!?hwv`yT>NlM4`d^fml%g2x-ZUd|bVugHb5jh(}Utj9wTh71cXvx^0 z$r|Tz)ivc^2pbV5W<0KWLbauHzI}-t#d2Xd+Gh2mw_LXd6>cy2$4B&3=1m@!6K!6=l2j` z5R0X=^9=!Zb_aVCryFcveM9zd=N~)d%mU!p79-?5mx`ez_80YaGrW2FA{@J6*lE)*mA?Cj&!*!nPN& zr98NG*Sz?kFLydf@sWZ^dfrZjqUB# z5EK7?cPUXm&OYnqh}JZ%tL zh3nCbo-bua!i7Y~WW~DV0l4?x+AqG@V0&P+>CP1zW8I$8o|epV6|mHClzg?I+?%&A z)NzLN1@fKPro{yw49PbPm9I5!o9BgAe#!=X4bbyBec9$Pq+1q#$(C%GhI z_O=CMesEd7+NR3z^@wF7{MO)|l{z-TR3ZF+{&?=~sn(*sG670q)gYWC zU9-jl4PpeP{J|Sx^~X_zX1k~u)u$$zP~^?2GH^s^zz^C;%Cw${wY54uSriHjP%5ulb-!=Hbj3D z=~0)JR$_&4enWb=z9v0fSN=KDb1$k&V&T17p-ioc;K_zt4WF8`h$()-tqx7NoI4=K z+Ik%;wumOnJRHT=dgl?TB3)N^`NRlc%p8uFythZkuo2pHz+tS!cdY^$2(0yMg33thZjs#EGoZMQWQ8tB2k zlMR#-QJ0g|$B;N7I|-F{V?qQK+m{@!3N0HUKEjY{ydxo|D-Jsxm}db9lL^#t((ooo zZCrmc`SH!bgH}m0ev}kd!m8FMC~XAc%YqKjB{vJdvVF z37*<(w(Q51&b!k`7MeqI^U3SDo#&z&?qC-ZT0f20+^c%&WKiBHDe5sT>MHx5TcIdM zI=Qhz0kN)e8*+nMw4H}pTEQf!49NG=)xEp6b00p%X|Wu?etDCfQ(n9nXgH6$csH(O zRiht+6fU&dV0WM<*HhT}!*I-02^VT!&c=2O?KqA@iuJ`>k`&vX;MMy(nM(aT(gCHc zTkKC8T(T;Zblx_BKE^68xVJxF4j+gNu!xqSg7<>P#xm=SRQkWy>1nX?WH_@x8WZ1L zpusvm4)w|$;S`mX?c<$s^7P^b*1K2tV=&0oIZNIL1uJLM9y;;Ab*d?*OiKved{VZK z?NIARvZ#}dp311faPmx3(lgWdzK=k(e@##dqKK~h0g)olA`(x3{oykxnk)3;enLv#D#u~zbRwMahXP?L zB#&ru2!dM4j>n}34X*li>9dY0F1Gq39~ur&5F5r;KOVy~iQ^tjHcwz)D^PxXO>#|$ zij-R`-8vCArIvTZJMQ|Y{r*_D!koogFjcz^?#G+f8SI{*c93&i? zIP_Op&n9bYEPFX#@Jhxbmt`>PW`Q3+C2We*6*l$ilkHhwi+#j>Y|VvmZTzo=tN|_%P_$#&fJ$?PK!1rkFuax=ULV7-@pi4S`B0Ws|=O;a1r=SDl zfkiH3Q=Q2N_Vc-#Xp%!A;5i(0Z^}9>DJ~ z;H7?|>wQR1ot_}ju594}s#7NtRO3JD^!ij;#or$}nZdH5*6@#iSuh6Ff zVT!(0bOE%RH%4ptG&G2Dx{pLZCNM2-D|A!Td-1Om99)y^wU&URI95bTa4&;2nCnOZ(3bpxfkz zjb`v|Fyx?bL{fj;>+g$9SunrUN`B-QP4?Qa&#RdF8j|oi18RaXpgIW883UpNvqM{Hawr#-N1;8#3IAv}@pveT9N|C|SXo-n`7gV6sx4?45J`B~)WG5$Oc z`YibSJV;@}KQfJ}bL49t1coKzeFxqA(A-3S8Ujf<%g~HT(Hn&b ze2ZkQ2gnmw6tYogvIrNSnO@@D)J$lL97D+7T6#MYz)!*8+tVjHvJzFRp!`@?+CcXd zTe7OBPM}-w3J9yznYn_=RABIlZKwb!0se@(?_ecnp7E`^osm9GEqz<`=@2!8%^v@b zsbrjubaL=}QR5zA` z`o}U}?5%fm#xrksPe`JK-W2n=a8i_RpeHw<}HnQFYrlu1scPSX^W@pE`508_aWXPguy&!FrrU2 zn(9TRmsD~baN66gY`?_lxsADV*O2XSj&#kG1Hu-2wB4JxhOw~_(ZvV>?x#3%KTg79!=~e%aG4gQURBCcV!Pimy_-$)*J>b&g^OE~t z=zACh^yjkzf- z(aYx6SJ(RS!w5+2!pCVYe-6i!j*_=_~ zHsTKg-f)N3XpW8Nv`yEFUly2b?simI?x~ua4^AI{jSqj`W&IV1@;99P|5juTbY_7+k1FSg@_8Enc|`dv`1^<=E77;x zJUD6aD@6I#$v>12melu~C;y{u3;NPQK{m}A{o6H(B;p1)NuO2D>P#x^K*%rY8+A#W zC{Hw$hu{x`yNZ!ZUo}S3LEeddR)N6j?k{AUnGW?ITSjkMxXsBSjtfME`BySdJxV zrjvm7q32a9z2SF;bI~Y4i6q2`H+F{ahbxAvBn{1&IH0jKJY%{sLBjcAtux-?siv5+ z>ea;$p~u-AtSQ+dIT;6=3$>YE5|y1PDDNk)kxy-unM>`JMdVxaAMx5eT$S&6CMu5G z?dI-X7ugr^f%DN=t)UB)%FxhsP+D4Ez)j;w$mGp(kbE4$kp~hzEmdZofu0uP<$MkP z$uLx_%=+@(a#=wgujZT{J?{9-XCANbmUIfK1_r)OGUexXAww*9{PEb4SB^ zYXJJI-b2rAs;<3oYxE^GbJ%Ca?PWhIBiD>d6ulgvTPg=tH!xrbCFJwg%PlrDYbO-z z&3%`xOqsgv5Ol+{7|QaIa4!wif+bbsa#vaJ6Ne1LNBb8vHVK{-D02guL2{~SJy zEGzcSql68lOh*`9l(vcmFdE0jY((|K&!+Jl<37Jt$ha6_h!RXz|1p&?Q71lQnV4qa z@hUwVju?i;w)b}WI*AX$))2^txFbc%i`z8Bey|W}E>EtvXK~h{wRtFd+wHPlBvbuI zEw4DOh`d+iyS}d;S}2`)r*JtF&l_4YL__K+UDhkpk2@~6UT-23bs=;+y5%~w>wXn? zyxf1w@jfHU&WU|p!^)+E*^S-Yfu1xD!70Y6f$M9Flr;|$>a$-@eb8xMu$ZEbA1g1P z)?^uNLyf$Wyl9upH2{Ad?anlj;`n7x>UOLJAJc+CyFIpA0<9yhh zA~~;)3*!eREiUV{wNTZaXG(oYk!5d#J6q#UM|D7(*RgP$NZ23L7M24D{?bYhhR7-T!$ zDv*0FT{)=zB5tT_hg-@OIX``Tjd^g=YYiJ(sG65zKTq`_2~*`Rk{MXS8X&8Z7?Wjf z%523)OIKCMsj3StOBV)fLdPoM`R-$M%I!^B8hdpafwM!sdFzBtHd39~FxXz#j9o-e zx-E9aQaHLZ2krP?QY_8XjLO1;*K0wwkbb&2pOpsqHL*^Ga=Lt^QQW@Cv1n2`wA34% zhfy@!9Tzi&Z3n%}g zCiCH&(w)y_>?>NbN2PL}fc;mD^=-mvZL{p&KiL!yL`8+d2LcvK?;|oh`!~#xl&6TI$0TI6p zG0A?FfBO$*7Q--s6GkC8xgqBeaen*HK}3er-W#;=@Q_6D7=Q0gOi7u%PTF=2R8vR` zi8A*SxW&o`j!n{*%}Iy}ng^<-qz8zhl@op+9*xaNR8!!#i80?TX^TM3bGHf>tR~9M z1U+=1P0XoL@XC^_q zyFDywyjlVcm+M2c-`!&z#6m5)<6glP_VL0}%a(ETQplKUaL`M`r7VJM4PUKixSY1` zO<+kEP?l%4o;iwkq|bd3S4J&Sy}nACX8m)B_$kEngF^hjkUXqltVzC!F~RXGi1?O5 zK)88+FM0SS_`?>|#DiDF03~ggY}8d?QIeLT%Z4Kh%BldOA(Hg2YO)>`E}11|lb^Gf zC6s@kNqDgzaepw732(133H6fSlx3`(`25YbnS$%P@f(JFB??>Q+JPB#CTI_$8)NR? zW8(Sf5xnxA_=G&9aNcxVgl^K5nNdf!)I@NCRWZMa56vzKGV)x}DsTSu&_X-4ajXaWmmQbdhYh71(KpBH0X%EKiP^3Jsr->6iUWSUM0WIqzx8g8bxkr^nsrozng%z zfI7FQru-fFFbty*4WB85^t*qCLa3-Ii+?$SfN*>&H{pexg_t;aV7DBw>XWnEe-0lS z4fB%mnadDc?t1~st?BdvD3R=G(m;Z*+&_j74)s4=qHWl#<+{ZFG{g^Aj_<9WREn$a zQc@00knK&`#^U|BcNQ^`wM~hMh*Kyb8Uu2rMr_0SSywA%Ag)J}HVCpJSYO8f*1D2ViHx5pvv%{rRcLaQ4KKYN8 z7l&TY`4B`Eg_>ded#LQZbP}$V_grbLwT9;x5WGBBhs^Q#5id5o7dpK@F>p@+(ydcb zN-i+iccmqR%GlqEXYxX5&=!$DH#~>wPM$`hy%3(#{xTsMw^#(GyaD~pht!WK4Rg1} z&+(xGMj=WdB0n8L@I!dN96|hcoycz1+vU15?QHntr>#*9b{6g{R9U%$fDDSISt=MSnXYb-t^^s63r*TE1_9w zlYrccpPXdHyVHxCs>~{AZqUi^!WH~PI#zzt;lT;6@q*+ov#IFzYYbO{OZzbZBOnuM z*`R03iJ$IFcJ7TBje(qWrnm9DiyN+0&kc;`tc82=x%6pY4p@!`PntQ;#$OkwSnTbI z2pBO+>RcELQx%#b2|36>gz60V81Yh&TOr*`pY^v84?5gF$ns0qkr7w;01fmU+9J!4n1DUUict2>6^lvP`N!|&9#Dny;`*5 zBg!ei=iw!)$O2Uv*vIx%rc&)d4ix`|w-awgb#J}662?YBDSjV#@Z46o>%FSvdp`Bs zG{Qnx=O1`y?SO$vb9e7DyD6uHlCr9W`js|^f!?SHDXtRBO9~CcSlXXHmkxx1g6(He z5c`KngPO9k#yKc(!44W=C5dORGt$8Si`%~`FZg_Pe-Py_G4NB3A_yH;qXC_V}l7_Ld*{{e2xat5vaTV174ulBo;9HKn$VNi1yUkmy;@EE zq?KF~jZl>}mhL5#a-KE5$1SJry_4}<99g7!EcjNbJ!&U^5UPSx~9aoCo@mm5s(>;?59H5scI=6}3wBInX^GpBJZY=Kqs z&3(0O7v%ttM4=F<-m~K{3}GQl);9k+o0B@(nM7WjtwO&G+m>8~Nm4T@@)Dy1Qq#95 zua;(iP}&n5AJL9-+Pgw?rzeACyeMmBjbJ4yeE_}Joi!wm5v#TQ&9w{bS#pQL!hLZ< zB@dv+<`+NYwk=|Ltpa?WRxFF8T#^E|@0cW0t5s)|yiDUtRkV=D=Bo!%p|;Ji6S5ND z+Ih0ppLJs&F<-F%q%rDry!S6*w`3UVLI1vto?bKNA&_TNBcw zu(FY}^HOkgWlGds*npzG`DoE_qIupjXjEDAG=gKf)R*jjp-(pYlJ$Yntn`(K#v*EM z&Fn$UDwm56SxzIu4K}p$NdM>IR{hsTLTZdOYqw@oN{ z3<6?jsY6sDn4iM>XH|dj5IES|FDe72b&;Rhg1wJ^D}NYxcEW*r)(7TU*&q<%my_?j zEHJY}(u;g|Nv-Uq6^~_vV*`9lWE?AsR>#I51 zuzI(*5?7dF(-RztdbII7>pjZgZg4kTw?fdWm!@Y%O(G~dbh|^&kA%XSQcgKbWe`Jl zU-Cu!RwR*riqYY;O3bzl0mXDq=4!>ov{FLR4H?ximjY8-RiS4!V~gS+U0A^`&xge7 z1K%?diQ)IVcAAXH3%;$;WLV#OnhlZGu1?O+)G%00N`FLR*BS%B2F~dFk+7ItEh5=k zNXSgyv?&_&e?TO;UuPSYa|n(%f4jUuxur$XTOyR}7Fn(y{IV3CY;EEAbQO(G|E zvXW~PTe_GS!{X2?vxeA3HVN*7u0R4aIYRh-hel3Z-loh>r_h3jj1CNK?$xh?ir(K5 zGTb;4s7$|3$F(DQo8a>3_)%2R7*RDdG)PeTXyUNO!0+(VG2mLLJCVQ;+yYco5>P(5)Q3%3|{)#x>@Q$R?Vy8!Yt} zUKeWqyc0*Th4_Ot&z(5^Hxuh`cB5xC<=;4Q4%jbSocr{@Y4r1>>)&(Y?*>n|bonLt zLa_u_r#{BnPCrGv(DKOVf+o_s!G%n6?_;qy_1Zp@QXai?qDZ8pXeh{IGUhKu64yzT z;3L!rcPQZ9Pt#6e?v$ZpJ&9G+N- zNNMdn*Wx=7V@Wwq8{D%fP$%?X?#>j8=iXTKvAS`zU34os=5kpK;L?7Wij)M@{Q1b` zwFw)eh({B>UY3zr6m14f%fpO*g(aIop`LjtO2~+pGCexM#5w~MJRrH|%hPl~(h5%H zRZ$edp{ZR3yj0IDX4B_Sc2!$OQu0Jv!icPJ0$#%@pdJwcEb4821yTjn0=LGqX*MF> z)|iX)COds-_Mdb)Dt$%#W){n9VB$%th${}5UyQDB_f)PeTkB~b_k6$uoVF{(S?X<1 zu%5#CzV~??-uAB9f3KqJ=~^wB6cfjYT~xRu-2oo*Wb7!_gsLf0gSnX7TtDJ);vKWo zyoMSYhSgiA9+uKN@H`VaQO*mUw++#gp%=!Zl#NfJ4)!_7O4y{hfljL!6!5FQs#RUb zyL6JRQQD`sE=nd9v5RerIA^O)Z785MCDV?G^pJa4;$MRA7$($CoLG*&?%TGgU}zbx zia02Yd?Dy6r5MGT1xW1FW%dF%8#-?nL?UO}C!X}B24>X}jF1uU;XA-+_$Mds59Egt z9_Vj5@-GM97tb6uC71$220=go!!7}^l&i0c)jv7(U)IZiK>?m~A_c3LXM!+5E}q}R z>g6x|`+E7W(cwGG;6Lwf{yd}kEcovj&DXzE@u`Mgx%-U~n-+X(#+e0#jU6Mq35|nw z?xK@Cws42$cCa>`@**0iMU1~Qut8v=^%ZguAgo0RE|#8jJ%-inLY$j7f-;QPT<)BxA)Iz{!1>M8e*=P+vxfkbCkZu1SNPkJBfd) zLOCQzX+JH<2f`9qxTBf@e9XYztUN_um~GGJ(Crmr!6TOBR1h#!kmXV_Ueqy)KfJ%J zndxCJ6&>&zNW358Sl^DaeSj0&SwxBT(PsuFZ675*;BG$GYr?m}IJiyix9sn;tORb8 zI5{4Mj~DM1G$~WKy%0=AFsIecj?VO+2EPYBCv3lO+JlE#j)l^CouB#Elh;ZqgsVmm z5jx24=qHG2ZZO;#l#Bs*0hH#2$4-L_?}SXg#OpAE&op?h$tq|Pf6G~=LBDRuoGTyLIUB z1HTY4@yB%C;t>VdyU#3nm$BJ&3h0g*FkgfXTWm$gW0eMW-!1~JO?bg z{|kV1o{Rf?fb}|I;Jta>vlm(xL^{`u{NwA$k!M4)`PUO18|9K#!iJO+>sCIpJM^hZ zX#?{#uHSyt=etF)dgBO93=btujn~PcokX2|zb}3O&kYYL=6T2KLjirF+td{Xk4q(Q zUD{@NbGBHYR>e-Vs&%2J8cw{lpzd`O^$u~J;*40;^g?58zw>Y=A%wm!NjJX{4$1b3 zir%KHY43FX1HUn)^u8<>T33ES2uSK1)jMp~wm=qqn_AZx!_lpKXIt zQeH=#{XLPQ{p8I-@k<88k6vW0V-wylbDS0z!m=(`y0&GZVdCdA+3#9*)DuN9$&vAF zKSJU@$58r1$tQM3Ci3ceq*At0RN;{kqjqGuG-@*B9rOFqb~ig`^_6yM-ucZxzKN{z zp|L8Sm%TD(_${OQXzlY$qa0N{*-$m2aI=bW(j_;k<~~s~V+yDrQ#txJmw<_%TXM%( zJ>s5#VXcU3OX#blPA#$}Jwrj!jz>{;%fmpEpP;^)Gl$h@s8bNwKoa8<{BX1vl$i~18@SoZ@r1fpOQz(AtoQ6&#-&QY zbQlXil;PQ?)Zcbh^A;yyjD_#H=(9H5>v<~fWCK@Aox*&XjO;%ID%qib9;jf!u`g5# z79RTtnALgN{O7vl61di9Dz`JcpL#cy@4FpVC99b z)781m*XHr;W!8>9OXB&lXo)wu@A*p$)VQQOj&D4o71!WsokDoGP$gQX^w6@f;mzHr zLNb{QuHdspN-9I|wjLhon#3X0jf~!)g9!+T>8G}y-_Lz)X+LjvSq1-A1218EePskz zcJXAhj`N0UbYNiUL;bI|J}sAdAx2N+FmC* zNi@MC_0|cKkP@-n^$^`nIHLvh2Ya2mRGs-x5tdFH4b)n33Z zxxEtjc1?QI{k0N;+KcKG=I3-8l(*jRLv90&yiXI)EYQ`*P8<_hwXj-2(rD}zCFQ7S zKFt}$hJ1C-n=SAuIeqLO1gbB^`agi`^AC&t3r59!zd_+vcRFhbrEK5c>9Ho!nFUD5 za#}VDs?u1ov+UZ)kTWc889wWoSZbj` z(Z89K@aGe4|%!24z`CF>6y)rqGBE5)=s@_37{$T}q zWdYjT@QKl#XgbU+&=5@%H>1i+xyp6Q-jyj>q-)Ab3WM@Qjb?9l4z@-wwJvMRzjA6d zlNG=)p!7puUTp{%BpVz)n#q$*h`v#DGIiVP^K|r>dPpEV z9Z;PIQpUF)yc%4~%Z&9Jy`D~R-$bN`57tv5<pkAm9+sxpzx$#1M@6-%RWkD;rASKb{TaP*63*pxwM^XpOaOtrM=paXxN|KCr)DU zzE+v^!5Bnz%_xwQ8zs^7iDiT58BoPMtsp`as2^qQDmJ90<{!a^WsZ7dZdH|sqp>}I zb#st}i;jKR!gyaI(&IWWYtK_$$!)&$fR=r6-Zid*4CFoZE={Dhry_$mc+1nA*N zc_5>UCq+_I7C~BXpWEg~-LrRQdu@gi-Le!pvRcIPUlSnw literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/830e1bf4c7f0c539e9686bc1517d6f87907d4bf8 b/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/830e1bf4c7f0c539e9686bc1517d6f87907d4bf8 new file mode 100644 index 0000000000000000000000000000000000000000..68688cbfa89db53119559f2f98b5ae7ff711455e GIT binary patch literal 10960 zcmeI22UL?;yYCYMp@V{gbfk&|l0ax8Z2+Z%AiV}i=pY0O3Mf&5NC%N#q$vnUFG`6t zL8?dxL6IU=0qG?-amE>E)}8O3d)7MNJ?qTPf~>rIKl^>({PuqS|NTC|4v?RE1PCfU zQs=pQ2h$bPxtj?9fT#d~V*o!gfGhUTza9V@Kp>MoEhz>`#{l>q2L#wc$&>-n0G8kT z{@hLjFyiE3K{~ zap4yPTvAd-O6<3Per@qyWHZz*N5; zf`OS>Ff|Mdrhs9|S296lKr&(gDg3t+0cnZhK5$wXH5g<}4rV4ZHiGlOxJU;y%q*8t z7++phl#j0q+Qk9si^A|qz~C_WF&G0WfR>r^*8mkb3?@!$0Wk}IZ!t7dAx0u(#q3>( z<5hUkUOv3vI}9{Ucu5R?@c5^)ATc1ZCGk*2`Z!`>+^qCOvM}P0tRxHuvtXqsPW>N; zFw~#t=oF0Q*EwSR&h?_#HI$F12g=hI{#y?%^RGQ>s4GYx-|szqFy3D$iS75fQ1$Zk zB@W^>a&huR`S41?ut2__R|j!1fv`YE0I{8h3=0GTCabU2pDdZt#26I?K7Vu{ZUjIM z-mc2V=~Lm2>bKCMbUs+Ikryo;1CER6n|yU z>hc>B1IsWAd8uq}EsJ|!&t(>#2tGrrMI%TXATPDh6rWPGR=MqNy-VPHl->uN7Izm8S~GLq{b2u@2CA;nmbBD z-%Tnc)=;4;2kk^>jiNGES{GzG$j5Lw%Q3wF|NeoDn0aaBYr5Q#OgSm=wyzE6xAX5IQs)%2a zaexKY{dBgV=kAWk|D8}ecq))iB`5(SjwZhUNI>F8Rnjpr35oB&g%GbzY9}o{h}YF0 z165TZUcZ0-DeZ}&q{N3fC>R?lIefp>-xNXK-o+E?;|Fo@@xow!QVIj4i_dR;urt5k zJusN_2Md&gJJMc8+|vO=V&ML}-ot`sh>MhqhdgKk7BmVA8p;fMml@O-4EZteFZMwE zBHsc2LCnF&Jvb=i|23pP=ozA}c@f3a#miHN=xINokR+Cift-c>MCWd`Er~%o$L*f= zy_&X$XH49kqO$HV9#RNDIWeK{oQP_O)KIIK+AE8W@$Ckgz9xLGr-QMQ0(i-Zatxyb z)BLLVL_eT{F_St3$?1MF0?O~2&BX`=63EFxWR!P)PIICO5Yrq8cxXXi{Eb4Ra%t94 z=+cXe64zgAi|~G$ejG`6gH|cj=$TJeuE_c`2Xn{%i8)vLl?Jnyrnt(?F3nwso?r^q zK)y#lOUEWZsh*?BNOiVo4q?kSJnNNm>2p}+5j>jTi6M>p1^_!&GY%=e%j)&wv0PkK z5+7zTLRkux`hk*##DL8e9S=qZItd(xfJwsTq+}6r3mEi| zUUE1eIqy-~D;06hnTBl->8h*OZUyyAmJRIGm&OBfF5uS7uvcN2-?tAGaHoHl^ZdRi zAu#}w_9f(4AmEot_7^-klV4q_SD?76<)VFKwYvnLg=i^S;7sN+I5cp^VioUgPk!E= z7H<$xdnf0-UAl9?$8j&WyKd^ZDv|8o(65R!x=(3>Acgp^{c1C1S#h{H^K^Z?@TBmM zbmK3@a8DU_@!A~c246qhMpQ>g35%Ga?&UR+jcibDEKKXYT6iU#Q*U_K6wAwl7Vy|` zE@=;)m!B{a#4-1_rm5fJN!RXHY~e7~F)CP!GW*(0_NZ4K?5xtP`u;P3YJHJl`0*t< zUf}~{q7=O`)U+OnGV^Wjq1Uxv&frzKi05n#Hq#?xE$!CEi#1K}QOb?&)-5kN4I*jj z0kb2^7y05I`|y!=u*8Q0ECtsUEX4^D9-c7bqr>-?q_cgBQ(wzi)tw|<3=W5@?7x!` zVf3s!dqp0~&o3i-S0(0jHBguXbA~nrX5?J*xGo41+AIiRiM6oG`jBdIIX3B0QmR?3 zMWLOeowMB;J3OT!UaX7Z(g$Z}yG%+ZB#Q}U7&(PJnQ^k&XCV|e=VbqS*aX>S_A<9W4GhfgKB89Z1NBCgQTl$}>|HS-C%EVHwDbMbh`n#U62 z`4l*HK|8kNpwpprGG=XX1u1B4zd@Ta&Gcnt=%=9Kj`m(nO)_!B?uouuxib(j5W9ak5I65QwKi#-xOufD)W-$ ztW}|4z>xfz=eun0VwbEeS8BHFb^|sc9K%%u;~~O|sa)Q>E{5;?N)Jkzw7ckQy2t>XHlVT$@UW7cRecxY(Y^FUvoTkL?WV zob|lA`{3+Jy_oT-4?WYnJL@C{u_@20X_rql)`h9;_1`~Pjn0*TOG?1RJ?*Oy&i2w$ z(UieCg%Y$d8g{k4?M=TL_gaG6yL&i6r=;d6!tK%o%G7AbU9%Q5HIsVlf$9$Pjmb|= zJZPEMT{DIna*FRV*QhmY(sS1$RX*w7ZF8e#heDm}`tsr~85-KmE&j&EEj1%9HdNQoCtXaVwjc&*0E)hstHJw@t%WjA zi!+w}Y9@@D z6J#+aV~(Qb2$AOC7ZsJ~Co$mHX3l0aXlciD38C==XkGm4o=D#DFom!%Z6l*!){g@X z?9$!)YA8E$+BQL4?2#IVeaHGV#os{1FEBA`bV0E9Bf%4!;T{qtS2T2cG<76~JGI4o zf^Gq=7Teb)C61hsNVL5d%z$Fe*nEc0(e46FveX-B4hh$tdTnk{>;{JQX}PyDy@MrhH=m!FGN1iiYPF;4E4L&het%ipR#MJfxw#msKABr$l6Phu;;9lF@gVLTh)n7DMpLxHk$?5|h^)dln-#IoL!kPf zCuXeSnd}g&hD#4LHEeNTrKeV$OqVhw51ejF^R|jh9^yXJw@t76 zJr*uv<;I=A4uMH!Ay4xIwpvU=9+VGCg;_GbNNHo!-`JxD;CQL9SzrLb8wmViB;@!j zSn_HTv_FZbB+S`9-VEQ>(%#b2V&Q@BY|9^D1AKXo{JT9z0+tU>`stA6U>KXRaU+us#qDM*Hlp zIu^?nbXFJQ8z-UCPvf$yPGg4y^uj3STe2S7gXFwzGBv@0XVkC8 z-3vO^qI+P6nb_zw3|sdx+R(C-m@r^V7{In%_Uarmwq?8R;vi8bB;hTGT*Unpn?uV`)#!j3_wT{jm@J!JBM63A?#7iVP|lqVEkKD~@juD(G^R@7bJ5E39IMlP zp<9lX$u=*TON_+uh7D))7G_6BpF>mEZx$r4FAP5dWyoYCmAkKGPzt$BMK#pLuYJ3q zqtfwY^+8LYr1|r$+tm%92u)QVj>=s(Z{+7|Pk$=7?}PTAd8&C>f_&Fm6-{E$1bt<> zr9aYCTQnJBJ|=Yzzahaa$q)K8EtK~TtgG{yekSO&$g?i8a4b0HC?J4a+;WvLhCteP zn9qIvM6g|+1qut8E3&{@VkVd4(I!p_^);VQWF|RUJ`w4u)EfE!M)Jc*Ee6RjBS_gj=%2m%%qJy=6Ffcz~wU8i|1-kw)9SVT}~fnNzBit@b-Z!+CcGo zX|Gdydtyt%#u|Wjsv$&07#jaleI$n*%u{&gm`is<4(U?%g*N zbvo*Ah!@B{nllK9?Zb^;hfEERr|8oRdDn?PFF9Ix?>F3ACEJxuQ0}%**^V;>o0_di zPlejZI%PS$8IT$r>aS%4#!%93BL1TDjYOTV`akHr!~b-huWBg&`kT&w=kYIe{(m%! zA39IsArrxxZ;34)8csj(-*awhC>Ki(KiHkG2K&_SC`B!lz8Z|O6wSW6d*AeF!9&hQ z6in5v`;ggmg)v9HqS%0D0k%`=-CrKYZfR>)mv-Yx-E#b`&r7&>=#@bCK-J#c4x^8C z>_$og=$+qKmfEUn7|kBdh!*lm?LQJd?>4&|Ah*=rG4Nrf+bOX3a^(E&n>7t1b8p=@ zznXTA2&c&eVBU;gvKE&TFy1QY(G*)D$v$l`35!wjeeKCrUfA*oybAI z`Np*P9qal&`8oaPFDBEn8rE$}dz#bme=7Gas;zUUdd}kt5 z=S$pfmajrkgmW&9V*go{H)5pF0i~ZHm<7BL#$;0s$Ja-M(6eXUnVB_b|8fd3iEyr~ z%3NE=w$XZ=V-pmlFxlH{txc-Uzi`tpsa5di!Y*nLKLC0l8DO_gmMiXbv3@2iwW@7b zP6RjdPiRkI;e1&17-faX-OILAm95}4be9Cmjq#JH6`B8v#;2`!6q3mDP`w*VG`S1O<4G11RP?z!A5ibzH5K`W}A_6`-I8rp;s>Oxp{r z-D&CKGyCj}x9%Mg0?~#H%%rvmVCw5;ra5a^@wt%@CH_yhSy<3QCKMp=W41vQW}Iwa zOS}au{9t)xVY29JAnWLRykW^fTG>o}0fIL>zFK)YPe-RDCS@mB#3Wiq#}y=`W`vn= zO59zSlTT^6w>3sKd#e*_%W~X!rao6pw!=Va7NzX7J>@=iXf=iP$_VtGGt$$c4@^ zJEvk7&yWg3**mYmwf~XAP~RAyN#M;{_ZfS%tDQ5_73t!#u)Ihn5ae0q>y1EQd`o>1 z6~59E)xH%lIJ}g^fLIs$&f}lTg2dnl55O}?_%%tX?}aplzZTL2o9UERBQl0$=7rV{ zN@lu6!zRr(KUReoW#0Rc7N*4G?aj?_<=p11?Ct2R?#PpjY3rf^a=8p<$>|oi2{9RM z`h$8=cNJfs*e1_;D$ZcGzP}A@{W@B7f0Ub|@(C;Yl*4uBsQg&EE1=mY8}Lsl7DUqu+bGk)imw z9>K)69&>ZP-`2Fc%OSK^79wcFm4S>ctXnoNL-tj;zSp01k{fj6Vm|Ack%78hyb!c% zNn(K0FE@_rvA!&jrvP7_inusTHeBriS&l5O71?O?NS-odd_A3 z5PJyUXe*d0AY|1m1Eck6VWUKt_IcQ5y0o)DS!{xnOPxdC4Pp^#4BOU8tQ}P>I6i!M z!fauQbsjyJ$G$L&VoCU%JD;!sGGaZGwHegG_;4?kYcn>?XN-M*K1aabC_UAQ*09*s z5ikG{K#H)m`-0bk@>w)~i3fCpad-QR^#Vn7vdgpe6jLJ}>f`g+*gp%52ZP6jzt@EX zu!f!MLB8m~bjH4uLz+o`IQ4jZ%crKc$K7r1Z{GB@xA(U=gHOOEu7u#&V3p>~UrWpR z+qdj{r>FY|9!C4C0Zt?eb0Ah#B=Wrvl|zF0V^1K+ePhGc!@^=(KunThc8{}x*A*O6 z=pdYiaTun!uFdt>Fw6%VK!R4;L3lX9+$=F^gabc|Ej%0A>ws@$^(lAn~=&f|0RVIT>kVg7AK4 z@VnxM?&pQ(;`QDxeN%D4+5y51PbW((hBy13sRYfC-r8Cin%{U#39`z*)8JWhY0sm5!#)S-ry_;+4g$fMwGgiW-+!hrt z`A{A2ua@PbZeI`hsOVb1vM4QL zUp!o{m4RxQ^aR8t01P_v$7I613&jn3H z!>A>}`IAWgss1zO{Ig-i|9k2`AZ-vc$U#-xND|b1#@j}fU!Yh;q##9ru7%fgnlj~6 zy6q#2hY2akretv+gWuHTun4fk-$AL--Q$&*uw#4uZJ=&OOO*{I5^8k+bR^{qA$}!c z!AgzOO_E)ixJ%S>zNgID5>rm?vfY`s($NhMr~57x#QM*79{*Gpq;>Fvhq$Blic^$W z5{E-~&lKe7Ey~imQ!kf~zoA*HEpoyGf`6=&NE4}@+R?sW;$@A*UfdA?+1 zo=N?1{6zFi%oC;gd%Z<3hAdZEL_XhYGoBi}tkk`Hc!)g8v06zF9!!%==B~d~=ufCl zzO)mwkr5)vn!+_0J=Yh<@U{Gz^+JQ4r|Y+I$V=YGjbO$v^-Mc0i&C2fYKrp^b6d&R zb1aYVS~6!0my9Gd#x0K4OI=rC*w?Ny&QdxTYw0<>*Kk~W!tdkO-00*!&&1Ak=?jKq zGapl_cqqh;%QHphXl)&#`_IlVWjZ((>2$Al5nR`ARwiXUAu$j-)nM`_FI4ks}Phv08$n9F{hb zC9Iq_*U#XTV`2Y9Fcn@tQmlM9%d`TIsMecdcP}`P-?>$(tR*+a+{`bY+qlJ5Me{LH z>B}HnqiVWj^#p-`bLJ>=RK`a-J#a`NJ8#oxTK(zK;P3t$kqqE~|6d|LIBfs` literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/9ad3fc3cb11967be927bad9263d326783c450e37 b/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/9ad3fc3cb11967be927bad9263d326783c450e37 new file mode 100644 index 0000000000000000000000000000000000000000..f9c6c87f6483b0e523775c623ef65565d4551f1a GIT binary patch literal 3641 zcmbVO2RK~m8a^|_WTQlj?j}lf!)U{-Hey4FE{JH+Wus)UN{|qdCu#^LWYi#5i_uNg z=w8cDjK31$x{gueHe~f)%YTIttK>6q$i=%gkkLom~uRljP=YzYxgvJ2zJ#i|l zRGuEHp6D0%F;I``8Yl)T09A)xqv!9r;Y=~h!NHEb`sAuQ`)Q*lZwd*S(O&(Rs8iD{ zYcYM?DkI!V)@|H+rb=p%^uoEhRtyU?YCRSb9Geh~FMj+oy*MtnIM(L9ZIiXb<8w(0 zKK4W7xY}x_x4Z^l*336sTb@Wz<%Na$>AV8tipMQiT zw>;rCy}v_+Y*euAQvQ*+BIYx!GKrfr_ieuZB_RK4i<0HT?MImpvs`A)h%&t&v$E}&Y=qyjBakIstW5LNe}BEM4kDK$;^S}8cyax0S)N` z12<{PSYXz`W25MN3cG;dEt+H$)vQ@TaIi~VgI6#bYoo5I8Jtje+ruE*%E~d!O3M-b z)XL2<`u44#PwErSu&Ly!L(|#7hB5NfkffKr?OSP~p-Ev&fIO8w^OY@HU)rkI@=Rlj zY(`0JcqFa8>U4mZ?J;jL-mz^98=_M}pj_QjpVjN^mYeflgA^e@B2Kv?u067KvbPtO z5`yDG)@T#QB3G;O5h=?m{!F z9R)l~h--DSW>iadv=+Ts4cEZ`b@nw{q6qvdZ*l)sXiY z1mPj|sfg%ZBu7QN%vNOCjLJIY9*rQyt>-JIDyF#|aGv|+;sw*fM&q}7u_tunx!zh7 zi+J3~$2?mOxh(r|3dUi9Kgf4gkNwDo);mW7xRlR(yoEkp)y<74|$hY z0!3CU1rj+QNBQLy!`Vc(-O?gW;)e)EbP=k4JR!8=-r;W_b#aW}T> z)fQ4$cRm+-n_Q^$t*qHdt9)1ZYf)k3WHD9=mOHXw((3nvXCNA_lvsUz8I2KSV3`t` zd?Q6HG#%`eB^j5HZ`^P0o zUBuRv)x}Ot0Y`OcYl}{#Ak7oDhivVTK;C=;m<9uly=26%!}@EEvfnZ(fN3V~ZA-*( z;k5KBSUAQBjkqa;v%Xf{@S%UT65q#+?u`jZ5Isl0)NoV13DQaOc?BV8oF zF&{)<5hQ$58+84m#ab|7+R1*Wx3Q7X>*M9xbJ>*(UgHciTa^Ekrn4RrnP9xx(HYjh$S1i_hk839Emmx_{ z;w)5*PCH8WI{SYtjUbYyU8&P9pAe6oisMRPVwEypLQD-Hr(ftv`P5pIR#r0Gz=fjs z)V8Apm#3V{F1Y>tF?*9KDOz_j?{VFyK67Ir$i>se-%d`}*4BpX9 zQXa>~CM3M%?uZ!=ii<+Vhw3B>%Z%zbqG+1mG0xEqQ4bs4?3K6#>+I6$7L}Zpd<*Wl zNiAJHTg|-&u2G_Opv_WMbhKe$y~9c=(M#_{X=<&Zcb3vg!&2=M1c|nST!Jt`_#p5H zjPtTGU=P};NFA6CER!ZY_Z{?KEd}piv=kwCziBDnCEn|Zjwg{`J7l}C$S%zB?`z3> zxz?#~M%9m*r%J1c)E@t26TapSUyNh($4_PVu%fSAMVps-Xg)LCE0|-xvte%a+eDra z%=e9c@BDj#xwHJk?g(YVVu6zLt8*1Rqb`m2J9m|>m(KLin&B%*qB9y@eVl0{RlRu< z73B&zabl@=qmwscyxIBKRLY?`kqOXGsI+#GQXnK-b#~yg<{;%lu3johd8&EqobTGx zU-GwTY7Ux;WLhrTkF2BOIJZ)QkgzarU_?*6v%jlLtp8GnnC`2tZbHAF9t;%z8e*q8 z)DE21Ls4-Vp*R>#1Gr1K*xC0>ad7Ekk)X`;Cc&XoK_fxfDCvyukYnDG31P9=K@`im zo;KcA-cRZ?DR_awdu#@qWkEhg)gu!wdQLLVE_O40j*w??Z*_HyNC*`~j%_L^x0~wW zdbsr9`YK+J&h3;Pmhn~c&g?X}wq{xpQu}na#P&2F&+=(|25I{1r#oT7u+B>`42_lpIt#5?0x?|kUU z&V6%bjl1@G$B8;-Z7IRDG2*VTugY)F9}X|g_W71(VyXoZ0q_Vf736DIjqHT&{9L1) zfRvg30!+K1Z4R@ToWWeKad*W0#v$)FQvj>(s&?OXP2ZP@;JCJx$61>gB&RM%yq>GV z0-@TU*Ppstt|)xJBq^-MN=jHmy!%5yf+)^=sKu+)!Z@^g{;4^}~ML9#UChRAs4tHe4&)vwkVMEmb~AscSA)Jt(l_Rs>98d(q=Z4rWhnFISnY zy4&~x$#=+I%3YrQnJ(cpCyZgv=ccQh>^qw$wQ7H~+*$GhICbr! e{O!rzg`BJ;0tSc6%D^Pa=)fNw{=^^bn*IsyoAi_b literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/b2b75c07a2c427c15ecd40ce47a9814279745b7d b/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/b2b75c07a2c427c15ecd40ce47a9814279745b7d new file mode 100644 index 0000000000000000000000000000000000000000..8c848037cb6dd403084fc44f7ed908c897f5ea95 GIT binary patch literal 3507 zcmdT`c|6ox8~@D=qZ+QQklZ5b3d5LThC-sq7EvJzGh-}iELo!L)lE^^jlJH6v?!D% z+gL`Jv1BP**@v=^Old6d;CerG@4MW8-*Y~{<$Ip`8c!wwfJAx$GH{RM@b3q~T!6xcSwRt)-7yDZg60MO z+P{DnKrF$pz;}QRECI{F%7zceyK&>Mkq&Tn1N^~YNi#D*Ko;P#(&b=4N@{%=1ZIQT zYZ%y=1_G~uSAN3F;N_n%=fpo@5E%3W<^lnKz>W2|K%DlI9Sr(oflSV@KS+qvf3Smu zz(SiFfY;&#_(L|#YwwM4f!DuozwQA*+yY=I2+#(BP6{63oI{5j5Cdenb-ADdAkg|` zP9U~zxNYMFJV73-CJ?XvEB~_jK-Oo?G6B%#RFpGzh1go_9SlMVOA8C5aFt0QrCr%) zQuKTM&g)_mu+9u(>|R0d6e?uTmc-*Pl!UR)eh zazn2!DMuSMad2S1ur601rNW8Y8i z5=1f>vH6?4Uk0U2&~2&&t#LVHarO20#sqD!s^pcf@o-z%XGq5FA&uqT5m31iC->R22Un}6Mho^)wQ|RA zp7*;gEM~wPc{@eShc{VFmG@gndi1CheyOFpnqKQm(cWEaNdVnA6<)u4a2(YlI)w<_ z-m^3~ustVoqQr(JULUr7Ht%NMP2;Xhq0uvuPI~o%W7fncOT0Q-R(4!GFP?&7m7wP! z%q}OL6ds(Murww+6mr})o!Um}qj-nTfossqkufn~`M~9o2NLCF^iAGE<#F_(qvd^c ziRCXHLYYaLi1gD@yi0+hTr#;Ay3}5Fha9+-79CBdNVZU*br^eB6a{DHNeI}T??!6&-Mz5JcYy&?pNmKfS10T|Gcfbj zmN_k@Wu}H_2PMX=D>UA9SZ0fC%~~bFU&t7~tCWBA`s_rDscHM{VsMnjP%`7i_8n8! z7#9a`QhT_+_5AZMN8|H?uO5`@jXCGu>(BDhWV*n8DY7=YVX@Ng>s*g9`=HXt-u!e2SFx;L=K*PlkcQ}mgcxKAM? zD3+x$I_RkG$k3emkl>fvul`Cx5Z5PsfgwcE=v>kvjDD|;t<*voCm!rL<)95Kqi zqKsBUBOP!Ka0C+J0AE9J2dt_i9E-=O<5iGI1g8c5uRI6+jXclzDbL^hDbEjJoUwQ8 zDD>L;+S-S5?i5;GPAB6nD=jfPIzGNivg%%MNNkjP+;x+r11eo+)!MwZgF+1cPS`sO zj}|2(cq7fENnUwGc>vtt0YjCJluFKl%QX4Od@@Hg2o6%B!J^#3cHEYB`lfrho%GL1 zLm=v&=OIQAVThzK*MnMrzNipeU1^+!kp)dQ9O+sNRKfUIs8eXOYsLDF4gJ5>_M5gS zcWA1p$*5Shw6@YItsQN(bV{bDmX{SGABn)QkYXynNL4hluj|rLm0RjeecZ&#GjyLY zq0@HkwQZ(4jRkQsI-~sL!RCGcDnjEIef+G0F*otFQ*)KP*p`^9U(lbw)B0?W%&~^L zwD#8$u3v|9!*!EKKDM)^wJK0k^Stc5@x`ZLhS=?vmc*xbNgl_0q=vM8?tZ)Vk+h&M zD!0_@e07Q%HlCXP$i7)LNYkB^v~#DJC`MV46JJ|53eT5Fg~QUr!6G7r{e=)HQ?ddH zLp&5eYH0Y&D@>Dd*Fw{nu?2PVbdhUI1r~LW`@jHB5GPooa;3qt2~(;gEob7LFw^&F z#@G9zs9K2Q4y$i`m-&jj)r5OA#4Jc+CF*<{+Cxl*J5Uz15cX8ms*vOq7q{K&)5LG0 zo4iNIM;#N!$#{|9K93R@0Ch4n@0lxpUv;{f*CHaKAoT=CM<+sPK@zXq5kqckI#~T7*rz`-sRK_SHk&kRrvaUV1&c9IlxF&Ylbw^cTa*WFiF%3Pwe7WaliA%xE z4Q&U;Woo(b7+hpFWv<`9ztTOv%uW7$%cs;=jck{3>GDn9G$9m!V~;qzR5D>jBZ&05 zthf+ga4yVRiYW!+KVsA}#qw!qtllYZOx9HbRMAL12 z;4|B1I?Ktv*oj*@mQ>nTwO5m8Pv%b4>~3Pn1qQrHkk&so|MYu?d&-VxH4}1?y8cRX z+wCo@?5Ox(ZPB}qdi?A(1^U?3>a<;4}GgSr|Di{U7T8WI6l z<{*x8pb?wOvCf-kEAaOe1pK3dY{<=DDh1D<6om9A1$nFNj1{r|LqQ(f{~s%e1^ko% z+O4X84GJK^^@7*`L>@zL-l)uZ6Ixw&J6cXP8=jnxwrIWpr74`Q zq4zoM)XNSsZJgFxh@Ft$Q)%yKQB2G+f5&)|%F?H@Z?%xU~}9gYm@%*Ff%$%;s26cV9G#71($8;KZz1n4DXM9&?D!BE0a z!a@~pD%I~LNVdtwCB|JHk-eS&M({-=?zB5;f zuTfW;SfhSM{)JXcTIU_p*wacSgYtFCkeRJF+jTi zxt|d_7o-D~p=bZbzh}&7bCCfFqofmAh6zV|MHX<(;P~ct=3VYA23VE#g4wugZ(_)z zNz&E|>nE97D^&E-6*$g%H>{^mF@1LSv6kxbQ(Cj6jiCvIIK(Z%7owIqLz8^x1Vk1> z)H6zmI&;4w2o$0YP>A6BF%&^jB9@nunUTa!dMA${a%2EmxB?s_g?W%&Flyu(>hEOnTK&n6U*4w9$L|s`Z zxZu*!l)jGR<$Jh(-@0CZ84Z)Rg*T>0w2RC4<(F&kU%~wfkU=_rOe!QI7^0&sWBTQ| z!jEB>xS5krWJL3l?51W{m$I-yQXaA0mHu2mge!y6qUv&F|NX;?pZJ-Tjspc9zD~^8Mnkxnu zPG?&+rMwZuOz1Jc%9rtc^Wx(&(oDKaWEAH*ev|XEI$^B7Lrvm<~A|B}DT2O^4(Vrc3KLoeU_uzU11b{5yUlNQ8=m=EJBI z4u`Ex^u<0eF>oBGcqUKaK z|N61ilP=jowdZK}>G5k_a_F%(iBoIl9njT};f^EA>NqX#?AmH(+S-z_vc5gwVXc9G zYE`9u%^x#a&V^Us<+|!#>lL*>qSvu|X6$g8-D=`Kjt*C;r?dwycIHj`2-8F8h9>t!$$EN6gD)prm7}o9o$a@(YVJNrS z*F8z)>8@9ro29)dUh`aS&tMuczbgVcxA`sPM&+N}hF67!02qvNL;IxMM+YJ0ACL-e zG>p#5~fIbkd88mbdh6Pm<(&!~DiU?C*s*}a{A3irWs5DZu=U=2s}CZ#iWqo9*OVf=?VVwHLN>S4 zarMiEN5pK`qMpRgb+69f_dDP2p2_QQ4^hkT2@z)g$B9Hy-<R##I)HZ?E<12_TzkN^SzZ2$%U4*>xIkN^Sz zkN^+>dN2S0000Fh|NlS$Kmd>c@&Ew<07p|!22cP(08j!c009LO02FwfW8h|BW6R1) z%}LEmHe>*Si406Yl9_=)tT;10FEcM)Av?8FAuYd10ip~jDagRgZqUTcY|zB`dI2*N zBNG#&rU5S-r&gOs+jm|@Ms8LH1202$164NWP!=v8x#Fy3y`t2VjKmVX`IHLS`N@XGeu#sHM)SMJ1VOnaPPIsRnZ5yoP25=7y$52Bzkw z7E$87MutGH36yK#ZYW|P1Tli!D>1t?Nx=)`QbTbAQHTrpLh`dy^Ax;+9tkZ@Eix1{ z5Mhu2@&M!FoTSz{`IAlxBO?zq1PmJIBYT69m4Ugjm%*U1lc}+hVLDs*o-;ZI-&0P? zu9h>4m>>B_E$n1{Mg_lp!~(W|O49=WdVSirBhy*jCfVMkZsXKXi+*W_?|JOrQ{1;; zPgaZRo{KVu^ z=xwgEi}|0_ZCaeB=Q6R1>5cYMCT2zk#>LeJl?Hr3Ps#E#GX7^_VP;}GU?2nH3$lnB z2sa8sJmP=|ZE)Di^0A1qi1;a9GGgvdzOBy}^3=(3&S~bx7Zs2I@&E?%AZcY52?MbP zk?my?I~Gr}wO{=8YrMS9-_7?=)-E#O1St?^VKQJqi(=*`Mn;Alz2EP4JABW)81?pQ z$q^5UBkez`)t5iM(JfuY9G)b zW;Xjp#P}}#x#H!s#a}(zFLsy;-#A^fKVCXMBIV{cCZ7|2b{7tZmNHvSjTK$X?|0Vf z&BF_PZ_hNFJs8 zXWw%OG0)bn_r7%Kw-CdmDKVFiJt>d?@&Gq1y=9rZ_UFQSF*!Mjgr_mvJ1%@{H~g&p zl!@=ep}k&*B&s5{Z#%qsZezYi(eM`gf}8LA{8nj-^c5c7``~behqzB#q+!IS>(j&x zvWz_1Lu>U3YLXj!ea>Ky;@1 z^?T0x?!&kI_bps;Q~s)O@LAs-_bAO&GWNVhM;5(VCu!X8y*K%x%Eb4@z0Yd(!1nX410ItK~Dko?&=!%{J0V%G-J0{dh*Dof9S*vvEvP^Z({@ zD&yYPyk+huH#)q88j+#RGn!i4_#2t~(l6$#%Ie8ur}h?I~3cmV5<@;Z$R zUM&YI4E{5?f4u2;CFE3_>XIe(?N2ym1r%rTZO@R}zj9Oe#62B*+$T@nvBUD^tg>hBGnO*N?o4dj!5Ke&`YX%G-YfIddb3SI*(P8SFjJWT83GG8 dA!RB6joW7OkN^SzoDu>6kN^SzkN^SzkN|eywg3PC literal 0 HcmV?d00001 From 8f4cf26797c4f2ce07ca21f2eb43860a7a690382 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 11 Feb 2022 16:37:58 +0100 Subject: [PATCH 2362/4321] Add fuzzer for basic sc_* operations --- src/tests/fuzzing/Makefile.am | 3 +- src/tests/fuzzing/fuzz_card.c | 121 ++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzz_card.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index aeb569b161..fa83ceddf1 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -8,7 +8,7 @@ LIBS = $(FUZZING_LIBS)\ noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ fuzz_scconf_parse_string fuzz_pkcs15init \ - fuzz_pkcs15_encode + fuzz_pkcs15_encode fuzz_card noinst_HEADERS = fuzzer_reader.h @@ -26,3 +26,4 @@ fuzz_pkcs15init_SOURCES = fuzz_pkcs15init.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) fuzz_pkcs15init_LDFLAGS = -static fuzz_pkcs15_encode_SOURCES = fuzz_pkcs15_encode.c fuzzer_reader.c $(ADDITIONAL_SRC) +fuzz_card_SOURCES = fuzz_card.c fuzzer_reader.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c new file mode 100644 index 0000000000..1d92243837 --- /dev/null +++ b/src/tests/fuzzing/fuzz_card.c @@ -0,0 +1,121 @@ +/* + * fuzz_card.c: Fuzzer for sc_* functions + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fuzzer_reader.h" + + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + sc_context_t *ctx = NULL; + sc_card_t *card = NULL; + struct sc_reader *reader = NULL; + unsigned long flag = 0; + const uint8_t *ptr = NULL; + uint16_t ptr_size = 0; + u8 files[SC_MAX_EXT_APDU_BUFFER_SIZE]; + uint8_t len = 0; + u8 *rnd = NULL, *wrap_buf = NULL, *unwrap_buf = NULL; + size_t wrap_buf_len = 0, unwrap_buf_len = 0; + int reset = 0; + +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + + if (size <= sizeof(unsigned long) + 1) + return 0; + + flag = *((unsigned long *) data); + len = *(data + sizeof(unsigned long)); + data += (sizeof(unsigned long) + sizeof(uint8_t)); + size -= (sizeof(unsigned long) + sizeof(uint8_t)); + + /* Establish context for fuzz app*/ + sc_establish_context(&ctx, "fuzz"); + if (!ctx) + return 0; + + /* Erase possible readers from ctx */ + while (list_size(&ctx->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); + + /* Create virtual reader */ + ctx->reader_driver = sc_get_fuzz_driver(); + /* Skip bytes used for flag and len*/ + fuzz_add_reader(ctx, data + sizeof(unsigned long) + 1, size - sizeof(unsigned long) - 1); + reader = sc_ctx_get_reader(ctx, 0); + + /* Connect card to reader */ + if (sc_connect_card(reader, &card)) + goto err; + + /* Wrap & Unwrap*/ + fuzz_get_chunk(reader, &ptr, &ptr_size); + if (!(wrap_buf = malloc(ptr_size))) + goto err; + memcpy(wrap_buf, ptr, ptr_size); + wrap_buf_len = ptr_size; + sc_wrap(card, NULL, 0, wrap_buf, wrap_buf_len); + + fuzz_get_chunk(reader, &ptr, &ptr_size); + if (!(unwrap_buf = malloc(ptr_size))) + goto err; + memcpy(unwrap_buf, ptr, ptr_size); + unwrap_buf_len = ptr_size; + sc_unwrap(card, unwrap_buf, unwrap_buf_len, NULL, 0); + + /* Write binary */ + sc_write_binary(card, 0, ptr, ptr_size, flag); + + /* Put data */ + fuzz_get_chunk(reader, &ptr, &ptr_size); + sc_put_data(card, flag, ptr, ptr_size); + + /* List files */ + sc_list_files(card, files, sizeof(files)); + + /* Get challenge */ + if ((rnd = malloc(len))) + sc_get_challenge(card, rnd, len); + + /* Append record */ + sc_append_record(card, ptr, ptr_size, flag); + + /* Reset card */ + reset = (*data) < 128 ? 1 : 0; + sc_reset(card, reset); + +err: + free(rnd); + free(wrap_buf); + free(unwrap_buf); + sc_disconnect_card(card); + sc_release_context(ctx); + return 0; +} From 901c38608c8047273410bfd8bb3f3f52444c758e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 13 Feb 2022 19:23:53 +0100 Subject: [PATCH 2363/4321] Export sc_wrap() and sc_unwrap() --- src/libopensc/libopensc.exports | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 73b2a6e186..f1d762c4bb 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -268,11 +268,13 @@ sc_set_security_env sc_strerror sc_transmit_apdu sc_unlock +sc_unwrap sc_update_binary sc_update_dir sc_update_record sc_verify sc_wait_for_event +sc_wrap sc_write_binary sc_write_record sc_erase_binary From fb94896d236315ff9b4ed52671a6e7b19d2e1302 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 27 Feb 2022 20:12:53 +0100 Subject: [PATCH 2364/4321] Add corpus for fuzz_card.c --- .../3676fcfa2dba95b7c439b6343228623ac0be93c4 | Bin 0 -> 1432 bytes .../3e651eeafa4f5ad5bb6e21787ba4ba43af7c6f76 | Bin 0 -> 3650 bytes .../68446db83043eb66ce144ab42466b39b0675c42d | Bin 0 -> 3162 bytes .../995545e7be2e433f450b87c2e9020ab480947bcf | Bin 0 -> 26458 bytes .../c62b44859dfb22dddcf8c19468b61587b02bbd5e | Bin 0 -> 10969 bytes .../f117a2bbb1ea0617255c7e993914ef9062303580 | Bin 0 -> 2660 bytes src/tests/fuzzing/corpus/fuzz_card/testfile2 | Bin 0 -> 1432 bytes 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_card/3676fcfa2dba95b7c439b6343228623ac0be93c4 create mode 100644 src/tests/fuzzing/corpus/fuzz_card/3e651eeafa4f5ad5bb6e21787ba4ba43af7c6f76 create mode 100644 src/tests/fuzzing/corpus/fuzz_card/68446db83043eb66ce144ab42466b39b0675c42d create mode 100644 src/tests/fuzzing/corpus/fuzz_card/995545e7be2e433f450b87c2e9020ab480947bcf create mode 100644 src/tests/fuzzing/corpus/fuzz_card/c62b44859dfb22dddcf8c19468b61587b02bbd5e create mode 100644 src/tests/fuzzing/corpus/fuzz_card/f117a2bbb1ea0617255c7e993914ef9062303580 create mode 100644 src/tests/fuzzing/corpus/fuzz_card/testfile2 diff --git a/src/tests/fuzzing/corpus/fuzz_card/3676fcfa2dba95b7c439b6343228623ac0be93c4 b/src/tests/fuzzing/corpus/fuzz_card/3676fcfa2dba95b7c439b6343228623ac0be93c4 new file mode 100644 index 0000000000000000000000000000000000000000..60b89ef8fc9e32208d5c8f875342efe47ba4b948 GIT binary patch literal 1432 zcmV;J1!wvJ000000000G82~%~6afE$G5$q>C7=KR09IF1LpC)q0|Ph$0FVFz0BryU z01p8H0gwO!0FVF>0D3S000005Cjb9H06+kc0P+9<002i*P6ki_LI6+#DF6Wl5&#r< zoMYf-U}MY5O3g{lOEzQxfr$)EK$4k(L9944JufpaT_HQQQXwtBNCBb@C@ILm%x=)c z%xuua_<8{|6C)E7qox5b8>d#AN85K^Mn-N{1_Licbpus4=1>+c9=YPIWWA!)l#Ij@ zz2y8{h2YfW(xS|gN(Gnv+{Da0LwN&PkV0l2F=t1GV5p_esYNB3X_?81C8-8-;=G1t z2IhvQMh2$lrWR4+yhesVt_hTD;BF{lAOtaj+bc1kzqPp z_?|O52H#Uo%C43(i7GCTKC6HKTw8s+M8@*L(Sv2WKV@u|6#bdivsNtVYW$3#-E&(! zSoWX&Vf@78Qs`~2vy1tk)NNXvrsp!Tis_B^QYL0b2FAtJ29*YUKu^i?Gcx{XVPR%s zJ76FK;tR5f8VENELOkMt2yJlK%JQ*@v55F7UNU0tPQI@%kOvA>dnIod~eS*)itPG2(DT6ktOP40Q02%Il5o66cqo7%4WEP7H#j>P?`Pk02rZwQoDTd2VCAM$zyV`+}SA`}|gEiu4s8-uvKig@?FL zTBKpbrt8zh46==Z`GJRFAp=9U5s)R!xRHU80f-nuSt;2FoTDbea+D-6lND7Klw{`T z5tXU5=#{A~3=EMo6^KipOm(K>#ii`!b8M{wY*s(rlKe^R>~3RkuLsXt>W!wfsLzXh zbh&|pcVb=1p#s*wLdlQ*yA*odV`wp`sB*ghv?C%Jo(uYcjDW9R`uAm99?&C zF^){dsz7w6`t^Ix`tHNG{P!(faZ~=PaPV2*9rq~BR5JFwMMoCBStn`S@4Ywqp~}Sf z#l6$Jb1EW|*Yv9!Jqn90OBQQ56MNF-QfAV!(5vM$zMf%taLqQ-NXpxJ-~D(-rJWNd z8MARrQuF`jaw_BA*1To+^BOb$uPV7#wS#-2#?sn2@!u0q>fXp&&0v_d>|$Lk)5r5c znc0D|u2srQVtQ|Pi65V+6<>2ewCeN(2Gx6O#oQgFJ;H?k_y|SEZxspO6nw?;bcmFY z0C)iFkMcT=3tlY;Dh&QJxPQFqcO~Rho9dD!_3ckMWd#&x@omqL+P`vB_ryINd)y~a z-Lb>+<*n5Cg<_#i8%`hE8W6M0>FVso!ZVgK#qLaO+QAt=eflfQ$lfdS(|WT_LD?o? m5inDk02u-cHz8#z0FB#b@{j-m0Gtv60FVFz0FVFz0FVIHfVL3; literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_card/3e651eeafa4f5ad5bb6e21787ba4ba43af7c6f76 b/src/tests/fuzzing/corpus/fuzz_card/3e651eeafa4f5ad5bb6e21787ba4ba43af7c6f76 new file mode 100644 index 0000000000000000000000000000000000000000..9c4954cdae78c48be217d8e7acab3b55a2791317 GIT binary patch literal 3650 zcmbVO2RK~m8a^|_WTQlj?j}lf!)U{-Hey4FE{JH+Wus)UN{|qdCu#^LWYi#5i_uNg z=)Fb>LV~a%%0vb+${noSP43>^d+&dqbI$Yr-~WH-f4}Fv@AH9xqoL0TC4R!-idSo0I^H}*@v6{d=g9n$Q*@b5WpHU0rUy9PXC{; z&mbabgJBcc21vjTunX)R?ImZS0v(*pX6+L|{wm-H0i$l}dmv5$z?E7+jJ=$P=WrSX zCV@%hIC-R#Z$A)t54?APzT#c*?l+j6^cxHUgZ_XiK)~8cDjK31$x{guaX08|}%jh?^vhBL(+2M0U$>XWPL?5B;IyeTAP#`^SM zqE5}Q5MuhdRYtj$tlPNtOqJ9i>4o$2tr!+))Osu=I5r^|U;OxGdU0HCajeaI+a_y= z$LEq1eC&rOaJAJ;Z+Q*A5X?7QTb@Wz<%Xt~@^W7S(bLfHvqnjJ5s=@|F)58XaP-lK)GIL+w2qZ>D%jZ5!9bQg|E|m4u8}YZV)LI14TZJ zyU>hkM*+_g;#y)T<8l3rN}f!7d`%XDJ@a&T3g53poE;=0*UaJ;+BLt>t)6watTO#s zHROFpxA3s~bVT$nlB1$sW-GF6R%M-Xk4BK<*7H?U71P`fIM4lZ@q!s)qlsI6*b}<( zTyHIkMLcfgTcKg)mOxYzq|3dUi9K^%8gkNwDofjdV7xRlR(yoEkp)y<7 z4|$hY0!3D<1rj+Q$N1$H!`Vc(-O)fQ9Nc0Lz+n_Q^$t*qHdt9)1ZYf)k3R54ZwmOHv=((3nvXCNA_lvsUz1&tA8 zV3`(~dLu=8IKYMg4C&g{NTkbyb(~ zdK5=%7L$-EEAa8y*m<9uly=26%!}@EEvfm0RfN3`F zZA-*R;f(YeSUAQBjkqa;v%Xf{@S;a5Gb^h>%UT65q#+?u`jZ5Isl0)NoV13DQaOc? zBV8oFF&{)<5hQ$58+84m1tGY5#>sxCud%Va*&EqC&B~W_S5H*XKRr9x#I)r#ZggeSlYzKF?M#dJQ@+2$!h_S zX9!WnUeR9dzNQ6br7C2ktCqg!r|(=q21kiEifQR?$TASB%qkO-C~waYlI7dIlIgr8QcTEXE5x4+X=qNHZEU)X8BK)4ANvr}pVV z_Eb#T?9z8z?qZe_v25(@Cg&0*^e_Qs8IOur`n>U56KD6~Y+Pe?HDkTE(_EsRenMxG zio8?sEjsR)6Zy^;m#dF?8@}^h?b5Yu67|p9TAvilvJ72toDN7?*DXu&(|koBIuT9T ztl|Uk0^Un3#7ri6UG=Gi`q4)8d8hma%=!lJi=mCrHM;%wDhw`L#Lj0GF<1ltf)RrC zM9qzm?9P>`kE@)fsnyR12)};l8FnqE!Kf&Ex$l=*%*}N%r*-3-HYjh$S1i?gPiQ9W zmmx_{;w)5*PCH8WIs1PsjUbX{T&dG8pAe6oj^j#TVwEypMobSPXI|(@`P5pIR#!9I zz=fjs)V8ApSEilHF1Y>tF?*9KDOz_b?{VFyesg0W$i>se-%d`}*4BpX9ez57kK&mKoD;MA0_dU=P};NFA6CER!ZY_Z{?KEd}piv=kwCziBDnCEn|Zjwg{`J7l}C$S%(F z?`z3>xz?#~M%9m-r%J1c)E@t2lfLE-UyNh(Cr)MevZAkCMVps-Xg)LCE0|}#vte%a z+hm>)%=e9c-@1$#MkjB?M6>g;sgy%?A`_sWP-*QVr9eow>fGRE%^}LgT)kA1@^tgo zIbXulU-GwTY7Ux;WLhrTkE~=RjAN*ubR@G2K^PJ>3I(dN5G< zYlxlZa652X4@JdggyLW{4d5=_VrSnk#lfYEMS?QVn*@hW2aN_{qogx>LXLS$CWOUe zhfpl%dfRwgc|WPorr-sJ?y(tcmIe6~RgX@(=sC$ayV%Y4J3^kpz17t*A|X@|IkxGb z+#afj>*3Nv>uY#DI=54HSjJb$J99JO+L{?fNbS?P65G>!JS(T|8Kmj2pYDVS!#Xd) zJcP7#IxdnA-rGl+V{WF)!T{lcfD${B#qNux-+O>DK6HwzkEfh;z36I7-Y*rn67Ni0 zz4M_XJNL~M0(b58juUmv+ERjP-R0q#8e9+0^ku|D#+Ka8rcck z`ME|p0V%Ts1(lBBR2D=A?O@tzL>38Faf;TEq_3**r0g{R_Jbc$CBA+XKR zNPJaoN#Fxw`iK3vJ*2Y2n96efT)0-YXZ>vdSf^mAgFqvt7bzP8h?S&rMf1*>^TiYSsQ|xwGsA iaO&Dc`P-Ab3prUy1Pl(Bm4Qi;(SbiW{E0u9$?=j9b=j|MYL?_dCCt_c`bL&ig*!^Ss}OfPu?-958#Q z2!H_ptmMh}4_OfuLvKbwsPO9@4p1;~D*^6UCn*3F00LqtPUI{AFzHkv3)YQul9L2n z>KGtB@Z5JMItQcz<>6=l#=mFGx8@=P5=KcSvJ4e|>lInRF@qDDJD7L4vlw7?#&c%F z>irvn7f+V9QP?=y)JCDAkFLOR)V*P&H`Vm%na7$c$4_a_k~W4W5aJNG1fPjotcEA~ z&IyPtgs4ZP5Ow5!K@ccJ9iR}wvoI7vQ6iR?lF?6KC%lzM5IHh{EL;JOk;2?bvQ&!Q z8g6)GSP-rR6(xuql{$!MxdpA};i^zs0%KI#NLY(y4K-EdaVBICbuj6(O-#L1@@;#Bidc~I5YH0SF zH)UI#7^NFbh#){U+K9i zE89+SAIa#is2vs-S1bdrglG2cagUf-RX5f)?PgliFS&)y^)7qkp2dVY?o;2a5*O&R zdAg%)$!n(kxn;TJ)WdG}TDlkKvJ`obcbdI6=&2dwP!)MU`K&X{wdGqqnLn}3;gA(o zwCq;Ijf5#P-j%&jEZtGvtCXinsGiQK=Td`n!WZuruO6>v24a$J8W!_h zULF-2Z816`x_JvvEJ$}*h4i~tVmjn>q!7s)FddRZm@Z|&bTXiWI(JB4G<~FqLPJr(6T$p z5;do?`HjbtPda4=)|{o?qsOgt%Av>DZkSfRAX~>Enme8>t37{7SNC=^(+4eStLi%Z zAJ!Q9C10(aTm8ojmSfSix4AAl*ZV{rkLb1RUj1E8vme-QZ29u{f(aHVtB)o~=%Bru zrpSmX=bn(5Zh#IVhaZp%ZgD9Xreo66;F|K;U3QhoBWifcsZVNetL z&VyQYLQ!DdJ?o5K6hpx1jevkgN;!;>a=@UJeW9RzNXhjVuU3jhel#dM*pf*Y3RQ-7 z42(*Z$e2g$7QAJ6&F3XN*BKJZ?I zgd54N@o`H~Zr}4#W2>|$#dCp+T>+*Z{rfl|=en?k+@SQ6>&U9GU;u+qZb-kB`{^L0 z`~yVAl_huT z9E0)=GmER$?yElV912=d1dQx*B;xb}pr)!klw8F5N%G@0DkRdxFE(Hqpt7N^^A^Q=hiNXVzyF_!?4V*ZumI zCuDQG=B;_L=!lr@Qrx?tYyHdf_k7QHxTW(t-GWuqyn}`5|8XKw)K@2d0-Qk#e#r8_ Kb<9RVK*c|qObRUk literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_card/995545e7be2e433f450b87c2e9020ab480947bcf b/src/tests/fuzzing/corpus/fuzz_card/995545e7be2e433f450b87c2e9020ab480947bcf new file mode 100644 index 0000000000000000000000000000000000000000..ee7f4ad2dd03f4a238ea34d11c3861a76bab7ac4 GIT binary patch literal 26458 zcmeHw1z40@*Y?aXbT>$sGz>Ac(%lUT(j_HbA|c&MNC=Vw5|YxP(jX}af+#K04N~9W z5zo={z9)RoIq&~}pL20J&okFvd(X4h-s|4?+G~wKz)vp`RDj?h5x|e*M5hyu01N>7 z#sENo>;51>41ft>??-nVq{8731p0yiLLq=aARr6~Ux4Kc1jYb-fe6_Mw}II4XEK)o z=_n8+FoG~Z1z!S~{qwbG&d=AXxj$b!oRZsceR2LfQ7{R_s50noyphT=9z!tc`vK){y~ zP|lww2KLM#AVdm+jfQk4O{pTQ1P4NB1_N;*a9|)Xg9X9_2Lhp?06`!i0_+ba2nGU( zFd<*Pu0X(GkT3uu03kp_SGTgTGjeuuH2bDAPzD)<1lF0td1pwzKz~?gKgoVJ&VS`C z20#YW6cJ2Qz)zY&v^m#QI2=39C%Z%VAQ#ZEC9Ev0oQ-TKzdRyL+rBV0K~TUzY}hq7 z2&OU&2pR+d3_hC{AP~}-Qb^D+mF(>()y!_Vm|7V*TiM(FBnQ(e5P}K@a>2m?03skD z+^=MXAh>8Kl6EGJ9yfj#141ytKqHup1OV0#%zoeuJO~a1?emyG*fa%v8u{N#8~;KY z{!dGr{6ZSxPfMHrLK^XpNuRB}b5+Bh-3-=)^XF$r`qw@DSLV_G;z7?W@W1%+{y%uM z9~Ss;8z~0h`eP0J7mV;TJd1vUXN2ru!!!H8gJ+R5c!q6durtsgU$$S8q7YUH(Z53F z^X6P%H5Z4l{|boDTN-8HLae;18+k zZ)_9;DE=FJ|LeQ{8P-%k!5a7rKmVC^@<0$_yyp{g;Dd2FIiVaJd=M@Ol!pfbh4OK5 z@qg>J$!uU=I~2xNkKg*i9BwATa@)iM{QwKXi4o;J}CA ze$^6QOB)tn3=;C1j6=HkMxQzPR?eI=8i@#l!``H)@GEShNP4dQ1=8v7Qtfl4<-bI~@ACBpPY(%z)O?#uQTX>wt zlP+Hv$|%Qqm)W#gTpGK*z&BlNCd755ewuWtC^?N&uWcSFyA6XtMjp!4(-z`t^ke5vt_%h z=x^%EMLEkmb-_@0lukFwra7AIboAsCFAy9M0L=0SPQbJ>3Q>V+m<$^%3z7DtGjoS2 z*^bTjOv7xpUsNvQ`X!#sW@?sBj)2090E_eb^WuTv(y`Dmw6qm9)ioqVT;14U(*weF z)*~Gl78^!Df;EJPhk?|WEAW>q#9wp+g3TzH5Dgf{!hDhB=~S5o=%*YZGUtt9VPzp$ zq?GUc9s&$vv2=F6A;8Y=U~l4dgYBzt$o}p8V~3nsfc$I-N-!bhZ2n?@dW0mDsH=FN zRs<~2>=$v?fCB6n0P*vKaHVskvj?$$9>v7b=6A+m6IWA!$fe7qO9e^Tm>QjZwX?Tx zq)hBCef#BDOieDiy1^FEPZt(vZ?L5YTaB=9g8@bXBZ)0&XB%9z7yNDxWI!U`G$d<4CNvTgANhrrh;&U*v)4+6i22`DptT_3x~2m zf%@wtmqg6owqVQ;F3VTjR2jY=v23I~Uf0gt3gnSa7D#-BULvyWl3k>B_E3WT6_@3$hj$6NPf*P4J`Cm^CHOoB+1Go#Wj)E< zZM0!l&dMn9<&c#3CJLv#b$pxurT_%rR-e%lnLk5rb4zcOS9BWasn}5eR#vBz4wadc z65~#X#`Tv8K1jOvy;TZd3qEn%dy*wNB?~-o^vIjv8oaYo$0nF6gx}8}&%Hg>TC`Ut zKq;&mgp;Ie)>xoHjG&Z1cq6R-IBL*r7d55vW$8%JnFXBusTH&d)H+4KA9a67ezykB zEb!gJKLq~*4g9dcU!cVQsEZ#K_>a{07YN4yTKB)nUo|tpe zv;WP8=x-uD>ax;GtPsv`NDtT7q=)OuKSz4*MO8^GyjLrfsZ|j?*>J1jQ*#zE#V@$k zp$V6B2gF!guVcj)(PWv2qu5&SJR()3>*_8)IV1DIy>6WTpbF*GeJ;kQT+cqrB25JW!#tg}#n_N-RkK`xM)z!?i?>U4NrW;>z8QGXDoMtVlA=mj)%s*ycwpH*wr(0*9hq)iYfS`!ez?nV+nc@( zo+P@3Z?WCU+inz(-YQviklkV)v-jziD^&KJ^aR65&us|gY>$i$W`xlHLDKUTKatR| z(W<+TE%Bf8lh0Fy9r9b;1o3;h$(aR2SwD~Q=lRKJ!Qba6GP<^;+Xa@AU-J_Lk?-Lr z{L6tSQZy;SQ+v&p{kYP3clyXeb7*cpc^$X&TvWpy>_S58rxBZbRWF?k${Qs`J*Gun zW#4lv6vap2ecmgCniZ?bdBix&e8 z=TR5$#+9sU^kb01g;pEv4%Fm&3Oj!oj+rXqLe0zB*p8tc$8kupzF13=V%rnEdVeQV zseea0ppekE~Mnt4w)4)e}1RY%}0V*bW8IJ zy2gWpghLaD{wnL)WNnRQFUJdB$#~?l3})Rd@Z+b1O>w%yre1xrJ?m?+kGPMmxe%_6 z|CP}4W4rNJYV&*g`eA|Z(b``r^TPsvr8d8(uOAlp91@tH{Ndlh7*NMK13LI;7?7lrxcaY;eYn47K-~Wz1FH60r+YrQDY+k7 z5BACf_#Fnk)K8RM!J%MmbhW*f&DGY`LBRQ8TyKsTY5Pz~Sv5yEG0?a(ad*_Mim#wz zP}SuX`ZOR+(YJ~&fOhl7Xbqo+1~E?ek?6++rp0ZAZi;#@{&j+bYm&Xz5^xm9ib#o^ zLUg2+XBL>7v}Ws9bY4Cw)ns(;_UWo|p($GPsSM}iZoDGP9!HbbH!4rl1vwbwTDw3> zeLOS@XkJS-wRd>NsV&!%O~p8Ha%Eq&RcJh;gCXmc_5HC%qPGBkT7>H66jK?zLl1Xp z|Jea_o7}L`489G99Q2Jy>W_QPZx>En2^PtZY=C^qe`k&`PXBId= zi~KyspXWiJ1%IChDNOiBrZIJne9eQvutdD?pqqdCWJgn@!g{up*@Yk-SnWVVASq`V znlUMQqY!~_k*xIqdE$yfHtI|k;o>vXOPrgU32l*M2-#apZ$|?7DHwcv`b0-oqG}bC zAInM`=$>LrR`t{gbn9IKVU;>FS1_3h3_h_96#yl`A5r%mti;SSzE!s~(x<7VZ;L)1 zqGqt!E$QcFZ#wwqF%e) zuEc)qAVVS|cWb!`9c}+wnh1s1W^g~vk{+7f%u@RWJ}Iw2W7sim@pRp#4{!WF#5;sA zn8yr8^r=Quy{Pn(N{$0gd%KnGml!>_F?a47vK`Kmu9*5ijt0;k z-#{pu@IBRlVzA2GGEMyGagCKgGS&E^cDBOZxXhvf@fTcN7bE=o%^ue-zXoO!21=Hvs>b}6vZ3$82iXVz3_g67769Ra z@WZl>c)5Oxkp1HJpNo*KBO)o^(i_DIu2XEQcq}))>i;oD9?qLeO>QXoI%*%kZEdax zTzY(7a{mi`4}*aIeAYn?viast_6{OKL8R58@ep2aTIuUsCgu-V3uGrm3QUWGl^uFA zUU4O|+|4$6+1&c-T0edmA&F*$w4&M8M|XKf`2N^4@5GthUsKyM`zVOuy*~9*1Piyj zq@E_5Gb-Fh{6WAQ?$8>|vGJU?>00s20+Y?%jta{?6%^>J^ACcvvyLziE#Bq?9dpXr zg#u*oi)R=0a?twprqe#k%6*vdqEJ{u_jHTM7k?;m>23Q-@mj|nzUO*gkNoe7Q^sSh zN>S)u#d?dWea(wRZ9VnD>Eo~Q;m^CQzXDPIhLiu_imZXoEb!-1Jw%fL8K5H=;eofihJbn`y>V5+^N;}pA}0d#*mh2aY$dXs}5c>ZKUB_T6+^Q zwF_~4b3_c-H@w71ZR%dvaJ*l5h7bITr`}T!xfhrsi$@A%XE&jJq>1E_o>6b4r~{wq zzwH~#u>{R@63{;Myh^1v{LXML8YL)^gc$M0&hY(k#ZZ-`p&1hgG?s>EOgAP-I6tg) z#ydRK6jN5cy7(dVIGcktC0isX<6v{4Hq%R@vNHwc{p29PeqC~J;RP@#Qslbvf>6+Ictl$gF`#5dJMX%oB``u7M@Md-`Xl-{Ca_67PseRV>_=tfno)_OmjiT5<)G>Y1`MHueBOGw z#b##hgkrt9@3NICQ@0(0Zg>_$Sw527_zrxSf$@j#&-_7_^}m4+P!4_$ZcZ*J$0z;( z`T6#r!-tV&#lCrzuz{562&0SARk|wETe6xkynxz?Q*#W;IE_InI=+v|KWiH1YWn-tYU*#7(#}_yd`;uQr0N^oOQ1O_kJEY}6)#&0w z2B3edgSqV9$qk*O!Nco-{7_cAlfG`l;*KM`TYig_!?Y4*_xWt_6QsuAD(}Yt?16<& ztdanOY^PfVa?hnJ2en_s4R!5sOSvNFr;o2O4^DcmVM7a5^HS{RsU9R@s@z2~14~!~ zWK|MlvaC&+t@vo^stP$(b)jYH!eCA4SS38)eT+`Iy-7=BuP!5ScBnURov_J9suLRq z+v}RKi|9$W#jaQiM|b9+9p6ierJ0&hS$ObzEvOdKPZ#I2(g43E)~QfVmya}x+c!BD zO)7_$dV}*Yie|gxVy3X|pm&-4@v`p?>kpn+Yo!wq7x?n-U&->&uXfbSKrg=yhtqCK z*JQo@@|fFXK73QUb6W55)7|Z2{+rA?r8T0HA%L1Nr5v&&O>1GbdBzD)Y?TiS*M{ib zLunKZ@JibH;QO#h+nRxrDqaKr(U`65yA~WQ)3s~cc|^s_o&_VJLUye+hQ(K{rv_j9 z3JthR6YRM7f!uhYqxfIW-DC8VHASc+}}1!3TCC$hv7wAf52eUM~OJyIjtd3*pjd5K*(9 zmE&G)J=Z=XJ41>Ak`rnh3PKf#0JR)gEM~7fBVXe-05pg_wR&i2oOohZT%9$u}`3 zIDQ2Y-%OSwQ@O8fHqz2` z(U$@Z++XK%8!H-bo8R5YvNijP2C^5?HcoA~Jin9}Nve&8A}cfJU`!tO?ea1G(!81fcp^?8+)8?Ah704Bxv4TGN$Va!u3ZRo!&bbzP&xR@x3Bl&pbK#D? zQo1t__QSDoOcbRIBs$sIvhpu?Xau4rYKUeY-R~P8^I+?Vrzd{&1QW+@gupPFl*mq~ ztWU`;l#!uW6*Xn?FGmm%j!)$#ypXdH69*6MmIGFO za(4UA;X|WgUNSy&8Dh(QFF?69on8PXl08itNbr^W$MC_S{)bDn4STg*m)M_%_~FX& zz15RSan)T)%ApCey(!yRydU?@A||r7DKQao3ME8iK(5q?ZCF3+YNZUs^$4-0bo=-< z?%pz|HK$SM@Q9DW)M@-H`)gtnmS_0TnSjUJvU>tdT_s9wwT^7SGIR9C!Krk1xOD1{ zfG^A^|FQDo(CaxLf~cZUGi-kkm7SMP!jD;bt+291qS=Bv}8~j`&;o$UI-1^BJ$^k=P=#L(@3-z!c*E`CM4q)i@=mOpr84W z`VpmJ?zZ?jK2*RcLXpaDO~VD z{)cJ+H9wM{(P4QZm-MDUmia^?D>be)LvX)?Olq~C-~b0%bowx-;kyW{y(`e0zMM~@ z`2=_+G%IZqkX!MSldO1mdT~>gSq04vI{96=f}cpo%1=5xIKeeuklbZ972SS~;Yx66 zKL%g~WI`<)^lUlt)1ArAy%D1^kdw~zHlBBJ!?o(Ufzh0`a4$ZWKJCi^%hBLTGw0d( z>*5rPy*&{DBSuM`3u9rbLQ^Cm2N{S^odF*sUJ7z6q8!)vBD@=_+lG^OeFD+7wO0c_w`l`suzVPhx=i^+YoUsyk7^Thq6A zaYhwx;Ko)alr+?!H28yA5X#}@+MmBkT_%013g0BJT|&d5$1B+jAEYLIQ+N|9w+F1b zRuHgPi&lI@Ipy~}yhIgQpeh6V*q+K%svXFI;=k~A;;pFetru6q*eEE)?*k8>+X{ER zSCxFvr+%A8Sm^5f1MjRIFfeKE?pc<(OjJ`?MHN>xC9xK(e29#bCdh)tJ zN+hgTtEr!~l53(7s^vkC#p4Tsm&% zG>(NWuu8tUua@ni9N>{C6av+Ib{vKwEM&>r=09h1QYSl;$ZNAz=yze;lB+ODY9>Wq zVst=i`u612((DgPdxGO5+EGq>S7`3^WRQ#(Wv#3ctR$rmp!d47hQu*qwU)oRc40kB z?l4%mFHWfB0o2(1;)mR}MJ%sXfX~y4Ws#IiQo!~dlVobO>Wq??XCx+0APb_0rjPd$s zqC#?OLV6TdHga}e3U01UiJA)=P}DacEgDWV&szqKDr=rba4eVllHD)#$wptYJ}{b< zzVgsmM6IovJ&0N5a?v5nX+*fehE|?jI^P8CP^&-~HkZDoUN_b1EI_)EO}Ou=aw;vY zb%igDKZSKg?>+Cd;A6+q>71U2R4x&p$`PF@Xe?x?Rf5ZqRVNgN4e;xTX6OCzIFZQB zYKi2w2_=s~KJJ_Q2YdTPWuUY!@-tho_t9_V4+GCmI8e{}z&tA( z1S0%$@|~9jW_Cz=k?$_4mA$m$v5atRfRBl6qkG0c$i5mEK=sCLG1g0w*6Cj8vsgz& zO3RXoTouoGi);C6B)2ZASTx)L@l~oxVpw0+-e-DWyh}N0{?bKique(Z2(`7BM@5sJ zL`QFZHAfp(@Ag*W3R7%)f+JCnHhyQlM;Y7=?uP4D2wL^h^vtM91Vx8#cgXpXP*_vS zDQBq+V#w}GzG&ZyB+^eYI-FLC*_I)on9j*ut+<$0N+`M^qZ;N?U`neh^sHuVQT(F| zE7;}vkXU`-dnO_={C?L?lM#8rw-uTU>w8bLA=28_$@!TY2CGTwk4WrVV*uE|8GSzz z7L%(*BwGs!naP_rMT7nih$Q#xY@>1x!SUvAmlr6vv?zK@gmT>?%hiKlmZFobEgXOR zkUP3bDTGFb|h~TTpk@iiYgi-s%C};2}&PL9M%~49bP&HTnlw45*UJe zZ`XYfE}u?$SmqJB>6^uH+gJ2xdym|lWgb6iPvI^);fLq$3Td8wRytZxm@>1qj%B9l zfJ7CW<`&X2@Ltx(yhH^-(ujMR9#}mI*-m9q5P6O=<3|w>LcA5am7`Z#Y<|SJ#+(t^ zL{oNyrQX8pLd~Cd;s~}7f3W7c6Q}=XV*Sl-^sJ`*8z;^I`(=xBpZ+(EetvZQdrth_ z;OUkwzXV?>mf-5t$2i;Rr)U>i9{F6*L|QkvkV)=+EcT{e+h@x8Szr4M<!Ku6|iXu2PwX1-a>Y2rC`uxeRYRgDUo=8g=krhtBYd8heBO-uBy{)f6s(@PH z)_69}M#S41b8+5erw`5klP*W4uZZ8wVtEZrJV_OC#R2n+(G~8V%C%){J?-P34|ssn zc7-@gz3mCsQ#jxEK99rO-ZlI0RdhXFt0j|S;ux`u3U{PCz(byl9i^I3HAQML7jv8I zM;uPPV|JR?P(#D8dh67~Qd$R|XCf!cd7<;RA$l_O!g!Rj@hQ~7J_lI|n-n+DX%&M4 ze$`jCs_S@{PO>#h`}EdD$)qB7u}u-@Y}Kg^1+=DQ+7Xc+at}-VOYj}TgxZM{%hA_; z+ZGiJEyGn22ZfO@1YM;Rqd2nwiJiL4UI1r9=k0<>33`nWLrzQ$WZd2nb-wlOCx`yadigIXz;jNdVD<7$ z5C+J_^Ltpm{DpsCFaI?aj?!^bdtvw?$F#0)}~WlMB}uG@plHc{TdVn1qrM6{RP+8r9sE__ftf?##UY~ za79@q4BkWR;_b)peYaslK+)Z;?mVHqZEhoTFMtK)hepX=QvFa>WoeeTUUBeNFC8;h zP90;>@itRjTU<>WACeX$c;FgS5glIld$|6K^gE8q(aD;T7nD8Ihad_=?>ySON=oR5O5&8MvF3r|1i_?fD$Ky&^1l#FCr}0)`5*Tq?$k zI!5t__m?#@J z{e6~|z-j44kja;L9Y*k(2G2EF1x?~_Ijc12 z*A1C-g``Mnj5;6Tv#12MqehNzn&y^{1!|qBQ>;SugGDd~azP@jmi*qhu4)CAH(9Jt z-`{Vy4jq2r7a}J9n66u#7FT(g$+sKvQRr>2QTs#FhiIvJ55nX+XfFN?SWbU18y3L~ z23U&cfJOIz0kF<uLRY)Cf$dV*u4T+&L|kaA+( z%13sGJ~b(AV4lYH+mHHuw+L2m9HEKfp`@wtIytnHsI%|)#Sh@Q;UUF5?|6MEpigw0 zy29XbspPFo+YE2c7VFch*ojuPF4R=RiI*1Cy>6o3A+A%L5v!VBXsqpb9?m3$(DxQ-{m&HQs$}ec#^z<Uxd*c$kmD9@r5U1jiJ6*IG1^xi?zCsMSZyg4X-$$!5Q!uw^8)8ax{*5yjqwk$ME{Cp<+UCWMo zq9`UgGM?>6NZjWbN`EN%#Lmb>UOkUg%2tXhJThX`jx3i(O@_QkwOSH=v#WmF%neST?_qlzaRszwxURxwVx6jm3*;m zJP|CVeL-}Qd;sF<&3|(X!e%?Ko2J zJ@j`A1Q#(g@-|`FBXwf%{MxB!tivD30Rt@7-vX>Jxxc@WU-f?;sLBa2`wwT}T#4Bk z;HJxs-(Npl0}Hel>|0e{qo!^3x5=4=iNEslu}Jn@8^RpA(^NUEhe51aF3f>nQWwuF z7>67*_nzx^s6e9%7Gz|C{91DGs-a^POb;0Sl6Kv_4)fQ)RdgphHZtXOwnk{h9D z@A4}x#dXy(lj~{+6?CTF*{sra&Bv*sF*ortX~~q^j{6@N*S-t%k9cq?uWoss2sq0joWFM(u%3t~~2o9r}DJkJpg2Qvy~Y%S;Kekn0~ zL<#|2+fvg)hwW_~nl&ZzoI1#qvO$SG%iZ%5$E;EOTsRb&w^e1X9|RPx>bTF$m$7J# zEXL~&e^7+_YAgA*(cK$sWh%gHv~v0HZJ}AO zG7Qpf%bNOD=?=zB$voPPsK``v)f6-;88=6;qfdR;`p){0b^2lSz-o=zz1@4slpK-u zo_))>R0)_4W8sG~JlmA|+pcQf;slJb@I4oO)`ojMPsN>V;A*K;m@ku&{f9s$JM_;3 z6)ZURg-XG~WB&lNIxn05J)l~FUx|=9$=*sUU|wFB!hA$8K?Pir?zfC15K0e^BVeaD zkmDMxywG*JI+yv{Jf6MG+RMxe6~nQW$4}3!y{djIE1>9(HnFy0Rb`n)YkL+xsNUF=glsw;NNQC zB}}icjKIn+o@~}}-m@Ce^KORAl%{?bz(j1)HUj0iv(noj);`M1mI2I*L`w3%o0vC` z*R4a_>qIAsCRn82I$;u0B9^-zqPq!aw1EC#uTz(*Gyf^V(rIIyP}I$Sb3?zL;|zn) zXf^Ok49oz-ht5qDE zBjlml3)m&MR|4OzNpHHpRzgsFQJup4oKA!C*86?PZJ?3&Y2uj$y876OV*;xdRx3yv zjlH6z92L!{IiuK+ug-b11wJLGkNtx{^`%(<2T**65|y zWo`LaPOWCL0vHCAe(1}q4FQ8>gTqHNd9n%7H;PWCEbqNTX@bwYNRA;ST4U=NrlwGG+ zeZtfhP0X&5mZCnza9lc~^DuY=p<>!oNje+AZH$y(wNz;(WP$Q%N1>$kM(J&IJ9{u& zrX_|tN>5ep44k#o+WSDM`Ee#nIl}%EnCA6aqp6WPJG<^>yIc|D0pe_CK6_Aw2*9 literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_card/c62b44859dfb22dddcf8c19468b61587b02bbd5e b/src/tests/fuzzing/corpus/fuzz_card/c62b44859dfb22dddcf8c19468b61587b02bbd5e new file mode 100644 index 0000000000000000000000000000000000000000..a5fe068d7cfac3342075b3b22b649ba7f33b16cc GIT binary patch literal 10969 zcmeI22UJsAyRH)gp@V{gbfk&|NFX$kCZKc>q}Kom9fV*(0VOIB=^)a3Q4o+`loDxz zRFMvXB1NhK(o1fl+r8a;-2LBk&lu;wXPkXA!Wvm~esisrXU^|^*ZKkw@Z+V=3Xq$6 z3|S*I0PIK26O!$^fv*2fAs%; zS7eBI1q3z$Nf8!SfDIETAD^q|#Kh3<&hAKYQ4eRdkEo;Pbum@AG+asz28W8n#Z_U_ zGE!>F;ukN#VG1qC+y&;B@9Lh4Jj{uMWPnjmBtR%*ere?Z~W~K-x-B%6LKc%t>KlWp-{jrs# z5Qj=YVd4@n1q{U-D2Ad9OnEj)J!qR2NKTT0p{OP_m6HHLFnTC0n9?>#9f$;xk^sp7 zP%1FRk6kb@0|TanV!&ij4CzV+hy+MN2q1?4b|4@%A>12A4W$Hwj7Y(ZBu0iXE+_|a zhl-Ku3KH$Zt%CISaYi}YBYco(ZgD6K3Ofd+BL+}2lK%)$hC!jC#1;^v;P(~-LuEoF zTt>vsnJ`|N8|CTE{k=n9!h44Bn~AMr-fzr$Dohy@WI1x*b^8%_EqOb3z{S1)<$5yYTz-K1ET0Sy`4&v!GxI zJOp=j&+^I}A_I$1b2-UuPEGUsU(aO}o(MWatx3gC?Jp;}&=i+kv{tgo&S>+HBxl@h ze=n7fvQC%BhD+y6mb`L#RqSQ8lLsE|7w*d;X(VL%Q<_o~7^A4l>Wp~jMp9z%@b}Yx z&dnVqA@3&T6KW`sm4mjzvxbrBE3FIC9i(H}9LD!^i&$D^criS|bs}b;p5|I0D&_%s z+M6u=n+rp6HJN;zs|hdStr}WJo~UyBvZaKJ0&}jw`(N%?l7N5!U^a%N6pA4!B9Ku9 zQwW2BWMt$(ASnhYMQ9O+Ui#SvB?*%I8)YL*K9K=&GQ?DriD`z`K%=iA9jpe7ZhOkIExJUyhpn;>%z@d!5cNu|wL6DyV z|6&h>FY+DWAH?jv-GTzs|6fD;gPsBMx+g(AojpCY37+;73Q=M?=t!AJPjv29+YlL~ zvEAue->YeBc*ellDJ}~DxRN9?9@s{l45HgANX~>6dmBT?=C(TWY~R>rBN9iMb*2w|F+L@_sYFC7S764KNyAtLrClZ z5+D$I`2eMQRDReYwzZqw@q{M|2XdHde2o2TP2j;8}e0QM&~J2AfyoYwO@6nEGrfpYnG;G z84T>+~DhH+wkgeNkJh~O6ITxnX}3N36V+J*&7k)~gpNgnsAft{3_Ro;IFP^>TF z4L-gk#mRr5PmrWF5;LhsAWeOmduVm+meaYFFX7l*gG_Zvm`l60a3W39d*rfXyLHP; zj)MqlTEOhc@+F?wOm80I9W3GD07J%c6+?D{h=(hb@aXXUCE;Y3?AX^bR&_TK8;!+c zEBo)phZ{cY&R&rdkWzNZ|0x*90RhCV}`3^jBr$*c>6gf#O*m}1N=vp%GlUx`V4 zoS0%7V_sX2Og2><}4(#1mIn$?X^Q zU*&FFy|$h*l&{t5imx3KbMru5uiP2%ABfpM9EhEFm|B}OO4z*Cu(dmoUCFR&@OZD0 zbCq#PV%D;d-+xH%%=2BAcQH$r7ArN|b-VtX5Vql}f$?BLg%l32U1x)LezDD~&vu`r zhK!fPWA}K= zI#Z`YgUcHy=kwev)^?l&xQYw1*Pd_0uShd*RY(qv4t2?fcCJmu#|f5SKU{22;FaN> z#>I37cFuZS+kJTUq;B;1)Q6tw-JNwJgP7!J)zr%;8tX!p_xc~4tVZRE!z9F^q8@ft za3?z{$td!moI-JGC>5*f-u9+%jax0=_1%3ezhh!^B>qlmJb6l#!>(zIsj6|k)j)NJ z*~a82M=q4~>#i9CbyvkQ%0;C8>?G-SQLe(NGExJ;;yfP zl8LDxa*m(Lh=ehcnk`t0jaOJ$j+e-QSBo*5MZcvT$02~i4WM*zuX`f6$3x{qL$wSI zFRUL2>f5Hd_0^DfAtX^6fN6TQeluigd0Jcs~KY=*gumt0lX>Cw;@ zAMVr=?FqaMv|Maomk>X4L?BRho=|E76pcy1gXO2f(+YO@R3wNZ(}%LA%~ z-m6oB4e=XdbqCAk_~kDAJ5S3#b%krzN-poymv6I4<@h4;Q#B#!;|p%J%{@r1X%oGL zgrg$c#mJZQZUq6mho(NzmfNp_4Woq}>lNp{G&LS|7z-V~9iulv$shSu-w4kte6v{* z^E_Bg@AJfr6>M|lb?!tWgSfn)AXhy~q10gMp@zB*_N&y?ilfO=y2OFwEh+9+QHewB zXWF*ub>B?EB4$qP`5O?ZWESEyFJP<1IQU`tpk$~8{fp!_7QKx0K9;} zpGHE8yNV&LCPMp@cuGK>?BYyuT`lb`EiLBmxX!lx!MV3vsqxX#$#JhT+M~wr#)iv2 zdZ3da1Rv3#RAOrR$iPIcAtHMDs;(SV-V8)gU&=r-ZbmcuVIq z_S|G%1<;l?rD2De`J5akA=R5fEO6M_)4_DS!XPvwuOdi4B{Ux!9sNh$$u_d zS)OBdd?0Y!p)$$(1!IY!2+pA4Y~I4`=;(8?l=WK$N$U&4k3s3u>51iTE9v9{&Qp;M zb#ZIoE@~@xJXw9%(kEf|eCtki!zX-G)rX^Um(82``C8MT3Lbc){AQkN9F`#7byh_Y z88nH#ve?oaX{s%n3^p5+Jcrv5XO!RteVP`?dk5CheoZ?Qcv|RL7fBcf9DU^P&narL ziXVd`>^jWmzJ9{nEYAW3`OFlUU`)}I%W)`U$N2i1&nGex9W0&*^;Bw({C^|)X(V#C z+;r2zC4f*~5T{h}eJT33E4Ig9cX?z`#~gFGETQjwh2+I^RWX*dPFfvyZ$=69ucq+! zp$bZ0;YMk%V_JJcOZ>(ffO@JSSXodk?xosD4k?(c@XRsi?uLRZuFPkO0~Xi9jclZB z#_RcOosW2{7JZ)!8&BPIs(*y<XVCC;YtRXyLu@aBr1NR}x;S+b(%K z)&y)~x*|0dVlCsCW&dVCa&V}>mL3>QPQ3~Li_SL^biV5Up!4?s({;Y8q5SJ_I{%%= zztH*r(JX%IJduZVICH)Qrg&&L?Z9u(simP@Bq{7*cfK0zUB9CkxlsCQFw#Oe``YdU zlcxob*c*{h71!=VMw1o#9JPvKeX0fMPNi3Wc_^!ejcHx#%_nusakoD&Vc(%v0^9;r zdhgheW@_7xl=#y+y|E~@QBgOXJ(>|Nv~!%DYfK<|}^`8&62 z8b;>cx@~?n=^PPEmG(!!8NF;JD#>TGRnW_M63-0_9tYQre-y)TbK4Uso^>B$Po@n@JApU#e<6s@rWlT^4-ckgO}{%cYsUKJ z6nqlyR9BU;wvK6|c0b3$&rfE&x7S*mSet+GmTzJ!|E+~xGL3;2iFWx)^?Zqp=&iIUQXq(va&J>@iHO< zI4lXM7Dh9Humfwm50UyUFH@A&kCfNcz$N+lxQ+wJ<~qRPx1+ROEEW4QKZfv;(E?Lv zvJR&0_}1>Wbn%#ecEVZpjtGFLg9m0(TKLfQbu-iKHO#o&2#6x@r#nncC;?+Kkk>Jr zKr&NymaipV{1v{?Jd#iu)OC8! z%6gGJQZ|sv=-BJBuOMQGOtKEc-*;%M)QwKDE11QHeMu>8_!g>n+HNmzQ~8b>qPZ2| zm>|J7<$r5&9(?24VBWx%YU^FO<6`#&>wNp9hT|(+FPs}WoNoH|Mo33D7EM=is8?*T zUaqjSw$y)}Io~9WZ6i|fe0*(=q=v^h=6=?Q7?Zcwkl_2H_3dU~vNpL;>6Q1%Uwr4k z^rl=wy1}Bedbw`CkdYJ!*s`f=n1mdT_6K_&Sc4VA6|GAB=3NzPMMQYCo>1&tB&DV= z?Czv5x=OFOGv-)JrseOv7?pGBq`8*MzP}HM!A2$gMdr!K2r_>_oYp@{+cRk=I~|*! zxAVyV1~TuIf>}I6EDUAuyaLz$M+!rIV>kxBH)q{u>`*SYP6!u-v-868A_-rhN0pBk z9FF!W^?_ITNQqbbR6t>{QX&IFUFbWHe<}+igP%MA&m>^iB_zKW(&YbINaJs&QCtmA zACjIISUV`0=@t&1G~N7I6;_mS|3hl1BA1sJC*9R^o3k=^qO!UpPSU5Y3;WCF(wQcu zncu-jr?=@1>PFsEczt4UXwidFPO{1;%&3#E#pJruiXF<;=BFpL zly85bDw=rh|FJtgSI{zTrEY<}t9&Z`A-ysXert|&L`-4bvQZhLufpZM-mIhSpeqOCS&#H| zdHrD2lcYIn$TL~*UqMx%SuY=g@-J?j=4!n7_m zRrkzS)pJ%w0Cf@E)~ci3NRyP%z|sx^nHwjPol>FYIo#hnZ&@{guXJu|i7D^;_!{3h z(h1UaD)WQbL3l=6!3_SvtDfm-%})y(C4$t?LpRf;ocu^);vJpq?E7vKib!LawoXFr zsA9q4(W4Wl3ro!NsJT4Wg;^w1{O8>H_yv$5^O>y8zz+IHdnp{7F`?dLtn>3Ze0GLu zDUQ?z#V!tj0RSIDh^gHNycU?xq<$d|&<)1k>o3*~5Yo;r&(>8)34f%A%VS~v%r_nc z9vA#x7vjShbgl>bpaRn9`%VsNB>H02;&3gWn%XkE+uGl}>1l88Z*c;jfQerX#2zzNDyR$uPTe@dmSnT2l2+7fRp;fgsz8%Mz??%BtmU7 zvw=6{?UQLB>;|!DhS;vn^_Wof2WvpQX4yel7~ae@A#sEaH;XAe8`5i!Yi)}rmWJMR zwIR6a7))$|O!naOZkERo0vA!rAfS})Q=adoqU%ynVyWn@RG(!AophjkAUt%Y5`Ya! zL{Ijlw20q840S(14>(rVRFJ95+))#@N>pyepbrKDg6jRydWuioCO5?kwHvPx*TIvD zv8m~unON|<;)d?$g=V7lUe0|}u|Zn?f(=h6jTg#K+oBdS8BdBSfIW4_Hz7-Ts^t%= z3{kJD+8RS|XduO{;gwZIBMGH5Q3lOeZL%JfG`Qsu^lbo;$qYiWh@bn`Qo zf~B116)$;^9q+G|d$-xK8aqv3gNA zomG9OI~ zx5qSj@~1SL$L5dXlaowHVm}7GsmWpDV~V?rRHeDkEk0q(^7`9A-HfIR3rHx$@WJT_ z@)rWUih}%=>Zh9|x-zhrDP?_5nXx1!pW0=)J8h}06Bb7ET__0kpYJ^WsVs==;3p4J z2dfpwNRdP~`|h48$kAJ*g;l3+E)Q=*vu0b$d??Si2Dv)(_qQs}wig}<+&0+j;-}s7 z6YJ;tlAduU<-_q4Q7_R?6zA{v7QGm3c3KuCHw#o1 z<{@S_60hf&GVfV1rVp2l#5cw+j@C=wP^R10sxrz_JQri(F}&AsTx-JjS5hxC8=mxOQWMLP*=;oFBswOK{N_ZtQCPAG~< z|KAz{{h6L`fgRM3Ui>RVVEADO48I#f-miv0|EnSV3o`(Bxh{th8H7P}!ca=bc|kW4 z5`c!ul0YswIgFdw7DQB3M~AZG5~)(4Z<+EZPQF;yVR|1Y86FK~6(zyiGmSN;G|qFw z$|;!6v0fdPsOrEqotBgpgmqYoiPg%GuaaHO=k4rm-${S)AQ5ZyN{PLNDE^m-;!o+$ z8J3UZiAa2}#LRcPJqwl5|CH3n25T*TKAtT}W<~%t_c_;?Z;ojuXOVw?KI>#~SB9U$ z#@nH#t}p&YBY0Pvgy~n0kM;_$=?ve>z9TjoTDUpC!#=v*aA$>qlK&&;)Vq_2tW;q= zBWd=P=#<@)k9cW*R3W~r?7)U_Upth9PreLXJszGmy88ltToU~Tq*<)iFvCZtS} z@3sq7v+zsPFZ6zwRL_Sh@OyWEN`HxH9qW#i*2vSbZm)OkhFpB<%CeXnxH0wR;AlwC zs;1zuw235s<+PbzI=d_r>nFU4;PR0|<)c}K6=>2U3Zeu<2qf%V2#AR6w1|Wl5R@hEND!3Gh-^keCtz3< zPy`*Logj+{LPt;_!XPe)N)Hfi1!WThLdyhctD4FDn7?zYPSsaWopZnQyyw)d3j#}z zgF0Y6%LafX>^G7xkwid20hEgq1c+oTA29#~SRBi_3UE*{P41HPRdiM03c&n6Nd|@i z;0jfU92A}h%CQt2bC(uC=2!||f7Kw!QlR`*0{~0G>BpR8mICodox)OZ{!yp0lu5aY z(#B8@(akvol(zm`TM%5_OU;kA4xqgEDn|$iI;{XufKZ+YlS2W(cLb3|P+0_%MJr?x zTo%d6qLs2pei>S30(?*P-hY}XEL-v2L{SzYWRa3AQkF$3vPkuB2n2jI93cQ8MF?r2 z&T?{4=?wsu=wirA6j-AF#Rnoio&R$u7@#bbPz8<{9tICBpkWc+VGH*_CIABl;Y?r> z0Ktf&zuRL$Uj5cGaszcU_&g_vpkCUriKMi5yDhI* zXk+URB|@Q4A`$1FYT%+jJWdJQN1;)NBNm;3jH6g{tf}dZ;>noZ6Ow&At)lSRh&b!0 z=FsV$FcQ{oNSV$W-Z@kNK*)V{b~@UZJB1;)@EN&rFw_-%+R5!;~bIc7mSZ zE`wWUGcUQK9QJfYO~ag*?x9LS8k`#)SzZ;;dHlR9-(PKWcvd#i;S} z<9+?3Wq-bWvgn+B=4hA4P-*>w6I#M zv@ZC+&1qM+3!(Xk&)2^=8QM6Cgs1MtE63nn0s>-PT-Z*j3D6*&fuu^2Nm+UM{p}(4 zb%w4O4Br`}&$sZ#5OA(d7C2i^z5FVNbL~&`Enf9u-@Mp^v8;aRpmMY5wugL`t$kgs z1BPeO<-jwnyP@-7Bh-#LGNY@zz`tdJyS+B4HsBXhrvofp)k~+9id}Rbhqx*JYJs%C zw?`!Rctq}`hLfwvRwnBUkni<58kWNb;ct_&$f&l~6}@dOFT%FA2pb%d&Z=B!UE>gt z+QYvAQEUQvAORWS#FY!(qQ0S~K6%5oJ;e_c@^w44^3f)dxciz22M~SPD=(E@RNz>N zcg+zqh&inb1X}KWCEHowj&9Z5C3v#X`|+Yz%@E>z(RZ@?@$ma*&72oVSe&F6E1d0@xw0rT@6TE)ngaXha_it`DAU`BbXewq;fPSobnw7vCH`I`AYYjj?F=6v%D;?#+62dV)x**9XPACD+1g+c+T1_qK|7gP~M2zO(=f)_@2UPec^?6};_ zP=ixZ${dr^*T}buQ%;@=jPxecBFX30p9i(KF@o~@^aoa))BgSA0mCSi(jZnbvv%gL zVH}-dvFL0RS8oVAYh+>lVKo^%<>%P(mOON+NVYGCLEB#amt?79@T01-A32XG`b}6H~>N>dLg;4I6M?@26%Z zx^?SyxkYRCo!7K_1pvbwXF%!{N)4lUNwp{=Q}$DFL+@;TH?4Ukh;t3U)bnm?40nWR zinq3GUuSfzwi)5KL0R~TRQXFhx$+!6o(*Tf;cx~coUKs2HOnD%OL7lf{67b>=)63X zXw=Go9k!gCI|H+{Iy)n$+rD~RDy-lP=~g}X2LMNrZN>e9!Lbgqv6X1DYdrQ@O52Ak zk20tUt?K9#3H~nxF^^lSeB-UQ^6ib^lUqMKb6q+2Okz`rRizJSYo<=k?}|>4$Tux~ z&QwWwW>ey2Ic+tRqd&^}iJQQ74GE;}-iV~{nzq96CPv(%qBjYT$*=z8o4EhV-C_^Q zf$?ercdhY==RvyUvgz+W2cEv+H?As4JE&(96>S*5|FEPiomVhDQgV%Vt@}elajbWD zy8(ulkw2foeZ)v<<&e=AH8-DN0)D{Qm&~=6;>>ck(fGskuJL1LWW9Rcz1&pZ$Db33 zMICqgT<5AQkc#g{vu4J0Uw<7gbpHBlNAg*ltyepvnJ>L2f})ECulsN2>I^lNLxAqO Kn+KMD1pf{HhRn|Z literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_card/testfile2 b/src/tests/fuzzing/corpus/fuzz_card/testfile2 new file mode 100644 index 0000000000000000000000000000000000000000..cd45339239403e506605749b623e759b05151fe3 GIT binary patch literal 1432 zcmZQ%fB*#{2J6~s3=9p14XGQN1%=l%GfZG$V#pd3f6>O zkcoxC1R`x>#_&P(BjYE=&jPsN7sjuQ-vqxi{9^dc@Q2|q!#{{#pebC8AeSY6_{0FT zm7$WE$)O;i$c&GHA!09sj^tKFMX)d<({HBVKzSfo0K}DyO#hhvfp~EKU#7n(e4wEy zd`2clBt8ox1C$FfkA)EkP~@2yp$04f1qP!5g8@Vuq#npm5J2M_pz;f>rP`f$1Dsc?L#S0VXykW(P*bKtV^Kf1Fqu9{E4PJeA@mp(sWo2#cX2%}I?TqTu#TwkR4T3W^ENp3%=s2u;Mt+s}n&l7X#ZQZx zGJW=}@T3#T2UsUP6iX{RS?>6VwW3<8OS+?};>@8My?=UKaq|?bi)i#Z-=+Pdw zX>4k2Zfpqxs^_vZSe{5pNzRU%73C%=5`4IfMc?Gc`GA8Ce2>IFPPm|8e_g>g{G#Uy@BpIU3a@9l-Sn@f)tJTJM-(rjhMmur?V zDJeZAMbk*bU_*L<9(O>@NhN^{4mxR`@{6e;Ow|?2wzF*5f`Rr7& zeHWv*EzkIM?WB6Wm)W&vdi|5Lf9-dEHSfcpFKf%fT(?(j-}7z$_J?a%tY6!6Z{uuR z-Idp0g&nKpD6TCmw4Jd#^IhRIbwRQFTKDc6eO()V`IPDJ&`lN&C7Z*-r@a#Yy>(~U L!pJ0 Date: Wed, 9 Mar 2022 11:06:30 +0100 Subject: [PATCH 2365/4321] Check arguments instead of asserts --- src/libopensc/card-muscle.c | 14 ++++++-- src/libopensc/muscle.c | 66 +++++++++++++++++++++++-------------- src/libopensc/muscle.h | 6 ++-- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 7dfe9ddbbe..3a0075d559 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -552,7 +552,9 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_CHV: { sc_apdu_t apdu; int r; - msc_verify_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len); + r = msc_verify_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len); + if (r < 0) + return r; cmd->apdu = &apdu; cmd->pin1.offset = 5; r = iso_ops->pin_cmd(card, cmd, tries_left); @@ -572,7 +574,10 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, switch(cmd->pin_type) { case SC_AC_CHV: { sc_apdu_t apdu; - msc_change_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len, cmd->pin2.data, cmd->pin2.len); + int r; + r = msc_change_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len, cmd->pin2.data, cmd->pin2.len); + if (r < 0) + return r; cmd->apdu = &apdu; return iso_ops->pin_cmd(card, cmd, tries_left); } @@ -588,7 +593,10 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, switch(cmd->pin_type) { case SC_AC_CHV: { sc_apdu_t apdu; - msc_unblock_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len); + int r; + r = msc_unblock_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len); + if (r < 0) + return r; cmd->apdu = &apdu; return iso_ops->pin_cmd(card, cmd, tries_left); } diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 1f8ef33e86..7af279a0aa 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -288,9 +288,13 @@ int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe const int bufferLength = MSC_MAX_PIN_LENGTH; u8 buffer[MSC_MAX_PIN_LENGTH]; - assert(pinLength <= MSC_MAX_PIN_LENGTH); - msc_verify_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pinValue, pinLength); + if (pinLength > MSC_MAX_PIN_LENGTH) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + r = msc_verify_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pinValue, pinLength); + LOG_TEST_RET(card->ctx, r, "APDU verification failed"); + if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); @@ -311,11 +315,10 @@ int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe } /* USE ISO_VERIFY due to tries return */ -void msc_verify_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength) +int msc_verify_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength) { - assert(buffer); - assert(bufferLength >= (size_t)pinLength); - assert(pinLength <= MSC_MAX_PIN_LENGTH); + if (!buffer || bufferLength < (size_t)pinLength || pinLength > MSC_MAX_PIN_LENGTH) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); truncatePinNulls(pinValue, &pinLength); @@ -324,6 +327,7 @@ void msc_verify_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bu apdu->lc = pinLength; apdu->data = buffer; apdu->datalen = pinLength; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukLength, int *tries) @@ -333,9 +337,12 @@ int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukL const int bufferLength = MSC_MAX_PIN_LENGTH; u8 buffer[MSC_MAX_PIN_LENGTH]; - assert(pukLength <= MSC_MAX_PIN_LENGTH); + if (pukLength > MSC_MAX_PIN_LENGTH) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + r = msc_unblock_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pukValue, pukLength); + LOG_TEST_RET(card->ctx, r, "APDU unblock failed"); - msc_unblock_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pukValue, pukLength); if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); @@ -355,11 +362,10 @@ int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukL SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_PIN_CODE_INCORRECT); } -void msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pukValue, int pukLength) +int msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pukValue, int pukLength) { - assert(buffer); - assert(bufferLength >= (size_t)pukLength); - assert(pukLength <= MSC_MAX_PIN_LENGTH); + if (!buffer || bufferLength < (size_t)pukLength || pukLength > MSC_MAX_PIN_LENGTH) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); truncatePinNulls(pukValue, &pukLength); @@ -368,6 +374,7 @@ void msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t b apdu->lc = pukLength; apdu->data = buffer; apdu->datalen = pukLength; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength, int *tries) @@ -377,7 +384,8 @@ int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe const int bufferLength = (MSC_MAX_PIN_LENGTH + 1) * 2; u8 buffer[(MSC_MAX_PIN_LENGTH + 1) * 2]; - msc_change_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pinValue, pinLength, newPin, newPinLength); + r = msc_change_pin_apdu(card, &apdu, buffer, bufferLength, pinNumber, pinValue, pinLength, newPin, newPinLength); + LOG_TEST_RET(card->ctx, r, "APDU change failed"); if(tries) *tries = -1; r = sc_transmit_apdu(card, &apdu); @@ -398,13 +406,12 @@ int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLe } /* USE ISO_VERIFY due to tries return */ -void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength) +int msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength) { u8 *ptr; - assert(pinLength <= MSC_MAX_PIN_LENGTH); - assert(newPinLength <= MSC_MAX_PIN_LENGTH); - assert(buffer); - assert(bufferLength >= pinLength + newPinLength + 2UL); + if (pinLength > MSC_MAX_PIN_LENGTH || newPinLength > MSC_MAX_PIN_LENGTH + || !buffer || bufferLength < pinLength + newPinLength + 2UL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); truncatePinNulls(pinValue, &pinLength); truncatePinNulls(newPin, &newPinLength); @@ -422,6 +429,7 @@ void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bu apdu->lc = pinLength + newPinLength + 2; apdu->datalen = apdu->lc; apdu->data = buffer; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData) @@ -435,8 +443,8 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short cse = (location == 1) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT; len = seedLength + 4; - assert(seedLength < MSC_MAX_SEND - 4); - assert(dataLength < MSC_MAX_READ - 9); /* Output buffer doesn't seem to operate as desired.... nobody can read/delete */ + if (seedLength >= MSC_MAX_SEND - 4 || dataLength >= MSC_MAX_READ - 9)/* Output buffer doesn't seem to operate as desired.... nobody can read/delete */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); buffer = malloc(len); if(!buffer) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); @@ -510,7 +518,8 @@ int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int alg unsigned short prRead = 0xFFFF, prWrite = 0x0002, prCompute = 0x0002, puRead = 0x0000, puWrite = 0x0002, puCompute = 0x0000; - assert(privateKey <= 0x0F && publicKey <= 0x0F); + if (privateKey > 0x0F || publicKey > 0x0F) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x30, privateKey, publicKey); @@ -673,7 +682,8 @@ int msc_compute_crypt_init(sc_card_t *card, short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; *outputDataLength = receivedData; - assert(receivedData <= MSC_MAX_APDU); + if (receivedData > MSC_MAX_APDU) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); memcpy(outputData, outputBuffer + 2, receivedData); return 0; } @@ -723,7 +733,9 @@ int msc_compute_crypt_final( if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; *outputDataLength = receivedData; - assert(receivedData <= MSC_MAX_APDU); + + if (receivedData > MSC_MAX_APDU) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); memcpy(outputData, outputBuffer + 2, receivedData); return 0; } @@ -825,7 +837,9 @@ int msc_compute_crypt(sc_card_t *card, int r; size_t received = 0; - assert(outputDataLength >= dataLength); + + if (outputDataLength < dataLength) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); /* Don't send data during init... apparently current version does not support it */ toSend = 0; @@ -886,7 +900,9 @@ int msc_import_key(sc_card_t *card, sc_apdu_t apdu; int r; - assert(data->keyType == 0x02 || data->keyType == 0x03); + if (data->keyType != 0x02 && data->keyType != 0x03) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + if(data->keyType == 0x02) { if( (data->pLength == 0 || !data->pValue) || (data->modLength == 0 || !data->modValue)) diff --git a/src/libopensc/muscle.h b/src/libopensc/muscle.h index 7f8f4fdd54..e87bebc10e 100644 --- a/src/libopensc/muscle.h +++ b/src/libopensc/muscle.h @@ -47,11 +47,11 @@ int msc_delete_object(sc_card_t *card, msc_id objectId, int zero); int msc_select_applet(sc_card_t *card, u8 *appletId, size_t appletIdLength); int msc_verify_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, int *tries); -void msc_verify_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength); +int msc_verify_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength); int msc_unblock_pin(sc_card_t *card, int pinNumber, const u8 *pukValue, int pukLength, int *tries); -void msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pukValue, int pukLength); +int msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pukValue, int pukLength); int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength, int *tries); -void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength); +int msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength); int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData); From 847ccabd898f31d2ade49cbfd11fef083ee9e84a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 9 Mar 2022 17:15:34 +0100 Subject: [PATCH 2366/4321] Add function for connecting to virtual fuzz reader --- src/tests/fuzzing/fuzz_card.c | 19 ++--------------- src/tests/fuzzing/fuzz_pkcs15_decode.c | 20 ++---------------- src/tests/fuzzing/fuzz_pkcs15_encode.c | 17 +++------------- src/tests/fuzzing/fuzz_pkcs15_reader.c | 18 ++++------------- src/tests/fuzzing/fuzz_pkcs15init.c | 20 ++---------------- src/tests/fuzzing/fuzzer_reader.c | 28 ++++++++++++++++++++++++++ src/tests/fuzzing/fuzzer_reader.h | 2 ++ 7 files changed, 43 insertions(+), 81 deletions(-) diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c index 1d92243837..4e0bd3950a 100644 --- a/src/tests/fuzzing/fuzz_card.c +++ b/src/tests/fuzzing/fuzz_card.c @@ -29,7 +29,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { sc_context_t *ctx = NULL; - sc_card_t *card = NULL; + sc_card_t *card = NULL; struct sc_reader *reader = NULL; unsigned long flag = 0; const uint8_t *ptr = NULL; @@ -57,22 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (!ctx) return 0; - /* Erase possible readers from ctx */ - while (list_size(&ctx->readers)) { - sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); - _sc_delete_reader(ctx, rdr); - } - if (ctx->reader_driver->ops->finish != NULL) - ctx->reader_driver->ops->finish(ctx); - - /* Create virtual reader */ - ctx->reader_driver = sc_get_fuzz_driver(); - /* Skip bytes used for flag and len*/ - fuzz_add_reader(ctx, data + sizeof(unsigned long) + 1, size - sizeof(unsigned long) - 1); - reader = sc_ctx_get_reader(ctx, 0); - - /* Connect card to reader */ - if (sc_connect_card(reader, &card)) + if (fuzz_connect_card(ctx, &card, &reader, data, size) != SC_SUCCESS) goto err; /* Wrap & Unwrap*/ diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index 28bf0c79af..11951a396d 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -48,24 +48,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) if (!ctx) return 0; - /* Erase possible readers from ctx */ - while (list_size(&ctx->readers)) { - sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); - _sc_delete_reader(ctx, rdr); - } - if (ctx->reader_driver->ops->finish != NULL) - ctx->reader_driver->ops->finish(ctx); - - /* Create virtual reader */ - ctx->reader_driver = sc_get_fuzz_driver(); - fuzz_add_reader(ctx, Data, Size); - reader = sc_ctx_get_reader(ctx, 0); - - /* Connect card to reader */ - if (sc_connect_card(reader, &card)) { - sc_release_context(ctx); - return 0; - } + if (fuzz_connect_card(ctx, &card, &reader, Data, Size) != SC_SUCCESS) + goto err; sc_pkcs15_bind(card, NULL, &p15card); if (!p15card) diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c index 3f1137cd39..073a041cfc 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_encode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c @@ -33,7 +33,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) struct sc_context *ctx = NULL; struct sc_card *card = NULL; struct sc_pkcs15_card *p15card = NULL; - struct sc_reader *reader; struct sc_pkcs15_object *obj; unsigned char *unused_space = NULL; size_t unused_space_len = 0; @@ -41,23 +40,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_establish_context(&ctx, "fuzz"); if (!ctx) return 0; - /* copied from sc_release_context() */ - while (list_size(&ctx->readers)) { - c_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); - _sc_delete_reader(ctx, rdr); - } - if (ctx->reader_driver->ops->finish != NULL) - ctx->reader_driver->ops->finish(ctx); - - ctx->reader_driver = sc_get_fuzz_driver(); - fuzz_add_reader(ctx, Data, Size); + if (fuzz_connect_card(ctx, &card, NULL, Data, Size) != SC_SUCCESS) + goto err; - reader = sc_ctx_get_reader(ctx, 0); - sc_connect_card(reader, &card); sc_pkcs15_bind(card, NULL, &p15card); if (!p15card) - goto end; + goto err; for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { u8 *buf = NULL; diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 0d7911eacc..36ed08a4e7 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -32,26 +32,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) struct sc_context *ctx = NULL; struct sc_card *card = NULL; struct sc_pkcs15_card *p15card = NULL; - struct sc_reader *reader; + struct sc_reader *reader = NULL; struct sc_pkcs15_object *obj; sc_establish_context(&ctx, "fuzz"); if (!ctx) return 0; - /* copied from sc_release_context() */ - while (list_size(&ctx->readers)) { - sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); - _sc_delete_reader(ctx, rdr); - } - if (ctx->reader_driver->ops->finish != NULL) - ctx->reader_driver->ops->finish(ctx); - - ctx->reader_driver = sc_get_fuzz_driver(); - - fuzz_add_reader(ctx, Data, Size); - reader = sc_ctx_get_reader(ctx, 0); - sc_connect_card(reader, &card); + if (fuzz_connect_card(ctx, &card, &reader, Data, Size) != SC_SUCCESS) + goto err; if (SC_SUCCESS == sc_pkcs15_bind(card, NULL, &p15card) && p15card) { @@ -135,6 +124,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_card_free(p15card); } +err: sc_disconnect_card(card); sc_release_context(ctx); diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index ce2022006d..31f3fc0427 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -298,24 +298,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (!ctx) return 0; - /* Erase possible readers from ctx */ - while (list_size(&ctx->readers)) { - sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); - _sc_delete_reader(ctx, rdr); - } - if (ctx->reader_driver->ops->finish != NULL) - ctx->reader_driver->ops->finish(ctx); - - /* Create virtual reader */ - ctx->reader_driver = sc_get_fuzz_driver(); - fuzz_add_reader(ctx, reader_data, reader_data_size); - reader = sc_ctx_get_reader(ctx, 0); - - /* Connect card to reader */ - if (sc_connect_card(reader, &card)) { // last op with card in open_reader_and_card - sc_release_context(ctx); - return 0; - } + if (fuzz_connect_card(ctx, &card, &reader, reader_data, reader_data_size) != SC_SUCCESS) + goto end; /* Load profile and bind with card */ fuzz_pkcs15init_bind(card, &profile, data, size - reader_data_size); diff --git a/src/tests/fuzzing/fuzzer_reader.c b/src/tests/fuzzing/fuzzer_reader.c index 78ea6e8e63..879c71a25e 100644 --- a/src/tests/fuzzing/fuzzer_reader.c +++ b/src/tests/fuzzing/fuzzer_reader.c @@ -170,3 +170,31 @@ void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size) reader->ctx = ctx; list_append(&ctx->readers, reader); } + +int fuzz_connect_card(sc_context_t *ctx, sc_card_t **card, sc_reader_t **reader_out, + const uint8_t *data, size_t size) +{ + struct sc_reader *reader = NULL; + + /* Erase possible readers from ctx */ + while (list_size(&ctx->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); + _sc_delete_reader(ctx, rdr); + } + if (ctx->reader_driver->ops->finish != NULL) + ctx->reader_driver->ops->finish(ctx); + + /* Create virtual reader */ + ctx->reader_driver = sc_get_fuzz_driver(); + fuzz_add_reader(ctx, data, size); + reader = sc_ctx_get_reader(ctx, 0); + + /* Connect card */ + if (sc_connect_card(reader, card)) + return SC_ERROR_INTERNAL; + + if (reader_out) + *reader_out = reader; + + return SC_SUCCESS; +} diff --git a/src/tests/fuzzing/fuzzer_reader.h b/src/tests/fuzzing/fuzzer_reader.h index 6267f9acda..fd39f29694 100644 --- a/src/tests/fuzzing/fuzzer_reader.h +++ b/src/tests/fuzzing/fuzzer_reader.h @@ -23,3 +23,5 @@ void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size); struct sc_reader_driver *sc_get_fuzz_driver(void); void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size); +int fuzz_connect_card(sc_context_t *ctx, sc_card_t **card, sc_reader_t **reader_out, + const uint8_t *data, size_t size); From b4fd86cdbdb06d022b9a03bca6e2b43b4906fbd6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 22 Mar 2022 16:11:53 +0100 Subject: [PATCH 2367/4321] fuzz_pkcs15_decode: Use one buffer to all tested operations Fuzz target uses the first two bytes of fuzzing input as the length for a buffer that is supplied to the tested function. The rest is set as data for the reader. --- src/tests/fuzzing/fuzz_pkcs15_decode.c | 42 ++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index 11951a396d..4011ba5c1d 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -24,13 +24,33 @@ #include "libopensc/pkcs15.h" #include "libopensc/internal.h" +uint16_t fuzz_get_buffer(const uint8_t **buf, size_t buf_len, const uint8_t **out, size_t *out_len) +{ + uint16_t len = 0; + + if (!buf || !(*buf) || buf_len < 2) + return 0; + + /* Get length of the result buffer*/ + len = *((uint16_t *) *buf); + if (buf_len - 2 <= len) + return 0; + (*buf) += 2; + buf_len -= 2; + + /* Set out buffer to new reader data*/ + *out = *buf + len; + *out_len = buf_len - len; + return len; +} int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { size_t i = 0; struct sc_reader *reader = NULL; - const uint8_t *buf; - uint16_t buf_len; + const uint8_t *buf = Data, *reader_data = NULL; + uint16_t buf_len = 0; + size_t reader_data_len = 0; static struct sc_context *ctx = NULL; static struct sc_pkcs15_card *p15card = NULL; static sc_card_t *card = NULL; @@ -43,12 +63,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) }; int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC, SC_ALGORITHM_GOSTR3410, SC_ALGORITHM_EDDSA }; + /* Split data into testing buffer and APDU for connecting */ + if ((buf_len = fuzz_get_buffer(&buf, Size, &reader_data, &reader_data_len)) == 0) + return 0; + /* Establish context for fuzz app*/ sc_establish_context(&ctx, "fuzz"); if (!ctx) return 0; - if (fuzz_connect_card(ctx, &card, &reader, Data, Size) != SC_SUCCESS) + if (fuzz_connect_card(ctx, &card, &reader, reader_data, reader_data_len) != SC_SUCCESS) goto err; sc_pkcs15_bind(card, NULL, &p15card); @@ -57,14 +81,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) for (i = 0; i < sizeof decode_entries/sizeof *decode_entries; i++) { struct sc_pkcs15_object *obj; - const u8 *p = NULL; - size_t len = 0; + const u8 *p = buf; + size_t len = (size_t) buf_len; if (!(obj = calloc(1, sizeof *obj))) goto err; - fuzz_get_chunk(reader, &buf, &buf_len); - p = buf; - len = (size_t) buf_len; - while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, (size_t *) &len)) { + while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, &len)) { sc_pkcs15_free_object(obj); if (!(obj = calloc(1, sizeof *obj))) goto err; @@ -72,7 +93,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_free_object(obj); } - fuzz_get_chunk(reader, &buf, &buf_len); for (i = 0; i < 4; i++) { struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey); if (!pubkey) @@ -82,12 +102,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_free_pubkey(pubkey); } - fuzz_get_chunk(reader, &buf, &buf_len); tokeninfo = sc_pkcs15_tokeninfo_new(); sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, buf, buf_len); sc_pkcs15_free_tokeninfo(tokeninfo); - fuzz_get_chunk(reader, &buf, &buf_len); sc_pkcs15_parse_unusedspace(buf, buf_len, p15card); sc_pkcs15_card_free(p15card); From b35993db095c14be95fc0f40b96b44e2850b7990 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 23 Mar 2022 09:28:23 +0100 Subject: [PATCH 2368/4321] Add corpus for fuzz_pkcs15_decode --- .../0204f84aede3986d1add8909124e021cac32bec8 | Bin 0 -> 1472 bytes .../0e9c8b959346f4894ea97d7e3f393c2442ee1e3d | Bin 0 -> 3236 bytes .../6e580d278c33a530284dfef5dd9ffd617597bb68 | Bin 0 -> 3861 bytes .../8989be8baa0b0269c8128729062b31f91b131ba4 | Bin 0 -> 3687 bytes .../b011d577451c835fd8f6052f0659337994273f3f | Bin 0 -> 2718 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0204f84aede3986d1add8909124e021cac32bec8 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0e9c8b959346f4894ea97d7e3f393c2442ee1e3d create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_decode/6e580d278c33a530284dfef5dd9ffd617597bb68 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_decode/8989be8baa0b0269c8128729062b31f91b131ba4 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_decode/b011d577451c835fd8f6052f0659337994273f3f diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0204f84aede3986d1add8909124e021cac32bec8 b/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0204f84aede3986d1add8909124e021cac32bec8 new file mode 100644 index 0000000000000000000000000000000000000000..c57cad01891c8e7b60e37893f46be32788900351 GIT binary patch literal 1472 zcmV;x1wZ;P05B~u3=9TpYGrI?ZUX`bfG`6D0Rf>HFct#>0|*KM0RjO80s$Zb0U&?@ z00aU582~%~6afE$G5$q>C7=KR09IF1LpC)q0|Ph$0FVFz0BryU01p8H0gwO!0FVF> z0D3S000005Cjb9H06+kc0P+9<002i*P6ki_LI6+#DF6Wl5&#rd#AN85K^Mn-N{1_Licbpus4=1>+c9=YPIWWA!)l#Ij@z2y8{h2YfW(xS|g zN(Gnv+{Da0LwN&PkV0l2F=t1GV5p_esYNB3X_?81C8-8-;=G1t2IhvQMh2$lrWR4+ zyhesVt_hTD;BF{lAOtaj+bc1kzqPp_?|O52H#Uo%C43( zi7GCTKC6HKTw8s+M8@*L(Sv2WKV@u|6#bdivsNtVYW$3#-E&(!SoWX&Vf@78Qs`~2 zvy1tk)NNXvrsp!Tis_B^QYL0b2FAtJ29*YUKu^i?Gcx{XVPR%sJ76FK;tR5f8VENE zLOkMt2yJlK%JQ*@v55F7UNU0tPQI@%kOvA>dnIo zd~eS*)itPG2(DT6ktOP40Q02%Il5o66cqo7%4WEP7H#j>P?`Pk0 z2rZwQoDTd2VCAM$zyV`+}SA`}|gEiu4s8-uvKig@?FLTBKpbrt8zh46==Z z`GJRFAp=9U5s)R!xRHU80f-nuSt;2FoTDbea+D-6lND7Klw{`T5tXU5=#{A~3=EMo z6^KipOm(K>#ii`!b8M{wY*s(rlKe^R>~3RkuLsXt>W!wfsLzXhbh&|pcVb=1p#s*w zLdlQ*yA*odV`wp`sB*ghv?C%Jo(uYcjDW9R`uAm99?&CF^){dsz7w6`t^Ix z`tHNG{P!(faZ~=PaPV2*9rq~BR5JFwMMoCBStn`S@4Ywqp~}Sf#l6$Jb1EW|*Yv9! zJqn90OBQQ56MNF-QfAV!(5vM$zMf%taLqQ-NXpxJ-~D(-rJWNd8MARrQuF`jaw_BA z*1To+^BOb$uPV7#wS#-2#?sn2@!u0q>fXp&&0v_d>|$Lk)5r5cnc0D|u2srQVtQ|P zi65V+6<>2ewCeN(2Gx6O#oQgFJ;H?k_y|SEZxspO6nw?;bcmFY0C)iFkMcT=3tlY; zDh&QJxPQFqcO~Rho9dD!_3ckMWd#&x@omqL+P`vB_ryINd)y~a-Lb>+<*n5Cg<_#i z8%`hE8W6M0>FVso!ZVgK#qLaO+QAt=eflfQ$lfdS(|WT_LD?o?5inDk02u-cHz8#z a0FB#b@{j-m0Gtv60FVFz0FVFz0FVGVh`j^= literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0e9c8b959346f4894ea97d7e3f393c2442ee1e3d b/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/0e9c8b959346f4894ea97d7e3f393c2442ee1e3d new file mode 100644 index 0000000000000000000000000000000000000000..e3183ae0c6ee97765097f7985fe68ec7d1ce64a3 GIT binary patch literal 3236 zcmd^BdpuNW82-*Vb8#7sl3OlKq#NoxOpRHWV$i5021P9nrjT2jvCYzErV=BiWV=a; zQt8fOTV;!cL2Z<7yKUNyRf#s;w#%Mz%i3-K=-=k|JHI*abI$jj_kF(SdB4vSKo4lZ z(B~0xp)4K|O9Y2UhKnRDUQD!z2#*%V!Abw~kft7#%twS69g!{uximGDCoPi0Ws2p27o3&fQ0Tr-3I`sk^$7fH={h%l>xyR z0aW^)2Tnt0fefHC`0Stfr;Pd7TvR~8=ow^|5wefHq6P%EP`|m2dyAOP0V}f~a~oIg zSsS)!oQjj?x^Xs6nw33lO@X`FRj0`lY#yGzZ>)Rtgz}Bt`y;VP)7-44CYXn#dCzlx*9kaa>zQk>>1WJ{<<1gWKmY! z{t#N@O!B+EAE8A=2qT5j1AsbX7=R4`(2vZ5PNv#uk0Lac-Wv>|V@`llf9kpal41&D zMX~g(M|)Go8i8NH!TP;xdV*99ty>pfogCGssMuRr!P*y1ya&ht9iJx^N)Zgw(V98= zd_wW-h#!fp@y9abM9Hobb1L&p;W#*!TplA+3c1EfqaVk`-`D7h{nkIB)Y-_m+pa0s z{@5_xU@`;&dg*5xI-fh<&Sb8yTVKSdyPkJh5}4O%SNP!PCPfOn3;i?2iL>cuHs=Q4 zMQb<3@{hQ!_VyPXLM}w*^z8JB8B<+9(mC^5X6o1ZMa>PKyAmHsBHeczZqQ8(4cIWr zU9I#PSL4jmd}_u)Z&#Mtx!F7|(fw_<&&<1ON4QnT{+#yx0+{bCp84C{F|BR~W-{bU zug6?X9zXSE`4g?Otu@`+1;&(mr!=l}BJpJ)uu>G3+&C-Oo0I)K#96S^XtkN6z`Snt z1&gyMa~zvepGo7#blY7LtNK2B{CXK>DqAP3A))0=Mp$0dq8*BrqYZ3_~M$ z?HGLVl_P1#J#s>8zh~ZICw}9R$Cfy+omew3*VH_o7)@0(nY*~7bBnFb-ImN1^=-kw z)>;ImU96g2^UGA8d-0_g`JSeid*p5R*meBwDce0}+;v{p^8T-R`t~TVhbc{NW4@fI z#gSAH$CRe)ql3)hGo*qjDFcIajC~kZTQQ@@RJ}LmM`XdBle6YCHrG6h4S?!bdpZeyX{Y0!*-AK-qgbaq_wXyUN3F zB^B$9mKEi+$6AD94?*d7C6%15?;lJ{&?;}-RpXWBQ|jAuWP;h7GXcyZ%esB9MNh(` zEY(*9cqi*T*!k3GlZqeRZ=R>iDa`Gbr%CfQLC%N6An{L(UQtTuXs8) z9e%gKGsGWcD18|#?SfL`&mQm?N^hVD7~171A+~-s~bOzI%JV<14vWWew+&3S-0;L)+Sp&|e8J zhH3dY*;B(gymM_jai*g;1{uiH7B|!R`fi(A<;N?l>8`ryR3K+sRYXIcKo Kj@c*(sr(!4*dm_* literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/6e580d278c33a530284dfef5dd9ffd617597bb68 b/src/tests/fuzzing/corpus/fuzz_pkcs15_decode/6e580d278c33a530284dfef5dd9ffd617597bb68 new file mode 100644 index 0000000000000000000000000000000000000000..81d9710d788d1c639ab7118137c13cf427c25384 GIT binary patch literal 3861 zcmbVO2{@E%8~$d-OebctWp~Pw-I%crlWnAktVxoPT_;O}V+mzauB;Iz8f%g>A!8{f zYxaFDgi?r8vP>Fe{fCZoPW|UU=l}ojz257)?)Q1O`}w~6zMf$KO&CP)hjZv?>j>!| z71D9`_PyY8!O`B=8O_E720#!941$AzVK^`dltsu#6Udo_ds&1GGy=9)I{bL}G6Dnw zK>-LMhOtuwm_Pu?+48G?eSDCJ@}I7%!{$a!kMai6mZFNXrGCX<#u|w&A?|QBz06k1 zpSXxw`eF(v&!$9?ndd+1vFP$_8smSkylLY{J93NauY+n1&0n%S(|*wFuy=NJ$ko!JywZ$lOi_ z2o0eBn9soH*}lW*Z*kn8=QHlh!DxRvAH)IX*x}7D`1?iKw)4)&z;EX;UOO`o;GMVo zj|Tw|lno36LvSFF8M`)v&k-na05}QNVS=%NzNT?Ipg658C2 zl69THd$V4wOE`em>IKyJvOz_M6xHF`<-(x=o+q z_KkDX;(CO%28A^2nuSa(HFO}E1yfT^L~dBjVmyQppG2S*-FcQ-lt3Pzr(~A*GRR!l85wkBe>*c1#yC~*7*$|5wnlX=t-!5;TqSm|3FI~p2z!vg@)k=cI z2G>;PMm@*3)|s(&Y7Xt1hw1aO{sUUCDO1(~4Hv!y=iO`6u(`E*JNs5n6RBG|iBgJD zun|g8v3TOq7*9uSE%-NiCet%>;yFJn@S|JXGy_ImR z0oQ^99wa3+#z7M)JscW7oT8%j=Oj9(Sg#hmn~OTwN5?K$B}}*Ie_@?J=w(xG`IC0o zyQ~hW7rJ9nu^U+aCoM`V(WMhwi_lHD1k>e5^OjncJaVhhW%iW|s#)*P& z&J{^}U(C(Rsh2ukptIcJUupE(G5OIKx^HqH6)7n7RG|NeH2sKdU}B+RC9)cq-L$yF z`*9giXgi;e%KbPbrm7yvE4}K4hs_PIs)x)MuqJdSaaZ?RKgo4l9cY!fYJeG-lDm~~ zakWP0L;Aw{=K{ae$I1fADwi_K-WL2)SP=cXh@^oe4}Lh^6!?Qr2p+GITybFzPn2Ni z9+Q6kN`YQr+25wTW>Kt)^DQ}TN&LXG_LzD)%gRBpQf)@16bw8FHXaIcP*71;b&z*P zDx+2Hk@5_L#40%1BeAN=XpDn1dix3aC*6Z~bbsn^bzl6A?uWnAeTscg!zkr9-IL3j zzSsTj|4;XA{Kvx>x)=Ff_m8S$(>4Dq^&@_;b)#ftT_XrK92*zT(!TOY`*L-xcKV~s z;V_(aXJ-r&3Fn^{-2)Ysf%rJ0!n7SF%pFDRH`Dt^d8VAXj+Yx0_PlD7dX229EJu?-rA&`hzcJn(v ztUgz>A=OCh4{!URC@`pgIw9m-zhicwe}ZF!in)K;&oXksXSwWNQR%uA!}SdRSc!Wo zKc0{`#;lxKm}%1&chQA4H5x@r!0+Y-32M^R!Ws%9t^MLjKz$4rtg ztkGf?q7YMckklnZ(1qjYXoQY&SEu#vy1I@AKR}SHm|1omRtXz*Pu=TrV3&6^*)V!E z6;>>S*W{MxjxWxUj@0u?Mu&KAWlp9}RANoZ!@ZeBF)=zML~`8_AD`7jxHNq9d@$qz zMn=6$rpvIqep*wb92@OnVCwVfI~P!*K&j?&jUBc3%_Ph2mr9}@w`55wi-{H;MPar4 z34#JVJ*wPI;y&!+Q&6ya@Xh_>K;J%t!Qxa|5!ewJ7)`=j!L4w6U*I?ok=yP$WrjL2 za~kp~UTeHYoJl6}^6{NMl#DVV2A5{tE}HB1qppk`+(PpT4pmnUbzRADk99qY&t5C^ zOQSX#c@g*IxgDRa*yVllZNPlHu}!^9(8HC*QQ7-8H>O?2g3}g_OVa}NpVR2BbW2{_ z#9*qp-wZcBn^V*L5YhEpJaY^K9|I+75;~pn1cJ~!}+k+=@B(tFW0h--N z<;Ad^wz=0I=LIa&D<1XIetF;d!lMXI)YA0z+A2LaIoZyY(Lt?Wf?i2{GE?I>qMx)? zie0;#a8Ap7zl(ggThPanDEivC2TR7OJ#z7534%$SJPH=Gn6WwiDeX>td{WXgq1L#O(1aLl;tiu@DWxIPIvl*=Eyon=3zh-%OWmjw$hLN)P8s=0 z`8VL!ODu{NlNCZVaHR&q8F61*-Nl}r=PC~r)y?J#wY1YSIS6&tv(Y&L!QyQpCm@^< zQ3(1b$F#B%*c%ZOZG<#JX2T=NZ()Cw6e539QiNUmrlfeAe7!X`ac%9TbB;T=@`ow0 zEdy0wk80iJn3`ehbVV)cs@RkOWBMol5rt%nO6rBY7gv)4=E&;-Fv?u#c>GwlFkWJFpG{+iN z4h7Ke{hYS~uiP#wQW1iPk32(i6wi_lNhv8x-=K+HTW@>2Z10IyS>xyJogKXK z>c?>(>S`8g68WS%kwz8ozs_s6TpH?MSTQ*2ZsMxs=I%Jr;{thr_S4lRN{2B+RCvci z$(_u%79$n=7Z<1|te*QENgU5p*C)rpRh8rFkg9u=#SZ&Lh3ED=u`9A&*x!bfLbjbi zdP^D@wH{|&ysI0UYi(uB%?=TUfRbBNWy57NuiqqE>^MdF$9=BGzN}Tn?`HBn=vPP1 zUVY!1Lwyp@KxlFnuE+Kw+3b>djd+bi4_ux7|F-SC8SqUl6K->P{{1^V{)(5R4!Q0U03RZu%Pp0u10LJD?g!0DvI5AZJnt8%KT!5CcE}kAL{= znOT4fOxJg%0|3Z11Y~V5`s+am1EBb2S`h=xb1r}%!9~{p+&+O+aEWahSOsXn8n6y* zd|6A6!U%4i%zpkOK;IR(1cl%(ns{OM0>H^iK!*3RkkIxp2%$k}^m+P|PX8`}kPXPj z7W#(QA?x2^deHAMJwt!O3?T3oeu+mS_8-iU?cV*T0{{qPg}@!{ zh5`G5<1lRoI4k%ijav!*vWyV{c!C!J zVM%gYBSCkf%<|eZXH-!lBGS?!T9HDfpg6y`1QQW$=0?i69?WyIPLy&WmpecEO{yK? zRQw&{T}y{%#~Rq}w_Gm1Eq+>~FuXrsIRDLScuH-6?1n6(ZK_ZQV@LGU8w9x5Xa$@A z7lZ4-&#;PioO5Fs=i}ogp1ONVhj*V@oi77QaiG)W8E)?=*FsE}pk}|Ix?Pi?v8B2; zG`(PAqLIJ_k6Mg{2FE4@lMC-WOD~MeDU7v$=TK+oeCJ@2s-M$~AyQ>I#~WeO&kNSe zjSY8EjCnGF=G6;E-0HqNyuAxs?l!%28My+V&ks;7_80A^DbEg{AKhGI#MY`hv}qio z&dK=oX}%^+SmW!@eh$dH*Pw25YxQ>Kt*l03r&I!|1S4-Fn51m}#G@gWirSp_YdoL0 zuz_Fcsd8>Z27A`ml$C{b_os(-_u}^d&SB-ub%vyPGao^F&n8G4F&7&*^;&v#IE7bC z{4ydL$2e}49~|snRpS%vNwn9|(+f_hy5eOTZENciW~=YwdC&H|OZ1h?zw9xg?B~(U z)q$t;K#s?#j6##1bvCc0g@z`D%>XKlPMjxKnDNYIFI6}O)p*R3c*t00C#}%{8HXL- zGQxwar|qe(34zL0GhMbXvl=c=`t&k{9K!7Nz?`}5;OgWgDKCL0g)A^94o1$G<*F#C zvk;3vy;g(TrGGv8*!kAik-KLn{3wm%rbZ2f=!v_FIpk*GANQSbVeeg*Rgz0niW?f zOU5)8VH*f>hRYAS38n@sA8DkX5+M#>H*kk4u3^wsZNY><SOvQWN*ctTdmffN}XT(RN!lIq!eFT zv6NQ&w&1r%1(B}{iR#Fl{wa&bOS`=TJw4SE%g@ew62#fKMxd~%!^cT zKE)Q6geh*?W3oktm4iTq>a=nR1b7f&G~n+budJlvAm@x!LaW##<>&~Bm3Oj7VpWvT z7zbzc))V+ox(By)f8uX-U-X^s2Y=9gl6_bGFzKuAb4nY3)cx)MPxq~SM?>hk7yhRE zhgH$38vm90nRnZ|kch)7;5h5{_9!G0!8a+g3nn5B z^>##sXgP|TIf~S6r1lPTPdIZPEz^J0^{Q3!HL|*@>;!obuXX;!g`fr|^3MIAI!UcO z(&j4qVZBlIlG}0f)~4mQzWfCCRzITG^hB&We?0TDoA1#EfRAC+>8RP1Sxu{68 zJ5yfsv|T>){{0$#J592LE(%rrGfK2r#T2EipsT6=m_fpYB~sK}1ZtuNN?tSo&mKL! z5KI|$bz1AJt)xj52HR3iz;l@*a=)v3?he<;YEU;8eDQ*u|-)@;kp+R z(SheT)5nv?DzGLwgWc(cQBm4N=ET|oUS6wQgcM@)d8 zZ{q#&2NzHz!N_JY4V0SurV^$1OC(T_n=>SoL`4dJMqxGmf(7`wyHvOu#k|?XCSVY? zfSdb9fu6nk{YA+#!tldz2%3nsLRjJUyufiB%xS&nlpf^7$YH>%aIN7QVLFk>!^>-N zFcD=;2q?+8T{zq6OI{f|u!-go7^tck=(v*R9_{+GXD02DZwk4=@B(31p4-ux@*UpC z-{R-mjBM(p{c~3qhh^^DgigAQ1f(n)m84wKd%i$*rCRdX#s`qae5bjnnH(xcIE^L;Z9v^SxOrwzNmS9)npG;T#4(TOqmSAaj<4$Xu?Q@aqbo2jE z96_axdN8G(*d-e~5+{(r!7Xn-gBj_;jy^S(_p7v{&CO*tK?-0gm^JWMH(Uv zk(r3_oVV~lN($k>DJep(eOFSvO}yR`9Z#dZbk1_;Qkt3&-PBj{@u<>Sj;bECPF2v9 zs@%C`!+2}w&*rgtLwmD2xIIsv^0Y4T(tB`xBY%SP>XNnX@58wgNc=04&dGOT69+{5 zE?_h$)A{Od&ksHk8gQ?@(Ymf-H?zNk*^2yxCOxLx*2SOJU)Gt6dh%G6Bug#!t#$Rq z4Ar~sn95_gVPpdQBQC93su&2#(i-nMq1OwW$}vu*X^hmb9K}V2h6#l3)mO>Wm zz0PC0ToUB>sJwsJ-Pl#p&E0XV%LV!X?W?0hkP2ahD)Wp4<+L;2S`1g{U7RNyvz*`S zNMwJWyf!`xsjL`PgI3-fFLKx?A~d_tiA{m^?7mi{B(n7w(n~_$u;nQI;2oW?Y-=kc zE;gtT6ijSMmboF5e*GrFeA_9?KJ0Zh@?ohgdN-Z#LA^S3>gxNJtejUT7X&NMw(P3n zG>{ih8>Ft|@tVIsywx`|-i0sDB$SI|0?-jYn%I{fx>*UUc{yg;0V!kM`Gn@<4%wVC z%BB-J=Is%aOWV9(jR4$6^9EgK_3+Oy!EsG3}R@x~siQg@~)nVZc0^2Qg54x)d>o0xg3F1U7hwi#K-Av;Nziqzv>FPNA9h+S8r1@ zR8=}qSxKX4u5?{!bF57=&6RLG`%~SiW!|;rJ^Gc0Y}RIc0DdFKD1Rqzhe4vz TN{UE1I@x*xjgt*5%{?dR8BU2Oq~W<+_k z6wQK$qxl~_jw4avFjOo8f{0iI3}E4KB+(oWgIB{KY@q^Cj)*}Z%m9RiK_C_;vj~H& z26Dh?jt4+2=_}oZMyKN70B3Cp13~PSBNV{E@>t1bz#*wb)Fl7_3kxm-&bLWo&<{YX zurL%HnF*n|k`@`?7r^GZl8%4X5X6;a{#66Om9+dZCypyg`%%YpC9Qtc30!GCj^jQlE8wann$3+i+Ds}m*3)DhyxH{0LcN90D?}@ zX%sy=jZW4!u+p{G)}>g{wDm2i`r1UQo-T<@GO!@hNzqV5F8P4Z9J5OlrbS0V1`62 zOa}&!PQ`TW!q~SLi&$xBPBn74=WxQ!I9y`O@aUM5?9dd|4KQqi{C~(;sBp)N`k#uyf=TC<2otW_#DCPys1x6SJH~LO@ z`_W0JgAzQW`fVXED1rN*Y&BV*)my+jPVkK^>L_kwC>u3ybaNV7=wq3k##8F&6Z>Pn z+((%P=Q~`@jm$gJBKz6)g1u>5u>eoi&PX%99+{W(Y<9Xt@3x#zEdn!BW?Iqh)v0k) zclHIpBb_&0T2(jisB*ZhB52H`Kgpq~N+w^AB5zVrJ?|uX*8XMMq337U11C%!?r0wH z=PFU@yH4Nl@S|A_+7T2xk~8m|oWGx*J4ttLQ;6^r1x6UI70A4L#(3EH?6X#V;UoXP z(c(W}JYIHAJ98}DdSNCtEc)o~pQ3w*@6k3Wxdc#lgkGK1zP)?mNqMGy>V&s*PPU4Q zvJ#c_2*G~f3TH7LTek^8aj8Wj%VDN;_%U^6>j{E%_iO(9lTmi9wr~#)%v6!2xJL1U z+ne-OIaBX2w}6G(=cjz@M^%vtdnwYP6l-_)aBFLxWkM9(Q@KC3tbRIvzLmB~ZVpAEomgZGGEltn;wl|6D%wx~WTxecr?w-&s zybhCUfCLa#HPDie^4%u4sj4<^(~f=l_a(Dc+7+|$#31rL1++PYFLcaI;N|65lu>Nb zhuO6B=0$2)#+FXrt|V`P>}1d@#kU1JxnGZMSJ+eWc(LchMaQZ^^!bL5nhq5s(xx?; zIU@r|cJ1m@2`Z`s0@aiSlL)UO;qah4&)cTxAJ;ZSy;2VxS<6lhT z>dB(E913ZO;qIURc+p#_xWp~T?a}3m4KD)s2=(xz{f|ApPlrkn`gj~xEPZfPi+y*k zn#U=ntgo(~SvAAAJY>Oa+V$|I$0OK>$z(!48X7Y_*0?;F2x-fHiOdaYFT{s5?J8_! z%OZVn(pkiqtBjlZ@uyCE1UWInf*9vEo`;lnusyST)%#bSQ~LeGLCs(sW`HD>QayV| zGlIp|Uv}1tsMSQA)zUY5zm`wd(IL9Vk8Uevdo>~Bu^Y044c`|Db8Bc zb=aJV6|m|irt-_=q{H^sZ6Z6qo0^+Z zsoAK)&s*nzUcvAs07F?;V9CkX$B*f_q{SSWGMkDRd~4#eW!=k)2%CUQ-EXJH$VX{9 z6eEMy4O+*m8_}+tq(vX;Wxqr+%FeMOc}O-AiDa__c#`?sQ_X$1#dRZx|K~uKomYku zf?NHsBL?&HXAlO4XJ=6=t!sBAAac&oZ`MM803?oKGTc`&FxJM9(15Y7w73D1zcfopDC`O1S0B{0xc LbK~ImkKn%nM5opH literal 0 HcmV?d00001 From aaaf1826f8fbd251871c0dc47bd55c206f7e9433 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 17:48:38 +0200 Subject: [PATCH 2369/4321] Free file in case of failure Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45387 --- src/pkcs15init/pkcs15-muscle.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 9545e9b799..626f801b23 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -49,8 +49,10 @@ static int muscle_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) sc_format_path("3F00", &path); if ((r = sc_select_file(p15card->card, &path, &file)) < 0) return r; - if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_ERASE)) < 0) + if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_ERASE)) < 0) { + sc_file_free(file); return r; + } if ((r = sc_delete_file(p15card->card, &path)) < 0) return r; return 0; From 5e05636ba6765b83bdf8bb9d1d87e7a89fa4de8b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 09:20:09 +0200 Subject: [PATCH 2370/4321] Division by zero Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45389 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46035 --- src/pkcs15init/profile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index bdb40e0e19..c3b5930642 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2491,7 +2491,10 @@ expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri) expr_eval(ctx, &right, new_pri + 1); switch (op) { case '*': left *= right; break; - case '/': left /= right; break; + case '/': + if (right == 0) + expr_fail(ctx); + left /= right; break; case '+': left += right; break; case '-': left -= right; break; case '&': left &= right; break; From 84c7c57f4a12a3df39c5e8e11a968218d6003dca Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 09:43:07 +0200 Subject: [PATCH 2371/4321] Check return value before dereferencing Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45390 --- src/pkcs15init/profile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index c3b5930642..c203b8bcda 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1577,7 +1577,8 @@ do_acl(struct state *cur, int argc, char **argv) if (map_str2int(cur, oper, &op, fileOpNames)) goto bad; - acl = sc_file_get_acl_entry(file, op); + if (!(acl = sc_file_get_acl_entry(file, op))) + goto bad; if (acl->method == SC_AC_NEVER || acl->method == SC_AC_NONE || acl->method == SC_AC_UNKNOWN) From 2a4da3533eee8b7d34e9ac1cfcfb9fd8e4200385 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 09:59:56 +0200 Subject: [PATCH 2372/4321] Set limit of file size for memory allocation Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45391 --- src/pkcs15init/pkcs15-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 2e7aeb281f..990ff0f7d9 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4390,6 +4390,8 @@ sc_pkcs15init_read_info(struct sc_card *card, struct sc_profile *profile) if (r >= 0) { len = file->size; sc_file_free(file); + if (len > MAX_FILE_SIZE) + return SC_ERROR_INTERNAL; mem = malloc(len); if (mem != NULL) r = sc_read_binary(card, 0, mem, len, 0); From fb0b15a675e7959fb31c3c1be44d8878c6dc868d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 10:11:40 +0200 Subject: [PATCH 2373/4321] Free driver in sc_profile_free() Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45393 --- src/pkcs15init/profile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index c203b8bcda..f79b2c89e1 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -450,6 +450,8 @@ sc_profile_free(struct sc_profile *profile) if (profile->name) free(profile->name); + if (profile->driver) + free(profile->driver); free_file_list(&profile->ef_list); From 59682b743e6bd89af4a1f7501043d0eff0204efc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 10:42:24 +0200 Subject: [PATCH 2374/4321] Free file if it is not already in profile Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45395 --- src/pkcs15init/profile.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index f79b2c89e1..2f45e11166 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1217,6 +1217,7 @@ new_file(struct state *cur, const char *name, unsigned int type) struct file_info *info; sc_file_t *file; unsigned int df_type = 0, dont_free = 0; + int free_file = 0; if ((info = sc_profile_find_file(profile, NULL, name)) != NULL) return info; @@ -1225,6 +1226,7 @@ new_file(struct state *cur, const char *name, unsigned int type) * by the PKCS15 logic */ if (strncasecmp(name, "PKCS15-", 7)) { file = init_file(type); + free_file = 1; } else if (!strcasecmp(name+7, "TokenInfo")) { if (!profile->p15_spec) { parse_error(cur, "no pkcs15 spec in profile"); @@ -1248,6 +1250,7 @@ new_file(struct state *cur, const char *name, unsigned int type) dont_free = 1; } else if (!strcasecmp(name+7, "AppDF")) { file = init_file(SC_FILE_TYPE_DF); + free_file = 1; } else { if (map_str2int(cur, name+7, &df_type, pkcs15DfNames) || df_type >= SC_PKCS15_DF_TYPE_COUNT) @@ -1255,6 +1258,7 @@ new_file(struct state *cur, const char *name, unsigned int type) file = init_file(SC_FILE_TYPE_WORKING_EF); profile->df[df_type] = file; + free_file = 1; } assert(file); if (file->type != type) { @@ -1262,8 +1266,7 @@ new_file(struct state *cur, const char *name, unsigned int type) file->type == SC_FILE_TYPE_DF ? "DF" : file->type == SC_FILE_TYPE_BSO ? "BS0" : "EF"); - if (strncasecmp(name, "PKCS15-", 7) || - !strcasecmp(name+7, "AppDF")) + if (free_file) sc_file_free(file); return NULL; } From 4c121cfcf4b63b610f3cb3f475d7fe03db147299 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 14:54:52 +0200 Subject: [PATCH 2375/4321] Do not dereference NULL Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45394 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45411 --- src/pkcs15init/profile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 2f45e11166..8f049c208f 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2122,12 +2122,14 @@ sc_profile_find_file(struct sc_profile *pro, { struct file_info *fi; unsigned int len; + const u8 *value; - len = path? path->len : 0; + value = path ? path->value : (const u8*) ""; + len = path ? path->len : 0; for (fi = pro->ef_list; fi; fi = fi->next) { sc_path_t *fpath = &fi->file->path; - if (!strcasecmp(fi->ident, name) && fpath->len >= len && !memcmp(fpath->value, path->value, len)) + if (!strcasecmp(fi->ident, name) && fpath->len >= len && !memcmp(fpath->value, value, len)) return fi; } return NULL; From 6c4f42e8f36f983d30354403317e298b040554c3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 15:16:07 +0200 Subject: [PATCH 2376/4321] Free profile name and options in case of failure Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45396 --- src/pkcs15init/pkcs15-lib.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 990ff0f7d9..b671527503 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4443,13 +4443,14 @@ sc_pkcs15init_parse_info(struct sc_card *card, const unsigned char *end; unsigned int nopts = 0; size_t n; + int r = 0; if ((p == NULL) || (len == 0)) return 0; end = p + (len - 1); while (p < end) { /* more bytes to look at */ - int r = 0; + r = 0; tag = *p; p++; if ((tag == 0) || (tag == 0xff) || (p >= end)) @@ -4458,23 +4459,26 @@ sc_pkcs15init_parse_info(struct sc_card *card, n = *p; p++; - if (p >= end || p + n > end) /* invalid length byte n */ + if (p >= end || p + n > end) { /* invalid length byte n */ + r = SC_ERROR_PKCS15INIT; goto error; + } switch (tag) { case OPENSC_INFO_TAG_PROFILE: r = set_info_string(&profile->name, p, n); if (r < 0) - return r; + goto error; break; case OPENSC_INFO_TAG_OPTION: if (nopts >= SC_PKCS15INIT_MAX_OPTIONS - 1) { sc_log(card->ctx, "Too many options in OpenSC Info file"); - return SC_ERROR_PKCS15INIT; + r = SC_ERROR_PKCS15INIT; + goto error; } r = set_info_string(&profile->options[nopts], p, n); if (r < 0) - return r; + goto error; profile->options[++nopts] = NULL; break; default: @@ -4486,7 +4490,16 @@ sc_pkcs15init_parse_info(struct sc_card *card, error: sc_log(card->ctx, "OpenSC info file corrupted"); - return SC_ERROR_PKCS15INIT; + if (profile->name) { + free(profile->name); + profile->name = NULL; + } + for (size_t i = 0; i < nopts; i++) { + if (profile->options[i]) + free(profile->options[i]); + profile->options[i] = NULL; + } + return r; } From b70d8ea756f2202d6f3ecb2bf5d0bc77ad793c74 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 18:02:14 +0200 Subject: [PATCH 2377/4321] Free allocated memory for EC point Q Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45400 --- src/pkcs15init/pkcs15-lib.c | 1 + src/pkcs15init/pkcs15-myeid.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index b671527503..3e96fc6ec9 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1613,6 +1613,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (r < 0 && algorithm == SC_ALGORITHM_EC) { free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); + free(pubkey_args.key.u.ec.ecpointQ.value); /* allocated in profile->ops->generate_key */ } LOG_TEST_GOTO_ERR(ctx, r, "Select intrinsic ID error"); diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 5e3368491d..75652f6e9f 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -917,10 +917,14 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->u.ec.params.der.len = 0; pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve); - if (!pubkey->u.ec.params.named_curve) + if (!pubkey->u.ec.params.named_curve) { + free(pubkey->u.ec.ecpointQ.value); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); + if (r < 0) + free(pubkey->u.ec.ecpointQ.value); LOG_TEST_RET(ctx, r, "Cannot fix EC parameters"); } } From 2c9dddc7386dbb57844cf17688859e735a783fd8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 15:43:23 +0200 Subject: [PATCH 2378/4321] Set pointer before while and avoid cycle Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45404 --- src/pkcs15init/profile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 8f049c208f..2f62651228 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2359,8 +2359,9 @@ __expr_get(struct num_exp_ctx *ctx, int eof_okay) } ctx->j = 0; + s = ctx->str; do { - if ((s = ctx->str) == NULL || *s == '\0') { + if (s == NULL || *s == '\0') { if (ctx->argc == 0) { if (eof_okay) return NULL; From 4d7368fd3519a4778765b8eb818af0941a8d4f25 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 16:21:51 +0200 Subject: [PATCH 2379/4321] Set zero byte as string ending Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45459 --- src/tests/fuzzing/fuzz_pkcs15init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 31f3fc0427..7b091de011 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -172,6 +172,7 @@ void do_store_data_object(struct sc_profile *profile, struct sc_pkcs15_card *p15 char value[SC_MAX_OBJECT_ID_OCTETS]; memcpy(value, buf, SC_MAX_OBJECT_ID_OCTETS); + value[len < SC_MAX_OBJECT_ID_OCTETS ? len : SC_MAX_OBJECT_ID_OCTETS - 1] = '\0'; memset(&args, 0, sizeof(args)); sc_init_oid(&args.app_oid); From dd4876d262be4c1ec089c7a64edf3b524c8ebe0e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Apr 2022 16:49:15 +0200 Subject: [PATCH 2380/4321] Free profile extension in EF list Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45516 --- src/pkcs15init/profile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 2f62651228..d2376abf00 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1201,6 +1201,7 @@ free_file_list(struct file_info **list) if (fi->dont_free == 0) sc_file_free(fi->file); + free(fi->profile_extension); free(fi->ident); free(fi); } From 089cedc7520fbb9e0e4a912c4c3866a1aa429de6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 16:56:17 +0200 Subject: [PATCH 2381/4321] Check file value length Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46002 --- src/pkcs15init/pkcs15-epass2003.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 74d8ba2639..b845b95a05 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -307,7 +307,7 @@ static int cosm_new_file(struct sc_profile *profile, struct sc_card *card, unsigned int type, unsigned int num, struct sc_file **out) { - struct sc_file *file; + struct sc_file *file = NULL; const char *_template = NULL, *desc = NULL; unsigned int structure = 0xFFFFFFFF; @@ -317,12 +317,12 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, while (1) { switch (type) { case SC_PKCS15_TYPE_PRKEY_EC: - desc = "RSA private key"; + desc = "EC private key"; _template = "private-key"; structure = SC_CARDCTL_OBERTHUR_KEY_EC_CRT; break; case SC_PKCS15_TYPE_PUBKEY_EC: - desc = "RSA public key"; + desc = "EC public key"; _template = "public-key"; structure = SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC; break; @@ -373,6 +373,11 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, return SC_ERROR_NOT_SUPPORTED; } + if (file->path.len < 1) { + sc_file_free(file); + return SC_ERROR_INTERNAL; + } + file->id &= 0xFF00; file->id |= (num & 0x00FF); From da37a0d5ece632080351c529ac87f00495eddbfa Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 15:54:15 +0200 Subject: [PATCH 2382/4321] Check length of path Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46006 --- src/libopensc/card-epass2003.c | 46 +++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 7efa339746..47a1c1006a 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1287,8 +1287,13 @@ epass2003_finish(sc_card_t *card) static int epass2003_hook_path(struct sc_path *path, int inc) { - u8 fid_h = path->value[path->len - 2]; - u8 fid_l = path->value[path->len - 1]; + u8 fid_h = 0; + u8 fid_l = 0; + + if (!path || path->len < 2) + return -1; + fid_h = path->value[path->len - 2]; + fid_l = path->value[path->len - 1]; switch (fid_h) { case 0x29: @@ -1310,17 +1315,24 @@ epass2003_hook_path(struct sc_path *path, int inc) } -static void +static int epass2003_hook_file(struct sc_file *file, int inc) { int fidl = file->id & 0xff; int fidh = file->id & 0xff00; - if (epass2003_hook_path(&file->path, inc)) { + int rv = 0; + + rv = epass2003_hook_path(&file->path, inc); + + if (rv > 0) { if (inc) file->id = fidh + fidl * FID_STEP; else file->id = fidh + fidl / FID_STEP; } + if (rv < 0) + return rv; + return SC_SUCCESS; } @@ -1333,7 +1345,9 @@ epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** fi int r, pathlen; sc_file_t *file = NULL; - epass2003_hook_path(in_path, 1); + r = epass2003_hook_path(in_path, 1); + LOG_TEST_RET(card->ctx, r, "Can not hook path"); + memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; @@ -2266,18 +2280,16 @@ epass2003_delete_file(struct sc_card *card, const sc_path_t * path) LOG_FUNC_CALLED(card->ctx); r = sc_select_file(card, path, NULL); - epass2003_hook_path((struct sc_path *)path, 1); - if (r == SC_SUCCESS) { - sbuf[0] = path->value[path->len - 2]; - sbuf[1] = path->value[path->len - 1]; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00); - apdu.lc = 2; - apdu.datalen = 2; - apdu.data = sbuf; - } - else { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } + LOG_TEST_RET(card->ctx, r, "Can not select file"); + r = epass2003_hook_path((struct sc_path *)path, 1); + LOG_TEST_RET(card->ctx, r, "Can not hook path"); + + sbuf[0] = path->value[path->len - 2]; + sbuf[1] = path->value[path->len - 1]; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00); + apdu.lc = 2; + apdu.datalen = 2; + apdu.data = sbuf; r = sc_transmit_apdu_t(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); From 901310c7b4a0a5f00105660e37dee971367366eb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Apr 2022 17:05:37 +0200 Subject: [PATCH 2383/4321] ci: Add missing dependency for the new test-pkcs11-tool-unwrap-wrap-test --- .github/setup-linux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index d1f898bd96..b6455a4f42 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -3,7 +3,7 @@ set -ex -o xtrace # Generic dependencies -DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git" +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd" # Add openssl or install openssl3.0 if [ "$1" != "ossl3" -a "$2" != "ossl3" -a ]; then @@ -23,7 +23,7 @@ if [ "$1" == "clang-tidy" ]; then elif [ "$1" == "cac" ]; then DEPS="$DEPS libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools" elif [ "$1" == "oseid" ]; then - DEPS="$DEPS socat gawk xxd" + DEPS="$DEPS socat gawk" elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == "openpgp" ]; then if [ "$1" == "piv" ]; then DEPS="$DEPS cmake" From 9056b5115a472f19440a9f243be3c7caa8a8c055 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Apr 2022 17:15:39 +0200 Subject: [PATCH 2384/4321] ci: Remove bogus trailing -a --- .github/setup-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index b6455a4f42..6a95828a91 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -6,7 +6,7 @@ set -ex -o xtrace DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd" # Add openssl or install openssl3.0 -if [ "$1" != "ossl3" -a "$2" != "ossl3" -a ]; then +if [ "$1" != "ossl3" -a "$2" != "ossl3" ]; then DEPS="$DEPS openssl" fi From 058873646d0aacd831e6b8c85e1ad31fa4b750f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Apr 2022 17:16:14 +0200 Subject: [PATCH 2385/4321] ci: Clone only one branch of OpenSSL to limit traffic --- .github/setup-openssl.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/setup-openssl.sh b/.github/setup-openssl.sh index 04c17db4c8..08048918fd 100755 --- a/.github/setup-openssl.sh +++ b/.github/setup-openssl.sh @@ -5,10 +5,9 @@ set -ex -o xtrace sudo apt-get remove -y openssl libssl-dev java8-runtime-headless default-jre-headless if [ ! -d "openssl" ]; then - git clone https://github.com/openssl/openssl + git clone --single-branch --branch=openssl-3.0 --depth 1 https://github.com/openssl/openssl fi pushd openssl -git checkout openssl-3.0 ./Configure --prefix=/usr/local linux-x86_64 make -j $(nproc) sudo make install From f776ee3c90a47376be631989d4972623a2a61aa7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Apr 2022 17:21:47 +0200 Subject: [PATCH 2386/4321] fuzz: Check return values Fixes CID 377385, Thanks coverity --- src/tests/fuzzing/fuzz_card.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c index 4e0bd3950a..c2d7e288d5 100644 --- a/src/tests/fuzzing/fuzz_card.c +++ b/src/tests/fuzzing/fuzz_card.c @@ -38,7 +38,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) uint8_t len = 0; u8 *rnd = NULL, *wrap_buf = NULL, *unwrap_buf = NULL; size_t wrap_buf_len = 0, unwrap_buf_len = 0; - int reset = 0; + int reset = 0, r = 0; #ifdef FUZZING_ENABLED fclose(stdout); @@ -86,8 +86,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) sc_list_files(card, files, sizeof(files)); /* Get challenge */ - if ((rnd = malloc(len))) - sc_get_challenge(card, rnd, len); + rnd = malloc(len); + if (rnd == NULL) + goto err; + if ((r = sc_get_challenge(card, rnd, len)) != SC_SUCCESS) + sc_log(ctx, "sc_get_challenge failed with rc = %d", r); /* Append record */ sc_append_record(card, ptr, ptr_size, flag); From 3acda3511bca43496e4dd90d7e9772cccc26f9bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Apr 2022 17:38:36 +0200 Subject: [PATCH 2387/4321] p11test: Fix typo in reading secret keys Fixes CID 374845, Thanks coverity --- src/tests/p11test/p11test_case_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index f091dbcc10..d428fbfa90 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -757,7 +757,7 @@ int callback_secret_keys(test_certs_t *objects, ? *((CK_BBOOL *) template[3].pValue) : CK_FALSE; o->sign = (template[4].ulValueLen != (CK_ULONG) -1) ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; - o->decrypt = (template[5].ulValueLen != (CK_ULONG) -1) + o->encrypt = (template[5].ulValueLen != (CK_ULONG) -1) ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; o->decrypt = (template[6].ulValueLen != (CK_ULONG) -1) ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; From d5b6539b3b34694a701dc6dca996f06dbcc172db Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 17 Apr 2022 10:22:28 +0200 Subject: [PATCH 2388/4321] fuzzing: Remove static --- src/tests/fuzzing/fuzz_pkcs15_decode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index 4011ba5c1d..a83c719cb9 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -51,9 +51,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) const uint8_t *buf = Data, *reader_data = NULL; uint16_t buf_len = 0; size_t reader_data_len = 0; - static struct sc_context *ctx = NULL; - static struct sc_pkcs15_card *p15card = NULL; - static sc_card_t *card = NULL; + struct sc_context *ctx = NULL; + struct sc_pkcs15_card *p15card = NULL; + sc_card_t *card = NULL; struct sc_pkcs15_tokeninfo *tokeninfo = NULL; int (* decode_entries[])(struct sc_pkcs15_card *, struct sc_pkcs15_object *, const u8 **nbuf, size_t *nbufsize) = { From 01cccbdc6332d9ea4bc7f8a68a22fa39e6251800 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Apr 2022 12:14:40 +0200 Subject: [PATCH 2389/4321] Unbreak yubico-piv-tool build --- .github/test-piv.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index c4ab409e50..a0f2282d17 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -27,6 +27,7 @@ if [ ! -d "build" ]; then fi pushd build cmake .. && make && sudo make install +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/x86_64-linux-gnu popd popd From 44f75b3e44758a523374dd8bea0df693932a0e03 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 11 Mar 2022 17:26:38 +0100 Subject: [PATCH 2390/4321] Add basic configuration for Packit --- .packit.yaml | 23 +++++ packaging/opensc.module | 9 ++ packaging/opensc.spec | 201 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 .packit.yaml create mode 100644 packaging/opensc.module create mode 100644 packaging/opensc.spec diff --git a/.packit.yaml b/.packit.yaml new file mode 100644 index 0000000000..e8c30f2a5e --- /dev/null +++ b/.packit.yaml @@ -0,0 +1,23 @@ +upstream_project_url: https://github.com/OpenSC/OpenSC + +specfile_path: packaging/opensc.spec +files_to_sync: + - packaging/opensc.spec + - .packit.yaml +upstream_package_name: opensc +downstream_package_name: opensc +merge_pr_in_ci: false + +notifications: + pull_request: + successful_build: true + +jobs: +- job: copr_build + trigger: pull_request + metadata: + targets: + - fedora-development-x86_64 + - fedora-development-aarch64 + - fedora-development-ppc64le + - fedora-development-s390x diff --git a/packaging/opensc.module b/packaging/opensc.module new file mode 100644 index 0000000000..c6699afcc3 --- /dev/null +++ b/packaging/opensc.module @@ -0,0 +1,9 @@ +# This file describes how to load the opensc module +# See: https://p11-glue.github.io/p11-glue/p11-kit/manual/pkcs11-conf.html +# or man pkcs11.conf + +# This is a relative path, which means it will be loaded from +# the p11-kit default path which is usually $(libdir)/pkcs11. +# Doing it this way allows for packagers to package opensc for +# 32-bit and 64-bit and make them parallel installable +module: opensc-pkcs11.so diff --git a/packaging/opensc.spec b/packaging/opensc.spec new file mode 100644 index 0000000000..49c5e20fa7 --- /dev/null +++ b/packaging/opensc.spec @@ -0,0 +1,201 @@ +%define opensc_module "OpenSC PKCS #11 Module" +%define nssdb %{_sysconfdir}/pki/nssdb + +Name: opensc +Version: 0.1.0 +Release: 1%{?dist} +Summary: Smart card library and applications + +License: LGPLv2+ +URL: https://github.com/OpenSC/OpenSC/wiki +Source0: opensc-0.1.0.tar.gz +Source1: opensc.module + +BuildRequires: make +BuildRequires: pcsc-lite-devel +BuildRequires: readline-devel +BuildRequires: openssl-devel +BuildRequires: /usr/bin/xsltproc +BuildRequires: docbook-style-xsl +BuildRequires: autoconf automake libtool gcc +BuildRequires: bash-completion +BuildRequires: zlib-devel +# For tests +BuildRequires: libcmocka-devel +%if ! 0%{?rhel} +BuildRequires: softhsm +%endif +BuildRequires: openssl +Requires: pcsc-lite-libs%{?_isa} +Requires: pcsc-lite +Obsoletes: mozilla-opensc-signer < 0.12.0 +Obsoletes: opensc-devel < 0.12.0 +Obsoletes: coolkey <= 1.1.0-36 +# The simclist is bundled in upstream +Provides: bundled(simclist) = 1.5 + +%description +OpenSC provides a set of libraries and utilities to work with smart cards. Its +main focus is on cards that support cryptographic operations, and facilitate +their use in security applications such as authentication, mail encryption and +digital signatures. OpenSC implements the PKCS#11 API so applications +supporting this API (such as Mozilla Firefox and Thunderbird) can use it. On +the card OpenSC implements the PKCS#15 standard and aims to be compatible with +every software/card that does so, too. + + +%prep +%setup -q + +# The test-pkcs11-tool-allowed-mechanisms already works in Fedora +sed -i -e '/XFAIL_TESTS/,$ { + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh/ + q +}' tests/Makefile.am + + +cp -p src/pkcs15init/README ./README.pkcs15init +cp -p src/scconf/README.scconf . +# No {_libdir} here to avoid multilib conflicts; it's just an example +sed -i -e 's|/usr/local/towitoko/lib/|/usr/lib/ctapi/|' etc/opensc.conf.example.in + + +%build +autoreconf -fvi +%ifarch %{ix86} +sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in +%endif +sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths +%set_build_flags +CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations" +%configure --disable-static\ + --disable-autostart-items \ + --disable-notify \ + --disable-assert \ + --enable-pcsc \ + --enable-cmocka \ + --enable-sm \ + --with-pcsc-provider=libpcsclite.so.1 +%make_build + + +%check +make check + + +%install +%make_install +install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module + +%ifarch %{ix86} +# To avoid multilib issues, move these files on 32b intel architectures +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/opensc.conf +install -Dpm 644 etc/opensc.conf $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +rm -f $RPM_BUILD_ROOT%{_mandir}/man5/opensc.conf.5 +install -Dpm 644 doc/files/opensc.conf.5 $RPM_BUILD_ROOT%{_mandir}/man5/opensc-%{_arch}.conf.5 +# use NEWS file timestamp as reference for configuration file +touch -r NEWS $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +touch -r NEWS $RPM_BUILD_ROOT%{_mandir}/man5/opensc-%{_arch}.conf.5 +%else +# For backward compatibility, symlink the old location to the new files +ln -s %{_sysconfdir}/opensc.conf $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +%endif + +find $RPM_BUILD_ROOT%{_libdir} -type f -name "*.la" | xargs rm + +rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/opensc + +# Upstream considers libopensc API internal and no longer ships +# public headers and pkgconfig files. +# Remove the symlink as nothing is supposed to link against libopensc. +rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so +# remove the .pc file so we do not confuse users #1673139 +rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc +rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so +%if 0%{?rhel} && 0%{?rhel} < 7 +rm -rf %{buildroot}%{_datadir}/bash-completion/ +%endif + +# the npa-tool builds to nothing since we do not have OpenPACE library +rm -rf %{buildroot}%{_bindir}/npa-tool +rm -rf %{buildroot}%{_mandir}/man1/npa-tool.1* + +# the pkcs11-register is not applicable to Fedora/RHEL where we use p11-kit +rm -rf %{buildroot}%{_bindir}/pkcs11-register +rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1* + +# Remove the notification files +rm %{buildroot}%{_bindir}/opensc-notify +rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop +rm %{buildroot}%{_mandir}/man1/opensc-notify.1* + + +%files +%doc COPYING NEWS README* + +%if ! 0%{?rhel} || 0%{?rhel} >= 7 +%{_datadir}/bash-completion/* +%endif + +%ifarch %{ix86} +%{_mandir}/man5/opensc-%{_arch}.conf.5* +%else +%config(noreplace) %{_sysconfdir}/opensc.conf +%{_mandir}/man5/opensc.conf.5* +%endif + +%config(noreplace) %{_sysconfdir}/opensc-%{_arch}.conf +# Co-owned with p11-kit so it is not hard dependency +%dir %{_datadir}/p11-kit +%dir %{_datadir}/p11-kit/modules +%{_datadir}/p11-kit/modules/opensc.module +%{_bindir}/cardos-tool +%{_bindir}/cryptoflex-tool +%{_bindir}/eidenv +%{_bindir}/iasecc-tool +%{_bindir}/gids-tool +%{_bindir}/netkey-tool +%{_bindir}/openpgp-tool +%{_bindir}/opensc-explorer +%{_bindir}/opensc-tool +%{_bindir}/opensc-asn1 +%{_bindir}/piv-tool +%{_bindir}/pkcs11-tool +%{_bindir}/pkcs15-crypt +%{_bindir}/pkcs15-init +%{_bindir}/pkcs15-tool +%{_bindir}/sc-hsm-tool +%{_bindir}/dnie-tool +%{_bindir}/westcos-tool +%{_bindir}/egk-tool +%{_bindir}/goid-tool +%{_libdir}/lib*.so.* +%{_libdir}/opensc-pkcs11.so +%{_libdir}/pkcs11-spy.so +%{_libdir}/onepin-opensc-pkcs11.so +%%dir %{_libdir}/pkcs11 +%{_libdir}/pkcs11/opensc-pkcs11.so +%{_libdir}/pkcs11/onepin-opensc-pkcs11.so +%{_libdir}/pkcs11/pkcs11-spy.so +%{_datadir}/opensc/ +%{_mandir}/man1/cardos-tool.1* +%{_mandir}/man1/cryptoflex-tool.1* +%{_mandir}/man1/eidenv.1* +%{_mandir}/man1/gids-tool.1* +%{_mandir}/man1/goid-tool.1* +%{_mandir}/man1/iasecc-tool.1* +%{_mandir}/man1/netkey-tool.1* +%{_mandir}/man1/openpgp-tool.1* +%{_mandir}/man1/opensc-explorer.* +%{_mandir}/man1/opensc-tool.1* +%{_mandir}/man1/opensc-asn1.1* +%{_mandir}/man1/piv-tool.1* +%{_mandir}/man1/pkcs11-tool.1* +%{_mandir}/man1/pkcs15-crypt.1* +%{_mandir}/man1/pkcs15-init.1* +%{_mandir}/man1/pkcs15-tool.1* +%{_mandir}/man1/sc-hsm-tool.1* +%{_mandir}/man1/westcos-tool.1* +%{_mandir}/man1/dnie-tool.1* +%{_mandir}/man1/egk-tool.1* +%{_mandir}/man5/pkcs15-profile.5* From 296b0cdde14fa61f5cfd51c6f33ed39fb38e3ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 14 Mar 2022 14:31:35 +0100 Subject: [PATCH 2391/4321] Remove unused variable --- src/tools/pkcs15-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 76a92dedee..49faf3dec0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1877,7 +1877,7 @@ init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *key; #else - char name[256]; size_t name_len = 0; + char name[256]; #endif int nid = NID_undef; @@ -1890,7 +1890,7 @@ init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey assert(EC_KEY_get0_group(key)); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key)); #else - assert(EVP_PKEY_get_group_name(pkey, name ,sizeof(name), &name_len)); + assert(EVP_PKEY_get_group_name(pkey, name, sizeof(name), NULL)); nid = OBJ_txt2nid(name); #endif assert(nid > 0); From e1003a976c43b220f32dc1e4719dfadbb8f60690 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 15 Mar 2022 09:49:09 +0100 Subject: [PATCH 2392/4321] Allow build of fuzz_pkcs15init only if static is enabled fuzz_pkcs15init uses API that is not exported by libopensc. --- configure.ac | 2 ++ src/tests/fuzzing/Makefile.am | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index db27ae5c42..21f2eda7e7 100644 --- a/configure.ac +++ b/configure.ac @@ -1100,6 +1100,8 @@ AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) AM_CONDITIONAL([ENABLE_FUZZING], [test "${enable_fuzzing}" = "yes"]) AM_CONDITIONAL([ENABLE_SHARED], [test "${enable_shared}" = "yes"]) AS_IF([test "${enable_shared}" = "yes"], [AC_DEFINE([ENABLE_SHARED], [1], [Enable shared libraries])]) +AM_CONDITIONAL([ENABLE_STATIC], [test "${enable_static}" = "yes"]) +AS_IF([test "${enable_static}" = "yes"], [AC_DEFINE([ENABLE_static], [1], [Enable static libraries])]) if test "${enable_pedantic}" = "yes"; then enable_strict="yes"; diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index fa83ceddf1..55f55f6d8c 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -7,8 +7,11 @@ LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/common/libcompat.la noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ - fuzz_scconf_parse_string fuzz_pkcs15init \ - fuzz_pkcs15_encode fuzz_card + fuzz_scconf_parse_string fuzz_pkcs15_encode fuzz_card + +if ENABLE_STATIC +noinst_PROGRAMS += fuzz_pkcs15init +endif noinst_HEADERS = fuzzer_reader.h From bbf33539967ddd9e88a482b701b63640a532b968 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 18 Mar 2022 09:42:22 +0100 Subject: [PATCH 2393/4321] Remove failing tests in make check Local build on RHEL8 and Fedora36 fails with errors on these two tests. --- packaging/opensc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 49c5e20fa7..45a1982ca2 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -49,7 +49,7 @@ every software/card that does so, too. # The test-pkcs11-tool-allowed-mechanisms already works in Fedora sed -i -e '/XFAIL_TESTS/,$ { - s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh/ + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh/ q }' tests/Makefile.am From 6b5b40f504c814a969135fd166b211189d064890 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 18 Mar 2022 17:32:18 +0100 Subject: [PATCH 2394/4321] Remove unneeded parts of specfile --- packaging/opensc.spec | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 45a1982ca2..6a4d45e929 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -1,6 +1,3 @@ -%define opensc_module "OpenSC PKCS #11 Module" -%define nssdb %{_sysconfdir}/pki/nssdb - Name: opensc Version: 0.1.0 Release: 1%{?dist} @@ -11,7 +8,7 @@ URL: https://github.com/OpenSC/OpenSC/wiki Source0: opensc-0.1.0.tar.gz Source1: opensc.module -BuildRequires: make +BuildRequires: make BuildRequires: pcsc-lite-devel BuildRequires: readline-devel BuildRequires: openssl-devel @@ -22,9 +19,7 @@ BuildRequires: bash-completion BuildRequires: zlib-devel # For tests BuildRequires: libcmocka-devel -%if ! 0%{?rhel} BuildRequires: softhsm -%endif BuildRequires: openssl Requires: pcsc-lite-libs%{?_isa} Requires: pcsc-lite @@ -112,9 +107,6 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so # remove the .pc file so we do not confuse users #1673139 rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so -%if 0%{?rhel} && 0%{?rhel} < 7 -rm -rf %{buildroot}%{_datadir}/bash-completion/ -%endif # the npa-tool builds to nothing since we do not have OpenPACE library rm -rf %{buildroot}%{_bindir}/npa-tool @@ -133,9 +125,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %files %doc COPYING NEWS README* -%if ! 0%{?rhel} || 0%{?rhel} >= 7 %{_datadir}/bash-completion/* -%endif %ifarch %{ix86} %{_mandir}/man5/opensc-%{_arch}.conf.5* @@ -173,7 +163,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_libdir}/opensc-pkcs11.so %{_libdir}/pkcs11-spy.so %{_libdir}/onepin-opensc-pkcs11.so -%%dir %{_libdir}/pkcs11 +%dir %{_libdir}/pkcs11 %{_libdir}/pkcs11/opensc-pkcs11.so %{_libdir}/pkcs11/onepin-opensc-pkcs11.so %{_libdir}/pkcs11/pkcs11-spy.so From 1b05d7664801d33f43475dfebb8741935977ad73 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Apr 2022 23:28:14 +0200 Subject: [PATCH 2395/4321] Windows changed readers (alternative) (#2525) Issue #2517 reports that minidriver may be presented with new handles to PCSC, even if card is moved from one reader to another. The previous code assumed a change in handles would always point at same reader. and if reader was changed, caller would do two operations: card is removed from one reader i.e. call CardDeleteContext and some time later when card is inserted, call CardAcquireContext. Thus previous code would not to call reinit_card_for. But this is not the case. So when handles change, the new handles are used to probe the new reader to obtain reader name to compare to old reader name. If they are the same returns to not call reinit_card. If they are different returns to call reinit_card. The assumption is if card is removed, it could be modified on another system then inserted on original system which changed data. --- src/libopensc/opensc.h | 13 ++++++++++++- src/libopensc/reader-pcsc.c | 25 +++++++++++++++++++++++++ src/minidriver/minidriver.c | 18 ++++++++++++------ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 604db92f79..475076dac1 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1036,10 +1036,21 @@ sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i); * @param ctx pointer to a sc_context_t * @param pcsc_context_handle pointer to the new context_handle to use * @param pcsc_card_handle pointer to the new card_handle to use - * @return SC_SUCCESS on success and an error code otherwise. + * @return SC_SUCCESS or 1 on success and an error code otherwise. + * a return of 1 indicates to call reinit_card_for, as + * the reader has changed. */ int sc_ctx_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_card_handle); +/** + * detect if the given handles are referencing `reader` + * + * 0 -> handles also point to `reader` + * 1 -> handles don't point to `reader`, but to a different reader + */ +int +pcsc_check_reader_handles(sc_context_t *ctx, sc_reader_t *reader, void * pcsc_context_handle, void * pcsc_card_handle); + /** * Returns a pointer to the specified sc_reader_t object * @param ctx OpenSC context diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 0882e2aef3..1efd8a0d31 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -2502,6 +2502,31 @@ static void detect_protocol(sc_reader_t *reader, SCARDHANDLE card_handle) reader->active_protocol = pcsc_proto_to_opensc(prot); } +int +pcsc_check_reader_handles(sc_context_t *ctx, sc_reader_t *reader, void * pcsc_context_handle, void * pcsc_card_handle) +{ + char reader_name[128]; + DWORD reader_name_size = sizeof(reader_name); + + if (NULL == reader) + return 1; + + struct pcsc_private_data *priv = reader->drv_data; + memset(reader_name, 0, sizeof(reader_name)); + + /* check if new handles are for the same reader as old handles */ + if (SCARD_S_SUCCESS != priv->gpriv->SCardGetAttrib(*(SCARDHANDLE *)pcsc_card_handle, + SCARD_ATTR_DEVICE_SYSTEM_NAME_A, (LPBYTE) + reader_name, &reader_name_size) + || strcmp(reader_name, reader->name) != 0) { + sc_log(ctx, "Reader name changed from \"%s\" to \"%s\"", reader->name, reader_name); + + return 1; + } + + return 0; +} + int pcsc_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_card_handle) { SCARDHANDLE card_handle; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 5e52778357..35f1c70952 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -412,6 +412,7 @@ static DWORD check_card_status(PCARD_DATA pCardData, const char *name) * check if the card is OK, has been removed, or the * caller has changed the handles. * if so, then try to reinit card + * or if different handles but same reader, just use the handles */ static DWORD check_card_reader_status(PCARD_DATA pCardData, const char *name) @@ -444,12 +445,17 @@ check_card_reader_status(PCARD_DATA pCardData, const char *name) (size_t)vs->hSCardCtx, (size_t)vs->hScard); if (vs->ctx) { - vs->hScard = pCardData->hScard; - vs->hSCardCtx = pCardData->hSCardCtx; - r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard); - logprintf(pCardData, 1, "sc_ctx_use_reader returned %d\n", r); - if (r) - MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); + if (1 == pcsc_check_reader_handles(vs->ctx, vs->reader, &pCardData->hSCardCtx, &pCardData->hScard)) { + _sc_delete_reader(vs->ctx, vs->reader); + MD_FUNC_RETURN(pCardData, 1, reinit_card_for(pCardData, name)); + } else { + vs->hScard = pCardData->hScard; + vs->hSCardCtx = pCardData->hSCardCtx; + r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard); + logprintf(pCardData, 1, "sc_ctx_use_reader returned %d\n", r); + if (r) + MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); + } } } From d095bb757707339fdee862901c877c50bf115505 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Apr 2022 15:32:43 +0200 Subject: [PATCH 2396/4321] Use https to avoid redirect warnings --- MacOSX/build-package.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 509fe0dfd4..29feda4b11 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -108,7 +108,7 @@ fi if ! test -e NotificationProxy; then - git clone http://github.com/frankmorgner/NotificationProxy.git + git clone https://github.com/frankmorgner/NotificationProxy.git fi if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ \ @@ -127,7 +127,7 @@ fi if (( $(xcodebuild -version | sed -En 's/Xcode[[:space:]]+([0-9]+)(\.[0-9]*)*/\1/p') < 10 )); then # Check out OpenSC.tokend, if not already fetched. if ! test -e OpenSC.tokend; then - git clone http://github.com/OpenSC/OpenSC.tokend.git + git clone https://github.com/OpenSC/OpenSC.tokend.git fi # Create the symlink to OpenSC sources From 973d76dffe1b6b570111a57c995ac913a65f1ffd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Apr 2022 16:42:24 +0200 Subject: [PATCH 2397/4321] buildsys: Do not try to build shared libraries with --disable-shared --- src/pkcs11/Makefile.am | 2 +- src/smm/Makefile.am | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 0c583fc1c4..96ab2f753c 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -3,8 +3,8 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-pkcs11.rc $(srcdir)/versioninfo-pkcs11-spy.rc EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest onepin-opensc-pkcs11.dll.manifest -lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la onepin-opensc-pkcs11.la if ENABLE_SHARED +lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la onepin-opensc-pkcs11.la else noinst_LTLIBRARIES = libopensc-pkcs11.la endif diff --git a/src/smm/Makefile.am b/src/smm/Makefile.am index ce5e4c4256..09dcbd47ee 100644 --- a/src/smm/Makefile.am +++ b/src/smm/Makefile.am @@ -11,8 +11,10 @@ LIBS = $(top_builddir)/src/sm/libsm.la \ $(top_builddir)/src/common/libcompat.la if ENABLE_OPENSSL +if ENABLE_SHARED lib_LTLIBRARIES = libsmm-local.la endif +endif libsmm_local_la_SOURCES = smm-local.c sm-module.h \ sm-global-platform.c sm-cwa14890.c \ From 10477a6f8757da16bb36ba7ab65ff07765697319 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Apr 2022 16:43:18 +0200 Subject: [PATCH 2398/4321] Reproducer for --disable-shared build configuration --- .github/build.sh | 6 ++++-- .github/workflows/linux.yml | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 3248db1864..149421c1d4 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -49,9 +49,11 @@ else if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then # without -Werror, because of rest of deprecated API - ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2" + ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2" + elif [ "$1" == "no-shared" ]; then + ./configure --disable-shared else - ./configure --disable-dependency-tracking + ./configure --disable-dependency-tracking fi make -j 2 V=1 # 32b build has some issues to find openssl correctly diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9803ce170f..2277539de6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -36,6 +36,13 @@ jobs: path: tests/*.log + build-no-shared: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-linux.sh + - run: .github/build.sh no-shared + build-ix86: runs-on: ubuntu-latest steps: From 4e2adc8fe3fb859c5657f93288bfb073b4b92241 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Apr 2022 15:08:08 +0200 Subject: [PATCH 2399/4321] Add missing header --- src/tests/fuzzing/fuzzer_reader.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzzer_reader.h b/src/tests/fuzzing/fuzzer_reader.h index fd39f29694..5441deac7a 100644 --- a/src/tests/fuzzing/fuzzer_reader.h +++ b/src/tests/fuzzing/fuzzer_reader.h @@ -16,12 +16,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "libopensc/internal.h" +#ifndef FUZZER_READER_H +#define FUZZER_READER_H + #include #include +#include +#include "libopensc/internal.h" void fuzz_get_chunk(sc_reader_t *reader, const uint8_t **chunk, uint16_t *chunk_size); struct sc_reader_driver *sc_get_fuzz_driver(void); void fuzz_add_reader(struct sc_context *ctx, const uint8_t *Data, size_t Size); int fuzz_connect_card(sc_context_t *ctx, sc_card_t **card, sc_reader_t **reader_out, const uint8_t *data, size_t size); + +#endif /* FUZZER_TOOL_H */ From cfa2d038ad484303b772180d9497113e6de24c55 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 13 Mar 2022 16:39:37 +0100 Subject: [PATCH 2400/4321] Add functions for tool fuzzers --- src/tests/fuzzing/Makefile.am | 2 +- src/tests/fuzzing/fuzzer_tool.c | 169 ++++++++++++++++++++++++++++++++ src/tests/fuzzing/fuzzer_tool.h | 43 ++++++++ 3 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzzer_tool.c create mode 100644 src/tests/fuzzing/fuzzer_tool.h diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 55f55f6d8c..1b426659a2 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -13,7 +13,7 @@ if ENABLE_STATIC noinst_PROGRAMS += fuzz_pkcs15init endif -noinst_HEADERS = fuzzer_reader.h +noinst_HEADERS = fuzzer_reader.h fuzzer_tool.h ADDITIONAL_SRC = if !ENABLE_FUZZING diff --git a/src/tests/fuzzing/fuzzer_tool.c b/src/tests/fuzzing/fuzzer_tool.c new file mode 100644 index 0000000000..e4fd964f8a --- /dev/null +++ b/src/tests/fuzzing/fuzzer_tool.c @@ -0,0 +1,169 @@ +/* + * fuzzer_tool.c: Implementation of general tool-fuzzing functions + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "fuzzer_tool.h" + +const uint8_t *get_word(const uint8_t *data, size_t size) +{ + /* Words are separated by one zero byte, + return pointer to the next word if there is one */ + const uint8_t *ptr = data; + if (size == 0 || *data == 0) + return NULL; + + while ((size_t) (ptr - data) < size && *ptr != 0) { + ptr++; + } + if ((size_t) (ptr - data) < size - 1 && *ptr == 0) + return ++ptr; + + return NULL; +} + +char *extract_word(const uint8_t **data, size_t *size) +{ + /* Find word and return its copy (needs to be freed) */ + char *result = NULL; + const uint8_t *ptr = NULL; + + if (*size < 2) + return NULL; + + ptr = get_word(*data, *size); + if (!ptr) + return NULL; + result = strdup((const char *)*data); + *size -=(ptr - *data); + *data = ptr; + + return result; +} + +int get_fuzzed_argv(const char *app_name, const uint8_t *data, size_t size, + char ***argv_out, int *argc_out, const uint8_t **reader_data, size_t *reader_data_size) +{ + const uint8_t *ptr = data, *help_ptr = data; + size_t ptr_size = size; + char **argv = NULL; + int argc = 1; + + /* Count arguments until double zero bytes occurs*/ + while(*ptr != 0) { + ptr = get_word(help_ptr, ptr_size); + if (!ptr) + return -1; + argc++; + ptr_size -= (ptr - help_ptr); + help_ptr = ptr; + } + + argv = malloc((argc + 1) * sizeof(char*)); + if (!argv) + return -1; + + /* Copy arguments into argv */ + ptr = data; + ptr_size = size; + argv[0] = strdup(app_name); + for (int i = 1; i < argc; i++) { + argv[i] = extract_word(&ptr, &ptr_size); + } + argv[argc] = NULL; + + *argc_out = argc; + *argv_out = argv; + *reader_data = ptr + 1; /* there are two zero bytes at the end of argv */ + *reader_data_size = ptr_size - 1; + return 0; +} + +static uint16_t get_buffer(const uint8_t **buf, size_t buf_len, const uint8_t **out, size_t *out_len) +{ + /* Split buf into two parts according to length stored in first two bytes */ + uint16_t len = 0; + + if (!buf || !(*buf) || buf_len < 2) + return 0; + + /* Get length of the result buffer*/ + len = *((uint16_t *) *buf); + if (buf_len - 2 <= len) + return 0; + (*buf) += 2; + buf_len -= 2; + + /* Set out buffer to new reader data*/ + *out = *buf + len; + *out_len = buf_len - len; + return len; +} + +int create_input_file(char **filename_out, const uint8_t **data, size_t *size) +{ + const uint8_t *ptr = *data; + size_t file_size = 0, backup_size = *size; + int fd = 0; + size_t r = 0; + char *filename = NULL; + + /* Split data into file content and rest*/ + file_size = get_buffer(&ptr, *size, data, size); + if (file_size == 0) + return 1; + + filename = strdup("/tmp/input.XXXXXX"); + fd = mkstemp(filename); + if (fd < 0) { + *data = ptr - 2; + *size = backup_size; + free(filename); + return 1; + } + + r = write(fd, ptr, file_size); + close(fd); + + if (r != file_size) { + *data = ptr - 2; + *size = backup_size; + remove_file(filename); + return 1; + } + + *filename_out = filename; + return 0; +} + +void remove_file(char *filename) +{ + if (filename) { + unlink(filename); + free(filename); + } +} + +void free_arguments(int argc, char **argv) +{ + for (int i = 0; i < argc; i++) { + free(argv[i]); + } + free(argv); +} diff --git a/src/tests/fuzzing/fuzzer_tool.h b/src/tests/fuzzing/fuzzer_tool.h new file mode 100644 index 0000000000..5c83242440 --- /dev/null +++ b/src/tests/fuzzing/fuzzer_tool.h @@ -0,0 +1,43 @@ +/* + * fuzzer_tool.c: Implementation of general tool-fuzzing functions + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FUZZER_TOOL_H +#define FUZZER_TOOL_H + +#include +#include +#include +#include +#include +#include +#include + +#define HALF_BYTE ((sizeof(uint8_t) * 8 * 8) / 2) + +const uint8_t *get_word(const uint8_t *, size_t); +char *extract_word(const uint8_t **, size_t *); +int get_fuzzed_argv(const char *, const uint8_t *, size_t , + char***, int *, const uint8_t **, size_t *); +int create_input_file(char **, const uint8_t **, size_t *); +void remove_file(char *); +void free_arguments(int, char **); + +#endif /* FUZZER_TOOL_H */ From 345541dfa9a90a8432490912b763a91bf87be3e9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 13 Mar 2022 16:23:32 +0100 Subject: [PATCH 2401/4321] Allow print usage and not die --- src/tools/util.c | 10 ++++++++-- src/tools/util.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/util.c b/src/tools/util.c index bf37597c08..3bb95bcfac 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -259,8 +259,8 @@ void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr) } } -NORETURN void -util_print_usage_and_die(const char *app_name, const struct option options[], +void +util_print_usage(const char *app_name, const struct option options[], const char *option_help[], const char *args) { int i; @@ -306,7 +306,13 @@ util_print_usage_and_die(const char *app_name, const struct option options[], } printf(" %-28s %s\n", buf, option_help[i]); } +} +NORETURN void +util_print_usage_and_die(const char *app_name, const struct option options[], + const char *option_help[], const char *args) +{ + util_print_usage(app_name, options, option_help, args); exit(2); } diff --git a/src/tools/util.h b/src/tools/util.h index 929928d827..49c8da3ff7 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -39,6 +39,8 @@ extern "C" { void util_print_binary(FILE *f, const u8 *buf, int count); void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep); void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr); +void util_print_usage(const char *app_name, const struct option options[], + const char *option_help[], const char *args); NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[], const char *option_help[], const char *args); int util_list_card_drivers(const sc_context_t *ctx); From eb3185712a3bfbfc42f4503c12461200d3e57bfb Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 13 Mar 2022 19:56:40 +0100 Subject: [PATCH 2402/4321] Add fuzz target for piv-tool --- src/tests/fuzzing/Makefile.am | 7 ++ src/tests/fuzzing/fuzz_piv_tool.c | 175 ++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 src/tests/fuzzing/fuzz_piv_tool.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 1b426659a2..a74002aae8 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -13,6 +13,10 @@ if ENABLE_STATIC noinst_PROGRAMS += fuzz_pkcs15init endif +if ENABLE_OPENSSL +noinst_PROGRAMS += fuzz_piv_tool +endif + noinst_HEADERS = fuzzer_reader.h fuzzer_tool.h ADDITIONAL_SRC = @@ -30,3 +34,6 @@ fuzz_pkcs15init_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) fuzz_pkcs15init_LDFLAGS = -static fuzz_pkcs15_encode_SOURCES = fuzz_pkcs15_encode.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_card_SOURCES = fuzz_card.c fuzzer_reader.c $(ADDITIONAL_SRC) +fuzz_piv_tool_SOURCES = fuzz_piv_tool.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ + ../../tools/util.c +fuzz_piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) \ No newline at end of file diff --git a/src/tests/fuzzing/fuzz_piv_tool.c b/src/tests/fuzzing/fuzz_piv_tool.c new file mode 100644 index 0000000000..28e7b124a5 --- /dev/null +++ b/src/tests/fuzzing/fuzz_piv_tool.c @@ -0,0 +1,175 @@ +/* + * fuzz_piv_tool.c: Fuzz target for piv-tool + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/internal.h" +#include +#include +#include +#include "fuzzer_reader.h" +#include "fuzzer_tool.h" +#undef stderr +#define stderr stdout + +/* Rename main for calling in fuzz target */ +#define main _main +/* Connect to virtual reader instead of real card*/ +#define util_connect_card(ctx, card, id, do_wait, verbose) fuzz_util_connect_card(ctx, card) +# include "tools/piv-tool.c" +#undef main + +static const uint8_t *reader_data = NULL; +static size_t reader_data_size = 0; + +/* Use instead of util_connect_card() */ +int fuzz_util_connect_card(struct sc_context *ctx, struct sc_card **card) +{ + return fuzz_connect_card(ctx, card, NULL, reader_data, reader_data_size); +} + +void initilize_global() +{ + /* Global variables need to be initialized + since libFuzzer runs more test in one thread. */ + reader_data = NULL; + reader_data_size = 0; + ctx = NULL; + card = NULL; + bp = NULL; + evpkey = NULL; + opt_reader = NULL; + opt_apdus = NULL; + opt_apdu_count = 0; + + optind = 0; + opterr = 0; /* do not print out error messages */ + optopt = 0; +} + +void test_load(char *op, const uint8_t *data, size_t size) +{ + char *filename = NULL; + char *argv[] = {"./fuzz_piv", op, NULL /*ref*/, "-i", NULL /*filename*/, "-A", NULL /*admin*/, NULL}; + int argc = 3; + char *opt_ref = NULL, *opt_admin = NULL; + + if (!(opt_ref = extract_word(&data, &size))) + return; + argv[2] = opt_ref; + + if (!(opt_admin = extract_word(&data, &size))) { + free(opt_ref); + return; + } + argv[7] = opt_admin; + + if (create_input_file(&filename, &data, &size) != 0) { + free(opt_ref); + free(opt_admin); + remove_file(filename); + return; + } + argv[4] = filename; + + reader_data = data; + reader_data_size = size; + _main(argc, argv); + + free(opt_ref); + free(opt_admin); + remove_file(filename); +} + +/* Skip argv with option for output file */ +int present_outfile(int argc, char *argv[]) +{ + const struct option _options[] = { + { "out",1, NULL,'o' }, + { NULL, 0, NULL, 0 } + }; + int c; + while ((c = getopt_long(argc, argv, "o:", _options, (int *) 0)) != -1) { + switch (c) { + case 'o': + return 1; + default: + continue; + } + } + optind = 0; + optopt = 0; + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + uint8_t operation = 0; + char *filename = NULL; + char **argv = NULL; + int argc = 0; + char auth_path[50] = {0}; + +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + if (size < 10) + return 0; + + initilize_global(); + operation = data[0]; + data++; + size--; + + /* extract admin argument and set file with admin key */ + if (create_input_file(&filename, &data, &size) != 0 || size < 3) + goto err; + sprintf(auth_path, "PIV_EXT_AUTH_KEY=%s", filename); + putenv(auth_path); + + switch (operation) { + case 0: + test_load("-O", data, size); + break; + case 1: + test_load("-C", data, size); + break; + case 2: + test_load("-Z", data, size); + break; + default: + if (get_fuzzed_argv("./fuzz_piv", data, size, &argv, &argc, &reader_data, &reader_data_size) != 0) + goto err; + if (present_outfile(argc, argv)) { + free_arguments(argc, argv); + goto err; + } + _main(argc, argv); + free_arguments(argc, argv); + } +err: + reader_data = NULL; + reader_data_size = 0; + remove_file(filename); + return 0; +} From cc55f918da4e6ded09eeb215f1843e1bc4d44da2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 12:03:49 +0200 Subject: [PATCH 2403/4321] Add corpus for fuzz_piv --- .../5cc15068920eb3c897b0129a6939e3b01574eb02 | Bin 0 -> 277 bytes .../df81168351db4e248a9a915bb521c85dce1d17c8 | Bin 0 -> 3048 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_piv_tool/5cc15068920eb3c897b0129a6939e3b01574eb02 create mode 100644 src/tests/fuzzing/corpus/fuzz_piv_tool/df81168351db4e248a9a915bb521c85dce1d17c8 diff --git a/src/tests/fuzzing/corpus/fuzz_piv_tool/5cc15068920eb3c897b0129a6939e3b01574eb02 b/src/tests/fuzzing/corpus/fuzz_piv_tool/5cc15068920eb3c897b0129a6939e3b01574eb02 new file mode 100644 index 0000000000000000000000000000000000000000..6a0d7a0e6eeb8d441c66093f75edb782b765a172 GIT binary patch literal 277 zcmZQ!WMJ0KW6;$tPA$qz%wb>@6Xn**XQUZ2T!li_ZA=uhL^2&3|TZyLjaCY&Wx0dIM=Qd|VC~`Onv?!i%5;*+YL}0pb(|^sl en>7Uqw;g#_T!}K}FfuSUFfcSQv}5=ObSnTRhd&em literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_piv_tool/df81168351db4e248a9a915bb521c85dce1d17c8 b/src/tests/fuzzing/corpus/fuzz_piv_tool/df81168351db4e248a9a915bb521c85dce1d17c8 new file mode 100644 index 0000000000000000000000000000000000000000..85f4387068ad7c8342da93015182357b6b539733 GIT binary patch literal 3048 zcmeHJeNYqE7Qed*N%#iw0V+reQUOD_3&9YS+BA$v`zT<5D$@ss5JG$*q1nKbQlDhe z45k&Z3KWW%YLON{YHJlOf|g2KtthQVDJs1B0aynS(DE!FeY=4Ob~@JS^pF1WW->Q> z&pG$p-QW569V-Ml2L|FYjY6UXU=~=iz8ru8tUz|K(An)$At(hXkj!=k|DF|VYXpGC z0>B9%ATMv74-luHzzFymjDj&R4kjiYJeAQOeS;^Rd#a0{ z%IFEVtS$H*`~ZrG3F}}u=VGs*6R++UoWpm#m$~}TJ9Y153jK&Z!bFV(>pCgwLJ=C~2<;ixYxFA+ z8I6u2Rsh;CSd&`@Vk8(GNHF{$VdZ3`p$Lj149a}U5n@Z4ufuGiHG`H&XSkq=V$2JA zQX3l=*8~}^Ws77Qts+Aqm1t!+I~ZaRbAk?(fvpR3(m;qUhCE6_a|tv{;-ZrRquDFP zLeicW7MP|Wy$B^#j{P483I~Lpq1Lc1P_ac4O*#(eyV;Z2Lh=_D0wGLxvnPW;y@m3} zqvQ@H=G`>k9am(tdF zx_7(?yX?2K<;eY>{oyGachv5@`1uyYCs$95%n9%%iniKjRvfo)8$9vi1)6E}4u8wS z?)HlG7U6+shc3A6ZtAreJrlEK!D?m4Q2NEzv5jKh;;Z=;!F*H~dsKiWL{;aR($(LZ zVuabkzKOKLyqww>d#klqV(~rnf1N`6hfx{=klh4&782;!Br4{t|rAR)Cs6Cm2p~ zpx>jfKqw6K9u{n5Ql%t~&s9lrr5PdWbD-`XnX;Z3bfn~T8pi^$%Q%xsu=1T~%LGZ?kIceO60yZN+Op##Oj$O<;KFjPCW4@p4Y! zqTU?8l$Nkl8$Y{~*xUXV)-s+Yd4F}JGljuOy;W#i9YHf0_RQ-n<1`MZRxJ^5@=e7H z>V6>F+GMN~hN!A-t%i*Q-ygfE@*d&Z9PnzqIeyJKzWFo%xe-S`IB@vrjifId58uu# zwNQVXt)ZL;u-Tm*@yvT-K-WexL~OdztmZ zns9LuF7`iEne^@}O1qkQz9q1)=h!MiN6)t9Yn@WL#w=N%X;u+Npa!z$^(cbC^?xdJ zQW(r=%fDjJ-(ZX>CZ9q4WNnavw{W{P4Vy6tK#ysK73N5i4F-8Igd8!*H5mp?Yw4Ib zoz1!VkIhNagH1O+n0sEb!KVMUt;~!y;t%6Pn2E{Px?T^5Ige%xD@^fckrRc1d5(A@ zK|Mac&=>L=CVV=+4 zHx00%Y@hh!I8*t_j@V-EtISvrS9a6Hp23rW5o1@5?dls`9onkf<6ucr U(@%Ff{$#s@IB>yz12t&>4~$9QcK`qY literal 0 HcmV?d00001 From c5a8f1c55085a5a635e75d6bab2524572ac3d633 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 25 Mar 2022 14:57:31 +0100 Subject: [PATCH 2404/4321] piv-tool: Do not exit --- src/tools/piv-tool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index ffeae2e31d..d57b64f714 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -634,13 +634,15 @@ int main(int argc, char *argv[]) opt_wait = 1; break; default: - util_print_usage_and_die(app_name, options, option_help, NULL); + util_print_usage(app_name, options, option_help, NULL); + return 2; } } - if (action_count == 0) - util_print_usage_and_die(app_name, options, option_help, NULL); - + if (action_count == 0) { + util_print_usage(app_name, options, option_help, NULL); + return 2; + } //#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) // OPENSSL_config(NULL); From 2c1550332caa899453e834c5b22bb56ed4e6763d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 24 Mar 2022 18:03:04 +0100 Subject: [PATCH 2405/4321] piv-tool: Check length of serial number before using memcpy() --- src/libopensc/pkcs15-piv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 1789cd8357..405d44a973 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -144,6 +144,8 @@ static int piv_get_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_o r = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serialnr); if (r) return r; + if (serialnr.len > SC_MAX_SERIALNR) + return SC_ERROR_INTERNAL; memset(guid_bin, 0, sizeof(guid_bin)); memset(out, 0, *out_size); From 6465263143379833bdaf69606c496ccb508ff35f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 12:01:28 +0200 Subject: [PATCH 2406/4321] Add lock and unlock operation for reader --- src/tests/fuzzing/fuzzer_reader.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests/fuzzing/fuzzer_reader.c b/src/tests/fuzzing/fuzzer_reader.c index 879c71a25e..aea171aaa1 100644 --- a/src/tests/fuzzing/fuzzer_reader.c +++ b/src/tests/fuzzing/fuzzer_reader.c @@ -136,12 +136,24 @@ static int fuzz_reader_transmit(sc_reader_t *reader, sc_apdu_t *apdu) return SC_SUCCESS; } +static int fuzz_reader_lock(sc_reader_t *reader) +{ + return 0; +} + +static int fuzz_reader_unlock(sc_reader_t *reader) +{ + return 0; +} + struct sc_reader_driver *sc_get_fuzz_driver(void) { fuzz_ops.release = fuzz_reader_release; fuzz_ops.connect = fuzz_reader_connect; fuzz_ops.disconnect = fuzz_reader_disconnect; fuzz_ops.transmit = fuzz_reader_transmit; + fuzz_ops.lock = fuzz_reader_lock; + fuzz_ops.unlock = fuzz_reader_unlock; return &fuzz_drv; } From 217590ce6d0d02bb9abe20ac26bde8774cf8c8a4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Apr 2022 12:39:45 +0200 Subject: [PATCH 2407/4321] Add fuzz target for pkcs15-tool --- src/tests/fuzzing/Makefile.am | 8 ++- src/tests/fuzzing/fuzz_pkcs15_tool.c | 98 ++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 src/tests/fuzzing/fuzz_pkcs15_tool.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index a74002aae8..759b80cd49 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -7,7 +7,8 @@ LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/common/libcompat.la noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ - fuzz_scconf_parse_string fuzz_pkcs15_encode fuzz_card + fuzz_scconf_parse_string fuzz_pkcs15_encode fuzz_card \ + fuzz_pkcs15_tool if ENABLE_STATIC noinst_PROGRAMS += fuzz_pkcs15init @@ -36,4 +37,7 @@ fuzz_pkcs15_encode_SOURCES = fuzz_pkcs15_encode.c fuzzer_reader.c $(ADDITIONAL_S fuzz_card_SOURCES = fuzz_card.c fuzzer_reader.c $(ADDITIONAL_SRC) fuzz_piv_tool_SOURCES = fuzz_piv_tool.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ ../../tools/util.c -fuzz_piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) \ No newline at end of file +fuzz_piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) +fuzz_pkcs15_tool_SOURCES = fuzz_pkcs15_tool.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ + ../../tools/util.c ../../pkcs11/pkcs11-display.c +fuzz_pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) diff --git a/src/tests/fuzzing/fuzz_pkcs15_tool.c b/src/tests/fuzzing/fuzz_pkcs15_tool.c new file mode 100644 index 0000000000..c57c8a9a45 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15_tool.c @@ -0,0 +1,98 @@ +/* + * fuzz_pkcs15_tool.c: Fuzz target for pkcs15-tool + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __APPLE__ +#define _XOPEN_SOURCE 600 +#else +#define _XOPEN_SOURCE 500 +#endif + +#include +#include +#include +#include "libopensc/internal.h" +#include "fuzzer_reader.h" +#include "fuzzer_tool.h" +#undef stderr +#define stderr stdout + +/* Rename main to call it in fuzz target */ +#define main _main +#define util_connect_card_ex(ctx, card, id, do_wait, do_lock, verbose) fuzz_util_connect_card(ctx, card) +# include "tools/pkcs15-tool.c" +#undef main + +static const uint8_t *reader_data = NULL; +static size_t reader_data_size = 0; + +/* Use instead of util_connect_card() */ +int fuzz_util_connect_card(sc_context_t *ctx, sc_card_t **card) +{ + return fuzz_connect_card(ctx, card, NULL, reader_data, reader_data_size); +} + +void initialize_global() +{ + /* Global variables need to be reser between runs, + fuzz target is called repetitively in one execution */ + ctx = NULL; + card = NULL; + p15card = NULL; + opt_auth_id = NULL; + opt_reader = NULL; + opt_cert = NULL; + opt_data = NULL; + opt_pubkey = NULL; + opt_outfile = NULL; + opt_bind_to_aid = NULL; + opt_newpin = NULL; + opt_pin = NULL; + opt_puk = NULL; + + optind = 0; + opterr = 0; /* do not print out error messages */ + optopt = 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char **argv = NULL; + int argc = 0; + + if (size < 10) + return 0; + +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + initialize_global(); + + if (get_fuzzed_argv("./fuzz_pkcs15", data, size, &argv, &argc, &reader_data, &reader_data_size) != 0) + return 0; + _main(argc, argv); + free_arguments(argc, argv); + + return 0; +} From 42bf95076dc8177c1925443cfc383126688df5e2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Mar 2022 10:17:43 +0200 Subject: [PATCH 2408/4321] Add corpus for fuzz_pkcs15_tool pkcs15-tool --change-pin --pin 111111 --new-pin 123456 pkcs15-tool -c pkcs15-tool --list-public-keys -k --list-secret-keys --- .../14cbed013fc24e65150bb6f737322bbcdb064554 | Bin 0 -> 10412 bytes .../84ec9c1c1720fdb2fe094168fd81905260421077 | Bin 0 -> 8952 bytes .../8c1c42b8b9ac94f0d913814685c18f78d0aaa922 | Bin 0 -> 1973 bytes .../ba99175e1d1561d6f5a38eee98f9b4472b9159e2 | Bin 0 -> 2686 bytes .../bcfc86233c2a553dd03681e139a44777e2dbe7db | Bin 0 -> 1783 bytes .../d76c9da7e83d1c9bcd27310197bbd01ee1746a3b | Bin 0 -> 1715 bytes .../dc9f8237a8e5d94119db6894fe81d5e18cbee80c | Bin 0 -> 3803 bytes .../fe4d8242cdc4596d8163baf8dec8ed1df88c0228 | Bin 0 -> 2649 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/14cbed013fc24e65150bb6f737322bbcdb064554 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/84ec9c1c1720fdb2fe094168fd81905260421077 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/8c1c42b8b9ac94f0d913814685c18f78d0aaa922 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ba99175e1d1561d6f5a38eee98f9b4472b9159e2 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/d76c9da7e83d1c9bcd27310197bbd01ee1746a3b create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/dc9f8237a8e5d94119db6894fe81d5e18cbee80c create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/fe4d8242cdc4596d8163baf8dec8ed1df88c0228 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/14cbed013fc24e65150bb6f737322bbcdb064554 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/14cbed013fc24e65150bb6f737322bbcdb064554 new file mode 100644 index 0000000000000000000000000000000000000000..3d906a65cf3ae63c97129fdeb42ff4aaed832a3f GIT binary patch literal 10412 zcmeHt%g^-KnOD8<_jPCDd?6Vra}ilgBQBc33ci=i3Q_R=Qnt%>U3^*L``uOLTiF)U zbP}c)tXeEsAR#5dXxO03yXmAD>fo ze&;#Q^Lu{J`A*q|o6R>i-~F%uWV87J@;`WO=4I|%zq7gi%^y7f?$3VswENMs@oOKw z`qkh1+3!7Xp8wI)SN`FfA8$6B(Acxb?;ym-n_u6&9rF6U_twYf4gB6$F3!{N@#gEB zr_JwvbF=xAr_J+MKi+(MbN!7EpEn==@agGC&(P+hSFgVRGUH~Q@#D=8H~zN|Uzpc; z@9nJS>+f%jUt1^sMSnitJa3ARevV~-x}FuGbv*|1(W|G=t>@|K#{m2*uit<9@!a!I z-nC!{L6RkSHJ(R{oWtEYrp@m-nE~8(HQ(+od19A_aA+N5BkOZ{^Je&gFk$J z+PntV@BGwe-n^m5xanK}1GSI-&WE4u|EuTM@IUY2Z$CdhJwJc*2k&iOJwLyB|Equh zBk3uA^?H5yw0Y@#UORvIzjr==+PMz-vm<}!)6Um_-pIebcK-ga{^mDO7)1~ig%Jc_ zTi$1jdhbu)E{c2qi<|!Z1phYtwKwloeh^o$p5Om_@Ymmb?N){zLVPE0^8TF}2>(BA z<mm9jUD;nAgfB7JY`(8i?aTKAsQbTXGWFT5B9wK0izz+{o8H;s7+C4L^`B>nc--z-tS8|Gaq}L z){5D^lSA5&V55VIR*{||;Nx(m*y)U(jkZ@>6$3`R;^bpkJQDU%)vA?jK~^I|N@$OY z*o{@Z5BYts_8n57XS!DoN8i`>5?`v|Y#&Dw*dDfMUs}mtr7C!V1O2`%Bs3Cr4kd=# zUNx+TC)!RT4DSsmql_C$k1Udrie*by!U1EF5BbQZnKUBq)w)5(jY6-|i<`*J0;^!C zpNhs;c;UjZ#eBq!tf5LpF4E|(#HO~~Lmr@R=PlY?HPImWj^p=}26wR3`4t3f7~=$c z^{A!lRm;g{CtY$qw;v62d^D1=&#O8xfkn=i-F|ScY%9uOr?Zvo3W1+6{rw>rM=1>6E>6(;SOb{r__EGkZpyD2tGO<06d2@rwo0ms0 zGG3f9G*8=^7(@u28rIJhxZj~BU>9YP9Sl5oakeDV5aR0>493i`9J}`q64>5o^$uQi zwIVV_M5QEl=*GW3kch30v#FEwqs>r^ouzc{ZNz zrDzQ6?k027-GBRxpu_r70=_7~YORmKX{*o?&+`vnrn!z4ADX~EN||}cqF`PXmhM=F zaasDovr@{l0#4hqc^ZM))4}QnU5rN5x#*<&pkyMH;2qO5>oO14F=dZ7={;+4@A|G8 z%h4=zUX%_vl=D%d-uX058^K5u$`w{`{_1dru$=ODFJce{q1y zl|?+=S;sMEx0-XvGTC|0nyE^srcI|BLudH^!mIBz%q~QC%9MMe!EUEbs*bN1h9YSGEphjpdX) z1a|JvFp?`rTeHv!nFur)L~^tlvj{@nz45MxlTOzh2YGu(7pMv-9Y~#`Ip0HHdK_+g7Mk><3hdJW zq4ssqhzD3_*PVYk%-d1BSHjMt!o#&-Pua}e0u9&CKo^TO3)ZeR!H>SYG%cu0Hfy)l zX=(Ig$Db5c^ne{Jf611aGOmSa6lnn~xU^0AW{&@i~r|d*>c^@NqiO`T72E zg*=>R>NG2QeUpjH_#ng-ZiMxmCcRFs=f>*=4`xHa%p%7o1z7SG|JtXX!_=vLE`u3| zaOYu7g<0Jj?0zGexfOeA8YSvEL^bpD}Hwo45Do2qeQ<&CjREAHR z54wdNqmF4&o*#HAPqJguxg87RWM9D1CTqa=W(r&V&#r*UnLjKHocENo9NUPT96VE^ zt*{fu9z0uBQ-j*&vP?sOENKqI@e2mUdYTI}~FkaLT7(=O_2qS^Vf&54YzYT1Y(coCA9snIktdE&S_hc)wq^|G;4?ES)Qgs$CW`0X;o`JOCJxRXKasQ$ zWZHB@+VN(%G007*IqpcQulKA0Oo8CJP_@L}?!pp-!LfEYP#xzTZEF!JBgPZkrtCya zYvCkW!~-L#t;RVo7 zVS~BkxT8*laqR*pz&cO?4r`1fF=19hxUk~#vhIZEovws^H}vj4-)M$sXj)WgOy)&; zjj62rHeP-fE`k3;yyVbS4(Qc!(>tZ1X^H-P+X+W}8zeih`rDf<0 zlaW_B7Dh+`P1FSzSGP~x-fE$%OXHPy&l6NuA!JB_;wp>-nh*?z`IK*%?nz|$%0c9^ zl#YXVk)s-hxb}9j$-LF$95rCv)M+d0S(ZIQ2r!1raoj=SPPiFygXfP_;b%5i9ST+) z3S=q4DI$p{QP-r6JY;qVwwJAkfcrH;8m0w!phve*MrXr}^?SG=9BI4H1hPMoJE*b2 zpqdY+bMPPswcEpkf58B)hPj5>vNLn??xPSuiTA_Y>2eT+8D><8Xo`1GpOfI|WETO1 zBXpab9^jM*sg*97O%6V5X3JpiIuRmp97v%WzA}k;CCk|B)Olhu5OkZgT=*pv7~6~H zFgZ3k%rN!9$~+ADJUvYJX?i5(@zw*%Q0H`iiWrc}xS*NMn3A2V#4bBpG9EaT=a*YG z6Dn`F^K`6n@m3-&eXj7cwb$!P2Cn8!nq+vM_UNN=Z3>;w7U$SosIAD0s$)9bmZjkY z&9SmyFwhb2I88ezQ3OrnlDj7RBQSYLLy$0XBozF>;X`k;2bu8_+}v?`T?9@PI#Lkq z@FS$pTpLX)3ZKzvKFwqrT23wsJh9JEI=aV{_etCew~* zUku~pW0nbL=dqZltcPYCbO3KWsj;YD#Uaq|NyVpS`y|>eA#It*iMs8tL{VVl9FI(V z=UNhnjM1(*^b*d-uw!R{tLQrw+Oc*rq+zA7QZg`^0)Zx})fA;zpk7*%?5vvdiosUf zlL2faxx?K{_6{lH>CS2(z)kpQ4lG~ho!DNes?8;_Tuz~&cAQ3v#kD>hwQC|C(p~N^ z6UO2zBPwqOpBzFFH$q@{!4lBD^iG7kY^~?rm3H-R_InyN^leSY$gX_cE=s1rN#aj3 zB4g0ZhB1?Rwp-;Hpf1bKx@6Z_w-dgN`-$#%3zkvEh@M5M4f z+w*nkO=y7@Oa@vM_bkKvsX_@Nah#_|x;>_y(rb|&KWwDCbc6nFs1)k!p(cgyAI-N%;7Pt<@CK1&~a{|Mi!ep)h zRH3zWp>Gt2?V{Bvk5sr8dfV&5p9Lhlsumk%f}<-UP8^FzzZ;9dy5A_4ogZ~^=t=;q zx)M=fV_C7yP{lVAdi8BelC-n@g2Anp7f7!~ciYEmp>W`XPwm7yx*Cxz2*iWjN(a|8 zUP_|~0t+>!ZuNW(G+%YLRoON&8dg11Wn7ByQ5f=WAuNr=BNN4F{oznlOOQDL1*f$1 zde--Thb%45Mi1IrvpXg?#T~<>3`^6skn=pbt53U zLs%a#LoAZ!aYu?<5^2TTnz9r^gOCU0jI!u0*+aCbi*bS+Zv(amzz&q9>~;@{Ep|;P z*6-FR0oNHMLq{$h%|(YWrCAuyHcw)|&7oPg$0nNM+aUU=Zvgi@3i$yq;JL7_Nb?roH}#x>yv6ryB08}oNW!5)6}hoShY4cbFK8Z z)@fE6bwV3KyinynPxYkSdG}d5Q%J22=Mg78=s0c*K%|ia=GHu>KvpMWyDM$ato#VJ z76Fndu0`Fb#EckU`G6Qc6~7qex{6K#t0_1F$baTHM7&;>?rJ#!*DjTZ=JWb6sb0dB-in7CG4mvP+-p_9pLJyGMufM!JON_Lk75rH5g>O(78ur}-*k}z};F3kgV z!$wd+1NU(X=Zn4HQh8F&IgIY=rmi!9)w%7Nj$5xA@~WG=$02s@K;DOE6zVe!g#@`0 z)|4y9xH3&T^>z;ZlT9pGWvjg(O~7M5Ondf$W{4k)$1c0xg9ksI2IP@ygkv8(ieb-@ z0qnqaB3`dX8|&hE1!7}C16b=6Y3+`E*ik9u`z zUOWpb6@R{mJ(HZ*F!WaZ0%*5nM%r{=FnHm}O7=x*;LleEj{d3)q>Nc|k2<7*w|x0? z3V`3Zs{)WRNLgtz26K;Xpy`TNfJADw4{EZ-g_; zuvaM@8lRe6%1vF6Zkm}+ilaJr1KDAaiH{RA=`vP#Y2Mgz15~VWJWY739u2)(@{!u7 zA&peWVtzD7bx+{{V=gTxi`oklyJ())*bR<& z>1LgIgs!#-=fxMUe8xs4V~?4G!xw3PNHx+pDS1_tcYsi8rsMSFY$kAfv%K@1f&N*! zR=U?f#Xcg#ZVF}O!Q9MJoGAwqKtz*rX*XAFSMj5TJDGwiJn-@6_crP2kSWC!c5dVur6+28ObJ#g zpuc&;Qu*;6-xo6EwYCwTJmg+V)+G*)eykr=;k%EXz4ZD~cV6Yx=$K z0pH`u0|>ko=Xss`3zYlM^#9Mw#m|4HT)cU{jIP6>G%)kpT2s2?}Jy*um0^?4FAbD;lJ|P1%v%s{(imr z@n106fBx71=0E-Hum7`u_tXFI=DXiN|Mb87;eY(_AHSRI`3sY+rS$(-HQX0l{iUn= z{G1E=5`!;Gr7tG)r5$`(F8;!mGHxvwfBuTx8Wz3_|J66&I>zD9=KcJ^AxZKuZa*+& z{UvU|>vgD~{p2^{Uw`$y`8x1&GwSv8)32<5A3nYGz%cxcH(zD^E)PFH;^~tS&u_js R;%Oc6b2_qL`0F2U{wK4dmT&+7 literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/84ec9c1c1720fdb2fe094168fd81905260421077 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/84ec9c1c1720fdb2fe094168fd81905260421077 new file mode 100644 index 0000000000000000000000000000000000000000..96cf335846f2b2e74d70dd2ea6513ac39b56aa37 GIT binary patch literal 8952 zcmds*cT`i`qV59-Y$+DNfFMPr69~OX-vUwv>Ai$NkQN})lp>&8kRrV|=^aFRub~$K z>AgyqE+xq&TkqLt-|M*dy>Z?jXS_MaO0vGpHOI(rt$gzvAD1nF%L2fK001ZeVm>hd zz$@NYmZh&{Bu>a~qW!`ExB%>7euokOC-=q0m+`~F@yEr%d541^jE6^c^(7dP>cb%& z=I%rme*ZoWz(X1!Po@NN#p8QrjmLj=2)?og0Px5FKga*Uinut$xHy1Y7Us^-XVCw= z?rIHOT)+*iXkqo2h=Ypu$k=J^gDYA-)_|&it z6!@D+jBkq-1^-#R`uxj*g=FLR*I^E%0>CMJaRImf#E<(Y{%eoO$gcR4{R8=bqW|-T z-J=7*sjseJ{BZ?7_J&=1L`4Ni`tvmma1DUN5C&ibD8UidF6Im>44TiK%@GI(OJ|0^ zjelMZpX|qK1pjR{0ssy`nBZzI4))zWiQgK+FJujgZ+I0S7#Df9S=%G*M8L36 z`>eSanfGPw^GR}Scz9xTOPW*T{VE(*8U!10B9EqZ>4$t@zJNAn&~mJ)R>adN)3gN> zt%StHxSWL~Q>`%5D7}dIRG76{8leV~t1$FKA3vC@iH)*Q_~aSB2~nb$i4r zjtic40Ad9fui+qwUy1yV=h3SZN@gJCdKQq~x|%93-jM1UwE!>2{kL}?aN;4zA4uV; zCk5pNhKDbPhh0XE(~FN`84yS+oaG&TP#B%9GB%^%kgJZ+h?69Z-lacin5F0)`VaHYNhOa^G3m_j)kj z+W7Q%*OTgERkmb=a5}2$j5cZH`-+kC_g;A^sa3g#{*3|$iODUR)>}(4& z0#_&=lv+Q&xtYxhB%r^BR!vB@KY4+yB7e&?p|7`|x?%Vs+xsE!v*w)s7fzp246 zs9~;drCye1EhA%SBCn|E8{O#bZ1Yr638I*8LMNazaz8vjHYt@jc2teKhkXo8z|4qB z8!fxs9;L`p(&KxTjq47<%MrBJz{?SkNOSNrzLx%96xQ z@hLh#@%7*v6-?>q$ht;L9+hf}>vUZ`!xv}904a1Qx8kh31K$kqW*E`Zr|=C&-f;enoS(Q)u203zNIgR~E{=pmh67)}oJ0VadtZ?U z9JX+qnB+B-iBQT7Ceb-`>n4U_FifFbbpt17&Er#CNxC}_C`)#zUrij2eDO4 zCAh4`b!>D~;)s(riGmz2wSh|)x24w#ogVq-5wWYnAZ^O6t z+ur1T5`wb_i|S6A&VFfWeVBzx11^KPBWbc76usricL`Q>?_&2?957K7aH zIDSdRAQboW?{RgU2i50Px~XhONEpr>OG*}F^?rR>(9uC02A zsg(~{#WAJkiJDKo5mUv%4&Zb+x7|G63_R9*r;e!&M1?>8f`Lu@rFt zcM1P=RZ2l?NRe@KUwc=3J8O|{ouct-q6pqC$61~Q%jHp^?=nK!5sbls(qS{17MCWuo9@dZ;)SrX9$md z8K~2#z7`)FV;V)QlYJ{9At^jIH8R!YnYDu%(Qpf>@a@Qg)|-Wh_U8=o@hP$KvBeA9 zxmylU2G#*vYjbNT6k`3%&Kd&5Uol{GB2Di;0BGI)R2r=7?Iiy!-S0i!&`Emx(o+2> zBR(l59zTNkfvP`?JoCye3#g@;17rmTc!%H>ysg>X!&AZo!WiX=+RGuFl z%`qtoN?rOU*=Tq~ns|orJv_V|qpC%*30QAk4!JHZWr4S-gX&|vtDZWFbY|;N8+5Hp z!4q@jgiC@H6VjdDc3o_la7y;7LOiP&AD=ZnjGgMqv+@%b>EI^ZQkmX3+w_}DE{Md; zHQmOzT094MNSv9CZA!4`EsFm%{YQra7OGQlI3!=IJF z4Z05Y;#`YlM^UE(Dh<%awO#_nnZqw!nNqp;@)C^t3`JXH22rD8iC6}YYgPJ!NrHnC zrc$C6xlGI-nVy1g zQs-=hv3*e<7<{9=$x69Ou|?@05$3IKqwno%^G=f)bX$4^AfD%|NiFcfcO;%py-H^J ziO>yuA$c7gS9$puq#!{EC#jM-BY}#2JdcOQY4ZqOqJ%eE1>T9{5n*k17 z7KucoQf?B(L9`47> zA@7I#NxA;eHN-c3zvFCw`Q={Z_|d+)d~ZV_(Vvc*{y#Y?HNAfnN2$P^kafLzSO*d> z=3;N$sJFe#?v~{(oRQ9UwzWqFoH`V~bPASqr2K8L~_ z%!C2?0GAzf?{X&j_@1&d-$4+cGRNm0eY3pJT|Dzkt7EnHWR;h!p(Qsy8*vZUn}s6Z z?(h{6d>}?C_Ho+W_P^QzgVtW>!Y5v0seVM(@QxJN;v=x2Wt!DTpYAz*of6U8B z%s%8j&Io+m89jw%&{4;t`d;lw-{%Vp`gBu~QdOAMb&KNR9nX$g1~R+$;Q=pBN89G7s2W4$abzRZ_O^x z^`p-Q^ckGObGCJP)$M?!<+mqx^#U8Yo@VZbBff*M zYm_@qhA$1rS)`mXQ#lao3uaT)R|UP(g^m{Ez4tYD0$e6BRwA>d&z1#pHeV*|a#EXu zNzS=|xg!@r!tC`R^5PySjM(YrIWQum8V|x90h_T2W)$gB#d~PpX=Q{xtBm*h{qA)X~Y~ z65Uf86-0w^?G!|l=E3}qXGq%Vp_D@BC^~n-)XT>LFSfSw@@+h4)ibzcmT+uMjd0T= zt+5vugX}ExDsyz|9^a#lPoymeYdc@ANOg+G9|bOt8O>*qyJx_NQp8YREp?>4cLIYG zl^!^JGx@G>`~}mpc5ny_YGtgZ6?A=4@1k6HcnsVj{Ghy!ITv*rxzx4OUUXAq8@TlN z+NTfOVXvU9y}=2e{OWub)f(kpKsao50roVR)TtDi`aN|6d71y}y)bG%CHBihsi*Ax zsKIrp=HQCiING2g>E@PjKv0=jrj$kh97fh+S)40+-380wV{JH&zX-$ih#~Ul^N+xnBPN64G%yll5O2(w~VVL90%+N}{d0(Y9pX+(--BB@2PHgH^M1a_gzLsnN?t0fEyeP(1a zR6U$V!2)R>jZut15cNfVDBcHgb2ER9OS`-z3s8PVO-iyb##fmqUDU6}%?+Rl=r_TW zRA1QV=R?EH&8;ACo>HsjYYEL*2CWlN?w)~kSXx^)?y|GM+;_IwnIVXKg?8!j1ot@7 zw4c`l;}BT2qetG?9@pB=W|@Y=rxGo9n+mqg;KsxIsrg=eUpo?CQ1NwOck``GjWD@h zX$xQKh--(q*XcgyvMES9e?z#9AxKE~zui0_36$l0{pxOhc#HnV(U}~pN#R*Nk{#v- zZT+PW zX6o~hPAtX>QLiW2kuaI>=I7);Oq|kya9+9T6Ppl6Ujl1+4o#2tY%Jc*)Gda1&`6DL zf2&SQIh;*CL(+!g=Rf0~{&O=bu<&`teS>%(Jw<8i(92VEAP=8n&FCg*`hBU6Rnfkt zA*ZFQUZqm|zIZqo0TarY9R5~}cwgjk;+!N=BoJ89&FtgR+>Xn+QF{V=rvrB_p4~di zH7Ys_e^7A2pIGj}>x?-N5oI}$FFH}KS_c~H3ZGGstBpq@d`!8MboJ;3mbV4RS5r^A z)}MSb5p`a^{}P7~s75aTebp7SEebRL+gZs9N*aX(L+5UmQ_ zcKFh8=ZNEAJ_wJdMm!8a4v-S^(($RA{2KLr-3@S(pjG@gQ+@iwRImTiR5^d9Th1Tp zR#(^>vSa#-bSw1lm2RQXd;e;>H6og4(k*tC*7=tC9s6f0=$6-h8}wdB%%~?#sl0Sgn`^ZqtndC(ieeyPC{aJ#U(S5m<_v99cXewdB<9J+o6=}xyeyJ z_!fJ>-ua=hXS7Zz;BEVq>V3Z#_lXUBN}YOB4~QBWUTBMfzS2*BuJyTmN!wIM8(*M- zF7>JKad+7|ti=;@2`Ze^d3R?=6g9IShu)LQIzX@rCn?t~l^-plDQU#$Oh>%q=rEo= zd&YB*g{@^@=yd9r!(R&64%7|$6^~)G$GxhZ%xV>053bDQ^_u?1DWby`xM8{oiZW9% zBKtVMyBza%BE6PWM$}|;M72FMcCWGjsL7!v-2V=-6_x=H3m-2(9}l+!MCWREjo}Z& zC&&ZQ2T=tDOl{n;pF0+tS9_;~Nvc|ySTpp#sr3Itx~;_f*%x5D0xX07r7u8jxeUaV z=tASDG~=k4Nz0|P^UBz0*jn$k_O)JFsc%p`VFK%suYPOVKCi+@T;*kZe)?OOz(^6k(bQ1HhIA(;-{``VkSD=)l4Pib>0-3E7-TT^VVBV z*TL1T@~fy}h3kfa;U_g>j9XI;*;(CpD^0%-XZO%!roa&vFR-3ah~-EI%7f+x+-hFH ze{p}&g4)dj%Yeyf&#OSP?BNMnN$u`=Wm^Q0mfcg%#heJnwc~dBn!D`zWR=u?6L1G2 zek<}&J80&Kp0KU4sl&s?_NGU7Ohk3}Ocknmk5|RsPZCZxxW-cw&uF5eMa|d#n0om* z@eU}P*E4B$ZmUicQ&arg>E>(FSWcjKR1}B8ll(bwL-pF(lxpvz)5g&6`DJYTpK4;v zgS~qmYsX9$pb3RaD0~jYH=V09)qFGVFP}gB^zFj z-aM7q8#%|!9R|<@B%8T_ENzdxms3Lr!rkmJBDB`EEHB>}!`mvTgDNB|yaup|+&&vF6$>mb;uq-~kMB0vAU`K~X zo*WT1H-Xg}P(Fb`HCUybS;tNnBE&r1~PxCxU{rg|$kZ~O;$C!qmsOVNBK|{CBan+9jzx9M& zbd+}&9}NZHY8xmXFQ#v@ud#4lEX6!ETs*ba-xVp-x5ijT*l4)U4Ai6btQRZ18)-?! z>(610QI~L0>+zjo%!^*zSc%xs7fupV{1(K^PW_fSv4dPu6wbn0#`f-525=T~{s(x= zODx%%1ga{Xe^m|#N~pz73Hq#(ImICOd^W^K65`Aq=_{^a5HHs%T__`4QMvGS9zaNW zIFhqwT3sc9S`3W^5gaq%AAs%Xc9r&5d0df9>lAUUkBpb~jf|9rcxBGcm~X`b1gWW-i!ALleGL** zjf?<7w-Or&Jky$&VbIIL*4DoEIWx01sYhRqr5It?T!n*4BLJ z_-0dJw)N4tIHW1T;vj*Bb+dd1z1ELSxw&=>Bz&sTZ#rKEg*^Ds@6Q_@AJT?3V=dpT z{Ysf-Qh$&TU1{J?GxpWz#a**zk>{l!PA>*fYgy+<5FZg~3{wqlLq6mg=Q1<#Gzs$+ zR+{I2HBCQ+E{~-}+Q4Q~_Px8pJibB4-}LDN5B{hPJi#~aJaK0^db2Sn&f{hLO*rPO z)MGi_fM~Z(E+V1h8jI<#TbTd&675W@yWuA_Os?u&Rnx{fYn{WWDP657G zfc`R9+aKmi{7ZAS`k8pGek5MCtDqzCs~W-f-^^Uw8UIytb+61kJi5P=7!z$?gMFX~ z-`z-pTG)HM*jLE*u)loF5+Wfr^$<3{G4G5Mf)CBNZW6mWv{SA1)O=~-Fc}f{_ zrx~UD3HpMS&cmr;1Fkj~Y~uyrU-9d8Gw>g{i#kVaCHHKEoPQuU$f|2a`|NMjSGccl z^mu$S-N`jMfsC&z>W_rR7zki`jOm@(eAWj-x1TFVPk8#XOU*;`3rjrbM(ocx$7U5O zhE`IS8l~1@#rsc3YmkHUg;G^Y8vCp5XYu?qdznQE^C{=Y8Jm|O@EiQSOkILAbA~-B zEvNm$HDzP{#v*>J!ND1yq|O=|om#$mv98|6lb9*gE$H5Xpjg>WXCm^ujY1(x!^d z*hfCzSo;ImR#41z z<}5AUW21YaT9&KaS5Ex_URzlwPG#$O!;u5(oC^&*lL!hG7 zNL_P0nU?}f{W5`NP!gLbe4Vdf?^b$Ym39of!Z8^}vJ-rK7)5)QDr!ybxUp{qJ_gM= zS2;X6ZG9(Z6C6_(8{Dx9#XCXxs5#GKzISZzX;xjMt@nCW@#O=&ZM~_p*TICjcr&*MBE|biwbS&;(D;jK=ZuKv6GbWA z)Tw@F>)BDG{V;$%KvXs4_jla)Q~B3v`@?7FU1rsK&ppy+$=`BnSgmKTb;ZwVJW&jq za@E>Ar0Dr)JDVSPUkIp|($UVa=DagEh(&m6E3Gi~4Y>jk>Y|Q%6{SMc#||4K}ug XUR#Q+uugzw@8Eqv#A#k@7~nqu2WF)( literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/8c1c42b8b9ac94f0d913814685c18f78d0aaa922 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/8c1c42b8b9ac94f0d913814685c18f78d0aaa922 new file mode 100644 index 0000000000000000000000000000000000000000..6ff731763d0dcb0d67f9e3a1bf4f6107b6f94679 GIT binary patch literal 1973 zcmdPRX3%wJ&@E@6Xn**XQUZ2Tn?ift)z6k&%H3&?a+Z3lqaAAQ#91+6)F!m>QZGm5>c(WMyD(V&rE4x`T_UiII`v z{6(`X^`9!57?$;BN=`j%u_4%=Ln}bEyY$k5DXFUtzWfj_;5xbSxX2UBwV9Xiz0s@j z==|5{sw3jVvhHLa57X;;Gbc4#mmPbjr}Znr?~%@mQ?~M}8rV{c6jmMRGy7U_x3uFC zC=7lV3r_rZM?adaK<&di-=mEMBHzV#FKuCX@J+nwhvRI{t0x~jmP*aOv5F~$`!nx! z?K_(;hJ9rA3`+kMT5-?eywHA``XVP8?bMzlLMm?S^DQNR+lQ92OJ5b^@$@`AYsxi+ z86VF-X+F!op(Rx0_^S7!Ioqp^ug6;_v#ObNv;0q%39B>n-LAOu+~$^d{(^s{TFzfR z+q!?o`=C#;Nu7~Q%!~|-$e{!bdSECqGOV{>r}W(Ypt0TFE$%!^Y6Sm^1c)1Jiafr< znz`b`2-dhVW8mK#!UK7KmIe8FCMu1@*J)2huWfd>0|kLvz-mX-Y= zara(^@4@@)eqEUyHA6M{+VYH^-`evIou0NWV~JJe&Dq)7S*+dfGt;<*j3-LT++Evz z`&lMm=B-y>Ew%?cC*9fP78fLJwoiehe&Hg&^UDj=W&cdKtIeM-^ZEEAgZr5)gu8|I zPwr0X)|ftZ*$Ymd9|@b5&tG4yrM=?ke#?~^LOXu0*e?A4+O>7d*S?FnVP&Qza!fXO z&K=tW)4zA#KXJ;ufy+3a<3+nyko8T4Rr&?ycNX98n3MSb>(xzMZH0{RB+aN*(8Q<+ zNzxEDFd4}jG#-Jb=%^U)@65k`FdgdNv*cvlU7o^&)?W>{*f@YG`kXBbGZSX&L{83@ z#s=WzY+!^ZIY$}@v$2ECV`79F%*@En?8Lw_-Q7;GK)Citc2=#q>KQOB`1w-y^J4`j1?KlMbIkX3pIIBq z8#q5=O?ltnsa&$pm8Z`vE)|nCPj5#K!8Bk9#zI37%m#*Fq(S3DXb6U#Y__sK_iFL+ zGgY$DZL9L_56!7Tb{O6eG%++XgM^@o5u`jYz)~QT83-UkkX5^pg+YlqiGgK7NLo$~ z=N22|;Abfh!}jmhzngR4VxK`!`ajue5B=gUox1;Vw7~54&>0mfy%?HBAh=@^H_;W0(66*2}~soxS?s6xkQd=?n&m zSvd?TOa^-Yzn(W#YClvaUT}D_m(4tJp+8IC)}AT4Kg&$4XKK^z%!(&(t{LSfsW<;? zWu5B(oykBd_3yI3KW7*2ym$7LTwme$L(}f297~-0X#J0xo;t_s6^DK?g+1J_ShO;0 ek)3Vwgd5P%$5-~_lfzYC43s!IZe?P~YytpE7mxP< literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ba99175e1d1561d6f5a38eee98f9b4472b9159e2 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ba99175e1d1561d6f5a38eee98f9b4472b9159e2 new file mode 100644 index 0000000000000000000000000000000000000000..90b3339dfde36b4ae9cee644233dacb16a9e39ad GIT binary patch literal 2686 zcmeHJO>YuW6utM&D@B;fhuRPuQcQG1tX>L6qK$O|Z9{142ni+KObAdMi$M9%xEmlQ zMmMwRUXmJ3`X}7F^_TP)7~gaXW3+KgY42D*-2Lkt{QxF_(*LvHR` z2lYl8kDXfi?9|V{IQ8LIr|vsitG3qazqArSQHH?h<^yUGXOof;XqsarGirt?# z=M-%^5m1J^pZkffH8|V=&$vz<;5&FG~Uh3-2hK*z5cJgwJOA^3ShSFcy zHM%ByHX7yj+m-`E@^Rb~m^26;V8}<;DM<3UCW@B_Eal6ytncCS?B;*m$;^RiyEb!R z`VPFF{e`Arf(f@pJTHrQ?w`#A2;+D@@r;Kh6U2Chv`GQkZ4D<8HM1iz*Efzql0-s} z?ow1@O!lA%U6(inkRybAVo3OH?Gfi}-OB7md0~?Be~__Jn3e?D_L$6V;6RYs*eNt< HB5A@expS-~ literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db new file mode 100644 index 0000000000000000000000000000000000000000..dc71f9d8d4a45f46f5a60e3618fd8e9346822421 GIT binary patch literal 1783 zcma)+2~bm46o&76FM+Vt009aT1uQPCF9`$?SsfI$f)a@WiY5>sF+zaBjm-o^F-TRG zs4P+yh_QgBwzz;{Q8rmdS&9m>skoyu$f7_aP-VvI^v>Kj|9Nxnx#xcK&oMRi3t|KZ zvP^mGU|>4^C6Or>mQ+~~%-S>agY;tB%wwuF_;Q!@(>ns*v zF~~7l7aYO2QWOEr7S(PYu({8$boi{pGhf*>g=fVDZPCX$eYl2DR8n4IpFCV)$L0=SR?VCY|s3SbE;fKKEfFa*PdmANnV zG?E7+CAFza>-sdDLV`t8sEV9|QG#p2hzbNLVF5aiq=G8RA)XjS850rC3PTrYsgTL2 zh3qCPinRsFTNcU!+0E0-`|AS&$Y5?!2n!GaG!Mx7P=o~#1e)(qTVvnt6@a{>Z0)p0 z>q|5ToY4jiVZ`0?RFt;gL-NyXE0avnbcZNxq8-;b%-?U9d9zBKy<{ zzU}Vn*JeiJJKXwA#PxOyB?shKVS1ACWa==lE8=k9Ck7wFRgX`0n)}G{7QZQ6e~Zr} zjA&iYjR!sNwFIM1847K6{Z0`&866VXUuj51WZYSNhyE5>;}JOSx%Z)Cvzk;lHq2Sq zn3Z%>?Wa{mAvW3{96TfB=eKDpuUS)dI<;NzzU=a9shzveBKh`N0EJW zh)8#+rVs6Ai`9i{(iEY;aH%LQ@2P_F=#Jw2Gewa`#^N!l&4nPfD`Vmk^{Mvu!u*2Q zTRWChjR@65T4twRxo9M@ySCoyfFfl(?&+bm9=7-NB<4J;&U4*|GZ|CEZN-WSq0nbb zLqT>ea^Rjv&g5I0ett%xFQ#YlH6p%NzJ;vuI6c@wF29FhIOI6DQN$IXF0el6J7S)f zyUYz|x%54kNaWHT60= zvF{SJAd#sv1TDxj^8o#ifv_9Je<6r9=3{^X!UUL{O#xi4!sQhd+7tg?y0px^i`#8| z1N8`;B&PSe`QEMXe*1gTt&#`(nWZHYqboIo7ZJ4clvq?e>(AE8v4)G)CIs=7-XmOk zeg_9@$)LCPmQGf;{8ACCyOr74Hf1^Y6-XdJ85}O~hf%Ys;bxM-p~~G_ysDJ7E3&oJ zKIXoPZV2l>P1Q_F6J)UWK6=?s-o;!JH+c}7<~{qEdB4zepoiL{{j7Idt?9r literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/d76c9da7e83d1c9bcd27310197bbd01ee1746a3b b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/d76c9da7e83d1c9bcd27310197bbd01ee1746a3b new file mode 100644 index 0000000000000000000000000000000000000000..12fd55d4b66c42fc4a1083162a569b8aebd270ce GIT binary patch literal 1715 zcmdN*W?&F!u>LE|z|d&;Pqd-V*8cL7YS$F*ut8qAp&a$$^15HMsP$GO)5RPXM|is|lA9 zE{0%h1Ia7TEpH{7+QZq!bKY8>E1uh&5uwQ8B+#OG!b#xpYZHOfpBk6mh}M<(rIQdH zvOso~DTk4Pv4Mf1fuSA4Kd@Vao0zs2G%>A9WME>1u??D-Rv9!gPFlds#K^=X;=J^Y zf@t6S>QyJEaC<)zb@5qwPB{BO^B}g8{!GuK_n3b0`Zl4@+rrYLS7Q zIIoeBfeFwib7Kn=!zdsZ$N}0622q$Ani!Rk4P|6yU~XdMX8^i`i>Zl`k>UJBvn%zV zDw-IU^=3*=J!`Qc*q%cxK(xE`(t#W5H8?4x$(Hj6U()km+!sNtMTak*XXJv z;={7;WF8OG>v=OLHCmS)d#9)ME5YxP&WcmE@~axyQi~K;9q2RrT5z|t;}IwfeisW) z{C7t`nyo|B3{N8*7R@zQdZi;=|-# z=EGNZrX`(How<7Mo>i6`Qg1$fI>mg!UU{xg`Nq?#%_)Hf`+1M*{&<#^{UCAoUWV_% z`|EyPnH)7kHTc@{jGo`x^A4S!wk>0cRprgu+1gpG-S0EgxP^=-O3B<^+kE?3CST^Q zS6?l*2RkR-+2j@%By6@%funxmBER#?3)E%*Ot-7epDy$H_#=b+nJa|5h4xSGPU+T| zK6Tj(PM#kLo0iXCU#+FR;^%(Ll^H@iey-Rq{Qugub<5Yji@9NCrX_MrHh9h*+XK_T zcium7%DjQgIG*E0yH}9)O@&qZ1?G1a-|v`{`2XwGOIw z$r>~sfu`uF81L`QzkVfW>DWZYez!h_ad4Y=4ifGPT%EekUfX6i&v&X&do;N)yz zgeN&i8VIwogUw@Ngc{7u$j1ttaN_cC+L_jR9H8_F9vKVnUJ z-`}ZRvd@*L&nzw#lQmCoM-IU>UAD1$YM2347>7h&%a}r`w!O3#3Y@)`rj1U7tHAl28mfY3@JDY`$)Osr>W)9lQOCvUD9i?a| zKq~d`vcErP7w)`w_LN*-;rBz+?xq||ocn0~kD8u3$LbY_eldkT+^<-)GHa2YZSsU0 J(9j2!{Q&QXZ2kZM literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/dc9f8237a8e5d94119db6894fe81d5e18cbee80c b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/dc9f8237a8e5d94119db6894fe81d5e18cbee80c new file mode 100644 index 0000000000000000000000000000000000000000..04a5fdd932d3c8b54f74a9c508bf1f00fe856ce4 GIT binary patch literal 3803 zcmdT{c|26>8$V};X&J6HgWMw3wT)(BhC)(NmWT>bF*8P%#!kqV>ZYjdYpC0h7KIYo z#xi9Yl%=d$%5bxfDA|5z$ovEw9>7l3`}g8 z1UcZ8;9t*A;50ZR^cnaH%mMSj0}c0E`vj5^)YUz93=t}~mj*vXV4H{$Y%^Zj>|F=P3jS)4u=~gk3*&OlGNq?-JBX@} zs&2dtMsBS{vqt*I&sQNQW>iE~1rd`87kz`>*Dsc?Z@Bhc7lCl^FGj>6wj;E+uiY0m zB`FCOUebM$5tk8n7-2_gyLp{PJdctbvA^q_zSb=)Cc4b{a#>m``L6$I*8`^?r{21i z7;-C%9+nug=l!`4CN>m18`_8+=JW`~(V5bgJ^J!2J*+1pN3HNU?enwHqMh%I%4p?9 zyGd_HHVWa`?C9K8-cJIPhgnwTLYCyL!IkmjQ$1#}Nv-hhpyB(b^B>`9SNk;2M)1uCgz#+5c4||5(jF{-uI{Cj%v z$}NpJRbighSX6ARf4om>(6UtHO^bP^*t(3RMD*jW`fth;|1+-PjvJTV&-Vb-6- zek{6S)RO36>zUXb>T5am=+nN~oS<_%WjdoyxODo?cxiGR(B5Tm(!1P?4cW!jeoEof z0Tl;dycOG`aLPMtpuW-U;Go0&XDfX_^0vG?qq+N+dDAli;l4tFvhk%Y0hQjqbDWwHQ&u9$v*{R#HHOIT-d{TPUpGpalyF{GW!VHbpc^&G&*Q)3;EsSCO&Xyxy zO{9({__M$UT9Bf2rI(9uAp2_DA^HiC2Jy8MQ!NK*#YLu#qfPbhS-a};@94f^YkZj< z(E##47-afm32FqKE!h^0!C`FCT!gkIsoJ4Q6rwss1&6~xN5KEu=itBC=V?Fe^Ot|x z=kmnUq-&=btg7m&syhlUjJg+Dt?bt`H{&BCV`Iyu%WrfBM@Oi~Tr^6MS7|e;(B`Y^ z6J`svBHx&~HtsM$*VY-;D`G!jdto)MNPN+UBI!w3u_iyAf9oC%s;vwv2*n$8ir4&< zp7Ca0d%Y8~aJahLNw@)A1THPYbGyoyKO)$AuPoWjz^qO#6z5m~lq30P@J9$H7Yg)h zYkGdE>M?G_wrHxTZB?;oeD#XOc-7KW#bTtpX}Mcqa&Z{q3{G6d8>dRZb+viyQ@Ntf z(IXEpJ|uLBP+P4BpIfJ^*UiA~4US>&-(LOSKa14~pzb|vVNVV}Xw_Vz&o;$p>*e+2 zN?0E6*t);w#m(mDQjVYBXNT@h`tYuKPFAZFKRU%Xmoqf`0LB)-+SnNX;CiC#fex8| zZLjNJuDnZ})l)NY$&GFFZOi5iaHNy!T ze2SX#Kvl~~Fp9N&dC>J%IBuN3u_6?L(KXmczPi^JWuO3t|O$THWd=w4;?g5!qrfTSpgaoSD7 z(8Ae{%Y_bkEcNEouZNek?A?r{wJn4R5|q^rS3ZwwT#t%6TzqwM(QsK07jY!k%;B1Si0Fu^}C` zJM;;fY5Z>12{T(#)&2GUHr1!UlZv$z3*I`XX!vxzL}u)=H%y6Lii_{8tf)1d?7Sbl z=y8R0(Fm1l<%J$!Ki*nG_a+Tr(J^P%eO7xqa{O@iaOI|YwnBj4%Q#uR{ZkLVrnw|< zXizhvKU3FROlrEic4;mm_Gha(YRoAwn|Ebhx^w3o<2nix`U~f>xADM$zyOEG{y1B8 zH9Uz3DTf*kgT_J#QVs%URXLV1ZXZ%U(h^GtjtpOlvxNSax%njgMIYEz9%``+mxd9&_$WBi%D*TLXJ% zxX)Cdg;jyD`YPr7lrq8G?c5LSOncUk+$~Y_@hf$`H!lCenV|w9! zx^Zcdle>{fyvY6YAxf8bRBxe5H_62$#H5);r45?IBt=D9+>TF4bCMQ_Iz|N%l+XhQ zYi`YCB(5teolSALmr(NY*l4@Cv*5xxC6dyXH3HtldSj(hXEq4WQ3GkUmCvV>`g?+s5+*%;c9KCo3*c~1agb$M!%Z5!K^AD^^or=}h@HMOBXO0$mnEk54z zc6^j&%H8)r7T=ITHmXe*Gg$y3Iq)2O|!pM$h4IKSUKY80WVs;LPvL$&$kg zJKIaUb}4Q?x9)YyOkWsT>?I-3%Zg4Z+T?yoqrb%Cec2Sby#9Kr+t-^39XZkW)AulY zf=q+c+h=1@=4p>w1ETzeDf{lwNBdIoEt0m-2EC~zl-Bt8hDiWQfcH7OzgQ#i*ch>I595 z33zp`Cg4^z;qSBnCGlO=V1nEOgDvXtg1G<&w#*w+0m6zN5Y(W8Llo>na&0$MgouLf z^5Aj{*LK6X)?FU9+`_fpaISTiU!CV$bqD2KKy`IPIy9RvROxUp&>yR+qDoXzfy4}Y zLvs-~4Wj&M;eWV6MHTn*hiGDK$y5RwVn#+|A;fi~{*xOFfNCws4X=*D6Y%O}H1xni PZWuf_OxPdYZUFxQ)F&Hb literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/fe4d8242cdc4596d8163baf8dec8ed1df88c0228 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/fe4d8242cdc4596d8163baf8dec8ed1df88c0228 new file mode 100644 index 0000000000000000000000000000000000000000..f660c15b61858476fcfe062f5b11f01815e5a915 GIT binary patch literal 2649 zcmdUvX;9Ni8i)Iz#6%z*a${8DD2NgaA&_uiAs`}hGa?cqASg$?ksv6S5xI&e{np#hue;hHBKR-> zD!^iv3qS(l52_c1O2)zg*3ljYqQHM!ieSH73hDv?fT;v70rr;$DHsBvWlAs<9GL^5 zII?!xUmIX^99j3jY6#-U(*LRf;KST@rHCt|RFq}tmb_j$P zNB?as1TCGV>f2abNXBD@9Snl(mjNsg%TN#~EC62+Od7$Z5keX*lSW8sgpx+frIE~c z=sOeeCDl9sZX)|##}^YhX@r(W^3q5_8YxO6rN1Evc&ggL09Zum#XucUDEQ(F0AJ}+ z$X_Y=O8wht5AITm~63dN!GR`q!Bgb=3QFqM;sMc9h^3^N@RFi&D%U^voQzAboX39(Cap(+r z$u@b{_7X8O6V0wh4s{<$zLAJcX&D+B)leS%ZB@T^%AnzNarag$LATh_$^}k=!{HPP z(Ir{eQD<*O$(jpDwo+bp>?j-Y}kd&X;6y zr^>48=G?Uol#9Yg{rXbfnyM5FO-QO%qUt#h@zeItQ*PZqdhb1I?RHyl?;ef@nY!)7 zJxK_~ZombvE=kL|eQfStR{jLlvrR1~L>v}lzEYt0@+s{>Kg1oai_=X_pgwW?SL zGJHbkYo8qtt{=f5lXsF7qDYRuzR`}3T>IoWxW8s!Lb=4Sq_p(z)egP(Z-YO=bSU5D`%MElY{>Rld@i6L-XGrn zyqck#e#&4b^IG)c=MfP^r_-SzUES$!M{EI1jC5wbK;}obU&KW=ZM)dWQbq=06?ldx zuh4E3CLKTF7w$o0gwxKfJqu}UVfp9w==3c+qw(weeR>gC`F?_2diBh0y%;9Tbjevi zrdAJeTHn;--AX>u$jHz;X=GCwE1(IPq_l=7YzW-KE;*cfQYjn$BHdGes?Jko@*_?j zEssW{y< zbtBq)or3rSwfv`8TKO4fEEmZ_B9SasC|9;{bB1m3ro=Af(El9BlJobWL}Hi!>!8`( z+$n^a`RN&yR_n?w$%wpD)El+XZvcs zi}QIVih9^o;T3DXS!iSMme%~yf$zk-V;G%8sVKfbTQzxNen({7v`oXo$8^QGCzeI- zW>e+^Svn(}ANX-xr$9f(&h;4Pjwy4ZV0_p)B65THh|J0lUh#V`-7a*c?;EQm^H&=T zyX|LAUo`sFbKm1v!ul0ODf_i8BO>);_a2-sNfqQx4HsPzTiM@rJ(IrkJDUb z8Ak5SNXE>l*2~X>`3|3dZc99Ex%qN?B>TDhxPN3p|5cxje9eJ|QW)s0xxSAL{sh9R B$p!!b literal 0 HcmV?d00001 From 0513c7dc48966f56c5299b40fa319010160823bd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 22 Mar 2022 15:05:36 +0100 Subject: [PATCH 2409/4321] Do not exit in pkcs15-tool --- src/tools/pkcs15-tool.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 6e44ece5bc..6ac42275d8 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2140,8 +2140,10 @@ int main(int argc, char *argv[]) c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind); if (c == -1) break; - if (c == '?') - util_print_usage_and_die(app_name, options, option_help, NULL); + if (c == '?') { + util_print_usage(app_name, options, option_help, NULL); + return 2; + } switch (c) { case 'r': @@ -2327,8 +2329,10 @@ int main(int argc, char *argv[]) break; } } - if (action_count == 0) - util_print_usage_and_die(app_name, options, option_help, NULL); + if (action_count == 0) { + util_print_usage(app_name, options, option_help, NULL); + return 2; + } if (do_print_version) { printf("%s\n", OPENSC_SCM_REVISION); From b3b241c1ad420d747090bedea90c8a81a10f1340 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 24 Mar 2022 18:47:45 +0100 Subject: [PATCH 2410/4321] pkcs15-tool: Free pincode only if allocated --- src/tools/pkcs15-tool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 6ac42275d8..56494e5d3d 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1854,7 +1854,8 @@ static int change_pin(void) if (newpin == NULL || strlen((char *) newpin) == 0) { fprintf(stderr, "No new PIN value supplied.\n"); free(newpin); - free(pincode); + if (opt_pin == NULL) + free(pincode); return 2; } From 77f2d9a7a92add7ad032c2f2b9d4889a0b3404cd Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Apr 2022 13:28:47 +0200 Subject: [PATCH 2411/4321] Reset card values if sc_lock() fails After locking the reader, the return value is overwritten by calling `card->ops->card_reader_lock_obtained()`. In case of its failure, the card has to be put in its original state; otherwise, the non-zero value of `card->lock_count` will note let the card be freed in `sc_disconnect_card()`. --- src/libopensc/card.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 7b1d6f18de..b636247607 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -507,8 +507,17 @@ int sc_lock(sc_card_t *card) } /* give card driver a chance to do something when reader lock first obtained */ - if (r == 0 && reader_lock_obtained == 1 && card->ops->card_reader_lock_obtained) + if (r == 0 && reader_lock_obtained == 1 && card->ops->card_reader_lock_obtained) { r = card->ops->card_reader_lock_obtained(card, was_reset); + /* return value of card->reader->ops->lock is overwritten here + by card->ops->card_reader_lock_obtained */ + if (r != 0) { + /* unlock reader and get the card to its original state in case of failure*/ + if (card->reader->ops->unlock != NULL) + r = card->reader->ops->unlock(card->reader); + card->lock_count--; + } + } LOG_FUNC_RETURN(card->ctx, r); } From df1b854ae4cf9aa7421c87670e489fe8fca953a7 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Apr 2022 15:49:29 +0200 Subject: [PATCH 2412/4321] Add fuzz target for pkcs15-crypt --- src/tests/fuzzing/Makefile.am | 5 +- src/tests/fuzzing/fuzz_pkcs15_crypt.c | 170 ++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzz_pkcs15_crypt.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 759b80cd49..0880bf8c21 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -8,7 +8,7 @@ LIBS = $(FUZZING_LIBS)\ noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ fuzz_scconf_parse_string fuzz_pkcs15_encode fuzz_card \ - fuzz_pkcs15_tool + fuzz_pkcs15_tool fuzz_pkcs15_crypt if ENABLE_STATIC noinst_PROGRAMS += fuzz_pkcs15init @@ -41,3 +41,6 @@ fuzz_piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) fuzz_pkcs15_tool_SOURCES = fuzz_pkcs15_tool.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ ../../tools/util.c ../../pkcs11/pkcs11-display.c fuzz_pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) +fuzz_pkcs15_crypt_SOURCES = fuzz_pkcs15_crypt.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ + ../../tools/util.c +fuzz_pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) diff --git a/src/tests/fuzzing/fuzz_pkcs15_crypt.c b/src/tests/fuzzing/fuzz_pkcs15_crypt.c new file mode 100644 index 0000000000..f940e786b4 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs15_crypt.c @@ -0,0 +1,170 @@ +/* + * fuzz_pkcs15_crypt.c: Fuzz target for pkcs15-crypt + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "libopensc/internal.h" +#include +#include +#include +#include "fuzzer_reader.h" +#include "fuzzer_tool.h" +#undef stderr +#define stderr stdout + +/* Rename main to call it in fuzz target */ +#define main _main +#define util_connect_card_ex(ctx, card, id, do_wait, do_lock, verbose) fuzz_util_connect_card(ctx, card) +# include "tools/pkcs15-crypt.c" +#undef main + +static const uint8_t *reader_data = NULL; +static size_t reader_data_size = 0; + +/* Use instead of util_connect_card() */ +int fuzz_util_connect_card(sc_context_t *ctx, sc_card_t **card) +{ + opt_output = NULL; /* Do not create new outputfile */ + return fuzz_connect_card(ctx, card, NULL, reader_data, reader_data_size); +} + +void initialize_global() +{ + /* Global variables need to be reser between runs, + fuzz target is called repetitively in one execution */ + verbose = 0, opt_wait = 0, opt_raw = 0; + opt_reader = NULL; + opt_pincode = NULL, opt_key_id = NULL; + opt_input = NULL, opt_output = NULL; + opt_bind_to_aid = NULL; + opt_sig_format = NULL; + opt_crypt_flags = 0; + ctx = NULL; + card = NULL; + p15card = NULL; + + optind = 0; + opterr = 0; + optopt = 0; +} + +void test_operation(char *op, char *pin, const uint8_t *data, size_t size, char *filename, + char *hash, char *format, char *aid, char *id, uint8_t pad) +{ + char *argv[] = {"./fuzz_pkcs15_crypt", op, "-p", pin, "-i", filename, + hash, "-f", format, NULL, NULL, NULL, NULL, NULL, NULL}; + int argc = 9; + + if (aid) { + argv[argc++] = "--aid"; + argv[argc++] = aid; + } + if (id) { + argv[argc++] = "-k"; + argv[argc++] = id; + } + if (pad) + argv[argc++] = "--pkcs1"; + + reader_data = data; + reader_data_size = size; + _main(argc, argv); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + uint8_t operation = 0; + uint8_t hash = 0; + char *hash_options[] = {"--md5", "--sha-1", "--sha-224", "--sha-256", "--sha-384", "--sha-512"}; + uint8_t pad = 0; + uint8_t format = 0; + char *formats[] = {"rs", "sequence", "openssl"}; + uint8_t aid = 0; + char *opt_aid = NULL; + uint8_t id = 0; + char *opt_id = NULL; + char *pin = NULL; + char *filename = NULL; + + if (size < 15) + return 0; + +#ifdef FUZZING_ENABLED + fclose(stdout); +#endif + + initialize_global(); + + operation = data[0] % 3; + data++; size--; + + if (!(pin = extract_word(&data, &size))) + return 0; + + if (operation == 0) { /* test random arguments */ + char **argv = NULL; + int argc = 0; + + /* setup pin and input file otherwise fuzz target waits for input from stdin */ + opt_pincode = pin; + opt_input = "invalid_filename"; + + if (get_fuzzed_argv("./fuzz_pkcs15_crypt", data, size, &argv, &argc, &reader_data, &reader_data_size) != 0) + goto err; + _main(argc, argv); + free_arguments(argc, argv); + } else { + /* Set options */ + if (size < 5) + goto err; + hash = data[0] % 6; data++; size--; + pad = data[0] % 2; data++; size--; + format = data[0] % 3; data++; size--; + + aid = data[0] % 2; data++; size--; + if (aid) { + if (!(opt_aid = extract_word(&data, &size))) + goto err; + } + if (size < 3) + goto err; + + id = data[0] % 2; data++; size--; + if (id) { + if (!(opt_id = extract_word(&data, &size))) + goto err; + } + + if (create_input_file(&filename, &data, &size) != 0) + goto err; + test_operation(operation == 1 ? "-c" : "-s", pin, data, size, filename, hash_options[hash], formats[format], opt_aid, opt_id, pad); + + remove_file(filename); + } + +err: + free(pin); + free(opt_aid); + free(opt_id); + return 0; +} From 2fb6133e11bb458108bd328fcefe93f68a3a2358 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 10 Apr 2022 21:50:22 +0200 Subject: [PATCH 2413/4321] Add corpus for fuzz_pkcs15_crypt --- .../5f52a1ae6be6d75d0be546604b47759c6621f46f | Bin 0 -> 9478 bytes .../6d06b28c9e3743122056f32e09f4c6d77763f4ba | Bin 0 -> 3796 bytes .../92f669ec651bb54b819db380603520c18b78297a | Bin 0 -> 7278 bytes .../bfb749d844f7c304e004c52a46ce84eb3da7a7f3 | Bin 0 -> 9097 bytes .../e52786b16a4202c5315c834788133b173bc141a6 | Bin 0 -> 2310 bytes .../e9016daf00fb6713ea6f7fc18c55e85a4a33ea3a | Bin 0 -> 2649 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/5f52a1ae6be6d75d0be546604b47759c6621f46f create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/6d06b28c9e3743122056f32e09f4c6d77763f4ba create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/92f669ec651bb54b819db380603520c18b78297a create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/bfb749d844f7c304e004c52a46ce84eb3da7a7f3 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/e52786b16a4202c5315c834788133b173bc141a6 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/e9016daf00fb6713ea6f7fc18c55e85a4a33ea3a diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/5f52a1ae6be6d75d0be546604b47759c6621f46f b/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/5f52a1ae6be6d75d0be546604b47759c6621f46f new file mode 100644 index 0000000000000000000000000000000000000000..cac951cc2fbe33068dc4370ff27c7e368abe3088 GIT binary patch literal 9478 zcmeHN2|QI>+u!?4=6RlSGRw4&c}Qith9q?mi8^$WOot&C|<3*HG^6jmZd%xT5``-KBzW4opuOH{P_FB(cd-<t1=U7ueh)X^_q9PggNV&LBB~!A%wc*;w`dgk_-GN@_TN#{QdrOoyTV840 z!QES^6x3p25@~NS`>V9V+x$5#DN09{eVqe;j3A)Xa}o&2|70W@8cc0Stbd;h0BCvu zU+P6o@9U zK`c0i9T6rV8I3`KSO8+g(SLr#fvGec14P4NAsS{p6^#N>C=f)n>Mkk}sKxSB3}>fgNH+44Am+J{#x}AV?9Z zL32qj)@&x~!Ir9;3Qn$Ye?9yzFCV-Wf&ns~rKt_xfaJ523a#K{fk%VjUriMVg0}Lp z!2j;IM~M8}dGSNMpXbH4_!46;KeCUf2ien?@TG-`>vM}CnL_gMU2GA9@Si6pu-Iqu z-Cmx)a3?&`)y0$SgC{^VP;5COFo0+p$Ogdmj3^oi0{y*W;k#^nyXHU9u}KDp#_Qh= zyR&6v(`oAM$8~h4W!{iCP#YiW2fl98>9#B~uDYj`(07P6-Z83HsXuCFD5e2Wo8Fn`#J7C>?n{+`j ztzV47uDZ#)+7IU(nh(8u=+?d<&z?0LW0@Obj9DssDJJ_rULmFYQkvjHKb=yTP)%~@ z3S$;c>AMD2S<=bP-X|)(4U)Zm)yGJ~{*mX<=&^_#c_OnM6@>-?FoTB5hiIs)FfxWX zdN~}3#nOQwh6bv`HOi3jQXPbf(An+lOVL(RqI$S`kd+lZU8%l`E?$00@B$zhAd8`7 zpoh2?)s#xzOWtYa1v?GmGX{E!6b)x6q+;15bW zclPn3QkU%xOOmV4mo`Y|>+Hb@;Uz4{&h8{94Mk69DuRLgS5%;o0oX}JL@^=HppXtI zq%Ae1B{ifeLVl^^e+O|9z;B2-`?yDhr2Jol^bNhuWIr!BV7PjDn!_u<1PT&XL|8Gr z81A*b#-j)ZTi)*<%{qRX|D@Nc4S(-cq|T zRLKnSAqIF19D*Qb9OLIG2gg8qhzn_u#4s-lesqg*N`wsr7cdw!iY|EhHirWryv;!% z%&K9Hn_-4Ge(YLuk7HI;*(ZTpubw%wsaZ&>@bejJW#S!GnYddC6PDxV@5%%ymo1Vp z{J~6o3{!D|mPPvv7}BD69t$K_(p^@$aoEGt!5 z;d&|KbpIfwH19X&S3M8)aDN)vx5E^{U{W~N-ijIWb4hyE8l&CHAk{DQppRiVjm&0J z+KqqIwvPkb$P9H{5l8c7j9ad_+Lq&pe(o@L;jX-HXAOPsWU`OWMDbW!9s6p2U@r2a zhkYPV&6Pc)g*_S8b{~&iufMs=g0nd5V@pC*&|9%F3#~jlo;Y&if{Ft*rm&=-RADb` zEP;li!5cde;f8%bi4ML|0gM5%Cy|%`md8>mEOPjIuz=zvkr(`7BkUqRHb zl!+y{{4D1A%EO2sfCv|3XdrMV%saif=BX1+=UV?(a3OuoT?6V+&3YTY!rPV~@fCOX z@aVrdZwORMJCqY2mYE4eHlJ;h2~~R*d2md%h#vpyWT91Ls$IgW#8ar}sz+%exbV&w zA}a&!1n4gY1Se#_J;Kr$)tPG&Io!)Vny-{k%_o(ON>T{&_y9UPu?GC43<(6H-?qm`v)aBS~ z%oS!^s^x#fFp0`SW91myiH{;U+ycCZkn;bbT@oG1d%QW+LALJ$p${w!utSf1sZ z8vE1K%s2P_qGTXVM67*PGO#;-dxZS{x{^UK;D$KiCEmA-Ldcy}hs-Z~_7{vZxz4 zD&0*r+66P`(SEW6#)9ML+H)h760Yjuyjvg4!J1g@mUb9GHsPwJP&niaLmqP${n z=l3NHo%H@9E6`dH4XyU$;E!PNjYI_Gi+u-aE^C#tuVf@wy|ZKN=6v!0pGpx77WKzp zQ(=n&;@?$)AsGAYjlwa)k{1KgG`LYH90nE}!1vS$ z3&g&Zkl`3W3>uahkP|W@2gV+zWR#AnzTp6$00qWhi4V;1)dMuz#7`+ZP_`TI)s`h8t$+b zoDd*Kn1;RP--CP>+fccA?q z)&5*^hnw(;^tiR(J^d`DhP-?H>LNUjAU^Ziygi`~UEqoK~%~!2{9dVNupDh#`iDl_9MTfWF z>Cwh->xj`fVN8=}Z|#z9xTq8Dkw0481eqyQCP*#&#bqo-geQ|K%%?OFKfo%q+;2Gg zm}MJ7gMvroyoR}UlaCk*+BrMX5L#cBvT%Z{iBAj|dRK2uf9%<{ZPLenk*cN>N%GHW z7}VN$Y>V;?&FqRA{h+&TF*vuWRVl#DCTw=oQp#KpE9=@HbK5swGpy1LbtU&qoqyAK z)@@Izi|-JP`uFl0f`QUc%cXymCjO<?h#FP^}>;0($P#BB^_`gA@)4Wl3u$-FudRmrZmS?^L>hj>+4x4H2u(}X;6-P4Q) zRI>vtZDxn=rrw&iETB_qzemqh|DkAI3i_OQGjpixsBYHi{gLqIBEf z#5A=)?HV2}%DouV_)F>5Z*IHpJ)C#{)XDnyM=98zyMr%T8drMZ(^RQXS!UdV(6lwi zw)nhOulrKo!8A2v>lFdH?d3{*x5GKJs4W%IDc$>`%!{PnZ7r~Q(gOOdZRC5n?(wMR z6)V{iUgH!$)uS77BqS`VD3c|#6c>Fr!*ugk+a*h^(R1R?zWH_nbRWtxe%&;oyj_@< zZ^i7m)z*z7xcOlJji>i!ruD#6$nN3|czv2qrNUnxJHn!8pqUW~s+YjO8OU zOx7pNt%zW*sgNSt8dWmxNETDem?-X=OTy8DP-i=cyM*j4j)a&`C5_dwu&Eqnb=wkL zIw*13^&e)MX-eaWu=|y<>oy%lAC)@`RnHf%{14Oo56`jx!!*v+?=cM)|93OZ5#GZn zRCH^^4H1RN+z-ONm}u~aktoNc3uh;F(b#Lcl` z!|cTbYSO)4kFHYB=Mv&*U!!vSU@h^g11b86Po$b-cJ$EbJ=aUR$dql=FB(65xHEoU z@E0e+eE~8x9kpydvYiF}t1T|Io5i#@yiN1XoHkZCctcCLK9Q(Bxywte;g-3;glyll z>}t)ttInF~+1p=@Nt_C`Fll8SG}ARO8L2f4z3Dw7{Zf2A2WJApG-1!9crT;;@<%Xj zdY%253_$*!6u&V#Hp;4*thz9sz?$oKW|~5;EGSwWaDH^LSVyR7fi%9qozx<_`W=2b z)6i3B*aalQz&Xug8O~=uz?XjgOF0eizXQ{R9RJG)We5g@KRzhafwW+igTZns8>*|p z8Mm4iM9|V#H-wBdAWcI(Lp_4JrkbXjin6L9q^hh8r{bE6cB(2y`hR+iR*U}>x$yL% zgT$I6Db58+lp6ZD-2}$?ThYClM;Mu2LF>v-bo8rVym{M9`;wexCvM-KySp>(8s5_? zHVTQ}RJhi+W_VhzM@~gjoPAt^|NdCQj_h~UUaEyw2OlLJpYc?org_%n>IQmjJS*H zPV^7jQQX$r^7oR!Pf0Zp3>L5M{x#E$-(BhbJ*ftQ!Q#FB-+Gz(JraQL+mH);5lQ6! zZTY<%{rAX$;}6cwl#wAgFmjOWAD@H$=nM?O;LADKmPDO_`-ev#?_S%fHGj9;O5%Zu z)AyGV;;4L|MScw!-NQY zP_FYdL^-tS#Wpp}MHm_N^rEh@_7bM3^s|lw#-``1M-rk3CvWhwXIkaBUdAL5C)Wg> zUPTFVx^e84I25iuf40RVb=oNBfaAFZUB(ZlM$WV5#suM9KYU4as{7{G3pWY7KSi1t zzv!6tpJP1N-*dvDrJvI#gYm5V%hlQL$E0Eh@g^4Q9HlF+cW!qWu8l-dnr-UzY==0X z$gVsTMlKGs#3;4oWypV2XICg9qzthT0TMGS&}1@eK_m-&;f(KnZ|2Xw&JqO#goM&U zf)8$vFSk2_7QT8{WUF#^6l@o zIP%FmsXY-D-{xd&Qu~H61R5vSuyM#)SFT>4nUKSp!t$gC5EyLBO}>yoaAbW7vTDH6E_M{=NSBS7hS%@ran3Q!nX&<0td4Kj`m|_x98kDFesN< zA8Dw{q@1s#jzZHDzo2Apv>=NLQIBK_oN0N>R5DTHLx7u+^>!T7L%O)#^jWLj&Y?o( zz>bs0f5)C&nBE6x<$u?Zb?+fz8_tQ`6$B3U#REZmAb<+l!RHeM2)Pebfq_fFe;)Qc zynq|*23IBkfQ0%05^$gG@UJJq9Dw4cT2Tp@*)ZT9dyJ_>Oi3YG&1AM_?2~$&mPY&R)Ji?X%Ny&|A5O@i^v@QdiW+3n?c=acF1-$Z; z%>Lq^WDs~`Pk#7wfHt>?ZIa0zz8oNS`;$Ef+x*81HuN9?cK?$eBmfrJS^&HrC%_l7 zsb0Tsh6}uLcl~V-0OI5WLqUKJ2y}}7F#9`nIROzsj`Iiyln(^jFlGm0$EMp3ZomWN zzGe)$EW7$oofl-oYK94buBM_c;8uxkwVr_>l%SNLAPQfZ2vYtv`)rDSpU-(cy|ZVb zp>juvkdtV-sSw&etIh7nc8Ch!?}mwoPAglQRB2TzzLHbMsO8n(uMdJr*T89$!;Fwx z*bGZ`ry3u0Hu0u!(B&Pg6+2q)z0re0FAtYNayaq;!i;x z9lFyZiI@;!(MhMru9@3B!eV18O>S3aq~jl7yWoEO!i)3=50Zi(jaRZWc+%22d($8Vqaxhp7gf;;?f ziij6?vWOb@x1jW>Q74Dx*6M0ntv6Xmyw-vMx^+6VL40T&)haxN@ZZ_HJT$m7Cw!s= z%Mxt}**TMcJO8#(_m$u%M!1t+1OJ#6@#!+RuC}Eu2iJ>dU|1z64}|&ENjHTHFE1#C z$qt4bw@Ih8ll#e@!L#5R^h$ViG+4oZW#pk)c^PdBw?KI;ZTM(;KTT}qYo|bFq81|k zOa%9`e=vu1?!|8PmpwuI@1#XVk;oFQWN016&ILurTY3=u#Iv0J+&_e0GBEwH*ht~@ z^QHJg{f;#{QskfyWL)U7dV04~vm^Jyn%?>QNq%{qG=F`<)*}NmS8b8gT3TjeU_B%@ zW>um2uG1o0XnWRL68wd+`dZE9 zeLWhNA9($MWMA|-w?1E%mlo3*?p+DNeJr@yl3Ui`rx-r(UwxwPz0h8HTko9F=2r6) zW6sM9SOY)2OyQ%cf@2%FN!ftFPzi4(V{Na0jkhnAa_{vQW`c}jMnDWpb9Bg2!;!AV z_z>@tI-v1Nj33`Gc#$qZ*6do=C5(Qrjj7Z|7$qF&Jnhwv>ura;4rn0;DoE6Lx%mdr z?{=RgofB*k*)}uRd7M~QYSuc{-h4UdAhqa`-aESHx5Y_KplHM}`D7ftCFa?-xm}Up%Hu2IB~yfw`sKwckPe>owp12&fL9K*%01DHEvc= z8BrMoH@d@6r6Z*hv*0o<9uklAVNHU)q;Q}xXP_;og{{8H9!@9yb5an9hR1n`Aw&=& zA;|Ht)|V$D$mWO?-rUffDi?}$DF&)wJS@~{wCRmv{ieo&eYFE7tty>bs_N3JmaT1V zG;&*Kdo7Ke>7jku5>bFeU|2{IRd1vk8rk1{<*4c%4W>SRV)Z$?Uy#scGxo+NQ-jKa zI2oQ*dHQhcye|k*d4-=m@1)O8JnPb0BQ3Tk5XJER>-PYEGXOT(n$9pA*b-W_K-T9a_uP-dW+;`#n6eVOl zHT|(&i*SIJTT`_6cv{9vvTbj2|aC z2<`haN}!KtXU7AS$>99wE)IhXm^4}Cmq(Hwx!aK^;*K@y1V#4xWIFz3YXn3*F548KOtT@h}O+)Xai3HqIvKlB%! z1QFFDG7ab8kb{szxd+ekB=#!K6j!RFw0K{0eI3j~6zxB3+-Rbt)J9ckLA5CuC@JWv z@WCxqFe*soV{A&+jXbM@i=|I$Vpd#sRrx1JJ2QxB=<$`Sy|+u83mLa`?CDo2<$_~y zp_!D~0pEd2x41G_h4ZbSQ(rYLIgd+~Z{em2pm>{lMd76q@vE8vNngr}iyR6MgobxS zVmuwzZdkwWu4DUTf&DCb!?+wzd=z_ZxPJ z5NqpY_p!2HZ|S;Ad~ZqOaLH1x32Ks%%P4%z*X21n>o;kE#}z3 z&9xo)-xvh^X9n4%o4-{G9zQWi(q93UG4$4n%A7N%*7bCt<<+v`$pvWhmWxoT;+Yy+zte8L>;RLd zY3=!#38_7mc0T6C#2mAC^rxvTeah0ER+49|Obh)$O&hV0c%-hYWYR}>9xK#4F@45E zy};MW>@}g&kxpS;DtMTzgj7Kx5lTc{I6J)Ih(U;-UVKK>>>(HoCHOQXSn;-U!(M_! zyIgEyY=(Js#+Yera&(mC!-Uj~ixRxiX9*yvL+J4njSpB^N!v>+7E_&{B$j_UJJn<1 z%C~Y|5vRD9i`RQXf4V~K(k_7|LIAO;=FNQa@Ze0s8M`6OpxPkelhK7aJ0nNj2wimx z_Y4q5EmRln{#cmW6pCi|ciRw%mnRC6EC?w-u){6-ue*WKbf&yZl6Sloz&J>sX z4NtD=b&PkMh&Y)ZvxIv1T)4Q!q^MgSY4K=D3LjR|*Hh7dP+`yY?Qc_ALt%KKdUT-| zmgG<>e)*Q>aQT%_m2>#2=Ew?`7uv34^svL&4My}7UP61GV;3oqy6UZk9IWt zMp9P7Zs2aD0?Mlvfo}2H)kAwU8A&U=kBm(Eujn$WUzR)Fye#X@xK@0Fvf9iV^)d7< zvRu|a@0hkUUFCV`Evoq-)4L+z45nUj@@qN@+7lwKd?d^G1l0nXMPf!Y`NC@HU9b|H zYc5Eqy3=2bpSL-yvGohCX;f7Yri?nln>FpPwZ9X-olas6x^R7qscS#&Qrg@EQG5o zqg#E1gj4*iVn4L^53~1NLkq`4s^h|CQzVn)d8>*IxL?+8k8RN_tJC(@Ng07_^G{(?~84O<9n4w8hX|d*NS|lyX zRpA!7gOajUTq%@nb=){pZj_5`Ebnn{eI_v&iVd-zu))!{|`ta z>rwO#01$wGqJR}%uFW3afz0eQ0sa!|mPb#_kLiPb(w+Xxq*5v$X;Jg)OuHhVoZe~m z*sxzDd%wvOE&i0aS6d#?;&x+4jG5K8pa6gFj6WU<2!w4^IR#*+jDr{-0MIx9kb>X9OBc0tBL1^J6;;4#?kk`l7yt%= zA>cJA^&2n@yaPsnQD6)hpB&(;g8tbj_}q10b>puJ`pjMYqrQM2fC8PkB4lXJgD&GH zcKS=>YW5GuH?7Z0$x88!;5p7V?50RzqSjnii?tXlNc4Js#8a83k0V2R5S&h=#a!HL zh>PpTiY(&U@`fcqVHBT>YlBTKC=gAOge0&c8+o=M9gRVOLI5O+#Z8`KK|U8tfVfyK zh$|$;N25R#3dADeQv-owaQGII7$ky4yI`=gC>JM^Dx`v(h{`HB)7hbTOL|Bs!6oPeX;bq=xvgp?QiDFt!lB&-y5DLOBOQ}z6|fg@MF?L@Fa)}s?E$0 zIHAy7P!fRcq9`s10(Vy9bj?%6mv#kMw%!g;FYj#(gV+wqmMF_bq6xP4*F3U|pP0~!Z>9+Z#9I8h89Z%ZZ{qBsr(#w2H(^oV*NR$cvSiy({caqsAe zu*?-*>7kDt*rzdnDMP&+M4>?dJjq4fg}A5+7#T+_P8$mf2?>KBh6^r(EsLR*(>4gj zTe2xMG{{6(mmSCmq?3tE20IkNfau2x*M+MEnGRh`3#8Q8c5HSS-N%^)mk&}su-DGg zf*52-gE(a~M&#rN_)tF?a$-0d(;OL2lMGFiA^aa62|iAjBK*-3IfqjaK7I&A>_{RK zSYguxSXvNR??2CI18^wP2naND7pEn(iN~Jm5T@P?CN(62Knr29*)uwaBb5;{<%6`| zzXgb3z*C;ahE5BhdK(g%G`^!KvzAVUR1vp21}^m|IXmLnUB$}#)3@iP86MCYAVgQ+(}NU|06Ye6)sQ$=bdn8F zAY?buHB>Y~@OO;(2cEzQPqcIuNyLspqlBYob^w?o;0^!+>wYlS|0T;j=-TXEr4g+O zezo53tfcdEi;s;Kz3gjP{b*ZJYuee2v!d(#hj0S7%;ew~j>)q_>w&?6O3u~;V@U)Z z?XEB_Pk~Wc%uhWoUA6Hf!B`;m)Ossv1cTwTLi$x%Ty%Zh>A6jbglmIdX{N@6ZT0&# zvYv9Qs_3{IaW-j(%j07D9u_`estprGb5yUjk2OoLDgJ4plKIs$Iadmvx!$~X<@u&W z!vm5#0*#Vu3}-(l-GAG4Ee_K^4~r9oVX@&yjMg?8>Thnza*>1tvO9cEzGf`avd1mk zXyO#hc3PO1>Uwl-fOy7S%>z((XW=^I#?Hgm{!(5MV)7Zp57!1f@zdNcf+o!n0+8|thY(2;CL0n&f%IUB0UzBU-49+2 zNezQ1w0rDvrClm|c1Ed&8Y%iR_@J=wMyKpGdcrPl%`IC^ps@EELx{xqR^)_WFrgzp zOHd!n7Yr8!&RHeO%{!VzKHY!U@x|!j4d7c0p9}na>2lQSjw2VmGMYSz*ZbbKS}{?f zyNu6!9qhP{&!9I|q?s5&qwGV^78F=$DF*O$z&Ew7P#Q5J32mGyxZS%Yd*N@?w-M^+ z_QpZ^iRYbi9qW@y8Xfi%HwZf@E8vU9PxqJTn2$axJkj01Uca1kLh7YeTW!OUMJIyB z4W5*CE^ORS+y~_|e=k2INf9PG=^LL@Ok0yM=XSO0^ZVl4Zl#;G;O<op8Q&Kz2Nk?NSZc1pw2s&}GKL>HK1+ebB4C}u1N!^FST6|K}-!y&yq164N*a`br z#15QAQ%duH9tUtz_{l*sFdx8*U2I~SEd1z9S_DZMQbMd~S=k9I!v33B0Y0z@T<2={ zMHyJ%9_CzdS2W5+E8SzALXzwD;`WqC-*~&bZ|DS(C%&#piTGs70@Qrk(TnxR4T4u805ZiJ4K|N$0xFJnPLo?W9D8@CNzk8HG{$+d8u^I6k~H z=Jma)!dbFOhUsz|rS8{C_t#BTTX)R!O`#3T*WZ;1)vnupw2V^{3%(kOTB;KnQzNA^ za6|dQoMEGzeR1TVcid=Kq@$E|#~wLjj@@>~lWgP}BZrf}+Vbww&{6GQ<1OAQ-0%`vn$ABUvKGczs%#ZCQ$DU`Cb*pA;FmP z=?eRXNWs1-8Hk3_LNEU^DSse!8?*ejvk64Og=lp6x~fgHpV=Se{M)1sg28)1rTZV( zhabzGKT4f{NAfJe{x*rb$>B!^Z?(*+BXvZ;B3?Y-FTEA^G~~cpDk(>*)K^jg2Y#bP~-# z?-RP3(4eQ%%&MEMh2G@4=rp=hIbCv(!=Jm;+c9%49)BtpwwN$He??%Ad*P}u=@T0y zG+4Y~%h9#nrWqcETPrT?_dmoiu0viK=oXyE%t>lR0 znq!*}2NNV>2n`#`a^$5`IT7L=?;=wVOWkX>Z0(7j-QN*g?ctAJdQ2I*Usk9r_TtP~ zb6En<r6 z_%FY+ZD%*hM)#*z;?MJ|6MxPfJ=_pCo|QHnw=6B&`kt4NzH0jxWBs_1i~NQPIkm>^ z>$2JcHz@TN5`)31T{UFeX=3YXlJpZ`(%%h}el$$_o2N;C*(WIeiAkTs`xjUrPVQ;a z|6j)eoZ9aB+pMnxX(OyJB&+dNHTb37pjvESY=hzz@2s7x`SYu{M(#*)$a|5?9vIkL zdh3RdOuLgjYPoF-&%IS-E$@>4`3`as`(Au6;nn8(O?B@YoT$`OMd>Pv)=Ljn3}##X zL^M+?U^=b|9*McRq%dXlOr`jSvBd^eEkoHG4;QHq_71JjReCGw7A6#~=KI#l{q@mC z(zD}WF;0?qxlSyTW|wHX;GD+9k~&bjRt%rjFVVN8?d=t2Y6H1O5bYBanx=Y{rJIsD z9&*ij?ObcdX#A^^PM*z`g_PL5@J4c%V3EhHN*M~dU!msa8G3N37&ji6lfAu_-qx3Y z`7Fpzd~m#nOzY^0;O=Wb75K`vcco2SpZl~7z``;B^^eE^^SKFEW6)#a>%+Cqm^98k z?ZT-_{6;bWY4(5OU622W3_vjW@83lGybM4v_`~K7vUU82O&~1p@A1AZWHib9BuMug za5y%*?fQ}57Zlj-U}2 zGw#S&Z&~p=Ia2(T*@{)!x#f0ILc1eV?wvkZN-yZmxYsx5wI<`?&9&zX91fL`9vliO zF~EzVoJIYPkDX^}r%{h20rDXxQrao?2aN}Yp9)YuO{;gGD;gra=0QjHSkKRCE6o|Z zUe#{>!ceZGeQu98t)+?@kJlSjbZFw{y;-iKtdrdunxb?cKTk6x@UrE3Ibo$gOVR7^D^6?7*umCs98-M~> zd)^3Q?~s?!Mq7&AWwi6QEa~{*{)Wx3_u_hInN7<_L^gevvc09}1P^cLg+5ziPV4%p z$amCfjObg(ONra&Wq3QtQ&rBJ$xvq9UxMswaS)#OhAHXah8#K3*Nmza4w;ZGmxFx9 zROH?psGRRJah!d=6lQds&NApWq6i`bi1@_Zd=Tz87Nu{c#Lh_WUi*asumPCW^Z_{l zM(T@=E9HlU<&TYp^#Kbv7zc;q<{$`=>cc7-=I%ri{^SW3z(W!sOQOK;io^593WxV* z<$q%Z0N{{dz9VM&KNt}kix3+NaL>%t+1%Rv$5ogu4mLL64n{Py{7b~b#sN@ZL{mpc z_Vc=P_J3kH&n-(RaK zkOBZB^Th_-`vX7rANX%QCn34PN%9Zm|B3#O8}{fi07iLp1>KJ;a4|RR)^iF9K++%E zFu*MU7Ht@S4xj*oTe+ChD$#2E=4=XwJ6Jf={%!f^(QrwAjE48$M#H~QYC3}xNW$*yJL8CYPf@)pu19fg|Z`J9m@qrD*(QRjnjA(#H&F1!1LtI894)x zd@~EkVpT&C7jHmeP07d2`sDq?r))TI(x(zQYDqzPf#KoH;bF+ANgB}!3+$fpJyN+I7N&GoLuH;U zB$%(SobmbXro&K@>Ol-T$W7sj12i0QztUlSW|FFdu-fqinHRS0q1OJevm)u@TVH|l z?dFeeJpqN+6|M*E6u@vox~4=RNA3qp`#ukbdt2o%_B|=C)}>3v@Moi{FQ}8ozONZN zfA5o(kXV;#9M~#w5S!kiYOB)(rR|G?rRQ52;MfB3?5Pct+uPYpKs=gT*UAaW_GhmU z)uiv~r}T6;Q@0F0WqUv4o|S^^jo1&(59K{lIyiOOx?HYgcO9w7|5%1$UUk(h?GB>WKrnf%iiO1SDdn@CxJiFTFGx#s_^!N87V0y8Sbw_2`K@ zD5W)R2}7@m9UZwPylk%Dy`CMT*>~@OsNGek9a1+{vs5cfvyzfBFqV~<_l<7ycD8vb zuK{he z%kagT(?BKd``8;jgf=?joEsH?2v-d0Q65|QjB}tO%Vi-^)_RCD`oe=*v zt!Zi)ilCy&N~F>!Dybr9{x|A}Ll}y$T{eVD1xnE>PIgeL|wQ=JfayZcwqV;d^({v_oNX z73#mlWl%m$+DDr(|7J{8lwfb@(yzBR?$vCA^jNoh;s!5td9C{?exxvtd(;S)V)j%

    p1I$EVQ^5TDywBZuewHZ z@Qn#~!HSffXDMp!0@>m*J2vUkW6N}wv{-IqL*D)_uUr7e5-hAU4W9qf+V(69l?Ge| zaYj;QJIH&>lJ4WJ={!mjW7#`7qgd#v(kNzkf8h8f6%Cg^%zwnuc^TA@Q{|?#8zE*e zcQS=kytw4rAf?i*8tmTG-mrI>DN5OIINw;Pmjix`QfVgKXuiI_!x>_JLS? zn0rBLjv&^70p)%T$3YNlH%NiKr+$aXMULavWYb;ZtRQMp=fnduHYqCJvA_ zDBuH}o1dG9=aFz7(o-|RJ(~NVAH!fy3#hm_KAvM-6qLI1O}xqAggEg6?t6TUoS>*f zG4omNActL7REdlp&tg zbT2NNpT*Af=2`j)3UzYg?}~18eXg%7p(&buv|4NNX4i)X)5f6YS&iZxZ#C8Nx+15mdE*i2 zalTCG!+4{4pRZlL@#xN}*W~sFp7gMY)o|+)n11)sL7Z!m^f>B#P^rHMe(v}S zN2WyXqr3#eegolFsUg(3NFs*8i#nzLV4~ol#5i1{gg6f(b6+XezAichU77i8(^U1t z%UQvoLRR$sV|UaAJh+}{O=`54odgd;OqXAY`vQ$8R1=pf&W~;+`CwOwUpV-Wm!A#B77rgV5p z_VM(>IW3|Ow<(8KR@D7MZ}$#?d~0syj{|;NzaNJ@U(=$jOsK zHQBz#K!QIUHT{2bR7x8EDArQG1p%uD)38niPR!N8q+wr2x7|I9dst n2fg^*w=- z?RS;6oPCX@6ew{LjM(`q6=~MwrGUgZmAI^O3s7TP#8Ye*_D9IMCy$8DjI?YfAggO0rTCqK& z&n)k8rJmHm_Bs3YVQJg-agVCOyQqbf(8CEYLlOIsk62@{N$2Ys41>;kM&*yHCwe|# z7_ZN_<;j%=nOt|sp1tULc6@M8%QMT&lII+2$Dbu~o`1!=R9IP0CuXx$=h$s~MC-la z0iOm*68$&zi9!qKUc>sglgHo`pNxcg5BT<6GXBJo16Xb9J zHR%+S7{IILe(SpdNvrSA>>BvCay?Dl4aR(jpts2PoD5zYOfpJ1qi1p;lvfO3)K@v( z^QF#Kql1sN4+31K(UwB|8#_-Eo7ez$BGQ; zjmB+2(4&~AH!%M);`=|0_?Mp=vB014R^ZQg%X1TND}NGiE&jdYZFe`Y0d-hi@d&en>jgqQKEBBr37y@s+)mmP(5AT^9)HlKbDZ| z8o$n+0(<$G;l$QeA>YTdRa?Wvvjk&nYXzI1Yfikn8e(BwR9bkf=J7q+=uFaLsIKev znnagq{7K;IgyCWase1;LAVmb_)ml%?{U9(nQQ@h>H{Y5XFKS z$;b3X{dA_Z6SV322977NH~v8vTN=lpx!II!$1X*n|En-;j~D`f9{&hj8A5`YBOV0> zg2I#2NR1!`brMCA)1$P{33mcD8`qGAHJRSdFI7H!b2H!H!q19XhvsApX|+XQ@jYlE zr4lNVilh|E+QM?7;@dZ09k#rAv|2#T&8-d1hHFOC$QU6l<1z9PaDx8GPsNAqoSY0_ zkAO01t3`pdA9M_jF17JL1|pm@U$UGbDO2SO*u5A`m z_Zm`J>zkbA?U{Rji+^?Eo1@fHY{(G{T6a0J+W`AKdn^)T32)F9?@XA^ck^@dA0xpPM2o4p&IB4F6c< zaps&PR>T)r*~8%D(b9pyU=I z@YN;=4DD6t?sK*P7v#w{mqvM<<%@XcwaxfQXo$ZkhH%-1-~exn>|WO`Ivx0Mve#?b zi<~FK+rTHGmc5rnkl8#Cef`pLH2g`P7XGy|aM$5Wt@lA6wM7hTBhrnkwK8_f_j)551Tvmt2f_7a2AiDbK9{}< zJa7^asV^>>i$rhPm1>(OCscH9^t2yKxLz8c1~6FZGC^iT0J22>Vx>*^xRQ+H_JmP$ zhjG^j5?M!ZCcz}d+Lelv(k;mXM@3_Zk&)x&0g%^TW(yz3;^eSMl`D_R4hy02s z&{~sTHBKgVa&L#$=JNW$zpx2uGY4*gm)WCClnhBeFYd3#e4R?KBbE|2-X2r#2#q~x z8aQcoXbty&Kxm0!z{SYJ&CA2Z=>XBbdAi2%hT-DnvC{-m1O?1&J+NOm6RYJ5|b1lh5 z{dY?ZzfTvBt|!32F-9+tu0V*zSO&_2>JH3ukJ^i6_ROPI&xIXqo^9RPl zItO668t&6|k&n~((~Yk2^yjA^iU?+dM%>4Ix~ff6#GBhhW=noL#S zj3=v?&&t1D89mf{PZrc~DSlPoy!QK2c9w){$7^piOFQbiU--Vq?DGk3E&i zprW0QRkle6`f^tGnhgLu%zbbJ_OGP-@P{cA{M3}k{!F@KKa#EpY`DXw=_g4S`frwW z$7z2gUFpbmtXv*T(}yLoJ(Pjs^AfCAi2fSfO~oJ>gIfEtYBOzea=9#6^f_s`%2qp(Jne=YlnHAbN(sx zn-gM3USFp{ni_VT)R$yB-!?KbP%LKuIulh#@UA))ZrmwBFz1vtxn6w5o=DBB((h@S zC$9J8%K{>paMfwRA}4l;BZ|yfP}9iX9m4>|NXq*ZXLW@!TLVv7sq3%G;Yb0s+$BbnRk9!- z1Y698_=rQCIU{{V<@Doa+9V65q${hIzAggr$&bf!Ho!I2VyNZNSa!TqTHGV{2Y42E z41^zmWEJZcQBh>NTRTiS!01f+82asXsZ~B|lB`!f7qyP^sI~MY2nwP`GJ02mqi;w> z*(v`m1GW|A8zz271%F09$7f?W+X7Z|J%~>OH#f6)u)BM-29f5JCB>rD@g|QWl75pc zj_JA4s-B^t!Z5eg#RbE?SO7mIMN5%|orbS|VydAbK;T|tBc5kk%PQ0yIn>tH-?3m~ z(vG;z=lkw+k6{#sL9)!EWUTT7#JW|(;mf+(Po3Xv3QTrB8x@B%Czu^2P%&*+%w2B` zU{Y?b9W4=$a`d~dH$fp!KMnYEN5_Y>W6W67H|wxUYL(cZUEpzP;GbsftH+JKVZ|uR zO*5Ka44~As%8wvCAy6Ns7~X|^$}`Gkpyz59>TNQ<v(rR+6u_If8J~Od3|K%d#Z{?d3I(cCrqNW zCaCAs{b=3((Cy<1@~Q8~1-{m`v>%h4JUCaChP*ABXW)m+`HGLKK5>?OuTo7Q3`6#j=hN#@Iy@jt($U?oHTb}0e7wJKou!vh`kn+PPzFjrpF#mjax9)g{+qKW(Rzs!x=2ovqIe0JE_zW_+F0VHh8l%sL?lq!u zX7f^A}6u5x%Sb)`vS6Iy)ua=aEXv{)!nt)PCm z-fNpw%7XaZ74nu=F)VVYBxvz2(CKj$^+l?%6{X|Wp(W^)ea^YsLFK&dgNRLVOj&Gj=ejx08Qe$J zc^>_}bN4`_`WAJA*PF^OpJ45q&0T#y4uyx?2h+T89}VTbUWNoh8UZ6?)>_A+-r2L* z*c{%&qV>CnA59hnJ_{XOoCN958jVud!csVe(R(9^=pik7?L_eF>et~fuX4mT`Nvcz z_E61E;srg$d;EtoP`gE>y;0G9-F7YRyn)M##_;)%iKn8mZ75wJyM_Hh&7_{YEyQ#D z^klD0gCOy4ZV^O+`?+!#SY>$f)vR+yM9Z1Hgih+rfV0*7xZz+D*!t}^DFaSeQdO`E%e%vXM%PCEc%9?03y!w+HR2l-F z=(@UOr>v2GSyGXuvXm@!Wea!0zw4a)uk(M-dCz&C^FHtMKJVvz&+|gcs|HZui$Q0r zOa*ffUb3}K_76Va6t`@d#*VtkLmev*&iC(sx+7#P=T%nP|GO3C2%MOPV!? za|qDJ$;4mx{xgXTS*X!lD~U>@4xO9C6_pK>B!qo_C6jh*`?dzPbx~h`2x)%2mt6Et zuRWF}J0>$ljWepQB7$qPWQg?s~pxRZ?8fb6r;7ZK0;@idojQj8V?Gd*oeT z7m}G-W<#Th+V4u+s%(mSp2(4{{}Wlw@F)46QWUhyHMuF8mo}rvk@kAJre~(FibGY9+x0qo(yC+#q;hOB2v9hCaxg-Ts-m-J0oWK zA&3_PkRO%#5ne8oH5$c-4)AmKMK+7@Qz(ck=OzsmO;u$(PRI#3H?NxAKMyb=sf|S; z3_vlV9|5Ni9L$6u(EeDxGxWn5Cdj!&7foo>ykn)0mETK@33yTy@64_pn>vU$j$h#3s#GV`WlLpons#e{@bL`OG|W7-#UPMQGs!QZQOUltqG0nNuozdpvu#uI>#|Gsxj!5U&BgZ$J7ye8N&-Ni4j* ztL;K{(&YXRM;xOL!6*no8!2(nb0|TeP`^NG#I#mLud>*b?^ck&5@D~1%1?w>y%;)c zD(({Me&;|Z<`x-KQTZnuLQGJ z)gcR=adt`4R^7R7v5Vx4x`#LZaJ!{__F3u)vO6YblJ3GQsB%qAye~iO#W4K``t!Fl znk807j=e=D4*P}Ft0b_YH?u6-bG>CrpA+?hy%NPgHVz^Ebe2$zV0B!KQ;b|iNihG>hgpJl2ux-ZcXBBRDV;8#(A8| zQS4}>`F@>e5^N=Jjox4SFQ(B}X1a=S5kAmYNkj79Oh|G~(rZ3PMkIvsU|rF6hj-1Q z7Utl(n2KA?4t;z+wK_8hjtk3C^dns~3jU`$H_BN{1zD9dLivuI42 z>T?JlLKuVV1Z|qbv~?c6{iU(>9LYX{?WJFr7PPUk?-Ep1rl_wGRHdxV1LS`Ugi{Fq zZ-N*y0}Z55jsTr`z{SIZr+B-H)v(i`O?9PGpGUuD6|&!TnRH{&!r@6v|MYK#^(8OP zIaZV`%^3-w+)5D5;dNHWJKycBn{Ul)P#~~M2ctb~a(mn{YBZb9!HVUEjw`jH;)fmE zx>nRSz5?Y65SqIOaDoxVm6>*BsmQuhBHs7o%(rKV2!76fAKdEOpQ0`to4`z^pLspr zP4RS;4O_l|NwA!S5i#eboTd3xpL;LcS~g$ynXS9g=hQ$;A1a&+iVdL#vg#IKo55;H z-`nn4db-E2_N>$Y-t31tBl}zb!k4`o5X6MgOeO@fj+(qLQ#WI^|8X?X@LXZ17BQn? zBx19K?(v(lCT@R@8geVWcZklG5&K+B>bfwo@3-ke1K&^Q?mi5J{Z8|hhOVTUl~T>2 z`mrSABXZX&IkQBenPlZjB;sP!6uI7XDG%gHW>ac($ESyrhj(O6drIP{KcGV-d#312 z>8Uq}zvI@=c~aO*uH(BJjPYDg$L>Yu+aFA2c;Q=6I;}g-9Egc^o#`--6%lzk56g9C z3}p8Ug;HqdyTK7po?GbVzS!hfQn6IgmeTE0;-;e)mknGkdB`@_=3y63r`pYa9QUb} nqcz=>nXU_rj#PY*^4h-MGio5>@nPPG<(X*Nj^xCZ!K>geD2;Y2 literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/e9016daf00fb6713ea6f7fc18c55e85a4a33ea3a b/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/e9016daf00fb6713ea6f7fc18c55e85a4a33ea3a new file mode 100644 index 0000000000000000000000000000000000000000..fa67e6ecb45dac8b601cc0b3e239290f3bb4c5bd GIT binary patch literal 2649 zcmZQH1Oo;}1|Vo)@QM$+8=I7yw{q4Yg$+!{V_&yyn)CU+;Ik|zff=W6Yb0*IX#KqY z!LmA+JLVrbSN2&w&{%N1-`nKV(YRx$pR&!H@yb}W<($#B&BjYqH)Wn#|L639Jj=Uv z`94vcNuLT;c3cWrb3Q@j;b#5%%YGj1(SG0Gsq22*_{&nQ;O5fk6R{HA+zi&2Bp4bE z|3#c+7Gq&xY?#2n#E{hl!4nv?81frco0$R(n;01zm>6t27+M(_x)@nk3p6k?PGD$Y zWLv`4%qTb&q|c6F0ha*>3!6PdfT#=O5(L|EDS{oi9KkMJfnYZx>@tGbWrWWz69xk< zCPoGpR(8RF2nHVBu>73t;_}4w)I0@8_Xh5;aD@PGPX*`1q7-H(1_2PsA~1nL7U&y^ zW+oR#unp`vFdMp=^@YH`F|aU@;t_PoOwTMy%uxu=OwUU!DJ@C`n$f_*$Y{XD!YBx2 zn=mmlF61-dF<@h10eO~*iG#tw%0QZj-!DH;At<$=G$k{!Br`t`qK^rv+<=>f(U_T; zfx&@^kr_j;je#%^mup^fQDp%_8>0a~3u6>ej|&6P90n#vmW3h)LIylgI~jq2&j7M{ z_yACP8a}=miar^Qfq{;-(HI!`7$_Spg$5uJCNQV~t7my&_1p-qo*5Zn)$?jDSYu-X z1F(6*Xy9fb$io4u+!X>m{g|294zMr^888ED=!H54TFgvLJY0;xN|z0YfErmC86@}( zP(YLc3k#DysLmGS;f2@oXofK@lr@kB8s-BtjH7|E31}EZ?*If4+)7Xr4IO7S001+$ B!JhyC literal 0 HcmV?d00001 From 044ac94d810437af1af26aca62c76cbdb9a4b831 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 21 Mar 2022 15:22:22 +0100 Subject: [PATCH 2414/4321] Do not exit is pkcs15-crypt --- src/tools/pkcs15-crypt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index d4017a5463..414b99c752 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -389,8 +389,10 @@ int main(int argc, char *argv[]) c = getopt_long(argc, argv, "sck:r:i:o:f:Rp:vw", options, &long_optind); if (c == -1) break; - if (c == '?') - util_print_usage_and_die(app_name, options, option_help, NULL); + if (c == '?') { + util_print_usage(app_name, options, option_help, NULL); + return 2; + } switch (c) { case OPT_VERSION: do_print_version = 1; @@ -458,8 +460,10 @@ int main(int argc, char *argv[]) break; } } - if (action_count == 0) - util_print_usage_and_die(app_name, options, option_help, NULL); + if (action_count == 0) { + util_print_usage(app_name, options, option_help, NULL); + return 2; + } if (do_print_version) { printf("%s\n", OPENSC_SCM_REVISION); From b67be317821cd70906f2e81cfdfb18b6a6ad00fb Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 30 Mar 2022 11:35:17 +0200 Subject: [PATCH 2415/4321] Update README --- src/tests/fuzzing/README.md | 128 +++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 23 deletions(-) diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md index 1ebd735dc7..cf8d5a7b33 100644 --- a/src/tests/fuzzing/README.md +++ b/src/tests/fuzzing/README.md @@ -1,11 +1,66 @@ -# Fuzzing +# Fuzzing in OpenSC -## Corpus semantics +OpenSC is part of the [OSS-Fuzz project](https://google.github.io/oss-fuzz/), which provides continuous fuzzing support for open-source projects. +Fuzzer [libFuzzer](https://llvm.org/docs/LibFuzzer.html) can be used for local testing. + +To the terms used, _fuzzer_ refers to a program that injects malformed inputs to the system under test; _fuzz target_ is a program that accepts data buffer, processes it and passes the data to the tested interface. + +## Building + +### Building for fuzzing +Successful build of fuzz targets requires `./configure` run with correctly set CC, CFLAGS and FUZZING_LIBS. Note that some of the fuzz targets can be built only with the `--disable-shared` option. + +Example configuration for libFuzzer: +``` +./configure --disable-optimization --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing CC=clang CFLAGS=-fsanitize=fuzzer-no-link FUZZING_LIBS=-fuzzer +``` + +To add some of the LLVM Sanitizers, modify `FUZZING_LIBS`: +``` +FUZZING_LIBS=-fuzzer,address,undefined +``` +Sanitizers can also be modified by [flags](https://github.com/google/sanitizers/wiki/SanitizerCommonFlags). + +### Building without fuzzing support +When fuzzing is not enabled explicitly by `--enable-fuzzing`, fuzz targets are built without fuzzing support. They can be used for local regression testing and accept one argument for filename with input for the testing functions. + +Example of testing without fuzzing: +``` +./fuzz_pkcs15_reader ./input_file +``` + +## Fuzzing +### libFuzzer +See libFuzzer [documentation](https://llvm.org/docs/LibFuzzer.html) for details. + +Fuzzing with a predefined corpus can be run like this: +``` +./fuzz_pkcs15_reader corpus/fuzz_pkcs15_reader +``` +Newly generated input files are stored in the corpus directory. + +By default, `stdout` is closed for fuzzing. However, some fuzz targets may output to `stderr`. You can suppress `stderr` with the `-close_fd_mask` option (see libFuzzer). + +To execute the fuzz target on one input, try: +``` +./fuzz_pkcs15_reader ./test-case +``` + +### Fuzzing OpenSC tools + +It is possible to fuzz also tools provided by OpenSC. Since it is not possible to directly fuzz the source code of tools (because of the `main()` function), the fuzz targets first create a copy of the source code via the `helper.sh` script during the build, and rename the `main()` functions (and do some more modifications if necessary). +The fuzz targets for tools then test the tool by supplying fuzzer arguments and card APDU responses. + +Fuzzing input can supply whole arguments for the `argv` or only particular values for static options. See the fuzz target source code for how the fuzzing input is split into an argument and APDU parts. + +## Corpus + +### Corpus for `fuzz_pkcs15_reader` The corpus files for the `fuzz_pkcs15_reader` are interpreted by the virtual reader as follows: - * first two bytes denote the block length N as unsigned integer. The endianness + * first two bytes denote the block length N as an unsigned integer. The endianness depends on the architecture * the following block of the length N @@ -35,26 +90,26 @@ Modify the `src/libopensc/reader-pcsc.c` and uncomment the following line: ``` #define APDU_LOG_FILE "apdulog" ``` -and rebuild OpenSC. Then run any opensc tool talking to the card. For example +and rebuild OpenSC. Then run any OpenSC tool talking to the card. For example ``` ./src/tools/pkcs11-tool -L --module ./src/pkcs11/.libs/opensc-pkcs11.so ``` Any APDU returned from the card is now logged into the file `apdulog` in the -format expected by the `fuzz_pkcs15_reader` fuzzer. It is also prefixed with -the ATR of the connected card as expected by the fuzzer. This file can be used -as a starting point which gets through the card detection, but does not go into -all the operations the fuzzer attempts later. +format expected by the `fuzz_pkcs15_reader` fuzz target. It is also prefixed with +the ATR of the connected card as expected by the fuzz target. This file can be used +as a starting point that gets through the card detection but does not go into +all the operations the fuzz target attempts later. -### The pkcs15init fuzzer +### The pkcs15init fuzz target -The pkcs15init fuzzer consist of two separate parts. The first one is parsing -of the profile file, which is separated from the rest of the input with a NULL -byte (0x00). The rest is interpreted as in case of the `fuzz_pkcs15_reader`. +The pkcs15init fuzz target consists of two separate parts. The first one is parsing +the profile file, which is separated from the rest of the input with a NULL +byte (0x00). The rest is interpreted as in the case of the `fuzz_pkcs15_reader`. -When creating corpus for this fuzzer, stuff get more messy because: +When creating a corpus for this fuzz target, stuff gets messier because: * The first part is the profile file - * The `pkcs15-init` can do only one operation at time so we need to skip the + * The `pkcs15-init` can do only one operation at a time, so we need to skip the card init when concatenating the APDU traces So at first, erase the card and move away the apdulog: @@ -62,7 +117,7 @@ So at first, erase the card and move away the apdulog: ./src/tools/pkcs15-init --erase-card --so-pin 12345678 $ mv apdulog /tmp/apdu_erase ``` -Then prepare the separate files for each operation in the fuzzer: +Then prepare the separate files for each operation in the fuzz target: ``` $ ./src/tools/pkcs15-init -C --pin 123456 --puk 12345678 --so-pin 12345678 --so-puk 12345678 $ mv apdulog /tmp/apdu_create @@ -79,13 +134,13 @@ $ mv apdulog /tmp/apdu_finalize ``` Now, construct the corpus file: -* insert profile and zero byte as delimiter -* apdu create can be used as it is -* from apdu\_create_pin remove part for connecting card -* from apdu\_store_data remove some central parts, since testing data is smaller than data used in apdu -* apdu_generate_* and apdu\_finalize need to skip connecting card and `sc_pcks15_bind()` -* symmetric key generation is not supported on the card, lets fill that part with some dummy values from generating RSA keys -* apdu\_erase needs to skip part for connecting card +* insert profile and zero bytes as a delimiter +* `apdu\_create` can be used as it is +* from `apdu\_create\_pin` remove the part for connecting the card +* from `apdu\_store\_data` remove some central parts since testing data is smaller than data used in apdu +* `apdu_generate_*` and `apdu\_finalize` need to skip connecting card and `sc_pcks15_bind()` +* symmetric key generation is not supported on the card; let's fill that part with some dummy values from generating RSA keys +* `apdu\_erase` needs to skip part for connecting card ``` SKIP=1257 @@ -105,9 +160,36 @@ SKIP=1257 ) > tmp/testcase ``` -Now, lets try to feed the data into the fuzzer: +Now, let's try to feed the data into the fuzz target: ``` OPENSC_DEBUG=9 ./src/tests/fuzzing/fuzz_pkcs15init_profile /tmp/testcase ``` The debug log should show the card detection, which goes through and then some pkcs15init operations. + +### The piv-tool fuzz target + +The `fuzz_piv_tool` target allows testing operations of `piv-tool`. What operation is tested depends of first byte of the fuzzing input: + +* `\x00` tests loading of the object, the input looks as\ +`| \x00 | len1 | len2 | admin key | containerID | \x00 | admin_arg | \x00 | len1 | len2 | file content | APDU part |`[^1] +* `\x01` tests loading of the certificate, the input looks as\ +`| \x01 | len1 | len2 | admin key | ref | \x00 | admin_arg | \x00 | len1 | len2 | file content | APDU part |`[^1] +* `\x02` tests loading of the compressed certificate, the input looks as by loading of certificate +* other values for first byte means that whole `argv` is taken from fuzzing input\ +`| > \x003 | arg_1 | \x00 | arg_2 | \x00 | ... | arg_n | \x00 | \x00 | APDU part |` + +### The pkcs15-tool fuzz target + +The `fuzz_pkcs15_tool` target allows testing operations of `pkcs15-tool`. The options are taken from fuzzing input, it is parsed as\ +`| arg_1 | \x00 | arg_2 | \x00 | ... | arg_n | \x00 | \x00 | APDU part |` + +[^1]: `len1` and `len2` refer to two bytes that are parsed as the length of the content of the file that is extracted from the input + +### The pkcs15-crypt fuzz target + +The `fuzz_pkcs15_crypt` target allows testing operations of `pkcs15-crypt`. What operation is tested depends of first byte of the fuzzing input: + +* the whole `argv` is taken from fuzzing input +* the `-c` and `-s` options are tested with various combinations of other command-line options\ +`| op | hash type | padding | format | aid | aid value | \x00 | id | id value | \x00 | len1 |len2 |file content | APDU part |` From a763d03ada77a84ae88358b5dea659a2d3984f6a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 6 Apr 2022 20:57:44 +0200 Subject: [PATCH 2416/4321] piv-tool: Free opt_apdus --- src/tools/piv-tool.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index d57b64f714..b62b91e221 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -635,12 +635,16 @@ int main(int argc, char *argv[]) break; default: util_print_usage(app_name, options, option_help, NULL); + if (opt_apdus) + free(opt_apdus); return 2; } } if (action_count == 0) { util_print_usage(app_name, options, option_help, NULL); + if (opt_apdus) + free(opt_apdus); return 2; } @@ -744,6 +748,8 @@ int main(int argc, char *argv[]) sc_unlock(card); sc_disconnect_card(card); } + if (opt_apdus) + free(opt_apdus); sc_release_context(ctx); ERR_print_errors_fp(stderr); From 4ebf005d4b04757beaf7c239799afbf84b137957 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 10 Apr 2022 21:51:01 +0200 Subject: [PATCH 2417/4321] pkcs15-crypt: Fix memory leak --- src/tools/pkcs15-crypt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 414b99c752..f714f037b8 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -495,7 +495,8 @@ int main(int argc, char *argv[]) aid.len = sizeof(aid.value); if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len)) { fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid); - return 1; + err = 1; + goto end; } r = sc_pkcs15_bind(card, &aid, &p15card); From 34d3dfa33d257cae15e1177524be181124ed0c82 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 27 Apr 2022 16:15:15 +0200 Subject: [PATCH 2418/4321] Simplify fuzzing input parsing --- src/tests/fuzzing/fuzzer_tool.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/tests/fuzzing/fuzzer_tool.c b/src/tests/fuzzing/fuzzer_tool.c index e4fd964f8a..a34e6c017e 100644 --- a/src/tests/fuzzing/fuzzer_tool.c +++ b/src/tests/fuzzing/fuzzer_tool.c @@ -26,16 +26,11 @@ const uint8_t *get_word(const uint8_t *data, size_t size) /* Words are separated by one zero byte, return pointer to the next word if there is one */ const uint8_t *ptr = data; - if (size == 0 || *data == 0) + if (!data || size == 0 || *data == 0) return NULL; - while ((size_t) (ptr - data) < size && *ptr != 0) { - ptr++; - } - if ((size_t) (ptr - data) < size - 1 && *ptr == 0) - return ++ptr; - - return NULL; + ptr = memchr(data, 0, size - 1); + return ptr ? ++ptr : NULL; } char *extract_word(const uint8_t **data, size_t *size) From 4edb7ceffb6d704688be20a71c77d302dea0e82a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 27 Apr 2022 16:16:10 +0200 Subject: [PATCH 2419/4321] Fix argc in fuzz_piv_tool --- src/tests/fuzzing/fuzz_piv_tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/fuzzing/fuzz_piv_tool.c b/src/tests/fuzzing/fuzz_piv_tool.c index 28e7b124a5..f5770d035d 100644 --- a/src/tests/fuzzing/fuzz_piv_tool.c +++ b/src/tests/fuzzing/fuzz_piv_tool.c @@ -50,8 +50,8 @@ int fuzz_util_connect_card(struct sc_context *ctx, struct sc_card **card) void initilize_global() { - /* Global variables need to be initialized - since libFuzzer runs more test in one thread. */ + /* Global variables need to be reser between runs, + fuzz target is called repetitively in one execution */ reader_data = NULL; reader_data_size = 0; ctx = NULL; @@ -71,7 +71,7 @@ void test_load(char *op, const uint8_t *data, size_t size) { char *filename = NULL; char *argv[] = {"./fuzz_piv", op, NULL /*ref*/, "-i", NULL /*filename*/, "-A", NULL /*admin*/, NULL}; - int argc = 3; + int argc = 7; char *opt_ref = NULL, *opt_admin = NULL; if (!(opt_ref = extract_word(&data, &size))) @@ -82,7 +82,7 @@ void test_load(char *op, const uint8_t *data, size_t size) free(opt_ref); return; } - argv[7] = opt_admin; + argv[6] = opt_admin; if (create_input_file(&filename, &data, &size) != 0) { free(opt_ref); From e35238c398d668fa98b150371498909dba7d443c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 29 Apr 2022 11:04:19 +0200 Subject: [PATCH 2420/4321] .github: Use better conditionalizing for uploading logs or caching results --- .github/workflows/linux.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2277539de6..49e22b4c2c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -194,13 +194,21 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh ossl3 - run: .github/build.sh dist ossl3 + - uses: actions/upload-artifact@v2 + with: + name: logs + path: | + tests/*.log + config.log - uses: actions/cache@v2 id: cache-build + if: ${{ success() }} with: path: ./* key: ${{ runner.os }}-${{ github.sha }}-ossl3 - name: Upload artifacts uses: actions/upload-artifact@v2 + if: ${{ success() }} with: name: opensc-build path: @@ -232,9 +240,9 @@ jobs: - run: .github/setup-linux.sh oseid ossl3 - run: .github/test-oseid.sh - ########################### - ## LibreSSL 3.0 pipeline ## - ########################### + ####################### + ## LibreSSL pipeline ## + ####################### build-libressl: runs-on: ubuntu-latest steps: @@ -242,7 +250,6 @@ jobs: - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl - uses: actions/upload-artifact@v2 - if: failure() with: name: logs path: | @@ -250,6 +257,7 @@ jobs: config.log - uses: actions/cache@v2 id: cache-build + if: ${{ success() }} with: path: ./* key: ${{ runner.os }}-${{ github.sha }}-libressl From 2f0860409fa5f104836ea331f66f5d7de3fa2239 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 29 Apr 2022 11:38:44 +0200 Subject: [PATCH 2421/4321] Update actions to v3 --- .github/workflows/linux.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 49e22b4c2c..0ad6bb2762 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -191,10 +191,10 @@ jobs: build-openssl-3: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh ossl3 - run: .github/build.sh dist ossl3 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: logs path: | @@ -218,8 +218,8 @@ jobs: runs-on: ubuntu-latest needs: [build-openssl-3] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -231,8 +231,8 @@ jobs: runs-on: ubuntu-latest needs: [build-openssl-3] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -246,10 +246,10 @@ jobs: build-libressl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: logs path: | @@ -266,8 +266,8 @@ jobs: runs-on: ubuntu-latest needs: [build-libressl] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -279,8 +279,8 @@ jobs: runs-on: ubuntu-latest needs: [build-libressl] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* From 05e23bf8bd7014030b32647baad5fcbcb220f928 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 29 Apr 2022 16:05:05 +0200 Subject: [PATCH 2422/4321] .gihub: Try to limit the output of the openssl/libressl builds we are not much interested in this output --- .github/setup-linux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 6a95828a91..1c253be605 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -55,12 +55,12 @@ sudo apt-get install -y build-essential $DEPS # install openssl 3.0 if needed if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - ./.github/setup-openssl.sh + ./.github/setup-openssl.sh &> /tmp/openssl.log || cat /tmp/openssl.log fi # install libressl if needed if [ "$1" == "libressl" -o "$2" == "libressl" ]; then - ./.github/setup-libressl.sh + ./.github/setup-libressl.sh &> /tmp/libressl.log || cat /tmp/libressl.log fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then From 64be6695cee03655e489ffc11a9fd97f2b534285 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 29 Apr 2022 17:02:11 +0200 Subject: [PATCH 2423/4321] Try to keep openssl installed, but remove libssl-dev --- .github/setup-libressl.sh | 2 +- .github/setup-openssl.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh index 298d837170..eed62cbc30 100755 --- a/.github/setup-libressl.sh +++ b/.github/setup-libressl.sh @@ -4,7 +4,7 @@ set -ex -o xtrace V=libressl-3.4.2 -sudo apt-get remove -y openssl libssl-dev java8-runtime-headless default-jre-headless +sudo apt-get remove -y libssl-dev if [ ! -d "$V" ]; then # letsencrypt CA does not seem to be included in CI runner diff --git a/.github/setup-openssl.sh b/.github/setup-openssl.sh index 08048918fd..c37ebc9f34 100755 --- a/.github/setup-openssl.sh +++ b/.github/setup-openssl.sh @@ -2,7 +2,7 @@ set -ex -o xtrace -sudo apt-get remove -y openssl libssl-dev java8-runtime-headless default-jre-headless +sudo apt-get remove -y libssl-dev if [ ! -d "openssl" ]; then git clone --single-branch --branch=openssl-3.0 --depth 1 https://github.com/openssl/openssl From 0ed4b62ae9cd7104706b779fd50bb65385443310 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Apr 2022 00:24:44 +0200 Subject: [PATCH 2424/4321] fixed accessing data length before accessing buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes UNKNOWN READ · sc_pkcs15_decode_pubkey_ec https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46852 --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 5c45104bcb..6982ccee97 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -649,7 +649,7 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, if (r < 0) LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - if (*ecpoint_data != 0x04) + if (ecpoint_len == 0 || *ecpoint_data != 0x04) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); key->ecpointQ.len = ecpoint_len; From 9035200bb931ef11a422854435079824fb9ae580 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Apr 2022 00:31:16 +0200 Subject: [PATCH 2425/4321] fixed input checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes Index-out-of-bounds · epassNUMBER_pkcs15_key_reference https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46738 --- src/pkcs15init/pkcs15-epass2003.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index b845b95a05..91d406c022 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -298,6 +298,8 @@ static int epass2003_pkcs15_key_reference(struct sc_profile *profile, struct sc_pkcs15_prkey_info *prkey) { SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); + if (prkey->path.len == 0) + SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); prkey->key_reference = prkey->path.value[prkey->path.len - 1]; SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } From 1e6558ad6fb4cb508bd6a9d115e0899eaf6d3926 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Apr 2022 00:42:50 +0200 Subject: [PATCH 2426/4321] fixed input checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes Heap-buffer-overflow READ 1 · sc_pkcs15init_delete_by_path https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46653 --- src/pkcs15init/pkcs15-lib.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 3e96fc6ec9..718d458cc0 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -588,9 +588,9 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * * card (driver and profile) that uses self delete ACL. */ /* Select the file itself */ - path = *file_path; - rv = sc_select_file(p15card->card, &path, &file); - LOG_TEST_RET(ctx, rv, "cannot select file to delete"); + path = *file_path; + rv = sc_select_file(p15card->card, &path, &file); + LOG_TEST_RET(ctx, rv, "cannot select file to delete"); if (sc_file_get_acl_entry(file, SC_AC_OP_DELETE_SELF)) { sc_log(ctx, "Found 'DELETE-SELF' acl"); @@ -625,6 +625,8 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; + if (file_path->len < 2) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); path.value[0] = file_path->value[file_path->len - 2]; path.value[1] = file_path->value[file_path->len - 1]; path.len = 2; From 8697a01850d5e02a3099acd5160d0a0ee2d31077 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Apr 2022 00:55:52 +0200 Subject: [PATCH 2427/4321] fixed input checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes Heap-buffer-overflow WRITE 2 · do_fileid https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=45430 --- src/pkcs15init/profile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index d2376abf00..598daf39ac 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1355,6 +1355,10 @@ do_fileid(struct state *cur, int argc, char **argv) } *path = df->path; } + if (path->len + 2 > sizeof(path->value)) { + parse_error(cur, "File path too long\n"); + return 1; + } memcpy(path->value + path->len, temp.value, 2); path->len += 2; From fdf343bfcd80d8041f6d199492cf5508dec7b2f8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 30 Apr 2022 01:14:06 +0200 Subject: [PATCH 2428/4321] sc-hsm: fixed buffer length check in listing files --- src/libopensc/card-sc-hsm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index ee3073dbea..b39e88b643 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -924,7 +924,10 @@ static int sc_hsm_list_files(sc_card_t *card, u8 * buf, size_t buflen) } LOG_TEST_RET(card->ctx, r, "ENUMERATE OBJECTS APDU transmit failed"); - memcpy(buf, recvbuf, buflen); + if (buflen < apdu.resplen) + memcpy(buf, recvbuf, buflen); + else + memcpy(buf, recvbuf, apdu.resplen); LOG_FUNC_RETURN(card->ctx, apdu.resplen); } From a6f363b92963b635d14897c9fef18c5354be4ff5 Mon Sep 17 00:00:00 2001 From: funnydog Date: Fri, 29 Apr 2022 20:11:47 +0200 Subject: [PATCH 2429/4321] Add an entry for Oberthur Technologies, Cosmo ID ONE(T) smart cards as "Italian CNS (e)" to the minidriver. --- win32/customactions.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index f2d9ad4124..7595cdf329 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -136,6 +136,8 @@ MD_REGISTRATION minidriver_registration[] = { 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Italian CNS (d)"), {0x3b,0xff,0x18,0x00,0xff,0x81,0x31,0xfe,0x55,0x00,0x6b,0x02,0x09,0x03,0x03,0x01,0x01,0x01,0x43,0x4e,0x53,0x10,0x31,0x80,0x9d}, 25, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("Italian CNS (e)"), {0x3b,0xff,0x18,0x00,0x00,0x81,0x31,0xfe,0x45,0x00,0x6b,0x11,0x05,0x07,0x00,0x01,0x21,0x01,0x43,0x4e,0x53,0x10,0x31,0x80,0x4a}, + 25, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("CardOS 4.0 a"), {0x3b,0xf4,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x4d,0x34,0x63,0x76,0xb4}, 15, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Cardos M4"), {0x3b,0xf2,0x18,0x00,0x02,0xc1,0x0a,0x31,0xfe,0x58,0xc8,0x08,0x74}, From d336f7f95e44b8797dd6e160e72c99f3b66eebdf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 18 Apr 2022 16:33:38 +0200 Subject: [PATCH 2430/4321] Enable getting buffer with max defined size --- src/tests/fuzzing/fuzzer_tool.c | 15 +++++++++------ src/tests/fuzzing/fuzzer_tool.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tests/fuzzing/fuzzer_tool.c b/src/tests/fuzzing/fuzzer_tool.c index a34e6c017e..aaa487ea62 100644 --- a/src/tests/fuzzing/fuzzer_tool.c +++ b/src/tests/fuzzing/fuzzer_tool.c @@ -90,20 +90,23 @@ int get_fuzzed_argv(const char *app_name, const uint8_t *data, size_t size, return 0; } -static uint16_t get_buffer(const uint8_t **buf, size_t buf_len, const uint8_t **out, size_t *out_len) +uint16_t get_buffer(const uint8_t **buf, size_t buf_len, const uint8_t **out, size_t *out_len, size_t max_size) { /* Split buf into two parts according to length stored in first two bytes */ uint16_t len = 0; - if (!buf || !(*buf) || buf_len < 2) + if (!buf || !(*buf) || buf_len < sizeof(uint16_t)) return 0; /* Get length of the result buffer*/ - len = *((uint16_t *) *buf); - if (buf_len - 2 <= len) - return 0; + len = *((uint16_t *) *buf) % max_size; (*buf) += 2; buf_len -= 2; + if (buf_len <= len) { + *out = *buf; + *out_len = buf_len; + return 0; + } /* Set out buffer to new reader data*/ *out = *buf + len; @@ -120,7 +123,7 @@ int create_input_file(char **filename_out, const uint8_t **data, size_t *size) char *filename = NULL; /* Split data into file content and rest*/ - file_size = get_buffer(&ptr, *size, data, size); + file_size = get_buffer(&ptr, *size, data, size, 6000); if (file_size == 0) return 1; diff --git a/src/tests/fuzzing/fuzzer_tool.h b/src/tests/fuzzing/fuzzer_tool.h index 5c83242440..85b4f28d2a 100644 --- a/src/tests/fuzzing/fuzzer_tool.h +++ b/src/tests/fuzzing/fuzzer_tool.h @@ -36,6 +36,7 @@ const uint8_t *get_word(const uint8_t *, size_t); char *extract_word(const uint8_t **, size_t *); int get_fuzzed_argv(const char *, const uint8_t *, size_t , char***, int *, const uint8_t **, size_t *); +uint16_t get_buffer(const uint8_t **, size_t, const uint8_t **, size_t *, size_t); int create_input_file(char **, const uint8_t **, size_t *); void remove_file(char *); void free_arguments(int, char **); From 67f73b6f69ea2e2cc2ee5386a9bddcbd77df346a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 28 Apr 2022 16:09:00 +0200 Subject: [PATCH 2431/4321] Add declaration sc_pkcs11_card_free() --- src/pkcs11/sc-pkcs11.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index de106257f6..992a8b525f 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -377,6 +377,7 @@ void strcpy_bp(u8 *dst, const char *src, size_t dstsize); CK_RV sc_to_cryptoki_error(int rc, const char *ctx); void sc_pkcs11_print_attrs(int level, const char *file, unsigned int line, const char *function, const char *info, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); +void sc_pkcs11_card_free(struct sc_pkcs11_card *p11card); #define dump_template(level, info, pTemplate, ulCount) \ sc_pkcs11_print_attrs(level, FILENAME, __LINE__, __FUNCTION__, \ info, pTemplate, ulCount) From 522d9410cb0e03b76d60a3a0aac1593bd134458a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 22 Apr 2022 16:10:13 +0200 Subject: [PATCH 2432/4321] Release operations in C_CloseSession --- src/pkcs11/pkcs11-session.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 402859705f..7fb9cb361b 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -126,6 +126,8 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession) slot->p11card->framework->logout(slot); } } + for (size_t i = 0; i < SC_PKCS11_OPERATION_MAX; i++) + sc_pkcs11_release_operation(&session->operation[i]); if (list_delete(&sessions, session) != 0) sc_log(context, "Could not delete session from list!"); From 8bb15107a0495e2e0e9ffbc6673e39f04e304674 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 18 Apr 2022 16:34:05 +0200 Subject: [PATCH 2433/4321] Add fuzz target fot PKCS#11 API --- src/tests/fuzzing/Makefile.am | 13 +- src/tests/fuzzing/fuzz_pkcs11.c | 1069 +++++++++++++++++++++++++++++++ 2 files changed, 1081 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/fuzz_pkcs11.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 0880bf8c21..0e719c611f 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -1,4 +1,5 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src -D'SC_PKCS15_PROFILE_DIRECTORY="$(pkgdatadir)"' +AM_CPPFLAGS = -I$(top_srcdir)/src -D'SC_PKCS15_PROFILE_DIRECTORY="$(pkgdatadir)"' \ + -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' AM_CFLAGS = -g -O0 $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) LIBS = $(FUZZING_LIBS)\ $(top_builddir)/src/libopensc/libopensc.la \ @@ -18,6 +19,11 @@ if ENABLE_OPENSSL noinst_PROGRAMS += fuzz_piv_tool endif +if ENABLE_SHARED +else +noinst_PROGRAMS += fuzz_pkcs11 +endif + noinst_HEADERS = fuzzer_reader.h fuzzer_tool.h ADDITIONAL_SRC = @@ -44,3 +50,8 @@ fuzz_pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) fuzz_pkcs15_crypt_SOURCES = fuzz_pkcs15_crypt.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) \ ../../tools/util.c fuzz_pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) +fuzz_pkcs11_SOURCES = fuzz_pkcs11.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) +fuzz_pkcs11_LDADD = \ + $(top_builddir)/src/common/libpkcs11.la \ + $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_CFLAGS) \ + $(top_builddir)/src/pkcs11/libopensc-pkcs11.la diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c new file mode 100644 index 0000000000..5a3ff08bc8 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -0,0 +1,1069 @@ +/* + * fuzz_pkcs11.c: Fuzz target for PKCS #11 API + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pkcs11/pkcs11.h" +#include "pkcs11/pkcs11-opensc.h" +#include "pkcs11/sc-pkcs11.h" +#include "fuzzer_reader.h" +#include "fuzzer_tool.h" + +#define SIG_LEN 512 + +/* If disabled, card is connected only via C_Initialize */ +#define FUZZING 1 + +extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; +static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; + +/* Values used for key template*/ +static CK_BBOOL _true = TRUE; +static CK_BBOOL _false = FALSE; + +/* Global parameters for key template */ +CK_ULONG key_type = 0; +unsigned char ecparams[256]; +unsigned char *opt_object_label[256]; +CK_BYTE opt_object_id[100]; +CK_MECHANISM_TYPE opt_allowed_mechanisms[20]; + +#if FUZZING +static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t **slot_out) +{ + /* Works in the same manner as card_detect() for only one slot and card with virtual reader */ + struct sc_pkcs11_card *p11card = NULL; + struct sc_reader *reader = NULL; + struct sc_app_info *app_generic = NULL; + sc_pkcs11_slot_t *slot = NULL; + int rv = CKR_OK; + + /* Erase possible virtual slots*/ + list_clear(&virtual_slots); + + /* Erase possible readers from context */ + while (list_size(&context->readers)) { + sc_reader_t *rdr = (sc_reader_t *) list_get_at(&context->readers, 0); + _sc_delete_reader(context, rdr); + } + if (context->reader_driver->ops->finish != NULL) + context->reader_driver->ops->finish(context); + + /* Create virtual reader */ + context->reader_driver = sc_get_fuzz_driver(); + fuzz_add_reader(context, data, size); + reader = sc_ctx_get_reader(context, 0); + + /* Add slot for reader */ + if (create_slot(reader) != CKR_OK) { + goto fail; + } + + /* Locate a slot related to the reader */ + for (size_t i = 0; i < list_size(&virtual_slots); i++) { + slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); + if (slot->reader == reader) { + p11card = slot->p11card; + break; + } + } + + /* Create p11card */ + p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card)); + p11card->reader = reader; + + /* Connect card to reader */ + if ((rv = sc_connect_card(reader, &p11card->card)) != SC_SUCCESS) { + goto fail; + } + init_slot_info(&slot->slot_info, reader); + + /* Instead of detecting framework*/ + p11card->framework = &framework_pkcs15; + + /* Bind 'generic' application or (emulated?) card without applications */ + app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic"); + if (app_generic || !p11card->card->app_count) { + scconf_block *conf_block = NULL; + + conf_block = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr); + if (!conf_block) /* check default block */ + conf_block = sc_get_conf_block(context, "framework", "pkcs15", 1); + + rv = p11card->framework->bind(p11card, app_generic); + if (rv != CKR_TOKEN_NOT_RECOGNIZED && rv != CKR_OK) + goto fail; + + rv = p11card->framework->create_tokens(p11card, app_generic); + if (rv != CKR_OK) + goto fail; + } + + /* Bind rest of application*/ + for (int j = 0; j < p11card->card->app_count; j++) { + struct sc_app_info *app_info = p11card->card->app[j]; + + if (app_generic && app_generic == p11card->card->app[j]) + continue; + + if (p11card->framework->bind(p11card, app_info) != CKR_OK) { + continue; + } + rv = p11card->framework->create_tokens(p11card, app_info); + if (rv != CKR_OK) { + goto fail; + } + } + if (slot_out) + *slot_out = slot; + return CKR_OK; +fail: + sc_pkcs11_card_free(p11card); + return rv; +} +#endif + +static int fuzz_pkcs11_initialize(const uint8_t *data, size_t size, sc_pkcs11_slot_t **slot_out, CK_SESSION_HANDLE *session) +{ + p11 = &pkcs11_function_list_3_0; + + context = NULL; + memset(&sc_pkcs11_conf, 0, sizeof(struct sc_pkcs11_config)); + + p11->C_Initialize(NULL); + + #if FUZZING + /* fuzz target can connect to real card via C_Initialize */ + if (fuzz_card_connect(data, size, slot_out) != CKR_OK) { + p11->C_Finalize(NULL); + return CKR_GENERAL_ERROR; + } + #endif + + if (p11->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, session) != CKR_OK) { + p11->C_Finalize(NULL); + return CKR_GENERAL_ERROR; + } + return CKR_OK; +} + +static int set_mechanism(const uint8_t **data, size_t *size, CK_MECHANISM *mech) +{ + if (*size < sizeof(unsigned long int)) + return 1; + + memset(mech, 0, sizeof(*mech)); + (*mech).mechanism = *((unsigned long int *)*data); + *data += sizeof(unsigned long int); + *size -= sizeof(unsigned long int); + return 0; +} + +static void test_change_pin(const unsigned char *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_TOKEN_INFO info; + char *pin = NULL; + char *new_pin = NULL; + int login_type = data[0]; + data++; size--; + + if (!(pin = extract_word(&data, &size))) + goto end; + if (!(new_pin = extract_word(&data, &size))) + goto end; + + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + p11->C_GetTokenInfo(0, &info); + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin)); + p11->C_SetPIN(session, + (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin), + (CK_UTF8CHAR *) new_pin, new_pin == NULL ? 0 : strlen(new_pin)); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(new_pin); + free(pin); +} + +static void test_init_pin(const unsigned char *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_TOKEN_INFO info; + char *pin = NULL; + char *so_pin = NULL; + int login_type = data[0]; + data++; size--; + + if (!(pin = extract_word(&data, &size))) + goto end; + if (!(so_pin = extract_word(&data, &size))) + goto end; + + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + p11->C_GetTokenInfo(0, &info); + p11->C_Login(session, login_type, (CK_UTF8CHAR *) so_pin, so_pin == NULL ? 0 : strlen(pin)); + p11->C_InitPIN(session, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin)); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(so_pin); +} + +static void test_init_token(const unsigned char *data, size_t size) +{ + CK_SESSION_HANDLE session; + char *pin = NULL; + unsigned char *label = NULL; + size_t label_len = 0; + unsigned char token_label[33]; + sc_pkcs11_slot_t *slot = NULL; + /* token label must be padded with blank characters, and which must not be null-terminated*/ + memset(token_label, ' ', sizeof(token_label)); + + if (!(pin = extract_word(&data, &size))) + goto end; + if (!(label = (unsigned char *) extract_word(&data, &size))) + goto end; + label_len = strlen((char *) label); + memcpy(token_label, label, label_len < 33 ? label_len : 32); + + if (fuzz_pkcs11_initialize(data, size, &slot, &session) != CKR_OK) + goto end; + p11->C_InitToken(slot->id, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin), token_label); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(label); +} + +static void test_random(const unsigned char *data, size_t size) +{ + CK_SESSION_HANDLE session; + size_t random_len = data[0]; + CK_BYTE buf[256]; + data++; size--; + + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + return; + + p11->C_GenerateRandom(session, buf, random_len); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +} + +static void test_digest_update(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + const uint8_t *dig_data = NULL; + size_t dig_size = 0; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + unsigned char buffer[64] = {0}; + CK_ULONG hash_len = sizeof(buffer); + int to_process = 0, rv = 0; + + if (set_mechanism(&data, &size, &mech)) + return; + + /* Copy data for hashing*/ + dig_data = data; + if ((dig_size = get_buffer(&dig_data, size, &data, &size, 6000)) == 0) + return; + + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + return; + + if (p11->C_DigestInit(session, &mech) != CKR_OK) + goto end; + + while (dig_size > 0) { + to_process = dig_size > sizeof(buffer) ? sizeof(buffer) : dig_size; + dig_size -= to_process; + memcpy(buffer, dig_data, to_process); + dig_data += to_process; + + rv = p11->C_DigestUpdate(session, buffer, to_process); + if (rv != CKR_OK) + goto end; + } + hash_len = sizeof(buffer); + p11->C_DigestFinal(session, buffer, &hash_len); + +end: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +} + +void test_digest(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + const uint8_t *ptr = NULL; + unsigned char *dig_data = NULL; + size_t dig_size = 0; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + unsigned char buffer[64] = {0}; + CK_ULONG hash_len = sizeof(buffer); + + if (set_mechanism(&data, &size, &mech)) + return; + + /* Copy data for hashing*/ + ptr = data; + if ((dig_size = get_buffer(&ptr, size, &data, &size, 6000)) == 0) + return; + if (!(dig_data = malloc(dig_size))) + return; + memcpy(dig_data, ptr, dig_size); + + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + if (p11->C_DigestInit(session, &mech) == CKR_OK) + p11->C_Digest(session, dig_data, dig_size, buffer, &hash_len); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(dig_data); +} + +static int fuzz_find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, + CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len) +{ + /* taken from tools/pkcs11-tool.c */ + CK_ATTRIBUTE attrs[2]; + unsigned int nattrs = 0; + CK_ULONG count = 0; + + attrs[0].type = CKA_CLASS; + attrs[0].pValue = &cls; + attrs[0].ulValueLen = sizeof(cls); + nattrs++; + if (id) { + attrs[nattrs].type = CKA_ID; + attrs[nattrs].pValue = (void *) id; + attrs[nattrs].ulValueLen = id_len; + nattrs++; + } + + if (p11->C_FindObjectsInit(sess, attrs, nattrs) != CKR_OK) + return -1; + + if (p11->C_FindObjects(sess, ret, 1, &count) != CKR_OK) + return -1; + + if (count == 0) + *ret = CK_INVALID_HANDLE; + p11->C_FindObjectsFinal(sess); + return count; +} + +static void test_sign(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + uint8_t login_type = CKU_USER; + char *pin = NULL; + const unsigned char *opt_id; + size_t opt_id_len = 0; + const uint8_t *sign_data = NULL; + size_t sign_data_size = 0; + CK_OBJECT_HANDLE key = CK_INVALID_HANDLE; + unsigned char in_buffer[1025], sig_buffer[512]; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + CK_ULONG sig_len = sizeof(sig_buffer); + size_t to_process = 0; + CK_TOKEN_INFO info; + + /* Process options*/ + if (set_mechanism(&data, &size, &mech) || size < 3) + return; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + return; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + + /* Prepare buffer for signing */ + sign_data = data; + if ((sign_data_size = get_buffer(&sign_data, size, &data, &size, 6000)) == 0) + goto end; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + p11->C_GetTokenInfo(0, &info); + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len); + + if (p11->C_SignInit(session, &mech, key) != CKR_OK) + goto fin; + p11->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_UTF8CHAR *) pin, strlen(pin)); + + if (sign_data_size <= sizeof(in_buffer)) { + memcpy(in_buffer, sign_data, sign_data_size); + p11->C_Sign(session, in_buffer, sign_data_size, sig_buffer, &sig_len); + } else { + while (sign_data_size > 0) { + to_process = sign_data_size < sizeof(in_buffer) ? sign_data_size : sizeof(in_buffer); + sign_data_size -= to_process; + memcpy(in_buffer, sign_data, to_process); + sign_data += to_process; + + if (p11->C_SignUpdate(session, in_buffer, to_process) != CKR_OK) + goto fin; + } + + sig_len = sizeof(sig_buffer); + p11->C_SignFinal(session, sig_buffer, &sig_len); + } + +fin: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); +} + +static void test_verify(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + uint8_t login_type = CKU_USER; + char *pin = NULL; + const unsigned char *opt_id = NULL; + size_t opt_id_len = 0; + const uint8_t *verify_data = NULL, *sig_data = NULL; + size_t verify_data_size = 0; + CK_OBJECT_HANDLE key = CK_INVALID_HANDLE; + unsigned char in_buffer[1025], sig_buffer[512]; + CK_ULONG sig_len = sizeof(sig_buffer); + size_t to_process = 0; + + /* Process options*/ + if (set_mechanism(&data, &size, &mech) || size < 3) + return; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + return; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + + /* Prepare buffer with data */ + verify_data = data; + if ((verify_data_size = get_buffer(&verify_data, size, &data, &size, 6000)) == 0) + goto end; + /* Get buffer with signature */ + sig_data = data; + if ((sig_len = get_buffer(&sig_data, size, &data, &size, 512)) == 0) + goto end; + memcpy(sig_buffer, sig_data, sig_len); + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + + if (!fuzz_find_object(session, CKO_PUBLIC_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len) + && !fuzz_find_object(session, CKO_CERTIFICATE, &key, opt_id_len ? opt_id : NULL, opt_id_len)) + goto fin; + + if (p11->C_VerifyInit(session, &mech, key) != CKR_OK) + goto fin; + + if (verify_data_size <= sizeof(in_buffer)) { + memcpy(in_buffer, verify_data, verify_data_size); + p11->C_Verify(session, in_buffer, verify_data_size, sig_buffer, sig_len); + } else { + while (size > 0) { + to_process = verify_data_size < sizeof(in_buffer) ? verify_data_size : sizeof(in_buffer); + verify_data_size -= to_process; + memcpy(in_buffer, data, to_process); + verify_data += to_process; + + if (p11->C_VerifyUpdate(session, in_buffer, to_process) != CKR_OK) + goto fin; + } + + p11->C_VerifyFinal(session, sig_buffer, sig_len); + } +fin: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); +} + +static void test_decrypt(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + uint8_t login_type = CKU_USER; + char *pin = NULL; + const unsigned char *opt_id; + size_t opt_id_len = 0; + const uint8_t *dec_data = NULL; + size_t dec_data_size = 0; + CK_OBJECT_HANDLE key = CK_INVALID_HANDLE; + unsigned char in_buffer[1024], out_buffer[1024]; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + size_t out_len = 0; + + /* Process options*/ + if (set_mechanism(&data, &size, &mech) || size < 3) + return; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + return; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + + /* Prepare buffer for signing */ + dec_data = data; + if ((dec_data_size = get_buffer(&dec_data, size, &data, &size, 1024)) == 0) + goto end; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + if (!fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len) + && !fuzz_find_object(session, CKO_SECRET_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len)) + goto fin; + + if (p11->C_DecryptInit(session, &mech, key) != CKR_OK) + goto fin; + + p11->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_UTF8CHAR *) pin, strlen(pin)); + out_len = sizeof(out_buffer); + + memcpy(in_buffer, dec_data, dec_data_size); + p11->C_Decrypt(session, in_buffer, dec_data_size, out_buffer, &out_len); +fin: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); +} + +static void test_wrap(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + uint8_t login_type = CKU_USER; + char *pin = NULL; + CK_BYTE pWrappedKey[4096]; + CK_ULONG pulWrappedKeyLen = sizeof(pWrappedKey); + CK_MECHANISM mech = {0, NULL_PTR, 0}; + CK_OBJECT_HANDLE hWrappingKey; + CK_OBJECT_HANDLE hkey; + const unsigned char *hkey_id; + const unsigned char *opt_id; + size_t opt_id_len = 0, hkey_id_len = 0; + + /* Set options */ + if (set_mechanism(&data, &size, &mech) || size < 3) + return; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + return; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + hkey_id = data; + hkey_id_len = get_buffer(&hkey_id, size, &data, &size, 256); + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + if (!fuzz_find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len)) + goto fin; + if (!fuzz_find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, opt_id_len ? opt_id : NULL, opt_id_len)) + if (!fuzz_find_object(session, CKO_SECRET_KEY, &hWrappingKey, opt_id_len ? opt_id : NULL, opt_id_len)) + goto fin; + p11->C_WrapKey(session, &mech, hWrappingKey, hkey, pWrappedKey, &pulWrappedKeyLen); + +fin: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); +} + +#define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;} +void fill_bool_attr(CK_ATTRIBUTE **keyTemplate, int *n_attr, int type, int value) +{ + if (value) { + FILL_ATTR((*keyTemplate)[*n_attr], type, &_true, sizeof(_true)); + } + else { + FILL_ATTR((*keyTemplate)[*n_attr], type, &_false, sizeof(_false)); + } + + ++(*n_attr); +} + +int fill_key_template(CK_ATTRIBUTE **keyTemplate, int *n_attr, const uint8_t **data, size_t *size, CK_OBJECT_CLASS *class, int token) +{ + const unsigned char *ptr = NULL; + size_t ecparams_size = 0; + size_t opt_object_label_size = 0; + size_t opt_object_id_len = 0; + size_t opt_allowed_mechanisms_len = 0; + int bool_types[] = {CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_VERIFY, CKA_SENSITIVE, + CKA_SIGN, CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, + CKA_DERIVE, CKA_PRIVATE, CKA_ALWAYS_AUTHENTICATE, CKA_EXTRACTABLE}; + + if (!(*keyTemplate = malloc(20 * sizeof(CK_ATTRIBUTE)))) + return 1; + memset(*keyTemplate, 0, 20 * sizeof(CK_ATTRIBUTE)); + FILL_ATTR((*keyTemplate)[0], CKA_CLASS, class, sizeof(CKA_CLASS)); + *n_attr = 1; + fill_bool_attr(keyTemplate, n_attr, CKA_TOKEN, token); + + for (int i = 0; i < 13; i++) { + /* ... | present -> 0/1 | value | ...*/ + if (*size < 3) + return 1; + if ((*data)[0] % 2) { + fill_bool_attr(keyTemplate, n_attr, bool_types[i], (*data)[1] % 2); + (*data)++; (*size)--; + } + (*data)++; (*size)--; + } + + if (*size > 2 && (*data)[0] % 2 && *n_attr < 20){ + /* ... | present -> 0/1 | value | ...*/ + key_type = (CK_ULONG) (*data)[1]; + FILL_ATTR((*keyTemplate)[*n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + ++(*n_attr); + (*data) += 2; + (*size) -= 2; + } + + if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){ + /* ... | present -> 0/1 | len | len | data | ... */ + (*data)++; (*size)--; + ptr = *data; + if ((ecparams_size = get_buffer(&ptr, *size, data, size, 256)) == 0) + return 1; + memcpy(ecparams, ptr, ecparams_size); + FILL_ATTR((*keyTemplate)[*n_attr], CKA_EC_PARAMS, ecparams, ecparams_size); + ++(*n_attr); + } + + if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){ + /* ... | present -> 0/1 | len | len | data | ... */ + (*data)++; (*size)--; + ptr = *data; + if ((opt_object_label_size = get_buffer(&ptr, *size, data, size, 128)) == 0) + return 1; + memcpy(opt_object_label, ptr, opt_object_label_size); + FILL_ATTR((*keyTemplate)[*n_attr], CKA_LABEL, opt_object_label, opt_object_label_size); + ++(*n_attr); + } + + if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){ + /* ... | present -> 0/1 | len | len | data | ... */ + (*data)++; (*size)--; + ptr = *data; + if ((opt_object_id_len = get_buffer(&ptr, *size, data, size, 100)) == 0) + return 1; + memcpy(opt_object_id, ptr, opt_object_id_len); + FILL_ATTR((*keyTemplate)[*n_attr], CKA_ID, opt_object_id, opt_object_id_len); + ++(*n_attr); + } + if (*size > 4 && (*data)[0] % 2 && *n_attr < 20){ + /* ... | present -> 0/1 | len | mech1 | mech2 | ... | mechn | ... */ + opt_allowed_mechanisms_len = (*data)[1] > 20 ? 20 : (*data)[1]; + (*data) += 2; + (*size) -= 2; + for (size_t i = 0; i < opt_allowed_mechanisms_len; i++) { + if (*size <= sizeof(unsigned int)) + return 1; + opt_allowed_mechanisms[i] = *((unsigned int *)data); + (*data) += sizeof(unsigned int); + (*size) -= sizeof(unsigned int); + } + FILL_ATTR((*keyTemplate)[*n_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, opt_allowed_mechanisms_len); + ++(*n_attr); + } + if (*size == 0) + return 1; + return 0; +} + +static void test_unwrap(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + uint8_t login_type = CKU_USER; + char *pin = NULL; + const unsigned char *opt_id, *wrapped_key; + size_t opt_id_len; + CK_OBJECT_HANDLE hUnwrappingKey; + CK_ULONG wrapped_key_length; + CK_BYTE_PTR pWrappedKey; + unsigned char in_buffer[1024]; + CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY; + CK_ATTRIBUTE *keyTemplate = NULL; + int n_attr = 2; + CK_OBJECT_HANDLE hSecretKey; + + /* Set options */ + if (set_mechanism(&data, &size, &mech) || size < 3) + goto end; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + goto end; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + wrapped_key = data; + if ((wrapped_key_length = get_buffer(&wrapped_key, size, &data, &size, 1024)) == 0) + goto end; + memcpy(in_buffer, wrapped_key, wrapped_key_length); + pWrappedKey = in_buffer; + + if (fill_key_template((CK_ATTRIBUTE **) &keyTemplate, &n_attr, &data, &size, &secret_key_class, true)) + goto end; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + /* Find keys*/ + if (!fuzz_find_object(session, CKO_PRIVATE_KEY, &hUnwrappingKey, opt_id_len ? opt_id : NULL, opt_id_len)) + if (!fuzz_find_object(session, CKO_SECRET_KEY, &hUnwrappingKey, opt_id_len ? opt_id : NULL, opt_id_len)) + goto fin; + p11->C_UnwrapKey(session, &mech, hUnwrappingKey, pWrappedKey, wrapped_key_length, keyTemplate, n_attr, &hSecretKey); + +fin: + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(keyTemplate); +} + +static void test_derive(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE key; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + uint8_t login_type = CKU_USER; + char *pin = NULL; + const unsigned char *opt_id = NULL; + size_t opt_id_len; + CK_OBJECT_HANDLE newkey = 0; + CK_OBJECT_CLASS newkey_class = CKO_SECRET_KEY; + CK_ATTRIBUTE *keyTemplate = NULL; + int n_attrs = 2; + + /* Set options */ + if (set_mechanism(&data, &size, &mech) || size < 3) + goto end; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + goto end; + opt_id = data; + opt_id_len = get_buffer(&opt_id, size, &data, &size, 256); + if (fill_key_template((CK_ATTRIBUTE **) &keyTemplate, &n_attrs, &data, &size, &newkey_class, false)) + goto end; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + if (fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len)) + p11->C_DeriveKey(session, &mech, key, keyTemplate, n_attrs, &newkey); + + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(keyTemplate); +} + +static void test_genkeypair(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE hPublicKey; + CK_OBJECT_HANDLE hPrivateKey; + CK_MECHANISM mech = {0, NULL_PTR, 0}; + uint8_t login_type = CKU_USER; + char *pin = NULL; + CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; + CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY; + int n_pubkey_attr = 2; + int n_privkey_attr = 2; + CK_ATTRIBUTE *publicKeyTemplate = NULL; + CK_ATTRIBUTE *privateKeyTemplate = NULL; + + /* Process options*/ + if (set_mechanism(&data, &size, &mech) || size < 3) + goto end; + login_type = data[0]; + data++; size--; + if (!(pin = extract_word(&data, &size))) + goto end; + + if (fill_key_template(&publicKeyTemplate, &n_pubkey_attr, &data, &size, &pubkey_class, true) != 0 + || fill_key_template(&privateKeyTemplate, &n_privkey_attr, &data, &size, &privkey_class, true) != 0) + goto end; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + p11->C_GenerateKeyPair(session, &mech, publicKeyTemplate, n_pubkey_attr, + privateKeyTemplate, n_privkey_attr, + &hPublicKey, &hPrivateKey); + p11->C_CloseSession(session); + p11->C_Finalize(NULL); + +end: + free(pin); + free(privateKeyTemplate); + free(publicKeyTemplate); +} + +static void test_store_data(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE data_obj; + CK_OBJECT_CLASS class = CKO_DATA; + uint8_t login_type = CKU_USER; + unsigned char contents[5001]; + int contents_len = 0; + const uint8_t *ptr = NULL; + CK_ATTRIBUTE *data_templ = NULL; + int n_data_attr = 0; + char *pin = NULL; + unsigned char app_id[256]; + int app_id_len = 0; + + /* Create data template */ + if (!(data_templ = malloc(20 * sizeof(CK_ATTRIBUTE)))) + return; + memset(data_templ, 0, 20 * sizeof(CK_ATTRIBUTE)); + + /* Get PIN */ + if (!(pin = extract_word(&data, &size))) + goto end; + + /* Extract content from fuzzing input*/ + memset(contents, 0, sizeof(contents)); + ptr = data; + if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0) + goto end; + memcpy(contents, ptr, contents_len); + contents[contents_len] = '\0'; + + /* Fill attributes to data template */ + if (size < 4) + goto end; + FILL_ATTR(data_templ[n_data_attr++], CKA_CLASS, &class, sizeof(class)); + FILL_ATTR(data_templ[n_data_attr++], CKA_VALUE, &contents, contents_len); + fill_bool_attr(&data_templ, &n_data_attr, CKA_TOKEN, *data % 2); + data++; size--; + fill_bool_attr(&data_templ, &n_data_attr, CKA_PRIVATE, *data % 2); + data++; size--; + + /* Get application id*/ + if (data[0] % 2){ + data++; size--; + ptr = data; + if ((app_id_len = get_buffer(&ptr, size, &data, &size, 256)) == 0) + goto end; + memcpy(app_id, ptr, app_id_len); + FILL_ATTR(data_templ[n_data_attr++], CKA_OBJECT_ID, app_id, app_id_len); + } + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + p11->C_CreateObject(session, data_templ, n_data_attr, &data_obj); + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(data_templ); + free(pin); +} + +static void test_store_cert(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_OBJECT_CLASS class = CKO_CERTIFICATE; + uint8_t login_type = CKU_USER; + unsigned char contents[5000]; + int contents_len = 0; + const uint8_t *ptr = NULL; + CK_ATTRIBUTE *cert_templ = NULL; + int n_cert_attr = 0; + char *pin = NULL; + CK_OBJECT_HANDLE cert_obj; + CK_CERTIFICATE_TYPE cert_type = CKC_X_509; + + /* Create certificate template */ + if (!(cert_templ = malloc(20 * sizeof(CK_ATTRIBUTE)))) + return; + memset(cert_templ, 0, 20 * sizeof(CK_ATTRIBUTE)); + + /* Get PIN */ + if (!(pin = extract_word(&data, &size))) + goto end; + + /* Extract content from fuzzing input */ + memset(contents, 0, sizeof(contents)); + ptr = data; + if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0) + goto end; + memcpy(contents, ptr, contents_len); + contents[contents_len] = '\0'; + + /* Fill attributes to certificate template */ + if (size < 4) + goto end; + FILL_ATTR(cert_templ[n_cert_attr++], CKA_CLASS, &class, sizeof(class)); + FILL_ATTR(cert_templ[n_cert_attr++], CKA_VALUE, contents, contents_len); + FILL_ATTR(cert_templ[n_cert_attr++], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); + fill_bool_attr(&cert_templ, &n_cert_attr, CKA_TOKEN, *data % 2); + data++; size--; + fill_bool_attr(&cert_templ, &n_cert_attr, CKA_PRIVATE, *data % 2); + data++; size--; + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + p11->C_CreateObject(session, cert_templ, n_cert_attr, &cert_obj); + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(cert_templ); +} + +static void test_store_key(const uint8_t *data, size_t size) +{ + CK_SESSION_HANDLE session; + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + uint8_t login_type = CKU_USER; + unsigned char contents[5000]; + int contents_len = 0; + const uint8_t *ptr = NULL; + CK_ATTRIBUTE *key_template = NULL; + int n_key_attr = 0; + char *pin = NULL; + CK_OBJECT_HANDLE key_obj; + + /* Get PIN */ + if (!(pin = extract_word(&data, &size))) + goto end; + + /* Extract content from fuzzing input */ + memset(contents, 0, sizeof(contents)); + + if (fill_key_template(&key_template, &n_key_attr, &data, &size, &class, true) != 0) + goto end; + + if (size < 3) + goto end; + if (data[0] && n_key_attr < 20) { + data++; size--; + ptr = data; + if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0) + goto end; + memcpy(contents, ptr, contents_len); + FILL_ATTR(key_template[n_key_attr++], CKA_VALUE, contents, contents_len); + } + class = *data; + data++; size--; + + + /* Initialize */ + if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) + goto end; + + p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin)); + p11->C_CreateObject(session, key_template, n_key_attr, &key_obj); + p11->C_CloseSession(session); + p11->C_Finalize(NULL); +end: + free(pin); + free(key_template); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + uint8_t operation = 0; + void (*func_ptr[])(const uint8_t*, size_t) = { + test_change_pin, + test_init_pin, + test_init_token, + test_random, + test_digest_update, + test_digest, + test_sign, + test_verify, + test_decrypt, + test_wrap, + test_unwrap, + test_derive, + test_genkeypair, + test_store_data, + test_store_cert, + test_store_key + }; + + if (size < 10) + return 0; + + operation = *data % 16; + data++; + size--; + + func_ptr[operation](data, size); + + return 0; +} From fd1976c8dd791da8dee6fff6c8bacde24ae709e6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 9 May 2022 12:02:43 +0200 Subject: [PATCH 2434/4321] Add corpus for fuzz_pkcs11 --- .../1dca0b7f951ad6c7cbb39e0e5fa1327ada85d4a5 | Bin 0 -> 1235 bytes .../334176efba3f10cbbb96b23d04ae03240ed31e0a | Bin 0 -> 2022 bytes .../533432db786d023c678187d79db1860ca1c44056 | Bin 0 -> 1850 bytes .../6ec181a01600525601900b9fe2b9eacf7d5df43d | Bin 0 -> 1769 bytes .../85bdf4bb93d2f4604fa3e21096d7da552cae8b97 | Bin 0 -> 1201 bytes .../96ff9ea1b05bc5d0443305fae8ace07732c85359 | Bin 0 -> 2662 bytes .../dff1ba4f2e96e390e03144ef40b06981c1a0cf8d | Bin 0 -> 1850 bytes .../dffd29e0ce2df7e99122dc3e5c7de81d77ffbbb9 | Bin 0 -> 2249 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/1dca0b7f951ad6c7cbb39e0e5fa1327ada85d4a5 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/334176efba3f10cbbb96b23d04ae03240ed31e0a create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/533432db786d023c678187d79db1860ca1c44056 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/6ec181a01600525601900b9fe2b9eacf7d5df43d create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/85bdf4bb93d2f4604fa3e21096d7da552cae8b97 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/96ff9ea1b05bc5d0443305fae8ace07732c85359 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/dff1ba4f2e96e390e03144ef40b06981c1a0cf8d create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/dffd29e0ce2df7e99122dc3e5c7de81d77ffbbb9 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/1dca0b7f951ad6c7cbb39e0e5fa1327ada85d4a5 b/src/tests/fuzzing/corpus/fuzz_pkcs11/1dca0b7f951ad6c7cbb39e0e5fa1327ada85d4a5 new file mode 100644 index 0000000000000000000000000000000000000000..62849a46512547b23b2c799c2cbabf89ad21394b GIT binary patch literal 1235 zcmZQ~6kq@YMnf73JBZC~EWw?7#2wyViT7=*~-J;tbY*g&7zc4gZNY6dzDL5FS~YlA=L0)r7#g3``6VEXt55 z=+DN$Ai%)LP|5Dkx`2U!nPUP27ek$pKR1Yz$Rh@4b3oL^>oYkp5T^#0URDNH7Ul^+ zS7bHeQo_X$Y;7QU<+yLir9%X7tZn=>L5Ih+Jq6i+w_9DZ#gFzZ02k?oO) zt|y%K$EuAMZ#3mFGB7qUFf=f(NW-{P6&?XLfnGE;V|!T;%2DE$e3qI-aRHB|W<{j^%;cE?I#S?3ay1 zpH9oOXIuV2MD?=+vO}3Y7z|vQ6d4|M=`UNV>BnKJ@hwMIHYd!!a~_M-+;smRiFyVM z3x2+o{rp&gNrCyj%pCK5-DlQ@@&?Y2SX18jcPf|cbLHtXi%Z31&C}Zp8Ns0l4#6~F z2*yG~5X=UKV5C9gLud$woou$UKKE+z@iSGj(QT{p?GMeVL3S8sfFOmSiJ_4hBm_;2 zAOUEAB?QY11P~#}s@=%Kpv0WSz_K7DEhmR_i;Z#cvy_Kn`}gYK&AD%}&mbuMpX{`U zesPyh-T%08{n72WtCIF?|NFyPEKgZPav683nLz5+D~EobS$#}LWW|n$T{&UPZ)CBW zCWc*kxaZ%o%l!xIWnz-fUj1*1>cvkQ0LJ9|p5ukib! uX?IhOCC+`c{zpwuon!TiL%*299`08xTA8)T&Ng|%4QS}&%PdU5G!6h~$D&C9 literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/334176efba3f10cbbb96b23d04ae03240ed31e0a b/src/tests/fuzzing/corpus/fuzz_pkcs11/334176efba3f10cbbb96b23d04ae03240ed31e0a new file mode 100644 index 0000000000000000000000000000000000000000..ae1ef65091ce0aaa8352324cea7f72bc347ece48 GIT binary patch literal 2022 zcma)+2{hDu6vu!6#gZXoY|#vc*Dn4ugGnQ6N-0j%RGQMr5?MyFq)E*Puay$LLMdxh z^qvygizFpW(Sk;n)a&(_7o#%Xgjde#dFS18e&>9D=XZbi-v8&`|4-Tq55^6mjGIIs z1j2Y^D8C>1^(+=UW2ueGaEF7{&hFscrKB@xny@HvF~?4%_nO&vPa}_*ZRsjj{-x>l zi#CJVP3w&li(2MaZWzF;j)6ks^hQzt9K1$j31mj94Y$pGwaZ2LOzZkC)Bezt6#Z2x zZVs6a-GGOz9q7OAry=LQu9y*U#Ht5_D##TZHwU|U+k5P_gnh>T03JYKuZ*KqDgcOV9FPMM1V`N04O?FAo0gsMb2Wr5!Tl74?%yL@0J<0B>~ExRz{Yql&tExb+eNWZ$n?rEhgb>Wtyp~J&FDn(pj%m<_ImP7K+#b z%oZktt|Nw-84Da_jpq;fl1RQxi^Jzp%@i+35!(O*sU!U);cFdO2l+rurk5S9zq&zT z-Gxn8LQjk)$dUT=&YTSjRwL29VgjLYisJ-5B?Pxl5**hOf}1g(V3Hv7e&kZdqqk}I z>cdG}qH_W)s*<@=3;Pks6oN(+s>uXFBkBY|>|Y3mVEFF@r55o}po_QxGN*Fm=T#TJ2zM(f92ME9`Rl1@Wa2zb@E$i> zsz&N_YxGsJZwZe0GPBxzq>S0j7D0))ra89q0FmYP@X46*)UQCi0LJ$51@16rF!r&5 zq8n2cqRzP!zuN4)I^j#k`~CI1JI|S@9ZTRRd53lX{*>zHHZM{fC6(Yf3}c!eqnV>4 zNr6Qj59_o}1P)gvw!7D`Q@Zj*++z_|`?9M(!AwCpdG}?XOXkaV#I;SK4;OOy@U;p0 z6B^^gIg$>Xn#3P|3}<_@Jf_2cPudl)P)w;b z8trQbXqbuQ|Cw%v`H=3^ppXdxy)FB7+AqW(eS+)$O)aXZ^-Z*e}z|d^_-CLBd zd)OL3>R4qDt&#b~Zr&*SS&QzX#c60b*D)mhW$aEf!oWq%HRqCI;@hhgjp}%M9{Ttz z$By?Bk1i}rpfCRPTXB@W6R*<7X+s$GczoDb2J#GC>E|KaoEyXh?lxYOmbEua(Sp+8 zzm{v;6P_#_u5k^kPJ4WMZ03IYrH%J(Z5c$ff}!lkOG-wT#N>V$jIe1QARO4vZS)kF zd-mjRIsDYGuKMht%V(CB$CD3ZTytkZ$Oq0G(Jgt?^lE}rLnhkW-z2Z?x3UTTBl7mx zgY=n%Om8jLj`@@T|9Qg!`(U0M@mg=-?Nt>y-BGPD0s&|$B?)>7B?#m{M)wrVRQQX1 z*WSIVEFq(}C(EHld-cKhrB}yrWmIsf&WX17{GBZ#_W;U_RkO0Y?lTxHYwuRaTw<|^ zZ&BKv^Jl$I7+v#JH~V%eKp*G7JG3kmy%#!nd8?rwbs3EXD1ICQE1aBAL(J5g3j|Db zX$U^T-k`jqkJP68B|4>*G|V!LSg@k?q&nH4^73lBY}8wE^O);#4D?7OI i!7OX-MGZ%?tZJ>S>1QsI_0u)cyp5?0O{=JDao}(3V%vBC literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/533432db786d023c678187d79db1860ca1c44056 b/src/tests/fuzzing/corpus/fuzz_pkcs11/533432db786d023c678187d79db1860ca1c44056 new file mode 100644 index 0000000000000000000000000000000000000000..aab4e117cd6256d9fe3653594a4a0a6f4ea449db GIT binary patch literal 1850 zcma)+2T)U46o&76FM*hZHIM)cCK_}>1(ZhuL`15KVgn_D1zQ3U5+g(ySe2T91yL+? zDY7aMqkwHU7LcMMAZ1lxQ9%SOpcKm@0T%C69$qsBP56?aSD_|Qp0{frc0XRNcCecHsZjeCsV1 zU@^!Mr3!)MTP1kFwnBC4URpllnA?7i1Jb%JYXZ_Eeb(yX97s`m3U_VOq7#H&-$+)NTBHxn?hKCNTA6;sRIv7APCgnv#1Myw^IVL5Ak&p zs^^_&+u{sYYQ_ZKFOKKQN;==HAvwm0?@*pu=JFpr>6#nj6g@0Z)*ajZq3s5x+d+b0Ge1JsWWH<@^-hz#E3t+*`~ zQTny7XGMXhAG9S3`_xJG747zcx~Yva*o*L9Ey<|q;yw4b$P!oYLARYx>}oZNsNwz& zR3qNOTN*zt%J;L>`Dp7Fs5+%yi@0RT&ExS6^yIg-&myZ;&qujY?#OyIh4NtLpPQ{b zu?A)_m=RB^dzi%vx!#$YOHn;8>O;Cwwe{6|ijsR>-)-bZuY(Z?Kocn`(JLuIAm27` z`pd;7Oq;^Xi;1U0)Q2c5wVAUi?M+y|^iA9$}BN&7p= zCe$y9`uF85V!UEzB_(8cOd=|_T+BISzNM~K59u-!5v%D`%l4BIOwwW-brCsKu}u)lqID3<{a#9|t~oho zF<#|RIv-rlKdx?H6;e4RHF^`~slhcGsa*8|L-To}udPbXQ;Pn3yNN;(CxAM_dZ6uq zNp{w3XPo)04?-GE=x!UGfzeI(c2RKVq9AjillH!y4%3ldY8vZCOjWL%+Nu+4&;1fR zlz^wboRO3g5U53CdGDJ@aI2Ew#&Lq9v6A3ARNOjF(7hsZzE#buQ+KL%(>(Ud{A^3p zLM96PEhQ$~`Gsf6HK>uSQ1fira1hGb94495^0VZ?xR-tgx4>Dmp7C>G?2RE>XYiqsj)ly pOB0*D$~ft5`HGN(VfMk&(m~k0wMftZjNqh=wdaw>ar&Qj|3Bz2>jZ&Q`vV~H+S?sp47@f+kT~b;(%B^zA zsjzJa9j9}2p>-*@T&7%7k!$I$GO`rThErxbHRqdoXa3L3^FHtY`^|qIgrEkjCzJu; znM|r23N6X$?RzJ=;Zd3t+j)rp%4}zd}uz9 z`XIo32m;M_&0C}2@8^TO<1F>mM$60Yc6j|wDuS?k2#q+mYiB8G98q$DO0juTl zE29YK_(`6VA?asKVO^j+{4)FWNuKq->NiIEf9oj1Fr4 zG3s?sU&<;KSzTs6=zo%8kyEya5Wk3bM>ocIGb&cNy+ZPoy{CtMqYR9?i=)O{lf6#q zy0_;CBz!c;uDp}>cff^}2OebXF<@f_Lo7czCF%(c&8~u&M^9PvSPx%}SeCf2W^@*> z@o`f&zo~_f{_UJgb3S(|`BS=WWKg>1a7`cD%@QgLl*GvbU%|5U)Vyc1@{(P}`Dcs5 z^$mn$VylY*N>|5(CCXFn?S=UTZ?<==G}k9plif2rZOYR}TH;PBE!H`!ni_}g^Ojk6UMosKg~`9YjLQDvOW^gI}v9gILSh$FzHueDX= zDo0B8up=$V&*W=^289jRot<(iFY-yxTdowHQFLgCs9%r~?}O>lyG|z7%Ct~ao}>lZ z;qrS(y2JK!jUvtfb%M1)-!bF7+~qEKvt=JRWHN_l7oUyM$ntlU(2Y=#GxnT3+^+>| zAw!y(7B>YA1s)2U&u;tum&A!w0(o$8`svUxRkDTuk+}r@qy%@&5}ejjf}SX^ca|Wn zE@q{5(~I*p4F}2IaiSo*%FKwl#(qf9)P!O_L(r5mvk%b!SP1)2;#Y!L10DwGAPj)X z+2Y6H$X;1Rb${yHOB0tFcX7HcZ=!DgljO8s7oU6e-S7S=x?S?P&%6f zd|}jRYNXjj=Sbx~HEvb%`c>I#N}qCHM>d3XpD|ZWNabg+_7A*jr|e}cjhQ@*O?4fG zQ4Quq-o#i&@U_Q{^$Qb&M=R61e5>hMeMORpgeZq_VdXeX>lJHtAn@=5ibRk5>ldaZfth-lUP|l|u`n+Q`~zR}d9?rl literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/85bdf4bb93d2f4604fa3e21096d7da552cae8b97 b/src/tests/fuzzing/corpus/fuzz_pkcs11/85bdf4bb93d2f4604fa3e21096d7da552cae8b97 new file mode 100644 index 0000000000000000000000000000000000000000..96da74ea45cc7dffb7c93acf48f68dc6a80a3234 GIT binary patch literal 1201 zcmZSMY)NDQ0Y*bG0J0hwe%1GIx?kw*`1EGhqAMH1Gxa|{U1M~Rm0Q(^w`#fI&0p^{ zHs+b~yBj$zRNY{Ex0T&UEAd(3&btiTe2@L&RzsoN4K4w+Z@!E zl(=3yMOa~_`r`eLE| zz|d&;Pqd-V*8cL7YS$F*ut8qAp&a$$^15HMsP$GO)5RPXM|is|lA9E{0%h1Ia7TEpH{7 z+QZq!bKY8>E1uh&5uwQ8B+#OG!b#xpYZHN42P%zhk3@7m;j}+iZM1l!DTk4Pv4Mf1 zfuSA4KcHJd76A=xV$>>VVpL3IU}A)^4VoBb4H}OuU}j=uViJjp@&3;I>j%@J?mbIR z#@*#9JZSyZfQyYotIgw_EekV~0ly)y0XG|SC<`+WOKEXxk%62zuaS{~3D72UV@qR$ zC?MCwzzAqF7(`)eh%^vpV+WhZ#0WK*nUS5@iGgLhyPaTxaP5!mtXgx~7d$8OpRYKx z%fof4(W~VmFE4LdKTFW@OwB3j*`0AL57c(a3Y=iSY$W=0TAn@I@&_WSpB<1L%Iv{l z;L4=P@Tg0F*-}kE4pWV9IkK`jVfLN#Sfu8r`~OJPGhkTo^QG+P#|lge%xKqspQny|?^z+Q>V>%)$c0BCL30r<6i`6tS?8?JE|BhYmKUgmllXUj# ze^X>%FsCyZBxdC>q%axi{r`I2P^tY;nRvnB$zC?|#D)GWeOr5`=>9A-v7V_-vokB6 zyt!tSo21_Sua$MG|92(>snoyA{{Ea@xbxoGQ*wQU-w#c@n{q61?xXcTYI^D%t5+QQ m#T52%zhcqKtVMRV$rElsLmyveVFIRcTp5XpArqMOGn)V$?1Xp# literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/96ff9ea1b05bc5d0443305fae8ace07732c85359 b/src/tests/fuzzing/corpus/fuzz_pkcs11/96ff9ea1b05bc5d0443305fae8ace07732c85359 new file mode 100644 index 0000000000000000000000000000000000000000..7fa6b5c893b88f5a8a3909e2c751662edb3624b6 GIT binary patch literal 2662 zcmb7G2{@G78$aJSma#Q7_EMIycFQ-$Hrcnbq;7^wDm9AiiO3dalt?5}%(X?bB}$E` zkh0`Twh9%gtaG`ODdU>xQvLgT{!gCU|2)t8Jn#FRbKdVg@9+2g&H)hq%K&%{f~J-> zkN|q~SO6&a1+nPBdbxVXT|us%Hg2KDFz}-O*L(pCzM2>yi|pV5Ko~$Ely?VrE&wQW zGT;Z1t9J-21!O_-?>_qLx_#=fG5EPPEA8b5++3*S#VWk0D=py%Bt1l`XO!4a)-w9; z2WCzZ+XJ&=Je=gvrot!WT1Ff@fPVyT~1UHT&Y_rEX^Eb4LALTexd1i>SCL$L6r zRuUDe@ux!9$pD7_<0Dk4Y|+GXQ7{C1N& z8Os)eAOUWGVDTadh6m-qg%U&udyxHtd_298brM1vOE4gKJVBR0bY2XXV&v;^{_!SC z&hp$4H$YJm0YZs~DHPCj7ACQf)E8KmN!np`H{GU&{hXTCY8=ggRogpQP-2K>+}!fY zxVU8@W_z6P16tUoNk=l8Z=^uCpGg#zHg>qa`$|u5%9%2`7C|^yjTx(b!zn|TQ-5W1 z+yimHljPcZU?3Wlkf*_feCr#u4#*XR(IS(LXco9G+&c?VLxxvq5R8HVw7kT{b<{%R_ShY$iStMR1GrAn;Jn9e zeY$tVj(;YT&!FB*RxRdrdR1VO$HgjkJJ;dpQH!SDyS;4Q^S2m}1L_*bbf#54z3pk| zJ3i|dJ}1?YG~Ma^%H!6EZ;fx?o^!JnGS$wAr{*uC?f3AmqX|-Z9s?8hBl$mM)lzeU zch``W!q@+eQa2n3&}3a)rRt`}pD1$sv%lY(yYAD%eA+}=TFQxQ9^uLh51EX*El%lf zb4BOVt>5o1?VmeL3@ar+Xaqy#ZN)0%8?D1iGS)Z!^#O6duW^aIe`4^Ehv}^tPdxPA zRJ4m=Uh6;)d;Dm8i)nAX1*+MyQ=_fG`R&?(bkA{Di7t4drLHM&m2=F-k9e6*t*Aoz z)w<*iFGt5}+nvSr${(I)MCj!RyzU<0gybZg9Jt3*+4t$SUd7R}x@@%Ee6^$D#V452 zE0q6-+L5YIKj8{G>=5KzC!Pmzs%kfSVg62_m1km(xIx54`JaZDi_2eThrCxjCe_3dml_$(eF5~ z`@oiBtv`hPXOo}!PU&jG~)|-$w)Cnt@yZ0`>ObKEn-NZ;n=S->Y;&A9psrY7G>E@HU z1A=o-C3PVwm6g6eE+5mBjV9vr*ovsCisvHc$I4!I&!m#hDz8ZGP$QN){ct#ZR{zax zp4huH?RjU;DdOfEtZSpL+45emAM6lRif&Skt#+{Nq0DcvvfjWE?~>zHslcW*5Y?xw zxowuHEiWBVTw^APb}sb3(BJ)5GpoaUlZ%LQXEVK+f^5uqIW~arJGDwoNm9s$VBmyZ zQ~b2W47d`aG?Mg(f)C6+SLkT$=)Rp%u(p?jUi<0ZzzmN=00S z*4R7#(wI2jSFTEz6XIWLE?5=z)YTUKdRhFGs*(E4q4RoKc7}(#YL4W$-b{c)7s^Qv z?Bmw_4z;ALhFj?hRacYmHMDjGyW7Zz^+PedeXRYdyE{o8ZH+VdWz>c={Hc)Yw|n@D zzo?Lk2&L_tXcJ~jD0b7^EqiT@%9(}{lkf8{6(RgQ=*4Te-GB=P|EpqaB0sCxyAUi7 z@0YwV^z8>Ih!t{}1S!bqO zO4il|x!QEhtSdc7{dT6AM-wauu7wDbwrzFD(3xVU)`o2ks_6}E+@vl28mE7GY_I#B blixbI(z6K$2Og|Emkd^#Tj@Kz_)4J)v`db>-=Ke+x9Rzp~uHj1flyHbzpJUuu-9}T`9{j(WZ@t9= zECxBKR3VUjs{{|&)~HV7GpqX?3%k#8Q08l^`k<^RzcqR|M^dz2l_TleD|6DVcjDX@ zuQ@*s8gKGil|z$R;20s-=I-SjRXare;^M{EjwChH)7~~bj;d2V6YWm9DeKh~%0rlcZnXBs z8komoM!cyW;g-wgdME48NB6j@59vlXG}Y}cP3v`gx1Jlb7DgZdO{AnmucQQlBD=!r z&lZ(4ZA&gJBAy6UAEK<#X3nN`wPN|wH;M7cwZ==Exi$Lfr?QG=R%dwkx}GGla!RJ* zW2T93=|}mjL`&6f%uzfQY+A zMgnYXFMl&ZgLz1o+Ex(t;3@wH{{5GIbLH#>+}3joH@J~4uhMZ5zaDdG$QR9|{hewX z7LZDPf3p*9=S#`48l{P`KC!b>lk=WWA}ThW%RgEaVrV2CD78B2r*UyWDkqOLHy7p? z^sH-{XK6^Oq_HzwZOT&nW7?}~Sdn<tq zmWB*P5=d{%(qpmGMl@7>ecaKW>z4K-g9^AJw)jN#hBo51a_c@6uYyxLy50tZz+by_ zqMfan=%}4h#&_(z7A32wj`oA0@x}LOcp5jjk;MG(fKJttNLJd@U5c6Q2T zyv(P(xO<`Kh`K{lt5^V%Z|u&c-n zoha3x$&|%xAKn`gC}dmYB8) z+vi?I-F$~>DIG2w?$oruJzI1`{$LlkSU#j!pyfY8sJ+}+IB%AFZCyc?VB+7F|;yrI0IfsAdJ9@f=NP1x37 pk<#W<$;s+0QiR5ZJA_Cp24RnmQoX>Ff@8Ke-UnO8>3`b&{{Zudsv!UX literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/dffd29e0ce2df7e99122dc3e5c7de81d77ffbbb9 b/src/tests/fuzzing/corpus/fuzz_pkcs11/dffd29e0ce2df7e99122dc3e5c7de81d77ffbbb9 new file mode 100644 index 0000000000000000000000000000000000000000..d80c8c1545bde7722e1a515f28ec5e5549eb61bf GIT binary patch literal 2249 zcma*n3p7-D90&0Ky?16zGqi(2WH#EgqPS)lNes1xwIxL9p$3DQ27{xmB{f4zBPk(y ztW6%xu1Aku?XEn_E03eWYL`5+skTyCF;mzH*E(l+JA2Q$=lnkB{_p?(?)Uu8ACYST z>q&J0gl1D3$HJ@ht9E!r_;8&$hwWg%6a9S$0T|5Q8i1|pLI8jQAaGd81)l=|LQDcA z5Uu7yeh;>?=6p?@UANB^wgdlf&40a%2Y4Kkr09Yt`mZG<;BJj-cMMzo%C=z5*WsDZ zty;sgVgh&S6E{#|^&2)&YX2~&+)yR)iG20`-P?0$5(^?7WuT}TYGw4Rq`QI7Fb!cD8GU*L)xgO%YwveVBAtq<0{Ffo$v-#WOuu*qhbe;Ct)7=EY%9q7k?g$0cajl>8VnP2KEzyL1#-h%~hxQRV8Ql`t zk36c9X54eF-SZXV5C#l=C7^|ocd+^-C zm&vD*+KwOneVPo?zs)L_Se0__Km7f?WzMZ-r1)jRy9P0Su4tvooi!7WcnA8~Ki>l5 z?v>HSDFZWU-&vFfAqj z@gn7k{nrY%s8X;4~(-Hs!mXv*$;;1 zHbx*NWCOsZIoPTS)Q?OY;2p7~JyvcA87^%8$#GL2{b>R9iS$OvMOFLesHUYE@!q)p zl|Rua4N6kF#_y@YEJ8s))nL?aVWWs6KsUkqVDOY_e%`9BL<_?=d>W1K$%@a$>0|}C zOt4K*kRy9S8-1t;>meh$nU)pe<{}Rj*ROYe_hsT_3W+xSNm_b%geJ{0;KafN{S^uB zol9`0RwU?!3J2yA^lXe-XWjZVx4!u++U__>2&*PDYGGp^Owinn&YVrqoIZOVp#O3p z97HL9Cx|x|;=ppm2jFtH`}6sWZmegxKk^&!th{B~%kNuTfw~1u(NYJtdf#j6dv&$s zPT6l?`IMJUPHfZ+{)DQXPv$TwobNkoWX<2!t)>><95}`IEa>LpE!dtN1Lae7(lgaZ zb@%wRbWU3={0k%ipllu=_`#^j^jMqO@)I=&wFI@vpRdo>QhS&8{77?H-$kZoLW(GZ zduZrc7d^=5)0nB__!O6M7}eoS=1YhvgLudbD5JeIaO->wta#PA&k_2YG{cdnp;yUF-rYewqLO+pI&wb@9T!sH7m?P32#pp zELO6?ygAW8vUI)gJIt-lPPv>l=3ban9Yh2#a{pt@W7DZa&WKYZ<`lW~=DlUnGR$6v z% Date: Tue, 10 May 2022 09:26:55 +0200 Subject: [PATCH 2435/4321] fuzz_pkcs11: Fix extraction ordering --- src/tests/fuzzing/fuzz_pkcs11.c | 73 ++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index 5a3ff08bc8..ddf3f94585 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -389,7 +389,7 @@ static int fuzz_find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, static void test_sign(const uint8_t *data, size_t size) { CK_SESSION_HANDLE session; - uint8_t login_type = CKU_USER; + uint8_t login_type = CKU_USER; char *pin = NULL; const unsigned char *opt_id; size_t opt_id_len = 0; @@ -405,7 +405,7 @@ static void test_sign(const uint8_t *data, size_t size) /* Process options*/ if (set_mechanism(&data, &size, &mech) || size < 3) return; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) return; @@ -457,7 +457,7 @@ static void test_verify(const uint8_t *data, size_t size) { CK_SESSION_HANDLE session; CK_MECHANISM mech = {0, NULL_PTR, 0}; - uint8_t login_type = CKU_USER; + uint8_t login_type = CKU_USER; char *pin = NULL; const unsigned char *opt_id = NULL; size_t opt_id_len = 0; @@ -471,7 +471,7 @@ static void test_verify(const uint8_t *data, size_t size) /* Process options*/ if (set_mechanism(&data, &size, &mech) || size < 3) return; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) return; @@ -527,7 +527,7 @@ static void test_verify(const uint8_t *data, size_t size) static void test_decrypt(const uint8_t *data, size_t size) { CK_SESSION_HANDLE session; - uint8_t login_type = CKU_USER; + uint8_t login_type = CKU_USER; char *pin = NULL; const unsigned char *opt_id; size_t opt_id_len = 0; @@ -541,7 +541,7 @@ static void test_decrypt(const uint8_t *data, size_t size) /* Process options*/ if (set_mechanism(&data, &size, &mech) || size < 3) return; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) return; @@ -594,7 +594,7 @@ static void test_wrap(const uint8_t *data, size_t size) /* Set options */ if (set_mechanism(&data, &size, &mech) || size < 3) return; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) return; @@ -745,7 +745,7 @@ static void test_unwrap(const uint8_t *data, size_t size) /* Set options */ if (set_mechanism(&data, &size, &mech) || size < 3) goto end; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) goto end; @@ -796,7 +796,7 @@ static void test_derive(const uint8_t *data, size_t size) /* Set options */ if (set_mechanism(&data, &size, &mech) || size < 3) goto end; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) goto end; @@ -838,7 +838,7 @@ static void test_genkeypair(const uint8_t *data, size_t size) /* Process options*/ if (set_mechanism(&data, &size, &mech) || size < 3) goto end; - login_type = data[0]; + login_type = data[0]; data++; size--; if (!(pin = extract_word(&data, &size))) goto end; @@ -899,8 +899,10 @@ static void test_store_data(const uint8_t *data, size_t size) /* Fill attributes to data template */ if (size < 4) goto end; - FILL_ATTR(data_templ[n_data_attr++], CKA_CLASS, &class, sizeof(class)); - FILL_ATTR(data_templ[n_data_attr++], CKA_VALUE, &contents, contents_len); + FILL_ATTR(data_templ[n_data_attr], CKA_CLASS, &class, sizeof(class)); + n_data_attr++; + FILL_ATTR(data_templ[n_data_attr], CKA_VALUE, &contents, contents_len); + n_data_attr++; fill_bool_attr(&data_templ, &n_data_attr, CKA_TOKEN, *data % 2); data++; size--; fill_bool_attr(&data_templ, &n_data_attr, CKA_PRIVATE, *data % 2); @@ -913,7 +915,8 @@ static void test_store_data(const uint8_t *data, size_t size) if ((app_id_len = get_buffer(&ptr, size, &data, &size, 256)) == 0) goto end; memcpy(app_id, ptr, app_id_len); - FILL_ATTR(data_templ[n_data_attr++], CKA_OBJECT_ID, app_id, app_id_len); + FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID, app_id, app_id_len); + n_data_attr++; } /* Initialize */ @@ -963,9 +966,12 @@ static void test_store_cert(const uint8_t *data, size_t size) /* Fill attributes to certificate template */ if (size < 4) goto end; - FILL_ATTR(cert_templ[n_cert_attr++], CKA_CLASS, &class, sizeof(class)); - FILL_ATTR(cert_templ[n_cert_attr++], CKA_VALUE, contents, contents_len); - FILL_ATTR(cert_templ[n_cert_attr++], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); + FILL_ATTR(cert_templ[n_cert_attr], CKA_CLASS, &class, sizeof(class)); + n_cert_attr++; + FILL_ATTR(cert_templ[n_cert_attr], CKA_VALUE, contents, contents_len); + n_cert_attr++; + FILL_ATTR(cert_templ[n_cert_attr], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); + n_cert_attr++; fill_bool_attr(&cert_templ, &n_cert_attr, CKA_TOKEN, *data % 2); data++; size--; fill_bool_attr(&cert_templ, &n_cert_attr, CKA_PRIVATE, *data % 2); @@ -986,24 +992,27 @@ static void test_store_cert(const uint8_t *data, size_t size) static void test_store_key(const uint8_t *data, size_t size) { - CK_SESSION_HANDLE session; - CK_OBJECT_CLASS class = CKO_SECRET_KEY; - uint8_t login_type = CKU_USER; - unsigned char contents[5000]; - int contents_len = 0; - const uint8_t *ptr = NULL; - CK_ATTRIBUTE *key_template = NULL; - int n_key_attr = 0; - char *pin = NULL; - CK_OBJECT_HANDLE key_obj; + CK_SESSION_HANDLE session; + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + uint8_t login_type = CKU_USER; + unsigned char contents[5000]; + int contents_len = 0; + const uint8_t *ptr = NULL; + CK_ATTRIBUTE *key_template = NULL; + int n_key_attr = 0; + char *pin = NULL; + CK_OBJECT_HANDLE key_obj; + + memset(contents, 0, sizeof(contents)); + if (size < 3) + return; + class = *data; + data++; size--; /* Get PIN */ if (!(pin = extract_word(&data, &size))) goto end; - /* Extract content from fuzzing input */ - memset(contents, 0, sizeof(contents)); - if (fill_key_template(&key_template, &n_key_attr, &data, &size, &class, true) != 0) goto end; @@ -1015,11 +1024,9 @@ static void test_store_key(const uint8_t *data, size_t size) if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0) goto end; memcpy(contents, ptr, contents_len); - FILL_ATTR(key_template[n_key_attr++], CKA_VALUE, contents, contents_len); + FILL_ATTR(key_template[n_key_attr], CKA_VALUE, contents, contents_len); + n_key_attr++; } - class = *data; - data++; size--; - /* Initialize */ if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) From 28996dc6c920ab39a242c58e0b652309d8bf3bec Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 11 May 2022 17:00:56 +0200 Subject: [PATCH 2436/4321] fuzz_pkcs11: Moe CFLAGS --- src/tests/fuzzing/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 0e719c611f..2df7905f73 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -51,7 +51,8 @@ fuzz_pkcs15_crypt_SOURCES = fuzz_pkcs15_crypt.c fuzzer_reader.c fuzzer_tool.c $( ../../tools/util.c fuzz_pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) fuzz_pkcs11_SOURCES = fuzz_pkcs11.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) +fuzz_pkcs11_CFLAGS = $(PTHREAD_CFLAGS) fuzz_pkcs11_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ - $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_CFLAGS) \ + $(OPTIONAL_OPENSSL_LIBS) \ $(top_builddir)/src/pkcs11/libopensc-pkcs11.la From e8fb2db93442d02eb3e5df28e1c7de1432aa7a85 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 11 May 2022 17:01:12 +0200 Subject: [PATCH 2437/4321] fuzz_pkcs11: Expand macro --- src/tests/fuzzing/fuzz_pkcs11.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index ddf3f94585..2b46223c90 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -622,7 +622,12 @@ static void test_wrap(const uint8_t *data, size_t size) free(pin); } -#define FILL_ATTR(attr, typ, val, len) {(attr).type=(typ); (attr).pValue=(val); (attr).ulValueLen=len;} +#define FILL_ATTR(attr, typ, val, len) do { \ + (attr).type=(typ); \ + (attr).pValue=(val); \ + (attr).ulValueLen=len; \ +} while(0) + void fill_bool_attr(CK_ATTRIBUTE **keyTemplate, int *n_attr, int type, int value) { if (value) { From 46708b78554147d1a57b9112eae145053e85602a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 10:27:16 +0200 Subject: [PATCH 2438/4321] Simplify condition in makefile --- src/tests/fuzzing/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 2df7905f73..c9ddaf4a64 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -19,8 +19,7 @@ if ENABLE_OPENSSL noinst_PROGRAMS += fuzz_piv_tool endif -if ENABLE_SHARED -else +if !ENABLE_SHARED noinst_PROGRAMS += fuzz_pkcs11 endif From c4371fac9e5b5a5505d9f9f2ca6f8cc7a5d61a24 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 18 May 2022 09:41:42 +0200 Subject: [PATCH 2439/4321] fuzz: Add missing CFLAGS to unbreak OSX build --- src/tests/fuzzing/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index c9ddaf4a64..6b53b6343e 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -50,7 +50,7 @@ fuzz_pkcs15_crypt_SOURCES = fuzz_pkcs15_crypt.c fuzzer_reader.c fuzzer_tool.c $( ../../tools/util.c fuzz_pkcs15_crypt_LDADD = $(OPTIONAL_OPENSSL_LIBS) fuzz_pkcs11_SOURCES = fuzz_pkcs11.c fuzzer_reader.c fuzzer_tool.c $(ADDITIONAL_SRC) -fuzz_pkcs11_CFLAGS = $(PTHREAD_CFLAGS) +fuzz_pkcs11_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) fuzz_pkcs11_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ $(OPTIONAL_OPENSSL_LIBS) \ From 622e6e2469c67b4fdbbf7c9268bf865e77e61f85 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Mon, 25 Apr 2022 13:36:47 +0800 Subject: [PATCH 2440/4321] Support feitian fips mode of epass2003. Support feitian fips mode of epass2003. --- src/libopensc/card-epass2003.c | 406 +++++++++++++++++++++++++++++---- 1 file changed, 361 insertions(+), 45 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 47a1c1006a..ac4131d5a0 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -41,6 +41,7 @@ #include #include +#include #include "internal.h" #include "asn1.h" @@ -98,6 +99,7 @@ typedef struct epass2003_exdata_st { unsigned char sk_enc[16]; /* encrypt session key */ unsigned char sk_mac[16]; /* mac session key */ unsigned char icv_mac[16]; /* instruction counter vector(for sm) */ + unsigned char bFipsCertification; /* fips mode Alg */ unsigned char currAlg; /* current Alg */ unsigned int ecAlgFlags; /* Ec Alg mechanism type*/ } epass2003_exdata; @@ -322,6 +324,101 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned return r; } +static int +aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, + const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) +{ + unsigned char data1[32] = {0}; + unsigned char data2[32] = {0}; + unsigned char k1Bin[32] = {0}; + unsigned char k2Bin[32] = {0}; + + unsigned char check = 0; + BIGNUM *enc1,*lenc1; + BIGNUM *enc2,*lenc2; + + // k1 + int offset = 0; + int r = SC_ERROR_INTERNAL; + unsigned char out[32] = {0}; + unsigned char iv0[EVP_MAX_IV_LENGTH] = {0}; + r = openssl_enc(EVP_aes_128_ecb(), key, iv0, data1, 16, out); + if( r != SC_SUCCESS) + return r; + + check = out[0]; + + enc1 = BN_new(); + lenc1 = BN_new(); + BN_bin2bn(out,16,enc1); + BN_lshift1(lenc1,enc1); + BN_bn2bin(lenc1,k1Bin); + if(check > 0x80){ + offset = 1; + k1Bin[15+offset] ^= 0x87; + } + BN_free(enc1); + BN_free(lenc1); + + // k2 + enc2 = BN_new(); + lenc2 = BN_new(); + check = k1Bin[offset]; + BN_bin2bn(&k1Bin[offset],16,enc2); + + offset = 0; + BN_lshift1(lenc2,enc2); + BN_bn2bin(lenc2,k2Bin); + if(check > 0x80){ + offset = 1; + k2Bin[15+offset] ^= 0x87; + } + BN_free(enc2); + BN_free(lenc2); + //padding + if(length < 16){ + memcpy(&data2[0],input,length); + data2[length] = 0x80; + } + + //k2 xor padded data + for (int i=0;i<16;i++){ + data2[i]=data2[i]^k2Bin[offset + i]; + } + return openssl_enc(EVP_aes_128_cbc(), key, iv, data2, 16, output); +} + +static int +aes128_encrypt_cmac(const unsigned char *key, int keysize, + const unsigned char *input, size_t length, unsigned char *output) +{ + size_t mactlen = 0; + CMAC_CTX *ctx = CMAC_CTX_new(); + if(ctx == NULL) + { + return SC_ERROR_INTERNAL; + } + + if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) + { + CMAC_CTX_free(ctx); + return SC_ERROR_INTERNAL; + } + + if(!CMAC_Update(ctx, input, length)) + { + CMAC_CTX_free(ctx); + return SC_ERROR_INTERNAL; + } + + if(!CMAC_Final(ctx, output, &mactlen)) + { + CMAC_CTX_free(ctx); + return SC_ERROR_INTERNAL; + } + CMAC_CTX_free(ctx); + return SC_SUCCESS; +} static int aes128_encrypt_ecb(const unsigned char *key, int keysize, @@ -473,6 +570,7 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma struct sc_apdu apdu; unsigned char data[256] = { 0 }; unsigned char tmp_sm; + unsigned char isFips; unsigned long blocksize = 0; unsigned char cryptogram[256] = { 0 }; /* host cryptogram */ unsigned char iv[16] = { 0 }; @@ -482,6 +580,7 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma return SC_ERROR_INVALID_ARGUMENTS; exdata = (epass2003_exdata *)card->drv_data; + isFips = exdata->bFipsCertification; LOG_FUNC_CALLED(card->ctx); @@ -489,7 +588,11 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma apdu.cla = 0x80; apdu.lc = apdu.datalen = sizeof(g_random); apdu.data = g_random; /* host random */ - apdu.le = apdu.resplen = 28; + if(isFips) + apdu.le = apdu.resplen = 29; + else + apdu.le = apdu.resplen = 28; + apdu.resp = result; /* card random is result[12~19] */ tmp_sm = exdata->sm; @@ -502,37 +605,78 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma LOG_TEST_RET(card->ctx, r, "gen_init_key failed"); /* Step 1 - Generate Derivation data */ - memcpy(data, &result[16], 4); - memcpy(&data[4], g_random, 4); - memcpy(&data[8], &result[12], 4); - memcpy(&data[12], &g_random[4], 4); + if(isFips){ + memset(data,0x00,15); + memset(&data[11], 0x04, 1); + memset(&data[14], 0x80, 1); + memset(&data[15], 0x01, 1); + memcpy(&data[16], g_random, 8); + memcpy(&data[24], &result[12+1], 8); + } + else{ + memcpy(data, &result[16], 4); + memcpy(&data[4], g_random, 4); + memcpy(&data[8], &result[12], 4); + memcpy(&data[12], &g_random[4], 4); + } /* Step 2,3 - Create S-ENC/S-MAC Session Key */ if (KEY_TYPE_AES == key_type) { - aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); - aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + if(isFips){ + r = aes128_encrypt_cmac(key_enc, 128, data, 32, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); + memset(&data[11], 0x06, 1); + r = aes128_encrypt_cmac(key_mac, 128, data, 32, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); + }else{ + r = aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc failed"); + r = aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac failed"); + } } else { - des3_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); - des3_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + r = des3_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); + r = des3_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); } - memcpy(data, g_random, 8); - memcpy(&data[8], &result[12], 8); - data[16] = 0x80; - blocksize = (key_type == KEY_TYPE_AES ? 16 : 8); - memset(&data[17], 0x00, blocksize - 1); + if(isFips){ + memset(&data[11], 0x00, 1); + memset(&data[14], 0x40, 1); + } + else{ + memcpy(data, g_random, 8); + memcpy(&data[8], &result[12], 8); + data[16] = 0x80; + blocksize = (key_type == KEY_TYPE_AES ? 16 : 8); + memset(&data[17], 0x00, blocksize - 1); + } /* calculate host cryptogram */ if (KEY_TYPE_AES == key_type) - aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + { + if(isFips){ + r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); + } + else{ + r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + } + } else - des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); - /* verify card cryptogram */ - if (0 != memcmp(&cryptogram[16], &result[20], 8)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); + LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); + /* verify card cryptogram */ + if(isFips){ + if (0 != memcmp(&cryptogram[0], &result[20+1], 8)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); + }else{ + if (0 != memcmp(&cryptogram[16], &result[20], 8)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); + } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -549,49 +693,86 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ unsigned char mac[256] = { 0 }; unsigned long i; unsigned char tmp_sm; + unsigned char isFips; epass2003_exdata *exdata = NULL; if (!card->drv_data) return SC_ERROR_INVALID_ARGUMENTS; exdata = (epass2003_exdata *)card->drv_data; + isFips = exdata->bFipsCertification; LOG_FUNC_CALLED(card->ctx); - - memcpy(data, ran_key, 8); - memcpy(&data[8], g_random, 8); - data[16] = 0x80; - memset(&data[17], 0x00, blocksize - 1); - memset(iv, 0, 16); + + if(isFips) + { + memset(data,0x00,15); + memset(&data[11], 0x01, 1); + memset(&data[14], 0x40, 1); + memset(&data[15], 0x01, 1); + memcpy(&data[16], g_random, 8); + memcpy(&data[24], ran_key, 8); + } + else + { + memcpy(data, ran_key, 8); + memcpy(&data[8], g_random, 8); + data[16] = 0x80; + memset(&data[17], 0x00, blocksize - 1); + memset(iv, 0, 16); + } /* calculate host cryptogram */ if (KEY_TYPE_AES == key_type) { - aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, - cryptogram); + if(isFips){ + r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); + } + else{ + r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); + } } else { - des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, - cryptogram); + r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); } + LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); + memset(data, 0, sizeof(data)); - memcpy(data, "\x84\x82\x03\x00\x10", 5); - memcpy(&data[5], &cryptogram[16], 8); - memcpy(&data[13], "\x80\x00\x00", 3); + if(isFips){ + memcpy(data, "\x84\x82\x03\x00\x10", 5); + memcpy(&data[5], &cryptogram[0], 8); + } + else{ + memcpy(data, "\x84\x82\x03\x00\x10", 5); + memcpy(&data[5], &cryptogram[16], 8); + memcpy(&data[13], "\x80\x00\x00", 3); + } /* calculate mac icv */ memset(iv, 0x00, 16); if (KEY_TYPE_AES == key_type) { - aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); + if(isFips){ + r = aes128_encrypt_cmac(exdata->sk_mac, 128, data, 13, mac); + } + else{ + r = aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); + } i = 0; } else { - des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); + r = des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); i = 8; } + + LOG_TEST_RET(card->ctx, r, "calculate mac icv failed"); /* save mac icv */ memset(exdata->icv_mac, 0x00, 16); memcpy(exdata->icv_mac, &mac[i], 8); /* verify host cryptogram */ - memcpy(data, &cryptogram[16], 8); + if(isFips){ + memcpy(data, &cryptogram[0], 8); + } + else{ + memcpy(data, &cryptogram[16], 8); + } memcpy(&data[8], &mac[i], 8); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x03, 0x00); apdu.cla = 0x84; @@ -628,7 +809,12 @@ mutual_auth(struct sc_card *card, unsigned char *key_enc, r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype); LOG_TEST_RET(ctx, r, "gen_init_key failed"); - memcpy(ran_key, &result[12], 8); + if(exdata->bFipsCertification){ + memcpy(ran_key, &result[12+1], 8); + } + else{ + memcpy(ran_key, &result[12], 8); + } r = verify_init_key(card, ran_key, exdata->smtype); LOG_TEST_RET(ctx, r, "verify_init_key failed"); @@ -748,6 +934,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv unsigned char mac[4096] = { 0 }; size_t mac_len; unsigned char icv[16] = { 0 }; + int r ; int i = (KEY_TYPE_AES == key_type ? 15 : 7); epass2003_exdata *exdata = NULL; @@ -788,22 +975,121 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv memset(icv, 0, sizeof(icv)); memcpy(icv, exdata->icv_mac, 16); if (KEY_TYPE_AES == key_type) { - aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); - memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + if(exdata->bFipsCertification) + { + for (int i=0;i<16;i++) + { + apdu_buf[i]=apdu_buf[i]^icv[i]; + } + r = aes128_encrypt_cmac(exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); + memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); + for (int j=0;j<4;j++) + { + apdu_buf[j]=apdu_buf[j]^icv[j]; + } + } + else{ + r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + } } else { unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; unsigned char tmp[8] = { 0 }; - des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); - des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed"); + r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); memset(iv, 0x00, sizeof iv); - des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed"); } *mac_tlv_len = 2 + 8; return 0; } +/* MAC(TLV case 1) */ +static int +construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len, + unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) +{ + int r; + size_t block_size = 4; + unsigned char mac[4096] = { 0 }; + size_t mac_len; + int i = (KEY_TYPE_AES == key_type ? 15 : 7); + unsigned char icv[16] = { 0 }; + + epass2003_exdata *exdata = NULL; + + if (!card->drv_data) + return SC_ERROR_INVALID_ARGUMENTS; + + exdata = (epass2003_exdata *)card->drv_data; + + if (0 == data_tlv_len && 0 == le_tlv_len) { + mac_len = block_size; + } + else { + /* padding */ + *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80; + if ((data_tlv_len + le_tlv_len + 1) % block_size) + { + mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +1) * block_size + block_size; + } + else + { + mac_len = data_tlv_len + le_tlv_len + 1 + block_size; + } + + } + /* increase icv */ + for (; i >= 0; i--) { + if (exdata->icv_mac[i] == 0xff) { + exdata->icv_mac[i] = 0; + } + else { + exdata->icv_mac[i]++; + break; + } + } + + /* calculate MAC */ + memset(icv, 0, sizeof(icv)); + memcpy(icv, exdata->icv_mac, 16); + if (KEY_TYPE_AES == key_type) { + if(exdata->bFipsCertification) + { + r = aes128_encrypt_cmac_ft(exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); + memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); + } + else + { + r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + } + } + else + { + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char tmp[8] = { 0 }; + r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); + r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); + memset(iv, 0x00, sizeof iv); + r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); + } + + *mac_tlv_len = 2 + 8; + return 0; +} /* According to GlobalPlatform Card Specification's SCP01 * encode APDU from @@ -842,7 +1128,17 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, apdu_buf[3] = (unsigned char)plain->p2; /* plain_le = plain->le; */ /* padding */ - apdu_buf[4] = 0x80; + if(exdata->bFipsCertification){ + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + apdu_buf[4] = 0x00; + } + else{ + apdu_buf[4] = 0x80; + } + } + else{ + apdu_buf[4] = 0x80; + } memset(&apdu_buf[5], 0x00, block_size - 5); /* Data -> Data' */ @@ -854,9 +1150,21 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv, &le_tlv_len, exdata->smtype)) return -1; - - if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; + + if(exdata->bFipsCertification){ + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + else{ + if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + } + else{ + if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } memset(apdu_buf + 4, 0, *apdu_buf_len - 4); sm->lc = sm->datalen = data_tlv_len + le_tlv_len + mac_tlv_len; @@ -1230,6 +1538,14 @@ epass2003_init(struct sc_card *card) return SC_ERROR_INVALID_CARD; } + if(memcmp(&data[32],"\x87\x01\x01" , 3)==0 && memcmp(&data[0],"\x80\x01\x01", 3)==0){ + exdata->bFipsCertification = 0x01; + } + else{ + exdata->bFipsCertification = 0x00; + } + + if (0x01 == data[2]) exdata->smtype = KEY_TYPE_AES; else From 9f99a31ab580bad1ca1e67db3ee4f9830e830f48 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Mon, 25 Apr 2022 13:47:30 +0800 Subject: [PATCH 2441/4321] Update card-epass2003.c --- src/libopensc/card-epass2003.c | 107 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index ac4131d5a0..1c6a43d8ab 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -606,14 +606,14 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 1 - Generate Derivation data */ if(isFips){ - memset(data,0x00,15); - memset(&data[11], 0x04, 1); - memset(&data[14], 0x80, 1); - memset(&data[15], 0x01, 1); - memcpy(&data[16], g_random, 8); - memcpy(&data[24], &result[12+1], 8); - } - else{ + memset(data,0x00,15); + memset(&data[11], 0x04, 1); + memset(&data[14], 0x80, 1); + memset(&data[15], 0x01, 1); + memcpy(&data[16], g_random, 8); + memcpy(&data[24], &result[12+1], 8); + } + else{ memcpy(data, &result[16], 4); memcpy(&data[4], g_random, 4); memcpy(&data[8], &result[12], 4); @@ -623,12 +623,12 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 2,3 - Create S-ENC/S-MAC Session Key */ if (KEY_TYPE_AES == key_type) { if(isFips){ - r = aes128_encrypt_cmac(key_enc, 128, data, 32, exdata->sk_enc); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); - memset(&data[11], 0x06, 1); - r = aes128_encrypt_cmac(key_mac, 128, data, 32, exdata->sk_mac); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); - }else{ + r = aes128_encrypt_cmac(key_enc, 128, data, 32, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); + memset(&data[11], 0x06, 1); + r = aes128_encrypt_cmac(key_mac, 128, data, 32, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); + }else{ r = aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc failed"); r = aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); @@ -706,14 +706,12 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ if(isFips) { memset(data,0x00,15); - memset(&data[11], 0x01, 1); - memset(&data[14], 0x40, 1); - memset(&data[15], 0x01, 1); - memcpy(&data[16], g_random, 8); - memcpy(&data[24], ran_key, 8); - } - else - { + memset(&data[11], 0x01, 1); + memset(&data[14], 0x40, 1); + memset(&data[15], 0x01, 1); + memcpy(&data[16], g_random, 8); + memcpy(&data[24], ran_key, 8); + }else{ memcpy(data, ran_key, 8); memcpy(&data[8], g_random, 8); data[16] = 0x80; @@ -738,9 +736,8 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ memset(data, 0, sizeof(data)); if(isFips){ memcpy(data, "\x84\x82\x03\x00\x10", 5); - memcpy(&data[5], &cryptogram[0], 8); - } - else{ + memcpy(&data[5], &cryptogram[0], 8); + }else{ memcpy(data, "\x84\x82\x03\x00\x10", 5); memcpy(&data[5], &cryptogram[16], 8); memcpy(&data[13], "\x80\x00\x00", 3); @@ -976,19 +973,19 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv memcpy(icv, exdata->icv_mac, 16); if (KEY_TYPE_AES == key_type) { if(exdata->bFipsCertification) - { - for (int i=0;i<16;i++) - { - apdu_buf[i]=apdu_buf[i]^icv[i]; - } - r = aes128_encrypt_cmac(exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); - memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); - for (int j=0;j<4;j++) - { - apdu_buf[j]=apdu_buf[j]^icv[j]; - } - } + { + for (int i=0;i<16;i++) + { + apdu_buf[i]=apdu_buf[i]^icv[i]; + } + r = aes128_encrypt_cmac(exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); + memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); + for (int j=0;j<4;j++) + { + apdu_buf[j]=apdu_buf[j]^icv[j]; + } + } else{ r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); @@ -1129,13 +1126,13 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, /* plain_le = plain->le; */ /* padding */ if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - apdu_buf[4] = 0x00; - } - else{ - apdu_buf[4] = 0x80; - } - } + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + apdu_buf[4] = 0x00; + } + else{ + apdu_buf[4] = 0x80; + } + } else{ apdu_buf[4] = 0x80; } @@ -1152,16 +1149,16 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, return -1; if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } - else{ - if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } - } - else{ + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + else{ + if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + } + else{ if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) return -1; } From b48e53e6d93f1e9d6cc30f58da7e4a4e9fc3d529 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Thu, 5 May 2022 13:22:19 +0800 Subject: [PATCH 2442/4321] Update card-epass2003.c indent and replace memset in some where --- src/libopensc/card-epass2003.c | 47 +++++++++++++++++----------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 1c6a43d8ab..ce04756824 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -606,14 +606,14 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 1 - Generate Derivation data */ if(isFips){ - memset(data,0x00,15); - memset(&data[11], 0x04, 1); - memset(&data[14], 0x80, 1); - memset(&data[15], 0x01, 1); - memcpy(&data[16], g_random, 8); - memcpy(&data[24], &result[12+1], 8); - } - else{ + memset(data,0x00,15); + memset(&data[11], 0x04, 1); + memset(&data[14], 0x80, 1); + memset(&data[15], 0x01, 1); + memcpy(&data[16], g_random, 8); + memcpy(&data[24], &result[12+1], 8); + } + else{ memcpy(data, &result[16], 4); memcpy(&data[4], g_random, 4); memcpy(&data[8], &result[12], 4); @@ -643,8 +643,8 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma } if(isFips){ - memset(&data[11], 0x00, 1); - memset(&data[14], 0x40, 1); + data[11] = 0x00; + data[14] = 0x40; } else{ memcpy(data, g_random, 8); @@ -706,11 +706,11 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ if(isFips) { memset(data,0x00,15); - memset(&data[11], 0x01, 1); - memset(&data[14], 0x40, 1); - memset(&data[15], 0x01, 1); - memcpy(&data[16], g_random, 8); - memcpy(&data[24], ran_key, 8); + data[11] = 0x01; + data[14] = 0x40; + data[15] = 0x01; + memcpy(&data[16], g_random, 8); + memcpy(&data[24], ran_key, 8); }else{ memcpy(data, ran_key, 8); memcpy(&data[8], g_random, 8); @@ -737,7 +737,8 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ if(isFips){ memcpy(data, "\x84\x82\x03\x00\x10", 5); memcpy(&data[5], &cryptogram[0], 8); - }else{ + } + else{ memcpy(data, "\x84\x82\x03\x00\x10", 5); memcpy(&data[5], &cryptogram[16], 8); memcpy(&data[13], "\x80\x00\x00", 3); @@ -1126,13 +1127,13 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, /* plain_le = plain->le; */ /* padding */ if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - apdu_buf[4] = 0x00; - } - else{ - apdu_buf[4] = 0x80; - } - } + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + apdu_buf[4] = 0x00; + } + else{ + apdu_buf[4] = 0x80; + } + } else{ apdu_buf[4] = 0x80; } From 1fa87fc22f453bada84802595be01d0f9da24504 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Thu, 5 May 2022 14:35:03 +0800 Subject: [PATCH 2443/4321] Update card-epass2003.c Indent and CMAC interfaces of different OpenSSL versions --- src/libopensc/card-epass2003.c | 178 ++++++++++++++++++++------------- 1 file changed, 106 insertions(+), 72 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index ce04756824..0c4f11869d 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -328,96 +328,130 @@ static int aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) { - unsigned char data1[32] = {0}; - unsigned char data2[32] = {0}; - unsigned char k1Bin[32] = {0}; - unsigned char k2Bin[32] = {0}; + unsigned char data1[32] = {0}; + unsigned char data2[32] = {0}; + unsigned char k1Bin[32] = {0}; + unsigned char k2Bin[32] = {0}; - unsigned char check = 0; - BIGNUM *enc1,*lenc1; - BIGNUM *enc2,*lenc2; + unsigned char check = 0; + BIGNUM *enc1,*lenc1; + BIGNUM *enc2,*lenc2; // k1 - int offset = 0; - int r = SC_ERROR_INTERNAL; - unsigned char out[32] = {0}; - unsigned char iv0[EVP_MAX_IV_LENGTH] = {0}; - r = openssl_enc(EVP_aes_128_ecb(), key, iv0, data1, 16, out); - if( r != SC_SUCCESS) - return r; - - check = out[0]; - - enc1 = BN_new(); - lenc1 = BN_new(); - BN_bin2bn(out,16,enc1); - BN_lshift1(lenc1,enc1); - BN_bn2bin(lenc1,k1Bin); + int offset = 0; + int r = SC_ERROR_INTERNAL; + unsigned char out[32] = {0}; + unsigned char iv0[EVP_MAX_IV_LENGTH] = {0}; + r = openssl_enc(EVP_aes_128_ecb(), key, iv0, data1, 16, out); + if( r != SC_SUCCESS) + return r; + + check = out[0]; + enc1 = BN_new(); + lenc1 = BN_new(); + BN_bin2bn(out,16,enc1); + BN_lshift1(lenc1,enc1); + BN_bn2bin(lenc1,k1Bin); if(check > 0x80){ - offset = 1; - k1Bin[15+offset] ^= 0x87; - } - BN_free(enc1); - BN_free(lenc1); + offset = 1; + k1Bin[15+offset] ^= 0x87; + } + BN_free(enc1); + BN_free(lenc1); // k2 - enc2 = BN_new(); - lenc2 = BN_new(); - check = k1Bin[offset]; - BN_bin2bn(&k1Bin[offset],16,enc2); - - offset = 0; - BN_lshift1(lenc2,enc2); - BN_bn2bin(lenc2,k2Bin); - if(check > 0x80){ - offset = 1; - k2Bin[15+offset] ^= 0x87; - } - BN_free(enc2); - BN_free(lenc2); + enc2 = BN_new(); + lenc2 = BN_new(); + check = k1Bin[offset]; + BN_bin2bn(&k1Bin[offset],16,enc2); + + offset = 0; + BN_lshift1(lenc2,enc2); + BN_bn2bin(lenc2,k2Bin); + if(check > 0x80){ + offset = 1; + k2Bin[15+offset] ^= 0x87; + } + BN_free(enc2); + BN_free(lenc2); //padding - if(length < 16){ - memcpy(&data2[0],input,length); - data2[length] = 0x80; - } + if(length < 16){ + memcpy(&data2[0],input,length); + data2[length] = 0x80; + } //k2 xor padded data - for (int i=0;i<16;i++){ - data2[i]=data2[i]^k2Bin[offset + i]; - } - return openssl_enc(EVP_aes_128_cbc(), key, iv, data2, 16, output); + for (int i=0;i<16;i++){ + data2[i]=data2[i]^k2Bin[offset + i]; + } + return openssl_enc(EVP_aes_128_cbc(), key, iv, data2, 16, output); } static int aes128_encrypt_cmac(const unsigned char *key, int keysize, const unsigned char *input, size_t length, unsigned char *output) { - size_t mactlen = 0; - CMAC_CTX *ctx = CMAC_CTX_new(); - if(ctx == NULL) - { - return SC_ERROR_INTERNAL; - } + size_t mactlen = 0; + int r = SC_ERROR_INTERNAL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX *ctx = CMAC_CTX_new(); + if(ctx == NULL) + { + return SC_ERROR_INTERNAL; + } + + if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) + { + goto err; + } + + if(!CMAC_Update(ctx, input, length)) + { + goto err; + } - if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) - { - CMAC_CTX_free(ctx); - return SC_ERROR_INTERNAL; - } + if(!CMAC_Final(ctx, output, &mactlen)) + { + goto err; + } + r = SC_SUCCESS; +err: + CMAC_CTX_free(ctx); +#else + EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL); + if(mac == NULL) + { + return r; + } - if(!CMAC_Update(ctx, input, length)) - { - CMAC_CTX_free(ctx); - return SC_ERROR_INTERNAL; - } + OSSL_PARAM params[2] = {0}; + params[0] = OSSL_PARAM_construct_utf8_string("cipher","aes-128-cbc", 0); + params[1] = OSSL_PARAM_construct_end(); - if(!CMAC_Final(ctx, output, &mactlen)) - { - CMAC_CTX_free(ctx); - return SC_ERROR_INTERNAL; - } - CMAC_CTX_free(ctx); - return SC_SUCCESS; + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac); + if(ctx == NULL) + { + EVP_MAC_CTX_free(ctx); + return r; + } + if(!EVP_MAC_init(ctx, (const unsigned char *)key, keysize/8,params)) + { + goto err; + } + if(!EVP_MAC_update(ctx, input,length)) + { + goto err; + } + if(!EVP_MAC_final(ctx, output, &mactlen, 16)) + { + goto err; + } + r = SC_SUCCESS; +err: + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); +#endif + return r; } static int From 0f77266f53729c8de3e1bead987d7d03ae261389 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Fri, 6 May 2022 09:55:36 +0800 Subject: [PATCH 2444/4321] Update card-epass2003.c indenting --- src/libopensc/card-epass2003.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 0c4f11869d..b9e6b5e04f 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -745,7 +745,8 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ data[15] = 0x01; memcpy(&data[16], g_random, 8); memcpy(&data[24], ran_key, 8); - }else{ + } + else{ memcpy(data, ran_key, 8); memcpy(&data[8], g_random, 8); data[16] = 0x80; @@ -1184,15 +1185,15 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, return -1; if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } - else{ - if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } - } + if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + else{ + if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; + } + } else{ if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) return -1; From 03471974491367317a4827f39f85c495c32f2836 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Fri, 6 May 2022 10:16:15 +0800 Subject: [PATCH 2445/4321] Update card-epass2003.c indent and no memset to set one byte. --- src/libopensc/card-epass2003.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index b9e6b5e04f..c7b2fdd9f3 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -416,7 +416,7 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, } r = SC_SUCCESS; err: - CMAC_CTX_free(ctx); + CMAC_CTX_free(ctx); #else EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL); if(mac == NULL) @@ -641,9 +641,9 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 1 - Generate Derivation data */ if(isFips){ memset(data,0x00,15); - memset(&data[11], 0x04, 1); - memset(&data[14], 0x80, 1); - memset(&data[15], 0x01, 1); + data[11] = 0x04; + data[14] = 0x80; + data[15] = 0x01; memcpy(&data[16], g_random, 8); memcpy(&data[24], &result[12+1], 8); } @@ -1194,7 +1194,7 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, return -1; } } - else{ + else{ if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) return -1; } From ee5ee9c5af48a83eeac4545febac0931db38f127 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Fri, 6 May 2022 10:32:38 +0800 Subject: [PATCH 2446/4321] Update card-epass2003.c repair if indent in aes128_encrypt_cmac function --- src/libopensc/card-epass2003.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index c7b2fdd9f3..415052387b 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -395,23 +395,17 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, int r = SC_ERROR_INTERNAL; #if OPENSSL_VERSION_NUMBER < 0x30000000L CMAC_CTX *ctx = CMAC_CTX_new(); - if(ctx == NULL) - { + if(ctx == NULL) { return SC_ERROR_INTERNAL; } - if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) - { + if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) { goto err; } - - if(!CMAC_Update(ctx, input, length)) - { + if(!CMAC_Update(ctx, input, length)) { goto err; } - - if(!CMAC_Final(ctx, output, &mactlen)) - { + if(!CMAC_Final(ctx, output, &mactlen)) { goto err; } r = SC_SUCCESS; @@ -419,8 +413,7 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, CMAC_CTX_free(ctx); #else EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL); - if(mac == NULL) - { + if(mac == NULL){ return r; } @@ -429,21 +422,17 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, params[1] = OSSL_PARAM_construct_end(); EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac); - if(ctx == NULL) - { + if(ctx == NULL){ EVP_MAC_CTX_free(ctx); return r; } - if(!EVP_MAC_init(ctx, (const unsigned char *)key, keysize/8,params)) - { + if(!EVP_MAC_init(ctx, (const unsigned char *)key, keysize/8,params)){ goto err; } - if(!EVP_MAC_update(ctx, input,length)) - { + if(!EVP_MAC_update(ctx, input,length)){ goto err; } - if(!EVP_MAC_final(ctx, output, &mactlen, 16)) - { + if(!EVP_MAC_final(ctx, output, &mactlen, 16)) { goto err; } r = SC_SUCCESS; From 5d6f7cbfef47746fe60ccb5e89ed6101ac20f543 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Sat, 7 May 2022 09:49:55 +0800 Subject: [PATCH 2447/4321] Update card-epass2003.c Merge if statement blocks --- src/libopensc/card-epass2003.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 415052387b..003ffedcfe 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -758,12 +758,11 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); memset(data, 0, sizeof(data)); + memcpy(data, "\x84\x82\x03\x00\x10", 5); if(isFips){ - memcpy(data, "\x84\x82\x03\x00\x10", 5); memcpy(&data[5], &cryptogram[0], 8); } else{ - memcpy(data, "\x84\x82\x03\x00\x10", 5); memcpy(&data[5], &cryptogram[16], 8); memcpy(&data[13], "\x80\x00\x00", 3); } @@ -1150,13 +1149,8 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, apdu_buf[3] = (unsigned char)plain->p2; /* plain_le = plain->le; */ /* padding */ - if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - apdu_buf[4] = 0x00; - } - else{ - apdu_buf[4] = 0x80; - } + if(exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + apdu_buf[4] = 0x00; } else{ apdu_buf[4] = 0x80; @@ -1173,15 +1167,9 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, &le_tlv_len, exdata->smtype)) return -1; - if(exdata->bFipsCertification){ - if(plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } - else{ - if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) - return -1; - } + if(exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + return -1; } else{ if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) From 9ca0f61363941a8acbd8607fac1ad87f7185110a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 3 May 2022 17:45:52 +0200 Subject: [PATCH 2448/4321] Free curve name in case of failure Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46750 --- src/libopensc/card.c | 4 +++- src/pkcs15init/pkcs15-isoApplet.c | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index b636247607..d62485fc85 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1461,8 +1461,10 @@ int sc_copy_ec_params(struct sc_ec_parameters *dst, struct sc_ec_parameters *src dst->id = src->id; if (src->der.value && src->der.len) { dst->der.value = malloc(src->der.len); - if (!dst->der.value) + if (!dst->der.value) { + free(dst->named_curve); return SC_ERROR_OUT_OF_MEMORY; + } memcpy(dst->der.value, src->der.value, src->der.len); dst->der.len = src->der.len; } diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 41b4dcfd42..d724eda2b3 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -576,6 +576,11 @@ isoApplet_generate_key_ec(const sc_pkcs15_prkey_info_t *key_info, sc_card_t *car pubkey->u.ec.params.der.value = NULL; pubkey->u.ec.params.der.len = 0; } + if(pubkey->u.ec.params.named_curve) + { + free(pubkey->u.ec.params.named_curve); + pubkey->u.ec.params.named_curve = NULL; + } if(pubkey->u.ec.ecpointQ.value) { free(pubkey->u.ec.ecpointQ.value); From 5b811caa617f7ce0a57a84bd6710328d72701662 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 5 May 2022 21:31:57 +0200 Subject: [PATCH 2449/4321] fuzz_pkcs15_tool: Fix corpus files --- ... 580ffba4a6c4d24100dd3dc11ab0014be3de7a6b} | Bin 3803 -> 3807 bytes ... 5ccb89aff2634fc168e0758cb2005d6dcf0398bc} | Bin 2649 -> 2653 bytes .../69456a048f311376c4093ae2c613ac1f261c6207 | Bin 0 -> 8404 bytes .../8c1c42b8b9ac94f0d913814685c18f78d0aaa922 | Bin 1973 -> 0 bytes ... a1e04ba21b4b54a1fdc048611c4f890405c9885d} | Bin 2686 -> 2688 bytes .../a3289103f478310fe6013369adf1b1e0e44b14c2 | Bin 0 -> 10168 bytes ... ade754cf6e6f55b8873e6d6a12080e7f8b4366ee} | Bin 10412 -> 10416 bytes .../bcfc86233c2a553dd03681e139a44777e2dbe7db | Bin 1783 -> 0 bytes ... c2e3f533efccdfbba6de4c3d2e4aea831f508034} | Bin 8952 -> 8952 bytes .../d76c9da7e83d1c9bcd27310197bbd01ee1746a3b | Bin 1715 -> 0 bytes .../f1cac4a34dcb285f87df7a4568fe8eb00f9a4cad | Bin 0 -> 1783 bytes 11 files changed, 0 insertions(+), 0 deletions(-) rename src/tests/fuzzing/corpus/fuzz_pkcs15_tool/{dc9f8237a8e5d94119db6894fe81d5e18cbee80c => 580ffba4a6c4d24100dd3dc11ab0014be3de7a6b} (88%) rename src/tests/fuzzing/corpus/fuzz_pkcs15_tool/{fe4d8242cdc4596d8163baf8dec8ed1df88c0228 => 5ccb89aff2634fc168e0758cb2005d6dcf0398bc} (95%) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/69456a048f311376c4093ae2c613ac1f261c6207 delete mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/8c1c42b8b9ac94f0d913814685c18f78d0aaa922 rename src/tests/fuzzing/corpus/fuzz_pkcs15_tool/{ba99175e1d1561d6f5a38eee98f9b4472b9159e2 => a1e04ba21b4b54a1fdc048611c4f890405c9885d} (96%) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/a3289103f478310fe6013369adf1b1e0e44b14c2 rename src/tests/fuzzing/corpus/fuzz_pkcs15_tool/{14cbed013fc24e65150bb6f737322bbcdb064554 => ade754cf6e6f55b8873e6d6a12080e7f8b4366ee} (97%) delete mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db rename src/tests/fuzzing/corpus/fuzz_pkcs15_tool/{84ec9c1c1720fdb2fe094168fd81905260421077 => c2e3f533efccdfbba6de4c3d2e4aea831f508034} (99%) delete mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/d76c9da7e83d1c9bcd27310197bbd01ee1746a3b create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_tool/f1cac4a34dcb285f87df7a4568fe8eb00f9a4cad diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/dc9f8237a8e5d94119db6894fe81d5e18cbee80c b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/580ffba4a6c4d24100dd3dc11ab0014be3de7a6b similarity index 88% rename from src/tests/fuzzing/corpus/fuzz_pkcs15_tool/dc9f8237a8e5d94119db6894fe81d5e18cbee80c rename to src/tests/fuzzing/corpus/fuzz_pkcs15_tool/580ffba4a6c4d24100dd3dc11ab0014be3de7a6b index 04a5fdd932d3c8b54f74a9c508bf1f00fe856ce4..2a502ef6cd70f72c3b7579ccdf4575a1a8762b45 100644 GIT binary patch delta 16 XcmcaDdta7aH=9A%nL&3W^9?=#EI0(q delta 12 TcmcaFds~)SH#>PF`wcz-AFTwD diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/fe4d8242cdc4596d8163baf8dec8ed1df88c0228 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/5ccb89aff2634fc168e0758cb2005d6dcf0398bc similarity index 95% rename from src/tests/fuzzing/corpus/fuzz_pkcs15_tool/fe4d8242cdc4596d8163baf8dec8ed1df88c0228 rename to src/tests/fuzzing/corpus/fuzz_pkcs15_tool/5ccb89aff2634fc168e0758cb2005d6dcf0398bc index f660c15b61858476fcfe062f5b11f01815e5a915..17af38c0e26b5580d5a955f37f6cda09bd887ae6 100644 GIT binary patch delta 16 Xcmca9a#w_1H=9A%nL&3Wa~Kx@Dfk30 delta 12 TcmcaBa#Ms^H#>PFdl(l09mNCn diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/69456a048f311376c4093ae2c613ac1f261c6207 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/69456a048f311376c4093ae2c613ac1f261c6207 new file mode 100644 index 0000000000000000000000000000000000000000..74ca130a94d1009aff136c7e3c66f3b7278dd882 GIT binary patch literal 8404 zcmeHM2|QG58$V}ejIo7mWyxeIF~b=S2 z1`rtlFdJCBClLTbNuku-Fj1+-Fd!B{0b5x!{@EzN7q*ebC4nDi+X!#~0F46x5dZ|- zG*BiJ{$Fg9lLzc&UIYEW05Av)0mGokFTe=!4tNiY0%O4VJ3uCf#zoF=3Nku zipHQo9suIU;wEpgAcut|KrE~Z#NrX*piv+S1!58RsewQN*nI~{0OG@<9Whujl%qXK z9+E?D_{Ah0sEh!-8Pz|)+tZsu4xlpdnh*&hi9oXu2LUnONe5GsE~JfE&|<_1i>r(v8TXwv0l)_N-_t*W;v z5MtQ4Zz+?f)HKk?g0zid1{?cyPBkfmiSKRZ*P8M={HX0DSJNr`Nbr?Iy;;n_B?JSD z_dZf7p%jbplO1aEh1|H1*8;&SLugtJv#YzMnrAr|NE}b1pHoCTIPUK|IM6HYrpjp8 zyR`S7mzS+;&6QhSW09nvRE}{AhC0t1x`rP;b?m{l15rOdzB)2jRhbnTC$J@{M5w0! z>Wcg5hW9;s2Nt&0C3$d7a~2HT7t1K^;(uSg`hd~~pQZti2UVlt_S(9ScO_}+p_n#B z1|$c|wBQC0`n`tLrhcZ~fu~kVaFW%}mw(^e7Osa>j_vLLU$EXG2a5N1+)b!zpV*6Uz|( zghzs}(@PQlYKGjyAqZbTx*~QY5DE0a=>g143G@%&XQTnx6-fjHim{{pQp&_@Pi2V3 z?%p)Ae=vdKPiHV@WDZ-hxBpZdr1IfcfCvU`*=cO36d$s?o;r=f@R>je`8g2tH5{^X z@)%|}#C#4h+c?Zt4)ZY^n(p)w&`-ep6g`T+51X0!R{`uJl543!bOZx9xq8!StKg`Z z1_?>QanWLh^9dDNV6gaUh1LZ*6L^WmdPGW+nt}P z7o##j2)kRa1xXT6v6Xjf@#>Y4O2{Oh+4 z;keGHlD5CJO_~$X01OUPGk3;}B@&2gU4bgDT>Z-M%RP==bndSt-l|i@E#Ri034F{DnpRsCcsJN?9mZ|YoQQ>_LiyzPwM%4Lp7!t*WvHw`{YaeI&zvQGSZkk##Pb1+RHF3Iw4&-<3HL3}&R|&)D;K7-NdbXAnQUHsFb$=5{_bX@(Gh zWIs0Wkc45fAwk-Z7A!H~t23nWu@ys7z~BiToAx{Gc&-NZ#LzoDd8qbi@}4>QniGVS&I|^91pEM-nwp_usL7IU2tae2d|* zfNQxILsvgPeBLd+*;T!y?`^9&4HdB0;GA3B^AdbIwfSbMp*}RqIMlwd$W%qjheHJ4 z)Hy+^>cNRI0tXVM199gAvKVg6)SUN_60s5BHcCA47#?OE7sek^Petots) zx-V@~_o1++pDpU|8ovKh=zdk~1pYf>2acjCrTMqV0h|Sju4%JV2wT~%mh<>Hk2FoZhtvMlNdI1j!@X^6 zi*0PR!~}2NjS?@?i$isGb!MNpeRzA!ZS7*oGn$6!iBN7R0fPG5Opxd&=L?s3F2F^Nn2YXvLJl;hfJZ%4lvDcy#XedCm~ z*KgB--iljZr;dvmLcLcddgY{sxMQ-XZ?0(!;U1WhfoK>l^zyHh@<&p)G%9R66RXZW zABGNEU$bRS`>^8vk{D_^I6atiH9~_YKM!!Qg}LM6v%T)bm%A zGqOpaspym^Fo12!n0c@onA)(QQCNO>>w*DUdg3S)76Uf}f21BQAs=K+Q4AHLa5QK1 zLvxe_75uz|yaV8!2jxQ^F$wgesZ)25ef@l>>J+*!n;7U%GYky$_ArEZHjoa zsjpAeCV6@g-SrK0h&rBB0|RXxDv6@2^%-4FXwZ|XMt7fB@Vv=$BsRH_nO)+KgI>5$ zJ1}!E9DgPdxP&k=e}!+4OYy2e(Gweml<4g3W~1x67pHG3-gz@uOH`wWTy+CbG~;!q z@YrOSa0rHBYdqxkaxHbY;w&@DRFZ;|YL9J;-%bz;Cp2!X%#jdHVFn96e;1MxFH--+ zthFa>PXF`ByPLM6O^(Sz_bZEK1zu*2J*kXkZ@NFuY0(k@JIAZ``J{+@Nd8i&ezQtG zcxQJ^=^OSlKE_R<{ZIJXx4Ki3NclzAS8!e}uu>$-Rm>kd^bw>7prdvr>bg5*=eHmG)elgFzH9Y zq#p*8{v8DDEtrNg! z_6zkbZF_r(meQzM%MJ4g4@i|Splc+b8u!2AuujIpdo=oWc_-WQ(jx81{GcYyF0SgP zS=F<(HTxxNuV+!WR|v48fw|ecTd8e*g%{6&jD!crdo(G}dxBX9I!^k&cIsVe8P(@9 zEd#Ky3_$%WGQe0Swjdlm7PKKqCCji$=CmWTCgD5D03_M}g{vO_6&ZkF@V{R~`?3r` zF!)Vz2Pqx@rU-<^{Soh5LHd)tPl7bQ1BYX?+e!}qy0FN44_#SJvE%mBv_|($M*Y;B zLRV4h5tXFD5^@V*vYt3Qba`8y?fn(nm~mTPW9R5qk@y}Lkg73CH*R#4=etT;_+otY@x{9X6p!h+_ zbvy4|_6@FRm6jabg?p+S(1D%5+plbve*|A*Lgfbz|Kicw7ml3%6aBt+jPyBbu!W@n!URLs{;jJ$K3x0UkmaCA%J+NS{V6~k9;wFH>$967F=HAcU&Ktk$bjgZY zM5mHV_m&oy$h?X}pB-%N@q^2P!ti?we7P+6QKS6raR9&X;o`TIN2!qbhggHFqr6k$ z^v9)9J<{)#M*Y@UZCSL0MR?bgL0WpY`nZE-ZG)-R&T~al#%}{ItTg;gaAV;5WMxF+ zBR=Q2B$L89-Z9BVWsY=5a$i4?6GWWNGskwb-`|22}I{lI&=~9a)Z1+Bj6|5 zcHnf7mPxgmTILgm0F{gEfJIo2kngNydqWZ(G%R|e8pLWjX?E&^P?|yyRNbN zU0j`6m$l!bDdqFW`ii@~3dgg1p6xfUS)63? zaHVSJFNBr7IvMiJ2S(kOQtIu#KrP=TR>6fWi2G4Qx%fR} zj`S0+9fH!YW2_@Wij?Y?Z7LcIzFf9Df_hP?lUvYlU1yN0_byFE<7s<$0|aWJ?L+em Nrs|V_GNo+|{U=fcgi`@6Xn**XQUZ2Tn?ift)z6k&%H3&?a+Z3lqaAAQ#91+6)F!m>QZGm5>c(WMyD(V&rE4x`T_UiII`v z{6(`X^`9!57?$;BN=`j%u_4%=Ln}bEyY$k5DXFUtzWfj_;5xbSxX2UBwV9Xiz0s@j z==|5{sw3jVvhHLa57X;;Gbc4#mmPbjr}Znr?~%@mQ?~M}8rV{c6jmMRGy7U_x3uFC zC=7lV3r_rZM?adaK<&di-=mEMBHzV#FKuCX@J+nwhvRI{t0x~jmP*aOv5F~$`!nx! z?K_(;hJ9rA3`+kMT5-?eywHA``XVP8?bMzlLMm?S^DQNR+lQ92OJ5b^@$@`AYsxi+ z86VF-X+F!op(Rx0_^S7!Ioqp^ug6;_v#ObNv;0q%39B>n-LAOu+~$^d{(^s{TFzfR z+q!?o`=C#;Nu7~Q%!~|-$e{!bdSECqGOV{>r}W(Ypt0TFE$%!^Y6Sm^1c)1Jiafr< znz`b`2-dhVW8mK#!UK7KmIe8FCMu1@*J)2huWfd>0|kLvz-mX-Y= zara(^@4@@)eqEUyHA6M{+VYH^-`evIou0NWV~JJe&Dq)7S*+dfGt;<*j3-LT++Evz z`&lMm=B-y>Ew%?cC*9fP78fLJwoiehe&Hg&^UDj=W&cdKtIeM-^ZEEAgZr5)gu8|I zPwr0X)|ftZ*$Ymd9|@b5&tG4yrM=?ke#?~^LOXu0*e?A4+O>7d*S?FnVP&Qza!fXO z&K=tW)4zA#KXJ;ufy+3a<3+nyko8T4Rr&?ycNX98n3MSb>(xzMZH0{RB+aN*(8Q<+ zNzxEDFd4}jG#-Jb=%^U)@65k`FdgdNv*cvlU7o^&)?W>{*f@YG`kXBbGZSX&L{83@ z#s=WzY+!^ZIY$}@v$2ECV`79F%*@En?8Lw_-Q7;GK)Citc2=#q>KQOB`1w-y^J4`j1?KlMbIkX3pIIBq z8#q5=O?ltnsa&$pm8Z`vE)|nCPj5#K!8Bk9#zI37%m#*Fq(S3DXb6U#Y__sK_iFL+ zGgY$DZL9L_56!7Tb{O6eG%++XgM^@o5u`jYz)~QT83-UkkX5^pg+YlqiGgK7NLo$~ z=N22|;Abfh!}jmhzngR4VxK`!`ajue5B=gUox1;Vw7~54&>0mfy%?HBAh=@^H_;W0(66*2}~soxS?s6xkQd=?n&m zSvd?TOa^-Yzn(W#YClvaUT}D_m(4tJp+8IC)}AT4Kg&$4XKK^z%!(&(t{LSfsW<;? zWu5B(oykBd_3yI3KW7*2ym$7LTwme$L(}f297~-0X#J0xo;t_s6^DK?g+1J_ShO;0 ek)3Vwgd5P%$5-~_lfzYC43s!IZe?P~YytpE7mxP< diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ba99175e1d1561d6f5a38eee98f9b4472b9159e2 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/a1e04ba21b4b54a1fdc048611c4f890405c9885d similarity index 96% rename from src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ba99175e1d1561d6f5a38eee98f9b4472b9159e2 rename to src/tests/fuzzing/corpus/fuzz_pkcs15_tool/a1e04ba21b4b54a1fdc048611c4f890405c9885d index 90b3339dfde36b4ae9cee644233dacb16a9e39ad..bd72e228bfad4b07fe9cdced21babc17bfbb051e 100644 GIT binary patch delta 16 Xcmew-(jdyNo6Vr>%%HoGwUP?}CyN9f delta 14 VcmZn={U^ezo6Vq`ypg?<3jiS01P}lK diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/a3289103f478310fe6013369adf1b1e0e44b14c2 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/a3289103f478310fe6013369adf1b1e0e44b14c2 new file mode 100644 index 0000000000000000000000000000000000000000..21515ccb6f6ea4e80f08cdc92a66b766dfababb0 GIT binary patch literal 10168 zcmeHN2|QI>+u!?~;~X;~L&(W2(>{hGQKoAM$w4IQq(d^D97BU}jyZFhm9dgWQ|6Ke z36&y+BxA;lkW%vQtw{H++xNZq-oE#KzuQlKYp?a}wYUF%*7N^A>sj)yfV?gsPX&M_ zfJWO9fR^)7UnDq)TANVwE)@XKi~zt1>_GuL>0keM2bh5XuJtU44T+U^zCCLX0$UVO zYk_#!hA21!i~_F#(qfVM_82e@On{tkfJtBqcn^F4rh$*J@%JbBNe@E(?n@BqOgKoO z(VPUJz_~WREturaPKmjcw!?-fUZ*3vILw@1cR+;`_{~36MkPoYA}A>nwCIf05S_6S z%d|YqFl>?y#Gz8@jD>Jl9tuPgI3PAG)7CIUkc`HlKn4I}#xj1o#Db}GEE7b>GC*|9 zP%0V)qEH}+n17xKWP#1S2rLj27Hx&Wa-*z>1QAFWxnSnzwIox$@w#L$Zx<&QN0K+0 zidTXN5P=h7M+{iFai0vd2@s@!^q{$=W_v7%+OVaHn*25w_DYP6c?8{25UANH7_yi07%y8rY$d%zzvSh%?dDyh&ue@2*}>wBm04U3xQm@52c*mf z&jxN;h0CYlS8|2i&dBs%d(S$3iKzN7`XQHG*C4qjDfR>Jp5M9+puS3okKRH_eoyQL@WG>FgWYAaAyIzqIv1+&qv zxNRqWYdS{{O=KzwB?!J7{ypb(a8nn#h8++7{n-S5Hqwu{o}8!8+>N^0a-Q?;1+EU8 zBF--7sA)x9<2d`OpI3p#HWv?)*B&`XFHb6U!Rjz4xp;jZgQVx*9t;zj!-DMSM%uPg z!NZY?VBj{73PkIIom5x^LwgR^Q4pQ0Qb0~sN1WIzJLx*+)B zX5*AF2MEq!FlZDmXyG!410TH1K_JAkR?Af{V;6q#N^+aSnTX<#0ykbgci>PplTha8 z(^EfJMJ#?KkbDhyLAmsRjs4y% z1$KKy+mul2D%DEy_GFFtj-tAoFJ}5`Bn{H{1}diQnlQQKvA>PyW53^4BLssHp%^<$ zR>;>m>3Kucss<*>PQmI9roJ>Xhhb4G{z0SPB8G>oP}4;*G+)M$`O-^`Sq|tI_ETqX z%V{=OGF~1@_R<(G7)-0;T+I(mg`ab`3s_uvapyo@TZWbGhv=&{*PYC`3eJ3}kBqr73LPn`>@9l=qNh8umcco@cT)0@P!Is43IU6Jp5}OOQp5K z-+PX#n9zg;yaow<8DJoAz)V7bR3K%7x{8{L@+L^}%P58*ioyTl@gX8OV}D8dgTy5| z2W8xD)Ng!(olHji4|p6au0Qk&qRvw$1Ht)cG0!{?BYprPT#TWE!10h>=>?U~w$U}N zbZ!D?(zR~uQhO`cS@Y%HH2;7vyS;O<&dXDJz%?oR65{=0V}bC;C+ehwRiB6N8&t_> z#J@U{XBnPq8^1i^DC&jELAo$DwE3m*vH)8F#&iBb@tJR;*&aqTUp5TyYv&orQB1X@ z-YjV2lNc&FKek_TCu-j*ap$ajxg4D;yXkSZMXA<}w#_3o%rJ?EQwo0#HBN}U2=LF?JLt|uw>}u)63?PRd-AttGD*Q zvgM;#2P~t;akq?CjOY}{80R<0pgd!4=5)mO9@+I-R-n}(I$HI|!5_ik3yBEG6?k{k zo!2O4Ud%`?e{0L!%JuU9Kb0aF%<7Lnrov_g#NSncAsGA#Dr|uQLlT;WLP6q_npg_c z%x9sCMq!y@$%_H$D|t{TECv=E!1vS$8^k%6kYSlX3>uah&^BboMHoBCHdSH4Oz2cR z>r!P{X{xEKs4Jx_{op&-fHDTi_S$)w=EA0XC5v`4M z|AhRVfK!2{?7=O&%$xgCdr{Lwy{%SDh6TuBMj@~HcVfdnR7V=^jXcW}ZGSFuGpc~7 zKivQHkt&{jPH+a8_Nvl-6@_x=lCTamEKsHI|Ia=l2ye0o=HQ6xCFq z_HNOVXXHNHy;hGT4QmDN?qy*}wP%;!WOp*T$yI3SOtfARhQswJ)3~O8O~#?JC*qR-6?L0|N0dR(zmz=!s8*G}y;P{$ySRu=?YciuhH(w|k9J%h( z@<1l=f!Ro#-7au;zhIVAv|vtAMeu_;Wws4-3Y-Qq2+VN`-)~U->5}Nbol}04GMAOz zwKhm`zBH)F6uLQBhpngTV9h%=Hnr+qAM7m0maJcy*^pbPpo{kI9TPXm4n1`8g2-`Y zj)M)PCmoxU7-CukFMAMGk46^kVJ(h{jNbRoLGaOHAKSsnbfT%Dwlbl(^VIF_@khHb z8~KJgA78Tkwck}rY%))L6n! z$}p*Zx0tlKu+T_SnaQXc;s*@!_4jHIK4RO@jPw%Yf#YfqVU-kCUvb_Xg@cweIgIVU1CVV7gpCfw8gS?ZUP`ICdV$1~;0BlXUa| zCMH=D`!u@n>Jwu^rw|uLIxRg%k-qz*&xc1)-7*QwV>+u6WC&g}g2#mlMjFY!BDMnW z^Qz_XvF`ZM>i-qf@c#zIf0$<8XbWCMserUttM`|_#DW-cl1cj zyMq*lw%gr3Y!8=t;?q>9&)CLY1JQIX0~>sHgXcZTT|snJ1FNO}m!Fm>^4$#OIzz25 zi%eV3gF%sXZ*ThSZRw8J;##OVUvw3Wr@YU&eCUh#>ce5qsZ#w^?!W~ zr%}OWdcHR}q%tsBxI5N-k8x^Zp@Cd@hT*#Ssik48m1UAd8~tm{Ta!gqGlmOVrjoGq zK-7sQqLZMlSv1XLG- zvVWN7f4GnR57RhOzsEET_`jNIqInOXP>~H`rNZ*zm){GuVdd+V3j1*wab?@7@~ zcp~{YYHJ&v(PN#2vvl!#o&2E#2b$xim;ADAiJ!l8Wz$`bHksz!&edk;pBhI!t$mZ` zeR|A5eqX7&P)!1H)rga)XzdLXfnk}B=b061*_RyE(lfWb8WcYoY-ZTN-fgU@YuJBR zFZlYdeyJX@b&I&-5vB=w5y5)_<(t!wY1D4+Jk12;+)D8s#BorTkDsXuSsYM#_11V@ z@WmMgvptRv&J}0~*3FQHc0VQ6i>!W&U&u6!6gtBU5@Fz+X0{FIGwhyitZ=K=}4XnFgc|s~ijix02opRXF2TRfh=bIxF-b{gsfKp0=JgVTGEinyRvr ziXNn*qy(qpYO{7K%KAFLyNz}i|1o^#*?oI)t>_fT+$2gRW9$wBbKH%{_S4bKEU%!o zC5M|jSDd?k(|FZ+S@UMB-_F}RPTSVLqnE806uB;cr9-Q4Otwu{Swf6+NSy!PVEoq1 zw-uf$d6xSgBpn*}P^PANR9@B$a9@8wq@ejSQ_xEGyu?Qmz$$Wbs>_>ZG z2nL_`!8Rsnblp2J@My=HX7%aYt(M}|hTBfPzh0H-6vkV4aI{lP@BmaKlxRP zxgpjg`Dg6TF(qzin+gj*k&~%oty$$4>rT14xHiJRQ9Gutb}CF?zpWj0g}t3HN@bjM z=rS-mRnZ?G**#Lq%X!)|%jE(li8!Jacx*W(a9e5OD={c^)%1ya_tY`{tUV4VXEd4L z8|gbvnivp-F8ksOBU9ZhUe8=7?D!aNXz;RWa_QkId-!?dlxQo-`O%_c6sZvtB=+cmkACfpf8NI4N&09EPQ+i#qj%;Sp3Ej zThvhROYVCcHI8(2Ox<$uQ~7wj-&Ch5C6-3rU0v#O)#*aWgr;J(n_e`3mD+1j*O|9%jPrbhaj?Z1uhTkr&uFGY|QTF?3>;=eQ%u=v;O{N z%8Zo5!V#4s`44?7?n&1rp3c25@Mw95lZB2X_m+ecJh3f6OP{oEX|H;sMVwHV#Yu_! l{XS`{rz{+@;}0h%sb}q%sxbbLaJBjO4!(VF0VC(s{snj8CXN6A literal 0 HcmV?d00001 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/14cbed013fc24e65150bb6f737322bbcdb064554 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ade754cf6e6f55b8873e6d6a12080e7f8b4366ee similarity index 97% rename from src/tests/fuzzing/corpus/fuzz_pkcs15_tool/14cbed013fc24e65150bb6f737322bbcdb064554 rename to src/tests/fuzzing/corpus/fuzz_pkcs15_tool/ade754cf6e6f55b8873e6d6a12080e7f8b4366ee index 3d906a65cf3ae63c97129fdeb42ff4aaed832a3f..f17a4ace5e178c057b61bea6d9e1c81bc138f108 100644 GIT binary patch delta 17 YcmZ1zxFL{3H=9A%nL)RBBg+a605PfsGynhq delta 13 UcmdlGxF(QAH@i4_BgYC203^i(`Tzg` diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/bcfc86233c2a553dd03681e139a44777e2dbe7db deleted file mode 100644 index dc71f9d8d4a45f46f5a60e3618fd8e9346822421..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1783 zcma)+2~bm46o&76FM+Vt009aT1uQPCF9`$?SsfI$f)a@WiY5>sF+zaBjm-o^F-TRG zs4P+yh_QgBwzz;{Q8rmdS&9m>skoyu$f7_aP-VvI^v>Kj|9Nxnx#xcK&oMRi3t|KZ zvP^mGU|>4^C6Or>mQ+~~%-S>agY;tB%wwuF_;Q!@(>ns*v zF~~7l7aYO2QWOEr7S(PYu({8$boi{pGhf*>g=fVDZPCX$eYl2DR8n4IpFCV)$L0=SR?VCY|s3SbE;fKKEfFa*PdmANnV zG?E7+CAFza>-sdDLV`t8sEV9|QG#p2hzbNLVF5aiq=G8RA)XjS850rC3PTrYsgTL2 zh3qCPinRsFTNcU!+0E0-`|AS&$Y5?!2n!GaG!Mx7P=o~#1e)(qTVvnt6@a{>Z0)p0 z>q|5ToY4jiVZ`0?RFt;gL-NyXE0avnbcZNxq8-;b%-?U9d9zBKy<{ zzU}Vn*JeiJJKXwA#PxOyB?shKVS1ACWa==lE8=k9Ck7wFRgX`0n)}G{7QZQ6e~Zr} zjA&iYjR!sNwFIM1847K6{Z0`&866VXUuj51WZYSNhyE5>;}JOSx%Z)Cvzk;lHq2Sq zn3Z%>?Wa{mAvW3{96TfB=eKDpuUS)dI<;NzzU=a9shzveBKh`N0EJW zh)8#+rVs6Ai`9i{(iEY;aH%LQ@2P_F=#Jw2Gewa`#^N!l&4nPfD`Vmk^{Mvu!u*2Q zTRWChjR@65T4twRxo9M@ySCoyfFfl(?&+bm9=7-NB<4J;&U4*|GZ|CEZN-WSq0nbb zLqT>ea^Rjv&g5I0ett%xFQ#YlH6p%NzJ;vuI6c@wF29FhIOI6DQN$IXF0el6J7S)f zyUYz|x%54kNaWHT60= zvF{SJAd#sv1TDxj^8o#ifv_9Je<6r9=3{^X!UUL{O#xi4!sQhd+7tg?y0px^i`#8| z1N8`;B&PSe`QEMXe*1gTt&#`(nWZHYqboIo7ZJ4clvq?e>(AE8v4)G)CIs=7-XmOk zeg_9@$)LCPmQGf;{8ACCyOr74Hf1^Y6-XdJ85}O~hf%Ys;bxM-p~~G_ysDJ7E3&oJ zKIXoPZV2l>P1Q_F6J)UWK6=?s-o;!JH+c}7<~{qEdB4zepoiL{{j7Idt?9r diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/84ec9c1c1720fdb2fe094168fd81905260421077 b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/c2e3f533efccdfbba6de4c3d2e4aea831f508034 similarity index 99% rename from src/tests/fuzzing/corpus/fuzz_pkcs15_tool/84ec9c1c1720fdb2fe094168fd81905260421077 rename to src/tests/fuzzing/corpus/fuzz_pkcs15_tool/c2e3f533efccdfbba6de4c3d2e4aea831f508034 index 96cf335846f2b2e74d70dd2ea6513ac39b56aa37..11c3cb69aeb52df8e0967f808fdaf23e22846b46 100644 GIT binary patch delta 14 Vcmez2`oon~H=9A%c_Zs*B>*f91ycY3 delta 14 Vcmez2`oon~H=98>c_Zs*B>*g~1#LE|z|d&;Pqd-V*8cL7YS$F*ut8qAp&a$$^15HMsP$GO)5RPXM|is|lA9 zE{0%h1Ia7TEpH{7+QZq!bKY8>E1uh&5uwQ8B+#OG!b#xpYZHOfpBk6mh}M<(rIQdH zvOso~DTk4Pv4Mf1fuSA4Kd@Vao0zs2G%>A9WME>1u??D-Rv9!gPFlds#K^=X;=J^Y zf@t6S>QyJEaC<)zb@5qwPB{BO^B}g8{!GuK_n3b0`Zl4@+rrYLS7Q zIIoeBfeFwib7Kn=!zdsZ$N}0622q$Ani!Rk4P|6yU~XdMX8^i`i>Zl`k>UJBvn%zV zDw-IU^=3*=J!`Qc*q%cxK(xE`(t#W5H8?4x$(Hj6U()km+!sNtMTak*XXJv z;={7;WF8OG>v=OLHCmS)d#9)ME5YxP&WcmE@~axyQi~K;9q2RrT5z|t;}IwfeisW) z{C7t`nyo|B3{N8*7R@zQdZi;=|-# z=EGNZrX`(How<7Mo>i6`Qg1$fI>mg!UU{xg`Nq?#%_)Hf`+1M*{&<#^{UCAoUWV_% z`|EyPnH)7kHTc@{jGo`x^A4S!wk>0cRprgu+1gpG-S0EgxP^=-O3B<^+kE?3CST^Q zS6?l*2RkR-+2j@%By6@%funxmBER#?3)E%*Ot-7epDy$H_#=b+nJa|5h4xSGPU+T| zK6Tj(PM#kLo0iXCU#+FR;^%(Ll^H@iey-Rq{Qugub<5Yji@9NCrX_MrHh9h*+XK_T zcium7%DjQgIG*E0yH}9)O@&qZ1?G1a-|v`{`2XwGOIw z$r>~sfu`uF81L`QzkVfW>DWZYez!h_ad4Y=4ifGPT%EekUfX6i&v&X&do;N)yz zgeN&i8VIwogUw@Ngc{7u$j1ttaN_cC+L_jR9H8_F9vKVnUJ z-`}ZRvd@*L&nzw#lQmCoM-IU>UAD1$YM2347>7h&%a}r`w!O3#3Y@)`rj1U7tHAl28mfY3@JDY`$)Osr>W)9lQOCvUD9i?a| zKq~d`vcErP7w)`w_LN*-;rBz+?xq||ocn0~kD8u3$LbY_eldkT+^<-)GHa2YZSsU0 J(9j2!{Q&QXZ2kZM diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/f1cac4a34dcb285f87df7a4568fe8eb00f9a4cad b/src/tests/fuzzing/corpus/fuzz_pkcs15_tool/f1cac4a34dcb285f87df7a4568fe8eb00f9a4cad new file mode 100644 index 0000000000000000000000000000000000000000..7b6d420813e655cf4733dd62b0fb183bd945c859 GIT binary patch literal 1783 zcma)+3pA8z7{}l5n;9lEGKSdf42Df5mv3e;G;XmrrESi#O{GZ&gRzW}T+*awgspVh zicX3~Yb`cLx$L-XIj42bzURE(`9I%z-sgF~-}8L0si|)u zR}jE674ikZboNP|T?#|Mi<)~uqgz;70iX?-lNtbssZ+}ihF4Llwr-E`;k)tnI>I1G z@@a`d~{e4WT0l6`|ULDMhU_i4*}Pkg-q#QMdqx{?&*CA|v9v87LTnVNFkt z+ZgJ-9IiQ9met_Zfe))@zC%=$u*M0l5ADz>7*V6DA~+?~7BmWvjtJ-NMs&4RX*9$_ zk%>XKp(CCO(*mI>GS4p0&kt-zG?bKQ+RKr8vErx1np;#U*qdT z`|_kEt}fZM{#?yBErr+5tFM!a8ox|E?1g@1R6-`yE4R>=^`r0-$QXY^9{F7#)<+GJ(ijy-rB}D8 zes^)(m8j#B$tvVN!?WkYBeckjfW$Cpmf|cye+9vv^8{zLg5Y*UESo3DZirjUeAu6P zPZ~qsk&qwiP?IKFSlH)477(0|S%~KxcgK9~``- z(3bAe>nCGZmYa73cUo5 zKc^81oUiD>sd@Y{NjR5Vm5DC}dor&CqQI3t5Cm>lIJOR_*O|nf**bJ?$lTWZZZWm% z9oVnt@XI1y+|9Qs*j)A`iI(;c;H7L8&A4XmBZ<3NlUgCINCq75bf%-`B zt;nS(CT(P_ZdY_|X49GJrTZC|wl=u9FiEzBqj^o%W#iU~1%tz}&Mia41Ky%$f0@01 zPr;7EPeU4O&kcKi;OO$63{H#eJ!FxC!WHsjyiHau(fv^ly7$dvyk5xq$MBzVrPKGb zmJ)OLx*XqC)KJ07vCw_6*oSnjH>`9+RepDT8;pVgw2+bly@C=1ZZx6y6fRZ$n|s&I zucjh7ySFEIbF1FQg9GJPr*RcDaH-LqzW2hN9df@=>XHp#@g+B9}On zcjx~l)sJTAoa*M5mIHLtjkkyFqR{uEjJ|F&H>BCoIe;1>BywUX$#tY0T_Yf4qt`|f zV%^LttNO_88WRcWZR9bIdF<+M+J4fem{nii$iT+;Pc=VFm#^jz7rwBsx_E~oLiTaH?Cb>Vm_ai^w!qPVMkvpt^d8A++;MD(+afb^wYFK^=b?aDM!@hy-dnwlT!#qNGsab^DlMTUHL literal 0 HcmV?d00001 From 4f5d4000549dc8382a22feb07e02fb8aa4f79423 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 6 May 2022 15:40:05 +0200 Subject: [PATCH 2450/4321] Free file in case of failure Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46786 --- src/pkcs15init/pkcs15-lib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 718d458cc0..e10312b771 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -609,10 +609,14 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * /* Select the parent DF */ path.len -= 2; rv = sc_select_file(p15card->card, &path, &parent); + if (rv < 0) + sc_file_free(file); LOG_TEST_RET(ctx, rv, "Cannot select parent"); rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); + if (rv < 0) + sc_file_free(file); LOG_TEST_RET(ctx, rv, "parent 'DELETE' authentication failed"); } } From 3ac2fa475c6576f11a4f8305ae78300d5012410e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 6 May 2022 16:54:23 +0200 Subject: [PATCH 2451/4321] Free options in profile Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46790 --- src/pkcs15init/profile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 598daf39ac..281f9db448 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -483,6 +483,10 @@ sc_profile_free(struct sc_profile *profile) free(pi); } + for (int i = 0; profile->options[i]; i++) { + free(profile->options[i]); + } + if (profile->p15_spec) sc_pkcs15_card_free(profile->p15_spec); free(profile); From 3d261b9a7f4b056b5b342c8b6ca1a5b1d91ee01e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 11:03:40 +0200 Subject: [PATCH 2452/4321] pkcs15-tool: Free PIN only if allocated Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47143 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47155 --- src/tools/pkcs15-tool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 56494e5d3d..fff93ab782 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1834,7 +1834,8 @@ static int change_pin(void) if (pincode && strlen((char *) pincode) == 0) { fprintf(stderr, "No PIN code supplied.\n"); - free(pincode); + if (opt_pin == NULL) + free(pincode); return 2; } From 3577feefe7cf522d7e7aa6554cafd95441a9e4dc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 12:02:19 +0200 Subject: [PATCH 2453/4321] piv-tool: Check for NULL and avoid memory leaking Free evpkey for OPENSSL_VERSION_NUMBER < 0x30000000L if error occurs and check whether keydata.pubkey or keydata.ecpoint is not NULL before calling BN_bin2bn() Thank to oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47173 --- src/tools/piv-tool.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b62b91e221..d97fc188a8 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -347,6 +347,7 @@ static int gen_key(const char * key_info) RSA * newkey = NULL; newkey = RSA_new(); if (newkey == NULL) { + EVP_PKEY_free(evpkey); fprintf(stderr, "gen_key RSA_new failed %d\n",r); return -1; } @@ -355,6 +356,13 @@ static int gen_key(const char * key_info) OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; #endif + + if (!keydata.pubkey) { + fprintf(stderr, "gen_key failed %d\n", r); + EVP_PKEY_free(evpkey); + return -1; + } + newkey_n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, NULL); expl = keydata.exponent; expc[3] = (u8) expl & 0xff; @@ -366,6 +374,7 @@ static int gen_key(const char * key_info) #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { fprintf(stderr, "gen_key unable to set RSA values"); + EVP_PKEY_free(evpkey); return -1; } @@ -416,6 +425,12 @@ static int gen_key(const char * key_info) const char *group_name; #endif + if (!keydata.ecpoint) { + fprintf(stderr, "gen_key failed %d\n", r); + EVP_PKEY_free(evpkey); + return -1; + } + ecgroup = EC_GROUP_new_by_curve_name(nid); EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); ecpoint = EC_POINT_new(ecgroup); @@ -427,6 +442,7 @@ static int gen_key(const char * key_info) r = EC_POINT_set_affine_coordinates_GFp(ecgroup, ecpoint, x, y, NULL); if (r == 0) { fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); + EVP_PKEY_free(evpkey); return -1; } #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -434,11 +450,13 @@ static int gen_key(const char * key_info) r = EC_KEY_set_group(eckey, ecgroup); if (r == 0) { fprintf(stderr, "EC_KEY_set_group failed\n"); + EVP_PKEY_free(evpkey); return -1; } r = EC_KEY_set_public_key(eckey, ecpoint); if (r == 0) { fprintf(stderr, "EC_KEY_set_public_key failed\n"); + EVP_PKEY_free(evpkey); return -1; } From 6dd0ea8999a0251b018b7a1be8cc088eeeb5f513 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 12:14:59 +0200 Subject: [PATCH 2454/4321] Free app when clearing p15card Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47302 --- src/libopensc/pkcs15.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 957a29de83..23bb2a32a2 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -859,6 +859,8 @@ sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card) p15card->tokeninfo->seInfo = NULL; p15card->tokeninfo->num_seInfo = 0; } + + sc_pkcs15_free_app(p15card); } From 26a7dceb7b2adb8162a3a8cd888d3ef16b24c76b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 13:34:25 +0200 Subject: [PATCH 2455/4321] Check pointer before dereferencing Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47400 --- src/pkcs15init/profile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 281f9db448..9c0e886975 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1542,6 +1542,10 @@ do_exclusive_aid(struct state *cur, int argc, char **argv) static int do_profile_extension(struct state *cur, int argc, char **argv) { + if (!cur->file) { + parse_error(cur, "Invalid state\n"); + return 1; + } return setstr(&cur->file->profile_extension, argv[0]); } From 74a8f296e0f195916d28e1c928f457e04aa22892 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 5 May 2022 17:03:51 +0200 Subject: [PATCH 2456/4321] fuzz_card: Do not use fuzzing input for output buffer --- src/tests/fuzzing/fuzz_card.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c index c2d7e288d5..d7e249223d 100644 --- a/src/tests/fuzzing/fuzz_card.c +++ b/src/tests/fuzzing/fuzz_card.c @@ -61,11 +61,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) goto err; /* Wrap & Unwrap*/ - fuzz_get_chunk(reader, &ptr, &ptr_size); - if (!(wrap_buf = malloc(ptr_size))) + if (!(wrap_buf = malloc(SC_MAX_APDU_BUFFER_SIZE))) goto err; - memcpy(wrap_buf, ptr, ptr_size); - wrap_buf_len = ptr_size; + wrap_buf_len = SC_MAX_APDU_BUFFER_SIZE; sc_wrap(card, NULL, 0, wrap_buf, wrap_buf_len); fuzz_get_chunk(reader, &ptr, &ptr_size); From d72b0df64ac5f7c6065b2ff9a2564ec859c1e725 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 13 May 2022 13:49:17 +0200 Subject: [PATCH 2457/4321] piv-tool: Free pubkey and ecpoint when generating key After calling BN_bin2bn() --- src/tools/piv-tool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index d97fc188a8..6b1182a829 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -348,6 +348,7 @@ static int gen_key(const char * key_info) newkey = RSA_new(); if (newkey == NULL) { EVP_PKEY_free(evpkey); + free(keydata.pubkey); fprintf(stderr, "gen_key RSA_new failed %d\n",r); return -1; } @@ -359,6 +360,7 @@ static int gen_key(const char * key_info) if (!keydata.pubkey) { fprintf(stderr, "gen_key failed %d\n", r); + free(keydata.pubkey); EVP_PKEY_free(evpkey); return -1; } @@ -370,6 +372,8 @@ static int gen_key(const char * key_info) expc[1] = (u8) (expl >>16) & 0xff; expc[0] = (u8) (expl >>24) & 0xff; newkey_e = BN_bin2bn(expc, 4, NULL); + free(keydata.pubkey); + keydata.pubkey_len = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { @@ -440,6 +444,9 @@ static int gen_key(const char * key_info) x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; r = EC_POINT_set_affine_coordinates_GFp(ecgroup, ecpoint, x, y, NULL); + + free(keydata.ecpoint); + keydata.ecpoint_len = 0; if (r == 0) { fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EVP_PKEY_free(evpkey); From 381c4c093399142f35c7ed60bd589421e28582ce Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sat, 14 May 2022 22:45:30 +0200 Subject: [PATCH 2458/4321] Remove unneeded part of readme --- src/tests/fuzzing/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md index cf8d5a7b33..0fdc72a43a 100644 --- a/src/tests/fuzzing/README.md +++ b/src/tests/fuzzing/README.md @@ -46,13 +46,6 @@ To execute the fuzz target on one input, try: ./fuzz_pkcs15_reader ./test-case ``` -### Fuzzing OpenSC tools - -It is possible to fuzz also tools provided by OpenSC. Since it is not possible to directly fuzz the source code of tools (because of the `main()` function), the fuzz targets first create a copy of the source code via the `helper.sh` script during the build, and rename the `main()` functions (and do some more modifications if necessary). -The fuzz targets for tools then test the tool by supplying fuzzer arguments and card APDU responses. - -Fuzzing input can supply whole arguments for the `argv` or only particular values for static options. See the fuzz target source code for how the fuzzing input is split into an argument and APDU parts. - ## Corpus ### Corpus for `fuzz_pkcs15_reader` From e455e2eac635a3ad47ff820de9026304690f9fa3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sat, 14 May 2022 22:46:14 +0200 Subject: [PATCH 2459/4321] Remove testfile from corpus --- src/tests/fuzzing/corpus/fuzz_card/testfile2 | Bin 1432 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/tests/fuzzing/corpus/fuzz_card/testfile2 diff --git a/src/tests/fuzzing/corpus/fuzz_card/testfile2 b/src/tests/fuzzing/corpus/fuzz_card/testfile2 deleted file mode 100644 index cd45339239403e506605749b623e759b05151fe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1432 zcmZQ%fB*#{2J6~s3=9p14XGQN1%=l%GfZG$V#pd3f6>O zkcoxC1R`x>#_&P(BjYE=&jPsN7sjuQ-vqxi{9^dc@Q2|q!#{{#pebC8AeSY6_{0FT zm7$WE$)O;i$c&GHA!09sj^tKFMX)d<({HBVKzSfo0K}DyO#hhvfp~EKU#7n(e4wEy zd`2clBt8ox1C$FfkA)EkP~@2yp$04f1qP!5g8@Vuq#npm5J2M_pz;f>rP`f$1Dsc?L#S0VXykW(P*bKtV^Kf1Fqu9{E4PJeA@mp(sWo2#cX2%}I?TqTu#TwkR4T3W^ENp3%=s2u;Mt+s}n&l7X#ZQZx zGJW=}@T3#T2UsUP6iX{RS?>6VwW3<8OS+?};>@8My?=UKaq|?bi)i#Z-=+Pdw zX>4k2Zfpqxs^_vZSe{5pNzRU%73C%=5`4IfMc?Gc`GA8Ce2>IFPPm|8e_g>g{G#Uy@BpIU3a@9l-Sn@f)tJTJM-(rjhMmur?V zDJeZAMbk*bU_*L<9(O>@NhN^{4mxR`@{6e;Ow|?2wzF*5f`Rr7& zeHWv*EzkIM?WB6Wm)W&vdi|5Lf9-dEHSfcpFKf%fT(?(j-}7z$_J?a%tY6!6Z{uuR z-Idp0g&nKpD6TCmw4Jd#^IhRIbwRQFTKDc6eO()V`IPDJ&`lN&C7Z*-r@a#Yy>(~U L!pJ0 Date: Sat, 14 May 2022 22:41:50 +0200 Subject: [PATCH 2460/4321] Fix integer overflow Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46736 --- src/libopensc/errors.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 03cb79dd1f..358c600335 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -30,6 +30,7 @@ const char *sc_strerror(int error) { + unsigned int error_index = 0; const char *rdr_errors[] = { "Generic reader error", "No readers found", @@ -49,7 +50,7 @@ const char *sc_strerror(int error) "Reader reattached", "Reader in use by another application" }; - const int rdr_base = -SC_ERROR_READER; + const unsigned int rdr_base = -SC_ERROR_READER; const char *card_errors[] = { "Card command failed", @@ -74,7 +75,7 @@ const char *sc_strerror(int error) "End of file/record reached before reading Le bytes", "Reference data not usable" }; - const int card_base = -SC_ERROR_CARD_CMD_FAILED; + const unsigned int card_base = -SC_ERROR_CARD_CMD_FAILED; const char *arg_errors[] = { "Invalid arguments", @@ -84,7 +85,7 @@ const char *sc_strerror(int error) "Invalid PIN length", "Invalid data", }; - const int arg_base = -SC_ERROR_INVALID_ARGUMENTS; + const unsigned int arg_base = -SC_ERROR_INVALID_ARGUMENTS; const char *int_errors[] = { "Internal error", @@ -107,7 +108,7 @@ const char *sc_strerror(int error) "Invalid Simple TLV object", "Premature end of Simple TLV stream", }; - const int int_base = -SC_ERROR_INTERNAL; + const unsigned int int_base = -SC_ERROR_INTERNAL; const char *p15i_errors[] = { "Generic PKCS#15 initialization error", @@ -122,7 +123,7 @@ const char *sc_strerror(int error) "Invalid PIN reference", "File too small", }; - const int p15i_base = -SC_ERROR_PKCS15INIT; + const unsigned int p15i_base = -SC_ERROR_PKCS15INIT; const char *sm_errors[] = { "Generic Secure Messaging error", @@ -139,54 +140,53 @@ const char *sc_strerror(int error) "SM session already active", "Invalid checksum" }; - const int sm_base = -SC_ERROR_SM; + const unsigned int sm_base = -SC_ERROR_SM; const char *misc_errors[] = { "Unknown error", "PKCS#15 compatible smart card not found", }; - const int misc_base = -SC_ERROR_UNKNOWN; + const unsigned int misc_base = -SC_ERROR_UNKNOWN; const char *no_errors = "Success"; const char **errors = NULL; - int count = 0, err_base = 0; + unsigned int count = 0, err_base = 0; if (!error) return no_errors; - if (error < 0) - error = -error; + error_index = error < 0 ? -error : error; - if (error >= misc_base) { + if (error_index >= misc_base) { errors = misc_errors; count = DIM(misc_errors); err_base = misc_base; - } else if (error >= sm_base) { + } else if (error_index >= sm_base) { errors = sm_errors; count = DIM(sm_errors); err_base = sm_base; - } else if (error >= p15i_base) { + } else if (error_index >= p15i_base) { errors = p15i_errors; count = DIM(p15i_errors); err_base = p15i_base; - } else if (error >= int_base) { + } else if (error_index >= int_base) { errors = int_errors; count = DIM(int_errors); err_base = int_base; - } else if (error >= arg_base) { + } else if (error_index >= arg_base) { errors = arg_errors; count = DIM(arg_errors); err_base = arg_base; - } else if (error >= card_base) { + } else if (error_index >= card_base) { errors = card_errors; count = DIM(card_errors); err_base = card_base; - } else if (error >= rdr_base) { + } else if (error_index >= rdr_base) { errors = rdr_errors; count = DIM(rdr_errors); err_base = rdr_base; } - error -= err_base; - if (error >= count || count == 0) + error_index -= err_base; + if (error_index >= count || count == 0) return misc_errors[0]; - return errors[error]; + return errors[error_index]; } From 45b599995c3a9d6a7f066e6f81fb61b43964d2de Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 16 May 2022 20:25:00 +0200 Subject: [PATCH 2461/4321] fuzz_card: Remove unneeded test for sc_reset() As it calls operation from the reader. --- src/tests/fuzzing/fuzz_card.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c index d7e249223d..665dce98bd 100644 --- a/src/tests/fuzzing/fuzz_card.c +++ b/src/tests/fuzzing/fuzz_card.c @@ -38,7 +38,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) uint8_t len = 0; u8 *rnd = NULL, *wrap_buf = NULL, *unwrap_buf = NULL; size_t wrap_buf_len = 0, unwrap_buf_len = 0; - int reset = 0, r = 0; + int r = 0; #ifdef FUZZING_ENABLED fclose(stdout); @@ -93,10 +93,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) /* Append record */ sc_append_record(card, ptr, ptr_size, flag); - /* Reset card */ - reset = (*data) < 128 ? 1 : 0; - sc_reset(card, reset); - err: free(rnd); free(wrap_buf); From b349ad5b98fab0410f37fa5d7208770a40559b11 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 17 May 2022 15:25:19 +0200 Subject: [PATCH 2462/4321] Remove unneeded condition --- src/libopensc/errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 358c600335..08fe9e060e 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -186,7 +186,7 @@ const char *sc_strerror(int error) err_base = rdr_base; } error_index -= err_base; - if (error_index >= count || count == 0) + if (error_index >= count) return misc_errors[0]; return errors[error_index]; } From c2e00e9071952b30ed6d58d9b7670eb3d93ea6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 20 May 2022 14:26:44 +0300 Subject: [PATCH 2463/4321] pkcs11-session: fix C_GetSessionInfo in 'atomic' mode The device is always in logged-out mode with PIN cached, so ignore the logged-in check. Since the token is now guaranteed to be logged-in or have sessions removed, simplify the further checks to match the session state. Fixes: 4bd8cda96604 "pkcs11-session: When we notice logout in lower layers..." --- src/pkcs11/pkcs11-session.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 7fb9cb361b..e938818376 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -252,7 +252,6 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_RV rv; struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; - int logged_out; const char *name; if (pInfo == NULL_PTR) @@ -276,16 +275,16 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ pInfo->ulDeviceError = 0; slot = session->slot; - logged_out = (slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT); - if (logged_out && slot->login_user >= 0) { + if (!sc_pkcs11_conf.atomic && slot->login_user >= 0 && + slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT) { slot->login_user = -1; sc_pkcs11_close_all_sessions(session->slot->id); rv = CKR_SESSION_HANDLE_INVALID; goto out; } - if (slot->login_user == CKU_SO && !logged_out) { + if (slot->login_user == CKU_SO) { pInfo->state = CKS_RW_SO_FUNCTIONS; - } else if ((slot->login_user == CKU_USER && !logged_out) || (!(slot->token_info.flags & CKF_LOGIN_REQUIRED))) { + } else if (slot->login_user == CKU_USER || !(slot->token_info.flags & CKF_LOGIN_REQUIRED)) { pInfo->state = (session->flags & CKF_RW_SESSION) ? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS; } else { From b134623713057c672e40bbe91af2c8ac94a859c3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 1 Jun 2022 11:49:43 +0200 Subject: [PATCH 2464/4321] iso-sm: check for maximum receive length avoids PC/SC sending SCARD_E_INSUFFICIENT_BUFFER, see https://github.com/LudovicRousseau/PCSC/issues/137 --- src/sm/sm-iso.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 2c3f6bcabd..bfc1d57f52 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -477,9 +477,13 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, if (apdu->cse & SC_APDU_EXT) { sm_apdu->cse = SC_APDU_CASE_4_EXT; sm_apdu->resplen = 4 + 2 + mac_len + 2 + 3 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length; + if (sm_apdu->resplen > SC_MAX_EXT_APDU_RESP_SIZE) + sm_apdu->resplen = SC_MAX_EXT_APDU_RESP_SIZE; } else { sm_apdu->cse = SC_APDU_CASE_4_SHORT; sm_apdu->resplen = 4 + 2 + mac_len + 2 + 2 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length; + if (sm_apdu->resplen > SC_MAX_APDU_RESP_SIZE) + sm_apdu->resplen = SC_MAX_APDU_RESP_SIZE; } resp_data = calloc(sm_apdu->resplen, 1); if (!resp_data) { From 972d3292eee44e9b4c61769365a3ec651ec18f39 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 20 Jun 2022 12:33:48 +0200 Subject: [PATCH 2465/4321] cardos: fixed reading file information blocks (#2561) fixes Stack-buffer-overflow READ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47035 --- src/libopensc/card-cardos.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 8cec82e72d..51f4ed4c25 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -496,7 +496,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) { sc_apdu_t apdu; u8 rbuf[256], offset = 0; - const u8 *p = rbuf, *q; + const u8 *p = rbuf, *q, *tag; int r; size_t fids = 0, len; @@ -525,15 +525,17 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) while (len != 0) { size_t tlen = 0, ilen = 0; /* is there a file information block (0x6f) ? */ - p = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen); - if (p == NULL) { + tag = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen); + if (tag == NULL) { sc_log(card->ctx, "directory tag missing"); return SC_ERROR_INTERNAL; } + len = len - tlen - (tag - p); + p = tag + tlen; if (tlen == 0) /* empty directory */ break; - q = sc_asn1_find_tag(card->ctx, p, tlen, 0x86, &ilen); + q = sc_asn1_find_tag(card->ctx, tag, tlen, 0x86, &ilen); if (q == NULL || ilen != 2) { sc_log(card->ctx, "error parsing file id TLV object"); return SC_ERROR_INTERNAL; @@ -547,13 +549,11 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) /* not enough space left in buffer => break */ break; /* extract next offset */ - q = sc_asn1_find_tag(card->ctx, p, tlen, 0x8a, &ilen); + q = sc_asn1_find_tag(card->ctx, tag, tlen, 0x8a, &ilen); if (q != NULL && ilen == 1) { offset = (u8)ilen; goto get_next_part; } - len -= tlen + 2; - p += tlen; } r = fids; From 92d1486e1eb03752a064af20bb718654beaac7d9 Mon Sep 17 00:00:00 2001 From: MkfsSion Date: Mon, 23 May 2022 22:38:22 +0800 Subject: [PATCH 2466/4321] framework-pkcs15: Fix use after free issue * Newly created pkcs15 secret key object is freed upon success, * which maybe used if user calls other PKCS11 functions * (like C_DestroyObject) and causes use after free issue. Co-authored-by: Hannu Honkanen Signed-off-by: MkfsSion --- src/pkcs11/framework-pkcs15.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 0903ccb502..156d9da31f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2576,7 +2576,9 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile out: free(args.key.data); /* if allocated */ - if (temp_object) + + /* on error, free key_obj, unless it's created by pkcs15init. if OK, let it live as part of key_any_obj. */ + if (rv != CKR_OK && temp_object) free(key_obj); /* do not free if the object was created by pkcs15init. It will be freed in C_Finalize */ return rv; } From 56d1abee4d35bf4a90ebb2bebb417890c534aec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Tue, 21 Dec 2021 15:31:11 +0200 Subject: [PATCH 2467/4321] myeid: support logout operation --- src/libopensc/card-myeid.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 1483a80315..a12eb3f472 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -427,6 +427,21 @@ static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path LOG_FUNC_RETURN(card->ctx, r); } +static int myeid_logout(struct sc_card *card) +{ + sc_apdu_t apdu; + int r; + + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x00, 0x00 /*pin ref: 0x01-0x0E, 0=ALL*/); + apdu.cla = 0; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen) { @@ -1820,6 +1835,7 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.update_record = NULL; myeid_ops.select_file = myeid_select_file; myeid_ops.get_response = iso_ops->get_response; + myeid_ops.logout = myeid_logout; myeid_ops.create_file = myeid_create_file; myeid_ops.delete_file = myeid_delete_file; myeid_ops.list_files = myeid_list_files; From 331abb3faeee4fdfca4b269af11ea55acd6372d8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 9 Jun 2022 14:27:40 +0200 Subject: [PATCH 2468/4321] pkcs15-muscle.c: Free file Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47677 --- src/pkcs15init/pkcs15-muscle.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 626f801b23..228e2df33e 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -101,10 +101,13 @@ muscle_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if ((r = sc_select_file(p15card->card, &df->path, &file)) < 0) return r; - if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_WRITE)) < 0) + if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_WRITE)) < 0) { + sc_file_free(file); return r; + } auth_info->attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; + sc_file_free(file); return 0; } From aa6bc38d6d0d6cafc4e4b05cdeb16ed8de01062b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Jun 2022 14:56:13 +0200 Subject: [PATCH 2469/4321] Do not overwrite pointer After allocating memory in do_content() called from process_command(), process_block(), the pointer was overwritten in the next loop process_block(), when the file is coppied in process_ef() into new state via new_file(). This happens since file ident is "". Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46787 --- src/pkcs15init/profile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 9c0e886975..3df31fbfef 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1431,6 +1431,9 @@ do_content(struct state *cur, int argc, char **argv) } file = cur->file->file; + if (file->encoded_content) + free(file->encoded_content); + file->encoded_content = malloc(len); if (!file->encoded_content) return 1; From 150f6274fd2a882bc3f240a89057ff655782f9af Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Jun 2022 15:43:01 +0200 Subject: [PATCH 2470/4321] Free ecpoint data in case of failure Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46855 --- src/libopensc/pkcs15-pubkey.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 6982ccee97..9d1e522a2b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -646,11 +646,17 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); - if (r < 0) + if (r < 0) { + if (ecpoint_data) + free(ecpoint_data); LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); + } - if (ecpoint_len == 0 || *ecpoint_data != 0x04) + if (ecpoint_len == 0 || *ecpoint_data != 0x04) { + if (ecpoint_data) + free(ecpoint_data); LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); + } key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; From 0863f2a2e70c5462e099f8a930b587f0d0526221 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 14 Jun 2022 14:44:21 +0200 Subject: [PATCH 2471/4321] Fix integer overflow Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46736 --- src/libopensc/errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 08fe9e060e..bd5ed085f3 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -154,7 +154,7 @@ const char *sc_strerror(int error) if (!error) return no_errors; - error_index = error < 0 ? -error : error; + error_index = error < 0 ? -((long long int) error) : error; if (error_index >= misc_base) { errors = misc_errors; From 27e3db8b142522d7367cc446283fb07d855443d7 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 29 Jun 2022 16:04:41 +0200 Subject: [PATCH 2472/4321] Get length of so_pin Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47521 --- src/tests/fuzzing/fuzz_pkcs11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index 2b46223c90..e9aa71d8fd 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -225,7 +225,7 @@ static void test_init_pin(const unsigned char *data, size_t size) if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK) goto end; p11->C_GetTokenInfo(0, &info); - p11->C_Login(session, login_type, (CK_UTF8CHAR *) so_pin, so_pin == NULL ? 0 : strlen(pin)); + p11->C_Login(session, login_type, (CK_UTF8CHAR *) so_pin, so_pin == NULL ? 0 : strlen(so_pin)); p11->C_InitPIN(session, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin)); p11->C_CloseSession(session); From a558d5d5c0ad39f5a4da20c58b5994ce4d9a39f9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 30 Jun 2022 10:07:42 +0200 Subject: [PATCH 2473/4321] fuzz_pkcs11: Free card if not bind Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47524 --- src/tests/fuzzing/fuzz_pkcs11.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index e9aa71d8fd..b2a4c985e9 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -56,7 +56,7 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t struct sc_reader *reader = NULL; struct sc_app_info *app_generic = NULL; sc_pkcs11_slot_t *slot = NULL; - int rv = CKR_OK; + int rv = CKR_OK, free_p11card = 0; /* Erase possible virtual slots*/ list_clear(&virtual_slots); @@ -91,6 +91,7 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t /* Create p11card */ p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card)); p11card->reader = reader; + free_p11card = 1; /* Connect card to reader */ if ((rv = sc_connect_card(reader, &p11card->card)) != SC_SUCCESS) { @@ -117,6 +118,7 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t rv = p11card->framework->create_tokens(p11card, app_generic); if (rv != CKR_OK) goto fail; + free_p11card = 0; } /* Bind rest of application*/ @@ -133,12 +135,14 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t if (rv != CKR_OK) { goto fail; } + free_p11card = 0; } if (slot_out) *slot_out = slot; - return CKR_OK; fail: - sc_pkcs11_card_free(p11card); + if (free_p11card) { + sc_pkcs11_card_free(p11card); + } return rv; } #endif From 3065bb803e10af08352f4eb7c2056f6a5a21efa8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 30 Jun 2022 10:40:41 +0200 Subject: [PATCH 2474/4321] piv-tool: Free RSA key Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47634 --- src/tools/piv-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 6b1182a829..fddb41a1d2 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -362,6 +362,9 @@ static int gen_key(const char * key_info) fprintf(stderr, "gen_key failed %d\n", r); free(keydata.pubkey); EVP_PKEY_free(evpkey); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(newkey); +#endif return -1; } @@ -379,6 +382,7 @@ static int gen_key(const char * key_info) if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { fprintf(stderr, "gen_key unable to set RSA values"); EVP_PKEY_free(evpkey); + RSA_free(newkey); return -1; } From 367c3ad2ef2c10cb29602f72163e7fb23c3f5827 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 30 Jun 2022 13:42:29 +0200 Subject: [PATCH 2475/4321] pkcs15-myeid: Path buffer overflow Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47655 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47769 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48000 --- src/pkcs15init/pkcs15-myeid.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 75652f6e9f..6105c8b850 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -417,6 +417,10 @@ myeid_new_file(sc_profile_t *profile, sc_card_t *card, file->id += num; p = &file->path; *p = profile->df_info->file->path; + if (p->len >= SC_MAX_PATH_SIZE) { + sc_log(card->ctx, "Wrong path length"); + return SC_ERROR_INTERNAL; + } p->value[p->len++] = (u8) (file->id / 256); p->value[p->len++] = (u8) (file->id % 256); @@ -598,8 +602,10 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = myeid_new_file(profile, card, object->type, *key_reference, &file); LOG_TEST_RET(ctx, r, "Cannot get new MyEID key file"); - if (!file || !file->path.len) + if (!file || !file->path.len || file->path.len > SC_MAX_PATH_SIZE) { + sc_file_free(file); LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot determine key file"); + } sc_log(ctx, "Key file size %d", keybits); file->size = keybits; From d1a3039c350bf081cae132d6ffc1781d01fd55c6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 1 Jul 2022 11:16:48 +0200 Subject: [PATCH 2476/4321] Fix buffer overflow Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47676 --- src/tools/pkcs15-tool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index fff93ab782..20fcba7804 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1961,8 +1961,11 @@ static int test_update(sc_card_t *in_card) } /* other tag */ i += 2 + rbuf[2+i+1]; /* length of this tag*/ + if (2+i+1 >= apdu.resplen) { + break; + } } - if (rbuf[2+i+1] < 9 || 2+i+2+9 > apdu.resplen) { + if (2+i+1 >= apdu.resplen || rbuf[2+i+1] < 9 || 2+i+2+9 > apdu.resplen) { printf("select file returned short fci\n"); goto bad_fci; } From f974627fc9ac734fa7e82b844e32b4d525700a05 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Jul 2022 11:06:40 +0200 Subject: [PATCH 2477/4321] card-muscle: Mark file for deletion Fixes stack-overflow from recursion, when the same files is matched instead of child file Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46848 --- src/libopensc/card-muscle.c | 8 +++++++- src/libopensc/muscle-filesystem.h | 1 + src/pkcs15init/pkcs15-muscle.c | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 3a0075d559..512f9df16d 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -270,6 +270,7 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) msc_id id = file_data->objectId; u8* oid = id.id; int r; + file_data->deleteFile = 1; if(!file_data->ef) { int x; @@ -285,13 +286,14 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) childFile = &fs->cache.array[x]; objectId = childFile->objectId; - if(0 == memcmp(oid + 2, objectId.id, 2)) { + if(0 == memcmp(oid + 2, objectId.id, 2) && !childFile->deleteFile) { sc_log(card->ctx, "DELETING: %02X%02X%02X%02X\n", objectId.id[0],objectId.id[1], objectId.id[2],objectId.id[3]); r = muscle_delete_mscfs_file(card, childFile); if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); + } } oid[0] = oid[2]; @@ -322,6 +324,10 @@ static int muscle_delete_file(sc_card_t *card, const sc_path_t *path_in) r = mscfs_loadFileInfo(fs, path_in->value, path_in->len, &file_data, NULL); if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); + for(int x = 0; x < fs->cache.size; x++) { + mscfs_file_t *file = &fs->cache.array[x]; + file->deleteFile = 0; + } r = muscle_delete_mscfs_file(card, file_data); mscfs_clear_cache(fs); if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); diff --git a/src/libopensc/muscle-filesystem.h b/src/libopensc/muscle-filesystem.h index 3978843b41..59243711d7 100644 --- a/src/libopensc/muscle-filesystem.h +++ b/src/libopensc/muscle-filesystem.h @@ -34,6 +34,7 @@ typedef struct mscfs_file { size_t size; unsigned short read, write, delete; int ef; + int deleteFile; } mscfs_file_t; typedef struct mscfs_cache { diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 228e2df33e..f827ff5d45 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -53,6 +53,7 @@ static int muscle_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) sc_file_free(file); return r; } + sc_file_free(file); if ((r = sc_delete_file(p15card->card, &path)) < 0) return r; return 0; From 1e37d171d1cfb253f9c724a8276f8c06855a8b54 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Jul 2022 15:31:10 +0200 Subject: [PATCH 2478/4321] fuzzer_tool: Limit number of arguments Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48702 --- src/tests/fuzzing/fuzzer_tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/fuzzing/fuzzer_tool.c b/src/tests/fuzzing/fuzzer_tool.c index aaa487ea62..a395e5efe6 100644 --- a/src/tests/fuzzing/fuzzer_tool.c +++ b/src/tests/fuzzing/fuzzer_tool.c @@ -20,6 +20,7 @@ */ #include "fuzzer_tool.h" +#define MAX_ARGC 10000 const uint8_t *get_word(const uint8_t *data, size_t size) { @@ -70,6 +71,9 @@ int get_fuzzed_argv(const char *app_name, const uint8_t *data, size_t size, help_ptr = ptr; } + if (argc > MAX_ARGC) + return -1; + argv = malloc((argc + 1) * sizeof(char*)); if (!argv) return -1; From 3afb3f4e007e896e3c818bbacbe909795022a34e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Jul 2022 16:20:39 +0200 Subject: [PATCH 2479/4321] pkcs15-pubkey: Initialize pointer to NULL --- src/libopensc/pkcs15-pubkey.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 9d1e522a2b..9aceea64e7 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -638,7 +638,7 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, const u8 *buf, size_t buflen) { int r; - u8 * ecpoint_data; + u8 * ecpoint_data = NULL; size_t ecpoint_len; struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; @@ -647,14 +647,12 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); if (r < 0) { - if (ecpoint_data) - free(ecpoint_data); + free(ecpoint_data); LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); } if (ecpoint_len == 0 || *ecpoint_data != 0x04) { - if (ecpoint_data) - free(ecpoint_data); + free(ecpoint_data); LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); } From 2762c44a96fbc4a49799cc79c983c0bbfd89857e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 4 Jul 2022 16:30:30 +0200 Subject: [PATCH 2480/4321] Remove unneeded NULL check --- src/pkcs15init/profile.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 3df31fbfef..8e072eb874 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1431,8 +1431,7 @@ do_content(struct state *cur, int argc, char **argv) } file = cur->file->file; - if (file->encoded_content) - free(file->encoded_content); + free(file->encoded_content); file->encoded_content = malloc(len); if (!file->encoded_content) From 187fa1a254b088b5ed4d74f3050baf5d4c5c6286 Mon Sep 17 00:00:00 2001 From: joseph Date: Thu, 7 Jul 2022 09:03:52 +0900 Subject: [PATCH 2481/4321] pkcs11-tool: Make it selectable as a label when set-id Fixes #1994 --- src/tools/pkcs11-tool.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a96c3d27e4..5a134ea895 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -547,6 +547,11 @@ static int write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); static int delete_object(CK_SESSION_HANDLE session); static void set_id_attr(CK_SESSION_HANDLE session); +static int find_object_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, + CK_OBJECT_HANDLE_PTR ret, + const unsigned char *, size_t id_len, + const char *, + int obj_index); static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); @@ -1446,8 +1451,8 @@ int main(int argc, char * argv[]) if (do_set_id) { if (opt_object_class_str == NULL) util_fatal("You should specify the object type with the -y option"); - if (opt_object_id_len == 0) - util_fatal("You should specify the current ID with the -d option"); + if (opt_object_id_len == 0 && opt_object_label == NULL) + util_fatal("You should specify the current object with the -d or -a option"); set_id_attr(session); } @@ -4386,8 +4391,8 @@ static void set_id_attr(CK_SESSION_HANDLE session) CK_ATTRIBUTE templ[] = {{CKA_ID, new_object_id, new_object_id_len}}; CK_RV rv; - if (!find_object(session, opt_object_class, &obj, opt_object_id, opt_object_id_len, 0)) { - fprintf(stderr, "set_id(): couldn't find the object\n"); + if (!find_object_id_or_label(session, opt_object_class, &obj, opt_object_id, opt_object_id_len, opt_object_label, 0)) { + fprintf(stderr, "set_id(): couldn't find the object by id %s label\n", (opt_object_label && opt_object_id_len) ? "and" : "or"); return; } @@ -4450,11 +4455,13 @@ static int find_slot_by_token_label(const char *label, CK_SLOT_ID_PTR result) } -static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, +static int find_object_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, CK_OBJECT_HANDLE_PTR ret, - const unsigned char *id, size_t id_len, int obj_index) + const unsigned char *id, size_t id_len, + const char *label, + int obj_index) { - CK_ATTRIBUTE attrs[2]; + CK_ATTRIBUTE attrs[3]; unsigned int nattrs = 0; CK_ULONG count; CK_RV rv; @@ -4464,12 +4471,18 @@ static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, attrs[0].pValue = &cls; attrs[0].ulValueLen = sizeof(cls); nattrs++; - if (id) { + if (id && id_len) { attrs[nattrs].type = CKA_ID; attrs[nattrs].pValue = (void *) id; attrs[nattrs].ulValueLen = id_len; nattrs++; } + if (label) { + attrs[nattrs].type = CKA_LABEL; + attrs[nattrs].pValue = (void *) label; + attrs[nattrs].ulValueLen = strlen(label); + nattrs++; + } rv = p11->C_FindObjectsInit(sess, attrs, nattrs); if (rv != CKR_OK) @@ -4486,13 +4499,21 @@ static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, if (rv != CKR_OK) p11_fatal("C_FindObjects", rv); -done: if (count == 0) +done: + if (count == 0) *ret = CK_INVALID_HANDLE; p11->C_FindObjectsFinal(sess); return count; } +static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, + CK_OBJECT_HANDLE_PTR ret, + const unsigned char *id, size_t id_len, int obj_index) +{ + return find_object_id_or_label(sess, cls, ret, id, id_len, NULL, obj_index); +} + static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len, int obj_index) From d85ac12a7b10d6b2f7f58f3c5e69af892d116c35 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 27 Apr 2022 14:22:02 +0200 Subject: [PATCH 2482/4321] Add support for ext APDU, PSS Padding, disable path caching, fix logout --- src/libopensc/card-starcos.c | 173 ++++++++++++++++++++++++++++------- 1 file changed, 142 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 80c5823f9a..6187504b94 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -281,7 +281,24 @@ static unsigned int starcos_determine_pin_encoding(sc_card_t *card) return encoding; } - +/** + * Returns 1 if an extended APDU can be sent to the card + * with the given card reader. Otherwise returns 0. + */ +static int starcos_probe_reader_for_ext_apdu(sc_card_t * card) { + sc_apdu_t apdu; + int rv; + u8 data[260]; + + // Get Data: Get Chip Serial Number + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0xCA, 0x9F, 0x6C); + apdu.cla = 0xA0; + apdu.resp = data; + apdu.resplen = sizeof(data); + apdu.le = apdu.datalen; + rv = sc_transmit_apdu(card, &apdu); + return ( rv == SC_SUCCESS ); +} static int starcos_init(sc_card_t *card) { @@ -310,18 +327,14 @@ static int starcos_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) - card->name = "STARCOS 3.4"; - else - card->name = "STARCOS 3.5"; - card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; card->caps |= SC_CARD_CAP_APDU_EXT; flags |= SC_CARD_FLAG_RNG | SC_ALGORITHM_RSA_HASH_SHA224 | SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA384 - | SC_ALGORITHM_RSA_HASH_SHA512; + | SC_ALGORITHM_RSA_HASH_SHA512 + | SC_ALGORITHM_RSA_PAD_PSS; _sc_card_add_rsa_alg(card, 512, flags, 0x10001); _sc_card_add_rsa_alg(card, 768, flags, 0x10001); @@ -329,6 +342,15 @@ static int starcos_init(sc_card_t *card) _sc_card_add_rsa_alg(card,1728, flags, 0x10001); _sc_card_add_rsa_alg(card,1976, flags, 0x10001); _sc_card_add_rsa_alg(card,2048, flags, 0x10001); + if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + card->name = "STARCOS 3.4"; + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + } else { + card->name = "STARCOS 3.5"; + _sc_card_add_rsa_alg(card,3072, flags, 0x10001); + } + card->max_send_size = 255; + card->max_recv_size = 256; } else { _sc_card_add_rsa_alg(card, 512, flags, 0x10001); _sc_card_add_rsa_alg(card, 768, flags, 0x10001); @@ -349,6 +371,13 @@ static int starcos_init(sc_card_t *card) if (card->ef_atr->max_command_apdu > 0) { card->max_send_size = card->ef_atr->max_command_apdu; } + if ( card->caps & SC_CARD_CAP_APDU_EXT && card->max_send_size > 255 && card->max_recv_size ) { + // probe reader for extended APDU support + if ( !starcos_probe_reader_for_ext_apdu(card) ) { + sc_log(card->ctx, "Failed probing extended APDU, reset caps"); + card->caps &= ~(SC_CARD_CAP_APDU_EXT); + } + } } if ( ex_data->pin_encoding == PIN_ENCODING_DETERMINE ) { @@ -827,9 +856,12 @@ static int starcos_select_file(sc_card_t *card, sc_file_t **file_out) { u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - int r; + int r, pathtype; size_t i, pathlen; char pbuf[SC_MAX_PATH_STRING_SIZE]; + /* option for path caching, it is deactivated by default, + but it can be enabled by setting cache_valid to option: card->cache.valid */ + int cache_valid = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -841,23 +873,50 @@ static int starcos_select_file(sc_card_t *card, "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", - card->cache.valid ? "valid" : "invalid", pbuf, + cache_valid ? "valid" : "invalid", pbuf, card->cache.current_path.len); + if ( in_path->len > sizeof(pathbuf) ) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); + } memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; + pathtype = in_path->type; - if (in_path->type == SC_PATH_TYPE_FILE_ID) + if (in_path->aid.len) { + if (!pathlen) { + if ( in_path->aid.len > sizeof(pathbuf) ) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); + } + memcpy(path, in_path->aid.value, in_path->aid.len); + pathlen = in_path->aid.len; + pathtype = SC_PATH_TYPE_DF_NAME; + } else { + if (!cache_valid + || card->cache.current_path.type != SC_PATH_TYPE_DF_NAME + || card->cache.current_path.len != pathlen + || memcmp(card->cache.current_path.value, in_path->aid.value, in_path->aid.len) != 0 ) { + r = starcos_select_aid(card, in_path->aid.value, in_path->aid.len, file_out); + LOG_TEST_RET(card->ctx, r, "Could not select AID!"); + } + + if (pathtype == SC_PATH_TYPE_DF_NAME) { + pathtype = SC_PATH_TYPE_FILE_ID; + } + } + } + + if (pathtype == SC_PATH_TYPE_FILE_ID) { /* SELECT EF/DF with ID */ /* Select with 2byte File-ID */ if (pathlen != 2) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); return starcos_select_fid(card, path[0], path[1], file_out, 1); } - else if (in_path->type == SC_PATH_TYPE_DF_NAME) - { /* SELECT DF with AID */ + else if (pathtype == SC_PATH_TYPE_DF_NAME) + { /* SELECT DF with AID */ /* Select with 1-16byte Application-ID */ - if (card->cache.valid + if (cache_valid && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME && card->cache.current_path.len == pathlen && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) @@ -868,7 +927,7 @@ static int starcos_select_file(sc_card_t *card, else return starcos_select_aid(card, pathbuf, pathlen, file_out); } - else if (in_path->type == SC_PATH_TYPE_PATH) + else if (pathtype == SC_PATH_TYPE_PATH) { u8 n_pathbuf[SC_MAX_PATH_SIZE]; int bMatch = -1; @@ -899,7 +958,7 @@ static int starcos_select_file(sc_card_t *card, } /* check current working directory */ - if (card->cache.valid + if (cache_valid && card->cache.current_path.type == SC_PATH_TYPE_PATH && card->cache.current_path.len >= 2 && card->cache.current_path.len <= pathlen ) @@ -919,7 +978,7 @@ static int starcos_select_file(sc_card_t *card, } } - if ( card->cache.valid && bMatch >= 0 ) + if ( cache_valid && bMatch >= 0 ) { if ( pathlen - bMatch == 2 ) /* we are in the right directory */ @@ -1525,13 +1584,14 @@ static int starcos_set_security_env(sc_card_t *card, if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { - if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || + u8 algorithm_supported = (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || + (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS); + if (!algorithm_supported || !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } - /* don't know what these mean but doesn't matter as card seems to take - * algorithm / cipher from PKCS#1 padding prefix */ + /* Tag '84' (length 1) denotes key name or key reference */ *p++ = 0x84; *p++ = 0x01; if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { @@ -1545,16 +1605,29 @@ static int starcos_set_security_env(sc_card_t *card, sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); /* algorithm / cipher selector? */ + /* algorithm: 13.23 PKCS#1 signature with RSA (standard) */ + /* algorithm: 13.33.30 PKCS#1-PSS signature with SHA-256 */ *p++ = 0x89; - *p++ = 0x02; - *p++ = 0x13; - *p++ = 0x23; + if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) { + *p++ = 0x03; + *p++ = 0x13; + *p++ = 0x33; + *p++ = 0x30; + } else { + // fall back, RSA PKCS1 Padding + *p++ = 0x02; + *p++ = 0x13; + *p++ = 0x23; + } break; case SC_SEC_OPERATION_DECIPHER: sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); /* algorithm / cipher selector? */ + /* algorithm: 11.3 Encipherment RSA (standard) */ + /* algorithm: 11.31 Encipherment RSA (standard) with PKCS#1 padding */ + /* algorithm: 11.32 Encipherment RSA OAEP padding */ *p++ = 0x89; *p++ = 0x02; *p++ = 0x11; @@ -1719,12 +1792,25 @@ static int starcos_compute_signature(sc_card_t *card, if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { size_t tmp_len; + u8 apdu_case; + size_t apdu_le; + + apdu_le = outlen; + /* RSA signatures with greater than 2048 bitlength require extended APDU, + Note SC_CARD_CAP_APDU_EXT cap was probed during card initialization */ + if (card->caps & SC_CARD_CAP_APDU_EXT) { + apdu_case = SC_APDU_CASE_4_EXT; + } + else { + apdu_case = SC_APDU_CASE_4_SHORT; + apdu_le = 0x00; /* allow max for short APDU (256) */ + } - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, + sc_format_apdu(card, &apdu, apdu_case, 0x2A, 0x9E, 0x9A); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 0; + apdu.resp = out; + apdu.resplen = outlen; + apdu.le = apdu_le; if (ex_data->fix_digestInfo) { // need to pad data unsigned int flags = ex_data->fix_digestInfo & SC_ALGORITHM_RSA_HASHES; @@ -1732,7 +1818,11 @@ static int starcos_compute_signature(sc_card_t *card, flags = SC_ALGORITHM_RSA_HASH_NONE; } tmp_len = sizeof(sbuf); - r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8, NULL); + if (ex_data->fix_digestInfo & SC_ALGORITHM_RSA_PAD_PSS) { + r = sc_pkcs1_strip_digest_info_prefix(NULL, data, datalen, sbuf, &tmp_len); + } else { + r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8, NULL); + } LOG_TEST_RET(card->ctx, r, "sc_pkcs1_encode failed"); } else { memcpy(sbuf, data, datalen); @@ -1742,9 +1832,7 @@ static int starcos_compute_signature(sc_card_t *card, apdu.data = sbuf; apdu.datalen = tmp_len; apdu.lc = tmp_len; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 0; + r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); } else { @@ -1778,7 +1866,10 @@ static int starcos_compute_signature(sc_card_t *card, } if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; - memcpy(out, apdu.resp, len); + /* Note: no local buffer was used for extended APDU */ + if ( out != apdu.resp ) { + memcpy(out, apdu.resp, len); + } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len); } } else if (ex_data->sec_ops == SC_SEC_OPERATION_AUTHENTICATE) { @@ -2011,12 +2102,32 @@ static int starcos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) } } +/** + * starcos_logout_v3_x() + * StarCOS 3.x cards will not clear the security status by selecting MF. + * Returning NOT_SUPPORTED would cause card reset, effectively invalidating + * the security status. + */ +static int starcos_logout_v3_x(sc_card_t *card) +{ + int r = SC_ERROR_NOT_SUPPORTED; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); + + starcos_pin_clear_logged_in(card); + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + static int starcos_logout(sc_card_t *card) { int r; sc_apdu_t apdu; const u8 mf_buf[2] = {0x3f, 0x00}; + if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + return starcos_logout_v3_x(card); + } + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x0C); apdu.le = 0; apdu.lc = 2; From 9c5a880ea089b090cd8db44568fbe98e7667e843 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 27 Apr 2022 14:22:55 +0200 Subject: [PATCH 2483/4321] Add PKCS15 Emulator for StarCOS 3.x ESign apps --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-starcos.c | 71 +++--- src/libopensc/pkcs15-starcos-esign.c | 363 +++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 1 + src/libopensc/pkcs15-syn.h | 1 + 6 files changed, 408 insertions(+), 34 deletions(-) create mode 100644 src/libopensc/pkcs15-starcos-esign.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index cd5bafb468..16209a4b53 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -59,7 +59,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - compression.c sm.c \ + pkcs15-starcos-esign.c compression.c sm.c \ aux-data.c if ENABLE_CRYPTOTOKENKIT @@ -142,7 +142,7 @@ TIDY_FILES = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - compression.c sm.c \ + pkcs15-starcos-esign.c compression.c sm.c \ aux-data.c \ #$(SOURCES) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index cafd2c28e7..d1961b1d84 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -37,7 +37,7 @@ OBJECTS = \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ - compression.obj sm.obj \ + pkcs15-starcos-esign.obj compression.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 6187504b94..e5e2478d1b 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -85,6 +85,12 @@ typedef struct starcos_ex_data_st { unsigned int pin_encoding; } starcos_ex_data; +/* + This constant allows signing or + decrypting with RSA keys up to 4096 bits. +*/ +#define STARCOS3X_PROBE_APDU_LENGTH 512 + #define PIN_ENCODING_DETERMINE 0 #define PIN_ENCODING_DEFAULT SC_PIN_ENCODING_GLP @@ -288,14 +294,15 @@ static unsigned int starcos_determine_pin_encoding(sc_card_t *card) static int starcos_probe_reader_for_ext_apdu(sc_card_t * card) { sc_apdu_t apdu; int rv; - u8 data[260]; + /* try to read STARCOS3X_PROBE_APDU_LENGTH bytes */ + u8 data[STARCOS3X_PROBE_APDU_LENGTH]; - // Get Data: Get Chip Serial Number + /* Get Data: Get Chip Serial Number */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0xCA, 0x9F, 0x6C); apdu.cla = 0xA0; apdu.resp = data; apdu.resplen = sizeof(data); - apdu.le = apdu.datalen; + apdu.le = apdu.resplen; rv = sc_transmit_apdu(card, &apdu); return ( rv == SC_SUCCESS ); } @@ -327,7 +334,6 @@ static int starcos_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { - card->caps |= SC_CARD_CAP_APDU_EXT; flags |= SC_CARD_FLAG_RNG | SC_ALGORITHM_RSA_HASH_SHA224 @@ -362,20 +368,39 @@ static int starcos_init(sc_card_t *card) } if (sc_parse_ef_atr(card) == SC_SUCCESS) { - if (card->ef_atr->card_capabilities & ISO7816_CAP_EXTENDED_LENGTH) { - card->caps |= SC_CARD_CAP_APDU_EXT; + size_t max_recv_size = 0; + size_t max_send_size = 0; + + /* Add max. length values from IAS/ECC specific issuer data */ + if ( card->ef_atr->issuer_data_len >= 4 ) { + max_recv_size = bebytes2ushort(card->ef_atr->issuer_data); + max_send_size = bebytes2ushort(card->ef_atr->issuer_data + 2); } + /* which could be overridden with ISO7816 EF.ATR options, if present */ if (card->ef_atr->max_response_apdu > 0) { - card->max_recv_size = card->ef_atr->max_response_apdu; + max_recv_size = card->ef_atr->max_response_apdu; } if (card->ef_atr->max_command_apdu > 0) { - card->max_send_size = card->ef_atr->max_command_apdu; + max_send_size = card->ef_atr->max_command_apdu; } - if ( card->caps & SC_CARD_CAP_APDU_EXT && card->max_send_size > 255 && card->max_recv_size ) { - // probe reader for extended APDU support - if ( !starcos_probe_reader_for_ext_apdu(card) ) { - sc_log(card->ctx, "Failed probing extended APDU, reset caps"); + + if ( max_send_size > 256 && max_recv_size > 256 ) { + size_t max_recv_size_prev = card->max_recv_size; + size_t max_send_size_prev = card->max_send_size; + /* allow SC_CARD_CAP_APDU_EXT independent of ef_atr->caps, see IAS/ECC issuer data above */ + card->caps |= SC_CARD_CAP_APDU_EXT; + /* the received data should not exceed max_recv_size including the sw1/sw2 */ + card->max_recv_size = max_recv_size - 2; + /* the sent APDU should not exceed max_send_size including the 4 bytes of the APDU and 2 * 3 bytes Lc/Le */ + card->max_send_size = max_send_size - 10; + /* probe reader for extended APDU support */ + if ( starcos_probe_reader_for_ext_apdu(card) ) { + sc_log(card->ctx, "Successfully probed extended APDU, enabling extended APDU with max send/recv %ld/%ld", max_send_size, max_recv_size); + } else { card->caps &= ~(SC_CARD_CAP_APDU_EXT); + card->max_recv_size = max_recv_size_prev; + card->max_send_size = max_send_size_prev; + sc_log(card->ctx, "Ext APDU probing failed, the actual reader does not support ext APDU"); } } } @@ -666,7 +691,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, } static int starcos_select_aid(sc_card_t *card, - u8 aid[16], size_t len, + const u8 aid[16], size_t len, sc_file_t **file_out) { sc_apdu_t apdu; @@ -1792,25 +1817,12 @@ static int starcos_compute_signature(sc_card_t *card, if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { size_t tmp_len; - u8 apdu_case; - size_t apdu_le; - - apdu_le = outlen; - /* RSA signatures with greater than 2048 bitlength require extended APDU, - Note SC_CARD_CAP_APDU_EXT cap was probed during card initialization */ - if (card->caps & SC_CARD_CAP_APDU_EXT) { - apdu_case = SC_APDU_CASE_4_EXT; - } - else { - apdu_case = SC_APDU_CASE_4_SHORT; - apdu_le = 0x00; /* allow max for short APDU (256) */ - } - sc_format_apdu(card, &apdu, apdu_case, 0x2A, + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x9E, 0x9A); apdu.resp = out; apdu.resplen = outlen; - apdu.le = apdu_le; + apdu.le = outlen; if (ex_data->fix_digestInfo) { // need to pad data unsigned int flags = ex_data->fix_digestInfo & SC_ALGORITHM_RSA_HASHES; @@ -1866,7 +1878,6 @@ static int starcos_compute_signature(sc_card_t *card, } if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { size_t len = apdu.resplen > outlen ? outlen : apdu.resplen; - /* Note: no local buffer was used for extended APDU */ if ( out != apdu.resp ) { memcpy(out, apdu.resp, len); } @@ -2113,8 +2124,6 @@ static int starcos_logout_v3_x(sc_card_t *card) int r = SC_ERROR_NOT_SUPPORTED; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); - starcos_pin_clear_logged_in(card); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } diff --git a/src/libopensc/pkcs15-starcos-esign.c b/src/libopensc/pkcs15-starcos-esign.c new file mode 100644 index 0000000000..11702f16e1 --- /dev/null +++ b/src/libopensc/pkcs15-starcos-esign.c @@ -0,0 +1,363 @@ +/** + * PKCS15 emulation layer for Giesecke & Devrient StarCOS 3.x cards + * with eSign application + * + * Copyright (C) 2022, jozsefd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "common/compat_strlcpy.h" +#include "internal.h" +#include "log.h" +#include "pkcs15.h" +#include "cards.h" + +#include +#include + +/* compile time option: define ENABLE_ESIGN_ISSUER_CONTAINERS to enable containers holding the issuer certificates */ + +static const char name_Card[] = "ESIGN"; +static const char name_Vendor[] = "Giesecke & Devrient"; +static const char name_ESign[] = "ESIGN"; +static const unsigned char aid_ESIGN[] = {0xA0, 0x00, 0x00, 0x02, 0x45, 0x53, 0x69, 0x67, 0x6E}; + +typedef struct cdata_st { + const char *label; + int authority; + const char *path; + const char *id; + int obj_flags; +} cdata, *pcdata; + +typedef struct pdata_st { + const char *id; + const char *label; + const char *path; + int ref; + int type; + unsigned int maxlen; + unsigned int minlen; + unsigned int storedlen; + int flags; + int tries_left; + int max_tries; + const char pad_char; + int obj_flags; +} pindata, *ppindata; + +typedef struct prdata_st { + const char *id; + const char *label; + unsigned int modulus_len; + int usage; + const char *path; + int ref; + const char *auth_id; + int obj_flags; +} prdata, *pprdata; + +typedef struct container_st { + const char *id; + const pcdata certdata; + const ppindata pindata; + const pprdata prdata; +} container; + +#define USAGE_NONREP SC_PKCS15_PRKEY_USAGE_NONREPUDIATION +#define USAGE_KE SC_PKCS15_PRKEY_USAGE_ENCRYPT | \ + SC_PKCS15_PRKEY_USAGE_DECRYPT | \ + SC_PKCS15_PRKEY_USAGE_WRAP | \ + SC_PKCS15_PRKEY_USAGE_UNWRAP +#define USAGE_AUT SC_PKCS15_PRKEY_USAGE_ENCRYPT | \ + SC_PKCS15_PRKEY_USAGE_DECRYPT | \ + SC_PKCS15_PRKEY_USAGE_WRAP | \ + SC_PKCS15_PRKEY_USAGE_UNWRAP | \ + SC_PKCS15_PRKEY_USAGE_SIGN +#define USER_PIN SC_PKCS15_PIN_FLAG_INITIALIZED | \ + SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | \ + SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL | \ + SC_PKCS15_PIN_AUTH_TYPE_PIN + +static int +get_cert_size(sc_card_t *card, sc_path_t *path, size_t *psize) +{ + int r; + sc_file_t *file = NULL; + + r = sc_select_file(card, path, &file); + LOG_TEST_RET(card->ctx, r, "Failed to select EF certificate"); + + *psize = file->size; + sc_file_free(file); + + return SC_SUCCESS; +} + +static int +add_app(sc_pkcs15_card_t *p15card, const container *containers, int container_count) +{ + int i, containers_added = 0, r = SC_SUCCESS; + ppindata installed_pins[4]; + size_t installed_pin_count = 0; + sc_card_t *card = p15card->card; + + LOG_FUNC_CALLED(card->ctx); + + for (i = 0; i < container_count; i++) { + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + size_t cert_size; + + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + sc_pkcs15_format_id(containers[i].id, &cert_info.id); + cert_info.authority = containers[i].certdata->authority; + sc_format_path(containers[i].certdata->path, &cert_info.path); + + r = get_cert_size(card, &cert_info.path, &cert_size); + if ( r != SC_SUCCESS ) { + sc_log(card->ctx, "Failed to determine size of certificate %s, ignoring container", containers[i].certdata->label); + continue; + } + + strlcpy(cert_obj.label, containers[i].certdata->label, sizeof(cert_obj.label)); + cert_obj.flags = containers[i].certdata->obj_flags; + + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + LOG_TEST_RET(card->ctx, r, "Failed to add certificate"); + + if (containers[i].pindata != 0) { + size_t j; + int is_pin_installed = 0; + + /* A pin object could be used by more than 1 container, ensure it is added only once */ + for (j = 0; j < installed_pin_count; j++) { + if (installed_pins[j] == containers[i].pindata) { + is_pin_installed = 1; + break; + } + } + + if (!is_pin_installed) { + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + + if (installed_pin_count < (int)(sizeof(installed_pins) / sizeof(ppindata))) { + installed_pins[installed_pin_count++] = containers[i].pindata; + } else { + sc_log(card->ctx, "Warning: cannot add more than 4 pins"); + continue; + } + + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + sc_pkcs15_format_id(containers[i].pindata->id, &pin_info.auth_id); + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.reference = containers[i].pindata->ref; + pin_info.attrs.pin.flags = containers[i].pindata->flags; + pin_info.attrs.pin.type = containers[i].pindata->type; + pin_info.attrs.pin.min_length = containers[i].pindata->minlen; + pin_info.attrs.pin.stored_length = containers[i].pindata->storedlen; + pin_info.attrs.pin.max_length = containers[i].pindata->maxlen; + pin_info.attrs.pin.pad_char = containers[i].pindata->pad_char; + if (containers[i].pindata->path != NULL) + sc_format_path(containers[i].pindata->path, &pin_info.path); + pin_info.tries_left = -1; + pin_info.max_tries = containers[i].pindata->max_tries; + + strlcpy(pin_obj.label, containers[i].pindata->label, sizeof(pin_obj.label)); + pin_obj.flags = containers[i].pindata->obj_flags; + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + LOG_TEST_RET(card->ctx, r, "Failed to add PIN object"); + } + } + + if (containers[i].prdata != 0) { + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + int modulus_len = containers[i].prdata->modulus_len; + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + sc_pkcs15_format_id(containers[i].id, &prkey_info.id); + prkey_info.usage = containers[i].prdata->usage; + prkey_info.native = 1; + prkey_info.key_reference = containers[i].prdata->ref; + prkey_info.modulus_length = modulus_len; + sc_format_path(containers[i].prdata->path, &prkey_info.path); + + strlcpy(prkey_obj.label, containers[i].prdata->label, sizeof(prkey_obj.label)); + prkey_obj.flags = containers[i].prdata->obj_flags; + if (containers[i].prdata->auth_id) { + sc_pkcs15_format_id(containers[i].prdata->auth_id, &prkey_obj.auth_id); + } + + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + LOG_TEST_RET(card->ctx, r, "Failed to add RSA prkey"); + } + + containers_added++; + } + + if (containers_added == 0) { + r = SC_ERROR_INVALID_CARD; + } else { + r = SC_SUCCESS; + } + + LOG_FUNC_RETURN(card->ctx, r); +} + +/* + * adds the PKCS15 objects of the ESIGN application. The app may contain + * 1) Authentication container + * - 2048-bit RSA key + * - CH certificate + * 2) Encryption container + * - 2048-bit RSA key + * - CH certificate + * 3) Authentication Issuer container + * - issuer certificate + * 3) Encryption Issuer container + * - issuer certificate + * Depending on the card profile, some containers may be missing. + * Both RSA keys are protected with the UserPIN. The app may have a PUK, not + * supported by this emulator. + * + * The issuer certificates are not included by default, define ENABLE_ESIGN_ISSUER_CONTAINERS + * to enable them. + */ +static int +starcos_add_esign_app(sc_pkcs15_card_t *p15card) +{ + static cdata auth_cert = {"C.CH.AUT", 0, "3F00060843F1", "1", 0}; + static cdata encr_cert = {"C.CH.ENC", 0, "3F0006084301", "2", 0}; +#ifdef ENABLE_ESIGN_ISSUER_CONTAINERS + const cdata auth_root_cert = { "C.RootCA_Auth", 1, "3F00060843F0", "3", 0 }; + const cdata encr_root_cert = { "C.RootCA_Enc", 1, "3F0006084300", "4", 0 }; +#endif + + static prdata auth_key = {"1", "PrK.CH.AUT", 2048, USAGE_AUT, "3F000608", 0x81, "1", SC_PKCS15_CO_FLAG_PRIVATE}; + static prdata encr_key = {"2", "PrK.CH.ENC", 2048, USAGE_KE, "3F000608", 0x83, "1", SC_PKCS15_CO_FLAG_PRIVATE}; + + static pindata auth_pin = {"1", "UserPIN", "3F00", 0x01, SC_PKCS15_PIN_TYPE_UTF8, 16, 6, 0, + USER_PIN, -1, 3, 0x00, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE}; + + static pindata auth_pin_v35 = {"1", "UserPIN", "3F00", 0x06, SC_PKCS15_PIN_TYPE_UTF8, 16, 6, 0, + USER_PIN, -1, 3, 0x00, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE}; + + ppindata auth = (p15card->card->type == SC_CARD_TYPE_STARCOS_V3_5) ? &auth_pin_v35 : &auth_pin; + + const container containers[] = { + {"1", &auth_cert, auth, &auth_key}, + {"2", &encr_cert, auth, &encr_key}, +#ifdef ENABLE_ESIGN_ISSUER_CONTAINERS + { "3", &auth_root_cert, 0, 0 }, + { "4", &encr_root_cert, 0, 0 }, +#endif + }; + + return add_app(p15card, containers, sizeof(containers) / sizeof(container)); +} + +static int +starcos_esign_init(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + const char *label = name_Card; + int r; + int apps_added = 0; + + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); + + if (card->type != SC_CARD_TYPE_STARCOS_V3_4 && card->type != SC_CARD_TYPE_STARCOS_V3_5) { + return SC_ERROR_WRONG_CARD; + } + + if (aid == NULL) { + // no aid: in this case all emulated apps are added, currently only the esign_app + r = starcos_add_esign_app(p15card); + if (r == SC_SUCCESS) + apps_added++; + } else { + // aid specified: only the matching app is added + if (aid->len == sizeof(aid_ESIGN) && memcmp(aid->value, aid_ESIGN, sizeof(aid_ESIGN)) == 0) { + r = starcos_add_esign_app(p15card); + if (r == SC_SUCCESS) { + label = name_ESign; + apps_added++; + } + } + + if (apps_added > 0) { + // pkcs11 requires the file_app + struct sc_path path; + struct sc_file *file = NULL; + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid->value, aid->len, 0, 0); + r = sc_select_file(card, &path, &file); + if (r != SC_SUCCESS || !file) + return SC_ERROR_INTERNAL; + sc_file_free(p15card->file_app); + p15card->file_app = file; + } + } + + if (apps_added == 0) { + LOG_TEST_RET(ctx, SC_ERROR_WRONG_CARD, "No supported app found on this card"); + } + + sc_pkcs15_free_tokeninfo(p15card->tokeninfo); + + p15card->tokeninfo = sc_pkcs15_tokeninfo_new(); + if (!p15card->tokeninfo) { + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "unable to create tokeninfo struct"); + } else { + sc_serial_number_t serial; + char serial_hex[SC_MAX_SERIALNR * 2 + 2]; + r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + LOG_TEST_RET(ctx, r, "Failed to query card serial number"); + + r = sc_bin_to_hex(serial.value, serial.len, serial_hex, sizeof serial_hex, 0); + LOG_TEST_RET(ctx, r, "Failed to convert S/N to hex"); + p15card->tokeninfo->serial_number = strdup(serial_hex); + p15card->tokeninfo->label = strdup(label); + p15card->tokeninfo->manufacturer_id = strdup(name_Vendor); + p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; + } + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + +int +sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + int r = SC_ERROR_WRONG_CARD; + + if (!p15card || !p15card->card || !p15card->card->ctx) + return SC_ERROR_INVALID_ARGUMENTS; + + r = starcos_esign_init(p15card, aid); + LOG_FUNC_RETURN(p15card->card->ctx, r); +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index f4ed6087ac..7d3855f994 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -58,6 +58,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, { "cardos", sc_pkcs15emu_cardos_init_ex }, { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, + { "esign", sc_pkcs15emu_starcos_esign_init_ex }, { NULL, NULL } }; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index 36c0018c15..af7257ae9e 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -56,6 +56,7 @@ int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_idprime_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_cardos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From 2b01d2b963295332f2db1877090061dfbe675019 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 18 May 2022 14:59:21 +0200 Subject: [PATCH 2484/4321] Add eSign profile specific types STARCOS_V3_x_ESIGN --- src/libopensc/card-starcos.c | 112 +++++++++++++++++---------- src/libopensc/cards.h | 2 + src/libopensc/pkcs15-starcos-esign.c | 4 +- src/libopensc/pkcs15-syn.c | 2 + 4 files changed, 78 insertions(+), 42 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index e5e2478d1b..1cbdb86e51 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -45,7 +45,7 @@ static const struct sc_atr_table starcos_atrs[] = { { "3B:D9:96:FF:81:31:FE:45:80:31:B8:73:86:01:E0:81:05:22", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, { "3B:D0:97:FF:81:B1:FE:45:1F:07:2B", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, { "3B:D0:96:FF:81:B1:FE:45:1F:07:2A", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_4, 0, NULL }, - { "3b:df:96:ff:81:31:fe:45:80:5b:44:45:2e:42:41:5f:53:43:33:35:32:81:05:b5", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5, 0, NULL }, + { "3b:df:96:ff:81:31:fe:45:80:5b:44:45:2e:42:41:5f:53:43:33:35:32:81:05:b5", NULL, NULL, SC_CARD_TYPE_STARCOS_V3_5_ESIGN, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -113,6 +113,11 @@ typedef struct starcos_ex_data_st { } \ } while (0); +/* card type helpers */ +#define IS_V34(card) card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_4_ESIGN +#define IS_V35(card) card->type == SC_CARD_TYPE_STARCOS_V3_5 || card->type == SC_CARD_TYPE_STARCOS_V3_5_ESIGN +#define IS_V3x(card) IS_V34(card) || IS_V35(card) + /* the starcos part */ static int starcos_match_card(sc_card_t *card) { @@ -263,9 +268,9 @@ static unsigned int starcos_determine_pin_encoding(sc_card_t *card) unsigned int pin_format = PIN_FORMAT_DEFAULT; unsigned int encoding = PIN_ENCODING_DETERMINE; - if ( card->type == SC_CARD_TYPE_STARCOS_V3_4 ) { + if ( IS_V34(card) ) { starcos_determine_pin_format34(card, &pin_format); - } else if ( card->type == SC_CARD_TYPE_STARCOS_V3_5 ) { + } else if ( IS_V35(card) ) { starcos_determine_pin_format35(card, &pin_format); } @@ -304,6 +309,45 @@ static int starcos_probe_reader_for_ext_apdu(sc_card_t * card) { apdu.resplen = sizeof(data); apdu.le = apdu.resplen; rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "Failed to send Get Data ext. APDU"); + return (apdu.sw1 == 0x90 && apdu.sw2 == 0x00); +} + +static int starcos_select_mf(sc_card_t * card) { + sc_apdu_t apdu; + const u8 mf_buf[2] = {0x3f, 0x00}; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x0C); + apdu.le = 0; + apdu.lc = 2; + apdu.data = mf_buf; + apdu.datalen = 2; + apdu.resplen = 0; + + return sc_transmit_apdu(card, &apdu); +} + +static int starcos_select_aid(sc_card_t *card, + const u8 aid[16], size_t len, + sc_file_t **file_out); + +/* returns 1 if the card has the eSign app with AID A0:00:00:02:45:53:69:67:6E + otherwise returns 0 + */ +static int starcos_has_esign_app(sc_card_t * card) { + + static u8 esign_aid[SC_MAX_PATH_SIZE] = { 0xA0, 0x00, 0x00, 0x02, 0x45, 0x53, 0x69, 0x67, 0x6E }; + int rv; + + rv = starcos_select_mf(card); + if ( rv == SC_SUCCESS ) { + sc_file_t * file; + rv = starcos_select_aid(card, esign_aid, 9, &file); + sc_file_free(file); + if ( rv == SC_SUCCESS ) { + starcos_select_mf(card); + } + } return ( rv == SC_SUCCESS ); } @@ -332,8 +376,7 @@ static int starcos_init(sc_card_t *card) card->caps = SC_CARD_CAP_RNG; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { flags |= SC_CARD_FLAG_RNG | SC_ALGORITHM_RSA_HASH_SHA224 @@ -348,7 +391,7 @@ static int starcos_init(sc_card_t *card) _sc_card_add_rsa_alg(card,1728, flags, 0x10001); _sc_card_add_rsa_alg(card,1976, flags, 0x10001); _sc_card_add_rsa_alg(card,2048, flags, 0x10001); - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) { + if ( IS_V34(card) ) { card->name = "STARCOS 3.4"; card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; } else { @@ -395,7 +438,8 @@ static int starcos_init(sc_card_t *card) card->max_send_size = max_send_size - 10; /* probe reader for extended APDU support */ if ( starcos_probe_reader_for_ext_apdu(card) ) { - sc_log(card->ctx, "Successfully probed extended APDU, enabling extended APDU with max send/recv %ld/%ld", max_send_size, max_recv_size); + sc_log(card->ctx, "Successfully probed extended APDU, enabling extended APDU with max send/recv %d/%d", + (int)card->max_send_size, (int)card->max_recv_size); } else { card->caps &= ~(SC_CARD_CAP_APDU_EXT); card->max_recv_size = max_recv_size_prev; @@ -410,6 +454,11 @@ static int starcos_init(sc_card_t *card) ex_data->pin_encoding = starcos_determine_pin_encoding(card); } + if ( card->type == SC_CARD_TYPE_STARCOS_V3_4 && starcos_has_esign_app(card) ) { + card->type = SC_CARD_TYPE_STARCOS_V3_4_ESIGN; + sc_log(card->ctx, "Card has eSign app, card type changed to %d", card->type); + } + return 0; } @@ -756,8 +805,7 @@ static int starcos_select_fid(sc_card_t *card, apdu.data = (u8*)data; apdu.datalen = 2; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { if (id_hi == 0x3f && id_lo == 0x0) { apdu.p1 = 0x0; apdu.p2 = 0x0; @@ -785,8 +833,7 @@ static int starcos_select_fid(sc_card_t *card, apdu.le = 0; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); - } else if ((card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) + } else if ((IS_V3x(card)) && apdu.p2 == 0x4 && apdu.sw1 == 0x6a && apdu.sw2 == 0x82) { /* not a file, could be a path */ bIsDF = 1; @@ -851,8 +898,7 @@ static int starcos_select_fid(sc_card_t *card, *file_out = file; } else { /* ok, assume we have a EF */ - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { if (isFCP) { r = process_fcp_v3_4(card->ctx, file, apdu.resp, apdu.resplen); @@ -969,8 +1015,7 @@ static int starcos_select_file(sc_card_t *card, if (pathlen == 6 && ( path[0] != 0x3f || path[1] != 0x00 )) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - if (card->type != SC_CARD_TYPE_STARCOS_V3_4 - && card->type != SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { /* unify path (the first FID should be MF) */ if (path[0] != 0x3f || path[1] != 0x00) { @@ -994,8 +1039,7 @@ static int starcos_select_file(sc_card_t *card, && card->cache.current_path.value[i+1] == path[i+1] ) bMatch += 2; - if ((card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) + if ((IS_V3x(card)) && bMatch > 0 && (size_t) bMatch < card->cache.current_path.len) { /* we're in the wrong folder, start traversing from root */ bMatch = 0; @@ -1607,8 +1651,7 @@ static int starcos_set_security_env(sc_card_t *card, p = sbuf; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { u8 algorithm_supported = (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS); if (!algorithm_supported || @@ -1656,7 +1699,7 @@ static int starcos_set_security_env(sc_card_t *card, *p++ = 0x89; *p++ = 0x02; *p++ = 0x11; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4) + if ( IS_V34(card) ) *p++ = 0x30; else *p++ = 0x31; @@ -1814,8 +1857,7 @@ static int starcos_compute_signature(sc_card_t *card, if (ex_data->sec_ops == SC_SEC_OPERATION_SIGN) { /* compute signature with the COMPUTE SIGNATURE command */ - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { size_t tmp_len; sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, @@ -1959,8 +2001,7 @@ static int starcos_decipher(struct sc_card *card, } } - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 - || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { sc_apdu_t apdu; u8 *sbuf = malloc(crgram_len + 1); @@ -2046,18 +2087,14 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) return SC_SUCCESS; } - switch (card->type) { - case SC_CARD_TYPE_STARCOS_V3_4: - case SC_CARD_TYPE_STARCOS_V3_5: + if ( IS_V3x(card) ) { card->serialnr.len = SC_MAX_SERIALNR; r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); if (r < 0) { card->serialnr.len = 0; return r; } - break; - - default: + } else { /* get serial number via GET CARD DATA */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00); apdu.cla |= 0x80; @@ -2073,7 +2110,6 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) /* cache serial number */ memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); - break; } /* copy and return serial number */ @@ -2133,7 +2169,7 @@ static int starcos_logout(sc_card_t *card) sc_apdu_t apdu; const u8 mf_buf[2] = {0x3f, 0x00}; - if (card->type == SC_CARD_TYPE_STARCOS_V3_4 || card->type == SC_CARD_TYPE_STARCOS_V3_5) { + if ( IS_V3x(card) ) { return starcos_logout_v3_x(card); } @@ -2163,15 +2199,11 @@ static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, LOG_FUNC_CALLED(card->ctx); starcos_ex_data * ex_data = (starcos_ex_data*)card->drv_data; - switch (card->type) { - case SC_CARD_TYPE_STARCOS_V3_4: - case SC_CARD_TYPE_STARCOS_V3_5: - data->flags |= SC_PIN_CMD_NEED_PADDING; - data->pin1.encoding = ex_data->pin_encoding; - /* fall through */ - default: - r = iso_ops->pin_cmd(card, data, tries_left); + if ( IS_V3x(card) ) { + data->flags |= SC_PIN_CMD_NEED_PADDING; + data->pin1.encoding = ex_data->pin_encoding; } + r = iso_ops->pin_cmd(card, data, tries_left); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index a508fa6d29..3e3f8dd268 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -90,6 +90,8 @@ enum { SC_CARD_TYPE_STARCOS_GENERIC, SC_CARD_TYPE_STARCOS_V3_4, SC_CARD_TYPE_STARCOS_V3_5, + SC_CARD_TYPE_STARCOS_V3_4_ESIGN, + SC_CARD_TYPE_STARCOS_V3_5_ESIGN, /* tcos driver */ SC_CARD_TYPE_TCOS_BASE = 8000, diff --git a/src/libopensc/pkcs15-starcos-esign.c b/src/libopensc/pkcs15-starcos-esign.c index 11702f16e1..62322eca1b 100644 --- a/src/libopensc/pkcs15-starcos-esign.c +++ b/src/libopensc/pkcs15-starcos-esign.c @@ -267,7 +267,7 @@ starcos_add_esign_app(sc_pkcs15_card_t *p15card) static pindata auth_pin_v35 = {"1", "UserPIN", "3F00", 0x06, SC_PKCS15_PIN_TYPE_UTF8, 16, 6, 0, USER_PIN, -1, 3, 0x00, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE}; - ppindata auth = (p15card->card->type == SC_CARD_TYPE_STARCOS_V3_5) ? &auth_pin_v35 : &auth_pin; + ppindata auth = (p15card->card->type == SC_CARD_TYPE_STARCOS_V3_5_ESIGN) ? &auth_pin_v35 : &auth_pin; const container containers[] = { {"1", &auth_cert, auth, &auth_key}, @@ -292,7 +292,7 @@ starcos_esign_init(sc_pkcs15_card_t *p15card, struct sc_aid *aid) SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); - if (card->type != SC_CARD_TYPE_STARCOS_V3_4 && card->type != SC_CARD_TYPE_STARCOS_V3_5) { + if (card->type != SC_CARD_TYPE_STARCOS_V3_4_ESIGN && card->type != SC_CARD_TYPE_STARCOS_V3_5_ESIGN) { return SC_ERROR_WRONG_CARD; } diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 7d3855f994..c4e99b97e4 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -107,6 +107,8 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_CARDOS_V5_0: case SC_CARD_TYPE_CARDOS_V5_3: case SC_CARD_TYPE_NQ_APPLET: + case SC_CARD_TYPE_STARCOS_V3_4_ESIGN: + case SC_CARD_TYPE_STARCOS_V3_5_ESIGN: return 1; default: From 9ac0583e91b1b59bd9dc55b2376ff0be944afe55 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Tue, 14 Jun 2022 17:22:49 +0200 Subject: [PATCH 2485/4321] Remove magic number in starcos_has_esign_app() --- src/libopensc/card-starcos.c | 52 +++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 1cbdb86e51..406b3abd90 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -335,14 +335,18 @@ static int starcos_select_aid(sc_card_t *card, otherwise returns 0 */ static int starcos_has_esign_app(sc_card_t * card) { - - static u8 esign_aid[SC_MAX_PATH_SIZE] = { 0xA0, 0x00, 0x00, 0x02, 0x45, 0x53, 0x69, 0x67, 0x6E }; + static const char * starcos_esign_aid = "A0:00:00:02:45:53:69:67:6E"; int rv; rv = starcos_select_mf(card); if ( rv == SC_SUCCESS ) { sc_file_t * file; - rv = starcos_select_aid(card, esign_aid, 9, &file); + u8 aid[SC_MAX_PATH_SIZE]; + size_t len = sizeof(aid); + + rv = sc_hex_to_bin(starcos_esign_aid, aid, &len); + LOG_TEST_RET(card->ctx, rv, "Failed to convert eSing AID"); + rv = starcos_select_aid(card, aid, len, &file); sc_file_free(file); if ( rv == SC_SUCCESS ) { starcos_select_mf(card); @@ -2088,28 +2092,28 @@ static int starcos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) } if ( IS_V3x(card) ) { - card->serialnr.len = SC_MAX_SERIALNR; - r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); - if (r < 0) { - card->serialnr.len = 0; - return r; - } + card->serialnr.len = SC_MAX_SERIALNR; + r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); + if (r < 0) { + card->serialnr.len = 0; + return r; + } } else { - /* get serial number via GET CARD DATA */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00); - apdu.cla |= 0x80; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - apdu.lc = 0; - apdu.datalen = 0; - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) - return SC_ERROR_INTERNAL; - /* cache serial number */ - memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); - card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); + /* get serial number via GET CARD DATA */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00); + apdu.cla |= 0x80; + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + apdu.lc = 0; + apdu.datalen = 0; + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + return SC_ERROR_INTERNAL; + /* cache serial number */ + memcpy(card->serialnr.value, apdu.resp, MIN(apdu.resplen, SC_MAX_SERIALNR)); + card->serialnr.len = MIN(apdu.resplen, SC_MAX_SERIALNR); } /* copy and return serial number */ From ca4d63ecf625a9c01f2829089a9b2b121a6ea59d Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 15 Jun 2022 14:44:22 +0200 Subject: [PATCH 2486/4321] Fix crash reported by CIFuzz in starcos_has_esign_app() --- src/libopensc/card-starcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 406b3abd90..90b339ecf0 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -347,8 +347,8 @@ static int starcos_has_esign_app(sc_card_t * card) { rv = sc_hex_to_bin(starcos_esign_aid, aid, &len); LOG_TEST_RET(card->ctx, rv, "Failed to convert eSing AID"); rv = starcos_select_aid(card, aid, len, &file); - sc_file_free(file); if ( rv == SC_SUCCESS ) { + sc_file_free(file); starcos_select_mf(card); } } From fa378dadb5ee62c5dc1119639ddae797c166a08f Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 15 Jun 2022 15:23:17 +0200 Subject: [PATCH 2487/4321] Fix CIFuzz crash in starcos_has_esign_app() --- src/libopensc/card-starcos.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 90b339ecf0..ffe4238bb1 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -340,15 +340,13 @@ static int starcos_has_esign_app(sc_card_t * card) { rv = starcos_select_mf(card); if ( rv == SC_SUCCESS ) { - sc_file_t * file; u8 aid[SC_MAX_PATH_SIZE]; size_t len = sizeof(aid); rv = sc_hex_to_bin(starcos_esign_aid, aid, &len); LOG_TEST_RET(card->ctx, rv, "Failed to convert eSing AID"); - rv = starcos_select_aid(card, aid, len, &file); + rv = starcos_select_aid(card, aid, len, NULL); if ( rv == SC_SUCCESS ) { - sc_file_free(file); starcos_select_mf(card); } } From fae908729155d378acb62edba933a51c49bc39ed Mon Sep 17 00:00:00 2001 From: Claus Steuer <108525640+swissbit-csteuer@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:15:00 +0200 Subject: [PATCH 2488/4321] Update the actions/virtual-environments#4589 workaround --- .github/setup-linux.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 1c253be605..ea96030b6b 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -44,7 +44,10 @@ fi # The Github's Ubuntu images since 20211122.1 are broken # https://github.com/actions/virtual-environments/issues/4589 if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then - sudo apt install -y --allow-downgrades libpcre2-8-0=10.34-7 + sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list + sudo apt-get update -qq + sudo apt-get install -yqq --allow-downgrades libgd3/focal libpcre2-8-0/focal libpcre2-16-0/focal libpcre2-32-0/focal libpcre2-posix2/focal + sudo apt-get purge -yqq libmono* moby* mono* php* libgdiplus libpcre2-posix3 libzip4 fi # make sure we do not get prompts From ec808839dc421b4a65ace5212e8f584f86297d9c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 09:01:01 +0200 Subject: [PATCH 2489/4321] profile: Avoid recursion in macro expansion Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48752 --- src/pkcs15init/profile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 8e072eb874..b9e6724cf4 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2000,6 +2000,9 @@ build_argv(struct state *cur, const char *cmdname, return SC_ERROR_SYNTAX_ERROR; } + if (list == mac->value) { + return SC_ERROR_SYNTAX_ERROR; + } #ifdef DEBUG_PROFILE { scconf_list *list; From 2b2ad1276dc878482172185b3ee3ce15a9ef50c9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 09:14:51 +0200 Subject: [PATCH 2490/4321] framework-pkcs15: Check token label for NULL Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48764 --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 156d9da31f..03723294c9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1175,7 +1175,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, if (pin_len) { size_t tokeninfo_len = 0; - if (p15card->tokeninfo) + if (p15card->tokeninfo && p15card->tokeninfo->label) tokeninfo_len = strlen(p15card->tokeninfo->label); /* Print the possibly truncated token label with at least 4 * characters followed by the PIN label in parenthesis */ From b0f962aa6fcd3dc2788d6cf2678d0f87b5bd02c2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 09:31:11 +0200 Subject: [PATCH 2491/4321] pkcs15-lib: Free allocated buffer Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48792 --- src/pkcs15init/pkcs15-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e10312b771..4ea694862a 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3177,6 +3177,8 @@ sc_pkcs15init_update_lastupdate(struct sc_pkcs15_card *p15card, struct sc_profil LOG_TEST_RET(ctx, r, "select object path failed"); r = sc_select_file(p15card->card, &last_update->path, &file); + if (r < 0) + free(buf); LOG_TEST_RET(ctx, r, "select object path failed"); r = sc_pkcs15init_update_file(profile, p15card, file, buf, buflen); From 3cd7e44447cd64ca7168647e3f7149eacd57025c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 11:13:37 +0200 Subject: [PATCH 2492/4321] fuzz_pkcs15_encode: Check return value Coverity 374853 --- src/tests/fuzzing/fuzz_pkcs15_encode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c index 073a041cfc..eb3436dae2 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_encode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c @@ -44,8 +44,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) if (fuzz_connect_card(ctx, &card, NULL, Data, Size) != SC_SUCCESS) goto err; - sc_pkcs15_bind(card, NULL, &p15card); - if (!p15card) + if (sc_pkcs15_bind(card, NULL, &p15card) != 0) goto err; for (obj = p15card->obj_list; obj != NULL; obj = obj->next) { From b550e572754e597b7963796e1c535f0b085e0e89 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 11:34:13 +0200 Subject: [PATCH 2493/4321] framework-pkcs15: Free allocated mechanism In the case, when mechanism `mt` is allocated and is directly assigned to `sign_type`, it needs to be freed at the end of block. Freeing `mt` does not affect registered mechanism, as the `sc_pkcs11_register_sign_and_hash_mechanism` works with copy. Coverity 374844 --- src/pkcs11/framework-pkcs15.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 03723294c9..379d209712 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5913,6 +5913,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags, } } } + sc_pkcs11_free_mechanism(&mt); #endif } From 21ae5f6eeed693cdbfef3cf9e921bcc7929ef3df Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 14:15:35 +0200 Subject: [PATCH 2494/4321] pkcs15-myeid: Free file Coverity 379254 OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49084 --- src/pkcs15init/pkcs15-myeid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 6105c8b850..a6f0dfbc1a 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -419,6 +419,7 @@ myeid_new_file(sc_profile_t *profile, sc_card_t *card, *p = profile->df_info->file->path; if (p->len >= SC_MAX_PATH_SIZE) { sc_log(card->ctx, "Wrong path length"); + sc_file_free(file); return SC_ERROR_INTERNAL; } p->value[p->len++] = (u8) (file->id / 256); From 93fac3f0b7ff17767bb4ddd78523a978302362c6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 14:31:33 +0200 Subject: [PATCH 2495/4321] pkcs15-myeid: Check correct path length Coverity 379253 --- src/pkcs15init/pkcs15-myeid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index a6f0dfbc1a..ecf09ea3b3 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -417,7 +417,7 @@ myeid_new_file(sc_profile_t *profile, sc_card_t *card, file->id += num; p = &file->path; *p = profile->df_info->file->path; - if (p->len >= SC_MAX_PATH_SIZE) { + if (p->len >= SC_MAX_PATH_SIZE - 2) { sc_log(card->ctx, "Wrong path length"); sc_file_free(file); return SC_ERROR_INTERNAL; From 39a006432e6fcd1349e17f2699e124516a372f42 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 14 Jul 2022 10:34:13 +0200 Subject: [PATCH 2496/4321] card-muscle: Fix undefined-shift for big key Ignore shift with key that is bigger than number of bits in acl_entry. Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47783 --- src/libopensc/card-muscle.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 512f9df16d..7b0bf64e5a 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -122,7 +122,9 @@ static unsigned short muscle_parse_singleAcl(const sc_acl_entry_t* acl) case SC_AC_UNKNOWN: break; case SC_AC_CHV: - acl_entry |= (1 << key); /* Assuming key 0 == SO */ + /* Ignore shift with more bits that acl_entry has */ + if ((size_t) key < sizeof(acl_entry) * 8) + acl_entry |= (1u << key); /* Assuming key 0 == SO */ break; case SC_AC_AUT: case SC_AC_TERM: From 1dc22b145a63192dbf2c8577d052e8fe5816023a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 14 Jul 2022 11:16:05 +0200 Subject: [PATCH 2497/4321] piv-tool: Fix memory leaks when generating key Thank oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49077 --- src/tools/piv-tool.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index fddb41a1d2..412fb82188 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -454,17 +454,22 @@ static int gen_key(const char * key_info) if (r == 0) { fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EVP_PKEY_free(evpkey); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); return -1; } #if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EC_KEY_new(); r = EC_KEY_set_group(eckey, ecgroup); + EC_GROUP_free(ecgroup); if (r == 0) { fprintf(stderr, "EC_KEY_set_group failed\n"); EVP_PKEY_free(evpkey); + EC_POINT_free(ecpoint); return -1; } r = EC_KEY_set_public_key(eckey, ecpoint); + EC_POINT_free(ecpoint); if (r == 0) { fprintf(stderr, "EC_KEY_set_public_key failed\n"); EVP_PKEY_free(evpkey); @@ -480,13 +485,21 @@ static int gen_key(const char * key_info) len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL); if (!(buf = malloc(len))) { fprintf(stderr, "EC_KEY_set_public_key out of memory\n"); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); return -1; } if (EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, buf, len, NULL) == 0) { fprintf(stderr, "EC_KEY_set_public_key failed\n"); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); free(buf); return -1; } + + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, sizeof(group_name)) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || From 0d09c096a1796203e3a8cc85d060ffedfbc81394 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 15 Jul 2022 15:26:17 +0200 Subject: [PATCH 2498/4321] profile: Do not overwrite existing pointer Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49123 --- src/pkcs15init/profile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index b9e6724cf4..c258b15b15 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1454,6 +1454,7 @@ do_prop_attr(struct state *cur, int argc, char **argv) } file = cur->file->file; + free(file->prop_attr); file->prop_attr = malloc(len); if (!file->prop_attr) return 1; From 08696d5bfcc7bffa88acdb4f1b0d38fe83480ab4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 15 Jul 2022 16:07:12 +0200 Subject: [PATCH 2499/4321] Fix memory leak when deleting file When 'DELETE' ACL of the file and parent fails, free memory and return error. Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49125 --- src/pkcs15init/pkcs15-lib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 4ea694862a..197c332e67 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -619,6 +619,11 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * sc_file_free(file); LOG_TEST_RET(ctx, rv, "parent 'DELETE' authentication failed"); } + else { + /* No 'DELETE' ACL of the file and not deleted for parent */ + rv = SC_ERROR_INVALID_ARGUMENTS; + sc_file_free(file); + } } LOG_TEST_RET(ctx, rv, "'DELETE' authentication failed"); @@ -629,8 +634,10 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; - if (file_path->len < 2) + if (file_path->len < 2) { + sc_file_free(file); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } path.value[0] = file_path->value[file_path->len - 2]; path.value[1] = file_path->value[file_path->len - 1]; path.len = 2; From 7789abaee6e1d0c633206e83d8373ca6ab410c95 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 17 Jul 2022 19:55:47 +0200 Subject: [PATCH 2500/4321] pkcs15-lib: Fix cycling while selecting parent directory Do not select parent when path length is 0 Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48056 --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 197c332e67..4b2e80b386 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4030,7 +4030,7 @@ do_select_parent(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = sc_select_file(p15card->card, &path, parent); /* If DF doesn't exist, create it (unless it's the MF, * but then something's badly broken anyway :-) */ - if (r == SC_ERROR_FILE_NOT_FOUND && path.len != 2) { + if (r == SC_ERROR_FILE_NOT_FOUND && path.len > 2) { r = sc_profile_get_file_by_path(profile, &path, parent); if (r < 0) { sc_log(ctx, "no profile template for DF %s", sc_print_path(&path)); From 89299329dfd2220bb3b6f66dd66a60b6dd5bb7ff Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 19 Jul 2022 16:07:07 +0200 Subject: [PATCH 2501/4321] card-piv: Unlock card with context-specific login When performing context specific login with PIV card, PIV driver does one extra sc_lock() call and expects sc_unlock() to be called by following cryptographic operation. If an error occurs in between, sc_disconnect_card was called, but not release the card due to remaining locks. Thank OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47149 --- src/libopensc/card-piv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c0aaf9c2c7..048b5a3a2d 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3006,6 +3006,11 @@ piv_finish(sc_card_t *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (priv) { + if (priv->context_specific) { + sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock"); + priv->context_specific = 0; + sc_unlock(card); + } if (priv->w_buf) free(priv->w_buf); if (priv->offCardCertURL) From b4d106a7ab41b2531ee6387a573d48f3b88bac1b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 19 Jul 2022 16:18:17 +0200 Subject: [PATCH 2502/4321] Remove check for card locks in sc_disconnect_card() --- src/libopensc/card.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index d62485fc85..ac21d2b56b 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -413,8 +413,6 @@ int sc_disconnect_card(sc_card_t *card) ctx = card->ctx; LOG_FUNC_CALLED(ctx); - if (card->lock_count != 0) - return SC_ERROR_NOT_ALLOWED; if (card->ops->finish) { int r = card->ops->finish(card); if (r) From cd50544ec09d17e3ffaacff1803498d1bb6925aa Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 09:56:25 +0200 Subject: [PATCH 2503/4321] Unchecked return value Coverity 378578 --- src/libopensc/card-epass2003.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 003ffedcfe..b699f8000e 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -877,6 +877,7 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap size_t tlv_more; /* increased tlv length */ unsigned char iv[16] = { 0 }; epass2003_exdata *exdata = NULL; + int r = 0; if (!card->drv_data) return SC_ERROR_INVALID_ARGUMENTS; @@ -909,10 +910,13 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap memcpy(data_tlv, &apdu_buf[block_size], tlv_more); /* encrypt Data */ - if (KEY_TYPE_AES == key_type) - aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); - else - des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + if (KEY_TYPE_AES == key_type) { + r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + } else { + r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed"); + } memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len); *data_tlv_len = tlv_more + pad_len; From e0378c281dd32d3257431259e92c6a81415cce85 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 10:00:39 +0200 Subject: [PATCH 2504/4321] Initialize variables Coverity 376512, 376510 --- src/tools/opensc-explorer.c | 2 +- src/tools/pkcs15-tool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index be5fb77632..c2c2e4e4be 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1858,7 +1858,7 @@ static int do_erase(int argc, char **argv) static int do_random(int argc, char **argv) { - unsigned char buffer[SC_MAX_EXT_APDU_BUFFER_SIZE]; + unsigned char buffer[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; int r, count; const char *filename = NULL; FILE *outf = NULL; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 20fcba7804..1683d422b7 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1377,7 +1377,7 @@ static int test_session_pin(void) unsigned int auth_method; unsigned char *pin; int r; - unsigned char sessionpin[SC_MAX_PIN_SIZE]; + unsigned char sessionpin[SC_MAX_PIN_SIZE] = {0}; size_t sessionpinlen = sizeof sessionpin; if (!opt_auth_id) { From 2cd3d547d595f053e70fd42e3bebde104bcb2345 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 11 Jul 2022 10:51:34 +0200 Subject: [PATCH 2505/4321] Initialize allocated memory Coverity 376509 --- src/sm/sm-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 58d0e43181..ce60a83a43 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -519,7 +519,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, data_len, sc_dump_hex(data, data_len)); *out_len = data_len; - *out = malloc(data_len + 8); + *out = calloc(data_len + 8, sizeof(unsigned char)); if (*out == NULL) { free(data); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM encrypt_des_cbc3: failure"); From d6155fc8db6fbb04c844ee0cb836c449d8db382f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 5 Jul 2022 09:21:12 -0500 Subject: [PATCH 2506/4321] Fix matching of Epass2003 tokens Fixes: #2572 Change ATR matching rules for epass2003 tokens to work with newer versions and with both Feitian initialized and OpenSC initialized tokens. On branch epass2003-atr Changes to be committed: modified: card-epass2003.c modified: ../../win32/customactions.cpp --- src/libopensc/card-epass2003.c | 16 ++++++++++++++-- win32/customactions.cpp | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index b699f8000e..5e5f4f2070 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -47,10 +47,22 @@ #include "asn1.h" #include "cardctl.h" +/* + * See https://github.com/OpenSC/OpenSC/issues/2572 + * 2012 ATR: note verion 01:00:11 + * 3b:9f:95:81:31:fe:9f:00:66:46:53:05:01:00:11:71:df:00:00:03:90:00:80 + * 2022 ATRs: note version 23:00:25 + * OpenSC-initialized ATR: + * 3b 9f:95:81:31:fe:9f:00:66:46:53:05:23:00:25:71:df:00:00:03:90:00:96 + * Feitian-initalized ATR: + * 3b:9f:95:81:31:fe:9f:00:66:46:53:05:23:00:25:71:df:00:00:00:00:00:05 + */ + static const struct sc_atr_table epass2003_atrs[] = { /* This is a FIPS certified card using SCP01 security messaging. */ - {"3B:9F:95:81:31:FE:9F:00:66:46:53:05:10:00:11:71:df:00:00:00:6a:82:5e", - "FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:ff:00:ff:ff:00:00:00:00", + /* will match all the above */ + {"3B:9F:95:81:31:FE:9F:00:66:46:53:05:00:00:00:71:df:00:00:00:00:00:00", + "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:FF:FF:FF:FF:00:00:00:00", "FTCOS/ePass2003", SC_CARD_TYPE_ENTERSAFE_FTCOS_EPASS2003, 0, NULL }, {NULL, NULL, NULL, 0, 0, NULL} }; diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 7595cdf329..d3266d97c3 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -69,8 +69,8 @@ For example, do not uninstall the minidriver for a card if a middleware is alrea */ MD_REGISTRATION minidriver_registration[] = { - {TEXT("ePass2003"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x66,0x46,0x53,0x05,0x01,0x00,0x11,0x71,0xdf,0x00,0x00,0x03,0x6a,0x82,0xf8}, - 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("ePass2003"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x66,0x46,0x53,0x05,0x00,0x00,0x00,0x71,0xdf,0x00,0x00,0x00,0x00,0x00,0x00}, + 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00}}, {TEXT("FTCOS/PK-01C"), {0x3b,0x9f,0x95,0x81,0x31,0xfe,0x9f,0x00,0x65,0x46,0x53,0x05,0x00,0x06,0x71,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 23, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00}}, {TEXT("SmartCard-HSM"), {0x3b,0xfe,0x18,0x00,0x00,0x81,0x31,0xfe,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4d,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xfa}, From 8335120a8e9fb8c9fbdbdef4fd22f0b83cdf3aa2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 10 Jul 2022 07:07:02 -0500 Subject: [PATCH 2507/4321] Spelling fix On branch epass2003-atr Changes to be committed: modified: card-epass2003.c --- src/libopensc/card-epass2003.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 5e5f4f2070..d8a88fa376 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -49,7 +49,7 @@ /* * See https://github.com/OpenSC/OpenSC/issues/2572 - * 2012 ATR: note verion 01:00:11 + * 2012 ATR: note version 01:00:11 * 3b:9f:95:81:31:fe:9f:00:66:46:53:05:01:00:11:71:df:00:00:03:90:00:80 * 2022 ATRs: note version 23:00:25 * OpenSC-initialized ATR: From 159c67588d46da1b568a39b1431e3143f565be62 Mon Sep 17 00:00:00 2001 From: Ulrich Buchgraber Date: Wed, 13 Jul 2022 01:44:12 +0200 Subject: [PATCH 2508/4321] Do not require a R/W session for --login, --pin and --sign This allows to perform commands like `--login --pin XXX --list-objects` or `--sign ...` on a read-only token (which otherwise could return an `CKR_TOKEN_WRITE_PROTECTED` error when calling `C_OpenSession()`). Fixes #2182. --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5a134ea895..dd190d772e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -858,7 +858,7 @@ int main(int argc, char * argv[]) opt_signature_file = optarg; break; case 'l': - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; opt_login = 1; break; case 'm': @@ -879,7 +879,7 @@ int main(int argc, char * argv[]) opt_output = optarg; break; case 'p': - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; opt_login = 1; util_get_pin(optarg, &opt_pin); break; @@ -894,7 +894,7 @@ int main(int argc, char * argv[]) action_count++; break; case 's': - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; do_sign = 1; action_count++; break; From 217199cfb387bc87bacbb0a45d98a806053691b2 Mon Sep 17 00:00:00 2001 From: Ulrich Buchgraber Date: Tue, 2 Aug 2022 16:03:24 +0200 Subject: [PATCH 2509/4321] Do not require a R/W session for --decrypt and --encrypt --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index dd190d772e..0c2b17bed0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -904,12 +904,12 @@ int main(int argc, char * argv[]) action_count++; break; case OPT_DECRYPT: - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; do_decrypt = 1; action_count++; break; case OPT_ENCRYPT: - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; do_encrypt = 1; action_count++; break; From 141ef84a36cb755699a78d67591a4db4f98355a5 Mon Sep 17 00:00:00 2001 From: Ulrich Buchgraber Date: Tue, 2 Aug 2022 20:47:55 +0200 Subject: [PATCH 2510/4321] Do not require a R/W session for --wrap --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0c2b17bed0..08a17558d9 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -919,7 +919,7 @@ int main(int argc, char * argv[]) action_count++; break; case OPT_WRAP: - need_session |= NEED_SESSION_RW; + need_session |= NEED_SESSION_RO; do_wrap = 1; action_count++; break; From b6e01bd7c67efd93356b045218fd8710eae4c544 Mon Sep 17 00:00:00 2001 From: Ulrich Buchgraber Date: Tue, 2 Aug 2022 16:06:28 +0200 Subject: [PATCH 2511/4321] Add a `--session-rw` switch to opt-in an `CKF_RW_SESSION` session --- doc/tools/pkcs11-tool.1.xml | 7 +++++++ src/tools/pkcs11-tool.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 7ff1a88978..97ec5d673f 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -234,6 +234,13 @@ List interfaces of PKCS #11 3.0 library. + + + , + + Forces to open the PKCS#11 session with CKF_RW_SESSION. + + , diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 08a17558d9..fc008f59af 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -171,6 +171,7 @@ enum { OPT_UNLOCK_PIN, OPT_PUK, OPT_NEW_PIN, + OPT_SESSION_RW, OPT_LOGIN_TYPE, OPT_TEST_EC, OPT_DERIVE, @@ -223,6 +224,7 @@ static const struct option options[] = { { "mgf", 1, NULL, OPT_MGF }, { "salt-len", 1, NULL, OPT_SALT }, + { "session-rw", 0, NULL, OPT_SESSION_RW }, { "login", 0, NULL, 'l' }, { "login-type", 1, NULL, OPT_LOGIN_TYPE }, { "pin", 1, NULL, 'p' }, @@ -309,6 +311,7 @@ static const char *option_help[] = { "Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)", "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", + "Forces to open the PKCS#11 session with CKF_RW_SESSION", "Log into the token first", "Specify login type ('so', 'user', 'context-specific'; default:'user')", "Supply User PIN on the command line (if used in scripts: careful!)", @@ -857,6 +860,9 @@ int main(int argc, char * argv[]) case OPT_SIGNATURE_FILE: opt_signature_file = optarg; break; + case OPT_SESSION_RW: + need_session |= NEED_SESSION_RW; + break; case 'l': need_session |= NEED_SESSION_RO; opt_login = 1; From e84cf49336f18564348da11002619557275de21a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 4 Aug 2022 15:45:56 +0200 Subject: [PATCH 2512/4321] Upload artifacts on failure --- .github/workflows/linux.yml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0ad6bb2762..89d497a23a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -18,6 +18,13 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh - run: .github/build.sh dist + - name: Upload test logs + uses: actions/upload-artifact@v2 + if: failure() + with: + name: ubuntu-test-logs + path: + tests/*.log - uses: actions/cache@v2 id: cache-build with: @@ -29,12 +36,6 @@ jobs: name: opensc-build path: opensc*.tar.gz - - name: Upload test logs - uses: actions/upload-artifact@v2 - with: - name: ubuntu-test-logs - path: - tests/*.log build-no-shared: runs-on: ubuntu-latest @@ -56,17 +57,18 @@ jobs: - uses: actions/checkout@v2 - run: .github/setup-linux.sh - run: .github/build.sh - - uses: actions/cache@v2 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} - name: Upload test logs uses: actions/upload-artifact@v2 + if: failure() with: name: ubuntu-18-test-logs path: tests/*.log + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-18-${{ github.sha }} build-mingw: runs-on: ubuntu-latest @@ -195,8 +197,9 @@ jobs: - run: .github/setup-linux.sh ossl3 - run: .github/build.sh dist ossl3 - uses: actions/upload-artifact@v3 + if: failure() with: - name: logs + name: openssl-3-logs path: | tests/*.log config.log @@ -250,8 +253,9 @@ jobs: - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl - uses: actions/upload-artifact@v3 + if: failure() with: - name: logs + name: libressl-logs path: | tests/test-suite.log config.log From 238eff7dee0cd1a699b9b01fe875ce1276397931 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 8 Aug 2022 16:46:56 +0200 Subject: [PATCH 2513/4321] pkcs11-register: recognize firefox-esr fixes https://github.com/OpenSC/OpenSC/issues/2581 --- src/tools/pkcs11-register.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index 873ebcba74..8cc2dceb52 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -231,6 +231,7 @@ add_module_firefox(const char *module_path, const char *module_name, const char {"APPDATA", "Mozilla\\Firefox"}, #else {"HOME", ".mozilla/firefox"}, + {"HOME", ".mozilla/firefox-esr"}, #endif }; From e0ba233e54ad2c2d1e146f11d2eafa5f02a43b95 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 22 Jul 2022 11:58:19 +0200 Subject: [PATCH 2514/4321] Fix uninstall for pkcs11 Remove pkcs11dir only if empty --- src/pkcs11/Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 96ab2f753c..9a8d55d195 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -82,6 +82,11 @@ install-exec-hook: $(LN_S) ../$$l "$(DESTDIR)$(pkcs11dir)/$$l"; \ done +uninstall-hook: + for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ + rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ + done + rm -df "$(DESTDIR)$(pkcs11dir)" || true endif TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(OPENSC_PKCS11_CFLAGS) From 279f7f51b79f99193fa9b14bd214135efa5dcd47 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 22 Jul 2022 12:18:18 +0200 Subject: [PATCH 2515/4321] Add uninstall hooks for win --- src/minidriver/Makefile.am | 3 +++ src/pkcs11/Makefile.am | 5 +++++ win32/Makefile.am | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index e0922e0f8b..ef3c332195 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -27,4 +27,7 @@ opensc_minidriver@LIBRARY_BITNESS@_la_LDFLAGS = $(AM_LDFLAGS) \ if ENABLE_MINIDRIVER install-exec-hook: mv "$(DESTDIR)$(libdir)/opensc-minidriver@LIBRARY_BITNESS@.dll" "$(DESTDIR)$(bindir)/" + +uninstall-hook: + rm -f "$(DESTDIR)$(bindir)/opensc-minidriver@LIBRARY_BITNESS@.dll" endif diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 9a8d55d195..7872cc0579 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -73,6 +73,11 @@ install-exec-hook: for l in opensc-pkcs11.dll pkcs11-spy.dll; do \ mv "$(DESTDIR)$(libdir)/$$l" "$(DESTDIR)$(bindir)/$$l"; \ done + +uninstall-hook: + for l in opensc-pkcs11.dll pkcs11-spy.dll; do \ + rm -f "$(DESTDIR)$(bindir)/$$l"; \ + done else # see http://wiki.cacert.org/wiki/Pkcs11TaskForce install-exec-hook: diff --git a/win32/Makefile.am b/win32/Makefile.am index 590cff84fd..751f7ae498 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -22,4 +22,7 @@ customactions@LIBRARY_BITNESS@_la_LDFLAGS = $(AM_LDFLAGS) \ install-exec-hook: mv "$(DESTDIR)$(libdir)/customactions@LIBRARY_BITNESS@.dll" "$(DESTDIR)$(bindir)/" + +uninstall-hook: + rm -f "$(DESTDIR)$(bindir)/customactions@LIBRARY_BITNESS@.dll" endif From 58d8099cb65d02589b4c54fbb5c820b0f4183aa5 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sat, 6 Aug 2022 15:28:18 +0200 Subject: [PATCH 2516/4321] Trigger github actions on makefile changes --- .github/workflows/linux.yml | 1 + .github/workflows/macos.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 89d497a23a..70b4f96d69 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -9,6 +9,7 @@ on: - .github/setup-linux.sh - .github/build.sh - .github/push-artifacts.sh + - '**.am' push: jobs: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2a932773b8..e5ac172944 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -11,6 +11,7 @@ on: - .github/cleanup-macos.sh - .github/build.sh - .github/push-artifacts.sh + - '**.am' push: jobs: From b8b700ade90d93bbf9c68f09375ad270b1dd63ab Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 1 Feb 2022 20:58:08 -0600 Subject: [PATCH 2517/4321] sc-ossl-compat.h cleanup Remove unused code and misplaced defines from sc-ossl-compat.h to support OpenSSL 1.1.1 and 3.0.0+ and LibreSSL 3.4.2+ The "inline" routines are no longer needed and have been removed. Several other source files were modified to include additional header files or use newer names for functions or macros which are defined in OpenSSL and LibreSSL. Date: Tue Feb 1 20:58:08 2022 -0600 On branch sc-ossl-compat-cleanup Changes to be committed: modified: sc-ossl-compat.h modified: ../pkcs11/framework-pkcs15.c modified: ../pkcs11/openssl.c modified: ../pkcs15init/pkcs15-westcos.c modified: ../tools/piv-tool.c modified: ../tools/pkcs15-init.c interactive rebase in progress; onto 238eff7d Last command done (1 command done): pick 7dea6a55 sc-ossl-compat.h cleanup Next commands to do (12 remaining commands): pick 0d051d11 Handle CRYPTO_secure_* pick b926a52f Fix reset of bn pointer and return false You are currently rebasing. Changes to be committed: modified: src/libopensc/sc-ossl-compat.h modified: src/pkcs11/framework-pkcs15.c modified: src/pkcs11/openssl.c modified: src/pkcs15init/pkcs15-westcos.c modified: src/tools/piv-tool.c modified: src/tools/pkcs15-init.c --- src/libopensc/sc-ossl-compat.h | 240 +------------------------------- src/pkcs11/framework-pkcs15.c | 1 + src/pkcs11/openssl.c | 2 +- src/pkcs15init/pkcs15-westcos.c | 4 +- src/tools/piv-tool.c | 5 +- src/tools/pkcs15-init.c | 12 +- 6 files changed, 14 insertions(+), 250 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index f0d5527984..5a3ae492d8 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -30,80 +30,22 @@ extern "C" { #include #include /* - * Provide backward compatibility to older versions of OpenSSL - * while using most of OpenSSL 1.1 API + * Provide compatibility OpenSSL 1.1.1, 3.0.1 and LibreSSL 3.4.2 * * LibreSSL is a fork of OpenSSL from 2014 * In its version of openssl/opensslv.h it defines: * OPENSSL_VERSION_NUMBER 0x20000000L (Will not change) - * LIBRESSL_VERSION_NUMBER 0x2050000fL (changes with its versions. - * The LibreSSL appears to follow the OpenSSL-1.0.1 API - * - */ - -/* - * 1.1.0 deprecated ERR_load_crypto_strings(), SSL_load_error_strings(), ERR_free_strings() - * and ENGINE_load_dynamic.EVP_CIPHER_CTX_cleanup and EVP_CIPHER_CTX_init are replaced - * by EVP_CIPHER_CTX_reset. - * But for compatibility with LibreSSL and older OpenSSL. OpenSC uses the older functions - */ -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) -# if !(defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT >= 0x10100000L) -# ifndef ERR_load_crypto_strings -#define ERR_load_crypto_strings(x) while (0) continue -# endif -# ifndef SSL_load_error_strings -#define SSL_load_error_strings(x) while (0) continue -# endif -# ifndef ERR_free_strings -#define ERR_free_strings(x) while (0) continue -# endif -# ifndef ENGINE_load_dynamic -#define ENGINE_load_dynamic(x) while (0) continue -# endif -# ifndef EVP_CIPHER_CTX_cleanup -#define EVP_CIPHER_CTX_cleanup(x) EVP_CIPHER_CTX_reset(x) -# endif -# ifndef EVP_CIPHER_CTX_init -#define EVP_CIPHER_CTX_init(x) EVP_CIPHER_CTX_reset(x) -# endif -# endif -#endif - - -/* - * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL - * use RSA_PKCS1_OpenSSL - * Previous versions are missing a number of functions to access - * some hidden structures. Define them here: + * LIBRESSL_VERSION_NUMBER 0x3040200fL (changes with its versions) */ -/* EVP_PKEY_base_id introduced in 1.0.1 */ -#if OPENSSL_VERSION_NUMBER < 0x10001000L -#define EVP_PKEY_base_id(x) (x->type) -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -#define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay - +#if defined(LIBRESSL_VERSION_NUMBER) #define X509_get_extension_flags(x) (x->ex_flags) #define X509_get_key_usage(x) (x->ex_kusage) #define X509_get_extended_key_usage(x) (x->ex_xkusage) -#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2050300fL -#define X509_up_ref(cert) CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509) -#endif -#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x20700000L -#define OPENSSL_malloc_init CRYPTO_malloc_init -#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) -#define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec) -#define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY) -#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) -#endif #endif -/* workaround unused value warning for a macro that does nothing */ -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L -#define OPENSSL_malloc_init() +#if defined(LIBRESSL_VERSION_NUMBER) +#define OPENSSL_malloc_init() while(0) continue #define FIPS_mode() (0) #define EVP_sha3_224() (NULL) #define EVP_sha3_256() (NULL) @@ -113,181 +55,11 @@ extern "C" { #define EVP_PKEY_get_raw_public_key(p, pu, l) (0) #endif +/* OpenSSL 1.1.1 has FIPS_mode function */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L -#define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates -#define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates - -# ifndef FIPS_mode #define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL) -# endif - -/* As defined in openssl/include/openssl/evp.h */ -# ifndef EVP_PK_RSA -# define EVP_PK_RSA 0x0001 -# define EVP_PK_DH 0x0004 -# define EVP_PK_EC 0x0008 -# define EVP_PKT_SIGN 0x0010 -# define EVP_PKT_ENC 0x0020 -# define EVP_PKT_EXCH 0x0040 -# define EVP_PKS_RSA 0x0100 -# define EVP_PKS_EC 0x0400 -# endif #endif -#if OPENSSL_VERSION_NUMBER < 0x30000000L -#define EVP_PKEY_eq EVP_PKEY_cmp -#define EVP_PKEY_CTX_set1_rsa_keygen_pubexp EVP_PKEY_CTX_set_rsa_keygen_pubexp -#endif - -/* - * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures - * One can no longer use statements like rsa->n = ... - * Macros and defines don't work on all systems, so use inline versions - * If that is not good enough, versions could be added to libopensc - */ - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) -/* based on OpenSSL-1.1.0 e_os2.h */ -/* sc_ossl_inline: portable inline definition usable in public headers */ -# if !defined(inline) && !defined(__cplusplus) -# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L - /* just use inline */ -# define sc_ossl_inline inline -# elif defined(__GNUC__) && __GNUC__>=2 -# define sc_ossl_inline __inline__ -# elif defined(_MSC_VER) -# define sc_ossl_inline __inline -# else -# define sc_ossl_inline -# endif -# else -# define sc_ossl_inline inline -# endif -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2050300fL) - -#define RSA_bits(R) (BN_num_bits(R->n)) - -#include -#ifndef OPENSSL_NO_RSA -#include -#endif -#ifndef OPENSSL_NO_EC -#include -#endif - -#ifndef OPENSSL_NO_RSA -static sc_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -{ - /* d is the private component and may be NULL */ - if (n == NULL || e == NULL) - return 0; - - BN_free(r->n); - BN_free(r->e); - BN_free(r->d); - r->n = n; - r->e = e; - r->d = d; - - return 1; -} - -static sc_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) -{ - if (p == NULL || q == NULL) - return 0; - - BN_free(r->p); - BN_free(r->q); - r->p = p; - r->q = q; - - return 1; -} - -static sc_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) -{ - if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL) - return 0; - - BN_free(r->dmp1); - BN_free(r->dmq1); - BN_free(r->iqmp); - r->dmp1 = dmp1; - r->dmq1 = dmq1; - r->iqmp = iqmp; - - return 1; -} - -static sc_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) - *n = r->n; - if (e != NULL) - *e = r->e; - if (d != NULL) - *d = r->d; -} - -static sc_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -{ - if (p != NULL) - *p = r->p; - if (q != NULL) - *q = r->q; -} - -static sc_ossl_inline void RSA_get0_crt_params(const RSA *r, - const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) -{ - if (dmp1 != NULL) - *dmp1 = r->dmp1; - if (dmq1 != NULL) - *dmq1 = r->dmq1; - if (iqmp != NULL) - *iqmp = r->iqmp; -} - -#endif /* OPENSSL_NO_RSA */ - - -#ifndef OPENSSL_NO_EC -static sc_ossl_inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} -#endif /* OPENSSL_NO_EC */ - -static sc_ossl_inline int CRYPTO_secure_malloc_init(size_t size, int minsize) -{ - return 0; -} - -static sc_ossl_inline int CRYPTO_secure_malloc_initialized() -{ - return 0; -} - -static sc_ossl_inline void CRYPTO_secure_malloc_done() -{ -} - -#else - -#include - -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ - - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 379d209712..57d32d19b2 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -30,6 +30,7 @@ #include "common/compat_strnlen.h" #ifdef ENABLE_OPENSSL #include +#include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #endif diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index a6ea9e4722..841f0d977f 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -462,7 +462,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub ASN1_OCTET_STRING_free(octet); P = EC_POINT_new(group); if (P && X && Y) - r = EC_POINT_set_affine_coordinates_GFp(group, + r = EC_POINT_set_affine_coordinates(group, P, X, Y, NULL); BN_free(X); BN_free(Y); diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index bc1130c878..b6467a2628 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -246,7 +246,8 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, if (BN_set_word(bn, RSA_F4) != 1 || EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || - EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || + (bn = NULL) == NULL || /* pctx will free bn */ EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; @@ -313,6 +314,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, BIO_free(mem); if(bn) BN_free(bn); + EVP_PKEY_CTX_free(pctx); EVP_PKEY_free(key); sc_file_free(prkf); return r; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 412fb82188..b93da551e7 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -447,10 +447,7 @@ static int gen_key(const char * key_info) i = (keydata.ecpoint_len - 1)/2; x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; - r = EC_POINT_set_affine_coordinates_GFp(ecgroup, ecpoint, x, y, NULL); - - free(keydata.ecpoint); - keydata.ecpoint_len = 0; + r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); if (r == 0) { fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EVP_PKEY_free(evpkey); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 49faf3dec0..19447bbc0c 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1344,19 +1344,11 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, /* Compare the public keys, there's no high level openssl function for this(?) */ /* Yes there is in 1.0.2 and above EVP_PKEY_cmp */ - r = SC_ERROR_INVALID_ARGUMENTS; if (oldpk_type == newpk_type) { -#if OPENSSL_VERSION_NUMBER >= 0x10002000L - if (EVP_PKEY_eq(oldpk, newpk) == 1) - r = 0; -#else - if ((oldpk_type == EVP_PKEY_RSA) && - !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->n, EVP_PKEY_get0_RSA(newpk)->n) && - !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->e, EVP_PKEY_get0_RSA(newpk)->e)) - r = 0; -#endif + if (EVP_PKEY_cmp(oldpk, newpk) == 1) + r = 0; } EVP_PKEY_free(newpk); From d06608675c2c02bb8c8f0bc4fc67f7536314585b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 2 Feb 2022 20:12:43 -0600 Subject: [PATCH 2518/4321] Handle CRYPTO_secure_* Make sure is included and test for !defined(LIBRESSL_VERSION_NUMBER) when using CRYPTO_secure_malloc_init, CRYPTO_secure_malloc_initialized and CRYPTO_secure_malloc_done On branch sc-ossl-compat-cleanup Changes to be committed: modified: ctx.c modified: ../minidriver/minidriver.c modified: ../pkcs11/pkcs11-global.c --- src/libopensc/ctx.c | 6 +++++- src/minidriver/minidriver.c | 3 ++- src/pkcs11/pkcs11-global.c | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 5bdc4095b3..5b637b8e88 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -40,7 +40,11 @@ #include "common/libscdl.h" #include "common/compat_strlcpy.h" #include "internal.h" +#ifdef ENABLE_OPENSSL +#include #include "sc-ossl-compat.h" +#endif + static int ignored_reader(sc_context_t *ctx, sc_reader_t *reader) { @@ -844,7 +848,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) return r; } -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) if (!CRYPTO_secure_malloc_initialized()) { CRYPTO_secure_malloc_init(OPENSSL_SECURE_MALLOC_SIZE, OPENSSL_SECURE_MALLOC_SIZE/8); } diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 35f1c70952..b8621ef090 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -57,6 +57,7 @@ #ifdef ENABLE_OPENSSL #include #include +#include #endif #ifdef ENABLE_OPENPACE @@ -7160,7 +7161,7 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, case DLL_PROCESS_DETACH: sc_notify_close(); if (lpReserved == NULL) { -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); #endif #ifdef ENABLE_OPENPACE diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index b18d014a5d..48ef7823f0 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -37,7 +37,10 @@ #include "sc-pkcs11.h" #include "ui/notify.h" +#ifdef ENABLE_OPENSSL +#include #include "libopensc/sc-ossl-compat.h" +#endif #ifdef ENABLE_OPENPACE #include #endif @@ -248,7 +251,7 @@ __attribute__((destructor)) int module_close() { sc_notify_close(); -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); #endif #ifdef ENABLE_OPENPACE From a7bcc49e371ce6beaa4073accd61c5b75d027133 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 3 Feb 2022 06:22:35 -0600 Subject: [PATCH 2519/4321] Fix reset of bn pointer and return false On branch sc-ossl-compat-cleanup Changes to be committed: modified: pkcs15-westcos.c --- src/pkcs15init/pkcs15-westcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index b6467a2628..656636c098 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -247,7 +247,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || - (bn = NULL) == NULL || /* pctx will free bn */ + (bn = NULL) != NULL || /* pctx will free bn */ EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; From 80556eaa6f1740153c768cbe6bfe22b7f911fa35 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 3 Feb 2022 11:23:42 -0600 Subject: [PATCH 2520/4321] update pkcs15-pubkey.c On branch sc-ossl-compat-cleanup Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 9aceea64e7..abc55e0dd1 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1678,7 +1678,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) X = BN_new(); Y = BN_new(); if (X && Y && group) - r = EC_POINT_get_affine_coordinates_GFp(group, point, X, Y, NULL); + r = EC_POINT_get_affine_coordinates(group, point, X, Y, NULL); if (r == 1) { dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y); dst->xy.data = malloc(dst->xy.len); From 9178a4260b4948300539f6bb06ea04497163a0fc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 3 Feb 2022 14:14:56 -0600 Subject: [PATCH 2521/4321] pkcs15-init.c use EVP_PKEY_eq on 3.0.0+ or EVP_PKEY_cmp on others On branch sc-ossl-compat-cleanup Changes to be committed: modified: pkcs15-init.c --- src/tools/pkcs15-init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 19447bbc0c..4ffd5a7f30 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1347,7 +1347,11 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, r = SC_ERROR_INVALID_ARGUMENTS; if (oldpk_type == newpk_type) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) + if (EVP_PKEY_eq(oldpk, newpk) == 1) +#else if (EVP_PKEY_cmp(oldpk, newpk) == 1) +#endif r = 0; } From 05160ab91c50ba6be8321a57aa4fb1501a8099fe Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 4 Feb 2022 10:28:38 -0600 Subject: [PATCH 2522/4321] p11tests replace deprecated EVP_PK_* with EVP_PKEY_* On branch sc-ossl-compat-cleanup Changes to be committed: modified: p11test_case_common.c modified: p11test_case_common.h modified: p11test_case_ec_derive.c modified: p11test_case_multipart.c modified: p11test_case_pss_oaep.c modified: p11test_case_readonly.c --- src/tests/p11test/p11test_case_common.c | 12 ++++++------ src/tests/p11test/p11test_case_common.h | 1 + src/tests/p11test/p11test_case_ec_derive.c | 2 +- src/tests/p11test/p11test_case_multipart.c | 2 +- src/tests/p11test/p11test_case_pss_oaep.c | 6 +++--- src/tests/p11test/p11test_case_readonly.c | 9 +++++---- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index d428fbfa90..929d3661e3 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -122,7 +122,7 @@ add_supported_mechs(test_cert_t *o) { size_t i; - if (o->type == EVP_PK_RSA) { + if (o->type == EVP_PKEY_RSA) { if (token.num_rsa_mechs > 0 ) { /* Get supported mechanisms by token */ o->num_mechs = token.num_rsa_mechs; @@ -144,7 +144,7 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT; } - } else if (o->type == EVP_PK_EC) { + } else if (o->type == EVP_PKEY_EC) { if (token.num_ec_mechs > 0 ) { o->num_mechs = token.num_ec_mechs; for (i = 0; i < token.num_ec_mechs; i++) { @@ -260,12 +260,12 @@ int callback_certificates(test_certs_t *objects, if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { o->key = evp; - o->type = EVP_PK_RSA; + o->type = EVP_PKEY_RSA; o->bits = EVP_PKEY_bits(evp); } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { o->key = evp; - o->type = EVP_PK_EC; + o->type = EVP_PKEY_EC; o->bits = EVP_PKEY_bits(evp); } else { @@ -407,7 +407,7 @@ int callback_public_keys(test_certs_t *objects, BN_free(n); BN_free(e); } else { /* store the public key for future use */ - o->type = EVP_PK_RSA; + o->type = EVP_PKEY_RSA; #if OPENSSL_VERSION_NUMBER < 0x30000000L o->key = EVP_PKEY_new(); RSA *rsa = RSA_new(); @@ -547,7 +547,7 @@ int callback_public_keys(test_certs_t *objects, EC_POINT_free(ecpoint); o->verify_public = 1; } else { /* store the public key for future use */ - o->type = EVP_PK_EC; + o->type = EVP_PKEY_EC; o->key = EVP_PKEY_new(); o->bits = EC_GROUP_get_degree(ecgroup); #if OPENSSL_VERSION_NUMBER < 0x30000000L diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 45ba3deb9e..1716745201 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -25,6 +25,7 @@ #include #include #include +#include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include # include diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index f7a5f92f9e..f46d9c0f20 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -237,7 +237,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) return 1; } - if (o->type != EVP_PK_EC) { + if (o->type != EVP_PKEY_EC) { debug_print(" [ KEY %s ] Skip non-EC key for derive", o->id_str); return 1; } diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index fcf1947530..bb070ec775 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -40,7 +40,7 @@ void multipart_tests(void **state) { objects.data[i].id_str); continue; } - if (objects.data[i].type == EVP_PK_EC) { + if (objects.data[i].type == EVP_PKEY_EC) { debug_print(" [ SKIP %s ] EC keys do not support multi-part operations", objects.data[i].id_str); continue; diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index fc231ccc0f..0102db0dcc 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -395,7 +395,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m return 0; } - if (o->type != EVP_PK_RSA) { + if (o->type != EVP_PKEY_RSA) { debug_print(" [ KEY %s ] Skip non-RSA key for encryption", o->id_str); return 0; } @@ -654,7 +654,7 @@ int pss_sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech) return 0; } - if (o->type != EVP_PK_RSA) { + if (o->type != EVP_PKEY_RSA) { debug_print(" [SKIP %s ] Skip non-RSA key", o->id_str); return 0; } @@ -827,7 +827,7 @@ void pss_oaep_test(void **state) { continue; /* Do not list non-RSA keys here */ - if (o->type != EVP_PK_RSA) + if (o->type != EVP_PKEY_RSA) continue; printf("\n[%-6s] [%s]\n", diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 2aefdc7a70..38c5dc29b7 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -25,6 +25,7 @@ #include #include #include +#include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include #endif @@ -229,7 +230,7 @@ int encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (o->type != EVP_PK_RSA) { + if (o->type != EVP_PKEY_RSA) { debug_print(" [SKIP %s ] Skip non-RSA key for encryption", o->id_str); return 0; } @@ -392,7 +393,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_BYTE *cmp_message = NULL; int cmp_message_length; - if (o->type == EVP_PK_RSA) { + if (o->type == EVP_PKEY_RSA) { const EVP_MD *md = NULL; EVP_MD_CTX *mdctx = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -462,7 +463,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, mech->result_flags |= FLAGS_SIGN_OPENSSL; debug_print(" [ OK %s ] Signature is valid.", o->id_str); return 1; - } else if (o->type == EVP_PK_EC) { + } else if (o->type == EVP_PKEY_EC) { unsigned int nlen; ECDSA_SIG *sig = ECDSA_SIG_new(); BIGNUM *r = NULL, *s = NULL; @@ -642,7 +643,7 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (o->type != EVP_PK_EC && o->type != EVP_PK_RSA + if (o->type != EVP_PKEY_EC && o->type != EVP_PKEY_RSA #ifdef EVP_PKEY_ED25519 && o->type != EVP_PKEY_ED25519 #endif From f9253644c91f4fd1f143423961d3586bfd1178e4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 4 Feb 2022 14:26:18 -0600 Subject: [PATCH 2523/4321] Remove calls to deprecated ERR_load_CRYPTO_strings, ERR_free_strings, OPENSSL_config and CRYPTO_malloc_init LibreSSL and OpenSSL 1.1.1 and 3.0.0+ Have deprecated or removed the need by OpenSC to call ERR_load_CRYPTO_strings, ERR_free_strings, OPENSSL_config and CRYPTO_malloc_init calls to these have been removed On branch sc-ossl-compat-cleanup Changes to be committed: modified: src/libopensc/card-westcos.c modified: src/libopensc/pkcs15-prkey.c modified: src/pkcs15init/pkcs15-oberthur-awp.c modified: src/sm/sslutil.h modified: src/tools/gids-tool.c modified: src/tools/piv-tool.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c modified: src/tools/sc-hsm-tool.c modified: src/tools/westcos-tool.c interactive rebase in progress; onto 238eff7d Last commands done (7 commands done): pick 86fd6394 p11tests replace deprecated EVP_PK_* with EVP_PKEY_* pick eeadd82d Remove calls to deprecated ERR_load_CRYPTO_strings, ERR_free_strings, OPENSSL_config and CRYPTO_malloc_init Next commands to do (6 remaining commands): pick 450f344a More EVP_CIPHER_CTX_reset changes pick d8319dc4 Fix use of EVP_PKEY_CTX_set_rsa_keygen_pubexp vs EVP_PKEY_CTX_set1_rsa_keygen_pubexp You are currently rebasing. Changes to be committed: modified: src/libopensc/card-westcos.c modified: src/libopensc/pkcs15-prkey.c modified: src/pkcs15init/pkcs15-oberthur-awp.c modified: src/sm/sslutil.h modified: src/tools/gids-tool.c modified: src/tools/piv-tool.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c modified: src/tools/sc-hsm-tool.c modified: src/tools/westcos-tool.c --- src/libopensc/card-westcos.c | 5 ----- src/libopensc/pkcs15-prkey.c | 6 ------ src/pkcs15init/pkcs15-oberthur-awp.c | 16 +--------------- src/sm/sslutil.h | 2 -- src/tools/gids-tool.c | 16 ---------------- src/tools/piv-tool.c | 16 ---------------- src/tools/pkcs11-tool.c | 8 -------- src/tools/pkcs15-init.c | 22 ---------------------- src/tools/sc-hsm-tool.c | 11 ----------- src/tools/westcos-tool.c | 7 ------- 10 files changed, 1 insertion(+), 108 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index b1e85b1c20..633d471d73 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -57,13 +57,8 @@ #ifdef DEBUG_SSL static void print_openssl_error(void) { - static int charge = 0; long r; - if (!charge) { - ERR_load_crypto_strings(); - charge = 1; - } while ((r = ERR_get_error()) != 0) fprintf(stderr, "%s\n", ERR_error_string(r, NULL)); } diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index d6046a45a2..09f3130dd7 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -458,11 +458,6 @@ sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15 key_info = (struct sc_pkcs15_prkey_info *) key_object->data; -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ERR_load_ERR_strings(); -#endif - ERR_load_crypto_strings(); - sc_log(ctx, "CertValue(%"SC_FORMAT_LEN_SIZE_T"u) %p", cert_object->content.len, cert_object->content.value); mem = BIO_new_mem_buf(cert_object->content.value, cert_object->content.len); @@ -501,7 +496,6 @@ sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15 OPENSSL_free(buff); ERR_clear_error(); - ERR_free_strings(); if (out_key_object) *out_key_object = key_object; diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 70ff580d0e..051c17db4c 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -769,10 +769,6 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj int r = 0; LOG_FUNC_CALLED(ctx); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ERR_load_ERR_strings(); -#endif - ERR_load_crypto_strings(); key_info = (struct sc_pkcs15_prkey_info *)obj->data; @@ -829,10 +825,6 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj sc_log(ctx, "cosm_encode_key_info() label:%s",ki->label.value); done: -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ERR_load_ERR_strings(); -#endif - ERR_load_crypto_strings(); LOG_FUNC_RETURN(ctx, r); } @@ -937,11 +929,6 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob LOG_FUNC_CALLED(ctx); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ERR_load_ERR_strings(); -#endif - ERR_load_crypto_strings(); - if (!obj || !ci) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "AWP encode cert failed: invalid parameters"); @@ -1078,10 +1065,9 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob err: ERR_print_errors_fp(stderr); ERR_clear_error(); - ERR_free_strings(); if (pubkey.exponent.data) free(pubkey.exponent.data); if (pubkey.modulus.data) free(pubkey.modulus.data); - if (x) X509_free(x); + if (x) X509_free(x); if (mem) BIO_free(mem); if (buff) OPENSSL_free(buff); diff --git a/src/sm/sslutil.h b/src/sm/sslutil.h index 7f5b072fcf..5752aa5134 100644 --- a/src/sm/sslutil.h +++ b/src/sm/sslutil.h @@ -28,11 +28,9 @@ #define ssl_error(ctx) { \ unsigned long _r; \ - ERR_load_crypto_strings(); \ for (_r = ERR_get_error(); _r; _r = ERR_get_error()) { \ sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "%s", ERR_error_string(_r, NULL)); \ } \ - ERR_free_strings(); \ } #endif diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index eb4ccc733b..5765472e9c 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -525,23 +525,7 @@ int main(int argc, char * argv[]) } } - - /* OpenSSL magic */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_config(NULL); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS - | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS, - NULL); -#else /* OpenSSL magic */ - OPENSSL_malloc_init(); - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); -#endif memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b93da551e7..d89551c44b 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -687,22 +687,6 @@ int main(int argc, char *argv[]) return 2; } -//#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -// OPENSSL_config(NULL); -//#endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS - | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS, - NULL); -#else - /* OpenSSL magic */ - OPENSSL_malloc_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - -#endif - if (out_file) { bp = BIO_new(BIO_s_file()); if (!BIO_write_filename(bp, (char *)out_file)) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fc008f59af..8c2736a679 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -747,14 +747,6 @@ int main(int argc, char * argv[]) util_fatal("Cannot set FMODE to O_BINARY"); #endif -#ifdef ENABLE_OPENSSL -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_config(NULL); - /* OpenSSL magic */ - OpenSSL_add_all_algorithms(); - OPENSSL_malloc_init(); -#endif -#endif while (1) { c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r", options, &long_optind); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 4ffd5a7f30..9e7a32d739 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -453,22 +453,6 @@ main(int argc, char **argv) int r = 0; struct sc_pkcs15_card *tmp_p15_data = NULL; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - OPENSSL_config(NULL); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !(defined LIBRESSL_VERSION_NUMBER) - /* Openssl 1.1.0 magic */ - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS - | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS - | OPENSSL_INIT_LOAD_CONFIG, - NULL); -#else - /* OpenSSL magic */ - OpenSSL_add_all_algorithms(); - OPENSSL_malloc_init(); -#endif - #ifdef RANDOM_POOL if (!RAND_load_file(RANDOM_POOL, 32)) util_fatal("Unable to seed random number pool for key generation"); @@ -2965,14 +2949,8 @@ next: ; static void ossl_print_errors(void) { - static int loaded = 0; long err; - if (!loaded) { - ERR_load_crypto_strings(); - loaded = 1; - } - while ((err = ERR_get_error()) != 0) fprintf(stderr, "%s\n", ERR_error_string(err, NULL)); } diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 9e41899eaa..0c64e03f6c 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -2077,17 +2077,6 @@ int main(int argc, char *argv[]) exit(1); } -#if OPENSSL_VERSION_NUMBER >= 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L) - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS - | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS, - NULL); -#else - CRYPTO_malloc_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); -#endif - memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 14861dc108..1c87446117 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -111,17 +111,10 @@ static int do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src) return 1; } -static int charge = 0; static void print_openssl_error(void) { long r; - if (!charge) - { - ERR_load_crypto_strings(); - charge = 1; - } - while ((r = ERR_get_error()) != 0) printf("%s\n", ERR_error_string(r, NULL)); } From bb62074b86e55b3e0b5d430bd6ba130881ab2d59 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 5 Feb 2022 08:03:23 -0600 Subject: [PATCH 2524/4321] More EVP_CIPHER_CTX_reset changes Changes to be committed: modified: src/libopensc/card-gpk.c modified: src/libopensc/card-piv.c --- src/libopensc/card-gpk.c | 8 ++++---- src/libopensc/card-piv.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 34bfaa727f..7571e0c042 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -903,14 +903,14 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, if (!EVP_EncryptUpdate(ctx, kats, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; - if (!EVP_CIPHER_CTX_cleanup(ctx)) + if (!EVP_CIPHER_CTX_reset(ctx)) r = SC_ERROR_INTERNAL; if (r == SC_SUCCESS) { - EVP_CIPHER_CTX_init(ctx); + EVP_CIPHER_CTX_reset(ctx); EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, out, NULL); if (!EVP_EncryptUpdate(ctx, kats+8, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; - if (!EVP_CIPHER_CTX_cleanup(ctx)) + if (!EVP_CIPHER_CTX_reset(ctx)) r = SC_ERROR_INTERNAL; } memset(out, 0, sizeof(out)); @@ -920,7 +920,7 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, * here? INVALID_ARGS doesn't seem quite right */ if (r == SC_SUCCESS) { - EVP_CIPHER_CTX_init(ctx); + EVP_CIPHER_CTX_reset(ctx); EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, kats, NULL); if (!EVP_EncryptUpdate(ctx, out, &outl, challenge, 8)) r = SC_ERROR_INTERNAL; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 048b5a3a2d..4bb28c764a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1778,7 +1778,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, goto err; } - EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_reset(ctx); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { r = SC_ERROR_INTERNAL; From 0790d79a414e60f90a20e26898f77e935d050781 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 5 Feb 2022 08:05:16 -0600 Subject: [PATCH 2525/4321] Fix use of EVP_PKEY_CTX_set_rsa_keygen_pubexp vs EVP_PKEY_CTX_set1_rsa_keygen_pubexp EVP_PKEY_CTX_set1_rsa_keygen_pubexp is used in 3.0 EVP_PKEY_CTX_set_rsa_keygen_pubexp is used in 1.1.1 and LibreSSL previous commit in this PR tried to use just one for all cases. On branch sc-ossl-compat-cleanup Changes to be committed: modified: src/pkcs15init/pkcs15-westcos.c --- src/pkcs15init/pkcs15-westcos.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 656636c098..646cb6db8e 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -246,8 +246,12 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, if (BN_set_word(bn, RSA_F4) != 1 || EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || +#else EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || - (bn = NULL) != NULL || /* pctx will free bn */ + (bn = NULL) || /* pctx will free bn */ +#endif EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; From 49f48f57211508997131dd52c689ee8cdea42468 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 7 Feb 2022 06:39:01 -0600 Subject: [PATCH 2526/4321] card-iasecc.c support for partial hash to use with final hash on card Update to use EVP_Digest* for SHA1 or SHA256 in iasecc_qsign_data_sha1 and iasecc_qsign_data_sha256. These routines extract partial hash data before EVP_DigestFinal. The data is then sent to the card to do the final round of the hash. LibreSSL, OpenSSL 1.1.m and 3.0.1 all define in sha.h identical SHA_CTX and SHA256_CTX structures. But if 3.0.1 is built with no-depracated the definition of the structures (and other defines) are undefined. In this these are defind in card-iasecc.c All three versions have a way to access the data in these structures: LibreSSL: md_data = (SHA_CTX *)mdctx->md_data; 1.1.1m: md_data = EVP_MD_CTX_md_data(mdctx); 3.0.1: md_data = EVP_MD_CTX_get0_md_data(mdctx); I believe that the depraction of the structures in 3.0.1 is an oversight as EVP_MD_CTX_get0_md_data (added in 3.0.0) will return the address of the structure but not the definition of the structure. On branch sc-ossl-compat-cleanup Changes to be committed: modified: card-iasecc.c --- src/libopensc/card-iasecc.c | 146 ++++++++++++++++++++++++++++++------ 1 file changed, 122 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 8682e143e3..51673c1a25 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -38,6 +38,25 @@ #include #include +#ifndef SHA_LONG +# define SHA_LONG unsigned int +# define SHA_LBLOCK 16 + +typedef struct SHAstate_st { +SHA_LONG h0, h1, h2, h3, h4; +SHA_LONG Nl, Nh; +SHA_LONG data[SHA_LBLOCK]; +unsigned int num; +} SHA_CTX; + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; +#endif /* SHA_LONG */ + #include "internal.h" #include "asn1.h" #include "cardctl.h" @@ -3164,10 +3183,12 @@ static int iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t in_len, struct iasecc_qsign_data *out) { - SHA_CTX sha; - SHA_LONG pre_hash_Nl, *hh[5] = { - &sha.h0, &sha.h1, &sha.h2, &sha.h3, &sha.h4 - }; + int r = SC_ERROR_INTERNAL; + EVP_MD_CTX *mdctx = NULL; + const EVP_MD *md = NULL; + SHA_CTX *md_data = NULL; + unsigned int md_out_len; + SHA_LONG pre_hash_Nl, *hh[5] = {NULL, NULL, NULL, NULL, NULL}; int jj, ii; int hh_size = sizeof(SHA_LONG), hh_num = SHA_DIGEST_LENGTH / sizeof(SHA_LONG); @@ -3181,8 +3202,35 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i in_len); memset(out, 0, sizeof(struct iasecc_qsign_data)); - SHA1_Init(&sha); - SHA1_Update(&sha, in, in_len); + md = EVP_get_digestbyname("SHA1"); + mdctx = EVP_MD_CTX_new(); + if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log(ctx, "EVP_DigestInit_ex failed"); + goto err; + } + +#if defined(LIBRESSL_VERSION_NUMBER) + md_data = (SHA_CTX *)mdctx->md_data; +#elif OPENSSL_VERSION_NUMBER < 0x30000000L + md_data = EVP_MD_CTX_md_data(mdctx); +#else + md_data = EVP_MD_CTX_get0_md_data(mdctx); +#endif + if (md_data == NULL) { + sc_log(ctx, "Failed to find md_data"); + goto err; + } + + if (EVP_DigestUpdate(mdctx, in, in_len) != 1) { + sc_log(ctx, "EVP_DigestUpdate failed"); + goto err; + } + + hh[0] = &md_data->h0; + hh[1] = &md_data->h1; + hh[2] = &md_data->h2; + hh[3] = &md_data->h3; + hh[4] = &md_data->h4; for (jj=0; jjpre_hash_size = SHA_DIGEST_LENGTH; sc_log(ctx, "Pre SHA1:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size)); - pre_hash_Nl = sha.Nl - (sha.Nl % (sizeof(sha.data) * 8)); + pre_hash_Nl = md_data->Nl - (md_data->Nl % (sizeof(md_data->data) *8)); for (ii=0; iicounter[ii] = (sha.Nh >> 8*(hh_size-1-ii)) &0xFF; + out->counter[ii] = (md_data->Nh >> 8*(hh_size-1-ii)) &0xFF; out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF; } for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++) out->counter_long = out->counter_long*0x100 + out->counter[ii]; sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter))); - if (sha.num) { - memcpy(out->last_block, in + in_len - sha.num, sha.num); - out->last_block_size = sha.num; + if (md_data->num) { + memcpy(out->last_block, in + in_len - md_data->num, md_data->num); + out->last_block_size = md_data->num; sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s", out->last_block_size, sc_dump_hex(out->last_block, out->last_block_size)); } - SHA1_Final(out->hash, &sha); + if (EVP_DigestFinal_ex(mdctx, out->hash, &md_out_len) != 1) { + sc_log(ctx, "EVP_DigestFinal_ex failed"); + goto err; + } + out->hash_size = SHA_DIGEST_LENGTH; sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size)); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + r = SC_SUCCESS; + goto end; + +err: + ERR_print_errors_fp(stderr); +end: + EVP_MD_CTX_free(mdctx); + + LOG_FUNC_RETURN(ctx, r); } @@ -3219,7 +3279,12 @@ static int iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len, struct iasecc_qsign_data *out) { - SHA256_CTX sha256; + int r = SC_ERROR_INTERNAL; + EVP_MD_CTX *mdctx = NULL; + const EVP_MD *md = NULL; + SHA256_CTX *md_data; + unsigned int md_out_len; + SHA_LONG pre_hash_Nl; int jj, ii; int hh_size = sizeof(SHA_LONG), hh_num = SHA256_DIGEST_LENGTH / sizeof(SHA_LONG); @@ -3233,37 +3298,70 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len); memset(out, 0, sizeof(struct iasecc_qsign_data)); - SHA256_Init(&sha256); - SHA256_Update(&sha256, in, in_len); + md = EVP_get_digestbyname("SHA256"); + mdctx = EVP_MD_CTX_new(); + if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log(ctx, "EVP_DigestInit_ex failed"); + goto err; + } + +#if defined(LIBRESSL_VERSION_NUMBER) + md_data = (SHA256_CTX *)mdctx->md_data; +#elif OPENSSL_VERSION_NUMBER < 0x30000000L + md_data = EVP_MD_CTX_md_data(mdctx); +#else + md_data = EVP_MD_CTX_get0_md_data(mdctx); +#endif + if (md_data == NULL) { + sc_log(ctx, "Failed to find md_data"); + goto err; + } + + if (EVP_DigestUpdate(mdctx, in, in_len) != 1) { + sc_log(ctx, "EVP_DigestUpdate failed"); + goto err; + } for (jj=0; jjpre_hash[jj*hh_size + ii] = ((sha256.h[jj] >> 8*(hh_size-1-ii)) & 0xFF); + out->pre_hash[jj*hh_size + ii] = ((md_data->h[jj] >> 8*(hh_size-1-ii)) & 0xFF); out->pre_hash_size = SHA256_DIGEST_LENGTH; sc_log(ctx, "Pre hash:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size)); - pre_hash_Nl = sha256.Nl - (sha256.Nl % (sizeof(sha256.data) * 8)); + pre_hash_Nl = md_data->Nl - (md_data->Nl % (sizeof(md_data->data) * 8)); for (ii=0; iicounter[ii] = (sha256.Nh >> 8*(hh_size-1-ii)) &0xFF; + out->counter[ii] = (md_data->Nh >> 8*(hh_size-1-ii)) &0xFF; out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF; } for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++) out->counter_long = out->counter_long*0x100 + out->counter[ii]; sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter))); - if (sha256.num) { - memcpy(out->last_block, in + in_len - sha256.num, sha256.num); - out->last_block_size = sha256.num; + if (md_data->num) { + memcpy(out->last_block, in + in_len - md_data->num, md_data->num); + out->last_block_size = md_data->num; sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s", out->last_block_size, sc_dump_hex(out->last_block, out->last_block_size)); } - SHA256_Final(out->hash, &sha256); + if (EVP_DigestFinal_ex(mdctx, out->hash, &md_out_len) != 1) { + sc_log(ctx, "EVP_DigestFinal_ex failed"); + goto err; + } + out->hash_size = SHA256_DIGEST_LENGTH; sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size)); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + r = SC_SUCCESS; + goto end; + +err: + ERR_print_errors_fp(stderr); +end: + EVP_MD_CTX_free(mdctx); + + LOG_FUNC_RETURN(ctx, r); } From 7f883f8b2d315ba9981dd056b957613ae4728f74 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 15 Feb 2022 12:25:21 -0600 Subject: [PATCH 2527/4321] card-iasecc.c OpenSSL-3.0.1 but without signatures OpenSSL 3.0.0 EVP_MD_CTX_get0_md_data returns NULL. See discussion https://github.com/openssl/openssl/issues/17688 on what it would take to support this. This commit will allow card-iasecc.c to authenticate but signatures will fail with using `OpenSSL-3.0.0 even when compiling with with different API for example: -DOPENSSL_API_COMPAT=0x10100000L --- src/libopensc/card-iasecc.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 51673c1a25..6af1bfb6a9 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -38,7 +38,13 @@ #include #include +/* + * OpenSSL-3.0.0 does not allow access to the SHA data + * so this driver can not produces signatures + */ + #ifndef SHA_LONG +//#warning "SHA_LONG not defined in this version of OpenSSL signatures not supported" # define SHA_LONG unsigned int # define SHA_LBLOCK 16 @@ -3218,6 +3224,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i #endif if (md_data == NULL) { sc_log(ctx, "Failed to find md_data"); + r = SC_ERROR_NOT_SUPPORTED; goto err; } @@ -3267,7 +3274,8 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i goto end; err: - ERR_print_errors_fp(stderr); + if (ctx->debug > 0 && ctx->debug_file != 0) + ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); @@ -3314,6 +3322,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t #endif if (md_data == NULL) { sc_log(ctx, "Failed to find md_data"); + r = SC_ERROR_NOT_SUPPORTED; goto err; } @@ -3357,7 +3366,8 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t goto end; err: - ERR_print_errors_fp(stderr); + if (ctx->debug > 0 && ctx->debug_file != 0) + ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); From cc5564ffbe24c81d1caaf60bc0dc80dce5236ce6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 18 Feb 2022 14:31:53 -0600 Subject: [PATCH 2528/4321] whitespace On branch sc-ossl-compat-cleanup Changes to be committed: modified: pkcs15-oberthur-awp.c --- src/pkcs15init/pkcs15-oberthur-awp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 051c17db4c..c9da5f658d 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1067,7 +1067,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ERR_clear_error(); if (pubkey.exponent.data) free(pubkey.exponent.data); if (pubkey.modulus.data) free(pubkey.modulus.data); - if (x) X509_free(x); + if (x) X509_free(x); if (mem) BIO_free(mem); if (buff) OPENSSL_free(buff); From ca1bf057fa8649031f1b65f7f3de0641b3fee312 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 18 Feb 2022 17:09:43 -0600 Subject: [PATCH 2529/4321] card-iasecc.c - return SC_ERROR_NOT_SUPPORTED when used with OpenSSL-3.0+ card-iasecc.c is the only place in OpenSC that needs acces to internal hash routines in order to pass intermediate hash data to the card so card can do last round of a hash on the card. LibreSSL and OpenSC-1.1.1 provide access to the SHA_CTX and SHA256_CTX structures. But OpenSSL 3.0 no longer provides access to internal hash data. This commit modifies the iasecc_qsign_data_sha1 and iasecc_qsign_data_sha256 routines to return SC_ERROR_NOT_SUPPORTED when compiled using OpenSSL 3.0.0 or greater. It is not clear at this time if this driver is even used. If the "dsign" routines are needed, a future commit could add a non-OpenSSL SHA1 and SHA256 routine to allow accss to internal data. On branch sc-ossl-compat-cleanup Changes to be committed: modified: card-iasecc.c --- src/libopensc/card-iasecc.c | 48 +++++++++++++------------------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 6af1bfb6a9..3c21183648 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -41,27 +41,13 @@ /* * OpenSSL-3.0.0 does not allow access to the SHA data * so this driver can not produces signatures + * OpenSSL 1.1.1 uses EVP_MD_CTX_md_data + * LibreSSL */ -#ifndef SHA_LONG -//#warning "SHA_LONG not defined in this version of OpenSSL signatures not supported" -# define SHA_LONG unsigned int -# define SHA_LBLOCK 16 - -typedef struct SHAstate_st { -SHA_LONG h0, h1, h2, h3, h4; -SHA_LONG Nl, Nh; -SHA_LONG data[SHA_LBLOCK]; -unsigned int num; -} SHA_CTX; - -typedef struct SHA256state_st { - SHA_LONG h[8]; - SHA_LONG Nl, Nh; - SHA_LONG data[SHA_LBLOCK]; - unsigned int num, md_len; -} SHA256_CTX; -#endif /* SHA_LONG */ +#if defined(LIBRESSL_VERSION_NUMBER) +# define EVP_MD_CTX_md_data(x) (x->md_data) +#endif #include "internal.h" #include "asn1.h" @@ -3189,6 +3175,8 @@ static int iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t in_len, struct iasecc_qsign_data *out) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + int r = SC_ERROR_INTERNAL; EVP_MD_CTX *mdctx = NULL; const EVP_MD *md = NULL; @@ -3215,13 +3203,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i goto err; } -#if defined(LIBRESSL_VERSION_NUMBER) - md_data = (SHA_CTX *)mdctx->md_data; -#elif OPENSSL_VERSION_NUMBER < 0x30000000L md_data = EVP_MD_CTX_md_data(mdctx); -#else - md_data = EVP_MD_CTX_get0_md_data(mdctx); -#endif if (md_data == NULL) { sc_log(ctx, "Failed to find md_data"); r = SC_ERROR_NOT_SUPPORTED; @@ -3280,6 +3262,10 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i EVP_MD_CTX_free(mdctx); LOG_FUNC_RETURN(ctx, r); + +#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ } @@ -3287,6 +3273,8 @@ static int iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len, struct iasecc_qsign_data *out) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + int r = SC_ERROR_INTERNAL; EVP_MD_CTX *mdctx = NULL; const EVP_MD *md = NULL; @@ -3313,13 +3301,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t goto err; } -#if defined(LIBRESSL_VERSION_NUMBER) - md_data = (SHA256_CTX *)mdctx->md_data; -#elif OPENSSL_VERSION_NUMBER < 0x30000000L md_data = EVP_MD_CTX_md_data(mdctx); -#else - md_data = EVP_MD_CTX_get0_md_data(mdctx); -#endif if (md_data == NULL) { sc_log(ctx, "Failed to find md_data"); r = SC_ERROR_NOT_SUPPORTED; @@ -3372,6 +3354,10 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t EVP_MD_CTX_free(mdctx); LOG_FUNC_RETURN(ctx, r); + +#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ } From 56df8f520bd91c2fc1c9d5367e7a2160003a9af9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 9 Aug 2022 13:15:49 -0500 Subject: [PATCH 2530/4321] Do not load GOST engine when using OpenSSL-3 OpenSSL is dropping support for engines. If and when GOST developers convert GOST to an OpenSSL provider, we can look at loading the provider if needed. On branch sc-ossl-compat-cleanup Changes to be committed: modified: openssl.c --- src/pkcs11/openssl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 841f0d977f..86aae6a7d6 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -227,6 +227,11 @@ void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) { sc_pkcs11_mechanism_type_t *mt = NULL; +/* + * Engine support is being dropped in 3.0. OpenSC loads GOST as engine. + * When GOST developers convert to provider, we can load the provider + */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L #if !defined(OPENSSL_NO_ENGINE) ENGINE *e; /* crypto locking removed in 1.1 */ @@ -272,6 +277,7 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) CRYPTO_set_locking_callback(locking_cb); #endif #endif /* !defined(OPENSSL_NO_ENGINE) */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) */ openssl_sha1_mech.mech_data = EVP_sha1(); mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); From f7b7ebc05df94c307ff180316e80d2076f8a3852 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 10 Aug 2022 06:55:41 -0500 Subject: [PATCH 2531/4321] Suggested changes to comments On branch sc-ossl-compat-cleanup Changes to be committed: modified: openssl.c --- src/pkcs11/openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 86aae6a7d6..80fdc4f917 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -228,7 +228,7 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) { sc_pkcs11_mechanism_type_t *mt = NULL; /* - * Engine support is being dropped in 3.0. OpenSC loads GOST as engine. + * Engine support is being deprecated in 3.0. OpenSC loads GOST as engine. * When GOST developers convert to provider, we can load the provider */ #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -277,7 +277,7 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) CRYPTO_set_locking_callback(locking_cb); #endif #endif /* !defined(OPENSSL_NO_ENGINE) */ -#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) */ +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ openssl_sha1_mech.mech_data = EVP_sha1(); mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); From 786d0ac7c26456b8e73e06a2ba1d3414e78d57b9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 10 Aug 2022 07:28:59 -0500 Subject: [PATCH 2532/4321] github build.sh treat ossl3 like other builds --- .github/build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 149421c1d4..bdaa11ccc3 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -48,8 +48,7 @@ else # normal procedure if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - # without -Werror, because of rest of deprecated API - ./configure --disable-dependency-tracking --disable-strict CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2" + ./configure --disable-dependency-tracking elif [ "$1" == "no-shared" ]; then ./configure --disable-shared else From e3f5156c40bc912354446de4603781420d375ca4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 10 Aug 2022 09:41:34 -0500 Subject: [PATCH 2533/4321] github build.sh treat ossl3 like other builds On branch sc-ossl-compat-cleanup Changes to be committed: modified: build.sh --- .github/build.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index bdaa11ccc3..3fc887768a 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -47,9 +47,7 @@ else fi # normal procedure - if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - ./configure --disable-dependency-tracking - elif [ "$1" == "no-shared" ]; then + if [ "$1" == "no-shared" ]; then ./configure --disable-shared else ./configure --disable-dependency-tracking From 1d9333ec6fa32de6cf3eb3794b9b74a575a10113 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 15:03:14 +0200 Subject: [PATCH 2534/4321] piv-tool: Free bignums after use Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49077 --- src/tools/piv-tool.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index d89551c44b..1cf5d75867 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -374,7 +374,7 @@ static int gen_key(const char * key_info) expc[2] = (u8) (expl >>8) & 0xff; expc[1] = (u8) (expl >>16) & 0xff; expc[0] = (u8) (expl >>24) & 0xff; - newkey_e = BN_bin2bn(expc, 4, NULL); + newkey_e = BN_bin2bn(expc, 4, NULL); free(keydata.pubkey); keydata.pubkey_len = 0; @@ -383,6 +383,8 @@ static int gen_key(const char * key_info) fprintf(stderr, "gen_key unable to set RSA values"); EVP_PKEY_free(evpkey); RSA_free(newkey); + BN_free(newkey_n); + BN_free(newkey_e); return -1; } @@ -396,9 +398,13 @@ static int gen_key(const char * key_info) OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { OSSL_PARAM_BLD_free(bld); + BN_free(newkey_n); + BN_free(newkey_e); return -1; } params = OSSL_PARAM_BLD_to_param(bld); + BN_free(newkey_n); + BN_free(newkey_e); ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); if (!ctx || @@ -448,6 +454,10 @@ static int gen_key(const char * key_info) x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); + + BN_free(x); + BN_free(y); + if (r == 0) { fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EVP_PKEY_free(evpkey); From fbddac37ee43322c55741dad831c4a9168fd5c16 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 15:08:20 +0200 Subject: [PATCH 2535/4321] profile.c: Do not overwrite existing pointer Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49848 --- src/pkcs15init/profile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index c258b15b15..b92cd5fbaf 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -835,6 +835,7 @@ init_state(struct state *cur_state, struct state *new_state) static int do_card_driver(struct state *cur, int argc, char **argv) { + free(cur->profile->driver); cur->profile->driver = strdup(argv[0]); return 0; } From ed949ed6b99eb6041c9309e061269c71540aabd5 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 15:20:43 +0200 Subject: [PATCH 2536/4321] pkcs15-tool: Free resources in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49865 --- src/tools/pkcs15-tool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 1683d422b7..6532b9682e 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2373,7 +2373,8 @@ int main(int argc, char *argv[]) aid.len = sizeof(aid.value); if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len)) { fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid); - return 1; + err = 1; + goto end; } r = sc_pkcs15_bind(card, &aid, &p15card); From e2c36463ea83c9e9362200f6caa54ae91f531c98 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 15:47:12 +0200 Subject: [PATCH 2537/4321] Free file after parent DELETE authentication Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49868 --- src/pkcs15init/pkcs15-lib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 4b2e80b386..2f9d5c99a9 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -615,8 +615,7 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); - if (rv < 0) - sc_file_free(file); + sc_file_free(file); LOG_TEST_RET(ctx, rv, "parent 'DELETE' authentication failed"); } else { From 4f6a4c580501e067fcf45c2dd4f03c3226282014 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 16:29:27 +0200 Subject: [PATCH 2538/4321] Check file size before allocating memory Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49908 --- src/pkcs15init/pkcs15-lib.c | 6 ++++++ src/pkcs15init/pkcs15-muscle.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 2f9d5c99a9..be56e2d729 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -651,6 +651,7 @@ sc_pkcs15init_delete_by_path(struct sc_profile *profile, struct sc_pkcs15_card * sc_log(ctx, "Now really delete file"); rv = sc_delete_file(p15card->card, &path); + sc_file_free(file); LOG_FUNC_RETURN(ctx, rv); } @@ -4151,6 +4152,11 @@ sc_pkcs15init_update_file(struct sc_profile *profile, else if (selected_file->size > datalen && need_to_zap) { /* zero out the rest of the file - we may have shrunk * the file contents */ + if (selected_file->size > MAX_FILE_SIZE) { + sc_file_free(selected_file); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + } + copy = calloc(1, selected_file->size); if (copy == NULL) { sc_file_free(selected_file); diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index f827ff5d45..ef821c73df 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -79,6 +79,8 @@ muscle_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d sc_file_free(file); return r; } + sc_file_free(file); + /* Create the application DF */ if ((r = sc_pkcs15init_create_file(profile, p15card, df)) < 0) return r; From ed2a7ca896bc097f1294cd5f84187dce2a815c8f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 14 Aug 2022 16:42:10 +0200 Subject: [PATCH 2539/4321] pkcs15-iasecc.c: Check whether p15card->app is allocated Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49912 --- src/pkcs15init/pkcs15-iasecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 4e92a2f6dd..7d95cfe81b 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -125,7 +125,7 @@ iasecc_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15c LOG_FUNC_CALLED(ctx); - if (p15card->app->ddo.aid.len) { + if (p15card->app && p15card->app->ddo.aid.len) { memset(&path, 0, sizeof(struct sc_path)); path.type = SC_PATH_TYPE_DF_NAME; memcpy(path.value, p15card->app->ddo.aid.value, p15card->app->ddo.aid.len); From d29fd8f4ea0870e5e2a6d650d22a01d1c50d5967 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 16 Aug 2022 15:05:44 +0200 Subject: [PATCH 2540/4321] Remove dead code Coverity 380282, 380280, 380278 --- src/libopensc/card-iasecc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 3c21183648..480c1cf87b 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -830,7 +830,7 @@ _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, sc_log(ctx, "READ method/reference %X/%X", entry->method, entry->key_ref); if ((entry->method == SC_AC_SCB) && (entry->key_ref & IASECC_SCB_METHOD_SM)) { - unsigned char se_num = (entry->method == SC_AC_SCB) ? (entry->key_ref & IASECC_SCB_METHOD_MASK_REF) : 0; + unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF; rv = iasecc_sm_read_binary(card, se_num, offs, buff, count); LOG_FUNC_RETURN(ctx, rv); @@ -865,7 +865,7 @@ _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, sc_log(ctx, "UPDATE method/reference %X/%X", entry->method, entry->key_ref); if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM)) { - unsigned char se_num = entry->method == SC_AC_SCB ? entry->key_ref & IASECC_SCB_METHOD_MASK_REF : 0; + unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF; rv = iasecc_sm_update_binary(card, se_num, offs, buff, count); LOG_FUNC_RETURN(ctx, rv); @@ -1569,7 +1569,7 @@ iasecc_delete_file(struct sc_card *card, const struct sc_path *path) sc_log(ctx, "DELETE method/reference %X/%X", entry->method, entry->key_ref); if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM)) { - unsigned char se_num = (entry->method == SC_AC_SCB) ? (entry->key_ref & IASECC_SCB_METHOD_MASK_REF) : 0; + unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF; rv = iasecc_sm_delete_file(card, se_num, file->id); } else { From a5f708b1cd67ad5d0fc0512b77605fd3455ef788 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 16 Aug 2022 15:14:53 +0200 Subject: [PATCH 2541/4321] Fix 'assign instead of compare' issue Coverity 380281 --- src/pkcs15init/pkcs15-westcos.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 646cb6db8e..fb8f8bda83 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -247,12 +247,17 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, key_info->modulus_length) != 1 || #if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1 || + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(pctx, bn) != 1) { #else - EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1 || - (bn = NULL) || /* pctx will free bn */ + EVP_PKEY_CTX_set_rsa_keygen_pubexp(pctx, bn) != 1) { #endif - EVP_PKEY_keygen(pctx, &key) != 1) { + r = SC_ERROR_UNKNOWN; + goto out; + } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + bn = NULL; /* pctx will free bn */ +#endif + if (EVP_PKEY_keygen(pctx, &key) != 1) { r = SC_ERROR_UNKNOWN; goto out; } From af5dea4c789077fea7fce5a54f0cd1a2baf722ed Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 16 Aug 2022 15:20:33 +0200 Subject: [PATCH 2542/4321] p11test: Check return value Coverity 380279 --- src/tests/p11test/p11test_case_wrap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c index 99042ed34d..7db970ac11 100644 --- a/src/tests/p11test/p11test_case_wrap.c +++ b/src/tests/p11test/p11test_case_wrap.c @@ -226,6 +226,10 @@ static int test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_ ciphertext_len += len; /* Now, decrypt with the PKCS#11 */ check_len = decrypt_message(key, info, ciphertext, ciphertext_len, &aes_mech, &check); + if (check_len < 0) { + fprintf(stderr, " Cannot decrypt message\n"); + return -1; + } check_len = strip_pkcs7_padding(check, check_len, 16); if (check_len <= 0) { From abfe5fa208bef939820e2d7c2c0d46ed37f7cbd1 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 17 Aug 2022 17:46:03 +0200 Subject: [PATCH 2543/4321] piv-tool: Fix memory leak Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50299 --- src/tools/piv-tool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 1cf5d75867..f8a39b5a49 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -455,6 +455,8 @@ static int gen_key(const char * key_info) y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); + free(keydata.ecpoint); + keydata.ecpoint_len = 0; BN_free(x); BN_free(y); From f5e13431419a43eb8df07ee0801a5b21d372adce Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Mon, 15 Aug 2022 15:24:56 +0200 Subject: [PATCH 2544/4321] Fix build with libressl >= 3.5.0 libressl added back FIPS_mode since version 3.5.0 and https://github.com/libressl-portable/openbsd/commit/a97eabc90d7647e374c1c6da686aeec63c49ff14 libressl provides X509_get_extension_flags since version 3.5.0 and https://github.com/libressl-portable/openbsd/commit/3180723224c1b2c7856a110b8213e4966995d7e0 Signed-off-by: Fabrice Fontaine --- src/libopensc/sc-ossl-compat.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 5a3ae492d8..da53ca8cee 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -38,7 +38,7 @@ extern "C" { * LIBRESSL_VERSION_NUMBER 0x3040200fL (changes with its versions) */ -#if defined(LIBRESSL_VERSION_NUMBER) +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x30500000L #define X509_get_extension_flags(x) (x->ex_flags) #define X509_get_key_usage(x) (x->ex_kusage) #define X509_get_extended_key_usage(x) (x->ex_xkusage) @@ -46,7 +46,9 @@ extern "C" { #if defined(LIBRESSL_VERSION_NUMBER) #define OPENSSL_malloc_init() while(0) continue +#if LIBRESSL_VERSION_NUMBER < 0x30500000L #define FIPS_mode() (0) +#endif #define EVP_sha3_224() (NULL) #define EVP_sha3_256() (NULL) #define EVP_sha3_384() (NULL) From d06c66a76c5ac40e75954254cc7b5f96d216e7a7 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 11 Aug 2022 10:01:43 +0200 Subject: [PATCH 2545/4321] symmetric encryption initial implementation: pkcs#11: C_EncryptInit, C_Encrypt, C_EncryptUpdate, C_EncryptFinal pkcs#15: pkcs15_skey_encrypt, sc_pkcs15_encrypt_sym also implements: sc_encrypt_sym This code is inspired by: https://github.com/carblue/OpenSC-1/tree/sym_hw_encrypt --- src/libopensc/iso7816.c | 3 +- src/libopensc/libopensc.exports | 2 + src/libopensc/opensc.h | 8 +- src/libopensc/pkcs15-sec.c | 89 ++++++++++- src/libopensc/pkcs15.h | 6 + src/libopensc/sec.c | 16 ++ src/pkcs11/framework-pkcs15.c | 80 ++++++++++ src/pkcs11/mechanism.c | 268 +++++++++++++++++++++++++++++++- src/pkcs11/openssl.c | 8 + src/pkcs11/pkcs11-object.c | 101 +++++++++++- src/pkcs11/sc-pkcs11.h | 22 ++- 11 files changed, 593 insertions(+), 10 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 8f0499eadd..8c69176372 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1324,7 +1324,8 @@ static struct sc_card_operations iso_ops = { NULL, /* read_public_key */ NULL, /* card_reader_lock_obtained */ NULL, /* wrap */ - NULL /* unwrap */ + NULL, /* unwrap */ + NULL /* encrypt_sym */ }; static struct sc_card_driver iso_driver = { diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index f1d762c4bb..07fa764679 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -94,6 +94,7 @@ sc_do_log_noframe _sc_debug _sc_debug_hex sc_enum_apps +sc_encrypt_sym sc_encode_oid sc_parse_ef_atr sc_establish_context @@ -180,6 +181,7 @@ sc_pkcs15_encode_pukdf_entry sc_pkcs15_encode_skdf_entry sc_pkcs15_encode_tokeninfo sc_pkcs15_encode_unusedspace +sc_pkcs15_encrypt_sym sc_pkcs15_erase_pubkey sc_pkcs15_dup_pubkey sc_pkcs15_find_cert_by_id diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 475076dac1..d0f67a95ba 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -59,7 +59,8 @@ extern "C" { #define SC_SEC_OPERATION_DERIVE 0x0004 #define SC_SEC_OPERATION_WRAP 0x0005 #define SC_SEC_OPERATION_UNWRAP 0x0006 - +#define SC_SEC_OPERATION_ENCRYPT_SYM 0x0007 +#define SC_SEC_OPERATION_DECRYPT_SYM 0x0008 /* sc_security_env flags */ #define SC_SEC_ENV_ALG_REF_PRESENT 0x0001 #define SC_SEC_ENV_FILE_REF_PRESENT 0x0002 @@ -814,6 +815,9 @@ struct sc_card_operations { int (*wrap)(struct sc_card *card, u8 *out, size_t outlen); int (*unwrap)(struct sc_card *card, const u8 *crgram, size_t crgram_len); + + int (*encrypt_sym)(struct sc_card *card, const u8 *plaintext, size_t plaintext_len, + u8 *out, size_t *outlen); }; typedef struct sc_card_driver { @@ -1378,6 +1382,8 @@ int sc_reset_retry_counter(struct sc_card *card, unsigned int type, const u8 *newref, size_t newlen); int sc_build_pin(u8 *buf, size_t buflen, struct sc_pin_cmd_pin *pin, int pad); +int sc_encrypt_sym(struct sc_card *card, const u8 *Data, size_t DataLen, + u8 *out, size_t *outlen); /********************************************************************/ /* ISO 7816-9 related functions */ diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 054e60811f..3675a1b616 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -249,7 +249,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, senv_out->algorithm_ref = prkey->field_length; break; case SC_PKCS15_TYPE_SKEY_GENERIC: - if (obj->type == SC_PKCS15_TYPE_SKEY_GENERIC && skey->key_type != CKK_AES) + if (skey->key_type != CKK_AES) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported"); *alg_info_out = sc_card_find_alg(p15card->card, SC_ALGORITHM_AES, skey->value_len, NULL); @@ -783,3 +783,90 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, r); } + +int +sc_pkcs15_encrypt_sym(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *obj, + unsigned long flags, + const u8 *in, size_t inlen, u8 *out, size_t *outlen, + const u8 *param, size_t paramlen) +{ + + sc_context_t *ctx = p15card->card->ctx; + + int i, r; + sc_algorithm_info_t *alg_info = NULL; + sc_security_env_t senv; + sc_sec_env_param_t senv_param; + const struct sc_pkcs15_skey_info *skey; + unsigned long pad_flags = 0, sec_flags = 0; + int revalidated_cached_pin = 0; + sc_path_t path; + + sc_log(ctx, "called with flags 0x%lX", flags); + + skey = (const struct sc_pkcs15_skey_info *)obj->data; + if (!(skey->usage & SC_PKCS15_PRKEY_USAGE_ENCRYPT)) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for encryption"); + + r = format_senv(p15card, obj, &senv, &alg_info); + LOG_TEST_RET(ctx, r, "Could not initialize security environment"); + senv.operation = SC_SEC_OPERATION_ENCRYPT_SYM; + + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); + LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); + senv.algorithm_flags = sec_flags; + + for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS && senv.supported_algos[i].reference; i++) { + if ((senv.supported_algos[i].mechanism == CKM_AES_ECB && sec_flags == SC_ALGORITHM_AES_ECB) || + (senv.supported_algos[i].mechanism == CKM_AES_CBC && sec_flags == SC_ALGORITHM_AES_CBC) || + (senv.supported_algos[i].mechanism == CKM_AES_CBC_PAD && sec_flags == SC_ALGORITHM_AES_CBC_PAD)) { + senv.algorithm_ref = senv.supported_algos[i].algo_ref; + senv.flags |= SC_SEC_ENV_ALG_REF_PRESENT; + break; + } + } + + if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { + senv_param = (sc_sec_env_param_t){ + SC_SEC_ENV_PARAM_IV, (void *)param, paramlen}; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); + } + + LOG_TEST_RET(p15card->card->ctx, get_file_path(obj, &path), "Failed to get key file path."); + + LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed"); + + do { + r = SC_SUCCESS; + if (outlen == NULL) { + /* C_EncryptInit */ + /* select key file and set sec env */ + if (path.len != 0 || path.aid.len != 0) { + r = select_key_file(p15card, obj, &senv); + if (r < 0) + sc_log(p15card->card->ctx, "Unable to select key file"); + } + if (r == SC_SUCCESS) { + r = sc_set_security_env(p15card->card, &senv, 0); + if (r < 0) + sc_log(p15card->card->ctx, "Unable to set security env"); + } + } + + if (r == SC_SUCCESS) + r = sc_encrypt_sym(p15card->card, in, inlen, out, outlen); + + if (revalidated_cached_pin) + /* only re-validate once */ + break; + if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { + r = sc_pkcs15_pincache_revalidate(p15card, obj); + if (r < 0) + break; + revalidated_cached_pin = 1; + } + } while (revalidated_cached_pin); + + LOG_FUNC_RETURN(ctx, r); +} diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 52b268ee1e..89e75f8c3b 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -680,6 +680,12 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, unsigned long alg_flags, const u8 *in, size_t inlen, u8 *out, size_t outlen, void *pMechanism); +int sc_pkcs15_encrypt_sym(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *obj, + unsigned long flags, + const u8 *in, size_t inlen, u8 *out, size_t *outlen, + const u8 *param, size_t paramlen); + int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *, const struct sc_pkcs15_object *, struct sc_pkcs15_pubkey **); int sc_pkcs15_decode_pubkey_rsa(struct sc_context *, diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 49913c6fe5..39904f292c 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -337,3 +337,19 @@ int sc_build_pin(u8 *buf, size_t buflen, struct sc_pin_cmd_pin *pin, int pad) return i; } + +int +sc_encrypt_sym(struct sc_card *card, const u8 *plaintext, size_t plaintext_len, + u8 *out, size_t *outlen) +{ + int r; + + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + + LOG_FUNC_CALLED(card->ctx); + if (card->ops->encrypt_sym == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + r = card->ops->encrypt_sym(card, plaintext, plaintext_len, out, outlen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 57d32d19b2..6189c11b28 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3837,6 +3837,7 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = { NULL, /* sign */ NULL, /* unwrap_key */ NULL, /* decrypt */ + NULL, /* encrypt */ NULL, /* derive */ NULL, /* can_do */ NULL, /* init_params */ @@ -4712,6 +4713,7 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = { pkcs15_prkey_sign, pkcs15_prkey_unwrap, pkcs15_prkey_decrypt, + NULL, /* encrypt */ pkcs15_prkey_derive, pkcs15_prkey_can_do, pkcs15_prkey_init_params, @@ -4971,6 +4973,7 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { NULL, /* sign */ NULL, /* unwrap_key */ NULL, /* decrypt */ + NULL, /* ecrypt */ NULL, /* derive */ NULL, /* can_do */ NULL, /* init_params */ @@ -5151,6 +5154,7 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = { NULL, /* sign */ NULL, /* unwrap_key */ NULL, /* decrypt */ + NULL, /* encrypt */ NULL, /* derive */ NULL, /* can_do */ NULL, /* init_params */ @@ -5216,6 +5220,7 @@ struct sc_pkcs11_object_ops pkcs15_profile_ops = { NULL, /* sign */ NULL, /* unwrap_key */ NULL, /* decrypt */ + NULL, /* encrypt */ NULL, /* derive */ NULL, /* can_do */ NULL, /* init_params */ @@ -5340,6 +5345,10 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = (skey->info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) != 0; break; + case CKA_ALWAYS_AUTHENTICATE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL *)attr->pValue = skey->base.p15_object->user_consent >= 1 ? CK_TRUE : CK_FALSE; + break; case CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT: check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = skey->base.p15_object->user_consent >= 1 ? CK_TRUE : CK_FALSE; @@ -5514,6 +5523,76 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj, return CKR_OK; } +static CK_RV +pkcs15_skey_encrypt(struct sc_pkcs11_session *session, void *obj, + CK_MECHANISM_PTR pMechanism, + CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + struct sc_pkcs11_card *p11card = session->slot->p11card; + struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *)obj; + int rv, flags = 0; + size_t lEncryptedDataLen, *lpEncryptedDataLen; + + if (!p11card) + return sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_Encrypt..."); + fw_data = (struct pkcs15_fw_data *)p11card->fws_data[session->slot->fw_data_idx]; + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Encrypt..."); + if (!fw_data->p15_card) + return sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_Encrypt..."); + + if (pMechanism == NULL) { + sc_log(context, "No mechanism specified\n"); + return CKR_ARGUMENTS_BAD; + } + + /* do not check NULL/0 in Data/EncryptedData here, this + can be an init operation or final operation..*/ + + if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_ENCRYPT)) + return CKR_KEY_FUNCTION_NOT_PERMITTED; + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); + + switch (pMechanism->mechanism) { + case CKM_AES_ECB: + /* handle this in card driver + if (ulDataLen % 16) + return CKR_DATA_LEN_RANGE; */ + flags |= SC_ALGORITHM_AES_ECB; + break; + case CKM_AES_CBC: + /* handle this in card driver + if (ulDataLen % 16) + return CKR_DATA_LEN_RANGE; */ + flags |= SC_ALGORITHM_AES_CBC; + break; + case CKM_AES_CBC_PAD: + flags |= SC_ALGORITHM_AES_CBC_PAD; + break; + default: + return CKR_MECHANISM_INVALID; + } + + rv = sc_lock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_Encrypt..."); + + /* pointer CK_ULONG_PTR to size_t conversion */ + lpEncryptedDataLen = pulEncryptedDataLen ? &lEncryptedDataLen : NULL; + + rv = sc_pkcs15_encrypt_sym(fw_data->p15_card, skey->prv_p15obj, flags, + pData, ulDataLen, pEncryptedData, lpEncryptedDataLen, + pMechanism->pParameter, pMechanism->ulParameterLen); + + if (pulEncryptedDataLen) + *pulEncryptedDataLen = *lpEncryptedDataLen; + + sc_unlock(p11card->card); + return sc_to_cryptoki_error(rv, "C_Encrypt..."); +} /* * Secret key objects, currently used only to retrieve derived session key @@ -5528,6 +5607,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { NULL, /* sign */ pkcs15_skey_unwrap, NULL, /* decrypt */ + pkcs15_skey_encrypt, /* encrypt */ NULL, /* derive */ NULL, /* can_do */ NULL, /* init_params */ diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index a9c7e4d1de..c77a1da9bb 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -891,6 +891,132 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, return rv; } #endif +/* + * Initialize a encrypting context. When we get here, we know + * the key object is capable of encrypt _something_ + */ +CK_RV +sc_pkcs11_encr_init(struct sc_pkcs11_session *session, + CK_MECHANISM_PTR pMechanism, + struct sc_pkcs11_object *key, + CK_KEY_TYPE key_type) +{ + struct sc_pkcs11_card *p11card; + sc_pkcs11_operation_t *operation; + sc_pkcs11_mechanism_type_t *mt; + CK_RV rv; + + if (!session || !session->slot || !(p11card = session->slot->p11card)) + return CKR_ARGUMENTS_BAD; + + /* See if we support this mechanism type */ + mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_ENCRYPT); + if (mt == NULL) + return CKR_MECHANISM_INVALID; + + /* See if compatible with key type */ + rv = _validate_key_type(mt, key_type); + if (rv != CKR_OK) + LOG_FUNC_RETURN(context, (int)rv); + + rv = session_start_operation(session, SC_PKCS11_OPERATION_ENCRYPT, mt, &operation); + if (rv != CKR_OK) + return rv; + + memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); + if (pMechanism->pParameter) { + memcpy(&operation->mechanism_params, pMechanism->pParameter, + pMechanism->ulParameterLen); + operation->mechanism.pParameter = &operation->mechanism_params; + } + rv = mt->encrypt_init(operation, key); + if (rv != CKR_OK) + goto out; + + /* Validate the mechanism parameters */ + if (key->ops->init_params) { + rv = key->ops->init_params(operation->session, &operation->mechanism); + if (rv != CKR_OK) + goto out; + } + LOG_FUNC_RETURN(context, (int)rv); +out: + session_stop_operation(session, SC_PKCS11_OPERATION_ENCRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} + +CK_RV +sc_pkcs11_encr(struct sc_pkcs11_session *session, + CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + sc_pkcs11_operation_t *op; + CK_RV rv; + + rv = session_get_operation(session, SC_PKCS11_OPERATION_ENCRYPT, &op); + if (rv != CKR_OK) + return rv; + + rv = op->type->encrypt(op, pData, ulDataLen, + pEncryptedData, pulEncryptedDataLen); + + /* application is requesting buffer size ? */ + if (pEncryptedData == NULL) { + /* do not terminate session for CKR_OK */ + if (rv == CKR_OK) + LOG_FUNC_RETURN(context, CKR_OK); + } else if (rv == CKR_BUFFER_TOO_SMALL) + LOG_FUNC_RETURN(context, CKR_BUFFER_TOO_SMALL); + + session_stop_operation(session, SC_PKCS11_OPERATION_ENCRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} + +CK_RV +sc_pkcs11_encr_update(struct sc_pkcs11_session *session, + CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + sc_pkcs11_operation_t *op; + CK_RV rv; + + rv = session_get_operation(session, SC_PKCS11_OPERATION_ENCRYPT, &op); + if (rv != CKR_OK) + return rv; + + rv = op->type->encrypt_update(op, pData, ulDataLen, + pEncryptedData, pulEncryptedDataLen); + + /* terminate session for any error except CKR_BUFFER_TOO_SMALL */ + if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) + session_stop_operation(session, SC_PKCS11_OPERATION_ENCRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} + +CK_RV +sc_pkcs11_encr_final(struct sc_pkcs11_session *session, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + sc_pkcs11_operation_t *op; + CK_RV rv; + + rv = session_get_operation(session, SC_PKCS11_OPERATION_ENCRYPT, &op); + if (rv != CKR_OK) + return rv; + + rv = op->type->encrypt_final(op, pEncryptedData, pulEncryptedDataLen); + + /* application is requesting buffer size ? */ + if (pEncryptedData == NULL) { + /* do not terminate session for CKR_OK */ + if (rv == CKR_OK) + LOG_FUNC_RETURN(context, CKR_OK); + } else if (rv == CKR_BUFFER_TOO_SMALL) + LOG_FUNC_RETURN(context, CKR_BUFFER_TOO_SMALL); + + session_stop_operation(session, SC_PKCS11_OPERATION_ENCRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} /* * Initialize a decryption context. When we get here, we know @@ -1065,8 +1191,6 @@ sc_pkcs11_unwrap(struct sc_pkcs11_session *session, return rv; } - - /* Derive one key from another, and return results in created object */ CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *session, @@ -1164,6 +1288,140 @@ sc_pkcs11_deri(struct sc_pkcs11_session *session, return rv; } +/* + * Initialize a encrypt operation + */ +static CK_RV +sc_pkcs11_encrypt_init(sc_pkcs11_operation_t *operation, + struct sc_pkcs11_object *key) +{ + struct signature_data *data; + CK_RV rv; + + if (!(data = new_signature_data())) + return CKR_HOST_MEMORY; + + data->key = key; + + if (key->ops->can_do) { + rv = key->ops->can_do(operation->session, key, operation->type->mech, CKF_ENCRYPT); + if ((rv == CKR_OK) || (rv == CKR_FUNCTION_NOT_SUPPORTED)) { + /* Mechanism recognized and can be performed by pkcs#15 card or algorithm references not supported */ + } else { + /* Mechanism cannot be performed by pkcs#15 card, or some general error. */ + free(data); + LOG_FUNC_RETURN(context, (int)rv); + } + } + + operation->priv_data = data; + + /* The last parameter is NULL - this is call to INIT code in underlying functions */ + return key->ops->encrypt(operation->session, + key, &operation->mechanism, NULL, 0, NULL, NULL); +} + +static CK_RV +sc_pkcs11_encrypt(sc_pkcs11_operation_t *operation, + CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + struct signature_data *data; + struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulEncryptedDataLen, ulLastEncryptedPartLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pEncryptedData && !pulEncryptedDataLen) + return CKR_ARGUMENTS_BAD; + + ulEncryptedDataLen = pulEncryptedDataLen ? *pulEncryptedDataLen : 0; + ulLastEncryptedPartLen = ulEncryptedDataLen; + + data = (struct signature_data *)operation->priv_data; + + key = data->key; + + /* Encrypt (Update) */ + rv = key->ops->encrypt(operation->session, key, &operation->mechanism, + pData, ulDataLen, pEncryptedData, &ulEncryptedDataLen); + + if (pulEncryptedDataLen) + *pulEncryptedDataLen = ulEncryptedDataLen; + + if (rv != CKR_OK) + return rv; + + /* recalculate buffer space */ + if (ulEncryptedDataLen <= ulLastEncryptedPartLen) + ulLastEncryptedPartLen -= ulEncryptedDataLen; + else + ulLastEncryptedPartLen = 0; + + /* EncryptFinalize */ + rv = key->ops->encrypt(operation->session, key, &operation->mechanism, + NULL, 0, pEncryptedData + ulEncryptedDataLen, &ulLastEncryptedPartLen); + + if (pulEncryptedDataLen) + *pulEncryptedDataLen = ulEncryptedDataLen + ulLastEncryptedPartLen; + return rv; +} + +static CK_RV +sc_pkcs11_encrypt_update(sc_pkcs11_operation_t *operation, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) +{ + struct signature_data *data; + struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulEncryptedPartLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pEncryptedPart && !pulEncryptedPartLen) + return CKR_ARGUMENTS_BAD; + + ulEncryptedPartLen = pulEncryptedPartLen ? *pulEncryptedPartLen : 0; + + data = (struct signature_data *)operation->priv_data; + + key = data->key; + + rv = key->ops->encrypt(operation->session, key, &operation->mechanism, + pPart, ulPartLen, pEncryptedPart, &ulEncryptedPartLen); + + if (pulEncryptedPartLen) + *pulEncryptedPartLen = ulEncryptedPartLen; + return rv; +} + +static CK_RV +sc_pkcs11_encrypt_final(sc_pkcs11_operation_t *operation, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen) +{ + struct signature_data *data; + struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulLastEncryptedPartLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pLastEncryptedPart && !pulLastEncryptedPartLen) + return CKR_ARGUMENTS_BAD; + + ulLastEncryptedPartLen = pulLastEncryptedPartLen ? *pulLastEncryptedPartLen : 0; + + data = (struct signature_data *)operation->priv_data; + + key = data->key; + + rv = key->ops->encrypt(operation->session, key, &operation->mechanism, + NULL, 0, pLastEncryptedPart, &ulLastEncryptedPartLen); + + if (pulLastEncryptedPartLen) + *pulLastEncryptedPartLen = ulLastEncryptedPartLen; + return rv; +} /* * Initialize a decrypt operation @@ -1312,6 +1570,12 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, mt->decrypt_init = sc_pkcs11_decrypt_init; mt->decrypt = sc_pkcs11_decrypt; } + if (pInfo->flags & CKF_ENCRYPT) { + mt->encrypt_init = sc_pkcs11_encrypt_init; + mt->encrypt = sc_pkcs11_encrypt; + mt->encrypt_update = sc_pkcs11_encrypt_update; + mt->encrypt_final = sc_pkcs11_encrypt_final; + } return mt; } diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 80fdc4f917..30204d0901 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -67,6 +67,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -87,6 +88,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -107,6 +109,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -127,6 +130,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -147,6 +151,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -167,6 +172,7 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -187,6 +193,7 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -207,6 +214,7 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 2e8caae117..907f0ad6b1 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -49,6 +49,10 @@ static sc_pkcs11_mechanism_type_t find_mechanism = { NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ + NULL, /* encrypt init */ + NULL, /* encrypt */ + NULL, /* ecnrypt_update */ + NULL, /* encrypt_final */ NULL, /* mech_data */ NULL, /* free_mech_data */ NULL, /* copy_mech_data */ @@ -831,7 +835,48 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ CK_OBJECT_HANDLE hKey) /* handle of encryption key */ { - return CKR_FUNCTION_NOT_SUPPORTED; + CK_BBOOL can_encrypt; + CK_KEY_TYPE key_type; + CK_ATTRIBUTE encrypt_attribute = {CKA_ENCRYPT, &can_encrypt, sizeof(can_encrypt)}; + CK_ATTRIBUTE key_type_attr = {CKA_KEY_TYPE, &key_type, sizeof(key_type)}; + struct sc_pkcs11_session *session; + struct sc_pkcs11_object *object; + CK_RV rv; + + if (pMechanism == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_object_from_session(hSession, hKey, &session, &object); + if (rv != CKR_OK) { + if (rv == CKR_OBJECT_HANDLE_INVALID) + rv = CKR_KEY_HANDLE_INVALID; + goto out; + } + + if (object->ops->encrypt == NULL_PTR) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + + rv = object->ops->get_attribute(session, object, &encrypt_attribute); + if (rv != CKR_OK || !can_encrypt) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + rv = object->ops->get_attribute(session, object, &key_type_attr); + if (rv != CKR_OK) { + rv = CKR_KEY_TYPE_INCONSISTENT; + goto out; + } + rv = sc_pkcs11_encr_init(session, pMechanism, object, key_type); +out: + SC_LOG_RV("C_EncryptInit() = %s", rv); + sc_pkcs11_unlock(); + return rv; } @@ -841,7 +886,24 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pEncryptedData, /* receives encrypted data */ CK_ULONG_PTR pulEncryptedDataLen) { /* receives encrypted byte count */ - return CKR_FUNCTION_NOT_SUPPORTED; + CK_RV rv; + struct sc_pkcs11_session *session; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_session(hSession, &session); + if (rv == CKR_OK) { + rv = restore_login_state(session->slot); + if (rv == CKR_OK) + rv = sc_pkcs11_encr(session, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); + rv = reset_login_state(session->slot, rv); + } + + SC_LOG_RV("C_Encrypt() = %s", rv); + sc_pkcs11_unlock(); + return rv; } CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ @@ -850,14 +912,45 @@ CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */ CK_ULONG_PTR pulEncryptedPartLen) { /* receives encrypted byte count */ - return CKR_FUNCTION_NOT_SUPPORTED; + CK_RV rv; + struct sc_pkcs11_session *session; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_session(hSession, &session); + if (rv == CKR_OK) + rv = sc_pkcs11_encr_update(session, pPart, ulPartLen, + pEncryptedPart, pulEncryptedPartLen); + + SC_LOG_RV("C_EncryptUpdate() = %s", rv); + sc_pkcs11_unlock(); + return rv; } CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pLastEncryptedPart, /* receives encrypted last part */ CK_ULONG_PTR pulLastEncryptedPartLen) { /* receives byte count */ - return CKR_FUNCTION_NOT_SUPPORTED; + CK_RV rv; + struct sc_pkcs11_session *session; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_session(hSession, &session); + if (rv == CKR_OK) { + rv = restore_login_state(session->slot); + if (rv == CKR_OK) + rv = sc_pkcs11_encr_final(session, pLastEncryptedPart, pulLastEncryptedPartLen); + rv = reset_login_state(session->slot, rv); + } + + SC_LOG_RV("C_EncryptFinal() = %s", rv); + sc_pkcs11_unlock(); + return rv; } CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 992a8b525f..4412bc4b75 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -105,7 +105,10 @@ struct sc_pkcs11_object_ops { CK_MECHANISM_PTR, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); - + CK_RV (*encrypt)(struct sc_pkcs11_session *, void *, + CK_MECHANISM_PTR, + CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen); CK_RV (*derive)(struct sc_pkcs11_session *, void *, CK_MECHANISM_PTR, CK_BYTE_PTR pSeedData, CK_ULONG ulSeedDataLen, @@ -258,6 +261,7 @@ enum { SC_PKCS11_OPERATION_VERIFY, SC_PKCS11_OPERATION_DIGEST, SC_PKCS11_OPERATION_DECRYPT, + SC_PKCS11_OPERATION_ENCRYPT, SC_PKCS11_OPERATION_DERIVE, SC_PKCS11_OPERATION_WRAP, SC_PKCS11_OPERATION_UNWRAP, @@ -302,6 +306,16 @@ struct sc_pkcs11_mechanism_type { CK_RV (*decrypt)(sc_pkcs11_operation_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*encrypt_init)(sc_pkcs11_operation_t *, + struct sc_pkcs11_object *); + CK_RV (*encrypt)(sc_pkcs11_operation_t *, + CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*encrypt_update)(sc_pkcs11_operation_t *, + CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*encrypt_final)(sc_pkcs11_operation_t *, + CK_BYTE_PTR, CK_ULONG_PTR); CK_RV (*derive)(sc_pkcs11_operation_t *, struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG, @@ -456,6 +470,12 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); #endif CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE); CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); + +CK_RV sc_pkcs11_encr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE); +CK_RV sc_pkcs11_encr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_encr_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_encr_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV sc_pkcs11_wrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, struct sc_pkcs11_object *, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_unwrap(struct sc_pkcs11_session *,CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_BYTE_PTR, CK_ULONG, struct sc_pkcs11_object *); CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR, From c852236e8368b47b38d89b1b7fb2dbd78753e109 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 11 Aug 2022 10:03:04 +0200 Subject: [PATCH 2546/4321] MyEID driver: support for symmetric crypt AES-ECB, AEC-CBC, AES-CBC-PAD Tested: MyEID 4.0.1, 4.5.5 card, pkcs11-tool --encrypt, 128 bit AES key (small file encryption by C_encrypt, and big file by C_EncryptUpdate and C_EncrytpFinal), all supported mechanisms: AES-ECB, AEC-CBC, AES-CBC-PAD. --- src/libopensc/card-myeid.c | 298 ++++++++++++++++++++++++++++++++++++- 1 file changed, 293 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index a12eb3f472..6b17f97534 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -84,6 +84,13 @@ typedef struct myeid_private_data { after this pair of calls and must not be used elsewhere. */ const struct sc_security_env* sec_env; int disable_hw_pkcs1_padding; + /* buffers for AES(DES) block cipher */ + uint8_t sym_crypt_buffer[16]; + uint8_t sym_plain_buffer[16]; + uint8_t sym_crypt_buffer_len; + uint8_t sym_plain_buffer_len; + /* PSO for AES/DES need algo+flags from sec env */ + unsigned int algorithm, algorithm_flags; } myeid_private_data_t; typedef struct myeid_card_caps { @@ -713,6 +720,8 @@ static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); } +#define IS_SYMETRIC_CRYPT(x) ((x) == SC_SEC_OPERATION_ENCRYPT_SYM || (x) == SC_SEC_OPERATION_DECRYPT_SYM) + static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t *env, int se_num) { @@ -756,6 +765,14 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * apdu.p1 = 0x81; apdu.p2 = 0xB8; break; + case SC_SEC_OPERATION_ENCRYPT_SYM: + apdu.p1 = 0x81; + apdu.p2 = 0xB8; + break; + case SC_SEC_OPERATION_DECRYPT_SYM: + apdu.p1 = 0x41; + apdu.p2 = 0xB8; + break; default: return SC_ERROR_INVALID_ARGUMENTS; } @@ -774,9 +791,16 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * memcpy(p, env->file_ref.value, 2); p += 2; } + /* symmetric operations: we need to set the key reference */ + if (IS_SYMETRIC_CRYPT(env->operation)) { + *p++ = 0x83; + *p++ = 1; + *p++ = 0; + } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && env->operation != SC_SEC_OPERATION_UNWRAP && - env->operation != SC_SEC_OPERATION_WRAP) - { + env->operation != SC_SEC_OPERATION_WRAP && + env->operation != SC_SEC_OPERATION_ENCRYPT_SYM && + env->operation != SC_SEC_OPERATION_DECRYPT_SYM) { *p++ = 0x84; *p++ = 1; *p++ = 0; @@ -795,11 +819,13 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * break; } - if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP) - { - /* add IV if present */ + r = 0; + if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP || + IS_SYMETRIC_CRYPT(env->operation)) { + /* add IV if present */ for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++) if (env->params[i].param_type == SC_SEC_ENV_PARAM_IV) { + r = 1; *p++ = 0x87; *p++ = (unsigned char) env->params[i].value_len; if (p + env->params[i].value_len >= sbuf + SC_MAX_APDU_BUFFER_SIZE) { @@ -811,6 +837,15 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * break; } } + /* for AES_ECB we need to reset the IV but we respect if the IV is already present */ + if (IS_SYMETRIC_CRYPT(env->operation) && env->algorithm == SC_ALGORITHM_AES && + env->algorithm_flags == SC_ALGORITHM_AES_ECB && r == 0) { + *p++ = 0x87; + *p++ = 16; + memset(p, 0, 16); + p += 16; + } + r = p - sbuf; apdu.lc = r; apdu.datalen = r; @@ -936,6 +971,10 @@ static int myeid_set_security_env(struct sc_card *card, /* store security environment to differentiate between ECDH and RSA in decipher - Hannu*/ priv->sec_env = env; + /* for symmetric operation save algo and algo flags */ + priv->algorithm_flags = env->algorithm_flags; + priv->algorithm = env->algorithm; + if (env->flags & SC_SEC_ENV_ALG_PRESENT) { sc_security_env_t tmp; @@ -982,6 +1021,13 @@ static int myeid_set_security_env(struct sc_card *card, if ((tmp.algorithm_flags & SC_ALGORITHM_AES_CBC_PAD) == SC_ALGORITHM_AES_CBC_PAD) tmp.algorithm_ref |= 0x80; /* set PKCS#7 padding */ + /* Tag 0x80 algorithm_ref - value 0x80 or 0x8A is working only for UNWRAP/WRAP + * AES is supported from version 4.0 but without pkcs#7 padding. + * For SC_SEC_OPERATION_ENCRYPT_SYM and SC_SEC_OPERATION_DECRYPT_SYM we running + * PKCS#7 in software, here we fix the algorithm_ref variable. + */ + if (IS_SYMETRIC_CRYPT(env->operation)) + tmp.algorithm_ref &= ~0x80; /* do not handle padding in card */ /* from this point, there's no difference to RSA SE */ return myeid_set_security_env_rsa(card, &tmp, se_num); @@ -1816,6 +1862,246 @@ static int myeid_finish(sc_card_t * card) return SC_SUCCESS; } +static int +myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, + u8 *out, size_t *outlen, int decipher) +{ + + struct sc_context *ctx; + + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 *sdata; + int r, padding = 0, cbc = 0; + + size_t block_size; + size_t len, rest_len; + size_t return_len = 0; + + size_t max_apdu_datalen; + size_t apdu_datalen; + + assert(card != NULL); + + ctx = card->ctx; + LOG_FUNC_CALLED(ctx); + + myeid_private_data_t *priv; + priv = (myeid_private_data_t *)card->drv_data; + + /* How many cipher blocks will fit in the APDU. We do not use the APDU chaining + * mechanism from OpenSC, because we need the size of the APDU data block + * to match a multiple of the cipher block size */ + + max_apdu_datalen = sc_get_max_send_size(card); + if (max_apdu_datalen > sc_get_max_recv_size(card)) + max_apdu_datalen = sc_get_max_recv_size(card); + + if (max_apdu_datalen > SC_MAX_APDU_BUFFER_SIZE) + max_apdu_datalen = SC_MAX_APDU_BUFFER_SIZE; + + sc_log(ctx, "algorithm %d algorithm_flags %x", priv->algorithm, priv->algorithm_flags); + + /* for C_Encrypt/C_EncryptUpdate/C_EncryptFinalize/C_Decrypt/C_DecryptUpdate/C_DecryptFinalize + * the 'outlen' is always not NULL (src/pkcs11/framework-pkcs15.c). + * For C_EncryptInit and C_DecrytpInit the 'outlen' is set to NULL + */ + if (outlen == NULL) { + /* C_EncryptInit/C_DecryptInit - clear buffers */ + sc_log(ctx, "%s (symmetric key) initialized", decipher ? "C_DecryptInit" : "C_EncryptInit"); + priv->sym_crypt_buffer_len = 0; + priv->sym_plain_buffer_len = 0; + return SC_SUCCESS; + } + + switch (priv->algorithm) { + case SC_ALGORITHM_AES: + block_size = 16; + if (priv->algorithm_flags & SC_ALGORITHM_AES_ECB) { + padding = 0; + cbc = 0; + } else if (priv->algorithm_flags & SC_ALGORITHM_AES_CBC) { + padding = 0; + cbc = 1; + } else if (priv->algorithm_flags & SC_ALGORITHM_AES_CBC_PAD) { + padding = 1; + cbc = 1; + } + break; + default: + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + } + + /* MyEID: ECB APDU must match exact cipher block size in CBC + * mode up to 240 bytes can be handled in one APDU + * round max_apdu_datalen to multiple of block_size (CBC mode) */ + + if (cbc) + max_apdu_datalen -= max_apdu_datalen % block_size; + else + max_apdu_datalen = block_size; + + /* Maybe we have more input data (from previous PSO operation). */ + rest_len = priv->sym_crypt_buffer_len; + + /* no input data from application (this is C_EncryptFinalize/C_DecryptFinalize */ + if (data == NULL) { + if (datalen != 0) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); + if (decipher) { + /* C_DecryptFinalize */ + /* decrypted buffer size must match the block size */ + if (priv->sym_plain_buffer_len != block_size) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); + /* do we have any encrypted data left? */ + if (rest_len) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); + + return_len = block_size; + if (padding) { + /* check padding */ + uint8_t i, pad_byte = *(priv->sym_plain_buffer + block_size - 1); + + sc_log(ctx, "Found padding byte %02x", pad_byte); + if (pad_byte == 0 || pad_byte > block_size) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + sdata = priv->sym_plain_buffer + block_size - pad_byte; + for (i = 0; i < pad_byte; i++) + if (sdata[i] != pad_byte) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + return_len = block_size - pad_byte; + } + *outlen = return_len; + if (return_len > *outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + memcpy(out, priv->sym_plain_buffer, return_len); + sc_log(ctx, "C_DecryptFinal %zu bytes", *outlen); + return SC_SUCCESS; + } else { + /* C_EncryptFinalize */ + if (padding) { + uint8_t pad_byte = block_size - rest_len; + sc_log(ctx, "Generating padding, padding byte: %d", pad_byte); + sdata = priv->sym_crypt_buffer + rest_len; + memset(sdata, pad_byte, pad_byte); + rest_len = block_size; + + } else if (rest_len) { + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); + } + /* fall through - encipher last block */ + } + } + /* check output buffer size */ + len = datalen + rest_len; + + sc_log(ctx, "datalen=%zu rest_len=%zu len=%zu outlen=%zu", datalen, rest_len, len, *outlen); + /* there is block_size bytes space that can be saved to next run */ + len -= (len % block_size); + + /* application can request buffer size or actual buffer size is too small */ + *outlen = len; + if (out == NULL) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + /* application buffer is too small */ + if (*outlen < len) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + + /* main loop */ + while (len >= block_size) { + if (!decipher) + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x84, 0x80); + else + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x84); + apdu.cla = 0; + + if (len > max_apdu_datalen) + apdu_datalen = max_apdu_datalen; + else + apdu_datalen = len; + + if (cbc) + apdu.cla = 0x10; + + len -= apdu_datalen; + sdata = sbuf; + + apdu.le = apdu_datalen; + apdu.lc = apdu_datalen; + apdu.datalen = apdu_datalen; + apdu.data = sbuf; + apdu.resplen = sizeof(rbuf); + apdu.resp = rbuf; + + /* do we have any data from the previous step ? */ + if (rest_len) { + memcpy(sbuf, priv->sym_crypt_buffer, rest_len); + sdata += rest_len; + apdu_datalen -= rest_len; + priv->sym_crypt_buffer_len = 0; + rest_len = 0; + } + memcpy(sdata, data, apdu_datalen); + data += apdu_datalen; + datalen -= apdu_datalen; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(ctx, r, "decrypt_sym/encrypt_sym failed"); + if (apdu.resplen != apdu.datalen) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); + memcpy(out, apdu.resp, apdu.resplen); + out += apdu.resplen; + return_len += apdu.resplen; + } + /* last block is stored in buffer and is returned to application + * in next call to C_DecryptUpdate or C_DecryptFinal. This allow us + * to compute how many bytes is to be returned after padding removal. + * Whole handling of this is here, because "data" and "out" buffer + * can be in the same place. + */ + if (decipher) { + uint8_t tmp_buf[16]; + if (return_len >= block_size) { + /* save last block to temp buffer */ + memcpy(tmp_buf, out - block_size, block_size); + if (priv->sym_plain_buffer_len) { + /* insert previous last block to output buffer */ + sc_log(ctx, "inserting block from previous decrypt"); + memmove(out - return_len + block_size, out - return_len, return_len - block_size); + memcpy(out - return_len, priv->sym_plain_buffer, block_size); + } else + return_len -= block_size; + /* save last (decrypted) block */ + memcpy(priv->sym_plain_buffer, tmp_buf, block_size); + priv->sym_plain_buffer_len = block_size; + + } else + priv->sym_plain_buffer_len = 0; + } + /* save rest of data for next run */ + priv->sym_crypt_buffer_len = datalen; + sc_log(ctx, "rest data len = %zu", datalen); + memcpy(priv->sym_crypt_buffer, data, datalen); + sc_log(ctx, "return data len = %zu", return_len); + *outlen = return_len; + return SC_SUCCESS; +} + +static int +myeid_encrypt_sym(struct sc_card *card, const u8 *data, size_t datalen, u8 *out, size_t *outlen) +{ + return myeid_enc_dec_sym(card, data, datalen, out, outlen, 0); +} +/* +static int +myeid_decrypt_sym(struct sc_card *card, const u8 *data, size_t datalen, u8 *out, size_t *outlen) +{ + return myeid_enc_dec_sym(card, data, datalen, out, outlen, 1); +} +*/ static struct sc_card_driver * sc_get_driver(void) { @@ -1847,6 +2133,8 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.pin_cmd = myeid_pin_cmd; myeid_ops.wrap = myeid_wrap_key; myeid_ops.unwrap = myeid_unwrap_key; + myeid_ops.encrypt_sym = myeid_encrypt_sym; +/* myeid_ops.decrypt_sym = myeid_decrypt_sym;*/ return &myeid_drv; } From 3cea3d0a3a68565673f1d6310283bf95164ba98f Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 11 Aug 2022 10:04:20 +0200 Subject: [PATCH 2547/4321] Github actions: AES encryption test (OsEID/MyEID) modified: .github/test-oseid.sh --- .github/test-oseid.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index f74e381163..1c992c9304 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -43,6 +43,8 @@ echo | ./OsEID-tool INIT ./OsEID-tool EC-SIGN-PKCS11-TEST ./OsEID-tool EC-ECDH-TEST ./OsEID-tool UNWRAP-WRAP-TEST +./OsEID-tool DES-AES-UPLOAD-KEYS +./OsEID-tool SYM-ENCRYPT-TEST popd # this does not work as we have random key IDs in here From 549432d5e051e29b4dff04131748692a2c48db3a Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 11 Aug 2022 10:05:18 +0200 Subject: [PATCH 2548/4321] Rename "signature_data" to "operation_data" Old name (signature_data) was confusing, because this structure is already used in encrypt and decrypt operation. Related functions are also renamed. --- src/pkcs11/mechanism.c | 76 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index c77a1da9bb..3035e8a763 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -34,7 +34,7 @@ struct hash_signature_info { }; /* Also used for verification and decryption data */ -struct signature_data { +struct operation_data { struct sc_pkcs11_object *key; struct hash_signature_info *info; sc_pkcs11_operation_t *md; @@ -42,14 +42,14 @@ struct signature_data { unsigned int buffer_len; }; -static struct signature_data * -new_signature_data() +static struct operation_data * +new_operation_data() { - return calloc(1, sizeof(struct signature_data)); + return calloc(1, sizeof(struct operation_data)); } static void -signature_data_release(struct signature_data *data) +operation_data_release(struct operation_data *data) { if (!data) return; @@ -59,7 +59,7 @@ signature_data_release(struct signature_data *data) } static CK_RV -signature_data_buffer_append(struct signature_data *data, +signature_data_buffer_append(struct operation_data *data, const CK_BYTE *in, unsigned int in_len) { if (!data) @@ -493,12 +493,12 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *key) { struct hash_signature_info *info; - struct signature_data *data; + struct operation_data *data; CK_RV rv; int can_do_it = 0; LOG_FUNC_CALLED(context); - if (!(data = new_signature_data())) + if (!(data = new_operation_data())) LOG_FUNC_RETURN(context, CKR_HOST_MEMORY); data->info = NULL; data->key = key; @@ -515,7 +515,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, } else { /* Mechanism recognised but cannot be performed by pkcs#15 card, or some general error. */ - signature_data_release(data); + operation_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } } @@ -525,7 +525,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, rv = key->ops->init_params(operation->session, &operation->mechanism); if (rv != CKR_OK) { /* Probably bad arguments */ - signature_data_release(data); + operation_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } } @@ -533,7 +533,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, /* If this is a signature with hash operation, * and card cannot perform itself signature with hash operation, * set up the hash operation */ - info = (struct hash_signature_info *) operation->type->mech_data; + info = (struct hash_signature_info *)operation->type->mech_data; if (info != NULL && !can_do_it) { /* Initialize hash operation */ @@ -544,7 +544,7 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, rv = info->hash_type->md_init(data->md); if (rv != CKR_OK) { sc_pkcs11_release_operation(&data->md); - signature_data_release(data); + operation_data_release(data); LOG_FUNC_RETURN(context, (int) rv); } data->info = info; @@ -558,12 +558,12 @@ static CK_RV sc_pkcs11_signature_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { - struct signature_data *data; + struct operation_data *data; CK_RV rv; LOG_FUNC_CALLED(context); sc_log(context, "data part length %li", ulPartLen); - data = (struct signature_data *) operation->priv_data; + data = (struct operation_data *)operation->priv_data; if (data->md) { rv = data->md->type->md_update(data->md, pPart, ulPartLen); LOG_FUNC_RETURN(context, (int) rv); @@ -578,11 +578,11 @@ static CK_RV sc_pkcs11_signature_final(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { - struct signature_data *data; + struct operation_data *data; CK_RV rv; LOG_FUNC_CALLED(context); - data = (struct signature_data *) operation->priv_data; + data = (struct operation_data *)operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; CK_BYTE hash[64]; @@ -612,7 +612,7 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) CK_ATTRIBUTE attr_key_type = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; CK_RV rv; - key = ((struct signature_data *) operation->priv_data)->key; + key = ((struct operation_data *)operation->priv_data)->key; /* * EC and GOSTR do not have CKA_MODULUS_BITS attribute. * But other code in framework treats them as if they do. @@ -650,11 +650,11 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) } static void -sc_pkcs11_signature_release(sc_pkcs11_operation_t *operation) +sc_pkcs11_operation_release(sc_pkcs11_operation_t *operation) { if (!operation) return; - signature_data_release(operation->priv_data); + operation_data_release(operation->priv_data); } #ifdef ENABLE_OPENSSL @@ -761,10 +761,10 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *key) { struct hash_signature_info *info; - struct signature_data *data; + struct operation_data *data; CK_RV rv; - if (!(data = new_signature_data())) + if (!(data = new_operation_data())) return CKR_HOST_MEMORY; data->info = NULL; @@ -819,9 +819,9 @@ static CK_RV sc_pkcs11_verify_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { - struct signature_data *data; + struct operation_data *data; - data = (struct signature_data *) operation->priv_data; + data = (struct operation_data *)operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; @@ -837,7 +837,7 @@ static CK_RV sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { - struct signature_data *data; + struct operation_data *data; struct sc_pkcs11_object *key; unsigned char *pubkey_value = NULL; CK_KEY_TYPE key_type; @@ -847,7 +847,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, CK_ATTRIBUTE attr_key_params = {CKA_GOSTR3410_PARAMS, ¶ms, sizeof(params)}; CK_RV rv; - data = (struct signature_data *) operation->priv_data; + data = (struct operation_data *)operation->priv_data; if (pSignature == NULL) return CKR_ARGUMENTS_BAD; @@ -1295,10 +1295,10 @@ static CK_RV sc_pkcs11_encrypt_init(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *key) { - struct signature_data *data; + struct operation_data *data; CK_RV rv; - if (!(data = new_signature_data())) + if (!(data = new_operation_data())) return CKR_HOST_MEMORY; data->key = key; @@ -1326,7 +1326,7 @@ sc_pkcs11_encrypt(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { - struct signature_data *data; + struct operation_data *data; struct sc_pkcs11_object *key; CK_RV rv; CK_ULONG ulEncryptedDataLen, ulLastEncryptedPartLen; @@ -1338,7 +1338,7 @@ sc_pkcs11_encrypt(sc_pkcs11_operation_t *operation, ulEncryptedDataLen = pulEncryptedDataLen ? *pulEncryptedDataLen : 0; ulLastEncryptedPartLen = ulEncryptedDataLen; - data = (struct signature_data *)operation->priv_data; + data = (struct operation_data *)operation->priv_data; key = data->key; @@ -1372,7 +1372,7 @@ sc_pkcs11_encrypt_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { - struct signature_data *data; + struct operation_data *data; struct sc_pkcs11_object *key; CK_RV rv; CK_ULONG ulEncryptedPartLen; @@ -1383,7 +1383,7 @@ sc_pkcs11_encrypt_update(sc_pkcs11_operation_t *operation, ulEncryptedPartLen = pulEncryptedPartLen ? *pulEncryptedPartLen : 0; - data = (struct signature_data *)operation->priv_data; + data = (struct operation_data *)operation->priv_data; key = data->key; @@ -1400,7 +1400,7 @@ sc_pkcs11_encrypt_final(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) { - struct signature_data *data; + struct operation_data *data; struct sc_pkcs11_object *key; CK_RV rv; CK_ULONG ulLastEncryptedPartLen; @@ -1411,7 +1411,7 @@ sc_pkcs11_encrypt_final(sc_pkcs11_operation_t *operation, ulLastEncryptedPartLen = pulLastEncryptedPartLen ? *pulLastEncryptedPartLen : 0; - data = (struct signature_data *)operation->priv_data; + data = (struct operation_data *)operation->priv_data; key = data->key; @@ -1430,10 +1430,10 @@ static CK_RV sc_pkcs11_decrypt_init(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *key) { - struct signature_data *data; + struct operation_data *data; CK_RV rv; - if (!(data = new_signature_data())) + if (!(data = new_operation_data())) return CKR_HOST_MEMORY; data->key = key; @@ -1459,10 +1459,10 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - struct signature_data *data; + struct operation_data *data; struct sc_pkcs11_object *key; - data = (struct signature_data*) operation->priv_data; + data = (struct operation_data *)operation->priv_data; key = data->key; return key->ops->decrypt(operation->session, @@ -1544,7 +1544,7 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, mt->copy_mech_data = copy_priv_data; mt->obj_size = sizeof(sc_pkcs11_operation_t); - mt->release = sc_pkcs11_signature_release; + mt->release = sc_pkcs11_operation_release; if (pInfo->flags & CKF_SIGN) { mt->sign_init = sc_pkcs11_signature_init; From d55ed8a950b24a27170de7b5d4dd48cbec7c78a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Aug 2022 14:37:41 +0200 Subject: [PATCH 2549/4321] Remove trailing and bogus whitespace --- src/libopensc/card-starcos.c | 118 +++++++++++++++++------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index ffe4238bb1..d28f807d7a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1,7 +1,7 @@ /* * card-starcos.c: Support for STARCOS SPK 2.3 cards * - * Copyright (C) 2003 Jörn Zukowski and + * Copyright (C) 2003 Jörn Zukowski and * Nils Larsch , TrustCenter AG * * This library is free software; you can redistribute it and/or @@ -59,7 +59,7 @@ static struct sc_card_driver starcos_drv = { NULL, 0, NULL }; -static const struct sc_card_error starcos_errors[] = +static const struct sc_card_error starcos_errors[] = { { 0x6600, SC_ERROR_INCORRECT_PARAMETERS, "Error setting the security env"}, { 0x66F0, SC_ERROR_INCORRECT_PARAMETERS, "No space left for padding"}, @@ -85,7 +85,7 @@ typedef struct starcos_ex_data_st { unsigned int pin_encoding; } starcos_ex_data; -/* +/* This constant allows signing or decrypting with RSA keys up to 4096 bits. */ @@ -179,7 +179,7 @@ static int starcos_parse_supported_sec_mechanisms(struct sc_card *card, const un LOG_FUNC_RETURN(ctx, SC_SUCCESS); } } - + LOG_FUNC_RETURN(ctx, SC_ERROR_TEMPLATE_NOT_FOUND); } @@ -260,7 +260,7 @@ static int starcos_determine_pin_format35(sc_card_t *card, unsigned int * pin_fo /** * Determine v3.x PIN encoding by parsing either * EF.PWDD (for v3.4) or EF.KEYD (for v3.5) - * + * * It returns an OpenSC PIN encoding, using the default value on failure */ static unsigned int starcos_determine_pin_encoding(sc_card_t *card) @@ -310,7 +310,7 @@ static int starcos_probe_reader_for_ext_apdu(sc_card_t * card) { apdu.le = apdu.resplen; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "Failed to send Get Data ext. APDU"); - return (apdu.sw1 == 0x90 && apdu.sw2 == 0x00); + return (apdu.sw1 == 0x90 && apdu.sw2 == 0x00); } static int starcos_select_mf(sc_card_t * card) { @@ -323,7 +323,7 @@ static int starcos_select_mf(sc_card_t * card) { apdu.data = mf_buf; apdu.datalen = 2; apdu.resplen = 0; - + return sc_transmit_apdu(card, &apdu); } @@ -367,7 +367,7 @@ static int starcos_init(sc_card_t *card) card->drv_data = (void *)ex_data; ex_data->pin_encoding = PIN_ENCODING_DETERMINE; - flags = SC_ALGORITHM_RSA_PAD_PKCS1 + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_ISO9796 | SC_ALGORITHM_RSA_HASH_NONE @@ -376,7 +376,7 @@ static int starcos_init(sc_card_t *card) | SC_ALGORITHM_RSA_HASH_RIPEMD160 | SC_ALGORITHM_RSA_HASH_MD5_SHA1; - card->caps = SC_CARD_CAP_RNG; + card->caps = SC_CARD_CAP_RNG; if ( IS_V3x(card) ) { @@ -482,7 +482,7 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - + sc_log(ctx, "processing FCI bytes\n"); if (buflen < 2) @@ -500,16 +500,16 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, file->shareable = 0; file->record_length = 0; file->size = 0; - + tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_log(ctx, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } - tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen); + tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen); if (tag != NULL) { const char *type = "unknown"; const char *structure = "unknown"; @@ -553,9 +553,9 @@ static int process_fci(sc_context_t *ctx, sc_file_t *file, } } - sc_log(ctx, + sc_log(ctx, " type: %s\n", type); - sc_log(ctx, + sc_log(ctx, " EF structure: %s\n", structure); } file->magic = SC_FILE_MAGIC; @@ -569,7 +569,7 @@ static int process_fci_v3_4(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_log(ctx, + sc_log(ctx, "processing %"SC_FORMAT_LEN_SIZE_T"u FCI bytes\n", buflen); if (buflen < 2) @@ -605,7 +605,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, size_t taglen, len = buflen; const u8 *tag = NULL, *p; - sc_log(ctx, + sc_log(ctx, "processing %"SC_FORMAT_LEN_SIZE_T"u FCP bytes\n", buflen); if (buflen < 2) @@ -620,7 +620,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_log(ctx, + sc_log(ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -628,7 +628,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, tag = sc_asn1_find_tag(ctx, p, len, 0xc5, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_log(ctx, + sc_log(ctx, " bytes in file 2: %d\n", bytes); file->size = bytes; } @@ -682,9 +682,9 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, break; } } - sc_log(ctx, + sc_log(ctx, " type: %s\n", type); - sc_log(ctx, + sc_log(ctx, " EF structure: %s\n", structure); if (taglen >= 2) { if (tag[1] != 0x41 || taglen != 5) { @@ -693,7 +693,7 @@ static int process_fcp_v3_4(sc_context_t *ctx, sc_file_t *file, /* formatted EF */ file->record_length = (tag[2] << 8) + tag[3]; file->record_count = tag[4]; - sc_log(ctx, + sc_log(ctx, " rec_len: %"SC_FORMAT_LEN_SIZE_T"u rec_cnt: %"SC_FORMAT_LEN_SIZE_T"u\n\n", file->record_length, file->record_count); } @@ -760,8 +760,8 @@ static int starcos_select_aid(sc_card_t *card, /* check return value */ if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 ) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); + /* update cache */ card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; card->cache.current_path.len = len; @@ -776,7 +776,7 @@ static int starcos_select_aid(sc_card_t *card, file->path.len = 0; file->size = 0; /* AID */ - for (i = 0; i < len; i++) + for (i = 0; i < len; i++) file->name[i] = aid[i]; file->namelen = len; file->id = 0x0000; @@ -942,14 +942,14 @@ static int starcos_select_file(sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_log(card->ctx, + sc_log(card->ctx, "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", cache_valid ? "valid" : "invalid", pbuf, card->cache.current_path.len); - if ( in_path->len > sizeof(pathbuf) ) { + if ( in_path->len > sizeof(pathbuf) ) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); } memcpy(path, in_path->value, in_path->len); @@ -958,14 +958,14 @@ static int starcos_select_file(sc_card_t *card, if (in_path->aid.len) { if (!pathlen) { - if ( in_path->aid.len > sizeof(pathbuf) ) { + if ( in_path->aid.len > sizeof(pathbuf) ) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); } memcpy(path, in_path->aid.value, in_path->aid.len); pathlen = in_path->aid.len; pathtype = SC_PATH_TYPE_DF_NAME; } else { - if (!cache_valid + if (!cache_valid || card->cache.current_path.type != SC_PATH_TYPE_DF_NAME || card->cache.current_path.len != pathlen || memcmp(card->cache.current_path.value, in_path->aid.value, in_path->aid.len) != 0 ) { @@ -977,7 +977,7 @@ static int starcos_select_file(sc_card_t *card, pathtype = SC_PATH_TYPE_FILE_ID; } } - } + } if (pathtype == SC_PATH_TYPE_FILE_ID) { /* SELECT EF/DF with ID */ @@ -989,7 +989,7 @@ static int starcos_select_file(sc_card_t *card, else if (pathtype == SC_PATH_TYPE_DF_NAME) { /* SELECT DF with AID */ /* Select with 1-16byte Application-ID */ - if (cache_valid + if (cache_valid && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME && card->cache.current_path.len == pathlen && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) @@ -1028,16 +1028,16 @@ static int starcos_select_file(sc_card_t *card, pathlen += 2; } } - + /* check current working directory */ - if (cache_valid + if (cache_valid && card->cache.current_path.type == SC_PATH_TYPE_PATH && card->cache.current_path.len >= 2 && card->cache.current_path.len <= pathlen ) { bMatch = 0; for (i=0; i < card->cache.current_path.len; i+=2) - if (card->cache.current_path.value[i] == path[i] + if (card->cache.current_path.value[i] == path[i] && card->cache.current_path.value[i+1] == path[i+1] ) bMatch += 2; @@ -1058,23 +1058,23 @@ static int starcos_select_file(sc_card_t *card, { /* two more steps to go */ sc_path_t new_path; - + /* first step: change directory */ r = starcos_select_fid(card, path[bMatch], path[bMatch+1], NULL, 0); LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - memset(&new_path, 0, sizeof(sc_path_t)); + + memset(&new_path, 0, sizeof(sc_path_t)); new_path.type = SC_PATH_TYPE_PATH; new_path.len = pathlen - bMatch-2; memcpy(new_path.value, &(path[bMatch+2]), new_path.len); /* final step: select file */ return starcos_select_file(card, &new_path, file_out); - } + } else /* if (bMatch - pathlen == 0) */ { /* done: we are already in the * requested directory */ - sc_log(card->ctx, + sc_log(card->ctx, "cache hit\n"); /* copy file info (if necessary) */ if (file_out) { @@ -1154,7 +1154,7 @@ static u8 process_acl_entry(sc_file_t *in, unsigned int method, unsigned int in_ * * This function tries to create a somewhat usable Starcos spk 2.3 acl * from the OpenSC internal acl (storing the result in the supplied - * sc_starcos_create_data structure). + * sc_starcos_create_data structure). */ static int starcos_process_acl(sc_card_t *card, sc_file_t *file, sc_starcos_create_data *data) @@ -1288,7 +1288,7 @@ static int starcos_process_acl(sc_card_t *card, sc_file_t *file, * \param card pointer to the sc_card structure * \param data pointer to a sc_starcos_create_data object * \return SC_SUCCESS or error code - * + * * This function creates the MF based on the information stored * in the sc_starcos_create_data.mf structure. Note: CREATE END must be * called separately to activate the ACs. @@ -1310,7 +1310,7 @@ static int starcos_create_mf(sc_card_t *card, sc_starcos_create_data *data) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); - return sc_check_sw(card, apdu.sw1, apdu.sw2); + return sc_check_sw(card, apdu.sw1, apdu.sw2); } /** starcos_create_df @@ -1370,7 +1370,7 @@ static int starcos_create_df(sc_card_t *card, sc_starcos_create_data *data) * the sc_starcos_create_data.ef data structure. */ static int starcos_create_ef(sc_card_t *card, sc_starcos_create_data *data) -{ +{ int r; sc_apdu_t apdu; sc_context_t *ctx = card->ctx; @@ -1431,7 +1431,7 @@ static int starcos_create_end(sc_card_t *card, sc_file_t *file) * information in the sc_file structure (using starcos_process_acl). */ static int starcos_create_file(sc_card_t *card, sc_file_t *file) -{ +{ int r; sc_starcos_create_data data; @@ -1483,7 +1483,7 @@ static int starcos_erase_card(sc_card_t *card) apdu.lc = 2; apdu.datalen = 2; apdu.data = sbuf; - + r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_invalidate_cache(card); @@ -1588,7 +1588,7 @@ static int starcos_gen_key(sc_card_t *card, sc_starcos_gen_key_data *data) CHECK_NOT_SUPPORTED_V3_4(card); /* generate key */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, data->key_id); apdu.le = 0; sbuf[0] = (u8)(data->key_length >> 8); @@ -1654,7 +1654,7 @@ static int starcos_set_security_env(sc_card_t *card, p = sbuf; if ( IS_V3x(card) ) { - u8 algorithm_supported = (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || + u8 algorithm_supported = (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) || (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS); if (!algorithm_supported || !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { @@ -1708,7 +1708,7 @@ static int starcos_set_security_env(sc_card_t *card, break; default: - sc_log(card->ctx, + sc_log(card->ctx, "not supported for STARCOS 3.4 cards"); return SC_ERROR_NOT_SUPPORTED; } @@ -1804,7 +1804,7 @@ static int starcos_set_security_env(sc_card_t *card, apdu.datalen = p - sbuf; apdu.lc = p - sbuf; apdu.le = 0; - /* we don't know whether to use + /* we don't know whether to use * COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */ r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -1820,7 +1820,7 @@ static int starcos_set_security_env(sc_card_t *card, } try_authenticate: /* try INTERNAL AUTHENTICATE */ - if (operation == SC_SEC_OPERATION_AUTHENTICATE && + if (operation == SC_SEC_OPERATION_AUTHENTICATE && env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { *p++ = 0x80; *p++ = 0x01; @@ -1858,7 +1858,7 @@ static int starcos_compute_signature(sc_card_t *card, if (ex_data->sec_ops == SC_SEC_OPERATION_SIGN) { /* compute signature with the COMPUTE SIGNATURE command */ - + if ( IS_V3x(card) ) { size_t tmp_len; @@ -2050,9 +2050,9 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) const int err_count = sizeof(starcos_errors)/sizeof(starcos_errors[0]); int i; - sc_log(card->ctx, + sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); - + if (sw1 == 0x90) return SC_SUCCESS; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) @@ -2061,7 +2061,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } - + /* check starcos error messages */ for (i = 0; i < err_count; i++) if (starcos_errors[i].SWs == ((sw1 << 8) | sw2)) @@ -2069,7 +2069,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) sc_log(card->ctx, "%s\n", starcos_errors[i].errorstr); return starcos_errors[i].errorno; } - + /* iso error */ return iso_ops->check_sw(card, sw1, sw2); } @@ -2154,7 +2154,7 @@ static int starcos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) /** * starcos_logout_v3_x() * StarCOS 3.x cards will not clear the security status by selecting MF. - * Returning NOT_SUPPORTED would cause card reset, effectively invalidating + * Returning NOT_SUPPORTED would cause card reset, effectively invalidating * the security status. */ static int starcos_logout_v3_x(sc_card_t *card) @@ -2181,7 +2181,7 @@ static int starcos_logout(sc_card_t *card) apdu.data = mf_buf; apdu.datalen = 2; apdu.resplen = 0; - + r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU re-transmit failed"); @@ -2214,7 +2214,7 @@ static struct sc_card_driver * sc_get_driver(void) struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); if (iso_ops == NULL) iso_ops = iso_drv->ops; - + starcos_ops = *iso_drv->ops; starcos_ops.match_card = starcos_match_card; starcos_ops.init = starcos_init; @@ -2230,7 +2230,7 @@ static struct sc_card_driver * sc_get_driver(void) starcos_ops.card_ctl = starcos_card_ctl; starcos_ops.logout = starcos_logout; starcos_ops.pin_cmd = starcos_pin_cmd; - + return &starcos_drv; } From ad7709725447c07697ed3f6eaf1de7e5e466be6d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Aug 2022 14:38:14 +0200 Subject: [PATCH 2550/4321] Fix spelling according to the codespell --- src/libopensc/card-starcos.c | 17 ++++++++--------- src/pkcs11/pkcs11-display.c | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index d28f807d7a..4705726903 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1542,16 +1542,15 @@ static int starcos_write_key(sc_card_t *card, sc_starcos_wkey_data *data) tlen = data->key_len; while (tlen != 0) { /* transmit the key in chunks of STARCOS_WKEY_CSIZE bytes */ - u8 clen = tlen < STARCOS_WKEY_CSIZE ? tlen : STARCOS_WKEY_CSIZE; + u8 c_len = tlen < STARCOS_WKEY_CSIZE ? tlen : STARCOS_WKEY_CSIZE; sbuf[0] = 0xc2; - sbuf[1] = 3 + clen; + sbuf[1] = 3 + c_len; sbuf[2] = data->kid; sbuf[3] = (offset >> 8) & 0xff; sbuf[4] = offset & 0xff; - memcpy(sbuf+5, p, clen); - len = 5 + clen; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xf4, - data->mode, 0x00); + memcpy(sbuf+5, p, c_len); + len = 5 + c_len; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xf4, data->mode, 0x00); apdu.cla |= 0x80; apdu.lc = len; apdu.datalen = len; @@ -1561,9 +1560,9 @@ static int starcos_write_key(sc_card_t *card, sc_starcos_wkey_data *data) LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return sc_check_sw(card, apdu.sw1, apdu.sw2); - offset += clen; - p += clen; - tlen -= clen; + offset += c_len; + p += c_len; + tlen -= c_len; } return SC_SUCCESS; } diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 97b1622030..da4cb528cf 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -172,7 +172,7 @@ print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P ascii_ptr++; } - /* padd */ + /* padding */ while (strlen(hex) < 3*16) strcat(hex, " "); fprintf(f, "\n %08X %s %s", offset, hex, ascii); From 669f677e4c4e27203c69c901bac0b1887106db2f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Aug 2022 14:47:50 +0200 Subject: [PATCH 2551/4321] README: Provide download links --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index da373420e8..31b781d944 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,27 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. +Do NOT use any links from wiki to download the OpenSC because wiki can be modified by anybody, see +[#2554](https://github.com/OpenSC/OpenSC/issues/2554). For downloading OpenSC, use the links here in README. + +# Downloads + +[OpenSC 0.22.0](https://github.com/OpenSC/OpenSC/releases/tag/0.22.0) is the latest stable version released on 10.08.2021. It is available as + + * Windows installer + * [OpenSC-0.22.0_win64.msi](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0_win64.msi) for 64 bit programs + * [OpenSC-0.22.0_win32.msi](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0_win32.msi) for 32 bit programs + * [OpenSC-0.22.0.dmg](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0.dmg): macOS installer + * [opensc-0.22.0.tar.gz](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/opensc-0.22.0.tar.gz): Source code distribution + +## Nightly build + +The latest source code is available through [GitHub](https://github.com/OpenSC/OpenSC/archive/master.zip). +Nightly builds are available by their git hash in branches of [OpenSC/Nightly](https://github.com/OpenSC/Nightly). + + +# Build and testing status + [![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) [![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) From b774a15862774da8f5aa48153ff57583e5430407 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Aug 2022 14:59:09 +0200 Subject: [PATCH 2552/4321] Add simple .editorconfig --- .editorconfig | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..51ac6a487a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +charset = utf-8 +max_line_length = 110 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{c,h}] +indent_style = tab +tab_width = 4 + +[{Makefile.am,configure.ac}] +indent_style = tab +tab_width = 4 + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 From fa2eab861714a64371a3e2317e096862f1d9e4c8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 6 Sep 2022 08:53:54 -0500 Subject: [PATCH 2553/4321] Update card-piv.c with PIVKey ATRs for current cards In response to Issue #1531, PIVkey was contacted to provide the list of ATRs for curent PKvKey devices. gw@taglio.com provided list of ATRs which included previously known cards. Some of these ATRs may be used by other card drivers. But will only be accepted by card-piv.c if the card responds to a SELECT PIV AID. On branch PIVKey-ATR Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 54 +++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 4bb28c764a..41fe76252f 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -239,19 +239,49 @@ static const struct sc_atr_table piv_atrs[] = { { "3B:D8:18:00:80:B1:FE:45:1F:07:80:31:C1:64:08:06:92:0F:D5", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, { "3b:86:80:01:80:31:c1:52:41:1a:7e", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */ - - /* PIVKEY from Taligo */ - /* PIVKEY T600 token and T800 on Feitian eJAVA */ - { "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:00:64:2D:70:C1:72:FE:E0:FE", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, - - /* PIVKEY C910 */ + /* Following PIVKEY entries are from Windows registry provided by gw@taglio.com 2022-09-05 */ + /* PIVKEY PIVKey Feitian (02) */ + { "3b:9f:95:81:31:fe:9f:00:66:46:53:05:10:00:11:71:df:00:00:00:00:00:02", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey Feitian (7C) aka C910 contactless */ + { "3b:8c:80:01:90:67:46:4a:00:64:16:06:f2:72:7e:00:7c", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /*PIVKey Feitian (E0) aka C910 */ { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:16:06:f2:72:7e:00:e0", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, - { "3b:8c:80:01:90:67:46:4a:00:64:16:06:f2:72:7e:00:7c", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, /* contactless */ - - - /* PIVKEY C980 */ - { "3B:f9:96:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:28", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, - { "3b:89:80:01:53:50:49:56:4b:45:59:37:30:44", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, /* contactless */ + /* PIVKey Feitian (FE) aka PIVKEY T600 token and T800 on Feitian eJAVA */ + { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:2d:70:c1:72:fe:e0:fe", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP241 (AD) */ + { "3b:f9:13:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:ad", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP242R2 (16) */ + { "3b:88:80:01:50:49:56:4b:45:59:37:30:16", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP242R2 (5E) */ + { "3b:88:80:01:4a:43:4f:50:76:32:34:31:5e", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP242R2 (B7) */ + { "3b:f8:13:00:00:81:31:fe:45:4a:43:4f:50:76:32:34:31:b7", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP3 (67) */ + { "3b:88:80:01:46:49:44:45:53:4d:4f:31:67", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP3 (8E) */ + { "3b:f8:13:00:00:81:31:fe:45:46:49:44:45:53:4d:4f:31:8e", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey JCOP31 (57) */ + { "3b:f9:18:00:ff:81:31:fe:45:4a:43:4f:50:33:31:56:32:32:57", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey NXP JCOP (03) */ + { "3b:8a:80:01:01:50:49:56:4b:45:59:37:30:16:03", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey NXP JCOP (FF) aka CP70 */ + { "3b:f8:13:00:00:81:31:fe:45:50:49:56:4b:45:59:37:30:ff", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey SLE78 (3B) */ + { "3b:8d:80:01:53:4c:4a:35:32:47:44:4c:31:32:38:43:52:3b", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey SLE78 (6D) */ + { "3b:88:80:01:00:00:00:11:77:81:83:00:6d", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey SLE78 (28) aka C980 */ + { "3b:f9:96:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:28", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey SLE78 (44) aka C980 contactless */ + { "3b:89:80:01:53:50:49:56:4b:45:59:37:30:44", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey SLE78 (57B) */ + { "3b:fd:96:00:00:81:31:fe:45:53:4c:4a:35:32:47:44:4c:31:32:38:43:52:57", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey uTrust (01) ISO 14443 Type B without historical bytes */ + { "3b:80:80:01:01", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey uTrust (73) */ + { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* PIVKey uTrust FIDO2 (73) */ + { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, /* ID-One PIV 2.4.1 on Cosmo V8.1 */ { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, From ac0f9473d0f000e6064f4d7778a524234581af88 Mon Sep 17 00:00:00 2001 From: Andrey Timofeev Date: Mon, 8 Aug 2022 01:04:10 -0700 Subject: [PATCH 2554/4321] pkcs15-init: Fix formatting rtecp cards --- src/pkcs15init/pkcs15-rtecp.c | 2 ++ src/pkcs15init/rutoken_ecp.profile | 8 ++++++++ src/pkcs15init/rutoken_lite.profile | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 35f629747d..843448af14 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -120,6 +120,8 @@ static int rtecp_init(sc_profile_t *profile, sc_pkcs15_card_t *p15card) create_sysdf(profile, card, "Resrv2-DF"); create_sysdf(profile, card, "Resrv3-DF"); create_sysdf(profile, card, "Resrv4-DF"); + create_sysdf(profile, card, "Resrv5-DF"); + create_sysdf(profile, card, "Resrv6-DF"); return sc_select_file(card, sc_get_mf_path(), NULL); } diff --git a/src/pkcs15init/rutoken_ecp.profile b/src/pkcs15init/rutoken_ecp.profile index 3ff4d3fa97..3b6f0a2909 100644 --- a/src/pkcs15init/rutoken_ecp.profile +++ b/src/pkcs15init/rutoken_ecp.profile @@ -110,6 +110,14 @@ filesystem { DF Resrv1-DF { file-id = 1001; + + DF Resrv5-DF { + file-id = 8001; + } + + DF Resrv6-DF { + file-id = 8002; + } } DF Resrv2-DF { file-id = 1002; diff --git a/src/pkcs15init/rutoken_lite.profile b/src/pkcs15init/rutoken_lite.profile index 60c924e14f..d6be963d35 100644 --- a/src/pkcs15init/rutoken_lite.profile +++ b/src/pkcs15init/rutoken_lite.profile @@ -90,6 +90,14 @@ filesystem { DF Resrv1-DF { file-id = 1001; + + DF Resrv5-DF { + file-id = 8001; + } + + DF Resrv6-DF { + file-id = 8002; + } } DF Resrv2-DF { file-id = 1002; From 79752170ca68b1f2fa3b2931bd2ae51421e47d0c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 13 Mar 2022 13:56:43 -0500 Subject: [PATCH 2555/4321] Minidriver fixes for key sizes for ECC "CardGetProperty" "CP_CARD_KEYSIZES" passes key_type in dwFlags SC_ALGORITHM_EXT_EC_NAMEDCURVE in not in the flags, but in ext_flags so remove from the test. If any test is needed it should be to match the curve name to suported by Windows. Date: Sun Mar 13 13:56:43 2022 -0500 On branch minidriver-ECC Changes to be committed: modified: minidriver.c --- src/minidriver/minidriver.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index b8621ef090..b35aab7c36 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2788,7 +2788,8 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi for (i = 0; i < count; i++) { algo_info = vs->p15card->card->algorithms + i; if (algo_info->algorithm == SC_ALGORITHM_EC) { - flag = SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_EXT_EC_NAMEDCURVE; + flag = SC_ALGORITHM_ECDH_CDH_RAW; + /* TODO check if namedCurve matches Windows supported curves */ /* ECDHE */ if ((dwKeySpec == AT_ECDHE_P256) && (algo_info->key_length == 256) && (algo_info->flags & flag)) { keysize = 256; @@ -2803,11 +2804,12 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi break; } /* ECDSA */ - flag = SC_ALGORITHM_ECDSA_HASH_NONE| + flag = SC_ALGORITHM_ECDSA_RAW| + SC_ALGORITHM_ECDSA_HASH_NONE| SC_ALGORITHM_ECDSA_HASH_SHA1| SC_ALGORITHM_ECDSA_HASH_SHA224| - SC_ALGORITHM_ECDSA_HASH_SHA256| - SC_ALGORITHM_EXT_EC_NAMEDCURVE; + SC_ALGORITHM_ECDSA_HASH_SHA256; + /* TODO check if namedCurve matches Windows supported curves */ if ((dwKeySpec == AT_ECDSA_P256) && (algo_info->key_length == 256) && (algo_info->flags & flag)) { keysize = 256; break; @@ -6284,7 +6286,8 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, if (cbData < sizeof(*pKeySizes)) MD_FUNC_RETURN(pCardData, 1, ERROR_INSUFFICIENT_BUFFER); - dwret = md_query_key_sizes(pCardData, 0, pKeySizes); + /* dwFlags has key_type */ + dwret = md_query_key_sizes(pCardData, dwFlags, pKeySizes); if (dwret != SCARD_S_SUCCESS) MD_FUNC_RETURN(pCardData, 1, dwret); } From 01af6dc541828df5c64e47faf95e710f4a90a23d Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 17 Mar 2022 11:05:10 -0500 Subject: [PATCH 2556/4321] Minidriver Support 32 keys on card Newer cards can have more then 12 key on card. Minidriver uses a fixed MD_MAX_KEY_CONTAINERS 12 change to 32 Changes to be committed: modified: minidriver.c --- src/minidriver/minidriver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index b35aab7c36..8492f0c585 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -98,7 +98,7 @@ HINSTANCE g_inst; #define NULLSTR(a) (a == NULL ? "" : a) #define NULLWSTR(a) (a == NULL ? L"" : a) -#define MD_MAX_KEY_CONTAINERS 12 +#define MD_MAX_KEY_CONTAINERS 32 #define MD_CARDID_SIZE 16 #define MD_ROLE_USER_SIGN (ROLE_ADMIN + 1) From b51471439d880fda3098a3d5f2ea3db44096e5fc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 17 Mar 2022 11:08:34 -0500 Subject: [PATCH 2557/4321] minidriver better debugging for ECC keys Changes to be committed: modified: minidriver.c --- src/minidriver/minidriver.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 8492f0c585..2440873330 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -3690,8 +3690,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine memcpy(((PBYTE)publicKey) + sizeof(BCRYPT_ECCKEY_BLOB), pubkey_der.value + 3, pubkey_der.len -3); logprintf(pCardData, 3, - "return info on ECC SIGN_CONTAINER_INDEX %u\n", - (unsigned int)bContainerIndex); + "return info on ECC SIGN_CONTAINER_INDEX %u cbKey:%u dwMagic:%u\n", + (unsigned int)bContainerIndex, + (unsigned int)publicKey->cbKey, + (unsigned int)publicKey->dwMagic); } if (cont->size_key_exchange) { sz = (DWORD) (sizeof(BCRYPT_ECCKEY_BLOB) + pubkey_der.len -3); @@ -3729,14 +3731,23 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine memcpy(((PBYTE)publicKey) + sizeof(BCRYPT_ECCKEY_BLOB), pubkey_der.value + 3, pubkey_der.len -3); logprintf(pCardData, 3, - "return info on ECC KEYX_CONTAINER_INDEX %u\n", - (unsigned int)bContainerIndex); + "return info on ECC KEYX_CONTAINER_INDEX %u cbKey:%u dwMagic:%u\n", + (unsigned int)bContainerIndex, + (unsigned int)publicKey->cbKey, + (unsigned int)publicKey->dwMagic); } } } logprintf(pCardData, 7, "returns container(idx:%u) info\n", (unsigned int)bContainerIndex); + logprintf(pCardData, 1, + "CardGetContainerInfo bContainerIndex=%u, dwFlags=0x%08X, dwVersion=%lu, cbSigPublicKey=%lu, cbKeyExPublicKey=%lu\n", + (unsigned int)bContainerIndex, (unsigned int)dwFlags, + (unsigned long)pContainerInfo->dwVersion, + (unsigned long)pContainerInfo->cbSigPublicKey, + (unsigned long)pContainerInfo->cbKeyExPublicKey); + err: free(pubkey_der.value); unlock(pCardData); From 256802805b5706ed5cf09851a652c3ecee2f9c05 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 17 Mar 2022 09:55:35 -0500 Subject: [PATCH 2558/4321] Register minidriver without replacing "Crypto Provider" Cards with ECC keys need in registry both: "Crypto Provider"="Microsoft Base Smart Card Crypto Provider" "Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" So instead of replacing the crypto Provider, add "InstalledBy"="OpenSC" Then when uninstalling drivers, only uninstall drivers which have "OpenSC" On branch minidriver-ECC Changes to be committed: modified: customactions.cpp --- win32/customactions.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index d3266d97c3..c6afe04dc3 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -49,8 +49,10 @@ #define X86onX64_SC_DATABASE TEXT("SOFTWARE\\Wow6432Node\\Microsoft\\Cryptography\\Calais\\SmartCards") #define SC_DATABASE TEXT("SOFTWARE\\Microsoft\\Cryptography\\Calais\\SmartCards") -#define BASE_CSP TEXT("OpenSC CSP") +#define BASE_CSP TEXT("Microsoft Base Smart Card Crypto Provider") #define BASE_KSP TEXT("Microsoft Smart Card Key Storage Provider") +#define BASE_INSTALLED_BY_KEY TEXT("InstalledBy") +#define BASE_INSTALLED_BY_VALUE TEXT("OpenSC") typedef struct _MD_REGISTRATION { @@ -199,7 +201,8 @@ MD_REGISTRATION minidriver_registration[] = { }; -/* remove a card in the database if and only if the CSP match the OpenSC CSP +/* remove a card in the database if and only if the BASE_INSTALLED_BY_KEY is present and has value of BASE INSTALLED_BY_VALUE +It also will not install drivers installed by other or modified by a user (who should have changed the BASE INSTALLED_BY_VALUE The program try to avoid any failure to not break the uninstall process */ VOID RemoveKey(PTSTR szSubKey) { @@ -226,13 +229,13 @@ VOID RemoveKey(PTSTR szSubKey) lResult = RegOpenKeyEx (hKey, szName, 0, KEY_READ, &hTempKey); if (lResult == ERROR_SUCCESS) { - TCHAR szCSP[MAX_PATH] = {0}; + TCHAR szIB[MAX_PATH] = {0}; dwSize = MAX_PATH; - lResult = RegQueryValueEx(hTempKey, TEXT("Crypto Provider"), NULL, NULL, (PBYTE) szCSP, &dwSize); + lResult = RegQueryValueEx(hTempKey, BASE_INSTALLED_BY_KEY, NULL, NULL, (PBYTE) szIB, &dwSize); RegCloseKey(hTempKey); if (lResult == ERROR_SUCCESS) { - if ( _tcsstr(szCSP, TEXT("OpenSC CSP")) != 0) + if ( _tcsstr(szIB, BASE_INSTALLED_BY_VALUE) != 0) { lResult = RegDeleteKey(hKey, szName); if (lResult != ERROR_SUCCESS) @@ -303,6 +306,8 @@ void RegisterCardWithKey(PTSTR szKey, PTSTR szCard, PTSTR szPath, PBYTE pbATR, D RegSetValueEx( hTempKey,TEXT("80000001"),0, REG_SZ, (PBYTE)szPath,(DWORD) (sizeof(TCHAR) * _tcslen(szPath))); RegSetValueEx( hTempKey,TEXT("ATR"),0, REG_BINARY, (PBYTE)pbATR, dwATRSize); RegSetValueEx( hTempKey,TEXT("ATRMask"),0, REG_BINARY, (PBYTE)pbAtrMask, dwATRSize); + RegSetValueEx( hTempKey,BASE_INSTALLED_BY_KEY,0, REG_SZ, (PBYTE)BASE_INSTALLED_BY_VALUE, + sizeof(BASE_INSTALLED_BY_VALUE) - sizeof(TCHAR)); RegCloseKey(hTempKey); } else From 87db8d763c4817a40c208dd382ba4089999e27b9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 28 Jul 2022 12:31:54 -0500 Subject: [PATCH 2559/4321] Add curve OIDs for EC keys in card-piv.c for use by minidriver --- src/libopensc/card-piv.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 41fe76252f..bda37f7b6c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -290,6 +290,15 @@ static const struct sc_atr_table piv_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; +static struct piv_supported_ec_curves { + struct sc_object_id oid; + size_t size; +} ec_curves[] = { + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384}, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */ + {{{-1}}, 0} /* This entry must not be touched. */ +}; + /* all have same AID */ static struct piv_aid piv_aids[] = { {SC_CARD_TYPE_PIV_II_GENERIC, /* TODO not really card type but what PIV AID is supported */ @@ -3487,12 +3496,14 @@ static int piv_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ if (!(priv->card_issues & CI_NO_EC)) { + int i; flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; - _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); - if (!(priv->card_issues & CI_NO_EC384)) - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + for (i = 0; ec_curves[i].oid.value[0] >= 0; i++) { + if (!(priv->card_issues & CI_NO_EC384 && ec_curves[i].size == 384)) + _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid); + } } if (!(priv->card_issues & CI_NO_RANDOM)) From f65746bb2a96113637528687e1675c51adcf01db Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 23 Aug 2022 14:38:24 -0500 Subject: [PATCH 2560/4321] "Defaults\Provider\OpenSC CSP" is still needed for backward compatibility Add comment: Date: Tue Aug 31 13:13:00 2022 -0500 On branch minidriver-ECC Changes to be committed: modified: win32/OpenSC.wxs.in --- win32/OpenSC.wxs.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 73c97e8a51..fe2bdc47d1 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -86,6 +86,9 @@ + From be7dd6fe65057acb47e2e7499d5f7bae228723c7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Sep 2022 16:11:26 +0200 Subject: [PATCH 2561/4321] .github: Try to avoid cache mismatch between normal builds and libressl ones There is a note in the actions/cache documentation that on restore keys is matched for prefixes and if one exists, it might restore the latest updated one https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key --- .github/workflows/linux.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 70b4f96d69..26860a6d3e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -209,7 +209,7 @@ jobs: if: ${{ success() }} with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-ossl3 + key: ${{ runner.os }}-ossl3-${{ github.sha }} - name: Upload artifacts uses: actions/upload-artifact@v2 if: ${{ success() }} @@ -227,7 +227,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-ossl3 + key: ${{ runner.os }}-ossl3-${{ github.sha }} - run: .github/setup-linux.sh cac ossl3 - run: .github/test-cac.sh @@ -240,7 +240,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-ossl3 + key: ${{ runner.os }}-ossl3-${{ github.sha }} - run: .github/setup-linux.sh oseid ossl3 - run: .github/test-oseid.sh @@ -265,7 +265,7 @@ jobs: if: ${{ success() }} with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-libressl + key: ${{ runner.os }}-libressl-${{ github.sha }} test-cac-libressl: runs-on: ubuntu-latest @@ -276,7 +276,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-libressl + key: ${{ runner.os }}-libressl-${{ github.sha }} - run: .github/setup-linux.sh cac libressl - run: .github/test-cac.sh @@ -289,7 +289,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }}-libressl + key: ${{ runner.os }}-libressl-${{ github.sha }} - run: .github/setup-linux.sh oseid libressl - run: .github/test-oseid.sh From d22f0e57f47ea36d54fdf5f6f06fc4bb936142db Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 28 Jul 2022 21:25:35 +0200 Subject: [PATCH 2562/4321] Add configuration option for caching private data By default, on-disk caching of private data is disabled. --- src/libopensc/pkcs15.c | 2 ++ src/libopensc/pkcs15.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 23bb2a32a2..d82b30d154 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1236,6 +1236,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->card = card; p15card->opts.use_file_cache = 0; + p15card->opts.cache_private_data = 0; p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; @@ -1250,6 +1251,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (conf_block) { p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache); + p15card->opts.cache_private_data = scconf_get_bool(conf_block, "cache_private_data", p15card->opts.cache_private_data); p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache); p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 89e75f8c3b..828662f29c 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -583,6 +583,7 @@ typedef struct sc_pkcs15_card { struct sc_pkcs15_card_opts { int use_file_cache; + int cache_private_data; int use_pin_cache; int pin_cache_counter; int pin_cache_ignore_user_consent; From d6371b68739080a17420d187b0355d495f58d01b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 29 Jul 2022 15:56:23 +0200 Subject: [PATCH 2563/4321] Add documentation for option for private data caching --- doc/files/files.html | 16 ++++++++++++++++ doc/files/opensc.conf.5.xml.in | 22 ++++++++++++++++++++++ etc/opensc.conf.example.in | 5 +++++ 3 files changed, 43 insertions(+) diff --git a/doc/files/files.html b/doc/files/files.html index a07c0b2858..d2b92253a5 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -759,6 +759,22 @@ cached information. Note that the cached files may contain personal data such as name and mail address. +

    + cache_private_data = bool; +

    + Whether to cache private card's files (e.g. + certificates) on disk in + file_cache_dir + Usable only with . + (Default: false). +

    + If caching is done by a system process, the + cached files may be placed inaccessible from + the user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address.

    file_cache_dir = filename;

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 17006d53a8..c70963f8d2 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1141,6 +1141,28 @@ app application { address. + + + + + + Whether to cache private card's files (e.g. + private keys) on disk in + . + Usable only with + (Default: + false). + + + If caching is done by a system process, the + cached files may be placed inaccessible from + the user account. Use a globally readable and + writable location if you wish to share the + cached information. Note that the cached files + may contain personal data such as name and mail + address. + + diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 499531731b..ec034f77a3 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -886,6 +886,11 @@ app default { # Default: false # use_file_caching = true; # + # Whether to cache private objects. + # + # Default: false + # cache_private_data = false; + # # set a path for caching # so you do not use the env variables and for pam_pkcs11 # (with certificate check) where $HOME is not set From d4ebb10d1268f685435080fa54ba6ba6fb27920c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 9 Aug 2022 18:32:52 +0200 Subject: [PATCH 2564/4321] Add flags for caching private data when reading file --- src/libopensc/pkcs15-cac.c | 2 +- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15-idprime.c | 2 +- src/libopensc/pkcs15-piv.c | 4 +++- src/libopensc/pkcs15-pubkey.c | 4 +++- src/libopensc/pkcs15.c | 8 ++++---- src/libopensc/pkcs15.h | 2 +- src/tests/p15dump.c | 2 +- 8 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index fceca06ac2..5b4637c716 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -252,7 +252,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; sc_pkcs15_format_id(pins[0].id, &prkey_obj.auth_id); - r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len); + r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, 0); if (r) { sc_log(card->ctx, "No cert found,i=%d", i); diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 972076d4c5..88a4220a17 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -384,7 +384,7 @@ sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, const struct sc_pkcs1 sc_der_copy(&der, &info->value); } else if (info->path.len) { - r = sc_pkcs15_read_file(p15card, &info->path, &der.value, &der.len); + r = sc_pkcs15_read_file(p15card, &info->path, &der.value, &der.len, 0); LOG_TEST_RET(ctx, r, "Unable to read certificate file."); } else { diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 9fd41e2016..6ef3901c77 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -173,7 +173,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); - r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len); + r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, 0); if (r) { sc_log(card->ctx, "No cert found,i=%d", i); diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 405d44a973..fda025c883 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -721,6 +721,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object cert_obj; sc_pkcs15_der_t cert_der; sc_pkcs15_cert_t *cert_out = NULL; + int private_obj; ckis[i].cert_found = 0; ckis[i].key_alg = -1; @@ -750,7 +751,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) continue; } - r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len); + private_obj = cert_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, private_obj); if (r) { sc_log(card->ctx, "No cert found,i=%d", i); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index abc55e0dd1..ee4ee4620a 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -883,6 +883,7 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj unsigned char *data = NULL; size_t len; int algorithm, r; + int private_obj; if (p15card == NULL || p15card->card == NULL || p15card->card->ops == NULL || obj == NULL || out == NULL) { @@ -951,7 +952,8 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj } else if (info->path.len) { sc_log(ctx, "Read from EF and decode"); - r = sc_pkcs15_read_file(p15card, &info->path, &data, &len); + private_obj = obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_file(p15card, &info->path, &data, &len, private_obj); LOG_TEST_GOTO_ERR(ctx, r, "Failed to read public key file."); if ((algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index d82b30d154..68ea1efac6 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2103,7 +2103,7 @@ sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) sc_log(ctx, "unknown DF type: %d", df->type); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } - r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize); + r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, 0); LOG_TEST_RET(ctx, r, "pkcs15 read file failed"); p = buf; @@ -2344,7 +2344,7 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_path, - unsigned char **buf, size_t *buflen) + unsigned char **buf, size_t *buflen, int private_data) { struct sc_context *ctx; struct sc_file *file = NULL; @@ -2361,7 +2361,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count); r = -1; /* file state: not in cache */ - if (p15card->opts.use_file_cache) { + if (p15card->opts.use_file_cache && (p15card->opts.cache_private_data || !private_data)) { r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len); if (!r && in_path->aid.len > 0 && in_path->len >= 2) { @@ -2449,7 +2449,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_file_free(file); - if (len && p15card->opts.use_file_cache) { + if (len && p15card->opts.use_file_cache && (p15card->opts.cache_private_data || !private_data)) { sc_pkcs15_cache_file(p15card, in_path, data, len); } } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 828662f29c..5ba8f3d30d 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -914,7 +914,7 @@ void sc_pkcs15_free_object(struct sc_pkcs15_object *obj); /* Generic file i/o */ int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *path, - u8 **buf, size_t *buflen); + u8 **buf, size_t *buflen, int private_data); /* Caching functions */ int sc_pkcs15_read_cached_file(struct sc_pkcs15_card *p15card, diff --git a/src/tests/p15dump.c b/src/tests/p15dump.c index 5e146c5284..f44c90f539 100644 --- a/src/tests/p15dump.c +++ b/src/tests/p15dump.c @@ -74,7 +74,7 @@ static int dump_unusedspace(void) } path.count = -1; - r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len); + r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len, 0); if (r < 0) { if (r == SC_ERROR_FILE_NOT_FOUND) { printf("\nNo EF(UnusedSpace) file\n"); From c475a2a04a1a8501520ea380af0b5811971e803f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 8 Aug 2022 14:47:15 +0200 Subject: [PATCH 2565/4321] Add check for private data caching for data objects --- src/libopensc/pkcs15-data.c | 3 ++- src/libopensc/pkcs15-iasecc.c | 7 +++++-- src/libopensc/pkcs15-itacns.c | 4 +++- src/libopensc/pkcs15.h | 1 + src/pkcs11/framework-pkcs15.c | 4 +++- src/pkcs15init/pkcs15-iasecc.c | 5 +++-- src/tools/pkcs15-tool.c | 10 +++++++--- 7 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index 07d68d7652..6dd748888a 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -41,6 +41,7 @@ int sc_pkcs15_read_data_object(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_data_info *info, + int private_obj, struct sc_pkcs15_data **data_object_out) { struct sc_context *ctx = p15card->card->ctx; @@ -53,7 +54,7 @@ sc_pkcs15_read_data_object(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); if (!info->data.value) { - r = sc_pkcs15_read_file(p15card, &info->path, (unsigned char **) &info->data.value, (size_t *) &info->data.len); + r = sc_pkcs15_read_file(p15card, &info->path, (unsigned char **) &info->data.value, (size_t *) &info->data.len, private_obj); LOG_TEST_RET(ctx, r, "Cannot get DATA object data"); } diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index a4dec05431..8c4941b896 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -51,13 +51,15 @@ _iasecc_md_update_keyinfo(struct sc_pkcs15_card *p15card, struct sc_pkcs15_objec struct sc_pkcs15_id id; int rv, offs; unsigned flags; + int private_obj; LOG_FUNC_CALLED(ctx); if (!dobj) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobj->data, &ddata); + private_obj = dobj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobj->data, private_obj, &ddata); LOG_TEST_RET(ctx, rv, "Failed to read container DATA object data"); offs = 0; @@ -184,12 +186,13 @@ _iasecc_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) count = rv; for(ii=0; iidata; + int private_obj = dobjs[ii]->flags & SC_PKCS15_CO_FLAG_PRIVATE; if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICATION_NAME)) continue; if (!strcmp(dobjs[ii]->label, IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL)) { - rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobjs[ii]->data, &default_guid); + rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobjs[ii]->data, private_obj, &default_guid); LOG_TEST_RET(ctx, rv, "Failed to read 'default container' DATA object data"); break; } diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index eec17c1b49..ea0f3ec1d3 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -493,6 +493,7 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) sc_pkcs15_data_info_t dinfo; struct sc_pkcs15_object *objs[32]; struct sc_pkcs15_data_info *cinfo; + int private_obj; for(i=0; i < array_size; i++) { sc_path_t path; @@ -548,7 +549,8 @@ static int itacns_add_data_files(sc_pkcs15_card_t *p15card) return SC_SUCCESS; } - rv = sc_pkcs15_read_data_object(p15card, cinfo, &p15_personaldata); + private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_data_object(p15card, cinfo, private_obj, &p15_personaldata); if (rv) { sc_log(p15card->card->ctx, "Could not read EF_DatiPersonali: " diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 5ba8f3d30d..3e742a0e32 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -728,6 +728,7 @@ void sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params); int sc_pkcs15_read_data_object(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_data_info *info, + int private_obj, struct sc_pkcs15_data **data_object_out); int sc_pkcs15_find_data_object_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id, diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 6189c11b28..68f7ad0cd3 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5008,6 +5008,7 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, struct pkcs15_fw_data *fw_data = NULL; struct sc_card *card; int rv; + int private_obj; if (!p11card) return sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetAttributeValue"); @@ -5030,7 +5031,8 @@ pkcs15_dobj_get_value(struct sc_pkcs11_session *session, if (rv < 0) return sc_to_cryptoki_error(rv, "C_GetAttributeValue"); - rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data); + private_obj = dobj->data_flags; + rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, private_obj, out_data); sc_unlock(card); if (rv < 0) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 7d95cfe81b..ed4e09830f 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1473,7 +1473,7 @@ iasecc_md_gemalto_unset_default(struct sc_pkcs15_card *p15card, struct sc_profil struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)key_obj->data; unsigned char guid[40]; size_t guid_len; - int rv, ii, keys_num; + int rv, ii, keys_num, private_obj; LOG_FUNC_CALLED(ctx); @@ -1487,7 +1487,8 @@ iasecc_md_gemalto_unset_default(struct sc_pkcs15_card *p15card, struct sc_profil if (rv == SC_ERROR_OBJECT_NOT_FOUND) LOG_FUNC_RETURN(ctx, SC_SUCCESS); - rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)data_obj->data, &dod); + private_obj = data_obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)data_obj->data, private_obj, &dod); LOG_TEST_RET(ctx, rv, "Cannot read from 'CSP/'Default Key Container'"); if (guid_len != dod->data_len || memcmp(guid, dod->data, guid_len)) { diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 6532b9682e..4cb4b1f7d7 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -466,6 +466,7 @@ static int read_data_object(void) for (i = 0; i < count; i++) { struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data; struct sc_pkcs15_data *data_object = NULL; + int private_obj; if (!sc_format_oid(&oid, opt_data)) { if (!sc_compare_oid(&oid, &cinfo->app_oid)) @@ -480,7 +481,8 @@ static int read_data_object(void) printf("Reading data object with label '%s'\n", opt_data); r = authenticate(objs[i]); if (r >= 0) { - r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object); + private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_data_object(p15card, cinfo, private_obj, &data_object); if (r) { fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r)); if (r == SC_ERROR_FILE_NOT_FOUND) @@ -527,7 +529,8 @@ static int list_data_objects(void) } if (objs[i]->auth_id.len == 0) { struct sc_pkcs15_data *data_object; - r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object); + int private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_data_object(p15card, cinfo, private_obj, &data_object); if (r) { fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r)); if (r == SC_ERROR_FILE_NOT_FOUND) @@ -559,7 +562,8 @@ static int list_data_objects(void) printf("\tPath: %s\n", sc_print_path(&cinfo->path)); if (objs[i]->auth_id.len == 0) { struct sc_pkcs15_data *data_object; - r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object); + int private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_data_object(p15card, cinfo, private_obj, &data_object); if (r) { fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r)); if (r == SC_ERROR_FILE_NOT_FOUND) From aa589f079acf2701fc76a8c0e68253e4b4a7bbce Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 1 Aug 2022 13:03:52 +0200 Subject: [PATCH 2566/4321] Add check for private data caching for certificate objects --- src/libopensc/pkcs15-cac.c | 2 +- src/libopensc/pkcs15-cert.c | 4 ++-- src/libopensc/pkcs15-coolkey.c | 2 +- src/libopensc/pkcs15-din-66291.c | 2 +- src/libopensc/pkcs15-esteid.c | 2 +- src/libopensc/pkcs15-esteid2018.c | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 5 +++-- src/libopensc/pkcs15-idprime.c | 2 +- src/libopensc/pkcs15-itacns.c | 5 +++-- src/libopensc/pkcs15-piv.c | 4 ++-- src/libopensc/pkcs15-westcos.c | 2 +- src/libopensc/pkcs15.h | 1 + src/pkcs11/framework-pkcs15.c | 6 ++++-- src/pkcs15init/pkcs15-oberthur-awp.c | 3 ++- src/tools/pkcs15-init.c | 16 ++++++++++++---- src/tools/pkcs15-tool.c | 16 ++++++++++++---- 16 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 5b4637c716..e4a6219a8c 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -274,7 +274,7 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card) } /* following will find the cached cert in cert_info */ - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert_out); if (r < 0 || cert_out->key == NULL) { sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 88a4220a17..1faa9cc771 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -367,7 +367,7 @@ sc_pkcs15_pubkey_from_cert(struct sc_context *ctx, int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_cert_info *info, - struct sc_pkcs15_cert **cert_out) + int private_obj, struct sc_pkcs15_cert **cert_out) { struct sc_context *ctx = NULL; struct sc_pkcs15_cert *cert = NULL; @@ -384,7 +384,7 @@ sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, const struct sc_pkcs1 sc_der_copy(&der, &info->value); } else if (info->path.len) { - r = sc_pkcs15_read_file(p15card, &info->path, &der.value, &der.len, 0); + r = sc_pkcs15_read_file(p15card, &info->path, &der.value, &der.len, private_obj); LOG_TEST_RET(ctx, r, "Unable to read certificate file."); } else { diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 3062bea6ad..1689c333e7 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -431,7 +431,7 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co if (r < 0) { goto fail; } - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert_out); if (r < 0) { goto fail; } diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index ef35c04eb8..c8d1530018 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -149,7 +149,7 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) if (i == 0) { sc_pkcs15_cert_t *cert; - if (SC_SUCCESS == sc_pkcs15_read_certificate(p15card, &cert_info, &cert)) { + if (SC_SUCCESS == sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert)) { static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }}; u8 *cn_name = NULL; size_t cn_len = 0; diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 5a01f245b9..74c1c71699 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -90,7 +90,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) continue; sc_pkcs15_cert_t *cert = NULL; - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert); if (r < 0) goto err; if (cert->key->algorithm == SC_ALGORITHM_EC) diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index c341ba9585..e3076b144d 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -87,7 +87,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { continue; sc_pkcs15_cert_t *cert = NULL; - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not read authentication certificate"); if (cert->key->algorithm == SC_ALGORITHM_EC) diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index 82429081cc..ae86ee00f3 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -345,6 +345,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; sc_pkcs15_cert_t *cert_out; + int private_obj; memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); @@ -410,8 +411,8 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) } /* now lets see if we have a matching key for this cert */ - - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); + private_obj = cert_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out); if (r < 0) { free(gsdata); sc_pkcs15_card_clear(p15card); diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 6ef3901c77..2d09b01a50 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -195,7 +195,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) } /* following will find the cached cert in cert_info */ - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert_out); if (r < 0 || cert_out->key == NULL) { sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index ea0f3ec1d3..5563f5cb27 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -198,6 +198,7 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, #ifdef ENABLE_OPENSSL X509 *x509; sc_pkcs15_cert_t *cert; + int private_obj; #endif SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL); @@ -228,8 +229,8 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, /* If we have OpenSSL, read keyUsage */ #ifdef ENABLE_OPENSSL - - r = sc_pkcs15_read_certificate(p15card, &info, &cert); + private_obj = obj_flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, &info, private_obj, &cert); LOG_TEST_RET(p15card->card->ctx, r, "Could not read X.509 certificate"); diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index fda025c883..4deda296bd 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -765,12 +765,12 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) if (cert_der.value) { cert_info.value.value = cert_der.value; cert_info.value.len = cert_der.len; - if (!p15card->opts.use_file_cache) { + if (!p15card->opts.use_file_cache || (private_obj && !p15card->opts.cache_private_data)) { cert_info.path.len = 0; /* use in mem cert from now on */ } } /* following will find the cached cert in cert_info */ - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out); + r = sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out); if (r < 0 || cert_out == NULL || cert_out->key == NULL) { sc_log(card->ctx, "Failed to read/parse the certificate r=%d",r); if (cert_out != NULL) diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 6c1660d0be..1e6d7f1d62 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -131,7 +131,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) cert_info.id.value[0] = 0x45; cert_info.authority = 0; cert_info.path = path; - r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert); cert_obj.data = (void *) cert; if (!r) { strlcpy(cert_obj.label, "User certificate", diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 3e742a0e32..5af97e846d 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -744,6 +744,7 @@ void sc_pkcs15_free_data_object(struct sc_pkcs15_data *data_object); int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card, const struct sc_pkcs15_cert_info *info, + int private_obj, struct sc_pkcs15_cert **cert); void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert); int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card, diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 68f7ad0cd3..da8136330f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -693,7 +693,7 @@ __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_obj p15_cert = NULL; /* will read cert when needed */ } else { - rv = sc_pkcs15_read_certificate(fw_data->p15_card, p15_info, &p15_cert); + rv = sc_pkcs15_read_certificate(fw_data->p15_card, p15_info, 0, &p15_cert); if (rv < 0) return rv; } @@ -1028,13 +1028,15 @@ check_cert_data_read(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object * { struct pkcs15_pubkey_object *obj2; int rv; + int private_obj; if (!cert) return SC_ERROR_OBJECT_NOT_FOUND; if (cert->cert_data) return 0; - rv = sc_pkcs15_read_certificate(fw_data->p15_card, cert->cert_info, &cert->cert_data); + private_obj = cert->cert_flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_certificate(fw_data->p15_card, cert->cert_info, private_obj, &cert->cert_data); if (rv < 0) return rv; diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index c9da5f658d..bdffeaec1c 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1455,11 +1455,12 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = sc_pkcs15_find_cert_by_id(p15card, &key_info->id, &cert_obj); if (!rv) { struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) cert_obj->data; + int private_obj = cert_obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; path = cert_info->path; cc.cert_id = (path.value[path.len-1] & 0xFF) + (path.value[path.len-2] & 0xFF) * 0x100; - rv = sc_pkcs15_read_certificate(p15card, cert_info, &p15cert); + rv = sc_pkcs15_read_certificate(p15card, cert_info, private_obj, &p15cert); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, rv, "AWP 'update private key' DF failed: cannot get certificate"); rv = sc_pkcs15_allocate_object_content(ctx, cert_obj, p15cert->data.value, p15cert->data.len); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 9e7a32d739..f8a62c442f 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1151,6 +1151,7 @@ is_cacert_already_present(struct sc_pkcs15init_certargs *args) count = r; for (i = 0; i < count; i++) { + int private_obj; cinfo = (sc_pkcs15_cert_info_t *) objs[i]->data; if (!cinfo->authority) @@ -1160,7 +1161,8 @@ is_cacert_already_present(struct sc_pkcs15init_certargs *args) /* XXX we should also match the usage field here */ /* Compare the DER representation of the certificates */ - r = sc_pkcs15_read_certificate(g_p15card, cinfo, &cert); + private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(g_p15card, cinfo, private_obj, &cert); if (r < 0 || !cert) continue; @@ -1366,6 +1368,7 @@ do_update_certificate(struct sc_profile *profile) sc_pkcs15_cert_t *oldcert = NULL; sc_pkcs15_der_t newcert_raw; int r; + int private_obj; if (opt_objectid == NULL) { util_error("no ID given for the cert: use --id"); @@ -1384,7 +1387,8 @@ do_update_certificate(struct sc_profile *profile) return r; certinfo = (sc_pkcs15_cert_info_t *) obj->data; - r = sc_pkcs15_read_certificate(g_p15card, certinfo, &oldcert); + private_obj = obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(g_p15card, certinfo, private_obj, &oldcert); if (r < 0) goto err; @@ -1481,12 +1485,14 @@ static int get_cert_info(sc_pkcs15_card_t *myp15card, sc_pkcs15_object_t *certob sc_pkcs15_object_t *otherobj; sc_pkcs15_cert_t *othercert = NULL; int r; + int private_obj; *issuercert = NULL; *has_sibling = 0; *stop = 0; - r = sc_pkcs15_read_certificate(myp15card, (sc_pkcs15_cert_info_t *) certobj->data, &cert); + private_obj = certobj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(myp15card, (sc_pkcs15_cert_info_t *) certobj->data, private_obj, &cert); if (r < 0) return r; @@ -1502,7 +1508,9 @@ static int get_cert_info(sc_pkcs15_card_t *myp15card, sc_pkcs15_object_t *certob sc_pkcs15_free_certificate(othercert); othercert=NULL; } - r = sc_pkcs15_read_certificate(myp15card, (sc_pkcs15_cert_info_t *) otherobj->data, &othercert); + + private_obj = otherobj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(myp15card, (sc_pkcs15_cert_info_t *) otherobj->data, private_obj, &othercert); if (r < 0 || !othercert) goto done; if ((cert->issuer_len == othercert->subject_len) && diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 4cb4b1f7d7..f68d99ed6a 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -269,6 +269,7 @@ static void print_cert_info(const struct sc_pkcs15_object *obj) struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) obj->data; struct sc_pkcs15_cert *cert_parsed = NULL; int rv; + int private_obj; if (compact) { printf("\tPath:%s ID:%s", sc_print_path(&cert_info->path), @@ -286,7 +287,8 @@ static void print_cert_info(const struct sc_pkcs15_object *obj) print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES); - rv = sc_pkcs15_read_certificate(p15card, cert_info, &cert_parsed); + private_obj = obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_certificate(p15card, cert_info, private_obj, &cert_parsed); if (rv >= 0 && cert_parsed) { printf("\tEncoded serial : %02X %02X ", *(cert_parsed->serial), *(cert_parsed->serial + 1)); util_hex_dump(stdout, cert_parsed->serial + 2, cert_parsed->serial_len - 2, ""); @@ -431,13 +433,15 @@ static int read_certificate(void) for (i = 0; i < count; i++) { struct sc_pkcs15_cert_info *cinfo = (struct sc_pkcs15_cert_info *) objs[i]->data; struct sc_pkcs15_cert *cert; + int private_obj; if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1) continue; if (verbose) printf("Reading certificate with ID '%s'\n", opt_cert); - r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); + private_obj = objs[i]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, cinfo, private_obj, &cert); if (r) { fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r)); return 1; @@ -806,11 +810,13 @@ static int read_public_key(void) r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey); } else if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* No pubkey - try if there's a certificate */ + int private_obj; r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj); if (r >= 0) { if (verbose) printf("Reading certificate with ID '%s'\n", opt_pubkey); - r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, &cert); + private_obj = obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, private_obj, &cert); } if (r >= 0) pubkey = cert->key; @@ -980,11 +986,13 @@ static int read_ssh_key(void) } else if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* No pubkey - try if there's a certificate */ + int private_obj; r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj); if (r >= 0) { if (verbose) fprintf(stderr,"Reading certificate with ID '%s'\n", opt_pubkey); - r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, &cert); + private_obj = obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, private_obj, &cert); } if (r >= 0) pubkey = cert->key; From c2765b1eccf3dee69ee1b4b7ba296b9faf01c980 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 10 Aug 2022 11:11:32 +0200 Subject: [PATCH 2567/4321] pkcs15-coolkey.c: Cache private data according to object flags --- src/libopensc/pkcs15-coolkey.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 1689c333e7..5d8c8de4a1 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -423,7 +423,8 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co sc_pkcs15_cert_info_t cert_info; sc_pkcs15_cert_t *cert_out = NULL; sc_pkcs15_pubkey_t *key = NULL; - int r; + int r, private_obj; + unsigned int flags; memset(&cert_info, 0, sizeof(cert_info)); @@ -431,7 +432,10 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co if (r < 0) { goto fail; } - r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert_out); + + coolkey_get_flags(p15card->card, obj, &flags); + private_obj = flags & SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out); if (r < 0) { goto fail; } From 35aac0ec2714836443fe7e5e98b03d5859f85fc3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 11 Aug 2022 14:41:57 +0200 Subject: [PATCH 2568/4321] minidriver.c: Add flags for reading certificate --- src/minidriver/minidriver.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 2440873330..4790f31de4 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1445,9 +1445,11 @@ md_fs_read_msroots_file(PCARD_DATA pCardData, struct md_file *file) for(ii = 0; ii < cert_num; ii++) { struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) prkey_objs[ii]->data; struct sc_pkcs15_cert *cert = NULL; + int private_obj; PCCERT_CONTEXT wincert = NULL; if (cert_info->authority) { - rv = sc_pkcs15_read_certificate(vs->p15card, cert_info, &cert); + private_obj = prkey_objs[ii]->flags & SC_PKCS15_CO_FLAG_PRIVATE; + rv = sc_pkcs15_read_certificate(vs->p15card, cert_info, private_obj, &cert); if(rv) { logprintf(pCardData, 2, "Cannot read certificate idx:%i: sc-error %d\n", ii, rv); continue; @@ -1547,8 +1549,9 @@ md_fs_read_content(PCARD_DATA pCardData, char *parent, struct md_file *file) struct sc_pkcs15_cert *cert = NULL; struct sc_pkcs15_object *cert_obj = vs->p15_containers[idx].cert_obj; struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *)cert_obj->data; + int private_obj = cert_obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; - rv = sc_pkcs15_read_certificate(vs->p15card, cert_info, &cert); + rv = sc_pkcs15_read_certificate(vs->p15card, cert_info, private_obj, &cert); if(rv) { logprintf(pCardData, 2, "Cannot read certificate idx:%i: sc-error %d\n", idx, rv); logprintf(pCardData, 2, "set cardcf from 'DATA' pkcs#15 object\n"); @@ -3563,9 +3566,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine if (!pubkey_der.value && cont->cert_obj) { struct sc_pkcs15_cert *cert = NULL; + int private_obj = cont->cert_obj->flags & SC_PKCS15_CO_FLAG_PRIVATE; logprintf(pCardData, 1, "now read certificate '%.*s'\n", (int) sizeof cont->cert_obj->label, cont->cert_obj->label); - rv = sc_pkcs15_read_certificate(vs->p15card, (struct sc_pkcs15_cert_info *)(cont->cert_obj->data), &cert); + rv = sc_pkcs15_read_certificate(vs->p15card, (struct sc_pkcs15_cert_info *)(cont->cert_obj->data), private_obj, &cert); if(!rv) { rv = sc_pkcs15_encode_pubkey(vs->ctx, cert->key, &pubkey_der.value, &pubkey_der.len); if (rv) { From 674faf9b2f38e9b0c85749da889294801ab15348 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 11 Aug 2022 14:47:30 +0200 Subject: [PATCH 2569/4321] Fix documentation for conf file --- doc/files/opensc.conf.5.xml.in | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index c70963f8d2..0c859fb5f9 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1146,22 +1146,13 @@ app application { - Whether to cache private card's files (e.g. - private keys) on disk in - . + Whether to cache private card's files + on disk in . Usable only with (Default: false). - - If caching is done by a system process, the - cached files may be placed inaccessible from - the user account. Use a globally readable and - writable location if you wish to share the - cached information. Note that the cached files - may contain personal data such as name and mail - address. - + From b416dd0b1b6216b0d6772e8ca0b2abaa04a0c979 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 31 Aug 2022 16:11:23 +0200 Subject: [PATCH 2570/4321] Use multi-option for caching files --- doc/files/files.html | 28 ++++++++++------------------ doc/files/opensc.conf.5.xml.in | 29 ++++++++++++++--------------- etc/opensc.conf | 2 +- etc/opensc.conf.example.in | 9 ++------- src/libopensc/pkcs15-actalis.c | 2 +- src/libopensc/pkcs15.c | 17 +++++++++++++---- src/libopensc/pkcs15.h | 6 +++++- 7 files changed, 46 insertions(+), 47 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index d2b92253a5..836aa933ec 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -749,24 +749,16 @@

    Whether to cache the card's files (e.g. certificates) on disk in - file_cache_dir (Default: - false). -

    - If caching is done by a system process, the - cached files may be placed inaccessible from - the user account. Use a globally readable and - writable location if you wish to share the - cached information. Note that the cached files - may contain personal data such as name and mail - address. -

    - cache_private_data = bool; -

    - Whether to cache private card's files (e.g. - certificates) on disk in - file_cache_dir - Usable only with . - (Default: false). + file_cache_dir. + Possible parameters: +

    + (Default:no).

    If caching is done by a system process, the cached files may be placed inaccessible from diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 0c859fb5f9..7e6699bd08 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1128,8 +1128,20 @@ app application { Whether to cache the card's files (e.g. certificates) on disk in - (Default: - false). + . + Possible parameters: + + + yes: Cache all files (public and private). + + public: Cache only public files. + + + no: File caching disabled. + + + + (Default: no). If caching is done by a system process, the @@ -1141,19 +1153,6 @@ app application { address. - - - - - - Whether to cache private card's files - on disk in . - Usable only with - (Default: - false). - - - diff --git a/etc/opensc.conf b/etc/opensc.conf index 4243d7caa9..fd88538b84 100644 --- a/etc/opensc.conf +++ b/etc/opensc.conf @@ -2,6 +2,6 @@ app default { # debug = 3; # debug_file = opensc-debug.txt; framework pkcs15 { - # use_file_caching = true; + # use_file_caching = public; } } diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index ec034f77a3..b8c621a5d1 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -883,13 +883,8 @@ app default { # inaccessible from the user account. Use a global caching directory if # you wish to share the cached information. # - # Default: false - # use_file_caching = true; - # - # Whether to cache private objects. - # - # Default: false - # cache_private_data = false; + # Default: no + # use_file_caching = public; # # set a path for caching # so you do not use the env variables and for pam_pkcs11 diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index a3fc27b305..ae355732de 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -168,7 +168,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) const char *authPRKEY = "Authentication Key"; /* const char *nonrepPRKEY = "Non repudiation Key"; */ - p15card->opts.use_file_cache = 1; + p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES; /* Get Serial number */ sc_format_path("3F0030000001", &path); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 68ea1efac6..de55a8e44e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1220,6 +1220,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, struct sc_context *ctx; scconf_block *conf_block = NULL; int r, emu_first, enable_emu; + const char *use_file_cache; const char *private_certificate; if (card == NULL || p15card_out == NULL) { @@ -1235,8 +1236,8 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); p15card->card = card; - p15card->opts.use_file_cache = 0; - p15card->opts.cache_private_data = 0; + p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES; + use_file_cache = "no"; p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; @@ -1250,14 +1251,22 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (conf_block) { - p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache); - p15card->opts.cache_private_data = scconf_get_bool(conf_block, "cache_private_data", p15card->opts.cache_private_data); + use_file_cache = scconf_get_str(conf_block, "use_file_caching", use_file_cache); p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache); p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", p15card->opts.pin_cache_ignore_user_consent); private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate); } + + if (0 == strcmp(use_file_cache, "yes")) { + p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES; + } else if (0 == strcmp(use_file_cache, "public")) { + p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_PUBLIC_FILES; + } else if (0 == strcmp(use_file_cache, "no")) { + p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES; + } + if (0 == strcmp(private_certificate, "protect")) { p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; } else if (0 == strcmp(private_certificate, "ignore")) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 5af97e846d..0c768be62b 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -583,7 +583,6 @@ typedef struct sc_pkcs15_card { struct sc_pkcs15_card_opts { int use_file_cache; - int cache_private_data; int use_pin_cache; int pin_cache_counter; int pin_cache_ignore_user_consent; @@ -608,6 +607,11 @@ typedef struct sc_pkcs15_card { /* flags suitable for struct sc_pkcs15_card */ #define SC_PKCS15_CARD_FLAG_EMULATED 0x02000000 +/* suitable for struct sc_pkcs15_card.opts.use_file_cache */ +#define SC_PKCS15_OPTS_CACHE_NO_FILES 0 +#define SC_PKCS15_OPTS_CACHE_PUBLIC_FILES 1 +#define SC_PKCS15_OPTS_CACHE_ALL_FILES 2 + /* suitable for struct sc_pkcs15_card.opts.private_certificate */ #define SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT 0 #define SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE 1 From 92b56282d48cd8700a0197277682a541a2b8030d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 31 Aug 2022 17:44:17 +0200 Subject: [PATCH 2571/4321] Add check for use_file_cache when reading file --- src/libopensc/pkcs15.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index de55a8e44e..dac6808a79 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2370,7 +2370,8 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count); r = -1; /* file state: not in cache */ - if (p15card->opts.use_file_cache && (p15card->opts.cache_private_data || !private_data)) { + if (p15card->opts.use_file_cache + && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) { r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len); if (!r && in_path->aid.len > 0 && in_path->len >= 2) { @@ -2458,7 +2459,8 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_file_free(file); - if (len && p15card->opts.use_file_cache && (p15card->opts.cache_private_data || !private_data)) { + if (len && p15card->opts.use_file_cache + && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) { sc_pkcs15_cache_file(p15card, in_path, data, len); } } From 4cff66c44e0195d1feb5103f3107baa419dab557 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 31 Aug 2022 18:00:56 +0200 Subject: [PATCH 2572/4321] pkcs15-piv: Add check for use_file_cache --- src/libopensc/pkcs15-piv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 4deda296bd..2c5e291631 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -765,7 +765,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) if (cert_der.value) { cert_info.value.value = cert_der.value; cert_info.value.len = cert_der.len; - if (!p15card->opts.use_file_cache || (private_obj && !p15card->opts.cache_private_data)) { + if (!p15card->opts.use_file_cache + || (private_obj && !(p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES))) { cert_info.path.len = 0; /* use in mem cert from now on */ } } From a39d70b5327429a6e26cab82513265a339ecda0e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 2 Sep 2022 16:19:26 +0200 Subject: [PATCH 2573/4321] Keep pcsc reader flags when disconnected When the reader is removed, the reader->flags are set to SC_READER_REMOVED. card_detect_all() then frees resources and sets slot->reader to NULL. During this, sc_card_disconnect() is called, setting reader->flags to 0. In a subsequent call to card_detect_all() with the reader still removed, the corresponding slot is reclaimed, and slot->reader set back to the removed reader, but slot->events is overwritten, which causes the C_WaitForSlot() not to recognize event on the slot. --- src/libopensc/reader-pcsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 1efd8a0d31..40bfd293d3 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -672,7 +672,7 @@ static int pcsc_disconnect(sc_reader_t * reader) LONG rv = priv->gpriv->SCardDisconnect(priv->pcsc_card, priv->gpriv->disconnect_action); PCSC_TRACE(reader, "SCardDisconnect returned", rv); } - reader->flags = 0; + reader->flags &= SC_READER_REMOVED; return SC_SUCCESS; } From 2158e709b7636e0b6fcf5f31705d455b31efb014 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 18 Sep 2022 07:03:46 +0200 Subject: [PATCH 2574/4321] Fix for 'Coverity scan' CID 380537 modified: src/pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index da8136330f..688cd84fdc 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -5556,7 +5556,14 @@ pkcs15_skey_encrypt(struct sc_pkcs11_session *session, void *obj, can be an init operation or final operation..*/ if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_ENCRYPT)) + skey = NULL; + + /* TODO: should we look for a compatible key automatically? prv_next not implemented yet. */ + /* skey = skey->prv_next; */ + + if (skey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); switch (pMechanism->mechanism) { From a3b5f8d0ae10c8db8f9ee1a9c5ea481dd01ded9f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Oct 2022 12:26:31 +0200 Subject: [PATCH 2575/4321] Preparation for 0.23.0 --- .appveyor.yml | 2 +- NEWS | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 6 ++--- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index e2b7a5ea48..4943394f1f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.22.0.{build} +version: 0.23.0.{build} platform: - x86 diff --git a/NEWS b/NEWS index 965203b3e4..94f4b2ae0a 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,67 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.23.0; 2022-10-11 +## General improvements +* Support signing of data with a length of more than 512 bytes (#2314) +* By default, disable support for old card drivers (#2391) and remove support for old drivers MioCOS and JCOP (#2374) +* Bump minimal required OpenSSL version to 1.1.1 and add support for OpenSSL 3.0 (#2438, #2506) +* Compatibility with LibreSSL (#2495, #2595) +* Remove support for DSA (#2503) +* Extend p11test to support symmetric keys (#2430) +* Notice detached reader on macOS (#2418) +* Support for OAEP padding (#2475, #2484) +* Fix for PSS salt length (#2478) +* Improve fuzzing by adding new tests (#2417, #2500, #2520, #2550) +* Fixed various issues reported by OSS-Fuzz and Coverity regarding card drivers, PKCS#11 and PKCS#15 init +* Fix issues with OpenPACE (#2472) +* Containers support for local testing +* Add support for encryption using symmetric keys (#2473) +* Stop building support for Gost algorithms with OpenSSL 3.0 as they require deprecated API (#2586) +* Fix detection of disconnected readers in PCSC (#2600) +* Add configuration option for on-disk caching of private data (#2588) +## PKCS#11 +* Implement `C_CreateObject` for EC keys and fix signature verification for `CKM_ECDSA_SHAx` cards (#2420) +## pkcs11-tool +* Add more elliptic curves (#2301) +* Add support for symmetric encrypt and decrypt, wrap and unwrap operations, and initialization vector (#2268) +* Fix consistent handling of secret key attributes (#2497) +* Add support for signing and verifying with HMAC (#2385) +* Add support for SHA3 (#2467) +* Make object selectable via label (#2570) +* Do not require an R/W session for some operations and add `--session-rw` option (#2579) +## sc-hsm-tool +* Add options for public key authentication (#2301) +## Minidriver +* Fix reinit of the card (#2525) +* Add an entry for Italian CNS (e) (#2548) +* Fix detection of ECC mechanisms (#2523) +## NQ-Applet +* Add support for the JCOP4 Cards with NQ-Applet (#2425) +## ItaCNS +* Add support for ItaCMS v1.1 (key length 2048) (#2371) +## Belpic +* Add support for applet v1.8 (#2455) +## Starcos +* Add ATR for V3.4 (#2464) +* Add PKCS#15 emulator for 3.x cards with eSign app (#2544) +## ePass2003 +* Fix PKCS#15 initialization (#2403) +* Add support for FIPS (#2543) +* Fix matching with newer versions and tokens initialized with OpenSC (#2575) +## MyEID +* Support logout operation (#2557) +## GIDS +* Fix decipher for TPM (#1881) +## OpenPGP +* Get the list of supported algorithms from algorithm information on the card (#2287) +## nPA +* Fix card detection (#2463) +## Rutoken +* Fix formatting rtecp cards (#2599) +## PIV +* Add new PIVKey ATRs for current cards (#2602) + + # New in 0.22.0; 2021-08-10 ## General improvements * Use standard paths for file cache on Linux (#2148) and OSX (#2214) diff --git a/configure.ac b/configure.ac index 21f2eda7e7..92de526053 100644 --- a/configure.ac +++ b/configure.ac @@ -7,9 +7,9 @@ define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [22]) +define([PACKAGE_VERSION_MINOR], [23]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], []) +define([PACKAGE_SUFFIX], [-rc1]) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) @@ -45,7 +45,7 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Code changed: REVISION++) # (Oldest interface changed/removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) -OPENSC_LT_CURRENT="8" +OPENSC_LT_CURRENT="9" OPENSC_LT_OLDEST="8" OPENSC_LT_REVISION="0" OPENSC_LT_AGE="0" From 6317b8aa98d33f3934b7405170c2366b20c3ed66 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 29 Aug 2022 16:21:31 +0200 Subject: [PATCH 2576/4321] Fix memory leak Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50512 --- src/pkcs15init/profile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index b92cd5fbaf..33a141c943 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1694,6 +1694,7 @@ static void set_pin_defaults(struct sc_profile *profile, struct pin_info *pi) static int do_pin_file(struct state *cur, int argc, char **argv) { + free(cur->pin->file_name); cur->pin->file_name = strdup(argv[0]); return 0; } From 1e4222efcf6d889adaab9d28f32623e5e1055042 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 1 Sep 2022 17:15:11 +0200 Subject: [PATCH 2577/4321] Avoid double-free Thank OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51185 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51837 --- src/libopensc/pkcs15.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index dac6808a79..4054f8e8ea 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2060,6 +2060,7 @@ sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, stru buf = p; memcpy(buf + bufsize, tmp, tmpsize); free(tmp); + tmp = NULL; bufsize += tmpsize; } *buf_out = buf; From 516dc1836ff4dfba72c8227c4e403b5a9dc46a5c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 1 Sep 2022 17:34:48 +0200 Subject: [PATCH 2578/4321] pkcs15-lib.c: Free file Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50560 --- src/pkcs15init/pkcs15-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index be56e2d729..91cee37310 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4421,6 +4421,7 @@ sc_pkcs15init_read_info(struct sc_card *card, struct sc_profile *profile) } else { r = 0; + sc_file_free(file); } if (r >= 0) From cbe8bbefea36e8980d5a65bc350b317bc0244bb9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 7 Oct 2022 13:13:02 +0200 Subject: [PATCH 2579/4321] Set buffer pointer before parsing ASN1 Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49248 --- src/libopensc/card-cardos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 51f4ed4c25..0d8e2651d7 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -496,7 +496,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) { sc_apdu_t apdu; u8 rbuf[256], offset = 0; - const u8 *p = rbuf, *q, *tag; + const u8 *p, *q, *tag; int r; size_t fids = 0, len; @@ -521,6 +521,7 @@ static int cardos_list_files(sc_card_t *card, u8 *buf, size_t buflen) sc_log(card->ctx, "directory listing > 256 bytes, cutting"); } + p = rbuf; len = apdu.resplen; while (len != 0) { size_t tlen = 0, ilen = 0; From 581b93543abbeda6c17a5da11e2cf82401824bef Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 10 Oct 2022 11:23:58 +0200 Subject: [PATCH 2580/4321] Separate function for parsing ECDSA signature from ASN.1 Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50683 --- src/libopensc/asn1.c | 50 +++++ src/libopensc/asn1.h | 4 + src/libopensc/card-piv.c | 38 +--- src/libopensc/card-sc-hsm.c | 40 +--- src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/decode_ecdsa_signature.c | 225 +++++++++++++++++++ 6 files changed, 286 insertions(+), 76 deletions(-) create mode 100644 src/tests/unittests/decode_ecdsa_signature.c diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 8fb3992457..df1f1c8fa7 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -2192,3 +2192,53 @@ sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in LOG_FUNC_RETURN(ctx, rv); } + +int sc_asn1_decode_ecdsa_signature(sc_context_t *ctx, const u8 *data, size_t datalen, size_t fieldsize, u8 **out, size_t outlen) { + int i, r; + const unsigned char *pseq, *pint, *pend; + unsigned int cla, tag; + size_t seqlen, intlen; + + if (!ctx || !data || !out || !(*out)) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + if (outlen < 2 * fieldsize) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Output too small for EC signature"); + } + + memset(*out, 0, outlen); + + pseq = data; + r = sc_asn1_read_tag(&pseq, datalen, &cla, &tag, &seqlen); + if (pseq == NULL || r < 0 || seqlen == 0 || (cla | tag) != 0x30) + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x30 tag"); + + pint = pseq; + pend = pseq + seqlen; + for (i = 0; i < 2; i++) { + r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen); + if (pint == NULL || r < 0 || intlen == 0 || (cla | tag) != 0x02) { + r = SC_ERROR_INVALID_DATA; + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x02"); + } + + if (intlen == fieldsize + 1) { /* drop leading 00 if present */ + if (*pint != 0x00) { + r = SC_ERROR_INVALID_DATA; + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long"); + } + pint++; + intlen--; + } + if (intlen > fieldsize) { + r = SC_ERROR_INVALID_DATA; + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long"); + } + memcpy(*out + fieldsize * i + fieldsize - intlen , pint, intlen); + pint += intlen; /* next integer */ + } + r = 2 * fieldsize; +err: + LOG_FUNC_RETURN(ctx, r); +} + diff --git a/src/libopensc/asn1.h b/src/libopensc/asn1.h index 3a4cb29c09..4490eff18f 100644 --- a/src/libopensc/asn1.h +++ b/src/libopensc/asn1.h @@ -127,6 +127,10 @@ int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in, size_t inlen, unsigned char *buf, size_t buflen); +/* ECDSA signature decoding*/ +int sc_asn1_decode_ecdsa_signature(sc_context_t *ctx, const u8 *data, size_t datalen, + size_t fieldsize, u8 **out, size_t outlen); + /* long form tags use these */ /* Same as SC_ASN1_TAG_* shifted left by 24 bits */ #define SC_ASN1_CLASS_MASK 0xC0000000 diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index bda37f7b6c..6bf740221e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2436,14 +2436,8 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, { piv_private_data_t * priv = PIV_DATA(card); int r; - int i; size_t nLen; u8 rbuf[128]; /* For EC conversions 384 will fit */ - const unsigned char *pseq, *pint, *ptemp, *pend; - unsigned int cla, tag; - size_t seqlen; - size_t intlen; - size_t templen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -2463,40 +2457,12 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, r = SC_ERROR_INVALID_DATA; goto err; } - memset(out, 0, outlen); r = piv_validate_general_authentication(card, data, datalen, rbuf, sizeof rbuf); if (r < 0) goto err; - - pseq = rbuf; - r = sc_asn1_read_tag(&pseq, r, &cla, &tag, &seqlen); - if (pseq == NULL || r < 0 || seqlen == 0 || (cla|tag) != 0x30) - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x30"); - - pint = pseq; - pend = pseq + seqlen; - for (i = 0; i < 2; i++) { - r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen); - if (pint == NULL || r < 0 || intlen == 0 || (cla|tag) != 0x02) - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x02"); - if (intlen > nLen + 1) - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); - - ptemp = pint; - templen = intlen; - if (intlen > nLen) { /* drop leading 00 if present */ - if (*ptemp != 0x00) { - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); - } - ptemp++; - templen--; - } - memcpy(out + nLen*i + nLen - templen, ptemp, templen); - pint += intlen; /* next integer */ - - } - r = 2 * nLen; + + r = sc_asn1_decode_ecdsa_signature(card->ctx, rbuf, r, nLen, &out, outlen); } else { /* RSA is all set */ r = piv_validate_general_authentication(card, data, datalen, out, outlen); } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index b39e88b643..6999e71426 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1034,10 +1034,8 @@ static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen) { - int i, r; + int r; size_t fieldsizebytes; - const u8 *body, *tag; - size_t bodylen, taglen; // Determine field size from length of signature if (datalen <= 58) { // 192 bit curve = 24 * 2 + 10 byte maximum DER signature @@ -1060,41 +1058,7 @@ static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, "Field size %"SC_FORMAT_LEN_SIZE_T"u, signature buffer size %"SC_FORMAT_LEN_SIZE_T"u", fieldsizebytes, outlen); - if (outlen < (fieldsizebytes * 2)) { - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "output too small for EC signature"); - } - memset(out, 0, outlen); - - // Copied from card-piv.c. Thanks - body = sc_asn1_find_tag(card->ctx, data, datalen, 0x30, &bodylen); - - for (i = 0; i<2; i++) { - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen); - if (tag) { - bodylen -= taglen - (tag - body); - body = tag + taglen; - - if (taglen > fieldsizebytes) { /* drop leading 00 if present */ - if (*tag != 0x00) { - r = SC_ERROR_INVALID_DATA; - goto err; - } - tag++; - taglen--; - } - memcpy(out + fieldsizebytes*i + fieldsizebytes - taglen , tag, taglen); - } else { - r = SC_ERROR_INVALID_DATA; - goto err; - } - } else { - r = SC_ERROR_INVALID_DATA; - goto err; - } - } - r = 2 * fieldsizebytes; -err: + r = sc_asn1_decode_ecdsa_signature(card->ctx, data, datalen, fieldsizebytes, &out, outlen); LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 5fe6db5c61..3c168b8764 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -6,8 +6,8 @@ include $(top_srcdir)/aminclude_static.am clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean -noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin -TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin +noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature +TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature noinst_HEADERS = torture.h @@ -27,6 +27,7 @@ cachedir_SOURCES = cachedir.c pkcs15filter_SOURCES = pkcs15-emulator-filter.c openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c hextobin_SOURCES = hextobin.c +decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/decode_ecdsa_signature.c b/src/tests/unittests/decode_ecdsa_signature.c new file mode 100644 index 0000000000..984970ea93 --- /dev/null +++ b/src/tests/unittests/decode_ecdsa_signature.c @@ -0,0 +1,225 @@ +/* + * decode_ecdsa_signature.c: Unit tests for decode ASN.1 ECDSA signature + * + * Copyright (C) 2022 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "torture.h" +#include "libopensc/log.c" +#include "libopensc/asn1.c" + +static void torture_empty_rs(void **state) +{ + int r = 0; + size_t fieldsize = 24; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + char data[] = { 0x30, 0x04, 0x02, 0x00, 0x02, 0x00}; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 6, fieldsize, (u8 ** ) &out, 2); + free(out); + assert_int_equal(r, SC_ERROR_INVALID_DATA); +} + +static void torture_valid_format(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + u8 result[2] = { 0x03, 0x04}; + char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, 2 * fieldsize); + assert_memory_equal(result, out, 2); + free(out); +} + +static void torture_valid_format_leading00(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + u8 result[2] = { 0x03, 0x04}; + char data[] = { 0x30, 0x07, 0x02, 0x02, 0x00, 0x03, 0x02, 0x01, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, 2 * fieldsize); + assert_memory_equal(result, out, 2); + free(out); +} + +static void torture_valid_format_long_fieldsize(void **state) +{ + int r = 0; + size_t fieldsize = 3; + struct sc_context *ctx = NULL; + u8 *out = malloc(6); + u8 result[6] = { 0x00, 0x00, 0x03, 0x00, 0x00, 0x04}; + char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 6); + + assert_int_equal(r, 2 * fieldsize); + assert_memory_equal(result, out, 6); + free(out); +} + +static void torture_wrong_tag_len(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + char data[] = { 0x30, 0x05, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + +static void torture_wrong_integer_tag_len(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + +static void torture_small_fieldsize(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(3); + char data[] = { 0x30, 0x07, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 3); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + +static void torture_long_leading00(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(3); + char data[] = { 0x30, 0x07, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x04}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 10, fieldsize, (u8 **) &out, 3); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + +static void torture_missing_tag(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + char data[] = { 0x20, 0x07, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + + +static void torture_missing_integer_tag(void **state) +{ + int r = 0; + size_t fieldsize = 1; + struct sc_context *ctx = NULL; + u8 *out = malloc(2); + char data[] = { 0x30, 0x07, 0x01, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; + + if (!out) + return; + + sc_establish_context(&ctx, "test"); + r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); + + assert_int_equal(r, SC_ERROR_INVALID_DATA); + free(out); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_empty_rs), + cmocka_unit_test(torture_valid_format), + cmocka_unit_test(torture_valid_format_leading00), + cmocka_unit_test(torture_valid_format_long_fieldsize), + cmocka_unit_test(torture_wrong_tag_len), + cmocka_unit_test(torture_wrong_integer_tag_len), + cmocka_unit_test(torture_small_fieldsize), + cmocka_unit_test(torture_long_leading00), + cmocka_unit_test(torture_missing_tag), + cmocka_unit_test(torture_missing_integer_tag), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} + From 9aeecabaddefd5ca1166dca1e9b9e7bccb2aeb09 Mon Sep 17 00:00:00 2001 From: Eitot Date: Wed, 28 Sep 2022 23:43:07 +0200 Subject: [PATCH 2581/4321] macOS: Update workflow to include build-package and Distribution*.xml --- .github/workflows/macos.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e5ac172944..4a93d45212 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -12,6 +12,8 @@ on: - .github/build.sh - .github/push-artifacts.sh - '**.am' + - MacOSX/build-package.in + - 'MacOSX/Distribution*.xml.in' push: jobs: From 26cd7f227720a560df113be1c7d620b1fb7cd98a Mon Sep 17 00:00:00 2001 From: Eitot Date: Thu, 29 Sep 2022 01:37:25 +0200 Subject: [PATCH 2582/4321] macOS: Define arm64 as a supported architecture in the Installer package The Installer app assumes that the package requires Rosetta 2, unless arm64 is explicitly declared. s. https://scriptingosx.com/2020/12/platform-support-in-macos-installer-packages-pkg/ --- .gitignore | 2 +- MacOSX/Distribution_universal.xml.in | 65 ++++++++++++++++++++++++++++ MacOSX/Makefile.am | 7 ++- MacOSX/build-package.in | 5 ++- configure.ac | 1 + 5 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 MacOSX/Distribution_universal.xml.in diff --git a/.gitignore b/.gitignore index cf497a070f..dfd916f7cd 100644 --- a/.gitignore +++ b/.gitignore @@ -97,7 +97,7 @@ win32/OpenSC.wixobj win32/OpenSC.wixpdb MacOSX/build-package -MacOSX/Distribution.xml +MacOSX/Distribution*.xml *.dmg *.pkg diff --git a/MacOSX/Distribution_universal.xml.in b/MacOSX/Distribution_universal.xml.in new file mode 100644 index 0000000000..f834088fe5 --- /dev/null +++ b/MacOSX/Distribution_universal.xml.in @@ -0,0 +1,65 @@ + + + + + + + + + @PACKAGE_STRING@ + + + + + + + + + + OpenSC.pkg + + + OpenSC-tokend.pkg + + + OpenSCToken.pkg + + + OpenSC-startup.pkg + + diff --git a/MacOSX/Makefile.am b/MacOSX/Makefile.am index b0fa2130e2..764b2b5071 100644 --- a/MacOSX/Makefile.am +++ b/MacOSX/Makefile.am @@ -1,5 +1,10 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = build build-package.in Distribution.xml.in libtool-bundle opensc-uninstall \ +EXTRA_DIST = build \ + build-package.in \ + Distribution.xml.in \ + Distribution_universal.xml.in \ + libtool-bundle \ + opensc-uninstall \ resources \ resources/background.jpg \ resources/Welcome.html.in \ diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 29feda4b11..ba28bd8559 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -58,6 +58,9 @@ export CFLAGS="$CFLAGS -isysroot $SDK_PATH" if test -n "${BUILD_ARM}"; then export CFLAGS="$CFLAGS -arch x86_64 -arch arm64" export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64" + DISTRIBUTION_XML=MacOSX/Distribution_universal.xml +else + DISTRIBUTION_XML=MacOSX/Distribution.xml fi export OBJCFLAGS=$CFLAGS @@ -220,7 +223,7 @@ pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.open pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg # Build product -productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" +productbuild --distribution $DISTRIBUTION_XML --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" # Sign installer if test -n "${INSTALLER_SIGN_IDENTITY}"; then diff --git a/configure.ac b/configure.ac index 92de526053..87f93a25e9 100644 --- a/configure.ac +++ b/configure.ac @@ -1150,6 +1150,7 @@ AC_CONFIG_FILES([ MacOSX/Makefile MacOSX/build-package MacOSX/Distribution.xml + MacOSX/Distribution_universal.xml MacOSX/resources/Welcome.html ]) From 10dca3b425dcb15bdc5005f8a2671cdb7c268820 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 17 Oct 2022 10:28:25 +0200 Subject: [PATCH 2583/4321] tools: Fix typo and convert to utf8 --- doc/tools/tools.html | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 34afb591eb..1dd92c0a7c 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -5,7 +5,7 @@ } .title { - font-size: 1.5em; + font-size: 1.5em; text-align: center; } @@ -50,7 +50,7 @@

    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA).
    openpgp-tool — utility for accessing visible data OpenPGP smart cards and compatible tokens
    opensc-asn1 — parse ASN.1 data -
    opensc-explorer — +
    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions
    opensc-notify — monitor smart card events and send notifications @@ -164,7 +164,7 @@

    See also

    pkcs15-tool(1)

    Authors

    cryptoflex-tool was written by - Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    + Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card.

    Options

    @@ -211,12 +211,12 @@ arg is an ATR, the reader with a matching card will be chosen.

    - --wait, + --wait, -w

    Causes dnie-tool to wait for the token to be inserted into reader.

    --verbose, -v -

    Causes dnie-tool to be more verbose. +

    Causes dnie-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    Authors

    dnie-tool was written by @@ -244,11 +244,11 @@ Specify this flag several times to be more verbose.

    Health Care Application (HCA)

    --pd

    - Show 'Persönliche Versicherungsdaten' (XML). + Show 'Persönliche Versicherungsdaten' (XML).

    --vd

    Show 'Allgemeine Versicherungsdaten' (XML).

    --gvd

    - Show 'Geschützte Versicherungsdaten' (XML). + Show 'Geschützte Versicherungsdaten' (XML).

    --vsd-status

    Show 'Versichertenstammdaten-Status'.

    Authors

    egk-tool was written by @@ -557,7 +557,7 @@

    Specify the terminal's private key.

    --cvc-dir DIRECTORY

    - Specify where to look for the certificate of the + Specify where to look for the certificate of the Country Verifying Certification Authority (CVCA). If not given, it defaults to @@ -743,7 +743,7 @@ --version, -V

    Print version and exit.

    Authors

    opensc-asn1 was written by - Frank Morgner .


    Name

    opensc-explorer — + Frank Morgner .

    Configuration of Tokend

    score = num;

    @@ -976,10 +1007,13 @@

    slots_per_card = num;

    - Maximum number of slots per smart card (Default: - 4). If the card has fewer keys + Maximum number of PIN slots per smart card (Default: + 4). If the card has fewer PINs than defined here, the remaining number of slots - will be empty. + will be empty. For Firefox, Chrome and Chromium, the + slots_per_card is set to 1, + to avoid prompting for unrelated PINs. Typically, this + effectively disables signature PINs and keys.

    lock_login = bool;

    @@ -1168,15 +1202,21 @@

    PIV configuration during initialization with piv-tool. +

    + PIV_USE_SM, + PIV_PAIRING_CODE +

    + PIV configuration during initialization + See Configuration Options for PIV Card.

    Files

    - /usr/etc/opensc.conf + /etc/opensc.conf

    System-wide configuration file

    /usr/share/doc/opensc/opensc.conf

    Extended example configuration file -


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    +


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    The pkcs15-init utility for PKCS #15 smart card personalization is controlled via profiles. When starting, it will read two such profiles at the moment, a generic application profile, and a card diff --git a/doc/tools/tools.html b/doc/tools/tools.html index dc4e7f881c..4294dc16fd 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1,11 +1,11 @@ -OpenSC Manual Pages: Section 1

    OpenSC Manual Pages: Section 1


    Table of Contents

    cardos-tool — displays information about Card OS-based security tokens or format them -
    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
    dnie-tool — displays information about DNIe based security tokens
    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) -
    eidenv — utility for accessing visible data from - electronic identity cards
    gids-tool — smart card utility for GIDS cards
    iasecc-tool — displays information about IAS/ECC card -
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). -
    openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens
    opensc-asn1 — parse ASN.1 data -
    opensc-explorer — + -->

    OpenSC Manual Pages: Section 1


    Table of Contents

    cardos-tool — displays information about Card OS-based security tokens or format them +
    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
    dnie-tool — displays information about DNIe based security tokens
    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) +
    eidenv — utility for accessing visible data from + electronic identity cards
    gids-tool — smart card utility for GIDS cards
    iasecc-tool — displays information about IAS/ECC card +
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). +
    openpgp-tool — utility for accessing visible data OpenPGP smart cards + and compatible tokens
    opensc-asn1 — parse ASN.1 data +
    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -
    opensc-notify — monitor smart card events and send notifications -
    opensc-tool — generic smart card utility
    piv-tool — smart card utility for HSPD-12 PIV cards
    pkcs11-tool — utility for managing and using PKCS #11 security tokens
    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
    pkcs15-init — smart card personalization utility
    pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens
    sc-hsm-tool — smart card utility for SmartCard-HSM
    westcos-tool — utility for manipulating data structures - on westcos smart cards

    Name

    cardos-tool — displays information about Card OS-based security tokens or format them +

    opensc-notify — monitor smart card events and send notifications +
    opensc-tool — generic smart card utility
    piv-tool — smart card utility for HSPD-12 PIV cards
    pkcs11-tool — utility for managing and using PKCS #11 security tokens
    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards
    pkcs15-init — smart card personalization utility
    pkcs15-tool — utility for manipulating PKCS #15 data structures + on smart cards and similar security tokens
    sc-hsm-tool — smart card utility for SmartCard-HSM
    westcos-tool — utility for manipulating data structures + on westcos smart cards

    Name

    cardos-tool — displays information about Card OS-based security tokens or format them

    Synopsis

    cardos-tool [OPTIONS]

    Description

    The cardos-tool utility is used to display information about smart cards and similar security tokens based on Siemens Card/OS M4. @@ -94,7 +94,7 @@

    Causes cardos-tool to wait for the token to be inserted into reader.

    Authors

    cardos-tool was written by - Andreas Jellinghaus .


    Name

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

    Synopsis

    cryptoflex-tool [OPTIONS]

    Description

    + Andreas Jellinghaus .


    Name

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures

    Synopsis

    cryptoflex-tool [OPTIONS]

    Description

    cryptoflex-tool is used to manipulate PKCS data structures on Schlumberger Cryptoflex smart cards. Users can create, list and read PINs and keys stored on the smart card. @@ -164,7 +164,7 @@

    See also

    pkcs15-tool(1)

    Authors

    cryptoflex-tool was written by - Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    + Juha Yrjölä .


    Name

    dnie-tool — displays information about DNIe based security tokens

    Synopsis

    dnie-tool [OPTIONS]

    Description

    The dnie-tool utility is used to display additional information about DNIe, the Spanish National eID card.

    Options

    @@ -220,7 +220,7 @@ Specify this flag several times to enable debug output in the opensc library.

    Authors

    dnie-tool was written by - Juan Antonio Martinez .


    Name

    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK) + Juan Antonio Martinez .


    Name

    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK)

    Synopsis

    egk-tool [OPTIONS]

    Description

    The egk-tool utility is used to display information stored on the German elektronic health card (elektronische Gesundheitskarte, eGK).

    Options

    @@ -243,16 +243,16 @@ Causes egk-tool to be more verbose. Specify this flag several times to be more verbose.

    -

    Health Care Application (HCA)

    --pd

    - Show 'Persönliche Versicherungsdaten' (XML). +

    'Gesundheitsanwendung', Health Care Application (HCA)

    --pd

    + Show 'Persönliche Versichertendaten' (XML).

    --vd

    - Show 'Allgemeine Versicherungsdaten' (XML). + Show 'Allgemeine Versichertendaten' (XML).

    --gvd

    - Show 'Geschützte Versicherungsdaten' (XML). + Show 'Geschützte Versichertendaten' (XML).

    --vsd-status

    Show 'Versichertenstammdaten-Status'.

    Authors

    egk-tool was written by - Frank Morgner .


    Name

    eidenv — utility for accessing visible data from + Frank Morgner .


    Name

    eidenv — utility for accessing visible data from electronic identity cards

    Synopsis

    eidenv [OPTIONS]

    Description

    The eidenv utility is used for accessing data from electronic identity cards (like @@ -294,7 +294,7 @@ -w

    Wait for a card to be inserted

    Authors

    eidenv utility was written by - Stef Hoeben and Martin Paljak .


    Name

    gids-tool — smart card utility for GIDS cards

    Synopsis

    gids-tool [OPTIONS]

    + Stef Hoeben and Martin Paljak .


    Name

    gids-tool — smart card utility for GIDS cards

    Synopsis

    gids-tool [OPTIONS]

    The gids-tool utility can be used from the command line to perform miscellaneous smart card operations on a GIDS smart card.

    Options

    @@ -348,7 +348,7 @@

    See also

    opensc-tool(1)

    Authors

    gids-tool was written by - Vincent Le Toux .


    Name

    iasecc-tool — displays information about IAS/ECC card + Vincent Le Toux .


    Name

    iasecc-tool — displays information about IAS/ECC card

    Synopsis

    iasecc-tool [OPTIONS]

    Description

    The iasecc-tool utility is used to display information about IAS/ECC v1.0.1 smart cards.

    Options

    @@ -376,7 +376,7 @@

    Causes iasecc-tool to wait for the token to be inserted into reader.

    Authors

    iasecc-tool was written by - Viktor Tarasov .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the + Viktor Tarasov .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying @@ -459,11 +459,15 @@

    See also

    opensc-explorer(1)

    Authors

    netkey-tool was written by - Peter Koch .


    Name

    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). + Peter Koch .


    Name

    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA).

    Synopsis

    npa-tool [OPTIONS]

    Description

    The npa-tool utility is used to display information stored on the German eID card (neuer Personalausweis, nPA), and to perform some write and verification operations. +

    + Extended Access Control version 2 is performed according to ICAO Doc + 9303 or BSI TR-03110 so that other identity cards and machine + readable travel documents (MRTDs) may be read as well.

    Options

    --help, @@ -602,7 +606,7 @@

    --disable-all-checks

    Disable all checking of fly-by-data. (default=off)

    Authors

    npa-tool was written by - Frank Morgner .


    Name

    openpgp-tool — utility for accessing visible data OpenPGP smart cards + Frank Morgner .


    Name

    openpgp-tool — utility for accessing visible data OpenPGP smart cards and compatible tokens

    Synopsis

    openpgp-tool [OPTIONS]

    Description

    The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards @@ -733,7 +737,7 @@ Wait for a card to be inserted.

    Authors

    openpgp-tool utility was written by - Peter Marschall .


    Name

    opensc-asn1 — parse ASN.1 data + Peter Marschall .


    Name

    opensc-asn1 — parse ASN.1 data

    Synopsis

    opensc-asn1 [OPTIONS] [FILES]

    Description

    The opensc-asn1 utility is used to parse ASN.1 data.

    Options

    @@ -743,7 +747,7 @@ --version, -V

    Print version and exit.

    Authors

    opensc-asn1 was written by - Frank Morgner .


    Name

    opensc-explorer — + Frank Morgner .


    Name

    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    @@ -812,14 +816,14 @@ The following commands are supported:

    # - ... + ...

    Treat line as a comment. Ignore anything until the end of the line introduced by #.

    apdu - data... + data...

    Send a custom APDU command to the card. data is a series of @@ -872,7 +876,7 @@ DF-name.

    change - CHVpin-ref + CHVpin-ref [ [old-pin] new-pin @@ -951,7 +955,7 @@ in double quotes ("...").

    echo - string... + string...

    Print the strings given.

    @@ -1207,7 +1211,7 @@

    See also

    opensc-tool(1)

    Authors

    opensc-explorer was written by - Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications + Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications

    Synopsis

    opensc-notify [OPTIONS]

    Description

    The opensc-notify utility is used to monitor smart card events and send the appropriate notification. @@ -1252,7 +1256,7 @@ See notify_pin_bad in opensc.conf (default=off).

    Authors

    opensc-notify was written by - Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    + Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    The opensc-tool utility can be used from the command line to perform miscellaneous smart card operations such as getting the card ATR or sending arbitrary APDU commands to a card. @@ -1309,8 +1313,16 @@ but warm reset is also possible.

    --send-apdu apdu, -s apdu -

    Sends an arbitrary APDU to the card in the format - AA:BB:CC:DD:EE:FF....

    +

    + Sends an arbitrary APDU to the card in the format + AA:BB:CC:DD:EE:FF.... Use this option + multiple times to send more than one APDU. +

    + The built-in card drivers may send additional APDUs + for detection and initialization. To avoid this + behavior, you may additionally specify + --card-driver default. +

    --serial

    Print the card serial number (normally the ICCSN). Output is in hex byte format

    @@ -1324,7 +1336,7 @@

    See also

    opensc-explorer(1)

    Authors

    opensc-tool was written by - Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    + Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate @@ -1340,15 +1352,18 @@

    Print the name of the inserted card (driver)

    --admin argument, -A argument -

    Authenticate to the card using a 2DES or 3DES key. +

    Authenticate to the card using a 2DES, 3DES or AES key. The argument of the form

     {A|M}:ref:alg

    is required, were A uses "EXTERNAL AUTHENTICATION" and M uses "MUTUAL AUTHENTICATION". ref is normally 9B, - and alg is 03 for 3DES. - The key is provided by the card vendor, and the environment variable - PIV_EXT_AUTH_KEY must point to a text file containing + and alg is 03 for 3DES, + 01 for 2DES, 08 for AES-128, + 0A for AES-192 or 0C for AES-256. + The key is provided by the card vendor. The environment variable + PIV_EXT_AUTH_KEY must point to either a binary file + matching the length of the key or a text file containing the key in the format: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX

    @@ -1415,7 +1430,7 @@

    See also

    opensc-tool(1)

    Authors

    piv-tool was written by - Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    + Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the @@ -1476,11 +1491,14 @@ --key-type specification

    Specify the type and length (bytes if symmetric) of the key to create, for example RSA:1024, EC:prime256v1, GOSTR3410-2012-256:B, - DES:8, DES3:24, AES:16 or GENERIC:64.

    + DES:8, DES3:24, AES:16 or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    --usage-sign

    Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

    --usage-decrypt -

    Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey).

    +

    Specify 'decrypt' key usage flag.

    + For RSA keys, sets DECRYPT in privkey and ENCRYPT in pubkey. For secret + keys, sets both DECRYPT and ENCRYPT. +

    --usage-derive

    Specify 'derive' key usage flag (EC only).

    --usage-wrap @@ -1495,7 +1513,9 @@

    Display a list of mechanisms supported by the token.

    --list-objects, -O -

    Display a list of objects.

    +

    Display a list of objects.

    The options --keytype, --label + , --id or --application-id can be + used to filter the listed objects.

    --list-slots, -L

    Display a list of available slots on the token.

    @@ -1504,6 +1524,8 @@

    List slots with tokens.

    --list-interfaces

    List interfaces of PKCS #11 3.0 library.

    + --session-rw, +

    Forces to open the PKCS#11 session with CKF_RW_SESSION.

    --login, -l

    Authenticate to the token before performing @@ -1570,6 +1592,12 @@

    Sign some data.

    --decrypt,

    Decrypt some data.

    + --encrypt, +

    Encrypt some data.

    + --unwrap, +

    Unwrap key.

    + --wrap, +

    Wrap key.

    --derive,

    Derive a secret key using another key and some data.

    --derive-pass-der, @@ -1578,7 +1606,9 @@

    Specify how many bytes of salt should be used in RSA-PSS signatures. Accepts two special values: "-1" means salt length equals to digest length, - "-2" means use maximum permissible length. + "-2" or "-3" means use maximum permissible length. + For verify operation "-2" means that the salt length is automatically recovered from signature. + The value "-2" for the verify operation is supported for opensc pkcs#11 module only. Default is digest length (-1).

    --slot id

    Specify the id of the slot to use (accepts HEX format with 0x.. prefix or decimal number).

    @@ -1680,25 +1710,108 @@ --allow-sw

    Allow using software mechanisms that do not have the CKF_HW flag set. May be required when using software tokens and emulators. +

    + --iv data +

    Initialization vector for symmetric ciphers. + The data is hexadecimal number, i.e. "000013aa7bffa0".

    Examples

    - To list all certificates on the smart card: + Perform a basic functionality test of the card: +

    pkcs11-tool --test --login

    + + List all certificates on the smart card:

    pkcs11-tool --list-objects --type cert

    - To read the certificate with ID KEY_ID - in DER format from smart card: -

    pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der

    + Read the certificate with ID CERT_ID + in DER format from smart card and convert it to PEM via OpenSSL: +

    +pkcs11-tool --read-object --id $CERT_ID --type cert \
    +					--output-file cert.der
    +openssl x509 -inform DER -in cert.der -outform PEM > cert.pem
    +			

    - To convert the certificate in DER format to PEM format, use OpenSSL - tools: -

    openssl x509 -inform DER -in cert.der -outform PEM > cert.pem

    + Write a certificate to token: +

    pkcs11-tool --login --write-object certificate.der --type cert

    - To sign some data stored in file data - using the private key with ID ID and + Generate new RSA Key pair: +

    pkcs11-tool --login --keypairgen --key-type RSA:2048

    + + Generate new extractable RSA Key pair: +

    pkcs11-tool --login --keypairgen --key-type RSA:2048 --extractable

    + + Generate an elliptic curve key pair with OpenSSL and import it to the card as $ID: +

    openssl genpkey -out EC_private.der -outform DER \
    +	-algorithm EC -pkeyopt ec_paramgen_curve:P-521
    +pkcs11-tool --write-object EC_private.der --id "$ID" \
    +	--type privkey --label "EC private key" -p "$PIN"
    +openssl pkey -in EC_private.der -out EC_public.der \
    +	-pubout -inform DER -outform DER
    +pkcs11-tool --write-object EC_public.der --id "$ID" \
    +	--type pubkey  --label "EC public key" -p $PIN

    + + List private keys: +

    pkcs11-tool --login --list-objects --type privkey

    + + Sign some data stored in file data + using the private key with ID ID and using the RSA-PKCS mechanism: -

    pkcs11-tool --sign --id ID --mechanism RSA-PKCS --input-file data --output-file data.sig

    +

    +pkcs11-tool --sign --id $ID --mechanism RSA-PKCS \
    +	--input-file data --output-file data.sig
    +			

    + The same is also possible by piping the data from stdin rather than specifying a input file: +

    +dd if=data bs=128 count=1 \
    +	| pkcs11-tool --sign --id $ID --mechanism RSA-PKCS \
    +	> data.sig
    +			

    + + Verify the signed data: +

    +pkcs11-tool --id ID --verify -m RSA-PKCS \
    +	--input-file data --signature-file data.sig
    +			

    + + To encrypt file using the AES key with ID 85 and using mechanism AES-CBC with padding: +

    +pkcs11-tool --login --encrypt --id 85 -m AES-CBC-PAD \
    +	--iv "00000000000000000000000000000000" \
    +	-i file.txt -o encrypted_file.data
    +				

    + Decipher the encrypted file: +

    +pkcs11-tool --login --decrypt --id 85 -m AES-CBC-PAD \
    +	--iv "00000000000000000000000000000000" \
    +	--i encrypted_file.data -o decrypted.txt
    +				

    + + Use the key with ID 75 using mechanism AES-CBC-PAD, with initialization vector + "00000000000000000000000000000000" to wrap the key with ID 76 into output file + exported_aes.key +

    +pkcs11-tool --login --wrap --id 75 --mechanism AES-CBC-PAD \
    +	--iv "00000000000000000000000000000000" \
    +	--application-id 76 \
    +	--output-file exported_aes.key
    +				

    + Use the key with ID 22 and mechanism RSA-PKCS to unwrap key from file + aes_wrapped.key. After a successful unwrap operation, + a new AES key is created on token. ID of this key is set to 90 and label of this + key is set to unwrapped-key + Note: for the MyEID card, the AES key size must be present in key + specification i.e. AES:16 +

    +pkcs11-tool --login --unwrap --mechanism RSA-PKCS --id 22 \
    +	-i aes_wrapped.key --key-type AES: \
    +	--application-id 90 --applicatin-label unwrapped-key
    +				

    + + Use the SO-PIN to initialize or re-set the PIN: +

    +pkcs11-tool --login --login-type so --init-pin
    +				

    Authors

    pkcs11-tool was written by - Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    + Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 @@ -1804,7 +1917,7 @@ pkcs15-init(1), pkcs15-tool(1)

    Authors

    pkcs15-crypt was written by - Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    + Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles. @@ -1871,7 +1984,7 @@ pkcs15-init lets you generate a new key and store it on the card. You can do this using:

    - pkcs15-init --generate-key " keyspec " --auth-id " nn + pkcs15-init --generate-key "keyspec" --auth-id "nn"

    where keyspec describes the algorithm and the parameters of the key to be created. For example, rsa:2048 generates a RSA key @@ -2153,8 +2266,7 @@ Tells pkcs15-init to not ask for the transport keys and use default keys, as known by the card driver.

    - --sanity-check, - -T + --sanity-check

    Tells pkcs15-init to perform a card specific sanity check and possibly update @@ -2180,10 +2292,19 @@ wait for a card insertion.

    --use-pinpad

    Do not prompt the user; if no PINs supplied, pinpad will be used.

    + --auth-id filename, + -a filename +

    + Specify ID of PIN to use/create +

    --puk-id ID

    Specify ID of PUK to use/create

    + --label LABEL +

    + Specify label for a PIN, key, certificate or data object when creating a new objects. When deleting objects, this can be used to delete object by label. +

    --puk-label LABEL

    Specify label of PUK @@ -2283,7 +2404,7 @@

    See also

    pkcs15-profile(5)

    Authors

    pkcs15-init was written by - Olaf Kirch .


    Name

    pkcs15-tool — utility for manipulating PKCS #15 data structures + Olaf Kirch .


    Name

    pkcs15-tool — utility for manipulating PKCS #15 data structures on smart cards and similar security tokens

    Synopsis

    pkcs15-tool [OPTIONS]

    Description

    The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security @@ -2292,7 +2413,7 @@ operations that require it.

    Options

    - --version, + --version

    Print the OpenSC package release version.

    --aid aid

    Specify in a hexadecimal form the AID of the on-card PKCS#15 @@ -2342,7 +2463,7 @@ --list-public-keys

    List all public keys stored on the token, including key name, id, algorithm and length information.

    - --short + --short, -s

    Output lists in compact format.

    --no-cache @@ -2351,11 +2472,6 @@

    Removes the user's cache directory. On Windows, this option additionally removes the system's caching directory (requires administrator - privileges).

    - --clear-cache -

    Removes the user's cache directory. On - Windows, this option additionally removes the system's - caching directory (requires administrator privileges).

    --output filename, -o filename @@ -2371,7 +2487,7 @@ always be in raw binary.

    --read-certificate cert

    Reads the certificate with the given id.

    - --read-data-object cert, + --read-data-object data, -R data

    Reads data object with OID, applicationName or label. The content is printed to standard output in hex notation, unless @@ -2391,10 +2507,10 @@

    When used in conjunction with option --read-ssh-key the output format of the public key follows rfc4716.

    The default output format is a single line (openssh).

    --test-update, - -T, + -T

    Test if the card needs a security update

    --update, - -U, + -U

    Update the card with a security update

    --reader arg

    @@ -2413,7 +2529,7 @@ verbose. Specify this flag several times to enable debug output in the OpenSC library.

    --pin pin, - --new-pin newpin + --new-pin newpin, --puk puk

    These options can be used to specify the PIN/PUK values @@ -2447,7 +2563,7 @@ pkcs15-init(1), pkcs15-crypt(1)

    Authors

    pkcs15-tool was written by - Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    + Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import @@ -2457,7 +2573,7 @@ --initialize, -X

    Initialize token, removing all existing keys, certificates and files.

    Use --so-pin to define SO-PIN for first initialization or to verify in subsequent - initializations.

    Use --pin to define the initial user pin value.

    Use --pin-retry to define the maximum number of wrong user PIN presentations.

    Use with --dkek-shares to enable key wrap / unwrap.

    Use with --label to define a token label

    + initializations.

    Use --pin to define the initial user pin value.

    Use --pin-retry to define the maximum number of wrong user PIN presentations.

    Use with --dkek-shares to enable key wrap / unwrap.

    Use with --label to define a token label

    Use with --public-key-auth and --required-pub-keys to require public key authentication for login

    --create-dkek-share filename, -C filename

    Create a DKEK share encrypted under a password and save it to the file @@ -2525,6 +2641,38 @@ arg is an ATR, the reader with a matching card will be chosen.

    + --public-key-auth total-number-of-public-keys, + -K total-number-of-public-keys +

    Define the total number of public keys to use for public key authentication when using --initialize. + --public-key-auth is optional, but if it's present, it must be used with --required-pub-keys. +

    When the SmartCard-HSM is initialized with these options, it will require M-of-N public key authentication to be used, where + --required-pub-keys sets the M and --public-key-auth sets the N. After the initialization, + the user should use --register-public-key to register the N public keys before the SmartCard-HSM can be used. +

    + --required-pub-keys required-number-of-public-keys, + -n required-number-of-public-keys +

    Define the required number of public keys to use for public key authentication when using --initialize. + This is the M in M-of-N public key authentication. See --public-key-auth for more information. +

    + --register-public-key input-public-key-file, + -g input-public-key-file +

    Register a public key to be used for M-of-N public key authentication. The file can be exported from + a different SmartCard-HSM with --export-for-pub-key-auth. This can only be used when the + SmartCard-HSM has been initialized with --public-key-auth and --required-pub-keys + and fewer than N public keys have been registered. Use --public-key-auth-status to check the + how many public keys have been registered. +

    + --export-for-pub-key-auth output-public-key-file, + -e output-public-key-file +

    Export a public key to be used for M-of-N public key authentication. This should be used with + --key-reference to choose the key to export. The file should be registered on + another SmartCard-HSM using --register-public-key. +

    + --public-key-auth-status + -S +

    Print the public key authentication status. This is only valid if the SmartCard-HSM was initialized + to use M-of-N public key authentication. +

    --wait, -w

    Wait for a card to be inserted

    @@ -2533,10 +2681,10 @@

    Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    See also

    +

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    Initialize SmartCard-HSM to use M-of-N public key authentication with M=2 and N=5

    sc-hsm-tool --initialize --required-pub-keys 2 --public-key-auth 5

    Export a public key for M-of-N public key authentication to a file

    sc-hsm-tool --key-reference 1 --export-for-pub-key-auth ./public_key1.asn1

    Register a public key for M-of-N public key authentication from a file

    sc-hsm-tool --register-public-key ./public_key1.asn1

    See also

    opensc-tool(1)

    Authors

    sc-hsm-tool was written by - Andreas Schwier .


    Name

    westcos-tool — utility for manipulating data structures + Andreas Schwier .


    Name

    westcos-tool — utility for manipulating data structures on westcos smart cards

    Synopsis

    westcos-tool [OPTIONS]

    Description

    The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, @@ -2565,7 +2713,7 @@

    Generate a private key on the card. The card must not have been finalized and a PIN must be installed (i.e. the file for the PIN must have been created, see option -i). - By default the key length is 1536 bits. User authentication is required for + By default the key length is 2048 bits. User authentication is required for this operation.

    --help, -h From 96bc6a16ed285d423cc86435405b1e6642f9b3a1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 27 Feb 2024 10:30:45 +0100 Subject: [PATCH 3360/4321] dtrust-tool: Fix NULL dereference with pinpad Thanks coverity: CID 414970 CID 414971 CID 414972 CID 414973 --- src/tools/dtrust-tool.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index a8d1e4dae6..f3d6cfb129 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -177,13 +177,12 @@ unlock_transport_protection(sc_card_t *card) fprintf(stderr, "New signature PINs doesn't match.\n"); goto fail_qespin2; } + data.pin1.data = (u8 *)tpin; + data.pin1.len = strlen(tpin); + data.pin2.data = (u8 *)qespin1; + data.pin2.len = strlen(qespin1); } - data.pin1.data = (u8 *)tpin; - data.pin1.len = strlen(tpin); - data.pin2.data = (u8 *)qespin1; - data.pin2.len = strlen(qespin1); - r = sc_pin_cmd(card, &data, &tries_left); if (r == SC_SUCCESS) From 3f0175c00fc9f4ab814ecbc4ec907a1722318f7c Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Tue, 27 Feb 2024 17:50:10 +0100 Subject: [PATCH 3361/4321] dtrust-tool: validate PIN length --- src/tools/dtrust-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index f3d6cfb129..0ab4b5aabc 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -145,6 +145,10 @@ unlock_transport_protection(sc_card_t *card) data.cmd = SC_PIN_CMD_CHANGE; data.pin_type = SC_AC_CHV; data.pin_reference = 0x87; + data.pin1.min_length = 5; + data.pin1.max_length = 5; + data.pin2.min_length = 6; + data.pin2.max_length = 12; if (card->reader->capabilities & SC_READER_CAP_PIN_PAD) { printf("Please enter PINs on the reader's pin pad.\n"); From 900d1c6740bb5d3602a3b4c9adf2e5f419fb5ca1 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 13 Feb 2024 10:03:44 +0200 Subject: [PATCH 3362/4321] Add SafeNet 5110+ FIPS token support Signed-off-by: Raul Metsma --- .gitignore | 2 ++ src/libopensc/card-idprime.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index c701372e60..46ab3925cb 100644 --- a/.gitignore +++ b/.gitignore @@ -148,3 +148,5 @@ src/tests/fuzzing/fuzz_pkcs15init src/tests/fuzzing/fuzz_scconf_parse_string version.m4.ci +openssl_arm64 +openssl_bin diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 5c13fb4b32..57b76919e4 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -57,6 +57,10 @@ static const struct sc_atr_table idprime_atrs[] = { "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 930/3930", SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85", + "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", + "based Gemalto IDPrime 930", + SC_CARD_TYPE_IDPRIME_930, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940", @@ -648,10 +652,8 @@ static int idprime_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_IDPRIME_930 || card->type == SC_CARD_TYPE_IDPRIME_940) { _sc_card_add_rsa_alg(card, 4096, flags, 0); - } - /* Set up algorithm info for EC */ - if (card->type == SC_CARD_TYPE_IDPRIME_940) { + /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_F_P | SC_ALGORITHM_EXT_EC_ECPARAMETERS From 67986eda93a3a359a897f0b0be97f4315dde8d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 5 Mar 2024 10:38:33 +0100 Subject: [PATCH 3363/4321] OpenSC 0.25.0 --- NEWS | 8 +++++++- configure.ac | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4cb611e2fb..13017fd7be 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.25.0; 2024-02-XX +# New in 0.25.0; 2024-03-06 ## Security * [CVE-2023-5992](https://github.com/OpenSC/OpenSC/wiki/CVE-2023-5992): Side-channel leaks while stripping encryption PKCS#1.5 padding in OpenSC (#2948) * [CVE-2024-1454](https://github.com/OpenSC/OpenSC/wiki/CVE-2024-1454): Potential use-after-free in AuthentIC driver during card enrollment in pkcs15init (#2962) @@ -23,21 +23,27 @@ NEWS for OpenSC -- History of user visible changes * Simplify printing EC keys parameters (#2960) * Add option to import GENERIC key (#2955) * Add support for importing Ed25518/448 keys (#2985) +## drust-tool +* Add tool for D-Trust cards (#3026, #3051) ## IDPrime * Support uncompressed certificates on IDPrime 940 (#2958) * Enhance IDPrime logging (#3003) +* Add SafeNet 5110+ FIPS token support (#3048) ## D-Trust Signature Cards * Add support for RSA D-Trust Signature Card 4.1 and 4.4 (#2943) ## EstEID * Remove expired EstEID 3.* card support (#2950) ## ePass2003 * Allow SW implementation with more SHA2 hashes and ECDSA (#3012) +* Fix EC key generation (#3045) ## SmartCard-HSM * Fix SELECT APDU command (#2978) ## MyEID * Update for PKCS#15 profile (#2965) ## Rutoken * Support for RSA 4096 key algorithm (#3011) +## OpenPGP +* Fix decryption requiting Manage Security Environment for authentication key (#3042) # New in 0.24.0; 2023-12-13 ## Security diff --git a/configure.ac b/configure.ac index 1639965ff2..e8d502bd9e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [25]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc1]) +define([PACKAGE_SUFFIX], []) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) @@ -48,7 +48,7 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Interfaces added: CURRENT++, REVISION=0) OPENSC_LT_CURRENT="11" OPENSC_LT_OLDEST="11" -OPENSC_LT_REVISION="0" +OPENSC_LT_REVISION="1" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libopensc/sc.c]) From 3a822b030619e667e4a7aa00340e50108287c1aa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 7 Mar 2024 14:38:50 +0100 Subject: [PATCH 3364/4321] README: Use https for HTML preview --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f594c020b..a35f53fb46 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # OpenSC documentation -Manual pages for the [OpenSC command line tools](htmlpreview.github.io/?https://github.com/OpenSC/OpenSC/blob/master/doc/tools/tools.html) as well as for the [OpenSC configuration files](http://htmlpreview.github.io/?https://github.com/OpenSC/OpenSC/blob/master/doc/files/files.html) are available online and typically distributed along with your installation. +Manual pages for the +[OpenSC command line tools](https://htmlpreview.github.io/?https://github.com/OpenSC/OpenSC/blob/master/doc/tools/tools.html) +as well as for the +[OpenSC configuration files](https://htmlpreview.github.io/?https://github.com/OpenSC/OpenSC/blob/master/doc/files/files.html) +are available online and typically distributed along with your installation. The [OpenSC Wiki](https://github.com/OpenSC/OpenSC/wiki) includes, among others, information for: * [Windows Quick Start](https://github.com/OpenSC/OpenSC/wiki/Windows-Quick-Start) From d6ca03a94d36cf25053f74d543f217caa21c80d4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 7 Mar 2024 14:41:02 +0100 Subject: [PATCH 3365/4321] doc: Include docbook-utf8.xml in the dist tarball --- doc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 754720a995..85db89a212 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,5 +2,5 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in SUBDIRS = tools files -dist_noinst_SCRIPTS = html.xsl man.xsl +dist_noinst_SCRIPTS = html.xsl docbook-utf8.xsl man.xsl dist_noinst_DATA = api.css From b694d932481ca528cc9cdc74b7445749f3d568e3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 7 Mar 2024 14:41:17 +0100 Subject: [PATCH 3366/4321] ci: Build docs by default --- .github/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/build.sh b/.github/build.sh index c955b8904c..ee4e54b746 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -54,7 +54,7 @@ else fi # normal procedure - CONFIGURE_FLAGS="--disable-dependency-tracking" + CONFIGURE_FLAGS="--disable-dependency-tracking --enable-doc" if [ "$1" == "piv-sm" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-piv-sm" fi From 4ba437c344d71cf1631debe8b7a2a3eee962e187 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 7 Mar 2024 14:56:36 +0100 Subject: [PATCH 3367/4321] ci: Pass the configure flags to distcheck too --- .github/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/build.sh b/.github/build.sh index ee4e54b746..7770590af1 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -92,6 +92,7 @@ fi # this is broken in old ubuntu if [ "$1" == "dist" -o "$2" == "dist" ]; then set +e + DISTCHECK_CONFIGURE_FLAGS="$CONFIGURE_FLAGS" make distcheck RV=$? if [ $RV -ne 0 ]; then From 6c15101fec17688257f07be5265f0bfab0ac20cb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Mar 2024 11:57:21 +0100 Subject: [PATCH 3368/4321] README: Fix link on to AppVeyor build --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a35f53fb46..d222721486 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Nightly builds are available by their git hash in branches of [OpenSC/Nightly](h [![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) [![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) -[![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) +[![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/frankmorgner/opensc/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![CodeQL](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml/badge.svg?event=push)](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opensc.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:opensc) From b6f69fd2d47edc8344c92eecdcb8147bbec4fa9e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 12 Feb 2024 21:52:02 +0100 Subject: [PATCH 3369/4321] OpenPGP: fixed state tracking after erasing card fixes https://github.com/OpenSC/OpenSC/issues/3018 --- src/libopensc/card-openpgp.c | 51 ++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0e80150539..584a5a8926 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -357,6 +357,27 @@ pgp_match_card(sc_card_t *card) } +/* populate MF - add matching blobs listed in the pgp_objects table */ +int populate_blobs_to_mf(sc_card_t *card, struct pgp_priv_data *priv) +{ + pgp_do_info_t *info; + for (info = priv->pgp_objects; (info != NULL) && (info->id > 0); info++) { + if (((info->access & READ_MASK) != READ_NEVER) && (info->get_fn != NULL)) { + pgp_blob_t *child = NULL; + sc_file_t *file = sc_file_new(); + + child = pgp_new_blob(card, priv->mf, info->id, file); + + /* catch out of memory condition */ + if (child == NULL) { + sc_file_free(file); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + } + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + /** * ABI: initialize driver & allocate private data. */ @@ -366,7 +387,6 @@ pgp_init(sc_card_t *card) struct pgp_priv_data *priv; sc_path_t path; sc_file_t *file = NULL; - pgp_do_info_t *info; int r, i; LOG_FUNC_CALLED(card->ctx); @@ -483,19 +503,10 @@ pgp_init(sc_card_t *card) /* select MF */ priv->current = priv->mf; - /* populate MF - add matching blobs listed in the pgp_objects table */ - for (info = priv->pgp_objects; (info != NULL) && (info->id > 0); info++) { - if (((info->access & READ_MASK) != READ_NEVER) && (info->get_fn != NULL)) { - pgp_blob_t *child = NULL; - - child = pgp_new_blob(card, priv->mf, info->id, sc_file_new()); - - /* catch out of memory condition */ - if (child == NULL) { - pgp_finish(card); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - } + r = populate_blobs_to_mf(card, priv); + if (r < 0) { + pgp_finish(card); + LOG_FUNC_RETURN(card->ctx, r); } /* get card_features from ATR & DOs */ @@ -3551,6 +3562,18 @@ pgp_erase_card(sc_card_t *card) "Card does not offer life cycle management"); } + if (r == SC_SUCCESS && priv->mf) { + pgp_blob_t *new_mf = pgp_new_blob(card, NULL, priv->mf->id, priv->mf->file); + if (new_mf == NULL) { + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Failed to allocate the new MF blob"); + } + priv->mf->file = NULL; + + pgp_free_blobs(priv->mf); + priv->mf = new_mf; + populate_blobs_to_mf(card, priv); + } + LOG_FUNC_RETURN(card->ctx, r); } From d2cbd63a25c73882ee0fbcc9d2d3d72140d2aa57 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Feb 2024 02:52:27 +0100 Subject: [PATCH 3370/4321] fixed error handling --- src/pkcs15init/pkcs15-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index a2817b9450..369d8ade5b 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1654,6 +1654,8 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr r = profile->ops->emu_store_data(p15card, profile, object, NULL, NULL); if (r == SC_ERROR_NOT_IMPLEMENTED) r = SC_SUCCESS; + if (r < 0) + sc_pkcs15_remove_object(p15card, object); LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'store data' failed"); } From 03f278d18675886592233c3e500803df78d6604a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 4 Mar 2024 14:24:42 +0100 Subject: [PATCH 3371/4321] tests: Reorder commands to avoid intefering with the Fedora setup The .github/setup-fedora.sh changes the XFAIL_TESTS by sed that expands to the end of the file, which previously removed also this p11test test. By reordering these we can keep the workaround working. --- tests/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 2f1693baba..c275167ed3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -47,11 +47,11 @@ TESTS = \ test-pkcs11-tool-sym-crypt-test.sh \ test-pkcs11-tool-unwrap-wrap-test.sh \ test-pkcs11-tool-import.sh -XFAIL_TESTS = \ - test-pkcs11-tool-test-threads.sh \ - test-pkcs11-tool-test.sh if ENABLE_TESTS if ENABLE_SHARED TESTS += test-p11test.sh endif endif +XFAIL_TESTS = \ + test-pkcs11-tool-test-threads.sh \ + test-pkcs11-tool-test.sh From 0ab1f8167151098b0e6cfc1d642a03b77d8d59ae Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 4 Mar 2024 13:01:28 +0100 Subject: [PATCH 3372/4321] ci: Verify the HTML documentation is up-to-date Using Fedora image as the ubuntu creates non-standard /usr/etc/... paths without more tweaking Fixes: #3056 --- .github/workflows/doc.yml | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/doc.yml diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml new file mode 100644 index 0000000000..3a4f8edec4 --- /dev/null +++ b/.github/workflows/doc.yml @@ -0,0 +1,40 @@ +--- +name: Make sure HTML files are updated + +on: + pull_request: + paths: + - '**.xml' + - '**.xml.in' + - .github/workflows/doc.yml + +jobs: + build: + runs-on: ubuntu-latest + container: + image: fedora:latest + steps: + # Do this before checkout otherwise we will not have a git repository + - run: dnf install -y git + - uses: actions/checkout@v3 + - run: .github/setup-fedora.sh + # git checkout to revert changes to tests/Makefile.am done by the setup + - run: | + git config --global --add safe.directory $GITHUB_WORKSPACE && + git checkout tests/Makefile.am && + ./bootstrap && + ./configure --prefix="/usr" --enable-doc && + cd doc/tools && + rm tools.html && + make tools.html && + cd ../files && + rm files.html && + make files.html && + cd ../../ && + git diff --exit-code --color || ( + echo "The documentation files were changed!" + echo -n "Regenerate the HTML files with " + echo -n "\`make tools.html\` in \`doc/tools\` and " + echo -n "\`make files.html\`in \`doc/files\` or apply the above patch" + exit 1 + ) From 19846e16d7f5a09db1420c2b947c16109725b745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 12 Mar 2024 13:32:51 +0100 Subject: [PATCH 3373/4321] Remove reselection of DF after error in decipher, sign and derive --- src/pkcs11/framework-pkcs15.c | 53 ++--------------------------------- 1 file changed, 3 insertions(+), 50 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 11cfc51273..ac72532029 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -218,7 +218,6 @@ static CK_RV get_ec_pubkey_point(struct sc_pkcs15_pubkey *, CK_ATTRIBUTE_PTR); static CK_RV get_ec_pubkey_params(struct sc_pkcs15_pubkey *, CK_ATTRIBUTE_PTR); static int lock_card(struct pkcs15_fw_data *); static int unlock_card(struct pkcs15_fw_data *); -static int reselect_app_df(sc_pkcs15_card_t *p15card); #ifdef USE_PKCS15_INIT static CK_RV set_gost3410_params(struct sc_pkcs15init_prkeyargs *, @@ -4263,7 +4262,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; CK_RV rv; - int flags = 0, prkey_has_path = 0, rc; + int flags = 0, rc; unsigned sign_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; @@ -4284,9 +4283,6 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, if (prkey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; - if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len) - prkey_has_path = 1; - switch (pMechanism->mechanism) { case CKM_RSA_PKCS: flags = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01 | SC_ALGORITHM_RSA_HASH_NONE; @@ -4421,17 +4417,6 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, flags, ulDataLen, *pulDataLen); rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, pData, ulDataLen, pSignature, *pulDataLen, pMechanism); - if (rc < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) { - /* If private key PKCS#15 object do not have 'path' attribute, - * and if PKCS#11 login session is not locked, - * the compute signature could fail because of concurrent access to the card - * by other application that could change the current DF. - * In this particular case try to 'reselect' application DF. - */ - if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) - rc = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, - pData, ulDataLen, pSignature, *pulDataLen, pMechanism); - } sc_unlock(p11card->card); @@ -4521,7 +4506,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey; unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */ - int rv, flags = 0, prkey_has_path = 0; + int rv, flags = 0; CK_ULONG mask, good, rv_pkcs11; if (pulDataLen == NULL) { @@ -4556,9 +4541,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, if (prkey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; - if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len) - prkey_has_path = 1; - /* Select the proper padding mechanism */ switch (pMechanism->mechanism) { case CKM_RSA_PKCS: @@ -4611,13 +4593,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags, pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism); - /* skip for PKCS#1 v1.5 padding prevent side channel attack */ - if (!(flags & SC_ALGORITHM_RSA_PAD_PKCS1) && - rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) - if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) - rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags, - pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism); - sc_unlock(p11card->card); sc_log(context, "Decryption complete."); @@ -4670,7 +4645,7 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, struct sc_pkcs11_card *p11card = session->slot->p11card; struct pkcs15_fw_data *fw_data = NULL; struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; - int need_unlock = 0, prkey_has_path = 0; + int need_unlock = 0; int rv, flags = 0; CK_BYTE_PTR pSeedData = NULL; CK_ULONG ulSeedDataLen = 0; @@ -4692,9 +4667,6 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, if (prkey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; - if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len) - prkey_has_path = 1; - if (pData != NULL && *pulDataLen > 0) { /* TODO DEE only test for NULL? */ need_unlock = 1; rv = sc_lock(p11card->card); @@ -4721,10 +4693,6 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj, size_t len = *pulDataLen; rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags, pSeedData, ulSeedDataLen, pData, &len); - if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path && need_unlock) - if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS) - rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags, - pSeedData, ulSeedDataLen, pData, &len); *pulDataLen = len; /* this may have been a request for size */ @@ -6803,18 +6771,3 @@ unlock_card(struct pkcs15_fw_data *fw_data) } return 0; } - - -static int -reselect_app_df(sc_pkcs15_card_t *p15card) -{ - int r = SC_SUCCESS; - - if (p15card->file_app != NULL) { - /* if the application df (of the pkcs15 application) is specified select it */ - sc_path_t *tpath = &p15card->file_app->path; - sc_log(p15card->card->ctx, "reselect application df"); - r = sc_select_file(p15card->card, tpath, NULL); - } - return r; -} From 3fde612636cfb0130c691e72d8857d7690f31832 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 Mar 2024 00:09:17 +0100 Subject: [PATCH 3374/4321] fixed gcc7 format-truncation warning (#3069) fixes https://github.com/OpenSC/OpenSC/issues/1800 --- src/libopensc/pkcs15-openpgp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 27fab34e66..47ced37b7f 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -628,6 +628,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) LOG_FUNC_RETURN(ctx, r); } +// see https://stackoverflow.com/a/10536254 for explanation +#define LEN_MAX_INT_AS_STR (3 * sizeof(int) + 2) + static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) { @@ -639,8 +642,8 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) for (i = 1; i <= PGP_NUM_PRIVDO; i++) { sc_pkcs15_data_info_t dat_info; sc_pkcs15_object_t dat_obj; - char name[8]; - char path[9]; + char name[6 + LEN_MAX_INT_AS_STR]; + char path[7 + LEN_MAX_INT_AS_STR]; u8 content[254]; memset(&dat_info, 0, sizeof(dat_info)); memset(&dat_obj, 0, sizeof(dat_obj)); From e71b05016684a9154c29d565baee3c568b2965c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 5 Oct 2023 10:57:59 +0200 Subject: [PATCH 3375/4321] Add OpenSSL logging function --- src/libopensc/libopensc.exports | 2 ++ src/libopensc/log.c | 40 +++++++++++++++++++++++++++++++++ src/libopensc/log.h | 9 ++++++++ 3 files changed, 51 insertions(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 5995de7753..b5f0b1cb27 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -92,6 +92,7 @@ sc_disconnect_card sc_do_log sc_do_log_color sc_do_log_noframe +sc_do_log_openssl _sc_debug _sc_debug_hex sc_enum_apps @@ -361,6 +362,7 @@ _sc_card_add_rsa_alg _sc_match_atr _sc_match_atr_block _sc_log +_sc_log_openssl eac_secret_name get_pace_capabilities perform_pace diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 875c801839..e0814f4a5d 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -44,6 +44,9 @@ #ifdef _WIN32 #include #endif +#ifdef ENABLE_OPENSSL +#include +#endif /* ENABLE_OPENSSL */ #include "internal.h" @@ -68,6 +71,38 @@ void sc_do_log_color(sc_context_t *ctx, int level, const char *file, int line, c va_end(ap); } +#ifdef ENABLE_OPENSSL +void sc_do_log_openssl(sc_context_t *ctx, int level, const char *file, int line, const char *func) +{ + BIO *bio = NULL; + int length = 0; + char *buffer = NULL; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + sc_do_log(ctx, level, file, line, func, "Cannot log OpenSSL error"); + goto end; + } + ERR_print_errors(bio); + + if ((length = BIO_pending(bio)) <= 0 || + (buffer = malloc(length)) == NULL || + BIO_read(bio, buffer, length) <= 0) { + sc_do_log(ctx, level, file, line, func, "Cannot log OpenSSL error"); + goto end; + } + + sc_do_log(ctx, level, file, line, func, "OpenSSL error\n%s", buffer); +end: + free(buffer); + BIO_free(bio); +} +#else +void sc_do_log_openssl(sc_context_t *ctx, int level, const char *file, int line, const char *func) +{ + sc_do_log(ctx, level, file, line, func, "OpenSSL not enabled"); +} +#endif + void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list args) { sc_do_log_va(ctx, level, NULL, 0, NULL, 0, format, args); @@ -172,6 +207,11 @@ void _sc_log(struct sc_context *ctx, const char *format, ...) va_end(ap); } +void _sc_log_openssl(struct sc_context *ctx) +{ + sc_do_log_openssl(ctx, SC_LOG_DEBUG_DEPS, NULL, 0, NULL); +} + static int is_a_tty(FILE *fp) { if (fp != NULL) { diff --git a/src/libopensc/log.h b/src/libopensc/log.h index a670fdb41d..49f53213b5 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -37,6 +37,7 @@ enum { SC_LOG_DEBUG_SM, /* secure messaging */ SC_LOG_DEBUG_ASN1, /* asn1.c */ SC_LOG_DEBUG_MATCH, /* card matching */ + SC_LOG_DEBUG_DEPS, /* debugging of dependencies, e.g. OpenSSL */ SC_LOG_DEBUG_PIN, /* PIN commands */ }; @@ -68,9 +69,11 @@ enum { #if defined(__GNUC__) #define sc_debug(ctx, level, format, args...) sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args) #define sc_log(ctx, format, args...) sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args) +#define sc_log_openssl(ctx) sc_do_log_openssl(ctx, SC_LOG_DEBUG_DEPS, FILENAME, __LINE__, __FUNCTION__) #else #define sc_debug _sc_debug #define sc_log _sc_log +#define sc_log_openssl _sc_log_openssl #endif #if defined(__GNUC__) @@ -93,6 +96,7 @@ void _sc_debug(struct sc_context *ctx, int level, const char *format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 3, 4))); void _sc_log(struct sc_context *ctx, const char *format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 2, 3))); +void _sc_log_openssl(struct sc_context *ctx); int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...) __attribute__ ((format (SC_PRINTF_FORMAT, 4, 5))); #else @@ -103,8 +107,13 @@ void sc_do_log_color(struct sc_context *ctx, int level, const char *file, int li void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list args); void _sc_debug(struct sc_context *ctx, int level, const char *format, ...); void _sc_log(struct sc_context *ctx, const char *format, ...); +void _sc_log_openssl(struct sc_context *ctx); int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...); #endif + +void sc_do_log_openssl(struct sc_context *ctx, int level, const char *file, int line, + const char *func); + /** * @brief Log binary data to a sc context * From 897e151d78b6ace4b7eaed96d3152502235b7dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 20 Oct 2023 18:03:46 +0200 Subject: [PATCH 3376/4321] card-piv: Rewrite OpenSSL logging --- src/libopensc/card-piv.c | 78 +++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index dc55ae75f1..5e9dcd9e68 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -50,12 +50,7 @@ #include #endif #include - -#define piv_log_openssl(C) \ - do { if (C && C->debug > 0 && C->debug_file != 0) \ - { ERR_print_errors_fp(C->debug_file); } \ - } while(0) -#endif /* ENABLE_OPENSSL */ +#endif /* 800-73-4 SM and VCI need: ECC, SM and real OpenSSL >= 1.1 */ #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) && !defined(OPENSSL_NO_EC) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -929,6 +924,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu #if OPENSSL_VERSION_NUMBER < 0x30000000L cmac_ctx = CMAC_CTX_new(); if (cmac_ctx == NULL) { + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -939,7 +935,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -957,7 +953,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { sc_log(card->ctx,"SM encode failed in OpenSSL"); - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1034,7 +1030,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { /* should not happen */ sc_log(card->ctx,"SM _encode failed in OpenSSL"); - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1056,6 +1052,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 || CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 || CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) { + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1066,7 +1063,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || !EVP_MAC_update(cmac_ctx, header, sizeof(header)) || !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) || !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1259,6 +1256,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu #if OPENSSL_VERSION_NUMBER < 0x30000000L cmac_ctx = CMAC_CTX_new(); if (cmac_ctx == NULL) { + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1267,7 +1265,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1281,6 +1279,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || CMAC_Update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) != 1 || CMAC_Update(cmac_ctx, sm_apdu->resp, macdatalen) != 1 || CMAC_Final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen) != 1) { + sc_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1290,7 +1289,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) || !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) || !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1314,8 +1313,8 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"SM encode failed in OpenSSL"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1365,8 +1364,8 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0 || outll != 16) { /* should not happen */ + sc_log_openssl(card->ctx); sc_log(card->ctx,"SM _decode failed in OpenSSL"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1899,8 +1898,8 @@ static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, || EVP_DigestVerifyInit(md_ctx, NULL, type, NULL, pkey) != 1 || EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 || EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) { + sc_log_openssl(card->ctx); sc_log (card->ctx, "EVP_DigestVerifyFinal failed"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1999,8 +1998,8 @@ static int piv_sm_verify_certs(struct sc_card *card) if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL || (cert_pkey = X509_get0_pubkey(cert)) == NULL) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to get pubkey from SM_CERT_SIGNER"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2025,8 +2024,8 @@ static int piv_sm_verify_certs(struct sc_card *card) priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 || EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 || EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2041,8 +2040,8 @@ static int piv_sm_verify_certs(struct sc_card *card) || !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) || !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) || !in_cvc_pkey) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2231,8 +2230,8 @@ static int piv_sm_open(struct sc_card *card) || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 || Qehlen > cs->Qlen) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2250,8 +2249,8 @@ static int piv_sm_open(struct sc_card *card) || !Qehx || Qehxlen > cs->Qlen ) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2401,8 +2400,8 @@ static int piv_sm_open(struct sc_card *card) if (EVP_DigestInit(hash_ctx,EVP_sha256()) != 1 || EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 || EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"IDsicc hash failed"); - piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -2421,8 +2420,8 @@ static int piv_sm_open(struct sc_card *card) priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 || EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 || EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to get card's EC pubkey"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2437,8 +2436,8 @@ static int piv_sm_open(struct sc_card *card) || !EVP_PKEY_fromdata_init(Cicc_ctx) || !EVP_PKEY_fromdata(Cicc_ctx, &Cicc_pkey, EVP_PKEY_PUBLIC_KEY, Cicc_params) || !Cicc_pkey) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey for Cicc"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2461,8 +2460,8 @@ static int piv_sm_open(struct sc_card *card) || (Z = malloc(Zlen)) == NULL || EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 || Zlen != cs->Zlen) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create secret Z"); - piv_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2536,6 +2535,7 @@ static int piv_sm_open(struct sc_card *card) if (EVP_DigestInit(hash_ctx,(*cs->kdf_md)()) != 1 || EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 || EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) { + sc_log_openssl(card->ctx); sc_log(card->ctx,"KDF hash failed"); r = SC_ERROR_INTERNAL; goto err; @@ -2602,6 +2602,7 @@ static int piv_sm_open(struct sc_card *card) || CMAC_Update(cmac_ctx, MacData, MacDatalen) != 1 || CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) { r = SC_ERROR_INTERNAL; + sc_log_openssl(card->ctx); sc_log(card->ctx,"AES_CMAC failed %d",r); goto err; } @@ -2616,7 +2617,7 @@ static int piv_sm_open(struct sc_card *card) priv->sm_session.aes_size, cmac_params) || !EVP_MAC_update( cmac_ctx, MacData, MacDatalen) || !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; sc_log(card->ctx,"AES_CMAC failed %d",r); goto err; @@ -2651,7 +2652,7 @@ static int piv_sm_open(struct sc_card *card) priv->sm_flags &= ~PIV_SM_FLAGS_DEFER_OPEN; if (r != 0) memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); - piv_log_openssl(card->ctx); /* catch any not logged above */ + sc_log_openssl(card->ctx); /* catch any not logged above */ sc_unlock(card); @@ -3780,14 +3781,15 @@ static int piv_general_mutual_authenticate(sc_card_t *card, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { + sc_log_openssl(card->ctx); r = SC_ERROR_OUT_OF_MEMORY; goto err; } cipher = get_cipher_for_algo(card, alg_id); if(!cipher) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); - piv_log_openssl(card->ctx); r = SC_ERROR_INVALID_ARGUMENTS; goto err; } @@ -3845,7 +3847,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* decrypt the data from the card */ if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { /* may fail if des parity of key is wrong. depends on OpenSSL options */ - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -3853,7 +3855,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, p = plain_text; if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, (int)witness_len)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -3861,7 +3863,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, p += tmplen; if(!EVP_DecryptFinal(ctx, p, &N)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -3994,7 +3996,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, EVP_CIPHER_CTX_reset(ctx); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -4002,7 +4004,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, tmp = decrypted_reponse; if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, (int)challenge_response_len)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -4010,7 +4012,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, tmp += tmplen; if(!EVP_DecryptFinal(ctx, tmp, &N)) { - piv_log_openssl(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -4081,6 +4083,7 @@ static int piv_general_external_authenticate(sc_card_t *card, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { + sc_log_openssl(card->ctx); r = SC_ERROR_OUT_OF_MEMORY; goto err; } @@ -4089,6 +4092,7 @@ static int piv_general_external_authenticate(sc_card_t *card, cipher = get_cipher_for_algo(card, alg_id); if(!cipher) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; goto err; @@ -4149,8 +4153,8 @@ static int piv_general_external_authenticate(sc_card_t *card, /* Encrypt the challenge with the secret */ if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt fail\n"); - piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -4164,16 +4168,16 @@ static int piv_general_external_authenticate(sc_card_t *card, EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_EncryptUpdate(ctx, cipher_text, &outlen, challenge_data, (int)challenge_len)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n"); - piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } cipher_text_len += outlen; if (!EVP_EncryptFinal(ctx, cipher_text + cipher_text_len, &outlen)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Final fail\n"); - piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -4184,8 +4188,8 @@ static int piv_general_external_authenticate(sc_card_t *card, * encrypted length */ if (cipher_text_len != tmplen) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Length test fail\n"); - piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } From c32e6eeb4a4543bef4ec303eccb2c704e2513f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 10:01:47 +0200 Subject: [PATCH 3377/4321] card-authentic: Remove unneeded openssl headers --- src/libopensc/card-authentic.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 7ad115e5ff..bb8642c3a5 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -38,13 +38,6 @@ /* #include "hash-strings.h" */ #include "authentic.h" -#include -#include -#include -#include -#include -#include -#include #include #define AUTHENTIC_CARD_DEFAULT_FLAGS ( 0 \ From 740e3c312f59b8c33bf873ec7baa814f6e0b6da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 10:22:29 +0200 Subject: [PATCH 3378/4321] card-coolkey: Remove unneeded openssl headers --- src/libopensc/card-coolkey.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 0b8019e18f..7f1c1024da 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -42,15 +42,6 @@ #include -#ifdef ENABLE_OPENSSL - /* openssl only needed for card administration */ -#include -#include -#include -#include -#include -#endif /* ENABLE_OPENSSL */ - #include "internal.h" #include "asn1.h" #include "cardctl.h" From 6bf605acd8cc90741a63f808688200abb6e5f9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 11:12:55 +0200 Subject: [PATCH 3379/4321] cwa-dnie, cwa14980: Update OpenSSL error logging --- src/libopensc/cwa-dnie.c | 12 +++ src/libopensc/cwa14890.c | 193 ++++++++++++++++++++++----------------- 2 files changed, 119 insertions(+), 86 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 16bdf30997..47f3792dad 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -591,6 +591,7 @@ static int dnie_read_certificate(sc_card_t * card, char *certpath, X509 ** cert) buffer2 = buffer; *cert = d2i_X509(NULL, (const unsigned char **)&buffer2, bufferlen); if (*cert == NULL) { /* received data is not a certificate */ + sc_log_openssl(card->ctx); res = SC_ERROR_OBJECT_NOT_VALID; msg = "Read data is not a certificate"; goto read_cert_end; @@ -649,6 +650,7 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce if (issuer) { buf = X509_NAME_oneline(issuer, buf, 0); if (!buf) { + sc_log_openssl(card->ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } sc_log(card->ctx, "icc_intermediate_ca_cert issuer %s", buf); @@ -699,6 +701,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL); if (!ctx) { #endif + sc_log_openssl(card->ctx); sc_log(card->ctx, "Cannot create data for root CA public key"); return SC_ERROR_OUT_OF_MEMORY; } @@ -723,6 +726,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) { + sc_log_openssl(card->ctx); BN_free(root_ca_rsa_n); BN_free(root_ca_rsa_e); EVP_PKEY_free(*root_ca_key); @@ -732,12 +736,14 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) } res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa); if (!res) { + sc_log_openssl(card->ctx); RSA_free(root_ca_rsa); #else if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, root_ca_rsa_n) != 1 || OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, root_ca_rsa_e) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(card->ctx); OSSL_PARAM_BLD_free(bld); OSSL_PARAM_free(params); EVP_PKEY_CTX_free(ctx); @@ -748,6 +754,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) if (EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, root_ca_key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + sc_log_openssl(card->ctx); EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); #endif @@ -899,6 +906,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, if (!ctx) { #endif + sc_log_openssl(card->ctx); sc_log(card->ctx, "Cannot create data for IFD private key"); return SC_ERROR_OUT_OF_MEMORY; } @@ -910,6 +918,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) { + sc_log_openssl(card->ctx); BN_free(ifd_rsa_n); BN_free(ifd_rsa_e); BN_free(ifd_rsa_d); @@ -922,12 +931,14 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa); if (!res) { RSA_free(ifd_rsa); + sc_log_openssl(card->ctx); #else if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, ifd_rsa_n) != 1 || OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, ifd_rsa_e) != 1 || OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, ifd_rsa_d) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(card->ctx); OSSL_PARAM_BLD_free(bld); OSSL_PARAM_free(params); EVP_PKEY_CTX_free(ctx); @@ -941,6 +952,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, if (EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, ifd_privkey, EVP_PKEY_KEYPAIR, params) != 1) { + sc_log_openssl(card->ctx); EVP_PKEY_CTX_free(ctx); #endif BN_free(ifd_rsa_n); diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index e828847e9c..e54c99334b 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -358,17 +358,24 @@ static int cwa_verify_icc_certificates(sc_card_t * card, /* verify sub_ca_cert against root_ca_key */ res = X509_verify(sub_ca_cert, root_ca_key); if (!res) { + sc_log_openssl(ctx); msg = "Cannot verify icc Sub-CA certificate"; res = SC_ERROR_SM_AUTHENTICATION_FAILED; goto verify_icc_certificates_end; } /* extract sub_ca_key from sub_ca_cert */ - sub_ca_key = X509_get_pubkey(sub_ca_cert); + if (!(sub_ca_key = X509_get_pubkey(sub_ca_cert))) { + sc_log_openssl(ctx); + msg = "Cannot extract public key icc Sub-CA certificate"; + res = SC_ERROR_INTERNAL; + goto verify_icc_certificates_end; + } /* verify icc_cert against sub_ca_key */ res = X509_verify(icc_cert, sub_ca_key); if (!res) { + sc_log_openssl(ctx); msg = "Cannot verify icc certificate"; res = SC_ERROR_SM_AUTHENTICATION_FAILED; goto verify_icc_certificates_end; @@ -381,8 +388,9 @@ static int cwa_verify_icc_certificates(sc_card_t * card, EVP_PKEY_free(root_ca_key); if (sub_ca_key) EVP_PKEY_free(sub_ca_key); - if (res != SC_SUCCESS) + if (res != SC_SUCCESS) { sc_log(ctx, "%s", msg); + } LOG_FUNC_RETURN(ctx, res); } @@ -599,6 +607,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, buf3[0] = 0x6A; /* iso padding */ if (RAND_bytes(buf3 + 1, 74) != 1 || /* pRND */ RAND_bytes(sm->ifd.k, 32) != 1) { /* Kifd */ + sc_log_openssl(ctx); msg = "prepare external auth: random data error"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; @@ -617,9 +626,10 @@ static int cwa_prepare_external_auth(sc_card_t * card, /* decrypt with ifd private key */ pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL); if (!pctx || - EVP_PKEY_decrypt_init(pctx) != 1 || - EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_decrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || EVP_PKEY_decrypt(pctx, buf2, &len2, buf3, 128) != 1) { + sc_log_openssl(ctx); msg = "Prepare external auth: ifd_privk decrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; EVP_PKEY_CTX_free(pctx); @@ -632,6 +642,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, bn = BN_bin2bn(buf2, (int)len2, NULL); bnsub = BN_new(); if (!bn || !bnsub) { + sc_log_openssl(ctx); msg = "Prepare external auth: BN creation failed"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; @@ -640,6 +651,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, NULL, NULL); #else if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1) { + sc_log_openssl(ctx); msg = "Prepare external auth: BN get param failed"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; @@ -648,18 +660,21 @@ static int cwa_prepare_external_auth(sc_card_t * card, res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */ if (res == 0) { /* 1:success 0 fail */ + sc_log_openssl(ctx); msg = "Prepare external auth: BN sigmin evaluation failed"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; } bnres = (BN_cmp(bn, bnsub) < 0) ? bn : bnsub; /* choose min(SIG,N.IFD-SIG) */ if (BN_num_bytes(bnres) > 128) { + sc_log_openssl(ctx); msg = "Prepare external auth: BN sigmin result is too big"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; } len3 = BN_bn2bin(bnres, buf3); /* convert result back into buf3 */ if (len3 <= 0) { + sc_log_openssl(ctx); msg = "Prepare external auth: BN to buffer conversion failed"; res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; @@ -668,10 +683,11 @@ static int cwa_prepare_external_auth(sc_card_t * card, /* re-encrypt result with icc public key */ pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL); if (!pctx || - EVP_PKEY_encrypt_init(pctx) != 1 || - EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || - EVP_PKEY_encrypt(pctx, buf1, &len1, buf3, 128) != 1 || - (size_t) len1 != sig_len) { + EVP_PKEY_encrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_encrypt(pctx, buf1, &len1, buf3, 128) != 1 || + (size_t)len1 != sig_len) { + sc_log_openssl(ctx); msg = "Prepare external auth: icc_pubk encrypt failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; EVP_PKEY_CTX_free(pctx); @@ -684,10 +700,8 @@ static int cwa_prepare_external_auth(sc_card_t * card, res = SC_SUCCESS; prepare_external_auth_end: - if (bn) - BN_free(bn); - if (bnsub) - BN_free(bnsub); + BN_free(bn); + BN_free(bnsub); if (buf1) { sc_mem_clear(buf1, 128); free(buf1); @@ -704,17 +718,14 @@ static int cwa_prepare_external_auth(sc_card_t * card, sc_mem_clear(sha_buf, 74 + 32 + 8 + 1 + 7); free(sha_buf); } - if (sha_data) { - free(sha_data); - } + free(sha_data); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (ifd_privkey_n) { - BN_clear_free(ifd_privkey_n); - } + BN_clear_free(ifd_privkey_n); #endif - if (res != SC_SUCCESS) + if (res != SC_SUCCESS) { sc_log(ctx, "%s", msg); + } LOG_FUNC_RETURN(ctx, res); } @@ -823,9 +834,7 @@ static int cwa_compute_session_keys(sc_card_t * card) sc_mem_clear(data, 32 + 4); free(data); } - if (sha_data) { - free(sha_data); - } + free(sha_data); if (res != SC_SUCCESS) sc_log(ctx, "%s", msg); else { @@ -866,10 +875,8 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data) if (memcmp(data + 127 - SHA_DIGEST_LENGTH, sha, SHA_DIGEST_LENGTH) == 0) res = SC_SUCCESS; compare_signature_end: - if (buf) - free(buf); - if (sha) - free(sha); + free(buf); + free(sha); return res; } @@ -960,9 +967,10 @@ static int cwa_verify_internal_auth(sc_card_t * card, /* decrypt data with our ifd priv key */ pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL); if (!pctx || - EVP_PKEY_decrypt_init(pctx) != 1 || - EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || - EVP_PKEY_decrypt(pctx, buf1, &len1, sig, sig_len) != 1) { + EVP_PKEY_decrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_decrypt(pctx, buf1, &len1, sig, sig_len) != 1) { + sc_log_openssl(ctx); msg = "Verify Signature: decrypt with ifd privk failed"; res = SC_ERROR_SM_ENCRYPT_FAILED; EVP_PKEY_CTX_free(pctx); @@ -976,10 +984,11 @@ static int cwa_verify_internal_auth(sc_card_t * card, /* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */ pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL); if (!pctx || - EVP_PKEY_encrypt_init(pctx) != 1 || - EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || - EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1) != 1) { + EVP_PKEY_encrypt_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || + EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1) != 1) { EVP_PKEY_CTX_free(pctx); + sc_log_openssl(ctx); goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */ } @@ -997,6 +1006,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, bn = BN_bin2bn(buf1, (int)len1, NULL); /* create BN data */ sigbn = BN_new(); if (!bn || !sigbn) { + sc_log_openssl(ctx); msg = "Verify Signature: cannot bignums creation error"; res = SC_ERROR_OUT_OF_MEMORY; goto verify_internal_done; @@ -1005,6 +1015,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, NULL, NULL); #else if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1) { + sc_log_openssl(ctx); msg = "Verify Signature: BN get param failed"; res = SC_ERROR_INTERNAL; goto verify_internal_done; @@ -1012,12 +1023,14 @@ static int cwa_verify_internal_auth(sc_card_t * card, #endif res = BN_sub(sigbn, icc_pubkey_n, bn); /* eval N.ICC-SIG */ if (!res) { + sc_log_openssl(ctx); msg = "Verify Signature: evaluation of N.ICC-SIG failed"; res = SC_ERROR_INTERNAL; goto verify_internal_done; } len2 = BN_bn2bin(sigbn, buf2); /* copy result to buffer */ if (len2 <= 0) { + sc_log_openssl(ctx); msg = "Verify Signature: cannot convert bignum to buffer"; res = SC_ERROR_INTERNAL; goto verify_internal_done; @@ -1029,6 +1042,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, EVP_PKEY_encrypt_init(pctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 || EVP_PKEY_encrypt(pctx, buf3, &len3, buf2, len2) != 1) { + sc_log_openssl(ctx); msg = "Verify Signature: cannot get valid SIG data"; res = SC_ERROR_INVALID_DATA; EVP_PKEY_CTX_free(pctx); @@ -1048,22 +1062,17 @@ static int cwa_verify_internal_auth(sc_card_t * card, memcpy(sm->icc.k, buf3 + 1 + 74, 32); /* extract Kicc from buf3 */ res = SC_SUCCESS; verify_internal_done: - if (buf1) - free(buf1); - if (buf2) - free(buf2); - if (buf3) - free(buf3); - if (bn) - BN_free(bn); - if (sigbn) - BN_free(sigbn); + free(buf1); + free(buf2); + free(buf3); + BN_free(bn); + BN_free(sigbn); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (icc_pubkey_n) - BN_clear_free(icc_pubkey_n); + BN_clear_free(icc_pubkey_n); #endif - if (res != SC_SUCCESS) + if (res != SC_SUCCESS) { sc_log(ctx, "%s", msg); + } LOG_FUNC_RETURN(ctx, res); } @@ -1212,7 +1221,12 @@ int cwa_create_secure_channel(sc_card_t * card, } /* Extract public key from ICC certificate */ - icc_pubkey = X509_get_pubkey(icc_cert); + if (!(icc_pubkey = X509_get_pubkey(icc_cert))) { + res = SC_ERROR_INTERNAL; + sc_log_openssl(ctx); + msg = "Cannot extract public key from ICC certificate"; + goto csc_end; + } /* Select Root CA in card for ifd certificate verification */ sc_log(ctx, @@ -1427,14 +1441,10 @@ int cwa_create_secure_channel(sc_card_t * card, res = SC_SUCCESS; csc_end: free(tlv); - if (icc_cert) - X509_free(icc_cert); - if (ca_cert) - X509_free(ca_cert); - if (icc_pubkey) - EVP_PKEY_free(icc_pubkey); - if (ifd_privkey) - EVP_PKEY_free(ifd_privkey); + X509_free(icc_cert); + X509_free(ca_cert); + EVP_PKEY_free(icc_pubkey); + EVP_PKEY_free(ifd_privkey); /* setup SM state according result */ if (res != SC_SUCCESS) { sc_log(ctx, "%s", msg); @@ -1572,10 +1582,11 @@ int cwa_encode_apdu(sc_card_t * card, alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); - if (EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || - EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || - EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { + if (!alg || + EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || + EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { msg = "Error in encrypting APDU"; res = SC_ERROR_INTERNAL; goto encode_end; @@ -1627,12 +1638,13 @@ int cwa_encode_apdu(sc_card_t * card, sc_evp_cipher_free(alg); alg = sc_evp_cipher(card->ctx, "DES-ECB"); - if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + if (!alg || + EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; goto encode_end; - } + } for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */ /* compute DES */ @@ -1655,10 +1667,11 @@ int cwa_encode_apdu(sc_card_t * card, sc_evp_cipher_free(alg); alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); - if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || - EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || - EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + if (!alg || + EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { msg = "Error in 3DEC ECB encryption"; res = SC_ERROR_INTERNAL; goto encode_end; @@ -1684,16 +1697,16 @@ int cwa_encode_apdu(sc_card_t * card, err: encode_end: - if (apdubuf) - free(apdubuf); + free(apdubuf); if (from->resp != to->resp) free(to->resp); encode_end_apdu_valid: sc_evp_cipher_free(alg); - if (cctx) - EVP_CIPHER_CTX_free(cctx); - if (msg) + EVP_CIPHER_CTX_free(cctx); + if (msg) { + sc_log_openssl(ctx); sc_log(ctx, "%s", msg); + } free(msgbuf); free(cryptbuf); free(ccbuf); @@ -1739,8 +1752,10 @@ int cwa_decode_response(sc_card_t * card, unsigned char *key = NULL; int tmplen = 0; - if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + sc_log_openssl(ctx); return SC_ERROR_INTERNAL; + } /* mandatory check */ if (!card || !card->ctx || !provider) @@ -1865,17 +1880,20 @@ int cwa_decode_response(sc_card_t * card, key = sm_session->session_mac; alg = sc_evp_cipher(card->ctx, "DES-ECB"); - if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + if (!alg || + EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + sc_log_openssl(ctx); msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; goto response_decode_end; - } + } memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */ for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */ /* compute DES */ if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) { + sc_log_openssl(ctx); msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; goto response_decode_end; @@ -1885,6 +1903,7 @@ int cwa_decode_response(sc_card_t * card, macbuf[j] ^= ccbuf[i + j]; } if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + sc_log_openssl(ctx); msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; goto response_decode_end; @@ -1894,10 +1913,12 @@ int cwa_decode_response(sc_card_t * card, sc_evp_cipher_free(alg); alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); - if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || - EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || - EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + if (!alg || + EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { + sc_log_openssl(ctx); msg = "Error in 3DEC ECB encryption"; res = SC_ERROR_INTERNAL; goto response_decode_end; @@ -1953,10 +1974,12 @@ int cwa_decode_response(sc_card_t * card, sc_evp_cipher_free(alg); alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); - if (EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 || - EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || - EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], (int)(e_tlv->len - 1)) != 1 || - EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) { + if (!alg || + EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], (int)(e_tlv->len - 1)) != 1 || + EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) { + sc_log_openssl(ctx); res = SC_ERROR_INTERNAL; msg = "Can not decrypt 3DES CBC"; goto response_decode_end; @@ -1984,10 +2007,8 @@ int cwa_decode_response(sc_card_t * card, response_decode_end: sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(cctx); - if (buffer) - free(buffer); - if (ccbuf) - free(ccbuf); + free(buffer); + free(ccbuf); if (msg) { sc_log(ctx, "%s", msg); } else { From 602e19ed52d0ba93f91e3b503086b06becbba612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 11:37:08 +0200 Subject: [PATCH 3380/4321] card-entersafe: Update OpenSSL error logging --- src/libopensc/card-entersafe.c | 88 +++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index b0da8dee7e..e186d14c49 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -198,7 +198,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *key, size_t keylen, u8 *buff, size_t buffsize) { - EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER_CTX * ctx = NULL; EVP_CIPHER *alg = NULL; u8 iv[8]={0}; @@ -218,29 +218,38 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, buff[apdu->lc+1]=0x80; ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) + if (ctx == NULL) { + sc_log_openssl(card->ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } EVP_CIPHER_CTX_set_padding(ctx,0); if (keylen == 8) { alg = sc_evp_cipher(card->ctx, "DES-ECB"); - EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); } else if (keylen == 16) { alg = sc_evp_cipher(card->ctx, "DES-EDE"); - EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); } else { EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - len = (int)apdu->lc; - if(!EVP_EncryptUpdate(ctx, buff, &len, buff, (int)buffsize)){ + if (EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) { + sc_log_openssl(card->ctx); sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(ctx); - sc_log(card->ctx, "entersafe encryption error."); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - } - apdu->lc = len; + sc_log(card->ctx, "entersafe encryption error."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + len = (int)apdu->lc; + if (!EVP_EncryptUpdate(ctx, buff, &len, buff, (int)buffsize)) { + sc_log_openssl(card->ctx); + sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(ctx); + sc_log(card->ctx, "entersafe encryption error."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + apdu->lc = len; sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(ctx); @@ -304,15 +313,44 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, tmp_rounded[4]+=4; tmp_rounded[tmpsize]=0x80; - /* block_size-1 blocks*/ - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; + /* block_size-1 blocks*/ + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + sc_log_openssl(card->ctx); goto out; - } - EVP_CIPHER_CTX_set_padding(ctx,0); + } + EVP_CIPHER_CTX_set_padding(ctx, 0); alg = sc_evp_cipher(card->ctx, "DES-CBC"); - EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); + if (!alg || + EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) { + r = SC_ERROR_INTERNAL; + sc_log_openssl(card->ctx); + goto out; + } + + if (tmpsize_rounded > 8) { + if (!EVP_EncryptUpdate(ctx, tmp_rounded, &outl, tmp_rounded, (int)tmpsize_rounded - 8)) { + r = SC_ERROR_INTERNAL; + sc_log_openssl(card->ctx); + goto out; + } + } + /* last block */ + if (keylen == 8) { + if (!EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) { + r = SC_ERROR_INTERNAL; + sc_log_openssl(card->ctx); + goto out; + } + } else { + if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) || + !EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) { + r = SC_ERROR_INTERNAL; + sc_log_openssl(card->ctx); + goto out; + } + } if(tmpsize_rounded>8){ if (!EVP_EncryptUpdate(ctx, tmp_rounded, &outl, tmp_rounded, (int)tmpsize_rounded - 8)) { @@ -330,8 +368,8 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, } else { - EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8); - if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) != 1 || + !EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ r = SC_ERROR_INTERNAL; goto out; } @@ -345,14 +383,10 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, apdu->datalen=apdu->lc; out: - if(tmp) - free(tmp); - if(tmp_rounded) - free(tmp_rounded); - if (ctx) { - sc_evp_cipher_free(alg); - EVP_CIPHER_CTX_free(ctx); - } + free(tmp); + free(tmp_rounded); + sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } From df5f9e28318c5d4ed0d5725bda988fd65bfeabbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 14:16:37 +0200 Subject: [PATCH 3381/4321] card-entersafe: Reformat code --- src/libopensc/card-entersafe.c | 1818 +++++++++++++++----------------- 1 file changed, 862 insertions(+), 956 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index e186d14c49..2fdc6c39bf 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -32,14 +32,14 @@ static const struct sc_atr_table entersafe_atrs[] = { { - "3b:0f:00:65:46:53:05:19:05:71:df:00:00:00:00:00:00", - "ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:00:00:00:00:00:00", - "ePass3000", SC_CARD_TYPE_ENTERSAFE_3K, 0, NULL }, + "3b:0f:00:65:46:53:05:19:05:71:df:00:00:00:00:00:00", + "ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:00:00:00:00:00:00", + "ePass3000", SC_CARD_TYPE_ENTERSAFE_3K, 0, NULL }, + { + "3b:9f:95:81:31:fe:9f:00:65:46:53:05:30:06:71:df:00:00:00:80:6a:82:5e", + "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:00", + "FTCOS/PK-01C", SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, 0, NULL }, { - "3b:9f:95:81:31:fe:9f:00:65:46:53:05:30:06:71:df:00:00:00:80:6a:82:5e", - "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:00", - "FTCOS/PK-01C", SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, 0, NULL }, - { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:18:14:00:00:00:00:02", "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00", "EJAVA/PK-01C", SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C, 0, NULL }, @@ -86,45 +86,44 @@ static struct sc_card_driver entersafe_drv = { static u8 trans_code_3k[] = { - 0x01,0x02,0x03,0x04, - 0x05,0x06,0x07,0x08, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, }; static u8 trans_code_ftcos_pk_01c[] = { - 0x92,0x34,0x2E,0xEF, - 0x23,0x40,0x4F,0xD1, + 0x92, 0x34, 0x2E, 0xEF, + 0x23, 0x40, 0x4F, 0xD1, }; static u8 init_key[] = { - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 10, 11, 12, - 13, 14, 15, 16, + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, }; static u8 key_maintain[] = { - 0x12, 0x34, 0x56, 0x78, - 0x21, 0x43, 0x65, 0x87, - 0x11, 0x22, 0xaa, 0xbb, - 0x33, 0x44, 0xcd, 0xef + 0x12, 0x34, 0x56, 0x78, + 0x21, 0x43, 0x65, 0x87, + 0x11, 0x22, 0xaa, 0xbb, + 0x33, 0x44, 0xcd, 0xef }; -static void entersafe_reverse_buffer(u8* buff,size_t size) +static void entersafe_reverse_buffer(u8* buff, size_t size) { - u8 t; - u8 * end=buff+size-1; - - while(buffcla = 0x00; card->drv_data = NULL; - flags =SC_ALGORITHM_ONBOARD_KEY_GEN - | SC_ALGORITHM_RSA_RAW - | SC_ALGORITHM_RSA_HASH_NONE; + flags = SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE; _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); - _sc_card_add_rsa_alg(card,2048, flags, 0); + _sc_card_add_rsa_alg(card, 1024, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); card->caps = SC_CARD_CAP_RNG; /* we need read_binary&friends with max 224 bytes per read */ card->max_send_size = 224; card->max_recv_size = 224; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } -static int entersafe_gen_random(sc_card_t *card,u8 *buff,size_t size) +static int entersafe_gen_random(sc_card_t *card, u8 *buff, size_t size) { - int r=SC_SUCCESS; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]={0}; - sc_apdu_t apdu; + int r = SC_SUCCESS; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; + sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_format_apdu(card,&apdu,SC_APDU_CASE_2_SHORT,0x84,0x00,0x00); - apdu.resp=rbuf; - apdu.le=size; - apdu.resplen=sizeof(rbuf); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00); + apdu.resp = rbuf; + apdu.le = size; + apdu.resplen = sizeof(rbuf); - r=sc_transmit_apdu(card,&apdu); - LOG_TEST_RET(card->ctx, r, "entersafe gen random failed"); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "entersafe gen random failed"); - if(apdu.resplen!=size) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - memcpy(buff,rbuf,size); + if (apdu.resplen != size) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + memcpy(buff, rbuf, size); - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(card->ctx, r); } static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *key, size_t keylen, u8 *buff, size_t buffsize) { - EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *alg = NULL; - u8 iv[8]={0}; - int len; + u8 iv[8] = {0}; + int len; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card); - assert(apdu); - assert(key); - assert(buff); + assert(card); + assert(apdu); + assert(key); + assert(buff); - /* padding as 0x80 0x00 0x00...... */ - memset(buff,0,buffsize); - buff[0]=apdu->lc; - memcpy(buff+1,apdu->data,apdu->lc); - buff[apdu->lc+1]=0x80; + /* padding as 0x80 0x00 0x00...... */ + memset(buff, 0, buffsize); + buff[0] = apdu->lc; + memcpy(buff + 1, apdu->data, apdu->lc); + buff[apdu->lc + 1] = 0x80; - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { - sc_log_openssl(card->ctx); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - EVP_CIPHER_CTX_set_padding(ctx,0); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + sc_log_openssl(card->ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + EVP_CIPHER_CTX_set_padding(ctx, 0); if (keylen == 8) { - alg = sc_evp_cipher(card->ctx, "DES-ECB"); + alg = sc_evp_cipher(card->ctx, "DES-ECB"); } else if (keylen == 16) { - alg = sc_evp_cipher(card->ctx, "DES-EDE"); + alg = sc_evp_cipher(card->ctx, "DES-EDE"); } else { EVP_CIPHER_CTX_free(ctx); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if (EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) { @@ -252,66 +249,64 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, apdu->lc = len; sc_evp_cipher_free(alg); - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(ctx); - if(apdu->lc!=buffsize) - { - sc_log(card->ctx, "entersafe build cipher apdu failed."); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); - } + if (apdu->lc != buffsize) { + sc_log(card->ctx, "entersafe build cipher apdu failed."); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); + } - apdu->data=buff; - apdu->datalen=apdu->lc; + apdu->data = buff; + apdu->datalen = apdu->lc; - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 * key,size_t keylen, u8 * buff,size_t buffsize) { - int r; - u8 iv[8]; - u8 *tmp=0,*tmp_rounded=NULL; - size_t tmpsize=0,tmpsize_rounded=0; - int outl=0; - EVP_CIPHER_CTX * ctx = NULL; + int r; + u8 iv[8]; + u8 *tmp = NULL, *tmp_rounded = NULL; + size_t tmpsize = 0, tmpsize_rounded = 0; + int outl = 0; + EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *alg = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card); - assert(apdu); - assert(key); - assert(buff); + assert(card); + assert(apdu); + assert(key); + assert(buff); - if(apdu->cse != SC_APDU_CASE_3_SHORT) - return SC_ERROR_INTERNAL; - if(keylen!=8 && keylen!=16) - return SC_ERROR_INTERNAL; + if (apdu->cse != SC_APDU_CASE_3_SHORT) + return SC_ERROR_INTERNAL; + if (keylen != 8 && keylen != 16) + return SC_ERROR_INTERNAL; - r=entersafe_gen_random(card,iv,sizeof(iv)); - LOG_TEST_RET(card->ctx,r,"entersafe gen random failed"); + r = entersafe_gen_random(card, iv, sizeof(iv)); + LOG_TEST_RET(card->ctx, r, "entersafe gen random failed"); - /* encode the APDU in the buffer */ - if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS) - goto out; + /* encode the APDU in the buffer */ + if ((r = sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize, SC_PROTO_RAW)) != SC_SUCCESS) + goto out; - /* round to 8 */ - tmpsize_rounded=(tmpsize/8+1)*8; + /* round to 8 */ + tmpsize_rounded = (tmpsize / 8 + 1) * 8; - tmp_rounded = malloc(tmpsize_rounded); - if (tmp_rounded == NULL) - { - r = SC_ERROR_OUT_OF_MEMORY; - goto out; - } + tmp_rounded = malloc(tmpsize_rounded); + if (tmp_rounded == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } - /*build content and padded buffer by 0x80 0x00 0x00..... */ - memset(tmp_rounded,0,tmpsize_rounded); - memcpy(tmp_rounded,tmp,tmpsize); - tmp_rounded[4]+=4; - tmp_rounded[tmpsize]=0x80; + /* build content and padded buffer by 0x80 0x00 0x00..... */ + memset(tmp_rounded, 0, tmpsize_rounded); + memcpy(tmp_rounded, tmp, tmpsize); + tmp_rounded[4] += 4; + tmp_rounded[tmpsize] = 0x80; /* block_size-1 blocks*/ ctx = EVP_CIPHER_CTX_new(); @@ -323,7 +318,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, EVP_CIPHER_CTX_set_padding(ctx, 0); alg = sc_evp_cipher(card->ctx, "DES-CBC"); if (!alg || - EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) { + EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) { r = SC_ERROR_INTERNAL; sc_log_openssl(card->ctx); goto out; @@ -344,43 +339,20 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, goto out; } } else { - if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) || - !EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) { + if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) != 1 || + !EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) { r = SC_ERROR_INTERNAL; sc_log_openssl(card->ctx); goto out; } } - if(tmpsize_rounded>8){ - if (!EVP_EncryptUpdate(ctx, tmp_rounded, &outl, tmp_rounded, (int)tmpsize_rounded - 8)) { - r = SC_ERROR_INTERNAL; - goto out; - } - } - /* last block */ - if(keylen==8) - { - if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ - r = SC_ERROR_INTERNAL; - goto out; - } - } - else - { - if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) != 1 || - !EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ - r = SC_ERROR_INTERNAL; - goto out; - } - } - - memcpy(buff,apdu->data,apdu->lc); - /* use first 4 bytes of last block as mac value*/ - memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4); - apdu->data=buff; - apdu->lc+=4; - apdu->datalen=apdu->lc; + memcpy(buff, apdu->data, apdu->lc); + /* use first 4 bytes of last block as mac value*/ + memcpy(buff + apdu->lc, tmp_rounded + tmpsize_rounded - 8, 4); + apdu->data = buff; + apdu->lc += 4; + apdu->datalen = apdu->lc; out: free(tmp); @@ -388,70 +360,64 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 * key, size_t keylen, - int cipher,int mac) + int cipher, int mac) { - u8 *cipher_data=0,*mac_data=0; - size_t cipher_data_size, mac_data_size, blocks; - int r=SC_SUCCESS; - u8 *sbuf=NULL; - size_t ssize=0; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - assert(card); - assert(apdu); - - if((cipher||mac) && (!key||(keylen!=8 && keylen!=16))) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - - r = sc_apdu_get_octets(card->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); - if (r == SC_SUCCESS) - sc_apdu_log(card->ctx, sbuf, ssize, 1); - if(sbuf) - free(sbuf); - - if(cipher) - { - blocks=(apdu->lc+2)/8+1; - cipher_data_size=blocks*8; - cipher_data=malloc(cipher_data_size); - if(!cipher_data) - { - r = SC_ERROR_OUT_OF_MEMORY; - goto out; - } - - if((r = entersafe_cipher_apdu(card,apdu,key,keylen,cipher_data,cipher_data_size))<0) - goto out; - } - if(mac) - { - mac_data_size=apdu->lc+4; - mac_data=malloc(mac_data_size); - if(!mac_data) - { - r = SC_ERROR_OUT_OF_MEMORY; - goto out; - } - r = entersafe_mac_apdu(card,apdu,key,keylen,mac_data,mac_data_size); - if(r < 0) - goto out; - } - - r = sc_transmit_apdu(card,apdu); + u8 *cipher_data = NULL, *mac_data = NULL; + size_t cipher_data_size, mac_data_size, blocks; + int r = SC_SUCCESS; + u8 *sbuf = NULL; + size_t ssize = 0; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + assert(card); + assert(apdu); + + if ((cipher || mac) && (!key || (keylen != 8 && keylen != 16))) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + + r = sc_apdu_get_octets(card->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); + if (r == SC_SUCCESS) + sc_apdu_log(card->ctx, sbuf, ssize, 1); + if (sbuf) + free(sbuf); + + if (cipher) { + blocks = (apdu->lc + 2) / 8 + 1; + cipher_data_size = blocks * 8; + cipher_data = malloc(cipher_data_size); + if (!cipher_data) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + + if ((r = entersafe_cipher_apdu(card, apdu, key, keylen, cipher_data, cipher_data_size)) < 0) + goto out; + } + if (mac) { + mac_data_size = apdu->lc + 4; + mac_data = malloc(mac_data_size); + if (!mac_data) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + r = entersafe_mac_apdu(card, apdu, key, keylen, mac_data, mac_data_size); + if (r < 0) + goto out; + } + + r = sc_transmit_apdu(card, apdu); out: - if(cipher_data) - free(cipher_data); - if(mac_data) - free(mac_data); + free(cipher_data); + free(mac_data); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_read_binary(sc_card_t *card, @@ -465,15 +431,14 @@ static int entersafe_read_binary(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); assert(count <= card->max_recv_size); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, - (idx >> 8) & 0xFF, idx & 0xFF); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (idx >> 8) & 0xFF, idx & 0xFF); - apdu.cla=idx > 0x7fff ? 0x80:0x00; + apdu.cla = idx > 0x7fff ? 0x80 : 0x00; apdu.le = count; apdu.resplen = count; apdu.resp = recvbuf; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.resplen == 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); @@ -493,44 +458,39 @@ static int entersafe_update_binary(sc_card_t *card, assert(count <= card->max_send_size); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, - (idx >> 8) & 0xFF, idx & 0xFF); - apdu.cla=idx > 0x7fff ? 0x80:0x00; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0xFF, idx & 0xFF); + apdu.cla = idx > 0x7fff ? 0x80 : 0x00; apdu.lc = count; apdu.datalen = count; apdu.data = buf; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Card returned error"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)count); } - static int entersafe_process_fci(struct sc_card *card, struct sc_file *file, - const u8 *buf, size_t buflen) + const u8 *buf, size_t buflen) { - int r; - - assert(file); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - r = iso_ops->process_fci(card,file,buf,buflen); - LOG_TEST_RET(card->ctx, r, "Process fci failed"); - - if(file->namelen) - { - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - } - else - { - file->type = SC_FILE_TYPE_WORKING_EF; - file->ef_structure = SC_FILE_EF_TRANSPARENT; - } - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + int r; + + assert(file); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = iso_ops->process_fci(card, file, buf, buflen); + LOG_TEST_RET(card->ctx, r, "Process fci failed"); + + if (file->namelen) { + file->type = SC_FILE_TYPE_DF; + file->ef_structure = SC_FILE_EF_UNKNOWN; + } else { + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + } + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_select_fid(sc_card_t *card, @@ -543,28 +503,28 @@ static int entersafe_select_fid(sc_card_t *card, memset(&path, 0, sizeof(sc_path_t)); - path.type=SC_PATH_TYPE_FILE_ID; - path.value[0]=id_hi; - path.value[1]=id_lo; - path.len=2; + path.type = SC_PATH_TYPE_FILE_ID; + path.value[0] = id_hi; + path.value[1] = id_lo; + path.len = 2; - r = iso_ops->select_file(card,&path,&file); + r = iso_ops->select_file(card, &path, &file); if (r < 0) sc_file_free(file); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* update cache */ if (file->type == SC_FILE_TYPE_DF) { - card->cache.current_path.type = SC_PATH_TYPE_PATH; - card->cache.current_path.value[0] = 0x3f; - card->cache.current_path.value[1] = 0x00; - if (id_hi == 0x3f && id_lo == 0x00){ - card->cache.current_path.len = 2; - } else { - card->cache.current_path.len = 4; - card->cache.current_path.value[2] = id_hi; - card->cache.current_path.value[3] = id_lo; - } + card->cache.current_path.type = SC_PATH_TYPE_PATH; + card->cache.current_path.value[0] = 0x3f; + card->cache.current_path.value[1] = 0x00; + if (id_hi == 0x3f && id_lo == 0x00) { + card->cache.current_path.len = 2; + } else { + card->cache.current_path.len = 4; + card->cache.current_path.value[2] = id_hi; + card->cache.current_path.value[3] = id_lo; + } } if (file_out) @@ -581,40 +541,36 @@ static int entersafe_select_aid(sc_card_t *card, { int r = 0; - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME - && card->cache.current_path.len == in_path->len - && memcmp(card->cache.current_path.value, in_path->value, in_path->len)==0 ) - { - if(file_out) - { - *file_out = sc_file_new(); - if(!file_out) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - } - else - { - r = iso_ops->select_file(card,in_path,file_out); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (card->cache.valid && + card->cache.current_path.type == SC_PATH_TYPE_DF_NAME && + card->cache.current_path.len == in_path->len && + memcmp(card->cache.current_path.value, in_path->value, in_path->len) == 0) { + if (file_out) { + *file_out = sc_file_new(); + if (!file_out) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + } else { + r = iso_ops->select_file(card, in_path, file_out); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - /* update cache */ - card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; - card->cache.current_path.len = in_path->len; - memcpy(card->cache.current_path.value,in_path->value,in_path->len); + /* update cache */ + card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; + card->cache.current_path.len = in_path->len; + memcpy(card->cache.current_path.value, in_path->value, in_path->len); } if (file_out) { - sc_file_t *file = *file_out; - assert(file); - - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->path.len = 0; - file->size = 0; - /* AID */ - memcpy(file->name,in_path->value,in_path->len); - file->namelen = in_path->len; - file->id = 0x0000; + sc_file_t *file = *file_out; + assert(file); + + file->type = SC_FILE_TYPE_DF; + file->ef_structure = SC_FILE_EF_UNKNOWN; + file->path.len = 0; + file->size = 0; + /* AID */ + memcpy(file->name, in_path->value, in_path->len); + file->namelen = in_path->len; + file->id = 0x0000; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -623,142 +579,127 @@ static int entersafe_select_path(sc_card_t *card, const u8 pathbuf[16], const size_t len, sc_file_t **file_out) { - u8 n_pathbuf[SC_MAX_PATH_SIZE]; - const u8 *path=pathbuf; - size_t pathlen=len; - int bMatch = -1; - unsigned int i; - int r; - - if (pathlen%2 != 0 || pathlen > 6 || pathlen <= 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - - /* if pathlen == 6 then the first FID must be MF (== 3F00) */ - if (pathlen == 6 && ( path[0] != 0x3f || path[1] != 0x00 )) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - - /* unify path (the first FID should be MF) */ - if (path[0] != 0x3f || path[1] != 0x00) - { - n_pathbuf[0] = 0x3f; - n_pathbuf[1] = 0x00; - memcpy(n_pathbuf+2, path, pathlen); - path = n_pathbuf; - pathlen += 2; - } - - /* check current working directory */ - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_PATH - && card->cache.current_path.len >= 2 - && card->cache.current_path.len <= pathlen ) - { - bMatch = 0; - for (i=0; i < card->cache.current_path.len; i+=2) - if (card->cache.current_path.value[i] == path[i] - && card->cache.current_path.value[i+1] == path[i+1] ) - bMatch += 2; - } - - if ( card->cache.valid && bMatch > 2 ) - { - if ( pathlen - bMatch == 2 ) - { - /* we are in the right directory */ - return entersafe_select_fid(card, path[bMatch], path[bMatch+1], file_out); - } - else if ( pathlen - bMatch > 2 ) - { - /* two more steps to go */ - sc_path_t new_path; - - /* first step: change directory */ - r = entersafe_select_fid(card, path[bMatch], path[bMatch+1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - memset(&new_path, 0, sizeof(sc_path_t)); - - new_path.type = SC_PATH_TYPE_PATH; - new_path.len = pathlen - bMatch-2; - memcpy(new_path.value, &(path[bMatch+2]), new_path.len); - /* final step: select file */ - return entersafe_select_file(card, &new_path, file_out); - } - else /* if (bMatch - pathlen == 0) */ - { - /* done: we are already in the - * requested directory */ - sc_log(card->ctx, - "cache hit\n"); - /* copy file info (if necessary) */ - if (file_out) { - sc_file_t *file = sc_file_new(); - if (!file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (path[pathlen-2] << 8) + - path[pathlen-1]; - file->path = card->cache.current_path; - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->size = 0; - file->namelen = 0; - file->magic = SC_FILE_MAGIC; - *file_out = file; - } - /* nothing left to do */ - return SC_SUCCESS; - } - } - else - { - /* no usable cache */ - for ( i=0; ictx, r, "SELECT FILE (DF-ID) failed"); - } - return entersafe_select_fid(card, path[pathlen-2], path[pathlen-1], file_out); - } + u8 n_pathbuf[SC_MAX_PATH_SIZE]; + const u8 *path = pathbuf; + size_t pathlen = len; + int bMatch = -1; + unsigned int i; + int r; + + if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + + /* if pathlen == 6 then the first FID must be MF (== 3F00) */ + if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00)) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + + /* unify path (the first FID should be MF) */ + if (path[0] != 0x3f || path[1] != 0x00) { + n_pathbuf[0] = 0x3f; + n_pathbuf[1] = 0x00; + memcpy(n_pathbuf + 2, path, pathlen); + path = n_pathbuf; + pathlen += 2; + } + + /* check current working directory */ + if (card->cache.valid && + card->cache.current_path.type == SC_PATH_TYPE_PATH && + card->cache.current_path.len >= 2 && + card->cache.current_path.len <= pathlen) { + bMatch = 0; + for (i = 0; i < card->cache.current_path.len; i += 2) { + if (card->cache.current_path.value[i] == path[i] && + card->cache.current_path.value[i + 1] == path[i + 1]) { + bMatch += 2; + } + } + } + + if (card->cache.valid && bMatch > 2) { + if (pathlen - bMatch == 2) { + /* we are in the right directory */ + return entersafe_select_fid(card, path[bMatch], path[bMatch + 1], file_out); + } else if (pathlen - bMatch > 2) { + /* two more steps to go */ + sc_path_t new_path; + + /* first step: change directory */ + r = entersafe_select_fid(card, path[bMatch], path[bMatch + 1], NULL); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); + + memset(&new_path, 0, sizeof(sc_path_t)); + + new_path.type = SC_PATH_TYPE_PATH; + new_path.len = pathlen - bMatch - 2; + memcpy(new_path.value, &(path[bMatch + 2]), new_path.len); + /* final step: select file */ + return entersafe_select_file(card, &new_path, file_out); + } else { /* if (bMatch - pathlen == 0) */ + /* done: we are already in the requested directory */ + sc_log(card->ctx, "cache hit\n"); + /* copy file info (if necessary) */ + if (file_out) { + sc_file_t *file = sc_file_new(); + if (!file) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + file->id = (path[pathlen - 2] << 8) + path[pathlen - 1]; + file->path = card->cache.current_path; + file->type = SC_FILE_TYPE_DF; + file->ef_structure = SC_FILE_EF_UNKNOWN; + file->size = 0; + file->namelen = 0; + file->magic = SC_FILE_MAGIC; + *file_out = file; + } + /* nothing left to do */ + return SC_SUCCESS; + } + } else { + /* no usable cache */ + for (i = 0; i < pathlen - 2; i += 2) { + r = entersafe_select_fid(card, path[i], path[i + 1], NULL); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); + } + return entersafe_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); + } } static int entersafe_select_file(sc_card_t *card, - const sc_path_t *in_path, - sc_file_t **file_out) + const sc_path_t *in_path, + sc_file_t **file_out) { - int r; - char pbuf[SC_MAX_PATH_STRING_SIZE]; - assert(card); - assert(in_path); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, - "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? - "aid" : "path", - card->cache.valid ? "valid" : "invalid", pbuf, - card->cache.current_path.len); - - switch(in_path->type) - { - case SC_PATH_TYPE_FILE_ID: - if (in_path->len != 2) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); - return entersafe_select_fid(card,in_path->value[0],in_path->value[1], file_out); - case SC_PATH_TYPE_DF_NAME: - return entersafe_select_aid(card,in_path,file_out); - case SC_PATH_TYPE_PATH: - return entersafe_select_path(card,in_path->value,in_path->len,file_out); - default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - } + int r; + char pbuf[SC_MAX_PATH_STRING_SIZE]; + assert(card); + assert(in_path); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); + if (r != SC_SUCCESS) + pbuf[0] = '\0'; + + sc_log(card->ctx, + "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", + card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", + card->cache.valid ? "valid" : "invalid", pbuf, + card->cache.current_path.len); + + switch (in_path->type) { + case SC_PATH_TYPE_FILE_ID: + if (in_path->len != 2) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return entersafe_select_fid(card,in_path->value[0], in_path->value[1], file_out); + case SC_PATH_TYPE_DF_NAME: + return entersafe_select_aid(card, in_path, file_out); + case SC_PATH_TYPE_PATH: + return entersafe_select_path(card, in_path->value, in_path->len, file_out); + default: + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + } } -static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data) +static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data *data) { int r; sc_apdu_t apdu; @@ -767,38 +708,35 @@ static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data) memcpy(data->data.df.init_key, init_key, sizeof(init_key)); - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x00,0x00); - apdu.cla=0x84; - apdu.data=(u8*)&data->data.df; - apdu.datalen=apdu.lc=sizeof(data->data.df); - - switch(card->type) - { - case SC_CARD_TYPE_ENTERSAFE_3K: - { - r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1); - }break; - case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1: - { - r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1); - }break; - default: - { - r = SC_ERROR_INTERNAL; - }break; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); + apdu.cla = 0x84; + apdu.data = (u8 *)&data->data.df; + apdu.datalen = apdu.lc = sizeof(data->data.df); + + switch(card->type) { + case SC_CARD_TYPE_ENTERSAFE_3K: + r = entersafe_transmit_apdu(card, &apdu, trans_code_3k, sizeof(trans_code_3k), 0, 1); + break; + case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1: + r = entersafe_transmit_apdu(card, &apdu, trans_code_ftcos_pk_01c, sizeof(trans_code_ftcos_pk_01c), 0, 1); + break; + default: + r = SC_ERROR_INTERNAL; + break; } LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } -static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data * data) + +static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data *data) { int r; sc_apdu_t apdu; @@ -807,17 +745,17 @@ static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data * data) memcpy(data->data.df.init_key, init_key, sizeof(init_key)); - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x01,0x00); - apdu.cla=0x84; - apdu.data=(u8*)&data->data.df; - apdu.lc=apdu.datalen=sizeof(data->data.df); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x01, 0x00); + apdu.cla = 0x84; + apdu.data = (u8 *)&data->data.df; + apdu.lc = apdu.datalen = sizeof(data->data.df); r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } -static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data * data) +static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data *data) { int r; sc_apdu_t apdu; @@ -829,7 +767,7 @@ static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data * data) apdu.data = (u8*)&data->data.ef; apdu.lc = apdu.datalen = sizeof(data->data.ef); - r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1); + r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -838,47 +776,40 @@ static u8 process_acl_entry(sc_file_t *in, unsigned int method, unsigned int in_ { u8 def = (u8)in_def; const sc_acl_entry_t *entry = sc_file_get_acl_entry(in, method); - if (!entry) - { + if (!entry) { return def; - } - else if (entry->method & SC_AC_CHV) - { + } else if (entry->method & SC_AC_CHV) { unsigned int key_ref = entry->key_ref; if (key_ref == SC_AC_KEY_REF_NONE) return def; else return ENTERSAFE_AC_ALWAYS&0x04; - } - else if (entry->method & SC_AC_NEVER) - { + } else if (entry->method & SC_AC_NEVER) { return ENTERSAFE_AC_NEVER; } - else - { - return def; - } + return def; } static int entersafe_create_file(sc_card_t *card, sc_file_t *file) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - if (file->type == SC_FILE_TYPE_WORKING_EF) { - sc_entersafe_create_data data; - memset(&data,0,sizeof(data)); - - data.data.ef.file_id[0] = (file->id>>8)&0xFF; - data.data.ef.file_id[1] = file->id&0xFF; - data.data.ef.size[0] = (file->size>>8)&0xFF; - data.data.ef.size[1] = file->size&0xFF; - memset(data.data.ef.ac,ENTERSAFE_AC_ALWAYS,sizeof(data.data.ef.ac)); - data.data.ef.ac[0] = process_acl_entry(file,SC_AC_OP_READ,ENTERSAFE_AC_ALWAYS); - data.data.ef.ac[1] = process_acl_entry(file,SC_AC_OP_UPDATE,ENTERSAFE_AC_ALWAYS); - - return entersafe_create_ef(card, &data); - } else - return SC_ERROR_INVALID_ARGUMENTS; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (file->type == SC_FILE_TYPE_WORKING_EF) { + sc_entersafe_create_data data; + memset(&data, 0, sizeof(data)); + + data.data.ef.file_id[0] = (file->id >> 8) & 0xFF; + data.data.ef.file_id[1] = file->id & 0xFF; + data.data.ef.size[0] = (file->size >> 8) & 0xFF; + data.data.ef.size[1] = file->size & 0xFF; + memset(data.data.ef.ac, ENTERSAFE_AC_ALWAYS, sizeof(data.data.ef.ac)); + data.data.ef.ac[0] = process_acl_entry(file, SC_AC_OP_READ, ENTERSAFE_AC_ALWAYS); + data.data.ef.ac[1] = process_acl_entry(file, SC_AC_OP_UPDATE, ENTERSAFE_AC_ALWAYS); + + return entersafe_create_ef(card, &data); + } else { + return SC_ERROR_INVALID_ARGUMENTS; + } } static int entersafe_internal_set_security_env(sc_card_t *card, @@ -887,7 +818,7 @@ static int entersafe_internal_set_security_env(sc_card_t *card, { sc_apdu_t apdu; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8 *p=sbuf; + u8 *p = sbuf; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -895,37 +826,33 @@ static int entersafe_internal_set_security_env(sc_card_t *card, assert(card != NULL && env != NULL); switch (env->operation) { - case SC_SEC_OPERATION_DECIPHER: - case SC_SEC_OPERATION_SIGN: - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); - apdu.p1 = 0x41; - apdu.p2 = 0xB8; - *p++ = 0x80; - *p++ = 0x01; - *p++ = 0x80; - *p++ = 0x83; - *p++ = 0x02; - *p++ = env->key_ref[0]; - *p++ = 0x22; - if(*size>1024/8) - { - if(*size == 2048/8) - { - *p++ = 0x89; - *p++ = 0x40; - memcpy(p,*data,0x40); - p+=0x40; - *data+=0x40; - *size-=0x40; - } - else - { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - } - } - break; - default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + case SC_SEC_OPERATION_DECIPHER: + case SC_SEC_OPERATION_SIGN: + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); + apdu.p1 = 0x41; + apdu.p2 = 0xB8; + *p++ = 0x80; + *p++ = 0x01; + *p++ = 0x80; + *p++ = 0x83; + *p++ = 0x02; + *p++ = env->key_ref[0]; + *p++ = 0x22; + if (*size > 1024 / 8) { + if (*size == 2048 / 8) { + *p++ = 0x89; + *p++ = 0x40; + memcpy(p, *data, 0x40); + p += 0x40; + *data += 0x40; + *size -= 0x40; + } else { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + } + } + break; + default: + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } apdu.le = 0; @@ -947,64 +874,64 @@ static int entersafe_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { - assert(card); - assert(env); + assert(card); + assert(env); - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if(card->drv_data){ - free(card->drv_data); - card->drv_data=0; - } + if (card->drv_data) { + free(card->drv_data); + card->drv_data = 0; + } - card->drv_data = calloc(1,sizeof(*env)); - if(!card->drv_data) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY); + card->drv_data = calloc(1, sizeof(*env)); + if (!card->drv_data) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY); - memcpy(card->drv_data,env,sizeof(*env)); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); + memcpy(card->drv_data, env, sizeof(*env)); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_restore_security_env(sc_card_t *card, int se_num) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - return SC_SUCCESS; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + return SC_SUCCESS; } static int entersafe_compute_with_prkey(sc_card_t *card, - const u8 * data, size_t datalen, - u8 * out, size_t outlen) + const u8 *data, size_t datalen, + u8 *out, size_t outlen) { int r; sc_apdu_t apdu; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - u8* p=sbuf; + u8 *p = sbuf; size_t size = datalen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if(!data) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); + if (!data) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); memcpy(p,data,size); - if(!card->drv_data) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INTERNAL); + if (!card->drv_data) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); - r = entersafe_internal_set_security_env(card,card->drv_data,&p,&size); + r = entersafe_internal_set_security_env(card, card->drv_data, &p, &size); LOG_TEST_RET(card->ctx, r, "internal set security env failed"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x86,0x80); - apdu.data=p; + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x86, 0x80); + apdu.data = p; apdu.lc = size; apdu.datalen = size; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { @@ -1019,16 +946,16 @@ static int entersafe_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - return entersafe_compute_with_prkey(card,data,datalen,out,outlen); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + return entersafe_compute_with_prkey(card, data, datalen, out, outlen); } static int entersafe_decipher(sc_card_t *card, - const u8 * crgram, size_t crgram_len, - u8 * out, size_t outlen) + const u8 *crgram, size_t crgram_len, + u8 *out, size_t outlen) { - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - return entersafe_compute_with_prkey(card,crgram,crgram_len,out,outlen); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + return entersafe_compute_with_prkey(card, crgram, crgram_len, out, outlen); } static void entersafe_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num) @@ -1042,51 +969,48 @@ static void entersafe_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num } static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) + int *tries_left) { - int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - entersafe_init_pin_info(&data->pin1,0); - entersafe_init_pin_info(&data->pin2,1); - data->flags |= SC_PIN_CMD_NEED_PADDING; - - if(data->cmd!=SC_PIN_CMD_UNBLOCK) - { - r = iso_ops->pin_cmd(card,data,tries_left); - sc_log(card->ctx, "Verify rv:%i", r); - } - else - { - {/*verify*/ - sc_apdu_t apdu; - u8 sbuf[0x10]={0}; - - memcpy(sbuf,data->pin1.data,data->pin1.len); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,0x20,0x00,data->pin_reference+1); - apdu.lc = apdu.datalen = sizeof(sbuf); - apdu.data = sbuf; - - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - } - - {/*change*/ - sc_apdu_t apdu; - u8 sbuf[0x12]={0}; - - sbuf[0] = 0x33; - sbuf[1] = 0x00; - memcpy(sbuf+2,data->pin2.data,data->pin2.len); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,0xF4,0x0B,data->pin_reference); - apdu.cla = 0x84; - apdu.lc = apdu.datalen = sizeof(sbuf); - apdu.data = sbuf; - - r = entersafe_transmit_apdu(card, &apdu,key_maintain,sizeof(key_maintain),1,1); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - } - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + entersafe_init_pin_info(&data->pin1, 0); + entersafe_init_pin_info(&data->pin2, 1); + data->flags |= SC_PIN_CMD_NEED_PADDING; + + if (data->cmd != SC_PIN_CMD_UNBLOCK) { + r = iso_ops->pin_cmd(card, data, tries_left); + sc_log(card->ctx, "Verify rv:%i", r); + } else { + { /*verify*/ + sc_apdu_t apdu; + u8 sbuf[0x10] = {0}; + + memcpy(sbuf, data->pin1.data, data->pin1.len); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, data->pin_reference + 1); + apdu.lc = apdu.datalen = sizeof(sbuf); + apdu.data = sbuf; + + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + } + + { /*change*/ + sc_apdu_t apdu; + u8 sbuf[0x12] = {0}; + + sbuf[0] = 0x33; + sbuf[1] = 0x00; + memcpy(sbuf + 2, data->pin2.data, data->pin2.len); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x0B, data->pin_reference); + apdu.cla = 0x84; + apdu.lc = apdu.datalen = sizeof(sbuf); + apdu.data = sbuf; + + r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + } + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_erase_card(sc_card_t *card) @@ -1100,122 +1024,113 @@ static int entersafe_erase_card(sc_card_t *card) sbuf[0] = 0x3f; sbuf[1] = 0x00; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x00); - apdu.lc = 2; + apdu.lc = 2; apdu.datalen = 2; apdu.data = sbuf; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); sc_invalidate_cache(card); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xEE, 0x00, 0x00); - apdu.cla=0x84; - apdu.lc=2; - apdu.datalen=2; - apdu.data=sbuf; + apdu.cla = 0x84; + apdu.lc = 2; + apdu.datalen = 2; + apdu.data = sbuf; - switch(card->type) - { - case SC_CARD_TYPE_ENTERSAFE_3K: - { - r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1); - }break; - case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1: - case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1: - { - r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1); - }break; - default: - { - r = SC_ERROR_INTERNAL; - }break; + switch(card->type) { + case SC_CARD_TYPE_ENTERSAFE_3K: + r = entersafe_transmit_apdu(card, &apdu, trans_code_3k, sizeof(trans_code_3k), 0, 1); + break; + case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1: + case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1: + r = entersafe_transmit_apdu(card, &apdu, trans_code_ftcos_pk_01c, sizeof(trans_code_ftcos_pk_01c), 0, 1); + break; + default: + r = SC_ERROR_INTERNAL; + break; } LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } -static void entersafe_encode_bignum(u8 tag,sc_pkcs15_bignum_t bignum,u8** ptr) +static void entersafe_encode_bignum(u8 tag, sc_pkcs15_bignum_t bignum, u8 **ptr) { - u8 *p=*ptr; - - *p++=tag; - if(bignum.len<128) - { - *p++=(u8)bignum.len; - } - else - { - u8 bytes=1; - size_t len=bignum.len; - while(len) - { - len=len>>8; - ++bytes; - } - bytes&=0x0F; - *p++=0x80|bytes; - while(bytes) - { - *p++=bignum.len>>((bytes-1)*8); - --bytes; - } - } - memcpy(p,bignum.data,bignum.len); - entersafe_reverse_buffer(p,bignum.len); - p+=bignum.len; - *ptr = p; + u8 *p = *ptr; + + *p++ = tag; + if (bignum.len < 128) { + *p++ = (u8)bignum.len; + } else { + u8 bytes = 1; + size_t len = bignum.len; + while (len) { + len = len >> 8; + ++bytes; + } + bytes &= 0x0F; + *p++ = 0x80 | bytes; + while (bytes) { + *p++ = bignum.len >> ((bytes - 1) * 8); + --bytes; + } + } + memcpy(p, bignum.data, bignum.len); + entersafe_reverse_buffer(p, bignum.len); + p += bignum.len; + *ptr = p; } -static int entersafe_write_small_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkcs15_prkey_rsa *rsa) +static int entersafe_write_small_rsa_key(sc_card_t *card, u8 key_id, struct sc_pkcs15_prkey_rsa *rsa) { - sc_apdu_t apdu; - u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; - int r; - u8 *p=sbuff; + sc_apdu_t apdu; + u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; + int r; + u8 *p = sbuff; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - {/* write prkey */ - *p++=0x00; /* EC */ - *p++=0x00; /* ver */ - entersafe_encode_bignum('E',rsa->exponent,&p); - entersafe_encode_bignum('D',rsa->d,&p); - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF4,0x22,key_id); - apdu.cla=0x84; - apdu.data=sbuff; - apdu.lc=apdu.datalen=p-sbuff; - - r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); - } - - p=sbuff; - {/* write pukey */ - *p++=0x00; /* EC */ - *p++=0x00; /* ver */ - entersafe_encode_bignum('E',rsa->exponent,&p); - entersafe_encode_bignum('N',rsa->modulus,&p); - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF4,0x2A,key_id); - apdu.cla=0x84; - apdu.data=sbuff; - apdu.lc=apdu.datalen=p-sbuff; - - r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey failed"); - } - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + { /* write prkey */ + *p++ = 0x00; /* EC */ + *p++ = 0x00; /* ver */ + entersafe_encode_bignum('E', rsa->exponent, &p); + entersafe_encode_bignum('D', rsa->d, &p); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x22, key_id); + apdu.cla = 0x84; + apdu.data = sbuff; + apdu.lc = apdu.datalen = p - sbuff; + + r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey failed"); + } + + p = sbuff; + { /* write pukey */ + *p++ = 0x00; /* EC */ + *p++ = 0x00; /* ver */ + entersafe_encode_bignum('E', rsa->exponent, &p); + entersafe_encode_bignum('N', rsa->modulus, &p); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x2A, key_id); + apdu.cla = 0x84; + apdu.data = sbuff; + apdu.lc = apdu.datalen = p - sbuff; + + r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey failed"); + } + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_write_rsa_key_factor(sc_card_t *card, @@ -1228,176 +1143,174 @@ static int entersafe_write_rsa_key_factor(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - {/* MSE */ - u8 sbuff[4]; - sbuff[0]=0x84; - sbuff[1]=0x02; - sbuff[2]=key_id; - sbuff[3]=usage; + { /* MSE */ + u8 sbuff[4]; + sbuff[0] = 0x84; + sbuff[1] = 0x02; + sbuff[2] = key_id; + sbuff[3] = usage; - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x22,0x01,0xB8); - apdu.data=sbuff; - apdu.lc=apdu.datalen=4; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8); + apdu.data = sbuff; + apdu.lc = apdu.datalen = 4; - r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed(MSE)"); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey factor failed(MSE)"); } - {/* Write 'x'; */ + { /* Write 'x'; */ u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x46,factor,0x00); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, factor, 0x00); - memcpy(sbuff,data.data,data.len); - entersafe_reverse_buffer(sbuff,data.len); + memcpy(sbuff, data.data, data.len); + entersafe_reverse_buffer(sbuff, data.len); /* * PK01C and PK13C smart card only support 1024 or 2048bit key . * Size of exponent1 exponent2 coefficient of RSA private key keep the same as size of prime1 * So check factor is padded with zero or not */ - switch(factor){ - case 0x3: - case 0x4: - case 0x5: - { + switch(factor) { + case 0x3: + case 0x4: + case 0x5: { size_t i; if (data.len > 32 && data.len < 64) { for (i = data.len; i < 64; i++) sbuff[i] = 0; data.len = 64; - } else if (data.len > 64 && data.len < 128) { + } else if( data.len > 64 && data.len < 128 ) { for (i = data.len; i < 128; i++) sbuff[i] = 0; data.len = 128; } - } - break; - default: - break; - } - - apdu.data=sbuff; - apdu.lc=apdu.datalen=data.len; - - r = entersafe_transmit_apdu(card,&apdu,0,0,0,0); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey factor failed"); + } + break; + default: + break; + } + + apdu.data = sbuff; + apdu.lc = apdu.datalen = data.len; + + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey factor failed"); } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_write_large_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkcs15_prkey_rsa *rsa) { - int r; + int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - {/* write prkey */ - r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x01,rsa->p); - LOG_TEST_RET(card->ctx, r, "write p failed"); - r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x02,rsa->q); - LOG_TEST_RET(card->ctx, r, "write q failed"); - r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x03,rsa->dmp1); - LOG_TEST_RET(card->ctx, r, "write dmp1 failed"); - r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x04,rsa->dmq1); - LOG_TEST_RET(card->ctx, r, "write dmq1 failed"); - r = entersafe_write_rsa_key_factor(card,key_id,0x22,0x05,rsa->iqmp); - LOG_TEST_RET(card->ctx, r, "write iqmp failed"); - } - - {/* write pukey */ - u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; - sc_apdu_t apdu; - - /* first 64(0x40) bytes of N */ - sbuff[0]=0x83; - sbuff[1]=0x02; - sbuff[2]=key_id; - sbuff[3]=0x2A; - sbuff[4]=0x89; - sbuff[5]=0x40; - memcpy(sbuff+6,rsa->modulus.data,0x40); - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x22,0x01,0xB8); - apdu.data=sbuff; - apdu.lc=apdu.datalen=0x46; - - r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(1) failed"); - - /* left 192(0xC0) bytes of N */ - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x46,0x0B,0x00); - apdu.data=rsa->modulus.data+0x40; - apdu.lc=apdu.datalen=0xC0; - - r=entersafe_transmit_apdu(card,&apdu,0,0,0,0); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write pukey N(2) failed"); - - /* E */ - r = entersafe_write_rsa_key_factor(card,key_id,0x2A,0x0D,rsa->exponent); - LOG_TEST_RET(card->ctx, r, "write exponent failed"); - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + { /* write prkey */ + r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x01, rsa->p); + LOG_TEST_RET(card->ctx, r, "write p failed"); + r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x02, rsa->q); + LOG_TEST_RET(card->ctx, r, "write q failed"); + r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x03, rsa->dmp1); + LOG_TEST_RET(card->ctx, r, "write dmp1 failed"); + r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x04, rsa->dmq1); + LOG_TEST_RET(card->ctx, r, "write dmq1 failed"); + r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x05, rsa->iqmp); + LOG_TEST_RET(card->ctx, r, "write iqmp failed"); + } + + { /* write pukey */ + u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; + sc_apdu_t apdu; + + /* first 64(0x40) bytes of N */ + sbuff[0] = 0x83; + sbuff[1] = 0x02; + sbuff[2] = key_id; + sbuff[3] = 0x2A; + sbuff[4] = 0x89; + sbuff[5] = 0x40; + memcpy(sbuff + 6, rsa->modulus.data, 0x40); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8); + apdu.data = sbuff; + apdu.lc = apdu.datalen = 0x46; + + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey N(1) failed"); + + /* left 192(0xC0) bytes of N */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x0B, 0x00); + apdu.data = rsa->modulus.data + 0x40; + apdu.lc = apdu.datalen = 0xC0; + + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey N(2) failed"); + + /* E */ + r = entersafe_write_rsa_key_factor(card, key_id, 0x2A, 0x0D, rsa->exponent); + LOG_TEST_RET(card->ctx, r, "write exponent failed"); + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_write_symmetric_key(sc_card_t *card, - u8 key_id,u8 usage, - u8 EC,u8 ver, - u8 *data,size_t len) + u8 key_id, u8 usage, + u8 EC, u8 ver, + u8 *data, size_t len) { - sc_apdu_t apdu; - u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]={0}; - int r; + sc_apdu_t apdu; + u8 sbuff[SC_MAX_APDU_BUFFER_SIZE] = {0}; + int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if(len>240) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INCORRECT_PARAMETERS); + if (len > 240) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INCORRECT_PARAMETERS); - sbuff[0]=EC; - sbuff[1]=ver; - memcpy(&sbuff[2],data,len); + sbuff[0] = EC; + sbuff[1] = ver; + memcpy(&sbuff[2], data, len); - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF4,usage,key_id); - apdu.cla=0x84; - apdu.data=sbuff; - apdu.lc=apdu.datalen=len+2; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, usage, key_id); + apdu.cla = 0x84; + apdu.data = sbuff; + apdu.lc = apdu.datalen = len + 2; - r=entersafe_transmit_apdu(card,&apdu,key_maintain,sizeof(key_maintain),1,1); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),"Write prkey failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); + r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey failed"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } static int entersafe_write_key(sc_card_t *card, sc_entersafe_wkey_data *data) { - struct sc_pkcs15_prkey_rsa* rsa=data->key_data.rsa; + struct sc_pkcs15_prkey_rsa *rsa = data->key_data.rsa; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - switch(data->usage) - { - case 0x22: - if(rsa->modulus.len < 256) - return entersafe_write_small_rsa_key(card,data->key_id,rsa); - else - return entersafe_write_large_rsa_key(card,data->key_id,rsa); - break; - case 0x2A: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); - break; - default: - return entersafe_write_symmetric_key(card,data->key_id,data->usage, - data->key_data.symmetric.EC, - data->key_data.symmetric.ver, - data->key_data.symmetric.key_val, - data->key_data.symmetric.key_len); - break; - } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + switch(data->usage) { + case 0x22: + if(rsa->modulus.len < 256) + return entersafe_write_small_rsa_key(card,data->key_id, rsa); + else + return entersafe_write_large_rsa_key(card,data->key_id, rsa); + break; + case 0x2A: + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + break; + default: + return entersafe_write_symmetric_key(card,data->key_id,data->usage, + data->key_data.symmetric.EC, + data->key_data.symmetric.ver, + data->key_data.symmetric.key_val, + data->key_data.symmetric.key_len); + break; + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) @@ -1406,49 +1319,49 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) size_t len = data->key_length >> 3; sc_apdu_t apdu; u8 rbuf[300] = {0}; - u8 sbuf[4],*p; + u8 sbuf[4], *p; size_t plen = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* MSE */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8); - apdu.lc=0x04; - sbuf[0]=0x83; - sbuf[1]=0x02; - sbuf[2]=data->key_id; - sbuf[3]=0x2A; + apdu.lc = 0x04; + sbuf[0] = 0x83; + sbuf[1] = 0x02; + sbuf[2] = data->key_id; + sbuf[3] = 0x2A; apdu.data = sbuf; - apdu.datalen=4; - apdu.lc=4; - apdu.le=0; + apdu.datalen = 4; + apdu.lc = 4; + apdu.le = 0; - r=entersafe_transmit_apdu(card, &apdu, 0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe set MSE failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe set MSE failed"); /* generate key */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00); - apdu.le = 0; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00); + apdu.le = 0; sbuf[0] = (u8)(data->key_length >> 8); sbuf[1] = (u8)(data->key_length); - apdu.data = sbuf; - apdu.lc = 2; + apdu.data = sbuf; + apdu.lc = 2; apdu.datalen = 2; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe generate key pair failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe generate key pair failed"); /* read public key via READ PUBLIC KEY */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xE6, 0x2A, data->key_id); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xE6, 0x2A, data->key_id); apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; - r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get pukey failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe get pukey failed"); p = rbuf; plen = apdu.resplen; @@ -1467,19 +1380,17 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); } ++p; - if (*p++ > 0x80) - { + if (*p++ > 0x80) { u8 len_bytes = (*(p - 1)) & 0x0f; size_t module_len = 0; if ((size_t)(p - rbuf) + len_bytes >= plen) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); } - while (len_bytes != 0) - { - module_len = module_len << 8; - module_len += *p++; - --len_bytes; - } + while (len_bytes != 0) { + module_len = module_len << 8; + module_len += *p++; + --len_bytes; + } } if ((p - rbuf) + len >= plen) { @@ -1504,28 +1415,28 @@ static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); assert(serial); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT,0xEA,0x00,0x00); - apdu.cla=0x80; - apdu.resp=rbuf; - apdu.resplen=sizeof(rbuf); - apdu.le=0x08; + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xEA, 0x00, 0x00); + apdu.cla = 0x80; + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 0x08; - r=entersafe_transmit_apdu(card, &apdu,0,0,0,0); + r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get SN failed"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe get SN failed"); - card->serialnr.len=serial->len=8; - memcpy(card->serialnr.value,rbuf,8); - memcpy(serial->value,rbuf,8); + card->serialnr.len = serial->len = 8; + memcpy(card->serialnr.value, rbuf, 8); + memcpy(serial->value, rbuf, 8); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } -static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) +static int entersafe_preinstall_rsa_2048(sc_card_t *card, u8 key_id) { u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_apdu_t apdu; - int ret=0; + int ret = 0; static u8 const rsa_key_e[] = { 'E', 0x04, 0x01, 0x00, 0x01, 0x00 @@ -1533,7 +1444,7 @@ static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* create rsa item in IKF */ + /* create rsa item in IKF */ sbuf[0] = 0x04; /* key len extern */ sbuf[1] = 0x0a; /* key len */ sbuf[2] = 0x22; /* USAGE */ @@ -1549,15 +1460,15 @@ static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) sbuf[9 + sizeof(rsa_key_e) + 2] = 0x04; sbuf[9 + sizeof(rsa_key_e) + 3] = 0x00; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,0xF0,0x00,key_id); - apdu.cla=0x84; - apdu.data=sbuf; - apdu.lc=apdu.datalen=9 + sizeof(rsa_key_e) + 4; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, key_id); + apdu.cla = 0x84; + apdu.data = sbuf; + apdu.lc = apdu.datalen = 9 + sizeof(rsa_key_e) + 4; - ret = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); + ret = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed"); - /* create rsa item in PKF */ + /* create rsa item in PKF */ sbuf[0] = 0x01; /* key len extern */ sbuf[1] = 0x0A; /* key len */ sbuf[2] = 0x2A; /* USAGE */ @@ -1573,102 +1484,98 @@ static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) sbuf[9 + sizeof(rsa_key_e) + 2] = 0x01; sbuf[9 + sizeof(rsa_key_e) + 3] = 0x00; - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF0,0x00,key_id); - apdu.cla=0x84; - apdu.data=sbuf; - apdu.lc=apdu.datalen=9 + sizeof(rsa_key_e) + 4; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, key_id); + apdu.cla = 0x84; + apdu.data = sbuf; + apdu.lc = apdu.datalen = 9 + sizeof(rsa_key_e) + 4; - ret=entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); + ret = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } -static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_t *,u8)) +static int entersafe_preinstall_keys(sc_card_t *card, int (*install_rsa)(sc_card_t *, u8)) { - int r; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - sc_apdu_t apdu; + int r; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - {/* RSA */ - u8 rsa_index; - for(rsa_index=ENTERSAFE_MIN_KEY_ID; - rsa_index<=ENTERSAFE_MAX_KEY_ID; - ++rsa_index) - { - r=install_rsa(card,rsa_index); - LOG_TEST_RET(card->ctx, r, "Preinstall rsa key failed"); - } - } - - {/* key maintain */ - /* create key maintain*/ - sbuf[0] = 0; /* key len extern */ - sbuf[1] = sizeof(key_maintain); /* key len */ - sbuf[2] = 0x03; /* USAGE */ - sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ - sbuf[4] = ENTERSAFE_AC_ALWAYS; /* CHANGE AC */ - sbuf[5] = ENTERSAFE_AC_NEVER; /* UPDATE AC */ - sbuf[6] = 0x01; /* ALGO */ - sbuf[7] = 0x00; /* EC */ - sbuf[8] = 0x00; /* VER */ - memcpy(&sbuf[9], key_maintain, sizeof(key_maintain)); - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF0,0x00,0x00); - apdu.cla=0x84; - apdu.data=sbuf; - apdu.lc=apdu.datalen=0x19; - - r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - LOG_TEST_RET(card->ctx, r, "Preinstall key maintain failed"); - } - - {/* user PIN */ - memset(sbuf,0,sizeof(sbuf)); - sbuf[0] = 0; /* key len extern */ - sbuf[1] = 16; /* key len */ - sbuf[2] = 0x0B; /* USAGE */ - sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ - sbuf[4] = 0X04; /* CHANGE AC */ - sbuf[5] = 0x38; /* UPDATE AC */ - sbuf[6] = 0x01; /* ALGO */ - sbuf[7] = 0xFF; /* EC */ - sbuf[8] = 0x00; /* VER */ - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF0,0x00,ENTERSAFE_USER_PIN_ID); - apdu.cla=0x84; - apdu.data=sbuf; - apdu.lc=apdu.datalen=0x19; - - r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - LOG_TEST_RET(card->ctx, r, "Preinstall user PIN failed"); - } - - {/* user PUK */ - memset(sbuf,0,sizeof(sbuf)); - sbuf[0] = 0; /* key len extern */ - sbuf[1] = 16; /* key len */ - sbuf[2] = 0x0B; /* USAGE */ - sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ - sbuf[4] = 0X08; /* CHANGE AC */ - sbuf[5] = 0xC0; /* UPDATE AC */ - sbuf[6] = 0x01; /* ALGO */ - sbuf[7] = 0xFF; /* EC */ - sbuf[8] = 0x00; /* VER */ - - sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF0,0x00,ENTERSAFE_USER_PIN_ID+1); - apdu.cla=0x84; - apdu.data=sbuf; - apdu.lc=apdu.datalen=0x19; - - r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1); - LOG_TEST_RET(card->ctx, r, "Preinstall user PUK failed"); - } - - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); + { /* RSA */ + u8 rsa_index; + for (rsa_index = ENTERSAFE_MIN_KEY_ID; rsa_index <= ENTERSAFE_MAX_KEY_ID; ++rsa_index) { + r = install_rsa(card, rsa_index); + LOG_TEST_RET(card->ctx, r, "Preinstall rsa key failed"); + } + } + + { /* key maintain */ + /* create key maintain*/ + sbuf[0] = 0; /* key len extern */ + sbuf[1] = sizeof(key_maintain); /* key len */ + sbuf[2] = 0x03; /* USAGE */ + sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ + sbuf[4] = ENTERSAFE_AC_ALWAYS; /* CHANGE AC */ + sbuf[5] = ENTERSAFE_AC_NEVER; /* UPDATE AC */ + sbuf[6] = 0x01; /* ALGO */ + sbuf[7] = 0x00; /* EC */ + sbuf[8] = 0x00; /* VER */ + memcpy(&sbuf[9], key_maintain, sizeof(key_maintain)); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, 0x00); + apdu.cla = 0x84; + apdu.data = sbuf; + apdu.lc = apdu.datalen = 0x19; + + r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); + LOG_TEST_RET(card->ctx, r, "Preinstall key maintain failed"); + } + + { /* user PIN */ + memset(sbuf, 0, sizeof(sbuf)); + sbuf[0] = 0; /* key len extern */ + sbuf[1] = 16; /* key len */ + sbuf[2] = 0x0B; /* USAGE */ + sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ + sbuf[4] = 0X04; /* CHANGE AC */ + sbuf[5] = 0x38; /* UPDATE AC */ + sbuf[6] = 0x01; /* ALGO */ + sbuf[7] = 0xFF; /* EC */ + sbuf[8] = 0x00; /* VER */ + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, ENTERSAFE_USER_PIN_ID); + apdu.cla = 0x84; + apdu.data = sbuf; + apdu.lc = apdu.datalen = 0x19; + + r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); + LOG_TEST_RET(card->ctx, r, "Preinstall user PIN failed"); + } + + { /* user PUK */ + memset(sbuf, 0, sizeof(sbuf)); + sbuf[0] = 0; /* key len extern */ + sbuf[1] = 16; /* key len */ + sbuf[2] = 0x0B; /* USAGE */ + sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */ + sbuf[4] = 0X08; /* CHANGE AC */ + sbuf[5] = 0xC0; /* UPDATE AC */ + sbuf[6] = 0x01; /* ALGO */ + sbuf[7] = 0xFF; /* EC */ + sbuf[8] = 0x00; /* VER */ + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, ENTERSAFE_USER_PIN_ID + 1); + apdu.cla = 0x84; + apdu.data = sbuf; + apdu.lc = apdu.datalen = 0x19; + + r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1); + LOG_TEST_RET(card->ctx, r, "Preinstall user PUK failed"); + } + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static int entersafe_card_ctl_2048(sc_card_t *card, unsigned long cmd, void *ptr) @@ -1677,29 +1584,28 @@ static int entersafe_card_ctl_2048(sc_card_t *card, unsigned long cmd, void *ptr SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - switch (cmd) - { - case SC_CARDCTL_ENTERSAFE_CREATE_FILE: - if (tmp->type == SC_ENTERSAFE_MF_DATA) - return entersafe_create_mf(card, tmp); - else if (tmp->type == SC_ENTERSAFE_DF_DATA) - return entersafe_create_df(card, tmp); - else if (tmp->type == SC_ENTERSAFE_EF_DATA) - return entersafe_create_ef(card, tmp); - else - return SC_ERROR_INTERNAL; - case SC_CARDCTL_ENTERSAFE_WRITE_KEY: - return entersafe_write_key(card, (sc_entersafe_wkey_data *)ptr); - case SC_CARDCTL_ENTERSAFE_GENERATE_KEY: - return entersafe_gen_key(card, (sc_entersafe_gen_key_data *)ptr); - case SC_CARDCTL_ERASE_CARD: - return entersafe_erase_card(card); - case SC_CARDCTL_GET_SERIALNR: - return entersafe_get_serialnr(card, (sc_serial_number_t *)ptr); - case SC_CARDCTL_ENTERSAFE_PREINSTALL_KEYS: - return entersafe_preinstall_keys(card,entersafe_preinstall_rsa_2048); - default: - return SC_ERROR_NOT_SUPPORTED; + switch (cmd) { + case SC_CARDCTL_ENTERSAFE_CREATE_FILE: + if (tmp->type == SC_ENTERSAFE_MF_DATA) + return entersafe_create_mf(card, tmp); + else if (tmp->type == SC_ENTERSAFE_DF_DATA) + return entersafe_create_df(card, tmp); + else if (tmp->type == SC_ENTERSAFE_EF_DATA) + return entersafe_create_ef(card, tmp); + else + return SC_ERROR_INTERNAL; + case SC_CARDCTL_ENTERSAFE_WRITE_KEY: + return entersafe_write_key(card, (sc_entersafe_wkey_data *)ptr); + case SC_CARDCTL_ENTERSAFE_GENERATE_KEY: + return entersafe_gen_key(card, (sc_entersafe_gen_key_data *)ptr); + case SC_CARDCTL_ERASE_CARD: + return entersafe_erase_card(card); + case SC_CARDCTL_GET_SERIALNR: + return entersafe_get_serialnr(card, (sc_serial_number_t *)ptr); + case SC_CARDCTL_ENTERSAFE_PREINSTALL_KEYS: + return entersafe_preinstall_keys(card, entersafe_preinstall_rsa_2048); + default: + return SC_ERROR_NOT_SUPPORTED; } } @@ -1712,19 +1618,19 @@ static struct sc_card_driver * sc_get_driver(void) entersafe_ops = *iso_drv->ops; entersafe_ops.match_card = entersafe_match_card; - entersafe_ops.init = entersafe_init; + entersafe_ops.init = entersafe_init; entersafe_ops.read_binary = entersafe_read_binary; entersafe_ops.write_binary = NULL; entersafe_ops.update_binary = entersafe_update_binary; entersafe_ops.select_file = entersafe_select_file; entersafe_ops.restore_security_env = entersafe_restore_security_env; - entersafe_ops.set_security_env = entersafe_set_security_env; + entersafe_ops.set_security_env = entersafe_set_security_env; entersafe_ops.decipher = entersafe_decipher; entersafe_ops.compute_signature = entersafe_compute_signature; entersafe_ops.create_file = entersafe_create_file; entersafe_ops.delete_file = NULL; entersafe_ops.pin_cmd = entersafe_pin_cmd; - entersafe_ops.card_ctl = entersafe_card_ctl_2048; + entersafe_ops.card_ctl = entersafe_card_ctl_2048; entersafe_ops.process_fci = entersafe_process_fci; return &entersafe_drv; } From 8b00f7acf1d58924ca74a6eb7a25d3883a0e7043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 24 Oct 2023 14:51:35 +0200 Subject: [PATCH 3382/4321] sm-eac: Update OpenSSL error logging --- src/sm/sm-eac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 7ddbc605dc..706b86cb61 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -624,6 +624,7 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id return NULL; } if (0 > EVP_read_pw_string_min(p, 0, EAC_MAX_MRZ_LEN, buf, 0)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s.\n", eac_secret_name(pin_id)); return NULL; From 870ad75135fd8d7886f67792119b3b7cadf5af45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 09:37:45 +0200 Subject: [PATCH 3383/4321] card-eoi: Update OpenSSL logging --- src/libopensc/card-eoi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index b6a8818403..37f323eb94 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -189,6 +189,7 @@ static int eoi_sm_open(struct sc_card *card) if (!privdata->can[0]) { /* If no CAN is specified in conf, try to decrypt it from enc_can file */ r = eoi_decrypt_can(&privdata->enc_can, privdata->can); + sc_log_openssl(card->ctx); LOG_TEST_RET(card->ctx, r, "Cannot decrypt CAN"); } /* CAN should be 6 chars long */ From 16cf732c2599166616dcbd5510183ac426c2c984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 10:06:52 +0200 Subject: [PATCH 3384/4321] card-epass2003: Update OpenSSL logging --- src/libopensc/card-epass2003.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index e66a7840fd..6af717e0d2 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -360,6 +360,7 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); r = openssl_enc(alg, key, iv0, data1, 16, out); if (r != SC_SUCCESS) { + sc_log_openssl(card->ctx); sc_evp_cipher_free(alg); return r; } @@ -404,6 +405,8 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi } r = openssl_enc(alg, key, iv, data2, 16, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -444,15 +447,19 @@ aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac); if(ctx == NULL){ EVP_MAC_CTX_free(ctx); + sc_log_openssl(card->ctx); return r; } if(!EVP_MAC_init(ctx, (const unsigned char *)key, keysize/8,params)){ + sc_log_openssl(card->ctx); goto err; } if(!EVP_MAC_update(ctx, input,length)){ + sc_log_openssl(card->ctx); goto err; } if(!EVP_MAC_final(ctx, output, &mactlen, 16)) { + sc_log_openssl(card->ctx); goto err; } r = SC_SUCCESS; @@ -472,6 +479,8 @@ aes128_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, int r; r = openssl_enc(alg, key, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -484,6 +493,8 @@ aes128_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, int r; r = openssl_enc(alg, key, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -496,6 +507,8 @@ aes128_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, int r; r = openssl_dec(alg, key, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -519,6 +532,8 @@ des3_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, r = openssl_enc(alg, bKey, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -541,6 +556,8 @@ des3_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, un r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -563,6 +580,8 @@ des3_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, un r = openssl_dec(alg, bKey, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -576,6 +595,8 @@ des_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, uns r = openssl_enc(alg, key, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -589,6 +610,8 @@ des_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, uns r = openssl_dec(alg, key, iv, input, length, output); sc_evp_cipher_free(alg); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -635,6 +658,8 @@ sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, uns r = openssl_dig(md, input, length, output); sc_evp_md_free(md); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -646,6 +671,8 @@ sha256_digest(struct sc_card *card, const unsigned char *input, size_t length, u r = openssl_dig(md, input, length, output); sc_evp_md_free(md); + if (r != SC_SUCCESS) + sc_log_openssl(card->ctx); return r; } @@ -3330,7 +3357,9 @@ external_key_auth(struct sc_card *card, unsigned char kid, r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); - des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data); + r = des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data); + LOG_TEST_RET(card->ctx, r, "encryption failed"); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x01, 0x80 | kid); apdu.lc = apdu.datalen = 8; apdu.data = tmp_data; From 8ed406bbb3ebf2f166a33fd22a6cfc497f7afa61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 10:21:22 +0200 Subject: [PATCH 3385/4321] card-gids: Update OpenSSL logging --- src/libopensc/card-gids.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 09e37dab55..82966fac10 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1901,9 +1901,10 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) } if (i < 0) { // set a random cardid if not set - r = RAND_bytes(param->cardid, sizeof(param->cardid)); - LOG_TEST_RET(card->ctx, r, "unable to set a random serial number"); - + if (RAND_bytes(param->cardid, sizeof(param->cardid)) != 1) { + sc_log_openssl(card->ctx); + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set a random serial number"); + } } #endif r = gids_put_DO(card, CARDID_FI, CARDID_DO, param->cardid, sizeof(param->cardid)); @@ -1965,8 +1966,10 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // generate a challenge - r = RAND_bytes(randomR1, 16); - LOG_TEST_RET(card->ctx, r, "unable to set computer random"); + if (RAND_bytes(randomR1, 16) != 1) { + sc_log_openssl(card->ctx); + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set computer random"); + } // send it to the card sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00); @@ -1981,8 +1984,11 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // compute the half size of the mutual authentication secret - r = RAND_bytes(z1, 7); - LOG_TEST_RET(card->ctx, r, "unable to set computer random"); + if (RAND_bytes(z1, 7) != 1) { + sc_log_openssl(card->ctx); + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set computer random"); + } + // set the padding z1[7] = 0x80; @@ -1993,22 +1999,26 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { // init crypto ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { + sc_log_openssl(card->ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { + sc_log_openssl(card->ctx); EVP_CIPHER_CTX_free(ctx); sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { + sc_log_openssl(card->ctx); EVP_CIPHER_CTX_free(ctx); sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { + sc_log_openssl(card->ctx); EVP_CIPHER_CTX_free(ctx); sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -2041,18 +2051,21 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { } cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { + sc_log_openssl(card->ctx); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, (int)apdu.resplen - 4)) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "unable to decrypt data"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "unable to decrypt final data"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); @@ -2060,18 +2073,21 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { } sc_log(card->ctx, "data has been decrypted using the key"); if (memcmp(buffer3, randomR1, 16) != 0) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "R1 doesn't match"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (memcmp(buffer3 + 16, randomR2, 16) != 0) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "R2 doesn't match"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (buffer[39] != 0x80) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "Padding not found"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); From 3adbd4c3c20f06e3a14d1c4438c1d193e3982bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 11:28:58 +0200 Subject: [PATCH 3386/4321] card-iasecc: Update OpenSSL logging --- src/libopensc/card-iasecc.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index b1ae31967b..4ecadc8bfb 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -3195,20 +3195,23 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i md = sc_evp_md(ctx, "SHA1"); mdctx = EVP_MD_CTX_new(); if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestInit_ex failed"); - goto err; + goto end; } md_data = EVP_MD_CTX_md_data(mdctx); if (md_data == NULL) { + sc_log_openssl(ctx); sc_log(ctx, "Failed to find md_data"); r = SC_ERROR_NOT_SUPPORTED; - goto err; + goto end; } if (EVP_DigestUpdate(mdctx, in, in_len) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestUpdate failed"); - goto err; + goto end; } hh[0] = &md_data->h0; @@ -3241,19 +3244,16 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i } if (EVP_DigestFinal_ex(mdctx, out->hash, &md_out_len) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestFinal_ex failed"); - goto err; + goto end; } out->hash_size = SHA_DIGEST_LENGTH; sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size)); r = SC_SUCCESS; - goto end; -err: - if (ctx->debug > 0 && ctx->debug_file != 0) - ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); sc_evp_md_free(md); @@ -3294,20 +3294,23 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t md = sc_evp_md(ctx, "SHA256"); mdctx = EVP_MD_CTX_new(); if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestInit_ex failed"); - goto err; + goto end; } md_data = EVP_MD_CTX_md_data(mdctx); if (md_data == NULL) { + sc_log_openssl(ctx); sc_log(ctx, "Failed to find md_data"); r = SC_ERROR_NOT_SUPPORTED; - goto err; + goto end; } if (EVP_DigestUpdate(mdctx, in, in_len) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestUpdate failed"); - goto err; + goto end; } for (jj=0; jjhash, &md_out_len) != 1) { + sc_log_openssl(ctx); sc_log(ctx, "EVP_DigestFinal_ex failed"); - goto err; + goto end; } out->hash_size = SHA256_DIGEST_LENGTH; sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size)); r = SC_SUCCESS; - goto end; -err: - if (ctx->debug > 0 && ctx->debug_file != 0) - ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); sc_evp_md_free(md); From c755f6947245879e2ff6b7a95b87259bcb2abc38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 11:31:15 +0200 Subject: [PATCH 3387/4321] card-npa: Update OpenSSL logging --- src/libopensc/card-npa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 35bad06d15..a32b6cfc68 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -651,6 +651,7 @@ npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, if (0 > EVP_read_pw_string_min(p, EAC_MIN_PIN_LEN, EAC_MAX_PIN_LEN+1, "Please enter your new PIN: ", 0)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n"); free(p); return SC_ERROR_INTERNAL; From bbc009c32ed781a30450465e3e16a38c7a580f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 11:45:43 +0200 Subject: [PATCH 3388/4321] card-oberthur: Update OpenSSL logging --- src/libopensc/card-oberthur.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 1e87c3b269..664ef064f3 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -31,10 +31,7 @@ #include #include #include -#include #include -#include -#include #include "internal.h" #include "cardctl.h" @@ -1371,11 +1368,18 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a alg = sc_evp_cipher(card->ctx, "DES-EDE"); else alg = sc_evp_cipher(card->ctx, "DES-ECB"); - EVP_EncryptInit_ex(ctx, alg, NULL, args->data, NULL); + rv = EVP_EncryptInit_ex(ctx, alg, NULL, args->data, NULL); + if (rv == 0) { + sc_evp_cipher_free(alg); + sc_log_openssl(card->ctx); + sc_log(card->ctx, "OpenSSL encryption error."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8); EVP_CIPHER_CTX_free(ctx); sc_evp_cipher_free(alg); if (rv == 0) { + sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL encryption error."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } From 1656aad1f4fd8668a9a07d73616886f0201144c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 14:35:12 +0200 Subject: [PATCH 3389/4321] card-piv: Following fixes for OpenSSL --- src/libopensc/card-piv.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 5e9dcd9e68..d7e3a48657 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -41,15 +41,12 @@ #ifdef ENABLE_OPENSSL /* openssl needed for card administration and SM */ #include -#include #include #include -#include #include #if !defined(OPENSSL_NO_EC) #include #endif -#include #endif /* 800-73-4 SM and VCI need: ECC, SM and real OpenSSL >= 1.1 */ @@ -952,8 +949,8 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.enc_counter, 16) != 1 || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { - sc_log(card->ctx,"SM encode failed in OpenSSL"); sc_log_openssl(card->ctx); + sc_log(card->ctx,"SM encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; goto err; } @@ -1029,8 +1026,8 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu || EVP_EncryptUpdate(ed_ctx, p + outl, &outll, pad, padlen) != 1 || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { /* should not happen */ - sc_log(card->ctx,"SM _encode failed in OpenSSL"); sc_log_openssl(card->ctx); + sc_log(card->ctx,"SM _encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; goto err; } @@ -2650,9 +2647,10 @@ static int piv_sm_open(struct sc_card *card) err: priv->sm_flags &= ~PIV_SM_FLAGS_DEFER_OPEN; - if (r != 0) - memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); - sc_log_openssl(card->ctx); /* catch any not logged above */ + if (r != 0) { + memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); + sc_log_openssl(card->ctx); /* catch any not logged above */ + } sc_unlock(card); @@ -3896,6 +3894,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = RAND_bytes(nonce, (int)witness_len); if(!r) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Generating random for nonce (%"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u)\n", witness_len, plain_text_len); From 53ad30964ab7083248423c1b3197f7a10075634d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 15:20:56 +0200 Subject: [PATCH 3390/4321] card-sc-hsm: Update OpenSSL logging --- src/libopensc/card-sc-hsm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 126f9dd4b1..cc0bd2d7d4 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -41,8 +41,7 @@ #include #include #include -#include -#include +#include #endif @@ -497,8 +496,6 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } - - #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) static int sc_hsm_perform_chip_authentication(sc_card_t *card) @@ -593,7 +590,11 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) goto err; } EVP_PKEY_free(ctx->ca_ctx->ka_ctx->key); - EVP_PKEY_up_ref(ctx->ta_ctx->pub_key); + if (!EVP_PKEY_up_ref(ctx->ta_ctx->pub_key)) { + sc_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } ctx->ca_ctx->ka_ctx->key = ctx->ta_ctx->pub_key; /* generate keys for CA */ From fe5f054a2d88ec07278568fa5702dc968dd04104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 16:02:51 +0200 Subject: [PATCH 3391/4321] Update OpenSSL logging in padding functions --- src/libopensc/padding.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index e8899a5131..c42dc945d5 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -299,14 +299,17 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne if ((md_ctx = EVP_MD_CTX_new())) { if (!EVP_DigestInit_ex(md_ctx, hash_md, NULL) || !EVP_DigestUpdate(md_ctx, param, paramlen) - || !EVP_DigestFinal_ex(md_ctx, label, &hash_len)) + || !EVP_DigestFinal_ex(md_ctx, label, &hash_len)) { + sc_log_openssl(ctx); hash_len = 0; + } EVP_MD_CTX_free(md_ctx); } sc_evp_md_free(hash_md); hash_md = NULL; - if (!hash_len) + if (!hash_len) { LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + } mgf1_md = mgf1_flag2md(ctx, flags); if (!mgf1_md) @@ -331,6 +334,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne } if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) { + sc_log_openssl(ctx); sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); } @@ -338,6 +342,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne seed[i] ^= data[i + 1]; if (mgf1(db, dblen, seed, mdlen, mgf1_md)) { + sc_log_openssl(ctx); sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); } @@ -478,8 +483,10 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi return SC_ERROR_BUFFER_TOO_SMALL; md = hash_flag2md(scctx, hash); - if (md == NULL) + if (md == NULL) { + sc_log_openssl(scctx); return SC_ERROR_NOT_SUPPORTED; + } hlen = EVP_MD_size(md); dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ plen = mod_length - sLen - hlen - 1; @@ -498,6 +505,7 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi return SC_ERROR_INVALID_ARGUMENTS; } if (RAND_bytes(salt, (unsigned)sLen) != 1) { + sc_log_openssl(scctx); sc_evp_md_free(md); return SC_ERROR_INTERNAL; } @@ -510,6 +518,7 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi EVP_DigestUpdate(ctx, buf, 8) != 1 || EVP_DigestUpdate(ctx, in, hlen) != 1 || /* mHash */ EVP_DigestUpdate(ctx, salt, sLen) != 1) { + sc_log_openssl(scctx); goto done; } @@ -519,6 +528,7 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi out[plen - 1] = 0x01; memcpy(out + plen, salt, sLen); if (EVP_DigestFinal_ex(ctx, out + dblen, NULL) != 1) { /* H */ + sc_log_openssl(scctx); goto done; } out[dblen + hlen] = 0xBC; @@ -527,8 +537,10 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi /* Construct the DB mask block by block and XOR it in. */ mgf1_md = mgf1_flag2md(scctx, mgf1_hash); - if (mgf1_md == NULL) - return SC_ERROR_NOT_SUPPORTED; + if (mgf1_md == NULL) { + sc_log_openssl(scctx); + goto done; + } mgf1_hlen = EVP_MD_size(mgf1_md); mgf_rounds = (dblen + mgf1_hlen - 1) / mgf1_hlen; /* round up */ @@ -541,6 +553,7 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */ EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */ EVP_DigestFinal_ex(ctx, mask, NULL) != 1) { + sc_log_openssl(scctx); goto done; } /* this is no longer part of the MGF1, but actually @@ -650,8 +663,10 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, hash_algo = hash_len2algo(tmp_len); } /* sLen is by default same as hash length */ - if (!(md = hash_flag2md(ctx, hash_algo))) + if (!(md = hash_flag2md(ctx, hash_algo))) { + sc_log_openssl(ctx); return SC_ERROR_NOT_SUPPORTED; + } sLen = EVP_MD_size(md); sc_evp_md_free(md); /* if application provide sLen, use it */ From 53e3116edd1ba26ec8269a20f349b0efbd842806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 16:21:10 +0200 Subject: [PATCH 3392/4321] pkcs15-itacns: Update OpenSSL logging --- src/libopensc/pkcs15-itacns.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 1b0772802d..17580f0a39 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -34,11 +34,6 @@ #include #include -#ifdef ENABLE_OPENSSL -#include -#include -#endif - #include "internal.h" #include "pkcs15.h" #include "log.h" @@ -240,7 +235,10 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, } sc_pkcs15_free_certificate(cert); - if (!x509) return SC_SUCCESS; + if (!x509) { + sc_log_openssl(p15card->card->ctx); + return SC_SUCCESS; + } X509_check_purpose(x509, -1, 0); if(X509_get_extension_flags(x509) & EXFLAG_KUSAGE) { From 1591a0237b523d0b1ed9d9f860071a39e74723af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 16:24:49 +0200 Subject: [PATCH 3393/4321] pkcs15-oberthur: Update OpenSSL logging --- src/libopensc/pkcs15-oberthur.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 121dbb6f6a..561e302bbe 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -38,7 +38,6 @@ #ifdef ENABLE_OPENSSL #include -#include #include #include #endif @@ -185,7 +184,7 @@ sc_oberthur_get_friends (unsigned int id, struct crypto_container *ccont) static int -sc_oberthur_get_certificate_authority(struct sc_pkcs15_der *der, int *out_authority) +sc_oberthur_get_certificate_authority(sc_context_t *ctx, struct sc_pkcs15_der *der, int *out_authority) { #ifdef ENABLE_OPENSSL X509 *x; @@ -206,6 +205,7 @@ sc_oberthur_get_certificate_authority(struct sc_pkcs15_der *der, int *out_author bio = BIO_new(BIO_s_mem()); if (!bio) { free(buf_mem.data); + sc_log_openssl(ctx); return SC_ERROR_OUT_OF_MEMORY; } @@ -213,8 +213,10 @@ sc_oberthur_get_certificate_authority(struct sc_pkcs15_der *der, int *out_author x = d2i_X509_bio(bio, 0); free(buf_mem.data); BIO_free(bio); - if (!x) + if (!x) { + sc_log_openssl(ctx); return SC_ERROR_INVALID_DATA; + } bs = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL); if (out_authority) @@ -732,7 +734,7 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file cinfo.value.value = cert_blob; cinfo.value.len = cert_len; - rv = sc_oberthur_get_certificate_authority(&cinfo.value, &cinfo.authority); + rv = sc_oberthur_get_certificate_authority(ctx, &cinfo.value, &cinfo.authority); if (rv != SC_SUCCESS) { free(cinfo.value.value); LOG_TEST_RET(ctx, rv, "Failed to add certificate: get certificate attributes error"); From 7719b1b5bc45e6a40ed174f361841518a9120a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 16:35:36 +0200 Subject: [PATCH 3394/4321] pkcs15-prkey: Update OpenSSL logging --- src/libopensc/pkcs15-prkey.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 5a605e2621..8b84dafaf4 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include @@ -252,17 +250,20 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, nid = OBJ_obj2nid(object); ASN1_OBJECT_free(object); if (nid == NID_undef) { + sc_log_openssl(ctx); r = SC_ERROR_OBJECT_NOT_FOUND; goto err; } group = EC_GROUP_new_by_curve_name(nid); if (!group) { + sc_log_openssl(ctx); r = SC_ERROR_INVALID_DATA; goto err; } info.field_length = EC_GROUP_order_bits(group); EC_GROUP_free(group); if (!info.field_length) { + sc_log_openssl(ctx); r = SC_ERROR_CORRUPTED_DATA; goto err; } @@ -495,21 +496,28 @@ sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15 sc_log(ctx, "CertValue(%"SC_FORMAT_LEN_SIZE_T"u) %p", cert_object->content.len, cert_object->content.value); mem = BIO_new_mem_buf(cert_object->content.value, (int)cert_object->content.len); - if (!mem) + if (!mem) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "MEM buffer allocation error"); + } x = d2i_X509_bio(mem, NULL); - if (!x) + if (!x) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "x509 parse error"); - + } buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE); - if (!buff) + if (!buff) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "OpenSSL allocation error"); + } ptr = buff; rv = i2d_X509_NAME(X509_get_subject_name(x), &ptr); - if (rv <= 0) + if (rv <= 0) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Get subject name error"); + } key_info->subject.value = malloc(rv); if (!key_info->subject.value) From 7513c49aea8ead8edc23673f011c5c141e947fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 25 Oct 2023 16:42:23 +0200 Subject: [PATCH 3395/4321] pkcs15-pubkey: Free RSA with RSA_free --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index a759efa45c..bbc9a2eed9 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1609,7 +1609,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) return SC_ERROR_INCOMPATIBLE_KEY; RSA_get0_key(src, &src_n, &src_e, NULL); if (!src_n || !src_e) { - free(src); + RSA_free(src); return SC_ERROR_INTERNAL; } #else From 65acca64b6001aed7ecd7a66e3571693c4aa3e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 26 Oct 2023 15:49:14 +0200 Subject: [PATCH 3396/4321] openssl: Update OpenSSL logging --- src/pkcs11/openssl.c | 63 +++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 8377236fc8..9a36044ffa 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -380,9 +380,12 @@ static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *op) if (!op || !(mt = op->type) || !(md = (EVP_MD *) mt->mech_data)) return CKR_ARGUMENTS_BAD; - if (!(md_ctx = EVP_MD_CTX_create())) + if (!(md_ctx = EVP_MD_CTX_create())) { + sc_log_openssl(context); return CKR_HOST_MEMORY; + } if (!EVP_DigestInit(md_ctx, md)) { + sc_log_openssl(context); EVP_MD_CTX_destroy(md_ctx); return CKR_GENERAL_ERROR; } @@ -394,10 +397,14 @@ static CK_RV sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *op, CK_BYTE_PTR pData, CK_ULONG pDataLen) { EVP_MD_CTX *md_ctx = DIGEST_CTX(op); - if (!md_ctx) + if (!md_ctx) { + sc_log_openssl(context); return CKR_ARGUMENTS_BAD; - if (!EVP_DigestUpdate(md_ctx, pData, pDataLen)) + } + if (!EVP_DigestUpdate(md_ctx, pData, pDataLen)) { + sc_log_openssl(context); return CKR_GENERAL_ERROR; + } return CKR_OK; } @@ -414,9 +421,10 @@ static CK_RV sc_pkcs11_openssl_md_final(sc_pkcs11_operation_t *op, *pulDigestLen = EVP_MD_CTX_size(md_ctx); return CKR_BUFFER_TOO_SMALL; } - if (!EVP_DigestFinal(md_ctx, pDigest, (unsigned *) pulDigestLen)) + if (!EVP_DigestFinal(md_ctx, pDigest, (unsigned *)pulDigestLen)) { + sc_log_openssl(context); return CKR_GENERAL_ERROR; - + } return CKR_OK; } @@ -469,13 +477,16 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len #endif pkey = EVP_PKEY_new(); - if (!pkey) + if (!pkey) { + sc_log_openssl(context); return CKR_HOST_MEMORY; + } r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001); if (r == 1) { pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!pkey_ctx) { + sc_log_openssl(context); EVP_PKEY_free(pkey); return CKR_HOST_MEMORY; } @@ -530,6 +541,7 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len size_t len = EC_POINT_point2oct(group, P, POINT_CONVERSION_COMPRESSED, buf, buf_len, NULL); if (len == 0) { + sc_log_openssl(context); r = -1; } } @@ -540,6 +552,7 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, buf_len) != 1 || !(new_params = OSSL_PARAM_BLD_to_param(bld)) || !(p = OSSL_PARAM_merge(old_params, new_params))) { + sc_log_openssl(context); r = -1; } free(buf); @@ -548,6 +561,7 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len if (r == 1) { if (EVP_PKEY_fromdata_init(pkey_ctx) != 1 || EVP_PKEY_fromdata(pkey_ctx, &new_pkey, EVP_PKEY_KEYPAIR, p) != 1) { + sc_log_openssl(context); r = -1; } } @@ -572,8 +586,9 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len } EVP_PKEY_CTX_free(pkey_ctx); EVP_PKEY_free(pkey); - if (r != 1) + if (r != 1) { return CKR_GENERAL_ERROR; + } return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID; } #endif /* !defined(OPENSSL_NO_EC) */ @@ -615,8 +630,10 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */ pkey = d2i_PUBKEY(NULL, &pubkey_tmp, pubkey_len); - if (pkey == NULL) + if (pkey == NULL) { + sc_log_openssl(context); return CKR_GENERAL_ERROR; + } if (md != NULL && (mech->mechanism == CKM_SHA1_RSA_PKCS || mech->mechanism == CKM_MD5_RSA_PKCS @@ -663,9 +680,11 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, if (res == 1) return CKR_OK; else if (res == 0) { + sc_log_openssl(context); sc_log(context, "EVP_VerifyFinal(): Signature invalid"); return CKR_SIGNATURE_INVALID; } else { + sc_log_openssl(context); sc_log(context, "EVP_VerifyFinal() returned %d\n", res); return CKR_GENERAL_ERROR; } @@ -725,6 +744,7 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, return CKR_DEVICE_MEMORY; } if ((mdctx = EVP_MD_CTX_new()) == NULL) { + sc_log_openssl(context); free(mdbuf); EVP_PKEY_free(pkey); sc_evp_md_free(md); @@ -733,6 +753,7 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, if (!EVP_DigestInit(mdctx, md) || !EVP_DigestUpdate(mdctx, data, data_len) || !EVP_DigestFinal(mdctx, mdbuf, &mdbuf_len)) { + sc_log_openssl(context); EVP_PKEY_free(pkey); EVP_MD_CTX_free(mdctx); sc_evp_md_free(md); @@ -757,18 +778,21 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, free(signat_tmp); free(mdbuf); - if (res == 1) + if (res == 1) { return CKR_OK; - else if (res == 0) + } else if (res == 0) { + sc_log_openssl(context); return CKR_SIGNATURE_INVALID; - else + } else { + sc_log_openssl(context); return CKR_GENERAL_ERROR; - + } } else { unsigned char *rsa_out = NULL, pad; size_t rsa_outlen = 0; EVP_PKEY_CTX *ctx = sc_evp_pkey_ctx_new(context, pkey); if (!ctx) { + sc_log_openssl(context); EVP_PKEY_free(pkey); return CKR_DEVICE_MEMORY; } @@ -797,8 +821,9 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, return CKR_ARGUMENTS_BAD; } - if ( EVP_PKEY_verify_recover_init(ctx) != 1 || + if (EVP_PKEY_verify_recover_init(ctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(ctx, pad) != 1) { + sc_log_openssl(context); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); return CKR_GENERAL_ERROR; @@ -812,6 +837,7 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, return CKR_DEVICE_MEMORY; } if (EVP_PKEY_verify_recover(ctx, rsa_out, &rsa_outlen, signat, signat_len) != 1) { + sc_log_openssl(context); free(rsa_out); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); @@ -895,6 +921,7 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, unsigned int tmp_len; if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { + sc_log_openssl(context); sc_evp_md_free(mgf_md); sc_evp_md_free(pss_md); free(rsa_out); @@ -920,18 +947,22 @@ CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, EVP_PKEY_CTX_set_signature_md(ctx, pss_md) != 1 || EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sLen) != 1 || EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf_md) != 1) { - sc_log(context, "Failed to initialize EVP_PKEY_CTX"); + sc_log_openssl(context); sc_evp_md_free(mgf_md); sc_evp_md_free(pss_md); free(rsa_out); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); + sc_log(context, "Failed to initialize EVP_PKEY_CTX"); return rv; } - if (data_len == (unsigned int) EVP_MD_size(pss_md) && - EVP_PKEY_verify(ctx, signat, signat_len, data, data_len) == 1) + if (data_len == (unsigned int)EVP_MD_size(pss_md) && + EVP_PKEY_verify(ctx, signat, signat_len, data, data_len) == 1) { rv = CKR_OK; + } else { + sc_log_openssl(context); + } EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); sc_evp_md_free(mgf_md); From 2e8c6aa0bb03532fdacd6ba3e6390ff472eb6292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 09:00:19 +0100 Subject: [PATCH 3397/4321] pkcs15-authentic: Remove unneeded openssl headers --- src/pkcs15init/pkcs15-authentic.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index 53d7a99fe9..dca8afa17c 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -34,16 +34,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/log.h" From 8321ba3caefe05d0f6095cdb0bad90cb8460b678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 09:03:25 +0100 Subject: [PATCH 3398/4321] pkcs15-iasecc: Remove unneeded openssl headers --- src/pkcs15init/pkcs15-iasecc.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 0d23443a3f..0ef0042960 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -37,16 +37,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "../libopensc/opensc.h" #include "../libopensc/cardctl.h" #include "../libopensc/log.h" From bd1f72450da825bd5c5471ccae3072fdc6862006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 09:48:38 +0100 Subject: [PATCH 3399/4321] pkcs15-lib: Add openssl error checking --- src/pkcs15init/pkcs15-lib.c | 45 ++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 369d8ade5b..0dc62af4ac 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2611,6 +2611,7 @@ static int prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) { struct sc_context *ctx = p15card->card->ctx; + int r = SC_SUCCESS; if (!key->modulus.len || !key->exponent.len || !key->d.len || !key->p.len || !key->q.len) { sc_log(ctx, "Missing private RSA coefficient"); @@ -2629,9 +2630,10 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) /* We don't really need an RSA structure, only the BIGNUMs */ if (!key->dmp1.len || !key->dmq1.len || !key->iqmp.len) { - BIGNUM *aux; - BN_CTX *bn_ctx; - BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp; + BIGNUM *aux = NULL; + BN_CTX *bn_ctx = NULL; + BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL, *rsa_p = NULL, + *rsa_q = NULL, *rsa_dmp1 = NULL, *rsa_dmq1 = NULL, *rsa_iqmp = NULL; rsa_n = BN_bin2bn(key->modulus.data, (int)key->modulus.len, NULL); rsa_e = BN_bin2bn(key->exponent.data, (int)key->exponent.len, NULL); @@ -2642,19 +2644,31 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) rsa_dmq1 = BN_new(); rsa_iqmp = BN_new(); + if (!rsa_n || !rsa_e || !rsa_d || !rsa_p || !rsa_q || + !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp) { + sc_log_openssl(ctx); + r = SC_ERROR_INTERNAL; + goto end; + } + aux = BN_new(); bn_ctx = BN_CTX_new(); - BN_sub(aux, rsa_q, BN_value_one()); - BN_mod(rsa_dmq1, rsa_d, aux, bn_ctx); - - BN_sub(aux, rsa_p, BN_value_one()); - BN_mod(rsa_dmp1, rsa_d, aux, bn_ctx); - - BN_mod_inverse(rsa_iqmp, rsa_q, rsa_p, bn_ctx); + if (!aux || !bn_ctx) { + sc_log_openssl(ctx); + r = SC_ERROR_INTERNAL; + goto end; + } - BN_clear_free(aux); - BN_CTX_free(bn_ctx); + if (BN_sub(aux, rsa_q, BN_value_one()) != 1 || + BN_mod(rsa_dmq1, rsa_d, aux, bn_ctx) != 1 || + BN_sub(aux, rsa_p, BN_value_one()) != 1 || + BN_mod(rsa_dmp1, rsa_d, aux, bn_ctx) != 1 || + !BN_mod_inverse(rsa_iqmp, rsa_q, rsa_p, bn_ctx)) { + sc_log_openssl(ctx); + r = SC_ERROR_INTERNAL; + goto end; + } /* Do not replace, only fill in missing */ if (key->dmp1.data == NULL) { @@ -2685,7 +2699,7 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) key->iqmp.len = 0; } } - +end: BN_clear_free(rsa_n); BN_clear_free(rsa_e); BN_clear_free(rsa_d); @@ -2694,10 +2708,11 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) BN_clear_free(rsa_dmp1); BN_clear_free(rsa_dmq1); BN_clear_free(rsa_iqmp); - + BN_clear_free(aux); + BN_CTX_free(bn_ctx); } #endif - return 0; + return r; } From c88d247138d94b7a2201235cdc83badc4fc6365e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 09:55:09 +0100 Subject: [PATCH 3400/4321] pkcs15-oberthut-awp: Update OpenSSL logging --- src/pkcs15init/pkcs15-oberthur-awp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 0e5d8c3e55..22c943127b 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -947,12 +947,16 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ci->label.len = strlen(obj->label); mem = BIO_new_mem_buf(obj->content.value, (int)obj->content.len); - if (!mem) + if (!mem) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: invalid data"); + } x = d2i_X509_bio(mem, NULL); - if (!x) + if (!x) { + sc_log_openssl(ctx); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "AWP encode cert failed: x509 parse error"); + } buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE); if (!buff) @@ -975,6 +979,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ptr = buff; r = i2d_X509_NAME(X509_get_subject_name(x),&ptr); if (r<=0) { + sc_log_openssl(ctx); r = SC_ERROR_INTERNAL; LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: cannot get SubjectName"); } @@ -993,6 +998,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob ptr = buff; r = i2d_X509_NAME(X509_get_issuer_name(x),&ptr); if (r <= 0) { + sc_log_openssl(ctx); r = SC_ERROR_INTERNAL; LOG_TEST_GOTO_ERR(ctx, r, "AWP encode cert failed: cannot get IssuerName"); } From b9ec918fa0efa3ef3d511bd6735d29e7b1016ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:12:46 +0100 Subject: [PATCH 3401/4321] sm-common: Update OpenSSL logging --- src/sm/sm-common.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index 778ffb2f06..faa9107b54 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -204,6 +204,7 @@ DES_cbc_cksum_3des_emv96(struct sc_context *ctx, if (l > 8) { alg = sc_evp_cipher(ctx, "DES-CBC"); if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -212,12 +213,14 @@ DES_cbc_cksum_3des_emv96(struct sc_context *ctx, EVP_CIPHER_CTX_set_padding(cctx, 0); for (; l > 8; l -= 8, in += 8) { if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -230,6 +233,7 @@ DES_cbc_cksum_3des_emv96(struct sc_context *ctx, memcpy(tmpout, outv, 4); alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); if (!EVP_EncryptInit_ex2(cctx, alg, key, outv, NULL)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -237,11 +241,13 @@ DES_cbc_cksum_3des_emv96(struct sc_context *ctx, /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, (int)l)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -327,6 +333,7 @@ DES_cbc_cksum_3des(struct sc_context *ctx, cctx = EVP_CIPHER_CTX_new(); alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -335,12 +342,14 @@ DES_cbc_cksum_3des(struct sc_context *ctx, EVP_CIPHER_CTX_set_padding(cctx, 0); for (; l > 0; l -= 8, in += 8) { if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; @@ -420,6 +429,7 @@ sm_encrypt_des_ecb3(struct sc_context *ctx, return SC_SUCCESS; err: + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); free(*out); @@ -472,6 +482,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, cctx = EVP_CIPHER_CTX_new(); alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); if (!EVP_DecryptInit_ex2(cctx, alg, key, icv, NULL)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); free(decrypted); @@ -480,6 +491,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_DecryptUpdate(cctx, decrypted, &tmplen, data, (int)data_len)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); free(decrypted); @@ -488,6 +500,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, decrypted_len = tmplen; if (!EVP_DecryptFinal_ex(cctx, decrypted + decrypted_len, &tmplen)) { + sc_log_openssl(ctx); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); free(decrypted); @@ -569,6 +582,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, cctx = EVP_CIPHER_CTX_new(); alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); if (!EVP_EncryptInit_ex2(cctx, alg, key, icv, NULL)) { + sc_log_openssl(ctx); free(*out); free(data); EVP_CIPHER_CTX_free(cctx); @@ -578,6 +592,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, (int)data_len)) { + sc_log_openssl(ctx); free(*out); free(data); EVP_CIPHER_CTX_free(cctx); @@ -587,6 +602,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, *out_len = tmplen; if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { + sc_log_openssl(ctx); free(*out); free(data); EVP_CIPHER_CTX_free(cctx); From 9f057efb2934f6c9ef8c6f356932a9e5b41a0d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:15:35 +0100 Subject: [PATCH 3402/4321] sm-eac: Update OpenSSL logging --- src/sm/sm-eac.c | 76 ++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 706b86cb61..488df79e62 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -32,8 +32,6 @@ #ifdef ENABLE_OPENSSL #include -#else -#define ssl_error(a) #endif char eac_default_flags = 0; @@ -238,7 +236,7 @@ static int encode_mse_cdata(struct sc_context *ctx, int protocol, if (chat) { encoded_chat_len = i2d_CVC_CHAT((CVC_CHAT *) chat, &encoded_chat); if (encoded_chat_len < 0) { - ssl_error(ctx); + sc_log_openssl(ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -676,8 +674,8 @@ int perform_pace(sc_card_t *card, pp = pace_input.certificate_description; if (!d2i_CVC_CERTIFICATE_DESCRIPTION(&desc, &pp, pace_input.certificate_description_length)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse certificate description."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -685,8 +683,8 @@ int perform_pace(sc_card_t *card, if (!bio_stdout) { bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); if (!bio_stdout) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create output buffer."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -695,8 +693,8 @@ int perform_pace(sc_card_t *card, printf("Certificate Description\n"); switch(certificate_description_print(bio_stdout, desc, 8)) { case 0: + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print certificate description."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; break; @@ -731,8 +729,8 @@ int perform_pace(sc_card_t *card, if (!bio_stdout) { bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); if (!bio_stdout) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not create output buffer."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -740,16 +738,16 @@ int perform_pace(sc_card_t *card, pp = pace_input.chat; if (!d2i_CVC_CHAT(&chat, &pp, pace_input.chat_length)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse card holder authorization template (CHAT)."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } printf("Card holder authorization template (CHAT)\n"); if (!cvc_chat_print(bio_stdout, chat, 8)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print card holder authorization template (CHAT)."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -779,8 +777,8 @@ int perform_pace(sc_card_t *card, || !EAC_CTX_init_ef_cardaccess(pace_output->ef_cardaccess, pace_output->ef_cardaccess_length, eac_ctx) || !eac_ctx->pace_ctx) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse EF.CardAccess."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -798,7 +796,7 @@ int perform_pace(sc_card_t *card, enc_nonce = BUF_MEM_new(); if (!enc_nonce) { - ssl_error(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_OUT_OF_MEMORY; goto err; } @@ -816,15 +814,15 @@ int perform_pace(sc_card_t *card, sec = get_psec(card, (char *) pace_input.pin, pace_input.pin_length, pace_input.pin_id); if (!sec) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encode PACE secret."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } if (!PACE_STEP2_dec_nonce(eac_ctx, sec, enc_nonce)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt MRTD's nonce."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -832,8 +830,8 @@ int perform_pace(sc_card_t *card, mdata_opp = BUF_MEM_new(); mdata = PACE_STEP3A_generate_mapping_data(eac_ctx); if (!mdata || !mdata_opp) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate mapping data."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -850,8 +848,8 @@ int perform_pace(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length); if (!PACE_STEP3A_map_generator(eac_ctx, mdata_opp)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not map generator."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -859,9 +857,9 @@ int perform_pace(sc_card_t *card, pub = PACE_STEP3B_generate_ephemeral_key(eac_ctx); pub_opp = BUF_MEM_new(); if (!pub || !pub_opp) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate ephemeral domain parameter or " "ephemeral key pair."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -880,17 +878,17 @@ int perform_pace(sc_card_t *card, if (!PACE_STEP3B_compute_shared_secret(eac_ctx, pub_opp) || !PACE_STEP3C_derive_keys(eac_ctx)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute ephemeral shared secret or " "derive keys for encryption and authentication."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } token = PACE_STEP3D_compute_authentication_token(eac_ctx, pub_opp); token_opp = BUF_MEM_new(); if (!token || !token_opp) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute authentication token."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -909,16 +907,16 @@ int perform_pace(sc_card_t *card, token_opp->max = token_opp->length; if (!PACE_STEP3D_verify_authentication_token(eac_ctx, token_opp)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify authentication token."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } /* Initialize secure channel */ if (!EAC_CTX_set_encryption_ctx(eac_ctx, EAC_ID_PACE)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize encryption."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -927,8 +925,8 @@ int perform_pace(sc_card_t *card, comp_pub = EAC_Comp(eac_ctx, EAC_ID_PACE, pub); comp_pub_opp = EAC_Comp(eac_ctx, EAC_ID_PACE, pub_opp); if (!comp_pub || !comp_pub_opp) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compress public keys for identification."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1054,8 +1052,8 @@ static int eac_verify(sc_card_t *card, } if (0x80 & ASN1_get_object(&cert, &length, &tag, &class, cert_len)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error decoding Certificate"); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1153,8 +1151,8 @@ int perform_terminal_authentication(sc_card_t *card, if (!eac_ctx || !EAC_CTX_init_ef_cardaccess(ef_cardaccess, ef_cardaccess_length, eac_ctx)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse EF.CardAccess."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1179,7 +1177,7 @@ int perform_terminal_authentication(sc_card_t *card, if (!CVC_d2i_CVC_CERT(&cvc_cert, &cert, cert_len) || !cvc_cert || !cvc_cert->body || !cvc_cert->body->certificate_authority_reference || !cvc_cert->body->certificate_holder_reference) { - ssl_error(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INVALID_DATA; goto err; } @@ -1207,8 +1205,8 @@ int perform_terminal_authentication(sc_card_t *card, if (!EAC_CTX_init_ta(eacsmctx->ctx, privkey, privkey_len, cert, cert_len)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize TA."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1218,8 +1216,8 @@ int perform_terminal_authentication(sc_card_t *card, BUF_MEM_free(eacsmctx->eph_pub_key); eacsmctx->eph_pub_key = TA_STEP3_generate_ephemeral_key(eacsmctx->ctx); if (!eacsmctx->eph_pub_key) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate CA ephemeral key."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1236,7 +1234,7 @@ int perform_terminal_authentication(sc_card_t *card, nonce = BUF_MEM_create(TA_NONCE_LENGTH); if (!nonce) { - ssl_error(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1246,8 +1244,8 @@ int perform_terminal_authentication(sc_card_t *card, goto err; } if (!TA_STEP4_set_nonce(eacsmctx->ctx, nonce)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not set nonce for TA."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1261,8 +1259,8 @@ int perform_terminal_authentication(sc_card_t *card, signature = TA_STEP5_sign(eacsmctx->ctx, eacsmctx->eph_pub_key, eacsmctx->id_icc, eacsmctx->auxiliary_data); if (!signature) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate signature."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1410,8 +1408,8 @@ int perform_chip_authentication(sc_card_t *card, } picc_pubkey = CA_get_pubkey(eacsmctx->ctx, *ef_cardsecurity, *ef_cardsecurity_len); if (!picc_pubkey) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify EF.CardSecurity."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1444,8 +1442,8 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, picc_pubkey_buf = BUF_MEM_create_init(picc_pubkey, picc_pubkey_len); if (!picc_pubkey_buf) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify EF.CardSecurity."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1461,8 +1459,8 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, eph_pub_key = CA_STEP2_get_eph_pubkey(ctx); if (!eph_pub_key) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not derive keys."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1474,16 +1472,16 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, if (!CA_STEP4_compute_shared_secret(ctx, picc_pubkey_buf)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute shared secret."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } if (!CA_STEP6_derive_keys(ctx, nonce, token)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not derive keys."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1491,8 +1489,8 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, /* Initialize secure channel */ if (!EAC_CTX_set_encryption_ctx(ctx, EAC_ID_CA)) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize encryption."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1543,8 +1541,8 @@ eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, databuf = BUF_MEM_create_init(data, datalen); encbuf = EAC_encrypt(eacsmctx->ctx, databuf); if (!databuf || !encbuf || !encbuf->length) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt data."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1585,7 +1583,7 @@ eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, databuf = EAC_decrypt(eacsmctx->ctx, encbuf); if (!encbuf || !databuf || !databuf->length) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt data."); - ssl_error(card->ctx); + sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1630,9 +1628,9 @@ eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, macbuf = EAC_authenticate(eacsmctx->ctx, inbuf); if (!macbuf || !macbuf->length) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute message authentication code (MAC)."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1678,9 +1676,9 @@ eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, my_mac = EAC_authenticate(eacsmctx->ctx, inbuf); if (!my_mac) { + sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute message authentication code (MAC) for verification."); - ssl_error(card->ctx); r = SC_ERROR_INTERNAL; goto err; } From 96bec4ff8188bbca73093afdfd5806f10da516a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:19:05 +0100 Subject: [PATCH 3403/4321] npa-tool: Update OpenSSL logging --- src/tools/npa-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index b7dbac6458..872d298fea 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -598,15 +598,15 @@ main (int argc, char **argv) || !cvc_cert->body->certificate_authority_reference || !cvc_cert->body->chat) { fprintf(stderr, "Could not parse certificate.\n"); - ssl_error(ctx); + sc_log_openssl(ctx); r = SC_ERROR_INVALID_DATA; goto err; } pace_input.chat_length = i2d_CVC_CHAT(cvc_cert->body->chat, &certs_chat); if (0 >= (int) pace_input.chat_length) { fprintf(stderr, "Could not parse CHAT.\n"); + sc_log_openssl(ctx); r = SC_ERROR_INVALID_DATA; - ssl_error(ctx); goto err; } pace_input.chat = certs_chat; From b1193b43db2c800f7ea2d1acace43504c7b3943f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:30:42 +0100 Subject: [PATCH 3404/4321] Remove sslutil.h --- src/sm/Makefile.am | 1 - src/sm/sm-eac.c | 1 - src/sm/sslutil.h | 37 ------------------------------------- src/tools/npa-tool.c | 1 - 4 files changed, 40 deletions(-) delete mode 100644 src/sm/sslutil.h diff --git a/src/sm/Makefile.am b/src/sm/Makefile.am index 80c12b97b8..de375393dd 100644 --- a/src/sm/Makefile.am +++ b/src/sm/Makefile.am @@ -8,7 +8,6 @@ noinst_LTLIBRARIES = libsmiso.la libsmeac.la noinst_HEADERS = \ sm-iso-internal.h \ sm-iso.h \ - sslutil.h \ sm-eac.h if ENABLE_OPENSSL diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 488df79e62..83e9b551ea 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -26,7 +26,6 @@ #include "libopensc/log.h" #include "libopensc/opensc.h" #include "sm-eac.h" -#include "sslutil.h" #include #include diff --git a/src/sm/sslutil.h b/src/sm/sslutil.h deleted file mode 100644 index 2b194a77ab..0000000000 --- a/src/sm/sslutil.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2011-2015 Frank Morgner - * - * This file is part of OpenSC. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef _SC_SSLUTIL_H -#define _SC_SSLUTIL_H - -#include -#include - -#ifdef ENABLE_OPENSSL -#include - -#define ssl_error(ctx) { \ - unsigned long _r; \ - for (_r = ERR_get_error(); _r; _r = ERR_get_error()) { \ - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "%s", ERR_error_string(_r, NULL)); \ - } \ -} -#endif - -#endif diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 872d298fea..64c370594b 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -24,7 +24,6 @@ #include "fread_to_eof.h" #include "npa-tool-cmdline.h" #include "sm/sm-eac.h" -#include "sm/sslutil.h" #include "util.h" #include #include From ccb91bab08ecb3b969dc65b0144d1c3280437259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:31:05 +0100 Subject: [PATCH 3405/4321] cards-tool: Update OpenSSL logging --- src/tools/cardos-tool.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 9a45a0b92a..bef36efe65 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -44,6 +44,7 @@ #include "libopensc/opensc.h" #include "libopensc/cards.h" +#include "libopensc/log.h" #include "util.h" #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -446,6 +447,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { + sc_log_openssl(ctx); printf("Failed to load legacy provider, aborting\n"); free(mac_input); return 0; @@ -457,6 +459,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char if (!cctx || !EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key1, NULL) || !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -466,6 +469,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* first block: XOR with IV and encrypt with key A IV is 8 bytes 00 */ for (i=0; i < 8; i++) des_in[i] = mac_input[i]^00; if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -476,6 +480,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char for (j=1; j < (mac_input_len / 8); j++) { for (i=0; i < 8; i++) des_in[i] = mac_input[i+j*8]^des_out[i]; if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -483,6 +488,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char } } if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -493,6 +499,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* (a noop if key A and B are the same, e.g. 8 bytes ff */ if (!EVP_DecryptInit_ex(cctx, EVP_des_ecb(), NULL, key2, NULL) || !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -500,12 +507,14 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char } for (i=0; i < 8; i++) des_in[i] = des_out[i]; if (!EVP_DecryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); return 0; } if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -514,6 +523,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char if (!EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key1, NULL) || !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -521,12 +531,14 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char } for (i=0; i < 8; i++) des_in[i] = des_out[i]; if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); return 0; } if (!EVP_EncryptFinal_ex(cctx, des_out + tmplen, &tmplen)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); EVP_CIPHER_CTX_free(cctx); @@ -568,6 +580,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char if (!cctx || !EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) || !EVP_CIPHER_CTX_set_padding(cctx, 0)) { + sc_log_openssl(ctx); printf("Can not setup context, aborting\n"); free(mac_input); free(enc_input); @@ -580,6 +593,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* encrypt with des2 (triple des, but using keys A-B-A) */ if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); free(enc_input); @@ -597,6 +611,7 @@ static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char /* encrypt with des2 (triple des, but using keys A-B-A) */ if (!EVP_EncryptUpdate(cctx, des_out, &tmplen, des_in, 8)) { + sc_log_openssl(ctx); printf("Can not encrypt, aborting\n"); free(mac_input); free(enc_input); From 38b33744f88c2baad4b37cbb9af48dd6fa5f6842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 10:50:06 +0100 Subject: [PATCH 3406/4321] cryptoflex-tool: Update OpenSSL logging --- src/tools/cryptoflex-tool.c | 141 ++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 45 deletions(-) diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index f0f820b9b3..92f5dad928 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -22,6 +22,7 @@ #include "libopensc/sc-ossl-compat.h" #include "libopensc/internal.h" +#include "libopensc/log.h" #include #include #include @@ -210,7 +211,7 @@ static int parse_public_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) #if OPENSSL_VERSION_NUMBER < 0x30000000L RSA *rsa = NULL; #else - EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY_CTX *cctx = NULL; OSSL_PARAM *params = NULL; OSSL_PARAM_BLD *bld = NULL; #endif @@ -221,8 +222,10 @@ static int parse_public_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) } p += 3; n = BN_new(); - if (n == NULL) + if (n == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, 2 * base, n); p += 2 * base; p += base; @@ -234,33 +237,36 @@ static int parse_public_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) #if OPENSSL_VERSION_NUMBER < 0x30000000L if (!(rsa = RSA_new()) || - !(pkey = EVP_PKEY_new()) || - RSA_set0_key(rsa, n, e, NULL) != 1 || - EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + !(pkey = EVP_PKEY_new()) || + RSA_set0_key(rsa, n, e, NULL) != 1 || + EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + sc_log_openssl(ctx); RSA_free(rsa); EVP_PKEY_free(pkey); return -1; } #else - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (!ctx || - !(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", e) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + cctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!cctx || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); return -1; } OSSL_PARAM_BLD_free(bld); - if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { - return -1;; + if (EVP_PKEY_fromdata_init(cctx) != 1 || + EVP_PKEY_fromdata(cctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + sc_log_openssl(ctx); + return -1; } OSSL_PARAM_free(params); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); #endif return 0; } @@ -282,6 +288,7 @@ static int gen_d(BIGNUM **rsa_d_new, const BIGNUM *rsa_p, const BIGNUM *rsa_q, c BN_sub(r2, rsa_q, BN_value_one()); BN_mul(r0, r1, r2, bnctx); if ((*rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) { + sc_log_openssl(ctx); fprintf(stderr, "BN_mod_inverse() failed.\n"); return -1; } @@ -302,14 +309,16 @@ static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) const BIGNUM *rsa_n, *rsa_e; BIGNUM *rsa_n_new, *rsa_e_new ; RSA *rsa = NULL; - if (!(rsa = EVP_PKEY_get0_RSA(pkey))) + if (!(rsa = EVP_PKEY_get0_RSA(pkey))) { + sc_log_openssl(ctx); return -1; + } #else OSSL_PARAM *params = NULL, *pkey_params = NULL, *new_params = NULL; const OSSL_PARAM *e = NULL, *n = NULL; BIGNUM *rsa_n, *rsa_e; OSSL_PARAM_BLD *bld = NULL; - EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY_CTX *cctx = NULL; #endif base = (keysize - 3) / 5; @@ -319,57 +328,74 @@ static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) } p += 3; bn_p = BN_new(); - if (bn_p == NULL) + if (bn_p == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, base, bn_p); p += base; q = BN_new(); - if (q == NULL) + if (q == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, base, q); p += base; iqmp = BN_new(); - if (iqmp == NULL) + if (iqmp == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, base, iqmp); p += base; dmp1 = BN_new(); - if (dmp1 == NULL) + if (dmp1 == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, base, dmp1); p += base; dmq1 = BN_new(); - if (dmq1 == NULL) + if (dmq1 == NULL) { + sc_log_openssl(ctx); return -1; + } cf2bn(p, base, dmq1); #if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); if (RSA_set0_factors(rsa, bn_p, q) != 1 || - RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1 || - gen_d(&rsa_d, bn_p, q, rsa_n, rsa_e) != 0) + RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1 || + gen_d(&rsa_d, bn_p, q, rsa_n, rsa_e) != 0) { + sc_log_openssl(ctx); return -1; + } /* RSA_set0_key will free previous value, and replace with new value * Thus the need to copy the contents of rsa_n and rsa_e */ rsa_n_new = BN_dup(rsa_n); rsa_e_new = BN_dup(rsa_e); - if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d) != 1) + if (!rsa_n_new || !rsa_e_new || + RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d) != 1) { + sc_log_openssl(ctx); return -1; + } #else /* Extract parameters from pkey */ if (EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &pkey_params) != 1) { + sc_log_openssl(ctx); return -1; - } + } e = OSSL_PARAM_locate_const(pkey_params, "e"); n = OSSL_PARAM_locate_const(pkey_params, "n"); - if (!e || !n) { + if (!e || !n) { + sc_log_openssl(ctx); OSSL_PARAM_free(pkey_params); return -1; } @@ -378,32 +404,36 @@ static int parse_private_key(const u8 *key, size_t keysize, EVP_PKEY *pkey) gen_d(&rsa_d, bn_p, q, rsa_n, rsa_e); /* Merge params*/ if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "d", rsa_d) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "rsa-factor1", bn_p) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "rsa-factor2", q) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent1", dmp1) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent2", dmq1) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "rsa-coefficient1", iqmp) != 1 || - !(new_params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_push_BN(bld, "d", rsa_d) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-factor1", bn_p) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-factor2", q) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent1", dmp1) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-exponent2", dmq1) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "rsa-coefficient1", iqmp) != 1 || + !(new_params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(ctx); OSSL_PARAM_free(pkey_params); OSSL_PARAM_BLD_free(bld); return -1; } OSSL_PARAM_BLD_free(bld); if (!(params = OSSL_PARAM_merge(pkey_params, new_params))) { + sc_log_openssl(ctx); OSSL_PARAM_free(pkey_params); OSSL_PARAM_free(new_params); return -1; } /* Create pkey from params */ - if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || - EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) + if (!(cctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || + EVP_PKEY_fromdata_init(cctx) != 1 || + EVP_PKEY_fromdata(cctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) { rv = -1; + sc_log_openssl(ctx); + } OSSL_PARAM_free(pkey_params); OSSL_PARAM_free(new_params); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); #endif return rv; } @@ -517,6 +547,7 @@ static int read_key(void) r = i2d_PUBKEY(pkey, &p); if (r <= 0) { + sc_log_openssl(ctx); fprintf(stderr, "Error encoding public key.\n"); return -1; } @@ -535,6 +566,7 @@ static int read_key(void) p = buf; r = i2d_PrivateKey(pkey, &p); if (r <= 0) { + sc_log_openssl(ctx); fprintf(stderr, "Error encoding private key.\n"); return -1; } @@ -738,24 +770,40 @@ static int read_rsa_privkey(EVP_PKEY **pkey_out) in = BIO_new(BIO_s_file()); if (opt_prkeyf == NULL) { + sc_log_openssl(ctx); fprintf(stderr, "Private key file must be set.\n"); return 2; } r = BIO_read_filename(in, opt_prkeyf); if (r <= 0) { + sc_log_openssl(ctx); perror(opt_prkeyf); return 2; } #if OPENSSL_VERSION_NUMBER < 0x30000000L rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); if (rsa == NULL) { + sc_log_openssl(ctx); fprintf(stderr, "Unable to load private key.\n"); + BIO_free(in); + return 2; + } + if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + sc_log_openssl(ctx); + fprintf(stderr, "Unable to set private key.\n"); + RSA_free(rsa); + BIO_free(in); return 2; } - EVP_PKEY_assign_RSA(pkey, rsa); #else dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA", OSSL_KEYMGMT_SELECT_KEYPAIR, NULL, NULL); - OSSL_DECODER_from_bio(dctx, in); + if (!dctx || OSSL_DECODER_from_bio(dctx, in) != 1) { + sc_log_openssl(ctx); + fprintf(stderr, "Unable to initialite decoder.\n"); + OSSL_DECODER_CTX_free(dctx); + BIO_free(in); + return 2; + } #endif BIO_free(in); *pkey_out = pkey; @@ -802,7 +850,8 @@ static int encode_private_key(EVP_PKEY *pkey, u8 *key, size_t *keysize) RSA_get0_factors(rsa, &rsa_p, &rsa_q); #else if (EVP_PKEY_get_bn_param(pkey, "rsa-factor1", &rsa_p) != 1 || - EVP_PKEY_get_bn_param(pkey, "rsa-factor2", &rsa_q) != 1) { + EVP_PKEY_get_bn_param(pkey, "rsa-factor2", &rsa_q) != 1) { + sc_log_openssl(ctx); fprintf(stderr, "Invalid private key.\n"); rv = 2; goto end; @@ -831,8 +880,9 @@ static int encode_private_key(EVP_PKEY *pkey, u8 *key, size_t *keysize) RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp); #else if (EVP_PKEY_get_bn_param(pkey, "rsa-exponent1", &rsa_dmp1) != 1 || - EVP_PKEY_get_bn_param(pkey, "rsa-exponent2", &rsa_dmq1) != 1 || - EVP_PKEY_get_bn_param(pkey, "rsa-coefficient1", &rsa_iqmp) != 1) { + EVP_PKEY_get_bn_param(pkey, "rsa-exponent2", &rsa_dmq1) != 1 || + EVP_PKEY_get_bn_param(pkey, "rsa-coefficient1", &rsa_iqmp) != 1) { + sc_log_openssl(ctx); fprintf(stderr, "Invalid private key.\n"); rv = 2; goto end; @@ -921,7 +971,8 @@ static int encode_public_key(EVP_PKEY *pkey, u8 *key, size_t *keysize) RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); #else if (EVP_PKEY_get_bn_param(pkey, "n", &rsa_n) != 1 || - EVP_PKEY_get_bn_param(pkey, "e", &rsa_e) != 1) { + EVP_PKEY_get_bn_param(pkey, "e", &rsa_e) != 1) { + sc_log_openssl(ctx); fprintf(stderr, "Invalid public key.\n"); rv = 2; goto end; From d1a1180a3561fe3d39f97f53ab72748fcf731efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 13:26:34 +0100 Subject: [PATCH 3407/4321] netkey-tool: Update OpenSSL logging --- src/tools/netkey-tool.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 0ee76d850f..23bab2a8ec 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -29,6 +29,7 @@ #include #include "libopensc/opensc.h" +#include "libopensc/log.h" static struct { const char *path; @@ -144,12 +145,25 @@ static void show_certs(sc_card_t *card) printf(", Len=%d\n", (q[2]<<8)|q[3]); if((c=d2i_X509(NULL,&q,f->size))){ char buf2[2000]; - X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2,sizeof(buf2)); + if (X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + sc_log_openssl(card->ctx); + printf(" Invalid Subject-CN\n"); + X509_free(c); + continue; + } printf(" Subject-CN: %s\n", buf2); - X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2,sizeof(buf2)); + if (X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + sc_log_openssl(card->ctx); + printf(" Invalid Issuer-CN\n"); + X509_free(c); + continue; + } printf(" Issuer-CN: %s\n", buf2); X509_free(c); - } else printf(" Invalid Certificate-Data\n"); + } else { + sc_log_openssl(card->ctx); + printf(" Invalid Certificate-Data\n"); + } } else printf(", empty\n"); } } @@ -339,6 +353,7 @@ static void handle_readcert(sc_card_t *card, long cert, char *file) q=buf; if(q[0]==0x30 && q[1]==0x82 && q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6; if((c=d2i_X509(NULL,&q,len))==NULL){ + sc_log_openssl(card->ctx); printf("cardfile contains %d bytes which are not a certificate\n", len); return; } @@ -346,8 +361,12 @@ static void handle_readcert(sc_card_t *card, long cert, char *file) if((fp=fopen(file,"w"))==NULL) printf("Cannot open file, %s\n", strerror(errno)); else { fprintf(fp,"Certificate %ld from Netkey E4 card\n\n", cert); - PEM_write_X509(fp,c); - printf("OK\n"); + if (PEM_write_X509(fp, c) != 1) { + sc_log_openssl(card->ctx); + printf("Cannot write certificate %ld\n", cert); + } else { + printf("OK\n"); + } } X509_free(c); } From 8dd1ae37eabc3a48d47226a1cd72ca0555023121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 13:26:52 +0100 Subject: [PATCH 3408/4321] piv-tool: Update OpenSSL logging --- src/tools/piv-tool.c | 104 +++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 81a1574ea1..799cae3858 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -58,6 +58,7 @@ #include "libopensc/cardctl.h" #include "libopensc/cards.h" #include "libopensc/asn1.h" +#include "libopensc/log.h" #include "util.h" #include "libopensc/sc-ossl-compat.h" @@ -214,9 +215,9 @@ static int load_cert(const char * cert_id, const char * cert_file, } else { cert = PEM_read_X509(fp, &cert, NULL, NULL); if(cert == NULL){ - printf("file %s does not contain PEM-encoded certificate\n", - cert_file); - goto err; + sc_log_openssl(ctx); + printf("file %s does not contain PEM-encoded certificate\n", cert_file); + goto err; } derlen = i2d_X509(cert, NULL); @@ -337,14 +338,19 @@ static int gen_key(const char * key_info) #if OPENSSL_VERSION_NUMBER < 0x30000000L evpkey = EVP_PKEY_new(); + if (!evpkey) { + sc_log_openssl(ctx); + fprintf(stderr, "allocation of key failed\n"); + return r; + } #endif if (keydata.key_bits > 0) { /* RSA key */ BIGNUM *newkey_n, *newkey_e; #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA * newkey = NULL; - newkey = RSA_new(); - if (newkey == NULL) { + RSA *newkey = RSA_new(); + if (!newkey) { + sc_log_openssl(ctx); EVP_PKEY_free(evpkey); free(keydata.pubkey); free(keydata.exponent); @@ -352,7 +358,7 @@ static int gen_key(const char * key_info) return -1; } #else - EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY_CTX *cctx = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; #endif @@ -369,31 +375,50 @@ static int gen_key(const char * key_info) } newkey_n = BN_bin2bn(keydata.pubkey, (int)keydata.pubkey_len, NULL); - newkey_e = BN_bin2bn(keydata.exponent, (int)keydata.exponent_len, NULL); + newkey_e = BN_bin2bn(keydata.exponent, (int)keydata.exponent_len, NULL); free(keydata.pubkey); keydata.pubkey_len = 0; free(keydata.exponent); keydata.exponent_len = 0; + if (!newkey_n || !newkey_e) { + sc_log_openssl(ctx); + EVP_PKEY_free(evpkey); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + RSA_free(newkey); +#endif + fprintf(stderr, "conversion or key params failed %d\n", r); + return -1; + } #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { - fprintf(stderr, "gen_key unable to set RSA values"); + sc_log_openssl(ctx); EVP_PKEY_free(evpkey); RSA_free(newkey); BN_free(newkey_n); BN_free(newkey_e); + fprintf(stderr, "gen_key unable to set RSA values"); return -1; } if (verbose) - RSA_print_fp(stdout, newkey,0); + RSA_print_fp(stdout, newkey, 0); - EVP_PKEY_assign_RSA(evpkey, newkey); + if (EVP_PKEY_assign_RSA(evpkey, newkey) != 1) { + sc_log_openssl(ctx); + EVP_PKEY_free(evpkey); + RSA_free(newkey); + BN_free(newkey_n); + BN_free(newkey_e); + fprintf(stderr, "gen_key unable to set RSA values"); + return -1; + } #else if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_BN(bld, "n", newkey_n) != 1 || OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); BN_free(newkey_n); BN_free(newkey_e); @@ -403,32 +428,33 @@ static int gen_key(const char * key_info) BN_free(newkey_n); BN_free(newkey_e); - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (!ctx || - EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { - fprintf(stderr, "gen_key unable to gen RSA"); - EVP_PKEY_CTX_free(ctx); + cctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!cctx || + EVP_PKEY_fromdata_init(cctx) != 1 || + EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + sc_log_openssl(ctx); + EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); + fprintf(stderr, "gen_key unable to gen RSA"); return -1; } if (verbose) EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); #endif } else { /* EC key */ #if !defined(OPENSSL_NO_EC) int i; - BIGNUM *x; - BIGNUM *y; + BIGNUM *x = NULL; + BIGNUM *y = NULL; EC_GROUP * ecgroup = NULL; EC_POINT * ecpoint = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY * eckey = NULL; #else - EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY_CTX *cctx = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; size_t len = 0; @@ -450,6 +476,17 @@ static int gen_key(const char * key_info) i = (int)(keydata.ecpoint_len - 1)/2; x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; + if (!x || !y) { + sc_log_openssl(ctx); + free(keydata.ecpoint); + keydata.ecpoint_len = 0; + BN_free(x); + BN_free(y); + EVP_PKEY_free(evpkey); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + return -1; + } r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); free(keydata.ecpoint); @@ -458,6 +495,7 @@ static int gen_key(const char * key_info) BN_free(y); if (r == 0) { + sc_log_openssl(ctx); fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EVP_PKEY_free(evpkey); EC_GROUP_free(ecgroup); @@ -469,6 +507,7 @@ static int gen_key(const char * key_info) r = EC_KEY_set_group(eckey, ecgroup); EC_GROUP_free(ecgroup); if (r == 0) { + sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_group failed\n"); EVP_PKEY_free(evpkey); EC_POINT_free(ecpoint); @@ -477,6 +516,7 @@ static int gen_key(const char * key_info) r = EC_KEY_set_public_key(eckey, ecpoint); EC_POINT_free(ecpoint); if (r == 0) { + sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_public_key failed\n"); EVP_PKEY_free(evpkey); return -1; @@ -485,17 +525,23 @@ static int gen_key(const char * key_info) if (verbose) EC_KEY_print_fp(stdout, eckey, 0); - EVP_PKEY_assign_EC_KEY(evpkey, eckey); + if (EVP_PKEY_assign_EC_KEY(evpkey, eckey) != 1) { + sc_log_openssl(ctx); + EVP_PKEY_free(evpkey); + return -1; + } #else group_name = OBJ_nid2sn(nid); len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL); if (!(buf = malloc(len))) { + sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_public_key out of memory\n"); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); return -1; } if (EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, buf, len, NULL) == 0) { + sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_public_key failed\n"); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); @@ -510,6 +556,7 @@ static int gen_key(const char * key_info) OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name)) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { + sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); free(buf); return -1; @@ -517,19 +564,20 @@ static int gen_key(const char * key_info) free(buf); OSSL_PARAM_BLD_free(bld); - ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); - if (!ctx || - EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + cctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + if (!cctx || + EVP_PKEY_fromdata_init(cctx) != 1 || + EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + sc_log_openssl(ctx); fprintf(stderr, "gen_key unable to gen EC key"); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); return -1; } if (verbose) EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); #endif #else /* OPENSSL_NO_EC */ From 5367917083517096d559ccb4d529be94c8eb1958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 14:00:58 +0100 Subject: [PATCH 3409/4321] pkcs15-crypt: Remove unneeded openssl headers --- src/tools/pkcs15-crypt.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 307ae7bafb..4d7147cb73 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -27,11 +27,6 @@ #endif #include #include -#ifdef ENABLE_OPENSSL -#include -#include -#include -#endif #include "common/compat_getpass.h" #include "libopensc/internal.h" From 25c65ae04a2ee84b669653898eb807fba4e60d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 14:02:33 +0100 Subject: [PATCH 3410/4321] pkcs15-init: Update OpenSSL logging --- src/tools/pkcs15-init.c | 63 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 9594b460d0..3759e252ee 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -118,7 +118,6 @@ static int do_read_public_key(const char *, const char *, EVP_PKEY **); static int do_read_certificate(const char *, const char *, X509 **); static char * cert_common_name(X509 *x509); static void parse_commandline(int argc, char **argv); -static void ossl_print_errors(void); static int verify_pin(struct sc_pkcs15_card *, char *); enum { @@ -1032,6 +1031,7 @@ do_store_private_key(struct sc_profile *profile) r = sc_pkcs15_convert_prkey(&args.key, pkey); if (r < 0) { EVP_PKEY_free(pkey); + sc_log_openssl(g_ctx); return r; } init_gost_params(&args.params.gost, pkey); @@ -1214,6 +1214,7 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey) } if (r >= 0) { r = sc_pkcs15_convert_pubkey(&args.key, pkey); + sc_log_openssl(g_ctx); if (r >= 0) init_gost_params(&args.params.gost, pkey); } @@ -1320,7 +1321,7 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, const char *filename, const char *format, sc_pkcs15_der_t *newcert_raw) { X509 *oldcert, *newcert; - EVP_PKEY *oldpk, *newpk; + EVP_PKEY *oldpk = NULL, *newpk = NULL; int oldpk_type, newpk_type; const u8 *ptr; int r; @@ -1329,8 +1330,10 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, ptr = sc_oldcert->data.value; oldcert = d2i_X509(NULL, &ptr, sc_oldcert->data.len); - if (oldcert == NULL) + if (oldcert == NULL) { + sc_log_openssl(g_ctx); return SC_ERROR_INTERNAL; + } /* Read the new cert from file and get it's public key */ r = do_read_certificate(filename, format, &newcert); @@ -1341,6 +1344,13 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, oldpk = X509_get_pubkey(oldcert); newpk = X509_get_pubkey(newcert); + if (!oldpk || !newpk) { + EVP_PKEY_free(newpk); + EVP_PKEY_free(oldpk); + X509_free(oldcert); + sc_log_openssl(g_ctx); + return SC_ERROR_INTERNAL; + } oldpk_type = EVP_PKEY_base_id(oldpk); newpk_type = EVP_PKEY_base_id(newpk); @@ -2276,7 +2286,7 @@ do_read_pem_private_key(const char *filename, const char *passphrase, *key = PEM_read_bio_PrivateKey(bio, NULL, pass_cb, (char *) passphrase); BIO_free(bio); if (*key == NULL) { - ossl_print_errors(); + sc_log_openssl(g_ctx); return SC_ERROR_CANNOT_LOAD_KEY; } return 0; @@ -2330,7 +2340,8 @@ do_read_pkcs12_private_key(const char *filename, const char *passphrase, *key = user_key; return ncerts; -error: ossl_print_errors(); +error: + sc_log_openssl(g_ctx); return SC_ERROR_CANNOT_LOAD_KEY; } @@ -2396,7 +2407,7 @@ do_read_pem_public_key(const char *filename) pk = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); BIO_free(bio); if (pk == NULL) - ossl_print_errors(); + sc_log_openssl(g_ctx); return pk; } @@ -2412,7 +2423,7 @@ do_read_der_public_key(const char *filename) pk = d2i_PUBKEY_bio(bio, NULL); BIO_free(bio); if (pk == NULL) - ossl_print_errors(); + sc_log_openssl(g_ctx); return pk; } @@ -2449,7 +2460,7 @@ do_read_pem_certificate(const char *filename) xp = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (xp == NULL) - ossl_print_errors(); + sc_log_openssl(g_ctx); return xp; } @@ -2465,7 +2476,7 @@ do_read_der_certificate(const char *filename) xp = d2i_X509_bio(bio, NULL); BIO_free(bio); if (xp == NULL) - ossl_print_errors(); + sc_log_openssl(g_ctx); return xp; } @@ -2482,8 +2493,10 @@ do_read_certificate(const char *name, const char *format, X509 **out) format); } - if (!*out) + if (!*out) { + sc_log_openssl(g_ctx); util_fatal("Unable to read certificate from %s\n", name); + } return 0; } @@ -2542,20 +2555,28 @@ cert_common_name(X509 *x509) int idx, out_len = 0; idx = X509_NAME_get_index_by_NID(X509_get_subject_name(x509), NID_commonName, -1); - if (idx < 0) + if (idx < 0) { + sc_log_openssl(g_ctx); return NULL; + } ne = X509_NAME_get_entry(X509_get_subject_name(x509), idx); - if (!ne) - return NULL; + if (!ne) { + sc_log_openssl(g_ctx); + return NULL; + } a_str = X509_NAME_ENTRY_get_data(ne); - if (!a_str) + if (!a_str) { + sc_log_openssl(g_ctx); return NULL; + } out_len = ASN1_STRING_to_UTF8(&tmp, a_str); - if (!tmp) + if (!tmp) { + sc_log_openssl(g_ctx); return NULL; + } out = calloc(1, out_len + 1); if (out) @@ -2972,18 +2993,6 @@ next: ; } } -/* - * OpenSSL helpers - */ -static void -ossl_print_errors(void) -{ - long err; - - while ((err = ERR_get_error()) != 0) - fprintf(stderr, "%s\n", ERR_error_string(err, NULL)); -} - /* * Retrieve a PIN from the user. * From 7227b422bbe1b672816261d18cb5358de2c9a618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 31 Oct 2023 15:36:17 +0100 Subject: [PATCH 3411/4321] sc-hsm-tool: Update OpenSSL logging --- src/tools/sc-hsm-tool.c | 55 ++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index e3f9d9e0d6..e3b20ba33c 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -780,7 +780,6 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas clearScreen(); r = reconstructSecret(shares, num_of_password_shares, prime, secret); - if (r < 0) { printf("\nError during reconstruction of secret. Wrong shares?\n"); cleanUpShares(shares, num_of_password_shares); @@ -850,6 +849,7 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c printf("\n"); } else { r = recreate_password_from_shares(&pwd, &pwdlen, num_of_password_shares); + sc_log_openssl(card->ctx); if (r < 0) { return -1; } @@ -869,16 +869,16 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c } bn_ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { - fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); - return -1; - } - - if (!EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { + if (!bn_ctx || + !EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv) || + !EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16) || + !EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { + sc_log_openssl(card->ctx); + EVP_CIPHER_CTX_free(bn_ctx); fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } + EVP_CIPHER_CTX_free(bn_ctx); memset(&dkekinfo, 0, sizeof(dkekinfo)); memcpy(dkekinfo.dkek_share, outbuff, sizeof(dkekinfo.dkek_share)); @@ -889,7 +889,6 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, (void *)&dkekinfo); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_free(bn_ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -970,16 +969,16 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch } bn_ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { - fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); - return -1; - } - - if (!EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { + if (!bn_ctx || + !EVP_DecryptInit_ex(bn_ctx, EVP_aes_256_cbc(), NULL, key, iv) || + !EVP_DecryptUpdate(bn_ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16) || + !EVP_DecryptFinal_ex(bn_ctx, outbuff + outlen, &r)) { + sc_log_openssl(card->ctx); + EVP_CIPHER_CTX_free(bn_ctx); fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } + EVP_CIPHER_CTX_free(bn_ctx); memset(&dkekinfo, 0, sizeof(dkekinfo)); memcpy(dkekinfo.dkek_share, outbuff, sizeof(dkekinfo.dkek_share)); @@ -996,7 +995,6 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch printf("\n\n"); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_free(bn_ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -1123,6 +1121,8 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas r = sc_get_challenge(card, rngseed, SEED_LENGTH); if (r < 0) { printf("Error generating random seed failed with %s", sc_strerror(r)); + BN_clear_free(prime); + BN_clear_free(secret); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); return r; @@ -1130,6 +1130,9 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas r = generatePrime(prime, secret, 64, rngseed, SEED_LENGTH); if (r < 0) { + sc_log_openssl(card->ctx); + BN_clear_free(prime); + BN_clear_free(secret); printf("Error generating valid prime number. Please try again."); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); @@ -1140,7 +1143,10 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas shares = malloc(password_shares_total * sizeof(secret_share_t)); if (!shares || 0 > createShares(secret, password_shares_threshold, password_shares_total, prime, shares)) { + sc_log_openssl(card->ctx); printf("Error generating Shares. Please try again."); + BN_clear_free(prime); + BN_clear_free(secret); OPENSSL_cleanse(*pwd, *pwdlen); free(*pwd); free(shares); @@ -1239,16 +1245,16 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const } c_ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(c_ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_EncryptUpdate(c_ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { - fprintf(stderr, "Error encrypting DKEK share\n"); - return -1; - } - - if (!EVP_EncryptFinal_ex(c_ctx, filebuff + 16 + outlen, &r)) { + if (!c_ctx || + !EVP_EncryptInit_ex(c_ctx, EVP_aes_256_cbc(), NULL, key, iv) || + !EVP_EncryptUpdate(c_ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share)) || + !EVP_EncryptFinal_ex(c_ctx, filebuff + 16 + outlen, &r)) { + sc_log_openssl(card->ctx); + EVP_CIPHER_CTX_free(c_ctx); fprintf(stderr, "Error encrypting DKEK share\n"); return -1; } + EVP_CIPHER_CTX_free(c_ctx); out = fopen(outf, "wb"); @@ -1266,7 +1272,6 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const fclose(out); OPENSSL_cleanse(filebuff, sizeof(filebuff)); - EVP_CIPHER_CTX_free(c_ctx); printf("DKEK share created and saved to %s\n", outf); return 0; From 6fee632515b0583c7d35db7d9c3f2a7631a61d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 6 Feb 2024 13:11:53 +0100 Subject: [PATCH 3412/4321] piv-tool: Reformat code --- src/tools/piv-tool.c | 53 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 799cae3858..fd37a82722 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -123,14 +123,14 @@ static int load_object(const char * object_id, const char * object_file) int r = -1; struct stat stat_buf; - if(!object_file || (fp=fopen(object_file, "rb")) == NULL){ - printf("Cannot open object file, %s %s\n", - (object_file)?object_file:"", strerror(errno)); + if (!object_file || (fp = fopen(object_file, "rb")) == NULL) { + printf("Cannot open object file, %s %s\n", + (object_file) ? object_file : "", strerror(errno)); goto err; - } + } if (0 != stat(object_file, &stat_buf)) { - printf("unable to read file %s\n",object_file); + printf("unable to read file %s\n", object_file); goto err; } derlen = stat_buf.st_size; @@ -146,7 +146,7 @@ static int load_object(const char * object_id, const char * object_file) } /* check if tag and length are valid */ body = (u8 *)sc_asn1_find_tag(card->ctx, der, derlen, 0x53, &bodylen); - if (body == NULL || derlen != body - der + bodylen) { + if (body == NULL || derlen != body - der + bodylen) { fprintf(stderr, "object tag or length not valid\n"); goto err; } @@ -185,20 +185,20 @@ static int load_cert(const char * cert_id, const char * cert_file, int r = -1; if (!cert_file) { - printf("Missing cert file\n"); + printf("Missing cert file\n"); goto err; } - if((fp=fopen(cert_file, "rb"))==NULL){ - printf("Cannot open cert file, %s %s\n", + if ((fp = fopen(cert_file, "rb")) == NULL) { + printf("Cannot open cert file, %s %s\n", cert_file, strerror(errno)); - goto err; - } + goto err; + } if (compress) { /* file is gzipped already */ struct stat stat_buf; if (0 != stat(cert_file, &stat_buf)) { - printf("unable to read file %s\n",cert_file); + printf("unable to read file %s\n", cert_file); goto err; } derlen = stat_buf.st_size; @@ -209,16 +209,16 @@ static int load_cert(const char * cert_id, const char * cert_file, goto err; } if (1 != fread(der, derlen, 1, fp)) { - printf("unable to read file %s\n",cert_file); + printf("unable to read file %s\n", cert_file); goto err; } } else { cert = PEM_read_X509(fp, &cert, NULL, NULL); - if(cert == NULL){ + if (cert == NULL) { sc_log_openssl(ctx); printf("file %s does not contain PEM-encoded certificate\n", cert_file); goto err; - } + } derlen = i2d_X509(cert, NULL); der = malloc(derlen); @@ -248,7 +248,7 @@ static int load_cert(const char * cert_id, const char * cert_file, } /* we pass length and 8 bits of flag to card-piv.c write_binary */ /* pass in its a cert and if needs compress */ - r = sc_write_binary(card, 0, der, derlen, (derlen<<8) | (compress<<4) | 1); + r = sc_write_binary(card, 0, der, derlen, (derlen << 8) | (compress << 4) | 1); err: free(der); @@ -270,7 +270,6 @@ static int admin_mode(const char* admin_info) (sc_hex_to_bin(admin_info+2, opts+1, &buflen) == 0) && buflen == 2) { opts[0] = admin_info[0]; - } else { fprintf(stderr, " admin_mode params ::\n"); return -1; @@ -415,9 +414,9 @@ static int gen_key(const char * key_info) } #else if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", newkey_n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_push_BN(bld, "n", newkey_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); BN_free(newkey_n); @@ -473,7 +472,7 @@ static int gen_key(const char * key_info) ecpoint = EC_POINT_new(ecgroup); /* PIV returns 04||x||y and x and y are the same size */ - i = (int)(keydata.ecpoint_len - 1)/2; + i = (int)(keydata.ecpoint_len - 1) / 2; x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; if (!x || !y) { @@ -553,9 +552,9 @@ static int gen_key(const char * key_info) EC_POINT_free(ecpoint); if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name)) != 1 || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name)) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); free(buf); @@ -566,8 +565,8 @@ static int gen_key(const char * key_info) cctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); if (!cctx || - EVP_PKEY_fromdata_init(cctx) != 1 || - EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { + EVP_PKEY_fromdata_init(cctx) != 1 || + EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) { sc_log_openssl(ctx); fprintf(stderr, "gen_key unable to gen EC key"); EVP_PKEY_CTX_free(cctx); @@ -749,7 +748,7 @@ int main(int argc, char *argv[]) if (out_file) { bp = BIO_new(BIO_s_file()); if (!BIO_write_filename(bp, (char *)out_file)) - goto end; + goto end; } else { bp = BIO_new(BIO_s_file()); BIO_set_fp(bp,stdout,BIO_NOCLOSE); From 69a18b85d91f5619c1db8d7764ee264d11e912c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 6 Feb 2024 15:04:32 +0100 Subject: [PATCH 3413/4321] card-gids: Reformat code --- src/libopensc/card-gids.c | 75 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 82966fac10..aa63035097 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -137,11 +137,10 @@ static struct gids_aid gids_aids[] = { // stolen from cardmod.h for the cardcf file typedef struct _CARD_CACHE_FILE_FORMAT { - unsigned char bVersion; // Cache version - unsigned char bPinsFreshness; // Card PIN - unsigned short wContainersFreshness; - unsigned short wFilesFreshness; - + unsigned char bVersion; // Cache version + unsigned char bPinsFreshness; // Card PIN + unsigned short wContainersFreshness; + unsigned short wFilesFreshness; } CARD_CACHE_FILE_FORMAT, *PCARD_CACHE_FILE_FORMAT; struct gids_private_data { @@ -194,7 +193,7 @@ static int gids_get_identifiers(sc_card_t* card, u8* masterfile, size_t masterfi return 0; } } - sc_log(card->ctx, "file %s %s not found\n", directory, filename); + sc_log(card->ctx, "file %s %s not found\n", directory, filename); return SC_ERROR_FILE_NOT_FOUND; } @@ -249,7 +248,7 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "gids get data failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize); if (!p) { @@ -288,7 +287,7 @@ static int gids_put_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "gids put data failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); return SC_SUCCESS; } @@ -311,13 +310,13 @@ static int gids_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response apdu.datalen = aidlen; apdu.resp = response; apdu.resplen = responselen ? *responselen : 0; - apdu.le = response == NULL ? 0 : 256; /* could be 21 for fci */ + apdu.le = response == NULL ? 0 : 256; /* could be 21 for fci */ r = sc_transmit_apdu(card, &apdu); if (responselen) *responselen = apdu.resplen; LOG_TEST_RET(card->ctx, r, "gids select failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } // DIRECT FILE MANIPULATION @@ -477,7 +476,7 @@ static int gids_create_file(sc_card_t *card, char* directory, char* filename) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_ENOUGH_MEMORY); } - records = ((privatedata->masterfilesize -1) / sizeof(gids_mf_record_t)); + records = ((privatedata->masterfilesize - 1) / sizeof(gids_mf_record_t)); offset = 1 + sizeof(gids_mf_record_t) * records; memcpy(masterfilebuffer + offset + sizeof(gids_mf_record_t), masterfilebuffer + offset, privatedata->masterfilesize - offset); @@ -902,7 +901,7 @@ static int gids_logout(sc_card_t *card) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } // read a public key @@ -939,12 +938,12 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "gids read public key failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); buffersize = apdu.resplen; keytemplate = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_PUBKEY_TAG, &tlen); if (keytemplate == NULL) { - sc_log(card->ctx, "invalid public key data: missing tag"); + sc_log(card->ctx, "invalid public key data: missing tag"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -968,7 +967,7 @@ static int gids_read_public_key (struct sc_card *card , unsigned int algorithm, r = sc_pkcs15_encode_pubkey_rsa(card->ctx, &rsa_key, response, responselen); LOG_TEST_RET(card->ctx, r, "failed to read public key: cannot encode RSA public key"); } else { - sc_log(card->ctx, "it is not a known public key"); + sc_log(card->ctx, "it is not a known public key"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -1024,7 +1023,7 @@ static int gids_select_file(sc_card_t *card, const struct sc_path *in_path, static int gids_get_pin_policy(struct sc_card *card, struct sc_pin_cmd_data *data) { int r; - if (data->pin_type != SC_AC_CHV) { + if (data->pin_type != SC_AC_CHV) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } r = gids_get_pin_status(card, data->pin_reference, &(data->pin1.tries_left), &(data->pin1.max_tries)); @@ -1075,7 +1074,7 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, data->buffersize = sizeof(data->buffer) - 4; memcpy(data->buffer, buffer + 4, buffersize); } else { - sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] <<8)); + sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] << 8)); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } data->state = GIDS_STATE_READ_DATA_PRESENT; @@ -1184,7 +1183,7 @@ gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) { // key was specified. Search if the key can be used size_t i = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER; if (i > GIDS_MAX_CONTAINER) { - sc_log(card->ctx, "invalid key ref %d", key_info->key_reference); + sc_log(card->ctx, "invalid key ref %d", key_info->key_reference); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (i > recordsnum) { @@ -1496,11 +1495,11 @@ static int gids_import_key(sc_card_t *card, sc_pkcs15_object_t *object, sc_pkcs1 assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) { - sc_log(card->ctx, "GIDS supports RSA keys only (but may support ECC one day)."); + sc_log(card->ctx, "GIDS supports RSA keys only (but may support ECC one day)."); return SC_ERROR_NOT_SUPPORTED; } if (!key->u.rsa.dmp1.len || !key->u.rsa.dmq1.len || !key->u.rsa.iqmp.len) { - sc_log(card->ctx, "GIDS needs dmp1 & dmq1 & iqmp"); + sc_log(card->ctx, "GIDS needs dmp1 & dmq1 & iqmp"); return SC_ERROR_NOT_SUPPORTED; } sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 0, &version, NULL, 1); @@ -1770,14 +1769,14 @@ static int gids_initialize_create_file(sc_card_t *card, u8* command, size_t comm r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU1 transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // activate file sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU2 transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1918,12 +1917,12 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // activate file sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); LOG_FUNC_RETURN(card->ctx, r); } @@ -1963,7 +1962,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.datalen = 3; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // generate a challenge if (RAND_bytes(randomR1, 16) != 1) { @@ -1981,7 +1980,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.le = 256; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); // compute the half size of the mutual authentication secret if (RAND_bytes(z1, 7) != 1) { @@ -2000,7 +1999,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { sc_log_openssl(card->ctx); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { @@ -2017,7 +2016,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { + if (!EVP_EncryptFinal(ctx, buffer2 + buffer2size, &buffer2size)) { sc_log_openssl(card->ctx); EVP_CIPHER_CTX_free(ctx); sc_evp_cipher_free(cipher); @@ -2037,17 +2036,17 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { apdu.le = 256; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); if (apdu.resplen != 44) { - sc_log(card->ctx, "Expecting a response len of 44 - found %d",(int) apdu.resplen); + sc_log(card->ctx, "Expecting a response len of 44 - found %d", (int)apdu.resplen); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } // init crypto ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { @@ -2059,36 +2058,36 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, (int)apdu.resplen - 4)) { sc_log_openssl(card->ctx); - sc_log(card->ctx, "unable to decrypt data"); + sc_log(card->ctx, "unable to decrypt data"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } - if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { + if (!EVP_DecryptFinal(ctx, buffer3 + buffer3size, &buffer3size)) { sc_log_openssl(card->ctx); - sc_log(card->ctx, "unable to decrypt final data"); + sc_log(card->ctx, "unable to decrypt final data"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } - sc_log(card->ctx, "data has been decrypted using the key"); + sc_log(card->ctx, "data has been decrypted using the key"); if (memcmp(buffer3, randomR1, 16) != 0) { sc_log_openssl(card->ctx); - sc_log(card->ctx, "R1 doesn't match"); + sc_log(card->ctx, "R1 doesn't match"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (memcmp(buffer3 + 16, randomR2, 16) != 0) { sc_log_openssl(card->ctx); - sc_log(card->ctx, "R2 doesn't match"); + sc_log(card->ctx, "R2 doesn't match"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (buffer[39] != 0x80) { sc_log_openssl(card->ctx); - sc_log(card->ctx, "Padding not found"); + sc_log(card->ctx, "Padding not found"); sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); From 4e0f42eed29a66d45707e4f9206ef8ceb2c0652e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 7 Feb 2024 08:55:18 +0100 Subject: [PATCH 3414/4321] npa-tool: Ordering of header files --- src/tools/npa-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 64c370594b..81a90a749d 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -25,8 +25,8 @@ #include "npa-tool-cmdline.h" #include "sm/sm-eac.h" #include "util.h" -#include #include +#include #include #include #include From 03b7969d0ce84063ca6d6f773199a77936f3c63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 18 Mar 2024 14:18:06 +0100 Subject: [PATCH 3415/4321] pkcs15-crypt: Use correct PKCS#1 v1.5 padding type --- src/tools/pkcs15-crypt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 4d7147cb73..33ec134bbc 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -210,7 +210,7 @@ static int sign(struct sc_pkcs15_object *obj) { u8 buf[1024], out[1024]; struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) obj->data; - int r; + int r, flags; size_t c, len; if (opt_input == NULL) { @@ -233,7 +233,8 @@ static int sign(struct sc_pkcs15_object *obj) return SC_ERROR_NOT_SUPPORTED; } - r = sc_pkcs15_compute_signature(p15card, obj, opt_crypt_flags, buf, c, out, len, NULL); + flags = opt_crypt_flags & ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02; + r = sc_pkcs15_compute_signature(p15card, obj, flags, buf, c, out, len, NULL); if (r < 0) { fprintf(stderr, "Compute signature failed: %s\n", sc_strerror(r)); return 1; @@ -265,7 +266,7 @@ static int sign(struct sc_pkcs15_object *obj) static int decipher(struct sc_pkcs15_object *obj) { u8 buf[1024], out[1024]; - int r, len; + int r, len, flags; size_t c; if (opt_input == NULL) { @@ -281,7 +282,8 @@ static int decipher(struct sc_pkcs15_object *obj) return SC_ERROR_NOT_SUPPORTED; } - r = sc_pkcs15_decipher(p15card, obj, opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02, buf, c, out, len, NULL); + flags = opt_crypt_flags & ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01; + r = sc_pkcs15_decipher(p15card, obj, flags, buf, c, out, len, NULL); if (r < 0) { fprintf(stderr, "Decrypt failed: %s\n", sc_strerror(r)); return 1; From a94af7f6ca0c190cbe9eb92fc17d6814709693a9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 21 Mar 2024 01:56:03 +0100 Subject: [PATCH 3416/4321] ignore autogenerated files from bear and automake --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 46ab3925cb..0f744e252c 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ test-driver *.res *.ggo ChangeLog +.cache +compile_commands.json +.dirstamp doc/tools/*-tool doc/tools/eidenv From 993e6469bd1861a0c24d1b013d05a8518eda8af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 21 Mar 2024 09:24:57 +0100 Subject: [PATCH 3417/4321] card-epass2003: Check OpenSSL functions for error Thanks Coverity CID 424593, 424594 --- src/libopensc/card-epass2003.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 6af717e0d2..173629bbf3 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -293,8 +293,10 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto out; - EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp); - EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || + !EVP_CIPHER_CTX_set_padding(ctx, 0)) + goto out; if (!EVP_EncryptUpdate(ctx, output, &outl, input, (int)length)) goto out; @@ -304,8 +306,7 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned r = SC_SUCCESS; out: - if (ctx) - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(ctx); return r; } @@ -323,8 +324,10 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto out; - EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp); - EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || + !EVP_CIPHER_CTX_set_padding(ctx, 0)) + goto out; if (!EVP_DecryptUpdate(ctx, output, &outl, input, (int)length)) goto out; @@ -334,8 +337,7 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned r = SC_SUCCESS; out: - if (ctx) - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(ctx); return r; } From ede023433542b40ce72464774078278a0458d07f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 Mar 2024 16:19:49 +0100 Subject: [PATCH 3418/4321] pkcs11: improve logging Signed-off-by: Jakub Jelen --- src/pkcs11/mechanism.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index d3f0434231..0b49e2eda1 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -106,7 +106,7 @@ sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, *new_mt = calloc(1, sizeof(sc_pkcs11_mechanism_type_t)); if (!(*new_mt)) return CKR_HOST_MEMORY; - + memcpy(*new_mt, mt, sizeof(sc_pkcs11_mechanism_type_t)); /* mech_data needs specific function for making copy*/ if (mt->copy_mech_data @@ -114,7 +114,7 @@ sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, free(*new_mt); return rv; } - + return CKR_OK; } @@ -864,7 +864,6 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, if (key_type != CKK_GOSTR3410) attr.type = CKA_SPKI; - rv = key->ops->get_attribute(operation->session, key, &attr); if (rv != CKR_OK) @@ -1769,7 +1768,7 @@ CK_RV copy_hash_signature_info(const void *mech_data, void **new_data) *new_data = calloc(1, sizeof(struct hash_signature_info)); if (!(*new_data)) return CKR_HOST_MEMORY; - + memcpy(*new_data, mech_data, sizeof(struct hash_signature_info)); return CKR_OK; } @@ -1789,33 +1788,37 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_INFO mech_info; CK_RV rv; + LOG_FUNC_CALLED(p11card->card->ctx); + sc_log(p11card->card->ctx, "mech = %lx, hash_mech = %lx", mech, hash_mech); + if (!sign_type) - return CKR_MECHANISM_INVALID; + LOG_FUNC_RETURN(p11card->card->ctx, CKR_MECHANISM_INVALID); mech_info = sign_type->mech_info; if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST))) - return CKR_MECHANISM_INVALID; + LOG_FUNC_RETURN(p11card->card->ctx, CKR_MECHANISM_INVALID); /* These hash-based mechs can only be used for sign/verify */ mech_info.flags &= (CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER); info = calloc(1, sizeof(*info)); if (!info) - return CKR_HOST_MEMORY; + LOG_FUNC_RETURN(p11card->card->ctx, CKR_HOST_MEMORY); info->mech = mech; info->hash_type = hash_type; info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; - new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_types[0], info, free_info, copy_hash_signature_info); + new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_types[0], + info, free_info, copy_hash_signature_info); if (!new_type) { free_info(info); - return CKR_HOST_MEMORY; + LOG_FUNC_RETURN(p11card->card->ctx, CKR_HOST_MEMORY); } rv = sc_pkcs11_register_mechanism(p11card, new_type, NULL); sc_pkcs11_free_mechanism(&new_type); - return rv; + LOG_FUNC_RETURN(p11card->card->ctx, (int)rv); } From b492a4cd8c848c8c3b420542238729fe892fc852 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Mar 2024 13:42:10 +0100 Subject: [PATCH 3419/4321] pkcs11: Do not enable RSA-PSS HASH mechanisms without OpenSSL --- src/pkcs11/framework-pkcs15.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ac72532029..68b7a790dd 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6681,6 +6681,11 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rc != CKR_OK) return rc; +#ifdef ENABLE_OPENSSL + /* sc_pkcs11_register_sign_and_hash_mechanism expects software hash */ + /* All hashes are in OpenSSL + * Either the card set the hashes or we helped it above */ + if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, registered_mt); @@ -6711,6 +6716,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) if (rc != CKR_OK) return rc; } +#endif /* ENABLE_OPENSSL */ mech_info.flags = old_flags; } From a05ee98cba03f960cd29413ea34e6d025c3d442a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Mar 2024 13:58:27 +0100 Subject: [PATCH 3420/4321] Run basic tests without OpenSSL in CI --- .github/build.sh | 3 +++ .github/workflows/linux.yml | 7 +++++++ tests/Makefile.am | 7 +++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 7770590af1..1393c9d0e6 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -64,6 +64,9 @@ else if [ "$1" == "no-shared" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-shared" fi + if [ "$1" == "no-openssl" ]; then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-openssl" + fi export CFLAGS="-DDEBUG_PROFILE=1 $CFLAGS" ./configure $CONFIGURE_FLAGS make -j 4 V=1 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7f73b54a00..625459d1e4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -66,6 +66,13 @@ jobs: - run: .github/setup-linux.sh - run: .github/build.sh no-shared valgrind + build-no-openssl: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: .github/setup-linux.sh + - run: .github/build.sh no-openssl valgrind + build-ix86: runs-on: ubuntu-20.04 steps: diff --git a/tests/Makefile.am b/tests/Makefile.am index c275167ed3..6325f1d6c7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,9 +42,11 @@ TESTS = \ test-duplicate-symbols.sh \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ - test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ - test-pkcs11-tool-sym-crypt-test.sh \ + test-pkcs11-tool-sym-crypt-test.sh +if ENABLE_OPENSSL +TESTS += \ + test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-unwrap-wrap-test.sh \ test-pkcs11-tool-import.sh if ENABLE_TESTS @@ -52,6 +54,7 @@ if ENABLE_SHARED TESTS += test-p11test.sh endif endif +endif XFAIL_TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-test.sh From 556cbf3ef71425e69eb3914961332f67335cd9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 19 Mar 2024 09:24:41 +0100 Subject: [PATCH 3421/4321] padding: Set correct output length in PKCS#1 v1.5 depadding --- src/libopensc/padding.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index c42dc945d5..484881575a 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -154,13 +154,15 @@ sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const { unsigned int i = 0; u8 *msg, *msg_orig = NULL; - unsigned int good, found_zero_byte, mask; + unsigned int good, found_zero_byte, mask, tmp_outlen; unsigned int zero_index = 0, msg_index, mlen = -1, len = 0; LOG_FUNC_CALLED(ctx); - if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE) + if (data == NULL || data_len <= 0 || data_len > n || + n < SC_PKCS1_PADDING_MIN_SIZE || out_len == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + tmp_outlen = *out_len; msg = msg_orig = calloc(n, sizeof(u8)); if (msg == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); @@ -201,18 +203,18 @@ sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const mlen = data_len - msg_index; // check that message fits into out buffer - good &= constant_time_ge(*out_len, mlen); + good &= constant_time_ge(tmp_outlen, mlen); // move the result in-place by |num|-SC_PKCS1_PADDING_MIN_SIZE-|mlen| bytes to the left. - *out_len = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, *out_len), - n - SC_PKCS1_PADDING_MIN_SIZE, *out_len); + tmp_outlen = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, tmp_outlen), + n - SC_PKCS1_PADDING_MIN_SIZE, tmp_outlen); for (msg_index = 1; msg_index < n - SC_PKCS1_PADDING_MIN_SIZE; msg_index <<= 1) { mask = ~constant_time_eq(msg_index & (n - SC_PKCS1_PADDING_MIN_SIZE - mlen), 0); for (i = SC_PKCS1_PADDING_MIN_SIZE; i < n - msg_index; i++) msg[i] = constant_time_select_8(mask, msg[i + msg_index], msg[i]); } // move message into out buffer, if good - for (i = 0; i < *out_len; i++) { + for (i = 0; i < tmp_outlen; i++) { unsigned int msg_index; // when out is longer than message in data, use some bogus index in msg mask = good & constant_time_lt(i, mlen); @@ -220,6 +222,7 @@ sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const out[i] = constant_time_select_8(mask, msg[msg_index], out[i]); } + *out_len = constant_time_select(good, mlen, *out_len); free(msg_orig); return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING); } From 21a0a25e516cc46724659efb1f08e778d1c225f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 20 Mar 2024 11:57:50 +0100 Subject: [PATCH 3422/4321] minidriver: Remove logging to prevent Marvin attack --- src/minidriver/minidriver.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 7796afdac2..fb59fb5923 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4721,18 +4721,14 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, } dwret = constant_time_select_s(good, SCARD_S_SUCCESS, SCARD_F_INTERNAL_ERROR); - logprintf(pCardData, 2, "decrypted data(%lu):\n", - (unsigned long)pInfo->cbData); - loghex(pCardData, 7, pbuf2, pInfo->cbData); - /*inversion donnees */ /* copy data in constant-time way to prevent leak */ for (ui = 0; ui < pbufLen; ui++) { unsigned int mask, msg_index, inv_ui; mask = good & constant_time_lt_s(ui, pInfo->cbData); /* ui should be in the bounds of pbuf2 */ inv_ui = pInfo->cbData - ui - 1; - msg_index = constant_time_select_s(mask, inv_ui, 0); - pInfo->pbData[ui] = constant_time_select_8(mask, pbuf2[msg_index], pInfo->pbData[ui]); + msg_index = constant_time_select_s(mask, inv_ui, ui); /* do not change data outside the depadded message */ + pInfo->pbData[ui] = pbuf2[msg_index]; } pCardData->pfnCspFree(pbuf); From 29a98e5b2811f3df7cc7982d8b30a86e756c325c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 20 Mar 2024 16:50:54 +0100 Subject: [PATCH 3423/4321] unittests: Test correct output length for PKCS#1 v1.5 depadding --- src/tests/unittests/strip_pkcs1_2_padding.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tests/unittests/strip_pkcs1_2_padding.c b/src/tests/unittests/strip_pkcs1_2_padding.c index 990e94a38b..385841fc59 100644 --- a/src/tests/unittests/strip_pkcs1_2_padding.c +++ b/src/tests/unittests/strip_pkcs1_2_padding.c @@ -18,6 +18,7 @@ torture_long_output_buffer(void **state) unsigned char result_msg[] = {'m', 's', 'g'}; int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); assert_int_equal(r, 3); + assert_int_equal(r, (int)out_len); assert_memory_equal(out, result_msg, r); free(out); } @@ -34,6 +35,7 @@ torture_short_output_buffer(void **state) unsigned int out_len = 1; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 1); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -52,6 +54,7 @@ torture_short_message_correct_padding(void **state) unsigned char result_msg[] = {'m', 's', 'g'}; int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); assert_int_equal(r, 3); + assert_int_equal(r, (int)out_len); assert_memory_equal(out, result_msg, r); free(out); } @@ -68,6 +71,7 @@ torture_missing_first_zero(void **state) unsigned int out_len = 10; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 10); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -84,6 +88,7 @@ torture_missing_two(void **state) unsigned int out_len = 10; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 10); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -100,6 +105,7 @@ torture_short_padding(void **state) unsigned int out_len = 10; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 10); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -115,6 +121,7 @@ torture_missing_second_zero(void **state) unsigned int out_len = 10; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 10); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -130,6 +137,7 @@ torture_missing_message(void **state) unsigned int out_len = 11; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 11); assert_int_equal(r, SC_ERROR_WRONG_PADDING); free(out); } @@ -148,6 +156,7 @@ torture_one_byte_message(void **state) unsigned char result_msg[] = {'m'}; int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); assert_int_equal(r, 1); + assert_int_equal(r, (int)out_len); assert_memory_equal(out, result_msg, r); free(out); } @@ -166,6 +175,7 @@ torture_longer_padding(void **state) unsigned char result_msg[] = {0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a}; int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); assert_int_equal(r, 8); + assert_int_equal(r, (int)out_len); assert_memory_equal(out, result_msg, r); free(out); } @@ -181,6 +191,7 @@ torture_empty_message(void **state) unsigned int out_len = 8; unsigned char *out = calloc(out_len, sizeof(unsigned char)); int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len); + assert_int_equal((int)out_len, 0); assert_int_equal(r, 0); free(out); } From 7471dd26cde84bf573c03af68b47c0b0dab5edfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 21 Mar 2024 10:45:30 +0100 Subject: [PATCH 3424/4321] minidriver: Refactor inversion of decrypted buffer --- src/minidriver/minidriver.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index fb59fb5923..1302f1b1d8 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4710,7 +4710,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, goto err; } - good = constant_time_eq_i(r, 0); + good = constant_time_ge(r, 1); /* if no error or padding error, do not return here to prevent Marvin attack */ if (!(good | wrong_padding) && r < 0) { logprintf(pCardData, 2, "sc_pkcs15_decipher error(%i): %s\n", r, sc_strerror(r)); @@ -4724,11 +4724,13 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData, /*inversion donnees */ /* copy data in constant-time way to prevent leak */ for (ui = 0; ui < pbufLen; ui++) { - unsigned int mask, msg_index, inv_ui; - mask = good & constant_time_lt_s(ui, pInfo->cbData); /* ui should be in the bounds of pbuf2 */ - inv_ui = pInfo->cbData - ui - 1; - msg_index = constant_time_select_s(mask, inv_ui, ui); /* do not change data outside the depadded message */ - pInfo->pbData[ui] = pbuf2[msg_index]; + unsigned int mask, inv_ui; + unsigned char msg_byte, orig_byte; + mask = good & constant_time_lt_s(ui, pInfo->cbData); /* ui should be in bounds of decrypted message */ + inv_ui = pInfo->cbData - ui - 1; /* compute inversed ui index */ + msg_byte = pbuf2[constant_time_select(mask, inv_ui, 0)]; /* if in range of decrypted message, read on inversed index otherwise read some bogus value */ + orig_byte = pInfo->pbData[ui]; + pInfo->pbData[ui] = constant_time_select_s(mask, msg_byte, orig_byte); /* store message byte only if in correct range */ } pCardData->pfnCspFree(pbuf); From 1f0af543f6e5920c7212fab8ee903d74bb6a4931 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Tue, 2 Apr 2024 16:29:11 +0200 Subject: [PATCH 3425/4321] Add check for the optional member app, fix #3084 --- src/minidriver/minidriver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 1302f1b1d8..496c3db654 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -513,9 +513,12 @@ get_pin_by_name(PCARD_DATA pCardData, struct sc_pkcs15_card *p15card, int role, if (!conf_block) MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); - memset(str_path, 0, sizeof(str_path)); - sc_bin_to_hex(p15card->app->path.value, p15card->app->path.len, str_path, sizeof(str_path), 0); - blocks = scconf_find_blocks(p15card->card->ctx->conf, conf_block, "application", str_path); + if ( p15card->app != NULL ) { + memset(str_path, 0, sizeof(str_path)); + sc_bin_to_hex(p15card->app->path.value, p15card->app->path.len, str_path, sizeof(str_path), 0); + blocks = scconf_find_blocks(p15card->card->ctx->conf, conf_block, "application", str_path); + } + if (blocks) { if (blocks[0]) { pin = (char *)scconf_get_str(blocks[0], pin_type, NULL); From 6a98d4a259c9839ac33361c8dd3f669435cc7774 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Tue, 2 Apr 2024 16:46:25 +0200 Subject: [PATCH 3426/4321] Fix coding style --- src/minidriver/minidriver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 496c3db654..10da7dba43 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -513,12 +513,12 @@ get_pin_by_name(PCARD_DATA pCardData, struct sc_pkcs15_card *p15card, int role, if (!conf_block) MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); - if ( p15card->app != NULL ) { + if (p15card->app != NULL) { memset(str_path, 0, sizeof(str_path)); sc_bin_to_hex(p15card->app->path.value, p15card->app->path.len, str_path, sizeof(str_path), 0); blocks = scconf_find_blocks(p15card->card->ctx->conf, conf_block, "application", str_path); } - + if (blocks) { if (blocks[0]) { pin = (char *)scconf_get_str(blocks[0], pin_type, NULL); From 13931a366bcfd7aa3547e0d4cea90166c0e7ea8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 4 Apr 2024 15:14:24 +0200 Subject: [PATCH 3427/4321] 0.25.1 --- .appveyor.yml | 2 +- NEWS | 9 +++++++++ SECURITY.md | 4 ++-- configure.ac | 4 ++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 4599100ad2..ea458405e2 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.25.0.{build} +version: 0.25.1.{build} platform: - x86 diff --git a/NEWS b/NEWS index 13017fd7be..4579e877a6 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.25.0; 2024-04-05 + +## General improvements +* Add missing file to dist tarball to build documentation (#3063) + +## minidriver +* Fix RSA decryption with PKCS#1 v1.5 padding (#3077) +* Fix crash when app is not set (#3084) + # New in 0.25.0; 2024-03-06 ## Security * [CVE-2023-5992](https://github.com/OpenSC/OpenSC/wiki/CVE-2023-5992): Side-channel leaks while stripping encryption PKCS#1.5 padding in OpenSC (#2948) diff --git a/SECURITY.md b/SECURITY.md index bba5a39845..51236a8c15 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,8 +9,8 @@ backport security fixes into them. Only the last release is supported. | Version | Supported | | -------- | ------------------ | -| 0.25.0 | :white_check_mark: | -| < 0.25.0 | :x: | +| 0.25.1 | :white_check_mark: | +| < 0.25.1 | :x: | ## Reporting a Vulnerability diff --git a/configure.ac b/configure.ac index e8d502bd9e..b8224b5de7 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [25]) -define([PACKAGE_VERSION_FIX], [0]) +define([PACKAGE_VERSION_FIX], [1]) define([PACKAGE_SUFFIX], []) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) @@ -48,7 +48,7 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Interfaces added: CURRENT++, REVISION=0) OPENSC_LT_CURRENT="11" OPENSC_LT_OLDEST="11" -OPENSC_LT_REVISION="1" +OPENSC_LT_REVISION="2" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libopensc/sc.c]) From 021436dac25a485f3c905b115abdf08a4a9f84c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 Apr 2024 15:33:32 +0200 Subject: [PATCH 3428/4321] Fix release version in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 4579e877a6..828a40cadd 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.25.0; 2024-04-05 +# New in 0.25.1; 2024-04-05 ## General improvements * Add missing file to dist tarball to build documentation (#3063) From f0a3f67ab1ee3aa8e763859fbcddde79e1c3d411 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Fri, 5 Apr 2024 15:29:36 +0200 Subject: [PATCH 3429/4321] Update versions to avoid Node16 GH action warnings Signed-off-by: Sergio Arroutbi --- .github/workflows/codeql.yml | 2 +- .github/workflows/codespell.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/doc.yml | 2 +- .github/workflows/fedora.yml | 4 +- .github/workflows/formatter.yml | 2 +- .github/workflows/linux-strict.yml | 2 +- .github/workflows/linux.yml | 92 +++++++++++++++--------------- .github/workflows/macos.yml | 4 +- .github/workflows/packit.yaml | 4 +- 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8be0a3af35..3509677b31 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 8a3a4ac764..39505eabb7 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: codespell-project/actions-codespell@master with: skip: ./src/tests/fuzzing/corpus,compat_* diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 29850b5e9b..58692b46c5 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -15,7 +15,7 @@ jobs: env: HAS_COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN != '' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: ./bootstrap - run: ./configure --disable-dependency-tracking --enable-piv-sm diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 3a4f8edec4..d03605c92d 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -16,7 +16,7 @@ jobs: steps: # Do this before checkout otherwise we will not have a git repository - run: dnf install -y git - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-fedora.sh # git checkout to revert changes to tests/Makefile.am done by the setup - run: | diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index b1ea693157..76ffb5b438 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -21,7 +21,7 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-fedora.sh - run: .github/build.sh dist - name: Upload test logs @@ -38,6 +38,6 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-fedora.sh ix86 - run: .github/build.sh ix86 diff --git a/.github/workflows/formatter.yml b/.github/workflows/formatter.yml index ea027b502f..dfb8b7ae2a 100644 --- a/.github/workflows/formatter.yml +++ b/.github/workflows/formatter.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 100 - uses: yshui/git-clang-format-lint@master diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index cfcd7633a3..fc45fffcfc 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -64,7 +64,7 @@ jobs: container: ubuntu:latest container: ${{ matrix.container }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh ${{ matrix.compiler }} - run: .github/build.sh dist env: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 625459d1e4..0ad52bd42c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh dist - name: Upload test logs @@ -32,7 +32,7 @@ jobs: path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -47,7 +47,7 @@ jobs: valgrind: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh debug - run: .github/build.sh valgrind - name: Upload test logs @@ -62,28 +62,28 @@ jobs: build-no-shared: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh no-shared valgrind build-no-openssl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh no-openssl valgrind build-ix86: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 build-mingw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh mingw - run: .github/build.sh mingw - name: Cache build artifacts @@ -96,7 +96,7 @@ jobs: build-mingw32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts @@ -109,7 +109,7 @@ jobs: build-piv-sm: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist - name: Upload test logs @@ -120,7 +120,7 @@ jobs: path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -130,8 +130,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -144,8 +144,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build-piv-sm] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -158,8 +158,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -172,8 +172,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -186,8 +186,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -200,8 +200,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -214,8 +214,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -227,8 +227,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -241,8 +241,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -257,7 +257,7 @@ jobs: build-ubuntu-22: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh dist valgrind - uses: actions/upload-artifact@v3 @@ -267,7 +267,7 @@ jobs: path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache-build if: ${{ success() }} with: @@ -284,7 +284,7 @@ jobs: build-ubuntu-22-piv-sm: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist valgrind - uses: actions/upload-artifact@v3 @@ -294,7 +294,7 @@ jobs: path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache-build if: ${{ success() }} with: @@ -305,8 +305,8 @@ jobs: runs-on: ubuntu-22.04 needs: [build-ubuntu-22-piv-sm] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -319,8 +319,8 @@ jobs: runs-on: ubuntu-22.04 needs: [build-ubuntu-22] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -333,8 +333,8 @@ jobs: runs-on: ubuntu-22.04 needs: [build-ubuntu-22] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -349,7 +349,7 @@ jobs: build-libressl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - uses: actions/upload-artifact@v3 @@ -360,7 +360,7 @@ jobs: config.log tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache-build if: ${{ success() }} with: @@ -371,8 +371,8 @@ jobs: runs-on: ubuntu-latest needs: [build-libressl] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -385,8 +385,8 @@ jobs: runs-on: ubuntu-latest needs: [build-libressl] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* @@ -402,8 +402,8 @@ jobs: runs-on: ubuntu-latest needs: [build, build-mingw] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 id: cache-build with: path: ./* diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 61196d10db..cfdb4209c1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -23,7 +23,7 @@ jobs: os: [macos-12, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: .github/setup-macos.sh env: KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} @@ -48,7 +48,7 @@ jobs: runs-on: macos-12 needs: [build] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Pull build artifacts uses: actions/download-artifact@v3 with: diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index f77a1e5ff7..85933ced5b 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest name: Packit SRPM steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: packit/actions/srpm@main @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest name: Packit RPM steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: ./.github/actions/packit From 26b9067f26bdfdf6781bd186690d1a0106385fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 4 Apr 2024 12:05:28 +0200 Subject: [PATCH 3430/4321] Free object after removing Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=67732 --- src/pkcs15init/pkcs15-authentic.c | 4 +++- src/pkcs15init/pkcs15-iasecc.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index dca8afa17c..d480c0590c 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -169,8 +169,10 @@ authentic_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p rv = sc_pkcs15_get_objects(p15card, obj_type, objs, 32); LOG_TEST_RET(ctx, rv, "Failed to get PKCS#15 objects to remove"); - for (ii=0; iicard, &df->path, &file); diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 0ef0042960..008dd26d55 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -156,6 +156,7 @@ iasecc_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15c } sc_pkcs15_remove_object(p15card, objs[ii]); + sc_pkcs15_free_object(objs[ii]); } rv = sc_select_file(p15card->card, &df->path, &file); From 10e9099fa55a5056e1d5f735a58ae2f02fd367f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 12 Mar 2024 17:14:14 +0100 Subject: [PATCH 3431/4321] config: Rename private_certificate to pin_protected_certificate Preserve reading of private_certificate for backward compatibility --- doc/files/files.html | 2 +- doc/files/opensc.conf.5.xml.in | 2 +- etc/opensc.conf.example.in | 2 +- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15.c | 31 ++++++++++++++++++++----------- src/libopensc/pkcs15.h | 4 ++-- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index a6f645b6a9..d320f84eff 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -874,7 +874,7 @@ use_pin_caching option for OpenSC to be able to provide PIN for the card when needed.

    - private_certificate = value; + pin_protected_certificate = value;

    How to handle a PIN-protected certificate. Known parameters: diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 9f0168ed76..9024262191 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1350,7 +1350,7 @@ app application { - + How to handle a PIN-protected certificate. Known diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 47344a03fe..8ac5559e39 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -948,7 +948,7 @@ app default { # How to handle a PIN-protected certificate # Valid values: protect, declassify, ignore. # Default: ignore in tokend, protect otherwise - # private_certificate = declassify; + # pin_protected_certificate = declassify; # Enable pkcs15 emulation. # Default: yes diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 7ec4b9d834..65e8cf736c 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -501,7 +501,7 @@ sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obje } sc_log(ctx, "Certificate path '%s'", sc_print_path(&info.path)); - switch (p15card->opts.private_certificate) { + switch (p15card->opts.pin_protected_certificate) { case SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY: sc_log(ctx, "Declassifying certificate"); obj->flags &= ~SC_PKCS15_CO_FLAG_PRIVATE; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 2e3f03d198..bb03ac7ec6 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1268,7 +1268,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, scconf_block *conf_block = NULL; int r, emu_first, enable_emu; const char *use_file_cache; - const char *private_certificate; + const char *pin_protected_certificate, *private_certificate; if (card == NULL || p15card_out == NULL) { return SC_ERROR_INVALID_ARGUMENTS; @@ -1289,12 +1289,11 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; if (0 == strcmp(ctx->app_name, "tokend")) { - private_certificate = "ignore"; - p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + pin_protected_certificate = "ignore"; } else { - private_certificate = "protect"; - p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + pin_protected_certificate = "protect"; } + private_certificate = ""; conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (conf_block) { @@ -1303,6 +1302,8 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", p15card->opts.pin_cache_ignore_user_consent); + pin_protected_certificate = scconf_get_str(conf_block, "pin_protected_certificate", pin_protected_certificate); + /* read also the old value to keep backward compatibility */ private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate); } @@ -1314,16 +1315,24 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES; } + if (0 == strcmp(pin_protected_certificate, "protect")) { + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + } else if (0 == strcmp(pin_protected_certificate, "ignore")) { + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + } else if (0 == strcmp(pin_protected_certificate, "declassify")) { + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY; + } + /* overwrite pin_protected_certificate when private_certificate set */ if (0 == strcmp(private_certificate, "protect")) { - p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; } else if (0 == strcmp(private_certificate, "ignore")) { - p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; } else if (0 == strcmp(private_certificate, "declassify")) { - p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY; + p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY; } - sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d private_certificate=%d", - p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter, - p15card->opts.pin_cache_ignore_user_consent, p15card->opts.private_certificate); + sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d pin_protected_certificate=%d", + p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter, + p15card->opts.pin_cache_ignore_user_consent, p15card->opts.pin_protected_certificate); r = sc_lock(card); if (r) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index f36b6de66e..ce107c02a0 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -586,7 +586,7 @@ typedef struct sc_pkcs15_card { int use_pin_cache; int pin_cache_counter; int pin_cache_ignore_user_consent; - int private_certificate; + int pin_protected_certificate; } opts; unsigned int magic; @@ -612,7 +612,7 @@ typedef struct sc_pkcs15_card { #define SC_PKCS15_OPTS_CACHE_PUBLIC_FILES 1 #define SC_PKCS15_OPTS_CACHE_ALL_FILES 2 -/* suitable for struct sc_pkcs15_card.opts.private_certificate */ +/* suitable for struct sc_pkcs15_card.opts.pin_protected_certificate */ #define SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT 0 #define SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE 1 #define SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY 2 From fe2c1c86c3826685be80a1c70aa526ae79477064 Mon Sep 17 00:00:00 2001 From: Wouter Verhelst Date: Thu, 11 Apr 2024 10:38:57 +0200 Subject: [PATCH 3432/4321] Disable the Applet V1.8 ATR The V1.8 applet has a few differences to the older applets. This causes the OpenSC PKCS#11 module to not be able to sign anything with the Belpic driver on this card. While the best solution is to implement the required changes to make this work correctly, for the time being it's better to not confuse users by claiming we support the card when in reality we don't. --- src/libopensc/card-belpic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 0f482e4174..c316b766ca 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -146,8 +146,8 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur; static size_t next_idx = (size_t)-1; static const struct sc_atr_table belpic_atrs[] = { - /* Applet V1.8 */ - { "3B:7F:96:00:00:80:31:80:65:B0:85:04:01:20:12:0F:FF:82:90:00", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, + /* Applet V1.8 -- disabled, as it requires driver updates which are not yet implemented */ + /* { "3B:7F:96:00:00:80:31:80:65:B0:85:04:01:20:12:0F:FF:82:90:00", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, */ /* Applet V1.1 */ { "3B:98:13:40:0A:A5:03:01:01:01:AD:13:11", NULL, NULL, SC_CARD_TYPE_BELPIC_EID, 0, NULL }, /* Applet V1.0 with new EMV-compatible ATR */ From c72edd520df5c1a5a6639523677e22dac8daa212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Apr 2024 15:40:47 +0200 Subject: [PATCH 3433/4321] Fix license identifier in specfile --- packaging/opensc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 2abf8c6365..7310d80058 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -3,7 +3,7 @@ Version: 0.1.0 Release: 1%{?dist} Summary: Smart card library and applications -License: LGPLv2+ +License: LGPL-2.1-or-later AND BSD-3-Clause URL: https://github.com/OpenSC/OpenSC/wiki Source0: opensc-0.1.0.tar.gz Source1: opensc.module From 5674ff65ebebb94302bfd6093dd842dff76ef8b1 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Fri, 19 Apr 2024 16:02:13 +0200 Subject: [PATCH 3434/4321] Include uri in pkcs11-tool -L option Fixes: #3123 Signed-off-by: Sergio Arroutbi --- src/tools/pkcs11-tool.c | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5b2abf590c..c165945872 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -621,6 +621,7 @@ static void generate_random(CK_SESSION_HANDLE session); static CK_RV find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out, CK_ATTRIBUTE *attrs, CK_ULONG attrsLen, CK_ULONG obj_index); static CK_ULONG get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey); +static const char *percent_encode(CK_UTF8CHAR *, size_t); /* win32 needs this in open(2) */ #ifndef O_BINARY @@ -1681,6 +1682,15 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); + printf(" uri : pkcs11:model="); + printf("%s", percent_encode(info.model, sizeof(info.model))); + printf(";manufacturer="); + printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID))); + printf(";serial="); + printf("%s", percent_encode(info.serialNumber, sizeof(info.serialNumber))); + printf(";token="); + printf("%s", percent_encode(info.label, sizeof(info.label))); + printf("\n"); } static void list_mechs(CK_SLOT_ID slot) @@ -8293,6 +8303,62 @@ static const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len) return buffer; } +static CK_BBOOL +p11_is_percent_format_reserved_char(CK_UTF8CHAR c) +{ + switch (c) { + case ' ': + case '!': + case '"': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case '/': + case ':': + case ';': + case '=': + case '?': + case '@': + case '[': + case ']': + return CK_TRUE; + } + return CK_FALSE; +} + +static const char * +percent_encode(CK_UTF8CHAR *string, size_t len) +{ + static char buffer[1024]; + size_t output_index, input_index; + + while (len && string[len - 1] == ' ') + len--; + + for (output_index = input_index = 0; output_index < sizeof(buffer) - 3; + output_index++) { + if (input_index >= len) { + break; + } + if (p11_is_percent_format_reserved_char(string[input_index])) { + snprintf(&buffer[output_index], 4, "%%%x", string[input_index]); + output_index += 2; + } else { + buffer[output_index] = string[input_index]; + } + input_index++; + } + buffer[output_index] = '\0'; + return buffer; +} + static void p11_fatal(const char *func, CK_RV rv) { if (p11) From 1fb5655d6907d380e9069fefb5e2ec9eaf8657eb Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Thu, 25 Apr 2024 13:42:14 +0200 Subject: [PATCH 3435/4321] Update src/tools/pkcs11-tool.c Co-authored-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index c165945872..46f8b735e5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1682,8 +1682,8 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); - printf(" uri : pkcs11:model="); - printf("%s", percent_encode(info.model, sizeof(info.model))); + printf(" uri : pkcs11:"); + printf("model=%s", percent_encode(info.model, sizeof(info.model))); printf(";manufacturer="); printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID))); printf(";serial="); From 42d4950b9804a6c057586e0e6cb614205818c411 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 9 May 2024 18:53:15 +0200 Subject: [PATCH 3436/4321] pkcs15init: Avoid memory leaks --- src/pkcs15init/pkcs15-lib.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 0dc62af4ac..dbb5748b25 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1888,8 +1888,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile key.u.rsa.modulus.data = NULL; key.u.rsa.exponent.data = NULL; // copy RSA params - if (!(key.u.rsa.modulus.data = malloc(keyargs->key.u.rsa.modulus.len))) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to copy RSA public key parameters"); + if (!(key.u.rsa.modulus.data = malloc(keyargs->key.u.rsa.modulus.len))) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy RSA public key parameters"); + } memcpy(key.u.rsa.modulus.data, keyargs->key.u.rsa.modulus.data, keyargs->key.u.rsa.modulus.len); if (!(key.u.rsa.exponent.data = malloc(keyargs->key.u.rsa.exponent.len))) { r = SC_ERROR_OUT_OF_MEMORY; @@ -1902,8 +1904,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile case SC_ALGORITHM_GOSTR3410: key.u.gostr3410.xy.data = NULL; // copy GOSTR params - if (!(key.u.gostr3410.xy.data = malloc(keyargs->key.u.gostr3410.xy.len))) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to copy GOSTR public key parameters"); + if (!(key.u.gostr3410.xy.data = malloc(keyargs->key.u.gostr3410.xy.len))) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy GOSTR public key parameters"); + } memcpy(key.u.gostr3410.xy.data, keyargs->key.u.gostr3410.xy.data, keyargs->key.u.gostr3410.xy.len); keybits = SC_PKCS15_GOSTR3410_KEYSIZE; type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; @@ -1912,14 +1916,15 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile type = SC_PKCS15_TYPE_PUBKEY_EC; r = sc_copy_ec_params(&key.u.ec.params, &keyargs->key.u.ec.params); - LOG_TEST_RET(ctx, r, "Failed to copy EC public key parameters"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy EC public key parameters"); r = sc_pkcs15_fix_ec_parameters(ctx, &key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Failed to fix EC public key parameters"); keybits = key.u.ec.params.field_length; break; default: - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported key algorithm."); + r = SC_ERROR_NOT_SUPPORTED; + LOG_TEST_GOTO_ERR(ctx, r, "Unsupported key algorithm."); } if ((usage = keyargs->usage) == 0) { @@ -1933,8 +1938,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile /* Set up the pkcs15 object. */ object = sc_pkcs15init_new_object(type, label, &keyargs->auth_id, NULL); - if (object == NULL) - LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate new public key object"); + if (object == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate new public key object"); + } key_info = (struct sc_pkcs15_pubkey_info *) object->data; key_info->usage = usage; From e4d2c99f4bdb4fc5029e5dcf11e86d8315f3c7c5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 May 2024 08:10:40 +0200 Subject: [PATCH 3437/4321] cert: Avoid use of uninitialized memory on errors Thanks oss-fuzz and deengert for pointing the issue out. This issue was introduced in 460a862ee043672b5114c1a0b8d429c587764c89 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66192 --- src/libopensc/pkcs15-cert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 65e8cf736c..c5c8c76e56 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -39,7 +39,7 @@ static int parse_x509_cert(sc_context_t *ctx, struct sc_pkcs15_der *der, struct sc_pkcs15_cert *cert) { int r; - struct sc_algorithm_id sig_alg; + struct sc_algorithm_id sig_alg = {0}; struct sc_pkcs15_pubkey *pubkey = NULL; unsigned char *serial = NULL, *issuer = NULL, *subject = NULL, *buf = der->value; size_t serial_len = 0, issuer_len = 0, subject_len = 0, data_len = 0, buflen = der->len; From 478e3be846c41b039ea1e429fabd61e5bbcd06ca Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Mar 2024 15:41:39 +0100 Subject: [PATCH 3438/4321] ci: Cache APT packages to speed up setup --- .github/setup-linux.sh | 19 +++-- .github/workflows/codeql.yml | 6 +- .github/workflows/coverity.yml | 2 +- .github/workflows/linux-strict.yml | 7 +- .github/workflows/linux.yml | 133 ++++++++++++++++++++++++++++- 5 files changed, 156 insertions(+), 11 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index affd43b52b..5670ae2f06 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -11,6 +11,11 @@ if [ -f "/etc/fedora-release" ]; then exit 0 fi +FORCE_INSTALL=0 +if [ "$1" == "force-install" -o "$2" == "force-install" ]; then + FORCE_INSTALL=1 +fi + WINE_DEPS="" # Generic dependencies DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd openssl valgrind" @@ -22,6 +27,7 @@ fi # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then DEPS="$DEPS gcc-multilib libpcsclite-dev:i386 libcmocka-dev:i386 libssl-dev:i386 zlib1g-dev:i386 libreadline-dev:i386 softhsm2:i386" + FORCE_INSTALL=1 else DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2" fi @@ -46,6 +52,7 @@ elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then elif [ "$1" == "mingw32" ]; then WINE_DEPS="$WINE_DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686" fi + FORCE_INSTALL=1 fi # The Github Ubuntu images since 20211122.1 are broken @@ -57,12 +64,14 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then $SUDO dpkg --add-architecture i386 fi -# make sure we do not get prompts -export DEBIAN_FRONTEND=noninteractive -export DEBCONF_NONINTERACTIVE_SEEN=true -$SUDO apt-get update -qq +if [ -z "$GITHUB_ACTIONS" -o "$FORCE_INSTALL" = "1" ]; then + # make sure we do not get prompts + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + $SUDO apt-get update -qq -$SUDO apt-get install -y build-essential $DEPS + $SUDO apt-get install -y build-essential $DEPS +fi # install libressl if needed if [ "$1" == "libressl" -o "$2" == "libressl" ]; then diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3509677b31..69c523a80c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -8,7 +8,7 @@ on: branches: [ "master" ] schedule: - cron: '30 16 * * 0' - + permissions: {} jobs: analyze: @@ -34,8 +34,8 @@ jobs: with: languages: ${{ matrix.language }} config-file: ./.github/.codeql.yml - - - run: .github/setup-linux.sh + + - run: .github/setup-linux.sh force-install - run: .github/build.sh - name: Perform CodeQL Analysis diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 58692b46c5..709c7b2d46 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -16,7 +16,7 @@ jobs: HAS_COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN != '' }} steps: - uses: actions/checkout@v4 - - run: .github/setup-linux.sh + - run: .github/setup-linux.sh force-install - run: ./bootstrap - run: ./configure --disable-dependency-tracking --enable-piv-sm - uses: vapier/coverity-scan-action@v0 diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index fc45fffcfc..3add7e4514 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -45,6 +45,11 @@ env: -Wno-format-pedantic -Wno-pedantic -Wno-incompatible-function-pointer-types + BASE_DEPS: | + build-essential docbook-xsl xsltproc gengetopt help2man pcscd check + pcsc-tools libtool make autoconf autoconf-archive automake pkg-config + git xxd openssl valgrind socat gawk + libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2 jobs: @@ -65,7 +70,7 @@ jobs: container: ${{ matrix.container }} steps: - uses: actions/checkout@v4 - - run: .github/setup-linux.sh ${{ matrix.compiler }} + - run: .github/setup-linux.sh ${{ matrix.compiler }} force-install - run: .github/build.sh dist env: CC: ${{ matrix.compiler }} diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0ad52bd42c..66bfb09a96 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -17,11 +17,27 @@ permissions: contents: read # to fetch code (actions/checkout) +env: + BASE_DEPS: | + build-essential docbook-xsl xsltproc gengetopt help2man pcscd check + pcsc-tools libtool make autoconf autoconf-archive automake pkg-config + git xxd openssl valgrind socat gawk + libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex + libnss3-tools + libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2 + JAVA_DEPS: | + ant openjdk-8-jdk maven cmake + jobs: build: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh dist - name: Upload test logs @@ -48,6 +64,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - run: .github/setup-linux.sh debug - run: .github/build.sh valgrind - name: Upload test logs @@ -63,6 +84,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh no-shared valgrind @@ -70,6 +96,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh no-openssl valgrind @@ -77,6 +108,11 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 @@ -84,7 +120,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: .github/setup-linux.sh mingw + - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts uses: actions/upload-artifact@v3 @@ -97,6 +133,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts @@ -110,6 +151,11 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist - name: Upload test logs @@ -131,6 +177,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -145,6 +196,11 @@ jobs: needs: [build-piv-sm] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -159,6 +215,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -173,6 +234,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -187,6 +253,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-20-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -201,6 +272,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -215,6 +291,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -228,6 +309,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -242,6 +328,11 @@ jobs: needs: [build] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -258,6 +349,11 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-22-base + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh dist valgrind - uses: actions/upload-artifact@v3 @@ -285,6 +381,11 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-22-java + execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist valgrind - uses: actions/upload-artifact@v3 @@ -306,6 +407,11 @@ jobs: needs: [build-ubuntu-22-piv-sm] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-22-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -320,6 +426,11 @@ jobs: needs: [build-ubuntu-22] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} + version: apt-22-java + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -334,6 +445,11 @@ jobs: needs: [build-ubuntu-22] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-22-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -350,6 +466,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - uses: actions/upload-artifact@v3 @@ -372,6 +493,11 @@ jobs: needs: [build-libressl] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: @@ -386,6 +512,11 @@ jobs: needs: [build-libressl] steps: - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ env.BASE_DEPS }} + version: apt-latest-base + execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: From 1ce4bc32b1591e13c855786be0d1089ba0fe03c1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Mar 2024 16:00:29 +0100 Subject: [PATCH 3439/4321] Use GA for java setup and Maven caching --- .github/setup-java.sh | 18 ++++++++------- .github/workflows/linux.yml | 45 ++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 5d7aff7270..32bc9e2d31 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -2,12 +2,15 @@ set -ex -o xtrace -# Select the right java -sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 -sudo update-alternatives --get-selections | grep ^java -export PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH" -export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ -env | grep -i openjdk +# github already selected the right java in https://github.com/actions/setup-java +if [ -z "$GITHUB_ACTIONS" ]; then + # Select the right java + sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 + sudo update-alternatives --get-selections | grep ^java + export PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH" + export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ +fi +env | grep -i JAVA # VSmartcard ./.github/setup-vsmartcard.sh @@ -25,8 +28,7 @@ if [ ! -d "jcardsim" ]; then git clone https://github.com/Jakuje/jcardsim.git fi pushd jcardsim -env | grep -i openjdk -export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ +env | grep -i JAVA if [ ! -f target/jcardsim-3.0.5-SNAPSHOT.jar ]; then mvn initialize && mvn clean install fi diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 66bfb09a96..e8de401ab6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -27,6 +27,7 @@ env: libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2 JAVA_DEPS: | ant openjdk-8-jdk maven cmake + JCARDSIM: https://github.com/Jakuje/jcardsim.git jobs: build: @@ -187,6 +188,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh piv - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind @@ -206,6 +213,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-piv-sm-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh piv - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind @@ -220,6 +233,12 @@ jobs: packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} version: apt-20-java execute_install_scripts: true + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - uses: actions/cache@v4 id: cache-build with: @@ -244,6 +263,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh v1 - run: .github/test-isoapplet.sh v1 valgrind @@ -263,6 +288,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh gidsapplet - run: .github/test-gidsapplet.sh - run: .github/test-gidsapplet.sh valgrind @@ -274,7 +305,7 @@ jobs: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: ${{ env.BASE_DEPS }} + packages: ${{ env.BASE_DEPS }} %{{ env.JAVA_DEPS }} version: apt-20-base execute_install_scripts: true - uses: actions/cache@v4 @@ -282,6 +313,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh openpgp - run: .github/test-openpgp.sh - run: .github/test-openpgp.sh valgrind @@ -417,6 +454,12 @@ jobs: with: path: ./* key: ${{ runner.os }}-22-piv-sm-${{ github.sha }} + - run: git clone $JCARDSIM + - uses: actions/setup-java@v4 + with: + distribution: 'semeru' + java-version: '8' + cache: 'maven' - run: .github/setup-linux.sh piv - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind From 756d49fa9745c2c3db7d23320c6459bfbc7526a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 Mar 2024 17:53:34 +0100 Subject: [PATCH 3440/4321] Skip running clang-tidy checks in the first fast build --- .github/build.sh | 3 +++ .github/workflows/linux.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/build.sh b/.github/build.sh index 1393c9d0e6..3105c94446 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -55,6 +55,9 @@ else # normal procedure CONFIGURE_FLAGS="--disable-dependency-tracking --enable-doc" + if [ "$1" != "clang-tidy" ]; then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS CLANGTIDY=/bin/no-clang-tidy" + fi if [ "$1" == "piv-sm" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-piv-sm" fi diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index e8de401ab6..a46976ae96 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -339,7 +339,7 @@ jobs: path: ./* key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh clang-tidy - - run: .github/build.sh + - run: .github/build.sh clang-tidy test-cac: runs-on: ubuntu-20.04 From 4fa782528b83dacccf89366849ba93338b0bbc15 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Apr 2024 11:58:34 +0200 Subject: [PATCH 3441/4321] Cache libressl build --- .github/setup-libressl.sh | 8 ++++++-- .github/workflows/linux.yml | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh index f5a68fe522..72325eade3 100755 --- a/.github/setup-libressl.sh +++ b/.github/setup-libressl.sh @@ -10,10 +10,14 @@ if [ ! -d "$V" ]; then # letsencrypt CA does not seem to be included in CI runner wget --no-check-certificate https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$V.tar.gz tar xzf $V.tar.gz + + pushd $V + ./configure --prefix=/usr/local + make -j $(nproc) + popd fi + pushd $V -./configure --prefix=/usr/local -make -j $(nproc) sudo make install popd diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a46976ae96..ed0609ff2b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -28,6 +28,7 @@ env: JAVA_DEPS: | ant openjdk-8-jdk maven cmake JCARDSIM: https://github.com/Jakuje/jcardsim.git + LIBRESSL_VERSION: 3.8.1 jobs: build: @@ -514,6 +515,13 @@ jobs: packages: ${{ env.BASE_DEPS }} version: apt-latest-base execute_install_scripts: true + - name: Restore LibreSSL build + uses: actions/cache/restore@v4 + id: libressl-cache + with: + path: | + libressl-${{ env.LIBRESSL_VERSION }}/ + key: libressl-${{ env.LIBRESSL_VERSION }} - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - uses: actions/upload-artifact@v3 @@ -530,6 +538,13 @@ jobs: with: path: ./* key: ${{ runner.os }}-libressl-${{ github.sha }} + - if: ${{ steps.libressl-cache.outputs.cache-hit != 'true' }} + name: Cache LibreSSL build + uses: actions/cache/save@v4 + with: + path: | + libressl-${{ env.LIBRESSL_VERSION }}/ + key: libressl-${{ env.LIBRESSL_VERSION }} test-cac-libressl: runs-on: ubuntu-latest From 092eea05df975a8680b354d90c8c0aae90ed8de1 Mon Sep 17 00:00:00 2001 From: Vladimir Stoiakin Date: Wed, 24 Apr 2024 15:32:15 +0300 Subject: [PATCH 3442/4321] unify '#ifdef HAVE_CONFIG_H' declaration --- src/common/compat___iob_func.c | 2 +- src/common/compat_getopt.c | 2 +- src/common/compat_getpass.c | 2 +- src/common/compat_overflow.c | 2 +- src/common/compat_report_rangecheckfailure.c | 2 +- src/common/compat_strlcat.c | 2 +- src/common/compat_strlcpy.c | 2 +- src/common/libpkcs11.c | 2 +- src/common/libscdl.c | 2 +- src/libopensc/apdu.c | 2 +- src/libopensc/asn1.c | 2 +- src/libopensc/aux-data.c | 2 +- src/libopensc/base64.c | 2 +- src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-belpic.c | 2 +- src/libopensc/card-cac-common.c | 2 +- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cac1.c | 2 +- src/libopensc/card-cardos.c | 2 +- src/libopensc/card-coolkey.c | 2 +- src/libopensc/card-default.c | 2 +- src/libopensc/card-dtrust.c | 2 +- src/libopensc/card-entersafe.c | 2 +- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-esteid2018.c | 2 +- src/libopensc/card-flex.c | 2 +- src/libopensc/card-gemsafeV1.c | 2 +- src/libopensc/card-idprime.c | 2 +- src/libopensc/card-jpki.c | 2 +- src/libopensc/card-masktech.c | 2 +- src/libopensc/card-mcrd.c | 2 +- src/libopensc/card-muscle.c | 2 +- src/libopensc/card-myeid.c | 2 +- src/libopensc/card-oberthur.c | 2 +- src/libopensc/card-openpgp.c | 2 +- src/libopensc/card-piv.c | 2 +- src/libopensc/card-rtecp.c | 2 +- src/libopensc/card-rutoken.c | 2 +- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/card-setcos.c | 2 +- src/libopensc/card-skeid.c | 2 +- src/libopensc/card-starcos.c | 2 +- src/libopensc/card-tcos.c | 2 +- src/libopensc/card.c | 2 +- src/libopensc/compression.c | 2 +- src/libopensc/ctbcs.c | 2 +- src/libopensc/ctx.c | 2 +- src/libopensc/dir.c | 2 +- src/libopensc/errors.c | 2 +- src/libopensc/gp.c | 2 +- src/libopensc/log.c | 2 +- src/libopensc/muscle-filesystem.c | 2 +- src/libopensc/muscle.c | 2 +- src/libopensc/padding.c | 2 +- src/libopensc/pkcs15-actalis.c | 2 +- src/libopensc/pkcs15-algo.c | 2 +- src/libopensc/pkcs15-atrust-acos.c | 2 +- src/libopensc/pkcs15-cac.c | 2 +- src/libopensc/pkcs15-cache.c | 2 +- src/libopensc/pkcs15-cardos.c | 2 +- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15-coolkey.c | 2 +- src/libopensc/pkcs15-data.c | 2 +- src/libopensc/pkcs15-dnie.c | 2 +- src/libopensc/pkcs15-esinit.c | 2 +- src/libopensc/pkcs15-esteid2018.c | 2 +- src/libopensc/pkcs15-gemsafeV1.c | 2 +- src/libopensc/pkcs15-iasecc.c | 2 +- src/libopensc/pkcs15-idprime.c | 2 +- src/libopensc/pkcs15-jpki.c | 2 +- src/libopensc/pkcs15-openpgp.c | 2 +- src/libopensc/pkcs15-pin.c | 2 +- src/libopensc/pkcs15-piv.c | 2 +- src/libopensc/pkcs15-prkey.c | 2 +- src/libopensc/pkcs15-pteid.c | 2 +- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15-sc-hsm.c | 2 +- src/libopensc/pkcs15-sec.c | 2 +- src/libopensc/pkcs15-skeid.c | 2 +- src/libopensc/pkcs15-starcert.c | 2 +- src/libopensc/pkcs15-syn.c | 2 +- src/libopensc/pkcs15-tccardos.c | 2 +- src/libopensc/pkcs15-tcos.c | 2 +- src/libopensc/reader-cryptotokenkit.m | 2 +- src/libopensc/reader-ctapi.c | 2 +- src/libopensc/reader-openct.c | 2 +- src/libopensc/reader-pcsc.c | 2 +- src/libopensc/reader-tr03119.c | 2 +- src/libopensc/sc.c | 2 +- src/libopensc/sec.c | 2 +- src/libopensc/simpletlv.c | 2 +- src/libopensc/sm.c | 2 +- src/tests/fuzzing/fuzz_asn1_print.c | 2 +- src/tests/fuzzing/fuzz_asn1_sig_value.c | 2 +- src/tests/fuzzing/fuzz_card.c | 2 +- src/tests/fuzzing/fuzz_piv_tool.c | 2 +- src/tests/fuzzing/fuzz_pkcs11.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_crypt.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_decode.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_encode.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_tool.c | 2 +- src/tests/fuzzing/fuzz_pkcs15init.c | 2 +- src/tests/fuzzing/fuzz_scconf_parse_string.c | 2 +- src/tools/gids-tool.c | 2 +- src/ui/notify.c | 2 +- 107 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/common/compat___iob_func.c b/src/common/compat___iob_func.c index b770243321..9eefb932da 100644 --- a/src/common/compat___iob_func.c +++ b/src/common/compat___iob_func.c @@ -1,4 +1,4 @@ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_getopt.c b/src/common/compat_getopt.c index bc70113599..5db6873a84 100644 --- a/src/common/compat_getopt.c +++ b/src/common/compat_getopt.c @@ -23,7 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_getpass.c b/src/common/compat_getpass.c index 22a1abd14b..90e19f1ae1 100644 --- a/src/common/compat_getpass.c +++ b/src/common/compat_getpass.c @@ -1,4 +1,4 @@ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_overflow.c b/src/common/compat_overflow.c index 4f64c141cc..049c3f9533 100644 --- a/src/common/compat_overflow.c +++ b/src/common/compat_overflow.c @@ -20,7 +20,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_report_rangecheckfailure.c b/src/common/compat_report_rangecheckfailure.c index 4fb48ec4e5..92b70fc634 100644 --- a/src/common/compat_report_rangecheckfailure.c +++ b/src/common/compat_report_rangecheckfailure.c @@ -15,7 +15,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_strlcat.c b/src/common/compat_strlcat.c index fa51cd29cc..e273d469b1 100644 --- a/src/common/compat_strlcat.c +++ b/src/common/compat_strlcat.c @@ -27,7 +27,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/compat_strlcpy.c b/src/common/compat_strlcpy.c index ef3c785b26..6993d0df05 100644 --- a/src/common/compat_strlcpy.c +++ b/src/common/compat_strlcpy.c @@ -16,7 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index e4b7533039..e21c7b4639 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 64ff43c6fb..92f9f9ca3f 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include #endif diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 82e55f7a8b..099d152aa8 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 1edb58cc54..08ef56149c 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/aux-data.c b/src/libopensc/aux-data.c index d978d2a179..35c6f07906 100644 --- a/src/libopensc/aux-data.c +++ b/src/libopensc/aux-data.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/base64.c b/src/libopensc/base64.c index bcfce4b659..e8193c976e 100644 --- a/src/libopensc/base64.c +++ b/src/libopensc/base64.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 74a2a74652..27e0c22578 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 92790322bf..ecfb7e9ee9 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index c316b766ca..3029c9c7cb 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -80,7 +80,7 @@ * language-selection functionality. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-cac-common.c b/src/libopensc/card-cac-common.c index 6a5289c638..0e8ecc43e3 100644 --- a/src/libopensc/card-cac-common.c +++ b/src/libopensc/card-cac-common.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 68feaec7ad..898fce8aa5 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -26,7 +26,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 6395dcdcdd..5ddacc4565 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -26,7 +26,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index f61d89b101..2e2d524333 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 7f1c1024da..9192aac092 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -24,7 +24,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index 89a8ec50c2..22fcf1cb84 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index b395cc2cdb..646e6ea331 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -20,7 +20,7 @@ * based on card-cardos.c */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 2fdc6c39bf..5f6d8a424d 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -16,7 +16,7 @@ /* Initially written by Weitao Sun (weitao@ftsafe.com) 2008 */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef ENABLE_OPENSSL /* empty file without openssl */ diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 173629bbf3..c3b33860ba 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef ENABLE_SM /* empty file without SM enabled */ diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index df8428878c..989a854d77 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index c0cb494e80..219b27806e 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index b18ddb2194..984563f08b 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -17,7 +17,7 @@ /* Initially written by David Mattes (david.mattes@boeing.com) */ /* Portuguese eID card support by Joao Poupino (joao.poupino@ist.utl.pt) */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 57b76919e4..9ce764b217 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 7e3be93bd2..6e4d0f3165 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index b00a4171cd..03cb769279 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 6c5b90175d..5abdfc4b43 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -22,7 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index a27c586cf6..fc0b1fa3e1 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 511b69fe88..ead572e36c 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 664ef064f3..f344d5901f 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -23,7 +23,7 @@ * best view with tabstop=4 */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 584a5a8926..7df722cdb7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -35,7 +35,7 @@ * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d7e3a48657..c3a3057997 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -22,7 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index cc13508ee6..338961cd6b 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index f9221e0885..3fa2d46d03 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cc0bd2d7d4..009439fe8f 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index d4030eba7e..3a624e0028 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-skeid.c b/src/libopensc/card-skeid.c index 573133879f..4062ee485c 100644 --- a/src/libopensc/card-skeid.c +++ b/src/libopensc/card-skeid.c @@ -20,7 +20,7 @@ * based on card-cardos.c */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index b428f737c9..baf673b007 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 86a47d0885..80527a6366 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 43bb41a65b..7f4ef98f91 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index 0c81d42d3b..26aba399ff 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/ctbcs.c b/src/libopensc/ctbcs.c index 4376aa14d0..dddb255536 100644 --- a/src/libopensc/ctbcs.c +++ b/src/libopensc/ctbcs.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index c0d170c9fa..2316209ee5 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 7648f6860e..7d634a8ec6 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 95cce563ce..58a28c5e18 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index 41b344e727..aed670399a 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/log.c b/src/libopensc/log.c index e0814f4a5d..1e8ca5f086 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 7fb6418754..2e65b4576d 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 20f60c874a..46a9f66b88 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 484881575a..bfc4273cd0 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index 7a7cfca5f0..540602460d 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -22,7 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index eb408cf264..3b1b3ba031 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index f5a580e9a8..e6b53989e0 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index 9f4a0034e3..6a65d5fc30 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -27,7 +27,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index bae5797fe2..6e0f70735c 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-cardos.c b/src/libopensc/pkcs15-cardos.c index ab33b18265..59f3b1e1be 100644 --- a/src/libopensc/pkcs15-cardos.c +++ b/src/libopensc/pkcs15-cardos.c @@ -23,7 +23,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index c5c8c76e56..1777a85835 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 7099b07f35..5435e59ca1 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -26,7 +26,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index f538a1ef0d..0d69650f95 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index e59a03f5b4..c72ee79c6b 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -21,7 +21,7 @@ #include #include -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "libopensc/log.h" diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 84b0db3ea7..bdade82079 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -15,7 +15,7 @@ */ /* Initially written by Weitao Sun (weitao@ftsafe.com) 2008*/ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 1f2aa6b815..f8569d1e54 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 39cf7a591d..25140503fa 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -17,7 +17,7 @@ /* Initially written by David Mattes */ /* Support for multiple key containers by Lukas Wunner */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index 1faac3ce3a..417549ba14 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 83600f56ee..34192f5aa2 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -22,7 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 6be0e5049d..8e0881c431 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 47ced37b7f..d465724c38 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index d9bfc4c8af..1203478260 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 6d5f336f13..db7e21decb 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -25,7 +25,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 8b84dafaf4..70834713a1 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index df05465aaf..4446b31ac9 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -36,7 +36,7 @@ * */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index bbc9a2eed9..1f9c2c46d9 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 2279676fa7..1f362777de 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index ba185ab5d0..edde62398b 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-skeid.c b/src/libopensc/pkcs15-skeid.c index 4447bf7d4b..cd802f95b8 100644 --- a/src/libopensc/pkcs15-skeid.c +++ b/src/libopensc/pkcs15-skeid.c @@ -20,7 +20,7 @@ * based on the PKCS15 emulation layer for EstEID card by Martin Paljak */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 04657d00da..b2beb75530 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index a9518066a7..dabbc87559 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index a86633e9de..4091c4cc52 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index a5666c9b78..a84001e122 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index 848216b23a..bf8a1a52c6 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index eb2ee4000e..10f3d335c3 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index 958476b4b2..7910b3ce2a 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 723bcfd013..35ce4803ce 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index b019552f9c..af363578cb 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 7c9e0d25ed..cf3d86a022 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index ec6a97b67d..6bd319e739 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c index 12c8bf6a79..09a269af9e 100644 --- a/src/libopensc/simpletlv.c +++ b/src/libopensc/simpletlv.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c index 9839b3d834..062efc5054 100644 --- a/src/libopensc/sm.c +++ b/src/libopensc/sm.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_asn1_print.c b/src/tests/fuzzing/fuzz_asn1_print.c index b6ebdd549c..dce3e11695 100644 --- a/src/tests/fuzzing/fuzz_asn1_print.c +++ b/src/tests/fuzzing/fuzz_asn1_print.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_asn1_sig_value.c b/src/tests/fuzzing/fuzz_asn1_sig_value.c index db17aee6cf..0a289c0493 100644 --- a/src/tests/fuzzing/fuzz_asn1_sig_value.c +++ b/src/tests/fuzzing/fuzz_asn1_sig_value.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_card.c b/src/tests/fuzzing/fuzz_card.c index b52d4590af..1f4dcc7f0b 100644 --- a/src/tests/fuzzing/fuzz_card.c +++ b/src/tests/fuzzing/fuzz_card.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_piv_tool.c b/src/tests/fuzzing/fuzz_piv_tool.c index 616f098327..05a8d87196 100644 --- a/src/tests/fuzzing/fuzz_piv_tool.c +++ b/src/tests/fuzzing/fuzz_piv_tool.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index fdc163b485..f440a7b701 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15_crypt.c b/src/tests/fuzzing/fuzz_pkcs15_crypt.c index 6824087000..730878e3ae 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_crypt.c +++ b/src/tests/fuzzing/fuzz_pkcs15_crypt.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index f359cfe381..58747fe469 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c index a10ecf5645..104bcf5c7c 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_encode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 7d8971ef0e..87c2b5e056 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15_tool.c b/src/tests/fuzzing/fuzz_pkcs15_tool.c index 089aaf431e..93c7abb270 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_tool.c +++ b/src/tests/fuzzing/fuzz_pkcs15_tool.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index e44e3aae35..8695c429a5 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tests/fuzzing/fuzz_scconf_parse_string.c b/src/tests/fuzzing/fuzz_scconf_parse_string.c index ee41d84618..3a5b46d8bf 100644 --- a/src/tests/fuzzing/fuzz_scconf_parse_string.c +++ b/src/tests/fuzzing/fuzz_scconf_parse_string.c @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index f5eaa68372..96fe63a980 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/ui/notify.c b/src/ui/notify.c index 6ef72c6310..5045c4f678 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif From 0ba15ba096b9cd58354cf8960e04f295af3de59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 23 Apr 2024 14:41:25 +0200 Subject: [PATCH 3443/4321] Check SW2 when SW1 is 0x90 The starcos_gen_key() correctly checks for SW to be 0x9000, but the starcos_gen_key() does not check for SW2. The error is not propagated and key generation works with not allocated values. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=68040 --- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-starcos.c | 2 +- src/libopensc/iso7816.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index ecfb7e9ee9..1f044d6ca6 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -803,7 +803,7 @@ static int atrust_acos_check_sw(struct sc_card *card, unsigned int sw1, sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); - if (sw1 == 0x90) + if (sw1 == 0x90 && sw2 == 0x00) return SC_SUCCESS; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index baf673b007..48eb49cbaa 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1974,7 +1974,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); - if (sw1 == 0x90) + if (sw1 == 0x90 && sw2 == 0x00) return SC_SUCCESS; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 2fea840785..6a49d64dff 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -117,12 +117,12 @@ iso7816_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) sc_log(card->ctx, "Wrong length; correct length is %d", sw2); return SC_ERROR_WRONG_LENGTH; } - if (sw1 == 0x90) + if (sw1 == 0x90 && sw2 == 0x00) return SC_SUCCESS; - if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) { - sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f)); - return SC_ERROR_PIN_CODE_INCORRECT; - } + if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) { + sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f)); + return SC_ERROR_PIN_CODE_INCORRECT; + } for (i = 0; i < err_count; i++) { if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) { sc_log(card->ctx, "%s", iso7816_errors[i].errorstr); From e9dcfe97de6a6cb8e1bb99b88eefac1889daaa19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 7 May 2024 16:30:14 +0200 Subject: [PATCH 3444/4321] profile.c: Treat long macro names as error Limiting the size and not returning an error leads to infinite recursion if the macro value is a macro name that is longer than the given limitation. Thank OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=68061 --- src/pkcs15init/profile.c | 10 +++++++--- .../unittests/check_macro_reference_loop.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 8f941aaa86..f8073ac0e4 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2007,19 +2007,22 @@ is_macro_character(char c) { return 0; } -static void +static int get_inner_word(char *str, char word[WORD_SIZE]) { char *inner = NULL; size_t len = 0; inner = str; + while (is_macro_character(*inner)) { inner++; len++; } - len = len >= WORD_SIZE ? WORD_SIZE - 1 : len; + if (len >= WORD_SIZE) + return 1; memcpy(word, str, len); word[len] = '\0'; + return 0; } /* @@ -2044,7 +2047,8 @@ check_macro_reference_loop(const char *start_name, sc_macro_t *macro, sc_profile if (!(name = strchr(macro_value, '$'))) continue; /* Extract the macro name from the string */ - get_inner_word(name + 1, word); + if (get_inner_word(name + 1, word)) + return 1; /* Find whether name corresponds to some other macro */ if (!(m = find_macro(profile, word))) continue; diff --git a/src/tests/unittests/check_macro_reference_loop.c b/src/tests/unittests/check_macro_reference_loop.c index 8ab2d3b9a2..98e5bdc854 100644 --- a/src/tests/unittests/check_macro_reference_loop.c +++ b/src/tests/unittests/check_macro_reference_loop.c @@ -143,6 +143,23 @@ static void torture_macro_loop_indirect_nonprintable(void **state) } #endif /* 0 */ +/* + *A reproducer for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=68061 + */ +static void torture_macro_loop_long_name(void **state) +{ + scconf_list value1 = { .data = "$second" }; + scconf_list value2 = { .data = "$dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe" }; + scconf_list value3 = { .data = "$second" }; + sc_macro_t macro3 = { .name = "dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe", .value = &value3 }; + sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; + sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; + sc_profile_t profile = { .macro_list = ¯o1 }; + + int r = check_macro_reference_loop("first", ¯o1, &profile, 10); + assert_int_equal(r, 1); +} + int main(void) { const struct CMUnitTest tests[] = { @@ -154,6 +171,7 @@ int main(void) cmocka_unit_test(torture_macro_loop_inner_string), cmocka_unit_test(torture_macro_loop_indirect), cmocka_unit_test(torture_macro_loop_indirect_multivalue), + cmocka_unit_test(torture_macro_loop_long_name), }; return cmocka_run_group_tests(tests, NULL, NULL); } From 793e3888920792f55e3079597eeafb486c3f5de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 10 May 2024 13:42:24 +0200 Subject: [PATCH 3445/4321] unittests: Reformat check_macro_reference_loop.c --- .../unittests/check_macro_reference_loop.c | 155 +++++++++--------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/src/tests/unittests/check_macro_reference_loop.c b/src/tests/unittests/check_macro_reference_loop.c index 98e5bdc854..c8a20a71af 100644 --- a/src/tests/unittests/check_macro_reference_loop.c +++ b/src/tests/unittests/check_macro_reference_loop.c @@ -27,98 +27,106 @@ #include "common/compat_strlcpy.c" #include -static void torture_no_loop(void **state) +static void +torture_no_loop(void **state) { - scconf_list value = { .data = "value" }; - sc_macro_t macro = { .name = "name", .value = &value }; - sc_profile_t profile = { .macro_list = ¯o }; + scconf_list value = {.data = "value"}; + sc_macro_t macro = {.name = "name", .value = &value}; + sc_profile_t profile = {.macro_list = ¯o}; int r = check_macro_reference_loop("name", ¯o, &profile, 10); assert_int_equal(r, 0); } -static void torture_one_macro_no_loop(void **state) +static void +torture_one_macro_no_loop(void **state) { - scconf_list value = { .data = "value" }; - sc_macro_t macro = { .name = "name", .value = &value }; - sc_profile_t profile = { .macro_list = ¯o }; + scconf_list value = {.data = "value"}; + sc_macro_t macro = {.name = "name", .value = &value}; + sc_profile_t profile = {.macro_list = ¯o}; int r = check_macro_reference_loop("name", ¯o, &profile, 10); assert_int_equal(r, 0); } -static void torture_one_macro_loop(void **state) +static void +torture_one_macro_loop(void **state) { - scconf_list value = { .data = "$name" }; - sc_macro_t macro = { .name = "name", .value = &value }; - sc_profile_t profile = { .macro_list = ¯o }; + scconf_list value = {.data = "$name"}; + sc_macro_t macro = {.name = "name", .value = &value}; + sc_profile_t profile = {.macro_list = ¯o}; int r = check_macro_reference_loop("name", ¯o, &profile, 10); assert_int_equal(r, 1); } -static void torture_long_macro_loop(void **state) +static void +torture_long_macro_loop(void **state) { - scconf_list value1 = { .data = "$second" }; - scconf_list value2 = { .data = "$third" }; - scconf_list value3 = { .data = "$first" }; - sc_macro_t macro3 = { .name = "third", .value = &value3 }; - sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; - sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value1 = {.data = "$second"}; + scconf_list value2 = {.data = "$third"}; + scconf_list value3 = {.data = "$first"}; + sc_macro_t macro3 = {.name = "third", .value = &value3}; + sc_macro_t macro2 = {.name = "second", .value = &value2, .next = ¯o3}; + sc_macro_t macro1 = {.name = "first", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("first", ¯o1, &profile, 10); assert_int_equal(r, 1); } -static void torture_long_macro_loop_too_deep(void **state) +static void +torture_long_macro_loop_too_deep(void **state) { - scconf_list value1 = { .data = "$second" }; - scconf_list value2 = { .data = "$third" }; - scconf_list value3 = { .data = "value" }; - sc_macro_t macro3 = { .name = "third", .value = &value3 }; - sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; - sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value1 = {.data = "$second"}; + scconf_list value2 = {.data = "$third"}; + scconf_list value3 = {.data = "value"}; + sc_macro_t macro3 = {.name = "third", .value = &value3}; + sc_macro_t macro2 = {.name = "second", .value = &value2, .next = ¯o3}; + sc_macro_t macro1 = {.name = "first", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("first", ¯o1, &profile, 14); assert_int_equal(r, 1); } -static void torture_macro_loop_inner_string(void **state) +static void +torture_macro_loop_inner_string(void **state) { - scconf_list value1 = { .data = "xx$second" }; - scconf_list value2 = { .data = "$third" }; - scconf_list value3 = { .data = "$first\0" }; - sc_macro_t macro3 = { .name = "third", .value = &value3 }; - sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; - sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value1 = {.data = "xx$second"}; + scconf_list value2 = {.data = "$third"}; + scconf_list value3 = {.data = "$first\0"}; + sc_macro_t macro3 = {.name = "third", .value = &value3}; + sc_macro_t macro2 = {.name = "second", .value = &value2, .next = ¯o3}; + sc_macro_t macro1 = {.name = "first", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("first", ¯o1, &profile, 10); assert_int_equal(r, 1); } -static void torture_macro_loop_indirect(void **state) +static void +torture_macro_loop_indirect(void **state) { - scconf_list value1 = { .data = "$x" }; - scconf_list value2 = { .data = "-$x" }; - sc_macro_t macro2 = { .name = "o", .value = &value2 }; - sc_macro_t macro1 = { .name = "x", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value1 = {.data = "$x"}; + scconf_list value2 = {.data = "-$x"}; + sc_macro_t macro2 = {.name = "o", .value = &value2}; + sc_macro_t macro1 = {.name = "x", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("o", ¯o2, &profile, 10); assert_int_equal(r, 1); } -static void torture_macro_loop_indirect_multivalue(void **state) +static void +torture_macro_loop_indirect_multivalue(void **state) { - scconf_list value3 = { .data = "-$x" }; - scconf_list value2 = { .data = "1", .next = &value3 }; - scconf_list value1 = { .data = "$x" }; - sc_macro_t macro2 = { .name = "o", .value = &value2 }; - sc_macro_t macro1 = { .name = "x", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value3 = {.data = "-$x"}; + scconf_list value2 = {.data = "1", .next = &value3}; + scconf_list value1 = {.data = "$x"}; + sc_macro_t macro2 = {.name = "o", .value = &value2}; + sc_macro_t macro1 = {.name = "x", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("o", ¯o2, &profile, 10); assert_int_equal(r, 1); @@ -130,13 +138,13 @@ static void torture_macro_loop_indirect_multivalue(void **state) */ static void torture_macro_loop_indirect_nonprintable(void **state) { - scconf_list value3 = { .data = "$\270\270x\001" }; - scconf_list value2 = { .data = "$e" }; - scconf_list value1 = { .data = "$e" }; - sc_macro_t macro3 = { .name = "e", .value = &value3 }; - sc_macro_t macro2 = { .name = "osi", .value = &value2, .next = ¯o3}; - sc_macro_t macro1 = { .name = "\270\270x\001", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value3 = {.data = "$\270\270x\001"}; + scconf_list value2 = {.data = "$e"}; + scconf_list value1 = {.data = "$e"}; + sc_macro_t macro3 = {.name = "e", .value = &value3}; + sc_macro_t macro2 = {.name = "osi", .value = &value2, .next = ¯o3}; + sc_macro_t macro1 = {.name = "\270\270x\001", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("osi", ¯o2, &profile, 10); assert_int_equal(r, 1); @@ -146,15 +154,16 @@ static void torture_macro_loop_indirect_nonprintable(void **state) /* *A reproducer for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=68061 */ -static void torture_macro_loop_long_name(void **state) +static void +torture_macro_loop_long_name(void **state) { - scconf_list value1 = { .data = "$second" }; - scconf_list value2 = { .data = "$dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe" }; - scconf_list value3 = { .data = "$second" }; - sc_macro_t macro3 = { .name = "dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe", .value = &value3 }; - sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; - sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; - sc_profile_t profile = { .macro_list = ¯o1 }; + scconf_list value1 = {.data = "$second"}; + scconf_list value2 = {.data = "$dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe"}; + scconf_list value3 = {.data = "$second"}; + sc_macro_t macro3 = {.name = "dtBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBBe", .value = &value3}; + sc_macro_t macro2 = {.name = "second", .value = &value2, .next = ¯o3}; + sc_macro_t macro1 = {.name = "first", .value = &value1, .next = ¯o2}; + sc_profile_t profile = {.macro_list = ¯o1}; int r = check_macro_reference_loop("first", ¯o1, &profile, 10); assert_int_equal(r, 1); @@ -163,15 +172,15 @@ static void torture_macro_loop_long_name(void **state) int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test(torture_no_loop), - cmocka_unit_test(torture_one_macro_no_loop), - cmocka_unit_test(torture_one_macro_loop), - cmocka_unit_test(torture_long_macro_loop), - cmocka_unit_test(torture_long_macro_loop_too_deep), - cmocka_unit_test(torture_macro_loop_inner_string), - cmocka_unit_test(torture_macro_loop_indirect), - cmocka_unit_test(torture_macro_loop_indirect_multivalue), - cmocka_unit_test(torture_macro_loop_long_name), + cmocka_unit_test(torture_no_loop), + cmocka_unit_test(torture_one_macro_no_loop), + cmocka_unit_test(torture_one_macro_loop), + cmocka_unit_test(torture_long_macro_loop), + cmocka_unit_test(torture_long_macro_loop_too_deep), + cmocka_unit_test(torture_macro_loop_inner_string), + cmocka_unit_test(torture_macro_loop_indirect), + cmocka_unit_test(torture_macro_loop_indirect_multivalue), + cmocka_unit_test(torture_macro_loop_long_name), }; return cmocka_run_group_tests(tests, NULL, NULL); } From ea4b217825ca4f16c138022f7a75d27bf64c7124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 10 May 2024 13:47:00 +0200 Subject: [PATCH 3446/4321] Fix formatting --- src/libopensc/iso7816.c | 6 +++--- src/pkcs15init/profile.c | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 6a49d64dff..73893e9416 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -119,9 +119,9 @@ iso7816_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) } if (sw1 == 0x90 && sw2 == 0x00) return SC_SUCCESS; - if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) { - sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f)); - return SC_ERROR_PIN_CODE_INCORRECT; + if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U) { + sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f)); + return SC_ERROR_PIN_CODE_INCORRECT; } for (i = 0; i < err_count; i++) { if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) { diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index f8073ac0e4..5113af6ef6 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2001,14 +2001,16 @@ static struct block root_ops = { }; static int -is_macro_character(char c) { +is_macro_character(char c) +{ if (isalnum(c) || c == '-' || c == '_') return 1; return 0; } static int -get_inner_word(char *str, char word[WORD_SIZE]) { +get_inner_word(char *str, char word[WORD_SIZE]) +{ char *inner = NULL; size_t len = 0; From 9a484a9d22368d2a0baad05ea6049e4c3d5e8cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 14 May 2024 10:11:56 +0200 Subject: [PATCH 3447/4321] pkcs15.c: Fix memory leak When sc_pkcs15_read_cached_file allocates data pointer but following sc_select_file fails, the data pointer is rewritten by another malloc. --- src/libopensc/pkcs15.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index bb03ac7ec6..3f3198d3bc 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2549,6 +2549,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat } } + free(data); data = malloc(len); if (data == NULL) { r = SC_ERROR_OUT_OF_MEMORY; From 865cb43a8c81b1a8a0a44f0d439b0d50494084a5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 10 May 2024 10:25:31 +0200 Subject: [PATCH 3448/4321] Use zlib-ng for Fedora It should be ABI compatible with the old zlib https://fedoraproject.org/wiki/Changes/ZlibNGTransition --- .github/setup-fedora.sh | 4 ++-- packaging/opensc.spec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 5f280cea92..4cbeb743d2 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -13,9 +13,9 @@ fi # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then - DEPS="$DEPS pcsc-lite-devel*.i686 readline-devel*.i686 openssl-devel*.i686 zlib-devel*.i686 libcmocka-devel*.i686 glibc-devel*i686" + DEPS="$DEPS pcsc-lite-devel*.i686 readline-devel*.i686 openssl-devel*.i686 zlib-ng-devel*.i686 libcmocka-devel*.i686 glibc-devel*i686" else - DEPS="$DEPS pcsc-lite-devel readline-devel openssl-devel zlib-devel libcmocka-devel" + DEPS="$DEPS pcsc-lite-devel readline-devel openssl-devel zlib-ng-devel libcmocka-devel" fi sudo dnf install -y $DEPS diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 7310d80058..5700e62e66 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -16,7 +16,7 @@ BuildRequires: /usr/bin/xsltproc BuildRequires: docbook-style-xsl BuildRequires: autoconf automake libtool gcc BuildRequires: bash-completion -BuildRequires: zlib-devel +BuildRequires: zlib-ng-devel # For tests BuildRequires: libcmocka-devel BuildRequires: vim-common From 5d040b34d15f78b75856ab8619eea106954dd183 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Mar 2024 15:31:34 +0100 Subject: [PATCH 3449/4321] Add support for SHA3 mechanisms --- src/pkcs11/pkcs11-display.c | 42 +++++- src/pkcs11/pkcs11.h | 1 + src/tests/p11test/p11test_case_common.c | 58 +++++++- src/tests/p11test/p11test_case_common.h | 2 +- src/tests/p11test/p11test_case_mechs.c | 60 +++++---- src/tests/p11test/p11test_case_pss_oaep.c | 155 ++++++++++++++++------ src/tests/p11test/p11test_case_readonly.c | 60 +++++++-- src/tests/p11test/p11test_common.h | 3 +- 8 files changed, 296 insertions(+), 85 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 9a4f2188f9..b561d5a262 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -315,9 +315,14 @@ static enum_specs ck_mec_s[] = { { CKM_MD2_RSA_PKCS , "CKM_MD2_RSA_PKCS " }, { CKM_MD5_RSA_PKCS , "CKM_MD5_RSA_PKCS " }, { CKM_SHA1_RSA_PKCS , "CKM_SHA1_RSA_PKCS " }, + { CKM_SHA224_RSA_PKCS , "CKM_SHA224_RSA_PKCS " }, { CKM_SHA256_RSA_PKCS , "CKM_SHA256_RSA_PKCS " }, { CKM_SHA384_RSA_PKCS , "CKM_SHA384_RSA_PKCS " }, { CKM_SHA512_RSA_PKCS , "CKM_SHA512_RSA_PKCS " }, + { CKM_SHA3_224_RSA_PKCS , "CKM_SHA3_224_RSA_PKCS " }, + { CKM_SHA3_256_RSA_PKCS , "CKM_SHA3_256_RSA_PKCS " }, + { CKM_SHA3_384_RSA_PKCS , "CKM_SHA3_383_RSA_PKCS " }, + { CKM_SHA3_512_RSA_PKCS , "CKM_SHA3_512_RSA_PKCS " }, { CKM_RIPEMD128_RSA_PKCS , "CKM_RIPEMD128_RSA_PKCS " }, { CKM_RIPEMD160_RSA_PKCS , "CKM_RIPEMD160_RSA_PKCS " }, { CKM_RSA_PKCS_OAEP , "CKM_RSA_PKCS_OAEP " }, @@ -326,9 +331,14 @@ static enum_specs ck_mec_s[] = { { CKM_SHA1_RSA_X9_31 , "CKM_SHA1_RSA_X9_31 " }, { CKM_RSA_PKCS_PSS , "CKM_RSA_PKCS_PSS " }, { CKM_SHA1_RSA_PKCS_PSS , "CKM_SHA1_RSA_PKCS_PSS " }, + { CKM_SHA224_RSA_PKCS_PSS , "CKM_SHA224_RSA_PKCS_PSS " }, { CKM_SHA256_RSA_PKCS_PSS , "CKM_SHA256_RSA_PKCS_PSS " }, { CKM_SHA384_RSA_PKCS_PSS , "CKM_SHA384_RSA_PKCS_PSS " }, { CKM_SHA512_RSA_PKCS_PSS , "CKM_SHA512_RSA_PKCS_PSS " }, + { CKM_SHA3_224_RSA_PKCS_PSS , "CKM_SHA3_224_RSA_PKCS_PSS " }, + { CKM_SHA3_256_RSA_PKCS_PSS , "CKM_SHA3_256_RSA_PKCS_PSS " }, + { CKM_SHA3_384_RSA_PKCS_PSS , "CKM_SHA3_384_RSA_PKCS_PSS " }, + { CKM_SHA3_512_RSA_PKCS_PSS , "CKM_SHA3_512_RSA_PKCS_PSS " }, { CKM_DSA_KEY_PAIR_GEN , "CKM_DSA_KEY_PAIR_GEN " }, { CKM_DSA , "CKM_DSA " }, { CKM_DSA_SHA1 , "CKM_DSA_SHA1 " }, @@ -394,6 +404,9 @@ static enum_specs ck_mec_s[] = { { CKM_RIPEMD160 , "CKM_RIPEMD160 " }, { CKM_RIPEMD160_HMAC , "CKM_RIPEMD160_HMAC " }, { CKM_RIPEMD160_HMAC_GENERAL , "CKM_RIPEMD160_HMAC_GENERAL " }, + { CKM_SHA224 , "CKM_SHA224 " }, + { CKM_SHA224_HMAC , "CKM_SHA224_HMAC " }, + { CKM_SHA224_HMAC_GENERAL , "CKM_SHA224_HMAC_GENERAL " }, { CKM_SHA256 , "CKM_SHA256 " }, { CKM_SHA256_HMAC , "CKM_SHA256_HMAC " }, { CKM_SHA256_HMAC_GENERAL , "CKM_SHA256_HMAC_GENERAL " }, @@ -497,11 +510,19 @@ static enum_specs ck_mec_s[] = { { CKM_EC_KEY_PAIR_GEN , "CKM_EC_KEY_PAIR_GEN " }, { CKM_ECDSA , "CKM_ECDSA " }, { CKM_ECDSA_SHA1 , "CKM_ECDSA_SHA1 " }, + { CKM_ECDSA_SHA224 , "CKM_ECDSA_SHA224 " }, + { CKM_ECDSA_SHA256 , "CKM_ECDSA_SHA256 " }, + { CKM_ECDSA_SHA384 , "CKM_ECDSA_SHA384 " }, + { CKM_ECDSA_SHA512 , "CKM_ECDSA_SHA512 " }, + { CKM_ECDSA_SHA3_224 , "CKM_ECDSA_SHA3_224 " }, + { CKM_ECDSA_SHA3_256 , "CKM_ECDSA_SHA3_256 " }, + { CKM_ECDSA_SHA3_384 , "CKM_ECDSA_SHA3_384 " }, + { CKM_ECDSA_SHA3_512 , "CKM_ECDSA_SHA3_512 " }, { CKM_ECDH1_DERIVE , "CKM_ECDH1_DERIVE " }, { CKM_ECDH1_COFACTOR_DERIVE , "CKM_ECDH1_COFACTOR_DERIVE " }, { CKM_ECMQV_DERIVE , "CKM_ECMQV_DERIVE " }, { CKM_EDDSA , "CKM_EDDSA " }, - { CKM_XEDDSA , "CKM_XEDDSA " }, + { CKM_XEDDSA , "CKM_XEDDSA " }, { CKM_JUNIPER_KEY_GEN , "CKM_JUNIPER_KEY_GEN " }, { CKM_JUNIPER_ECB128 , "CKM_JUNIPER_ECB128 " }, { CKM_JUNIPER_CBC128 , "CKM_JUNIPER_CBC128 " }, @@ -520,6 +541,11 @@ static enum_specs ck_mec_s[] = { { CKM_AES_CCM , "CKM_AES_CCM " }, { CKM_AES_CMAC , "CKM_AES_CMAC " }, { CKM_AES_CTS , "CKM_AES_CTS " }, + { CKM_AES_OFB , "CKM_AES_OFB " }, + { CKM_AES_CFB64 , "CKM_AES_CFB64 " }, + { CKM_AES_CFB8 , "CKM_AES_CFB8 " }, + { CKM_AES_CFB128 , "CKM_AES_CFB128 " }, + { CKM_AES_CFB1 , "CKM_AES_CFB1 " }, { CKM_BLOWFISH_KEY_GEN , "CKM_BLOWFISH_KEY_GEN " }, { CKM_BLOWFISH_CBC , "CKM_BLOWFISH_CBC " }, { CKM_TWOFISH_KEY_GEN , "CKM_TWOFISH_KEY_GEN " }, @@ -550,11 +576,15 @@ static enum_specs ck_mec_s[] = { }; static enum_specs ck_mgf_s[] = { - { CKG_MGF1_SHA1 , "CKG_MGF1_SHA1 " }, - { CKG_MGF1_SHA224, "CKG_MGF1_SHA224" }, - { CKG_MGF1_SHA256, "CKG_MGF1_SHA256" }, - { CKG_MGF1_SHA384, "CKG_MGF1_SHA384" }, - { CKG_MGF1_SHA512, "CKG_MGF1_SHA512" }, + { CKG_MGF1_SHA1 , "CKG_MGF1_SHA1 " }, + { CKG_MGF1_SHA224 , "CKG_MGF1_SHA224 " }, + { CKG_MGF1_SHA256 , "CKG_MGF1_SHA256 " }, + { CKG_MGF1_SHA384 , "CKG_MGF1_SHA384 " }, + { CKG_MGF1_SHA512 , "CKG_MGF1_SHA512 " }, + { CKG_MGF1_SHA3_224, "CKG_MGF1_SHA3_224" }, + { CKG_MGF1_SHA3_256, "CKG_MGF1_SHA3_256" }, + { CKG_MGF1_SHA3_384, "CKG_MGF1_SHA3_384" }, + { CKG_MGF1_SHA3_512, "CKG_MGF1_SHA3_512" }, }; static enum_specs ck_err_s[] = { diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index b5bbd8e2c9..49c16b74b1 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -809,6 +809,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_CFB64 (0x2105UL) #define CKM_AES_CFB8 (0x2106UL) #define CKM_AES_CFB128 (0x2107UL) +#define CKM_AES_CFB1 (0x2108UL) #define CKM_AES_KEY_WRAP (0x2109UL) #define CKM_AES_KEY_WRAP_PAD (0x210AUL) #define CKM_XEDDSA (0x4029UL) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 6c4e63976f..14304d9988 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -1023,6 +1023,14 @@ const char *get_mechanism_name(unsigned long mech_id) return "SHA384_RSA_PKCS"; case CKM_SHA512_RSA_PKCS: return "SHA512_RSA_PKCS"; + case CKM_SHA3_224_RSA_PKCS: + return "SHA3_224_RSA_PKCS"; + case CKM_SHA3_256_RSA_PKCS: + return "SHA3_256_RSA_PKCS"; + case CKM_SHA3_384_RSA_PKCS: + return "SHA3_384_RSA_PKCS"; + case CKM_SHA3_512_RSA_PKCS: + return "SHA3_512_RSA_PKCS"; case CKM_RSA_X_509: return "RSA_X_509"; case CKM_ECDSA: @@ -1037,6 +1045,14 @@ const char *get_mechanism_name(unsigned long mech_id) return "ECDSA_SHA384"; case CKM_ECDSA_SHA512: return "ECDSA_SHA512"; + case CKM_ECDSA_SHA3_224: + return "ECDSA_SHA3_224"; + case CKM_ECDSA_SHA3_256: + return "ECDSA_SHA3_256"; + case CKM_ECDSA_SHA3_384: + return "ECDSA_SHA3_384"; + case CKM_ECDSA_SHA3_512: + return "ECDSA_SHA3_512"; case CKM_EDDSA: return "EDDSA"; case CKM_XEDDSA: @@ -1069,18 +1085,36 @@ const char *get_mechanism_name(unsigned long mech_id) return "SHA384_RSA_PKCS_PSS"; case CKM_SHA512_RSA_PKCS_PSS: return "SHA512_RSA_PKCS_PSS"; + case CKM_SHA3_224_RSA_PKCS_PSS: + return "SHA3_224_RSA_PKCS_PSS"; + case CKM_SHA3_256_RSA_PKCS_PSS: + return "SHA3_256_RSA_PKCS_PSS"; + case CKM_SHA3_384_RSA_PKCS_PSS: + return "SHA3_384_RSA_PKCS_PSS"; + case CKM_SHA3_512_RSA_PKCS_PSS: + return "SHA3_512_RSA_PKCS_PSS"; case CKM_MD5_HMAC: return "MD5_HMAC"; case CKM_SHA_1_HMAC: return "SHA_1_HMAC"; + case CKM_SHA_1_HMAC_GENERAL: + return "SHA_1_HMAC_GENERAL"; case CKM_SHA224_HMAC: return "SHA224_HMAC"; + case CKM_SHA224_HMAC_GENERAL: + return "SHA224_HMAC_GENERAL"; case CKM_SHA256_HMAC: return "SHA256_HMAC"; + case CKM_SHA256_HMAC_GENERAL: + return "SHA256_HMAC_GENERAL"; case CKM_SHA384_HMAC: return "SHA384_HMAC"; + case CKM_SHA384_HMAC_GENERAL: + return "SHA384_HMAC_GENERAL"; case CKM_SHA512_HMAC: return "SHA512_HMAC"; + case CKM_SHA512_HMAC_GENERAL: + return "SHA512_HMAC_GENERAL"; case CKM_RSA_PKCS_OAEP: return "RSA_PKCS_OAEP"; case CKM_RIPEMD160: @@ -1182,6 +1216,14 @@ const char *get_mgf_name(unsigned long mgf_id) return "MGF1_SHA384"; case CKG_MGF1_SHA512: return "MGF1_SHA512"; + case CKG_MGF1_SHA3_224: + return "MGF1_SHA3_224"; + case CKG_MGF1_SHA3_256: + return "MGF1_SHA3_256"; + case CKG_MGF1_SHA3_384: + return "MGF1_SHA3_384"; + case CKG_MGF1_SHA3_512: + return "MGF1_SHA3_512"; default: sprintf(name_buffer, "0x%.8lX", mgf_id); return name_buffer; @@ -1312,12 +1354,16 @@ void write_data_row(token_info_t *info, int cols, ...) int is_pss_mechanism(CK_MECHANISM_TYPE mech) { - return (mech == CKM_RSA_PKCS_PSS - || mech == CKM_SHA1_RSA_PKCS_PSS - || mech == CKM_SHA256_RSA_PKCS_PSS - || mech == CKM_SHA384_RSA_PKCS_PSS - || mech == CKM_SHA512_RSA_PKCS_PSS - || mech == CKM_SHA224_RSA_PKCS_PSS); + return (mech == CKM_RSA_PKCS_PSS || + mech == CKM_SHA1_RSA_PKCS_PSS || + mech == CKM_SHA256_RSA_PKCS_PSS || + mech == CKM_SHA384_RSA_PKCS_PSS || + mech == CKM_SHA512_RSA_PKCS_PSS || + mech == CKM_SHA224_RSA_PKCS_PSS || + mech == CKM_SHA3_256_RSA_PKCS_PSS || + mech == CKM_SHA3_384_RSA_PKCS_PSS || + mech == CKM_SHA3_512_RSA_PKCS_PSS || + mech == CKM_SHA3_224_RSA_PKCS_PSS); } CK_RV diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index b16fa12d6f..a9d91c572e 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -58,7 +58,7 @@ typedef struct { CK_ULONG bits; char *value; int verify_public; - test_mech_t mechs[MAX_MECHS]; + test_mech_t mechs[MAX_PSS_MECHS]; size_t num_mechs; } test_cert_t; diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index 4289c6ccaf..3e763789fc 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -84,22 +84,30 @@ supported_mechanisms_test(void **state) /* store mechanisms list for later tests */ /* List all known RSA mechanisms */ - if (mechanism_list[i] == CKM_RSA_X_509 - || mechanism_list[i] == CKM_RSA_PKCS - || mechanism_list[i] == CKM_MD5_RSA_PKCS - || mechanism_list[i] == CKM_RIPEMD160_RSA_PKCS - || mechanism_list[i] == CKM_SHA1_RSA_PKCS - || mechanism_list[i] == CKM_SHA224_RSA_PKCS - || mechanism_list[i] == CKM_SHA256_RSA_PKCS - || mechanism_list[i] == CKM_SHA384_RSA_PKCS - || mechanism_list[i] == CKM_SHA512_RSA_PKCS - || mechanism_list[i] == CKM_RSA_PKCS_PSS - || mechanism_list[i] == CKM_SHA1_RSA_PKCS_PSS - || mechanism_list[i] == CKM_SHA256_RSA_PKCS_PSS - || mechanism_list[i] == CKM_SHA384_RSA_PKCS_PSS - || mechanism_list[i] == CKM_SHA512_RSA_PKCS_PSS - || mechanism_list[i] == CKM_SHA224_RSA_PKCS_PSS - || mechanism_list[i] == CKM_RSA_PKCS_OAEP) { + if (mechanism_list[i] == CKM_RSA_X_509 || + mechanism_list[i] == CKM_RSA_PKCS || + mechanism_list[i] == CKM_MD5_RSA_PKCS || + mechanism_list[i] == CKM_RIPEMD160_RSA_PKCS || + mechanism_list[i] == CKM_SHA1_RSA_PKCS || + mechanism_list[i] == CKM_SHA224_RSA_PKCS || + mechanism_list[i] == CKM_SHA256_RSA_PKCS || + mechanism_list[i] == CKM_SHA384_RSA_PKCS || + mechanism_list[i] == CKM_SHA512_RSA_PKCS || + mechanism_list[i] == CKM_SHA3_224_RSA_PKCS || + mechanism_list[i] == CKM_SHA3_256_RSA_PKCS || + mechanism_list[i] == CKM_SHA3_384_RSA_PKCS || + mechanism_list[i] == CKM_SHA3_512_RSA_PKCS || + mechanism_list[i] == CKM_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA1_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA256_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA384_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA512_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA224_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA3_224_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA3_256_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA3_384_RSA_PKCS_PSS || + mechanism_list[i] == CKM_SHA3_512_RSA_PKCS_PSS || + mechanism_list[i] == CKM_RSA_PKCS_OAEP) { if (token.num_rsa_mechs < MAX_MECHS) { insert_mechanism(token.rsa_mechs, &token.num_rsa_mechs, mechanism_list[i], mechanism_info[i]); @@ -108,15 +116,19 @@ supported_mechanisms_test(void **state) } /* We list all known EC mechanisms */ - if (mechanism_list[i] == CKM_ECDSA - || mechanism_list[i] == CKM_ECDSA_SHA1 - || mechanism_list[i] == CKM_ECDSA_SHA256 - || mechanism_list[i] == CKM_ECDSA_SHA384 - || mechanism_list[i] == CKM_ECDSA_SHA512 + if (mechanism_list[i] == CKM_ECDSA || + mechanism_list[i] == CKM_ECDSA_SHA1 || + mechanism_list[i] == CKM_ECDSA_SHA256 || + mechanism_list[i] == CKM_ECDSA_SHA384 || + mechanism_list[i] == CKM_ECDSA_SHA512 || + mechanism_list[i] == CKM_ECDSA_SHA3_224 || + mechanism_list[i] == CKM_ECDSA_SHA3_256 || + mechanism_list[i] == CKM_ECDSA_SHA3_384 || + mechanism_list[i] == CKM_ECDSA_SHA3_512 || /* Including derive mechanisms */ - || mechanism_list[i] == CKM_ECDH1_DERIVE - || mechanism_list[i] == CKM_ECDH1_COFACTOR_DERIVE - || mechanism_list[i] == CKM_ECMQV_DERIVE) { + mechanism_list[i] == CKM_ECDH1_DERIVE || + mechanism_list[i] == CKM_ECDH1_COFACTOR_DERIVE || + mechanism_list[i] == CKM_ECMQV_DERIVE) { if (token.num_ec_mechs < MAX_MECHS) { insert_mechanism(token.ec_mechs, &token.num_ec_mechs, mechanism_list[i], mechanism_info[i]); diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 7498581621..597e0a0d3e 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -34,7 +34,7 @@ size_t global_message_length = sizeof(SHORT_MESSAGE_TO_SIGN); const CK_MECHANISM_TYPE * get_oaep_mechanism_hashes(CK_MECHANISM_TYPE mech) { - static CK_MECHANISM_TYPE h[6]; + static CK_MECHANISM_TYPE h[10]; switch (mech) { case CKM_RSA_PKCS_OAEP: @@ -43,7 +43,11 @@ get_oaep_mechanism_hashes(CK_MECHANISM_TYPE mech) h[2] = CKM_SHA256; h[3] = CKM_SHA384; h[4] = CKM_SHA512; - h[5] = -1; + h[5] = CKM_SHA3_224; + h[6] = CKM_SHA3_256; + h[7] = CKM_SHA3_384; + h[8] = CKM_SHA3_512; + h[9] = -1; break; default: @@ -56,7 +60,7 @@ get_oaep_mechanism_hashes(CK_MECHANISM_TYPE mech) const CK_MECHANISM_TYPE * get_pss_mechanism_hashes(CK_MECHANISM_TYPE mech) { - static CK_MECHANISM_TYPE h[6]; + static CK_MECHANISM_TYPE h[10]; switch (mech) { case CKM_RSA_PKCS_PSS: @@ -65,7 +69,11 @@ get_pss_mechanism_hashes(CK_MECHANISM_TYPE mech) h[2] = CKM_SHA256; h[3] = CKM_SHA384; h[4] = CKM_SHA512; - h[5] = -1; + h[5] = CKM_SHA3_224; + h[6] = CKM_SHA3_256; + h[7] = CKM_SHA3_384; + h[8] = CKM_SHA3_512; + h[9] = -1; break; case CKM_SHA1_RSA_PKCS_PSS: @@ -93,6 +101,26 @@ get_pss_mechanism_hashes(CK_MECHANISM_TYPE mech) h[1] = -1; break; + case CKM_SHA3_224_RSA_PKCS_PSS: + h[0] = CKM_SHA3_224; + h[1] = -1; + break; + + case CKM_SHA3_256_RSA_PKCS_PSS: + h[0] = CKM_SHA3_256; + h[1] = -1; + break; + + case CKM_SHA3_384_RSA_PKCS_PSS: + h[0] = CKM_SHA3_384; + h[1] = -1; + break; + + case CKM_SHA3_512_RSA_PKCS_PSS: + h[0] = CKM_SHA3_512; + h[1] = -1; + break; + default: h[0] = -1; break; @@ -113,13 +141,19 @@ get_mechanism_hashes(CK_MECHANISM_TYPE mech) const CK_RSA_PKCS_MGF_TYPE * get_mgfs(void) { - static CK_RSA_PKCS_MGF_TYPE h[6]; + static CK_RSA_PKCS_MGF_TYPE h[10]; + h[0] = CKG_MGF1_SHA1; h[1] = CKG_MGF1_SHA224; h[2] = CKG_MGF1_SHA256; h[3] = CKG_MGF1_SHA384; h[4] = CKG_MGF1_SHA512; - h[5] = -1; + h[5] = CKG_MGF1_SHA3_224; + h[6] = CKG_MGF1_SHA3_256; + h[7] = CKG_MGF1_SHA3_384; + h[8] = CKG_MGF1_SHA3_512; + h[9] = -1; + return h; } @@ -138,6 +172,18 @@ const EVP_MD *mgf_cryptoki_to_ossl(CK_RSA_PKCS_MGF_TYPE mgf) case CKG_MGF1_SHA512: return EVP_sha512(); + case CKG_MGF1_SHA3_224: + return EVP_sha3_224(); + + case CKG_MGF1_SHA3_256: + return EVP_sha3_256(); + + case CKG_MGF1_SHA3_384: + return EVP_sha3_384(); + + case CKG_MGF1_SHA3_512: + return EVP_sha3_512(); + case CKG_MGF1_SHA1: default: return EVP_sha1(); @@ -161,6 +207,18 @@ const EVP_MD *md_cryptoki_to_ossl(CK_MECHANISM_TYPE hash) case CKM_SHA512: return EVP_sha512(); + case CKM_SHA3_224: + return EVP_sha3_224(); + + case CKM_SHA3_256: + return EVP_sha3_256(); + + case CKM_SHA3_384: + return EVP_sha3_384(); + + case CKM_SHA3_512: + return EVP_sha3_512(); + case CKM_SHA_1: default: return EVP_sha1(); @@ -179,6 +237,14 @@ size_t get_hash_length(CK_MECHANISM_TYPE mech) return SHA384_DIGEST_LENGTH; case CKM_SHA512: return SHA512_DIGEST_LENGTH; + case CKM_SHA3_224: + return 224 / 8; + case CKM_SHA3_256: + return 256 / 8; + case CKM_SHA3_384: + return 384 / 8; + case CKM_SHA3_512: + return 512 / 8; default: case CKM_SHA_1: return SHA_DIGEST_LENGTH; @@ -213,6 +279,26 @@ CK_BYTE *hash_message(const CK_BYTE *message, size_t message_length, md = EVP_sha512(); break; + case CKM_SHA3_224: + digest_len = 224 / 8; + md = EVP_sha3_224(); + break; + + case CKM_SHA3_256: + digest_len = 256 / 8; + md = EVP_sha3_256(); + break; + + case CKM_SHA3_384: + digest_len = 384 / 8; + md = EVP_sha3_384(); + break; + + case CKM_SHA3_512: + digest_len = 512 / 8; + md = EVP_sha3_512(); + break; + case CKM_SHA_1: default: digest_len = SHA_DIGEST_LENGTH; @@ -735,10 +821,8 @@ void fill_object_pss_mechanisms(token_info_t *info, test_cert_t *o) mech->usage_flags = source_mech->usage_flags; mech->result_flags = 0; - if (n >= MAX_MECHS) - P11TEST_FAIL(info, - "Too many mechanisms (%d)", - MAX_MECHS); + if (n >= MAX_PSS_MECHS) + P11TEST_FAIL(info, "Too many mechanisms (%d)", MAX_PSS_MECHS); } } } @@ -816,8 +900,8 @@ void pss_oaep_test(void **state) { /* print summary */ printf("[KEY ID] [LABEL]\n"); - printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT]\n"); - printf("[ MECHANISM ] [ HASH ] [ MGF ] [SALT] [ WORKS ] [ WORKS ]\n"); + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT]\n"); + printf("[ MECHANISM ] [ HASH ] [ MGF ] [SALT] [ WORKS ] [ WORKS ]\n"); P11TEST_DATA_ROW(info, 7, 's', "KEY ID", 's', "MECHANISM", @@ -840,30 +924,27 @@ void pss_oaep_test(void **state) { printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s]\n", - o->key_type == CKK_RSA ? "RSA " : - o->key_type == CKK_EC ? " EC " : " ?? ", - o->bits, - o->verify_public == 1 ? " ./ " : " ", - o->sign ? "[./] " : "[ ] ", - o->verify ? " [./] " : " [ ] ", - o->encrypt ? "[./] " : "[ ] ", - o->decrypt ? " [./] " : " [ ] "); + printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s]\n", + o->key_type == CKK_RSA ? "RSA " : " ?? ", + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] "); if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { printf(" no usable attributes found ... ignored\n"); continue; } for (j = 0; j < o->num_mechs; j++) { test_mech_t *mech = &o->mechs[j]; - printf(" [ %-20s ] [%-6s] [%-11s] [%4d] [ %s ] [ %s ]\n", - get_mechanism_name(mech->mech), - get_mechanism_name(mech->hash), - get_mgf_name(mech->mgf), - mech->salt, - mech->result_flags & FLAGS_SIGN_ANY - ? "[./]" : " ", - mech->result_flags & FLAGS_DECRYPT_ANY - ? "[./]" : " "); + printf(" [ %-20s ] [%-8s] [%-13s] [%4d] [ %s ] [ %s ]\n", + get_mechanism_name(mech->mech), + get_mechanism_name(mech->hash), + get_mgf_name(mech->mgf), + mech->salt, + mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", + mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); if ((mech->result_flags & FLAGS_SIGN_ANY) == 0 && (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) continue; /* skip empty rows for export */ @@ -879,13 +960,13 @@ void pss_oaep_test(void **state) { ? "YES" : ""); } } - printf(" Public == Cert ----------^ ^ ^ ^ ^ ^ ^\n"); - printf(" Sign Attribute -------------------------------------------' | | | | |\n"); - printf(" Sign&Verify functionality -----------------------------------' | | | |\n"); - printf(" Verify Attribute -----------------------------------------------' | | |\n"); - printf(" Encrypt Attribute ------------------------------------------------------' | |\n"); - printf(" Encrypt & Decrypt functionality -------------------------------------------' |\n"); - printf(" Decrypt Attribute ------------------------------------------------------------'\n"); + printf(" Public == Cert ----------^ ^ ^ ^ ^ ^ ^\n"); + printf(" Sign Attribute -----------------------------------------------' | | | | |\n"); + printf(" Sign&Verify functionality ---------------------------------------' | | | |\n"); + printf(" Verify Attribute ---------------------------------------------------' | | |\n"); + printf(" Encrypt Attribute ----------------------------------------------------------' | |\n"); + printf(" Encrypt & Decrypt functionality -----------------------------------------------' |\n"); + printf(" Decrypt Attribute ----------------------------------------------------------------'\n"); clean_all_objects(&objects); P11TEST_PASS(info); diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index b83f00531f..1ed5bfba52 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -394,7 +394,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_BYTE *cmp_message = NULL; - unsigned long cmp_message_length; + unsigned int cmp_message_length; if (o->type == EVP_PKEY_RSA) { const EVP_MD *md = NULL; @@ -437,6 +437,18 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, case CKM_SHA512_RSA_PKCS: md = EVP_sha512(); break; + case CKM_SHA3_224_RSA_PKCS: + md = EVP_sha3_224(); + break; + case CKM_SHA3_256_RSA_PKCS: + md = EVP_sha3_256(); + break; + case CKM_SHA3_384_RSA_PKCS: + md = EVP_sha3_384(); + break; + case CKM_SHA3_512_RSA_PKCS: + md = EVP_sha3_512(); + break; case CKM_MD5_RSA_PKCS: md = EVP_md5(); break; @@ -470,6 +482,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, return 1; } else if (o->type == EVP_PKEY_EC) { int nlen; + const EVP_MD *md = NULL; ECDSA_SIG *sig = ECDSA_SIG_new(); BIGNUM *r = NULL, *s = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -488,24 +501,32 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, switch (mech->mech) { case CKM_ECDSA_SHA512: - cmp_message = SHA512(message, message_length, NULL); - cmp_message_length = SHA512_DIGEST_LENGTH; + md = EVP_sha512(); break; case CKM_ECDSA_SHA384: - cmp_message = SHA384(message, message_length, NULL); - cmp_message_length = SHA384_DIGEST_LENGTH; + md = EVP_sha384(); break; case CKM_ECDSA_SHA256: - cmp_message = SHA256(message, message_length, NULL); - cmp_message_length = SHA256_DIGEST_LENGTH; + md = EVP_sha256(); break; case CKM_ECDSA_SHA1: - cmp_message = SHA1(message, message_length, NULL); - cmp_message_length = SHA_DIGEST_LENGTH; + md = EVP_sha1(); break; case CKM_ECDSA: cmp_message = message; - cmp_message_length = message_length; + cmp_message_length = (unsigned)message_length; + break; + case CKM_ECDSA_SHA3_224: + md = EVP_sha3_224(); + break; + case CKM_ECDSA_SHA3_256: + md = EVP_sha3_256(); + break; + case CKM_ECDSA_SHA3_384: + md = EVP_sha3_384(); + break; + case CKM_ECDSA_SHA3_512: + md = EVP_sha3_512(); break; default: debug_print(" [SKIP %s ] Skip verify of unknown mechanism", o->id_str); @@ -518,12 +539,31 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, sig_asn1_len = i2d_ECDSA_SIG(sig, &sig_asn1); ECDSA_SIG_free(sig); + if (md != NULL) { + cmp_message = malloc(EVP_MAX_MD_SIZE); + if (cmp_message == NULL) { + fprintf(stderr, "malloc failed\n"); + return -1; + } + rv = EVP_Digest(message, message_length, cmp_message, &cmp_message_length, md, NULL); + if (rv != 1) { + fprintf(stderr, "EVP_Digest failed\n"); + free(cmp_message); + return -1; + } + } + if (EVP_PKEY_verify_init(ctx) != 1) { fprintf(stderr, "EVP_PKEY_verify_init\n"); + free(cmp_message); + return -1; } rv = EVP_PKEY_verify(ctx, sig_asn1, sig_asn1_len, cmp_message, cmp_message_length); OPENSSL_free(sig_asn1); + if (md != NULL) { + free(cmp_message); + } EVP_PKEY_CTX_free(ctx); if (rv == 1) { debug_print(" [ OK %s ] EC Signature of length %lu is valid.", diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index 9aff6b9319..d2d6288daf 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -31,7 +31,8 @@ #include "pkcs11/pkcs11.h" #include "libopensc/sc-ossl-compat.h" -#define MAX_MECHS 200 +#define MAX_MECHS 256 +#define MAX_PSS_MECHS 1024 #define debug_print(fmt, ...) \ do { \ From 9be88a25f03150ed5eacd8fdb4ba5d1db6a98e22 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 25 Mar 2024 13:55:30 +0100 Subject: [PATCH 3450/4321] pkcs11: Add CCM params --- src/pkcs11/pkcs11-spy.c | 15 +++++++++++++++ src/pkcs11/pkcs11.h | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 1eb354918b..f15c9cdf93 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -450,6 +450,21 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) break; } break; + case CKM_AES_CCM: + if (pMechanism->pParameter != NULL) { + CK_CCM_PARAMS *param = (CK_CCM_PARAMS *)pMechanism->pParameter; + snprintf(param_name, sizeof(param_name), "%s->pParameter->ulDataLen", name); + spy_dump_ulong_in(param_name, param->ulDataLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pNonce[ulNonceLen]", name); + spy_dump_string_in(param_name, param->pNonce, param->ulNonceLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pAAD[ulAADLen]", name); + spy_dump_string_in(param_name, param->pAAD, param->ulAADLen); + fprintf(spy_output, "[in] %s->pParameter->ulMacLen = %lu\n", name, param->ulMACLen); + } else { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + break; + } + break; case CKM_ECDH1_DERIVE: case CKM_ECDH1_COFACTOR_DERIVE: if (pMechanism->pParameter != NULL) { diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 49c16b74b1..929afd92a1 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -934,6 +934,15 @@ typedef struct CK_GCM_PARAMS { unsigned long ulTagBits; } CK_GCM_PARAMS; +typedef struct CK_CCM_PARAMS { + unsigned long ulDataLen; + unsigned char *pNonce; + unsigned long ulNonceLen; + unsigned char *pAAD; + unsigned long ulAADLen; + unsigned long ulMACLen; +} CK_CCM_PARAMS; + /* EDDSA */ typedef struct CK_EDDSA_PARAMS { unsigned char phFlag; From d5336389b8b750ef064f28d030a6785240b1f666 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Apr 2024 10:03:24 +0200 Subject: [PATCH 3451/4321] spy: Log requested length when buffer is too small --- src/pkcs11/pkcs11-spy.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index f15c9cdf93..d73680098a 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -1035,8 +1035,11 @@ C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, spy_dump_ulong_in("hSession", hSession); spy_dump_string_in("pData[ulDataLen]", pData, ulDataLen); rv = po->C_Encrypt(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pEncryptedData[*pulEncryptedDataLen]", pEncryptedData, *pulEncryptedDataLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulEncryptedDataLen", *pulEncryptedDataLen); + } return retne(rv); } @@ -1063,9 +1066,12 @@ C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_UL enter("C_EncryptFinal"); spy_dump_ulong_in("hSession", hSession); rv = po->C_EncryptFinal(hSession, pLastEncryptedPart, pulLastEncryptedPartLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pLastEncryptedPart[*pulLastEncryptedPartLen]", pLastEncryptedPart, *pulLastEncryptedPartLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulLastEncryptedPartLen", *pulLastEncryptedPartLen); + } return retne(rv); } @@ -1093,8 +1099,11 @@ C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEn spy_dump_ulong_in("hSession", hSession); spy_dump_string_in("pEncryptedData[ulEncryptedDataLen]", pEncryptedData, ulEncryptedDataLen); rv = po->C_Decrypt(hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pData[*pulDataLen]", pData, *pulDataLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulDataLen", *pulDataLen); + } return retne(rv); } @@ -1123,8 +1132,11 @@ C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR p enter("C_DecryptFinal"); spy_dump_ulong_in("hSession", hSession); rv = po->C_DecryptFinal(hSession, pLastPart, pulLastPartLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pLastPart[*pulLastPartLen]", pLastPart, *pulLastPartLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulLastPartLen", *pulLastPartLen); + } return retne(rv); } @@ -1218,8 +1230,11 @@ C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, spy_dump_ulong_in("hSession", hSession); spy_dump_string_in("pData[ulDataLen]", pData, ulDataLen); rv = po->C_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pSignature[*pulSignatureLen]", pSignature, *pulSignatureLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulSignatureLen", *pulSignatureLen); + } return retne(rv); } @@ -1244,8 +1259,11 @@ C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pul enter("C_SignFinal"); spy_dump_ulong_in("hSession", hSession); rv = po->C_SignFinal(hSession, pSignature, pulSignatureLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pSignature[*pulSignatureLen]", pSignature, *pulSignatureLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulSignatureLen", *pulSignatureLen); + } return retne(rv); } @@ -1273,8 +1291,11 @@ C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen spy_dump_ulong_in("hSession", hSession); spy_dump_string_in("pData[ulDataLen]", pData, ulDataLen); rv = po->C_SignRecover(hSession, pData, ulDataLen, pSignature, pulSignatureLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pSignature[*pulSignatureLen]", pSignature, *pulSignatureLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulSignatureLen", *pulSignatureLen); + } return retne(rv); } @@ -1477,8 +1498,11 @@ C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, spy_dump_ulong_in("hWrappingKey", hWrappingKey); spy_dump_ulong_in("hKey", hKey); rv = po->C_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); - if (rv == CKR_OK) + if (rv == CKR_OK) { spy_dump_string_out("pWrappedKey[*pulWrappedKeyLen]", pWrappedKey, *pulWrappedKeyLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulWrappedKeyLen", *pulWrappedKeyLen); + } return retne(rv); } From 1db08690b9bca73f30133f8556d7e35374091af7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Apr 2024 16:25:33 +0200 Subject: [PATCH 3452/4321] spy: Dump the interface versions and better handle version faking In the past the queries for the interface were passed through directly to the underlying pkcs11 module. But this could cause an issue if the caller requested specific version reported by the GetInterfaceList. This changes improves faking of the version numbers and maps the minor versions to the correct major versions of the API. --- src/pkcs11/pkcs11-display.c | 9 +++++--- src/pkcs11/pkcs11-spy.c | 41 ++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index b561d5a262..a81cf26d27 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -1152,9 +1152,12 @@ print_interfaces_list(FILE *f, CK_INTERFACE_PTR pInterfacesList, CK_ULONG ulCoun if (pInterfacesList) { for (i = 0; i < ulCount; i++) { - fprintf(f, "Interface '%s' flags=%lx\n", - pInterfacesList[i].pInterfaceName, - pInterfacesList[i].flags); + CK_INTERFACE_PTR in = &pInterfacesList[i]; + fprintf(f, "Interface '%s' version=%d.%d flags=%lx\n", + in->pInterfaceName, + ((CK_VERSION *)(in->pFunctionList))->major, + ((CK_VERSION *)(in->pFunctionList))->minor, + in->flags); } } else { diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index d73680098a..d7172df915 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -51,6 +51,9 @@ static CK_FUNCTION_LIST_PTR pkcs11_spy = NULL; static CK_FUNCTION_LIST_3_0_PTR pkcs11_spy_3_0 = NULL; /* Real Module Function List */ static CK_FUNCTION_LIST_3_0_PTR po = NULL; +/* Real module interface list */ +static CK_INTERFACE_PTR orig_interfaces = NULL; +static unsigned long num_orig_interfaces = 0; /* Dynamic Module Handle */ static void *modhandle = NULL; /* Spy module output */ @@ -1666,17 +1669,30 @@ C_GetInterfaceList(CK_INTERFACE_PTR pInterfacesList, CK_ULONG_PTR pulCount) } rv = po->C_GetInterfaceList(pInterfacesList, pulCount); if (rv == CKR_OK) { - spy_dump_desc_out("pInterfacesList"); + spy_dump_desc_out("pInterfacesList (original)"); print_interfaces_list(spy_output, pInterfacesList, *pulCount); - spy_dump_ulong_out("*pulCount", *pulCount); - /* Now, replace function lists of known interfaces (PKCS 11, v 2.x and 3.0) */ if (pInterfacesList != NULL) { unsigned long i; + /* Record the module interface so we can transparently proxy the GetInterface calls */ + free(orig_interfaces); + num_orig_interfaces = 0; + orig_interfaces = malloc(*pulCount * sizeof(CK_INTERFACE)); + if (orig_interfaces == NULL) { + return CKR_HOST_MEMORY; + } + memcpy(orig_interfaces, pInterfacesList, *pulCount * sizeof(CK_INTERFACE)); + num_orig_interfaces = *pulCount; + + /* Now, replace function lists of known interfaces (PKCS 11, v 2.x and 3.0) */ for (i = 0; i < *pulCount; i++) { spy_interface_function_list(&pInterfacesList[i]); } } + + spy_dump_desc_out("pInterfacesList (faked)"); + print_interfaces_list(spy_output, pInterfacesList, *pulCount); + spy_dump_ulong_out("*pulCount", *pulCount); } return retne(rv); } @@ -1710,6 +1726,25 @@ C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, fprintf(spy_output, "[in] flags = %s\n", (flags & CKF_INTERFACE_FORK_SAFE ? "CKF_INTERFACE_FORK_SAFE" : "")); if (po->version.major >= 3) { + /* We can not assume the version we told the caller matches the version in the underlying + * pkcs11 module so map it back to the known ones */ + CK_VERSION in_version; + if ((pInterfaceName == NULL || strcmp((char *)pInterfaceName, "PKCS 11") == 0) && pVersion) { + for (unsigned long i = 0; i < num_orig_interfaces; i++) { + CK_VERSION *v = (CK_VERSION *)orig_interfaces[i].pFunctionList; + /* We found the same major version. Copy the minor and call it a day */ + if (v->major == pVersion->major) { + in_version.major = v->major; + in_version.minor = v->minor; + pVersion = &in_version; + fprintf(spy_output, "[in] pVersion = %d.%d (faked)\n", + pVersion->major, pVersion->minor); + break; + } + } + /* If not found, see what we will get */ + } + rv = po->C_GetInterface(pInterfaceName, pVersion, ppInterface, flags); if (rv == CKR_OK && ppInterface != NULL) { spy_interface_function_list(*ppInterface); From 05393f43af21e1e5a385809d666af7c5ffdc6773 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 6 May 2024 15:59:22 +0200 Subject: [PATCH 3453/4321] pkcs11: Print missing attribute --- src/pkcs11/pkcs11-display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index a81cf26d27..6da6f21b24 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -754,6 +754,7 @@ type_spec ck_attribute_specs[] = { { CKA_SUBJECT , "CKA_SUBJECT ", print_generic, NULL }, #endif { CKA_ID , "CKA_ID ", print_generic, NULL }, + { CKA_UNIQUE_ID , "CKA_UNIQUE_ID ", print_generic, NULL }, { CKA_SENSITIVE , "CKA_SENSITIVE ", print_boolean, NULL }, { CKA_ENCRYPT , "CKA_ENCRYPT ", print_boolean, NULL }, { CKA_DECRYPT , "CKA_DECRYPT ", print_boolean, NULL }, From f505b2cba5366a5f584f7e4b15fe424c30975ba2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 9 May 2024 19:21:57 +0200 Subject: [PATCH 3454/4321] pkcs11: Do not reformat lists --- src/pkcs11/pkcs11-display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 6da6f21b24..a3cad957ee 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -245,6 +245,7 @@ print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR fprintf(f, "\n"); } +// clang-format off static enum_specs ck_cls_s[] = { { CKO_DATA , "CKO_DATA " }, { CKO_CERTIFICATE , "CKO_CERTIFICATE " }, @@ -866,6 +867,7 @@ type_spec ck_attribute_specs[] = { { CKA_CERT_SHA1_HASH, "CKA_CERT_SHA1_HASH(Netsc) ", print_generic, NULL }, { CKA_CERT_MD5_HASH, "CKA_CERT_MD5_HASH(Netsc) ", print_generic, NULL }, }; +// clang-format on CK_ULONG ck_attribute_num = sizeof(ck_attribute_specs)/sizeof(type_spec); From 08206111fef381b59bed4adf0f55df8211059271 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 10 May 2024 13:03:44 +0200 Subject: [PATCH 3455/4321] pkcs11: Release operation on uknown params The invalid or unknown RSA OAEP decryption parameters caused the session kept holding the operation as started and all following operations failed as other operation was in progress. --- src/pkcs11/mechanism.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 0b49e2eda1..596b7a637c 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1066,10 +1066,6 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session, /* Validate the mechanism parameters */ if (key->ops->init_params) { rv = key->ops->init_params(operation->session, &operation->mechanism); - if (rv != CKR_OK) { - /* Probably bad arguments */ - LOG_FUNC_RETURN(context, (int) rv); - } } if (rv != CKR_OK) From ead7cac2549b5d200e1ff340768d47b59ebd922c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Mar 2024 11:51:13 +0100 Subject: [PATCH 3456/4321] p11test: Skip non-multipart mechanisms --- src/tests/p11test/p11test_case_multipart.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_multipart.c b/src/tests/p11test/p11test_case_multipart.c index c37babf69c..fdc8019a93 100644 --- a/src/tests/p11test/p11test_case_multipart.c +++ b/src/tests/p11test/p11test_case_multipart.c @@ -51,9 +51,17 @@ void multipart_tests(void **state) { /* XXX some keys do not have appropriate flags, but we can use them * or vice versa */ //if (objects.data[i].sign && objects.data[i].verify) - for (j = 0; j < objects.data[i].num_mechs; j++) - used |= sign_verify_test(&(objects.data[i]), info, + for (j = 0; j < objects.data[i].num_mechs; j++) { + switch (objects.data[i].mechs[j].mech) { + case CKM_RSA_X_509: + case CKM_RSA_PKCS: + case CKM_RSA_PKCS_PSS: + /* these should not support multi-part operations */ + continue; + } + used |= sign_verify_test(&(objects.data[i]), info, &(objects.data[i].mechs[j]), 32, 1); + } if (!used) { debug_print(" [ WARN %s ] Private key with unknown purpose T:%02lX", @@ -91,6 +99,14 @@ void multipart_tests(void **state) { } for (j = 0; j < o->num_mechs; j++) { test_mech_t *mech = &o->mechs[j]; + + switch (mech->mech) { + case CKM_RSA_X_509: + case CKM_RSA_PKCS: + case CKM_RSA_PKCS_PSS: + /* these do not support multi-part operations */ + continue; + } if ((mech->usage_flags & CKF_SIGN) == 0) { /* not applicable mechanisms are skipped */ continue; From f66c39bc7f1f078b2e30f3197e17586071c6d5e2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 18 Mar 2024 21:44:13 +0100 Subject: [PATCH 3457/4321] p11test: Skip objects without ID or label --- src/tests/p11test/p11test_case_common.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 14304d9988..bc6d80dcd1 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -261,6 +261,11 @@ int callback_certificates(test_certs_t *objects, if (*(CK_CERTIFICATE_TYPE *)template[3].pValue != CKC_X_509) return 0; + /* Ignore objects with empty ID -- we don't know what to do with them */ + if (template[0].ulValueLen == 0) { + return 0; + } + if ((o = add_object(objects, template[0], template[2])) == NULL) return -1; @@ -304,6 +309,11 @@ int callback_private_keys(test_certs_t *objects, test_cert_t *o = NULL; char *key_id; + /* Ignore objects with empty ID -- we don't know what to do with them */ + if (template[3].ulValueLen == 0) { + return 0; + } + /* Search for already stored certificate with same ID */ if ((o = search_certificate(objects, &(template[3]))) == NULL) { key_id = convert_byte_string(template[3].pValue, @@ -763,7 +773,7 @@ int callback_secret_keys(test_certs_t *objects, /* Ignore objects with empty ID and label that are left in SoftHSM after deriving key even after * destroying them */ - if (template[13].ulValueLen == 0 && template[1].ulValueLen == 0) { + if (template[13].pValue == NULL || template[1].pValue == NULL) { return 0; } @@ -803,7 +813,9 @@ int callback_secret_keys(test_certs_t *objects, template[10].pValue = NULL; } - o->bits = template[11].ulValueLen > 0 ? *((CK_ULONG *) template[11].pValue)*8 : 0; + if (template[11].pValue != NULL && template[11].ulValueLen > 0) { + o->bits = *((CK_ULONG *)template[11].pValue) * 8; + } add_supported_mechs(o); From aabcba482346dd965b7015bfa5948047b7cc2338 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 18 Mar 2024 21:44:56 +0100 Subject: [PATCH 3458/4321] p11test: Add support for kryoptic --- src/tests/p11test/runtest.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index d2fbdcbb12..e8d772c7e8 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -21,7 +21,6 @@ #set -x SOPIN="12345678" PIN="123456" -export GNUTLS_PIN=$PIN GENERATE_KEYS=1 PKCS11_TOOL="../../tools/pkcs11-tool"; PKCS15_INIT="env OPENSC_CONF=p11test_opensc.conf ../../tools/pkcs15-init" @@ -64,6 +63,7 @@ function generate_cert() { if [[ "$CERT" -ne 0 ]]; then # check type value for the PKCS#11 URI (RHEL7 is using old "object-type") TYPE_KEY="type" + export GNUTLS_PIN=$PIN p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \ TYPE_KEY="object-type" @@ -119,6 +119,15 @@ function card_setup() { echo "test_swtok" | /usr/sbin/pkcsconf -I -c $SLOT_ID -S $SO_PIN /usr/sbin/pkcsconf -u -c $SLOT_ID -S $SO_PIN -n $PIN ;; + "kryoptic") + PIN="$SOPIN" + P11LIB="/home/jjelen/devel/kryoptic/target/debug/libkryoptic_pkcs11.so" + KRYOPTIC_DB="kryoptic.sql" + export KRYOPTIC_CONF="$KRYOPTIC_DB:1" + # Init token + $PKCS11_TOOL --init-token --so-pin="$SOPIN" --label="Kryoptic token" --module="$P11LIB" + $PKCS11_TOOL --init-pin --pin="$PIN" --so-pin="$SOPIN" --label="Kryoptic token" --module="$P11LIB" + ;; "readonly") GENERATE_KEYS=0 if [[ ! -z "$2" && -f "$2" ]]; then @@ -165,7 +174,7 @@ function card_setup() { *) echo "Error: Missing argument." echo " Usage:" - echo " runtest.sh [softhsm|opencryptoki|myeid|sc-hsm|readonly [pkcs-library.so]]" + echo " runtest.sh [softhsm|opencryptoki|myeid|sc-hsm|kryoptic|readonly [pkcs-library.so]]" exit 1; ;; esac @@ -203,6 +212,9 @@ function card_cleanup() { rm .softhsm2.conf rm -rf ".tokens" ;; + "kryoptic") + rm kryoptic.sql + ;; esac } From 9109a7aa96293ab0cb11b24bcc44472fc5814f80 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 25 Mar 2024 13:54:40 +0100 Subject: [PATCH 3459/4321] p11test: Add support for more AES mechanisms --- src/tests/p11test/p11test_case_secret.c | 51 +++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/tests/p11test/p11test_case_secret.c b/src/tests/p11test/p11test_case_secret.c index 99e77578e5..c80a53cba5 100644 --- a/src/tests/p11test/p11test_case_secret.c +++ b/src/tests/p11test/p11test_case_secret.c @@ -69,6 +69,14 @@ int test_secret_encrypt_decrypt(test_cert_t *o, token_info_t *info, test_mech_t .ulAADLen = sizeof(aad), .ulTagBits = 128, }; + CK_CCM_PARAMS ccm_params = { + .ulDataLen = message_length, + .pNonce = (void *)iv, + .ulNonceLen = 13, + .pAAD = aad, + .ulAADLen = sizeof(aad), + .ulMACLen = 16, + }; int dec_message_length = 0; unsigned char *enc_message = NULL; int enc_message_length, rv; @@ -83,30 +91,41 @@ int test_secret_encrypt_decrypt(test_cert_t *o, token_info_t *info, test_mech_t return 0; } - /* The CBC mechanisms require parameter with IV. Not the ECB. */ - if (mech->mech == CKM_AES_CBC || mech->mech == CKM_AES_CBC_PAD) { + switch (mech->mech) { + case CKM_AES_CBC: + case CKM_AES_CBC_PAD: + case CKM_AES_CTS: + case CKM_AES_OFB: + case CKM_AES_CFB8: + case CKM_AES_CFB128: mech->params = &iv; mech->params_len = sizeof(iv); - } - if (mech->mech == CKM_AES_CBC || mech->mech == CKM_AES_ECB) { - /* This mechanism requires the blocks to be aligned to block size */ - message = pkcs7_pad_message(short_message, message_length, 16, &message_length); - } else if (mech->mech == CKM_AES_CBC_PAD || mech->mech == CKM_AES_CTS) { - message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); - } else if (mech->mech == CKM_AES_CTR) { - /* The CTR requires counter block + counter bits */ + break; + case CKM_AES_CTR: mech->params = &ctr_params; mech->params_len = sizeof(ctr_params); - message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); - } else if (mech->mech == CKM_AES_GCM) { - /* The GCM requires GCM parameter */ + break; + case CKM_AES_GCM: mech->params = &gcm_params; mech->params_len = sizeof(gcm_params); - message = (CK_BYTE *) strndup(MESSAGE_TO_SIGN, message_length); - } else { - debug_print(" [SKIP %s ] Unknown mechanism", o->id_str); + break; + case CKM_AES_CCM: + mech->params = &ccm_params; + mech->params_len = sizeof(ccm_params); + break; + case CKM_AES_ECB: + /* No parameters needed */ + break; + default: + debug_print(" [SKIP %s ] Unknown mechanism %s", o->id_str, get_mechanism_name(mech->mech)); return 0; } + if (mech->mech == CKM_AES_CBC || mech->mech == CKM_AES_ECB) { + /* This mechanism requires the blocks to be aligned to block size */ + message = pkcs7_pad_message(short_message, message_length, 16, &message_length); + } else { + message = (CK_BYTE *)strndup(MESSAGE_TO_SIGN, message_length); + } debug_print(" [ KEY %s ] Encrypt message using CKM_%s", o->id_str, get_mechanism_name(mech->mech)); From 381a6fc44ba8b962a360c9bc298951a170a61c36 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Apr 2024 10:02:43 +0200 Subject: [PATCH 3460/4321] p11test: Derive key length from CKA_VALUE if available --- src/tests/p11test/p11test_case_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index bc6d80dcd1..3505ef76d3 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -811,6 +811,8 @@ int callback_secret_keys(test_certs_t *objects, /* pass the pointer to our structure */ o->value = template[10].pValue; template[10].pValue = NULL; + /* if there is CKA_VALUE_LEN it will be rewritten later */ + o->bits = template[10].ulValueLen * 8; } if (template[11].pValue != NULL && template[11].ulValueLen > 0) { From 3d33de29f5bef1eec129b4eded1e917004c8b2de Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Apr 2024 10:04:19 +0200 Subject: [PATCH 3461/4321] p11test: Generate keys with all usage attributes --- src/tests/p11test/runtest.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index e8d772c7e8..45f38a17e2 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -33,7 +33,8 @@ function generate_sym() { # Generate key $PKCS11_TOOL --keygen --key-type="$TYPE" --login --pin=$PIN \ - --extractable --module="$P11LIB" --label="$LABEL" --id=$ID + --extractable --usage-wrap --usage-decrypt \ + --module="$P11LIB" --label="$LABEL" --id=$ID if [[ "$?" -ne "0" ]]; then echo "Couldn't generate $TYPE key pair" @@ -51,7 +52,8 @@ function generate_cert() { # Generate key pair $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --extractable --module="$P11LIB" --label="$LABEL" --id=$ID + --extractable --usage-wrap --usage-sign --usage-decrypt \ + --module="$P11LIB" --label="$LABEL" --id=$ID if [[ "$?" -ne "0" ]]; then echo "Couldn't generate $TYPE key pair" From dfee50410a9732158bd04ab396b81c9a849150d0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Apr 2024 10:05:35 +0200 Subject: [PATCH 3462/4321] p11test: Improve wrapping coverage --- src/tests/p11test/p11test_case_wrap.c | 46 ++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c index ab6b557789..78d9d0afd7 100644 --- a/src/tests/p11test/p11test_case_wrap.c +++ b/src/tests/p11test/p11test_case_wrap.c @@ -156,6 +156,7 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec { CK_FUNCTION_LIST_PTR fp = info->function_pointer; CK_MECHANISM mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM tmp_mechanism = {mech->mech, NULL_PTR, 0}; /* SoftHSM supports only SHA1 with OAEP encryption */ CK_RSA_PKCS_OAEP_PARAMS oaep_params = {CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL, 0}; CK_BYTE iv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, @@ -171,6 +172,14 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec .ulAADLen = sizeof(aad), .ulTagBits = 128, }; + CK_CCM_PARAMS ccm_params = { + .ulDataLen = key->bits, + .pNonce = (void *)iv, + .ulNonceLen = 13, + .pAAD = aad, + .ulAADLen = sizeof(aad), + .ulMACLen = 16, + }; //unsigned char key[16]; CK_BYTE *wrapped = NULL; CK_ULONG wrapped_len = 0; @@ -215,6 +224,10 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec /* AES mechanisms */ case CKM_AES_CBC: case CKM_AES_CBC_PAD: + case CKM_AES_CTS: + case CKM_AES_OFB: + case CKM_AES_CFB8: + case CKM_AES_CFB128: mech->params = &iv; mech->params_len = sizeof(iv); break; @@ -226,6 +239,25 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec mech->params = &gcm_params; mech->params_len = sizeof(gcm_params); break; + case CKM_AES_CCM: + /* The CCM parameters need to match with the input data length + * for encryption but we do not know the size for asymmetric + * keys so try to figure out by querying size in different mode */ + tmp_mechanism.mechanism = CKM_AES_CTR; + tmp_mechanism.pParameter = &ctr_params; + tmp_mechanism.ulParameterLen = sizeof(ctr_params); + rv = fp->C_WrapKey(info->session_handle, &tmp_mechanism, o->public_handle, + key->private_handle, wrapped, &wrapped_len); + if (rv != CKR_OK) { + mech->params = NULL; + mech->params_len = 0; + debug_print(" [ KEY %s ] Failed to find CCM param dataLen", o->id_str); + return 1; + } + ccm_params.ulDataLen = wrapped_len; + mech->params = &ccm_params; + mech->params_len = sizeof(ccm_params); + break; case CKM_AES_ECB: case CKM_AES_KEY_WRAP: case CKM_AES_KEY_WRAP_PAD: @@ -305,8 +337,12 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec } else { fprintf(stderr, " [ ERROR %s ] Wrapped key does not match\n", o->id_str); fprintf(stderr, "\nplaintext:\n"); - for (unsigned long i = 0; i < plain_len; i++) { - fprintf(stderr, ":%x", plain[i]); + if (plain != NULL) { + for (unsigned long i = 0; i < plain_len; i++) { + fprintf(stderr, ":%x", plain[i]); + } + } else { + fprintf(stderr, "NULL"); } fprintf(stderr, "\nkey->value:\n"); for (unsigned long i = 0; i < key->bits / 8; i++) { @@ -316,7 +352,7 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec return 1; } free(plain); - } else { + } else if (key->key_type == CKK_AES) { rv = check_encrypt_decrypt_secret(plain, plain_len, key, info); free(plain); if (rv == 0) { @@ -348,7 +384,7 @@ test_unwrap_aes(test_cert_t *o, token_info_t *info, test_mech_t *mech) 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; CK_BYTE *key_padded = key; CK_ULONG key_len = sizeof(key); - CK_ULONG key_padded_len = sizeof(key_padded); + CK_ULONG key_padded_len = sizeof(key); CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_AES; CK_BBOOL true = CK_TRUE; @@ -389,7 +425,7 @@ test_unwrap_aes(test_cert_t *o, token_info_t *info, test_mech_t *mech) mech->params_len = sizeof(oaep_params); /* fall through */ case CKM_RSA_X_509: - if ((key_padded = rsa_x_509_pad_message(key, &key_padded_len, o, 1)) == NULL) { + if (mech->mech == CKM_RSA_X_509 && (key_padded = rsa_x_509_pad_message(key, &key_padded_len, o, 1)) == NULL) { debug_print(" [ERROR %s ] Could not pad message", o->id_str); return 1; } From 97ac2d21b045a6137779461e82101d54f28694b3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Apr 2024 18:10:40 +0200 Subject: [PATCH 3463/4321] p11test: Improve interface test --- src/tests/p11test/p11test_case_interface.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_interface.c b/src/tests/p11test/p11test_case_interface.c index 37370d109f..fa606f2952 100644 --- a/src/tests/p11test/p11test_case_interface.c +++ b/src/tests/p11test/p11test_case_interface.c @@ -74,6 +74,7 @@ void interface_test(void **state) } /* run the rest only if we have 2 interfaces (assume OpenSC) */ if (count == 2) { + CK_VERSION version2; assert_string_equal(interfaces[0].pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interfaces[0].pFunctionList)->major, 3); assert_int_equal(((CK_VERSION *)interfaces[0].pFunctionList)->minor, 0); @@ -82,6 +83,7 @@ void interface_test(void **state) assert_int_equal(((CK_VERSION *)interfaces[1].pFunctionList)->major, 2); // assert_int_equal(((CK_VERSION *)interfaces[1].pFunctionList)->minor, 20); assert_int_equal(interfaces[1].flags, 0); + version2 = *(CK_VERSION *)interfaces[1].pFunctionList; /* GetInterface with NULL name should give us default PKCS 11 one */ rv = C_GetInterface(NULL, NULL, &interface, 0); @@ -105,9 +107,9 @@ void interface_test(void **state) /* The function list should be the same */ assert_ptr_equal(interfaces[0].pFunctionList, interface->pFunctionList); - /* GetInterface with explicit 2.20 version */ - version.major = 2; - version.minor = 20; + /* GetInterface the other interface (with explicit 2.x version) */ + version.major = 2; /* assumed 2 */ + version.minor = version2.minor; rv = C_GetInterface((unsigned char *)"PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_OK); assert_string_equal(interface->pInterfaceName, "PKCS 11"); @@ -123,7 +125,7 @@ void interface_test(void **state) assert_int_equal(rv, CKR_ARGUMENTS_BAD); /* GetInterface with wrong version */ - version.major = 2; + version.major = 4; version.minor = 50; rv = C_GetInterface((unsigned char *)"PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_ARGUMENTS_BAD); From e95935b15a17a372b6e5fa6f9488a9fe8bad857e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 2 May 2024 13:37:10 +0200 Subject: [PATCH 3464/4321] p11test: Be more verbose about wrapping --- src/tests/p11test/p11test_case_common.c | 20 ++++++++++++++++++++ src/tests/p11test/p11test_case_common.h | 1 + src/tests/p11test/p11test_case_wrap.c | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 3505ef76d3..ed8c2526d3 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -1244,6 +1244,26 @@ const char *get_mgf_name(unsigned long mgf_id) } } +const char * +get_key_type(test_cert_t * key) +{ + switch (key->key_type) { + case CKK_RSA: + return "RSA"; + case CKK_EC: + return "EC"; + case CKK_EC_EDWARDS: + return "EC_EDWARDS"; + case CKK_EC_MONTGOMERY: + return "EC_MONTGOMERY"; + case CKK_AES: + return "AES"; + default: + sprintf(name_buffer, "0x%.8lX", key->key_type); + return name_buffer; + } +} + const char *get_mechanism_flag_name(unsigned long mech_id) { switch (mech_id) { diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index a9d91c572e..4c1fd4b72a 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -82,6 +82,7 @@ const char *get_mechanism_name(unsigned long mech_id); const char *get_mgf_name(unsigned long mech_id); const char *get_mechanism_flag_name(unsigned long flag_id); const char *get_mechanism_all_flag_name(unsigned long flag_id); +const char *get_key_type(test_cert_t *key); char *convert_byte_string(unsigned char *id, unsigned long length); int is_pss_mechanism(CK_MECHANISM_TYPE mech); diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c index 78d9d0afd7..d269613976 100644 --- a/src/tests/p11test/p11test_case_wrap.c +++ b/src/tests/p11test/p11test_case_wrap.c @@ -197,8 +197,8 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec return 0; } - debug_print(" [ KEY %s ] Wrap a key [%s] using CKM_%s", o->id_str, key->id_str, - get_mechanism_name(mech->mech)); + debug_print(" [ KEY %s ] Wrap a key [%s] (%s) using CKM_%s", o->id_str, key->id_str, + get_key_type(key), get_mechanism_name(mech->mech)); /* RSA mechanisms */ switch (mech->mech) { case CKM_RSA_X_509: From da72da2d7e946452a8bd46c1c6a46df4724f434c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 6 May 2024 10:07:49 +0200 Subject: [PATCH 3465/4321] p11test: Note about AES-CCM key wrapping --- src/tests/p11test/p11test_case_wrap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c index d269613976..0b44a169d0 100644 --- a/src/tests/p11test/p11test_case_wrap.c +++ b/src/tests/p11test/p11test_case_wrap.c @@ -172,6 +172,9 @@ test_wrap(test_cert_t *o, token_info_t *info, test_cert_t *key, test_mech_t *mec .ulAADLen = sizeof(aad), .ulTagBits = 128, }; + /* It is very unclear from the PKCS#11 specs what + * value we should provide here to DataLen for + * wrapping and unwrapping operation. */ CK_CCM_PARAMS ccm_params = { .ulDataLen = key->bits, .pNonce = (void *)iv, From 50c17ba6c0c171ee107ed8158216899bcc515949 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 9 May 2024 18:57:24 +0200 Subject: [PATCH 3466/4321] p11test: Wrap also EC keys --- src/tests/p11test/p11test_case_wrap.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_wrap.c b/src/tests/p11test/p11test_case_wrap.c index 0b44a169d0..ecb257b565 100644 --- a/src/tests/p11test/p11test_case_wrap.c +++ b/src/tests/p11test/p11test_case_wrap.c @@ -527,12 +527,14 @@ wrap_tests(void **state) test_certs_t objects; test_cert_t *aes_key = NULL, *aes2_key = NULL; test_cert_t *rsa_key = NULL, *rsa2_key = NULL; + test_cert_t *ec_key = NULL; test_certs_init(&objects); P11TEST_START(info); search_for_all_objects(&objects, info); + /* Find keys to wrap */ for (i = 0; i < objects.count; i++) { test_cert_t *o = &objects.data[i]; if (aes_key == NULL && o->key_type == CKK_AES && o->extractable) { @@ -543,6 +545,8 @@ wrap_tests(void **state) rsa_key = o; } else if (rsa2_key == NULL && o->key_type == CKK_RSA && o->extractable) { rsa2_key = o; + } else if (ec_key == NULL && o->key_type == CKK_EC && o->extractable) { + ec_key = o; } } @@ -574,6 +578,9 @@ wrap_tests(void **state) if (aes_key) { errors += test_wrap(o, info, aes_key, &(o->mechs[j])); } + if (ec_key) { + errors += test_wrap(o, info, ec_key, &(o->mechs[j])); + } errors += test_unwrap_aes(o, info, &(o->mechs[j])); break; case CKK_AES: @@ -586,10 +593,14 @@ wrap_tests(void **state) if (rsa_key) { errors += test_wrap(o, info, rsa_key, &(o->mechs[j])); } + /* TODO differentiate the RSA and EC key */ + if (ec_key) { + errors += test_wrap(o, info, ec_key, &(o->mechs[j])); + } // errors += test_unwrap_aes(o, info, &(o->mechs[j])); break; default: - /* Other keys do not support derivation */ + /* Other keys do not support wrapping */ break; } } From 5a603eba8eeda8a8214b2a6ac50b2a53744dda1f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 9 May 2024 18:58:12 +0200 Subject: [PATCH 3467/4321] p11test: Generate RSA keys of different size --- src/tests/p11test/runtest.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index 45f38a17e2..c0aa7f43d1 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -186,6 +186,10 @@ function card_setup() { generate_cert "RSA:1024" "01" "RSA_auth" 1 # Generate 2048b RSA Key pair generate_cert "RSA:2048" "02" "RSA2048" 1 + # Generate 3082b RSA Key pair + generate_cert "RSA:3072" "09" "RSA3072" 1 + # Generate 4096 RSA Key pair + generate_cert "RSA:4096" "10" "RSA4096" 1 if [[ $ECC_KEYS -eq 1 ]]; then # Generate 256b ECC Key pair generate_cert "EC:secp256r1" "03" "ECC_auth" 1 From c64713e9f1036ce4fe9dd70dbc7364a042ad28f5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 10 May 2024 09:49:20 +0200 Subject: [PATCH 3468/4321] tests: Update reference files removing multipart RSA tests --- src/tests/p11test/isoapplet_ref_v0.json | 5 ----- src/tests/p11test/isoapplet_ref_v1.json | 5 ----- src/tests/p11test/openpgp_s0_ref.json | 5 ----- src/tests/p11test/openpgp_s1_ref.json | 5 ----- src/tests/p11test/oseid_ref.json | 10 --------- src/tests/p11test/piv_ref.json | 20 ----------------- src/tests/p11test/virt_cacard_ref.json | 30 ------------------------- 7 files changed, 80 deletions(-) diff --git a/src/tests/p11test/isoapplet_ref_v0.json b/src/tests/p11test/isoapplet_ref_v0.json index 440b8feb48..085b4a515b 100644 --- a/src/tests/p11test/isoapplet_ref_v0.json +++ b/src/tests/p11test/isoapplet_ref_v0.json @@ -213,11 +213,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "RSA_PKCS", - "YES" - ], [ "01", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/isoapplet_ref_v1.json b/src/tests/p11test/isoapplet_ref_v1.json index 4e8a3ab00f..c0b40f3ee2 100644 --- a/src/tests/p11test/isoapplet_ref_v1.json +++ b/src/tests/p11test/isoapplet_ref_v1.json @@ -303,11 +303,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "RSA_PKCS", - "YES" - ], [ "01", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/openpgp_s0_ref.json b/src/tests/p11test/openpgp_s0_ref.json index 6d7bf66da9..04898efd65 100644 --- a/src/tests/p11test/openpgp_s0_ref.json +++ b/src/tests/p11test/openpgp_s0_ref.json @@ -195,11 +195,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "03", - "RSA_PKCS", - "YES" - ], [ "03", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/openpgp_s1_ref.json b/src/tests/p11test/openpgp_s1_ref.json index 76d41f398b..37a77bb373 100644 --- a/src/tests/p11test/openpgp_s1_ref.json +++ b/src/tests/p11test/openpgp_s1_ref.json @@ -189,11 +189,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "RSA_PKCS", - "YES" - ], [ "01", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/oseid_ref.json b/src/tests/p11test/oseid_ref.json index c18e1b424a..bce5925e38 100644 --- a/src/tests/p11test/oseid_ref.json +++ b/src/tests/p11test/oseid_ref.json @@ -357,16 +357,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "RSA_PKCS", - "YES" - ], - [ - "01", - "RSA_X_509", - "YES" - ], [ "01", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/piv_ref.json b/src/tests/p11test/piv_ref.json index ed96067343..026959ef36 100644 --- a/src/tests/p11test/piv_ref.json +++ b/src/tests/p11test/piv_ref.json @@ -369,16 +369,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "RSA_PKCS", - "YES" - ], - [ - "01", - "RSA_X_509", - "YES" - ], [ "01", "MD5_RSA_PKCS", @@ -414,16 +404,6 @@ "SHA224_RSA_PKCS", "YES" ], - [ - "04", - "RSA_PKCS", - "YES" - ], - [ - "04", - "RSA_X_509", - "YES" - ], [ "04", "MD5_RSA_PKCS", diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index e152182910..5dd4fed34a 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -345,16 +345,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "00:01", - "RSA_PKCS", - "YES" - ], - [ - "00:01", - "RSA_X_509", - "YES" - ], [ "00:01", "MD5_RSA_PKCS", @@ -390,16 +380,6 @@ "SHA224_RSA_PKCS", "YES" ], - [ - "00:02", - "RSA_PKCS", - "YES" - ], - [ - "00:02", - "RSA_X_509", - "YES" - ], [ "00:02", "MD5_RSA_PKCS", @@ -435,16 +415,6 @@ "SHA224_RSA_PKCS", "YES" ], - [ - "00:03", - "RSA_PKCS", - "YES" - ], - [ - "00:03", - "RSA_X_509", - "YES" - ], [ "00:03", "MD5_RSA_PKCS", From b90191e6c53aba954370e1db9a09a843124c24f5 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Tue, 30 Apr 2024 18:30:16 +0200 Subject: [PATCH 3469/4321] Include URIs for PKCS#11 objects Fixes: #3129 Signed-off-by: Sergio Arroutbi --- src/tests/fuzzing/fuzz_pkcs15init.c | 7 +- src/tools/pkcs11-tool.c | 119 ++++++++++++++++++++++------ tests/test-pkcs11-tool-test.sh | 20 ++++- 3 files changed, 116 insertions(+), 30 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 8695c429a5..d039fd6712 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -109,7 +109,7 @@ int fuzz_get_reader_data(const uint8_t *from, size_t from_size, const uint8_t ** size_t i = 0; while(i < from_size - 1 && from[i] != '\0') i++; - + if (from[i] != '\0') return 0; @@ -126,6 +126,7 @@ void do_init_app(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_ int so_puk_disabled = 0; memset(&init_args, 0, sizeof(init_args)); + memset(&info, 0, sizeof(info)); sc_pkcs15init_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &info); if ((info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED) && (info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)) @@ -150,7 +151,7 @@ void do_store_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc struct sc_pkcs15init_pinargs pin_args; char pin_id[SC_PKCS15_MAX_ID_SIZE] = "1\0"; sc_pkcs15init_set_p15card(profile, p15card); - + memcpy(pin, "1234555678\0", 11); /* Set new pin */ memset(&pin_args, 0, sizeof(pin_args)); @@ -363,6 +364,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (card) sc_disconnect_card(card); sc_release_context(ctx); - + return 0; } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 46f8b735e5..4e1668290f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1648,6 +1648,43 @@ static void list_slots(int tokens, int refresh, int print) } } +static const char * +copy_key_value_to_uri(const char *key, const char *value, CK_BBOOL last) +{ + static char URI[1024]; + static size_t shift = 0; + if (key && (shift + strlen(key) < sizeof(URI))) { + strcpy(&URI[shift], key); + shift += strlen(key); + } + if (value && (shift + strlen(value) < sizeof(URI))) { + strcpy(&URI[shift], value); + shift += strlen(value); + } + if (key && value && !last && shift < sizeof(URI)) { + URI[shift++] = ';'; + } + if (last && shift < sizeof(URI)) { + URI[shift] = '\0'; + shift = 0; + } + return URI; +} + +static const char * +get_uri(CK_TOKEN_INFO_PTR info) +{ + copy_key_value_to_uri("pkcs11:", NULL, CK_FALSE); + const char *model = percent_encode(info->model, sizeof(info->model)); + copy_key_value_to_uri("model=", model, CK_FALSE); + const char *manufacturer = percent_encode(info->manufacturerID, sizeof(info->manufacturerID)); + copy_key_value_to_uri("manufacturer=", manufacturer, CK_FALSE); + const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber)); + copy_key_value_to_uri("serial=", serial, CK_FALSE); + const char *token = percent_encode(info->label, sizeof(info->label)); + return copy_key_value_to_uri("token=", token, CK_TRUE); +} + static void show_token(CK_SLOT_ID slot) { CK_TOKEN_INFO info; @@ -1682,14 +1719,7 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); - printf(" uri : pkcs11:"); - printf("model=%s", percent_encode(info.model, sizeof(info.model))); - printf(";manufacturer="); - printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID))); - printf(";serial="); - printf("%s", percent_encode(info.serialNumber, sizeof(info.serialNumber))); - printf(";token="); - printf("%s", percent_encode(info.label, sizeof(info.label))); + printf(" uri : %s", get_uri(&info)); printf("\n"); } @@ -5045,13 +5075,14 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { CK_MECHANISM_TYPE_PTR mechs = NULL; CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj); - CK_ULONG size = 0; + CK_ULONG size, idsize = 0; unsigned char *id, *oid, *value; const char *sepa; char *label; char *unique_id; int pub = 1; int sec = 0; + CK_TOKEN_INFO info; switch(getCLASS(sess, obj)) { case CKO_PRIVATE_KEY: @@ -5243,17 +5274,15 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if ((label = getLABEL(sess, obj, NULL)) != NULL) { printf(" label: %s\n", label); - free(label); } - if ((id = getID(sess, obj, &size)) != NULL && size) { + if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { unsigned int n; printf(" ID: "); - for (n = 0; n < size; n++) + for (n = 0; n < idsize; n++) printf("%02x", id[n]); printf("\n"); - free(id); } printf(" Usage: "); @@ -5355,7 +5384,26 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf(" Unique ID: %s\n", unique_id); free(unique_id); } - + get_token_info(opt_slot, &info); + printf(" uri: %s", get_uri(&info)); + if (id != NULL && idsize) { + printf(";id=%%"); + for (unsigned int n = 0; n < idsize; n++) + printf("%02x", id[n]); + free(id); + } + if (label != NULL) { + const char *pelabel = percent_encode((unsigned char *)label, strlen(label)); + printf(";object=%s", pelabel); + free(label); + } + if (sec) { + printf(";type=secret-key\n"); + } else if (pub) { + printf(";type=public\n"); + } else { + printf(";type=private\n"); + } suppress_warn = 0; } @@ -5363,6 +5411,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { CK_CERTIFICATE_TYPE cert_type = getCERTIFICATE_TYPE(sess, obj); CK_ULONG size; + CK_TOKEN_INFO info; unsigned char *id; char *label; char *unique_id; @@ -5389,7 +5438,6 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if ((label = getLABEL(sess, obj, NULL)) != NULL) { printf(" label: %s\n", label); - free(label); } #if defined(ENABLE_OPENSSL) @@ -5433,37 +5481,49 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) for (n = 0; n < size; n++) printf("%02x", id[n]); printf("\n"); - free(id); } if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { printf(" Unique ID: %s\n", unique_id); free(unique_id); } + get_token_info(opt_slot, &info); + printf(" uri: %s", get_uri(&info)); + if (id != NULL && size) { + printf(";id=%%"); + for (unsigned int n = 0; n < size; n++) + printf("%02x", id[n]); + free(id); + } + if (label != NULL) { + const char *pelabel = percent_encode((unsigned char *)label, strlen(label)); + printf(";object=%s", pelabel); + free(label); + } + printf(";type=cert\n"); } static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { unsigned char *oid_buf; char *label; + char *application; CK_ULONG size = 0; + CK_TOKEN_INFO info; suppress_warn = 1; printf("Data object %u\n", (unsigned int) obj); printf(" label: "); if ((label = getLABEL(sess, obj, NULL)) != NULL) { printf("'%s'\n", label); - free(label); - } - else { + } else { printf("\n"); } printf(" application: "); - if ((label = getAPPLICATION(sess, obj, NULL)) != NULL) { - printf("'%s'\n", label); - free(label); - } - else { + if ((application = getAPPLICATION(sess, obj, NULL)) != NULL) { + printf("'%s'\n", application); + free(application); + } else { printf("\n"); } @@ -5494,8 +5554,16 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf(" private"); if (!getMODIFIABLE(sess, obj) && !getPRIVATE(sess, obj)) printf(""); + printf("\n"); - printf ("\n"); + get_token_info(opt_slot, &info); + printf(" uri: %s", get_uri(&info)); + if (label != NULL) { + const char *pelabel = percent_encode((unsigned char *)label, strlen(label)); + printf(";object=%s", pelabel); + free(label); + } + printf(";type=data\n"); suppress_warn = 0; } @@ -8337,6 +8405,7 @@ static const char * percent_encode(CK_UTF8CHAR *string, size_t len) { static char buffer[1024]; + memset(buffer, 0, 1024); size_t output_index, input_index; while (len && string[len - 1] == ' ') diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 2a1f43b8bc..1a96cbd754 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -20,12 +20,28 @@ assert $? "Failed to set up card" echo "=======================================================" echo "Test" echo "=======================================================" -$PKCS11_TOOL --test -p $PIN --module $P11LIB +$PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" assert $? "Failed running tests" +echo "=======================================================" +echo "Test objects URI" +echo "=======================================================" +$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null +assert $? "Failed running objects URI tests" +$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null +assert $? "Failed running objects URI tests" + +echo "=======================================================" +echo "Test slots URI" +echo "=======================================================" +$PKCS11_TOOL -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null +assert $? "Failed running slots URI tests" +$PKCS11_TOOL -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null +assert $? "Failed running slots URI tests" + echo "=======================================================" echo "Cleanup" echo "=======================================================" card_cleanup -exit $ERRORS +exit "${ERRORS}" From cda053d452c3a439f85bb367125e521feb40a24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 2 May 2024 16:21:43 +0200 Subject: [PATCH 3470/4321] Add documentation for PKCS#15 profiles --- doc/files/files.html | 442 ++++++++++++++++++- doc/files/pkcs15-profile.5.xml | 760 ++++++++++++++++++++++++++++++++- 2 files changed, 1194 insertions(+), 8 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index d320f84eff..ad0c7753c8 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -1232,10 +1232,444 @@ The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ -

    Syntax

    - This section should contain information about the profile syntax. Will add - this soonishly. -

    See also

    +

    + Basic PKCS#15 terminology: +

    1. + MF (Master File) is root of the filesystem hierarchy +

    2. + DF(PKCS#15) is directory containing the PKCS#15 files and directories +

    3. + EF(ODF) (Object Directory File) is elementary file containing pointers + to other elementary files (PrKDFs, PuKDFs, SKDFs, CDFs, DODFs, AODFs) +

    4. + PrKDF (Private Key Directory File) is elementary file containing + pointers to the private keys and additional information about the private keys +

    5. + PubKDF (Public Key Directory File) is elementary file containing pointers to the public + keys and additional information about the public keys +

    6. + CDF (Certificate Directory File) is elementary file containing pointers to the + certificates and additional information about the certificates +

    7. + EF(TokenInfo) is elementary file with generic information about the card +

    +

    Syntax and semantics

    + The block syntax of profile files is in general similar to the configuration file. + The profile file, is composed of blocks, which, in general, have the following format: +

    +key [, name...] {
    +	block_contents
    +}
    +			

    + block_contents is one or more + block_items where a + block_item is one of +

    • + # comment string +

    • + key [, name...] = value; +

    • + block +

    +

    + At the root level, the profile contains several configuration blocks. + The block keys are as follows: +

    • + cardinfo: Configuration for general information about card. +

    • + pkcs15: Control for some of the general aspects of the PKCS#15 put onto the card. +

    • + option: Profile options to modify the behavior of profile. +

    • + PIN: Configuration and limits for particular PIN type. +

    • + filesystem: Specification for filesystem that is to be created on the card. +

    • + macros +

    +

    Profile file configuration

    Configuration of Card Information

    + cardinfo { + block_contents + } + +

    + Configuration for general information about card: +

    + label = name; +

    + Card label (Default: OpenSC Card). +

    + manufacturer = name; +

    + Card manufacturer (Default: OpenSC Project). +

    + min-pin-length = int; +

    + Minimal length of PIN (Default: 4). +

    + max-pin-length = int; +

    + Maximal length of PIN, should be overridden in the per-card profile + (Default: 8). +

    + pin-encoding = value; +

    + Encoding type of PIN. Known parameters: +

    • + BCD: + binary-coded decimal +

    • + ascii-numeric: + ASCII numerical values +

    • + utf8 +

    • + half-nibble-bcd +

    • + iso9564-1 +

    + (Default: ascii-numeric). +

    + pin-pad-char = value; +

    + Character used for padding the PIN when needed (Default: 0x00). +

    + pin-domains = bool; +

    + Some cards need to keep all their PINs in separate directories. + The particular keys in that domain will be put below the DF of the specified PIN. + (Default: no) +

    Configuration of PKCS#15

    + pkcs15 { + block_contents + } + +

    + Control for some of the general aspects of the PKCS#15 put onto the card. + Parameters in this block are: +

    + direct-certificates = bool; +

    + The PKCS#15 system must contain at least one CDF, it contains the certificates + directly or references to certificates. This options defines whether the certificates + should be put directly in the CDF itself or not (Default: no). +

    + encode-df-length = bool; +

    + Save length of DF into ODF file. Useful if we store certificates directly in the CDF + for better better performance and robustness (Default: no). +

    + do-last-update = value; +

    + Store information about last update in the EF(TokenInfo) (Default: yes). +

    + pkcs15-id-style = value; +

    + Method to calculate ID of the crypto objects. Known parameters: +

    native
    • + native: + 'E' + number_of_present_objects_of_the_same_type +

    • + mozilla: + SHA1(modulus) for RSA +

    • + rfc2459 + SHA1(SequenceASN1 of public key components as ASN1 integers) +

    +

    + minidriver-support-style = value; +

    + Style of pkcs15-init support of minidriver. Known parameters: +

    • + none +

    • + gemalto +

    + (Default: none) +

    Configuration of Profile Option

    + option name { + block_contents + } + +

    + The name specifies profile options to modify the behavior of profile, it can be +

    +

    +

    • + default: + option specifies default settings and this block with option is always processed, +

    • + onepin: + option for using 1 user PIN, creation/deletion/generation is controlled by the user PIN and thus by the user (as a result, only 1 user PIN is possible), +

    • + small + option suitable for cards with small memory. +

    +

    +

    + The options are used by pkcs15-init tool by --profile name, -p name: +

    +

    +

    • + pkcs15+default: + the default (not needed to specify it) +

    • + pkcs15+onepin: + for the onepin profile option +

    • + pkcs15+small + for the small profile option +

    +

    +

    + The option block can contain following sub-blocks: +

    +
    + macros { block_contents } +

    + Macros are specified in form of name = value; pairs. +

    + pkcs15 { block_contents } +

    + Inner block for configuration of PKCS#15 structure. +

    Configuration of PINs

    + PIN name { + block_contents + } + +

    + The name specifies PIN type, it can be +

    +

    +

    • + pin or user-pin + (no need to set file path or reference as it is done dynamically) +

    • + puk or user-puk +

    • + sopin or so-pin +

    • + sopuk or so-puk +

    +

    +

    + Known parameters are: +

    + attempts = int; +

    + Defines number of attempts for the given PIN (Default: 3). +

    + flags = value...; +

    + Flags define properties of the PIN. Possible flags: +

    • + case-sensitive +

    • + local +

    • + change-disabled +

    • + unblock-disabled +

    • + initialized +

    • + needs-padding +

    • + unblockingPin +

    • + soPin +

    • + disable-allowed +

    • + integrity-protected +

    • + confidentiality-protected +

    • + exchangeRefData +

    + (Default: local,initialized,needs-padding). +

    + auth-id = value; +

    + Value used for auth ID (Default: 0). +

    + min-length = int; +

    + Minimal length of PIN (Default: value min-pin-length set in cardinfo block). +

    + max-length = int; +

    + Maximal length of PIN (Default: value max-pin-length set in cardinfo block). +

    + reference = int; +

    + Value of reference of the PIN (Default: set in particular card driver). +

    + file = name; +

    + File with PIN, obsolete option (Default: None). +

    + offset = int; +

    + Offset of PIN in PIN file, obsolete option (Default: 0). +

    + encoding = value; +

    + Encoding type of PIN. Possible values: +

    • + BCD +

    • + ascii-numeric +

    • + utf8 +

    • + half-nibble-bcd +

    • + iso9564-1 +

    + (Default: value pin-encoding set in cardinfo block). +

    + stored-length = int; +

    + (Default: value max-pin-length set in cardinfo block). +

    + max-unlocks = int; +

    + (Default: 0). +

    + Values in this block can be set by macros. That allows to specify the particular values with the usage of option. +

    Configuration of Filesystem

    filesystem { + block_contents + } +

    + This block contains the specification for filesystem that is to be created on the card. + The filesystem consists of several nested blocks representing DF and EF files. + When the DFs or EFs are specified in card specific profile, this is added to the file system info specified in the main profile. +

    + EF name { + block_contents + } + +

    + This block defines elementary file in PKCS#15 file hierarchy. + The name can be one of: +

    • + PKCS15-TokenInfo +

    • + PKCS15-ODF +

    • + PKCS15-UnusedSpace +

    • + PKCS15-PRKDF +

    • + PKCS15-PUKDF +

    • + PKCS15-PUKDF-TRUSTED +

    • + PKCS15-SKDF +

    • + PKCS15-CDF +

    • + PKCS15-CDF-TRUSTED +

    • + PKCS15-CDF-USEFUL +

    • + PKCS15-DODF +

    • + PKCS15-AODF +

    +

    +

    + The EF block can contain: +

    +
    + type = EF; +

    + Type must match type of file. +

    + acl = value; +

    + Value of ACL (Access Control List) (Default: NONE) +

    + file-id = EF; +

    + File ID, relative path. +

    + structure = value; +

    + File structure is one of: +

    • + TRANSPARENT +

    • + LINEAR-FIXED +

    • + LINEAR-FIXED-TLV +

    • + LINEAR-VARIABLE +

    • + LINEAR-VARIABLE-TLV +

    • + CYCLIC +

    • + CYCLIC-TLV +

    +

    + DF name { + block_contents + } + +

    + This block defines directory file in PKCS#15 file hierarchy. + The name can be one of: +

    • + MF +

    • + PKCS15-AppDF +

    • + Special cases for those DFs handled separately by the PKCS15 logic +

    +

    +

    + The DF block can contain: +

    +
    + type = DF; +

    + Type must match type of file. +

    + path = value; +

    + Specification of path of the directory file. +

    + file-id = value; +

    + File ID, relative path. +

    + aid = value; +

    + Value of AID, in XX:XX:XX:...:XX:XX:XX notation. +

    + acl = value; +

    + Type must match type of file. +

    + size = int; +

    + Size of the file in bytes. +

    + EF name { block_contents } +

    + Block specifying nested elementary file. +

    + Typically, the root DF is MF. +

    + It is mandatory that profile file contains DF entry for MF (Master File). + Otherwise the profile file is incomplete and cannot be used. +

    + The DF can contain other DF or MF blocks. + For examples how the filesystem structure may look like, + please refer to pkcs15.profile or any other present profile file. +

    See also

    pkcs15-init(1), pkcs15-crypt(1)

    diff --git a/doc/files/pkcs15-profile.5.xml b/doc/files/pkcs15-profile.5.xml index cf555ec0c8..8a41ce3429 100644 --- a/doc/files/pkcs15-profile.5.xml +++ b/doc/files/pkcs15-profile.5.xml @@ -34,14 +34,766 @@ card initialization, such as location of PIN files, key references etc. Profiles currently reside in @pkgdatadir@ + + Basic PKCS#15 terminology: + + + MF (Master File) is root of the filesystem hierarchy + + + DF(PKCS#15) is directory containing the PKCS#15 files and directories + + + EF(ODF) (Object Directory File) is elementary file containing pointers + to other elementary files (PrKDFs, PuKDFs, SKDFs, CDFs, DODFs, AODFs) + + + PrKDF (Private Key Directory File) is elementary file containing + pointers to the private keys and additional information about the private keys + + + PubKDF (Public Key Directory File) is elementary file containing pointers to the public + keys and additional information about the public keys + + + CDF (Certificate Directory File) is elementary file containing pointers to the + certificates and additional information about the certificates + + + EF(TokenInfo) is elementary file with generic information about the card + + + - - Syntax + + Syntax and semantics - This section should contain information about the profile syntax. Will add - this soonishly. + The block syntax of profile files is in general similar to the configuration file. + The profile file, is composed of blocks, which, in general, have the following format: + +key, name { + block_contents +} + + block_contents is one or more + block_items where a + block_item is one of + + + # comment string + + + key, name = value; + + + block + + + + At the root level, the profile contains several configuration blocks. + The block keys are as follows: + + + cardinfo: Configuration for general information about card. + + + pkcs15: Control for some of the general aspects of the PKCS#15 put onto the card. + + + option: Profile options to modify the behavior of profile. + + + PIN: Configuration and limits for particular PIN type. + + + filesystem: Specification for filesystem that is to be created on the card. + + + macros + + + + + Profile file configuration + + + Configuration of Card Information + + + + + + + Configuration for general information about card: + + + + + + + + Card label (Default: OpenSC Card). + + + + + + + + Card manufacturer (Default: OpenSC Project). + + + + + + + + Minimal length of PIN (Default: 4). + + + + + + + + Maximal length of PIN, should be overridden in the per-card profile + (Default: 8). + + + + + + + + Encoding type of PIN. Known parameters: + + + BCD: + binary-coded decimal + + + ascii-numeric: + ASCII numerical values + + + utf8 + + + half-nibble-bcd + + + iso9564-1 + + + (Default: ascii-numeric). + + + + + + + + Character used for padding the PIN when needed (Default: 0x00). + + + + + + + + Some cards need to keep all their PINs in separate directories. + The particular keys in that domain will be put below the DF of the specified PIN. + (Default: no) + + + + + + + + + + Configuration of PKCS#15 + + + + + + + Control for some of the general aspects of the PKCS#15 put onto the card. + Parameters in this block are: + + + + + + + + The PKCS#15 system must contain at least one CDF, it contains the certificates + directly or references to certificates. This options defines whether the certificates + should be put directly in the CDF itself or not (Default: no). + + + + + + + + Save length of DF into ODF file. Useful if we store certificates directly in the CDF + for better better performance and robustness (Default: no). + + + + + + + + Store information about last update in the EF(TokenInfo) (Default: yes). + + + + + + + + Method to calculate ID of the crypto objects. Known parameters: + + + native: + 'E' + number_of_present_objects_of_the_same_type + + + mozilla: + SHA1(modulus) for RSA + + + rfc2459 + SHA1(SequenceASN1 of public key components as ASN1 integers) + + (Default: native) + + + + + + + + + Style of pkcs15-init support of minidriver. Known parameters: + + + none + + + gemalto + + + (Default: none) + + + + + + + + + + Configuration of Profile Option + + + + + + The name specifies profile options to modify the behavior of profile, it can be + + + + + default: + option specifies default settings and this block with option is always processed, + + + onepin: + option for using 1 user PIN, creation/deletion/generation is controlled by the user PIN and thus by the user (as a result, only 1 user PIN is possible), + + + small + option suitable for cards with small memory. + + + + + The options are used by pkcs15-init tool by --profile name, -p name: + + + + + pkcs15+default: + the default (not needed to specify it) + + + pkcs15+onepin: + for the onepin profile option + + + pkcs15+small + for the small profile option + + + + + The option block can contain following sub-blocks: + + + + + + + + + + Macros are specified in form of name = value; pairs. + + + + + + + + Inner block for configuration of PKCS#15 structure. + + + + + + + + + + Configuration of PINs + + + + + + The name specifies PIN type, it can be + + + + + pin or user-pin + (no need to set file path or reference as it is done dynamically) + + + puk or user-puk + + + sopin or so-pin + + + sopuk or so-puk + + + + + + Known parameters are: + + + + + + + + Defines number of attempts for the given PIN (Default: 3). + + + + + + + + Flags define properties of the PIN. Possible flags: + + + case-sensitive + + + local + + + change-disabled + + + unblock-disabled + + + initialized + + + needs-padding + + + unblockingPin + + + soPin + + + disable-allowed + + + integrity-protected + + + confidentiality-protected + + + exchangeRefData + + + (Default: local,initialized,needs-padding). + + + + + + + + Value used for auth ID (Default: 0). + + + + + + + + Minimal length of PIN (Default: value min-pin-length set in cardinfo block). + + + + + + + + Maximal length of PIN (Default: value max-pin-length set in cardinfo block). + + + + + + + + Value of reference of the PIN (Default: set in particular card driver). + + + + + + + + File with PIN, obsolete option (Default: None). + + + + + + + + Offset of PIN in PIN file, obsolete option (Default: 0). + + + + + + + + Encoding type of PIN. Possible values: + + + BCD + + + ascii-numeric + + + utf8 + + + half-nibble-bcd + + + iso9564-1 + + + (Default: value pin-encoding set in cardinfo block). + + + + + + + + (Default: value max-pin-length set in cardinfo block). + + + + + + + + (Default: 0). + + + + + + + + Values in this block can be set by macros. That allows to specify the particular values with the usage of option. + + + + + Configuration of Filesystem + + + This block contains the specification for filesystem that is to be created on the card. + The filesystem consists of several nested blocks representing DF and EF files. + When the DFs or EFs are specified in card specific profile, this is added to the file system info specified in the main profile. + + + + + + + This block defines elementary file in PKCS#15 file hierarchy. + The name can be one of: + + + PKCS15-TokenInfo + + + PKCS15-ODF + + + PKCS15-UnusedSpace + + + PKCS15-PRKDF + + + PKCS15-PUKDF + + + PKCS15-PUKDF-TRUSTED + + + PKCS15-SKDF + + + PKCS15-CDF + + + PKCS15-CDF-TRUSTED + + + PKCS15-CDF-USEFUL + + + PKCS15-DODF + + + PKCS15-AODF + + + + + The EF block can contain: + + + + + + + + + + Type must match type of file. + + + + + + + + Value of ACL (Access Control List) (Default: NONE) + + + + + + + + File ID, relative path. + + + + + + + + File structure is one of: + + + TRANSPARENT + + + LINEAR-FIXED + + + LINEAR-FIXED-TLV + + + LINEAR-VARIABLE + + + LINEAR-VARIABLE-TLV + + + CYCLIC + + + CYCLIC-TLV + + + + + + + + + + + + This block defines directory file in PKCS#15 file hierarchy. + The name can be one of: + + + MF + + + PKCS15-AppDF + + + Special cases for those DFs handled separately by the PKCS15 logic + + + + + The DF block can contain: + + + + + + + + + + Type must match type of file. + + + + + + + + Specification of path of the directory file. + + + + + + + + File ID, relative path. + + + + + + + + Value of AID, in XX:XX:XX:...:XX:XX:XX notation. + + + + + + + + Type must match type of file. + + + + + + + + Size of the file in bytes. + + + + + + + + Block specifying nested elementary file. + + + + + Typically, the root DF is MF. + + + It is mandatory that profile file contains DF entry for MF (Master File). + Otherwise the profile file is incomplete and cannot be used. + + + + + + The DF can contain other DF or MF blocks. + For examples how the filesystem structure may look like, + please refer to pkcs15.profile or any other present profile file. + + + + From 94c23f9eadfd9e9e4de329f487e337ba35564413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 16 May 2024 13:04:17 +0200 Subject: [PATCH 3471/4321] Fix generation of pkcs15-profile documentation --- .gitignore | 1 + doc/files/Makefile.am | 12 +++++++++--- doc/files/files.html | 2 +- ...{pkcs15-profile.5.xml => pkcs15-profile.5.xml.in} | 0 4 files changed, 11 insertions(+), 4 deletions(-) rename doc/files/{pkcs15-profile.5.xml => pkcs15-profile.5.xml.in} (100%) diff --git a/.gitignore b/.gitignore index 0f744e252c..82015023ca 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ doc/tools/pkcs15-init doc/tools/opensc-asn1 doc/tools/opensc-notify doc/files/opensc.conf.5.xml +doc/files/pkcs15-profile.5.xml etc/opensc.conf.example src/common/compat_getopt_main diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am index d28d75e1ce..0a8a498b7b 100644 --- a/doc/files/Makefile.am +++ b/doc/files/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -dist_noinst_DATA = pkcs15-profile.5.xml opensc.conf.5.xml.in files.xml +dist_noinst_DATA = pkcs15-profile.5.xml.in opensc.conf.5.xml.in files.xml if ENABLE_DOC html_DATA = files.html endif @@ -21,7 +21,13 @@ opensc.conf.5.xml opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in < $< > opensc.conf.5.xml $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl opensc.conf.5.xml 2>/dev/null -files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml +pkcs15-profile.5.xml pkcs15-profile.5: $(srcdir)/pkcs15-profile.5.xml.in + @sed \ + -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \ + < $< > pkcs15-profile.5.xml + $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl pkcs15-profile.5.xml 2>/dev/null + +files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml pkcs15-profile.5.xml $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< 2>/dev/null %.5: $(srcdir)/%.5.xml @@ -29,4 +35,4 @@ files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml | $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl - 2>/dev/null clean-local: - -rm -rf $(html_DATA) $(man5_MANS) opensc.conf.5.xml + -rm -rf $(html_DATA) $(man5_MANS) *.5.xml diff --git a/doc/files/files.html b/doc/files/files.html index ad0c7753c8..59a25268f9 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -1231,7 +1231,7 @@

    The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. - Profiles currently reside in @pkgdatadir@ + Profiles currently reside in /usr/share/opensc

    Basic PKCS#15 terminology:

    1. diff --git a/doc/files/pkcs15-profile.5.xml b/doc/files/pkcs15-profile.5.xml.in similarity index 100% rename from doc/files/pkcs15-profile.5.xml rename to doc/files/pkcs15-profile.5.xml.in From 23882037dcfa003d07ca57ef9ac917f9dc416f36 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 15 May 2024 09:57:17 +0300 Subject: [PATCH 3472/4321] Remove legacy EstEID codepaths Signed-off-by: Raul Metsma --- src/libopensc/card-mcrd.c | 70 --------------------------------------- 1 file changed, 70 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 5abdfc4b43..3a549999eb 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -102,24 +102,6 @@ struct mcrd_priv_data { #define DRVDATA(card) ((struct mcrd_priv_data *) ((card)->drv_data)) -// Control Reference Template Tag for Key Agreement (ISO 7816-4:2013 Table 54) -static const struct sc_asn1_entry c_asn1_control[] = { - { "control", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 0xA6, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -// Ephemeral public key Template Tag (ISO 7816-8:2016 Table 3) -static const struct sc_asn1_entry c_asn1_ephermal[] = { - { "ephemeral", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x7F49, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - -// External Public Key -static const struct sc_asn1_entry c_asn1_public[] = { - { "publicKey", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0x86, 0, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - static int load_special_files(sc_card_t * card); static int select_part(sc_card_t * card, u8 kind, unsigned short int fid, sc_file_t ** file); @@ -950,7 +932,6 @@ static int mcrd_set_security_env(sc_card_t * card, switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - case SC_SEC_OPERATION_DERIVE: sc_log(card->ctx, "Using keyref %d to decipher\n", env->key_ref[0]); mcrd_delete_ref_to_authkey(card); mcrd_delete_ref_to_signkey(card); @@ -966,7 +947,6 @@ static int mcrd_set_security_env(sc_card_t * card, sbuf[3] = env->key_ref[0]; switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: - case SC_SEC_OPERATION_DERIVE: sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, sbuf, 5, NULL, 0); break; case SC_SEC_OPERATION_SIGN: @@ -1043,55 +1023,6 @@ static int mcrd_compute_signature(sc_card_t * card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen); } -static int mcrd_decipher(struct sc_card *card, - const u8 * crgram, size_t crgram_len, - u8 * out, size_t outlen) -{ - sc_security_env_t *env = NULL; - int r = 0; - size_t sbuf_len = 0; - sc_apdu_t apdu; - u8 *sbuf = NULL; - struct sc_asn1_entry asn1_control[2], asn1_ephermal[2], asn1_public[2]; - - if (card == NULL || crgram == NULL || out == NULL) - return SC_ERROR_INVALID_ARGUMENTS; - env = &DRVDATA(card)->sec_env; - - LOG_FUNC_CALLED(card->ctx); - if (env->operation != SC_SEC_OPERATION_DERIVE) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->decipher(card, crgram, crgram_len, out, outlen)); - if (crgram_len > 255) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); - - sc_log(card->ctx, - "Will derive (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %lu flags %lu\n", - env->operation, crgram_len, crgram_len, env->key_ref[0], - env->algorithm, env->algorithm_flags); - - // Encode TLV - sc_copy_asn1_entry(c_asn1_control, asn1_control); - sc_copy_asn1_entry(c_asn1_ephermal, asn1_ephermal); - sc_copy_asn1_entry(c_asn1_public, asn1_public); - sc_format_asn1_entry(asn1_public + 0, (void*)crgram, &crgram_len, 1); - sc_format_asn1_entry(asn1_ephermal + 0, &asn1_public, NULL, 1); - sc_format_asn1_entry(asn1_control + 0, &asn1_ephermal, NULL, 1); - r = sc_asn1_encode(card->ctx, asn1_control, &sbuf, &sbuf_len); - LOG_TEST_RET(card->ctx, r, "Error encoding TLV."); - - // Create APDU - sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x80, 0x86, sbuf, sbuf_len, out, MIN(0x80U, outlen)); - r = sc_transmit_apdu(card, &apdu); - sc_mem_clear(sbuf, sbuf_len); - free(sbuf); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, "Card returned error"); - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen); -} - /* added by -mp, to give pin information in the card driver (pkcs15emu->driver needed) */ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int *tries_left) @@ -1127,7 +1058,6 @@ static struct sc_card_driver *sc_get_driver(void) mcrd_ops.select_file = mcrd_select_file; mcrd_ops.set_security_env = mcrd_set_security_env; mcrd_ops.compute_signature = mcrd_compute_signature; - mcrd_ops.decipher = mcrd_decipher; mcrd_ops.pin_cmd = mcrd_pin_cmd; mcrd_ops.logout = mcrd_logout; From 82340fe1060c033d8a503cbce9d7e783ed8b765c Mon Sep 17 00:00:00 2001 From: msetina Date: Sun, 12 May 2024 13:15:09 +0200 Subject: [PATCH 3473/4321] Changes to properly identify IDPrime MD 840 Previously MD 840 was identified as 940. Also changed the part where mechanism are assigned to the card, so that EC is also added as by spec. --- src/libopensc/card-idprime.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 9ce764b217..bafbdc6d2f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -61,6 +61,10 @@ static const struct sc_atr_table idprime_atrs[] = { "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", "based Gemalto IDPrime 930", SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", + "Gemalto IDPrime 840", + SC_CARD_TYPE_IDPRIME_840, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940", @@ -68,11 +72,7 @@ static const struct sc_atr_table idprime_atrs[] = { { "3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940C", - SC_CARD_TYPE_IDPRIME_940, 0, NULL }, - { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", - "Gemalto IDPrime 840", - SC_CARD_TYPE_IDPRIME_840, 0, NULL }, + SC_CARD_TYPE_IDPRIME_940, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards", @@ -652,7 +652,10 @@ static int idprime_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_IDPRIME_930 || card->type == SC_CARD_TYPE_IDPRIME_940) { _sc_card_add_rsa_alg(card, 4096, flags, 0); - + } + if (card->type == SC_CARD_TYPE_IDPRIME_930 + || card->type == SC_CARD_TYPE_IDPRIME_940 + || card->type == SC_CARD_TYPE_IDPRIME_840) { /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_F_P From 04c7b983cbf6dd8a53cc80ec4a381c57dae5f42c Mon Sep 17 00:00:00 2001 From: msetina Date: Mon, 13 May 2024 12:35:48 +0200 Subject: [PATCH 3474/4321] formating condition --- src/libopensc/card-idprime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index bafbdc6d2f..204841fed8 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -653,9 +653,9 @@ static int idprime_init(sc_card_t *card) || card->type == SC_CARD_TYPE_IDPRIME_940) { _sc_card_add_rsa_alg(card, 4096, flags, 0); } - if (card->type == SC_CARD_TYPE_IDPRIME_930 - || card->type == SC_CARD_TYPE_IDPRIME_940 - || card->type == SC_CARD_TYPE_IDPRIME_840) { + if (card->type == SC_CARD_TYPE_IDPRIME_930 || + card->type == SC_CARD_TYPE_IDPRIME_940 || + card->type == SC_CARD_TYPE_IDPRIME_840) { /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_F_P From 48e50070981df1cbb5386e00255cde0ea06200c0 Mon Sep 17 00:00:00 2001 From: msetina Date: Mon, 13 May 2024 14:18:18 +0200 Subject: [PATCH 3475/4321] formating of condition --- src/libopensc/card-idprime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 204841fed8..faf5053e11 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -654,8 +654,8 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 4096, flags, 0); } if (card->type == SC_CARD_TYPE_IDPRIME_930 || - card->type == SC_CARD_TYPE_IDPRIME_940 || - card->type == SC_CARD_TYPE_IDPRIME_840) { + card->type == SC_CARD_TYPE_IDPRIME_940 || + card->type == SC_CARD_TYPE_IDPRIME_840) { /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_F_P From 6eae1d3679ae7db029a46403fec7aafeae319c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 21 May 2024 09:27:47 +0200 Subject: [PATCH 3476/4321] p11test: Initialize variable Thanks Coverity CID 425951 --- src/tests/p11test/p11test_case_readonly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 1ed5bfba52..8cb57b6c30 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -394,7 +394,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_BYTE *cmp_message = NULL; - unsigned int cmp_message_length; + unsigned int cmp_message_length = 0; if (o->type == EVP_PKEY_RSA) { const EVP_MD *md = NULL; From 36df02863d5e7d2d95fb308cc518c97e4c28fe45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 21 May 2024 09:41:25 +0200 Subject: [PATCH 3477/4321] goid-tool-cmdline.c: Check realloc return value Thanks Coverity CID 14282 --- src/tools/goid-tool-cmdline.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index 1836678a7f..c0b1a6f40d 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -1048,6 +1048,8 @@ void update_multiple_arg(void *field, char ***orig_field, if (prev_given && list) { *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); + if (!*orig_field) + return; switch(arg_type) { case ARG_INT: From 4a673504395034ff104d9a9f8418465761f7fbf3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 May 2024 10:25:54 +0200 Subject: [PATCH 3478/4321] pcsc: fixed unhandled error on reconnection fixes https://github.com/OpenSC/OpenSC/issues/3139 --- src/libopensc/reader-pcsc.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 35ce4803ce..a1deb779bb 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -276,11 +276,15 @@ static int pcsc_internal_transmit(sc_reader_t *reader, case SCARD_E_INVALID_HANDLE: case SCARD_E_INVALID_VALUE: case SCARD_E_READER_UNAVAILABLE: - pcsc_connect(reader); + LOG_TEST_RET(reader->ctx, + pcsc_connect(reader), + "Could not connect to card after reattached reader."); /* return failure so that upper layers will be notified */ return SC_ERROR_READER_REATTACHED; case SCARD_W_RESET_CARD: - pcsc_reconnect(reader, SCARD_LEAVE_CARD); + LOG_TEST_RET(reader->ctx, + pcsc_reconnect(reader, SCARD_LEAVE_CARD), + "Could not reconnect to card after reattached reader."); /* return failure so that upper layers will be notified */ return SC_ERROR_CARD_RESET; default: @@ -680,7 +684,6 @@ static int pcsc_disconnect(sc_reader_t * reader) static int pcsc_lock(sc_reader_t *reader) { LONG rv; - int r; struct pcsc_private_data *priv = reader->drv_data; if (priv->gpriv->cardmod) @@ -702,23 +705,15 @@ static int pcsc_lock(sc_reader_t *reader) /* This is returned in case of the same reader was re-attached */ case SCARD_E_INVALID_HANDLE: case SCARD_E_READER_UNAVAILABLE: - r = pcsc_connect(reader); - if (r != SC_SUCCESS) { - sc_log(reader->ctx, "pcsc_connect failed (%d)", - r); - return r; - } + LOG_TEST_RET(reader->ctx, + pcsc_connect(reader), + "Could not connect to card after reattached reader."); /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_READER_REATTACHED; case SCARD_W_RESET_CARD: - /* try to reconnect if the card was reset by some other application */ - PCSC_TRACE(reader, "SCardBeginTransaction calling pcsc_reconnect", rv); - r = pcsc_reconnect(reader, SCARD_LEAVE_CARD); - if (r != SC_SUCCESS) { - sc_log(reader->ctx, - "pcsc_reconnect failed (%d)", r); - return r; - } + LOG_TEST_RET(reader->ctx, + pcsc_reconnect(reader, SCARD_LEAVE_CARD), + "Could not reconnect to card after reattached reader."); /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_CARD_RESET; case SCARD_S_SUCCESS: From cd3e8b955b67a38d5090871cf850fe968be3f834 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 May 2024 11:13:41 +0200 Subject: [PATCH 3479/4321] changed formatting --- src/libopensc/reader-pcsc.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index a1deb779bb..9599b7ac27 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -239,6 +239,7 @@ static int pcsc_internal_transmit(sc_reader_t *reader, SCARD_IO_REQUEST sSendPci, sRecvPci; DWORD dwSendLength, dwRecvLength; LONG rv = SCARD_E_INVALID_VALUE; + int r; SCARDHANDLE card; LOG_FUNC_CALLED(reader->ctx); @@ -276,15 +277,13 @@ static int pcsc_internal_transmit(sc_reader_t *reader, case SCARD_E_INVALID_HANDLE: case SCARD_E_INVALID_VALUE: case SCARD_E_READER_UNAVAILABLE: - LOG_TEST_RET(reader->ctx, - pcsc_connect(reader), - "Could not connect to card after reattached reader."); + r = pcsc_connect(reader); + LOG_TEST_RET(reader->ctx, r, "Could not connect to card after reattached reader."); /* return failure so that upper layers will be notified */ return SC_ERROR_READER_REATTACHED; case SCARD_W_RESET_CARD: - LOG_TEST_RET(reader->ctx, - pcsc_reconnect(reader, SCARD_LEAVE_CARD), - "Could not reconnect to card after reattached reader."); + r = pcsc_reconnect(reader, SCARD_LEAVE_CARD); + LOG_TEST_RET(reader->ctx, r, "Could not reconnect to card after reattached reader."); /* return failure so that upper layers will be notified */ return SC_ERROR_CARD_RESET; default: @@ -684,6 +683,7 @@ static int pcsc_disconnect(sc_reader_t * reader) static int pcsc_lock(sc_reader_t *reader) { LONG rv; + int r; struct pcsc_private_data *priv = reader->drv_data; if (priv->gpriv->cardmod) @@ -705,15 +705,13 @@ static int pcsc_lock(sc_reader_t *reader) /* This is returned in case of the same reader was re-attached */ case SCARD_E_INVALID_HANDLE: case SCARD_E_READER_UNAVAILABLE: - LOG_TEST_RET(reader->ctx, - pcsc_connect(reader), - "Could not connect to card after reattached reader."); + r = pcsc_connect(reader); + LOG_TEST_RET(reader->ctx, r, "Could not connect to card after reattached reader."); /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_READER_REATTACHED; case SCARD_W_RESET_CARD: - LOG_TEST_RET(reader->ctx, - pcsc_reconnect(reader, SCARD_LEAVE_CARD), - "Could not reconnect to card after reattached reader."); + r = pcsc_reconnect(reader, SCARD_LEAVE_CARD); + LOG_TEST_RET(reader->ctx, r, "Could not reconnect to card after reattached reader."); /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_CARD_RESET; case SCARD_S_SUCCESS: From 13951f633b5f1df14d5c49310cd397a42a467f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 22 May 2024 09:21:03 +0200 Subject: [PATCH 3480/4321] Desctivate driver for MICARDO No recent user activity. Regarding the developer activity, the only changes in recent years were tackling EstEID card, for which the support was removed in 7c19a92. --- src/libopensc/ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 2316209ee5..6fbab389c1 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -148,7 +148,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { * put the muscle driver first to cope with this bug. */ { "muscle", (void *(*)(void)) sc_get_muscle_driver }, { "sc-hsm", (void *(*)(void)) sc_get_sc_hsm_driver }, - { "mcrd", (void *(*)(void)) sc_get_mcrd_driver }, { "setcos", (void *(*)(void)) sc_get_setcos_driver }, { "PIV-II", (void *(*)(void)) sc_get_piv_driver }, { "cac", (void *(*)(void)) sc_get_cac_driver }, @@ -176,6 +175,7 @@ static const struct _sc_driver_entry old_card_drivers[] = { { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, { "cyberflex", (void *(*)(void)) sc_get_cyberflex_driver }, { "flex", (void *(*)(void)) sc_get_cryptoflex_driver }, + { "mcrd", (void *(*)(void)) sc_get_mcrd_driver }, { NULL, NULL } }; // clang-format on From c8cb5f0e906d9b5c3237e5cfccb72f99f169e4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 22 May 2024 09:24:41 +0200 Subject: [PATCH 3481/4321] Update use_file_caching for deactivated drivers --- doc/files/files.html | 8 ++++---- doc/files/opensc.conf.5.xml.in | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index 59a25268f9..cd18cfcf37 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -797,7 +797,7 @@

    (Default: public for the following card drivers - atrust-acos, + atrust-acos (deactivated driver), belpic, cac1, cac, @@ -805,14 +805,14 @@ dnie, edo, esteid2018, - flex, - cyberflex, + flex (deactivated driver), + cyberflex (deactivated driver), gemsafeV1, idprime, itacns, jpki, MaskTech, - mcrd, + mcrd (deactivated driver), npa, nqapplet, tcos and otherwise no). diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 9024262191..820a62be18 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1240,7 +1240,7 @@ app application { (Default: public for the following card drivers - atrust-acos, + atrust-acos (deactivated driver), belpic, cac1, cac, @@ -1248,14 +1248,14 @@ app application { dnie, edo, esteid2018, - flex, - cyberflex, + flex (deactivated driver), + cyberflex (deactivated driver), gemsafeV1, idprime, itacns, jpki, MaskTech, - mcrd, + mcrd (deactivated driver), npa, nqapplet, tcos and otherwise no). From 86eabd42ea7c93d23258c70ea79ea3ed4f3110f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 22 May 2024 09:55:04 +0200 Subject: [PATCH 3482/4321] card-piv: Fix integer overflow --- src/libopensc/card-piv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c3a3057997..ca071c58ed 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3408,11 +3408,11 @@ piv_put_data(sc_card_t *card, int tag, const u8 *buf, size_t buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); tag_len = piv_objects[tag].tag_len; - sbuflen = sc_asn1_put_tag(0x5c, piv_objects[tag].tag_value, tag_len, NULL, 0, NULL); - if (sbuflen <= 0) { + r = sc_asn1_put_tag(0x5c, piv_objects[tag].tag_value, tag_len, NULL, 0, NULL); + if (r <= 0) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - sbuflen += buf_len; + sbuflen = r + buf_len; if (!(sbuf = malloc(sbuflen))) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } From 6923b97d59f8a5a636223a36465912e0c640a534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 22 May 2024 10:11:46 +0200 Subject: [PATCH 3483/4321] iso7816.c: Check length of file_ref to prevent buffer overrun --- src/libopensc/iso7816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 73893e9416..98c059bdce 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1003,7 +1003,7 @@ iso7816_set_security_env(struct sc_card *card, *p++ = env->algorithm_ref & 0xFF; } if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { - if (env->file_ref.len > 0xFF) + if (env->file_ref.len > SC_MAX_PATH_SIZE) return SC_ERROR_INVALID_ARGUMENTS; if (sizeof(sbuf) - (p - sbuf) < env->file_ref.len + 2) return SC_ERROR_OFFSET_TOO_LARGE; From 6ceb50e271f4b67ec934aae5f8383475e1bd58ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 23 May 2024 10:04:08 +0200 Subject: [PATCH 3484/4321] iso7816.c: Check length of key_ref_len to prevent buffer overrun --- src/libopensc/iso7816.c | 2 +- src/libopensc/opensc.h | 2 +- src/libopensc/types.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 98c059bdce..d7e044993c 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1021,7 +1021,7 @@ iso7816_set_security_env(struct sc_card *card, *p++ = 0x83; else *p++ = 0x84; - if (env->key_ref_len > 0xFF) + if (env->key_ref_len > SC_MAX_KEYREF_SIZE) return SC_ERROR_INVALID_ARGUMENTS; *p++ = env->key_ref_len & 0xFF; memcpy(p, env->key_ref, env->key_ref_len); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index cbcb3bebb3..5faf590aec 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -251,7 +251,7 @@ typedef struct sc_security_env { unsigned long algorithm_ref; struct sc_path file_ref; - unsigned char key_ref[8]; + unsigned char key_ref[SC_MAX_KEYREF_SIZE]; size_t key_ref_len; struct sc_path target_file_ref; /* target key file in unwrap operation */ diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 7eea3fa826..304725a674 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -50,6 +50,7 @@ typedef unsigned char u8; #define SC_MAX_CRTS_IN_SE 12 #define SC_MAX_SE_NUM 8 #define SC_MAX_PKCS15_EMULATORS 48 +#define SC_MAX_KEYREF_SIZE 8 /* When changing this value, pay attention to the initialization of the ASN1 * static variables that use this macro, like, for example, From 66adbca8c7356cd78dce81bde573499043d33b3d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 27 May 2024 15:58:11 +0200 Subject: [PATCH 3485/4321] containers: Fix typos --- containers/opensc-build-ix86/Containerfile | 2 +- containers/opensc-build/Containerfile | 2 +- containers/opensc-mingw/Containerfile | 2 +- containers/opensc-test-cac/Containerfile | 2 +- containers/opensc-test-gidsapplet/Containerfile | 2 +- containers/opensc-test-openpgp/Containerfile | 2 +- containers/opensc-test-oseid/Containerfile | 2 +- containers/opensc-test-piv/Containerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/containers/opensc-build-ix86/Containerfile b/containers/opensc-build-ix86/Containerfile index 803b240fe2..52796df9da 100644 --- a/containers/opensc-build-ix86/Containerfile +++ b/containers/opensc-build-ix86/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-build/Containerfile b/containers/opensc-build/Containerfile index 8793c89bf6..79011dd5c6 100644 --- a/containers/opensc-build/Containerfile +++ b/containers/opensc-build/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-mingw/Containerfile b/containers/opensc-mingw/Containerfile index 7e1fe607d7..4722a79261 100644 --- a/containers/opensc-mingw/Containerfile +++ b/containers/opensc-mingw/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-test-cac/Containerfile b/containers/opensc-test-cac/Containerfile index 7dde899311..1f17f84595 100644 --- a/containers/opensc-test-cac/Containerfile +++ b/containers/opensc-test-cac/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-test-gidsapplet/Containerfile b/containers/opensc-test-gidsapplet/Containerfile index eee792f9e9..196abc9a4c 100644 --- a/containers/opensc-test-gidsapplet/Containerfile +++ b/containers/opensc-test-gidsapplet/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-test-openpgp/Containerfile b/containers/opensc-test-openpgp/Containerfile index 1c217ce336..4b647b5325 100644 --- a/containers/opensc-test-openpgp/Containerfile +++ b/containers/opensc-test-openpgp/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-test-oseid/Containerfile b/containers/opensc-test-oseid/Containerfile index a590832c11..34fdf31bf8 100644 --- a/containers/opensc-test-oseid/Containerfile +++ b/containers/opensc-test-oseid/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:latest RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ diff --git a/containers/opensc-test-piv/Containerfile b/containers/opensc-test-piv/Containerfile index ccf70628f5..15b11c040b 100644 --- a/containers/opensc-test-piv/Containerfile +++ b/containers/opensc-test-piv/Containerfile @@ -1,6 +1,6 @@ FROM ubuntu:20.04 RUN apt update -# Install sudo to mimic Github Actions runnner +# Install sudo to mimic Github Actions runner # Install tzdata to avoid messing up with interactive prompts later RUN export DEBIAN_FRONTEND=noninteractive; \ export DEBCONF_NONINTERACTIVE_SEEN=true; \ From d5087266554dabf78810092b1fe5e042b902a4ce Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 28 May 2024 18:25:10 +0200 Subject: [PATCH 3486/4321] log: Null terminate the errors from OpenSSL Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=67807 --- src/libopensc/log.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 1e8ca5f086..36d24a3e20 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -75,7 +75,7 @@ void sc_do_log_color(sc_context_t *ctx, int level, const char *file, int line, c void sc_do_log_openssl(sc_context_t *ctx, int level, const char *file, int line, const char *func) { BIO *bio = NULL; - int length = 0; + int length, rc; char *buffer = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL) { @@ -84,10 +84,21 @@ void sc_do_log_openssl(sc_context_t *ctx, int level, const char *file, int line, } ERR_print_errors(bio); - if ((length = BIO_pending(bio)) <= 0 || - (buffer = malloc(length)) == NULL || - BIO_read(bio, buffer, length) <= 0) { - sc_do_log(ctx, level, file, line, func, "Cannot log OpenSSL error"); + length = BIO_pending(bio); + if (length <= 0) { + /* no error? */ + goto end; + } + /* trailing null byte */ + buffer = malloc(length + 1); + if (buffer == NULL) { + sc_do_log(ctx, level, file, line, func, "No memory!"); + goto end; + } + rc = BIO_read(bio, buffer, length); + buffer[length] = '\0'; + if (rc <= 0) { + sc_do_log(ctx, level, file, line, func, "Cannot read OpenSSL error"); goto end; } From 61eed31286884ff8f0c4ad38f04586e234256832 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 3 Jun 2024 13:37:55 +0200 Subject: [PATCH 3487/4321] dtrust-tool: fix memory leak If `qespin1` and `qespin2` doesn't match, `qespin2` was neither cleared nor freed; --- src/tools/dtrust-tool.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 0ab4b5aabc..b29e16697a 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -167,19 +167,19 @@ unlock_transport_protection(sc_card_t *card) r = util_getpass(&qespin1, &qespin1_len, stdin); if (r < 0 || qespin1 == NULL) { fprintf(stderr, "Unable to get PIN"); - goto fail_qespin1; + goto fail; } printf("Enter new Signature PIN again:"); r = util_getpass(&qespin2, &qespin1_len, stdin); if (r < 0 || qespin2 == NULL) { fprintf(stderr, "Unable to get PIN"); - goto fail_qespin2; + goto fail; } if (strcmp(qespin1, qespin2)) { fprintf(stderr, "New signature PINs doesn't match.\n"); - goto fail_qespin2; + goto fail; } data.pin1.data = (u8 *)tpin; data.pin1.len = strlen(tpin); @@ -196,18 +196,17 @@ unlock_transport_protection(sc_card_t *card) else printf("Can't change pin: %s\n", sc_strerror(r)); +fail: if (qespin2 != NULL) { sc_mem_clear(qespin2, qespin2_len); free(qespin2); } -fail_qespin2: if (qespin1 != NULL) { sc_mem_clear(qespin1, qespin1_len); free(qespin1); } -fail_qespin1: if (tpin != NULL) { sc_mem_clear(tpin, tpin_len); free(tpin); From 1fc50dacbb2be1cf8a2d4416644017ff40c6c221 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Jun 2024 10:48:46 +0200 Subject: [PATCH 3488/4321] feat(pkcs11-tool): don't limit object size to 5000 bytes --- src/tools/pkcs11-tool.c | 50 +++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4e1668290f..14062ef710 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4015,17 +4015,15 @@ static void gost_info_free(struct gostkey_info gost) } #endif -#define MAX_OBJECT_SIZE 5000 - /* Currently for certificates (-type cert), private keys (-type privkey), public keys (-type pubkey) and data objects (-type data). */ static CK_RV write_object(CK_SESSION_HANDLE session) { CK_BBOOL _true = TRUE; CK_BBOOL _false = FALSE; - unsigned char contents[MAX_OBJECT_SIZE + 1]; + unsigned char *contents = NULL; ssize_t contents_len = 0; - unsigned char certdata[MAX_OBJECT_SIZE]; + unsigned char *certdata = NULL; ssize_t certdata_len = 0; FILE *f; CK_OBJECT_HANDLE cert_obj, privkey_obj, pubkey_obj, seckey_obj, data_obj; @@ -4038,6 +4036,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) CK_OBJECT_CLASS clazz; CK_CERTIFICATE_TYPE cert_type; CK_KEY_TYPE type = CKK_RSA; + size_t ret = 0; #ifdef ENABLE_OPENSSL struct x509cert_info cert; struct rsakey_info rsa; @@ -4050,25 +4049,43 @@ static CK_RV write_object(CK_SESSION_HANDLE session) memset(&gost, 0, sizeof(gost)); #endif - memset(contents, 0, sizeof(contents)); - memset(certdata, 0, sizeof(certdata)); - f = fopen(opt_file_to_write, "rb"); if (f == NULL) util_fatal("Couldn't open file \"%s\"", opt_file_to_write); - contents_len = fread(contents, 1, sizeof(contents) - 1, f); + if (fseek(f, 0L, SEEK_END) != 0) + util_fatal("Couldn't set file position to the end of the file \"%s\"", opt_file_to_write); + contents_len = ftell(f); if (contents_len < 0) + util_fatal("Couldn't get file position \"%s\"", opt_file_to_write); + contents = malloc(contents_len + 1); + if (contents == NULL) + util_fatal("malloc() failure\n"); + if (fseek(f, 0L, SEEK_SET) != 0) + util_fatal("Couldn't set file position to the beginning of the file \"%s\"", opt_file_to_write); + ret = fread(contents, 1, contents_len, f); + if (ret != (size_t)contents_len) util_fatal("Couldn't read from file \"%s\"", opt_file_to_write); fclose(f); contents[contents_len] = '\0'; if (opt_attr_from_file) { - if (!(f = fopen(opt_attr_from_file, "rb"))) + f = fopen(opt_attr_from_file, "rb"); + if (f == NULL) util_fatal("Couldn't open file \"%s\"", opt_attr_from_file); - certdata_len = fread(certdata, 1, sizeof(certdata) - 1, f); - fclose(f); + if (fseek(f, 0L, SEEK_END) != 0) + util_fatal("Couldn't set file position to the end of the file \"%s\"", opt_attr_from_file); + certdata_len = ftell(f); if (certdata_len < 0) + util_fatal("Couldn't get file position \"%s\"", opt_attr_from_file); + certdata = malloc(certdata_len + 1); + if (certdata == NULL) + util_fatal("malloc() failure\n"); + if (fseek(f, 0L, SEEK_SET) != 0) + util_fatal("Couldn't set file position to the beginning of the file \"%s\"", opt_attr_from_file); + ret = fread(certdata, 1, certdata_len, f); + if (ret != (size_t)certdata_len) util_fatal("Couldn't read from file \"%s\"", opt_attr_from_file); + fclose(f); certdata[certdata_len] = '\0'; need_to_parse_certdata = 1; } @@ -4083,7 +4100,10 @@ static CK_RV write_object(CK_SESSION_HANDLE session) util_fatal("No OpenSSL support, cannot parse certificate"); #endif } else { - memcpy(certdata, contents, MAX_OBJECT_SIZE); + certdata = malloc(contents_len + 1); + if (certdata == NULL) + util_fatal("malloc() failure\n"); + memcpy(certdata, contents, contents_len + 1); certdata_len = contents_len; need_to_parse_certdata = 1; } @@ -4421,7 +4441,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(seckey_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); FILL_ATTR(seckey_templ[1], CKA_KEY_TYPE, &type, sizeof(type)); FILL_ATTR(seckey_templ[2], CKA_TOKEN, &_true, sizeof(_true)); - FILL_ATTR(seckey_templ[3], CKA_VALUE, &contents, contents_len); + FILL_ATTR(seckey_templ[3], CKA_VALUE, contents, contents_len); n_seckey_attr = 4; if (opt_is_private != 0) { @@ -4484,7 +4504,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) clazz = CKO_DATA; FILL_ATTR(data_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); FILL_ATTR(data_templ[1], CKA_TOKEN, &_true, sizeof(_true)); - FILL_ATTR(data_templ[2], CKA_VALUE, &contents, contents_len); + FILL_ATTR(data_templ[2], CKA_VALUE, contents, contents_len); n_data_attr = 3; @@ -4575,6 +4595,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) EVP_PKEY_free(evp_key); #endif /* ENABLE_OPENSSL */ + free(contents); + free(certdata); if (oid_buf) free(oid_buf); return 1; From 82e8216a42e3227c9fbe85c848b59b6d73d6385e Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Jun 2024 15:18:02 +0200 Subject: [PATCH 3489/4321] feat(pkcs11-tool): remove useless calls to token in show_dobj() --- src/tools/pkcs11-tool.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 14062ef710..98cb484d09 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5531,6 +5531,8 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) char *application; CK_ULONG size = 0; CK_TOKEN_INFO info; + CK_BBOOL modifiable = 0; + CK_BBOOL private = 0; suppress_warn = 1; printf("Data object %u\n", (unsigned int) obj); @@ -5570,11 +5572,13 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } printf(" flags: "); - if (getMODIFIABLE(sess, obj)) + modifiable = getMODIFIABLE(sess, obj); + if (modifiable) printf(" modifiable"); - if (getPRIVATE(sess, obj)) + private = getPRIVATE(sess, obj); + if (private) printf(" private"); - if (!getMODIFIABLE(sess, obj) && !getPRIVATE(sess, obj)) + if (!modifiable && !private) printf(""); printf("\n"); From c3e4d2a7cbcf1a14c07e69424203dd2876116c0e Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Jun 2024 14:57:29 +0200 Subject: [PATCH 3490/4321] feat(pkcs11-tool): an invalid signature is a fatal error --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 98cb484d09..ecd54c5ce3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2541,9 +2541,9 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (rv == CKR_OK) printf("Signature is valid\n"); else if (rv == CKR_SIGNATURE_INVALID) - printf("Invalid signature\n"); + util_fatal("Invalid signature"); else - printf("Cryptoki returned error: %s\n", CKR2Str(rv)); + util_fatal("Signature verification failed: rv = %s (0x%0x)\n", CKR2Str(rv), (unsigned int)rv); } static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, From 81e5d5488d1b18240b6d759bcb58f7484ada0e0f Mon Sep 17 00:00:00 2001 From: Vladimir Stoiakin Date: Tue, 4 Jun 2024 14:27:25 +0300 Subject: [PATCH 3491/4321] build: fix linking of opensc-notify.exe on Windows --- src/ui/invisible_window.h | 2 +- src/ui/notify.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/invisible_window.h b/src/ui/invisible_window.h index f7f0121111..89dd906ae3 100644 --- a/src/ui/invisible_window.h +++ b/src/ui/invisible_window.h @@ -20,7 +20,7 @@ #include -HWND create_invisible_window(LPCTSTR lpszClassName, +static HWND create_invisible_window(LPCTSTR lpszClassName, LRESULT (CALLBACK* WndProc)(HWND, UINT, WPARAM, LPARAM), HINSTANCE hInstance) { diff --git a/src/ui/notify.c b/src/ui/notify.c index 5045c4f678..e693bb377d 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -104,7 +104,7 @@ static int GetMonitorScalingRatio(void) return 100; } -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: From d18d2cd2a97c7bdfd654282e60fdc413ffedda94 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Fri, 24 May 2024 17:27:31 +0200 Subject: [PATCH 3492/4321] Add key size to security environment passed into card driver --- src/libopensc/opensc.h | 1 + src/libopensc/pkcs15-sec.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5faf590aec..3dfba519d3 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -248,6 +248,7 @@ typedef struct sc_security_env { unsigned long flags; int operation; unsigned long algorithm, algorithm_flags; + int key_size; unsigned long algorithm_ref; struct sc_path file_ref; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index edde62398b..0cfa47e67b 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -200,6 +200,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_RSA; + senv_out->key_size = prkey->modulus_length; break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: @@ -211,6 +212,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_GOSTR3410; + senv_out->key_size = prkey->modulus_length; break; case SC_PKCS15_TYPE_PRKEY_EDDSA: @@ -222,6 +224,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_EDDSA; + senv_out->key_size = prkey->field_length; break; case SC_PKCS15_TYPE_PRKEY_XEDDSA: @@ -233,6 +236,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_XEDDSA; + senv_out->key_size = prkey->field_length; break; case SC_PKCS15_TYPE_PRKEY_EC: @@ -244,6 +248,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_EC; + senv_out->key_size = prkey->field_length; senv_out->flags |= SC_SEC_ENV_ALG_REF_PRESENT; senv_out->algorithm_ref = prkey->field_length; @@ -260,6 +265,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_AES; + senv_out->key_size = skey->value_len; break; /* add other crypto types here */ default: From 8b7f7f53be9296a7ed8284175b6b6d52906a1bd6 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Fri, 24 May 2024 17:30:11 +0200 Subject: [PATCH 3493/4321] Fix sporadic failure of secp521r1 signature and add missing mechanisms --- src/libopensc/card-sc-hsm.c | 36 +++++++++++++++-------------------- src/libopensc/card-sc-hsm.h | 6 ++++++ src/libopensc/pkcs15-sc-hsm.c | 9 +++++++++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 009439fe8f..d4c9ff2643 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1020,6 +1020,10 @@ static int sc_hsm_set_security_env(sc_card_t *card, priv->algorithm = ALGO_RSA_PKCS1_SHA1; } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) { priv->algorithm = ALGO_RSA_PKCS1_SHA256; + } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) { + priv->algorithm = ALGO_RSA_PKCS1_SHA384; + } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) { + priv->algorithm = ALGO_RSA_PKCS1_SHA512; } else { priv->algorithm = ALGO_RSA_PKCS1; } @@ -1048,6 +1052,10 @@ static int sc_hsm_set_security_env(sc_card_t *card, priv->algorithm = ALGO_EC_SHA224; } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { priv->algorithm = ALGO_EC_SHA256; + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA384) { + priv->algorithm = ALGO_EC_SHA384; + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA512) { + priv->algorithm = ALGO_EC_SHA512; } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { priv->algorithm = ALGO_EC_RAW; } else { @@ -1065,27 +1073,11 @@ static int sc_hsm_set_security_env(sc_card_t *card, static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, const u8 * data, size_t datalen, - u8 * out, size_t outlen) { + u8 * out, size_t outlen, + int key_size) { int r; - size_t fieldsizebytes; - - // Determine field size from length of signature - if (datalen <= 58) { // 192 bit curve = 24 * 2 + 10 byte maximum DER signature - fieldsizebytes = 24; - } else if (datalen <= 66) { // 224 bit curve = 28 * 2 + 10 byte maximum DER signature - fieldsizebytes = 28; - } else if (datalen <= 74) { // 256 bit curve = 32 * 2 + 10 byte maximum DER signature - fieldsizebytes = 32; - } else if (datalen <= 90) { // 320 bit curve = 40 * 2 + 10 byte maximum DER signature - fieldsizebytes = 40; - } else if (datalen <= 106) { // 384 bit curve = 48 * 2 + 10 byte maximum DER signature - fieldsizebytes = 48; - } else if (datalen <= 137) { // 512 bit curve = 64 * 2 + 9 byte maximum DER signature - fieldsizebytes = 64; - } else { - fieldsizebytes = 66; - } + size_t fieldsizebytes = (key_size + 7) >> 3; sc_log(card->ctx, "Field size %"SC_FORMAT_LEN_SIZE_T"u, signature buffer size %"SC_FORMAT_LEN_SIZE_T"u", @@ -1131,7 +1123,7 @@ static int sc_hsm_compute_signature(sc_card_t *card, int len; if ((priv->algorithm & 0xF0) == ALGO_EC_RAW) { - len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen); + len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen, priv->env->key_size); if (len < 0) { LOG_FUNC_RETURN(card->ctx, len); } @@ -1802,7 +1794,7 @@ static int sc_hsm_init(struct sc_card *card) LOG_FUNC_CALLED(card->ctx); flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN - |SC_ALGORITHM_RSA_HASH_SHA256|SC_ALGORITHM_RSA_HASH_SHA384|SC_ALGORITHM_RSA_HASH_SHA512 + |SC_ALGORITHM_RSA_HASH_SHA1|SC_ALGORITHM_RSA_HASH_SHA256|SC_ALGORITHM_RSA_HASH_SHA384|SC_ALGORITHM_RSA_HASH_SHA512 |SC_ALGORITHM_MGF1_SHA256|SC_ALGORITHM_MGF1_SHA384|SC_ALGORITHM_MGF1_SHA512; _sc_card_add_rsa_alg(card, 1024, flags, 0); @@ -1817,6 +1809,8 @@ static int sc_hsm_init(struct sc_card *card) SC_ALGORITHM_ECDSA_HASH_SHA1| SC_ALGORITHM_ECDSA_HASH_SHA224| SC_ALGORITHM_ECDSA_HASH_SHA256| + SC_ALGORITHM_ECDSA_HASH_SHA384| + SC_ALGORITHM_ECDSA_HASH_SHA512| SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_F_P| diff --git a/src/libopensc/card-sc-hsm.h b/src/libopensc/card-sc-hsm.h index 5b2734015d..3668f960d8 100644 --- a/src/libopensc/card-sc-hsm.h +++ b/src/libopensc/card-sc-hsm.h @@ -40,15 +40,21 @@ #define ALGO_RSA_PKCS1 0x30 /* RSA signature with DigestInfo input and PKCS#1 V1.5 padding */ #define ALGO_RSA_PKCS1_SHA1 0x31 /* RSA signature with SHA-1 hash and PKCS#1 V1.5 padding */ #define ALGO_RSA_PKCS1_SHA256 0x33 /* RSA signature with SHA-256 hash and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PKCS1_SHA384 0x34 /* RSA signature with SHA-384 hash and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PKCS1_SHA512 0x35 /* RSA signature with SHA-512 hash and PKCS#1 V1.5 padding */ #define ALGO_RSA_PSS 0x40 /* RSA signature with external hash and PKCS#1 PSS padding*/ #define ALGO_RSA_PSS_SHA1 0x41 /* RSA signature with SHA-1 hash and PKCS#1 PSS padding */ #define ALGO_RSA_PSS_SHA256 0x43 /* RSA signature with SHA-256 hash and PKCS#1 PSS padding */ +#define ALGO_RSA_PSS_SHA384 0x44 /* RSA signature with SHA-384 hash and PKCS#1 PSS padding */ +#define ALGO_RSA_PSS_SHA512 0x45 /* RSA signature with SHA-512 hash and PKCS#1 PSS padding */ #define ALGO_EC_RAW 0x70 /* ECDSA signature with hash input */ #define ALGO_EC_SHA1 0x71 /* ECDSA signature with SHA-1 hash */ #define ALGO_EC_SHA224 0x72 /* ECDSA signature with SHA-224 hash */ #define ALGO_EC_SHA256 0x73 /* ECDSA signature with SHA-256 hash */ +#define ALGO_EC_SHA384 0x74 /* ECDSA signature with SHA-384 hash */ +#define ALGO_EC_SHA512 0x75 /* ECDSA signature with SHA-512 hash */ #define ALGO_EC_DH 0x80 /* ECDH key derivation */ #define ID_USER_PIN 0x81 /* User PIN identifier */ diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 1f362777de..d0c68c6c1d 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1076,6 +1076,11 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) { size_t len; int r; + if (keyid == 0) { + // Device authentication key doe not have PKCS#15 meta data + return SC_SUCCESS; + } + fid[0] = PRKD_PREFIX; fid[1] = keyid; @@ -1106,6 +1111,10 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) { if (prkd.type == SC_PKCS15_TYPE_PRKEY_RSA) { r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkd, key_info); } else { + if (key_info->field_length == 528) { + // Fix a bug for secp521 key generated with OpenSCDP + key_info->field_length = 521; + } r = sc_pkcs15emu_add_ec_prkey(p15card, &prkd, key_info); } From d4e7823c8f5f265bdf64904cc644eeb26b89ad31 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Fri, 24 May 2024 17:45:01 +0200 Subject: [PATCH 3494/4321] Avoid conversion of int to size_t --- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/opensc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index d4c9ff2643..9ea103bc4d 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1074,7 +1074,7 @@ static int sc_hsm_set_security_env(sc_card_t *card, static int sc_hsm_decode_ecdsa_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen, - int key_size) { + size_t key_size) { int r; size_t fieldsizebytes = (key_size + 7) >> 3; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 3dfba519d3..f24c6fca29 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -248,7 +248,7 @@ typedef struct sc_security_env { unsigned long flags; int operation; unsigned long algorithm, algorithm_flags; - int key_size; + size_t key_size; unsigned long algorithm_ref; struct sc_path file_ref; From 83acf2fb9b36ea36c800d1888768338983882798 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Thu, 30 May 2024 13:46:12 +0200 Subject: [PATCH 3495/4321] Rename field to clarify encoding in bits --- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/opensc.h | 2 +- src/libopensc/pkcs15-sec.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 9ea103bc4d..cd22f543eb 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1123,7 +1123,7 @@ static int sc_hsm_compute_signature(sc_card_t *card, int len; if ((priv->algorithm & 0xF0) == ALGO_EC_RAW) { - len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen, priv->env->key_size); + len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen, priv->env->key_size_bits); if (len < 0) { LOG_FUNC_RETURN(card->ctx, len); } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index f24c6fca29..97659527af 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -248,7 +248,7 @@ typedef struct sc_security_env { unsigned long flags; int operation; unsigned long algorithm, algorithm_flags; - size_t key_size; + size_t key_size_bits; unsigned long algorithm_ref; struct sc_path file_ref; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 0cfa47e67b..d1631610f4 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -200,7 +200,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_RSA; - senv_out->key_size = prkey->modulus_length; + senv_out->key_size_bits = prkey->modulus_length; break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: @@ -212,7 +212,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_GOSTR3410; - senv_out->key_size = prkey->modulus_length; + senv_out->key_size_bits = prkey->modulus_length; break; case SC_PKCS15_TYPE_PRKEY_EDDSA: @@ -224,7 +224,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_EDDSA; - senv_out->key_size = prkey->field_length; + senv_out->key_size_bits = prkey->field_length; break; case SC_PKCS15_TYPE_PRKEY_XEDDSA: @@ -236,7 +236,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_XEDDSA; - senv_out->key_size = prkey->field_length; + senv_out->key_size_bits = prkey->field_length; break; case SC_PKCS15_TYPE_PRKEY_EC: @@ -248,7 +248,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_EC; - senv_out->key_size = prkey->field_length; + senv_out->key_size_bits = prkey->field_length; senv_out->flags |= SC_SEC_ENV_ALG_REF_PRESENT; senv_out->algorithm_ref = prkey->field_length; @@ -265,7 +265,7 @@ static int format_senv(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } senv_out->algorithm = SC_ALGORITHM_AES; - senv_out->key_size = skey->value_len; + senv_out->key_size_bits = skey->value_len; break; /* add other crypto types here */ default: From 19b0e9830c2581a1d57b1da08a17e05f225358d4 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Thu, 30 May 2024 13:48:35 +0200 Subject: [PATCH 3496/4321] Fix typo --- src/libopensc/pkcs15-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index d0c68c6c1d..315cd74482 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1077,7 +1077,7 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) { int r; if (keyid == 0) { - // Device authentication key doe not have PKCS#15 meta data + // Device authentication key does not have PKCS#15 meta data return SC_SUCCESS; } From 1685f370b07128ef1fd0e602860d4ce76a7f9b81 Mon Sep 17 00:00:00 2001 From: invis-z <22781620+invis-z@users.noreply.github.com> Date: Sat, 25 May 2024 10:31:59 +0800 Subject: [PATCH 3497/4321] piv-tool: Fix RSA key generation `params = OSSL_PARAM_BLD_to_param(bld)` was called twice, once inside `if` condition and once after the `if`. Removed the second one to resolve issue generating RSA keys with OpenSSL 3.0. --- src/tools/piv-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index fd37a82722..b9e3d4a5c3 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -423,7 +423,7 @@ static int gen_key(const char * key_info) BN_free(newkey_e); return -1; } - params = OSSL_PARAM_BLD_to_param(bld); + BN_free(newkey_n); BN_free(newkey_e); From 98ead26a963336e7f7e8a14def2b2ca36676feec Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 20 Jun 2024 11:49:21 +0200 Subject: [PATCH 3498/4321] ci: Update upload/download-artifact to v4 The v3 will be deprecated in the end of 2024 https://github.com/actions/upload-artifact/blob/main/docs/MIGRATION.md --- .github/workflows/cifuzz.yml | 2 +- .github/workflows/fedora.yml | 2 +- .github/workflows/linux-strict.yml | 2 +- .github/workflows/linux.yml | 24 ++++++++++++------------ .github/workflows/macos.yml | 4 ++-- .github/workflows/packit.yaml | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 9b6c34f03f..02590105b3 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -22,7 +22,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 76ffb5b438..0755cd69af 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -25,7 +25,7 @@ jobs: - run: .github/setup-fedora.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: fedora-test-logs diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 3add7e4514..3be81565b4 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -76,7 +76,7 @@ jobs: CC: ${{ matrix.compiler }} CFLAGS: ${{ env.CFLAGS }} ${{ matrix.compiler == 'clang' && env.CLANG_CFLAGS || '' }} - name: Upload test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: ${{ matrix.name }}-${{ matrix.compiler }}-strict-test-logs diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ed0609ff2b..53aa595fe6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -43,7 +43,7 @@ jobs: - run: .github/setup-linux.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: ubuntu-test-logs @@ -56,7 +56,7 @@ jobs: path: ./* key: ${{ runner.os }}-${{ github.sha }} - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-build path: @@ -74,7 +74,7 @@ jobs: - run: .github/setup-linux.sh debug - run: .github/build.sh valgrind - name: Upload test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: ubuntu-valgrind-logs @@ -125,7 +125,7 @@ jobs: - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-build-mingw path: @@ -143,7 +143,7 @@ jobs: - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-build-mingw32 path: @@ -161,7 +161,7 @@ jobs: - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist - name: Upload test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: name: ubuntu-piv-sm-test-logs @@ -394,7 +394,7 @@ jobs: execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh dist valgrind - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: name: ubuntu-22-test-logs @@ -408,10 +408,10 @@ jobs: path: ./* key: ${{ runner.os }}-22-${{ github.sha }} - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ success() }} with: - name: opensc-build + name: opensc-22-build path: opensc*.tar.gz @@ -426,7 +426,7 @@ jobs: execute_install_scripts: true - run: .github/setup-linux.sh - run: .github/build.sh piv-sm dist valgrind - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: name: ubuntu-22-piv-sm-test-logs @@ -524,7 +524,7 @@ jobs: key: libressl-${{ env.LIBRESSL_VERSION }} - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: name: libressl-logs @@ -598,7 +598,7 @@ jobs: path: ./* key: ${{ runner.os }}-${{ github.sha }} - name: Pull mingw build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: opensc-build-mingw - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index cfdb4209c1..e446b803df 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -34,7 +34,7 @@ jobs: DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} - name: Cache build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-build-${{ matrix.os }} path: @@ -50,7 +50,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Pull build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: opensc-build-macos-12 - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index 85933ced5b..95676a693f 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -21,7 +21,7 @@ jobs: fetch-depth: 0 - uses: packit/actions/srpm@main - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-srpm path: @@ -35,7 +35,7 @@ jobs: fetch-depth: 0 - uses: ./.github/actions/packit - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: opensc-rpm path: From 4b7a9b01416aea283969c0ca285555921727ed9d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Jun 2024 21:26:01 +0200 Subject: [PATCH 3499/4321] pkcs15-init: Check return value of fseek Thanks coverity CID 426268 --- src/tools/pkcs15-init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 3759e252ee..61aa9bfbb7 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -2504,11 +2504,16 @@ static size_t determine_filesize(const char *filename) { FILE *fp; long ll; + int rc; - if ((fp = fopen(filename,"rb")) == NULL) + fp = fopen(filename,"rb"); + if (fp == NULL) util_fatal("Unable to open %s: %m", filename); - fseek(fp,0L,SEEK_END); + rc = fseek(fp, 0L, SEEK_END); + if (rc != 0) + util_fatal("Unable seek in the opened file %s", filename); + ll = ftell(fp); if (ll == -1l) util_fatal("fseek/ftell error"); From b879b9b20523d44d40a43d215d63c367b78a4588 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Mon, 24 Jun 2024 12:49:22 +0200 Subject: [PATCH 3500/4321] clang-format cardctl.h so PR #3189 can be applied cleanly --- src/libopensc/cardctl.h | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 70115977a7..34f88c9da8 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -56,7 +56,7 @@ enum { /* * TCOS specific calls */ - SC_CARDCTL_TCOS_BASE = _CTL_PREFIX('T','C','S'), + SC_CARDCTL_TCOS_BASE = _CTL_PREFIX('T', 'C', 'S'), SC_CARDCTL_TCOS_SETPERM, /* @@ -99,7 +99,7 @@ enum { /* * Muscle specific calls */ - SC_CARDCTL_MUSCLE_BASE = _CTL_PREFIX('M','S','C'), + SC_CARDCTL_MUSCLE_BASE = _CTL_PREFIX('M', 'S', 'C'), SC_CARDCTL_MUSCLE_GENERATE_KEY, SC_CARDCTL_MUSCLE_EXTRACT_KEY, SC_CARDCTL_MUSCLE_IMPORT_KEY, @@ -108,26 +108,26 @@ enum { /* * ASEPCOS specific calls */ - SC_CARDCTL_ASEPCOS_BASE = _CTL_PREFIX('A','S','E'), + SC_CARDCTL_ASEPCOS_BASE = _CTL_PREFIX('A', 'S', 'E'), SC_CARDCTL_ASEPCOS_CHANGE_KEY, SC_CARDCTL_ASEPCOS_AKN2FILEID, SC_CARDCTL_ASEPCOS_SET_SATTR, SC_CARDCTL_ASEPCOS_ACTIVATE_FILE, - /* + /* * ruToken specific calls */ - SC_CARDCTL_RUTOKEN_BASE = _CTL_PREFIX('R', 'T', 'K'), - /* PUT_DATA */ - SC_CARDCTL_RUTOKEN_CREATE_DO, - SC_CARDCTL_RUTOKEN_CHANGE_DO, - SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, - SC_CARDCTL_RUTOKEN_DELETE_DO, - SC_CARDCTL_RUTOKEN_GET_INFO, - /* NON STANDARD */ - SC_CARDCTL_RUTOKEN_GET_DO_INFO, - SC_CARDCTL_RUTOKEN_GOST_ENCIPHER, - SC_CARDCTL_RUTOKEN_GOST_DECIPHER, + SC_CARDCTL_RUTOKEN_BASE = _CTL_PREFIX('R', 'T', 'K'), + /* PUT_DATA */ + SC_CARDCTL_RUTOKEN_CREATE_DO, + SC_CARDCTL_RUTOKEN_CHANGE_DO, + SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, + SC_CARDCTL_RUTOKEN_DELETE_DO, + SC_CARDCTL_RUTOKEN_GET_INFO, + /* NON STANDARD */ + SC_CARDCTL_RUTOKEN_GET_DO_INFO, + SC_CARDCTL_RUTOKEN_GOST_ENCIPHER, + SC_CARDCTL_RUTOKEN_GOST_DECIPHER, SC_CARDCTL_RUTOKEN_FORMAT_INIT, SC_CARDCTL_RUTOKEN_FORMAT_END, @@ -150,8 +150,8 @@ enum { SC_CARDCTL_RTECP_GENERATE_KEY, /* - * Westcos specific - */ + * Westcos specific + */ SC_CARDCTL_WESTCOS_FREEZE = _CTL_PREFIX('W', 'T', 'C'), SC_CARDCTL_WESTCOS_CREATE_MF, SC_CARDCTL_WESTCOS_COMMIT, @@ -191,14 +191,14 @@ enum { SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS, SC_CARDCTL_CAC_GET_ACA_PATH, - /* + /* * AuthentIC v3 */ - SC_CARDCTL_AUTHENTIC_BASE = _CTL_PREFIX('A','V','3'), - SC_CARDCTL_AUTHENTIC_SDO_CREATE, - SC_CARDCTL_AUTHENTIC_SDO_DELETE, - SC_CARDCTL_AUTHENTIC_SDO_STORE, - SC_CARDCTL_AUTHENTIC_SDO_GENERATE, + SC_CARDCTL_AUTHENTIC_BASE = _CTL_PREFIX('A', 'V', '3'), + SC_CARDCTL_AUTHENTIC_SDO_CREATE, + SC_CARDCTL_AUTHENTIC_SDO_DELETE, + SC_CARDCTL_AUTHENTIC_SDO_STORE, + SC_CARDCTL_AUTHENTIC_SDO_GENERATE, /* * Coolkey specific calls @@ -211,13 +211,13 @@ enum { SC_CARDCTL_COOLKEY_GET_TOKEN_INFO, SC_CARDCTL_COOLKEY_FIND_OBJECT, - /* + /* * IAS/ECC */ - SC_CARDCTL_IASECC_BASE = _CTL_PREFIX('E','C','C'), + SC_CARDCTL_IASECC_BASE = _CTL_PREFIX('E', 'C', 'C'), SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE, - SC_CARDCTL_IASECC_SDO_MAGIC = _CTL_PREFIX('S','D','O') | 'M', - SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA = _CTL_PREFIX('S','D','O') | 'P', + SC_CARDCTL_IASECC_SDO_MAGIC = _CTL_PREFIX('S', 'D', 'O') | 'M', + SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA = _CTL_PREFIX('S', 'D', 'O') | 'P', SC_CARDCTL_IASECC_SDO_PUT_DATA, SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA, SC_CARDCTL_IASECC_SDO_GET_DATA, @@ -248,21 +248,21 @@ enum { /* * DNIe specific calls */ - SC_CARDCTL_DNIE_BASE = _CTL_PREFIX('D', 'N', 'I'), + SC_CARDCTL_DNIE_BASE = _CTL_PREFIX('D', 'N', 'I'), SC_CARDCTL_DNIE_GENERATE_KEY, SC_CARDCTL_DNIE_GET_INFO, /* * isoApplet Java Card Applet */ - SC_CARDCTL_ISOAPPLET_BASE = _CTL_PREFIX('I','S','O'), + SC_CARDCTL_ISOAPPLET_BASE = _CTL_PREFIX('I', 'S', 'O'), SC_CARDCTL_ISOAPPLET_GENERATE_KEY, SC_CARDCTL_ISOAPPLET_IMPORT_KEY, /* * GIDS cards */ - SC_CARDCTL_GIDS_BASE = _CTL_PREFIX('G','I','D'), + SC_CARDCTL_GIDS_BASE = _CTL_PREFIX('G', 'I', 'D'), SC_CARDCTL_GIDS_GET_ALL_CONTAINERS, SC_CARDCTL_GIDS_GET_CONTAINER_DETAIL, SC_CARDCTL_GIDS_SELECT_KEY_REFERENCE, From 6a65b5159cce51cc75d85777865622ddcaad157f Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Fri, 21 Jun 2024 13:27:13 +0200 Subject: [PATCH 3501/4321] Verbosify sc_card_ctl() invocation Currently it's hard to know which SC_CARDCTL_* parameter was sc_card_ctl() called with --- src/libopensc/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 7f4ef98f91..6978639565 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1116,7 +1116,7 @@ sc_card_ctl(sc_card_t *card, unsigned long cmd, void *args) if (card == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } - LOG_FUNC_CALLED(card->ctx); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called with cmd=%lu\n", cmd); if (card->ops->card_ctl != NULL) r = card->ops->card_ctl(card, cmd, args); From 2b9188b401d39235a0727eff343f5cc6d632a480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Mon, 24 Jun 2024 11:22:23 +0200 Subject: [PATCH 3502/4321] feat(pkcs11-tool): add support for CKM_AES_CMAC_GENERAL --- src/pkcs11/pkcs11.h | 4 ++++ src/tools/pkcs11-tool.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 929afd92a1..288cf6e0cb 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -966,6 +966,10 @@ typedef struct CK_AES_CTR_PARAMS { typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR; +typedef unsigned long CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS *CK_MAC_GENERAL_PARAMS_PTR; + typedef unsigned long ck_rv_t; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ecd54c5ce3..6a123c9582 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -212,7 +212,8 @@ enum { OPT_OBJECT_INDEX, OPT_ALLOW_SW, OPT_LIST_INTERFACES, - OPT_IV + OPT_IV, + OPT_MAC_GEN_PARAM, }; // clang-format off @@ -300,6 +301,7 @@ static const struct option options[] = { { "generate-random", 1, NULL, OPT_GENERATE_RANDOM }, { "allow-sw", 0, NULL, OPT_ALLOW_SW }, { "iv", 1, NULL, OPT_IV }, + { "mac-general-param", 1, NULL, OPT_MAC_GEN_PARAM}, { NULL, 0, NULL, 0 } }; @@ -389,6 +391,7 @@ static const char *option_help[] = { "Generate given amount of random data", "Allow using software mechanisms (without CKF_HW)", "Initialization vector", + "Specify the value of the mechanism parameter CK_MAC_GENERAL_PARAMS", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -448,6 +451,7 @@ static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input param static int opt_always_auth = 0; static CK_FLAGS opt_allow_sw = CKF_HW; static const char * opt_iv = NULL; +static unsigned long opt_mac_gen_param = 0; static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -1077,6 +1081,14 @@ int main(int argc, char * argv[]) case OPT_UNDESTROYABLE: opt_is_destroyable = 0; break; + case OPT_MAC_GEN_PARAM: + if (optarg != NULL) { + char *end_ptr; + opt_mac_gen_param = strtoul(optarg, &end_ptr, 10); + } else { + util_fatal("--mac-general-param option needs a decimal value argument"); + } + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -2308,6 +2320,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1025], sig_buffer[512]; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; + CK_MAC_GENERAL_PARAMS mac_gen_param; CK_RV rv; CK_ULONG sig_len; int fd; @@ -2336,6 +2349,16 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("For %s mechanism, message size (got %z bytes) " "must be equal to specified digest length (%lu)\n", p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } else if (opt_mechanism == CKM_AES_CMAC_GENERAL) { + if (opt_mac_gen_param == 0 || opt_mac_gen_param > 16) { + util_fatal("For %s mechanism, the option --mac-general-param " + "is mandatory and its value must be comprised between 1 and " + "16 (>=8 recommended).\n", + p11_mechanism_to_name(opt_mechanism)); + } + mac_gen_param = opt_mac_gen_param; + mech.pParameter = &mac_gen_param; + mech.ulParameterLen = sizeof(CK_MAC_GENERAL_PARAMS); } rv = CKR_CANCEL; @@ -2415,6 +2438,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1025], sig_buffer[512]; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; + CK_MAC_GENERAL_PARAMS mac_gen_param; CK_RV rv; CK_ULONG sig_len; int fd, fd2; @@ -2504,6 +2528,16 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("For %s mechanism, message size (got %z bytes)" " must be equal to specified digest length (%lu)\n", p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } else if (opt_mechanism == CKM_AES_CMAC_GENERAL) { + if (opt_mac_gen_param == 0 || opt_mac_gen_param > 16) { + util_fatal("For %s mechanism, the option --mac-general-param " + "is mandatory and its value must be comprised between 1 and " + "16 (>=8 recommended).\n", + p11_mechanism_to_name(opt_mechanism)); + } + mac_gen_param = opt_mac_gen_param; + mech.pParameter = &mac_gen_param; + mech.ulParameterLen = sizeof(CK_MAC_GENERAL_PARAMS); } rv = CKR_CANCEL; @@ -8741,6 +8775,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_AES_CTR, "AES-CTR", NULL, MF_UNKNOWN }, { CKM_AES_GCM, "AES-GCM", NULL, MF_UNKNOWN }, { CKM_AES_CMAC, "AES-CMAC", NULL, (MF_SIGN | MF_VERIFY | MF_CKO_SECRET_KEY) }, + { CKM_AES_CMAC_GENERAL, "AES-CMAC-GENERAL", NULL, (MF_SIGN | MF_VERIFY | MF_CKO_SECRET_KEY) }, { CKM_DES_ECB_ENCRYPT_DATA, "DES-ECB-ENCRYPT-DATA", NULL, MF_UNKNOWN }, { CKM_DES_CBC_ENCRYPT_DATA, "DES-CBC-ENCRYPT-DATA", NULL, MF_UNKNOWN }, { CKM_DES3_ECB_ENCRYPT_DATA, "DES3-ECB-ENCRYPT-DATA", NULL, MF_UNKNOWN }, From 62c0daa3b429145bdd4a860e9bd88ed7a34c9c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Mon, 24 Jun 2024 11:50:20 +0200 Subject: [PATCH 3503/4321] doc(pkcs11-tool): Add new cli switch --- doc/tools/pkcs11-tool.1.xml | 9 +++++++++ doc/tools/tools.html | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 965d704077..d505563d9d 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -700,6 +700,15 @@ + + + num + + Sets the length of the MAC for the general-length MACing mechanisms + to num bytes. + + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 4294dc16fd..46848c3be3 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1714,6 +1714,10 @@ --iv data

    Initialization vector for symmetric ciphers. The data is hexadecimal number, i.e. "000013aa7bffa0". +

    + --mac-general-param num +

    Sets the length of the MAC for the general-length MACing mechanisms + to num bytes.

    Examples

    Perform a basic functionality test of the card: From 259decf656a77a6d1bd3e944d6f198ed70832ff5 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Mon, 24 Jun 2024 11:26:51 +0200 Subject: [PATCH 3504/4321] Only append PIN name to token label if necessary There is no need to append PIN name to token label, if the token has only one PIN object (occupies only one virtual slot). --- src/pkcs11/framework-pkcs15.c | 28 +++++++++++++++++++++++++++- src/pkcs11/sc-pkcs11.h | 3 +++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 68b7a790dd..dff50f6716 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1108,6 +1108,17 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj, obj->base.flags &= ~SC_PKCS11_OBJECT_RECURS; } +static unsigned int +get_num_slots(struct sc_card *card) +{ + unsigned int i; + for (i = 0; i < list_size(&virtual_slots); i++) { + sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *)list_get_at(&virtual_slots, i); + if (slot && slot->p11card && slot->p11card->card == card) + return slot->p11card->num_slots; + } + return 0; +} static void pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, @@ -1159,7 +1170,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, size_t pin_len = 0; if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) pin_len = strlen(auth->label); - if (pin_len) { + if (pin_len && get_num_slots(p15card->card) > 1) { size_t tokeninfo_len = 0; if (p15card->tokeninfo && p15card->tokeninfo->label) tokeninfo_len = strlen(p15card->tokeninfo->label); @@ -1624,6 +1635,10 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf } sc_log(context, "create slots flags 0x%X", cs_flags); + if (p11card) { + p11card->num_slots = 0; + } + /* Find out framework data corresponding to the given application */ fw_data = get_fw_data(p11card, app_info, &idx); if (!fw_data) { @@ -1680,6 +1695,13 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf auth_count = rc; sc_log(context, "Found %d authentication objects", auth_count); + for (i = 0; i < auth_count; i++) { + struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *)auths[i]->data; + if (!_is_slot_auth_object(pin_info)) + continue; + p11card->num_slots++; + } + for (i = 0; i < auth_count; i++) { struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info*)auths[i]->data; struct sc_pkcs11_slot *islot = NULL; @@ -1703,6 +1725,10 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf } } else { + if (auth_user_pin && (cs_flags & SC_PKCS11_SLOT_FOR_PIN_USER)) + p11card->num_slots++; + if (auth_sign_pin && (cs_flags & SC_PKCS11_SLOT_FOR_PIN_SIGN)) + p11card->num_slots++; sc_log(context, "User/Sign PINs %p/%p", auth_user_pin, auth_sign_pin); if (auth_user_pin && (cs_flags & SC_PKCS11_SLOT_FOR_PIN_USER)) { /* For the UserPIN of the first slot create slot */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 510017ed2a..4334f58fff 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -201,6 +201,9 @@ struct sc_pkcs11_card { /* List of supported mechanisms */ struct sc_pkcs11_mechanism_type **mechanisms; unsigned int nmechanisms; + + /* Number of virtual slots the card occupies */ + unsigned int num_slots; }; /* If the slot did already show with `C_GetSlotList`, then we need to keep this From fdea247c1ff9fc638c78fcfcdfd09d1dcad88c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Wed, 3 Jul 2024 17:14:53 +0200 Subject: [PATCH 3505/4321] feat(pkcs11-tool): add support for CKM_AES_GCM encryption --- src/tools/pkcs11-tool.c | 110 ++++++++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6a123c9582..2e425b36ae 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -214,6 +214,8 @@ enum { OPT_LIST_INTERFACES, OPT_IV, OPT_MAC_GEN_PARAM, + OPT_AAD, + OPT_TAG_BITS }; // clang-format off @@ -302,6 +304,8 @@ static const struct option options[] = { { "allow-sw", 0, NULL, OPT_ALLOW_SW }, { "iv", 1, NULL, OPT_IV }, { "mac-general-param", 1, NULL, OPT_MAC_GEN_PARAM}, + { "aad", 1, NULL, OPT_AAD }, + { "tag-bits-len", 1, NULL, OPT_TAG_BITS}, { NULL, 0, NULL, 0 } }; @@ -392,6 +396,8 @@ static const char *option_help[] = { "Allow using software mechanisms (without CKF_HW)", "Initialization vector", "Specify the value of the mechanism parameter CK_MAC_GENERAL_PARAMS", + "Specify additional authenticated data for AEAD ciphers as a hex string", + "Specify the required length (in bits) for the authentication tag for AEAD ciphers", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -452,6 +458,8 @@ static int opt_always_auth = 0; static CK_FLAGS opt_allow_sw = CKF_HW; static const char * opt_iv = NULL; static unsigned long opt_mac_gen_param = 0; +static const char *opt_aad = NULL; +static unsigned long opt_tag_bits = 0; static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -604,7 +612,7 @@ static void p11_perror(const char *, CK_RV); static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); static int test_card_detection(int); -static CK_BYTE_PTR get_iv(const char * iv_input, size_t *iv_size); +static CK_BYTE_PTR hex_string_to_byte_array(const char *iv_input, size_t *iv_size, const char *buffer_name); static void pseudo_randomize(unsigned char *data, size_t dataLen); static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session); static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session); @@ -1089,6 +1097,17 @@ int main(int argc, char * argv[]) util_fatal("--mac-general-param option needs a decimal value argument"); } break; + case OPT_AAD: + opt_aad = optarg; + break; + case OPT_TAG_BITS: + if (optarg != NULL) { + char *end_ptr; + opt_tag_bits = strtoul(optarg, &end_ptr, 10); + } else { + util_fatal("--tag-bits-len option needs a decimal value argument"); + } + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -2587,11 +2606,14 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_MECHANISM mech; CK_RV rv; CK_RSA_PKCS_OAEP_PARAMS oaep_params; + CK_GCM_PARAMS gcm_params = {0}; CK_ULONG in_len, out_len; int fd_in, fd_out; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; ssize_t sz; + CK_BYTE_PTR aad = NULL; + size_t aad_size = 0; if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_DECRYPT|opt_allow_sw, NULL, 0, &opt_mechanism)) @@ -2653,10 +2675,21 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, case CKM_AES_CBC: case CKM_AES_CBC_PAD: iv_size = 16; - iv = get_iv(opt_iv, &iv_size); + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mech.pParameter = iv; mech.ulParameterLen = iv_size; break; + case CKM_AES_GCM: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + gcm_params.pIv = iv; + gcm_params.ulIvLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + gcm_params.pAAD = aad; + gcm_params.ulAADLen = aad_size; + gcm_params.ulTagBits = opt_tag_bits; + mech.pParameter = &gcm_params; + mech.ulParameterLen = sizeof(gcm_params); + break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } @@ -2746,6 +2779,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, close(fd_out); free(iv); + free(aad); } static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, @@ -2757,8 +2791,11 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_ULONG in_len, out_len; int fd_in, fd_out; ssize_t sz; + CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; + CK_BYTE_PTR aad = NULL; + size_t aad_size = 0; if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_ENCRYPT | opt_allow_sw, NULL, 0, &opt_mechanism)) @@ -2776,10 +2813,21 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, case CKM_AES_CBC: case CKM_AES_CBC_PAD: iv_size = 16; - iv = get_iv(opt_iv, &iv_size); + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mech.pParameter = iv; mech.ulParameterLen = iv_size; break; + case CKM_AES_GCM: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + gcm_params.pIv = iv; + gcm_params.ulIvLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + gcm_params.pAAD = aad; + gcm_params.ulAADLen = aad_size; + gcm_params.ulTagBits = opt_tag_bits; + mech.pParameter = &gcm_params; + mech.ulParameterLen = sizeof(gcm_params); + break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } @@ -2847,6 +2895,7 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, close(fd_out); free(iv); + free(aad); } @@ -3471,7 +3520,7 @@ unwrap_key(CK_SESSION_HANDLE session) if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { iv_size = 16; - iv = get_iv(opt_iv, &iv_size); + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mechanism.pParameter = iv; mechanism.ulParameterLen = iv_size; } @@ -3584,7 +3633,7 @@ wrap_key(CK_SESSION_HANDLE session) mechanism.ulParameterLen = 0; if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { iv_size = 16; - iv = get_iv(opt_iv, &iv_size); + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mechanism.pParameter = iv; mechanism.ulParameterLen = iv_size; } @@ -8508,35 +8557,52 @@ static void p11_perror(const char *msg, CK_RV rv) { fprintf(stderr, " ERR: %s failed: %s (0x%0x)\n", msg, CKR2Str(rv), (unsigned int) rv); } -static CK_BYTE_PTR get_iv(const char *iv_input, size_t *iv_size) + +#define MAX_HEX_STR_LEN (1U << 16) // Arbitrary, GCM IV and AAD can theoretically be much bigger +static CK_BYTE_PTR +hex_string_to_byte_array(const char *hex_input, size_t *input_size, const char *buffer_name) { - CK_BYTE_PTR iv; - size_t size = *iv_size; + CK_BYTE_PTR array; + size_t size = 0; - /* no IV supplied on command line */ - if (!iv_input) { - *iv_size = 0; + /* no hex string supplied on command line */ + if (!hex_input) { + *input_size = 0; return NULL; } - iv = calloc(*iv_size, sizeof(CK_BYTE)); - if (!iv) { - fprintf(stderr, "Warning, out of memory, IV will not be used.\n"); - *iv_size = 0; + /* If no length is provided, determine the length of the hex string */ + if (*input_size == 0) { + size = strnlen(hex_input, MAX_HEX_STR_LEN); + if (size % 2 != 0) { + fprintf(stderr, "Odd length, provided %s is an invalid hex string.\n", buffer_name); + return NULL; + } + *input_size = size / 2; + } + + size = *input_size; + + array = calloc(*input_size, sizeof(CK_BYTE)); + if (!array) { + fprintf(stderr, "Warning, out of memory, %s will not be used.\n", buffer_name); + *input_size = 0; return NULL; } - if (sc_hex_to_bin(iv_input, iv, &size)) { - fprintf(stderr, "Warning, unable to parse IV, IV will not be used.\n"); - *iv_size = 0; - free(iv); + if (sc_hex_to_bin(hex_input, array, &size)) { + fprintf(stderr, "Warning, unable to parse %s, %s will not be used.\n", + buffer_name, buffer_name); + *input_size = 0; + free(array); return NULL; } - if (*iv_size != size) - fprintf(stderr, "Warning: IV string is too short, IV will be padded from the right by zeros.\n"); + if (*input_size != size) + fprintf(stderr, "Warning: %s string is too short, %s will be padded from the right by zeros.\n", + buffer_name, buffer_name); - return iv; + return array; } static void pseudo_randomize(unsigned char *data, size_t dataLen) From 40db104f77394de40e05bd164a376a791f469e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Wed, 3 Jul 2024 17:43:29 +0200 Subject: [PATCH 3506/4321] doc(pkcs11-tool): Add new cli switches --- doc/tools/pkcs11-tool.1.xml | 18 ++++++++++++++++++ doc/tools/tools.html | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index d505563d9d..d758649ad2 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -709,6 +709,24 @@ + + + data + + Additional authenticated data for AEAD ciphers. + The data is an hexadecimal number. + + + + + + num + + Sets the length of the tag for AEAD ciphers to + num bits. + + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 46848c3be3..2ca4c60bed 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1718,6 +1718,14 @@ --mac-general-param num

    Sets the length of the MAC for the general-length MACing mechanisms to num bytes. +

    + --aad data +

    Additional authenticated data for AEAD ciphers. + The data is an hexadecimal number. +

    + --tag-bits-len num +

    Sets the length of the tag for AEAD ciphers to + num bits.

    Examples

    Perform a basic functionality test of the card: From cea5b9a040df5ac143a574cf22b671a77b0705e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Wed, 3 Jul 2024 19:03:51 +0200 Subject: [PATCH 3507/4321] tst(pkcs11-tool): Test AES GCM encryption and decryption --- tests/test-pkcs11-tool-sym-crypt-test.sh | 37 +++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index b55fc0515c..d6b36f0cff 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -145,11 +145,46 @@ assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong encrypt" +ID3="87" +echo "=======================================================" +echo " AES-GCM, compare with test vectors" +echo " plaintext vector, pkcs11-tool encrypt, compare to ciphertext & tag vector" +echo " ciphertext & tag vector, pkcs11-tool decrypt, compare to plaintext vector" +echo "=======================================================" +# Command line OpenSSL does not support AES GCM, we have to compare with validated test vectors. +# The test vectors come from https://github.com/google/boringssl/blob/master/crypto/cipher_extra/test/cipher_tests.txt lines 354-360. +KEY="feffe9928665731c6d6a8f9467308308" +IV="cafebabefacedbaddecaf888" +PT="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39" +CT="42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091" +AAD="feedfacedeadbeeffeedfacedeadbeefabaddad2" +TAG="5bc94fbc3221a5db94fae95ae7121a47" + +echo -n $KEY | xxd -r -p > gcm_128.key +echo -n $PT | xxd -r -p > gcm_vector_plain.data +echo -n $CT | xxd -r -p > gcm_vector_ct_tag.data +echo -n $TAG | xxd -r -p >> gcm_vector_ct_tag.data + +softhsm2-util --import gcm_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_gcm_128 --id "$ID3" >/dev/null +assert $? "Fail, unable to import key" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ + --tag-bits-len 128 --input-file gcm_vector_plain.data --output-file gcm_test_ct_tag.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp gcm_vector_ct_tag.data gcm_test_ct_tag.data >/dev/null 2>&1 +assert $? "Fail, AES-GCM - wrong encrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ + --tag-bits-len 128 --input-file gcm_vector_ct_tag.data --output-file gcm_test_plain.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp gcm_vector_plain.data gcm_test_plain.data >/dev/null 2>&1 +assert $? "Fail, AES-GCM - wrong decrypt" + echo "=======================================================" echo "Cleanup" echo "=======================================================" softhsm_cleanup rm objects.list -rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain_pkcs11.data +rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain_pkcs11.data gcm_128.key gcm_vector_plain.data gcm_test_plain.data gcm_vector_ct_tag.data gcm_test_ct_tag.data exit $ERRORS From 9af4154700f61f54fa631a098019f4fde2714b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Thu, 4 Jul 2024 09:05:09 +0200 Subject: [PATCH 3508/4321] style(pkcs11-tool): Fix code style issues --- src/tools/pkcs11-tool.c | 158 ++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2e425b36ae..ec554647ba 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -312,89 +312,89 @@ static const struct option options[] = { // clang-format on static const char *option_help[] = { - "Specify the module to load (default:" DEFAULT_PKCS11_PROVIDER ")", - "Show global token information", - "List available slots", - "List slots with tokens", - "List mechanisms supported by the token", - "Show objects on token", - "List interfaces of PKCS #11 3.0 library", - - "Sign some data", - "Verify a signature of some data", - "Decrypt some data", - "Encrypt some data", - "Unwrap key", - "Wrap key", - "Hash some data", - "Derive a secret key using another key and some data", - "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", - "Specify mechanism (use -M for a list of supported mechanisms), or by hexadecimal, e.g., 0x80001234", - "Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption", - "Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)", - "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", - - "Forces to open the PKCS#11 session with CKF_RW_SESSION", - "Log into the token first", - "Specify login type ('so', 'user', 'context-specific'; default:'user')", - "Supply User PIN on the command line (if used in scripts: careful!)", - "Supply User PUK on the command line", - "Supply new User PIN on the command line", - "Supply SO PIN on the command line (if used in scripts: careful!)", - "Initialize the token, its label and its SO PIN (use with --label and --so-pin)", - "Initialize the User PIN (use with --pin and --login)", - "Change User PIN", - "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", - "Key pair generation", - "Key generation", - "Specify the type and length (bytes if symmetric) of the key to create, for example rsa:1024, EC:prime256v1, EC:ed25519, EC:curve25519, GOSTR3410-2012-256:B, AES:16 or GENERIC:64", - "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", - "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", - "Specify 'derive' key usage flag (EC only)", - "Specify 'wrap' key usage flag", - "Write an object (key, cert, data) to the card", - "Get object's CKA_VALUE attribute (use with --type)", - "Delete an object (use with --type cert/data/privkey/pubkey/secrkey)", - "Specify the application label of the data object (use with --type data)", - "Specify the application ID of the data object (use with --type data)", - "Specify the issuer in hexadecimal format (use with --type cert)", - "Specify the subject in hexadecimal format (use with --type cert/privkey/pubkey)", - "Specify the type of object (e.g. cert, privkey, pubkey, secrkey, data)", - "Specify the ID of the object", - "Specify the label of the object", - "Specify the ID of the slot to use (accepts HEX format with 0x.. prefix or decimal number)", - "Specify the description of the slot to use", - "Specify the index of the slot to use", - "Specify the index of the object to use", - "Specify the token label of the slot to use", - "Set the CKA_ID of an object, = the (new) CKA_ID", - "Use to create some attributes when writing an object", - "Specify the input file", - "Specify the file with signature for verification", - "Specify the output file", - "Format for ECDSA signature : 'rs' (default), 'sequence', 'openssl'", - "Specify the comma-separated list of allowed mechanisms when creating an object.", - - "Test (best used with the --login or --pin option)", - "Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)", - "Test Mozilla-like key pair gen and cert req, =certfile", - "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", - "Set the CKA_PRIVATE attribute (object is only viewable after a login)", - "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", - "Set the CKA_EXTRACTABLE attribute (object can be extracted)", - "Set the CKA_DESTROYABLE attribute to false (object cannot be destroyed)", - "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", - "Test EC (best used with the --login or --pin option)", + "Specify the module to load (default:" DEFAULT_PKCS11_PROVIDER ")", + "Show global token information", + "List available slots", + "List slots with tokens", + "List mechanisms supported by the token", + "Show objects on token", + "List interfaces of PKCS #11 3.0 library", + + "Sign some data", + "Verify a signature of some data", + "Decrypt some data", + "Encrypt some data", + "Unwrap key", + "Wrap key", + "Hash some data", + "Derive a secret key using another key and some data", + "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", + "Specify mechanism (use -M for a list of supported mechanisms), or by hexadecimal, e.g., 0x80001234", + "Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption", + "Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)", + "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", + + "Forces to open the PKCS#11 session with CKF_RW_SESSION", + "Log into the token first", + "Specify login type ('so', 'user', 'context-specific'; default:'user')", + "Supply User PIN on the command line (if used in scripts: careful!)", + "Supply User PUK on the command line", + "Supply new User PIN on the command line", + "Supply SO PIN on the command line (if used in scripts: careful!)", + "Initialize the token, its label and its SO PIN (use with --label and --so-pin)", + "Initialize the User PIN (use with --pin and --login)", + "Change User PIN", + "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", + "Key pair generation", + "Key generation", + "Specify the type and length (bytes if symmetric) of the key to create, for example rsa:1024, EC:prime256v1, EC:ed25519, EC:curve25519, GOSTR3410-2012-256:B, AES:16 or GENERIC:64", + "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", + "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", + "Specify 'derive' key usage flag (EC only)", + "Specify 'wrap' key usage flag", + "Write an object (key, cert, data) to the card", + "Get object's CKA_VALUE attribute (use with --type)", + "Delete an object (use with --type cert/data/privkey/pubkey/secrkey)", + "Specify the application label of the data object (use with --type data)", + "Specify the application ID of the data object (use with --type data)", + "Specify the issuer in hexadecimal format (use with --type cert)", + "Specify the subject in hexadecimal format (use with --type cert/privkey/pubkey)", + "Specify the type of object (e.g. cert, privkey, pubkey, secrkey, data)", + "Specify the ID of the object", + "Specify the label of the object", + "Specify the ID of the slot to use (accepts HEX format with 0x.. prefix or decimal number)", + "Specify the description of the slot to use", + "Specify the index of the slot to use", + "Specify the index of the object to use", + "Specify the token label of the slot to use", + "Set the CKA_ID of an object, = the (new) CKA_ID", + "Use to create some attributes when writing an object", + "Specify the input file", + "Specify the file with signature for verification", + "Specify the output file", + "Format for ECDSA signature : 'rs' (default), 'sequence', 'openssl'", + "Specify the comma-separated list of allowed mechanisms when creating an object.", + + "Test (best used with the --login or --pin option)", + "Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)", + "Test Mozilla-like key pair gen and cert req, =certfile", + "Verbose operation. (Set OPENSC_DEBUG to enable OpenSC specific debugging)", + "Set the CKA_PRIVATE attribute (object is only viewable after a login)", + "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", + "Set the CKA_EXTRACTABLE attribute (object can be extracted)", + "Set the CKA_DESTROYABLE attribute to false (object cannot be destroyed)", + "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", + "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 - "Test forking and calling C_Initialize() in the child", + "Test forking and calling C_Initialize() in the child", #endif - "Call C_initialize() with CKF_OS_LOCKING_OK.", + "Call C_initialize() with CKF_OS_LOCKING_OK.", #if defined(_WIN32) || defined(HAVE_PTHREAD) - "Test threads. Multiple times to start additional threads, arg is string or 2 byte commands", + "Test threads. Multiple times to start additional threads, arg is string or 2 byte commands", #endif - "Generate given amount of random data", - "Allow using software mechanisms (without CKF_HW)", - "Initialization vector", + "Generate given amount of random data", + "Allow using software mechanisms (without CKF_HW)", + "Initialization vector", "Specify the value of the mechanism parameter CK_MAC_GENERAL_PARAMS", "Specify additional authenticated data for AEAD ciphers as a hex string", "Specify the required length (in bits) for the authentication tag for AEAD ciphers", From 5d9f0d8333c4b507c4431f343e218a166c16f983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 2 Jul 2024 10:50:34 +0200 Subject: [PATCH 3509/4321] Allow OpenSSL engine header only for <3.0 --- src/pkcs11/openssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 9a36044ffa..c9c7c71506 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -33,6 +33,7 @@ #include #include /* for OPENSSL_NO_* */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#define OPENSSL_NO_ENGINE #include #include #endif @@ -258,7 +259,6 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) * Engine support is being deprecated in 3.0. OpenSC loads GOST as engine. * When GOST developers convert to provider, we can load the provider */ -#if OPENSSL_VERSION_NUMBER < 0x30000000L #if !defined(OPENSSL_NO_ENGINE) ENGINE *e; /* crypto locking removed in 1.1 */ @@ -304,7 +304,6 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) CRYPTO_set_locking_callback(locking_cb); #endif #endif /* !defined(OPENSSL_NO_ENGINE) */ -#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); openssl_sha1_mech.free_mech_data = ossl_md_free; From e3e09f74ab3fabb7d7fc79ac6510f6be0416cee5 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Mon, 24 Jun 2024 11:41:02 +0200 Subject: [PATCH 3510/4321] Fix disable flag for application conf block Currently the mere presence of 'disable=xx' disables the application. Even the 'disable=false', which imho can be confusing. Instead treat it as a boolan --- src/libopensc/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 7d634a8ec6..25db151dd3 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -98,8 +98,8 @@ parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, int rec_nr) sc_bin_to_hex(aid.value, aid.len, aid_str, sizeof(aid_str), 0); blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", aid_str); if (blocks) { - ignore_app = (blocks[0] && scconf_get_str(blocks[0], "disable", 0)); - free(blocks); + ignore_app = (blocks[0] && scconf_get_bool(blocks[0], "disable", 0)); + free(blocks); } if (ignore_app) { From 3fe53fb81ce3fd206e64927ac5c4d172c7234eee Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Jun 2024 12:08:25 +0200 Subject: [PATCH 3511/4321] feat(pkcs11-tool): allow encryption with public keys --- src/tools/pkcs11-tool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ec554647ba..6bd4bbe18f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1416,9 +1416,11 @@ int main(int argc, char * argv[]) find_object_flags(session, mf_flags, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0); - } else if (!find_object(session, CKO_SECRET_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) - util_fatal("Secret key not found"); + } else if (!find_object(session, CKO_PUBLIC_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Public/Secret key not found"); } if (do_verify) { From 8a20af82238ed5e26a3cb9d02b763ece3bd056dc Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Jun 2024 13:38:41 +0200 Subject: [PATCH 3512/4321] feat(pkcs11-tool): add support for RSA OAEP encryption --- src/tools/pkcs11-tool.c | 215 ++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 132 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6bd4bbe18f..d9a6af5567 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2601,6 +2601,72 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Signature verification failed: rv = %s (0x%0x)\n", CKR2Str(rv), (unsigned int)rv); } +static void +build_rsa_oaep_params( + CK_RSA_PKCS_OAEP_PARAMS *oaep_params, + CK_MECHANISM *mech, + char *param, + int param_len) +{ + /* An RSA-OAEP mechanism needs parameters */ + + /* set "default" MGF and hash algorithms. We can overwrite MGF later */ + oaep_params->hashAlg = opt_hash_alg; + switch (opt_hash_alg) { + case CKM_SHA_1: + oaep_params->mgf = CKG_MGF1_SHA1; + break; + case CKM_SHA224: + oaep_params->mgf = CKG_MGF1_SHA224; + break; + case CKM_SHA3_224: + oaep_params->mgf = CKG_MGF1_SHA3_224; + break; + case CKM_SHA3_256: + oaep_params->mgf = CKG_MGF1_SHA3_256; + break; + case CKM_SHA3_384: + oaep_params->mgf = CKG_MGF1_SHA3_384; + break; + case CKM_SHA3_512: + oaep_params->mgf = CKG_MGF1_SHA3_512; + break; + default: + printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(opt_hash_alg)); + oaep_params->hashAlg = CKM_SHA256; + /* fall through */ + case CKM_SHA256: + oaep_params->mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + oaep_params->mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + oaep_params->mgf = CKG_MGF1_SHA512; + break; + } + + if (opt_mgf != 0) { + oaep_params->mgf = opt_mgf; + } else { + printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(oaep_params->mgf)); + } + + oaep_params->source = CKZ_DATA_SPECIFIED; + oaep_params->pSourceData = param; + oaep_params->ulSourceDataLen = param_len; + + mech->pParameter = oaep_params; + mech->ulParameterLen = sizeof(*oaep_params); + + printf("OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", + p11_mechanism_to_name(oaep_params->hashAlg), + p11_mgf_to_name(oaep_params->mgf), + oaep_params->source, + oaep_params->pSourceData, + oaep_params->ulSourceDataLen); +} + static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { @@ -2624,7 +2690,6 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; - oaep_params.hashAlg = 0; if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) util_fatal("The hash-algorithm is applicable only to " @@ -2634,39 +2699,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { case CKM_RSA_PKCS_OAEP: - oaep_params.hashAlg = opt_hash_alg; - switch (opt_hash_alg) { - case CKM_SHA_1: - oaep_params.mgf = CKG_MGF1_SHA1; - break; - case CKM_SHA224: - oaep_params.mgf = CKG_MGF1_SHA224; - break; - case CKM_SHA3_224: - oaep_params.mgf = CKG_MGF1_SHA3_224; - break; - case CKM_SHA3_256: - oaep_params.mgf = CKG_MGF1_SHA3_256; - break; - case CKM_SHA3_384: - oaep_params.mgf = CKG_MGF1_SHA3_384; - break; - case CKM_SHA3_512: - oaep_params.mgf = CKG_MGF1_SHA3_512; - break; - default: - oaep_params.hashAlg = CKM_SHA256; - /* fall through */ - case CKM_SHA256: - oaep_params.mgf = CKG_MGF1_SHA256; - break; - case CKM_SHA384: - oaep_params.mgf = CKG_MGF1_SHA384; - break; - case CKM_SHA512: - oaep_params.mgf = CKG_MGF1_SHA512; - break; - } + build_rsa_oaep_params(&oaep_params, &mech, NULL, 0); break; case CKM_RSA_X_509: case CKM_RSA_PKCS: @@ -2696,29 +2729,6 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } - - /* If an RSA-OAEP mechanism, it needs parameters */ - if (oaep_params.hashAlg) { - if (opt_mgf != 0) - oaep_params.mgf = opt_mgf; - - /* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */ - oaep_params.source = 0UL; /* empty encoding parameter (label) */ - oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ - oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ - - mech.pParameter = &oaep_params; - mech.ulParameterLen = sizeof(oaep_params); - - fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", - p11_mechanism_to_name(oaep_params.hashAlg), - p11_mgf_to_name(oaep_params.mgf), - oaep_params.source, - oaep_params.pSourceData, - oaep_params.ulSourceDataLen); - - } - if (opt_input == NULL) fd_in = 0; else if ((fd_in = open(opt_input, O_RDONLY | O_BINARY)) < 0) @@ -2790,6 +2800,7 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1024], out_buffer[1024]; CK_MECHANISM mech; CK_RV rv; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_ULONG in_len, out_len; int fd_in, fd_out; ssize_t sz; @@ -2807,7 +2818,14 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; + if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) + util_fatal("The hash-algorithm is applicable only to " + "RSA-PKCS-OAEP mechanism"); + switch (opt_mechanism) { + case CKM_RSA_PKCS_OAEP: + build_rsa_oaep_params(&oaep_params, &mech, NULL, 0); + break; case CKM_AES_ECB: mech.pParameter = NULL; mech.ulParameterLen = 0; @@ -7509,8 +7527,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, CK_ULONG encrypted_len, data_len; int failed; CK_RV rv; - int pad; - CK_MECHANISM_TYPE hash_alg = CKM_SHA256; + int pad; CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256; CK_RSA_PKCS_OAEP_PARAMS oaep_params; @@ -7538,50 +7555,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, max_in_len = mod_len-11; in_len = 10; break; - case CKM_RSA_PKCS_OAEP: { - if (opt_hash_alg != 0) { - hash_alg = opt_hash_alg; - } - switch (hash_alg) { - case CKM_SHA_1: - mgf = CKG_MGF1_SHA1; - break; - case CKM_SHA224: - mgf = CKG_MGF1_SHA224; - break; - default: - printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(hash_alg)); - /* fall through */ - case CKM_SHA256: - mgf = CKG_MGF1_SHA256; - break; - case CKM_SHA384: - mgf = CKG_MGF1_SHA384; - break; - case CKM_SHA512: - mgf = CKG_MGF1_SHA512; - break; - case CKM_SHA3_224: - mgf = CKG_MGF1_SHA3_224; - break; - case CKM_SHA3_256: - mgf = CKG_MGF1_SHA3_256; - break; - case CKM_SHA3_384: - mgf = CKG_MGF1_SHA3_384; - break; - case CKM_SHA3_512: - mgf = CKG_MGF1_SHA3_512; - break; - } - if (opt_mgf != 0) { - mgf = opt_mgf; - } else { - printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(mgf)); - } + case CKM_RSA_PKCS_OAEP: + build_rsa_oaep_params(&oaep_params, &mech, param, param_len); pad = RSA_PKCS1_OAEP_PADDING; - size_t len = 2+2*hash_length(hash_alg); + size_t len = 2 + 2 * hash_length(oaep_params.hashAlg); if (len >= mod_len) { printf("Incompatible mechanism and key size\n"); return 0; @@ -7590,7 +7568,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, max_in_len = mod_len-len; in_len = 10; break; - } case CKM_RSA_X_509: pad = RSA_NO_PADDING; /* input length equals modulus length */ @@ -7637,15 +7614,15 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, if (mech_type == CKM_RSA_PKCS_OAEP) { #if OPENSSL_VERSION_NUMBER >= 0x10002000L const EVP_MD *md; - switch (hash_alg) { + switch (oaep_params.hashAlg) { case CKM_SHA_1: md = EVP_sha1(); break; case CKM_SHA224: md = EVP_sha224(); break; - default: /* it should not happen, hash_alg is checked earlier */ - /* fall through */ + default: /* it should not happen, oaep_params.hashAlg is checked earlier */ + /* fall through */ case CKM_SHA256: md = EVP_sha256(); break; @@ -7726,7 +7703,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } } #else - if (hash_alg != CKM_SHA_1) { + if (oaep_params.hashAlg != CKM_SHA_1) { printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n"); return 0; } @@ -7744,34 +7721,8 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, EVP_PKEY_free(pkey); encrypted_len = out_len; - /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (mech_type) { case CKM_RSA_PKCS_OAEP: - oaep_params.hashAlg = hash_alg; - oaep_params.mgf = mgf; - - oaep_params.source = 0UL; /* empty encoding parameter (label) */ - oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */ - oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */ - - fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, ", - p11_mechanism_to_name(oaep_params.hashAlg), - p11_mgf_to_name(oaep_params.mgf)); - - if (param != NULL && param_len > 0) { - oaep_params.source = CKZ_DATA_SPECIFIED; - oaep_params.pSourceData = param; - oaep_params.ulSourceDataLen = param_len; - fprintf(stderr, "encoding parameter (Label) present, length %d\n", param_len); - } else { - fprintf(stderr, "encoding parameter (Label) not present\n"); - } - - mech.pParameter = &oaep_params; - mech.ulParameterLen = sizeof(oaep_params); - - - break; case CKM_RSA_X_509: case CKM_RSA_PKCS: From b8cde78132e718255fc65fd68ec8829fdf3aa791 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Mon, 1 Jul 2024 11:03:22 +0200 Subject: [PATCH 3513/4321] feat(pkcs11-tool): add test for RSA OAEP --- tests/test-pkcs11-tool-sign-verify.sh | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 8f8df6dd3c..472943de23 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -113,6 +113,48 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do rm data.{sig,hash} done + METHOD="RSA-PKCS-OAEP" + # RSA-PKCS-OAEP works only on small data (input length <= k-2-2hLen) + # generate small data: + head -c 64 data + for ENC_KEY in "01" "02"; do + # SoftHSM only supports SHA1 for both hashAlg and mgf + if [[ -z $HASH ]]; then + continue + elif [[ "$HASH" != "SHA1" ]]; then + continue + fi + echo + echo "=======================================================" + echo "$METHOD: Encrypt & Decrypt (KEY $ENC_KEY)" + echo "=======================================================" + # OpenSSL Encryption + # pkeyutl does not work with libressl + openssl rsautl -encrypt -oaep -inkey $ENC_KEY.pub -in data -pubin -out data.crypt + assert $? "Failed to encrypt data using OpenSSL" + $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data.crypt --output-file data.decrypted + assert $? "Failed to decrypt data using pkcs11-tool" + diff data{,.decrypted} + assert $? "The decrypted data do not match the original" + rm data.{crypt,decrypted} + + $PKCS11_TOOL --id $ENC_KEY --encrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data --output-file data.crypt + assert $? "Failed to encrypt data using pkcs11-tool" + # It would be better to decrypt with OpenSSL but we can't read the + # private key with the pkcs11-tool (yet) + $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data.crypt --output-file data.decrypted + assert $? "Failed to decrypt data using pkcs11-tool" + diff data{,.decrypted} + assert $? "The decrypted data do not match the original" + rm data.{crypt,decrypted} + done + # Skip hashed algorithms (do not support encryption & decryption) if [[ ! -z "$HASH" ]]; then continue; From f4315c17bec5724a5b00d2f37bd7aaee0bcd598d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 16 Jul 2024 15:51:08 +0200 Subject: [PATCH 3514/4321] p11test: Generate keys with derive flags --- src/tests/p11test/runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index c0aa7f43d1..12b2d703fc 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -52,7 +52,7 @@ function generate_cert() { # Generate key pair $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --extractable --usage-wrap --usage-sign --usage-decrypt \ + --extractable --usage-wrap --usage-sign --usage-decrypt --usage-derive \ --module="$P11LIB" --label="$LABEL" --id=$ID if [[ "$?" -ne "0" ]]; then From 7099f4e34760de89ab3a36c9cc3b5a12d60e18a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 16 Jul 2024 15:59:14 +0200 Subject: [PATCH 3515/4321] pkcs11-tool: Avoid dead code Fixups #3175 ** CID 440022: (DEADCODE) Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d9a6af5567..611cd54003 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7528,7 +7528,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, int failed; CK_RV rv; int pad; - CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256; CK_RSA_PKCS_OAEP_PARAMS oaep_params; printf(" %s: ", p11_mechanism_to_name(mech_type)); @@ -7651,17 +7650,13 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, printf("set md failed, returning\n"); return 0; } - switch (mgf) { + switch (oaep_params.mgf) { case CKG_MGF1_SHA1: md = EVP_sha1(); break; case CKG_MGF1_SHA224: md = EVP_sha224(); break; - default: - printf("mgf %s unknown, defaulting to CKG_MGF1_SHA256\n", p11_mgf_to_name(mgf)); - mgf = CKG_MGF1_SHA256; - /* fall through */ case CKG_MGF1_SHA256: md = EVP_sha256(); break; From 83d56e2cc40ac531312ad004e0e7db7b25cbbc2e Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Mon, 24 Jun 2024 12:19:17 +0200 Subject: [PATCH 3516/4321] Introduce SC_CARDCTL_GET_MODEL Card model can now alternatively be set by card driver via the sc_card_ctl() SC_CARDCTL_GET_MODEL call and not just via the configuration file --- src/libopensc/card-eoi.c | 22 ++++++++++++++++++++++ src/libopensc/cardctl.h | 1 + src/pkcs11/framework-pkcs15.c | 2 ++ 3 files changed, 25 insertions(+) diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index 37f323eb94..0a8144f9cc 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -45,6 +45,8 @@ static struct { {384, {{1, 3, 132, 0, 34, -1}}} }; +static char *eoi_model = "ChipDocLite"; + /* The description of the driver. */ static struct sc_card_driver eoi_drv = { @@ -417,6 +419,25 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->pin_cmd(card, data, tries_left)); } +static int +eoi_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) +{ + int r = SC_SUCCESS; + + LOG_FUNC_CALLED(card->ctx); + switch (cmd) { + case SC_CARDCTL_GET_MODEL: + if (!ptr) + r = SC_ERROR_INVALID_ARGUMENTS; + else + *(char **)ptr = eoi_model; + break; + default: + r = sc_get_iso7816_driver()->ops->card_ctl(card, cmd, ptr); + } + LOG_FUNC_RETURN(card->ctx, r); +} + #define ALREADY_PROCESSED 0x80000000 static int eoi_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) @@ -545,6 +566,7 @@ struct sc_card_driver *sc_get_eoi_driver(void) eoi_ops.select_file = eoi_select_file; eoi_ops.logout = eoi_logout; eoi_ops.pin_cmd = eoi_pin_cmd; + eoi_ops.card_ctl = eoi_card_ctl; eoi_ops.set_security_env = eoi_set_security_env; eoi_ops.compute_signature = eoi_compute_signature; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 34f88c9da8..7b01b9ca9a 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -46,6 +46,7 @@ enum { SC_CARDCTL_GET_CHV_REFERENCE_IN_SE, SC_CARDCTL_PKCS11_INIT_TOKEN, SC_CARDCTL_PKCS11_INIT_PIN, + SC_CARDCTL_GET_MODEL, /* * Cryptoflex specific calls diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index dff50f6716..763165d867 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -415,6 +415,8 @@ pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken) if (model) strcpy_bp(pToken->model, model, sizeof(pToken->model)); + else if (sc_card_ctl(p15card->card, SC_CARDCTL_GET_MODEL, &model) == SC_SUCCESS) + strcpy_bp(pToken->model, model, sizeof(pToken->model)); else if (p15card->flags & SC_PKCS15_CARD_FLAG_EMULATED) strcpy_bp(pToken->model, "PKCS#15 emulated", sizeof(pToken->model)); else From f6679a8dbab79d59d38e2cdd70a247c43157b507 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 25 Jun 2024 14:02:32 +0200 Subject: [PATCH 3517/4321] feat(pkcs11-tool): --usage-derive is also for secret keys --- src/tools/pkcs11-tool.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 611cd54003..11b97079c9 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3448,6 +3448,14 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey n_attr++; } + if (opt_key_usage_derive != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_DERIVE, &_true, sizeof(_true)); + n_attr++; + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_DERIVE, &_false, sizeof(_false)); + n_attr++; + } + FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); n_attr++; @@ -4594,6 +4602,14 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_seckey_attr++; } + if (opt_key_usage_derive != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_DERIVE, &_true, sizeof(_true)); + n_seckey_attr++; + } else { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_DERIVE, &_false, sizeof(_false)); + n_seckey_attr++; + } + if (opt_object_label != NULL) { FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); n_seckey_attr++; From 0a85287a613f48dcc7347e12b34d30e4944a3402 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 25 Jun 2024 14:24:31 +0200 Subject: [PATCH 3518/4321] feat(pkcs11-tool): secret keys can also be used for derivation --- src/tools/pkcs11-tool.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 11b97079c9..bce71afea8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1382,9 +1382,10 @@ int main(int argc, char * argv[]) opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0); } else if (!find_object(session, CKO_PRIVATE_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0)) - util_fatal("Private key not found"); + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + util_fatal("Private/secret key not found"); } if (do_decrypt) { From 294def08102dcbced01510ff69bc7646e8783952 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Mon, 1 Jul 2024 11:54:59 +0200 Subject: [PATCH 3519/4321] feat(pkcs11-tool): add support for HKDF --- src/pkcs11/pkcs11.h | 21 +++- src/tools/pkcs11-tool.c | 206 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 221 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 288cf6e0cb..09c0ca39fc 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -372,6 +372,7 @@ typedef unsigned long ck_key_type_t; #define CKK_GOST28147 (0x32UL) #define CKK_EC_EDWARDS (0x40UL) #define CKK_EC_MONTGOMERY (0x41UL) +#define CKK_HKDF (0x42UL) #define CKK_VENDOR_DEFINED (1UL << 31) /* @@ -813,7 +814,9 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_KEY_WRAP (0x2109UL) #define CKM_AES_KEY_WRAP_PAD (0x210AUL) #define CKM_XEDDSA (0x4029UL) - +#define CKM_HKDF_DERIVE (0x402AUL) +#define CKM_HKDF_DATA (0x402BUL) +#define CKM_HKDF_KEY_GEN (0x402CUL) #define CKM_VENDOR_DEFINED (1UL << 31) @@ -1726,6 +1729,22 @@ typedef void **CK_VOID_PTR_PTR; #endif #endif +typedef struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; +} CK_HKDF_PARAMS; + +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bce71afea8..0ee1e4764a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -20,12 +20,13 @@ #include "config.h" +#include #include #include -#include +#include #include +#include #include -#include #ifndef _WIN32 #include @@ -215,7 +216,9 @@ enum { OPT_IV, OPT_MAC_GEN_PARAM, OPT_AAD, - OPT_TAG_BITS + OPT_TAG_BITS, + OPT_SALT_FILE, + OPT_INFO_FILE }; // clang-format off @@ -306,6 +309,8 @@ static const struct option options[] = { { "mac-general-param", 1, NULL, OPT_MAC_GEN_PARAM}, { "aad", 1, NULL, OPT_AAD }, { "tag-bits-len", 1, NULL, OPT_TAG_BITS}, + { "salt-file", 1, NULL, OPT_SALT_FILE}, + { "info-file", 1, NULL, OPT_INFO_FILE}, { NULL, 0, NULL, 0 } }; @@ -398,6 +403,8 @@ static const char *option_help[] = { "Specify the value of the mechanism parameter CK_MAC_GENERAL_PARAMS", "Specify additional authenticated data for AEAD ciphers as a hex string", "Specify the required length (in bits) for the authentication tag for AEAD ciphers", + "Specify the file containing the salt for HKDF (optional)", + "Specify the file containing the info for HKDF (optional)", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -460,6 +467,8 @@ static const char * opt_iv = NULL; static unsigned long opt_mac_gen_param = 0; static const char *opt_aad = NULL; static unsigned long opt_tag_bits = 0; +static const char *opt_salt_file = NULL; +static const char *opt_info_file = NULL; static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -1182,6 +1191,12 @@ int main(int argc, char * argv[]) case OPT_IV: opt_iv = optarg; break; + case OPT_SALT_FILE: + opt_salt_file = optarg; + break; + case OPT_INFO_FILE: + opt_info_file = optarg; + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -3399,7 +3414,25 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; } - else { + + else if (strncasecmp(type, "HKDF:", strlen("HKDF:")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_HKDF_KEY_GEN}; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); + const char *size = type + strlen("HKDF:"); + + key_type = CKK_HKDF; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate Key mechanism not supported\n"); + + key_length = (unsigned long)atol(size); + if (key_length == 0) + util_fatal("Unknown key type %s, expecting HKDF:", type); + + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + n_attr++; + } else { util_fatal("Unknown key type %s", type); } @@ -3562,7 +3595,9 @@ unwrap_key(CK_SESSION_HANDLE session) } else if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) == 0) { length = opt_key_type + strlen("GENERIC:"); key_type = CKK_GENERIC_SECRET; - + } else if (strncasecmp(opt_key_type, "HKDF:", strlen("HKDF:")) == 0) { + length = opt_key_type + strlen("HKDF:"); + key_type = CKK_HKDF; } else { util_fatal("Unsupported key type %s", opt_key_type); } @@ -4546,6 +4581,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) type = CKK_DES3; else if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) == 0) type = CKK_GENERIC_SECRET; + else if (strncasecmp(opt_key_type, "HKDF:", strlen("HKDF:")) == 0) + type = CKK_HKDF; else util_fatal("Unknown key type: 0x%lX", type); } @@ -5168,6 +5205,156 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #endif /* ENABLE_OPENSSL && !OPENSSL_NO_EC && !OPENSSL_NO_ECDSA */ } +static CK_BBOOL s_true = TRUE; +static CK_BBOOL s_false = FALSE; + +static void +fill_attributes_seckey(CK_ATTRIBUTE *template, int *n_attrs, int max_attrs) +{ + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_PRIVATE, opt_is_private ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_SENSITIVE, opt_is_sensitive ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_EXTRACTABLE, opt_is_extractable ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + if (opt_key_usage_default || opt_key_usage_decrypt) { + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_ENCRYPT, &s_true, sizeof(CK_BBOOL)); + (*n_attrs)++; + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_DECRYPT, &s_true, sizeof(CK_BBOOL)); + (*n_attrs)++; + } + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_WRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_UNWRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_SIGN, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_VERIFY, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; + + assert(*n_attrs < max_attrs); + FILL_ATTR(template[*n_attrs], CKA_DERIVE, opt_key_usage_derive ? &s_true : &s_false, sizeof(CK_BBOOL)); + (*n_attrs)++; +} + +static CK_OBJECT_HANDLE +derive_hkdf(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) +{ + CK_MECHANISM mech; + CK_KEY_TYPE key_type = CKK_GENERIC_SECRET; + CK_ULONG key_length = hash_length(opt_hash_alg); + CK_OBJECT_HANDLE newkey = 0; + CK_ATTRIBUTE template[13] = { + {CKA_TOKEN, &s_false, sizeof(s_false) }, /* session only object */ + {CKA_KEY_TYPE, &key_type, sizeof(key_type) }, + {CKA_VALUE_LEN, &key_length, sizeof(key_length)} + }; + int n_attrs = 3; + CK_RV rv; + CK_HKDF_PARAMS hkdf_params; + void *salt = NULL; + ssize_t salt_len = 0; + void *info = NULL; + ssize_t info_len = 0; + + if (opt_key_type != NULL) { + if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) != 0) { + util_fatal("Generic key type expected\n"); + } + const char *size = opt_key_type + strlen("GENERIC:"); + key_length = (unsigned long)atol(size); + if (key_length == 0) + util_fatal("Unknown key type %s, expecting GENERIC:", opt_key_type); + } + + fill_attributes_seckey(template, &n_attrs, ARRAY_SIZE(template)); + + if (opt_salt_file != NULL) { + FILE *f; + + f = fopen(opt_salt_file, "rb"); + if (f == NULL) + util_fatal("Cannot open %s: %m", opt_salt_file); + if (fseek(f, 0L, SEEK_END) != 0) + util_fatal("Couldn't set file position to the end of the file \"%s\"", opt_salt_file); + salt_len = ftell(f); + if (salt_len < 0) + util_fatal("Couldn't get file position \"%s\"", opt_salt_file); + salt = malloc(salt_len); + if (salt == NULL) + util_fatal("malloc() failure\n"); + if (fseek(f, 0L, SEEK_SET) != 0) + util_fatal("Couldn't set file position to the beginning of the file \"%s\"", opt_salt_file); + size_t ret = fread(salt, 1, salt_len, f); + if (ret != (size_t)salt_len) + util_fatal("Couldn't read from file \"%s\"", opt_salt_file); + fclose(f); + } + if (opt_info_file != NULL) { + FILE *f; + + f = fopen(opt_info_file, "rb"); + if (f == NULL) + util_fatal("Cannot open %s: %m", opt_info_file); + if (fseek(f, 0L, SEEK_END) != 0) + util_fatal("Couldn't set file position to the end of the file \"%s\"", opt_info_file); + info_len = ftell(f); + if (info_len < 0) + util_fatal("Couldn't get file position \"%s\"", opt_info_file); + info = malloc(info_len); + if (info == NULL) + util_fatal("malloc() failure\n"); + if (fseek(f, 0L, SEEK_SET) != 0) + util_fatal("Couldn't set file position to the beginning of the file \"%s\"", opt_info_file); + size_t ret = fread(info, 1, info_len, f); + if (ret != (size_t)info_len) + util_fatal("Couldn't read from file \"%s\"", opt_info_file); + fclose(f); + } + + memset(&hkdf_params, 0, sizeof(hkdf_params)); + hkdf_params.bExtract = TRUE; + hkdf_params.bExpand = TRUE; + hkdf_params.prfHashMechanism = opt_hash_alg; + if (salt == NULL) { + hkdf_params.ulSaltType = CKF_HKDF_SALT_NULL; + } else { + hkdf_params.ulSaltType = CKF_HKDF_SALT_DATA; + } + hkdf_params.pSalt = salt; + hkdf_params.ulSaltLen = (CK_ULONG)salt_len; + hkdf_params.hSaltKey = CK_INVALID_HANDLE; + hkdf_params.pInfo = info; + hkdf_params.ulInfoLen = (CK_ULONG)info_len; + + mech.mechanism = CKM_HKDF_DERIVE; + mech.pParameter = &hkdf_params; + mech.ulParameterLen = sizeof(hkdf_params); + + rv = p11->C_DeriveKey(session, &mech, key, template, n_attrs, &newkey); + if (rv != CKR_OK) + p11_fatal("C_DeriveKey", rv); + + free(salt); + free(info); + return newkey; +} static void derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) @@ -5187,6 +5374,9 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) case CKM_ECDH1_DERIVE: derived_key= derive_ec_key(session, key, opt_mechanism); break; + case CKM_HKDF_DERIVE: + derived_key = derive_hkdf(session, key); + break; default: util_fatal("mechanism not supported for derive"); break; @@ -5381,12 +5571,15 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) case CKK_AES: case CKK_DES: case CKK_DES3: + case CKK_HKDF: if (key_type == CKK_AES) printf("; AES"); else if (key_type == CKK_DES) printf("; DES"); else if (key_type == CKK_DES3) printf("; DES3"); + else if (key_type == CKK_HKDF) + printf("; HKDF"); else printf("; Generic secret"); size = getVALUE_LEN(sess, obj); @@ -8717,6 +8910,9 @@ static struct mech_info p11_mechanisms[] = { { CKM_IDEA_MAC_GENERAL, "IDEA-MAC-GENERAL", NULL, MF_UNKNOWN }, { CKM_IDEA_CBC_PAD, "IDEA-CBC-PAD", NULL, MF_UNKNOWN }, { CKM_GENERIC_SECRET_KEY_GEN,"GENERIC-SECRET-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_HKDF_KEY_GEN, "HKDF-KEY-GEN", NULL, MF_UNKNOWN }, + { CKM_HKDF_DATA, "HKDF-DATA", NULL, MF_UNKNOWN }, + { CKM_HKDF_DERIVE, "HKDF-DERIVE", NULL, MF_UNKNOWN }, { CKM_CONCATENATE_BASE_AND_KEY,"CONCATENATE-BASE-AND-KEY", NULL, MF_UNKNOWN }, { CKM_CONCATENATE_BASE_AND_DATA,"CONCATENATE-BASE-AND-DATA", NULL, MF_UNKNOWN }, { CKM_CONCATENATE_DATA_AND_BASE,"CONCATENATE-DATA-AND-BASE", NULL, MF_UNKNOWN }, From 2c85144b0ff962524441f76131c1ffb12a35e0b0 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 16 Jul 2024 10:08:53 +0200 Subject: [PATCH 3520/4321] feat(pkcs11-tool): add new macro FILL_ATTR_EX --- src/tools/pkcs11-tool.c | 58 +++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0ee1e4764a..5c4612b8e7 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -20,7 +20,6 @@ #include "config.h" -#include #include #include #include @@ -5208,49 +5207,34 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE static CK_BBOOL s_true = TRUE; static CK_BBOOL s_false = FALSE; +#define FILL_ATTR_EX(attr, index, max, typ, val, len) \ + { \ + if (*(index) >= max) { \ + util_fatal("Template is too small"); \ + } \ + (attr)[*(index)].type = (typ); \ + (attr)[*(index)].pValue = (val); \ + (attr)[*(index)].ulValueLen = (len); \ + (*(index))++; \ + } + static void fill_attributes_seckey(CK_ATTRIBUTE *template, int *n_attrs, int max_attrs) { - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_PRIVATE, opt_is_private ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_SENSITIVE, opt_is_sensitive ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_EXTRACTABLE, opt_is_extractable ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_PRIVATE, opt_is_private ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_SENSITIVE, opt_is_sensitive ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_EXTRACTABLE, opt_is_extractable ? &s_true : &s_false, sizeof(CK_BBOOL)); if (opt_key_usage_default || opt_key_usage_decrypt) { - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_ENCRYPT, &s_true, sizeof(CK_BBOOL)); - (*n_attrs)++; - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_DECRYPT, &s_true, sizeof(CK_BBOOL)); - (*n_attrs)++; + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_ENCRYPT, &s_true, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_DECRYPT, &s_true, sizeof(CK_BBOOL)); } - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_WRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_UNWRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_SIGN, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_VERIFY, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; - - assert(*n_attrs < max_attrs); - FILL_ATTR(template[*n_attrs], CKA_DERIVE, opt_key_usage_derive ? &s_true : &s_false, sizeof(CK_BBOOL)); - (*n_attrs)++; + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_WRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_UNWRAP, opt_key_usage_wrap ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_SIGN, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_VERIFY, opt_key_usage_sign ? &s_true : &s_false, sizeof(CK_BBOOL)); + FILL_ATTR_EX(template, n_attrs, max_attrs, CKA_DERIVE, opt_key_usage_derive ? &s_true : &s_false, sizeof(CK_BBOOL)); } static CK_OBJECT_HANDLE From 947211ed0dd45c8ce10fb20b98951e12e33aee4e Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 16 Jul 2024 10:52:33 +0200 Subject: [PATCH 3521/4321] doc(pkcs11-tool): add new CLI switches --- doc/tools/pkcs11-tool.1.xml | 14 ++++++++++++++ doc/tools/tools.html | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index d758649ad2..9737131445 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -727,6 +727,20 @@ + + + filename + + Specify the file containing the salt for HKDF (optional) + + + + + filename + + Specify the file containing the info for HKDF (optional) + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 2ca4c60bed..a4e96bfc58 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1726,7 +1726,11 @@ --tag-bits-len num

    Sets the length of the tag for AEAD ciphers to num bits. -

    +

    + --salt-file filename +

    Specify the file containing the salt for HKDF (optional)

    + --info-file filename +

    Specify the file containing the info for HKDF (optional)

    Examples

    Perform a basic functionality test of the card:

    pkcs11-tool --test --login

    From 338eb8b957951d3255f220a97cc1ff10b75a40a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Fri, 5 Jul 2024 10:57:47 +0200 Subject: [PATCH 3522/4321] dev(pkcs11-tool): add support for CKM_AES_GCM key wrapping --- src/tools/pkcs11-tool.c | 47 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5c4612b8e7..9538ec34f9 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3548,8 +3548,11 @@ unwrap_key(CK_SESSION_HANDLE session) unsigned char in_buffer[1024]; CK_ULONG wrapped_key_length; CK_BYTE_PTR pWrappedKey; + CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; + CK_BYTE_PTR aad = NULL; + size_t aad_size = 0; CK_OBJECT_HANDLE hUnwrappingKey; ssize_t sz; @@ -3579,11 +3582,28 @@ unwrap_key(CK_SESSION_HANDLE session) close(fd); pWrappedKey = in_buffer; - if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { + switch (opt_mechanism) { + case CKM_AES_CBC: + case CKM_AES_CBC_PAD: iv_size = 16; iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mechanism.pParameter = iv; mechanism.ulParameterLen = iv_size; + break; + case CKM_AES_GCM: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + gcm_params.pIv = iv; + gcm_params.ulIvLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + gcm_params.pAAD = aad; + gcm_params.ulAADLen = aad_size; + gcm_params.ulTagBits = opt_tag_bits; + mechanism.pParameter = &gcm_params; + mechanism.ulParameterLen = sizeof(gcm_params); + break; + default: + // Nothing to do with other mechanisms. + break; } if (opt_key_type != NULL) { @@ -3665,6 +3685,7 @@ unwrap_key(CK_SESSION_HANDLE session) p11_fatal("C_UnwrapKey", rv); free(iv); + free(aad); printf("Key unwrapped\n"); show_object(session, hSecretKey); return 1; @@ -3683,8 +3704,11 @@ wrap_key(CK_SESSION_HANDLE session) size_t hkey_id_len; int fd; ssize_t sz; + CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; + CK_BYTE_PTR aad = NULL; + size_t aad_size = 0; if (NULL == opt_application_id) util_fatal("Use --application-id to specify secret key (to be wrapped)"); @@ -3694,11 +3718,29 @@ wrap_key(CK_SESSION_HANDLE session) mechanism.mechanism = opt_mechanism; mechanism.pParameter = NULL_PTR; mechanism.ulParameterLen = 0; - if (opt_mechanism == CKM_AES_CBC || opt_mechanism == CKM_AES_CBC_PAD) { + + switch (opt_mechanism) { + case CKM_AES_CBC: + case CKM_AES_CBC_PAD: iv_size = 16; iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); mechanism.pParameter = iv; mechanism.ulParameterLen = iv_size; + break; + case CKM_AES_GCM: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + gcm_params.pIv = iv; + gcm_params.ulIvLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + gcm_params.pAAD = aad; + gcm_params.ulAADLen = aad_size; + gcm_params.ulTagBits = opt_tag_bits; + mechanism.pParameter = &gcm_params; + mechanism.ulParameterLen = sizeof(gcm_params); + break; + default: + // Nothing to do with other mechanisms. + break; } hkey_id_len = sizeof(hkey_id); @@ -3731,6 +3773,7 @@ wrap_key(CK_SESSION_HANDLE session) if (fd != 1) close(fd); free(iv); + free(aad); return 1; } From 5a260cc109a4dc8724393fb7b2c56dd213d9e1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Fri, 5 Jul 2024 10:58:38 +0200 Subject: [PATCH 3523/4321] dev(pkcs11-tool): Add CKM_AES_KEY_WRAP_PAD in supported mechanisms --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9538ec34f9..43e8aa966a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -9060,6 +9060,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL, MF_UNKNOWN }, { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL, MF_UNKNOWN }, { CKM_AES_KEY_WRAP, "AES-KEY-WRAP", NULL, MF_UNKNOWN }, + { CKM_AES_KEY_WRAP_PAD, "AES-KEY-WRAP-PAD", NULL, MF_UNKNOWN}, { 0, NULL, NULL, MF_UNKNOWN }, }; From e4a4046ec818b00e2427bfc49ff40eed6daf7a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Fri, 5 Jul 2024 15:23:47 +0200 Subject: [PATCH 3524/4321] dev(pkcs11-tool): Add support for private key wrapping --- src/tools/pkcs11-tool.c | 118 +++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 43e8aa966a..bd27cc3a5a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -351,7 +351,7 @@ static const char *option_help[] = { "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", "Key pair generation", "Key generation", - "Specify the type and length (bytes if symmetric) of the key to create, for example rsa:1024, EC:prime256v1, EC:ed25519, EC:curve25519, GOSTR3410-2012-256:B, AES:16 or GENERIC:64", + "Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, DES:8, DES3:24, AES:16, AES: or GENERIC:64", "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", "Specify 'derive' key usage flag (EC only)", @@ -3529,15 +3529,15 @@ static int unwrap_key(CK_SESSION_HANDLE session) { CK_MECHANISM mechanism; - CK_OBJECT_CLASS secret_key_class = CKO_SECRET_KEY; + CK_OBJECT_CLASS class = CKO_SECRET_KEY; CK_BBOOL _true = TRUE; CK_BBOOL _false = FALSE; CK_KEY_TYPE key_type = CKK_AES; CK_ULONG key_length; const char *length; CK_ATTRIBUTE keyTemplate[20] = { - {CKA_CLASS, &secret_key_class, sizeof(secret_key_class)}, - {CKA_TOKEN, &_true, sizeof(_true)}, + {CKA_CLASS, &class, sizeof(class)}, + {CKA_TOKEN, &_true, sizeof(_true)}, }; CK_BYTE object_id[100]; size_t id_len; @@ -3545,7 +3545,7 @@ unwrap_key(CK_SESSION_HANDLE session) int n_attr = 2; CK_RV rv; int fd; - unsigned char in_buffer[1024]; + unsigned char in_buffer[2048]; CK_ULONG wrapped_key_length; CK_BYTE_PTR pWrappedKey; CK_GCM_PARAMS gcm_params = {0}; @@ -3606,59 +3606,78 @@ unwrap_key(CK_SESSION_HANDLE session) break; } - if (opt_key_type != NULL) { - if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0) { - length = opt_key_type + strlen("AES:"); - key_type = CKK_AES; - - } else if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) == 0) { - length = opt_key_type + strlen("GENERIC:"); - key_type = CKK_GENERIC_SECRET; - } else if (strncasecmp(opt_key_type, "HKDF:", strlen("HKDF:")) == 0) { - length = opt_key_type + strlen("HKDF:"); - key_type = CKK_HKDF; - } else { - util_fatal("Unsupported key type %s", opt_key_type); - } + if (opt_key_type == NULL) { + util_fatal("Key type must be specified"); + } + + if (strncasecmp(opt_key_type, "AES:", strlen("AES:")) == 0) { + length = opt_key_type + strlen("AES:"); + } else if (strncasecmp(opt_key_type, "GENERIC:", strlen("GENERIC:")) == 0) { + length = opt_key_type + strlen("GENERIC:"); + key_type = CKK_GENERIC_SECRET; + } else if (strncasecmp(opt_key_type, "HKDF:", strlen("HKDF:")) == 0) { + length = opt_key_type + strlen("HKDF:"); + key_type = CKK_HKDF; + } else if (strncasecmp(opt_key_type, "RSA:", strlen("RSA:")) == 0) { + length = "0"; // No key length for RSA keys + key_type = CKK_RSA; + class = CKO_PRIVATE_KEY; + } else if (strncasecmp(opt_key_type, "EC:", strlen("EC:")) == 0) { + length = "0"; // No key length for EC keys + key_type = CKK_EC; + class = CKO_PRIVATE_KEY; + } else { + util_fatal("Unsupported key type %s", opt_key_type); + } - FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); - n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + n_attr++; - if (opt_is_sensitive != 0) { - FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); - n_attr++; - } else { - FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); - n_attr++; - } + if (opt_is_sensitive != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_true, sizeof(_true)); + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_SENSITIVE, &_false, sizeof(_false)); + } + n_attr++; - if (opt_key_usage_default || opt_key_usage_decrypt) { + if (opt_key_usage_default || opt_key_usage_decrypt) { + if (class != CKO_PRIVATE_KEY) { FILL_ATTR(keyTemplate[n_attr], CKA_ENCRYPT, &_true, sizeof(_true)); n_attr++; - FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); - n_attr++; } - if (opt_key_usage_wrap) { + FILL_ATTR(keyTemplate[n_attr], CKA_DECRYPT, &_true, sizeof(_true)); + n_attr++; + } + if (opt_key_usage_wrap) { + if (class != CKO_PRIVATE_KEY) { FILL_ATTR(keyTemplate[n_attr], CKA_WRAP, &_true, sizeof(_true)); n_attr++; - FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true)); - n_attr++; - } - - if (opt_is_extractable != 0) { - FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); - n_attr++; - } else { - FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_false, sizeof(_true)); - n_attr++; } - /* softhsm2 does not allow to attribute CKA_VALUE_LEN, but MyEID card must have this attribute - specified. We set CKA_VALUE_LEN only if the user sets it in the key specification. */ - key_length = (unsigned long)atol(length); - if (key_length != 0) { - FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); + FILL_ATTR(keyTemplate[n_attr], CKA_UNWRAP, &_true, sizeof(_true)); + n_attr++; + } + if (opt_key_usage_sign) { + if (class != CKO_PRIVATE_KEY) { + FILL_ATTR(keyTemplate[n_attr], CKA_VERIFY, &_true, sizeof(_true)); n_attr++; } + FILL_ATTR(keyTemplate[n_attr], CKA_SIGN, &_true, sizeof(_true)); + n_attr++; + } + + if (opt_is_extractable != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_true, sizeof(_true)); + } else { + FILL_ATTR(keyTemplate[n_attr], CKA_EXTRACTABLE, &_false, sizeof(_false)); + } + n_attr++; + + /* softhsm2 does not allow to attribute CKA_VALUE_LEN, but MyEID card must have this attribute + specified. We set CKA_VALUE_LEN only if the user sets it in the key specification. */ + key_length = (unsigned long)atol(length); + if (key_length != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); + n_attr++; } if (opt_application_label != NULL) { @@ -3748,13 +3767,14 @@ wrap_key(CK_SESSION_HANDLE session) util_fatal("Invalid application-id \"%s\"\n", opt_application_id); if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, 0)) - util_fatal("Secret key (to be wrapped) not found"); + if (!find_object(session, CKO_PRIVATE_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, 0)) + util_fatal("Key to be wrapped not found"); if (!find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) if (!find_object(session, CKO_SECRET_KEY, &hWrappingKey, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) - util_fatal("Public/secret key (wrapping key) not found"); + util_fatal("Wrapping key not found"); rv = p11->C_WrapKey(session, &mechanism, hWrappingKey, hkey, pWrappedKey, &pulWrappedKeyLen); if (rv != CKR_OK) From 6186ab04f3b85788147fb90c4beb86ff5477fbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Tue, 9 Jul 2024 10:31:49 +0200 Subject: [PATCH 3525/4321] doc(pkcs11-tool): Clarify --key-type cli switch documentation --- doc/tools/pkcs11-tool.1.xml | 6 +++--- doc/tools/tools.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 9737131445..9a04a861ad 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -146,9 +146,9 @@ specification - Specify the type and length (bytes if symmetric) of the key to create, - for example RSA:1024, EC:prime256v1, GOSTR3410-2012-256:B, - DES:8, DES3:24, AES:16 or GENERIC:64. If the key type was incompletely specified, possible values are listed. + Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, + elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, + DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed. diff --git a/doc/tools/tools.html b/doc/tools/tools.html index a4e96bfc58..ee62ac381d 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1489,9 +1489,9 @@ --keygen

    Generate a new key.

    --key-type specification -

    Specify the type and length (bytes if symmetric) of the key to create, - for example RSA:1024, EC:prime256v1, GOSTR3410-2012-256:B, - DES:8, DES3:24, AES:16 or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    +

    Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, + elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, + DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    --usage-sign

    Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

    --usage-decrypt From bec3e2e29c88ee72debf007424e86ff618ccd0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Thura?= Date: Tue, 9 Jul 2024 10:32:04 +0200 Subject: [PATCH 3526/4321] tst(pkcs11-tool): Add key wrapping tests --- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 177 +++++++++++++++++++-- 1 file changed, 162 insertions(+), 15 deletions(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index a785bb7aac..0072d0406a 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -12,17 +12,19 @@ fi grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 softhsm_initialize +PKCS11_TOOL_W_PIN="$PKCS11_TOOL --module $P11LIB --pin $PIN" + echo "=======================================================" -echo " Unwrap test" +echo " RSA-PKCS Unwrap test" echo "=======================================================" ID1="85" ID2="95" ID3="96" # Generate RSA key (this key is used to unwrap/wrap operation) -$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --keypairgen --key-type="rsa:1024" --id "$ID1" --usage-wrap +$PKCS11_TOOL_W_PIN --keypairgen --key-type rsa:1024 --id $ID1 --usage-wrap assert $? "Failed to Generate RSA key" # export public key -$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --read-object --type pubkey --id="$ID1" -o rsa_pub.key +$PKCS11_TOOL_W_PIN --read-object --type pubkey --id $ID1 -o rsa_pub.key assert $? "Failed to export public key" # create AES key @@ -34,18 +36,18 @@ openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes_plain_key assert $? "Failed wrap AES key" # unwrap key by pkcs11 interface -$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --unwrap --mechanism RSA-PKCS --id "$ID1" -i aes_wrapped_key --key-type GENERIC: \ - --extractable --application-id "$ID3" --application-label "unwrap-generic-ex" 2>/dev/null +$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ + --extractable --application-id $ID3 --application-label "unwrap-generic-ex" 2>/dev/null assert $? "Unwrap failed" # because key is extractable, there is no problem to compare key value with original key -$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --id "$ID3" --read-object --type secrkey --output-file generic_extracted_key +$PKCS11_TOOL_W_PIN --id $ID3 --read-object --type secrkey --output-file generic_extracted_key assert $? "unable to read key value" cmp generic_extracted_key aes_plain_key >/dev/null 2>/dev/null assert $? "extracted key does not match the input key" # unwrap AES key, not extractable -$PKCS11_TOOL --module="$P11LIB" --login --pin=$PIN --unwrap --mechanism RSA-PKCS --id "$ID1" -i aes_wrapped_key --key-type AES: \ - --application-id "$ID2" --application-label "unwrap-aes" 2>/dev/null +$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type AES: \ + --application-id $ID2 --application-label "unwrap-aes" 2>/dev/null assert $? "Unwrap failed" # To check if AES key was correctly unwrapped (non extractable), we need to encrypt some data by pkcs11 interface and by openssl @@ -53,31 +55,176 @@ assert $? "Unwrap failed" VECTOR="00000000000000000000000000000000" echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data -openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K $KEY +openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY assert $? "Fail/Openssl" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +$PKCS11_TOOL_W_PIN --encrypt --id $ID2 -m AES-CBC --iv $VECTOR \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong encrypt" echo "=======================================================" -echo " Wrap test" +echo " RSA-PKCS Wrap test" echo "=======================================================" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --wrap --mechanism RSA-PKCS --id "$ID1" --application-id "$ID3" --output-file wrapped.key +$PKCS11_TOOL_W_PIN --wrap -m RSA-PKCS --id $ID1 --application-id $ID3 --output-file wrapped.key assert $? "Fail, unable to wrap" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --mechanism RSA-PKCS --id "$ID1" --input-file wrapped.key --output-file plain_wrapped.key +$PKCS11_TOOL_W_PIN --decrypt -m RSA-PKCS --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key assert $? "Fail, unable to decrypt wrapped key" cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null assert $? "wrapped key after decipher does not match the original key" echo "=======================================================" -echo "Cleanup" +echo " RSA-PKCS Cleanup" echo "=======================================================" -softhsm_cleanup rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wrapped.key plain_wrapped.key +echo "=======================================================" +echo " AES wrap/unwrap" +echo "=======================================================" + +ID_RSA=$(echo "RSA" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") +ID_AES=$(echo "AES" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") +ID_KEK=$(echo "KEK" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") +ID_UNWRAPPED=$(echo "UW" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") + +openssl genpkey -algorithm RSA -out rsa_priv.pem +assert $? "OpenSSL / Failed to generate RSA private key" +openssl pkey -in rsa_priv.pem -pubout -out rsa_pub.pem +assert $? "OpenSSL / Failed to convert RSA private key to public" +openssl pkcs8 -topk8 -inform PEM -outform DER -in rsa_priv.pem -out rsa_priv.der -nocrypt +assert $? "OpenSSL / Failed to PKCS8 encode RSA private key" +$PKCS11_TOOL_W_PIN --write-object rsa_priv.pem --id $ID_RSA --type privkey --usage-sign --extractable +assert $? "PKCS11 / Failed to write RSA private key" +$PKCS11_TOOL_W_PIN --write-object rsa_pub.pem --id $ID_RSA --type pubkey --usage-sign +assert $? "PKCS11 / Failed to write RSA public key" + +AES_KEY=$(head /dev/urandom | sha256sum | head -c 64) +echo -n $AES_KEY | xxd -p -r > aes.key +$PKCS11_TOOL_W_PIN --write-object aes.key --id $ID_AES --type secrkey --key-type AES:32 --usage-decrypt --extractable +assert $? "PKCS11 / Failed to write AES key" + +AES_KEK=$(head /dev/urandom | sha256sum | head -c 64) +echo -n $AES_KEK | xxd -p -r > aes_kek.key +$PKCS11_TOOL_W_PIN --write-object aes_kek.key --id $ID_KEK --type secrkey --key-type AES:32 --usage-wrap --extractable +assert $? "PKCS11 / Failed to write AES KEK" + +is_openssl_3=$(openssl version | grep "OpenSSL 3.") +is_softhsm2_2_6_1=$(softhsm2-util -version | grep "2.6.1") + +if [[ -n $is_softhsm2_2_6_1 ]] +then + # CKM_AES_CBC -- SoftHSM2 AES CBC wrapping currently has a bug, the IV is not correctly used. Only IV=0 will work --* + IV="00000000000000000000000000000000" + + # RSA key + # SoftHSM2 does not support wrapping asymmetric keys with AES CBC since the length of the encoded private key is likely not aligned to 16 bytes and SoftHSM2 does not pad the input as intended in the PKCS#11 documentation (PKCS#11 mechanisms v3.0, section 2.10.5) + + # AES Key + openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data -nopad + assert $? "OpenSSL / Failed to AES CBC encrypt AES key" + # Wrapping + $PKCS11_TOOL_W_PIN --wrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES CBC wrap AES key" + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES CBC wrong AES key wrap" + # Unwrapping -- SoftHSM2 currently does not support CKM_AES_CBC unwrapping -- + # $PKCS11_TOOL_W_PIN --unwrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable + # assert $? "PKCS11 / Failed to AES CBC unwrap AES key" + # $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key + # assert $? "PKCS11 / Failed to read unwrapped AES key" + # cmp aes.key unwrapped.key + # assert $? "AES CBC wrong AES key unwrap" + # Cleanup + # $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED + # assert $? "PKCS11 / Failed to delete unwrapped AES key" +fi + +# CKM_AES_CBC_PAD -- SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping mechanism -- +# IV="000102030405060708090A0B0C0D0E0F" + + # RSA key +# $PKCS11_TOOL_W_PIN --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_RSA --output-file pkcs11_wrapped.data +# assert $? "PKCS11 / Failed to AES CBC PAD wrap RSA priv key" +# openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in rsa_priv.der -out openssl_wrapped.data +# assert $? "OpenSSL / Failed to AES CBC encrypt RSA priv key" +# cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null +# assert $? "AES CBC PAD wrong RSA key wrap" + + # AES key +# $PKCS11_TOOL_W_PIN --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data +# assert $? "PKCS11 / Failed to AES CBC PAD wrap AES key" +# openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data +# assert $? "OpenSSL / Failed to AES CBC encrypt AES key" +# cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null +# assert $? "AES CBC PAD wrong AES key wrap" + + +if [[ -n $is_openssl_3 ]] +then + # CKM_AES_KEY_WRAP + IV="a6a6a6a6a6a6a6a6" + + # RSA Key + # --AES-KEY-WRAP is not suitable for asymmetric key wrapping since the length of the encoded private key is likely not aligned to 8 bytes + + # AES Key + openssl enc -id-aes256-wrap -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL / Failed to AES KEY WRAP wrap AES key" + # Wrapping + $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES KEY WRAP wrap AES key" + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES KEY WRAP wrong AES key wrap" + # Unwrapping + $PKCS11_TOOL_W_PIN --unwrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable + assert $? "PKCS11 / Failed to AES KEY WRAP wrap unwrap AES key" + $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key + assert $? "PKCS11 / Failed to read unwrapped AES key" + cmp aes.key unwrapped.key + assert $? "AES KEY WRAP wrong AES key unwrap" + # Cleanup + $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED + assert $? "PKCS11 / Failed to delete unwrapped AES key" + + # CKM_AES_KEY_WRAP_PAD + IV="a65959a6" + + # RSA Key -- Fails with the current version of SoftHSM2 -- + # $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_RSA --output-file pkcs11_wrapped.data + # assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap RSA priv key" + # openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in rsa_priv.der -out openssl_wrapped.data + # assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt RSA priv key" + # cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + # assert $? "AES KEY WRAP PAD wrong RSA key wrap" + + # AES Key + openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt AES key" + # Wrapping + $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap AES key" + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES KEY WRAP PAD wrong AES key wrap" + # Unwrapping + $PKCS11_TOOL_W_PIN --unwrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable + assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap unwrap AES key" + $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key + assert $? "PKCS11 / Failed to read unwrapped AES key" + cmp aes.key unwrapped.key + assert $? "AES KEY WRAP PAD wrong AES key unwrap" + # Cleanup + $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED + assert $? "PKCS11 / Failed to delete unwrapped AES key" +fi + +rm rsa_priv.pem rsa_pub.pem rsa_priv.der aes.key aes_kek.key pkcs11_wrapped.data openssl_wrapped.data unwrapped.key + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +softhsm_cleanup + exit $ERRORS From 9eef825b6ec1d41fd3cbf715436146328529e6da Mon Sep 17 00:00:00 2001 From: baryshnikova Date: Wed, 24 Jul 2024 18:34:17 +0300 Subject: [PATCH 3527/4321] Update min-length of user-pin to support new tokens Rutoken ECP BIO requires min-length param for user/so PIN to be greater than 6 bytes --- src/pkcs15init/rutoken_ecp.profile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/rutoken_ecp.profile b/src/pkcs15init/rutoken_ecp.profile index 3b6f0a2909..f74726ece9 100644 --- a/src/pkcs15init/rutoken_ecp.profile +++ b/src/pkcs15init/rutoken_ecp.profile @@ -48,7 +48,7 @@ PIN user-pin { auth-id = 2; reference = 2; attempts = 5; - min-length = 4; + min-length = 6; max-length = 32; flags = case-sensitive, initialized; } From 99acab9e6cf20ed50570abe792472e99e4524e45 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 16:04:45 +0200 Subject: [PATCH 3528/4321] ci: Fix PIV test after yubico-piv-tool update The recent CI runs started failing with errors like this causing the CI failures: yubico-piv-tool: ambiguous argument, "verify", for option `--action' (`-a') The new option is called "verify-pin" so updated the scripts to use that. --- .github/test-piv.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index e6d7ced222..2444b5f808 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -55,19 +55,19 @@ $VALGRIND opensc-tool -n PIN="123456" yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -a generate -A RSA2048 | tee 9e.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify -aselfsign < 9e.pub | tee 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify-pin -aselfsign < 9e.pub | tee 9e.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -aimport-certificate < 9e.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -a generate -A RSA2048 | tee 9a.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9a.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify-pin -aselfsign < 9a.pub | tee 9a.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9a.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -a generate -A ECCP256 | tee 9c.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9c.pub | tee 9c.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -S'/CN=bar/OU=test/O=example.com/' -averify-pin -aselfsign < 9c.pub | tee 9c.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9c -aimport-certificate < 9c.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -a generate -A ECCP256 | tee 9d.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9d.pub | tee 9d.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -S'/CN=bar/OU=test/O=example.com/' -averify-pin -aselfsign < 9d.pub | tee 9d.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9d -aimport-certificate < 9d.cert $VALGRIND pkcs11-tool -l -O -p "$PIN" From 6e56353af8a99e245db30db0e970089ee1073b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 Jul 2024 14:41:05 +0200 Subject: [PATCH 3529/4321] base64.c: Fix variable overflow Thanks Coverity CID 427421,427427 --- src/libopensc/base64.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libopensc/base64.c b/src/libopensc/base64.c index e8193c976e..119c02224b 100644 --- a/src/libopensc/base64.c +++ b/src/libopensc/base64.c @@ -54,15 +54,14 @@ static const u8 bin_table[128] = { static void to_base64(unsigned int i, u8 *out, size_t fillers) { - unsigned int s = 18, c; + unsigned int s, c; - for (c = 0; c < 4; c++) { + for (c = 0, s = 18; c < 4; c++, s -= 6) { if (fillers >= 4 - c) *out = base64_table[64]; else *out = base64_table[(i >> s) & 0x3f]; out++; - s -= 6; } } @@ -174,4 +173,4 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen) if (r == 0) return len; return SC_ERROR_INVALID_ARGUMENTS; -} +} \ No newline at end of file From ec1fb62cd6315efd23128f5ddab8fbe093dbcf62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 Jul 2024 15:18:30 +0200 Subject: [PATCH 3530/4321] card-openpgp.c: Fix variable overflow Thanks Coverity CID 427425 --- src/libopensc/card-openpgp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7df722cdb7..485b2c3165 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3129,7 +3129,8 @@ pgp_build_tlv(sc_context_t *ctx, unsigned int tag, u8 *data, size_t len, u8 **ou while ((tag >> 8*highest_order) != 0) { highest_order++; } - highest_order--; + if (highest_order != 0) + highest_order--; /* restore class bits in output */ if (highest_order < 4) From 4d7d7cf234c08060aa2df045b62670f46d18d9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 Jul 2024 15:44:48 +0200 Subject: [PATCH 3531/4321] cwa14890.c: Fix variable overflow Thanks Coverity CID 427423 --- src/libopensc/cwa14890.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index e54c99334b..77aaf7cb49 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1600,24 +1600,28 @@ int cwa_encode_apdu(sc_card_t * card, goto encode_end; } } else if ((0xff & from->le) > 0) { - - /* if le byte is declared, compose and add Le TLV */ - /* FIXME: For DNIe we must not send the le bytes - when le == 256 but this goes against the standard - and might break other cards reusing this code */ - /* NOTE: In FNMT MultiPKCS11 code this is an if, i.e., - the le is only sent if no data (lc) is set. - In DNIe 3.0 pin verification sending both TLV return - 69 88 "SM Data Object incorrect". For the moment it is - fixed sendind le=0 in pin verification apdu */ - u8 le = 0xff & from->le; - res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen); - if (res != SC_SUCCESS) { - msg = "Encode APDU compose_tlv(0x97) failed"; - goto encode_end; - } + /* if le byte is declared, compose and add Le TLV */ + /* FIXME: For DNIe we must not send the le bytes + when le == 256 but this goes against the standard + and might break other cards reusing this code */ + /* NOTE: In FNMT MultiPKCS11 code this is an if, i.e., + the le is only sent if no data (lc) is set. + In DNIe 3.0 pin verification sending both TLV return + 69 88 "SM Data Object incorrect". For the moment it is + fixed sendind le=0 in pin verification apdu */ + u8 le = 0xff & from->le; + res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen); + if (res != SC_SUCCESS) { + msg = "Encode APDU compose_tlv(0x97) failed"; + goto encode_end; + } } /* copy current data to apdu buffer (skip header and header padding) */ + if (cclen < 8) { + res = SC_ERROR_INTERNAL; + msg = "Incorrect checksum length"; + goto encode_end; + } memcpy(apdubuf, ccbuf + 8, cclen - 8); apdulen = cclen - 8; /* pad again ccbuffer to compute CC */ From bc10aa98d15d1926e74d6808185932c9f82a5017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 Jul 2024 16:22:08 +0200 Subject: [PATCH 3532/4321] pkcs11-tool.c: Fix variable overflow Thanks Coverity CID 427419 --- src/tools/pkcs11-tool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bd27cc3a5a..81ed632306 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2318,6 +2318,8 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, unsigned long modlen = 0; modlen = (get_private_key_length(session, key) + 7) / 8; + if (modlen == 0) + util_fatal("Incorrect length of private key"); switch (opt_salt_len) { case -1: /* salt size equals to digest size */ pss_params->sLen = hashlen; From 295e4950960f19feb8c4b8810804effec6f14abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 4 Jul 2024 09:25:48 +0200 Subject: [PATCH 3533/4321] pkcs15-pubkey.c: Fix variable overflow Thanks Coverity CID 427418 --- src/libopensc/pkcs15-pubkey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 1f9c2c46d9..83f3feb26a 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1367,6 +1367,8 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke pk_alg.params = NULL; sc_log(ctx, "DEE pk_alg.algorithm=%lu", pk_alg.algorithm); + if (pk.len == 0) + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INTERNAL, "Incorrect length of key"); pk.len = (pk.len + 7)/8; /* convert number of bits to bytes */ if (pk_alg.algorithm == SC_ALGORITHM_EC) { From e78867175df9832da615c6e5906e4bccadf6be04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 4 Jul 2024 09:35:28 +0200 Subject: [PATCH 3534/4321] pkcs15-lib.c: Fix variable overflow Thanks Coverity CID 427417 --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index dbb5748b25..6574e8025d 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3911,7 +3911,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p sc_log(ctx, "Symbolic PIN resolved to PIN(type:CHV,reference:%i)", reference); } - if (path && path->len) { + if (path && path->len && path->len <= SC_MAX_PATH_SIZE) { struct sc_path tmp_path = *path; int iter; r = SC_ERROR_OBJECT_NOT_FOUND; From 726109db516a623b4181a9254ea21f685b6bb3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 4 Jul 2024 10:53:19 +0200 Subject: [PATCH 3535/4321] card-epass2003.c: Fix code style --- src/libopensc/card-epass2003.c | 735 ++++++++++++++------------------- 1 file changed, 302 insertions(+), 433 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index c3b33860ba..a32a247f8a 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -252,8 +252,7 @@ epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) return SC_ERROR_WRONG_LENGTH; } - - for (i = 0; i < err_count; i++) { + for (i = 0; i < err_count; i++) { if (epass2003_errors[i].SWs == ((sw1 << 8) | sw2)) { sc_log(card->ctx, "%s", epass2003_errors[i].errorstr); return epass2003_errors[i].errorno; @@ -269,8 +268,7 @@ sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu) { size_t resplen = apdu->resplen; int r = sc_transmit_apdu(card, apdu); - if ( ((0x69 == apdu->sw1) && (0x85 == apdu->sw2)) || ((0x69 == apdu->sw1) && (0x88 == apdu->sw2))) - { + if ((0x69 == apdu->sw1 && 0x85 == apdu->sw2) || (0x69 == apdu->sw1 && 0x88 == apdu->sw2)) { epass2003_refresh(card); /* renew old resplen */ apdu->resplen = resplen; @@ -287,15 +285,14 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned EVP_CIPHER_CTX * ctx = NULL; int outl = 0; int outl_tmp = 0; - unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0}; memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH); ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto out; - if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || - !EVP_CIPHER_CTX_set_padding(ctx, 0)) + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || !EVP_CIPHER_CTX_set_padding(ctx, 0)) goto out; if (!EVP_EncryptUpdate(ctx, output, &outl, input, (int)length)) @@ -318,7 +315,7 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned EVP_CIPHER_CTX * ctx = NULL; int outl = 0; int outl_tmp = 0; - unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0}; memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH); ctx = EVP_CIPHER_CTX_new(); @@ -354,7 +351,7 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi BIGNUM *enc1,*lenc1; BIGNUM *enc2,*lenc2; - // k1 + // k1 int offset = 0; int r = SC_ERROR_INTERNAL; unsigned char out[32] = {0}; @@ -373,14 +370,14 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi BN_bin2bn(out,16,enc1); BN_lshift1(lenc1,enc1); BN_bn2bin(lenc1,k1Bin); - if(check & 0x80){ + if (check & 0x80) { offset = 1; k1Bin[15+offset] ^= 0x87; } BN_free(enc1); BN_free(lenc1); - // k2 + // k2 enc2 = BN_new(); lenc2 = BN_new(); check = k1Bin[offset]; @@ -389,21 +386,21 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi offset = 0; BN_lshift1(lenc2,enc2); BN_bn2bin(lenc2,k2Bin); - if(check & 0x80){ + if (check & 0x80) { offset = 1; k2Bin[15+offset] ^= 0x87; } BN_free(enc2); BN_free(lenc2); - //padding - if(length < 16){ + // padding + if (length < 16) { memcpy(&data2[0],input,length); data2[length] = 0x80; } - //k2 xor padded data - for (int i=0;i<16;i++){ - data2[i]=data2[i]^k2Bin[offset + i]; + // k2 xor padded data + for (int i = 0; i < 16; i++) { + data2[i] = data2[i] ^ k2Bin[offset + i]; } r = openssl_enc(alg, key, iv, data2, 16, output); sc_evp_cipher_free(alg); @@ -420,17 +417,17 @@ aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, int r = SC_ERROR_INTERNAL; #if OPENSSL_VERSION_NUMBER < 0x30000000L CMAC_CTX *ctx = CMAC_CTX_new(); - if(ctx == NULL) { + if (ctx == NULL) { return SC_ERROR_INTERNAL; } - if(!CMAC_Init(ctx, key,keysize/8, EVP_aes_128_cbc(), NULL)) { + if (!CMAC_Init(ctx, key, keysize / 8, EVP_aes_128_cbc(), NULL)) { goto err; } - if(!CMAC_Update(ctx, input, length)) { + if (!CMAC_Update(ctx, input, length)) { goto err; } - if(!CMAC_Final(ctx, output, &mactlen)) { + if (!CMAC_Final(ctx, output, &mactlen)) { goto err; } r = SC_SUCCESS; @@ -438,7 +435,7 @@ aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, CMAC_CTX_free(ctx); #else EVP_MAC *mac = EVP_MAC_fetch(card->ctx->ossl3ctx->libctx, "cmac", NULL); - if(mac == NULL){ + if (mac == NULL) { return r; } @@ -447,20 +444,20 @@ aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, params[1] = OSSL_PARAM_construct_end(); EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac); - if(ctx == NULL){ + if (ctx == NULL) { EVP_MAC_CTX_free(ctx); sc_log_openssl(card->ctx); return r; } - if(!EVP_MAC_init(ctx, (const unsigned char *)key, keysize/8,params)){ + if (!EVP_MAC_init(ctx, (const unsigned char *)key, keysize / 8, params)) { sc_log_openssl(card->ctx); goto err; } - if(!EVP_MAC_update(ctx, input,length)){ + if (!EVP_MAC_update(ctx, input, length)) { sc_log_openssl(card->ctx); goto err; } - if(!EVP_MAC_final(ctx, output, &mactlen, 16)) { + if (!EVP_MAC_final(ctx, output, &mactlen, 16)) { sc_log_openssl(card->ctx); goto err; } @@ -476,7 +473,7 @@ static int aes128_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, const unsigned char *input, size_t length, unsigned char *output) { - unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); int r; r = openssl_enc(alg, key, iv, input, length, output); @@ -519,16 +516,15 @@ static int des3_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, const unsigned char *input, int length, unsigned char *output) { - unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; - unsigned char bKey[24] = { 0 }; + unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; + unsigned char bKey[24] = {0}; EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3"); int r; if (keysize == 16) { memcpy(&bKey[0], key, 16); memcpy(&bKey[16], key, 8); - } - else { + } else { memcpy(&bKey[0], key, 24); } @@ -544,15 +540,14 @@ static int des3_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { - unsigned char bKey[24] = { 0 }; + unsigned char bKey[24] = {0}; EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); int r; if (keysize == 16) { memcpy(&bKey[0], key, 16); memcpy(&bKey[16], key, 8); - } - else { + } else { memcpy(&bKey[0], key, 24); } @@ -568,15 +563,14 @@ static int des3_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { - unsigned char bKey[24] = { 0 }; + unsigned char bKey[24] = {0}; EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); int r; if (keysize == 16) { memcpy(&bKey[0], key, 16); memcpy(&bKey[16], key, 8); - } - else { + } else { memcpy(&bKey[0], key, 24); } @@ -633,8 +627,8 @@ openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length, } EVP_MD_CTX_init(ctx); - if (!EVP_DigestInit_ex(ctx, digest, NULL) - || !EVP_DigestUpdate(ctx, input, length)) { + if (!EVP_DigestInit_ex(ctx, digest, NULL) || + !EVP_DigestUpdate(ctx, input, length)) { r = SC_ERROR_INTERNAL; goto err; } @@ -685,12 +679,12 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma { int r; struct sc_apdu apdu; - unsigned char data[256] = { 0 }; + unsigned char data[256] = {0}; unsigned char tmp_sm; unsigned char isFips; unsigned long blocksize = 0; - unsigned char cryptogram[256] = { 0 }; /* host cryptogram */ - unsigned char iv[16] = { 0 }; + unsigned char cryptogram[256] = {0}; /* host cryptogram */ + unsigned char iv[16] = {0}; epass2003_exdata *exdata = NULL; if (!card->drv_data) @@ -708,7 +702,7 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma apdu.cla = 0x80; apdu.lc = apdu.datalen = sizeof(g_random); apdu.data = g_random; /* host random */ - if(isFips) + if (isFips) apdu.le = apdu.resplen = 29; else apdu.le = apdu.resplen = 28; @@ -725,15 +719,14 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma LOG_TEST_RET(card->ctx, r, "gen_init_key failed"); /* Step 1 - Generate Derivation data */ - if(isFips){ - memset(data,0x00,15); + if (isFips) { + memset(data, 0x00, 15); data[11] = 0x04; data[14] = 0x80; data[15] = 0x01; memcpy(&data[16], g_random, 8); - memcpy(&data[24], &result[12+1], 8); - } - else{ + memcpy(&data[24], &result[12 + 1], 8); + } else { memcpy(data, &result[16], 4); memcpy(&data[4], g_random, 4); memcpy(&data[8], &result[12], 4); @@ -742,31 +735,29 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 2,3 - Create S-ENC/S-MAC Session Key */ if (KEY_TYPE_AES == key_type) { - if(isFips){ - r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); - memset(&data[11], 0x06, 1); - r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); - }else{ + if (isFips) { + r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); + memset(&data[11], 0x06, 1); + r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); + } else { r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc failed"); r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac failed"); } - } - else { + } else { r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); } - if(isFips){ + if (isFips) { data[11] = 0x00; data[14] = 0x40; - } - else{ + } else { memcpy(data, g_random, 8); memcpy(&data[8], &result[12], 8); data[16] = 0x80; @@ -775,25 +766,23 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma } /* calculate host cryptogram */ - if (KEY_TYPE_AES == key_type) - { - if(isFips){ + if (KEY_TYPE_AES == key_type) { + if (isFips) { r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); - } - else{ + } else { r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); } - } - else + } else { r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + } LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); /* verify card cryptogram */ - if(isFips){ + if (isFips) { if (0 != memcmp(&cryptogram[0], &result[20+1], 8)) LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); - }else{ + } else { if (0 != memcmp(&cryptogram[16], &result[20], 8)) LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED); } @@ -807,10 +796,10 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ int r; struct sc_apdu apdu; unsigned long blocksize = (key_type == KEY_TYPE_AES ? 16 : 8); - unsigned char data[256] = { 0 }; - unsigned char cryptogram[256] = { 0 }; /* host cryptogram */ - unsigned char iv[16] = { 0 }; - unsigned char mac[256] = { 0 }; + unsigned char data[256] = {0}; + unsigned char cryptogram[256] = {0}; /* host cryptogram */ + unsigned char iv[16] = {0}; + unsigned char mac[256] = {0}; unsigned long i; unsigned char tmp_sm; unsigned char isFips; @@ -823,16 +812,14 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ LOG_FUNC_CALLED(card->ctx); - if(isFips) - { + if (isFips) { memset(data,0x00,15); data[11] = 0x01; data[14] = 0x40; data[15] = 0x01; memcpy(&data[16], g_random, 8); memcpy(&data[24], ran_key, 8); - } - else{ + } else { memcpy(data, ran_key, 8); memcpy(&data[8], g_random, 8); data[16] = 0x80; @@ -842,10 +829,9 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ /* calculate host cryptogram */ if (KEY_TYPE_AES == key_type) { - if(isFips){ + if (isFips) { r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); - } - else{ + } else { r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); } } else { @@ -856,10 +842,9 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ memset(data, 0, sizeof(data)); memcpy(data, "\x84\x82\x03\x00\x10", 5); - if(isFips){ - memcpy(&data[5], &cryptogram[0], 8); - } - else{ + if (isFips) { + memcpy(&data[5], &cryptogram[0], 8); + } else { memcpy(&data[5], &cryptogram[16], 8); memcpy(&data[13], "\x80\x00\x00", 3); } @@ -867,10 +852,9 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ /* calculate mac icv */ memset(iv, 0x00, 16); if (KEY_TYPE_AES == key_type) { - if(isFips){ + if (isFips) { r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, data, 13, mac); - } - else{ + } else { r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac); } i = 0; @@ -885,10 +869,9 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ memcpy(exdata->icv_mac, &mac[i], 8); /* verify host cryptogram */ - if(isFips){ + if (isFips) { memcpy(data, &cryptogram[0], 8); - } - else{ + } else { memcpy(data, &cryptogram[16], 8); } memcpy(&data[8], &mac[i], 8); @@ -900,11 +883,9 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ exdata->sm = SM_PLAIN; r = epass2003_transmit_apdu(card, &apdu); exdata->sm = tmp_sm; - LOG_TEST_RET(card->ctx, r, - "APDU verify_init_key failed"); + LOG_TEST_RET(card->ctx, r, "APDU verify_init_key failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, - "verify_init_key failed"); + LOG_TEST_RET(card->ctx, r, "verify_init_key failed"); return r; } @@ -915,8 +896,8 @@ mutual_auth(struct sc_card *card, unsigned char *key_enc, { struct sc_context *ctx = card->ctx; int r; - unsigned char result[256] = { 0 }; - unsigned char ran_key[8] = { 0 }; + unsigned char result[256] = {0}; + unsigned char ran_key[8] = {0}; epass2003_exdata *exdata = NULL; if (!card->drv_data) @@ -927,10 +908,9 @@ mutual_auth(struct sc_card *card, unsigned char *key_enc, r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype); LOG_TEST_RET(ctx, r, "gen_init_key failed"); - if(exdata->bFipsCertification){ + if (exdata->bFipsCertification) { memcpy(ran_key, &result[12+1], 8); - } - else{ + } else { memcpy(ran_key, &result[12], 8); } @@ -969,10 +949,10 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap unsigned char *data_tlv, size_t * data_tlv_len, const unsigned char key_type) { size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8); - unsigned char pad[4096] = { 0 }; + unsigned char pad[4096] = {0}; size_t pad_len; size_t tlv_more; /* increased tlv length */ - unsigned char iv[16] = { 0 }; + unsigned char iv[16] = {0}; epass2003_exdata *exdata = NULL; int r = 0; @@ -998,8 +978,7 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap apdu_buf[block_size + 3] = (unsigned char)((pad_len + 1) % 0x100); apdu_buf[block_size + 4] = 0x01; tlv_more = 5; - } - else { + } else { apdu_buf[block_size + 1] = (unsigned char)pad_len + 1; apdu_buf[block_size + 2] = 0x01; tlv_more = 3; @@ -1036,8 +1015,7 @@ construct_le_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf, size_t data_tlv_ *(apdu_buf + block_size + data_tlv_len + 3) = (unsigned char)(apdu->le % 0x100); memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 4); *le_tlv_len = 4; - } - else { + } else { *(apdu_buf + block_size + data_tlv_len + 1) = 1; *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)apdu->le; memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 3); @@ -1053,9 +1031,9 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) { size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8); - unsigned char mac[4096] = { 0 }; + unsigned char mac[4096] = {0}; size_t mac_len; - unsigned char icv[16] = { 0 }; + unsigned char icv[16] = {0}; int r ; int i = (KEY_TYPE_AES == key_type ? 15 : 7); epass2003_exdata *exdata = NULL; @@ -1067,17 +1045,15 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv if (0 == data_tlv_len && 0 == le_tlv_len) { mac_len = block_size; - } - else { + } else { /* padding */ *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80; - if ((data_tlv_len + le_tlv_len + 1) % block_size) + if ((data_tlv_len + le_tlv_len + 1) % block_size) { mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) + 1) * block_size + block_size; - - else + } else { mac_len = data_tlv_len + le_tlv_len + 1 + block_size; - + } memset((apdu_buf + block_size + data_tlv_len + le_tlv_len + 1), 0, (mac_len - (data_tlv_len + le_tlv_len + 1))); } @@ -1086,8 +1062,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv for (; i >= 0; i--) { if (exdata->icv_mac[i] == 0xff) { exdata->icv_mac[i] = 0; - } - else { + } else { exdata->icv_mac[i]++; break; } @@ -1097,29 +1072,24 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv memset(icv, 0, sizeof(icv)); memcpy(icv, exdata->icv_mac, 16); if (KEY_TYPE_AES == key_type) { - if(exdata->bFipsCertification) - { - for (int i=0;i<16;i++) - { - apdu_buf[i]=apdu_buf[i]^icv[i]; - } - r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); - memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); - for (int j=0;j<4;j++) - { - apdu_buf[j]=apdu_buf[j]^icv[j]; - } - } - else{ + if (exdata->bFipsCertification) { + for (int i = 0; i < 16; i++) { + apdu_buf[i] = apdu_buf[i] ^ icv[i]; + } + r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); + memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8); + for (int j = 0; j < 4; j++) { + apdu_buf[j] = apdu_buf[j] ^ icv[j]; + } + } else { r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); } - } - else { - unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; - unsigned char tmp[8] = { 0 }; + } else { + unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; + unsigned char tmp[8] = {0}; r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed"); r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); @@ -1138,79 +1108,68 @@ static int construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len, unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) { - int r; - size_t block_size = 4; - unsigned char mac[4096] = { 0 }; - size_t mac_len; - int i = (KEY_TYPE_AES == key_type ? 15 : 7); - unsigned char icv[16] = { 0 }; - - epass2003_exdata *exdata = NULL; - - if (!card->drv_data) - return SC_ERROR_INVALID_ARGUMENTS; - - exdata = (epass2003_exdata *)card->drv_data; - - if (0 == data_tlv_len && 0 == le_tlv_len) { - mac_len = block_size; - } - else { - /* padding */ - *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80; - if ((data_tlv_len + le_tlv_len + 1) % block_size) - { - mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +1) * block_size + block_size; - } - else - { - mac_len = data_tlv_len + le_tlv_len + 1 + block_size; - } - - } + int r; + size_t block_size = 4; + unsigned char mac[4096] = {0}; + size_t mac_len; + int i = (KEY_TYPE_AES == key_type ? 15 : 7); + unsigned char icv[16] = {0}; + + epass2003_exdata *exdata = NULL; + + if (!card->drv_data) + return SC_ERROR_INVALID_ARGUMENTS; + + exdata = (epass2003_exdata *)card->drv_data; + + if (0 == data_tlv_len && 0 == le_tlv_len) { + mac_len = block_size; + } else { + /* padding */ + *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80; + if ((data_tlv_len + le_tlv_len + 1) % block_size) { + mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) + 1) * block_size + block_size; + } else { + mac_len = data_tlv_len + le_tlv_len + 1 + block_size; + } + } /* increase icv */ - for (; i >= 0; i--) { - if (exdata->icv_mac[i] == 0xff) { - exdata->icv_mac[i] = 0; - } - else { - exdata->icv_mac[i]++; - break; - } - } - - /* calculate MAC */ + for (; i >= 0; i--) { + if (exdata->icv_mac[i] == 0xff) { + exdata->icv_mac[i] = 0; + } else { + exdata->icv_mac[i]++; + break; + } + } + + /* calculate MAC */ memset(icv, 0, sizeof(icv)); - memcpy(icv, exdata->icv_mac, 16); - if (KEY_TYPE_AES == key_type) { - if(exdata->bFipsCertification) - { - r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); - memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); - } - else - { - r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); - LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); - memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); - } - } - else - { - unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; - unsigned char tmp[8] = { 0 }; - r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); - LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); - r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); - LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); - memset(iv, 0x00, sizeof iv); - r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); - LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); - } - - *mac_tlv_len = 2 + 8; - return 0; + memcpy(icv, exdata->icv_mac, 16); + if (KEY_TYPE_AES == key_type) { + if (exdata->bFipsCertification) { + r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac, &icv[0]); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); + memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8); + } else { + r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + } + } else { + unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; + unsigned char tmp[8] = {0}; + r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); + r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); + memset(iv, 0x00, sizeof iv); + r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); + } + + *mac_tlv_len = 2 + 8; + return 0; } /* According to GlobalPlatform Card Specification's SCP01 @@ -1225,14 +1184,14 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, unsigned char *apdu_buf, size_t * apdu_buf_len) { size_t block_size = 0; - unsigned char dataTLV[4096] = { 0 }; + unsigned char dataTLV[4096] = {0}; size_t data_tlv_len = 0; - unsigned char le_tlv[256] = { 0 }; + unsigned char le_tlv[256] = {0}; size_t le_tlv_len = 0; size_t mac_tlv_len = 10; size_t tmp_lc = 0; size_t tmp_le = 0; - unsigned char mac_tlv[256] = { 0 }; + unsigned char mac_tlv[256] = {0}; epass2003_exdata *exdata = NULL; mac_tlv[0] = 0x8E; @@ -1250,10 +1209,9 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, apdu_buf[3] = (unsigned char)plain->p2; /* plain_le = plain->le; */ /* padding */ - if(exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ + if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) { apdu_buf[4] = 0x00; - } - else{ + } else { apdu_buf[4] = 0x80; } memset(&apdu_buf[5], 0x00, block_size - 5); @@ -1268,11 +1226,10 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, &le_tlv_len, exdata->smtype)) return -1; - if(exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01){ - if(0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) + if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) { + if (0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) return -1; - } - else{ + } else { if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype)) return -1; } @@ -1285,8 +1242,7 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, apdu_buf[5] = (unsigned char)(((sm->lc) / 0x100) % 0x100); apdu_buf[6] = (unsigned char)((sm->lc) % 0x100); tmp_lc = 3; - } - else { + } else { apdu_buf[4] = (unsigned char)sm->lc; tmp_lc = 1; } @@ -1302,8 +1258,7 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)(plain->le / 0x100); *(apdu_buf + 4 + tmp_lc + sm->lc + 1) = (unsigned char)(plain->le % 0x100); tmp_le = 2; - } - else if (3 == le_tlv_len) { + } else if (3 == le_tlv_len) { *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)plain->le; tmp_le = 1; } @@ -1317,7 +1272,7 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, static int epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm) { - unsigned char buf[4096] = { 0 }; /* APDU buffer */ + unsigned char buf[4096] = {0}; /* APDU buffer */ size_t buf_len = sizeof(buf); epass2003_exdata *exdata = NULL; @@ -1403,8 +1358,9 @@ epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm) tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen); if (tag == NULL || taglen != 2) return ret; - } else + } else { return ret; + } } if (sm->sw1 != tag[0] || sm->sw2 != tag[1]) return ret; @@ -1481,8 +1437,8 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned { size_t cipher_len; size_t i; - unsigned char iv[16] = { 0 }; - unsigned char plaintext[4096] = { 0 }; + unsigned char iv[16] = {0}; + unsigned char plaintext[4096] = {0}; epass2003_exdata *exdata = NULL; if (!card->drv_data) @@ -1498,21 +1454,18 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned if (0x01 == in[2] && 0x82 != in[1]) { cipher_len = in[1]; i = 3; - } - else if (0x01 == in[3] && 0x81 == in[1]) { + } else if (0x01 == in[3] && 0x81 == in[1]) { cipher_len = in[2]; i = 4; - } - else if (0x01 == in[4] && 0x82 == in[1]) { + } else if (0x01 == in[4] && 0x82 == in[1]) { cipher_len = in[2] * 0x100; cipher_len += in[3]; i = 5; - } - else { + } else { return -1; } - if (cipher_len < 2 || i+cipher_len > inlen || cipher_len > sizeof plaintext) + if (cipher_len < 2 || i + cipher_len > inlen || cipher_len > sizeof plaintext) return -1; /* decrypt */ @@ -1561,8 +1514,7 @@ epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apd len = plain->resplen; if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len)) return SC_ERROR_CARD_CMD_FAILED; - } - else { + } else { memcpy(plain->resp, sm->resp, sm->resplen); len = sm->resplen; } @@ -1644,7 +1596,7 @@ epass2003_sm_get_wrapped_apdu(struct sc_card *card, apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE; rv = epass2003_sm_wrap_apdu(card, plain, apdu); - if (rv) { + if (rv) { rv = epass2003_sm_free_wrapped_apdu(card, NULL, &apdu); if (rv < 0) goto err; @@ -1682,7 +1634,7 @@ get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t d { int r; struct sc_apdu apdu; - unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = {0}; size_t resplen = SC_MAX_APDU_BUFFER_SIZE; epass2003_exdata *exdata = NULL; @@ -1703,8 +1655,7 @@ get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t d exdata->sm = SM_PLAIN; r = sc_transmit_apdu(card, &apdu); exdata->sm = tmp_sm; - } - else { + } else { r = sc_transmit_apdu_t(card, &apdu); } LOG_TEST_RET(card->ctx, r, "APDU get_data failed"); @@ -1735,7 +1686,7 @@ epass2003_init(struct sc_card *card) { unsigned int flags; unsigned int ext_flags; - unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = {0}; size_t datalen = SC_MAX_APDU_BUFFER_SIZE; epass2003_exdata *exdata = NULL; void *old_drv_data = card->drv_data; @@ -1759,14 +1710,12 @@ epass2003_init(struct sc_card *card) return SC_ERROR_INVALID_CARD; } - if(memcmp(&data[32],"\x87\x01\x01" , 3)==0 && memcmp(&data[0],"\x80\x01\x01", 3)==0){ + if (memcmp(&data[32], "\x87\x01\x01", 3) == 0 && memcmp(&data[0], "\x80\x01\x01", 3) == 0) { exdata->bFipsCertification = 0x01; - } - else{ + } else { exdata->bFipsCertification = 0x00; } - if (0x01 == data[2]) exdata->smtype = KEY_TYPE_AES; else @@ -1778,7 +1727,6 @@ epass2003_init(struct sc_card *card) } } - /* mutual authentication */ card->max_recv_size = 0xD8; card->max_send_size = 0xE8; @@ -1877,7 +1825,7 @@ static int epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** file_out) { struct sc_apdu apdu; - u8 buf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + u8 buf[SC_MAX_APDU_BUFFER_SIZE] = {0}; u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; int r; size_t pathlen; @@ -1909,8 +1857,7 @@ epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** fi apdu.resp = buf; apdu.resplen = sizeof(buf); apdu.le = 0; - } - else { + } else { apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT; } @@ -1992,8 +1939,7 @@ epass2003_select_fid(struct sc_card *card, unsigned int id_hi, unsigned int id_l card->cache.current_path.value[1] = 0x00; if (id_hi == 0x3f && id_lo == 0x00) { card->cache.current_path.len = 2; - } - else { + } else { card->cache.current_path.len = 4; card->cache.current_path.value[2] = id_hi; card->cache.current_path.value[3] = id_lo; @@ -2074,7 +2020,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l if (path[0] != 0x3f || path[1] != 0x00) { n_pathbuf[0] = 0x3f; n_pathbuf[1] = 0x00; - memcpy(n_pathbuf+2, path, pathlen); + memcpy(n_pathbuf + 2, path, pathlen); path = n_pathbuf; pathlen += 2; } @@ -2095,8 +2041,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l if (pathlen - bMatch == 2) { /* we are in the right directory */ return epass2003_select_fid(card, path[bMatch], path[bMatch + 1], file_out); - } - else if (pathlen - bMatch > 2) { + } else if (pathlen - bMatch > 2) { /* two more steps to go */ sc_path_t new_path; @@ -2110,9 +2055,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l /* final step: select file */ return epass2003_select_file(card, &new_path, file_out); - } - else { /* if (bMatch - pathlen == 0) */ - + } else { /* if (bMatch - pathlen == 0) */ /* done: we are already in the * requested directory */ sc_log(card->ctx, "cache hit\n"); @@ -2133,8 +2076,7 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l /* nothing left to do */ return SC_SUCCESS; } - } - else { + } else { /* no usable cache */ for (i = 0; i < pathlen - 2; i += 2) { r = epass2003_select_fid(card, path[i], path[i + 1], NULL); @@ -2185,7 +2127,7 @@ static int epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, int se_num) { struct sc_apdu apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; u8 *p; unsigned short fid = 0; int r, locked = 0; @@ -2215,35 +2157,25 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, apdu.datalen = r; apdu.data = sbuf; - if (env->algorithm == SC_ALGORITHM_EC) - { + if (env->algorithm == SC_ALGORITHM_EC) { apdu.p2 = 0xB6; exdata->currAlg = SC_ALGORITHM_EC; - if(env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) - { + if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) { sbuf[2] = 0x91; exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1; - } - else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) - { + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) { sbuf[2] = 0x92; exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256; - } - else - { + } else { sbuf[2] = 0x92; exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_NONE; } - } - else if(env->algorithm == SC_ALGORITHM_RSA) - { + } else if (env->algorithm == SC_ALGORITHM_RSA) { exdata->currAlg = SC_ALGORITHM_RSA; apdu.p2 = 0xB8; - sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0lx\n",env->algorithm_flags); - } - else - { - sc_log(card->ctx, "%0lx Alg Not Support! ", env->algorithm); + sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0lx\n", env->algorithm_flags); + } else { + sc_log(card->ctx, "%0lx Alg Not Supported!", env->algorithm); } if (se_num > 0) { @@ -2294,8 +2226,8 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data { int r; struct sc_apdu apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; epass2003_exdata *exdata = NULL; LOG_FUNC_CALLED(card->ctx); @@ -2305,35 +2237,27 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data exdata = (epass2003_exdata *)card->drv_data; - if(exdata->currAlg == SC_ALGORITHM_EC) - { - if(exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) - { + if (exdata->currAlg == SC_ALGORITHM_EC) { + if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) { r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash_data failed"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A); apdu.data = sbuf; apdu.lc = 0x14; apdu.datalen = 0x14; - } - else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) - { + } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) { r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); LOG_TEST_RET(card->ctx, r, "hash_data failed"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A); apdu.data = sbuf; apdu.lc = 0x20; apdu.datalen = 0x20; - } - else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_NONE) - { + } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_NONE) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); apdu.data = data; apdu.lc = datalen; apdu.datalen = datalen; - } - else - { + } else { return SC_ERROR_NOT_SUPPORTED; } apdu.resp = rbuf; @@ -2348,9 +2272,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data LOG_FUNC_RETURN(card->ctx, (int)len); } LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); - } - else if(exdata->currAlg == SC_ALGORITHM_RSA) - { + } else if (exdata->currAlg == SC_ALGORITHM_RSA) { sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -2360,9 +2282,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data apdu.data = sbuf; apdu.lc = datalen; apdu.datalen = datalen; - } - else - { + } else { sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -2417,21 +2337,20 @@ sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - switch (file->sec_attr[indx]) { - case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE): - method = SC_AC_NONE; - keyref = SC_AC_KEY_REF_NONE; - break; - case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER): - method = SC_AC_CHV; - keyref = 1; - break; - default: - sc_log(card->ctx,"Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[indx], indx); - method = SC_AC_NEVER; - keyref = SC_AC_KEY_REF_NONE; - - break; + switch (file->sec_attr[indx]) { + case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE): + method = SC_AC_NONE; + keyref = SC_AC_KEY_REF_NONE; + break; + case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER): + method = SC_AC_CHV; + keyref = 1; + break; + default: + sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[indx], indx); + method = SC_AC_NEVER; + keyref = SC_AC_KEY_REF_NONE; + break; } for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) { @@ -2493,8 +2412,7 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si if (byte == 0x38) { type = "DF"; file->type = SC_FILE_TYPE_DF; - } - else if (0x01 <= byte && byte <= 0x07) { + } else if (0x01 <= byte && byte <= 0x07) { type = "working EF"; file->type = SC_FILE_TYPE_WORKING_EF; switch (byte) { @@ -2511,12 +2429,10 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si break; } - } - else if (0x10 == byte) { + } else if (0x10 == byte) { type = "BSO"; file->type = SC_FILE_TYPE_BSO; - } - else if (0x11 <= byte) { + } else if (0x11 <= byte) { type = "internal EF"; file->type = SC_FILE_TYPE_INTERNAL_EF; switch (byte) { @@ -2527,11 +2443,9 @@ epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, si default: break; } - } - else { + } else { type = "unknown"; file->type = SC_FILE_TYPE_INTERNAL_EF; - } sc_log(ctx, "type %s, EF structure %d", type, byte); } @@ -2613,37 +2527,32 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { buf[1] = 0x00; sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p); - } - else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED - || file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED || + file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { buf[1] = 0x00; buf[2] = 0x00; buf[3] = 0x40; /* record length */ buf[4] = 0x00; /* record count */ sc_asn1_put_tag(0x82, buf, 5, p, *outlen - (p - out), &p); - } - else { + } else { return SC_ERROR_NOT_SUPPORTED; } } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { buf[0] = 0x11; buf[1] = 0x00; - } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || + } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { buf[0] = 0x12; buf[1] = 0x00; - } - else { + } else { return SC_ERROR_NOT_SUPPORTED; } sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p); - } - else if (file->type == SC_FILE_TYPE_BSO) { + } else if (file->type == SC_FILE_TYPE_BSO) { buf[0] = 0x10; buf[1] = 0x00; sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p); @@ -2655,8 +2564,7 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, if (file->type == SC_FILE_TYPE_DF) { if (file->namelen != 0) { sc_asn1_put_tag(0x84, file->name, file->namelen, p, *outlen - (p - out), &p); - } - else { + } else { return SC_ERROR_INVALID_ARGUMENTS; } } @@ -2664,16 +2572,14 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, unsigned char data[2] = {0x00, 0x7F}; /* 127 files at most */ sc_asn1_put_tag(0x85, data, sizeof(data), p, *outlen - (p - out), &p); - } - else if (file->type == SC_FILE_TYPE_BSO) { + } else if (file->type == SC_FILE_TYPE_BSO) { buf[0] = file->size & 0xff; sc_asn1_put_tag(0x85, buf, 1, p, *outlen - (p - out), &p); - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT|| - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { buf[0] = (file->size >> 8) & 0xFF; buf[1] = file->size & 0xFF; sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p); @@ -2683,51 +2589,43 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, memcpy(buf, file->sec_attr, file->sec_attr_len); sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p); - } - else { + } else { sc_log(card->ctx, "SC_FILE_ACL"); if (file->type == SC_FILE_TYPE_DF) { ops[0] = SC_AC_OP_LIST_FILES; ops[1] = SC_AC_OP_CREATE; ops[3] = SC_AC_OP_DELETE; - } - else if (file->type == SC_FILE_TYPE_WORKING_EF) { + } else if (file->type == SC_FILE_TYPE_WORKING_EF) { if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { ops[0] = SC_AC_OP_READ; ops[1] = SC_AC_OP_UPDATE; ops[3] = SC_AC_OP_DELETE; - } - else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED - || file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED || + file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { ops[0] = SC_AC_OP_READ; ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_WRITE; ops[3] = SC_AC_OP_DELETE; - } - else { + } else { return SC_ERROR_NOT_SUPPORTED; } - } - else if (file->type == SC_FILE_TYPE_BSO) { + } else if (file->type == SC_FILE_TYPE_BSO) { ops[0] = SC_AC_OP_UPDATE; ops[3] = SC_AC_OP_DELETE; - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT || - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) { ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_CRYPTO; ops[3] = SC_AC_OP_DELETE; - } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| + } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { ops[0] = SC_AC_OP_READ; ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_CRYPTO; ops[3] = SC_AC_OP_DELETE; } - } - else { + } else { return SC_ERROR_NOT_SUPPORTED; } @@ -2745,21 +2643,18 @@ epass2003_construct_fci(struct sc_card *card, const sc_file_t * file, buf[ii] = rv; } sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p); - if(file->size == 256) - { + if (file->size == 256) { out[4]= 0x13; } - } /* VT ??? */ - if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC|| - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { + if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC || + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) { unsigned char data[2] = {0x00, 0x66}; sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p); - if(file->size == 256) - { - out[4]= 0x14; + if (file->size == 256) { + out[4] = 0x14; } } @@ -2775,7 +2670,7 @@ epass2003_create_file(struct sc_card *card, sc_file_t * file) { int r; size_t len; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; struct sc_apdu apdu; len = SC_MAX_APDU_BUFFER_SIZE; @@ -2836,7 +2731,7 @@ static int epass2003_list_files(struct sc_card *card, unsigned char *buf, size_t buflen) { struct sc_apdu apdu; - unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -2868,7 +2763,7 @@ internal_write_rsa_key_factor(struct sc_card *card, unsigned short fid, u8 facto { int r; struct sc_apdu apdu; - u8 sbuff[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 }; + u8 sbuff[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; LOG_FUNC_CALLED(card->ctx); @@ -2914,28 +2809,23 @@ hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsig if ((NULL == data) || (NULL == hash)) return SC_ERROR_INVALID_ARGUMENTS; - if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) - { - unsigned char data_hash[24] = { 0 }; + if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) { + unsigned char data_hash[24] = {0}; size_t len = 0; sha1_digest(card, data, datalen, data_hash); len = REVERSE_ORDER4(datalen); memcpy(&data_hash[20], &len, 4); memcpy(hash, data_hash, 24); - } - else if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256) - { - unsigned char data_hash[36] = { 0 }; + } else if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256) { + unsigned char data_hash[36] = {0}; size_t len = 0; sha256_digest(card, data, datalen, data_hash); len = REVERSE_ORDER4(datalen); memcpy(&data_hash[32], &len, 4); memcpy(hash, data_hash, 36); - } - else - { + } else { return SC_ERROR_NOT_SUPPORTED; } @@ -2951,7 +2841,7 @@ install_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, int r; struct sc_apdu apdu; unsigned char isapp = 0x00; /* appendable */ - unsigned char tmp_data[256] = { 0 }; + unsigned char tmp_data[256] = {0}; tmp_data[0] = ktype; tmp_data[1] = kid; @@ -3008,7 +2898,7 @@ static int internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin) { int r; - unsigned char hash[HASH_LEN] = { 0 }; + unsigned char hash[HASH_LEN] = {0}; r = hash_data(card, pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); @@ -3041,8 +2931,7 @@ epass2003_write_key(struct sc_card *card, sc_epass2003_wkey_data * data) return internal_install_pin(card, data); else LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - } - else { + } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } @@ -3056,17 +2945,14 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) int r; size_t len = data->key_length; struct sc_apdu apdu; - u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 }; - u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 }; + u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; + u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; LOG_FUNC_CALLED(card->ctx); - if(len == 256) - { + if (len == 256) { sbuf[0] = 0x02; - } - else - { + } else { sbuf[0] = 0x01; } sbuf[1] = (u8) ((len >> 8) & 0xff); @@ -3088,8 +2974,7 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) /* read public key */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00); - if(len == 256) - { + if (len == 256) { apdu.p1 = 0x00; } @@ -3108,8 +2993,7 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) if (len < apdu.resplen) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if(256 == len) /* ECC 256 bit */ - { + if (256 == len) { /* ECC 256 bit */ size_t xCoordinateLen = rbuf[1]; size_t yCoordinateLen; unsigned char *tmp; @@ -3123,39 +3007,29 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data) } data->modulus_len = xCoordinateLen + yCoordinateLen; tmp = (u8 *)malloc(data->modulus_len); - if(!tmp) - { + if (!tmp) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } - if(0x58 == rbuf[0]) - { + if (0x58 == rbuf[0]) { memcpy(tmp, &rbuf[2], xCoordinateLen); - } - else{ + } else { free(tmp); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); } - if(0x59 == rbuf[2+xCoordinateLen]) - { + if (0x59 == rbuf[2 + xCoordinateLen]) { memcpy(tmp + xCoordinateLen, &rbuf[2+xCoordinateLen+2], yCoordinateLen); - } - else{ + } else { free(tmp); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); } data->modulus = tmp; - } - else - { + } else { data->modulus = (u8 *) malloc(len); - if (!data->modulus) - { + if (!data->modulus) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - else - { + } else { memcpy(data->modulus, rbuf, len); } } @@ -3269,7 +3143,7 @@ internal_sanitize_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num) static int get_external_key_maxtries(struct sc_card *card, unsigned char *maxtries) { - unsigned char maxcounter[2] = { 0 }; + unsigned char maxcounter[2] = {0}; static const sc_path_t file_path = { {0x3f, 0x00, 0x50, 0x15, 0x9f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6, 0, @@ -3295,7 +3169,7 @@ get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char { int r; struct sc_apdu apdu; - unsigned char random[16] = { 0 }; + unsigned char random[16] = {0}; r = sc_get_challenge(card, random, 8); LOG_TEST_RET(card->ctx, r, "get challenge get_external_key_retries failed"); @@ -3310,8 +3184,7 @@ get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char if (retries && ((0x63 == (apdu.sw1 & 0xff)) && (0xC0 == (apdu.sw2 & 0xf0)))) { *retries = (apdu.sw2 & 0x0f); r = SC_SUCCESS; - } - else { + } else { LOG_TEST_RET(card->ctx, r, "get_external_key_retries failed"); r = SC_ERROR_CARD_CMD_FAILED; } @@ -3348,10 +3221,10 @@ external_key_auth(struct sc_card *card, unsigned char kid, { int r; struct sc_apdu apdu; - unsigned char random[16] = { 0 }; - unsigned char tmp_data[16] = { 0 }; - unsigned char hash[HASH_LEN] = { 0 }; - unsigned char iv[16] = { 0 }; + unsigned char random[16] = {0}; + unsigned char tmp_data[16] = {0}; + unsigned char hash[HASH_LEN] = {0}; + unsigned char iv[16] = {0}; r = sc_get_challenge(card, random, 8); LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed"); @@ -3381,8 +3254,8 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, { int r; struct sc_apdu apdu; - unsigned char hash[HASH_LEN] = { 0 }; - unsigned char tmp_data[256] = { 0 }; + unsigned char hash[HASH_LEN] = {0}; + unsigned char tmp_data[256] = {0}; unsigned char maxtries = 0; r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); @@ -3423,7 +3296,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries data->flags |= SC_PIN_CMD_NEED_PADDING; kid = data->pin_reference; - if(NULL == (unsigned char *)data->pin1.data || 0 == data->pin1.len) + if (NULL == (unsigned char *)data->pin1.data || 0 == data->pin1.len) LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); /* get pin retries */ @@ -3441,13 +3314,11 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries data->pin1.max_tries = maxtries; } LOG_TEST_RET(card->ctx, r, "verify pin failed"); - } - else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */ + } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */ r = external_key_auth(card, (kid + 1), (unsigned char *)data->pin1.data, data->pin1.len); LOG_TEST_RET(card->ctx, r, "verify pin failed"); - } - else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */ + } else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */ r = external_key_auth(card, kid, (unsigned char *)data->pin1.data, data->pin1.len); LOG_TEST_RET(card->ctx, r, "verify pin failed"); @@ -3455,8 +3326,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries r = update_secret_key(card, 0x04, kid, data->pin2.data, (unsigned long)data->pin2.len); LOG_TEST_RET(card->ctx, r, "change pin failed"); - } - else { + } else { r = external_key_auth(card, kid, (unsigned char *)data->pin1.data, data->pin1.len); LOG_TEST_RET(card->ctx, r, "verify pin failed"); @@ -3468,8 +3338,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries LOG_TEST_RET(card->ctx, r, "verify pin failed"); } - if (r == SC_SUCCESS) - { + if (r == SC_SUCCESS) { data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN; } return r; From 3a52206e8c134e3497c64cd24cca8c69be3dc52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 10 Jul 2024 15:39:21 +0200 Subject: [PATCH 3536/4321] card-epass2003.c: Fix variable overflow Thanks Coverity CID 427420 --- src/libopensc/card-epass2003.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index a32a247f8a..4131682caf 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1152,6 +1152,8 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8); } else { + if (mac_len < 16) + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length"); r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); @@ -1159,6 +1161,8 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da } else { unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; unsigned char tmp[8] = {0}; + if (mac_len < 8) + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length"); r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); From d5a5b5428ef1b33c71057fd173e541cdc0273485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 11:51:34 +0200 Subject: [PATCH 3537/4321] Add unittests for base64 encoder and decoder --- src/tests/unittests/Makefile.am | 11 +- src/tests/unittests/Makefile.mak | 3 +- src/tests/unittests/base64.c | 176 +++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 src/tests/unittests/base64.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 4c73911e48..5c9fab9319 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -15,9 +15,11 @@ TESTS_ENVIRONMENT = LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1' endif noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \ - decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding + decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding \ + base64 TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \ - decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding + decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding \ + base64 noinst_HEADERS = torture.h @@ -38,8 +40,9 @@ pkcs15filter_SOURCES = pkcs15-emulator-filter.c openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c hextobin_SOURCES = hextobin.c decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c -check_macro_reference_loop = check_macro_reference_loop.c -strip_pkcs1_2_padding = strip_pkcs1_2_padding.c +check_macro_reference_loop_SOURCES = check_macro_reference_loop.c +strip_pkcs1_2_padding_SOURCES = strip_pkcs1_2_padding.c +base64_SOURCES = base64.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak index 6284b51af9..5e6056238d 100644 --- a/src/tests/unittests/Makefile.mak +++ b/src/tests/unittests/Makefile.mak @@ -1,6 +1,7 @@ TOPDIR = ..\..\.. -TARGETS = asn1 compression pkcs15filter check_macro_reference_loop strip_pkcs1_2_padding +TARGETS = asn1 compression pkcs15filter check_macro_reference_loop \ + strip_pkcs1_2_padding base64 OBJECTS = asn1.obj \ compression.obj \ diff --git a/src/tests/unittests/base64.c b/src/tests/unittests/base64.c new file mode 100644 index 0000000000..a63bcc6e1f --- /dev/null +++ b/src/tests/unittests/base64.c @@ -0,0 +1,176 @@ +/* + * base64.c: Unit tests for Base64 encoding and decoding + * + * Copyright (C) 2024 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "common/compat_strlcpy.c" +#include "libopensc/log.c" +#include "libopensc/padding.c" +#include "torture.h" +#include + +static void +torture_encode_short_length(void **state) +{ + u8 data[] = "ew"; + size_t data_len = 2; + u8 buf[6] = {0}; + size_t buf_len = 6; + u8 expected[] = "ZXc=\n"; + size_t expected_size = 6; + int r = sc_base64_encode(data, data_len, buf, buf_len, 64); + assert_int_equal(r, SC_SUCCESS); + assert_memory_equal(buf, expected, expected_size); +} + +static void +torture_encode_data(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[18] = {0}; + size_t buf_len = 18; + u8 expected[] = "SGVsbG8gV29ybGQ=\n"; + size_t expected_size = 18; + int r = sc_base64_encode(data, data_len, buf, buf_len, 64); + assert_int_equal(r, SC_SUCCESS); + assert_memory_equal(buf, expected, expected_size); +} + +static void +torture_encode_more_lines(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[21] = {0}; + size_t buf_len = 21; + u8 expected[] = "SGVs\nbG8g\nV29y\nbGQ=\n"; + size_t expected_size = 21; + int r = sc_base64_encode(data, data_len, buf, buf_len, 4); + assert_int_equal(r, SC_SUCCESS); + assert_memory_equal(buf, expected, expected_size); +} + +static void +torture_encode_small_out_length_for_lines(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[18] = {0}; + size_t buf_len = 18; + int r = sc_base64_encode(data, data_len, buf, buf_len, 4); + assert_int_equal(r, SC_ERROR_BUFFER_TOO_SMALL); +} + +static void +torture_encode_small_out_length_for_last_foursome(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[15] = {0}; + size_t buf_len = 15; + int r = sc_base64_encode(data, data_len, buf, buf_len, 64); + assert_int_equal(r, SC_ERROR_BUFFER_TOO_SMALL); +} + +static void +torture_encode_small_out_length_for_last_newline(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[16] = {0}; + size_t buf_len = 16; + int r = sc_base64_encode(data, data_len, buf, buf_len, 64); + assert_int_equal(r, SC_ERROR_BUFFER_TOO_SMALL); +} + +static void +torture_encode_small_out_length_for_last_0(void **state) +{ + u8 data[] = "Hello World"; + size_t data_len = 11; + u8 buf[17] = {0}; + size_t buf_len = 17; + int r = sc_base64_encode(data, data_len, buf, buf_len, 64); + assert_int_equal(r, SC_ERROR_BUFFER_TOO_SMALL); +} + +static void +torture_decode_short_data(void **state) +{ + char data[] = "SGVsbG8gV29ybGQ="; + u8 buf[11] = {0}; + size_t buf_len = 11; + u8 expected[] = "Hello World"; + size_t expected_size = 11; + int actual_size = sc_base64_decode(data, buf, buf_len); + assert_int_equal(actual_size, expected_size); + assert_memory_equal(buf, expected, expected_size); +} + +static void +torture_decode_skip_newline_inside(void **state) +{ + char data[] = "SG\nVsbG8gV29ybGQ="; + u8 buf[11] = {0}; + size_t buf_len = 11; + u8 expected[] = "Hello World"; + size_t expected_size = 11; + int actual_size = sc_base64_decode(data, buf, buf_len); + assert_int_equal(actual_size, expected_size); + assert_memory_equal(buf, expected, expected_size); +} + +static void +torture_decode_zero_byte_early_finish(void **state) +{ + char data[] = "\0GVsbG8gV29ybGQ="; + u8 buf[11] = {0}; + size_t buf_len = 11; + int error = sc_base64_decode(data, buf, buf_len); + assert_int_equal(error, 0); +} + +static void +torture_decode_non_ascii_character(void **state) +{ + char data[] = "SG\x11sbG8gV29ybGQ="; + u8 buf[11] = {0}; + size_t buf_len = 11; + int error = sc_base64_decode(data, buf, buf_len); + assert_int_equal(error, SC_ERROR_INVALID_ARGUMENTS); +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_encode_short_length), + cmocka_unit_test(torture_encode_data), + cmocka_unit_test(torture_encode_more_lines), + cmocka_unit_test(torture_encode_small_out_length_for_lines), + cmocka_unit_test(torture_encode_small_out_length_for_last_foursome), + cmocka_unit_test(torture_encode_small_out_length_for_last_newline), + cmocka_unit_test(torture_encode_small_out_length_for_last_0), + cmocka_unit_test(torture_decode_short_data), + cmocka_unit_test(torture_decode_skip_newline_inside), + cmocka_unit_test(torture_decode_zero_byte_early_finish), + cmocka_unit_test(torture_decode_non_ascii_character)}; + return cmocka_run_group_tests(tests, NULL, NULL); +} \ No newline at end of file From d336324c11f7c6acd3bad7e9b456b59af60bc857 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 8 Jun 2024 11:26:47 -0500 Subject: [PATCH 3538/4321] Minidriver.c sign_pin and user_consent - PinCacheAlwaysPrompt At least 5 card drivers set user_consent on a sign pin The user_consent indicates a prompt for the pin should always be done by minidriver. PKCS15 can also set user_consent and PKCS11 sets key attribute CKA_ALWAYS_AUTHENTICATE when key has user_consent, but windows need the PinCacheAlwaysPrompt flag set on the pin. pkcs15-piv.c now defines a sign pin which is used only with the 9C key. ======= On branch minidriver-PinCacheAlwaysPrompt Changes to be committed: modified: libopensc/pkcs15-piv.c modified: minidriver/minidriver.c --- src/libopensc/pkcs15-piv.c | 39 ++++++++++++++++++++++++++++--------- src/minidriver/minidriver.c | 39 +++++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index db7e21decb..fad10899e1 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -71,6 +71,7 @@ typedef struct pdata_st { int tries_left; const unsigned char pad_char; int obj_flags; + int cardmod; /* only use with cardmod minidriver */ } pindata; typedef struct pubdata_st { @@ -385,17 +386,30 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, -1, 0xFF, - SC_PKCS15_CO_FLAG_PRIVATE }, + SC_PKCS15_CO_FLAG_PRIVATE, 0}, + { "02", "PIV PUK", "", 0x81, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 8, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | - SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_SO_PIN | + SC_PKCS15_PIN_FLAG_SO_PIN | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN, -1, 0xFF, - SC_PKCS15_CO_FLAG_PRIVATE }, - { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} + SC_PKCS15_CO_FLAG_PRIVATE, 0}, + + /* only used with minidriver */ + { "03", "PIN", "", 0x80, + /* used in minidriver as the sign key and for 9C key */ + /* label, flag and ref will change if using global pin */ + SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, + 8, 4, 8, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | + SC_PKCS15_PIN_FLAG_INITIALIZED | + SC_PKCS15_PIN_FLAG_LOCAL, + -1, 0xFF, + SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* only use if cardmod */ + { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; // clang-format on @@ -540,7 +554,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, - "", 0x9C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, + "", 0x9C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* use sign pin and user_consent */ { "03", "KEY MAN key", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, @@ -952,6 +966,10 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) const char * label; int pin_ref; + /* the SignPIN is only used with minidriver */ + if (pins[i].cardmod && (strcmp(card->ctx->app_name, "cardmod") != 0)) + continue; + memset(&pin_info, 0, sizeof(pin_info)); memset(&pin_obj, 0, sizeof(pin_obj)); @@ -968,17 +986,17 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) sc_format_path(pins[i].path, &pin_info.path); label = pins[i].label; - if (i == 0 && + if ((i == 0 || pins[i].cardmod) && sc_card_ctl(card, SC_CARDCTL_PIV_PIN_PREFERENCE, &pin_ref) == 0 && pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */ pin_info.attrs.pin.reference = pin_ref; - pin_info.attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; label = "Global PIN"; } + strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; - if (i == 0 && pin_info.attrs.pin.reference == 0x80) { + if ((i == 0 || pins[i].cardmod)) { /* * according to description of "RESET RETRY COUNTER" * command in specs PUK can only unblock PIV PIN @@ -1016,7 +1034,6 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) pubkey_obj.flags = pubkeys[i].obj_flags; - if (pubkeys[i].auth_id) sc_pkcs15_format_id(pubkeys[i].auth_id, &pubkey_obj.auth_id); @@ -1169,6 +1186,10 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) if (prkeys[i].auth_id) sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id); + /* If using minidriver, use Sign PIN for 9C key */ + if (prkey_obj.user_consent && (strcmp(card->ctx->app_name, "cardmod") == 0)) + sc_pkcs15_format_id("03", &prkey_obj.auth_id); + /* * When no cert is present and a pubkey in a file was found, * means the caller is initializing a card. A sign operation diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 10da7dba43..c17933de09 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -233,6 +233,9 @@ typedef struct _VENDOR_SPECIFIC struct md_dh_agreement* dh_agreements; BYTE allocatedAgreements; + /* if any key used with the MD_ROLE_USER_SIGN has user_consent set PinCacheAlwaysPrompt */ + int need_pin_always; + CRITICAL_SECTION hScard_lock; } VENDOR_SPECIFIC; @@ -1888,6 +1891,12 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ? " (default)" : ""); + /* set flag that at least one key that uses the sign key needs PinCacheAlwaysPrompt */ + logprintf(pCardData, 7, "key_obj->user_consent: %d\n", (int) key_obj->user_consent); + if (key_obj->user_consent) + vs->need_pin_always = 1; + logprintf(pCardData, 7, "vs->need_pin_always %d\n", (int) vs->need_pin_always); + if (pin_mode < pin_mode_n) { pin_mode = pin_mode_n; pin_cont_idx = ii; @@ -5999,6 +6008,16 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (pcbSessionPin) *pcbSessionPin = 0; if (ppbSessionPin) *ppbSessionPin = NULL; logprintf(pCardData, 2, "standard pin verification"); + /* + * TODO the use of auth_method being overridden to do session pin + * conflicts with framework-pkcs15.c use of auth_method SC_AC_CONTEXT_SPECIFIC + * for a different purpose. But needs to be reviewed + */ + if (PinId == MD_ROLE_USER_SIGN && vs->need_pin_always) { + logprintf(pCardData, 7, "Setting SC_AC_CONTEXT_SPECIFIC cbPinData: %lu old auth_method: %0x auth_id:%x \n", + (unsigned long) cbPinData, (unsigned int) auth_info->auth_method, (unsigned char) auth_info->auth_id.value[0]); + auth_info->auth_method = SC_AC_CONTEXT_SPECIFIC; + } r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_VERIFY, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, NULL, NULL, DisplayPinpadUI, PinId); } @@ -6475,16 +6494,28 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, "returning info on normal PIN [%lu]\n", (unsigned long)dwFlags); - if (dwFlags == ROLE_USER) + if (dwFlags == ROLE_USER) { + p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; p->PinPurpose = PrimaryCardPin; - else if (dwFlags == MD_ROLE_USER_SIGN) + } + else if (dwFlags == MD_ROLE_USER_SIGN) { + logprintf(pCardData, 7, "vs->need_pin_always %d\n", (int) vs->need_pin_always); + if (vs->need_pin_always) { + p->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt; + logprintf(pCardData, 7, "Setting PinCacheAlwaysPrompt\n"); + } + else + p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; + p->PinPurpose = DigitalSignaturePin; - else + } + else { p->PinPurpose = AuthenticationPin; + p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; + } p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION; p->PinCachePolicy.dwPinCachePolicyInfo = 0; - p->PinCachePolicy.PinCachePolicyType = PinCacheNormal; p->dwChangePermission = CREATE_PIN_SET(dwFlags); p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN); break; From 3b289b17866a72349fcc6e2a6413af17f772cf77 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 1 Jul 2024 16:00:08 -0500 Subject: [PATCH 3539/4321] minidriver.c - move logprintf into loop As suggested in https://github.com/OpenSC/OpenSC/pull/3167#discussion_r1645272537 --- src/minidriver/minidriver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index c17933de09..92dcceac37 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1893,9 +1893,10 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file) /* set flag that at least one key that uses the sign key needs PinCacheAlwaysPrompt */ logprintf(pCardData, 7, "key_obj->user_consent: %d\n", (int) key_obj->user_consent); - if (key_obj->user_consent) + if (key_obj->user_consent) { vs->need_pin_always = 1; - logprintf(pCardData, 7, "vs->need_pin_always %d\n", (int) vs->need_pin_always); + logprintf(pCardData, 7, "vs->need_pin_always %d\n", (int) vs->need_pin_always); + } if (pin_mode < pin_mode_n) { pin_mode = pin_mode_n; From b28a3cef416fcfb92fbb9ea7fd3c71df52c6c9fc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Aug 2024 19:02:14 +0200 Subject: [PATCH 3540/4321] openpgp: Do not accept non-matching key responses When generating RSA key pair using PKCS#15 init, the driver could accept responses relevant to ECC keys, which made further processing in the pkcs15-init failing/accessing invalid parts of structures. Thanks oss-fuzz! https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=71010 Signed-off-by: Jakub Jelen --- src/libopensc/card-openpgp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 485b2c3165..2c92ee597a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2903,6 +2903,9 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* RSA modulus */ if (tag == 0x0081) { + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } if ((BYTES4BITS(key_info->u.rsa.modulus_len) < len) /* modulus_len is in bits */ || key_info->u.rsa.modulus == NULL) { @@ -2918,6 +2921,9 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, } /* RSA public exponent */ else if (tag == 0x0082) { + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } if ((BYTES4BITS(key_info->u.rsa.exponent_len) < len) /* exponent_len is in bits */ || key_info->u.rsa.exponent == NULL) { @@ -2933,6 +2939,10 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, } /* ECC public key */ else if (tag == 0x0086) { + if (key_info->algorithm != SC_OPENPGP_KEYALGO_ECDSA && + key_info->algorithm != SC_OPENPGP_KEYALGO_ECDH) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } /* set the output data */ /* len is ecpoint length + format byte * see section 7.2.14 of 3.3.1 specs */ From 02e847458369c08421fd2d5e9a16a5f272c2de9e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Aug 2024 11:13:47 +0200 Subject: [PATCH 3541/4321] openpgp: Avoid buffer overflow when writing fingerprint Fix also surrounding code to return error (not just log it) when some step fails. Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=70933 Signed-off-by: Jakub Jelen --- src/libopensc/card-openpgp.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 2c92ee597a..0012496a30 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2781,14 +2781,21 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* update the blob containing fingerprints (00C5) */ sc_log(card->ctx, "Updating fingerprint blob 00C5."); fpseq_blob = pgp_find_blob(card, 0x00C5); - if (fpseq_blob == NULL) - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot find blob 00C5"); + if (fpseq_blob == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(card->ctx, r, "Cannot find blob 00C5"); + } + if (20 * key_info->key_id > fpseq_blob->len) { + r = SC_ERROR_OBJECT_NOT_VALID; + LOG_TEST_GOTO_ERR(card->ctx, r, "The 00C5 blob is not large enough"); + } /* save the fingerprints sequence */ newdata = malloc(fpseq_blob->len); - if (newdata == NULL) - LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY, - "Not enough memory to update fingerprint blob 00C5"); + if (newdata == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(card->ctx, r, "Not enough memory to update fingerprint blob 00C5"); + } memcpy(newdata, fpseq_blob->data, fpseq_blob->len); /* move p to the portion holding the fingerprint of the current key */ From 6eeeae7ab0436f85bc9e8c7e9ad1931cd982aed7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 16 Aug 2024 12:11:20 +0200 Subject: [PATCH 3542/4321] openpgp: Set the ecpoint_len based on received length This avoids buffer overrun later when the further processing assumes the length is a field length Signed-off-by: Jakub Jelen --- src/libopensc/card-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0012496a30..dce6b7fe1b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2961,6 +2961,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } memcpy(key_info->u.ec.ecpoint, part + 1, len - 1); + key_info->u.ec.ecpoint_len = len - 1; } /* go to next part to parse */ From 1ab2af78f0a7214404e9545c965b877327dc117d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 16 Aug 2024 13:13:22 +0200 Subject: [PATCH 3543/4321] openpgp: Try to workaround the windows unsigned/signed issue --- src/libopensc/card-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index dce6b7fe1b..78328ffcf2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2785,7 +2785,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, r = SC_ERROR_OUT_OF_MEMORY; LOG_TEST_GOTO_ERR(card->ctx, r, "Cannot find blob 00C5"); } - if (20 * key_info->key_id > fpseq_blob->len) { + if (20U * key_info->key_id > fpseq_blob->len) { r = SC_ERROR_OBJECT_NOT_VALID; LOG_TEST_GOTO_ERR(card->ctx, r, "The 00C5 blob is not large enough"); } From 2646f62102de1928bb86cc1be3a3d371b7c1e3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 21 Aug 2024 09:22:16 +0200 Subject: [PATCH 3544/4321] card-idprime: Fix log message --- src/libopensc/card-idprime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index faf5053e11..bc4b73f699 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -574,7 +574,7 @@ static int idprime_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found"); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Container file found"); r = idprime_process_containermap(card, priv, r); if (r != SC_SUCCESS) { From 900360267ec1bacd6bbf8feb673b33a0ab6476e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 21 Aug 2024 12:48:20 +0200 Subject: [PATCH 3545/4321] card-idprime: Add key reference even when container does not exist Some IDPrime 940 cards have empty container map file even when the keys corresponding to certificates exist. For 940 cards, it is more reliable to check key reference file, the other cards still relies on container map file. --- src/libopensc/card-idprime.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index bc4b73f699..fe1531a063 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -441,11 +441,16 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, container = (idprime_container_t *) list_seek(&priv->containers, &cert_id); if (!container) { - /* Object is added, but missing private key */ + /* Container map missing container with certificate ID */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding container with private key found for certificate with id=%d", cert_id); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd); - idprime_add_object_to_list(&priv->pki_list, &new_object); - continue; + if (card->type != SC_CARD_TYPE_IDPRIME_940) { + /* For cards other than the 940, we don't know how to recognize + certificates missing keys other than to check + that there is a corresponding entry in the container map.*/ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd); + idprime_add_object_to_list(&priv->pki_list, &new_object); + continue; + } } switch (card->type) { @@ -461,7 +466,10 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, case SC_CARD_TYPE_IDPRIME_940: { idprime_keyref_t *keyref = (idprime_keyref_t *) list_seek(&priv->keyrefmap, &cert_id); if (!keyref) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d, skipping", cert_id); + /* Key reference file does not contain record of the key for given certificate */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d", cert_id); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd); + idprime_add_object_to_list(&priv->pki_list, &new_object); continue; } new_object.key_reference = keyref->key_reference; @@ -476,8 +484,14 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, break; } new_object.valid_key_ref = 1; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d corresponding to container \"%s\"", - new_object.fd, new_object.key_reference, container->guid); + if (container != NULL) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d corresponding to container \"%s\"", + new_object.fd, new_object.key_reference, container->guid); + } else { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d without corresponding container", + new_object.fd, new_object.key_reference); + } + idprime_add_object_to_list(&priv->pki_list, &new_object); /* This looks like non-standard extension listing pkcs11 token info label in my card */ From c86656b461ac7503018e5ccb7efa0fa6902580f6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 12 Apr 2024 17:12:59 -0500 Subject: [PATCH 3546/4321] card-piv.c - Card matching fix for unknown card During card matching, only use GET DATA of Discovery object before or in place of SELECT AID, if the ATR matches a known card or user has forced the card type or forced the use of a PIV driver. This avoids possible state change in the unknown card if used by other processes. partial fox for #3108 On branch piv-fix-#3108 Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index ca071c58ed..f4eafe47a4 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -5468,9 +5468,16 @@ static int piv_match_card_continued(sc_card_t *card) * Will fail for other reasons if wrong applet is selected or bad PIV implementation. */ - /* first test if PIV is active applet without using AID If fails use the AID */ + /* + * if ATR matched or user forced card type + * test if PIV is active applet without using AID If fails use the AID + */ + + if (card->type != SC_CARD_TYPE_PIV_II_BASE) + r = piv_find_discovery(card); + else + r = SC_CARD_TYPE_UNKNOWN; - r = piv_find_discovery(card); if (r < 0) { piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache on failure */ r = piv_find_aid(card); From 21ba386091b6d8e992439d6b04f577fe46d0e190 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 23 May 2024 13:51:58 +0200 Subject: [PATCH 3547/4321] idprime: Add known ATRs and card owners --- src/libopensc/card-idprime.c | 39 ++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index fe1531a063..531ac0401d 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -45,41 +45,72 @@ static struct sc_card_driver idprime_drv = { /* This ATR says, there is no EF.DIR nor EF.ATR so ISO discovery mechanisms * are not useful here */ static const struct sc_atr_table idprime_atrs[] = { + /* known ATRs for IDPrime 3810: + * 3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00 Jakuje/xhanulik + */ { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 3810", SC_CARD_TYPE_IDPRIME_3810, 0, NULL }, + /* known ATRs for IDPrime 930: + * 3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00 Jakuje/xhanulik + */ { "3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 830", SC_CARD_TYPE_IDPRIME_830, 0, NULL }, + /* known ATRs for IDPrime 930: + * 3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fd:82:90:00 Jakuje/xhanulik + */ { "3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 930/3930", SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + /* known ATRs: + * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85 metsma + */ { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85", "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", - "based Gemalto IDPrime 930", + "based Gemalto IDPrime 930 (eToken 5110+ FIPS)", SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + /* known ATR for IDPrime 940: Placing in front of the 940 as its mask overlaps this one! + * 3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00 msetina + */ { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 840", SC_CARD_TYPE_IDPRIME_840, 0, NULL }, + /* known ATR for IDPrime 940: + * 3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00 Jakuje/xhanulik, msetina, kirichkov + */ { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940", SC_CARD_TYPE_IDPRIME_940, 0, NULL }, + /* Known ATRs: + * 3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00 vbonamy + */ { "3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940C", - SC_CARD_TYPE_IDPRIME_940, 0, NULL }, + SC_CARD_TYPE_IDPRIME_940, 0, NULL }, + /* Known ATRs for IDPrime 940 (eToken 5110) + * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00 metsma, jurajsarinay + */ + { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", + "Gemalto IDPrime MD 940 (eToken 5110)", + SC_CARD_TYPE_IDPRIME_940, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards", SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, - { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00", + /* Known ATRs: Overlaps partially with 930 and 940 + * 3b:ff:96:00:00:81:31:80:43:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00:66 metsma + */ + { "3b:ff:96:00:00:81:31:80:43:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00:66", "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", - "Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards", + "Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards (eToken)", SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; From 8d04748704f24da97dd98b66c2fcd7f718eb8b4a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 11 Jun 2024 08:59:37 -0500 Subject: [PATCH 3548/4321] pkcs15-jpki.c - minidriver problem with reading public key Add SC_PKCS15_CO_FLAG_PRIVATE on "Digital Signature Public Key" and set pubkey_obj.flags and pubkey_obj.auth_id to use the Sign KEY so minidriver.c can request the pin before reading the public key. Card enforces this as perspecs. Partial fix for #3169 Only pkcs15-jpki.c is changed. In addition to changes in #3167 that address "user_consent" using "PinCacheAlwaysPrompt", The JPKI card forces the user to verify the Sign PIN before the public key is read. But to use the Sign KEY, Windows minidriver specs V7.07 says: the "CCP_CONTAINER_INFO" contains "cbSigPublicKey" and "pbSigPublicKey" which is needed before the key is selected. It might be possible to add bogus information in these and substitute the real values at a later time. But this will require someone with a working card. On branch minidriver-PinCacheAlwaysPrompt Changes to be committed: modified: libopensc/pkcs15-jpki.c On branch JPKI-Improvments Changes to be committed: modified: libopensc/pkcs15-jpki.c --- src/libopensc/pkcs15-jpki.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 8e0881c431..0d423a7057 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -199,6 +199,11 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) "User Authentication Public Key", "Digital Signature Public Key" }; + static int jpki_pubkey_flags[2] = { + 0, + SC_PKCS15_CO_FLAG_PRIVATE + }; + static int jpki_pubkey_auth_id[2] = {0, 2}; struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_object pubkey_obj; static char const *jpki_pubkey_paths[2] = { @@ -217,6 +222,9 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) sc_format_path(jpki_pubkey_paths[i], &pubkey_info.path); pubkey_info.path.type = SC_PATH_TYPE_FILE_ID; + pubkey_obj.flags = jpki_pubkey_flags[i]; + pubkey_obj.auth_id.len = 1; + pubkey_obj.auth_id.value[0] = jpki_pubkey_auth_id[i]; rc = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info); if (rc < 0) { From 9dc4e11325280dc1356ae5ffb3a8fd598cb591b9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 30 Aug 2024 09:25:11 -0500 Subject: [PATCH 3549/4321] pkcs15-jpki.c - code format change Suggesed by clang-format-lint On branch JPKI-Improvements Changes to be committed: modified: libopensc/pkcs15-jpki.c --- src/libopensc/pkcs15-jpki.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 0d423a7057..5711e739bf 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -200,9 +200,8 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) "Digital Signature Public Key" }; static int jpki_pubkey_flags[2] = { - 0, - SC_PKCS15_CO_FLAG_PRIVATE - }; + 0, + SC_PKCS15_CO_FLAG_PRIVATE}; static int jpki_pubkey_auth_id[2] = {0, 2}; struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_object pubkey_obj; From fdce98546077f94a7adaed6448560a5bc1c5ebd0 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Tue, 3 Sep 2024 19:17:15 +0200 Subject: [PATCH 3550/4321] Cleanse the right buffer (Fixes #3224) --- src/tools/sc-hsm-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index e3b20ba33c..6413d6830a 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1271,7 +1271,7 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const fclose(out); - OPENSSL_cleanse(filebuff, sizeof(filebuff)); + OPENSSL_cleanse(dkek_share, sizeof(dkek_share)); printf("DKEK share created and saved to %s\n", outf); return 0; From a240d6e2cc3e4975a87a14338d082dcc5f084fa5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 6 Sep 2024 11:33:57 +0200 Subject: [PATCH 3551/4321] ci: Detect expired github tokens --- .github/push_artifacts.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 873c306c74..31f0b16b8f 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -6,6 +6,13 @@ if [ -z "$GH_TOKEN" ]; then exit 0 fi +# Check the GH_TOKEN is not expired +curl --fail --silent -XGET -H "authorization: token $GH_TOKEN" 'https://api.github.com/repos/OpenSC/Nightly' +if [ 0 -eq "$?" ]; then + echo "The GH_TOKEN is expired -- please renew it!" + exit 1 +fi + BUILDPATH=${PWD} BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" From 895af9b74316908dd8f41c5fe9696675a7beead0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 6 Sep 2024 13:19:13 +0200 Subject: [PATCH 3552/4321] Fix expired GH token detection --- .github/push_artifacts.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 31f0b16b8f..8b24427e91 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -7,11 +7,8 @@ if [ -z "$GH_TOKEN" ]; then fi # Check the GH_TOKEN is not expired -curl --fail --silent -XGET -H "authorization: token $GH_TOKEN" 'https://api.github.com/repos/OpenSC/Nightly' -if [ 0 -eq "$?" ]; then - echo "The GH_TOKEN is expired -- please renew it!" - exit 1 -fi +curl --fail --silent -XGET -H "authorization: token $GH_TOKEN" 'https://api.github.com/repos/OpenSC/Nightly' || \ + ( echo "The GH_TOKEN is expired -- please renew it!"; exit 1 ) BUILDPATH=${PWD} BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`" From 0783c1c6c039af6d41ea89cd1baeba0004c3aa10 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Sep 2024 19:39:53 +0200 Subject: [PATCH 3553/4321] regenerated AppVeyor token for OpenSC-Nightly access --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index ea458405e2..00a40da197 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,7 +10,7 @@ configuration: environment: GH_TOKEN: - secure: jeReA6BNx/dXVMGfroKadgVyPPLNrGL1pvLfc+sizlOLebm/+chuB9AcOi5mTdqHIb3E+TGIR+9fZ+kJotsjCF63ElwE8oJni0Ugrrs16SFwHLAnLpzZBQ5uuIOTVh1X + secure: jeReA6BNx/dXVMGfroKadgE9ByKAE/tAGcb2z+dIVZGAN29X1Pu22wi1TuVOy9ZugqBzjvFV4knwHJSGi0+U6Yj1fTfa2CYpeCBym4JOXqPis/GpKfSeBV9IrmJGT/Av PATH: C:\cygwin\bin;%PATH% OPENPACE_VER: 1.1.3 ZLIB_VER_DOT: 1.2.12 From 76115e34799906a64202df952a8a9915d30bc89d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2024 21:19:15 +0200 Subject: [PATCH 3554/4321] gids: Avoid using uninitialized memory Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-h5f7-rjr5-vx54 Signed-off-by: Jakub Jelen --- src/libopensc/card-gids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index aa63035097..90c98b557d 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -250,7 +250,7 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti LOG_TEST_RET(card->ctx, r, "gids get data failed"); LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); - p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize); + p = sc_asn1_find_tag(card->ctx, buffer, apdu.resplen, dataObjectIdentifier, &datasize); if (!p) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } From bde991b0fe4f0250243b0e4960978b1043c13b03 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2024 21:31:38 +0200 Subject: [PATCH 3555/4321] pkcs15init: Avoid using uninitialized memory Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-h5f7-rjr5-vx54 Signed-off-by: Jakub Jelen --- src/pkcs15init/profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 5113af6ef6..72963e2f9c 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1809,7 +1809,7 @@ do_pin_storedlength(struct state *cur, int argc, char **argv) static int do_pin_flags(struct state *cur, int argc, char **argv) { - unsigned int flags; + unsigned int flags = 0; int i, r; if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) From 7b37d120169bb771b6e5dae79839d35c302e9df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 3 Sep 2024 09:15:22 +0200 Subject: [PATCH 3556/4321] pkcs15init: Remove tab indentation --- src/pkcs15init/profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 72963e2f9c..4fbc3e7e1f 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1809,7 +1809,7 @@ do_pin_storedlength(struct state *cur, int argc, char **argv) static int do_pin_flags(struct state *cur, int argc, char **argv) { - unsigned int flags = 0; + unsigned int flags = 0; int i, r; if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) From e7177c7ca00200afea820d155dca67f38b232967 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 May 2024 22:14:48 +0200 Subject: [PATCH 3557/4321] cac: Correctly calculate certificate length based on the resplen Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-h5f7-rjr5-vx54 Signed-off-by: Jakub Jelen --- src/libopensc/card-cac1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 5ddacc4565..06b2671f43 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -92,12 +92,12 @@ static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_l if (apdu.sw1 != 0x63 || apdu.sw2 < 1) { /* we've either finished reading, or hit an error, break */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); - left -= len; + left -= apdu.resplen; break; } /* Adjust the lengths */ - left -= len; - out_ptr += len; + left -= apdu.resplen; + out_ptr += apdu.resplen; len = MIN(left, apdu.sw2); } if (r < 0) { From 5e4f26b510b04624386c54816bf26aacea0fe4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 11 Jul 2024 14:58:25 +0200 Subject: [PATCH 3558/4321] cac: Fix uninitialized values Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_card/1,fuzz_pkcs11/6 --- src/libopensc/card-cac.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 898fce8aa5..412f22644d 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -252,7 +252,7 @@ static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2, size_t * recvbuflen) { int r; - sc_apdu_t apdu; + sc_apdu_t apdu = {0}; u8 rbufinitbuf[CAC_MAX_SIZE]; u8 *rbuf; size_t rbuflen; @@ -389,13 +389,13 @@ cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len) static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *out_len) { u8 params[2]; - u8 count[2]; + u8 count[2] = {0}; u8 *out = NULL; - u8 *out_ptr; + u8 *out_ptr = NULL; size_t offset = 0; size_t size = 0; size_t left = 0; - size_t len; + size_t len = 0; int r; params[0] = file_type; @@ -458,7 +458,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, const u8 *tl_ptr, *val_ptr, *tl_start; u8 *tlv_ptr; const u8 *cert_ptr; - size_t tl_len, val_len, tlv_len; + size_t tl_len = 0, val_len = 0, tlv_len; size_t len, tl_head_len, cert_len; u8 cert_type, tag; @@ -1519,7 +1519,7 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv, int depth) { u8 *tl = NULL, *val = NULL; - size_t tl_len, val_len; + size_t tl_len = 0, val_len = 0; int r; if (depth > CAC_MAX_CCC_DEPTH) { From 1d3b410e06d33cfc4c70e8a25386e456cfbd7bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 11 Jul 2024 15:27:19 +0200 Subject: [PATCH 3559/4321] cardos: Fix uninitialized values Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_card/2 --- src/libopensc/card-cardos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 2e2d524333..a0e2322478 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -94,14 +94,14 @@ static void fixup_transceive_length(const struct sc_card *card, static int cardos_match_card(sc_card_t *card) { - unsigned char atr[SC_MAX_ATR_SIZE]; + unsigned char atr[SC_MAX_ATR_SIZE] = { 0 }; int i; i = _sc_match_atr(card, cardos_atrs, &card->type); if (i < 0) return 0; - memcpy(atr, card->atr.value, sizeof(atr)); + memcpy(atr, card->atr.value, card->atr.len); /* Do not change card type for CIE! */ if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1) @@ -114,8 +114,8 @@ static int cardos_match_card(sc_card_t *card) return 1; if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int rv; - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + sc_apdu_t apdu = { 0 }; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; /* first check some additional ATR bytes */ if ((atr[4] != 0xff && atr[4] != 0x02) || (atr[6] != 0x10 && atr[6] != 0x0a) || From cccdfc46b10184d1eea62d07fe2b06240b7fafbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 12 Jul 2024 13:16:56 +0200 Subject: [PATCH 3560/4321] card-dnie: Check APDU response length and ASN1 lengths Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_decode/10, fuzz_pkcs15_encode/12 --- src/libopensc/asn1.c | 4 +++- src/libopensc/card-dnie.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 08ef56149c..548263a2da 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -68,7 +68,7 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, *buf = NULL; - if (left == 0 || !p) + if (left == 0 || !p || buflen == 0) return SC_ERROR_INVALID_ASN1_OBJECT; if (*p == 0xff || *p == 0) { /* end of data reached */ @@ -83,6 +83,8 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out, */ cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED); tag = *p & SC_ASN1_TAG_PRIMITIVE; + if (left < 1) + return SC_ERROR_INVALID_ASN1_OBJECT; p++; left--; if (tag == SC_ASN1_TAG_PRIMITIVE) { diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 464670f096..d8b90e8439 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1172,12 +1172,16 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa if (file_out) { /* finally process FCI response */ + size_t len = apdu.resp[1]; sc_file_free(*file_out); *file_out = sc_file_new(); if (*file_out == NULL) { LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } - res = card->ops->process_fci(card, *file_out, apdu.resp + 2, apdu.resp[1]); + if (apdu.resplen - 2 < len || len < 1) { + LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } + res = card->ops->process_fci(card, *file_out, apdu.resp + 2, len); } LOG_FUNC_RETURN(ctx, res); } @@ -1935,7 +1939,7 @@ static int dnie_process_fci(struct sc_card *card, int *op = df_acl; int n = 0; sc_context_t *ctx = NULL; - if ((card == NULL) || (card->ctx == NULL) || (file == NULL)) + if ((card == NULL) || (card->ctx == NULL) || (file == NULL) || buflen == 0) return SC_ERROR_INVALID_ARGUMENTS; ctx = card->ctx; LOG_FUNC_CALLED(ctx); From 5fa758767e517779fc5398b6b4faedc4e36d3de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 12 Jul 2024 14:03:59 +0200 Subject: [PATCH 3561/4321] muscle: Report invalid SW when reading object Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/20, fuzz_pkcs15init/10 --- src/libopensc/muscle.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 46a9f66b88..89dfcbbcba 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -92,33 +92,34 @@ int msc_partial_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *da apdu.resp = data; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && dataLength <= apdu.resplen) return (int)dataLength; - if(apdu.sw1 == 0x9C) { - if(apdu.sw2 == 0x07) { + if (apdu.sw1 == 0x9C) { + if (apdu.sw2 == 0x07) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_FILE_NOT_FOUND); - } else if(apdu.sw2 == 0x06) { + } else if (apdu.sw2 == 0x06) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_ALLOWED); - } else if(apdu.sw2 == 0x0F) { + } else if (apdu.sw2 == 0x0F) { /* GUESSED */ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } } sc_log(card->ctx, "got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); - return (int)dataLength; - + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED); } int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength) { - int r; + int r = 0; unsigned int i; size_t max_read_unit = MSC_MAX_READ; - for(i = 0; i < dataLength; i += max_read_unit) { + for (i = 0; i < dataLength; i += r) { r = msc_partial_read_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_read_unit)); LOG_TEST_RET(card->ctx, r, "Error in partial object read"); + if (r == 0) + break; } return (int)dataLength; } From 3562969c90a71b0bcce979f0e6d627546073a7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 12 Jul 2024 14:16:24 +0200 Subject: [PATCH 3562/4321] card-mcrd: Check length of response buffer in select Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/5,12 fuzz_pkcs15_crypt/9 --- src/libopensc/card-mcrd.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 3a549999eb..911e9f0a07 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -587,20 +587,23 @@ do_select(sc_card_t * card, u8 kind, } } - if (p2 == 0x04 && apdu.resp[0] == 0x62) { + if (p2 == 0x04 && apdu.resplen > 2 && apdu.resp[0] == 0x62) { *file = sc_file_new(); if (!*file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + if (apdu.resp[1] > apdu.resplen - 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } - if (p2 != 0x0C && apdu.resp[0] == 0x6F) { + if (p2 != 0x0C && apdu.resplen > 2 && apdu.resp[0] == 0x6F) { *file = sc_file_new(); if (!*file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - if (apdu.resp[1] <= apdu.resplen) - process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); + if (apdu.resp[1] > apdu.resplen - 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); + process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } return SC_SUCCESS; From bb3dedb71e59bd17f96fd4e807250a5cf2253cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 12 Jul 2024 14:35:47 +0200 Subject: [PATCH 3563/4321] pkcs15-cert.c: Initialize OID length In case it is not set later. Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/7 --- src/libopensc/pkcs15-cert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 1777a85835..5e2dbb89d0 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -169,7 +169,7 @@ sc_pkcs15_get_name_from_dn(struct sc_context *ctx, const u8 *dn, size_t dn_len, for (next_ava = rdn, next_ava_len = rdn_len; next_ava_len; ) { const u8 *ava, *dummy, *oidp; struct sc_object_id oid; - size_t ava_len, dummy_len, oid_len; + size_t ava_len = 0, dummy_len, oid_len = 0; /* unwrap the set and point to the next ava */ ava = sc_asn1_skip_tag(ctx, &next_ava, &next_ava_len, SC_ASN1_TAG_SET | SC_ASN1_CONS, &ava_len); From 16ada9dc7cddf1cb99516aea67b6752c251c94a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 12 Jul 2024 15:04:19 +0200 Subject: [PATCH 3564/4321] card-gids: Use actual length of reponse buffer Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/11 --- src/libopensc/card-gids.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 90c98b557d..5fb0d4acb4 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -230,6 +230,7 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti size_t datasize = 0; const u8* p; u8 buffer[MAX_GIDS_FILE_SIZE]; + size_t buffer_len = sizeof(buffer); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, @@ -243,14 +244,15 @@ static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdenti apdu.data = data; apdu.datalen = 04; apdu.resp = buffer; - apdu.resplen = sizeof(buffer); + apdu.resplen = buffer_len; apdu.le = 256; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "gids get data failed"); LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return"); + buffer_len = apdu.resplen; - p = sc_asn1_find_tag(card->ctx, buffer, apdu.resplen, dataObjectIdentifier, &datasize); + p = sc_asn1_find_tag(card->ctx, buffer, buffer_len, dataObjectIdentifier, &datasize); if (!p) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } From fdb9e903eb124b6b18a5a9350a26eceb775585bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 14:05:36 +0200 Subject: [PATCH 3565/4321] cac: Check return value when selecting AID Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/14 --- src/libopensc/card-cac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 412f22644d..71ab7e482f 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1293,10 +1293,10 @@ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, const u8 *ai /* Call without OID set will just select the AID without subsequent * OID selection, which we need to figure out just now */ - cac_select_file_by_type(card, &new_object.path, NULL); + r = cac_select_file_by_type(card, &new_object.path, NULL); + LOG_TEST_RET(card->ctx, r, "Cannot select AID"); r = cac_get_properties(card, &prop); - if (r < 0) - return SC_ERROR_INTERNAL; + LOG_TEST_RET(card->ctx, r, "Cannot get CAC properties"); for (i = 0; i < prop.num_objects; i++) { /* don't fail just because we have more certs than we can support */ From f01bfbd19b9c8243a40f7f17d554fe0eb9e89d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 14:22:02 +0200 Subject: [PATCH 3566/4321] pkcs15-tcos: Check number of read bytes for cert Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/15 --- src/libopensc/pkcs15-tcos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index a84001e122..4d02a98ee1 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -62,7 +62,8 @@ static int insert_cert( "Select(%s) failed\n", path); return 1; } - if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){ + r = sc_read_binary(card, 0, cert, sizeof(cert), 0); + if (r <= 0){ sc_log(ctx, "ReadBinary(%s) failed\n", path); return 2; From 21d869b77792b6f189eebf373e399747177d99e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 14:29:01 +0200 Subject: [PATCH 3567/4321] cardos: Return error when response length is 0 Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/18 --- src/libopensc/card-cardos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index a0e2322478..124752d78b 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -1281,7 +1281,7 @@ cardos_lifecycle_get(sc_card_t *card, int *mode) LOG_TEST_RET(card->ctx, r, "Card returned error"); if (apdu.resplen < 1) { - LOG_TEST_RET(card->ctx, r, "Lifecycle byte not in response"); + LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Lifecycle byte not in response"); } r = SC_SUCCESS; From 7d68a7f442e38e16625270a0fdc6942c9e9437e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 15:51:51 +0200 Subject: [PATCH 3568/4321] card-piv: Initialize variables for tag and CLA In case they are not later initialize later by sc_asn1_read_tag() function. Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/21 --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index f4eafe47a4..034635d898 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -4428,7 +4428,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) const u8 *p; size_t out_len = 0; int r; - unsigned int tag_out, cla_out; + unsigned int tag_out = 0, cla_out = 0; piv_private_data_t * priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); From 42d718dfccd2a10f6d26705b8c991815c855fa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 Jul 2024 16:32:45 +0200 Subject: [PATCH 3569/4321] pkcs15-sc-hsm: Initialize variables for tag and CLA In case they are not later initialize later by sc_asn1_read_tag() function. Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_crypt/12 --- src/libopensc/pkcs15-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 315cd74482..acdbee7054 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -386,7 +386,7 @@ int sc_pkcs15emu_sc_hsm_decode_cvc(sc_pkcs15_card_t * p15card, struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE]; struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE]; struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE]; - unsigned int cla,tag; + unsigned int cla = 0, tag = 0; size_t taglen; const u8 *tbuf; int r; From 673065630bf4aaf03c370fc791ef6a6239431214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 17 Jul 2024 09:15:43 +0200 Subject: [PATCH 3570/4321] pkcs15-gemsafeV1: Check length of buffer for object Number of actually read bytes may differ from the stated object length. Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_crypt/15 --- src/libopensc/pkcs15-gemsafeV1.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 25140503fa..9fb8956fe9 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -169,6 +169,7 @@ static int gemsafe_get_cert_len(sc_card_t *card) size_t objlen; int certlen; unsigned int ind, i=0; + int read_len; sc_format_path(GEMSAFE_PATH, &path); r = sc_select_file(card, &path, &file); @@ -177,9 +178,11 @@ static int gemsafe_get_cert_len(sc_card_t *card) sc_file_free(file); /* Initial read */ - r = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0); - if (r < 0) + read_len = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0); + if (read_len <= 2) { + sc_log(card->ctx, "Invalid size of object data: %d", read_len); return SC_ERROR_INTERNAL; + } /* Actual stored object size is encoded in first 2 bytes * (allocated EF space is much greater!) @@ -208,7 +211,7 @@ static int gemsafe_get_cert_len(sc_card_t *card) * the private key. */ ind = 2; /* skip length */ - while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) { + while (ind + 1 < (size_t)read_len && ibuf[ind] == 0x01 && i < gemsafe_cert_max) { if (ibuf[ind+1] == 0xFE) { gemsafe_prkeys[i].ref = ibuf[ind+4]; sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d", @@ -235,7 +238,7 @@ static int gemsafe_get_cert_len(sc_card_t *card) /* Read entire file, then dissect in memory. * Gemalto ClassicClient seems to do it the same way. */ - iptr = ibuf + GEMSAFE_READ_QUANTUM; + iptr = ibuf + read_len; while ((size_t)(iptr - ibuf) < objlen) { r = sc_read_binary(card, (unsigned)(iptr - ibuf), iptr, MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0); @@ -243,7 +246,14 @@ static int gemsafe_get_cert_len(sc_card_t *card) sc_log(card->ctx, "Could not read cert object"); return SC_ERROR_INTERNAL; } - iptr += GEMSAFE_READ_QUANTUM; + if (r == 0) + break; + read_len += r; + iptr += r; + } + if ((size_t)read_len < objlen) { + sc_log(card->ctx, "Could not read cert object"); + return SC_ERROR_INTERNAL; } /* Search buffer for certificates, they start with 0x3082. */ From efbc14ffa190e3e0ceecceb479024bb778b0ab68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 17 Jul 2024 10:39:52 +0200 Subject: [PATCH 3571/4321] card-jpki: Check number of read bytes Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_encode/18 --- src/libopensc/card-jpki.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 6e4d0f3165..71339491d1 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -195,6 +195,8 @@ jpki_select_file(struct sc_card *card, u8 buf[4]; rc = sc_read_binary(card, 0, buf, 4, 0); LOG_TEST_RET(card->ctx, rc, "SW Check failed"); + if (rc < 4) + LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Received data too short"); file = sc_file_new(); if (!file) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); From 8632ec172beda894581d67eaa991e519a7874f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 17 Jul 2024 11:18:52 +0200 Subject: [PATCH 3572/4321] pkcs15-tcos: Check return value of serial num conversion Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_encode/21 --- src/libopensc/pkcs15-tcos.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 4d02a98ee1..2bd275c4f4 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -531,10 +531,15 @@ int sc_pkcs15emu_tcos_init_ex( /* get the card serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); if (r < 0) { - sc_log(ctx, "unable to get ICCSN\n"); + sc_log(ctx, "unable to get ICCSN"); return SC_ERROR_WRONG_CARD; } - sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); + r = sc_bin_to_hex(serialnr.value, serialnr.len, serial, sizeof(serial), 0); + if (r != SC_SUCCESS) { + sc_log(ctx, "serial number invalid"); + return SC_ERROR_INTERNAL; + } + serial[19] = '\0'; set_string(&p15card->tokeninfo->serial_number, serial); From a1d8c01c1cabd115dda8c298941d1786fb4c5c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 17 Jul 2024 12:53:52 +0200 Subject: [PATCH 3573/4321] pkcs15-tcos: Check certificate length before accessing Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_encode/8 --- src/libopensc/pkcs15-tcos.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 2bd275c4f4..ecaa66edf2 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -45,6 +45,7 @@ static int insert_cert( struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; unsigned char cert[20]; + size_t cert_len = 0; int r; memset(&cert_info, 0, sizeof(cert_info)); @@ -57,25 +58,31 @@ static int insert_cert( strlcpy(cert_obj.label, label, sizeof(cert_obj.label)); cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0; - if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){ - sc_log(ctx, - "Select(%s) failed\n", path); + if (sc_select_file(card, &cert_info.path, NULL) != SC_SUCCESS) { + sc_log(ctx, "Select(%s) failed", path); return 1; } r = sc_read_binary(card, 0, cert, sizeof(cert), 0); - if (r <= 0){ - sc_log(ctx, - "ReadBinary(%s) failed\n", path); + if (r <= 0) { + sc_log(ctx, "ReadBinary(%s) failed\n", path); return 2; } - if(cert[0]!=0x30 || cert[1]!=0x82){ - sc_log(ctx, - "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); + cert_len = r; /* actual number of read bytes */ + if (cert_len < 7 || (size_t)(7 + cert[5]) > cert_len) { + sc_log(ctx, "Invalid certificate length"); + return 3; + } + if (cert[0] != 0x30 || cert[1] != 0x82) { + sc_log(ctx, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); return 3; } /* some certificates are prefixed by an OID */ - if(cert[4]==0x06 && cert[5]<10 && cert[6+cert[5]]==0x30 && cert[7+cert[5]]==0x82){ + if (cert[4] == 0x06 && cert[5] < 10 && cert[6 + cert[5]] == 0x30 && cert[7 + cert[5]] == 0x82) { + if ((size_t)(9 + cert[5]) > cert_len) { + sc_log(ctx, "Invalid certificate length"); + return 3; + } cert_info.path.index=6+cert[5]; cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4; } else { @@ -83,12 +90,12 @@ static int insert_cert( cert_info.path.count=(cert[2]<<8) + cert[3] + 4; } - r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if(r!=SC_SUCCESS){ - sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path); + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + if (r != SC_SUCCESS) { + sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed", path); return 4; } - sc_log(ctx, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count); + sc_log(ctx, "%s: OK, Index=%d, Count=%d", path, cert_info.path.index, cert_info.path.count); return 0; } From f9d68660f032ad4d7803431d5fc7577ea8792ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 17 Jul 2024 14:56:22 +0200 Subject: [PATCH 3574/4321] pkcs15-lib: Report transport key error Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/17, fuzz_pkcs15init/18 --- src/pkcs15init/pkcs15-lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 6574e8025d..943d53e987 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3831,13 +3831,15 @@ sc_pkcs15init_get_transport_key(struct sc_profile *profile, struct sc_pkcs15_car if (callbacks.get_key) { rv = callbacks.get_key(profile, type, reference, defbuf, defsize, pinbuf, pinsize); LOG_TEST_RET(ctx, rv, "Cannot get key"); - } - else if (rv >= 0) { + } else if (rv >= 0) { if (*pinsize < defsize) LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Get transport key error"); memcpy(pinbuf, data.key_data, data.len); *pinsize = data.len; + } else { + /* pinbuf and pinsize were not filled */ + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Get transport key error"); } memset(&auth_info, 0, sizeof(auth_info)); From a1bcc6516f43d570899820d259b71c53f8049168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 09:23:20 +0200 Subject: [PATCH 3575/4321] pkcs15-starcos: Check length of file to be non-zero Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/20 --- src/pkcs15init/pkcs15-starcos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index bde7413a46..267ad2b04a 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -670,6 +670,8 @@ static int starcos_write_pukey(sc_profile_t *profile, sc_card_t *card, return r; len = tfile->size; sc_file_free(tfile); + if (len == 0) + return SC_ERROR_INTERNAL; buf = malloc(len); if (!buf) return SC_ERROR_OUT_OF_MEMORY; @@ -684,7 +686,7 @@ static int starcos_write_pukey(sc_profile_t *profile, sc_card_t *card, if (num_keys == 0xff) num_keys = 0; /* encode public key */ - keylen = starcos_encode_pukey(rsa, NULL, kinfo); + keylen = starcos_encode_pukey(rsa, NULL, kinfo); if (!keylen) { free(buf); return SC_ERROR_INTERNAL; From 6baa19596598169d652659863470a60c5ed79ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 09:35:23 +0200 Subject: [PATCH 3576/4321] iasecc-sdo: Check length of data before dereferencing Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/21 --- src/libopensc/iasecc-sdo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 417b6dd57d..98402a4e3f 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -760,6 +760,9 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str LOG_FUNC_CALLED(ctx); + if (data == NULL || data_len < 2) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + if (*data == IASECC_SDO_TEMPLATE_TAG) { size_size = iasecc_parse_size(data + 1, data_len - 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); From ef7b10a18e6a4d4f03f0c47ea81aa8136f3eca60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 15:39:15 +0200 Subject: [PATCH 3577/4321] card-oberthur: Check length of serial number Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/1, fuzz_pkcs15init/2 --- src/libopensc/card-oberthur.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index f344d5901f..5920c2c417 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -145,7 +145,7 @@ auth_select_aid(struct sc_card *card) { struct sc_apdu apdu; unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; - struct auth_private_data *data = (struct auth_private_data *) card->drv_data; + struct auth_private_data *data = (struct auth_private_data *)card->drv_data; int rv, ii; struct sc_path tmp_path; @@ -162,6 +162,9 @@ auth_select_aid(struct sc_card *card) rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + if (apdu.resplen < 20) { + LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Serial number has incorrect length"); + } card->serialnr.len = 4; memcpy(card->serialnr.value, apdu.resp+15, 4); From e20ca25204c9c5e36f53ae92ddf017cd17d07e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 10:16:39 +0200 Subject: [PATCH 3578/4321] pkcs15-setcos: Check length of generated key Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/26 --- src/pkcs15init/pkcs15-setcos.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index a445513901..6525541f5a 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -507,6 +507,9 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed"); + if (data_obj.DataLen < 3 || data_obj.DataLen < pubkey->u.rsa.modulus.len) + LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Cannot get key modulus: wrong length of raw key"); + keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (keybits != key_info->modulus_length) { sc_log(ctx, @@ -514,7 +517,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, keybits, key_info->modulus_length); LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key"); } - memcpy (pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len); + memcpy(pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len); } else { sc_file_free(file); } From 468a314d76b26f724a551f2eb339dd17c856cf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 11:03:46 +0200 Subject: [PATCH 3579/4321] iasecc-sdo: Check length of data when parsing Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/27,29 --- src/libopensc/iasecc-sdo.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 98402a4e3f..dbd5b9f08c 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -318,16 +318,25 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru LOG_FUNC_CALLED(ctx); + if (data_len < 1) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + if (*data == IASECC_SDO_TEMPLATE_TAG) { size_size = iasecc_parse_size(data + 1, data_len - 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); + if (data_len - 1 < size) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + data += size_size + 1; data_len = size; sc_log(ctx, "IASECC_SDO_TEMPLATE: size %"SC_FORMAT_LEN_SIZE_T"u, size_size %d", size, size_size); + if (data_len < 3) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + if (*data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); From 2b6cd52775b5448f6a993922a30c7a38d9626134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 11:38:25 +0200 Subject: [PATCH 3580/4321] pkcs15-sc-hsm: Properly check length of file list Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15init/8 --- src/pkcs15init/pkcs15-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 71f96cfc56..db1a2b518f 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -140,7 +140,7 @@ static int sc_hsm_determine_free_id(struct sc_pkcs15_card *p15card, u8 range) LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier"); for (j = 0; j < 256; j++) { - for (i = 0; i < filelistlength; i += 2) { + for (i = 0; i + 1 < filelistlength; i += 2) { if ((filelist[i] == range) && (filelist[i + 1] == j)) { break; } From dd554a2e1e31e6cb75c627c653652696d61e8de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 Jul 2024 12:33:31 +0200 Subject: [PATCH 3581/4321] card-coolkey: Check length of buffer before conversion Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_reader/3 --- src/libopensc/card-coolkey.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 9192aac092..5d547bc960 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1688,6 +1688,7 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, u8 key_number; size_t params_len; u8 buf[MAX_COMPUTE_BUF + 2]; + size_t buf_len; u8 *buf_out; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1728,8 +1729,6 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, ushort2bebytes(params.init.buf_len, 0); } else { /* The data fits in APDU. Copy it to the params object */ - size_t buf_len; - params.init.location = COOLKEY_CRYPT_LOCATION_APDU; params_len = sizeof(params.init) + datalen; @@ -1749,6 +1748,7 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, if (r < 0) { goto done; } + buf_len = crypt_out_len_p; if (datalen > MAX_COMPUTE_BUF) { u8 len_buf[2]; @@ -1767,7 +1767,12 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, priv->nonce, sizeof(priv->nonce)); } else { - size_t out_length = bebytes2ushort(buf); + size_t out_length; + if (buf_len < 2) { + r = SC_ERROR_WRONG_LENGTH; + goto done; + } + out_length = bebytes2ushort(buf); if (out_length > sizeof buf - 2) { r = SC_ERROR_WRONG_LENGTH; goto done; From aa102cd9abe1b0eaf537d9dd926844a46060d8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 23 Jul 2024 10:48:32 +0200 Subject: [PATCH 3582/4321] card-entersafe: Check length of serial number Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs15_reader/5 --- src/libopensc/card-entersafe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 5f6d8a424d..025ebedc91 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -1424,6 +1424,8 @@ static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe get SN failed"); + if (apdu.resplen != 8) + LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Invalid length of SN"); card->serialnr.len = serial->len = 8; memcpy(card->serialnr.value, rbuf, 8); From 265b28344d036a462f38002d957a0636fda57614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 1 Aug 2024 10:32:40 +0200 Subject: [PATCH 3583/4321] card-cardos: Check length of APDU response --- src/libopensc/card-cardos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 124752d78b..595ec099e3 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -94,7 +94,7 @@ static void fixup_transceive_length(const struct sc_card *card, static int cardos_match_card(sc_card_t *card) { - unsigned char atr[SC_MAX_ATR_SIZE] = { 0 }; + unsigned char atr[SC_MAX_ATR_SIZE] = {0}; int i; i = _sc_match_atr(card, cardos_atrs, &card->type); @@ -114,8 +114,8 @@ static int cardos_match_card(sc_card_t *card) return 1; if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int rv; - sc_apdu_t apdu = { 0 }; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 }; + sc_apdu_t apdu = {0}; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0}; /* first check some additional ATR bytes */ if ((atr[4] != 0xff && atr[4] != 0x02) || (atr[6] != 0x10 && atr[6] != 0x0a) || @@ -131,7 +131,7 @@ static int cardos_match_card(sc_card_t *card) apdu.lc = 0; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || apdu.resplen < 2) return 0; if (apdu.resp[0] != atr[10] || apdu.resp[1] != atr[11]) From 48f3248ba95990373d5492116d92c0391961cfe4 Mon Sep 17 00:00:00 2001 From: dlegaultbbry Date: Thu, 11 Jan 2024 16:14:48 -0500 Subject: [PATCH 3584/4321] pkcs11-tool: add pure EdDSA support to sign/verify - add matching of ec_curve_info using ec_params value - distinguish between ed25519 and edd448 using curve size Related #2952 --- src/tools/pkcs11-tool.c | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 81ed632306..5c0e6e88e0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2173,6 +2173,28 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +/* return matching ec_curve_info or NULL based on ec_params */ +static const struct ec_curve_info * +match_ec_curve_by_params(const unsigned char *ec_params, CK_ULONG ec_params_size) +{ + char ecpbuf[64]; + + if (ec_params_size > (sizeof(ecpbuf) / 2)) { + util_fatal("Invalid EC params"); + } + + sc_bin_to_hex(ec_params, ec_params_size, ecpbuf, sizeof(ecpbuf), 0); + + for (size_t i = 0; ec_curve_infos[i].name != NULL; ++i) { + + if (strcmp(ec_curve_infos[i].ec_params, ecpbuf) == 0) { + return &ec_curve_infos[i]; + } + } + + return NULL; +} + /* return digest length in bytes */ static unsigned long hash_length(const unsigned long hash) { unsigned long sLen = 0; @@ -2359,6 +2381,9 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; CK_MAC_GENERAL_PARAMS mac_gen_param; + CK_EDDSA_PARAMS eddsa_params = { + .phFlag = CK_FALSE, + }; CK_RV rv; CK_ULONG sig_len; int fd; @@ -2374,6 +2399,29 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.mechanism = opt_mechanism; hashlen = parse_pss_params(session, key, &mech, &pss_params); + /* support pure EdDSA only */ + if (opt_mechanism == CKM_EDDSA) { + const struct ec_curve_info *curve; + unsigned char *ec_params; + CK_ULONG ec_params_size = 0; + + ec_params = getEC_PARAMS(session, key, &ec_params_size); + if (ec_params == NULL) { + util_fatal("Key has no EC_PARAMS attribute"); + } + + curve = match_ec_curve_by_params(ec_params, ec_params_size); + if (curve == NULL) { + util_fatal("Unknown or unsupported EC curve used in key"); + } + + /* Ed448: need the params defined but default to false */ + if (curve->size == 448) { + mech.pParameter = &eddsa_params; + mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); + } + } + if (opt_input == NULL) fd = 0; else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) @@ -2477,6 +2525,9 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; CK_MAC_GENERAL_PARAMS mac_gen_param; + CK_EDDSA_PARAMS eddsa_params = { + .phFlag = CK_FALSE, + }; CK_RV rv; CK_ULONG sig_len; int fd, fd2; @@ -2502,6 +2553,30 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, fprintf(stderr, "Warning, requesting salt length recovery from signature (supported only in in opensc pkcs11 module).\n"); } } + + /* support pure EdDSA only */ + if (opt_mechanism == CKM_EDDSA) { + const struct ec_curve_info *curve; + unsigned char *ec_params; + CK_ULONG ec_params_size = 0; + + ec_params = getEC_PARAMS(session, key, &ec_params_size); + if (ec_params == NULL) { + util_fatal("Key has no EC_PARAMS attribute"); + } + + curve = match_ec_curve_by_params(ec_params, ec_params_size); + if (curve == NULL) { + util_fatal("Unknown or unsupported EC curve used in key"); + } + + /* Ed448: need the params defined but default to false */ + if (curve->size == 448) { + mech.pParameter = &eddsa_params; + mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); + } + } + /* Open a signature file */ if (opt_signature_file == NULL) util_fatal("No file with signature provided. Use --signature-file"); From 1e39a07c331a1a8c784fd460008ef62c07353171 Mon Sep 17 00:00:00 2001 From: dlegaultbbry Date: Wed, 4 Sep 2024 08:45:12 -0400 Subject: [PATCH 3585/4321] pkcs11-tool: Add Edwards/Montgomery Curve Information - Add the information for the various RFC versions of the Edwards (Ed25519/Ed448) curves - Add the information for the various RFC versions of the Montgomery (X25519/X448) curves This was pulled as a separate change from Doug Engert's X25519 improvements changeset so that EdDSA support in pkcs11-tool had proper curve support. Related #2952 --- src/tools/pkcs11-tool.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 5c0e6e88e0..d618b6925b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -147,8 +147,23 @@ static struct ec_curve_info { {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256, 0}, {"secp521k1", "1.3.132.0.35", "06052B81040023", 521, 0}, - {"edwards25519","1.3.6.1.4.1159.15.1", "130c656477617264733235353139", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, - {"curve25519", "1.3.6.1.4.3029.1.5.1", "130b63757276653235353139", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, + /* Some of the following may not yet be supported by the OpenSC module, but may be by other modules */ + /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs, so pass by printable string */ + /* See PKCS#11 3.0 2.3.7 */ + {"edwards25519", "1.3.6.1.4.1.11591.15.1", "130c656477617264733235353139", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "130a63757276653235353139", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ + + /* RFC8410, EDWARDS and MONTGOMERY curves are used by GnuPG and also by OpenSSL */ + + {"X25519", "1.3.101.110", "06032b656e", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"X448", "1.3.101.111", "06032b656f", 448, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed25519", "1.3.101.112", "06032b6570", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed448", "1.3.101.113", "06032b6571", 448, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + + /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ + {"cv25519", "1.3.101.110", "06032b656e", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, + {"ed25519", "1.3.101.112", "06032b6570", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, + /* OpenSC card-openpgp.c will map these to what is need on the card */ {NULL, NULL, NULL, 0, 0}, }; From f15a7601617e6c787603affd3e7b6d7233104279 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 11 Sep 2024 01:03:09 +0200 Subject: [PATCH 3586/4321] Removed unused newline --- src/tools/pkcs11-tool.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d618b6925b..34ec3a5a92 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2201,7 +2201,6 @@ match_ec_curve_by_params(const unsigned char *ec_params, CK_ULONG ec_params_size sc_bin_to_hex(ec_params, ec_params_size, ecpbuf, sizeof(ecpbuf), 0); for (size_t i = 0; ec_curve_infos[i].name != NULL; ++i) { - if (strcmp(ec_curve_infos[i].ec_params, ecpbuf) == 0) { return &ec_curve_infos[i]; } From 8511d546058384fc48cf6ee139e00827e132c122 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Feb 2024 14:09:34 +0100 Subject: [PATCH 3587/4321] pkcs11-register: Chrome supports native crypto modules like Firefox --- src/tools/pkcs11-register.ggo.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-register.ggo.in b/src/tools/pkcs11-register.ggo.in index 7d463536cb..39f44c48a7 100644 --- a/src/tools/pkcs11-register.ggo.in +++ b/src/tools/pkcs11-register.ggo.in @@ -8,7 +8,7 @@ option "module" m option "skip-chrome" - "Don't install module to Chrome" - flag off + flag @PKCS11_REGISTER_SKIP_FIREFOX@ option "skip-firefox" - "Don't install module to Firefox" From 84ed5042a73d2ad2da586a2ab34da230bf548ec9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Feb 2024 14:29:30 +0100 Subject: [PATCH 3588/4321] include .dirstamp in gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 82015023ca..cbedc03c4c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ tags test-driver .deps .libs +.dirstamp .#*# .*.bak .*.orig From 71959c7105537ae8a84d747e5605fcef6cad3f17 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 28 Feb 2024 10:57:37 +0100 Subject: [PATCH 3589/4321] pkcs11-register: don't adapt Firefox/Chrome by default The source code files for command line interface of pkcs11-register are switched to macOS/Windows defaults in case of adapting the configuration of the browsers. Setting up gengetopt as requirement in Linux is much easier. Also regenerates command line files for all other tools. --- src/tools/egk-tool-cmdline.c | 2 +- src/tools/goid-tool-cmdline.c | 288 ++++++++++++++-------------- src/tools/npa-tool-cmdline.c | 2 +- src/tools/opensc-asn1-cmdline.c | 2 +- src/tools/opensc-notify-cmdline.c | 2 +- src/tools/pkcs11-register-cmdline.c | 10 +- src/tools/pkcs11-register-cmdline.h | 4 +- 7 files changed, 154 insertions(+), 156 deletions(-) diff --git a/src/tools/egk-tool-cmdline.c b/src/tools/egk-tool-cmdline.c index 636c07690a..305b5691d2 100644 --- a/src/tools/egk-tool-cmdline.c +++ b/src/tools/egk-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=egk-tool-cmdline --output-dir=. + /opt/homebrew/bin/gengetopt --file-name=egk-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index c0b1a6f40d..fe89bb7252 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=goid-tool-cmdline --output-dir=. + /opt/homebrew/bin/gengetopt --file-name=goid-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -61,9 +61,9 @@ const char *gengetopt_args_info_help[] = { " --create-dg=ID Create the specified data group; use several\n times to create multiple files", " --new-size=SIZE File size of newly created DGs (default=`256')", " --new-read-ac=STRING Access condition for reading newly created DGs\n (possible values=\"always\", \"never\",\n \"ta\", \"sm\" default=`sm')", - " --new-read-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", + " --new-read-ac-chatbit=INDEX\n Required access bit in certificate's CHAT for\n reading newly created DGs", " --new-write-ac=STRING Access condition for writing newly created DGs\n (possible values=\"always\", \"never\",\n \"ta\", \"sm\" default=`sm')", - " --new-write-ac-chatbit=INDEX\n Required access bits in certificate's CHAT for\n reading newly created DGs", + " --new-write-ac-chatbit=INDEX\n Required access bit in certificate's CHAT for\n reading newly created DGs", 0 }; @@ -160,7 +160,7 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->new_write_ac_orig = NULL; args_info->new_write_ac_chatbit_arg = NULL; args_info->new_write_ac_chatbit_orig = NULL; - + } static @@ -217,7 +217,7 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->new_write_ac_chatbit_help = gengetopt_args_info_help[29] ; args_info->new_write_ac_chatbit_min = 0; args_info->new_write_ac_chatbit_max = 0; - + } void @@ -273,7 +273,7 @@ void cmdline_parser_params_init(struct cmdline_parser_params *params) { if (params) - { + { params->override = 0; params->initialize = 1; params->check_required = 1; @@ -285,9 +285,9 @@ cmdline_parser_params_init(struct cmdline_parser_params *params) struct cmdline_parser_params * cmdline_parser_params_create(void) { - struct cmdline_parser_params *params = + struct cmdline_parser_params *params = (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); - cmdline_parser_params_init(params); + cmdline_parser_params_init(params); return params; } @@ -317,7 +317,7 @@ struct generic_list }; /** - * @brief add a node at the head of the list + * @brief add a node at the head of the list */ static void add_node(struct generic_list **list) { struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list)); @@ -397,8 +397,8 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->new_write_ac_orig)); free_multiple_field (args_info->new_write_ac_chatbit_given, (void *)(args_info->new_write_ac_chatbit_arg), &(args_info->new_write_ac_chatbit_orig)); args_info->new_write_ac_chatbit_arg = 0; - - + + clear_given (args_info); } @@ -428,7 +428,7 @@ check_possible_values(const char *val, const char *values[]) ++found; last = i; if (strlen(values[i]) == len) - return i; /* exact match no need to check more */ + return i; /* exact macth no need to check more */ } } @@ -445,7 +445,7 @@ write_into_file(FILE *outfile, const char *opt, const char *arg, const char *val int found = -1; if (arg) { if (values) { - found = check_possible_values(arg, values); + found = check_possible_values(arg, values); } if (found >= 0) fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); @@ -460,7 +460,7 @@ static void write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[]) { int i; - + for (i = 0; i < len; ++i) write_into_file(outfile, opt, (arg ? arg[i] : 0), values); } @@ -519,7 +519,7 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) if (args_info->new_write_ac_given) write_into_file(outfile, "new-write-ac", args_info->new_write_ac_orig, cmdline_parser_new_write_ac_values); write_multiple_into_file(outfile, args_info->new_write_ac_chatbit_given, "new-write-ac-chatbit", args_info->new_write_ac_chatbit_orig, 0); - + i = EXIT_SUCCESS; return i; @@ -605,8 +605,8 @@ get_multiple_arg_token(const char *arg) j = 0; while (arg[i] && (j < len-1)) { - if (arg[i] == '\\' && - arg[ i + 1 ] && + if (arg[i] == '\\' && + arg[ i + 1 ] && arg[ i + 1 ] == ',') ++i; @@ -698,7 +698,7 @@ check_multiple_option_occurrences(const char *prog_name, unsigned int option_giv } } } - + return error_occurred; } int @@ -719,7 +719,7 @@ cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info cmdline_parser_free (args_info); exit (EXIT_FAILURE); } - + return result; } @@ -728,7 +728,7 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i { int result; struct cmdline_parser_params params; - + params.override = override; params.initialize = initialize; params.check_required = check_required; @@ -742,7 +742,7 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i cmdline_parser_free (args_info); exit (EXIT_FAILURE); } - + return result; } @@ -759,7 +759,7 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog cmdline_parser_free (args_info); exit (EXIT_FAILURE); } - + return result; } @@ -772,38 +772,38 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro /* checks for required options */ if (check_multiple_option_occurrences(prog_name, args_info->verbose_given, args_info->verbose_min, args_info->verbose_max, "'--verbose' ('-v')")) error_occurred = 1; - + if (args_info->soc_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_bio_given, args_info->new_bio_min, args_info->new_bio_max, "'--new-bio'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->certificate_given, args_info->certificate_min, args_info->certificate_max, "'--certificate' ('-c')")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->read_dg_given, args_info->read_dg_min, args_info->read_dg_max, "'--read-dg'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->out_file_given, args_info->out_file_min, args_info->out_file_max, "'--out-file'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->write_dg_given, args_info->write_dg_min, args_info->write_dg_max, "'--write-dg'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->in_file_given, args_info->in_file_min, args_info->in_file_max, "'--in-file'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->delete_dg_given, args_info->delete_dg_min, args_info->delete_dg_max, "'--delete-dg'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->create_dg_given, args_info->create_dg_min, args_info->create_dg_max, "'--create-dg'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_read_ac_chatbit_given, args_info->new_read_ac_chatbit_min, args_info->new_read_ac_chatbit_max, "'--new-read-ac-chatbit'")) error_occurred = 1; - + if (args_info->pxs_mode_counter && check_multiple_option_occurrences(prog_name, args_info->new_write_ac_chatbit_given, args_info->new_write_ac_chatbit_min, args_info->new_write_ac_chatbit_max, "'--new-write-ac-chatbit'")) error_occurred = 1; - - + + /* checks for dependences among options */ if (args_info->certificate_given && ! args_info->key_given) { @@ -867,7 +867,7 @@ static char *package_name = 0; */ static int update_arg(void *field, char **orig_field, - unsigned int *field_given, unsigned int *prev_given, + unsigned int *field_given, unsigned int *prev_given, char *value, const char *possible_values[], const char *default_value, cmdline_parser_arg_type arg_type, @@ -888,11 +888,11 @@ int update_arg(void *field, char **orig_field, if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) { if (short_opt != '-') - fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", package_name, long_opt, short_opt, (additional_error ? additional_error : "")); else - fprintf (stderr, "%s: `--%s' option given more than once%s\n", + fprintf (stderr, "%s: `--%s' option given more than once%s\n", package_name, long_opt, (additional_error ? additional_error : "")); return 1; /* failure */ @@ -901,16 +901,16 @@ int update_arg(void *field, char **orig_field, if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) { if (short_opt != '-') - fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, (additional_error ? additional_error : "")); else - fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, (additional_error ? additional_error : "")); return 1; /* failure */ } - + if (field_given && *field_given && ! override) return 0; if (prev_given) @@ -995,7 +995,7 @@ int update_multiple_arg_temp(struct generic_list **list, { add_node (list); if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0, - prev_given, multi_token, possible_values, default_value, + prev_given, multi_token, possible_values, default_value, arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) { if (multi_token) free(multi_token); return 1; /* failure */ @@ -1048,8 +1048,6 @@ void update_multiple_arg(void *field, char ***orig_field, if (prev_given && list) { *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); - if (!*orig_field) - return; switch(arg_type) { case ARG_INT: @@ -1059,11 +1057,11 @@ void update_multiple_arg(void *field, char ***orig_field, default: break; }; - + for (i = (prev_given - 1); i >= 0; --i) { tmp = list; - + switch(arg_type) { case ARG_INT: (*((int **)field))[i + field_given] = tmp->arg.int_arg; break; @@ -1071,7 +1069,7 @@ void update_multiple_arg(void *field, char ***orig_field, (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break; default: break; - } + } (*orig_field) [i + field_given] = list->orig; list = list->next; free (tmp); @@ -1082,7 +1080,7 @@ void update_multiple_arg(void *field, char ***orig_field, case ARG_INT: if (! *((int **)field)) { *((int **)field) = (int *)malloc (sizeof (int)); - (*((int **)field))[0] = default_value->int_arg; + (*((int **)field))[0] = default_value->int_arg; } break; case ARG_STRING: @@ -1106,7 +1104,7 @@ static int check_modes( int given2[], const char *options2[]) { int i = 0, j = 0, errors = 0; - + while (given1[i] >= 0) { if (given1[i]) { while (given2[j] >= 0) { @@ -1120,7 +1118,7 @@ static int check_modes( } ++i; } - + return errors; } @@ -1142,14 +1140,14 @@ cmdline_parser_internal ( struct generic_list * new_write_ac_chatbit_list = NULL; int error_occurred = 0; struct gengetopt_args_info local_args_info; - + int override; int initialize; int check_required; int check_ambiguity; - + package_name = argv[0]; - + /* TODO: Why is this here? It is not used anywhere. */ override = params->override; FIX_UNUSED(override); @@ -1223,325 +1221,325 @@ cmdline_parser_internal ( exit (EXIT_SUCCESS); case 'r': /* Number of the reader to use. By default, the first reader with a present card is used. If the argument is an ATR, the reader with a matching card will be chosen.. */ - - - if (update_arg( (void *)&(args_info->reader_arg), + + + if (update_arg( (void *)&(args_info->reader_arg), &(args_info->reader_orig), &(args_info->reader_given), &(local_args_info.reader_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "reader", 'r', additional_error)) goto failure; - + break; case 'v': /* Use (several times) to be more verbose. */ - + local_args_info.verbose_given++; - + break; case 'p': /* Verify PIN. */ - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->verify_pin_given), &(local_args_info.verify_pin_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "verify-pin", 'p', additional_error)) goto failure; - + break; case 'b': /* Verify finger print. */ - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->verify_bio_given), &(local_args_info.verify_bio_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "verify-bio", 'b', additional_error)) goto failure; - + break; case 'c': /* Use (several times) to pass CV certificates. */ args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&certificate_list, + + if (update_multiple_arg_temp(&certificate_list, &(local_args_info.certificate_given), optarg, 0, 0, ARG_STRING, "certificate", 'c', additional_error)) goto failure; - + break; case 'k': /* Private key for the CV certificate. */ args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->key_arg), + + + if (update_arg( (void *)&(args_info->key_arg), &(args_info->key_orig), &(args_info->key_given), &(local_args_info.key_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "key", 'k', additional_error)) goto failure; - + break; case 0: /* Long option with no short option */ /* Verify PIN or finger print (user's choice). */ if (strcmp (long_options[option_index].name, "verify-pin-or-bio") == 0) { - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->verify_pin_or_bio_given), &(local_args_info.verify_pin_or_bio_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "verify-pin-or-bio", '-', additional_error)) goto failure; - + } /* Change PIN. */ else if (strcmp (long_options[option_index].name, "new-pin") == 0) { args_info->soc_mode_counter += 1; - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->new_pin_given), &(local_args_info.new_pin_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "new-pin", '-', additional_error)) goto failure; - + } /* Use (several times) to change one or more biometric templates. */ else if (strcmp (long_options[option_index].name, "new-bio") == 0) { args_info->soc_mode_counter += 1; - + local_args_info.new_bio_given++; - + } /* Dump Information about the SoCManager's configuration. */ else if (strcmp (long_options[option_index].name, "info") == 0) { args_info->soc_mode_counter += 1; - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->info_given), &(local_args_info.info_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "info", '-', additional_error)) goto failure; - + } /* Print the card ID. */ else if (strcmp (long_options[option_index].name, "print-cardid") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->print_cardid_given), &(local_args_info.print_cardid_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "print-cardid", '-', additional_error)) goto failure; - + } /* Write the specified card ID. */ else if (strcmp (long_options[option_index].name, "write-cardid") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->write_cardid_arg), + + + if (update_arg( (void *)&(args_info->write_cardid_arg), &(args_info->write_cardid_orig), &(args_info->write_cardid_given), &(local_args_info.write_cardid_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "write-cardid", '-', additional_error)) goto failure; - + } /* Print the PAccess ID. */ else if (strcmp (long_options[option_index].name, "print-paccessid") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->print_paccessid_given), &(local_args_info.print_paccessid_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "print-paccessid", '-', additional_error)) goto failure; - + } /* Write the specified PAccess ID. */ else if (strcmp (long_options[option_index].name, "write-paccessid") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->write_paccessid_arg), + + + if (update_arg( (void *)&(args_info->write_paccessid_arg), &(args_info->write_paccessid_orig), &(args_info->write_paccessid_given), &(local_args_info.write_paccessid_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "write-paccessid", '-', additional_error)) goto failure; - + } /* Read the specified data group; use several times to read out multiple files. */ else if (strcmp (long_options[option_index].name, "read-dg") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&read_dg_list, + + if (update_multiple_arg_temp(&read_dg_list, &(local_args_info.read_dg_given), optarg, 0, 0, ARG_INT, "read-dg", '-', additional_error)) goto failure; - + } /* Write output to a file instead of printing it; use once for each use of `--read-dg'. */ else if (strcmp (long_options[option_index].name, "out-file") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&out_file_list, + + if (update_multiple_arg_temp(&out_file_list, &(local_args_info.out_file_given), optarg, 0, 0, ARG_STRING, "out-file", '-', additional_error)) goto failure; - + } /* Write the specified data group; use several times to write multiple files. */ else if (strcmp (long_options[option_index].name, "write-dg") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&write_dg_list, + + if (update_multiple_arg_temp(&write_dg_list, &(local_args_info.write_dg_given), optarg, 0, 0, ARG_INT, "write-dg", '-', additional_error)) goto failure; - + } /* Read input from a file; use once for each use of `--write-dg'. */ else if (strcmp (long_options[option_index].name, "in-file") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&in_file_list, + + if (update_multiple_arg_temp(&in_file_list, &(local_args_info.in_file_given), optarg, 0, 0, ARG_STRING, "in-file", '-', additional_error)) goto failure; - + } /* Delete the specified data group; use several times to delete multiple files. */ else if (strcmp (long_options[option_index].name, "delete-dg") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&delete_dg_list, + + if (update_multiple_arg_temp(&delete_dg_list, &(local_args_info.delete_dg_given), optarg, 0, 0, ARG_INT, "delete-dg", '-', additional_error)) goto failure; - + } /* Create the specified data group; use several times to create multiple files. */ else if (strcmp (long_options[option_index].name, "create-dg") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&create_dg_list, + + if (update_multiple_arg_temp(&create_dg_list, &(local_args_info.create_dg_given), optarg, 0, 0, ARG_INT, "create-dg", '-', additional_error)) goto failure; - + } /* File size of newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-size") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->new_size_arg), + + + if (update_arg( (void *)&(args_info->new_size_arg), &(args_info->new_size_orig), &(args_info->new_size_given), &(local_args_info.new_size_given), optarg, 0, "256", ARG_INT, check_ambiguity, override, 0, 0, "new-size", '-', additional_error)) goto failure; - + } /* Access condition for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-read-ac") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->new_read_ac_arg), + + + if (update_arg( (void *)&(args_info->new_read_ac_arg), &(args_info->new_read_ac_orig), &(args_info->new_read_ac_given), &(local_args_info.new_read_ac_given), optarg, cmdline_parser_new_read_ac_values, "sm", ARG_STRING, check_ambiguity, override, 0, 0, "new-read-ac", '-', additional_error)) goto failure; - + } - /* Required access bits in certificate's CHAT for reading newly created DGs. */ + /* Required access bit in certificate's CHAT for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-read-ac-chatbit") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&new_read_ac_chatbit_list, + + if (update_multiple_arg_temp(&new_read_ac_chatbit_list, &(local_args_info.new_read_ac_chatbit_given), optarg, 0, 0, ARG_INT, "new-read-ac-chatbit", '-', additional_error)) goto failure; - + } /* Access condition for writing newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-write-ac") == 0) { args_info->pxs_mode_counter += 1; - - - if (update_arg( (void *)&(args_info->new_write_ac_arg), + + + if (update_arg( (void *)&(args_info->new_write_ac_arg), &(args_info->new_write_ac_orig), &(args_info->new_write_ac_given), &(local_args_info.new_write_ac_given), optarg, cmdline_parser_new_write_ac_values, "sm", ARG_STRING, check_ambiguity, override, 0, 0, "new-write-ac", '-', additional_error)) goto failure; - + } - /* Required access bits in certificate's CHAT for reading newly created DGs. */ + /* Required access bit in certificate's CHAT for reading newly created DGs. */ else if (strcmp (long_options[option_index].name, "new-write-ac-chatbit") == 0) { args_info->pxs_mode_counter += 1; - - if (update_multiple_arg_temp(&new_write_ac_chatbit_list, + + if (update_multiple_arg_temp(&new_write_ac_chatbit_list, &(local_args_info.new_write_ac_chatbit_given), optarg, 0, 0, ARG_INT, "new-write-ac-chatbit", '-', additional_error)) goto failure; - + } - + break; case '?': /* Invalid option. */ /* `getopt_long' already printed an error message. */ @@ -1613,7 +1611,7 @@ cmdline_parser_internal ( local_args_info.new_read_ac_chatbit_given = 0; args_info->new_write_ac_chatbit_given += local_args_info.new_write_ac_chatbit_given; local_args_info.new_write_ac_chatbit_given = 0; - + if (args_info->pxs_mode_counter && args_info->soc_mode_counter) { int pxs_given[] = {args_info->certificate_given, args_info->key_given, args_info->print_cardid_given, args_info->write_cardid_given, args_info->print_paccessid_given, args_info->write_paccessid_given, args_info->read_dg_given, args_info->out_file_given, args_info->write_dg_given, args_info->in_file_given, args_info->delete_dg_given, args_info->create_dg_given, args_info->new_size_given, args_info->new_read_ac_given, args_info->new_read_ac_chatbit_given, args_info->new_write_ac_given, args_info->new_write_ac_chatbit_given, -1}; const char *pxs_desc[] = {"--certificate", "--key", "--print-cardid", "--write-cardid", "--print-paccessid", "--write-paccessid", "--read-dg", "--out-file", "--write-dg", "--in-file", "--delete-dg", "--create-dg", "--new-size", "--new-read-ac", "--new-read-ac-chatbit", "--new-write-ac", "--new-write-ac-chatbit", 0}; @@ -1621,7 +1619,7 @@ cmdline_parser_internal ( const char *soc_desc[] = {"--new-pin", "--new-bio", "--info", 0}; error_occurred += check_modes(pxs_given, pxs_desc, soc_given, soc_desc); } - + if (check_required) { error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error); @@ -1644,7 +1642,7 @@ cmdline_parser_internal ( free_list (create_dg_list, 0 ); free_list (new_read_ac_chatbit_list, 0 ); free_list (new_write_ac_chatbit_list, 0 ); - + cmdline_parser_release (&local_args_info); return (EXIT_FAILURE); } diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index c617dca7e2..47e14153ea 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=npa-tool-cmdline --output-dir=. + /opt/homebrew/bin/gengetopt --file-name=npa-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: diff --git a/src/tools/opensc-asn1-cmdline.c b/src/tools/opensc-asn1-cmdline.c index 13e5412acf..a571762b27 100644 --- a/src/tools/opensc-asn1-cmdline.c +++ b/src/tools/opensc-asn1-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts + /opt/homebrew/bin/gengetopt --file-name=opensc-asn1-cmdline --output-dir=. --unamed-opts The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: diff --git a/src/tools/opensc-notify-cmdline.c b/src/tools/opensc-notify-cmdline.c index 9bae830a9e..7f148927c0 100644 --- a/src/tools/opensc-notify-cmdline.c +++ b/src/tools/opensc-notify-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=opensc-notify-cmdline --output-dir=. + /opt/homebrew/bin/gengetopt --file-name=opensc-notify-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: diff --git a/src/tools/pkcs11-register-cmdline.c b/src/tools/pkcs11-register-cmdline.c index 4cdc789009..467fd927ab 100644 --- a/src/tools/pkcs11-register-cmdline.c +++ b/src/tools/pkcs11-register-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /usr/bin/gengetopt --file-name=pkcs11-register-cmdline --output-dir=. + /opt/homebrew/bin/gengetopt --file-name=pkcs11-register-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -37,8 +37,8 @@ const char *gengetopt_args_info_help[] = { " -h, --help Print help and exit", " -V, --version Print version and exit", " -m, --module=FILENAME Specify the module to load (default=`OpenSC's\n PKCS#11 module')", - " --skip-chrome Don't install module to Chrome (default=off)", - " --skip-firefox Don't install module to Firefox (default=off)", + " --skip-chrome Don't install module to Chrome (default=on)", + " --skip-firefox Don't install module to Firefox (default=on)", " --skip-thunderbird Don't install module to Thunderbird (default=off)", " --skip-seamonkey Don't install module to SeaMonkey (default=off)", "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", @@ -81,8 +81,8 @@ void clear_args (struct gengetopt_args_info *args_info) FIX_UNUSED (args_info); args_info->module_arg = gengetopt_strdup ("OpenSC's PKCS#11 module"); args_info->module_orig = NULL; - args_info->skip_chrome_flag = 0; - args_info->skip_firefox_flag = 0; + args_info->skip_chrome_flag = 1; + args_info->skip_firefox_flag = 1; args_info->skip_thunderbird_flag = 0; args_info->skip_seamonkey_flag = 0; diff --git a/src/tools/pkcs11-register-cmdline.h b/src/tools/pkcs11-register-cmdline.h index 67188023db..8262da3e42 100644 --- a/src/tools/pkcs11-register-cmdline.h +++ b/src/tools/pkcs11-register-cmdline.h @@ -42,9 +42,9 @@ struct gengetopt_args_info char * module_arg; /**< @brief Specify the module to load (default='OpenSC's PKCS#11 module'). */ char * module_orig; /**< @brief Specify the module to load original value given at command line. */ const char *module_help; /**< @brief Specify the module to load help description. */ - int skip_chrome_flag; /**< @brief Don't install module to Chrome (default=off). */ + int skip_chrome_flag; /**< @brief Don't install module to Chrome (default=on). */ const char *skip_chrome_help; /**< @brief Don't install module to Chrome help description. */ - int skip_firefox_flag; /**< @brief Don't install module to Firefox (default=off). */ + int skip_firefox_flag; /**< @brief Don't install module to Firefox (default=on). */ const char *skip_firefox_help; /**< @brief Don't install module to Firefox help description. */ int skip_thunderbird_flag; /**< @brief Don't install module to Thunderbird (default=off). */ const char *skip_thunderbird_help; /**< @brief Don't install module to Thunderbird help description. */ From 7d1fd10b7fc6b35489da31b517982fe723231752 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 28 Feb 2024 11:13:54 +0100 Subject: [PATCH 3590/4321] fixed shorten-64-to-32 warning for gengetopt generated files --- .github/workflows/linux-strict.yml | 1 - configure.ac | 2 ++ src/tools/Makefile.am | 24 ++++++++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 3be81565b4..536a91bfaa 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -34,7 +34,6 @@ permissions: # -Wno-incompatible-function-pointer-types -- this looks just buggy as it # complains about missing const, which is there env: - CLANG_CFLAGS: -Wshorten-64-to-32 CFLAGS: >- -pedantic -Werror -Wall -Wno-strict-prototypes -Wno-empty-translation-unit diff --git a/configure.ac b/configure.ac index b8224b5de7..e06b0d818b 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,8 @@ AX_CODE_COVERAGE() AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"]) AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"]) +AX_CHECK_COMPILE_FLAG([-Wshorten-64-to-32], [have_shorten_warning_option="yes"], [have_shorten_warning_option="no"]) +AM_CONDITIONAL([HAVE_SHORTEN_WARNING_OPTION], [test "${have_shorten_warning_option}" = "yes"]) AX_VALGRIND_CHECK() diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index aab4a81163..ae491d2efd 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -107,12 +107,18 @@ npa_tool_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPENPACE_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option endif +if HAVE_SHORTEN_WARNING_OPTION +npa_tool_CFLAGS += -Wno-shorten-64-to-32 +endif opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION opensc_notify_CFLAGS += -Wno-unknown-warning-option endif +if HAVE_SHORTEN_WARNING_OPTION +opensc_notify_CFLAGS += -Wno-shorten-64-to-32 +endif egk_tool_SOURCES = egk-tool.c util.c egk-tool-cmdline.c egk_tool_LDADD = $(OPTIONAL_ZLIB_LIBS) @@ -120,6 +126,9 @@ egk_tool_CFLAGS = $(OPTIONAL_ZLIB_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION egk_tool_CFLAGS += -Wno-unknown-warning-option endif +if HAVE_SHORTEN_WARNING_OPTION +egk_tool_CFLAGS += -Wno-shorten-64-to-32 +endif goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c goid-tool-cmdline.c goid_tool_LDADD = $(OPENPACE_LIBS) @@ -127,18 +136,29 @@ goid_tool_CFLAGS = $(OPENPACE_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION goid_tool_CFLAGS += -Wno-unknown-warning-option endif +if HAVE_SHORTEN_WARNING_OPTION +goid_tool_CFLAGS += -Wno-shorten-64-to-32 +endif dtrust_tool_SOURCES = dtrust-tool.c util.c opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c +opensc_asn1_CFLAGS = if HAVE_UNKNOWN_WARNING_OPTION -opensc_asn1_CFLAGS = -Wno-unknown-warning-option +opensc_asn1_CFLAGS += -Wno-unknown-warning-option +endif +if HAVE_SHORTEN_WARNING_OPTION +opensc_asn1_CFLAGS += -Wno-shorten-64-to-32 endif pkcs11_register_SOURCES = pkcs11-register.c fread_to_eof.c pkcs11-register-cmdline.c pkcs11_register_LDADD = $(top_builddir)/src/common/libpkcs11.la +pkcs11_register_CFLAGS = if HAVE_UNKNOWN_WARNING_OPTION -pkcs11_register_CFLAGS = -Wno-unknown-warning-option +pkcs11_register_CFLAGS += -Wno-unknown-warning-option +endif +if HAVE_SHORTEN_WARNING_OPTION +pkcs11_register_CFLAGS += -Wno-shorten-64-to-32 endif .PHONY: cmdline From 4624a1959b06be09f2b1197beed11c15f96cc3ea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 7 Mar 2024 00:36:45 +0100 Subject: [PATCH 3591/4321] goid-tool: workaround for compiler warning of generated code --- src/tools/goid-tool-cmdline.c | 52 +++++++++++++++++------------------ src/tools/goid-tool-cmdline.h | 14 +++++----- src/tools/goid-tool.c | 2 +- src/tools/goid-tool.ggo.in | 14 +++++----- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index fe89bb7252..459e10e2f6 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -69,7 +69,7 @@ const char *gengetopt_args_info_help[] = { typedef enum {ARG_NO , ARG_STRING - , ARG_INT + , ARG_SHORT } cmdline_parser_arg_type; static @@ -303,7 +303,7 @@ free_string_field (char **s) /** @brief generic value variable */ union generic_value { - int int_arg; + short short_arg; char *string_arg; const char *default_string_arg; }; @@ -921,8 +921,8 @@ int update_arg(void *field, char **orig_field, val = possible_values[found]; switch(arg_type) { - case ARG_INT: - if (val) *((int *)field) = (int)strtol (val, &stop_char, 0); + case ARG_SHORT: + if (val) *((short *)field) = (short)strtol (val, &stop_char, 0); break; case ARG_STRING: if (val) { @@ -938,7 +938,7 @@ int update_arg(void *field, char **orig_field, /* check numeric conversion */ switch(arg_type) { - case ARG_INT: + case ARG_SHORT: if (val && !(stop_char && *stop_char == '\0')) { fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); return 1; /* failure */ @@ -1050,8 +1050,8 @@ void update_multiple_arg(void *field, char ***orig_field, *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); switch(arg_type) { - case ARG_INT: - *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break; + case ARG_SHORT: + *((short **)field) = (short *)realloc (*((short **)field), (field_given + prev_given) * sizeof (short)); break; case ARG_STRING: *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break; default: @@ -1063,8 +1063,8 @@ void update_multiple_arg(void *field, char ***orig_field, tmp = list; switch(arg_type) { - case ARG_INT: - (*((int **)field))[i + field_given] = tmp->arg.int_arg; break; + case ARG_SHORT: + (*((short **)field))[i + field_given] = tmp->arg.short_arg; break; case ARG_STRING: (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break; default: @@ -1077,10 +1077,10 @@ void update_multiple_arg(void *field, char ***orig_field, } else { /* set the default value */ if (default_value && ! field_given) { switch(arg_type) { - case ARG_INT: - if (! *((int **)field)) { - *((int **)field) = (int *)malloc (sizeof (int)); - (*((int **)field))[0] = default_value->int_arg; + case ARG_SHORT: + if (! *((short **)field)) { + *((short **)field) = (short *)malloc (sizeof (short)); + (*((short **)field))[0] = default_value->short_arg; } break; case ARG_STRING: @@ -1404,7 +1404,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&read_dg_list, - &(local_args_info.read_dg_given), optarg, 0, 0, ARG_INT, + &(local_args_info.read_dg_given), optarg, 0, 0, ARG_SHORT, "read-dg", '-', additional_error)) goto failure; @@ -1428,7 +1428,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&write_dg_list, - &(local_args_info.write_dg_given), optarg, 0, 0, ARG_INT, + &(local_args_info.write_dg_given), optarg, 0, 0, ARG_SHORT, "write-dg", '-', additional_error)) goto failure; @@ -1452,7 +1452,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&delete_dg_list, - &(local_args_info.delete_dg_given), optarg, 0, 0, ARG_INT, + &(local_args_info.delete_dg_given), optarg, 0, 0, ARG_SHORT, "delete-dg", '-', additional_error)) goto failure; @@ -1464,7 +1464,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&create_dg_list, - &(local_args_info.create_dg_given), optarg, 0, 0, ARG_INT, + &(local_args_info.create_dg_given), optarg, 0, 0, ARG_SHORT, "create-dg", '-', additional_error)) goto failure; @@ -1478,7 +1478,7 @@ cmdline_parser_internal ( if (update_arg( (void *)&(args_info->new_size_arg), &(args_info->new_size_orig), &(args_info->new_size_given), - &(local_args_info.new_size_given), optarg, 0, "256", ARG_INT, + &(local_args_info.new_size_given), optarg, 0, "256", ARG_SHORT, check_ambiguity, override, 0, 0, "new-size", '-', additional_error)) @@ -1506,7 +1506,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&new_read_ac_chatbit_list, - &(local_args_info.new_read_ac_chatbit_given), optarg, 0, 0, ARG_INT, + &(local_args_info.new_read_ac_chatbit_given), optarg, 0, 0, ARG_SHORT, "new-read-ac-chatbit", '-', additional_error)) goto failure; @@ -1533,7 +1533,7 @@ cmdline_parser_internal ( args_info->pxs_mode_counter += 1; if (update_multiple_arg_temp(&new_write_ac_chatbit_list, - &(local_args_info.new_write_ac_chatbit_given), optarg, 0, 0, ARG_INT, + &(local_args_info.new_write_ac_chatbit_given), optarg, 0, 0, ARG_SHORT, "new-write-ac-chatbit", '-', additional_error)) goto failure; @@ -1559,7 +1559,7 @@ cmdline_parser_internal ( update_multiple_arg((void *)&(args_info->read_dg_arg), &(args_info->read_dg_orig), args_info->read_dg_given, local_args_info.read_dg_given, 0, - ARG_INT, read_dg_list); + ARG_SHORT, read_dg_list); update_multiple_arg((void *)&(args_info->out_file_arg), &(args_info->out_file_orig), args_info->out_file_given, local_args_info.out_file_given, 0, @@ -1567,7 +1567,7 @@ cmdline_parser_internal ( update_multiple_arg((void *)&(args_info->write_dg_arg), &(args_info->write_dg_orig), args_info->write_dg_given, local_args_info.write_dg_given, 0, - ARG_INT, write_dg_list); + ARG_SHORT, write_dg_list); update_multiple_arg((void *)&(args_info->in_file_arg), &(args_info->in_file_orig), args_info->in_file_given, local_args_info.in_file_given, 0, @@ -1575,19 +1575,19 @@ cmdline_parser_internal ( update_multiple_arg((void *)&(args_info->delete_dg_arg), &(args_info->delete_dg_orig), args_info->delete_dg_given, local_args_info.delete_dg_given, 0, - ARG_INT, delete_dg_list); + ARG_SHORT, delete_dg_list); update_multiple_arg((void *)&(args_info->create_dg_arg), &(args_info->create_dg_orig), args_info->create_dg_given, local_args_info.create_dg_given, 0, - ARG_INT, create_dg_list); + ARG_SHORT, create_dg_list); update_multiple_arg((void *)&(args_info->new_read_ac_chatbit_arg), &(args_info->new_read_ac_chatbit_orig), args_info->new_read_ac_chatbit_given, local_args_info.new_read_ac_chatbit_given, 0, - ARG_INT, new_read_ac_chatbit_list); + ARG_SHORT, new_read_ac_chatbit_list); update_multiple_arg((void *)&(args_info->new_write_ac_chatbit_arg), &(args_info->new_write_ac_chatbit_orig), args_info->new_write_ac_chatbit_given, local_args_info.new_write_ac_chatbit_given, 0, - ARG_INT, new_write_ac_chatbit_list); + ARG_SHORT, new_write_ac_chatbit_list); args_info->verbose_given += local_args_info.verbose_given; local_args_info.verbose_given = 0; diff --git a/src/tools/goid-tool-cmdline.h b/src/tools/goid-tool-cmdline.h index 3aec314753..50002c6a7f 100644 --- a/src/tools/goid-tool-cmdline.h +++ b/src/tools/goid-tool-cmdline.h @@ -69,7 +69,7 @@ struct gengetopt_args_info char * write_paccessid_arg; /**< @brief Write the specified PAccess ID. */ char * write_paccessid_orig; /**< @brief Write the specified PAccess ID original value given at command line. */ const char *write_paccessid_help; /**< @brief Write the specified PAccess ID help description. */ - int* read_dg_arg; /**< @brief Read the specified data group; use several times to read out multiple files. */ + short* read_dg_arg; /**< @brief Read the specified data group; use several times to read out multiple files. */ char ** read_dg_orig; /**< @brief Read the specified data group; use several times to read out multiple files original value given at command line. */ unsigned int read_dg_min; /**< @brief Read the specified data group; use several times to read out multiple files's minimum occurreces */ unsigned int read_dg_max; /**< @brief Read the specified data group; use several times to read out multiple files's maximum occurreces */ @@ -79,7 +79,7 @@ struct gengetopt_args_info unsigned int out_file_min; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg''s minimum occurreces */ unsigned int out_file_max; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg''s maximum occurreces */ const char *out_file_help; /**< @brief Write output to a file instead of printing it; use once for each use of `--read-dg' help description. */ - int* write_dg_arg; /**< @brief Write the specified data group; use several times to write multiple files. */ + short* write_dg_arg; /**< @brief Write the specified data group; use several times to write multiple files. */ char ** write_dg_orig; /**< @brief Write the specified data group; use several times to write multiple files original value given at command line. */ unsigned int write_dg_min; /**< @brief Write the specified data group; use several times to write multiple files's minimum occurreces */ unsigned int write_dg_max; /**< @brief Write the specified data group; use several times to write multiple files's maximum occurreces */ @@ -89,23 +89,23 @@ struct gengetopt_args_info unsigned int in_file_min; /**< @brief Read input from a file; use once for each use of `--write-dg''s minimum occurreces */ unsigned int in_file_max; /**< @brief Read input from a file; use once for each use of `--write-dg''s maximum occurreces */ const char *in_file_help; /**< @brief Read input from a file; use once for each use of `--write-dg' help description. */ - int* delete_dg_arg; /**< @brief Delete the specified data group; use several times to delete multiple files. */ + short* delete_dg_arg; /**< @brief Delete the specified data group; use several times to delete multiple files. */ char ** delete_dg_orig; /**< @brief Delete the specified data group; use several times to delete multiple files original value given at command line. */ unsigned int delete_dg_min; /**< @brief Delete the specified data group; use several times to delete multiple files's minimum occurreces */ unsigned int delete_dg_max; /**< @brief Delete the specified data group; use several times to delete multiple files's maximum occurreces */ const char *delete_dg_help; /**< @brief Delete the specified data group; use several times to delete multiple files help description. */ - int* create_dg_arg; /**< @brief Create the specified data group; use several times to create multiple files. */ + short* create_dg_arg; /**< @brief Create the specified data group; use several times to create multiple files. */ char ** create_dg_orig; /**< @brief Create the specified data group; use several times to create multiple files original value given at command line. */ unsigned int create_dg_min; /**< @brief Create the specified data group; use several times to create multiple files's minimum occurreces */ unsigned int create_dg_max; /**< @brief Create the specified data group; use several times to create multiple files's maximum occurreces */ const char *create_dg_help; /**< @brief Create the specified data group; use several times to create multiple files help description. */ - int new_size_arg; /**< @brief File size of newly created DGs (default='256'). */ + short new_size_arg; /**< @brief File size of newly created DGs (default='256'). */ char * new_size_orig; /**< @brief File size of newly created DGs original value given at command line. */ const char *new_size_help; /**< @brief File size of newly created DGs help description. */ char * new_read_ac_arg; /**< @brief Access condition for reading newly created DGs (default='sm'). */ char * new_read_ac_orig; /**< @brief Access condition for reading newly created DGs original value given at command line. */ const char *new_read_ac_help; /**< @brief Access condition for reading newly created DGs help description. */ - int* new_read_ac_chatbit_arg; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs. */ + short* new_read_ac_chatbit_arg; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs. */ char ** new_read_ac_chatbit_orig; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs original value given at command line. */ unsigned int new_read_ac_chatbit_min; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs's minimum occurreces */ unsigned int new_read_ac_chatbit_max; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs's maximum occurreces */ @@ -113,7 +113,7 @@ struct gengetopt_args_info char * new_write_ac_arg; /**< @brief Access condition for writing newly created DGs (default='sm'). */ char * new_write_ac_orig; /**< @brief Access condition for writing newly created DGs original value given at command line. */ const char *new_write_ac_help; /**< @brief Access condition for writing newly created DGs help description. */ - int* new_write_ac_chatbit_arg; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs. */ + short* new_write_ac_chatbit_arg; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs. */ char ** new_write_ac_chatbit_orig; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs original value given at command line. */ unsigned int new_write_ac_chatbit_min; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs's minimum occurreces */ unsigned int new_write_ac_chatbit_max; /**< @brief Required access bit in certificate's CHAT for reading newly created DGs's maximum occurreces */ diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index c4a11475d9..619bf742af 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -453,7 +453,7 @@ paccess_delete_file(struct sc_card *card, int fid) } int -paccess_get_security_attributes(struct sc_context *ctx, const char *ac, int* chatbits, size_t chatbits_len, u8 sec_attr[2]) +paccess_get_security_attributes(struct sc_context *ctx, const char *ac, short* chatbits, size_t chatbits_len, u8 sec_attr[2]) { int ok = 0; memset(sec_attr, 0, 2); diff --git a/src/tools/goid-tool.ggo.in b/src/tools/goid-tool.ggo.in index fcf3a05b15..7d8b126cce 100644 --- a/src/tools/goid-tool.ggo.in +++ b/src/tools/goid-tool.ggo.in @@ -49,37 +49,37 @@ modeoption "write-paccessid" - string mode="pxs" optional typestr="PACCESSID" modeoption "read-dg" - "Read the specified data group; use several times to read out multiple files" - int mode="pxs" optional multiple typestr="ID" + short mode="pxs" optional multiple typestr="ID" modeoption "out-file" - "Write output to a file instead of printing it; use once for each use of `--read-dg'" string mode="pxs" optional multiple typestr="FILENAME" modeoption "write-dg" - "Write the specified data group; use several times to write multiple files" - int mode="pxs" optional multiple typestr="ID" + short mode="pxs" optional multiple typestr="ID" modeoption "in-file" - "Read input from a file; use once for each use of `--write-dg'" string mode="pxs" optional multiple typestr="FILENAME" modeoption "delete-dg" - "Delete the specified data group; use several times to delete multiple files" - int mode="pxs" optional multiple typestr="ID" + short mode="pxs" optional multiple typestr="ID" modeoption "create-dg" - "Create the specified data group; use several times to create multiple files" - int mode="pxs" optional multiple typestr="ID" + short mode="pxs" optional multiple typestr="ID" modeoption "new-size" - "File size of newly created DGs" - int mode="pxs" optional dependon="create-dg" typestr="SIZE" default="256" + short mode="pxs" optional dependon="create-dg" typestr="SIZE" default="256" modeoption "new-read-ac" - "Access condition for reading newly created DGs" values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" modeoption "new-read-ac-chatbit" - "Required access bit in certificate's CHAT for reading newly created DGs" - int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" + short mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" modeoption "new-write-ac" - "Access condition for writing newly created DGs" values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" modeoption "new-write-ac-chatbit" - "Required access bit in certificate's CHAT for reading newly created DGs" - int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" + short mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" text " Report bugs to @PACKAGE_BUGREPORT@ From d18c0b32161672d5f5b34446c2c8d3872b9da3e6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 10 Mar 2024 01:34:20 +0100 Subject: [PATCH 3592/4321] fixed dtrust-tool build (extension) --- src/tools/Makefile.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index b2682727d2..f8d5032cbe 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -6,7 +6,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ - opensc-notify.exe egk-tool.exe goid-tool.exe dtrust-tool paccess-tool.exe \ + opensc-notify.exe egk-tool.exe goid-tool.exe dtrust-tool.exe \ opensc-asn1.exe pkcs11-register.exe $(PROGRAMS_OPENSSL) $(PROGRAMS_OPENPACE) OBJECTS = util.obj versioninfo-tools.res From cae5fe4cddb6e827a8251175cf5e2066884af3fb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 10 Mar 2024 02:26:11 +0100 Subject: [PATCH 3593/4321] fixed formatting --- src/tools/goid-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index 619bf742af..c8bdf6f63e 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -453,7 +453,7 @@ paccess_delete_file(struct sc_card *card, int fid) } int -paccess_get_security_attributes(struct sc_context *ctx, const char *ac, short* chatbits, size_t chatbits_len, u8 sec_attr[2]) +paccess_get_security_attributes(struct sc_context *ctx, const char *ac, short *chatbits, size_t chatbits_len, u8 sec_attr[2]) { int ok = 0; memset(sec_attr, 0, 2); From fabadaa7537f8575722e345a9d5f9e24885178fc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 10 Sep 2024 09:57:23 +0200 Subject: [PATCH 3594/4321] XDG autostart: launch pkcs11-register WITH Firefox and Chrome initialization this is disabled by default due to Windows/macOS defaults. Note that autostart can completely be disabled by using ./configure --disable-autostart-items --- src/tools/pkcs11-register.desktop.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-register.desktop.in b/src/tools/pkcs11-register.desktop.in index ea6a514081..0f350d33ef 100644 --- a/src/tools/pkcs11-register.desktop.in +++ b/src/tools/pkcs11-register.desktop.in @@ -1,7 +1,7 @@ [Desktop Entry] Name=Install OpenSC PKCS#11 module Type=Application -Exec=@bindir@/pkcs11-register +Exec=@bindir@/pkcs11-register --skip-chrome=off --skip-firefox=off Categories=Security;System; X-GNOME-AutoRestart=true X-GNOME-Autostart-Phase=Initialization From 67929fc307d204b4d2c7ba9073d793f4451d0511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 11 Sep 2024 14:29:14 +0200 Subject: [PATCH 3595/4321] Fix spelling error --- src/tools/goid-tool-cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/goid-tool-cmdline.c b/src/tools/goid-tool-cmdline.c index 459e10e2f6..f87b986da9 100644 --- a/src/tools/goid-tool-cmdline.c +++ b/src/tools/goid-tool-cmdline.c @@ -428,7 +428,7 @@ check_possible_values(const char *val, const char *values[]) ++found; last = i; if (strlen(values[i]) == len) - return i; /* exact macth no need to check more */ + return i; /* exact match no need to check more */ } } From 7f7e5dd262e0aeea45ced672783c5335c768aa8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 28 Aug 2024 10:18:28 +0200 Subject: [PATCH 3596/4321] OpenSC 0.26.0-rc1 --- .appveyor.yml | 2 +- NEWS | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 12 ++++----- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 00a40da197..bce960249f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.25.1.{build} +version: 0.26.0.{build} platform: - x86 diff --git a/NEWS b/NEWS index 828a40cadd..46764e04b2 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,78 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.26.0; 2024-09-11 + +## Security +* CVE-2024-45615: Usage of uninitialized values in libopensc and pkcs15init (#3225) +* CVE-2024-45616: Uninitialized values after incorrect check or usage of APDU response values in libopensc (#3225) +* CVE-2024-45617: Uninitialized values after incorrect or missing checking return values of functions in libopensc (#3225) +* CVE-2024-45618: Uninitialized values after incorrect or missing checking return values of functions in pkcs15init (#3225) +* CVE-2024-45619: Incorrect handling length of buffers or files in libopensc (#3225) +* CVE-2024-45620: Incorrect handling of the length of buffers or files in pkcs15init (#3225) +* CVE-2024-8443: Heap buffer overflow in OpenPGP driver when generating key (#3219) + +## General improvements +* Fix reselection of DF after error in PKCS#15 layer (#3067) +* Unify OpenSSL logging throughout code (#2922) +* Extend the p11test to support kryoptic (#3141) +* Fix for error in PCSC reconnection (#3150) +* Fixed various issues reported by OSS-Fuzz and Coverity in drivers, PKCS#11 and PKCS#15 layer + +## PKCS#15 +* Documentation for PKCS#15 profile files (#3132) + +## minidriver +* Support PinCacheAlwaysPrompt usable for PIV cards (#3167) + +## pkcs11-tool +* Show URI when listing token information (#3125) and objects (#3130) +* Do not limit size of objects to 5000 bytes (#3174) +* Add support for AES CMAC (#3184) +* Add support for Add support for AES GCM encryption (#3195) +* Add support for RSA OAEP encryption (#3175) +* Add support for HKDF (#3193) +* Implement better support for wrapping and unwrapping (#3198) +* Add support for EdDSA sign and verify (#2979) + +## pkcs15-crypt +* Fix PKCS#1 encoding function to correctly detect padding type (#3075) + +## piv-tool +* Fix RSA key generation (#3158) +* Avoid possible state change when matching unknown card (#3112) + +## sc-hsm-tool +* Cleanse buffer with plaintext key share (#3226) + +## pkcs11-register +* Fix pkcs11-register defaults on macOS and Windows (#3053) + +## IDPrime +* Fix identification of IDPrime 840 cards (#3146) +* Fix container mapping for IDPrime 940 cards (#3220) +* Reorder ATRs for matching cards (#3154) + +## OpenPGP +* Fix state tracking after erasing card (#3024) + +## Belpic +* Disable Applet V1.8 (#3109) + +## MICARDO +* Deactivate driver (#3152) + +## SmartCard-HSM +* Fix signing with secp521r1 signature (#3157) + +## eOI +* Set model via `sc_card_ctl` function (#3189) + +## Rutoken +* increase the minimum PIN size to support Rutoken ECP BIO (#3208) + +# JPKI +* Adjust parameters for public key in PKCS#15 emulator (#3182) + # New in 0.25.1; 2024-04-05 ## General improvements diff --git a/configure.ac b/configure.ac index e06b0d818b..e27d50da71 100644 --- a/configure.ac +++ b/configure.ac @@ -7,9 +7,9 @@ define([PRODUCT_TARNAME], [opensc]) define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [25]) -define([PACKAGE_VERSION_FIX], [1]) -define([PACKAGE_SUFFIX], []) +define([PACKAGE_VERSION_MINOR], [26]) +define([PACKAGE_VERSION_FIX], [0]) +define([PACKAGE_SUFFIX], [-rc1]) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) @@ -46,9 +46,9 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Code changed: REVISION++) # (Oldest interface changed/removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) -OPENSC_LT_CURRENT="11" -OPENSC_LT_OLDEST="11" -OPENSC_LT_REVISION="2" +OPENSC_LT_CURRENT="12" +OPENSC_LT_OLDEST="12" +OPENSC_LT_REVISION="0" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libopensc/sc.c]) From e8a693c76db6b1b3d66e32984de7bf743a9ea699 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Tue, 1 Oct 2024 15:54:19 +0200 Subject: [PATCH 3597/4321] Add PKCS#15 emulation for D-Trust Card * dtrust: add PKCS#15 emulation --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/pkcs15-dtrust.c | 105 ++++++++++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 6 ++ src/libopensc/pkcs15-syn.h | 1 + 5 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 src/libopensc/pkcs15-dtrust.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index ffce861b2c..08ce281e7c 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -58,7 +58,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c compression.c sm.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c pkcs15-dtrust.c compression.c sm.c \ aux-data.c if ENABLE_CRYPTOTOKENKIT @@ -140,7 +140,7 @@ TIDY_FILES = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c pkcs15-skeid.c compression.c sm.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-dtrust.c compression.c sm.c \ aux-data.c \ #$(SOURCES) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 588c013287..21e45cbf35 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -36,8 +36,8 @@ OBJECTS = \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ - pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj compression.obj sm.obj \ - aux-data.obj \ + pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj pkcs15-dtrust.obj \ + compression.obj sm.obj aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\common\common.lib \ diff --git a/src/libopensc/pkcs15-dtrust.c b/src/libopensc/pkcs15-dtrust.c new file mode 100644 index 0000000000..b534521b7c --- /dev/null +++ b/src/libopensc/pkcs15-dtrust.c @@ -0,0 +1,105 @@ +/* + * PKCS15 emulation layer for D-Trust card. + * + * Copyright (C) 2024, Mario Haustein + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "internal.h" +#include "pkcs15.h" + +static int +_dtrust_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) +{ + struct sc_context *ctx = p15card->card->ctx; + struct sc_pkcs15_object *pkobjs[32]; + struct sc_pkcs15_prkey_info *prkey_info; + int rv, i, count; + + LOG_FUNC_CALLED(ctx); + + if (!df) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + + if (df->enumerated) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + + rv = sc_pkcs15_parse_df(p15card, df); + LOG_TEST_RET(ctx, rv, "DF parse error"); + + if (df->type != SC_PKCS15_PRKDF) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + + switch (p15card->card->type) { + /* Cards with EC keys, don't encode the curve size in the + * private key directory file. We need to set the field_length + * element after parsing the private key directory file. */ + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, pkobjs, sizeof(pkobjs) / sizeof(pkobjs[0])); + LOG_TEST_RET(ctx, rv, "Cannot get PRKEY objects list"); + + count = rv; + for (i = 0; i < count; i++) { + prkey_info = (struct sc_pkcs15_prkey_info *)pkobjs[i]->data; + prkey_info->field_length = 256; + } + break; + } + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + +static int +dtrust_pkcs15emu_detect_card(sc_pkcs15_card_t *p15card) +{ + if (p15card->card->type < SC_CARD_TYPE_DTRUST_V4_1_STD) + return SC_ERROR_WRONG_CARD; + + if (p15card->card->type > SC_CARD_TYPE_DTRUST_V4_4_MULTI) + return SC_ERROR_WRONG_CARD; + + return SC_SUCCESS; +} + +static int +sc_pkcs15emu_dtrust_init(struct sc_pkcs15_card *p15card, struct sc_aid *aid) +{ + struct sc_context *ctx = p15card->card->ctx; + int rv; + + LOG_FUNC_CALLED(ctx); + + rv = sc_pkcs15_bind_internal(p15card, aid); + + p15card->ops.parse_df = _dtrust_parse_df; + + LOG_FUNC_RETURN(ctx, rv); +} + +int +sc_pkcs15emu_dtrust_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) +{ + if (dtrust_pkcs15emu_detect_card(p15card)) + return SC_ERROR_WRONG_CARD; + + return sc_pkcs15emu_dtrust_init(p15card, aid); +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index dabbc87559..3fe0914493 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -61,6 +61,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, { "esign", sc_pkcs15emu_starcos_esign_init_ex }, { "eOI", sc_pkcs15emu_eoi_init_ex }, + { "dtrust", sc_pkcs15emu_dtrust_init_ex }, { NULL, NULL } }; @@ -113,6 +114,11 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_SKEID_V3: case SC_CARD_TYPE_EOI: case SC_CARD_TYPE_EOI_CONTACTLESS: + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: return 1; default: return 0; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index f598766684..f931409964 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -56,6 +56,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_eoi_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_dtrust_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From f7070f4c9f9c6e1cb8d2efe838f73d54c78553da Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 18 Sep 2024 09:47:31 +0200 Subject: [PATCH 3598/4321] Add support for ECC signatures on D-Trust Card 4.1 & 4.4 * dtrust: implement ECDSA signature closes #3236 --- src/libopensc/card-dtrust.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 646e6ea331..5c53867602 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -256,12 +256,10 @@ dtrust_init(sc_card_t *card) r = SC_SUCCESS; break; - /* Untested due to lacking hardware */ case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: - flags |= SC_ALGORITHM_ECDH_CDH_RAW; - flags |= SC_ALGORITHM_ECDSA_HASH_SHA256; + flags |= SC_ALGORITHM_ECDSA_RAW; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; for (unsigned int i = 0; dtrust_curves[i].oid.value[0] >= 0; i++) { _sc_card_add_ec_alg(card, dtrust_curves[i].size, flags, ext_flags, &dtrust_curves[i].oid); @@ -372,6 +370,8 @@ dtrust_set_security_env(sc_card_t *card, default: return SC_ERROR_NOT_SUPPORTED; } + } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { + se_num = 0x21; } else { return SC_ERROR_NOT_SUPPORTED; } From 0731c9629266de6c2c2fc5b8dfd8b13745c24845 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 16 Oct 2024 10:19:34 +0200 Subject: [PATCH 3599/4321] Add support for ECC decryption on D-Trust Card 4.1 & 4.4 * dtrust: implement ECDH key agreement --- src/libopensc/card-dtrust.c | 109 ++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 5c53867602..2a274691b4 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -70,6 +70,27 @@ static struct dtrust_supported_ec_curves { }; // clang-format on +/* copied from iso7816.c */ +static void +fixup_transceive_length(const struct sc_card *card, + struct sc_apdu *apdu) +{ + if (card == NULL || apdu == NULL) { + return; + } + + if (apdu->lc > sc_get_max_send_size(card)) { + /* The lower layers will automatically do chaining */ + apdu->flags |= SC_APDU_FLAGS_CHAINING; + } + + if (apdu->le > sc_get_max_recv_size(card)) { + /* The lower layers will automatically do a GET RESPONSE, if possible. + * All other workarounds must be carried out by the upper layers. */ + apdu->le = sc_get_max_recv_size(card); + } +} + static int _dtrust_match_cardos(sc_card_t *card) { @@ -259,6 +280,7 @@ dtrust_init(sc_card_t *card) case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + flags |= SC_ALGORITHM_ECDH_CDH_RAW; flags |= SC_ALGORITHM_ECDSA_RAW; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; for (unsigned int i = 0; dtrust_curves[i].oid.value[0] >= 0; i++) { @@ -377,6 +399,14 @@ dtrust_set_security_env(sc_card_t *card, } break; + case SC_SEC_OPERATION_DERIVE: + if (env->algorithm_flags & SC_ALGORITHM_ECDH_CDH_RAW) { + se_num = 0x39; + } else { + return SC_ERROR_NOT_SUPPORTED; + } + break; + default: return SC_ERROR_NOT_SUPPORTED; } @@ -438,6 +468,84 @@ dtrust_compute_signature(struct sc_card *card, const u8 *data, return r; } +static int +_dtrust_compute_shared_value(struct sc_card *card, + const u8 *crgram, size_t crgram_len, + u8 *out, size_t outlen) +{ + int r; + struct sc_apdu apdu; + u8 *sbuf = NULL; + + if (card == NULL || crgram == NULL || out == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "CardOS compute shared value: in-len %" SC_FORMAT_LEN_SIZE_T "u, out-len %" SC_FORMAT_LEN_SIZE_T "u", crgram_len, outlen); + + /* Ensure public key is provided in uncompressed format (indicator byte + * 0x04 followed by X and Y coordinate. */ + if (crgram_len % 2 == 0 || crgram[0] != 0x04) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + /* strip indicator byte */ + crgram++; + crgram_len--; + + sbuf = malloc(crgram_len + 2); + if (sbuf == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x80 Resp: Plain value + * P2: 0xA6 Cmd: Control reference template for key agreement */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0xA6); + apdu.resp = out; + apdu.resplen = outlen; + apdu.le = outlen; + + sbuf[0] = 0x9c; /* context specific ASN.1 tag */ + sbuf[1] = crgram_len; + memcpy(sbuf + 2, crgram, crgram_len); + apdu.data = sbuf; + apdu.lc = crgram_len + 2; + apdu.datalen = crgram_len + 2; + + fixup_transceive_length(card, &apdu); + r = sc_transmit_apdu(card, &apdu); + sc_mem_clear(sbuf, crgram_len + 2); + free(sbuf); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); + else + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} + +static int +dtrust_decipher(struct sc_card *card, const u8 *data, + size_t data_len, u8 *out, size_t outlen) +{ + switch (card->type) { + /* No special handling necessary for RSA cards. */ + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + LOG_FUNC_RETURN(card->ctx, iso_ops->decipher(card, data, data_len, out, outlen)); + + /* Elliptic Curve cards cannot use PSO:DECIPHER command and need to + * perform key agreement by a CardOS specific command. */ + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + LOG_FUNC_RETURN(card->ctx, _dtrust_compute_shared_value(card, data, data_len, out, outlen)); + + default: + return SC_ERROR_NOT_SUPPORTED; + } +} + static int dtrust_logout(sc_card_t *card) { @@ -462,6 +570,7 @@ sc_get_dtrust_driver(void) dtrust_ops.finish = dtrust_finish; dtrust_ops.set_security_env = dtrust_set_security_env; dtrust_ops.compute_signature = dtrust_compute_signature; + dtrust_ops.decipher = dtrust_decipher; dtrust_ops.logout = dtrust_logout; return &dtrust_drv; From 3b650102d3c127ae48b8a1aee38400077d0ac934 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 16 Oct 2024 16:04:19 +0200 Subject: [PATCH 3600/4321] dtrust: add more tracing messages --- src/libopensc/card-dtrust.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 2a274691b4..4fa8521435 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -312,6 +312,8 @@ dtrust_set_security_env(sc_card_t *card, { struct dtrust_drv_data_t *drv_data; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (card == NULL || env == NULL) return SC_ERROR_INVALID_ARGUMENTS; @@ -424,6 +426,8 @@ dtrust_compute_signature(struct sc_card *card, const u8 *data, u8 *buf = NULL; int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; flags = drv_data->env->algorithm_flags; @@ -528,6 +532,8 @@ static int dtrust_decipher(struct sc_card *card, const u8 *data, size_t data_len, u8 *out, size_t outlen) { + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + switch (card->type) { /* No special handling necessary for RSA cards. */ case SC_CARD_TYPE_DTRUST_V4_1_STD: From 548ce105d020e21bf2f89f62ccaebd4040262772 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Fri, 18 Oct 2024 17:15:51 +0200 Subject: [PATCH 3601/4321] iso7816.c: make fixup_transceive_length() public The code of `fixup_transceive_length()` was duplicated multiple times in the code. Make this function public and remove duplicated code to improve maintainability. --- src/libopensc/card-cardos.c | 22 +--------------------- src/libopensc/card-dtrust.c | 23 +---------------------- src/libopensc/card-gids.c | 21 +-------------------- src/libopensc/iso7816.c | 22 +++++++++++----------- src/libopensc/opensc.h | 12 ++++++++++++ 5 files changed, 26 insertions(+), 74 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 595ec099e3..2e9e59f06e 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -72,26 +72,6 @@ typedef struct cardos_data { const sc_security_env_t * sec_env; } cardos_data_t; -/* copied from iso7816.c */ -static void fixup_transceive_length(const struct sc_card *card, - struct sc_apdu *apdu) -{ - if (card == NULL || apdu == NULL) { - return; - } - - if (apdu->lc > sc_get_max_send_size(card)) { - /* The lower layers will automatically do chaining */ - apdu->flags |= SC_APDU_FLAGS_CHAINING; - } - - if (apdu->le > sc_get_max_recv_size(card)) { - /* The lower layers will automatically do a GET RESPONSE, if possible. - * All other workarounds must be carried out by the upper layers. */ - apdu->le = sc_get_max_recv_size(card); - } -} - static int cardos_match_card(sc_card_t *card) { unsigned char atr[SC_MAX_ATR_SIZE] = {0}; @@ -1080,7 +1060,7 @@ do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, apdu.data = data; apdu.lc = datalen; apdu.datalen = datalen; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 4fa8521435..3932a61183 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -70,27 +70,6 @@ static struct dtrust_supported_ec_curves { }; // clang-format on -/* copied from iso7816.c */ -static void -fixup_transceive_length(const struct sc_card *card, - struct sc_apdu *apdu) -{ - if (card == NULL || apdu == NULL) { - return; - } - - if (apdu->lc > sc_get_max_send_size(card)) { - /* The lower layers will automatically do chaining */ - apdu->flags |= SC_APDU_FLAGS_CHAINING; - } - - if (apdu->le > sc_get_max_recv_size(card)) { - /* The lower layers will automatically do a GET RESPONSE, if possible. - * All other workarounds must be carried out by the upper layers. */ - apdu->le = sc_get_max_recv_size(card); - } -} - static int _dtrust_match_cardos(sc_card_t *card) { @@ -516,7 +495,7 @@ _dtrust_compute_shared_value(struct sc_card *card, apdu.lc = crgram_len + 2; apdu.datalen = crgram_len + 2; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, crgram_len + 2); free(sbuf); diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 5fb0d4acb4..cce235b8a4 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -155,25 +155,6 @@ struct gids_private_data { size_t buffersize; }; -static void fixup_transceive_length(const struct sc_card *card, - struct sc_apdu *apdu) -{ - if (card == NULL || apdu == NULL) { - return; - } - - if (apdu->lc > sc_get_max_send_size(card)) { - /* The lower layers will automatically do chaining */ - apdu->flags |= SC_APDU_FLAGS_CHAINING; - } - - if (apdu->le > sc_get_max_recv_size(card)) { - /* The lower layers will automatically do a GET RESPONSE, if possible. - * All other workarounds must be carried out by the upper layers. */ - apdu->le = sc_get_max_recv_size(card); - } -} - // LOW LEVEL API /////////////////////////////////////////// @@ -879,7 +860,7 @@ gids_decipher(struct sc_card *card, apdu.lc = crgram_len; apdu.datalen = crgram_len; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index d7e044993c..e17549cd18 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -30,8 +30,8 @@ #include "iso7816.h" #include "sm/sm-iso.h" - -static void fixup_transceive_length(const struct sc_card *card, +void +iso7816_fixup_transceive_length(const struct sc_card *card, struct sc_apdu *apdu) { if (card == NULL || apdu == NULL) { @@ -152,7 +152,7 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun apdu.resplen = count; apdu.resp = buf; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); @@ -254,7 +254,7 @@ iso7816_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -295,7 +295,7 @@ iso7816_write_record(struct sc_card *card, unsigned int rec_nr, if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -318,7 +318,7 @@ iso7816_append_record(struct sc_card *card, apdu.data = buf; apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -358,7 +358,7 @@ iso7816_update_record(struct sc_card *card, unsigned int rec_nr, unsigned int id if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -388,7 +388,7 @@ iso7816_write_binary(struct sc_card *card, apdu.datalen = count; apdu.data = buf; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -415,7 +415,7 @@ iso7816_update_binary(struct sc_card *card, apdu.datalen = count; apdu.data = buf; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1114,7 +1114,7 @@ iso7816_compute_signature(struct sc_card *card, apdu.lc = datalen; apdu.datalen = datalen; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) @@ -1162,7 +1162,7 @@ iso7816_decipher(struct sc_card *card, apdu.lc = crgram_len + 1; apdu.datalen = crgram_len + 1; - fixup_transceive_length(card, &apdu); + iso7816_fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, crgram_len + 1); free(sbuf); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 97659527af..5f1c99f6e4 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1673,6 +1673,18 @@ extern const char *sc_get_version(void); extern sc_card_driver_t *sc_get_iso7816_driver(void); +/* + * @brief Request command chaining if needed. + * + * @param[in] card card + * @param[in,out] apdu apdu structure to update + * + * @note Checks if the command payload or the expected response fits into the + * card transceive buffer. It requests command chaining from the lower levels + * if the data length exceeds the buffer size. + */ +void iso7816_fixup_transceive_length(const struct sc_card *card, struct sc_apdu *apdu); + /** * @brief Read a complete EF by short file identifier. * From 9eec0dc8ee2fb59258ead2d56cd13deb3b2dd99e Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 21 Oct 2024 15:19:19 +0200 Subject: [PATCH 3602/4321] card-cardos-common.c: move common CardOS function to a separate file --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-cardos-common.c | 85 ++++++++++++++++++++++++++++++ src/libopensc/card-cardos-common.h | 43 +++++++++++++++ src/libopensc/card-dtrust.c | 59 +-------------------- 5 files changed, 133 insertions(+), 60 deletions(-) create mode 100644 src/libopensc/card-cardos-common.c create mode 100644 src/libopensc/card-cardos-common.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 08ce281e7c..c3cec250fa 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -14,7 +14,7 @@ noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ jpki.h sc-ossl-compat.h card-npa.h card-openpgp.h \ card-eoi.h ccid-types.h reader-tr03119.h \ - card-cac-common.h + card-cac-common.h card-cardos-common.h AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ -D'DEFAULT_SM_MODULE_PATH="$(DEFAULT_SM_MODULE_PATH)"' \ @@ -38,7 +38,7 @@ libopensc_la_SOURCES_BASE = \ ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ \ card-setcos.c card-flex.c \ - card-cardos.c card-tcos.c card-default.c \ + card-cardos.c card-cardos-common.c card-tcos.c card-default.c \ card-mcrd.c card-starcos.c card-openpgp.c \ card-oberthur.c card-belpic.c card-atrust-acos.c \ card-entersafe.c card-epass2003.c card-coolkey.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 21e45cbf35..42179b2e34 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -15,7 +15,7 @@ OBJECTS = \ ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj reader-tr03119.obj \ \ card-setcos.obj card-flex.obj \ - card-cardos.obj card-tcos.obj card-default.obj \ + card-cardos.obj card-cardos-common.obj card-tcos.obj card-default.obj \ card-mcrd.obj card-starcos.obj card-openpgp.obj \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj \ card-entersafe.obj card-epass2003.obj card-coolkey.obj \ diff --git a/src/libopensc/card-cardos-common.c b/src/libopensc/card-cardos-common.c new file mode 100644 index 0000000000..d649f0cc59 --- /dev/null +++ b/src/libopensc/card-cardos-common.c @@ -0,0 +1,85 @@ +/* + * card-cardos-common.c: Common code for CardOS based cards + * + * Copyright (C) 2024 Mario Haustein + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "card-cardos-common.h" +#include "internal.h" + +int +cardos_ec_compute_shared_value(struct sc_card *card, + const u8 *crgram, size_t crgram_len, + u8 *out, size_t outlen) +{ + int r; + struct sc_apdu apdu; + u8 *sbuf = NULL; + + if (card == NULL || crgram == NULL || out == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "CardOS compute shared value: in-len %" SC_FORMAT_LEN_SIZE_T "u, out-len %" SC_FORMAT_LEN_SIZE_T "u", crgram_len, outlen); + + /* Ensure public key is provided in uncompressed format (indicator byte + * 0x04 followed by X and Y coordinate. */ + if (crgram_len % 2 == 0 || crgram[0] != 0x04) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + /* strip indicator byte */ + crgram++; + crgram_len--; + + sbuf = malloc(crgram_len + 2); + if (sbuf == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x80 Resp: Plain value + * P2: 0xA6 Cmd: Control reference template for key agreement */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0xA6); + apdu.resp = out; + apdu.resplen = outlen; + apdu.le = outlen; + + sbuf[0] = 0x9c; /* context specific ASN.1 tag */ + sbuf[1] = crgram_len; + memcpy(sbuf + 2, crgram, crgram_len); + apdu.data = sbuf; + apdu.lc = crgram_len + 2; + apdu.datalen = crgram_len + 2; + + iso7816_fixup_transceive_length(card, &apdu); + r = sc_transmit_apdu(card, &apdu); + sc_mem_clear(sbuf, crgram_len + 2); + free(sbuf); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); + else + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} diff --git a/src/libopensc/card-cardos-common.h b/src/libopensc/card-cardos-common.h new file mode 100644 index 0000000000..fbccc965c0 --- /dev/null +++ b/src/libopensc/card-cardos-common.h @@ -0,0 +1,43 @@ +/* + * card-cardos-common.c: Common code for CardOS based cards + * + * Copyright (C) 2024 Mario Haustein + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef HAVE_CARD_CARDOS_COMMON_H +#define HAVE_CARD_CARDOS_COMMON_H + +#include "libopensc/opensc.h" + +/** + * @brief compute a shared value from the peers public ECC key + * + * Key agreement on ECC keys requires a CardOS-specific command. + * + * @param card[in] struct sc_card object on which to issue the command + * @param crgram[in] public key point coordinates of the peer party in uncompressed format + * @param crgram_len[in] size of the public key point + * @param out[out] output buffer for the shared value + * @param outlen[in] size of the output buffer + * @return number of bytes of the shared value or an error code + */ +int +cardos_ec_compute_shared_value(struct sc_card *card, + const u8 *crgram, size_t crgram_len, + u8 *out, size_t outlen); + +#endif /* HAVE_CARD_CARDOS_COMMON_H */ diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 3932a61183..20c1870f62 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -28,6 +28,7 @@ #include #include "asn1.h" +#include "card-cardos-common.h" #include "internal.h" static const struct sc_card_operations *iso_ops = NULL; @@ -451,62 +452,6 @@ dtrust_compute_signature(struct sc_card *card, const u8 *data, return r; } -static int -_dtrust_compute_shared_value(struct sc_card *card, - const u8 *crgram, size_t crgram_len, - u8 *out, size_t outlen) -{ - int r; - struct sc_apdu apdu; - u8 *sbuf = NULL; - - if (card == NULL || crgram == NULL || out == NULL) { - return SC_ERROR_INVALID_ARGUMENTS; - } - LOG_FUNC_CALLED(card->ctx); - sc_log(card->ctx, "CardOS compute shared value: in-len %" SC_FORMAT_LEN_SIZE_T "u, out-len %" SC_FORMAT_LEN_SIZE_T "u", crgram_len, outlen); - - /* Ensure public key is provided in uncompressed format (indicator byte - * 0x04 followed by X and Y coordinate. */ - if (crgram_len % 2 == 0 || crgram[0] != 0x04) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - - /* strip indicator byte */ - crgram++; - crgram_len--; - - sbuf = malloc(crgram_len + 2); - if (sbuf == NULL) - return SC_ERROR_OUT_OF_MEMORY; - - /* INS: 0x2A PERFORM SECURITY OPERATION - * P1: 0x80 Resp: Plain value - * P2: 0xA6 Cmd: Control reference template for key agreement */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0xA6); - apdu.resp = out; - apdu.resplen = outlen; - apdu.le = outlen; - - sbuf[0] = 0x9c; /* context specific ASN.1 tag */ - sbuf[1] = crgram_len; - memcpy(sbuf + 2, crgram, crgram_len); - apdu.data = sbuf; - apdu.lc = crgram_len + 2; - apdu.datalen = crgram_len + 2; - - iso7816_fixup_transceive_length(card, &apdu); - r = sc_transmit_apdu(card, &apdu); - sc_mem_clear(sbuf, crgram_len + 2); - free(sbuf); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); - else - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); -} - static int dtrust_decipher(struct sc_card *card, const u8 *data, size_t data_len, u8 *out, size_t outlen) @@ -524,7 +469,7 @@ dtrust_decipher(struct sc_card *card, const u8 *data, case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: - LOG_FUNC_RETURN(card->ctx, _dtrust_compute_shared_value(card, data, data_len, out, outlen)); + LOG_FUNC_RETURN(card->ctx, cardos_ec_compute_shared_value(card, data, data_len, out, outlen)); default: return SC_ERROR_NOT_SUPPORTED; From cc367d3b11ca18d33026b4ce7e0ef714cc895017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 12 Nov 2024 14:56:19 +0100 Subject: [PATCH 3603/4321] card-dtrust: Fix NULL dereference before check Thanks Coverity CID 448878 --- src/libopensc/card-dtrust.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 20c1870f62..afba1866af 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -292,11 +292,11 @@ dtrust_set_security_env(sc_card_t *card, { struct dtrust_drv_data_t *drv_data; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card == NULL || env == NULL) return SC_ERROR_INVALID_ARGUMENTS; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; drv_data->env = env; From fe857cc4c68da4873071f168c9aaf9860040ff4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 12 Nov 2024 11:19:56 +0100 Subject: [PATCH 3604/4321] OpenSC 0.26.0 --- NEWS | 7 +++++-- configure.ac | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 46764e04b2..d60e82d7ea 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.26.0; 2024-09-11 +# New in 0.26.0; 2024-11-13 ## Security * CVE-2024-45615: Usage of uninitialized values in libopensc and pkcs15init (#3225) @@ -28,7 +28,7 @@ NEWS for OpenSC -- History of user visible changes * Show URI when listing token information (#3125) and objects (#3130) * Do not limit size of objects to 5000 bytes (#3174) * Add support for AES CMAC (#3184) -* Add support for Add support for AES GCM encryption (#3195) +* Add support for AES GCM encryption (#3195) * Add support for RSA OAEP encryption (#3175) * Add support for HKDF (#3193) * Implement better support for wrapping and unwrapping (#3198) @@ -73,6 +73,9 @@ NEWS for OpenSC -- History of user visible changes # JPKI * Adjust parameters for public key in PKCS#15 emulator (#3182) +# D-Trust +* Add support for ECDSA signatures and ECDH key agreement for D-Trust Signatures Cards 4.1/4.4 (#3240, #3248) + # New in 0.25.1; 2024-04-05 ## General improvements diff --git a/configure.ac b/configure.ac index e27d50da71..733bc58ab1 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [26]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc1]) +define([PACKAGE_SUFFIX], []) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) @@ -48,7 +48,7 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # (Interfaces added: CURRENT++, REVISION=0) OPENSC_LT_CURRENT="12" OPENSC_LT_OLDEST="12" -OPENSC_LT_REVISION="0" +OPENSC_LT_REVISION="1" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libopensc/sc.c]) From 6a704ffd69324b90fc6d7f7342866b4e9f967dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 13 Nov 2024 10:13:18 +0100 Subject: [PATCH 3605/4321] Fix supported versions --- NEWS | 4 ++-- SECURITY.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index d60e82d7ea..9039c2adaf 100644 --- a/NEWS +++ b/NEWS @@ -70,10 +70,10 @@ NEWS for OpenSC -- History of user visible changes ## Rutoken * increase the minimum PIN size to support Rutoken ECP BIO (#3208) -# JPKI +## JPKI * Adjust parameters for public key in PKCS#15 emulator (#3182) -# D-Trust +## D-Trust * Add support for ECDSA signatures and ECDH key agreement for D-Trust Signatures Cards 4.1/4.4 (#3240, #3248) # New in 0.25.1; 2024-04-05 diff --git a/SECURITY.md b/SECURITY.md index 51236a8c15..d80ec9ee8a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,8 +9,8 @@ backport security fixes into them. Only the last release is supported. | Version | Supported | | -------- | ------------------ | -| 0.25.1 | :white_check_mark: | -| < 0.25.1 | :x: | +| 0.26.0 | :white_check_mark: | +| < 0.26.0 | :x: | ## Reporting a Vulnerability From 37457b050064c501dcafa54bc58627873e8b1ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 10 Sep 2024 10:35:42 +0200 Subject: [PATCH 3606/4321] Add OpenPACE to dependencies on Fedora --- .github/setup-fedora.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 4cbeb743d2..b392508656 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -3,7 +3,7 @@ set -ex -o xtrace # Generic dependencies -DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils" +DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils openpace openpace-devel" if [ "$1" == "clang" ]; then DEPS="$DEPS clang" From cc14481a68941f14e12a82ad8d6c10773ab55ac5 Mon Sep 17 00:00:00 2001 From: George Pantelakis Date: Mon, 11 Nov 2024 16:44:42 +0100 Subject: [PATCH 3607/4321] Change expected test failures in FIPs mode. Expecting fail in FIPs mode of test-pkcs11-tool-unwrap-wrap-test.sh test since it FIPs mode OpenSSL doesn't allow RSA-PKCS. --- .github/setup-fedora.sh | 14 +++++++++++--- packaging/opensc.spec | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index b392508656..582f76a5e8 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -20,7 +20,15 @@ fi sudo dnf install -y $DEPS -sed -i -e '/XFAIL_TESTS/,$ { - s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh/ +XFAIL_TESTS="test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh" + +# In FIPS mode, OpenSSL doesn't allow RSA-PKCS, this is hardcoded into OpenSSL +# and we cannot influence it. Hence, the test is expected to fail in FIPS mode. +if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + XFAIL_TESTS+=" test-pkcs11-tool-unwrap-wrap-test.sh test-p11test.sh" +fi + +sed -i -e "/XFAIL_TESTS/,$ { + s/XFAIL_TESTS.*/XFAIL_TESTS=$XFAIL_TESTS/ q -}' tests/Makefile.am +}" tests/Makefile.am diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 5700e62e66..7947ef6b94 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -44,10 +44,18 @@ every software/card that does so, too. %setup -q # The test-pkcs11-tool-allowed-mechanisms already works in Fedora -sed -i -e '/XFAIL_TESTS/,$ { - s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh/ +XFAIL_TESTS="test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh" + +# In FIPS mode, OpenSSL doesn't allow RSA-PKCS, this is hardcoded into OpenSSL +# and we cannot influence it. Hence, the test is expected to fail in FIPS mode. +if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + XFAIL_TESTS+=" test-pkcs11-tool-unwrap-wrap-test.sh test-p11test.sh" +fi + +sed -i -e "/XFAIL_TESTS/,$ { + s/XFAIL_TESTS.*/XFAIL_TESTS=$XFAIL_TESTS/ q -}' tests/Makefile.am +}" tests/Makefile.am cp -p src/pkcs15init/README ./README.pkcs15init From 3d36248e0754595de7d1233d9686c31ff5513a3f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 Oct 2024 21:37:47 +0200 Subject: [PATCH 3608/4321] CI: update github's macos runners --- .github/workflows/macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e446b803df..fba351b4d7 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -20,7 +20,7 @@ jobs: build: strategy: matrix: - os: [macos-12, macos-14] + os: [macos-15, macos-14, macos-13] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -45,14 +45,14 @@ jobs: PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} push-artifacts: - runs-on: macos-12 + runs-on: macos-latest needs: [build] steps: - uses: actions/checkout@v4 - name: Pull build artifacts uses: actions/download-artifact@v4 with: - name: opensc-build-macos-12 + name: opensc-build-macos-15 - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" From c6e13509457923d60ee2e9269a46756138a9760c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 16 Oct 2024 21:47:19 +0200 Subject: [PATCH 3609/4321] CI: avoid outdated VS 2015 --- .appveyor.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index bce960249f..57ab9eca73 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -18,11 +18,12 @@ environment: # not compatible with OpenSSL 1.1.1: # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 # VCVARSALL: "%VS120COMNTOOLS%/../../VC/vcvarsall.bat" - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - VCVARSALL: "%VS140COMNTOOLS%/../../VC/vcvarsall.bat" - DO_PUSH_ARTIFACT: yes + #- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + #VCVARSALL: "%VS140COMNTOOLS%/../../VC/vcvarsall.bat" + #DO_PUSH_ARTIFACT: yes - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" + DO_PUSH_ARTIFACT: yes # not compatible with WiX 3.11.2: # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 # VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" From f78439c1049c150018a13eef1c733fa6879998b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 15 Jun 2023 10:59:00 +0200 Subject: [PATCH 3610/4321] reader-pcsc: check card status when timeout is received When the reader is removed and inserted back between two consecutive callings to SCardGetStatusChange(), the change is not reported. The SC_READER_CARD_CHANGED should be set and propagated into higher levels. When no reconnection is done afterwards, SCardGetStatusChange() will still return timeout and card handle will be invalid, but SCardStatus() does not report that situation. --- src/libopensc/reader-pcsc.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 9599b7ac27..73a0ffb974 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -378,14 +378,28 @@ static int refresh_attributes(sc_reader_t *reader) if (rv != SCARD_S_SUCCESS) { if (rv == (LONG)SCARD_E_TIMEOUT) { - /* Timeout, no change from previous recorded state. Make sure that - * changed flag is not set. */ - reader->flags &= ~SC_READER_CARD_CHANGED; + unsigned char atr[SC_MAX_ATR_SIZE]; + /* Make sure to preserve the CARD_PRESENT flag if the reader was * reattached and we called the refresh_attributes too recently */ if (priv->reader_state.dwEventState & SCARD_STATE_PRESENT) { reader->flags |= SC_READER_CARD_PRESENT; } + + /* Timeout should denote no change from previous recorded state, + * but check if the card handle is valid */ + reader->flags &= ~SC_READER_CARD_CHANGED; + if (priv->pcsc_card != 0) { + DWORD readers_len = 0, cstate = 0, prot, atr_len = SC_MAX_ATR_SIZE; + /* When reader is removed between two subsequent calls to refresh_attributes, + * SCardGetStatusChange does not notice the change, test the card handle with SCardStatus */ + rv = priv->gpriv->SCardStatus(priv->pcsc_card, NULL, &readers_len, &cstate, &prot, atr, &atr_len); + if (rv == (LONG)SCARD_W_REMOVED_CARD || rv == (LONG)SCARD_E_INVALID_VALUE) + reader->flags |= SC_READER_CARD_CHANGED; + /* If this happens, card must be reconnected, otherwise SCardGetStatusChange() will still return timeout + * and card handle will be invalid. */ + } + LOG_FUNC_RETURN(reader->ctx, SC_SUCCESS); } From 84e76a76e2234ec9b5c32c7d07da1051fe409132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 15 Jun 2023 11:05:58 +0200 Subject: [PATCH 3611/4321] reader-pcsc: Set flag denoting change when reader is removed When the removed reader is detected for the first time, set SC_READER_CARD_CHANGED denoting change. Remove the flag when the condition is hit again. Before this change, when reader was removed the reader->flags in refresh_attributes() was updated from 0x00000001 (SC_READER_CARD_PRESENT) to 0x00000020 (SC_READER_REMOVED). However, when the reader is still removed by another call to refresh_attributes(), the flags remained as 0x00000020 (SC_READER_REMOVED). Now the flags should change with SC_READER_CARD_CHANGED. When SCardGetStatusChange returns value successfully, remove also SC_READER_REMOVED before setting the current state. --- src/libopensc/reader-pcsc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 73a0ffb974..bbf0c27eef 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -409,7 +409,13 @@ static int refresh_attributes(sc_reader_t *reader) || rv == (LONG)SCARD_E_NO_READERS_AVAILABLE #endif || rv == (LONG)SCARD_E_SERVICE_STOPPED) { - reader->flags &= ~(SC_READER_CARD_PRESENT); + /* Set flag when state changes */ + if (reader->flags & SC_READER_REMOVED) { + reader->flags &= ~SC_READER_CARD_CHANGED; + } else { + reader->flags |= SC_READER_CARD_CHANGED; + } + reader->flags &= ~SC_READER_CARD_PRESENT; reader->flags |= SC_READER_REMOVED; priv->gpriv->removed_reader = reader; SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); @@ -434,7 +440,7 @@ static int refresh_attributes(sc_reader_t *reader) SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } - reader->flags &= ~(SC_READER_CARD_CHANGED|SC_READER_CARD_INUSE|SC_READER_CARD_EXCLUSIVE); + reader->flags &= ~(SC_READER_CARD_CHANGED | SC_READER_CARD_INUSE | SC_READER_CARD_EXCLUSIVE); if (state & SCARD_STATE_PRESENT) { reader->flags |= SC_READER_CARD_PRESENT; From f9d93446b2a7da5fd92ef77b8c0692f1bb2648db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 15 Jun 2023 11:34:57 +0200 Subject: [PATCH 3612/4321] slot: remove infinite loop when card change happens When reader is removed and inserted back between two consecutive calls to PCSC SCardGetStatusChange() function, and no reconnection is done, the status will remain SC_READER_CARD_CHANGED. --- src/pkcs11/slot.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 0020a4002d..6647e34b46 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -215,6 +215,7 @@ CK_RV card_detect(sc_reader_t *reader) CK_RV rv; unsigned int i; int j; + static int retry = 3; sc_log(context, "%s: Detecting smart card", reader->name); /* Check if someone inserted a card */ @@ -235,10 +236,12 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: Card changed", reader->name); /* The following should never happen - but if it * does we'll be stuck in an endless loop. - * So better be fussy. - if (!retry--) - return CKR_TOKEN_NOT_PRESENT; */ + * So better be fussy.*/ card_removed(reader); + if (!retry--) { + retry = 3; + return CKR_TOKEN_NOT_PRESENT; + } goto again; } From 7eeddcfa3192b0d799b7185911cded60c2ea1c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 1 Nov 2024 15:19:10 +0100 Subject: [PATCH 3613/4321] reader-pcsc: Set card handle to 0 when card disconnected When there is a call to pcsc_disconnect(), the card handle should be invalided afterwards. Otherwise, when there is a call to refresh_attributes() then, it attempts to check the card status change on the invalidated handle and then reports missing token error. --- src/libopensc/reader-pcsc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index bbf0c27eef..ae0fd85fde 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -394,7 +394,7 @@ static int refresh_attributes(sc_reader_t *reader) /* When reader is removed between two subsequent calls to refresh_attributes, * SCardGetStatusChange does not notice the change, test the card handle with SCardStatus */ rv = priv->gpriv->SCardStatus(priv->pcsc_card, NULL, &readers_len, &cstate, &prot, atr, &atr_len); - if (rv == (LONG)SCARD_W_REMOVED_CARD || rv == (LONG)SCARD_E_INVALID_VALUE) + if (rv != (LONG)SCARD_S_SUCCESS) reader->flags |= SC_READER_CARD_CHANGED; /* If this happens, card must be reconnected, otherwise SCardGetStatusChange() will still return timeout * and card handle will be invalid. */ @@ -695,6 +695,10 @@ static int pcsc_disconnect(sc_reader_t * reader) if (!priv->gpriv->cardmod && !(reader->ctx->flags & SC_CTX_FLAG_TERMINATE)) { LONG rv = priv->gpriv->SCardDisconnect(priv->pcsc_card, priv->gpriv->disconnect_action); PCSC_TRACE(reader, "SCardDisconnect returned", rv); + if (rv == SCARD_S_SUCCESS) { + // Card was successfully disconnected, reset the card handle + priv->pcsc_card = 0; + } } reader->flags &= SC_READER_REMOVED; return SC_SUCCESS; From 8f15301afd648ec47239d68ea61598d9c5972a1e Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 6 Nov 2024 13:48:48 -0600 Subject: [PATCH 3614/4321] Use 'BYTES4BITS' in all OpenSC code 'BYTES4BITS' is defined in 'libopensc/internal.c' As suggested,in https://github.com/OpenSC/OpenSC/pull/3090#issuecomment-2459547719 All places in OpenSC that need to get number of bytes needed to hold some data bits i.e. 'bytes = (bits + 7) / 8;' will now use 'bytes = BYTES4BITS(bits);' `#include "libopensc/internal.h"' was added to 7 of these files. This command was used to find the lines which needed to be changed: find . -type d -name .svn -prune , -name .git -prune , -type f -name \*.c -exec \ grep -E -n -e '[(].*+[[:blank:]]?7[[:blank:]]?[)]?[[:blank:]]?[/][[:blank:]]?8' {} \; -print There are two other files that use 'Y = (X + 7) / 8;' but these are to alloc multiples of 8 bytes for SM padding bytes. These where not changed. On branch BYTES4BITS Changes to be committed: modified: src/libopensc/asn1.c modified: src/libopensc/card-eoi.c modified: src/libopensc/card-isoApplet.c modified: src/libopensc/card-myeid.c modified: src/libopensc/card-piv.c modified: src/libopensc/card-setcos.c modified: src/libopensc/padding.c modified: src/libopensc/pkcs15-prkey.c modified: src/libopensc/pkcs15-pubkey.c modified: src/libopensc/pkcs15-sec.c modified: src/pkcs11/mechanism.c modified: src/pkcs15init/pkcs15-isoApplet.c modified: src/pkcs15init/pkcs15-myeid.c modified: src/pkcs15init/pkcs15-setcos.c modified: src/tests/fuzzing/fuzz_pkcs15init.c modified: src/tests/p11test/p11test_case_ec_derive.c modified: src/tests/p11test/p11test_case_ec_sign.c modified: src/tests/p11test/p11test_case_pss_oaep.c modified: src/tests/p11test/p11test_case_readonly.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c --- src/libopensc/asn1.c | 2 +- src/libopensc/card-eoi.c | 2 +- src/libopensc/card-isoApplet.c | 2 +- src/libopensc/card-myeid.c | 6 +++--- src/libopensc/card-piv.c | 2 +- src/libopensc/card-setcos.c | 12 ++++++------ src/libopensc/padding.c | 4 ++-- src/libopensc/pkcs15-prkey.c | 4 ++-- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15-sec.c | 10 +++++----- src/pkcs11/mechanism.c | 7 ++++--- src/pkcs15init/pkcs15-isoApplet.c | 2 +- src/pkcs15init/pkcs15-myeid.c | 3 ++- src/pkcs15init/pkcs15-setcos.c | 3 ++- src/tests/fuzzing/fuzz_pkcs15init.c | 2 +- src/tests/p11test/p11test_case_ec_derive.c | 3 ++- src/tests/p11test/p11test_case_ec_sign.c | 3 ++- src/tests/p11test/p11test_case_pss_oaep.c | 4 ++-- src/tests/p11test/p11test_case_readonly.c | 3 ++- src/tools/pkcs11-tool.c | 13 +++++++------ src/tools/pkcs15-init.c | 2 +- 21 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 548263a2da..262308930b 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -654,7 +654,7 @@ static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf, u8 *out; size_t bytes, skipped = 0; - bytes = (bits_left + 7)/8 + 1; + bytes = BYTES4BITS(bits_left) + 1; *outbuf = out = malloc(bytes); if (out == NULL) return SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index 0a8144f9cc..27c7da4f1d 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -457,7 +457,7 @@ static int eoi_set_security_env(struct sc_card *card, const struct sc_security_e /* We don't know yet which hash is used. So just store the security_env data and return */ if (!(env->algorithm_flags & ALREADY_PROCESSED)) { - privdata->key_len = (env->algorithm_ref + 7)/8; + privdata->key_len = BYTES4BITS(env->algorithm_ref); memcpy(&privdata->sec_env, env, sizeof(struct sc_security_env)); privdata->se_num = se_num; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index f0199eb216..87be918e2d 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1249,7 +1249,7 @@ isoApplet_compute_signature(struct sc_card *card, } /* Convert ASN.1 sequence of integers R,S to the raw concatenation of R,S for PKCS#11. */ - size_t len = (drvdata->sec_env_ec_field_length + 7) / 8 * 2; + size_t len = BYTES4BITS(drvdata->sec_env_ec_field_length) * 2; if (len > outlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index ead572e36c..643ad08690 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1087,7 +1087,7 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char * return SC_ERROR_INVALID_DATA; /* test&fail early */ - buflen = (s_len + 7)/8*2; + buflen = BYTES4BITS(s_len) * 2; if (buflen > datalen) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); @@ -1199,8 +1199,8 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, field_length = priv->sec_env->algorithm_ref; /* pad with zeros if needed */ - if (datalen < (field_length + 7) / 8 ) { - pad_chars = ((field_length + 7) / 8) - datalen; + if (datalen < BYTES4BITS(field_length)) { + pad_chars = BYTES4BITS(field_length) - datalen; memset(sbuf, 0, pad_chars); } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 034635d898..81a1ad5415 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -4635,7 +4635,7 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, */ if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) { - nLen = (priv->key_size + 7) / 8; + nLen = BYTES4BITS(priv->key_size); if (outlen < 2*nLen) { sc_log(card->ctx, " output too small for EC signature %"SC_FORMAT_LEN_SIZE_T"u < %"SC_FORMAT_LEN_SIZE_T"u", diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 3a624e0028..d471bc9b46 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -1064,18 +1064,18 @@ static int setcos_generate_store_key(sc_card_t *card, sbuf[len++] = data->pubexp_len / 256; /* 2 bytes for pubexp bitlength */ sbuf[len++] = data->pubexp_len % 256; - memcpy(sbuf + len, data->pubexp, (data->pubexp_len + 7) / 8); - len += (data->pubexp_len + 7) / 8; + memcpy(sbuf + len, data->pubexp, BYTES4BITS(data->pubexp_len)); + len += BYTES4BITS(data->pubexp_len); if (data->op_type == OP_TYPE_STORE) { sbuf[len++] = data->primep_len / 256; sbuf[len++] = data->primep_len % 256; - memcpy(sbuf + len, data->primep, (data->primep_len + 7) / 8); - len += (data->primep_len + 7) / 8; + memcpy(sbuf + len, data->primep, BYTES4BITS(data->primep_len)); + len += BYTES4BITS(data->primep_len); sbuf[len++] = data->primeq_len / 256; sbuf[len++] = data->primeq_len % 256; - memcpy(sbuf + len, data->primeq, (data->primeq_len + 7) / 8); - len += (data->primeq_len + 7) / 8; + memcpy(sbuf + len, data->primeq, BYTES4BITS(data->primeq_len)); + len += BYTES4BITS(data->primeq_len); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00); diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index bfc4273cd0..e56ec99fcb 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -480,7 +480,7 @@ static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsi EVP_MD_CTX* ctx = NULL; u8 buf[8]; u8 salt[PSS_MAX_SALT_SIZE], mask[EVP_MAX_MD_SIZE]; - size_t mod_length = (mod_bits + 7) / 8; + size_t mod_length = BYTES4BITS(mod_bits); if (*out_len < mod_length) return SC_ERROR_BUFFER_TOO_SMALL; @@ -614,7 +614,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, size_t tmp_len = *out_len; const u8 *tmp = in; unsigned int hash_algo, pad_algo; - size_t mod_len = (mod_bits + 7) / 8; + size_t mod_len = BYTES4BITS(mod_bits); #ifdef ENABLE_OPENSSL size_t sLen; EVP_MD* md = NULL; diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 70834713a1..5ecee4be20 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -828,8 +828,8 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) #endif /* Octetstring may need leading zeros if BN is to short */ - if (dst->privateD.len < (dst->params.field_length + 7) / 8) { - size_t d = (dst->params.field_length + 7) / 8 - dst->privateD.len; + if (dst->privateD.len < BYTES4BITS(dst->params.field_length)) { + size_t d = BYTES4BITS(dst->params.field_length) - dst->privateD.len; dst->privateD.data = realloc(dst->privateD.data, dst->privateD.len + d); if (!dst->privateD.data) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 83f3feb26a..eb136973e2 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1369,7 +1369,7 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke if (pk.len == 0) LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INTERNAL, "Incorrect length of key"); - pk.len = (pk.len + 7)/8; /* convert number of bits to bytes */ + pk.len = BYTES4BITS(pk.len); /* convert number of bits to bytes */ if (pk_alg.algorithm == SC_ALGORITHM_EC) { /* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */ diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index d1631610f4..0b06764574 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -370,8 +370,8 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card, switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_EC: case SC_PKCS15_TYPE_PRKEY_XEDDSA: - if (out == NULL || *poutlen < (prkey->field_length + 7) / 8) { - *poutlen = (prkey->field_length + 7) / 8; + if (out == NULL || *poutlen < BYTES4BITS(prkey->field_length)) { + *poutlen = BYTES4BITS(prkey->field_length); r = 0; /* say no data to return */ LOG_FUNC_RETURN(ctx, r); } @@ -624,15 +624,15 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: - modlen = (prkey->modulus_length + 7) / 8; + modlen = BYTES4BITS(prkey->modulus_length); break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: - modlen = (prkey->modulus_length + 7) / 8 * 2; + modlen = BYTES4BITS(prkey->modulus_length) * 2; break; case SC_PKCS15_TYPE_PRKEY_EC: case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: - modlen = ((prkey->field_length +7) / 8) * 2; /* 2*nLen */ + modlen = BYTES4BITS(prkey->field_length) * 2; /* 2*nLen */ break; default: LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported"); diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 596b7a637c..6b879fa529 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -26,6 +26,7 @@ #include "common/compat_overflow.h" #include "common/constant-time.h" #include "sc-pkcs11.h" +#include "libopensc/internal.h" /* Also used for verification data */ struct hash_signature_info { @@ -631,7 +632,7 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) rv = key->ops->get_attribute(operation->session, key, &attr); /* convert bits to bytes */ if (rv == CKR_OK) - *pLength = (*pLength + 7) / 8; + *pLength = BYTES4BITS(*pLength); break; case CKK_EC: case CKK_EC_EDWARDS: @@ -639,12 +640,12 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) /* TODO: -DEE we should use something other then CKA_MODULUS_BITS... */ rv = key->ops->get_attribute(operation->session, key, &attr); if (rv == CKR_OK) - *pLength = ((*pLength + 7)/8) * 2 ; /* 2*nLen in bytes */ + *pLength = BYTES4BITS(*pLength) * 2 ; /* 2*nLen in bytes */ break; case CKK_GOSTR3410: rv = key->ops->get_attribute(operation->session, key, &attr); if (rv == CKR_OK) - *pLength = (*pLength + 7) / 8 * 2; + *pLength = BYTES4BITS(*pLength) * 2; break; default: rv = CKR_MECHANISM_INVALID; diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 632989d142..48dc15fd27 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -488,7 +488,7 @@ isoApplet_generate_key_ec(const sc_pkcs15_prkey_info_t *key_info, sc_card_t *car args.pubkey.ec.params.coFactor.len = curve->coFactor.len; /* The length of the public key point will be: * Uncompressed tag + 2 * field length in bytes. */ - args.pubkey.ec.ecPointQ.len = 1 + (key_info->field_length + 7) / 8 * 2; + args.pubkey.ec.ecPointQ.len = 1 + BYTES4BITS(key_info->field_length) * 2; args.pubkey.ec.ecPointQ.value = malloc(args.pubkey.ec.ecPointQ.len); if(!args.pubkey.ec.ecPointQ.value) { diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 07e9ca5017..805966abc5 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -27,6 +27,7 @@ #include "libopensc/opensc.h" #include "libopensc/cardctl.h" +#include "libopensc/internal.h" #include "libopensc/log.h" #include "pkcs15-init.h" #include "profile.h" @@ -848,7 +849,7 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) { pubkey->algorithm = SC_ALGORITHM_RSA; - pubkey->u.rsa.modulus.len = (keybits + 7) / 8; + pubkey->u.rsa.modulus.len = BYTES4BITS(keybits); pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); pubkey->u.rsa.exponent.len = MYEID_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(MYEID_DEFAULT_PUBKEY_LEN); diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 6525541f5a..73be2b7a6a 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -26,6 +26,7 @@ #include "libopensc/opensc.h" #include "libopensc/cardctl.h" +#include "libopensc/internal.h" #include "libopensc/log.h" #include "pkcs15-init.h" #include "profile.h" @@ -488,7 +489,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* Key pair generation -> collect public key info */ if (pubkey != NULL) { pubkey->algorithm = SC_ALGORITHM_RSA; - pubkey->u.rsa.modulus.len = (keybits + 7) / 8; + pubkey->u.rsa.modulus.len = BYTES4BITS(keybits); pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); pubkey->u.rsa.exponent.len = SETCOS_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(SETCOS_DEFAULT_PUBKEY_LEN); diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index d039fd6712..d67121ce03 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -243,7 +243,7 @@ void do_store_secret_key(struct sc_profile *profile, struct sc_pkcs15_card *p15c sc_pkcs15_format_id("02", &(args.auth_id)); for (int i = 0; i < 3; i++) { - size_t keybytes = (keybits[i] + 7) / 8; + size_t keybytes = BYTES4BITS(keybits[i]); args.key.data = malloc(keybytes); memcpy(args.key.data, buf, keybytes); args.key.data_len = keybytes; diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 1eebccccae..f1fb5e4a78 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -19,6 +19,7 @@ * along with this program. If not, see . */ #include "p11test_case_ec_derive.h" +#include "libopensc/internal.h" size_t pkcs11_derive(test_cert_t *o, token_info_t * info, @@ -31,7 +32,7 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, CK_OBJECT_HANDLE newkey; CK_OBJECT_CLASS newkey_class = CKO_SECRET_KEY; CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET; - CK_ULONG newkey_len = (o->bits + 7) / 8; + CK_ULONG newkey_len = BYTES4BITS(o->bits); CK_BYTE newkey_id[] = {0x00, 0xff, 0x31}; CK_BYTE newkey_label[] = {"Derived key"}; CK_BBOOL _true = TRUE; diff --git a/src/tests/p11test/p11test_case_ec_sign.c b/src/tests/p11test/p11test_case_ec_sign.c index 806b23d463..3d0139ffab 100644 --- a/src/tests/p11test/p11test_case_ec_sign.c +++ b/src/tests/p11test/p11test_case_ec_sign.c @@ -19,6 +19,7 @@ * along with this program. If not, see . */ #include "p11test_case_ec_sign.h" +#include "libopensc/internal.h" void ec_sign_size_test(void **state) { unsigned int i; @@ -45,7 +46,7 @@ void ec_sign_size_test(void **state) { case CKK_EC: /* This tests just couple of sizes around the curve length * to verify they are properly truncated on input */ - curve_len = (objects.data[i].bits + 7) / 8; + curve_len = BYTES4BITS(objects.data[i].bits); min = curve_len - 2; max = curve_len + 2; inc = 1; diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 597e0a0d3e..2b91b9280a 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -493,7 +493,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m } message_length = MIN((int)global_message_length, - (int)((o->bits+7)/8 - 2*get_hash_length(mech->hash) - 2)); + (int)(BYTES4BITS(o->bits) - 2 * get_hash_length(mech->hash) - 2)); /* will not work for 1024b RSA key and SHA512 hash: It has max size -2 */ if (message_length < 0) { @@ -541,7 +541,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m static unsigned long get_max_salt_len(unsigned long bits, CK_MECHANISM_TYPE hash) { - return (bits + 7)/8 - get_hash_length(hash) - 2; + return BYTES4BITS(bits) - get_hash_length(hash) - 2; } int fill_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 8cb57b6c30..b453d87c41 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -26,6 +26,7 @@ #include #include #include +#include "libopensc/internal.h" #if OPENSSL_VERSION_NUMBER >= 0x30000000L # include #endif @@ -64,7 +65,7 @@ const unsigned char *const_message = (unsigned char *) MESSAGE_TO_SIGN; unsigned char * rsa_x_509_pad_message(const unsigned char *message, unsigned long *message_length, test_cert_t *o, int encrypt) { - unsigned long pad_message_length = (o->bits+7)/8; + unsigned long pad_message_length = BYTES4BITS(o->bits); unsigned char *pad_message = NULL; size_t padding_len = pad_message_length - (*message_length) - 3; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 34ec3a5a92..d701d76d6a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -67,6 +67,7 @@ #include "pkcs11/pkcs11-opensc.h" #include "libopensc/asn1.h" #include "libopensc/log.h" +#include "libopensc/internal.h" #include "common/compat_strlcat.h" #include "common/compat_strlcpy.h" #include "common/libpkcs11.h" @@ -2353,7 +2354,7 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, if (opt_salt_len_given == 1) { /* salt size explicitly given */ unsigned long modlen = 0; - modlen = (get_private_key_length(session, key) + 7) / 8; + modlen = BYTES4BITS(get_private_key_length(session, key)); if (modlen == 0) util_fatal("Incorrect length of private key"); switch (opt_salt_len) { @@ -5284,7 +5285,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #endif /* both eckeys must be same curve */ - key_len = (EC_GROUP_get_degree(ecgroup) + 7) / 8; + key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); n_attrs++; @@ -7306,7 +7307,7 @@ static int test_signature(CK_SESSION_HANDLE sess) continue; } - modLenBytes = (get_private_key_length(sess, privKeyObject) + 7) / 8; + modLenBytes = BYTES4BITS(get_private_key_length(sess, privKeyObject)); if(!modLenBytes) { printf(" -- can't be used for signature, skipping: can't obtain modulus\n"); continue; @@ -7499,7 +7500,7 @@ static int test_signature(CK_SESSION_HANDLE sess) } modLenBits = get_private_key_length(sess, privKeyObject); - modLenBytes = (modLenBits + 7) / 8; + modLenBytes = BYTES4BITS(modLenBits); if (!modLenBytes) { printf(" -- can't be used to sign/verify, skipping: can't obtain modulus\n"); continue; @@ -7664,7 +7665,7 @@ static int test_verify(CK_SESSION_HANDLE sess) continue; } - key_len = (get_private_key_length(sess, priv_key) + 7) / 8; + key_len = BYTES4BITS(get_private_key_length(sess, priv_key)); if (!key_len || key_len > INT_MAX) { printf(" -- can't get the modulus length, skipping\n"); continue; @@ -7894,7 +7895,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } size_t in_len; size_t max_in_len; - CK_ULONG mod_len = (get_private_key_length(session, privKeyObject) + 7) / 8; + CK_ULONG mod_len = BYTES4BITS(get_private_key_length(session, privKeyObject)); switch (mech_type) { case CKM_RSA_PKCS: pad = RSA_PKCS1_PADDING; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 61aa9bfbb7..1ebb29d280 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1256,7 +1256,7 @@ do_store_secret_key(struct sc_profile *profile) return SC_ERROR_INVALID_ARGUMENTS; } - r = do_read_data_object(opt_infile, &args.key.data, &args.key.data_len, (keybits+7) / 8); + r = do_read_data_object(opt_infile, &args.key.data, &args.key.data_len, BYTES4BITS(keybits)); if (r < 0) { free(args.key.data); return r; From eedc301d0543b5671e0f8b2b12d3f8b4c560cf55 Mon Sep 17 00:00:00 2001 From: tinyboxvk <13696594+tinyboxvk@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:01:03 +0000 Subject: [PATCH 3615/4321] Update codeql.yml --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 69c523a80c..0fd05d42b5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,7 +30,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/.codeql.yml @@ -39,6 +39,6 @@ jobs: - run: .github/build.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" From 9afebbc21d928b34dc0947a4edd3430609085091 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 20 Oct 2024 22:18:28 +0300 Subject: [PATCH 3616/4321] Run Windows CI on Github Actions Signed-off-by: Raul Metsma --- .github/workflows/windows.yml | 120 ++++++++++++++++++++++++++++++++++ Makefile.mak | 17 +---- win32/Make.rules.mak | 91 +++++++------------------- win32/Makefile.mak | 4 +- win32/OpenSC.wxs.in | 9 ++- 5 files changed, 152 insertions(+), 89 deletions(-) create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000000..d44b6e08a6 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,120 @@ +name: Windows + +on: + pull_request: + paths: + - '**.c' + - '**.h' + - '**.sh' + - .github/workflows/windows.yml + - '**.am' + - '**.mak' + - configure.ac + push: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build: + runs-on: ${{ matrix.image }} + strategy: + matrix: + platform: [x86, x64] + configuration: [Light, Release] + image: [windows-2019, windows-2022] + env: + OPENPACE_VER: 1.1.3 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Git describe + id: ghd + uses: proudust/gh-describe@v2 + - name: Package name + shell: bash + run: | + echo PACKAGE_NAME=OpenSC-${{ steps.ghd.outputs.tag }} >> $GITHUB_ENV + echo ARTIFACT=OpenSC-${{ steps.ghd.outputs.tag }}_${{ matrix.platform == 'x86' && 'win32' || 'win64' }}${{ matrix.configuration == 'Light' && '-Light' || '' }} >> $GITHUB_ENV + - name: Install CPDK + run: choco install windows-cryptographic-provider-development-kit -y > $null + - name: Install autotools + uses: msys2/setup-msys2@v2 + with: + install: autotools mingw-w64-x86_64-pkg-config + - name: Bootstrap + shell: msys2 {0} + run: | + if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "master" ]]; then + ./bootstrap + elif [[ "${{ github.event_name }}" == "push" ]]; then + ./bootstrap.ci -s "-${{ github.ref_name }}" + elif [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "master" ]]; then + ./bootstrap.ci -s "-pr${{ github.event.number }}" + else + ./bootstrap.ci -s "-${{ github.base_ref }}-pr${{ github.event.number }}" + fi + - name: Configure + shell: bash + run: ./configure --disable-openssl --disable-readline --disable-zlib || cat config.log + - name: Setup dev env + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.platform }} + - name: Prepare vcpkg + if: matrix.configuration == 'Release' + uses: lukka/run-vcpkg@v7 + with: + vcpkgArguments: zlib openssl + vcpkgGitCommitId: 511d74f695bd45959d12b50b00f1b68f69e8f0b0 + vcpkgTriplet: ${{ matrix.platform }}-windows-static + - name: Restore Cache + if: matrix.configuration == 'Release' + uses: actions/cache@v4 + id: cache + with: + path: openpace-${{ env.OPENPACE_VER }} + key: OpenPACE-${{ env.OPENPACE_VER }}-${{ matrix.image }}-${{ matrix.platform }} + - name: Build OpenPACE + if: matrix.configuration == 'Release' && steps.cache.outputs.cache-hit != 'true' + run: | + Invoke-WebRequest "https://github.com/frankmorgner/openpace/archive/${env:OPENPACE_VER}.zip" -OutFile openpace.zip + tar xf openpace.zip + cd openpace-${env:OPENPACE_VER}\src + cl /nologo /O1 /Zi /W3 /GS /MT /I${env:RUNVCPKG_VCPKG_ROOT}\installed\${env:RUNVCPKG_VCPKG_TRIPLET}\include /I. ` + /DX509DIR=`"/`" /DCVCDIR=`"/`" /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN ` + /DHAVE_ASN1_STRING_GET0_DATA /DHAVE_DECL_OPENSSL_ZALLOC /DHAVE_DH_GET0_KEY /DHAVE_DH_GET0_PQG ` + /DHAVE_DH_SET0_KEY /DHAVE_DH_SET0_PQG /DHAVE_ECDSA_SIG_GET0 /DHAVE_ECDSA_SIG_SET0 ` + /DHAVE_EC_KEY_METHOD /DHAVE_RSA_GET0_KEY /DHAVE_RSA_SET0_KEY /DHAVE_EC_POINT_GET_AFFINE_COORDINATES ` + /DHAVE_EC_POINT_SET_AFFINE_COORDINATES /DHAVE_EVP_PKEY_DUP /c ` + ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c ` + eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c ` + pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c + lib /nologo /machine:${{ matrix.platform }} /out:libeac.lib ` + ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj ` + eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj ` + pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj + - name: Set NMake Variables + if: matrix.configuration == 'Release' + run: | + $VCPKG_DIR="${env:RUNVCPKG_VCPKG_ROOT}\installed\${env:RUNVCPKG_VCPKG_TRIPLET}" + $NMAKE_EXTRA="ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC ZLIB_INCL_DIR=/I${VCPKG_DIR}\include ZLIB_LIB=${VCPKG_DIR}\lib\zlib.lib" + $NMAKE_EXTRA+=" OPENSSL_DEF=/DENABLE_OPENSSL OPENSSL_DIR=${VCPKG_DIR} OPENSSL_LIB=${VCPKG_DIR}\lib\libcrypto.lib OPENSSL_EXTRA_CFLAGS=/DOPENSSL_SECURE_MALLOC_SIZE=65536" + $NMAKE_EXTRA+=" OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=${env:GITHUB_WORKSPACE}\openpace-${env:OPENPACE_VER}" + echo "NMAKE_EXTRA=$NMAKE_EXTRA" >> $env:GITHUB_ENV + - name: Build OpenSC + run: | + nmake /nologo /f Makefile.mak ${{ env.NMAKE_EXTRA }} opensc.msi + move win32\OpenSC.msi OpenSC-${env:ARTIFACT}.msi + - name: Debug symbols + run: | + Get-ChildItem -recurse . -exclude vc*.pdb *.pdb | % { + 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName + } + - name: Archive artifacts + uses: actions/upload-artifact@v4 + with: + name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} + path: | + ./*.msi + ./*-Debug.zip diff --git a/Makefile.mak b/Makefile.mak index 9489a5ccad..0b4f486322 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -2,19 +2,8 @@ SUBDIRS = etc win32 src default: all -32: - CALL "C:\Program Files\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - $(MAKE) /f Makefile.mak opensc.msi PLATFORM=x86 OPENPACE_DIR=C:\openpace-Win32_1.0.2 - MOVE win32\OpenSC.msi OpenSC_win32.msi - -64: - CALL "C:\Program Files\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 - $(MAKE) /f Makefile.mak opensc.msi OPENPACE_DIR=C:\openpace-Win64_1.0.2 - MOVE win32\OpenSC.msi OpenSC_win64.msi - -opensc.msi: - $(MAKE) /f Makefile.mak all OPENSSL_DEF=/DENABLE_OPENSSL OPENPACE_DEF=/DENABLE_OPENPACE" - @cmd /c "cd win32 && $(MAKE) /nologo /f Makefile.mak opensc.msi OPENSSL_DEF=/DENABLE_OPENSSL OPENPACE_DEF=/DENABLE_OPENPACE" +opensc.msi: all + cd win32 && $(MAKE) /nologo /f Makefile.mak opensc.msi && cd .. all clean:: - @for %i in ( $(SUBDIRS) ) do @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" + @for %%i in ( $(SUBDIRS) ) do ( cd %%i && $(MAKE) /nologo /f Makefile.mak $@ && cd ..) diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 5948d9779a..980a2a344f 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -3,28 +3,9 @@ OPENSC_FEATURES = pcsc #Include support for minidriver MINIDRIVER_DEF = /DENABLE_MINIDRIVER -#Build MSI with the Windows Installer XML (WIX) toolkit, requires WIX >= 3.9 -!IF "$(WIX)" == "" -# at least WiX 3.11 sets the WIX environment variable to its path -WIX = C:\Program Files\WiX Toolset v3.10 -!ENDIF -!IF "$(DEVENVDIR)" == "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\" || "$(DEVENVDIR)" == "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\" -WIXVSVER = VS2010 -!ENDIF -!IF "$(VISUALSTUDIOVERSION)" == "12.0" -WIXVSVER = VS2013 -!ENDIF -!IF "$(VISUALSTUDIOVERSION)" == "14.0" -WIXVSVER = VS2015 -!ENDIF -!IF "$(VISUALSTUDIOVERSION)" == "15.0" -WIXVSVER = VS2017 -!ENDIF -!IF "$(VISUALSTUDIOVERSION)" == "16.0" -WIXVSVER = VS2019 -!ENDIF -WIX_INCL_DIR = "/I$(WIX)\SDK\$(WIXVSVER)\inc" -WIX_LIBS = "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\wcautil.lib" +#Build MSI with the Windows Installer XML (WIX) toolkit, requires WIX >= 3.14 +WIX_INCL_DIR = "/I$(WIX)\SDK\VS2017\inc" +WIX_LIBS = "$(WIX)\SDK\VS2017\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\VS2017\lib\$(PLATFORM)\wcautil.lib" # We do not build tests on windows #TESTS_DEF = /DENABLE_TESTS @@ -54,31 +35,22 @@ OPENSSL_INCL_DIR = /I$(OPENSSL_DIR)\include #define OPENSSL_STATIC if you have visual studio compatible with OpenSSL's static binaries OPENSSL_STATIC_DIR = static +!IF "$(OPENSSL_LIB)" == "" !IF "$(DEBUG_DEF)" == "/DDEBUG" !IF "$(PLATFORM)" == "x86" -# OpenSSL 1.0.2 -#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib -# OpenSSL 1.1.0 -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MTd.lib !ELSE -# OpenSSL 1.0.2 -#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib -# OpenSSL 1.1.0 -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MTd.lib !ENDIF !ELSE !IF "$(PLATFORM)" == "x86" -# OpenSSL 1.0.2 -#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib -# OpenSSL 1.1.0 -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto32MT.lib !ELSE -# OpenSSL 1.0.2 -#OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libeay32MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib -# OpenSSL 1.1.0 -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user32.lib advapi32.lib crypt32.lib ws2_32.lib +OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib !ENDIF !ENDIF +!ENDIF +OPENSSL_LIB = $(OPENSSL_LIB) user32.lib advapi32.lib crypt32.lib ws2_32.lib PROGRAMS_OPENSSL = cryptoflex-tool.exe pkcs15-init.exe netkey-tool.exe piv-tool.exe \ westcos-tool.exe sc-hsm-tool.exe dnie-tool.exe gids-tool.exe @@ -135,45 +107,28 @@ CANDLEFLAGS = -dOpenPACE="$(OPENPACE_DIR)" $(CANDLEFLAGS) # Used for MiniDriver -CNGSDK_INCL_DIR = "/IC:\Program Files (x86)\Microsoft CNG Development Kit\Include" -CPDK_INCL_DIR = "/IC:\Program Files (x86)\Windows Kits\10\Cryptographic Provider Development Kit\Include" -!IF "$(PROCESSOR_ARCHITECTURE)" == "x86" && "$(PROCESSOR_ARCHITEW6432)" == "" -CNGSDK_INCL_DIR = "/IC:\Program Files\Microsoft CNG Development Kit\Include" -CPDK_INCL_DIR = "/IC:\Program Files\Windows Kits\10\Cryptographic Provider Development Kit\Include" -!ENDIF -# Mandatory path to 'ISO C9x compliant stdint.h and inttypes.h for Microsoft Visual Studio' -# http://msinttypes.googlecode.com/files/msinttypes-r26.zip -# INTTYPES_INCL_DIR = /IC:\opensc\dependencies\msys\local +CPDK_INCL_DIR = "/IC:\Program Files (x86)\Windows Kits\10\Cryptographic Provider Development Kit\Include" -# Code optimisation -# O1 - minimal code size -CODE_OPTIMIZATION = /O1 - -ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(OPENSSL_EXTRA_CFLAGS) $(ZLIB_INCL_DIR) $(LIBLTDL_INCL) $(INTTYPES_INCL_DIR) $(CPDK_INCL_DIR) $(CNGSDK_INCL_DIR) $(WIX_INCL_DIR) +COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /DHAVE_CONFIG_H /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = $(COPTS) $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) +COPTS = $(COPTS) /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) $(WIX_INCL_DIR) +LINKFLAGS = /nologo /machine:$(PLATFORM) /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD +LIBFLAGS = /nologo /machine:$(PLATFORM) +CANDLEFLAGS = -arch $(PLATFORM) $(CANDLEFLAGS) !IF "$(DEBUG_DEF)" == "/DDEBUG" -LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG -CODE_OPTIMIZATION = -COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od -!ELSE -LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD /DEBUG /OPT:REF /OPT:ICF -COPTS = /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /Zi -!ENDIF - - -LINKFLAGS = /NOLOGO /INCREMENTAL:NO /MACHINE:$(PLATFORM) /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:MSVCRT /NXCOMPAT /DYNAMICBASE $(LINKDEBUGFLAGS) -LIBFLAGS = /nologo /machine:$(PLATFORM) -!IF "$(PLATFORM)" == "x86" -CANDLEFLAGS = -dPlatform=x86 $(CANDLEFLAGS) +LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMT +COPTS = /Od /MTd $(COPTS) !ELSE -CANDLEFLAGS = -dPlatform=x64 $(CANDLEFLAGS) +LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMTD /OPT:REF /OPT:ICF +COPTS = /O1 /MT $(COPTS) !ENDIF .c.obj:: - cl $(CODE_OPTIMIZATION) $(COPTS) /c $< + cl $(COPTS) /c $< .cpp.obj:: - cl $(CODE_OPTIMIZATION) $(COPTS) /c $< + cl $(COPTS) /c $< .rc.res:: rc /l 0x0409 $< diff --git a/win32/Makefile.mak b/win32/Makefile.mak index 71e43476af..0231c92656 100644 --- a/win32/Makefile.mak +++ b/win32/Makefile.mak @@ -14,10 +14,10 @@ customactions.dll: versioninfo-customactions.res customactions.obj link /dll $(LINKFLAGS) /def:$*.def /out:customactions.dll versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib OpenSC.msi: OpenSC.wixobj - "$(WIX)\bin\light.exe" -sh -ext WixUIExtension -ext WiXUtilExtension $? + "$(WIX)\bin\light.exe" -ext WixUIExtension -ext WiXUtilExtension $? OpenSC.wixobj: OpenSC.wxs customactions.dll - "$(WIX)\bin\candle.exe" -ext WiXUtilExtension -dSOURCE_DIR=$(TOPDIR) $(CANDLEFLAGS) OpenSC.wxs + "$(WIX)\bin\candle.exe" -ext WiXUtilExtension -dSOURCE_DIR=$(TOPDIR) $(CANDLEFLAGS) OpenSC.wxs clean:: del /Q config.h *.msi *.wixobj *.wixpdb diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 9191da43af..cab970161b 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -1,5 +1,5 @@ - + @@ -27,8 +27,7 @@ Codepage="1252" Version="@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" Manufacturer="@OPENSC_VS_FF_COMPANY_NAME@"> - - - + + - - - - + + + + - - + + - - - + + + - - - - - - - - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - + + + - - + + - - - + + + - - + + - + - - - + + + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - + - - - + + + - 1 - 1 + + - - - + - - - + - - - + - + From db56bc2100ed8ffc40c06044fe8c397282d46630 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 25 Nov 2024 12:44:35 +0200 Subject: [PATCH 3648/4321] Build Wix 5 CustomAction Signed-off-by: Raul Metsma --- .github/setup-wix.ps1 | 6 +++++- win32/Make.rules.mak | 19 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/setup-wix.ps1 b/.github/setup-wix.ps1 index e8788ea487..d9828b7e16 100644 --- a/.github/setup-wix.ps1 +++ b/.github/setup-wix.ps1 @@ -3,4 +3,8 @@ param( ) & dotnet tool install -g --version $version wix & wix extension add -g WixToolset.UI.wixext/$version -& wix extension add -g WixToolset.Util.wixext/$version \ No newline at end of file +& wix extension add -g WixToolset.Util.wixext/$version +& cd win32 +& dotnet new console --force --name CustomAction +& dotnet add CustomAction package WixToolset.WcaUtil --version $version --package-directory packages +& cd .. \ No newline at end of file diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index d9647833a5..c274f56938 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -3,9 +3,14 @@ OPENSC_FEATURES = pcsc #Include support for minidriver MINIDRIVER_DEF = /DENABLE_MINIDRIVER -#Build MSI with the Windows Installer XML (WIX) toolkit, requires WIX >= 3.14 -WIX_INCL_DIR = "/I$(WIX)\SDK\VS2017\inc" -WIX_LIBS = "$(WIX)\SDK\VS2017\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\VS2017\lib\$(PLATFORM)\wcautil.lib" +#Build MSI with the Windows Installer XML (WIX) toolkit +!IF "$(WIX_PACKAGES)" == "" +WIX_PACKAGES = $(TOPDIR)\win32\packages +!ENDIF +WIX_INCL_DIR = "/I$(WIX_PACKAGES)/wixtoolset.dutil/5.0.2/build/native/include" \ + "/I$(WIX_PACKAGES)/wixtoolset.wcautil/5.0.2/build/native/include" +WIX_LIBS = "$(WIX_PACKAGES)/wixtoolset.dutil/5.0.2/build/native/v14/$(PLATFORM)/dutil.lib" \ + "$(WIX_PACKAGES)/wixtoolset.wcautil/5.0.2/build/native/v14/$(PLATFORM)/wcautil.lib" # We do not build tests on windows #TESTS_DEF = /DENABLE_TESTS @@ -113,9 +118,9 @@ CPDK_INCL_DIR = "/IC:\Program Files (x86)\Windows Kits\10\Cryptographic Provider COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /DHAVE_CONFIG_H \ /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" \ $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) \ - /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) $(WIX_INCL_DIR) -LINKFLAGS = /nologo /machine:$(PLATFORM) /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD -LIBFLAGS = /nologo /machine:$(PLATFORM) + /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) +LINKFLAGS = /nologo /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD +LIBFLAGS = /nologo WIXFLAGS = -arch $(PLATFORM) $(WIXFLAGS) !IF "$(DEBUG_DEF)" == "/DDEBUG" @@ -130,7 +135,7 @@ COPTS = /O1 /$(BUILD_TYPE) $(COPTS) cl $(COPTS) /c $< .cpp.obj:: - cl $(COPTS) /c $< + cl $(COPTS) $(WIX_INCL_DIR) /c $< .rc.res:: rc /l 0x0409 $< From fe6519238fca1f26648aabd6dbb75e82a0ee63bc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 8 Dec 2023 17:10:34 -0600 Subject: [PATCH 3649/4321] pkcs11-tool.c - CKK_GENERIC_SECRET do not have CKA_ENCRYPT or CKA_DECRYPT On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e8f69f45db..dd1bfb15dd 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5225,12 +5225,10 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)}, {CKA_SENSITIVE, &_false, sizeof(_false)}, {CKA_EXTRACTABLE, &_true, sizeof(_true)}, - {CKA_ENCRYPT, &_true, sizeof(_true)}, - {CKA_DECRYPT, &_true, sizeof(_true)}, {CKA_WRAP, &_true, sizeof(_true)}, {CKA_UNWRAP, &_true, sizeof(_true)} }; - int n_attrs = 9; + int n_attrs = 7; CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; BIO *bio_in = NULL; From 0943149947344e14d116e681d4977927d01ee802 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 8 Dec 2023 18:04:00 -0600 Subject: [PATCH 3650/4321] pkcs11-tool.c Add derive key support for CKK_MONTGOMERY OpenSSL treats EVP_PKEY_EC, EVP_PKEY_X25519 and EVP_PKEY_X448 as different key types. Refer to the other key as a peer key. Use mech_mech as it is passed into derive_ec_key. On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 92 +++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index dd1bfb15dd..983a7b8613 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5240,6 +5240,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE unsigned char * derp = NULL; size_t der_size = 0; EVP_PKEY *pkey = NULL; + int key_id = 0; /* nid of peer key */ #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *eckey = NULL; const EC_GROUP *ecgroup = NULL; @@ -5250,7 +5251,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE int nid = 0; #endif - printf("Using derive algorithm 0x%8.8lx %s\n", opt_mechanism, p11_mechanism_to_name(mech_mech)); + printf("Using derive algorithm 0x%8.8lx %s\n", mech_mech, p11_mechanism_to_name(mech_mech)); memset(&mech, 0, sizeof(mech)); mech.mechanism = mech_mech; @@ -5266,26 +5267,33 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #endif if (!pkey) - util_fatal("Cannot read EC key from %s", opt_input); + util_fatal("Cannot read peer EC key from %s", opt_input); + + key_id = EVP_PKEY_id(pkey); + + switch(key_id) { + case EVP_PKEY_EC: /* CKK_EC*/ #if OPENSSL_VERSION_NUMBER < 0x30000000L - eckey = EVP_PKEY_get0_EC_KEY(pkey); - ecpoint = EC_KEY_get0_public_key(eckey); - ecgroup = EC_KEY_get0_group(eckey); + eckey = EVP_PKEY_get0_EC_KEY(pkey); + ecpoint = EC_KEY_get0_public_key(eckey); + ecgroup = EC_KEY_get0_group(eckey); - if (!ecpoint || !ecgroup) - util_fatal("Failed to parse other EC key from %s", opt_input); + if (!ecpoint || !ecgroup) + util_fatal("Failed to parse peer EC key from %s", opt_input); #else - if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 - || (nid = OBJ_txt2nid(name)) == NID_undef - || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) - util_fatal("Failed to parse other EC key from %s", opt_input); + if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 + || (nid = OBJ_txt2nid(name)) == NID_undef + || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) + util_fatal("Failed to parse peer EC key from %s", opt_input); #endif - /* both eckeys must be same curve */ - key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); - FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); - n_attrs++; + /* both eckeys must be same curve */ + key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); + FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); + n_attrs++; + break; + } if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(newkey_template[n_attrs], @@ -5295,11 +5303,27 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE } #if OPENSSL_VERSION_NUMBER < 0x30000000L - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - buf = (unsigned char *)malloc(buf_size); - if (buf == NULL) - util_fatal("malloc() failure\n"); - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); + switch(key_id) { + case EVP_PKEY_EC: + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + buf = (unsigned char *)malloc(buf_size); + if (buf == NULL) + util_fatal("malloc() failure\n"); + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); + break; + case EVP_PKEY_X25519: + case EVP_PKEY_X448: + EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); + if (buf_size == 0) + util_fatal("Unable to get of peer key\n"); + buf = (unsigned char *)malloc(buf_size); + if (buf == NULL) + util_fatal("malloc() failure\n"); + EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); + break; + default: + util_fatal("Unknown EVP_PKEY_id\n"); + } #else EC_GROUP_free(ecgroup); EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); @@ -5308,10 +5332,25 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buf_size, NULL) != 1) { free(buf); - util_fatal("Failed to parse other EC key from %s", opt_input); + util_fatal("Failed to parse peer EC key from %s", opt_input); } #endif + switch (key_id) { + case EVP_PKEY_EC: /* CKK_EC*/ + if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) + util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); + break; + case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ + case EVP_PKEY_X448: + if (mech_mech != CKM_ECDH1_DERIVE) + util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); + break; + default: + util_fatal("Peer key not usable with derive or unknown %i", key_id); + break; + } + if (opt_derive_pass_der) { octet = ASN1_OCTET_STRING_new(); if (octet == NULL) @@ -5501,21 +5540,22 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) CK_OBJECT_HANDLE derived_key = 0; int fd; ssize_t sz; + CK_KEY_TYPE key_type = getKEY_TYPE(session, key); if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_DERIVE|opt_allow_sw, NULL, 0, &opt_mechanism)) util_fatal("Derive mechanism not supported"); - switch(opt_mechanism) { - case CKM_ECDH1_COFACTOR_DERIVE: - case CKM_ECDH1_DERIVE: - derived_key= derive_ec_key(session, key, opt_mechanism); + switch(key_type) { + case CKK_EC: + case CKK_EC_MONTGOMERY: + derived_key = derive_ec_key(session, key, opt_mechanism); break; case CKM_HKDF_DERIVE: derived_key = derive_hkdf(session, key); break; default: - util_fatal("mechanism not supported for derive"); + util_fatal("Key type %lu does not support derive", key_type); break; } From 33f87c9f36e0eb1a3b73882bb05bf1222ad8d441 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 21 Jan 2024 06:48:45 -0600 Subject: [PATCH 3651/4321] pkcs11-tool.c - EVP_KEY_X448 not defined in LibreSSL EVP_KEY_X25519 is defined but not EVP_KEY_X448. Test if defined. Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 983a7b8613..488098a1fb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5312,7 +5312,9 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); break; case EVP_PKEY_X25519: +#if defined(EVP_PKEY_X448) case EVP_PKEY_X448: +#endif EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); if (buf_size == 0) util_fatal("Unable to get of peer key\n"); @@ -5342,7 +5344,9 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); break; case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ +#if defined(EVP_PKEY_X448) case EVP_PKEY_X448: +#endif if (mech_mech != CKM_ECDH1_DERIVE) util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); break; From 591b762bb290eddd2f1a14cfb4f373a27dd78dc5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 20 Jan 2024 21:00:59 -0600 Subject: [PATCH 3652/4321] pkcs11-tool.c calculate size in bits for eddsa and xeddsa CKA_EC_POINT CKA_EC_POINT for eddsa and xeddsa are bit strings. Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 488098a1fb..d3611e6d77 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5702,8 +5702,17 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) else ksize = (size - 5) * 4; } else { - /* This should be 255 for ed25519 and 448 for ed448 curves so roughly */ - ksize = size * 8; + /* + * EDDSA and XEDDSA in PKCS11 are in bit strings. + * need to drop '03' tag, len (in bytes) and 00 bits in last byte. + */ + if ((size - 3) < 127) + ksize = (size - 3) * 8; + else if ((size - 4) <= 255) + ksize = (size - 4) * 8; + else + ksize = (size - 5) * 8; + } printf(" EC_POINT %lu bits\n", ksize); From 0827576c45b90ce62e9d3a9215c5ea5618fa3c32 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 29 Jan 2024 15:19:55 -0600 Subject: [PATCH 3653/4321] pkcs11-tool.c - EC_POINT DER in BIT STRING or OCTET STRING Accept either encoding. On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 189 +++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 89 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d3611e6d77..605b11fb84 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5219,15 +5219,17 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE CK_BBOOL _true = TRUE; CK_BBOOL _false = FALSE; CK_OBJECT_HANDLE newkey = 0; +//clang-format off CK_ATTRIBUTE newkey_template[20] = { - {CKA_TOKEN, &_false, sizeof(_false)}, /* session only object */ - {CKA_CLASS, &newkey_class, sizeof(newkey_class)}, - {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)}, - {CKA_SENSITIVE, &_false, sizeof(_false)}, - {CKA_EXTRACTABLE, &_true, sizeof(_true)}, - {CKA_WRAP, &_true, sizeof(_true)}, - {CKA_UNWRAP, &_true, sizeof(_true)} - }; + {CKA_TOKEN, &_false, sizeof(_false) }, /* session only object */ + {CKA_CLASS, &newkey_class, sizeof(newkey_class)}, + {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type) }, + {CKA_SENSITIVE, &_false, sizeof(_false) }, + {CKA_EXTRACTABLE, &_true, sizeof(_true) }, + {CKA_WRAP, &_true, sizeof(_true) }, + {CKA_UNWRAP, &_true, sizeof(_true) }, + }; +//clang-format on int n_attrs = 7; CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; @@ -5271,29 +5273,27 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE key_id = EVP_PKEY_id(pkey); - switch(key_id) { - case EVP_PKEY_EC: /* CKK_EC*/ + switch (key_id) { + case EVP_PKEY_EC: /* CKK_EC*/ #if OPENSSL_VERSION_NUMBER < 0x30000000L - eckey = EVP_PKEY_get0_EC_KEY(pkey); - ecpoint = EC_KEY_get0_public_key(eckey); - ecgroup = EC_KEY_get0_group(eckey); + eckey = EVP_PKEY_get0_EC_KEY(pkey); + ecpoint = EC_KEY_get0_public_key(eckey); + ecgroup = EC_KEY_get0_group(eckey); - if (!ecpoint || !ecgroup) - util_fatal("Failed to parse peer EC key from %s", opt_input); + if (!ecpoint || !ecgroup) + util_fatal("Failed to parse peer EC key from %s", opt_input); #else - if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 - || (nid = OBJ_txt2nid(name)) == NID_undef - || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) - util_fatal("Failed to parse peer EC key from %s", opt_input); + if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 || (nid = OBJ_txt2nid(name)) == NID_undef || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) + util_fatal("Failed to parse peer EC key from %s", opt_input); #endif - /* both eckeys must be same curve */ - key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); - FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); - n_attrs++; - break; - } + /* both eckeys must be same curve */ + key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); + FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); + n_attrs++; + break; + } if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(newkey_template[n_attrs], @@ -5303,28 +5303,28 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE } #if OPENSSL_VERSION_NUMBER < 0x30000000L - switch(key_id) { - case EVP_PKEY_EC: - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - buf = (unsigned char *)malloc(buf_size); - if (buf == NULL) - util_fatal("malloc() failure\n"); - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); - break; - case EVP_PKEY_X25519: + switch (key_id) { + case EVP_PKEY_EC: + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + buf = (unsigned char *)malloc(buf_size); + if (buf == NULL) + util_fatal("malloc() failure\n"); + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); + break; + case EVP_PKEY_X25519: #if defined(EVP_PKEY_X448) - case EVP_PKEY_X448: + case EVP_PKEY_X448: #endif - EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); - if (buf_size == 0) - util_fatal("Unable to get of peer key\n"); - buf = (unsigned char *)malloc(buf_size); - if (buf == NULL) - util_fatal("malloc() failure\n"); - EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); - break; - default: - util_fatal("Unknown EVP_PKEY_id\n"); + EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); + if (buf_size == 0) + util_fatal("Unable to get of peer key\n"); + buf = (unsigned char *)malloc(buf_size); + if (buf == NULL) + util_fatal("malloc() failure\n"); + EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); + break; + default: + util_fatal("Unknown EVP_PKEY_id\n"); } #else EC_GROUP_free(ecgroup); @@ -5339,21 +5339,21 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #endif switch (key_id) { - case EVP_PKEY_EC: /* CKK_EC*/ - if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) - util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); - break; - case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ + case EVP_PKEY_EC: /* CKK_EC*/ + if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) + util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); + break; + case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ #if defined(EVP_PKEY_X448) - case EVP_PKEY_X448: + case EVP_PKEY_X448: #endif - if (mech_mech != CKM_ECDH1_DERIVE) - util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); - break; - default: - util_fatal("Peer key not usable with derive or unknown %i", key_id); - break; - } + if (mech_mech != CKM_ECDH1_DERIVE) + util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); + break; + default: + util_fatal("Peer key not usable with derive or unknown %i", key_id); + break; + } if (opt_derive_pass_der) { octet = ASN1_OCTET_STRING_new(); @@ -5550,10 +5550,10 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) if (!find_mechanism(slot, CKF_DERIVE|opt_allow_sw, NULL, 0, &opt_mechanism)) util_fatal("Derive mechanism not supported"); - switch(key_type) { - case CKK_EC: - case CKK_EC_MONTGOMERY: - derived_key = derive_ec_key(session, key, opt_mechanism); + switch (key_type) { + case CKK_EC: + case CKK_EC_MONTGOMERY: + derived_key = derive_ec_key(session, key, opt_mechanism); break; case CKM_HKDF_DERIVE: derived_key = derive_hkdf(session, key); @@ -5683,39 +5683,50 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } if (pub) { unsigned char *bytes = NULL; - unsigned long ksize; + unsigned long ksize = 0; unsigned int n; + unsigned long body_len = 0; - bytes = getEC_POINT(sess, obj, &size); - if (key_type == CKK_EC) { + bytes = getEC_POINT(sess, obj, &ksize); + /* + * simple parse of DER BIT STRING 0x03 or OCTET STRING 0x04 + * good to 65K bytes + */ + if (ksize > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { + if (bytes[1] <= 127 && ksize == (unsigned long)(bytes[1] + 2)) { + body_len = ksize - 2; + } else if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { + body_len = ksize - 3; + } else if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { + body_len = ksize - 4; + } + } + /* With BIT STRING remove unused bits in last byte indicator */ + if (body_len > 0 && bytes[0] == 0x03) + body_len--; + + if (key_type == CKK_EC && body_len > 0) { /* - * (We only support uncompressed for now) - * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" - * So a "256" bit key has x and y of 32 bytes each - * something like: "04 41 04||x||y" - * Do simple size calculation based on DER encoding - */ - if ((size - 2) <= 127) - ksize = (size - 3) * 4; - else if ((size - 3) <= 255) - ksize = (size - 4) * 4; - else - ksize = (size - 5) * 4; - } else { - /* - * EDDSA and XEDDSA in PKCS11 are in bit strings. - * need to drop '03' tag, len (in bytes) and 00 bits in last byte. + * (We only support uncompressed for now) + * Uncompressed EC_POINT is DER OCTET STRING + * or DER BIT STRING "04||x||y" + * So a "256" bit key has x and y of 32 bytes each + * something like: "03 42 00 04|x|y" or "04 41 04||x||y" + * Do simple size calculation based on DER encoding */ - if ((size - 3) < 127) - ksize = (size - 3) * 8; - else if ((size - 4) <= 255) - ksize = (size - 4) * 8; - else - ksize = (size - 5) * 8; - + ksize = (body_len - 1) * 4; + } else if (body_len > 0) { + /* + * EDDSA and XEDDSA in PKCS11 and only one coordinate + */ + ksize = (body_len) * 8; } - printf(" EC_POINT %lu bits\n", ksize); + if (ksize) + printf(" EC_POINT %lu bits\n", ksize); + else + printf(" EC_POINT size unknown"); + if (bytes) { if ((CK_LONG)size > 0) { /* Will print the point here */ printf(" EC_POINT: "); From 62ac0c69197daeadac1931c2f6a210648b155a87 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 17 Apr 2024 15:03:57 -0500 Subject: [PATCH 3654/4321] pkcs11-tool.c - remore wrap/unwrap from template On branch X25519-improvements-2 Changes to be committed: modified: pkcs11-tool.c --- src/tools/pkcs11-tool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 605b11fb84..175ab9d0df 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5226,8 +5226,6 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type) }, {CKA_SENSITIVE, &_false, sizeof(_false) }, {CKA_EXTRACTABLE, &_true, sizeof(_true) }, - {CKA_WRAP, &_true, sizeof(_true) }, - {CKA_UNWRAP, &_true, sizeof(_true) }, }; //clang-format on int n_attrs = 7; From 312ce3be0c7687f99885dd29d64503d21c08cd4c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 8 Dec 2023 20:08:06 -0600 Subject: [PATCH 3655/4321] pkcs15.h - PKCS11 ecparams are used by CKK_EC, CKK_EDWARDS and CKK_MONTGOMERY Remove redundent code for struct sc_pkcs15_prkey_eddsa eddsa. Please enter the commit message for your changes. Lines starting --- src/libopensc/pkcs15.h | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index e4be6f12aa..361569e952 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -203,19 +203,10 @@ struct sc_pkcs15_pubkey_ec { struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */ }; -struct sc_pkcs15_pubkey_eddsa { - struct sc_pkcs15_u8 pubkey; -}; - struct sc_pkcs15_prkey_ec { struct sc_ec_parameters params; - sc_pkcs15_bignum_t privateD; /* note this is bignum */ - struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */ -}; - -struct sc_pkcs15_prkey_eddsa { - struct sc_pkcs15_u8 pubkey; - struct sc_pkcs15_u8 value; + struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */ + sc_pkcs15_bignum_t privateD; /* note this is bignum */ }; struct sc_pkcs15_pubkey_gostr3410 { @@ -236,7 +227,6 @@ struct sc_pkcs15_pubkey { union { struct sc_pkcs15_pubkey_rsa rsa; struct sc_pkcs15_pubkey_ec ec; - struct sc_pkcs15_pubkey_eddsa eddsa; struct sc_pkcs15_pubkey_gostr3410 gostr3410; } u; }; @@ -249,7 +239,6 @@ struct sc_pkcs15_prkey { union { struct sc_pkcs15_prkey_rsa rsa; struct sc_pkcs15_prkey_ec ec; - struct sc_pkcs15_prkey_eddsa eddsa; struct sc_pkcs15_prkey_gostr3410 gostr3410; struct sc_pkcs15_skey secret; } u; @@ -716,7 +705,7 @@ int sc_pkcs15_decode_pubkey_ec(struct sc_context *, int sc_pkcs15_encode_pubkey_ec(struct sc_context *, struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_encode_pubkey_eddsa(struct sc_context *, - struct sc_pkcs15_pubkey_eddsa *, u8 **, size_t *); + struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_decode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, const u8 *, size_t); int sc_pkcs15_encode_pubkey(struct sc_context *, From afe9fb49d0f813e4ae1ea49fc1b24c69c18125f3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 8 Dec 2023 20:18:51 -0600 Subject: [PATCH 3656/4321] pkcs15-prkey.c pkcs15-pubkey.c - Use common EC params On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-prkey.c modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-prkey.c | 10 +-- src/libopensc/pkcs15-pubkey.c | 115 +++++++++------------------------- src/pkcs11/framework-pkcs15.c | 20 +++--- src/tools/pkcs15-tool.c | 4 +- 4 files changed, 39 insertions(+), 110 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 5ecee4be20..e9cffd9f05 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -569,20 +569,12 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key) case SC_ALGORITHM_GOSTR3410: free(key->u.gostr3410.d.data); break; - case SC_ALGORITHM_EC: + case SC_ALGORITHM_EC: /* EC, Edwards and Montgomery use common ec params */ free(key->u.ec.params.der.value); free(key->u.ec.params.named_curve); free(key->u.ec.privateD.data); free(key->u.ec.ecpointQ.value); break; - case SC_ALGORITHM_EDDSA: - free(key->u.eddsa.pubkey.value); - key->u.eddsa.pubkey.value = NULL; - key->u.eddsa.pubkey.len = 0; - free(key->u.eddsa.value.value); - key->u.eddsa.value.value = NULL; - key->u.eddsa.value.len = 0; - break; } sc_mem_clear(key, sizeof(*key)); } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index eb136973e2..035746612f 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -542,13 +542,6 @@ static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_EDDSA_PUBKEY_SIZE 2 -static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = { - { "pubkey", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL }, - { NULL, 0, 0, 0, NULL, NULL } -}; - - int sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, const u8 *buf, size_t buflen) @@ -690,47 +683,27 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, } /* - * EdDSA keys are just byte strings. For now only - * for Ed25519 keys 32B length are supported +all "ec" keys uses same pubkey format, keep this external entrypoint + * keys are just byte strings. */ int sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, - struct sc_pkcs15_pubkey_eddsa *key, + struct sc_pkcs15_pubkey_ec *key, const u8 *buf, size_t buflen) { - int r; - u8 * pubkey = NULL; - size_t pubkey_len; - struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; - - LOG_FUNC_CALLED(ctx); - sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 0, &pubkey, &pubkey_len, 1); - r = sc_asn1_decode(ctx, asn1_eddsa_pubkey, buf, buflen, NULL, NULL); - if (r < 0) - LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); - - key->pubkey.len = pubkey_len; - key->pubkey.value = pubkey; - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + return sc_pkcs15_decode_pubkey_ec(ctx, key, buf, buflen); } +/* + * all "ec" keys uses same pubkey format, keep this external entrypoint + */ int -sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_eddsa *key, +sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { - struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; - - LOG_FUNC_CALLED(ctx); - sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->pubkey.value, &key->pubkey.len, 1); - - LOG_FUNC_RETURN(ctx, - sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); + return sc_pkcs15_encode_pubkey_ec(ctx, key, buf, buflen); } - int sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, u8 **buf, size_t *len) @@ -739,11 +712,8 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_encode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); - if (key->algorithm == SC_ALGORITHM_EC) + if (key->algorithm == SC_ALGORITHM_EC || key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) return sc_pkcs15_encode_pubkey_ec(ctx, &key->u.ec, buf, len); - if (key->algorithm == SC_ALGORITHM_EDDSA || - key->algorithm == SC_ALGORITHM_XEDDSA) /* XXX encoding is the same here */ - return sc_pkcs15_encode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len); sc_log(ctx, "Encoding of public key type %lu not supported", key->algorithm); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); @@ -789,6 +759,8 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk switch (pubkey->algorithm) { case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: /* * most keys, but not EC have only one encoding. * For a SPKI, the ecpoint is placed directly in the @@ -826,14 +798,6 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; break; - case SC_ALGORITHM_EDDSA: - case SC_ALGORITHM_XEDDSA: - /* For a SPKI, the pubkey is placed directly in the BIT STRING */ - pkey.value = malloc(pubkey->u.eddsa.pubkey.len); - memcpy(pkey.value, pubkey->u.eddsa.pubkey.value, pubkey->u.eddsa.pubkey.len); - // Should be pkey.len = 0 there? - key_len = pubkey->u.eddsa.pubkey.len * 8; - break; default: r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; @@ -865,11 +829,8 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_decode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); - if (key->algorithm == SC_ALGORITHM_EC) + if (key->algorithm == SC_ALGORITHM_EC || key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) return sc_pkcs15_decode_pubkey_ec(ctx, &key->u.ec, buf, len); - if (key->algorithm == SC_ALGORITHM_EDDSA || - key->algorithm == SC_ALGORITHM_XEDDSA) - return sc_pkcs15_decode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len); sc_log(ctx, "Decoding of public key type %lu not supported", key->algorithm); return SC_ERROR_NOT_SUPPORTED; @@ -1030,29 +991,20 @@ sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prv case SC_ALGORITHM_GOSTR3410: break; case SC_ALGORITHM_EC: - pubkey->u.ec.ecpointQ.value = malloc(prvkey->u.ec.ecpointQ.len); - if (!pubkey->u.ec.ecpointQ.value) { - sc_pkcs15_free_pubkey(pubkey); - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - } - memcpy(pubkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.len); - pubkey->u.ec.ecpointQ.len = prvkey->u.ec.ecpointQ.len; - break; case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: /* Copy pubkey */ - if (prvkey->u.eddsa.pubkey.value == NULL || prvkey->u.eddsa.pubkey.len <= 0) { + if (prvkey->u.ec.ecpointQ.value == NULL || prvkey->u.ec.ecpointQ.len <= 0) { sc_pkcs15_free_pubkey(pubkey); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); } - pubkey->u.eddsa.pubkey.value = malloc(prvkey->u.eddsa.pubkey.len); - if (!pubkey->u.eddsa.pubkey.value) { + pubkey->u.ec.ecpointQ.value = malloc(prvkey->u.ec.ecpointQ.len); + if (!pubkey->u.ec.ecpointQ.value) { sc_pkcs15_free_pubkey(pubkey); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } - memcpy(pubkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.len); - pubkey->u.eddsa.pubkey.len = prvkey->u.eddsa.pubkey.len; - + memcpy(pubkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.len); + pubkey->u.ec.ecpointQ.len = prvkey->u.ec.ecpointQ.len; break; default: sc_log(ctx, "Unsupported private key algorithm"); @@ -1111,6 +1063,8 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc case SC_ALGORITHM_GOSTR3410: break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: pubkey->u.ec.ecpointQ.value = malloc(key->u.ec.ecpointQ.len); if (!pubkey->u.ec.ecpointQ.value) { rv = SC_ERROR_OUT_OF_MEMORY; @@ -1137,18 +1091,6 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc rv = SC_ERROR_NOT_SUPPORTED; } - break; - case SC_ALGORITHM_EDDSA: - case SC_ALGORITHM_XEDDSA: - /* Copy pubkey */ - pubkey->u.eddsa.pubkey.value = malloc(key->u.eddsa.pubkey.len); - if (!pubkey->u.eddsa.pubkey.value) { - rv = SC_ERROR_OUT_OF_MEMORY; - break; - } - memcpy(pubkey->u.eddsa.pubkey.value, key->u.eddsa.pubkey.value, key->u.eddsa.pubkey.len); - pubkey->u.eddsa.pubkey.len = key->u.eddsa.pubkey.len; - break; default: sc_log(ctx, "Unsupported private key algorithm"); @@ -1187,6 +1129,8 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) free(key->u.gostr3410.xy.data); break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: if (key->u.ec.params.der.value) free(key->u.ec.params.der.value); if (key->u.ec.params.named_curve) @@ -1194,12 +1138,6 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) if (key->u.ec.ecpointQ.value) free(key->u.ec.ecpointQ.value); break; - case SC_ALGORITHM_EDDSA: - case SC_ALGORITHM_XEDDSA: - free(key->u.eddsa.pubkey.value); - key->u.eddsa.pubkey.value = NULL; - key->u.eddsa.pubkey.len = 0; - break; } sc_mem_clear(key, sizeof(*key)); } @@ -1404,9 +1342,9 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke } else if (pk_alg.algorithm == SC_ALGORITHM_EDDSA || pk_alg.algorithm == SC_ALGORITHM_XEDDSA) { /* EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING */ - pubkey->u.eddsa.pubkey.value = malloc(pk.len); - memcpy(pubkey->u.eddsa.pubkey.value, pk.value, pk.len); - pubkey->u.eddsa.pubkey.len = pk.len; + pubkey->u.ec.ecpointQ.value = malloc(pk.len); + memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len); + pubkey->u.ec.ecpointQ.len = pk.len; } else { /* Public key is expected to be encapsulated into BIT STRING */ r = sc_pkcs15_decode_pubkey(ctx, pubkey, pk.value, pk.len); @@ -1513,11 +1451,14 @@ static struct ec_curve_info { {"ed25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255}, + {"Ed25519", "1.3.101.112", "06032b6570", 255}, + {"X25519", "1.3.101.110", "06032b656e", 255}, {NULL, NULL, NULL, 0}, /* Do not touch this */ }; +/* TODO DEE add changes for mapping */ int sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams) { diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 763165d867..9160d8fa70 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3385,7 +3385,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, keybits = 1024; /* Default key size */ /* TODO: check allowed values of keybits */ } - else if (keytype == CKK_EC) { + else if (keytype == CKK_EC || keytype == CKK_EC_EDWARDS || keytype == CKK_EC_MONTGOMERY) { struct sc_lv_data *der = &keygen_args.prkey_args.key.u.ec.params.der; void *ptr = NULL; @@ -3397,26 +3397,22 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, return rv; } + } + + if (keytype == CKK_EC) { keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EC; pub_args.key.algorithm = SC_ALGORITHM_EC; } else if (keytype == CKK_EC_EDWARDS) { - /* TODO Validate EC_PARAMS contains curveName "edwards25519" or "edwards448" (from RFC 8032) - * or id-Ed25519 or id-Ed448 (or equivalent OIDs in oId field) (from RFC 8410) - * otherwise return CKR_CURVE_NOT_SUPPORTED - */ keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EDDSA; + keygen_args.prkey_args.usage |= SC_PKCS15_PRKEY_USAGE_SIGN; pub_args.key.algorithm = SC_ALGORITHM_EDDSA; - return CKR_CURVE_NOT_SUPPORTED; } else if (keytype == CKK_EC_MONTGOMERY) { - /* TODO Validate EC_PARAMS contains curveName "curve25519" or "curve448" (from RFC 7748) - * or id-X25519 or id-X448 (or equivalent OIDs in oId field) (from RFC 8410) - * otherwise return CKR_CURVE_NOT_SUPPORTED - */ keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_XEDDSA; + /* Can not sign. To created a cert, see: openssl x509 -force_pubkey */ + keygen_args.prkey_args.usage |= SC_PKCS15_PRKEY_USAGE_DERIVE; pub_args.key.algorithm = SC_ALGORITHM_XEDDSA; - return CKR_CURVE_NOT_SUPPORTED; } else { /* CKA_KEY_TYPE is set, but keytype isn't correct */ @@ -6017,7 +6013,7 @@ get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) switch (key->algorithm) { case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: - rc = sc_pkcs15_encode_pubkey_eddsa(context, &key->u.eddsa, &value, &value_len); + rc = sc_pkcs15_encode_pubkey_eddsa(context, &key->u.ec, &value, &value_len); if (rc != SC_SUCCESS) return sc_to_cryptoki_error(rc, NULL); diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 59551c97e5..fc5df6b5eb 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1021,7 +1021,7 @@ static int read_ssh_key(void) unsigned char buf[64]; size_t n, len; - n = pubkey->u.eddsa.pubkey.len; + n = pubkey->u.ec.ecpointQ.len; if (n != 32) { fprintf(stderr, "Wrong public key length\n"); goto fail2; @@ -1039,7 +1039,7 @@ static int read_ssh_key(void) buf[len++] = 0; buf[len++] = 0; buf[len++] = n & 0xff; - memcpy(buf + len, pubkey->u.eddsa.pubkey.value, n); + memcpy(buf + len, pubkey->u.ec.ecpointQ.value, n); len += n; print_ssh_key(outf, alg, obj, buf, len); From c7ba42a0287e00c8649f71514595420318245b92 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 9 Dec 2023 16:39:20 -0600 Subject: [PATCH 3657/4321] card-openpgp.c - Use common "ec_pointQ" for EC, EDDSA and XEDDSA In previous OpenSC code EC public key is called a ec_pointQ. EDDSA and XEDDSA called it public. Both are stored asvalue and len. So to simplify the code, we use the same structures. The difference comes when they are returned in pkcs11. EC is encoded in an OCTET STRING, The others are iencoded in a BIT STRING. Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 78328ffcf2..0d88e79b28 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1709,8 +1709,8 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* In EDDSA key case we do not have to care about OIDs * as we support only one for now */ p15pubkey.algorithm = SC_ALGORITHM_EDDSA; - p15pubkey.u.eddsa.pubkey.value = pubkey_blob->data; - p15pubkey.u.eddsa.pubkey.len = pubkey_blob->len; + p15pubkey.u.ec.ecpointQ.value = pubkey_blob->data; + p15pubkey.u.ec.ecpointQ.len = pubkey_blob->len; /* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use * of the curveName selection to specify a curve name as defined * in [RFC 8032] */ @@ -1720,8 +1720,8 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* This yields either EC(DSA) key or EC_MONTGOMERY (curve25519) key */ if (sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) { p15pubkey.algorithm = SC_ALGORITHM_XEDDSA; - p15pubkey.u.eddsa.pubkey.value = pubkey_blob->data; - p15pubkey.u.eddsa.pubkey.len = pubkey_blob->len; + p15pubkey.u.ec.ecpointQ.value = pubkey_blob->data; + p15pubkey.u.ec.ecpointQ.len = pubkey_blob->len; /* PKCS#11 3.0 2.3.7 Montgomery EC public keys only support * the use of the curveName selection to specify a curve * name as defined in [RFC7748] */ @@ -1762,14 +1762,12 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) p15pubkey.u.rsa.modulus.len = 0; p15pubkey.u.rsa.exponent.data = NULL; p15pubkey.u.rsa.exponent.len = 0; - } else if (p15pubkey.algorithm == SC_ALGORITHM_EC) { + } else if (p15pubkey.algorithm == SC_ALGORITHM_EC + || p15pubkey.algorithm == SC_ALGORITHM_EDDSA + || p15pubkey.algorithm == SC_ALGORITHM_XEDDSA) { p15pubkey.u.ec.ecpointQ.value = NULL; p15pubkey.u.ec.ecpointQ.len = 0; /* p15pubkey.u.ec.params.der and named_curve will be freed by sc_pkcs15_erase_pubkey */ - } else if (p15pubkey.algorithm == SC_ALGORITHM_EDDSA - || p15pubkey.algorithm == SC_ALGORITHM_XEDDSA) { - p15pubkey.u.eddsa.pubkey.value = NULL; - p15pubkey.u.eddsa.pubkey.len = 0; } sc_pkcs15_erase_pubkey(&p15pubkey); From 0bcca6056797194cacc0e59293f9c88ae1002367 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 9 Dec 2023 18:57:26 -0600 Subject: [PATCH 3658/4321] pkcs15init/pkcs15-lib.c pkcs15init/pkcs15-openpgp.c - EDDSA and XEDDSA Improvments to allow for key generation via pkcs11 or pkcs15 Date: Sat Dec 9 18:57:26 2023 -0600 On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-lib.c modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-lib.c | 23 +++++++++++++++++------ src/pkcs15init/pkcs15-openpgp.c | 5 +++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 943d53e987..26d0e5239c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1303,10 +1303,12 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof keyinfo_gostparams->gostr3410 = keyargs->params.gost.gostr3410; keyinfo_gostparams->gostr3411 = keyargs->params.gost.gostr3411; keyinfo_gostparams->gost28147 = keyargs->params.gost.gost28147; - } - else if (key->algorithm == SC_ALGORITHM_EC) { + } else if (key->algorithm == SC_ALGORITHM_EC || + key->algorithm == SC_ALGORITHM_EDDSA || + key->algorithm == SC_ALGORITHM_XEDDSA) { /* keyargs->key.u.ec.params.der.value is allocated in keyargs, which is on stack */ struct sc_ec_parameters *ecparams = &keyargs->key.u.ec.params; + new_ecparams = calloc(1, sizeof(struct sc_ec_parameters)); if (!new_ecparams) { r = SC_ERROR_OUT_OF_MEMORY; @@ -1603,8 +1605,9 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr pubkey_args.params.gost = keygen_args->prkey_args.params.gost; r = sc_copy_gost_params(&(pubkey_args.key.u.gostr3410.params), &(keygen_args->prkey_args.key.u.gostr3410.params)); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate GOST parameters"); - } - else if (algorithm == SC_ALGORITHM_EC) { + } else if (algorithm == SC_ALGORITHM_EC || + algorithm == SC_ALGORITHM_EDDSA || + algorithm == SC_ALGORITHM_XEDDSA) { /* needs to be freed in case of failure when pubkey is not set yet */ r = sc_copy_ec_params(&pubkey_args.key.u.ec.params, &keygen_args->prkey_args.key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC parameters"); @@ -2526,7 +2529,9 @@ check_keygen_params_consistency(struct sc_card *card, struct sc_context *ctx = card->ctx; int i, rv; - if (alg == SC_ALGORITHM_EC && prkey) { + if (prkey && (alg == SC_ALGORITHM_EC || + alg == SC_ALGORITHM_EDDSA || + alg == SC_ALGORITHM_XEDDSA)) { struct sc_ec_parameters *ecparams = &prkey->key.u.ec.params; rv = sc_pkcs15_fix_ec_parameters(ctx, ecparams); @@ -2549,7 +2554,9 @@ check_keygen_params_consistency(struct sc_card *card, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - if (alg == SC_ALGORITHM_EC && prkey) + if (prkey && (alg == SC_ALGORITHM_EC || + alg == SC_ALGORITHM_EDDSA || + alg == SC_ALGORITHM_XEDDSA)) /* allocated in sc_pkcs15_fix_ec_parameters */ free(prkey->key.u.ec.params.der.value); @@ -2779,6 +2786,10 @@ key_pkcs15_algo(struct sc_pkcs15_card *p15card, unsigned long algorithm) return SC_PKCS15_TYPE_PRKEY_GOSTR3410; case SC_ALGORITHM_EC: return SC_PKCS15_TYPE_PRKEY_EC; + case SC_ALGORITHM_EDDSA: + return SC_PKCS15_TYPE_PRKEY_EDDSA; + case SC_ALGORITHM_XEDDSA: + return SC_PKCS15_TYPE_PRKEY_XEDDSA; case SC_ALGORITHM_DES: return SC_PKCS15_TYPE_SKEY_DES; case SC_ALGORITHM_3DES: diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 553c8acea8..5ec7cbc64d 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -385,8 +385,9 @@ static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card r = openpgp_generate_key_ec(card, obj, pubkey); break; case SC_PKCS15_TYPE_PRKEY_EDDSA: - if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EdDSA is not supported on this card"); + case SC_PKCS15_TYPE_PRKEY_XEDDSA: + if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && card->type < SC_CARD_TYPE_OPENPGP_V3) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EdDSA or XEDDSA are not supported on this card"); return SC_ERROR_NOT_SUPPORTED; } r = openpgp_generate_key_ec(card, obj, pubkey); From 7996d340125c46c0e1f4ebd8b9310dee463a6fa5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 9 Dec 2023 19:15:51 -0600 Subject: [PATCH 3659/4321] card-openpgp.c - add SC_ALGORITHM_ONBOARD_KEY_GEN This will add PKCS11 key gen mechanisms. On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0d88e79b28..8bac24a634 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -89,8 +89,8 @@ static struct sc_card_driver pgp_drv = { static pgp_ec_curves_t ec_curves_openpgp34[] = { /* OpenPGP 3.4+ Ed25519 and Curve25519 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ @@ -109,8 +109,8 @@ struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; static pgp_ec_curves_t ec_curves_gnuk[] = { {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 10, -1}}, 256}, /* secp256k1 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ {{{-1}}, 0} /* This entry must not be touched. */ }; @@ -687,7 +687,7 @@ int _pgp_handle_curve25519(sc_card_t *card, * OpenPGP card supports only derivation using these * keys as far as I know */ _sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_ECDH_CDH_RAW, 0, &key_info.u.ec.oid); + SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); sc_log(card->ctx, "DO %uX: Added XEDDSA algorithm (%d), mod_len = %zu", do_num, SC_ALGORITHM_XEDDSA, key_info.u.ec.key_length); return 1; @@ -739,7 +739,7 @@ int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, un if (_pgp_handle_curve25519(card, key_info, do_num)) break; _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid); + SC_ALGORITHM_EDDSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); sc_log(card->ctx, "DO %uX: Added EDDSA algorithm (%d), mod_len = %zu" , do_num, key_info.algorithm, key_info.u.ec.key_length); @@ -3040,11 +3040,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA + && card->type != SC_CARD_TYPE_OPENPGP_GNUK && priv->bcd_version < OPENPGP_CARD_3_0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA - && card->type != SC_CARD_TYPE_OPENPGP_GNUK) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* set Control Reference Template for key */ if (key_info->key_id == SC_OPENPGP_KEY_SIGN) From 8f3b1ce959c807ce6be0f85e094472bfc4b06d90 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 10 Dec 2023 17:08:05 -0600 Subject: [PATCH 3660/4321] pkcs15-pubkey.c update ec curves and map printable strings GnuPG says with version 5 cards, the RFC8410 OIDs can be written to the card so we will accept these and if needed use the older OpenPGP curves on older cards within the card-openpgp.c ec_params using the printablestring will be mapped to ones with OIDs if possible/ Date: Sun Dec 10 17:08:05 2023 -0600 On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 95 ++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 035746612f..66c894585f 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -683,7 +683,7 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, } /* -all "ec" keys uses same pubkey format, keep this external entrypoint + * all "ec" keys uses same pubkey format, keep this external entrypoint * keys are just byte strings. */ int @@ -1449,47 +1449,84 @@ static struct ec_curve_info { {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192}, {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256}, - {"ed25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255}, - {"Ed25519", "1.3.101.112", "06032b6570", 255}, + /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ + + {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060a2B060104019755010501", 255}, + + /* RFC 8410 defined curves */ {"X25519", "1.3.101.110", "06032b656e", 255}, + {"X448", "1.3.101.111", "06032b656f", 448}, + {"Ed25519", "1.3.101.112", "06032b6570", 255}, + {"Ed448", "1.3.101.113", "06032b6571", 448}, + /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ + {"cv25519", "1.3.101.110", "06032b656e", 255}, + {"ed25519", "1.3.101.112", "06032b6570", 255}, + {NULL, NULL, NULL, 0}, /* Do not touch this */ }; -/* TODO DEE add changes for mapping */ int sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams) { int rv, ii; + int mapped = 0; LOG_FUNC_CALLED(ctx); /* In PKCS#11 EC parameters arrives in DER encoded form */ - if (ecparams->der.value && ecparams->der.len) { - for (ii=0; ec_curve_infos[ii].name; ii++) { - struct sc_object_id id; - unsigned char *buf = NULL; - size_t len = 0; - - sc_format_oid(&id, ec_curve_infos[ii].oid_str); - sc_encode_oid (ctx, &id, &buf, &len); + if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { + switch (ecparams->der.value[0]) { + case 0x06: /* OID */ + for (ii=0; ec_curve_infos[ii].name; ii++) { + struct sc_object_id id; + unsigned char *buf = NULL; + size_t len = 0; + + sc_format_oid(&id, ec_curve_infos[ii].oid_str); + sc_encode_oid (ctx, &id, &buf, &len); + + if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) { + free(buf); + break; + } + free(buf); + } + break; - if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) { - free(buf); + case 0x13: /* printable string max of 127 */ + if (ecparams->der.value[1] != ecparams->der.len - 2) { + sc_log(ctx, "Unsupported ec params"); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + } + for (ii=0; ec_curve_infos[ii].name; ii++) { + size_t len = strlen(ec_curve_infos[ii].name); + if (ecparams->der.len - 2 != len + || memcmp(ec_curve_infos[ii].name, ecparams->der.value + 2, len) != 0) + continue; + /* force replacement of printable string to allow mapping */ + mapped = 1; + break; + } break; - } - free(buf); + default: + sc_log(ctx, "Unsupported ec params"); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } - /* TODO: support of explicit EC parameters form */ if (!ec_curve_infos[ii].name) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve"); sc_log(ctx, "Found known curve '%s'", ec_curve_infos[ii].name); - if (!ecparams->named_curve) { + if (mapped) { + free(ecparams->named_curve); + ecparams->named_curve = NULL; + } + + if (!ecparams->named_curve) { ecparams->named_curve = strdup(ec_curve_infos[ii].name); if (!ecparams->named_curve) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); @@ -1497,21 +1534,33 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp sc_log(ctx, "Curve name: '%s'", ecparams->named_curve); } - if (!sc_valid_oid(&ecparams->id)) + if (!sc_valid_oid(&ecparams->id) || mapped) sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str); ecparams->field_length = ec_curve_infos[ii].size; sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u", ecparams->field_length); + if (mapped) { + /* replace the printable string version with the mapped oid */ + free(ecparams->der.value); + ecparams->der.len = strlen(ec_curve_infos[ii].oid_encoded) / 2; + ecparams->der.value = malloc(ecparams->der.len); + if (!ecparams->der.value) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + if (sc_hex_to_bin(ec_curve_infos[ii].oid_encoded, ecparams->der.value, &ecparams->der.len) < 0) { + free(ecparams->der.value); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } + } } - else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */ - for (ii=0; ec_curve_infos[ii].name; ii++) { + else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */ + for (ii=0; ec_curve_infos[ii].name; ii++) { if (!strcmp(ec_curve_infos[ii].name, ecparams->named_curve)) break; if (!strcmp(ec_curve_infos[ii].oid_str, ecparams->named_curve)) break; } - if (!ec_curve_infos[ii].name) { + if (!ec_curve_infos[ii].name) { sc_log(ctx, "Named curve '%s' not supported", ecparams->named_curve); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } From 4c2461f8d8b96e154550ef5ae2f35db84b5640c1 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 21 Jan 2024 06:55:39 -0600 Subject: [PATCH 3661/4321] pkcs15-init.c squash adding additional if statement Changes to be committed: modified: src/tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 1ebb29d280..b236112fc6 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -724,6 +724,8 @@ static const struct alg_spec alg_types_asym[] = { { "rsa", SC_ALGORITHM_RSA, 1024 }, { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, + { "eddsa", SC_ALGORITHM_EDDSA, 0 }, + { "xeddsa", SC_ALGORITHM_XEDDSA, 0 }, { NULL, -1, 0 } }; @@ -750,7 +752,9 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key spec++; if (*spec) { - if (isalpha((unsigned char)*spec) && algorithm == SC_ALGORITHM_EC && prkey) { + if (isalpha((unsigned char)*spec) + && (algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || SC_ALGORITHM_XEDDSA) + && prkey) { prkey->u.ec.params.named_curve = strdup(spec); } else { *keybits = (unsigned)strtoul(spec, &end, 10); From da5e8dfac527b43de7c19c075dbda0d7e74d328d Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 15 Jan 2024 12:57:33 -0600 Subject: [PATCH 3662/4321] pkcs15-algo.c - add Ed448, X448 and openpgp oids Changes to be committed: modified: libopensc/pkcs15-algo.c --- src/libopensc/pkcs15-algo.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 3b1b3ba031..0110b0ccc0 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -448,13 +448,18 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #endif #ifdef SC_ALGORITHM_EDDSA /* aka Ed25519 */ - /* RFC 8410, needed to parse/create X509 certs/pubkeys */ - { SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL }, + /* RFC 8410, needed to parse/create X509 certs/pubkeys */ + /* TODO DEE add asn1_decode_ec_params, asn1_encode_ec_params,asn1_free_ec_params */ + { SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL}, /* Ed25119 */ + { SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL}, /* Ed25519 OID used by OpenPGP */ + { SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}}, NULL, NULL, NULL}, /* Ed448 */ #endif #ifdef SC_ALGORITHM_XEDDSA /* aka curve25519 */ - /* RFC 8410, needed to parse/create X509 certs/pubkeys */ - { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL }, + /* RFC 8410, needed to parse/create X509 certs/pubkeys no ec_parms*/ + { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL}, /* X25519 */ + { SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 -1}}, NULL, NULL, NULL}, /* X25519 OID used by OpenPGP */ + { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}}, NULL, NULL, NULL}, /* X448 */ #endif { -1, {{ -1 }}, NULL, NULL, NULL } }; From 007414e39971334c60e47f99eb2e2d66546d0bd2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 15 Jan 2024 13:00:51 -0600 Subject: [PATCH 3663/4321] OpenPGP - Move mapping of OpenPGP specifix OIDs The mapping of curve OIDs to be written to a card is moved from pkcs15init/pkcs15-openpgp.c to card-openpgp.c pkcs15init/pkcs15-openpgp and pkcs11 can then provide old or new OIDSs. The card driver will remap if needed. Date: Mon Jan 15 13:00:51 2024 -0600 Changes to be committed: modified: src/libopensc/card-openpgp.c modified: src/libopensc/card-openpgp.h modified: src/pkcs15init/pkcs15-openpgp.c --- src/libopensc/card-openpgp.c | 47 ++++++++++++++++++++++++++++----- src/libopensc/card-openpgp.h | 5 ++++ src/pkcs15init/pkcs15-openpgp.c | 13 +++++---- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 8bac24a634..0452986da2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -101,6 +101,12 @@ static pgp_ec_curves_t ec_curves_openpgp34[] = { {{{-1}}, 0} /* This entry must not be touched. */ }; +static pgp_ec_curves_alt_t ec_curves_alt[] = { + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, {{1 ,3 ,101, 110, -1}}, 255}, /* curve25519 CKK_EC_MONTGOMERY X25519 */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ + {{{-1}}, {{-1}}, 0} /* This entry must not be touched. */ +}; + static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; @@ -2500,7 +2506,7 @@ static int pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); - pgp_blob_t *algo_blob; + pgp_blob_t *algo_blob = NULL; const unsigned int tag = 0x00C0 | key_info->key_id; u8 *data; size_t data_len; @@ -2514,19 +2520,46 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) { /* ECDSA and ECDH */ + /* TODO -DEE could map new OIDs to old OID needed for card here */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA){ - data_len = key_info->u.ec.oid_len+1; + /* Note OpenPGP or current cards do not support 448 size keys yet */ + unsigned char *aoid = NULL; /* ASN1 */ + size_t aoid_len; + struct sc_object_id *scoid = NULL; + + scoid = &key_info->u.ec.oid; + /* + * Current OpenPGP cards use pre RFC8410 OIDs for ECDH and EdDSA + * so convert to older versions of the OIDs. + * TODO if newer cards or OpenPGP specs accept RFC8410 code + * will be needed here to not do the conversion + */ + for (i = 0; ec_curves_alt[i].oid.value[0] > 0; i++) { + if (sc_compare_oid(scoid, &ec_curves_alt[i].oid_alt)) { + scoid = &ec_curves_alt[i].oid; + break; + } + } + + r = sc_encode_oid(card->ctx, scoid, &aoid, &aoid_len); + LOG_TEST_RET(card->ctx, r, "invalid ec oid"); + if (aoid == NULL || aoid_len < 3 || aoid[1] > 127) { + free(aoid); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + data_len = aoid_len + 1 - 2; /* +1 for algorithm -2 drop 06 len */ data = malloc(data_len); - if (!data) + if (!data) { + free(aoid); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + } data[0] = key_info->algorithm; - /* oid.value is type int, therefore we need to loop over the values */ - for (i=0; i < key_info->u.ec.oid_len; i++){ - data[i+1] = key_info->u.ec.oid.value[i]; - } + for (i = 0; i < aoid_len - 2; i++) + data[i+1] = aoid[i+2]; } /* RSA */ diff --git a/src/libopensc/card-openpgp.h b/src/libopensc/card-openpgp.h index 36a84086bf..29f5d8a20c 100644 --- a/src/libopensc/card-openpgp.h +++ b/src/libopensc/card-openpgp.h @@ -165,6 +165,11 @@ typedef struct _pgp_ec_curves { size_t size; } pgp_ec_curves_t; +typedef struct _pgp_ec_curves_alt { + struct sc_object_id oid; + struct sc_object_id oid_alt; /* RFC8410 OIDs to be mapped to oid */ + size_t size; +} pgp_ec_curves_alt_t; #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 5ec7cbc64d..a3ad176c6c 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -317,17 +317,15 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ - /* extract oid the way we need to import it to OpenPGP Card */ + /* DEE NO extract oid the way we need to import it to OpenPGP Card */ + /* TODO DEE pass the oid. will convert to asn1 before writing */ + /* TODO DEE not sure id test for der.len >2 is needed */ + /* copying info_ec.id works for any EC ECDH EdDSA keys */ if (info_ec->der.len > 2) - key_info.u.ec.oid_len = info_ec->der.value[1]; + key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - for (i=0; (i < key_info.u.ec.oid_len) && (i+2 < info_ec->der.len); i++){ - key_info.u.ec.oid.value[i] = info_ec->der.value[i+2]; - } - key_info.u.ec.oid.value[key_info.u.ec.oid_len] = -1; - /* Prepare buffer */ key_info.u.ec.ecpoint_len = required->field_length; key_info.u.ec.ecpoint = malloc(key_info.u.ec.ecpoint_len); @@ -340,6 +338,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, /* set pubkey according to response of card */ sc_log(ctx, "Set output ecpoint info"); + /* TODO DEE may need changes for ECDH and EdDSA or XEDDSA */ pubkey->algorithm = SC_ALGORITHM_EC; pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); From 076ccccbf851c042915c6863eec621311ed41d6e Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 15 Jan 2024 13:48:01 -0600 Subject: [PATCH 3664/4321] pkcs15init/pkcs15-opensc.c unused variable On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index a3ad176c6c..dbe2e66227 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -287,8 +287,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; sc_pkcs15_id_t *kid = &(required->id); const struct sc_ec_parameters *info_ec = - (struct sc_ec_parameters *) required->params.data; - unsigned int i; + (struct sc_ec_parameters *)required->params.data; int r; LOG_FUNC_CALLED(ctx); @@ -322,7 +321,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, /* TODO DEE not sure id test for der.len >2 is needed */ /* copying info_ec.id works for any EC ECDH EdDSA keys */ if (info_ec->der.len > 2) - key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ + key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); From 500aec716ff1faab3087faaf0d87748ae99d9f26 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 20 Jan 2024 12:41:06 -0600 Subject: [PATCH 3665/4321] tools/pkcs15-init.c accept and case and convert to correct case Accept any case of curve names but pass corrected case to lower level routines. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index b236112fc6..8640900d54 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -720,23 +720,40 @@ static const struct alg_spec alg_types_sym[] = { { NULL, -1, 0 } }; +/* RSA can have a number , default is 2048 */ +/* EC require a curve name */ +/* EDDSA and XEDDSA without a size require a size or curve name or OID */ +/* other EDDSA and XEDDSA can be used alone */ static const struct alg_spec alg_types_asym[] = { - { "rsa", SC_ALGORITHM_RSA, 1024 }, + { "rsa", SC_ALGORITHM_RSA, 2048 }, /* new default */ { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, - { "eddsa", SC_ALGORITHM_EDDSA, 0 }, + { "EdDSA", SC_ALGORITHM_EDDSA, 0 }, /* RFC 8410 section 8 */ { "xeddsa", SC_ALGORITHM_XEDDSA, 0 }, + { "ECDH", SC_ALGORITHM_XEDDSA, 0 }, /* RFC 8410 section 8 */ + /* RFC 8410 */ + { "Ed25519", SC_ALGORITHM_EDDSA, 255 }, /* RFC 8410 and gunpg */ + { "Ed448", SC_ALGORITHM_EDDSA, 448 }, + { "X25519", SC_ALGORITHM_XEDDSA, 255 }, + { "X448", SC_ALGORITHM_XEDDSA, 448 }, + /* used by Yubikey and GNUK */ + { "edwards25519", SC_ALGORITHM_EDDSA, 255 }, + { "curve25519", SC_ALGORITHM_XEDDSA, 255 }, + /* gnupg */ + { "cv25519", SC_ALGORITHM_XEDDSA, 255 }, + { NULL, -1, 0 } }; static int parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *keybits, struct sc_pkcs15_prkey *prkey) { - int i, algorithm = -1; + int i, types_idx = -1, algorithm = -1; char *end; for (i = 0; types[i].spec; i++) { if (!strncasecmp(spec, types[i].spec, strlen(types[i].spec))) { + types_idx = i; /* save index of types array */ algorithm = types[i].algorithm; *keybits = types[i].keybits; spec += strlen(types[i].spec); @@ -750,12 +767,19 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key if (*spec == '/' || *spec == '-' || *spec == ':') spec++; + + /* if we have everything for EDDSA or XEDDSA */ + if (*spec == 0x00 && *keybits && (algorithm == SC_ALGORITHM_EDDSA || SC_ALGORITHM_XEDDSA) && prkey) { + prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* correct case */ + *keybits = types[types_idx].keybits; + return algorithm; + } if (*spec) { if (isalpha((unsigned char)*spec) && (algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || SC_ALGORITHM_XEDDSA) && prkey) { - prkey->u.ec.params.named_curve = strdup(spec); + prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* copy correct case */ } else { *keybits = (unsigned)strtoul(spec, &end, 10); if (*end) { From d3b0dbc29ae9c8392b7c150e7729b66bbfcc6f6a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 20 Jan 2024 12:43:26 -0600 Subject: [PATCH 3666/4321] card-openpgp.c card-openpgp.h fix so will compile on mingw Date: Sat Jan 20 12:43:26 2024 -0600 Changes to be committed: modified: src/libopensc/card-openpgp.c modified: src/libopensc/card-openpgp.h --- src/libopensc/card-openpgp.c | 4 +++- src/libopensc/card-openpgp.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0452986da2..3ae557e391 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -101,11 +101,13 @@ static pgp_ec_curves_t ec_curves_openpgp34[] = { {{{-1}}, 0} /* This entry must not be touched. */ }; +#ifdef ENABLE_OPENSSL static pgp_ec_curves_alt_t ec_curves_alt[] = { {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, {{1 ,3 ,101, 110, -1}}, 255}, /* curve25519 CKK_EC_MONTGOMERY X25519 */ {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ {{{-1}}, {{-1}}, 0} /* This entry must not be touched. */ }; +#endif /* ENABLE_OPENSSL */ static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; @@ -2536,7 +2538,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ * TODO if newer cards or OpenPGP specs accept RFC8410 code * will be needed here to not do the conversion */ - for (i = 0; ec_curves_alt[i].oid.value[0] > 0; i++) { + for (i = 0; ec_curves_alt[i].size > 0; i++) { if (sc_compare_oid(scoid, &ec_curves_alt[i].oid_alt)) { scoid = &ec_curves_alt[i].oid; break; diff --git a/src/libopensc/card-openpgp.h b/src/libopensc/card-openpgp.h index 29f5d8a20c..732ca3a325 100644 --- a/src/libopensc/card-openpgp.h +++ b/src/libopensc/card-openpgp.h @@ -165,11 +165,13 @@ typedef struct _pgp_ec_curves { size_t size; } pgp_ec_curves_t; +#ifdef ENABLE_OPENSSL typedef struct _pgp_ec_curves_alt { struct sc_object_id oid; struct sc_object_id oid_alt; /* RFC8410 OIDs to be mapped to oid */ size_t size; } pgp_ec_curves_alt_t; +#endif /* ENABLE_OPENSSL */ #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) From 2efa25c0802522ec5afd9d9b6523bbf8279d9389 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 20 Jan 2024 21:07:23 -0600 Subject: [PATCH 3667/4321] doc/tools/pkcs15-init.1.xml document Curve names for eddsa and xeddsa Changes to be committed: modified: doc/tools/pkcs15-init.1.xml --- doc/tools/pkcs15-init.1.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 5ddaad56a3..9c5018297c 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -139,7 +139,13 @@ where keyspec describes the algorithm and the parameters of the key to be created. For example, rsa:2048 generates a RSA key with 2048-bit modulus. If you are generating an EC key, the curve designation must - be specified, for example ec:prime256v1. For symmetric key, + be specified, for example ec:prime256v1. + The following curves do not need parameters: + Edwards 25519 curves use one of these equivalent names: Ed25519(preferred), ed25519 or edwards25519 + and for the 448 curve use: Ed448. + For Montgomery 25519 curves use one of these equivalent names: X25519(preferred), cv25519 or curve25519 + and for the 448 curve use: X448. + For symmetric key, the length of key is specified in bytes, for example AES:32 or DES3:24. From a331060f5a113f7c4528a74a3bdc19153701ef78 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 27 Jan 2024 20:22:57 -0600 Subject: [PATCH 3668/4321] framework-pkcs15.c - Support CKA_PUBKEY_KEY_INFO PKCS11 V2.4 and V3.0 added CKA_PUBKEY_KEY_INFO as SPKI from pubkey On branch X25519-improvements-2 Changes to be committed: modified: framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9160d8fa70..3df7992761 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4933,6 +4933,7 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ case CKA_MODULUS_BITS: case CKA_VALUE: case CKA_SPKI: + case CKA_PUBLIC_KEY_INFO: case CKA_PUBLIC_EXPONENT: case CKA_EC_PARAMS: case CKA_EC_POINT: @@ -5059,8 +5060,11 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ */ case CKA_VALUE: case CKA_SPKI: + case CKA_PUBLIC_KEY_INFO: + - if (attr->type != CKA_SPKI && pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { + if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO + && pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { check_attribute_buffer(attr, pubkey->pub_info->direct.raw.len); memcpy(attr->pValue, pubkey->pub_info->direct.raw.value, pubkey->pub_info->direct.raw.len); } @@ -5072,7 +5076,7 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ unsigned char *value = NULL; size_t len; - if (attr->type != CKA_SPKI) { + if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO) { if (sc_pkcs15_encode_pubkey(context, pubkey->pub_data, &value, &len)) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); } else { @@ -5095,7 +5099,8 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ free(value); } - else if (attr->type != CKA_SPKI && pubkey->base.p15_object && pubkey->base.p15_object->content.value && pubkey->base.p15_object->content.len) { + else if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO + && pubkey->base.p15_object && pubkey->base.p15_object->content.value && pubkey->base.p15_object->content.len) { check_attribute_buffer(attr, pubkey->base.p15_object->content.len); memcpy(attr->pValue, pubkey->base.p15_object->content.value, pubkey->base.p15_object->content.len); } From e970d538a3a38491a79c9aa1a980c629fba80265 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 9 Feb 2024 15:32:20 -0600 Subject: [PATCH 3669/4321] WIP to accept pkcs11 ec_point encoded in bit string or byte string See opensc issue #3000 On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c modified: libopensc/pkcs15-pubkey.c modified: tools/pkcs11-tool.c modified: tools/pkcs15-init.c --- src/libopensc/card-openpgp.c | 2 +- src/libopensc/pkcs15-pubkey.c | 67 +++++++++++++++++++++++++++-------- src/tools/pkcs11-tool.c | 10 ++++-- src/tools/pkcs15-init.c | 8 +++-- 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3ae557e391..b61c460679 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2892,7 +2892,7 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in memset(&p15pubkey, 0, sizeof(p15pubkey)); p15pubkey.algorithm = SC_ALGORITHM_EC; p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpoint; - p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpoint_len; + p15pubkey.u.ec.ecpointQ.len = BYTES4BITS(key_info->u.ec.ecpoint_len); } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 66c894585f..30e5f01ab3 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -536,9 +536,13 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_P { NULL, 0, 0, 0, NULL, NULL } }; -#define C_ASN1_EC_POINTQ_SIZE 2 + +/* older incorrect implementation may have encoded as OCTET STRING */ +/* accept either */ +#define C_ASN1_EC_POINTQ_SIZE 3 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { - { "ecpointQ", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-OS",SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; @@ -629,7 +633,8 @@ sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *ctx, } /* - * We are storing the ec_pointQ as u8 string. not as DER + * We are storing the ec_pointQ as u8 string not as DER + * Will accept either BIT STRING or OCTET STRING */ int sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, @@ -644,13 +649,15 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); - r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); - if (r < 0) { + sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 1); + r = sc_asn1_decode_choice(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); + if (r < 0 || ecpoint_len == 0) { free(ecpoint_data); + /* TODO DEE fix if r == 0 */ LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); } - if (ecpoint_len == 0 || *ecpoint_data != 0x04) { + if (*ecpoint_data != 0x04) { free(ecpoint_data); LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); } @@ -658,11 +665,6 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; - /* - * Only get here if raw point is stored in pkcs15 without curve name - * spki has the curvename, so we can get the field_length - * Following only true for curves that are multiple of 8 - */ key->params.field_length = (ecpoint_len - 1)/2 * 8; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -673,10 +675,19 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; + size_t key_len; + volatile int gdb_test = 0; /* so can reset via gdb for testing old way OS*/ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key->ecpointQ.len, 1); + + if (gdb_test == 0) { + key_len = key->ecpointQ.len * 8; /* encode in bit string */ + sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); + } else { + key_len = key->ecpointQ.len; + sc_format_asn1_entry(asn1_ec_pointQ + 1, key->ecpointQ.value, &key_len, 1); + } LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen)); @@ -685,13 +696,34 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, /* * all "ec" keys uses same pubkey format, keep this external entrypoint * keys are just byte strings. + * will accept in either BIT STRING or OCTET STRING */ int sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, const u8 *buf, size_t buflen) { - return sc_pkcs15_decode_pubkey_ec(ctx, key, buf, buflen); + int r; + u8 * ecpoint_data = NULL; + size_t ecpoint_len; + struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; + + LOG_FUNC_CALLED(ctx); + sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); + sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); + sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 1); + r = sc_asn1_decode_choice(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); + if (r < 0 || ecpoint_data == NULL) { + free(ecpoint_data); + /* TODO DEE fix if r == 0 */ + LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); + } + + key->ecpointQ.len = ecpoint_len; + key->ecpointQ.value = ecpoint_data; + key->params.field_length = ecpoint_len * 8; + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } /* @@ -701,6 +733,7 @@ int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { + /* same format */ return sc_pkcs15_encode_pubkey_ec(ctx, key, buf, buflen); } @@ -712,8 +745,10 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_encode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); - if (key->algorithm == SC_ALGORITHM_EC || key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) + if (key->algorithm == SC_ALGORITHM_EC) return sc_pkcs15_encode_pubkey_ec(ctx, &key->u.ec, buf, len); + if (key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) + return sc_pkcs15_encode_pubkey_eddsa(ctx, &key->u.ec, buf, len); sc_log(ctx, "Encoding of public key type %lu not supported", key->algorithm); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); @@ -829,8 +864,10 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_GOSTR3410) return sc_pkcs15_decode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len); - if (key->algorithm == SC_ALGORITHM_EC || key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) + if (key->algorithm == SC_ALGORITHM_EC) return sc_pkcs15_decode_pubkey_ec(ctx, &key->u.ec, buf, len); + if (key->algorithm == SC_ALGORITHM_EDDSA || key->algorithm == SC_ALGORITHM_XEDDSA) + return sc_pkcs15_decode_pubkey_eddsa(ctx, &key->u.ec, buf, len); sc_log(ctx, "Decoding of public key type %lu not supported", key->algorithm); return SC_ERROR_NOT_SUPPORTED; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 175ab9d0df..65ec12a96a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2618,6 +2618,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char rs_buffer[512]; bytes = getEC_POINT(session, key, &len); free(bytes); + /* TODO DEE EDDSA and EC_POINT returned in BIT STRING needs some work */ /* * (We only support uncompressed for now) * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" @@ -5693,9 +5694,11 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if (ksize > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { if (bytes[1] <= 127 && ksize == (unsigned long)(bytes[1] + 2)) { body_len = ksize - 2; - } else if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { + } else + if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { body_len = ksize - 3; - } else if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { + } else + if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { body_len = ksize - 4; } } @@ -6385,6 +6388,7 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ + /* TODO DEE Should be returned encoded in BIT STRING, Need to accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -6491,6 +6495,7 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ + /* TODO DEE should be in BIT STRING accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { @@ -8644,6 +8649,7 @@ static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session) return; } getEC_POINT(session, pub_key, &ec_point_len); + /* TODO only looking at length of encoded EC_POINT. May be in BIT STRING or OCTET STRING */ if (ec_point_len < 5 || ec_point_len > 10000) { printf("ERR: GetAttribute(pubkey, CKA_EC_POINT) doesn't seem to work\n"); return; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 8640900d54..214fcb0267 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -769,7 +769,7 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key spec++; /* if we have everything for EDDSA or XEDDSA */ - if (*spec == 0x00 && *keybits && (algorithm == SC_ALGORITHM_EDDSA || SC_ALGORITHM_XEDDSA) && prkey) { + if (*spec == 0x00 && *keybits && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* correct case */ *keybits = types[types_idx].keybits; return algorithm; @@ -777,7 +777,11 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key if (*spec) { if (isalpha((unsigned char)*spec) - && (algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || SC_ALGORITHM_XEDDSA) + && algorithm == SC_ALGORITHM_EC && prkey) + prkey->u.ec.params.named_curve = strdup(spec); + else + if (isalpha((unsigned char)*spec) + && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* copy correct case */ } else { From 87878f08141e76996a017acb010a1b0039daabe3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 16 Feb 2024 11:22:18 -0600 Subject: [PATCH 3670/4321] pkcs15-pubkey.c make default for CKA_EC_POINT to return old OCTET STRING p11test is still using old way. On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 30e5f01ab3..114a0e3b31 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -676,12 +676,12 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; size_t key_len; - volatile int gdb_test = 0; /* so can reset via gdb for testing old way OS*/ + volatile int gdb_test = 0; /* so can reset via gdb for testing new way */ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - if (gdb_test == 0) { + if (gdb_test == 1) { key_len = key->ecpointQ.len * 8; /* encode in bit string */ sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); } else { From 6a1b902ddea6044cb6972bbb6cd17a1dde315b9d Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 16 Feb 2024 12:52:35 -0600 Subject: [PATCH 3671/4321] test-oseid.sh use restart-pcscd.sh Added github/restart-pcscd.sh On branch X25519-improvements-2 Changes to be committed: modified: test-oseid.sh --- .github/test-oseid.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index c5a5eba27f..277303bfd1 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -28,7 +28,9 @@ sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf cat /etc/reader.conf.d/reader.conf popd -sudo /etc/init.d/pcscd restart +# prepare pcscd +. .github/restart-pcscd.sh + # Needed for tput to not report warnings export TERM=xterm-256color @@ -65,7 +67,5 @@ $VALGRIND ./p11test -s 0 -p 11111111 -o oseid.json diff -u3 oseid_ref.json oseid.json popd -# cleanup -- this would break later uses of pcscd -kill -9 $PID rm oseid/src/card_mem sudo rm /etc/reader.conf.d/reader.conf From 567947c3a6d0161b5d77e7fae0a3ff9b32df9da0 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 28 Mar 2024 09:16:00 -0500 Subject: [PATCH 3672/4321] Revert "test-oseid.sh use restart-pcscd.sh" This is unrelated to to the PR so if needed submit as seperate PR This reverts commit 00c4a73af5522f5c09bec1cd5cded788d0bf39ba. On branch X25519-improvements-2 Changes to be committed: modified: .github/test-oseid.sh --- .github/test-oseid.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index 277303bfd1..c5a5eba27f 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -28,9 +28,7 @@ sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf cat /etc/reader.conf.d/reader.conf popd -# prepare pcscd -. .github/restart-pcscd.sh - +sudo /etc/init.d/pcscd restart # Needed for tput to not report warnings export TERM=xterm-256color @@ -67,5 +65,7 @@ $VALGRIND ./p11test -s 0 -p 11111111 -o oseid.json diff -u3 oseid_ref.json oseid.json popd +# cleanup -- this would break later uses of pcscd +kill -9 $PID rm oseid/src/card_mem sudo rm /etc/reader.conf.d/reader.conf From 73f72af45abc8ee3613876d328d71c8756a25a84 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 28 Mar 2024 11:41:20 -0500 Subject: [PATCH 3673/4321] pkcs15-pubkey.c fix bug found by fuzzer On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 141 ++++++++++++++++------------------ 1 file changed, 67 insertions(+), 74 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 114a0e3b31..42e29a1973 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -517,6 +517,7 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje return r; } +// clang-format off #define C_ASN1_PUBLIC_KEY_SIZE 2 static struct sc_asn1_entry c_asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE] = { { "publicKeyCoefficients", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, @@ -536,15 +537,15 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_P { NULL, 0, 0, 0, NULL, NULL } }; - /* older incorrect implementation may have encoded as OCTET STRING */ /* accept either */ #define C_ASN1_EC_POINTQ_SIZE 3 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { - { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, - { "ecpointQ-OS",SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; +// clang-format on int sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, @@ -643,7 +644,7 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, { int r; u8 * ecpoint_data = NULL; - size_t ecpoint_len; + size_t ecpoint_len = 0; struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; LOG_FUNC_CALLED(ctx); @@ -651,10 +652,9 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode_choice(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); - if (r < 0 || ecpoint_len == 0) { + if (r < 0 || ecpoint_len == 0 || ecpoint_data == NULL) { free(ecpoint_data); - /* TODO DEE fix if r == 0 */ - LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } if (*ecpoint_data != 0x04) { @@ -675,17 +675,17 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; - size_t key_len; + size_t key_len; volatile int gdb_test = 0; /* so can reset via gdb for testing new way */ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); if (gdb_test == 1) { - key_len = key->ecpointQ.len * 8; /* encode in bit string */ + key_len = key->ecpointQ.len * 8; /* encode in bit string */ sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); } else { - key_len = key->ecpointQ.len; + key_len = key->ecpointQ.len; sc_format_asn1_entry(asn1_ec_pointQ + 1, key->ecpointQ.value, &key_len, 1); } @@ -704,8 +704,8 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, const u8 *buf, size_t buflen) { int r; - u8 * ecpoint_data = NULL; - size_t ecpoint_len; + u8 *ecpoint_data = NULL; + size_t ecpoint_len = 0; struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; LOG_FUNC_CALLED(ctx); @@ -713,16 +713,15 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode_choice(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); - if (r < 0 || ecpoint_data == NULL) { + if (r < 0 || ecpoint_len == 0 || ecpoint_data == NULL) { free(ecpoint_data); - /* TODO DEE fix if r == 0 */ - LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; key->params.field_length = ecpoint_len * 8; - + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -1156,24 +1155,18 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) } switch (key->algorithm) { case SC_ALGORITHM_RSA: - if (key->u.rsa.modulus.data) - free(key->u.rsa.modulus.data); - if (key->u.rsa.exponent.data) - free(key->u.rsa.exponent.data); + free(key->u.rsa.modulus.data); + free(key->u.rsa.exponent.data); break; case SC_ALGORITHM_GOSTR3410: - if (key->u.gostr3410.xy.data) - free(key->u.gostr3410.xy.data); + free(key->u.gostr3410.xy.data); break; case SC_ALGORITHM_EC: case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: - if (key->u.ec.params.der.value) - free(key->u.ec.params.der.value); - if (key->u.ec.params.named_curve) - free(key->u.ec.params.named_curve); - if (key->u.ec.ecpointQ.value) - free(key->u.ec.ecpointQ.value); + free(key->u.ec.params.der.value); + free(key->u.ec.params.named_curve); + free(key->u.ec.ecpointQ.value); break; } sc_mem_clear(key, sizeof(*key)); @@ -1448,12 +1441,13 @@ sc_pkcs15_pubkey_from_spki_file(struct sc_context *ctx, char * filename, LOG_FUNC_RETURN(ctx, r); } - +// clang-format off static struct ec_curve_info { const char *name; const char *oid_str; const char *oid_encoded; size_t size; + } ec_curve_infos[] = { {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, @@ -1476,10 +1470,10 @@ static struct ec_curve_info { {"secp521r1", "1.3.132.0.35", "06052B81040023", 521}, {"nistp521", "1.3.132.0.35", "06052B81040023", 521}, - {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192}, - {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224}, - {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256}, - {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320}, + {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192}, + {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224}, + {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256}, + {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320}, {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384}, {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512}, @@ -1488,8 +1482,8 @@ static struct ec_curve_info { /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060a2B060104019755010501", 255}, + {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255}, /* RFC 8410 defined curves */ {"X25519", "1.3.101.110", "06032b656e", 255}, @@ -1500,10 +1494,9 @@ static struct ec_curve_info { {"cv25519", "1.3.101.110", "06032b656e", 255}, {"ed25519", "1.3.101.112", "06032b6570", 255}, - {NULL, NULL, NULL, 0}, /* Do not touch this */ }; - +// clang-format on int sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams) @@ -1515,43 +1508,43 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp /* In PKCS#11 EC parameters arrives in DER encoded form */ if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { + /* caller provided a der version of OID */ switch (ecparams->der.value[0]) { - case 0x06: /* OID */ - for (ii=0; ec_curve_infos[ii].name; ii++) { - struct sc_object_id id; - unsigned char *buf = NULL; - size_t len = 0; - - sc_format_oid(&id, ec_curve_infos[ii].oid_str); - sc_encode_oid (ctx, &id, &buf, &len); - - if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) { - free(buf); - break; - } - free(buf); - } - break; + case 0x06: /* OID */ + for (ii = 0; ec_curve_infos[ii].name; ii++) { + struct sc_object_id id; + unsigned char *buf = NULL; + size_t len = 0; - case 0x13: /* printable string max of 127 */ - if (ecparams->der.value[1] != ecparams->der.len - 2) { - sc_log(ctx, "Unsupported ec params"); - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); - } - for (ii=0; ec_curve_infos[ii].name; ii++) { - size_t len = strlen(ec_curve_infos[ii].name); - if (ecparams->der.len - 2 != len - || memcmp(ec_curve_infos[ii].name, ecparams->der.value + 2, len) != 0) - continue; - /* force replacement of printable string to allow mapping */ - mapped = 1; - break; + sc_format_oid(&id, ec_curve_infos[ii].oid_str); + sc_encode_oid(ctx, &id, &buf, &len); + + if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) { + free(buf); + break; /* found ec_curve_infos[ii] */ } - break; + free(buf); /* ii points at {NULL, NULL, NULL, 0} entry */ + } + break; - default: + case 0x13: /* printable string max of 127 as per PKCS11 V 3.0 for experimental curves */ + if (ecparams->der.value[1] != ecparams->der.len - 2) { sc_log(ctx, "Unsupported ec params"); LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + } + for (ii = 0; ec_curve_infos[ii].name; ii++) { + size_t len = strlen(ec_curve_infos[ii].name); + if (ecparams->der.len - 2 != len || memcmp(ec_curve_infos[ii].name, ecparams->der.value + 2, len) != 0) + continue; + /* force replacement of printable string to allow mapping */ + mapped = 1; + break; + } + break; + + default: + sc_log(ctx, "Unsupported ec params"); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } if (!ec_curve_infos[ii].name) @@ -1562,7 +1555,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp free(ecparams->named_curve); ecparams->named_curve = NULL; } - + if (!ecparams->named_curve) { ecparams->named_curve = strdup(ec_curve_infos[ii].name); if (!ecparams->named_curve) @@ -1589,9 +1582,9 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } } - } - else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */ - for (ii=0; ec_curve_infos[ii].name; ii++) { + } else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */ + /* caller did not provide an OID, look for a name or oid_string */ + for (ii = 0; ec_curve_infos[ii].name; ii++) { if (!strcmp(ec_curve_infos[ii].name, ecparams->named_curve)) break; if (!strcmp(ec_curve_infos[ii].oid_str, ecparams->named_curve)) @@ -1608,11 +1601,11 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp ecparams->field_length = ec_curve_infos[ii].size; if (!ecparams->der.value || !ecparams->der.len) { + /* if caller did not provide der OID, fill in */ rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len); LOG_TEST_RET(ctx, rv, "Cannot encode object ID"); } - } - else + } else LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "EC parameters has to be presented as a named curve or explicit data"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); From a3c609668af8933acc2b2f4dfa802c58b2f900d5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Mar 2024 08:01:20 -0500 Subject: [PATCH 3674/4321] card-openpgp.c - whitespace and code style Code style from yshui/git-clang-format-lint On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 66 +++++++++++++++++------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b61c460679..71ab1fdecc 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -86,26 +86,25 @@ static struct sc_card_driver pgp_drv = { NULL, 0, NULL }; - -static pgp_ec_curves_t ec_curves_openpgp34[] = { +static pgp_ec_curves_t ec_curves_openpgp34[] = { /* OpenPGP 3.4+ Ed25519 and Curve25519 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ - {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256}, /* brainpoolP256r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384}, /* brainpoolP384r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512}, /* brainpoolP512r1 */ - {{{-1}}, 0} /* This entry must not be touched. */ + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ + {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256}, /* brainpoolP256r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384}, /* brainpoolP384r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512}, /* brainpoolP512r1 */ + {{{-1}}, 0 } /* This entry must not be touched. */ }; #ifdef ENABLE_OPENSSL static pgp_ec_curves_alt_t ec_curves_alt[] = { - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, {{1 ,3 ,101, 110, -1}}, 255}, /* curve25519 CKK_EC_MONTGOMERY X25519 */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ - {{{-1}}, {{-1}}, 0} /* This entry must not be touched. */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, {{1, 3, 101, 110, -1}}, 255}, /* curve25519 CKK_EC_MONTGOMERY X25519 */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ + {{{-1}}, {{-1}}, 0 } /* This entry must not be touched. */ }; #endif /* ENABLE_OPENSSL */ @@ -114,15 +113,14 @@ static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; /* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */ -static pgp_ec_curves_t ec_curves_gnuk[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 10, -1}}, 256}, /* secp256k1 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ - {{{-1}}, 0} /* This entry must not be touched. */ +static pgp_ec_curves_t ec_curves_gnuk[] = { + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 10, -1}}, 256}, /* secp256k1 */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{-1}}, 0 } /* This entry must not be touched. */ }; - /* * The OpenPGP card doesn't have a file system, instead everything * is stored in data objects that are accessed through GET/PUT. @@ -695,7 +693,7 @@ int _pgp_handle_curve25519(sc_card_t *card, * OpenPGP card supports only derivation using these * keys as far as I know */ _sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); + SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); sc_log(card->ctx, "DO %uX: Added XEDDSA algorithm (%d), mod_len = %zu", do_num, SC_ALGORITHM_XEDDSA, key_info.u.ec.key_length); return 1; @@ -747,7 +745,7 @@ int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, un if (_pgp_handle_curve25519(card, key_info, do_num)) break; _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_EDDSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); + SC_ALGORITHM_EDDSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); sc_log(card->ctx, "DO %uX: Added EDDSA algorithm (%d), mod_len = %zu" , do_num, key_info.algorithm, key_info.u.ec.key_length); @@ -1770,9 +1768,9 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) p15pubkey.u.rsa.modulus.len = 0; p15pubkey.u.rsa.exponent.data = NULL; p15pubkey.u.rsa.exponent.len = 0; - } else if (p15pubkey.algorithm == SC_ALGORITHM_EC - || p15pubkey.algorithm == SC_ALGORITHM_EDDSA - || p15pubkey.algorithm == SC_ALGORITHM_XEDDSA) { + } else if (p15pubkey.algorithm == SC_ALGORITHM_EC || + p15pubkey.algorithm == SC_ALGORITHM_EDDSA || + p15pubkey.algorithm == SC_ALGORITHM_XEDDSA) { p15pubkey.u.ec.ecpointQ.value = NULL; p15pubkey.u.ec.ecpointQ.len = 0; /* p15pubkey.u.ec.params.der and named_curve will be freed by sc_pkcs15_erase_pubkey */ @@ -2532,10 +2530,10 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ struct sc_object_id *scoid = NULL; scoid = &key_info->u.ec.oid; - /* + /* * Current OpenPGP cards use pre RFC8410 OIDs for ECDH and EdDSA - * so convert to older versions of the OIDs. - * TODO if newer cards or OpenPGP specs accept RFC8410 code + * so convert to older versions of the OIDs. + * TODO if newer cards or OpenPGP specs accept RFC8410 code * will be needed here to not do the conversion */ for (i = 0; ec_curves_alt[i].size > 0; i++) { @@ -2544,7 +2542,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ break; } } - + r = sc_encode_oid(card->ctx, scoid, &aoid, &aoid_len); LOG_TEST_RET(card->ctx, r, "invalid ec oid"); if (aoid == NULL || aoid_len < 3 || aoid[1] > 127) { @@ -2561,7 +2559,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ data[0] = key_info->algorithm; for (i = 0; i < aoid_len - 2; i++) - data[i+1] = aoid[i+2]; + data[i + 1] = aoid[i + 2]; } /* RSA */ @@ -3074,9 +3072,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) LOG_FUNC_CALLED(card->ctx); /* protect incompatible cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && card->type != SC_CARD_TYPE_OPENPGP_GNUK - && priv->bcd_version < OPENPGP_CARD_3_0) + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA && + card->type != SC_CARD_TYPE_OPENPGP_GNUK && + priv->bcd_version < OPENPGP_CARD_3_0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* set Control Reference Template for key */ From 0118c9de82e19a18b7e19c4fe6dbf555f25082d7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Mar 2024 08:04:27 -0500 Subject: [PATCH 3675/4321] framework-pkcs15,c - whitespace and code style Code style from yshui/git-clang-format-lint On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 43 ++++++++++++----------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3df7992761..fecd734d1e 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3384,8 +3384,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, if (rv != CKR_OK) keybits = 1024; /* Default key size */ /* TODO: check allowed values of keybits */ - } - else if (keytype == CKK_EC || keytype == CKK_EC_EDWARDS || keytype == CKK_EC_MONTGOMERY) { + } else if (keytype == CKK_EC || keytype == CKK_EC_EDWARDS || keytype == CKK_EC_MONTGOMERY) { struct sc_lv_data *der = &keygen_args.prkey_args.key.u.ec.params.der; void *ptr = NULL; @@ -3396,25 +3395,21 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, sc_unlock(p11card->card); return rv; } - } if (keytype == CKK_EC) { keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EC; pub_args.key.algorithm = SC_ALGORITHM_EC; - } - else if (keytype == CKK_EC_EDWARDS) { + } else if (keytype == CKK_EC_EDWARDS) { keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EDDSA; keygen_args.prkey_args.usage |= SC_PKCS15_PRKEY_USAGE_SIGN; - pub_args.key.algorithm = SC_ALGORITHM_EDDSA; - } - else if (keytype == CKK_EC_MONTGOMERY) { + pub_args.key.algorithm = SC_ALGORITHM_EDDSA; + } else if (keytype == CKK_EC_MONTGOMERY) { keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_XEDDSA; /* Can not sign. To created a cert, see: openssl x509 -force_pubkey */ keygen_args.prkey_args.usage |= SC_PKCS15_PRKEY_USAGE_DERIVE; - pub_args.key.algorithm = SC_ALGORITHM_XEDDSA; - } - else { + pub_args.key.algorithm = SC_ALGORITHM_XEDDSA; + } else { /* CKA_KEY_TYPE is set, but keytype isn't correct */ rv = CKR_ATTRIBUTE_VALUE_INVALID; goto kpgen_done; @@ -5061,28 +5056,24 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ case CKA_VALUE: case CKA_SPKI: case CKA_PUBLIC_KEY_INFO: - - if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO - && pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { + if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO && pubkey->pub_info && pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) { check_attribute_buffer(attr, pubkey->pub_info->direct.raw.len); memcpy(attr->pValue, pubkey->pub_info->direct.raw.value, pubkey->pub_info->direct.raw.len); - } - else if (pubkey->pub_info && pubkey->pub_info->direct.spki.value && pubkey->pub_info->direct.spki.len) { + } else if (pubkey->pub_info && pubkey->pub_info->direct.spki.value && pubkey->pub_info->direct.spki.len) { check_attribute_buffer(attr, pubkey->pub_info->direct.spki.len); memcpy(attr->pValue, pubkey->pub_info->direct.spki.value, pubkey->pub_info->direct.spki.len); - } - else if (pubkey->pub_data) { + } else if (pubkey->pub_data) { unsigned char *value = NULL; size_t len; if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO) { if (sc_pkcs15_encode_pubkey(context, pubkey->pub_data, &value, &len)) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); - } else { - if (sc_pkcs15_encode_pubkey_as_spki(context, pubkey->pub_data, &value, &len)) + } else { + if (sc_pkcs15_encode_pubkey_as_spki(context, pubkey->pub_data, &value, &len)) return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetAttributeValue"); - } + } if (attr->pValue == NULL_PTR) { attr->ulValueLen = len; @@ -5098,17 +5089,13 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ memcpy(attr->pValue, value, len); free(value); - } - else if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO - && pubkey->base.p15_object && pubkey->base.p15_object->content.value && pubkey->base.p15_object->content.len) { + } else if (attr->type != CKA_SPKI && attr->type != CKA_PUBLIC_KEY_INFO && pubkey->base.p15_object && pubkey->base.p15_object->content.value && pubkey->base.p15_object->content.len) { check_attribute_buffer(attr, pubkey->base.p15_object->content.len); memcpy(attr->pValue, pubkey->base.p15_object->content.value, pubkey->base.p15_object->content.len); - } - else if (cert && cert->cert_data) { + } else if (cert && cert->cert_data) { check_attribute_buffer(attr, cert->cert_data->data.len); memcpy(attr->pValue, cert->cert_data->data.value, cert->cert_data->data.len); - } - else { + } else { return CKR_ATTRIBUTE_TYPE_INVALID; } break; From 693b89d72a4749eab44eaccdaede8f584a078455 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Mar 2024 08:15:37 -0500 Subject: [PATCH 3676/4321] pkcs15-alg.c whitespace and code style Code style from yshui/git-clang-format-lint On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/pkcs15-algo.c --- src/libopensc/pkcs15-algo.c | 83 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 0110b0ccc0..a1f7cd1086 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -347,121 +347,120 @@ asn1_free_ec_params(void *params) } } - static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #ifdef SC_ALGORITHM_SHA1 /* hmacWithSHA1 */ - { SC_ALGORITHM_SHA1, {{ 1, 2, 840, 113549, 2, 7, -1}}, NULL, NULL, NULL }, - { SC_ALGORITHM_SHA1, {{ 1, 3, 6, 1, 5, 5, 8, 1, 2, -1}}, NULL, NULL, NULL }, - /* SHA1 */ - { SC_ALGORITHM_SHA1, {{ 1, 3, 14, 3, 2, 26, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_SHA1, {{1, 2, 840, 113549, 2, 7, -1}}, NULL, NULL, NULL}, + {SC_ALGORITHM_SHA1, {{1, 3, 6, 1, 5, 5, 8, 1, 2, -1}}, NULL, NULL, NULL}, + /* SHA1 */ + {SC_ALGORITHM_SHA1, {{1, 3, 14, 3, 2, 26, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_MD5 - { SC_ALGORITHM_MD5, {{ 1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_MD5, {{1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_RSA /* really rsaEncryption */ - { SC_ALGORITHM_RSA, {{ 1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_RSA, {{1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_DH - { SC_ALGORITHM_DH, {{ 1, 2, 840, 10046, 2, 1, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_DH, {{1, 2, 840, 10046, 2, 1, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_RC2_WRAP /* from CMS */ - { SC_ALGORITHM_RC2_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 7, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_RC2_WRAP, {{1, 2, 840, 113549, 1, 9, 16, 3, 7, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_RC2 /* CBC mode */ - { SC_ALGORITHM_RC2, {{ 1, 2, 840, 113549, 3, 2, -1}}, + {SC_ALGORITHM_RC2, {{1, 2, 840, 113549, 3, 2, -1}}, asn1_decode_rc2_params, - asn1_encode_rc2_params }, + asn1_encode_rc2_params}, #endif #ifdef SC_ALGORITHM_DES /* CBC mode */ - { SC_ALGORITHM_DES, {{ 1, 3, 14, 3, 2, 7, -1}}, + {SC_ALGORITHM_DES, {{1, 3, 14, 3, 2, 7, -1}}, asn1_decode_des_params, asn1_encode_des_params, - free }, + free}, #endif #ifdef SC_ALGORITHM_3DES_WRAP /* from CMS */ - { SC_ALGORITHM_3DES_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 6, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_3DES_WRAP, {{1, 2, 840, 113549, 1, 9, 16, 3, 6, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_3DES /* EDE CBC mode */ - { SC_ALGORITHM_3DES, {{ 1, 2, 840, 113549, 3, 7, -1}}, + {SC_ALGORITHM_3DES, {{1, 2, 840, 113549, 3, 7, -1}}, asn1_decode_des_params, asn1_encode_des_params, - free }, + free}, #endif #ifdef SC_ALGORITHM_GOST /* EDE CBC mode */ - { SC_ALGORITHM_GOST, {{ 1, 2, 4434, 66565, 3, 7, -1}}, NULL, NULL, NULL }, + {SC_ALGORITHM_GOST, {{1, 2, 4434, 66565, 3, 7, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_GOSTR3410 - { SC_ALGORITHM_GOSTR3410, {{ 1, 2, 643, 2, 2, 19, -1}}, + {SC_ALGORITHM_GOSTR3410, {{1, 2, 643, 2, 2, 19, -1}}, asn1_decode_gostr3410_params, asn1_encode_gostr3410_params, - NULL }, + NULL}, #endif /* We do not support PBES1 because the encryption is weak */ #ifdef SC_ALGORITHM_PBKDF2 - { SC_ALGORITHM_PBKDF2, {{ 1, 2, 840, 113549, 1, 5, 12, -1}}, + {SC_ALGORITHM_PBKDF2, {{1, 2, 840, 113549, 1, 5, 12, -1}}, asn1_decode_pbkdf2_params, asn1_encode_pbkdf2_params, - free }, + free}, #endif #ifdef SC_ALGORITHM_PBES2 - { SC_ALGORITHM_PBES2, {{ 1, 2, 840, 113549, 1, 5, 13, -1}}, + {SC_ALGORITHM_PBES2, {{1, 2, 840, 113549, 1, 5, 13, -1}}, asn1_decode_pbes2_params, asn1_encode_pbes2_params, - asn1_free_pbes2_params }, + asn1_free_pbes2_params}, #endif #ifdef SC_ALGORITHM_EC - { SC_ALGORITHM_EC, {{ 1, 2, 840, 10045, 2, 1, -1}}, + {SC_ALGORITHM_EC, {{1, 2, 840, 10045, 2, 1, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, - asn1_free_ec_params }, + asn1_free_ec_params}, #endif /* TODO: -DEE Not clear if we need the next five or not */ #ifdef SC_ALGORITHM_ECDSA_SHA1 /* Note RFC 3279 says no ecParameters */ - { SC_ALGORITHM_ECDSA_SHA1, {{ 1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL}, + {SC_ALGORITHM_ECDSA_SHA1, {{1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA224 -/* These next 4 are defined in RFC 5758 */ - { SC_ALGORITHM_ECDSA_SHA224, {{ 1, 2, 840, 10045, 4, 3, 1, -1}}, + /* These next 4 are defined in RFC 5758 */ + {SC_ALGORITHM_ECDSA_SHA224, {{1, 2, 840, 10045, 4, 3, 1, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, - asn1_free_ec_params }, + asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA256 - { SC_ALGORITHM_ECDSA_SHA256, {{ 1, 2, 840, 10045, 4, 3, 2, -1}}, + {SC_ALGORITHM_ECDSA_SHA256, {{1, 2, 840, 10045, 4, 3, 2, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, - asn1_free_ec_params }, + asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA384 - { SC_ALGORITHM_ECDSA_SHA384, {{ 1, 2, 840, 10045, 4, 3, 3, -1}}, + {SC_ALGORITHM_ECDSA_SHA384, {{1, 2, 840, 10045, 4, 3, 3, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, - asn1_free_ec_params }, + asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA512 - { SC_ALGORITHM_ECDSA_SHA512, {{ 1, 2, 840, 10045, 4, 3, 4, -1}}, + {SC_ALGORITHM_ECDSA_SHA512, {{1, 2, 840, 10045, 4, 3, 4, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, - asn1_free_ec_params }, + asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_EDDSA /* aka Ed25519 */ /* RFC 8410, needed to parse/create X509 certs/pubkeys */ /* TODO DEE add asn1_decode_ec_params, asn1_encode_ec_params,asn1_free_ec_params */ - { SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL}, /* Ed25119 */ - { SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL}, /* Ed25519 OID used by OpenPGP */ - { SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}}, NULL, NULL, NULL}, /* Ed448 */ + {SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL}, /* Ed25119 */ + {SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL}, /* Ed25519 OID used by OpenPGP */ + {SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}}, NULL, NULL, NULL}, /* Ed448 */ #endif #ifdef SC_ALGORITHM_XEDDSA /* aka curve25519 */ /* RFC 8410, needed to parse/create X509 certs/pubkeys no ec_parms*/ - { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL}, /* X25519 */ - { SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 -1}}, NULL, NULL, NULL}, /* X25519 OID used by OpenPGP */ - { SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}}, NULL, NULL, NULL}, /* X448 */ + {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL}, /* X25519 */ + {SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 - 1}}, NULL, NULL, NULL}, /* X25519 OID used by OpenPGP */ + {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}}, NULL, NULL, NULL}, /* X448 */ #endif - { -1, {{ -1 }}, NULL, NULL, NULL } + {-1, {{-1}}, NULL, NULL, NULL} }; From f69cd013a456037e14afce47be31ecafcb546e2a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Mar 2024 08:30:46 -0500 Subject: [PATCH 3677/4321] pkcs15-init.c whitespace and code style Code style from yshui/git-clang-format-lint On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 214fcb0267..9d924b2bb0 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -720,6 +720,7 @@ static const struct alg_spec alg_types_sym[] = { { NULL, -1, 0 } }; +// clang-format off /* RSA can have a number , default is 2048 */ /* EC require a curve name */ /* EDDSA and XEDDSA without a size require a size or curve name or OID */ @@ -744,6 +745,7 @@ static const struct alg_spec alg_types_asym[] = { { NULL, -1, 0 } }; +// clang-format on static int parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *keybits, struct sc_pkcs15_prkey *prkey) @@ -767,22 +769,18 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key if (*spec == '/' || *spec == '-' || *spec == ':') spec++; - + /* if we have everything for EDDSA or XEDDSA */ if (*spec == 0x00 && *keybits && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* correct case */ - *keybits = types[types_idx].keybits; + *keybits = types[types_idx].keybits; return algorithm; } if (*spec) { - if (isalpha((unsigned char)*spec) - && algorithm == SC_ALGORITHM_EC && prkey) + if (isalpha((unsigned char)*spec) && algorithm == SC_ALGORITHM_EC && prkey) prkey->u.ec.params.named_curve = strdup(spec); - else - if (isalpha((unsigned char)*spec) - && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) - && prkey) { + else if (isalpha((unsigned char)*spec) && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* copy correct case */ } else { *keybits = (unsigned)strtoul(spec, &end, 10); From 4f03e6e8bed33dc77eb2b1d85b775a33bcc2afc8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Mar 2024 08:49:10 -0500 Subject: [PATCH 3678/4321] files.html, tools.html - rebuild As suggeseted by .github/workflows/doc.yml On branch X25519-improvements-2 Changes to be committed: modified: files/files.html modified: tools/tools.html --- doc/tools/tools.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/tools/tools.html b/doc/tools/tools.html index ee62ac381d..e463ea57ae 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -2005,7 +2005,13 @@ where keyspec describes the algorithm and the parameters of the key to be created. For example, rsa:2048 generates a RSA key with 2048-bit modulus. If you are generating an EC key, the curve designation must - be specified, for example ec:prime256v1. For symmetric key, + be specified, for example ec:prime256v1. + The following curves do not need parameters: + Edwards 25519 curves use one of these equivalent names: Ed25519(preferred), ed25519 or edwards25519 + and for the 448 curve use: Ed448. + For Montgomery 25519 curves use one of these equivalent names: X25519(preferred), cv25519 or curve25519 + and for the 448 curve use: X448. + For symmetric key, the length of key is specified in bytes, for example AES:32 or DES3:24.

    From 5db2e2a1a133b4d6967c36c5b916c30e5cbcde70 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 17 Apr 2024 14:51:19 -0500 Subject: [PATCH 3679/4321] pkcs15-pubkey.c - readability of mapped_string On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-prkey.c | 3 ++- src/libopensc/pkcs15-pubkey.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index e9cffd9f05..78c80978db 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -569,7 +569,8 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key) case SC_ALGORITHM_GOSTR3410: free(key->u.gostr3410.d.data); break; - case SC_ALGORITHM_EC: /* EC, Edwards and Montgomery use common ec params */ + case SC_ALGORITHM_EC: + /* EC, Edwards and Montgomery use common ec params */ free(key->u.ec.params.der.value); free(key->u.ec.params.named_curve); free(key->u.ec.privateD.data); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 42e29a1973..fade457d07 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1502,7 +1502,7 @@ int sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams) { int rv, ii; - int mapped = 0; + int mapped_string = 0; /* der is printable string that can be replaced with der of OID */ LOG_FUNC_CALLED(ctx); @@ -1510,7 +1510,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { /* caller provided a der version of OID */ switch (ecparams->der.value[0]) { - case 0x06: /* OID */ + case 0x06: /* der.value is an OID */ for (ii = 0; ec_curve_infos[ii].name; ii++) { struct sc_object_id id; unsigned char *buf = NULL; @@ -1536,8 +1536,8 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp size_t len = strlen(ec_curve_infos[ii].name); if (ecparams->der.len - 2 != len || memcmp(ec_curve_infos[ii].name, ecparams->der.value + 2, len) != 0) continue; - /* force replacement of printable string to allow mapping */ - mapped = 1; + /* found replacement of printable string to OID */ + mapped_string = 1; break; } break; @@ -1551,7 +1551,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve"); sc_log(ctx, "Found known curve '%s'", ec_curve_infos[ii].name); - if (mapped) { + if (mapped_string) { /* free der of printable string replace below with OID */ free(ecparams->named_curve); ecparams->named_curve = NULL; } @@ -1564,14 +1564,14 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp sc_log(ctx, "Curve name: '%s'", ecparams->named_curve); } - if (!sc_valid_oid(&ecparams->id) || mapped) + if (!sc_valid_oid(&ecparams->id) || mapped_string) sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str); ecparams->field_length = ec_curve_infos[ii].size; sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u", ecparams->field_length); - if (mapped) { - /* replace the printable string version with the mapped oid */ + if (mapped_string) { + /* replace the printable string version with the oid */ free(ecparams->der.value); ecparams->der.len = strlen(ec_curve_infos[ii].oid_encoded) / 2; ecparams->der.value = malloc(ecparams->der.len); From ed27016b169751f4215305175d060060c789e3c9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 17 Apr 2024 20:11:37 -0500 Subject: [PATCH 3680/4321] card-openpgp.c - renove TODO comments as code was added On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 71ab1fdecc..fde8f8ac29 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2520,7 +2520,6 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) { /* ECDSA and ECDH */ - /* TODO -DEE could map new OIDs to old OID needed for card here */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA){ @@ -2533,8 +2532,6 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ /* * Current OpenPGP cards use pre RFC8410 OIDs for ECDH and EdDSA * so convert to older versions of the OIDs. - * TODO if newer cards or OpenPGP specs accept RFC8410 code - * will be needed here to not do the conversion */ for (i = 0; ec_curves_alt[i].size > 0; i++) { if (sc_compare_oid(scoid, &ec_curves_alt[i].oid_alt)) { From 7d5076689ac68b62eee75f7cb5a0fbb2a3cbfd58 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 17 Apr 2024 20:13:08 -0500 Subject: [PATCH 3681/4321] pkcs15-algo.c - removed comments and added asn1 calls On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-algo.c --- src/libopensc/pkcs15-algo.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index a1f7cd1086..6a130c87d4 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -415,7 +415,6 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { asn1_encode_ec_params, asn1_free_ec_params}, #endif -/* TODO: -DEE Not clear if we need the next five or not */ #ifdef SC_ALGORITHM_ECDSA_SHA1 /* Note RFC 3279 says no ecParameters */ {SC_ALGORITHM_ECDSA_SHA1, {{1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL}, @@ -448,17 +447,34 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #ifdef SC_ALGORITHM_EDDSA /* aka Ed25519 */ /* RFC 8410, needed to parse/create X509 certs/pubkeys */ - /* TODO DEE add asn1_decode_ec_params, asn1_encode_ec_params,asn1_free_ec_params */ - {SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL}, /* Ed25119 */ - {SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL}, /* Ed25519 OID used by OpenPGP */ - {SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}}, NULL, NULL, NULL}, /* Ed448 */ + {SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* Ed25119 */ + {SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* Ed25519 OID used by OpenPGP */ + {SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* Ed448 */ #endif #ifdef SC_ALGORITHM_XEDDSA /* aka curve25519 */ - /* RFC 8410, needed to parse/create X509 certs/pubkeys no ec_parms*/ - {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL}, /* X25519 */ - {SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 - 1}}, NULL, NULL, NULL}, /* X25519 OID used by OpenPGP */ - {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}}, NULL, NULL, NULL}, /* X448 */ + /* RFC 8410, needed to parse/create X509 certs/pubkeys ec_parms*/ + {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* X25519 */ + {SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 - 1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* X25519 OID used by OpenPGP */ + {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}}, + asn1_decode_ec_params, + asn1_encode_ec_params, + asn1_free_ec_params}, /* X448 */ #endif {-1, {{-1}}, NULL, NULL, NULL} }; From 002f8c91d12b4c750980487ec6f914743e7ffbe9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 19 Apr 2024 15:15:11 -0500 Subject: [PATCH 3682/4321] pkcs11-tool.c - formating On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 65ec12a96a..6e3f2c9219 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5220,7 +5220,8 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE CK_BBOOL _true = TRUE; CK_BBOOL _false = FALSE; CK_OBJECT_HANDLE newkey = 0; -//clang-format off + + // clang-format off CK_ATTRIBUTE newkey_template[20] = { {CKA_TOKEN, &_false, sizeof(_false) }, /* session only object */ {CKA_CLASS, &newkey_class, sizeof(newkey_class)}, @@ -5228,7 +5229,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE {CKA_SENSITIVE, &_false, sizeof(_false) }, {CKA_EXTRACTABLE, &_true, sizeof(_true) }, }; -//clang-format on + // clang-format on int n_attrs = 7; CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; @@ -5694,11 +5695,9 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if (ksize > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { if (bytes[1] <= 127 && ksize == (unsigned long)(bytes[1] + 2)) { body_len = ksize - 2; - } else - if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { + } else if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { body_len = ksize - 3; - } else - if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { + } else if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { body_len = ksize - 4; } } From 3efffe553e49dd1f1c3c2955376f4ab830b8f9a5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 21 Apr 2024 14:03:14 -0500 Subject: [PATCH 3683/4321] pkcs15-pubkey.c - Use sc_asn1_read_tag for printable string On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index fade457d07..7e4c28942b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1508,6 +1508,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp /* In PKCS#11 EC parameters arrives in DER encoded form */ if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { + /* caller provided a der version of OID */ switch (ecparams->der.value[0]) { case 0x06: /* der.value is an OID */ @@ -1527,18 +1528,28 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp } break; - case 0x13: /* printable string max of 127 as per PKCS11 V 3.0 for experimental curves */ - if (ecparams->der.value[1] != ecparams->der.len - 2) { - sc_log(ctx, "Unsupported ec params"); - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); - } - for (ii = 0; ec_curve_infos[ii].name; ii++) { - size_t len = strlen(ec_curve_infos[ii].name); - if (ecparams->der.len - 2 != len || memcmp(ec_curve_infos[ii].name, ecparams->der.value + 2, len) != 0) - continue; - /* found replacement of printable string to OID */ - mapped_string = 1; - break; + case 0x13: + /* printable string as per PKCS11 V 3.0 for experimental curves */ + { + int r_tag; + const u8 *body = ecparams->der.value; + size_t len = ecparams->der.len; + unsigned int cla_out, tag_out; + size_t bodylen; + + r_tag = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen); + if (r_tag != SC_SUCCESS || tag_out != 0x13) { + sc_log(ctx, "Invalid printable string"); + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); + } + for (ii = 0; ec_curve_infos[ii].name; ii++) { + size_t len = strlen(ec_curve_infos[ii].name); + if (bodylen != len || memcmp(ec_curve_infos[ii].name, body, len) != 0) + continue; + /* found replacement of printable string to OID */ + mapped_string = 1; + break; + } } break; From 54c9618d418e15b61cd6b8d59cf3df97594435d4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 22 Apr 2024 10:42:03 -0500 Subject: [PATCH 3684/4321] pkcs15-pubkey.c opensc.h - Add SC_ALGORITHM_* to ec_curve_info Make it easier to tell difference between EC, EDDSA and XEDDSA On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/opensc.h modified: src/libopensc/pkcs15-pubkey.c --- src/libopensc/opensc.h | 8 +++- src/libopensc/pkcs15-pubkey.c | 72 ++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5f1c99f6e4..7d9e170853 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -281,14 +281,19 @@ struct sc_pbes2_params { }; /* + * PKCS11 2.3 Elliptic Curve lists mechanisms that use CKA_ECPARMS + * which implies the type of key and size needed in the OID * The ecParameters can be presented as * - name of curve; * - OID of named curve; * - implicit parameters. * * type - type(choice) of 'EC domain parameters' as it present in CKA_EC_PARAMS (PKCS#11). - Recommended value '1' -- namedCurve. + * Recommended value '1' -- namedCurve. * field_length - EC key size in bits. + * key_type - 0 implies SC_ALGORITHM_EC, SC_ALGORITHM_EDDSA or SC_ALGORITHM_XEDDSA + * Not actually part of CKA_EC_PARAMS - used to differentiate key types that use ec_params + * will be set by, sc_pkcs15_fix_ec_parameters */ struct sc_ec_parameters { char *named_curve; @@ -297,6 +302,7 @@ struct sc_ec_parameters { int type; size_t field_length; + unsigned int key_type; }; typedef struct sc_algorithm_info { diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 7e4c28942b..cf49daa2f2 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1446,55 +1446,56 @@ static struct ec_curve_info { const char *name; const char *oid_str; const char *oid_encoded; + const unsigned int key_type; size_t size; } ec_curve_infos[] = { - {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, - {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, - {"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, - {"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192}, + {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, + {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, + {"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, + {"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, - {"secp224r1", "1.3.132.0.33", "06052b81040021", 224}, - {"nistp224", "1.3.132.0.33", "06052b81040021", 224}, + {"secp224r1", "1.3.132.0.33", "06052b81040021", 224, SC_ALGORITHM_EC}, + {"nistp224", "1.3.132.0.33", "06052b81040021", 224, SC_ALGORITHM_EC}, - {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256}, - {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256}, - {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256}, - {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256}, + {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, + {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, + {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, + {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, - {"secp384r1", "1.3.132.0.34", "06052B81040022", 384}, - {"prime384v1", "1.3.132.0.34", "06052B81040022", 384}, - {"nistp384", "1.3.132.0.34", "06052B81040022", 384}, - {"ansiX9p384r1", "1.3.132.0.34", "06052B81040022", 384}, + {"secp384r1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, + {"prime384v1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, + {"nistp384", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, + {"ansiX9p384r1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, - {"secp521r1", "1.3.132.0.35", "06052B81040023", 521}, - {"nistp521", "1.3.132.0.35", "06052B81040023", 521}, + {"secp521r1", "1.3.132.0.35", "06052B81040023", 521, SC_ALGORITHM_EC}, + {"nistp521", "1.3.132.0.35", "06052B81040023", 521, SC_ALGORITHM_EC}, - {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192}, - {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224}, - {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256}, - {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320}, - {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384}, - {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512}, + {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192, SC_ALGORITHM_EC}, + {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224, SC_ALGORITHM_EC}, + {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256, SC_ALGORITHM_EC}, + {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320, SC_ALGORITHM_EC}, + {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384, SC_ALGORITHM_EC}, + {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512, SC_ALGORITHM_EC}, - {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192}, - {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256}, + {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192, SC_ALGORITHM_EC}, + {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256, SC_ALGORITHM_EC}, /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255}, + {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255, SC_ALGORITHM_EDDSA}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255, SC_ALGORITHM_XEDDSA}, /* RFC 8410 defined curves */ - {"X25519", "1.3.101.110", "06032b656e", 255}, - {"X448", "1.3.101.111", "06032b656f", 448}, - {"Ed25519", "1.3.101.112", "06032b6570", 255}, - {"Ed448", "1.3.101.113", "06032b6571", 448}, + {"X25519", "1.3.101.110", "06032b656e", 255, SC_ALGORITHM_XEDDSA}, + {"X448", "1.3.101.111", "06032b656f", 448, SC_ALGORITHM_XEDDSA}, + {"Ed25519", "1.3.101.112", "06032b6570", 255, SC_ALGORITHM_EDDSA}, + {"Ed448", "1.3.101.113", "06032b6571", 448, SC_ALGORITHM_EDDSA}, /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", "06032b656e", 255}, - {"ed25519", "1.3.101.112", "06032b6570", 255}, + {"cv25519", "1.3.101.110", "06032b656e", 255, SC_ALGORITHM_XEDDSA}, + {"ed25519", "1.3.101.112", "06032b6570", 255, SC_ALGORITHM_EDDSA}, - {NULL, NULL, NULL, 0}, /* Do not touch this */ + {NULL, NULL, NULL, 0, 0}, /* Do not touch this */ }; // clang-format on @@ -1579,8 +1580,9 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str); ecparams->field_length = ec_curve_infos[ii].size; - sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u", - ecparams->field_length); + ecparams->key_type = ec_curve_infos[ii].key_type; + sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u key_type %d", + ecparams->field_length, ecparams->key_type); if (mapped_string) { /* replace the printable string version with the oid */ free(ecparams->der.value); From bfdf26a8f139090035d2478622552277f29d42e8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 22 Apr 2024 11:18:27 -0500 Subject: [PATCH 3685/4321] card-openpgp.c card-openpgp.h - Add SC_ALGORITHM_* to ec_curves_openpgp* On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c modified: src/libopensc/card-openpgp.h --- src/libopensc/card-openpgp.c | 32 ++++++++++++++++---------------- src/libopensc/card-openpgp.h | 1 + 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fde8f8ac29..9145f0304d 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -88,23 +88,23 @@ static struct sc_card_driver pgp_drv = { static pgp_ec_curves_t ec_curves_openpgp34[] = { /* OpenPGP 3.4+ Ed25519 and Curve25519 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */ - {{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256}, /* brainpoolP256r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384}, /* brainpoolP384r1 */ - {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512}, /* brainpoolP512r1 */ - {{{-1}}, 0 } /* This entry must not be touched. */ + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384, SC_ALGORITHM_EC}, /* ansiX9p384r1 */ + {{{1, 3, 132, 0, 35, -1}}, 521, SC_ALGORITHM_EC}, /* ansiX9p521r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* brainpoolP256r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384, SC_ALGORITHM_EC}, /* brainpoolP384r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512, SC_ALGORITHM_EC}, /* brainpoolP512r1 */ + {{{-1}}, 0, 0 } /* This entry must not be touched. */ }; #ifdef ENABLE_OPENSSL static pgp_ec_curves_alt_t ec_curves_alt[] = { {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, {{1, 3, 101, 110, -1}}, 255}, /* curve25519 CKK_EC_MONTGOMERY X25519 */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ - {{{-1}}, {{-1}}, 0 } /* This entry must not be touched. */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ + {{{-1}}, {{-1}}, 0 } /* This entry must not be touched. */ }; #endif /* ENABLE_OPENSSL */ @@ -114,11 +114,11 @@ struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; /* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */ static pgp_ec_curves_t ec_curves_gnuk[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 10, -1}}, 256}, /* secp256k1 */ - {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255}, /* ed25519 for signatures => CKK_EC_EDWARDS */ - {{{-1}}, 0 } /* This entry must not be touched. */ + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 10, -1}}, 256, SC_ALGORITHM_EC}, /* secp256k1 */ + {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{-1}}, 0, 0} /* This entry must not be touched. */ }; /* diff --git a/src/libopensc/card-openpgp.h b/src/libopensc/card-openpgp.h index 732ca3a325..85fc14865a 100644 --- a/src/libopensc/card-openpgp.h +++ b/src/libopensc/card-openpgp.h @@ -163,6 +163,7 @@ typedef struct pgp_blob { typedef struct _pgp_ec_curves { struct sc_object_id oid; size_t size; + unsigned int key_type; } pgp_ec_curves_t; #ifdef ENABLE_OPENSSL From 1c9cc1ddea5e32bdf542fb0ab70fa2da8c947ed3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 23 Apr 2024 07:28:50 -0500 Subject: [PATCH 3686/4321] card.c - when adding an EC type alg call sc_pkcs15_fix_ec_parameters Changes to be committed: modified: libopensc/card.c --- src/libopensc/card.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 6978639565..09490adcbf 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1167,6 +1167,7 @@ _sc_card_add_ec_alg_int(sc_card_t *card, size_t key_length, int algorithm) { sc_algorithm_info_t info; + int r; memset(&info, 0, sizeof(info)); sc_init_oid(&info.u._ec.params.id); @@ -1176,10 +1177,18 @@ _sc_card_add_ec_alg_int(sc_card_t *card, size_t key_length, info.flags = flags; info.u._ec.ext_flags = ext_flags; - if (curve_oid) + if (curve_oid) { info.u._ec.params.id = *curve_oid; + r = sc_encode_oid(card->ctx, &info.u._ec.params.id, &info.u._ec.params.der.value, &info.u._ec.params.der.len); + LOG_TEST_GOTO_ERR(card->ctx, r, "sc_encode_oid failed"); + r = sc_pkcs15_fix_ec_parameters(card->ctx, &info.u._ec.params); + LOG_TEST_GOTO_ERR(card->ctx, r, "sc_pkcs15_fix_ec_parameters failed"); + } - return _sc_card_add_algorithm(card, &info); + r = _sc_card_add_algorithm(card, &info); +err: + free(info.u._ec.params.der.value); + return r; } int _sc_card_add_ec_alg(sc_card_t *card, size_t key_length, From 5e990bed538203852a620ad9a5ee436c04a1bf9e Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 23 Apr 2024 07:32:53 -0500 Subject: [PATCH 3687/4321] pkcs15-pubkey.c - FIXUP order of key_type in sc_curve_info On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index cf49daa2f2..cdce990f5b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1446,8 +1446,8 @@ static struct ec_curve_info { const char *name; const char *oid_str; const char *oid_encoded; - const unsigned int key_type; size_t size; + const unsigned int key_type; } ec_curve_infos[] = { {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, @@ -1509,7 +1509,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp /* In PKCS#11 EC parameters arrives in DER encoded form */ if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { - + /* caller provided a der version of OID */ switch (ecparams->der.value[0]) { case 0x06: /* der.value is an OID */ @@ -1582,7 +1582,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp ecparams->field_length = ec_curve_infos[ii].size; ecparams->key_type = ec_curve_infos[ii].key_type; sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u key_type %d", - ecparams->field_length, ecparams->key_type); + ecparams->field_length, ecparams->key_type); if (mapped_string) { /* replace the printable string version with the oid */ free(ecparams->der.value); @@ -1612,8 +1612,13 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp LOG_TEST_RET(ctx, rv, "Invalid OID format"); ecparams->field_length = ec_curve_infos[ii].size; + ecparams->key_type = ec_curve_infos[ii].key_type; + sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u key_type %d", + ecparams->field_length, ecparams->key_type); if (!ecparams->der.value || !ecparams->der.len) { + free(ecparams->der.value); /* just in case */ + ecparams->der.value = NULL; /* if caller did not provide der OID, fill in */ rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len); LOG_TEST_RET(ctx, rv, "Cannot encode object ID"); From dc368e5f6ba4d43b7042f34ea4f4cb3feb3c56b9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 23 Apr 2024 11:18:50 -0500 Subject: [PATCH 3688/4321] card.c - fix bug in sc_copy_ec_params Two fields were being copied from the dst the src sc_copy_ec_params is only used in pkcs15init/pkcs15-lib.c On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card.c --- src/libopensc/card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 09490adcbf..fa89338222 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1537,8 +1537,8 @@ int sc_copy_ec_params(struct sc_ec_parameters *dst, struct sc_ec_parameters *src memcpy(dst->der.value, src->der.value, src->der.len); dst->der.len = src->der.len; } - src->type = dst->type; - src->field_length = dst->field_length; + dst->type = src->type; + dst->field_length = src->field_length; return SC_SUCCESS; } From f37fecae192fc0668e45ab7616ba5beb0407534b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 24 Apr 2024 11:25:01 -0500 Subject: [PATCH 3689/4321] pkcs15init/pkcs15-openpgp.c - test id and ec type keys On branch X25519-improvements-2 Changes to be committed: modified: ../pkcs15init/pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 26d0e5239c..60e9dfb283 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2563,7 +2563,6 @@ check_keygen_params_consistency(struct sc_card *card, LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } - /* * Check whether the card has native crypto support for this key. */ @@ -2575,13 +2574,21 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, unsigned long alg, struct sc_context *ctx = p15card->card->ctx; struct sc_algorithm_info *info; unsigned int count; + unsigned long talg = alg; LOG_FUNC_CALLED(ctx); + + if (alg == SC_ALGORITHM_EDDSA || alg == SC_ALGORITHM_XEDDSA) + talg = SC_ALGORITHM_EC; /* really testing ecparams */ + count = p15card->card->algorithm_count; for (info = p15card->card->algorithms; count--; info++) { /* don't check flags if none was specified */ - if (info->algorithm != alg || info->key_length != key_length) - continue; + + if (alg != SC_ALGORITHM_EDDSA && alg != SC_ALGORITHM_XEDDSA) { + if (info->algorithm != alg || info->key_length != key_length) + continue; + } if (flags != 0 && ((info->flags & flags) != flags)) continue; @@ -2600,8 +2607,7 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, unsigned long alg, if (info->u._rsa.exponent != exponent) continue; } - } - else if (alg == SC_ALGORITHM_EC) { + } else if (talg == SC_ALGORITHM_EC) { /* includes EDDSA and XEDDSA */ if (!sc_valid_oid(&prkey->u.ec.params.id)) if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->u.ec.params)) LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID); From e40bfcc734aa81d10d75887f19cb0133055a64f6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 24 Apr 2024 11:36:03 -0500 Subject: [PATCH 3690/4321] card.c when copying sc_ec_parameters get new key_type too On branch X25519-improvements-2 Changes to be committed: modified: card.c --- src/libopensc/card.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index fa89338222..b0638f5b49 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1188,7 +1188,7 @@ _sc_card_add_ec_alg_int(sc_card_t *card, size_t key_length, r = _sc_card_add_algorithm(card, &info); err: free(info.u._ec.params.der.value); - return r; + return r; } int _sc_card_add_ec_alg(sc_card_t *card, size_t key_length, @@ -1539,6 +1539,7 @@ int sc_copy_ec_params(struct sc_ec_parameters *dst, struct sc_ec_parameters *src } dst->type = src->type; dst->field_length = src->field_length; + dst->key_type = src->key_type; return SC_SUCCESS; } From 78db2ff3888b0a172d1360f5f3187fa0611c0de8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 24 Apr 2024 11:49:40 -0500 Subject: [PATCH 3691/4321] pkcs15init/pkcs15-openpgp.c - set key_info.algorithm so EDDSA and XEDDSA work On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index dbe2e66227..d9b7e1922b 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -286,7 +286,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, sc_cardctl_openpgp_keygen_info_t key_info; sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; sc_pkcs15_id_t *kid = &(required->id); - const struct sc_ec_parameters *info_ec = + struct sc_ec_parameters *info_ec = (struct sc_ec_parameters *)required->params.data; int r; @@ -311,14 +311,22 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, key_info.key_id = kid->value[0]; - /* set algorithm id based on key reference */ - key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) - ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ - : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ - - /* DEE NO extract oid the way we need to import it to OpenPGP Card */ - /* TODO DEE pass the oid. will convert to asn1 before writing */ - /* TODO DEE not sure id test for der.len >2 is needed */ + /* set algorithm id based on key reference and key type */ + switch (pubkey->algorithm) { + case SC_ALGORITHM_EC: + key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) + ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ + : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + break; + case SC_ALGORITHM_EDDSA: + key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* oly sign */ + break; + case SC_ALGORITHM_XEDDSA: + /* TODO may need to look at MSE, and how sign XEDDSA certificate */ + key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be be used to sign too */ + break; + } + /* copying info_ec.id works for any EC ECDH EdDSA keys */ if (info_ec->der.len > 2) key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ @@ -337,7 +345,12 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, /* set pubkey according to response of card */ sc_log(ctx, "Set output ecpoint info"); + /* TODO DEE may need changes for ECDH and EdDSA or XEDDSA */ + + + + pubkey->algorithm = SC_ALGORITHM_EC; pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); From c5d6b55b61497845b0526a7132029a5667b388cd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 22 Aug 2024 14:48:42 -0500 Subject: [PATCH 3692/4321] card-openpgp.c - fix invalid read found by valgrind On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 78 ++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 9145f0304d..7d0b9bafb6 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -86,6 +86,7 @@ static struct sc_card_driver pgp_drv = { NULL, 0, NULL }; +// clang-format off static pgp_ec_curves_t ec_curves_openpgp34[] = { /* OpenPGP 3.4+ Ed25519 and Curve25519 */ {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ @@ -106,6 +107,7 @@ static pgp_ec_curves_alt_t ec_curves_alt[] = { {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, {{1, 3, 101, 112, -1}}, 255}, /* ed25519 CKK_EC_EDWARDS Ed25519 */ {{{-1}}, {{-1}}, 0 } /* This entry must not be touched. */ }; + #endif /* ENABLE_OPENSSL */ static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; @@ -114,12 +116,13 @@ struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; /* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */ static pgp_ec_curves_t ec_curves_gnuk[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ - {{{1, 3, 132, 0, 10, -1}}, 256, SC_ALGORITHM_EC}, /* secp256k1 */ + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ + {{{1, 3, 132, 0, 10, -1}}, 256, SC_ALGORITHM_EC}, /* secp256k1 */ {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ - {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ - {{{-1}}, 0, 0} /* This entry must not be touched. */ + {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{-1}}, 0, 0} /* This entry must not be touched. */ }; +// clang-format on /* * The OpenPGP card doesn't have a file system, instead everything @@ -2585,10 +2588,9 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - pgp_set_blob(algo_blob, data, data_len); + r = pgp_put_data(card, tag, data, data_len); + /* Note: pgp_put_data calls pgp_set_blob */ free(data); - r = pgp_put_data(card, tag, algo_blob->data, data_len); - /* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */ LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); } else { sc_cardctl_openpgp_keygen_info_t old_key_info; @@ -2693,8 +2695,9 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, } /* ECC */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* also includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { if (key_info->u.ec.ecpoint == NULL || (key_info->u.ec.ecpoint_len) == 0) { sc_log(card->ctx, "Error: ecpoint required!"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -2707,7 +2710,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, + 1 /* algorithm */ + 1 /* oid len */ + (key_info->u.ec.oid_len) /* oid */ - + (key_info->u.ec.ecpoint_len); /* ecpoint */ + + BYTES4BITS(key_info->u.ec.ecpoint_len); /* ecpoint */ /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { @@ -2757,9 +2760,9 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, memcpy(p, key_info->u.rsa.exponent, bytes_length); } /* ECC */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA - || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { /* Algorithm ID, see https://tools.ietf.org/html/rfc6637#section-5 */ *p = key_info->algorithm + 6; p += 1; @@ -2767,13 +2770,13 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, p += 1; memcpy(p, key_info->u.ec.oid.value, key_info->u.ec.oid_len); p += key_info->u.ec.oid_len; - memcpy(p, key_info->u.ec.ecpoint, key_info->u.ec.ecpoint_len); + memcpy(p, key_info->u.ec.ecpoint, BYTES4BITS(key_info->u.ec.ecpoint_len)); /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { /* https://tools.ietf.org/html/rfc6637#section-8 * This is copied from GnuPG's ecdh_params() function in app-openpgp.c */ - p += key_info->u.ec.ecpoint_len; + p += BYTES4BITS(key_info->u.ec.ecpoint_len); *p = 0x03; /* number of bytes following */ p += 1; *p = 0x01; /* version of this format */ @@ -2882,10 +2885,12 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in p15pubkey.u.rsa.exponent.len = BYTES4BITS(key_info->u.rsa.exponent_len); } /* ECC */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + /* TODO FIXME? */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { memset(&p15pubkey, 0, sizeof(p15pubkey)); - p15pubkey.algorithm = SC_ALGORITHM_EC; + p15pubkey.algorithm = key_info->key_type; p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpoint; p15pubkey.u.ec.ecpointQ.len = BYTES4BITS(key_info->u.ec.ecpoint_len); } @@ -2979,10 +2984,27 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } /* set the output data */ - /* len is ecpoint length + format byte - * see section 7.2.14 of 3.3.1 specs */ - if ((key_info->u.ec.ecpoint_len) != (len - 1) - || key_info->u.ec.ecpoint == NULL) { + /* EC is in 04||x||y format + * (field_length + 7)/8 * 2 + 1 in bytes + * len is ecpoint length + format byte + * see section 7.2.14 of 3.3.1 specs + * EDDSA and XEDDSA have no format byte and one number + * (field_length + 7)/8 in bytes + */ + switch(key_info->key_type) { + case SC_ALGORITHM_EC: + len = 1 + BYTES4BITS((key_info->u.ec.ecpoint_len * 2)); + break; + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: + len = BYTES4BITS(key_info->u.ec.ecpoint_len); + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + /* FIXME is this redundent? */ + if (key_info->u.ec.ecpoint == NULL || len != BYTES4BITS(key_info->u.ec.ecpoint_len)) { free(key_info->u.ec.ecpoint); key_info->u.ec.ecpoint = malloc(len); if (key_info->u.ec.ecpoint == NULL) @@ -3023,6 +3045,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA && priv->bcd_version < OPENPGP_CARD_3_0) + /* TODO GUNK needs test here? */ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); if (id > card->algorithm_count) { @@ -3039,8 +3062,10 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke algo->algorithm = SC_ALGORITHM_RSA; algo->key_length = (unsigned int)key_info->u.rsa.modulus_len; } - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) { + /* TODO FIXME */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { algo->algorithm = SC_ALGORITHM_EC; algo->key_length = (unsigned int)((key_info->u.ec.ecpoint_len)); } @@ -3482,8 +3507,9 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); } /* ECC */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA){ memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; pubkey.algorithm = key_info->algorithm; From a730f4ee0e89b100f172aed5a14460e2aaaf12dd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 27 Apr 2024 16:12:34 -0500 Subject: [PATCH 3693/4321] pkcs15init/pkcs15-lib.c - fix double free Changes to be committed: modified: pkcs15init/pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 60e9dfb283..68073c7917 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2559,6 +2559,7 @@ check_keygen_params_consistency(struct sc_card *card, alg == SC_ALGORITHM_XEDDSA)) /* allocated in sc_pkcs15_fix_ec_parameters */ free(prkey->key.u.ec.params.der.value); + prkey->key.u.ec.params.der.value = NULL; LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } @@ -2579,7 +2580,7 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, unsigned long alg, LOG_FUNC_CALLED(ctx); if (alg == SC_ALGORITHM_EDDSA || alg == SC_ALGORITHM_XEDDSA) - talg = SC_ALGORITHM_EC; /* really testing ecparams */ + talg = SC_ALGORITHM_EC; /* really testing ecparams */ count = p15card->card->algorithm_count; for (info = p15card->card->algorithms; count--; info++) { From 69466a21d651109b126c9d8116f965b9a778c6bc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 28 Apr 2024 14:02:46 -0500 Subject: [PATCH 3694/4321] cardctl.h - add key_type as SC_ALGORITHM_* to sc_cardctl_openpgp_keygen_info keytype is used to map SC_ALGORITHM_* to/from SC_OPENPGP_KEYALGO_* On branch X25519-improvements-2 Changes to be committed: modified: libopensc/cardctl.h modified: libopensc/pkcs15-prkey.c modified: pkcs15init/pkcs15-lib.c modified: pkcs15init/pkcs15-openpgp.c --- src/libopensc/cardctl.h | 1 + src/libopensc/pkcs15-prkey.c | 2 ++ src/pkcs15init/pkcs15-lib.c | 3 ++- src/pkcs15init/pkcs15-openpgp.c | 24 +++++++++--------------- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 7b01b9ca9a..b3eed71a33 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -883,6 +883,7 @@ typedef struct sc_cardctl_piv_genkey_info_st { typedef struct sc_cardctl_openpgp_keygen_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ + unsigned long key_type; /* SC_ALGORITHM_... */ union { struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 78c80978db..9a358f24ab 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -570,6 +570,8 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key) free(key->u.gostr3410.d.data); break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: /* EC, Edwards and Montgomery use common ec params */ free(key->u.ec.params.der.value); free(key->u.ec.params.named_curve); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 68073c7917..7d675c6eb8 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2556,10 +2556,11 @@ check_keygen_params_consistency(struct sc_card *card, if (prkey && (alg == SC_ALGORITHM_EC || alg == SC_ALGORITHM_EDDSA || - alg == SC_ALGORITHM_XEDDSA)) + alg == SC_ALGORITHM_XEDDSA)) { /* allocated in sc_pkcs15_fix_ec_parameters */ free(prkey->key.u.ec.params.der.value); prkey->key.u.ec.params.der.value = NULL; + } LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index d9b7e1922b..d430d5b790 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -309,24 +309,23 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, if (!key_info.key_id) key_info.key_id = kid->value[0]; - - + key_info.key_type = pubkey->algorithm; /* set algorithm id based on key reference and key type */ switch (pubkey->algorithm) { case SC_ALGORITHM_EC: key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) - ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ - : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ + : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ break; case SC_ALGORITHM_EDDSA: - key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* oly sign */ + key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* only sign */ break; - case SC_ALGORITHM_XEDDSA: + case SC_ALGORITHM_XEDDSA: /* TODO may need to look at MSE, and how sign XEDDSA certificate */ - key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be be used to sign too */ + key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be be used to sign too */ break; } - + /* copying info_ec.id works for any EC ECDH EdDSA keys */ if (info_ec->der.len > 2) key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ @@ -335,7 +334,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, /* Prepare buffer */ key_info.u.ec.ecpoint_len = required->field_length; - key_info.u.ec.ecpoint = malloc(key_info.u.ec.ecpoint_len); + key_info.u.ec.ecpoint = malloc(BYTES4BITS(key_info.u.ec.ecpoint_len)); if (key_info.u.ec.ecpoint == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); @@ -346,12 +345,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, /* set pubkey according to response of card */ sc_log(ctx, "Set output ecpoint info"); - /* TODO DEE may need changes for ECDH and EdDSA or XEDDSA */ - - - - - pubkey->algorithm = SC_ALGORITHM_EC; + pubkey->algorithm = key_info.key_type; pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); if (pubkey->u.ec.ecpointQ.value == NULL) From 34c1489c8a6d0c4cf47b3b9f9bbd242d1c4b439a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 17:22:35 -0500 Subject: [PATCH 3695/4321] opensc.h - add sc_clear_ec_params sc_clear_ec_params used to free allocated menory and clear other data in struct sc_ec_parameters --- src/libopensc/opensc.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 7d9e170853..281392cf9c 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -281,19 +281,20 @@ struct sc_pbes2_params { }; /* - * PKCS11 2.3 Elliptic Curve lists mechanisms that use CKA_ECPARMS + * PKCS11 2.3 Elliptic Curve lists mechanisms that use CKA_EC_PARAMS * which implies the type of key and size needed in the OID * The ecParameters can be presented as * - name of curve; * - OID of named curve; * - implicit parameters. + * - printable string for non standard OIDS - added in pkcs11 3.0 * * type - type(choice) of 'EC domain parameters' as it present in CKA_EC_PARAMS (PKCS#11). * Recommended value '1' -- namedCurve. * field_length - EC key size in bits. * key_type - 0 implies SC_ALGORITHM_EC, SC_ALGORITHM_EDDSA or SC_ALGORITHM_XEDDSA - * Not actually part of CKA_EC_PARAMS - used to differentiate key types that use ec_params - * will be set by, sc_pkcs15_fix_ec_parameters + * Not actually part of CKA_EC_PARAMS - used in OpenSC to differentiate key types that use ec_params + * will be set by sc_pkcs15_fix_ec_parameters */ struct sc_ec_parameters { char *named_curve; @@ -1653,6 +1654,11 @@ const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outl */ void sc_remote_data_init(struct sc_remote_data *rdata); +/** + * Clear ec_params + * @ecp + */ +void sc_clear_ec_params(struct sc_ec_parameters *); /** * Copy and allocate if needed EC parameters data From c2390afb0537bb77a14da29d76f9e73cb57adf16 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 17:29:14 -0500 Subject: [PATCH 3696/4321] pkcs11-tool.c - CKK_EC_EDWARDS and CKK_EC_MONTGOMERY improvements Add support write_object support for ED448 and X448 objects, but no cards current suported by OpenSC implement these. Fix bug with n_attrs in derive-ec-key. Allow read_object of an EC_POINT to be in either OCTET_STRING or BIT_STRING On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 61 +++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6e3f2c9219..e8b7f538eb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4584,12 +4584,24 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } #if !defined(OPENSSL_NO_EC) -#ifdef EVP_PKEY_ED448 - else if ((pk_type == EVP_PKEY_EC) || (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) { -#else - else if ((pk_type == EVP_PKEY_EC) || (pk_type == EVP_PKEY_ED25519)) { +/* aappeas the precompiler */ +#ifndef EVP_PKEY_ED448 +#define EVP_PKEY_ED448 EVP_PKEY_ED25519 +#endif +#ifndef EVP_PKEY_X448 +#define EVP_PKEY_X448 EVP_PKEY_X25519 #endif - type = (pk_type == EVP_PKEY_EC) ? CKK_EC : CKK_EC_EDWARDS; + + else if ((pk_type == EVP_PKEY_EC) || + (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448) || + (pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) { + + if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) + type = CKK_EC_EDWARDS; + else if ((pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) + type = CKK_EC_MONTGOMERY; + else + type = CKK_EC; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; @@ -4597,8 +4609,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); n_privkey_attr++; - } - else if (pk_type == NID_id_GostR3410_2001) { + } else if (pk_type == NID_id_GostR3410_2001) { type = CKK_GOSTR3410; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); @@ -4625,12 +4636,11 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #if !defined(OPENSSL_NO_EC) else if (pk_type == EVP_PKEY_EC) type = CKK_EC; -#ifdef EVP_PKEY_ED448 else if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) -#else - else if (pk_type == EVP_PKEY_ED25519) -#endif type = CKK_EC_EDWARDS; + else if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) + type = CKK_EC_MONTGOMERY; + else if (pk_type == NID_id_GostR3410_2001) type = CKK_GOSTR3410; #endif @@ -4694,12 +4704,16 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; } #if !defined(OPENSSL_NO_EC) -#ifdef EVP_PKEY_ED448 - else if ((pk_type == EVP_PKEY_EC) || (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) { -#else - else if ((pk_type == EVP_PKEY_EC) || (pk_type == EVP_PKEY_ED25519)) { -#endif - type = (pk_type == EVP_PKEY_EC) ? CKK_EC : CKK_EC_EDWARDS; + else if ((pk_type == EVP_PKEY_EC) || + (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448) || + (pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) { + + if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) + type = CKK_EC_EDWARDS; + else if ((pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) + type = CKK_EC_MONTGOMERY; + else + type = CKK_EC; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_pubkey_attr++; @@ -4707,8 +4721,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, gost.public.value, gost.public.len); n_pubkey_attr++; - } - else if (pk_type == NID_id_GostR3410_2001) { + } else if (pk_type == NID_id_GostR3410_2001) { type = CKK_GOSTR3410; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); @@ -5230,7 +5243,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE {CKA_EXTRACTABLE, &_true, sizeof(_true) }, }; // clang-format on - int n_attrs = 7; + int n_attrs = 5; CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; BIO *bio_in = NULL; @@ -5719,7 +5732,9 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) /* * EDDSA and XEDDSA in PKCS11 and only one coordinate */ - ksize = (body_len) * 8; + /* TODO rebase on changes in master in this area */ + ksize = (body_len) * 8 - 1; + size = body_len; } if (ksize) @@ -6497,6 +6512,10 @@ static int read_object(CK_SESSION_HANDLE session) /* TODO DEE should be in BIT STRING accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); + if (!os) { + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)&len); + len = (len + 7) / 8; + } if (!os) { util_fatal("cannot decode EC_POINT"); } From 18144b5e517697b6244e055e1e0974d7115f15c7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 23 Aug 2024 15:43:46 -0500 Subject: [PATCH 3697/4321] pkcs11-tool.c - Accept EC_POINT as OCTET STRING or BIT STRING OpenSC has been using OCTET_STRING but PKCS11 says "DER-encoding of ANSI X9.62 ECPoint value Q" and ANSI X9.62 says the encoding is in a BIT_STRING just as in a SPKI, OpenSSL and isoApplet expects as well as every other document says. Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 130 +++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 60 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e8b7f538eb..64c5eb1487 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5241,9 +5241,13 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type) }, {CKA_SENSITIVE, &_false, sizeof(_false) }, {CKA_EXTRACTABLE, &_true, sizeof(_true) }, + {CKA_ENCRYPT, &_true, sizeof(_true) }, + {CKA_DECRYPT, &_true, sizeof(_true) }, + {CKA_WRAP, &_true, sizeof(_true) }, + {CKA_UNWRAP, &_true, sizeof(_true) } }; // clang-format on - int n_attrs = 5; + int n_attrs = 9; CK_ECDH1_DERIVE_PARAMS ecdh_parms; CK_RV rv; BIO *bio_in = NULL; @@ -5254,8 +5258,8 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE unsigned char * der = NULL; unsigned char * derp = NULL; size_t der_size = 0; - EVP_PKEY *pkey = NULL; - int key_id = 0; /* nid of peer key */ + EVP_PKEY *pkey = NULL; /* peer key */ + int key_id = 0; /* nid of peer key must match nid of key */ #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *eckey = NULL; const EC_GROUP *ecgroup = NULL; @@ -5285,9 +5289,11 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE util_fatal("Cannot read peer EC key from %s", opt_input); key_id = EVP_PKEY_id(pkey); + if (key_id == 0) + util_fatal("Unknown key type of peer key"); switch (key_id) { - case EVP_PKEY_EC: /* CKK_EC*/ + case EVP_PKEY_EC: /* CKK_EC need to get curves of pkey and key */ #if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EVP_PKEY_get0_EC_KEY(pkey); @@ -5305,26 +5311,37 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE key_len = BYTES4BITS(EC_GROUP_get_degree(ecgroup)); FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len)); n_attrs++; - break; - } - if (opt_allowed_mechanisms_len > 0) { - FILL_ATTR(newkey_template[n_attrs], - CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, - sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); - n_attrs++; - } + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(newkey_template[n_attrs], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_attrs++; + } #if OPENSSL_VERSION_NUMBER < 0x30000000L - switch (key_id) { - case EVP_PKEY_EC: - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) - util_fatal("malloc() failure\n"); + util_fatal("malloc() failure\n"); buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); +#else + EC_GROUP_free(ecgroup); + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); + if ((buf = (unsigned char *)malloc(buf_size)) == NULL) + util_fatal("malloc() failure\n"); + + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buf_size, NULL) != 1) { + free(buf); + util_fatal("Failed to parse other EC key from %s", opt_input); + } +#endif + if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) + util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); break; - case EVP_PKEY_X25519: + +#if defined(EVP_PKEY_X25519) + case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ #if defined(EVP_PKEY_X448) case EVP_PKEY_X448: #endif @@ -5335,34 +5352,11 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (buf == NULL) util_fatal("malloc() failure\n"); EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); - break; - default: - util_fatal("Unknown EVP_PKEY_id\n"); - } -#else - EC_GROUP_free(ecgroup); - EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); - if ((buf = (unsigned char *)malloc(buf_size)) == NULL) - util_fatal("malloc() failure\n"); - - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buf_size, NULL) != 1) { - free(buf); - util_fatal("Failed to parse peer EC key from %s", opt_input); - } -#endif - - switch (key_id) { - case EVP_PKEY_EC: /* CKK_EC*/ - if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) - util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); - break; - case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ -#if defined(EVP_PKEY_X448) - case EVP_PKEY_X448: -#endif + if (mech_mech != CKM_ECDH1_DERIVE) util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); break; +#endif /* defined(EVP_PKEY_X25519) */ default: util_fatal("Peer key not usable with derive or unknown %i", key_id); break; @@ -5696,27 +5690,36 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } if (pub) { unsigned char *bytes = NULL; + unsigned char *body; + unsigned long ksize = 0; unsigned int n; unsigned long body_len = 0; - bytes = getEC_POINT(sess, obj, &ksize); + bytes = getEC_POINT(sess, obj, &size); /* * simple parse of DER BIT STRING 0x03 or OCTET STRING 0x04 * good to 65K bytes */ - if (ksize > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { - if (bytes[1] <= 127 && ksize == (unsigned long)(bytes[1] + 2)) { - body_len = ksize - 2; + if (size > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { + if (bytes[1] <= 127 && size == (unsigned long)(bytes[1] + 2)) { + body_len = size - 2; + body = bytes + 2; } else if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { - body_len = ksize - 3; + body_len = size - 3; + body = bytes + 3; } else if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { - body_len = ksize - 4; + body_len = size - 4; + body = bytes + 4; + } else { + body_len = 0; /* some problem with size */ } } /* With BIT STRING remove unused bits in last byte indicator */ - if (body_len > 0 && bytes[0] == 0x03) + if (body_len > 0 && bytes[0] == 0x03) { body_len--; + body++; + } if (key_type == CKK_EC && body_len > 0) { /* @@ -5728,13 +5731,14 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) * Do simple size calculation based on DER encoding */ ksize = (body_len - 1) * 4; + } else if (body_len > 0) { /* * EDDSA and XEDDSA in PKCS11 and only one coordinate */ - /* TODO rebase on changes in master in this area */ - ksize = (body_len) * 8 - 1; - size = body_len; + ksize = (body_len) * 8; + if (ksize == 256) + ksize--; /* as 25519 uses 255 as bits */ } if (ksize) @@ -5742,18 +5746,19 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) else printf(" EC_POINT size unknown"); - if (bytes) { + if (bytes && body) { if ((CK_LONG)size > 0) { /* Will print the point here */ printf(" EC_POINT: "); - for (n = 0; n < size; n++) - printf("%02x", bytes[n]); + for (n = 0; n < body_len; n++) + printf("%02x", body[n]); printf("\n"); } - free(bytes); } + free(bytes); bytes = NULL; + size = 0; bytes = getEC_PARAMS(sess, obj, &size); - if (bytes){ + if (bytes) { if ((CK_LONG)size > 0) { struct sc_object_id oid; @@ -6402,9 +6407,14 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* TODO DEE Should be returned encoded in BIT STRING, Need to accept both */ + /* DEE Should be returned encoded in BIT STRING, Need to accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); + if (!os) { + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); + len = (len + 7) / 8; + } + #if OPENSSL_VERSION_NUMBER < 0x30000000L group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); #else @@ -6509,11 +6519,11 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* TODO DEE should be in BIT STRING accept both */ + /* DEE should be in BIT STRING accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { - os = d2i_ASN1_BIT_STRING(NULL, &a, (long)&len); + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); len = (len + 7) / 8; } if (!os) { From 5f3f393502c4dd411fa573119d8287bacc7288a3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 31 Aug 2024 13:29:04 -0500 Subject: [PATCH 3698/4321] pkcs11-tool.c - Improved handling of versions or OpenSSL or no OpenSSL When compiled with different versions of OpenSSL, LibreSSL or no OpenSSL have different support for EVP_PKEY for different key types. evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) takes a pkey and maps it to a PKCS11 CK_KEY_TYPE, in one place. It also returns the EVP_PKEY base id. PKCS11 treats Edwards and Montgomery keys as having 2 different EC curve names, where as OpenSSL gives every EC and Edwards and Montgomery keys their own NID. Thus the use of the CK_KEY_TYPE *type and pk_type (the NID) can be used to tell the difference. Addressed some comments in github. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 197 ++++++++++++++++++++++++---------------- 1 file changed, 119 insertions(+), 78 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 64c5eb1487..7a6b21265a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4257,6 +4257,90 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) return 0; } + +#ifdef ENABLE_OPENSSL +/* return PKCS11 key type based on OpenSSL EVP_PKEY type + * which are support by PKCS11 and OpenSSL used when compiling + * PKCS11 returns CKK_EC_EDWARDS for both ED25529 and X448 + * and CKK_EC_MONTGOMERY for X25519 and X448, use pk_type. + */ +static CK_RV +evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) +{ + if (!pkey || !pk_type || !type) + return CKR_GENERAL_ERROR; + + *pk_type = EVP_PKEY_base_id(pkey); + +#if defined(EVP_PKEY_RSA) + if (*pk_type == EVP_PKEY_RSA) { + *type = CKK_RSA; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_EC) + if (*pk_type == EVP_PKEY_EC) { + *type = CKK_EC; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_ED25519) + if (*pk_type == EVP_PKEY_ED25519) { + *type = CKK_EC_EDWARDS; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_ED448) + if (*pk_type == EVP_PKEY_ED448) { + *type = CKK_EC_EDWARDS; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_X25519) + if (*pk_type == EVP_PKEY_X25519) { + *type = CKK_EC_MONTGOMERY; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_X448) + if (*pk_type == EVP_PKEY_X448) { + *type = CKK_EC_MONTGOMERY; + return CKR_OK; + } +#endif + +#if defined(NID_id_GostR3410_2001) + if (*pk_type == NID_id_GostR3410_2001) { + *type = CKK_GOSTR3410; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_GOSTR3411) + if (*pk_type == EVP_PKEY_GOSTR3411) { + *type = CKK_GOSTR3411; + return CKR_OK; + } +#endif + +#if defined(EVP_PKEY_GOST28147) + if (*pk_type == EVP_PKEY_GOST28147) { + *type = CKK_GOST28147; + return CKR_OK; + } +#endif + /* unsupported by OpenSSL, PKCS11 or this program */ + *type = -1; + *pk_type = -1; + return CKR_FUNCTION_NOT_SUPPORTED; +} +#endif /* ENABLE_OPENSSL */ + static int parse_ed_pkey(EVP_PKEY *pkey, int pk_type, int private, struct gostkey_info *gost) { @@ -4426,6 +4510,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #ifdef ENABLE_OPENSSL int is_private = opt_object_class == CKO_PRIVATE_KEY; int rv; + CK_KEY_TYPE type; rv = do_read_key(contents, contents_len, is_private, &evp_key); if (rv) { @@ -4435,25 +4520,21 @@ static CK_RV write_object(CK_SESSION_HANDLE session) util_fatal("Cannot read public key"); } - pk_type = EVP_PKEY_base_id(evp_key); + /* get CK_TYPE from EVP_PKEY if both supported by OpenSSL and PKCS11 */ + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + util_fatal("Key type not supported by OpenSSL and/or PKCS11"); - if (pk_type == EVP_PKEY_RSA) { + if (type == CKK_RSA) { rv = parse_rsa_pkey(evp_key, is_private, &rsa); } #if !defined(OPENSSL_NO_EC) - else if (pk_type == NID_id_GostR3410_2001) { + else if (type == NID_id_GostR3410_2001) { rv = parse_gost_pkey(evp_key, is_private, &gost); type = CKK_GOSTR3410; - } else if (pk_type == EVP_PKEY_EC) { + } else if (type == CKK_EC) { rv = parse_ec_pkey(evp_key, is_private, &gost); - type = CKK_EC; -#ifdef EVP_PKEY_ED448 - } else if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) { -#else - } else if (pk_type == EVP_PKEY_ED25519) { -#endif + } else if (type == CKK_EC_EDWARDS) { rv = parse_ed_pkey(evp_key, pk_type, is_private, &gost); - type = CKK_EC_EDWARDS; } #endif else @@ -4560,10 +4641,11 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); n_privkey_attr++; } - pk_type = EVP_PKEY_base_id(evp_key); - if (pk_type == EVP_PKEY_RSA) { - type = CKK_RSA; + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + util_fatal("Key type not supported by OpenSSL and/or PKCS11"); + + if (type == CKK_RSA) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len); @@ -4583,34 +4665,15 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_COEFFICIENT, rsa.coefficient, rsa.coefficient_len); n_privkey_attr++; } -#if !defined(OPENSSL_NO_EC) -/* aappeas the precompiler */ -#ifndef EVP_PKEY_ED448 -#define EVP_PKEY_ED448 EVP_PKEY_ED25519 -#endif -#ifndef EVP_PKEY_X448 -#define EVP_PKEY_X448 EVP_PKEY_X25519 -#endif - - else if ((pk_type == EVP_PKEY_EC) || - (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448) || - (pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) { - - if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) - type = CKK_EC_EDWARDS; - else if ((pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) - type = CKK_EC_MONTGOMERY; - else - type = CKK_EC; + else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type = CKK_EC_MONTGOMERY)) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); n_privkey_attr++; - } else if (pk_type == NID_id_GostR3410_2001) { - type = CKK_GOSTR3410; + } else if (type == CKK_GOSTR3410) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; @@ -4623,30 +4686,16 @@ static CK_RV write_object(CK_SESSION_HANDLE session) return rv; n_privkey_attr++; } - -#endif +#else + util_fatal("No OpenSSL support, cannot write private key"); #endif break; case CKO_PUBLIC_KEY: clazz = CKO_PUBLIC_KEY; + #ifdef ENABLE_OPENSSL - pk_type = EVP_PKEY_base_id(evp_key); - if (pk_type == EVP_PKEY_RSA) - type = CKK_RSA; -#if !defined(OPENSSL_NO_EC) - else if (pk_type == EVP_PKEY_EC) - type = CKK_EC; - else if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) - type = CKK_EC_EDWARDS; - else if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) - type = CKK_EC_MONTGOMERY; - - else if (pk_type == NID_id_GostR3410_2001) - type = CKK_GOSTR3410; -#endif - else - util_fatal("Unsupported public key type: 0x%X", pk_type); -#endif + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + util_fatal("Key type not supported by OpenSSL and/or PKCS11"); n_pubkey_attr = 0; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_CLASS, &clazz, sizeof(clazz)); @@ -4686,15 +4735,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; } -#ifdef ENABLE_OPENSSL if (cert.subject_len != 0) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); n_pubkey_attr++; } - pk_type = EVP_PKEY_base_id(evp_key); - if (pk_type == EVP_PKEY_RSA) { - type = CKK_RSA; + if (type == CKK_RSA) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS, @@ -4704,16 +4750,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; } #if !defined(OPENSSL_NO_EC) - else if ((pk_type == EVP_PKEY_EC) || - (pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448) || - (pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) { - - if ((pk_type == EVP_PKEY_ED25519) || (pk_type == EVP_PKEY_ED448)) - type = CKK_EC_EDWARDS; - else if ((pk_type == EVP_PKEY_X25519) || (pk_type == EVP_PKEY_X448)) - type = CKK_EC_MONTGOMERY; - else - type = CKK_EC; + else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_pubkey_attr++; @@ -4736,6 +4773,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; } #endif +#else + util_fatal("No OpenSSL support, cannot write public key"); #endif break; case CKO_SECRET_KEY: @@ -5259,7 +5298,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE unsigned char * derp = NULL; size_t der_size = 0; EVP_PKEY *pkey = NULL; /* peer key */ - int key_id = 0; /* nid of peer key must match nid of key */ + int key_id = 0; /* nid of peer key must match nid of key */ #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *eckey = NULL; const EC_GROUP *ecgroup = NULL; @@ -5303,7 +5342,9 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (!ecpoint || !ecgroup) util_fatal("Failed to parse peer EC key from %s", opt_input); #else - if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 || (nid = OBJ_txt2nid(name)) == NID_undef || (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) + if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 || + (nid = OBJ_txt2nid(name)) == NID_undef || + (ecgroup = EC_GROUP_new_by_curve_name(nid)) == NULL) util_fatal("Failed to parse peer EC key from %s", opt_input); #endif @@ -5314,22 +5355,22 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(newkey_template[n_attrs], - CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, - sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); n_attrs++; } #if OPENSSL_VERSION_NUMBER < 0x30000000L - buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) - util_fatal("malloc() failure\n"); + util_fatal("malloc() failure\n"); buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); #else EC_GROUP_free(ecgroup); EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); if ((buf = (unsigned char *)malloc(buf_size)) == NULL) - util_fatal("malloc() failure\n"); + util_fatal("malloc() failure\n"); if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buf_size, NULL) != 1) { free(buf); @@ -5339,7 +5380,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (mech_mech != CKM_ECDH1_DERIVE && mech_mech != CKM_ECDH1_COFACTOR_DERIVE) util_fatal("Peer key %s not usable with %s", "CKK_EC", p11_mechanism_to_name(mech_mech)); break; - + #if defined(EVP_PKEY_X25519) case EVP_PKEY_X25519: /* "CKK_EC_MONTGOMERY */ #if defined(EVP_PKEY_X448) @@ -5352,7 +5393,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (buf == NULL) util_fatal("malloc() failure\n"); EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); - + if (mech_mech != CKM_ECDH1_DERIVE) util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); break; @@ -6414,7 +6455,7 @@ static int read_object(CK_SESSION_HANDLE session) os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); len = (len + 7) / 8; } - + #if OPENSSL_VERSION_NUMBER < 0x30000000L group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); #else From c870275de73c4d094888d169cae14699c4a0bfa4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 17:39:20 -0500 Subject: [PATCH 3699/4321] card.c - add sc_clear_ec_params expand sc_card_find_alg sc_clear_ec_params clears an struct sc_ec_parameters by freeing allocated memory. card_find_alg will first check if info->algroithm is one that uses sc_ec_parameters and then checks that the OIDs match. then check if keylength match. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card.c --- src/libopensc/card.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index b0638f5b49..e44d4984b7 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -163,11 +163,10 @@ static void sc_card_free(sc_card_t *card) int i; for (i=0; ialgorithm_count; i++) { struct sc_algorithm_info *info = (card->algorithms + i); - if (info->algorithm == SC_ALGORITHM_EC) { - struct sc_ec_parameters ep = info->u._ec.params; - - free(ep.named_curve); - free(ep.der.value); + if (info->algorithm == SC_ALGORITHM_EC || + info->algorithm == SC_ALGORITHM_EDDSA || + info->algorithm == SC_ALGORITHM_XEDDSA) { + sc_clear_ec_params(&info->u._ec.params); } } free(card->algorithms); @@ -1186,8 +1185,9 @@ _sc_card_add_ec_alg_int(sc_card_t *card, size_t key_length, } r = _sc_card_add_algorithm(card, &info); + return r; err: - free(info.u._ec.params.der.value); + sc_clear_ec_params(&info.u._ec.params); return r; } @@ -1225,13 +1225,13 @@ sc_algorithm_info_t *sc_card_find_alg(sc_card_t *card, for (i = 0; i < card->algorithm_count; i++) { sc_algorithm_info_t *info = &card->algorithms[i]; - if (info->algorithm != algorithm) - continue; if (param && (info->algorithm == SC_ALGORITHM_EC || info->algorithm == SC_ALGORITHM_EDDSA || info->algorithm == SC_ALGORITHM_XEDDSA)) { if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id)) return info; + } else if (info->algorithm != algorithm) { + continue; } else if (info->key_length == key_length) return info; } @@ -1516,6 +1516,17 @@ void sc_print_cache(struct sc_card *card) sc_print_path(&card->cache.current_df->path)); } +void +sc_clear_ec_params(struct sc_ec_parameters *ecp) +{ + if (ecp) { + free(ecp->named_curve); + free(ecp->der.value); + memset(ecp, 0, sizeof(struct sc_ec_parameters)); + } + return; +} + int sc_copy_ec_params(struct sc_ec_parameters *dst, struct sc_ec_parameters *src) { if (!dst || !src) From cba3204196029a2f1ca31b343ddb611f7bb5b359 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 17:55:30 -0500 Subject: [PATCH 3700/4321] pkcs15init/pkcs15-lib.c - Changes for sc_clear_ec_params Fix several problems with use of sc_ec_parameters On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 42 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 7d675c6eb8..09a32f6f15 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -176,10 +176,7 @@ static void sc_pkcs15init_free_ec_params(void *ptr) { struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)ptr; if (ecparams) { - if (ecparams->der.value) - free(ecparams->der.value); - if (ecparams->named_curve) - free(ecparams->named_curve); + sc_clear_ec_params(ecparams); free(ecparams); } } @@ -1608,7 +1605,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr } else if (algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) { - /* needs to be freed in case of failure when pubkey is not set yet */ r = sc_copy_ec_params(&pubkey_args.key.u.ec.params, &keygen_args->prkey_args.key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC parameters"); } @@ -1633,7 +1629,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (iid.len) key_info->id = iid; } - pubkey = &pubkey_args.key; if (!pubkey->alg_id) { pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id)); @@ -1676,11 +1671,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr err: sc_pkcs15_free_object(object); sc_pkcs15_erase_pubkey(&pubkey_args.key); - if (algorithm == SC_ALGORITHM_EC) { - /* allocated in check_keygen_params_consistency() */ - free(keygen_args->prkey_args.key.u.ec.params.der.value); - keygen_args->prkey_args.key.u.ec.params.der.value = NULL; - } LOG_FUNC_RETURN(ctx, r); } @@ -1916,13 +1906,29 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; break; case SC_ALGORITHM_EC: - type = SC_PKCS15_TYPE_PUBKEY_EC; + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: r = sc_copy_ec_params(&key.u.ec.params, &keyargs->key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy EC public key parameters"); r = sc_pkcs15_fix_ec_parameters(ctx, &key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Failed to fix EC public key parameters"); + if (keyargs->key.u.ec.ecpointQ.value) { + key.u.ec.ecpointQ.value = malloc(keyargs->key.u.ec.ecpointQ.len); + if (!key.u.ec.ecpointQ.value) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy EC... public key parameters"); + } + } + + if (key.algorithm == SC_ALGORITHM_EC) + type = SC_PKCS15_TYPE_PUBKEY_EC; + else if (key.algorithm == SC_ALGORITHM_EDDSA) + type = SC_PKCS15_TYPE_PUBKEY_EDDSA; + else if (key.algorithm == SC_ALGORITHM_XEDDSA) + type = SC_PKCS15_TYPE_PUBKEY_XEDDSA; + keybits = key.u.ec.params.field_length; break; default: @@ -1963,8 +1969,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile keyinfo_gostparams->gostr3410 = keyargs->params.gost.gostr3410; keyinfo_gostparams->gostr3411 = keyargs->params.gost.gostr3411; keyinfo_gostparams->gost28147 = keyargs->params.gost.gost28147; - } - else if (key.algorithm == SC_ALGORITHM_EC) { + } else if (key.algorithm == SC_ALGORITHM_EC || + key.algorithm == SC_ALGORITHM_EDDSA || + key.algorithm == SC_ALGORITHM_XEDDSA) { + /* TODO if EC don't write the 0x04 byte to card */ key_info->field_length = keybits; if (key.u.ec.params.der.value) { key_info->params.data = malloc(key.u.ec.params.der.len); @@ -2769,8 +2777,10 @@ prkey_bits(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key) } return SC_PKCS15_GOSTR3410_KEYSIZE; case SC_ALGORITHM_EC: - sc_log(ctx, "Private EC key length %"SC_FORMAT_LEN_SIZE_T"u", - key->u.ec.params.field_length); + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: + sc_log(ctx, "Private EC type key length %" SC_FORMAT_LEN_SIZE_T "u", + key->u.ec.params.field_length); if (key->u.ec.params.field_length == 0) { sc_log(ctx, "Invalid EC key length"); return SC_ERROR_OBJECT_NOT_VALID; From 2c76fb5b96a954fc14a6b900bfe09c126654166c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 18:02:37 -0500 Subject: [PATCH 3701/4321] card-openpgp.c pkcs15init/pkcs15-openpgp.c - fixes Improvments and fixes for mem leaks and GUNK and mapping RFC8410 OIDs. When writing or generating a key add all known algs to card->algrorithms. Fix some BYTES4BITS bugs and formating. Add note about borblems trying to store RFC8410 type key. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c modified: pkcs15init/pkcs15-openpgp.c --- src/libopensc/card-openpgp.c | 250 ++++++++++++++++++++------------ src/pkcs15init/pkcs15-openpgp.c | 68 ++++----- 2 files changed, 183 insertions(+), 135 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7d0b9bafb6..fb7c793387 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -90,7 +90,10 @@ static struct sc_card_driver pgp_drv = { static pgp_ec_curves_t ec_curves_openpgp34[] = { /* OpenPGP 3.4+ Ed25519 and Curve25519 */ {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 101, 110, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* RFC8410 OID equivalent to curve25519 */ {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 101, 112, -1}}, 255, SC_ALGORITHM_EDDSA}, /* RFC8410 OID equivalent to ed25519 */ + /* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */ {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 34, -1}}, 384, SC_ALGORITHM_EC}, /* ansiX9p384r1 */ @@ -110,16 +113,19 @@ static pgp_ec_curves_alt_t ec_curves_alt[] = { #endif /* ENABLE_OPENSSL */ -static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2; +static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 4; struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}; +struct sc_object_id X25519_oid = {{1, 3, 101, 110, -1}}; /* need to check for RFC8410 version? */ /* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */ static pgp_ec_curves_t ec_curves_gnuk[] = { {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* ansiX9p256r1 */ {{{1, 3, 132, 0, 10, -1}}, 256, SC_ALGORITHM_EC}, /* secp256k1 */ {{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */ + {{{1, 3, 101, 110, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* RFC8410 OID equivalent to curve25519 */ {{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 255, SC_ALGORITHM_EDDSA}, /* ed25519 for signatures => CKK_EC_EDWARDS */ + {{{1, 3, 101, 112, -1}}, 255, SC_ALGORITHM_EDDSA}, /* RFC8410 OID equivalent to ed25519 */ {{{-1}}, 0, 0} /* This entry must not be touched. */ }; // clang-format on @@ -525,9 +531,11 @@ pgp_init(sc_card_t *card) /* if algorithm attributes can be changed, * add supported algorithms based on specification for pkcs15-init */ - if ((priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) && - (strcmp(card->ctx->app_name, "pkcs15-init") == 0)) { + /* pkcs11 or other utilities may need all the algs registered */ + if ((priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) + /* && (strcmp(card->ctx->app_name, "pkcs15-init") == 0) */) { unsigned long flags_rsa, flags_ecc, ext_flags; + unsigned long flags_eddsa, flags_xeddsa; /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / v3.x section 7.2.11 & 7.2.12 */ flags_rsa = SC_ALGORITHM_RSA_PAD_PKCS1| @@ -539,6 +547,12 @@ pgp_init(sc_card_t *card) SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; + flags_eddsa = SC_ALGORITHM_EDDSA_RAW | + SC_ALGORITHM_ONBOARD_KEY_GEN; + /* xeddsa may allow signing at some time */ + flags_xeddsa = SC_ALGORITHM_ECDH_CDH_RAW | + SC_ALGORITHM_ONBOARD_KEY_GEN; + switch (card->type) { case SC_CARD_TYPE_OPENPGP_V3: /* RSA 1024 was removed for v3+ */ @@ -549,8 +563,15 @@ pgp_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 2048, flags_rsa, 0); for (i=0; priv->ec_curves[i].oid.value[0] >= 0; i++) { - _sc_card_add_ec_alg(card, priv->ec_curves[i].size, - flags_ecc, ext_flags, &priv->ec_curves[i].oid); + if (priv->ec_curves[i].key_type == SC_ALGORITHM_EC) + _sc_card_add_ec_alg(card, priv->ec_curves[i].size, + flags_ecc, ext_flags, &priv->ec_curves[i].oid); + else if (priv->ec_curves[i].key_type == SC_ALGORITHM_EDDSA) + _sc_card_add_eddsa_alg(card, priv->ec_curves[i].size, + flags_eddsa, ext_flags, &priv->ec_curves[i].oid); + else + _sc_card_add_xeddsa_alg(card, priv->ec_curves[i].size, + flags_xeddsa, ext_flags, &priv->ec_curves[i].oid); } break; case SC_CARD_TYPE_OPENPGP_V2: @@ -689,7 +710,8 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, int _pgp_handle_curve25519(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, unsigned int do_num) { - if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) + if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid) && + !sc_compare_oid(&key_info.u.ec.oid, &X25519_oid)) return 0; /* CKM_XEDDSA supports both Sign and Derive, but @@ -2560,6 +2582,8 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ data[0] = key_info->algorithm; for (i = 0; i < aoid_len - 2; i++) data[i + 1] = aoid[i + 2]; + + free(aoid); } /* RSA */ @@ -2696,8 +2720,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* also includes XEDDSA */ - key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || - key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { if (key_info->u.ec.ecpoint == NULL || (key_info->u.ec.ecpoint_len) == 0) { sc_log(card->ctx, "Error: ecpoint required!"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -2705,11 +2729,11 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* https://tools.ietf.org/html/rfc4880 page 41, 72 * and https://tools.ietf.org/html/rfc6637 section 9 (page 8 and 9) */ - pk_packet_len = 1 /* version number */ - + 4 /* creation time */ - + 1 /* algorithm */ - + 1 /* oid len */ - + (key_info->u.ec.oid_len) /* oid */ + pk_packet_len = 1 /* version number */ + + 4 /* creation time */ + + 1 /* algorithm */ + + 1 /* oid len */ + + (key_info->u.ec.oid_len) /* oid */ + BYTES4BITS(key_info->u.ec.ecpoint_len); /* ecpoint */ /* KDF parameters for ECDH */ @@ -2720,8 +2744,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, + 1 /* KDF algo */ + 1; /* KEK algo */ } - } - else + } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); sc_log(card->ctx, "pk_packet_len is %"SC_FORMAT_LEN_SIZE_T"u", pk_packet_len); @@ -2794,8 +2817,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, *(p+1) = 0x09; /* KEK algo */ } } - } - else + } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); p = NULL; @@ -2892,9 +2914,8 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in memset(&p15pubkey, 0, sizeof(p15pubkey)); p15pubkey.algorithm = key_info->key_type; p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpoint; - p15pubkey.u.ec.ecpointQ.len = BYTES4BITS(key_info->u.ec.ecpoint_len); - } - else + p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpoint_len; + } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); r = sc_pkcs15_encode_pubkey(card->ctx, &p15pubkey, &data, &len); @@ -2922,7 +2943,8 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* store creation time */ r = pgp_store_creationtime(card, key_info->key_id, &ctime); - LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); + /* TODO for now with GNUK at least, log but do not return error */ + sc_log(card->ctx, "Cannot store creation time"); /* parse response. Ref: pgp_enumerate_blob() */ while (data_len > (size_t) (in - data)) { @@ -2984,26 +3006,32 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } /* set the output data */ - /* EC is in 04||x||y format + /* EC is in 04||x||y format * (field_length + 7)/8 * 2 + 1 in bytes * len is ecpoint length + format byte * see section 7.2.14 of 3.3.1 specs * EDDSA and XEDDSA have no format byte and one number * (field_length + 7)/8 in bytes */ - switch(key_info->key_type) { + /* GNUK returns 04|x|y */ + + /* TODO check len is reasonable */ + key_info->u.ec.ecpoint = malloc(len); + if (key_info->u.ec.ecpoint == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + + switch (key_info->key_type) { case SC_ALGORITHM_EC: - len = 1 + BYTES4BITS((key_info->u.ec.ecpoint_len * 2)); - break; case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: - len = BYTES4BITS(key_info->u.ec.ecpoint_len); + memcpy(key_info->u.ec.ecpoint, part, len); + key_info->u.ec.ecpoint_len = len; break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - /* FIXME is this redundent? */ + /* FIXME is this redundant? */ if (key_info->u.ec.ecpoint == NULL || len != BYTES4BITS(key_info->u.ec.ecpoint_len)) { free(key_info->u.ec.ecpoint); key_info->u.ec.ecpoint = malloc(len); @@ -3026,6 +3054,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, /* update pubkey blobs (B601, B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, key_info); + LOG_FUNC_RETURN(card->ctx, r); } @@ -3043,9 +3072,9 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke LOG_FUNC_CALLED(card->ctx); /* protect incompatible cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && priv->bcd_version < OPENPGP_CARD_3_0) - /* TODO GUNK needs test here? */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA && + priv->bcd_version < OPENPGP_CARD_3_0 && + card->type != SC_CARD_TYPE_OPENPGP_GNUK) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); if (id > card->algorithm_count) { @@ -3068,8 +3097,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { algo->algorithm = SC_ALGORITHM_EC; algo->key_length = (unsigned int)((key_info->u.ec.ecpoint_len)); - } - else + } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); @@ -3095,8 +3123,8 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA && - card->type != SC_CARD_TYPE_OPENPGP_GNUK && - priv->bcd_version < OPENPGP_CARD_3_0) + priv->bcd_version < OPENPGP_CARD_3_0 && + card->type != SC_CARD_TYPE_OPENPGP_GNUK) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* set Control Reference Template for key */ @@ -3313,12 +3341,12 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info componenttags[3] = 0x97; componentnames[3] = "modulus"; comp_to_add = 4; - } - /* validate */ - if (comp_to_add == 4 && (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0)){ - sc_log(ctx, "Error: Modulus required!"); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + /* validate */ + if (comp_to_add == 4 && (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0)) { + sc_log(ctx, "Error: Modulus required!"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } } /* Cardholder private key template's data part */ @@ -3354,18 +3382,18 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info comp_to_add = 1; /* import public key as well */ - if (key_info->u.ec.keyformat == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ + if (key_info->u.ec.keyformat == SC_OPENPGP_KEYFORMAT_EC_STDPUB) { components[1] = key_info->u.ec.ecpointQ; componentlens[1] = key_info->u.ec.ecpointQ_len; componenttags[1] = 0x99; componentnames[1] = "public key"; comp_to_add = 2; - } - /* validate */ - if ((key_info->u.ec.ecpointQ == NULL || key_info->u.ec.ecpointQ_len == 0)){ - sc_log(ctx, "Error: ecpointQ required!"); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + /* validate */ + if ((key_info->u.ec.ecpointQ == NULL || key_info->u.ec.ecpointQ_len == 0)) { + sc_log(ctx, "Error: ecpointQ required!"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } } /* Cardholder private key template's data part */ @@ -3453,14 +3481,25 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) sc_cardctl_openpgp_keygen_info_t pubkey; u8 *data = NULL; size_t len = 0; - int r; + int r = 0; + int has_pubkey = 0, has_privkey = 0; struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); + /* PKCS11 loads privkey separately from pubkey as two different operations + * So this routine will be called twice to create two different objects. + * pkcs15init only calls once, with both. + * OpenPGP 4.3.1 says modulus and ecpointQ are optional when + * creating the extended header. + * So we can tell the difference and only do appropriate parts of this + * routine. + */ + /* protect incompatible cards against non-RSA */ - if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && priv->bcd_version < OPENPGP_CARD_3_0) + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA && + priv->bcd_version < OPENPGP_CARD_3_0 && + card->type != SC_CARD_TYPE_OPENPGP_GNUK) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* Validate */ @@ -3471,18 +3510,29 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* set algorithm attributes */ /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ + has_pubkey = (key_info->u.rsa.n && key_info->u.rsa.n_len && + key_info->u.rsa.e && key_info->u.rsa.e_len); + has_privkey = (has_pubkey && + key_info->u.rsa.p && key_info->u.rsa.p_len && + key_info->u.rsa.q && key_info->u.rsa.q_len); + + if (!has_pubkey && !has_privkey) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + /* we just support standard key format */ - switch (key_info->u.rsa.keyformat) { - case SC_OPENPGP_KEYFORMAT_RSA_STD: - case SC_OPENPGP_KEYFORMAT_RSA_STDN: - break; + if (has_privkey) { + switch (key_info->u.rsa.keyformat) { + case SC_OPENPGP_KEYFORMAT_RSA_STD: + case SC_OPENPGP_KEYFORMAT_RSA_STDN: + break; - case SC_OPENPGP_KEYFORMAT_RSA_CRT: - case SC_OPENPGP_KEYFORMAT_RSA_CRTN: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + case SC_OPENPGP_KEYFORMAT_RSA_CRT: + case SC_OPENPGP_KEYFORMAT_RSA_CRTN: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - default: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } } /* we only support exponent of maximum 32 bits */ @@ -3496,60 +3546,68 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; pubkey.algorithm = key_info->algorithm; - if (key_info->u.rsa.n && key_info->u.rsa.n_len - && key_info->u.rsa.e && key_info->u.rsa.e_len) { - pubkey.u.rsa.modulus = key_info->u.rsa.n; - pubkey.u.rsa.modulus_len = key_info->u.rsa.n_len; - pubkey.u.rsa.exponent = key_info->u.rsa.e; - pubkey.u.rsa.exponent_len = key_info->u.rsa.e_len; - } - else - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + pubkey.u.rsa.modulus = key_info->u.rsa.n; + pubkey.u.rsa.modulus_len = key_info->u.rsa.n_len; + pubkey.u.rsa.exponent = key_info->u.rsa.e; + pubkey.u.rsa.exponent_len = key_info->u.rsa.e_len; + } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || - key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ - key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA){ + key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { + has_pubkey = (key_info->u.ec.ecpointQ && key_info->u.ec.ecpointQ_len); + has_privkey = (key_info->u.ec.privateD && key_info->u.ec.privateD_len); + + if (!has_pubkey && !has_privkey) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; pubkey.algorithm = key_info->algorithm; - if (key_info->u.ec.ecpointQ && key_info->u.ec.ecpointQ_len){ - pubkey.u.ec.ecpoint = key_info->u.ec.ecpointQ; - pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpointQ_len; - pubkey.u.ec.oid = key_info->u.ec.oid; - pubkey.u.ec.oid_len = key_info->u.ec.oid_len; - } - else - LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); + pubkey.u.ec.oid = key_info->u.ec.oid; + pubkey.u.ec.oid_len = key_info->u.ec.oid_len; + pubkey.u.ec.ecpoint = key_info->u.ec.ecpointQ; + pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpointQ_len; + pubkey.u.ec.oid = key_info->u.ec.oid; + pubkey.u.ec.oid_len = key_info->u.ec.oid_len; } - else - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - r = pgp_update_new_algo_attr(card, &pubkey); - LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); + /* TODO where is curve_name are */ + if (has_pubkey) { + r = pgp_update_new_algo_attr(card, &pubkey); + LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); + } /* build Extended Header list */ - r = pgp_build_extended_header_list(card, key_info, &data, &len); - LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to build Extended Header list"); + if (has_privkey) { + r = pgp_build_extended_header_list(card, key_info, &data, &len); + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to build Extended Header list"); + } /* write to DO */ - r = pgp_put_data(card, 0x4D, data, len); - LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to write to DO 004D"); + if (has_privkey) { + r = pgp_put_data(card, 0x4D, data, len); + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to write to DO 004D"); - /* store creation time */ - r = pgp_store_creationtime(card, key_info->key_id, &key_info->creationtime); - LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); + /* store creation time */ + r = pgp_store_creationtime(card, key_info->key_id, &key_info->creationtime); + LOG_TEST_RET(card->ctx, r, "Cannot store creation time"); + } - /* calculate and store fingerprint */ - sc_log(card->ctx, "Calculate and store fingerprint"); - r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, &pubkey); - LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); - /* update pubkey blobs (B601,B801, A401) */ - sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, &pubkey); + if (has_pubkey) { + /* calculate and store fingerprint */ + sc_log(card->ctx, "Calculate and store fingerprint"); + r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, &pubkey); + + LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); + /* update pubkey blobs (B601,B801, A401) */ + sc_log(card->ctx, "Update blobs holding pubkey info."); + r = pgp_update_pubkey_blob(card, &pubkey); - sc_log(card->ctx, "Update card algorithms"); - pgp_update_card_algorithms(card, &pubkey); + sc_log(card->ctx, "Update card algorithms"); + pgp_update_card_algorithms(card, &pubkey); + } err: free(data); diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index d430d5b790..5a767fd41c 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -117,9 +117,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, { sc_card_t *card = p15card->card; sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; - sc_cardctl_openpgp_keystore_info_t key_info; + sc_cardctl_openpgp_keystore_info_t key_info = {0}; int r; - unsigned int i; LOG_FUNC_CALLED(card->ctx); @@ -140,7 +139,10 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); break; case SC_PKCS15_TYPE_PRKEY_EC: - if (card->type < SC_CARD_TYPE_OPENPGP_V3) { + case SC_PKCS15_TYPE_PRKEY_EDDSA: + case SC_PKCS15_TYPE_PRKEY_XEDDSA: + if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && + card->type < SC_CARD_TYPE_OPENPGP_V3) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } @@ -151,35 +153,14 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.key_id = kinfo->id.value[0]; key_info.u.ec.privateD = key->u.ec.privateD.data; key_info.u.ec.privateD_len = key->u.ec.privateD.len; - key_info.u.ec.ecpointQ = key->u.ec.ecpointQ.value; - key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; - /* extract oid the way we need to import it to OpenPGP Card */ - if (key->u.ec.params.der.len > 2) - key_info.u.ec.oid_len = key->u.ec.params.der.value[1]; - else - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - - for (i=0; (i < key_info.u.ec.oid_len) && (i+2 < key->u.ec.params.der.len); i++){ - key_info.u.ec.oid.value[i] = key->u.ec.params.der.value[i+2]; + if (key->u.ec.ecpointQ.len) { + key_info.u.ec.ecpointQ = malloc(key->u.ec.ecpointQ.len); + if (!key_info.u.ec.ecpointQ) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + memcpy(&key_info.u.ec.ecpointQ, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len); } - key_info.u.ec.oid.value[key_info.u.ec.oid_len] = -1; - r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); - break; - case SC_PKCS15_TYPE_PRKEY_EDDSA: - if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EdDSA keys not supported on this card"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - } - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); - key_info.algorithm = (kinfo->id.value[0] == SC_OPENPGP_KEY_ENCR) - ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ - : SC_OPENPGP_KEYALGO_EDDSA; /* EdDSA for slot 1 and 3 */ - key_info.key_id = kinfo->id.value[0]; - /* TODO Test -- might not work */ - key_info.u.ec.privateD = key->u.ec.privateD.data; - key_info.u.ec.privateD_len = key->u.ec.privateD.len; - key_info.u.ec.ecpointQ = key->u.ec.ecpointQ.value; key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; + key_info.u.ec.oid = key->u.ec.params.id; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); break; default: @@ -312,17 +293,28 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, key_info.key_type = pubkey->algorithm; /* set algorithm id based on key reference and key type */ switch (pubkey->algorithm) { + /* EC is in 04||x||y format + * (field_length + 7)/8 * 2 + 1 in bytes + * len is ecpoint length + format byte + * see section 7.2.14 of 3.3.1 specs + * EDDSA and XEDDSA have no format byte and one number + * (field_length + 7)/8 in bytes + */ + case SC_ALGORITHM_EC: key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) - ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ - : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ + : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + key_info.u.ec.ecpoint_len = 1 + 2 * BYTES4BITS(required->field_length); break; case SC_ALGORITHM_EDDSA: key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* only sign */ + key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); break; case SC_ALGORITHM_XEDDSA: /* TODO may need to look at MSE, and how sign XEDDSA certificate */ - key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be be used to sign too */ + key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be used to sign too */ + key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); break; } @@ -332,11 +324,8 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - /* Prepare buffer */ - key_info.u.ec.ecpoint_len = required->field_length; - key_info.u.ec.ecpoint = malloc(BYTES4BITS(key_info.u.ec.ecpoint_len)); - if (key_info.u.ec.ecpoint == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + /* save expected length */ + key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); /* generate key on card */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); @@ -349,7 +338,8 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); if (pubkey->u.ec.ecpointQ.value == NULL) - goto err; + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpoint, key_info.u.ec.ecpoint_len); err: From ec2798551a5b4b8571b9f542bcf4fc34ccd0d28e Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 18:14:28 -0500 Subject: [PATCH 3702/4321] libopensc.exports - export sc_clear_ec_params On branch X25519-improvements-2 Changes to be committed: modified: libopensc/libopensc.exports --- src/libopensc/libopensc.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index b5f0b1cb27..fbc0ea96c4 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -64,6 +64,7 @@ sc_cancel sc_card_ctl sc_change_reference_data sc_check_sw +sc_clear_ec_params sc_compare_oid sc_compare_path sc_compare_path_prefix From cffbc1291506acc2dedcef1d91f811d03caa1235 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 18:17:26 -0500 Subject: [PATCH 3703/4321] framework-pkcs15.c - added support for more 448 size keys Base OIDs for EDWARDS and MONTGOMERY keys on the size of ecpointQ bewween 32 for 25519 and 56 for 448 keys. On branch X25519-improvements-2 Changes to be committed: modified: pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 108 +++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 27 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index fecd734d1e..b4c062c5ad 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -163,6 +163,15 @@ const unsigned int gostr3410_paramset_B_oid[] = {1, 2, 643, 2, 2, 35, 2, (unsign const CK_BYTE gostr3410_paramset_C_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 }; const unsigned int gostr3410_paramset_C_oid[] = {1, 2, 643, 2, 2, 35, 3, (unsigned int)-1}; +#ifdef ENABLE_OPENSSL +// clang-format off +static const struct sc_object_id oid_ED25519 = { { 1, 3, 101, 112, -1 } }; +static const struct sc_object_id oid_ED448 = { { 1, 3, 101, 113, -1 } }; +static const struct sc_object_id oid_X25519 = { { 1, 3, 101, 110, -1 } }; +static const struct sc_object_id oid_X448 = { { 1, 3, 101, 111, -1 } }; +// clang-format on +#endif /* ENABLE_OPENSSL */ + static const struct { const CK_BYTE *encoded_oid; const unsigned int encoded_oid_size; @@ -2367,12 +2376,12 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil break; case CKK_EC_EDWARDS: args.key.algorithm = SC_ALGORITHM_EDDSA; - /* TODO */ - return CKR_ATTRIBUTE_VALUE_INVALID; + ec = &args.key.u.ec; + break; case CKK_EC_MONTGOMERY: args.key.algorithm = SC_ALGORITHM_XEDDSA; - /* TODO */ - return CKR_ATTRIBUTE_VALUE_INVALID; + ec = &args.key.u.ec; + break; case CKK_EC: args.key.algorithm = SC_ALGORITHM_EC; ec = &args.key.u.ec; @@ -2414,15 +2423,21 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil case CKA_VALUE: if (key_type == CKK_GOSTR3410) bn = &gost->d; - if (key_type == CKK_EC) + else if (key_type == CKK_EC || + key_type == CKK_EC_EDWARDS || + key_type == CKK_EC_MONTGOMERY) { bn = &ec->privateD; + } break; case CKA_EC_PARAMS: ec->params.der.value = calloc(1, attr->ulValueLen); ec->params.der.len = attr->ulValueLen; rv = attr_extract(attr, ec->params.der.value, &ec->params.der.len); - if (rv != CKR_OK) + if (rv != CKR_OK) { + free(ec->params.der.value); + ec->params.der.value = NULL; goto out; + } if (sc_pkcs15_fix_ec_parameters(p11card->card->ctx, &ec->params) != SC_SUCCESS) return CKR_ATTRIBUTE_VALUE_INVALID; break; @@ -2476,9 +2491,10 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil rv = sc_to_cryptoki_error(rc, "C_CreateObject"); goto out; } - } - else if (key_type == CKK_EC) { - if (!ec->privateD.len || !ec->params.field_length) { + } else if (key_type == CKK_EC || + key_type == CKK_EC_EDWARDS || + key_type == CKK_EC_MONTGOMERY) { + if (!ec->privateD.len || !ec->params.field_length) { sc_log(context, "Template to store the EC private key is incomplete"); return CKR_TEMPLATE_INCOMPLETE; } @@ -2486,11 +2502,11 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil rc = sc_pkcs15init_store_private_key(fw_data->p15_card, profile, &args, &key_obj); /* free args now */ - if (key_type == CKK_EC) { + if (key_type == CKK_EC || + key_type == CKK_EC_EDWARDS || + key_type == CKK_EC_MONTGOMERY) { + sc_clear_ec_params(&ec->params); /* allocated above */ - free(ec->params.der.value); - /* in sc_pkcs15_fix_ec_parameters() */ - free(ec->params.named_curve); } if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); @@ -2748,9 +2764,13 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile ec = &args.key.u.ec; break; case CKK_EC_EDWARDS: + args.key.algorithm = SC_ALGORITHM_EDDSA; + ec = &args.key.u.ec; + break; case CKK_EC_MONTGOMERY: - /* TODO: -DEE Do not have real pkcs15 card with EC */ - /* fall through */ + args.key.algorithm = SC_ALGORITHM_XEDDSA; + ec = &args.key.u.ec; + break; default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -2792,17 +2812,39 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_WRAP); break; case CKA_EC_POINT: - if (key_type == CKK_EC) { + switch (key_type) { + case CKK_EC: if (sc_pkcs15_decode_pubkey_ec(p11card->card->ctx, ec, attr->pValue, attr->ulValueLen) < 0) return CKR_ATTRIBUTE_VALUE_INVALID; + break; + case CKK_EC_EDWARDS: + case CKK_EC_MONTGOMERY: + /* Difference between 25519 and 448 versions set by ec->ecpointQ.len below */ + ec->ecpointQ.value = calloc(1, attr->ulValueLen); + ec->ecpointQ.len = attr->ulValueLen; + rv = attr_extract(attr, ec->ecpointQ.value, &ec->ecpointQ.len); + if (rv != CKR_OK) { + free(ec->ecpointQ.value); + ec->ecpointQ.value = NULL; + ec->ecpointQ.len = 0; + sc_clear_ec_params(&ec->params); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + break; + + default: + return CKR_ATTRIBUTE_VALUE_INVALID; } break; case CKA_EC_PARAMS: ec->params.der.value = calloc(1, attr->ulValueLen); ec->params.der.len = attr->ulValueLen; rv = attr_extract(attr, ec->params.der.value, &ec->params.der.len); - if (rv != CKR_OK) + if (rv != CKR_OK) { + sc_clear_ec_params(&ec->params); + free(ec->params.der.value); return CKR_ATTRIBUTE_VALUE_INVALID; + } break; default: /* ignore unknown attrs, or flag error? */ @@ -2817,12 +2859,27 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } } + if (key_type == CKK_EC_EDWARDS) { + if (ec->ecpointQ.len == 32) + ec->params.id = oid_ED25519; + else + ec->params.id = oid_ED448; + } else if (key_type == CKK_EC_MONTGOMERY) { + if (ec->ecpointQ.len == 32) + ec->params.id = oid_X25519; + else + ec->params.id = oid_X448; + } + if (key_type == CKK_RSA) { if (!rsa->modulus.len || !rsa->exponent.len) return CKR_TEMPLATE_INCOMPLETE; - } - else if (key_type == CKK_EC) { - if (!ec->ecpointQ.len || !ec->params.der.value) { + } else if (key_type == CKK_EC || + key_type == CKK_EC_EDWARDS || + key_type == CKK_EC_MONTGOMERY) { + rc = sc_pkcs15_fix_ec_parameters(p11card->card->ctx, &ec->params); + + if (rc || !ec->ecpointQ.len || !ec->params.der.value) { sc_log(context, "Template to store the EC public key is incomplete"); return CKR_TEMPLATE_INCOMPLETE; } @@ -2830,13 +2887,10 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile rc = sc_pkcs15init_store_public_key(fw_data->p15_card, profile, &args, &key_obj); /* free args now */ - if (key_type == CKK_EC) { - /* allocated above */ - free(ec->params.der.value); - /* in sc_pkcs15_fix_ec_parameters() */ - free(ec->params.named_curve); - /* in sc_pkcs15_decode_pubkey_ec() */ - free(ec->ecpointQ.value); + if (key_type == CKK_EC || + key_type == CKK_EC_EDWARDS || + key_type == CKK_EC_MONTGOMERY) { + sc_clear_ec_params(&ec->params); } if (rc < 0) return sc_to_cryptoki_error(rc, "C_CreateObject"); From c52e504dbed091c0b6506f8a73bdc10054146900 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 18:24:54 -0500 Subject: [PATCH 3704/4321] pkcs15-isoApplet.c - use sc_clear_ec_params On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-isoApplet.c Revert "pkcs15-isoApplet.c - use sc_clear_ec_params" This reverts commit 29e337a51314d9026e09b42b6f3b1b9e97beef7c. Attempt to see if this is the problem. On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs15init/pkcs15-isoApplet.c From cb39ba0025107fc77284810818403ea3fa57ef85 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 16 May 2024 18:28:32 -0500 Subject: [PATCH 3705/4321] pkcs15-algo.c, pkcs15-prkey.c and pkcs15-pubkey.c Various changes for RFC8410 curves On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-algo.c modified: libopensc/pkcs15-prkey.c modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-algo.c | 17 ++++++------ src/libopensc/pkcs15-prkey.c | 3 +-- src/libopensc/pkcs15-pubkey.c | 51 ++++++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 6a130c87d4..b3ebacdfba 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -349,10 +349,10 @@ asn1_free_ec_params(void *params) static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #ifdef SC_ALGORITHM_SHA1 - /* hmacWithSHA1 */ + /* hmacWithSHA1 */ {SC_ALGORITHM_SHA1, {{1, 2, 840, 113549, 2, 7, -1}}, NULL, NULL, NULL}, {SC_ALGORITHM_SHA1, {{1, 3, 6, 1, 5, 5, 8, 1, 2, -1}}, NULL, NULL, NULL}, - /* SHA1 */ + /* SHA1 */ {SC_ALGORITHM_SHA1, {{1, 3, 14, 3, 2, 26, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_MD5 @@ -416,11 +416,11 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA1 - /* Note RFC 3279 says no ecParameters */ + /* Note RFC 3279 says no ecParameters */ {SC_ALGORITHM_ECDSA_SHA1, {{1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_ECDSA_SHA224 - /* These next 4 are defined in RFC 5758 */ + /* These next 4 are defined in RFC 5758 */ {SC_ALGORITHM_ECDSA_SHA224, {{1, 2, 840, 10045, 4, 3, 1, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, @@ -445,8 +445,8 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { asn1_free_ec_params}, #endif #ifdef SC_ALGORITHM_EDDSA - /* aka Ed25519 */ - /* RFC 8410, needed to parse/create X509 certs/pubkeys */ + /* aka Ed25519 */ + /* RFC 8410, needed to parse/create X509 certs/pubkeys */ {SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, @@ -461,8 +461,8 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { asn1_free_ec_params}, /* Ed448 */ #endif #ifdef SC_ALGORITHM_XEDDSA - /* aka curve25519 */ - /* RFC 8410, needed to parse/create X509 certs/pubkeys ec_parms*/ + /* aka curve25519 */ + /* RFC 8410, needed to parse/create X509 certs/pubkeys ec_parms*/ {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, asn1_decode_ec_params, asn1_encode_ec_params, @@ -574,6 +574,7 @@ sc_asn1_encode_algorithm_id(struct sc_context *ctx, u8 **buf, size_t *len, /* no parameters, write NULL tag */ /* If it's EDDSA/XEDDSA, according to RFC8410, params * MUST be absent */ + /* PKCS11 3.0 list them under ec_params */ if (id->algorithm != SC_ALGORITHM_EDDSA && id->algorithm != SC_ALGORITHM_XEDDSA && (!id->params || !alg_info->encode)) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 9a358f24ab..6244261d90 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -573,8 +573,7 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key) case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: /* EC, Edwards and Montgomery use common ec params */ - free(key->u.ec.params.der.value); - free(key->u.ec.params.named_curve); + sc_clear_ec_params(&key->u.ec.params); free(key->u.ec.privateD.data); free(key->u.ec.ecpointQ.value); break; diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index cdce990f5b..7ed40de2f3 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -545,6 +545,14 @@ static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; + +/* See RFC8410 */ +#define C_ASN1_EDDSA_PUBKEY_SIZE 3 +static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = { + { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; // clang-format on int @@ -676,7 +684,7 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; size_t key_len; - volatile int gdb_test = 0; /* so can reset via gdb for testing new way */ + volatile int gdb_test = 1; /* so can reset via gdb for testing new way */ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); @@ -725,15 +733,18 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } -/* - * all "ec" keys uses same pubkey format, keep this external entrypoint - */ int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { - /* same format */ - return sc_pkcs15_encode_pubkey_ec(ctx, key, buf, buflen); + struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; + + LOG_FUNC_CALLED(ctx); + sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); + sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->ecpointQ.value, &key->ecpointQ.len, 1); + + LOG_FUNC_RETURN(ctx, + sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); } int @@ -1109,6 +1120,12 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc memcpy(pubkey->u.ec.ecpointQ.value, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len); pubkey->u.ec.ecpointQ.len = key->u.ec.ecpointQ.len; + if (key->u.ec.params.named_curve) { + rv = sc_pkcs15_fix_ec_parameters(ctx, &key->u.ec.params); + if (rv) + break; + } + pubkey->u.ec.params.der.value = malloc(key->u.ec.params.der.len); if (!pubkey->u.ec.params.der.value) { rv = SC_ERROR_OUT_OF_MEMORY; @@ -1117,14 +1134,16 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc memcpy(pubkey->u.ec.params.der.value, key->u.ec.params.der.value, key->u.ec.params.der.len); pubkey->u.ec.params.der.len = key->u.ec.params.der.len; - if (key->u.ec.params.named_curve){ - pubkey->u.ec.params.named_curve = strdup(key->u.ec.params.named_curve); - if (!pubkey->u.ec.params.named_curve) - rv = SC_ERROR_OUT_OF_MEMORY; - } - else { - sc_log(ctx, "named_curve parameter missing"); - rv = SC_ERROR_NOT_SUPPORTED; + /* RFC4810 no named_curve */ + if ((key->algorithm != SC_ALGORITHM_EDDSA) && (key->algorithm != SC_ALGORITHM_XEDDSA)) { + if (key->u.ec.params.named_curve) { + pubkey->u.ec.params.named_curve = strdup(key->u.ec.params.named_curve); + if (!pubkey->u.ec.params.named_curve) + rv = SC_ERROR_OUT_OF_MEMORY; + } else { + sc_log(ctx, "named_curve parameter missing"); + rv = SC_ERROR_NOT_SUPPORTED; + } } break; @@ -1581,7 +1600,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp ecparams->field_length = ec_curve_infos[ii].size; ecparams->key_type = ec_curve_infos[ii].key_type; - sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u key_type %d", + sc_log(ctx, "Curve length %" SC_FORMAT_LEN_SIZE_T "u key_type %d", ecparams->field_length, ecparams->key_type); if (mapped_string) { /* replace the printable string version with the oid */ @@ -1613,7 +1632,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp ecparams->field_length = ec_curve_infos[ii].size; ecparams->key_type = ec_curve_infos[ii].key_type; - sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u key_type %d", + sc_log(ctx, "Curve length %" SC_FORMAT_LEN_SIZE_T "u key_type %d", ecparams->field_length, ecparams->key_type); if (!ecparams->der.value || !ecparams->der.len) { From a975c3b051b9ced5d5f370ad601fca9fdf2dd529 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 22 Aug 2024 13:45:23 -0500 Subject: [PATCH 3706/4321] pkcs15-pubkey.c - fix SPKI decoding of EDDSA and XEDDSA EDDSA and XEDDSA public keys have a OID but no params unlike EC that has EC OID and params have the OID of the curve. EDDSA has two sub curves 25519 and 448 as does XEDDSA. The OID in the pubkey is then mapped to a ec-curve by and sc_pkcs15_fix_ec_parameters get the size of the curve. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 7ed40de2f3..0f9843cbcd 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -738,10 +738,12 @@ sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; + size_t key_len; LOG_FUNC_CALLED(ctx); + key_len = key->ecpointQ.len * 8; /* in bits */ sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->ecpointQ.value, &key->ecpointQ.len, 1); + sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->ecpointQ.value, &key_len, 1); LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); @@ -1390,7 +1392,16 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke pubkey->u.ec.ecpointQ.len = pk.len; } else if (pk_alg.algorithm == SC_ALGORITHM_EDDSA || pk_alg.algorithm == SC_ALGORITHM_XEDDSA) { - /* EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING */ + /* + * SPKI will have OID, EDDSA can have ED25519 or ED448 with different sizes + * EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING + * no params, but oid is the params. + */ + r = sc_encode_oid(ctx, &pk_alg.oid, &pubkey->u.ec.params.der.value, &pubkey->u.ec.params.der.len); + LOG_TEST_GOTO_ERR(ctx, r, "failed to encode (X)EDDSA oid"); + r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); + LOG_TEST_GOTO_ERR(ctx, r, "failed to fix EC parameters"); + pubkey->u.ec.ecpointQ.value = malloc(pk.len); memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len); pubkey->u.ec.ecpointQ.len = pk.len; From 8da7a56cafd4585ccc0c387b99cea6a5ec009c87 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 22 Aug 2024 14:01:38 -0500 Subject: [PATCH 3707/4321] pkcs15-sec.c - fix caculations of dignature size for EDDSA and XEDDSA On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-sec.c --- src/libopensc/pkcs15-sec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 0b06764574..bcf93670df 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -630,6 +630,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, modlen = BYTES4BITS(prkey->modulus_length) * 2; break; case SC_PKCS15_TYPE_PRKEY_EC: + modlen = ((prkey->field_length + 7) / 8) * 2; /* 2*nLen */ + break; case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: modlen = BYTES4BITS(prkey->field_length) * 2; /* 2*nLen */ From ec2c3bdbe12280ec4fcc47560acda3daeee7d171 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 14 Aug 2024 19:08:28 -0500 Subject: [PATCH 3708/4321] card-piv.c,pkcs15-piv.c,piv-tool.c - Support for RSA 4096 and 25519 Yubikey with firmware >= 5.7 supports RSA 4096, and EDDSA and XEDDSA which is non standard PIV. WIP Only tested with 9A key and self signed certificate created by Yubic-piv-tool. Signature created with: ./pkcs11-tool -m EDDSA --login --sign --id 01 --input-file /tmp/data.txt --output-file /tmp/YK11-9A-signature.der and signature verified via openssl 3.3.1 ./openssl pkeyutl -verify -pubin -inkey /tmp/YK11-9A-pub.pem -rawin -in /tmp/data.txt -sigfile /tmp/YK11-9A-signature.der On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-piv.c modified: libopensc/pkcs15-piv.c modified: tools/piv-tool.c --- src/libopensc/card-piv.c | 85 ++++++++++++++++++++++++++++++++------ src/libopensc/pkcs15-piv.c | 27 ++++++++++-- src/tools/piv-tool.c | 29 +++++++++++++ 3 files changed, 125 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 573d0bae5b..e16e1b7b96 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3,7 +3,7 @@ * card-default.c: Support for cards with no driver * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2005-2023 Douglas E. Engert + * Copyright (C) 2005-2024 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner * @@ -39,7 +39,7 @@ #endif #ifdef ENABLE_OPENSSL - /* openssl needed for card administration and SM */ +/* openssl needed for card administration and SM */ #include #include #include @@ -544,10 +544,13 @@ static const struct sc_atr_table piv_atrs[] = { static struct piv_supported_ec_curves { struct sc_object_id oid; size_t size; + unsigned int key_type; } ec_curves[] = { - {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */ - {{{1, 3, 132, 0, 34, -1}}, 384}, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */ - {{{-1}}, 0} /* This entry must not be touched. */ + {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC }, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */ + {{{1, 3, 132, 0, 34, -1}}, 384, SC_ALGORITHM_EC }, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */ + {{{1, 3, 101, 112, -1}}, 255, SC_ALGORITHM_EDDSA }, /* RFC8410 OID equivalent to ed25519 */ + {{{1, 3, 101, 110, -1}}, 255, SC_ALGORITHM_XEDDSA}, /* RFC8410 OID equivalent to curve25519 */ + {{{-1}}, 0, 0 } /* This entry must not be touched. */ }; /* all have same AID */ @@ -573,6 +576,8 @@ static struct piv_aid piv_aids[] = { #define CI_NO_RSA2048 0x00010000U /* does not have RSA 2048 */ #define CI_NO_EC384 0x00020000U /* does not have EC 384 */ #define CI_NO_EC 0x00040000U /* No EC at all */ +#define CI_RSA_4096 0x00080000U /* Card supports rsa 4096 */ +#define CI_25519 0x00100000U /* Card supports ED25519 and X25519 */ /* * Flags in the piv_object: @@ -2720,14 +2725,23 @@ static int piv_generate_key(sc_card_t *card, case 0x05: keydata->key_bits = 3072; break; case 0x06: keydata->key_bits = 1024; break; case 0x07: keydata->key_bits = 2048; break; + case 0x16: + keydata->key_bits = 4096; + break; case 0x11: keydata->key_bits = 0; - keydata->ecparam = 0; /* we only support prime256v1 for 11 */ + keydata->ecparam = 0; /* we only support prime256v1 */ keydata->ecparam_len =0; break; case 0x14: keydata->key_bits = 0; keydata->ecparam = 0; /* we only support secp384r1 */ keydata->ecparam_len = 0; break; + case 0xE0: + case 0xE1: + keydata->key_bits = 0; + keydata->ecparam = 0; + keydata->ecparam_len = 0; + break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2780,8 +2794,11 @@ static int piv_generate_key(sc_card_t *card, keydata->pubkey_len = taglen; memcpy (keydata->pubkey, tag, taglen); } - } - else { /* must be EC */ + // } else if (keydata->key_algid == 0xE0 || keydata->key_algid == 0xE1) { + // /* TODO DEE need to look at what gets returned */ + /* TODO assume same as EC with tag 86 */ + + } else { /* must be EC */ tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x86, &taglen); if (tag != NULL && taglen > 0) { keydata->ecpoint = malloc(taglen); @@ -2793,7 +2810,8 @@ static int piv_generate_key(sc_card_t *card, } /* TODO: -DEE Could add key to cache so could use engine to generate key, - * and sign req in single operation */ + * and sign req in single operation or write temporary selfsigned + * certificate with new public key */ r = 0; } @@ -4512,6 +4530,12 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) } } else r = SC_ERROR_NO_CARD_SUPPORT; + } else if (env->algorithm == SC_ALGORITHM_EDDSA) { + priv->alg_id = 0xE0; + priv->key_size = 255; + } else if (env->algorithm == SC_ALGORITHM_XEDDSA) { + priv->alg_id = 0xE1; + priv->key_size = 255; } else r = SC_ERROR_NO_CARD_SUPPORT; priv->key_ref = env->key_ref[0]; @@ -4541,6 +4565,7 @@ static int piv_validate_general_authentication(sc_card_t *card, unsigned int cla, tag; unsigned int real_alg_id, op_tag; + /* TODO check for 4096 keys */ u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ size_t sbuflen = sizeof(sbuf); u8 rbuf[4096]; @@ -4561,6 +4586,7 @@ static int piv_validate_general_authentication(sc_card_t *card, } if (priv->operation == SC_SEC_OPERATION_DERIVE && priv->algorithm == SC_ALGORITHM_EC) { + /* TODO add code for X25519 */ op_tag = 0x85; } else { op_tag = 0x81; @@ -4583,11 +4609,14 @@ static int piv_validate_general_authentication(sc_card_t *card, case 128: real_alg_id = 0x06; break; case 256: real_alg_id = 0x07; break; case 384: real_alg_id = 0x05; break; + case 512: + real_alg_id = 0x16; + break; default: SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); } } - /* EC alg_id was already set */ + /* EC and ED alg_id was already set */ r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf); @@ -4649,6 +4678,18 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, goto err; r = sc_asn1_decode_ecdsa_signature(card->ctx, rbuf, r, nLen, &out, outlen); + /* Yubikey 5.7.x supports ED25519 */ + } else if (priv->alg_id == 0xE0) { + nLen = (priv->key_size + 7) / 8; + if (outlen < nLen) { + sc_log(card->ctx, + " output too small for ED signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u", + outlen, nLen); + r = SC_ERROR_INVALID_DATA; + goto err; + } + r = piv_validate_general_authentication(card, data, datalen, out, outlen); + } else { /* RSA is all set */ r = piv_validate_general_authentication(card, data, datalen, out, outlen); } @@ -5500,7 +5541,7 @@ static int piv_match_card_continued(sc_card_t *card) apdu.resplen = sizeof(yubico_version_buf); apdu.le = apdu.resplen; r2 = sc_transmit_apdu(card, &apdu); /* on error yubico_version == 0 */ - if (r2 >= 3) { + if (apdu.resplen == 3) { priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); } @@ -5615,6 +5656,9 @@ static int piv_match_card_continued(sc_card_t *card) | CI_LEAKS_FILE_NOT_FOUND; if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; + /* TODO may need to relocate when I get card to test */ + if (priv->yubico_version >= 0x00050700) + priv->card_issues |= CI_RSA_4096 | CI_25519; break; case SC_CARD_TYPE_PIV_II_GI_DE: @@ -5698,6 +5742,8 @@ static int piv_init(sc_card_t *card) int r = 0; piv_private_data_t * priv = PIV_DATA(card); unsigned long flags; + unsigned long flags_eddsa; + unsigned long flags_xeddsa; unsigned long ext_flags; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -5746,15 +5792,28 @@ static int piv_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ + if (priv->card_issues & CI_RSA_4096) + _sc_card_add_rsa_alg(card, 4096, flags, 0); /* some Yubikeys support this */ if (!(priv->card_issues & CI_NO_EC)) { int i; flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + flags_eddsa = SC_ALGORITHM_EDDSA_RAW; + flags_xeddsa = SC_ALGORITHM_XEDDSA_RAW; for (i = 0; ec_curves[i].oid.value[0] >= 0; i++) { - if (!(priv->card_issues & CI_NO_EC384 && ec_curves[i].size == 384)) - _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid); + if (ec_curves[i].key_type == SC_ALGORITHM_EC) { + if (!(priv->card_issues & CI_NO_EC384 && ec_curves[i].size == 384)) + _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid); + + } else if (priv->card_issues & CI_25519) { + if (ec_curves[i].key_type == SC_ALGORITHM_EDDSA) { + _sc_card_add_eddsa_alg(card, ec_curves[i].size, flags_eddsa, ext_flags, &ec_curves[i].oid); + } else if (ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) { + _sc_card_add_xeddsa_alg(card, ec_curves[i].size, flags_xeddsa, ext_flags, &ec_curves[i].oid); + } + } } } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index fad10899e1..9c2689bb86 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -900,6 +900,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: ckis[i].pubkey_len = cert_out->key->u.ec.params.field_length; if (ckis[i].cert_keyUsage_present) { if (ckis[i].cert_keyUsage & SC_X509_DIGITAL_SIGNATURE) { @@ -1099,7 +1101,9 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) ckis[i].pubkey_from_file = 1; break; case SC_ALGORITHM_EC: - ckis[i].key_alg = SC_ALGORITHM_EC; + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: + ckis[i].key_alg = p15_key->algorithm; ckis[i].pubkey_len = p15_key->u.ec.params.field_length; ckis[i].pubkey_found = 1; ckis[i].pubkey_from_file = 1; @@ -1138,6 +1142,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) ckis[i].pubkey_found = 1; break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: if (ckis[i].cert_keyUsage_present) { pubkey_info.usage = ckis[i].pub_usage; } else { @@ -1148,7 +1154,14 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); /* should not fail */ - r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); + + if (ckis[i].key_alg == SC_ALGORITHM_EDDSA) + r = sc_pkcs15emu_add_eddsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA) + r = sc_pkcs15emu_add_xeddsa_pubkey(p15card, &pubkey_obj, &pubkey_info); + else + r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add EC pubkey"); ckis[i].pubkey_found = 1; @@ -1219,6 +1232,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); break; case SC_ALGORITHM_EC: + case SC_ALGORITHM_EDDSA: + case SC_ALGORITHM_XEDDSA: if (ckis[i].cert_keyUsage_present) { prkey_info.usage |= ckis[i].priv_usage; /* If retired key and non gov cert has NONREPUDIATION, treat as user_consent */ @@ -1231,7 +1246,13 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) prkey_info.field_length = ckis[i].pubkey_len; sc_log(card->ctx, "DEE added key_alg %2.2lx prkey_obj.flags %8.8x", ckis[i].key_alg, prkey_obj.flags); - r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + + if (ckis[i].key_alg == SC_ALGORITHM_EDDSA) + r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info); + else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA) + r = sc_pkcs15emu_add_xeddsa_prkey(p15card, &prkey_obj, &prkey_info); + else + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); break; default: sc_log(card->ctx, "Unsupported key_alg %lu", ckis[i].key_alg); diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b9e3d4a5c3..9c5218a8b8 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -320,6 +320,14 @@ static int gen_key(const char * key_info) case 0x14: keydata.key_bits = 0; nid = NID_secp384r1; break; + case 0xE0: + keydata.key_bits = 0; + nid = NID_ED25519; + break; + case 0xE1: + keydata.key_bits = 0; + nid = NID_X25519; + break; #endif default: fprintf(stderr, ": algid=RSA - 05, 06, 07 for 3072, 1024, 2048;EC - 11, 14 for 256, 384\n"); @@ -443,6 +451,27 @@ static int gen_key(const char * key_info) EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); #endif + +#ifdef EVP_PKEY_ED25519 + } else if (nid == NID_ED25519 || nid == NID_X25519) { +#if OPENSSL_VERSION_NUMBER < 0x30000000L + fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n"); + return -1; +#else + evpkey = EVP_PKEY_new_raw_public_key(nid, NULL, keydata.ecpoint, keydata.ecpoint_len); + if (!evpkey) { + sc_log_openssl(ctx); + fprintf(stderr, "gen key failed ti copy 25519 pubkey\n"); + return -1; + } + + if (verbose) + EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); +#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ +#else + fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n"); + return -1; +#endif /* EVP_PKEY_ED25519 */ } else { /* EC key */ #if !defined(OPENSSL_NO_EC) int i; From 91fa8b43b60605bebbaa5538d4d23c1af30bc52c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 26 Aug 2024 16:09:53 -0500 Subject: [PATCH 3709/4321] pkcs15-pubkey.c explain problem with EC pubkeys as OCTET STRING vs BIT STRING On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 0f9843cbcd..5e09a244c6 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -537,7 +537,7 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_P { NULL, 0, 0, 0, NULL, NULL } }; -/* older incorrect implementation may have encoded as OCTET STRING */ +/* PKCS15 raw uses OCTET STRING, SPKI uses BIT STRING */ /* accept either */ #define C_ASN1_EC_POINTQ_SIZE 3 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { @@ -684,7 +684,17 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; size_t key_len; - volatile int gdb_test = 1; /* so can reset via gdb for testing new way */ + /* + * PKCS15 uses RAW vs SPKI for pub key, and in raw uses OCTET STRING + * PKCS11 does not define CKA_VALUE for a pub key + * But some PKCS11 modules define a CKA_VALUE for a public key + * and PKCS11 says ECPOINT is encoded as "DER-encoding of ANSI X9.62 ECPoint value Q" + * But ANSI X9.62 (early draft at least) says encode as BIT STRING + * IETF encodes in SubjectPublicKeyInfo (SPKI) in BIT STRING + * PKCS11 V3 does add CKA_PUBLIC_KEY_INFO as SPKI + * For now return as OCTET STRING. + */ + volatile int gdb_test = 0; /* 0 - OCTET STRING (PKCS15 RAW) 1 - BIT STRING (SPKI) */ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); From f414eabffbdcccd308b035461b22caeea28e9326 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 27 Aug 2024 08:05:16 -0500 Subject: [PATCH 3710/4321] pkcs15-pubkey.c - return EC_POINT as OCTET STRING by default Removes changes that would have returned EC_POINT as BIT_STRING OpenSC has should be using BIT_STRING, as per standards. See: https://github.com/OpenSC/OpenSC/issues/3000 Solutions include: * Define new PKCS11 vendor attribute to CKA_EC_POINT_OCTET_STRING for backwards compatability. but only good with OpenSC PKCA11 module. * Environment variable. * The use of the PKCS11 V3 defines CKA_PUBLIC_KEY_INFO (which is implemented in this PR) should be encouraged. * Some how in pkcs11-tool.c determine what module cand do. The only use of sc_pkcs15_encode_pubkey_eddsa is when creating a key So it defaults to returning a BIT STRING All the routines that accept as input an EC_POINT will accept it either OCTET_STRING or BIT_STRING. Note SPKI already uses BIT_STRING. Correct decoding of length of ec_pointQ Changes to be committed: modified: src/libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 39 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 5e09a244c6..072dbec7b6 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -541,16 +541,16 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_P /* accept either */ #define C_ASN1_EC_POINTQ_SIZE 3 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = { - { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-BS", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; /* See RFC8410 */ #define C_ASN1_EDDSA_PUBKEY_SIZE 3 static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = { - { "ecpointQ", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { "ecpointQ-OS", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { "ecpointQ-BS", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; // clang-format on @@ -657,14 +657,20 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); - sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 1); + sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 0); + sc_format_asn1_entry(asn1_ec_pointQ + 1, &ecpoint_data, &ecpoint_len, 0); r = sc_asn1_decode_choice(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); if (r < 0 || ecpoint_len == 0 || ecpoint_data == NULL) { free(ecpoint_data); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ecpoint_len:%" SC_FORMAT_LEN_SIZE_T "u", ecpoint_len); + /* if from bit string */ + if (asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) + ecpoint_len = (ecpoint_len + 7) / 8; /* bits to bytes */ + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ecpoint_len:%" SC_FORMAT_LEN_SIZE_T "u", ecpoint_len); + if (*ecpoint_data != 0x04) { free(ecpoint_data); LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value"); @@ -687,10 +693,10 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, /* * PKCS15 uses RAW vs SPKI for pub key, and in raw uses OCTET STRING * PKCS11 does not define CKA_VALUE for a pub key - * But some PKCS11 modules define a CKA_VALUE for a public key - * and PKCS11 says ECPOINT is encoded as "DER-encoding of ANSI X9.62 ECPoint value Q" + * But some PKCS11 modules define a CKA_VALUE for a public key + * and PKCS11 says ECPOINT is encoded as "DER-encoding of ANSI X9.62 ECPoint value Q" * But ANSI X9.62 (early draft at least) says encode as BIT STRING - * IETF encodes in SubjectPublicKeyInfo (SPKI) in BIT STRING + * IETF encodes it in SubjectPublicKeyInfo (SPKI) in BIT STRING * PKCS11 V3 does add CKA_PUBLIC_KEY_INFO as SPKI * For now return as OCTET STRING. */ @@ -699,11 +705,11 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - if (gdb_test == 1) { - key_len = key->ecpointQ.len * 8; /* encode in bit string */ + if (gdb_test == 0) { + key_len = key->ecpointQ.len; sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); } else { - key_len = key->ecpointQ.len; + key_len = key->ecpointQ.len * 8; /* encode in bit string */ sc_format_asn1_entry(asn1_ec_pointQ + 1, key->ecpointQ.value, &key_len, 1); } @@ -736,6 +742,9 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } + if (asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) + ecpoint_len = (ecpoint_len + 7) / 8; + key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; key->params.field_length = ecpoint_len * 8; @@ -743,6 +752,9 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } +/* This is a change from previous code that used OCTET STRING + * But RFC 8410 and PKCS11 use BITSTRING. + */ int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) @@ -753,7 +765,7 @@ sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key LOG_FUNC_CALLED(ctx); key_len = key->ecpointQ.len * 8; /* in bits */ sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->ecpointQ.value, &key_len, 1); + sc_format_asn1_entry(asn1_eddsa_pubkey + 1, key->ecpointQ.value, &key_len, 1); LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); @@ -1402,8 +1414,8 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke pubkey->u.ec.ecpointQ.len = pk.len; } else if (pk_alg.algorithm == SC_ALGORITHM_EDDSA || pk_alg.algorithm == SC_ALGORITHM_XEDDSA) { - /* - * SPKI will have OID, EDDSA can have ED25519 or ED448 with different sizes + /* + * SPKI will have OID, EDDSA can have ED25519 or ED448 with different sizes * EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING * no params, but oid is the params. */ @@ -1659,6 +1671,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp if (!ecparams->der.value || !ecparams->der.len) { free(ecparams->der.value); /* just in case */ ecparams->der.value = NULL; + ecparams->der.len = 0; /* if caller did not provide der OID, fill in */ rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len); LOG_TEST_RET(ctx, rv, "Cannot encode object ID"); From 118a11eff1790e256c55d4bd94cefa5eca3d809a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 27 Aug 2024 13:18:15 -0500 Subject: [PATCH 3711/4321] pkcs15init/pkcs15-lib.c - Fix memory leak On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 09a32f6f15..e83cf04827 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2026,7 +2026,9 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile LOG_TEST_GOTO_ERR(ctx, r, "SPKI encode public key error"); /* Now create key file and store key */ - if (type == SC_PKCS15_TYPE_PUBKEY_EC) + if (type == SC_PKCS15_TYPE_PUBKEY_EC || + type == SC_PKCS15_TYPE_PUBKEY_EDDSA || + type == SC_PKCS15_TYPE_PUBKEY_XEDDSA) r = sc_pkcs15init_store_data(p15card, profile, object, &key_info->direct.spki, &key_info->path); else r = sc_pkcs15init_store_data(p15card, profile, object, &object->content, &key_info->path); @@ -2050,6 +2052,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile err: sc_pkcs15_erase_pubkey(&key); + sc_clear_ec_params(&keyargs->key.u.ec.params); sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } From 1c48cd62a3c262178932860b021ccf5d5a0cfcdb Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 28 Aug 2024 08:20:59 -0500 Subject: [PATCH 3712/4321] pkcs15-init.c - fix memory leak or RSA exponent On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 9d924b2bb0..26b0833316 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1258,6 +1258,7 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey) sc_pkcs15_erase_pubkey(&(args.key)); sc_unlock(g_p15card->card); } + sc_pkcs15_erase_pubkey(&(args.key)); return r; } From 1e9f821b8d4b2526dff4f2b8828d5d23c63782b6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 29 Aug 2024 15:11:33 -0500 Subject: [PATCH 3713/4321] pkcs15-openpgp.c - clear pointers just in case Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/libopensc/card-openpgp.c | 6 +++--- src/pkcs15init/pkcs15-openpgp.c | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fb7c793387..5633ad81c3 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3032,7 +3032,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, } /* FIXME is this redundant? */ - if (key_info->u.ec.ecpoint == NULL || len != BYTES4BITS(key_info->u.ec.ecpoint_len)) { + if (key_info->u.ec.ecpoint == NULL || len != BYTES4BITS(key_info->u.ec.ecpoint_len)) { free(key_info->u.ec.ecpoint); key_info->u.ec.ecpoint = malloc(len); if (key_info->u.ec.ecpoint == NULL) @@ -3487,11 +3487,11 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(card->ctx); - /* PKCS11 loads privkey separately from pubkey as two different operations + /* PKCS11 loads privkey separately from pubkey as two different operations * So this routine will be called twice to create two different objects. * pkcs15init only calls once, with both. * OpenPGP 4.3.1 says modulus and ecpointQ are optional when - * creating the extended header. + * creating the extended header. * So we can tell the difference and only do appropriate parts of this * routine. */ diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 5a767fd41c..4b4cc541ba 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -248,7 +248,9 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, err: free(key_info.u.rsa.modulus); + key_info.u.rsa.modulus = NULL; free(key_info.u.rsa.exponent); + key_info.u.rsa.exponent = NULL; LOG_FUNC_RETURN(ctx, r); } From d5edb9624090c83edaf4b3557aabd4215c3505f7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 29 Aug 2024 15:08:44 -0500 Subject: [PATCH 3714/4321] pkcs15-lib.c - various fixes Log how usage was determined. Use sc_copy_ec_params and sc_clear_ec_params Avoid memory leak, fix comments Changes to be committed: modified: pkcs15-lib.c --- src/pkcs15init/pkcs15-lib.c | 43 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e83cf04827..fa5d38eca7 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1311,17 +1311,8 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof r = SC_ERROR_OUT_OF_MEMORY; LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); } - /* copy ecparams into allocated one - * it will be freed with the corresponding object */ - memcpy(new_ecparams, ecparams, sizeof(struct sc_ec_parameters)); - - new_ecparams->named_curve = strdup(ecparams->named_curve); - new_ecparams->der.value = malloc(ecparams->der.len); - if (!new_ecparams->named_curve || !new_ecparams->der.value) { - r = SC_ERROR_OUT_OF_MEMORY; - LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate memory for EC parameters"); - } - memcpy(new_ecparams->der.value, ecparams->der.value, ecparams->der.len); + r = sc_copy_ec_params(new_ecparams, &keyargs->key.u.ec.params); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot copy EC parameters"); key_info->params.data = new_ecparams; key_info->params.free_params = sc_pkcs15init_free_ec_params; @@ -1362,8 +1353,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof err: if (new_ecparams) { - free(new_ecparams->named_curve); - free(new_ecparams->der.value); + sc_clear_ec_params(new_ecparams); free(new_ecparams); key_info->params.data = NULL; } @@ -1550,7 +1540,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr r = check_keygen_params_consistency(p15card->card, algorithm, &keygen_args->prkey_args, &keybits); - LOG_TEST_RET(ctx, r, "Invalid key size"); + LOG_TEST_GOTO_ERR(ctx, r, "Invalid key size"); if (check_key_compatibility(p15card, algorithm, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, @@ -1914,14 +1904,6 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile r = sc_pkcs15_fix_ec_parameters(ctx, &key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Failed to fix EC public key parameters"); - if (keyargs->key.u.ec.ecpointQ.value) { - key.u.ec.ecpointQ.value = malloc(keyargs->key.u.ec.ecpointQ.len); - if (!key.u.ec.ecpointQ.value) { - r = SC_ERROR_OUT_OF_MEMORY; - LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy EC... public key parameters"); - } - } - if (key.algorithm == SC_ALGORITHM_EC) type = SC_PKCS15_TYPE_PUBKEY_EC; else if (key.algorithm == SC_ALGORITHM_EDDSA) @@ -1937,10 +1919,15 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile } if ((usage = keyargs->usage) == 0) { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting default usage to verify"); usage = SC_PKCS15_PRKEY_USAGE_VERIFY; - if (keyargs->x509_usage) + if (keyargs->x509_usage) { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting usage from keyargs->x509_usage"); usage = sc_pkcs15init_map_usage(keyargs->x509_usage, 0); + } } + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Usage: 0x%X", usage); + label = keyargs->label; if (!label) label = "Public Key"; @@ -1972,8 +1959,13 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile } else if (key.algorithm == SC_ALGORITHM_EC || key.algorithm == SC_ALGORITHM_EDDSA || key.algorithm == SC_ALGORITHM_XEDDSA) { - /* TODO if EC don't write the 0x04 byte to card */ key_info->field_length = keybits; + /* only SC_ALGORITHM_EC has ec_params with the EC curveName OID + * that becomes part of the SPKI algo params. + * EDDSA and XEDDSA ec_params have the OID of the EDDSA or XEDDSA + * which is used as the alg OID. But we still copy here + * as the asn1 routines will do the right thing based on key.algorithm. + */ if (key.u.ec.params.der.value) { key_info->params.data = malloc(key.u.ec.params.der.len); if (!key_info->params.data) { @@ -1987,7 +1979,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile key.u.ec.ecpointQ.value = malloc(keyargs->key.u.ec.ecpointQ.len); if (!key.u.ec.ecpointQ.value) { r = SC_ERROR_OUT_OF_MEMORY; - LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC params"); + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC public key"); } key.u.ec.ecpointQ.len = keyargs->key.u.ec.ecpointQ.len; memcpy(key.u.ec.ecpointQ.value, keyargs->key.u.ec.ecpointQ.value, key.u.ec.ecpointQ.len); @@ -2052,7 +2044,6 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile err: sc_pkcs15_erase_pubkey(&key); - sc_clear_ec_params(&keyargs->key.u.ec.params); sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } From a01821a8f1c6a831978e588a1cf2c42f56a20ac4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 6 Sep 2024 14:18:30 -0500 Subject: [PATCH 3715/4321] opensc.supp and pkcs11-spy.c - Suppress memory leak error with github tests SPY does not cleanup the function lists, assuming the module will not be unloaded, but when valgrind is run from github actions, this will cause the tests to fail. The real solution could include some atexit routine to cleanup the finction lists. Changes to pkcs11-spy.c in this commit try to make sure if function lists are freed there is no double free. On branch X25519-improvements-2 Changes to be committed: modified: ../src/pkcs11/pkcs11-spy.c modified: opensc.supp --- src/pkcs11/pkcs11-spy.c | 5 +++++ tests/opensc.supp | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index a8f8303875..98ab07b65c 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -211,6 +211,7 @@ init_spy(void) pkcs11_spy_3_0 = allocate_function_list(1); if (pkcs11_spy_3_0 == NULL) { free(pkcs11_spy); + pkcs11_spy = NULL; return CKR_HOST_MEMORY; } @@ -295,6 +296,9 @@ init_spy(void) if (module == NULL) { fprintf(spy_output, "Error: no module specified. Please set PKCS11SPY environment.\n"); free(pkcs11_spy); + pkcs11_spy = NULL; + free(pkcs11_spy_3_0); + pkcs11_spy_3_0 = NULL; return CKR_DEVICE_ERROR; } modhandle = C_LoadModule(module, &po_v2); @@ -305,6 +309,7 @@ init_spy(void) else { po = NULL; free(pkcs11_spy); + free(pkcs11_spy_3_0); rv = CKR_GENERAL_ERROR; } diff --git a/tests/opensc.supp b/tests/opensc.supp index bf6bb9b2f9..46cd2e1d45 100644 --- a/tests/opensc.supp +++ b/tests/opensc.supp @@ -75,3 +75,25 @@ fun:_cmocka_run_group_tests fun:main } +{ + OpenSC SPY does not cleanup the function_lists + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:allocate_function_list + fun:init_spy + fun:C_GetInterface + fun:C_LoadModule + fun:main +} +{ + OpenSC SPY does not cleanup Interfaces + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:C_LoadModule + fun:init_spy + fun:C_GetInterface + fun:C_LoadModule + fun:main +} From 52065876e0e0ceb25756b697b764816affeefe1b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 6 Sep 2024 15:26:59 -0500 Subject: [PATCH 3716/4321] framework-pkcs15.c - fix memory leak On branch X25519-improvements-2 Changes to be committed: modified: pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index b4c062c5ad..3365396e4e 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2814,11 +2814,18 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile case CKA_EC_POINT: switch (key_type) { case CKK_EC: - if (sc_pkcs15_decode_pubkey_ec(p11card->card->ctx, ec, attr->pValue, attr->ulValueLen) < 0) + if (sc_pkcs15_decode_pubkey_ec(p11card->card->ctx, ec, attr->pValue, attr->ulValueLen) < 0) { + free(ec->ecpointQ.value); + ec->ecpointQ.value = NULL; + ec->ecpointQ.len = 0; + sc_clear_ec_params(&ec->params); return CKR_ATTRIBUTE_VALUE_INVALID; + } + break; case CKK_EC_EDWARDS: case CKK_EC_MONTGOMERY: + /* TODO my need to decode here too to support OS vs BS */ /* Difference between 25519 and 448 versions set by ec->ecpointQ.len below */ ec->ecpointQ.value = calloc(1, attr->ulValueLen); ec->ecpointQ.len = attr->ulValueLen; @@ -2891,6 +2898,7 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile key_type == CKK_EC_EDWARDS || key_type == CKK_EC_MONTGOMERY) { sc_clear_ec_params(&ec->params); + free(ec->ecpointQ.value); } if (rc < 0) return sc_to_cryptoki_error(rc, "C_CreateObject"); From c43f01d6680dc790b3dd8557e64a80ca236026cd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 7 Sep 2024 12:18:35 -0500 Subject: [PATCH 3717/4321] fuzz_pkcs15init.c, framework-pkcs15.c, minidriver.c - erase keygen_args The caller of sc_pkcs15init_generate_key needs to clear the keygen_args when done. pkcs15-tool.c already does. framework-pkcs15.c - test for 56 bytes for ED448 and X448 framework-pkcs15.c - verify ec parameters before key generation Verify the CKA_EC_PARAMS provided are supported by OpenSC and set the keygen_args.prkey_args.key.u.ec.params On branch X25519-improvements-2 Changes to be committed: modified: minidriver/minidriver.c modified: pkcs11/framework-pkcs15.c modified: tests/fuzzing/fuzz_pkcs15init.c --- src/minidriver/minidriver.c | 1 + src/pkcs11/framework-pkcs15.c | 23 ++++++++++++++++------- src/tests/fuzzing/fuzz_pkcs15init.c | 4 ++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 92dcceac37..c378270907 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2552,6 +2552,7 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke keygen_args.pubkey_label = keygen_args.prkey_args.label; rv = sc_pkcs15init_generate_key(vs->p15card, profile, &keygen_args, key_size, &cont->prkey_obj); + sc_pkcs15_erase_prkey(&keygen_args.prkey_args.key); if (rv < 0) { logprintf(pCardData, 3, "MdGenerateKey(): key generation failed: sc-error %i\n", rv); goto done; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 3365396e4e..c7ffbbca34 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2869,13 +2869,18 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile if (key_type == CKK_EC_EDWARDS) { if (ec->ecpointQ.len == 32) ec->params.id = oid_ED25519; - else + else if (ec->ecpointQ.len == 56) ec->params.id = oid_ED448; + else + return CKR_ATTRIBUTE_VALUE_INVALID; + } else if (key_type == CKK_EC_MONTGOMERY) { if (ec->ecpointQ.len == 32) ec->params.id = oid_X25519; - else + else if (ec->ecpointQ.len == 56) ec->params.id = oid_X448; + else + return CKR_ATTRIBUTE_VALUE_INVALID; } if (key_type == CKK_RSA) { @@ -3450,13 +3455,20 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, struct sc_lv_data *der = &keygen_args.prkey_args.key.u.ec.params.der; void *ptr = NULL; - der->len = sizeof(struct sc_object_id); rv = attr_find_and_allocate_ptr(pPubTpl, ulPubCnt, CKA_EC_PARAMS, &ptr, &der->len); der->value = (unsigned char *) ptr; if (rv != CKR_OK) { sc_unlock(p11card->card); return rv; } + if (sc_pkcs15_fix_ec_parameters(context, &keygen_args.prkey_args.key.u.ec.params) < 0) { + rv = CKR_CURVE_NOT_SUPPORTED; + goto kpgen_done; + } + } else { + /* CKA_KEY_TYPE is set, but keytype isn't correct */ + rv = CKR_ATTRIBUTE_VALUE_INVALID; + goto kpgen_done; } if (keytype == CKK_EC) { @@ -3471,10 +3483,6 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, /* Can not sign. To created a cert, see: openssl x509 -force_pubkey */ keygen_args.prkey_args.usage |= SC_PKCS15_PRKEY_USAGE_DERIVE; pub_args.key.algorithm = SC_ALGORITHM_XEDDSA; - } else { - /* CKA_KEY_TYPE is set, but keytype isn't correct */ - rv = CKR_ATTRIBUTE_VALUE_INVALID; - goto kpgen_done; } id.len = SC_PKCS15_MAX_ID_SIZE; @@ -3569,6 +3577,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, rv = sc_pkcs15_dup_pubkey(context, ((struct pkcs15_pubkey_object *)pub_any_obj)->pub_data, &priv_prk_obj->pub_data); kpgen_done: + sc_pkcs15_erase_prkey(&keygen_args.prkey_args.key); sc_pkcs15init_unbind(profile); sc_unlock(p11card->card); diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index d67121ce03..fd2ed1188b 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -206,8 +206,8 @@ void do_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (algorithms[i] == SC_ALGORITHM_EC) /* strdup called also in parse_alg_spec() */ keygen_args.prkey_args.key.u.ec.params.named_curve = strdup("prime256v1"); sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits[i], NULL); - if (algorithms[i] == SC_ALGORITHM_EC) - free(keygen_args.prkey_args.key.u.ec.params.named_curve); + /* clear the keygen prkey by algorithms which includes the pubkey and ec_params */ + sc_pkcs15_erase_prkey(&keygen_args.prkey_args.key); } } From 38e2f504f986badd69c02dbafa1ba659bc2038bb Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 8 Sep 2024 17:02:04 -0500 Subject: [PATCH 3718/4321] pkcs15init/pkcs15-openpgp.c - fix up problems reported in github On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 4b4cc541ba..e4bba7d479 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -326,9 +326,6 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - /* save expected length */ - key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); - /* generate key on card */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed"); @@ -339,8 +336,10 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, pubkey->algorithm = key_info.key_type; pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); - if (pubkey->u.ec.ecpointQ.value == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + if (pubkey->u.ec.ecpointQ.value == NULL) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto err; + } memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpoint, key_info.u.ec.ecpoint_len); From bce7f374d65a3314d4e4cdc83381b9cdc429f135 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 14 Sep 2024 07:07:58 -0500 Subject: [PATCH 3719/4321] card-openpgp.c - copy ecpoint to new pubkey Fix copying of the ecpoint read from card after key gen to pubkey for EC, EDDSA and XEDDSA keys, based on ec parameters which include length need for EC ecpoint shich is diffrent then EDDSA and XEDDSA. And address comments made in github On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 54 +++++++++++++++--------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5633ad81c3..cf7e4d2ad8 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -531,9 +531,7 @@ pgp_init(sc_card_t *card) /* if algorithm attributes can be changed, * add supported algorithms based on specification for pkcs15-init */ - /* pkcs11 or other utilities may need all the algs registered */ - if ((priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) - /* && (strcmp(card->ctx->app_name, "pkcs15-init") == 0) */) { + if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) { unsigned long flags_rsa, flags_ecc, ext_flags; unsigned long flags_eddsa, flags_xeddsa; @@ -569,7 +567,7 @@ pgp_init(sc_card_t *card) else if (priv->ec_curves[i].key_type == SC_ALGORITHM_EDDSA) _sc_card_add_eddsa_alg(card, priv->ec_curves[i].size, flags_eddsa, ext_flags, &priv->ec_curves[i].oid); - else + else if (priv->ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) _sc_card_add_xeddsa_alg(card, priv->ec_curves[i].size, flags_xeddsa, ext_flags, &priv->ec_curves[i].oid); } @@ -2999,23 +2997,29 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, memcpy(key_info->u.rsa.exponent, part, len); key_info->u.rsa.exponent_len = len * 8; /* store length in bits */ } - /* ECC public key */ + /* ECC or EDDSA public key */ else if (tag == 0x0086) { + /* Note: SC_OPENPGP_KEYALGO_ECDH could be either EC or XEDDSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_ECDSA && - key_info->algorithm != SC_OPENPGP_KEYALGO_ECDH) { + key_info->algorithm != SC_OPENPGP_KEYALGO_ECDH && + key_info->algorithm != SC_OPENPGP_KEYALGO_EDDSA) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } /* set the output data */ - /* EC is in 04||x||y format - * (field_length + 7)/8 * 2 + 1 in bytes - * len is ecpoint length + format byte - * see section 7.2.14 of 3.3.1 specs + /* key_info->u.ec.ecpoint_len is already set based on + * key_info->key_type + * EC is in 04||x||y format i.e. + * (field_length + 7)/8 * 2 + 1 in bytes + * len is ecpoint length + format byte + * see section 7.2.14 of 3.3.1 specs * EDDSA and XEDDSA have no format byte and one number - * (field_length + 7)/8 in bytes + * (field_length + 7)/8 in bytes */ - /* GNUK returns 04|x|y */ + /* GNUK returns 04||x||y */ + + if (len != key_info->u.ec.ecpoint_len) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - /* TODO check len is reasonable */ key_info->u.ec.ecpoint = malloc(len); if (key_info->u.ec.ecpoint == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); @@ -3030,16 +3034,6 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - - /* FIXME is this redundant? */ - if (key_info->u.ec.ecpoint == NULL || len != BYTES4BITS(key_info->u.ec.ecpoint_len)) { - free(key_info->u.ec.ecpoint); - key_info->u.ec.ecpoint = malloc(len); - if (key_info->u.ec.ecpoint == NULL) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - } - memcpy(key_info->u.ec.ecpoint, part + 1, len - 1); - key_info->u.ec.ecpoint_len = len - 1; } /* go to next part to parse */ @@ -3343,7 +3337,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info comp_to_add = 4; /* validate */ - if (comp_to_add == 4 && (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0)) { + if (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0) { sc_log(ctx, "Error: Modulus required!"); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -3487,6 +3481,8 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(card->ctx); + memset(&pubkey, 0, sizeof(pubkey)); + /* PKCS11 loads privkey separately from pubkey as two different operations * So this routine will be called twice to create two different objects. * pkcs15init only calls once, with both. @@ -3543,7 +3539,6 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - memset(&pubkey, 0, sizeof(pubkey)); pubkey.key_id = key_info->key_id; pubkey.algorithm = key_info->algorithm; pubkey.u.rsa.modulus = key_info->u.rsa.n; @@ -3569,24 +3564,19 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) pubkey.u.ec.oid_len = key_info->u.ec.oid_len; pubkey.u.ec.ecpoint = key_info->u.ec.ecpointQ; pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpointQ_len; - pubkey.u.ec.oid = key_info->u.ec.oid; - pubkey.u.ec.oid_len = key_info->u.ec.oid_len; } - /* TODO where is curve_name are */ if (has_pubkey) { r = pgp_update_new_algo_attr(card, &pubkey); LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); } - /* build Extended Header list */ if (has_privkey) { + /* build Extended Header list */ r = pgp_build_extended_header_list(card, key_info, &data, &len); LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to build Extended Header list"); - } - /* write to DO */ - if (has_privkey) { + /* write to DO */ r = pgp_put_data(card, 0x4D, data, len); LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to write to DO 004D"); From 69d9fe80201e72b066c169ee2e8f79b41f9ca88f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 14 Sep 2024 07:54:18 -0500 Subject: [PATCH 3720/4321] card-piv.c - fixup based on comments On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-piv.c --- src/libopensc/card-piv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index e16e1b7b96..c940caa42f 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2725,7 +2725,7 @@ static int piv_generate_key(sc_card_t *card, case 0x05: keydata->key_bits = 3072; break; case 0x06: keydata->key_bits = 1024; break; case 0x07: keydata->key_bits = 2048; break; - case 0x16: + case 0x16: /* Yubico 5.7 support for 4096 */ keydata->key_bits = 4096; break; case 0x11: keydata->key_bits = 0; @@ -2736,8 +2736,8 @@ static int piv_generate_key(sc_card_t *card, keydata->ecparam = 0; /* we only support secp384r1 */ keydata->ecparam_len = 0; break; - case 0xE0: - case 0xE1: + case 0xE0: /* Yubico 5.7 support for EDDSA 25519 */ + case 0xE1: /* Yubico 5.7 support for XEDDSA 25519 */ keydata->key_bits = 0; keydata->ecparam = 0; keydata->ecparam_len = 0; From e02beb68805d4fae29debcd9da82ac9bb76fcc30 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 14 Sep 2024 11:00:24 -0500 Subject: [PATCH 3721/4321] pkcs15-pubkey.c - improve sc_pkcs15_fix_ec_parameters The ec_curve_infos now store the curve OID as DER to simplify the code when caller provides the OID as DER or as printable string for experimental curves. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 112 ++++++++++++++++------------------ 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 072dbec7b6..b36824c030 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -718,9 +718,9 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, } /* - * all "ec" keys uses same pubkey format, keep this external entrypoint + * all "ec" keys use same pubkey format, keep this external entrypoint * keys are just byte strings. - * will accept in either BIT STRING or OCTET STRING + * will accept in either BIT STRING or OCTET STRING */ int sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, @@ -1497,57 +1497,57 @@ sc_pkcs15_pubkey_from_spki_file(struct sc_context *ctx, char * filename, static struct ec_curve_info { const char *name; const char *oid_str; - const char *oid_encoded; + const struct sc_pkcs15_der oid_der; size_t size; const unsigned int key_type; } ec_curve_infos[] = { - {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, - {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, - {"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, - {"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, SC_ALGORITHM_EC}, + {"secp192r1", "1.2.840.10045.3.1.1", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10}, 192, SC_ALGORITHM_EC}, + {"prime192v1", "1.2.840.10045.3.1.1", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10}, 192, SC_ALGORITHM_EC}, + {"nistp192", "1.2.840.10045.3.1.1", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10}, 192, SC_ALGORITHM_EC}, + {"ansiX9p192r1", "1.2.840.10045.3.1.1", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10}, 192, SC_ALGORITHM_EC}, - {"secp224r1", "1.3.132.0.33", "06052b81040021", 224, SC_ALGORITHM_EC}, - {"nistp224", "1.3.132.0.33", "06052b81040021", 224, SC_ALGORITHM_EC}, + {"secp224r1", "1.3.132.0.33", {(u8 *)"\x06\x05\x2b\x81\x04\x00\x21", 7}, 224, SC_ALGORITHM_EC}, + {"nistp224", "1.3.132.0.33", {(u8 *)"\x06\x05\x2b\x81\x04\x00\x21", 7}, 224, SC_ALGORITHM_EC}, - {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, - {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, - {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, - {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, SC_ALGORITHM_EC}, + {"secp256r1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, + {"prime256v1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, + {"nistp256", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, + {"ansiX9p256r1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, - {"secp384r1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, - {"prime384v1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, - {"nistp384", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, - {"ansiX9p384r1", "1.3.132.0.34", "06052B81040022", 384, SC_ALGORITHM_EC}, + {"secp384r1", "1.3.132.0.34", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x22", 7}, 384, SC_ALGORITHM_EC}, + {"prime384v1", "1.3.132.0.34", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x22", 7}, 384, SC_ALGORITHM_EC}, + {"nistp384", "1.3.132.0.34", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x22", 7}, 384, SC_ALGORITHM_EC}, + {"ansiX9p384r1", "1.3.132.0.34", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x22", 7}, 384, SC_ALGORITHM_EC}, - {"secp521r1", "1.3.132.0.35", "06052B81040023", 521, SC_ALGORITHM_EC}, - {"nistp521", "1.3.132.0.35", "06052B81040023", 521, SC_ALGORITHM_EC}, + {"secp521r1", "1.3.132.0.35", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x23", 7}, 521, SC_ALGORITHM_EC}, + {"nistp521", "1.3.132.0.35", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x23", 7}, 521, SC_ALGORITHM_EC}, - {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192, SC_ALGORITHM_EC}, - {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224, SC_ALGORITHM_EC}, - {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256, SC_ALGORITHM_EC}, - {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320, SC_ALGORITHM_EC}, - {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384, SC_ALGORITHM_EC}, - {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512, SC_ALGORITHM_EC}, + {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x03", 11}, 192, SC_ALGORITHM_EC}, + {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x05", 11}, 224, SC_ALGORITHM_EC}, + {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x07", 11}, 256, SC_ALGORITHM_EC}, + {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x09", 11}, 320, SC_ALGORITHM_EC}, + {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 11}, 384, SC_ALGORITHM_EC}, + {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 11}, 512, SC_ALGORITHM_EC}, - {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192, SC_ALGORITHM_EC}, - {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256, SC_ALGORITHM_EC}, + {"secp192k1", "1.3.132.0.31", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x1F", 7}, 192, SC_ALGORITHM_EC}, + {"secp256k1", "1.3.132.0.10", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x0A", 7}, 256, SC_ALGORITHM_EC}, /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255, SC_ALGORITHM_EDDSA}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255, SC_ALGORITHM_XEDDSA}, + {"edwards25519", "1.3.6.1.4.1.11591.15.1", {(u8 *)"\x06\x09\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01", 11}, 255, SC_ALGORITHM_EDDSA}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", {(u8 *)"\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01", 12}, 255, SC_ALGORITHM_XEDDSA}, /* RFC 8410 defined curves */ - {"X25519", "1.3.101.110", "06032b656e", 255, SC_ALGORITHM_XEDDSA}, - {"X448", "1.3.101.111", "06032b656f", 448, SC_ALGORITHM_XEDDSA}, - {"Ed25519", "1.3.101.112", "06032b6570", 255, SC_ALGORITHM_EDDSA}, - {"Ed448", "1.3.101.113", "06032b6571", 448, SC_ALGORITHM_EDDSA}, + {"X25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, + {"X448", "1.3.101.111", {(u8 *)"\x06\x03\x2b\x65\x6f", 5}, 448, SC_ALGORITHM_XEDDSA}, + {"Ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, + {"Ed448", "1.3.101.113", {(u8 *)"\x06\x03\x2b\x65\x71", 5}, 448, SC_ALGORITHM_EDDSA}, /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", "06032b656e", 255, SC_ALGORITHM_XEDDSA}, - {"ed25519", "1.3.101.112", "06032b6570", 255, SC_ALGORITHM_EDDSA}, + {"cv25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, + {"ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, - {NULL, NULL, NULL, 0, 0}, /* Do not touch this */ + {NULL, NULL, {NULL, 0}, 0, 0}, /* Do not touch this */ }; // clang-format on @@ -1562,22 +1562,14 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp /* In PKCS#11 EC parameters arrives in DER encoded form */ if (ecparams->der.value && ecparams->der.len && ecparams->der.len > 2) { - /* caller provided a der version of OID */ switch (ecparams->der.value[0]) { case 0x06: /* der.value is an OID */ for (ii = 0; ec_curve_infos[ii].name; ii++) { - struct sc_object_id id; - unsigned char *buf = NULL; - size_t len = 0; + size_t len = ec_curve_infos[ii].oid_der.len; - sc_format_oid(&id, ec_curve_infos[ii].oid_str); - sc_encode_oid(ctx, &id, &buf, &len); - - if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) { - free(buf); + if (ecparams->der.len == len && + memcmp(ecparams->der.value, ec_curve_infos[ii].oid_der.value, len) == 0) break; /* found ec_curve_infos[ii] */ - } - free(buf); /* ii points at {NULL, NULL, NULL, 0} entry */ } break; @@ -1611,16 +1603,17 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } - if (!ec_curve_infos[ii].name) + if (ec_curve_infos[ii].name == NULL) /* end of ec_curve_info */ LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve"); + /* ii points to entry with matching oid_der or a mapped entry with replacement oid_der */ sc_log(ctx, "Found known curve '%s'", ec_curve_infos[ii].name); - if (mapped_string) { /* free der of printable string replace below with OID */ + if (mapped_string) { /* free previous name if any replace below with new name */ free(ecparams->named_curve); ecparams->named_curve = NULL; } - if (!ecparams->named_curve) { + if (!ecparams->named_curve) { /* if present,keep the name as some curves have multiple names */ ecparams->named_curve = strdup(ec_curve_infos[ii].name); if (!ecparams->named_curve) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); @@ -1628,8 +1621,8 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp sc_log(ctx, "Curve name: '%s'", ecparams->named_curve); } - if (!sc_valid_oid(&ecparams->id) || mapped_string) - sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str); + /* fill in object_id based on oid_der */ + sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str); ecparams->field_length = ec_curve_infos[ii].size; ecparams->key_type = ec_curve_infos[ii].key_type; @@ -1637,15 +1630,14 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp ecparams->field_length, ecparams->key_type); if (mapped_string) { /* replace the printable string version with the oid */ - free(ecparams->der.value); - ecparams->der.len = strlen(ec_curve_infos[ii].oid_encoded) / 2; + if (ecparams->der.value) + free(ecparams->der.value); + ecparams->der.len = ec_curve_infos[ii].oid_der.len; ecparams->der.value = malloc(ecparams->der.len); - if (!ecparams->der.value) + if (ecparams->der.value == NULL) { LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - if (sc_hex_to_bin(ec_curve_infos[ii].oid_encoded, ecparams->der.value, &ecparams->der.len) < 0) { - free(ecparams->der.value); - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } + memcpy(ecparams->der.value, ec_curve_infos[ii].oid_der.value, ecparams->der.len); } } else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */ /* caller did not provide an OID, look for a name or oid_string */ @@ -1668,11 +1660,11 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecp sc_log(ctx, "Curve length %" SC_FORMAT_LEN_SIZE_T "u key_type %d", ecparams->field_length, ecparams->key_type); - if (!ecparams->der.value || !ecparams->der.len) { + if (ecparams->der.value == NULL || ecparams->der.len == 0) { free(ecparams->der.value); /* just in case */ ecparams->der.value = NULL; ecparams->der.len = 0; - /* if caller did not provide der OID, fill in */ + /* if caller did not provide valid der OID, fill in */ rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len); LOG_TEST_RET(ctx, rv, "Cannot encode object ID"); } From 41f8693dc33504fb4b71aa8762cf80baf429cb04 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 3 Oct 2024 10:07:43 -0500 Subject: [PATCH 3722/4321] pkcs11-tool.c - combine Edwards and Montgomery parsing Pass RFC 8410 OIDS and work with whatever crypto lib defines. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 71 +++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7a6b21265a..45d5e0f690 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -126,6 +126,7 @@ static struct ec_curve_info { {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, + {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, {"frp256v1", "1.2.250.1.223.101.256.1", "060a2a817a01815f65820001", 256, 0}, @@ -2189,6 +2190,19 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +/* return matching ec_curve_info or NULL based on name */ +static struct ec_curve_info * +match_ec_curve_by_name(const char *name) +{ + for (size_t i = 0; ec_curve_infos[i].name != NULL; ++i) { + if (strcmp(ec_curve_infos[i].name, name) == 0) { + return &ec_curve_infos[i]; + } + } + + return NULL; +} + /* return matching ec_curve_info or NULL based on ec_params */ static const struct ec_curve_info * match_ec_curve_by_params(const unsigned char *ec_params, CK_ULONG ec_params_size) @@ -4259,18 +4273,22 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) } #ifdef ENABLE_OPENSSL -/* return PKCS11 key type based on OpenSSL EVP_PKEY type - * which are support by PKCS11 and OpenSSL used when compiling - * PKCS11 returns CKK_EC_EDWARDS for both ED25529 and X448 - * and CKK_EC_MONTGOMERY for X25519 and X448, use pk_type. +/* Return PKCS11 key type based on OpenSSL EVP_PKEY type + * which are support by PKCS11 and OpenSSL used when compiling. + * PKCS11 defines CKK_EC_EDWARDS for both Ed25529 and X448 + * and CKK_EC_MONTGOMERY for X25519 and X448. + * If requested, return pointer to struct ec_curve_info containing OID and size */ + static CK_RV -evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) +evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_curve_info **ec_curve_info) { if (!pkey || !pk_type || !type) return CKR_GENERAL_ERROR; *pk_type = EVP_PKEY_base_id(pkey); + if (ec_curve_info) + *ec_curve_info = NULL; #if defined(EVP_PKEY_RSA) if (*pk_type == EVP_PKEY_RSA) { @@ -4289,6 +4307,9 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) #if defined(EVP_PKEY_ED25519) if (*pk_type == EVP_PKEY_ED25519) { *type = CKK_EC_EDWARDS; + if (ec_curve_info == NULL) + goto err; + *ec_curve_info = match_ec_curve_by_name("Ed25519"); return CKR_OK; } #endif @@ -4296,6 +4317,9 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) #if defined(EVP_PKEY_ED448) if (*pk_type == EVP_PKEY_ED448) { *type = CKK_EC_EDWARDS; + if (ec_curve_info == NULL) + goto err; + *ec_curve_info = match_ec_curve_by_name("Ed448"); return CKR_OK; } #endif @@ -4303,6 +4327,9 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) #if defined(EVP_PKEY_X25519) if (*pk_type == EVP_PKEY_X25519) { *type = CKK_EC_MONTGOMERY; + if (ec_curve_info == NULL) + goto err; + *ec_curve_info = match_ec_curve_by_name("X25519"); return CKR_OK; } #endif @@ -4310,6 +4337,9 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) #if defined(EVP_PKEY_X448) if (*pk_type == EVP_PKEY_X448) { *type = CKK_EC_MONTGOMERY; + if (ec_curve_info == NULL) + goto err; + *ec_curve_info = match_ec_curve_by_name("X448"); return CKR_OK; } #endif @@ -4334,6 +4364,7 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) return CKR_OK; } #endif +err: /* unsupported by OpenSSL, PKCS11 or this program */ *type = -1; *pk_type = -1; @@ -4341,23 +4372,27 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type) } #endif /* ENABLE_OPENSSL */ +/* Edwards and Montogmery keys have the same format */ static int -parse_ed_pkey(EVP_PKEY *pkey, int pk_type, int private, struct gostkey_info *gost) +parse_ed_mont_pkey(EVP_PKEY *pkey, int type, int pk_type, struct ec_curve_info *ec_info, int private, struct gostkey_info *gost) { - static unsigned char ec_params_ed25519[] = {0x06, 0x03, 0x2b, 0x65, 0x70}; - static unsigned char ec_params_ed448[] = {0x06, 0x03, 0x2b, 0x65, 0x71}; - unsigned char *ec_params = (pk_type == EVP_PKEY_ED25519) ? ec_params_ed25519 : ec_params_ed448; - size_t ec_params_size = (pk_type == EVP_PKEY_ED25519) ? sizeof(ec_params_ed25519) : sizeof(ec_params_ed448); + + size_t ec_params_size; unsigned char *key; size_t key_size; - /* set EC_PARAMS value */ + /* set EC_PARAMS value + * The param passed is DER of an OID or a PRINTABLE STRING as defines in PKCS11 3.0 + * ec_info containes these and all have one byte tag and one byte length. + */ + + ec_params_size = ec_info->ec_params[1] + 2; gost->param_oid.value = OPENSSL_malloc(ec_params_size); if (gost->param_oid.value == NULL) { return -1; } gost->param_oid.len = ec_params_size; - memcpy(gost->param_oid.value, ec_params, ec_params_size); + memcpy(gost->param_oid.value, ec_info->ec_params, ec_params_size); if (private) { if (EVP_PKEY_get_raw_private_key(pkey, NULL, &key_size) != 1) { @@ -4429,6 +4464,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) struct gostkey_info gost; EVP_PKEY *evp_key = NULL; int pk_type; + struct ec_curve_info *ec_info = NULL; memset(&cert, 0, sizeof(cert)); memset(&rsa, 0, sizeof(rsa)); @@ -4511,6 +4547,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) int is_private = opt_object_class == CKO_PRIVATE_KEY; int rv; CK_KEY_TYPE type; + struct ec_curve_info *ec_info; rv = do_read_key(contents, contents_len, is_private, &evp_key); if (rv) { @@ -4521,7 +4558,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) } /* get CK_TYPE from EVP_PKEY if both supported by OpenSSL and PKCS11 */ - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); if (type == CKK_RSA) { @@ -4533,8 +4570,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) type = CKK_GOSTR3410; } else if (type == CKK_EC) { rv = parse_ec_pkey(evp_key, is_private, &gost); - } else if (type == CKK_EC_EDWARDS) { - rv = parse_ed_pkey(evp_key, pk_type, is_private, &gost); + } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { + rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_info, is_private, &gost); } #endif else @@ -4642,7 +4679,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type,&ec_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); if (type == CKK_RSA) { @@ -4694,7 +4731,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) clazz = CKO_PUBLIC_KEY; #ifdef ENABLE_OPENSSL - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); n_pubkey_attr = 0; From 95422a0f9c04d046148fd95a8b22fd2e898581f6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 11 Oct 2024 19:18:17 -0500 Subject: [PATCH 3723/4321] pkcs11-tool.c - curve handling improvements The ec_curve_info entries now have static DER values for the ec_params. This improves the handling of the DER values, and the matching routines now return a pointer to a found entry. On branch X25519-improvements-2 Changes to be committed: modified: pkcs11-tool.c --- src/tools/pkcs11-tool.c | 154 ++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 85 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 45d5e0f690..254fe50fe3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -107,67 +107,69 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) // clang-format off +/* EC, Edwards and Montgomery curves understood by pkcs11-tool */ static struct ec_curve_info { - const char *name; - const char *oid; - const char *ec_params; - size_t size; + const char *name; /* common name of curve */ + const char *oid; /* formated printable OID */ + unsigned char *ec_params; /* der of OID or printable string */ + size_t ec_params_size; + size_t size; /* field_size in bits */ CK_KEY_TYPE mechanism; } ec_curve_infos[] = { - {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0}, - {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0}, - {"prime192v2", "1.2.840.10045.3.1.2", "06082A8648CE3D030102", 192, 0}, - {"prime192v3", "1.2.840.10045.3.1.3", "06082A8648CE3D030103", 192, 0}, - {"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0}, - {"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192, 0}, - - {"secp224r1", "1.3.132.0.33", "06052b81040021", 224, 0}, - {"nistp224", "1.3.132.0.33", "06052b81040021", 224, 0}, - - {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, - {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, - {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, - {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256, 0}, - {"frp256v1", "1.2.250.1.223.101.256.1", "060a2a817a01815f65820001", 256, 0}, - - {"secp384r1", "1.3.132.0.34", "06052B81040022", 384, 0}, - {"prime384v1", "1.3.132.0.34", "06052B81040022", 384, 0}, - {"ansiX9p384r1", "1.3.132.0.34", "06052B81040022", 384, 0}, - - {"prime521v1", "1.3.132.0.35", "06052B81040023", 521, 0}, - {"secp521r1", "1.3.132.0.35", "06052B81040023", 521, 0}, - {"nistp521", "1.3.132.0.35", "06052B81040023", 521, 0}, - - {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192, 0}, - {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224, 0}, - {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256, 0}, - {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320, 0}, - {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384, 0}, - {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512, 0}, - - {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192, 0}, - {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256, 0}, - {"secp521k1", "1.3.132.0.35", "06052B81040023", 521, 0}, + {"secp192r1", "1.2.840.10045.3.1.1", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10, 192, 0}, + {"prime192v1", "1.2.840.10045.3.1.1", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10, 192, 0}, + {"prime192v2", "1.2.840.10045.3.1.2", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x02", 10, 192, 0}, + {"prime192v3", "1.2.840.10045.3.1.3", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x03", 10, 192, 0}, + {"nistp192", "1.2.840.10045.3.1.1", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10, 192, 0}, + {"ansiX9p192r1", "1.2.840.10045.3.1.1", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10, 192, 0}, + + {"secp224r1", "1.3.132.0.33", (unsigned char*)"\x06\x05\x2b\x81\x04\x00\x21", 7, 224, 0}, + {"nistp224", "1.3.132.0.33", (unsigned char*)"\x06\x05\x2b\x81\x04\x00\x21", 7, 224, 0}, + + {"prime256v1", "1.2.840.10045.3.1.7", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10, 256, 0}, + {"secp256r1", "1.2.840.10045.3.1.7", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10, 256, 0}, + {"nistp256", "1.2.840.10045.3.1.7", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10, 256, 0}, + {"ansiX9p256r1", "1.2.840.10045.3.1.7", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10, 256, 0}, + {"frp256v1", "1.2.250.1.223.101.256.1", (unsigned char*)"\x06\x0a\x2a\x81\x7a\x01\x81\x5f\x65\x82\x00\x01", 11, 256, 0}, + + {"secp384r1", "1.3.132.0.34", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x22", 7, 384, 0}, + {"prime384v1", "1.3.132.0.34", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x22", 7, 384, 0}, + {"ansiX9p384r1", "1.3.132.0.34", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x22", 7, 384, 0}, + + {"prime521v1", "1.3.132.0.35", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x23", 7, 521, 0}, + {"secp521r1", "1.3.132.0.35", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x23", 7, 521, 0}, + {"nistp521", "1.3.132.0.35", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x23", 7, 521, 0}, + + {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x03", 11, 192, 0}, + {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x05", 11, 224, 0}, + {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x07", 11, 256, 0}, + {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x09", 11, 320, 0}, + {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 11, 384, 0}, + {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 11, 512, 0}, + + {"secp192k1", "1.3.132.0.31", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x1F", 7, 192, 0}, + {"secp256k1", "1.3.132.0.10", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x0A", 7, 256, 0}, + {"secp521k1", "1.3.132.0.35", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x23", 7, 521, 0}, /* Some of the following may not yet be supported by the OpenSC module, but may be by other modules */ /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs, so pass by printable string */ /* See PKCS#11 3.0 2.3.7 */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", "130c656477617264733235353139", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "130a63757276653235353139", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ + {"edwards25519", "1.3.6.1.4.1.11591.15.1", (unsigned char*)"\x13\x0c\x65\x64\x77\x61\x72\x64\x73\x32\x35\x35\x31\x39", 14, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", (unsigned char*)"\x13\x0a\x63\x75\x72\x76\x65\x32\x35\x35\x31\x39", 12, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ /* RFC8410, EDWARDS and MONTGOMERY curves are used by GnuPG and also by OpenSSL */ - {"X25519", "1.3.101.110", "06032b656e", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ - {"X448", "1.3.101.111", "06032b656f", 448, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ - {"Ed25519", "1.3.101.112", "06032b6570", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ - {"Ed448", "1.3.101.113", "06032b6571", 448, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"X25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"X448", "1.3.101.111", (unsigned char*)"\x06\x03\x2b\x65\x6f", 5, 448, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed448", "1.3.101.113", (unsigned char*)"\x06\x03\x2b\x65\x71", 5, 448, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", "06032b656e", 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, - {"ed25519", "1.3.101.112", "06032b6570", 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, + {"cv25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, + {"ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* OpenSC card-openpgp.c will map these to what is need on the card */ - {NULL, NULL, NULL, 0, 0}, + {NULL, NULL, NULL, 0, 0, 0}, }; // clang-format on @@ -2207,16 +2209,12 @@ match_ec_curve_by_name(const char *name) static const struct ec_curve_info * match_ec_curve_by_params(const unsigned char *ec_params, CK_ULONG ec_params_size) { - char ecpbuf[64]; - - if (ec_params_size > (sizeof(ecpbuf) / 2)) { - util_fatal("Invalid EC params"); - } - - sc_bin_to_hex(ec_params, ec_params_size, ecpbuf, sizeof(ecpbuf), 0); + if (ec_params_size < 3) + return NULL; for (size_t i = 0; ec_curve_infos[i].name != NULL; ++i) { - if (strcmp(ec_curve_infos[i].ec_params, ecpbuf) == 0) { + if ((ec_curve_infos[i].ec_params_size == ec_params_size) && + (memcmp(&ec_curve_infos[i].ec_params, ec_params, ec_params_size) == 0)) { return &ec_curve_infos[i]; } } @@ -2596,7 +2594,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, curve = match_ec_curve_by_params(ec_params, ec_params_size); if (curve == NULL) { - util_fatal("Unknown or unsupported EC curve used in key"); + util_fatal("Unknown, invalid or unsupported EC curve used in key"); } /* Ed448: need the params defined but default to false */ @@ -3119,8 +3117,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, }; unsigned long int gost_key_type = -1; int n_privkey_attr = 4; - unsigned char *ecparams = NULL; - size_t ecparams_size; CK_ULONG key_type = CKK_RSA; CK_RV rv; @@ -3217,14 +3213,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } } - ecparams_size = strlen(ec_curve_infos[ii].ec_params) / 2; - ecparams = malloc(ecparams_size); - if (!ecparams) - util_fatal("Allocation error", 0); - if (sc_hex_to_bin(ec_curve_infos[ii].ec_params, ecparams, &ecparams_size)) { - fprintf(stderr, "Cannot convert \"%s\"\n", ec_curve_infos[ii].ec_params); - util_print_usage_and_die(app_name, options, option_help, NULL); - } + if (opt_key_usage_default || opt_key_usage_sign) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); @@ -3240,7 +3229,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ecparams, ecparams_size); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ec_curve_infos[ii].ec_params, ec_curve_infos[ii].ec_params_size); n_pubkey_attr++; FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_pubkey_attr++; @@ -3419,9 +3408,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (rv != CKR_OK) p11_fatal("C_GenerateKeyPair", rv); - if (ecparams) - free(ecparams); - printf("Key pair generated:\n"); show_object(session, *hPrivateKey); show_object(session, *hPublicKey); @@ -4279,7 +4265,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) * and CKK_EC_MONTGOMERY for X25519 and X448. * If requested, return pointer to struct ec_curve_info containing OID and size */ - + static CK_RV evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_curve_info **ec_curve_info) { @@ -4374,25 +4360,22 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ /* Edwards and Montogmery keys have the same format */ static int -parse_ed_mont_pkey(EVP_PKEY *pkey, int type, int pk_type, struct ec_curve_info *ec_info, int private, struct gostkey_info *gost) +parse_ed_mont_pkey(EVP_PKEY *pkey, int type, int pk_type, struct ec_curve_info *ec_curve_info, int private, struct gostkey_info *gost) { - - size_t ec_params_size; unsigned char *key; size_t key_size; /* set EC_PARAMS value * The param passed is DER of an OID or a PRINTABLE STRING as defines in PKCS11 3.0 - * ec_info containes these and all have one byte tag and one byte length. + * all of the ec_curve_info entries have one byte len values */ - ec_params_size = ec_info->ec_params[1] + 2; - gost->param_oid.value = OPENSSL_malloc(ec_params_size); + gost->param_oid.value = OPENSSL_malloc(ec_curve_info->ec_params_size); if (gost->param_oid.value == NULL) { return -1; } - gost->param_oid.len = ec_params_size; - memcpy(gost->param_oid.value, ec_info->ec_params, ec_params_size); + gost->param_oid.len = ec_curve_info->ec_params_size; + memcpy(gost->param_oid.value, ec_curve_info->ec_params, ec_curve_info->ec_params_size); if (private) { if (EVP_PKEY_get_raw_private_key(pkey, NULL, &key_size) != 1) { @@ -4464,7 +4447,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) struct gostkey_info gost; EVP_PKEY *evp_key = NULL; int pk_type; - struct ec_curve_info *ec_info = NULL; + struct ec_curve_info *ec_curve_info = NULL; memset(&cert, 0, sizeof(cert)); memset(&rsa, 0, sizeof(rsa)); @@ -4547,7 +4530,6 @@ static CK_RV write_object(CK_SESSION_HANDLE session) int is_private = opt_object_class == CKO_PRIVATE_KEY; int rv; CK_KEY_TYPE type; - struct ec_curve_info *ec_info; rv = do_read_key(contents, contents_len, is_private, &evp_key); if (rv) { @@ -4558,7 +4540,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) } /* get CK_TYPE from EVP_PKEY if both supported by OpenSSL and PKCS11 */ - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_info) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_curve_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); if (type == CKK_RSA) { @@ -4571,7 +4553,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) } else if (type == CKK_EC) { rv = parse_ec_pkey(evp_key, is_private, &gost); } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { - rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_info, is_private, &gost); + rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_curve_info, is_private, &gost); } #endif else @@ -4635,6 +4617,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SENSITIVE, &_true, sizeof(_true)); n_privkey_attr++; + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); + n_privkey_attr++; if (opt_object_label != NULL) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); @@ -4679,7 +4663,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type,&ec_info) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type,&ec_curve_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); if (type == CKK_RSA) { @@ -4731,7 +4715,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) clazz = CKO_PUBLIC_KEY; #ifdef ENABLE_OPENSSL - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_info) != CKR_OK) + if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_curve_info) != CKR_OK) util_fatal("Key type not supported by OpenSSL and/or PKCS11"); n_pubkey_attr = 0; From 175ac15c37817d0641ecd87066158365e49c6418 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 16 Oct 2024 07:29:14 -0500 Subject: [PATCH 3724/4321] pkcs11-tool.c - If module supports CKA_PUBLIC_KEY_INFO, use it The PKCS11 3.0 defines CKA_PUBLIC_KEY_INFO which is "Subject Public Key Info" as used in certiicates. If not suppoerted the older code, about 260 lines of code, will still be used. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- doc/tools/pkcs11-tool.1.xml | 10 + doc/tools/tools.html | 5 + src/tools/pkcs11-tool.c | 455 ++++++++++++++++++------------------ 3 files changed, 249 insertions(+), 221 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 9a04a861ad..7ffd5940ad 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -332,6 +332,16 @@ the option. + + + + + Read public key from the module using "CKA_PUBLIC_KEY_INFO" + (use with ). + The output is a "SubjectPublicKeyInfo" i.e. as used in certificates + and openssl, + + puk diff --git a/doc/tools/tools.html b/doc/tools/tools.html index e463ea57ae..3116235a62 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1571,6 +1571,11 @@ environment variable VARIABLE is used.

    This option will also set the --login option.

    + --public-key-info +

    Read public key from the module using "CKA_PUBLIC_KEY_INFO" + (use with --read-object --type public). + The output is a "SubjectPublicKeyInfo" i.e. as used in certificates + and openssl,

    --puk puk

    Supply User PUK on the command line.

    --new-pin pin diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 254fe50fe3..35961e98ef 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -110,7 +110,7 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; /* EC, Edwards and Montgomery curves understood by pkcs11-tool */ static struct ec_curve_info { const char *name; /* common name of curve */ - const char *oid; /* formated printable OID */ + const char *oid; /* formatted printable OID */ unsigned char *ec_params; /* der of OID or printable string */ size_t ec_params_size; size_t size; /* field_size in bits */ @@ -236,7 +236,8 @@ enum { OPT_AAD, OPT_TAG_BITS, OPT_SALT_FILE, - OPT_INFO_FILE + OPT_INFO_FILE, + OPT_PUBLIC_KEY_INFO }; // clang-format off @@ -329,6 +330,7 @@ static const struct option options[] = { { "tag-bits-len", 1, NULL, OPT_TAG_BITS}, { "salt-file", 1, NULL, OPT_SALT_FILE}, { "info-file", 1, NULL, OPT_INFO_FILE}, + { "public-key-info", 0, NULL, OPT_PUBLIC_KEY_INFO}, { NULL, 0, NULL, 0 } }; @@ -487,6 +489,7 @@ static const char *opt_aad = NULL; static unsigned long opt_tag_bits = 0; static const char *opt_salt_file = NULL; static const char *opt_info_file = NULL; +static int opt_public_key_info = 0; /* return pubkey as SPKI DER */ static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -752,6 +755,7 @@ VARATTR_METHOD(GOSTR3411_PARAMS, unsigned char); /* getGOSTR3411_PARAMS */ VARATTR_METHOD(EC_POINT, unsigned char); /* getEC_POINT */ VARATTR_METHOD(EC_PARAMS, unsigned char); /* getEC_PARAMS */ VARATTR_METHOD(ALLOWED_MECHANISMS, CK_MECHANISM_TYPE); /* getALLOWED_MECHANISMS */ +VARATTR_METHOD(PUBLIC_KEY_INFO, unsigned char); /* getPUBLIC_KEY_INFO */ int main(int argc, char * argv[]) { @@ -1215,6 +1219,9 @@ int main(int argc, char * argv[]) case OPT_INFO_FILE: opt_info_file = optarg; break; + case OPT_PUBLIC_KEY_INFO: + opt_public_key_info = 1; + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -2192,6 +2199,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +#ifdef ENABLE_OPENSSL /* return matching ec_curve_info or NULL based on name */ static struct ec_curve_info * match_ec_curve_by_name(const char *name) @@ -2204,6 +2212,7 @@ match_ec_curve_by_name(const char *name) return NULL; } +#endif /* return matching ec_curve_info or NULL based on ec_params */ static const struct ec_curve_info * @@ -4617,9 +4626,6 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SENSITIVE, &_true, sizeof(_true)); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); - n_privkey_attr++; - if (opt_object_label != NULL) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); n_privkey_attr++; @@ -6350,274 +6356,281 @@ static int read_object(CK_SESSION_HANDLE session) else if (obj==CK_INVALID_HANDLE) util_fatal("object not found"); -/* TODO: -DEE should look at object class, and get appropriate values - * based on the object, and other attributes. For example EC keys do - * not have a VALUE But have a EC_POINT. DvO: done for RSA and EC public keys. - */ if (clazz == CKO_PRIVATE_KEY) { fprintf(stderr, "sorry, reading private keys not (yet) supported\n"); return 0; } if (clazz == CKO_PUBLIC_KEY) { + /* If module supports CKA_PUBLIC_KEY_INFO which is DER of SPKI + * return whatever the module provides including ED448 and X448 + */ + if (opt_public_key_info) + value = getPUBLIC_KEY_INFO(session, obj, &len); + /* softhsm2 may return length 0 and varattr may allocate memory treat as invalid */ + if (value && len == 0) { + p11_warn("getPUBLIC_KEY_INFO returned a value of length 0",0); + free(value); + value = NULL; + } + if (value == NULL) { /* Do the old way */ #ifdef ENABLE_OPENSSL - long derlen; - EVP_PKEY *pkey = NULL; + long derlen; + EVP_PKEY *pkey = NULL; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_PKEY_CTX *ctx = NULL; - OSSL_PARAM *params = NULL; - OSSL_PARAM_BLD *bld = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *bld = NULL; #endif + BIO *pout = BIO_new(BIO_s_mem()); + if (!pout) + util_fatal("out of memory"); - BIO *pout = BIO_new(BIO_s_mem()); - if (!pout) - util_fatal("out of memory"); - - type = getKEY_TYPE(session, obj); - if (type == CKK_RSA) { - BIGNUM *rsa_n = NULL; - BIGNUM *rsa_e = NULL; + type = getKEY_TYPE(session, obj); + if (type == CKK_RSA) { + BIGNUM *rsa_n = NULL; + BIGNUM *rsa_e = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA *rsa = RSA_new(); - if (!rsa) - util_fatal("out of memory"); + RSA *rsa = RSA_new(); + if (!rsa) + util_fatal("out of memory"); #endif - if ((value = getMODULUS(session, obj, &len))) { - if (!(rsa_n = BN_bin2bn(value, (int)len, NULL))) - util_fatal("cannot parse MODULUS"); - free(value); - } else - util_fatal("cannot obtain MODULUS"); + if ((value = getMODULUS(session, obj, &len))) { + if (!(rsa_n = BN_bin2bn(value, (int)len, NULL))) + util_fatal("cannot parse MODULUS"); + free(value); + } else + util_fatal("cannot obtain MODULUS"); - if ((value = getPUBLIC_EXPONENT(session, obj, &len))) { - if (!(rsa_e = BN_bin2bn(value, (int)len, NULL))) - util_fatal("cannot parse PUBLIC_EXPONENT"); - free(value); - } else - util_fatal("cannot obtain PUBLIC_EXPONENT"); + if ((value = getPUBLIC_EXPONENT(session, obj, &len))) { + if (!(rsa_e = BN_bin2bn(value, (int)len, NULL))) + util_fatal("cannot parse PUBLIC_EXPONENT"); + free(value); + } else + util_fatal("cannot obtain PUBLIC_EXPONENT"); #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) - util_fatal("cannot set RSA values"); + if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) + util_fatal("cannot set RSA values"); - if (!i2d_RSA_PUBKEY_bio(pout, rsa)) - util_fatal("cannot convert RSA public key to DER"); - RSA_free(rsa); + if (!i2d_RSA_PUBKEY_bio(pout, rsa)) + util_fatal("cannot convert RSA public key to DER"); + RSA_free(rsa); #else - ctx = EVP_PKEY_CTX_new_from_name(osslctx, "RSA", NULL); - if (!ctx) - util_fatal("out of memory"); - if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + ctx = EVP_PKEY_CTX_new_from_name(osslctx, "RSA", NULL); + if (!ctx) + util_fatal("out of memory"); + if (!(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + BN_free(rsa_n); + BN_free(rsa_e); + OSSL_PARAM_BLD_free(bld); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + util_fatal("cannot set RSA values"); + } BN_free(rsa_n); BN_free(rsa_e); OSSL_PARAM_BLD_free(bld); - EVP_PKEY_CTX_free(ctx); - OSSL_PARAM_free(params); - util_fatal("cannot set RSA values"); - } - BN_free(rsa_n); - BN_free(rsa_e); - OSSL_PARAM_BLD_free(bld); - if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { - EVP_PKEY_CTX_free(ctx); + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + util_fatal("cannot set RSA values"); + } OSSL_PARAM_free(params); - util_fatal("cannot set RSA values"); - } - OSSL_PARAM_free(params); - if (i2d_PUBKEY_bio(pout, pkey) != 1) { + if (i2d_PUBKEY_bio(pout, pkey) != 1) { + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot convert RSA public key to DER"); + } + EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); - util_fatal("cannot convert RSA public key to DER"); - } - EVP_PKEY_free(pkey); - EVP_PKEY_CTX_free(ctx); #endif #if !defined(OPENSSL_NO_EC) - } else if (type == CKK_EC) { - CK_BYTE *params; - const unsigned char *a; - size_t a_len = 0; - ASN1_OCTET_STRING *os; - int success = 0; - EC_POINT *point = NULL; + } else if (type == CKK_EC) { + CK_BYTE *params; + const unsigned char *a; + size_t a_len = 0; + ASN1_OCTET_STRING *os; + int success = 0; + EC_POINT *point = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - const EC_GROUP *group = NULL; - EC_KEY *ec = EC_KEY_new(); - pkey = EVP_PKEY_new(); + const EC_GROUP *group = NULL; + EC_KEY *ec = EC_KEY_new(); + pkey = EVP_PKEY_new(); #else - EC_GROUP *group = NULL; - char group_name[80]; - OSSL_PARAM *old = NULL, *new = NULL, *p = NULL; - OSSL_PARAM_BLD *bld = NULL; + EC_GROUP *group = NULL; + char group_name[80]; + OSSL_PARAM *old = NULL, *new = NULL, *p = NULL; + OSSL_PARAM_BLD *bld = NULL; #endif - if ((params = getEC_PARAMS(session, obj, &len))) { - const unsigned char *a = params; + if ((params = getEC_PARAMS(session, obj, &len))) { + const unsigned char *a = params; #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (!d2i_ECParameters(&ec, &a, (long)len)) - util_fatal("cannot parse EC_PARAMS"); - EVP_PKEY_assign_EC_KEY(pkey, ec); + if (!d2i_ECParameters(&ec, &a, (long)len)) + util_fatal("cannot parse EC_PARAMS"); + EVP_PKEY_assign_EC_KEY(pkey, ec); #else - if (!d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len)) - util_fatal("cannot parse EC_PARAMS"); + if (!d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len)) + util_fatal("cannot parse EC_PARAMS"); #endif - free(params); - } else - util_fatal("cannot obtain EC_PARAMS"); - - value = getEC_POINT(session, obj, &len); - /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* DEE Should be returned encoded in BIT STRING, Need to accept both */ - a = value; - os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); - if (!os) { - os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); + free(params); + } else + util_fatal("cannot obtain EC_PARAMS"); + + value = getEC_POINT(session, obj, &len); + /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ + /* No, should return encoded in BIT STRING, Need to accept both */ + a = value; + os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); + if (!os) { + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); len = (len + 7) / 8; - } + } #if OPENSSL_VERSION_NUMBER < 0x30000000L - group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); + group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); #else - if (EVP_PKEY_get_group_name(pkey, group_name, sizeof(group_name), NULL) != 1) - util_fatal("cannot obtain EC_PARAMS"); - group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); + if (EVP_PKEY_get_group_name(pkey, group_name, sizeof(group_name), NULL) != 1) + util_fatal("cannot obtain EC_PARAMS"); + group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); #endif - point = EC_POINT_new(group); - if (os) { - a = os->data; - a_len = os->length; - success = EC_POINT_oct2point(group, point, a, a_len, NULL); - } - if (!success) { /* Workaround for broken PKCS#11 modules */ - ASN1_STRING_free(os); - a = value; - a_len = len; - if (!EC_POINT_oct2point(group, point, a, len, NULL)) { - free(value); - util_fatal("cannot obtain and parse EC_POINT"); + point = EC_POINT_new(group); + if (os) { + a = os->data; + a_len = os->length; + success = EC_POINT_oct2point(group, point, a, a_len, NULL); + } + if (!success) { /* Workaround for broken PKCS#11 modules */ + ASN1_STRING_free(os); + a = value; + a_len = len; + if (!EC_POINT_oct2point(group, point, a, len, NULL)) { + free(value); + util_fatal("cannot obtain and parse EC_POINT"); + } } - } #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (success) - ASN1_STRING_free(os); - free(value); - EC_KEY_set_public_key(EVP_PKEY_get0_EC_KEY(pkey), point); + if (success) + ASN1_STRING_free(os); + free(value); + EC_KEY_set_public_key(EVP_PKEY_get0_EC_KEY(pkey), point); #else - if (!(bld = OSSL_PARAM_BLD_new()) || - EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &old) != 1 || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", a, a_len) != 1 || - !(new = OSSL_PARAM_BLD_to_param(bld)) || - !(p = OSSL_PARAM_merge(old, new))) { - OSSL_PARAM_BLD_free(bld); - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); - OSSL_PARAM_free(p); - if (success) - ASN1_STRING_free(os); - free(value); - util_fatal("cannot set OSSL_PARAM"); - } + if (!(bld = OSSL_PARAM_BLD_new()) || + EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &old) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", a, a_len) != 1 || + !(new = OSSL_PARAM_BLD_to_param(bld)) || + !(p = OSSL_PARAM_merge(old, new))) { + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); + OSSL_PARAM_free(p); + if (success) + ASN1_STRING_free(os); + free(value); + util_fatal("cannot set OSSL_PARAM"); + } OSSL_PARAM_BLD_free(bld); - if (success) - ASN1_STRING_free(os); - free(value); + if (success) + ASN1_STRING_free(os); + free(value); - if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || - EVP_PKEY_fromdata_init(ctx) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot set CTX"); - } - EVP_PKEY_free(pkey); - pkey = NULL; - if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot create EVP_PKEY"); - } - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || + EVP_PKEY_fromdata_init(ctx) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot set CTX"); + } + EVP_PKEY_free(pkey); + pkey = NULL; + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot create EVP_PKEY"); + } + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); #endif - if (!i2d_PUBKEY_bio(pout, pkey)) - util_fatal("cannot convert EC public key to DER"); + if (!i2d_PUBKEY_bio(pout, pkey)) + util_fatal("cannot convert EC public key to DER"); #endif #ifdef EVP_PKEY_ED25519 - } else if (type == CKK_EC_EDWARDS) { - EVP_PKEY *key = NULL; - CK_BYTE *params = NULL; - const unsigned char *a; - ASN1_OCTET_STRING *os; - - if ((params = getEC_PARAMS(session, obj, &len))) { - ASN1_PRINTABLESTRING *curve = NULL; - ASN1_OBJECT *obj = NULL; - - a = params; - if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { - if (strcmp((char *)curve->data, "edwards25519")) { - util_fatal("Unknown curve name, expected edwards25519, got %s", - curve->data); - } - ASN1_PRINTABLESTRING_free(curve); - } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { - int nid = OBJ_obj2nid(obj); - if (nid != NID_ED25519) { - util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d", - NID_ED25519, nid); + } else if (type == CKK_EC_EDWARDS) { + EVP_PKEY *key = NULL; + CK_BYTE *params = NULL; + const unsigned char *a; + ASN1_OCTET_STRING *os; + + if ((params = getEC_PARAMS(session, obj, &len))) { + ASN1_PRINTABLESTRING *curve = NULL; + ASN1_OBJECT *obj = NULL; + + a = params; + if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { + if (strcmp((char *)curve->data, "edwards25519")) { + util_fatal("Unknown curve name, expected edwards25519, got %s", + curve->data); + } + ASN1_PRINTABLESTRING_free(curve); + } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_ED25519) { + util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d", + NID_ED25519, nid); + } + ASN1_OBJECT_free(obj); + } else { + util_fatal("cannot parse curve name from EC_PARAMS"); } - ASN1_OBJECT_free(obj); + free(params); } else { - util_fatal("cannot parse curve name from EC_PARAMS"); + util_fatal("cannot obtain EC_PARAMS"); } - free(params); - } else { - util_fatal("cannot obtain EC_PARAMS"); - } - - value = getEC_POINT(session, obj, &len); - /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* DEE should be in BIT STRING accept both */ - a = value; - os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); - if (!os) { - os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); - len = (len + 7) / 8; - } - if (!os) { - util_fatal("cannot decode EC_POINT"); - } - if (os->length != 32) { - util_fatal("Invalid length of EC_POINT value"); - } - key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, - (const uint8_t *)os->data, - os->length); - ASN1_STRING_free(os); - if (key == NULL) { - util_fatal("out of memory"); - } - /* Note, that we write PEM here as there is no "native" - * representation of EdDSA public keys to use */ - if (!PEM_write_bio_PUBKEY(pout, key)) { - util_fatal("cannot convert EdDSA public key to PEM"); - } - - EVP_PKEY_free(key); + value = getEC_POINT(session, obj, &len); + /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ + /* No, should be in BIT STRING accept both */ + a = value; + os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); + if (!os) { + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); + len = (len + 7) / 8; + } + if (!os) { + util_fatal("cannot decode EC_POINT"); + } + if (os->length != 32) { + util_fatal("Invalid length of EC_POINT value"); + } + key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, + (const uint8_t *)os->data, + os->length); + ASN1_STRING_free(os); + if (key == NULL) { + util_fatal("out of memory"); + } + /* Note, that we write PEM here as there is no "native" + * representation of EdDSA public keys to use */ + if (!PEM_write_bio_PUBKEY(pout, key)) { + util_fatal("cannot convert EdDSA public key to PEM"); + } + + EVP_PKEY_free(key); #endif - } - else - util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); - value = BIO_copy_data(pout, &derlen); - BIO_free(pout); - len = derlen; + } + else + util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); + value = BIO_copy_data(pout, &derlen); + BIO_free(pout); + len = derlen; #else - util_fatal("No OpenSSL support, cannot read public key"); + util_fatal("No OpenSSL support, cannot read public key"); #endif + } /* value is PUBKEY_KEY_INFO */ } else value = getVALUE(session, obj, &len); From 3a088dd212303a9cccabba584d15d19da4503bd3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 16 Oct 2024 07:48:01 -0500 Subject: [PATCH 3725/4321] pkcs15-pubkey.c - Fix sc_pkcs15_encode_pubkey_as_spki for EDDSA and XEDDSA Edward and Montgomery curves do not take an algorithm parameter. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index b36824c030..ab4f027843 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -826,6 +826,7 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk pubkey->alg_id->algorithm = pubkey->algorithm; } +/* TODO fix EDDSA and XEDDSA to only have algo and no param in SPKI */ switch (pubkey->algorithm) { case SC_ALGORITHM_EC: case SC_ALGORITHM_EDDSA: @@ -845,20 +846,23 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); LOG_TEST_RET(ctx, r, "failed to fix EC parameters"); - ec_params = calloc(1, sizeof(struct sc_ec_parameters)); - if (!ec_params) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - ec_params->type = 1; - ec_params->der.value = calloc(1, pubkey->u.ec.params.der.len); - if (!ec_params->der.value) { - free(ec_params); - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + /* EDDSA and XEDDSA only have algo and no param in SPKI */ + if (pubkey->algorithm == SC_ALGORITHM_EC) { + ec_params = calloc(1, sizeof(struct sc_ec_parameters)); + if (!ec_params) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + ec_params->type = 1; + ec_params->der.value = calloc(1, pubkey->u.ec.params.der.len); + if (!ec_params->der.value) { + free(ec_params); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } + memcpy(ec_params->der.value, pubkey->u.ec.params.der.value, pubkey->u.ec.params.der.len); + ec_params->der.len = pubkey->u.ec.params.der.len; } - memcpy(ec_params->der.value, pubkey->u.ec.params.der.value, pubkey->u.ec.params.der.len); - ec_params->der.len = pubkey->u.ec.params.der.len; /* This could have been already allocated: avoid memory leak */ sc_asn1_clear_algorithm_id(pubkey->alg_id); - pubkey->alg_id->params = ec_params; + pubkey->alg_id->params = ec_params; /* NULL for EDDSA and XEDDSA */ } break; case SC_ALGORITHM_GOSTR3410: From 0b82b761abd6a655df9f17eeb01c0d7330facc01 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 16 Oct 2024 07:57:40 -0500 Subject: [PATCH 3726/4321] In OpenPGP code combine the keygen and keystore structures In PKCS11 writing key objects to a token two sepeate calls are made, one for the private key and one for the public key. The code in card-openpgp.c, pkcs15init/pkcs15-openpgp.c used two different code paths for generating a key vs storing a key. sc_cardctl_openpgp_keystore_info and sc_cardctl_openpgp_keygen_info were combined into struct sc_cardctl_openpgp_key_gen_store_info. Code was added to allow storing of the private key first followed by a second operation to store the public key. RSA does not have this problem because the modulus and exponent are part of the private key. But this in not the case with EC, Edwards or Montgomery keys. pkcs11-tool can now store EC, ED25519 and X25519 keys. On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c modified: libopensc/cardctl.h modified: pkcs15init/pkcs15-openpgp.c modified: tools/openpgp-tool.c --- src/libopensc/card-openpgp.c | 194 ++++++++++++++++---------------- src/libopensc/cardctl.h | 58 ++++------ src/pkcs15init/pkcs15-openpgp.c | 193 ++++++++++++++++++++++++++----- src/tools/openpgp-tool.c | 4 +- 4 files changed, 285 insertions(+), 164 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cf7e4d2ad8..a1b3ebbb8f 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -620,7 +620,7 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) **/ static int pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, - sc_cardctl_openpgp_keygen_info_t *key_info) + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); struct sc_object_id oid; @@ -660,7 +660,7 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB){ if (blob->len < 3) return SC_ERROR_INCORRECT_PARAMETERS; - key_info->u.ec.oid_len = blob->len - 2; + key_info->u.ec.oidv_len = blob->len - 2; key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STDPUB; } else { @@ -669,15 +669,15 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, if (blob->len < 2) return SC_ERROR_INCORRECT_PARAMETERS; if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STD) - key_info->u.ec.oid_len = blob->len - 2; + key_info->u.ec.oidv_len = blob->len - 2; else - key_info->u.ec.oid_len = blob->len - 1; + key_info->u.ec.oidv_len = blob->len - 1; key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STD; } /* Create copy of oid from blob */ sc_init_oid(&oid); - r = sc_asn1_decode_object_id(&blob->data[1], key_info->u.ec.oid_len, &oid); + r = sc_asn1_decode_object_id(&blob->data[1], key_info->u.ec.oidv_len, &oid); /* decoding failed, return sc_asn1_decode_object_id error code */ if (r > 0){ @@ -706,7 +706,7 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, } int _pgp_handle_curve25519(sc_card_t *card, - sc_cardctl_openpgp_keygen_info_t key_info, unsigned int do_num) + sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) { if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid) && !sc_compare_oid(&key_info.u.ec.oid, &X25519_oid)) @@ -722,7 +722,7 @@ int _pgp_handle_curve25519(sc_card_t *card, return 1; } -int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t key_info, unsigned int do_num) +int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) { unsigned long flags = 0, ext_flags = 0; @@ -858,7 +858,7 @@ pgp_get_card_features(sc_card_t *card) for (child = blobfa->files; child; child = child->next) { if ((child->id < 0x00c1) || (child->id > 0x00c3)) continue; - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; if (pgp_parse_algo_attr_blob(card, child, &key_info) >= 0) handled_algos += _pgp_add_algo(card, key_info, 0x00fa); } @@ -960,7 +960,7 @@ pgp_get_card_features(sc_card_t *card) * well and therefore added * see OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ for (i = 0x00c1; i <= 0x00c3; i++) { - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; sc_log(card->ctx, "Parsing algorithm attributes DO %uX" , i); @@ -1690,7 +1690,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *blob, *mod_blob, *exp_blob, *pubkey_blob, *blob6e, *blob73, *aa_blob; sc_pkcs15_pubkey_t p15pubkey; - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; unsigned int aa_tag = 0; u8 *data = NULL; size_t len = 0; @@ -2526,13 +2526,11 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, * Internal: update algorithm attribute for new key size (before generating key). **/ static int -pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) +pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *algo_blob = NULL; const unsigned int tag = 0x00C0 | key_info->key_id; - u8 *data; - size_t data_len; int r = SC_SUCCESS; unsigned int i; @@ -2570,16 +2568,16 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - data_len = aoid_len + 1 - 2; /* +1 for algorithm -2 drop 06 len */ - data = malloc(data_len); - if (!data) { + key_info->data_len = aoid_len + 1 - 2; /* +1 for algorithm -2 drop 06 len */ + key_info->data = malloc(key_info->data_len); + if (!key_info->data) { free(aoid); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); } - data[0] = key_info->algorithm; + key_info->data[0] = key_info->algorithm; for (i = 0; i < aoid_len - 2; i++) - data[i + 1] = aoid[i + 2]; + key_info->data[i + 1] = aoid[i + 2]; free(aoid); } @@ -2591,31 +2589,30 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_ if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0) LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS); - data_len = 6; - data = malloc(data_len); - if (!data) + key_info->data_len = 6; + key_info->data = malloc(key_info->data_len); + if (!key_info->data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - data[0] = key_info->algorithm; - ushort2bebytes(data+1, key_info->u.rsa.modulus_len); + key_info->data[0] = key_info->algorithm; + ushort2bebytes(key_info->data+1, key_info->u.rsa.modulus_len); /* OpenPGP Card only accepts 32bit as exponent length field, * although you can import keys with smaller exponent; * thus we don't change rsa.exponent_len, but ignore it here */ - ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS); + ushort2bebytes(key_info->data+3, SC_OPENPGP_MAX_EXP_BITS); /* Import-Format of private key (e,p,q) */ - data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; + key_info->data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; } else { sc_log(card->ctx, "Unknown algorithm id"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - r = pgp_put_data(card, tag, data, data_len); + r = pgp_put_data(card, tag, key_info->data, key_info->data_len); /* Note: pgp_put_data calls pgp_set_blob */ - free(data); LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes"); } else { - sc_cardctl_openpgp_keygen_info_t old_key_info; + sc_cardctl_openpgp_key_gen_store_info_t old_key_info; if (pgp_parse_algo_attr_blob(card, algo_blob, &old_key_info) != SC_SUCCESS || old_key_info.algorithm != key_info->algorithm) @@ -2679,7 +2676,7 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) **/ static int pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, - sc_cardctl_openpgp_keygen_info_t *key_info) + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { u8 fingerprint[SHA_DIGEST_LENGTH]; u8 *fp_buffer = NULL; /* fingerprint buffer, not hashed */ @@ -2720,7 +2717,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* also includes XEDDSA */ key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { - if (key_info->u.ec.ecpoint == NULL || (key_info->u.ec.ecpoint_len) == 0) { + if (key_info->u.ec.ecpointQ == NULL || (key_info->u.ec.ecpointQ_len) == 0) { sc_log(card->ctx, "Error: ecpoint required!"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -2731,8 +2728,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, + 4 /* creation time */ + 1 /* algorithm */ + 1 /* oid len */ - + (key_info->u.ec.oid_len) /* oid */ - + BYTES4BITS(key_info->u.ec.ecpoint_len); /* ecpoint */ + + key_info->u.ec.oidv_len /* oid */ + + key_info->u.ec.ecpointQ_len; /* ecpoint */ /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { @@ -2787,26 +2784,28 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* Algorithm ID, see https://tools.ietf.org/html/rfc6637#section-5 */ *p = key_info->algorithm + 6; p += 1; - *p = key_info->u.ec.oid_len; + *p = key_info->u.ec.oidv_len; p += 1; - memcpy(p, key_info->u.ec.oid.value, key_info->u.ec.oid_len); - p += key_info->u.ec.oid_len; - memcpy(p, key_info->u.ec.ecpoint, BYTES4BITS(key_info->u.ec.ecpoint_len)); + /* TODO Should this be a loop to copy byte be byte? */ + /* Should it be the key_info data and data_len? */ + memcpy(p, key_info->u.ec.oidv.value, key_info->u.ec.oidv_len); + p += key_info->u.ec.oidv_len; + memcpy(p, key_info->u.ec.ecpointQ, key_info->u.ec.ecpointQ_len); /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { /* https://tools.ietf.org/html/rfc6637#section-8 * This is copied from GnuPG's ecdh_params() function in app-openpgp.c */ - p += BYTES4BITS(key_info->u.ec.ecpoint_len); + p += BYTES4BITS(key_info->u.ec.ecpointQ_len); *p = 0x03; /* number of bytes following */ p += 1; *p = 0x01; /* version of this format */ p += 1; - if (key_info->u.ec.ecpoint_len <= 256){ /* ec bit size <= 256 */ + if (key_info->u.ec.key_length <= 256){ /* ec bit size <= 256 */ *p = 0x08; /* KDF algo */ *(p+1) = 0x07; /* KEK algo */ } - else if (key_info->u.ec.ecpoint_len <= 384) { /* ec bit size <= 384 */ + else if (key_info->u.ec.key_length <= 384) { /* ec bit size <= 384 */ *p = 0x09; /* KDF algo */ *(p+1) = 0x08; /* KEK algo */ } @@ -2867,7 +2866,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, * Note that modulus_len, exponent_len is measured in bit. **/ static int -pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) +pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *pk_blob; @@ -2905,14 +2904,14 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in p15pubkey.u.rsa.exponent.len = BYTES4BITS(key_info->u.rsa.exponent_len); } /* ECC */ - /* TODO FIXME? */ + /* TODO FIXME? YES 24-10-06 */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { memset(&p15pubkey, 0, sizeof(p15pubkey)); - p15pubkey.algorithm = key_info->key_type; - p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpoint; - p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpoint_len; + p15pubkey.algorithm = key_info->key_type; /* TODO not set? */ + p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpointQ; + p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpointQ_len; } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -2932,7 +2931,7 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in **/ static int pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, - sc_cardctl_openpgp_keygen_info_t *key_info) + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { time_t ctime = 0; u8 *in = data; @@ -3017,19 +3016,19 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, */ /* GNUK returns 04||x||y */ - if (len != key_info->u.ec.ecpoint_len) + if (len != key_info->u.ec.ecpointQ_len) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - key_info->u.ec.ecpoint = malloc(len); - if (key_info->u.ec.ecpoint == NULL) + key_info->u.ec.ecpointQ = malloc(len); + if (key_info->u.ec.ecpointQ == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); switch (key_info->key_type) { case SC_ALGORITHM_EC: case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: - memcpy(key_info->u.ec.ecpoint, part, len); - key_info->u.ec.ecpoint_len = len; + memcpy(key_info->u.ec.ecpointQ, part, len); + key_info->u.ec.ecpointQ_len = len; break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -3045,6 +3044,8 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, sc_log(card->ctx, "Calculate and store fingerprint"); r = pgp_calculate_and_store_fingerprint(card, ctime, key_info); LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); + /* TODO only try and update pubkey if present */ + /* update pubkey blobs (B601, B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); r = pgp_update_pubkey_blob(card, key_info); @@ -3057,7 +3058,7 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, * Internal: update card->algorithms */ static int -pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) +pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { sc_algorithm_info_t *algo; u8 id = key_info->key_id; @@ -3090,7 +3091,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { algo->algorithm = SC_ALGORITHM_EC; - algo->key_length = (unsigned int)((key_info->u.ec.ecpoint_len)); + algo->key_length = (unsigned int)((key_info->u.ec.ecpointQ_len)); } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -3102,7 +3103,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke * ABI (card ctl): GENERATE ASYMMETRIC KEY PAIR **/ static int -pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) +pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { sc_apdu_t apdu; /* temporary variables to hold APDU params */ @@ -3271,7 +3272,7 @@ set_taglength_tlv(u8 *buffer, unsigned int tag, size_t length) * Internal: build Extended Header list (sec 4.3.3.9 - OpenPGP card spec v.3) **/ static int -pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info, +pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info, u8 **result, size_t *resultlen) { sc_context_t *ctx = card->ctx; @@ -3309,10 +3310,10 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ - components[0] = key_info->u.rsa.e; + components[0] = key_info->u.rsa.exponent; components[1] = key_info->u.rsa.p; components[2] = key_info->u.rsa.q; - componentlens[0] = key_info->u.rsa.e_len; + componentlens[0] = key_info->u.rsa.exponent_len; componentlens[1] = key_info->u.rsa.p_len; componentlens[2] = key_info->u.rsa.q_len; componenttags[0] = 0x91; @@ -3326,18 +3327,18 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info /* The maximum exponent length is 32 bit, as set on card * we use this variable to check against actual exponent_len */ size_t max_e_len_bytes = BYTES4BITS(SC_OPENPGP_MAX_EXP_BITS); - size_t e_len_bytes = BYTES4BITS(key_info->u.rsa.e_len); + size_t e_len_bytes = BYTES4BITS(key_info->u.rsa.exponent_len); if (key_info->u.rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_STDN || key_info->u.rsa.keyformat == SC_OPENPGP_KEYFORMAT_RSA_CRTN){ - components[3] = key_info->u.rsa.n; - componentlens[3] = key_info->u.rsa.n_len; + components[3] = key_info->u.rsa.modulus; + componentlens[3] = key_info->u.rsa.modulus_len; componenttags[3] = 0x97; componentnames[3] = "modulus"; comp_to_add = 4; /* validate */ - if (key_info->u.rsa.n == NULL || key_info->u.rsa.n_len == 0) { + if (key_info->u.rsa.modulus == NULL || key_info->u.rsa.modulus_len == 0) { sc_log(ctx, "Error: Modulus required!"); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -3347,28 +3348,29 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info memset(pritemplate, 0, max_prtem_len); /* maximum 32 bit exponent length allowed on OpenPGP Card */ - assert(key_info->u.rsa.e_len <= SC_OPENPGP_MAX_EXP_BITS); + assert(key_info->u.rsa.exponent_len <= SC_OPENPGP_MAX_EXP_BITS); /* We need to right justify the exponent with allowed exponent length, * e.g. from '01 00 01' to '00 01 00 01' */ - if (key_info->u.rsa.e_len < SC_OPENPGP_MAX_EXP_BITS) { + if (key_info->u.rsa.exponent_len < SC_OPENPGP_MAX_EXP_BITS) { /* create new buffer */ p = calloc(1, max_e_len_bytes); if (!p) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - memcpy(p + (max_e_len_bytes - e_len_bytes), key_info->u.rsa.e, e_len_bytes); + memcpy(p + (max_e_len_bytes - e_len_bytes), key_info->u.rsa.exponent, e_len_bytes); /* set key_info->u.rsa.e to new buffer */ - free(key_info->u.rsa.e); - key_info->u.rsa.e = p; + free(key_info->u.rsa.exponent); + key_info->u.rsa.exponent = p; components[0] = p; - key_info->u.rsa.e_len = SC_OPENPGP_MAX_EXP_BITS; /* we store info in bits */ + key_info->u.rsa.exponent_len = SC_OPENPGP_MAX_EXP_BITS; /* we store info in bits */ componentlens[0] = max_e_len_bytes; /* ... but in bytes for header list */ } } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){ + || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA + || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { components[0] = key_info->u.ec.privateD; componentlens[0] = key_info->u.ec.privateD_len; componenttags[0] = 0x92; @@ -3470,9 +3472,9 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info * ABI (card ctl): store key **/ static int -pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) +pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { - sc_cardctl_openpgp_keygen_info_t pubkey; +// sc_cardctl_openpgp_key_gen_store_info_t pubkey; u8 *data = NULL; size_t len = 0; int r = 0; @@ -3481,7 +3483,7 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) LOG_FUNC_CALLED(card->ctx); - memset(&pubkey, 0, sizeof(pubkey)); +// memset(&pubkey, 0, sizeof(pubkey)); /* PKCS11 loads privkey separately from pubkey as two different operations * So this routine will be called twice to create two different objects. @@ -3506,8 +3508,8 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) /* set algorithm attributes */ /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){ - has_pubkey = (key_info->u.rsa.n && key_info->u.rsa.n_len && - key_info->u.rsa.e && key_info->u.rsa.e_len); + has_pubkey = (key_info->u.rsa.modulus && key_info->u.rsa.modulus_len && + key_info->u.rsa.exponent && key_info->u.rsa.exponent_len); has_privkey = (has_pubkey && key_info->u.rsa.p && key_info->u.rsa.p_len && key_info->u.rsa.q && key_info->u.rsa.q_len); @@ -3532,19 +3534,19 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) } /* we only support exponent of maximum 32 bits */ - if (key_info->u.rsa.e_len > SC_OPENPGP_MAX_EXP_BITS) { + if (key_info->u.rsa.exponent_len > SC_OPENPGP_MAX_EXP_BITS) { sc_log(card->ctx, "Exponent %"SC_FORMAT_LEN_SIZE_T"u-bit (>32) is not supported.", - key_info->u.rsa.e_len); + key_info->u.rsa.exponent_len); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - pubkey.key_id = key_info->key_id; - pubkey.algorithm = key_info->algorithm; - pubkey.u.rsa.modulus = key_info->u.rsa.n; - pubkey.u.rsa.modulus_len = key_info->u.rsa.n_len; - pubkey.u.rsa.exponent = key_info->u.rsa.e; - pubkey.u.rsa.exponent_len = key_info->u.rsa.e_len; +// pubkey.key_id = key_info->key_id; +// pubkey.algorithm = key_info->algorithm; +// pubkey.u.rsa.modulus = key_info->u.rsa.modulus; +// pubkey.u.rsa.modulus_len = key_info->u.rsa.modulus_len; +// pubkey.u.rsa.exponent = key_info->u.rsa.exponent; +// pubkey.u.rsa.exponent_len = key_info->u.rsa.exponent_len; } /* ECC */ @@ -3557,17 +3559,17 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) if (!has_pubkey && !has_privkey) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - memset(&pubkey, 0, sizeof(pubkey)); - pubkey.key_id = key_info->key_id; - pubkey.algorithm = key_info->algorithm; - pubkey.u.ec.oid = key_info->u.ec.oid; - pubkey.u.ec.oid_len = key_info->u.ec.oid_len; - pubkey.u.ec.ecpoint = key_info->u.ec.ecpointQ; - pubkey.u.ec.ecpoint_len = key_info->u.ec.ecpointQ_len; - } +// memset(&pubkey, 0, sizeof(pubkey)); +// pubkey.key_id = key_info->key_id; +// pubkey.algorithm = key_info->algorithm; +// +// pubkey.u.ec.oid_len = key_info->u.ec.oid_len; +// pubkey.u.ec.oid = key_info->u.ec.oid; +// pubkey.u.ec.ecpointQ = key_info->u.ec.ecpointQ; +// pubkey.u.ec.ecpointQ_len = key_info->u.ec.ecpointQ_len; + + r = pgp_update_new_algo_attr(card, key_info); - if (has_pubkey) { - r = pgp_update_new_algo_attr(card, &pubkey); LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); } @@ -3588,15 +3590,15 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) if (has_pubkey) { /* calculate and store fingerprint */ sc_log(card->ctx, "Calculate and store fingerprint"); - r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, &pubkey); - + r = pgp_calculate_and_store_fingerprint(card, key_info->creationtime, key_info); LOG_TEST_RET(card->ctx, r, "Cannot store fingerprint"); + /* update pubkey blobs (B601,B801, A401) */ sc_log(card->ctx, "Update blobs holding pubkey info."); - r = pgp_update_pubkey_blob(card, &pubkey); + r = pgp_update_pubkey_blob(card, key_info); sc_log(card->ctx, "Update card algorithms"); - pgp_update_card_algorithms(card, &pubkey); + pgp_update_card_algorithms(card, key_info); } err: @@ -3718,11 +3720,11 @@ pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) break; #ifdef ENABLE_OPENSSL case SC_CARDCTL_OPENPGP_GENERATE_KEY: - r = pgp_gen_key(card, (sc_cardctl_openpgp_keygen_info_t *) ptr); + r = pgp_gen_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *) ptr); LOG_FUNC_RETURN(card->ctx, r); break; case SC_CARDCTL_OPENPGP_STORE_KEY: - r = pgp_store_key(card, (sc_cardctl_openpgp_keystore_info_t *) ptr); + r = pgp_store_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *) ptr); LOG_FUNC_RETURN(card->ctx, r); break; #endif /* ENABLE_OPENSSL */ diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index b3eed71a33..1fa2d621d9 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -24,6 +24,7 @@ #include #include "libopensc/types.h" +#include "libopensc/opensc.h" #ifdef __cplusplus extern "C" { @@ -880,56 +881,43 @@ typedef struct sc_cardctl_piv_genkey_info_st { #define SC_OPENPGP_MAX_EXP_BITS 0x20 /* maximum exponent length supported in bits */ -typedef struct sc_cardctl_openpgp_keygen_info { +typedef struct sc_cardctl_openpgp_key_gen_store_info { u8 key_id; /* SC_OPENPGP_KEY_... */ u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ unsigned long key_type; /* SC_ALGORITHM_... */ - union { - struct { - u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ - u8 *modulus; /* New-generated pubkey info responded from the card */ - size_t modulus_len; /* Length of modulus in bit */ - u8 *exponent; - size_t exponent_len; /* Length of exponent in bit */ - } rsa; - struct { - u8 keyformat; /* SC_OPENPGP_KEYFORMAT_EC_... */ - u8 *ecpoint; - size_t ecpoint_len; - struct sc_object_id oid; - u8 oid_len; - size_t key_length; - } ec; - } u; -} sc_cardctl_openpgp_keygen_info_t; - -typedef struct sc_cardctl_openpgp_keystore_info { - u8 key_id; /* SC_OPENPGP_KEY_... */ - u8 algorithm; /* SC_OPENPGP_KEYALGO_... */ + u8 *data; /* algo blob data */ + size_t data_len; /* bytes */ + time_t creationtime; /* when private generated or stored */ union { struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ - u8 *e; - size_t e_len; /* Length of exponent in bit */ + u8 *exponent; /* exponent to store or generated */ + size_t exponent_len; /* bit */ u8 *p; size_t p_len; u8 *q; size_t q_len; - u8 *n; - size_t n_len; + u8 *modulus; /* modulus to store or generated */ + size_t modulus_len; /* bits - field_length */ } rsa; struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_EC_... */ - u8 *privateD; - size_t privateD_len; - u8 *ecpointQ; - size_t ecpointQ_len; - struct sc_object_id oid; - u8 oid_len; + u8 *privateD; /* private key to store */ + size_t privateD_len; /* bytes */ + u8 *ecpointQ; /* public key to store or generated */ + size_t ecpointQ_len; /* bytes */ + struct sc_object_id oid; /* RFC8410 OID */ + /* + * sc_object_id oidv is misused here to contain the bytes + * of the values from TLV of OID DER TLV + */ + struct sc_object_id oidv; + size_t oidv_len; + size_t key_length; /* field_length bits */ } ec; } u; - time_t creationtime; -} sc_cardctl_openpgp_keystore_info_t; +} sc_cardctl_openpgp_key_gen_store_info_t; + /* * SmartCard-HSM diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index e4bba7d479..96fa23616d 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -103,6 +103,61 @@ static int openpgp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_FUNC_CALLED(p15card->card->ctx); LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS); } +/** + * Set algorithm and check if card supports it + * @param p15card sc_pkcs15_card_t + * @param type SC_PKCS15_TYPE_* + * @param key_id openspgp id + * @param &algorithm SC_OPENPGP_KEYALGO_* + + * @returns 0 or error + */ + +static int openpgp_set_algorithm(sc_pkcs15_card_t *p15card, + u8 key_id, unsigned long type, u8 *algo) +{ + sc_card_t *card = p15card->card; + + if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && + card->type < SC_CARD_TYPE_OPENPGP_V3) { + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + switch (key_id) { + case SC_OPENPGP_KEY_SIGN: + case SC_OPENPGP_KEY_AUTH: + switch (type) { + case SC_PKCS15_TYPE_PRKEY_EC: + case SC_PKCS15_TYPE_PUBKEY_EC: + *algo = SC_OPENPGP_KEYALGO_ECDSA; + return SC_SUCCESS; + break; + case SC_PKCS15_TYPE_PRKEY_EDDSA: + case SC_PKCS15_TYPE_PUBKEY_EDDSA: + *algo = SC_OPENPGP_KEYALGO_EDDSA; + return SC_SUCCESS; + break; + } + break; + case SC_OPENPGP_KEY_ENCR: + switch (type) { + case SC_PKCS15_TYPE_PRKEY_EC: + case SC_PKCS15_TYPE_PUBKEY_EC: + *algo = SC_OPENPGP_KEYALGO_ECDH; + return SC_SUCCESS; + break; + case SC_PKCS15_TYPE_PRKEY_XEDDSA: + case SC_PKCS15_TYPE_PUBKEY_XEDDSA: + *algo = SC_OPENPGP_KEYALGO_ECDH; + return SC_SUCCESS; + break; + } + break; + } + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid algorithm of openpgp slot"); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); +} /** * Stores an external key on the card. @@ -115,9 +170,17 @@ static int openpgp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { + /* Maybe called internally to write public key because PKCS11 stores + * private and public keyis in separate operations. In this case + * the object will have a type of SC_PKCS15_TYPE_PUBLIC_* + * and key will be sc_pkcs15_pubkey_t + */ sc_card_t *card = p15card->card; + sc_pkcs15_pubkey_t *pubkey = (sc_pkcs15_pubkey_t *) key; /* maybe pubkey */ sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; - sc_cardctl_openpgp_keystore_info_t key_info = {0}; + sc_pkcs15_pubkey_info_t *pubkinfo = (sc_pkcs15_pubkey_info_t *) obj->data; + + sc_cardctl_openpgp_key_gen_store_info_t key_info = {0}; int r; LOG_FUNC_CALLED(card->ctx); @@ -125,34 +188,32 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, switch(obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.key_id = kinfo->id.value[0]; - key_info.u.rsa.e = key->u.rsa.exponent.data; - key_info.u.rsa.e_len = key->u.rsa.exponent.len * 8; /* use bits instead of bytes */ + key_info.u.rsa.exponent = key->u.rsa.exponent.data; + key_info.u.rsa.exponent_len = key->u.rsa.exponent.len * 8; /* use bits instead of bytes */ key_info.u.rsa.p = key->u.rsa.p.data; key_info.u.rsa.p_len = key->u.rsa.p.len; key_info.u.rsa.q = key->u.rsa.q.data; key_info.u.rsa.q_len = key->u.rsa.q.len; - key_info.u.rsa.n = key->u.rsa.modulus.data; - key_info.u.rsa.n_len = key->u.rsa.modulus.len * 8; /* use bits instead of bytes */ + key_info.u.rsa.modulus = key->u.rsa.modulus.data; + key_info.u.rsa.modulus_len = key->u.rsa.modulus.len * 8; /* use bits instead of bytes */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); break; + case SC_PKCS15_TYPE_PRKEY_EC: case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: - if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && - card->type < SC_CARD_TYPE_OPENPGP_V3) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - } - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); - key_info.algorithm = (kinfo->id.value[0] == SC_OPENPGP_KEY_ENCR) - ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ - : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); + + r = openpgp_set_algorithm(p15card, kinfo->id.value[0], obj->type, &key_info.algorithm); + LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id"); + key_info.key_id = kinfo->id.value[0]; key_info.u.ec.privateD = key->u.ec.privateD.data; key_info.u.ec.privateD_len = key->u.ec.privateD.len; + /* key->u.ec.ecpointQ.len is optional with private key */ if (key->u.ec.ecpointQ.len) { key_info.u.ec.ecpointQ = malloc(key->u.ec.ecpointQ.len); if (!key_info.u.ec.ecpointQ) @@ -163,11 +224,56 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.u.ec.oid = key->u.ec.params.id; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); break; + + /* Unlike RSA which includes modulus in privkey, + * PKCS11 stores pubkey as separate operation + */ + case SC_PKCS15_TYPE_PUBKEY_EC: + case SC_PKCS15_TYPE_PUBKEY_EDDSA: + case SC_PKCS15_TYPE_PUBKEY_XEDDSA: + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); + + r = openpgp_set_algorithm(p15card, pubkinfo->id.value[0], obj->type, &key_info.algorithm); + LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id"); + + key_info.key_id = pubkinfo->id.value[0]; + if (pubkey->u.ec.ecpointQ.len) { + key_info.u.ec.ecpointQ = malloc(pubkey->u.ec.ecpointQ.len); + if (!key_info.u.ec.ecpointQ) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + memcpy(&key_info.u.ec.ecpointQ, &pubkey->u.ec.ecpointQ.value, pubkey->u.ec.ecpointQ.len); + key_info.u.ec.ecpointQ_len = pubkey->u.ec.ecpointQ.len; + + } + /* copy oid, oid_len and key_length from pubkey */ + + if (pubkey->u.ec.params.der.len > 2) + key_info.u.ec.oidv_len = pubkey->u.ec.params.der.value[1]; + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + for ( size_t i = 0; (i < key_info.u.ec.oidv_len) && (i+2 < pubkey->u.ec.params.der.len); i++){ + key_info.u.ec.oidv.value[i] = pubkey->u.ec.params.der.value[i+2]; + } + key_info.u.ec.oidv.value[key_info.u.ec.oidv_len] = -1; + + /* copy sc_object_id too */ + key_info.u.ec.oid = pubkey->u.ec.params.id; + + key_info.u.ec.key_length = pubkey->u.ec.params.field_length; + key_info.key_type = pubkey->u.ec.params.key_type; + + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + break; + default: r = SC_ERROR_NOT_SUPPORTED; sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r)); } +err: + /* TODO cleanup key_info */ + LOG_FUNC_RETURN(card->ctx, r); } @@ -182,7 +288,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { sc_context_t *ctx = card->ctx; - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; sc_pkcs15_id_t *kid = &(required->id); int r; @@ -251,6 +357,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, key_info.u.rsa.modulus = NULL; free(key_info.u.rsa.exponent); key_info.u.rsa.exponent = NULL; + free(key_info.data); LOG_FUNC_RETURN(ctx, r); } @@ -266,7 +373,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { sc_context_t *ctx = card->ctx; - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data; sc_pkcs15_id_t *kid = &(required->id); struct sc_ec_parameters *info_ec = @@ -307,25 +414,33 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR) ? SC_OPENPGP_KEYALGO_ECDH /* ECDH for slot 2 only */ : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */ - key_info.u.ec.ecpoint_len = 1 + 2 * BYTES4BITS(required->field_length); + key_info.u.ec.ecpointQ_len = 1 + 2 * BYTES4BITS(required->field_length); break; case SC_ALGORITHM_EDDSA: key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* only sign */ - key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); + key_info.u.ec.ecpointQ_len = BYTES4BITS(required->field_length); break; case SC_ALGORITHM_XEDDSA: /* TODO may need to look at MSE, and how sign XEDDSA certificate */ key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be used to sign too */ - key_info.u.ec.ecpoint_len = BYTES4BITS(required->field_length); + key_info.u.ec.ecpointQ_len = BYTES4BITS(required->field_length); break; } /* copying info_ec.id works for any EC ECDH EdDSA keys */ if (info_ec->der.len > 2) - key_info.u.ec.oid = info_ec->id; /* copy sc_object_id */ + key_info.u.ec.oidv_len = info_ec->der.value[1]; else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + for (size_t i=0; (i < key_info.u.ec.oidv_len) && (i+2 < info_ec->der.len); i++){ + key_info.u.ec.oidv.value[i] = info_ec->der.value[i+2]; + } + key_info.u.ec.oidv.value[key_info.data_len] = -1; + + /* copy id also */ + key_info.u.ec.oid = info_ec->id; + /* generate key on card */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed"); @@ -334,18 +449,17 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, sc_log(ctx, "Set output ecpoint info"); pubkey->algorithm = key_info.key_type; - pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpoint_len; - pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpoint_len); + pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpointQ_len; + pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpointQ_len); if (pubkey->u.ec.ecpointQ.value == NULL) { r = SC_ERROR_NOT_ENOUGH_MEMORY; goto err; } - memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpoint, key_info.u.ec.ecpoint_len); + memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpointQ, key_info.u.ec.ecpointQ_len); err: - if (key_info.u.ec.ecpoint) - free(key_info.u.ec.ecpoint); + free(key_info.u.ec.ecpointQ); LOG_FUNC_RETURN(ctx, r); } @@ -425,18 +539,33 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile sc_pkcs15_id_t *cid; sc_pkcs15_data_info_t *dinfo; u8 buf[254]; - int r; + int r = 0; + sc_pkcs15_pubkey_t *pubkey = NULL; + LOG_FUNC_CALLED(card->ctx); switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: - case SC_PKCS15_TYPE_PUBKEY: - /* For these two type, store_data just don't need to do anything. - * All have been done already before this function is called */ r = SC_SUCCESS; break; + case SC_PKCS15_TYPE_PUBKEY: + + if (obj->type == SC_PKCS15_TYPE_PUBKEY_EC || + obj->type == SC_PKCS15_TYPE_PUBKEY_EDDSA || + obj->type == SC_PKCS15_TYPE_PUBKEY_XEDDSA) { + r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to get pubkey from spki"); + + /* PKCS11 stores private and public keys as two operations */ + r = openpgp_store_key (profile, p15card, obj, (void *)pubkey); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to store pubkey fromk spki"); + + r = SC_SUCCESS; + } + break; + case SC_PKCS15_TYPE_CERT: cinfo = (sc_pkcs15_cert_info_t *) obj->data; cid = &(cinfo->id); @@ -517,6 +646,8 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile default: r = SC_ERROR_NOT_IMPLEMENTED; } +err: + sc_pkcs15_free_pubkey(pubkey); sc_file_free(file); LOG_FUNC_RETURN(card->ctx, r); } @@ -530,7 +661,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = { openpgp_create_pin, NULL, /* select key reference */ openpgp_create_key, - openpgp_store_key, + openpgp_store_key, /* May be called for private and public key twice */ openpgp_generate_key, NULL, NULL, /* encode private/public key */ NULL, /* finalize_card */ diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index dfd72eab9d..4b7510fd49 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -477,7 +477,7 @@ static int do_dump_do(sc_card_t *card, unsigned int tag) int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) { int r; - sc_cardctl_openpgp_keygen_info_t key_info; + sc_cardctl_openpgp_key_gen_store_info_t key_info; u8 fingerprints[60]; sc_path_t path; sc_file_t *file; @@ -492,7 +492,7 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) if (!keytype) keytype = "RSA2048"; - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); + memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); /* generate key depending on keytype passed */ if (strncasecmp("RSA", keytype, strlen("RSA")) == 0) { From dfab75cf749d931ff1a19c5d27a438da88e64d7b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 18 Oct 2024 08:02:01 -0500 Subject: [PATCH 3727/4321] pkcs11-tool.c - softhsm problem with CKM_RSA_PKCS_OAEP skip for now On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 35961e98ef..bab27053e3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -8354,9 +8354,9 @@ static int test_decrypt(CK_SESSION_HANDLE sess) #else for (n = 0; n < num_mechs; n++) { switch (mechs[n]) { - case CKM_RSA_PKCS_OAEP: +// case CKM_RSA_PKCS_OAEP: /* one more OAEP test with param .. */ - errors += encrypt_decrypt(sess, mechs[n], privKeyObject, "ABC", 3); +// errors += encrypt_decrypt(sess, mechs[n], privKeyObject, "ABC", 3); /* fall through */ case CKM_RSA_PKCS: case CKM_RSA_X_509: From 438ead232a2b856d343c5e89555d16a86aaa8953 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 18 Oct 2024 08:03:42 -0500 Subject: [PATCH 3728/4321] tests/Makefile.am and script so all can pass test/Makefile.am - remove the XFAILS_TESTS tests/common.sh - show version of softhsm2, and add sleep to avoid any problems with the softhsm2 programs. tests/test-pkcs11-tool-sym-crypt-test.sh and tests/test-pkcs11-tool-unwrap-wrap-test.sh - need out of source build changes tests/test-pkcs11-tool-test-threads.sh and tests/test-pkcs11-tool-test.sh - Use 'opensc-tool -a' to test for a reader with a card before trying some of thes tests. If not found skip these tests. Usefull when run from system with real toekns On branch X25519-improvements-2 On branch X25519-improvements-2 Changes to be committed: modified: Makefile.am modified: common.sh modified: test-pkcs11-tool-sym-crypt-test.sh modified: test-pkcs11-tool-test-threads.sh modified: test-pkcs11-tool-test.sh modified: test-pkcs11-tool-unwrap-wrap-test.sh --- tests/Makefile.am | 5 +-- tests/common.sh | 3 ++ tests/test-pkcs11-tool-sym-crypt-test.sh | 3 +- tests/test-pkcs11-tool-test-threads.sh | 12 +++++- tests/test-pkcs11-tool-test.sh | 46 +++++++++++++++------- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 3 +- 6 files changed, 51 insertions(+), 21 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index e02795b956..8124b06ecf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -55,6 +55,5 @@ TESTS += test-p11test.sh endif endif endif -XFAIL_TESTS = \ - test-pkcs11-tool-test-threads.sh \ - test-pkcs11-tool-test.sh +# no tests expected to fail +#XFAIL_TESTS = diff --git a/tests/common.sh b/tests/common.sh index b1a3bbf904..9d98d26d3c 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -78,6 +78,7 @@ function softhsm_initialize() { mkdir ".tokens" export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") # Init token + softhsm2-util --version softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" } @@ -104,9 +105,11 @@ function card_setup() { function softhsm_cleanup() { rm .softhsm2.conf rm -rf ".tokens" + sleep 1 } function card_cleanup() { softhsm_cleanup rm 0{1,2,3,4}.pub + sleep 1 } diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index d6b36f0cff..9956369a08 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -1,6 +1,7 @@ #!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} -source common.sh +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index bf2a060eeb..b3d4364955 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -6,13 +6,23 @@ source $SOURCE_PATH/tests/common.sh # Test our PKCS #11 module here P11LIB="../src/pkcs11/.libs/opensc-pkcs11.so" +OPENSC_TOOL="../src/tools/opensc-tool" +echo "check for opensc-tool" +if [[ -f $OPENSC_TOOL ]] ; then +echo "trying opensc-tool -a" + $OPENSC_TOOL -a + if [[ "$?" -ne "0" ]] ; then + echo "No token found, skipping Test pkcs11 threads " + exit 77 + fi +fi + echo "=======================================================" echo "Test pkcs11 threads IN " echo "=======================================================" $PKCS11_TOOL --test-threads IN -L --module="$P11LIB" assert $? "Failed running tests" - echo "=======================================================" echo "Test pkcs11 threads ILGISLT0 " echo "=======================================================" diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 1a96cbd754..a22c6cd24c 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -23,21 +23,37 @@ echo "=======================================================" $PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" assert $? "Failed running tests" -echo "=======================================================" -echo "Test objects URI" -echo "=======================================================" -$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null -assert $? "Failed running objects URI tests" -$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null -assert $? "Failed running objects URI tests" - -echo "=======================================================" -echo "Test slots URI" -echo "=======================================================" -$PKCS11_TOOL -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null -assert $? "Failed running slots URI tests" -$PKCS11_TOOL -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null -assert $? "Failed running slots URI tests" +# done with $P11LIB + +# test if OpenSC can access a reader with a token using OpenSC module +# to test how OpenSC creates +# softhsm2 module does not count +# +OPENSC_TOOL="../src/tools/opensc-tool" +if [[ -f "$OPENSC_TOOL" ]] ; then + $OPENSC_TOOL -a + if [[ "$?" -eq "0" ]] ; then + echo "=======================================================" + echo "Test objects URI" + echo "=======================================================" + $PKCS11_TOOL -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null + assert $? "Failed running objects URI tests" + $PKCS11_TOOL -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null + assert $? "Failed running objects URI tests" + + echo "=======================================================" + echo "Test slots URI" + echo "=======================================================" + $PKCS11_TOOL -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null + assert $? "Failed running slots URI tests" + $PKCS11_TOOL -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null + assert $? "Failed running slots URI tests" + else + echo "Skipping URI tests because no token found" + fi +else + echo "Skipping URI tests because because opensc-tool not found" +fi echo "=======================================================" echo "Cleanup" diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 0072d0406a..1cb4ea175a 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -1,5 +1,6 @@ #!/bin/bash -source common.sh +SOURCE_PATH=${SOURCE_PATH:-..} +source $SOURCE_PATH/tests/common.sh echo "=======================================================" echo "Setup SoftHSM" From d4e2023398b1254fc954c5bba21ac4893028a544 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 22 Oct 2024 06:50:20 -0500 Subject: [PATCH 3729/4321] test-pkcs11-tool-test.sh and tests/Makefile.am return 77 if opensc-tool can not be found. Only run test-pkcs11-tool-test.sh "if ENABLE_OPENSSL" On branch X25519-improvements-2 Changes to be committed: modified: Makefile.am modified: test-pkcs11-tool-test.sh --- tests/Makefile.am | 2 +- tests/test-pkcs11-tool-test.sh | 46 +++++++++++----------------------- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 8124b06ecf..be8216834f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -40,12 +40,12 @@ dist_noinst_SCRIPTS = common.sh \ TESTS = \ test-manpage.sh \ test-duplicate-symbols.sh \ - test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ test-pkcs11-tool-sym-crypt-test.sh if ENABLE_OPENSSL TESTS += \ + test-pkcs11-tool-test.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-unwrap-wrap-test.sh \ test-pkcs11-tool-import.sh diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index a22c6cd24c..94a5f4b527 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -23,37 +23,21 @@ echo "=======================================================" $PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" assert $? "Failed running tests" -# done with $P11LIB - -# test if OpenSC can access a reader with a token using OpenSC module -# to test how OpenSC creates -# softhsm2 module does not count -# -OPENSC_TOOL="../src/tools/opensc-tool" -if [[ -f "$OPENSC_TOOL" ]] ; then - $OPENSC_TOOL -a - if [[ "$?" -eq "0" ]] ; then - echo "=======================================================" - echo "Test objects URI" - echo "=======================================================" - $PKCS11_TOOL -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null - assert $? "Failed running objects URI tests" - $PKCS11_TOOL -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null - assert $? "Failed running objects URI tests" - - echo "=======================================================" - echo "Test slots URI" - echo "=======================================================" - $PKCS11_TOOL -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null - assert $? "Failed running slots URI tests" - $PKCS11_TOOL -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null - assert $? "Failed running slots URI tests" - else - echo "Skipping URI tests because no token found" - fi -else - echo "Skipping URI tests because because opensc-tool not found" -fi +echo "=======================================================" +echo "Test objects URI" +echo "=======================================================" +$PKCS11_TOOL --module "${P11LIB}" -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null +assert $? "Failed running objects URI tests" +$PKCS11_TOOL --module "${P11LIB}" -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null +assert $? "Failed running objects URI tests" + +echo "=======================================================" +echo "Test slots URI" +echo "=======================================================" +$PKCS11_TOOL --module "${P11LIB}" -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null +assert $? "Failed running slots URI tests" +$PKCS11_TOOL --module "${P11LIB}" -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null +assert $? "Failed running slots URI tests" echo "=======================================================" echo "Cleanup" From afbcf77a4cc9cfb84cfb0c0f04e3c8c691df00de Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 29 Oct 2024 14:53:48 -0500 Subject: [PATCH 3730/4321] pkcs15-init.c - Improve parsing of keys that uses ecparms When generating or importing a key that uses ecparams, remove EdDSA, xeddsa and ECDH which are not complete. Instead support the names EC, Ed25519, Ed448, X25519, X448, edwards25519, curve25519 and cv25519. --- src/tools/pkcs15-init.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 26b0833316..c7e001c9be 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -728,10 +728,7 @@ static const struct alg_spec alg_types_sym[] = { static const struct alg_spec alg_types_asym[] = { { "rsa", SC_ALGORITHM_RSA, 2048 }, /* new default */ { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, - { "ec", SC_ALGORITHM_EC, 0 }, - { "EdDSA", SC_ALGORITHM_EDDSA, 0 }, /* RFC 8410 section 8 */ - { "xeddsa", SC_ALGORITHM_XEDDSA, 0 }, - { "ECDH", SC_ALGORITHM_XEDDSA, 0 }, /* RFC 8410 section 8 */ + { "ec", SC_ALGORITHM_EC, 0 }, /* keybits derived from curve */ /* RFC 8410 */ { "Ed25519", SC_ALGORITHM_EDDSA, 255 }, /* RFC 8410 and gunpg */ { "Ed448", SC_ALGORITHM_EDDSA, 448 }, @@ -751,6 +748,7 @@ static int parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *keybits, struct sc_pkcs15_prkey *prkey) { int i, types_idx = -1, algorithm = -1; + unsigned int user_keybits = 0; char *end; for (i = 0; types[i].spec; i++) { @@ -770,19 +768,30 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key if (*spec == '/' || *spec == '-' || *spec == ':') spec++; - /* if we have everything for EDDSA or XEDDSA */ - if (*spec == 0x00 && *keybits && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { - prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* correct case */ - *keybits = types[types_idx].keybits; + /* prkey is required for keys that use ecparms */ + if (*spec == '\0' && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { + if ((prkey->u.ec.params.named_curve = strdup(types[types_idx].spec)) == NULL) /* correct case */ + return SC_ERROR_OUT_OF_MEMORY; return algorithm; } - if (*spec) { - if (isalpha((unsigned char)*spec) && algorithm == SC_ALGORITHM_EC && prkey) - prkey->u.ec.params.named_curve = strdup(spec); - else if (isalpha((unsigned char)*spec) && (algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { - prkey->u.ec.params.named_curve = strdup(types[types_idx].spec); /* copy correct case */ - } else { + if (*spec != '\0') { + if (isalpha((unsigned char)*spec) && algorithm == SC_ALGORITHM_EC && prkey) { + if ((prkey->u.ec.params.named_curve = strdup(spec)) == NULL) /* pass EC curve name */ + return SC_ERROR_OUT_OF_MEMORY; + } else if ((algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) && prkey) { + if ((prkey->u.ec.params.named_curve = strdup(types[types_idx].spec)) == NULL) /* copy correct case */ + return SC_ERROR_OUT_OF_MEMORY; + user_keybits = (unsigned)strtoul(spec, &end, 10); + if (*end) { + util_error("Invalid number of key bits \"%s\"", spec); + return SC_ERROR_INVALID_ARGUMENTS; + } + if (user_keybits != *keybits) { + util_error("If specified, number of key bits must be \"%d\" for \"%s\"", *keybits, types[types_idx].spec); + return SC_ERROR_INVALID_ARGUMENTS; + } + } else { /* rsa or symetric key */ *keybits = (unsigned)strtoul(spec, &end, 10); if (*end) { util_error("Invalid number of key bits \"%s\"", spec); From acb57007becb0e40869e020d9125fdc3bc1ba7a8 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 29 Oct 2024 15:23:22 -0500 Subject: [PATCH 3731/4321] pkcs15-openpgp.c - fixup spelling --- src/pkcs15init/pkcs15-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 96fa23616d..e54c0fad42 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -171,7 +171,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { /* Maybe called internally to write public key because PKCS11 stores - * private and public keyis in separate operations. In this case + * private and public keys in separate operations. In this case * the object will have a type of SC_PKCS15_TYPE_PUBLIC_* * and key will be sc_pkcs15_pubkey_t */ From d070ecb4a129b2751d3d9b419e3b3e32ae2dedc7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 30 Oct 2024 08:43:45 -0500 Subject: [PATCH 3732/4321] pkcs15-init.c - fixup spelling On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index c7e001c9be..576bb78add 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -791,7 +791,7 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key util_error("If specified, number of key bits must be \"%d\" for \"%s\"", *keybits, types[types_idx].spec); return SC_ERROR_INVALID_ARGUMENTS; } - } else { /* rsa or symetric key */ + } else { /* rsa or symmetric key */ *keybits = (unsigned)strtoul(spec, &end, 10); if (*end) { util_error("Invalid number of key bits \"%s\"", spec); From 5d1aaa14c72e92d9934bd3727502ff68ac9cfbbf Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 30 Oct 2024 09:45:51 -0500 Subject: [PATCH 3733/4321] pkcs11-tool.c - fixing CKM_HKDF_DERIVE and test for eckey As suggested in comments: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1822119938 reverted the test in derive_key so CKM_ECDH1_DERIVE works https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1816358015 tests if eckey is not NULL and some other fixes. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bab27053e3..e512ad8e4a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4270,7 +4270,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #ifdef ENABLE_OPENSSL /* Return PKCS11 key type based on OpenSSL EVP_PKEY type * which are support by PKCS11 and OpenSSL used when compiling. - * PKCS11 defines CKK_EC_EDWARDS for both Ed25529 and X448 + * PKCS11 defines CKK_EC_EDWARDS for both Ed25529 and Ed448 * and CKK_EC_MONTGOMERY for X25519 and X448. * If requested, return pointer to struct ec_curve_info containing OID and size */ @@ -5363,10 +5363,12 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EVP_PKEY_get0_EC_KEY(pkey); - ecpoint = EC_KEY_get0_public_key(eckey); - ecgroup = EC_KEY_get0_group(eckey); + if (eckey) { + ecpoint = EC_KEY_get0_public_key(eckey); + ecgroup = EC_KEY_get0_group(eckey); + } - if (!ecpoint || !ecgroup) + if (!eckey || !ecpoint || !ecgroup) util_fatal("Failed to parse peer EC key from %s", opt_input); #else if (EVP_PKEY_get_group_name(pkey, name, sizeof(name), &len) != 1 || @@ -5389,10 +5391,14 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #if OPENSSL_VERSION_NUMBER < 0x30000000L buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + if (buf_size == 0) + util_fatal("Failed to parse peer EC key \n"); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) util_fatal("malloc() failure\n"); buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL); + if (buf_size == 0) + util_fatal("Failed to parse peer EC key \n"); #else EC_GROUP_free(ecgroup); EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); @@ -5415,7 +5421,7 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #endif EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); if (buf_size == 0) - util_fatal("Unable to get of peer key\n"); + util_fatal("Unable to get public key of peer\n"); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) util_fatal("malloc() failure\n"); @@ -5625,9 +5631,9 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) if (!find_mechanism(slot, CKF_DERIVE|opt_allow_sw, NULL, 0, &opt_mechanism)) util_fatal("Derive mechanism not supported"); - switch (key_type) { - case CKK_EC: - case CKK_EC_MONTGOMERY: + switch(opt_mechanism) { + case CKM_ECDH1_COFACTOR_DERIVE: + case CKM_ECDH1_DERIVE: derived_key = derive_ec_key(session, key, opt_mechanism); break; case CKM_HKDF_DERIVE: From eac85b20ba7bc4411787733228a1d948217d01c4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 30 Oct 2024 16:52:47 -0500 Subject: [PATCH 3734/4321] pkcs15-pubkey.c CKA_EC_POINT ::= OCTET STRING Remove code that falsely retuned EC POINT as BIT STRING as based on https://github.com/OpenSC/OpenSC/issues/3000 which has been withdrawn. The code will still accept an EC_POINT as either OCTET STRING or BIT STRING. The EC POINT when returned in SPKI format still uses BIT STRING. On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 45 ++++++++++++----------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index ab4f027843..2d0e5fa3f9 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -512,8 +512,7 @@ sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_obje sc_log(ctx, "Key path %s", sc_print_path(&pubkey->path)); - if (spki_value) - free(spki_value); + free(spki_value); return r; } @@ -668,7 +667,7 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ecpoint_len:%" SC_FORMAT_LEN_SIZE_T "u", ecpoint_len); /* if from bit string */ if (asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) - ecpoint_len = (ecpoint_len + 7) / 8; /* bits to bytes */ + ecpoint_len = BYTES4BITS(ecpoint_len); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ecpoint_len:%" SC_FORMAT_LEN_SIZE_T "u", ecpoint_len); if (*ecpoint_data != 0x04) { @@ -695,23 +694,16 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, * PKCS11 does not define CKA_VALUE for a pub key * But some PKCS11 modules define a CKA_VALUE for a public key * and PKCS11 says ECPOINT is encoded as "DER-encoding of ANSI X9.62 ECPoint value Q" - * But ANSI X9.62 (early draft at least) says encode as BIT STRING + * But ANSI X9.62 (early draft at least) says encode as OCTET STRING * IETF encodes it in SubjectPublicKeyInfo (SPKI) in BIT STRING - * PKCS11 V3 does add CKA_PUBLIC_KEY_INFO as SPKI * For now return as OCTET STRING. */ - volatile int gdb_test = 0; /* 0 - OCTET STRING (PKCS15 RAW) 1 - BIT STRING (SPKI) */ LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); - if (gdb_test == 0) { - key_len = key->ecpointQ.len; - sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); - } else { - key_len = key->ecpointQ.len * 8; /* encode in bit string */ - sc_format_asn1_entry(asn1_ec_pointQ + 1, key->ecpointQ.value, &key_len, 1); - } + key_len = key->ecpointQ.len; + sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key_len, 1); LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen)); @@ -743,7 +735,7 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, } if (asn1_ec_pointQ[1].flags & SC_ASN1_PRESENT) - ecpoint_len = (ecpoint_len + 7) / 8; + ecpoint_len = BYTES4BITS(ecpoint_len); key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; @@ -752,9 +744,6 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } -/* This is a change from previous code that used OCTET STRING - * But RFC 8410 and PKCS11 use BITSTRING. - */ int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) @@ -763,9 +752,9 @@ sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key size_t key_len; LOG_FUNC_CALLED(ctx); - key_len = key->ecpointQ.len * 8; /* in bits */ + key_len = key->ecpointQ.len; /* in bytes */ sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 1, key->ecpointQ.value, &key_len, 1); + sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->ecpointQ.value, &key_len, 1); LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); @@ -826,7 +815,6 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk pubkey->alg_id->algorithm = pubkey->algorithm; } -/* TODO fix EDDSA and XEDDSA to only have algo and no param in SPKI */ switch (pubkey->algorithm) { case SC_ALGORITHM_EC: case SC_ALGORITHM_EDDSA: @@ -848,7 +836,7 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk /* EDDSA and XEDDSA only have algo and no param in SPKI */ if (pubkey->algorithm == SC_ALGORITHM_EC) { - ec_params = calloc(1, sizeof(struct sc_ec_parameters)); + ec_params = calloc(1, sizeof(struct sc_ec_parameters)); if (!ec_params) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); ec_params->type = 1; @@ -887,6 +875,7 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk r = sc_asn1_encode(ctx, asn1_spki_key, buf, len); } + /* pkey.len == 0 is flag to not delete */ if (pkey.len && pkey.value) free(pkey.value); @@ -1384,7 +1373,7 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke if (pk.len == 0) LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INTERNAL, "Incorrect length of key"); - pk.len = BYTES4BITS(pk.len); /* convert number of bits to bytes */ + pk.len = BYTES4BITS(pk.len); /* convert number of bits to bytes */ if (pk_alg.algorithm == SC_ALGORITHM_EC) { /* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */ @@ -1441,12 +1430,9 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke pubkey = NULL; err: - if (pubkey) - sc_pkcs15_free_pubkey(pubkey); - if (pk.value) - free(pk.value); - if (tmp_buf) - free(tmp_buf); + sc_pkcs15_free_pubkey(pubkey); + free(pk.value); + free(tmp_buf); LOG_FUNC_RETURN(ctx, r); } @@ -1491,8 +1477,7 @@ sc_pkcs15_pubkey_from_spki_file(struct sc_context *ctx, char * filename, LOG_TEST_RET(ctx, r, "Cannot read SPKI DER file"); r = sc_pkcs15_pubkey_from_spki_sequence(ctx, buf, buflen, outpubkey); - if (buf) - free(buf); + free(buf); LOG_FUNC_RETURN(ctx, r); } From 8364cd5b21b71a7a54639635cd6d50d2e7da17cd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 31 Oct 2024 07:17:03 -0500 Subject: [PATCH 3735/4321] pkcs11-tool.c - rewrite of show key For EC, Edwards and Montgomery keys,'show_key' now uses 'getEC_POINT' and 'getEC_PARAMS' which return DER from the PKCS11 module. The DER of each is printed in hex. 'match_ec_curve_by_params' is used to look up the curve in 'ec_curve_info' to print the common name, printable OID and key bits. if curve is not known to pkcs11,tool, but supported by the pkcs11 module, the OID parsed using SC routines and printed. in the case EC_PARAMS returns a PRINTABLE string it will attemp to print it as well. (This could be removed.) See: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1816395476 Please enter the commit message for your changes. Lines starting On branch X25519-improvements-2 Changes to be committed: modified: pkcs11-tool.c --- src/tools/pkcs11-tool.c | 160 ++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 98 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e512ad8e4a..bed116cd37 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -112,8 +112,8 @@ static struct ec_curve_info { const char *name; /* common name of curve */ const char *oid; /* formatted printable OID */ unsigned char *ec_params; /* der of OID or printable string */ - size_t ec_params_size; - size_t size; /* field_size in bits */ + CK_ULONG ec_params_size; + CK_ULONG size; /* field_size in bits */ CK_KEY_TYPE mechanism; } ec_curve_infos[] = { {"secp192r1", "1.2.840.10045.3.1.1", (unsigned char*)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01", 10, 192, 0}, @@ -2223,7 +2223,7 @@ match_ec_curve_by_params(const unsigned char *ec_params, CK_ULONG ec_params_size for (size_t i = 0; ec_curve_infos[i].name != NULL; ++i) { if ((ec_curve_infos[i].ec_params_size == ec_params_size) && - (memcmp(&ec_curve_infos[i].ec_params, ec_params, ec_params_size) == 0)) { + (memcmp(ec_curve_infos[i].ec_params, ec_params, ec_params_size) == 0)) { return &ec_curve_infos[i]; } } @@ -2639,7 +2639,6 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char rs_buffer[512]; bytes = getEC_POINT(session, key, &len); free(bytes); - /* TODO DEE EDDSA and EC_POINT returned in BIT STRING needs some work */ /* * (We only support uncompressed for now) * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" @@ -4269,7 +4268,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #ifdef ENABLE_OPENSSL /* Return PKCS11 key type based on OpenSSL EVP_PKEY type - * which are support by PKCS11 and OpenSSL used when compiling. + * which are supported by PKCS11 and OpenSSL used when compiling. * PKCS11 defines CKK_EC_EDWARDS for both Ed25529 and Ed448 * and CKK_EC_MONTGOMERY for X25519 and X448. * If requested, return pointer to struct ec_curve_info containing OID and size @@ -4721,9 +4720,6 @@ static CK_RV write_object(CK_SESSION_HANDLE session) clazz = CKO_PUBLIC_KEY; #ifdef ENABLE_OPENSSL - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type, &ec_curve_info) != CKR_OK) - util_fatal("Key type not supported by OpenSSL and/or PKCS11"); - n_pubkey_attr = 0; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_CLASS, &clazz, sizeof(clazz)); n_pubkey_attr++; @@ -5401,7 +5397,10 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE util_fatal("Failed to parse peer EC key \n"); #else EC_GROUP_free(ecgroup); - EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size); + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &buf_size) != 1) + util_fatal("Failed to get size of public key\n"); + if (buf_size == 0) + util_fatal("Failed to get size of public key\n"); if ((buf = (unsigned char *)malloc(buf_size)) == NULL) util_fatal("malloc() failure\n"); @@ -5419,13 +5418,15 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE #if defined(EVP_PKEY_X448) case EVP_PKEY_X448: #endif - EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size); + if (EVP_PKEY_get_raw_public_key(pkey, NULL, &buf_size) != 1) + util_fatal("Unable to get public key of peer\n"); if (buf_size == 0) util_fatal("Unable to get public key of peer\n"); buf = (unsigned char *)malloc(buf_size); if (buf == NULL) util_fatal("malloc() failure\n"); - EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size); + if (EVP_PKEY_get_raw_public_key(pkey, buf, &buf_size) != 1) + util_fatal("Unable to get public key of peer\n"); if (mech_mech != CKM_ECDH1_DERIVE) util_fatal("Peer key %s not usable with %s", "CKK_EC_MONTGOMERY", p11_mechanism_to_name(mech_mech)); @@ -5763,101 +5764,64 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("; EC"); } if (pub) { - unsigned char *bytes = NULL; - unsigned char *body; + unsigned char *point_bytes = NULL; + CK_ULONG point_size = 0; + unsigned char *params_bytes = NULL; + CK_ULONG params_size = 0; + const struct ec_curve_info *curve_info = NULL; - unsigned long ksize = 0; unsigned int n; - unsigned long body_len = 0; - bytes = getEC_POINT(sess, obj, &size); + point_bytes = getEC_POINT(sess, obj, &point_size); + params_bytes = getEC_PARAMS(sess, obj, ¶ms_size); + + /* get field length from known EC curves */ + curve_info = match_ec_curve_by_params(params_bytes, params_size); + if (curve_info) + printf(" EC_POINT %lu bits\n", curve_info->size); + else + printf(" EC_POINT size unknown\n"); + /* - * simple parse of DER BIT STRING 0x03 or OCTET STRING 0x04 - * good to 65K bytes + * PKCS11 EC_POINT is "DER-encoding of ANSI X9.62 ECPoint value Q" + * "ECPoint ::= OCTET STRING" */ - if (size > 3 && (bytes[0] == 0x03 || bytes[0] == 0x04)) { - if (bytes[1] <= 127 && size == (unsigned long)(bytes[1] + 2)) { - body_len = size - 2; - body = bytes + 2; - } else if (bytes[1] == 0x81 && size == ((unsigned long)bytes[2] + 3)) { - body_len = size - 3; - body = bytes + 3; - } else if (bytes[1] == 0x82 && size == ((unsigned long)(bytes[2] << 8) + (unsigned long)bytes[3] + 4)) { - body_len = size - 4; - body = bytes + 4; - } else { - body_len = 0; /* some problem with size */ - } - } - /* With BIT STRING remove unused bits in last byte indicator */ - if (body_len > 0 && bytes[0] == 0x03) { - body_len--; - body++; - } - - if (key_type == CKK_EC && body_len > 0) { - /* - * (We only support uncompressed for now) - * Uncompressed EC_POINT is DER OCTET STRING - * or DER BIT STRING "04||x||y" - * So a "256" bit key has x and y of 32 bytes each - * something like: "03 42 00 04|x|y" or "04 41 04||x||y" - * Do simple size calculation based on DER encoding - */ - ksize = (body_len - 1) * 4; - - } else if (body_len > 0) { - /* - * EDDSA and XEDDSA in PKCS11 and only one coordinate - */ - ksize = (body_len) * 8; - if (ksize == 256) - ksize--; /* as 25519 uses 255 as bits */ + if (point_bytes && point_size) { + printf(" EC_POINT: "); + for (n = 0; n < point_size; n++) + printf("%02x", point_bytes[n]); + printf("\n"); } - if (ksize) - printf(" EC_POINT %lu bits\n", ksize); - else - printf(" EC_POINT size unknown"); - - if (bytes && body) { - if ((CK_LONG)size > 0) { /* Will print the point here */ - printf(" EC_POINT: "); - for (n = 0; n < body_len; n++) - printf("%02x", body[n]); - printf("\n"); - } - } - free(bytes); - bytes = NULL; - size = 0; - bytes = getEC_PARAMS(sess, obj, &size); - if (bytes) { - if ((CK_LONG)size > 0) { - struct sc_object_id oid; - - printf(" EC_PARAMS: "); - for (n = 0; n < size; n++) - printf("%02x", bytes[n]); - - if (size > 2 && bytes[0] == 0x06) { // OID - sc_init_oid(&oid); - if (sc_asn1_decode_object_id(bytes + 2, size - 2, &oid) == SC_SUCCESS) { - printf(" (OID %i", oid.value[0]); - if (oid.value[0] >= 0) - for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) - && (oid.value[n] >= 0); n++) - printf(".%i", oid.value[n]); - printf(")"); - } - } else if (size > 2 && bytes[0] == 0x13) { // Printable string - printf(" (PrintableString %.*s)", bytes[1], bytes+2); + if (params_bytes && params_size > 2) { + struct sc_object_id oid; + + printf(" EC_PARAMS: "); + for (n = 0; n < params_size; n++) + printf("%02x", params_bytes[n]); + + if (curve_info) + printf(" (\"%s\" OID:\"%s\")", curve_info->name, curve_info->oid); + else /* if unknown curve, type and print something */ + if (params_bytes[0] == SC_ASN1_OBJECT) { + sc_init_oid(&oid); + if (sc_asn1_decode_object_id(params_bytes + 2, params_size - 2, &oid) == SC_SUCCESS) { + printf(" (OID %i", oid.value[0]); + if (oid.value[0] >= 0) + for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) + && (oid.value[n] >= 0); n++) + printf(".%i", oid.value[n]); + printf(")"); } - printf("\n"); - + } else if (params_size > 2 && params_bytes[0] == SC_ASN1_PRINTABLESTRING) { // Printable string + printf(" (PrintableString %.*s)", params_bytes[1], params_bytes+2); + } else { + printf("Unknown format of CKA_EC_PARAMS"); } - free(bytes); + printf("\n"); } + free(point_bytes); + free(params_bytes); } else { printf("\n"); } @@ -6488,12 +6452,12 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* No, should return encoded in BIT STRING, Need to accept both */ + /* will accept BIT STRING, accept both */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); - len = (len + 7) / 8; + len = (len + 7) / 8; } #if OPENSSL_VERSION_NUMBER < 0x30000000L From a549939610a14bd6893ff7d94d8dc131af9088bb Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 1 Nov 2024 12:38:09 -0500 Subject: [PATCH 3736/4321] pkcs11-tool.c - bypass failure of CKM_RSA_PKCS_OAEP with pSourceData SoftHSM2 has problem with CKM_RSA_PKCS_OAEP with pSourceData. It ignores the pSourceData, which then leads to a bad decrypt. As a temporary fix so the CI test can run, the "--test" routines will skip CKM_RSA_PKCS_OAEP with pSourceData. SoftHSM2 only supports --hash-algorithm SHA-1 and --mgf MGF1-SHA1 but pkcs11-tool defaults to SHA256. On branch X25519-improvements-2 Changes to be committed: modified: pkcs11-tool.c Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bed116cd37..1263110bc0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2780,6 +2780,7 @@ build_rsa_oaep_params( printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(oaep_params->mgf)); } + /* PKCS11 3.0 is vague about setting CKZ_DATA_SPECIFIED */ oaep_params->source = CKZ_DATA_SPECIFIED; oaep_params->pSourceData = param; oaep_params->ulSourceDataLen = param_len; @@ -5793,33 +5794,33 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); } - if (params_bytes && params_size > 2) { + if (params_bytes && params_size > 0) { struct sc_object_id oid; printf(" EC_PARAMS: "); for (n = 0; n < params_size; n++) printf("%02x", params_bytes[n]); - if (curve_info) + if (curve_info) { /* we matched it above, use printable OID */ printf(" (\"%s\" OID:\"%s\")", curve_info->name, curve_info->oid); - else /* if unknown curve, type and print something */ - if (params_bytes[0] == SC_ASN1_OBJECT) { + } else if (params_bytes[0] == SC_ASN1_OBJECT) { sc_init_oid(&oid); - if (sc_asn1_decode_object_id(params_bytes + 2, params_size - 2, &oid) == SC_SUCCESS) { - printf(" (OID %i", oid.value[0]); - if (oid.value[0] >= 0) + if (sc_asn1_decode_object_id(params_bytes, params_size, &oid) == SC_SUCCESS) { + printf(" (OID: \"%i", oid.value[0]); + if (oid.value[0] >= 0) { for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) - && (oid.value[n] >= 0); n++) + && (oid.value[n] >= 1); n++) { printf(".%i", oid.value[n]); - printf(")"); + } + } + printf("\""); } - } else if (params_size > 2 && params_bytes[0] == SC_ASN1_PRINTABLESTRING) { // Printable string - printf(" (PrintableString %.*s)", params_bytes[1], params_bytes+2); - } else { - printf("Unknown format of CKA_EC_PARAMS"); - } printf("\n"); + } + } else { + printf(" EC_PARAMS: not available\n"); } + free(point_bytes); free(params_bytes); } else { @@ -8324,9 +8325,12 @@ static int test_decrypt(CK_SESSION_HANDLE sess) #else for (n = 0; n < num_mechs; n++) { switch (mechs[n]) { -// case CKM_RSA_PKCS_OAEP: + case CKM_RSA_PKCS_OAEP: /* one more OAEP test with param .. */ -// errors += encrypt_decrypt(sess, mechs[n], privKeyObject, "ABC", 3); + /* SoftHSM2 and maybe others fail with pSourceData */ + /* the pSourceData is not used so the C_Decrypt fails with CKR_GENERAL_ERROR */ + // errors += encrypt_decrypt(sess, mechs[n], privKeyObject, "ABC", 3)) != 0); + printf(" -- CKM_RSA_PKCS_OAEP with pSourceData != NULL, skipping\n"); /* fall through */ case CKM_RSA_PKCS: case CKM_RSA_X_509: From 45508b561d53a3c265fbbe25603bec230aa5a31b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 1 Nov 2024 13:59:01 -0500 Subject: [PATCH 3737/4321] tests/common.sh - track down what versions of softhsm are used in CI On branch X25519-improvements-2 Changes to be committed: modified: common.sh --- tests/common.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/common.sh b/tests/common.sh index 9d98d26d3c..ccf9ce76f7 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -78,7 +78,11 @@ function softhsm_initialize() { mkdir ".tokens" export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") # Init token - softhsm2-util --version + echo DEE uname -a: $(uname -a) + echo DEE softhsm version: $(softhsm2-util --version) + echo DEE whereis: $(whereis softhsm2-util) + echo DEE P11LIB: "$P11LIB" + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" } From 1dba86ea15fa3652853106c35eb15a7fb6a05e94 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 2 Nov 2024 16:59:21 -0500 Subject: [PATCH 3738/4321] test-pkcs11-tool-test.sh - SoftHSM and CKM_RSA_PKCS_OAEP Also see pkcs11-tool SoftHSM only supports CKM_RSA_PKCS_OAEP with --hash-algorithm SHA-1 and --mgf MGF1-SHA1 On branch X25519-improvements-2 Changes to be committed: modified: ../../tests/test-pkcs11-tool-test.sh --- tests/test-pkcs11-tool-test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 94a5f4b527..b5da43f717 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -20,7 +20,9 @@ assert $? "Failed to set up card" echo "=======================================================" echo "Test" echo "=======================================================" -$PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" +#SoftHSM only supports CKM_RSA_PKCS_OAEP with --hash-algorithm SHA-1 and --mgf MGF1-SHA1 +# and it accepts pSourceData, but does not use, so decrypt fails, See pkcs11-tool.c comments +$PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" assert $? "Failed running tests" echo "=======================================================" From dea1fc1c380b1e67c07fab5895bea7378eaed107 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 3 Nov 2024 20:07:57 -0600 Subject: [PATCH 3739/4321] pkcs11-opensc.h - Define CKK_OPENSC_UNDEFINED For internal OpenSc and PKCS11-tool.c On branch X25519-improvements-2 Changes to be committed: modified: pkcs11/pkcs11-opensc.h --- src/pkcs11/pkcs11-opensc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index fef2f7aa42..9975e99fc2 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -25,5 +25,6 @@ * to set userConsent=1 for other objects than private keys via PKCS#11. */ #define CKA_OPENSC_ALWAYS_AUTH_ANY_OBJECT (CKA_VENDOR_DEFINED | SC_VENDOR_DEFINED | 3UL) - +/* PKCS11 does not define an unknown CKK. Define one for internal OpenSC and pkcs11-tool.c */ +#define CKK_OPENSC_UNDEFINED (CKK_VENDOR_DEFINED | SC_VENDOR_DEFINED | 0xffUL) #endif From c5e4aa7c087250086c3e949fbbfed9671ef461dc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 3 Nov 2024 20:10:23 -0600 Subject: [PATCH 3740/4321] pkcs11-tool.c - Fix problem with writing public key object to token On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 127 +++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1263110bc0..4246355a6d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -489,7 +489,7 @@ static const char *opt_aad = NULL; static unsigned long opt_tag_bits = 0; static const char *opt_salt_file = NULL; static const char *opt_info_file = NULL; -static int opt_public_key_info = 0; /* return pubkey as SPKI DER */ +static int opt_public_key_info = 0; /* return pubkey as SPKI DER */ static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -2209,7 +2209,7 @@ match_ec_curve_by_name(const char *name) return &ec_curve_infos[i]; } } - + return NULL; } #endif @@ -3222,8 +3222,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } } - - if (opt_key_usage_default || opt_key_usage_sign) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); n_pubkey_attr++; @@ -4274,7 +4272,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) * and CKK_EC_MONTGOMERY for X25519 and X448. * If requested, return pointer to struct ec_curve_info containing OID and size */ - + static CK_RV evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_curve_info **ec_curve_info) { @@ -4361,7 +4359,7 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ #endif err: /* unsupported by OpenSSL, PKCS11 or this program */ - *type = -1; + *type = CKK_OPENSC_UNDEFINED; *pk_type = -1; return CKR_FUNCTION_NOT_SUPPORTED; } @@ -4375,7 +4373,7 @@ parse_ed_mont_pkey(EVP_PKEY *pkey, int type, int pk_type, struct ec_curve_info * size_t key_size; /* set EC_PARAMS value - * The param passed is DER of an OID or a PRINTABLE STRING as defines in PKCS11 3.0 + * The param passed is DER of an OID or a PRINTABLE STRING as defines in PKCS11 3.0 * all of the ec_curve_info entries have one byte len values */ @@ -4448,14 +4446,14 @@ static CK_RV write_object(CK_SESSION_HANDLE session) unsigned char *oid_buf = NULL; CK_OBJECT_CLASS clazz; CK_CERTIFICATE_TYPE cert_type; - CK_KEY_TYPE type = CKK_RSA; + CK_KEY_TYPE type = CKK_OPENSC_UNDEFINED; size_t ret = 0; #ifdef ENABLE_OPENSSL struct x509cert_info cert; struct rsakey_info rsa; struct gostkey_info gost; EVP_PKEY *evp_key = NULL; - int pk_type; + int pk_type = -1; struct ec_curve_info *ec_curve_info = NULL; memset(&cert, 0, sizeof(cert)); @@ -4538,7 +4536,6 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #ifdef ENABLE_OPENSSL int is_private = opt_object_class == CKO_PRIVATE_KEY; int rv; - CK_KEY_TYPE type; rv = do_read_key(contents, contents_len, is_private, &evp_key); if (rv) { @@ -4556,9 +4553,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) rv = parse_rsa_pkey(evp_key, is_private, &rsa); } #if !defined(OPENSSL_NO_EC) - else if (type == NID_id_GostR3410_2001) { + else if (type == CKK_GOSTR3410) { rv = parse_gost_pkey(evp_key, is_private, &gost); - type = CKK_GOSTR3410; } else if (type == CKK_EC) { rv = parse_ec_pkey(evp_key, is_private, &gost); } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { @@ -4669,9 +4665,6 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } - if (evp_pkey2ck_key_type(evp_key, &type, &pk_type,&ec_curve_info) != CKR_OK) - util_fatal("Key type not supported by OpenSSL and/or PKCS11"); - if (type == CKK_RSA) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; @@ -4712,6 +4705,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) if (rv) return rv; n_privkey_attr++; + } else { + util_fatal("Unsupported CK_KEY_TYPE, cannot write private key"); } #else util_fatal("No OpenSSL support, cannot write private key"); @@ -4795,6 +4790,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) if (rv) return rv; n_pubkey_attr++; + } else { + util_fatal("Unsupported CK_KEY_TYPE, cannot write public key"); } #endif #else @@ -5808,14 +5805,13 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if (sc_asn1_decode_object_id(params_bytes, params_size, &oid) == SC_SUCCESS) { printf(" (OID: \"%i", oid.value[0]); if (oid.value[0] >= 0) { - for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) - && (oid.value[n] >= 1); n++) { + for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[n] >= 1); n++) { printf(".%i", oid.value[n]); } } printf("\""); } - printf("\n"); + printf("\n"); } } else { printf(" EC_PARAMS: not available\n"); @@ -6332,14 +6328,14 @@ static int read_object(CK_SESSION_HANDLE session) return 0; } if (clazz == CKO_PUBLIC_KEY) { - /* If module supports CKA_PUBLIC_KEY_INFO which is DER of SPKI - * return whatever the module provides including ED448 and X448 + /* If module supports CKA_PUBLIC_KEY_INFO which is DER of SPKI + * return whatever the module provides including ED448 and X448 */ if (opt_public_key_info) value = getPUBLIC_KEY_INFO(session, obj, &len); /* softhsm2 may return length 0 and varattr may allocate memory treat as invalid */ if (value && len == 0) { - p11_warn("getPUBLIC_KEY_INFO returned a value of length 0",0); + p11_warn("getPUBLIC_KEY_INFO returned a value of length 0", 0); free(value); value = NULL; } @@ -6390,9 +6386,9 @@ static int read_object(CK_SESSION_HANDLE session) if (!ctx) util_fatal("out of memory"); if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || - OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + OSSL_PARAM_BLD_push_BN(bld, "n", rsa_n) != 1 || + OSSL_PARAM_BLD_push_BN(bld, "e", rsa_e) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { BN_free(rsa_n); BN_free(rsa_e); OSSL_PARAM_BLD_free(bld); @@ -6404,10 +6400,10 @@ static int read_object(CK_SESSION_HANDLE session) BN_free(rsa_e); OSSL_PARAM_BLD_free(bld); if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); - util_fatal("cannot set RSA values"); + util_fatal("cannot set RSA values"); } OSSL_PARAM_free(params); if (i2d_PUBKEY_bio(pout, pkey) != 1) { @@ -6458,7 +6454,7 @@ static int read_object(CK_SESSION_HANDLE session) os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); - len = (len + 7) / 8; + len = BYTES4BITS(len); } #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -6491,39 +6487,39 @@ static int read_object(CK_SESSION_HANDLE session) EC_KEY_set_public_key(EVP_PKEY_get0_EC_KEY(pkey), point); #else if (!(bld = OSSL_PARAM_BLD_new()) || - EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &old) != 1 || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", a, a_len) != 1 || - !(new = OSSL_PARAM_BLD_to_param(bld)) || - !(p = OSSL_PARAM_merge(old, new))) { - OSSL_PARAM_BLD_free(bld); - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); - OSSL_PARAM_free(p); - if (success) - ASN1_STRING_free(os); - free(value); - util_fatal("cannot set OSSL_PARAM"); + EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &old) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", a, a_len) != 1 || + !(new = OSSL_PARAM_BLD_to_param(bld)) || + !(p = OSSL_PARAM_merge(old, new))) { + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); + OSSL_PARAM_free(p); + if (success) + ASN1_STRING_free(os); + free(value); + util_fatal("cannot set OSSL_PARAM"); } OSSL_PARAM_BLD_free(bld); - if (success) - ASN1_STRING_free(os); - free(value); + if (success) + ASN1_STRING_free(os); + free(value); - if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || EVP_PKEY_fromdata_init(ctx) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot set CTX"); - } - EVP_PKEY_free(pkey); - pkey = NULL; - if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot create EVP_PKEY"); - } - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot set CTX"); + } + EVP_PKEY_free(pkey); + pkey = NULL; + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot create EVP_PKEY"); + } + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); #endif if (!i2d_PUBKEY_bio(pout, pkey)) @@ -6535,23 +6531,23 @@ static int read_object(CK_SESSION_HANDLE session) CK_BYTE *params = NULL; const unsigned char *a; ASN1_OCTET_STRING *os; - + if ((params = getEC_PARAMS(session, obj, &len))) { ASN1_PRINTABLESTRING *curve = NULL; ASN1_OBJECT *obj = NULL; - + a = params; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { if (strcmp((char *)curve->data, "edwards25519")) { util_fatal("Unknown curve name, expected edwards25519, got %s", - curve->data); + curve->data); } ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { int nid = OBJ_obj2nid(obj); if (nid != NID_ED25519) { util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d", - NID_ED25519, nid); + NID_ED25519, nid); } ASN1_OBJECT_free(obj); } else { @@ -6569,7 +6565,7 @@ static int read_object(CK_SESSION_HANDLE session) os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); - len = (len + 7) / 8; + len = BYTES4BITS(len); } if (!os) { util_fatal("cannot decode EC_POINT"); @@ -6578,8 +6574,8 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("Invalid length of EC_POINT value"); } key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, - (const uint8_t *)os->data, - os->length); + (const uint8_t *)os->data, + os->length); ASN1_STRING_free(os); if (key == NULL) { util_fatal("out of memory"); @@ -6589,11 +6585,10 @@ static int read_object(CK_SESSION_HANDLE session) if (!PEM_write_bio_PUBKEY(pout, key)) { util_fatal("cannot convert EdDSA public key to PEM"); } - + EVP_PKEY_free(key); #endif - } - else + } else util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); value = BIO_copy_data(pout, &derlen); BIO_free(pout); From a1b24985dc977aee2ba96a4626fc6596d2f43333 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 4 Nov 2024 10:04:22 -0600 Subject: [PATCH 3741/4321] test-pkcs11-tool-import.sh - Comment on adding Ed25519 test 'openssl genpkey' prior to 3.2 does not have '-outpubkey' and '-algorithm Ed25519' will only write the private key to '-out' The privete key does not contain the EC_POINT public key. With RSA the 'n' and 'e' are part of th private key and with EC both the private key and public key are written to the same file. in all cases the public key is in SPKI format. --- tests/test-pkcs11-tool-import.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index 653d0491ae..161f348f7a 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -13,6 +13,9 @@ fi card_setup assert $? "Failed to set up card" +# To add Ed25519 will require OpenSSL 3.2 and use of genpkey -outpubkey +# which will also work for other keys, and will not require openssl pkey + for KEYTYPE in "RSA" "EC"; do echo "=======================================================" echo "Generate and import $KEYTYPE keys" From 39c54569d22bd772bb7aa05853aec20536b3c31b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 4 Nov 2024 13:58:20 -0600 Subject: [PATCH 3742/4321] pkcs15-init.c - set default RSA key size to 3072 As recommented in comment: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1816249166 On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-init.c --- src/tools/pkcs15-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 576bb78add..df6fc05656 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -724,9 +724,9 @@ static const struct alg_spec alg_types_sym[] = { /* RSA can have a number , default is 2048 */ /* EC require a curve name */ /* EDDSA and XEDDSA without a size require a size or curve name or OID */ -/* other EDDSA and XEDDSA can be used alone */ +/* other EDDSA and XEDDSA can be used alone */ static const struct alg_spec alg_types_asym[] = { - { "rsa", SC_ALGORITHM_RSA, 2048 }, /* new default */ + { "rsa", SC_ALGORITHM_RSA, 3072 }, /* new default */ { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, /* keybits derived from curve */ /* RFC 8410 */ From bbb36f69db169662e1f830d1e41e681c7d181441 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 4 Nov 2024 14:57:54 -0600 Subject: [PATCH 3743/4321] card-openpgp.c - add test for possible internal error See: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1749997143 On branch X25519-improvements-2 Changes to be committed: modified: card-openpgp.c --- src/libopensc/card-openpgp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index a1b3ebbb8f..616b12fef5 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -570,6 +570,8 @@ pgp_init(sc_card_t *card) else if (priv->ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) _sc_card_add_xeddsa_alg(card, priv->ec_curves[i].size, flags_xeddsa, ext_flags, &priv->ec_curves[i].oid); + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } break; case SC_CARD_TYPE_OPENPGP_V2: From b6c1641126140d0dd99b43ae5f0bbdc0b40fbc04 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 4 Nov 2024 17:15:38 -0600 Subject: [PATCH 3744/4321] pkcs15init/pkcs15-openpgp.c - cleanup copied ecpointQ 'sc_cardctl_openpgp_key_gen_store_info_t' passes some pointers to to data in other structures but only does malloc for ecpointQ. See: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1816687658 On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index e54c0fad42..286580c754 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -200,6 +200,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.u.rsa.modulus = key->u.rsa.modulus.data; key_info.u.rsa.modulus_len = key->u.rsa.modulus.len * 8; /* use bits instead of bytes */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + + /* nothing to free in key_info for RSA */ break; case SC_PKCS15_TYPE_PRKEY_EC: @@ -223,6 +225,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; key_info.u.ec.oid = key->u.ec.params.id; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + + free(key_info.u.ec.ecpointQ); break; /* Unlike RSA which includes modulus in privkey, @@ -249,8 +253,10 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (pubkey->u.ec.params.der.len > 2) key_info.u.ec.oidv_len = pubkey->u.ec.params.der.value[1]; - else + else { + free(key_info.u.ec.ecpointQ); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } for ( size_t i = 0; (i < key_info.u.ec.oidv_len) && (i+2 < pubkey->u.ec.params.der.len); i++){ key_info.u.ec.oidv.value[i] = pubkey->u.ec.params.der.value[i+2]; @@ -264,6 +270,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.key_type = pubkey->u.ec.params.key_type; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); + + free(key_info.u.ec.ecpointQ); break; default: @@ -272,8 +280,6 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } err: - /* TODO cleanup key_info */ - LOG_FUNC_RETURN(card->ctx, r); } From 752495e0ee7a97eb52457277098a43f8abcea75b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 4 Nov 2024 19:48:40 -0600 Subject: [PATCH 3745/4321] card-openpgp.c - remove leftover comments As suggested: https://github.com/OpenSC/OpenSC/pull/3090#discussion_r1816750718 On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 616b12fef5..1a2c25645e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2788,8 +2788,6 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, p += 1; *p = key_info->u.ec.oidv_len; p += 1; - /* TODO Should this be a loop to copy byte be byte? */ - /* Should it be the key_info data and data_len? */ memcpy(p, key_info->u.ec.oidv.value, key_info->u.ec.oidv_len); p += key_info->u.ec.oidv_len; memcpy(p, key_info->u.ec.ecpointQ, key_info->u.ec.ecpointQ_len); @@ -3476,7 +3474,6 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store static int pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) { -// sc_cardctl_openpgp_key_gen_store_info_t pubkey; u8 *data = NULL; size_t len = 0; int r = 0; @@ -3485,8 +3482,6 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info LOG_FUNC_CALLED(card->ctx); -// memset(&pubkey, 0, sizeof(pubkey)); - /* PKCS11 loads privkey separately from pubkey as two different operations * So this routine will be called twice to create two different objects. * pkcs15init only calls once, with both. @@ -3542,14 +3537,6 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info key_info->u.rsa.exponent_len); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - -// pubkey.key_id = key_info->key_id; -// pubkey.algorithm = key_info->algorithm; -// pubkey.u.rsa.modulus = key_info->u.rsa.modulus; -// pubkey.u.rsa.modulus_len = key_info->u.rsa.modulus_len; -// pubkey.u.rsa.exponent = key_info->u.rsa.exponent; -// pubkey.u.rsa.exponent_len = key_info->u.rsa.exponent_len; - } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || @@ -3561,15 +3548,6 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info if (!has_pubkey && !has_privkey) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); -// memset(&pubkey, 0, sizeof(pubkey)); -// pubkey.key_id = key_info->key_id; -// pubkey.algorithm = key_info->algorithm; -// -// pubkey.u.ec.oid_len = key_info->u.ec.oid_len; -// pubkey.u.ec.oid = key_info->u.ec.oid; -// pubkey.u.ec.ecpointQ = key_info->u.ec.ecpointQ; -// pubkey.u.ec.ecpointQ_len = key_info->u.ec.ecpointQ_len; - r = pgp_update_new_algo_attr(card, key_info); LOG_TEST_RET(card->ctx, r, "Failed to update new algorithm attributes"); From 12e8f24d633a0f0286ac270a12f6cd2c5c2cee1f Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 5 Nov 2024 08:37:09 -0600 Subject: [PATCH 3746/4321] card-openpgp.c - codding style On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 59 +++++++++++++++++------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 1a2c25645e..f9a7117c7e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -622,7 +622,7 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len) **/ static int pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, - sc_cardctl_openpgp_key_gen_store_info_t *key_info) + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { struct pgp_priv_data *priv = DRVDATA(card); struct sc_object_id oid; @@ -707,8 +707,9 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -int _pgp_handle_curve25519(sc_card_t *card, - sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) +int +_pgp_handle_curve25519(sc_card_t *card, + sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) { if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid) && !sc_compare_oid(&key_info.u.ec.oid, &X25519_oid)) @@ -724,7 +725,8 @@ int _pgp_handle_curve25519(sc_card_t *card, return 1; } -int _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) +int +_pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) { unsigned long flags = 0, ext_flags = 0; @@ -2597,11 +2599,11 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); key_info->data[0] = key_info->algorithm; - ushort2bebytes(key_info->data+1, key_info->u.rsa.modulus_len); + ushort2bebytes(key_info->data + 1, key_info->u.rsa.modulus_len); /* OpenPGP Card only accepts 32bit as exponent length field, * although you can import keys with smaller exponent; * thus we don't change rsa.exponent_len, but ignore it here */ - ushort2bebytes(key_info->data+3, SC_OPENPGP_MAX_EXP_BITS); + ushort2bebytes(key_info->data + 3, SC_OPENPGP_MAX_EXP_BITS); /* Import-Format of private key (e,p,q) */ key_info->data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD; } @@ -2678,7 +2680,7 @@ pgp_store_creationtime(sc_card_t *card, u8 key_id, time_t *outtime) **/ static int pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, - sc_cardctl_openpgp_key_gen_store_info_t *key_info) + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { u8 fingerprint[SHA_DIGEST_LENGTH]; u8 *fp_buffer = NULL; /* fingerprint buffer, not hashed */ @@ -2726,12 +2728,12 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* https://tools.ietf.org/html/rfc4880 page 41, 72 * and https://tools.ietf.org/html/rfc6637 section 9 (page 8 and 9) */ - pk_packet_len = 1 /* version number */ - + 4 /* creation time */ - + 1 /* algorithm */ - + 1 /* oid len */ - + key_info->u.ec.oidv_len /* oid */ - + key_info->u.ec.ecpointQ_len; /* ecpoint */ + pk_packet_len = 1 /* version number */ + + 4 /* creation time */ + + 1 /* algorithm */ + + 1 /* oid len */ + + key_info->u.ec.oidv_len /* oid */ + + key_info->u.ec.ecpointQ_len; /* ecpoint */ /* KDF parameters for ECDH */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH) { @@ -2801,15 +2803,13 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, p += 1; *p = 0x01; /* version of this format */ p += 1; - if (key_info->u.ec.key_length <= 256){ /* ec bit size <= 256 */ + if (key_info->u.ec.key_length <= 256) { /* ec bit size <= 256 */ *p = 0x08; /* KDF algo */ *(p+1) = 0x07; /* KEK algo */ - } - else if (key_info->u.ec.key_length <= 384) { /* ec bit size <= 384 */ + } else if (key_info->u.ec.key_length <= 384) { /* ec bit size <= 384 */ *p = 0x09; /* KDF algo */ *(p+1) = 0x08; /* KEK algo */ - } - else { /* ec bit size = 512 or 521*/ + } else { /* ec bit size = 512 or 521*/ *p = 0x0a; /* KDF algo */ *(p+1) = 0x09; /* KEK algo */ } @@ -2909,7 +2909,7 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { memset(&p15pubkey, 0, sizeof(p15pubkey)); - p15pubkey.algorithm = key_info->key_type; /* TODO not set? */ + p15pubkey.algorithm = key_info->key_type; /* TODO not set? */ p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpointQ; p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpointQ_len; } else @@ -2930,8 +2930,8 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t * Internal: parse response data and set output **/ static int -pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len, - sc_cardctl_openpgp_key_gen_store_info_t *key_info) +pgp_parse_and_set_pubkey_output(sc_card_t *card, u8 *data, size_t data_len, + sc_cardctl_openpgp_key_gen_store_info_t *key_info) { time_t ctime = 0; u8 *in = data; @@ -3273,7 +3273,7 @@ set_taglength_tlv(u8 *buffer, unsigned int tag, size_t length) **/ static int pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info, - u8 **result, size_t *resultlen) + u8 **result, size_t *resultlen) { sc_context_t *ctx = card->ctx; /* Cardholder private key template (7F48) part */ @@ -3368,9 +3368,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store } } /* ECC */ - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH - || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA - || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { components[0] = key_info->u.ec.privateD; componentlens[0] = key_info->u.ec.privateD_len; componenttags[0] = 0x92; @@ -3394,8 +3392,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store /* Cardholder private key template's data part */ memset(pritemplate, 0, max_prtem_len); - } - else + } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* start from beginning of pritemplate */ @@ -3533,8 +3530,8 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info /* we only support exponent of maximum 32 bits */ if (key_info->u.rsa.exponent_len > SC_OPENPGP_MAX_EXP_BITS) { sc_log(card->ctx, - "Exponent %"SC_FORMAT_LEN_SIZE_T"u-bit (>32) is not supported.", - key_info->u.rsa.exponent_len); + "Exponent %" SC_FORMAT_LEN_SIZE_T "u-bit (>32) is not supported.", + key_info->u.rsa.exponent_len); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } } @@ -3700,11 +3697,11 @@ pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) break; #ifdef ENABLE_OPENSSL case SC_CARDCTL_OPENPGP_GENERATE_KEY: - r = pgp_gen_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *) ptr); + r = pgp_gen_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *)ptr); LOG_FUNC_RETURN(card->ctx, r); break; case SC_CARDCTL_OPENPGP_STORE_KEY: - r = pgp_store_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *) ptr); + r = pgp_store_key(card, (sc_cardctl_openpgp_key_gen_store_info_t *)ptr); LOG_FUNC_RETURN(card->ctx, r); break; #endif /* ENABLE_OPENSSL */ From 00dc57f1fd641bbb9ae1ecf40ca358773afe1f47 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 5 Nov 2024 08:38:19 -0600 Subject: [PATCH 3747/4321] src/libopensc/cardctl.h - coding style On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/cardctl.h --- src/libopensc/cardctl.h | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 1fa2d621d9..6b898e41cd 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -22,9 +22,9 @@ #ifndef _OPENSC_CARDCTL_H #define _OPENSC_CARDCTL_H -#include -#include "libopensc/types.h" #include "libopensc/opensc.h" +#include "libopensc/types.h" +#include #ifdef __cplusplus extern "C" { @@ -887,28 +887,28 @@ typedef struct sc_cardctl_openpgp_key_gen_store_info { unsigned long key_type; /* SC_ALGORITHM_... */ u8 *data; /* algo blob data */ size_t data_len; /* bytes */ - time_t creationtime; /* when private generated or stored */ + time_t creationtime; /* when private generated or stored */ union { struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_RSA_... */ - u8 *exponent; /* exponent to store or generated */ - size_t exponent_len; /* bit */ + u8 *exponent; /* exponent to store or generated */ + size_t exponent_len; /* bit */ u8 *p; size_t p_len; u8 *q; size_t q_len; - u8 *modulus; /* modulus to store or generated */ - size_t modulus_len; /* bits - field_length */ + u8 *modulus; /* modulus to store or generated */ + size_t modulus_len; /* bits - field_length */ } rsa; struct { u8 keyformat; /* SC_OPENPGP_KEYFORMAT_EC_... */ u8 *privateD; /* private key to store */ - size_t privateD_len; /* bytes */ - u8 *ecpointQ; /* public key to store or generated */ - size_t ecpointQ_len; /* bytes */ + size_t privateD_len; /* bytes */ + u8 *ecpointQ; /* public key to store or generated */ + size_t ecpointQ_len; /* bytes */ struct sc_object_id oid; /* RFC8410 OID */ /* - * sc_object_id oidv is misused here to contain the bytes + * sc_object_id oidv is misused here to contain the bytes * of the values from TLV of OID DER TLV */ struct sc_object_id oidv; @@ -918,7 +918,6 @@ typedef struct sc_cardctl_openpgp_key_gen_store_info { } u; } sc_cardctl_openpgp_key_gen_store_info_t; - /* * SmartCard-HSM */ From 9c71256459f930186e028796f1a2c1cafede0cd1 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 5 Nov 2024 08:40:24 -0600 Subject: [PATCH 3748/4321] pkcs15-openpgp.c - coding style On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 73 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 286580c754..842e3bcee8 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -113,11 +113,12 @@ static int openpgp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, * @returns 0 or error */ -static int openpgp_set_algorithm(sc_pkcs15_card_t *p15card, +static int +openpgp_set_algorithm(sc_pkcs15_card_t *p15card, u8 key_id, unsigned long type, u8 *algo) { sc_card_t *card = p15card->card; - + if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && card->type < SC_CARD_TYPE_OPENPGP_V3) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card"); @@ -170,15 +171,15 @@ static int openpgp_set_algorithm(sc_pkcs15_card_t *p15card, static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { - /* Maybe called internally to write public key because PKCS11 stores + /* Maybe called internally to write public key because PKCS11 stores * private and public keys in separate operations. In this case * the object will have a type of SC_PKCS15_TYPE_PUBLIC_* * and key will be sc_pkcs15_pubkey_t */ sc_card_t *card = p15card->card; - sc_pkcs15_pubkey_t *pubkey = (sc_pkcs15_pubkey_t *) key; /* maybe pubkey */ + sc_pkcs15_pubkey_t *pubkey = (sc_pkcs15_pubkey_t *)key; /* maybe pubkey */ sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; - sc_pkcs15_pubkey_info_t *pubkinfo = (sc_pkcs15_pubkey_info_t *) obj->data; + sc_pkcs15_pubkey_info_t *pubkinfo = (sc_pkcs15_pubkey_info_t *)obj->data; sc_cardctl_openpgp_key_gen_store_info_t key_info = {0}; int r; @@ -208,10 +209,10 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); - + r = openpgp_set_algorithm(p15card, kinfo->id.value[0], obj->type, &key_info.algorithm); LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id"); - + key_info.key_id = kinfo->id.value[0]; key_info.u.ec.privateD = key->u.ec.privateD.data; key_info.u.ec.privateD_len = key->u.ec.privateD.len; @@ -229,7 +230,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, free(key_info.u.ec.ecpointQ); break; - /* Unlike RSA which includes modulus in privkey, + /* Unlike RSA which includes modulus in privkey, * PKCS11 stores pubkey as separate operation */ case SC_PKCS15_TYPE_PUBKEY_EC: @@ -239,15 +240,14 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = openpgp_set_algorithm(p15card, pubkinfo->id.value[0], obj->type, &key_info.algorithm); LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id"); - + key_info.key_id = pubkinfo->id.value[0]; if (pubkey->u.ec.ecpointQ.len) { key_info.u.ec.ecpointQ = malloc(pubkey->u.ec.ecpointQ.len); if (!key_info.u.ec.ecpointQ) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(&key_info.u.ec.ecpointQ, &pubkey->u.ec.ecpointQ.value, pubkey->u.ec.ecpointQ.len); - key_info.u.ec.ecpointQ_len = pubkey->u.ec.ecpointQ.len; - + key_info.u.ec.ecpointQ_len = pubkey->u.ec.ecpointQ.len; } /* copy oid, oid_len and key_length from pubkey */ @@ -258,8 +258,8 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - for ( size_t i = 0; (i < key_info.u.ec.oidv_len) && (i+2 < pubkey->u.ec.params.der.len); i++){ - key_info.u.ec.oidv.value[i] = pubkey->u.ec.params.der.value[i+2]; + for (size_t i = 0; (i < key_info.u.ec.oidv_len) && (i + 2 < pubkey->u.ec.params.der.len); i++) { + key_info.u.ec.oidv.value[i] = pubkey->u.ec.params.der.value[i + 2]; } key_info.u.ec.oidv.value[key_info.u.ec.oidv_len] = -1; @@ -273,7 +273,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, free(key_info.u.ec.ecpointQ); break; - + default: r = SC_ERROR_NOT_SUPPORTED; sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r)); @@ -439,8 +439,8 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - for (size_t i=0; (i < key_info.u.ec.oidv_len) && (i+2 < info_ec->der.len); i++){ - key_info.u.ec.oidv.value[i] = info_ec->der.value[i+2]; + for (size_t i = 0; (i < key_info.u.ec.oidv_len) && (i + 2 < info_ec->der.len); i++) { + key_info.u.ec.oidv.value[i] = info_ec->der.value[i + 2]; } key_info.u.ec.oidv.value[key_info.data_len] = -1; @@ -548,7 +548,6 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile int r = 0; sc_pkcs15_pubkey_t *pubkey = NULL; - LOG_FUNC_CALLED(card->ctx); switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { @@ -565,7 +564,7 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile LOG_TEST_GOTO_ERR(ctx, r, "Failed to get pubkey from spki"); /* PKCS11 stores private and public keys as two operations */ - r = openpgp_store_key (profile, p15card, obj, (void *)pubkey); + r = openpgp_store_key(profile, p15card, obj, (void *)pubkey); LOG_TEST_GOTO_ERR(ctx, r, "Failed to store pubkey fromk spki"); r = SC_SUCCESS; @@ -659,25 +658,25 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile } static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = { - openpgp_erase, - NULL, /* init_card */ - openpgp_create_dir, - NULL, /* create_domain */ - openpgp_select_pin_reference, - openpgp_create_pin, - NULL, /* select key reference */ - openpgp_create_key, - openpgp_store_key, /* May be called for private and public key twice */ - openpgp_generate_key, - NULL, NULL, /* encode private/public key */ - NULL, /* finalize_card */ - NULL, /* delete_object */ - NULL, - openpgp_emu_update_any_df, - openpgp_emu_update_tokeninfo, - NULL, /* emu_write_info */ - openpgp_store_data, /* emu_store_data */ - NULL /* sanity_check */ + openpgp_erase, + NULL, /* init_card */ + openpgp_create_dir, + NULL, /* create_domain */ + openpgp_select_pin_reference, + openpgp_create_pin, + NULL, /* select key reference */ + openpgp_create_key, + openpgp_store_key, /* May be called for private and public key twice */ + openpgp_generate_key, + NULL, NULL, /* encode private/public key */ + NULL, /* finalize_card */ + NULL, /* delete_object */ + NULL, + openpgp_emu_update_any_df, + openpgp_emu_update_tokeninfo, + NULL, /* emu_write_info */ + openpgp_store_data, /* emu_store_data */ + NULL /* sanity_check */ }; struct sc_pkcs15init_operations *sc_pkcs15init_get_openpgp_ops(void) From 00bf6c94b8aeb31743618d83281b2f909952d945 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 5 Nov 2024 08:42:15 -0600 Subject: [PATCH 3749/4321] pkcs15-init.c - coding style On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs15-init.c --- src/tools/pkcs15-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index df6fc05656..e011232987 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -785,13 +785,13 @@ parse_alg_spec(const struct alg_spec *types, const char *spec, unsigned int *key user_keybits = (unsigned)strtoul(spec, &end, 10); if (*end) { util_error("Invalid number of key bits \"%s\"", spec); - return SC_ERROR_INVALID_ARGUMENTS; + return SC_ERROR_INVALID_ARGUMENTS; } if (user_keybits != *keybits) { util_error("If specified, number of key bits must be \"%d\" for \"%s\"", *keybits, types[types_idx].spec); return SC_ERROR_INVALID_ARGUMENTS; } - } else { /* rsa or symmetric key */ + } else { /* rsa or symmetric key */ *keybits = (unsigned)strtoul(spec, &end, 10); if (*end) { util_error("Invalid number of key bits \"%s\"", spec); From 38b433fd2ea6fd07c2cfe51c598e97d972e37c00 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:22:29 -0600 Subject: [PATCH 3750/4321] tests/common.h - fixup remove debugging as suggested in PR comments On branch X25519-improvements-2 Changes to be committed: modified: common.sh --- tests/common.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index ccf9ce76f7..733a93efb9 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -78,11 +78,7 @@ function softhsm_initialize() { mkdir ".tokens" export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") # Init token - echo DEE uname -a: $(uname -a) - echo DEE softhsm version: $(softhsm2-util --version) - echo DEE whereis: $(whereis softhsm2-util) - echo DEE P11LIB: "$P11LIB" - + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" } From efffe991db0ad35498f2332a10243eb0529e8be9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:24:36 -0600 Subject: [PATCH 3751/4321] card-openpgp.c - moved malloc inside switch As suggested in PR comments, moved malloc ad test for NULL just before the memcpy --- src/libopensc/card-openpgp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index f9a7117c7e..292cbc2ef7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3019,14 +3019,13 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8 *data, size_t data_len, if (len != key_info->u.ec.ecpointQ_len) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - key_info->u.ec.ecpointQ = malloc(len); - if (key_info->u.ec.ecpointQ == NULL) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); - switch (key_info->key_type) { case SC_ALGORITHM_EC: case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: + key_info->u.ec.ecpointQ = malloc(len); + if (key_info->u.ec.ecpointQ == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); memcpy(key_info->u.ec.ecpointQ, part, len); key_info->u.ec.ecpointQ_len = len; break; From 65eb6358569eacf93149d276b3050e224d4fd730 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:28:20 -0600 Subject: [PATCH 3752/4321] card-piv.c - BYTES4BITS and format change On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-piv.c --- src/libopensc/card-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c940caa42f..096186bec3 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2730,7 +2730,7 @@ static int piv_generate_key(sc_card_t *card, break; case 0x11: keydata->key_bits = 0; keydata->ecparam = 0; /* we only support prime256v1 */ - keydata->ecparam_len =0; + keydata->ecparam_len = 0; break; case 0x14: keydata->key_bits = 0; keydata->ecparam = 0; /* we only support secp384r1 */ @@ -4680,7 +4680,7 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, r = sc_asn1_decode_ecdsa_signature(card->ctx, rbuf, r, nLen, &out, outlen); /* Yubikey 5.7.x supports ED25519 */ } else if (priv->alg_id == 0xE0) { - nLen = (priv->key_size + 7) / 8; + nLen = BYTES4BITS(priv->key_size); if (outlen < nLen) { sc_log(card->ctx, " output too small for ED signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u", From fdc152d327674fd5a4879b71a780991e308dc484 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:31:34 -0600 Subject: [PATCH 3753/4321] pkcs15-sec.c - BYTES4BITS On branch X25519-improvements-2 Changes to be committed: modified: libopensc/pkcs15-sec.c --- src/libopensc/pkcs15-sec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index bcf93670df..28560c8fc1 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -630,7 +630,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, modlen = BYTES4BITS(prkey->modulus_length) * 2; break; case SC_PKCS15_TYPE_PRKEY_EC: - modlen = ((prkey->field_length + 7) / 8) * 2; /* 2*nLen */ + modlen = BYTES4BITS(prkey->field_length) * 2; /* 2*nLen */ break; case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: @@ -772,7 +772,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, */ else if (senv.algorithm == SC_ALGORITHM_EC && (senv.algorithm_flags & SC_ALGORITHM_ECDSA_HASHES) == 0) { - inlen = MIN(inlen, (prkey->field_length+7)/8); + inlen = MIN(inlen, BYTES4BITS(prkey->field_length)); } From 92edf88625f20320ce54ffddefd76f2a0ae69383 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:32:29 -0600 Subject: [PATCH 3754/4321] framework-pkcs15.c - fixup remove unneeded free As suggested in PR comments On branch X25519-improvements-2 Changes to be committed: modified: pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index c7ffbbca34..2f05c6b26d 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2849,7 +2849,6 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile rv = attr_extract(attr, ec->params.der.value, &ec->params.der.len); if (rv != CKR_OK) { sc_clear_ec_params(&ec->params); - free(ec->params.der.value); return CKR_ATTRIBUTE_VALUE_INVALID; } break; From 3bea09c65505796d087a13364b29414c7b1c43bd Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 12 Nov 2024 10:34:17 -0600 Subject: [PATCH 3755/4321] pkcs15init/pkcs15-openpgp.c - Check length of der before using it As suggested in PR comments On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 842e3bcee8..8a1c21f80b 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -434,7 +434,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, } /* copying info_ec.id works for any EC ECDH EdDSA keys */ - if (info_ec->der.len > 2) + if (info_ec->der.len > 2 && info_ec->der.len == (size_t)(info_ec->der.value[1] + 2)) key_info.u.ec.oidv_len = info_ec->der.value[1]; else LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); From 43cdbae1b77a53484dc588119c4b3b9bc671d42c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 15 Nov 2024 05:04:56 -0600 Subject: [PATCH 3756/4321] pkcs11-tool.c - fix for X25529 WIP On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4246355a6d..63fd3f004a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6526,7 +6526,7 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot convert EC public key to DER"); #endif #ifdef EVP_PKEY_ED25519 - } else if (type == CKK_EC_EDWARDS) { + } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; CK_BYTE *params = NULL; const unsigned char *a; @@ -6545,7 +6545,7 @@ static int read_object(CK_SESSION_HANDLE session) ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { int nid = OBJ_obj2nid(obj); - if (nid != NID_ED25519) { + if (nid != NID_ED25519 && nid != NID_X25519) { util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d", NID_ED25519, nid); } From 0b5cd7fbabb0fab93278fe0b1c1896909fb254c0 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 15:06:20 -0600 Subject: [PATCH 3757/4321] pkcs11-tool.c, pkcs11-tool.1.xml - help, docs, error handling Update help, improved error handling and formating. Curve names are case insenstive. On branch X25519-improvements-2 Changes to be committed: modified: doc/tools/pkcs11-tool.1.xml modified: src/tools/pkcs11-tool.c --- doc/tools/pkcs11-tool.1.xml | 4 ++-- src/tools/pkcs11-tool.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 7ffd5940ad..b087266a4a 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -147,7 +147,7 @@ specification Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, - elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, + elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, EC:ED25519, EC:X448, GOSTR3410-2012-256:B, DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed. @@ -339,7 +339,7 @@ Read public key from the module using "CKA_PUBLIC_KEY_INFO" (use with ). The output is a "SubjectPublicKeyInfo" i.e. as used in certificates - and openssl, + and openssl. diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 63fd3f004a..9927049412 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -63,16 +63,16 @@ #include #endif -#include "pkcs11/pkcs11.h" -#include "pkcs11/pkcs11-opensc.h" -#include "libopensc/asn1.h" -#include "libopensc/log.h" -#include "libopensc/internal.h" #include "common/compat_strlcat.h" #include "common/compat_strlcpy.h" #include "common/libpkcs11.h" -#include "util.h" +#include "libopensc/asn1.h" +#include "libopensc/internal.h" +#include "libopensc/log.h" #include "libopensc/sc-ossl-compat.h" +#include "pkcs11/pkcs11-opensc.h" +#include "pkcs11/pkcs11.h" +#include "util.h" /* pkcs11-tool uses libopensc routines that do not use an sc_context * but does use some OpenSSL routines @@ -372,7 +372,7 @@ static const char *option_help[] = { "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", "Key pair generation", "Key generation", - "Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, DES:8, DES3:24, AES:16, AES: or GENERIC:64", + "Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, EC:ED25519, EC:X448, GOSTR3410-2012-256:B, DES:8, DES3:24, AES:16, AES: or GENERIC:64", "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", "Specify 'derive' key usage flag (EC only)", @@ -3183,7 +3183,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, key_type = CKK_EC; for (ii=0; ec_curve_infos[ii].name; ii++) { - if (!strcmp(ec_curve_infos[ii].name, type + 3)) + if (!strcasecmp(ec_curve_infos[ii].name, type + 3)) break; if (!strcmp(ec_curve_infos[ii].oid, type + 3)) break; @@ -3218,7 +3218,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (!opt_mechanism_used) { if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) { - util_fatal("Generate EC key mechanism %lx not supported", mtypes[0]); + util_fatal("Generate key mechanism %s not supported by token", p11_mechanism_to_name(mtypes[0])); } } @@ -5799,7 +5799,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("%02x", params_bytes[n]); if (curve_info) { /* we matched it above, use printable OID */ - printf(" (\"%s\" OID:\"%s\")", curve_info->name, curve_info->oid); + printf(" (\"%s\" OID:\"%s\")\n", curve_info->name, curve_info->oid); } else if (params_bytes[0] == SC_ASN1_OBJECT) { sc_init_oid(&oid); if (sc_asn1_decode_object_id(params_bytes, params_size, &oid) == SC_SUCCESS) { From 1daf0c0bbb305b2062bb452b543cf22209cef400 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 15:07:56 -0600 Subject: [PATCH 3758/4321] pkcs15-init.1.xml - RSA:3072 is now default On branch X25519-improvements-2 Changes to be committed: modified: doc/tools/pkcs15-init.1.xml --- doc/tools/pkcs15-init.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 9c5018297c..538ed5dc31 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -138,7 +138,7 @@ where keyspec describes the algorithm and the parameters of the key to be created. For example, rsa:2048 generates a RSA key - with 2048-bit modulus. If you are generating an EC key, the curve designation must + with 2048-bit modulus, default is 3072. If you are generating an EC key, the curve designation must be specified, for example ec:prime256v1. The following curves do not need parameters: Edwards 25519 curves use one of these equivalent names: Ed25519(preferred), ed25519 or edwards25519 From 5169743c14d1ac59001b79a05331091dd745eebc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 15:09:17 -0600 Subject: [PATCH 3759/4321] card-piv.c - Improved processing of piv_generate_key ipiv_generate_key is only called from piv-tool various formating and comments removed. On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 43 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 096186bec3..32f7989554 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2773,7 +2773,7 @@ static int piv_generate_key(sc_card_t *card, goto err; } - /* if RSA vs EC */ + /* if RSA vs EC, ED25519 or X25519 */ if (keydata->key_bits > 0 ) { tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen); if (tag != NULL && taglen <= 4) { @@ -2781,7 +2781,11 @@ static int piv_generate_key(sc_card_t *card, if (keydata->exponent == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); keydata->exponent_len = taglen; - memcpy (keydata->exponent, tag, taglen); + memcpy(keydata->exponent, tag, taglen); + } else { + sc_log(card->ctx, "Tag 0x82 not found"); + r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + goto err; } tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x81, &taglen); @@ -2792,30 +2796,44 @@ static int piv_generate_key(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } keydata->pubkey_len = taglen; - memcpy (keydata->pubkey, tag, taglen); + memcpy(keydata->pubkey, tag, taglen); + } else { + sc_log(card->ctx, "Tag 0x81 not found"); + r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + goto err; } - // } else if (keydata->key_algid == 0xE0 || keydata->key_algid == 0xE1) { - // /* TODO DEE need to look at what gets returned */ - /* TODO assume same as EC with tag 86 */ - - } else { /* must be EC */ + } else { /* must be EC, ED25519 or X25519 */ tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x86, &taglen); if (tag != NULL && taglen > 0) { keydata->ecpoint = malloc(taglen); if (keydata->ecpoint == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); keydata->ecpoint_len = taglen; - memcpy (keydata->ecpoint, tag, taglen); + memcpy(keydata->ecpoint, tag, taglen); + } else { + sc_log(card->ctx, "Tag 0x86 not found"); + r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + goto err; } } - /* TODO: -DEE Could add key to cache so could use engine to generate key, + /* Could add key to cache so could use engine to generate key, * and sign req in single operation or write temporary selfsigned - * certificate with new public key */ + * certificate with new public key + */ r = 0; } err: + if (r < 0) { + free(keydata->exponent); + keydata->exponent = NULL; + free(keydata->pubkey); + keydata->pubkey = NULL; + free(keydata->ecpoint); + keydata->ecpoint = NULL; + } + LOG_FUNC_RETURN(card->ctx, r); } @@ -4585,8 +4603,7 @@ static int piv_validate_general_authentication(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } if (priv->operation == SC_SEC_OPERATION_DERIVE - && priv->algorithm == SC_ALGORITHM_EC) { - /* TODO add code for X25519 */ + && (priv->algorithm == SC_ALGORITHM_EC || priv->algorithm == SC_ALGORITHM_XEDDSA)) { op_tag = 0x85; } else { op_tag = 0x81; From 07f911a895e3d450efcfa31e0f90dd52e65664ff Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 15:12:41 -0600 Subject: [PATCH 3760/4321] card-openpgp.c removed comments On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 292cbc2ef7..9d9ac13934 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2904,12 +2904,11 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t p15pubkey.u.rsa.exponent.len = BYTES4BITS(key_info->u.rsa.exponent_len); } /* ECC */ - /* TODO FIXME? YES 24-10-06 */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { memset(&p15pubkey, 0, sizeof(p15pubkey)); - p15pubkey.algorithm = key_info->key_type; /* TODO not set? */ + p15pubkey.algorithm = key_info->key_type; p15pubkey.u.ec.ecpointQ.value = key_info->u.ec.ecpointQ; p15pubkey.u.ec.ecpointQ.len = key_info->u.ec.ecpointQ_len; } else @@ -3085,7 +3084,6 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_inf algo->algorithm = SC_ALGORITHM_RSA; algo->key_length = (unsigned int)key_info->u.rsa.modulus_len; } - /* TODO FIXME */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { From 254b31c30fababae091d77dda0dc0fe54063c7d4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 17:09:15 -0600 Subject: [PATCH 3761/4321] tools.html - doc files On branch X25519-improvements-2 Changes to be committed: modified: doc/tools/tools.html --- doc/tools/tools.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 3116235a62..d9feec87b2 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1490,7 +1490,7 @@

    Generate a new key.

    --key-type specification

    Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, - elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, GOSTR3410-2012-256:B, + elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, EC:ED25519, EC:X448, GOSTR3410-2012-256:B, DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    --usage-sign

    Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

    @@ -1575,7 +1575,7 @@

    Read public key from the module using "CKA_PUBLIC_KEY_INFO" (use with --read-object --type public). The output is a "SubjectPublicKeyInfo" i.e. as used in certificates - and openssl,

    + and openssl.

    --puk puk

    Supply User PUK on the command line.

    --new-pin pin @@ -2009,7 +2009,7 @@

    where keyspec describes the algorithm and the parameters of the key to be created. For example, rsa:2048 generates a RSA key - with 2048-bit modulus. If you are generating an EC key, the curve designation must + with 2048-bit modulus, default is 3072. If you are generating an EC key, the curve designation must be specified, for example ec:prime256v1. The following curves do not need parameters: Edwards 25519 curves use one of these equivalent names: Ed25519(preferred), ed25519 or edwards25519 From 667ff4d1474798fdf33d59bf650625ec94ff1ef3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 18:37:27 -0600 Subject: [PATCH 3762/4321] card-openpgp.c - formating On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 9d9ac13934..7be8bef60e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3083,8 +3083,7 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_inf if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { algo->algorithm = SC_ALGORITHM_RSA; algo->key_length = (unsigned int)key_info->u.rsa.modulus_len; - } - else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ + } else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH || /* includes XEDDSA */ key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA || key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) { algo->algorithm = SC_ALGORITHM_EC; From 45a7305d8f52510bfc92d056cdba0f1fc3ab2d9a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 18:38:19 -0600 Subject: [PATCH 3763/4321] card-piv.c - formating On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 32f7989554..4d0b6f4038 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -4602,8 +4602,7 @@ static int piv_validate_general_authentication(sc_card_t *card, (r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) { LOG_FUNC_RETURN(card->ctx, r); } - if (priv->operation == SC_SEC_OPERATION_DERIVE - && (priv->algorithm == SC_ALGORITHM_EC || priv->algorithm == SC_ALGORITHM_XEDDSA)) { + if (priv->operation == SC_SEC_OPERATION_DERIVE && (priv->algorithm == SC_ALGORITHM_EC || priv->algorithm == SC_ALGORITHM_XEDDSA)) { op_tag = 0x85; } else { op_tag = 0x81; From 2bcc94cb976a3890dbbb9686a6679b68eb933260 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 18:39:35 -0600 Subject: [PATCH 3764/4321] src/libopensc/pkcs15-prkey.c - formating On branch X25519-improvements-2 Changes to be committed: modified: src/libopensc/pkcs15-prkey.c --- src/libopensc/pkcs15-prkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 6244261d90..2c9067b69f 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -822,7 +822,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) #endif /* Octetstring may need leading zeros if BN is to short */ - if (dst->privateD.len < BYTES4BITS(dst->params.field_length)) { + if (dst->privateD.len < BYTES4BITS(dst->params.field_length)) { size_t d = BYTES4BITS(dst->params.field_length) - dst->privateD.len; dst->privateD.data = realloc(dst->privateD.data, dst->privateD.len + d); From ecba32defc71ed5e83c4b04e21c9b002c99d3705 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 18:41:22 -0600 Subject: [PATCH 3765/4321] fuzz_pkcs15init.c - formating On branch X25519-improvements-2 Changes to be committed: modified: src/tests/fuzzing/fuzz_pkcs15init.c --- src/tests/fuzzing/fuzz_pkcs15init.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index fd2ed1188b..76d3d8df85 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -243,16 +243,16 @@ void do_store_secret_key(struct sc_profile *profile, struct sc_pkcs15_card *p15c sc_pkcs15_format_id("02", &(args.auth_id)); for (int i = 0; i < 3; i++) { - size_t keybytes = BYTES4BITS(keybits[i]); - args.key.data = malloc(keybytes); - memcpy(args.key.data, buf, keybytes); - args.key.data_len = keybytes; - args.algorithm = algorithms[i]; - args.value_len = keybits[i]; - - sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); - if (args.key.data) - free(args.key.data); + size_t keybytes = BYTES4BITS(keybits[i]); + args.key.data = malloc(keybytes); + memcpy(args.key.data, buf, keybytes); + args.key.data_len = keybytes; + args.algorithm = algorithms[i]; + args.value_len = keybits[i]; + + sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); + if (args.key.data) + free(args.key.data); } } From 96f95e640bc24bee5f381aaececabd9457fc92e2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 19 Nov 2024 18:42:03 -0600 Subject: [PATCH 3766/4321] common/libpkcs11.h - #include "pkcs11/pkcs11.h" On branch X25519-improvements-2 Changes to be committed: modified: src/common/libpkcs11.h --- src/common/libpkcs11.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/libpkcs11.h b/src/common/libpkcs11.h index b6bae88f9d..d29e8dce02 100644 --- a/src/common/libpkcs11.h +++ b/src/common/libpkcs11.h @@ -20,6 +20,7 @@ #ifndef __LIBPKCS11_H #define __LIBPKCS11_H +#include "pkcs11/pkcs11.h" void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); CK_RV C_UnloadModule(void *module); #endif From ff08429157051e016fb5546ffb582d6b6c1a0a88 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 25 Nov 2024 21:16:38 -0600 Subject: [PATCH 3767/4321] test-pkcs11-tool-test-threads.sh - skip if opensc-tool not present As suggested in PR comments On branch X25519-improvements-2 Changes to be committed: modified: tests/test-pkcs11-tool-test-threads.sh --- tests/test-pkcs11-tool-test-threads.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index b3d4364955..032b01fa16 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -20,6 +20,17 @@ fi echo "=======================================================" echo "Test pkcs11 threads IN " echo "=======================================================" +OPENSC_TOOL="../src/tools/opensc-tool" +echo "check for opensc-tool" +if [[ -f $OPENSC_TOOL ]] ; then +echo "trying opensc-tool -a" + $OPENSC_TOOL -a + if [[ "$?" -ne "0" ]] ; then + echo "No token found, skipping Test pkcs11 threads " + exit 77 + fi +fi + $PKCS11_TOOL --test-threads IN -L --module="$P11LIB" assert $? "Failed running tests" From 46f34e1cfc8b4d236d7e87e72e55dab848d6b2d4 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 26 Nov 2024 09:54:10 -0600 Subject: [PATCH 3768/4321] framework-pkcs15.c - use BYTES4BITS for readability On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 2f05c6b26d..ba50b469fc 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2866,17 +2866,17 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } if (key_type == CKK_EC_EDWARDS) { - if (ec->ecpointQ.len == 32) + if (ec->ecpointQ.len == BYTES4BITS(255)) ec->params.id = oid_ED25519; - else if (ec->ecpointQ.len == 56) + else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_ED448; else return CKR_ATTRIBUTE_VALUE_INVALID; } else if (key_type == CKK_EC_MONTGOMERY) { - if (ec->ecpointQ.len == 32) + if (ec->ecpointQ.len == BYTES4BITS(255)) ec->params.id = oid_X25519; - else if (ec->ecpointQ.len == 56) + else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_X448; else return CKR_ATTRIBUTE_VALUE_INVALID; From 17dd8c8ca874b12bd83062071ef3a6329e665f51 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 27 Nov 2024 17:28:55 -0600 Subject: [PATCH 3769/4321] libopensc.exports, pkcs15-pubkey.c, pkcs15.h PKCS11 pub key conversions PKCS11 v3.0 errata and 3.1 for Edwards and Montgomery public key EC_POINT is raw data not DER like EC keys when passed between PKCS11 application and PKCS11 module. PKCS15 can store public keys as raw or SPKI, but tools and other routines internal to OpenSC that have to work with OpenSSL need these keys in OCTETS STRINGS. `sc_pkcs15_encode_pubkey_eddsa_raw_to_os` is used by pkcs11-tool.c to convert a raw key to an OCTET STRING which can then be used by OpenSSL. `sc_pkcs15_encode_pubkey_eddsa_raw` is used by pkcs11/framework-pkcs15.c to retrun a EC_POINT in raw format. On branch X25519-improvements-2 Changes to be committed: modified: libopensc.exports modified: pkcs15-pubkey.c modified: pkcs15.h --- src/libopensc/libopensc.exports | 2 ++ src/libopensc/pkcs15-pubkey.c | 34 +++++++++++++++++++++++++++++++++ src/libopensc/pkcs15.h | 4 ++++ 3 files changed, 40 insertions(+) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index fbc0ea96c4..d124d65595 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -178,6 +178,8 @@ sc_pkcs15_encode_pubkey sc_pkcs15_encode_pubkey_rsa sc_pkcs15_encode_pubkey_ec sc_pkcs15_encode_pubkey_eddsa +sc_pkcs15_encode_pubkey_eddsa_raw_to_os +sc_pkcs15_encode_pubkey_eddsa_raw sc_pkcs15_encode_pubkey_gostr3410 sc_pkcs15_encode_pubkey_as_spki sc_pkcs15_encode_pukdf_entry diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 2d0e5fa3f9..fe23219b0d 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -744,6 +744,40 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } + +/* Used by pkcs11-tool to convert raw ec_point to octet_string */ +int +sc_pkcs15_encode_pubkey_eddsa_raw_to_os(sc_context_t *ctx, u8 *inbuf, size_t inlen, + u8 **buf, size_t *buflen) +{ + struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; + size_t key_len = inlen; + + + LOG_FUNC_CALLED(ctx); + sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); + sc_format_asn1_entry(asn1_eddsa_pubkey + 0, inbuf, &key_len, 1); + + + LOG_FUNC_RETURN(ctx, + sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); +} + +/* For PKCS11 3.0 errata and 3.1 Edwards and Montgomery CKA_EC_POINT are raw not DER */ +int sc_pkcs15_encode_pubkey_eddsa_raw(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, + u8 **buf, size_t *buflen) +{ + LOG_FUNC_CALLED(ctx); + + *buf = malloc(key->ecpointQ.len); + if (*buf == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + memcpy(*buf, key->ecpointQ.value, key->ecpointQ.len); + *buflen = key->ecpointQ.len; + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 361569e952..bc420eed89 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -706,6 +706,10 @@ int sc_pkcs15_encode_pubkey_ec(struct sc_context *, struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_encode_pubkey_eddsa(struct sc_context *, struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); +int sc_pkcs15_encode_pubkey_eddsa_raw_to_os(struct sc_context *, + u8 *in, size_t inlen, u8 **, size_t *); +int sc_pkcs15_encode_pubkey_eddsa_raw(struct sc_context *, + struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_decode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, const u8 *, size_t); int sc_pkcs15_encode_pubkey(struct sc_context *, From 2a7357a43d226471b8fe947a7fee3508dc8b2f6b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 27 Nov 2024 17:46:23 -0600 Subject: [PATCH 3770/4321] pkcs11/framework-pkcs15.c - Edwards and Montgomery public keys PKCS11 3.0 errata and 3.1 define Edwards and Montgomery public keys as raw byte strings. framework-pkcs15,c will now use sc_pkcs15_encode_pubkey_eddsa_raw return these EC_POINTs as raw byte strings. On branch X25519-improvements-2 Changes to be committed: modified: pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index ba50b469fc..1b590b1386 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6075,7 +6075,8 @@ get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) switch (key->algorithm) { case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: - rc = sc_pkcs15_encode_pubkey_eddsa(context, &key->u.ec, &value, &value_len); + /* For PKCS11 3.0 errata and 3.1, Edwards and Montgomery EC_POINT is raw byte string */ + rc = sc_pkcs15_encode_pubkey_eddsa_raw(context, &key->u.ec, &value, &value_len); if (rc != SC_SUCCESS) return sc_to_cryptoki_error(rc, NULL); From a9a7916611686a05d6dba0d29386d018af03f54c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 29 Nov 2024 13:20:20 -0600 Subject: [PATCH 3771/4321] pkcs15init/pkcs15-openpgp.c - avoid a double free Avoid a double free When PKCS11 tries to write a pubkey as second part to write a key. On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 8a1c21f80b..1e33f0011c 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -231,7 +231,10 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, break; /* Unlike RSA which includes modulus in privkey, - * PKCS11 stores pubkey as separate operation + * and pkcs15_init includes public ecpoint with private key, + * PKCS11 stores pubkey as separate operation and + * we only get here if called from openpgp_store_data + * after the private key was stored as first operation. */ case SC_PKCS15_TYPE_PUBKEY_EC: case SC_PKCS15_TYPE_PUBKEY_EDDSA: @@ -271,7 +274,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); - free(key_info.u.ec.ecpointQ); + /* do not free key_info.u.ec.ecpointQ. openpgp_store_data will free it */ break; default: From ad0c6a39092c9f160bfc2e72522a26d01bf08212 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 27 Nov 2024 17:52:28 -0600 Subject: [PATCH 3772/4321] tools/pkcs11-tool.c - Changes for PKCS11 v3.0 errata and v3.1 https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html PKCS11 3.0 OASIS Standard (15 June 2020) said for Edwards and Montgomery public keys: "CKA_EC_POINT | byte array | DER-encoding of ANSI X9.62 ECPoint value Q" https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.pdf PKCS11 3.1 OASIS Standard (23 July 2023) says for Edwards public keys: "CKA_EC_POINT | Byte array | Public key bytes in little endian order as defined in RFC 8032" and for Montgomery public keys: "CKA_EC_POINT | Byte array | Public key bytes in little endian order as defined in RFC 7748" https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/errata01/csd01/pkcs11-curr-v3.0-errata01-csd01-public-review-metadata.html announces v3.0 errata with comments ending on 07 June 2024. This puts V3.0 in line with v3.1 In order to align OpenSC PKCS11 module and pkcs11-tool to v3.1 specs: Pkcs11-tool will send EC_POINT for Edwards and Montgomery public keys to a PKCS11 module as raw byte string. pkcs11-tool will accept an EC_POINT from a pkcs11 module as raw byte string, OCTET STRING or BIT STRING. Note: CKA_PUBLIC_KEY_INFO is SubjectPublicKeyInfo as defined in RFC8410. Additional tests when compiled by OpenSSL older versions and Libressl 3.8.4 have been added and a signautre operation using a Yubkey Ed25519 key verifies using OpenSSL 3.3.2 utilities. Pkcs11-tool as input and output files use RFC 8410 formats as OpenSSL formats are based on RFC 8410. On branch X25519-improvements-2 Changes to be committed: modified: tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 85 +++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9927049412..b1c98a3757 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4686,15 +4686,15 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } - else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type = CKK_EC_MONTGOMERY)) { + else if ((type == CKK_EC) ||(type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); n_privkey_attr++; + } else if (type == CKK_GOSTR3410) { - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len); @@ -4769,6 +4769,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; } #if !defined(OPENSSL_NO_EC) + else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); @@ -6331,13 +6332,14 @@ static int read_object(CK_SESSION_HANDLE session) /* If module supports CKA_PUBLIC_KEY_INFO which is DER of SPKI * return whatever the module provides including ED448 and X448 */ - if (opt_public_key_info) + if (opt_public_key_info) { value = getPUBLIC_KEY_INFO(session, obj, &len); - /* softhsm2 may return length 0 and varattr may allocate memory treat as invalid */ - if (value && len == 0) { - p11_warn("getPUBLIC_KEY_INFO returned a value of length 0", 0); - free(value); - value = NULL; + /* softhsm2 may return length 0 and varattr may allocate memory treat as invalid */ + if (value && len == 0) { + p11_warn("getPUBLIC_KEY_INFO returned a value of length 0", 0); + free(value); + value = NULL; + } } if (value == NULL) { /* Do the old way */ #ifdef ENABLE_OPENSSL @@ -6525,12 +6527,15 @@ static int read_object(CK_SESSION_HANDLE session) if (!i2d_PUBKEY_bio(pout, pkey)) util_fatal("cannot convert EC public key to DER"); #endif + /* only if compiled with a version of or OpenSSL or libressl */ + /* do more tests for the other 3 as needed */ #ifdef EVP_PKEY_ED25519 } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; CK_BYTE *params = NULL; const unsigned char *a; ASN1_OCTET_STRING *os; + int raw_pk = 0; if ((params = getEC_PARAMS(session, obj, &len))) { ASN1_PRINTABLESTRING *curve = NULL; @@ -6538,9 +6543,9 @@ static int read_object(CK_SESSION_HANDLE session) a = params; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { - if (strcmp((char *)curve->data, "edwards25519")) { - util_fatal("Unknown curve name, expected edwards25519, got %s", - curve->data); + if (strcmp((char *)curve->data, "edwards25519") && + strcmp((char *)curve->data, "curve25519")) { + util_fatal("Unknown curve name \"%si\"", curve->data); } ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { @@ -6559,21 +6564,56 @@ static int read_object(CK_SESSION_HANDLE session) } value = getEC_POINT(session, obj, &len); - /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ - /* No, should be in BIT STRING accept both */ + /* PKCS11 3.0 errta and 3.1 say Edwards and Montgomery + * return raw byte strings, convert to OCTET string for OpenSSL + * Will asccept as OCT STRING + */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); if (!os) { os = d2i_ASN1_BIT_STRING(NULL, &a, (long)len); - len = BYTES4BITS(len); + if (os) + len = BYTES4BITS(len); } if (!os) { - util_fatal("cannot decode EC_POINT"); + size_t buflen = 0; + unsigned char * buf = NULL; + unsigned char *in = value; + + if (sc_pkcs15_encode_pubkey_eddsa_raw_to_os(NULL, + in, (size_t) len, + &buf, &buflen) != 0) { + util_fatal("cannot obtain EC POINT"); + } + a = buf; + if ((os = d2i_ASN1_OCTET_STRING(NULL, &a, + (long) buflen)) == NULL) { + util_fatal("cannot obtain EC POINT"); + } + free(buf); } - if (os->length != 32) { - util_fatal("Invalid length of EC_POINT value"); + if (!os) { + util_fatal("cannot decode EC_POINT"); } - key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, + + if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) + raw_pk = EVP_PKEY_ED25519; +#if defined(EVP_PKEY_ED448) + else if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(448)) + raw_pk = EVP_PKEY_ED448; +#endif /* EVP_PKEY_ED448 */ +#if defined(EVP_PKEY_X25519) + else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(255)) + raw_pk = EVP_PKEY_X25519; +#endif /*EVP_PKEY_X25519 */ +#if defined(EVP_PKEY_X448) + else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(448)) + raw_pk = EVP_PKEY_X448; +#endif /* EVP_PKEY_X448 */ + else + util_fatal("Invalid or not supported CKK_EC_EDWARDS or CKK_EC_MONTGOMERY public key"); + + key = EVP_PKEY_new_raw_public_key(raw_pk, NULL, (const uint8_t *)os->data, os->length); ASN1_STRING_free(os); @@ -6581,7 +6621,9 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("out of memory"); } /* Note, that we write PEM here as there is no "native" - * representation of EdDSA public keys to use */ + * in RFC 8410 /OpenSSL format + * representation of EdDSA public keys to use + */ if (!PEM_write_bio_PUBKEY(pout, key)) { util_fatal("cannot convert EdDSA public key to PEM"); } @@ -8721,7 +8763,10 @@ static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session) return; } getEC_POINT(session, pub_key, &ec_point_len); - /* TODO only looking at length of encoded EC_POINT. May be in BIT STRING or OCTET STRING */ + /* TODO if this routine us expanded to test EDDSA keys the following may be needed. + * a per 3.0 errata and 3.1 Edwards and Montgomery EC_POINT is just a byte string. + * Accept either BIT STRING, OCTET STRING or raw byte string. + */ if (ec_point_len < 5 || ec_point_len > 10000) { printf("ERR: GetAttribute(pubkey, CKA_EC_POINT) doesn't seem to work\n"); return; From 8bede17020771dc2aee9af918d7eb02c4d20a995 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 5 Dec 2024 07:52:36 -0600 Subject: [PATCH 3773/4321] card-openpgp.c - return SPKI in pgp_get_pubkey_pem On branch X25519-improvements-2 Changes to be committed: modified: libopensc/card-openpgp.c --- src/libopensc/card-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7be8bef60e..5b9b9e422e 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1747,7 +1747,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use * of the curveName selection to specify a curve name as defined * in [RFC 8032] */ - r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); + r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); break; case SC_OPENPGP_KEYALGO_ECDH: /* This yields either EC(DSA) key or EC_MONTGOMERY (curve25519) key */ @@ -2914,7 +2914,7 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t } else LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - r = sc_pkcs15_encode_pubkey(card->ctx, &p15pubkey, &data, &len); + r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); sc_log(card->ctx, "Updating blob %04X's content.", blob_id); From 466ba0ca82e2c311b2a3e102a2e48b1d753b03ec Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 5 Dec 2024 07:55:23 -0600 Subject: [PATCH 3774/4321] pkcs15init/pkcs15-lib.c - pass key_id CKA_ID default usage for ECDH --- src/pkcs15init/pkcs15-lib.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index fa5d38eca7..4b5f2813bc 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1919,8 +1919,13 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile } if ((usage = keyargs->usage) == 0) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting default usage to verify"); - usage = SC_PKCS15_PRKEY_USAGE_VERIFY; + if (type == SC_PKCS15_TYPE_PUBKEY_XEDDSA) { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting default usage to derive"); + usage = SC_PKCS15_PRKEY_USAGE_DERIVE; + } else { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting default usage to verify"); + usage = SC_PKCS15_PRKEY_USAGE_VERIFY; + } if (keyargs->x509_usage) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Setting usage from keyargs->x509_usage"); usage = sc_pkcs15init_map_usage(keyargs->x509_usage, 0); @@ -1941,9 +1946,11 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile key_info = (struct sc_pkcs15_pubkey_info *) object->data; key_info->usage = usage; - key_info->modulus_length = keybits; + key_info->id = keyargs->id; - if (key.algorithm == SC_ALGORITHM_GOSTR3410) { + if (key.algorithm == SC_ALGORITHM_RSA) { + key_info->modulus_length = keybits; + } else if (key.algorithm == SC_ALGORITHM_GOSTR3410) { key_info->params.len = sizeof(*keyinfo_gostparams); /* FIXME: malloc() call in pkcs15init, but free() call * in libopensc (sc_pkcs15_free_prkey_info) */ From f600e0c18e3fad20cb0dcc7c6f87fd8097a03ccc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 10 Dec 2024 14:48:06 -0600 Subject: [PATCH 3775/4321] pkcs15init/pkcs15-openpgp.c - fizxup copy ecpointQ correctly On branch X25519-improvements-2 Changes to be committed: modified: pkcs15init/pkcs15-openpgp.c --- src/pkcs15init/pkcs15-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 1e33f0011c..e3293d94ae 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -221,7 +221,7 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.u.ec.ecpointQ = malloc(key->u.ec.ecpointQ.len); if (!key_info.u.ec.ecpointQ) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(&key_info.u.ec.ecpointQ, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len); + memcpy(key_info.u.ec.ecpointQ, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len); } key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; key_info.u.ec.oid = key->u.ec.params.id; From 77314cbade259b6a8f2138e4cd959605eebeced3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 11 Dec 2024 11:05:43 -0600 Subject: [PATCH 3776/4321] pkcs15-pubkey.c - move secp256r1 to be first in list Some curves heve multiple names with same OID. OpenSSL in some calls only uses one name. A search for an OID will find the first OID which may not have the curve name used by OpenSSL, resulting in an unsupported curve name error. So "secp256r1" is placed first. On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-pubkey.c --- src/libopensc/pkcs15-pubkey.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index fe23219b0d..4ebc2607ed 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -744,7 +744,6 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - /* Used by pkcs11-tool to convert raw ec_point to octet_string */ int sc_pkcs15_encode_pubkey_eddsa_raw_to_os(sc_context_t *ctx, u8 *inbuf, size_t inlen, @@ -753,27 +752,26 @@ sc_pkcs15_encode_pubkey_eddsa_raw_to_os(sc_context_t *ctx, u8 *inbuf, size_t inl struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; size_t key_len = inlen; - LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); sc_format_asn1_entry(asn1_eddsa_pubkey + 0, inbuf, &key_len, 1); - LOG_FUNC_RETURN(ctx, sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); } /* For PKCS11 3.0 errata and 3.1 Edwards and Montgomery CKA_EC_POINT are raw not DER */ -int sc_pkcs15_encode_pubkey_eddsa_raw(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, +int +sc_pkcs15_encode_pubkey_eddsa_raw(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { LOG_FUNC_CALLED(ctx); *buf = malloc(key->ecpointQ.len); if (*buf == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(*buf, key->ecpointQ.value, key->ecpointQ.len); - *buflen = key->ecpointQ.len; + *buflen = key->ecpointQ.len; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -1533,8 +1531,8 @@ static struct ec_curve_info { {"secp224r1", "1.3.132.0.33", {(u8 *)"\x06\x05\x2b\x81\x04\x00\x21", 7}, 224, SC_ALGORITHM_EC}, {"nistp224", "1.3.132.0.33", {(u8 *)"\x06\x05\x2b\x81\x04\x00\x21", 7}, 224, SC_ALGORITHM_EC}, - {"secp256r1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, {"prime256v1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, + {"secp256r1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, {"nistp256", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, {"ansiX9p256r1", "1.2.840.10045.3.1.7", {(u8 *)"\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07", 10}, 256, SC_ALGORITHM_EC}, From a89e50d08a9c9dad90817867c9aad67ff64e6c95 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 13 Dec 2024 06:34:33 -0600 Subject: [PATCH 3777/4321] pkcs15init/pkcs15-openpgp.c - revert trying to store public key The ability to store the public key on OpenPGP cards is optional. NitroStart and Yubikey both fail to store or accep the store but can not read the stored key. It may be possible but not with the code being reverted. --- src/pkcs15init/pkcs15-openpgp.c | 89 +++++---------------------------- 1 file changed, 12 insertions(+), 77 deletions(-) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index e3293d94ae..b3172d13d2 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -171,16 +171,8 @@ openpgp_set_algorithm(sc_pkcs15_card_t *p15card, static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { - /* Maybe called internally to write public key because PKCS11 stores - * private and public keys in separate operations. In this case - * the object will have a type of SC_PKCS15_TYPE_PUBLIC_* - * and key will be sc_pkcs15_pubkey_t - */ sc_card_t *card = p15card->card; - sc_pkcs15_pubkey_t *pubkey = (sc_pkcs15_pubkey_t *)key; /* maybe pubkey */ sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; - sc_pkcs15_pubkey_info_t *pubkinfo = (sc_pkcs15_pubkey_info_t *)obj->data; - sc_cardctl_openpgp_key_gen_store_info_t key_info = {0}; int r; @@ -216,7 +208,11 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, key_info.key_id = kinfo->id.value[0]; key_info.u.ec.privateD = key->u.ec.privateD.data; key_info.u.ec.privateD_len = key->u.ec.privateD.len; - /* key->u.ec.ecpointQ.len is optional with private key */ + /* + * key->u.ec.ecpointQ.len is optional with private key + * PKCS11 does not pass it when creting private key object. + * pkcs15init/pkcs15-lib.c will attempt to derive it from private key + */ if (key->u.ec.ecpointQ.len) { key_info.u.ec.ecpointQ = malloc(key->u.ec.ecpointQ.len); if (!key_info.u.ec.ecpointQ) @@ -225,58 +221,12 @@ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len; key_info.u.ec.oid = key->u.ec.params.id; + key_info.key_type = key->algorithm; /* SC_SC_ALGORITHM_* */ r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); free(key_info.u.ec.ecpointQ); break; - /* Unlike RSA which includes modulus in privkey, - * and pkcs15_init includes public ecpoint with private key, - * PKCS11 stores pubkey as separate operation and - * we only get here if called from openpgp_store_data - * after the private key was stored as first operation. - */ - case SC_PKCS15_TYPE_PUBKEY_EC: - case SC_PKCS15_TYPE_PUBKEY_EDDSA: - case SC_PKCS15_TYPE_PUBKEY_XEDDSA: - memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t)); - - r = openpgp_set_algorithm(p15card, pubkinfo->id.value[0], obj->type, &key_info.algorithm); - LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id"); - - key_info.key_id = pubkinfo->id.value[0]; - if (pubkey->u.ec.ecpointQ.len) { - key_info.u.ec.ecpointQ = malloc(pubkey->u.ec.ecpointQ.len); - if (!key_info.u.ec.ecpointQ) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(&key_info.u.ec.ecpointQ, &pubkey->u.ec.ecpointQ.value, pubkey->u.ec.ecpointQ.len); - key_info.u.ec.ecpointQ_len = pubkey->u.ec.ecpointQ.len; - } - /* copy oid, oid_len and key_length from pubkey */ - - if (pubkey->u.ec.params.der.len > 2) - key_info.u.ec.oidv_len = pubkey->u.ec.params.der.value[1]; - else { - free(key_info.u.ec.ecpointQ); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - - for (size_t i = 0; (i < key_info.u.ec.oidv_len) && (i + 2 < pubkey->u.ec.params.der.len); i++) { - key_info.u.ec.oidv.value[i] = pubkey->u.ec.params.der.value[i + 2]; - } - key_info.u.ec.oidv.value[key_info.u.ec.oidv_len] = -1; - - /* copy sc_object_id too */ - key_info.u.ec.oid = pubkey->u.ec.params.id; - - key_info.u.ec.key_length = pubkey->u.ec.params.field_length; - key_info.key_type = pubkey->u.ec.params.key_type; - - r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); - - /* do not free key_info.u.ec.ecpointQ. openpgp_store_data will free it */ - break; - default: r = SC_ERROR_NOT_SUPPORTED; sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r)); @@ -548,30 +498,16 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile sc_pkcs15_id_t *cid; sc_pkcs15_data_info_t *dinfo; u8 buf[254]; - int r = 0; - sc_pkcs15_pubkey_t *pubkey = NULL; + int r; LOG_FUNC_CALLED(card->ctx); switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: - r = SC_SUCCESS; - break; - case SC_PKCS15_TYPE_PUBKEY: - - if (obj->type == SC_PKCS15_TYPE_PUBKEY_EC || - obj->type == SC_PKCS15_TYPE_PUBKEY_EDDSA || - obj->type == SC_PKCS15_TYPE_PUBKEY_XEDDSA) { - r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey); - LOG_TEST_GOTO_ERR(ctx, r, "Failed to get pubkey from spki"); - - /* PKCS11 stores private and public keys as two operations */ - r = openpgp_store_key(profile, p15card, obj, (void *)pubkey); - LOG_TEST_GOTO_ERR(ctx, r, "Failed to store pubkey fromk spki"); - - r = SC_SUCCESS; - } + /* For these two type, store_data just don't need to do anything. + * All have been done already before this function is called */ + r = SC_SUCCESS; break; case SC_PKCS15_TYPE_CERT: @@ -654,8 +590,7 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile default: r = SC_ERROR_NOT_IMPLEMENTED; } -err: - sc_pkcs15_free_pubkey(pubkey); + sc_file_free(file); LOG_FUNC_RETURN(card->ctx, r); } @@ -669,7 +604,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = { openpgp_create_pin, NULL, /* select key reference */ openpgp_create_key, - openpgp_store_key, /* May be called for private and public key twice */ + openpgp_store_key, openpgp_generate_key, NULL, NULL, /* encode private/public key */ NULL, /* finalize_card */ From d60f255166f23a3694188e8016c36aae6e7f64d5 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 13 Dec 2024 17:14:29 -0600 Subject: [PATCH 3778/4321] pkcs11-tool.c - output Edwards or Montgomery keys in DER format When reading an EC or RSA public key, the output is on DER format But current code was writting Edwards keys in PEM format and did not support Montgomery keys. Pkcs11-tool will now write all public keys DER format. On branch X25519-improvements-2 Changes to be committed: modified: pkcs11-tool.c --- src/tools/pkcs11-tool.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b1c98a3757..03c2cba481 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4686,14 +4686,14 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } - else if ((type == CKK_EC) ||(type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { + else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); n_privkey_attr++; - + } else if (type == CKK_GOSTR3410) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; @@ -6527,8 +6527,8 @@ static int read_object(CK_SESSION_HANDLE session) if (!i2d_PUBKEY_bio(pout, pkey)) util_fatal("cannot convert EC public key to DER"); #endif - /* only if compiled with a version of or OpenSSL or libressl */ - /* do more tests for the other 3 as needed */ + /* only if compiled with a version of or OpenSSL or libressl */ + /* do more tests for the other 3 as needed */ #ifdef EVP_PKEY_ED25519 } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; @@ -6566,7 +6566,7 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS11 3.0 errta and 3.1 say Edwards and Montgomery * return raw byte strings, convert to OCTET string for OpenSSL - * Will asccept as OCT STRING + * Will asccept as OCTET STRING */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); @@ -6577,17 +6577,17 @@ static int read_object(CK_SESSION_HANDLE session) } if (!os) { size_t buflen = 0; - unsigned char * buf = NULL; + unsigned char *buf = NULL; unsigned char *in = value; if (sc_pkcs15_encode_pubkey_eddsa_raw_to_os(NULL, - in, (size_t) len, - &buf, &buflen) != 0) { + in, (size_t)len, + &buf, &buflen) != 0) { util_fatal("cannot obtain EC POINT"); } a = buf; if ((os = d2i_ASN1_OCTET_STRING(NULL, &a, - (long) buflen)) == NULL) { + (long)buflen)) == NULL) { util_fatal("cannot obtain EC POINT"); } free(buf); @@ -6595,7 +6595,7 @@ static int read_object(CK_SESSION_HANDLE session) if (!os) { util_fatal("cannot decode EC_POINT"); } - + if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) raw_pk = EVP_PKEY_ED25519; #if defined(EVP_PKEY_ED448) @@ -6609,7 +6609,7 @@ static int read_object(CK_SESSION_HANDLE session) #if defined(EVP_PKEY_X448) else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(448)) raw_pk = EVP_PKEY_X448; -#endif /* EVP_PKEY_X448 */ +#endif /* EVP_PKEY_X448 */ else util_fatal("Invalid or not supported CKK_EC_EDWARDS or CKK_EC_MONTGOMERY public key"); @@ -6620,12 +6620,8 @@ static int read_object(CK_SESSION_HANDLE session) if (key == NULL) { util_fatal("out of memory"); } - /* Note, that we write PEM here as there is no "native" - * in RFC 8410 /OpenSSL format - * representation of EdDSA public keys to use - */ - if (!PEM_write_bio_PUBKEY(pout, key)) { - util_fatal("cannot convert EdDSA public key to PEM"); + if (i2d_PUBKEY_bio(pout, key) < 1) { + util_fatal("cannot write public key to output"); } EVP_PKEY_free(key); @@ -6642,6 +6638,7 @@ static int read_object(CK_SESSION_HANDLE session) } else value = getVALUE(session, obj, &len); + if (value == NULL) util_fatal("get CKA_VALUE failed"); @@ -8763,7 +8760,7 @@ static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session) return; } getEC_POINT(session, pub_key, &ec_point_len); - /* TODO if this routine us expanded to test EDDSA keys the following may be needed. + /* TODO if this routine us expanded to test EDDSA keys the following may be needed. * a per 3.0 errata and 3.1 Edwards and Montgomery EC_POINT is just a byte string. * Accept either BIT STRING, OCTET STRING or raw byte string. */ From 55d998005326aad0926fe010f799c37481142e4b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 14 Dec 2024 06:14:04 -0600 Subject: [PATCH 3779/4321] card-openpgp.c - avoid a memory leak --- src/libopensc/card-openpgp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5b9b9e422e..69b458388f 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1747,7 +1747,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) /* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use * of the curveName selection to specify a curve name as defined * in [RFC 8032] */ - r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); + r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); break; case SC_OPENPGP_KEYALGO_ECDH: /* This yields either EC(DSA) key or EC_MONTGOMERY (curve25519) key */ @@ -2915,6 +2915,12 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len); + /* + * key_info is missing an algo_id. sc_pkcs15_encode_pubkey_as_spki + * allocates one. Free it here. + */ + free(p15pubkey.alg_id); + p15pubkey.alg_id = NULL; LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); sc_log(card->ctx, "Updating blob %04X's content.", blob_id); From 6af2c6e49ba37a980ef73828accf7b2d4878ab0d Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 6 Jan 2025 08:36:18 -0600 Subject: [PATCH 3780/4321] fuzz_pkcs15init.c formating Changes to be committed: modified: tests/fuzzing/fuzz_pkcs15init.c --- src/tests/fuzzing/fuzz_pkcs15init.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 76d3d8df85..ea9c84fa38 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -243,16 +243,16 @@ void do_store_secret_key(struct sc_profile *profile, struct sc_pkcs15_card *p15c sc_pkcs15_format_id("02", &(args.auth_id)); for (int i = 0; i < 3; i++) { - size_t keybytes = BYTES4BITS(keybits[i]); - args.key.data = malloc(keybytes); - memcpy(args.key.data, buf, keybytes); - args.key.data_len = keybytes; - args.algorithm = algorithms[i]; - args.value_len = keybits[i]; - - sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); - if (args.key.data) - free(args.key.data); + size_t keybytes = BYTES4BITS(keybits[i]); + args.key.data = malloc(keybytes); + memcpy(args.key.data, buf, keybytes); + args.key.data_len = keybytes; + args.algorithm = algorithms[i]; + args.value_len = keybits[i]; + + sc_pkcs15init_store_secret_key(p15card, profile, &args, NULL); + if (args.key.data) + free(args.key.data); } } From 07d0a2ebe293933edf30da8e63fd448dfb5e270b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 6 Jan 2025 08:49:10 -0600 Subject: [PATCH 3781/4321] pkcs15-sec.c - simplify code, remove 2 lines On branch X25519-improvements-2 Changes to be committed: modified: pkcs15-sec.c --- src/libopensc/pkcs15-sec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 28560c8fc1..262168166f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -630,8 +630,6 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, modlen = BYTES4BITS(prkey->modulus_length) * 2; break; case SC_PKCS15_TYPE_PRKEY_EC: - modlen = BYTES4BITS(prkey->field_length) * 2; /* 2*nLen */ - break; case SC_PKCS15_TYPE_PRKEY_EDDSA: case SC_PKCS15_TYPE_PRKEY_XEDDSA: modlen = BYTES4BITS(prkey->field_length) * 2; /* 2*nLen */ From dbcc4284950020ebb49817a33a42c524ab1baf7b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 6 Jan 2025 08:55:50 -0600 Subject: [PATCH 3782/4321] card-piv.c - fix comments Yubikey 5.7.1 can support RSA 4096 --- src/libopensc/card-piv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 4d0b6f4038..50bd73dedb 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -4583,8 +4583,7 @@ static int piv_validate_general_authentication(sc_card_t *card, unsigned int cla, tag; unsigned int real_alg_id, op_tag; - /* TODO check for 4096 keys */ - u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ + u8 sbuf[4096]; /* needs work. for 4096 needs 512+10 or so */ size_t sbuflen = sizeof(sbuf); u8 rbuf[4096]; From f19a2c9df194cb0dc62ae021341478e64103a783 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 28 Jan 2025 12:40:11 -0600 Subject: [PATCH 3783/4321] pkcs11-tool.c - drop usage of sc_pkcs15_encode_pubkey_eddsa_raw_to_os sc_pkcs15_encode_pubkey_eddsa_raw_is being replaced with OpenSSL ASN1_OCTET_STRING_new and ASN1_OCTET_STRING_set On branch X25519-improvements-2 Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 03c2cba481..0f39eca87e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6527,7 +6527,7 @@ static int read_object(CK_SESSION_HANDLE session) if (!i2d_PUBKEY_bio(pout, pkey)) util_fatal("cannot convert EC public key to DER"); #endif - /* only if compiled with a version of or OpenSSL or libressl */ + /* only if compiled with a version of OpenSSL or libressl */ /* do more tests for the other 3 as needed */ #ifdef EVP_PKEY_ED25519 } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { @@ -6566,7 +6566,7 @@ static int read_object(CK_SESSION_HANDLE session) value = getEC_POINT(session, obj, &len); /* PKCS11 3.0 errta and 3.1 say Edwards and Montgomery * return raw byte strings, convert to OCTET string for OpenSSL - * Will asccept as OCTET STRING + * Will asccept as OCTET STRING and BIT_STRING */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); @@ -6576,24 +6576,11 @@ static int read_object(CK_SESSION_HANDLE session) len = BYTES4BITS(len); } if (!os) { - size_t buflen = 0; - unsigned char *buf = NULL; - unsigned char *in = value; - - if (sc_pkcs15_encode_pubkey_eddsa_raw_to_os(NULL, - in, (size_t)len, - &buf, &buflen) != 0) { - util_fatal("cannot obtain EC POINT"); + if ((os = ASN1_OCTET_STRING_new()) == NULL) + util_fatal("cannot decode EC_POINT"); + if (ASN1_OCTET_STRING_set(os, value, (long)len) == 0) { + util_fatal("cannot decode EC_POINT"); } - a = buf; - if ((os = d2i_ASN1_OCTET_STRING(NULL, &a, - (long)buflen)) == NULL) { - util_fatal("cannot obtain EC POINT"); - } - free(buf); - } - if (!os) { - util_fatal("cannot decode EC_POINT"); } if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) From 7ee3b9938537b70a4ce26b31216e25e546f03440 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 28 Jan 2025 13:55:43 -0600 Subject: [PATCH 3784/4321] framework-pkcs15.c - drop use of sc_pkcs15_encode_pubkey_raw sc_pkcs15_encode_pubkey_eddsa_raw_is being replaced with inline code. On branch X25519-improvements-2 Changes to be committed: modified: src/pkcs11/framework-pkcs15.c --- src/pkcs11/framework-pkcs15.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1b590b1386..6ef2cb67cd 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6076,24 +6076,20 @@ get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) case SC_ALGORITHM_EDDSA: case SC_ALGORITHM_XEDDSA: /* For PKCS11 3.0 errata and 3.1, Edwards and Montgomery EC_POINT is raw byte string */ - rc = sc_pkcs15_encode_pubkey_eddsa_raw(context, &key->u.ec, &value, &value_len); - if (rc != SC_SUCCESS) - return sc_to_cryptoki_error(rc, NULL); + /* key->key->u.ec.ecpointQ is raw byte string */ + if (key->u.ec.ecpointQ.value == NULL || key->u.ec.ecpointQ.len == 0) + return CKR_ATTRIBUTE_TYPE_INVALID; if (attr->pValue == NULL_PTR) { - attr->ulValueLen = value_len; - free(value); + attr->ulValueLen = key->u.ec.ecpointQ.len; return CKR_OK; } - if (attr->ulValueLen < value_len) { - attr->ulValueLen = value_len; - free(value); + if (attr->ulValueLen < key->u.ec.ecpointQ.len) { + attr->ulValueLen = key->u.ec.ecpointQ.len; return CKR_BUFFER_TOO_SMALL; } - attr->ulValueLen = value_len; - - memcpy(attr->pValue, value, value_len); - free(value); + attr->ulValueLen = key->u.ec.ecpointQ.len; + memcpy(attr->pValue, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len); return CKR_OK; case SC_ALGORITHM_EC: From 20bd9ef27a490d6d0188e69979628cb417b197da Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 28 Jan 2025 14:08:37 -0600 Subject: [PATCH 3785/4321] Revert "libopensc.exports, pkcs15-pubkey.c, pkcs15.h PKCS11 pub key conversions" This reverts commit 17dd8c8ca874b12bd83062071ef3a6329e665f51. Changes to be committed: modified: src/libopensc/libopensc.exports modified: src/libopensc/pkcs15-pubkey.c modified: src/libopensc/pkcs15.h --- src/libopensc/libopensc.exports | 2 -- src/libopensc/pkcs15-pubkey.c | 32 -------------------------------- src/libopensc/pkcs15.h | 4 ---- 3 files changed, 38 deletions(-) diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index d124d65595..fbc0ea96c4 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -178,8 +178,6 @@ sc_pkcs15_encode_pubkey sc_pkcs15_encode_pubkey_rsa sc_pkcs15_encode_pubkey_ec sc_pkcs15_encode_pubkey_eddsa -sc_pkcs15_encode_pubkey_eddsa_raw_to_os -sc_pkcs15_encode_pubkey_eddsa_raw sc_pkcs15_encode_pubkey_gostr3410 sc_pkcs15_encode_pubkey_as_spki sc_pkcs15_encode_pukdf_entry diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 4ebc2607ed..2ff130c22d 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -744,38 +744,6 @@ sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } -/* Used by pkcs11-tool to convert raw ec_point to octet_string */ -int -sc_pkcs15_encode_pubkey_eddsa_raw_to_os(sc_context_t *ctx, u8 *inbuf, size_t inlen, - u8 **buf, size_t *buflen) -{ - struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE]; - size_t key_len = inlen; - - LOG_FUNC_CALLED(ctx); - sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey); - sc_format_asn1_entry(asn1_eddsa_pubkey + 0, inbuf, &key_len, 1); - - LOG_FUNC_RETURN(ctx, - sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen)); -} - -/* For PKCS11 3.0 errata and 3.1 Edwards and Montgomery CKA_EC_POINT are raw not DER */ -int -sc_pkcs15_encode_pubkey_eddsa_raw(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, - u8 **buf, size_t *buflen) -{ - LOG_FUNC_CALLED(ctx); - - *buf = malloc(key->ecpointQ.len); - if (*buf == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(*buf, key->ecpointQ.value, key->ecpointQ.len); - *buflen = key->ecpointQ.len; - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); -} - int sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index bc420eed89..361569e952 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -706,10 +706,6 @@ int sc_pkcs15_encode_pubkey_ec(struct sc_context *, struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_encode_pubkey_eddsa(struct sc_context *, struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); -int sc_pkcs15_encode_pubkey_eddsa_raw_to_os(struct sc_context *, - u8 *in, size_t inlen, u8 **, size_t *); -int sc_pkcs15_encode_pubkey_eddsa_raw(struct sc_context *, - struct sc_pkcs15_pubkey_ec *, u8 **, size_t *); int sc_pkcs15_decode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, const u8 *, size_t); int sc_pkcs15_encode_pubkey(struct sc_context *, From f2eb2fbe045e35765c1b5ebb315119db4fda5406 Mon Sep 17 00:00:00 2001 From: Eugene Mironenko Date: Fri, 24 Jan 2025 17:24:57 +0300 Subject: [PATCH 3786/4321] pkcs11-tool: fix percent-encoding of id in pkcs11-uri Fixes #3325 --- src/tools/pkcs11-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e8f69f45db..199d621d99 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5861,9 +5861,9 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) get_token_info(opt_slot, &info); printf(" uri: %s", get_uri(&info)); if (id != NULL && idsize) { - printf(";id=%%"); + printf(";id="); for (unsigned int n = 0; n < idsize; n++) - printf("%02x", id[n]); + printf("%%%02x", id[n]); free(id); } if (label != NULL) { @@ -5963,9 +5963,9 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) get_token_info(opt_slot, &info); printf(" uri: %s", get_uri(&info)); if (id != NULL && size) { - printf(";id=%%"); + printf(";id="); for (unsigned int n = 0; n < size; n++) - printf("%02x", id[n]); + printf("%%%02x", id[n]); free(id); } if (label != NULL) { From 107a85153f617163e144fb68ea2c3717038ca697 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 11 Jan 2025 11:47:34 -0600 Subject: [PATCH 3787/4321] setup-linux.sh - get package name for debug Use the same OpenSSL package names as installed for libs. Newer versions use a different naming convention for libs. On branch github-setup Changes to be committed: modified: setup-linux.sh --- .github/setup-linux.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 24aa9e7d0f..94882a0322 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -91,7 +91,9 @@ deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-proposed main restri $SUDO apt-get update -qq DEP="libssl1.1-dbgsym" if [ -f "/usr/lib/x86_64-linux-gnu/libssl.so.3" ]; then - DEP="libssl3t64-dbgsym" +# libcrypto is in same package as libssl + DEPX=`dpkg -S "/usr/lib/x86_64-linux-gnu/libssl.so.3"` + DEP="${DEPX%%:*}-dbgsym" fi $SUDO apt-get install -y openssl-dbgsym "$DEP" softhsm2-dbgsym libsofthsm2-dbgsym fi From 97e590428d5edb1299a75a5d52ec4d2626410a93 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Sat, 28 Oct 2023 23:10:43 +0200 Subject: [PATCH 3788/4321] pkcs11: Fix C_WaitForSlotEvent() not working in Windows If there are any readers present when C_WaitForSlotEvent() is called, C_WaitForSlotEvent() returns immediately and does not wait for the card/slot event to happen. Apparently the MSDN documentation for SCardGetStatusChange() is inaccurate/incomplete and the dwCurrentState for \\?PnP?\Notification reader should contain the number of readers in it's HiWord to work properly. See https://stackoverflow.com/questions/16370909. --- src/libopensc/reader-pcsc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index ae0fd85fde..51b974a598 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1654,6 +1654,11 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re #else rgReaderStates[num_watch].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE; +#ifdef _WIN32 + /* Windows expects number of readers in HiWord of dwCurrentState. + * See https://stackoverflow.com/questions/16370909. */ + rgReaderStates[num_watch].dwCurrentState |= (num_watch << 16); +#endif rgReaderStates[num_watch].dwEventState = SCARD_STATE_UNAWARE; num_watch++; sc_log(ctx, "Trying to detect new readers"); @@ -1720,6 +1725,13 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re prev_state = rsp->dwCurrentState; state = rsp->dwEventState; rsp->dwCurrentState = rsp->dwEventState; +#ifdef _WIN32 + if (!strcmp(rsp->szReader, "\\\\?PnP?\\Notification")) { + /* Windows expects number of readers in HiWord of dwCurrentState. + * See https://stackoverflow.com/questions/16370909. */ + rsp->dwCurrentState |= ((num_watch - 1) << 16); + } +#endif if (state & SCARD_STATE_CHANGED) { /* check for hotplug events */ if (!strcmp(rsp->szReader, "\\\\?PnP?\\Notification")) { From b35f5afe8ebabbc983cc7b635d467736e5311b7b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 14 Jan 2024 02:46:55 +0100 Subject: [PATCH 3789/4321] add some debugging regarding language of user messages --- src/ui/strings.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ui/strings.c b/src/ui/strings.c index b06434b9ec..1eedb905c0 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -19,6 +19,7 @@ */ #include "libopensc/internal.h" +#include "libopensc/log.h" #include "ui/strings.h" #include #include @@ -163,14 +164,22 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, LANGID langid = GetUserDefaultUILanguage(); if ((langid & LANG_GERMAN) == LANG_GERMAN) { lang = DE; + sc_log(ctx, "Using the system's language for user messages (German)."); } #else + const char *language = getenv("LANGUAGE"); /* LANGUAGE supersedes locale */ - if (!find_lang_str(getenv("LANGUAGE"), &lang)) { + if (!find_lang_str(language, &lang)) { /* XXX Should we use LC_MESSAGES instead? */ - find_lang_str(setlocale(LC_ALL, ""), &lang); + language = setlocale(LC_ALL, ""); + if (find_lang_str(language, &lang)) + sc_log(ctx, "Using the system's native environment locale for user messages (%s).", language); + } else { + sc_log(ctx, "Using the system's LANGUAGE for user messages (%s).", language); } #endif + } else { + sc_log(ctx, "Using the token's preferred language for user messages (%s).", p15card->tokeninfo->preferred_language); } /* load default strings */ From 891dfc772b1ec51b6aa1ee3552f7c6fdf8369916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 23 Jan 2025 12:11:12 +0100 Subject: [PATCH 3790/4321] pkcs15-sc-hsm: Fix leak of sc_pkcs15_pubkey attributes Thanks Coverity CID 454838 --- src/libopensc/pkcs15-sc-hsm.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index acdbee7054..a0c6146fff 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1028,11 +1028,20 @@ static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, u8 *efbin, memset(&pubkey_obj, 0, sizeof(pubkey_obj)); r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len); - LOG_TEST_RET(ctx, r, "Could not encode public key"); + if (r != SC_SUCCESS) { + sc_pkcs15_erase_pubkey(&pubkey); + LOG_TEST_RET(ctx, r, "Could not encode public key"); + } r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_info.direct.raw.value, &pubkey_info.direct.raw.len); - LOG_TEST_RET(ctx, r, "Could not encode public key"); + if (r != SC_SUCCESS) { + sc_pkcs15_erase_pubkey(&pubkey); + LOG_TEST_RET(ctx, r, "Could not encode public key"); + } r = sc_pkcs15_encode_pubkey_as_spki(ctx, &pubkey, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len); - LOG_TEST_RET(ctx, r, "Could not encode public key"); + if (r != SC_SUCCESS) { + sc_pkcs15_erase_pubkey(&pubkey); + LOG_TEST_RET(ctx, r, "Could not encode public key"); + } pubkey_info.id = key_info->id; strlcpy(pubkey_obj.label, label, sizeof(pubkey_obj.label)); From 370b99e6813bf738892592b31d0f8915c6c65c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 23 Jan 2025 12:13:55 +0100 Subject: [PATCH 3791/4321] pkcs15-sc-hsm: Fix leak of sc_cvc_t object Thanks Coverity CID 454837, 454834, 454831, 454828, 454826 --- src/pkcs15init/pkcs15-sc-hsm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index db1a2b518f..c425bbeb05 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -282,7 +282,10 @@ static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card r = SC_ERROR_NOT_IMPLEMENTED; break; } - LOG_TEST_RET(p15card->card->ctx, r, "Could not encode GAKP cdata"); + if (r != SC_SUCCESS) { + sc_pkcs15emu_sc_hsm_free_cvc(&cvc); + LOG_TEST_RET(p15card->card->ctx, r, "Could not encode GAKP cdata"); + } r = sc_pkcs15emu_sc_hsm_encode_cvc(p15card, &cvc, &cvcbin, &cvclen); sc_pkcs15emu_sc_hsm_free_cvc(&cvc); From 0d8cd4a4dab6da48593fe75ca8e2a69629b0dcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 23 Jan 2025 13:54:05 +0100 Subject: [PATCH 3792/4321] muscle: Fix memory leak Thanks Coverity CID 454836 --- src/libopensc/muscle.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 89dfcbbcba..de85a611ff 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -467,7 +467,10 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short if(location == 1) { u8* outputBuffer = malloc(dataLength + 2); - if(outputBuffer == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + if(outputBuffer == NULL) { + free(buffer); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + }; apdu.le = dataLength + 2; apdu.resp = outputBuffer; apdu.resplen = dataLength + 2; From 177f77f5405f4fc0e09f8f12c3a7dd512b8c03b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 24 Jan 2025 14:12:18 +0100 Subject: [PATCH 3793/4321] pkcs15-coolkey: Fix memory leak of certificate value Thanks Coverity CID 454822, 454833 --- src/libopensc/pkcs15-coolkey.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 5435e59ca1..cf68f7a264 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -546,7 +546,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) for (i = 0; i < count; i++) { struct sc_cardctl_coolkey_object coolkey_obj; struct sc_pkcs15_object obj_obj; - struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_cert_info cert_info = {0}; struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_prkey_info prkey_info; sc_pkcs15_pubkey_t *key = NULL; @@ -678,8 +678,12 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) if (r != SC_SUCCESS) sc_log(card->ctx, "sc_pkcs15emu_object_add() returned %d", r); fail: - if (key) { sc_pkcs15_free_pubkey(key); } - + if (key) { + sc_pkcs15_free_pubkey(key); + } + if (r < 0) { + free(cert_info.value.value); + } } r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize objects."); From d337f7e039c086277942ed13acc390faa1810b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 28 Jan 2025 10:41:52 +0100 Subject: [PATCH 3794/4321] compression: Fix memory leak of z_stream Thanks Coverity CID 454832 --- src/libopensc/compression.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index 26aba399ff..0e98689b0c 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -210,6 +210,7 @@ static int sc_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size if (!buf) { free(*out); *out = NULL; + inflateEnd(&gz); return SC_ERROR_OUT_OF_MEMORY; } *out = buf; From ddbaa22dd390773a246dc852affe2354bdf93aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 28 Jan 2025 11:01:19 +0100 Subject: [PATCH 3795/4321] libpkcs11: Call sc_dlsym on handle in case of error Thanks Coverity CID 454829 --- src/common/libpkcs11.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index e21c7b4639..5ad0dd3e56 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -99,6 +99,8 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) mod = NULL; /* already freed */ } failed: + if (mod && mod->handle) + sc_dlclose(mod->handle); free(mod); return NULL; } From 133cad9002725aed6d3067ce9259f1b0bdf5227f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 28 Jan 2025 13:54:16 +0100 Subject: [PATCH 3796/4321] card-authentic: Fix memory leak in apdu Thanks Coverity CID 454827 --- src/libopensc/card-authentic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index bb8642c3a5..fc53d31bc7 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -2295,6 +2295,7 @@ authentic_sm_get_wrapped_apdu(struct sc_card *card, struct sc_apdu *plain, struc apdu->resp = calloc (1, plain->resplen + 32); if (!apdu->resp) { + free((unsigned char *) apdu->data); free(apdu); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } @@ -2305,6 +2306,7 @@ authentic_sm_get_wrapped_apdu(struct sc_card *card, struct sc_apdu *plain, struc rv = card->sm_ctx.module.ops.get_apdus(ctx, &card->sm_ctx.info, NULL, 0, NULL); if (rv < 0) { free(apdu->resp); + free((unsigned char *) apdu->data); free(apdu); } LOG_TEST_RET(ctx, rv, "SM: GET_APDUS failed"); From 7cf121717c1499adada4aa0e3507d4ac5470767a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 28 Jan 2025 15:08:58 +0100 Subject: [PATCH 3797/4321] egk-tool: Free stream variable in case of error Thanks Coverity CID 454823 --- src/tools/egk-tool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index aa1903fecd..099d29e8ce 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -66,12 +66,14 @@ int uncompress_gzip(void* uncompressed, size_t *uncompressed_len, stream.next_out = (Bytef *) uncompressed; /* 15 window bits, and the +32 tells zlib to to detect if using gzip or zlib */ - if (Z_OK == inflateInit2(&stream, (15 + 32)) - && Z_STREAM_END == inflate(&stream, Z_FINISH)) { - *uncompressed_len = stream.total_out; - } else { + if (inflateInit2(&stream, (15 + 32)) != Z_OK) { return SC_ERROR_INVALID_DATA; } + if (inflate(&stream, Z_FINISH) != Z_STREAM_END) { + inflateEnd(&stream); + return SC_ERROR_INVALID_DATA; + } + *uncompressed_len = stream.total_out; inflateEnd(&stream); return SC_SUCCESS; From 10a500cc62e97766038aaef5424ed003d1bf5bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 28 Jan 2025 16:00:23 +0100 Subject: [PATCH 3798/4321] pkcs15-lib: Unload dynamic library when freeing profile Thanks Coverity CID 454835 --- src/pkcs15init/pkcs15-lib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 4b5f2813bc..4d4c6eb3b4 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -358,6 +358,8 @@ sc_pkcs15init_bind(struct sc_card *card, const char *name, const char *profile_o r = sc_pkcs15init_read_info(card, profile); if (r < 0) { + if (profile->dll) + sc_dlclose(profile->dll); sc_profile_free(profile); LOG_TEST_RET(ctx, r, "Read info error"); } @@ -389,6 +391,8 @@ sc_pkcs15init_bind(struct sc_card *card, const char *name, const char *profile_o } while (0); if (r < 0) { + if (profile->dll) + sc_dlclose(profile->dll); sc_profile_free(profile); LOG_TEST_RET(ctx, r, "Load profile error"); } From bffc8b6fc5caf59caa6d464197af8073e40f4e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 30 Jan 2025 10:34:51 +0100 Subject: [PATCH 3799/4321] Fix spelling error with indx variable --- src/libopensc/card-epass2003.c | 10 +-- src/libopensc/iasecc-sdo.c | 122 ++++++++++++++++----------------- src/pkcs15init/pkcs15-iasecc.c | 8 +-- src/pkcs15init/pkcs15-lib.c | 20 +++--- 4 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 5a0fbfc95b..e448f1f75f 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -184,7 +184,7 @@ static const struct sc_card_error epass2003_errors[] = { typedef struct sec_attr_to_acl_entries { unsigned int file_type; /* file->type */ unsigned int file_ef_structure; /* file->ef_structure */ - int indx; /* index in epass2003 iversion of sec_attr */ + int index; /* index in epass2003 iversion of sec_attr */ /* use the follow for sc_file_add_entry */ int op; /* SC_AC_OP_* */ } sec_attr_to_acl_entries_t; @@ -2330,7 +2330,7 @@ acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e) /* Use epass2003 sec_attr to add acl entries */ int -sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) +sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int index) { int i; int found = 0; @@ -2340,7 +2340,7 @@ sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - switch (file->sec_attr[indx]) { + switch (file->sec_attr[index]) { case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE): method = SC_AC_NONE; keyref = SC_AC_KEY_REF_NONE; @@ -2350,7 +2350,7 @@ sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) keyref = 1; break; default: - sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[indx], indx); + sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[index], index); method = SC_AC_NEVER; keyref = SC_AC_KEY_REF_NONE; break; @@ -2359,7 +2359,7 @@ sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int indx) for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) { const sec_attr_to_acl_entries_t *e = &sec_attr_to_acl_entry[i]; - if (indx == e->indx && file->type == e->file_type + if (index == e->index && file->type == e->file_type && file->ef_structure == e->file_ef_structure) { /* may add multiple entries */ sc_file_add_acl_entry(file, e->op, method, keyref); diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index dbd5b9f08c..7c77a0c831 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -1137,7 +1137,7 @@ iasecc_sdo_encode_rsa_update(struct sc_context *ctx, struct iasecc_sdo *sdo, str sc_log(ctx, "iasecc_sdo_encode_rsa_update() SDO class %X", sdo->sdo_class); memset(sdo_update, 0, sizeof(*sdo_update)); if (sdo->sdo_class == IASECC_SDO_CLASS_RSA_PRIVATE) { - int indx = 0; + int index = 0; sc_log(ctx, "iasecc_sdo_encode_rsa_update(IASECC_SDO_CLASS_RSA_PRIVATE)"); if (!rsa->p.len || !rsa->q.len || !rsa->iqmp.len || !rsa->dmp1.len || !rsa->dmq1.len) @@ -1148,35 +1148,35 @@ iasecc_sdo_encode_rsa_update(struct sc_context *ctx, struct iasecc_sdo *sdo, str sdo_update->sdo_class = IASECC_SDO_CLASS_RSA_PRIVATE; - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_P; - sdo_update->fields[indx].value = rsa->p.data; - sdo_update->fields[indx].size = rsa->p.len; - indx++; - - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_Q; - sdo_update->fields[indx].value = rsa->q.data; - sdo_update->fields[indx].size = rsa->q.len; - indx++; - - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_IQMP; - sdo_update->fields[indx].value = rsa->iqmp.data; - sdo_update->fields[indx].size = rsa->iqmp.len; - indx++; - - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_DMP1; - sdo_update->fields[indx].value = rsa->dmp1.data; - sdo_update->fields[indx].size = rsa->dmp1.len; - indx++; - - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_DMQ1; - sdo_update->fields[indx].value = rsa->dmq1.data; - sdo_update->fields[indx].size = rsa->dmq1.len; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_P; + sdo_update->fields[index].value = rsa->p.data; + sdo_update->fields[index].size = rsa->p.len; + index++; + + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_Q; + sdo_update->fields[index].value = rsa->q.data; + sdo_update->fields[index].size = rsa->q.len; + index++; + + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_IQMP; + sdo_update->fields[index].value = rsa->iqmp.data; + sdo_update->fields[index].size = rsa->iqmp.len; + index++; + + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_DMP1; + sdo_update->fields[index].value = rsa->dmp1.data; + sdo_update->fields[index].size = rsa->dmp1.len; + index++; + + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_DMQ1; + sdo_update->fields[index].value = rsa->dmq1.data; + sdo_update->fields[index].size = rsa->dmq1.len; + index++; sc_log(ctx, "prv_key.compulsory.on_card %i", sdo->data.prv_key.compulsory.on_card); if (!sdo->data.prv_key.compulsory.on_card) { @@ -1184,16 +1184,16 @@ iasecc_sdo_encode_rsa_update(struct sc_context *ctx, struct iasecc_sdo *sdo, str sc_log(ctx, "sdo_prvkey->data.prv_key.compulsory.size %"SC_FORMAT_LEN_SIZE_T"u", sdo->data.prv_key.compulsory.size); - sdo_update->fields[indx].parent_tag = IASECC_SDO_PRVKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PRVKEY_TAG_COMPULSORY; - sdo_update->fields[indx].value = sdo->data.prv_key.compulsory.value; - sdo_update->fields[indx].size = sdo->data.prv_key.compulsory.size; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PRVKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PRVKEY_TAG_COMPULSORY; + sdo_update->fields[index].value = sdo->data.prv_key.compulsory.value; + sdo_update->fields[index].size = sdo->data.prv_key.compulsory.size; + index++; } } } else if (sdo->sdo_class == IASECC_SDO_CLASS_RSA_PUBLIC) { - int indx = 0; + int index = 0; sc_log(ctx, "iasecc_sdo_encode_rsa_update(IASECC_SDO_CLASS_RSA_PUBLIC)"); sdo_update->magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA; @@ -1201,45 +1201,45 @@ iasecc_sdo_encode_rsa_update(struct sc_context *ctx, struct iasecc_sdo *sdo, str sdo_update->sdo_class = sdo->sdo_class; if (rsa->exponent.len) { - sdo_update->fields[indx].parent_tag = IASECC_SDO_PUBKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PUBKEY_TAG_E; - sdo_update->fields[indx].value = rsa->exponent.data; - sdo_update->fields[indx].size = rsa->exponent.len; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PUBKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PUBKEY_TAG_E; + sdo_update->fields[index].value = rsa->exponent.data; + sdo_update->fields[index].size = rsa->exponent.len; + index++; } if (rsa->modulus.len) { - sdo_update->fields[indx].parent_tag = IASECC_SDO_PUBKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PUBKEY_TAG_N; - sdo_update->fields[indx].value = rsa->modulus.data; - sdo_update->fields[indx].size = rsa->modulus.len; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PUBKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PUBKEY_TAG_N; + sdo_update->fields[index].value = rsa->modulus.data; + sdo_update->fields[index].size = rsa->modulus.len; + index++; } if (sdo->data.pub_key.cha.value) { - sdo_update->fields[indx].parent_tag = IASECC_SDO_PUBKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PUBKEY_TAG_CHA; - sdo_update->fields[indx].value = sdo->data.pub_key.cha.value; - sdo_update->fields[indx].size = sdo->data.pub_key.cha.size; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PUBKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PUBKEY_TAG_CHA; + sdo_update->fields[index].value = sdo->data.pub_key.cha.value; + sdo_update->fields[index].size = sdo->data.pub_key.cha.size; + index++; } if (sdo->data.pub_key.chr.value) { - sdo_update->fields[indx].parent_tag = IASECC_SDO_PUBKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PUBKEY_TAG_CHR; - sdo_update->fields[indx].value = sdo->data.pub_key.chr.value; - sdo_update->fields[indx].size = sdo->data.pub_key.chr.size; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PUBKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PUBKEY_TAG_CHR; + sdo_update->fields[index].value = sdo->data.pub_key.chr.value; + sdo_update->fields[index].size = sdo->data.pub_key.chr.size; + index++; } /* For ECC card 'compulsory' flag should be already here */ if (!sdo->data.pub_key.compulsory.on_card) { if (sdo->data.pub_key.compulsory.value) { - sdo_update->fields[indx].parent_tag = IASECC_SDO_PUBKEY_TAG; - sdo_update->fields[indx].tag = IASECC_SDO_PUBKEY_TAG_COMPULSORY; - sdo_update->fields[indx].value = sdo->data.pub_key.compulsory.value; - sdo_update->fields[indx].size = sdo->data.pub_key.compulsory.size; - indx++; + sdo_update->fields[index].parent_tag = IASECC_SDO_PUBKEY_TAG; + sdo_update->fields[index].tag = IASECC_SDO_PUBKEY_TAG_COMPULSORY; + sdo_update->fields[index].value = sdo->data.pub_key.compulsory.value; + sdo_update->fields[index].size = sdo->data.pub_key.compulsory.size; + index++; } } } diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 008dd26d55..dcb525e27a 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1734,15 +1734,15 @@ iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof struct sc_card *card = p15card->card; struct sc_pkcs15_object *p15objects[MAX_DATA_OBJS]; struct sc_file *cfile = NULL, *file = NULL, *parent = NULL; - int rv, nn_objs, indx, ii; + int rv, nn_objs, index, ii; LOG_FUNC_CALLED(ctx); sc_log(ctx, "iasecc_store_data_object() authID '%s'", sc_pkcs15_print_id(&object->auth_id)); nn_objs = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, p15objects, MAX_DATA_OBJS); LOG_TEST_RET(ctx, nn_objs, "IasEcc get pkcs15 DATA objects error"); - for(indx = 1; indx < MAX_DATA_OBJS; indx++) { - rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_DATA_OBJECT, indx, &file); + for(index = 1; index < MAX_DATA_OBJS; index++) { + rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_DATA_OBJECT, index, &file); LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() pkcs15 new DATA file error"); for (ii=0; iicard->ctx; struct sc_file *file; struct sc_pkcs15_object *objs[32]; - struct sc_pkcs15_id indx_id; + struct sc_pkcs15_id index_id; struct sc_path obj_path; - int ii, r, nn_objs, indx; + int ii, r, nn_objs, index; const char *name; LOG_FUNC_CALLED(ctx); @@ -3118,18 +3118,18 @@ select_object_path(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_log(ctx, "key-domain.%s @%s (auth_id.len=%"SC_FORMAT_LEN_SIZE_T"u)", name, sc_print_path(path), obj->auth_id.len); - indx_id.len = 1; - for (indx = TEMPLATE_INSTANTIATE_MIN_INDEX; indx <= TEMPLATE_INSTANTIATE_MAX_INDEX; indx++) { - indx_id.value[0] = indx; - r = sc_profile_instantiate_template(profile, "key-domain", path, name, &indx_id, &file); + index_id.len = 1; + for (index = TEMPLATE_INSTANTIATE_MIN_INDEX; index <= TEMPLATE_INSTANTIATE_MAX_INDEX; index++) { + index_id.value[0] = index; + r = sc_profile_instantiate_template(profile, "key-domain", path, name, &index_id, &file); if (r == SC_ERROR_TEMPLATE_NOT_FOUND) { /* No template in 'key-domain' -- try to instantiate the template-'object name' * outside of the 'key-domain' scope. */ char t_name[0x40]; snprintf(t_name, sizeof(t_name), "template-%s", name); - sc_log(ctx, "get instance %i of '%s'", indx, t_name); - r = sc_profile_get_file_instance(profile, t_name, indx, &file); + sc_log(ctx, "get instance %i of '%s'", index, t_name); + r = sc_profile_get_file_instance(profile, t_name, index, &file); if (r == SC_ERROR_FILE_NOT_FOUND) LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -3158,10 +3158,10 @@ select_object_path(struct sc_pkcs15_card *p15card, struct sc_profile *profile, sc_file_free(file); - indx_id.value[0] += 1; + index_id.value[0] += 1; } - if (indx > TEMPLATE_INSTANTIATE_MAX_INDEX) + if (index > TEMPLATE_INSTANTIATE_MAX_INDEX) LOG_TEST_RET(ctx, SC_ERROR_TOO_MANY_OBJECTS, "Template instantiation error"); *path = file->path; From c1059df64eba72ae54b7d0a0fb13f4f92f242f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 4 Feb 2025 13:18:54 +0100 Subject: [PATCH 3800/4321] pkcs11-tool: Fix parsing of decompressed point length Thanks Coverity CID 454830 --- src/tools/pkcs11-tool.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ae8b06839e..a70cfbb154 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2633,25 +2633,27 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { - CK_BYTE* bytes; + CK_BYTE *bytes, *tmp; CK_ULONG len; - size_t rs_len = 0; + size_t rs_len = 0, taglen; + unsigned int cla, tag; unsigned char rs_buffer[512]; bytes = getEC_POINT(session, key, &len); - free(bytes); /* * (We only support uncompressed for now) * Uncompressed EC_POINT is DER OCTET STRING of "04||x||y" * So a "256" bit key has x and y of 32 bytes each * something like: "04 41 04||x||y" - * Do simple size calculation based on DER encoding + * Extract length from ASN.1 */ - if ((len - 2) <= 127) - rs_len = len - 3; - else if ((len - 3) <= 255) - rs_len = len - 4; - else + tmp = bytes; + if (sc_asn1_read_tag((const u8 **)&tmp, len, &cla, &tag, &taglen) != SC_SUCCESS || + len < 2 || len > 255) { + free(bytes); util_fatal("Key not supported"); + } + free(bytes); + rs_len = taglen - 1; // len is length of "04||x||y" if (sc_asn1_sig_value_sequence_to_rs(NULL, sig_buffer, sz2, rs_buffer, rs_len)) { From f2a9f3a7275fac806d529d2dad43db937e11c7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 4 Feb 2025 13:39:59 +0100 Subject: [PATCH 3801/4321] codespell: ignore german word for algorithm --- .github/codespell_ignore_words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/codespell_ignore_words.txt b/.github/codespell_ignore_words.txt index 35bebfe400..96efc88620 100644 --- a/.github/codespell_ignore_words.txt +++ b/.github/codespell_ignore_words.txt @@ -20,3 +20,4 @@ responde sie signatur standarts +algorithmus From c6e8171040d8bc299b1ebce4a9084d3872206443 Mon Sep 17 00:00:00 2001 From: cdanger <1372580+cdanger@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:02:58 +0100 Subject: [PATCH 3802/4321] Fixed #3293 and added corresponding test of RSA-PKCS-OAEP wrap/unwrap operations in file tests/test-pkcs11-tool-unwrap-wrap-test.sh (Parameterized the RSA-PKCSA-OAEP tests with variables so that the OAEP hash / MGF algorithms can be replaced easily in all openssl and pkcs11-tool commands used in the test.) --- src/tools/pkcs11-tool.c | 8 +++ tests/test-pkcs11-tool-unwrap-wrap-test.sh | 61 +++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ae8b06839e..108a8ac511 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3653,6 +3653,7 @@ unwrap_key(CK_SESSION_HANDLE session) size_t iv_size = 0; CK_BYTE_PTR aad = NULL; size_t aad_size = 0; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_OBJECT_HANDLE hUnwrappingKey; ssize_t sz; @@ -3701,6 +3702,9 @@ unwrap_key(CK_SESSION_HANDLE session) mechanism.pParameter = &gcm_params; mechanism.ulParameterLen = sizeof(gcm_params); break; + case CKM_RSA_PKCS_OAEP: + build_rsa_oaep_params(&oaep_params, &mechanism, NULL, 0); + break; default: // Nothing to do with other mechanisms. break; @@ -3828,6 +3832,7 @@ wrap_key(CK_SESSION_HANDLE session) size_t iv_size = 0; CK_BYTE_PTR aad = NULL; size_t aad_size = 0; + CK_RSA_PKCS_OAEP_PARAMS oaep_params; if (NULL == opt_application_id) util_fatal("Use --application-id to specify secret key (to be wrapped)"); @@ -3857,6 +3862,9 @@ wrap_key(CK_SESSION_HANDLE session) mechanism.pParameter = &gcm_params; mechanism.ulParameterLen = sizeof(gcm_params); break; + case CKM_RSA_PKCS_OAEP: + build_rsa_oaep_params(&oaep_params, &mechanism, NULL, 0); + break; default: // Nothing to do with other mechanisms. break; diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 1cb4ea175a..8d5f2cb712 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -77,7 +77,66 @@ cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null assert $? "wrapped key after decipher does not match the original key" echo "=======================================================" -echo " RSA-PKCS Cleanup" +echo " RSA-PKCS-OAEP Unwrap test" +echo "=======================================================" +# RSA-PKCS-OAEP mechanism takes both a hash algorithm and MGF algorithm as parameters. For now we use SHA1, although it has been deprecated by NIST, because SoftHSM only supports SHA1 hash with OAEP currently. Known issue: https://github.com/softhsm/SoftHSMv2/issues/474 . When this issue is fixed, we shall replace with SHA256 or higher. +# OpenSSL rsa_oaep_md hash algorithm option +OSSL_OAEP_HASH_ALG="sha1" +# pkcs11-tool hash-algorithm option +P11_OAEP_HASH_ALG="SHA-1" +# pkcs11-tool mgf option +P11_OAEP_MGF_ALG="MGF1-SHA1" + +# Identifiers (pkcs11-tool --application-id argument) of PKCS11 key objects to be created +ID4="97" +ID5="98" + +# Reusing AES key and RSA key for unwrap/wrap operation already generated with ID1 in previous RSA-PKCS Unwrap test +# Cleanup previously generated output +rm aes_wrapped_key generic_extracted_key aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data wrapped.key plain_wrapped.key + +# wrap AES key with RSA OAEP mode +openssl pkeyutl -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:$OSSL_OAEP_HASH_ALG -pkeyopt rsa_mgf1_md:$OSSL_OAEP_HASH_ALG -pubin -keyform DER -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key +assert $? "Failed wrap AES key" + +# unwrap key by pkcs11 interface, extractable +$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ + --extractable --application-id $ID4 --application-label "unwrap-aes-ex-with-rsa-oaep" 2>/dev/null +assert $? "Unwrap failed" +# because key is extractable, there is no problem to compare key value with original key +$PKCS11_TOOL_W_PIN --id $ID4 --read-object --type secrkey --output-file generic_extracted_key +assert $? "unable to read key value" +cmp generic_extracted_key aes_plain_key >/dev/null 2>/dev/null +assert $? "extracted key does not match the input key" + +# unwrap AES key, not extractable +$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type AES: \ + --application-id $ID5 --application-label "unwrap-aes-non-ex-with-rsa-oaep" 2>/dev/null +assert $? "Unwrap failed" + +# To check if AES key was correctly unwrapped (non extractable), we do the same as in the RSA-PKCS test. +openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY +assert $? "Fail/Openssl" + +$PKCS11_TOOL_W_PIN --encrypt --id $ID5 -m AES-CBC --iv $VECTOR \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CBC - wrong encrypt" + +echo "=======================================================" +echo " RSA-PKCS-OAEP Wrap test" +echo "=======================================================" + +$PKCS11_TOOL_W_PIN --wrap -m RSA-PKCS-OAEP --id $ID1 --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID4 --output-file wrapped.key +assert $? "Fail, unable to wrap" +$PKCS11_TOOL_W_PIN --decrypt -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key +assert $? "Fail, unable to decrypt wrapped key" +cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null +assert $? "wrapped key after decipher does not match the original key" + +echo "=======================================================" +echo " RSA-PKCS / RSA-PKCS-OAEP Cleanup" echo "=======================================================" rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wrapped.key plain_wrapped.key From 3c5083832e6a61039fb1024ee8ee5c49e9a1473a Mon Sep 17 00:00:00 2001 From: cdanger <1372580+cdanger@users.noreply.github.com> Date: Tue, 4 Feb 2025 23:21:03 +0100 Subject: [PATCH 3803/4321] Fixed openssl pkeyutl command in tests/test-pkcs11-tool-unwrap-wrap-test.sh to work with libressl --- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 8d5f2cb712..cb4329a8c0 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -96,7 +96,7 @@ ID5="98" rm aes_wrapped_key generic_extracted_key aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data wrapped.key plain_wrapped.key # wrap AES key with RSA OAEP mode -openssl pkeyutl -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:$OSSL_OAEP_HASH_ALG -pkeyopt rsa_mgf1_md:$OSSL_OAEP_HASH_ALG -pubin -keyform DER -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key +openssl pkeyutl -encrypt -pubin -keyform DER -inkey rsa_pub.key -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:$OSSL_OAEP_HASH_ALG -pkeyopt rsa_mgf1_md:$OSSL_OAEP_HASH_ALG -in aes_plain_key -out aes_wrapped_key assert $? "Failed wrap AES key" # unwrap key by pkcs11 interface, extractable From 8523ee5db88ed056bb3bd098485d5fb6b44a7f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 7 Feb 2025 14:51:47 +0100 Subject: [PATCH 3804/4321] card-openpgp: Pass struct by reference not value Thanks Coverity CID 456622, 456621 --- src/libopensc/card-openpgp.c | 44 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 69b458388f..3abc5b41f0 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -709,29 +709,34 @@ pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob, int _pgp_handle_curve25519(sc_card_t *card, - sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) + sc_cardctl_openpgp_key_gen_store_info_t *key_info, unsigned int do_num) { - if (!sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid) && - !sc_compare_oid(&key_info.u.ec.oid, &X25519_oid)) + if (!card || !key_info) + return 0; + if (!sc_compare_oid(&key_info->u.ec.oid, &curve25519_oid) && + !sc_compare_oid(&key_info->u.ec.oid, &X25519_oid)) return 0; /* CKM_XEDDSA supports both Sign and Derive, but * OpenPGP card supports only derivation using these * keys as far as I know */ - _sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); + _sc_card_add_xeddsa_alg(card, key_info->u.ec.key_length, + SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info->u.ec.oid); sc_log(card->ctx, "DO %uX: Added XEDDSA algorithm (%d), mod_len = %zu", - do_num, SC_ALGORITHM_XEDDSA, key_info.u.ec.key_length); + do_num, SC_ALGORITHM_XEDDSA, key_info->u.ec.key_length); return 1; } int -_pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, unsigned int do_num) +_pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info, unsigned int do_num) { unsigned long flags = 0, ext_flags = 0; + if (!card || !key_info) + return 0; + /* [RFC 4880], [draft-ietf-openpgp-crypto-refresh] */ - switch (key_info.algorithm) { + switch (key_info->algorithm) { case SC_OPENPGP_KEYALGO_RSA: /* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 / * v3.x section 7.2.11 & 7.2.12 */ @@ -739,10 +744,10 @@ _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */ - _sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0); + _sc_card_add_rsa_alg(card, key_info->u.rsa.modulus_len, flags, 0); sc_log(card->ctx, "DO %uX: Added RSA algorithm, mod_len = %" SC_FORMAT_LEN_SIZE_T"u", - do_num, key_info.u.rsa.modulus_len); + do_num, key_info->u.rsa.modulus_len); break; case SC_OPENPGP_KEYALGO_ECDH: /* The montgomery curve (curve25519) needs to go through @@ -761,25 +766,25 @@ _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t key_info, flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - _sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags, - &key_info.u.ec.oid); + _sc_card_add_ec_alg(card, key_info->u.ec.key_length, flags, ext_flags, + &key_info->u.ec.oid); sc_log(card->ctx, "DO %uX: Added EC algorithm (%d), mod_len = %zu" , - do_num, key_info.algorithm, key_info.u.ec.key_length); + do_num, key_info->algorithm, key_info->u.ec.key_length); break; case SC_OPENPGP_KEYALGO_EDDSA: /* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */ /* Handle Yubikey bug, that in DO FA curve25519 has EDDSA algo */ if (_pgp_handle_curve25519(card, key_info, do_num)) break; - _sc_card_add_eddsa_alg(card, key_info.u.ec.key_length, - SC_ALGORITHM_EDDSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info.u.ec.oid); + _sc_card_add_eddsa_alg(card, key_info->u.ec.key_length, + SC_ALGORITHM_EDDSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN, 0, &key_info->u.ec.oid); sc_log(card->ctx, "DO %uX: Added EDDSA algorithm (%d), mod_len = %zu" , - do_num, key_info.algorithm, key_info.u.ec.key_length); + do_num, key_info->algorithm, key_info->u.ec.key_length); break; default: sc_log(card->ctx, "DO %uX: Unknown algorithm ID (%d)" , - do_num, key_info.algorithm); + do_num, key_info->algorithm); /* return "false" if we do not understand algo */ return 0; } @@ -864,7 +869,7 @@ pgp_get_card_features(sc_card_t *card) continue; sc_cardctl_openpgp_key_gen_store_info_t key_info; if (pgp_parse_algo_attr_blob(card, child, &key_info) >= 0) - handled_algos += _pgp_add_algo(card, key_info, 0x00fa); + handled_algos += _pgp_add_algo(card, &key_info, 0x00fa); } } } @@ -971,7 +976,8 @@ pgp_get_card_features(sc_card_t *card) /* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */ if ((pgp_get_blob(card, blob73, i, &blob) >= 0) && (pgp_parse_algo_attr_blob(card, blob, &key_info) >= 0)) { - _pgp_add_algo(card, key_info, i); + if (!_pgp_add_algo(card, &key_info, i)) + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Cannot add algorithm"); } } From 3d4ffa1f8214870f7810430cce9e0b8b43c61570 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Feb 2025 14:40:52 +0100 Subject: [PATCH 3805/4321] feat(pkcs11-tool): use an union for the RSA OAEP and AES GCM parameters --- src/tools/pkcs11-tool.c | 92 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 06b1b009dd..6917bccdcf 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2804,8 +2804,11 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1024], out_buffer[1024]; CK_MECHANISM mech; CK_RV rv; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; - CK_GCM_PARAMS gcm_params = {0}; + union + { + CK_RSA_PKCS_OAEP_PARAMS oaep; + CK_GCM_PARAMS gcm; + } params = {0}; CK_ULONG in_len, out_len; int fd_in, fd_out; CK_BYTE_PTR iv = NULL; @@ -2830,7 +2833,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(&oaep_params, &mech, NULL, 0); + build_rsa_oaep_params(¶ms.oaep, &mech, NULL, 0); break; case CKM_RSA_X_509: case CKM_RSA_PKCS: @@ -2847,14 +2850,14 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; case CKM_AES_GCM: iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - gcm_params.pIv = iv; - gcm_params.ulIvLen = iv_size; + params.gcm.pIv = iv; + params.gcm.ulIvLen = iv_size; aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - gcm_params.pAAD = aad; - gcm_params.ulAADLen = aad_size; - gcm_params.ulTagBits = opt_tag_bits; - mech.pParameter = &gcm_params; - mech.ulParameterLen = sizeof(gcm_params); + params.gcm.pAAD = aad; + params.gcm.ulAADLen = aad_size; + params.gcm.ulTagBits = opt_tag_bits; + mech.pParameter = ¶ms.gcm; + mech.ulParameterLen = sizeof(params.gcm); break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); @@ -2931,11 +2934,14 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, unsigned char in_buffer[1024], out_buffer[1024]; CK_MECHANISM mech; CK_RV rv; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; + union + { + CK_RSA_PKCS_OAEP_PARAMS oaep; + CK_GCM_PARAMS gcm; + } params = {0}; CK_ULONG in_len, out_len; int fd_in, fd_out; ssize_t sz; - CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; CK_BYTE_PTR aad = NULL; @@ -2955,7 +2961,7 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, switch (opt_mechanism) { case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(&oaep_params, &mech, NULL, 0); + build_rsa_oaep_params(¶ms.oaep, &mech, NULL, 0); break; case CKM_AES_ECB: mech.pParameter = NULL; @@ -2970,14 +2976,14 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; case CKM_AES_GCM: iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - gcm_params.pIv = iv; - gcm_params.ulIvLen = iv_size; + params.gcm.pIv = iv; + params.gcm.ulIvLen = iv_size; aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - gcm_params.pAAD = aad; - gcm_params.ulAADLen = aad_size; - gcm_params.ulTagBits = opt_tag_bits; - mech.pParameter = &gcm_params; - mech.ulParameterLen = sizeof(gcm_params); + params.gcm.pAAD = aad; + params.gcm.ulAADLen = aad_size; + params.gcm.ulTagBits = opt_tag_bits; + mech.pParameter = ¶ms.gcm; + mech.ulParameterLen = sizeof(params.gcm); break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); @@ -3650,12 +3656,15 @@ unwrap_key(CK_SESSION_HANDLE session) unsigned char in_buffer[2048]; CK_ULONG wrapped_key_length; CK_BYTE_PTR pWrappedKey; - CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; CK_BYTE_PTR aad = NULL; size_t aad_size = 0; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; + union + { + CK_RSA_PKCS_OAEP_PARAMS oaep; + CK_GCM_PARAMS gcm; + } params = {0}; CK_OBJECT_HANDLE hUnwrappingKey; ssize_t sz; @@ -3695,17 +3704,17 @@ unwrap_key(CK_SESSION_HANDLE session) break; case CKM_AES_GCM: iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - gcm_params.pIv = iv; - gcm_params.ulIvLen = iv_size; + params.gcm.pIv = iv; + params.gcm.ulIvLen = iv_size; aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - gcm_params.pAAD = aad; - gcm_params.ulAADLen = aad_size; - gcm_params.ulTagBits = opt_tag_bits; - mechanism.pParameter = &gcm_params; - mechanism.ulParameterLen = sizeof(gcm_params); + params.gcm.pAAD = aad; + params.gcm.ulAADLen = aad_size; + params.gcm.ulTagBits = opt_tag_bits; + mechanism.pParameter = ¶ms.gcm; + mechanism.ulParameterLen = sizeof(params.gcm); break; case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(&oaep_params, &mechanism, NULL, 0); + build_rsa_oaep_params(¶ms.oaep, &mechanism, NULL, 0); break; default: // Nothing to do with other mechanisms. @@ -3829,12 +3838,15 @@ wrap_key(CK_SESSION_HANDLE session) size_t hkey_id_len; int fd; ssize_t sz; - CK_GCM_PARAMS gcm_params = {0}; CK_BYTE_PTR iv = NULL; size_t iv_size = 0; CK_BYTE_PTR aad = NULL; size_t aad_size = 0; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; + union + { + CK_RSA_PKCS_OAEP_PARAMS oaep; + CK_GCM_PARAMS gcm; + } params = {0}; if (NULL == opt_application_id) util_fatal("Use --application-id to specify secret key (to be wrapped)"); @@ -3855,17 +3867,17 @@ wrap_key(CK_SESSION_HANDLE session) break; case CKM_AES_GCM: iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - gcm_params.pIv = iv; - gcm_params.ulIvLen = iv_size; + params.gcm.pIv = iv; + params.gcm.ulIvLen = iv_size; aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - gcm_params.pAAD = aad; - gcm_params.ulAADLen = aad_size; - gcm_params.ulTagBits = opt_tag_bits; - mechanism.pParameter = &gcm_params; - mechanism.ulParameterLen = sizeof(gcm_params); + params.gcm.pAAD = aad; + params.gcm.ulAADLen = aad_size; + params.gcm.ulTagBits = opt_tag_bits; + mechanism.pParameter = ¶ms.gcm; + mechanism.ulParameterLen = sizeof(params.gcm); break; case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(&oaep_params, &mechanism, NULL, 0); + build_rsa_oaep_params(¶ms.oaep, &mechanism, NULL, 0); break; default: // Nothing to do with other mechanisms. From 192f830a60cb18545951985dfb13e7f7f72ad769 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Feb 2025 15:14:51 +0100 Subject: [PATCH 3806/4321] feat(pkcs11-tool): add support for ChaCha20 and Poly1305 --- src/pkcs11/pkcs11.h | 21 +++++++ src/tools/pkcs11-tool.c | 119 +++++++++++++++++++++++++++++++++++----- 2 files changed, 126 insertions(+), 14 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 09c0ca39fc..236712bd01 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -370,6 +370,8 @@ typedef unsigned long ck_key_type_t; #define CKK_GOSTR3410 (0x30UL) #define CKK_GOSTR3411 (0x31UL) #define CKK_GOST28147 (0x32UL) +#define CKK_CHACHA20 (0x33UL) +#define CKK_POLY1305 (0x34UL) #define CKK_EC_EDWARDS (0x40UL) #define CKK_EC_MONTGOMERY (0x41UL) #define CKK_HKDF (0x42UL) @@ -802,6 +804,10 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_GOST28147 (0x1222UL) #define CKM_GOST28147_MAC (0x1223UL) #define CKM_GOST28147_KEY_WRAP (0x1224UL) +#define CKM_CHACHA20_KEY_GEN (0x1225UL) +#define CKM_CHACHA20 (0x1226UL) +#define CKM_POLY1305_KEY_GEN (0x1227UL) +#define CKM_POLY1305 (0x1228UL) #define CKM_DSA_PARAMETER_GEN (0x2000UL) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) @@ -813,6 +819,7 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_CFB1 (0x2108UL) #define CKM_AES_KEY_WRAP (0x2109UL) #define CKM_AES_KEY_WRAP_PAD (0x210AUL) +#define CKM_CHACHA20_POLY1305 (0x4021UL) #define CKM_XEDDSA (0x4029UL) #define CKM_HKDF_DERIVE (0x402AUL) #define CKM_HKDF_DATA (0x402BUL) @@ -962,6 +969,20 @@ typedef struct CK_XEDDSA_PARAMS { typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR; +typedef struct CK_CHACHA20_PARAMS { + unsigned char *pBlockCounter; + unsigned long blockCounterBits; + unsigned char *pNonce; + unsigned long ulNonceBits; +} CK_CHACHA20_PARAMS; + +typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { + unsigned char *pNonce; + unsigned long ulNonceLen; + unsigned char *pAAD; + unsigned long ulAADLen; +} CK_SALSA20_CHACHA20_POLY1305_PARAMS; + typedef struct CK_AES_CTR_PARAMS { unsigned long ulCounterBits; unsigned char cb[16]; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6917bccdcf..f361b39b25 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2798,6 +2798,21 @@ build_rsa_oaep_params( oaep_params->ulSourceDataLen); } +static void +build_chacha20_params( + CK_CHACHA20_PARAMS *params, + CK_MECHANISM *mech, + CK_BYTE *iv) +{ + params->pBlockCounter = iv; + params->blockCounterBits = 64; + params->pNonce = &iv[8]; + params->ulNonceBits = 64; + + mech->pParameter = params; + mech->ulParameterLen = sizeof(*params); +} + static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { @@ -2808,6 +2823,8 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, { CK_RSA_PKCS_OAEP_PARAMS oaep; CK_GCM_PARAMS gcm; + CK_CHACHA20_PARAMS chacha20; + CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; } params = {0}; CK_ULONG in_len, out_len; int fd_in, fd_out; @@ -2859,6 +2876,23 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.pParameter = ¶ms.gcm; mech.ulParameterLen = sizeof(params.gcm); break; + case CKM_CHACHA20: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + if (iv_size != 16) { + util_fatal("Invalid iv size %zu\n", iv_size); + } + build_chacha20_params(¶ms.chacha20, &mech, iv); + break; + case CKM_CHACHA20_POLY1305: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + params.chacha20poly1305.pNonce = iv; + params.chacha20poly1305.ulNonceLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + params.chacha20poly1305.pAAD = aad; + params.chacha20poly1305.ulAADLen = aad_size; + mech.pParameter = ¶ms.chacha20poly1305; + mech.ulParameterLen = sizeof(params.chacha20poly1305); + break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } @@ -2938,6 +2972,8 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, { CK_RSA_PKCS_OAEP_PARAMS oaep; CK_GCM_PARAMS gcm; + CK_CHACHA20_PARAMS chacha20; + CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; } params = {0}; CK_ULONG in_len, out_len; int fd_in, fd_out; @@ -2985,6 +3021,23 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.pParameter = ¶ms.gcm; mech.ulParameterLen = sizeof(params.gcm); break; + case CKM_CHACHA20: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + if (iv_size != 16) { + util_fatal("Invalid iv size %zu\n", iv_size); + } + build_chacha20_params(¶ms.chacha20, &mech, iv); + break; + case CKM_CHACHA20_POLY1305: + iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + params.chacha20poly1305.pNonce = iv; + params.chacha20poly1305.ulNonceLen = iv_size; + aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + params.chacha20poly1305.pAAD = aad; + params.chacha20poly1305.ulAADLen = aad_size; + mech.pParameter = ¶ms.chacha20poly1305; + mech.ulParameterLen = sizeof(params.chacha20poly1305); + break; default: util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); } @@ -3451,7 +3504,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey if (type != NULL) { if (strncasecmp(type, "AES:", strlen("AES:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_AES_KEY_GEN}; - size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); const char *size = type + strlen("AES:"); key_type = CKK_AES; @@ -3466,10 +3519,9 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; - } - else if (strncasecmp(type, "DES:", strlen("DES:")) == 0) { + } else if (strncasecmp(type, "DES:", strlen("DES:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_DES_KEY_GEN}; - size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); const char *size = type + strlen("DES:"); key_type = CKK_DES; @@ -3484,10 +3536,9 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; - } - else if (strncasecmp(type, "DES3:", strlen("DES3:")) == 0) { + } else if (strncasecmp(type, "DES3:", strlen("DES3:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_DES3_KEY_GEN}; - size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); const char *size = type + strlen("DES3:"); key_type = CKK_DES3; @@ -3502,10 +3553,9 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; - } - else if (strncasecmp(type, "GENERIC:", strlen("GENERIC:")) == 0) { + } else if (strncasecmp(type, "GENERIC:", strlen("GENERIC:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_GENERIC_SECRET_KEY_GEN}; - size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); const char *size = type + strlen("GENERIC:"); key_type = CKK_GENERIC_SECRET; @@ -3520,9 +3570,7 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; - } - - else if (strncasecmp(type, "HKDF:", strlen("HKDF:")) == 0) { + } else if (strncasecmp(type, "HKDF:", strlen("HKDF:")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_HKDF_KEY_GEN}; size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); const char *size = type + strlen("HKDF:"); @@ -3537,6 +3585,34 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey if (key_length == 0) util_fatal("Unknown key type %s, expecting HKDF:", type); + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + n_attr++; + } else if (strncasecmp(type, "CHACHA20", strlen("CHACHA20")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_CHACHA20_KEY_GEN}; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); + + key_type = CKK_CHACHA20; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate Key mechanism not supported\n"); + + key_length = 32U; + + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); + n_attr++; + } else if (strncasecmp(type, "POLY1305", strlen("POLY1305")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_POLY1305_KEY_GEN}; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); + + key_type = CKK_POLY1305; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate Key mechanism not supported\n"); + + key_length = 32U; + FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; } else { @@ -4834,8 +4910,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) type = CKK_GENERIC_SECRET; else if (strncasecmp(opt_key_type, "HKDF:", strlen("HKDF:")) == 0) type = CKK_HKDF; + else if (strncasecmp(opt_key_type, "CHACHA20", strlen("CHACHA20")) == 0) + type = CKK_CHACHA20; + else if (strncasecmp(opt_key_type, "POLY1305", strlen("POLY1305")) == 0) + type = CKK_POLY1305; else - util_fatal("Unknown key type: 0x%lX", type); + util_fatal("Unknown key type: 0x%lX\nSupported key types are AES, DES3, GENERIC, HKDF, CHACHA20 and POLY1305", type); } FILL_ATTR(seckey_templ[0], CKA_CLASS, &clazz, sizeof(clazz)); @@ -5851,6 +5931,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) case CKK_DES: case CKK_DES3: case CKK_HKDF: + case CKK_CHACHA20: + case CKK_POLY1305: if (key_type == CKK_AES) printf("; AES"); else if (key_type == CKK_DES) @@ -5859,6 +5941,10 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("; DES3"); else if (key_type == CKK_HKDF) printf("; HKDF"); + else if (key_type == CKK_CHACHA20) + printf("; CHACHA20"); + else if (key_type == CKK_POLY1305) + printf("; POLY1305"); else printf("; Generic secret"); size = getVALUE_LEN(sess, obj); @@ -9362,6 +9448,11 @@ static struct mech_info p11_mechanisms[] = { { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL, MF_UNKNOWN }, { CKM_AES_KEY_WRAP, "AES-KEY-WRAP", NULL, MF_UNKNOWN }, { CKM_AES_KEY_WRAP_PAD, "AES-KEY-WRAP-PAD", NULL, MF_UNKNOWN}, + { CKM_CHACHA20_KEY_GEN, "CHACHA20-KEY-GEN", NULL, MF_UNKNOWN}, + { CKM_CHACHA20, "CHACHA20", NULL, MF_UNKNOWN}, + { CKM_POLY1305_KEY_GEN, "POLY1305-KEY-GEN", NULL, MF_UNKNOWN}, + { CKM_POLY1305, "POLY1305", NULL, MF_GENERIC_HMAC_FLAGS}, + { CKM_CHACHA20_POLY1305, "CHACHA20-POLY1305", NULL, MF_UNKNOWN}, { 0, NULL, NULL, MF_UNKNOWN }, }; From 6123b4262cdce3bf1883cc3e4096ef15291b61d1 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Tue, 11 Feb 2025 17:20:08 +0100 Subject: [PATCH 3807/4321] feat(pkcs11-tool): avoid code duplication when building the operation parameters --- src/tools/pkcs11-tool.c | 268 +++++++++++++--------------------------- 1 file changed, 83 insertions(+), 185 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f361b39b25..939f1bb4ff 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2813,89 +2813,102 @@ build_chacha20_params( mech->ulParameterLen = sizeof(*params); } -static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE key) +typedef union { - unsigned char in_buffer[1024], out_buffer[1024]; - CK_MECHANISM mech; - CK_RV rv; - union - { - CK_RSA_PKCS_OAEP_PARAMS oaep; - CK_GCM_PARAMS gcm; - CK_CHACHA20_PARAMS chacha20; - CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; - } params = {0}; - CK_ULONG in_len, out_len; - int fd_in, fd_out; - CK_BYTE_PTR iv = NULL; - size_t iv_size = 0; - ssize_t sz; - CK_BYTE_PTR aad = NULL; - size_t aad_size = 0; - - if (!opt_mechanism_used) - if (!find_mechanism(slot, CKF_DECRYPT|opt_allow_sw, NULL, 0, &opt_mechanism)) - util_fatal("Decrypt mechanism not supported"); - - fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); - memset(&mech, 0, sizeof(mech)); - mech.mechanism = opt_mechanism; - - if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) - util_fatal("The hash-algorithm is applicable only to " - "RSA-PKCS-OAEP mechanism"); + CK_RSA_PKCS_OAEP_PARAMS oaep; + CK_GCM_PARAMS gcm; + CK_CHACHA20_PARAMS chacha20; + CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; +} params_t; +static void +build_params( + params_t *params, + CK_MECHANISM *mech, + CK_BYTE_PTR *iv, + CK_BYTE_PTR *aad) +{ + size_t iv_size = 0; + size_t aad_size = 0; /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(¶ms.oaep, &mech, NULL, 0); + build_rsa_oaep_params(¶ms->oaep, mech, NULL, 0); break; case CKM_RSA_X_509: case CKM_RSA_PKCS: case CKM_AES_ECB: - mech.pParameter = NULL; - mech.ulParameterLen = 0; + mech->pParameter = NULL; + mech->ulParameterLen = 0; break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: iv_size = 16; - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - mech.pParameter = iv; - mech.ulParameterLen = iv_size; + *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + mech->pParameter = *iv; + mech->ulParameterLen = iv_size; break; case CKM_AES_GCM: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.gcm.pIv = iv; - params.gcm.ulIvLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.gcm.pAAD = aad; - params.gcm.ulAADLen = aad_size; - params.gcm.ulTagBits = opt_tag_bits; - mech.pParameter = ¶ms.gcm; - mech.ulParameterLen = sizeof(params.gcm); + *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + params->gcm.pIv = *iv; + params->gcm.ulIvLen = iv_size; + *aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + params->gcm.pAAD = *aad; + params->gcm.ulAADLen = aad_size; + params->gcm.ulTagBits = opt_tag_bits; + mech->pParameter = ¶ms->gcm; + mech->ulParameterLen = sizeof(params->gcm); break; case CKM_CHACHA20: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); if (iv_size != 16) { util_fatal("Invalid iv size %zu\n", iv_size); } - build_chacha20_params(¶ms.chacha20, &mech, iv); + build_chacha20_params(¶ms->chacha20, mech, *iv); break; case CKM_CHACHA20_POLY1305: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.chacha20poly1305.pNonce = iv; - params.chacha20poly1305.ulNonceLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.chacha20poly1305.pAAD = aad; - params.chacha20poly1305.ulAADLen = aad_size; - mech.pParameter = ¶ms.chacha20poly1305; - mech.ulParameterLen = sizeof(params.chacha20poly1305); + *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + params->chacha20poly1305.pNonce = *iv; + params->chacha20poly1305.ulNonceLen = iv_size; + *aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); + params->chacha20poly1305.pAAD = *aad; + params->chacha20poly1305.ulAADLen = aad_size; + mech->pParameter = ¶ms->chacha20poly1305; + mech->ulParameterLen = sizeof(params->chacha20poly1305); break; default: - util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); + break; } +} + +static void +decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + unsigned char in_buffer[1024], out_buffer[1024]; + CK_MECHANISM mech; + CK_RV rv; + params_t params = {0}; + CK_BYTE_PTR iv = NULL; + CK_BYTE_PTR aad = NULL; + CK_ULONG in_len, out_len; + int fd_in, fd_out; + ssize_t sz; + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_DECRYPT | opt_allow_sw, NULL, 0, &opt_mechanism)) + util_fatal("Decrypt mechanism not supported"); + + fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); + memset(&mech, 0, sizeof(mech)); + mech.mechanism = opt_mechanism; + + if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP) + util_fatal("The hash-algorithm is applicable only to " + "RSA-PKCS-OAEP mechanism"); + + build_params(¶ms, &mech, &iv, &aad); if (opt_input == NULL) fd_in = 0; @@ -2965,23 +2978,15 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char in_buffer[1024], out_buffer[1024]; - CK_MECHANISM mech; - CK_RV rv; - union - { - CK_RSA_PKCS_OAEP_PARAMS oaep; - CK_GCM_PARAMS gcm; - CK_CHACHA20_PARAMS chacha20; - CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; - } params = {0}; - CK_ULONG in_len, out_len; - int fd_in, fd_out; - ssize_t sz; - CK_BYTE_PTR iv = NULL; - size_t iv_size = 0; + unsigned char in_buffer[1024], out_buffer[1024]; + CK_MECHANISM mech; + CK_RV rv; + params_t params = {0}; + CK_BYTE_PTR iv = NULL; CK_BYTE_PTR aad = NULL; - size_t aad_size = 0; + CK_ULONG in_len, out_len; + int fd_in, fd_out; + ssize_t sz; if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_ENCRYPT | opt_allow_sw, NULL, 0, &opt_mechanism)) @@ -2995,52 +3000,7 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("The hash-algorithm is applicable only to " "RSA-PKCS-OAEP mechanism"); - switch (opt_mechanism) { - case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(¶ms.oaep, &mech, NULL, 0); - break; - case CKM_AES_ECB: - mech.pParameter = NULL; - mech.ulParameterLen = 0; - break; - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - iv_size = 16; - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - mech.pParameter = iv; - mech.ulParameterLen = iv_size; - break; - case CKM_AES_GCM: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.gcm.pIv = iv; - params.gcm.ulIvLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.gcm.pAAD = aad; - params.gcm.ulAADLen = aad_size; - params.gcm.ulTagBits = opt_tag_bits; - mech.pParameter = ¶ms.gcm; - mech.ulParameterLen = sizeof(params.gcm); - break; - case CKM_CHACHA20: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - if (iv_size != 16) { - util_fatal("Invalid iv size %zu\n", iv_size); - } - build_chacha20_params(¶ms.chacha20, &mech, iv); - break; - case CKM_CHACHA20_POLY1305: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.chacha20poly1305.pNonce = iv; - params.chacha20poly1305.ulNonceLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.chacha20poly1305.pAAD = aad; - params.chacha20poly1305.ulAADLen = aad_size; - mech.pParameter = ¶ms.chacha20poly1305; - mech.ulParameterLen = sizeof(params.chacha20poly1305); - break; - default: - util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism)); - } + build_params(¶ms, &mech, &iv, &aad); if (opt_input == NULL) fd_in = 0; @@ -3732,15 +3692,9 @@ unwrap_key(CK_SESSION_HANDLE session) unsigned char in_buffer[2048]; CK_ULONG wrapped_key_length; CK_BYTE_PTR pWrappedKey; + params_t params = {0}; CK_BYTE_PTR iv = NULL; - size_t iv_size = 0; CK_BYTE_PTR aad = NULL; - size_t aad_size = 0; - union - { - CK_RSA_PKCS_OAEP_PARAMS oaep; - CK_GCM_PARAMS gcm; - } params = {0}; CK_OBJECT_HANDLE hUnwrappingKey; ssize_t sz; @@ -3770,32 +3724,7 @@ unwrap_key(CK_SESSION_HANDLE session) close(fd); pWrappedKey = in_buffer; - switch (opt_mechanism) { - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - iv_size = 16; - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - mechanism.pParameter = iv; - mechanism.ulParameterLen = iv_size; - break; - case CKM_AES_GCM: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.gcm.pIv = iv; - params.gcm.ulIvLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.gcm.pAAD = aad; - params.gcm.ulAADLen = aad_size; - params.gcm.ulTagBits = opt_tag_bits; - mechanism.pParameter = ¶ms.gcm; - mechanism.ulParameterLen = sizeof(params.gcm); - break; - case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(¶ms.oaep, &mechanism, NULL, 0); - break; - default: - // Nothing to do with other mechanisms. - break; - } + build_params(¶ms, &mechanism, &iv, &aad); if (opt_key_type == NULL) { util_fatal("Key type must be specified"); @@ -3914,15 +3843,9 @@ wrap_key(CK_SESSION_HANDLE session) size_t hkey_id_len; int fd; ssize_t sz; + params_t params = {0}; CK_BYTE_PTR iv = NULL; - size_t iv_size = 0; CK_BYTE_PTR aad = NULL; - size_t aad_size = 0; - union - { - CK_RSA_PKCS_OAEP_PARAMS oaep; - CK_GCM_PARAMS gcm; - } params = {0}; if (NULL == opt_application_id) util_fatal("Use --application-id to specify secret key (to be wrapped)"); @@ -3933,32 +3856,7 @@ wrap_key(CK_SESSION_HANDLE session) mechanism.pParameter = NULL_PTR; mechanism.ulParameterLen = 0; - switch (opt_mechanism) { - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - iv_size = 16; - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - mechanism.pParameter = iv; - mechanism.ulParameterLen = iv_size; - break; - case CKM_AES_GCM: - iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); - params.gcm.pIv = iv; - params.gcm.ulIvLen = iv_size; - aad = hex_string_to_byte_array(opt_aad, &aad_size, "AAD"); - params.gcm.pAAD = aad; - params.gcm.ulAADLen = aad_size; - params.gcm.ulTagBits = opt_tag_bits; - mechanism.pParameter = ¶ms.gcm; - mechanism.ulParameterLen = sizeof(params.gcm); - break; - case CKM_RSA_PKCS_OAEP: - build_rsa_oaep_params(¶ms.oaep, &mechanism, NULL, 0); - break; - default: - // Nothing to do with other mechanisms. - break; - } + build_params(¶ms, &mechanism, &iv, &aad); hkey_id_len = sizeof(hkey_id); if (sc_hex_to_bin(opt_application_id, hkey_id, &hkey_id_len)) From 36e377b5a8a269e0780b30696575c03290019e1a Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 09:08:33 +0100 Subject: [PATCH 3808/4321] doc(pkcs11-tool): update the documentation for ChaCha20 and Poly1305 --- doc/tools/pkcs11-tool.1.xml | 4 ++-- doc/tools/tools.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index b087266a4a..3c1ca4c08c 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -148,7 +148,7 @@ Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, EC:ED25519, EC:X448, GOSTR3410-2012-256:B, - DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed. + DES:8, DES3:24, AES:16, AES:, CHACHA20, POLY1305 or GENERIC:64. If the key type was incompletely specified, possible values are listed. @@ -845,7 +845,7 @@ pkcs11-tool --login --wrap --id 75 --mechanism AES-CBC-PAD \ pkcs11-tool --login --unwrap --mechanism RSA-PKCS --id 22 \ -i aes_wrapped.key --key-type AES: \ - --application-id 90 --applicatin-label unwrapped-key + --application-id 90 --application-label unwrapped-key Use the SO-PIN to initialize or re-set the PIN: diff --git a/doc/tools/tools.html b/doc/tools/tools.html index d9feec87b2..bf20ebce2f 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1491,7 +1491,7 @@ --key-type specification

    Specify the type and (not always compulsory) flavour (byte-wise symmetric key length, bit-wise asymmetric key length, elliptic curve identifier, etc.) of the key to create, for example RSA:2048, EC:prime256v1, EC:ED25519, EC:X448, GOSTR3410-2012-256:B, - DES:8, DES3:24, AES:16, AES: or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    + DES:8, DES3:24, AES:16, AES:, CHACHA20, POLY1305 or GENERIC:64. If the key type was incompletely specified, possible values are listed.

    --usage-sign

    Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).

    --usage-decrypt @@ -1824,7 +1824,7 @@

     pkcs11-tool --login --unwrap --mechanism RSA-PKCS --id 22 \
     	-i aes_wrapped.key --key-type AES: \
    -	--application-id 90 --applicatin-label unwrapped-key
    +	--application-id 90 --application-label unwrapped-key
     				

    Use the SO-PIN to initialize or re-set the PIN: From 4d701bd04ef2c0109de2852ec5b2e059cdb0f2de Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 22 Dec 2024 23:28:37 +0200 Subject: [PATCH 3809/4321] Use config.h in RC files, no need to substitute them at configure time. Signed-off-by: Raul Metsma --- .gitignore | 1 - configure.ac | 7 ---- src/minidriver/Makefile.am | 4 +- ...driver.rc.in => versioninfo-minidriver.rc} | 21 ++++++---- src/pkcs11/Makefile.am | 4 +- src/pkcs11/versioninfo-pkcs11-spy.rc | 41 +++++++++++++++++++ src/pkcs11/versioninfo-pkcs11-spy.rc.in | 38 ----------------- src/pkcs11/versioninfo-pkcs11.rc | 41 +++++++++++++++++++ src/pkcs11/versioninfo-pkcs11.rc.in | 38 ----------------- src/tools/Makefile.am | 4 +- ...ify.rc.in => versioninfo-opensc-notify.rc} | 21 ++++++---- src/tools/versioninfo-tools.rc | 40 ++++++++++++++++++ src/tools/versioninfo-tools.rc.in | 37 ----------------- win32/Make.rules.mak | 2 +- win32/Makefile.am | 8 ++-- win32/versioninfo-customactions.rc | 40 ++++++++++++++++++ win32/versioninfo-customactions.rc.in | 37 ----------------- win32/versioninfo.rc | 41 +++++++++++++++++++ win32/versioninfo.rc.in | 38 ----------------- win32/winconfig.h.in | 16 ++++++++ 20 files changed, 254 insertions(+), 225 deletions(-) rename src/minidriver/{versioninfo-minidriver.rc.in => versioninfo-minidriver.rc} (50%) create mode 100644 src/pkcs11/versioninfo-pkcs11-spy.rc delete mode 100644 src/pkcs11/versioninfo-pkcs11-spy.rc.in create mode 100644 src/pkcs11/versioninfo-pkcs11.rc delete mode 100644 src/pkcs11/versioninfo-pkcs11.rc.in rename src/tools/{versioninfo-opensc-notify.rc.in => versioninfo-opensc-notify.rc} (50%) create mode 100644 src/tools/versioninfo-tools.rc delete mode 100644 src/tools/versioninfo-tools.rc.in create mode 100644 win32/versioninfo-customactions.rc delete mode 100644 win32/versioninfo-customactions.rc.in create mode 100644 win32/versioninfo.rc delete mode 100644 win32/versioninfo.rc.in diff --git a/.gitignore b/.gitignore index cbedc03c4c..0f0e175901 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ test-driver *.pdb *.rej *.u -*.rc *.pc *~ *.o diff --git a/configure.ac b/configure.ac index 894cd4a19f..f8342b529f 100644 --- a/configure.ac +++ b/configure.ac @@ -1177,8 +1177,6 @@ AC_CONFIG_FILES([ src/libopensc/Makefile src/sm/Makefile src/pkcs11/Makefile - src/pkcs11/versioninfo-pkcs11.rc - src/pkcs11/versioninfo-pkcs11-spy.rc src/pkcs11/opensc-pkcs11.pc src/pkcs15init/Makefile src/scconf/Makefile @@ -1188,15 +1186,10 @@ AC_CONFIG_FILES([ src/tests/fuzzing/Makefile src/tests/unittests/Makefile src/tools/Makefile - src/tools/versioninfo-tools.rc - src/tools/versioninfo-opensc-notify.rc src/smm/Makefile src/minidriver/Makefile - src/minidriver/versioninfo-minidriver.rc src/minidriver/opensc-minidriver.inf win32/Makefile - win32/versioninfo.rc - win32/versioninfo-customactions.rc win32/winconfig.h win32/OpenSC.iss win32/OpenSC.wxs diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index 4e7165ad55..ffd6f2194d 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-minidriver.rc -EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc.in opensc-minidriver.dll.manifest +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc opensc-minidriver.dll.manifest if ENABLE_MINIDRIVER lib_LTLIBRARIES = opensc-minidriver@LIBRARY_BITNESS@.la diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc similarity index 50% rename from src/minidriver/versioninfo-minidriver.rc.in rename to src/minidriver/versioninfo-minidriver.rc index 4844a14b00..d39fd0dcd5 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc @@ -1,4 +1,7 @@ #include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) #define IDC_STATIC -1 /* defined twice: in resource file and in source code */ @@ -11,8 +14,8 @@ IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.i #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x21L @@ -27,15 +30,15 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT VALUE "LegalTrademarks", "" VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) VALUE "SpecialBuild", "" VALUE "FileDescription", "OpenSC minidriver" END diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 8fb404a09a..ec97761264 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-pkcs11.rc $(srcdir)/versioninfo-pkcs11-spy.rc -EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc versioninfo-pkcs11-spy.rc opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest if ENABLE_SHARED lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la diff --git a/src/pkcs11/versioninfo-pkcs11-spy.rc b/src/pkcs11/versioninfo-pkcs11-spy.rc new file mode 100644 index 0000000000..d39deb8003 --- /dev/null +++ b/src/pkcs11/versioninfo-pkcs11-spy.rc @@ -0,0 +1,41 @@ +#include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC PKCS#11 spy module" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/src/pkcs11/versioninfo-pkcs11-spy.rc.in b/src/pkcs11/versioninfo-pkcs11-spy.rc.in deleted file mode 100644 index a4a1a281da..0000000000 --- a/src/pkcs11/versioninfo-pkcs11-spy.rc.in +++ /dev/null @@ -1,38 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" - VALUE "LegalTrademarks", "" - VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" - VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC PKCS#11 spy module" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - diff --git a/src/pkcs11/versioninfo-pkcs11.rc b/src/pkcs11/versioninfo-pkcs11.rc new file mode 100644 index 0000000000..f437f9445d --- /dev/null +++ b/src/pkcs11/versioninfo-pkcs11.rc @@ -0,0 +1,41 @@ +#include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC PKCS#11 module" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/src/pkcs11/versioninfo-pkcs11.rc.in b/src/pkcs11/versioninfo-pkcs11.rc.in deleted file mode 100644 index e8bc91d3be..0000000000 --- a/src/pkcs11/versioninfo-pkcs11.rc.in +++ /dev/null @@ -1,38 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" - VALUE "LegalTrademarks", "" - VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" - VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC PKCS#11 module" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index ae491d2efd..db3fdd6fcc 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -21,8 +21,8 @@ do_subst = $(SED) \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc $(srcdir)/versioninfo-opensc-notify.rc -EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in versioninfo-opensc-notify.rc.in goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in org.opensc-project.mac.pkcs11-register.plist.in org.opensc-project.mac.opensc-notify.plist.in +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc versioninfo-opensc-notify.rc goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in org.opensc-project.mac.pkcs11-register.plist.in org.opensc-project.mac.opensc-notify.plist.in noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ diff --git a/src/tools/versioninfo-opensc-notify.rc.in b/src/tools/versioninfo-opensc-notify.rc similarity index 50% rename from src/tools/versioninfo-opensc-notify.rc.in rename to src/tools/versioninfo-opensc-notify.rc index 3b01d660b9..ce136cf617 100644 --- a/src/tools/versioninfo-opensc-notify.rc.in +++ b/src/tools/versioninfo-opensc-notify.rc @@ -1,4 +1,7 @@ #include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) #define IDC_STATIC -1 /* defined twice: in resource file and in source code */ @@ -11,8 +14,8 @@ IDI_SMARTCARD ICON "../../win32/DDORes.dll_14_2302.i #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x21L @@ -27,15 +30,15 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT VALUE "LegalTrademarks", "" VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) VALUE "SpecialBuild", "" VALUE "FileDescription", "OpenSC Notify" END diff --git a/src/tools/versioninfo-tools.rc b/src/tools/versioninfo-tools.rc new file mode 100644 index 0000000000..3daacc6b4b --- /dev/null +++ b/src/tools/versioninfo-tools.rc @@ -0,0 +1,40 @@ +#include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC command line tool" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/tools/versioninfo-tools.rc.in b/src/tools/versioninfo-tools.rc.in deleted file mode 100644 index 444b1a2522..0000000000 --- a/src/tools/versioninfo-tools.rc.in +++ /dev/null @@ -1,37 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" - VALUE "LegalTrademarks", "" - VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" - VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC command line tool" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index c274f56938..049792d9cc 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -138,7 +138,7 @@ COPTS = /O1 /$(BUILD_TYPE) $(COPTS) cl $(COPTS) $(WIX_INCL_DIR) /c $< .rc.res:: - rc /l 0x0409 $< + rc /l 0x0409 /I$(TOPDIR) $< clean:: del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.res diff --git a/win32/Makefile.am b/win32/Makefile.am index 751f7ae498..73dd81ba22 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -1,9 +1,9 @@ include $(top_srcdir)/win32/ltrc.inc -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo.rc $(srcdir)/winconfig.h \ - $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs $(srcdir)/versioninfo-customactions.rc -EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak versioninfo.rc.in winconfig.h.in \ - OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc.in \ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/winconfig.h \ + $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs +EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak versioninfo.rc winconfig.h.in \ + OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc \ OpenSC.ico dlgbmp.bmp bannrbmp.bmp DDORes.dll_14_2302.ico dist_noinst_HEADERS = versioninfo.rc winconfig.h OpenSC.iss OpenSC.wxs diff --git a/win32/versioninfo-customactions.rc b/win32/versioninfo-customactions.rc new file mode 100644 index 0000000000..63c9378de3 --- /dev/null +++ b/win32/versioninfo-customactions.rc @@ -0,0 +1,40 @@ +#include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC custom actions setup" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/win32/versioninfo-customactions.rc.in b/win32/versioninfo-customactions.rc.in deleted file mode 100644 index 757e916584..0000000000 --- a/win32/versioninfo-customactions.rc.in +++ /dev/null @@ -1,37 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" - VALUE "LegalTrademarks", "" - VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" - VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC custom actions setup" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/win32/versioninfo.rc b/win32/versioninfo.rc new file mode 100644 index 0000000000..51889eb365 --- /dev/null +++ b/win32/versioninfo.rc @@ -0,0 +1,41 @@ +#include +#include "config.h" +#define TO_STR_HELPER(x) #x +#define TO_STR(x) TO_STR_HELPER(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + PRODUCTVERSION OPENSC_VERSION_MAJOR,OPENSC_VERSION_MINOR,OPENSC_VERSION_FIX,OPENSC_VERSION_REVISION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", OPENSC_VS_FF_COMMENTS + VALUE "CompanyName", OPENSC_VS_FF_COMPANY_NAME + VALUE "FileVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "InternalName", PACKAGE_NAME + VALUE "LegalCopyright", OPENSC_VS_FF_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", "" + VALUE "PrivateBuild", "" + VALUE "ProductName", OPENSC_VS_FF_PRODUCT_NAME + VALUE "ProductVersion", TO_STR(OPENSC_VERSION_MAJOR.OPENSC_VERSION_MINOR.OPENSC_VERSION_FIX.OPENSC_VERSION_REVISION) + VALUE "SpecialBuild", "" + VALUE "FileDescription", "OpenSC common usage application extension" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/win32/versioninfo.rc.in b/win32/versioninfo.rc.in deleted file mode 100644 index 23cf3ed49f..0000000000 --- a/win32/versioninfo.rc.in +++ /dev/null @@ -1,38 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - PRODUCTVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "@OPENSC_VS_FF_COMMENTS@" - VALUE "CompanyName", "@OPENSC_VS_FF_COMPANY_NAME@" - VALUE "FileVersion", "@OPENSC_VERSION_MAJOR@.@OPENSC_VERSION_MINOR@.@OPENSC_VERSION_FIX@.@OPENSC_VERSION_REVISION@" - VALUE "InternalName", "@PACKAGE_NAME@" - VALUE "LegalCopyright", "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" - VALUE "LegalTrademarks", "" - VALUE "PrivateBuild", "" - VALUE "ProductName", "@OPENSC_VS_FF_PRODUCT_NAME@" - VALUE "ProductVersion", "@OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@" - VALUE "SpecialBuild", "" - VALUE "FileDescription", "OpenSC common usage application extension" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index de053c016d..e820758b52 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -84,6 +84,14 @@ #define OPENSC_VERSION_MINOR @OPENSC_VERSION_MINOR@ #endif +#ifndef OPENSC_VERSION_FIX +#define OPENSC_VERSION_FIX @OPENSC_VERSION_FIX@ +#endif + +#ifndef OPENSC_VERSION_REVISION +#define OPENSC_VERSION_REVISION @OPENSC_VERSION_REVISION@ +#endif + #ifndef OPENSC_VS_FF_COMPANY_NAME #define OPENSC_VS_FF_COMPANY_NAME "@OPENSC_VS_FF_COMPANY_NAME@" #endif @@ -92,6 +100,14 @@ #define OPENSC_VS_FF_PRODUCT_NAME "@OPENSC_VS_FF_PRODUCT_NAME@" #endif +#ifndef OPENSC_VS_FF_LEGAL_COPYRIGHT +#define OPENSC_VS_FF_LEGAL_COPYRIGHT "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" +#endif + +#ifndef OPENSC_VS_FF_COMMENTS +#define OPENSC_VS_FF_COMMENTS "@OPENSC_VS_FF_COMMENTS@" +#endif + #ifndef CVCDIR #define CVCDIR "%PROGRAMFILES%\\OpenSC Project\\OpenSC\\cvc" #endif From 52bc91cb1b43f1762b70041fbf48f5e2c10025cb Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 16 Jan 2025 09:30:40 +0200 Subject: [PATCH 3810/4321] Build Windows Arm64 binaries #2450, Depends #3283 Signed-off-by: Raul Metsma --- .github/vcpkg.json | 8 ++++++ .github/workflows/windows.yml | 29 +++++++++++++------ configure.ac | 6 +--- win32/Make.rules.mak | 1 - win32/Makefile.mak | 2 +- win32/OpenSC.wxs.in | 53 ++++++++++++++++++++--------------- 6 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 .github/vcpkg.json diff --git a/.github/vcpkg.json b/.github/vcpkg.json new file mode 100644 index 0000000000..32ea198967 --- /dev/null +++ b/.github/vcpkg.json @@ -0,0 +1,8 @@ +{ + "name": "opensc", + "dependencies": [ + "openssl", + "zlib" + ], + "builtin-baseline": "e4644bd15436d406bba71928d086c809e5c9ca45" +} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8fa0f54ff2..8261a53c3e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -20,11 +20,19 @@ jobs: runs-on: ${{ matrix.image }} strategy: matrix: - platform: [x86, x64] + platform: [x86, x64, arm64] configuration: [Light, Release] image: [windows-2019, windows-2022] + include: + - platform: x86 + setenv: amd64_x86 + - platform: x64 + setenv: amd64 + - platform: arm64 + setenv: amd64_arm64 env: OPENPACE_VER: 1.1.3 + VCPKG_INSTALLED: ${{ github.workspace }}\vcpkg_installed steps: - name: Checkout uses: actions/checkout@v4 @@ -34,7 +42,7 @@ jobs: - name: Package name shell: bash run: | - echo ARTIFACT=OpenSC-${{ steps.ghd.outputs.tag }}_${{ matrix.platform == 'x86' && 'win32' || 'win64' }}${{ matrix.configuration == 'Light' && '-Light' || '' }} >> $GITHUB_ENV + echo ARTIFACT=OpenSC-${{ steps.ghd.outputs.tag }}_${{ matrix.platform }}${{ matrix.configuration == 'Light' && '-Light' || '' }} >> $GITHUB_ENV - name: Install CPDK run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Install autotools @@ -59,14 +67,17 @@ jobs: - name: Setup dev env uses: ilammy/msvc-dev-cmd@v1 with: - arch: ${{ matrix.platform }} + arch: ${{ matrix.setenv }} - name: Prepare vcpkg if: matrix.configuration == 'Release' - uses: lukka/run-vcpkg@v7 + uses: lukka/run-vcpkg@v11 with: - vcpkgArguments: zlib openssl - vcpkgGitCommitId: 511d74f695bd45959d12b50b00f1b68f69e8f0b0 - vcpkgTriplet: ${{ matrix.platform }}-windows-static + vcpkgGitCommitId: e4644bd15436d406bba71928d086c809e5c9ca45 + vcpkgJsonGlob: .github/vcpkg.json + runVcpkgInstall: true + env: + VCPKG_DEFAULT_TRIPLET: ${{ matrix.platform }}-windows-static + VCPKG_INSTALLED_DIR: ${{ env.VCPKG_INSTALLED }} - name: Install WIX run: powershell -ExecutionPolicy Bypass -File .github/setup-wix.ps1 - name: Restore Cache @@ -82,7 +93,7 @@ jobs: Invoke-WebRequest "https://github.com/frankmorgner/openpace/archive/${env:OPENPACE_VER}.zip" -OutFile openpace.zip tar xf openpace.zip cd openpace-${env:OPENPACE_VER}\src - cl /nologo /O1 /Zi /W3 /GS /MT /I${env:RUNVCPKG_VCPKG_ROOT}\installed\${env:RUNVCPKG_VCPKG_TRIPLET}\include /I. ` + cl /nologo /O1 /Zi /W3 /GS /MT /I${env:VCPKG_INSTALLED}\${env:VCPKG_DEFAULT_TRIPLET}\include /I. ` /DX509DIR=`"/`" /DCVCDIR=`"/`" /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN ` /DHAVE_ASN1_STRING_GET0_DATA /DHAVE_DECL_OPENSSL_ZALLOC /DHAVE_DH_GET0_KEY /DHAVE_DH_GET0_PQG ` /DHAVE_DH_SET0_KEY /DHAVE_DH_SET0_PQG /DHAVE_ECDSA_SIG_GET0 /DHAVE_ECDSA_SIG_SET0 ` @@ -98,7 +109,7 @@ jobs: - name: Set NMake Variables if: matrix.configuration == 'Release' run: | - $VCPKG_DIR="${env:RUNVCPKG_VCPKG_ROOT}\installed\${env:RUNVCPKG_VCPKG_TRIPLET}" + $VCPKG_DIR="${env:VCPKG_INSTALLED}\${env:VCPKG_DEFAULT_TRIPLET}" echo "ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC" >> $env:GITHUB_ENV echo "ZLIB_INCL_DIR=/I${VCPKG_DIR}\include" >> $env:GITHUB_ENV echo "ZLIB_LIB=${VCPKG_DIR}\lib\zlib.lib" >> $env:GITHUB_ENV diff --git a/configure.ac b/configure.ac index f8342b529f..b7078f533e 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,6 @@ define([VS_FF_LEGAL_COMPANY_URL], [https://github.com/OpenSC]) define([VS_FF_COMMENTS], [Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).]) define([VS_FF_PRODUCT_NAME], [OpenSC smartcard framework]) define([VS_FF_PRODUCT_UPDATES], [https://github.com/OpenSC/OpenSC/releases]) -define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(m4/version.m4.ci) @@ -40,7 +39,6 @@ OPENSC_VS_FF_COMPANY_URL="VS_FF_LEGAL_COMPANY_URL" OPENSC_VS_FF_COMMENTS="VS_FF_COMMENTS" OPENSC_VS_FF_PRODUCT_NAME="VS_FF_PRODUCT_NAME" OPENSC_VS_FF_PRODUCT_UPDATES="VS_FF_PRODUCT_UPDATES" -OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL" # LT Version numbers, remember to change them just *before* a release. # (Code changed: REVISION++) @@ -1082,7 +1080,6 @@ AC_DEFINE_UNQUOTED([OPENSC_VS_FF_COMPANY_NAME], ["${OPENSC_VS_FF_COMPANY_NAME}"] AC_DEFINE_UNQUOTED([OPENSC_VS_FF_COMMENTS], ["${OPENSC_VS_FF_COMMENTS}"], [OpenSC version-info Comments]) AC_DEFINE_UNQUOTED([OPENSC_VS_FF_PRODUCT_NAME], ["${OPENSC_VS_FF_PRODUCT_NAME}"], [OpenSC version-info ProductName]) AC_DEFINE_UNQUOTED([OPENSC_VS_FF_PRODUCT_UPDATES], ["${OPENSC_VS_FF_PRODUCT_UPDATES}"], [OpenSC version-info UpdateURL]) -AC_DEFINE_UNQUOTED([OPENSC_VS_FF_PRODUCT_URL], ["${OPENSC_VS_FF_PRODUCT_URL}"], [OpenSC version-info ProductURL]) AC_DEFINE_UNQUOTED([OPENSC_VS_FF_COMPANY_URL], ["${OPENSC_VS_FF_COMPANY_URL}"], [OpenSC version-info UpdateURL]) pkcs11dir="\$(libdir)/pkcs11" @@ -1099,7 +1096,6 @@ AC_SUBST([OPENSC_VS_FF_COMPANY_NAME]) AC_SUBST([OPENSC_VS_FF_COMMENTS]) AC_SUBST([OPENSC_VS_FF_PRODUCT_NAME]) AC_SUBST([OPENSC_VS_FF_PRODUCT_UPDATES]) -AC_SUBST([OPENSC_VS_FF_PRODUCT_URL]) AC_SUBST([OPENSC_VS_FF_COMPANY_URL]) AC_SUBST([OPENSC_LT_CURRENT]) AC_SUBST([OPENSC_LT_REVISION]) @@ -1218,7 +1214,7 @@ Company URL: ${OPENSC_VS_FF_COMPANY_URL} Comments: ${OPENSC_VS_FF_COMMENTS} Product name: ${OPENSC_VS_FF_PRODUCT_NAME} Product updates: ${OPENSC_VS_FF_PRODUCT_UPDATES} -Product URL: ${OPENSC_VS_FF_PRODUCT_URL} +Product URL: ${PACKAGE_URL} User binaries: $(eval eval eval echo "${bindir}") Configuration files: $(eval eval eval echo "${sysconfdir}") diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 049792d9cc..4c31fd258d 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -121,7 +121,6 @@ COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WAR /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) LINKFLAGS = /nologo /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD LIBFLAGS = /nologo -WIXFLAGS = -arch $(PLATFORM) $(WIXFLAGS) !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMT diff --git a/win32/Makefile.mak b/win32/Makefile.mak index 32a51aba41..0fe63736f3 100644 --- a/win32/Makefile.mak +++ b/win32/Makefile.mak @@ -14,7 +14,7 @@ customactions.dll: versioninfo-customactions.res customactions.obj link /dll $(LINKFLAGS) /def:$*.def /out:customactions.dll versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib OpenSC.msi: OpenSC.wxs customactions.dll - wix build -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -d SOURCE_DIR=$(TOPDIR) $(WIXFLAGS) OpenSC.wxs + wix build -arch $(PLATFORM) -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -d SOURCE_DIR=$(TOPDIR) $(WIXFLAGS) OpenSC.wxs clean:: del /Q config.h *.msi *.wixobj *.wixpdb diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 803abecba6..33cf991eca 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -6,6 +6,17 @@ + + + + + + + + + + + @@ -13,6 +24,8 @@ + + - + - - + + @@ -45,6 +56,12 @@ + + + + + @@ -57,7 +74,7 @@ - + @@ -71,9 +88,7 @@ - - - + @@ -106,12 +121,8 @@ - - - - - - + + @@ -121,7 +132,7 @@ - + @@ -129,12 +140,8 @@ - - - - - - + + From 2d21e324fc4eeb45ab847255ebe223203ff741dd Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 12 Dec 2024 10:18:57 +0200 Subject: [PATCH 3811/4321] Remove obsolete tokend support Signed-off-by: Raul Metsma --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .gitignore | 1 - MacOSX/Distribution.xml.in | 19 +------- MacOSX/Distribution_universal.xml.in | 19 +------- MacOSX/build-package.in | 43 ++----------------- doc/files/files.html | 15 +------ doc/files/opensc.conf.5.xml.in | 25 +---------- etc/opensc.conf.example.in | 23 +--------- src/libopensc/ctx.c | 7 --- src/libopensc/pkcs15.c | 6 +-- src/libopensc/reader-pcsc.c | 8 ---- .../497025125e0dfab0b9e16155ce16d6e25ec8ec6d | 8 ---- 12 files changed, 11 insertions(+), 165 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e6f6596dc2..6f8e139a7d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,4 +14,4 @@ run this command: `opensc-tool -n` - [ ] New files have a LGPL 2.1 license statement - [ ] PKCS#11 module is tested - [ ] Windows minidriver is tested -- [ ] macOS tokend is tested +- [ ] macOS token is tested diff --git a/.gitignore b/.gitignore index 0f0e175901..368a04c29b 100644 --- a/.gitignore +++ b/.gitignore @@ -108,7 +108,6 @@ MacOSX/resources/Welcome.html *.dmg *.pkg -OpenSC.tokend/ build/ engine_pkcs11/ libp11/ diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index 83874467be..238513837c 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -11,32 +11,15 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/I @PACKAGE_STRING@ - - OpenSC.pkg - - OpenSC-tokend.pkg - - + OpenSCToken.pkg diff --git a/MacOSX/Distribution_universal.xml.in b/MacOSX/Distribution_universal.xml.in index 40ea3949e3..0b8823d122 100644 --- a/MacOSX/Distribution_universal.xml.in +++ b/MacOSX/Distribution_universal.xml.in @@ -11,32 +11,15 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/I @PACKAGE_STRING@ - - OpenSC.pkg - - OpenSC-tokend.pkg - - + OpenSCToken.pkg diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 0dcc9acdba..0ebca23b4c 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -1,5 +1,5 @@ #!/bin/bash -# Build the macOS installer for the tokend and command line tools. +# Build the macOS installer for the token and command line tools. # # This is only tested and supported on macOS 10.10 or later, using Xcode 6.0.1. # Building should also work on older macOS versions with slight changes; YMMV. @@ -129,42 +129,6 @@ if test -n "${CODE_SIGN_IDENTITY}"; then fi -# Build OpenSC.tokend when XCode version < 10 -if (( $(xcodebuild -version | sed -En 's/Xcode[[:space:]]+([0-9]+)(\.[0-9]*)*/\1/p') < 10 )); then - # Check out OpenSC.tokend, if not already fetched. - if ! test -e OpenSC.tokend; then - git clone https://github.com/OpenSC/OpenSC.tokend.git - fi - - # Create the symlink to OpenSC sources - test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src - - # Build and copy OpenSC.tokend - if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then - xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend \ - CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual - else - xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend - fi - - TOKEND="-tokend" -else - # https://github.com/OpenSC/OpenSC.tokend/issues/33 - mkdir -p ${BUILDPATH}/target_tokend - TOKEND="" -fi - -#if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then - #if ! test -e terminal-notifier-1.7.1.zip; then - #curl -L https://github.com/julienXX/terminal-notifier/releases/download/1.7.1/terminal-notifier-1.7.1.zip > terminal-notifier-1.7.1.zip - #fi - #if ! test -e terminal-notifier-1.7.1; then - #unzip terminal-notifier-1.7.1.zip - #fi - #mkdir -p $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications - #cp -r terminal-notifier-1.7.1/terminal-notifier.app $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications -#fi - imagedir=$(mktemp -d) # Prepare target root @@ -221,7 +185,6 @@ fi # Build package pkgbuild --root ${BUILDPATH}/target --component-plist MacOSX/target.plist --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg -pkgbuild --root ${BUILDPATH}/target_tokend --component-plist MacOSX/target_tokend.plist --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.opensc-project.mac.opensctoken --version @PACKAGE_VERSION@ --install-location / OpenSCToken.pkg pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg @@ -241,9 +204,9 @@ if test -n "${CODE_SIGN_IDENTITY}"; then fi # Create .dmg -rm -f OpenSC-@PACKAGE_VERSION@$TOKEND.dmg +rm -f OpenSC-@PACKAGE_VERSION@.dmg i=0 -while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@$TOKEND.dmg +while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@.dmg do i=$[$i+1] if [ $i -gt 2 ] diff --git a/doc/files/files.html b/doc/files/files.html index cd18cfcf37..486b13ff76 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -98,8 +98,6 @@ onepin-opensc-pkcs11: Configuration block for the PKCS#11 one-PIN-module (onepin-opensc-pkcs11.so)

  • cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) -

  • - tokend: Configuration block for macOS' tokend (OpenSC.tokend)

  • cardos-tool, cryptoflex-tool, @@ -352,8 +350,6 @@ Internal configuration options where name is one of:

    pkcs11 { @@ -887,8 +883,7 @@

  • ignore: Ignore PIN-protected certificates.

  • - (Default: ignore in Tokend, - protect otherwise). + (Default: protect.

    enable_pkcs15_emulation = bool;

    @@ -991,13 +986,7 @@ sign_pin = name;

    Name of the PIN object that will be used for signing. -

    Configuration of Tokend

    - score = num; -

    - Score for OpenSC.tokend - (Default: 300). The tokend with - the highest score shall be used. -

    Configuration of PKCS#11

    +

    Configuration of PKCS#11

    max_virtual_slots = num;

    Maximum Number of virtual slots (Default: diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 820a62be18..86195b8303 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -88,9 +88,6 @@ app application { cardmod: Configuration block for Windows' minidriver (opensc-minidriver.dll) - - tokend: Configuration block for macOS' tokend (OpenSC.tokend) - cardos-tool, cryptoflex-tool, @@ -481,9 +478,6 @@ app application { pkcs15: See - - tokend: See - @@ -1368,8 +1362,7 @@ app application { ignore: Ignore PIN-protected certificates. - (Default: ignore in Tokend, - protect otherwise). + (Default: protect. @@ -1545,22 +1538,6 @@ app application { - - Configuration of Tokend - - - - - - - Score for OpenSC.tokend - (Default: 300). The tokend with - the highest score shall be used. - - - - - Configuration of PKCS#11 diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 8ac5559e39..3781f48a3d 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -947,7 +947,7 @@ app default { # How to handle a PIN-protected certificate # Valid values: protect, declassify, ignore. - # Default: ignore in tokend, protect otherwise + # Default: protect # pin_protected_certificate = declassify; # Enable pkcs15 emulation. @@ -1167,27 +1167,6 @@ app "C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe" { } } -# Used by OpenSC.tokend on Mac OS X only -app tokend { - # The file to which debug log will be written - # Default: /tmp/opensc-tokend.log - # - # debug_file = /Library/Logs/OpenSC.tokend.log - - framework tokend { - # Score for OpenSC.tokend - # The tokend with the highest score shall be used. - # Default: 300 - # - # score = 10; - - # Tokend ignore to read PIN protected certificate that is set SC_PKCS15_CO_FLAG_PRIVATE flag. - # Default: true - # - # ignore_private_certificate = false; - } -} - # Used by OpenSC minidriver on Windows only app cardmod { } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 6fbab389c1..b95a24e9fc 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -319,13 +319,6 @@ static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts) fclose(ctx->debug_file); ctx->debug_file = stderr; ctx->flags = 0; - -#ifdef __APPLE__ - /* Override the default debug log for OpenSC.tokend to be different from PKCS#11. - * TODO: Could be moved to OpenSC.tokend */ - if (!strcmp(ctx->app_name, "tokend")) - ctx->debug_file = fopen("/tmp/opensc-tokend.log", "a"); -#endif ctx->forced_driver = NULL; add_internal_drvs(opts); } diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 0876cf8f88..c89feddb8c 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1288,11 +1288,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; - if (0 == strcmp(ctx->app_name, "tokend")) { - pin_protected_certificate = "ignore"; - } else { - pin_protected_certificate = "protect"; - } + pin_protected_certificate = "protect"; private_certificate = ""; conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 51b974a598..9619edd95a 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -644,14 +644,6 @@ static int pcsc_connect(sc_reader_t *reader) rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, reader->name, priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED, protocol, &card_handle, &active_proto); -#ifdef __APPLE__ - if (rv == (LONG)SCARD_E_SHARING_VIOLATION) { - sleep(1); /* Try again to compete with Tokend probes */ - rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, reader->name, - priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED, - protocol, &card_handle, &active_proto); - } -#endif if (rv != SCARD_S_SUCCESS) { PCSC_TRACE(reader, "SCardConnect failed", rv); return pcsc_to_opensc_error(rv); diff --git a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d index 1193203c07..a8f57485e1 100644 --- a/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d +++ b/src/tests/fuzzing/corpus/fuzz_scconf_parse_string/497025125e0dfab0b9e16155ce16d6e25ec8ec6d @@ -169,14 +169,6 @@ app onepin-opensc-pkcs11 { } } -# Used by OpenSC.tokend on Mac OS X only -app tokend { - framework tokend { - score = 10; - ignore_private_certificate = false; - } -} - # Used by OpenSC minidriver on Windows only app cardmod { } From 9c57b82c51dd76f138760ac1445581797a62e19d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Feb 2025 13:55:53 +0100 Subject: [PATCH 3812/4321] Remove double-semicolons --- src/libopensc/cwa14890.c | 2 +- src/minidriver/minidriver.c | 4 ++-- src/pkcs11/framework-pkcs15.c | 2 +- src/pkcs11/pkcs11-global.c | 2 +- src/tests/unittests/pkcs15-emulator-filter.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 77aaf7cb49..8f1d5561bf 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -305,7 +305,7 @@ static int cwa_parse_tlv(sc_card_t * card, } } tlv->data = buffer + n + j; - tlv->buflen = j + tlv->len;; + tlv->buflen = j + tlv->len; sc_log(ctx, "Found Tag: '0x%02X': Length: '%"SC_FORMAT_LEN_SIZE_T"u' Value:\n%s", tlv->tag, tlv->len, sc_dump_hex(tlv->data, tlv->len)); /* set index to next Tag to jump to */ diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index c378270907..c835f49c87 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -902,11 +902,11 @@ md_contguid_add_conversion(PCARD_DATA pCardData, struct sc_pkcs15_object *prkey, strlcpy(md_static_conversions[i].szOpenSCGuid, szOpenSCGuid, MAX_CONTAINER_NAME_LEN + 1); logprintf(pCardData, 0, "md_contguid_add_conversion(): Registering conversion '%s' '%s'\n", szWindowsGuid, szOpenSCGuid); - return SCARD_S_SUCCESS;; + return SCARD_S_SUCCESS; } } logprintf(pCardData, 0, "md_contguid_add_conversion(): Unable to add a new conversion with guid %s.\n", szWindowsGuid); - return SCARD_F_INTERNAL_ERROR;; + return SCARD_F_INTERNAL_ERROR; } /* remove an entry in the guid conversion table*/ diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 6ef2cb67cd..f51cc5f8e4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1506,7 +1506,7 @@ static void _add_profile_object(struct sc_pkcs11_slot *slot, struct pkcs15_fw_da int rv; if (slot->profile) { - struct pkcs15_profile_object *pobj = (struct pkcs15_profile_object *)slot->profile;; + struct pkcs15_profile_object *pobj = (struct pkcs15_profile_object *)slot->profile; /* already exists -- downgrade if we found some non-public certificates */ if (pobj->profile_id == CKP_PUBLIC_CERTIFICATES_TOKEN && !public_certificates) { pobj->profile_id = CKP_AUTHENTICATION_TOKEN; diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 65fcee73c9..b72de8efe3 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -76,7 +76,7 @@ CK_RV mutex_create(void **mutex) m = calloc(1, sizeof(*m)); if (m == NULL) - return CKR_GENERAL_ERROR;; + return CKR_GENERAL_ERROR; pthread_mutex_init(m, NULL); *mutex = m; return CKR_OK; diff --git a/src/tests/unittests/pkcs15-emulator-filter.c b/src/tests/unittests/pkcs15-emulator-filter.c index 771211c8c9..9960fc5815 100644 --- a/src/tests/unittests/pkcs15-emulator-filter.c +++ b/src/tests/unittests/pkcs15-emulator-filter.c @@ -340,7 +340,7 @@ static void torture_name_and_internal(void **state) static void torture_internal_and_nonexisting(void **state) { struct _sc_pkcs15_emulators filtered_emulators; - int i, rv;; + int i, rv; scconf_list list2 = { NULL, "non" }; scconf_list list1 = { &list2, "internal" }; filtered_emulators.ccount = 0; From 5fd4568b7258b1ab971c8abb2815fb148e835abf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Feb 2025 13:56:15 +0100 Subject: [PATCH 3813/4321] minidriver: Remove trailing whitespace and clean up formaatting issues --- src/minidriver/minidriver.c | 53 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index c835f49c87..15012f3558 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1,4 +1,4 @@ -/* +/* * minidriver.c: OpenSC minidriver * * Copyright (C) 2009,2010 francois.leblanc@cev-sa.com @@ -3064,9 +3064,7 @@ static HRESULT CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, L return S_FALSE; } - - -static int +static int md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj, const u8 *pin1, size_t pin1len, @@ -3100,7 +3098,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p return rv; } - /* launch the UI in the same thread context than the parent and the function to perform in another thread context + /* launch the UI in the same thread context than the parent and the function to perform in another thread context this is the only way to display a modal dialog attached to a parent (hwndParent != 0) */ tc.hwndParent = pv->hwndParent; tc.hInstance = g_inst; @@ -3146,7 +3144,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p if (md_get_pinpad_dlg_timeout(pCardData) > 0) { tc.dwFlags |= TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER; } - + checked = !md_is_pinpad_dlg_enable_cancel(pCardData); if (checked) { tc.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED; @@ -4953,7 +4951,6 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO goto err; } } - /* Compute output size */ if ( prkey_info->modulus_length > 0) { @@ -5024,7 +5021,6 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO pInfo->cbSignedData = r; - /*revert data only for RSA (Microsoft uses the big endian version while everyone is using little endian*/ if ( prkey_info->modulus_length > 0) { for(i = 0; i < r; i++) @@ -5195,12 +5191,11 @@ DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData, MD_FUNC_RETURN(pCardData, 1, dwret); } - DWORD WINAPI CardDeriveHashOrHMAC(__in PCARD_DATA pCardData, __inout PCARD_DERIVE_KEY pAgreementInfo, __in struct md_dh_agreement* agreement, __in PWSTR szAlgorithm, - __in PBYTE pbHmacKey, __in DWORD dwHmacKeySize + __in PBYTE pbHmacKey, __in DWORD dwHmacKeySize ) { DWORD dwReturn = 0; @@ -5327,10 +5322,10 @@ DWORD WINAPI CardDeriveHashOrHMAC(__in PCARD_DATA pCardData, /* Generic function to perform hash. Could have been OpenSSL but used BCrypt* functions. BCrypt is loaded as a delay load library. The dll can be loaded into Windows XP until this code is called. Hopefully, ECC is not available in Windows XP and BCrypt functions are not called */ -DWORD HashDataWithBCrypt(__in PCARD_DATA pCardData, BCRYPT_ALG_HANDLE hAlgorithm, - PBYTE pbOuput, DWORD dwOutputSize, PBYTE pbSecret, DWORD dwSecretSize, +DWORD HashDataWithBCrypt(__in PCARD_DATA pCardData, BCRYPT_ALG_HANDLE hAlgorithm, + PBYTE pbOuput, DWORD dwOutputSize, PBYTE pbSecret, DWORD dwSecretSize, PBYTE pbData1, DWORD dwDataSize1, - PBYTE pbData2, DWORD dwDataSize2, + PBYTE pbData2, DWORD dwDataSize2, PBYTE pbData3, DWORD dwDataSize3 ) { DWORD dwReturn, dwSize, dwBufferSize; @@ -5448,22 +5443,22 @@ DWORD WINAPI DoTlsPrf(__in PCARD_DATA pCardData, dwReturn = SCARD_E_NO_MEMORY; goto cleanup; } - + for (i = 0; ipParameterList; - + if (parameters) { for (i = 0; i < parameters->cBuffers; i++) { NCryptBuffer* buffer = parameters->pBuffers + i; @@ -6011,9 +6006,9 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData, if (ppbSessionPin) *ppbSessionPin = NULL; logprintf(pCardData, 2, "standard pin verification"); /* - * TODO the use of auth_method being overridden to do session pin + * TODO the use of auth_method being overridden to do session pin * conflicts with framework-pkcs15.c use of auth_method SC_AC_CONTEXT_SPECIFIC - * for a different purpose. But needs to be reviewed + * for a different purpose. But needs to be reviewed */ if (PinId == MD_ROLE_USER_SIGN && vs->need_pin_always) { logprintf(pCardData, 7, "Setting SC_AC_CONTEXT_SPECIFIC cbPinData: %lu old auth_method: %0x auth_id:%x \n", @@ -6677,7 +6672,7 @@ DWORD WINAPI CardSetProperty(__in PCARD_DATA pCardData, logprintf(pCardData, 3, "Saved parent window (%p)\n", vs->hwndParent); MD_FUNC_RETURN(pCardData, 1, SCARD_S_SUCCESS); } - + if (wcscmp(CP_PIN_CONTEXT_STRING, wszProperty) == 0) { vs->wszPinContext = (PWSTR) pbData; logprintf(pCardData, 3, "Saved PIN context string: %S\n", (PWSTR) pbData); From 6a84142693a2164172dd7bbfe1b28d818787df57 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Feb 2025 14:17:25 +0100 Subject: [PATCH 3814/4321] Avoid use after free during WaitForSlotEvent() Fixes: #3334 --- src/pkcs11/slot.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 6647e34b46..27e4b6ba8c 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -529,6 +529,7 @@ CK_RV slot_token_removed(CK_SLOT_ID id) /* Reset relevant slot properties */ slot->slot_info.flags &= ~CKF_TOKEN_PRESENT; slot->login_user = -1; + slot->profile = NULL; pop_all_login_states(slot); if (token_was_present) From 595cd112535806804c11e3c1376fc4bb492b19c9 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 11:41:04 +0100 Subject: [PATCH 3815/4321] feat(pkcs11-tool): add support for AES CTR in decrypt_data() and encrypt_data() --- src/tools/pkcs11-tool.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 939f1bb4ff..12f191f36a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2819,6 +2819,7 @@ typedef union CK_GCM_PARAMS gcm; CK_CHACHA20_PARAMS chacha20; CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha20poly1305; + CK_AES_CTR_PARAMS ctr; } params_t; static void @@ -2860,6 +2861,16 @@ build_params( mech->pParameter = ¶ms->gcm; mech->ulParameterLen = sizeof(params->gcm); break; + case CKM_AES_CTR: + *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); + if (iv_size != 16U) { + util_fatal("Invalid IV length %zu", iv_size); + } + memcpy(¶ms->ctr.cb[0], *iv, sizeof(params->ctr.cb)); + params->ctr.ulCounterBits = 128U; + mech->pParameter = ¶ms->ctr; + mech->ulParameterLen = sizeof(params->ctr); + break; case CKM_CHACHA20: *iv = hex_string_to_byte_array(opt_iv, &iv_size, "IV"); if (iv_size != 16) { From c7a4ba9c00de73df3bcfcda2e77f073121e92b58 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 12:10:35 +0100 Subject: [PATCH 3816/4321] feat(pkcs11-tool): add test for AES CTR --- tests/test-pkcs11-tool-sym-crypt-test.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index 9956369a08..fed6dab008 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -181,6 +181,26 @@ assert $? "Fail/pkcs11-tool decrypt" cmp gcm_vector_plain.data gcm_test_plain.data >/dev/null 2>&1 assert $? "Fail, AES-GCM - wrong decrypt" +echo "=======================================================" +echo " AES-CTR" +echo " OpenSSL encrypt, pkcs11-tool decrypt" +echo " pkcs11-tool encrypt, compare to openssl encrypt" +echo "=======================================================" + +openssl enc -aes-128-ctr -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" +assert $? "Fail/OpenSSL" +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ + --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +assert $? "Fail/pkcs11-tool decrypt" +cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CTR - wrong decrypt" + +$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +assert $? "Fail/pkcs11-tool encrypt" +cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null +assert $? "Fail, AES-CTR - wrong encrypt" + echo "=======================================================" echo "Cleanup" echo "=======================================================" From 29a01966586981b8fec1ff49f1dfc6b6caec89c3 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 22:29:00 +0100 Subject: [PATCH 3817/4321] fix(pkcs11-tool): fixes for Ed448 and X448 --- src/libopensc/opensc.h | 2 ++ src/tools/pkcs11-tool.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 281392cf9c..ac09b41a4b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -228,6 +228,8 @@ extern "C" { #define MAX_FILE_SIZE 65535 +#define ED448_KEY_SIZE_BYTES 57U + struct sc_supported_algo_info { unsigned int reference; unsigned int mechanism; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 12f191f36a..6078fb4d92 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6567,9 +6567,31 @@ static int read_object(CK_SESSION_HANDLE session) ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { int nid = OBJ_obj2nid(obj); - if (nid != NID_ED25519 && nid != NID_X25519) { - util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d", - NID_ED25519, nid); + if (nid != NID_ED25519 && + nid != NID_X25519 +#if defined(EVP_PKEY_ED448) + && nid != NID_ED448 +#endif +#if defined(EVP_PKEY_X448) + && nid != NID_X448 +#endif + ) { + util_fatal("Unknown curve OID, expected NID_ED25519 (%d), NID_X25519 (%d), " +#if defined(EVP_PKEY_ED448) + "NID_ED448 (%d), " +#endif +#if defined(EVP_PKEY_X448) + "NID_X448 (%d), " +#endif + "got %d", + NID_ED25519, NID_X25519, +#if defined(EVP_PKEY_ED448) + NID_ED448, +#endif +#if defined(EVP_PKEY_X448) + NID_X448, +#endif + nid); } ASN1_OBJECT_free(obj); } else { @@ -6581,9 +6603,9 @@ static int read_object(CK_SESSION_HANDLE session) } value = getEC_POINT(session, obj, &len); - /* PKCS11 3.0 errta and 3.1 say Edwards and Montgomery + /* PKCS11 3.0 errata and 3.1 say Edwards and Montgomery * return raw byte strings, convert to OCTET string for OpenSSL - * Will asccept as OCTET STRING and BIT_STRING + * Will accept as OCTET STRING and BIT_STRING */ a = value; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)len); @@ -6603,7 +6625,7 @@ static int read_object(CK_SESSION_HANDLE session) if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) raw_pk = EVP_PKEY_ED25519; #if defined(EVP_PKEY_ED448) - else if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(448)) + else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #if defined(EVP_PKEY_X25519) From 5d15e33a374e71a0072d8b12026ad478466aedac Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 10:59:11 +0100 Subject: [PATCH 3818/4321] feat(pkcs11-tool): CKA_ALLOWED_MECHANISMS is also for public and secret keys --- src/tools/pkcs11-tool.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6078fb4d92..84792c5d19 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3434,6 +3434,10 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_pubkey_attr++; FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); @@ -4805,6 +4809,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #else util_fatal("No OpenSSL support, cannot write public key"); #endif + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(pubkey_templ[n_pubkey_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_pubkey_attr++; + } break; case CKO_SECRET_KEY: clazz = CKO_SECRET_KEY; @@ -4896,6 +4906,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(seckey_templ[n_seckey_attr], CKA_ID, opt_object_id, opt_object_id_len); n_seckey_attr++; } + if (opt_allowed_mechanisms_len > 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], + CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + n_seckey_attr++; + } break; case CKO_DATA: clazz = CKO_DATA; @@ -5976,18 +5992,16 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("none"); printf("\n"); - if (!pub) { - mechs = getALLOWED_MECHANISMS(sess, obj, &size); - if (mechs && size) { - unsigned int n; + mechs = getALLOWED_MECHANISMS(sess, obj, &size); + if (mechs && size) { + unsigned int n; - printf(" Allowed mechanisms: "); - for (n = 0; n < size; n++) { - printf("%s%s", (n != 0 ? "," : ""), + printf(" Allowed mechanisms: "); + for (n = 0; n < size; n++) { + printf("%s%s", (n != 0 ? "," : ""), p11_mechanism_to_name(mechs[n])); - } - printf("\n"); } + printf("\n"); } if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { printf(" Unique ID: %s\n", unique_id); From d5977555889db0f2ea931ae7d25001e94418f1d4 Mon Sep 17 00:00:00 2001 From: Alexandre Gonzalo Date: Wed, 12 Feb 2025 16:47:33 +0100 Subject: [PATCH 3819/4321] feat(pkcs11-tool): allow EC keys to have CKA_ENCRYPT or CKA_DECRYPT --- src/tools/pkcs11-tool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 84792c5d19..634f254d1a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3268,6 +3268,13 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } + if (opt_key_usage_default || opt_key_usage_decrypt) { + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ENCRYPT, &_true, sizeof(_true)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DECRYPT, &_true, sizeof(_true)); + n_privkey_attr++; + } + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ec_curve_infos[ii].ec_params, ec_curve_infos[ii].ec_params_size); n_pubkey_attr++; FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); From 5d02bed3d9dc43d6170fbc8dfb7821373f9a4c9d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 7 Feb 2025 23:11:49 +0200 Subject: [PATCH 3820/4321] Cleanup Cygwin handling Signed-off-by: Raul Metsma --- configure.ac | 7 +------ src/libopensc/internal-winscard.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index b7078f533e..b29d48263c 100644 --- a/configure.ac +++ b/configure.ac @@ -82,7 +82,6 @@ fi dnl Check for some target-specific stuff test -z "${WIN32}" && WIN32="no" -test -z "${CYGWIN}" && CYGWIN="no" case "${host}" in *-*-solaris*) @@ -95,17 +94,14 @@ case "${host}" in WIN_LIBPREFIX="lib" ;; *-cygwin*) + CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" AC_MSG_CHECKING([cygwin mode to use]) - CYGWIN="yes" if test "${with_cygwin_native}" = "yes"; then AC_MSG_RESULT([Using native win32]) - CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" - #CFLAGS="${CFLAGS} -mno-cygwin" deprecated/removed flag WIN32="yes" else AC_MSG_RESULT([Using cygwin]) WIN_LIBPREFIX="cyg" - AC_DEFINE([USE_CYGWIN], [1], [Define if you are on Cygwin]) fi ;; esac @@ -1137,7 +1133,6 @@ AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"]) AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"]) AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) -AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"]) AM_CONDITIONAL([ENABLE_MINIDRIVER], [test "${enable_minidriver}" = "yes"]) AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidriver_ca}" = "yes"]) AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"]) diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index 00c004e03c..2aa250b857 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -143,7 +143,7 @@ typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST; #ifndef PCSC_API #if defined(_WIN32) #define PCSC_API WINAPI -#elif defined(USE_CYGWIN) +#elif defined(__CYGWIN__) #define PCSC_API __stdcall #else #define PCSC_API From f923dc712516551ce0f17496cfa220b1536f4a6f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 1 Mar 2025 01:27:13 +0100 Subject: [PATCH 3821/4321] CI: updated ubuntu runner sets up polkit rules for testing on Github runner fixes https://github.com/OpenSC/OpenSC/issues/3349 --- .github/restart-pcscd.sh | 7 +++++++ .github/test-oseid.sh | 5 +++++ .github/workflows/linux.yml | 24 ++++++++++++------------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/restart-pcscd.sh b/.github/restart-pcscd.sh index b40cb02794..d6c3d4dd5d 100644 --- a/.github/restart-pcscd.sh +++ b/.github/restart-pcscd.sh @@ -16,6 +16,13 @@ function pcscd_cleanup { trap pcscd_cleanup EXIT + +# set up polkit rule to let user "runner" access PC/SC remotely for testing +if [ ! -f "/usr/share/polkit-1/rules.d/03-polkit-pcscd.rules" ]; then + echo 'polkit.addRule(function(action, subject) { if ((action.id == "org.debian.pcsc-lite.access_pcsc" || action.id == "org.debian.pcsc-lite.access_card") && subject.user == "runner") { return polkit.Result.YES; } });' > /usr/share/polkit-1/rules.d/03-polkit-pcscd.rules; +fi + + # stop the pcscd service and run it from console to see possible errors if which systemctl && systemctl is-system-running; then sudo systemctl stop pcscd.service pcscd.socket diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index c5a5eba27f..a56a2721fd 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -28,6 +28,11 @@ sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf cat /etc/reader.conf.d/reader.conf popd +# set up polkit rule to let user "runner" access PC/SC remotely for testing +if [ ! -f "/usr/share/polkit-1/rules.d/03-polkit-pcscd.rules" ]; then + echo 'polkit.addRule(function(action, subject) { if ((action.id == "org.debian.pcsc-lite.access_pcsc" || action.id == "org.debian.pcsc-lite.access_card") && subject.user == "runner") { return polkit.Result.YES; } });' > /usr/share/polkit-1/rules.d/03-polkit-pcscd.rules; +fi + sudo /etc/init.d/pcscd restart # Needed for tput to not report warnings diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 19e18ebccb..b03f2b8a15 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -32,7 +32,7 @@ env: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 @@ -107,7 +107,7 @@ jobs: - run: .github/build.sh no-openssl valgrind build-ix86: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 @@ -150,7 +150,7 @@ jobs: win32/Output/OpenSC*.exe build-piv-sm: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 @@ -175,7 +175,7 @@ jobs: key: ${{ runner.os }}-piv-sm-${{ github.sha }} test-piv: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -200,7 +200,7 @@ jobs: - run: .github/test-piv.sh valgrind test-piv-sm: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build-piv-sm] steps: - uses: actions/checkout@v4 @@ -225,7 +225,7 @@ jobs: - run: .github/test-piv.sh valgrind test-isoapplet-v0: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -250,7 +250,7 @@ jobs: - run: .github/test-isoapplet.sh v0 valgrind test-isoapplet-v1: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -275,7 +275,7 @@ jobs: - run: .github/test-isoapplet.sh v1 valgrind test-gidsapplet: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -300,7 +300,7 @@ jobs: - run: .github/test-gidsapplet.sh valgrind test-openpgp: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -325,7 +325,7 @@ jobs: - run: .github/test-openpgp.sh valgrind build-clang-tidy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -343,7 +343,7 @@ jobs: - run: .github/build.sh clang-tidy test-cac: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 @@ -362,7 +362,7 @@ jobs: - run: .github/test-cac.sh valgrind test-oseid: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [build] steps: - uses: actions/checkout@v4 From 8d29bb6722d6d1aaafecd046a50c6dbddcd4ae05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 5 Mar 2025 15:05:02 +0100 Subject: [PATCH 3822/4321] Do not add CKA_ENCRYPT or CKA_DECRYPT for EC keys by default --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 634f254d1a..bf72a0dfa0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3268,7 +3268,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } - if (opt_key_usage_default || opt_key_usage_decrypt) { + if (opt_key_usage_decrypt) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ENCRYPT, &_true, sizeof(_true)); n_pubkey_attr++; FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DECRYPT, &_true, sizeof(_true)); From 1809f244362d94899290a4891b900467bface095 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Mar 2025 11:35:11 +0100 Subject: [PATCH 3823/4321] Add option to disable integration tests and do that with valgrind Alternative solution to #3360 Signed-off-by: Jakub Jelen --- .github/build.sh | 2 +- Makefile.am | 6 +++++- configure.ac | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 3105c94446..da380fb7a2 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -62,7 +62,7 @@ else CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-piv-sm" fi if [ "$1" == "valgrind" -o "$2" == "valgrind" ]; then - CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-notify --enable-valgrind" + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-notify --enable-valgrind --disable-integration-tests" fi if [ "$1" == "no-shared" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-shared" diff --git a/Makefile.am b/Makefile.am index a087de1d75..a05b28b757 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,11 @@ EXTRA_DIST = Makefile.mak DISTCHECK_CONFIGURE_FLAGS = --with-completiondir=/tmp -SUBDIRS = etc src win32 doc MacOSX tests +SUBDIRS = etc src win32 doc MacOSX + +if ENABLE_INTEGRATION_TESTS +SUBDIRS += tests +endif dist_noinst_SCRIPTS = bootstrap bootstrap.ci dist_noinst_DATA = README \ diff --git a/configure.ac b/configure.ac index b29d48263c..895f621c27 100644 --- a/configure.ac +++ b/configure.ac @@ -282,6 +282,13 @@ AC_ARG_ENABLE( [enable_tests="yes"] ) +AC_ARG_ENABLE( + [integration_tests], + [AS_HELP_STRING([--enable-integration-tests],[enable integration tests with software token @<:@enabled@:>@])], + , + [enable_integration_tests="yes"] +) + AC_ARG_ENABLE( [dnie-ui], [AS_HELP_STRING([--enable-dnie-ui],[enable use of external user interface program to request DNIe pin@<:@disabled@:>@])], @@ -1132,6 +1139,7 @@ AM_CONDITIONAL([ENABLE_CRYPTOTOKENKIT], [test "${enable_cryptotokenkit}" = "yes" AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"]) AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"]) AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) +AM_CONDITIONAL([ENABLE_INTEGRATION_TESTS], [test "${enable_integration_tests}" = "yes"]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([ENABLE_MINIDRIVER], [test "${enable_minidriver}" = "yes"]) AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidriver_ca}" = "yes"]) @@ -1219,6 +1227,7 @@ XSL stylesheets: ${xslstylesheetsdir} man support: ${enable_man} doc support: ${enable_doc} tests: ${enable_tests} +integration tests: ${enable_integration_tests} thread locking support: ${enable_thread_locking} zlib support: ${enable_zlib} readline support: ${enable_readline} From 91d857b307bccdf59d546d5dcd40711ce8ac69b3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 25 Feb 2025 16:16:09 -0600 Subject: [PATCH 3824/4321] Configure.ac - enable-piv-sm now test for enable_sm and enable-openssl card-piv.c now relies on configure tests. --enable-piv-sm can also use LibreSSL Changes to be committed: modified: configure.ac modified: src/libopensc/card-piv.c --- configure.ac | 6 +++++- src/libopensc/card-piv.c | 10 +++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 895f621c27..65b8095ebe 100644 --- a/configure.ac +++ b/configure.ac @@ -864,7 +864,11 @@ else fi if test "${enable_piv_sm}" = "yes"; then - AC_DEFINE([ENABLE_PIV_SM], [1], [Enable PIV SM]) + if test "${enable_sm}" = "yes" -a "${enable_openssl}" = "yes" ; then + AC_DEFINE([ENABLE_PIV_SM], [1], [Enable PIV SM]) + else + AC_MSG_ERROR([ENABLE_PIV_SM requires ENABLE_SM and ENABLE_OPENSSL]) + fi fi if test "${enable_openct}" = "yes"; then diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 50bd73dedb..9818847619 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -49,18 +49,14 @@ #endif #endif -/* 800-73-4 SM and VCI need: ECC, SM and real OpenSSL >= 1.1 */ -#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) && !defined(OPENSSL_NO_EC) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L -#else -#undef ENABLE_PIV_SM -#endif +#include "internal.h" -#ifdef ENABLE_PIV_SM +/* 800-73-4 SM and VCI need: ECC, SM and OpenSSL or LibreSSL */ +#if defined(ENABLE_PIV_SM) #include #include "compression.h" #endif -#include "internal.h" #include "asn1.h" #include "cardctl.h" #include "simpletlv.h" From cfe6195b0fd9d14b5d969f95bd4aa673846155bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 14 Mar 2025 16:22:26 +0100 Subject: [PATCH 3825/4321] Fix memory leaks in piv-tool key generation Thanks OSS-Fuzz https://issues.oss-fuzz.com/issues/397209407 --- src/tools/piv-tool.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 9c5218a8b8..ec23b4b1a4 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -374,8 +374,8 @@ static int gen_key(const char * key_info) fprintf(stderr, "gen_key failed %d\n", r); free(keydata.pubkey); free(keydata.exponent); - EVP_PKEY_free(evpkey); #if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_PKEY_free(evpkey); RSA_free(newkey); #endif return -1; @@ -389,8 +389,8 @@ static int gen_key(const char * key_info) keydata.exponent_len = 0; if (!newkey_n || !newkey_e) { sc_log_openssl(ctx); - EVP_PKEY_free(evpkey); #if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_PKEY_free(evpkey); RSA_free(newkey); #endif fprintf(stderr, "conversion or key params failed %d\n", r); @@ -458,7 +458,13 @@ static int gen_key(const char * key_info) fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n"); return -1; #else + if (!keydata.ecpoint) { + fprintf(stderr, "gen_key failed %d\n", r); + return -1; + } evpkey = EVP_PKEY_new_raw_public_key(nid, NULL, keydata.ecpoint, keydata.ecpoint_len); + free(keydata.ecpoint); + keydata.ecpoint_len = 0; if (!evpkey) { sc_log_openssl(ctx); fprintf(stderr, "gen key failed ti copy 25519 pubkey\n"); @@ -492,7 +498,9 @@ static int gen_key(const char * key_info) if (!keydata.ecpoint) { fprintf(stderr, "gen_key failed %d\n", r); +#if OPENSSL_VERSION_NUMBER < 0x30000000L EVP_PKEY_free(evpkey); +#endif return -1; } @@ -503,31 +511,33 @@ static int gen_key(const char * key_info) /* PIV returns 04||x||y and x and y are the same size */ i = (int)(keydata.ecpoint_len - 1) / 2; x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); - y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL) ; + y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL); + free(keydata.ecpoint); + keydata.ecpoint_len = 0; if (!x || !y) { sc_log_openssl(ctx); - free(keydata.ecpoint); - keydata.ecpoint_len = 0; BN_free(x); BN_free(y); - EVP_PKEY_free(evpkey); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_PKEY_free(evpkey); +#endif return -1; } r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); - free(keydata.ecpoint); - keydata.ecpoint_len = 0; BN_free(x); BN_free(y); if (r == 0) { sc_log_openssl(ctx); fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); - EVP_PKEY_free(evpkey); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EVP_PKEY_free(evpkey); +#endif return -1; } #if OPENSSL_VERSION_NUMBER < 0x30000000L From a34fddf7d627e761b7dc1cfd1664b1f6d7d14f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 6 Mar 2025 14:45:50 +0100 Subject: [PATCH 3826/4321] Remove doubled code in tests --- tests/test-pkcs11-tool-test-threads.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index 032b01fa16..0dd618eb5f 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -6,17 +6,6 @@ source $SOURCE_PATH/tests/common.sh # Test our PKCS #11 module here P11LIB="../src/pkcs11/.libs/opensc-pkcs11.so" -OPENSC_TOOL="../src/tools/opensc-tool" -echo "check for opensc-tool" -if [[ -f $OPENSC_TOOL ]] ; then -echo "trying opensc-tool -a" - $OPENSC_TOOL -a - if [[ "$?" -ne "0" ]] ; then - echo "No token found, skipping Test pkcs11 threads " - exit 77 - fi -fi - echo "=======================================================" echo "Test pkcs11 threads IN " echo "=======================================================" From 8f183af09c433a7cb31a4f43a8f0bc51c12da221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 7 Mar 2025 14:01:03 +0100 Subject: [PATCH 3827/4321] Add kryoptic and softokn modules into tests/ --- tests/README.md | 18 ++ tests/common.sh | 80 +++--- tests/setup-kryoptic.sh | 40 +++ tests/setup-softhsm.sh | 42 +++ tests/setup-softokn.sh | 45 ++++ tests/softhsm_ref.json | 26 +- tests/test-p11test.sh | 8 +- tests/test-pkcs11-tool-allowed-mechanisms.sh | 27 +- tests/test-pkcs11-tool-import.sh | 28 +- tests/test-pkcs11-tool-sign-verify.sh | 258 ++++++++++--------- tests/test-pkcs11-tool-sym-crypt-test.sh | 16 +- tests/test-pkcs11-tool-test-threads.sh | 12 +- tests/test-pkcs11-tool-test.sh | 32 ++- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 18 +- 14 files changed, 442 insertions(+), 208 deletions(-) create mode 100644 tests/README.md create mode 100755 tests/setup-kryoptic.sh create mode 100755 tests/setup-softhsm.sh create mode 100644 tests/setup-softokn.sh diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..d35bd784df --- /dev/null +++ b/tests/README.md @@ -0,0 +1,18 @@ +# OpenSC test scripts + +## The pkcs11-tool tests + +Some of the tests support running with several PKCS#11 modules: + +- SoftHSM, +- Kyoptic, +- and Softokn. + +The test can be run with specified token `softhsm | kryoptic | softokn`: + +```bash +./test-pkcs11-tool-test.sh # default: softhsm +./test-pkcs11-tool-test.sh softhsm +./test-pkcs11-tool-test.sh kryoptic +./test-pkcs11-tool-sign-verify.sh softokn +``` diff --git a/tests/common.sh b/tests/common.sh index 733a93efb9..90b1c08947 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -2,31 +2,26 @@ ## from OpenSC/src/tests/p11test/runtest.sh BUILD_PATH=${BUILD_PATH:-..} +TOKENTYPE=$1 + # run valgrind with all the switches we are interested in if [ -n "$VALGRIND" -a -n "$LOG_COMPILER" ]; then VALGRIND="$LOG_COMPILER" fi -SOPIN="12345678" -PIN="123456" +export SOPIN="12345678" +export PIN="123456" PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" -softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ - /usr/lib/softhsm/libsofthsm2.so - /usr/lib64/pkcs11/libsofthsm2.so \ - /usr/lib/i386-linux-gnu/softhsm/libsofthsm2.so \ - /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" - -for LIB in $softhsm_paths; do - echo "Testing $LIB" - if [[ -f $LIB ]]; then - P11LIB=$LIB - echo "Setting P11LIB=$LIB" - break - fi -done -if [[ -z "$P11LIB" ]]; then - echo "Warning: Could not find the softhsm pkcs11 module" +if [ "${TOKENTYPE}" == "softhsm" ]; then + source "${BUILD_PATH}/tests/setup-softhsm.sh" +elif [ "${TOKENTYPE}" == "softokn" ]; then + source "${BUILD_PATH}/tests/setup-softokn.sh" +elif [ "${TOKENTYPE}" == "kryoptic" ]; then + source "${BUILD_PATH}/tests/setup-kryoptic.sh" +else + echo "Unknown token type: $1" + exit 1 fi ERRORS=0 @@ -44,16 +39,14 @@ function generate_key() { echo "Generate $TYPE key (ID=$ID)" # Generate key pair - $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --module="$P11LIB" --label="$LABEL" --id=$ID + $PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type="$TYPE" --label="$LABEL" --id=$ID if [[ "$?" -ne "0" ]]; then echo "Couldn't generate $TYPE key pair" return 1 fi # Extract public key from the card - $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ - --module="$P11LIB" + $PKCS11_TOOL "${PUB_ARGS[@]}" --read-object --id $ID --type pubkey --output-file $ID.der if [[ "$?" -ne "0" ]]; then echo "Couldn't read generated $TYPE public key" return 1 @@ -70,46 +63,31 @@ function generate_key() { rm $ID.der } -function softhsm_initialize() { - echo "directories.tokendir = $(realpath .tokens)" > .softhsm2.conf - if [ -d ".tokens" ]; then - rm -rf ".tokens" - fi - mkdir ".tokens" - export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") - # Init token - - softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" -} - function card_setup() { - softhsm_initialize + initialize_token - # Generate 1024b RSA Key pair - generate_key "RSA:1024" "01" "RSA_auth" || return 1 # Generate 2048b RSA Key pair - generate_key "RSA:2048" "02" "RSA2048" || return 1 + generate_key "RSA:2048" "01" "RSA2048" || return 1 + # Generate 4096b RSA Key pair + generate_key "RSA:4096" "02" "RSA4096" || return 1 # Generate 256b ECC Key pair generate_key "EC:secp256r1" "03" "ECC_auth" || return 1 # Generate 521b ECC Key pair generate_key "EC:secp521r1" "04" "ECC521" || return 1 - # Generate an HMAC:SHA256 key - $PKCS11_TOOL --keygen --key-type="GENERIC:64" --login --pin=$PIN \ - --module="$P11LIB" --label="HMAC-SHA256" --id="05" - if [[ "$?" -ne "0" ]]; then - echo "Couldn't generate GENERIC key" - return 1 - fi -} -function softhsm_cleanup() { - rm .softhsm2.conf - rm -rf ".tokens" - sleep 1 + if [[ ${TOKENTYPE} == "softhsm" ]]; then + # Generate an HMAC:SHA256 key + $PKCS11_TOOL --keygen --key-type="GENERIC:64" --login --pin=$PIN \ + --module="$P11LIB" --label="HMAC-SHA256" --id="05" + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate GENERIC key" + return 1 + fi + fi } function card_cleanup() { - softhsm_cleanup + token_cleanup rm 0{1,2,3,4}.pub sleep 1 } diff --git a/tests/setup-kryoptic.sh b/tests/setup-kryoptic.sh new file mode 100755 index 0000000000..b4dfd9c0dd --- /dev/null +++ b/tests/setup-kryoptic.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# set paths +KRYOPTIC_PWD="$BUILD_PATH/kryoptic/target/debug/libkryoptic_pkcs11.so" +if test -f "$KRYOPTIC_PWD" ; then + echo "Using kryoptic path $KRYOPTIC_PWD" + P11LIB="$KRYOPTIC_PWD" +else + echo "Kryoptic not found" + exit 0 +fi + +function initialize_token() { + TMPPDIR="$BUILD_PATH/kryoptic/tmp" + export TOKDIR="$TMPPDIR/tokens" + if [ -d "${TMPPDIR}" ]; then + rm -fr "${TMPPDIR}" + fi + mkdir -p "${TMPPDIR}" + mkdir "${TOKDIR}" + + export KRYOPTIC_CONF="${KRYOPTIC_CONF:-$TOKDIR/kryoptic.sql}" + export TOKENCONFIGVARS="export KRYOPTIC_CONF=$TOKDIR/kryoptic.sql" + export TOKENLABEL="Kryoptic Token" + + # init token + $PKCS11_TOOL --module "${P11LIB}" --init-token \ + --label "${TOKENLABEL}" --so-pin "${PIN}" + # set pin + $PKCS11_TOOL --module "${P11LIB}" --so-pin "${PIN}" \ + --login --login-type so --init-pin --pin "${PIN}" + + export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") + export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PIN}") +} + +function token_cleanup() { + rm -fr "${TMPPDIR}" + sleep 1 +} diff --git a/tests/setup-softhsm.sh b/tests/setup-softhsm.sh new file mode 100755 index 0000000000..c54c656ee8 --- /dev/null +++ b/tests/setup-softhsm.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +SOURCE_PATH=${SOURCE_PATH:-..} + +softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ + /usr/lib/softhsm/libsofthsm2.so + /usr/lib64/pkcs11/libsofthsm2.so \ + /usr/lib/i386-linux-gnu/softhsm/libsofthsm2.so \ + /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" + +for LIB in $softhsm_paths; do + echo "Testing $LIB" + if [[ -f $LIB ]]; then + export P11LIB=$LIB + echo "Setting P11LIB=$LIB" + break + fi +done +if [[ -z "$P11LIB" ]]; then + echo "Warning: Could not find the softhsm pkcs11 module" +fi + +function initialize_token() { + echo "directories.tokendir = $(realpath .tokens)" > .softhsm2.conf + if [ -d ".tokens" ]; then + rm -rf ".tokens" + fi + mkdir ".tokens" + export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") + # Init token + + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" + + export PUB_ARGS=("--module=${P11LIB}") + export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PIN}") +} + +function token_cleanup() { + rm .softhsm2.conf + rm -rf ".tokens" + sleep 1 +} diff --git a/tests/setup-softokn.sh b/tests/setup-softokn.sh new file mode 100644 index 0000000000..e77a5723de --- /dev/null +++ b/tests/setup-softokn.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +softokn_paths=( + "/usr/lib64/libsoftokn3.so" # Fedora + "/usr/lib/x86_64-linux-gnu/libsoftokn3.so" # Ubuntu +) +P11LIB="" +for lib in "${softokn_paths[@]}"; do + if [ -f "$lib" ]; then + echo "Using softokn path $lib" + P11LIB="$lib" + break + fi +done +if [ -z "$P11LIB" ]; then + echo "Unable to find softokn PKCS#11 library" + exit 1 +fi + +function initialize_token() { + TMPPDIR="$BUILD_PATH/softokn" + export TOKDIR="$TMPPDIR/tokens" + if [ -d "${TMPPDIR}" ]; then + rm -fr "${TMPPDIR}" + fi + mkdir "${TMPPDIR}" + mkdir "${TOKDIR}" + + TOKENLABEL="NSS Certificate DB" + PINVALUE="12345678" + PINFILE="${TMPPDIR}/pinfile.txt" + echo ${PINVALUE} > "${PINFILE}" + + certutil -N -d $TOKDIR -f $PINFILE + + export NSS_LIB_PARAMS=configDir=$TMPPDIR/tokens + export PKCS11_TOOL="pkcs11-tool" + export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") + export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PINVALUE}") +} + +function token_cleanup() { + rm -fr "${TMPPDIR}" + sleep 1 +} diff --git a/tests/softhsm_ref.json b/tests/softhsm_ref.json index de27feb6a3..03e7d20612 100644 --- a/tests/softhsm_ref.json +++ b/tests/softhsm_ref.json @@ -642,9 +642,9 @@ ], [ "01", - "RSA_auth", + "RSA2048", "RSA", - "1024", + "2048", "", "YES", "YES", @@ -658,9 +658,9 @@ ], [ "02", - "RSA2048", + "RSA4096", "RSA", - "2048", + "4096", "", "YES", "YES", @@ -860,6 +860,15 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -959,6 +968,15 @@ "YES", "" ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], [ "01", "SHA512_RSA_PKCS_PSS", diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index d5841aa66e..7f5e031082 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -1,7 +1,7 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +source $SOURCE_PATH/tests/common.sh softhsm echo "=======================================================" echo "Setup SoftHSM" @@ -11,8 +11,10 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi -# The Ubuntu has old softhsm version not supporting this feature -grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +if [ "${TOKENTYPE}" == "softhsm" ]; then + # The Ubuntu has old softhsm version not supporting this feature + grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +fi card_setup assert $? "Failed to set up card" diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index f9bb0dabd4..44a0b7f17e 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -1,19 +1,32 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "softokn" ]; then + echo "Generate key-pair with CKA_ALLOWED_MECHANISMS not supported" + exit 1 +elif [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNING: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The $TOKENTYPE is not installed. Can not run this test" exit 77; fi -# The Ubuntu has old softhsm version not supporting this feature -grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -softhsm_initialize +if [ "${TOKENTYPE}" == "softhsm" ]; then + # The Ubuntu has old softhsm version not supporting this feature + grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +fi + +initialize_token echo "=======================================================" echo "Generate key-pair with CKA_ALLOWED_MECHANISMS" @@ -46,7 +59,7 @@ rm -f data{,.sig} echo "=======================================================" echo "Cleanup" echo "=======================================================" -softhsm_cleanup +token_cleanup rm objects.list sign.log diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index 161f348f7a..530dacdbcb 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -1,13 +1,20 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNING: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The $TOKENTYPE is not installed. Can not run this test" exit 77; fi card_setup @@ -21,23 +28,24 @@ for KEYTYPE in "RSA" "EC"; do echo "Generate and import $KEYTYPE keys" echo "=======================================================" ID="0100" - OPTS="" + OPTS="-pkeyopt rsa_keygen_bits:2048" if [ "$KEYTYPE" == "EC" ]; then ID="0200" - OPTS="-pkeyopt ec_paramgen_curve:P-521" + OPTS="-pkeyopt ec_paramgen_curve:P-256" fi openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS + assert $? "Failed to generate private $KEYTYPE key" - $PKCS11_TOOL --write-object "${KEYTYPE}_private.der" --id "$ID" --type privkey \ - --label "$KEYTYPE" -p "$PIN" --module "$P11LIB" + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object "${KEYTYPE}_private.der" --id "$ID" \ + --type privkey --label "$KEYTYPE" assert $? "Failed to write private $KEYTYPE key" + echo "Private key written" openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER assert $? "Failed to convert private $KEYTYPE key to public" - $PKCS11_TOOL --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" \ - -p $PIN --module $P11LIB + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" assert $? "Failed to write public $KEYTYPE key" - # certificate import already tested in all other tests + echo "Public key written" rm "${KEYTYPE}_private.der" "${KEYTYPE}_public.der" done diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 472943de23..ce1fe82b6d 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -1,19 +1,26 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNING: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The $TOKENTYPE is not installed. Can not run this test" exit 77; fi card_setup assert $? "Failed to set up card" -# get informaation about OS +# get information about OS source /etc/os-release || true echo "=======================================================" @@ -38,11 +45,12 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do echo "=======================================================" echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" echo "=======================================================" - $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ - --input-file data --output-file data.sig + # pkcs11-tool signature + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD --input-file data --output-file data.sig assert $? "Failed to Sign data" # OpenSSL verification + echo -n "Verification by OpenSSL: " if [[ -z $HASH ]]; then openssl rsautl -verify -inkey $SIGN_KEY.pub -in data.sig -pubin # pkeyutl does not work with libressl @@ -58,102 +66,114 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do fi # pkcs11-tool verification - $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ - --input-file data --signature-file data.sig + echo "Verification by pkcs11-tool:" + $PKCS11_TOOL "${PUB_ARGS[@]}" --id $SIGN_KEY --verify -m $METHOD \ + --input-file data --signature-file data.sig assert $? "Failed to Verify signature using pkcs11-tool" rm data.sig - METHOD="$METHOD-PSS" - # -PSS methods should work on data > 512 bytes; generate data: - head -c 1024 data - if [[ "$HASH" == "SHA512" ]]; then - continue; # This one is broken - fi - # Ubuntu SoftHSM version does not support RSA-PSS - grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && continue + if [ "${TOKENTYPE}" != "softokn" ]; then + # RSA-PKCS-OAEP decryption by pkcs11-tool returns + # error: PKCS11 function C_DecryptUpdate failed: rv = CKR_OPERATION_NOT_INITIALIZED (0x91) + METHOD="$METHOD-PSS" + # -PSS methods should work on data > 512 bytes; generate data: + head -c 1024 data - echo - echo "=======================================================" - echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" - echo "=======================================================" - if [[ -z $HASH ]]; then - # hashing is done outside of the module. We choose here SHA256 - openssl dgst -binary -sha256 data > data.hash - HASH_ALGORITM="--hash-algorithm=SHA256" - VERIFY_DGEST="-sha256" - VERIFY_OPTS="-sigopt rsa_mgf1_md:sha256" - else - # hashing is done inside of the module - cp data data.hash - HASH_ALGORITM="" - VERIFY_DGEST="-${HASH,,*}" - VERIFY_OPTS="-sigopt rsa_mgf1_md:${HASH,,*}" - fi - $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ - $HASH_ALGORITM --salt-len=-1 \ - --input-file data.hash --output-file data.sig - assert $? "Failed to Sign data" + if [ "${TOKENTYPE}" == "softhsm" ]; then + if [[ "$HASH" == "SHA512" ]]; then + continue; # This one is broken + fi + # Ubuntu SoftHSM version does not support RSA-PSS + grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && continue + fi - # OpenSSL verification - openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ - -sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ - -signature data.sig data - if [[ "$RETOSSL" == "0" ]]; then - assert $? "Failed to Verify signature using openssl" - elif [[ "$?" == "0" ]]; then - assert 1 "Unexpectedly Verified signature using OpenSSL" - fi + echo + echo "=======================================================" + echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" + echo "=======================================================" + if [[ -z $HASH ]]; then + # hashing is done outside of the module. We choose here SHA256 + openssl dgst -binary -sha256 data > data.hash + HASH_ALGORITM="--hash-algorithm=SHA256" + VERIFY_DGEST="-sha256" + VERIFY_OPTS="-sigopt rsa_mgf1_md:sha256" + else + # hashing is done inside of the module + cp data data.hash + HASH_ALGORITM="" + VERIFY_DGEST="-${HASH,,*}" + VERIFY_OPTS="-sigopt rsa_mgf1_md:${HASH,,*}" + fi + # pkcs11-tool signature + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD $HASH_ALGORITM --salt-len=-1 \ + --input-file data.hash --output-file data.sig + assert $? "Failed to Sign data" - # pkcs11-tool verification - $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ - $HASH_ALGORITM --salt-len=-1 \ - --input-file data.hash --signature-file data.sig - assert $? "Failed to Verify signature using pkcs11-tool" - rm data.{sig,hash} - done + # OpenSSL verification + echo -n "Verification by OpenSSL: " + openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ + -sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ + -signature data.sig data + if [[ "$RETOSSL" == "0" ]]; then + assert $? "Failed to Verify signature using openssl" + elif [[ "$?" == "0" ]]; then + assert 1 "Unexpectedly Verified signature using OpenSSL" + fi - METHOD="RSA-PKCS-OAEP" - # RSA-PKCS-OAEP works only on small data (input length <= k-2-2hLen) - # generate small data: - head -c 64 data - for ENC_KEY in "01" "02"; do - # SoftHSM only supports SHA1 for both hashAlg and mgf - if [[ -z $HASH ]]; then - continue - elif [[ "$HASH" != "SHA1" ]]; then - continue + # pkcs11-tool verification + echo "Verification by pkcs11-tool:" + $PKCS11_TOOL "${PUB_ARGS[@]}" --id $SIGN_KEY --verify -m $METHOD \ + $HASH_ALGORITM --salt-len=-1 \ + --input-file data.hash --signature-file data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.{sig,hash} fi - echo - echo "=======================================================" - echo "$METHOD: Encrypt & Decrypt (KEY $ENC_KEY)" - echo "=======================================================" - # OpenSSL Encryption - # pkeyutl does not work with libressl - openssl rsautl -encrypt -oaep -inkey $ENC_KEY.pub -in data -pubin -out data.crypt - assert $? "Failed to encrypt data using OpenSSL" - $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ - -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ - --input-file data.crypt --output-file data.decrypted - assert $? "Failed to decrypt data using pkcs11-tool" - diff data{,.decrypted} - assert $? "The decrypted data do not match the original" - rm data.{crypt,decrypted} + done - $PKCS11_TOOL --id $ENC_KEY --encrypt -p $PIN --module $P11LIB \ - -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ - --input-file data --output-file data.crypt - assert $? "Failed to encrypt data using pkcs11-tool" - # It would be better to decrypt with OpenSSL but we can't read the - # private key with the pkcs11-tool (yet) - $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ - -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ - --input-file data.crypt --output-file data.decrypted - assert $? "Failed to decrypt data using pkcs11-tool" - diff data{,.decrypted} - assert $? "The decrypted data do not match the original" - rm data.{crypt,decrypted} - done + if [ "${TOKENTYPE}" != "softokn" ]; then + METHOD="RSA-PKCS-OAEP" + # RSA-PKCS-OAEP works only on small data (input length <= k-2-2hLen) + # generate small data: + head -c 64 data + for ENC_KEY in "01" "02"; do + # SoftHSM only supports SHA1 for both hashAlg and mgf + if [[ -z $HASH ]]; then + continue + elif [[ "$HASH" != "SHA1" ]]; then + continue + fi + echo + echo "=======================================================" + echo "$METHOD: Encrypt & Decrypt (KEY $ENC_KEY)" + echo "=======================================================" + # OpenSSL Encryption + # pkeyutl does not work with libressl + openssl rsautl -encrypt -oaep -inkey $ENC_KEY.pub -in data -pubin -out data.crypt + assert $? "Failed to encrypt data using OpenSSL" + $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data.crypt --output-file data.decrypted + assert $? "Failed to decrypt data using pkcs11-tool" + diff data{,.decrypted} + assert $? "The decrypted data do not match the original" + rm data.{crypt,decrypted} + + $PKCS11_TOOL --id $ENC_KEY --encrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data --output-file data.crypt + assert $? "Failed to encrypt data using pkcs11-tool" + # It would be better to decrypt with OpenSSL but we can't read the + # private key with the pkcs11-tool (yet) + $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN --module $P11LIB \ + -m $METHOD --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" \ + --input-file data.crypt --output-file data.decrypted + assert $? "Failed to decrypt data using pkcs11-tool" + diff data{,.decrypted} + assert $? "The decrypted data do not match the original" + rm data.{crypt,decrypted} + done + fi # Skip hashed algorithms (do not support encryption & decryption) if [[ ! -z "$HASH" ]]; then @@ -174,13 +194,13 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do #openssl pkeyutl -encrypt -inkey $ENC_KEY.pub -in data \ # -pubin -out data.crypt assert $? "Failed to encrypt data using OpenSSL" - $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN -m $METHOD \ - --module $P11LIB --input-file data.crypt > data.decrypted + # pkcs11-tool Decryption + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ENC_KEY --decrypt -m $METHOD \ + --input-file data.crypt > data.decrypted + assert $? "Failed to Decrypt data" diff data{,.decrypted} assert $? "The decrypted data do not match the original" rm data.{crypt,decrypted} - - # TODO pkcs11-tool encryption not supported done done @@ -197,48 +217,52 @@ for SIGN_KEY in "03" "04"; do echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" echo "=======================================================" openssl dgst -binary -sha256 data > data.hash - $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD \ --input-file data.hash --output-file data.sig assert $? "Failed to Sign data" - $PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD \ --input-file data.hash --output-file data.sig.openssl \ --signature-format openssl assert $? "Failed to Sign data into OpenSSL format" # OpenSSL verification + echo -n "Verification by OpenSSL: " openssl dgst -keyform PEM -verify $SIGN_KEY.pub -sha256 \ -signature data.sig.openssl data assert $? "Failed to Verify signature using OpenSSL" # pkcs11-tool verification - $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ + echo "Verification by pkcs11-tool:" + $PKCS11_TOOL "${PUB_ARGS[@]}" --id $SIGN_KEY --verify -m $METHOD \ --input-file data.hash --signature-file data.sig assert $? "Failed to Verify signature using pkcs11-tool" rm data.sig{,.openssl} data.hash done -echo "=======================================================" -echo "Test GENERIC keys" -echo "=======================================================" +if [ "${TOKENTYPE}" == "softhsm" ]; then + echo "=======================================================" + echo "Test GENERIC keys" + echo "=======================================================" -echo "Hello World" > data.msg + echo "Hello World" > data.msg -for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do - echo - echo "=======================================================" - echo "$MECHANISM: Sign & Verify (KEY (First Found))" - echo "=======================================================" + for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do + echo + echo "=======================================================" + echo "$MECHANISM: Sign & Verify (KEY (First Found))" + echo "=======================================================" - $PKCS11_TOOL --login --pin=$PIN --sign --mechanism=$MECHANISM \ - --input-file=data.msg --output-file=data.sig --module $P11LIB - assert $? "Failed to Sign data" - $PKCS11_TOOL --login --pin=$PIN --verify --mechanism=$MECHANISM \ - --input-file=data.msg --signature-file=data.sig --module $P11LIB - assert $? "Failed to Verify signature using pkcs11-tool" - rm data.sig -done; + $PKCS11_TOOL --login --pin=$PIN --sign --mechanism=$MECHANISM \ + --input-file=data.msg --output-file=data.sig --module $P11LIB + assert $? "Failed to Sign data" + $PKCS11_TOOL --login --pin=$PIN --verify --mechanism=$MECHANISM \ + --input-file=data.msg --signature-file=data.sig --module $P11LIB + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.sig + done; -rm data.msg + rm data.msg +fi echo "=======================================================" echo "Cleanup" diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index fed6dab008..576a9df182 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -1,7 +1,17 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +elif [ "${TOKENTYPE}" != "softhsm" ]; then + echo "Supported only for softhsm" + exit 1 +fi + +source $SOURCE_PATH/tests/common.sh softhsm echo "=======================================================" echo "Setup SoftHSM" @@ -13,7 +23,7 @@ fi # The Ubuntu has old softhsm version not supporting this feature grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -softhsm_initialize +initialize_token #echo "=======================================================" #echo "Generate AES key" @@ -204,7 +214,7 @@ assert $? "Fail, AES-CTR - wrong encrypt" echo "=======================================================" echo "Cleanup" echo "=======================================================" -softhsm_cleanup +token_cleanup rm objects.list rm aes_128.key aes_plain.data aes_plain_test.data aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain_pkcs11.data gcm_128.key gcm_vector_plain.data gcm_test_plain.data gcm_vector_ct_tag.data gcm_test_ct_tag.data diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index 0dd618eb5f..6d778b15b7 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -1,7 +1,17 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +elif [ "${TOKENTYPE}" != "softhsm" ]; then + echo "Supported only for softhsm" + exit 1 +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE # Test our PKCS #11 module here P11LIB="../src/pkcs11/.libs/opensc-pkcs11.so" diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index b5da43f717..96d2acd41d 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -1,18 +1,27 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then - echo "WARNING: The SoftHSM is not installed. Can not run this test" + echo "WARNING: The $TOKENTYPE is not installed. Can not run this test" exit 77; fi -# The Ubuntu has old softhsm version not supporting this feature -grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +if [ "${TOKENTYPE}" == "softhsm" ]; then + # The Ubuntu has old softhsm version not supporting this feature + grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 +fi card_setup assert $? "Failed to set up card" @@ -20,10 +29,15 @@ assert $? "Failed to set up card" echo "=======================================================" echo "Test" echo "=======================================================" -#SoftHSM only supports CKM_RSA_PKCS_OAEP with --hash-algorithm SHA-1 and --mgf MGF1-SHA1 -# and it accepts pSourceData, but does not use, so decrypt fails, See pkcs11-tool.c comments -$PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" -assert $? "Failed running tests" +if [ "${TOKENTYPE}" == "softhsm" ]; then + #SoftHSM only supports CKM_RSA_PKCS_OAEP with --hash-algorithm SHA-1 and --mgf MGF1-SHA1 + # and it accepts pSourceData, but does not use, so decrypt fails, See pkcs11-tool.c comments + $PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" --hash-algorithm "SHA-1" --mgf "MGF1-SHA1" + assert $? "Failed running tests" +else + $PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}" + assert $? "Failed running tests" +fi echo "=======================================================" echo "Test objects URI" diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index cb4329a8c0..83399cf74d 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -1,6 +1,17 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh + +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm +echo "No tokentype provided, running with SoftHSM" +elif [ "${TOKENTYPE}" != "softhsm" ]; then + echo "Supported only for softhsm" + exit 1 +fi + +source $SOURCE_PATH/tests/common.sh softhsm echo "=======================================================" echo "Setup SoftHSM" @@ -9,9 +20,10 @@ if [[ ! -f $P11LIB ]]; then echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi + # The Ubuntu has old softhsm version not supporting this feature grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -softhsm_initialize +initialize_token PKCS11_TOOL_W_PIN="$PKCS11_TOOL --module $P11LIB --pin $PIN" @@ -285,6 +297,6 @@ rm rsa_priv.pem rsa_pub.pem rsa_priv.der aes.key aes_kek.key pkcs11_wrapped.data echo "=======================================================" echo "Cleanup" echo "=======================================================" -softhsm_cleanup +token_cleanup exit $ERRORS From 9815727925712507c1a0d4340237d95757f8d8ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 7 Mar 2025 14:01:48 +0100 Subject: [PATCH 3828/4321] Add CI tests for pkcs11-tool with kryoptic, softhsm and softokn --- .github/setup-fedora.sh | 4 + .github/setup-kryoptic.sh | 11 +++ .github/setup-linux.sh | 2 + .github/workflows/external-pkcs11.yaml | 114 +++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100755 .github/setup-kryoptic.sh create mode 100644 .github/workflows/external-pkcs11.yaml diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 57de2ede61..42dbb10989 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -18,6 +18,10 @@ else DEPS="$DEPS pcsc-lite-devel readline-devel openssl-devel zlib-ng-devel libcmocka-devel" fi +if [ "$1" == "kryoptic" ]; then + DEPS="$DEPS clang meson cargo expect pkgconf-pkg-config openssl-devel p11-kit-devel gnutls-utils g++ sqlite-devel python3-six git" +fi + sudo dnf install -y $DEPS XFAIL_TESTS="test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh" diff --git a/.github/setup-kryoptic.sh b/.github/setup-kryoptic.sh new file mode 100755 index 0000000000..6310165772 --- /dev/null +++ b/.github/setup-kryoptic.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# build kryoptic +if [ ! -d "kryoptic" ]; then + git clone https://github.com/latchset/kryoptic.git +fi +pushd kryoptic +git submodule init +git submodule update +cargo build --features dynamic,standard,nssdb +popd diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 94882a0322..4f501dd35f 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -53,6 +53,8 @@ elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then WINE_DEPS="$WINE_DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686" fi FORCE_INSTALL=1 +elif [ "$1" == "softokn" ]; then + DEPS="$DEPS libnss3" fi # The Github Ubuntu images since 20211122.1 are broken diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml new file mode 100644 index 0000000000..c97613585d --- /dev/null +++ b/.github/workflows/external-pkcs11.yaml @@ -0,0 +1,114 @@ +name: Tests of external pkcs11 modules + +on: + pull_request: + paths: + - '**.c' + - '**.h' + - '**.sh' + - .github/workflows/fedora.yml + - '**.am' + - doc/** + - configure.ac + push: + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + BASE_DEPS: | + build-essential docbook-xsl xsltproc gengetopt help2man pcscd check + pcsc-tools libtool make autoconf autoconf-archive automake pkg-config + git xxd openssl valgrind socat gawk + libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex + libnss3-tools + libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2 + KRYOPTIC: https://github.com/latchset/kryoptic.git + +jobs: + ####################### + ## pkcs11-tool tests ## + ####################### + + test-kryoptic: + runs-on: ubuntu-24.04 + container: + image: fedora:latest + env: + SOURCE_PATH: ./ + BUILD_PATH: ./ + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Setup Fedora + run: .github/setup-fedora.sh kryoptic + - name: Install OpenSC + run: .github/build.sh + - name: Setup Kryoptic + run: .github/setup-kryoptic.sh + - name: Test Sign & Verify with Kryoptic + run: tests/test-pkcs11-tool-sign-verify.sh kryoptic + - name: Test Import with Kryoptic + run: tests/test-pkcs11-tool-import.sh kryoptic kryoptic + - name: Test Allowed Mechanisms with Kryoptic + run: tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic + - name: Test pkcs11-tool test with Kryoptic + run: tests/test-pkcs11-tool-test.sh kryoptic + + test-softokn: + runs-on: ubuntu-24.04 + env: + SOURCE_PATH: ./ + BUILD_PATH: ./ + steps: + - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true + - name: Setup Ubuntu + run: .github/setup-linux.sh softokn + - name: Build OpenSC + run: .github/build.sh + - name: Test Sign & Verify with Softokn + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-sign-verify.sh softokn + - name: Test Import with Softokn + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-import.sh softokn + + test-softhsm: + runs-on: ubuntu-24.04 + env: + SOURCE_PATH: ./ + BUILD_PATH: ./ + steps: + - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + with: + packages: ${{ env.BASE_DEPS }} + version: apt-20-base + execute_install_scripts: true + - name: Setup Ubuntu + run: .github/setup-linux.sh + - name: Build OpenSC + run: .github/build.sh + - name: Test Sign & Verify with SoftHSM + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-sign-verify.sh softhsm + - name: Test Import with SoftHSM + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-import.sh softhsm + - name: Test Allowed Mechanisms with SoftHSM + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm + - name: Test pkcs11-tool test with SoftHSM + env: + LD_LIBRARY_PATH: /usr/local/lib + run: tests/test-pkcs11-tool-test.sh softhsm From 7725950090753362d7931cab7fcdafdecfd1b7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 10:08:19 +0100 Subject: [PATCH 3829/4321] Remove pulling openssl submodules --- .github/setup-kryoptic.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/setup-kryoptic.sh b/.github/setup-kryoptic.sh index 6310165772..60a5fecf07 100755 --- a/.github/setup-kryoptic.sh +++ b/.github/setup-kryoptic.sh @@ -5,7 +5,5 @@ if [ ! -d "kryoptic" ]; then git clone https://github.com/latchset/kryoptic.git fi pushd kryoptic -git submodule init -git submodule update cargo build --features dynamic,standard,nssdb popd From 58dc9732a71f8b2230cb17d128d3a4080a793d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 10:08:40 +0100 Subject: [PATCH 3830/4321] Add NSS Softokn name --- tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/README.md b/tests/README.md index d35bd784df..0cc761cc99 100644 --- a/tests/README.md +++ b/tests/README.md @@ -6,7 +6,7 @@ Some of the tests support running with several PKCS#11 modules: - SoftHSM, - Kyoptic, -- and Softokn. +- and NSS Softokn. The test can be run with specified token `softhsm | kryoptic | softokn`: From d19d9b1e6db6cc75bdf23a216b93327c72061f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 10:09:38 +0100 Subject: [PATCH 3831/4321] Rename init scripts for SW tokens --- tests/common.sh | 6 +++--- tests/{setup-kryoptic.sh => init-kryoptic.sh} | 0 tests/{setup-softhsm.sh => init-softhsm.sh} | 0 tests/{setup-softokn.sh => init-softokn.sh} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename tests/{setup-kryoptic.sh => init-kryoptic.sh} (100%) rename tests/{setup-softhsm.sh => init-softhsm.sh} (100%) rename tests/{setup-softokn.sh => init-softokn.sh} (100%) diff --git a/tests/common.sh b/tests/common.sh index 90b1c08947..0890419bb0 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -14,11 +14,11 @@ export PIN="123456" PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" if [ "${TOKENTYPE}" == "softhsm" ]; then - source "${BUILD_PATH}/tests/setup-softhsm.sh" + source "${BUILD_PATH}/tests/init-softhsm.sh" elif [ "${TOKENTYPE}" == "softokn" ]; then - source "${BUILD_PATH}/tests/setup-softokn.sh" + source "${BUILD_PATH}/tests/init-softokn.sh" elif [ "${TOKENTYPE}" == "kryoptic" ]; then - source "${BUILD_PATH}/tests/setup-kryoptic.sh" + source "${BUILD_PATH}/tests/init-kryoptic.sh" else echo "Unknown token type: $1" exit 1 diff --git a/tests/setup-kryoptic.sh b/tests/init-kryoptic.sh similarity index 100% rename from tests/setup-kryoptic.sh rename to tests/init-kryoptic.sh diff --git a/tests/setup-softhsm.sh b/tests/init-softhsm.sh similarity index 100% rename from tests/setup-softhsm.sh rename to tests/init-softhsm.sh diff --git a/tests/setup-softokn.sh b/tests/init-softokn.sh similarity index 100% rename from tests/setup-softokn.sh rename to tests/init-softokn.sh From 56708513a3176561e12f0cb7f23a5a49318a8f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 10:10:20 +0100 Subject: [PATCH 3832/4321] Remove checks for Ubuntu 18 --- tests/test-p11test.sh | 5 ----- tests/test-pkcs11-tool-allowed-mechanisms.sh | 5 ----- tests/test-pkcs11-tool-sign-verify.sh | 8 ++------ tests/test-pkcs11-tool-sym-crypt-test.sh | 2 -- tests/test-pkcs11-tool-test.sh | 5 ----- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 2 -- 6 files changed, 2 insertions(+), 25 deletions(-) diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 7f5e031082..617ac7ca4b 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -11,11 +11,6 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi -if [ "${TOKENTYPE}" == "softhsm" ]; then - # The Ubuntu has old softhsm version not supporting this feature - grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -fi - card_setup assert $? "Failed to set up card" diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 44a0b7f17e..9fdcd31f77 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -21,11 +21,6 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi -if [ "${TOKENTYPE}" == "softhsm" ]; then - # The Ubuntu has old softhsm version not supporting this feature - grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -fi - initialize_token echo "=======================================================" diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index ce1fe82b6d..eb698bbe0f 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -80,12 +80,8 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do # -PSS methods should work on data > 512 bytes; generate data: head -c 1024 data - if [ "${TOKENTYPE}" == "softhsm" ]; then - if [[ "$HASH" == "SHA512" ]]; then - continue; # This one is broken - fi - # Ubuntu SoftHSM version does not support RSA-PSS - grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && continue + if [[ "${TOKENTYPE}" == "softhsm" && "$HASH" == "SHA512" ]]; then + continue; # This one is broken for SoftHSM fi echo diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index 576a9df182..2ae03b779b 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -20,8 +20,6 @@ if [[ ! -f $P11LIB ]]; then echo "WARNING: The SoftHSM is not installed. Can not run this test" exit 77; fi -# The Ubuntu has old softhsm version not supporting this feature -grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 initialize_token diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 96d2acd41d..d84d3e7c2d 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -18,11 +18,6 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi -if [ "${TOKENTYPE}" == "softhsm" ]; then - # The Ubuntu has old softhsm version not supporting this feature - grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 -fi - card_setup assert $? "Failed to set up card" diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 83399cf74d..757caf09e6 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -21,8 +21,6 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi -# The Ubuntu has old softhsm version not supporting this feature -grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 initialize_token PKCS11_TOOL_W_PIN="$PKCS11_TOOL --module $P11LIB --pin $PIN" From e23688d0e14f4ca770aa608d007ea37d43b1dacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 10:24:02 +0100 Subject: [PATCH 3833/4321] Add separate test scripts for each token --- .github/workflows/external-pkcs11.yaml | 34 +++++--------------------- tests/test-kryoptic.sh | 9 +++++++ tests/test-softhsm.sh | 9 +++++++ tests/test-softokn.sh | 7 ++++++ 4 files changed, 31 insertions(+), 28 deletions(-) create mode 100755 tests/test-kryoptic.sh create mode 100755 tests/test-softhsm.sh create mode 100755 tests/test-softokn.sh diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index c97613585d..10b2db5ad7 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -46,14 +46,8 @@ jobs: run: .github/build.sh - name: Setup Kryoptic run: .github/setup-kryoptic.sh - - name: Test Sign & Verify with Kryoptic - run: tests/test-pkcs11-tool-sign-verify.sh kryoptic - - name: Test Import with Kryoptic - run: tests/test-pkcs11-tool-import.sh kryoptic kryoptic - - name: Test Allowed Mechanisms with Kryoptic - run: tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic - - name: Test pkcs11-tool test with Kryoptic - run: tests/test-pkcs11-tool-test.sh kryoptic + - name: Test with Kryoptic + run: tests/test-kryoptic.sh test-softokn: runs-on: ubuntu-24.04 @@ -71,14 +65,10 @@ jobs: run: .github/setup-linux.sh softokn - name: Build OpenSC run: .github/build.sh - - name: Test Sign & Verify with Softokn + - name: Test NSS Softokn env: LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-sign-verify.sh softokn - - name: Test Import with Softokn - env: - LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-import.sh softokn + run: tests/test-softokn.sh test-softhsm: runs-on: ubuntu-24.04 @@ -96,19 +86,7 @@ jobs: run: .github/setup-linux.sh - name: Build OpenSC run: .github/build.sh - - name: Test Sign & Verify with SoftHSM - env: - LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-sign-verify.sh softhsm - - name: Test Import with SoftHSM - env: - LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-import.sh softhsm - - name: Test Allowed Mechanisms with SoftHSM - env: - LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm - - name: Test pkcs11-tool test with SoftHSM + - name: Test SoftHSM env: LD_LIBRARY_PATH: /usr/local/lib - run: tests/test-pkcs11-tool-test.sh softhsm + run: tests/test-softhsm.sh diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh new file mode 100755 index 0000000000..c76df1c4e9 --- /dev/null +++ b/tests/test-kryoptic.sh @@ -0,0 +1,9 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +echo "Running all supported tests for Kryoptic token..." + +$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-test.sh kryoptic diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh new file mode 100755 index 0000000000..b79f6d16f5 --- /dev/null +++ b/tests/test-softhsm.sh @@ -0,0 +1,9 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +echo "Running all supported tests for SoftHSM token..." + +$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-test.sh softhsm diff --git a/tests/test-softokn.sh b/tests/test-softokn.sh new file mode 100755 index 0000000000..7c7ab643ee --- /dev/null +++ b/tests/test-softokn.sh @@ -0,0 +1,7 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +echo "Running all supported tests for NSS Softokn token..." + +$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softokn +$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softokn From 8dee9178bd24d7f656047984355e2573ded43360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 11 Mar 2025 16:06:11 +0100 Subject: [PATCH 3834/4321] Test sign with generic key on kryoptic --- tests/common.sh | 13 ++++----- tests/test-pkcs11-tool-sign-verify.sh | 38 +++++++++++++-------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index 0890419bb0..56dabdcd9d 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -75,14 +75,11 @@ function card_setup() { # Generate 521b ECC Key pair generate_key "EC:secp521r1" "04" "ECC521" || return 1 - if [[ ${TOKENTYPE} == "softhsm" ]]; then - # Generate an HMAC:SHA256 key - $PKCS11_TOOL --keygen --key-type="GENERIC:64" --login --pin=$PIN \ - --module="$P11LIB" --label="HMAC-SHA256" --id="05" - if [[ "$?" -ne "0" ]]; then - echo "Couldn't generate GENERIC key" - return 1 - fi + # Generate an HMAC:SHA256 key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --keygen --key-type="GENERIC:64" --label="HMAC-SHA256" --id="05" --usage-sign + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate GENERIC key" + return 1 fi } diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index eb698bbe0f..96674be974 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -235,30 +235,28 @@ for SIGN_KEY in "03" "04"; do rm data.sig{,.openssl} data.hash done -if [ "${TOKENTYPE}" == "softhsm" ]; then - echo "=======================================================" - echo "Test GENERIC keys" - echo "=======================================================" +echo "=======================================================" +echo "Test GENERIC keys" +echo "=======================================================" - echo "Hello World" > data.msg +echo "Hello World" > data.msg - for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do - echo - echo "=======================================================" - echo "$MECHANISM: Sign & Verify (KEY (First Found))" - echo "=======================================================" +for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do + echo + echo "=======================================================" + echo "$MECHANISM: Sign & Verify (KEY (First Found))" + echo "=======================================================" - $PKCS11_TOOL --login --pin=$PIN --sign --mechanism=$MECHANISM \ - --input-file=data.msg --output-file=data.sig --module $P11LIB - assert $? "Failed to Sign data" - $PKCS11_TOOL --login --pin=$PIN --verify --mechanism=$MECHANISM \ - --input-file=data.msg --signature-file=data.sig --module $P11LIB - assert $? "Failed to Verify signature using pkcs11-tool" - rm data.sig - done; + $PKCS11_TOOL "${PRIV_ARGS[@]}" --sign --mechanism=$MECHANISM \ + --input-file=data.msg --output-file=data.sig + assert $? "Failed to Sign data" + $PKCS11_TOOL "${PRIV_ARGS[@]}" --verify --mechanism=$MECHANISM \ + --input-file=data.msg --signature-file=data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.sig +done; - rm data.msg -fi +rm data.msg echo "=======================================================" echo "Cleanup" From 75039acf88d0a3d16902fe1d677a829e09c8a378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 12 Mar 2025 09:48:44 +0100 Subject: [PATCH 3835/4321] Add rest of the tests for SoftHSM --- tests/test-softhsm.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh index b79f6d16f5..2b500215e6 100755 --- a/tests/test-softhsm.sh +++ b/tests/test-softhsm.sh @@ -3,7 +3,11 @@ SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for SoftHSM token..." -$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm +$SOURCE_PATH/tests/test-p11test.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-test-threads.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-test.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softhsm From 9daeb8bcc0683ad72931c33b6efd585067acc614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 12 Mar 2025 09:49:01 +0100 Subject: [PATCH 3836/4321] Run p11test also on Kryoptic --- tests/test-kryoptic.sh | 1 + tests/test-p11test.sh | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index c76df1c4e9..5c6f0b2551 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -3,6 +3,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for Kryoptic token..." +$SOURCE_PATH/tests/test-p11test.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 617ac7ca4b..13cac358e8 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -1,10 +1,20 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} -source $SOURCE_PATH/tests/common.sh softhsm +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "softokn" ]; then + echo "p11test not supported" + exit 1 +elif [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then echo "WARNING: The SoftHSM is not installed. Can not run this test" @@ -17,10 +27,10 @@ assert $? "Failed to set up card" echo "=======================================================" echo "Run p11test" echo "=======================================================" -$VALGRIND ./../src/tests/p11test/p11test -v -m $P11LIB -o softhsm.json -p $PIN +$VALGRIND ./../src/tests/p11test/p11test -v -m $P11LIB -o $TOKENTYPE.json -p $PIN assert $? "Failed running tests" -# Run the input shrough sed to skip the mechanism part: +# Run the input through sed to skip the mechanism part: # * broken because of uninitialized memory in softhsm # * different for different softhsm versions # and interface tests @@ -29,25 +39,25 @@ function filter_log() { sed -n '/readonly_tests/,$p' $1 } -REF_FILE="$SOURCE_PATH/tests/softhsm_ref.json" +REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_ref.json" if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then - REF_FILE="$SOURCE_PATH/tests/softhsm_fips_ref.json" + REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" fi -diff -U3 <(filter_log $REF_FILE) <(filter_log softhsm.json) +diff -U3 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) assert $? "Unexpected results" echo "=======================================================" echo "Run p11test with PKCS11SPY" echo "=======================================================" export PKCS11SPY="$P11LIB" -$VALGRIND ./../src/tests/p11test/p11test -v -m ../src/pkcs11/.libs/pkcs11-spy.so -o softhsm.json -p $PIN +$VALGRIND ./../src/tests/p11test/p11test -v -m ../src/pkcs11/.libs/pkcs11-spy.so -o $TOKENTYPE.json -p $PIN assert $? "Failed running tests" -diff -U3 <(filter_log $REF_FILE) <(filter_log softhsm.json) +diff -U3 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) assert $? "Unexpected results with PKCS11 spy" -rm softhsm.json +rm $TOKENTYPE.json echo "=======================================================" echo "Cleanup" From cbc5717baa22f6770ccd1738b4d85d12172e3bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 12 Mar 2025 11:26:49 +0100 Subject: [PATCH 3837/4321] Run sym crypt test also when kryoptic --- tests/test-kryoptic.sh | 5 +- tests/test-pkcs11-tool-sym-crypt-test.sh | 69 ++++++++++++------------ 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index 5c6f0b2551..4d8d3aeac0 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -4,7 +4,8 @@ SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for Kryoptic token..." $SOURCE_PATH/tests/test-p11test.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic +#$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-test.sh kryoptic diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index 2ae03b779b..da4a496501 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -3,15 +3,15 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 -if [ "${TOKENTYPE}" == "" ]; then +if [ "${TOKENTYPE}" == "softokn" ]; then + echo "p11test not supported" + exit 1 +elif [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm echo "No tokentype provided, running with SoftHSM" -elif [ "${TOKENTYPE}" != "softhsm" ]; then - echo "Supported only for softhsm" - exit 1 fi -source $SOURCE_PATH/tests/common.sh softhsm +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" echo "Setup SoftHSM" @@ -23,25 +23,21 @@ fi initialize_token -#echo "=======================================================" -#echo "Generate AES key" -#echo "=======================================================" -#ID1="85" -# Generate key -#$PKCS11_TOOL --keygen --key-type="aes:32" --login --pin=$PIN \ -# --module="$P11LIB" --label="gen_aes256" --id="$ID1" -#assert $? "Failed to Generate AES key" - echo "=======================================================" echo "import AES key" echo "=======================================================" ID2="86" echo -n "pppppppppppppppp" > aes_128.key # import key -softhsm2-util --import aes_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_128 --id "$ID2" +if [ "${TOKENTYPE}" == "softhsm" ]; then + softhsm2-util --import aes_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_128 --id "$ID2" +else + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes_128.key --id "$ID2" \ + --type secrkey --label "import_aes_128" --key-type AES:16 +fi assert $? "Fail, unable to import key" -$PKCS11_TOOL --module="$P11LIB" --list-objects -l --pin=$PIN 2>/dev/null |tee > objects.list +$PKCS11_TOOL "${PRIV_ARGS[@]}" --list-objects -l 2>/dev/null |tee > objects.list assert $? "Failed to list objects" VECTOR="00000000000000000000000000000000" @@ -53,14 +49,15 @@ echo "=======================================================" echo "C_Encrypt" dd if=/dev/urandom bs=200 count=1 >aes_plain.data 2>/dev/null -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" openssl enc -aes-128-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC-PAD (C_Encrypt) - wrong encrypt" + echo "C_Decrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_ciphertext_pkcs11.data --output-file aes_plain_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp aes_plain.data aes_plain_pkcs11.data >/dev/null 2>/dev/null @@ -70,13 +67,14 @@ echo "C_DecryptUpdate" dd if=/dev/urandom bs=8131 count=3 >aes_plain.data 2>/dev/null openssl enc -aes-128-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" assert $? "Fail, OpenSSL" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null assert $? "Fail/pkcs11-tool (C_DecryptUpdate) decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC-PAD - wrong decrypt" + echo "C_EncryptUpdate" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CBC-PAD --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null @@ -87,9 +85,9 @@ echo " AES-ECB, AES-CBC - must fail, because the length of " echo " the input is not multiple od block size " echo "=======================================================" echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data -! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +! $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail, AES-ECB must not work if the input is not a multiple of the block size" -! $PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +! $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail, AES-CBC must not work if the input is not a multiple of the block size" @@ -103,12 +101,12 @@ echo "=======================================================" openssl enc -aes-128-ecb -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -K "70707070707070707070707070707070" assert $? "Fail/OpenSSL" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-ECB --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-ECB --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-ECB - wrong decrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-ECB --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-ECB - wrong encrypt" @@ -121,13 +119,13 @@ echo "=======================================================" openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" assert $? "Fail/OpenSSL" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong decrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null @@ -142,13 +140,13 @@ echo "=======================================================" openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" assert $? "Fail/Openssl" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong decrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CBC --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null @@ -174,16 +172,21 @@ echo -n $PT | xxd -r -p > gcm_vector_plain.data echo -n $CT | xxd -r -p > gcm_vector_ct_tag.data echo -n $TAG | xxd -r -p >> gcm_vector_ct_tag.data -softhsm2-util --import gcm_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_gcm_128 --id "$ID3" >/dev/null +if [ "${TOKENTYPE}" == "softhsm" ]; then + softhsm2-util --import gcm_128.key --aes --token "SC test" --pin "$PIN" --label import_aes_gcm_128 --id "$ID3" >/dev/null +else + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object gcm_128.key --id "$ID3" \ + --type secrkey --label "import_aes_gcm_128" --key-type AES:16 +fi assert $? "Fail, unable to import key" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ --tag-bits-len 128 --input-file gcm_vector_plain.data --output-file gcm_test_ct_tag.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp gcm_vector_ct_tag.data gcm_test_ct_tag.data >/dev/null 2>&1 assert $? "Fail, AES-GCM - wrong encrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID3" -m AES-GCM --iv "$IV" --aad "$AAD" \ --tag-bits-len 128 --input-file gcm_vector_ct_tag.data --output-file gcm_test_plain.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp gcm_vector_plain.data gcm_test_plain.data >/dev/null 2>&1 @@ -197,13 +200,13 @@ echo "=======================================================" openssl enc -aes-128-ctr -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv "${VECTOR}" -K "70707070707070707070707070707070" assert $? "Fail/OpenSSL" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --decrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ --input-file aes_ciphertext_openssl.data --output-file aes_plain_test.data 2>/dev/null assert $? "Fail/pkcs11-tool decrypt" cmp aes_plain.data aes_plain_test.data >/dev/null 2>/dev/null assert $? "Fail, AES-CTR - wrong decrypt" -$PKCS11_TOOL --module="$P11LIB" --pin "$PIN" --encrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id "$ID2" -m AES-CTR --iv "${VECTOR}" \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null From 5c31e7447c25c71e4f508899e32f590c4b9a4dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 13 Mar 2025 14:32:13 +0100 Subject: [PATCH 3838/4321] Add wrap/unwrap tests also for kryoptic --- tests/test-kryoptic.sh | 1 + tests/test-pkcs11-tool-unwrap-wrap-test.sh | 322 ++++++++++++--------- 2 files changed, 181 insertions(+), 142 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index 4d8d3aeac0..1a9c0105cb 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -9,3 +9,4 @@ $SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic #$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-test.sh kryoptic +$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh kryoptic diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 757caf09e6..380f9403b6 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -1,20 +1,33 @@ #!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} +function compare_keys() { + RET=$1 + EXTRACTED=$2 + PLAIN=$3 + + if [ $RET == 0 ]; then + cmp $EXTRACTED $PLAIN >/dev/null 2>/dev/null + assert $? "Extracted key does not match the input key" + else + echo "Key cannot be read in plaintext" + fi +} + TOKENTYPE=$1 -if [ "${TOKENTYPE}" == "" ]; then +if [ "${TOKENTYPE}" == "softokn" ]; then + echo "Wrap/unwrap test not supported" + exit 1 +elif [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm -echo "No tokentype provided, running with SoftHSM" -elif [ "${TOKENTYPE}" != "softhsm" ]; then - echo "Supported only for softhsm" - exit 1 + echo "No tokentype provided, running with SoftHSM" fi -source $SOURCE_PATH/tests/common.sh softhsm +source $SOURCE_PATH/tests/common.sh $TOKENTYPE echo "=======================================================" -echo "Setup SoftHSM" +echo "Setup $TOKENTYPE" echo "=======================================================" if [[ ! -f $P11LIB ]]; then echo "WARNING: The SoftHSM is not installed. Can not run this test" @@ -23,19 +36,18 @@ fi initialize_token -PKCS11_TOOL_W_PIN="$PKCS11_TOOL --module $P11LIB --pin $PIN" - echo "=======================================================" echo " RSA-PKCS Unwrap test" echo "=======================================================" -ID1="85" -ID2="95" -ID3="96" +ID1="85" # RSA key +ID2="95" # GENERIC key +ID3="96" # AES key # Generate RSA key (this key is used to unwrap/wrap operation) -$PKCS11_TOOL_W_PIN --keypairgen --key-type rsa:1024 --id $ID1 --usage-wrap +$PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type rsa:1024 --id $ID1 --usage-wrap --usage-decrypt --label wrap-rsa assert $? "Failed to Generate RSA key" + # export public key -$PKCS11_TOOL_W_PIN --read-object --type pubkey --id $ID1 -o rsa_pub.key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type pubkey --id $ID1 -o rsa_pub.key assert $? "Failed to export public key" # create AES key @@ -46,18 +58,17 @@ echo -n $KEY|xxd -p -r > aes_plain_key openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key assert $? "Failed wrap AES key" -# unwrap key by pkcs11 interface -$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ - --extractable --application-id $ID3 --application-label "unwrap-generic-ex" 2>/dev/null +# unwrap key as generic key by pkcs11 interface +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ + --extractable --application-id $ID3 --application-label "unwrap-generic-ex" --extractable 2>/dev/null assert $? "Unwrap failed" -# because key is extractable, there is no problem to compare key value with original key -$PKCS11_TOOL_W_PIN --id $ID3 --read-object --type secrkey --output-file generic_extracted_key -assert $? "unable to read key value" -cmp generic_extracted_key aes_plain_key >/dev/null 2>/dev/null -assert $? "extracted key does not match the input key" + +# if extractable, there is no problem to compare key value with original key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID3 --read-object --type secrkey --output-file generic_extracted_key +compare_keys $? generic_extracted_key aes_plain_key # unwrap AES key, not extractable -$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type AES: \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type AES: \ --application-id $ID2 --application-label "unwrap-aes" 2>/dev/null assert $? "Unwrap failed" @@ -69,7 +80,7 @@ echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY assert $? "Fail/Openssl" -$PKCS11_TOOL_W_PIN --encrypt --id $ID2 -m AES-CBC --iv $VECTOR \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID2 -m AES-CBC --iv $VECTOR \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null @@ -79,12 +90,14 @@ echo "=======================================================" echo " RSA-PKCS Wrap test" echo "=======================================================" -$PKCS11_TOOL_W_PIN --wrap -m RSA-PKCS --id $ID1 --application-id $ID3 --output-file wrapped.key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS --id $ID1 --application-id $ID3 --output-file wrapped.key assert $? "Fail, unable to wrap" -$PKCS11_TOOL_W_PIN --decrypt -m RSA-PKCS --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key + +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key assert $? "Fail, unable to decrypt wrapped key" cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null assert $? "wrapped key after decipher does not match the original key" +echo "RSA-PKCS wrap test successful" echo "=======================================================" echo " RSA-PKCS-OAEP Unwrap test" @@ -110,17 +123,16 @@ openssl pkeyutl -encrypt -pubin -keyform DER -inkey rsa_pub.key -pkeyopt rsa_pad assert $? "Failed wrap AES key" # unwrap key by pkcs11 interface, extractable -$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ --extractable --application-id $ID4 --application-label "unwrap-aes-ex-with-rsa-oaep" 2>/dev/null assert $? "Unwrap failed" + # because key is extractable, there is no problem to compare key value with original key -$PKCS11_TOOL_W_PIN --id $ID4 --read-object --type secrkey --output-file generic_extracted_key -assert $? "unable to read key value" -cmp generic_extracted_key aes_plain_key >/dev/null 2>/dev/null -assert $? "extracted key does not match the input key" +$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID4 --read-object --type secrkey --output-file generic_extracted_key +compare_keys $? generic_extracted_key aes_plain_key # unwrap AES key, not extractable -$PKCS11_TOOL_W_PIN --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type AES: \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type AES: \ --application-id $ID5 --application-label "unwrap-aes-non-ex-with-rsa-oaep" 2>/dev/null assert $? "Unwrap failed" @@ -128,22 +140,25 @@ assert $? "Unwrap failed" openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY assert $? "Fail/Openssl" -$PKCS11_TOOL_W_PIN --encrypt --id $ID5 -m AES-CBC --iv $VECTOR \ +$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID5 -m AES-CBC --iv $VECTOR \ --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null assert $? "Fail/pkcs11-tool encrypt" cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrong encrypt" + echo "=======================================================" echo " RSA-PKCS-OAEP Wrap test" echo "=======================================================" -$PKCS11_TOOL_W_PIN --wrap -m RSA-PKCS-OAEP --id $ID1 --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID4 --output-file wrapped.key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS-OAEP --id $ID1 --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID4 --output-file wrapped.key assert $? "Fail, unable to wrap" -$PKCS11_TOOL_W_PIN --decrypt -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key + +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key assert $? "Fail, unable to decrypt wrapped key" cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null assert $? "wrapped key after decipher does not match the original key" +echo "RSA-PKCS-OAEP wrap test successful" echo "=======================================================" echo " RSA-PKCS / RSA-PKCS-OAEP Cleanup" @@ -155,142 +170,165 @@ echo "=======================================================" echo " AES wrap/unwrap" echo "=======================================================" -ID_RSA=$(echo "RSA" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") -ID_AES=$(echo "AES" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") -ID_KEK=$(echo "KEK" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") -ID_UNWRAPPED=$(echo "UW" | tr -d "\n" | od -An -vtx1 | tr -d " " | tr -d "\n") - -openssl genpkey -algorithm RSA -out rsa_priv.pem -assert $? "OpenSSL / Failed to generate RSA private key" -openssl pkey -in rsa_priv.pem -pubout -out rsa_pub.pem -assert $? "OpenSSL / Failed to convert RSA private key to public" -openssl pkcs8 -topk8 -inform PEM -outform DER -in rsa_priv.pem -out rsa_priv.der -nocrypt -assert $? "OpenSSL / Failed to PKCS8 encode RSA private key" -$PKCS11_TOOL_W_PIN --write-object rsa_priv.pem --id $ID_RSA --type privkey --usage-sign --extractable -assert $? "PKCS11 / Failed to write RSA private key" -$PKCS11_TOOL_W_PIN --write-object rsa_pub.pem --id $ID_RSA --type pubkey --usage-sign -assert $? "PKCS11 / Failed to write RSA public key" - -AES_KEY=$(head /dev/urandom | sha256sum | head -c 64) +is_openssl_3=$(openssl version | grep "OpenSSL 3.") +is_softhsm2_2_6_1=$(softhsm2-util -version | grep "2.6.1") + +$PKCS11_TOOL "${PRIV_ARGS[@]}" -O + +ID_KEK="0101" +ID_UNWRAPPED="0102" + +AES_KEY="7070707070707070707070707070707070707070707070707070707070707070" echo -n $AES_KEY | xxd -p -r > aes.key -$PKCS11_TOOL_W_PIN --write-object aes.key --id $ID_AES --type secrkey --key-type AES:32 --usage-decrypt --extractable -assert $? "PKCS11 / Failed to write AES key" AES_KEK=$(head /dev/urandom | sha256sum | head -c 64) echo -n $AES_KEK | xxd -p -r > aes_kek.key -$PKCS11_TOOL_W_PIN --write-object aes_kek.key --id $ID_KEK --type secrkey --key-type AES:32 --usage-wrap --extractable +$PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes_kek.key --id $ID_KEK --type secrkey \ + --key-type AES:32 --usage-wrap --extractable --label wrap-aes-32 assert $? "PKCS11 / Failed to write AES KEK" -is_openssl_3=$(openssl version | grep "OpenSSL 3.") -is_softhsm2_2_6_1=$(softhsm2-util -version | grep "2.6.1") - -if [[ -n $is_softhsm2_2_6_1 ]] -then +if [[ "$TOKENTYPE" != "softhsm" || -n "$is_softhsm2_2_6_1" ]]; then # CKM_AES_CBC -- SoftHSM2 AES CBC wrapping currently has a bug, the IV is not correctly used. Only IV=0 will work --* IV="00000000000000000000000000000000" - # RSA key - # SoftHSM2 does not support wrapping asymmetric keys with AES CBC since the length of the encoded private key is likely not aligned to 16 bytes and SoftHSM2 does not pad the input as intended in the PKCS#11 documentation (PKCS#11 mechanisms v3.0, section 2.10.5) - - # AES Key + echo "=======================================================" + echo " AES 256 CBC Unwrap test" + echo "=======================================================" + # wrapping AES Key with openssl openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data -nopad assert $? "OpenSSL / Failed to AES CBC encrypt AES key" - # Wrapping - $PKCS11_TOOL_W_PIN --wrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data - assert $? "PKCS11 / Failed to AES CBC wrap AES key" - cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - assert $? "AES CBC wrong AES key wrap" - # Unwrapping -- SoftHSM2 currently does not support CKM_AES_CBC unwrapping -- - # $PKCS11_TOOL_W_PIN --unwrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable - # assert $? "PKCS11 / Failed to AES CBC unwrap AES key" - # $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key - # assert $? "PKCS11 / Failed to read unwrapped AES key" - # cmp aes.key unwrapped.key - # assert $? "AES CBC wrong AES key unwrap" - # Cleanup - # $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED - # assert $? "PKCS11 / Failed to delete unwrapped AES key" -fi - -# CKM_AES_CBC_PAD -- SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping mechanism -- -# IV="000102030405060708090A0B0C0D0E0F" - # RSA key -# $PKCS11_TOOL_W_PIN --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_RSA --output-file pkcs11_wrapped.data -# assert $? "PKCS11 / Failed to AES CBC PAD wrap RSA priv key" -# openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in rsa_priv.der -out openssl_wrapped.data -# assert $? "OpenSSL / Failed to AES CBC encrypt RSA priv key" -# cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null -# assert $? "AES CBC PAD wrong RSA key wrap" - - # AES key -# $PKCS11_TOOL_W_PIN --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data -# assert $? "PKCS11 / Failed to AES CBC PAD wrap AES key" -# openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data -# assert $? "OpenSSL / Failed to AES CBC encrypt AES key" -# cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null -# assert $? "AES CBC PAD wrong AES key wrap" + if [ "${TOKENTYPE}" == "softhsm" ]; then + echo "SoftHSM2 currently does not support CKM_AES_CBC unwrapping" + # SoftHSM does not have the wrapped key already, write it for wrap test + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes.key --id $ID_UNWRAPPED --type secrkey --key-type AES:32 \ + --usage-decrypt --extractable --label "aes-stored" + assert $? "PKCS11 / Failed to write AES key" + else + # unwrap key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ + --key-type AES: --input-file openssl_wrapped.data --extractable --application-label "unwrap-aes-with-aes" + assert $? "PKCS11 / Failed to AES CBC unwrap AES key" + + # compare keys + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key + compare_keys $? aes.key unwrapped.key + + # check if AES key was correctly unwrapped with encryption + # encrypt with openssl + echo -n "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" > aes_plain.data + openssl enc -aes-256-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv $IV -K $AES_KEY + assert $? "Fail/Openssl" + # decrypt with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID_UNWRAPPED -m AES-CBC-PAD --iv $IV \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data + assert $? "Fail/pkcs11-tool encrypt" + cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null + assert $? "Fail, AES-CBC - wrong encrypt" + rm aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain.data + fi + echo "=======================================================" + echo " AES 256 CBC Wrap test" + echo "=======================================================" + # Wrapping AES Key with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ + --output-file pkcs11_wrapped.data + assert $? "Fail, unable to wrap" + + # Compare wrapped keys + cmp pkcs11_wrapped.data openssl_wrapped.data >/dev/null 2>/dev/null + assert $? "Fail, AES-CBC - wrapped key incorrect" + + # clean up + #$PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID_UNWRAPPED + #assert $? "PKCS11 / Failed to delete unwrapped AES key" +else + echo "Not supported" +fi +if [[ "$TOKENTYPE" != "softhsm" ]]; then + # CKM_AES_CBC_PAD -- SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping mechanism -- + IV="000102030405060708090A0B0C0D0E0F" + echo "=======================================================" + echo " AES 256 CBC PAD Wrap test" + echo "=======================================================" + # Wrapping AES key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES CBC PAD wrap AES key" + openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL / Failed to AES CBC encrypt AES key" + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES CBC PAD wrong AES key wrap" +fi -if [[ -n $is_openssl_3 ]] -then +if [[ -n $is_openssl_3 ]]; then # CKM_AES_KEY_WRAP IV="a6a6a6a6a6a6a6a6" - - # RSA Key + ID7="0103" + echo "=======================================================" + echo "AES-KEY-WRAP Wrap test" + echo "=======================================================" + # RSA Key # --AES-KEY-WRAP is not suitable for asymmetric key wrapping since the length of the encoded private key is likely not aligned to 8 bytes - # AES Key + # AES Key openssl enc -id-aes256-wrap -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data assert $? "OpenSSL / Failed to AES KEY WRAP wrap AES key" - # Wrapping - $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data + + # Wrapping + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ + --output-file pkcs11_wrapped.data assert $? "PKCS11 / Failed to AES KEY WRAP wrap AES key" cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null assert $? "AES KEY WRAP wrong AES key wrap" - # Unwrapping - $PKCS11_TOOL_W_PIN --unwrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable + + echo "=======================================================" + echo "AES-KEY-WRAP Unwrap test" + echo "=======================================================" + # Unwrapping + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID7 \ + --key-type AES: --input-file openssl_wrapped.data --extractable assert $? "PKCS11 / Failed to AES KEY WRAP wrap unwrap AES key" - $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key - assert $? "PKCS11 / Failed to read unwrapped AES key" - cmp aes.key unwrapped.key - assert $? "AES KEY WRAP wrong AES key unwrap" - # Cleanup - $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID7 --output-file unwrapped.key + compare_keys $? aes.key unwrapped.key + # Cleanup + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID_UNWRAPPED assert $? "PKCS11 / Failed to delete unwrapped AES key" - # CKM_AES_KEY_WRAP_PAD - IV="a65959a6" - - # RSA Key -- Fails with the current version of SoftHSM2 -- - # $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_RSA --output-file pkcs11_wrapped.data - # assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap RSA priv key" - # openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in rsa_priv.der -out openssl_wrapped.data - # assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt RSA priv key" - # cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - # assert $? "AES KEY WRAP PAD wrong RSA key wrap" - + if [[ "$TOKENTYPE" != "kryoptic" ]]; then + echo "=======================================================" + echo "AES-KEY-WRAP-PAD Wrap test" + echo "=======================================================" + # CKM_AES_KEY_WRAP_PAD + IV="a65959a6" + ID8="0104" # AES Key - openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data - assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt AES key" - # Wrapping - $PKCS11_TOOL_W_PIN --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_AES --output-file pkcs11_wrapped.data - assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap AES key" - cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - assert $? "AES KEY WRAP PAD wrong AES key wrap" - # Unwrapping - $PKCS11_TOOL_W_PIN --unwrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --key-type AES: --input-file openssl_wrapped.data --extractable - assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap unwrap AES key" - $PKCS11_TOOL_W_PIN --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key - assert $? "PKCS11 / Failed to read unwrapped AES key" - cmp aes.key unwrapped.key - assert $? "AES KEY WRAP PAD wrong AES key unwrap" - # Cleanup - $PKCS11_TOOL_W_PIN --delete-object --type secrkey --id $ID_UNWRAPPED - assert $? "PKCS11 / Failed to delete unwrapped AES key" + openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt AES key" + # Wrapping + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID7 --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap AES key" + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES KEY WRAP PAD wrong AES key wrap" + + echo "=======================================================" + echo "AES-KEY-WRAP-PAD Unwrap test" + echo "=======================================================" + # Unwrapping + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID8 --key-type AES: --input-file openssl_wrapped.data --extractable + assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap unwrap AES key" + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID8 --output-file unwrapped.key + assert $? "PKCS11 / Failed to read unwrapped AES key" + cmp aes.key unwrapped.key + assert $? "AES KEY WRAP PAD wrong AES key unwrap" + # Cleanup + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID8 + assert $? "PKCS11 / Failed to delete unwrapped AES key" + fi fi +$PKCS11_TOOL "${PRIV_ARGS[@]}" -O -rm rsa_priv.pem rsa_pub.pem rsa_priv.der aes.key aes_kek.key pkcs11_wrapped.data openssl_wrapped.data unwrapped.key +rm -f aes.key aes_kek.key pkcs11_wrapped.data openssl_wrapped.data unwrapped.key echo "=======================================================" echo "Cleanup" From d83ee0b2cf4ce3ffef4a9e066fd6bb0ba637de36 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 21 Mar 2025 12:05:23 +0200 Subject: [PATCH 3839/4321] Build on Linux arm64 Signed-off-by: Raul Metsma --- .github/setup-linux.sh | 5 +- .github/workflows/linux.yml | 115 ++++++++++++------------------------ 2 files changed, 40 insertions(+), 80 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 4f501dd35f..24d166735a 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -91,10 +91,11 @@ deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-updates main restric deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-proposed main restricted universe multiverse" | \ $SUDO tee -a /etc/apt/sources.list.d/ddebs.list $SUDO apt-get update -qq + ARCH_TRIPLET=$(dpkg-architecture -qDEB_HOST_MULTIARCH) DEP="libssl1.1-dbgsym" - if [ -f "/usr/lib/x86_64-linux-gnu/libssl.so.3" ]; then + if [ -f "/usr/lib/${ARCH_TRIPLET}/libssl.so.3" ]; then # libcrypto is in same package as libssl - DEPX=`dpkg -S "/usr/lib/x86_64-linux-gnu/libssl.so.3"` + DEPX=`dpkg -S "/usr/lib/${ARCH_TRIPLET}/libssl.so.3"` DEP="${DEPX%%:*}-dbgsym" fi $SUDO apt-get install -y openssl-dbgsym "$DEP" softhsm2-dbgsym libsofthsm2-dbgsym diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b03f2b8a15..3565c715bc 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -32,56 +32,47 @@ env: jobs: build: - runs-on: ubuntu-24.04 + name: build-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }} + strategy: + matrix: + dist: ['22.04', '24.04'] + arch: ['amd64', 'arm64'] + build: ['dist', 'valgrind'] + exclude: + - build: dist + arch: arm64 + runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-20-base + version: apt-${{ matrix.dist }}-${{ matrix.arch }}-base execute_install_scripts: true - - run: .github/setup-linux.sh - - run: .github/build.sh dist + - run: .github/setup-linux.sh ${{ matrix.build == 'valgrind' && 'debug' || '' }} + - run: .github/build.sh ${{ matrix.build }} - name: Upload test logs uses: actions/upload-artifact@v4 if: failure() with: - name: ubuntu-test-logs + name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-test-logs path: | tests/*.log src/tests/unittests/*.log - uses: actions/cache@v4 id: cache-build + if: matrix.build == 'dist' with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ github.sha }} - name: Upload build artifacts + if: matrix.build == 'dist' uses: actions/upload-artifact@v4 with: - name: opensc-build + name: opensc-build-${{ matrix.dist }}-${{ matrix.arch }} path: opensc*.tar.gz - valgrind: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-latest-base - execute_install_scripts: true - - run: .github/setup-linux.sh debug - - run: .github/build.sh valgrind - - name: Upload test logs - uses: actions/upload-artifact@v4 - if: failure() - with: - name: ubuntu-valgrind-logs - path: | - tests/*.log - src/tests/unittests/*.log - build-no-shared: runs-on: ubuntu-latest steps: @@ -113,7 +104,7 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-20-base + version: apt-24.04-amd64-base execute_install_scripts: true - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 @@ -188,7 +179,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: @@ -244,7 +235,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh v0 - run: .github/test-isoapplet.sh v0 valgrind @@ -263,7 +254,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: @@ -288,7 +279,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: @@ -307,13 +298,13 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} %{{ env.JAVA_DEPS }} - version: apt-20-base + version: apt-24.04-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: @@ -332,13 +323,13 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-20-base + version: apt-24.04-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh clang-tidy - run: .github/build.sh clang-tidy @@ -350,13 +341,13 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-20-base + version: apt-24.04-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh cac - run: .github/test-cac.sh - run: .github/test-cac.sh valgrind @@ -369,13 +360,13 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-20-base + version: apt-24.04-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh oseid - run: .github/test-oseid.sh - run: .github/test-oseid.sh valgrind @@ -383,38 +374,6 @@ jobs: ############################################ ## Ubuntu 22.04 with OpenSSL 3.0 pipeline ## ############################################ - build-ubuntu-22: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-22-base - execute_install_scripts: true - - run: .github/setup-linux.sh - - run: .github/build.sh dist valgrind - - uses: actions/upload-artifact@v4 - if: failure() - with: - name: ubuntu-22-test-logs - path: | - tests/*.log - src/tests/unittests/*.log - - uses: actions/cache@v4 - id: cache-build - if: ${{ success() }} - with: - path: ./* - key: ${{ runner.os }}-22-${{ github.sha }} - - name: Upload artifacts - uses: actions/upload-artifact@v4 - if: ${{ success() }} - with: - name: opensc-22-build - path: - opensc*.tar.gz - build-ubuntu-22-piv-sm: runs-on: ubuntu-22.04 steps: @@ -467,7 +426,7 @@ jobs: test-cac-ubuntu-22: runs-on: ubuntu-22.04 - needs: [build-ubuntu-22] + needs: [build] steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 @@ -479,26 +438,26 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-22-${{ github.sha }} + key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh cac - run: .github/test-cac.sh - run: .github/test-cac.sh valgrind test-oseid-ubuntu-22: runs-on: ubuntu-22.04 - needs: [build-ubuntu-22] + needs: [build] steps: - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-22-base + version: apt-22.04-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-22-${{ github.sha }} + key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - run: .github/setup-linux.sh oseid - run: .github/test-oseid.sh - run: .github/test-oseid.sh valgrind @@ -596,7 +555,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - name: Pull mingw build artifacts uses: actions/download-artifact@v4 with: From 8b89f80b8140a4938239282dbc6a4cc66dde7b94 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 16 Sep 2024 15:22:07 +0300 Subject: [PATCH 3840/4321] Simplify macOS build process * Xcode 12.2 was released 2020 Signed-off-by: Raul Metsma --- .github/setup-macos.sh | 1 - MacOSX/Distribution.xml.in | 4 +-- MacOSX/Distribution_universal.xml.in | 28 ------------------- MacOSX/Makefile.am | 1 - MacOSX/build-package.in | 42 +++++++++------------------- MacOSX/target_tokend.plist | 5 ---- configure.ac | 1 - 7 files changed, 15 insertions(+), 67 deletions(-) delete mode 100644 MacOSX/Distribution_universal.xml.in delete mode 100644 MacOSX/target_tokend.plist diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index 1324cd43f4..aee52dd1a5 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -7,7 +7,6 @@ brew install automake gengetopt help2man libtool # openSCToken export PATH="/usr/local/opt/ccache/libexec:$PATH" git clone https://github.com/frankmorgner/OpenSCToken.git -sudo rm -rf /Library/Developer/CommandLineTools; if [ -n "$PASS_SECRETS_TAR_ENC" ]; then gpg --quiet --batch --yes --decrypt --passphrase="$PASS_SECRETS_TAR_ENC" --output .github/secrets.tar .github/secrets.tar.gpg diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index 238513837c..f6a265f2e2 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -5,12 +5,12 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/I --> - + @PACKAGE_STRING@ - + diff --git a/MacOSX/Distribution_universal.xml.in b/MacOSX/Distribution_universal.xml.in deleted file mode 100644 index 0b8823d122..0000000000 --- a/MacOSX/Distribution_universal.xml.in +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - @PACKAGE_STRING@ - - - - - - - - OpenSC.pkg - - - OpenSCToken.pkg - - - OpenSC-startup.pkg - - diff --git a/MacOSX/Makefile.am b/MacOSX/Makefile.am index 764b2b5071..2130aa59a9 100644 --- a/MacOSX/Makefile.am +++ b/MacOSX/Makefile.am @@ -2,7 +2,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = build \ build-package.in \ Distribution.xml.in \ - Distribution_universal.xml.in \ libtool-bundle \ opensc-uninstall \ resources \ diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 0ebca23b4c..c66c78bc70 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -14,12 +14,6 @@ set -ex test -x ./configure || ./bootstrap BUILDPATH=${PWD} -xcode_ver=$(xcodebuild -version | sed -En 's/Xcode[[:space:]](.*)/\1/p') -base_ver="12.2" -if [ $(echo -e $base_ver"\n"$xcode_ver | sort -V | head -1) == "$base_ver" ]; then - export BUILD_ARM="true" -fi - export SED=/usr/bin/sed PREFIX=/Library/OpenSC export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig @@ -32,20 +26,19 @@ if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-versio git clone --depth=1 https://github.com/openssl/openssl.git -b openssl-3.0 fi cd openssl - ./Configure darwin64-x86_64 no-shared --prefix=$PREFIX enable-ec_nistp_64_gcc_128 + sed -ie 's!my @disablables = (!my @disablables = (\n "apps",!' Configure + ./Configure darwin64-x86_64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 make clean make -j 4 make DESTDIR=$BUILDPATH/openssl_bin install_sw - if test -n "${BUILD_ARM}"; then - make clean - ./Configure darwin64-arm64 no-shared --prefix=$PREFIX enable-ec_nistp_64_gcc_128 - make -j 4 - make DESTDIR=$BUILDPATH/openssl_arm64 install_sw - lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a -output libcrypto.a - lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a -output libssl.a - mv libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a - mv libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a - fi + make clean + ./Configure darwin64-arm64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 + make -j 4 + make DESTDIR=$BUILDPATH/openssl_arm64 install_sw + lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a -output libcrypto.a + lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a -output libssl.a + mv libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a + mv libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a cd .. fi export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`" @@ -54,17 +47,8 @@ if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-versio export CRYPTO_LIBS="$OPENSSL_LIBS" fi -# Locate the latest OSX SDK -SDK_PATH=$(xcrun --sdk macosx --show-sdk-path) -export CFLAGS="$CFLAGS -isysroot $SDK_PATH" - -if test -n "${BUILD_ARM}"; then - export CFLAGS="$CFLAGS -arch x86_64 -arch arm64" - export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64" - DISTRIBUTION_XML=MacOSX/Distribution_universal.xml -else - DISTRIBUTION_XML=MacOSX/Distribution.xml -fi +export CFLAGS="$CFLAGS -arch x86_64 -arch arm64" +export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64" export OBJCFLAGS=$CFLAGS if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then @@ -189,7 +173,7 @@ pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.open pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg # Build product -productbuild --distribution $DISTRIBUTION_XML --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" +productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" # Sign installer if test -n "${INSTALLER_SIGN_IDENTITY}"; then diff --git a/MacOSX/target_tokend.plist b/MacOSX/target_tokend.plist deleted file mode 100644 index 5dd5da85fd..0000000000 --- a/MacOSX/target_tokend.plist +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/configure.ac b/configure.ac index 65b8095ebe..50bc9aec4b 100644 --- a/configure.ac +++ b/configure.ac @@ -1199,7 +1199,6 @@ AC_CONFIG_FILES([ MacOSX/Makefile MacOSX/build-package MacOSX/Distribution.xml - MacOSX/Distribution_universal.xml MacOSX/resources/Welcome.html ]) From 9f9ae268bd0c2298ab79955b757a1656f86951a0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 3 Apr 2025 15:40:21 +0200 Subject: [PATCH 3841/4321] DNIe: disable file cache by default fixes https://github.com/OpenSC/OpenSC/issues/3276 --- src/libopensc/pkcs15.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index c89feddb8c..7357a02e32 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1232,7 +1232,6 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) "cac1", "cac", "coolkey", - "dnie", "edo", "esteid2018", "flex", From 5305bfa57d834ff4958803896b28ff54e4465c81 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 3 Apr 2025 18:28:19 +0200 Subject: [PATCH 3842/4321] fixed formatting --- src/libopensc/pkcs15.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 7357a02e32..73ca1807ad 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1227,25 +1227,25 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) * The following list was initialized with the cards that can't be modified * with OpenSC i.e. which don't have a profile/driver for pkcs15-init. */ const char *card_drivers_with_file_cache[] = { - "atrust-acos", - "belpic", - "cac1", - "cac", - "coolkey", - "edo", - "esteid2018", - "flex", - "cyberflex", - "gemsafeV1", - "idprime", - "itacns", - "jpki", - "MaskTech", - "mcrd", - "myeid", - "npa", - "nqapplet", - "tcos", + "atrust-acos", + "belpic", + "cac1", + "cac", + "coolkey", + "edo", + "esteid2018", + "flex", + "cyberflex", + "gemsafeV1", + "idprime", + "itacns", + "jpki", + "MaskTech", + "mcrd", + "myeid", + "npa", + "nqapplet", + "tcos", }; if (NULL == card || NULL == card->driver || NULL == card->driver->short_name) From 1538f8515757d9eecd3e9f2656589606524bfbe1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 3 Apr 2025 18:28:39 +0200 Subject: [PATCH 3843/4321] CI: fixed fedora deps --- .github/setup-fedora.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 42dbb10989..3a25f6fc51 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -3,7 +3,7 @@ set -ex -o xtrace # Generic dependencies -DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils openpace openpace-devel" +DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils openpace openpace-devel gawk" if [ "$1" == "clang" ]; then DEPS="$DEPS clang" From ff9830da6014c290768b84a13e107000a36afa70 Mon Sep 17 00:00:00 2001 From: d4ryus Date: Wed, 2 Apr 2025 09:46:07 +0200 Subject: [PATCH 3844/4321] pkcs11-tool: Don't clutter stdout Use stderr for info messages instead. --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index bf72a0dfa0..e4836d1723 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2762,7 +2762,7 @@ build_rsa_oaep_params( oaep_params->mgf = CKG_MGF1_SHA3_512; break; default: - printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(opt_hash_alg)); + fprintf(stderr, "hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(opt_hash_alg)); oaep_params->hashAlg = CKM_SHA256; /* fall through */ case CKM_SHA256: @@ -2779,7 +2779,7 @@ build_rsa_oaep_params( if (opt_mgf != 0) { oaep_params->mgf = opt_mgf; } else { - printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(oaep_params->mgf)); + fprintf(stderr, "mgf not set, defaulting to %s\n", p11_mgf_to_name(oaep_params->mgf)); } /* PKCS11 3.0 is vague about setting CKZ_DATA_SPECIFIED */ @@ -2790,7 +2790,7 @@ build_rsa_oaep_params( mech->pParameter = oaep_params; mech->ulParameterLen = sizeof(*oaep_params); - printf("OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", + fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n", p11_mechanism_to_name(oaep_params->hashAlg), p11_mgf_to_name(oaep_params->mgf), oaep_params->source, From e1bf1a30518b4b246da13711a1cb215aaece2f73 Mon Sep 17 00:00:00 2001 From: CardContact Systems GmbH Date: Thu, 10 Apr 2025 00:37:35 +0200 Subject: [PATCH 3845/4321] Add support for RSA public key encoded with id-RSASSA-PSS (#3353) * Add support for RSA public key encoded with id-RSASSA-PSS * Fix whitespace --------- Co-authored-by: Andreas Schwier --- src/libopensc/pkcs15-algo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index b3ebacdfba..335bde8c18 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -358,8 +358,9 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { #ifdef SC_ALGORITHM_MD5 {SC_ALGORITHM_MD5, {{1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL}, #endif -#ifdef SC_ALGORITHM_RSA /* really rsaEncryption */ +#ifdef SC_ALGORITHM_RSA /* really rsaEncryption and id-RSASSA-PSS */ {SC_ALGORITHM_RSA, {{1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL}, + {SC_ALGORITHM_RSA, {{1, 2, 840, 113549, 1, 1, 10, -1}}, NULL, NULL, NULL}, #endif #ifdef SC_ALGORITHM_DH {SC_ALGORITHM_DH, {{1, 2, 840, 10046, 2, 1, -1}}, NULL, NULL, NULL}, From 6d52a501ee066a0f378252f6c271e5b48e9c1a1d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 25 Feb 2025 23:24:46 +0100 Subject: [PATCH 3846/4321] win: remove pkcs11-register from autostart Since on Windows Firefox switched to the OS' native method for hardware tokens, FF integration is already disabled by default on those platforms in pkcs11-register. There now is not much to register anymore. Closes https://github.com/OpenSC/OpenSC/pull/3218 Closes https://github.com/OpenSC/OpenSC/pull/3336 Fixes https://github.com/OpenSC/OpenSC/issues/3217 --- win32/OpenSC.wxs.in | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 33cf991eca..c6b181f81e 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -54,7 +54,6 @@ - - - - - - @@ -175,10 +169,7 @@ - - - - + @@ -220,8 +211,7 @@ - - + @@ -248,10 +238,6 @@ - - - From 17dcbb587e8f28614f26229833e8d4bde5c4194c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 11 Apr 2025 00:54:35 +0200 Subject: [PATCH 3847/4321] Add P11-Kit configuration for OpenSC (#3389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add P11-Kit configuration for OpenSC fixes https://github.com/OpenSC/OpenSC/issues/3110 * fixed typo Co-authored-by: Veronika Hanulíková * added p11-kit-devel to rpm packaging * enable p11-kit install directory --------- Co-authored-by: Veronika Hanulíková --- configure.ac | 13 +++++++++++++ packaging/opensc.spec | 3 +-- src/pkcs11/Makefile.am | 7 ++++++- .../opensc.module => src/pkcs11/opensc.module.in | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) rename packaging/opensc.module => src/pkcs11/opensc.module.in (91%) diff --git a/configure.ac b/configure.ac index 50bc9aec4b..9fa43c6f4e 100644 --- a/configure.ac +++ b/configure.ac @@ -956,6 +956,17 @@ if test "${completiondir}" = "detect"; then fi AC_SUBST([completiondir]) +AC_ARG_ENABLE(p11_system_config_modules, + AS_HELP_STRING([--enable-p11_system_config_modules=DIR], + [directory containing P11-Kit configuration files (default is determined by libp11-kit)]), + [p11_system_config_modules="${enableval}"], + [p11_system_config_modules=false]) +if test "${p11_system_config_modules}" = false ; then + p11_system_config_modules="`$PKG_CONFIG p11-kit-1 --variable=p11_system_config_modules`" +fi +AM_CONDITIONAL([ENABLE_P11KIT], [test -n "${p11_system_config_modules}"]) +P11_SYSTEM_CONFIG_MODULES="${p11_system_config_modules}" +AC_SUBST(P11_SYSTEM_CONFIG_MODULES) AC_SUBST(DYN_LIB_EXT) AC_SUBST(LIBDIR) @@ -1181,6 +1192,7 @@ AC_CONFIG_FILES([ src/sm/Makefile src/pkcs11/Makefile src/pkcs11/opensc-pkcs11.pc + src/pkcs11/opensc.module src/pkcs15init/Makefile src/scconf/Makefile src/tests/Makefile @@ -1226,6 +1238,7 @@ User binaries: $(eval eval eval echo "${bindir}") Configuration files: $(eval eval eval echo "${sysconfdir}") Bash completion: ${completiondir} XSL stylesheets: ${xslstylesheetsdir} +p11_system_config: ${p11_system_config_modules} man support: ${enable_man} doc support: ${enable_doc} diff --git a/packaging/opensc.spec b/packaging/opensc.spec index d6923b4cab..e886581ee0 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -6,7 +6,6 @@ Summary: Smart card library and applications License: LGPL-2.1-or-later AND BSD-3-Clause URL: https://github.com/OpenSC/OpenSC/wiki Source0: opensc-0.1.0.tar.gz -Source1: opensc.module BuildRequires: make BuildRequires: pcsc-lite-devel @@ -21,6 +20,7 @@ BuildRequires: bash-completion-devel BuildRequires: bash-completion %endif BuildRequires: zlib-ng-devel +BuildRequires: p11-kit-devel # For tests BuildRequires: libcmocka-devel BuildRequires: vim-common @@ -102,7 +102,6 @@ make check || (cat tests/*.log src/tests/unittests/*.log && exit 1) %install %make_install -install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module %ifarch %{ix86} # To avoid multilib issues, move these files on 32b intel architectures diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index ec97761264..df180f3577 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc versioninfo-pkcs11-spy.rc opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest +EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc versioninfo-pkcs11-spy.rc opensc-pkcs11.pc.in opensc.module.in opensc-pkcs11.dll.manifest if ENABLE_SHARED lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la @@ -30,6 +30,11 @@ endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = opensc-pkcs11.pc DISTCLEANFILES = $(pkgconfig_DATA) +if ENABLE_P11KIT +p11kitdir = $(P11_SYSTEM_CONFIG_MODULES) +p11kit_DATA = opensc.module +DISTCLEANFILES += $(p11kit_DATA) +endif opensc_pkcs11_la_SOURCES = $(OPENSC_PKCS11_SRC) $(OPENSC_PKCS11_INC) opensc_pkcs11_la_CFLAGS = $(OPENSC_PKCS11_CFLAGS) diff --git a/packaging/opensc.module b/src/pkcs11/opensc.module.in similarity index 91% rename from packaging/opensc.module rename to src/pkcs11/opensc.module.in index c6699afcc3..a3050801cd 100644 --- a/packaging/opensc.module +++ b/src/pkcs11/opensc.module.in @@ -6,4 +6,4 @@ # the p11-kit default path which is usually $(libdir)/pkcs11. # Doing it this way allows for packagers to package opensc for # 32-bit and 64-bit and make them parallel installable -module: opensc-pkcs11.so +module: opensc-pkcs11@DYN_LIB_EXT@ From 99b6c85107e05ced1dee654781451f0780eb576c Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 23 Mar 2025 22:27:45 +0200 Subject: [PATCH 3848/4321] More strict code checking Signed-off-by: Raul Metsma --- .github/workflows/linux-strict.yml | 9 ++++++--- src/libopensc/card-eoi.c | 2 +- src/libopensc/reader-pcsc.c | 13 +++++++++++-- src/sm/sm-eac.c | 10 +++++----- src/tools/npa-tool.c | 10 +++++----- src/tools/pkcs11-tool.c | 4 ++-- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 536a91bfaa..9b34bfaa78 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -7,7 +7,7 @@ on: - '**.c' - '**.h' - '**.sh' - - .github/workflows/linux.yml + - .github/workflows/linux-strict.yml - '**.am' - doc/** - configure.ac @@ -28,6 +28,7 @@ permissions: # -Wno-incompatible-pointer-types-discards-qualifiers -- again with logging # -Wno-unused-function -- the inline compat functions for openssl # are included in files where they are needed and clang does not like it +# -Wno-unused-parameter -- too many to fix them right now # -Wformat-pedantic - this complains about missing casts to (void *) which is # pointles # -Wno-pedantic -- this complains about void and function pointers casts @@ -35,15 +36,17 @@ permissions: # complains about missing const, which is there env: CFLAGS: >- - -pedantic -Werror -Wall + -pedantic -Werror -Wall -Wextra -Wno-strict-prototypes -Wno-empty-translation-unit -Wno-incompatible-library-redeclaration - -Wno-variadic-macros -Wno-unused-function + -Wno-variadic-macros -Wno-unused-function -Wno-unused-parameter -Wno-incompatible-pointer-types-discards-qualifiers -Wno-gnu-zero-variadic-macro-arguments -Wno-format-pedantic -Wno-pedantic -Wno-incompatible-function-pointer-types + CLANG_CFLAGS: >- + -Wshorten-64-to-32 BASE_DEPS: | build-essential docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index 27c7da4f1d..24b5e6df99 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -392,7 +392,7 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * if (data->cmd == SC_PIN_CMD_UNBLOCK) { int pin_reference = data->pin_reference; - int pin2_len = data->pin2.len; + size_t pin2_len = data->pin2.len; /* Verify PUK, establish SM if necessary */ data->cmd = SC_PIN_CMD_VERIFY; data->pin_reference = data->puk_reference; diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 9619edd95a..25d038ed58 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -43,6 +43,10 @@ #include "pace.h" +#ifndef MAXDWORD +#define MAXDWORD UINT32_MAX +#endif + #ifdef HAVE_PCSCLITE_H #if !defined (__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < 101000 #define HAVE_PCSCLITE 1 @@ -245,6 +249,11 @@ static int pcsc_internal_transmit(sc_reader_t *reader, LOG_FUNC_CALLED(reader->ctx); card = priv->pcsc_card; + // Ensure send buffer fits into a DWORD + if (sendsize > MAXDWORD) + return SC_ERROR_INVALID_ARGUMENTS; + if (*recvsize > MAXDWORD) + return SC_ERROR_INVALID_ARGUMENTS; if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; @@ -253,8 +262,8 @@ static int pcsc_internal_transmit(sc_reader_t *reader, sRecvPci.dwProtocol = opensc_proto_to_pcsc(reader->active_protocol); sRecvPci.cbPciLength = sizeof(sRecvPci); - dwSendLength = sendsize; - dwRecvLength = *recvsize; + dwSendLength = (DWORD)sendsize; + dwRecvLength = (DWORD)*recvsize; if (!control) { rv = priv->gpriv->SCardTransmit(card, &sSendPci, sendbuf, dwSendLength, diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 83e9b551ea..c311674eed 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -250,7 +250,7 @@ static int encode_mse_cdata(struct sc_context *ctx, int protocol, memcpy(p, data, data_len); memcpy(p+data_len, encoded_chat, encoded_chat_len); *cdata = p; - r = data_len + encoded_chat_len; + r = (int)(data_len + encoded_chat_len); sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MSE command data", p, r); @@ -405,7 +405,7 @@ static int encode_gen_auth_cdata(struct sc_context *ctx, r = sc_asn1_encode(ctx, capdu_eac_gen_auth, cdata, &data_len); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, r, "Error encoding General Authenticate APDU data"); - r = data_len; + r = (int)data_len; err: return r; @@ -1553,7 +1553,7 @@ eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, } *enc = p; memcpy(*enc, encbuf->data, encbuf->length); - r = encbuf->length; + r = (int)encbuf->length; err: BUF_MEM_clear_free(databuf); @@ -1594,7 +1594,7 @@ eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, } *data = p; memcpy(*data, databuf->data, databuf->length); - r = databuf->length; + r = (int)databuf->length; err: BUF_MEM_clear_free(databuf); @@ -1641,7 +1641,7 @@ eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, } *macdata = p; memcpy(*macdata, macbuf->data, macbuf->length); - r = macbuf->length; + r = (int)macbuf->length; err: if (inbuf) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 81a90a749d..30ccf732da 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -63,7 +63,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) #endif #ifndef HAVE_GETLINE -static int getline(char **lineptr, size_t *n, FILE *stream) +static ssize_t +getline(char **lineptr, size_t *n, FILE *stream) { char *p; @@ -172,7 +173,7 @@ int npa_translate_apdus(sc_card_t *card, FILE *input) char *read = NULL; size_t readlen = 0, apdulen; sc_apdu_t apdu; - int linelen; + ssize_t linelen; int r; memset(&apdu, 0, sizeof apdu); @@ -269,9 +270,8 @@ static int add_to_ASN1_AUXILIARY_DATA_NPA_TOOL( if (data && data_len) { template->discretionary_data3 = ASN1_OCTET_STRING_new(); - if (!template->discretionary_data3 - || !ASN1_OCTET_STRING_set( - template->discretionary_data3, data, data_len)) { + if (!template->discretionary_data3 || !ASN1_OCTET_STRING_set( + template->discretionary_data3, data, (int)data_len)) { r = SC_ERROR_INTERNAL; goto err; } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e4836d1723..018e9071bc 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4385,7 +4385,7 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ /* Edwards and Montogmery keys have the same format */ static int -parse_ed_mont_pkey(EVP_PKEY *pkey, int type, int pk_type, struct ec_curve_info *ec_curve_info, int private, struct gostkey_info *gost) +parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curve_info *ec_curve_info, int private, struct gostkey_info *gost) { unsigned char *key; size_t key_size; @@ -6638,7 +6638,7 @@ static int read_object(CK_SESSION_HANDLE session) if (!os) { if ((os = ASN1_OCTET_STRING_new()) == NULL) util_fatal("cannot decode EC_POINT"); - if (ASN1_OCTET_STRING_set(os, value, (long)len) == 0) { + if (ASN1_OCTET_STRING_set(os, value, (int)len) == 0) { util_fatal("cannot decode EC_POINT"); } } From e6ca5f8935c53edc64d8b41ea5ed3f43c4212552 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 16 Sep 2024 15:23:00 +0300 Subject: [PATCH 3849/4321] EstEID 2025 Signed-off-by: Raul Metsma --- .gitignore | 1 + doc/files/files.html | 1 + doc/files/opensc.conf.5.xml.in | 1 + src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-esteid2025.c | 229 ++++++++++++++++++++++++++++++ src/libopensc/cards.h | 10 +- src/libopensc/ctx.c | 3 +- src/libopensc/pkcs15-esteid2025.c | 210 +++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 1 + src/libopensc/pkcs15-syn.h | 1 + src/libopensc/pkcs15.c | 1 + 12 files changed, 457 insertions(+), 9 deletions(-) create mode 100644 src/libopensc/card-esteid2025.c create mode 100644 src/libopensc/pkcs15-esteid2025.c diff --git a/.gitignore b/.gitignore index 368a04c29b..ff43bafd14 100644 --- a/.gitignore +++ b/.gitignore @@ -153,3 +153,4 @@ src/tests/fuzzing/fuzz_scconf_parse_string version.m4.ci openssl_arm64 openssl_bin +openpace_bin diff --git a/doc/files/files.html b/doc/files/files.html index 486b13ff76..c01b2d55ec 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -801,6 +801,7 @@ dnie, edo, esteid2018, + esteid2025, flex (deactivated driver), cyberflex (deactivated driver), gemsafeV1, diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 86195b8303..e4c0c4acea 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1242,6 +1242,7 @@ app application { dnie, edo, esteid2018, + esteid2025, flex (deactivated driver), cyberflex (deactivated driver), gemsafeV1, diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index c3cec250fa..903f9fce4d 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -49,12 +49,12 @@ libopensc_la_SOURCES_BASE = \ card-iasecc.c iasecc-sdo.c iasecc-sm.c card-sc-hsm.c \ card-dnie.c cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ - card-npa.c card-esteid2018.c card-idprime.c \ + card-npa.c card-esteid2018.c card-esteid2025.c card-idprime.c \ card-edo.c card-nqApplet.c card-skeid.c card-eoi.c card-dtrust.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c pkcs15-tcos.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ - pkcs15-cac.c pkcs15-esinit.c pkcs15-pteid.c \ + pkcs15-cac.c pkcs15-esinit.c pkcs15-pteid.c pkcs15-esteid2025.c \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 42179b2e34..193f5fde19 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -27,7 +27,7 @@ OBJECTS = \ card-iasecc.obj iasecc-sdo.obj iasecc-sm.obj cwa-dnie.obj cwa14890.obj \ card-sc-hsm.obj card-dnie.obj card-isoApplet.obj pkcs15-coolkey.obj \ card-masktech.obj card-gids.obj card-jpki.obj \ - card-npa.obj card-esteid2018.obj card-idprime.obj \ + card-npa.obj card-esteid2018.obj card-esteid2025.obj card-idprime.obj \ card-edo.obj card-nqApplet.obj card-skeid.obj card-eoi.obj card-dtrust.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj pkcs15-tcos.obj \ @@ -35,7 +35,7 @@ OBJECTS = \ pkcs15-cac.obj pkcs15-esinit.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ - pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ + pkcs15-esteid2018.obj pkcs15-esteid2025.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj pkcs15-dtrust.obj \ compression.obj sm.obj aux-data.obj \ $(TOPDIR)\win32\versioninfo.res diff --git a/src/libopensc/card-esteid2025.c b/src/libopensc/card-esteid2025.c new file mode 100644 index 0000000000..a0f153dbc1 --- /dev/null +++ b/src/libopensc/card-esteid2025.c @@ -0,0 +1,229 @@ +/* + * Driver for EstEID card issued from December 2025. + * + * Copyright (C) 2025, Raul Metsma + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "asn1.h" +#include "gp.h" +#include "internal.h" + +#define SIGNATURE_PAYLOAD_SIZE 0x30 + +static const struct sc_atr_table esteid_atrs[] = { + {"3b:ff:96:00:00:80:31:fe:43:80:31:b8:53:65:49:44:64:b0:85:05:10:12:23:3f:1d", NULL, "EstEID 2025", SC_CARD_TYPE_ESTEID_2025, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; + +static const struct sc_aid THALES_AID = { + {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}, + 12 +}; + +static const struct sc_card_operations *iso_ops = NULL; +static struct sc_card_operations esteid_ops; + +static struct sc_card_driver esteid2025_driver = {"EstEID 2025", "esteid2025", &esteid_ops, NULL, 0, NULL}; + +#define SC_TRANSMIT_TEST_RET(card, apdu, text) \ + do { \ + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); \ + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), text); \ + } while (0) + +static int +esteid_match_card(sc_card_t *card) +{ + int i = _sc_match_atr(card, esteid_atrs, &card->type); + + if (i >= 0 && gp_select_aid(card, &THALES_AID) == SC_SUCCESS) { + card->name = esteid_atrs[i].name; + return 1; + } + return 0; +} + +static int +esteid_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) +{ + u8 resp[SC_MAX_APDU_RESP_SIZE]; + size_t resplen = sizeof(resp); + int r; + struct sc_file *file = NULL; + struct sc_apdu apdu; + + LOG_FUNC_CALLED(card->ctx); + + // Only support full paths + if (in_path->type != SC_PATH_TYPE_PATH) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + sc_format_apdu_ex(&apdu, card->cla, 0xA4, 0x08, 0x04, in_path->value, in_path->len, resp, resplen); + SC_TRANSMIT_TEST_RET(card, apdu, "SELECT failed"); + if (file_out != NULL) { + file = sc_file_new(); + if (file == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + r = iso_ops->process_fci(card, file, resp, resplen); + if (r != SC_SUCCESS) { + sc_file_free(file); + } + LOG_TEST_RET(card->ctx, r, "Process fci failed"); + *file_out = file; + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) +{ + struct sc_apdu apdu; + u8 cse_crt_sig[] = {0x80, 0x01, 0x54, 0x84, 0x01, 0x00}; + u8 cse_crt_der[] = {0x84, 0x01, 0x00}; + + LOG_FUNC_CALLED(card->ctx); + + if (env == NULL || env->key_ref_len != 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + sc_log(card->ctx, "algo: %lu operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); + + if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN) { + cse_crt_sig[5] = env->key_ref[0]; + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); + } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE) { + cse_crt_der[2] = env->key_ref[0]; + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, cse_crt_der, sizeof(cse_crt_der), NULL, 0); + } else { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + SC_TRANSMIT_TEST_RET(card, apdu, "SET SECURITY ENV failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +esteid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) +{ + struct sc_apdu apdu; + u8 sbuf[SIGNATURE_PAYLOAD_SIZE + 2] = {0x90, SIGNATURE_PAYLOAD_SIZE}; + size_t le = MIN(SC_MAX_APDU_RESP_SIZE, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen)); + + LOG_FUNC_CALLED(card->ctx); + if (data == NULL || out == NULL || datalen > SIGNATURE_PAYLOAD_SIZE) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + // left-pad if necessary + memcpy(&sbuf[SIGNATURE_PAYLOAD_SIZE + 2 - datalen], data, MIN(datalen, SIGNATURE_PAYLOAD_SIZE)); + datalen = SIGNATURE_PAYLOAD_SIZE + 2; + + sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x90, 0xA0, sbuf, datalen, NULL, 0); + SC_TRANSMIT_TEST_RET(card, apdu, "PSO Set Hash failed"); + + sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x9E, 0x9A, NULL, 0, out, le); + SC_TRANSMIT_TEST_RET(card, apdu, "PSO Compute Digital Signature failed"); + + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); +} + +static int +esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) +{ + const u8 get_pin_info[] = {0xA0, 0x03, 0x83, 0x01, pin_reference}; + struct sc_apdu apdu; + u8 apdu_resp[SC_MAX_APDU_RESP_SIZE]; + size_t taglen; + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu_ex(&apdu, 0x00, 0xCB, 0x00, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, sizeof(apdu_resp)); + SC_TRANSMIT_TEST_RET(card, apdu, "GET DATA(pin info) failed"); + if (apdu.resplen < 3 || apdu.resp[0] != 0xA0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + const u8 *tag = sc_asn1_find_tag(card->ctx, apdu_resp + 2, apdu.resplen - 2, 0xDF21, &taglen); + if (tag == NULL || taglen == 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + return tag[0]; +} + +static int +esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + int r; + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "PIN CMD is %d", data->cmd); + if (data->cmd == SC_PIN_CMD_GET_INFO) { + sc_log(card->ctx, "SC_PIN_CMD_GET_INFO for %d", data->pin_reference); + r = esteid_get_pin_remaining_tries(card, data->pin_reference); + LOG_TEST_RET(card->ctx, r, "GET DATA(pin info) failed"); + + data->pin1.tries_left = r; + data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks + data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); +} + +static int +esteid_init(sc_card_t *card) +{ + unsigned long flags, ext_flags; + + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +esteid_logout(sc_card_t *card) +{ + return gp_select_aid(card, &THALES_AID); +} + +struct sc_card_driver * +sc_get_esteid2025_driver(void) +{ + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + + if (iso_ops == NULL) + iso_ops = iso_drv->ops; + + esteid_ops = *iso_drv->ops; + esteid_ops.match_card = esteid_match_card; + esteid_ops.init = esteid_init; + + esteid_ops.select_file = esteid_select_file; + + esteid_ops.set_security_env = esteid_set_security_env; + esteid_ops.compute_signature = esteid_compute_signature; + esteid_ops.pin_cmd = esteid_pin_cmd; + esteid_ops.logout = esteid_logout; + + return &esteid2025_driver; +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index f410f0672e..4ecf16b1f2 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -100,7 +100,7 @@ enum { SC_CARD_TYPE_OBERTHUR_32K_BIO, SC_CARD_TYPE_OBERTHUR_64K, /* Oberthur 'COSMO v7' with applet 'AuthentIC v3.2' */ - SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2 = 11100, + SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2 = 11100, /* belpic driver */ SC_CARD_TYPE_BELPIC_BASE = 12000, @@ -191,9 +191,9 @@ enum { /* Spanish DNIe card */ SC_CARD_TYPE_DNIE_BASE = 27000, - SC_CARD_TYPE_DNIE_BLANK, /* ATR LC byte: 00 */ - SC_CARD_TYPE_DNIE_ADMIN, /* ATR LC byte: 01 */ - SC_CARD_TYPE_DNIE_USER, /* ATR LC byte: 03 */ + SC_CARD_TYPE_DNIE_BLANK, /* ATR LC byte: 00 */ + SC_CARD_TYPE_DNIE_ADMIN, /* ATR LC byte: 01 */ + SC_CARD_TYPE_DNIE_USER, /* ATR LC byte: 03 */ SC_CARD_TYPE_DNIE_TERMINATED, /* ATR LC byte: 0F */ /* JavaCards with isoApplet */ @@ -231,6 +231,7 @@ enum { /* EstEID cards */ SC_CARD_TYPE_ESTEID_2018 = 35000, + SC_CARD_TYPE_ESTEID_2025, /* Rutoken cards */ SC_CARD_TYPE_RUTOKENS = 36000, @@ -305,6 +306,7 @@ extern sc_card_driver_t *sc_get_cac_driver(void); extern sc_card_driver_t *sc_get_cac1_driver(void); extern sc_card_driver_t *sc_get_npa_driver(void); extern sc_card_driver_t *sc_get_esteid2018_driver(void); +extern sc_card_driver_t *sc_get_esteid2025_driver(void); extern sc_card_driver_t *sc_get_idprime_driver(void); extern sc_card_driver_t *sc_get_edo_driver(void); extern sc_card_driver_t *sc_get_nqApplet_driver(void); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index b95a24e9fc..6c677bc0fb 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -134,7 +134,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "dnie", (void *(*)(void)) sc_get_dnie_driver }, #endif { "masktech", (void *(*)(void)) sc_get_masktech_driver }, - { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver }, { "idprime", (void *(*)(void)) sc_get_idprime_driver }, #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) { "edo", (void *(*)(void)) sc_get_edo_driver }, @@ -142,6 +141,8 @@ static const struct _sc_driver_entry internal_card_drivers[] = { /* Here should be placed drivers that need some APDU transactions in the * driver's `match_card()` function. */ + { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver }, + { "esteid2025", (void *(*)(void)) sc_get_esteid2025_driver }, { "coolkey", (void *(*)(void)) sc_get_coolkey_driver }, /* MUSCLE card applet returns 9000 on whatever AID is selected, see * https://github.com/JavaCardOS/MuscleCard-Applet/blob/master/musclecard/src/com/musclecard/CardEdge/CardEdge.java#L326 diff --git a/src/libopensc/pkcs15-esteid2025.c b/src/libopensc/pkcs15-esteid2025.c new file mode 100644 index 0000000000..5b7e9522cb --- /dev/null +++ b/src/libopensc/pkcs15-esteid2025.c @@ -0,0 +1,210 @@ +/* + * PKCS15 emulation layer for EstEID card issued from December 2025. + * + * Copyright (C) 2025, Raul Metsma + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "common/compat_strlcpy.h" + +#include "internal.h" +#include "opensc.h" +#include "pkcs15.h" + +static int +sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) +{ + sc_card_t *card = p15card->card; + u8 *buff; + int r, i; + size_t field_length = 0, buflen = 9, j; + sc_path_t tmppath; + static const u8 prkey_id[2] = {0x01, 0x02}; + + set_string(&p15card->tokeninfo->label, "ID-kaart"); + set_string(&p15card->tokeninfo->manufacturer_id, "Thales"); + + buff = malloc(buflen + 1); + if (!buff) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + + /* Read document number to be used as serial */ + sc_format_path("DFDD5007", &tmppath); + LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); + r = sc_read_binary(card, 0, buff, buflen, 0); + if (r < 0) { + free(buff); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } + LOG_TEST_RET(card->ctx, r, "read document number failed"); + + for (j = 0; j < buflen; j++) { + if (!isalnum(buff[j])) { + free(buff); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } + } + buff[buflen] = '\0'; + + free(p15card->tokeninfo->serial_number); + p15card->tokeninfo->serial_number = (char *)buff; + p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; + + /* add certificates */ + for (i = 0; i < 2; i++) { + static const char *cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; + static const char *cert_paths[2] = {"ADF1:3411", "ADF2:3421"}; + + struct sc_pkcs15_cert_info cert_info = { + .id = {.len = 1, .value[0] = prkey_id[i]} + }; + struct sc_pkcs15_object cert_obj = {0}; + + strlcpy(cert_obj.label, cert_names[i], sizeof(cert_obj.label)); + sc_format_path(cert_paths[i], &cert_info.path); + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add cert object"); + + if (i != 0) + continue; + + sc_pkcs15_cert_t *cert = NULL; + r = sc_pkcs15_read_certificate(p15card, &cert_info, 0, &cert); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not read authentication certificate"); + + if (cert->key->algorithm == SC_ALGORITHM_EC) + field_length = cert->key->u.ec.params.field_length; + + static const struct sc_object_id cn_oid = { + {2, 5, 4, 3, -1} + }; + u8 *cn_name = NULL; + size_t cn_len = 0; + r = sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, cert->subject_len, &cn_oid, &cn_name, &cn_len); + sc_pkcs15_free_certificate(cert); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not read authentication certificate"); + if (cn_len > 0) { + char *token_name = (char *)realloc(cn_name, cn_len + 1); + if (token_name) { + token_name[cn_len] = '\0'; + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = token_name; + } else + free(cn_name); + } + } + + /* add pins */ + for (i = 0; i < 3; i++) { + static const char *pin_names[3] = {"PIN1", "PIN2", "PUK"}; + static const size_t pin_min[3] = {4, 5, 8}; + static const int pin_ref[3] = {0x81, 0x82, 0x83}; + static const u8 pin_authid[3] = {1, 2, 3}; + + static const unsigned int pin_flags[3] = { + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + + struct sc_pkcs15_auth_info pin_info = { + .auth_id = {.len = 1, .value[0] = pin_authid[i]}, + .auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN, + .attrs = { + .pin = { + .reference = pin_ref[i], + .flags = pin_flags[i], + .type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, + .min_length = pin_min[i], + .stored_length = 12, + .max_length = 12, + .pad_char = 0x00}}, + .tries_left = 3, + .max_tries = 3 + }; + struct sc_pkcs15_object pin_obj = {.flags = pin_flags[i]}; + + strlcpy(pin_obj.label, pin_names[i], sizeof(pin_obj.label)); + + /* Link normal PINs with PUK */ + if (i < 2) { + pin_obj.auth_id.len = 1; + pin_obj.auth_id.value[0] = 3; + } + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add pin object"); + } + + // trigger PIN counter refresh via pin_cmd + struct sc_pkcs15_object *objs[3]; + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 3); + if (r != 3) { + sc_log(card->ctx, "Can not get auth objects"); + goto err; + } + for (i = 0; i < r; i++) { + r = sc_pkcs15_get_pin_info(p15card, objs[i]); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not get pin object"); + } + + /* add private keys */ + for (i = 0; i < 2; i++) { + static const u8 prkey_ref[2] = {0x01, 0x05}; + static const u8 prkey_pin[2] = {1, 2}; + static const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; + static const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + static const int prkey_consent[2] = {0, 1}; + + struct sc_pkcs15_prkey_info prkey_info = { + .id = {.len = 1, .value[0] = prkey_id[i]}, + .native = 1, + .key_reference = prkey_ref[i], + .field_length = field_length, + .usage = prkey_usage[i] + }; + struct sc_pkcs15_object prkey_obj = { + .auth_id = {.len = 1, .value[0] = prkey_pin[i]}, + .user_consent = prkey_consent[i], + .flags = SC_PKCS15_CO_FLAG_PRIVATE + }; + + strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label)); + + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add private key object"); + } + + return SC_SUCCESS; +err: + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); +} + +int +sc_pkcs15emu_esteid2025_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + if (p15card->card->type == SC_CARD_TYPE_ESTEID_2025) + return sc_pkcs15emu_esteid2025_init(p15card); + return SC_ERROR_WRONG_CARD; +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 3fe0914493..8874555a5b 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -56,6 +56,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "coolkey", sc_pkcs15emu_coolkey_init_ex }, { "din66291", sc_pkcs15emu_din_66291_init_ex }, { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, + { "esteid2025", sc_pkcs15emu_esteid2025_init_ex }, { "skeid", sc_pkcs15emu_skeid_init_ex }, { "cardos", sc_pkcs15emu_cardos_init_ex }, { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index f931409964..ed144b84c8 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -33,6 +33,7 @@ int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *, struct sc_aid *); +int sc_pkcs15emu_esteid2025_init_ex(sc_pkcs15_card_t *, struct sc_aid *); int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_cac_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 73ca1807ad..47e13d40ce 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1234,6 +1234,7 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) "coolkey", "edo", "esteid2018", + "esteid2025", "flex", "cyberflex", "gemsafeV1", From 0ab952c0d98aef3d55ab154cc9070095a7396a99 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 18 Apr 2025 19:15:54 +0200 Subject: [PATCH 3850/4321] piv_tool: Refactor the keygen cleanup to avoid possible memory leaks reported by oss-fuzz https://issues.oss-fuzz.com/u/1/issues/397209407 Signed-off-by: Jakub Jelen --- src/tests/fuzzing/fuzz_piv_tool.c | 1 - src/tools/piv-tool.c | 138 +++++++++++++++--------------- 2 files changed, 68 insertions(+), 71 deletions(-) diff --git a/src/tests/fuzzing/fuzz_piv_tool.c b/src/tests/fuzzing/fuzz_piv_tool.c index 05a8d87196..9d5d7ca778 100644 --- a/src/tests/fuzzing/fuzz_piv_tool.c +++ b/src/tests/fuzzing/fuzz_piv_tool.c @@ -57,7 +57,6 @@ void initilize_global() ctx = NULL; card = NULL; bp = NULL; - evpkey = NULL; opt_reader = NULL; opt_apdus = NULL; opt_apdu_count = 0; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index ec23b4b1a4..3dee5efaf9 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -109,8 +109,7 @@ static const char *option_help[] = { static sc_context_t *ctx = NULL; static sc_card_t *card = NULL; -static BIO * bp = NULL; -static EVP_PKEY * evpkey = NULL; +static BIO *bp = NULL; static int load_object(const char * object_id, const char * object_file) { @@ -284,14 +283,16 @@ static int admin_mode(const char* admin_info) /* generate a new key pair, and save public key in newkey */ static int gen_key(const char * key_info) { - int r; + int r = 1; u8 buf[2]; size_t buflen = 2; sc_cardctl_piv_genkey_info_t keydata = {0, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; + EVP_PKEY *evpkey = NULL; #if !defined(OPENSSL_NO_EC) int nid = -1; #endif + sc_hex_to_bin(key_info, buf, &buflen); if (buflen != 2) { fprintf(stderr, ": invalid, example: 9A:06\n"); @@ -340,7 +341,7 @@ static int gen_key(const char * key_info) r = sc_card_ctl(card, SC_CARDCTL_PIV_GENERATE_KEY, &keydata); if (r) { fprintf(stderr, "gen_key failed %d\n", r); - return r; + return 1; } #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -348,22 +349,15 @@ static int gen_key(const char * key_info) if (!evpkey) { sc_log_openssl(ctx); fprintf(stderr, "allocation of key failed\n"); - return r; + r = 1; + goto out; } #endif if (keydata.key_bits > 0) { /* RSA key */ BIGNUM *newkey_n, *newkey_e; #if OPENSSL_VERSION_NUMBER < 0x30000000L - RSA *newkey = RSA_new(); - if (!newkey) { - sc_log_openssl(ctx); - EVP_PKEY_free(evpkey); - free(keydata.pubkey); - free(keydata.exponent); - fprintf(stderr, "gen_key RSA_new failed %d\n",r); - return -1; - } + RSA *newkey = NULL; #else EVP_PKEY_CTX *cctx = NULL; OSSL_PARAM_BLD *bld = NULL; @@ -372,40 +366,36 @@ static int gen_key(const char * key_info) if (!keydata.pubkey || !keydata.exponent) { fprintf(stderr, "gen_key failed %d\n", r); - free(keydata.pubkey); - free(keydata.exponent); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - EVP_PKEY_free(evpkey); - RSA_free(newkey); -#endif - return -1; + r = 1; + goto out; } newkey_n = BN_bin2bn(keydata.pubkey, (int)keydata.pubkey_len, NULL); newkey_e = BN_bin2bn(keydata.exponent, (int)keydata.exponent_len, NULL); - free(keydata.pubkey); - keydata.pubkey_len = 0; - free(keydata.exponent); - keydata.exponent_len = 0; if (!newkey_n || !newkey_e) { sc_log_openssl(ctx); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - EVP_PKEY_free(evpkey); - RSA_free(newkey); -#endif - fprintf(stderr, "conversion or key params failed %d\n", r); - return -1; + fprintf(stderr, "conversion or key params failed\n"); + r = 1; + goto out; } #if OPENSSL_VERSION_NUMBER < 0x30000000L + newkey = RSA_new(); + if (!newkey) { + sc_log_openssl(ctx); + fprintf(stderr, "gen_key RSA_new failed\n"); + r = 1; + goto out; + } + if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { sc_log_openssl(ctx); - EVP_PKEY_free(evpkey); RSA_free(newkey); BN_free(newkey_n); BN_free(newkey_e); fprintf(stderr, "gen_key unable to set RSA values"); - return -1; + r = 1; + goto out; } if (verbose) @@ -413,12 +403,12 @@ static int gen_key(const char * key_info) if (EVP_PKEY_assign_RSA(evpkey, newkey) != 1) { sc_log_openssl(ctx); - EVP_PKEY_free(evpkey); RSA_free(newkey); BN_free(newkey_n); BN_free(newkey_e); fprintf(stderr, "gen_key unable to set RSA values"); - return -1; + r = 1; + goto out; } #else if (!(bld = OSSL_PARAM_BLD_new()) || @@ -429,7 +419,8 @@ static int gen_key(const char * key_info) OSSL_PARAM_BLD_free(bld); BN_free(newkey_n); BN_free(newkey_e); - return -1; + r = 1; + goto out; } BN_free(newkey_n); @@ -443,7 +434,8 @@ static int gen_key(const char * key_info) EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); fprintf(stderr, "gen_key unable to gen RSA"); - return -1; + r = 1; + goto out; } if (verbose) EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); @@ -459,16 +451,14 @@ static int gen_key(const char * key_info) return -1; #else if (!keydata.ecpoint) { - fprintf(stderr, "gen_key failed %d\n", r); - return -1; + fprintf(stderr, "gen_key failed\n"); + return 1; } evpkey = EVP_PKEY_new_raw_public_key(nid, NULL, keydata.ecpoint, keydata.ecpoint_len); - free(keydata.ecpoint); - keydata.ecpoint_len = 0; if (!evpkey) { sc_log_openssl(ctx); fprintf(stderr, "gen key failed ti copy 25519 pubkey\n"); - return -1; + return 1; } if (verbose) @@ -497,11 +487,9 @@ static int gen_key(const char * key_info) #endif if (!keydata.ecpoint) { - fprintf(stderr, "gen_key failed %d\n", r); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - EVP_PKEY_free(evpkey); -#endif - return -1; + fprintf(stderr, "gen_key failed\n"); + r = 1; + goto out; } ecgroup = EC_GROUP_new_by_curve_name(nid); @@ -512,18 +500,14 @@ static int gen_key(const char * key_info) i = (int)(keydata.ecpoint_len - 1) / 2; x = BN_bin2bn(keydata.ecpoint + 1, i, NULL); y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL); - free(keydata.ecpoint); - keydata.ecpoint_len = 0; if (!x || !y) { sc_log_openssl(ctx); BN_free(x); BN_free(y); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - EVP_PKEY_free(evpkey); -#endif - return -1; + r = 1; + goto out; } r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL); @@ -535,10 +519,8 @@ static int gen_key(const char * key_info) fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n"); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - EVP_PKEY_free(evpkey); -#endif - return -1; + r = 1; + goto out; } #if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EC_KEY_new(); @@ -547,17 +529,17 @@ static int gen_key(const char * key_info) if (r == 0) { sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_group failed\n"); - EVP_PKEY_free(evpkey); EC_POINT_free(ecpoint); - return -1; + r = 1; + goto out; } r = EC_KEY_set_public_key(eckey, ecpoint); EC_POINT_free(ecpoint); if (r == 0) { sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_public_key failed\n"); - EVP_PKEY_free(evpkey); - return -1; + r = 1; + goto out; } if (verbose) @@ -565,8 +547,8 @@ static int gen_key(const char * key_info) if (EVP_PKEY_assign_EC_KEY(evpkey, eckey) != 1) { sc_log_openssl(ctx); - EVP_PKEY_free(evpkey); - return -1; + r = 1; + goto out; } #else group_name = OBJ_nid2sn(nid); @@ -576,7 +558,8 @@ static int gen_key(const char * key_info) fprintf(stderr, "EC_KEY_set_public_key out of memory\n"); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); - return -1; + r = 1; + goto out; } if (EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, buf, len, NULL) == 0) { sc_log_openssl(ctx); @@ -584,7 +567,8 @@ static int gen_key(const char * key_info) EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); free(buf); - return -1; + r = 1; + goto out; } EC_GROUP_free(ecgroup); @@ -597,7 +581,8 @@ static int gen_key(const char * key_info) sc_log_openssl(ctx); OSSL_PARAM_BLD_free(bld); free(buf); - return -1; + r = 1; + goto out; } free(buf); OSSL_PARAM_BLD_free(bld); @@ -610,7 +595,8 @@ static int gen_key(const char * key_info) fprintf(stderr, "gen_key unable to gen EC key"); EVP_PKEY_CTX_free(cctx); OSSL_PARAM_free(params); - return -1; + r = 1; + goto out; } if (verbose) EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL); @@ -624,11 +610,23 @@ static int gen_key(const char * key_info) #endif /* OPENSSL_NO_EC */ } - if (bp) + + if (bp) { r = i2d_PUBKEY_bio(bp, evpkey); + if (r != 1) { + sc_log_openssl(ctx); + fprintf(stderr, "Failed to encode public key"); + r = 1; + goto out; + } + } + r = SC_SUCCESS; +out: + free(keydata.pubkey); + free(keydata.exponent); + free(keydata.ecpoint); - if (evpkey) - EVP_PKEY_free(evpkey); + EVP_PKEY_free(evpkey); return r; } From c5b42f06eae67375fc74ae0afd4bd73b98c9fddc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 19 Apr 2025 20:47:04 +0200 Subject: [PATCH 3851/4321] pkcs11-tool: avoid integer underflow fixes coverity 454830 Overflowed constant --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 018e9071bc..2cae357159 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2648,7 +2648,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, */ tmp = bytes; if (sc_asn1_read_tag((const u8 **)&tmp, len, &cla, &tag, &taglen) != SC_SUCCESS || - len < 2 || len > 255) { + len < 2 || len > 255 || taglen < 1) { free(bytes); util_fatal("Key not supported"); } From 763db201f08fd468e40838d80b435a73f3a6ce2a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 19 Apr 2025 21:03:43 +0200 Subject: [PATCH 3852/4321] pkcs15init: fixed coverity 454835 Resource leak --- src/pkcs15init/pkcs15-lib.c | 8 +------- src/pkcs15init/profile.c | 4 ++++ src/tests/unittests/Makefile.am | 1 + 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index f2cdbf9058..8bdc0d668d 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -358,8 +358,6 @@ sc_pkcs15init_bind(struct sc_card *card, const char *name, const char *profile_o r = sc_pkcs15init_read_info(card, profile); if (r < 0) { - if (profile->dll) - sc_dlclose(profile->dll); sc_profile_free(profile); LOG_TEST_RET(ctx, r, "Read info error"); } @@ -390,9 +388,7 @@ sc_pkcs15init_bind(struct sc_card *card, const char *name, const char *profile_o sc_log(ctx, "Failed to finalize profile: %s", sc_strerror(r)); } while (0); - if (r < 0) { - if (profile->dll) - sc_dlclose(profile->dll); + if (r < 0) { sc_profile_free(profile); LOG_TEST_RET(ctx, r, "Load profile error"); } @@ -440,8 +436,6 @@ sc_pkcs15init_unbind(struct sc_profile *profile) if (r < 0) sc_log(ctx, "Failed to update TokenInfo: %s", sc_strerror(r)); } - if (profile->dll) - sc_dlclose(profile->dll); sc_profile_free(profile); } diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 4fbc3e7e1f..f22798d9f8 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -492,6 +492,10 @@ sc_profile_free(struct sc_profile *profile) if (profile->p15_spec) sc_pkcs15_card_free(profile->p15_spec); + + if (profile->dll) + sc_dlclose(profile->dll); + free(profile); } diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 5c9fab9319..7f861f0e8d 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -29,6 +29,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/ \ $(CMOCKA_CFLAGS) AM_CPPFLAGS =$(CODE_COVERAGE_CPPFLAGS) LDADD = $(top_builddir)/src/libopensc/libopensc.la \ + $(top_builddir)/src/common/libscdl.la \ $(CODE_COVERAGE_LIBS) \ $(OPTIONAL_OPENSSL_LIBS) \ $(CMOCKA_LIBS) From 00072dd51219c7b2a00a34fef14f4546d5e8d343 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 19 Apr 2025 22:02:36 +0200 Subject: [PATCH 3853/4321] fixed coverity 454825 Resource leak --- src/libopensc/compression.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index 0e98689b0c..c50a021432 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -91,9 +91,12 @@ static int sc_compress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) gz.avail_out = (unsigned)*outLen; err = deflateInit2(&gz, Z_BEST_COMPRESSION, Z_DEFLATED, window_size, 9, Z_DEFAULT_STRATEGY); - if(err != Z_OK) return zerr_to_opensc(err); + if (err != Z_OK) { + deflateEnd(&gz); + return zerr_to_opensc(err); + } err = deflate(&gz, Z_FINISH); - if(err != Z_STREAM_END) { + if (err != Z_STREAM_END) { deflateEnd(&gz); return zerr_to_opensc(err); } From d0fc5a933ca89062206a9ab305c9567e6282f4bd Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 15 Apr 2025 09:03:25 +0300 Subject: [PATCH 3854/4321] EstEID 2018 v2 new ATR + code cleanup Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2018.c | 155 ++++++++++++------------------ src/libopensc/pkcs15-esteid2018.c | 138 +++++++++++++------------- 2 files changed, 129 insertions(+), 164 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 989a854d77..9a57d7d638 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -32,18 +32,32 @@ /* Helping defines */ #define SIGNATURE_PAYLOAD_SIZE 0x30 -#define PIN1_REF 0x01 -#define PIN2_REF 0x85 -#define PUK_REF 0x02 +#define AUTH_REF 0x81 +#define SIGN_REF 0x9f +#define PIN1_REF 0x01 +#define PIN2_REF 0x85 +#define PUK_REF 0x02 static const struct sc_atr_table esteid_atrs[] = { - {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL}}; + {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; + +static const struct sc_aid IASECC_AID = { + {0xA0, 0x00, 0x00, 0x00, 0x77, 0x01, 0x08, 0x00, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0x00}, + 16 +}; -static const struct sc_aid IASECC_AID = {{0xA0, 0x00, 0x00, 0x00, 0x77, 0x01, 0x08, 0x00, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0x00}, - 16}; +static const struct sc_path MF = { + {0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + 2, 0, 0, SC_PATH_TYPE_PATH, {{0}, 0} +}; -static const struct sc_path adf2 = {{0x3f, 0x00, 0xAD, 0xF2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 4, 0, 0, SC_PATH_TYPE_PATH, {{0}, 0}}; +static const struct sc_path adf2 = { + {0x3f, 0x00, 0xAD, 0xF2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + 4, 0, 0, SC_PATH_TYPE_PATH, {{0}, 0} +}; static const struct sc_card_operations *iso_ops = NULL; static struct sc_card_operations esteid_ops; @@ -56,10 +70,10 @@ struct esteid_priv_data { #define DRVDATA(card) ((struct esteid_priv_data *)((card)->drv_data)) -#define SC_TRANSMIT_TEST_RET(card, apdu, text) \ - do { \ - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); \ - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), text); \ +#define SC_TRANSMIT_TEST_RET(card, apdu, text) \ + do { \ + LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); \ + LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), text); \ } while (0) static int esteid_match_card(sc_card_t *card) { @@ -72,40 +86,13 @@ static int esteid_match_card(sc_card_t *card) { return 0; } -static int esteid_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) { - if (sw1 == 0x6B && sw2 == 0x00) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED); - return iso_ops->check_sw(card, sw1, sw2); -} - -static int esteid_select(struct sc_card *card, unsigned char p1, unsigned char id1, unsigned char id2) { - struct sc_apdu apdu; - unsigned char sbuf[2]; - - LOG_FUNC_CALLED(card->ctx); - - // Select EF/DF - sbuf[0] = id1; - sbuf[1] = id2; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, p1, 0x0C); - if (id1 != 0x3F && id2 != 0x00) { - apdu.cse = SC_APDU_CASE_3_SHORT; - apdu.lc = 2; - apdu.data = sbuf; - apdu.datalen = 2; - } - apdu.le = 0; - apdu.resplen = 0; - - SC_TRANSMIT_TEST_RET(card, apdu, "SELECT failed"); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); -} - static int esteid_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out) { - unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - size_t pathlen; + const u8 *path = in_path->value; + u8 resp[SC_MAX_APDU_RESP_SIZE]; + size_t resplen = sizeof(resp); + int r; struct sc_file *file = NULL; + struct sc_apdu apdu; LOG_FUNC_CALLED(card->ctx); @@ -113,54 +100,45 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat if (in_path->type != SC_PATH_TYPE_PATH) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } + if (in_path->len % 2 != 0) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } - memcpy(path, in_path->value, in_path->len); - pathlen = in_path->len; - - while (pathlen >= 2) { + for (size_t pathlen = in_path->len; pathlen >= 2; pathlen -= 2, path += 2) { if (memcmp(path, "\x3F\x00", 2) == 0) { - LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "MF select failed"); - } else if (path[0] == 0xAD) { - LOG_TEST_RET(card->ctx, esteid_select(card, 0x01, path[0], path[1]), "DF select failed"); - } else if (pathlen == 2) { - LOG_TEST_RET(card->ctx, esteid_select(card, 0x02, path[0], path[1]), "EF select failed"); - - if (file_out != NULL) // Just make a dummy file - { + sc_format_apdu_ex(&apdu, card->cla, 0xA4, 0x00, 0x0C, path, 0, NULL, 0); + SC_TRANSMIT_TEST_RET(card, apdu, "MF select failed"); + } else if (pathlen == 2 && path[0] == 0xAD) { + sc_format_apdu_ex(&apdu, card->cla, 0xA4, 0x01, 0x0C, path, 2, NULL, 0); + SC_TRANSMIT_TEST_RET(card, apdu, "DF select failed"); + } else { + sc_format_apdu_ex(&apdu, card->cla, 0xA4, 0x09, 0x04, path, pathlen, resp, resplen); + SC_TRANSMIT_TEST_RET(card, apdu, "EF select failed"); + + if (file_out != NULL) { file = sc_file_new(); if (file == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->path = *in_path; - file->size = 1536; // Dummy size, to be above 1024 - + r = iso_ops->process_fci(card, file, resp, resplen); + if (r != SC_SUCCESS) { + sc_file_free(file); + } + LOG_TEST_RET(card->ctx, r, "Process fci failed"); *file_out = file; } + break; } - path += 2; - pathlen -= 2; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -// temporary hack, overload 6B00 SW processing -static int esteid_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long *flags) { - int r; - int (*saved)(struct sc_card *, unsigned int, unsigned int) = card->ops->check_sw; - LOG_FUNC_CALLED(card->ctx); - card->ops->check_sw = esteid_check_sw; - r = iso_ops->read_binary(card, idx, buf, count, flags); - card->ops->check_sw = saved; - LOG_FUNC_RETURN(card->ctx, r); -} - static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { struct esteid_priv_data *priv; struct sc_apdu apdu; - // XXX: could be const - unsigned char cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, 0x81}; - unsigned char cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, 0x9F}; - unsigned char cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, 0x81}; + static const u8 cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, AUTH_REF}; + static const u8 cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, SIGN_REF}; + static const u8 cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, AUTH_REF}; LOG_FUNC_CALLED(card->ctx); @@ -169,11 +147,11 @@ static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env sc_log(card->ctx, "algo: %lu operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); - if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 1) { + if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == AUTH_REF) { sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0); - } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 2) { + } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == SIGN_REF) { sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); - } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == 1) { + } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == AUTH_REF) { sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0); } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); @@ -189,7 +167,7 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data struct esteid_priv_data *priv = DRVDATA(card); struct sc_security_env *env = NULL; struct sc_apdu apdu; - u8 sbuf[SIGNATURE_PAYLOAD_SIZE]; + u8 sbuf[SIGNATURE_PAYLOAD_SIZE] = {0}; size_t le = MIN(SC_MAX_APDU_RESP_SIZE, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen)); LOG_FUNC_CALLED(card->ctx); @@ -199,11 +177,10 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data env = &priv->sec_env; // left-pad if necessary memcpy(&sbuf[SIGNATURE_PAYLOAD_SIZE - datalen], data, MIN(datalen, SIGNATURE_PAYLOAD_SIZE)); - memset(sbuf, 0x00, SIGNATURE_PAYLOAD_SIZE - datalen); datalen = SIGNATURE_PAYLOAD_SIZE; switch (env->key_ref[0]) { - case 1: /* authentication key */ + case AUTH_REF: sc_format_apdu_ex(&apdu, 0x00, 0x88, 0, 0, sbuf, datalen, out, le); break; default: @@ -216,22 +193,20 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data } static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { - unsigned char get_pin_info[] = {0x4D, 0x08, 0x70, 0x06, 0xBF, 0x81, 0xFF, 0x02, 0xA0, 0x80}; - + const u8 get_pin_info[] = {0x4D, 0x08, 0x70, 0x06, 0xBF, 0x81, pin_reference & 0x0F, 0x02, 0xA0, 0x80}; // mask out local/global struct sc_apdu apdu; - unsigned char apdu_resp[SC_MAX_APDU_RESP_SIZE]; + u8 apdu_resp[SC_MAX_APDU_RESP_SIZE]; LOG_FUNC_CALLED(card->ctx); // We don't get the file information here, so we need to be ugly if (pin_reference == PIN1_REF || pin_reference == PUK_REF) { - LOG_TEST_RET(card->ctx, esteid_select(card, 0x00, 0x3F, 0x00), "Cannot select MF"); + LOG_TEST_RET(card->ctx, esteid_select_file(card, &MF, NULL), "Cannot select MF"); } else if (pin_reference == PIN2_REF) { LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - get_pin_info[6] = pin_reference & 0x0F; // mask out local/global sc_format_apdu_ex(&apdu, 0x00, 0xCB, 0x3F, 0xFF, get_pin_info, sizeof(get_pin_info), apdu_resp, sizeof(apdu_resp)); SC_TRANSMIT_TEST_RET(card, apdu, "GET DATA(pin info) failed"); if (apdu.resplen < 32) { @@ -260,14 +235,14 @@ static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tr } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { // Verify PUK, then issue UNBLOCK // VERIFY - memcpy(&tmp, data, sizeof(struct sc_pin_cmd_data)); + tmp = *data; tmp.cmd = SC_PIN_CMD_VERIFY; tmp.pin_reference = PUK_REF; tmp.pin2.len = 0; r = iso_ops->pin_cmd(card, &tmp, tries_left); LOG_TEST_RET(card->ctx, r, "VERIFY during unblock failed"); - if (data->pin_reference == 0x85) { + if (data->pin_reference == PIN2_REF) { LOG_TEST_RET(card->ctx, esteid_select_file(card, &adf2, NULL), "Cannot select QSCD AID"); } // UNBLOCK @@ -290,7 +265,6 @@ static int esteid_init(sc_card_t *card) { if (!priv) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); card->drv_data = priv; - card->max_recv_size = 233; // XXX: empirical, not documented flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; @@ -322,7 +296,6 @@ struct sc_card_driver *sc_get_esteid2018_driver(void) { esteid_ops.finish = esteid_finish; esteid_ops.select_file = esteid_select_file; - esteid_ops.read_binary = esteid_read_binary; esteid_ops.set_security_env = esteid_set_security_env; esteid_ops.compute_signature = esteid_compute_signature; diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index f8569d1e54..8295ad51e1 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -48,7 +48,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); r = sc_read_binary(card, 0, buff, 11, 0); LOG_TEST_RET(card->ctx, r, "read document number failed"); - const unsigned char *tag = sc_asn1_find_tag(card->ctx, buff, (size_t)r, 0x04, &taglen); + const u8 *tag = sc_asn1_find_tag(card->ctx, buff, (size_t)r, 0x04, &taglen); if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); @@ -65,20 +65,17 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { /* add certificates */ for (i = 0; i < 2; i++) { - const char *esteid_cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; - const char *esteid_cert_paths[2] = {"3f00:adf1:3401", "3f00:adf2:341f"}; - const u8 esteid_cert_ids[2] = {1, 2}; + static const char *esteid_cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; + static const char *esteid_cert_paths[2] = {"3f00:adf1:3401", "3f00:adf2:341f"}; + static const u8 esteid_cert_ids[2] = {1, 2}; - struct sc_pkcs15_cert_info cert_info; - struct sc_pkcs15_object cert_obj; - - memset(&cert_info, 0, sizeof(cert_info)); - memset(&cert_obj, 0, sizeof(cert_obj)); + struct sc_pkcs15_cert_info cert_info = { + .id = {.len = 1, .value[0] = esteid_cert_ids[i]} + }; + struct sc_pkcs15_object cert_obj = {0}; strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label)); sc_format_path(esteid_cert_paths[i], &cert_info.path); - cert_info.id.value[0] = esteid_cert_ids[i]; - cert_info.id.len = 1; r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add cert oebjct"); @@ -93,58 +90,57 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { if (cert->key->algorithm == SC_ALGORITHM_EC) field_length = cert->key->u.ec.params.field_length; - const struct sc_object_id cn_oid = {{2, 5, 4, 3, -1}}; + static const struct sc_object_id cn_oid = { + {2, 5, 4, 3, -1} + }; u8 *cn_name = NULL; size_t cn_len = 0; sc_pkcs15_get_name_from_dn(card->ctx, cert->subject, cert->subject_len, &cn_oid, &cn_name, &cn_len); + sc_pkcs15_free_certificate(cert); if (cn_len > 0) { - char *token_name = malloc(cn_len + 1); + char *token_name = (char *)realloc(cn_name, cn_len + 1); if (token_name) { - memcpy(token_name, cn_name, cn_len); token_name[cn_len] = '\0'; - set_string(&p15card->tokeninfo->label, (const char *)token_name); - free(token_name); - } + free(p15card->tokeninfo->label); + p15card->tokeninfo->label = token_name; + } else + free(cn_name); } - free(cn_name); - sc_pkcs15_free_certificate(cert); } /* add pins */ for (i = 0; i < 3; i++) { - const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; - const size_t esteid_pin_min[3] = {4, 5, 8}; - const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; - const u8 esteid_pin_authid[3] = {1, 2, 3}; - const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; - - const unsigned int esteid_pin_flags[3] = { - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; - - struct sc_pkcs15_auth_info pin_info; - struct sc_pkcs15_object pin_obj; - - memset(&pin_info, 0, sizeof(pin_info)); - memset(&pin_obj, 0, sizeof(pin_obj)); + static const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; + static const size_t esteid_pin_min[3] = {4, 5, 8}; + static const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; + static const u8 esteid_pin_authid[3] = {1, 2, 3}; + static const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; + + static const unsigned int esteid_pin_flags[3] = { + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + + struct sc_pkcs15_auth_info pin_info = { + .auth_id = {.len = 1, .value[0] = esteid_pin_authid[i]}, + .auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN, + .attrs = { + .pin = { + .reference = esteid_pin_ref[i], + .flags = esteid_pin_flags[i], + .type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, + .min_length = esteid_pin_min[i], + .stored_length = 12, + .max_length = 12, + .pad_char = 0xFF}}, + .tries_left = 3, + .max_tries = 3 + }; + struct sc_pkcs15_object pin_obj = { + .flags = esteid_pin_flags[i]}; sc_format_path(esteid_pin_path[i], &pin_info.path); - pin_info.auth_id.len = 1; - pin_info.auth_id.value[0] = esteid_pin_authid[i]; - pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; - pin_info.attrs.pin.reference = esteid_pin_ref[i]; - pin_info.attrs.pin.flags = esteid_pin_flags[i]; - pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; - pin_info.attrs.pin.min_length = esteid_pin_min[i]; - pin_info.attrs.pin.stored_length = 12; - pin_info.attrs.pin.max_length = 12; - pin_info.attrs.pin.pad_char = 0xFF; - pin_info.tries_left = 3; - pin_info.max_tries = 3; - strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label)); - pin_obj.flags = esteid_pin_flags[i]; /* Link normal PINs with PUK */ if (i < 2) { @@ -170,33 +166,29 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { /* add private keys */ for (i = 0; i < 2; i++) { - const u8 prkey_pin[2] = {1, 2}; - - const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; - const char *prkey_path[2] = {"3F00:ADF1", "3F00:ADF2"}; - const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, - SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; - const int prkey_consent[2] = {0, 1}; - - struct sc_pkcs15_prkey_info prkey_info; - struct sc_pkcs15_object prkey_obj; - - memset(&prkey_info, 0, sizeof(prkey_info)); - memset(&prkey_obj, 0, sizeof(prkey_obj)); + static const u8 prkey_pin[2] = {1, 2}; + static const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; + static const char *prkey_path[2] = {"3F00:ADF1", "3F00:ADF2"}; + static const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + static const int prkey_consent[2] = {0, 1}; + static const u8 esteid_prkey_id[2] = {0x81, 0x9F}; + + struct sc_pkcs15_prkey_info prkey_info = { + .id = {.len = 1, .value[0] = prkey_pin[i]}, + .native = 1, + .key_reference = esteid_prkey_id[i], + .field_length = field_length, + .usage = prkey_usage[i] + }; + struct sc_pkcs15_object prkey_obj = { + .auth_id = {.len = 1, .value[0] = prkey_pin[i]}, + .user_consent = prkey_consent[i], + .flags = SC_PKCS15_CO_FLAG_PRIVATE + }; sc_format_path(prkey_path[i], &prkey_info.path); - prkey_info.id.len = 1; - prkey_info.id.value[0] = prkey_pin[i]; - prkey_info.native = 1; - prkey_info.key_reference = i + 1; - prkey_info.field_length = field_length; - prkey_info.usage = prkey_usage[i]; - strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label)); - prkey_obj.auth_id.len = 1; - prkey_obj.auth_id.value[0] = prkey_pin[i]; - prkey_obj.user_consent = prkey_consent[i]; - prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add private key object"); From 03013c8de50aac63af3a57787104b70a1fc2fac7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 5 May 2025 15:20:04 +0200 Subject: [PATCH 3855/4321] pkcs11-spy: Fall back to PKCS#11 2.* interfaces rather than returning NULL function list pointer --- src/pkcs11/pkcs11-spy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 98ab07b65c..73b65f4555 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -1631,10 +1631,10 @@ spy_interface_function_list(CK_INTERFACE_PTR pInterface, CK_INTERFACE_PTR_PTR re } version = (CK_VERSION *)pInterface->pFunctionList; - if (version->major == 2) { - (*retInterface)->pFunctionList = pkcs11_spy; - } else if (version->major == 3 && version->minor == 0) { + if (version->major == 3 && version->minor == 0) { (*retInterface)->pFunctionList = pkcs11_spy_3_0; + } else { + (*retInterface)->pFunctionList = pkcs11_spy; } } From 7c41432031f62ce68e74331237029d08e64e7202 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 13 May 2025 11:34:09 +0300 Subject: [PATCH 3856/4321] Add EstEID 2018 V2 label Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2018.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 9a57d7d638..59791b492b 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -39,9 +39,9 @@ #define PUK_REF 0x02 static const struct sc_atr_table esteid_atrs[] = { - {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL} + {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} }; static const struct sc_aid IASECC_AID = { From 0960daa672be6c902e3c821ec948825b5088a286 Mon Sep 17 00:00:00 2001 From: Vassil Dimitrov Date: Thu, 8 May 2025 22:10:43 +0200 Subject: [PATCH 3857/4321] idprime: IDPrime 940 supports 3072 RSA keys Such is the key on the Gemalto IDPrime 940B card I got from the bulgarian eID provider B-Trust [1]. Tested and confirmed to work. Its ATR is as follows: 3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00 I.e. identical to the one already defined for IDPrime 940. [1] https://www.b-trust.bg/en/electronic-signatures/cards-and-readers --- src/libopensc/card-idprime.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 531ac0401d..b00872e13f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -694,6 +694,9 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); + if (card->type == SC_CARD_TYPE_IDPRIME_940) { + _sc_card_add_rsa_alg(card, 3072, flags, 0); + } if (card->type == SC_CARD_TYPE_IDPRIME_930 || card->type == SC_CARD_TYPE_IDPRIME_940) { _sc_card_add_rsa_alg(card, 4096, flags, 0); From e87c715f6410c05e8d4b2315e968f7ee8c828a0d Mon Sep 17 00:00:00 2001 From: Hendrik Donner Date: Sat, 12 Apr 2025 00:42:10 +0200 Subject: [PATCH 3858/4321] sc-hsm-tool: Use dynamic allocations where possible While the MAX_KEY value is used down the stack in card-sc-hsm, all other values can be computed or derived from the file size information from SELECT APDUs. At least a higher value than 256 for the EF PRKD can easily be reached in practice. Signed-off-by: Hendrik Donner --- src/tools/sc-hsm-tool.c | 176 ++++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 71 deletions(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 6413d6830a..b96f60b7ae 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -63,10 +63,7 @@ static char *opt_label = NULL; static int verbose = 0; // Some reasonable maximums -#define MAX_CERT 4096 -#define MAX_PRKD 256 -#define MAX_KEY 1500 -#define MAX_WRAPPED_KEY (MAX_CERT + MAX_PRKD + MAX_KEY) +#define MAX_KEY 1500 #define SEED_LENGTH 16 @@ -1329,17 +1326,18 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o sc_cardctl_sc_hsm_wrapped_key_t wrapped_key; struct sc_pin_cmd_data data; sc_path_t path; + sc_file_t *file = NULL; FILE *out = NULL; u8 fid[2]; - u8 ef_prkd[MAX_PRKD]; - u8 ef_cert[MAX_CERT]; + u8 *ef_prkd = NULL; + u8 *ef_cert = NULL; u8 wrapped_key_buff[MAX_KEY]; - u8 keyblob[MAX_WRAPPED_KEY]; - u8 *key; - u8 *ptr; + u8 *keyblob = NULL; + u8 *key = NULL; + u8 *ptr = NULL; char *lpin = NULL; - size_t key_len; - int r, ef_prkd_len, ef_cert_len; + size_t key_len = 0, keyblob_len = MAX_KEY; + int r, ef_prkd_len = 0, ef_cert_len = 0; if ((keyid < 1) || (keyid > 255)) { fprintf(stderr, "Invalid key reference (must be 0 < keyid <= 255)\n"); @@ -1400,10 +1398,16 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o /* Try to select a related EF containing the PKCS#15 description of the key */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); - r = sc_select_file(card, &path, NULL); - + r = sc_select_file(card, &path, &file); if (r == SC_SUCCESS) { - ef_prkd_len = sc_read_binary(card, 0, ef_prkd, sizeof(ef_prkd), 0); + if (!(ef_prkd = malloc(file->size))) { + r = -1; + goto err; + } + + ef_prkd_len = sc_read_binary(card, 0, ef_prkd, file->size, 0); + sc_file_free(file); + file = NULL; if (ef_prkd_len < 0) { fprintf(stderr, "Error reading PRKD file %s. Skipping.\n", sc_strerror(ef_prkd_len)); @@ -1412,6 +1416,7 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o ef_prkd_len = (int)determineLength(ef_prkd, ef_prkd_len); } } + keyblob_len += ef_prkd_len; fid[0] = EE_CERTIFICATE_PREFIX; fid[1] = (unsigned char)keyid; @@ -1419,10 +1424,14 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o /* Try to select a related EF containing the certificate for the key */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); - r = sc_select_file(card, &path, NULL); + r = sc_select_file(card, &path, &file); if (r == SC_SUCCESS) { - ef_cert_len = sc_read_binary(card, 0, ef_cert, sizeof(ef_cert), 0); + if (!(ef_cert = malloc(file->size))) { + r = -1; + goto err; + } + ef_cert_len = sc_read_binary(card, 0, ef_cert, file->size, 0); if (ef_cert_len < 0) { fprintf(stderr, "Error reading certificate %s. Skipping\n", sc_strerror(ef_cert_len)); @@ -1431,6 +1440,12 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o ef_cert_len = (int)determineLength(ef_cert, ef_cert_len); } } + keyblob_len += ef_cert_len; + + if (!(keyblob = malloc(keyblob_len))) { + r = -1; + goto err; + } ptr = keyblob; @@ -1467,20 +1482,23 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o if (out == NULL) { perror(outf); - free(key); - return -1; + r = -1; + goto err; } if (fwrite(key, 1, key_len, out) != key_len) { perror(outf); - free(key); - fclose(out); - return -1; + r = -1; } - free(key); fclose(out); - return 0; +err: + free(key); + free(keyblob); + free(ef_cert); + free(ef_prkd); + sc_file_free(file); + return r; } @@ -1528,17 +1546,14 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p { sc_cardctl_sc_hsm_wrapped_key_t wrapped_key; struct sc_pin_cmd_data data; - u8 keyblob[MAX_WRAPPED_KEY]; - const u8 *ptr,*prkd,*cert; - FILE *in = NULL; + u8 *keyblob; + const u8 *ptr, *prkd, *cert; sc_path_t path; u8 fid[2]; char *lpin = NULL; unsigned int cla, tag; int r; - size_t keybloblen; - size_t len, olen, prkd_len, cert_len; - ssize_t sz; + size_t keybloblen, len, olen, prkd_len, cert_len; if ((keyid < 1) || (keyid > 255)) { fprintf(stderr, "Invalid key reference (must be 0 < keyid <= 255)\n"); @@ -1550,34 +1565,27 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p return -1; } - in = fopen(inf, "rb"); - - if (in == NULL) { - perror(inf); - return -1; - } - - sz = fread(keyblob, 1, sizeof(keyblob), in); - fclose(in); - if (sz < 0) { + if (!fread_to_eof(inf, &keyblob, &keybloblen)) { perror(inf); - return -1; + r = -1; + goto err; } - keybloblen = sz; ptr = keyblob; if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) || (tag != SC_ASN1_TAG_SEQUENCE) ){ fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n"); - return -1; + r = -1; + goto err; } if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) || ((cla & SC_ASN1_TAG_CONSTRUCTED) == SC_ASN1_TAG_CONSTRUCTED) || (tag != SC_ASN1_TAG_OCTET_STRING) ){ fprintf(stderr, "Invalid wrapped key format (Key binary).\n"); - return -1; + r = -1; + goto err; } wrapped_key.wrapped_key = (u8 *)ptr; @@ -1610,7 +1618,8 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r == SC_SUCCESS) { fprintf(stderr, "Found existing private key description in EF with fid %02x%02x. Please remove key first, select unused key reference or use --force.\n", fid[0], fid[1]); - return -1; + r = -1; + goto err; } } @@ -1624,7 +1633,8 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r == SC_SUCCESS) { fprintf(stderr, "Found existing certificate in EF with fid %02x%02x. Please remove certificate first, select unused key reference or use --force.\n", fid[0], fid[1]); - return -1; + r = -1; + goto err; } } @@ -1647,7 +1657,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r < 0) { fprintf(stderr, "PIN verification failed with %s\n", sc_strerror(r)); - return -1; + goto err; } if (pin == NULL) { @@ -1668,17 +1678,17 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Card not initialized for key wrap\n"); - return -1; + goto err; } if (r == SC_ERROR_INCORRECT_PARAMETERS) { // Not supported or not initialized for key shares fprintf(stderr, "Wrapped key does not match DKEK\n"); - return -1; + goto err; } if (r < 0) { fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_SC_HSM_UNWRAP_KEY, *) failed with %s\n", sc_strerror(r)); - return -1; + goto err; } if (prkd_len > 0) { @@ -1686,7 +1696,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r < 0) { fprintf(stderr, "Updating private key description failed with %s\n", sc_strerror(r)); - return -1; + goto err; } } @@ -1695,26 +1705,30 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p if (r < 0) { fprintf(stderr, "Updating certificate failed with %s\n", sc_strerror(r)); - return -1; + goto err; } } printf("Key successfully imported\n"); - return 0; + +err: + free(keyblob); + return r; } static int export_key(sc_card_t *card, int keyid, const char *outf) { sc_path_t path; + sc_file_t *file = NULL; FILE *outfp = NULL; u8 fid[2]; - u8 ef_cert[MAX_CERT]; - u8 dev_aut_cert[MAX_CERT]; - u8 dica[MAX_CERT]; + u8 *ef_cert = NULL; + u8 *dev_aut_cert = NULL; + u8 *dica = NULL; u8 tag = SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE; /* 0x30 */ - int r = 0, ef_cert_len, total_certs_len; - size_t dev_aut_cert_len, dica_len; + int r = 0, ef_cert_len = 0, total_certs_len; + size_t dev_aut_cert_len = 0, dica_len = 0; u8 *data = NULL, *out = NULL, *ptr; size_t datalen, outlen; @@ -1729,19 +1743,26 @@ static int export_key(sc_card_t *card, int keyid, const char *outf) /* Try to select a related EF containing the certificate for the key */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); - r = sc_select_file(card, &path, NULL); + r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS) { fprintf(stderr, "Wrong key reference (-i %d)? Failed to select file: %s\n", keyid, sc_strerror(r)); return -1; } - ef_cert_len = sc_read_binary(card, 0, ef_cert, sizeof(ef_cert), 0); + if (!(ef_cert = malloc(file->size))) { + r = -1; + goto err; + } + + ef_cert_len = sc_read_binary(card, 0, ef_cert, file->size, 0); if (ef_cert_len < 0) { fprintf(stderr, "Error reading certificate %s. Skipping\n", sc_strerror(ef_cert_len)); ef_cert_len = 0; } else { ef_cert_len = (int)determineLength(ef_cert, ef_cert_len); } + sc_file_free(file); + file = NULL; /* C_DevAut */ fid[0] = 0x2F; @@ -1750,30 +1771,42 @@ static int export_key(sc_card_t *card, int keyid, const char *outf) /* Read concatenation of both certificates */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); - r = sc_select_file(card, &path, NULL); + r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to select certificates: %s\n", sc_strerror(r)); - return -1; + r = -1; + goto err; } - total_certs_len = sc_read_binary(card, 0, dev_aut_cert, sizeof(dev_aut_cert), 0); + if (!(dev_aut_cert = malloc(file->size))) { + r = -1; + goto err; + } + + total_certs_len = sc_read_binary(card, 0, dev_aut_cert, file->size, 0); if (total_certs_len < 0) { fprintf(stderr, "Error reading certificate: %s\n", sc_strerror(total_certs_len)); - return -1; + r = -1; + goto err; } else { dev_aut_cert_len = determineLength(dev_aut_cert, total_certs_len); dica_len = total_certs_len - dev_aut_cert_len; + if (!(dica = malloc(dica_len))) { + r = -1; + goto err; + } memcpy(dica, dev_aut_cert + dev_aut_cert_len, dica_len); } if (dica_len == 0) { fprintf(stderr, "Could not determine device issuer certificate\n"); - return -1; + r = -1; + goto err; } if ((outfp = fopen(outf, "r"))) { fprintf(stderr, "Output file '%s' already exists\n", outf); - fclose(outfp); - return -1; + r = -1; + goto err; } fprintf(stderr, "Warning: Device certificate chain not verified!\n"); @@ -1809,16 +1842,17 @@ static int export_key(sc_card_t *card, int keyid, const char *outf) if (fwrite(out, 1, outlen, outfp) != (size_t)outlen) { perror(outf); r = -1; - goto err; } err: if (outfp) fclose(outfp); - if (out) - free(out); - if (data) - free(data); + free(out); + free(data); + free(dica); + free(dev_aut_cert); + free(ef_cert); + sc_file_free(file); return r; } From c1448c4c8896f57628466e25801ef52b6f4abd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 14 May 2025 10:20:21 +0200 Subject: [PATCH 3859/4321] sc-hsm-tool: Free keyblob when error occurs Thanks Coverity CID 465325 --- src/tools/sc-hsm-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index b96f60b7ae..44ae92a0b0 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1453,7 +1453,7 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o key_len = 0; r = wrap_with_tag(0x04, wrapped_key.wrapped_key, wrapped_key.wrapped_key_length, &key, &key_len); - LOG_TEST_RET(ctx, r, "Out of memory"); + LOG_TEST_GOTO_ERR(ctx, r, "Out of memory"); memcpy(ptr, key, key_len); ptr += key_len; @@ -1476,7 +1476,7 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o // Encode key, key description and certificate object in sequence r = wrap_with_tag(0x30, keyblob, ptr - keyblob, &key, &key_len); - LOG_TEST_RET(ctx, r, "Out of memory"); + LOG_TEST_GOTO_ERR(ctx, r, "Out of memory"); out = fopen(outf, "wb"); From 876e9e2f5529a8bf8182587d4424e56d0aaa4954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 14 May 2025 10:32:15 +0200 Subject: [PATCH 3860/4321] pkcs15-esteid2025: Fix memory leak when selecting file Thanks Coverity CID 462004 --- src/libopensc/pkcs15-esteid2025.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-esteid2025.c b/src/libopensc/pkcs15-esteid2025.c index 5b7e9522cb..8514667647 100644 --- a/src/libopensc/pkcs15-esteid2025.c +++ b/src/libopensc/pkcs15-esteid2025.c @@ -50,13 +50,16 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) /* Read document number to be used as serial */ sc_format_path("DFDD5007", &tmppath); - LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); + r = sc_select_file(card, &tmppath, NULL); + if (r < 0) { + free(buff); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } r = sc_read_binary(card, 0, buff, buflen, 0); if (r < 0) { free(buff); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } - LOG_TEST_RET(card->ctx, r, "read document number failed"); for (j = 0; j < buflen; j++) { if (!isalnum(buff[j])) { From bd7de44b3971d0b4f66140ce7afb09408ffdbcd6 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 13 May 2025 12:54:59 +0300 Subject: [PATCH 3861/4321] Use iso7816_select_aid Signed-off-by: Raul Metsma --- src/libopensc/card-authentic.c | 38 ++------------------- src/libopensc/card-edo.c | 7 +--- src/libopensc/card-gemsafeV1.c | 32 ++---------------- src/libopensc/card-iasecc.c | 36 ++------------------ src/libopensc/card-isoApplet.c | 60 ++++------------------------------ src/libopensc/card-myeid.c | 35 +------------------- src/libopensc/card-nqApplet.c | 14 +++----- src/libopensc/card-piv.c | 31 ++---------------- src/libopensc/card-sc-hsm.c | 18 +++------- src/libopensc/gp.c | 19 ++--------- src/libopensc/iso7816.c | 25 ++++++++++++++ src/libopensc/opensc.h | 18 ++++++++++ 12 files changed, 74 insertions(+), 259 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index fc53d31bc7..5a2a07b6e9 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -385,38 +385,6 @@ authentic_get_cplc(struct sc_card *card) return SC_SUCCESS; } - -static int -authentic_select_aid(struct sc_card *card, unsigned char *aid, size_t aid_len, - unsigned char *out, size_t *out_len) -{ - struct sc_apdu apdu; - unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; - int rv; - - /* Select Card Manager (to deselect previously selected application) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = aid_len; - apdu.data = aid; - apdu.datalen = aid_len; - apdu.resplen = sizeof(apdu_resp); - apdu.resp = apdu_resp; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, rv, "Cannot select AID"); - - if (out && out_len) { - if (*out_len < apdu.resplen) - LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID"); - memcpy(out, apdu.resp, apdu.resplen); - } - - return SC_SUCCESS; -} - - static int authentic_match_card(struct sc_card *card) { @@ -456,7 +424,7 @@ authentic_init_oberthur_authentic_3_2(struct sc_card *card) card->sm_ctx.ops.free_sm_apdu = authentic_sm_free_wrapped_apdu; #endif - rv = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); + rv = iso7816_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); LOG_TEST_RET(ctx, rv, "AuthentIC application select error"); rv = authentic_select_mf(card, NULL); @@ -2085,7 +2053,7 @@ static int authentic_card_reader_lock_obtained(sc_card_t *card, int was_reset) if (was_reset > 0 && card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { - r = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); + r = iso7816_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); } LOG_FUNC_RETURN(card->ctx, r); @@ -2321,7 +2289,7 @@ int authentic_logout(sc_card_t *card) int r = SC_ERROR_NOT_SUPPORTED; if (card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { - r = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); + r = iso7816_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); } return r; diff --git a/src/libopensc/card-edo.c b/src/libopensc/card-edo.c index 1c49cabfe4..eb18215c5f 100644 --- a/src/libopensc/card-edo.c +++ b/src/libopensc/card-edo.c @@ -164,12 +164,7 @@ static int edo_select_ef(struct sc_card* card, const u8 path[2], struct edo_buff static int edo_select_name(struct sc_card* card, const u8* name, size_t namelen, struct edo_buff* buff) { LOG_FUNC_CALLED(card->ctx); - struct sc_apdu apdu; - sc_format_apdu_ex(&apdu, 00, 0xA4, 0x04, 0x00, name, namelen, buff->val, sizeof buff->val); - LOG_TEST_RET(card->ctx, sc_transmit_apdu(card, &apdu), "APDU transmit failed"); - LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "SW check failed"); - buff->len = apdu.resplen; - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, iso7816_select_aid(card, name, namelen, buff->val, &buff->len)); } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 984563f08b..04ad57fed1 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -120,32 +120,6 @@ static int get_conf_aid(sc_card_t *card, u8 *aid, size_t *len) return sc_hex_to_bin(str_aid, aid, len); } -static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len) -{ - int r; - u8 buf[MAX_RESP_BUFFER_SIZE]; - struct sc_context *ctx = card->ctx; - struct sc_apdu apdu; - - SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); - apdu.lc = aid_len; - apdu.data = aid; - apdu.datalen = aid_len; - apdu.resp = buf; - apdu.le = 256; - apdu.resplen = sizeof(buf); - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, r, "APDU transmit failed"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r); - - return SC_SUCCESS; -} - static int gemsafe_match_card(sc_card_t *card) { int i; @@ -191,7 +165,7 @@ static int gemsafe_init(struct sc_card *card) * applet twice in gp_select_applet */ card->lock_count++; /* SELECT applet */ - r = gp_select_applet(card, exdata->aid, exdata->aid_len); + r = iso7816_select_aid(card, exdata->aid, exdata->aid_len, NULL, NULL); if (r < 0) { free(exdata); sc_log(card->ctx, "applet selection failed\n"); @@ -577,7 +551,7 @@ static int gemsafe_card_reader_lock_obtained(sc_card_t *card, int was_reset) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (was_reset > 0 && exdata) { - r = gp_select_applet(card, exdata->aid, exdata->aid_len); + r = iso7816_select_aid(card, exdata->aid, exdata->aid_len, NULL, NULL); } LOG_FUNC_RETURN(card->ctx, r); @@ -587,7 +561,7 @@ static int gemsafe_logout(sc_card_t *card) { gemsafe_exdata *exdata = (gemsafe_exdata *)card->drv_data; - return gp_select_applet(card, exdata->aid, exdata->aid_len); + return iso7816_select_aid(card, exdata->aid, exdata->aid_len, NULL, NULL); } static struct sc_card_driver *sc_get_driver(void) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 4ecadc8bfb..4cb4ec7192 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -344,37 +344,6 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) LOG_FUNC_RETURN(ctx, rv); } - -static int -iasecc_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, size_t *out_len) -{ - struct sc_apdu apdu; - unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; - int rv; - - LOG_FUNC_CALLED(card->ctx); - - /* Select application (deselect previously selected application) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = aid->len; - apdu.data = aid->value; - apdu.datalen = aid->len; - apdu.resplen = sizeof(apdu_resp); - apdu.resp = apdu_resp; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, rv, "Cannot select AID"); - - if (*out_len < apdu.resplen) - LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID"); - memcpy(out, apdu.resp, apdu.resplen); - - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); -} - - static int iasecc_match_card(struct sc_card *card) { @@ -556,13 +525,12 @@ iasecc_mi_match(struct sc_card *card) { struct sc_context *ctx = card->ctx; unsigned char resp[0x100]; - size_t resp_len; + size_t resp_len = sizeof(resp); int rv = 0; LOG_FUNC_CALLED(ctx); - resp_len = sizeof(resp); - rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len); + rv = iso7816_select_aid(card, MIIASECC_AID.value, MIIASECC_AID.len, resp, &resp_len); LOG_TEST_RET(ctx, rv, "IASECC: failed to select MI IAS/ECC applet"); if (!card->ef_atr) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 87be918e2d..e0f5c70f64 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -92,45 +92,6 @@ static struct isoapplet_supported_ec_curves { {{{-1}}, 0, 0} /* This entry must not be touched. */ }; -/* - * SELECT an applet on the smartcard. (Not in the emulated filesystem.) - * The response will be written to resp. - * - * @param[in] card - * @param[in] aid The applet ID. - * @param[in] aid_len The length of aid. - * - * @return SC_SUCCESS: The applet is present and could be selected. - * any other: Transmit failure or the card returned an error. - * The card will return an error when the applet is - * not present. - */ -static int -isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len) -{ - int rv; - sc_context_t *ctx = card->ctx; - sc_apdu_t apdu; - - LOG_FUNC_CALLED(card->ctx); - - if(aid_len > SC_MAX_APDU_BUFFER_SIZE) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xa4, 0x04, 0x00); - apdu.lc = aid_len; - apdu.data = aid; - apdu.datalen = aid_len; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit failure."); - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, rv, "Card returned error"); - - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); -} - static int isoApplet_finish(sc_card_t *card) { @@ -150,7 +111,7 @@ isoApplet_match_card(sc_card_t *card) { int rv; - rv = isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); + rv = iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), NULL, NULL); if(rv != SC_SUCCESS) { return 0; @@ -169,19 +130,10 @@ isoApplet_get_info(sc_card_t * card, struct isoApplet_drv_data * drvdata) { if(rv == SC_ERROR_INS_NOT_SUPPORTED) { /* INS not supported. This is an older IsoApplet that might return the * applet information upon selection. For backward compatibility, try this. */ - sc_apdu_t apdu; - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); - apdu.lc = sizeof(isoApplet_aid); - apdu.data = isoApplet_aid; - apdu.datalen = sizeof(isoApplet_aid); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit failure."); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + size_t rlen = sizeof(rbuf); + rv = iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), rbuf, &rlen); LOG_TEST_RET(ctx, rv, "Error selecting applet."); - rv = (int) apdu.resplen; + rv = (int)rlen; } if (rv < 0) { @@ -1285,7 +1237,7 @@ static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (was_reset > 0) { - r = isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); + r = iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), NULL, NULL); } LOG_FUNC_RETURN(card->ctx, r); @@ -1293,7 +1245,7 @@ static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) static int isoApplet_logout(sc_card_t *card) { - return isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); + return iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), NULL, NULL); } static struct sc_card_driver *sc_get_driver(void) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 643ad08690..b8bb46b2c1 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -139,38 +139,6 @@ static int myeid_match_card(struct sc_card *card) return 0; } -static int -myeid_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, size_t *out_len) -{ - struct sc_apdu apdu; - unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; - int rv; - - /* Select application (deselect previously selected application) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = aid->len; - apdu.data = aid->value; - apdu.datalen = aid->len; - apdu.resplen = sizeof(apdu_resp); - apdu.resp = apdu_resp; - - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, rv, "Cannot select AID"); - - if (*out_len > 0) { - if (*out_len < apdu.resplen) - LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID - response buffer too small."); - if (out == NULL) - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot select AID - invalid arguments."); - memcpy(out, apdu.resp, apdu.resplen); - *out_len = apdu.resplen; - } - - return SC_SUCCESS; -} - static int myeid_load_options(sc_context_t *ctx, myeid_private_data_t *priv) { int r; @@ -206,7 +174,6 @@ static int myeid_init(struct sc_card *card) u8 appletInfo[20]; size_t appletInfoLen; myeid_card_caps_t card_caps; - size_t resp_len = 0; static struct sc_aid myeid_aid = { "\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35", 0x0C }; int rv = 0; void *old_drv_data = card->drv_data; @@ -236,7 +203,7 @@ static int myeid_init(struct sc_card *card) card->drv_data = priv; /* Ensure that the MyEID applet is selected. */ - rv = myeid_select_aid(card, &myeid_aid, NULL, &resp_len); + rv = iso7816_select_aid(card, myeid_aid.value, myeid_aid.len, NULL, NULL); LOG_TEST_GOTO_ERR(card->ctx, rv, "Failed to select MyEID applet."); /* find out MyEID version */ diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index f9075b948c..5d5f02834f 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -107,22 +107,16 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor { int rv; sc_context_t *ctx = card->ctx; - sc_apdu_t apdu; u8 buffer[APPLET_VERSION_LEN + APPLET_MEMTYPE_LEN + APPLET_SERIALNR_LEN + 2]; size_t cb_buffer = sizeof(buffer); size_t cb_aid = sizeof(nqapplet_aid); LOG_FUNC_CALLED(card->ctx); - sc_format_apdu_ex(&apdu, 0x00, 0xA4, 0x04, 0x00, nqapplet_aid, cb_aid, buffer, cb_buffer); + rv = iso7816_select_aid(card, nqapplet_aid, cb_aid, buffer, &cb_buffer); + LOG_TEST_RET(card->ctx, rv, "Failed to select NQ-Applet."); - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit failure."); - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, rv, "Card returned error"); - - if (apdu.resplen < APPLET_VERSION_LEN + APPLET_MEMTYPE_LEN + APPLET_SERIALNR_LEN) { + if (cb_buffer < APPLET_VERSION_LEN + APPLET_MEMTYPE_LEN + APPLET_SERIALNR_LEN) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_WRONG_LENGTH); } @@ -138,7 +132,7 @@ static int select_nqapplet(sc_card_t *card, u8 *version_major, u8 *version_minor *serial_nr_len = cb; } - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); } /* driver operations API */ diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 9818847619..8a4dc937c9 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2833,31 +2833,6 @@ static int piv_generate_key(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, size_t *responselen) -{ - sc_apdu_t apdu; - int r; - - LOG_FUNC_CALLED(card->ctx); - - sc_format_apdu(card, &apdu, - response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = aidlen; - apdu.data = aid; - apdu.datalen = aidlen; - apdu.resp = response; - apdu.resplen = responselen ? *responselen : 0; - apdu.le = response == NULL ? 0 : 256; /* could be 21 for fci */ - - r = sc_transmit_apdu(card, &apdu); - if (responselen) - *responselen = apdu.resplen; - LOG_TEST_RET(card->ctx, r, "PIV select failed"); - - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); -} - /* find the PIV AID on the card. If card->type already filled in, * then look for specific AID only */ @@ -2888,7 +2863,7 @@ static int piv_find_aid(sc_card_t * card) * that we know about. */ - r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen); + r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen); if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) { LOG_FUNC_RETURN(card->ctx,SC_SUCCESS); /* no need to parse again, same as last time */ @@ -6265,8 +6240,8 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) if (r < 0) { if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { - r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "piv_select_aid card->type:%d r:%d\n", card->type, r); + r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "iso7816_select_aid card->type:%d r:%d\n", card->type, r); } else { r = 0; /* can't do anything with this card, hope there was no interference */ } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cd22f543eb..d2e5bc6fd8 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -331,24 +331,16 @@ static int sc_hsm_encode_sopin(const u8 *sopin, u8 *sopinbin) static int sc_hsm_soc_select_minbioclient(sc_card_t *card) { - sc_apdu_t apdu; - struct sc_aid minBioClient_aid = { - { 0xFF,'m','i','n','B','i','o','C','l','i','e','n','t',0x01 }, 14 - }; + static const struct sc_aid minBioClient_aid = { + {0xFF, 'm', 'i', 'n', 'B', 'i', 'o', 'C', 'l', 'i', 'e', 'n', 't', 0x01}, + 14 + }; /* Select MinBioClient */ #ifdef ENABLE_SM sc_sm_stop(card); #endif - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); - apdu.data = minBioClient_aid.value; - apdu.datalen = minBioClient_aid.len; - apdu.lc = minBioClient_aid.len; - LOG_TEST_RET(card->ctx, - sc_transmit_apdu(card, &apdu), - "APDU transmit failed"); - - return sc_check_sw(card, apdu.sw1, apdu.sw2); + return iso7816_select_aid(card, minBioClient_aid.value, minBioClient_aid.len, NULL, NULL); } static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index aed670399a..32e399782d 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -48,23 +48,10 @@ static const struct sc_aid gp_isd_rid = { int gp_select_aid(struct sc_card *card, const struct sc_aid *aid) { - struct sc_apdu apdu; int rv; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); - apdu.lc = aid->len; - apdu.data = aid->value; - apdu.datalen = aid->len; - - rv = sc_transmit_apdu(card, &apdu); - if (rv < 0) - return rv; - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (rv < 0) - return rv; - - return (int)apdu.resplen; + LOG_FUNC_CALLED(card->ctx); + rv = iso7816_select_aid(card, aid->value, aid->len, NULL, NULL); + LOG_FUNC_RETURN(card->ctx, rv); } /* Select the Open Platform Card Manager */ diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index e17549cd18..8b07e6af0d 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1393,7 +1393,32 @@ static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, si LOG_FUNC_RETURN(card->ctx, r); } +int +iso7816_select_aid(struct sc_card *card, const u8 *req, + size_t reqlen, u8 *resp, size_t *resplen) +{ + struct sc_context *ctx = card->ctx; + struct sc_apdu apdu; + int rv; + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); + + sc_format_apdu(card, &apdu, resp == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 0xA4, 0x04, resp == NULL ? 0x0C : 0x00); + apdu.lc = reqlen; + apdu.data = req; + apdu.datalen = reqlen; + apdu.resp = resp; + apdu.resplen = resp == NULL ? 0 : *resplen; + apdu.le = resp == NULL ? 0 : 256; + + rv = sc_transmit_apdu(card, &apdu); + if (resplen) + *resplen = apdu.resplen; + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_FUNC_RETURN(ctx, rv); +} static int iso7816_init(struct sc_card *card) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index ac09b41a4b..365afbcf3b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1763,6 +1763,24 @@ int iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len); +/* + * @brief Send a SELECT AID APDU to the smart card. + * + * This function constructs and transmits a SELECT command using the provided + * AID (Application Identifier) to select an application on the card. + * + * @param[in] card Pointer to the smart card context. + * @param[in] req Pointer to the AID to be selected. + * @param[in] reqlen Length of the AID. + * @param[out] resp Optional. Buffer to receive the response from the card. + * May be NULL if the response is not needed. + * @param[in,out] resplen Optional. On input, the maximum length of the response buffer. + * On output, the actual length of the response. May be NULL + * if resp is NULL or response length is not needed. + */ +int iso7816_select_aid(struct sc_card *card, const u8 *req, + size_t reqlen, u8 *resp, size_t *resplen); + /** * Free a buffer returned by OpenSC. * Use this instead your C libraries free() to free memory allocated by OpenSC. From e88272d556f51dde2e789cf8d9afafd8b490cf67 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 May 2025 08:42:39 +0200 Subject: [PATCH 3862/4321] doc: Add more infos about gdb debugging of oss-fuzz --- src/tests/fuzzing/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md index 9dcd82bc75..1225e8176b 100644 --- a/src/tests/fuzzing/README.md +++ b/src/tests/fuzzing/README.md @@ -42,6 +42,15 @@ After that, you can download reproducer from the oss-fuzz dashboard and run it l ``` python3 infra/helper.py reproduce opensc fuzz_pkcs15_decode /path/to/testcase ``` +For creating a docker image for debugging the issue, run the following command: +``` +python infra/helper.py shell base-runner-debug +``` +This gives a shell inside a Docker image containing GDB. Now you can reproduce the issue and inspect the backtrace: +``` +# Shell inside Docker debug image +gdb -ex 'break __sanitizer::Die' -ex 'run' --args /out/opensc/fuzz_pkcs15_decode /out/opensc/testcase +``` ### Expanding incomplete backtraces Sometimes the backtrace visible in the oss-fuzz dashboard is not useful, for example showing only part of the From 953986f65db61871bbbff72788d861d67d5140c6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 May 2025 00:24:32 +0200 Subject: [PATCH 3863/4321] fixed Stack-buffer-overflow WRITE in GET RESPONSE The do-while loop in apdu.c requires the output data to be set in any case, otherwise non existent data may be copied to the output data. fixes https://issues.oss-fuzz.com/issues/416351800 fixes https://issues.oss-fuzz.com/issues/416295951 --- src/libopensc/card-nqApplet.c | 11 ++++++----- src/libopensc/iso7816.c | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 5d5f02834f..025847bbbf 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -184,9 +184,10 @@ static int nqapplet_finish(struct sc_card *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp) +static int +nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp) { - struct sc_apdu apdu; + struct sc_apdu apdu = {0}; int rv; size_t resplen; @@ -198,12 +199,12 @@ static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.resplen == 0) { - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); - } *cb_resp = apdu.resplen; + if (apdu.resplen == 0) { + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { rv = SC_SUCCESS; } else if (apdu.sw1 == 0x61) { diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 8b07e6af0d..36b9e016da 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -920,11 +920,12 @@ iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen == 0) - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); *count = apdu.resplen; + if (apdu.resplen == 0) { + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) r = 0; /* no more data to read */ else if (apdu.sw1 == 0x61) From d48c30853070f08518ad850e1f30848fb2fa254f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 May 2025 11:26:49 +0200 Subject: [PATCH 3864/4321] piv-tool: Fix few more possible memory leaks caught by oss-fuzz Third time the charm. I think the relevant part that the fuzzer was catching is the Ed25519 key generation, which is not supported in the OpenSSL 1.1.1 used by the fuzzer images. Verified locally that the given input no longer shows memory leak. Remaining fixes around add some more missing checks or memory cleanup on very unlikely conditions. https://issues.oss-fuzz.com/issues/397209407 Signed-off-by: Jakub Jelen --- src/tools/piv-tool.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 3dee5efaf9..1c2d912a84 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -423,6 +423,7 @@ static int gen_key(const char * key_info) goto out; } + OSSL_PARAM_BLD_free(bld); BN_free(newkey_n); BN_free(newkey_e); @@ -448,17 +449,20 @@ static int gen_key(const char * key_info) } else if (nid == NID_ED25519 || nid == NID_X25519) { #if OPENSSL_VERSION_NUMBER < 0x30000000L fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n"); - return -1; + r = 1; + goto out; #else if (!keydata.ecpoint) { fprintf(stderr, "gen_key failed\n"); - return 1; + r = 1; + goto out; } evpkey = EVP_PKEY_new_raw_public_key(nid, NULL, keydata.ecpoint, keydata.ecpoint_len); if (!evpkey) { sc_log_openssl(ctx); fprintf(stderr, "gen key failed ti copy 25519 pubkey\n"); - return 1; + r = 1; + goto out; } if (verbose) @@ -524,12 +528,21 @@ static int gen_key(const char * key_info) } #if OPENSSL_VERSION_NUMBER < 0x30000000L eckey = EC_KEY_new(); + if (eckey == NULL) { + sc_log_openssl(ctx); + fprintf(stderr, "EC_KEY_new failed\n"); + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); + r = 1; + goto out; + } r = EC_KEY_set_group(eckey, ecgroup); EC_GROUP_free(ecgroup); if (r == 0) { sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_group failed\n"); EC_POINT_free(ecpoint); + EC_KEY_free(eckey); r = 1; goto out; } @@ -538,6 +551,7 @@ static int gen_key(const char * key_info) if (r == 0) { sc_log_openssl(ctx); fprintf(stderr, "EC_KEY_set_public_key failed\n"); + EC_KEY_free(eckey); r = 1; goto out; } @@ -546,6 +560,7 @@ static int gen_key(const char * key_info) EC_KEY_print_fp(stdout, eckey, 0); if (EVP_PKEY_assign_EC_KEY(evpkey, eckey) != 1) { + EC_KEY_free(eckey); sc_log_openssl(ctx); r = 1; goto out; From fa313a8821e4caca4cbfc31101e553729d810986 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 Apr 2025 01:38:05 +0200 Subject: [PATCH 3865/4321] Removed internal caching for current EF/DF This fixes concurrent access to the card from different threads or processes at the cost of potentially causing more card interactions than necessary. Since the card driver for IAS/ECC uses the cached path additionally for managing the ACLs in SM context, this state tracking was moved to a card driver private scope. --- src/libopensc/apdu.c | 1 - src/libopensc/card-atrust-acos.c | 130 ++-------------------- src/libopensc/card-authentic.c | 185 ------------------------------- src/libopensc/card-entersafe.c | 114 ++----------------- src/libopensc/card-epass2003.c | 115 ++----------------- src/libopensc/card-flex.c | 98 +--------------- src/libopensc/card-iasecc.c | 166 ++++++++++----------------- src/libopensc/card-mcrd.c | 2 - src/libopensc/card-oberthur.c | 5 - src/libopensc/card-starcos.c | 33 +----- src/libopensc/card.c | 48 -------- src/libopensc/iasecc-sm.c | 3 +- src/libopensc/iasecc.h | 11 ++ src/libopensc/libopensc.exports | 1 - src/libopensc/opensc.h | 14 --- 15 files changed, 104 insertions(+), 822 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 099d152aa8..51b3aaac1f 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -636,7 +636,6 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) } if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { - sc_invalidate_cache(card); /* give card driver a chance to react on resets */ if (card->ops->card_reader_lock_obtained) card->ops->card_reader_lock_obtained(card, 1); diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 2acdb11f09..43a498e2a7 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -255,11 +255,6 @@ static int atrust_acos_select_aid(struct sc_card *card, if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - /* update cache */ - card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; - card->cache.current_path.len = len; - memcpy(card->cache.current_path.value, aid, len); - if (file_out) { sc_file_t *file = sc_file_new(); if (!file) @@ -331,26 +326,11 @@ static int atrust_acos_select_fid(struct sc_card *card, if (apdu.sw1 != 0x61 && (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - /* update cache */ - if (bIsDF) { - card->cache.current_path.type = SC_PATH_TYPE_PATH; - card->cache.current_path.value[0] = 0x3f; - card->cache.current_path.value[1] = 0x00; - if (id_hi == 0x3f && id_lo == 0x00) - card->cache.current_path.len = 2; - else { - card->cache.current_path.len = 4; - card->cache.current_path.value[2] = id_hi; - card->cache.current_path.value[3] = id_lo; - } - } - if (file_out) { sc_file_t *file = sc_file_new(); if (!file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (id_hi << 8) + id_lo; - file->path = card->cache.current_path; + file->id = (id_hi << 8) + id_lo; if (bIsDF) { /* we have a DF */ @@ -385,48 +365,22 @@ static int atrust_acos_select_file(struct sc_card *card, u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; int r; size_t i, pathlen; - char pbuf[SC_MAX_PATH_STRING_SIZE]; - - - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, - "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? - "aid" : "path", - card->cache.valid ? "valid" : "invalid", pbuf, - card->cache.current_path.len); memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; - if (in_path->type == SC_PATH_TYPE_FILE_ID) - { /* SELECT EF/DF with ID */ + if (in_path->type == SC_PATH_TYPE_FILE_ID) { + /* SELECT EF/DF with ID */ /* Select with 2byte File-ID */ if (pathlen != 2) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); return atrust_acos_select_fid(card, path[0], path[1], file_out); - } - else if (in_path->type == SC_PATH_TYPE_DF_NAME) - { /* SELECT DF with AID */ + } else if (in_path->type == SC_PATH_TYPE_DF_NAME) { + /* SELECT DF with AID */ /* Select with 1-16byte Application-ID */ - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME - && card->cache.current_path.len == pathlen - && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) - { - sc_log(card->ctx, "cache hit\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); - } - else - return atrust_acos_select_aid(card, pathbuf, pathlen, file_out); - } - else if (in_path->type == SC_PATH_TYPE_PATH) - { + return atrust_acos_select_aid(card, pathbuf, pathlen, file_out); + } else if (in_path->type == SC_PATH_TYPE_PATH) { u8 n_pathbuf[SC_MAX_PATH_SIZE]; - size_t bMatch = 0; /* Select with path (sequence of File-IDs) */ /* ACOS only supports one @@ -450,72 +404,12 @@ static int atrust_acos_select_file(struct sc_card *card, pathlen += 2; } - /* check current working directory */ - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_PATH - && card->cache.current_path.len >= 2 - && card->cache.current_path.len <= pathlen ) - { - for (i=0; i < card->cache.current_path.len; i+=2) - if (card->cache.current_path.value[i] == path[i] - && card->cache.current_path.value[i+1] == path[i+1] ) - bMatch += 2; + for (i = 0; i < pathlen - 2; i += 2) { + r = atrust_acos_select_fid(card, path[i], path[i + 1], NULL); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } - - if (card->cache.valid && bMatch > 2) { - if ( pathlen - bMatch == 2 ) - /* we are in the right directory */ - return atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], file_out); - else if ( pathlen - bMatch > 2 ) - { - /* two more steps to go */ - sc_path_t new_path; - - /* first step: change directory */ - r = atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - memset(&new_path, 0, sizeof(sc_path_t)); - new_path.type = SC_PATH_TYPE_PATH; - new_path.len = pathlen - bMatch-2; - memcpy(new_path.value, &(path[bMatch+2]), new_path.len); - /* final step: select file */ - return atrust_acos_select_file(card, &new_path, file_out); - } - else /* if (bMatch - pathlen == 0) */ - { - /* done: we are already in the - * requested directory */ - sc_log(card->ctx, "cache hit\n"); - /* copy file info (if necessary) */ - if (file_out) { - sc_file_t *file = sc_file_new(); - if (!file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (path[pathlen-2] << 8) + - path[pathlen-1]; - file->path = card->cache.current_path; - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->size = 0; - file->namelen = 0; - file->magic = SC_FILE_MAGIC; - *file_out = file; - } - /* nothing left to do */ - return SC_SUCCESS; - } - } else { - /* no usable cache */ - for ( i=0; ictx, r, "SELECT FILE (DF-ID) failed"); - } - return atrust_acos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out); - } - } - else + return atrust_acos_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); + } else SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 5a2a07b6e9..297f40e71f 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -89,7 +89,6 @@ static int authentic_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_dat static int authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, int *tries_left); static int authentic_select_mf(struct sc_card *card, struct sc_file **file_out); static int authentic_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr); -static void authentic_debug_select_file(struct sc_card *card, const struct sc_path *path); #ifdef ENABLE_SM static int authentic_sm_open(struct sc_card *card); @@ -488,10 +487,6 @@ authentic_erase_binary(struct sc_card *card, unsigned int offs, size_t count, un if (!count) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "'ERASE BINARY' with ZERO count not supported"); - if (card->cache.valid && card->cache.current_ef) - sc_log(ctx, "current_ef(type=%i) %s", card->cache.current_ef->path.type, - sc_print_path(&card->cache.current_ef->path)); - buf_zero = calloc(1, count); if (!buf_zero) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cannot allocate buff 'zero'"); @@ -533,41 +528,6 @@ authentic_set_current_files(struct sc_card *card, struct sc_path *path, LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } - if (file->type == SC_FILE_TYPE_DF) { - struct sc_path cur_df_path; - - memset(&cur_df_path, 0, sizeof(cur_df_path)); - if (card->cache.valid && card->cache.current_df) { - cur_df_path = card->cache.current_df->path; - sc_file_free(card->cache.current_df); - } - card->cache.current_df = NULL; - sc_file_dup(&card->cache.current_df, file); - - if (cur_df_path.len) { - if (cur_df_path.len + card->cache.current_df->path.len > sizeof card->cache.current_df->path.value - || cur_df_path.len > sizeof card->cache.current_df->path.value) { - sc_file_free(file); - LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); - } - memmove(card->cache.current_df->path.value + cur_df_path.len, - card->cache.current_df->path.value, - card->cache.current_df->path.len); - memcpy(card->cache.current_df->path.value, cur_df_path.value, cur_df_path.len); - card->cache.current_df->path.len += cur_df_path.len; - } - - sc_file_free(card->cache.current_ef); - card->cache.current_ef = NULL; - - card->cache.valid = 1; - } - else { - sc_file_free(card->cache.current_ef); - card->cache.current_ef = NULL; - sc_file_dup(&card->cache.current_ef, file); - } - if (file_out) *file_out = file; else @@ -593,16 +553,6 @@ authentic_select_mf(struct sc_card *card, struct sc_file **file_out) sc_format_path("3F00", &mfpath); mfpath.type = SC_PATH_TYPE_PATH; - if (card->cache.valid == 1 - && card->cache.current_df - && card->cache.current_df->path.len == 2 - && !memcmp(card->cache.current_df->path.value, "\x3F\x00", 2)) { - if (file_out) - sc_file_dup(file_out, card->cache.current_df); - - LOG_FUNC_RETURN(ctx, SC_SUCCESS); - } - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0x00, 0x00); apdu.resp = rbuf; @@ -613,107 +563,12 @@ authentic_select_mf(struct sc_card *card, struct sc_file **file_out) rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, rv, "authentic_select_file() check SW failed"); - if (card->cache.valid == 1) { - sc_file_free(card->cache.current_df); - card->cache.current_df = NULL; - - sc_file_free(card->cache.current_ef); - card->cache.current_ef = NULL; - } - rv = authentic_set_current_files(card, &mfpath, apdu.resp, apdu.resplen, file_out); LOG_TEST_RET(ctx, rv, "authentic_select_file() cannot set 'current_file'"); LOG_FUNC_RETURN(ctx, rv); } - -static int -authentic_reduce_path(struct sc_card *card, struct sc_path *path) -{ - struct sc_context *ctx = card->ctx; - struct sc_path in_path, cur_path; - size_t offs; - - LOG_FUNC_CALLED(ctx); - - if (!path || path->len <= 2 || path->type == SC_PATH_TYPE_DF_NAME) - LOG_FUNC_RETURN(ctx, SC_SUCCESS); - - if (!card->cache.valid || !card->cache.current_df) - LOG_FUNC_RETURN(ctx, 0); - - in_path = *path; - cur_path = card->cache.current_df->path; - - if (!memcmp(cur_path.value, "\x3F\x00", 2) && memcmp(in_path.value, "\x3F\x00", 2)) { - memmove(in_path.value + 2, in_path.value, (in_path.len - 2)); - memcpy(in_path.value, "\x3F\x00", 2); - in_path.len += 2; - } - - for (offs = 0; (offs + 1) < in_path.len && (offs + 1) < cur_path.len; offs += 2) { - if (cur_path.value[offs] != in_path.value[offs]) - break; - if (cur_path.value[offs + 1] != in_path.value[offs + 1]) - break; - } - - memmove(in_path.value, in_path.value + offs, sizeof(in_path.value) - offs); - in_path.len -= offs; - *path = in_path; - - LOG_FUNC_RETURN(ctx, (int)offs); -} - - -static void -authentic_debug_select_file(struct sc_card *card, const struct sc_path *path) -{ - struct sc_context *ctx = card->ctx; - struct sc_card_cache *cache = &card->cache; - - if (path) - sc_log(ctx, "try to select path(type:%i,len=%"SC_FORMAT_LEN_SIZE_T"u) %s", - path->type, path->len, sc_print_path(path)); - - if (!cache->valid) - return; - - if (cache->current_df) - sc_log(ctx, "current_df(type=%i) %s", - cache->current_df->path.type, sc_print_path(&cache->current_df->path)); - else - sc_log(ctx, "current_df empty"); - - if (cache->current_ef) - sc_log(ctx, "current_ef(type=%i) %s", - cache->current_ef->path.type, sc_print_path(&cache->current_ef->path)); - else - sc_log(ctx, "current_ef empty"); -} - - -static int -authentic_is_selected(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out) -{ - if (!path->len) { - if (file_out && card->cache.valid && card->cache.current_df) - sc_file_dup(file_out, card->cache.current_df); - return SC_SUCCESS; - } - else if (path->len == 2 && card->cache.valid && card->cache.current_ef) { - if (!memcmp(card->cache.current_ef->path.value, path->value, 2)) { - if (file_out) - sc_file_dup(file_out, card->cache.current_ef); - return SC_SUCCESS; - } - } - - return SC_ERROR_FILE_NOT_FOUND; -} - - static int authentic_select_file(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out) @@ -726,35 +581,12 @@ authentic_select_file(struct sc_card *card, const struct sc_path *path, int rv; LOG_FUNC_CALLED(ctx); - authentic_debug_select_file(card, path); memcpy(&lpath, path, sizeof(struct sc_path)); - rv = authentic_reduce_path(card, &lpath); - LOG_TEST_RET(ctx, rv, "reduce path error"); - - if (lpath.len >= 2 && lpath.value[0] == 0x3F && lpath.value[1] == 0x00) { - rv = authentic_select_mf(card, file_out); - LOG_TEST_RET(ctx, rv, "cannot select MF"); - - memmove(&lpath.value[0], &lpath.value[2], lpath.len - 2); - lpath.len -= 2; - - if (lpath.len == 0) { - LOG_FUNC_RETURN(ctx, SC_SUCCESS); - } else if (file_out != NULL) { - sc_file_free(*file_out); - *file_out = NULL; - } - } - if (lpath.type == SC_PATH_TYPE_PATH && (lpath.len == 2)) lpath.type = SC_PATH_TYPE_FILE_ID; - rv = authentic_is_selected(card, &lpath, file_out); - if (!rv) - LOG_FUNC_RETURN(ctx, SC_SUCCESS); - pathlen = lpath.len; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00); @@ -1089,8 +921,6 @@ authentic_create_file(struct sc_card *card, struct sc_file *file) if (file->type != SC_FILE_TYPE_WORKING_EF) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Creation of the file with of this type is not supported"); - authentic_debug_select_file(card, &file->path); - rv = authentic_fcp_encode(card, file, sbuf + 2, sizeof(sbuf)-2); LOG_TEST_RET(ctx, rv, "FCP encode error"); sbuf_len = rv; @@ -1098,16 +928,6 @@ authentic_create_file(struct sc_card *card, struct sc_file *file) sbuf[0] = ISO7816_TAG_FCP; sbuf[1] = sbuf_len; - if (card->cache.valid && card->cache.current_df) { - const struct sc_acl_entry *entry = sc_file_get_acl_entry(card->cache.current_df, SC_AC_OP_CREATE); - if (!entry) - LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); - - sc_log(ctx, "CREATE method/reference %X/%X", entry->method, entry->key_ref); - if (entry->method == SC_AC_SCB) - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet supported"); - } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0, 0); apdu.data = sbuf; apdu.datalen = sbuf_len + 2; @@ -1155,11 +975,6 @@ authentic_delete_file(struct sc_card *card, const struct sc_path *path) } LOG_TEST_RET(ctx, rv, "Delete file failed"); - if (card->cache.valid) { - sc_file_free(card->cache.current_ef); - card->cache.current_ef = NULL; - } - LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index c23bf7c6bc..10d3b81f2a 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -513,20 +513,6 @@ static int entersafe_select_fid(sc_card_t *card, sc_file_free(file); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - /* update cache */ - if (file->type == SC_FILE_TYPE_DF) { - card->cache.current_path.type = SC_PATH_TYPE_PATH; - card->cache.current_path.value[0] = 0x3f; - card->cache.current_path.value[1] = 0x00; - if (id_hi == 0x3f && id_lo == 0x00) { - card->cache.current_path.len = 2; - } else { - card->cache.current_path.len = 4; - card->cache.current_path.value[2] = id_hi; - card->cache.current_path.value[3] = id_lo; - } - } - if (file_out) *file_out = file; else @@ -539,26 +525,11 @@ static int entersafe_select_aid(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - int r = 0; - - if (card->cache.valid && - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME && - card->cache.current_path.len == in_path->len && - memcmp(card->cache.current_path.value, in_path->value, in_path->len) == 0) { - if (file_out) { - *file_out = sc_file_new(); - if (!file_out) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - } else { - r = iso_ops->select_file(card, in_path, file_out); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + int r; + + r = iso_ops->select_file(card, in_path, file_out); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - /* update cache */ - card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; - card->cache.current_path.len = in_path->len; - memcpy(card->cache.current_path.value, in_path->value, in_path->len); - } if (file_out) { sc_file_t *file = *file_out; assert(file); @@ -582,7 +553,6 @@ static int entersafe_select_path(sc_card_t *card, u8 n_pathbuf[SC_MAX_PATH_SIZE]; const u8 *path = pathbuf; size_t pathlen = len; - size_t bMatch = 0; unsigned int i; int r; @@ -602,88 +572,21 @@ static int entersafe_select_path(sc_card_t *card, pathlen += 2; } - /* check current working directory */ - if (card->cache.valid && - card->cache.current_path.type == SC_PATH_TYPE_PATH && - card->cache.current_path.len >= 2 && - card->cache.current_path.len <= pathlen) { - for (i = 0; i < card->cache.current_path.len; i += 2) { - if (card->cache.current_path.value[i] == path[i] && - card->cache.current_path.value[i + 1] == path[i + 1]) { - bMatch += 2; - } - } - } - - if (card->cache.valid && bMatch > 2) { - if (pathlen - bMatch == 2) { - /* we are in the right directory */ - return entersafe_select_fid(card, path[bMatch], path[bMatch + 1], file_out); - } else if (pathlen - bMatch > 2) { - /* two more steps to go */ - sc_path_t new_path; - - /* first step: change directory */ - r = entersafe_select_fid(card, path[bMatch], path[bMatch + 1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - memset(&new_path, 0, sizeof(sc_path_t)); - - new_path.type = SC_PATH_TYPE_PATH; - new_path.len = pathlen - bMatch - 2; - memcpy(new_path.value, &(path[bMatch + 2]), new_path.len); - /* final step: select file */ - return entersafe_select_file(card, &new_path, file_out); - } else { /* if (bMatch - pathlen == 0) */ - /* done: we are already in the requested directory */ - sc_log(card->ctx, "cache hit\n"); - /* copy file info (if necessary) */ - if (file_out) { - sc_file_t *file = sc_file_new(); - if (!file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (path[pathlen - 2] << 8) + path[pathlen - 1]; - file->path = card->cache.current_path; - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->size = 0; - file->namelen = 0; - file->magic = SC_FILE_MAGIC; - *file_out = file; - } - /* nothing left to do */ - return SC_SUCCESS; - } - } else { - /* no usable cache */ - for (i = 0; i < pathlen - 2; i += 2) { - r = entersafe_select_fid(card, path[i], path[i + 1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - } - return entersafe_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); + for (i = 0; i < pathlen - 2; i += 2) { + r = entersafe_select_fid(card, path[i], path[i + 1], NULL); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } + return entersafe_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); } static int entersafe_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - int r; - char pbuf[SC_MAX_PATH_STRING_SIZE]; assert(card); assert(in_path); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, - "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? "aid" : "path", - card->cache.valid ? "valid" : "invalid", pbuf, - card->cache.current_path.len); - switch (in_path->type) { case SC_PATH_TYPE_FILE_ID: if (in_path->len != 2) @@ -1029,7 +932,6 @@ static int entersafe_erase_card(sc_card_t *card) r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - sc_invalidate_cache(card); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xEE, 0x00, 0x00); apdu.cla = 0x84; diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index e448f1f75f..2b884049b1 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1936,20 +1936,6 @@ epass2003_select_fid(struct sc_card *card, unsigned int id_hi, unsigned int id_l r = epass2003_select_fid_(card, &path, &file); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - /* update cache */ - if (file && file->type == SC_FILE_TYPE_DF) { - card->cache.current_path.type = SC_PATH_TYPE_PATH; - card->cache.current_path.value[0] = 0x3f; - card->cache.current_path.value[1] = 0x00; - if (id_hi == 0x3f && id_lo == 0x00) { - card->cache.current_path.len = 2; - } else { - card->cache.current_path.len = 4; - card->cache.current_path.value[2] = id_hi; - card->cache.current_path.value[3] = id_lo; - } - } - if (file_out) { *file_out = file; } else { @@ -1965,25 +1951,8 @@ epass2003_select_aid(struct sc_card *card, const sc_path_t * in_path, sc_file_t { int r = 0; - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME - && card->cache.current_path.len == in_path->len - && memcmp(card->cache.current_path.value, in_path->value, in_path->len) == 0) { - if (file_out) { - *file_out = sc_file_new(); - if (!file_out) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - } - else { - r = iso_ops->select_file(card, in_path, file_out); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - /* update cache */ - card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; - card->cache.current_path.len = in_path->len; - memcpy(card->cache.current_path.value, in_path->value, in_path->len); - } + r = iso_ops->select_file(card, in_path, file_out); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (file_out) { sc_file_t *file = *file_out; @@ -2009,7 +1978,6 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l u8 n_pathbuf[SC_MAX_PATH_SIZE]; const u8 *path = pathbuf; size_t pathlen = len; - size_t bMatch = 0; unsigned int i; int r; @@ -2029,65 +1997,12 @@ epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t l pathlen += 2; } - /* check current working directory */ - if (card->cache.valid - && card->cache.current_path.type == SC_PATH_TYPE_PATH - && card->cache.current_path.len >= 2 - && card->cache.current_path.len <= pathlen) { - for (i = 0; i < card->cache.current_path.len; i += 2) - if (card->cache.current_path.value[i] == path[i] - && card->cache.current_path.value[i + 1] == path[i + 1]) - bMatch += 2; - } - - if (card->cache.valid && bMatch > 2) { - if (pathlen - bMatch == 2) { - /* we are in the right directory */ - return epass2003_select_fid(card, path[bMatch], path[bMatch + 1], file_out); - } else if (pathlen - bMatch > 2) { - /* two more steps to go */ - sc_path_t new_path; - - /* first step: change directory */ - r = epass2003_select_fid(card, path[bMatch], path[bMatch + 1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - new_path.type = SC_PATH_TYPE_PATH; - new_path.len = pathlen - bMatch - 2; - memcpy(new_path.value, &(path[bMatch + 2]), new_path.len); - - /* final step: select file */ - return epass2003_select_file(card, &new_path, file_out); - } else { /* if (bMatch - pathlen == 0) */ - /* done: we are already in the - * requested directory */ - sc_log(card->ctx, "cache hit\n"); - /* copy file info (if necessary) */ - if (file_out) { - sc_file_t *file = sc_file_new(); - if (!file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (path[pathlen - 2] << 8) + path[pathlen - 1]; - file->path = card->cache.current_path; - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->size = 0; - file->namelen = 0; - file->magic = SC_FILE_MAGIC; - *file_out = file; - } - /* nothing left to do */ - return SC_SUCCESS; - } - } else { - /* no usable cache */ - for (i = 0; i < pathlen - 2; i += 2) { - r = epass2003_select_fid(card, path[i], path[i + 1], NULL); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - } - - return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); + for (i = 0; i < pathlen - 2; i += 2) { + r = epass2003_select_fid(card, path[i], path[i + 1], NULL); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } + + return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out); } @@ -2095,22 +2010,8 @@ static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out) { - int r; - char pbuf[SC_MAX_PATH_STRING_SIZE]; - LOG_FUNC_CALLED(card->ctx); - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, - "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? - "aid" : "path", - card->cache.valid ? "valid" : "invalid", pbuf, - card->cache.current_path.len); - switch (in_path->type) { case SC_PATH_TYPE_FILE_ID: if (in_path->len != 2) @@ -2125,7 +2026,6 @@ epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, } } - static int epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, int se_num) { @@ -3058,7 +2958,6 @@ epass2003_erase_card(struct sc_card *card) int r; LOG_FUNC_CALLED(card->ctx); - sc_invalidate_cache(card); /* install magic pin */ sc_format_apdu(card, &apdu, 0x03, 0xe3, 0x00, 0x00); diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 219b27806e..8490a8351c 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -433,80 +433,6 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file, return 0; } -static int check_path(sc_card_t *card, const u8 **pathptr, size_t *pathlen, - int need_info) -{ - const u8 *curptr = card->cache.current_path.value; - const u8 *ptr = *pathptr; - size_t curlen = card->cache.current_path.len; - size_t len = *pathlen; - - if (curlen < 2) - return 0; - if (len < 2) - return 0; - if (memcmp(ptr, "\x3F\x00", 2) != 0) { - /* Skip the MF id */ - curptr += 2; - curlen -= 2; - } - if (len == curlen && memcmp(ptr, curptr, len) == 0) { - if (need_info) - return 0; - *pathptr = ptr + len; - *pathlen = 0; - return 1; - } - if (curlen < len && memcmp(ptr, curptr, curlen) == 0) { - *pathptr = ptr + curlen; - *pathlen = len - curlen; - return 1; - } - /* FIXME: Build additional logic */ - return 0; -} - -static void cache_path(sc_card_t *card, const sc_path_t *path, - int result) -{ - sc_path_t *curpath = &card->cache.current_path; - - if (result < 0) { - curpath->len = 0; - return; - } - - switch (path->type) { - case SC_PATH_TYPE_FILE_ID: - if (path->value[0] == 0x3F && path->value[1] == 0x00) - sc_format_path("3F00", curpath); - else { - if (curpath->len + 2 > SC_MAX_PATH_SIZE) { - curpath->len = 0; - return; - } - memcpy(curpath->value + curpath->len, path->value, 2); - curpath->len += 2; - } - break; - case SC_PATH_TYPE_PATH: - curpath->len = 0; - if (path->value[0] != 0x3F || path->value[1] != 0) - sc_format_path("3F00", curpath); - if (curpath->len + path->len > SC_MAX_PATH_SIZE) { - curpath->len = 0; - return; - } - memcpy(curpath->value + curpath->len, path->value, path->len); - curpath->len += path->len; - break; - case SC_PATH_TYPE_DF_NAME: - /* All bets are off */ - curpath->len = 0; - break; - } -} - static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, u8 p1, sc_file_t **file_out) { @@ -566,29 +492,20 @@ static int flex_select_file(sc_card_t *card, const sc_path_t *path, int r; const u8 *pathptr = path->value; size_t pathlen = path->len; - int locked = 0, magic_done; + int locked = 0; u8 p1 = 0; - char pbuf[SC_MAX_PATH_STRING_SIZE]; - - - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, "called, cached path=%s\n", pbuf); switch (path->type) { case SC_PATH_TYPE_PATH: if ((pathlen & 1) != 0) /* not divisible by 2 */ return SC_ERROR_INVALID_ARGUMENTS; - magic_done = check_path(card, &pathptr, &pathlen, file_out != NULL); if (pathlen == 0) return 0; if (pathlen != 2 || memcmp(pathptr, "\x3F\x00", 2) != 0) { locked = 1; r = sc_lock(card); LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); - if (!magic_done && memcmp(pathptr, "\x3F\x00", 2) != 0) { + if (memcmp(pathptr, "\x3F\x00", 2) != 0) { r = select_file_id(card, (const u8 *) "\x3F\x00", 2, 0, NULL); if (r) sc_unlock(card); @@ -615,7 +532,6 @@ static int flex_select_file(sc_card_t *card, const sc_path_t *path, r = select_file_id(card, pathptr, pathlen, p1, file_out); if (locked) sc_unlock(card); - cache_path(card, path, r); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -921,15 +837,7 @@ static int flex_create_file(sc_card_t *card, sc_file_t *file) LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "Card returned error"); - if (card->cache.valid) { - u8 file_id[2]; - - file_id[0] = file->id >> 8; - file_id[1] = file->id & 0xFF; - if (card->cache.current_path.len != 0) - sc_append_path_id(&card->cache.current_path, file_id, 2); - } - return 0; + return SC_SUCCESS; } static int flex_set_security_env(sc_card_t *card, diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 4cb4ec7192..e515259949 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -159,6 +159,18 @@ static int _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, unsig static int _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, const unsigned char *buff, size_t count); #endif +void +sc_invalidate_cache(struct sc_card *card) +{ + if (card) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; + sc_file_free(prv->cache.current_ef); + sc_file_free(prv->cache.current_df); + memset(&prv->cache, 0, sizeof(prv->cache)); + prv->cache.valid = 0; + } +} + static int iasecc_chv_cache_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) { @@ -269,6 +281,7 @@ iasecc_chv_cache_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_c static int iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct sc_file *mf_file = NULL; struct sc_path path; @@ -323,18 +336,9 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out) mf_file->type = SC_FILE_TYPE_DF; mf_file->path = path; - if (card->cache.valid) { - sc_file_free(card->cache.current_df); - } - card->cache.current_df = NULL; - - if (card->cache.valid) { - sc_file_free(card->cache.current_ef); - } - card->cache.current_ef = NULL; - - sc_file_dup(&card->cache.current_df, mf_file); - card->cache.valid = 1; + sc_invalidate_cache(card); + sc_file_dup(&prv->cache.current_df, mf_file); + prv->cache.valid = 1; if (file_out && *file_out == NULL) *file_out = mf_file; @@ -765,6 +769,7 @@ static int _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, unsigned char *buff, size_t count) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; const struct sc_acl_entry *entry = NULL; int rv; @@ -779,10 +784,8 @@ _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, if (count == 0) return 0; - sc_print_cache(card); - - if (card->cache.valid && card->cache.current_ef) { - entry = sc_file_get_acl_entry(card->cache.current_ef, SC_AC_OP_READ); + if (prv->cache.valid && prv->cache.current_ef) { + entry = sc_file_get_acl_entry(prv->cache.current_ef, SC_AC_OP_READ); if (!entry) LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_read() 'READ' ACL not present"); @@ -803,6 +806,7 @@ static int _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, const unsigned char *buff, size_t count) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; const struct sc_acl_entry *entry = NULL; int rv; @@ -812,12 +816,11 @@ _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, LOG_FUNC_CALLED(ctx); sc_log(ctx, - "iasecc_sm_read_binary() card:%p offs:%i count:%"SC_FORMAT_LEN_SIZE_T"u ", - card, offs, count); - sc_print_cache(card); + "iasecc_sm_read_binary() card:%p offs:%i count:%" SC_FORMAT_LEN_SIZE_T "u ", + card, offs, count); - if (card->cache.valid && card->cache.current_ef) { - entry = sc_file_get_acl_entry(card->cache.current_ef, SC_AC_OP_UPDATE); + if (prv->cache.valid && prv->cache.current_ef) { + entry = sc_file_get_acl_entry(prv->cache.current_ef, SC_AC_OP_UPDATE); if (!entry) LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_update() 'UPDATE' ACL not present"); @@ -872,9 +875,9 @@ static int iasecc_select_file(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct sc_path lpath; - int cache_valid = card->cache.valid, df_from_cache = 0; int rv, ii; LOG_FUNC_CALLED(ctx); @@ -887,7 +890,6 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, card, path->len, path->type, path->aid.len); sc_log(ctx, "iasecc_select_file() path:%s", sc_print_path(path)); - sc_print_cache(card); if ((!iasecc_is_cpx(card)) && (card->type != SC_CARD_TYPE_IASECC_GEMALTO) && (path->type != SC_PATH_TYPE_DF_NAME @@ -915,11 +917,6 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, ppath.len = lpath.aid.len; ppath.type = SC_PATH_TYPE_DF_NAME; - if (card->cache.valid && card->cache.current_df - && card->cache.current_df->path.len == lpath.aid.len - && !memcmp(card->cache.current_df->path.value, lpath.aid.value, lpath.aid.len)) - df_from_cache = 1; - rv = iasecc_select_file(card, &ppath, &file); LOG_TEST_GOTO_ERR(ctx, rv, "select AID path failed"); @@ -945,21 +942,6 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, LOG_FUNC_RETURN(ctx, SC_SUCCESS); } - sc_print_cache(card); - - if (card->cache.valid && card->cache.current_df && lpath.type == SC_PATH_TYPE_DF_NAME - && card->cache.current_df->path.len == lpath.len - && !memcmp(card->cache.current_df->path.value, lpath.value, lpath.len)) { - sc_log(ctx, "returns current DF path %s", sc_print_path(&card->cache.current_df->path)); - if (file_out) { - sc_file_free(*file_out); - sc_file_dup(file_out, card->cache.current_df); - } - - sc_print_cache(card); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); - } - do { struct sc_apdu apdu; struct sc_file *file = NULL; @@ -1054,22 +1036,6 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, break; } - /* - * Using of the cached DF and EF can cause problems in the multi-thread environment. - * FIXME: introduce config. option that invalidates this cache outside the locked card session, - * (or invent something else) - */ - if (rv == SC_ERROR_FILE_NOT_FOUND && cache_valid && df_from_cache) { - sc_invalidate_cache(card); - sc_log(ctx, "iasecc_select_file() file not found, retry without cached DF"); - if (file_out) { - sc_file_free(*file_out); - *file_out = NULL; - } - rv = iasecc_select_file(card, path, file_out); - LOG_FUNC_RETURN(ctx, rv); - } - LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_select_file() check SW failed"); sc_log(ctx, @@ -1111,23 +1077,14 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, sc_log(ctx, "FileType %i", file->type); if (file->type == SC_FILE_TYPE_DF) { - if (card->cache.valid) { - sc_file_free(card->cache.current_df); - } - card->cache.current_df = NULL; - - sc_file_dup(&card->cache.current_df, file); - card->cache.valid = 1; + sc_invalidate_cache(card); + sc_file_dup(&prv->cache.current_df, file); + prv->cache.valid = 1; } else { - if (card->cache.valid) { - sc_file_free(card->cache.current_ef); - } - - card->cache.current_ef = NULL; - - sc_file_dup(&card->cache.current_ef, file); - card->cache.valid = 1; + sc_file_free(prv->cache.current_ef); + sc_file_dup(&prv->cache.current_ef, file); + prv->cache.valid = 1; } if (file_out) { @@ -1139,17 +1096,11 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path, } } else if (lpath.type == SC_PATH_TYPE_DF_NAME) { - sc_file_free(card->cache.current_df); - card->cache.current_df = NULL; - - sc_file_free(card->cache.current_ef); - card->cache.current_ef = NULL; - - card->cache.valid = 1; + sc_invalidate_cache(card); + prv->cache.valid = 1; } } while(0); - sc_print_cache(card); LOG_FUNC_RETURN(ctx, SC_SUCCESS); err: if (file_out) { @@ -1382,6 +1333,7 @@ iasecc_fcp_encode(struct sc_card *card, struct sc_file *file, unsigned char *out static int iasecc_create_file(struct sc_card *card, struct sc_file *file) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct sc_apdu apdu; const struct sc_acl_entry *entry = NULL; @@ -1390,7 +1342,6 @@ iasecc_create_file(struct sc_card *card, struct sc_file *file) int rv; LOG_FUNC_CALLED(ctx); - sc_print_cache(card); if (file->type != SC_FILE_TYPE_WORKING_EF) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Creation of the file with of this type is not supported"); @@ -1402,8 +1353,8 @@ iasecc_create_file(struct sc_card *card, struct sc_file *file) sbuf[0] = IASECC_FCP_TAG; sbuf[1] = sbuf_len; - if (card->cache.valid && card->cache.current_df) { - entry = sc_file_get_acl_entry(card->cache.current_df, SC_AC_OP_CREATE); + if (prv->cache.valid && prv->cache.current_df) { + entry = sc_file_get_acl_entry(prv->cache.current_df, SC_AC_OP_CREATE); if (!entry) LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_create_file() 'CREATE' ACL not present"); @@ -1491,6 +1442,8 @@ iasecc_finish(struct sc_card *card) LOG_FUNC_CALLED(ctx); + sc_invalidate_cache(card); + while (se_info) { sc_file_free(se_info->df); next = se_info->next; @@ -1515,7 +1468,6 @@ iasecc_delete_file(struct sc_card *card, const struct sc_path *path) int rv; LOG_FUNC_CALLED(ctx); - sc_print_cache(card); rv = iasecc_select_file(card, path, &file); if (rv == SC_ERROR_FILE_NOT_FOUND) @@ -1535,6 +1487,7 @@ iasecc_delete_file(struct sc_card *card, const struct sc_path *path) sc_file_free(file); } else { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; sc_file_free(file); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); @@ -1543,10 +1496,10 @@ iasecc_delete_file(struct sc_card *card, const struct sc_path *path) rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(ctx, rv, "Delete file failed"); - if (card->cache.valid) { - sc_file_free(card->cache.current_ef); + if (prv->cache.valid) { + sc_file_free(prv->cache.current_ef); } - card->cache.current_ef = NULL; + prv->cache.current_ef = NULL; } LOG_FUNC_RETURN(ctx, rv); @@ -1594,7 +1547,7 @@ iasecc_get_algorithm(struct sc_context *ctx, const struct sc_security_env *env, static int iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se) { - struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data; + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct iasecc_se_info *se_info = NULL, *si = NULL; int rv; @@ -1606,8 +1559,8 @@ iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SE info allocation error"); memcpy(se_info, se, sizeof(struct iasecc_se_info)); - if (card->cache.valid && card->cache.current_df) { - sc_file_dup(&se_info->df, card->cache.current_df); + if (prv->cache.valid && prv->cache.current_df) { + sc_file_dup(&se_info->df, prv->cache.current_df); if (se_info->df == NULL) { free(se_info); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file"); @@ -1637,7 +1590,7 @@ iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se) static int iasecc_se_get_info_from_cache(struct sc_card *card, struct iasecc_se_info *se) { - struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data; + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct iasecc_se_info *si = NULL; int rv; @@ -1647,12 +1600,12 @@ iasecc_se_get_info_from_cache(struct sc_card *card, struct iasecc_se_info *se) for(si = prv->se_info; si; si = si->next) { if (si->reference != se->reference) continue; - if (!(card->cache.valid && card->cache.current_df) && si->df) + if (!(prv->cache.valid && prv->cache.current_df) && si->df) continue; - if (card->cache.valid && card->cache.current_df && !si->df) + if (prv->cache.valid && prv->cache.current_df && !si->df) continue; - if (card->cache.valid && card->cache.current_df && si->df) - if (memcmp(&card->cache.current_df->path, &si->df->path, sizeof(struct sc_path))) + if (prv->cache.valid && prv->cache.current_df && si->df) + if (memcmp(&prv->cache.current_df->path, &si->df->path, sizeof(struct sc_path))) continue; break; } @@ -1733,7 +1686,7 @@ iasecc_set_security_env(struct sc_card *card, { struct sc_context *ctx = card->ctx; struct iasecc_sdo sdo; - struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data; + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; unsigned algo_ref; struct sc_apdu apdu; unsigned sign_meth, sign_ref, auth_meth, auth_ref; @@ -2086,6 +2039,7 @@ iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries static int iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx = card->ctx; struct sc_file *save_current_df = NULL, *save_current_ef = NULL; struct iasecc_sdo sdo; @@ -2100,8 +2054,8 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struc LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); } - if (card->cache.valid && card->cache.current_df) { - sc_file_dup(&save_current_df, card->cache.current_df); + if (prv->cache.valid && prv->cache.current_df) { + sc_file_dup(&save_current_df, prv->cache.current_df); if (save_current_df == NULL) { rv = SC_ERROR_OUT_OF_MEMORY; sc_log(ctx, "Cannot duplicate current DF file"); @@ -2109,8 +2063,8 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struc } } - if (card->cache.valid && card->cache.current_ef) { - sc_file_dup(&save_current_ef, card->cache.current_ef); + if (prv->cache.valid && prv->cache.current_ef) { + sc_file_dup(&save_current_ef, prv->cache.current_ef); if (save_current_ef == NULL) { rv = SC_ERROR_OUT_OF_MEMORY; sc_log(ctx, "Cannot duplicate current EF file"); @@ -2118,7 +2072,7 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struc } } - if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && card->cache.valid && card->cache.current_df) { + if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && prv->cache.valid && prv->cache.current_df) { sc_format_path("3F00", &path); path.type = SC_PATH_TYPE_FILE_ID; rv = iasecc_select_file(card, &path, NULL); @@ -3332,7 +3286,7 @@ iasecc_compute_signature_dst(struct sc_card *card, const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len) { struct sc_context *ctx = card->ctx; - struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data; + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_security_env *env = &prv->security_env; struct iasecc_qsign_data qsign_data; struct sc_apdu apdu; @@ -3428,7 +3382,7 @@ iasecc_compute_signature_at(struct sc_card *card, const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len) { struct sc_context *ctx = card->ctx; - struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data; + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_security_env *env = &prv->security_env; struct sc_apdu apdu; size_t offs = 0, sz = 0; @@ -3491,7 +3445,7 @@ iasecc_compute_signature(struct sc_card *card, return SC_ERROR_INVALID_ARGUMENTS; ctx = card->ctx; - prv = (struct iasecc_private_data *) card->drv_data; + prv = (struct iasecc_private_data *)card->drv_data; env = &prv->security_env; LOG_FUNC_CALLED(ctx); diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 911e9f0a07..8f2669639d 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -569,8 +569,6 @@ do_select(sc_card_t * card, u8 kind, if (apdu.sw1 == 0x61) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (!r && kind == MCRD_SEL_AID) - card->cache.current_path.len = 0; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } r = sc_check_sw(card, apdu.sw1, apdu.sw2); diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 5920c2c417..7caea31128 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -187,7 +187,6 @@ auth_select_aid(struct sc_card *card) rv = iso_ops->select_file(card, &tmp_path, &auth_current_df); LOG_TEST_RET(card->ctx, rv, "select parent failed"); - sc_format_path("3F00", &card->cache.current_path); sc_file_free(auth_current_ef); auth_current_ef = NULL; sc_file_dup(&auth_current_ef, auth_current_df); @@ -945,10 +944,6 @@ auth_create_file(struct sc_card *card, struct sc_file *file) if (file->id==0x0000 || file->id==0xFFFF || file->id==0x3FFF) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - rv = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (rv != SC_SUCCESS) - pbuf[0] = '\0'; - if (file->path.len) { memcpy(&path, &file->path, sizeof(path)); if (path.len>2) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 48eb49cbaa..204c9fefc0 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -764,11 +764,6 @@ static int starcos_select_aid(sc_card_t *card, if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 ) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - /* update cache */ - card->cache.current_path.type = SC_PATH_TYPE_DF_NAME; - card->cache.current_path.len = len; - memcpy(card->cache.current_path.value, aid, len); - if (file_out) { sc_file_t *file = sc_file_new(); if (!file) @@ -876,26 +871,11 @@ static int starcos_select_fid(sc_card_t *card, if (apdu.sw1 != 0x61 && (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); - /* update cache */ - if (bIsDF || isMF) { - card->cache.current_path.type = SC_PATH_TYPE_PATH; - card->cache.current_path.value[0] = 0x3f; - card->cache.current_path.value[1] = 0x00; - if (id_hi == 0x3f && id_lo == 0x00) - card->cache.current_path.len = 2; - else { - card->cache.current_path.len = 4; - card->cache.current_path.value[2] = id_hi; - card->cache.current_path.value[3] = id_lo; - } - } - if (file_out) { sc_file_t *file = sc_file_new(); if (!file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (id_hi << 8) + id_lo; - file->path = card->cache.current_path; + file->id = (id_hi << 8) + id_lo; if (bIsDF || isMF) { /* we have a DF */ @@ -938,19 +918,9 @@ static int starcos_select_file(sc_card_t *card, u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; int r, pathtype; size_t i, pathlen; - char pbuf[SC_MAX_PATH_STRING_SIZE]; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - sc_log(card->ctx, - "current path (%s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", - card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? - "aid" : "path", pbuf, card->cache.current_path.len); - if ( in_path->len > sizeof(pathbuf) ) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); } @@ -1407,7 +1377,6 @@ static int starcos_erase_card(sc_card_t *card) r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - sc_invalidate_cache(card); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) /* no MF to delete, ignore error */ return SC_SUCCESS; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index e44d4984b7..d13922cdb1 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -175,9 +175,6 @@ static void sc_card_free(sc_card_t *card) card->algorithm_count = 0; } - sc_file_free(card->cache.current_ef); - sc_file_free(card->cache.current_df); - if (card->mutex != NULL) { int r = sc_mutex_destroy(card->ctx, card->mutex); if (r != SC_SUCCESS) @@ -447,7 +444,6 @@ int sc_reset(sc_card_t *card, int do_cold_reset) return r; r = card->reader->ops->reset(card->reader, do_cold_reset); - sc_invalidate_cache(card); r2 = sc_mutex_unlock(card->ctx, card->mutex); if (r2 != SC_SUCCESS) { @@ -476,7 +472,6 @@ int sc_lock(sc_card_t *card) if (card->reader->ops->lock != NULL) { r = card->reader->ops->lock(card->reader); while (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { - sc_invalidate_cache(card); if (was_reset++ > 4) /* TODO retry a few times */ break; r = card->reader->ops->lock(card->reader); @@ -484,8 +479,6 @@ int sc_lock(sc_card_t *card) if (r == 0) reader_lock_obtained = 1; } - if (r == 0) - card->cache.valid = 1; } if (r == 0) card->lock_count++; @@ -529,12 +522,6 @@ int sc_unlock(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (--card->lock_count == 0) { - if (card->flags & SC_CARD_FLAG_KEEP_ALIVE) { - /* Multiple processes accessing the card will most likely render - * the card cache useless. To not have a bad cache, we explicitly - * invalidate it. */ - sc_invalidate_cache(card); - } /* release reader lock */ if (card->reader->ops->unlock != NULL) r = card->reader->ops->unlock(card->reader); @@ -1481,41 +1468,6 @@ scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char return conf_block; } -void sc_invalidate_cache(struct sc_card *card) -{ - if (card) { - sc_file_free(card->cache.current_ef); - sc_file_free(card->cache.current_df); - memset(&card->cache, 0, sizeof(card->cache)); - card->cache.valid = 0; - } -} - -void sc_print_cache(struct sc_card *card) -{ - struct sc_context *ctx = NULL; - - if (card == NULL) - return; - ctx = card->ctx; - - if (!card->cache.valid || (!card->cache.current_ef && !card->cache.current_df)) { - sc_log(ctx, "card cache invalid"); - return; - } - - if (card->cache.current_ef) - sc_log(ctx, "current_ef(type=%i) %s", card->cache.current_ef->path.type, - sc_print_path(&card->cache.current_ef->path)); - - if (card->cache.current_df) - sc_log(ctx, - "current_df(type=%i, aid_len=%"SC_FORMAT_LEN_SIZE_T"u) %s", - card->cache.current_df->path.type, - card->cache.current_df->path.aid.len, - sc_print_path(&card->cache.current_df->path)); -} - void sc_clear_ec_params(struct sc_ec_parameters *ecp) { diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index a8ca132612..e2a254da59 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -38,6 +38,7 @@ static int sm_save_sc_context (struct sc_card *card, struct sm_info *sm_info) { + struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; struct sc_context *ctx; struct sc_card_cache *cache; @@ -45,7 +46,7 @@ sm_save_sc_context (struct sc_card *card, struct sm_info *sm_info) return SC_ERROR_INVALID_ARGUMENTS; ctx = card->ctx; - cache = &card->cache; + cache = &prv->cache; sc_log(ctx, "SM save context: cache(valid:%i,current_df:%p)", cache->valid, cache->current_df); if (cache->valid && cache->current_df) { diff --git a/src/libopensc/iasecc.h b/src/libopensc/iasecc.h index 7362e5d5be..2e5408e981 100644 --- a/src/libopensc/iasecc.h +++ b/src/libopensc/iasecc.h @@ -123,6 +123,15 @@ struct iasecc_io_buffer_sizes { size_t recv_sc; }; +struct sc_card_cache { + struct sc_path current_path; + + struct sc_file *current_ef; + struct sc_file *current_df; + + int valid; +}; + struct iasecc_private_data { struct iasecc_version version; struct iasecc_io_buffer_sizes max_sizes; @@ -132,6 +141,8 @@ struct iasecc_private_data { unsigned op_method, op_ref; struct iasecc_se_info *se_info; + + struct sc_card_cache cache; }; #endif diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index fbc0ea96c4..c9a0b35fcc 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -337,7 +337,6 @@ sc_pkcs15init_finalize_profile sc_card_find_rsa_alg sc_card_find_ec_alg sc_check_apdu -sc_print_cache sc_find_app sc_remote_data_init sc_crc32 diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 365afbcf3b..26344c54a9 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -356,15 +356,6 @@ struct sc_ef_atr { unsigned status; }; -struct sc_card_cache { - struct sc_path current_path; - - struct sc_file *current_ef; - struct sc_file *current_df; - - int valid; -}; - #define SC_PROTO_T0 0x00000001 #define SC_PROTO_T1 0x00000002 #define SC_PROTO_RAW 0x00001000 @@ -617,8 +608,6 @@ typedef struct sc_card { void *drv_data; int max_pin_len; - struct sc_card_cache cache; - struct sc_serial_number serialnr; struct sc_version version; @@ -1613,9 +1602,6 @@ int sc_parse_ef_gdo(struct sc_card *card, unsigned char *chn, size_t *chn_len); int sc_update_dir(struct sc_card *card, sc_app_info_t *app); -void sc_invalidate_cache(struct sc_card *card); -void sc_print_cache(struct sc_card *card); - struct sc_algorithm_info * sc_card_find_rsa_alg(struct sc_card *card, size_t key_length); struct sc_algorithm_info * sc_card_find_ec_alg(struct sc_card *card, From 4aae2a9203ef80f19429c1f86eaa252247d4e75f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 21 Apr 2025 11:06:49 +0200 Subject: [PATCH 3866/4321] IAS/ECC: avoid memory leak on initialization error --- src/libopensc/card-iasecc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index e515259949..1806a9c72b 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -617,8 +617,6 @@ iasecc_init_cpx(struct sc_card *card) _sc_card_add_rsa_alg(card, 2048, flags, 0); rv = iasecc_parse_ef_atr(card); - if (rv) - sc_invalidate_cache(card); /* avoid memory leakage */ LOG_TEST_RET(ctx, rv, "Parse EF.ATR"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -686,6 +684,7 @@ iasecc_init(struct sc_card *card) err: if (rv < 0) { + sc_invalidate_cache(card); free(private_data); card->drv_data = old_drv_data; } else { From b825d640484833806d78ca7a7b45027105bf7bcc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 May 2025 21:36:46 +0200 Subject: [PATCH 3867/4321] npa-tool: allow reading DGs from eMRTD Adds the new options --application and --read-all-dgs fixes https://github.com/OpenSC/OpenSC/issues/2253 --- src/tools/npa-tool-cmdline.c | 288 ++++++++++++++++++++++++----------- src/tools/npa-tool-cmdline.h | 129 +++++++++------- src/tools/npa-tool.c | 173 +++++++++++++-------- src/tools/npa-tool.ggo.in | 62 ++++---- 4 files changed, 416 insertions(+), 236 deletions(-) diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 47e14153ea..3834dc4a75 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -1,7 +1,7 @@ /* File autogenerated by gengetopt version 2.23 generated with the following command: - /opt/homebrew/bin/gengetopt --file-name=npa-tool-cmdline --output-dir=. + /usr/bin/gengetopt --file-name=npa-tool-cmdline --output-dir=. The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -58,33 +58,36 @@ const char *gengetopt_args_info_help[] = { " --x509-dir=DIRECTORY Where to look for the CSCA's certificate\n (default=`')", " --disable-ta-checks Disable checking the validity period of CV\n certificates (default=off)", " --disable-ca-checks Disable passive authentication (default=off)", + "\nCard application:", + " --application=ENUM What card application to select (possible\n values=\"eID\", \"eMRTD\" default=`eID')", "\nRead and write data groups:", - " --read-dg1 Read DG 1 (Document Type) (default=off)", - " --read-dg2 Read DG 2 (Issuing State) (default=off)", - " --read-dg3 Read DG 3 (Date of Expiry) (default=off)", - " --read-dg4 Read DG 4 (Given Names) (default=off)", - " --read-dg5 Read DG 5 (Family Names) (default=off)", - " --read-dg6 Read DG 6 (Religious/Artistic Name)\n (default=off)", - " --read-dg7 Read DG 7 (Academic Title) (default=off)", - " --read-dg8 Read DG 8 (Date of Birth) (default=off)", - " --read-dg9 Read DG 9 (Place of Birth) (default=off)", - " --read-dg10 Read DG 10 (Nationality) (default=off)", - " --read-dg11 Read DG 11 (Sex) (default=off)", - " --read-dg12 Read DG 12 (Optional Data) (default=off)", - " --read-dg13 Read DG 13 (Birth Name) (default=off)", - " --read-dg14 Read DG 14 (default=off)", - " --read-dg15 Read DG 15 (default=off)", - " --read-dg16 Read DG 16 (default=off)", - " --read-dg17 Read DG 17 (Normal Place of Residence)\n (default=off)", - " --read-dg18 Read DG 18 (Community ID) (default=off)", - " --read-dg19 Read DG 19 (Residence Permit I) (default=off)", - " --read-dg20 Read DG 20 (Residence Permit II)\n (default=off)", - " --read-dg21 Read DG 21 (Optional Data) (default=off)", - " --write-dg17=HEX_STRING Write DG 17 (Normal Place of Residence)", - " --write-dg18=HEX_STRING Write DG 18 (Community ID)", - " --write-dg19=HEX_STRING Write DG 19 (Residence Permit I)", - " --write-dg20=HEX_STRING Write DG 20 (Residence Permit II)", - " --write-dg21=HEX_STRING Write DG 21 (Optional Data)", + " --read-all-dgs Read all available data groups (default=off)", + " --read-dg1 Read data group 1 (default=off)", + " --read-dg2 Read data group 2 (default=off)", + " --read-dg3 Read data group 3 (default=off)", + " --read-dg4 Read data group 4 (default=off)", + " --read-dg5 Read data group 5 (default=off)", + " --read-dg6 Read data group 6 (default=off)", + " --read-dg7 Read data group 7 (default=off)", + " --read-dg8 Read data group 8 (default=off)", + " --read-dg9 Read data group 9 (default=off)", + " --read-dg10 Read data group 10 (default=off)", + " --read-dg11 Read data group 11 (default=off)", + " --read-dg12 Read data group 12 (default=off)", + " --read-dg13 Read data group 13 (default=off)", + " --read-dg14 Read data group 14 (default=off)", + " --read-dg15 Read data group 15 (default=off)", + " --read-dg16 Read data group 16 (default=off)", + " --read-dg17 Read data group 17 (default=off)", + " --read-dg18 Read data group 18 (default=off)", + " --read-dg19 Read data group 19 (default=off)", + " --read-dg20 Read data group 20 (default=off)", + " --read-dg21 Read data group 21 (default=off)", + " --write-dg17=HEX_STRING Write data group 17", + " --write-dg18=HEX_STRING Write data group 18", + " --write-dg19=HEX_STRING Write data group 19", + " --write-dg20=HEX_STRING Write data group 20", + " --write-dg21=HEX_STRING Write data group 21", "\nVerification of validity, age and community ID:", " --verify-validity=YYYYMMDD\n Verify chip's validity with a reference date", " --older-than=YYYYMMDD Verify age with a reference date", @@ -100,6 +103,7 @@ const char *gengetopt_args_info_help[] = { typedef enum {ARG_NO , ARG_FLAG , ARG_STRING + , ARG_ENUM } cmdline_parser_arg_type; static @@ -114,6 +118,8 @@ cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args static int cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); +const char *cmdline_parser_application_values[] = {"eID", "eMRTD", 0}; /*< Possible values for application. */ + static char * gengetopt_strdup (const char *s); @@ -141,6 +147,8 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->x509_dir_given = 0 ; args_info->disable_ta_checks_given = 0 ; args_info->disable_ca_checks_given = 0 ; + args_info->application_given = 0 ; + args_info->read_all_dgs_given = 0 ; args_info->read_dg1_given = 0 ; args_info->read_dg2_given = 0 ; args_info->read_dg3_given = 0 ; @@ -210,6 +218,9 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->x509_dir_orig = NULL; args_info->disable_ta_checks_flag = 0; args_info->disable_ca_checks_flag = 0; + args_info->application_arg = application_arg_eID; + args_info->application_orig = NULL; + args_info->read_all_dgs_flag = 0; args_info->read_dg1_flag = 0; args_info->read_dg2_flag = 0; args_info->read_dg3_flag = 0; @@ -284,38 +295,40 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->x509_dir_help = gengetopt_args_info_help[21] ; args_info->disable_ta_checks_help = gengetopt_args_info_help[22] ; args_info->disable_ca_checks_help = gengetopt_args_info_help[23] ; - args_info->read_dg1_help = gengetopt_args_info_help[25] ; - args_info->read_dg2_help = gengetopt_args_info_help[26] ; - args_info->read_dg3_help = gengetopt_args_info_help[27] ; - args_info->read_dg4_help = gengetopt_args_info_help[28] ; - args_info->read_dg5_help = gengetopt_args_info_help[29] ; - args_info->read_dg6_help = gengetopt_args_info_help[30] ; - args_info->read_dg7_help = gengetopt_args_info_help[31] ; - args_info->read_dg8_help = gengetopt_args_info_help[32] ; - args_info->read_dg9_help = gengetopt_args_info_help[33] ; - args_info->read_dg10_help = gengetopt_args_info_help[34] ; - args_info->read_dg11_help = gengetopt_args_info_help[35] ; - args_info->read_dg12_help = gengetopt_args_info_help[36] ; - args_info->read_dg13_help = gengetopt_args_info_help[37] ; - args_info->read_dg14_help = gengetopt_args_info_help[38] ; - args_info->read_dg15_help = gengetopt_args_info_help[39] ; - args_info->read_dg16_help = gengetopt_args_info_help[40] ; - args_info->read_dg17_help = gengetopt_args_info_help[41] ; - args_info->read_dg18_help = gengetopt_args_info_help[42] ; - args_info->read_dg19_help = gengetopt_args_info_help[43] ; - args_info->read_dg20_help = gengetopt_args_info_help[44] ; - args_info->read_dg21_help = gengetopt_args_info_help[45] ; - args_info->write_dg17_help = gengetopt_args_info_help[46] ; - args_info->write_dg18_help = gengetopt_args_info_help[47] ; - args_info->write_dg19_help = gengetopt_args_info_help[48] ; - args_info->write_dg20_help = gengetopt_args_info_help[49] ; - args_info->write_dg21_help = gengetopt_args_info_help[50] ; - args_info->verify_validity_help = gengetopt_args_info_help[52] ; - args_info->older_than_help = gengetopt_args_info_help[53] ; - args_info->verify_community_help = gengetopt_args_info_help[54] ; - args_info->break_help = gengetopt_args_info_help[56] ; - args_info->translate_help = gengetopt_args_info_help[57] ; - args_info->tr_03110v201_help = gengetopt_args_info_help[58] ; + args_info->application_help = gengetopt_args_info_help[25] ; + args_info->read_all_dgs_help = gengetopt_args_info_help[27] ; + args_info->read_dg1_help = gengetopt_args_info_help[28] ; + args_info->read_dg2_help = gengetopt_args_info_help[29] ; + args_info->read_dg3_help = gengetopt_args_info_help[30] ; + args_info->read_dg4_help = gengetopt_args_info_help[31] ; + args_info->read_dg5_help = gengetopt_args_info_help[32] ; + args_info->read_dg6_help = gengetopt_args_info_help[33] ; + args_info->read_dg7_help = gengetopt_args_info_help[34] ; + args_info->read_dg8_help = gengetopt_args_info_help[35] ; + args_info->read_dg9_help = gengetopt_args_info_help[36] ; + args_info->read_dg10_help = gengetopt_args_info_help[37] ; + args_info->read_dg11_help = gengetopt_args_info_help[38] ; + args_info->read_dg12_help = gengetopt_args_info_help[39] ; + args_info->read_dg13_help = gengetopt_args_info_help[40] ; + args_info->read_dg14_help = gengetopt_args_info_help[41] ; + args_info->read_dg15_help = gengetopt_args_info_help[42] ; + args_info->read_dg16_help = gengetopt_args_info_help[43] ; + args_info->read_dg17_help = gengetopt_args_info_help[44] ; + args_info->read_dg18_help = gengetopt_args_info_help[45] ; + args_info->read_dg19_help = gengetopt_args_info_help[46] ; + args_info->read_dg20_help = gengetopt_args_info_help[47] ; + args_info->read_dg21_help = gengetopt_args_info_help[48] ; + args_info->write_dg17_help = gengetopt_args_info_help[49] ; + args_info->write_dg18_help = gengetopt_args_info_help[50] ; + args_info->write_dg19_help = gengetopt_args_info_help[51] ; + args_info->write_dg20_help = gengetopt_args_info_help[52] ; + args_info->write_dg21_help = gengetopt_args_info_help[53] ; + args_info->verify_validity_help = gengetopt_args_info_help[55] ; + args_info->older_than_help = gengetopt_args_info_help[56] ; + args_info->verify_community_help = gengetopt_args_info_help[57] ; + args_info->break_help = gengetopt_args_info_help[59] ; + args_info->translate_help = gengetopt_args_info_help[60] ; + args_info->tr_03110v201_help = gengetopt_args_info_help[61] ; } @@ -402,6 +415,7 @@ free_string_field (char **s) /** @brief generic value variable */ union generic_value { + int int_arg; char *string_arg; const char *default_string_arg; }; @@ -474,6 +488,7 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->cvc_dir_orig)); free_string_field (&(args_info->x509_dir_arg)); free_string_field (&(args_info->x509_dir_orig)); + free_string_field (&(args_info->application_orig)); free_string_field (&(args_info->write_dg17_arg)); free_string_field (&(args_info->write_dg17_orig)); free_string_field (&(args_info->write_dg18_arg)); @@ -498,13 +513,54 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) clear_given (args_info); } +/** + * @param val the value to check + * @param values the possible values + * @return the index of the matched value: + * -1 if no value matched, + * -2 if more than one value has matched + */ +static int +check_possible_values(const char *val, const char *values[]) +{ + int i, found, last; + size_t len; + + if (!val) /* otherwise strlen() crashes below */ + return -1; /* -1 means no argument for the option */ + + found = last = 0; + + for (i = 0, len = strlen(val); values[i]; ++i) + { + if (strncmp(val, values[i], len) == 0) + { + ++found; + last = i; + if (strlen(values[i]) == len) + return i; /* exact macth no need to check more */ + } + } + + if (found == 1) /* one match: OK */ + return last; + + return (found ? -2 : -1); /* return many values or none matched */ +} + static void write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) { - FIX_UNUSED (values); + int found = -1; if (arg) { - fprintf(outfile, "%s=\"%s\"\n", opt, arg); + if (values) { + found = check_possible_values(arg, values); + } + if (found >= 0) + fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); + else + fprintf(outfile, "%s=\"%s\"\n", opt, arg); } else { fprintf(outfile, "%s\n", opt); } @@ -570,6 +626,10 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "disable-ta-checks", 0, 0 ); if (args_info->disable_ca_checks_given) write_into_file(outfile, "disable-ca-checks", 0, 0 ); + if (args_info->application_given) + write_into_file(outfile, "application", args_info->application_orig, cmdline_parser_application_values); + if (args_info->read_all_dgs_given) + write_into_file(outfile, "read-all-dgs", 0, 0 ); if (args_info->read_dg1_given) write_into_file(outfile, "read-dg1", 0, 0 ); if (args_info->read_dg2_given) @@ -951,7 +1011,18 @@ int update_arg(void *field, char **orig_field, return 1; /* failure */ } - FIX_UNUSED (default_value); + if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) + { + if (short_opt != '-') + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } if (field_given && *field_given && ! override) return 0; @@ -966,6 +1037,9 @@ int update_arg(void *field, char **orig_field, case ARG_FLAG: *((int *)field) = !*((int *)field); break; + case ARG_ENUM: + if (val) *((int *)field) = found; + break; case ARG_STRING: if (val) { string_field = (char **)field; @@ -1083,6 +1157,8 @@ void update_multiple_arg(void *field, char ***orig_field, *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *)); switch(arg_type) { + case ARG_ENUM: + *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break; case ARG_STRING: *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break; default: @@ -1094,6 +1170,8 @@ void update_multiple_arg(void *field, char ***orig_field, tmp = list; switch(arg_type) { + case ARG_ENUM: + (*((int **)field))[i + field_given] = tmp->arg.int_arg; break; case ARG_STRING: (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break; default: @@ -1106,6 +1184,12 @@ void update_multiple_arg(void *field, char ***orig_field, } else { /* set the default value */ if (default_value && ! field_given) { switch(arg_type) { + case ARG_ENUM: + if (! *((int **)field)) { + *((int **)field) = (int *)malloc (sizeof (int)); + (*((int **)field))[0] = default_value->int_arg; + } + break; case ARG_STRING: if (! *((char ***)field)) { *((char ***)field) = (char **)malloc (sizeof (char *)); @@ -1187,6 +1271,8 @@ cmdline_parser_internal ( { "x509-dir", 1, NULL, 0 }, { "disable-ta-checks", 0, NULL, 0 }, { "disable-ca-checks", 0, NULL, 0 }, + { "application", 1, NULL, 0 }, + { "read-all-dgs", 0, NULL, 0 }, { "read-dg1", 0, NULL, 0 }, { "read-dg2", 0, NULL, 0 }, { "read-dg3", 0, NULL, 0 }, @@ -1484,7 +1570,33 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 1 (Document Type). */ + /* What card application to select. */ + else if (strcmp (long_options[option_index].name, "application") == 0) + { + + + if (update_arg( (void *)&(args_info->application_arg), + &(args_info->application_orig), &(args_info->application_given), + &(local_args_info.application_given), optarg, cmdline_parser_application_values, "eID", ARG_ENUM, + check_ambiguity, override, 0, 0, + "application", '-', + additional_error)) + goto failure; + + } + /* Read all available data groups. */ + else if (strcmp (long_options[option_index].name, "read-all-dgs") == 0) + { + + + if (update_arg((void *)&(args_info->read_all_dgs_flag), 0, &(args_info->read_all_dgs_given), + &(local_args_info.read_all_dgs_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "read-all-dgs", '-', + additional_error)) + goto failure; + + } + /* Read data group 1. */ else if (strcmp (long_options[option_index].name, "read-dg1") == 0) { @@ -1496,7 +1608,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 2 (Issuing State). */ + /* Read data group 2. */ else if (strcmp (long_options[option_index].name, "read-dg2") == 0) { @@ -1508,7 +1620,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 3 (Date of Expiry). */ + /* Read data group 3. */ else if (strcmp (long_options[option_index].name, "read-dg3") == 0) { @@ -1520,7 +1632,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 4 (Given Names). */ + /* Read data group 4. */ else if (strcmp (long_options[option_index].name, "read-dg4") == 0) { @@ -1532,7 +1644,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 5 (Family Names). */ + /* Read data group 5. */ else if (strcmp (long_options[option_index].name, "read-dg5") == 0) { @@ -1544,7 +1656,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 6 (Religious/Artistic Name). */ + /* Read data group 6. */ else if (strcmp (long_options[option_index].name, "read-dg6") == 0) { @@ -1556,7 +1668,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 7 (Academic Title). */ + /* Read data group 7. */ else if (strcmp (long_options[option_index].name, "read-dg7") == 0) { @@ -1568,7 +1680,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 8 (Date of Birth). */ + /* Read data group 8. */ else if (strcmp (long_options[option_index].name, "read-dg8") == 0) { @@ -1580,7 +1692,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 9 (Place of Birth). */ + /* Read data group 9. */ else if (strcmp (long_options[option_index].name, "read-dg9") == 0) { @@ -1592,7 +1704,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 10 (Nationality). */ + /* Read data group 10. */ else if (strcmp (long_options[option_index].name, "read-dg10") == 0) { @@ -1604,7 +1716,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 11 (Sex). */ + /* Read data group 11. */ else if (strcmp (long_options[option_index].name, "read-dg11") == 0) { @@ -1616,7 +1728,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 12 (Optional Data). */ + /* Read data group 12. */ else if (strcmp (long_options[option_index].name, "read-dg12") == 0) { @@ -1628,7 +1740,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 13 (Birth Name). */ + /* Read data group 13. */ else if (strcmp (long_options[option_index].name, "read-dg13") == 0) { @@ -1640,7 +1752,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 14. */ + /* Read data group 14. */ else if (strcmp (long_options[option_index].name, "read-dg14") == 0) { @@ -1652,7 +1764,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 15. */ + /* Read data group 15. */ else if (strcmp (long_options[option_index].name, "read-dg15") == 0) { @@ -1664,7 +1776,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 16. */ + /* Read data group 16. */ else if (strcmp (long_options[option_index].name, "read-dg16") == 0) { @@ -1676,7 +1788,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 17 (Normal Place of Residence). */ + /* Read data group 17. */ else if (strcmp (long_options[option_index].name, "read-dg17") == 0) { @@ -1688,7 +1800,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 18 (Community ID). */ + /* Read data group 18. */ else if (strcmp (long_options[option_index].name, "read-dg18") == 0) { @@ -1700,7 +1812,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 19 (Residence Permit I). */ + /* Read data group 19. */ else if (strcmp (long_options[option_index].name, "read-dg19") == 0) { @@ -1712,7 +1824,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 20 (Residence Permit II). */ + /* Read data group 20. */ else if (strcmp (long_options[option_index].name, "read-dg20") == 0) { @@ -1724,7 +1836,7 @@ cmdline_parser_internal ( goto failure; } - /* Read DG 21 (Optional Data). */ + /* Read data group 21. */ else if (strcmp (long_options[option_index].name, "read-dg21") == 0) { @@ -1736,7 +1848,7 @@ cmdline_parser_internal ( goto failure; } - /* Write DG 17 (Normal Place of Residence). */ + /* Write data group 17. */ else if (strcmp (long_options[option_index].name, "write-dg17") == 0) { @@ -1750,7 +1862,7 @@ cmdline_parser_internal ( goto failure; } - /* Write DG 18 (Community ID). */ + /* Write data group 18. */ else if (strcmp (long_options[option_index].name, "write-dg18") == 0) { @@ -1764,7 +1876,7 @@ cmdline_parser_internal ( goto failure; } - /* Write DG 19 (Residence Permit I). */ + /* Write data group 19. */ else if (strcmp (long_options[option_index].name, "write-dg19") == 0) { @@ -1778,7 +1890,7 @@ cmdline_parser_internal ( goto failure; } - /* Write DG 20 (Residence Permit II). */ + /* Write data group 20. */ else if (strcmp (long_options[option_index].name, "write-dg20") == 0) { @@ -1792,7 +1904,7 @@ cmdline_parser_internal ( goto failure; } - /* Write DG 21 (Optional Data). */ + /* Write data group 21. */ else if (strcmp (long_options[option_index].name, "write-dg21") == 0) { diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index e38e1e69a8..fef98a7b68 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -34,6 +34,8 @@ extern "C" { #define CMDLINE_PARSER_VERSION VERSION #endif +enum enum_application { application__NULL = -1, application_arg_eID = 0, application_arg_eMRTD }; + /** @brief Where the command line options are stored */ struct gengetopt_args_info { @@ -83,73 +85,78 @@ struct gengetopt_args_info char * private_key_arg; /**< @brief Terminal's private key. */ char * private_key_orig; /**< @brief Terminal's private key original value given at command line. */ const char *private_key_help; /**< @brief Terminal's private key help description. */ - char * cvc_dir_arg; /**< @brief Where to look for the CVCA's certificate (default=''). */ + char * cvc_dir_arg; /**< @brief Where to look for the CVCA's certificate (default='/home/fm/.local/etc/eac/cvc'). */ char * cvc_dir_orig; /**< @brief Where to look for the CVCA's certificate original value given at command line. */ const char *cvc_dir_help; /**< @brief Where to look for the CVCA's certificate help description. */ - char * x509_dir_arg; /**< @brief Where to look for the CSCA's certificate (default=''). */ + char * x509_dir_arg; /**< @brief Where to look for the CSCA's certificate (default='/home/fm/.local/etc/eac/x509'). */ char * x509_dir_orig; /**< @brief Where to look for the CSCA's certificate original value given at command line. */ const char *x509_dir_help; /**< @brief Where to look for the CSCA's certificate help description. */ int disable_ta_checks_flag; /**< @brief Disable checking the validity period of CV certificates (default=off). */ const char *disable_ta_checks_help; /**< @brief Disable checking the validity period of CV certificates help description. */ int disable_ca_checks_flag; /**< @brief Disable passive authentication (default=off). */ const char *disable_ca_checks_help; /**< @brief Disable passive authentication help description. */ - int read_dg1_flag; /**< @brief Read DG 1 (Document Type) (default=off). */ - const char *read_dg1_help; /**< @brief Read DG 1 (Document Type) help description. */ - int read_dg2_flag; /**< @brief Read DG 2 (Issuing State) (default=off). */ - const char *read_dg2_help; /**< @brief Read DG 2 (Issuing State) help description. */ - int read_dg3_flag; /**< @brief Read DG 3 (Date of Expiry) (default=off). */ - const char *read_dg3_help; /**< @brief Read DG 3 (Date of Expiry) help description. */ - int read_dg4_flag; /**< @brief Read DG 4 (Given Names) (default=off). */ - const char *read_dg4_help; /**< @brief Read DG 4 (Given Names) help description. */ - int read_dg5_flag; /**< @brief Read DG 5 (Family Names) (default=off). */ - const char *read_dg5_help; /**< @brief Read DG 5 (Family Names) help description. */ - int read_dg6_flag; /**< @brief Read DG 6 (Religious/Artistic Name) (default=off). */ - const char *read_dg6_help; /**< @brief Read DG 6 (Religious/Artistic Name) help description. */ - int read_dg7_flag; /**< @brief Read DG 7 (Academic Title) (default=off). */ - const char *read_dg7_help; /**< @brief Read DG 7 (Academic Title) help description. */ - int read_dg8_flag; /**< @brief Read DG 8 (Date of Birth) (default=off). */ - const char *read_dg8_help; /**< @brief Read DG 8 (Date of Birth) help description. */ - int read_dg9_flag; /**< @brief Read DG 9 (Place of Birth) (default=off). */ - const char *read_dg9_help; /**< @brief Read DG 9 (Place of Birth) help description. */ - int read_dg10_flag; /**< @brief Read DG 10 (Nationality) (default=off). */ - const char *read_dg10_help; /**< @brief Read DG 10 (Nationality) help description. */ - int read_dg11_flag; /**< @brief Read DG 11 (Sex) (default=off). */ - const char *read_dg11_help; /**< @brief Read DG 11 (Sex) help description. */ - int read_dg12_flag; /**< @brief Read DG 12 (Optional Data) (default=off). */ - const char *read_dg12_help; /**< @brief Read DG 12 (Optional Data) help description. */ - int read_dg13_flag; /**< @brief Read DG 13 (Birth Name) (default=off). */ - const char *read_dg13_help; /**< @brief Read DG 13 (Birth Name) help description. */ - int read_dg14_flag; /**< @brief Read DG 14 (default=off). */ - const char *read_dg14_help; /**< @brief Read DG 14 help description. */ - int read_dg15_flag; /**< @brief Read DG 15 (default=off). */ - const char *read_dg15_help; /**< @brief Read DG 15 help description. */ - int read_dg16_flag; /**< @brief Read DG 16 (default=off). */ - const char *read_dg16_help; /**< @brief Read DG 16 help description. */ - int read_dg17_flag; /**< @brief Read DG 17 (Normal Place of Residence) (default=off). */ - const char *read_dg17_help; /**< @brief Read DG 17 (Normal Place of Residence) help description. */ - int read_dg18_flag; /**< @brief Read DG 18 (Community ID) (default=off). */ - const char *read_dg18_help; /**< @brief Read DG 18 (Community ID) help description. */ - int read_dg19_flag; /**< @brief Read DG 19 (Residence Permit I) (default=off). */ - const char *read_dg19_help; /**< @brief Read DG 19 (Residence Permit I) help description. */ - int read_dg20_flag; /**< @brief Read DG 20 (Residence Permit II) (default=off). */ - const char *read_dg20_help; /**< @brief Read DG 20 (Residence Permit II) help description. */ - int read_dg21_flag; /**< @brief Read DG 21 (Optional Data) (default=off). */ - const char *read_dg21_help; /**< @brief Read DG 21 (Optional Data) help description. */ - char * write_dg17_arg; /**< @brief Write DG 17 (Normal Place of Residence). */ - char * write_dg17_orig; /**< @brief Write DG 17 (Normal Place of Residence) original value given at command line. */ - const char *write_dg17_help; /**< @brief Write DG 17 (Normal Place of Residence) help description. */ - char * write_dg18_arg; /**< @brief Write DG 18 (Community ID). */ - char * write_dg18_orig; /**< @brief Write DG 18 (Community ID) original value given at command line. */ - const char *write_dg18_help; /**< @brief Write DG 18 (Community ID) help description. */ - char * write_dg19_arg; /**< @brief Write DG 19 (Residence Permit I). */ - char * write_dg19_orig; /**< @brief Write DG 19 (Residence Permit I) original value given at command line. */ - const char *write_dg19_help; /**< @brief Write DG 19 (Residence Permit I) help description. */ - char * write_dg20_arg; /**< @brief Write DG 20 (Residence Permit II). */ - char * write_dg20_orig; /**< @brief Write DG 20 (Residence Permit II) original value given at command line. */ - const char *write_dg20_help; /**< @brief Write DG 20 (Residence Permit II) help description. */ - char * write_dg21_arg; /**< @brief Write DG 21 (Optional Data). */ - char * write_dg21_orig; /**< @brief Write DG 21 (Optional Data) original value given at command line. */ - const char *write_dg21_help; /**< @brief Write DG 21 (Optional Data) help description. */ + enum enum_application application_arg; /**< @brief What card application to select (default='eID'). */ + char * application_orig; /**< @brief What card application to select original value given at command line. */ + const char *application_help; /**< @brief What card application to select help description. */ + int read_all_dgs_flag; /**< @brief Read all available data groups (default=off). */ + const char *read_all_dgs_help; /**< @brief Read all available data groups help description. */ + int read_dg1_flag; /**< @brief Read data group 1 (default=off). */ + const char *read_dg1_help; /**< @brief Read data group 1 help description. */ + int read_dg2_flag; /**< @brief Read data group 2 (default=off). */ + const char *read_dg2_help; /**< @brief Read data group 2 help description. */ + int read_dg3_flag; /**< @brief Read data group 3 (default=off). */ + const char *read_dg3_help; /**< @brief Read data group 3 help description. */ + int read_dg4_flag; /**< @brief Read data group 4 (default=off). */ + const char *read_dg4_help; /**< @brief Read data group 4 help description. */ + int read_dg5_flag; /**< @brief Read data group 5 (default=off). */ + const char *read_dg5_help; /**< @brief Read data group 5 help description. */ + int read_dg6_flag; /**< @brief Read data group 6 (default=off). */ + const char *read_dg6_help; /**< @brief Read data group 6 help description. */ + int read_dg7_flag; /**< @brief Read data group 7 (default=off). */ + const char *read_dg7_help; /**< @brief Read data group 7 help description. */ + int read_dg8_flag; /**< @brief Read data group 8 (default=off). */ + const char *read_dg8_help; /**< @brief Read data group 8 help description. */ + int read_dg9_flag; /**< @brief Read data group 9 (default=off). */ + const char *read_dg9_help; /**< @brief Read data group 9 help description. */ + int read_dg10_flag; /**< @brief Read data group 10 (default=off). */ + const char *read_dg10_help; /**< @brief Read data group 10 help description. */ + int read_dg11_flag; /**< @brief Read data group 11 (default=off). */ + const char *read_dg11_help; /**< @brief Read data group 11 help description. */ + int read_dg12_flag; /**< @brief Read data group 12 (default=off). */ + const char *read_dg12_help; /**< @brief Read data group 12 help description. */ + int read_dg13_flag; /**< @brief Read data group 13 (default=off). */ + const char *read_dg13_help; /**< @brief Read data group 13 help description. */ + int read_dg14_flag; /**< @brief Read data group 14 (default=off). */ + const char *read_dg14_help; /**< @brief Read data group 14 help description. */ + int read_dg15_flag; /**< @brief Read data group 15 (default=off). */ + const char *read_dg15_help; /**< @brief Read data group 15 help description. */ + int read_dg16_flag; /**< @brief Read data group 16 (default=off). */ + const char *read_dg16_help; /**< @brief Read data group 16 help description. */ + int read_dg17_flag; /**< @brief Read data group 17 (default=off). */ + const char *read_dg17_help; /**< @brief Read data group 17 help description. */ + int read_dg18_flag; /**< @brief Read data group 18 (default=off). */ + const char *read_dg18_help; /**< @brief Read data group 18 help description. */ + int read_dg19_flag; /**< @brief Read data group 19 (default=off). */ + const char *read_dg19_help; /**< @brief Read data group 19 help description. */ + int read_dg20_flag; /**< @brief Read data group 20 (default=off). */ + const char *read_dg20_help; /**< @brief Read data group 20 help description. */ + int read_dg21_flag; /**< @brief Read data group 21 (default=off). */ + const char *read_dg21_help; /**< @brief Read data group 21 help description. */ + char * write_dg17_arg; /**< @brief Write data group 17. */ + char * write_dg17_orig; /**< @brief Write data group 17 original value given at command line. */ + const char *write_dg17_help; /**< @brief Write data group 17 help description. */ + char * write_dg18_arg; /**< @brief Write data group 18. */ + char * write_dg18_orig; /**< @brief Write data group 18 original value given at command line. */ + const char *write_dg18_help; /**< @brief Write data group 18 help description. */ + char * write_dg19_arg; /**< @brief Write data group 19. */ + char * write_dg19_orig; /**< @brief Write data group 19 original value given at command line. */ + const char *write_dg19_help; /**< @brief Write data group 19 help description. */ + char * write_dg20_arg; /**< @brief Write data group 20. */ + char * write_dg20_orig; /**< @brief Write data group 20 original value given at command line. */ + const char *write_dg20_help; /**< @brief Write data group 20 help description. */ + char * write_dg21_arg; /**< @brief Write data group 21. */ + char * write_dg21_orig; /**< @brief Write data group 21 original value given at command line. */ + const char *write_dg21_help; /**< @brief Write data group 21 help description. */ char * verify_validity_arg; /**< @brief Verify chip's validity with a reference date. */ char * verify_validity_orig; /**< @brief Verify chip's validity with a reference date original value given at command line. */ const char *verify_validity_help; /**< @brief Verify chip's validity with a reference date help description. */ @@ -188,6 +195,8 @@ struct gengetopt_args_info unsigned int x509_dir_given ; /**< @brief Whether x509-dir was given. */ unsigned int disable_ta_checks_given ; /**< @brief Whether disable-ta-checks was given. */ unsigned int disable_ca_checks_given ; /**< @brief Whether disable-ca-checks was given. */ + unsigned int application_given ; /**< @brief Whether application was given. */ + unsigned int read_all_dgs_given ; /**< @brief Whether read-all-dgs was given. */ unsigned int read_dg1_given ; /**< @brief Whether read-dg1 was given. */ unsigned int read_dg2_given ; /**< @brief Whether read-dg2 was given. */ unsigned int read_dg3_given ; /**< @brief Whether read-dg3 was given. */ @@ -344,6 +353,8 @@ void cmdline_parser_free (struct gengetopt_args_info *args_info); int cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name); +extern const char *cmdline_parser_application_values[]; /**< @brief Possible values for application. */ + #ifdef __cplusplus } diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 30ccf732da..4b5bc04803 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -122,7 +122,8 @@ static void read_dg(sc_card_t *card, unsigned char sfid, const char *dg_str, fprintf(stderr, "Could not read DG %02u %s (%s)\n", sfid, dg_str, sc_strerror(r)); else { - char buf[0x200]; + /* 32768 is the maximum size of dg according to ICAO Doc 9303 */ + char buf[32768*5]; sc_hex_dump(*dg, *dg_len, buf, sizeof buf); fprintf(stdout, "Read %s", buf); } @@ -712,9 +713,6 @@ main (int argc, char **argv) nopace: if (cmdline.cv_certificate_given || cmdline.private_key_given) { - unsigned char eid_aid[] = { 0xE8, 0x07, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x02}; - sc_path_t path; - r = perform_terminal_authentication(card, (const unsigned char **) certs, certs_lens, privkey, privkey_len, auxiliary_data, auxiliary_data_len); @@ -726,67 +724,116 @@ main (int argc, char **argv) if (r < 0) goto err; printf("Performed Chip Authentication.\n"); - - sc_path_set(&path, SC_PATH_TYPE_DF_NAME, eid_aid, sizeof eid_aid, 0, 0); - r = sc_select_file(card, &path, NULL); - if (r < 0) - goto err; - printf("Selected eID application.\n"); } - if (cmdline.read_dg1_flag) - read_dg(card, 1, "Document Type", &dg, &dg_len); - if (cmdline.read_dg2_flag) - read_dg(card, 2, "Issuing State", &dg, &dg_len); - if (cmdline.read_dg3_flag) - read_dg(card, 3, "Date of Expiry", &dg, &dg_len); - if (cmdline.read_dg4_flag) - read_dg(card, 4, "Given Names", &dg, &dg_len); - if (cmdline.read_dg5_flag) - read_dg(card, 5, "Family Names", &dg, &dg_len); - if (cmdline.read_dg6_flag) - read_dg(card, 6, "Religious/Artistic Name", &dg, &dg_len); - if (cmdline.read_dg7_flag) - read_dg(card, 7, "Academic Title", &dg, &dg_len); - if (cmdline.read_dg8_flag) - read_dg(card, 8, "Date of Birth", &dg, &dg_len); - if (cmdline.read_dg9_flag) - read_dg(card, 9, "Place of Birth", &dg, &dg_len); - if (cmdline.read_dg10_flag) - read_dg(card, 10, "Nationality", &dg, &dg_len); - if (cmdline.read_dg11_flag) - read_dg(card, 11, "Sex", &dg, &dg_len); - if (cmdline.read_dg12_flag) - read_dg(card, 12, "Optional Data", &dg, &dg_len); - if (cmdline.read_dg13_flag) - read_dg(card, 13, "Birth Name", &dg, &dg_len); - if (cmdline.read_dg14_flag) - read_dg(card, 14, "DG 14", &dg, &dg_len); - if (cmdline.read_dg15_flag) - read_dg(card, 15, "DG 15", &dg, &dg_len); - if (cmdline.read_dg16_flag) - read_dg(card, 16, "DG 16", &dg, &dg_len); - if (cmdline.read_dg17_flag) - read_dg(card, 17, "Normal Place of Residence", &dg, &dg_len); - if (cmdline.read_dg18_flag) - read_dg(card, 18, "Community ID", &dg, &dg_len); - if (cmdline.read_dg19_flag) - read_dg(card, 19, "Residence Permit I", &dg, &dg_len); - if (cmdline.read_dg20_flag) - read_dg(card, 20, "Residence Permit II", &dg, &dg_len); - if (cmdline.read_dg21_flag) - read_dg(card, 21, "Optional Data", &dg, &dg_len); - - if (cmdline.write_dg17_given) - write_dg(card, 17, "Normal Place of Residence", cmdline.write_dg17_arg); - if (cmdline.write_dg18_given) - write_dg(card, 18, "Community ID", cmdline.write_dg18_arg); - if (cmdline.write_dg19_given) - write_dg(card, 19, "Residence Permit I", cmdline.write_dg19_arg); - if (cmdline.write_dg20_given) - write_dg(card, 20, "Residence Permit II", cmdline.write_dg20_arg); - if (cmdline.write_dg21_given) - write_dg(card, 21, "Optional Data", cmdline.write_dg21_arg); + const unsigned char eid_aid[] = { 0xE8, 0x07, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x02}; + const unsigned char emrtd_aid[] = { 0xA0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01}; + sc_path_t path; + switch (cmdline.application_arg) { + case application_arg_eMRTD: + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, emrtd_aid, sizeof emrtd_aid, 0, 0); + r = sc_select_file(card, &path, NULL); + if (r < 0) + goto err; + printf("Selected eMRTD application.\n"); + + if (cmdline.read_dg1_flag || cmdline.read_all_dgs_flag) + read_dg(card, 1, "Machine Readable Zone Information", &dg, &dg_len); + if (cmdline.read_dg2_flag || cmdline.read_all_dgs_flag) + read_dg(card, 2, "Encoded Identification Features - Face", &dg, &dg_len); + if (cmdline.read_dg3_flag || cmdline.read_all_dgs_flag) + read_dg(card, 3, "Additional Identification Feature - Finger(s)", &dg, &dg_len); + if (cmdline.read_dg4_flag || cmdline.read_all_dgs_flag) + read_dg(card, 4, "Additional Identification Feature - Iris(es)", &dg, &dg_len); + if (cmdline.read_dg5_flag || cmdline.read_all_dgs_flag) + read_dg(card, 5, "Iris(es)", &dg, &dg_len); + if (cmdline.read_dg6_flag || cmdline.read_all_dgs_flag) + read_dg(card, 6, "Reserved For Future Use", &dg, &dg_len); + if (cmdline.read_dg7_flag || cmdline.read_all_dgs_flag) + read_dg(card, 7, "Displayed Signature or Usual Mark", &dg, &dg_len); + if (cmdline.read_dg8_flag || cmdline.read_all_dgs_flag) + read_dg(card, 8, "Data Feature(s)", &dg, &dg_len); + if (cmdline.read_dg9_flag || cmdline.read_all_dgs_flag) + read_dg(card, 9, "Structure Feature(s)", &dg, &dg_len); + if (cmdline.read_dg10_flag || cmdline.read_all_dgs_flag) + read_dg(card, 10, "Substance Feature(s)", &dg, &dg_len); + if (cmdline.read_dg11_flag || cmdline.read_all_dgs_flag) + read_dg(card, 11, "Additional Personal Detail(s)", &dg, &dg_len); + if (cmdline.read_dg12_flag || cmdline.read_all_dgs_flag) + read_dg(card, 12, "Additional Document Detail(s)", &dg, &dg_len); + if (cmdline.read_dg13_flag || cmdline.read_all_dgs_flag) + read_dg(card, 13, "Optional Details(s)", &dg, &dg_len); + if (cmdline.read_dg14_flag || cmdline.read_all_dgs_flag) + read_dg(card, 14, "Security Options", &dg, &dg_len); + if (cmdline.read_dg15_flag || cmdline.read_all_dgs_flag) + read_dg(card, 15, "Active Authentication Public Key Info", &dg, &dg_len); + if (cmdline.read_dg16_flag || cmdline.read_all_dgs_flag) + read_dg(card, 16, "Person(s) to Notify", &dg, &dg_len); + break; + + case application_arg_eID: + default: + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, eid_aid, sizeof eid_aid, 0, 0); + r = sc_select_file(card, &path, NULL); + if (r < 0) + goto err; + printf("Selected eMRTD application.\n"); + + if (cmdline.read_dg1_flag || cmdline.read_all_dgs_flag) + read_dg(card, 1, "Document Type", &dg, &dg_len); + if (cmdline.read_dg2_flag || cmdline.read_all_dgs_flag) + read_dg(card, 2, "Issuing State", &dg, &dg_len); + if (cmdline.read_dg3_flag || cmdline.read_all_dgs_flag) + read_dg(card, 3, "Date of Expiry", &dg, &dg_len); + if (cmdline.read_dg4_flag || cmdline.read_all_dgs_flag) + read_dg(card, 4, "Given Names", &dg, &dg_len); + if (cmdline.read_dg5_flag || cmdline.read_all_dgs_flag) + read_dg(card, 5, "Family Names", &dg, &dg_len); + if (cmdline.read_dg6_flag || cmdline.read_all_dgs_flag) + read_dg(card, 6, "Religious/Artistic Name", &dg, &dg_len); + if (cmdline.read_dg7_flag || cmdline.read_all_dgs_flag) + read_dg(card, 7, "Academic Title", &dg, &dg_len); + if (cmdline.read_dg8_flag || cmdline.read_all_dgs_flag) + read_dg(card, 8, "Date of Birth", &dg, &dg_len); + if (cmdline.read_dg9_flag || cmdline.read_all_dgs_flag) + read_dg(card, 9, "Place of Birth", &dg, &dg_len); + if (cmdline.read_dg10_flag || cmdline.read_all_dgs_flag) + read_dg(card, 10, "Nationality", &dg, &dg_len); + if (cmdline.read_dg11_flag || cmdline.read_all_dgs_flag) + read_dg(card, 11, "Sex", &dg, &dg_len); + if (cmdline.read_dg12_flag || cmdline.read_all_dgs_flag) + read_dg(card, 12, "Optional Data", &dg, &dg_len); + if (cmdline.read_dg13_flag || cmdline.read_all_dgs_flag) + read_dg(card, 13, "Birth Name", &dg, &dg_len); + if (cmdline.read_dg14_flag || cmdline.read_all_dgs_flag) + read_dg(card, 14, "DG 14", &dg, &dg_len); + if (cmdline.read_dg15_flag || cmdline.read_all_dgs_flag) + read_dg(card, 15, "DG 15", &dg, &dg_len); + if (cmdline.read_dg16_flag || cmdline.read_all_dgs_flag) + read_dg(card, 16, "DG 16", &dg, &dg_len); + if (cmdline.read_dg17_flag || cmdline.read_all_dgs_flag) + read_dg(card, 17, "Normal Place of Residence", &dg, &dg_len); + if (cmdline.read_dg18_flag || cmdline.read_all_dgs_flag) + read_dg(card, 18, "Community ID", &dg, &dg_len); + if (cmdline.read_dg19_flag || cmdline.read_all_dgs_flag) + read_dg(card, 19, "Residence Permit I", &dg, &dg_len); + if (cmdline.read_dg20_flag || cmdline.read_all_dgs_flag) + read_dg(card, 20, "Residence Permit II", &dg, &dg_len); + if (cmdline.read_dg21_flag || cmdline.read_all_dgs_flag) + read_dg(card, 21, "Optional Data", &dg, &dg_len); + + if (cmdline.write_dg17_given) + write_dg(card, 17, "Normal Place of Residence", cmdline.write_dg17_arg); + if (cmdline.write_dg18_given) + write_dg(card, 18, "Community ID", cmdline.write_dg18_arg); + if (cmdline.write_dg19_given) + write_dg(card, 19, "Residence Permit I", cmdline.write_dg19_arg); + if (cmdline.write_dg20_given) + write_dg(card, 20, "Residence Permit II", cmdline.write_dg20_arg); + if (cmdline.write_dg21_given) + write_dg(card, 21, "Optional Data", cmdline.write_dg21_arg); + break; + } if (cmdline.older_than_given) { unsigned char id_DateOfBirth[] = {6, 9, 4, 0, 127, 0, 7, 3, 1, 4, 1}; diff --git a/src/tools/npa-tool.ggo.in b/src/tools/npa-tool.ggo.in index 45a5bf0d79..8c0cddada0 100644 --- a/src/tools/npa-tool.ggo.in +++ b/src/tools/npa-tool.ggo.in @@ -94,92 +94,102 @@ option "disable-ca-checks" - "Disable passive authentication" flag off +section "Card application" +option "application" - + "What card application to select" + values="eID","eMRTD" default="eID" + enum + optional + section "Read and write data groups" +option "read-all-dgs" - + "Read all available data groups" + flag off option "read-dg1" - - "Read DG 1 (Document Type)" + "Read data group 1" flag off option "read-dg2" - - "Read DG 2 (Issuing State)" + "Read data group 2" flag off option "read-dg3" - - "Read DG 3 (Date of Expiry)" + "Read data group 3" flag off option "read-dg4" - - "Read DG 4 (Given Names)" + "Read data group 4" flag off option "read-dg5" - - "Read DG 5 (Family Names)" + "Read data group 5" flag off option "read-dg6" - - "Read DG 6 (Religious/Artistic Name)" + "Read data group 6" flag off option "read-dg7" - - "Read DG 7 (Academic Title)" + "Read data group 7" flag off option "read-dg8" - - "Read DG 8 (Date of Birth)" + "Read data group 8" flag off option "read-dg9" - - "Read DG 9 (Place of Birth)" + "Read data group 9" flag off option "read-dg10" - - "Read DG 10 (Nationality)" + "Read data group 10" flag off option "read-dg11" - - "Read DG 11 (Sex)" + "Read data group 11" flag off option "read-dg12" - - "Read DG 12 (Optional Data)" + "Read data group 12" flag off option "read-dg13" - - "Read DG 13 (Birth Name)" + "Read data group 13" flag off option "read-dg14" - - "Read DG 14" + "Read data group 14" flag off option "read-dg15" - - "Read DG 15" + "Read data group 15" flag off option "read-dg16" - - "Read DG 16" + "Read data group 16" flag off option "read-dg17" - - "Read DG 17 (Normal Place of Residence)" + "Read data group 17" flag off option "read-dg18" - - "Read DG 18 (Community ID)" + "Read data group 18" flag off option "read-dg19" - - "Read DG 19 (Residence Permit I)" + "Read data group 19" flag off option "read-dg20" - - "Read DG 20 (Residence Permit II)" + "Read data group 20" flag off option "read-dg21" - - "Read DG 21 (Optional Data)" + "Read data group 21" flag off option "write-dg17" - - "Write DG 17 (Normal Place of Residence)" + "Write data group 17" string typestr="HEX_STRING" optional option "write-dg18" - - "Write DG 18 (Community ID)" + "Write data group 18" string typestr="HEX_STRING" optional option "write-dg19" - - "Write DG 19 (Residence Permit I)" + "Write data group 19" string typestr="HEX_STRING" optional option "write-dg20" - - "Write DG 20 (Residence Permit II)" + "Write data group 20" string typestr="HEX_STRING" optional option "write-dg21" - - "Write DG 21 (Optional Data)" + "Write data group 21" string typestr="HEX_STRING" optional From c94bd0464a3aa3522507e7fb71f6e02d6625008c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 10 Mar 2021 11:02:31 +0100 Subject: [PATCH 3868/4321] iso7816: if index is beyond file, return EOF commands for data unit handling may return 6B00 if the specified index is too large (ISO 7816-4). Maybe SC_ERROR_OFFSET_TOO_LARGE would be more appropriate, but this is (1) currently not used only for internal errors and (2) this error code is not currently handled by sc_read_binary. Hence, we stick to SC_ERROR_FILE_END_REACHED. --- src/libopensc/iso7816.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 36b9e016da..ecd0cda4a5 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -157,8 +157,9 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r == SC_ERROR_FILE_END_REACHED) - LOG_FUNC_RETURN(ctx, (int)apdu.resplen); + if (r == SC_ERROR_FILE_END_REACHED + || r == SC_ERROR_INCORRECT_PARAMETERS) + LOG_FUNC_RETURN(ctx, apdu.resplen); LOG_TEST_RET(ctx, r, "Check SW error"); LOG_FUNC_RETURN(ctx, (int)apdu.resplen); From a62df3fdee1ce9027d1748df142ba350b31aa2e5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 May 2025 21:55:46 +0200 Subject: [PATCH 3869/4321] npa-tool: add info to DG when reading --- src/tools/npa-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 4b5bc04803..d74b5a8917 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -125,7 +125,7 @@ static void read_dg(sc_card_t *card, unsigned char sfid, const char *dg_str, /* 32768 is the maximum size of dg according to ICAO Doc 9303 */ char buf[32768*5]; sc_hex_dump(*dg, *dg_len, buf, sizeof buf); - fprintf(stdout, "Read %s", buf); + fprintf(stdout, "Read DG %02u %s:\n%s", sfid, dg_str, buf); } } From fa01235c60ffec1ab1db1751bca125f8176aaa50 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 May 2025 22:12:58 +0200 Subject: [PATCH 3870/4321] iso7816: allow less than requested data when reading via SFID and still continue --- src/libopensc/iso7816.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index ecd0cda4a5..6a10d948e0 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -157,9 +157,8 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r == SC_ERROR_FILE_END_REACHED - || r == SC_ERROR_INCORRECT_PARAMETERS) - LOG_FUNC_RETURN(ctx, apdu.resplen); + if (r == SC_ERROR_FILE_END_REACHED || r == SC_ERROR_INCORRECT_PARAMETERS) + LOG_FUNC_RETURN(ctx, (int)apdu.resplen); LOG_TEST_RET(ctx, r, "Check SW error"); LOG_FUNC_RETURN(ctx, (int)apdu.resplen); @@ -1530,11 +1529,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, /* emulate the behaviour of iso7816_read_binary */ r = (int)apdu.resplen; - while(1) { - if (r >= 0 && ((size_t) r) != read) { - *ef_len += r; - break; - } + while (1) { if (r <= 0) { if (*ef_len > 0) break; From 359fcb3b0b9973e59be7cc3c2d22f88f4fbb77bc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 May 2025 22:31:08 +0200 Subject: [PATCH 3871/4321] npa-tool: updated documentation --- doc/tools/npa-tool.1.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/tools/npa-tool.1.xml b/doc/tools/npa-tool.1.xml index cbd20fef50..b50eb79b70 100644 --- a/doc/tools/npa-tool.1.xml +++ b/doc/tools/npa-tool.1.xml @@ -10,7 +10,7 @@ npa-tool - displays information on the German eID card (neuer Personalausweis, nPA). + displays information of an ID card or ePassport. @@ -25,13 +25,15 @@ Description The npa-tool utility is used to display information - stored on the German eID card (neuer Personalausweis, nPA), - and to perform some write and verification operations. + stored on an ID card or on a passport and to perform some write and + verification operations. Extended Access Control version 2 is performed according to ICAO Doc - 9303 or BSI TR-03110 so that other identity cards and machine - readable travel documents (MRTDs) may be read as well. + 9303 or BSI TR-03110 so that an ICAO compliant machine readable + travel document (MRTD) as well as EAC compliant ID + cards, for example the German ID card (neuer Personalausweis, + nPA), may be read. From 2e85667aa9280c17f59d2b9b476fb1456ea3a7f2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 May 2025 14:15:57 +0200 Subject: [PATCH 3872/4321] fixed some generated code --- src/tools/npa-tool-cmdline.c | 2 +- src/tools/npa-tool-cmdline.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 3834dc4a75..fa8ba87812 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -538,7 +538,7 @@ check_possible_values(const char *val, const char *values[]) ++found; last = i; if (strlen(values[i]) == len) - return i; /* exact macth no need to check more */ + return i; /* exact match no need to check more */ } } diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index fef98a7b68..35dcff4350 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -85,10 +85,10 @@ struct gengetopt_args_info char * private_key_arg; /**< @brief Terminal's private key. */ char * private_key_orig; /**< @brief Terminal's private key original value given at command line. */ const char *private_key_help; /**< @brief Terminal's private key help description. */ - char * cvc_dir_arg; /**< @brief Where to look for the CVCA's certificate (default='/home/fm/.local/etc/eac/cvc'). */ + char * cvc_dir_arg; /**< @brief Where to look for the CVCA's certificate (default=''). */ char * cvc_dir_orig; /**< @brief Where to look for the CVCA's certificate original value given at command line. */ const char *cvc_dir_help; /**< @brief Where to look for the CVCA's certificate help description. */ - char * x509_dir_arg; /**< @brief Where to look for the CSCA's certificate (default='/home/fm/.local/etc/eac/x509'). */ + char * x509_dir_arg; /**< @brief Where to look for the CSCA's certificate (default=''). */ char * x509_dir_orig; /**< @brief Where to look for the CSCA's certificate original value given at command line. */ const char *x509_dir_help; /**< @brief Where to look for the CSCA's certificate help description. */ int disable_ta_checks_flag; /**< @brief Disable checking the validity period of CV certificates (default=off). */ From 8466d823b8e7d6c4f59b6652b9cb9eb12b5ca8a7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 May 2025 14:26:11 +0200 Subject: [PATCH 3873/4321] npa-tool: added documentation for --read-all-dgs and --application --- doc/tools/npa-tool.1.xml | 65 ++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/doc/tools/npa-tool.1.xml b/doc/tools/npa-tool.1.xml index b50eb79b70..c8b5692e66 100644 --- a/doc/tools/npa-tool.1.xml +++ b/doc/tools/npa-tool.1.xml @@ -252,60 +252,79 @@ + + Card application + + + app + + What application to select on the card, use eID for the + electronic identification application and eMRTD for the + ePassport application. (default=eID) + + + + + + Read and write data groups + + + Read all available data groups. + - Read data group 1: Document Type. + Read data group 1. - Read data group 2: Issuing State. + Read data group 2. - Read data group 3: Date of Expiry. + Read data group 3. - Read data group 4: Given Name(s). + Read data group 4. - Read data group 5: Family Name. + Read data group 5. - Read data group 6: Religious/Artistic Name. + Read data group 6. - Read data group 7: Academic Title. + Read data group 7. - Read data group 8: Date of Birth. + Read data group 8. - Read data group 9: Place of Birth. + Read data group 9. - Read data group 10: Nationality. + Read data group 10. - Read data group 11: Sex. + Read data group 11. - Read data group 12: Optional Data. + Read data group 12. - Read data group 13: Birth Name. + Read data group 13. @@ -321,47 +340,47 @@ - Read data group 17: Normal Place of Residence. + Read data group 17. - Read data group 18: Community ID. + Read data group 18. - Read data group 19: Residence Permit I. + Read data group 19. - Read data group 20: Residence Permit II. + Read data group 20. - Read data group 21: Optional Data. + Read data group 21. HEX_STRING - Write data group 17: Normal Place of Residence. + Write data group 17. HEX_STRING - Write data group 18: Community ID. + Write data group 18. HEX_STRING - Write data group 19: Residence Permit I. + Write data group 19. HEX_STRING - Write data group 20: Residence Permit II. + Write data group 20. HEX_STRING - Write data group 21: Optional Data. + Write data group 21. From 2742f82e74dbed7e781170cad0fdc4187dc88b80 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 28 May 2025 00:03:42 +0200 Subject: [PATCH 3874/4321] CI: do macos build with libressl fixes https://github.com/OpenSC/OpenSC/issues/2670 --- .github/build.sh | 18 ++++++++++++++---- .github/setup-macos.sh | 3 +++ .github/workflows/macos.yml | 25 +++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index da380fb7a2..782fe738d9 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -28,8 +28,13 @@ else fi if [ "$RUNNER_OS" == "macOS" ]; then - ./MacOSX/build - exit $? + if [ "$1" == "libressl" ]; then + export OPENSSL_LIBS="-L/opt/homebrew/opt/libressl/lib -lcrypto" + export OPENSSL_CFLAGS="-I/opt/homebrew/opt/libressl/include" + else + ./MacOSX/build + exit $? + fi fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then @@ -54,7 +59,10 @@ else fi # normal procedure - CONFIGURE_FLAGS="--disable-dependency-tracking --enable-doc" + CONFIGURE_FLAGS="--disable-dependency-tracking" + if [ "$RUNNER_OS" != "macOS" ]; then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-doc" + fi if [ "$1" != "clang-tidy" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS CLANGTIDY=/bin/no-clang-tidy" fi @@ -109,7 +117,9 @@ if [ "$1" == "dist" -o "$2" == "dist" ]; then make dist fi -$SUDO make install +if [ "$RUNNER_OS" != "macOS" ]; then + $SUDO make install +fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then # pack installed files wine "C:/Program Files/Inno Setup 5/ISCC.exe" win32/OpenSC.iss diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index aee52dd1a5..8cf3ec8a4a 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -3,6 +3,9 @@ set -ex -o xtrace brew install automake gengetopt help2man libtool +if [ "$1" == "libressl" ]; then + brew install libressl +fi # openSCToken export PATH="/usr/local/opt/ccache/libexec:$PATH" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index fba351b4d7..8a0eebb355 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -43,6 +43,31 @@ jobs: env: KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} + - name: Upload test logs + uses: actions/upload-artifact@v4 + if: failure() + with: + name: ${{ matrix.os }}-logs + path: | + config.log + + build-libressl: + strategy: + matrix: + os: [macos-15, macos-14, macos-13] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - run: .github/setup-macos.sh libressl + - run: .github/build.sh libressl + - run: .github/cleanup-macos.sh + - name: Upload test logs + uses: actions/upload-artifact@v4 + if: failure() + with: + name: ${{ matrix.os }}-libressl-logs + path: | + config.log push-artifacts: runs-on: macos-latest From 5713f5053cec5a852f46673d81858fd99011818a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 May 2025 16:28:29 +0200 Subject: [PATCH 3875/4321] pkcs11: Add CK_GCM_MESSAGE_PARAMS and CK_GENERATOR_FUNCTION definitions Signed-off-by: Jakub Jelen --- src/pkcs11/pkcs11-display.c | 29 +++++++++++++++++++---------- src/pkcs11/pkcs11-display.h | 23 ++++++++++++----------- src/pkcs11/pkcs11.h | 24 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 86f8b858ac..a8a498cd58 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -588,6 +588,14 @@ static enum_specs ck_mgf_s[] = { { CKG_MGF1_SHA3_512, "CKG_MGF1_SHA3_512" }, }; +static enum_specs ck_generate_s[] = { + { CKG_NO_GENERATE , "CKG_NO_GENERATE " }, + { CKG_GENERATE , "CKG_GENERATE " }, + { CKG_GENERATE_COUNTER , "CKG_GENERATE_COUNTER " }, + { CKG_GENERATE_RANDOM , "CKG_GENERATE_RANDOM " }, + { CKG_GENERATE_COUNTER_XOR, "CKG_GENERATE_COUNTER_XOR" }, +}; + static enum_specs ck_err_s[] = { { CKR_OK, "CKR_OK" }, { CKR_CANCEL, "CKR_CANCEL" }, @@ -702,16 +710,17 @@ static enum_specs ck_ckd_s[] = { #define SZ_SPECS sizeof(enum_specs) enum_spec ck_types[] = { - { OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" }, - { PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE"}, - { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, - { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, - { MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, - { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE"}, - { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, - { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, - { CKD_T, ck_ckd_s, sizeof(ck_ckd_s) / SZ_SPECS, "CK_EC_KDF_TYPE" }, - { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, + { OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" }, + { PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE" }, + { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, + { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, + { MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, + { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE" }, + { GENERATE_T, ck_generate_s, sizeof(ck_generate_s) / SZ_SPECS, "CK_GENERATOR_FUNCTION"}, + { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, + { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, + { CKD_T, ck_ckd_s, sizeof(ck_ckd_s) / SZ_SPECS, "CK_EC_KDF_TYPE" }, + { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, }; static enum_spec ck_key_t[] = { { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" } }; diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index cc6510f434..06d79d8fe2 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -51,17 +51,18 @@ typedef struct { void * arg; } type_spec; -enum ck_type{ - OBJ_T, - PROFILE_T, - KEY_T, - CRT_T, - MEC_T, - MGF_T, - USR_T, - STA_T, - CKD_T, - RV_T +enum ck_type { + OBJ_T, + PROFILE_T, + KEY_T, + CRT_T, + MEC_T, + MGF_T, + GENERATE_T, + USR_T, + STA_T, + CKD_T, + RV_T }; const char *lookup_enum_spec(enum_spec *spec, CK_ULONG value); diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 236712bd01..5d26ce8c22 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -155,6 +155,8 @@ extern "C" { #define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE +#define ck_generator_function_t CK_GENERATOR_FUNCTION + #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen @@ -909,6 +911,8 @@ typedef struct CK_ECMQV_DERIVE_PARAMS { typedef unsigned long ck_rsa_pkcs_mgf_type_t; typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; +typedef unsigned long ck_generator_function_t; + typedef struct CK_RSA_PKCS_OAEP_PARAMS { CK_MECHANISM_TYPE hashAlg; CK_RSA_PKCS_MGF_TYPE mgf; @@ -944,6 +948,22 @@ typedef struct CK_GCM_PARAMS { unsigned long ulTagBits; } CK_GCM_PARAMS; +/* CKG (GCM) */ +#define CKG_NO_GENERATE (0x00000000UL) +#define CKG_GENERATE (0x00000001UL) +#define CKG_GENERATE_COUNTER (0x00000002UL) +#define CKG_GENERATE_RANDOM (0x00000003UL) +#define CKG_GENERATE_COUNTER_XOR (0x00000004UL) + +typedef struct CK_GCM_MESSAGE_PARAMS { + void *pIv; + unsigned long ulIvLen; + unsigned long ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + void *pTag; + unsigned long ulTagBits; +} CK_GCM_MESSAGE_PARAMS; + typedef struct CK_CCM_PARAMS { unsigned long ulDataLen; unsigned char *pNonce; @@ -1799,6 +1819,8 @@ typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; +typedef ck_generator_function_t *CK_GENERATOR_FUNCTION_PTR; + typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; @@ -1879,6 +1901,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_rsa_pkcs_mgf_type_t +#undef ck_generator_function_t + #undef ck_mechanism #undef parameter #undef parameter_len From 5b7fb6d26d745e460291c839185a26daf0d18f61 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 26 May 2025 16:28:57 +0200 Subject: [PATCH 3876/4321] pkcs11-spy: Improve printing mechanism parameters Some mechanisms in PKCS#11 3.0 have different parameters so when printing them, we need to take into the account the context where the parameter is provided. In this case, the AES-GCM mechanisms has different parameters when called with normal C_Encrypt() API and message based C_MessageEncryptInit() API. Not following the context leads into printing nonsense. I also took the opportunity here to make sure the parameters length is verified against the expected parameter size and possible inconsistencies reported. Signed-off-by: Jakub Jelen --- src/pkcs11/pkcs11-spy.c | 215 +++++++++++++++++++++------------------- 1 file changed, 114 insertions(+), 101 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 73b65f4555..1ed2a5d200 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -19,8 +19,9 @@ #include "config.h" -#include +#include #include +#include #include #ifdef _WIN32 @@ -418,7 +419,7 @@ spy_attribute_list_out(const char *name, CK_ATTRIBUTE_PTR pTemplate, } static void -spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) +spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism, bool is_c_message) { char param_name[64]; const char *mec_name; @@ -441,118 +442,130 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism) } } + /* This is common case for all mechanisms */ + if (pMechanism->pParameter == NULL) { + fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + return; + } + switch (pMechanism->mechanism) { - case CKM_AES_GCM: - if (pMechanism->pParameter != NULL) { - CK_GCM_PARAMS *param = - (CK_GCM_PARAMS *) pMechanism->pParameter; + case CKM_AES_GCM: { + if (!is_c_message && pMechanism->ulParameterLen == sizeof(CK_GCM_PARAMS)) { + CK_GCM_PARAMS *param = (CK_GCM_PARAMS *)pMechanism->pParameter; snprintf(param_name, sizeof(param_name), "%s->pParameter->pIv[ulIvLen]", name); - spy_dump_string_in(param_name, - param->pIv, param->ulIvLen); + spy_dump_string_in(param_name, param->pIv, param->ulIvLen); snprintf(param_name, sizeof(param_name), "%s->pParameter->ulIvBits", name); spy_dump_ulong_in(param_name, param->ulIvBits); snprintf(param_name, sizeof(param_name), "%s->pParameter->pAAD[ulAADLen]", name); - spy_dump_string_in(param_name, - param->pAAD, param->ulAADLen); + spy_dump_string_in(param_name, param->pAAD, param->ulAADLen); fprintf(spy_output, "[in] %s->pParameter->ulTagBits = %lu\n", name, param->ulTagBits); + } else if (is_c_message && pMechanism->ulParameterLen == sizeof(CK_GCM_MESSAGE_PARAMS)) { + CK_GCM_MESSAGE_PARAMS *param = (CK_GCM_MESSAGE_PARAMS *)pMechanism->pParameter; + snprintf(param_name, sizeof(param_name), "%s->pParameter->pIv[ulIvLen]", name); + spy_dump_string_in(param_name, param->pIv, param->ulIvLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter->ulIvFixedBits", name); + spy_dump_ulong_in(param_name, param->ulIvFixedBits); + fprintf(spy_output, "[in] %s->pParameter->ivGenerator = %s\n", name, + lookup_enum(GENERATE_T, param->ivGenerator)); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pTag", name); + spy_dump_string_in(param_name, param->pTag, param->ulTagBits / 8); } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); - break; + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); } break; - case CKM_AES_CCM: - if (pMechanism->pParameter != NULL) { - CK_CCM_PARAMS *param = (CK_CCM_PARAMS *)pMechanism->pParameter; - snprintf(param_name, sizeof(param_name), "%s->pParameter->ulDataLen", name); - spy_dump_ulong_in(param_name, param->ulDataLen); - snprintf(param_name, sizeof(param_name), "%s->pParameter->pNonce[ulNonceLen]", name); - spy_dump_string_in(param_name, param->pNonce, param->ulNonceLen); - snprintf(param_name, sizeof(param_name), "%s->pParameter->pAAD[ulAADLen]", name); - spy_dump_string_in(param_name, param->pAAD, param->ulAADLen); - fprintf(spy_output, "[in] %s->pParameter->ulMacLen = %lu\n", name, param->ulMACLen); - } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + } + case CKM_AES_CCM: { + if (pMechanism->ulParameterLen != sizeof(CK_CCM_PARAMS)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); break; } + + CK_CCM_PARAMS *param = (CK_CCM_PARAMS *)pMechanism->pParameter; + snprintf(param_name, sizeof(param_name), "%s->pParameter->ulDataLen", name); + spy_dump_ulong_in(param_name, param->ulDataLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pNonce[ulNonceLen]", name); + spy_dump_string_in(param_name, param->pNonce, param->ulNonceLen); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pAAD[ulAADLen]", name); + spy_dump_string_in(param_name, param->pAAD, param->ulAADLen); + fprintf(spy_output, "[in] %s->pParameter->ulMacLen = %lu\n", name, param->ulMACLen); break; + } case CKM_ECDH1_DERIVE: - case CKM_ECDH1_COFACTOR_DERIVE: - if (pMechanism->pParameter != NULL) { - CK_ECDH1_DERIVE_PARAMS *param = - (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, - lookup_enum(CKD_T, param->kdf)); - fprintf(spy_output, "[in] %s->pParameter->pSharedData[ulSharedDataLen] = ", name); - print_generic(spy_output, 0, param->pSharedData, - param->ulSharedDataLen, NULL); - fprintf(spy_output, "[in] %s->pParameter->pPublicData[ulPublicDataLen] = ", name); - print_generic(spy_output, 0, param->pPublicData, - param->ulPublicDataLen, NULL); - } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + case CKM_ECDH1_COFACTOR_DERIVE: { + if (pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); break; } + + CK_ECDH1_DERIVE_PARAMS *param = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); + fprintf(spy_output, "[in] %s->pParameter->pSharedData[ulSharedDataLen] = ", name); + print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); + fprintf(spy_output, "[in] %s->pParameter->pPublicData[ulPublicDataLen] = ", name); + print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); break; - case CKM_ECMQV_DERIVE: - if (pMechanism->pParameter != NULL) { - CK_ECMQV_DERIVE_PARAMS *param = - (CK_ECMQV_DERIVE_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, - lookup_enum(CKD_T, param->kdf)); - fprintf(spy_output, "%s->pParameter->pSharedData[ulSharedDataLen] = ", name); - print_generic(spy_output, 0, param->pSharedData, - param->ulSharedDataLen, NULL); - fprintf(spy_output, "%s->pParameter->pPublicData[ulPublicDataLen] = ", name); - print_generic(spy_output, 0, param->pPublicData, - param->ulPublicDataLen, NULL); - fprintf(spy_output, "%s->pParameter->ulPrivateDataLen = %lu", name, - param->ulPrivateDataLen); - fprintf(spy_output, "%s->pParameter->hPrivateData = %lu", name, param->hPrivateData); - fprintf(spy_output, "%s->pParameter->pPublicData2[ulPublicDataLen2] = ", name); - print_generic(spy_output, 0, param->pPublicData2, - param->ulPublicDataLen2, NULL); - fprintf(spy_output, "%s->pParameter->publicKey = %lu", name, param->publicKey); - } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + } + case CKM_ECMQV_DERIVE: { + if (pMechanism->ulParameterLen != sizeof(CK_ECMQV_DERIVE_PARAMS)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); break; } + + CK_ECMQV_DERIVE_PARAMS *param = (CK_ECMQV_DERIVE_PARAMS *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); + fprintf(spy_output, "%s->pParameter->pSharedData[ulSharedDataLen] = ", name); + print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); + fprintf(spy_output, "%s->pParameter->pPublicData[ulPublicDataLen] = ", name); + print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); + fprintf(spy_output, "%s->pParameter->ulPrivateDataLen = %lu", name, param->ulPrivateDataLen); + fprintf(spy_output, "%s->pParameter->hPrivateData = %lu", name, param->hPrivateData); + fprintf(spy_output, "%s->pParameter->pPublicData2[ulPublicDataLen2] = ", name); + print_generic(spy_output, 0, param->pPublicData2, param->ulPublicDataLen2, NULL); + fprintf(spy_output, "%s->pParameter->publicKey = %lu", name, param->publicKey); break; - case CKM_RSA_PKCS_OAEP: - if (pMechanism->pParameter != NULL) { - CK_RSA_PKCS_OAEP_PARAMS *param = - (CK_RSA_PKCS_OAEP_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "[in] %s->pParameter->source = %lu\n", name, param->source); - snprintf(param_name, sizeof(param_name), "%s->pParameter->pSourceData[ulSourceDalaLen]", name); - spy_dump_string_in(param_name, - param->pSourceData, param->ulSourceDataLen); - } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + } + case CKM_RSA_PKCS_OAEP: { + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); break; } + CK_RSA_PKCS_OAEP_PARAMS *param = (CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "[in] %s->pParameter->source = %lu\n", name, param->source); + snprintf(param_name, sizeof(param_name), "%s->pParameter->pSourceData[ulSourceDalaLen]", name); + spy_dump_string_in(param_name, param->pSourceData, param->ulSourceDataLen); break; + } case CKM_RSA_PKCS_PSS: case CKM_SHA1_RSA_PKCS_PSS: case CKM_SHA256_RSA_PKCS_PSS: case CKM_SHA384_RSA_PKCS_PSS: - case CKM_SHA512_RSA_PKCS_PSS: - if (pMechanism->pParameter != NULL) { - CK_RSA_PKCS_PSS_PARAMS *param = - (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "[in] %s->pParameter->sLen = %lu\n", name, - param->sLen); - } else { - fprintf(spy_output, "[in] %s->pParameter = NULL\n", name); + case CKM_SHA512_RSA_PKCS_PSS: { + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); break; } + CK_RSA_PKCS_PSS_PARAMS *param = (CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hashAlg = %s\n", name, + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "[in] %s->pParameter->mgf = %s\n", name, lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "[in] %s->pParameter->sLen = %lu\n", name, param->sLen); break; + } default: snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); @@ -1029,7 +1042,7 @@ C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_EncryptInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_EncryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1093,7 +1106,7 @@ C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT enter("C_DecryptInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_DecryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1158,7 +1171,7 @@ C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) enter("C_DigestInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); rv = po->C_DigestInit(hSession, pMechanism); return retne(rv); } @@ -1224,7 +1237,7 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA enter("C_SignInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_SignInit(hSession, pMechanism, hKey); return retne(rv); @@ -1285,7 +1298,7 @@ C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OB enter("C_SignRecoverInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_SignRecoverInit(hSession, pMechanism, hKey); return retne(rv); @@ -1316,7 +1329,7 @@ C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_ enter("C_VerifyInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_VerifyInit(hSession, pMechanism, hKey); return retne(rv); @@ -1369,7 +1382,7 @@ C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_VerifyRecoverInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hKey", hKey); rv = po->C_VerifyRecoverInit(hSession, pMechanism, hKey); return retne(rv); @@ -1462,7 +1475,7 @@ C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_GenerateKey"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_attribute_list_in("pTemplate", pTemplate, ulCount); rv = po->C_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey); if (rv == CKR_OK) @@ -1481,7 +1494,7 @@ C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_GenerateKeyPair"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_attribute_list_in("pPublicKeyTemplate", pPublicKeyTemplate, ulPublicKeyAttributeCount); spy_attribute_list_in("pPrivateKeyTemplate", pPrivateKeyTemplate, ulPrivateKeyAttributeCount); rv = po->C_GenerateKeyPair(hSession, pMechanism, @@ -1504,7 +1517,7 @@ C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_WrapKey"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hWrappingKey", hWrappingKey); spy_dump_ulong_in("hKey", hKey); rv = po->C_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); @@ -1527,7 +1540,7 @@ C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, enter("C_UnwrapKey"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hUnwrappingKey", hUnwrappingKey); spy_dump_string_in("pWrappedKey[ulWrappedKeyLen]", pWrappedKey, ulWrappedKeyLen); spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); @@ -1546,7 +1559,7 @@ C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_H enter("C_DeriveKey"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, false); spy_dump_ulong_in("hBaseKey", hBaseKey); spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); rv = po->C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); @@ -1829,7 +1842,7 @@ C_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK enter("C_MessageEncryptInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, true); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageEncryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1912,7 +1925,7 @@ C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK enter("C_MessageDecryptInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, true); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageDecryptInit(hSession, pMechanism, hKey); return retne(rv); @@ -1995,7 +2008,7 @@ C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OB enter("C_MessageSignInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, true); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageSignInit(hSession, pMechanism, hKey); return retne(rv); @@ -2067,7 +2080,7 @@ C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ enter("C_MessageVerifyInit"); spy_dump_ulong_in("hSession", hSession); - spy_dump_mechanism_in("pMechanism", pMechanism); + spy_dump_mechanism_in("pMechanism", pMechanism, true); spy_dump_ulong_in("hKey", hKey); rv = po->C_MessageVerifyInit(hSession, pMechanism, hKey); return retne(rv); From 0ccc20f481b179b59d798dc8c41ba154e55811e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 May 2025 15:41:53 +0200 Subject: [PATCH 3877/4321] pkcs11-register: allow explicitly specifying an app to configure fixes https://github.com/OpenSC/OpenSC/issues/3404 --- src/tools/pkcs11-register-cmdline.c | 148 +++++++++++++++++++++------- src/tools/pkcs11-register-cmdline.h | 22 ++++- src/tools/pkcs11-register.c | 8 +- src/tools/pkcs11-register.ggo.in | 12 ++- 4 files changed, 140 insertions(+), 50 deletions(-) diff --git a/src/tools/pkcs11-register-cmdline.c b/src/tools/pkcs11-register-cmdline.c index 467fd927ab..4d5c4daa44 100644 --- a/src/tools/pkcs11-register-cmdline.c +++ b/src/tools/pkcs11-register-cmdline.c @@ -34,20 +34,20 @@ const char *gengetopt_args_info_versiontext = ""; const char *gengetopt_args_info_description = "Install a PKCS#11 module to known applications."; const char *gengetopt_args_info_help[] = { - " -h, --help Print help and exit", - " -V, --version Print version and exit", - " -m, --module=FILENAME Specify the module to load (default=`OpenSC's\n PKCS#11 module')", - " --skip-chrome Don't install module to Chrome (default=on)", - " --skip-firefox Don't install module to Firefox (default=on)", - " --skip-thunderbird Don't install module to Thunderbird (default=off)", - " --skip-seamonkey Don't install module to SeaMonkey (default=off)", + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -m, --module=FILENAME Specify the module to load (default=`OpenSC's\n PKCS#11 module')", + " --skip-chrome=ENUM Don't install module to Chrome (possible\n values=\"on\", \"off\" default=`on')", + " --skip-firefox=ENUM Don't install module to Firefox (possible\n values=\"on\", \"off\" default=`on')", + " --skip-thunderbird=ENUM Don't install module to Thunderbird (possible\n values=\"on\", \"off\" default=`off')", + " --skip-seamonkey=ENUM Don't install module to SeaMonkey (possible\n values=\"on\", \"off\" default=`off')", "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; typedef enum {ARG_NO - , ARG_FLAG , ARG_STRING + , ARG_ENUM } cmdline_parser_arg_type; static @@ -60,6 +60,11 @@ cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args struct cmdline_parser_params *params, const char *additional_error); +const char *cmdline_parser_skip_chrome_values[] = {"on", "off", 0}; /*< Possible values for skip-chrome. */ +const char *cmdline_parser_skip_firefox_values[] = {"on", "off", 0}; /*< Possible values for skip-firefox. */ +const char *cmdline_parser_skip_thunderbird_values[] = {"on", "off", 0}; /*< Possible values for skip-thunderbird. */ +const char *cmdline_parser_skip_seamonkey_values[] = {"on", "off", 0}; /*< Possible values for skip-seamonkey. */ + static char * gengetopt_strdup (const char *s); @@ -81,10 +86,14 @@ void clear_args (struct gengetopt_args_info *args_info) FIX_UNUSED (args_info); args_info->module_arg = gengetopt_strdup ("OpenSC's PKCS#11 module"); args_info->module_orig = NULL; - args_info->skip_chrome_flag = 1; - args_info->skip_firefox_flag = 1; - args_info->skip_thunderbird_flag = 0; - args_info->skip_seamonkey_flag = 0; + args_info->skip_chrome_arg = skip_chrome_arg_on; + args_info->skip_chrome_orig = NULL; + args_info->skip_firefox_arg = skip_firefox_arg_on; + args_info->skip_firefox_orig = NULL; + args_info->skip_thunderbird_arg = skip_thunderbird_arg_off; + args_info->skip_thunderbird_orig = NULL; + args_info->skip_seamonkey_arg = skip_seamonkey_arg_off; + args_info->skip_seamonkey_orig = NULL; } @@ -191,19 +200,64 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->module_arg)); free_string_field (&(args_info->module_orig)); + free_string_field (&(args_info->skip_chrome_orig)); + free_string_field (&(args_info->skip_firefox_orig)); + free_string_field (&(args_info->skip_thunderbird_orig)); + free_string_field (&(args_info->skip_seamonkey_orig)); clear_given (args_info); } +/** + * @param val the value to check + * @param values the possible values + * @return the index of the matched value: + * -1 if no value matched, + * -2 if more than one value has matched + */ +static int +check_possible_values(const char *val, const char *values[]) +{ + int i, found, last; + size_t len; + + if (!val) /* otherwise strlen() crashes below */ + return -1; /* -1 means no argument for the option */ + + found = last = 0; + + for (i = 0, len = strlen(val); values[i]; ++i) + { + if (strncmp(val, values[i], len) == 0) + { + ++found; + last = i; + if (strlen(values[i]) == len) + return i; /* exact macth no need to check more */ + } + } + + if (found == 1) /* one match: OK */ + return last; + + return (found ? -2 : -1); /* return many values or none matched */ +} + static void write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) { - FIX_UNUSED (values); + int found = -1; if (arg) { - fprintf(outfile, "%s=\"%s\"\n", opt, arg); + if (values) { + found = check_possible_values(arg, values); + } + if (found >= 0) + fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); + else + fprintf(outfile, "%s=\"%s\"\n", opt, arg); } else { fprintf(outfile, "%s\n", opt); } @@ -228,13 +282,13 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) if (args_info->module_given) write_into_file(outfile, "module", args_info->module_orig, 0); if (args_info->skip_chrome_given) - write_into_file(outfile, "skip-chrome", 0, 0 ); + write_into_file(outfile, "skip-chrome", args_info->skip_chrome_orig, cmdline_parser_skip_chrome_values); if (args_info->skip_firefox_given) - write_into_file(outfile, "skip-firefox", 0, 0 ); + write_into_file(outfile, "skip-firefox", args_info->skip_firefox_orig, cmdline_parser_skip_firefox_values); if (args_info->skip_thunderbird_given) - write_into_file(outfile, "skip-thunderbird", 0, 0 ); + write_into_file(outfile, "skip-thunderbird", args_info->skip_thunderbird_orig, cmdline_parser_skip_thunderbird_values); if (args_info->skip_seamonkey_given) - write_into_file(outfile, "skip-seamonkey", 0, 0 ); + write_into_file(outfile, "skip-seamonkey", args_info->skip_seamonkey_orig, cmdline_parser_skip_seamonkey_values); i = EXIT_SUCCESS; @@ -389,7 +443,18 @@ int update_arg(void *field, char **orig_field, return 1; /* failure */ } - FIX_UNUSED (default_value); + if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) + { + if (short_opt != '-') + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } if (field_given && *field_given && ! override) return 0; @@ -401,8 +466,8 @@ int update_arg(void *field, char **orig_field, val = possible_values[found]; switch(arg_type) { - case ARG_FLAG: - *((int *)field) = !*((int *)field); + case ARG_ENUM: + if (val) *((int *)field) = found; break; case ARG_STRING: if (val) { @@ -421,7 +486,6 @@ int update_arg(void *field, char **orig_field, /* store the original value */ switch(arg_type) { case ARG_NO: - case ARG_FLAG: break; default: if (value && orig_field) { @@ -485,10 +549,10 @@ cmdline_parser_internal ( { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, { "module", 1, NULL, 'm' }, - { "skip-chrome", 0, NULL, 0 }, - { "skip-firefox", 0, NULL, 0 }, - { "skip-thunderbird", 0, NULL, 0 }, - { "skip-seamonkey", 0, NULL, 0 }, + { "skip-chrome", 1, NULL, 0 }, + { "skip-firefox", 1, NULL, 0 }, + { "skip-thunderbird", 1, NULL, 0 }, + { "skip-seamonkey", 1, NULL, 0 }, { 0, 0, 0, 0 } }; @@ -527,9 +591,11 @@ cmdline_parser_internal ( { - if (update_arg((void *)&(args_info->skip_chrome_flag), 0, &(args_info->skip_chrome_given), - &(local_args_info.skip_chrome_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "skip-chrome", '-', + if (update_arg( (void *)&(args_info->skip_chrome_arg), + &(args_info->skip_chrome_orig), &(args_info->skip_chrome_given), + &(local_args_info.skip_chrome_given), optarg, cmdline_parser_skip_chrome_values, "on", ARG_ENUM, + check_ambiguity, override, 0, 0, + "skip-chrome", '-', additional_error)) goto failure; @@ -539,9 +605,11 @@ cmdline_parser_internal ( { - if (update_arg((void *)&(args_info->skip_firefox_flag), 0, &(args_info->skip_firefox_given), - &(local_args_info.skip_firefox_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "skip-firefox", '-', + if (update_arg( (void *)&(args_info->skip_firefox_arg), + &(args_info->skip_firefox_orig), &(args_info->skip_firefox_given), + &(local_args_info.skip_firefox_given), optarg, cmdline_parser_skip_firefox_values, "on", ARG_ENUM, + check_ambiguity, override, 0, 0, + "skip-firefox", '-', additional_error)) goto failure; @@ -551,9 +619,11 @@ cmdline_parser_internal ( { - if (update_arg((void *)&(args_info->skip_thunderbird_flag), 0, &(args_info->skip_thunderbird_given), - &(local_args_info.skip_thunderbird_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "skip-thunderbird", '-', + if (update_arg( (void *)&(args_info->skip_thunderbird_arg), + &(args_info->skip_thunderbird_orig), &(args_info->skip_thunderbird_given), + &(local_args_info.skip_thunderbird_given), optarg, cmdline_parser_skip_thunderbird_values, "off", ARG_ENUM, + check_ambiguity, override, 0, 0, + "skip-thunderbird", '-', additional_error)) goto failure; @@ -563,9 +633,11 @@ cmdline_parser_internal ( { - if (update_arg((void *)&(args_info->skip_seamonkey_flag), 0, &(args_info->skip_seamonkey_given), - &(local_args_info.skip_seamonkey_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "skip-seamonkey", '-', + if (update_arg( (void *)&(args_info->skip_seamonkey_arg), + &(args_info->skip_seamonkey_orig), &(args_info->skip_seamonkey_given), + &(local_args_info.skip_seamonkey_given), optarg, cmdline_parser_skip_seamonkey_values, "off", ARG_ENUM, + check_ambiguity, override, 0, 0, + "skip-seamonkey", '-', additional_error)) goto failure; diff --git a/src/tools/pkcs11-register-cmdline.h b/src/tools/pkcs11-register-cmdline.h index 8262da3e42..16d5179b35 100644 --- a/src/tools/pkcs11-register-cmdline.h +++ b/src/tools/pkcs11-register-cmdline.h @@ -34,6 +34,11 @@ extern "C" { #define CMDLINE_PARSER_VERSION VERSION #endif +enum enum_skip_chrome { skip_chrome__NULL = -1, skip_chrome_arg_on = 0, skip_chrome_arg_off }; +enum enum_skip_firefox { skip_firefox__NULL = -1, skip_firefox_arg_on = 0, skip_firefox_arg_off }; +enum enum_skip_thunderbird { skip_thunderbird__NULL = -1, skip_thunderbird_arg_on = 0, skip_thunderbird_arg_off }; +enum enum_skip_seamonkey { skip_seamonkey__NULL = -1, skip_seamonkey_arg_on = 0, skip_seamonkey_arg_off }; + /** @brief Where the command line options are stored */ struct gengetopt_args_info { @@ -42,13 +47,17 @@ struct gengetopt_args_info char * module_arg; /**< @brief Specify the module to load (default='OpenSC's PKCS#11 module'). */ char * module_orig; /**< @brief Specify the module to load original value given at command line. */ const char *module_help; /**< @brief Specify the module to load help description. */ - int skip_chrome_flag; /**< @brief Don't install module to Chrome (default=on). */ + enum enum_skip_chrome skip_chrome_arg; /**< @brief Don't install module to Chrome (default='on'). */ + char * skip_chrome_orig; /**< @brief Don't install module to Chrome original value given at command line. */ const char *skip_chrome_help; /**< @brief Don't install module to Chrome help description. */ - int skip_firefox_flag; /**< @brief Don't install module to Firefox (default=on). */ + enum enum_skip_firefox skip_firefox_arg; /**< @brief Don't install module to Firefox (default='on'). */ + char * skip_firefox_orig; /**< @brief Don't install module to Firefox original value given at command line. */ const char *skip_firefox_help; /**< @brief Don't install module to Firefox help description. */ - int skip_thunderbird_flag; /**< @brief Don't install module to Thunderbird (default=off). */ + enum enum_skip_thunderbird skip_thunderbird_arg; /**< @brief Don't install module to Thunderbird (default='off'). */ + char * skip_thunderbird_orig; /**< @brief Don't install module to Thunderbird original value given at command line. */ const char *skip_thunderbird_help; /**< @brief Don't install module to Thunderbird help description. */ - int skip_seamonkey_flag; /**< @brief Don't install module to SeaMonkey (default=off). */ + enum enum_skip_seamonkey skip_seamonkey_arg; /**< @brief Don't install module to SeaMonkey (default='off'). */ + char * skip_seamonkey_orig; /**< @brief Don't install module to SeaMonkey original value given at command line. */ const char *skip_seamonkey_help; /**< @brief Don't install module to SeaMonkey help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ @@ -182,6 +191,11 @@ void cmdline_parser_free (struct gengetopt_args_info *args_info); int cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name); +extern const char *cmdline_parser_skip_chrome_values[]; /**< @brief Possible values for skip-chrome. */ +extern const char *cmdline_parser_skip_firefox_values[]; /**< @brief Possible values for skip-firefox. */ +extern const char *cmdline_parser_skip_thunderbird_values[]; /**< @brief Possible values for skip-thunderbird. */ +extern const char *cmdline_parser_skip_seamonkey_values[]; /**< @brief Possible values for skip-seamonkey. */ + #ifdef __cplusplus } diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index cfc604d6d1..02ecb6b109 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -332,13 +332,13 @@ main(int argc, char **argv) return 1; } - if (!cmdline.skip_chrome_flag) + if (cmdline.skip_chrome_arg != skip_chrome_arg_on) add_module_chrome(module_path, module_name, exclude_module_path); - if (!cmdline.skip_firefox_flag) + if (cmdline.skip_firefox_arg != skip_firefox_arg_on) add_module_firefox(module_path, module_name, exclude_module_path); - if (!cmdline.skip_thunderbird_flag) + if (cmdline.skip_thunderbird_arg != skip_thunderbird_arg_on) add_module_thunderbird(module_path, module_name, exclude_module_path); - if (!cmdline.skip_seamonkey_flag) + if (cmdline.skip_seamonkey_arg != skip_seamonkey_arg_on) add_module_seamonkey(module_path, module_name, exclude_module_path); cmdline_parser_free (&cmdline); diff --git a/src/tools/pkcs11-register.ggo.in b/src/tools/pkcs11-register.ggo.in index 39f44c48a7..b6e432ea7f 100644 --- a/src/tools/pkcs11-register.ggo.in +++ b/src/tools/pkcs11-register.ggo.in @@ -8,19 +8,23 @@ option "module" m option "skip-chrome" - "Don't install module to Chrome" - flag @PKCS11_REGISTER_SKIP_FIREFOX@ + enum values="on","off" optional + default="@PKCS11_REGISTER_SKIP_FIREFOX@" option "skip-firefox" - "Don't install module to Firefox" - flag @PKCS11_REGISTER_SKIP_FIREFOX@ + enum values="on","off" optional + default="@PKCS11_REGISTER_SKIP_FIREFOX@" option "skip-thunderbird" - "Don't install module to Thunderbird" - flag off + enum values="on","off" optional + default="off" option "skip-seamonkey" - "Don't install module to SeaMonkey" - flag off + enum values="on","off" optional + default="off" text " Report bugs to @PACKAGE_BUGREPORT@ From 5ba68bd95527bb818264ec3f9e46a0462d4e3e8b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 May 2025 19:16:39 +0200 Subject: [PATCH 3878/4321] fix spelling --- src/tools/pkcs11-register-cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-register-cmdline.c b/src/tools/pkcs11-register-cmdline.c index 4d5c4daa44..1c6a11e781 100644 --- a/src/tools/pkcs11-register-cmdline.c +++ b/src/tools/pkcs11-register-cmdline.c @@ -235,7 +235,7 @@ check_possible_values(const char *val, const char *values[]) ++found; last = i; if (strlen(values[i]) == len) - return i; /* exact macth no need to check more */ + return i; /* exact match no need to check more */ } } From 15f60c6169a09a292b0e374fad0bddefc171af61 Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Thu, 22 May 2025 14:21:42 -0400 Subject: [PATCH 3879/4321] pkcs11-tool: allocate for C_Sign/C_SignFinal This will become necessary for post-quantum cryptography which hash large signature sizes --- src/tools/pkcs11-tool.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2cae357159..fee6113347 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2413,7 +2413,8 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char in_buffer[1025], sig_buffer[512]; + unsigned char in_buffer[1025]; + CK_BYTE_PTR sig_buffer = NULL; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; CK_MAC_GENERAL_PARAMS mac_gen_param; @@ -2421,7 +2422,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, .phFlag = CK_FALSE, }; CK_RV rv; - CK_ULONG sig_len; + CK_ULONG sig_len = 0; int fd; ssize_t sz; unsigned long hashlen; @@ -2491,8 +2492,13 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if ((getCLASS(session, key) == CKO_PRIVATE_KEY) && getALWAYS_AUTHENTICATE(session, key)) login(session,CKU_CONTEXT_SPECIFIC); - sig_len = sizeof(sig_buffer); rv = p11->C_Sign(session, in_buffer, sz, sig_buffer, &sig_len); + if (rv == CKR_OK) { + sig_buffer = malloc(sig_len); + if (!sig_buffer) + util_fatal("malloc() failure\n"); + rv = p11->C_Sign(session, in_buffer, sz, sig_buffer, &sig_len); + } } if (rv != CKR_OK) { @@ -2512,6 +2518,12 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, sig_len = sizeof(sig_buffer); rv = p11->C_SignFinal(session, sig_buffer, &sig_len); + if ((rv == CKR_OK) && !sig_buffer) { + sig_buffer = malloc(sig_len); + if (!sig_buffer) + util_fatal("malloc() failure\n"); + rv = p11->C_SignFinal(session, sig_buffer, &sig_len); + } if (rv != CKR_OK) p11_fatal("C_SignFinal", rv); } @@ -2552,6 +2564,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Failed to write to %s: %m", opt_output); if (fd != 1) close(fd); + free(sig_buffer); } static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, From 8e628f4d45942fb0e73c978287c08e3e35cea9d1 Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Fri, 23 May 2025 21:10:07 -0400 Subject: [PATCH 3880/4321] Changes recommended by CI lint tool --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fee6113347..a27a005964 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2413,8 +2413,8 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char in_buffer[1025]; - CK_BYTE_PTR sig_buffer = NULL; + unsigned char in_buffer[1025]; + CK_BYTE_PTR sig_buffer = NULL; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; CK_MAC_GENERAL_PARAMS mac_gen_param; @@ -2422,7 +2422,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, .phFlag = CK_FALSE, }; CK_RV rv; - CK_ULONG sig_len = 0; + CK_ULONG sig_len = 0; int fd; ssize_t sz; unsigned long hashlen; From cac82bf868d6b3a720cb19c278eefccad689d320 Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Sat, 24 May 2025 01:48:58 -0400 Subject: [PATCH 3881/4321] Dynamic allocation for C_Verify/C_VerifyFinal --- src/tools/pkcs11-tool.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a27a005964..d60526be9f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2570,7 +2570,8 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char in_buffer[1025], sig_buffer[512]; + unsigned char in_buffer[1025]; + CK_BYTE_PTR sig_buffer = NULL; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; CK_MAC_GENERAL_PARAMS mac_gen_param; @@ -2578,8 +2579,9 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, .phFlag = CK_FALSE, }; CK_RV rv; - CK_ULONG sig_len; + CK_ULONG sig_len = 0; int fd, fd2; + struct stat sig_st; ssize_t sz, sz2; unsigned long hashlen; @@ -2631,8 +2633,13 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("No file with signature provided. Use --signature-file"); else if ((fd2 = open(opt_signature_file, O_RDONLY|O_BINARY)) < 0) util_fatal("Cannot open %s: %m", opt_signature_file); - - sz2 = read(fd2, sig_buffer, sizeof(sig_buffer)); + else if (fstat(fd2, &sig_st) != 0) + util_fatal("Couldn't get size of file \"", opt_signature_file); + sig_len = sig_st.st_size; + sig_buffer = malloc(sig_len); + if (!sig_buffer) + util_fatal("malloc() failure\n"); + sz2 = read(fd2, sig_buffer, sig_len); if (sz2 < 0) util_fatal("Cannot read from %s: %m", opt_signature_file); @@ -2742,6 +2749,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Invalid signature"); else util_fatal("Signature verification failed: rv = %s (0x%0x)\n", CKR2Str(rv), (unsigned int)rv); + free(sig_buffer); } static void From 4ff9a1d8129b457b7cd2b35c6856ef930075f715 Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Mon, 26 May 2025 20:50:39 -0400 Subject: [PATCH 3882/4321] Changes recommended by yshui/git-clang-format-lint@master --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d60526be9f..fc9295edc4 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2570,7 +2570,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char in_buffer[1025]; + unsigned char in_buffer[1025]; CK_BYTE_PTR sig_buffer = NULL; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; @@ -2579,7 +2579,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, .phFlag = CK_FALSE, }; CK_RV rv; - CK_ULONG sig_len = 0; + CK_ULONG sig_len = 0; int fd, fd2; struct stat sig_st; ssize_t sz, sz2; From 35c07ad9f919cbe12e3c9a111e905f44ec26d9ad Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Wed, 28 May 2025 11:01:40 -0400 Subject: [PATCH 3883/4321] Fix bug identified by Jakuje that causes memory corruption with ECDSA --- src/tools/pkcs11-tool.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fc9295edc4..d93d31ffff 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2516,9 +2516,11 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, sz = read(fd, in_buffer, sizeof(in_buffer)); } while (sz > 0); - sig_len = sizeof(sig_buffer); + /* Signature buffer may have been allocated above */ + free(sig_buffer); + sig_buffer = NULL; rv = p11->C_SignFinal(session, sig_buffer, &sig_len); - if ((rv == CKR_OK) && !sig_buffer) { + if (rv == CKR_OK) { sig_buffer = malloc(sig_len); if (!sig_buffer) util_fatal("malloc() failure\n"); @@ -2552,10 +2554,9 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Failed to convert signature to ASN.1 sequence format"); } - memcpy(sig_buffer, seq, seqlen); + free(sig_buffer); + sig_buffer = seq; sig_len = seqlen; - - free(seq); } } sz = write(fd, sig_buffer, sig_len); From 8660374d27bce5ce4e61bdf915e0236192726b60 Mon Sep 17 00:00:00 2001 From: Jeff Gold Date: Wed, 28 May 2025 11:09:40 -0400 Subject: [PATCH 3884/4321] Rearranged error handling for C_SignFinal, as suggested by Jakuje --- src/tools/pkcs11-tool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d93d31ffff..3d987fa773 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2520,12 +2520,12 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, free(sig_buffer); sig_buffer = NULL; rv = p11->C_SignFinal(session, sig_buffer, &sig_len); - if (rv == CKR_OK) { - sig_buffer = malloc(sig_len); - if (!sig_buffer) - util_fatal("malloc() failure\n"); - rv = p11->C_SignFinal(session, sig_buffer, &sig_len); - } + if (rv != CKR_OK) + p11_fatal("C_SignFinal", rv); + sig_buffer = malloc(sig_len); + if (!sig_buffer) + util_fatal("malloc() failure\n"); + rv = p11->C_SignFinal(session, sig_buffer, &sig_len); if (rv != CKR_OK) p11_fatal("C_SignFinal", rv); } From e95052f17b96a896277f85792ba78fa4f0f7817f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 16 Apr 2025 14:41:21 +0200 Subject: [PATCH 3885/4321] Rework wrap/unwrap tests and enable them for softokn --- tests/init-kryoptic.sh | 19 +- tests/init-softhsm.sh | 8 +- tests/init-softokn.sh | 27 +- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 411 +++++++++++---------- tests/test-softokn.sh | 1 + 5 files changed, 248 insertions(+), 218 deletions(-) diff --git a/tests/init-kryoptic.sh b/tests/init-kryoptic.sh index b4dfd9c0dd..1f29aab9c4 100755 --- a/tests/init-kryoptic.sh +++ b/tests/init-kryoptic.sh @@ -1,13 +1,18 @@ #!/bin/bash # set paths -KRYOPTIC_PWD="$BUILD_PATH/kryoptic/target/debug/libkryoptic_pkcs11.so" -if test -f "$KRYOPTIC_PWD" ; then - echo "Using kryoptic path $KRYOPTIC_PWD" - P11LIB="$KRYOPTIC_PWD" -else - echo "Kryoptic not found" - exit 0 +kryoptic_paths="$BUILD_PATH/kryoptic/target/debug/libkryoptic_pkcs11.so" + +for LIB in $kryoptic_paths; do + echo "Testing $LIB" + if [[ -f $LIB ]]; then + export P11LIB=$LIB + echo "Setting P11LIB=$LIB" + break + fi +done +if [[ -z "$P11LIB" ]]; then + echo "Warning: Could not find the Kryoptic PKCS#11 module" fi function initialize_token() { diff --git a/tests/init-softhsm.sh b/tests/init-softhsm.sh index c54c656ee8..e0dfdaf0d7 100755 --- a/tests/init-softhsm.sh +++ b/tests/init-softhsm.sh @@ -2,8 +2,9 @@ SOURCE_PATH=${SOURCE_PATH:-..} + softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ - /usr/lib/softhsm/libsofthsm2.so + /usr/lib/softhsm/libsofthsm2.so \ /usr/lib64/pkcs11/libsofthsm2.so \ /usr/lib/i386-linux-gnu/softhsm/libsofthsm2.so \ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" @@ -17,7 +18,7 @@ for LIB in $softhsm_paths; do fi done if [[ -z "$P11LIB" ]]; then - echo "Warning: Could not find the softhsm pkcs11 module" + echo "Warning: Could not find the SoftHSM PKCS#11 module" fi function initialize_token() { @@ -26,9 +27,8 @@ function initialize_token() { rm -rf ".tokens" fi mkdir ".tokens" - export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") - # Init token + export SOFTHSM2_CONF=$(realpath ".softhsm2.conf") softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" export PUB_ARGS=("--module=${P11LIB}") diff --git a/tests/init-softokn.sh b/tests/init-softokn.sh index e77a5723de..7114fad9ef 100644 --- a/tests/init-softokn.sh +++ b/tests/init-softokn.sh @@ -1,20 +1,18 @@ #!/bin/bash -softokn_paths=( - "/usr/lib64/libsoftokn3.so" # Fedora - "/usr/lib/x86_64-linux-gnu/libsoftokn3.so" # Ubuntu -) -P11LIB="" -for lib in "${softokn_paths[@]}"; do - if [ -f "$lib" ]; then - echo "Using softokn path $lib" - P11LIB="$lib" - break - fi +softokn_paths="/usr/lib64/libsoftokn3.so \ + /usr/lib/x86_64-linux-gnu/libsoftokn3.so" + +for LIB in $softokn_paths; do + echo "Testing $LIB" + if [[ -f $LIB ]]; then + export P11LIB=$LIB + echo "Setting P11LIB=$LIB" + break + fi done -if [ -z "$P11LIB" ]; then - echo "Unable to find softokn PKCS#11 library" - exit 1 +if [[ -z "$P11LIB" ]]; then + echo "Warning: Could not find the Softokn PKCS#11 module" fi function initialize_token() { @@ -34,7 +32,6 @@ function initialize_token() { certutil -N -d $TOKDIR -f $PINFILE export NSS_LIB_PARAMS=configDir=$TMPPDIR/tokens - export PKCS11_TOOL="pkcs11-tool" export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PINVALUE}") } diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 380f9403b6..e38c42df9f 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -10,16 +10,38 @@ function compare_keys() { cmp $EXTRACTED $PLAIN >/dev/null 2>/dev/null assert $? "Extracted key does not match the input key" else + # softokn and kryoptic keys are extractable but sensitive echo "Key cannot be read in plaintext" fi } +function test_unwrapped_aes_encryption() { + AES_256_KEY=$1 + KEY_ID=$2 + IV="00000000000000000000000000000000" + (printf '\xAB%.0s' {1..64};) > aes_plain.data + + echo "Testing unwrapped key with encryption" + + # Encrypt with openssl + openssl enc -aes-256-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv $IV -K $AES_256_KEY + assert $? "AES CBC OpenSSL encryption failed" + + # Encrypt with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $KEY_ID -m AES-CBC-PAD --iv $IV \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data + assert $? "Fail/pkcs11-tool encrypt" + + # Compare ciphertexts + cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null + assert $? "AES CBC encrypted ciphertexts do not match" + + rm aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain.data +} + TOKENTYPE=$1 -if [ "${TOKENTYPE}" == "softokn" ]; then - echo "Wrap/unwrap test not supported" - exit 1 -elif [ "${TOKENTYPE}" == "" ]; then +if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm echo "No tokentype provided, running with SoftHSM" fi @@ -36,156 +58,158 @@ fi initialize_token +# create AES key +AES_256_KEY="7070707070707070707070707070707070707070707070707070707070707070" +echo -n $AES_256_KEY | xxd -p -r > aes.key + echo "=======================================================" -echo " RSA-PKCS Unwrap test" +echo " RSA Wrap/Unwrap tests" echo "=======================================================" -ID1="85" # RSA key -ID2="95" # GENERIC key -ID3="96" # AES key -# Generate RSA key (this key is used to unwrap/wrap operation) -$PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type rsa:1024 --id $ID1 --usage-wrap --usage-decrypt --label wrap-rsa +ID_RSA_WRAP="85" # RSA wrapping key +ID_GENERIC_UNWRAPPED_1="95" # GENERIC key +ID_AES_UNWRAPPED_1="96" # AES key + +# Generate RSA key for unwrap/wrap operation +$PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type rsa:1024 --id $ID_RSA_WRAP --usage-wrap --usage-decrypt --label rsa-wrapping-key assert $? "Failed to Generate RSA key" -# export public key -$PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type pubkey --id $ID1 -o rsa_pub.key +# Export public key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type pubkey --id $ID_RSA_WRAP -o rsa_pub.key assert $? "Failed to export public key" -# create AES key -KEY="70707070707070707070707070707070" +echo "=======================================================" +echo " RSA-PKCS Unwrap generic key test" +echo "=======================================================" -echo -n $KEY|xxd -p -r > aes_plain_key -# wrap AES key -openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes_plain_key -out aes_wrapped_key -assert $? "Failed wrap AES key" +# Wrap with OpenSSL +openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes.key -out openssl_wrapped.data +assert $? "OpenSSL failed wrap AES key" -# unwrap key as generic key by pkcs11 interface -$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ - --extractable --application-id $ID3 --application-label "unwrap-generic-ex" --extractable 2>/dev/null -assert $? "Unwrap failed" +# Unwrap with pkcs11-tool as generic key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type GENERIC: \ + --application-id $ID_GENERIC_UNWRAPPED_1 --application-label "unwrap-generic-ex-with-rsa-pkcs" --extractable 2>/dev/null +assert $? "RSA-PKCS unwrap GENERIC key failed" -# if extractable, there is no problem to compare key value with original key -$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID3 --read-object --type secrkey --output-file generic_extracted_key -compare_keys $? generic_extracted_key aes_plain_key +# Compare original and unwrapped key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_GENERIC_UNWRAPPED_1 --read-object --type secrkey --output-file generic_extracted.key +compare_keys $? generic_extracted.key aes.key -# unwrap AES key, not extractable -$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID1 -i aes_wrapped_key --key-type AES: \ - --application-id $ID2 --application-label "unwrap-aes" 2>/dev/null -assert $? "Unwrap failed" +echo "=======================================================" +echo " RSA-PKCS Unwrap AES key test" +echo "=======================================================" -# To check if AES key was correctly unwrapped (non extractable), we need to encrypt some data by pkcs11 interface and by openssl -# (with same key). If result is same, key was correctly unwrapped. -VECTOR="00000000000000000000000000000000" -echo -n "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" > aes_plain.data +# Unwrap with pkcs11-tool as AES key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type AES: \ + --application-id $ID_AES_UNWRAPPED_1 --application-label "unwrap-aes-with-rsa-pkcs" --extractable 2>/dev/null +assert $? "RSA-PKCS unwrap AES key failed" -openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY -assert $? "Fail/Openssl" +# Read value of unwrapped key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_AES_UNWRAPPED_1 --read-object --type secrkey --output-file aes_extracted.key -$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID2 -m AES-CBC --iv $VECTOR \ - --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null -assert $? "Fail/pkcs11-tool encrypt" -cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null -assert $? "Fail, AES-CBC - wrong encrypt" +# Compare original and unwrapped key +compare_keys $? aes_extracted.key aes.key + +# Check if AES key was correctly unwrapped with encryption +test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_1 echo "=======================================================" -echo " RSA-PKCS Wrap test" +echo " RSA-PKCS Wrap AES key test" echo "=======================================================" -$PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS --id $ID1 --application-id $ID3 --output-file wrapped.key -assert $? "Fail, unable to wrap" +# Wrap with pkcs11-tool +$PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS --id $ID_RSA_WRAP --application-id $ID_AES_UNWRAPPED_1 --output-file pkcs11_wrapped.data +assert $? "Unable to wrap with RSA-PKCS" -$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key -assert $? "Fail, unable to decrypt wrapped key" -cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null -assert $? "wrapped key after decipher does not match the original key" -echo "RSA-PKCS wrap test successful" +# Compare keys with decryption +$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS --id $ID_RSA_WRAP --input-file pkcs11_wrapped.data --output-file aes_wrapped_decrypted.key +assert $? "Unable to decrypt wrapped key" +cmp aes_wrapped_decrypted.key aes.key >/dev/null 2>/dev/null +assert $? "Wrapped key after decipher does not match the original key" -echo "=======================================================" -echo " RSA-PKCS-OAEP Unwrap test" -echo "=======================================================" -# RSA-PKCS-OAEP mechanism takes both a hash algorithm and MGF algorithm as parameters. For now we use SHA1, although it has been deprecated by NIST, because SoftHSM only supports SHA1 hash with OAEP currently. Known issue: https://github.com/softhsm/SoftHSMv2/issues/474 . When this issue is fixed, we shall replace with SHA256 or higher. -# OpenSSL rsa_oaep_md hash algorithm option -OSSL_OAEP_HASH_ALG="sha1" -# pkcs11-tool hash-algorithm option -P11_OAEP_HASH_ALG="SHA-1" -# pkcs11-tool mgf option -P11_OAEP_MGF_ALG="MGF1-SHA1" - -# Identifiers (pkcs11-tool --application-id argument) of PKCS11 key objects to be created -ID4="97" -ID5="98" - -# Reusing AES key and RSA key for unwrap/wrap operation already generated with ID1 in previous RSA-PKCS Unwrap test -# Cleanup previously generated output -rm aes_wrapped_key generic_extracted_key aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data wrapped.key plain_wrapped.key - -# wrap AES key with RSA OAEP mode -openssl pkeyutl -encrypt -pubin -keyform DER -inkey rsa_pub.key -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:$OSSL_OAEP_HASH_ALG -pkeyopt rsa_mgf1_md:$OSSL_OAEP_HASH_ALG -in aes_plain_key -out aes_wrapped_key -assert $? "Failed wrap AES key" - -# unwrap key by pkcs11 interface, extractable -$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type GENERIC: \ - --extractable --application-id $ID4 --application-label "unwrap-aes-ex-with-rsa-oaep" 2>/dev/null -assert $? "Unwrap failed" - -# because key is extractable, there is no problem to compare key value with original key -$PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID4 --read-object --type secrkey --output-file generic_extracted_key -compare_keys $? generic_extracted_key aes_plain_key - -# unwrap AES key, not extractable -$PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 -i aes_wrapped_key --key-type AES: \ - --application-id $ID5 --application-label "unwrap-aes-non-ex-with-rsa-oaep" 2>/dev/null -assert $? "Unwrap failed" - -# To check if AES key was correctly unwrapped (non extractable), we do the same as in the RSA-PKCS test. -openssl enc -aes-128-cbc -nopad -in aes_plain.data -out aes_ciphertext_openssl.data -iv $VECTOR -K $KEY -assert $? "Fail/Openssl" - -$PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID5 -m AES-CBC --iv $VECTOR \ - --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data 2>/dev/null -assert $? "Fail/pkcs11-tool encrypt" -cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null -assert $? "Fail, AES-CBC - wrong encrypt" +rm openssl_wrapped.data generic_extracted.key pkcs11_wrapped.data aes_wrapped_decrypted.key aes_extracted.key +if [ "${TOKENTYPE}" != "softokn" ]; then + echo "=======================================================" + echo " RSA-PKCS-OAEP Unwrap generic key test" + echo "=======================================================" + # RSA-PKCS-OAEP mechanism takes both a hash algorithm and MGF algorithm as parameters. + # For now we use SHA1, although it has been deprecated by NIST, because SoftHSM only supports SHA1 hash with OAEP currently. + # Known issue: https://github.com/softhsm/SoftHSMv2/issues/474 . When this issue is fixed, we shall replace with SHA256 or higher. -echo "=======================================================" -echo " RSA-PKCS-OAEP Wrap test" -echo "=======================================================" + OSSL_OAEP_HASH_ALG="sha1" + P11_OAEP_HASH_ALG="SHA-1" + P11_OAEP_MGF_ALG="MGF1-SHA1" -$PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS-OAEP --id $ID1 --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID4 --output-file wrapped.key -assert $? "Fail, unable to wrap" + # Identifiers (pkcs11-tool --application-id argument) of PKCS11 key objects to be created + ID_GENERIC_UNWRAPPED_2="97" + ID_AES_UNWRAPPED_3="98" -$PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID1 --input-file wrapped.key --output-file plain_wrapped.key -assert $? "Fail, unable to decrypt wrapped key" -cmp plain_wrapped.key aes_plain_key >/dev/null 2>/dev/null -assert $? "wrapped key after decipher does not match the original key" -echo "RSA-PKCS-OAEP wrap test successful" + # Wrap with OpenSSL + openssl pkeyutl -encrypt -pubin -keyform DER -inkey rsa_pub.key -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:$OSSL_OAEP_HASH_ALG -pkeyopt rsa_mgf1_md:$OSSL_OAEP_HASH_ALG -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL failed wrap AES key" -echo "=======================================================" -echo " RSA-PKCS / RSA-PKCS-OAEP Cleanup" -echo "=======================================================" + # Unwrap with pkcs11-tool as generic key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type GENERIC: \ + --extractable --application-id $ID_GENERIC_UNWRAPPED_2 --application-label "unwrap-aes-ex-with-rsa-oaep" 2>/dev/null + assert $? "RSA-PKCS-OAEP unwrap GENERIC key failed" + + # Compare original and unwrapped key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_GENERIC_UNWRAPPED_2 --read-object --type secrkey --output-file generic_extracted.key + compare_keys $? generic_extracted.key aes.key + + echo "=======================================================" + echo " RSA-PKCS-OAEP Unwrap AES key test" + echo "=======================================================" + + # Unwrap with pkcs11-tool as AES key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type AES: \ + --extractable --application-id $ID_AES_UNWRAPPED_3 --application-label "unwrap-aes-non-ex-with-rsa-oaep" 2>/dev/null + assert $? "RSA-PKCS-OAEP unwrap AES key failed" + + # Compare original and unwrapped key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_AES_UNWRAPPED_1 --read-object --type secrkey --output-file aes_extracted.key + compare_keys $? aes_extracted.key aes.key -rm rsa_pub.key aes_plain_key aes_wrapped_key aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data aes_plain.data generic_extracted_key wrapped.key plain_wrapped.key + # Check if AES key was correctly unwrapped with encryption + test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_3 + + echo "=======================================================" + echo " RSA-PKCS-OAEP Wrap test" + echo "=======================================================" + + # Wrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS-OAEP --id $ID_RSA_WRAP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID_GENERIC_UNWRAPPED_2 --output-file pkcs11_wrapped.data + assert $? "Unable to wrap with RSA-PKCS-OAEP" + + # Compare keys with decryption + $PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID_RSA_WRAP --input-file pkcs11_wrapped.data --output-file aes_wrapped_decrypted.key + assert $? "Fail, unable to decrypt wrapped key" + cmp aes_wrapped_decrypted.key aes.key >/dev/null 2>/dev/null + assert $? "Wrapped key after decipher does not match the original key" + + rm openssl_wrapped.data generic_extracted.key pkcs11_wrapped.data aes_wrapped_decrypted.key aes_extracted.key + +fi + +rm rsa_pub.key echo "=======================================================" -echo " AES wrap/unwrap" +echo " AES Wrap/Unwrap tests" echo "=======================================================" +ID_AES_WRAP="0101" # AES wrapping key +ID_AES_UNWRAPPED_4="0102" # AES 256 CBC +ID_AES_UNWRAPPED_5="0103" # AES-KEY-WRAP +ID_AES_UNWRAPPED_6="0104" # AES-KEY-WRAP-PAD is_openssl_3=$(openssl version | grep "OpenSSL 3.") is_softhsm2_2_6_1=$(softhsm2-util -version | grep "2.6.1") -$PKCS11_TOOL "${PRIV_ARGS[@]}" -O - -ID_KEK="0101" -ID_UNWRAPPED="0102" - -AES_KEY="7070707070707070707070707070707070707070707070707070707070707070" -echo -n $AES_KEY | xxd -p -r > aes.key - -AES_KEK=$(head /dev/urandom | sha256sum | head -c 64) -echo -n $AES_KEK | xxd -p -r > aes_kek.key -$PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes_kek.key --id $ID_KEK --type secrkey \ - --key-type AES:32 --usage-wrap --extractable --label wrap-aes-32 -assert $? "PKCS11 / Failed to write AES KEK" +# Generate AES key for unwrap/wrap operation +AES_WRAP=$(head /dev/urandom | sha256sum | head -c 64) +echo -n $AES_WRAP | xxd -p -r > aes_kek.key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes_kek.key --id $ID_AES_WRAP --type secrkey \ + --key-type AES:32 --usage-wrap --extractable --label aes-32-wrapping-key +assert $? "Failed to write AES key" if [[ "$TOKENTYPE" != "softhsm" || -n "$is_softhsm2_2_6_1" ]]; then # CKM_AES_CBC -- SoftHSM2 AES CBC wrapping currently has a bug, the IV is not correctly used. Only IV=0 will work --* @@ -194,139 +218,142 @@ if [[ "$TOKENTYPE" != "softhsm" || -n "$is_softhsm2_2_6_1" ]]; then echo "=======================================================" echo " AES 256 CBC Unwrap test" echo "=======================================================" - # wrapping AES Key with openssl - openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data -nopad + # Wrap with OpenSSL + openssl enc -aes-256-cbc -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data -nopad assert $? "OpenSSL / Failed to AES CBC encrypt AES key" if [ "${TOKENTYPE}" == "softhsm" ]; then echo "SoftHSM2 currently does not support CKM_AES_CBC unwrapping" - # SoftHSM does not have the wrapped key already, write it for wrap test - $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes.key --id $ID_UNWRAPPED --type secrkey --key-type AES:32 \ - --usage-decrypt --extractable --label "aes-stored" + # SoftHSM does not have the wrapped key already, write it for the wrap test + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes.key --id $ID_AES_UNWRAPPED_4 --type secrkey --key-type AES:32 \ + --usage-decrypt --extractable --label "stored-aes-32-cbc" assert $? "PKCS11 / Failed to write AES key" else - # unwrap key - $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ - --key-type AES: --input-file openssl_wrapped.data --extractable --application-label "unwrap-aes-with-aes" + # Unwrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-CBC --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 \ + --key-type AES: --input-file openssl_wrapped.data --extractable --application-label "unwrap-aes-with-aes-32-cbc" assert $? "PKCS11 / Failed to AES CBC unwrap AES key" - # compare keys - $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID_UNWRAPPED --output-file unwrapped.key + # Compare original and unwrapped key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID_AES_UNWRAPPED_4 --output-file unwrapped.key compare_keys $? aes.key unwrapped.key - # check if AES key was correctly unwrapped with encryption - # encrypt with openssl - echo -n "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" > aes_plain.data - openssl enc -aes-256-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv $IV -K $AES_KEY - assert $? "Fail/Openssl" - # decrypt with pkcs11-tool - $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID_UNWRAPPED -m AES-CBC-PAD --iv $IV \ - --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data - assert $? "Fail/pkcs11-tool encrypt" - cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null - assert $? "Fail, AES-CBC - wrong encrypt" - rm aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain.data + # Check if AES key was correctly unwrapped with encryption + test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 fi echo "=======================================================" echo " AES 256 CBC Wrap test" echo "=======================================================" - # Wrapping AES Key with pkcs11-tool - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ + # Wrap with OpenSSL + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 \ --output-file pkcs11_wrapped.data assert $? "Fail, unable to wrap" - # Compare wrapped keys + # Compare OpenSSL and pkcs11-tool wrapped keys cmp pkcs11_wrapped.data openssl_wrapped.data >/dev/null 2>/dev/null assert $? "Fail, AES-CBC - wrapped key incorrect" - - # clean up - #$PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID_UNWRAPPED - #assert $? "PKCS11 / Failed to delete unwrapped AES key" else echo "Not supported" fi if [[ "$TOKENTYPE" != "softhsm" ]]; then - # CKM_AES_CBC_PAD -- SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping mechanism -- - IV="000102030405060708090A0B0C0D0E0F" + # SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping echo "=======================================================" echo " AES 256 CBC PAD Wrap test" echo "=======================================================" - # Wrapping AES key - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC-PAD --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED --output-file pkcs11_wrapped.data - assert $? "PKCS11 / Failed to AES CBC PAD wrap AES key" - openssl enc -aes-256-cbc -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + IV="000102030405060708090A0B0C0D0E0F" + # Wrap with OpenSSL + openssl enc -aes-256-cbc -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data assert $? "OpenSSL / Failed to AES CBC encrypt AES key" + + # Wrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC-PAD --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 --output-file pkcs11_wrapped.data + assert $? "PKCS11 / Failed to AES CBC PAD wrap AES key" + + # Compare OpenSSL and pkcs11-tool wrapped keys cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - assert $? "AES CBC PAD wrong AES key wrap" + assert $? "AES 256 CBC PAD wrapped keys do not match" fi if [[ -n $is_openssl_3 ]]; then - # CKM_AES_KEY_WRAP - IV="a6a6a6a6a6a6a6a6" - ID7="0103" echo "=======================================================" echo "AES-KEY-WRAP Wrap test" echo "=======================================================" # RSA Key # --AES-KEY-WRAP is not suitable for asymmetric key wrapping since the length of the encoded private key is likely not aligned to 8 bytes + IV="a6a6a6a6a6a6a6a6" - # AES Key - openssl enc -id-aes256-wrap -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data + # Wrap with OpenSSL + openssl enc -id-aes256-wrap -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data assert $? "OpenSSL / Failed to AES KEY WRAP wrap AES key" - # Wrapping - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID_UNWRAPPED \ + # Wrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 \ --output-file pkcs11_wrapped.data assert $? "PKCS11 / Failed to AES KEY WRAP wrap AES key" + + # Compare OpenSSL and pkcs11-tool wrapped keys cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - assert $? "AES KEY WRAP wrong AES key wrap" + assert $? "AES-KEY-WRAP wrapped keys do not match" echo "=======================================================" echo "AES-KEY-WRAP Unwrap test" echo "=======================================================" - # Unwrapping - $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_KEK --iv $IV --application-id $ID7 \ - --key-type AES: --input-file openssl_wrapped.data --extractable + # Unwrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_5 \ + --key-type AES: --input-file pkcs11_wrapped.data --extractable --application-label "unwrap-aes-with-aes-key-wrap" assert $? "PKCS11 / Failed to AES KEY WRAP wrap unwrap AES key" - $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID7 --output-file unwrapped.key + + # Read value of unwrapped key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID_AES_UNWRAPPED_5 --output-file unwrapped.key + + # Compare original and unwrapped key compare_keys $? aes.key unwrapped.key - # Cleanup - $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID_UNWRAPPED - assert $? "PKCS11 / Failed to delete unwrapped AES key" + + # Check if AES key was correctly unwrapped with encryption + test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 if [[ "$TOKENTYPE" != "kryoptic" ]]; then echo "=======================================================" echo "AES-KEY-WRAP-PAD Wrap test" echo "=======================================================" - # CKM_AES_KEY_WRAP_PAD IV="a65959a6" - ID8="0104" - # AES Key - openssl enc -id-aes256-wrap-pad -e -K $AES_KEK -iv $IV -in aes.key -out openssl_wrapped.data - assert $? "OpenSSL / Failed to AES KEY WRAP PAD encrypt AES key" - # Wrapping - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID7 --output-file pkcs11_wrapped.data + + # Wrap with OpenSSL + openssl enc -aes256-wrap-pad -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data + assert $? "OpenSSL failed wrap AES key" + + # Wrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_AES_UNWRAPPED_4 --output-file pkcs11_wrapped.data assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap AES key" - cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null - assert $? "AES KEY WRAP PAD wrong AES key wrap" + + # Compare OpenSSL and pkcs11-tool wrapped keys + if [[ "$TOKENTYPE" != "softokn" ]]; then + cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null + assert $? "AES-KEY-WRAP-PAD wrapped keys do not match" + else + echo "Comparing OpenSSL and pkcs11-tool wrapped keys for softokn fails" + fi echo "=======================================================" echo "AES-KEY-WRAP-PAD Unwrap test" echo "=======================================================" - # Unwrapping - $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_KEK --iv $IV --application-id $ID8 --key-type AES: --input-file openssl_wrapped.data --extractable + # Unwrap with pkcs11-tool + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_6 \ + --key-type AES: --input-file pkcs11_wrapped.data --extractable --application-label "unwrap-aes-with-aes-key-wrap-pad" assert $? "PKCS11 / Failed to AES KEY WRAP PAD wrap unwrap AES key" - $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID8 --output-file unwrapped.key - assert $? "PKCS11 / Failed to read unwrapped AES key" - cmp aes.key unwrapped.key - assert $? "AES KEY WRAP PAD wrong AES key unwrap" - # Cleanup - $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type secrkey --id $ID8 - assert $? "PKCS11 / Failed to delete unwrapped AES key" + + # Read value of unwrapped key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type secrkey --id $ID_AES_UNWRAPPED_6 --output-file unwrapped.key + + # Compare original and unwrapped key + compare_keys $? aes.key unwrapped.key + + # Check if AES key was correctly unwrapped with encryption + test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 fi fi -$PKCS11_TOOL "${PRIV_ARGS[@]}" -O rm -f aes.key aes_kek.key pkcs11_wrapped.data openssl_wrapped.data unwrapped.key diff --git a/tests/test-softokn.sh b/tests/test-softokn.sh index 7c7ab643ee..5e467cf311 100755 --- a/tests/test-softokn.sh +++ b/tests/test-softokn.sh @@ -5,3 +5,4 @@ echo "Running all supported tests for NSS Softokn token..." $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softokn $SOURCE_PATH/tests/test-pkcs11-tool-import.sh softokn +$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softokn From 34a9f47cea6f5e8c3db04bc99bcea0dfabeb841f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 30 Apr 2025 10:04:17 +0200 Subject: [PATCH 3886/4321] Add wrap/unwrap tests for RSA private keys --- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 176 ++++++++++++++++----- 1 file changed, 140 insertions(+), 36 deletions(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index e38c42df9f..8ddfcd5dfa 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -63,7 +63,7 @@ AES_256_KEY="7070707070707070707070707070707070707070707070707070707070707070" echo -n $AES_256_KEY | xxd -p -r > aes.key echo "=======================================================" -echo " RSA Wrap/Unwrap tests" +echo " RSA Wrap/Unwrap of secret key tests" echo "=======================================================" ID_RSA_WRAP="85" # RSA wrapping key ID_GENERIC_UNWRAPPED_1="95" # GENERIC key @@ -77,9 +77,9 @@ assert $? "Failed to Generate RSA key" $PKCS11_TOOL "${PRIV_ARGS[@]}" --read-object --type pubkey --id $ID_RSA_WRAP -o rsa_pub.key assert $? "Failed to export public key" -echo "=======================================================" +echo "-------------------------------------------------------" echo " RSA-PKCS Unwrap generic key test" -echo "=======================================================" +echo "-------------------------------------------------------" # Wrap with OpenSSL openssl rsautl -encrypt -pubin -keyform der -inkey rsa_pub.key -in aes.key -out openssl_wrapped.data @@ -94,9 +94,9 @@ assert $? "RSA-PKCS unwrap GENERIC key failed" $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_GENERIC_UNWRAPPED_1 --read-object --type secrkey --output-file generic_extracted.key compare_keys $? generic_extracted.key aes.key -echo "=======================================================" +echo "-------------------------------------------------------" echo " RSA-PKCS Unwrap AES key test" -echo "=======================================================" +echo "-------------------------------------------------------" # Unwrap with pkcs11-tool as AES key $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type AES: \ @@ -112,9 +112,9 @@ compare_keys $? aes_extracted.key aes.key # Check if AES key was correctly unwrapped with encryption test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_1 -echo "=======================================================" +echo "-------------------------------------------------------" echo " RSA-PKCS Wrap AES key test" -echo "=======================================================" +echo "-------------------------------------------------------" # Wrap with pkcs11-tool $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS --id $ID_RSA_WRAP --application-id $ID_AES_UNWRAPPED_1 --output-file pkcs11_wrapped.data @@ -129,9 +129,9 @@ assert $? "Wrapped key after decipher does not match the original key" rm openssl_wrapped.data generic_extracted.key pkcs11_wrapped.data aes_wrapped_decrypted.key aes_extracted.key if [ "${TOKENTYPE}" != "softokn" ]; then - echo "=======================================================" + echo "-------------------------------------------------------" echo " RSA-PKCS-OAEP Unwrap generic key test" - echo "=======================================================" + echo "-------------------------------------------------------" # RSA-PKCS-OAEP mechanism takes both a hash algorithm and MGF algorithm as parameters. # For now we use SHA1, although it has been deprecated by NIST, because SoftHSM only supports SHA1 hash with OAEP currently. # Known issue: https://github.com/softhsm/SoftHSMv2/issues/474 . When this issue is fixed, we shall replace with SHA256 or higher. @@ -157,9 +157,9 @@ if [ "${TOKENTYPE}" != "softokn" ]; then $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $ID_GENERIC_UNWRAPPED_2 --read-object --type secrkey --output-file generic_extracted.key compare_keys $? generic_extracted.key aes.key - echo "=======================================================" + echo "-------------------------------------------------------" echo " RSA-PKCS-OAEP Unwrap AES key test" - echo "=======================================================" + echo "-------------------------------------------------------" # Unwrap with pkcs11-tool as AES key $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m RSA-PKCS-OAEP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --id $ID_RSA_WRAP -i openssl_wrapped.data --key-type AES: \ @@ -173,9 +173,9 @@ if [ "${TOKENTYPE}" != "softokn" ]; then # Check if AES key was correctly unwrapped with encryption test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_3 - echo "=======================================================" - echo " RSA-PKCS-OAEP Wrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo " RSA-PKCS-OAEP Wrap AES key test" + echo "-------------------------------------------------------" # Wrap with pkcs11-tool $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m RSA-PKCS-OAEP --id $ID_RSA_WRAP --hash-algorithm $P11_OAEP_HASH_ALG --mgf $P11_OAEP_MGF_ALG --application-id $ID_GENERIC_UNWRAPPED_2 --output-file pkcs11_wrapped.data @@ -194,7 +194,7 @@ fi rm rsa_pub.key echo "=======================================================" -echo " AES Wrap/Unwrap tests" +echo " AES Wrap/Unwrap of secret key tests" echo "=======================================================" ID_AES_WRAP="0101" # AES wrapping key ID_AES_UNWRAPPED_4="0102" # AES 256 CBC @@ -215,9 +215,9 @@ if [[ "$TOKENTYPE" != "softhsm" || -n "$is_softhsm2_2_6_1" ]]; then # CKM_AES_CBC -- SoftHSM2 AES CBC wrapping currently has a bug, the IV is not correctly used. Only IV=0 will work --* IV="00000000000000000000000000000000" - echo "=======================================================" - echo " AES 256 CBC Unwrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo " AES 256 CBC Unwrap AES key test" + echo "-------------------------------------------------------" # Wrap with OpenSSL openssl enc -aes-256-cbc -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data -nopad assert $? "OpenSSL / Failed to AES CBC encrypt AES key" @@ -241,9 +241,9 @@ if [[ "$TOKENTYPE" != "softhsm" || -n "$is_softhsm2_2_6_1" ]]; then # Check if AES key was correctly unwrapped with encryption test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 fi - echo "=======================================================" - echo " AES 256 CBC Wrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo " AES 256 CBC Wrap AES key test" + echo "-------------------------------------------------------" # Wrap with OpenSSL $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 \ --output-file pkcs11_wrapped.data @@ -258,9 +258,9 @@ fi if [[ "$TOKENTYPE" != "softhsm" ]]; then # SoftHSM2 currently doesn't support CKM_AES_CBC_PAD as a wrapping - echo "=======================================================" - echo " AES 256 CBC PAD Wrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo " AES 256 CBC PAD Wrap AES test" + echo "-------------------------------------------------------" IV="000102030405060708090A0B0C0D0E0F" # Wrap with OpenSSL openssl enc -aes-256-cbc -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data @@ -276,9 +276,9 @@ if [[ "$TOKENTYPE" != "softhsm" ]]; then fi if [[ -n $is_openssl_3 ]]; then - echo "=======================================================" - echo "AES-KEY-WRAP Wrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP Wrap AES test" + echo "-------------------------------------------------------" # RSA Key # --AES-KEY-WRAP is not suitable for asymmetric key wrapping since the length of the encoded private key is likely not aligned to 8 bytes IV="a6a6a6a6a6a6a6a6" @@ -296,9 +296,9 @@ if [[ -n $is_openssl_3 ]]; then cmp pkcs11_wrapped.data openssl_wrapped.data 2>&1 >/dev/null assert $? "AES-KEY-WRAP wrapped keys do not match" - echo "=======================================================" - echo "AES-KEY-WRAP Unwrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP Unwrap AES key test" + echo "-------------------------------------------------------" # Unwrap with pkcs11-tool $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_5 \ --key-type AES: --input-file pkcs11_wrapped.data --extractable --application-label "unwrap-aes-with-aes-key-wrap" @@ -314,9 +314,9 @@ if [[ -n $is_openssl_3 ]]; then test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 if [[ "$TOKENTYPE" != "kryoptic" ]]; then - echo "=======================================================" - echo "AES-KEY-WRAP-PAD Wrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP-PAD Wrap AES key test" + echo "-------------------------------------------------------" IV="a65959a6" # Wrap with OpenSSL @@ -336,9 +336,9 @@ if [[ -n $is_openssl_3 ]]; then echo "Comparing OpenSSL and pkcs11-tool wrapped keys for softokn fails" fi - echo "=======================================================" - echo "AES-KEY-WRAP-PAD Unwrap test" - echo "=======================================================" + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP-PAD Unwrap AES key test" + echo "-------------------------------------------------------" # Unwrap with pkcs11-tool $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_6 \ --key-type AES: --input-file pkcs11_wrapped.data --extractable --application-label "unwrap-aes-with-aes-key-wrap-pad" @@ -357,6 +357,110 @@ fi rm -f aes.key aes_kek.key pkcs11_wrapped.data openssl_wrapped.data unwrapped.key +echo "=======================================================" +echo " AES Wrap/Unwrap of private key tests" +echo "=======================================================" + +function test_unwrapped_rsa_pkcs_decryption() { + ID_RSA_WRAPPED=$1 + ID_RSA_UNWRAPPED=$2 + + echo "Testing unwrapped key with decryption" + + (printf '\xAB%.0s' {1..64};) > plaintext.data + # Encrypt with original RSA key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --encrypt --id $ID_RSA_WRAPPED -m RSA-PKCS \ + --input-file plaintext.data --output-file ciphertext.data + assert $? "Fail/pkcs11-tool encrypt" + # Decrypt with unwrapped private key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --decrypt --id $ID_RSA_UNWRAPPED -m RSA-PKCS \ + --input-file ciphertext.data > decrypted_plaintext.data + # Compare plaintexts + cmp plaintext.data decrypted_plaintext.data >/dev/null 2>/dev/null + assert $? "RSA decrypted plaintexts do not match" + rm plaintext.data decrypted_plaintext.data +} + +ID_AES_WRAP="0200" +ID_RSA_WRAPPED="0201" +ID_RSA_UNWRAPPED="0202" +IV="00000000000000000000000000000000" + +# Generate AES key for unwrap/wrap operation +AES_WRAP=$(head /dev/urandom | sha256sum | head -c 64) +echo -n $AES_WRAP | xxd -p -r > aes_kek.key +$PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object aes_kek.key --id $ID_AES_WRAP --type secrkey \ + --key-type AES:32 --usage-wrap --usage-decrypt --extractable --label aes-32-wrapping-key +assert $? "Failed to write AES key" + +# Generate RSA key to be wrapped/unwrapped +$PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type rsa:2048 --id $ID_RSA_WRAPPED --usage-decrypt --extractable --label rsa-key +assert $? "Failed to Generate RSA key" + +# AES-KEY-WRAP, AES-KEY-WRAP-PAD, AES-CBC, AES-CBC-PAD +if [[ "$TOKENTYPE" == "softhsm" ]]; then + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP Wrap/Unwrap RSA key test" + echo "-------------------------------------------------------" + # Wrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key" + # Unwrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH" + rm rsa_wrapped_key.data + + # Test with decryption + test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED + + # Remove unwrapped RSA keys + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED +fi + +if [[ "$TOKENTYPE" != "kryoptic" ]]; then + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP-PAD Wrap/Unwrap RSA key test" + echo "-------------------------------------------------------" + # Wrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key" + # Unwrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH" + rm rsa_wrapped_key.data + + # Test with decryption + test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED + + # Remove unwrapped RSA key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED +fi + +if [[ "$TOKENTYPE" != "softhsm" ]]; then + echo "-------------------------------------------------------" + echo "AES-CBC-PAD Wrap/Unwrap RSA key test" + echo "-------------------------------------------------------" + # Wrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-CBC-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key" + # Unwrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-CBC-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH" + rm rsa_wrapped_key.data + + # Test with decryption + test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED + + # Remove unwrapped RSA key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED +fi + echo "=======================================================" echo "Cleanup" echo "=======================================================" From 0fb5538f970dd3b8de154a542e9c45e57cf46a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 25 Apr 2025 10:04:57 +0200 Subject: [PATCH 3887/4321] pkcs11-tool: Enable wrap/unwrap usage when writing object --- src/tools/pkcs11-tool.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 3d987fa773..9c53c90c2d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4682,6 +4682,10 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true)); n_privkey_attr++; } + if (opt_key_usage_wrap) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_UNWRAP, &_true, sizeof(_true)); + n_privkey_attr++; + } if (opt_always_auth != 0) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE, &_true, sizeof(_true)); @@ -4793,6 +4797,10 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_DERIVE, &_true, sizeof(_true)); n_pubkey_attr++; } + if (opt_key_usage_wrap) { + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_WRAP, &_true, sizeof(_true)); + n_pubkey_attr++; + } if (cert.subject_len != 0) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); From ff36a90064634799523381bf68b09ed26b16bc65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 17 Apr 2025 13:28:31 +0200 Subject: [PATCH 3888/4321] Add tests for wrap/unwrap interoperability testing --- tests/init-kryoptic.sh | 1 + tests/init-softhsm.sh | 1 + tests/init-softokn.sh | 1 + ...-tool-unwrap-wrap-interoperability-test.sh | 193 ++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100755 tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh diff --git a/tests/init-kryoptic.sh b/tests/init-kryoptic.sh index 1f29aab9c4..6d4237c5a3 100755 --- a/tests/init-kryoptic.sh +++ b/tests/init-kryoptic.sh @@ -37,6 +37,7 @@ function initialize_token() { export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PIN}") + export PRIV_ARGS_KRYOPTIC=("${PRIV_ARGS[@]}") } function token_cleanup() { diff --git a/tests/init-softhsm.sh b/tests/init-softhsm.sh index e0dfdaf0d7..ccb377c9d9 100755 --- a/tests/init-softhsm.sh +++ b/tests/init-softhsm.sh @@ -33,6 +33,7 @@ function initialize_token() { export PUB_ARGS=("--module=${P11LIB}") export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PIN}") + export PRIV_ARGS_SOFTHSM=("${PRIV_ARGS[@]}") } function token_cleanup() { diff --git a/tests/init-softokn.sh b/tests/init-softokn.sh index 7114fad9ef..f219f9df82 100644 --- a/tests/init-softokn.sh +++ b/tests/init-softokn.sh @@ -34,6 +34,7 @@ function initialize_token() { export NSS_LIB_PARAMS=configDir=$TMPPDIR/tokens export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PINVALUE}") + export PRIV_ARGS_SOFTOKN=("${PRIV_ARGS[@]}") } function token_cleanup() { diff --git a/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh new file mode 100755 index 0000000000..88ebe63ad3 --- /dev/null +++ b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh @@ -0,0 +1,193 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +get_priv_args() { + local target=$1 + case "$target" in + Kryoptic) + ARGS=("${PRIV_ARGS_KRYOPTIC[@]}") + ;; + Softokn) + ARGS=("${PRIV_ARGS_SOFTOKN[@]}") + ;; + SoftHSM) + ARGS=("${PRIV_ARGS_SOFTHSM[@]}") + ;; + *) + echo "Unknown target: $target" >&2 + return 1 + ;; + esac +} + +function test_unwrapped_aes_encryption() { + TARGET=$1 + AES_256_KEY=$2 + KEY_ID=$3 + IV="00000000000000000000000000000000" + (printf '\xAB%.0s' {1..64};) > aes_plain.data + get_priv_args "$TARGET" + + echo "Testing unwrapped key with encryption" + + # Encrypt with openssl + openssl enc -aes-256-cbc -in aes_plain.data -out aes_ciphertext_openssl.data -iv $IV -K $AES_256_KEY + assert $? "AES CBC OpenSSL encryption failed" + + # Encrypt with pkcs11-tool + $PKCS11_TOOL "${ARGS[@]}" --encrypt --id $KEY_ID -m AES-CBC-PAD --iv $IV \ + --input-file aes_plain.data --output-file aes_ciphertext_pkcs11.data + assert $? "Fail/pkcs11-tool encrypt" + + # Compare ciphertexts + cmp aes_ciphertext_pkcs11.data aes_ciphertext_openssl.data >/dev/null 2>/dev/null + assert $? "AES CBC encrypted ciphertexts do not match" + + rm aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain.data +} + +source $SOURCE_PATH/tests/help.sh +# Initialize tokens with their custom pkcs11-tool arguments +source $SOURCE_PATH/tests/common.sh softokn +initialize_token +source $SOURCE_PATH/tests/common.sh softhsm +initialize_token +source $SOURCE_PATH/tests/common.sh kryoptic +initialize_token + +# Generate AES and RSA keys for wrapping/unwrapping +ID_AES_WRAP="0100" +ID_RSA_WRAP="0200" +ID_RSA_WRAPPED="0201" +ID_RSA_UNWRAPPED="0202" + +AES_WRAP_KEY="7070707070707070707070707070707070707070707070707070707070707070" +echo -n $AES_WRAP_KEY | xxd -p -r > aes_wrap.key +IV="00000000000000000000000000000000" + +openssl genpkey -out "rsa_private.der" -outform DER -algorithm RSA -pkeyopt rsa_keygen_bits:1024 +openssl pkey -in "rsa_private.der" -out "rsa_public.der" -pubout -inform DER -outform DER + +# import keys +for TARGET in SoftHSM Kryoptic Softokn; do + get_priv_args "$TARGET" + # Write AES key for wrapping + $PKCS11_TOOL "${ARGS[@]}" --write-object aes_wrap.key --id $ID_AES_WRAP \ + --type secrkey --key-type AES:32 --usage-wrap --extractable --label aes-32-wrapping-key + assert $? "Failed to write AES key to $TARGET" + + # Write RSA private key for unwrapping + $PKCS11_TOOL "${ARGS[@]}" --write-object rsa_private.der --id $ID_RSA_WRAP \ + --type privkey --usage-wrap --usage-decrypt --label rsa-wrapping-key + assert $? "Failed to write RSA private key to $TARGET" + + # Write RSA public key for wrapping + $PKCS11_TOOL "${ARGS[@]}" --write-object rsa_public.der --id $ID_RSA_WRAP \ + --type pubkey --usage-wrap --usage-decrypt --label rsa-wrapping-key + assert $? "Failed to write RSA public key to $TARGET" + + # Generate RSA key to be wrapped/unwrapped + $PKCS11_TOOL "${ARGS[@]}" --keypairgen --key-type rsa:2048 --id $ID_RSA_WRAPPED \ + --usage-decrypt --extractable --label rsa-key + assert $? "Failed to Generate RSA key" +done + +echo "=======================================================" +echo " Wrap/Unwrap of secret keys" +echo "=======================================================" +# Generate key to be wrapped/unwrapped +ID_AES="0101" +AES_KEY="ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB" +echo -n $AES_KEY | xxd -p -r > aes.key + +for MECH in AES-CBC AES-KEY-WRAP RSA-PKCS; do + echo "-------------------------------------------------------" + echo " $MECH Wrap/Unwrap of secret key test" + echo "-------------------------------------------------------" + ID_WRAP=$ID_AES_WRAP + if [ "$MECH" == "RSA-PKCS" ]; then + ID_WRAP=$ID_RSA_WRAP + fi + for WRAPPER in SoftHSM Kryoptic Softokn; do + for UNWRAPPER in SoftHSM Kryoptic Softokn; do + if [ "$WRAPPER" == "$UNWRAPPER" ]; then + continue; + fi + if [ "$UNWRAPPER" == "SoftHSM" ] && [ $MECH == "AES-CBC" ]; then + continue; + fi + echo "-------------------------------------------------------" + echo " $WRAPPER Wrap -> $UNWRAPPER Unwrap" + echo "-------------------------------------------------------" + get_priv_args "$WRAPPER" + # 1. Load key + $PKCS11_TOOL "${ARGS[@]}" --write-object aes.key --id $ID_AES --type secrkey --key-type AES:32 \ + --usage-decrypt --extractable --label "stored-aes-32" + assert $? "Failed to write AES key on $WRAPPER" + # 2. Wrap + $PKCS11_TOOL "${ARGS[@]}" --wrap -m $MECH --id $ID_WRAP --iv $IV --application-id $ID_AES \ + --output-file wrapped_key.data + assert $? "Failed to wrap AES key with $MECH from $WRAPPER" + + get_priv_args "$UNWRAPPER" + #3. Unwrap + $PKCS11_TOOL "${ARGS[@]}" --unwrap -m $MECH --id $ID_WRAP --iv $IV --application-id $ID_AES \ + --key-type AES: --input-file wrapped_key.data --usage-decrypt --extractable + assert $? "Failed to unwrap AES key with $MECH by $UNWRAPPER" + + # 4. Test unwrapped key with encryption + test_unwrapped_aes_encryption $UNWRAPPER $AES_KEY $ID_AES + + # 5. Clean up + $PKCS11_TOOL "${ARGS[@]}" --delete-object --type secrkey --id $ID_AES + get_priv_args "$WRAPPER" + $PKCS11_TOOL "${ARGS[@]}" --delete-object --type secrkey --id $ID_AES + rm wrapped_key.data + done + done +done + +echo "=======================================================" +echo " Wrap/Unwrap of private keys" +echo "=======================================================" + +for MECH in AES-CBC-PAD; do + ID_WRAP=$ID_AES_WRAP + + for WRAPPER in Kryoptic Softokn; do + for UNWRAPPER in Kryoptic Softokn; do + if [ "$WRAPPER" == "$UNWRAPPER" ]; then + continue; + fi + if { [[ "$MECH" == "AES-CBC-PAD" ]] && ([[ "$WRAPPER" == "SoftHSM" ]] || [[ "$UNWRAPPER" == "SoftHSM" ]]); } || \ + { [[ "$MECH" == "AES-KEY-WRAP-PAD" ]] && ([[ "$WRAPPER" == "Kryoptic" ]] || [[ "$UNWRAPPER" == "Kryoptic" ]]); }; then + continue + fi + echo "-------------------------------------------------------" + echo " $MECH: $WRAPPER Wrap -> $UNWRAPPER Unwrap" + echo "-------------------------------------------------------" + # Wrap + get_priv_args "$WRAPPER" + $PKCS11_TOOL "${ARGS[@]}" --wrap -m $MECH --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key by $WRAPPER" + # Unwrap + get_priv_args "$UNWRAPPER" + $PKCS11_TOOL "${ARGS[@]}" --unwrap -m $MECH --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH by $UNWRAPPER" + rm rsa_wrapped_key.data + + # Remove unwrapped RSA key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED + done + done +done + + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +rm aes_wrap.key rsa_private.der rsa_public.der aes.key + +exit $ERRORS From b33c31ff0e25aedc57046e7ace408e950db95678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 25 Apr 2025 10:33:16 +0200 Subject: [PATCH 3889/4321] Add wrap/unwrap interoperability tests into CI --- .github/setup-fedora.sh | 2 +- .github/workflows/external-pkcs11.yaml | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 3a25f6fc51..a5806ac13a 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -3,7 +3,7 @@ set -ex -o xtrace # Generic dependencies -DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils openpace openpace-devel gawk" +DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils openpace openpace-devel gawk nss-softokn nss-tools" if [ "$1" == "clang" ]; then DEPS="$DEPS clang" diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 10b2db5ad7..73fc6d9bad 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -90,3 +90,22 @@ jobs: env: LD_LIBRARY_PATH: /usr/local/lib run: tests/test-softhsm.sh + + test-interoperability: + runs-on: ubuntu-24.04 + container: + image: fedora:latest + env: + SOURCE_PATH: ./ + BUILD_PATH: ./ + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Setup Fedora + run: .github/setup-fedora.sh kryoptic + - name: Install OpenSC + run: .github/build.sh + - name: Setup Kryoptic + run: .github/setup-kryoptic.sh + - name: Interoperability tests + run: tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh From f041813c3fdf76d80605647f34606827a8178784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 27 May 2025 14:01:04 +0200 Subject: [PATCH 3890/4321] Run wrap/unwrap with AES-KEY-WRAP only for OpenSSL3 --- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 80 +++++++++++----------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 8ddfcd5dfa..57d47ac9b9 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -398,46 +398,48 @@ $PKCS11_TOOL "${PRIV_ARGS[@]}" --keypairgen --key-type rsa:2048 --id $ID_RSA_WRA assert $? "Failed to Generate RSA key" # AES-KEY-WRAP, AES-KEY-WRAP-PAD, AES-CBC, AES-CBC-PAD -if [[ "$TOKENTYPE" == "softhsm" ]]; then - echo "-------------------------------------------------------" - echo "AES-KEY-WRAP Wrap/Unwrap RSA key test" - echo "-------------------------------------------------------" - # Wrap - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ - --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data - assert $? "Failed to wrap RSA key" - # Unwrap - $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ - --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data - assert $? "Failed to unwrap RSA key with $MECH" - rm rsa_wrapped_key.data - - # Test with decryption - test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED - - # Remove unwrapped RSA keys - $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED -fi - -if [[ "$TOKENTYPE" != "kryoptic" ]]; then - echo "-------------------------------------------------------" - echo "AES-KEY-WRAP-PAD Wrap/Unwrap RSA key test" - echo "-------------------------------------------------------" - # Wrap - $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ - --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data - assert $? "Failed to wrap RSA key" - # Unwrap - $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ - --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data - assert $? "Failed to unwrap RSA key with $MECH" - rm rsa_wrapped_key.data - - # Test with decryption - test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED +if [[ -n $is_openssl_3 ]]; then + if [[ "$TOKENTYPE" == "softhsm" ]]; then + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP Wrap/Unwrap RSA key test" + echo "-------------------------------------------------------" + # Wrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key" + # Unwrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH" + rm rsa_wrapped_key.data + + # Test with decryption + test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED + + # Remove unwrapped RSA keys + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED + fi - # Remove unwrapped RSA key - $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED + if [[ "$TOKENTYPE" != "kryoptic" ]]; then + echo "-------------------------------------------------------" + echo "AES-KEY-WRAP-PAD Wrap/Unwrap RSA key test" + echo "-------------------------------------------------------" + # Wrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_WRAPPED --output-file rsa_wrapped_key.data + assert $? "Failed to wrap RSA key" + # Unwrap + $PKCS11_TOOL "${PRIV_ARGS[@]}" --unwrap -m AES-KEY-WRAP-PAD --id $ID_AES_WRAP --iv $IV \ + --application-id $ID_RSA_UNWRAPPED --key-type RSA:2048 --input-file rsa_wrapped_key.data + assert $? "Failed to unwrap RSA key with $MECH" + rm rsa_wrapped_key.data + + # Test with decryption + test_unwrapped_rsa_pkcs_decryption $ID_RSA_WRAPPED $ID_RSA_UNWRAPPED + + # Remove unwrapped RSA key + $PKCS11_TOOL "${PRIV_ARGS[@]}" --delete-object --type privkey --id $ID_RSA_UNWRAPPED + fi fi if [[ "$TOKENTYPE" != "softhsm" ]]; then From 83977f474df47eda391b579ce76a285dd48de268 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 19 May 2025 12:35:48 +0300 Subject: [PATCH 3891/4321] EstEID 2018 v2 fixes with some readers Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2018.c | 11 ++++++++--- src/libopensc/cards.h | 1 + src/libopensc/pkcs15-esteid2018.c | 3 ++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 59791b492b..683b58935a 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -39,9 +39,9 @@ #define PUK_REF 0x02 static const struct sc_atr_table esteid_atrs[] = { - {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL} + {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018_V2_2025, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} }; static const struct sc_aid IASECC_AID = { @@ -265,6 +265,11 @@ static int esteid_init(sc_card_t *card) { if (!priv) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); card->drv_data = priv; + card->max_recv_size = 233; // XXX: empirical, not documented + // Workaround for the 2018 v2 card, with reader Alcor Micro AU9540 + if (card->type == SC_CARD_TYPE_ESTEID_2018_V2_2025) { + card->max_recv_size = 0xC0; + } flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 4ecf16b1f2..e2c4e724e3 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -231,6 +231,7 @@ enum { /* EstEID cards */ SC_CARD_TYPE_ESTEID_2018 = 35000, + SC_CARD_TYPE_ESTEID_2018_V2_2025, SC_CARD_TYPE_ESTEID_2025, /* Rutoken cards */ diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 8295ad51e1..ab728b138b 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -201,7 +201,8 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { } int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { - if (p15card->card->type == SC_CARD_TYPE_ESTEID_2018) + if (p15card->card->type == SC_CARD_TYPE_ESTEID_2018 || + p15card->card->type == SC_CARD_TYPE_ESTEID_2018_V2_2025) return sc_pkcs15emu_esteid2018_init(p15card); return SC_ERROR_WRONG_CARD; } From 72125917695362de3306ebfeb06ce518b6fc42e6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 17 Feb 2025 12:53:38 -0600 Subject: [PATCH 3892/4321] Fix Edwards and Montgomery "field_length" The Edwards and Montgomery "field_length" is changed from 255 to 256 and for Ed448, 448 is changed to 456 as it needs an extra byte. The field_length in bits, and is used to caculate number of bytes. The BYTES4BITS(255) returns 32 and happens to work but should be BTYES4BITS(256) so the 25519 curves have been working but not as expected. But BYTES4BITS(448) returns 56, but Ed448 needed an extra byte so will use BYTES4BITS(456) to return 57 as required in the RFCs. On branch ED448-X448-fix Changes to be committed: modified: src/libopensc/pkcs15-pubkey.c modified: src/pkcs11/framework-pkcs15.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c --- src/libopensc/pkcs15-pubkey.c | 15 ++++++++------- src/pkcs11/framework-pkcs15.c | 6 +++--- src/tools/pkcs11-tool.c | 20 ++++++++++---------- src/tools/pkcs15-init.c | 12 ++++++------ 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 2ff130c22d..f752eaf570 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1524,17 +1524,18 @@ static struct ec_curve_info { /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", {(u8 *)"\x06\x09\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01", 11}, 255, SC_ALGORITHM_EDDSA}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", {(u8 *)"\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01", 12}, 255, SC_ALGORITHM_XEDDSA}, + {"edwards25519", "1.3.6.1.4.1.11591.15.1", {(u8 *)"\x06\x09\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01", 11}, 256, SC_ALGORITHM_EDDSA}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", {(u8 *)"\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01", 12}, 256, SC_ALGORITHM_XEDDSA}, /* RFC 8410 defined curves */ - {"X25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, + {"X25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 256, SC_ALGORITHM_XEDDSA}, {"X448", "1.3.101.111", {(u8 *)"\x06\x03\x2b\x65\x6f", 5}, 448, SC_ALGORITHM_XEDDSA}, - {"Ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, - {"Ed448", "1.3.101.113", {(u8 *)"\x06\x03\x2b\x65\x71", 5}, 448, SC_ALGORITHM_EDDSA}, + {"Ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 256, SC_ALGORITHM_EDDSA}, + /* Ed448 needs extra byte thus 456 */ + {"Ed448", "1.3.101.113", {(u8 *)"\x06\x03\x2b\x65\x71", 5}, 456, SC_ALGORITHM_EDDSA}, /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, - {"ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, + {"cv25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 256, SC_ALGORITHM_XEDDSA}, + {"ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 256, SC_ALGORITHM_EDDSA}, {NULL, NULL, {NULL, 0}, 0, 0}, /* Do not touch this */ }; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index f51cc5f8e4..aed2e9d858 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2866,15 +2866,15 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } if (key_type == CKK_EC_EDWARDS) { - if (ec->ecpointQ.len == BYTES4BITS(255)) + if (ec->ecpointQ.len == BYTES4BITS(256)) ec->params.id = oid_ED25519; - else if (ec->ecpointQ.len == BYTES4BITS(448)) + else if (ec->ecpointQ.len == BYTES4BITS(456)) /* note extra byte */ ec->params.id = oid_ED448; else return CKR_ATTRIBUTE_VALUE_INVALID; } else if (key_type == CKK_EC_MONTGOMERY) { - if (ec->ecpointQ.len == BYTES4BITS(255)) + if (ec->ecpointQ.len == BYTES4BITS(256)) ec->params.id = oid_X25519; else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_X448; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9c53c90c2d..9c31233518 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -154,19 +154,19 @@ static struct ec_curve_info { /* Some of the following may not yet be supported by the OpenSC module, but may be by other modules */ /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs, so pass by printable string */ /* See PKCS#11 3.0 2.3.7 */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", (unsigned char*)"\x13\x0c\x65\x64\x77\x61\x72\x64\x73\x32\x35\x35\x31\x39", 14, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", (unsigned char*)"\x13\x0a\x63\x75\x72\x76\x65\x32\x35\x35\x31\x39", 12, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ + {"edwards25519", "1.3.6.1.4.1.11591.15.1", (unsigned char*)"\x13\x0c\x65\x64\x77\x61\x72\x64\x73\x32\x35\x35\x31\x39", 14, 256, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", (unsigned char*)"\x13\x0a\x63\x75\x72\x76\x65\x32\x35\x35\x31\x39", 12, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ /* RFC8410, EDWARDS and MONTGOMERY curves are used by GnuPG and also by OpenSSL */ - {"X25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"X25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ {"X448", "1.3.101.111", (unsigned char*)"\x06\x03\x2b\x65\x6f", 5, 448, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ {"Ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ - {"Ed448", "1.3.101.113", (unsigned char*)"\x06\x03\x2b\x65\x71", 5, 448, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed448", "1.3.101.113", (unsigned char*)"\x06\x03\x2b\x65\x71", 5, 456, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, - {"ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, + {"cv25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, + {"ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 256, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* OpenSC card-openpgp.c will map these to what is need on the card */ {NULL, NULL, NULL, 0, 0, 0}, @@ -2453,7 +2453,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } /* Ed448: need the params defined but default to false */ - if (curve->size == 448) { + if (curve->size == 456) { mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } @@ -2623,7 +2623,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } /* Ed448: need the params defined but default to false */ - if (curve->size == 448) { + if (curve->size == 456) { mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } @@ -6673,14 +6673,14 @@ static int read_object(CK_SESSION_HANDLE session) } } - if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) + if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) raw_pk = EVP_PKEY_ED25519; #if defined(EVP_PKEY_ED448) else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #if defined(EVP_PKEY_X25519) - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(255)) + else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ #if defined(EVP_PKEY_X448) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e011232987..31c723e767 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -730,15 +730,15 @@ static const struct alg_spec alg_types_asym[] = { { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, /* keybits derived from curve */ /* RFC 8410 */ - { "Ed25519", SC_ALGORITHM_EDDSA, 255 }, /* RFC 8410 and gunpg */ - { "Ed448", SC_ALGORITHM_EDDSA, 448 }, - { "X25519", SC_ALGORITHM_XEDDSA, 255 }, + { "Ed25519", SC_ALGORITHM_EDDSA, 256 }, /* RFC 8410 and gunpg */ + { "Ed448", SC_ALGORITHM_EDDSA, 456 }, /* note extra 8 bits to get 57 bytes */ + { "X25519", SC_ALGORITHM_XEDDSA, 256 }, { "X448", SC_ALGORITHM_XEDDSA, 448 }, /* used by Yubikey and GNUK */ - { "edwards25519", SC_ALGORITHM_EDDSA, 255 }, - { "curve25519", SC_ALGORITHM_XEDDSA, 255 }, + { "edwards25519", SC_ALGORITHM_EDDSA, 256 }, + { "curve25519", SC_ALGORITHM_XEDDSA, 256 }, /* gnupg */ - { "cv25519", SC_ALGORITHM_XEDDSA, 255 }, + { "cv25519", SC_ALGORITHM_XEDDSA, 256 }, { NULL, -1, 0 } }; From a1375a5cdf6ba7ecc1450fcbb03599d54bbdfa7e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 13:54:59 +0200 Subject: [PATCH 3893/4321] pkcs11-tool: Add missing help message to avoid buffer overrun This was uninitentionally omitted in 175ac15c37817d0641ecd87066158365e49c6418 and later reported as #3418. The PR #3419 was stale so fixing this in separate PR. Fixes: #3418 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9c31233518..7ebeb9ee0c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -425,6 +425,7 @@ static const char *option_help[] = { "Specify the required length (in bits) for the authentication tag for AEAD ciphers", "Specify the file containing the salt for HKDF (optional)", "Specify the file containing the info for HKDF (optional)", + "When reading a public key, try to read PUBLIC_KEY_INFO (DER encoding of SPKI)", }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ From 781568f6479e4a8127c7ed53f92e098bcd347146 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 14:07:44 +0200 Subject: [PATCH 3894/4321] piv: Fix possible integer truncation/overflow When negative value is returned from sc_asn1_put_tag(), it is first assigned to `sbuflen`, which is unsigned, truncating the negative numbers. Only after that assigned to the `r`, causing it can't be negative, effectively hiding possible errors from the above function. Thanks coverity (CID 468028) Signed-off-by: Jakub Jelen --- src/libopensc/card-piv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 8a4dc937c9..a266888cae 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2270,7 +2270,7 @@ static int piv_sm_open(struct sc_card *card) r = len2b = sc_asn1_put_tag(0x80, NULL, 0, NULL, 0, NULL); if (r < 0) goto err; - r = sbuflen = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, NULL, 0, NULL); + sbuflen = r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, NULL, 0, NULL); if (r < 0) goto err; @@ -5496,9 +5496,9 @@ static int piv_match_card_continued(sc_card_t *card) */ /* - * if ATR matched or user forced card type - * test if PIV is active applet without using AID If fails use the AID - */ + * if ATR matched or user forced card type + * test if PIV is active applet without using AID If fails use the AID + */ if (card->type != SC_CARD_TYPE_PIV_II_BASE) r = piv_find_discovery(card); From bffa8d2fe30e19dad7e5ee65edf2dddaa3f45d1a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 14:17:51 +0200 Subject: [PATCH 3895/4321] coolkey: Avoid memory leak when reading certificate The certificate is read from the CKA_VALUE, which is allocated in `data` field of `sc_pkcs15_der` structure of the `sc_pkcs15_cert_info`. This is processed, but never cleaned up. Thanks coverity (CID 454833, CID 454822) Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index cf68f7a264..44eb84627a 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -681,7 +681,7 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card) if (key) { sc_pkcs15_free_pubkey(key); } - if (r < 0) { + if (r != SC_SUCCESS) { free(cert_info.value.value); } } From e4eaa2af96867ae256636b075c7fba17f5d37250 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 14:48:42 +0200 Subject: [PATCH 3896/4321] iasecc: Avoid dereference before NULL check Thanks coverity (CID 13754) Signed-off-by: Jakub Jelen --- src/libopensc/iasecc-sm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index e2a254da59..418b06d261 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -38,13 +38,14 @@ static int sm_save_sc_context (struct sc_card *card, struct sm_info *sm_info) { - struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data; + struct iasecc_private_data *prv; struct sc_context *ctx; struct sc_card_cache *cache; if (!card || !sm_info) return SC_ERROR_INVALID_ARGUMENTS; + prv = (struct iasecc_private_data *)card->drv_data; ctx = card->ctx; cache = &prv->cache; From eab4d17866bb457dd86d067b304294e9f6671d52 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Jun 2025 00:52:13 +0200 Subject: [PATCH 3897/4321] fixed Stack-buffer-overflow WRITE fixes https://issues.oss-fuzz.com/issues/421520684 --- src/libopensc/card-oberthur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 7caea31128..6830c81aa0 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1127,7 +1127,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile apdu.lc = ilen; apdu.le = olen > 256 ? 256 : olen; apdu.resp = resp; - apdu.resplen = olen; + apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); From 3402a90d8c9be223d4cf6abe009a4707117d7972 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 4 Jun 2025 01:07:56 +0200 Subject: [PATCH 3898/4321] oberthur: fixed potential Stack-buffer-overflow WRITE --- src/libopensc/card-oberthur.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 6830c81aa0..7a675f03a6 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2245,14 +2245,16 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec, unsigned int idx, if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; - apdu.le = count; - apdu.resplen = count; + apdu.le = count > SC_MAX_APDU_BUFFER_SIZE ? SC_MAX_APDU_BUFFER_SIZE : count; + apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; apdu.resp = recvbuf; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); if (apdu.resplen == 0) LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + if (count < apdu.resplen) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); memcpy(buf, recvbuf, apdu.resplen); rv = sc_check_sw(card, apdu.sw1, apdu.sw2); From a4bbf8a631537a4c0083b264095ed1cd36d307ab Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Jun 2025 13:18:15 +0200 Subject: [PATCH 3899/4321] oberthur: use MIN where possible --- src/libopensc/card-oberthur.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 7a675f03a6..c73d60044b 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -602,7 +602,7 @@ auth_list_files(struct sc_card *card, unsigned char *buf, size_t buflen) if (apdu.resplen == 0x100 && rbuf[0]==0 && rbuf[1]==0) LOG_FUNC_RETURN(card->ctx, 0); - buflen = buflen < apdu.resplen ? buflen : apdu.resplen; + buflen = MIN(buflen, apdu.resplen); memcpy(buf, rbuf, buflen); LOG_FUNC_RETURN(card->ctx, (int)buflen); @@ -1125,7 +1125,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile apdu.datalen = ilen; apdu.data = in; apdu.lc = ilen; - apdu.le = olen > 256 ? 256 : olen; + apdu.le = MIN(olen, 256); apdu.resp = resp; apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; @@ -2245,7 +2245,7 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec, unsigned int idx, if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; - apdu.le = count > SC_MAX_APDU_BUFFER_SIZE ? SC_MAX_APDU_BUFFER_SIZE : count; + apdu.le = MIN(count, SC_MAX_APDU_BUFFER_SIZE); apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; apdu.resp = recvbuf; From 56bc5e9575965461d99a274be45d71c18ab6eae0 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Jun 2025 14:04:35 +0200 Subject: [PATCH 3900/4321] oberthur: use SC_MAX_APDU_RESP_SIZE where possible --- src/libopensc/card-oberthur.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index c73d60044b..59eceac073 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1125,7 +1125,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile apdu.datalen = ilen; apdu.data = in; apdu.lc = ilen; - apdu.le = MIN(olen, 256); + apdu.le = MIN(olen, SC_MAX_APDU_RESP_SIZE); apdu.resp = resp; apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; @@ -1172,14 +1172,14 @@ auth_decipher(struct sc_card *card, const unsigned char *in, size_t inlen, } _inlen = inlen; - if (_inlen == 256) { + if (_inlen == SC_MAX_APDU_RESP_SIZE) { apdu.cla |= 0x10; apdu.data = in; apdu.datalen = 8; apdu.resp = resp; apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; apdu.lc = 8; - apdu.le = 256; + apdu.le = SC_MAX_APDU_RESP_SIZE; rv = sc_transmit_apdu(card, &apdu); sc_log(card->ctx, "rv %i", rv); @@ -1503,7 +1503,7 @@ auth_read_component(struct sc_card *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type { struct sc_apdu apdu; int rv; - unsigned char resp[256]; + unsigned char resp[SC_MAX_APDU_RESP_SIZE]; LOG_FUNC_CALLED(card->ctx); sc_log(card->ctx, "num %i, outlen %"SC_FORMAT_LEN_SIZE_T"u, type %i", @@ -2159,7 +2159,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, if (auth_current_ef->magic==SC_FILE_MAGIC && auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { int jj; - unsigned char resp[256]; + unsigned char resp[SC_MAX_APDU_RESP_SIZE]; size_t resp_len, out_len; struct sc_pkcs15_pubkey_rsa key; From efd1d479832141bcf705c2f47655ada4d5f92f5d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 5 Jun 2025 15:59:19 +0200 Subject: [PATCH 3901/4321] fixed formatting --- src/libopensc/card-oberthur.c | 203 ++++++++++++++-------------------- 1 file changed, 86 insertions(+), 117 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 59eceac073..8a103757e5 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -227,7 +227,7 @@ auth_init(struct sc_card *card) card->caps |= SC_CARD_CAP_RNG; card->caps |= SC_CARD_CAP_USE_FCI_AC; - if (auth_select_aid(card)) { + if (auth_select_aid(card)) { sc_log(card->ctx, "Failed to initialize %s", card->name); rv = SC_ERROR_INVALID_CARD; LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize"); @@ -258,7 +258,7 @@ static void add_acl_entry(struct sc_card *card, struct sc_file *file, unsigned int op, unsigned char acl_byte) { - if ((acl_byte & 0xE0) == 0x60) { + if ((acl_byte & 0xE0) == 0x60) { sc_log(card->ctx, "called; op 0x%X; SC_AC_PRO; ref 0x%X", op, acl_byte); sc_file_add_acl_entry(file, op, SC_AC_PRO, acl_byte); return; @@ -352,7 +352,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, file->size = PUBKEY_1024_ASN1_SIZE; else if (file->size==2048) file->size = PUBKEY_2048_ASN1_SIZE; - else { + else { sc_log(card->ctx, "Not supported public key size: %"SC_FORMAT_LEN_SIZE_T"u", file->size); @@ -391,8 +391,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, add_acl_entry(card, file, SC_AC_OP_PIN_CHANGE, attr[5]); add_acl_entry(card, file, SC_AC_OP_PIN_RESET, attr[6]); sc_log(card->ctx, "SC_FILE_TYPE_DF:CRYPTO %X", attr[1]); - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ switch (file->ef_structure) { case SC_CARDCTL_OBERTHUR_KEY_DES: add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]); @@ -416,8 +415,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, add_acl_entry(card, file, SC_AC_OP_INTERNAL_AUTHENTICATE, attr[5]); break; } - } - else { + } else { switch (file->ef_structure) { case SC_FILE_EF_TRANSPARENT: add_acl_entry(card, file, SC_AC_OP_WRITE, attr[0]); @@ -466,7 +464,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, sc_log(card->ctx, "current file; type=%d, path=%s", auth_current_ef->path.type, sc_print_path(&auth_current_ef->path)); - if (path.type == SC_PATH_TYPE_PARENT || path.type == SC_PATH_TYPE_FILE_ID) { + if (path.type == SC_PATH_TYPE_PARENT || path.type == SC_PATH_TYPE_FILE_ID) { sc_file_free(auth_current_ef); auth_current_ef = NULL; @@ -475,7 +473,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, if (!tmp_file) return SC_ERROR_OBJECT_NOT_FOUND; - if (path.type == SC_PATH_TYPE_PARENT) { + if (path.type == SC_PATH_TYPE_PARENT) { memcpy(&tmp_file->path, &auth_current_df->path, sizeof(struct sc_path)); if (tmp_file->path.len > 2) tmp_file->path.len -= 2; @@ -483,16 +481,14 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, sc_file_free(auth_current_df); auth_current_df = NULL; sc_file_dup(&auth_current_df, tmp_file); - } - else { - if (tmp_file->type == SC_FILE_TYPE_DF) { + } else { + if (tmp_file->type == SC_FILE_TYPE_DF) { sc_concatenate_path(&tmp_file->path, &auth_current_df->path, &path); sc_file_free(auth_current_df); auth_current_df = NULL; sc_file_dup(&auth_current_df, tmp_file); - } - else { + } else { sc_file_free(auth_current_ef); auth_current_ef = NULL; @@ -506,28 +502,26 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, } sc_file_free(tmp_file); - } - else if (path.type == SC_PATH_TYPE_DF_NAME) { + } else if (path.type == SC_PATH_TYPE_DF_NAME) { rv = iso_ops->select_file(card, &path, NULL); - if (rv) { + if (rv) { sc_file_free(auth_current_ef); auth_current_ef = NULL; } LOG_TEST_RET(card->ctx, rv, "select file failed"); - } - else { + } else { for (offs = 0; offs < path.len && offs < auth_current_df->path.len; offs += 2) if (path.value[offs] != auth_current_df->path.value[offs] || path.value[offs + 1] != auth_current_df->path.value[offs + 1]) break; sc_log(card->ctx, "offs %"SC_FORMAT_LEN_SIZE_T"u", offs); - if (offs && offs < auth_current_df->path.len) { + if (offs && offs < auth_current_df->path.len) { size_t deep = auth_current_df->path.len - offs; sc_log(card->ctx, "deep %"SC_FORMAT_LEN_SIZE_T"u", deep); - for (ii=0; iipath, sizeof(struct sc_path)); @@ -543,14 +537,14 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, } } - if (path.len > offs) { + if (path.len > offs) { struct sc_path tmp_path; memset(&tmp_path, 0, sizeof(struct sc_path)); tmp_path.type = SC_PATH_TYPE_FILE_ID; tmp_path.len = 2; - for (ii=0; ii < path.len - offs; ii+=2) { + for (ii = 0; ii < path.len - offs; ii += 2) { memcpy(tmp_path.value, path.value + offs + ii, 2); if (file_out) { @@ -561,8 +555,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, rv = auth_select_file(card, &tmp_path, file_out); LOG_TEST_RET(card->ctx, rv, "select file failed"); } - } - else if (path.len - offs == 0 && file_out) { + } else if (path.len - offs == 0 && file_out) { if (sc_compare_path(&path, &auth_current_df->path) && file_out) { sc_file_free(*file_out); sc_file_dup(file_out, auth_current_df); @@ -625,12 +618,12 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) sc_log(card->ctx, "path; type=%d, path=%s", path->type, pbuf); - if (path->len < 2) { + if (path->len < 2) { sc_log(card->ctx, "Invalid path length"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - if (path->len > 2) { + if (path->len > 2) { struct sc_path parent = *path; parent.len -= 2; @@ -653,7 +646,7 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (apdu.sw1==0x6A && apdu.sw2==0x82) { + if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) { /* Clean up tDF contents.*/ struct sc_path tmp_path; int ii, len; @@ -669,7 +662,7 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) len = auth_list_files(card, lbuf, sizeof(lbuf)); LOG_TEST_RET(card->ctx, len, "list DF failed"); - for (ii=0; iitype == SC_FILE_TYPE_DF) { + if (file->type == SC_FILE_TYPE_DF) { p[4] = 0x38; p[5] = 0x00; - } - else if (file->type == SC_FILE_TYPE_WORKING_EF) { + } else if (file->type == SC_FILE_TYPE_WORKING_EF) { switch (file->ef_structure) { case SC_FILE_EF_TRANSPARENT: p[4] = 0x01; @@ -771,8 +763,7 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, rv = SC_ERROR_INVALID_ARGUMENTS; break; } - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { switch (file->ef_structure) { case SC_CARDCTL_OBERTHUR_KEY_DES: p[4] = 0x11; @@ -790,11 +781,10 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, rv = -1; break; } - } - else + } else rv = SC_ERROR_INVALID_ARGUMENTS; - if (rv) { + if (rv) { sc_log(card->ctx, "Invalid EF structure 0x%X/0x%X", file->type, file->ef_structure); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS); } @@ -809,11 +799,10 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, size = file->size; - if (file->type == SC_FILE_TYPE_DF) { + if (file->type == SC_FILE_TYPE_DF) { size &= 0xFF; - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF && - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF && + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { sc_log(card->ctx, "ef %s","SC_FILE_EF_RSA_PUBLIC"); if (file->size == PUBKEY_512_ASN1_SIZE || file->size == 512) size = 512; @@ -821,22 +810,21 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, size = 1024; else if (file->size == PUBKEY_2048_ASN1_SIZE || file->size == 2048) size = 2048; - else { + else { sc_log(card->ctx, "incorrect RSA size %"SC_FORMAT_LEN_SIZE_T"X", file->size); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS); } - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF && - file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF && + file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { if (file->size == 8 || file->size == 64) size = 64; else if (file->size == 16 || file->size == 128) size = 128; else if (file->size == 24 || file->size == 192) size = 192; - else { + else { sc_log(card->ctx, "incorrect DES size %"SC_FORMAT_LEN_SIZE_T"u", file->size); @@ -858,25 +846,22 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, ops[4] = SC_AC_OP_PIN_DEFINE; ops[5] = SC_AC_OP_PIN_CHANGE; ops[6] = SC_AC_OP_PIN_RESET; - } - else if (file->type == SC_FILE_TYPE_WORKING_EF) { - if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { + } else if (file->type == SC_FILE_TYPE_WORKING_EF) { + if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { sc_log(card->ctx, "SC_FILE_EF_TRANSPARENT"); ops[0] = SC_AC_OP_WRITE; ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_READ; ops[3] = SC_AC_OP_ERASE; - } - else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + } else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { sc_log(card->ctx, "SC_FILE_EF_LINEAR_VARIABLE"); ops[0] = SC_AC_OP_WRITE; ops[1] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_READ; ops[3] = SC_AC_OP_ERASE; } - } - else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { - if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { sc_log(card->ctx, "EF_DES"); ops[0] = SC_AC_OP_UPDATE; ops[1] = SC_AC_OP_PSO_DECRYPT; @@ -885,15 +870,13 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, ops[4] = SC_AC_OP_PSO_VERIFY_CHECKSUM; ops[5] = SC_AC_OP_INTERNAL_AUTHENTICATE; ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE; - } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { sc_log(card->ctx, "EF_RSA_PUBLIC"); ops[0] = SC_AC_OP_UPDATE; ops[2] = SC_AC_OP_PSO_ENCRYPT; ops[4] = SC_AC_OP_PSO_VERIFY_SIGNATURE; ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE; - } - else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { sc_log(card->ctx, "EF_RSA_PRIVATE"); ops[0] = SC_AC_OP_UPDATE; ops[1] = SC_AC_OP_PSO_DECRYPT; @@ -944,12 +927,12 @@ auth_create_file(struct sc_card *card, struct sc_file *file) if (file->id==0x0000 || file->id==0xFFFF || file->id==0x3FFF) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if (file->path.len) { + if (file->path.len) { memcpy(&path, &file->path, sizeof(path)); if (path.len>2) path.len -= 2; - if (auth_select_file(card, &path, NULL)) { + if (auth_select_file(card, &path, NULL)) { sc_log(card->ctx, "Cannot select parent DF."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -974,7 +957,7 @@ auth_create_file(struct sc_card *card, struct sc_file *file) LOG_TEST_RET(card->ctx, rv, "Card returned error"); /* select created DF. */ - if (file->type == SC_FILE_TYPE_DF) { + if (file->type == SC_FILE_TYPE_DF) { struct sc_path tmp_path; struct sc_file *df_file = NULL; @@ -1024,20 +1007,19 @@ auth_set_security_env(struct sc_card *card, if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT)) LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Key file is not selected."); - switch (env->algorithm) { + switch (env->algorithm) { case SC_ALGORITHM_DES: case SC_ALGORITHM_3DES: sc_log(card->ctx, "algo SC_ALGORITHM_xDES: ref %lX, flags %lX", env->algorithm_ref, env->flags); - if (env->operation == SC_SEC_OPERATION_DECIPHER) { + if (env->operation == SC_SEC_OPERATION_DECIPHER) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); apdu.lc = 3; apdu.data = des_sbuf; apdu.datalen = 3; - } - else { + } else { sc_log(card->ctx, "Invalid crypto operation: %X", env->operation); LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto operation"); } @@ -1049,28 +1031,26 @@ auth_set_security_env(struct sc_card *card, LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No support for hashes."); } - if (pads & (~supported_pads)) { + if (pads & (~supported_pads)) { sc_log(card->ctx, "No support for PAD %lX", pads); LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No padding support."); } - if (env->operation == SC_SEC_OPERATION_SIGN) { + if (env->operation == SC_SEC_OPERATION_SIGN) { rsa_sbuf[2] = 0x11; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); apdu.lc = sizeof(rsa_sbuf); apdu.datalen = sizeof(rsa_sbuf); apdu.data = rsa_sbuf; - } - else if (env->operation == SC_SEC_OPERATION_DECIPHER) { + } else if (env->operation == SC_SEC_OPERATION_DECIPHER) { rsa_sbuf[2] = 0x11; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); apdu.lc = sizeof(rsa_sbuf); apdu.datalen = sizeof(rsa_sbuf); apdu.data = rsa_sbuf; - } - else { + } else { sc_log(card->ctx, "Invalid crypto operation: %X", env->operation); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } @@ -1106,10 +1086,9 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile unsigned char resp[SC_MAX_APDU_BUFFER_SIZE]; int rv; - if (!card || !in || !out) { + if (!card || !in || !out) { return SC_ERROR_INVALID_ARGUMENTS; - } - else if (ilen > 96) { + } else if (ilen > 96) { sc_log(card->ctx, "Illegal input length %"SC_FORMAT_LEN_SIZE_T"u", ilen); @@ -1134,7 +1113,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Compute signature failed"); - if (apdu.resplen > olen) { + if (apdu.resplen > olen) { sc_log(card->ctx, "Compute signature failed: invalid response length %"SC_FORMAT_LEN_SIZE_T"u", apdu.resplen); @@ -1166,13 +1145,13 @@ auth_decipher(struct sc_card *card, const unsigned char *in, size_t inlen, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); sc_log(card->ctx, "algorithm SC_ALGORITHM_RSA"); - if (inlen % 64) { + if (inlen % 64) { rv = SC_ERROR_INVALID_ARGUMENTS; goto done; } _inlen = inlen; - if (_inlen == SC_MAX_APDU_RESP_SIZE) { + if (_inlen == SC_MAX_APDU_RESP_SIZE) { apdu.cla |= 0x10; apdu.data = in; apdu.datalen = 8; @@ -1257,7 +1236,7 @@ auth_generate_key(struct sc_card *card, int use_sm, LOG_FUNC_CALLED(card->ctx); if (data->key_bits < 512 || data->key_bits > 2048 || - (data->key_bits%0x20)!=0) { + (data->key_bits % 0x20) != 0) { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal key length"); } @@ -1265,7 +1244,7 @@ auth_generate_key(struct sc_card *card, int use_sm, sbuf[1] = data->id_pub & 0xFF; sbuf[2] = (data->id_prv >> 8) & 0xFF; sbuf[3] = data->id_prv & 0xFF; - if (data->exponent != 0x10001) { + if (data->exponent != 0x10001) { rv = auth_encode_exponent(data->exponent, &sbuf[5],SC_MAX_APDU_BUFFER_SIZE-6); LOG_TEST_RET(card->ctx, rv, "Cannot encode exponent"); @@ -1303,7 +1282,7 @@ auth_generate_key(struct sc_card *card, int use_sm, apdu.resplen = rv; - if (data->pubkey) { + if (data->pubkey) { if (data->pubkey_len < apdu.resplen) { rv = SC_ERROR_INVALID_ARGUMENTS; LOG_TEST_GOTO_ERR(card->ctx, rv, "invalid length received"); @@ -1347,7 +1326,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a memcpy(sbuf + len, args->data, args->len); len += args->len; - if (args->type == SC_CARDCTL_OBERTHUR_KEY_DES) { + if (args->type == SC_CARDCTL_OBERTHUR_KEY_DES) { int outl; const unsigned char in[8] = {0,0,0,0,0,0,0,0}; unsigned char out[8]; @@ -1385,8 +1364,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a sbuf[len++] = 0x03; memcpy(sbuf + len, out, 3); len += 3; - } - else { + } else { sbuf[len++] = 0; } @@ -1395,7 +1373,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a apdu.data = sbuf; apdu.datalen = len; apdu.lc = len; - if (args->len == 0x100) { + if (args->len == 0x100) { sbuf[0] = args->type; sbuf[1] = 0x20; memcpy(sbuf + 2, args->data, 0x20); @@ -1436,7 +1414,7 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info if (info->data_len != sizeof(void *) || !info->data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { struct sc_pkcs15_prkey_rsa *rsa = (struct sc_pkcs15_prkey_rsa *)info->data; struct sc_pkcs15_bignum bn[5]; @@ -1446,7 +1424,7 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info bn[2] = rsa->iqmp; bn[3] = rsa->dmp1; bn[4] = rsa->dmq1; - for (ii=0;ii<5;ii++) { + for (ii = 0; ii < 5; ii++) { struct auth_update_component_info args; memset(&args, 0, sizeof(args)); @@ -1458,11 +1436,9 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info rv = auth_update_component(card, &args); LOG_TEST_RET(card->ctx, rv, "Update RSA component failed"); } - } - else if (info->type == SC_CARDCTL_OBERTHUR_KEY_DES) { + } else if (info->type == SC_CARDCTL_OBERTHUR_KEY_DES) { rv = SC_ERROR_NOT_SUPPORTED; - } - else { + } else { rv = SC_ERROR_INVALID_DATA; } @@ -1564,11 +1540,10 @@ auth_init_pin_info(struct sc_card *card, struct sc_pin_cmd_pin *pin, pin->pad_char = 0xFF; pin->encoding = SC_PIN_ENCODING_ASCII; - if (type == OBERTHUR_AUTH_TYPE_PIN) { + if (type == OBERTHUR_AUTH_TYPE_PIN) { pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PIN; pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PIN; - } - else { + } else { pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PUK; pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PUK; } @@ -1688,7 +1663,7 @@ auth_pin_is_verified(struct sc_card *card, int pin_reference, int *tries_left) *tries_left = apdu.sw2 & 0x0F; /* Replace 'no tries left' with 'auth method blocked' */ - if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) { + if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) { apdu.sw1 = 0x69; apdu.sw2 = 0x83; } @@ -1765,7 +1740,7 @@ auth_pin_change(struct sc_card *card, unsigned int type, LOG_FUNC_CALLED(card->ctx); - if (data->pin1.len && data->pin2.len) { + if (data->pin1.len && data->pin2.len) { /* Direct unblock style */ data->flags |= SC_PIN_CMD_NEED_PADDING; data->flags &= ~SC_PIN_CMD_USE_PINPAD; @@ -1778,13 +1753,11 @@ auth_pin_change(struct sc_card *card, unsigned int type, rv = iso_drv->ops->pin_cmd(card, data, tries_left); LOG_TEST_RET(card->ctx, rv, "CMD 'PIN CHANGE' failed"); - } - else if (!data->pin1.len && !data->pin2.len) { + } else if (!data->pin1.len && !data->pin2.len) { /* Oberthur unblock style with PIN pad. */ rv = auth_pin_change_pinpad(card, data, tries_left); LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failed: SOPIN verify with pinpad failed"); - } - else { + } else { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed"); } @@ -1850,7 +1823,7 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, pin_cmd.pin1.data = ffs1; pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PUK; - if (data->pin2.data) { + if (data->pin2.data) { memcpy(&pin_cmd.pin2, &data->pin2, sizeof(pin_cmd.pin2)); rv = auth_pin_reset(card, SC_AC_CHV, &pin_cmd, tries_left); LOG_FUNC_RETURN(card->ctx, rv); @@ -1985,7 +1958,7 @@ auth_create_reference_data (struct sc_card *card, len += pin_info.pad_length; sc_log(card->ctx, "len %i", len); - if (args->puk && args->puk_len) { + if (args->puk && args->puk_len) { sbuf[len++] = args->puk_tries; sbuf[len++] = args->puk_len / puk_info.pad_length; sc_log(card->ctx, "len %i", len); @@ -2016,7 +1989,7 @@ auth_logout(struct sc_card *card) int ii, rv = 0, pin_ref; int reset_flag = 0x20; - for (ii=0; ii < 4; ii++) { + for (ii = 0; ii < 4; ii++) { rv = auth_get_pin_reference (card, SC_AC_CHV, ii+1, SC_PIN_CMD_UNBLOCK, &pin_ref); LOG_TEST_RET(card->ctx, rv, "Cannot get PIN reference"); @@ -2025,7 +1998,6 @@ auth_logout(struct sc_card *card) apdu.p2 = pin_ref | reset_flag; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); - } LOG_FUNC_RETURN(card->ctx, rv); @@ -2053,7 +2025,7 @@ write_publickey (struct sc_card *card, unsigned int offset, memcpy(rsa_der + offset, buf, len); rsa_der_len = offset + len; - if (rsa_der[0]==0x30) { + if (rsa_der[0] == 0x30) { if (rsa_der[1] & 0x80) for (ii=0; ii < (rsa_der[1]&0x0F); ii++) der_size = der_size*0x100 + rsa_der[2+ii]; @@ -2109,12 +2081,11 @@ auth_update_binary(struct sc_card *card, unsigned int offset, if (offset & ~0x7FFF) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset"); - if (auth_current_ef->magic==SC_FILE_MAGIC && - auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + if (auth_current_ef->magic == SC_FILE_MAGIC && + auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { rv = write_publickey(card, offset, buf, count); - } - else if (auth_current_ef->magic==SC_FILE_MAGIC && - auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + } else if (auth_current_ef->magic == SC_FILE_MAGIC && + auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { struct auth_update_component_info args; memset(&args, 0, sizeof(args)); @@ -2122,8 +2093,7 @@ auth_update_binary(struct sc_card *card, unsigned int offset, args.data = (unsigned char *)buf; args.len = count; rv = auth_update_component(card, &args); - } - else { + } else { rv = iso_ops->update_binary(card, offset, buf, count, 0); } @@ -2156,8 +2126,8 @@ auth_read_binary(struct sc_card *card, unsigned int offset, if (offset & ~0x7FFF) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset"); - if (auth_current_ef->magic==SC_FILE_MAGIC && - auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + if (auth_current_ef->magic == SC_FILE_MAGIC && + auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { int jj; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; size_t resp_len, out_len; @@ -2211,8 +2181,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, sc_log_hex(card->ctx, "write_publickey", buf, sz); rv = (int)sz; } - } - else { + } else { rv = iso_ops->read_binary(card, offset, buf, count, 0); } @@ -2312,8 +2281,8 @@ auth_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) { int ii; - for (ii=0; auth_warnings[ii].SWs; ii++) { - if (auth_warnings[ii].SWs == ((sw1 << 8) | sw2)) { + for (ii = 0; auth_warnings[ii].SWs; ii++) { + if (auth_warnings[ii].SWs == ((sw1 << 8) | sw2)) { sc_log(card->ctx, "%s", auth_warnings[ii].errorstr); return auth_warnings[ii].errorno; } From e5a40f63525b4c01c9901918b7211d802ff027f9 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 3 Jun 2025 11:17:19 +0300 Subject: [PATCH 3902/4321] Upgrade Wix 6.0.0 * Fix PKCS11-Spy location in arm64 * Make minidriver conditional * Remove deprecated GithubActions Windows 2019 runner Signed-off-by: Raul Metsma --- .github/setup-wix.ps1 | 2 +- .github/vcpkg.json | 2 +- .github/workflows/windows.yml | 20 +-- win32/Make.rules.mak | 10 +- win32/OpenSC.wxs.in | 253 +++++++++++++++------------------- 5 files changed, 131 insertions(+), 156 deletions(-) diff --git a/.github/setup-wix.ps1 b/.github/setup-wix.ps1 index d9828b7e16..42a0021e39 100644 --- a/.github/setup-wix.ps1 +++ b/.github/setup-wix.ps1 @@ -1,5 +1,5 @@ param( - [string]$version = '5.0.2' + [string]$version = '6.0.0' ) & dotnet tool install -g --version $version wix & wix extension add -g WixToolset.UI.wixext/$version diff --git a/.github/vcpkg.json b/.github/vcpkg.json index 32ea198967..ead08f8ca9 100644 --- a/.github/vcpkg.json +++ b/.github/vcpkg.json @@ -4,5 +4,5 @@ "openssl", "zlib" ], - "builtin-baseline": "e4644bd15436d406bba71928d086c809e5c9ca45" + "builtin-baseline": "0d5cae153065957df7f382de7c1549ccc88027e5" } diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8261a53c3e..1001f9f7e2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -22,7 +22,7 @@ jobs: matrix: platform: [x86, x64, arm64] configuration: [Light, Release] - image: [windows-2019, windows-2022] + image: [windows-2022] include: - platform: x86 setenv: amd64_x86 @@ -72,7 +72,7 @@ jobs: if: matrix.configuration == 'Release' uses: lukka/run-vcpkg@v11 with: - vcpkgGitCommitId: e4644bd15436d406bba71928d086c809e5c9ca45 + vcpkgGitCommitId: 0d5cae153065957df7f382de7c1549ccc88027e5 vcpkgJsonGlob: .github/vcpkg.json runVcpkgInstall: true env: @@ -123,15 +123,17 @@ jobs: run: | nmake /nologo /f Makefile.mak opensc.msi move win32\OpenSC.msi OpenSC-${env:ARTIFACT}.msi - - name: Debug symbols - run: | - Get-ChildItem -recurse . -exclude vc*.pdb *.pdb | % { - 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName - } - name: Archive artifacts uses: actions/upload-artifact@v4 with: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} + path: ./*.msi + - name: Archive debug artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ env.ARTIFACT }}-Debug path: | - ./*.msi - ./*-Debug.zip + ./src/**/*.pdb + ./win32/*.pdb + !./src/**/vc*.pdb + !./win32/vc*.pdb diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 4c31fd258d..78dff1c06d 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -2,15 +2,17 @@ OPENSC_FEATURES = pcsc #Include support for minidriver MINIDRIVER_DEF = /DENABLE_MINIDRIVER +WIXFLAGS = -d ENABLE_MINIDRIVER #Build MSI with the Windows Installer XML (WIX) toolkit !IF "$(WIX_PACKAGES)" == "" WIX_PACKAGES = $(TOPDIR)\win32\packages +WIX_VERSION = 6.0.0 !ENDIF -WIX_INCL_DIR = "/I$(WIX_PACKAGES)/wixtoolset.dutil/5.0.2/build/native/include" \ - "/I$(WIX_PACKAGES)/wixtoolset.wcautil/5.0.2/build/native/include" -WIX_LIBS = "$(WIX_PACKAGES)/wixtoolset.dutil/5.0.2/build/native/v14/$(PLATFORM)/dutil.lib" \ - "$(WIX_PACKAGES)/wixtoolset.wcautil/5.0.2/build/native/v14/$(PLATFORM)/wcautil.lib" +WIX_INCL_DIR = "/I$(WIX_PACKAGES)/wixtoolset.dutil/$(WIX_VERSION)/build/native/include" \ + "/I$(WIX_PACKAGES)/wixtoolset.wcautil/$(WIX_VERSION)/build/native/include" +WIX_LIBS = "$(WIX_PACKAGES)/wixtoolset.dutil/$(WIX_VERSION)/build/native/v14/$(PLATFORM)/dutil.lib" \ + "$(WIX_PACKAGES)/wixtoolset.wcautil/$(WIX_VERSION)/build/native/v14/$(PLATFORM)/wcautil.lib" # We do not build tests on windows #TESTS_DEF = /DENABLE_TESTS diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index c6b181f81e..715bcae0f1 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -28,14 +28,16 @@ - + Version="!(bind.FileVersion.opensc.dll)" + Manufacturer="@OPENSC_VS_FF_COMPANY_NAME@" + Compressed="yes"> @@ -50,11 +52,6 @@ - - - - - @@ -63,169 +60,143 @@ - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + - - - + + + + - - + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + - + + - - + + + + + - - + + + + + + - - - - - - + + + + + @@ -237,7 +208,7 @@ - + From a7e33798aa814f8aa2e6dd664f45f459213b1c5e Mon Sep 17 00:00:00 2001 From: Shawn C Date: Fri, 16 May 2025 15:25:48 +0800 Subject: [PATCH 3903/4321] Fix the memory leaks and unifying the allocation/deallocation Caught by libp11 regression tests: https://github.com/OpenSC/libp11/issues/597 Signed-off-by: Shawn Chang --- src/tools/pkcs11-tool.c | 48 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7ebeb9ee0c..f3287059c5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -576,6 +576,9 @@ struct gostkey_info { struct sc_lv_data param_oid; struct sc_lv_data public; struct sc_lv_data private; +#ifdef EC_POINT_NO_ASN1_OCTET_STRING + size_t header_len; +#endif }; static void show_cryptoki_info(void); @@ -4055,7 +4058,7 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) #define RSA_GET_BN(RSA, LOCALNAME, BNVALUE) \ do { \ if (BNVALUE) { \ - RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \ + RSA->LOCALNAME = OPENSSL_malloc(BN_num_bytes(BNVALUE)); \ if (!RSA->LOCALNAME) \ util_fatal("malloc() failure\n"); \ RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \ @@ -4167,7 +4170,7 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) if (rv < 0) return -1; - gost->param_oid.value = malloc(rv); + gost->param_oid.value = OPENSSL_malloc(rv); if (!gost->param_oid.value) return -1; @@ -4183,7 +4186,7 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) return -1; #endif gost->private.len = BN_num_bytes(bignum); - gost->private.value = malloc(gost->private.len); + gost->private.value = OPENSSL_malloc(gost->private.len); if (!gost->private.value) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(bignum); @@ -4203,21 +4206,22 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #else group = EC_GROUP_new_by_curve_name_ex(osslctx, NULL, nid); EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pubkey_len); - if (!(pubkey = malloc(pubkey_len)) || - EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey, pubkey_len, NULL) != 1 || - !(point = EC_POINT_new(group)) || - EC_POINT_oct2point(group, point, pubkey, pubkey_len, NULL) != 1) { + if (!(pubkey = OPENSSL_malloc(pubkey_len)) || + EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey, pubkey_len, NULL) != 1 || + !(point = EC_POINT_new(group)) || + EC_POINT_oct2point(group, point, pubkey, pubkey_len, NULL) != 1) { EC_GROUP_free(group); EC_POINT_free(point); return -1; } + OPENSSL_free(pubkey); #endif rv = -1; if (X && Y && point && group) rv = EC_POINT_get_affine_coordinates(group, point, X, Y, NULL); if (rv == 1) { gost->public.len = BN_num_bytes(X) + BN_num_bytes(Y); - gost->public.value = malloc(gost->public.len); + gost->public.value = OPENSSL_malloc(gost->public.len); if (!gost->public.value) rv = -1; else @@ -4264,7 +4268,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) } #endif gost->private.len = BN_num_bytes(bignum); - gost->private.value = malloc(gost->private.len); + gost->private.value = OPENSSL_malloc(gost->private.len); if (!gost->private.value) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(bignum); @@ -4289,7 +4293,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #else EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, sizeof(buf), &point_len); #endif - gost->public.value = malloc(MAX_HEADER_LEN+point_len); + gost->public.value = OPENSSL_malloc(MAX_HEADER_LEN + point_len); if (!gost->public.value) return -1; point = gost->public.value; @@ -4300,6 +4304,8 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #ifdef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding gost->public.len -= header_len; gost->public.value += header_len; + // store header_len to restore public.value before free it + gost->header_len = header_len; #endif } @@ -4459,12 +4465,30 @@ parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curv return 0; } #endif -static void gost_info_free(struct gostkey_info gost) +static void +gost_info_free(struct gostkey_info gost) { +#ifdef EC_POINT_NO_ASN1_OCTET_STRING // restore public.value before free it + if (gost.public.value) + gost.public.value -= gost.header_len; +#endif OPENSSL_free(gost.param_oid.value); OPENSSL_free(gost.public.value); OPENSSL_free(gost.private.value); } + +static void +rsa_info_free(struct rsakey_info rsa) +{ + OPENSSL_free(rsa.modulus); + OPENSSL_free(rsa.public_exponent); + OPENSSL_free(rsa.private_exponent); + OPENSSL_free(rsa.prime_1); + OPENSSL_free(rsa.prime_2); + OPENSSL_free(rsa.exponent_1); + OPENSSL_free(rsa.exponent_2); + OPENSSL_free(rsa.coefficient); +} #endif /* Currently for certificates (-type cert), private keys (-type privkey), @@ -5043,6 +5067,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #ifdef ENABLE_OPENSSL gost_info_free(gost); + rsa_info_free(rsa); EVP_PKEY_free(evp_key); #endif /* ENABLE_OPENSSL */ @@ -6041,6 +6066,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } printf("\n"); } + free(mechs); if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { printf(" Unique ID: %s\n", unique_id); free(unique_id); From c190f9e606e703c2071be18c6faa2c14d755e63c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 17:46:08 +0200 Subject: [PATCH 3904/4321] openpgp: Check return values to prevent crashing on invalid input Thanks oss-fuzz https://issues.oss-fuzz.com/u/1/issues/421943164 Signed-off-by: Jakub Jelen --- src/libopensc/card-openpgp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 3abc5b41f0..0f614212ce 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2951,8 +2951,10 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8 *data, size_t data_len, /* store creation time */ r = pgp_store_creationtime(card, key_info->key_id, &ctime); - /* TODO for now with GNUK at least, log but do not return error */ - sc_log(card->ctx, "Cannot store creation time"); + if (r != SC_SUCCESS) { + /* TODO for now with GNUK at least, log but do not return error */ + sc_log(card->ctx, "Cannot store creation time"); + } /* parse response. Ref: pgp_enumerate_blob() */ while (data_len > (size_t) (in - data)) { @@ -3196,8 +3198,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info) LOG_TEST_GOTO_ERR(card->ctx, r, "Card returned error"); /* parse response data and set output */ - pgp_parse_and_set_pubkey_output(card, apdu.resp, apdu.resplen, key_info); - pgp_update_card_algorithms(card, key_info); + r = pgp_parse_and_set_pubkey_output(card, apdu.resp, apdu.resplen, key_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to parse pubkey output"); + r = pgp_update_card_algorithms(card, key_info); err: free(apdu.resp); From 9f2a5df7e41417ddacaf75c2129936a1e8c0cc04 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 18:46:46 +0200 Subject: [PATCH 3905/4321] ci: Upgrade the container image befor installing debug sysmbols --- .github/setup-linux.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 24d166735a..5425372a00 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -91,6 +91,15 @@ deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-updates main restric deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-proposed main restricted universe multiverse" | \ $SUDO tee -a /etc/apt/sources.list.d/ddebs.list $SUDO apt-get update -qq + + # Github Actions images are terribly large containing a lot of nonsense that takes ages just to upgrade + if [ -n "$GITHUB_ACTIONS" ]; then + $SUDO apt-get autopurge snapd + $SUDO apt-mark hold snapd + $SUDO apt-get remove -y -qq mysql* php* firefox ruby* dotnet* + fi + + $SUDO apt-get upgrade -qq ARCH_TRIPLET=$(dpkg-architecture -qDEB_HOST_MULTIARCH) DEP="libssl1.1-dbgsym" if [ -f "/usr/lib/${ARCH_TRIPLET}/libssl.so.3" ]; then From d28d07524a023b31d42e3599be84eedf089ac410 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 6 Jun 2025 11:09:32 +0200 Subject: [PATCH 3906/4321] ci: Do not fail fast to allow working jobs to finish --- .github/workflows/linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 3565c715bc..1aa79750dc 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -34,6 +34,7 @@ jobs: build: name: build-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }} strategy: + fail-fast: false matrix: dist: ['22.04', '24.04'] arch: ['amd64', 'arm64'] From 53d7e117bae6a20822b8f2522ce03192b2528a5b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 6 Jun 2025 16:58:26 +0200 Subject: [PATCH 3907/4321] ci: Install missing debug symobls Without this, valgrind fails with every program like this in some configurations on ubuntu 22. valgrind: Fatal error at startup: a function redirection valgrind: which is mandatory for this platform-tool combination valgrind: cannot be set up. Details of the redirection are: valgrind: valgrind: A must-be-redirected function valgrind: whose name matches the pattern: strlen valgrind: in an object with soname matching: ld-linux-x86-64.so.2 valgrind: was not found whilst processing valgrind: symbols from the object with soname: ld-linux-x86-64.so.2 valgrind: valgrind: Possible fixes: (1, short term): install glibc's debuginfo valgrind: package on this machine. (2, longer term): ask the packagers valgrind: for your Linux distribution to please in future ship a non- valgrind: stripped ld.so (or whatever the dynamic linker .so is called) valgrind: that exports the above-named function using the standard valgrind: calling conventions for this platform. The package you need valgrind: to install for fix (1) is called valgrind: valgrind: On Debian, Ubuntu: libc6-dbg valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo valgrind: valgrind: Note that if you are debugging a 32 bit process on a valgrind: 64 bit system, you will need a corresponding 32 bit debuginfo valgrind: package (e.g. libc6-dbg:i386). valgrind: valgrind: Cannot continue -- exiting now. Sorry. Signed-off-by: Jakub Jelen --- .github/setup-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 5425372a00..1b1a6b2120 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -107,7 +107,7 @@ deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-proposed main restri DEPX=`dpkg -S "/usr/lib/${ARCH_TRIPLET}/libssl.so.3"` DEP="${DEPX%%:*}-dbgsym" fi - $SUDO apt-get install -y openssl-dbgsym "$DEP" softhsm2-dbgsym libsofthsm2-dbgsym + $SUDO apt-get install -y openssl-dbgsym "$DEP" softhsm2-dbgsym libsofthsm2-dbgsym libc6-dbg fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then From a3def3e395b3ed9957740b0c45fea37f1c3afdf9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Jun 2025 10:26:11 +0200 Subject: [PATCH 3908/4321] ci: Exclude valgrind on arm64 on ubuntu 22 as it is broken now --- .github/workflows/linux.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1aa79750dc..b5524c7798 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -42,6 +42,9 @@ jobs: exclude: - build: dist arch: arm64 + - dist: 22.04 + build: valgrind + arch: arm64 runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - uses: actions/checkout@v4 From c32fd39d4bfd6fd9ff2dd92f1351ca45e1e176ff Mon Sep 17 00:00:00 2001 From: Marc Willert <78364219+marcwillert@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:04:16 +0200 Subject: [PATCH 3909/4321] initialize keyblob keyblob is a local variable as local variables are not initialized, its value is indeterminate keyblob is passed into fread_to_eof(...) which will do a realloc on keyblob --- src/tools/sc-hsm-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 44ae92a0b0..accadf772c 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -1546,7 +1546,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p { sc_cardctl_sc_hsm_wrapped_key_t wrapped_key; struct sc_pin_cmd_data data; - u8 *keyblob; + u8 *keyblob = NULL; const u8 *ptr, *prkd, *cert; sc_path_t path; u8 fid[2]; From 785f904df891487bd4dd1b3987729b81e14bf3b4 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Mon, 21 Jul 2025 10:13:29 +0200 Subject: [PATCH 3910/4321] Add new card type NQ_APPLET_RFID --- src/libopensc/cards.h | 1 + src/libopensc/pkcs15-nqApplet.c | 2 +- src/libopensc/pkcs15-syn.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index e2c4e724e3..a11526cdda 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -255,6 +255,7 @@ enum { /* JCOP4 cards with NQ-Applet */ SC_CARD_TYPE_NQ_APPLET = 39000, + SC_CARD_TYPE_NQ_APPLET_RFID = 39001, /* Slovak eID cards */ SC_CARD_TYPE_SKEID_BASE = 40000, diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 37103389c0..00966f3461 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -188,7 +188,7 @@ int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); - if (card->type != SC_CARD_TYPE_NQ_APPLET) { + if (card->type < SC_CARD_TYPE_NQ_APPLET || card->type > SC_CARD_TYPE_NQ_APPLET_RFID) { sc_log(p15card->card->ctx, "Unsupported card type: %d", card->type); return SC_ERROR_WRONG_CARD; } diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 8874555a5b..3c20f9ad89 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -110,6 +110,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_CARDOS_V5_0: case SC_CARD_TYPE_CARDOS_V5_3: case SC_CARD_TYPE_NQ_APPLET: + case SC_CARD_TYPE_NQ_APPLET_RFID: case SC_CARD_TYPE_STARCOS_V3_4_ESIGN: case SC_CARD_TYPE_STARCOS_V3_5_ESIGN: case SC_CARD_TYPE_SKEID_V3: From 17cf7b9b666492d52451d0dd79d1ee7dae3f9d86 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Mon, 21 Jul 2025 10:14:13 +0200 Subject: [PATCH 3911/4321] Add nqApplet RFID and JCOP4.52 ATRs --- src/libopensc/card-nqApplet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 025847bbbf..e015064725 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -33,7 +33,9 @@ /* card constants */ static const struct sc_atr_table nqapplet_atrs[] = { - {"3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, + {"3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, // JCOP4 + {"3b:d8:18:ff:81:b1:fe:45:1f:c3:80:73:c8:21:10:52:b7:7f:f8", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, //JCOP4.52 + {"3b:85:80:01:80:73:C8:21:10:0e", NULL, NULL, SC_CARD_TYPE_NQ_APPLET_RFID, 0, NULL}, {NULL, NULL, NULL, 0, 0, NULL}}; static const u8 nqapplet_aid[] = {0xd2, 0x76, 0x00, 0x01, 0x80, 0xBA, 0x01, 0x44, 0x02, 0x01, 0x00}; From 5601046f4b262ff5e5c21879b921e05fc7b91a72 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Mon, 21 Jul 2025 10:25:53 +0200 Subject: [PATCH 3912/4321] Add PIN handling fix for cards with multiple applets --- src/libopensc/card-nqApplet.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index e015064725..e3cb3201a5 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -449,6 +449,22 @@ static int nqapplet_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return SC_ERROR_NOT_SUPPORTED; } +static int nqapplet_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + int r; + + LOG_FUNC_CALLED(card->ctx); + r = iso_operations->pin_cmd(card, data, tries_left); + if ( r == SC_ERROR_OBJECT_NOT_FOUND ) { + /* it is possible that the NQ-Applet is not active, try to activate it */ + r = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); + if ( r == SC_SUCCESS ) { + r = iso_operations->pin_cmd(card, data, tries_left); + } + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + struct sc_card_driver *sc_get_nqApplet_driver(void) { sc_card_driver_t *iso_driver = sc_get_iso7816_driver(); @@ -473,6 +489,7 @@ struct sc_card_driver *sc_get_nqApplet_driver(void) nqapplet_operations.get_data = nqapplet_get_data; nqapplet_operations.select_file = nqapplet_select_file; nqapplet_operations.card_ctl = nqapplet_card_ctl; + nqapplet_operations.pin_cmd = nqapplet_pin_cmd; /* unsupported operations */ nqapplet_operations.read_binary = NULL; @@ -498,7 +515,6 @@ struct sc_card_driver *sc_get_nqApplet_driver(void) nqapplet_operations.read_public_key = NULL; /* let iso driver handle these operations - nqapplet_operations.pin_cmd; nqapplet_operations.card_reader_lock_obtained; nqapplet_operations.wrap; nqapplet_operations.unwrap; From c52c0d87fe54ef14e1e49311724da49e09f9f7b7 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Mon, 21 Jul 2025 10:27:43 +0200 Subject: [PATCH 3913/4321] Add support for cards without Encryption option --- src/libopensc/pkcs15-nqApplet.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index 00966f3461..f5a178f06b 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -164,11 +164,13 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) // 3.1) C.CH.Encr rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); - LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. certificate"); - - // 3.2) PrK.CH.Encr - rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); - LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); + if ( rv == SC_SUCCESS ) { + // 3.2) PrK.CH.Encr + rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); + LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); + } else { + sc_log(p15card->card->ctx, "The card has no C.CH.Encr, ignoring CH.Encr container"); + } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } From 46f284c113be69827c1cc313c620bb26afe454d5 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Mon, 21 Jul 2025 10:44:46 +0200 Subject: [PATCH 3914/4321] Add nqApplet minidriver registration --- win32/customactions.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 3e48855294..0db8b5bbb8 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -205,6 +205,14 @@ MD_REGISTRATION minidriver_registration[] = { /* from card-piv.c */ {TEXT("Swissbit iShield Key Pro"), {0x3b,0x97,0x11,0x81,0x21,0x75,0x69,0x53,0x68,0x69,0x65,0x6c,0x64,0x05}, 14, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + + /* from nqApplet.c */ + {TEXT("nqApplet JCOP4"), {0x3b,0xd5,0x18,0xff,0x81,0x91,0xfe,0x1f,0xc3,0x80,0x73,0xc8,0x21,0x10,0x0a}, + 15, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("nqApplet JCOP4.52"), {0x3b,0xd8,0x18,0xff,0x81,0xb1,0xfe,0x45,0x1f,0xc3,0x80,0x73,0xc8,0x21,0x10,0x52,0xb7,0x7f,0xf8}, + 19, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + {TEXT("nqApplet JCOP4 RFID"), {0x3b,0x85,0x80,0x01,0x80,0x73,0xC8,0x21,0x10,0x0e}, + 10, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, }; // clang-format on From 7f3dd28866fe96461519f7bafae5851b649d96e7 Mon Sep 17 00:00:00 2001 From: jozsefd Date: Mon, 21 Jul 2025 17:29:30 +0200 Subject: [PATCH 3915/4321] Fix formatting --- src/libopensc/card-nqApplet.c | 16 +++++++++------- src/libopensc/pkcs15-nqApplet.c | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index e3cb3201a5..37ee057cca 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -33,10 +33,11 @@ /* card constants */ static const struct sc_atr_table nqapplet_atrs[] = { - {"3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, // JCOP4 - {"3b:d8:18:ff:81:b1:fe:45:1f:c3:80:73:c8:21:10:52:b7:7f:f8", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, //JCOP4.52 - {"3b:85:80:01:80:73:C8:21:10:0e", NULL, NULL, SC_CARD_TYPE_NQ_APPLET_RFID, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL}}; + {"3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, // JCOP4 + {"3b:d8:18:ff:81:b1:fe:45:1f:c3:80:73:c8:21:10:52:b7:7f:f8", NULL, NULL, SC_CARD_TYPE_NQ_APPLET, 0, NULL}, // JCOP4.52 + {"3b:85:80:01:80:73:C8:21:10:0e", NULL, NULL, SC_CARD_TYPE_NQ_APPLET_RFID, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; static const u8 nqapplet_aid[] = {0xd2, 0x76, 0x00, 0x01, 0x80, 0xBA, 0x01, 0x44, 0x02, 0x01, 0x00}; @@ -449,16 +450,17 @@ static int nqapplet_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return SC_ERROR_NOT_SUPPORTED; } -static int nqapplet_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +static int +nqapplet_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { int r; LOG_FUNC_CALLED(card->ctx); r = iso_operations->pin_cmd(card, data, tries_left); - if ( r == SC_ERROR_OBJECT_NOT_FOUND ) { + if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* it is possible that the NQ-Applet is not active, try to activate it */ r = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); - if ( r == SC_SUCCESS ) { + if (r == SC_SUCCESS) { r = iso_operations->pin_cmd(card, data, tries_left); } } diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index f5a178f06b..c97d7666ea 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -164,7 +164,7 @@ static int add_nqapplet_objects(sc_pkcs15_card_t *p15card) // 3.1) C.CH.Encr rv = add_nqapplet_certificate(p15card, "2", "C.CH.Encr", 0x01); - if ( rv == SC_SUCCESS ) { + if (rv == SC_SUCCESS) { // 3.2) PrK.CH.Encr rv = add_nqapplet_private_key(p15card, "2", 0x02, "PrK.CH.Encr", "1", SC_PKCS15_PRKEY_USAGE_DECRYPT); LOG_TEST_RET(card->ctx, rv, "Failed to add Encr. private key"); From fc8083444f008048be753b4d407c64a4f6ad748a Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 3 Jul 2025 23:08:32 +0300 Subject: [PATCH 3916/4321] Cleanup manifest handling Helps to integrate #3128 Signed-off-by: Raul Metsma --- .gitignore | 1 + src/libopensc/Makefile.am | 2 +- src/libopensc/Makefile.mak | 3 +- src/libopensc/opensc.dll.manifest | 15 ---------- src/minidriver/Makefile.am | 2 +- src/minidriver/Makefile.mak | 3 +- src/minidriver/opensc-minidriver.dll.manifest | 15 ---------- src/pkcs11/Makefile.am | 2 +- src/pkcs11/Makefile.mak | 6 ++-- src/pkcs11/onepin-opensc-pkcs11.dll.manifest | 15 ---------- src/pkcs11/opensc-pkcs11.dll.manifest | 15 ---------- src/smm/Makefile.am | 2 +- src/smm/Makefile.mak | 3 +- src/smm/smm-local.dll.manifest | 15 ---------- src/tests/Makefile.mak | 6 ++-- src/tests/p11test/Makefile.mak | 3 +- src/tests/unittests/Makefile.mak | 3 +- src/tools/Makefile.am | 2 +- src/tools/Makefile.mak | 30 +++++++------------ src/tools/exe.manifest | 15 ---------- win32/Make.rules.mak | 3 +- win32/Makefile.mak | 2 +- 22 files changed, 28 insertions(+), 135 deletions(-) delete mode 100644 src/libopensc/opensc.dll.manifest delete mode 100644 src/minidriver/opensc-minidriver.dll.manifest delete mode 100644 src/pkcs11/onepin-opensc-pkcs11.dll.manifest delete mode 100644 src/pkcs11/opensc-pkcs11.dll.manifest delete mode 100644 src/smm/smm-local.dll.manifest delete mode 100644 src/tools/exe.manifest diff --git a/.gitignore b/.gitignore index ff43bafd14..dee0626eb3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ test-driver *.la *.lib *.lo +*.manifest *.orig *.pdb *.rej diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 903f9fce4d..4d6a9b000a 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak opensc.dll.manifest +EXTRA_DIST = Makefile.mak lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 193f5fde19..9be75761ab 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -56,8 +56,7 @@ opensc.dll: $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type lib$*.exports >> $*.def - link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:opensc.dll $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib shlwapi.lib - if EXIST opensc.dll.manifest mt -manifest opensc.dll.manifest -outputresource:opensc.dll;2 + link $(LINKFLAGS) /dll /out:$@ /def:$*.def /implib:$*.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib shlwapi.lib opensc_a.lib: $(OBJECTS) lib $(LIBFLAGS) /out:opensc_a.lib $(OBJECTS) diff --git a/src/libopensc/opensc.dll.manifest b/src/libopensc/opensc.dll.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/libopensc/opensc.dll.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index ffd6f2194d..29d944f4d0 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc opensc-minidriver.dll.manifest +EXTRA_DIST = Makefile.mak versioninfo-minidriver.rc if ENABLE_MINIDRIVER lib_LTLIBRARIES = opensc-minidriver@LIBRARY_BITNESS@.la diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index abde6e20ea..8fa7984391 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -20,5 +20,4 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib shlwapi.lib /DELAYLOAD:bcrypt.dll - if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 + link /dll $(LINKFLAGS) /out:$@ /def:$*.def $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib shlwapi.lib /DELAYLOAD:bcrypt.dll diff --git a/src/minidriver/opensc-minidriver.dll.manifest b/src/minidriver/opensc-minidriver.dll.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/minidriver/opensc-minidriver.dll.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index df180f3577..7b6e5c6751 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc versioninfo-pkcs11-spy.rc opensc-pkcs11.pc.in opensc.module.in opensc-pkcs11.dll.manifest +EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc versioninfo-pkcs11-spy.rc opensc-pkcs11.pc.in opensc.module.in if ENABLE_SHARED lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index bbcd856c01..1be883fe90 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -25,9 +25,7 @@ all: $(TARGET1) $(TARGET3) !INCLUDE $(TOPDIR)\win32\Make.rules.mak $(TARGET1): $(OBJECTS) $(LIBS) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib - if EXIST $(TARGET1).manifest mt -manifest $(TARGET1).manifest -outputresource:$(TARGET1);2 + link /dll $(LINKFLAGS) /out:$@ /implib:$*.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib $(TARGET3): $(OBJECTS3) $(LIBS3) - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib - if EXIST $(TARGET3).manifest mt -manifest $(TARGET3).manifest -outputresource:$(TARGET3);2 + link /dll $(LINKFLAGS) /out:$@ /implib:$*.lib $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib diff --git a/src/pkcs11/onepin-opensc-pkcs11.dll.manifest b/src/pkcs11/onepin-opensc-pkcs11.dll.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/pkcs11/onepin-opensc-pkcs11.dll.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/pkcs11/opensc-pkcs11.dll.manifest b/src/pkcs11/opensc-pkcs11.dll.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/pkcs11/opensc-pkcs11.dll.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/smm/Makefile.am b/src/smm/Makefile.am index 097f045f28..873335fc65 100644 --- a/src/smm/Makefile.am +++ b/src/smm/Makefile.am @@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = Makefile.mak smm-local.dll.manifest +EXTRA_DIST = Makefile.mak AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/common -I$(top_builddir)/src/include diff --git a/src/smm/Makefile.mak b/src/smm/Makefile.mak index b8cc25319c..fb3395fa92 100644 --- a/src/smm/Makefile.mak +++ b/src/smm/Makefile.mak @@ -24,8 +24,7 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type $*.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib shlwapi.lib - if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 + link /dll $(LINKFLAGS) /out:$@ /def:$*.def $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib shlwapi.lib !ELSE $(TARGET): diff --git a/src/smm/smm-local.dll.manifest b/src/smm/smm-local.dll.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/smm/smm-local.dll.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/tests/Makefile.mak b/src/tests/Makefile.mak index 49ac651f74..5c02de90a4 100644 --- a/src/tests/Makefile.mak +++ b/src/tests/Makefile.mak @@ -14,10 +14,8 @@ $(TARGETS): $(OBJECTS) $(LIBS) opensc-minidriver-test.exe: cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj bcrypt.lib ncrypt.lib crypt32.lib winscard.lib - if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj bcrypt.lib ncrypt.lib crypt32.lib winscard.lib .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) - if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj $(OBJECTS) $(LIBS) diff --git a/src/tests/p11test/Makefile.mak b/src/tests/p11test/Makefile.mak index 197830137a..daa0de3782 100644 --- a/src/tests/p11test/Makefile.mak +++ b/src/tests/p11test/Makefile.mak @@ -22,5 +22,4 @@ $(TARGETS): $(OBJECTS) $(LIBS) .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) - if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj $(OBJECTS) $(LIBS) diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak index 5e6056238d..927aa034b4 100644 --- a/src/tests/unittests/Makefile.mak +++ b/src/tests/unittests/Makefile.mak @@ -18,5 +18,4 @@ $(TARGETS): $(OBJECTS) $(LIBS) .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) - if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj $(OBJECTS) $(LIBS) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index db3fdd6fcc..7d86493556 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -22,7 +22,7 @@ do_subst = $(SED) \ -e 's,[@]X509DIR[@],$(X509DIR),g' MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak versioninfo-tools.rc versioninfo-opensc-notify.rc goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in exe.manifest pkcs11-register.desktop.in org.opensc-project.mac.pkcs11-register.plist.in org.opensc-project.mac.opensc-notify.plist.in +EXTRA_DIST = Makefile.mak versioninfo-tools.rc versioninfo-opensc-notify.rc goid-tool.ggo.in npa-tool.ggo.in opensc-notify.ggo.in egk-tool.ggo.in opensc-asn1.ggo.in org.opensc.notify.desktop.in pkcs11-register.desktop.in org.opensc-project.mac.pkcs11-register.plist.in org.opensc-project.mac.opensc-notify.plist.in noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index f8d5032cbe..d0a2b76536 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -24,50 +24,40 @@ $(TARGETS): $(OBJECTS) $(LIBS) opensc-notify.exe: opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj opensc-notify-cmdline.obj versioninfo-opensc-notify.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib npa-tool.exe: npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj npa-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib egk-tool.exe: egk-tool-cmdline.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj egk-tool-cmdline.obj $(OBJECTS) $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj egk-tool-cmdline.obj $(OBJECTS) $(LIBS) $(ZLIB_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib goid-tool.exe: goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj goid-tool-cmdline.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib opensc-asn1.exe: opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj opensc-asn1-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib pkcs11-register.exe: pkcs11-register-cmdline.obj fread_to_eof.obj $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib pkcs15-tool.exe: pkcs15-tool.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib openpgp-tool.exe: openpgp-tool-helpers.obj $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj openpgp-tool-helpers.obj $(OBJECTS) $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj openpgp-tool-helpers.obj $(OBJECTS) $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib sc-hsm-tool.exe: sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib .c.exe: cl $(COPTS) /c $< - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 + link $(LINKFLAGS) /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib diff --git a/src/tools/exe.manifest b/src/tools/exe.manifest deleted file mode 100644 index 029b353778..0000000000 --- a/src/tools/exe.manifest +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 78dff1c06d..72c0295520 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -121,7 +121,8 @@ COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WAR /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" \ $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) \ /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) -LINKFLAGS = /nologo /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD +LINKFLAGS = /nologo /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD /MANIFEST:embed \ + "/MANIFESTDEPENDENCY:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'" LIBFLAGS = /nologo !IF "$(DEBUG_DEF)" == "/DDEBUG" diff --git a/win32/Makefile.mak b/win32/Makefile.mak index 0fe63736f3..e6472b0989 100644 --- a/win32/Makefile.mak +++ b/win32/Makefile.mak @@ -11,7 +11,7 @@ customactions.dll: versioninfo-customactions.res customactions.obj echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type customactions.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:customactions.dll versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib + link /dll $(LINKFLAGS) /out:$@ /def:$*.def versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib OpenSC.msi: OpenSC.wxs customactions.dll wix build -arch $(PLATFORM) -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -d SOURCE_DIR=$(TOPDIR) $(WIXFLAGS) OpenSC.wxs From 8d72a7602b079fd00894c7fdb72ae7452a7d7210 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 22 Jul 2025 09:41:39 +0200 Subject: [PATCH 3917/4321] dnie: fixed memory handling in case of SM error partially fixes https://github.com/OpenSC/OpenSC/issues/3390 --- src/libopensc/card-dnie.c | 25 ++++++++----------------- src/libopensc/cwa14890.c | 6 ++++-- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index d8b90e8439..5c9babf15a 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -773,8 +773,10 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card, plain->sw1 = (*sm_apdu)->sw1; plain->sw2 = (*sm_apdu)->sw2; } - free((unsigned char *) (*sm_apdu)->data); - free((*sm_apdu)->resp); + if ((*sm_apdu)->data != plain->data) + free((unsigned char *) (*sm_apdu)->data); + if ((*sm_apdu)->resp != plain->resp) + free((*sm_apdu)->resp); free(*sm_apdu); } *sm_apdu = NULL; @@ -786,7 +788,6 @@ static int dnie_sm_get_wrapped_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu **sm_apdu) { struct sc_context *ctx = card->ctx; - struct sc_apdu *apdu = NULL; cwa_provider_t *provider = NULL; int rv = SC_SUCCESS; @@ -797,28 +798,18 @@ static int dnie_sm_get_wrapped_apdu(struct sc_card *card, provider = GET_DNIE_PRIV_DATA(card)->cwa_provider; if (((plain->cla & 0x0C) == 0) && (plain->ins != 0xC0)) { - *sm_apdu = NULL; - //construct new SM apdu from original apdu - apdu = calloc(1, sizeof(struct sc_apdu)); - if (!apdu) + *sm_apdu = calloc(1, sizeof(struct sc_apdu)); + if (!(*sm_apdu)) return SC_ERROR_OUT_OF_MEMORY; - memcpy(apdu, plain, sizeof(sc_apdu_t)); - - rv = cwa_encode_apdu(card, provider, plain, apdu); + rv = cwa_encode_apdu(card, provider, plain, *sm_apdu); if (rv != SC_SUCCESS) { - dnie_sm_free_wrapped_apdu(card, NULL, &apdu); - goto err; + dnie_sm_free_wrapped_apdu(card, plain, sm_apdu); } - - *sm_apdu = apdu; } else *sm_apdu = plain; - apdu = NULL; -err: - free(apdu); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 8f1d5561bf..715b79094d 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1690,7 +1690,7 @@ int cwa_encode_apdu(sc_card_t * card, goto encode_end; } - /* rewrite resulting header */ + /* rewrite resulting APDU */ to->lc = apdulen; to->data = apdubuf; to->datalen = apdulen; @@ -1702,8 +1702,10 @@ int cwa_encode_apdu(sc_card_t * card, err: encode_end: free(apdubuf); - if (from->resp != to->resp) + if (from->resp != to->resp) { free(to->resp); + to->resp = NULL; + } encode_end_apdu_valid: sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(cctx); From 918460b805b90c76633c4d098c2d459bfde3263f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 4 Aug 2025 16:10:04 +0300 Subject: [PATCH 3918/4321] Fix signing with IDPrime 5110 FIPS+ Signed-off-by: Raul Metsma --- src/libopensc/card-idprime.c | 26 +++++++++++++++++--------- src/libopensc/cards.h | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index b00872e13f..ca9b4c0ebc 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -44,6 +44,7 @@ static struct sc_card_driver idprime_drv = { /* This ATR says, there is no EF.DIR nor EF.ATR so ISO discovery mechanisms * are not useful here */ +// clang-format off static const struct sc_atr_table idprime_atrs[] = { /* known ATRs for IDPrime 3810: * 3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00 Jakuje/xhanulik @@ -72,7 +73,7 @@ static const struct sc_atr_table idprime_atrs[] = { { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85", "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", "based Gemalto IDPrime 930 (eToken 5110+ FIPS)", - SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + SC_CARD_TYPE_IDPRIME_930_PLUS, 0, NULL }, /* known ATR for IDPrime 940: Placing in front of the 940 as its mask overlaps this one! * 3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00 msetina */ @@ -114,6 +115,7 @@ static const struct sc_atr_table idprime_atrs[] = { SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; +// clang-format on static const sc_path_t idprime_path = { "", 0, @@ -494,6 +496,9 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, case SC_CARD_TYPE_IDPRIME_930: new_object.key_reference = 0x11 + cert_id * 2; break; + case SC_CARD_TYPE_IDPRIME_930_PLUS: + new_object.key_reference = 0x10 + cert_id * 2; + break; case SC_CARD_TYPE_IDPRIME_940: { idprime_keyref_t *keyref = (idprime_keyref_t *) list_seek(&priv->keyrefmap, &cert_id); if (!keyref) { @@ -668,6 +673,7 @@ static int idprime_init(sc_card_t *card) card->name = "Gemalto IDPrime MD 830"; break; case SC_CARD_TYPE_IDPRIME_930: + case SC_CARD_TYPE_IDPRIME_930_PLUS: card->name = "Gemalto IDPrime 930/3930"; break; case SC_CARD_TYPE_IDPRIME_940: @@ -694,16 +700,15 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); - if (card->type == SC_CARD_TYPE_IDPRIME_940) { + switch (card->type) { + case SC_CARD_TYPE_IDPRIME_930_PLUS: + case SC_CARD_TYPE_IDPRIME_940: _sc_card_add_rsa_alg(card, 3072, flags, 0); - } - if (card->type == SC_CARD_TYPE_IDPRIME_930 - || card->type == SC_CARD_TYPE_IDPRIME_940) { + /* fallthrough */ + case SC_CARD_TYPE_IDPRIME_930: _sc_card_add_rsa_alg(card, 4096, flags, 0); - } - if (card->type == SC_CARD_TYPE_IDPRIME_930 || - card->type == SC_CARD_TYPE_IDPRIME_940 || - card->type == SC_CARD_TYPE_IDPRIME_840) { + /* fallthrough */ + case SC_CARD_TYPE_IDPRIME_840: /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_F_P @@ -714,6 +719,9 @@ static int idprime_init(sc_card_t *card) _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL); + break; + default: + break; } card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index a11526cdda..79bf74fce9 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -246,6 +246,7 @@ enum { SC_CARD_TYPE_IDPRIME_3810, SC_CARD_TYPE_IDPRIME_830, SC_CARD_TYPE_IDPRIME_930, + SC_CARD_TYPE_IDPRIME_930_PLUS, SC_CARD_TYPE_IDPRIME_940, SC_CARD_TYPE_IDPRIME_840, SC_CARD_TYPE_IDPRIME_GENERIC, From efbb69e1f6feeec7abea99e7f487a5dc55a407c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 16 Dec 2024 17:35:42 +0100 Subject: [PATCH 3919/4321] Implement parser for PKCS#11 URI --- src/tools/pkcs11_uri.c | 342 +++++++++++++++++++++++++++++++++++++++++ src/tools/pkcs11_uri.h | 42 +++++ 2 files changed, 384 insertions(+) create mode 100644 src/tools/pkcs11_uri.c create mode 100644 src/tools/pkcs11_uri.h diff --git a/src/tools/pkcs11_uri.c b/src/tools/pkcs11_uri.c new file mode 100644 index 0000000000..95dbf34de8 --- /dev/null +++ b/src/tools/pkcs11_uri.c @@ -0,0 +1,342 @@ +/* + * pkcs11-uri.c: PKCS#11 URI Parser + * + * Copyright (C) 2024 Veronika Hanulikova + * Original parser implementation: https://src.fedoraproject.org/rpms/openssh/blob/rawhide/f/openssh-8.0p1-pkcs11-uri.patch + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "pkcs11_uri.h" + +static struct pkcs11_uri_attr path_attr[] = { + {"id", 0}, + {"library-description", 1}, + {"library-manufacturer", 2}, + {"library-version", 3}, + {"manufacturer", 4}, + {"model", 5}, + {"object", 6}, + {"serial", 7}, + {"slot-description", 8}, + {"slot-id", 9}, + {"slot-manufacturer", 10}, + {"token", 11}, + {"type", 12}, + {NULL, 0} +}; + +static struct pkcs11_uri_attr query_attr[] = { + {"pin-source", 0}, + {"pin-value", 1}, + {"module-name", 2}, + {"module-path", 3}, + {NULL, 0} +}; + +static int +get_attr(struct pkcs11_uri_attr attr[], char *token) +{ + for (int i = 0; attr[i].name; i++) { + if (strncasecmp(token, attr[i].name, strlen(attr[i].name)) == 0 && + *(token + strlen(attr[i].name)) == '=') + return attr[i].id; + } + return -1; +} + +static int +decode_percent_string(char *data, char **out) +{ + char tmp[3]; + char *decoded, *tmp_end; + char *p = data; + long value; + size_t decoded_len = 0; + + decoded = malloc(strlen(data) + 1); + if (decoded == NULL) + return -1; + while (*p != '\0') { + switch (*p) { + case '%': + p++; + if (*p == '\0') + goto fail; + tmp[0] = *p++; + if (*p == '\0') + goto fail; + tmp[1] = *p++; + tmp[2] = '\0'; + tmp_end = NULL; + errno = 0; + value = strtol(tmp, &tmp_end, 16); + if (errno == EINVAL) + goto fail; + if (tmp_end != tmp + 2) + goto fail; + else + decoded[decoded_len++] = (char)value; + break; + default: + decoded[decoded_len++] = *p++; + break; + } + } + + /* zero terminate */ + decoded[decoded_len] = '\0'; + *out = decoded; + return decoded_len; +fail: + free(decoded); + return -1; +} + +static int +parse_string(char *argument, char **out, int *out_len, int max_len) +{ + int rv = 0, len = 0; + char *tmp = NULL; + if (*out != NULL) { + rv = 1; + fprintf(stderr, "Attribute already set\n"); + goto end; + } + len = decode_percent_string(argument, &tmp); + if (len < 0) { + rv = 1; + fprintf(stderr, "Invalid percent decode result\n"); + goto end; + } + if (max_len >= 0 && max_len < len) { + rv = 1; + free(tmp); + fprintf(stderr, "Invalid length of decoded result\n"); + goto end; + } + *out = tmp; + if (out_len != NULL) { + *out_len = len; + } +end: + return rv; +} + +struct pkcs11_uri * +pkcs11_uri_new() +{ + struct pkcs11_uri *uri = calloc(1, sizeof(struct pkcs11_uri)); + return uri; +} + +int +parse_pkcs11_uri(const char *input_string, struct pkcs11_uri *result) +{ + size_t length = 0; + char *uri; + char *path, *query, *token; + int rv = 0; + + if (!input_string || !result) { + return 1; + } + + /* Check PKCS#11 URI scheme */ + length = strlen(PKCS11_URI_SCHEME); + if (strlen(input_string) < length || strncmp(input_string, PKCS11_URI_SCHEME, length) != 0) { + return 1; + } + + /* Divide path and query part*/ + if ((uri = strdup(input_string)) == NULL) { + rv = 1; + fprintf(stderr, "Error when allocating memory\n"); + goto end; + } + path = uri; + path = strtok(path, "?"); + query = strtok(NULL, "?"); + if (path == NULL) { + rv = 1; + goto end; + } + /* Skip PKCS#11 URI scheme*/ + path = path + length; + + /* parse path */ + token = strtok(path, ";"); + while (token != NULL) { + char *argument = NULL, **result_ptr = NULL; + int *result_len = NULL; + int max_len = -1; + int id = get_attr(path_attr, token); + if (id == -1) { + rv = 1; + fprintf(stderr, "Invalid PKCS#11 token\n"); + goto end; + } + argument = token + strlen(path_attr[id].name) + 1; + + switch (id) { + case 0: /* CKA_ID */ + result_ptr = &result->id; + result_len = &result->id_len; + break; + case 1: /* CK_INFO -> libraryDescription */ + rv = 1; + fprintf(stderr, "PKCS#11 library description not supported\n"); + goto end; + break; + case 2: /* CK_INFO -> manufacturerID */ + rv = 1; + fprintf(stderr, "PKCS#11 manufacturer ID not supported\n"); + goto end; + break; + case 3: /* CK_INFO -> libraryVersion*/ + rv = 1; + fprintf(stderr, "PKCS#11 library version not supported\n"); + goto end; + break; + case 4: /* CK_TOKEN_INFO -> manufacturerID */ + result_ptr = &result->token_manufacturer; + max_len = 32; + break; + case 5: /* CK_TOKEN_INFO -> model */ + result_ptr = &result->token_model; + max_len = 16; + break; + case 6: /* CKA_LABEL */ + result_ptr = &result->object; + break; + case 7: /* CK_TOKEN_INFO -> serialNumber */ + result_ptr = &result->serial; + max_len = 16; + break; + case 8: /* CK_SLOT_INFO -> slotDescription */ + result_ptr = &result->slot_description; + break; + case 9: /* CK_SLOT_ID */ + result_ptr = &result->slot_id; + break; + case 10: /* CK_SLOT_INFO -> manufacturerID */ + result_ptr = &result->slot_manufacturer; + break; + case 11: /* CK_TOKEN_INFO -> label */ + result_ptr = &result->token_label; + max_len = 32; + break; + case 12: /* CKA_CLASS */ + result_ptr = &result->type; + break; + } + if (parse_string(argument, result_ptr, result_len, max_len) != 0) { + rv = 1; + goto end; + } + token = strtok(NULL, ";"); + } + + /* parse query */ + if (query == NULL) { + goto end; + } + token = strtok(query, ";"); + while (token != NULL) { + char *argument = NULL, **result_ptr = NULL; + int id = get_attr(query_attr, token); + if (id == -1) { + rv = 1; + fprintf(stderr, "Invalid PKCS#11 URI query\n"); + goto end; + } + argument = token + strlen(query_attr[id].name) + 1; + + switch (id) { + case 0: + if (result->pin != NULL) { + rv = 1; + fprintf(stderr, "A pin and pin-source cannot be specified together in PKCS#11 URI\n"); + goto end; + } + result_ptr = &result->pin_source; + break; + case 1: + if (result->pin_source != NULL) { + rv = 1; + fprintf(stderr, "A pin and pin-source cannot be specified together in PKCS#11 URI\n"); + goto end; + } + result_ptr = &result->pin; + break; + case 2: + rv = 1; + fprintf(stderr, "PKCS#11 module name for query not supported\n"); + goto end; + break; + case 3: + result_ptr = &result->module_path; + break; + } + if (parse_string(argument, result_ptr, NULL, -1) != 0) { + rv = 1; + goto end; + } + token = strtok(NULL, ";"); + } + +end: + free(uri); + return rv; +} + +void +pkcs11_uri_free(struct pkcs11_uri *uri) +{ + if (uri == NULL) { + return; + } + + free(uri->id); + free(uri->library_description); + free(uri->library_manufacturer); + free(uri->library_version); + free(uri->token_manufacturer); + free(uri->token_model); + free(uri->object); + free(uri->serial); + free(uri->slot_description); + free(uri->slot_id); + free(uri->slot_manufacturer); + free(uri->token_label); + free(uri->type); + free(uri->pin_source); + if (uri->pin) { + memset(uri->pin, 0, strlen(uri->pin)); + free(uri->pin); + } + free(uri->module_name); + free(uri->module_path); + free(uri); +} diff --git a/src/tools/pkcs11_uri.h b/src/tools/pkcs11_uri.h new file mode 100644 index 0000000000..158c2eb628 --- /dev/null +++ b/src/tools/pkcs11_uri.h @@ -0,0 +1,42 @@ +#ifndef PKCS11_URI_H +#define PKCS11_URI_H + +#include +#include +#include + +#define PKCS11_URI_SCHEME "pkcs11:" + +struct pkcs11_uri { + /* taken from https://www.rfc-editor.org/rfc/rfc7512.html mapping of the PKCS #11 URI path component attributes */ + char *id; + int id_len; + char *library_description; + char *library_manufacturer; + char *library_version; + char *token_manufacturer; + char *token_model; + char *object; + char *serial; + char *slot_description; + char *slot_id; + char *slot_manufacturer; + char *token_label; + char *type; + /* query */ + char *pin_source; + char *pin; + char *module_name; + char *module_path; +}; + +struct pkcs11_uri_attr { + char *name; + int id; +}; + +struct pkcs11_uri *pkcs11_uri_new(); +int parse_pkcs11_uri(const char *input_string, struct pkcs11_uri *result); +void pkcs11_uri_free(struct pkcs11_uri *uri); + +#endif // PKCS11_URI_H From ce3add8c965bb4cc8b3423b21af3eb61f8c31760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 16 Dec 2024 17:36:27 +0100 Subject: [PATCH 3920/4321] Add option for file path into 'util_get_pin' --- src/tools/util.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tools/util.c b/src/tools/util.c index 50fbcbacc7..b173d7ab4b 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -498,13 +498,20 @@ util_getpass (char **lineptr, size_t *len, FILE *stream) size_t util_get_pin(const char *input, const char **pin) { - size_t inputlen = strlen(input); + size_t inputlen; size_t pinlen = 0; - if(inputlen > 4 && strncasecmp(input, "env:", 4) == 0) { + if (!input || !pin) { + return 0; + } + inputlen = strlen(input); + + if (inputlen > 4 && strncasecmp(input, "env:", 4) == 0) { // Get a PIN from a environment variable *pin = getenv(input + 4); pinlen = *pin ? strlen(*pin) : 0; + } else if (inputlen > 5 && strncasecmp(input, "file:", 5) == 0) { + fprintf(stderr, "Reading PIN from file not supported!\n"); } else { //Just use the input *pin = input; From ce33923951d9c38469b4fd041695296f1cd3dbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 16 Dec 2024 17:37:14 +0100 Subject: [PATCH 3921/4321] Integrate PKCS#11 URI option into pkcs11-tool --- src/tools/Makefile.am | 4 +- src/tools/Makefile.mak | 5 + src/tools/pkcs11-tool.c | 339 ++++++++++++++++++++++++++++++++++------ 3 files changed, 296 insertions(+), 52 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 7d86493556..b175c95aa9 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -27,7 +27,7 @@ EXTRA_DIST = Makefile.mak versioninfo-tools.rc versioninfo-opensc-notify.rc goid noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h \ - openpgp-tool-helpers.h + openpgp-tool-helpers.h pkcs11_uri.h bin_PROGRAMS = opensc-tool opensc-explorer opensc-asn1 \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ cardos-tool eidenv openpgp-tool iasecc-tool egk-tool goid-tool \ @@ -67,7 +67,7 @@ opensc_explorer_SOURCES = opensc-explorer.c util.c opensc_explorer_LDADD = $(OPTIONAL_READLINE_LIBS) pkcs15_tool_SOURCES = pkcs15-tool.c util.c ../pkcs11/pkcs11-display.c ../pkcs11/pkcs11-display.h pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) -pkcs11_tool_SOURCES = pkcs11-tool.c util.c +pkcs11_tool_SOURCES = pkcs11-tool.c util.c pkcs11_uri.c pkcs11_tool_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) pkcs11_tool_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index d0a2b76536..c475e6f332 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -58,6 +58,11 @@ sc-hsm-tool.exe: sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c link $(LINKFLAGS) /out:$@ $*.obj sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib +pkcs11-tool.exe: pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) + cl $(COPTS) /c $*.c + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib + mt -manifest exe.manifest -outputresource:$@;1 + .c.exe: cl $(COPTS) /c $< link $(LINKFLAGS) /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f3287059c5..caa84cc27f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -73,6 +73,7 @@ #include "pkcs11/pkcs11-opensc.h" #include "pkcs11/pkcs11.h" #include "util.h" +#include "pkcs11_uri.h" /* pkcs11-tool uses libopensc routines that do not use an sc_context * but does use some OpenSSL routines @@ -237,7 +238,8 @@ enum { OPT_TAG_BITS, OPT_SALT_FILE, OPT_INFO_FILE, - OPT_PUBLIC_KEY_INFO + OPT_PUBLIC_KEY_INFO, + OPT_URI }; // clang-format off @@ -331,7 +333,7 @@ static const struct option options[] = { { "salt-file", 1, NULL, OPT_SALT_FILE}, { "info-file", 1, NULL, OPT_INFO_FILE}, { "public-key-info", 0, NULL, OPT_PUBLIC_KEY_INFO}, - + { "uri", 1, NULL, OPT_URI}, { NULL, 0, NULL, 0 } }; // clang-format on @@ -426,6 +428,7 @@ static const char *option_help[] = { "Specify the file containing the salt for HKDF (optional)", "Specify the file containing the info for HKDF (optional)", "When reading a public key, try to read PUBLIC_KEY_INFO (DER encoding of SPKI)", + "Specify the PKCS#11 URI for module, slot, token or object" }; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -434,7 +437,7 @@ static int verbose = 0; static const char * opt_input = NULL; static const char * opt_output = NULL; static const char * opt_signature_file = NULL; -static const char * opt_module = DEFAULT_PKCS11_PROVIDER; +static const char * opt_module = NULL; static int opt_slot_set = 0; static CK_SLOT_ID opt_slot = 0; static const char * opt_slot_description = NULL; @@ -491,6 +494,7 @@ static unsigned long opt_tag_bits = 0; static const char *opt_salt_file = NULL; static const char *opt_info_file = NULL; static int opt_public_key_info = 0; /* return pubkey as SPKI DER */ +static struct pkcs11_uri *opt_uri = NULL; static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -613,18 +617,24 @@ static CK_RV write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); static int delete_object(CK_SESSION_HANDLE session); static void set_id_attr(CK_SESSION_HANDLE session); -static int find_object_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, +static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, + CK_OBJECT_CLASS cls, int cls_set, CK_OBJECT_HANDLE_PTR ret, const unsigned char *, size_t id_len, - const char *, - int obj_index); + const char *, int obj_index); static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); static int find_object_flags(CK_SESSION_HANDLE, uint16_t flags, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); +static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, + uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, + CK_OBJECT_CLASS cls, int cls_set, + const unsigned char *id, size_t id_len, const char *label, int obj_index); static CK_ULONG find_mechanism(CK_SLOT_ID, CK_FLAGS, CK_MECHANISM_TYPE_PTR, size_t, CK_MECHANISM_TYPE_PTR); +static int get_default_slot(CK_SLOT_ID_PTR result); +static int find_slot_by_uri(struct pkcs11_uri *uri, CK_SLOT_ID_PTR result); static int find_slot_by_description(const char *, CK_SLOT_ID_PTR); static int find_slot_by_token_label(const char *, CK_SLOT_ID_PTR); static void get_token_info(CK_SLOT_ID, CK_TOKEN_INFO_PTR); @@ -635,6 +645,7 @@ static void p11_warn(const char *, CK_RV); static const char * p11_slot_info_flags(CK_FLAGS); static const char * p11_token_info_flags(CK_FLAGS); static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t); +static char * p11_utf8_to_string(CK_UTF8CHAR *, size_t); static const char * p11_flag_names(struct flag_info *, CK_FLAGS); static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE); static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); @@ -1143,6 +1154,16 @@ int main(int argc, char * argv[]) util_fatal("--tag-bits-len option needs a decimal value argument"); } break; + case OPT_URI: + if (optarg == NULL) { + util_fatal("--uri option needs an argument"); + } + opt_uri = pkcs11_uri_new(); + if (parse_pkcs11_uri(optarg, opt_uri) != 0) { + pkcs11_uri_free(opt_uri); + util_fatal("--uri option argument invalid"); + } + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -1237,6 +1258,53 @@ int main(int argc, char * argv[]) if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); + if (opt_uri) { + /* Check that no interfering options were set */ + if (opt_module || opt_slot_set || opt_slot_index_set || opt_slot_description || + opt_pin || opt_object_label || opt_object_class_str || opt_object_id_len) { + fprintf(stderr, "Invalid combination of arguments when --uri used\n"); + util_print_usage_and_die(app_name, options, option_help, NULL); + } + if (opt_uri->slot_id) { + opt_slot = (CK_SLOT_ID)strtoul(opt_uri->slot_id, NULL, 0); + opt_slot_set = 1; + } + opt_module = opt_uri->module_path; + util_get_pin(opt_uri->pin, &opt_pin); + util_get_pin(opt_uri->pin_source, &opt_pin); + if (opt_pin) + opt_login = 1; + opt_object_label = opt_uri->object; + if (opt_uri->type) { + if (strcmp(opt_uri->type, "cert") == 0) { + opt_object_class = CKO_CERTIFICATE; + opt_object_class_str = "cert"; + } else if (strcmp(opt_uri->type, "private") == 0) { + opt_object_class = CKO_PRIVATE_KEY; + opt_object_class_str = "privkey"; + } else if (strcmp(opt_uri->type, "secret-key") == 0) { + opt_object_class = CKO_SECRET_KEY; + opt_object_class_str = "secrkey"; + } else if (strcmp(opt_uri->type, "public") == 0) { + opt_object_class = CKO_PUBLIC_KEY; + opt_object_class_str = "pubkey,"; + } else if (strcmp(opt_uri->type, "data") == 0) { + opt_object_class = CKO_DATA; + opt_object_class_str = "data"; + } else { + fprintf(stderr, "Unsupported object type \"%s\" specified in PKCS#11 URI\n", opt_uri->type); + util_print_usage_and_die(app_name, options, option_help, NULL); + } + } + if (opt_uri->id) { + opt_object_id_len = opt_uri->id_len; + memcpy(opt_object_id, opt_uri->id, opt_object_id_len); + } + } + + if (!opt_module) { + opt_module = DEFAULT_PKCS11_PROVIDER; + } #ifdef _WIN32 expanded_len = PATH_MAX; expanded_len = ExpandEnvironmentStringsA(opt_module, expanded_val, expanded_len); @@ -1297,7 +1365,23 @@ int main(int argc, char * argv[]) goto end; } - if (!opt_slot_set && (action_count > do_list_slots)) { + if (opt_uri && !opt_slot_set && (action_count > do_list_slots)) { + if (opt_uri->token_manufacturer || opt_uri->token_model || opt_uri->serial || + opt_uri->slot_description || opt_uri->slot_manufacturer || opt_uri->token_label) { + if (!find_slot_by_uri(opt_uri, &opt_slot)) { + fprintf(stderr, "No slot matching URI found\n"); + err = 1; + goto end; + } + if (verbose) + fprintf(stderr, "Using slot matched by URI(0x%lx)\n", opt_slot); + } else { + if (!get_default_slot(&opt_slot)) { + err = 1; + goto end; + } + } + } else if (!opt_slot_set && (action_count > do_list_slots)) { if (opt_slot_description) { if (!find_slot_by_description(opt_slot_description, &opt_slot)) { fprintf(stderr, "No slot named \"%s\" found\n", opt_slot_description); @@ -1325,26 +1409,10 @@ int main(int argc, char * argv[]) goto end; } } else { - /* use first slot with token present (or default slot on error) */ - unsigned int i, found = 0; - for (i = 0; i < p11_num_slots; i++) { - CK_SLOT_INFO info; - rv = p11->C_GetSlotInfo(p11_slots[i], &info); - if (rv != CKR_OK) - p11_fatal("C_GetSlotInfo", rv); - if (info.flags & CKF_TOKEN_PRESENT) { - opt_slot = p11_slots[i]; - fprintf(stderr, "Using slot %u with a present token (0x%lx)\n", i, opt_slot); - found = 1; - break; - } - } - if (!found) { - fprintf(stderr, "No slot with a token was found.\n"); + if (!get_default_slot(&opt_slot)) { err = 1; goto end; } - } } @@ -1414,7 +1482,6 @@ int main(int argc, char * argv[]) } if (do_sign || do_derive) { - /* * Newer mechanisms have their details in the mechanism table, however * if it's not known fall back to the old code always assuming it was a @@ -1422,14 +1489,30 @@ int main(int argc, char * argv[]) */ if (mf_flags != MF_UNKNOWN) { /* this function dies on error via util_fatal */ - find_object_flags(session, mf_flags, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + if (opt_uri) { + find_object_flags_and_type_or_id_or_label(session, mf_flags, &object, + opt_object_class, opt_uri->type == NULL ? 0 : 1, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0); + } else { + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } + } else if (opt_uri && opt_uri->type) { + /* If type in PKCS#11 URI is set, check the type and use it */ + if (opt_object_class != CKO_PRIVATE_KEY && opt_object_class != CKO_SECRET_KEY) { + util_fatal("Incorrect type of key"); + } + if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + util_fatal("Private/secret key not found"); + } } else if (!find_object(session, CKO_PRIVATE_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) { if (!find_object(session, CKO_SECRET_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) util_fatal("Private/secret key not found"); + } } if (do_decrypt) { @@ -1440,10 +1523,25 @@ int main(int argc, char * argv[]) */ if (mf_flags != MF_UNKNOWN) { /* this function dies on error via util_fatal */ - find_object_flags(session, mf_flags, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); - } else if (!find_object(session, CKO_PRIVATE_KEY, &object, + if (opt_uri) { + find_object_flags_and_type_or_id_or_label(session, mf_flags, &object, + opt_object_class, opt_uri->type == NULL ? 0 : 1, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0); + } else { + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } + } else if (opt_uri && opt_uri->type) { + /* If type in PKCS#11 URI is set, check the type and use it */ + if (opt_object_class != CKO_PRIVATE_KEY && opt_object_class != CKO_SECRET_KEY) { + util_fatal("Incorrect type of key"); + } + if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + util_fatal("Private/secret key not found"); + } + } else if (!find_object(session, CKO_PRIVATE_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) if (!find_object(session, CKO_SECRET_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) @@ -1456,11 +1554,27 @@ int main(int argc, char * argv[]) * if it's not known fall back to the old code always assuming it was a * CKO_PUBLIC_KEY then a CKO_CERTIFICATE. */ + if (mf_flags != MF_UNKNOWN) { /* this function dies on error via util_fatal */ - find_object_flags(session, mf_flags, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + if (opt_uri) { + find_object_flags_and_type_or_id_or_label(session, mf_flags, &object, + opt_object_class, opt_uri->type == NULL ? 0 : 1, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0); + } else { + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } + } else if (opt_uri && opt_uri->type) { + /* If type in PKCS#11 URI is set, check the type and use it */ + if (opt_object_class != CKO_PUBLIC_KEY && opt_object_class != CKO_SECRET_KEY) { + util_fatal("Incorrect type of key"); + } + if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + util_fatal("Public/Secret key not found"); + } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) if (!find_object(session, CKO_SECRET_KEY, &object, @@ -1474,11 +1588,27 @@ int main(int argc, char * argv[]) * if it's not known fall back to the old code always assuming it was a * CKO_PUBLIC_KEY then a CKO_CERTIFICATE. */ + if (mf_flags != MF_UNKNOWN) { /* this function dies on error via util_fatal */ - find_object_flags(session, mf_flags, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + if (opt_uri) { + find_object_flags_and_type_or_id_or_label(session, mf_flags, &object, + opt_object_class, opt_uri->type == NULL ? 0 : 1, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0); + } else { + find_object_flags(session, mf_flags, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0); + } + } else if (opt_uri && opt_uri->type) { + /* If type in PKCS#11 URI is set, check the type and use it */ + if (opt_object_class != CKO_PUBLIC_KEY && opt_object_class != CKO_CERTIFICATE) { + util_fatal("Incorrect type of key"); + } + if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + util_fatal("Public key nor certificate not found"); + } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0) && @@ -1589,6 +1719,7 @@ int main(int argc, char * argv[]) if (rv != CKR_OK) p11_fatal("C_CloseSession", rv); } + pkcs11_uri_free(opt_uri); #if defined(_WIN32) || defined(HAVE_PTHREAD) if (do_test_threads) { @@ -1608,7 +1739,6 @@ int main(int argc, char * argv[]) return err; } - static void show_cryptoki_info(void) { CK_INFO info; @@ -5084,7 +5214,7 @@ static void set_id_attr(CK_SESSION_HANDLE session) CK_ATTRIBUTE templ[] = {{CKA_ID, new_object_id, new_object_id_len}}; CK_RV rv; - if (!find_object_id_or_label(session, opt_object_class, &obj, opt_object_id, opt_object_id_len, opt_object_label, 0)) { + if (!find_object_type_or_id_or_label(session, opt_object_class, 1, &obj, opt_object_id, opt_object_id_len, opt_object_label, 0)) { fprintf(stderr, "set_id(): couldn't find the object by id %s label\n", (opt_object_label && opt_object_id_len) ? "and" : "or"); return; } @@ -5097,6 +5227,70 @@ static void set_id_attr(CK_SESSION_HANDLE session) show_object(session, obj); } +static int get_default_slot(CK_SLOT_ID_PTR result) +{ + /* use first slot with token present (or default slot on error) */ + CK_RV rv; + for (unsigned int i = 0; i < p11_num_slots; i++) { + CK_SLOT_INFO info; + rv = p11->C_GetSlotInfo(p11_slots[i], &info); + if (rv != CKR_OK) + p11_fatal("C_GetSlotInfo", rv); + if (info.flags & CKF_TOKEN_PRESENT) { + *result = p11_slots[i]; + fprintf(stderr, "Using slot %u with a present token (0x%lx)\n", i, *result); + return 1; + } + } + fprintf(stderr, "No slot with a token was found.\n"); + return 0; +} + +static int find_slot_by_uri(struct pkcs11_uri *uri, CK_SLOT_ID_PTR result) +{ + CK_SLOT_INFO slot_info; + CK_TOKEN_INFO token_info; + struct attr { + char *uri_attr; + char *actual_attr; + } attr_array[6]; + + for (CK_ULONG n = 0; n < p11_num_slots; n++) { + int invalid = 0; + + if (p11->C_GetSlotInfo(p11_slots[n], &slot_info) != CKR_OK || + p11->C_GetTokenInfo(p11_slots[n], &token_info) != CKR_OK) { + continue; + } + + attr_array[0] = (struct attr){uri->slot_description, p11_utf8_to_string(slot_info.slotDescription, sizeof(slot_info.slotDescription))}; + attr_array[1] = (struct attr){uri->slot_manufacturer, p11_utf8_to_string(slot_info.manufacturerID, sizeof(slot_info.manufacturerID))}; + attr_array[2] = (struct attr){uri->token_manufacturer, p11_utf8_to_string(token_info.manufacturerID, sizeof(token_info.manufacturerID))}; + attr_array[3] = (struct attr){uri->token_model, p11_utf8_to_string(token_info.model, sizeof(token_info.model))}; + attr_array[4] = (struct attr){uri->serial, p11_utf8_to_string(token_info.serialNumber, sizeof(token_info.serialNumber))}; + attr_array[5] = (struct attr){uri->token_label, p11_utf8_to_string(token_info.label, sizeof(token_info.label))}; + + for (int i = 0; i < 6; i++) { + if (!attr_array[i].uri_attr || !attr_array[i].actual_attr) + continue; + if (strlen(attr_array[i].uri_attr) != strlen(attr_array[i].actual_attr) || + strncmp(attr_array[i].actual_attr, attr_array[i].uri_attr, strlen(attr_array[i].actual_attr))) { + invalid = 1; + break; + } + } + if (invalid) + continue; + + for (int i = 0; i < 6; i++) { + free(attr_array[i].actual_attr); + } + *result = p11_slots[n]; + return 1; + } + return 0; +} + static int find_slot_by_description(const char *label, CK_SLOT_ID_PTR result) { CK_SLOT_INFO info; @@ -5147,8 +5341,8 @@ static int find_slot_by_token_label(const char *label, CK_SLOT_ID_PTR result) return 0; } - -static int find_object_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, +static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, + CK_OBJECT_CLASS cls, int cls_set, CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len, const char *label, @@ -5160,10 +5354,12 @@ static int find_object_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, CK_RV rv; int i; - attrs[0].type = CKA_CLASS; - attrs[0].pValue = &cls; - attrs[0].ulValueLen = sizeof(cls); - nattrs++; + if (cls_set) { + attrs[nattrs].type = CKA_CLASS; + attrs[nattrs].pValue = &cls; + attrs[nattrs].ulValueLen = sizeof(cls); + nattrs++; + } if (id && id_len) { attrs[nattrs].type = CKA_ID; attrs[nattrs].pValue = (void *) id; @@ -5204,7 +5400,7 @@ static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len, int obj_index) { - return find_object_id_or_label(sess, cls, ret, id, id_len, NULL, obj_index); + return find_object_type_or_id_or_label(sess, cls, 1, ret, id, id_len, NULL, obj_index); } static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, @@ -5212,14 +5408,35 @@ static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, const unsigned char *id, size_t id_len, int obj_index) { int count; - char err_key_types[1024] = { 0 }; + char err_key_types[1024] = {0}; if (mf_flags & MF_CKO_SECRET_KEY) { count = find_object(sess, CKO_SECRET_KEY, ret, id, id_len, obj_index); if (count) return count; - strncat(err_key_types, "Secret", sizeof(err_key_types)-1); + strncat(err_key_types, "Secret", sizeof(err_key_types) - 1); + } + + util_fatal("Could not find key of type: %s", err_key_types); +} + +static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, + uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, + CK_OBJECT_CLASS cls, int cls_set, + const unsigned char *id, size_t id_len, const char *label, int obj_index) +{ + int count; + char err_key_types[1024] = {0}; + + if (mf_flags & MF_CKO_SECRET_KEY) { + if (!cls_set || (cls_set && cls == CKO_SECRET_KEY)) { + count = find_object_type_or_id_or_label(sess, cls, cls_set, ret, id, id_len, label, obj_index); + if (count) + return count; + } + + strncat(err_key_types, "Secret", sizeof(err_key_types) - 1); } util_fatal("Could not find key of type: %s", err_key_types); @@ -9061,6 +9278,28 @@ static const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len) return buffer; } +static char *p11_utf8_to_string(CK_UTF8CHAR *string, size_t len) +{ + char *buffer = NULL; + size_t n, m; + + while (len && string[len - 1] == ' ') + len--; + + if (len < 1 || !(buffer = calloc(len, sizeof(char)))) { + return NULL; + } + + /* For now, simply copy this thing */ + for (n = m = 0; n < len; n++) { + if (m >= len) + break; + buffer[n] = string[m++]; + } + buffer[n] = '\0'; + return buffer; +} + static CK_BBOOL p11_is_percent_format_reserved_char(CK_UTF8CHAR c) { From 16553b0273d198b3d443f90be70c9e322b14ef00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 16 Dec 2024 17:37:56 +0100 Subject: [PATCH 3922/4321] Implement unit tests for PKCS#11 URI parser --- src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/Makefile.mak | 3 +- src/tests/unittests/parse_pkcs11_uri.c | 277 +++++++++++++++++++++++++ 3 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 src/tests/unittests/parse_pkcs11_uri.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 7f861f0e8d..aa69a567bf 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -16,10 +16,10 @@ endif noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \ decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding \ - base64 + base64 parse_pkcs11_uri TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \ decode_ecdsa_signature check_macro_reference_loop strip_pkcs1_2_padding \ - base64 + base64 parse_pkcs11_uri noinst_HEADERS = torture.h @@ -44,6 +44,7 @@ decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c check_macro_reference_loop_SOURCES = check_macro_reference_loop.c strip_pkcs1_2_padding_SOURCES = strip_pkcs1_2_padding.c base64_SOURCES = base64.c +parse_pkcs11_uri_SOURCES = parse_pkcs11_uri.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak index 927aa034b4..998a55bc33 100644 --- a/src/tests/unittests/Makefile.mak +++ b/src/tests/unittests/Makefile.mak @@ -1,13 +1,14 @@ TOPDIR = ..\..\.. TARGETS = asn1 compression pkcs15filter check_macro_reference_loop \ - strip_pkcs1_2_padding base64 + strip_pkcs1_2_padding base64 parse_pkcs11_uri OBJECTS = asn1.obj \ compression.obj \ pkcs15-emulator-filter.obj \ check_macro_reference_loop.obj \ strip_pkcs1_2_padding.obj \ + parse_pkcs11_uri.obj \ $(TOPDIR)\win32\versioninfo.res all: $(TARGETS) diff --git a/src/tests/unittests/parse_pkcs11_uri.c b/src/tests/unittests/parse_pkcs11_uri.c new file mode 100644 index 0000000000..e50b1c3e9e --- /dev/null +++ b/src/tests/unittests/parse_pkcs11_uri.c @@ -0,0 +1,277 @@ +/* + * parse_pkcs11_uri.c: Unit tests for PKCS#11 URI parser + * + * Copyright (C) 2024 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "tools/pkcs11_uri.c" +#include "torture.h" +#include + +static void +torture_id_non_percent(void **state) +{ + char *uri = "pkcs11:id=123456;"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("123456", result->id); + assert_int_equal(strlen("123456"), result->id_len); + pkcs11_uri_free(result); +} + +static void +torture_id_percent(void **state) +{ + char *uri = "pkcs11:id=%30%31%32"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("012", result->id); + assert_int_equal(3, result->id_len); + pkcs11_uri_free(result); +} + +static void +torture_id_percent_incorrect(void **state) +{ + char *uri = "pkcs11:id=%30%31%3"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 1); + assert_ptr_equal(NULL, result->id); + assert_int_equal(0, result->id_len); + pkcs11_uri_free(result); +} + +static void +torture_manufacturer(void **state) +{ + char *uri = "pkcs11:manufacturer=Snake%20Oil,%20Inc."; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("Snake Oil, Inc.", result->token_manufacturer); + pkcs11_uri_free(result); +} + +static void +torture_object(void **state) +{ + char *uri = "pkcs11:object=my-certificate;"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("my-certificate", result->object); + pkcs11_uri_free(result); +} + +static void +torture_empty_serial(void **state) +{ + char *uri = "pkcs11:serial=;"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("", result->serial); + pkcs11_uri_free(result); +} + +static void +torture_serial(void **state) +{ + char *uri = "pkcs11:serial=123456;"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("123456", result->serial); + pkcs11_uri_free(result); +} + +static void +torture_invalid_token(void **state) +{ + char *uri = "pkcs11:invalid=123456"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 1); + pkcs11_uri_free(result); +} + +static void +torture_half_invalid_token(void **state) +{ + char *uri = "pkcs11:serial-number=123456;"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 1); + pkcs11_uri_free(result); +} + +static void +torture_spec_only_scheme(void **state) +{ + char *uri = "pkcs11:"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + pkcs11_uri_free(result); +} + +static void +torture_spec_object_label(void **state) +{ + char *uri = "pkcs11:object=my-pubkey;type=public"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("my-pubkey", result->object); + assert_string_equal("public", result->type); + pkcs11_uri_free(result); +} + +static void +torture_spec_type_pin(void **state) +{ + char *uri = "pkcs11:object=my-key;type=private?pin-source=file:/etc/token"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("my-key", result->object); + assert_string_equal("private", result->type); + assert_string_equal("file:/etc/token", result->pin_source); + pkcs11_uri_free(result); +} + +static void +torture_spec_token_object_serial_pin(void **state) +{ + char *uri = "pkcs11:token=The%20Software%20PKCS%2311%20Softtoken;" + "manufacturer=Snake%20Oil,%20Inc.;" + "model=1.0;" + "object=my-certificate;" + "type=cert;" + "id=%69%95%3E%5C%F4%BD%EC%91;" + "serial=" + "?pin-source=file:/etc/token_pin"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("The Software PKCS#11 Softtoken", result->token_label); + assert_string_equal("Snake Oil, Inc.", result->token_manufacturer); + assert_string_equal("my-certificate", result->object); + assert_string_equal("cert", result->type); + assert_string_equal("\x69\x95\x3E\x5C\xF4\xBD\xEC\x91", result->id); + assert_int_equal(8, result->id_len); + assert_string_equal("", result->serial); + assert_string_equal("file:/etc/token_pin", result->pin_source); + pkcs11_uri_free(result); +} + +static void +torture_spec_unsupported_module_name(void **state) +{ + char *uri = "pkcs11:object=my-sign-key;" + "type=private" + "?module-name=mypkcs11"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 1); + pkcs11_uri_free(result); +} + +static void +torture_module_path(void **state) +{ + char *uri = "pkcs11:object=my-sign-key;" + "type=private" + "?module-path=/mnt/libmypkcs11.so.1"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("my-sign-key", result->object); + assert_string_equal("private", result->type); + assert_string_equal("/mnt/libmypkcs11.so.1", result->module_path); + pkcs11_uri_free(result); +} + +static void +torture_pin_value(void **state) +{ + char *uri = "pkcs11:token=Software%20PKCS%2311%20softtoken;" + "manufacturer=Snake%20Oil,%20Inc." + "?pin-value=the-pin"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("Software PKCS#11 softtoken", result->token_label); + assert_string_equal("Snake Oil, Inc.", result->token_manufacturer); + assert_string_equal("the-pin", result->pin); + pkcs11_uri_free(result); +} + +static void +torture_encoded_semicolon(void **state) +{ + char *uri = "pkcs11:token=A%20name%20with%20a%20substring%20%25%3B;" + "object=my-certificate;" + "type=cert"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 0); + assert_string_equal("A name with a substring %;", result->token_label); + assert_string_equal("my-certificate", result->object); + assert_string_equal("cert", result->type); + pkcs11_uri_free(result); +} + +static void +torture_pin_pin_source(void **state) +{ + char *uri = "pkcs11:?pin-value=the-pin;pin-source=file:/path/to/pin"; + struct pkcs11_uri *result = pkcs11_uri_new(); + int rv = parse_pkcs11_uri(uri, result); + assert_int_equal(rv, 1); + pkcs11_uri_free(result); +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_id_non_percent), + cmocka_unit_test(torture_id_percent), + cmocka_unit_test(torture_id_percent_incorrect), + cmocka_unit_test(torture_manufacturer), + cmocka_unit_test(torture_invalid_token), + cmocka_unit_test(torture_half_invalid_token), + cmocka_unit_test(torture_object), + cmocka_unit_test(torture_empty_serial), + cmocka_unit_test(torture_serial), + cmocka_unit_test(torture_spec_only_scheme), + cmocka_unit_test(torture_spec_object_label), + cmocka_unit_test(torture_spec_type_pin), + cmocka_unit_test(torture_spec_token_object_serial_pin), + cmocka_unit_test(torture_spec_unsupported_module_name), + cmocka_unit_test(torture_module_path), + cmocka_unit_test(torture_pin_value), + cmocka_unit_test(torture_encoded_semicolon), + cmocka_unit_test(torture_pin_pin_source) + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} From a55c1748fde23db869c37bb6f88dadd151a46db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 16 Dec 2024 17:38:43 +0100 Subject: [PATCH 3923/4321] Add documentation for PKCS#11 URI option in pkcs11-tool --- doc/tools/pkcs11-tool.1.xml | 7 +++++++ doc/tools/tools.html | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 3c1ca4c08c..3998363945 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -751,6 +751,13 @@ Specify the file containing the info for HKDF (optional) + + + value + + Specify the PKCS#11 URI for module, slot, token or object + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index bf20ebce2f..1428223efb 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1735,7 +1735,9 @@ --salt-file filename

    Specify the file containing the salt for HKDF (optional)

    --info-file filename -

    Specify the file containing the info for HKDF (optional)

    +

    Specify the file containing the info for HKDF (optional)

    + --uri value +

    Specify the PKCS#11 URI for module, slot, token or object

    Examples

    Perform a basic functionality test of the card:

    pkcs11-tool --test --login

    From 484a48d3f90ae15aa74dcad92eb42e65b219b6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 1 Apr 2025 16:25:38 +0200 Subject: [PATCH 3924/4321] Use enums to PKCS#11 URI implementation --- src/tests/unittests/parse_pkcs11_uri.c | 2 +- src/tools/pkcs11-tool.c | 2 +- src/tools/pkcs11_uri.c | 86 +++++++++++++------------- src/tools/pkcs11_uri.h | 25 +++++++- 4 files changed, 69 insertions(+), 46 deletions(-) diff --git a/src/tests/unittests/parse_pkcs11_uri.c b/src/tests/unittests/parse_pkcs11_uri.c index e50b1c3e9e..748f15187c 100644 --- a/src/tests/unittests/parse_pkcs11_uri.c +++ b/src/tests/unittests/parse_pkcs11_uri.c @@ -221,7 +221,7 @@ torture_pin_value(void **state) assert_int_equal(rv, 0); assert_string_equal("Software PKCS#11 softtoken", result->token_label); assert_string_equal("Snake Oil, Inc.", result->token_manufacturer); - assert_string_equal("the-pin", result->pin); + assert_string_equal("the-pin", result->pin_value); pkcs11_uri_free(result); } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index caa84cc27f..ca9d0cd302 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1270,7 +1270,7 @@ int main(int argc, char * argv[]) opt_slot_set = 1; } opt_module = opt_uri->module_path; - util_get_pin(opt_uri->pin, &opt_pin); + util_get_pin(opt_uri->pin_value, &opt_pin); util_get_pin(opt_uri->pin_source, &opt_pin); if (opt_pin) opt_login = 1; diff --git a/src/tools/pkcs11_uri.c b/src/tools/pkcs11_uri.c index 95dbf34de8..9161790ce1 100644 --- a/src/tools/pkcs11_uri.c +++ b/src/tools/pkcs11_uri.c @@ -31,27 +31,27 @@ #include "pkcs11_uri.h" static struct pkcs11_uri_attr path_attr[] = { - {"id", 0}, - {"library-description", 1}, - {"library-manufacturer", 2}, - {"library-version", 3}, - {"manufacturer", 4}, - {"model", 5}, - {"object", 6}, - {"serial", 7}, - {"slot-description", 8}, - {"slot-id", 9}, - {"slot-manufacturer", 10}, - {"token", 11}, - {"type", 12}, + {"id", PKCS11_ID}, + {"library-description", PKCS11_LIB_DESCRIPTION}, + {"library-manufacturer", PKCS11_LIB_MANUFACTURER}, + {"library-version", PKCS11_LIB_VERSION}, + {"manufacturer", PKCS11_MANUFACTURER}, + {"model", PKCS11_MODEL}, + {"object", PKCS11_OBJECT}, + {"serial", PKCS11_SERIAL}, + {"slot-description", PKCS11_SLOT_DESCRIPTION}, + {"slot-id", PKCS11_SLOT_ID}, + {"slot-manufacturer", PKCS11_SLOT_MANUFACTURER}, + {"token", PKCS11_TOKEN}, + {"type", PKCS11_TYPE}, {NULL, 0} }; static struct pkcs11_uri_attr query_attr[] = { - {"pin-source", 0}, - {"pin-value", 1}, - {"module-name", 2}, - {"module-path", 3}, + {"pin-source", PKCS11_PIN_SOURCE}, + {"pin-value", PKCS11_PIN_VALUE}, + {"module-name", PKCS11_MODULE_NAME}, + {"module-path", PKCS11_MODULE_PATH}, {NULL, 0} }; @@ -108,7 +108,7 @@ decode_percent_string(char *data, char **out) /* zero terminate */ decoded[decoded_len] = '\0'; *out = decoded; - return decoded_len; + return (int) decoded_len; fail: free(decoded); return -1; @@ -194,60 +194,60 @@ parse_pkcs11_uri(const char *input_string, struct pkcs11_uri *result) int id = get_attr(path_attr, token); if (id == -1) { rv = 1; - fprintf(stderr, "Invalid PKCS#11 token\n"); + fprintf(stderr, "Invalid PKCS#11 uri attribute\n"); goto end; } argument = token + strlen(path_attr[id].name) + 1; switch (id) { - case 0: /* CKA_ID */ + case PKCS11_ID: result_ptr = &result->id; result_len = &result->id_len; break; - case 1: /* CK_INFO -> libraryDescription */ + case PKCS11_LIB_DESCRIPTION: rv = 1; fprintf(stderr, "PKCS#11 library description not supported\n"); goto end; break; - case 2: /* CK_INFO -> manufacturerID */ + case PKCS11_LIB_MANUFACTURER: rv = 1; fprintf(stderr, "PKCS#11 manufacturer ID not supported\n"); goto end; break; - case 3: /* CK_INFO -> libraryVersion*/ + case PKCS11_LIB_VERSION: rv = 1; fprintf(stderr, "PKCS#11 library version not supported\n"); goto end; break; - case 4: /* CK_TOKEN_INFO -> manufacturerID */ + case PKCS11_MANUFACTURER: result_ptr = &result->token_manufacturer; max_len = 32; break; - case 5: /* CK_TOKEN_INFO -> model */ + case PKCS11_MODEL: result_ptr = &result->token_model; max_len = 16; break; - case 6: /* CKA_LABEL */ + case PKCS11_OBJECT: result_ptr = &result->object; break; - case 7: /* CK_TOKEN_INFO -> serialNumber */ + case PKCS11_SERIAL: result_ptr = &result->serial; max_len = 16; break; - case 8: /* CK_SLOT_INFO -> slotDescription */ + case PKCS11_SLOT_DESCRIPTION: result_ptr = &result->slot_description; break; - case 9: /* CK_SLOT_ID */ + case PKCS11_SLOT_ID: result_ptr = &result->slot_id; break; - case 10: /* CK_SLOT_INFO -> manufacturerID */ + case PKCS11_SLOT_MANUFACTURER: result_ptr = &result->slot_manufacturer; break; - case 11: /* CK_TOKEN_INFO -> label */ + case PKCS11_TOKEN: result_ptr = &result->token_label; max_len = 32; break; - case 12: /* CKA_CLASS */ + case PKCS11_TYPE: result_ptr = &result->type; break; } @@ -274,28 +274,28 @@ parse_pkcs11_uri(const char *input_string, struct pkcs11_uri *result) argument = token + strlen(query_attr[id].name) + 1; switch (id) { - case 0: - if (result->pin != NULL) { + case PKCS11_PIN_SOURCE: + if (result->pin_value != NULL) { rv = 1; - fprintf(stderr, "A pin and pin-source cannot be specified together in PKCS#11 URI\n"); + fprintf(stderr, "A pin-value and pin-source cannot be specified together in PKCS#11 URI\n"); goto end; } result_ptr = &result->pin_source; break; - case 1: + case PKCS11_PIN_VALUE: if (result->pin_source != NULL) { rv = 1; - fprintf(stderr, "A pin and pin-source cannot be specified together in PKCS#11 URI\n"); + fprintf(stderr, "A pin-value and pin-source cannot be specified together in PKCS#11 URI\n"); goto end; } - result_ptr = &result->pin; + result_ptr = &result->pin_value; break; - case 2: + case PKCS11_MODULE_NAME: rv = 1; fprintf(stderr, "PKCS#11 module name for query not supported\n"); goto end; break; - case 3: + case PKCS11_MODULE_PATH: result_ptr = &result->module_path; break; } @@ -332,9 +332,9 @@ pkcs11_uri_free(struct pkcs11_uri *uri) free(uri->token_label); free(uri->type); free(uri->pin_source); - if (uri->pin) { - memset(uri->pin, 0, strlen(uri->pin)); - free(uri->pin); + if (uri->pin_value) { + memset(uri->pin_value, 0, strlen(uri->pin_value)); + free(uri->pin_value); } free(uri->module_name); free(uri->module_path); diff --git a/src/tools/pkcs11_uri.h b/src/tools/pkcs11_uri.h index 158c2eb628..87f2ead40c 100644 --- a/src/tools/pkcs11_uri.h +++ b/src/tools/pkcs11_uri.h @@ -7,6 +7,29 @@ #define PKCS11_URI_SCHEME "pkcs11:" +typedef enum { + PKCS11_ID = 0, + PKCS11_LIB_DESCRIPTION, + PKCS11_LIB_MANUFACTURER, + PKCS11_LIB_VERSION, + PKCS11_MANUFACTURER, + PKCS11_MODEL, + PKCS11_OBJECT, + PKCS11_SERIAL, + PKCS11_SLOT_DESCRIPTION, + PKCS11_SLOT_ID, + PKCS11_SLOT_MANUFACTURER, + PKCS11_TOKEN, + PKCS11_TYPE +} pkcs11_uri_attr_code; + +typedef enum { + PKCS11_PIN_SOURCE = 0, + PKCS11_PIN_VALUE, + PKCS11_MODULE_NAME, + PKCS11_MODULE_PATH +} pkcs11_uri_query_code; + struct pkcs11_uri { /* taken from https://www.rfc-editor.org/rfc/rfc7512.html mapping of the PKCS #11 URI path component attributes */ char *id; @@ -25,7 +48,7 @@ struct pkcs11_uri { char *type; /* query */ char *pin_source; - char *pin; + char *pin_value; char *module_name; char *module_path; }; From d068f17ef0b74a2c07dce52871aad31837fced37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 3 Apr 2025 15:30:02 +0200 Subject: [PATCH 3925/4321] Add fuzzing target for parsing PKCS#11 URI --- src/tests/fuzzing/Makefile.am | 3 +- .../28ebe0a968fab20ddb61808decaa1b18369b635e | 1 + .../2b24f3f7b062c3e845aad88b1cc76ace2fe36048 | 1 + .../3dc11f14c5e5b62d0f579fe0b462c2f2f4735c1b | 1 + .../4b38e89701235f53db2a39715e9bd1c3189abe3c | 1 + .../5c56fda36553f0b28e31c735564ed2e26c88a958 | 1 + .../7e0a8c68797ba32db195022be9811cb0072e9353 | 1 + .../a81eb2485c1d1d4eb7a7dc048c9bce3f66889785 | 1 + .../bd87cedd745977935d20c7622974ce5b455c29b3 | 1 + .../d876e02864ba5f2287838ab6b14c9238f2f97450 | 1 + src/tests/fuzzing/fuzz_pkcs11_uri.c | 54 +++++++++++++++++++ 11 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/28ebe0a968fab20ddb61808decaa1b18369b635e create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/2b24f3f7b062c3e845aad88b1cc76ace2fe36048 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/3dc11f14c5e5b62d0f579fe0b462c2f2f4735c1b create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/4b38e89701235f53db2a39715e9bd1c3189abe3c create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/5c56fda36553f0b28e31c735564ed2e26c88a958 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/7e0a8c68797ba32db195022be9811cb0072e9353 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/a81eb2485c1d1d4eb7a7dc048c9bce3f66889785 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/bd87cedd745977935d20c7622974ce5b455c29b3 create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11_uri/d876e02864ba5f2287838ab6b14c9238f2f97450 create mode 100644 src/tests/fuzzing/fuzz_pkcs11_uri.c diff --git a/src/tests/fuzzing/Makefile.am b/src/tests/fuzzing/Makefile.am index 6b53b6343e..ea643f635e 100644 --- a/src/tests/fuzzing/Makefile.am +++ b/src/tests/fuzzing/Makefile.am @@ -9,7 +9,7 @@ LIBS = $(FUZZING_LIBS)\ noinst_PROGRAMS = fuzz_asn1_print fuzz_asn1_sig_value fuzz_pkcs15_decode fuzz_pkcs15_reader \ fuzz_scconf_parse_string fuzz_pkcs15_encode fuzz_card \ - fuzz_pkcs15_tool fuzz_pkcs15_crypt + fuzz_pkcs15_tool fuzz_pkcs15_crypt fuzz_pkcs11_uri if ENABLE_STATIC noinst_PROGRAMS += fuzz_pkcs15init @@ -55,3 +55,4 @@ fuzz_pkcs11_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ $(OPTIONAL_OPENSSL_LIBS) \ $(top_builddir)/src/pkcs11/libopensc-pkcs11.la +fuzz_pkcs11_uri_SOURCES = fuzz_pkcs11_uri.c ../../tools/pkcs11_uri.c $(ADDITIONAL_SRC) diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/28ebe0a968fab20ddb61808decaa1b18369b635e b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/28ebe0a968fab20ddb61808decaa1b18369b635e new file mode 100644 index 0000000000..708d8372b8 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/28ebe0a968fab20ddb61808decaa1b18369b635e @@ -0,0 +1 @@ +pkcs11:object=my-sign-key;type=private?module-path=/mnt/libmypkcs11.so.1 \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/2b24f3f7b062c3e845aad88b1cc76ace2fe36048 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/2b24f3f7b062c3e845aad88b1cc76ace2fe36048 new file mode 100644 index 0000000000..89fe39486a --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/2b24f3f7b062c3e845aad88b1cc76ace2fe36048 @@ -0,0 +1 @@ +pkcs11:object=my-pubkey;type=public \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/3dc11f14c5e5b62d0f579fe0b462c2f2f4735c1b b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/3dc11f14c5e5b62d0f579fe0b462c2f2f4735c1b new file mode 100644 index 0000000000..146a701cd5 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/3dc11f14c5e5b62d0f579fe0b462c2f2f4735c1b @@ -0,0 +1 @@ +pkcs11: \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/4b38e89701235f53db2a39715e9bd1c3189abe3c b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/4b38e89701235f53db2a39715e9bd1c3189abe3c new file mode 100644 index 0000000000..0dd050f29d --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/4b38e89701235f53db2a39715e9bd1c3189abe3c @@ -0,0 +1 @@ +pkcs11:token=The%20Software%20PKCS%2311%20Softtoken;manufacturer=Snake%20Oil,%20Inc.;model=1.0;object=my-certificate;type=cert;id=%69%95%3E%5C%F4%BD%EC%91;serial=?pin-source=file:/etc/token_pin \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/5c56fda36553f0b28e31c735564ed2e26c88a958 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/5c56fda36553f0b28e31c735564ed2e26c88a958 new file mode 100644 index 0000000000..33d92b1f38 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/5c56fda36553f0b28e31c735564ed2e26c88a958 @@ -0,0 +1 @@ +pkcs11:object=my-key;type=private?pin-source=file:/etc/token \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/7e0a8c68797ba32db195022be9811cb0072e9353 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/7e0a8c68797ba32db195022be9811cb0072e9353 new file mode 100644 index 0000000000..8cfd422076 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/7e0a8c68797ba32db195022be9811cb0072e9353 @@ -0,0 +1 @@ +pkcs11:slot-description=Sun%20Metaslot \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/a81eb2485c1d1d4eb7a7dc048c9bce3f66889785 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/a81eb2485c1d1d4eb7a7dc048c9bce3f66889785 new file mode 100644 index 0000000000..a63d98ab82 --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/a81eb2485c1d1d4eb7a7dc048c9bce3f66889785 @@ -0,0 +1 @@ +pkcs11:library-manufacturer=Snake%20Oil,%20Inc.;library-description=Soft%20Token%20Library;library-version=1.23 \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/bd87cedd745977935d20c7622974ce5b455c29b3 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/bd87cedd745977935d20c7622974ce5b455c29b3 new file mode 100644 index 0000000000..f884558f7a --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/bd87cedd745977935d20c7622974ce5b455c29b3 @@ -0,0 +1 @@ +pkcs11:object=my-sign-key;type=private?module-name=mypkcs11 \ No newline at end of file diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/d876e02864ba5f2287838ab6b14c9238f2f97450 b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/d876e02864ba5f2287838ab6b14c9238f2f97450 new file mode 100644 index 0000000000..0ebe8a984d --- /dev/null +++ b/src/tests/fuzzing/corpus/fuzz_pkcs11_uri/d876e02864ba5f2287838ab6b14c9238f2f97450 @@ -0,0 +1 @@ +pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin \ No newline at end of file diff --git a/src/tests/fuzzing/fuzz_pkcs11_uri.c b/src/tests/fuzzing/fuzz_pkcs11_uri.c new file mode 100644 index 0000000000..09a0ff4a44 --- /dev/null +++ b/src/tests/fuzzing/fuzz_pkcs11_uri.c @@ -0,0 +1,54 @@ +/* + * fuzz_pkcs11_uri.c: Fuzz target for PKCS #11 URI parser + * + * Copyright (C) 2025 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#undef stderr +#define stderr stdout + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + char *input_string = NULL; + struct pkcs11_uri *uri = NULL; + if (Size == 0) + return 0; + if ((input_string = malloc(Size + 1)) == NULL) + return 0; + memcpy(input_string, Data, Size); + input_string[Size] = 0; + + if ((uri = pkcs11_uri_new()) == NULL) + return 0; + parse_pkcs11_uri(input_string, uri); + + pkcs11_uri_free(uri); + free(input_string); + return 0; +} + \ No newline at end of file From 4f3de4e147c01bb685ff94c47e1cf369afb5766f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 5 Aug 2025 11:28:59 +0200 Subject: [PATCH 3926/4321] Fix formatting issues --- src/tests/fuzzing/fuzz_pkcs11_uri.c | 8 ++-- src/tests/unittests/parse_pkcs11_uri.c | 3 +- src/tools/pkcs11-tool.c | 64 ++++++++++++++------------ src/tools/pkcs11_uri.c | 38 +++++++-------- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11_uri.c b/src/tests/fuzzing/fuzz_pkcs11_uri.c index 09a0ff4a44..b248fde12a 100644 --- a/src/tests/fuzzing/fuzz_pkcs11_uri.c +++ b/src/tests/fuzzing/fuzz_pkcs11_uri.c @@ -24,15 +24,16 @@ #endif #include +#include #include #include -#include #include #undef stderr #define stderr stdout - -int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) + +int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { char *input_string = NULL; struct pkcs11_uri *uri = NULL; @@ -51,4 +52,3 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) free(input_string); return 0; } - \ No newline at end of file diff --git a/src/tests/unittests/parse_pkcs11_uri.c b/src/tests/unittests/parse_pkcs11_uri.c index 748f15187c..9909aebae9 100644 --- a/src/tests/unittests/parse_pkcs11_uri.c +++ b/src/tests/unittests/parse_pkcs11_uri.c @@ -271,7 +271,6 @@ main(void) cmocka_unit_test(torture_module_path), cmocka_unit_test(torture_pin_value), cmocka_unit_test(torture_encoded_semicolon), - cmocka_unit_test(torture_pin_pin_source) - }; + cmocka_unit_test(torture_pin_pin_source)}; return cmocka_run_group_tests(tests, NULL, NULL); } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ca9d0cd302..cbfd248716 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -72,8 +72,8 @@ #include "libopensc/sc-ossl-compat.h" #include "pkcs11/pkcs11-opensc.h" #include "pkcs11/pkcs11.h" -#include "util.h" #include "pkcs11_uri.h" +#include "util.h" /* pkcs11-tool uses libopensc routines that do not use an sc_context * but does use some OpenSSL routines @@ -428,8 +428,7 @@ static const char *option_help[] = { "Specify the file containing the salt for HKDF (optional)", "Specify the file containing the info for HKDF (optional)", "When reading a public key, try to read PUBLIC_KEY_INFO (DER encoding of SPKI)", - "Specify the PKCS#11 URI for module, slot, token or object" -}; + "Specify the PKCS#11 URI for module, slot, token or object"}; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -437,7 +436,7 @@ static int verbose = 0; static const char * opt_input = NULL; static const char * opt_output = NULL; static const char * opt_signature_file = NULL; -static const char * opt_module = NULL; +static const char *opt_module = NULL; static int opt_slot_set = 0; static CK_SLOT_ID opt_slot = 0; static const char * opt_slot_description = NULL; @@ -617,21 +616,21 @@ static CK_RV write_object(CK_SESSION_HANDLE session); static int read_object(CK_SESSION_HANDLE session); static int delete_object(CK_SESSION_HANDLE session); static void set_id_attr(CK_SESSION_HANDLE session); -static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, - CK_OBJECT_CLASS cls, int cls_set, - CK_OBJECT_HANDLE_PTR ret, - const unsigned char *, size_t id_len, - const char *, int obj_index); +static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, + CK_OBJECT_CLASS cls, int cls_set, + CK_OBJECT_HANDLE_PTR ret, + const unsigned char *, size_t id_len, + const char *, int obj_index); static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); static int find_object_flags(CK_SESSION_HANDLE, uint16_t flags, CK_OBJECT_HANDLE_PTR, const unsigned char *, size_t id_len, int obj_index); -static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, - uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, - CK_OBJECT_CLASS cls, int cls_set, - const unsigned char *id, size_t id_len, const char *label, int obj_index); +static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, + uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, + CK_OBJECT_CLASS cls, int cls_set, + const unsigned char *id, size_t id_len, const char *label, int obj_index); static CK_ULONG find_mechanism(CK_SLOT_ID, CK_FLAGS, CK_MECHANISM_TYPE_PTR, size_t, CK_MECHANISM_TYPE_PTR); static int get_default_slot(CK_SLOT_ID_PTR result); static int find_slot_by_uri(struct pkcs11_uri *uri, CK_SLOT_ID_PTR result); @@ -645,7 +644,7 @@ static void p11_warn(const char *, CK_RV); static const char * p11_slot_info_flags(CK_FLAGS); static const char * p11_token_info_flags(CK_FLAGS); static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t); -static char * p11_utf8_to_string(CK_UTF8CHAR *, size_t); +static char *p11_utf8_to_string(CK_UTF8CHAR *, size_t); static const char * p11_flag_names(struct flag_info *, CK_FLAGS); static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE); static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); @@ -1504,7 +1503,7 @@ int main(int argc, char * argv[]) util_fatal("Incorrect type of key"); } if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, - &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { util_fatal("Private/secret key not found"); } } else if (!find_object(session, CKO_PRIVATE_KEY, &object, @@ -1538,11 +1537,11 @@ int main(int argc, char * argv[]) util_fatal("Incorrect type of key"); } if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, - &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { util_fatal("Private/secret key not found"); } - } else if (!find_object(session, CKO_PRIVATE_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + } else if (!find_object(session, CKO_PRIVATE_KEY, &object, + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) if (!find_object(session, CKO_SECRET_KEY, &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) util_fatal("Private/secret key not found"); @@ -1572,7 +1571,7 @@ int main(int argc, char * argv[]) util_fatal("Incorrect type of key"); } if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, - &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { util_fatal("Public/Secret key not found"); } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, @@ -1606,15 +1605,15 @@ int main(int argc, char * argv[]) util_fatal("Incorrect type of key"); } if (!find_object_type_or_id_or_label(session, opt_object_class, opt_uri->type == NULL ? 0 : 1, - &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { + &object, opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { util_fatal("Public key nor certificate not found"); } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0) && - !find_object(session, CKO_CERTIFICATE, &object, - opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0) && + !find_object(session, CKO_CERTIFICATE, &object, + opt_object_id_len ? opt_object_id : NULL, + opt_object_id_len, 0)) util_fatal("Public key nor certificate not found"); } @@ -5227,7 +5226,8 @@ static void set_id_attr(CK_SESSION_HANDLE session) show_object(session, obj); } -static int get_default_slot(CK_SLOT_ID_PTR result) +static int +get_default_slot(CK_SLOT_ID_PTR result) { /* use first slot with token present (or default slot on error) */ CK_RV rv; @@ -5246,7 +5246,8 @@ static int get_default_slot(CK_SLOT_ID_PTR result) return 0; } -static int find_slot_by_uri(struct pkcs11_uri *uri, CK_SLOT_ID_PTR result) +static int +find_slot_by_uri(struct pkcs11_uri *uri, CK_SLOT_ID_PTR result) { CK_SLOT_INFO slot_info; CK_TOKEN_INFO token_info; @@ -5341,7 +5342,8 @@ static int find_slot_by_token_label(const char *label, CK_SLOT_ID_PTR result) return 0; } -static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, +static int +find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, int cls_set, CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len, @@ -5421,7 +5423,8 @@ static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, util_fatal("Could not find key of type: %s", err_key_types); } -static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, +static int +find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, CK_OBJECT_CLASS cls, int cls_set, const unsigned char *id, size_t id_len, const char *label, int obj_index) @@ -9278,7 +9281,8 @@ static const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len) return buffer; } -static char *p11_utf8_to_string(CK_UTF8CHAR *string, size_t len) +static char * +p11_utf8_to_string(CK_UTF8CHAR *string, size_t len) { char *buffer = NULL; size_t n, m; diff --git a/src/tools/pkcs11_uri.c b/src/tools/pkcs11_uri.c index 9161790ce1..6b768389fa 100644 --- a/src/tools/pkcs11_uri.c +++ b/src/tools/pkcs11_uri.c @@ -31,35 +31,35 @@ #include "pkcs11_uri.h" static struct pkcs11_uri_attr path_attr[] = { - {"id", PKCS11_ID}, - {"library-description", PKCS11_LIB_DESCRIPTION}, - {"library-manufacturer", PKCS11_LIB_MANUFACTURER}, - {"library-version", PKCS11_LIB_VERSION}, - {"manufacturer", PKCS11_MANUFACTURER}, - {"model", PKCS11_MODEL}, - {"object", PKCS11_OBJECT}, - {"serial", PKCS11_SERIAL}, - {"slot-description", PKCS11_SLOT_DESCRIPTION}, - {"slot-id", PKCS11_SLOT_ID}, - {"slot-manufacturer", PKCS11_SLOT_MANUFACTURER}, - {"token", PKCS11_TOKEN}, - {"type", PKCS11_TYPE}, - {NULL, 0} + {"id", PKCS11_ID }, + {"library-description", PKCS11_LIB_DESCRIPTION }, + {"library-manufacturer", PKCS11_LIB_MANUFACTURER }, + {"library-version", PKCS11_LIB_VERSION }, + {"manufacturer", PKCS11_MANUFACTURER }, + {"model", PKCS11_MODEL }, + {"object", PKCS11_OBJECT }, + {"serial", PKCS11_SERIAL }, + {"slot-description", PKCS11_SLOT_DESCRIPTION }, + {"slot-id", PKCS11_SLOT_ID }, + {"slot-manufacturer", PKCS11_SLOT_MANUFACTURER}, + {"token", PKCS11_TOKEN }, + {"type", PKCS11_TYPE }, + {NULL, 0 } }; static struct pkcs11_uri_attr query_attr[] = { - {"pin-source", PKCS11_PIN_SOURCE}, - {"pin-value", PKCS11_PIN_VALUE}, + {"pin-source", PKCS11_PIN_SOURCE }, + {"pin-value", PKCS11_PIN_VALUE }, {"module-name", PKCS11_MODULE_NAME}, {"module-path", PKCS11_MODULE_PATH}, - {NULL, 0} + {NULL, 0 } }; static int get_attr(struct pkcs11_uri_attr attr[], char *token) { for (int i = 0; attr[i].name; i++) { - if (strncasecmp(token, attr[i].name, strlen(attr[i].name)) == 0 && + if (strncasecmp(token, attr[i].name, strlen(attr[i].name)) == 0 && *(token + strlen(attr[i].name)) == '=') return attr[i].id; } @@ -108,7 +108,7 @@ decode_percent_string(char *data, char **out) /* zero terminate */ decoded[decoded_len] = '\0'; *out = decoded; - return (int) decoded_len; + return (int)decoded_len; fail: free(decoded); return -1; From fc4e0ee8cce56db48842a065a3113f3fd90328dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 5 Aug 2025 13:30:17 +0200 Subject: [PATCH 3927/4321] pkcs11-tool: Add concrete error messages when specifying URI option --- src/tools/pkcs11-tool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index cbfd248716..191715bb65 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1261,7 +1261,14 @@ int main(int argc, char * argv[]) /* Check that no interfering options were set */ if (opt_module || opt_slot_set || opt_slot_index_set || opt_slot_description || opt_pin || opt_object_label || opt_object_class_str || opt_object_id_len) { - fprintf(stderr, "Invalid combination of arguments when --uri used\n"); + if (opt_module) + fprintf(stderr, "The --module cannot be specified with --uri option\n"); + if (opt_slot_set || opt_slot_index_set || opt_slot_description) + fprintf(stderr, "Options specifying slot cannot be specified with --uri option\n"); + if (opt_pin) + fprintf(stderr, "The PIN option cannot be specified with --uri option\n"); + if (opt_object_label || opt_object_class_str || opt_object_id_len) + fprintf(stderr, "Options specifying object cannot be specified with --uri option\n"); util_print_usage_and_die(app_name, options, option_help, NULL); } if (opt_uri->slot_id) { From 43424990a1aff1ea1c4b91c35d7c9f936d644e29 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 5 Aug 2025 16:20:00 +0200 Subject: [PATCH 3928/4321] dnie: Fix possible NULL pointer dereference CID 487569 Thanks coverity Signed-off-by: Jakub Jelen --- src/libopensc/card-dnie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 5c9babf15a..50e8a78f0a 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -773,9 +773,9 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card, plain->sw1 = (*sm_apdu)->sw1; plain->sw2 = (*sm_apdu)->sw2; } - if ((*sm_apdu)->data != plain->data) + if (plain == NULL || (*sm_apdu)->data != plain->data) free((unsigned char *) (*sm_apdu)->data); - if ((*sm_apdu)->resp != plain->resp) + if (plain == NULL || (*sm_apdu)->resp != plain->resp) free((*sm_apdu)->resp); free(*sm_apdu); } From afbbac95fa28ace7241b79106610854a6d456c87 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 3 Jun 2024 23:25:19 +0200 Subject: [PATCH 3929/4321] sm-eac: Allow non-standard PIN reference IDs for PACE --- src/sm/sm-eac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index c311674eed..123f90a36c 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -634,6 +634,9 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id pin = p; } + if (pin_id != PACE_PIN && pin_id != PACE_CAN && pin_id != PACE_MRZ && pin_id != PACE_PUK) + pin_id = PACE_RAW; + r = PACE_SEC_new(pin, length_pin, pin_id); if (p) { From 0ac6cd64ef066c4aac9dc09f596635618533a327 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 8 May 2024 21:54:10 +0200 Subject: [PATCH 3930/4321] dtrust: Read serial number from EF.GDO This is necessary, because for D-Trust Cards 5.x the CardOS command requires PACE authentication. --- src/libopensc/card-dtrust.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index c18355c28c..94b78bf83c 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -185,20 +185,14 @@ static int _dtrust_get_serialnr(sc_card_t *card) { int r; - u8 buf[32]; - - r = sc_get_data(card, 0x0181, buf, 32); - LOG_TEST_RET(card->ctx, r, "querying serial number failed"); - if (r != 8) { - sc_log(card->ctx, "unexpected response to GET DATA serial number"); - return SC_ERROR_INTERNAL; + card->serialnr.len = SC_MAX_SERIALNR; + r = sc_parse_ef_gdo(card, card->serialnr.value, &card->serialnr.len, NULL, 0); + if (r < 0) { + card->serialnr.len = 0; + return r; } - /* cache serial number */ - memcpy(card->serialnr.value, buf, 8); - card->serialnr.len = 8; - return SC_SUCCESS; } From a0c07b2846dddc8ea5f8ea989411c959c99465ad Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 8 May 2024 21:57:46 +0200 Subject: [PATCH 3931/4321] dtrust: Identify D-Trust Card 5.1 & 5.4 (#3131) --- src/libopensc/card-dtrust.c | 109 +++++++++++++++++++++++++--------- src/libopensc/cards.h | 5 ++ src/libopensc/pkcs15-dtrust.c | 37 +++++++----- src/libopensc/pkcs15-syn.c | 5 ++ win32/customactions.cpp | 2 + 5 files changed, 115 insertions(+), 43 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 94b78bf83c..0fe4a03687 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -57,19 +57,29 @@ static const struct sc_atr_table dtrust_atrs[] = { * as it is identical to that of CardOS v5.4 and therefore already included. * Any new ATR may need an entry in minidriver_registration[]. */ { "3b:d2:18:00:81:31:fe:58:c9:04:11", NULL, NULL, SC_CARD_TYPE_DTRUST_V4_1_STD, 0, NULL }, + + + /* D-Trust Signature Card v5.1 and v5.4 - CardOS 6.0 + * + * These cards are dual interface cards. Thus they have separate ATRs. */ + + /* contact based */ + { "3b:d2:18:00:81:31:fe:58:cb:01:16", NULL, NULL, SC_CARD_TYPE_DTRUST_V5_1_STD, 0, NULL }, + + /* contactless */ + { "3b:82:80:01:cb:01:c9", NULL, NULL, SC_CARD_TYPE_DTRUST_V5_1_STD, 0, NULL }, + { "07:78:77:74:03:cb:01:09", NULL, NULL, SC_CARD_TYPE_DTRUST_V5_1_STD, 0, NULL }, + { NULL, NULL, NULL, 0, 0, NULL } }; // clang-format on -// clang-format off -static struct dtrust_supported_ec_curves { - struct sc_object_id oid; - size_t size; -} dtrust_curves[] = { - { .oid = {{ 1, 2, 840, 10045, 3, 1, 7, -1 }}, .size = 256 }, /* secp256r1 */ - { .oid = {{ -1 }}, .size = 0 }, +static struct sc_object_id oid_secp256r1 = { + {1, 2, 840, 10045, 3, 1, 7, -1} +}; +static struct sc_object_id oid_secp384r1 = { + {1, 3, 132, 0, 34, -1} }; -// clang-format on static int _dtrust_match_cardos(sc_card_t *card) @@ -82,16 +92,26 @@ _dtrust_match_cardos(sc_card_t *card) r = sc_get_data(card, 0x0182, buf, 32); LOG_TEST_RET(card->ctx, r, "OS version check failed"); - if (r != 2 || buf[0] != 0xc9 || buf[1] != 0x04) - return SC_ERROR_WRONG_CARD; + if (card->type == SC_CARD_TYPE_DTRUST_V4_1_STD) { + if (r != 2 || buf[0] != 0xc9 || buf[1] != 0x04) + return SC_ERROR_WRONG_CARD; + } else if (card->type == SC_CARD_TYPE_DTRUST_V5_1_STD) { + if (r != 2 || buf[0] != 0xcb || buf[1] != 0x01) + return SC_ERROR_WRONG_CARD; + } /* check product name */ r = sc_get_data(card, 0x0180, buf, 32); LOG_TEST_RET(card->ctx, r, "Product name check failed"); prodlen = (size_t)r; - if (prodlen != strlen("CardOS V5.4 2019") + 1 || memcmp(buf, "CardOS V5.4 2019", prodlen)) - return SC_ERROR_WRONG_CARD; + if (card->type == SC_CARD_TYPE_DTRUST_V4_1_STD) { + if (prodlen != strlen("CardOS V5.4 2019") + 1 || memcmp(buf, "CardOS V5.4 2019", prodlen)) + return SC_ERROR_WRONG_CARD; + } else if (card->type == SC_CARD_TYPE_DTRUST_V5_1_STD) { + if (prodlen != strlen("CardOS V6.0 2021") + 1 || memcmp(buf, "CardOS V6.0 2021", prodlen)) + return SC_ERROR_WRONG_CARD; + } return SC_SUCCESS; } @@ -139,18 +159,33 @@ _dtrust_match_profile(sc_card_t *card) * on the production process, but aren't relevant for determining the * card profile. */ - if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.1 Std. RSA 2", 27)) - card->type = SC_CARD_TYPE_DTRUST_V4_1_STD; - else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 4.1 Multi ECC 2", 28)) - card->type = SC_CARD_TYPE_DTRUST_V4_1_MULTI; - else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.1 M100 ECC 2", 27)) - card->type = SC_CARD_TYPE_DTRUST_V4_1_M100; - else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.4 Std. RSA 2", 27)) - card->type = SC_CARD_TYPE_DTRUST_V4_4_STD; - else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 4.4 Multi ECC 2", 28)) - card->type = SC_CARD_TYPE_DTRUST_V4_4_MULTI; - else - return SC_ERROR_WRONG_CARD; + if (card->type == SC_CARD_TYPE_DTRUST_V4_1_STD) { + if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.1 Std. RSA 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V4_1_STD; + else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 4.1 Multi ECC 2", 28)) + card->type = SC_CARD_TYPE_DTRUST_V4_1_MULTI; + else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.1 M100 ECC 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V4_1_M100; + else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 4.4 Std. RSA 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V4_4_STD; + else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 4.4 Multi ECC 2", 28)) + card->type = SC_CARD_TYPE_DTRUST_V4_4_MULTI; + else + return SC_ERROR_WRONG_CARD; + } else if (card->type == SC_CARD_TYPE_DTRUST_V5_1_STD) { + if (plen >= 27 && !memcmp(pp, "D-TRUST Card 5.1 Std. RSA 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V5_1_STD; + else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 5.1 Multi ECC 2", 28)) + card->type = SC_CARD_TYPE_DTRUST_V5_1_MULTI; + else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 5.1 M100 ECC 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V5_1_M100; + else if (plen >= 27 && !memcmp(pp, "D-TRUST Card 5.4 Std. RSA 2", 27)) + card->type = SC_CARD_TYPE_DTRUST_V5_4_STD; + else if (plen >= 28 && !memcmp(pp, "D-TRUST Card 5.4 Multi ECC 2", 28)) + card->type = SC_CARD_TYPE_DTRUST_V5_4_MULTI; + else + return SC_ERROR_WRONG_CARD; + } name = malloc(plen + 1); if (name == NULL) @@ -176,7 +211,7 @@ dtrust_match_card(sc_card_t *card) if (_dtrust_match_profile(card) != SC_SUCCESS) return 0; - sc_log(card->ctx, "D-Trust Signature Card (CardOS 5.4)"); + sc_log(card->ctx, "D-Trust Signature Card"); return 1; } @@ -236,6 +271,8 @@ dtrust_init(sc_card_t *card) switch (card->type) { case SC_CARD_TYPE_DTRUST_V4_1_STD: case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_4_STD: flags |= SC_ALGORITHM_RSA_PAD_PKCS1; flags |= SC_ALGORITHM_RSA_PAD_PSS; flags |= SC_ALGORITHM_RSA_PAD_OAEP; @@ -254,12 +291,23 @@ dtrust_init(sc_card_t *card) case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + flags |= SC_ALGORITHM_ECDSA_RAW; flags |= SC_ALGORITHM_ECDH_CDH_RAW; + ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; + + _sc_card_add_ec_alg(card, 256, flags, ext_flags, &oid_secp256r1); + + r = SC_SUCCESS; + break; + + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: flags |= SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDH_CDH_RAW; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; - for (unsigned int i = 0; dtrust_curves[i].oid.value[0] >= 0; i++) { - _sc_card_add_ec_alg(card, dtrust_curves[i].size, flags, ext_flags, &dtrust_curves[i].oid); - } + + _sc_card_add_ec_alg(card, 384, flags, ext_flags, &oid_secp384r1); r = SC_SUCCESS; break; @@ -498,6 +546,8 @@ dtrust_decipher(struct sc_card *card, const u8 *data, /* No special handling necessary for RSA cards. */ case SC_CARD_TYPE_DTRUST_V4_1_STD: case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_4_STD: LOG_FUNC_RETURN(card->ctx, iso_ops->decipher(card, data, data_len, out, outlen)); /* Elliptic Curve cards cannot use PSO:DECIPHER command and need to @@ -505,6 +555,9 @@ dtrust_decipher(struct sc_card *card, const u8 *data, case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: LOG_FUNC_RETURN(card->ctx, cardos_ec_compute_shared_value(card, data, data_len, out, outlen)); default: diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 79bf74fce9..d4a815f624 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -272,6 +272,11 @@ enum { SC_CARD_TYPE_DTRUST_V4_1_M100, SC_CARD_TYPE_DTRUST_V4_4_STD, SC_CARD_TYPE_DTRUST_V4_4_MULTI, + SC_CARD_TYPE_DTRUST_V5_1_STD, + SC_CARD_TYPE_DTRUST_V5_1_MULTI, + SC_CARD_TYPE_DTRUST_V5_1_M100, + SC_CARD_TYPE_DTRUST_V5_4_STD, + SC_CARD_TYPE_DTRUST_V5_4_MULTI, }; extern sc_card_driver_t *sc_get_default_driver(void); diff --git a/src/libopensc/pkcs15-dtrust.c b/src/libopensc/pkcs15-dtrust.c index b534521b7c..8f754a6a74 100644 --- a/src/libopensc/pkcs15-dtrust.c +++ b/src/libopensc/pkcs15-dtrust.c @@ -47,22 +47,29 @@ _dtrust_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) if (df->type != SC_PKCS15_PRKDF) LOG_FUNC_RETURN(ctx, SC_SUCCESS); - switch (p15card->card->type) { - /* Cards with EC keys, don't encode the curve size in the - * private key directory file. We need to set the field_length - * element after parsing the private key directory file. */ - case SC_CARD_TYPE_DTRUST_V4_1_MULTI: - case SC_CARD_TYPE_DTRUST_V4_1_M100: - case SC_CARD_TYPE_DTRUST_V4_4_MULTI: - rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, pkobjs, sizeof(pkobjs) / sizeof(pkobjs[0])); - LOG_TEST_RET(ctx, rv, "Cannot get PRKEY objects list"); - - count = rv; - for (i = 0; i < count; i++) { - prkey_info = (struct sc_pkcs15_prkey_info *)pkobjs[i]->data; + rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, pkobjs, sizeof(pkobjs) / sizeof(pkobjs[0])); + LOG_TEST_RET(ctx, rv, "Cannot get PRKEY objects list"); + + count = rv; + for (i = 0; i < count; i++) { + prkey_info = (struct sc_pkcs15_prkey_info *)pkobjs[i]->data; + + switch (p15card->card->type) { + /* Cards with EC keys, don't encode the curve size in the + * private key directory file. We need to set the field_length + * element after parsing the private key directory file. */ + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: prkey_info->field_length = 256; + break; + + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + prkey_info->field_length = 384; + break; } - break; } LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -74,7 +81,7 @@ dtrust_pkcs15emu_detect_card(sc_pkcs15_card_t *p15card) if (p15card->card->type < SC_CARD_TYPE_DTRUST_V4_1_STD) return SC_ERROR_WRONG_CARD; - if (p15card->card->type > SC_CARD_TYPE_DTRUST_V4_4_MULTI) + if (p15card->card->type > SC_CARD_TYPE_DTRUST_V5_4_MULTI) return SC_ERROR_WRONG_CARD; return SC_SUCCESS; diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 3c20f9ad89..45d28eba81 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -121,6 +121,11 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: return 1; default: return 0; diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 0db8b5bbb8..716691e226 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -158,6 +158,8 @@ MD_REGISTRATION minidriver_registration[] = { 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("CardOS v5.4"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xc9,0x04,0x11}, 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("CardOS v6.0"), {0x3b,0xd2,0x18,0x00,0x81,0x31,0xfe,0x58,0xcb,0x01,0x16}, + 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("JPKI"), {0x3b,0xe0,0x00,0xff,0x81,0x31,0xfe,0x45,0x14}, 9, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, From 2288de0174e74643fc59810f3052e88ccd2dd0a6 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Fri, 15 Nov 2024 15:13:17 +0100 Subject: [PATCH 3932/4321] dtrust: Don't allocate PKCS#11 slot for CAN --- src/libopensc/pkcs15-dtrust.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libopensc/pkcs15-dtrust.c b/src/libopensc/pkcs15-dtrust.c index 8f754a6a74..2c4fd07e1f 100644 --- a/src/libopensc/pkcs15-dtrust.c +++ b/src/libopensc/pkcs15-dtrust.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -99,6 +101,22 @@ sc_pkcs15emu_dtrust_init(struct sc_pkcs15_card *p15card, struct sc_aid *aid) p15card->ops.parse_df = _dtrust_parse_df; +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) + struct sc_pkcs15_search_key sk; + struct sc_pkcs15_object *objs[8]; + int i, len; + + memset(&sk, 0, sizeof(sk)); + sk.class_mask = SC_PKCS15_SEARCH_CLASS_AUTH; + len = sc_pkcs15_search_objects(p15card, &sk, (struct sc_pkcs15_object **)&objs, sizeof(objs) / sizeof(struct sc_pkcs15_object *)); + for (i = 0; i < len; i++) { + if (!strcmp(objs[i]->label, "CAN")) { + /* Mark "Card CAN" as NOT a PIN object, so that it doesn't get it's own PKCS#11 slot */ + objs[i]->type &= ~SC_PKCS15_TYPE_AUTH_PIN; + } + } +#endif + LOG_FUNC_RETURN(ctx, rv); } From 28229998b43d23b261d36466c7e4d3a348b43313 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Tue, 19 Nov 2024 14:05:32 +0100 Subject: [PATCH 3933/4321] dtrust: Perform PACE authentication where necessary --- src/libopensc/Makefile.am | 2 +- src/libopensc/card-dtrust.c | 274 ++++++++++++++++++++++++++++++++---- src/libopensc/card-dtrust.h | 29 ++++ 3 files changed, 276 insertions(+), 29 deletions(-) create mode 100644 src/libopensc/card-dtrust.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 4d6a9b000a..428ed1865d 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -13,7 +13,7 @@ noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \ pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ jpki.h sc-ossl-compat.h card-npa.h card-openpgp.h \ - card-eoi.h ccid-types.h reader-tr03119.h \ + card-eoi.h card-dtrust.h ccid-types.h reader-tr03119.h \ card-cac-common.h card-cardos-common.h AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 0fe4a03687..5be896b30d 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -27,9 +27,14 @@ #include #include +#include "libopensc/pace.h" + #include "asn1.h" #include "card-cardos-common.h" #include "internal.h" +#include "sm/sm-eac.h" + +#include "card-dtrust.h" static const struct sc_card_operations *iso_ops = NULL; @@ -327,6 +332,216 @@ dtrust_finish(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +static int +dtrust_select_app(struct sc_card *card, int ref) +{ + sc_path_t path; + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + switch (ref) { + case DTRUST5_PIN_ID_QES: + sc_format_path("3F000101", &path); + break; + + case DTRUST5_PIN_ID_AUT: + sc_format_path("3F000102", &path); + break; + + default: + sc_format_path("3F00", &path); + break; + } + + r = sc_select_file(card, &path, NULL); + LOG_TEST_RET(card->ctx, r, "Selecting master file failed"); + break; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +dtrust_perform_pace(struct sc_card *card, + int ref, + const unsigned char *pin, + size_t pinlen, + int *tries_left) +{ + int r; + struct establish_pace_channel_input pace_input; + struct establish_pace_channel_output pace_output; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* The PKCS#11 layer cannot provide a CAN. Instead we consider the + * following sources for CAN input. + * 1. A CAN provided by the caller + * 2. A cached CAN when the cache feature is enabled + * 3. If the reader supports the PACE protocol, we let it query for a + * CAN on the pin pad. + * 4. Querying the user interactively if possible */ + if (ref == PACE_PIN_ID_CAN) { + /* TODO: Query the CAN cache if no CAN is provided by the caller. */ + + if (pin == NULL) { + if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { + /* If no CAN is provided and the reader is + * PACE-capable, we leave pin == NULL to request the + * ready for querying the CAN on its pin pad. */ + sc_log(card->ctx, "Letting the reader prompt for the CAN on its pin pad."); + } else { + /* TODO: Request user input */ + sc_log(card->ctx, "Unable to query for the CAN. Aborting."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + } + } + + /* Establish secure channel via PACE */ + memset(&pace_input, 0, sizeof pace_input); + memset(&pace_output, 0, sizeof pace_output); + + pace_input.pin_id = ref; + pace_input.pin = pin; + pace_input.pin_length = pinlen; + + /* Select the right application for authentication. */ + r = dtrust_select_app(card, ref); + LOG_TEST_RET(card->ctx, r, "Selecting application failed"); + + r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); + + free(pace_output.ef_cardaccess); + free(pace_output.recent_car); + free(pace_output.previous_car); + free(pace_output.id_icc); + free(pace_output.id_pcd); + + if (tries_left != NULL) { + if (r != SC_SUCCESS && + pace_output.mse_set_at_sw1 == 0x63 && + (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) { + *tries_left = pace_output.mse_set_at_sw2 & 0x0f; + } else { + *tries_left = -1; + } + } + + /* TODO: Put CAN into the cache if necessary. */ + + return r; +} + +static int +dtrust_pin_cmd_get_info(struct sc_card *card, + struct sc_pin_cmd_data *data, + int *tries_left) +{ + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + switch (data->pin_reference) { + case PACE_PIN_ID_CAN: + /* unlimited number of retries */ + *tries_left = -1; + data->pin1.max_tries = -1; + data->pin1.tries_left = -1; + r = SC_SUCCESS; + break; + + case PACE_PIN_ID_PUK: + case DTRUST5_PIN_ID_PIN_T: + case DTRUST5_PIN_ID_PIN_T_AUT: + /* Select the right application for authentication. */ + r = dtrust_select_app(card, data->pin_reference); + LOG_TEST_RET(card->ctx, r, "Selecting application failed"); + + /* FIXME: Doesn't work. Returns SW1=69 SW2=85 (Conditions of use not satisfied) instead. */ + data->pin1.max_tries = 3; + r = eac_pace_get_tries_left(card, data->pin_reference, &data->pin1.tries_left); + if (tries_left != NULL) { + *tries_left = data->pin1.tries_left; + } + break; + + default: + /* Check if a secure channel exists. + * FIXME: This won't work for readers handling the secure + * channel transparently. */ + if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { + /* We need to establish a secure channel to query PIN information. */ + r = dtrust_perform_pace(card, PACE_PIN_ID_CAN, NULL, 0, NULL); + LOG_TEST_RET(card->ctx, r, "CAN authentication failed"); + + /* Select the right application again. */ + r = dtrust_select_app(card, data->pin_reference); + LOG_TEST_RET(card->ctx, r, "Selecting application failed"); + } + + /* Now query PIN information */ + r = iso_ops->pin_cmd(card, data, tries_left); + break; + } + + LOG_FUNC_RETURN(card->ctx, r); +} + +static int +dtrust_pin_cmd_verify(struct sc_card *card, + struct sc_pin_cmd_data *data, + int *tries_left) +{ + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + switch (data->pin_reference) { + /* When the retry counter reaches 1 PACE-PINs become suspended. Before + * verifying a suspended PIN, the CAN has to verified. We go without + * verifying the CAN here, as this only matters for the PUK and the + * transport PIN. Neither PIN ist required during normal operation. The + * user has to resume a suspended PIN using dtrust-tool which manages + * CAN authentication. */ + case PACE_PIN_ID_CAN: + case PACE_PIN_ID_PUK: + case DTRUST5_PIN_ID_PIN_T: + case DTRUST5_PIN_ID_PIN_T_AUT: + /* Establish secure channel via PACE */ + r = dtrust_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, tries_left); + break; + + default: + /* Check if a secure channel exists. + * FIXME: This wouldn't work for readers handling the secure + * channel transparently. */ + if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { + /* We need to establish a secure channel to verify the PINs. */ + r = dtrust_perform_pace(card, PACE_PIN_ID_CAN, NULL, 0, NULL); + LOG_TEST_RET(card->ctx, r, "CAN authentication failed"); + + /* Select the right application again. */ + r = dtrust_select_app(card, data->pin_reference); + LOG_TEST_RET(card->ctx, r, "Selecting application failed"); + } + + /* Now verify the PIN */ + r = iso_ops->pin_cmd(card, data, tries_left); + + break; + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static int dtrust_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, @@ -339,33 +554,25 @@ dtrust_pin_cmd(struct sc_card *card, if (!data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - /* Upper layers may try to verify the PIN twice, first with PIN type - * SC_AC_CHV and then with PIN type SC_AC_CONTEXT_SPECIFIC. For the - * second attempt we first check by SC_PIN_CMD_GET_INFO whether a - * second PIN authentication is still necessary. If not, we simply - * return without a second verification attempt. Otherwise we perform - * the verification as requested. This only matters for pin pad readers - * to prevent the user from prompting the PIN twice. */ - if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { - struct sc_pin_cmd_data data2; - - memset(&data2, 0, sizeof(struct sc_pin_cmd_data)); - data2.pin_reference = data->pin_reference; - data2.pin1 = data->pin1; - - /* Check verification state */ - data2.cmd = SC_PIN_CMD_GET_INFO; - data2.pin_type = data->pin_type; - r = iso_ops->pin_cmd(card, &data2, tries_left); - - if (data2.pin1.logged_in == SC_PIN_STATE_LOGGED_IN) { - /* Return if we are already authenticated */ - data->pin1 = data2.pin1; - LOG_FUNC_RETURN(card->ctx, r); - } + /* No special handling for D-Trust Card 4.1/4.4 */ + if (card->type >= SC_CARD_TYPE_DTRUST_V4_1_STD && card->type <= SC_CARD_TYPE_DTRUST_V4_4_MULTI) { + r = iso_ops->pin_cmd(card, data, tries_left); + LOG_FUNC_RETURN(card->ctx, r); + } + + switch (data->cmd) { + case SC_PIN_CMD_GET_INFO: + r = dtrust_pin_cmd_get_info(card, data, tries_left); + break; + + case SC_PIN_CMD_VERIFY: + r = dtrust_pin_cmd_verify(card, data, tries_left); + break; + + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - r = iso_ops->pin_cmd(card, data, tries_left); LOG_FUNC_RETURN(card->ctx, r); } @@ -568,11 +775,22 @@ dtrust_decipher(struct sc_card *card, const u8 *data, static int dtrust_logout(sc_card_t *card) { - sc_path_t path; + struct sc_apdu apdu; int r; - sc_format_path("3F00", &path); - r = sc_select_file(card, &path, NULL); + sc_sm_stop(card); + + if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { + /* If PACE is done between reader and card, SM is transparent to us as + * it ends at the reader. With CLA=0x0C we provoke a SM error to + * disable SM on the reader. */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x00, 0x00); + apdu.cla = 0x0C; + if (SC_SUCCESS != sc_transmit_apdu(card, &apdu)) + sc_log(card->ctx, "Warning: Could not logout."); + } + + r = sc_select_file(card, sc_get_mf_path(), NULL); return r; } diff --git a/src/libopensc/card-dtrust.h b/src/libopensc/card-dtrust.h new file mode 100644 index 0000000000..221bf7ce55 --- /dev/null +++ b/src/libopensc/card-dtrust.h @@ -0,0 +1,29 @@ +/* + * card-dtrust.h: Support for (CardOS based) D-Trust Signature Cards + * + * Copyright (C) 2024 Mario Haustein + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CARD_DTRUST_H +#define _CARD_DTRUST_H + +#define DTRUST5_PIN_ID_PIN_T 0x0b +#define DTRUST5_PIN_ID_PIN_T_AUT 0x0c +#define DTRUST5_PIN_ID_QES 0x87 +#define DTRUST5_PIN_ID_AUT 0x91 + +#endif From 60d8cab6fa957bc3110df10d7ad3a39670007dad Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 11:11:39 +0100 Subject: [PATCH 3934/4321] dtrust: Implement CAN tracking for PACE-capable readers --- src/libopensc/card-dtrust.c | 67 ++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 5be896b30d..6aaca678e5 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -49,8 +49,10 @@ static struct sc_card_driver dtrust_drv = { }; // clang-format on -/* internal structure to save the current security environment */ struct dtrust_drv_data_t { + /* track PACE state */ + unsigned char can : 1; + /* save the current security environment */ const sc_security_env_t *env; }; @@ -239,6 +241,7 @@ _dtrust_get_serialnr(sc_card_t *card) static int dtrust_init(sc_card_t *card) { + struct dtrust_drv_data_t *drv_data; int r; const size_t data_field_length = 437; unsigned long flags, ext_flags; @@ -247,10 +250,13 @@ dtrust_init(sc_card_t *card) card->cla = 0x00; - card->drv_data = calloc(1, sizeof(struct dtrust_drv_data_t)); - if (card->drv_data == NULL) + drv_data = calloc(1, sizeof(struct dtrust_drv_data_t)); + if (drv_data == NULL) return SC_ERROR_OUT_OF_MEMORY; + drv_data->can = 0; + card->drv_data = drv_data; + r = _dtrust_get_serialnr(card); LOG_TEST_RET(card->ctx, r, "Error reading serial number."); @@ -375,12 +381,15 @@ dtrust_perform_pace(struct sc_card *card, size_t pinlen, int *tries_left) { + struct dtrust_drv_data_t *drv_data; int r; struct establish_pace_channel_input pace_input; struct establish_pace_channel_output pace_output; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; + /* The PKCS#11 layer cannot provide a CAN. Instead we consider the * following sources for CAN input. * 1. A CAN provided by the caller @@ -419,6 +428,15 @@ dtrust_perform_pace(struct sc_card *card, r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); + /* We need to track whether we established a PACE channel with CAN. + * Checking against card->sm_ctx.sm_mode != SM_MODE_TRANSMIT is not + * sufficient as PACE-capable card readers handle secure messaging + * transparently and authenticating against non-CAN-PINs doesn't allow + * us to verify the QES or AUT-PIN. */ + if (ref == PACE_PIN_ID_CAN) { + drv_data->can = r == SC_SUCCESS; + } + free(pace_output.ef_cardaccess); free(pace_output.recent_car); free(pace_output.previous_car); @@ -445,10 +463,13 @@ dtrust_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) { + struct dtrust_drv_data_t *drv_data; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; + switch (data->pin_reference) { case PACE_PIN_ID_CAN: /* unlimited number of retries */ @@ -474,11 +495,9 @@ dtrust_pin_cmd_get_info(struct sc_card *card, break; default: - /* Check if a secure channel exists. - * FIXME: This won't work for readers handling the secure - * channel transparently. */ - if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - /* We need to establish a secure channel to query PIN information. */ + /* Check if CAN authentication is necessary */ + if (!drv_data->can) { + /* Establish a secure channel with CAN to query PIN information. */ r = dtrust_perform_pace(card, PACE_PIN_ID_CAN, NULL, 0, NULL); LOG_TEST_RET(card->ctx, r, "CAN authentication failed"); @@ -500,10 +519,13 @@ dtrust_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) { + struct dtrust_drv_data_t *drv_data; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; + switch (data->pin_reference) { /* When the retry counter reaches 1 PACE-PINs become suspended. Before * verifying a suspended PIN, the CAN has to verified. We go without @@ -520,11 +542,9 @@ dtrust_pin_cmd_verify(struct sc_card *card, break; default: - /* Check if a secure channel exists. - * FIXME: This wouldn't work for readers handling the secure - * channel transparently. */ - if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - /* We need to establish a secure channel to verify the PINs. */ + /* Check if CAN authentication is necessary */ + if (!drv_data->can) { + /* Establish a secure channel with CAN to to verify the PINs. */ r = dtrust_perform_pace(card, PACE_PIN_ID_CAN, NULL, 0, NULL); LOG_TEST_RET(card->ctx, r, "CAN authentication failed"); @@ -775,24 +795,33 @@ dtrust_decipher(struct sc_card *card, const u8 *data, static int dtrust_logout(sc_card_t *card) { - struct sc_apdu apdu; + struct dtrust_drv_data_t *drv_data; int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + drv_data = card->drv_data; + sc_sm_stop(card); + drv_data->can = 0; + /* If PACE is done between reader and card, SM is transparent to us as + * it ends at the reader. With CLA=0x0C we provoke a SM error to + * disable SM on the reader. */ if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { - /* If PACE is done between reader and card, SM is transparent to us as - * it ends at the reader. With CLA=0x0C we provoke a SM error to - * disable SM on the reader. */ + struct sc_apdu apdu; + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x00, 0x00); apdu.cla = 0x0C; - if (SC_SUCCESS != sc_transmit_apdu(card, &apdu)) + + r = sc_transmit_apdu(card, &apdu); + if (r != SC_SUCCESS) sc_log(card->ctx, "Warning: Could not logout."); } r = sc_select_file(card, sc_get_mf_path(), NULL); - return r; + LOG_FUNC_RETURN(card->ctx, r); } struct sc_card_driver * From f5f6d42a001aa43edb565abdc38cfb70c1022ac8 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 11:13:15 +0100 Subject: [PATCH 3935/4321] dtrust: Prevent unnecessary PIN prompts on pin pad readers closes #2244 --- src/libopensc/card-dtrust.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 6aaca678e5..86b411ee60 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -574,6 +574,38 @@ dtrust_pin_cmd(struct sc_card *card, if (!data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + /* Upper layers may try to verify the PIN twice, first with PIN type + * SC_AC_CHV and then with PIN type SC_AC_CONTEXT_SPECIFIC. For the + * second attempt we first check by SC_PIN_CMD_GET_INFO whether a + * second PIN authentication is still necessary. If not, we simply + * return without a second verification attempt. Otherwise we perform + * the verification as requested. This only matters for pin pad readers + * to prevent the user from prompting the PIN twice. */ + if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { + struct sc_pin_cmd_data data2; + + sc_log(card->ctx, "Checking if verification of PIN 0x%02x is necessary.", data->pin_reference); + + memset(&data2, 0, sizeof(struct sc_pin_cmd_data)); + data2.pin_reference = data->pin_reference; + data2.pin1 = data->pin1; + + /* Check verification state */ + data2.cmd = SC_PIN_CMD_GET_INFO; + data2.pin_type = data->pin_type; + r = dtrust_pin_cmd(card, &data2, tries_left); + + if (data2.pin1.logged_in == SC_PIN_STATE_LOGGED_IN) { + /* Return if we are already authenticated */ + sc_log(card->ctx, "PIN 0x%02x already verified. Skipping authentication.", data->pin_reference); + + data->pin1 = data2.pin1; + LOG_FUNC_RETURN(card->ctx, r); + } + + sc_log(card->ctx, "Additional verification of PIN 0x%02x is necessary.", data->pin_reference); + } + /* No special handling for D-Trust Card 4.1/4.4 */ if (card->type >= SC_CARD_TYPE_DTRUST_V4_1_STD && card->type <= SC_CARD_TYPE_DTRUST_V4_4_MULTI) { r = iso_ops->pin_cmd(card, data, tries_left); From 3492432c5dc202804467841937689421dcf80eb8 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 21:45:54 +0100 Subject: [PATCH 3936/4321] dtrust: Add support timeline for different D-Trust products --- src/libopensc/card-dtrust.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 86b411ee60..cf83f72fa1 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -20,6 +20,19 @@ * based on card-cardos.c */ +/* + * This are the support periods for the D-Trust cards. The end of life time is + * set by the expiry of the underlying card operating system and sets the + * validity limit of the issued certificates. After end of life, the code paths + * for the affected products may be removed, as the cards are then not useful + * anymore. + * + * Start of Sales End of Sales End of life + * D-Trust Card 4.1/4.4 n/a Nov 2024 Sep 2026 + * D-Trust Card 5.1/5.4 Nov 2023 n/a Oct 2028 + * D-Trust Card 6.1/6.4 Summer 2025 n/a n/a + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif From 3c8f8b12fbb9949004b505715ab67f4e06cdd2d2 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 21:46:32 +0100 Subject: [PATCH 3937/4321] dtrust: Add SEID for D-Trust 5.1/5.4 ECDSA signatures --- src/libopensc/card-dtrust.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index cf83f72fa1..73fe139966 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -731,7 +731,24 @@ dtrust_set_security_env(sc_card_t *card, return SC_ERROR_NOT_SUPPORTED; } } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { - se_num = 0x21; + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + /* ECDSA on SHA-256 hashes. Other hashes will work though. */ + se_num = 0x21; + break; + + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + /* ECDSA on SHA-384 hashes. Other hashes will work though. */ + se_num = 0x22; + break; + + default: + return SC_ERROR_NOT_SUPPORTED; + } } else { return SC_ERROR_NOT_SUPPORTED; } From 399a7f56d714bb31aed56a8d4860b89bbf4002a9 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Fri, 22 Nov 2024 17:55:34 +0100 Subject: [PATCH 3938/4321] dtrust: Implement PIN change and retry counter reset for D-Trust Card 5.1/5.4 --- src/libopensc/card-dtrust.c | 57 +++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 73fe139966..55c0de5712 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -64,6 +64,7 @@ static struct sc_card_driver dtrust_drv = { struct dtrust_drv_data_t { /* track PACE state */ + unsigned char pace : 1; unsigned char can : 1; /* save the current security environment */ const sc_security_env_t *env; @@ -267,6 +268,7 @@ dtrust_init(sc_card_t *card) if (drv_data == NULL) return SC_ERROR_OUT_OF_MEMORY; + drv_data->pace = 0; drv_data->can = 0; card->drv_data = drv_data; @@ -441,11 +443,15 @@ dtrust_perform_pace(struct sc_card *card, r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); - /* We need to track whether we established a PACE channel with CAN. - * Checking against card->sm_ctx.sm_mode != SM_MODE_TRANSMIT is not - * sufficient as PACE-capable card readers handle secure messaging - * transparently and authenticating against non-CAN-PINs doesn't allow - * us to verify the QES or AUT-PIN. */ + /* We need to track whether we established a PACE channel. Checking + * against card->sm_ctx.sm_mode != SM_MODE_TRANSMIT is not sufficient + * as PACE-capable card readers handle secure messaging transparently. */ + if (r == SC_SUCCESS) { + drv_data->pace = 1; + } + + /* We further need to track whether we authenticated against CAN as + * only this PINs allows us to verify the QES or AUT-PIN. */ if (ref == PACE_PIN_ID_CAN) { drv_data->can = r == SC_SUCCESS; } @@ -580,10 +586,13 @@ dtrust_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) { + struct dtrust_drv_data_t *drv_data; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; + if (!data) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -634,6 +643,43 @@ dtrust_pin_cmd(struct sc_card *card, r = dtrust_pin_cmd_verify(card, data, tries_left); break; + case SC_PIN_CMD_CHANGE: + /* The card requires a secure channel to change the PIN. + * Although we could return the error code of the card, we + * prevent to send the APDU in case no secure channel was + * established. This prevents us from exposing our new PIN + * inadvertently in plaintext over the contactless interface in + * case of a software error in the upper layers. */ + if (!drv_data->pace) { + sc_log(card->ctx, "Secure channel required for PIN change"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED); + } + + if (data->pin1.len != 0 || !(data->flags & SC_PIN_CMD_IMPLICIT_CHANGE)) { + sc_log(card->ctx, "Card supports implicit PIN change only"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + if (data->pin2.len == 0 && !(data->flags & SC_PIN_CMD_USE_PINPAD)) { + sc_log(card->ctx, "No value provided for the new PIN"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + r = iso_ops->pin_cmd(card, data, tries_left); + break; + + case SC_PIN_CMD_UNBLOCK: + /* The supports only to reset the retry counter to its default + * value, but not to set verify or set a PIN. */ + if (data->pin1.len != 0 || data->pin2.len != 0 || + data->flags & SC_PIN_CMD_USE_PINPAD) { + sc_log(card->ctx, "Card supports retry counter reset only"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + r = iso_ops->pin_cmd(card, data, tries_left); + break; + default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -865,6 +911,7 @@ dtrust_logout(sc_card_t *card) drv_data = card->drv_data; sc_sm_stop(card); + drv_data->pace = 0; drv_data->can = 0; /* If PACE is done between reader and card, SM is transparent to us as From 8100c089b819bae0e50394c04d4719910d8e29c3 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 27 Nov 2024 23:11:44 +0100 Subject: [PATCH 3939/4321] dtrust: Read CAN from environment or config file --- doc/files/files.html | 13 ++++++++- doc/files/opensc.conf.5.xml.in | 29 ++++++++++++++++++++ src/libopensc/card-dtrust.c | 48 +++++++++++++++++++++++++++++++--- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index c01b2d55ec..cb97e3f112 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -239,6 +239,8 @@ eoi: See the section called “Configuration Options for Slovenian eID Cardâ€

  • myeid: See the section called “Configuration Options for MyEID Card†+

  • + dtrust: See the section called “Configuration Options for D-Trust Signature Cardsâ€

  • Any other value: Configuration block for an externally loaded card driver

  • @@ -551,7 +553,16 @@ (in encrypted form) it can be used to automatically establish secure connection, but only if the card is accessed over the contact interface. -

    Configuration Options for PIV Card

    Configuration based on ATR

    +

    Configuration Options for D-Trust Signature Cards

    + can = value; +

    + CAN (Card Access Number – 6 digit number printed on the front side of + the card) is required to establish connection with the card. It might + be overwritten by DTRUST_CAN environment variable. + If not specified here, the CAN will be read from a card specific cache, + prompted on the card readers PIN pad or prompted interactively in the + following order. +

    1. Environment variable DTRUST_CAN

    2. This configuration file option

    3. Pin pad of a PACE-capable card reader

    Configuration Options for PIV Card

    Configuration based on ATR

    atrmask = hexstring;

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index e4c0c4acea..56a7e550c2 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -302,6 +302,9 @@ app application { myeid: See + + dtrust: See + Any other value: Configuration block for an externally loaded card driver @@ -824,6 +827,32 @@ app application { + + Configuration Options for D-Trust Signature Cards + + + + + + + + CAN (Card Access Number – 6 digit number printed on the front side of + the card) is required to establish connection with the card. It might + be overwritten by DTRUST_CAN environment variable. + If not specified here, the CAN will be read from a card specific cache, + prompted on the card readers PIN pad or prompted interactively in the + following order. + + + Environment variable DTRUST_CAN + This configuration file option + Pin pad of a PACE-capable card reader + + + + + + Configuration Options for PIV Card diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 55c0de5712..3fc8884c00 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -66,6 +66,8 @@ struct dtrust_drv_data_t { /* track PACE state */ unsigned char pace : 1; unsigned char can : 1; + /* global CAN from configuration file */ + const char *can_value; /* save the current security environment */ const sc_security_env_t *env; }; @@ -256,6 +258,9 @@ static int dtrust_init(sc_card_t *card) { struct dtrust_drv_data_t *drv_data; + const char *can_env = NULL; + size_t i, j; + scconf_block **found_blocks, *block; int r; const size_t data_field_length = 437; unsigned long flags, ext_flags; @@ -270,6 +275,32 @@ dtrust_init(sc_card_t *card) drv_data->pace = 0; drv_data->can = 0; + drv_data->can_value = NULL; + + drv_data->can_value = can_env = getenv("DTRUST_CAN"); + if (can_env != NULL) { + sc_log(card->ctx, "Using CAN provided by environment variable."); + } + + /* read configuration */ + for (i = 0; card->ctx->conf_blocks[i]; i++) { + found_blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], "card_driver", "dtrust"); + if (!found_blocks) + continue; + + for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { + /* Environment variable has precedence over configured CAN */ + if (can_env == NULL) { + drv_data->can_value = scconf_get_str(block, "can", drv_data->can_value); + } + } + free(found_blocks); + } + + if (can_env == NULL && drv_data->can_value != NULL) { + sc_log(card->ctx, "Using CAN provided by configuration file."); + } + card->drv_data = drv_data; r = _dtrust_get_serialnr(card); @@ -408,11 +439,22 @@ dtrust_perform_pace(struct sc_card *card, /* The PKCS#11 layer cannot provide a CAN. Instead we consider the * following sources for CAN input. * 1. A CAN provided by the caller - * 2. A cached CAN when the cache feature is enabled - * 3. If the reader supports the PACE protocol, we let it query for a + * 2. A CAN provided in the environment variable DTRUST_CAN + * 3. A CAN provided in the configuration file + * 4. A cached CAN when the cache feature is enabled + * 5. If the reader supports the PACE protocol, we let it query for a * CAN on the pin pad. - * 4. Querying the user interactively if possible */ + * 6. Querying the user interactively if possible */ if (ref == PACE_PIN_ID_CAN) { + /* Use CAN from environment variable or configuration file */ + if (pin == NULL) { + pin = (const unsigned char *)drv_data->can_value; + if (pin != NULL) { + sc_log(card->ctx, "Using static CAN (environment variable/configuration file)."); + pinlen = strlen(drv_data->can_value); + } + } + /* TODO: Query the CAN cache if no CAN is provided by the caller. */ if (pin == NULL) { From 4161ccb080ebdf19edbe9c18d6c4d21f64624a68 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sun, 24 Nov 2024 14:55:02 +0100 Subject: [PATCH 3940/4321] dtrust-tool: Reorder options in manpage according to getopt help text --- doc/tools/dtrust-tool.1.xml | 87 ++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index d3e67a7576..c8dca40d66 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -34,6 +34,42 @@ Options + + + arg, + arg + + + Number of the reader to use. By default, the first reader with a + present card is used. If arg is an ATR, the + reader with a matching card will be chosen. + + + + + , + + + + Causes dtrust-tool to wait for the token to be + inserted into reader. + + + + + , + + + + Show the status of the various PINs. The Card Holder PIN is used for + advanced signatures and decryption. It is only defined for signature + cards, but not for sealing cards. The signature PIN is used for + qualified signatures. It can only be used if it is unlocked by + presenting the Transport PIN. Once the Transport PIN is used, it cannot + be used anymore. The PUK is used to unlock PIN which had beend entered + incorrectly several times. + + , @@ -64,46 +100,20 @@ - , - - - Print help message on screen. - - - - arg, - arg + , + - Number of the reader to use. By default, the first reader with a - present card is used. If arg is an ATR, the - reader with a matching card will be chosen. + This command removes the transport protection. It first queries the + Transport PIN and then the new value of the Signature PIN twice. - , - - - - Show the status of the various PINs. The Card Holder PIN is used for - advanced signatures and decryption. It is only defined for signature - cards, but not for sealing cards. The signature PIN is used for - qualified signatures. It can only be used if it is unlocked by - presenting the Transport PIN. Once the Transport PIN is used, it cannot - be used anymore. The PUK is used to unlock PIN which had beend entered - incorrectly several times. - - - - - , - + , + - - This command removes the transport protection. If first queries for the - Transport PIN and then for the new value of the Signature PIN twice. - + Print help message on screen. @@ -115,20 +125,9 @@ flag several times to enable debug output in the opensc library. - - - , - - - - Causes dtrust-tool to wait for the token to be - inserted into reader. - - - Authors dtrust-tool was written by From 7d55686cae490f836cd7e1c09de7e2138d0bd48b Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 18:05:21 +0100 Subject: [PATCH 3941/4321] dtrust-tool: Refactor PIN entry logic --- src/tools/dtrust-tool.c | 104 ++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index b29e16697a..942cd03b83 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -61,6 +61,62 @@ static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; +int +get_pin(char **pin, const char *label, unsigned char check) +{ + int r; + char *pin2 = NULL; + size_t len1 = 0; + size_t len2 = 0; + + r = -1; + + if (pin == NULL) + return -1; + + *pin = NULL; + + printf("Enter %s:", label); + r = util_getpass(pin, &len1, stdin); + if (r < 0 || *pin == NULL) { + fprintf(stderr, "Unable to get PIN"); + goto fail; + } + + if (!check) + return 0; + + printf("Enter %s again:", label); + r = util_getpass(&pin2, &len2, stdin); + if (r < 0 || pin2 == NULL) { + fprintf(stderr, "Unable to get PIN"); + goto fail; + } + + r = strcmp(*pin, pin2); + if (r) + fprintf(stderr, "PINs doesn't match.\n"); + + /* Free repeated PIN in any case. */ + if (pin2 != NULL) { + sc_mem_clear(pin2, len2); + free(pin2); + } + + if (r == 0) + return 0; + +fail: + /* Free PIN only in case of an error. */ + if (*pin != NULL) { + sc_mem_clear(*pin, len1); + free(*pin); + *pin = NULL; + } + + return -1; +} + void pin_status(sc_card_t *card, int ref, const char *pin_label) { @@ -134,11 +190,7 @@ unlock_transport_protection(sc_card_t *card) struct sc_pin_cmd_data data; int r; char *tpin = NULL; - char *qespin1 = NULL; - char *qespin2 = NULL; - size_t tpin_len = 0; - size_t qespin1_len = 0; - size_t qespin2_len = 0; + char *qespin = NULL; int tries_left; memset(&data, 0, sizeof(data)); @@ -156,35 +208,18 @@ unlock_transport_protection(sc_card_t *card) data.pin2.prompt = "Enter Signature PIN"; data.flags |= SC_PIN_CMD_USE_PINPAD; } else { - printf("Enter Transport PIN:"); - r = util_getpass(&tpin, &tpin_len, stdin); - if (r < 0 || tpin == NULL) { - fprintf(stderr, "Unable to get PIN"); - return; - } - - printf("Enter new Signature PIN:"); - r = util_getpass(&qespin1, &qespin1_len, stdin); - if (r < 0 || qespin1 == NULL) { - fprintf(stderr, "Unable to get PIN"); + r = get_pin(&tpin, "Transport PIN", 0); + if (r < 0) goto fail; - } - printf("Enter new Signature PIN again:"); - r = util_getpass(&qespin2, &qespin1_len, stdin); - if (r < 0 || qespin2 == NULL) { - fprintf(stderr, "Unable to get PIN"); + r = get_pin(&qespin, "new Signature PIN", 1); + if (r < 0) goto fail; - } - if (strcmp(qespin1, qespin2)) { - fprintf(stderr, "New signature PINs doesn't match.\n"); - goto fail; - } data.pin1.data = (u8 *)tpin; data.pin1.len = strlen(tpin); - data.pin2.data = (u8 *)qespin1; - data.pin2.len = strlen(qespin1); + data.pin2.data = (u8 *)qespin; + data.pin2.len = strlen(qespin); } r = sc_pin_cmd(card, &data, &tries_left); @@ -197,18 +232,13 @@ unlock_transport_protection(sc_card_t *card) printf("Can't change pin: %s\n", sc_strerror(r)); fail: - if (qespin2 != NULL) { - sc_mem_clear(qespin2, qespin2_len); - free(qespin2); - } - - if (qespin1 != NULL) { - sc_mem_clear(qespin1, qespin1_len); - free(qespin1); + if (qespin != NULL) { + sc_mem_clear(qespin, strlen(qespin)); + free(qespin); } if (tpin != NULL) { - sc_mem_clear(tpin, tpin_len); + sc_mem_clear(tpin, strlen(tpin)); free(tpin); } } From 76beee5f5c03c82a5e34d3d72f3e2eff7505f0d9 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 18:12:52 +0100 Subject: [PATCH 3942/4321] dtrust-tool: Establish PACE channel for D-Trust Card 5 --- doc/tools/dtrust-tool.1.xml | 23 ++++++++++++++++ src/tools/Makefile.am | 2 ++ src/tools/dtrust-tool.c | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index c8dca40d66..e1189ce508 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -55,6 +55,29 @@ inserted into reader. + + + , + + + + D-Trust Card 5 comes with a Card Access Number (CAN) printed + onto the card. The purpose of this number is to establish a + secure communication channel between the card and the card + reader. In normal operation dtrust-tool + automatically prompts for the CAN. + + + In case you entered a transport PIN wrong two times, the + transport PIN becomes suspended. You need this parameter + together with to + resume the suspended transport PIN for a last attempt. Failing + to enter the transport PIN successfully blocks the transport + PIN. You then need to unblock the transport PIN with + . + + + , diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b175c95aa9..d2bd4c614b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -141,6 +141,8 @@ goid_tool_CFLAGS += -Wno-shorten-64-to-32 endif dtrust_tool_SOURCES = dtrust-tool.c util.c +dtrust_tool_LDADD = $(OPENPACE_LIBS) +dtrust_tool_CFLAGS = $(OPENPACE_CFLAGS) opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c opensc_asn1_CFLAGS = diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 942cd03b83..5fea457a12 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -28,14 +28,20 @@ #include "libopensc/cards.h" #include "libopensc/errors.h" +#include "sm/sm-eac.h" #include "util.h" static const char *app_name = "dtrust-tool"; +enum { + OPT_CAN_VERIFY = 0x100, +}; + // clang-format off static const struct option options[] = { {"reader", 1, NULL, 'r'}, {"wait", 0, NULL, 'w'}, + {"verify-can", 0, NULL, OPT_CAN_VERIFY}, {"pin-status", 0, NULL, 's'}, {"check-transport-protection", 0, NULL, 'c'}, {"unlock-transport-protection", 0, NULL, 'u'}, @@ -47,6 +53,7 @@ static const struct option options[] = { static const char *option_help[] = { "Uses reader number [0]", "Wait for card insertion", + "Verify Card Access Number (CAN)", "Show PIN status", "Check transport protection", "Unlock transport protection", @@ -57,6 +64,7 @@ static const char *option_help[] = { static const char *opt_reader = NULL; static int opt_wait = 0, verbose = 0; +static unsigned char opt_can_verify = 0; static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; @@ -247,6 +255,7 @@ int main(int argc, char *argv[]) { int r, c, long_optind = 0; + char *can = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; @@ -268,6 +277,9 @@ main(int argc, char *argv[]) case 'w': opt_wait = 1; break; + case OPT_CAN_VERIFY: + opt_can_verify = 1; + break; case 's': opt_status = 1; break; @@ -306,6 +318,43 @@ main(int argc, char *argv[]) if (r) goto out; + if (opt_status || opt_check) + opt_can_verify = 1; + + /* D-Trust Card 5 requires PACE authentication with CAN */ + if (opt_can_verify && + card->type >= SC_CARD_TYPE_DTRUST_V5_1_STD && + card->type <= SC_CARD_TYPE_DTRUST_V5_4_MULTI) { + struct sc_pin_cmd_data data; + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_VERIFY; + data.pin_type = SC_AC_CHV; + data.pin_reference = PACE_PIN_ID_CAN; + + if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { + data.pin1.data = NULL; + data.pin1.len = 0; + } else { + r = get_pin(&can, "CAN", 0); + if (r < 0) + goto out; + + data.pin1.data = (const unsigned char *)can; + data.pin1.len = strlen(can); + } + + r = sc_select_file(card, sc_get_mf_path(), NULL); + if (r) + goto out; + + r = sc_pin_cmd(card, &data, NULL); + if (r) { + fprintf(stderr, "Error verifying CAN.\n"); + goto out; + } + } + /* * We have to select the QES app to verify and change the QES PIN. */ @@ -336,6 +385,11 @@ main(int argc, char *argv[]) } out: + if (can != NULL) { + sc_mem_clear(can, strlen(can)); + free(can); + } + if (card) { sc_unlock(card); sc_disconnect_card(card); From 614a69e11f90a6f2d7877098a6ea5a96bfd95fbe Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 18:39:08 +0100 Subject: [PATCH 3943/4321] dtrust-tool: Use symbolic names for PIN IDs --- src/libopensc/card-dtrust.h | 4 ++++ src/tools/dtrust-tool.c | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-dtrust.h b/src/libopensc/card-dtrust.h index 221bf7ce55..f435883834 100644 --- a/src/libopensc/card-dtrust.h +++ b/src/libopensc/card-dtrust.h @@ -21,6 +21,10 @@ #ifndef _CARD_DTRUST_H #define _CARD_DTRUST_H +#define DTRUST4_PIN_ID_PIN_CH 0x03 +#define DTRUST4_PIN_ID_PUK_CH 0x04 +#define DTRUST4_PIN_ID_PIN_T 0x0b +#define DTRUST4_PIN_ID_QES 0x87 #define DTRUST5_PIN_ID_PIN_T 0x0b #define DTRUST5_PIN_ID_PIN_T_AUT 0x0c #define DTRUST5_PIN_ID_QES 0x87 diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 5fea457a12..92dd45914c 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -25,6 +25,7 @@ #include "libopensc/opensc.h" +#include "libopensc/card-dtrust.h" #include "libopensc/cards.h" #include "libopensc/errors.h" @@ -204,7 +205,7 @@ unlock_transport_protection(sc_card_t *card) memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_CHANGE; data.pin_type = SC_AC_CHV; - data.pin_reference = 0x87; + data.pin_reference = DTRUST4_PIN_ID_QES; data.pin1.min_length = 5; data.pin1.max_length = 5; data.pin2.min_length = 6; @@ -367,10 +368,12 @@ main(int argc, char *argv[]) if (card->type == SC_CARD_TYPE_DTRUST_V4_1_STD || card->type == SC_CARD_TYPE_DTRUST_V4_1_MULTI || card->type == SC_CARD_TYPE_DTRUST_V4_1_M100) - pin_status(card, 0x03, "Card Holder PIN"); - pin_status(card, 0x04, "Card Holder PUK"); - pin_status(card, 0x87, "Signature PIN"); - pin_status(card, 0x8B, "Transport PIN"); + pin_status(card, DTRUST4_PIN_ID_PIN_CH, "Card Holder PIN"); + pin_status(card, DTRUST4_PIN_ID_PUK_CH, "Card Holder PUK"); + pin_status(card, DTRUST4_PIN_ID_QES, "Signature PIN"); + + /* According to the spec, the local bit has to be set. */ + pin_status(card, 0x80 | DTRUST4_PIN_ID_PIN_T, "Transport PIN"); } if (opt_check) From 684ac427f8cc22f61a473d4080d64793ec6b4b73 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 18:41:05 +0100 Subject: [PATCH 3944/4321] dtrust-tool: Show PIN status for D-Trust Card 5 --- src/tools/dtrust-tool.c | 71 ++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 92dd45914c..83b633abdb 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -356,24 +356,65 @@ main(int argc, char *argv[]) } } - /* - * We have to select the QES app to verify and change the QES PIN. - */ - sc_format_path("3F000101", &path); - r = sc_select_file(card, &path, NULL); - if (r) - goto out; - if (opt_status) { - if (card->type == SC_CARD_TYPE_DTRUST_V4_1_STD || - card->type == SC_CARD_TYPE_DTRUST_V4_1_MULTI || - card->type == SC_CARD_TYPE_DTRUST_V4_1_M100) + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: pin_status(card, DTRUST4_PIN_ID_PIN_CH, "Card Holder PIN"); - pin_status(card, DTRUST4_PIN_ID_PUK_CH, "Card Holder PUK"); - pin_status(card, DTRUST4_PIN_ID_QES, "Signature PIN"); + /* fall through */ + + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + /* We have to select the QES app to verify and change the Signature PIN. */ + sc_format_path("3F000101", &path); + r = sc_select_file(card, &path, NULL); + if (r) + goto out; + + pin_status(card, DTRUST4_PIN_ID_PUK_CH, "Card Holder PUK"); + pin_status(card, DTRUST4_PIN_ID_QES, "Signature PIN"); + + /* According to the spec, the local bit has to be set. */ + pin_status(card, 0x80 | DTRUST4_PIN_ID_PIN_T, "Transport PIN"); + break; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + r = sc_select_file(card, sc_get_mf_path(), NULL); + if (r) + goto out; + + pin_status(card, DTRUST5_PIN_ID_PIN_T_AUT, "Transport PIN (Authentication)"); - /* According to the spec, the local bit has to be set. */ - pin_status(card, 0x80 | DTRUST4_PIN_ID_PIN_T, "Transport PIN"); + /* We have to select the eSign app to verify and change the Authentication PIN. */ + sc_format_path("3F000102", &path); + r = sc_select_file(card, &path, NULL); + if (r) + goto out; + + pin_status(card, DTRUST5_PIN_ID_AUT, "Authentication PIN"); + /* fall through */ + + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + r = sc_select_file(card, sc_get_mf_path(), NULL); + if (r) + goto out; + + pin_status(card, PACE_PIN_ID_PUK, "Card Holder PUK"); + pin_status(card, DTRUST5_PIN_ID_PIN_T, "Transport PIN (Signature)"); + + /* We have to select the QES app to verify and change the Signature PIN. */ + sc_format_path("3F000101", &path); + r = sc_select_file(card, &path, NULL); + if (r) + goto out; + + pin_status(card, DTRUST5_PIN_ID_QES, "Signature PIN"); + break; + } } if (opt_check) From 36746facea41645ebf5045c35012a64446c3f437 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 18:52:52 +0100 Subject: [PATCH 3945/4321] dtrust-tool: Don't show misleading "transport protection broken" "transport protection broken" should only be shown for unusable transport PINs, but not for regular PINs. Regular PINs are unusable in the default state with transport protection in force, so this output may be misleading. --- src/tools/dtrust-tool.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 83b633abdb..bda8bcc76c 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -127,7 +127,7 @@ get_pin(char **pin, const char *label, unsigned char check) } void -pin_status(sc_card_t *card, int ref, const char *pin_label) +pin_status(sc_card_t *card, int ref, const char *pin_label, unsigned char transport) { int r; struct sc_pin_cmd_data data; @@ -149,9 +149,12 @@ pin_status(sc_card_t *card, int ref, const char *pin_label) printf("%s: not usable (transport protection still in force)\n", pin_label); else if (r == SC_ERROR_AUTH_METHOD_BLOCKED) printf("%s: blocked (use PUK to unblock PIN)\n", pin_label); - else if (r == SC_ERROR_REF_DATA_NOT_USABLE) - printf("%s: not usable (transport protection already broken)\n", pin_label); - else + else if (r == SC_ERROR_REF_DATA_NOT_USABLE) { + if (transport) + printf("%s: not usable (transport protection already broken)\n", pin_label); + else + printf("%s: not usable\n", pin_label); + } else fprintf(stderr, "%s: status query failed (%s).\n", pin_label, sc_strerror(r)); } @@ -361,7 +364,7 @@ main(int argc, char *argv[]) case SC_CARD_TYPE_DTRUST_V4_1_STD: case SC_CARD_TYPE_DTRUST_V4_1_MULTI: case SC_CARD_TYPE_DTRUST_V4_1_M100: - pin_status(card, DTRUST4_PIN_ID_PIN_CH, "Card Holder PIN"); + pin_status(card, DTRUST4_PIN_ID_PIN_CH, "Card Holder PIN", 0); /* fall through */ case SC_CARD_TYPE_DTRUST_V4_4_STD: @@ -372,11 +375,11 @@ main(int argc, char *argv[]) if (r) goto out; - pin_status(card, DTRUST4_PIN_ID_PUK_CH, "Card Holder PUK"); - pin_status(card, DTRUST4_PIN_ID_QES, "Signature PIN"); + pin_status(card, DTRUST4_PIN_ID_PUK_CH, "Card Holder PUK", 0); + pin_status(card, DTRUST4_PIN_ID_QES, "Signature PIN", 0); /* According to the spec, the local bit has to be set. */ - pin_status(card, 0x80 | DTRUST4_PIN_ID_PIN_T, "Transport PIN"); + pin_status(card, 0x80 | DTRUST4_PIN_ID_PIN_T, "Transport PIN", 1); break; case SC_CARD_TYPE_DTRUST_V5_1_STD: @@ -386,7 +389,7 @@ main(int argc, char *argv[]) if (r) goto out; - pin_status(card, DTRUST5_PIN_ID_PIN_T_AUT, "Transport PIN (Authentication)"); + pin_status(card, DTRUST5_PIN_ID_PIN_T_AUT, "Transport PIN (Authentication)", 1); /* We have to select the eSign app to verify and change the Authentication PIN. */ sc_format_path("3F000102", &path); @@ -394,7 +397,7 @@ main(int argc, char *argv[]) if (r) goto out; - pin_status(card, DTRUST5_PIN_ID_AUT, "Authentication PIN"); + pin_status(card, DTRUST5_PIN_ID_AUT, "Authentication PIN", 0); /* fall through */ case SC_CARD_TYPE_DTRUST_V5_4_STD: @@ -403,8 +406,8 @@ main(int argc, char *argv[]) if (r) goto out; - pin_status(card, PACE_PIN_ID_PUK, "Card Holder PUK"); - pin_status(card, DTRUST5_PIN_ID_PIN_T, "Transport PIN (Signature)"); + pin_status(card, PACE_PIN_ID_PUK, "Card Holder PUK", 0); + pin_status(card, DTRUST5_PIN_ID_PIN_T, "Transport PIN (Signature)", 1); /* We have to select the QES app to verify and change the Signature PIN. */ sc_format_path("3F000101", &path); @@ -412,7 +415,7 @@ main(int argc, char *argv[]) if (r) goto out; - pin_status(card, DTRUST5_PIN_ID_QES, "Signature PIN"); + pin_status(card, DTRUST5_PIN_ID_QES, "Signature PIN", 0); break; } } From ce308d9fffd79097149a91453d81b00bf6a7025d Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 20:36:03 +0100 Subject: [PATCH 3946/4321] dtrust-tool: Show transport protection status for D-Trust Card 5 --- src/tools/dtrust-tool.c | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index bda8bcc76c..bd7abd51b4 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -159,37 +159,46 @@ pin_status(sc_card_t *card, int ref, const char *pin_label, unsigned char transp } int -check_transport_protection(sc_card_t *card) +check_transport_protection(sc_card_t *card, u8 ref, const char *pin_label) { - struct sc_apdu apdu; int r; + struct sc_apdu apdu; u8 buf[6]; u8 prot_intact[6] = {0xE3, 0x04, 0x90, 0x02, 0x00, 0x01}; u8 prot_broken[6] = {0xE3, 0x04, 0x90, 0x02, 0x00, 0x00}; - sc_format_apdu_ex(&apdu, 0x80, 0xCA, 0x00, 0x0B, NULL, 0, buf, sizeof(buf)); + r = sc_select_file(card, sc_get_mf_path(), NULL); + if (r != SC_SUCCESS) { + fprintf(stderr, "Check transport protection of %s: Unable to select master file (%s)\n", pin_label, sc_strerror(r)); + return -1; + } + + sc_format_apdu_ex(&apdu, 0x80, 0xCA, 0x00, ref, NULL, 0, buf, sizeof(buf)); r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - fprintf(stderr, "Check transport protection: APDU transmit failed (%s)\n", sc_strerror(r)); + fprintf(stderr, "Check transport protection of %s: APDU transmit failed (%s)\n", pin_label, sc_strerror(r)); return -1; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r != SC_SUCCESS) { - fprintf(stderr, "Check transport protection: GET_DATA failed (%s)\n", sc_strerror(r)); + /* Pin use counter may only be read out, if the retry counter + * is on its maximum value. In case of an error, the PIN has to + * be verified successfully first. */ + fprintf(stderr, "Check transport protection of %s: GET_DATA failed (%s)\n", pin_label, sc_strerror(r)); return -1; } if (apdu.resplen == sizeof(prot_intact) && !memcmp(apdu.resp, prot_intact, 6)) { - printf("Transport protection is still intact.\n"); + printf("Transport protection of %s is still intact.\n", pin_label); return 0; } else if (apdu.resplen == sizeof(prot_broken) && !memcmp(apdu.resp, prot_broken, 6)) { - printf("Transport protection is broken.\n"); + printf("Transport protection of %s is broken.\n", pin_label); return 1; } - fprintf(stderr, "Check transport protection: illegal response: "); + fprintf(stderr, "Check transport protection of %s: illegal response: ", pin_label); util_hex_dump(stderr, apdu.resp, apdu.resplen, " "); fprintf(stderr, "\n"); @@ -420,13 +429,33 @@ main(int argc, char *argv[]) } } - if (opt_check) - check_transport_protection(card); + if (opt_check) { + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + check_transport_protection(card, DTRUST4_PIN_ID_PIN_T, "Signature PIN"); + break; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + check_transport_protection(card, DTRUST5_PIN_ID_PIN_T_AUT, "Authentication PIN"); + /* fall through */ + + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + check_transport_protection(card, DTRUST5_PIN_ID_PIN_T_AUT, "Signature PIN"); + break; + } + } if (opt_unlock) { - r = check_transport_protection(card); + r = check_transport_protection(card, DTRUST4_PIN_ID_PIN_T, "Signature PIN"); if (r) - printf("Cannot remove transport protection.\n"); + printf("Cannot remove transport protection of Signature PIN.\n"); else unlock_transport_protection(card); } From 87716936d6509054a7f54753da45008702253e7f Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 20 Nov 2024 21:04:55 +0100 Subject: [PATCH 3947/4321] dtrust-tool: Unlock transport protection for D-Trust Card 5 --- src/tools/dtrust-tool.c | 181 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 175 insertions(+), 6 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index bd7abd51b4..193b789ac4 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -206,7 +206,7 @@ check_transport_protection(sc_card_t *card, u8 ref, const char *pin_label) } void -unlock_transport_protection(sc_card_t *card) +unlock_transport_protection4(sc_card_t *card) { struct sc_pin_cmd_data data; int r; @@ -264,6 +264,105 @@ unlock_transport_protection(sc_card_t *card) } } +void +unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const char *pathstr, const char *pin_label) +{ + int r; + sc_path_t path; + struct sc_pin_cmd_data data; + char *tpin = NULL; + char *newpin = NULL; + int tries_left; + + printf("Unlocking %s\n", pin_label); + + /* Query all PINs at once */ + if (!(card->reader->capabilities & SC_READER_CAP_PACE_GENERIC)) { + r = get_pin(&tpin, "Transport PIN", 0); + if (r < 0) + goto fail; + } + + if (!(card->reader->capabilities & SC_READER_CAP_PIN_PAD)) { + r = get_pin(&newpin, pin_label, 1); + if (r < 0) + goto fail; + + if (strlen(newpin) != 8) { + fprintf(stderr, "Error. New PIN must be exactly 8 characters long.\n"); + goto fail; + } + } + + /* Authenticate via PACE */ + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_VERIFY; + data.pin_type = SC_AC_CHV; + data.pin_reference = ref_pace; + + if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) + printf("Enter Transport PIN on the readers pin pad now.\n"); + else { + data.pin1.data = (u8 *)tpin; + data.pin1.len = strlen(tpin); + } + + r = sc_pin_cmd(card, &data, &tries_left); + if (r) { + fprintf(stderr, "Error verifying Transport PIN: %s\n", sc_strerror(r)); + goto fail; + } + + /* Select application of the PIN */ + sc_format_path(pathstr, &path); + r = sc_select_file(card, &path, NULL); + if (r) + goto fail; + + /* Change PIN */ + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_CHANGE; + data.flags = SC_PIN_CMD_IMPLICIT_CHANGE; + data.pin_type = SC_AC_CHV; + data.pin_reference = ref_pin; + data.pin2.min_length = 8; + data.pin2.max_length = 8; + + if (card->reader->capabilities & SC_READER_CAP_PIN_PAD) { + printf("Enter new %s on the readers pin pad now.\n", pin_label); + data.pin2.prompt = pin_label; + data.flags |= SC_PIN_CMD_USE_PINPAD; + } else { + data.pin2.data = (u8 *)newpin; + data.pin2.len = strlen(newpin); + } + + /* We only have one chance to set the new PIN. Once the Transport PIN + * is verified, it is not usable anymore. For pin pad readers we + * continue as long as the new PIN is set successfully or the user + * aborts the program and renders its card unusable as a consequence. */ + do { + r = sc_pin_cmd(card, &data, NULL); + if (r == SC_SUCCESS) { + printf("Transport protection removed. You can now use your %s.\n", pin_label); + break; + } + + printf("Can't change pin: %s\n", sc_strerror(r)); + } while (card->reader->capabilities & SC_READER_CAP_PIN_PAD); + +fail: + if (newpin != NULL) { + sc_mem_clear(newpin, strlen(newpin)); + free(newpin); + } + + if (tpin != NULL) { + sc_mem_clear(tpin, strlen(tpin)); + free(tpin); + } +} + int main(int argc, char *argv[]) { @@ -453,11 +552,81 @@ main(int argc, char *argv[]) } if (opt_unlock) { - r = check_transport_protection(card, DTRUST4_PIN_ID_PIN_T, "Signature PIN"); - if (r) - printf("Cannot remove transport protection of Signature PIN.\n"); - else - unlock_transport_protection(card); + /* Warn the user he must not abort the unlocking process on + * pin pad readers, as the transport pin has already been used + * and there is no next attempt. */ + if (card->reader->capabilities & SC_READER_CAP_PIN_PAD && + card->type >= SC_CARD_TYPE_DTRUST_V5_1_STD && + card->type <= SC_CARD_TYPE_DTRUST_V5_4_MULTI) { + printf("\n"); + printf("CAUTION.\n"); + printf("\n"); + printf("You are about to remove the transport protection. After entering the transport\n"); + printf("PIN, don't abort the program! Otherwise your card becomes irrecoverably unusable.\n"); + printf("In case of an error, continue to enter your PIN as long as you reader accepts\n"); + printf("it. The new PIN must be exactly 8 characters long.\n"); + printf("\n"); + printf("If in doubt, cancel now and try to unlock your card in a card reader without a\n"); + printf("pin pad. Then all, your inputs will be validated before unlocking the card.\n"); + printf("\n"); + printf("Enter 'yes' to continue.\n"); + +#ifndef _WIN32 + ssize_t ret; + char *str = NULL; + size_t len = 0; + + ret = getline(&str, &len, stdin); + if (ret >= 0) + ret = strcmp(str, "yes\n"); + free(str); + + if (ret) + goto out; +#else + char str[8]; + char *ret; + + ret = fgets(str, 8, stdin); + if (ret == NULL || strcmp(ret, "yes\n")) + goto out; +#endif + } + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + r = check_transport_protection(card, DTRUST4_PIN_ID_PIN_T, "Signature PIN"); + if (r) + printf("Cannot remove transport protection of Signature PIN.\n"); + else + unlock_transport_protection4(card); + break; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + r = check_transport_protection(card, DTRUST5_PIN_ID_PIN_T_AUT, "Authentication PIN"); + if (r) + printf("Cannot remove transport protection of Authentication PIN.\n"); + else { + unlock_transport_protection5(card, DTRUST5_PIN_ID_PIN_T_AUT, DTRUST5_PIN_ID_AUT, "3F000102", "Authentication PIN"); + } + /* fall through */ + + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + r = check_transport_protection(card, DTRUST5_PIN_ID_PIN_T, "Signature PIN"); + if (r) + printf("Cannot remove transport protection of Signature PIN.\n"); + else { + unlock_transport_protection5(card, DTRUST5_PIN_ID_PIN_T, DTRUST5_PIN_ID_QES, "3F000101", "Signature PIN"); + } + break; + } } out: From 9ec914f39175e91c0386bf8cd33e22fcb56ae1cb Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 23 Nov 2024 20:10:13 +0100 Subject: [PATCH 3948/4321] dtrust-tool: Output error messages to stderr --- src/tools/dtrust-tool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 193b789ac4..f607c8fd2a 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -310,6 +310,8 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c r = sc_pin_cmd(card, &data, &tries_left); if (r) { fprintf(stderr, "Error verifying Transport PIN: %s\n", sc_strerror(r)); + if (tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", tries_left); goto fail; } @@ -416,13 +418,13 @@ main(int argc, char *argv[]) r = sc_context_create(&ctx, &ctx_param); if (r) { - printf("Failed to establish context: %s\n", sc_strerror(r)); + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } r = sc_set_card_driver(ctx, "dtrust"); if (r) { - printf("Driver 'dtrust' not found!\n"); + fprintf(stderr, "Driver 'dtrust' not found!\n"); goto out; } From cb6cc14db4cb97d7ec692884f92c85708820e013 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 23 Nov 2024 22:49:12 +0100 Subject: [PATCH 3949/4321] dtrust-tool: Implement unblocking PINs --- doc/tools/dtrust-tool.1.xml | 27 +++++ src/tools/dtrust-tool.c | 193 ++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index e1189ce508..b01897a270 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -131,6 +131,33 @@ Transport PIN and then the new value of the Signature PIN twice. + + + , + + + + Reset the retry counter of a PIN to its default value. To + unblock a PIN, you first have to provide the PUK. The following + PINs can be unblocked: + + + + For D-Trust Card 4: PIN.T, PIN.CH, PIN.QES + + + For D-Trust Card 5: PIN.T, PIN.T.AUT, PIN.QES, PIN.AUT + + + + It is impossible to unblock a blocked PUK. + + + Please keep in mind that the PUK may only be used a limited + number of times (48 times for D-Trust Card 4 and 5). + + + , diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index f607c8fd2a..15f49abb63 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -36,6 +36,7 @@ static const char *app_name = "dtrust-tool"; enum { OPT_CAN_VERIFY = 0x100, + OPT_UNBLOCK, }; // clang-format off @@ -46,6 +47,7 @@ static const struct option options[] = { {"pin-status", 0, NULL, 's'}, {"check-transport-protection", 0, NULL, 'c'}, {"unlock-transport-protection", 0, NULL, 'u'}, + {"unblock-pin", 1, NULL, OPT_UNBLOCK}, {"help", 0, NULL, 'h'}, {"verbose", 0, NULL, 'v'}, {NULL, 0, NULL, 0} @@ -58,6 +60,7 @@ static const char *option_help[] = { "Show PIN status", "Check transport protection", "Unlock transport protection", + "Unblock blocked PIN", "This message", "Verbose operation, may be used several times", }; @@ -69,6 +72,7 @@ static unsigned char opt_can_verify = 0; static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; +static const char *opt_unblock = NULL; int get_pin(char **pin, const char *label, unsigned char check) @@ -126,6 +130,66 @@ get_pin(char **pin, const char *label, unsigned char check) return -1; } +int +parse_pin(sc_card_t *card, const char *pinstr, const char *label, unsigned char *require_can) +{ + const char *valid = NULL; + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + valid = "PIN.CH, PUK.CH, PIN.T, PIN.QES"; + + if (!strcasecmp(pinstr, "PIN.CH")) + return DTRUST4_PIN_ID_PIN_CH; + if (!strcasecmp(pinstr, "PUK.CH")) + return DTRUST4_PIN_ID_PUK_CH; + if (!strcasecmp(pinstr, "PIN.T")) + return DTRUST4_PIN_ID_PIN_T; + if (!strcasecmp(pinstr, "PIN.QES")) + return DTRUST4_PIN_ID_QES; + break; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + valid = "PUK.CH, PIN.T, PIN.T.AUT, PIN.QES, PIN.AUT"; + + if (!strcasecmp(pinstr, "PIN.T.AUT")) { + return DTRUST5_PIN_ID_PIN_T_AUT; + } + if (!strcasecmp(pinstr, "PIN.AUT")) { + if (require_can != NULL) + *require_can = 1; + return DTRUST5_PIN_ID_AUT; + } + /* fall through */ + + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + if (valid == NULL) + valid = "PUK.CH, PIN.T, PIN.QES"; + + if (!strcasecmp(pinstr, "PUK.CH")) + return PACE_PIN_ID_PUK; + if (!strcasecmp(pinstr, "PIN.T")) + return DTRUST5_PIN_ID_PIN_T; + if (!strcasecmp(pinstr, "PIN.QES")) { + if (require_can != NULL) + *require_can = 1; + return DTRUST5_PIN_ID_QES; + } + break; + } + + fprintf(stderr, "%s PIN '%s' is invalid. Choose one from: %s\n", label, pinstr, valid); + + return -1; +} + void pin_status(sc_card_t *card, int ref, const char *pin_label, unsigned char transport) { @@ -365,6 +429,123 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c } } +void +unblock_pin(sc_card_t *card, int ref_pin) +{ + struct sc_pin_cmd_data data_verify, data_unblock; + const char *pathstr = "3F00"; + unsigned char pace = 0; + char *puk = NULL; + sc_path_t path; + int r; + int tries_left; + + memset(&data_verify, 0, sizeof(struct sc_pin_cmd_data)); + memset(&data_unblock, 0, sizeof(struct sc_pin_cmd_data)); + + data_verify.cmd = SC_PIN_CMD_VERIFY; + data_verify.pin_type = SC_AC_CHV; + + data_unblock.cmd = SC_PIN_CMD_UNBLOCK; + data_unblock.pin_type = SC_AC_CHV; + data_unblock.pin_reference = ref_pin; + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + data_verify.pin_reference = DTRUST4_PIN_ID_PUK_CH; + data_verify.pin1.min_length = 8; + data_verify.pin1.max_length = 12; + + if (ref_pin == DTRUST4_PIN_ID_QES) + pathstr = "3F000101"; + + if (ref_pin == DTRUST4_PIN_ID_PIN_CH || + ref_pin == DTRUST4_PIN_ID_PIN_T || + ref_pin == DTRUST4_PIN_ID_QES) { + break; + } + + fprintf(stderr, "Invalid unblock PIN. Only PIN.CH, PIN.T or PIN.QES may be unblocked.\n"); + return; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + pace = 1; + data_verify.pin_reference = PACE_PIN_ID_PUK; + data_verify.pin1.min_length = 8; + data_verify.pin1.max_length = 8; + + if (ref_pin == DTRUST5_PIN_ID_QES) + pathstr = "3F000101"; + else if (ref_pin == DTRUST5_PIN_ID_AUT) + pathstr = "3F000102"; + + if (ref_pin == DTRUST5_PIN_ID_PIN_T || + ref_pin == DTRUST5_PIN_ID_PIN_T_AUT || + ref_pin == DTRUST5_PIN_ID_QES || + ref_pin == DTRUST5_PIN_ID_AUT) { + break; + } + + fprintf(stderr, "Invalid unblock PIN. Only PIN.T, PIN.T.AUT, PIN.QES or PIN.AUT may be unblocked.\n"); + return; + + default: + return; + } + + if ((card->reader->capabilities & SC_READER_CAP_PIN_PAD) && !pace) { + data_verify.flags |= SC_PIN_CMD_USE_PINPAD; + } else if (!(card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) || !pace) { + r = get_pin(&puk, "PUK", 0); + if (r < 0) + goto fail; + + data_verify.pin1.data = (const unsigned char *)puk; + data_verify.pin1.len = strlen(puk); + } + + sc_format_path(pathstr, &path); + + r = sc_select_file(card, pace ? sc_get_mf_path() : &path, NULL); + if (r) { + fprintf(stderr, "Error selecting application: %s\n", sc_strerror(r)); + goto fail; + } + + r = sc_pin_cmd(card, &data_verify, &tries_left); + if (r) { + fprintf(stderr, "Error verifying PUK: %s\n", sc_strerror(r)); + if (tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", tries_left); + goto fail; + } + + if (!pace) { + r = sc_select_file(card, &path, NULL); + if (r) { + fprintf(stderr, "Error selecting application: %s\n", sc_strerror(r)); + goto fail; + } + } + + r = sc_pin_cmd(card, &data_unblock, NULL); + if (r) { + fprintf(stderr, "Error unblocking PIN: %s\n", sc_strerror(r)); + goto fail; + } + +fail: + free(puk); +} + int main(int argc, char *argv[]) { @@ -373,6 +554,7 @@ main(int argc, char *argv[]) sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; + int pin_unblock = -1; sc_path_t path; while (1) { @@ -403,6 +585,9 @@ main(int argc, char *argv[]) case 'u': opt_unlock = 1; break; + case OPT_UNBLOCK: + opt_unblock = optarg; + break; case 'v': verbose++; break; @@ -435,6 +620,12 @@ main(int argc, char *argv[]) if (opt_status || opt_check) opt_can_verify = 1; + if (opt_unblock != NULL) { + pin_unblock = parse_pin(card, opt_unblock, "Unblock", NULL); + if (pin_unblock < 0) + goto out; + } + /* D-Trust Card 5 requires PACE authentication with CAN */ if (opt_can_verify && card->type >= SC_CARD_TYPE_DTRUST_V5_1_STD && @@ -629,6 +820,8 @@ main(int argc, char *argv[]) } break; } + } else if (opt_unblock != NULL) { + unblock_pin(card, pin_unblock); } out: From e826c044eefcdefb0a9aedaf71db0543231318c6 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 23 Nov 2024 23:03:24 +0100 Subject: [PATCH 3950/4321] dtrust-tool: Implement resuming PINs --- doc/tools/dtrust-tool.1.xml | 20 +++++++++ src/tools/dtrust-tool.c | 85 +++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index b01897a270..3d9afddc1d 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -131,6 +131,26 @@ Transport PIN and then the new value of the Signature PIN twice. + + + , + + + + Resume a suspended PIN. This matters only for the PUK (PUK.CH) + of D-Trust 5 cards. After two unsuccessful attempts to verify + the PUK, the PUK is suspended. To resume the suspended PUK you + first have to input the CAN and then the value of the suspended + PUK. If you enter the wrong PUK again, the PUK is finally + blocked and cannot be recovered. + + + To resume a suspended transport PIN use + together with + . + + + , diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 15f49abb63..baf990ec5d 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -36,6 +36,7 @@ static const char *app_name = "dtrust-tool"; enum { OPT_CAN_VERIFY = 0x100, + OPT_RESUME, OPT_UNBLOCK, }; @@ -47,6 +48,7 @@ static const struct option options[] = { {"pin-status", 0, NULL, 's'}, {"check-transport-protection", 0, NULL, 'c'}, {"unlock-transport-protection", 0, NULL, 'u'}, + {"resume-pin", 1, NULL, OPT_RESUME}, {"unblock-pin", 1, NULL, OPT_UNBLOCK}, {"help", 0, NULL, 'h'}, {"verbose", 0, NULL, 'v'}, @@ -60,6 +62,7 @@ static const char *option_help[] = { "Show PIN status", "Check transport protection", "Unlock transport protection", + "Resume suspended PIN", "Unblock blocked PIN", "This message", "Verbose operation, may be used several times", @@ -72,6 +75,7 @@ static unsigned char opt_can_verify = 0; static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; +static const char *opt_resume = NULL; static const char *opt_unblock = NULL; int @@ -429,6 +433,74 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c } } +void +resume_pin(sc_card_t *card, int ref_pin) +{ + struct sc_pin_cmd_data data; + char *pin = NULL; + int r; + + memset(&data, 0, sizeof(struct sc_pin_cmd_data)); + + data.cmd = SC_PIN_CMD_VERIFY; + data.pin_type = SC_AC_CHV; + data.pin_reference = ref_pin; + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + data.pin1.min_length = 8; + data.pin1.max_length = 8; + + if (ref_pin == PACE_PIN_ID_PUK) + break; + + /* Resuming a transport PIN leads to decreasing its use + * counter. Not performing the signature PIN changing procedure + * irectly after transport PIN verification would render the + * card useless. Thus we enforce the user to resume the PIN + * during the regular unlock procedure. */ + fprintf(stderr, "Invalid PIN to resume. Only the PUK can be resumed with this command.\n"); + fprintf(stderr, "To resume a transport PIN call this tool with --can and --unlock-transport-protection parameter.\n"); + return; + + default: + fprintf(stderr, "This card does not support PINs which can be resumed.\n"); + return; + } + + /* Suspended PIN always require a PACE authentication. */ + if (!(card->reader->capabilities & SC_READER_CAP_PACE_GENERIC)) { + r = get_pin(&pin, "PIN to resume", 0); + if (r < 0) + goto fail; + + data.pin1.data = (const unsigned char *)pin; + data.pin1.len = strlen(pin); + } + + /* CAN was already verified by the caller at this point. We can + * directly verify the resumed PIN. */ + + r = sc_select_file(card, sc_get_mf_path(), NULL); + if (r) { + fprintf(stderr, "Error selecting master application: %s\n", sc_strerror(r)); + goto fail; + } + + r = sc_pin_cmd(card, &data, NULL); + if (r) { + fprintf(stderr, "Error resuming PIN: %s\n", sc_strerror(r)); + goto fail; + } + +fail: + free(pin); +} + void unblock_pin(sc_card_t *card, int ref_pin) { @@ -554,6 +626,7 @@ main(int argc, char *argv[]) sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; + int pin_resume = -1; int pin_unblock = -1; sc_path_t path; @@ -585,6 +658,9 @@ main(int argc, char *argv[]) case 'u': opt_unlock = 1; break; + case OPT_RESUME: + opt_resume = optarg; + break; case OPT_UNBLOCK: opt_unblock = optarg; break; @@ -620,6 +696,13 @@ main(int argc, char *argv[]) if (opt_status || opt_check) opt_can_verify = 1; + if (opt_resume != NULL) { + opt_can_verify = 1; + pin_resume = parse_pin(card, opt_resume, "Resume", NULL); + if (pin_resume < 0) + goto out; + } + if (opt_unblock != NULL) { pin_unblock = parse_pin(card, opt_unblock, "Unblock", NULL); if (pin_unblock < 0) @@ -820,6 +903,8 @@ main(int argc, char *argv[]) } break; } + } else if (opt_resume != NULL) { + resume_pin(card, pin_resume); } else if (opt_unblock != NULL) { unblock_pin(card, pin_unblock); } From e38642b796483e5ace3aa5796ddc37c1190db602 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 23 Nov 2024 23:43:19 +0100 Subject: [PATCH 3951/4321] dtrust-tool: Implement changing PINs --- doc/tools/dtrust-tool.1.xml | 38 ++++++++ src/tools/dtrust-tool.c | 186 ++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index 3d9afddc1d..55a0b0fc91 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -131,6 +131,44 @@ Transport PIN and then the new value of the Signature PIN twice. + + + , + + + + Change the specified PIN. The following PINs can be changed: + + + + For D-Trust Card 4: PIN.CH, PIN.QES, PUK.CH + + + For D-Trust Card 5: PIN.QES, PIN.AUT, PUK.CH + + + + It is not recommended to change the PUK. + + + To change a PIN, you first have to enter the old PIN and then + the new PIN value two times. + + + + + + , + + + This option specifies the PIN to verify for changing the PIN + specified with the command. The only + useful application of this option is to reset the cardholder PIN + (PIN.CH) of D-Trust 4.1 cards by providing the cardholder PUK (PUK.CH). + In all other cases, a PIN may only changed by providing its current + value. + + , diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index baf990ec5d..cb600d1e02 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -36,6 +36,8 @@ static const char *app_name = "dtrust-tool"; enum { OPT_CAN_VERIFY = 0x100, + OPT_CHANGE, + OPT_VERIFY, OPT_RESUME, OPT_UNBLOCK, }; @@ -48,6 +50,8 @@ static const struct option options[] = { {"pin-status", 0, NULL, 's'}, {"check-transport-protection", 0, NULL, 'c'}, {"unlock-transport-protection", 0, NULL, 'u'}, + {"change-pin", 1, NULL, OPT_CHANGE}, + {"change-verify", 1, NULL, OPT_VERIFY}, {"resume-pin", 1, NULL, OPT_RESUME}, {"unblock-pin", 1, NULL, OPT_UNBLOCK}, {"help", 0, NULL, 'h'}, @@ -62,6 +66,8 @@ static const char *option_help[] = { "Show PIN status", "Check transport protection", "Unlock transport protection", + "Change PIN", + "Verification PIN ID for PIN change", "Resume suspended PIN", "Unblock blocked PIN", "This message", @@ -75,6 +81,8 @@ static unsigned char opt_can_verify = 0; static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; +static const char *opt_change = NULL; +static const char *opt_verify = NULL; static const char *opt_resume = NULL; static const char *opt_unblock = NULL; @@ -433,6 +441,161 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c } } +void +change_pin(sc_card_t *card, int ref_verify, int ref_change) +{ + struct sc_pin_cmd_data data_verify, data_change; + const char *pathstr = "3F00"; + const char *oldstr = "Old PIN"; + const char *newstr = "New PIN"; + unsigned char pace = 0; + char *oldpin = NULL; + char *newpin = NULL; + sc_path_t path; + int r; + int tries_left; + + memset(&data_verify, 0, sizeof(struct sc_pin_cmd_data)); + memset(&data_change, 0, sizeof(struct sc_pin_cmd_data)); + + data_verify.cmd = SC_PIN_CMD_VERIFY; + data_verify.pin_type = SC_AC_CHV; + data_verify.pin_reference = ref_verify; + + data_change.cmd = SC_PIN_CMD_CHANGE; + data_change.flags |= SC_PIN_CMD_IMPLICIT_CHANGE; + data_change.pin_type = SC_AC_CHV; + data_change.pin_reference = ref_change; + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V4_1_STD: + case SC_CARD_TYPE_DTRUST_V4_1_MULTI: + case SC_CARD_TYPE_DTRUST_V4_1_M100: + case SC_CARD_TYPE_DTRUST_V4_4_STD: + case SC_CARD_TYPE_DTRUST_V4_4_MULTI: + data_verify.pin1.min_length = ref_verify == DTRUST4_PIN_ID_PUK_CH ? 8 : 6; + data_verify.pin1.max_length = 12; + data_change.pin2.min_length = ref_change == DTRUST4_PIN_ID_PUK_CH ? 8 : 6; + data_change.pin2.max_length = 12; + + if (ref_change == DTRUST4_PIN_ID_QES) + pathstr = "3F000101"; + + if (ref_change != DTRUST4_PIN_ID_PIN_CH && + ref_change != DTRUST4_PIN_ID_PUK_CH && + ref_change != DTRUST4_PIN_ID_QES) { + fprintf(stderr, "Invalid change PIN. Only PIN.CH, PUK.CH or PIN.QES may be changed.\n"); + return; + } + + /* Every PIN can change itself */ + if (ref_verify == ref_change) + break; + + /* PUK can change cardholder PIN */ + if (ref_verify == DTRUST4_PIN_ID_PUK_CH && ref_change == DTRUST4_PIN_ID_PIN_CH) { + oldstr = "Cardholder PIN"; + break; + } + + fprintf(stderr, "Invalid verification PIN. PINs can only changed by itself.\n"); + fprintf(stderr, "Additionally the cardholder PIN may by changed by the PUK.\n"); + return; + + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + data_verify.pin1.min_length = 8; + data_verify.pin1.max_length = 8; + data_change.pin2.min_length = 8; + data_change.pin2.max_length = 8; + + if (ref_change == DTRUST5_PIN_ID_QES) + pathstr = "3F000101"; + else if (ref_change == DTRUST5_PIN_ID_AUT) + pathstr = "3F000102"; + + if (ref_change != PACE_PIN_ID_PUK && + ref_change != DTRUST5_PIN_ID_QES && + ref_change != DTRUST5_PIN_ID_AUT) { + fprintf(stderr, "Invalid change PIN. Only PUK.CH, PIN.QES or PIN.AUT may be changed.\n"); + return; + } + + /* PUK has to be verified via PACE */ + if (ref_verify == PACE_PIN_ID_PUK) + pace = 1; + + /* Every PIN can change itself */ + if (ref_verify == ref_change) + break; + + fprintf(stderr, "Invalid verification PIN. PINs can only changed by itself.\n"); + return; + + default: + return; + } + + if ((card->reader->capabilities & SC_READER_CAP_PIN_PAD) && !pace) { + data_verify.flags |= SC_PIN_CMD_USE_PINPAD; + } else if (!(card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) || !pace) { + r = get_pin(&oldpin, oldstr, 0); + if (r < 0) + goto fail; + + data_verify.pin1.data = (const unsigned char *)oldpin; + data_verify.pin1.len = strlen(oldpin); + } + + if (card->reader->capabilities & SC_READER_CAP_PIN_PAD) { + data_change.flags |= SC_PIN_CMD_USE_PINPAD; + } else { + r = get_pin(&newpin, newstr, 1); + if (r < 0) + goto fail; + + data_change.pin2.data = (const unsigned char *)newpin; + data_change.pin2.len = strlen(newpin); + } + + sc_format_path(pathstr, &path); + + r = sc_select_file(card, pace ? sc_get_mf_path() : &path, NULL); + if (r) { + fprintf(stderr, "Error selecting application: %s\n", sc_strerror(r)); + goto fail; + } + + r = sc_pin_cmd(card, &data_verify, &tries_left); + if (r) { + fprintf(stderr, "Error verifying PIN: %s\n", sc_strerror(r)); + if (tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", tries_left); + goto fail; + } + + if (pace) { + r = sc_select_file(card, &path, NULL); + if (r) { + fprintf(stderr, "Error selecting application: %s\n", sc_strerror(r)); + goto fail; + } + } + + r = sc_pin_cmd(card, &data_change, NULL); + if (r) { + fprintf(stderr, "Error changing PIN: %s\n", sc_strerror(r)); + goto fail; + } + +fail: + free(oldpin); + free(newpin); +} + void resume_pin(sc_card_t *card, int ref_pin) { @@ -626,6 +789,8 @@ main(int argc, char *argv[]) sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; + int pin_change = -1; + int pin_verify = -1; int pin_resume = -1; int pin_unblock = -1; sc_path_t path; @@ -658,6 +823,12 @@ main(int argc, char *argv[]) case 'u': opt_unlock = 1; break; + case OPT_CHANGE: + opt_change = optarg; + break; + case OPT_VERIFY: + opt_verify = optarg; + break; case OPT_RESUME: opt_resume = optarg; break; @@ -696,6 +867,19 @@ main(int argc, char *argv[]) if (opt_status || opt_check) opt_can_verify = 1; + if (opt_change != NULL) { + pin_change = parse_pin(card, opt_change, "Change", opt_verify == NULL ? &opt_can_verify : NULL); + pin_verify = pin_change; + if (pin_change < 0) + goto out; + } + + if (opt_verify != NULL) { + pin_verify = parse_pin(card, opt_verify, "Verification", &opt_can_verify); + if (pin_verify < 0) + goto out; + } + if (opt_resume != NULL) { opt_can_verify = 1; pin_resume = parse_pin(card, opt_resume, "Resume", NULL); @@ -903,6 +1087,8 @@ main(int argc, char *argv[]) } break; } + } else if (opt_change != NULL) { + change_pin(card, pin_verify, pin_change); } else if (opt_resume != NULL) { resume_pin(card, pin_resume); } else if (opt_unblock != NULL) { From 9aaddf2191c9e31f67c7409fa77072f5852c49ec Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 30 Nov 2024 10:04:04 +0100 Subject: [PATCH 3952/4321] dtrust: Cache CAN --- doc/files/files.html | 9 ++++- doc/files/opensc.conf.5.xml.in | 14 +++++++ doc/tools/dtrust-tool.1.xml | 4 ++ src/libopensc/card-dtrust.c | 74 +++++++++++++++++++++++++++++----- 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index cb97e3f112..dbcefd23cf 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -562,7 +562,14 @@ If not specified here, the CAN will be read from a card specific cache, prompted on the card readers PIN pad or prompted interactively in the following order. -

    1. Environment variable DTRUST_CAN

    2. This configuration file option

    3. Pin pad of a PACE-capable card reader

    Configuration Options for PIV Card

    Configuration based on ATR

    +

    1. Environment variable DTRUST_CAN

    2. This configuration file option

    3. PKCS#15 card-specific cache

    4. Pin pad of a PACE-capable card reader

    + can_use_cache = bool; +

    + Cache the CAN number of a card once it was provided by the user in the + directory file_cache_dir. The cached CAN is used + later to avoid interactively prompting for the CAN. This feature is + enabled by default. +

    Configuration Options for PIV Card

    Configuration based on ATR

    atrmask = hexstring;

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 56a7e550c2..3f465cf6a3 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -846,10 +846,24 @@ app application { Environment variable DTRUST_CAN This configuration file option + PKCS#15 card-specific cache Pin pad of a PACE-capable card reader + + + + + + + Cache the CAN number of a card once it was provided by the user in the + directory file_cache_dir. The cached CAN is used + later to avoid interactively prompting for the CAN. This feature is + enabled by default. + + + diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index 55a0b0fc91..f116a61ed8 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -76,6 +76,10 @@ PIN. You then need to unblock the transport PIN with . + + You may call dtrust-tool with just this + option to save the CAN into the cache. + diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 3fc8884c00..e003698890 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -68,6 +68,10 @@ struct dtrust_drv_data_t { unsigned char can : 1; /* global CAN from configuration file */ const char *can_value; + /* use CAN cache */ + unsigned char can_cache : 1; + /* PKCS#15 context for CAN caching */ + struct sc_pkcs15_card *p15card; /* save the current security environment */ const sc_security_env_t *env; }; @@ -276,6 +280,8 @@ dtrust_init(sc_card_t *card) drv_data->pace = 0; drv_data->can = 0; drv_data->can_value = NULL; + drv_data->can_cache = 1; + drv_data->p15card = NULL; drv_data->can_value = can_env = getenv("DTRUST_CAN"); if (can_env != NULL) { @@ -289,6 +295,8 @@ dtrust_init(sc_card_t *card) continue; for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { + drv_data->can_cache = scconf_get_bool(block, "can_use_cache", drv_data->can_cache); + /* Environment variable has precedence over configured CAN */ if (can_env == NULL) { drv_data->can_value = scconf_get_str(block, "can", drv_data->can_value); @@ -323,7 +331,6 @@ dtrust_init(sc_card_t *card) card->max_recv_size = sc_get_max_recv_size(card); flags = 0; - r = SC_ERROR_WRONG_CARD; switch (card->type) { case SC_CARD_TYPE_DTRUST_V4_1_STD: @@ -341,8 +348,6 @@ dtrust_init(sc_card_t *card) flags |= SC_ALGORITHM_MGF1_SHA512; _sc_card_add_rsa_alg(card, 3072, flags, 0); - - r = SC_SUCCESS; break; case SC_CARD_TYPE_DTRUST_V4_1_MULTI: @@ -353,8 +358,6 @@ dtrust_init(sc_card_t *card) ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; _sc_card_add_ec_alg(card, 256, flags, ext_flags, &oid_secp256r1); - - r = SC_SUCCESS; break; case SC_CARD_TYPE_DTRUST_V5_1_MULTI: @@ -365,19 +368,38 @@ dtrust_init(sc_card_t *card) ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; _sc_card_add_ec_alg(card, 384, flags, ext_flags, &oid_secp384r1); + break; - r = SC_SUCCESS; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); + } + + switch (card->type) { + case SC_CARD_TYPE_DTRUST_V5_1_STD: + case SC_CARD_TYPE_DTRUST_V5_4_STD: + case SC_CARD_TYPE_DTRUST_V5_1_MULTI: + case SC_CARD_TYPE_DTRUST_V5_1_M100: + case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + r = sc_pkcs15_bind(card, NULL, &drv_data->p15card); + LOG_TEST_RET(card->ctx, r, "Binding PKCS#15 context failed"); break; } - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int dtrust_finish(sc_card_t *card) { + struct dtrust_drv_data_t *drv_data; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + drv_data = card->drv_data; + + if (drv_data->p15card != NULL) { + sc_pkcs15_unbind(drv_data->p15card); + } free((char *)card->name); free(card->drv_data); @@ -428,6 +450,10 @@ dtrust_perform_pace(struct sc_card *card, int *tries_left) { struct dtrust_drv_data_t *drv_data; + sc_path_t can_path; + u8 can_buffer[16]; + u8 *can_ptr = can_buffer; + size_t can_len; int r; struct establish_pace_channel_input pace_input; struct establish_pace_channel_output pace_output; @@ -436,6 +462,22 @@ dtrust_perform_pace(struct sc_card *card, drv_data = card->drv_data; + /* Dummy file path for the CAN cache */ + sc_format_path("CA4E", &can_path); + + /* Read CAN cache always. We need to know if the cache contains a CAN + * value even if we use a CAN source with higher precedence. The CAN + * cache must only be written if it was empty. Writing to a non-empty + * cache file will append the data to be written instead of overwriting + * the file. */ + can_len = sizeof(can_buffer) - 1; + r = sc_pkcs15_read_cached_file(drv_data->p15card, &can_path, &can_ptr, &can_len); + if (r == SC_SUCCESS && can_len > 0) { + can_buffer[can_len] = '\0'; + } else { + can_len = 0; + } + /* The PKCS#11 layer cannot provide a CAN. Instead we consider the * following sources for CAN input. * 1. A CAN provided by the caller @@ -455,8 +497,18 @@ dtrust_perform_pace(struct sc_card *card, } } - /* TODO: Query the CAN cache if no CAN is provided by the caller. */ + /* Use the CAN cache if no CAN is provided. */ + if (drv_data->can_cache && pin == NULL) { + if (can_len > 0) { + sc_log(card->ctx, "Using cached CAN."); + pin = can_buffer; + pinlen = can_len; + } else { + sc_log(card->ctx, "No cached CAN available."); + } + } + /* Query the user interactively if no cached CAN is available. */ if (pin == NULL) { if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { /* If no CAN is provided and the reader is @@ -514,7 +566,11 @@ dtrust_perform_pace(struct sc_card *card, } } - /* TODO: Put CAN into the cache if necessary. */ + /* Write CAN to the cache, if it is correct and the cache was initially empty. */ + if (ref == PACE_PIN_ID_CAN && pin != NULL && drv_data->can_cache && + r == SC_SUCCESS && can_len == 0) { + sc_pkcs15_cache_file(drv_data->p15card, &can_path, pin, pinlen); + } return r; } From d67ee2e2d146f002020a0f7539ba54146eb6d55f Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 30 Nov 2024 10:04:53 +0100 Subject: [PATCH 3953/4321] dtrust: Use PKCS#15 file caching by default --- doc/files/files.html | 3 ++- doc/files/opensc.conf.5.xml.in | 3 ++- src/libopensc/pkcs15.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index dbcefd23cf..32256afe2f 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -830,7 +830,8 @@ mcrd (deactivated driver), npa, nqapplet, - tcos and otherwise no). + tcos, + dtrust and otherwise no).

    If caching is done by a system process, the cached files may be placed inaccessible from diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 3f465cf6a3..a6d7d8646b 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1296,7 +1296,8 @@ app application { mcrd (deactivated driver), npa, nqapplet, - tcos and otherwise no). + tcos, + dtrust and otherwise no). If caching is done by a system process, the diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 47e13d40ce..a932a445cf 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1247,6 +1247,7 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) "npa", "nqapplet", "tcos", + "dtrust", }; if (NULL == card || NULL == card->driver || NULL == card->driver->short_name) From 1a897945256b13ca6df7c67380e39d57b284b288 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Thu, 19 Dec 2024 10:42:16 +0100 Subject: [PATCH 3954/4321] dtrust-tool: Use all CAN sources provided by the card driver --- doc/tools/dtrust-tool.1.xml | 66 +++++++++++++++++++++++++++++++------ src/tools/dtrust-tool.c | 12 ++++--- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/doc/tools/dtrust-tool.1.xml b/doc/tools/dtrust-tool.1.xml index f116a61ed8..99dc0a31c0 100644 --- a/doc/tools/dtrust-tool.1.xml +++ b/doc/tools/dtrust-tool.1.xml @@ -65,20 +65,55 @@ onto the card. The purpose of this number is to establish a secure communication channel between the card and the card reader. In normal operation dtrust-tool - automatically prompts for the CAN. + automatically prompts for the CAN when necessary. Under certain + circumstances dtrust-tool cannot decide + whether the CAN is necessary. + + + You may call dtrust-tool with just + this option to force a CAN verification, which saves + the CAN into the cache if it proved right. Once the CAN + was saved into the cache, You do not need to enter the + CAN of this card again. + + + In case you entered a transport PIN wrong two times, + the transport PIN is suspended. You need this parameter + together with + to resume the suspended transport PIN for a last + attempt. Failing to enter the transport PIN + successfully blocks the transport PIN. You then need to + unblock the transport PIN with . + + + + + + + , + + - In case you entered a transport PIN wrong two times, the - transport PIN becomes suspended. You need this parameter - together with to - resume the suspended transport PIN for a last attempt. Failing - to enter the transport PIN successfully blocks the transport - PIN. You then need to unblock the transport PIN with - . + There are several ways to provide a CAN. See the + dtrust section in the + opensc.conf manpage for details. With this + parameter dtrust-tool will prompt + interactively for a CAN, bypassing all other sources. This is + useful if you: + + + enter the CAN for the first time and want it to be + saved in the CAN cache + + + want to bypass the pin pad of card reader. Bypassing + the pin pad will save the CAN into the cache as well. + + - You may call dtrust-tool with just this - option to save the CAN into the cache. + Once the CAN is cached, you do not need this parameter anymore. @@ -240,6 +275,17 @@ + + + See also + + + opensc.conf + 5 + + + + Authors dtrust-tool was written by diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index cb600d1e02..912fdf4dcb 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -36,6 +36,7 @@ static const char *app_name = "dtrust-tool"; enum { OPT_CAN_VERIFY = 0x100, + OPT_CAN_ENTER, OPT_CHANGE, OPT_VERIFY, OPT_RESUME, @@ -47,6 +48,7 @@ static const struct option options[] = { {"reader", 1, NULL, 'r'}, {"wait", 0, NULL, 'w'}, {"verify-can", 0, NULL, OPT_CAN_VERIFY}, + {"enter-can", 0, NULL, OPT_CAN_ENTER}, {"pin-status", 0, NULL, 's'}, {"check-transport-protection", 0, NULL, 'c'}, {"unlock-transport-protection", 0, NULL, 'u'}, @@ -63,6 +65,7 @@ static const char *option_help[] = { "Uses reader number [0]", "Wait for card insertion", "Verify Card Access Number (CAN)", + "Enter CAN explicitly", "Show PIN status", "Check transport protection", "Unlock transport protection", @@ -78,6 +81,7 @@ static const char *option_help[] = { static const char *opt_reader = NULL; static int opt_wait = 0, verbose = 0; static unsigned char opt_can_verify = 0; +static unsigned char opt_can_enter = 0; static int opt_status = 0; static int opt_check = 0; static int opt_unlock = 0; @@ -814,6 +818,9 @@ main(int argc, char *argv[]) case OPT_CAN_VERIFY: opt_can_verify = 1; break; + case OPT_CAN_ENTER: + opt_can_enter = 1; + break; case 's': opt_status = 1; break; @@ -904,10 +911,7 @@ main(int argc, char *argv[]) data.pin_type = SC_AC_CHV; data.pin_reference = PACE_PIN_ID_CAN; - if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { - data.pin1.data = NULL; - data.pin1.len = 0; - } else { + if (opt_can_enter) { r = get_pin(&can, "CAN", 0); if (r < 0) goto out; From a6fa59be799806483a9fcf69350d43c086620dc5 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 3 Feb 2025 17:49:41 +0100 Subject: [PATCH 3955/4321] dtrust-tool: cache CAN in secure memory --- src/libopensc/card-dtrust.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index e003698890..a8cc2623c3 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -67,7 +67,7 @@ struct dtrust_drv_data_t { unsigned char pace : 1; unsigned char can : 1; /* global CAN from configuration file */ - const char *can_value; + char *can_value; /* use CAN cache */ unsigned char can_cache : 1; /* PKCS#15 context for CAN caching */ @@ -262,7 +262,7 @@ static int dtrust_init(sc_card_t *card) { struct dtrust_drv_data_t *drv_data; - const char *can_env = NULL; + const char *can_env, *can_value; size_t i, j; scconf_block **found_blocks, *block; int r; @@ -283,12 +283,11 @@ dtrust_init(sc_card_t *card) drv_data->can_cache = 1; drv_data->p15card = NULL; - drv_data->can_value = can_env = getenv("DTRUST_CAN"); - if (can_env != NULL) { - sc_log(card->ctx, "Using CAN provided by environment variable."); - } + /* read environment variable */ + can_env = getenv("DTRUST_CAN"); /* read configuration */ + can_value = NULL; for (i = 0; card->ctx->conf_blocks[i]; i++) { found_blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], "card_driver", "dtrust"); if (!found_blocks) @@ -299,16 +298,30 @@ dtrust_init(sc_card_t *card) /* Environment variable has precedence over configured CAN */ if (can_env == NULL) { - drv_data->can_value = scconf_get_str(block, "can", drv_data->can_value); + can_value = scconf_get_str(block, "can", can_value); } } free(found_blocks); } - if (can_env == NULL && drv_data->can_value != NULL) { + if (can_env != NULL) { + sc_log(card->ctx, "Using CAN provided by environment variable."); + can_value = can_env; + } else if (can_value != NULL) { sc_log(card->ctx, "Using CAN provided by configuration file."); } + if (can_value != NULL) { + size_t can_len; + + can_len = strlen(can_env); + drv_data->can_value = sc_mem_secure_alloc(can_len + 1); + if (drv_data->can_value == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + memcpy(drv_data->can_value, can_value, can_len + 1); + } + card->drv_data = drv_data; r = _dtrust_get_serialnr(card); @@ -400,6 +413,11 @@ dtrust_finish(sc_card_t *card) if (drv_data->p15card != NULL) { sc_pkcs15_unbind(drv_data->p15card); } + + if (drv_data->can_value != NULL) { + sc_mem_secure_free(drv_data->can_value, strlen(drv_data->can_value) + 1); + } + free((char *)card->name); free(card->drv_data); From bd73fc397269a294ca2ae54b2deb1bc56ae802f8 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 25 Jun 2025 14:09:48 +0200 Subject: [PATCH 3956/4321] dtrust: Prevent timeout during PIN input on Windows systems fixes #3448 --- src/tools/dtrust-tool.c | 66 +++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 912fdf4dcb..5aa33f108e 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -848,29 +848,6 @@ main(int argc, char *argv[]) } } - memset(&ctx_param, 0, sizeof(ctx_param)); - ctx_param.ver = 0; - ctx_param.app_name = argv[0]; - ctx_param.debug = verbose; - if (verbose) - ctx_param.debug_file = stderr; - - r = sc_context_create(&ctx, &ctx_param); - if (r) { - fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); - return 1; - } - - r = sc_set_card_driver(ctx, "dtrust"); - if (r) { - fprintf(stderr, "Driver 'dtrust' not found!\n"); - goto out; - } - - r = util_connect_card(ctx, &card, opt_reader, opt_wait); - if (r) - goto out; - if (opt_status || opt_check) opt_can_verify = 1; @@ -900,6 +877,34 @@ main(int argc, char *argv[]) goto out; } + /* All interactive inputs have to be queried up to this point. OpenSC + * internally locks the cards, but Windows drivers release this lock + * after 5 seconds of inactivity and reset the card. Thus we have to + * prevent to reset the card while waiting for user input. */ + + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = argv[0]; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; + + r = sc_context_create(&ctx, &ctx_param); + if (r) { + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); + return 1; + } + + r = sc_set_card_driver(ctx, "dtrust"); + if (r) { + fprintf(stderr, "Driver 'dtrust' not found!\n"); + goto out; + } + + r = util_connect_card(ctx, &card, opt_reader, opt_wait); + if (r) + goto out; + /* D-Trust Card 5 requires PACE authentication with CAN */ if (opt_can_verify && card->type >= SC_CARD_TYPE_DTRUST_V5_1_STD && @@ -912,10 +917,25 @@ main(int argc, char *argv[]) data.pin_reference = PACE_PIN_ID_CAN; if (opt_can_enter) { + /* To determine whether we need to query for the CAN, + * we first need to check the card type and thus + * connect to the card. The Windows driver releases + * the card lock after 5 seconds of inactivity. Thus + * we release the card on our own, wait for the user + * input, and finally lock the card again to circumvent + * this timeout. */ + sc_unlock(card); + r = get_pin(&can, "CAN", 0); if (r < 0) goto out; + r = sc_lock(card); + if (r < 0) { + fprintf(stderr, "Failed to lock card.\n"); + goto out; + } + data.pin1.data = (const unsigned char *)can; data.pin1.len = strlen(can); } From 96219986e091709d392ddfd8faa41fb69a10b545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 23 Jul 2025 14:44:21 +0200 Subject: [PATCH 3957/4321] Fix bash completion function name The `_split_longopt` is renamed to `_comp__split_longopt` from bash-completion v2.12.0. Replace it with _init_completion. --- doc/tools/completion-template | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/tools/completion-template b/doc/tools/completion-template index 895a3a9ceb..5bf3308e23 100644 --- a/doc/tools/completion-template +++ b/doc/tools/completion-template @@ -5,7 +5,11 @@ _FUNCTION_NAME() local cur prev split=false _get_comp_words_by_ref -n : cur prev - _split_longopt && split=true + if type _init_completion &>/dev/null; then + _init_completion -s && split=true + else + _split_longopt && split=true + fi opts="ALLOPTS" From 972d19aeb72e7f9af5a6d000c40b03d4ec83bf4d Mon Sep 17 00:00:00 2001 From: MkfsSion Date: Sun, 13 Apr 2025 03:07:37 +0800 Subject: [PATCH 3958/4321] openpgp: Implement key derived PIN format (KDF-DO) as per OpenPGP card spec v3.3 --- src/libopensc/card-openpgp.c | 306 ++++++++++++++++++++++++++++++++++- src/libopensc/card-openpgp.h | 18 ++- 2 files changed, 321 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0f614212ce..b247fe34cf 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -49,6 +49,7 @@ #include "cardctl.h" #include "errors.h" #ifdef ENABLE_OPENSSL +#include #include #endif /* ENABLE_OPENSSL */ @@ -218,7 +219,7 @@ static pgp_do_info_t pgp34_objects[] = { /**** OpenPGP card spec 3.4 ****/ /* DO FC is CONSTRUCTED in spec; we treat it as SIMPLE for the time being */ { 0x00fc, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, /**** OpenPGP card spec 3.3 ****/ - { 0x00f9, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, + { DO_KDF, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, /**** OpenPGP card spec 3.0 - 3.2 ****/ { 0x00d6, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, { 0x00d7, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, @@ -792,6 +793,107 @@ _pgp_add_algo(sc_card_t *card, sc_cardctl_openpgp_key_gen_store_info_t *key_info return 1; } +#ifdef ENABLE_OPENSSL +static int +pgp_decode_kdf_do(sc_card_t *card, struct pgp_priv_data *priv) +{ + pgp_pin_kdf_info_t *pin_kdf_info = (pgp_pin_kdf_info_t *)calloc(1, sizeof(pgp_pin_kdf_info_t)); + int r = SC_ERROR_OUT_OF_MEMORY; + pgp_blob_t *kdf_blob; + const uint8_t *data; + size_t data_len; + size_t tag_len; + const uint8_t *p; + pgp_blob_t *blob; + + if (!pin_kdf_info) { + return r; + } + + r = SC_ERROR_INVALID_DATA; + priv->pin_kdf_info = NULL; + if ((pgp_get_blob(card, priv->mf, DO_KDF, &kdf_blob) != SC_SUCCESS) || (kdf_blob->len < 3)) { + sc_log(card->ctx, "KDF DO does not exists or contains invalid data but card claims to support it"); + goto out; + } + + data = kdf_blob->data; + data_len = kdf_blob->len; + p = sc_asn1_find_tag(card->ctx, data, data_len, 0x81, &tag_len); + if (!p) { + sc_log(card->ctx, "KDF algorithm byte not found"); + goto out; + } + if (tag_len != 1) { + sc_log(card->ctx, "Unexpected KDF algorithm byte length, expects 1, got %" SC_FORMAT_LEN_SIZE_T "u", tag_len); + goto out; + } + + if (*p != 0x3) { + if (*p == 0x0) { + r = SC_SUCCESS; + sc_log(card->ctx, "KDF derived PIN format disabled"); + } else { + sc_log(card->ctx, "Unknown KDF algorithm ID %x", *p); + } + goto out; + } + + p = sc_asn1_find_tag(card->ctx, data, data_len, 0x82, &tag_len); + if (!p) { + sc_log(card->ctx, "KDF hash algorithm byte not found"); + goto out; + } + if (tag_len != 1) { + sc_log(card->ctx, "Unexpected KDF hash algorithm byte length, expects 1, got %" SC_FORMAT_LEN_SIZE_T "u", tag_len); + goto out; + } + + switch (*p) { + case 0x08: + pin_kdf_info->hash_algo = "SHA256"; + break; + case 0x0A: + pin_kdf_info->hash_algo = "SHA512"; + break; + default: + sc_log(card->ctx, "Unknown KDF hash algorithm ID %x", *p); + goto out; + } + + p = sc_asn1_find_tag(card->ctx, data, data_len, 0x83, &tag_len); + if (!p) { + sc_log(card->ctx, "KDF iteration count not found"); + goto out; + } + if (tag_len != 4) { + sc_log(card->ctx, "Unexpected KDF iteration count length, expects 4, got %" SC_FORMAT_LEN_SIZE_T "u", tag_len); + goto out; + } + pin_kdf_info->iterations = (uint32_t)bebytes2ulong(p); + + r = pgp_get_blob(card, kdf_blob, 0x84, &blob); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "Failed to get salt bytes of user password"); + goto out; + } + pin_kdf_info->userpw_salt = blob; + + r = pgp_get_blob(card, kdf_blob, 0x86, &blob); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "Failed to get salt bytes of admin password"); + goto out; + } + pin_kdf_info->adminpw_salt = blob; + + sc_log(card->ctx, "KDF derived PIN format enabled"); + priv->pin_kdf_info = pin_kdf_info; + return r; +out: + free(pin_kdf_info); + return r; +} +#endif /* ENABLE_OPENSSL */ /** * Internal: get features of the card: capabilities, ... @@ -883,6 +985,9 @@ pgp_get_card_features(sc_card_t *card) /* get "extended capabilities" DO */ if ((pgp_get_blob(card, blob73, 0x00c0, &blob) >= 0) && (blob->data != NULL) && (blob->len > 0)) { + if ((blob->data[0] & 0x01) && (priv->bcd_version >= OPENPGP_CARD_3_3)) { + priv->ext_caps |= EXT_CAP_KDF_DO; + } /* v2.0+: bit 0x04 in first byte means "algorithm attributes changeable" */ if ((blob->data[0] & 0x04) && (priv->bcd_version >= OPENPGP_CARD_2_0)) @@ -956,6 +1061,15 @@ pgp_get_card_features(sc_card_t *card) } } +#ifdef ENABLE_OPENSSL + if (priv->ext_caps & EXT_CAP_KDF_DO) { + int r = pgp_decode_kdf_do(card, priv); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "Failed to decode KDF DO: %s", sc_strerror(r)); + } + } +#endif /* ENABLE_OPENSSL */ + /* if we found at least one usable algo, let's skip other ways to find them */ if (handled_algos) { sc_log(card->ctx, "Algo list populated from Algorithm Information DO"); @@ -1000,6 +1114,9 @@ pgp_finish(sc_card_t *card) /* delete fake file hierarchy */ pgp_free_blobs(priv->mf); + /* delete kdf do related data if exists */ + free(priv->pin_kdf_info); + /* delete private data */ free(priv); } @@ -2082,6 +2199,184 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) LOG_FUNC_RETURN(card->ctx, (int)buf_len); } +#ifdef ENABLE_OPENSSL +/* KDF_ITERSALTED_S2K algorithm, a simplified version of openpgp_s2k from libgcrypt[1] + * that supports one-pass only and outputs the same key length as the hash length of + * the specified hash algorithm. + * [1]: https://github.com/gpg/libgcrypt/blob/libgcrypt-1.11.0/cipher/kdf.c#L32-L109 + */ +static int +kdf_itersalted_s2k(struct sc_context *ctx, const char *hash, const uint8_t *pin, size_t pinlen, const uint8_t *salt, size_t saltlen, uint32_t iterations, uint8_t **out, size_t *outlen) +{ + int r = SC_ERROR_INVALID_ARGUMENTS; + EVP_MD *md = NULL; + EVP_MD_CTX *hctx = NULL; + int keysize; + uint8_t *outkey = NULL; + size_t count; + int ret; + unsigned int outsize; + + if (!ctx || !hash || !pin || pinlen == 0 || !salt || saltlen != 8 || !out || !outlen) { + return r; + } + + md = sc_evp_md(ctx, hash); + if (md == NULL) { + return r; + } + + r = SC_ERROR_INTERNAL; + hctx = EVP_MD_CTX_new(); + if (hctx == NULL) { + goto out; + } + + if (!EVP_DigestInit(hctx, md)) { + goto out; + } + + keysize = EVP_MD_size(md); + if (keysize <= 0) { + goto out; + } + + outkey = (uint8_t *)sc_mem_secure_alloc(keysize); + if (outkey == NULL) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto out; + } + + count = iterations; + if (count < pinlen + saltlen) { + count = pinlen + saltlen; + } + + while (count >= pinlen + saltlen) { + ret = EVP_DigestUpdate(hctx, salt, saltlen); + if (!ret) { + goto out; + } + ret = EVP_DigestUpdate(hctx, pin, pinlen); + if (!ret) { + goto out; + } + count -= pinlen + saltlen; + } + + if (count <= saltlen) { + ret = EVP_DigestUpdate(hctx, salt, count); + } else { + ret = EVP_DigestUpdate(hctx, salt, saltlen); + if (!ret) { + goto out; + } + count -= saltlen; + ret = EVP_DigestUpdate(hctx, pin, count); + } + if (!ret) { + goto out; + } + + outsize = keysize; + ret = EVP_DigestFinal(hctx, outkey, &outsize); + if (ret && outsize == (unsigned int)keysize) { + r = SC_SUCCESS; + } +out: + if (r != SC_SUCCESS && outkey != NULL) { + sc_mem_secure_clear_free(outkey, keysize); + } + EVP_MD_CTX_free(hctx); + sc_evp_md_free(md); + if (r == SC_SUCCESS) { + *out = outkey; + *outlen = outsize; + } + return r; +} + +static int +pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + int r = SC_ERROR_INVALID_ARGUMENTS; + struct pgp_priv_data *priv = DRVDATA(card); + const pgp_pin_kdf_info_t *const info = priv->pin_kdf_info; + uint8_t *pin1_derived = NULL; + uint8_t *pin2_derived = NULL; + size_t pin1_derived_len = 0; + size_t pin2_derived_len = 0; + const uint8_t *const pin1 = data->pin1.data; + const size_t pin1len = data->pin1.len; + const uint8_t *const pin2 = data->pin2.data; + const size_t pin2len = data->pin2.len; + const uint8_t *salt = NULL; + size_t saltlen = 0; + + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + case SC_PIN_CMD_CHANGE: + case SC_PIN_CMD_UNBLOCK: + break; + default: + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); + } + if (!info) { + return r; + } + + switch (data->pin_reference) { + case 0x81: + case 0x82: + salt = info->userpw_salt->data; + saltlen = info->userpw_salt->len; + break; + case 0x83: + salt = info->adminpw_salt->data; + saltlen = info->adminpw_salt->len; + break; + } + + switch (data->cmd) { + case SC_PIN_CMD_UNBLOCK: + case SC_PIN_CMD_CHANGE: + r = kdf_itersalted_s2k(card->ctx, info->hash_algo, pin2, pin2len, salt, saltlen, info->iterations, &pin2_derived, &pin2_derived_len); + if (r != SC_SUCCESS) { + break; + } + data->pin2.data = pin2_derived; + data->pin2.len = pin2_derived_len; + if (data->cmd == SC_PIN_CMD_UNBLOCK) { + salt = info->adminpw_salt->data; + saltlen = info->adminpw_salt->len; + } + // fallthrough + case SC_PIN_CMD_VERIFY: + r = kdf_itersalted_s2k(card->ctx, info->hash_algo, pin1, pin1len, salt, saltlen, info->iterations, &pin1_derived, &pin1_derived_len); + if (r != SC_SUCCESS) { + break; + } + data->pin1.data = pin1_derived; + data->pin1.len = pin1_derived_len; + break; + } + + if (r == SC_SUCCESS) { + r = iso_ops->pin_cmd(card, data, tries_left); + } + if (pin1_derived) { + data->pin1.data = pin1; + data->pin1.len = pin1len; + sc_mem_secure_clear_free(pin1_derived, pin1_derived_len); + } + if (pin2_derived) { + data->pin2.data = pin2; + data->pin2.len = pin2len; + sc_mem_secure_clear_free(pin2_derived, pin2_derived_len); + } + LOG_FUNC_RETURN(card->ctx, r); +} +#endif /* ENABLE_OPENSSL */ /** * ABI: ISO 7816-9 PIN CMD - verify/change/unblock a PIN. @@ -2090,6 +2385,7 @@ static int pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { struct pgp_priv_data *priv = DRVDATA(card); + struct sc_card_operations ops = {.pin_cmd = iso_ops->pin_cmd}; LOG_FUNC_CALLED(card->ctx); @@ -2181,7 +2477,13 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); +#ifdef ENABLE_OPENSSL + if (priv->pin_kdf_info) { + ops.pin_cmd = &pgp_kdf_do_pin_cmd; + } +#endif /* ENABLE_OPENSSL */ + + LOG_FUNC_RETURN(card->ctx, ops.pin_cmd(card, data, tries_left)); } diff --git a/src/libopensc/card-openpgp.h b/src/libopensc/card-openpgp.h index 85fc14865a..26cdf1d553 100644 --- a/src/libopensc/card-openpgp.h +++ b/src/libopensc/card-openpgp.h @@ -66,7 +66,9 @@ typedef enum _pgp_access { /* access flags for the respective DO/file */ WRITE_MASK = 0x1F00 } pgp_access_t; +// clang-format off typedef enum _pgp_ext_caps { /* extended capabilities/features: bit flags */ + EXT_CAP_KDF_DO = 0x0001, EXT_CAP_ALG_ATTR_CHANGEABLE = 0x0004, EXT_CAP_PRIVATE_DO = 0x0008, EXT_CAP_C4_CHANGEABLE = 0x0010, @@ -78,6 +80,7 @@ typedef enum _pgp_ext_caps { /* extended capabilities/features: bit flags */ EXT_CAP_APDU_EXT = 0x2000, EXT_CAP_MSE = 0x4000 } pgp_ext_caps_t; +// clang-format on typedef enum _pgp_card_state { CARD_STATE_UNKNOWN = 0x00, @@ -122,7 +125,14 @@ typedef struct pgp_blob { struct pgp_blob *files; /* pointer to 1st child */ } pgp_blob_t; +typedef struct _pgp_pin_kdf_info { + const char *hash_algo; + uint32_t iterations; + pgp_blob_t *userpw_salt; + pgp_blob_t *adminpw_salt; +} pgp_pin_kdf_info_t; +// clang-format off /* The DO holding X.509 certificate is constructed but does not contain a child DO. * We should notice this when building fake file system later. */ #define DO_CERT 0x7f21 @@ -145,6 +155,8 @@ typedef struct pgp_blob { #define DO_NAME 0x5b #define DO_LANG_PREF 0x5f2d #define DO_SEX 0x5f35 +/* KDF-DO */ +#define DO_KDF 0xf9 /* Maximum length for response buffer when reading pubkey. @@ -158,7 +170,7 @@ typedef struct pgp_blob { * v3.0+: max. special DO size is at bytes 7-8 of Extended Capabilities DO 00C0 * Theoretically we should have the 64k, but we currently limit to 8k. */ #define MAX_OPENPGP_DO_SIZE 8192 - +// clang-format on typedef struct _pgp_ec_curves { struct sc_object_id oid; @@ -176,6 +188,7 @@ typedef struct _pgp_ec_curves_alt { #define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) +// clang-format off struct pgp_priv_data { pgp_blob_t *mf; pgp_blob_t *current; /* currently selected file */ @@ -188,6 +201,8 @@ struct pgp_priv_data { pgp_sm_algo_t sm_algo; /* Secure Messaging algorithm */ + pgp_pin_kdf_info_t *pin_kdf_info; /* KDF-DO */ + size_t max_challenge_size; size_t max_cert_size; size_t max_specialDO_size; @@ -196,6 +211,7 @@ struct pgp_priv_data { sc_security_env_t sec_env; }; +// clang-format on #define BCD2UCHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F)) From 5f39aa9ceabfc3d2b6b7698cae4074393fc7de09 Mon Sep 17 00:00:00 2001 From: MkfsSion Date: Fri, 22 Aug 2025 15:15:46 +0800 Subject: [PATCH 3959/4321] openpgp: Fix retry counter for card does not support query PIN status by VERIFY command According to OpenPGP spec, DO C4 is a simple DO which means response of GET DATA is not TLV encoded data. So retry counter bytes starts from byte 5 (count from 1) of buffer. Since 81 <= PIN reference <= 83, access to error counter would start from byte 6 of buffer and get wrong data. --- src/libopensc/card-openpgp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index b247fe34cf..1c32335198 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2468,9 +2468,9 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) LOG_TEST_RET(card->ctx, SC_ERROR_OBJECT_NOT_VALID, "CHV status bytes have unexpected length"); - data->pin1.tries_left = c4data[4 + (data->pin_reference & 0x0F)]; - data->pin1.max_tries = 3; - data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; + data->pin1.tries_left = c4data[3 + (data->pin_reference & 0x0F)]; + data->pin1.max_tries = 3; + data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; if (tries_left != NULL) *tries_left = data->pin1.tries_left; From 63ad34d69154fd6473fb9e83ef67708113ca90c4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 14 Aug 2025 11:38:21 +0200 Subject: [PATCH 3960/4321] pkcs11: Add missing CKR messages to print Signed-off-by: Jakub Jelen --- src/pkcs11/pkcs11-display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index a8a498cd58..9c9b538dda 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -611,6 +611,7 @@ static enum_specs ck_err_s[] = { { CKR_ATTRIBUTE_SENSITIVE, "CKR_ATTRIBUTE_SENSITIVE" }, { CKR_ATTRIBUTE_TYPE_INVALID, "CKR_ATTRIBUTE_TYPE_INVALID" }, { CKR_ATTRIBUTE_VALUE_INVALID, "CKR_ATTRIBUTE_VALUE_INVALID" }, + { CKR_ACTION_PROHIBITED, "CKR_ACTION_PROHIBITED" }, { CKR_DATA_INVALID, "CKR_DATA_INVALID" }, { CKR_DATA_LEN_RANGE, "CKR_DATA_LEN_RANGE" }, { CKR_DEVICE_ERROR, "CKR_DEVICE_ERROR" }, @@ -673,6 +674,7 @@ static enum_specs ck_err_s[] = { { CKR_RANDOM_SEED_NOT_SUPPORTED, "CKR_RANDOM_SEED_NOT_SUPPORTED" }, { CKR_RANDOM_NO_RNG, "CKR_RANDOM_NO_RNG" }, { CKR_DOMAIN_PARAMS_INVALID, "CKR_DOMAIN_PARAMS_INVALID" }, + { CKR_CURVE_NOT_SUPPORTED, "CKR_CURVE_NOT_SUPPORTED" }, { CKR_BUFFER_TOO_SMALL, "CKR_BUFFER_TOO_SMALL" }, { CKR_SAVED_STATE_INVALID, "CKR_SAVED_STATE_INVALID" }, { CKR_INFORMATION_SENSITIVE, "CKR_INFORMATION_SENSITIVE" }, @@ -681,6 +683,7 @@ static enum_specs ck_err_s[] = { { CKR_CRYPTOKI_ALREADY_INITIALIZED, "CKR_CRYPTOKI_ALREADY_INITIALIZED" }, { CKR_MUTEX_BAD, "CKR_MUTEX_BAD" }, { CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED" }, + { CKR_FUNCTION_REJECTED, "CKR_FUNCTION_REJECTED" }, { CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED" } }; From 78d1e7cca1b8b76ac56bd7e1c832fce8c097bd0f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 1 Sep 2025 22:46:57 +0200 Subject: [PATCH 3961/4321] DNIe: Always select MF without SM to delete session at card Explicitly disabling SM is, for example, done at logout, finish and init which sets the card into a usable state when being used concurrently fixes https://github.com/OpenSC/OpenSC/issues/3466 --- src/libopensc/card-dnie.c | 12 ++---------- src/libopensc/cwa14890.c | 6 +++++- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 50e8a78f0a..fd40d96e55 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -846,8 +846,8 @@ static int dnie_init(struct sc_card *card) card->sm_ctx.ops.free_sm_apdu = dnie_sm_free_wrapped_apdu; card->sm_ctx.sm_mode = SM_MODE_NONE; - res=cwa_create_secure_channel(card,provider,CWA_SM_OFF); - LOG_TEST_RET(card->ctx, res, "Failure creating CWA secure channel."); + res = cwa_create_secure_channel(card, provider, CWA_SM_OFF); + LOG_TEST_RET(card->ctx, res, "Failure resetting CWA secure channel."); /* initialize private data */ card->drv_data = calloc(1, sizeof(dnie_private_data_t)); @@ -1355,7 +1355,6 @@ static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len) static int dnie_logout(struct sc_card *card) { int result = SC_SUCCESS; - sc_file_t *file = NULL; if ((card == NULL) || (card->ctx == NULL)) return SC_ERROR_INVALID_ARGUMENTS; @@ -1366,15 +1365,8 @@ static int dnie_logout(struct sc_card *card) result = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF); LOG_TEST_RET(card->ctx, result, "Cannot close the secure channel"); - /* request the Master File to provoke an SM error and close the channel */ - result = dnie_compose_and_send_apdu(card, (const u8 *) DNIE_MF_NAME, - sizeof(DNIE_MF_NAME) - 1, 4, &file); - if (result == SC_ERROR_SM) - result = SC_SUCCESS; } - if (file != NULL) - sc_file_free(file); LOG_FUNC_RETURN(card->ctx, result); } diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 715b79094d..a5ff0061f8 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1136,7 +1136,11 @@ int cwa_create_secure_channel(sc_card_t * card, case CWA_SM_OFF: /* disable SM */ card->sm_ctx.sm_mode = SM_MODE_NONE; sc_log(ctx, "Setting CWA SM status to none"); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + /* request the Master File to provoke an SM error and close the channel */ + res = sc_select_file(card, sc_get_mf_path(), NULL); + if (res == SC_ERROR_SM) + res = SC_SUCCESS; + LOG_FUNC_RETURN(ctx, res); case CWA_SM_ON: /* force sm initialization process */ sc_log(ctx, "CWA SM initialization requested"); break; From 79f5059135a5ac7b71258b196986e81d71a4256c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 2 Sep 2025 00:10:34 +0200 Subject: [PATCH 3962/4321] DNIe: fixed memory leak on card initialization --- src/libopensc/card-dnie.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index fd40d96e55..b57db099ef 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -847,18 +847,23 @@ static int dnie_init(struct sc_card *card) card->sm_ctx.sm_mode = SM_MODE_NONE; res = cwa_create_secure_channel(card, provider, CWA_SM_OFF); + if (res < 0) + free(provider); LOG_TEST_RET(card->ctx, res, "Failure resetting CWA secure channel."); /* initialize private data */ card->drv_data = calloc(1, sizeof(dnie_private_data_t)); - if (card->drv_data == NULL) + if (card->drv_data == NULL) { + free(provider); LOG_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Could not allocate DNIe private data."); + } #ifdef ENABLE_DNIE_UI /* read environment from configuration file */ res = dnie_get_environment(card, &(GET_DNIE_UI_CTX(card))); if (res != SC_SUCCESS) { free(card->drv_data); + free(provider); LOG_TEST_RET(card->ctx, res, "Failure reading DNIe environment."); } #endif From 3b2452e4f818a83e6a59afe58be7d188dbb2bc4c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Aug 2025 12:11:07 +0200 Subject: [PATCH 3963/4321] pkcs11-tool: Avoid memory overrun Thanks coverity! CID 487665 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 191715bb65..6ba894c215 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -9297,7 +9297,7 @@ p11_utf8_to_string(CK_UTF8CHAR *string, size_t len) while (len && string[len - 1] == ' ') len--; - if (len < 1 || !(buffer = calloc(len, sizeof(char)))) { + if (len < 1 || !(buffer = calloc(len + 1, sizeof(char)))) { return NULL; } From e0b231d1ce7cfc32ab5656c4d0ee1ac8868951bb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Aug 2025 12:19:13 +0200 Subject: [PATCH 3964/4321] pkcs11_uri: Avoid potential NULL dereference The issue reported by coverity is false positive, but we can sanitize inputs to the parse_string function to make it more clear to the analyzer. CID 487664 Signed-off-by: Jakub Jelen --- src/tools/pkcs11_uri.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/pkcs11_uri.c b/src/tools/pkcs11_uri.c index 6b768389fa..ef4e883919 100644 --- a/src/tools/pkcs11_uri.c +++ b/src/tools/pkcs11_uri.c @@ -119,6 +119,10 @@ parse_string(char *argument, char **out, int *out_len, int max_len) { int rv = 0, len = 0; char *tmp = NULL; + if (out == NULL) { + fprintf(stderr, "Wrong parameters provided\n"); + return 1; + } if (*out != NULL) { rv = 1; fprintf(stderr, "Attribute already set\n"); From c170808934512a0a07050889d4d417e7891764c2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Aug 2025 12:21:43 +0200 Subject: [PATCH 3965/4321] fuzzer: Avoid memory leak CID 487663 Signed-off-by: Jakub Jelen --- src/tests/fuzzing/fuzz_pkcs11_uri.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11_uri.c b/src/tests/fuzzing/fuzz_pkcs11_uri.c index b248fde12a..2ceed7b9ac 100644 --- a/src/tests/fuzzing/fuzz_pkcs11_uri.c +++ b/src/tests/fuzzing/fuzz_pkcs11_uri.c @@ -44,8 +44,10 @@ LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) memcpy(input_string, Data, Size); input_string[Size] = 0; - if ((uri = pkcs11_uri_new()) == NULL) + if ((uri = pkcs11_uri_new()) == NULL) { + free(input_string); return 0; + } parse_pkcs11_uri(input_string, uri); pkcs11_uri_free(uri); From e5db4d502d4a7bf726c2ee8923879e7cc15cc2f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Aug 2025 13:01:15 +0200 Subject: [PATCH 3966/4321] dtrust: Fix possible NULL pointer dereference If I understand the code, right, it should be the can_value, rather than the can_env here. Thanks coverity. CID 487696 Signed-off-by: Jakub Jelen --- src/libopensc/card-dtrust.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index a8cc2623c3..fcc73464b0 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -314,7 +314,7 @@ dtrust_init(sc_card_t *card) if (can_value != NULL) { size_t can_len; - can_len = strlen(can_env); + can_len = strlen(can_value); drv_data->can_value = sc_mem_secure_alloc(can_len + 1); if (drv_data->can_value == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); From 92fe011a9cc5e03a1c9a2127d33b603e6d24907e Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 10 Sep 2025 14:48:44 +0200 Subject: [PATCH 3967/4321] dtrust: Fix NULL pointer dereference --- src/tools/dtrust-tool.c | 51 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 5aa33f108e..4596c4617a 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -848,6 +848,29 @@ main(int argc, char *argv[]) } } + memset(&ctx_param, 0, sizeof(ctx_param)); + ctx_param.ver = 0; + ctx_param.app_name = argv[0]; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; + + r = sc_context_create(&ctx, &ctx_param); + if (r) { + fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); + return 1; + } + + r = sc_set_card_driver(ctx, "dtrust"); + if (r) { + fprintf(stderr, "Driver 'dtrust' not found!\n"); + goto out; + } + + r = util_connect_card(ctx, &card, opt_reader, opt_wait); + if (r) + goto out; + if (opt_status || opt_check) opt_can_verify = 1; @@ -877,34 +900,6 @@ main(int argc, char *argv[]) goto out; } - /* All interactive inputs have to be queried up to this point. OpenSC - * internally locks the cards, but Windows drivers release this lock - * after 5 seconds of inactivity and reset the card. Thus we have to - * prevent to reset the card while waiting for user input. */ - - memset(&ctx_param, 0, sizeof(ctx_param)); - ctx_param.ver = 0; - ctx_param.app_name = argv[0]; - ctx_param.debug = verbose; - if (verbose) - ctx_param.debug_file = stderr; - - r = sc_context_create(&ctx, &ctx_param); - if (r) { - fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); - return 1; - } - - r = sc_set_card_driver(ctx, "dtrust"); - if (r) { - fprintf(stderr, "Driver 'dtrust' not found!\n"); - goto out; - } - - r = util_connect_card(ctx, &card, opt_reader, opt_wait); - if (r) - goto out; - /* D-Trust Card 5 requires PACE authentication with CAN */ if (opt_can_verify && card->type >= SC_CARD_TYPE_DTRUST_V5_1_STD && From 23dcca082fa35eb454f8a2add163dfd506eab434 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 17 Jun 2025 12:31:36 +0300 Subject: [PATCH 3968/4321] Fix Arm64 paths and improve nmake makefiles Signed-off-by: Raul Metsma --- configure.ac | 1 + src/common/libscdl.c | 19 +++++++++- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 5 +-- src/libopensc/card.c | 37 +++++++++---------- src/libopensc/ctx.c | 6 +-- .../{libopensc.exports => opensc.exports} | 0 src/minidriver/Makefile.am | 4 +- src/minidriver/Makefile.mak | 5 +-- src/minidriver/minidriver.c | 4 +- ...iver.exports => opensc-minidriver.exports} | 0 src/pkcs11/pkcs11-spy.c | 12 +++--- src/pkcs15init/profile.c | 2 +- src/smm/Makefile.mak | 5 +-- src/tools/Makefile.am | 6 --- win32/Make.rules.mak | 13 +++++-- win32/Makefile.mak | 5 +-- win32/OpenSC.wxs.in | 33 +++++++---------- win32/customactions.cpp | 4 +- win32/winconfig.h.in | 21 +++++++---- 20 files changed, 95 insertions(+), 91 deletions(-) rename src/libopensc/{libopensc.exports => opensc.exports} (100%) rename src/minidriver/{minidriver.exports => opensc-minidriver.exports} (100%) diff --git a/configure.ac b/configure.ac index 9fa43c6f4e..37c74b22fe 100644 --- a/configure.ac +++ b/configure.ac @@ -1099,6 +1099,7 @@ AC_DEFINE_UNQUOTED([OPENSC_VS_FF_COMMENTS], ["${OPENSC_VS_FF_COMMENTS}"], [OpenS AC_DEFINE_UNQUOTED([OPENSC_VS_FF_PRODUCT_NAME], ["${OPENSC_VS_FF_PRODUCT_NAME}"], [OpenSC version-info ProductName]) AC_DEFINE_UNQUOTED([OPENSC_VS_FF_PRODUCT_UPDATES], ["${OPENSC_VS_FF_PRODUCT_UPDATES}"], [OpenSC version-info UpdateURL]) AC_DEFINE_UNQUOTED([OPENSC_VS_FF_COMPANY_URL], ["${OPENSC_VS_FF_COMPANY_URL}"], [OpenSC version-info UpdateURL]) +AC_DEFINE_UNQUOTED([OPENSC_ARCH_SUFFIX], [""], [OpenSC architecture suffix]) pkcs11dir="\$(libdir)/pkcs11" diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 92f9f9ca3f..7ee50f3d4e 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -25,8 +25,9 @@ #include "libscdl.h" #ifdef _WIN32 -#include #include +#include +#include void *sc_dlopen(const char *filename) { @@ -41,7 +42,21 @@ void *sc_dlsym(void *handle, const char *symbol) const char *sc_dlerror() { - return "LoadLibrary/GetProcAddress failed"; + static char msg[1024]; + DWORD err = GetLastError(); + DWORD rv = 0; + + if (err == ERROR_BAD_EXE_FORMAT) { + return "LoadLibrary/GetProcAddress failed: check module architecture matches application architecture"; + } + + rv = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + msg, sizeof(msg), NULL); + if (rv == 0) { + snprintf(msg, sizeof(msg), "LoadLibrary/GetProcAddress failed: %lx", err); + } + return msg; } int sc_dlclose(void *handle) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 428ed1865d..eb17dfe7e6 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -70,7 +70,7 @@ libopensc_la_LIBTOOLFLAGS = --tag CC libopensc_static_la_LIBTOOLFLAGS = --tag CC libopensc_la_SOURCES = $(libopensc_la_SOURCES_BASE) \ - libopensc.exports + opensc.exports libopensc_static_la_SOURCES = $(libopensc_la_SOURCES_BASE) if WIN32 @@ -91,7 +91,7 @@ endif libopensc_static_la_LIBADD = $(libopensc_la_LIBADD) libopensc_la_LDFLAGS = $(AM_LDFLAGS) \ -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@ \ - -export-symbols "$(srcdir)/libopensc.exports" \ + -export-symbols "$(srcdir)/opensc.exports" \ -no-undefined if WIN32 diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 9be75761ab..026fe52b80 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -52,10 +52,7 @@ all: $(TOPDIR)\win32\versioninfo.res $(TARGET) !INCLUDE $(TOPDIR)\win32\Make.rules.mak -opensc.dll: $(OBJECTS) $(LIBS) - echo LIBRARY $* > $*.def - echo EXPORTS >> $*.def - type lib$*.exports >> $*.def +opensc.dll: $(OBJECTS) $(LIBS) $*.def link $(LINKFLAGS) /dll /out:$@ /def:$*.def /implib:$*.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib shlwapi.lib opensc_a.lib: $(OBJECTS) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index d13922cdb1..f79989e5d9 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -1534,11 +1534,7 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo int rv = SC_ERROR_INTERNAL; char *module = NULL; #ifdef _WIN32 - char temp_path[PATH_MAX]; - size_t temp_len; const char path_delim = '\\'; - char expanded_val[PATH_MAX]; - DWORD expanded_len; #else const char path_delim = '/'; #endif @@ -1551,21 +1547,6 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo if (!in_module) return sc_card_sm_unload(card); -#ifdef _WIN32 - if (!module_path || strlen(module_path) == 0) { - temp_len = PATH_MAX-1; - rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\OpenSC Project\\OpenSC", - temp_path, &temp_len); - if (rv == SC_SUCCESS) { - temp_path[temp_len] = '\0'; - module_path = temp_path; - } - } - expanded_len = PATH_MAX; - expanded_len = ExpandEnvironmentStringsA(module_path, expanded_val, expanded_len); - if (0 < expanded_len && expanded_len < sizeof expanded_val) - module_path = expanded_val; -#endif sc_log(ctx, "SM module '%s' located in '%s'", in_module, module_path); if (module_path && strlen(module_path) > 0) { size_t sz = strlen(in_module) + strlen(module_path) + 3; @@ -1643,6 +1624,12 @@ sc_card_sm_check(struct sc_card *card) struct sc_context *ctx = card->ctx; scconf_block *atrblock = NULL, *sm_conf_block = NULL; int rv, ii; +#ifdef _WIN32 + char temp_path[PATH_MAX]; + size_t temp_len = PATH_MAX - 1; + char expanded_val[PATH_MAX]; + DWORD expanded_len = PATH_MAX; +#endif LOG_FUNC_CALLED(ctx); @@ -1672,7 +1659,19 @@ sc_card_sm_check(struct sc_card *card) LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "SM configuration block not preset"); /* check if an external SM module has to be used */ +#ifdef _WIN32 + rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX, + temp_path, &temp_len); + if (rv == SC_SUCCESS) { + temp_path[temp_len] = '\0'; + module_path = temp_path; + } + expanded_len = ExpandEnvironmentStringsA(module_path, expanded_val, expanded_len); + if (0 < expanded_len && expanded_len < sizeof expanded_val) + module_path = expanded_val; +#else module_path = scconf_get_str(sm_conf_block, "module_path", DEFAULT_SM_MODULE_PATH); +#endif module_name = scconf_get_str(sm_conf_block, "module_name", DEFAULT_SM_MODULE); sc_log(ctx, "SM module '%s' in '%s'", module_name, module_path); if (!module_name) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 6c677bc0fb..9e3bc49893 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -214,7 +214,7 @@ sc_ctx_win32_get_config_value(const char *name_env, return SC_ERROR_INVALID_ARGUMENTS; if (!name_key) - name_key = "Software\\OpenSC Project\\OpenSC"; + name_key = "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX; rc = RegOpenKeyExA(HKEY_CURRENT_USER, name_key, 0, KEY_QUERY_VALUE, &hKey); if (rc == ERROR_SUCCESS) { @@ -709,8 +709,8 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks)); #ifdef _WIN32 temp_len = PATH_MAX-1; - r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC", - temp_path, &temp_len); + r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX, + temp_path, &temp_len); if (r) { sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key."); return; diff --git a/src/libopensc/libopensc.exports b/src/libopensc/opensc.exports similarity index 100% rename from src/libopensc/libopensc.exports rename to src/libopensc/opensc.exports diff --git a/src/minidriver/Makefile.am b/src/minidriver/Makefile.am index 29d944f4d0..d116784ef9 100644 --- a/src/minidriver/Makefile.am +++ b/src/minidriver/Makefile.am @@ -15,13 +15,13 @@ endif AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPENPACE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -opensc_minidriver@LIBRARY_BITNESS@_la_SOURCES = minidriver.c minidriver.exports versioninfo-minidriver.rc +opensc_minidriver@LIBRARY_BITNESS@_la_SOURCES = minidriver.c opensc-minidriver.exports versioninfo-minidriver.rc opensc_minidriver@LIBRARY_BITNESS@_la_LIBADD = \ $(top_builddir)/src/libopensc/libopensc_static.la \ $(OPTIONAL_OPENSSL_LIBS) \ -lbcrypt -lcrypt32 -lrpcrt4 -lwinmm opensc_minidriver@LIBRARY_BITNESS@_la_LDFLAGS = $(AM_LDFLAGS) \ - -export-symbols "$(srcdir)/minidriver.exports" \ + -export-symbols "$(srcdir)/opensc-minidriver.exports" \ -module -avoid-version -no-undefined if ENABLE_MINIDRIVER diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index 8fa7984391..2130c62b32 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -16,8 +16,5 @@ all: $(TARGET) !INCLUDE $(TOPDIR)\win32\Make.rules.mak -$(TARGET): $(OBJECTS) $(LIBS) - echo LIBRARY $* > $*.def - echo EXPORTS >> $*.def - type minidriver.exports >> $*.def +$(TARGET): $(OBJECTS) $(LIBS) $*.def link /dll $(LINKFLAGS) /out:$@ /def:$*.def $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib Shell32.lib Comctl32.lib Winmm.lib shlwapi.lib /DELAYLOAD:bcrypt.dll diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 15012f3558..1ffc74489b 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -150,7 +150,7 @@ HINSTANCE g_inst; /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ #define IDI_SMARTCARD 102 -#define SUBKEY_ENABLE_CANCEL "Software\\OpenSC Project\\OpenSC\\md_pinpad_dlg_enable_cancel" +#define SUBKEY_ENABLE_CANCEL "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX "\\md_pinpad_dlg_enable_cancel" /* magic to determine previous pinpad authentication */ #define MAGIC_SESSION_PIN "opensc-minidriver" @@ -268,7 +268,7 @@ static void logprintf(PCARD_DATA pCardData, int level, _Printf_format_string_ co int rv; rv = sc_ctx_win32_get_config_value("CARDMOD_LOW_LEVEL_DEBUG", - "MiniDriverDebug", "Software\\OpenSC Project\\OpenSC", + "MiniDriverDebug", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX, (char *)(&md_debug), &sz); if (rv == SC_SUCCESS && md_debug != 0) { FILE *lldebugfp = fopen("C:\\tmp\\md.log","a+"); diff --git a/src/minidriver/minidriver.exports b/src/minidriver/opensc-minidriver.exports similarity index 100% rename from src/minidriver/minidriver.exports rename to src/minidriver/opensc-minidriver.exports diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 1ed2a5d200..6b2a30ca05 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -235,9 +235,9 @@ init_spy(void) /* try for the machine version first, as we may be running * without a user during login */ - rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\PKCS11-Spy", 0, KEY_QUERY_VALUE, &hKey ); + rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\PKCS11-Spy" OPENSC_ARCH_SUFFIX, 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS ) - rc = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\OpenSC Project\\PKCS11-Spy", 0, KEY_QUERY_VALUE, &hKey ); + rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\PKCS11-Spy" OPENSC_ARCH_SUFFIX, 0, KEY_QUERY_VALUE, &hKey); if( rc == ERROR_SUCCESS ) { temp_len = PATH_MAX; @@ -270,11 +270,11 @@ init_spy(void) /* try for the machine version first, as we may be running * without a user during login */ - rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\PKCS11-Spy", - 0, KEY_QUERY_VALUE, &hKey ); + rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\PKCS11-Spy" OPENSC_ARCH_SUFFIX, + 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) - rc = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\OpenSC Project\\PKCS11-Spy", - 0, KEY_QUERY_VALUE, &hKey ); + rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\PKCS11-Spy" OPENSC_ARCH_SUFFIX, + 0, KEY_QUERY_VALUE, &hKey); if (rc == ERROR_SUCCESS) { temp_len = PATH_MAX; diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index f22798d9f8..85bd8438b5 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -344,7 +344,7 @@ sc_profile_load(struct sc_profile *profile, const char *filename) if (!profile_dir) { #ifdef _WIN32 temp_len = PATH_MAX - 1; - res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\OpenSC Project\\OpenSC", + res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX, temp_path, &temp_len); if (res) LOG_FUNC_RETURN(ctx, res); diff --git a/src/smm/Makefile.mak b/src/smm/Makefile.mak index fb3395fa92..ca06ecc47f 100644 --- a/src/smm/Makefile.mak +++ b/src/smm/Makefile.mak @@ -20,10 +20,7 @@ all: $(TARGET) !INCLUDE $(TOPDIR)\win32\Make.rules.mak !IF "$(OPENSSL_DEF)" == "/DENABLE_OPENSSL" -$(TARGET): $(OBJECTS) $(LIBS) - echo LIBRARY $* > $*.def - echo EXPORTS >> $*.def - type $*.exports >> $*.def +$(TARGET): $(OBJECTS) $(LIBS) $*.def link /dll $(LINKFLAGS) /out:$@ /def:$*.def $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib Shell32.lib Comctl32.lib shlwapi.lib !ELSE diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index d2bd4c614b..dbfc518dc5 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -9,14 +9,8 @@ endif do_subst = $(SED) \ -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]CVCDIR[@],$(CVCDIR),g' \ - -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ - -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \ - -e 's,[@]PACKAGE_TARNAME[@],$(PACKAGE_TARNAME),g' \ - -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ - -e 's,[@]PACKAGE_VERSION[@],"$(PACKAGE_VERSION)",g' \ - -e 's,[@]DEFAULT_PKCS11_PROVIDER[@],"$(DEFAULT_PKCS11_PROVIDER)",g' \ -e 's,[@]PKCS11_REGISTER_SKIP_FIREFOX[@],$(PKCS11_REGISTER_SKIP_FIREFOX),g' \ -e 's,[@]VDFORMAT[@],$(VDFORMAT),g' \ -e 's,[@]X509DIR[@],$(X509DIR),g' diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 72c0295520..cb5fd8c5b5 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -117,9 +117,9 @@ WIXFLAGS = -d OpenPACE="$(OPENPACE_DIR)" $(WIXFLAGS) # Used for MiniDriver CPDK_INCL_DIR = "/IC:\Program Files (x86)\Windows Kits\10\Cryptographic Provider Development Kit\Include" +DEFS = /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /DHAVE_CONFIG_H \ - /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" \ - $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) \ + $(DEFS) $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) \ /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) LINKFLAGS = /nologo /INCREMENTAL:NO /NXCOMPAT /DYNAMICBASE /DEBUG /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD /MANIFEST:embed \ "/MANIFESTDEPENDENCY:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'" @@ -133,6 +133,8 @@ LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMTD /OPT:REF /OPT:ICF COPTS = /O1 /$(BUILD_TYPE) $(COPTS) !ENDIF +.SUFFIXES: .exports .def + .c.obj:: cl $(COPTS) /c $< @@ -140,7 +142,12 @@ COPTS = /O1 /$(BUILD_TYPE) $(COPTS) cl $(COPTS) $(WIX_INCL_DIR) /c $< .rc.res:: - rc /l 0x0409 /I$(TOPDIR) $< + rc $(DEFS) /l 0x0409 /I$(TOPDIR)\win32 $< + +.exports.def: + echo LIBRARY $* > $*.def + echo EXPORTS >> $*.def + type $*.exports >> $*.def clean:: del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.res diff --git a/win32/Makefile.mak b/win32/Makefile.mak index e6472b0989..8c42f1c83f 100644 --- a/win32/Makefile.mak +++ b/win32/Makefile.mak @@ -7,10 +7,7 @@ all: versioninfo-customactions.res config.h config.h: winconfig.h copy /y winconfig.h config.h -customactions.dll: versioninfo-customactions.res customactions.obj - echo LIBRARY $* > $*.def - echo EXPORTS >> $*.def - type customactions.exports >> $*.def +customactions.dll: versioninfo-customactions.res $*.obj $*.def link /dll $(LINKFLAGS) /out:$@ /def:$*.def versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib OpenSC.msi: OpenSC.wxs customactions.dll diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index 715bcae0f1..b0adcd406a 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -1,28 +1,21 @@  + + + + + - - - - - + - - - - - + - - - - - + @@ -32,14 +25,16 @@ xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui"> - + Keywords="SmartCard, eID" /> + @@ -96,7 +91,7 @@ - + @@ -126,7 +121,7 @@ Description="PKCS#11 module for debugging library invocations."> - + diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 716691e226..71bf0a0456 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -340,11 +340,11 @@ VOID RegisterSmartCard(PMD_REGISTRATION registration) TCHAR expanded_val[PATH_MAX]; BYTE pbAtrReduced[256]; DWORD i; - PTSTR szPath = TEXT("C:\\Program Files\\OpenSC Project\\OpenSC\\minidriver\\opensc-minidriver.dll"); + PTSTR szPath = TEXT("C:\\Program Files\\OpenSC Project\\OpenSC" OPENSC_ARCH_SUFFIX "\\minidriver\\opensc-minidriver.dll"); /* cope with x86 installation on x64 */ expanded_len = ExpandEnvironmentStrings( - TEXT("%ProgramFiles%\\OpenSC Project\\OpenSC\\minidriver\\opensc-minidriver.dll"), + TEXT("%ProgramFiles%\\OpenSC Project\\OpenSC" OPENSC_ARCH_SUFFIX "\\minidriver\\opensc-minidriver.dll"), expanded_val, expanded_len); if (0 < expanded_len && expanded_len < sizeof expanded_val) szPath = expanded_val; diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in index e820758b52..426fb3b79e 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h.in @@ -56,8 +56,6 @@ #define ENABLE_SHARED 1 #define ENABLE_NOTIFY 1 -#define SC_PKCS15_PROFILE_DIRECTORY "C:\\Program Files\\OpenSC Project\\OpenSC\\profiles" - #define PATH_MAX FILENAME_MAX #ifndef PACKAGE_VERSION @@ -108,15 +106,25 @@ #define OPENSC_VS_FF_COMMENTS "@OPENSC_VS_FF_COMMENTS@" #endif +#if defined(_M_ARM64) || defined(_M_ARM64EC) +#define OPENSC_ARCH_SUFFIX "_arm64" +#else +#define OPENSC_ARCH_SUFFIX "" +#endif + +#ifndef OPENSC_PATH +#define OPENSC_PATH "%PROGRAMFILES%\\OpenSC Project\\OpenSC" OPENSC_ARCH_SUFFIX "\\" +#endif + #ifndef CVCDIR -#define CVCDIR "%PROGRAMFILES%\\OpenSC Project\\OpenSC\\cvc" +#define CVCDIR OPENSC_PATH "cvc" #endif #ifndef DEFAULT_PKCS11_PROVIDER -#define DEFAULT_PKCS11_PROVIDER "@DEFAULT_PKCS11_PROVIDER@" +#define DEFAULT_PKCS11_PROVIDER OPENSC_PATH "pkcs11\\opensc-pkcs11.dll" #endif #ifndef DEFAULT_ONEPIN_PKCS11_PROVIDER -#define DEFAULT_ONEPIN_PKCS11_PROVIDER "@DEFAULT_ONEPIN_PKCS11_PROVIDER@" +#define DEFAULT_ONEPIN_PKCS11_PROVIDER OPENSC_PATH "pkcs11\\onepin-opensc-pkcs11.dll" #endif #define PKCS11_THREAD_LOCKING @@ -124,9 +132,6 @@ #ifndef DEFAULT_SM_MODULE #define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@" #endif -#ifndef DEFAULT_SM_MODULE_PATH -#define DEFAULT_SM_MODULE_PATH "@DEFAULT_SM_MODULE_PATH@" -#endif #ifndef OPENSC_SCM_REVISION #define OPENSC_SCM_REVISION "@OPENSC_SCM_REVISION@" From fbc4d0d9ae1e2ed16da23e3517214a0032832879 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 13:05:30 +0200 Subject: [PATCH 3969/4321] iasecc: Avoid memory leak on error condition https://issues.oss-fuzz.com/u/0/issues/443265733 Signed-off-by: Jakub Jelen --- src/libopensc/iasecc-sm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index 418b06d261..6e3d8b5223 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -238,9 +238,8 @@ iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num) LOG_TEST_RET(ctx, rv, "Get SE info error"); rv = iasecc_se_get_crt(card, &se, crt); - LOG_TEST_RET(ctx, rv, "Cannot get authentication CRT"); - sc_file_free(se.df); + LOG_TEST_RET(ctx, rv, "Cannot get authentication CRT"); /* MSE SET Mutual Authentication SK scheme */ offs = 0; From 68c0bff4565673dcd3e916c91463b3aff1b999a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 13:21:41 +0200 Subject: [PATCH 3970/4321] pkcs15-openpgp: Avoid memory leak of data passed from the driver Fixes up 0b82b761abd6a655df9f17eeb01c0d7330facc01 https://issues.oss-fuzz.com/u/0/issues/442170527 Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index b3172d13d2..d16ad6b59a 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -419,6 +419,7 @@ static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj, err: free(key_info.u.ec.ecpointQ); + free(key_info.data); LOG_FUNC_RETURN(ctx, r); } From 91e61b9a7667ce0bf62e4b0e872e39a34295eb89 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Oct 2025 00:05:20 +0200 Subject: [PATCH 3971/4321] Do not register SHA1-based mechanisms in FIPS mode Fixes: #3495 Signed-off-by: Jakub Jelen --- src/pkcs11/openssl.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index c9c7c71506..0a5d4394a2 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -305,12 +305,14 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) #endif #endif /* !defined(OPENSSL_NO_ENGINE) */ - openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); - openssl_sha1_mech.free_mech_data = ossl_md_free; - openssl_sha1_mech.copy_mech_data = ossl_md_copy; - mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); - sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(&mt); + if (!FIPS_mode()) { + openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); + openssl_sha1_mech.free_mech_data = ossl_md_free; + openssl_sha1_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + } openssl_sha224_mech.mech_data = sc_evp_md(context, "sha224"); openssl_sha224_mech.free_mech_data = ossl_md_free; From 495114b45e3364c55ceee9c80f4f82fa9dcd6871 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Oct 2025 10:02:33 +0200 Subject: [PATCH 3972/4321] ci: Fix Ubuntu 22 jobs for valgrind Signed-off-by: Jakub Jelen --- .github/workflows/linux.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b5524c7798..9baf73a35c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -424,7 +424,7 @@ jobs: distribution: 'semeru' java-version: '8' cache: 'maven' - - run: .github/setup-linux.sh piv + - run: .github/setup-linux.sh piv debug - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind @@ -443,7 +443,7 @@ jobs: with: path: ./* key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh cac + - run: .github/setup-linux.sh cac debug - run: .github/test-cac.sh - run: .github/test-cac.sh valgrind @@ -462,7 +462,7 @@ jobs: with: path: ./* key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh oseid + - run: .github/setup-linux.sh oseid debug - run: .github/test-oseid.sh - run: .github/test-oseid.sh valgrind From bee5ce19acb03e6c1c1dd38258ae16e8d5c4ee85 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Sep 2025 07:53:30 +0200 Subject: [PATCH 3973/4321] Consistently load shared libraries with RTL_LOCAL Linux and macOS defaults are differing on this otherwise --- src/common/libscdl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 7ee50f3d4e..cd3c6bf7e6 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -63,11 +63,14 @@ int sc_dlclose(void *handle) { return FreeLibrary((HMODULE)handle); } + #else + #include + void *sc_dlopen(const char *filename) { - return dlopen(filename, RTLD_LAZY); + return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); } void *sc_dlsym(void *handle, const char *symbol) From 60ded2bbf90f2ddb638cc481ac714829a2445af3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 30 Sep 2025 22:00:35 +0200 Subject: [PATCH 3974/4321] Use dlopen with RTLD_DEEPBIND if possible This prefers the loaded module's implementation of some function over the same function that may be registered globally. In PKCS#11, this problem may occur, for example, if the application loads PKCS#11 spy with RTLD_GLOBAL, which then loads the spied-on-PKCS#11-module. With RTLD_DEEPBIND, the spied-on-module now calls its own implementation of, for example, C_Initialize rather than the globally registered implementation of C_Initialize from PKCS#11 spy. fixes #2875 --- src/common/libscdl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/libscdl.c b/src/common/libscdl.c index cd3c6bf7e6..ec96a68fae 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -70,7 +70,11 @@ int sc_dlclose(void *handle) void *sc_dlopen(const char *filename) { - return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + return dlopen(filename, RTLD_LAZY | RTLD_LOCAL +#ifdef RTLD_DEEPBIND + | RTLD_DEEPBIND +#endif + ); } void *sc_dlsym(void *handle, const char *symbol) From 458db6f44bfb66e000544ce2d87c47bcc84fe19d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 13 Oct 2025 19:46:14 +0300 Subject: [PATCH 3975/4321] Merge libressl tests Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9baf73a35c..64ff3bd32a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -509,30 +509,15 @@ jobs: libressl-${{ env.LIBRESSL_VERSION }}/ key: libressl-${{ env.LIBRESSL_VERSION }} - test-cac-libressl: - runs-on: ubuntu-latest - needs: [build-libressl] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-latest-base - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-libressl-${{ github.sha }} - - run: .github/setup-linux.sh cac libressl - - run: .github/test-cac.sh - - run: .github/test-cac.sh valgrind - - test-oseid-libressl: + test-libressl: + name: test-${{ matrix.target }}-libressl runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: [cac, oseid] needs: [build-libressl] steps: - - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} @@ -543,9 +528,9 @@ jobs: with: path: ./* key: ${{ runner.os }}-libressl-${{ github.sha }} - - run: .github/setup-linux.sh oseid libressl - - run: .github/test-oseid.sh - - run: .github/test-oseid.sh valgrind + - run: .github/setup-linux.sh ${{ matrix.target }} libressl + - run: .github/test-${{ matrix.target }}.sh + - run: .github/test-${{ matrix.target }}.sh valgrind #################### ## Push artifacts ## From 7b1e1b4ba2b2b9c49ee839c9e5b5d4df6d397f64 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 13 Oct 2025 19:56:21 +0300 Subject: [PATCH 3976/4321] Merge isoapplet tests Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 41 +++++++++---------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 64ff3bd32a..1dbbdbae0d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -219,15 +219,19 @@ jobs: - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind - test-isoapplet-v0: + test-isoapplet: + name: test-isoapplet-${{ matrix.target }} + strategy: + fail-fast: false + matrix: + target: [v0, v1] runs-on: ubuntu-24.04 needs: [build] steps: - - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java + version: apt-24.04-amd64-base execute_install_scripts: true - run: git clone $JCARDSIM - uses: actions/setup-java@v4 @@ -240,34 +244,9 @@ jobs: with: path: ./* key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh isoapplet - - run: .github/test-isoapplet.sh v0 - - run: .github/test-isoapplet.sh v0 valgrind - - test-isoapplet-v1: - runs-on: ubuntu-24.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - run: .github/setup-linux.sh isoapplet - - run: .github/test-isoapplet.sh v1 - - run: .github/test-isoapplet.sh v1 valgrind + - run: .github/setup-linux.sh isoapplet debug + - run: .github/test-isoapplet.sh ${{ matrix.target }} + - run: .github/test-isoapplet.sh ${{ matrix.target }} valgrind test-gidsapplet: runs-on: ubuntu-24.04 From e69d36cfbeed543d33a990d8ee6a0ced19014104 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 13 Oct 2025 20:02:23 +0300 Subject: [PATCH 3977/4321] Merge cac/oseid tests Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 78 +++++++------------------------------ 1 file changed, 13 insertions(+), 65 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1dbbdbae0d..2f75a03d28 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -316,43 +316,29 @@ jobs: - run: .github/setup-linux.sh clang-tidy - run: .github/build.sh clang-tidy - test-cac: - runs-on: ubuntu-24.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-24.04-amd64-base - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh cac - - run: .github/test-cac.sh - - run: .github/test-cac.sh valgrind - - test-oseid: - runs-on: ubuntu-24.04 + test: + name: test-${{ matrix.target }}-${{ matrix.dist }} + strategy: + fail-fast: false + matrix: + dist: ['22.04', '24.04'] + target: [cac, oseid] + runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-24.04-amd64-base + version: apt-${{ matrix.dist }}-amd64-base execute_install_scripts: true - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh oseid - - run: .github/test-oseid.sh - - run: .github/test-oseid.sh valgrind + key: ${{ runner.os }}-${{ matrix.dist }}-amd64-${{ github.sha }} + - run: .github/setup-linux.sh ${{ matrix.target }} debug + - run: .github/test-${{ matrix.target }}.sh + - run: .github/test-${{ matrix.target }}.sh valgrind ############################################ ## Ubuntu 22.04 with OpenSSL 3.0 pipeline ## @@ -407,44 +393,6 @@ jobs: - run: .github/test-piv.sh - run: .github/test-piv.sh valgrind - test-cac-ubuntu-22: - runs-on: ubuntu-22.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-22-java - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh cac debug - - run: .github/test-cac.sh - - run: .github/test-cac.sh valgrind - - test-oseid-ubuntu-22: - runs-on: ubuntu-22.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-22.04-amd64-base - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-22.04-amd64-${{ github.sha }} - - run: .github/setup-linux.sh oseid debug - - run: .github/test-oseid.sh - - run: .github/test-oseid.sh valgrind - ####################### ## LibreSSL pipeline ## ####################### From d6ded4ff49d6cace880a81e9a0e6072bbba0692a Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 13 Oct 2025 20:11:14 +0300 Subject: [PATCH 3978/4321] Merge piv/gidsapplet/openpgp tests Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 66 ++++++------------------------------- 1 file changed, 10 insertions(+), 56 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2f75a03d28..5916d69d3f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -169,31 +169,6 @@ jobs: path: ./* key: ${{ runner.os }}-piv-sm-${{ github.sha }} - test-piv: - runs-on: ubuntu-24.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - run: .github/setup-linux.sh piv - - run: .github/test-piv.sh - - run: .github/test-piv.sh valgrind - test-piv-sm: runs-on: ubuntu-24.04 needs: [build-piv-sm] @@ -248,15 +223,19 @@ jobs: - run: .github/test-isoapplet.sh ${{ matrix.target }} - run: .github/test-isoapplet.sh ${{ matrix.target }} valgrind - test-gidsapplet: + test-java: + name: test-${{ matrix.target }} + strategy: + fail-fast: false + matrix: + target: [piv, gidsapplet, openpgp] runs-on: ubuntu-24.04 needs: [build] steps: - - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java + version: apt-24.04-amd64-java execute_install_scripts: true - uses: actions/cache@v4 id: cache-build @@ -269,34 +248,9 @@ jobs: distribution: 'semeru' java-version: '8' cache: 'maven' - - run: .github/setup-linux.sh gidsapplet - - run: .github/test-gidsapplet.sh - - run: .github/test-gidsapplet.sh valgrind - - test-openpgp: - runs-on: ubuntu-24.04 - needs: [build] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} %{{ env.JAVA_DEPS }} - version: apt-24.04-amd64-base - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - run: .github/setup-linux.sh openpgp - - run: .github/test-openpgp.sh - - run: .github/test-openpgp.sh valgrind + - run: .github/setup-linux.sh ${{ matrix.target }} + - run: .github/test-${{ matrix.target }}.sh + - run: .github/test-${{ matrix.target }}.sh valgrind build-clang-tidy: runs-on: ubuntu-24.04 From be548cdd7f789a7c7fae48b43a2c0c8b064ec1eb Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 13 Oct 2025 21:03:51 +0300 Subject: [PATCH 3979/4321] Merge piv-sm build/tests Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 179 ++++++++---------------------------- 1 file changed, 36 insertions(+), 143 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5916d69d3f..ca40aba0c6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -37,38 +37,36 @@ jobs: fail-fast: false matrix: dist: ['22.04', '24.04'] - arch: ['amd64', 'arm64'] - build: ['dist', 'valgrind'] + arch: [amd64, arm64] + build: [dist, valgrind, piv-sm] # piv-sm will also include valgrind tests exclude: - build: dist arch: arm64 - - dist: 22.04 - build: valgrind - arch: arm64 runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + # Create with piv-sm build with java deps - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: - packages: ${{ env.BASE_DEPS }} - version: apt-${{ matrix.dist }}-${{ matrix.arch }}-base + packages: ${{ env.BASE_DEPS }} ${{ matrix.build == 'piv-sm' && env.JAVA_DEPS || '' }} + version: apt-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build == 'piv-sm' && 'java' || 'base' }} execute_install_scripts: true - - run: .github/setup-linux.sh ${{ matrix.build == 'valgrind' && 'debug' || '' }} - - run: .github/build.sh ${{ matrix.build }} + - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds + - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs uses: actions/upload-artifact@v4 if: failure() with: - name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-test-logs + name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-test-logs path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v4 + - &use_cache + uses: actions/cache@v4 id: cache-build - if: matrix.build == 'dist' with: path: ./* - key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ github.sha }} + key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-${{ github.sha }} - name: Upload build artifacts if: matrix.build == 'dist' uses: actions/upload-artifact@v4 @@ -144,69 +142,22 @@ jobs: path: win32/Output/OpenSC*.exe - build-piv-sm: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java - execute_install_scripts: true - - run: .github/setup-linux.sh - - run: .github/build.sh piv-sm dist - - name: Upload test logs - uses: actions/upload-artifact@v4 - if: failure() - with: - name: ubuntu-piv-sm-test-logs - path: | - tests/*.log - src/tests/unittests/*.log - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-piv-sm-${{ github.sha }} - - test-piv-sm: - runs-on: ubuntu-24.04 - needs: [build-piv-sm] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-20-java - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-piv-sm-${{ github.sha }} - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - run: .github/setup-linux.sh piv - - run: .github/test-piv.sh - - run: .github/test-piv.sh valgrind - test-isoapplet: name: test-isoapplet-${{ matrix.target }} strategy: fail-fast: false matrix: + dist: ['24.04'] + arch: [amd64] + build: [valgrind] target: [v0, v1] - runs-on: ubuntu-24.04 + runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-24.04-amd64-base + version: apt-${{ matrix.dist }}-${{ matrix.arch }}-java execute_install_scripts: true - run: git clone $JCARDSIM - uses: actions/setup-java@v4 @@ -214,41 +165,40 @@ jobs: distribution: 'semeru' java-version: '8' cache: 'maven' - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} + - *use_cache - run: .github/setup-linux.sh isoapplet debug - run: .github/test-isoapplet.sh ${{ matrix.target }} - run: .github/test-isoapplet.sh ${{ matrix.target }} valgrind test-java: - name: test-${{ matrix.target }} + name: test-${{ matrix.target }}-${{ matrix.dist }}-${{ matrix.build }} strategy: fail-fast: false matrix: + dist: ['24.04'] + arch: [amd64] + build: [valgrind] target: [piv, gidsapplet, openpgp] - runs-on: ubuntu-24.04 + include: [ + { dist: '22.04', arch: amd64, build: 'piv-sm', target: 'piv' }, + { dist: '24.04', arch: amd64, build: 'piv-sm', target: 'piv' } + ] + runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-24.04-amd64-java + version: apt-${{ matrix.dist }}-${{ matrix.arch }}-java execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} + - *use_cache - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: distribution: 'semeru' java-version: '8' cache: 'maven' - - run: .github/setup-linux.sh ${{ matrix.target }} + - run: .github/setup-linux.sh ${{ matrix.target }} debug - run: .github/test-${{ matrix.target }}.sh - run: .github/test-${{ matrix.target }}.sh valgrind @@ -256,7 +206,6 @@ jobs: runs-on: ubuntu-24.04 needs: [build] steps: - - uses: actions/checkout@v4 - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} @@ -266,7 +215,7 @@ jobs: id: cache-build with: path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-valgrind-${{ github.sha }} - run: .github/setup-linux.sh clang-tidy - run: .github/build.sh clang-tidy @@ -276,6 +225,8 @@ jobs: fail-fast: false matrix: dist: ['22.04', '24.04'] + arch: [amd64] + build: [valgrind] target: [cac, oseid] runs-on: ubuntu-${{ matrix.dist }} needs: [build] @@ -283,70 +234,13 @@ jobs: - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: ${{ env.BASE_DEPS }} - version: apt-${{ matrix.dist }}-amd64-base + version: apt-${{ matrix.dist }}-${{ matrix.arch }}-base execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-${{ matrix.dist }}-amd64-${{ github.sha }} + - *use_cache - run: .github/setup-linux.sh ${{ matrix.target }} debug - run: .github/test-${{ matrix.target }}.sh - run: .github/test-${{ matrix.target }}.sh valgrind - ############################################ - ## Ubuntu 22.04 with OpenSSL 3.0 pipeline ## - ############################################ - build-ubuntu-22-piv-sm: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-22-java - execute_install_scripts: true - - run: .github/setup-linux.sh - - run: .github/build.sh piv-sm dist valgrind - - uses: actions/upload-artifact@v4 - if: failure() - with: - name: ubuntu-22-piv-sm-test-logs - path: | - tests/*.log - src/tests/unittests/*.log - - uses: actions/cache@v4 - id: cache-build - if: ${{ success() }} - with: - path: ./* - key: ${{ runner.os }}-22-piv-sm-${{ github.sha }} - - test-piv-sm-ubuntu-22: - runs-on: ubuntu-22.04 - needs: [build-ubuntu-22-piv-sm] - steps: - - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-22-java - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-22-piv-sm-${{ github.sha }} - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - run: .github/setup-linux.sh piv debug - - run: .github/test-piv.sh - - run: .github/test-piv.sh valgrind - ####################### ## LibreSSL pipeline ## ####################### @@ -420,12 +314,11 @@ jobs: runs-on: ubuntu-latest needs: [build, build-mingw] steps: - - uses: actions/checkout@v4 - uses: actions/cache@v4 id: cache-build with: path: ./* - key: ${{ runner.os }}-24.04-amd64-${{ github.sha }} + key: ${{ runner.os }}-24.04-amd64-dist-${{ github.sha }} - name: Pull mingw build artifacts uses: actions/download-artifact@v4 with: From 6db171bcb6fd7cb3b51098fefbb3b28e44f0a79c Mon Sep 17 00:00:00 2001 From: David Fort Date: Wed, 1 Oct 2025 21:50:52 +0200 Subject: [PATCH 3980/4321] idprime: fix pin padding for SafeNet eToken 5100 [eToken 5110 SC] As discussed in https://github.com/OpenSC/OpenSC/issues/3488 , it seems like my card with ATR 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:01:78:82:90:00:88 needs to be identified as SC_CARD_TYPE_IDPRIME_940 to have padding for the pin. --- src/libopensc/card-idprime.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index ca9b4c0ebc..18a559df8c 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -71,7 +71,7 @@ static const struct sc_atr_table idprime_atrs[] = { * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85 metsma */ { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85", - "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", + "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:ff:ff:ff:ff:ff:00", "based Gemalto IDPrime 930 (eToken 5110+ FIPS)", SC_CARD_TYPE_IDPRIME_930_PLUS, 0, NULL }, /* known ATR for IDPrime 940: Placing in front of the 940 as its mask overlaps this one! @@ -97,9 +97,10 @@ static const struct sc_atr_table idprime_atrs[] = { SC_CARD_TYPE_IDPRIME_940, 0, NULL }, /* Known ATRs for IDPrime 940 (eToken 5110) * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00 metsma, jurajsarinay + * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:01:78:82:90:00:88 hardening */ { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:f0:00:ff:ff:ff:00", "Gemalto IDPrime MD 940 (eToken 5110)", SC_CARD_TYPE_IDPRIME_940, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", From c2bedf0fd33ad8f2561f79fe943cb40f0a628b69 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 19 Jun 2025 00:30:50 +0200 Subject: [PATCH 3981/4321] fixed coverity 462005 Use after free likely a false positive, but this rewrite doesn't hurt --- src/libopensc/card-esteid2018.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 683b58935a..0272e01165 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -122,9 +122,10 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat r = iso_ops->process_fci(card, file, resp, resplen); if (r != SC_SUCCESS) { sc_file_free(file); + } else { + *file_out = file; } LOG_TEST_RET(card->ctx, r, "Process fci failed"); - *file_out = file; } break; } From 95cb5aadca3e5cb4ebe1ca317c16921c3f6c69f6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 19 Jun 2025 00:43:33 +0200 Subject: [PATCH 3982/4321] fixed coverity 454824 Improper use of negative value likely a false positive --- src/libopensc/pkcs15-sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 262168166f..9e979c416b 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -320,7 +320,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, /* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */ } #ifdef ENABLE_OPENSSL - if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) + else if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) { size_t s = r; uint8_t *param = NULL; From d66297c5bf3edf751c817b3f957aec5ccffd4f05 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 31 Oct 2025 09:06:52 +0100 Subject: [PATCH 3983/4321] fixed formatting --- src/libopensc/pkcs15-sec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 9e979c416b..835a75e2a9 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -320,8 +320,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, /* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */ } #ifdef ENABLE_OPENSSL - else if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) - { + else if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP) { size_t s = r; uint8_t *param = NULL; size_t paramlen = 0; From 86a2333c980aeb10d0b468e54af4c042dba8b82f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Sep 2025 14:41:25 +0200 Subject: [PATCH 3984/4321] eoi: Avoid NULL dereference The iso driver never had the card_ctl operation so this have never worked. The original intention is unclear, so at least add a guardrails, rather than breaking it altogether. https://issues.oss-fuzz.com/issues/447805091 Signed-off-by: Jakub Jelen --- src/libopensc/card-eoi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index 24b5e6df99..a1e4884893 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -422,18 +422,24 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * static int eoi_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) { - int r = SC_SUCCESS; + struct sc_card_driver *iso_driver = NULL; + int r = SC_ERROR_NOT_SUPPORTED; LOG_FUNC_CALLED(card->ctx); switch (cmd) { case SC_CARDCTL_GET_MODEL: - if (!ptr) + if (!ptr) { r = SC_ERROR_INVALID_ARGUMENTS; - else + } else { *(char **)ptr = eoi_model; + r = SC_SUCCESS; + } break; default: - r = sc_get_iso7816_driver()->ops->card_ctl(card, cmd, ptr); + iso_driver = sc_get_iso7816_driver(); + if (iso_driver->ops->card_ctl != NULL) { + r = sc_get_iso7816_driver()->ops->card_ctl(card, cmd, ptr); + } } LOG_FUNC_RETURN(card->ctx, r); } From d35f184ef37002cfdd08e7f7c1544bd287ae4e0f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 30 Sep 2025 18:09:00 +0200 Subject: [PATCH 3985/4321] mcrd: Avoid memory leak https://issues.oss-fuzz.com/issues/447702255 Signed-off-by: Jakub Jelen --- src/libopensc/card-mcrd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 8f2669639d..31bf1e0402 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -596,11 +596,11 @@ do_select(sc_card_t * card, u8 kind, } if (p2 != 0x0C && apdu.resplen > 2 && apdu.resp[0] == 0x6F) { + if (apdu.resp[1] > apdu.resplen - 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); *file = sc_file_new(); if (!*file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - if (apdu.resp[1] > apdu.resplen - 2) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } From 52401901801429e6b8a2bb4eeaee40a9719ad0ee Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 2 Oct 2025 09:59:43 +0200 Subject: [PATCH 3986/4321] cflex: Avoid stack underflow https://issues.oss-fuzz.com/issues/448717172 Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-cflex.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index f288bb43dd..8ede1ebd4e 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -652,6 +652,10 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card, sc_path_t path = *df_path; int r; + if (path.len <= 2) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + /* Get the private key file */ r = sc_profile_get_file_by_path(profile, &path, prkf); if (r < 0) { From d048fefc8ac8fdf6274b7a1985b457d2e1ba3f38 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 15 Oct 2025 13:16:17 +0200 Subject: [PATCH 3987/4321] pteid: Avoid global buffer underflow https://issues.oss-fuzz.com/issues/452150051 Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-pteid.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index 4446b31ac9..37b2d2ec71 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -256,6 +256,13 @@ static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card) struct sc_pin_cmd_data pin_cmd_data; struct sc_pkcs15_auth_info *pin_info = (sc_pkcs15_auth_info_t *) p15_obj->data; + if (pin_info->auth_id.value[0] < 1 || pin_info->auth_id.value[0] > 3) { + sc_log(ctx, "Invalid auth_id for PIN: Value %d out of range. Skipping.", + pin_info->auth_id.value[0]); + p15_obj = p15_obj->next; + continue; + } + strlcpy(p15_obj->label, pteid_pin_names[pin_info->auth_id.value[0]-1], sizeof(p15_obj->label)); pin_info->attrs.pin.flags |= SC_PKCS15_PIN_FLAG_NEEDS_PADDING; From 1b6889ff3c6b9d44d30fab3aac48fea6ad975083 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 13 Jun 2025 16:06:05 +0300 Subject: [PATCH 3988/4321] Remove autotools dependency from NMake build Signed-off-by: Raul Metsma --- .appveyor.yml | 6 --- .github/setup-wix.ps1 | 2 +- .github/vcpkg.json | 12 ++--- .github/workflows/windows.yml | 37 +++++++------- .gitignore | 2 - Makefile.am | 2 +- VERSION.mk | 17 +++++++ configure.ac | 31 +++++------- src/tools/Makefile.mak | 1 - win32/Make.rules.mak | 27 +++++++++-- win32/Makefile.am | 7 ++- win32/{OpenSC.wxs.in => OpenSC.wxs} | 14 +++--- win32/{winconfig.h.in => winconfig.h} | 70 +++++---------------------- 13 files changed, 98 insertions(+), 130 deletions(-) create mode 100644 VERSION.mk rename win32/{OpenSC.wxs.in => OpenSC.wxs} (95%) rename win32/{winconfig.h.in => winconfig.h} (50%) diff --git a/.appveyor.yml b/.appveyor.yml index 16ffb8e4b9..57f75d7b89 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -92,12 +92,6 @@ build_script: $env:OPENPACE_DEF="/DENABLE_OPENPACE" $env:OPENPACE_DIR="C:\openpace-${env:OPENSSL_PF}" } - - bash -c "exec 0> $GITHUB_ENV - - name: Install CPDK - run: choco install windows-cryptographic-provider-development-kit -y > $null - - name: Install autotools - uses: msys2/setup-msys2@v2 - with: - install: autotools mingw-w64-x86_64-pkg-config - - name: Bootstrap - shell: msys2 {0} run: | if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "master" ]]; then - ./bootstrap + SUFFIX="" elif [[ "${{ github.event_name }}" == "push" ]]; then - ./bootstrap.ci -s "-${{ github.ref_name }}" + SUFFIX="-${{ github.ref_name }}" elif [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "master" ]]; then - ./bootstrap.ci -s "-pr${{ github.event.number }}" + SUFFIX="-pr${{ github.event.number }}" else - ./bootstrap.ci -s "-${{ github.base_ref }}-pr${{ github.event.number }}" + SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" fi - - name: Configure - shell: bash - run: ./configure --disable-openssl --disable-readline --disable-zlib || cat config.log + echo ARTIFACT=${{ steps.ghd.outputs.tag }}${SUFFIX}_${{ matrix.platform }}${{ matrix.configuration == 'Light' && '-Light' || '' }} >> $GITHUB_ENV + - name: Install CPDK + run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Setup dev env uses: ilammy/msvc-dev-cmd@v1 with: arch: ${{ matrix.setenv }} + - name: Cache vcpkg + if: matrix.configuration == 'Release' + uses: actions/cache@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/workflows/windows.yml', '.github/vcpkg.json') }} - name: Prepare vcpkg if: matrix.configuration == 'Release' uses: lukka/run-vcpkg@v11 with: - vcpkgGitCommitId: 0d5cae153065957df7f382de7c1549ccc88027e5 vcpkgJsonGlob: .github/vcpkg.json runVcpkgInstall: true env: + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite VCPKG_DEFAULT_TRIPLET: ${{ matrix.platform }}-windows-static VCPKG_INSTALLED_DIR: ${{ env.VCPKG_INSTALLED }} - name: Install WIX @@ -131,7 +128,7 @@ jobs: - name: Archive debug artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.ARTIFACT }}-Debug + name: OpenSC-${{ env.ARTIFACT }}-Debug path: | ./src/**/*.pdb ./win32/*.pdb diff --git a/.gitignore b/.gitignore index dee0626eb3..307f18788a 100644 --- a/.gitignore +++ b/.gitignore @@ -97,8 +97,6 @@ src/tools/org.opensc-project.mac.opensc-notify.plist src/tools/org.opensc-project.mac.pkcs11-register.plist win32/OpenSC.iss -win32/OpenSC.wxs -win32/winconfig.h win32/OpenSC.msi win32/OpenSC.wixobj win32/OpenSC.wixpdb diff --git a/Makefile.am b/Makefile.am index a05b28b757..9c6c53a5b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ MAINTAINERCLEANFILES = \ $(srcdir)/m4/ltversion.m4 $(srcdir)/m4/lt~obsolete.m4 \ $(srcdir)/m4/ltoptions.m4 \ $(srcdir)/packaged -EXTRA_DIST = Makefile.mak +EXTRA_DIST = Makefile.mak VERSION.mk DISTCHECK_CONFIGURE_FLAGS = --with-completiondir=/tmp diff --git a/VERSION.mk b/VERSION.mk new file mode 100644 index 0000000000..ab56d02199 --- /dev/null +++ b/VERSION.mk @@ -0,0 +1,17 @@ +PRODUCT_NAME=OpenSC +PRODUCT_TARNAME=opensc +PRODUCT_BUGREPORT=https://github.com/OpenSC/OpenSC/issues +PRODUCT_URL=https://github.com/OpenSC/OpenSC +PACKAGE_VERSION_MAJOR=0 +PACKAGE_VERSION_MINOR=26 +PACKAGE_VERSION_FIX=1 +PACKAGE_VERSION_REVISION=0 +PACKAGE_SUFFIX= +PACKAGE_SCM_REVISION=No Git revision info available + +VS_FF_LEGAL_COPYRIGHT=OpenSC Project +VS_FF_LEGAL_COMPANY_NAME=OpenSC Project +VS_FF_LEGAL_COMPANY_URL=https://github.com/OpenSC +VS_FF_COMMENTS=Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+). +VS_FF_PRODUCT_NAME=OpenSC smartcard framework +VS_FF_PRODUCT_UPDATES=https://github.com/OpenSC/OpenSC/releases \ No newline at end of file diff --git a/configure.ac b/configure.ac index 37c74b22fe..282d20fd3e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,21 +2,16 @@ dnl -*- mode: m4; -*- AC_PREREQ(2.68) -define([PRODUCT_NAME], [OpenSC]) -define([PRODUCT_TARNAME], [opensc]) -define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues]) -define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) -define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [26]) -define([PACKAGE_VERSION_FIX], [1]) -define([PACKAGE_SUFFIX], []) - -define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) -define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) -define([VS_FF_LEGAL_COMPANY_URL], [https://github.com/OpenSC]) -define([VS_FF_COMMENTS], [Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).]) -define([VS_FF_PRODUCT_NAME], [OpenSC smartcard framework]) -define([VS_FF_PRODUCT_UPDATES], [https://github.com/OpenSC/OpenSC/releases]) +m4_esyscmd([awk -F= ' + /^[[:space:]]*#/ { next } + /^[[:space:]]*$/ { next } + { + key = $1; val = $2; + gsub(/^[[:space:]]+|[[:space:]]+$/, "", key); + gsub(/^[[:space:]]+|[[:space:]]+$/, "", val); + printf("m4_define([%s],[%s])\n", key, val); + } +' "VERSION.mk"]) m4_sinclude(m4/version.m4.ci) @@ -418,8 +413,8 @@ if test "${GIT_CHECKOUT}" = "yes"; then OPENSC_SCM_REVISION="OpenSC-${REVISION_DESCRIPTION}, ${HASH_COMMIT_DATE}" OPENSC_VERSION_REVISION="$(${GIT} rev-list ${GIT_TAG_COMMIT}..HEAD --count || echo 0)" else - OPENSC_SCM_REVISION="No Git revision info available" - OPENSC_VERSION_REVISION="0" + OPENSC_SCM_REVISION="PACKAGE_SCM_REVISION" + OPENSC_VERSION_REVISION="PACKAGE_VERSION_REVISION" fi dnl C Compiler features @@ -1206,9 +1201,7 @@ AC_CONFIG_FILES([ src/minidriver/Makefile src/minidriver/opensc-minidriver.inf win32/Makefile - win32/winconfig.h win32/OpenSC.iss - win32/OpenSC.wxs MacOSX/Makefile MacOSX/build-package MacOSX/Distribution.xml diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index c475e6f332..7a0156f206 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -61,7 +61,6 @@ sc-hsm-tool.exe: sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) pkcs11-tool.exe: pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib - mt -manifest exe.manifest -outputresource:$@;1 .c.exe: cl $(COPTS) /c $< diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index cb5fd8c5b5..ed3fc87b74 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -1,13 +1,26 @@ -OPENSC_FEATURES = pcsc +!INCLUDE $(TOPDIR)\VERSION.mk + +!IF "$(BUILD_NUMBER)" != "" +PACKAGE_VERSION_REVISION = $(BUILD_NUMBER) +!ENDIF +OPENSC_FEATURES = pcsc +PRODUCT_VERSION = $(PACKAGE_VERSION_MAJOR).$(PACKAGE_VERSION_MINOR).$(PACKAGE_VERSION_FIX).$(PACKAGE_VERSION_REVISION) +WIXFLAGS = \ + -d PRODUCT_NAME="$(VS_FF_PRODUCT_NAME)" \ + -d PRODUCT_BUGREPORT="$(PRODUCT_BUGREPORT)" \ + -d PRODUCT_URL="$(PRODUCT_URL)" \ + -d VS_FF_LEGAL_COMPANY_NAME="$(VS_FF_LEGAL_COMPANY_NAME)" \ + -d VS_FF_PRODUCT_UPDATES="$(VS_FF_PRODUCT_UPDATES)" \ + -d VS_FF_LEGAL_COMPANY_URL="$(VS_FF_LEGAL_COMPANY_URL)" #Include support for minidriver MINIDRIVER_DEF = /DENABLE_MINIDRIVER -WIXFLAGS = -d ENABLE_MINIDRIVER +WIXFLAGS = -d ENABLE_MINIDRIVER $(WIXFLAGS) #Build MSI with the Windows Installer XML (WIX) toolkit !IF "$(WIX_PACKAGES)" == "" WIX_PACKAGES = $(TOPDIR)\win32\packages -WIX_VERSION = 6.0.0 +WIX_VERSION = 6.0.2 !ENDIF WIX_INCL_DIR = "/I$(WIX_PACKAGES)/wixtoolset.dutil/$(WIX_VERSION)/build/native/include" \ "/I$(WIX_PACKAGES)/wixtoolset.wcautil/$(WIX_VERSION)/build/native/include" @@ -117,7 +130,13 @@ WIXFLAGS = -d OpenPACE="$(OPENPACE_DIR)" $(WIXFLAGS) # Used for MiniDriver CPDK_INCL_DIR = "/IC:\Program Files (x86)\Windows Kits\10\Cryptographic Provider Development Kit\Include" -DEFS = /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +DEFS = /DWINVER=0x0601 /D_WIN32_WINNT=0x0601 /DWIN32_LEAN_AND_MEAN /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" \ + /DPACKAGE_NAME="\"$(PRODUCT_NAME)\"" /DPACKAGE_VERSION="\"$(PRODUCT_VERSION)\"" \ + /DOPENSC_VERSION_MAJOR=$(PACKAGE_VERSION_MAJOR) /DOPENSC_VERSION_MINOR=$(PACKAGE_VERSION_MINOR) \ + /DOPENSC_VERSION_FIX=$(PACKAGE_VERSION_FIX) /DOPENSC_VERSION_REVISION=$(PACKAGE_VERSION_REVISION) \ + /DOPENSC_SCM_REVISION="\"$(PACKAGE_SCM_REVISION)\"" \ + /DOPENSC_VS_FF_COMPANY_NAME="\"$(VS_FF_LEGAL_COMPANY_NAME)\"" /DOPENSC_VS_FF_PRODUCT_NAME="\"$(VS_FF_PRODUCT_NAME)\"" \ + /DOPENSC_VS_FF_LEGAL_COPYRIGHT="\"$(VS_FF_LEGAL_COPYRIGHT)\"" /DOPENSC_VS_FF_COMMENTS="\"$(VS_FF_COMMENTS)\"" COPTS = /nologo /Zi /GS /W3 /WX /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS /DHAVE_CONFIG_H \ $(DEFS) $(DEBUG_DEF) $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) $(TESTS_DEF) $(OPENSSL_EXTRA_CFLAGS) \ /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(CPDK_INCL_DIR) diff --git a/win32/Makefile.am b/win32/Makefile.am index 73dd81ba22..b1ff42e8f0 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -1,9 +1,8 @@ include $(top_srcdir)/win32/ltrc.inc -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/winconfig.h \ - $(srcdir)/OpenSC.iss $(srcdir)/OpenSC.wxs -EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak versioninfo.rc winconfig.h.in \ - OpenSC.iss.in OpenSC.wxs.in versioninfo-customactions.rc \ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/OpenSC.iss +EXTRA_DIST = ltrc.inc Makefile.mak Make.rules.mak versioninfo.rc winconfig.h \ + OpenSC.iss.in OpenSC.wxs versioninfo-customactions.rc \ OpenSC.ico dlgbmp.bmp bannrbmp.bmp DDORes.dll_14_2302.ico dist_noinst_HEADERS = versioninfo.rc winconfig.h OpenSC.iss OpenSC.wxs diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs similarity index 95% rename from win32/OpenSC.wxs.in rename to win32/OpenSC.wxs index b0adcd406a..3373b00146 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs @@ -25,13 +25,13 @@ xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui"> - - @@ -39,10 +39,10 @@ - - - - + + + + diff --git a/win32/winconfig.h.in b/win32/winconfig.h similarity index 50% rename from win32/winconfig.h.in rename to win32/winconfig.h index 426fb3b79e..c3a4f4dc35 100644 --- a/win32/winconfig.h.in +++ b/win32/winconfig.h @@ -2,16 +2,16 @@ #define _OPENSC_WINCONFIG_H #include +#include +#include #include #include -#include -#include -#ifdef _MSC_VER +#ifdef _MSC_VER // TODO fix data truncation instead of disabling them // VC++ 2015 changes truncation warnings from 4244 to 4267. -#pragma warning (disable : 4267) -#pragma warning (disable : 4244) +#pragma warning(disable : 4267) +#pragma warning(disable : 4244) #endif #ifndef strcasecmp @@ -31,10 +31,10 @@ #endif #ifndef R_OK -#define R_OK 4 /* test whether readable. */ -#define W_OK 2 /* test whether writable. */ -#define X_OK 1 /* test whether executable. */ -#define F_OK 0 /* test whether exist. */ +#define R_OK 4 /* test whether readable. */ +#define W_OK 2 /* test whether writable. */ +#define X_OK 1 /* test whether executable. */ +#define F_OK 0 /* test whether exist. */ #endif #ifndef S_IRUSR @@ -50,7 +50,7 @@ #define ENABLE_PCSC #define HAVE_WINSCARD_H #ifndef DEFAULT_PCSC_PROVIDER -#define DEFAULT_PCSC_PROVIDER "@DEFAULT_PCSC_PROVIDER@" +#define DEFAULT_PCSC_PROVIDER "winscard.dll" #endif #define ENABLE_SHARED 1 @@ -58,54 +58,10 @@ #define PATH_MAX FILENAME_MAX -#ifndef PACKAGE_VERSION -#define PACKAGE_VERSION "@PACKAGE_VERSION@" -#endif - #ifndef VERSION #define VERSION PACKAGE_VERSION #endif -#ifndef PACKAGE_NAME -#define PACKAGE_NAME "@PACKAGE_NAME@" -#endif - -#ifndef OPENSC_FEATURES -#define OPENSC_FEATURES "N/A" -#endif - -#ifndef OPENSC_VERSION_MAJOR -#define OPENSC_VERSION_MAJOR @OPENSC_VERSION_MAJOR@ -#endif - -#ifndef OPENSC_VERSION_MINOR -#define OPENSC_VERSION_MINOR @OPENSC_VERSION_MINOR@ -#endif - -#ifndef OPENSC_VERSION_FIX -#define OPENSC_VERSION_FIX @OPENSC_VERSION_FIX@ -#endif - -#ifndef OPENSC_VERSION_REVISION -#define OPENSC_VERSION_REVISION @OPENSC_VERSION_REVISION@ -#endif - -#ifndef OPENSC_VS_FF_COMPANY_NAME -#define OPENSC_VS_FF_COMPANY_NAME "@OPENSC_VS_FF_COMPANY_NAME@" -#endif - -#ifndef OPENSC_VS_FF_PRODUCT_NAME -#define OPENSC_VS_FF_PRODUCT_NAME "@OPENSC_VS_FF_PRODUCT_NAME@" -#endif - -#ifndef OPENSC_VS_FF_LEGAL_COPYRIGHT -#define OPENSC_VS_FF_LEGAL_COPYRIGHT "@OPENSC_VS_FF_LEGAL_COPYRIGHT@" -#endif - -#ifndef OPENSC_VS_FF_COMMENTS -#define OPENSC_VS_FF_COMMENTS "@OPENSC_VS_FF_COMMENTS@" -#endif - #if defined(_M_ARM64) || defined(_M_ARM64EC) #define OPENSC_ARCH_SUFFIX "_arm64" #else @@ -130,11 +86,7 @@ #define PKCS11_THREAD_LOCKING #ifndef DEFAULT_SM_MODULE -#define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@" -#endif - -#ifndef OPENSC_SCM_REVISION -#define OPENSC_SCM_REVISION "@OPENSC_SCM_REVISION@" +#define DEFAULT_SM_MODULE "smm-local.dll" #endif #endif From 5fb8242e57bbcb302cffbd0ca9af20ef115adc1f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 4 Aug 2025 22:46:26 +0300 Subject: [PATCH 3989/4321] Implement 5110+ FIPS and 5110 CC (940) derive support Signed-off-by: Raul Metsma --- src/libopensc/card-idprime.c | 27 ++++++++++++--------------- src/libopensc/iso7816.c | 1 + src/libopensc/pkcs15-cert.c | 3 ++- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 18a559df8c..6c3e079a3e 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -712,6 +712,9 @@ static int idprime_init(sc_card_t *card) case SC_CARD_TYPE_IDPRIME_840: /* Set up algorithm info for EC */ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + if (card->type == SC_CARD_TYPE_IDPRIME_930_PLUS || card->type == SC_CARD_TYPE_IDPRIME_940) { + flags |= SC_ALGORITHM_ECDH_CDH_RAW; + } ext_flags = SC_ALGORITHM_EXT_EC_F_P | SC_ALGORITHM_EXT_EC_ECPARAMETERS | SC_ALGORITHM_EXT_EC_NAMEDCURVE @@ -1035,6 +1038,10 @@ idprime_set_security_env(struct sc_card *card, new_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT; /* SHA-1 mechanisms are not allowed in the card I have available */ switch (env->operation) { + case SC_SEC_OPERATION_DERIVE: + priv->current_op = SC_ALGORITHM_EC; + new_env.flags &= ~SC_SEC_ENV_ALG_REF_PRESENT; + break; case SC_SEC_OPERATION_DECIPHER: if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_OAEP) { if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA1) { @@ -1145,11 +1152,7 @@ idprime_compute_signature(struct sc_card *card, apdu.resp = out; apdu.resplen = outlen; apdu.le = outlen; - if (apdu.le > sc_get_max_recv_size(card)) { - /* The lower layers will automatically do a GET RESPONSE, if possible. - * All other workarounds must be carried out by the upper layers. */ - apdu.le = sc_get_max_recv_size(card); - } + iso7816_fixup_transceive_length(card, &apdu); apdu.data = NULL; apdu.datalen = 0; @@ -1175,11 +1178,13 @@ idprime_decipher(struct sc_card *card, int r; struct sc_apdu apdu; u8 *sbuf = NULL; + idprime_private_data_t *priv; if (card == NULL || crgram == NULL || out == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } LOG_FUNC_CALLED(card->ctx); + priv = card->drv_data; sc_log(card->ctx, "IDPrime decipher: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u", crgram_len, outlen); @@ -1196,19 +1201,11 @@ idprime_decipher(struct sc_card *card, apdu.resplen = outlen; apdu.le = outlen; - sbuf[0] = 0x81; /* padding indicator byte, 0x81 = Proprietary */ + sbuf[0] = priv->current_op == SC_ALGORITHM_EC ? 0x00 : 0x81; /* padding indicator byte, 0x81 = Proprietary, 0x00 = No further indication */ memcpy(sbuf + 1, crgram, crgram_len); apdu.data = sbuf; apdu.lc = crgram_len + 1; - if (apdu.lc > sc_get_max_send_size(card)) { - /* The lower layers will automatically do chaining */ - apdu.flags |= SC_APDU_FLAGS_CHAINING; - } - if (apdu.le > sc_get_max_recv_size(card)) { - /* The lower layers will automatically do a GET RESPONSE, if possible. - * All other workarounds must be carried out by the upper layers. */ - apdu.le = sc_get_max_recv_size(card); - } + iso7816_fixup_transceive_length(card, &apdu); apdu.datalen = crgram_len + 1; r = sc_transmit_apdu(card, &apdu); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 36b9e016da..e58fed1498 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -989,6 +989,7 @@ iso7816_set_security_env(struct sc_card *card, sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: + case SC_SEC_OPERATION_DERIVE: apdu.p2 = 0xB8; break; case SC_SEC_OPERATION_SIGN: diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 5e2dbb89d0..9088256da6 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -594,7 +594,8 @@ sc_pkcs15_alg_flags_from_algorithm(unsigned long algorithm) SC_X509_KEY_CERT_SIGN | \ SC_X509_CRL_SIGN) #define SC_PKCS15_X509_USAGE_DERIVE \ - SC_X509_KEY_AGREEMENT + (SC_X509_KEY_ENCIPHERMENT | \ + SC_X509_KEY_AGREEMENT) #define SC_PKCS15_X509_USAGE_UNWRAP \ (SC_X509_KEY_ENCIPHERMENT | \ SC_X509_KEY_AGREEMENT) From cc516a6c8fb0b8b4b058004a3086833f1255ceab Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 3 Nov 2025 00:38:41 +0100 Subject: [PATCH 3990/4321] AppVeyor: removed GH_TOKEN from configuration file the regenewed token was directly added to the online project settings fixes https://github.com/OpenSC/OpenSC/issues/3507 --- .appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 57f75d7b89..04d48e35ed 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -9,8 +9,6 @@ configuration: - Light environment: - GH_TOKEN: - secure: jeReA6BNx/dXVMGfroKadgE9ByKAE/tAGcb2z+dIVZGAN29X1Pu22wi1TuVOy9ZugqBzjvFV4knwHJSGi0+U6Yj1fTfa2CYpeCBym4JOXqPis/GpKfSeBV9IrmJGT/Av PATH: C:\cygwin\bin;%PATH% OPENPACE_VER: 1.1.3 ZLIB_VER_DOT: 1.3.1 From 24eddbf9a9a167184245123ce66797c76acc9f14 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Wed, 3 Sep 2025 13:00:36 +0200 Subject: [PATCH 3991/4321] pkcs11-tool: Add id/slot-id to PKCS#11 URIs Extend pkcs11-tool to include additional identifier parameters in PKCS#11 URIs to improve object and token identification: For -L option (list slots): - Add slot-id parameter to token URIs to identify specific slots - Before: pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=84914bc36f04a55d;token=clevis - After: pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=84914bc36f04a55d;token=clevis;slot-id=0 For -O option (list objects): - Add id parameter to data object URIs when CKA_ID attribute is available - Previously only keys and certificates included id parameters - Data objects now consistently show id parameters using getID() function Changes made: 1. Created get_uri_with_slot() function to generate token URIs with slot-id parameter 2. Modified show_token() to use new URI generation function with slot identification 3. Enhanced show_dobj() to retrieve and include object IDs for data objects 4. Added proper ID handling using existing getID() function for PKCS#11 objects The implementation correctly distinguishes between: - Token identifiers: slot-id parameter for slot/token identification - Object identifiers: id parameter from CKA_ID attribute for PKCS#11 objects Co-Authored-By: Claude Signed-off-by: Sergio Arroutbi --- src/tools/pkcs11-tool.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6ba894c215..8d6f1e108b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1899,6 +1899,24 @@ get_uri(CK_TOKEN_INFO_PTR info) return copy_key_value_to_uri("token=", token, CK_TRUE); } +static const char * +get_uri_with_slot(CK_TOKEN_INFO_PTR info, CK_SLOT_ID slot) +{ + copy_key_value_to_uri("pkcs11:", NULL, CK_FALSE); + const char *model = percent_encode(info->model, sizeof(info->model)); + copy_key_value_to_uri("model=", model, CK_FALSE); + const char *manufacturer = percent_encode(info->manufacturerID, sizeof(info->manufacturerID)); + copy_key_value_to_uri("manufacturer=", manufacturer, CK_FALSE); + const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber)); + copy_key_value_to_uri("serial=", serial, CK_FALSE); + const char *token = percent_encode(info->label, sizeof(info->label)); + copy_key_value_to_uri("token=", token, CK_FALSE); + + static char slot_id_str[32]; + snprintf(slot_id_str, sizeof(slot_id_str), "%lu", slot); + return copy_key_value_to_uri("slot-id=", slot_id_str, CK_TRUE); +} + static void show_token(CK_SLOT_ID slot) { CK_TOKEN_INFO info; @@ -1933,7 +1951,7 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); - printf(" uri : %s", get_uri(&info)); + printf(" uri : %s", get_uri_with_slot(&info, slot)); printf("\n"); } @@ -6419,9 +6437,11 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { unsigned char *oid_buf; + unsigned char *id; char *label; char *application; CK_ULONG size = 0; + CK_ULONG idsize = 0; CK_TOKEN_INFO info; CK_BBOOL modifiable = 0; CK_BBOOL private = 0; @@ -6476,6 +6496,12 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) get_token_info(opt_slot, &info); printf(" uri: %s", get_uri(&info)); + if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { + printf(";id="); + for (unsigned int n = 0; n < idsize; n++) + printf("%%%02x", id[n]); + free(id); + } if (label != NULL) { const char *pelabel = percent_encode((unsigned char *)label, strlen(label)); printf(";object=%s", pelabel); From e54dcb153a37cb4ba7f2ff8a00dd1b0b527300db Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Fri, 31 Oct 2025 16:40:16 +0100 Subject: [PATCH 3992/4321] Add --uri-with-slot-id option to show slot-id Co-Authored-By: Claude Signed-off-by: Sergio Arroutbi --- doc/tools/pkcs11-tool.1.xml | 7 +++ doc/tools/tools.html | 4 +- src/tools/pkcs11-tool.c | 35 +++++++++--- tests/Makefile.am | 6 ++- tests/test-pkcs11-tool-uri-with-slot-id.sh | 62 ++++++++++++++++++++++ 5 files changed, 105 insertions(+), 9 deletions(-) create mode 100755 tests/test-pkcs11-tool-uri-with-slot-id.sh diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 3998363945..4a154722ac 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -758,6 +758,13 @@ Specify the PKCS#11 URI for module, slot, token or object + + + + + Include SlotId in PKCS#11 URI + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 1428223efb..3667e92913 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1737,7 +1737,9 @@ --info-file filename

    Specify the file containing the info for HKDF (optional)

    --uri value -

    Specify the PKCS#11 URI for module, slot, token or object

    +

    Specify the PKCS#11 URI for module, slot, token or object

    + --uri-with-slot-id +

    Include SlotId in PKCS#11 URI

    Examples

    Perform a basic functionality test of the card:

    pkcs11-tool --test --login

    diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8d6f1e108b..db36eca752 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -239,7 +239,8 @@ enum { OPT_SALT_FILE, OPT_INFO_FILE, OPT_PUBLIC_KEY_INFO, - OPT_URI + OPT_URI, + OPT_URI_WITH_SLOT_ID }; // clang-format off @@ -334,6 +335,7 @@ static const struct option options[] = { { "info-file", 1, NULL, OPT_INFO_FILE}, { "public-key-info", 0, NULL, OPT_PUBLIC_KEY_INFO}, { "uri", 1, NULL, OPT_URI}, + { "uri-with-slot-id", 0, NULL, OPT_URI_WITH_SLOT_ID}, { NULL, 0, NULL, 0 } }; // clang-format on @@ -428,7 +430,8 @@ static const char *option_help[] = { "Specify the file containing the salt for HKDF (optional)", "Specify the file containing the info for HKDF (optional)", "When reading a public key, try to read PUBLIC_KEY_INFO (DER encoding of SPKI)", - "Specify the PKCS#11 URI for module, slot, token or object"}; + "Specify the PKCS#11 URI for module, slot, token or object", + "Include SlotId in PKCS#11 URI"}; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -494,6 +497,7 @@ static const char *opt_salt_file = NULL; static const char *opt_info_file = NULL; static int opt_public_key_info = 0; /* return pubkey as SPKI DER */ static struct pkcs11_uri *opt_uri = NULL; +static int opt_uri_with_slot_id = 0; /* include slot-id in PKCS#11 URI */ static void *module = NULL; static CK_FUNCTION_LIST_3_0_PTR p11 = NULL; @@ -1246,6 +1250,9 @@ int main(int argc, char * argv[]) case OPT_PUBLIC_KEY_INFO: opt_public_key_info = 1; break; + case OPT_URI_WITH_SLOT_ID: + opt_uri_with_slot_id = 1; + break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } @@ -1951,7 +1958,11 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); - printf(" uri : %s", get_uri_with_slot(&info, slot)); + if (opt_uri_with_slot_id) { + printf(" uri : %s", get_uri_with_slot(&info, slot)); + } else { + printf(" uri : %s", get_uri(&info)); + } printf("\n"); } @@ -6317,7 +6328,11 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(unique_id); } get_token_info(opt_slot, &info); - printf(" uri: %s", get_uri(&info)); + if (opt_uri_with_slot_id) { + printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); + } else { + printf(" uri: %s", get_uri(&info)); + } if (id != NULL && idsize) { printf(";id="); for (unsigned int n = 0; n < idsize; n++) @@ -6419,7 +6434,11 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(unique_id); } get_token_info(opt_slot, &info); - printf(" uri: %s", get_uri(&info)); + if (opt_uri_with_slot_id) { + printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); + } else { + printf(" uri: %s", get_uri(&info)); + } if (id != NULL && size) { printf(";id="); for (unsigned int n = 0; n < size; n++) @@ -6495,7 +6514,11 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); get_token_info(opt_slot, &info); - printf(" uri: %s", get_uri(&info)); + if (opt_uri_with_slot_id) { + printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); + } else { + printf(" uri: %s", get_uri(&info)); + } if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { printf(";id="); for (unsigned int n = 0; n < idsize; n++) diff --git a/tests/Makefile.am b/tests/Makefile.am index be8216834f..20f5be73c0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -34,7 +34,8 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ test-pkcs11-tool-sym-crypt-test.sh \ test-pkcs11-tool-unwrap-wrap-test.sh \ - test-pkcs11-tool-import.sh + test-pkcs11-tool-import.sh \ + test-pkcs11-tool-uri-with-slot-id.sh .NOTPARALLEL: TESTS = \ @@ -48,7 +49,8 @@ TESTS += \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-unwrap-wrap-test.sh \ - test-pkcs11-tool-import.sh + test-pkcs11-tool-import.sh \ + test-pkcs11-tool-uri-with-slot-id.sh if ENABLE_TESTS if ENABLE_SHARED TESTS += test-p11test.sh diff --git a/tests/test-pkcs11-tool-uri-with-slot-id.sh b/tests/test-pkcs11-tool-uri-with-slot-id.sh new file mode 100755 index 0000000000..c8ea54964e --- /dev/null +++ b/tests/test-pkcs11-tool-uri-with-slot-id.sh @@ -0,0 +1,62 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +TOKENTYPE=$1 + +if [ "${TOKENTYPE}" == "" ]; then + TOKENTYPE=softhsm + echo "No tokentype provided, running with SoftHSM" +fi + +source "$SOURCE_PATH/tests/common.sh" "$TOKENTYPE" + +echo "=======================================================" +echo "Setup $TOKENTYPE" +echo "=======================================================" +if [[ ! -f "$P11LIB" ]]; then + echo "WARNING: The $TOKENTYPE is not installed. Can not run this test" + exit 77; +fi + +card_setup +assert $? "Failed to set up card" + +echo "=======================================================" +echo "Test URI without --uri-with-slot-id (default)" +echo "=======================================================" +# Test that slot URIs do NOT contain slot-id by default +$PKCS11_TOOL --module "${P11LIB}" -L 2>/dev/null | grep 'uri' | grep 'slot-id' && { + echo "ERROR: Found slot-id in URI without --uri-with-slot-id flag" + ERRORS=1 +} + +# Test that object URIs do NOT contain slot-id by default +$PKCS11_TOOL --module "${P11LIB}" -O 2>/dev/null | grep 'uri:' | grep 'slot-id' && { + echo "ERROR: Found slot-id in object URI without --uri-with-slot-id flag" + ERRORS=1 +} + +echo "=======================================================" +echo "Test URI with --uri-with-slot-id flag" +echo "=======================================================" +# Test that slot URIs DO contain slot-id with the flag +$PKCS11_TOOL --module "${P11LIB}" --uri-with-slot-id -L 2>/dev/null | grep 'uri' | grep 'slot-id' >/dev/null +assert $? "Expected slot-id in URI with --uri-with-slot-id flag for slots" + +# Test that object URIs DO contain slot-id with the flag +$PKCS11_TOOL --module "${P11LIB}" --uri-with-slot-id -O 2>/dev/null | grep 'uri:' | grep 'slot-id' >/dev/null +assert $? "Expected slot-id in URI with --uri-with-slot-id flag for objects" + +# Verify the URI format is still valid (contains pkcs11:) +$PKCS11_TOOL --module "${P11LIB}" --uri-with-slot-id -L 2>/dev/null | grep 'uri' | grep 'pkcs11:' >/dev/null +assert $? "URI format validation failed for slots with --uri-with-slot-id" + +$PKCS11_TOOL --module "${P11LIB}" --uri-with-slot-id -O 2>/dev/null | grep 'uri:' | grep 'pkcs11:' >/dev/null +assert $? "URI format validation failed for objects with --uri-with-slot-id" + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +card_cleanup + +exit "${ERRORS}" From 25a394a8a8084ae203438f6d3b0fd7ed54eed5da Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Sat, 1 Nov 2025 11:46:15 +0100 Subject: [PATCH 3993/4321] Refactor code and use get_uri to avoid duplication Signed-off-by: Sergio Arroutbi --- src/tools/pkcs11-tool.c | 51 ++++++++++------------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index db36eca752..470f9a9df3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1893,7 +1893,7 @@ copy_key_value_to_uri(const char *key, const char *value, CK_BBOOL last) } static const char * -get_uri(CK_TOKEN_INFO_PTR info) +get_uri(CK_TOKEN_INFO_PTR info, CK_SLOT_ID slot) { copy_key_value_to_uri("pkcs11:", NULL, CK_FALSE); const char *model = percent_encode(info->model, sizeof(info->model)); @@ -1903,25 +1903,15 @@ get_uri(CK_TOKEN_INFO_PTR info) const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber)); copy_key_value_to_uri("serial=", serial, CK_FALSE); const char *token = percent_encode(info->label, sizeof(info->label)); - return copy_key_value_to_uri("token=", token, CK_TRUE); -} -static const char * -get_uri_with_slot(CK_TOKEN_INFO_PTR info, CK_SLOT_ID slot) -{ - copy_key_value_to_uri("pkcs11:", NULL, CK_FALSE); - const char *model = percent_encode(info->model, sizeof(info->model)); - copy_key_value_to_uri("model=", model, CK_FALSE); - const char *manufacturer = percent_encode(info->manufacturerID, sizeof(info->manufacturerID)); - copy_key_value_to_uri("manufacturer=", manufacturer, CK_FALSE); - const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber)); - copy_key_value_to_uri("serial=", serial, CK_FALSE); - const char *token = percent_encode(info->label, sizeof(info->label)); - copy_key_value_to_uri("token=", token, CK_FALSE); + if (opt_uri_with_slot_id) { + copy_key_value_to_uri("token=", token, CK_FALSE); + static char slot_id_str[32]; + snprintf(slot_id_str, sizeof(slot_id_str), "%lu", slot); + return copy_key_value_to_uri("slot-id=", slot_id_str, CK_TRUE); + } - static char slot_id_str[32]; - snprintf(slot_id_str, sizeof(slot_id_str), "%lu", slot); - return copy_key_value_to_uri("slot-id=", slot_id_str, CK_TRUE); + return copy_key_value_to_uri("token=", token, CK_TRUE); } static void show_token(CK_SLOT_ID slot) @@ -1958,12 +1948,7 @@ static void show_token(CK_SLOT_ID slot) printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber, sizeof(info.serialNumber))); printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen); - if (opt_uri_with_slot_id) { - printf(" uri : %s", get_uri_with_slot(&info, slot)); - } else { - printf(" uri : %s", get_uri(&info)); - } - printf("\n"); + printf(" uri : %s\n", get_uri(&info, slot)); } static void list_mechs(CK_SLOT_ID slot) @@ -6328,11 +6313,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(unique_id); } get_token_info(opt_slot, &info); - if (opt_uri_with_slot_id) { - printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); - } else { - printf(" uri: %s", get_uri(&info)); - } + printf(" uri: %s", get_uri(&info, opt_slot)); if (id != NULL && idsize) { printf(";id="); for (unsigned int n = 0; n < idsize; n++) @@ -6434,11 +6415,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(unique_id); } get_token_info(opt_slot, &info); - if (opt_uri_with_slot_id) { - printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); - } else { - printf(" uri: %s", get_uri(&info)); - } + printf(" uri: %s", get_uri(&info, opt_slot)); if (id != NULL && size) { printf(";id="); for (unsigned int n = 0; n < size; n++) @@ -6514,11 +6491,7 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); get_token_info(opt_slot, &info); - if (opt_uri_with_slot_id) { - printf(" uri: %s", get_uri_with_slot(&info, opt_slot)); - } else { - printf(" uri: %s", get_uri(&info)); - } + printf(" uri: %s", get_uri(&info, opt_slot)); if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { printf(";id="); for (unsigned int n = 0; n < idsize; n++) From 72a4c842c6740e24cf82520e9bb98648f9d631a4 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Mon, 3 Nov 2025 09:02:00 +0100 Subject: [PATCH 3994/4321] Update src/tools/pkcs11-tool.c Co-authored-by: Jakub Jelen Signed-off-by: Sergio Arroutbi --- src/tools/pkcs11-tool.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 470f9a9df3..8a5042fac1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1902,15 +1902,14 @@ get_uri(CK_TOKEN_INFO_PTR info, CK_SLOT_ID slot) copy_key_value_to_uri("manufacturer=", manufacturer, CK_FALSE); const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber)); copy_key_value_to_uri("serial=", serial, CK_FALSE); - const char *token = percent_encode(info->label, sizeof(info->label)); if (opt_uri_with_slot_id) { - copy_key_value_to_uri("token=", token, CK_FALSE); static char slot_id_str[32]; snprintf(slot_id_str, sizeof(slot_id_str), "%lu", slot); - return copy_key_value_to_uri("slot-id=", slot_id_str, CK_TRUE); + copy_key_value_to_uri("slot-id=", slot_id_str, CK_FALSE); } + const char *token = percent_encode(info->label, sizeof(info->label)); return copy_key_value_to_uri("token=", token, CK_TRUE); } From b538efb703cb99b87beb4663acd907b8bd0fadf0 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Mon, 3 Nov 2025 09:05:48 +0100 Subject: [PATCH 3995/4321] Data objects do not have the CKA_ID attribute It can not be enured CKA_ID is appropriately set in all the cases. Removing it from uri to avoid false errors/warnings on compliant implementations Co-authored-by: Jakub Jelen Signed-off-by: Sergio Arroutbi --- src/tools/pkcs11-tool.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8a5042fac1..80abf639b3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6432,11 +6432,9 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { unsigned char *oid_buf; - unsigned char *id; char *label; char *application; CK_ULONG size = 0; - CK_ULONG idsize = 0; CK_TOKEN_INFO info; CK_BBOOL modifiable = 0; CK_BBOOL private = 0; @@ -6491,12 +6489,6 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) get_token_info(opt_slot, &info); printf(" uri: %s", get_uri(&info, opt_slot)); - if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { - printf(";id="); - for (unsigned int n = 0; n < idsize; n++) - printf("%%%02x", id[n]); - free(id); - } if (label != NULL) { const char *pelabel = percent_encode((unsigned char *)label, strlen(label)); printf(";object=%s", pelabel); From 9f4aa9cb54ada79b24456b069036282f49246e70 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 17 Oct 2025 09:00:39 +0300 Subject: [PATCH 3996/4321] Remove deprecated macos-13 and add macos-26 + add missing files to dist * https://github.com/actions/runner-images/issues/13046 Signed-off-by: Raul Metsma --- .github/workflows/macos.yml | 26 +++++++++++++++---- .gitignore | 2 ++ MacOSX/Makefile.am | 11 ++++++-- MacOSX/build-openssl-macos.sh | 49 +++++++++++++++++++++++++++++++++++ MacOSX/build-package.in | 22 +--------------- 5 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 MacOSX/build-openssl-macos.sh diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8a0eebb355..88cbeda8b6 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -20,14 +20,30 @@ jobs: build: strategy: matrix: - os: [macos-15, macos-14, macos-13] + os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: .github/setup-macos.sh env: KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} + - name: Checkout OpenSSL sources + uses: actions/checkout@v5 + with: + repository: openssl/openssl + ref: openssl-3.5 + path: openssl + - name: Get OpenSSL commit hash + id: openssl_hash + run: echo "hash=$(cd openssl && git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + - uses: actions/cache@v4 + id: cache + with: + path: openssl_bin + key: ${{ matrix.os }}-OpenSSL-${{ steps.openssl_hash.outputs.hash }} + - run: sh MacOSX/build-openssl-macos.sh + if: steps.cache.outputs.cache-hit != 'true' - run: .github/build.sh env: CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} @@ -54,10 +70,10 @@ jobs: build-libressl: strategy: matrix: - os: [macos-15, macos-14, macos-13] + os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: .github/setup-macos.sh libressl - run: .github/build.sh libressl - run: .github/cleanup-macos.sh @@ -73,7 +89,7 @@ jobs: runs-on: macos-latest needs: [build] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Pull build artifacts uses: actions/download-artifact@v4 with: diff --git a/.gitignore b/.gitignore index 307f18788a..0fc2b038df 100644 --- a/.gitignore +++ b/.gitignore @@ -111,6 +111,7 @@ build/ engine_pkcs11/ libp11/ target/ +target_startup/ src/scconf/test-conf @@ -141,6 +142,7 @@ src/tests/fuzzing/fuzz_asn1_sig_value src/tests/fuzzing/fuzz_card src/tests/fuzzing/fuzz_piv_tool src/tests/fuzzing/fuzz_pkcs11 +src/tests/fuzzing/fuzz_pkcs11_uri src/tests/fuzzing/fuzz_pkcs15_crypt src/tests/fuzzing/fuzz_pkcs15_decode src/tests/fuzzing/fuzz_pkcs15_encode diff --git a/MacOSX/Makefile.am b/MacOSX/Makefile.am index 2130aa59a9..e149a0c78f 100644 --- a/MacOSX/Makefile.am +++ b/MacOSX/Makefile.am @@ -1,12 +1,19 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = build \ + build-openssl-macos.sh \ build-package.in \ Distribution.xml.in \ libtool-bundle \ + OpenSC_applescripts.entitlements \ + OpenSC_binaries.entitlements \ + OpenSC_Notify.applescript \ + OpenSC_Uninstaller.applescript \ opensc-uninstall \ + target.plist \ + target_startup.plist \ + target_token.plist \ resources \ resources/background.jpg \ resources/Welcome.html.in \ scripts \ - scripts/postinstall \ - OpenSC_Uninstaller.applescript + scripts/postinstall diff --git a/MacOSX/build-openssl-macos.sh b/MacOSX/build-openssl-macos.sh new file mode 100644 index 0000000000..f585a45d30 --- /dev/null +++ b/MacOSX/build-openssl-macos.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +BUILDPATH=${PWD} +PREFIX=/Library/OpenSC +export MACOSX_DEPLOYMENT_TARGET="10.13" + +# parse arguments: options -b/--buildpath and -p/--prefix +while [ $# -gt 0 ]; do + case "$1" in + -b|--buildpath) + BUILDPATH="$2" + shift 2 + ;; + -p|--prefix) + PREFIX="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + echo "Usage: $0 [-b|--buildpath ] [-p|--prefix ]" >&2 + exit 1 + ;; + esac +done + +pushd $BUILDPATH +if ! test -e openssl; then + git clone --depth=1 https://github.com/openssl/openssl.git -b openssl-3.5 + sed -ie 's!my @disablables = (!my @disablables = (\n "apps",!' openssl/Configure +fi + +pushd openssl +./Configure darwin64-x86_64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 +make clean +make -j 4 +make DESTDIR=$BUILDPATH/openssl_bin install_sw +make clean + +./Configure darwin64-arm64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 +make -j 4 +make DESTDIR=$BUILDPATH/openssl_arm64 install_sw + +lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a -output libcrypto.a +lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a -output libssl.a +mv libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a +mv libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a + +popd +popd \ No newline at end of file diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index c66c78bc70..80b32a188e 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -22,24 +22,7 @@ if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-versio # OpenSSL is not installed if ! test -e $BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig; then # Build OpenSSL manually, because Apple's binaries are deprecated - if ! test -e openssl; then - git clone --depth=1 https://github.com/openssl/openssl.git -b openssl-3.0 - fi - cd openssl - sed -ie 's!my @disablables = (!my @disablables = (\n "apps",!' Configure - ./Configure darwin64-x86_64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 - make clean - make -j 4 - make DESTDIR=$BUILDPATH/openssl_bin install_sw - make clean - ./Configure darwin64-arm64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 - make -j 4 - make DESTDIR=$BUILDPATH/openssl_arm64 install_sw - lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a -output libcrypto.a - lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a -output libssl.a - mv libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a - mv libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a - cd .. + sh build-openssl-macos.sh -b $BUILDPATH -p $PREFIX fi export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`" export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`" @@ -199,6 +182,3 @@ do fi done rm -rf ${imagedir} - -#if [ "$TRAVIS_EVENT_TYPE" != "pull_request" ]; then xcrun altool --notarize-app --file $(pwd)/vorteil_darwin-x86.dmg --username $OSX_NOTARIZE_USERNAME --primary-bundle-id com.vorteil.cli -p $OSX_NOTARIZE_PW -- >> /dev/null; fi; -#if [ "$TRAVIS_EVENT_TYPE" != "pull_request" ]; then for ((i=1;i<=30;i+=1)); do xcrun stapler staple $(pwd)/vorteil_darwin-x86.dmg >> /dev/null; if [ $? = 65 ]; then echo "Waiting for notarization to complete..." && sleep 10; fi; done; fi; From 71182f5501abc1530cfab884fd32f81432f8040f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sat, 1 Nov 2025 22:23:36 +0200 Subject: [PATCH 3997/4321] Use VERSION.mk to avoid double configure run Signed-off-by: Raul Metsma --- .gitignore | 1 - MacOSX/Makefile.am | 1 - MacOSX/build | 193 ++++++++++++++++++++++++++++++++++++++-- MacOSX/build-package.in | 184 -------------------------------------- configure.ac | 3 +- 5 files changed, 189 insertions(+), 193 deletions(-) delete mode 100755 MacOSX/build-package.in diff --git a/.gitignore b/.gitignore index 0fc2b038df..46b0c19b71 100644 --- a/.gitignore +++ b/.gitignore @@ -101,7 +101,6 @@ win32/OpenSC.msi win32/OpenSC.wixobj win32/OpenSC.wixpdb -MacOSX/build-package MacOSX/Distribution*.xml MacOSX/resources/Welcome.html diff --git a/MacOSX/Makefile.am b/MacOSX/Makefile.am index e149a0c78f..d186984ae2 100644 --- a/MacOSX/Makefile.am +++ b/MacOSX/Makefile.am @@ -1,7 +1,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in EXTRA_DIST = build \ build-openssl-macos.sh \ - build-package.in \ Distribution.xml.in \ libtool-bundle \ OpenSC_applescripts.entitlements \ diff --git a/MacOSX/build b/MacOSX/build index e51dd25e40..a6d7075820 100755 --- a/MacOSX/build +++ b/MacOSX/build @@ -1,8 +1,191 @@ #!/bin/bash +# Build the macOS installer for the token and command line tools. +# +# This is only tested and supported on macOS 10.10 or later, using Xcode 6.0.1. +# Building should also work on older macOS versions with slight changes; YMMV. + +# You need to install the following packages from homebrew or macports or fink: +# autoconf automake libtool pkg-config help2man gengetopt + +export MACOSX_DEPLOYMENT_TARGET="10.13" +FORCE_OPENSSL_BUILD="1" + set -ex -# generate configure test -x ./configure || ./bootstrap -# configure once to set the version in build script -./configure -# build and package installer -bash ./MacOSX/build-package $@ +BUILDPATH=${PWD} + +while IFS='=' read -r key value; do + # Skip empty or comment lines + [[ -z "$key" || "$key" =~ ^# ]] && continue + export "$key=$value" +done < $BUILDPATH/VERSION.mk + +export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX} +export SED=/usr/bin/sed +PREFIX=/Library/OpenSC +export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig + +if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-version=1.1.1; then + # OpenSSL is not installed + if ! test -e $BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig; then + # Build OpenSSL manually, because Apple's binaries are deprecated + sh $BUILDPATH/MacOSX/build-openssl-macos.sh -b $BUILDPATH -p $PREFIX + fi + export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`" + export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`" + export CRYPTO_CFLAGS="$OPENSSL_CFLAGS" + export CRYPTO_LIBS="$OPENSSL_LIBS" +fi + +export CFLAGS="$CFLAGS -arch x86_64 -arch arm64" +export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64" +export OBJCFLAGS=$CFLAGS + +if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then + if ! test -e openpace; then + git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.3 + fi + cd openpace + autoreconf -vis + CFLAGS="${CFLAGS} -DOPENSSL_SUPPRESS_DEPRECATED" ./configure --disable-shared --prefix=$PREFIX HELP2MAN=/usr/bin/true + touch src/cvc-create.1 src/cvc-print.1 + make DESTDIR=$BUILDPATH/openpace_bin install + cd .. +fi +export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" +export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" + +if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then + ./configure --prefix=$PREFIX \ + --sysconfdir=$PREFIX/etc \ + --enable-cvcdir=$PREFIX/etc/cvc \ + --enable-x509dir=$PREFIX/etc/x509 \ + --enable-openssl-secure-malloc=65536 \ + --disable-dependency-tracking \ + --enable-shared \ + --enable-static \ + --enable-strict \ + --disable-assert \ + --enable-sm # TODO: remove this (must be sensible default in master) + + # always make clean + make clean + + # compile + make -j 4 + + # copy files + rm -rf ${BUILDPATH}/target + make install DESTDIR=${BUILDPATH}/target + + # remove garbage + rm -f ${BUILDPATH}/target/$PREFIX/lib/*.la + rm -f ${BUILDPATH}/target/$PREFIX/lib/*.a + + # generate .bundle (required by Adobe Acrobat) + ./MacOSX/libtool-bundle ${BUILDPATH}/target/$PREFIX/lib/opensc-pkcs11.so ${BUILDPATH}/target/$PREFIX/lib +fi + + +if ! test -e NotificationProxy; then + git clone https://github.com/frankmorgner/NotificationProxy.git +fi +if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then + xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \ + CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual +else + xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} +fi +mkdir -p "$BUILDPATH/target/Applications/Utilities" +osacompile -o "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" +if test -n "${CODE_SIGN_IDENTITY}"; then + codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app" +fi + + +imagedir=$(mktemp -d) + +# Prepare target root +mkdir -p ${BUILDPATH}/target/usr/local/bin +cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin + +# Prepare startup root +mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents +cp src/tools/org.opensc-project.mac.pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents +cp src/tools/org.opensc-project.mac.opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents + +# Build OpenSCToken if possible +if test -e OpenSCToken -a -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then + cd OpenSCToken + # make sure OpenSCToken builds with the same dependencies as before + if ! test -e OpenSC; then + git clone --depth=1 file://$PWD/../../OpenSC + else + cd OpenSC && git pull && cd .. + fi + mkdir -p build + if ! test -e build/openssl; then + # build/openssl/lib/libcrypto.a is hardcoded in OpenSCToken + ln -sf $BUILDPATH/openssl_bin/$PREFIX build/openssl + # in OpenSCToken's variant of OpenSC we still use OpenSSL flags from above + fi + if ! test -e build/openpace; then + # build/openpace/lib/libeac.a is hardcoded in OpenSCToken + ln -sf $BUILDPATH/openpace_bin/$PREFIX build/openpace + # in OpenSCToken's variant of OpenSC we still use OpenPACE flags from above + fi + BP=${BUILDPATH} + . ./bootstrap + BUILDPATH=${BP} + xcodebuild -target OpenSCTokenApp -configuration Debug -project OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target_token \ + CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual + cd .. + + COMPONENT_TOKEN="--component-plist MacOSX/target_token.plist" +else + # if no OpenSCToken is checked out, then we create a dummy package + mkdir -p ${BUILDPATH}/target_token +fi + +if test -n "${CODE_SIGN_IDENTITY}"; then + for d in ${BUILDPATH}/target/Library/OpenSC/bin ${BUILDPATH}/target/Library/OpenSC/lib + do + # find executable files and run codesign on them + find ${d} -type f -perm +111 -print -exec \ + codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_binaries.entitlements --deep --timestamp --options runtime {} \; + done +fi + + +# Build package +pkgbuild --root ${BUILDPATH}/target --component-plist MacOSX/target.plist --scripts MacOSX/scripts --identifier org.opensc-project.mac --version ${PACKAGE_VERSION} --install-location / OpenSC.pkg +pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.opensc-project.mac.opensctoken --version ${PACKAGE_VERSION} --install-location / OpenSCToken.pkg +pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version ${PACKAGE_VERSION} --install-location / OpenSC-startup.pkg + +# Build product +productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC ${PACKAGE_VERSION}.pkg" + +# Sign installer +if test -n "${INSTALLER_SIGN_IDENTITY}"; then + productsign --sign "${INSTALLER_SIGN_IDENTITY}" "${imagedir}/OpenSC ${PACKAGE_VERSION}.pkg" "${BUILDPATH}/OpenSC ${PACKAGE_VERSION}.pkg" + mv "${BUILDPATH}/OpenSC ${PACKAGE_VERSION}.pkg" "${imagedir}/OpenSC ${PACKAGE_VERSION}.pkg" +fi + +# Build "Uninstaller" +osacompile -o "${imagedir}/OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript" +if test -n "${CODE_SIGN_IDENTITY}"; then + codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "${imagedir}/OpenSC Uninstaller.app" +fi + +# Create .dmg +rm -f OpenSC-${PACKAGE_VERSION}.dmg +i=0 +while ! hdiutil create -srcfolder "${imagedir}" -volname "${PACKAGE_NAME}" -fs JHFS+ OpenSC-${PACKAGE_VERSION}.dmg +do + i=$[$i+1] + if [ $i -gt 2 ] + then + exit 1 + fi +done +rm -rf ${imagedir} diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in deleted file mode 100755 index 80b32a188e..0000000000 --- a/MacOSX/build-package.in +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/bash -# Build the macOS installer for the token and command line tools. -# -# This is only tested and supported on macOS 10.10 or later, using Xcode 6.0.1. -# Building should also work on older macOS versions with slight changes; YMMV. - -# You need to install the following packages from homebrew or macports or fink: -# autoconf automake libtool pkg-config help2man gengetopt - -export MACOSX_DEPLOYMENT_TARGET="10.13" -FORCE_OPENSSL_BUILD="1" - -set -ex -test -x ./configure || ./bootstrap -BUILDPATH=${PWD} - -export SED=/usr/bin/sed -PREFIX=/Library/OpenSC -export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig - -if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-version=1.1.1; then - # OpenSSL is not installed - if ! test -e $BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig; then - # Build OpenSSL manually, because Apple's binaries are deprecated - sh build-openssl-macos.sh -b $BUILDPATH -p $PREFIX - fi - export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`" - export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`" - export CRYPTO_CFLAGS="$OPENSSL_CFLAGS" - export CRYPTO_LIBS="$OPENSSL_LIBS" -fi - -export CFLAGS="$CFLAGS -arch x86_64 -arch arm64" -export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64" -export OBJCFLAGS=$CFLAGS - -if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then - if ! test -e openpace; then - git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.3 - fi - cd openpace - autoreconf -vis - ./configure --disable-shared --prefix=$PREFIX HELP2MAN=/usr/bin/true - touch src/cvc-create.1 src/cvc-print.1 - make DESTDIR=$BUILDPATH/openpace_bin install - cd .. -fi -export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS" -export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig:$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS" - -if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then - ./configure --prefix=$PREFIX \ - --sysconfdir=$PREFIX/etc \ - --enable-cvcdir=$PREFIX/etc/cvc \ - --enable-x509dir=$PREFIX/etc/x509 \ - --enable-openssl-secure-malloc=65536 \ - --disable-dependency-tracking \ - --enable-shared \ - --enable-static \ - --enable-strict \ - --disable-assert \ - --enable-sm # TODO: remove this (must be sensible default in master) - - # always make clean - make clean - - # compile - make -j 4 - - # copy files - rm -rf ${BUILDPATH}/target - make install DESTDIR=${BUILDPATH}/target - - # remove garbage - rm -f ${BUILDPATH}/target/$PREFIX/lib/*.la - rm -f ${BUILDPATH}/target/$PREFIX/lib/*.a - - # generate .bundle (required by Adobe Acrobat) - ./MacOSX/libtool-bundle ${BUILDPATH}/target/$PREFIX/lib/opensc-pkcs11.so ${BUILDPATH}/target/$PREFIX/lib -fi - - -if ! test -e NotificationProxy; then - git clone https://github.com/frankmorgner/NotificationProxy.git -fi -if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then - xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ \ - CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual -else - xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ -fi -mkdir -p "$BUILDPATH/target/Applications/Utilities" -osacompile -o "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript" -if test -n "${CODE_SIGN_IDENTITY}"; then - codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app" -fi - - -imagedir=$(mktemp -d) - -# Prepare target root -mkdir -p ${BUILDPATH}/target/usr/local/bin -cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin - -# Prepare startup root -mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents -cp src/tools/org.opensc-project.mac.pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents -cp src/tools/org.opensc-project.mac.opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents - -# Build OpenSCToken if possible -if test -e OpenSCToken -a -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then - cd OpenSCToken - # make sure OpenSCToken builds with the same dependencies as before - if ! test -e OpenSC; then - git clone --depth=1 file://$PWD/../../OpenSC - else - cd OpenSC && git pull && cd .. - fi - mkdir -p build - if ! test -e build/openssl; then - # build/openssl/lib/libcrypto.a is hardcoded in OpenSCToken - ln -sf $BUILDPATH/openssl_bin/$PREFIX build/openssl - # in OpenSCToken's variant of OpenSC we still use OpenSSL flags from above - fi - if ! test -e build/openpace; then - # build/openpace/lib/libeac.a is hardcoded in OpenSCToken - ln -sf $BUILDPATH/openpace_bin/$PREFIX build/openpace - # in OpenSCToken's variant of OpenSC we still use OpenPACE flags from above - fi - BP=${BUILDPATH} - . ./bootstrap - BUILDPATH=${BP} - xcodebuild -target OpenSCTokenApp -configuration Debug -project OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target_token \ - CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual - cd .. - - COMPONENT_TOKEN="--component-plist MacOSX/target_token.plist" -else - # if no OpenSCToken is checked out, then we create a dummy package - mkdir -p ${BUILDPATH}/target_token -fi - -if test -n "${CODE_SIGN_IDENTITY}"; then - for d in ${BUILDPATH}/target/Library/OpenSC/bin ${BUILDPATH}/target/Library/OpenSC/lib - do - # find executable files and run codesign on them - find ${d} -type f -perm +111 -print -exec \ - codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_binaries.entitlements --deep --timestamp --options runtime {} \; - done -fi - - -# Build package -pkgbuild --root ${BUILDPATH}/target --component-plist MacOSX/target.plist --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg -pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.opensc-project.mac.opensctoken --version @PACKAGE_VERSION@ --install-location / OpenSCToken.pkg -pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg - -# Build product -productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" - -# Sign installer -if test -n "${INSTALLER_SIGN_IDENTITY}"; then - productsign --sign "${INSTALLER_SIGN_IDENTITY}" "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" "${BUILDPATH}/OpenSC @PACKAGE_VERSION@.pkg" - mv "${BUILDPATH}/OpenSC @PACKAGE_VERSION@.pkg" "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" -fi - -# Build "Uninstaller" -osacompile -o "${imagedir}/OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript" -if test -n "${CODE_SIGN_IDENTITY}"; then - codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "${imagedir}/OpenSC Uninstaller.app" -fi - -# Create .dmg -rm -f OpenSC-@PACKAGE_VERSION@.dmg -i=0 -while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@.dmg -do - i=$[$i+1] - if [ $i -gt 2 ] - then - exit 1 - fi -done -rm -rf ${imagedir} diff --git a/configure.ac b/configure.ac index 282d20fd3e..f6e5cfe48c 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ m4_esyscmd([awk -F= ' m4_sinclude(m4/version.m4.ci) -# Hint: MacOSX/build-package.in contains minimum OpenSSL reference +# Hint: MacOSX/build contains minimum OpenSSL reference m4_define([openssl_minimum_version], [1.1.1]) AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) @@ -1203,7 +1203,6 @@ AC_CONFIG_FILES([ win32/Makefile win32/OpenSC.iss MacOSX/Makefile - MacOSX/build-package MacOSX/Distribution.xml MacOSX/resources/Welcome.html ]) From 22484d970f4136ac25bdb3c000f6ba6abbb07f26 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 27 Oct 2025 09:34:50 +0200 Subject: [PATCH 3998/4321] Implement FinEID 4.0/4.1 support Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2025.c | 9 ++ src/libopensc/cards.h | 2 + src/libopensc/pkcs15-esteid2025.c | 139 ++++++++++++++++++++---------- 3 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/libopensc/card-esteid2025.c b/src/libopensc/card-esteid2025.c index a0f153dbc1..0b3d53b05f 100644 --- a/src/libopensc/card-esteid2025.c +++ b/src/libopensc/card-esteid2025.c @@ -30,8 +30,17 @@ #define SIGNATURE_PAYLOAD_SIZE 0x30 +/* + * EstEID: https://www.id.ee/wp-content/uploads/2025/11/ged24035_015_tdc_est_eid_developer_guide.pdf + * FinEID: + * * App 4.0: https://dvv.fi/documents/16079645/17324992/S1v40+(1).pdf/56a167fe-9f26-1fda-7d76-cfbbb29d184e/S1v40+(1).pdf + * * Imp 4.0: https://dvv.fi/documents/16079645/17324992/S4-1v40.pdf/55bddc08-6893-b4b4-73fa-24dced600198/S4-1v40.pdf + * * Imp 4.1: https://dvv.fi/documents/16079645/17324992/S4-1v41.pdf/63afc997-ed16-a00b-bdca-e9971b164137/S4-1v41.pdf + */ static const struct sc_atr_table esteid_atrs[] = { {"3b:ff:96:00:00:80:31:fe:43:80:31:b8:53:65:49:44:64:b0:85:05:10:12:23:3f:1d", NULL, "EstEID 2025", SC_CARD_TYPE_ESTEID_2025, 0, NULL}, + {"3b:7f:96:00:00:80:31:b8:65:b0:85:05:00:11:12:24:60:82:90:00", NULL, "FinEID 2022", SC_CARD_TYPE_FINEID_2022, 0, NULL}, + {"3b:7f:96:00:00:80:31:b8:65:b0:85:05:10:24:12:24:60:82:90:00", NULL, "FinEID 2025", SC_CARD_TYPE_FINEID_2025, 0, NULL}, {NULL, NULL, NULL, 0, 0, NULL} }; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index d4a815f624..34e4a9b3d2 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -233,6 +233,8 @@ enum { SC_CARD_TYPE_ESTEID_2018 = 35000, SC_CARD_TYPE_ESTEID_2018_V2_2025, SC_CARD_TYPE_ESTEID_2025, + SC_CARD_TYPE_FINEID_2022, + SC_CARD_TYPE_FINEID_2025, /* Rutoken cards */ SC_CARD_TYPE_RUTOKENS = 36000, diff --git a/src/libopensc/pkcs15-esteid2025.c b/src/libopensc/pkcs15-esteid2025.c index 8514667647..bd6b42fff5 100644 --- a/src/libopensc/pkcs15-esteid2025.c +++ b/src/libopensc/pkcs15-esteid2025.c @@ -24,6 +24,7 @@ #include #include +#include #include "common/compat_strlcpy.h" @@ -31,52 +32,91 @@ #include "opensc.h" #include "pkcs15.h" +static int +is_fin_eid(sc_pkcs15_card_t *p15card) +{ + return p15card->card->type == SC_CARD_TYPE_FINEID_2022 || + p15card->card->type == SC_CARD_TYPE_FINEID_2025; +} + static int sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) { sc_card_t *card = p15card->card; - u8 *buff; int r, i; - size_t field_length = 0, buflen = 9, j; + size_t field_length = 0; sc_path_t tmppath; static const u8 prkey_id[2] = {0x01, 0x02}; + static const u8 pin_authid[3] = {1, 2, 3}; - set_string(&p15card->tokeninfo->label, "ID-kaart"); - set_string(&p15card->tokeninfo->manufacturer_id, "Thales"); + if (is_fin_eid(p15card)) { + u8 buf[SC_MAX_APDU_BUFFER_SIZE]; + const u8 *tag; + size_t taglen; - buff = malloc(buflen + 1); - if (!buff) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + sc_format_path("5032", &tmppath); + r = sc_select_file(card, &tmppath, NULL); + LOG_TEST_RET(card->ctx, r, "Selecting CIA path failed"); - /* Read document number to be used as serial */ - sc_format_path("DFDD5007", &tmppath); - r = sc_select_file(card, &tmppath, NULL); - if (r < 0) { - free(buff); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); - } - r = sc_read_binary(card, 0, buff, buflen, 0); - if (r < 0) { - free(buff); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); - } + r = sc_read_binary(p15card->card, 4, buf, sizeof(buf), 0); + LOG_TEST_RET(card->ctx, r, "Reading tokeninfo file failed"); + + tag = sc_asn1_find_tag(card->ctx, buf, r, 0x04, &taglen); + if (tag == NULL) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Finding document number tag failed"); + + for (size_t j = 0; j < taglen; j++) { + if (!isalnum(tag[j])) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Invalid character in document number"); + } + + free(p15card->tokeninfo->serial_number); + p15card->tokeninfo->serial_number = malloc(taglen + 1); + if (p15card->tokeninfo->serial_number == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + p15card->tokeninfo->serial_number = memcpy(p15card->tokeninfo->serial_number, tag, taglen); + p15card->tokeninfo->serial_number[taglen] = '\0'; + } else { + u8 *buf; + size_t buflen = 9; - for (j = 0; j < buflen; j++) { - if (!isalnum(buff[j])) { - free(buff); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + /* Read document number to be used as serial */ + sc_format_path("DFDD5007", &tmppath); + r = sc_select_file(card, &tmppath, NULL); + LOG_TEST_RET(card->ctx, r, "Selecting document number file failed"); + + buf = malloc(buflen + 1); + if (!buf) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + r = sc_read_binary(card, 0, buf, buflen, 0); + if (r < 0) { + free(buf); + LOG_TEST_GOTO_ERR(card->ctx, r, "Reading document number failed"); + } + + for (int j = 0; j < r; j++) { + if (!isalnum(buf[j])) { + free(buf); + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_CARD, "Invalid character in document number"); + } } + buf[r] = '\0'; + + free(p15card->tokeninfo->serial_number); + p15card->tokeninfo->serial_number = (char *)buf; } - buff[buflen] = '\0'; - free(p15card->tokeninfo->serial_number); - p15card->tokeninfo->serial_number = (char *)buff; + set_string(&p15card->tokeninfo->label, "ID-kaart"); + set_string(&p15card->tokeninfo->manufacturer_id, "Thales"); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; /* add certificates */ for (i = 0; i < 2; i++) { static const char *cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; - static const char *cert_paths[2] = {"ADF1:3411", "ADF2:3421"}; + static const char *cert_paths[2][2] = { + {"ADF1:3411", "ADF2:3421"}, + {"4331", "5016:4332"}, + }; struct sc_pkcs15_cert_info cert_info = { .id = {.len = 1, .value[0] = prkey_id[i]} @@ -84,7 +124,7 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object cert_obj = {0}; strlcpy(cert_obj.label, cert_names[i], sizeof(cert_obj.label)); - sc_format_path(cert_paths[i], &cert_info.path); + sc_format_path(cert_paths[is_fin_eid(p15card)][i], &cert_info.path); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add cert object"); @@ -120,31 +160,40 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) /* add pins */ for (i = 0; i < 3; i++) { static const char *pin_names[3] = {"PIN1", "PIN2", "PUK"}; - static const size_t pin_min[3] = {4, 5, 8}; - static const int pin_ref[3] = {0x81, 0x82, 0x83}; - static const u8 pin_authid[3] = {1, 2, 3}; + static const size_t pin_min[2][3] = { + {4, 5, 8}, + {4, 6, 8}, + }; + static const int pin_ref[2][3] = { + {0x81, 0x82, 0x83}, + {0x11, 0x82, 0x83}, + }; - static const unsigned int pin_flags[3] = { - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + static const unsigned int pin_flags[2][3] = { + {SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL}, + {SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL}, + }; struct sc_pkcs15_auth_info pin_info = { .auth_id = {.len = 1, .value[0] = pin_authid[i]}, .auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN, .attrs = { .pin = { - .reference = pin_ref[i], - .flags = pin_flags[i], + .reference = pin_ref[is_fin_eid(p15card)][i], + .flags = pin_flags[is_fin_eid(p15card)][i], .type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - .min_length = pin_min[i], + .min_length = pin_min[is_fin_eid(p15card)][i], .stored_length = 12, .max_length = 12, .pad_char = 0x00}}, .tries_left = 3, .max_tries = 3 }; - struct sc_pkcs15_object pin_obj = {.flags = pin_flags[i]}; + struct sc_pkcs15_object pin_obj = {.flags = pin_flags[is_fin_eid(p15card)][i]}; strlcpy(pin_obj.label, pin_names[i], sizeof(pin_obj.label)); @@ -172,8 +221,10 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) /* add private keys */ for (i = 0; i < 2; i++) { - static const u8 prkey_ref[2] = {0x01, 0x05}; - static const u8 prkey_pin[2] = {1, 2}; + static const u8 prkey_ref[2][2] = { + {0x01, 0x05}, + {0x01, 0x02}, + }; static const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; static const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; @@ -182,12 +233,12 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_prkey_info prkey_info = { .id = {.len = 1, .value[0] = prkey_id[i]}, .native = 1, - .key_reference = prkey_ref[i], + .key_reference = prkey_ref[is_fin_eid(p15card)][i], .field_length = field_length, .usage = prkey_usage[i] }; struct sc_pkcs15_object prkey_obj = { - .auth_id = {.len = 1, .value[0] = prkey_pin[i]}, + .auth_id = {.len = 1, .value[0] = pin_authid[i]}, .user_consent = prkey_consent[i], .flags = SC_PKCS15_CO_FLAG_PRIVATE }; @@ -207,7 +258,7 @@ sc_pkcs15emu_esteid2025_init(sc_pkcs15_card_t *p15card) int sc_pkcs15emu_esteid2025_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { - if (p15card->card->type == SC_CARD_TYPE_ESTEID_2025) + if (p15card->card->type == SC_CARD_TYPE_ESTEID_2025 || is_fin_eid(p15card)) return sc_pkcs15emu_esteid2025_init(p15card); return SC_ERROR_WRONG_CARD; } From f6270095900b88588cfab1d76157bfb5825ae2c7 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 20 Oct 2025 12:54:34 +0300 Subject: [PATCH 3999/4321] Add Latvian IDEMIA Cosmo X card support Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2018.c | 53 ++++++++++++++++++------------- src/libopensc/cards.h | 1 + src/libopensc/iso7816.c | 3 ++ src/libopensc/pkcs15-esteid2018.c | 49 +++++++++++++++++----------- 4 files changed, 66 insertions(+), 40 deletions(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 0272e01165..2eb10ad2b8 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -32,15 +32,18 @@ /* Helping defines */ #define SIGNATURE_PAYLOAD_SIZE 0x30 -#define AUTH_REF 0x81 -#define SIGN_REF 0x9f +#define SIGN_REF 0x10 #define PIN1_REF 0x01 #define PIN2_REF 0x85 #define PUK_REF 0x02 +/* + * EstEID: https://www.id.ee/wp-content/uploads/2025/10/id1developerguide2025.pdf + */ static const struct sc_atr_table esteid_atrs[] = { {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, - {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018_V2_2025, 0, NULL}, + {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018_V2_2025, 0, NULL}, + {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:42:8f:54:65:49:44:32:0f:90:00:12", NULL, "Latvian eID 2018 v2", SC_CARD_TYPE_LATEID_2018_V2_2025, 0, NULL}, {NULL, NULL, NULL, 0, 0, NULL} }; @@ -105,7 +108,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat } for (size_t pathlen = in_path->len; pathlen >= 2; pathlen -= 2, path += 2) { - if (memcmp(path, "\x3F\x00", 2) == 0) { + if (pathlen == 2 && memcmp(path, "\x3F\x00", 2) == 0) { sc_format_apdu_ex(&apdu, card->cla, 0xA4, 0x00, 0x0C, path, 0, NULL, 0); SC_TRANSMIT_TEST_RET(card, apdu, "MF select failed"); } else if (pathlen == 2 && path[0] == 0xAD) { @@ -135,11 +138,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { struct esteid_priv_data *priv; - struct sc_apdu apdu; - - static const u8 cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, AUTH_REF}; - static const u8 cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, SIGN_REF}; - static const u8 cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, AUTH_REF}; + sc_security_env_t new_env = {0}; LOG_FUNC_CALLED(card->ctx); @@ -148,16 +147,28 @@ static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env sc_log(card->ctx, "algo: %lu operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); - if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == AUTH_REF) { - sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0); - } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == SIGN_REF) { - sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0); - } else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == AUTH_REF) { - sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0); - } else { + if (env->algorithm != SC_ALGORITHM_EC) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - SC_TRANSMIT_TEST_RET(card, apdu, "SET SECURITY ENV failed"); + new_env = *env; + switch (env->operation) { + case SC_SEC_OPERATION_SIGN: + if (env->key_ref[0] & SIGN_REF) { + new_env.algorithm_ref = 0x54; + } else { + new_env.operation = SC_SEC_OPERATION_AUTHENTICATE; + new_env.algorithm_ref = 0x04; + } + break; + case SC_SEC_OPERATION_DERIVE: + new_env.algorithm_ref = 0x0B; + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + new_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT; + new_env.flags &= ~SC_SEC_ENV_FILE_REF_PRESENT; + LOG_TEST_RET(card->ctx, iso_ops->set_security_env(card, &new_env, se_num), "Failed to set security environment"); priv = DRVDATA(card); priv->sec_env = *env; @@ -180,12 +191,10 @@ static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t data memcpy(&sbuf[SIGNATURE_PAYLOAD_SIZE - datalen], data, MIN(datalen, SIGNATURE_PAYLOAD_SIZE)); datalen = SIGNATURE_PAYLOAD_SIZE; - switch (env->key_ref[0]) { - case AUTH_REF: - sc_format_apdu_ex(&apdu, 0x00, 0x88, 0, 0, sbuf, datalen, out, le); - break; - default: + if ((env->key_ref[0] & SIGN_REF) > 0) { sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, le); + } else { + sc_format_apdu_ex(&apdu, 0x00, 0x88, 0, 0, sbuf, datalen, out, le); } SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed"); diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 34e4a9b3d2..ce61867f47 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -232,6 +232,7 @@ enum { /* EstEID cards */ SC_CARD_TYPE_ESTEID_2018 = 35000, SC_CARD_TYPE_ESTEID_2018_V2_2025, + SC_CARD_TYPE_LATEID_2018_V2_2025, SC_CARD_TYPE_ESTEID_2025, SC_CARD_TYPE_FINEID_2022, SC_CARD_TYPE_FINEID_2025, diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index e58fed1498..d61a274236 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -988,6 +988,9 @@ iso7816_set_security_env(struct sc_card *card, } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); switch (env->operation) { + case SC_SEC_OPERATION_AUTHENTICATE: + apdu.p2 = 0xA4; + break; case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_DERIVE: apdu.p2 = 0xB8; diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index ab728b138b..f2baf17640 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -33,16 +33,19 @@ #include "opensc.h" #include "pkcs15.h" +static int +is_latvian_eid(sc_pkcs15_card_t *p15card) +{ + return p15card->card->type == SC_CARD_TYPE_LATEID_2018_V2_2025; +} + static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { sc_card_t *card = p15card->card; u8 buff[11]; int r, i; - size_t field_length = 0, taglen, j; + size_t field_length = 0, taglen; sc_path_t tmppath; - set_string(&p15card->tokeninfo->label, "ID-kaart"); - set_string(&p15card->tokeninfo->manufacturer_id, "IDEMIA"); - /* Read documber number to be used as serial */ sc_format_path("3F00D003", &tmppath); LOG_TEST_RET(card->ctx, sc_select_file(card, &tmppath, NULL), "SELECT docnr"); @@ -52,13 +55,16 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - for (j = 0; j < taglen; j++) + for (size_t j = 0; j < taglen; j++) if (!isalnum(tag[j])) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = malloc(taglen + 1); if (!p15card->tokeninfo->serial_number) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + + set_string(&p15card->tokeninfo->label, "ID-kaart"); + set_string(&p15card->tokeninfo->manufacturer_id, "IDEMIA"); p15card->tokeninfo->serial_number = memcpy(p15card->tokeninfo->serial_number, tag, taglen); p15card->tokeninfo->serial_number[taglen] = '\0'; p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; @@ -109,27 +115,30 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { } /* add pins */ + static const u8 pin_authid[3] = {1, 2, 3}; for (i = 0; i < 3; i++) { static const char *esteid_pin_names[3] = {"PIN1", "PIN2", "PUK"}; - static const size_t esteid_pin_min[3] = {4, 5, 8}; + static const size_t pin_min[2][3] = { + {4, 5, 8}, // Estonian + {4, 6, 8}, // Latvian + }; static const int esteid_pin_ref[3] = {0x01, 0x85, 0x02}; - static const u8 esteid_pin_authid[3] = {1, 2, 3}; static const char *esteid_pin_path[3] = {"3F00", "3F00ADF2", "3F00"}; static const unsigned int esteid_pin_flags[3] = { - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL, - SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL, + SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL}; struct sc_pkcs15_auth_info pin_info = { - .auth_id = {.len = 1, .value[0] = esteid_pin_authid[i]}, + .auth_id = {.len = 1, .value[0] = pin_authid[i]}, .auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN, .attrs = { .pin = { .reference = esteid_pin_ref[i], .flags = esteid_pin_flags[i], .type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, - .min_length = esteid_pin_min[i], + .min_length = pin_min[is_latvian_eid(p15card)][i], .stored_length = 12, .max_length = 12, .pad_char = 0xFF}}, @@ -166,23 +175,26 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { /* add private keys */ for (i = 0; i < 2; i++) { - static const u8 prkey_pin[2] = {1, 2}; + static const u8 prkey_id[2] = {1, 2}; static const char *prkey_name[2] = {"Isikutuvastus", "Allkirjastamine"}; static const char *prkey_path[2] = {"3F00:ADF1", "3F00:ADF2"}; static const unsigned int prkey_usage[2] = {SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; static const int prkey_consent[2] = {0, 1}; - static const u8 esteid_prkey_id[2] = {0x81, 0x9F}; + static const u8 prkey_ref[2][2] = { + {0x81, 0x9F}, // Slot 1 + {0x82, 0x9E}, // Slot 2 + }; struct sc_pkcs15_prkey_info prkey_info = { - .id = {.len = 1, .value[0] = prkey_pin[i]}, + .id = {.len = 1, .value[0] = prkey_id[i]}, .native = 1, - .key_reference = esteid_prkey_id[i], + .key_reference = prkey_ref[is_latvian_eid(p15card)][i], .field_length = field_length, .usage = prkey_usage[i] }; struct sc_pkcs15_object prkey_obj = { - .auth_id = {.len = 1, .value[0] = prkey_pin[i]}, + .auth_id = {.len = 1, .value[0] = pin_authid[i]}, .user_consent = prkey_consent[i], .flags = SC_PKCS15_CO_FLAG_PRIVATE }; @@ -202,7 +214,8 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { int sc_pkcs15emu_esteid2018_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) { if (p15card->card->type == SC_CARD_TYPE_ESTEID_2018 || - p15card->card->type == SC_CARD_TYPE_ESTEID_2018_V2_2025) + p15card->card->type == SC_CARD_TYPE_ESTEID_2018_V2_2025 || + is_latvian_eid(p15card)) return sc_pkcs15emu_esteid2018_init(p15card); return SC_ERROR_WRONG_CARD; } From b678790dae577d83605c433a083eba4603aaf225 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:11:13 +0100 Subject: [PATCH 4000/4321] ci: Dump just tail of the test logs to make ui usable --- .github/dump-logs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dump-logs.sh b/.github/dump-logs.sh index cca2ccc5e9..ad0f385a24 100755 --- a/.github/dump-logs.sh +++ b/.github/dump-logs.sh @@ -6,7 +6,7 @@ fi echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" for F in ${REL}tests/*.log ${REL}src/tests/unittests/*.log; do echo "::group::$F" - cat $F + tail -n50 $F echo "::endgroup::" done echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" From 6f56b52d1b2bd7046580bac1552245862cd626de Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:11:29 +0100 Subject: [PATCH 4001/4321] ci: Upload full test logs also from the codeql job --- .github/workflows/codeql.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0fd05d42b5..b182a6c4ba 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,6 +38,15 @@ jobs: - run: .github/setup-linux.sh force-install - run: .github/build.sh + - name: Upload test logs + uses: actions/upload-artifact@v4 + if: failure() + with: + name: codeql-logs + path: | + tests/*.log + src/tests/unittests/*.log + - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: From e888216cb06027e44aa91ccc2cf7ae560756b100 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:28:39 +0100 Subject: [PATCH 4002/4321] tests: Make p11test more verbose and show more context in diff --- tests/test-p11test.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 13cac358e8..1c27d09cd5 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -33,8 +33,6 @@ assert $? "Failed running tests" # Run the input through sed to skip the mechanism part: # * broken because of uninitialized memory in softhsm # * different for different softhsm versions -# and interface tests -# * different results for softhsm and pkcs11-spy function filter_log() { sed -n '/readonly_tests/,$p' $1 } @@ -44,7 +42,8 @@ if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" fi -diff -U3 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) +echo "Comparing with $REF_FILE" +diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) assert $? "Unexpected results" echo "=======================================================" @@ -54,7 +53,8 @@ export PKCS11SPY="$P11LIB" $VALGRIND ./../src/tests/p11test/p11test -v -m ../src/pkcs11/.libs/pkcs11-spy.so -o $TOKENTYPE.json -p $PIN assert $? "Failed running tests" -diff -U3 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) +echo "Comparing with $REF_FILE" +diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) assert $? "Unexpected results with PKCS11 spy" rm $TOKENTYPE.json From 00f98615b3a72bac47e6aeeb33e8794cac8712f0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:54:13 +0100 Subject: [PATCH 4003/4321] tests: Use proper paths for running p11test --- tests/test-p11test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 1c27d09cd5..69130ae911 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -27,7 +27,7 @@ assert $? "Failed to set up card" echo "=======================================================" echo "Run p11test" echo "=======================================================" -$VALGRIND ./../src/tests/p11test/p11test -v -m $P11LIB -o $TOKENTYPE.json -p $PIN +$VALGRIND "$BUILD_PATH/src/tests/p11test/p11test" -v -m $P11LIB -o $TOKENTYPE.json -p $PIN assert $? "Failed running tests" # Run the input through sed to skip the mechanism part: @@ -37,7 +37,7 @@ function filter_log() { sed -n '/readonly_tests/,$p' $1 } -REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_ref.json" +REF_FILE="$BUILD_PATH/tests/${TOKENTYPE}_ref.json" if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" fi @@ -50,7 +50,7 @@ echo "=======================================================" echo "Run p11test with PKCS11SPY" echo "=======================================================" export PKCS11SPY="$P11LIB" -$VALGRIND ./../src/tests/p11test/p11test -v -m ../src/pkcs11/.libs/pkcs11-spy.so -o $TOKENTYPE.json -p $PIN +$VALGRIND "$BUILD_PATH/src/tests/p11test/p11test" -v -m "$BUILD_PATH/src/pkcs11/.libs/pkcs11-spy.so" -o $TOKENTYPE.json -p $PIN assert $? "Failed running tests" echo "Comparing with $REF_FILE" From 85594879b3063a24a0f5e4c6291c622a8933f436 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:55:02 +0100 Subject: [PATCH 4004/4321] tests: Properly report errors from external scripts --- tests/test-kryoptic.sh | 2 +- tests/test-softhsm.sh | 2 +- tests/test-softokn.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index 1a9c0105cb..202dd8fe12 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for Kryoptic token..." diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh index 2b500215e6..92e4c05604 100755 --- a/tests/test-softhsm.sh +++ b/tests/test-softhsm.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for SoftHSM token..." diff --git a/tests/test-softokn.sh b/tests/test-softokn.sh index 5e467cf311..813aec97ea 100755 --- a/tests/test-softokn.sh +++ b/tests/test-softokn.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for NSS Softokn token..." From 26b2f7c30a45928babfa1fdc84ddb4d06eb0530f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 14:10:06 +0100 Subject: [PATCH 4005/4321] tests: Fix test name in script --- tests/test-kryoptic.sh | 2 +- tests/test-softhsm.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index 202dd8fe12..c235da55ca 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -7,6 +7,6 @@ $SOURCE_PATH/tests/test-p11test.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic -#$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt.sh kryoptic +#$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt-test.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-test.sh kryoptic $SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh kryoptic diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh index 92e4c05604..85093a0bda 100755 --- a/tests/test-softhsm.sh +++ b/tests/test-softhsm.sh @@ -7,7 +7,7 @@ $SOURCE_PATH/tests/test-p11test.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt.sh softhsm +$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt-test.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-test-threads.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-test.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softhsm From c315d99d0337268d5e72f12482a072245290172e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 14:20:55 +0100 Subject: [PATCH 4006/4321] tests: Properly use BUILD_PATH --- tests/test-pkcs11-tool-test-threads.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index 6d778b15b7..a961e634ff 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -14,12 +14,12 @@ fi source $SOURCE_PATH/tests/common.sh $TOKENTYPE # Test our PKCS #11 module here -P11LIB="../src/pkcs11/.libs/opensc-pkcs11.so" +P11LIB="$BUILD_PATH/src/pkcs11/.libs/opensc-pkcs11.so" echo "=======================================================" echo "Test pkcs11 threads IN " echo "=======================================================" -OPENSC_TOOL="../src/tools/opensc-tool" +OPENSC_TOOL="$BUILD_PATH/src/tools/opensc-tool" echo "check for opensc-tool" if [[ -f $OPENSC_TOOL ]] ; then echo "trying opensc-tool -a" From eb7f0af64fff9a9fff421998612adc31d853e721 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 14:31:07 +0100 Subject: [PATCH 4007/4321] tests: Drop threads tests from softhsm CI --- tests/test-softhsm.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh index 85093a0bda..f456c6dc2e 100755 --- a/tests/test-softhsm.sh +++ b/tests/test-softhsm.sh @@ -8,6 +8,5 @@ $SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt-test.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-test-threads.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-test.sh softhsm $SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softhsm From 98c9ef09da3896b26596043916fba3bce71ac443 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 14:54:23 +0100 Subject: [PATCH 4008/4321] ci: Add reference kryoptic results --- tests/kryoptic_ref.json | 11525 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 11525 insertions(+) create mode 100644 tests/kryoptic_ref.json diff --git a/tests/kryoptic_ref.json b/tests/kryoptic_ref.json new file mode 100644 index 0000000000..10a76d7d45 --- /dev/null +++ b/tests/kryoptic_ref.json @@ -0,0 +1,11525 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "1024", + "16384", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "RSA_PKCS", + "1024", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" + ], + [ + "RSA_X_509", + "1024", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" + ], + [ + "SHA1_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_OAEP", + "1024", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA1_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000048", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x00000049", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000004A", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000004B", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x0000004C", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x0000004D", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000004E", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000004F", + "0", + "0", + "CKF_DERIVE" + ], + [ + "SHA3_256_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_384_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_512_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_256_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_384_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_512_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_224_RSA_PKCS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_224_RSA_PKCS_PSS", + "1024", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA_1_HMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA_1_HMAC_GENERAL", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256_HMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_HMAC_GENERAL", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224_HMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224_HMAC_GENERAL", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384_HMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_HMAC_GENERAL", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512_HMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_HMAC_GENERAL", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA3_256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x000002B1", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002B2", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002B3", + "0", + "0", + "CKF_GENERATE" + ], + [ + "SHA3_224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x000002B6", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002B7", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002B8", + "0", + "0", + "CKF_GENERATE" + ], + [ + "SHA3_384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x000002C1", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002C2", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002C3", + "0", + "0", + "CKF_GENERATE" + ], + [ + "SHA3_512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "0x000002D1", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002D2", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000002D3", + "0", + "0", + "CKF_GENERATE" + ], + [ + "GENERIC_SECRET_KEY_GEN", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00000392", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000393", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000394", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000395", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000396", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000397", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000398", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00000399", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x0000039A", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x000003AC", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x000003AD", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x000003B0", + "0", + "-1", + "CKF_GENERATE" + ], + [ + "0x000003D8", + "0", + "-1", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000003D9", + "48", + "48", + "CKF_DERIVE" + ], + [ + "0x000003E0", + "48", + "48", + "CKF_DERIVE" + ], + [ + "0x000003E1", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x000003E3", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x000003E4", + "0", + "-1", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x000003E5", + "48", + "48", + "CKF_DERIVE" + ], + [ + "EC_KEY_PAIR_GEN", + "256", + "521", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "ECDSA", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA1", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA224", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA256", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA384", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA512", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA3_224", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA3_256", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA3_384", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDSA_SHA3_512", + "256", + "521", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "ECDH1_DERIVE", + "256", + "521", + "CKF_DERIVE" + ], + [ + "ECDH1_COFACTOR_DERIVE", + "256", + "521", + "CKF_DERIVE" + ], + [ + "EC_EDWARDS_KEY_PAIR_GEN", + "256", + "456", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x00001056", + "256", + "448", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "EDDSA", + "256", + "456", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_KEY_GEN", + "16", + "32", + "CKF_GENERATE" + ], + [ + "AES_ECB", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_CBC", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_MAC", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_MAC_GENERAL", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_CBC_PAD", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_CTR", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_GCM", + "16", + "32", + "CKF_MESSAGE_ENCRYPT,CKF_MESSAGE_DECRYPT,CKF_MULTI_MESSAGE,CKF_ENCRYPT,CKF_DECRY" + ], + [ + "AES_CCM", + "16", + "32", + "CKF_MESSAGE_ENCRYPT,CKF_MESSAGE_DECRYPT,CKF_MULTI_MESSAGE,CKF_ENCRYPT,CKF_DECRY" + ], + [ + "AES_CTS", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_CMAC", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_CMAC_GENERAL", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_ECB_ENCRYPT_DATA", + "16", + "32", + "CKF_DERIVE" + ], + [ + "AES_CBC_ENCRYPT_DATA", + "16", + "32", + "CKF_DERIVE" + ], + [ + "AES_OFB", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CFB8", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CFB128", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00002108", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_KEY_WRAP", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "0x0000210B", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "0x00004003", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004004", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004005", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004006", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004007", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004008", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00004009", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x0000402A", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x0000402B", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x0000402C", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x8007678C", + "0", + "-1", + "CKF_DERIVE" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "01", + "RSA_X_509", + "YES", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "02", + "RSA_X_509", + "YES", + "YES" + ], + [ + "02", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS", + "YES", + "" + ], + [ + "03", + "ECDSA", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA512", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA3_224", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA3_256", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA3_384", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA3_512", + "YES", + "" + ], + [ + "04", + "ECDSA", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA512", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA3_224", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA3_256", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA3_384", + "YES", + "" + ], + [ + "04", + "ECDSA_SHA3_512", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA3_256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA3_384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA3_512_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA3_224_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA3_256_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA3_384_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA3_512_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA3_224_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "result": "pass" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "01", + "RSA2048", + "RSA", + "2048", + "", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "02", + "RSA4096", + "RSA", + "4096", + "", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "03", + "ECC_auth", + "EC", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "YES", + "YES", + "" + ], + [ + "04", + "ECC521", + "EC", + "521", + "", + "YES", + "YES", + "", + "", + "", + "", + "YES", + "YES", + "" + ], + [ + "05", + "HMAC-SHA256", + "GEN", + "512", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "data": [ + [ + "KEY ID", + "MECHANISM", + "HASH", + "MGF", + "SALT", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA256", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA384", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_256", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ], + [ + "03", + "ECDH1_DERIVE", + "YES" + ], + [ + "03", + "ECDH1_COFACTOR_DERIVE", + "YES" + ], + [ + "04", + "ECDH1_DERIVE", + "YES" + ], + [ + "04", + "ECDH1_COFACTOR_DERIVE", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" +}] +} From 96f911f2037ff867d7d2fe281e3ea390bdd660a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Nov 2025 15:55:23 +0100 Subject: [PATCH 4009/4321] tests: Add more common kryoptic paths --- tests/init-kryoptic.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/init-kryoptic.sh b/tests/init-kryoptic.sh index 6d4237c5a3..1a0b5d6bd9 100755 --- a/tests/init-kryoptic.sh +++ b/tests/init-kryoptic.sh @@ -1,7 +1,9 @@ #!/bin/bash # set paths -kryoptic_paths="$BUILD_PATH/kryoptic/target/debug/libkryoptic_pkcs11.so" +kryoptic_paths="$BUILD_PATH/kryoptic/target/debug/libkryoptic_pkcs11.so \ + /usr/lib64/pkcs11/libkryoptic_pkcs11.so \ + /usr/lib/pkcs11/libkryoptic_pkcs11.so" for LIB in $kryoptic_paths; do echo "Testing $LIB" From ddc71a192fae34e1ea35183aed002e1e7d3dd2e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Trojnara?= Date: Tue, 28 Oct 2025 12:08:01 +0100 Subject: [PATCH 4010/4321] Revert "Fix Edwards and Montgomery "field_length"" This reverts commit 72125917695362de3306ebfeb06ce518b6fc42e6. --- src/libopensc/pkcs15-pubkey.c | 15 +++++++-------- src/pkcs11/framework-pkcs15.c | 6 +++--- src/tools/pkcs11-tool.c | 20 ++++++++++---------- src/tools/pkcs15-init.c | 12 ++++++------ 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index f752eaf570..2ff130c22d 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1524,18 +1524,17 @@ static struct ec_curve_info { /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs but we know the oid written to card */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", {(u8 *)"\x06\x09\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01", 11}, 256, SC_ALGORITHM_EDDSA}, - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", {(u8 *)"\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01", 12}, 256, SC_ALGORITHM_XEDDSA}, + {"edwards25519", "1.3.6.1.4.1.11591.15.1", {(u8 *)"\x06\x09\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01", 11}, 255, SC_ALGORITHM_EDDSA}, + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", {(u8 *)"\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01", 12}, 255, SC_ALGORITHM_XEDDSA}, /* RFC 8410 defined curves */ - {"X25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 256, SC_ALGORITHM_XEDDSA}, + {"X25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, {"X448", "1.3.101.111", {(u8 *)"\x06\x03\x2b\x65\x6f", 5}, 448, SC_ALGORITHM_XEDDSA}, - {"Ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 256, SC_ALGORITHM_EDDSA}, - /* Ed448 needs extra byte thus 456 */ - {"Ed448", "1.3.101.113", {(u8 *)"\x06\x03\x2b\x65\x71", 5}, 456, SC_ALGORITHM_EDDSA}, + {"Ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, + {"Ed448", "1.3.101.113", {(u8 *)"\x06\x03\x2b\x65\x71", 5}, 448, SC_ALGORITHM_EDDSA}, /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 256, SC_ALGORITHM_XEDDSA}, - {"ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 256, SC_ALGORITHM_EDDSA}, + {"cv25519", "1.3.101.110", {(u8 *)"\x06\x03\x2b\x65\x6e", 5}, 255, SC_ALGORITHM_XEDDSA}, + {"ed25519", "1.3.101.112", {(u8 *)"\x06\x03\x2b\x65\x70", 5}, 255, SC_ALGORITHM_EDDSA}, {NULL, NULL, {NULL, 0}, 0, 0}, /* Do not touch this */ }; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index aed2e9d858..f51cc5f8e4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2866,15 +2866,15 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } if (key_type == CKK_EC_EDWARDS) { - if (ec->ecpointQ.len == BYTES4BITS(256)) + if (ec->ecpointQ.len == BYTES4BITS(255)) ec->params.id = oid_ED25519; - else if (ec->ecpointQ.len == BYTES4BITS(456)) /* note extra byte */ + else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_ED448; else return CKR_ATTRIBUTE_VALUE_INVALID; } else if (key_type == CKK_EC_MONTGOMERY) { - if (ec->ecpointQ.len == BYTES4BITS(256)) + if (ec->ecpointQ.len == BYTES4BITS(255)) ec->params.id = oid_X25519; else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_X448; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 80abf639b3..4ddfe6f8e1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -155,19 +155,19 @@ static struct ec_curve_info { /* Some of the following may not yet be supported by the OpenSC module, but may be by other modules */ /* OpenPGP extensions by Yubikey and GNUK are not defined in RFCs, so pass by printable string */ /* See PKCS#11 3.0 2.3.7 */ - {"edwards25519", "1.3.6.1.4.1.11591.15.1", (unsigned char*)"\x13\x0c\x65\x64\x77\x61\x72\x64\x73\x32\x35\x35\x31\x39", 14, 256, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ - {"curve25519", "1.3.6.1.4.1.3029.1.5.1", (unsigned char*)"\x13\x0a\x63\x75\x72\x76\x65\x32\x35\x35\x31\x39", 12, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ + {"edwards25519", "1.3.6.1.4.1.11591.15.1", (unsigned char*)"\x13\x0c\x65\x64\x77\x61\x72\x64\x73\x32\x35\x35\x31\x39", 14, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* send by curve name */ + {"curve25519", "1.3.6.1.4.1.3029.1.5.1", (unsigned char*)"\x13\x0a\x63\x75\x72\x76\x65\x32\x35\x35\x31\x39", 12, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* send by curve name */ /* RFC8410, EDWARDS and MONTGOMERY curves are used by GnuPG and also by OpenSSL */ - {"X25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"X25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ {"X448", "1.3.101.111", (unsigned char*)"\x06\x03\x2b\x65\x6f", 5, 448, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ {"Ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ - {"Ed448", "1.3.101.113", (unsigned char*)"\x06\x03\x2b\x65\x71", 5, 456, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ + {"Ed448", "1.3.101.113", (unsigned char*)"\x06\x03\x2b\x65\x71", 5, 448, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* RFC 4810 send by OID */ /* GnuPG openpgp curves as used in gnupg-card are equivalent to RFC8410 OIDs */ - {"cv25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 256, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, - {"ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 256, CKM_EC_EDWARDS_KEY_PAIR_GEN}, + {"cv25519", "1.3.101.110", (unsigned char*)"\x06\x03\x2b\x65\x6e", 5, 255, CKM_EC_MONTGOMERY_KEY_PAIR_GEN}, + {"ed25519", "1.3.101.112", (unsigned char*)"\x06\x03\x2b\x65\x70", 5, 255, CKM_EC_EDWARDS_KEY_PAIR_GEN}, /* OpenSC card-openpgp.c will map these to what is need on the card */ {NULL, NULL, NULL, 0, 0, 0}, @@ -2606,7 +2606,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } /* Ed448: need the params defined but default to false */ - if (curve->size == 456) { + if (curve->size == 448) { mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } @@ -2776,7 +2776,7 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } /* Ed448: need the params defined but default to false */ - if (curve->size == 456) { + if (curve->size == 448) { mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } @@ -6940,14 +6940,14 @@ static int read_object(CK_SESSION_HANDLE session) } } - if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) + if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) raw_pk = EVP_PKEY_ED25519; #if defined(EVP_PKEY_ED448) else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #if defined(EVP_PKEY_X25519) - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) + else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(255)) raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ #if defined(EVP_PKEY_X448) diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 31c723e767..e011232987 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -730,15 +730,15 @@ static const struct alg_spec alg_types_asym[] = { { "gost2001", SC_ALGORITHM_GOSTR3410, SC_PKCS15_GOSTR3410_KEYSIZE }, { "ec", SC_ALGORITHM_EC, 0 }, /* keybits derived from curve */ /* RFC 8410 */ - { "Ed25519", SC_ALGORITHM_EDDSA, 256 }, /* RFC 8410 and gunpg */ - { "Ed448", SC_ALGORITHM_EDDSA, 456 }, /* note extra 8 bits to get 57 bytes */ - { "X25519", SC_ALGORITHM_XEDDSA, 256 }, + { "Ed25519", SC_ALGORITHM_EDDSA, 255 }, /* RFC 8410 and gunpg */ + { "Ed448", SC_ALGORITHM_EDDSA, 448 }, + { "X25519", SC_ALGORITHM_XEDDSA, 255 }, { "X448", SC_ALGORITHM_XEDDSA, 448 }, /* used by Yubikey and GNUK */ - { "edwards25519", SC_ALGORITHM_EDDSA, 256 }, - { "curve25519", SC_ALGORITHM_XEDDSA, 256 }, + { "edwards25519", SC_ALGORITHM_EDDSA, 255 }, + { "curve25519", SC_ALGORITHM_XEDDSA, 255 }, /* gnupg */ - { "cv25519", SC_ALGORITHM_XEDDSA, 256 }, + { "cv25519", SC_ALGORITHM_XEDDSA, 255 }, { NULL, -1, 0 } }; From c70be5a408e7d79c60bef5555240730af5f32804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Trojnara?= Date: Wed, 29 Oct 2025 21:39:06 +0100 Subject: [PATCH 4011/4321] Update Edwards and Montgomery key storage length This commit is a stripped down reimplementation of 72125917695362de3306ebfeb06ce518b6fc42e6, which updated the expected field_size instead of only the internal storage length. This broke pkcs11-tool at least with the following modules: - libsofthsm2.so - libykcs11.so.2 - opensc-pkcs11.so The returned error was: P:5669; T:0x139760863991616 09:18:11.899 [opensc-pkcs11] pkcs15-sec.c:221:format_senv: Card does not support EDDSA with field_size 256 --- src/pkcs11/framework-pkcs15.c | 6 +++--- src/tools/pkcs11-tool.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index f51cc5f8e4..9b6b067e7f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2866,15 +2866,15 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } if (key_type == CKK_EC_EDWARDS) { - if (ec->ecpointQ.len == BYTES4BITS(255)) + if (ec->ecpointQ.len == BYTES4BITS(256)) /* note extra bit */ ec->params.id = oid_ED25519; - else if (ec->ecpointQ.len == BYTES4BITS(448)) + else if (ec->ecpointQ.len == ED448_KEY_SIZE_BYTES) ec->params.id = oid_ED448; else return CKR_ATTRIBUTE_VALUE_INVALID; } else if (key_type == CKK_EC_MONTGOMERY) { - if (ec->ecpointQ.len == BYTES4BITS(255)) + if (ec->ecpointQ.len == BYTES4BITS(256)) /* note extra bit */ ec->params.id = oid_X25519; else if (ec->ecpointQ.len == BYTES4BITS(448)) ec->params.id = oid_X448; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4ddfe6f8e1..a37410239a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6940,14 +6940,14 @@ static int read_object(CK_SESSION_HANDLE session) } } - if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(255)) + if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_ED25519; #if defined(EVP_PKEY_ED448) else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #if defined(EVP_PKEY_X25519) - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(255)) + else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ #if defined(EVP_PKEY_X448) From 70a9e773be70b553ec44223af37b787bef9175e1 Mon Sep 17 00:00:00 2001 From: MkfsSion Date: Mon, 20 Oct 2025 16:07:01 +0800 Subject: [PATCH 4012/4321] openpgp: Fix retry counter of encryption PIN in SC_PIN_CMD_GET_INFO emulation for card supporting OpenPGP card spec v2.0 and later The meaning of byte 6 of DO C4 has changed from the retry counter of the encryption PIN (CHV2) to that of resetting code since OpenPGP card spec v2.0, and PW1 now serves as both the signature and encryption PIN. Map PIN reference from 82 to 81 to correct retry counter of encryption PIN for these cards. --- src/libopensc/card-openpgp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 1c32335198..0dde7903f5 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2468,6 +2468,14 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) LOG_TEST_RET(card->ctx, SC_ERROR_OBJECT_NOT_VALID, "CHV status bytes have unexpected length"); + /* The definition of fields of DO C4 changed between OpenPGP + * card specification v1.1 and v2.0. There is no longer a separate + * CHV2 retry counter but only one retry counter for both PW1 mode 1 + * and mode 2 at byte 5 (count from 1) of the DO. + */ + if (priv->bcd_version >= OPENPGP_CARD_2_0 && data->pin_reference == 0x82) + data->pin_reference = 0x81; + data->pin1.tries_left = c4data[3 + (data->pin_reference & 0x0F)]; data->pin1.max_tries = 3; data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; From 1ed039298bab35ede7e801f479434dfa031827c5 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 30 Sep 2025 11:06:08 +0300 Subject: [PATCH 4013/4321] Check if PIN is locked and hint CKF_USER_PIN_TO_BE_CHANGED Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2025.c | 24 ++++++++++++------------ src/libopensc/opensc.h | 3 ++- src/pkcs11/framework-pkcs15.c | 7 +++++-- src/pkcs15init/pkcs15-lib.c | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libopensc/card-esteid2025.c b/src/libopensc/card-esteid2025.c index 0b3d53b05f..ae8e6cb467 100644 --- a/src/libopensc/card-esteid2025.c +++ b/src/libopensc/card-esteid2025.c @@ -157,9 +157,9 @@ esteid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *ou } static int -esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) +esteid_get_pin_info(sc_card_t *card, struct sc_pin_cmd_data *data) { - const u8 get_pin_info[] = {0xA0, 0x03, 0x83, 0x01, pin_reference}; + const u8 get_pin_info[] = {0xA0, 0x03, 0x83, 0x01, data->pin_reference}; struct sc_apdu apdu; u8 apdu_resp[SC_MAX_APDU_RESP_SIZE]; size_t taglen; @@ -173,26 +173,26 @@ esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) const u8 *tag = sc_asn1_find_tag(card->ctx, apdu_resp + 2, apdu.resplen - 2, 0xDF21, &taglen); if (tag == NULL || taglen == 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - return tag[0]; + data->pin1.tries_left = tag[0]; + data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks + data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; + tag += taglen; + tag = sc_asn1_find_tag(card->ctx, tag, apdu.resplen - (tag - apdu_resp), 0xDF2F, &taglen); + if (tag != NULL && taglen == 1 && tag[0] == 0x00) { + data->pin1.logged_in |= SC_PIN_STATE_NEEDS_CHANGE; + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { - int r; LOG_FUNC_CALLED(card->ctx); sc_log(card->ctx, "PIN CMD is %d", data->cmd); if (data->cmd == SC_PIN_CMD_GET_INFO) { sc_log(card->ctx, "SC_PIN_CMD_GET_INFO for %d", data->pin_reference); - r = esteid_get_pin_remaining_tries(card, data->pin_reference); - LOG_TEST_RET(card->ctx, r, "GET DATA(pin info) failed"); - - data->pin1.tries_left = r; - data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks - data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, esteid_get_pin_info(card, data)); } - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 26344c54a9..c54edd493a 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -433,10 +433,11 @@ typedef struct sc_reader { #define SC_PIN_ENCODING_BCD 1 #define SC_PIN_ENCODING_GLP 2 /* Global Platform - Card Specification v2.0.1 */ -/** Values for sc_pin_cmd_pin.logged_in */ +/** Values for sc_pin_cmd_pin.logged_in, can be bitmapped together */ #define SC_PIN_STATE_UNKNOWN -1 #define SC_PIN_STATE_LOGGED_OUT 0 #define SC_PIN_STATE_LOGGED_IN 1 +#define SC_PIN_STATE_NEEDS_CHANGE 2 /* A card driver receives the sc_pin_cmd_data and sc_pin_cmd_pin structures filled in by the * caller, with the exception of the fields returned by the driver for SC_PIN_CMD_GET_INFO. diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9b6b067e7f..a01a7f60e3 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -575,7 +575,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) goto out; } /* User PIN flags are cleared before re-calculation */ - slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED); + slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_LOCKED | CKF_USER_PIN_TO_BE_CHANGED); auth = slot_data_auth(slot->fw_data); sc_log(context, "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, @@ -602,6 +602,9 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) else if (pin_info->max_tries > 1 && pin_info->tries_left < pin_info->max_tries) slot->token_info.flags |= CKF_USER_PIN_COUNT_LOW; } + if (pin_info->logged_in & SC_PIN_STATE_NEEDS_CHANGE) { + slot->token_info.flags |= CKF_USER_PIN_TO_BE_CHANGED; + } } memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO)); @@ -1401,7 +1404,7 @@ int slot_get_logged_in_state(struct sc_pkcs11_slot *slot) if (!pin_info) goto out; sc_pkcs15_get_pin_info(p15card, pin_obj); - logged_in = pin_info->logged_in; + logged_in = pin_info->logged_in & ~SC_PIN_STATE_NEEDS_CHANGE; out: return logged_in; } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 8bdc0d668d..202db2daf4 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4026,7 +4026,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p /* update local copy of auth info */ memcpy(&auth_info, pin_obj->data, sizeof(auth_info)); - if (r == SC_SUCCESS && auth_info.logged_in == SC_PIN_STATE_LOGGED_IN) + if (r == SC_SUCCESS && auth_info.logged_in & SC_PIN_STATE_LOGGED_IN) LOG_FUNC_RETURN(ctx, r); } From bb0fa34666ae4937ab2f01ab33de1f8f6b4640a6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 09:52:25 +0100 Subject: [PATCH 4014/4321] oberthur: Avoid buffer overflow Thanks 7erryX for the report! Fixes: #3511 Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-oberthur.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index dc7e71aa48..a97e460a57 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -612,6 +612,11 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported"); + if (key_info->path.len < 4) { + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, + "The path needs to be at least four bytes long"); + } + path = key_info->path; path.len -= 2; @@ -721,8 +726,10 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); - if (key_info->path.len < 2) - LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "The path needs to be at least to bytes long"); + if (key_info->path.len < 2) { + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, + "The path needs to be at least two bytes long"); + } sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); /* Here, the path of private key file should be defined. From e151e2f39d8ffdad7506ed36250635a925421903 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 13:22:38 +0100 Subject: [PATCH 4015/4321] mcrd: Avoid memory leak on error condition Thanks oss-fuzz https://issues.oss-fuzz.com//issues/457247630 Signed-off-by: Jakub Jelen --- src/libopensc/card-mcrd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 31bf1e0402..76da89934b 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -586,11 +586,11 @@ do_select(sc_card_t * card, u8 kind, } if (p2 == 0x04 && apdu.resplen > 2 && apdu.resp[0] == 0x62) { + if (apdu.resp[1] > apdu.resplen - 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); *file = sc_file_new(); if (!*file) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - if (apdu.resp[1] > apdu.resplen - 2) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } From 1243e53ebdc48521bb6d462acf1a1ed728cadbe2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 13:23:18 +0100 Subject: [PATCH 4016/4321] mcrd: Rewrite conditions for readability Signed-off-by: Jakub Jelen --- src/libopensc/card-mcrd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 76da89934b..4790caa182 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -658,10 +658,10 @@ select_down(sc_card_t * card, /* first try to select an EF and retry an DF on error. */ r = select_part(card, MCRD_SEL_EF, *pathptr, file); - if (!r) + if (r == SC_SUCCESS) found_ef = 1; } - if (r) + if (r != SC_SUCCESS) r = select_part(card, MCRD_SEL_DF, *pathptr, pathlen == 1 ? file : NULL); LOG_TEST_RET(card->ctx, r, "unable to select DF"); From a20b91adc2fc66785c0df98abc8ef456c0eaab9d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 14:13:59 +0100 Subject: [PATCH 4017/4321] compacttlv: Fix possible buffer overrun Fixes: GHSA-72x5-fwjx-2459 Signed-off-by: Jakub Jelen --- src/libopensc/sc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index ec03af0b80..ab5d3d0f5a 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -1062,13 +1062,15 @@ const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outl size_t expected_len = tag & 0x0F; for (idx = 0; idx < len; idx++) { - if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len && - (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) { + u8 ctag = buf[idx] & 0xF0; + size_t ctag_len = buf[idx] & 0x0F; + if (ctag == plain_tag && idx + ctag_len < len && + (expected_len == 0 || expected_len == ctag_len)) { if (outlen != NULL) - *outlen = buf[idx] & 0x0F; + *outlen = ctag_len; return buf + (idx + 1); } - idx += (buf[idx] & 0x0F); + idx += ctag_len; } } return NULL; From 24fc0b618111539b40ca5f7c2d0bd34d79fc6ebb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 22 Nov 2025 22:06:22 +0100 Subject: [PATCH 4018/4321] Fix indentation of sc_compacttlv_find_tag() --- src/libopensc/sc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index ab5d3d0f5a..075259be79 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -1061,7 +1061,7 @@ const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outl u8 plain_tag = tag & 0xF0; size_t expected_len = tag & 0x0F; - for (idx = 0; idx < len; idx++) { + for (idx = 0; idx < len; idx++) { u8 ctag = buf[idx] & 0xF0; size_t ctag_len = buf[idx] & 0x0F; if (ctag == plain_tag && idx + ctag_len < len && @@ -1071,8 +1071,8 @@ const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outl return buf + (idx + 1); } idx += ctag_len; - } - } + } + } return NULL; } From 44bd944e1871dc6a9f11eb95682451e904d7312f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 16 Sep 2024 15:22:34 +0300 Subject: [PATCH 4019/4321] Remove obsolete FinEID cards Since 2017-01-01 issued cards are Gemalto MultiApp Signed-off-by: Raul Metsma --- src/libopensc/card-setcos.c | 80 ++++++++++--------------------------- src/libopensc/cards.h | 3 -- 2 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index d471bc9b46..0ebe7c34f7 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -31,36 +31,16 @@ #include "asn1.h" #include "cardctl.h" -#define _FINEID_BROKEN_SELECT_FLAG 1 - static const struct sc_atr_table setcos_atrs[] = { - /* some Nokia branded SC */ - { "3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_GENERIC, 0, NULL }, - /* RSA SecurID 3100 */ - { "3B:9F:94:40:1E:00:67:16:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_PKI, 0, NULL }, - - /* FINEID 1016 (SetCOS 4.3.1B3/PKCS#15, VRK) */ - { "3b:9f:94:40:1e:00:67:00:43:46:49:53:45:10:52:66:ff:81:90:00", "ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff", NULL, SC_CARD_TYPE_SETCOS_FINEID, SC_CARD_FLAG_RNG, NULL }, - /* FINEID 2032 (EIDApplet/7816-15, VRK test) */ - { "3b:6b:00:ff:80:62:00:a2:56:46:69:6e:45:49:44", "ff:ff:00:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff", NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - /* FINEID 2132 (EIDApplet/7816-15, 3rdparty test) */ - { "3b:64:00:ff:80:62:00:a2", "ff:ff:00:ff:ff:ff:00:ff", NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - /* FINEID 2064 (EIDApplet/7816-15, VRK) */ - { "3b:7b:00:00:00:80:62:00:51:56:46:69:6e:45:49:44", "ff:ff:00:ff:ff:ff:ff:f0:ff:ff:ff:ff:ff:ff:ff:ff", NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - /* FINEID 2164 (EIDApplet/7816-15, 3rdparty) */ - { "3b:64:00:00:80:62:00:51", "ff:ff:ff:ff:ff:ff:f0:ff", NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - /* FINEID 2264 (EIDApplet/7816-15, OPK/EMV/AVANT) */ - { "3b:6e:00:00:00:62:00:00:57:41:56:41:4e:54:10:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - { "3b:7b:94:00:00:80:62:11:51:56:46:69:6e:45:49:44", NULL, NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, 0, NULL }, - /* FINEID cards 1.3.2011 with Samsung chips (round connector) that supports 2048 bit keys. */ - { "3b:7b:94:00:00:80:62:12:51:56:46:69:6e:45:49:44", NULL, NULL, SC_CARD_TYPE_SETCOS_FINEID_V2_2048, 0, NULL }, - /* FINEID card for organisations, chip unknown. */ - { "3b:7b:18:00:00:80:62:01:54:56:46:69:6e:45:49:44", NULL, NULL, SC_CARD_TYPE_SETCOS_FINEID_V2, _FINEID_BROKEN_SELECT_FLAG, NULL }, - /* Swedish NIDEL card */ - { "3b:9f:94:80:1f:c3:00:68:10:44:05:01:46:49:53:45:31:c8:07:90:00:18", NULL, NULL, SC_CARD_TYPE_SETCOS_NIDEL, 0, NULL }, - /* Setcos 4.4.1 */ - { "3b:9f:94:80:1f:c3:00:68:11:44:05:01:46:49:53:45:31:c8:00:00:00:00", "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00", NULL, SC_CARD_TYPE_SETCOS_44, 0, NULL }, - { NULL, NULL, NULL, 0, 0, NULL } + /* some Nokia branded SC */ + {"3B:1F:11:00:67:80:42:46:49:53:45:10:52:66:FF:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_GENERIC, 0, NULL}, + /* RSA SecurID 3100 */ + {"3B:9F:94:40:1E:00:67:16:43:46:49:53:45:10:52:66:FF:81:90:00", NULL, NULL, SC_CARD_TYPE_SETCOS_PKI, 0, NULL}, + /* Swedish NIDEL card */ + {"3b:9f:94:80:1f:c3:00:68:10:44:05:01:46:49:53:45:31:c8:07:90:00:18", NULL, NULL, SC_CARD_TYPE_SETCOS_NIDEL, 0, NULL}, + /* Setcos 4.4.1 */ + {"3b:9f:94:80:1f:c3:00:68:11:44:05:01:46:49:53:45:31:c8:00:00:00:00", "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00", NULL, SC_CARD_TYPE_SETCOS_44, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} }; #define SETCOS_IS_EID_APPLET(card) ((card)->type == SC_CARD_TYPE_SETCOS_EID_V2_0 || (card)->type == SC_CARD_TYPE_SETCOS_EID_V2_1) @@ -107,11 +87,6 @@ static int setcos_match_card(sc_card_t *card) i = _sc_match_atr(card, setcos_atrs, &card->type); if (i < 0) { - /* Unknown card, but has the FinEID application for sure */ - if (match_hist_bytes(card, "FinEID", 0)) { - card->type = SC_CARD_TYPE_SETCOS_FINEID_V2_2048; - return 1; - } if (match_hist_bytes(card, "FISE", 0)) { card->type = SC_CARD_TYPE_SETCOS_GENERIC; return 1; @@ -164,8 +139,6 @@ static int setcos_init(sc_card_t *card) } switch (card->type) { - case SC_CARD_TYPE_SETCOS_FINEID: - case SC_CARD_TYPE_SETCOS_FINEID_V2_2048: case SC_CARD_TYPE_SETCOS_NIDEL: card->cla = 0x00; select_pkcs15_app(card); @@ -189,18 +162,15 @@ static int setcos_init(sc_card_t *card) } switch (card->type) { - case SC_CARD_TYPE_SETCOS_PKI: - case SC_CARD_TYPE_SETCOS_FINEID_V2_2048: - { - unsigned long flags; + case SC_CARD_TYPE_SETCOS_PKI: { + unsigned long flags; - flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; - flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; + flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; - _sc_card_add_rsa_alg(card, 1024, flags, 0); - _sc_card_add_rsa_alg(card, 2048, flags, 0); - } - break; + _sc_card_add_rsa_alg(card, 1024, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + } break; case SC_CARD_TYPE_SETCOS_44: case SC_CARD_TYPE_SETCOS_NIDEL: case SC_CARD_TYPE_SETCOS_EID_V2_0: @@ -593,11 +563,11 @@ static int setcos_set_security_env2(sc_card_t *card, break; case SC_SEC_OPERATION_SIGN: /* Should be 0x41 */ - apdu.p1 = ((card->type == SC_CARD_TYPE_SETCOS_FINEID_V2) || - (card->type == SC_CARD_TYPE_SETCOS_FINEID_V2_2048) || - (card->type == SC_CARD_TYPE_SETCOS_44) || - (card->type == SC_CARD_TYPE_SETCOS_NIDEL) || - SETCOS_IS_EID_APPLET(card)) ? 0x41 : 0x81; + apdu.p1 = ((card->type == SC_CARD_TYPE_SETCOS_44) || + (card->type == SC_CARD_TYPE_SETCOS_NIDEL) || + SETCOS_IS_EID_APPLET(card)) + ? 0x41 + : 0x81; apdu.p2 = 0xB6; break; default: @@ -617,8 +587,7 @@ static int setcos_set_security_env2(sc_card_t *card, p += env->file_ref.len; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT && - !(card->type == SC_CARD_TYPE_SETCOS_NIDEL || - card->type == SC_CARD_TYPE_SETCOS_FINEID_V2_2048)) { + !(card->type == SC_CARD_TYPE_SETCOS_NIDEL)) { if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) *p++ = 0x83; else @@ -679,8 +648,6 @@ static int setcos_set_security_env(sc_card_t *card, } switch (card->type) { case SC_CARD_TYPE_SETCOS_PKI: - case SC_CARD_TYPE_SETCOS_FINEID: - case SC_CARD_TYPE_SETCOS_FINEID_V2_2048: case SC_CARD_TYPE_SETCOS_NIDEL: case SC_CARD_TYPE_SETCOS_44: case SC_CARD_TYPE_SETCOS_EID_V2_0: @@ -922,9 +889,6 @@ static int setcos_select_file(sc_card_t *card, int r; r = iso_ops->select_file(card, in_path, file); - /* Certain FINeID cards for organisations return 6A88 instead of 6A82 for missing files */ - if (card->flags & _FINEID_BROKEN_SELECT_FLAG && r == SC_ERROR_DATA_OBJECT_NOT_FOUND) - return SC_ERROR_FILE_NOT_FOUND; if (r) return r; if (file != NULL) { diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index ce61867f47..7b8c527e34 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -64,10 +64,7 @@ enum { SC_CARD_TYPE_SETCOS_BASE = 6000, SC_CARD_TYPE_SETCOS_GENERIC, SC_CARD_TYPE_SETCOS_PKI, - SC_CARD_TYPE_SETCOS_FINEID, - SC_CARD_TYPE_SETCOS_FINEID_V2, SC_CARD_TYPE_SETCOS_NIDEL, - SC_CARD_TYPE_SETCOS_FINEID_V2_2048, SC_CARD_TYPE_SETCOS_44 = 6100, SC_CARD_TYPE_SETCOS_EID_V2_0, SC_CARD_TYPE_SETCOS_EID_V2_1, From 1f8bd33ae89825bb0c488a0e169e27ed1c323cbc Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 20 Oct 2025 13:05:57 +0300 Subject: [PATCH 4020/4321] Add Latvian Cosmo 8.2 card support * Issued after 2022 Signed-off-by: Raul Metsma --- src/libopensc/card-esteid2018.c | 1 + src/libopensc/cards.h | 1 + src/libopensc/pkcs15-esteid2018.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index 2eb10ad2b8..ea3b8bbf87 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -42,6 +42,7 @@ */ static const struct sc_atr_table esteid_atrs[] = { {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:23:3f:53:65:49:44:0f:90:00:f1", NULL, "EstEID 2018", SC_CARD_TYPE_ESTEID_2018, 0, NULL}, + {"3b:db:96:00:80:b1:fe:45:1f:83:00:12:42:8f:53:65:49:44:0f:90:00:20", NULL, "Latvian eID 2018", SC_CARD_TYPE_LATEID_2018, 0, NULL}, {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:23:3f:54:65:49:44:32:0f:90:00:c3", NULL, "EstEID 2018 v2", SC_CARD_TYPE_ESTEID_2018_V2_2025, 0, NULL}, {"3b:dc:96:00:80:b1:fe:45:1f:83:00:12:42:8f:54:65:49:44:32:0f:90:00:12", NULL, "Latvian eID 2018 v2", SC_CARD_TYPE_LATEID_2018_V2_2025, 0, NULL}, {NULL, NULL, NULL, 0, 0, NULL} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 7b8c527e34..8405fba1a6 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -233,6 +233,7 @@ enum { SC_CARD_TYPE_ESTEID_2025, SC_CARD_TYPE_FINEID_2022, SC_CARD_TYPE_FINEID_2025, + SC_CARD_TYPE_LATEID_2018, /* Rutoken cards */ SC_CARD_TYPE_RUTOKENS = 36000, diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index f2baf17640..58e873d444 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -36,7 +36,8 @@ static int is_latvian_eid(sc_pkcs15_card_t *p15card) { - return p15card->card->type == SC_CARD_TYPE_LATEID_2018_V2_2025; + return p15card->card->type == SC_CARD_TYPE_LATEID_2018 || + p15card->card->type == SC_CARD_TYPE_LATEID_2018_V2_2025; } static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { From 0116667174060aaf609ff07daa99deeae1497e0e Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 20 Oct 2025 13:10:25 +0300 Subject: [PATCH 4021/4321] Add Latvian Cosmo 8.2 card support * Updated cards from RSA Signed-off-by: Raul Metsma --- src/libopensc/pkcs15-esteid2018.c | 43 ++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 58e873d444..0cddbe21a5 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -43,8 +43,8 @@ is_latvian_eid(sc_pkcs15_card_t *p15card) static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { sc_card_t *card = p15card->card; u8 buff[11]; - int r, i; - size_t field_length = 0, taglen; + int r, i, cert_slot = 0; + size_t field_length = 0, taglen, buflen; sc_path_t tmppath; /* Read documber number to be used as serial */ @@ -70,10 +70,45 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { p15card->tokeninfo->serial_number[taglen] = '\0'; p15card->tokeninfo->flags = SC_PKCS15_TOKEN_READONLY; + if (is_latvian_eid(p15card)) { + u8 *buf; + const u8 *ptr; + sc_pkcs15_object_t obj = {0}; + sc_pkcs15_cert_info_t *cert_info = NULL; + + if (!p15card->file_app) { + p15card->file_app = sc_file_new(); + } + if (!p15card->file_app) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + + sc_format_path("3F00adf1", &p15card->file_app->path); + sc_format_path("3F00adf17005", &tmppath); + r = sc_pkcs15_read_file(p15card, &tmppath, &buf, &buflen, 0); + LOG_TEST_GOTO_ERR(card->ctx, r, "Reading EF.CDF file failed"); + ptr = buf; + r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &buflen); + LOG_TEST_GOTO_ERR(card->ctx, r, "Decoding EF.CDF file failed"); + + cert_info = (struct sc_pkcs15_cert_info *)obj.data; + if (cert_info && cert_info->path.len > 0) { + cert_slot = cert_info->path.value[cert_info->path.len - 1] - 1; + } + + sc_pkcs15_free_cert_info(cert_info); + sc_file_free(p15card->file_app); + p15card->file_app = NULL; + free(buf); + } + /* add certificates */ for (i = 0; i < 2; i++) { static const char *esteid_cert_names[2] = {"Isikutuvastus", "Allkirjastamine"}; - static const char *esteid_cert_paths[2] = {"3f00:adf1:3401", "3f00:adf2:341f"}; + static const char *cert_paths[2][2] = { + {"3f00:adf1:3401", "3f00:adf2:341f"}, + {"3f00:adf1:3402", "3f00:adf2:341e"} + }; static const u8 esteid_cert_ids[2] = {1, 2}; struct sc_pkcs15_cert_info cert_info = { @@ -82,7 +117,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { struct sc_pkcs15_object cert_obj = {0}; strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label)); - sc_format_path(esteid_cert_paths[i], &cert_info.path); + sc_format_path(cert_paths[cert_slot][i], &cert_info.path); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not add cert oebjct"); From 11a7777bbf65694d51e310c6f39ba24ad0192da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 30 Jul 2025 10:47:28 +0200 Subject: [PATCH 4022/4321] Integrate open-source PKCS#11 v3.1 header file https://github.com/latchset/pkcs11-headers/ --- src/common/libpkcs11.c | 2 +- src/pkcs11/pkcs11-global.c | 6 +- src/pkcs11/pkcs11-spy.c | 6 +- src/pkcs11/pkcs11.h | 4152 +++++++++++--------- src/tests/p11test/p11test_case_interface.c | 20 +- 5 files changed, 2358 insertions(+), 1828 deletions(-) diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index 5ad0dd3e56..cc1fa22403 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -72,7 +72,7 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) CK_INTERFACE *interface = NULL; /* Get default PKCS #11 interface */ - rv = c_get_interface((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 0); + rv = c_get_interface((CK_UTF8CHAR_PTR)"PKCS 11", NULL, &interface, 0); if (rv == CKR_OK) { /* this is actually 3.0 function list, but it starts * with the same fields. Only for new functions, it diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index b72de8efe3..98d6ef55f8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -865,8 +865,8 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */ #define DEFAULT_INTERFACE 0 // clang-format off CK_INTERFACE interfaces[NUM_INTERFACES] = { - {"PKCS 11", (void *)&pkcs11_function_list_3_0, 0}, - {"PKCS 11", (void *)&pkcs11_function_list, 0} + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&pkcs11_function_list_3_0, 0}, + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&pkcs11_function_list, 0} }; // clang-format on @@ -923,7 +923,7 @@ CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, /* name of the interface */ CK_VERSION_PTR interface_version = (CK_VERSION_PTR)interfaces[i].pFunctionList; /* The interface name is not null here */ - if (strcmp((char *)pInterfaceName, interfaces[i].pInterfaceName) != 0) { + if (strcmp((char *)pInterfaceName, (char *)interfaces[i].pInterfaceName) != 0) { continue; } /* If version is not null, it must match */ diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 6b2a30ca05..e480c710fa 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -185,10 +185,10 @@ allocate_function_list(int v3) * if the V3 API is used, but the proxied module does not support V3 API */ #define NUM_INTERFACES 1 CK_INTERFACE compat_interfaces[NUM_INTERFACES] = { - {"PKCS 11", NULL, 0} + {(CK_UTF8CHAR_PTR)"PKCS 11", NULL, 0} }; -CK_INTERFACE spy_interface = {"PKCS 11", NULL, 0}; +CK_INTERFACE spy_interface = {(CK_UTF8CHAR_PTR)"PKCS 11", NULL, 0}; /* Inits the spy. If successful, po != NULL */ static CK_RV @@ -1638,7 +1638,7 @@ spy_interface_function_list(CK_INTERFACE_PTR pInterface, CK_INTERFACE_PTR_PTR re CK_VERSION *version; /* Do not touch unknown interfaces. We can not do anything with these */ - if (strcmp(pInterface->pInterfaceName, "PKCS 11") != 0) { + if (strcmp((char *)pInterface->pInterfaceName, "PKCS 11") != 0) { *retInterface = pInterface; return; } diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 5d26ce8c22..254809a86c 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -1,1937 +1,2467 @@ -/* pkcs11.h - Copyright 2006, 2007 g10 Code GmbH - Copyright 2006 Andreas Jellinghaus +#ifndef PKCS11_H +#define PKCS11_H 1 - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. +#if defined(__cplusplus) +extern "C" { +#endif - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. */ -/* Please submit changes back to the Scute project at - http://www.scute.org/ (or send them to marcus@g10code.com), so that - they can be picked up by other projects from there as well. */ +/* System dependencies. */ +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) -/* This file is a modified implementation of the PKCS #11 standard by - RSA Security Inc. It is mostly a drop-in replacement, with the - following change: +/* There is a matching pop below. */ +#pragma pack(push, cryptoki, 1) - This header file does not require any macro definitions by the user - (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros - for you (if useful, some are missing, let me know if you need - more). +#ifdef CRYPTOKI_EXPORTS +#define CK_SPEC __declspec(dllexport) +#else +#define CK_SPEC __declspec(dllimport) +#endif - There is an additional API available that does comply better to the - GNU coding standard. It can be switched on by defining - CRYPTOKI_GNU before including this header file. For this, the - following changes are made to the specification: +#else - All structure types are changed to a "struct ck_foo" where CK_FOO - is the type name in PKCS #11. +#define CK_SPEC - All non-structure types are changed to ck_foo_t where CK_FOO is the - lowercase version of the type name in PKCS #11. The basic types - (CK_ULONG et al.) are removed without substitute. +#endif - All members of structures are modified in the following way: Type - indication prefixes are removed, and underscore characters are - inserted before words. Then the result is lowercased. +/* Miscellaneous */ - Note that function names are still in the original case, as they - need for ABI compatibility. +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#endif - CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use - . +#define PKCS11_DEPRECATED - If CRYPTOKI_COMPAT is defined before including this header file, - then none of the API changes above take place, and the API is the - one defined by the PKCS #11 standard. */ +typedef long int CK_LONG; -#ifndef PKCS11_H -#define PKCS11_H 1 +/* This file is in the Public Domain */ -#if defined(__cplusplus) -extern "C" { -#endif +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 1 +#define CRYPTOKI_VERSION_AMENDMENT 0 +/* Basic types */ +typedef unsigned char CK_BBOOL; +typedef unsigned char CK_BYTE; +typedef unsigned char CK_CHAR; +typedef unsigned char CK_UTF8CHAR; +typedef unsigned long int CK_ULONG; -/* The version of cryptoki we implement. The revision is changed with - each modification of this file. If you do not use the "official" - version of this file, please consider deleting the revision macro - (you may use a macro with a different name to keep track of your - versions). */ -#define CRYPTOKI_VERSION_MAJOR 3 -#define CRYPTOKI_VERSION_MINOR 0 -#define CRYPTOKI_VERSION_REVISION 0 +typedef CK_BBOOL * CK_BBOOL_PTR; +typedef CK_BYTE * CK_BYTE_PTR; +typedef CK_CHAR * CK_CHAR_PTR; +typedef CK_UTF8CHAR * CK_UTF8CHAR_PTR; +typedef CK_ULONG * CK_ULONG_PTR; +/* Basic defines */ +#define NULL_PTR ((void *)0) +typedef void * CK_VOID_PTR; +typedef void ** CK_VOID_PTR_PTR; -/* Compatibility interface is default, unless CRYPTOKI_GNU is - given. */ -#ifndef CRYPTOKI_GNU -#ifndef CRYPTOKI_COMPAT -#define CRYPTOKI_COMPAT 1 -#endif +#define CK_EFFECTIVELY_INFINITE 0UL +#define CK_UNAVAILABLE_INFORMATION ~0UL +#define CK_INVALID_HANDLE 0UL +#define CK_TRUE 1 +#define CK_FALSE 0 + +/* CK_ types in alphabetical order */ +#define ULONGDEF(__name__) \ +typedef CK_ULONG __name__; \ +typedef __name__ * __name__ ## _PTR; + +ULONGDEF(CK_ATTRIBUTE_TYPE); +ULONGDEF(CK_CERTIFICATE_CATEGORY); +ULONGDEF(CK_CERTIFICATE_TYPE); +ULONGDEF(CK_EC_KDF_TYPE); +ULONGDEF(CK_EXTRACT_PARAMS); +ULONGDEF(CK_FLAGS); +ULONGDEF(CK_GENERATOR_FUNCTION); +ULONGDEF(CK_HSS_LEVELS); +ULONGDEF(CK_HW_FEATURE_TYPE); +ULONGDEF(CK_JAVA_MIDP_SECURITY_DOMAIN); +ULONGDEF(CK_KEY_TYPE); +ULONGDEF(CK_LMS_TYPE); +ULONGDEF(CK_LMOTS_TYPE); +ULONGDEF(CK_MAC_GENERAL_PARAMS); +ULONGDEF(CK_MECHANISM_TYPE); +ULONGDEF(CK_NOTIFICATION); +ULONGDEF(CK_OBJECT_CLASS); +ULONGDEF(CK_OBJECT_HANDLE); +ULONGDEF(CK_OTP_PARAM_TYPE); +ULONGDEF(CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE); +ULONGDEF(CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE); +ULONGDEF(CK_PRF_DATA_TYPE); +ULONGDEF(CK_PROFILE_ID); +ULONGDEF(CK_RC2_PARAMS); +ULONGDEF(CK_RSA_PKCS_MGF_TYPE); +ULONGDEF(CK_RSA_PKCS_OAEP_SOURCE_TYPE); +ULONGDEF(CK_RV); +ULONGDEF(CK_SESSION_HANDLE); +ULONGDEF(CK_SLOT_ID); +ULONGDEF(CK_SP800_108_DKM_LENGTH_METHOD); +ULONGDEF(CK_STATE); +ULONGDEF(CK_USER_TYPE); +ULONGDEF(CK_X2RATCHET_KDF_TYPE); +ULONGDEF(CK_X3DH_KDF_TYPE); +ULONGDEF(CK_X9_42_DH_KDF_TYPE); +ULONGDEF(CK_XEDDSA_HASH_TYPE); + +/* domain specific values and constants */ + +/* CK (certificate) */ +#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL +#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL +#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL +#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL + +/* CK (OTP) */ +#define CK_OTP_VALUE 0UL +#define CK_OTP_PIN 1UL +#define CK_OTP_CHALLENGE 2UL +#define CK_OTP_TIME 3UL +#define CK_OTP_COUNTER 4UL +#define CK_OTP_FLAGS 5UL +#define CK_OTP_OUTPUT_LENGTH 6UL +#define CK_OTP_OUTPUT_FORMAT 7UL + +/* CK (OTP format) */ +#define CK_OTP_FORMAT_DECIMAL 0UL +#define CK_OTP_FORMAT_HEXADECIMAL 1UL +#define CK_OTP_FORMAT_ALPHANUMERIC 2UL +#define CK_OTP_FORMAT_BINARY 3UL + +/* CK (OTP requirement) */ +#define CK_OTP_PARAM_IGNORED 0UL +#define CK_OTP_PARAM_OPTIONAL 1UL +#define CK_OTP_PARAM_MANDATORY 2UL + +/* CK (security) */ +#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL +#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL +#define CK_SECURITY_DOMAIN_OPERATOR 2UL +#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL + +/* CK (SP800 KDF) */ +#define CK_SP800_108_ITERATION_VARIABLE 0x00000001UL +#define CK_SP800_108_OPTIONAL_COUNTER 0x00000002UL +#define CK_SP800_108_COUNTER 0x00000002UL +#define CK_SP800_108_DKM_LENGTH 0x00000003UL +#define CK_SP800_108_BYTE_ARRAY 0x00000004UL + +/* CK (SP800 DKM) */ +#define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL +#define CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS 0x00000002UL + +/* CKA */ +#define CKA_CLASS 0x00000000UL +#define CKA_TOKEN 0x00000001UL +#define CKA_PRIVATE 0x00000002UL +#define CKA_LABEL 0x00000003UL +#define CKA_UNIQUE_ID 0x00000004UL +#define CKA_APPLICATION 0x00000010UL +#define CKA_VALUE 0x00000011UL +#define CKA_OBJECT_ID 0x00000012UL +#define CKA_CERTIFICATE_TYPE 0x00000080UL +#define CKA_ISSUER 0x00000081UL +#define CKA_SERIAL_NUMBER 0x00000082UL +#define CKA_AC_ISSUER 0x00000083UL +#define CKA_OWNER 0x00000084UL +#define CKA_ATTR_TYPES 0x00000085UL +#define CKA_TRUSTED 0x00000086UL +#define CKA_CERTIFICATE_CATEGORY 0x00000087UL +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL +#define CKA_URL 0x00000089UL +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL +#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL +#define CKA_CHECK_VALUE 0x00000090UL +#define CKA_KEY_TYPE 0x00000100UL +#define CKA_SUBJECT 0x00000101UL +#define CKA_ID 0x00000102UL +#define CKA_SENSITIVE 0x00000103UL +#define CKA_ENCRYPT 0x00000104UL +#define CKA_DECRYPT 0x00000105UL +#define CKA_WRAP 0x00000106UL +#define CKA_UNWRAP 0x00000107UL +#define CKA_SIGN 0x00000108UL +#define CKA_SIGN_RECOVER 0x00000109UL +#define CKA_VERIFY 0x0000010AUL +#define CKA_VERIFY_RECOVER 0x0000010BUL +#define CKA_DERIVE 0x0000010CUL +#define CKA_START_DATE 0x00000110UL +#define CKA_END_DATE 0x00000111UL +#define CKA_MODULUS 0x00000120UL +#define CKA_MODULUS_BITS 0x00000121UL +#define CKA_PUBLIC_EXPONENT 0x00000122UL +#define CKA_PRIVATE_EXPONENT 0x00000123UL +#define CKA_PRIME_1 0x00000124UL +#define CKA_PRIME_2 0x00000125UL +#define CKA_EXPONENT_1 0x00000126UL +#define CKA_EXPONENT_2 0x00000127UL +#define CKA_COEFFICIENT 0x00000128UL +#define CKA_PUBLIC_KEY_INFO 0x00000129UL +#define CKA_PRIME 0x00000130UL +#define CKA_SUBPRIME 0x00000131UL +#define CKA_BASE 0x00000132UL +#define CKA_PRIME_BITS 0x00000133UL +#define CKA_SUBPRIME_BITS 0x00000134UL +#define CKA_SUB_PRIME_BITS 0x00000134UL +#define CKA_VALUE_BITS 0x00000160UL +#define CKA_VALUE_LEN 0x00000161UL +#define CKA_EXTRACTABLE 0x00000162UL +#define CKA_LOCAL 0x00000163UL +#define CKA_NEVER_EXTRACTABLE 0x00000164UL +#define CKA_ALWAYS_SENSITIVE 0x00000165UL +#define CKA_KEY_GEN_MECHANISM 0x00000166UL +#define CKA_MODIFIABLE 0x00000170UL +#define CKA_COPYABLE 0x00000171UL +#define CKA_DESTROYABLE 0x00000172UL +#define CKA_EC_PARAMS 0x00000180UL +#define CKA_EC_POINT 0x00000181UL +#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL +#define CKA_WRAP_WITH_TRUSTED 0x00000210UL +#define CKA_OTP_FORMAT 0x00000220UL +#define CKA_OTP_LENGTH 0x00000221UL +#define CKA_OTP_TIME_INTERVAL 0x00000222UL +#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL +#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL +#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL +#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL +#define CKA_OTP_COUNTER 0x0000022EUL +#define CKA_OTP_TIME 0x0000022FUL +#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL +#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL +#define CKA_OTP_SERVICE_LOGO 0x0000022CUL +#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL +#define CKA_GOSTR3410_PARAMS 0x00000250UL +#define CKA_GOSTR3411_PARAMS 0x00000251UL +#define CKA_GOST28147_PARAMS 0x00000252UL +#define CKA_HW_FEATURE_TYPE 0x00000300UL +#define CKA_RESET_ON_INIT 0x00000301UL +#define CKA_HAS_RESET 0x00000302UL +#define CKA_PIXEL_X 0x00000400UL +#define CKA_PIXEL_Y 0x00000401UL +#define CKA_RESOLUTION 0x00000402UL +#define CKA_CHAR_ROWS 0x00000403UL +#define CKA_CHAR_COLUMNS 0x00000404UL +#define CKA_COLOR 0x00000405UL +#define CKA_BITS_PER_PIXEL 0x00000406UL +#define CKA_CHAR_SETS 0x00000480UL +#define CKA_ENCODING_METHODS 0x00000481UL +#define CKA_MIME_TYPES 0x00000482UL +#define CKA_MECHANISM_TYPE 0x00000500UL +#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL +#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL +#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL +#define CKA_PROFILE_ID 0x00000601UL +#define CKA_X2RATCHET_BAG 0x00000602UL +#define CKA_X2RATCHET_BAGSIZE 0x00000603UL +#define CKA_X2RATCHET_BOBS1STMSG 0x00000604UL +#define CKA_X2RATCHET_CKR 0x00000605UL +#define CKA_X2RATCHET_CKS 0x00000606UL +#define CKA_X2RATCHET_DHP 0x00000607UL +#define CKA_X2RATCHET_DHR 0x00000608UL +#define CKA_X2RATCHET_DHS 0x00000609UL +#define CKA_X2RATCHET_HKR 0x0000060AUL +#define CKA_X2RATCHET_HKS 0x0000060BUL +#define CKA_X2RATCHET_ISALICE 0x0000060CUL +#define CKA_X2RATCHET_NHKR 0x0000060DUL +#define CKA_X2RATCHET_NHKS 0x0000060EUL +#define CKA_X2RATCHET_NR 0x0000060FUL +#define CKA_X2RATCHET_NS 0x00000610UL +#define CKA_X2RATCHET_PNS 0x00000611UL +#define CKA_X2RATCHET_RK 0x00000612UL +#define CKA_HSS_LEVELS 0x00000617UL +#define CKA_HSS_LMS_TYPE 0x00000618UL +#define CKA_HSS_LMOTS_TYPE 0x00000619UL +#define CKA_HSS_LMS_TYPES 0x0000061AUL +#define CKA_HSS_LMOTS_TYPES 0x0000061BUL +#define CKA_HSS_KEYS_REMAINING 0x0000061CUL +#define CKA_VENDOR_DEFINED 0x80000000UL +/* Array attributes */ +#define CKA_WRAP_TEMPLATE 0x40000211UL +#define CKA_UNWRAP_TEMPLATE 0x40000212UL +#define CKA_DERIVE_TEMPLATE 0x40000213UL +#define CKA_ALLOWED_MECHANISMS 0x40000600UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKA_ECDSA_PARAMS 0x00000180UL +#define CKA_SECONDARY_AUTH 0x00000200UL +#define CKA_AUTH_PIN_FLAGS 0x00000201UL #endif -/* System dependencies. */ +/* CKC */ +#define CKC_X_509 0x00000000UL +#define CKC_X_509_ATTR_CERT 0x00000001UL +#define CKC_WTLS 0x00000002UL +#define CKC_VENDOR_DEFINED 0x80000000UL + +/* CKD */ +#define CKD_NULL 0x00000001UL +#define CKD_SHA1_KDF 0x00000002UL +#define CKD_SHA1_KDF_ASN1 0x00000003UL +#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL +#define CKD_SHA224_KDF 0x00000005UL +#define CKD_SHA256_KDF 0x00000006UL +#define CKD_SHA384_KDF 0x00000007UL +#define CKD_SHA512_KDF 0x00000008UL +#define CKD_CPDIVERSIFY_KDF 0x00000009UL +#define CKD_SHA3_224_KDF 0x0000000AUL +#define CKD_SHA3_256_KDF 0x0000000BUL +#define CKD_SHA3_384_KDF 0x0000000CUL +#define CKD_SHA3_512_KDF 0x0000000DUL +#define CKD_SHA1_KDF_SP800 0x0000000EUL +#define CKD_SHA224_KDF_SP800 0x0000000FUL +#define CKD_SHA256_KDF_SP800 0x00000010UL +#define CKD_SHA384_KDF_SP800 0x00000011UL +#define CKD_SHA512_KDF_SP800 0x00000012UL +#define CKD_SHA3_224_KDF_SP800 0x00000013UL +#define CKD_SHA3_256_KDF_SP800 0x00000014UL +#define CKD_SHA3_384_KDF_SP800 0x00000015UL +#define CKD_SHA3_512_KDF_SP800 0x00000016UL +#define CKD_BLAKE2B_160_KDF 0x00000017UL +#define CKD_BLAKE2B_256_KDF 0x00000018UL +#define CKD_BLAKE2B_384_KDF 0x00000019UL +#define CKD_BLAKE2B_512_KDF 0x0000001AUL + +/* CFK (array attributes) */ +#define CKF_ARRAY_ATTRIBUTE 0x40000000UL + +/* CKF (capabilities) */ +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL +#define CKF_OS_LOCKING_OK 0x00000002UL + +/* CKF (HKDF) */ +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + +/* CKF (interface) */ +#define CKF_INTERFACE_FORK_SAFE 0x00000001UL + +/* CKF (mechanism) */ +#define CKF_HW 0x00000001UL +#define CKF_MESSAGE_ENCRYPT 0x00000002UL +#define CKF_MESSAGE_DECRYPT 0x00000004UL +#define CKF_MESSAGE_SIGN 0x00000008UL +#define CKF_MESSAGE_VERIFY 0x00000010UL +#define CKF_MULTI_MESSAGE 0x00000020UL +#define CKF_MULTI_MESSGE 0x00000020UL +#define CKF_FIND_OBJECTS 0x00000040UL +#define CKF_ENCRYPT 0x00000100UL +#define CKF_DECRYPT 0x00000200UL +#define CKF_DIGEST 0x00000400UL +#define CKF_SIGN 0x00000800UL +#define CKF_SIGN_RECOVER 0x00001000UL +#define CKF_VERIFY 0x00002000UL +#define CKF_VERIFY_RECOVER 0x00004000UL +#define CKF_GENERATE 0x00008000UL +#define CKF_GENERATE_KEY_PAIR 0x00010000UL +#define CKF_WRAP 0x00020000UL +#define CKF_UNWRAP 0x00040000UL +#define CKF_DERIVE 0x00080000UL +#define CKF_EC_F_P 0x00100000UL +#define CKF_EC_F_2M 0x00200000UL +#define CKF_EC_ECPARAMETERS 0x00400000UL +#define CKF_EC_OID 0x00800000UL +#define CKF_EC_UNCOMPRESS 0x01000000UL +#define CKF_EC_COMPRESS 0x02000000UL +#define CKF_EC_CURVENAME 0x04000000UL +#define CKF_EXTENSION 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKF_EC_NAMEDCURVE 0x00800000U +#endif -#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) +/* CKF (message) */ +#define CKF_END_OF_MESSAGE 0x00000001UL + +/* CKF (OTP) */ +#define CKF_NEXT_OTP 0x00000001UL +#define CKF_EXCLUDE_TIME 0x00000002UL +#define CKF_EXCLUDE_COUNTER 0x00000004UL +#define CKF_EXCLUDE_CHALLENGE 0x00000008UL +#define CKF_EXCLUDE_PIN 0x00000010UL +#define CKF_USER_FRIENDLY_OTP 0x00000020UL + +/* CKF (parameters to functions) */ +#define CKF_DONT_BLOCK 1 + +/* CKF (session) */ +#define CKF_RW_SESSION 0x00000002UL +#define CKF_SERIAL_SESSION 0x00000004UL + +/* CFK (slot) */ +#define CKF_TOKEN_PRESENT 0x00000001UL +#define CKF_REMOVABLE_DEVICE 0x00000002UL +#define CKF_HW_SLOT 0x00000004UL + +/* CKF (token) */ +#define CKF_RNG 0x00000001UL +#define CKF_WRITE_PROTECTED 0x00000002UL +#define CKF_LOGIN_REQUIRED 0x00000004UL +#define CKF_USER_PIN_INITIALIZED 0x00000008UL +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL +#define CKF_CLOCK_ON_TOKEN 0x00000040UL +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL +#define CKF_TOKEN_INITIALIZED 0x00000400UL +#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL +#define CKF_USER_PIN_COUNT_LOW 0x00010000UL +#define CKF_USER_PIN_FINAL_TRY 0x00020000UL +#define CKF_USER_PIN_LOCKED 0x00040000UL +#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL +#define CKF_SO_PIN_COUNT_LOW 0x00100000UL +#define CKF_SO_PIN_FINAL_TRY 0x00200000UL +#define CKF_SO_PIN_LOCKED 0x00400000UL +#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL +#define CKF_ERROR_STATE 0x01000000UL -/* There is a matching pop below. */ -#pragma pack(push, cryptoki, 1) +/* CKG (GCM) */ +#define CKG_NO_GENERATE 0x00000000UL +#define CKG_GENERATE 0x00000001UL +#define CKG_GENERATE_COUNTER 0x00000002UL +#define CKG_GENERATE_RANDOM 0x00000003UL +#define CKG_GENERATE_COUNTER_XOR 0x00000004UL + +/* CKG (MFG) */ +#define CKG_MGF1_SHA1 0x00000001UL +#define CKG_MGF1_SHA256 0x00000002UL +#define CKG_MGF1_SHA384 0x00000003UL +#define CKG_MGF1_SHA512 0x00000004UL +#define CKG_MGF1_SHA224 0x00000005UL +#define CKG_MGF1_SHA3_224 0x00000006UL +#define CKG_MGF1_SHA3_256 0x00000007UL +#define CKG_MGF1_SHA3_384 0x00000008UL +#define CKG_MGF1_SHA3_512 0x00000009UL + +/* CKH */ +#define CKH_MONOTONIC_COUNTER 0x00000001UL +#define CKH_CLOCK 0x00000002UL +#define CKH_USER_INTERFACE 0x00000003UL +#define CKH_VENDOR_DEFINED 0x80000000UL + +/* CKK */ +#define CKK_RSA 0x00000000UL +#define CKK_DSA 0x00000001UL +#define CKK_DH 0x00000002UL +#define CKK_EC 0x00000003UL +#define CKK_X9_42_DH 0x00000004UL +#define CKK_KEA 0x00000005UL +#define CKK_GENERIC_SECRET 0x00000010UL +#define CKK_RC2 0x00000011UL +#define CKK_RC4 0x00000012UL +#define CKK_DES 0x00000013UL +#define CKK_DES2 0x00000014UL +#define CKK_DES3 0x00000015UL +#define CKK_CAST 0x00000016UL +#define CKK_CAST3 0x00000017UL +#define CKK_CAST128 0x00000018UL +#define CKK_RC5 0x00000019UL +#define CKK_IDEA 0x0000001AUL +#define CKK_SKIPJACK 0x0000001BUL +#define CKK_BATON 0x0000001CUL +#define CKK_JUNIPER 0x0000001DUL +#define CKK_CDMF 0x0000001EUL +#define CKK_AES 0x0000001FUL +#define CKK_BLOWFISH 0x00000020UL +#define CKK_TWOFISH 0x00000021UL +#define CKK_SECURID 0x00000022UL +#define CKK_HOTP 0x00000023UL +#define CKK_ACTI 0x00000024UL +#define CKK_CAMELLIA 0x00000025UL +#define CKK_ARIA 0x00000026UL +#define CKK_MD5_HMAC 0x00000027UL +#define CKK_SHA_1_HMAC 0x00000028UL +#define CKK_RIPEMD128_HMAC 0x00000029UL +#define CKK_RIPEMD160_HMAC 0x0000002AUL +#define CKK_SHA256_HMAC 0x0000002BUL +#define CKK_SHA384_HMAC 0x0000002CUL +#define CKK_SHA512_HMAC 0x0000002DUL +#define CKK_SHA224_HMAC 0x0000002EUL +#define CKK_SEED 0x0000002FUL +#define CKK_GOSTR3410 0x00000030UL +#define CKK_GOSTR3411 0x00000031UL +#define CKK_GOST28147 0x00000032UL +#define CKK_CHACHA20 0x00000033UL +#define CKK_POLY1305 0x00000034UL +#define CKK_AES_XTS 0x00000035UL +#define CKK_SHA3_224_HMAC 0x00000036UL +#define CKK_SHA3_256_HMAC 0x00000037UL +#define CKK_SHA3_384_HMAC 0x00000038UL +#define CKK_SHA3_512_HMAC 0x00000039UL +#define CKK_BLAKE2B_160_HMAC 0x0000003AUL +#define CKK_BLAKE2B_256_HMAC 0x0000003BUL +#define CKK_BLAKE2B_384_HMAC 0x0000003CUL +#define CKK_BLAKE2B_512_HMAC 0x0000003DUL +#define CKK_SALSA20 0x0000003EUL +#define CKK_X2RATCHET 0x0000003FUL +#define CKK_EC_EDWARDS 0x00000040UL +#define CKK_EC_MONTGOMERY 0x00000041UL +#define CKK_HKDF 0x00000042UL +#define CKK_SHA512_224_HMAC 0x00000043UL +#define CKK_SHA512_256_HMAC 0x00000044UL +#define CKK_SHA512_T_HMAC 0x00000045UL +#define CKK_HSS 0x00000046UL +#define CKK_VENDOR_DEFINED 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKK_ECDSA 0x00000003UL +#define CKK_CAST5 0x00000018UL +#endif -#ifdef CRYPTOKI_EXPORTS -#define CK_SPEC __declspec(dllexport) -#else -#define CK_SPEC __declspec(dllimport) +/* CKM */ +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL +#define CKM_RSA_PKCS 0x00000001UL +#define CKM_RSA_9796 0x00000002UL +#define CKM_RSA_X_509 0x00000003UL +#define CKM_MD2_RSA_PKCS 0x00000004UL +#define CKM_MD5_RSA_PKCS 0x00000005UL +#define CKM_SHA1_RSA_PKCS 0x00000006UL +#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL +#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL +#define CKM_RSA_PKCS_OAEP 0x00000009UL +#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL +#define CKM_RSA_X9_31 0x0000000BUL +#define CKM_SHA1_RSA_X9_31 0x0000000CUL +#define CKM_RSA_PKCS_PSS 0x0000000DUL +#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL +#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL +#define CKM_DSA 0x00000011UL +#define CKM_DSA_SHA1 0x00000012UL +#define CKM_DSA_SHA224 0x00000013UL +#define CKM_DSA_SHA256 0x00000014UL +#define CKM_DSA_SHA384 0x00000015UL +#define CKM_DSA_SHA512 0x00000016UL +#define CKM_DSA_SHA3_224 0x00000018UL +#define CKM_DSA_SHA3_256 0x00000019UL +#define CKM_DSA_SHA3_384 0x0000001AUL +#define CKM_DSA_SHA3_512 0x0000001BUL +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL +#define CKM_DH_PKCS_DERIVE 0x00000021UL +#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL +#define CKM_X9_42_DH_DERIVE 0x00000031UL +#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL +#define CKM_X9_42_MQV_DERIVE 0x00000033UL +#define CKM_SHA256_RSA_PKCS 0x00000040UL +#define CKM_SHA384_RSA_PKCS 0x00000041UL +#define CKM_SHA512_RSA_PKCS 0x00000042UL +#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL +#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL +#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL +#define CKM_SHA224_RSA_PKCS 0x00000046UL +#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL +#define CKM_SHA512_224 0x00000048UL +#define CKM_SHA512_224_HMAC 0x00000049UL +#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL +#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL +#define CKM_SHA512_256 0x0000004CUL +#define CKM_SHA512_256_HMAC 0x0000004DUL +#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL +#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL +#define CKM_SHA512_T 0x00000050UL +#define CKM_SHA512_T_HMAC 0x00000051UL +#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL +#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL +#define CKM_SHA3_256_RSA_PKCS 0x00000060UL +#define CKM_SHA3_384_RSA_PKCS 0x00000061UL +#define CKM_SHA3_512_RSA_PKCS 0x00000062UL +#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL +#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL +#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL +#define CKM_SHA3_224_RSA_PKCS 0x00000066UL +#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL +#define CKM_RC2_KEY_GEN 0x00000100UL +#define CKM_RC2_ECB 0x00000101UL +#define CKM_RC2_CBC 0x00000102UL +#define CKM_RC2_MAC 0x00000103UL +#define CKM_RC2_MAC_GENERAL 0x00000104UL +#define CKM_RC2_CBC_PAD 0x00000105UL +#define CKM_RC4_KEY_GEN 0x00000110UL +#define CKM_RC4 0x00000111UL +#define CKM_DES_KEY_GEN 0x00000120UL +#define CKM_DES_ECB 0x00000121UL +#define CKM_DES_CBC 0x00000122UL +#define CKM_DES_MAC 0x00000123UL +#define CKM_DES_MAC_GENERAL 0x00000124UL +#define CKM_DES_CBC_PAD 0x00000125UL +#define CKM_DES2_KEY_GEN 0x00000130UL +#define CKM_DES3_KEY_GEN 0x00000131UL +#define CKM_DES3_ECB 0x00000132UL +#define CKM_DES3_CBC 0x00000133UL +#define CKM_DES3_MAC 0x00000134UL +#define CKM_DES3_MAC_GENERAL 0x00000135UL +#define CKM_DES3_CBC_PAD 0x00000136UL +#define CKM_DES3_CMAC_GENERAL 0x00000137UL +#define CKM_DES3_CMAC 0x00000138UL +#define CKM_CDMF_KEY_GEN 0x00000140UL +#define CKM_CDMF_ECB 0x00000141UL +#define CKM_CDMF_CBC 0x00000142UL +#define CKM_CDMF_MAC 0x00000143UL +#define CKM_CDMF_MAC_GENERAL 0x00000144UL +#define CKM_CDMF_CBC_PAD 0x00000145UL +#define CKM_DES_OFB64 0x00000150UL +#define CKM_DES_OFB8 0x00000151UL +#define CKM_DES_CFB64 0x00000152UL +#define CKM_DES_CFB8 0x00000153UL +#define CKM_MD2 0x00000200UL +#define CKM_MD2_HMAC 0x00000201UL +#define CKM_MD2_HMAC_GENERAL 0x00000202UL +#define CKM_MD5 0x00000210UL +#define CKM_MD5_HMAC 0x00000211UL +#define CKM_MD5_HMAC_GENERAL 0x00000212UL +#define CKM_SHA_1 0x00000220UL +#define CKM_SHA_1_HMAC 0x00000221UL +#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL +#define CKM_RIPEMD128 0x00000230UL +#define CKM_RIPEMD128_HMAC 0x00000231UL +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL +#define CKM_RIPEMD160 0x00000240UL +#define CKM_RIPEMD160_HMAC 0x00000241UL +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL +#define CKM_SHA256 0x00000250UL +#define CKM_SHA256_HMAC 0x00000251UL +#define CKM_SHA256_HMAC_GENERAL 0x00000252UL +#define CKM_SHA224 0x00000255UL +#define CKM_SHA224_HMAC 0x00000256UL +#define CKM_SHA224_HMAC_GENERAL 0x00000257UL +#define CKM_SHA384 0x00000260UL +#define CKM_SHA384_HMAC 0x00000261UL +#define CKM_SHA384_HMAC_GENERAL 0x00000262UL +#define CKM_SHA512 0x00000270UL +#define CKM_SHA512_HMAC 0x00000271UL +#define CKM_SHA512_HMAC_GENERAL 0x00000272UL +#define CKM_SECURID_KEY_GEN 0x00000280UL +#define CKM_SECURID 0x00000282UL +#define CKM_HOTP_KEY_GEN 0x00000290UL +#define CKM_HOTP 0x00000291UL +#define CKM_ACTI 0x000002A0UL +#define CKM_ACTI_KEY_GEN 0x000002A1UL +#define CKM_SHA3_256 0x000002B0UL +#define CKM_SHA3_256_HMAC 0x000002B1UL +#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL +#define CKM_SHA3_256_KEY_GEN 0x000002B3UL +#define CKM_SHA3_224 0x000002B5UL +#define CKM_SHA3_224_HMAC 0x000002B6UL +#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL +#define CKM_SHA3_224_KEY_GEN 0x000002B8UL +#define CKM_SHA3_384 0x000002C0UL +#define CKM_SHA3_384_HMAC 0x000002C1UL +#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL +#define CKM_SHA3_384_KEY_GEN 0x000002C3UL +#define CKM_SHA3_512 0x000002D0UL +#define CKM_SHA3_512_HMAC 0x000002D1UL +#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL +#define CKM_SHA3_512_KEY_GEN 0x000002D3UL +#define CKM_CAST_KEY_GEN 0x00000300UL +#define CKM_CAST_ECB 0x00000301UL +#define CKM_CAST_CBC 0x00000302UL +#define CKM_CAST_MAC 0x00000303UL +#define CKM_CAST_MAC_GENERAL 0x00000304UL +#define CKM_CAST_CBC_PAD 0x00000305UL +#define CKM_CAST3_KEY_GEN 0x00000310UL +#define CKM_CAST3_ECB 0x00000311UL +#define CKM_CAST3_CBC 0x00000312UL +#define CKM_CAST3_MAC 0x00000313UL +#define CKM_CAST3_MAC_GENERAL 0x00000314UL +#define CKM_CAST3_CBC_PAD 0x00000315UL +#define CKM_CAST128_KEY_GEN 0x00000320UL +#define CKM_CAST5_ECB 0x00000321UL +#define CKM_CAST128_ECB 0x00000321UL +#define CKM_CAST128_MAC 0x00000323UL +#define CKM_CAST128_CBC 0x00000322UL +#define CKM_CAST128_MAC_GENERAL 0x00000324UL +#define CKM_CAST128_CBC_PAD 0x00000325UL +#define CKM_RC5_KEY_GEN 0x00000330UL +#define CKM_RC5_ECB 0x00000331UL +#define CKM_RC5_CBC 0x00000332UL +#define CKM_RC5_MAC 0x00000333UL +#define CKM_RC5_MAC_GENERAL 0x00000334UL +#define CKM_RC5_CBC_PAD 0x00000335UL +#define CKM_IDEA_KEY_GEN 0x00000340UL +#define CKM_IDEA_ECB 0x00000341UL +#define CKM_IDEA_CBC 0x00000342UL +#define CKM_IDEA_MAC 0x00000343UL +#define CKM_IDEA_MAC_GENERAL 0x00000344UL +#define CKM_IDEA_CBC_PAD 0x00000345UL +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL +#define CKM_XOR_BASE_AND_DATA 0x00000364UL +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL +#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL +#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL +#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL +#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL +#define CKM_TLS_PRF 0x00000378UL +#define CKM_SSL3_MD5_MAC 0x00000380UL +#define CKM_SSL3_SHA1_MAC 0x00000381UL +#define CKM_MD5_KEY_DERIVATION 0x00000390UL +#define CKM_MD2_KEY_DERIVATION 0x00000391UL +#define CKM_SHA1_KEY_DERIVATION 0x00000392UL +#define CKM_SHA256_KEY_DERIVATION 0x00000393UL +#define CKM_SHA384_KEY_DERIVATION 0x00000394UL +#define CKM_SHA512_KEY_DERIVATION 0x00000395UL +#define CKM_SHA224_KEY_DERIVATION 0x00000396UL +#define CKM_SHA3_256_KEY_DERIVATION 0x00000397UL +#define CKM_SHA3_256_KEY_DERIVE 0x00000397UL +#define CKM_SHA3_224_KEY_DERIVATION 0x00000398UL +#define CKM_SHA3_224_KEY_DERIVE 0x00000398UL +#define CKM_SHA3_384_KEY_DERIVATION 0x00000399UL +#define CKM_SHA3_384_KEY_DERIVE 0x00000399UL +#define CKM_SHA3_512_KEY_DERIVATION 0x0000039AUL +#define CKM_SHA3_512_KEY_DERIVE 0x0000039AUL +#define CKM_SHAKE_128_KEY_DERIVATION 0x0000039BUL +#define CKM_SHAKE_128_KEY_DERIVE 0x0000039BUL +#define CKM_SHAKE_256_KEY_DERIVATION 0x0000039CUL +#define CKM_SHAKE_256_KEY_DERIVE 0x0000039CUL +#define CKM_PBE_MD2_DES_CBC 0x000003A0UL +#define CKM_PBE_MD5_DES_CBC 0x000003A1UL +#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL +#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL +#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL +#define CKM_PBE_SHA1_RC4_128 0x000003A6UL +#define CKM_PBE_SHA1_RC4_40 0x000003A7UL +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL +#define CKM_PKCS5_PBKD2 0x000003B0UL +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL +#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL +#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL +#define CKM_WTLS_PRF 0x000003D3UL +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL +#define CKM_TLS10_MAC_SERVER 0x000003D6UL +#define CKM_TLS10_MAC_CLIENT 0x000003D7UL +#define CKM_TLS12_MAC 0x000003D8UL +#define CKM_TLS12_KDF 0x000003D9UL +#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL +#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL +#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL +#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL +#define CKM_TLS_MAC 0x000003E4UL +#define CKM_TLS_KDF 0x000003E5UL +#define CKM_KEY_WRAP_LYNKS 0x00000400UL +#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL +#define CKM_CMS_SIG 0x00000500UL +#define CKM_KIP_DERIVE 0x00000510UL +#define CKM_KIP_WRAP 0x00000511UL +#define CKM_KIP_MAC 0x00000512UL +#define CKM_CAMELLIA_KEY_GEN 0x00000550UL +#define CKM_CAMELLIA_ECB 0x00000551UL +#define CKM_CAMELLIA_CBC 0x00000552UL +#define CKM_CAMELLIA_MAC 0x00000553UL +#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL +#define CKM_CAMELLIA_CBC_PAD 0x00000555UL +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL +#define CKM_CAMELLIA_CTR 0x00000558UL +#define CKM_ARIA_KEY_GEN 0x00000560UL +#define CKM_ARIA_ECB 0x00000561UL +#define CKM_ARIA_CBC 0x00000562UL +#define CKM_ARIA_MAC 0x00000563UL +#define CKM_ARIA_MAC_GENERAL 0x00000564UL +#define CKM_ARIA_CBC_PAD 0x00000565UL +#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL +#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL +#define CKM_SEED_KEY_GEN 0x00000650UL +#define CKM_SEED_ECB 0x00000651UL +#define CKM_SEED_CBC 0x00000652UL +#define CKM_SEED_MAC 0x00000653UL +#define CKM_SEED_MAC_GENERAL 0x00000654UL +#define CKM_SEED_CBC_PAD 0x00000655UL +#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL +#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL +#define CKM_SKIPJACK_KEY_GEN 0x00001000UL +#define CKM_SKIPJACK_ECB64 0x00001001UL +#define CKM_SKIPJACK_CBC64 0x00001002UL +#define CKM_SKIPJACK_OFB64 0x00001003UL +#define CKM_SKIPJACK_CFB64 0x00001004UL +#define CKM_SKIPJACK_CFB32 0x00001005UL +#define CKM_SKIPJACK_CFB16 0x00001006UL +#define CKM_SKIPJACK_CFB8 0x00001007UL +#define CKM_SKIPJACK_WRAP 0x00001008UL +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL +#define CKM_SKIPJACK_RELAYX 0x0000100AUL +#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL +#define CKM_KEA_KEY_DERIVE 0x00001011UL +#define CKM_KEA_DERIVE 0x00001012UL +#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL +#define CKM_BATON_KEY_GEN 0x00001030UL +#define CKM_BATON_ECB128 0x00001031UL +#define CKM_BATON_ECB96 0x00001032UL +#define CKM_BATON_CBC128 0x00001033UL +#define CKM_BATON_COUNTER 0x00001034UL +#define CKM_BATON_SHUFFLE 0x00001035UL +#define CKM_BATON_WRAP 0x00001036UL +#define CKM_EC_KEY_PAIR_GEN 0x00001040UL +#define CKM_ECDSA 0x00001041UL +#define CKM_ECDSA_SHA1 0x00001042UL +#define CKM_ECDSA_SHA224 0x00001043UL +#define CKM_ECDSA_SHA256 0x00001044UL +#define CKM_ECDSA_SHA384 0x00001045UL +#define CKM_ECDSA_SHA512 0x00001046UL +#define CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS 0x0000140BUL +#define CKM_ECDH1_DERIVE 0x00001050UL +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL +#define CKM_ECMQV_DERIVE 0x00001052UL +#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL +#define CKM_RSA_AES_KEY_WRAP 0x00001054UL +#define CKM_JUNIPER_KEY_GEN 0x00001060UL +#define CKM_JUNIPER_ECB128 0x00001061UL +#define CKM_JUNIPER_CBC128 0x00001062UL +#define CKM_JUNIPER_COUNTER 0x00001063UL +#define CKM_JUNIPER_SHUFFLE 0x00001064UL +#define CKM_JUNIPER_WRAP 0x00001065UL +#define CKM_FASTHASH 0x00001070UL +#define CKM_AES_XTS 0x00001071UL +#define CKM_AES_XTS_KEY_GEN 0x00001072UL +#define CKM_AES_KEY_GEN 0x00001080UL +#define CKM_AES_ECB 0x00001081UL +#define CKM_AES_CBC 0x00001082UL +#define CKM_AES_MAC 0x00001083UL +#define CKM_AES_MAC_GENERAL 0x00001084UL +#define CKM_AES_CBC_PAD 0x00001085UL +#define CKM_AES_CTR 0x00001086UL +#define CKM_AES_GCM 0x00001087UL +#define CKM_AES_CCM 0x00001088UL +#define CKM_AES_CTS 0x00001089UL +#define CKM_AES_CMAC 0x0000108AUL +#define CKM_AES_CMAC_GENERAL 0x0000108BUL +#define CKM_AES_XCBC_MAC 0x0000108CUL +#define CKM_AES_XCBC_MAC_96 0x0000108DUL +#define CKM_AES_GMAC 0x0000108EUL +#define CKM_BLOWFISH_KEY_GEN 0x00001090UL +#define CKM_BLOWFISH_CBC 0x00001091UL +#define CKM_TWOFISH_KEY_GEN 0x00001092UL +#define CKM_TWOFISH_CBC 0x00001093UL +#define CKM_BLOWFISH_CBC_PAD 0x00001094UL +#define CKM_TWOFISH_CBC_PAD 0x00001095UL +#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL +#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL +#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL +#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL +#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL +#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL +#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL +#define CKM_GOSTR3410 0x00001201UL +#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL +#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL +#define CKM_GOSTR3410_DERIVE 0x00001204UL +#define CKM_GOSTR3411 0x00001210UL +#define CKM_GOSTR3411_HMAC 0x00001211UL +#define CKM_GOST28147_KEY_GEN 0x00001220UL +#define CKM_GOST28147_ECB 0x00001221UL +#define CKM_GOST28147 0x00001222UL +#define CKM_GOST28147_MAC 0x00001223UL +#define CKM_GOST28147_KEY_WRAP 0x00001224UL +#define CKM_CHACHA20_KEY_GEN 0x00001225UL +#define CKM_CHACHA20 0x00001226UL +#define CKM_POLY1305_KEY_GEN 0x00001227UL +#define CKM_POLY1305 0x00001228UL +#define CKM_DSA_PARAMETER_GEN 0x00002000UL +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL +#define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL +#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL +#define CKM_DSA_FIPS_G_GEN 0x00002005UL +#define CKM_AES_OFB 0x00002104UL +#define CKM_AES_CFB64 0x00002105UL +#define CKM_AES_CFB8 0x00002106UL +#define CKM_AES_CFB128 0x00002107UL +#define CKM_AES_CFB1 0x00002108UL +#define CKM_AES_KEY_WRAP 0x00002109UL +#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL +#define CKM_AES_KEY_WRAP_KWP 0x0000210BUL +#define CKM_AES_KEY_WRAP_PKCS7 0x0000210CUL +#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL +#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL +#define CKM_SHA_1_KEY_GEN 0x00004003UL +#define CKM_SHA224_KEY_GEN 0x00004004UL +#define CKM_SHA256_KEY_GEN 0x00004005UL +#define CKM_SHA384_KEY_GEN 0x00004006UL +#define CKM_SHA512_KEY_GEN 0x00004007UL +#define CKM_SHA512_224_KEY_GEN 0x00004008UL +#define CKM_SHA512_256_KEY_GEN 0x00004009UL +#define CKM_SHA512_T_KEY_GEN 0x0000400AUL +#define CKM_NULL 0x0000400BUL +#define CKM_BLAKE2B_160 0x0000400CUL +#define CKM_BLAKE2B_160_HMAC 0x0000400DUL +#define CKM_BLAKE2B_160_HMAC_GENERAL 0x0000400EUL +#define CKM_BLAKE2B_160_KEY_DERIVE 0x0000400FUL +#define CKM_BLAKE2B_160_KEY_GEN 0x00004010UL +#define CKM_BLAKE2B_256 0x00004011UL +#define CKM_BLAKE2B_256_HMAC 0x00004012UL +#define CKM_BLAKE2B_256_HMAC_GENERAL 0x00004013UL +#define CKM_BLAKE2B_256_KEY_DERIVE 0x00004014UL +#define CKM_BLAKE2B_256_KEY_GEN 0x00004015UL +#define CKM_BLAKE2B_384 0x00004016UL +#define CKM_BLAKE2B_384_HMAC 0x00004017UL +#define CKM_BLAKE2B_384_HMAC_GENERAL 0x00004018UL +#define CKM_BLAKE2B_384_KEY_DERIVE 0x00004019UL +#define CKM_BLAKE2B_384_KEY_GEN 0x0000401AUL +#define CKM_BLAKE2B_512 0x0000401BUL +#define CKM_BLAKE2B_512_HMAC 0x0000401CUL +#define CKM_BLAKE2B_512_HMAC_GENERAL 0x0000401DUL +#define CKM_BLAKE2B_512_KEY_DERIVE 0x0000401EUL +#define CKM_BLAKE2B_512_KEY_GEN 0x0000401FUL +#define CKM_SALSA20 0x00004020UL +#define CKM_CHACHA20_POLY1305 0x00004021UL +#define CKM_SALSA20_POLY1305 0x00004022UL +#define CKM_X3DH_INITIALIZE 0x00004023UL +#define CKM_X3DH_RESPOND 0x00004024UL +#define CKM_X2RATCHET_INITIALIZE 0x00004025UL +#define CKM_X2RATCHET_RESPOND 0x00004026UL +#define CKM_X2RATCHET_ENCRYPT 0x00004027UL +#define CKM_X2RATCHET_DECRYPT 0x00004028UL +#define CKM_XEDDSA 0x00004029UL +#define CKM_HKDF_DERIVE 0x0000402AUL +#define CKM_HKDF_DATA 0x0000402BUL +#define CKM_HKDF_KEY_GEN 0x0000402CUL +#define CKM_SALSA20_KEY_GEN 0x0000402DUL +#define CKM_ECDSA_SHA3_224 0x00001047UL +#define CKM_ECDSA_SHA3_256 0x00001048UL +#define CKM_ECDSA_SHA3_384 0x00001049UL +#define CKM_ECDSA_SHA3_512 0x0000104AUL +#define CKM_EC_EDWARDS_KEY_PAIR_GEN 0x00001055UL +#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN 0x00001056UL +#define CKM_EDDSA 0x00001057UL +#define CKM_SP800_108_COUNTER_KDF 0x000003ACUL +#define CKM_SP800_108_FEEDBACK_KDF 0x000003ADUL +#define CKM_SP800_108_DOUBLE_PIPELINE_KDF 0x000003AEUL +#define CKM_IKE2_PRF_PLUS_DERIVE 0x0000402EUL +#define CKM_IKE_PRF_DERIVE 0x0000402FUL +#define CKM_IKE1_PRF_DERIVE 0x00004030UL +#define CKM_IKE1_EXTENDED_DERIVE 0x00004031UL +#define CKM_HSS_KEY_PAIR_GEN 0x00004032UL +#define CKM_HSS 0x00004033UL +#define CKM_VENDOR_DEFINED 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKM_CAST5_KEY_GEN 0x00000320UL +#define CKM_CAST5_CBC 0x00000322UL +#define CKM_CAST5_MAC 0x00000323UL +#define CKM_CAST5_MAC_GENERAL 0x00000324UL +#define CKM_CAST5_CBC_PAD 0x00000325UL +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL #endif -#else +/* CKN */ +#define CKN_SURRENDER 0UL +#define CKN_OTP_CHANGED 1UL + +/* CKO */ +#define CKO_DATA 0x00000000UL +#define CKO_CERTIFICATE 0x00000001UL +#define CKO_PUBLIC_KEY 0x00000002UL +#define CKO_PRIVATE_KEY 0x00000003UL +#define CKO_SECRET_KEY 0x00000004UL +#define CKO_HW_FEATURE 0x00000005UL +#define CKO_DOMAIN_PARAMETERS 0x00000006UL +#define CKO_MECHANISM 0x00000007UL +#define CKO_OTP_KEY 0x00000008UL +#define CKO_PROFILE 0x00000009UL +#define CKO_VENDOR_DEFINED 0x80000000UL + +/* CKP (profile) */ +#define CKP_INVALID_ID 0x00000000UL +#define CKP_BASELINE_PROVIDER 0x00000001UL +#define CKP_EXTENDED_PROVIDER 0x00000002UL +#define CKP_AUTHENTICATION_TOKEN 0x00000003UL +#define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL +#define CKP_COMPLETE_PROVIDER 0x00000005UL +#define CKP_HKDF_TLS_TOKEN 0x00000006UL +#define CKP_VENDOR_DEFINED 0x80000000UL + +/* CKP (PBKD2) */ +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL +#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL +#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL +#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL +#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL + +/* CKR */ +#define CKR_OK 0x00000000UL +#define CKR_CANCEL 0x00000001UL +#define CKR_HOST_MEMORY 0x00000002UL +#define CKR_SLOT_ID_INVALID 0x00000003UL +#define CKR_GENERAL_ERROR 0x00000005UL +#define CKR_FUNCTION_FAILED 0x00000006UL +#define CKR_ARGUMENTS_BAD 0x00000007UL +#define CKR_NO_EVENT 0x00000008UL +#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL +#define CKR_CANT_LOCK 0x0000000AUL +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL +#define CKR_ACTION_PROHIBITED 0x0000001BUL +#define CKR_DATA_INVALID 0x00000020UL +#define CKR_DATA_LEN_RANGE 0x00000021UL +#define CKR_DEVICE_ERROR 0x00000030UL +#define CKR_DEVICE_MEMORY 0x00000031UL +#define CKR_DEVICE_REMOVED 0x00000032UL +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL +#define CKR_AEAD_DECRYPT_FAILED 0x00000042UL +#define CKR_FUNCTION_CANCELED 0x00000050UL +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL +#define CKR_KEY_HANDLE_INVALID 0x00000060UL +#define CKR_KEY_SIZE_RANGE 0x00000062UL +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL +#define CKR_KEY_NOT_NEEDED 0x00000064UL +#define CKR_KEY_CHANGED 0x00000065UL +#define CKR_KEY_NEEDED 0x00000066UL +#define CKR_KEY_INDIGESTIBLE 0x00000067UL +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL +#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL +#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL +#define CKR_MECHANISM_INVALID 0x00000070UL +#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL +#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL +#define CKR_OPERATION_ACTIVE 0x00000090UL +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL +#define CKR_PIN_INCORRECT 0x000000A0UL +#define CKR_PIN_INVALID 0x000000A1UL +#define CKR_PIN_LEN_RANGE 0x000000A2UL +#define CKR_PIN_EXPIRED 0x000000A3UL +#define CKR_PIN_LOCKED 0x000000A4UL +#define CKR_SESSION_CLOSED 0x000000B0UL +#define CKR_SESSION_COUNT 0x000000B1UL +#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL +#define CKR_SESSION_READ_ONLY 0x000000B5UL +#define CKR_SESSION_EXISTS 0x000000B6UL +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL +#define CKR_SIGNATURE_INVALID 0x000000C0UL +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL +#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL +#define CKR_USER_NOT_LOGGED_IN 0x00000101UL +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL +#define CKR_USER_TYPE_INVALID 0x00000103UL +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL +#define CKR_USER_TOO_MANY_TYPES 0x00000105UL +#define CKR_WRAPPED_KEY_INVALID 0x00000110UL +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL +#define CKR_RANDOM_NO_RNG 0x00000121UL +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL +#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL +#define CKR_BUFFER_TOO_SMALL 0x00000150UL +#define CKR_SAVED_STATE_INVALID 0x00000160UL +#define CKR_INFORMATION_SENSITIVE 0x00000170UL +#define CKR_STATE_UNSAVEABLE 0x00000180UL +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL +#define CKR_MUTEX_BAD 0x000001A0UL +#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL +#define CKR_NEW_PIN_MODE 0x000001B0UL +#define CKR_NEXT_OTP 0x000001B1UL +#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL +#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL +#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL +#define CKR_PIN_TOO_WEAK 0x000001B8UL +#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL +#define CKR_FUNCTION_REJECTED 0x00000200UL +#define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL +#define CKR_OPERATION_CANCEL_FAILED 0x00000202UL +#define CKR_KEY_EXHAUSTED 0x00000203UL +#define CKR_VENDOR_DEFINED 0x80000000UL + + +/* CKS */ +#define CKS_RO_PUBLIC_SESSION 0UL +#define CKS_RO_USER_FUNCTIONS 1UL +#define CKS_RW_PUBLIC_SESSION 2UL +#define CKS_RW_USER_FUNCTIONS 3UL +#define CKS_RW_SO_FUNCTIONS 4UL + +/* CKU */ +#define CKU_SO 0UL +#define CKU_USER 1UL +#define CKU_CONTEXT_SPECIFIC 2UL + +/* CKZ (data) */ +#define CKZ_DATA_SPECIFIED 0x00000001UL + +/* CKZ (salt) */ +#define CKZ_SALT_SPECIFIED 0x00000001UL + +/* Sundry structures type definition in alphabetical order */ +#define STRUCTDEF(__name__) \ +struct __name__; \ +typedef struct __name__ __name__; \ +typedef struct __name__ * __name__ ## _PTR; \ +typedef struct __name__ ** __name__ ## _PTR_PTR; + +STRUCTDEF(CK_ATTRIBUTE); +STRUCTDEF(CK_C_INITIALIZE_ARGS); +STRUCTDEF(CK_DATE); +STRUCTDEF(CK_DERIVED_KEY); +STRUCTDEF(CK_FUNCTION_LIST); +STRUCTDEF(CK_FUNCTION_LIST_3_0); +STRUCTDEF(CK_INFO); +STRUCTDEF(CK_INTERFACE); +STRUCTDEF(CK_MECHANISM); +STRUCTDEF(CK_MECHANISM_INFO); +STRUCTDEF(CK_SESSION_INFO); +STRUCTDEF(CK_SLOT_INFO); +STRUCTDEF(CK_TOKEN_INFO); +STRUCTDEF(CK_VERSION); + +/* Function type definitions */ +typedef CK_RV (* CK_NOTIFY)(CK_SESSION_HANDLE, CK_NOTIFICATION, void *); +typedef CK_RV (* CK_CREATEMUTEX)(void **); +typedef CK_RV (* CK_DESTROYMUTEX)(void *); +typedef CK_RV (* CK_LOCKMUTEX)(void *); +typedef CK_RV (* CK_UNLOCKMUTEX)(void *); + +/* General Structure definitions */ +struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + void * pValue; + CK_ULONG ulValueLen; +}; -#define CK_SPEC +struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + void * pReserved; +}; -#endif +struct CK_DATE{ + CK_CHAR year[4]; + CK_CHAR month[2]; + CK_CHAR day[2]; +}; -#ifdef CRYPTOKI_COMPAT - /* If we are in compatibility mode, switch all exposed names to the - PKCS #11 variant. There are corresponding #undefs below. */ +struct CK_DERIVED_KEY +{ + CK_ATTRIBUTE * pTemplate; + CK_ULONG ulAttributeCount; + CK_OBJECT_HANDLE * phKey; +}; -#define ck_flags_t CK_FLAGS -#define ck_version _CK_VERSION +struct CK_VERSION { + CK_BYTE major; + CK_BYTE minor; +}; -#define ck_info _CK_INFO -#define cryptoki_version cryptokiVersion -#define manufacturer_id manufacturerID -#define library_description libraryDescription -#define library_version libraryVersion +struct CK_INFO { + struct CK_VERSION cryptokiVersion; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + CK_UTF8CHAR libraryDescription[32]; + struct CK_VERSION libraryVersion; +}; -#define ck_notification_t CK_NOTIFICATION -#define ck_slot_id_t CK_SLOT_ID +struct CK_INTERFACE { + CK_CHAR * pInterfaceName; + void * pFunctionList; + CK_FLAGS flags; +}; -#define ck_slot_info _CK_SLOT_INFO -#define slot_description slotDescription -#define hardware_version hardwareVersion -#define firmware_version firmwareVersion +struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + void * pParameter; + CK_ULONG ulParameterLen; +}; -#define ck_token_info _CK_TOKEN_INFO -#define serial_number serialNumber -#define max_session_count ulMaxSessionCount -#define session_count ulSessionCount -#define max_rw_session_count ulMaxRwSessionCount -#define rw_session_count ulRwSessionCount -#define max_pin_len ulMaxPinLen -#define min_pin_len ulMinPinLen -#define total_public_memory ulTotalPublicMemory -#define free_public_memory ulFreePublicMemory -#define total_private_memory ulTotalPrivateMemory -#define free_private_memory ulFreePrivateMemory -#define utc_time utcTime +struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +}; -#define ck_session_handle_t CK_SESSION_HANDLE -#define ck_user_type_t CK_USER_TYPE -#define ck_state_t CK_STATE +struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; + CK_ULONG ulDeviceError; +}; -#define ck_session_info _CK_SESSION_INFO -#define slot_id slotID -#define device_error ulDeviceError +struct CK_SLOT_INFO { + CK_UTF8CHAR slotDescription[64]; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; +}; -#define ck_object_handle_t CK_OBJECT_HANDLE -#define ck_object_class_t CK_OBJECT_CLASS -#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE -#define ck_key_type_t CK_KEY_TYPE -#define ck_certificate_type_t CK_CERTIFICATE_TYPE -#define ck_attribute_type_t CK_ATTRIBUTE_TYPE +struct CK_TOKEN_INFO { + CK_UTF8CHAR label[32]; + CK_UTF8CHAR manufacturerID[32]; + CK_UTF8CHAR model[16]; + CK_CHAR serialNumber[16]; + CK_FLAGS flags; + CK_ULONG ulMaxSessionCount; + CK_ULONG ulSessionCount; + CK_ULONG ulMaxRwSessionCount; + CK_ULONG ulRwSessionCount; + CK_ULONG ulMaxPinLen; + CK_ULONG ulMinPinLen; + CK_ULONG ulTotalPublicMemory; + CK_ULONG ulFreePublicMemory; + CK_ULONG ulTotalPrivateMemory; + CK_ULONG ulFreePrivateMemory; + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; + CK_CHAR utcTime[16]; +}; -#define ck_attribute _CK_ATTRIBUTE -#define value pValue -#define value_len ulValueLen +/* Param Structure definitions in alphabetical order */ +STRUCTDEF(CK_AES_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_AES_CCM_PARAMS); +STRUCTDEF(CK_AES_CTR_PARAMS); +STRUCTDEF(CK_AES_GCM_PARAMS); +STRUCTDEF(CK_ARIA_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_CAMELLIA_CTR_PARAMS); +STRUCTDEF(CK_CCM_MESSAGE_PARAMS); +STRUCTDEF(CK_CCM_PARAMS); +STRUCTDEF(CK_CHACHA20_PARAMS); +STRUCTDEF(CK_CMS_SIG_PARAMS); +STRUCTDEF(CK_DES_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_DSA_PARAMETER_GEN_PARAM); +STRUCTDEF(CK_ECDH_AES_KEY_WRAP_PARAMS); +STRUCTDEF(CK_ECDH1_DERIVE_PARAMS); +STRUCTDEF(CK_ECDH2_DERIVE_PARAMS); +STRUCTDEF(CK_ECMQV_DERIVE_PARAMS); +STRUCTDEF(CK_EDDSA_PARAMS); +STRUCTDEF(CK_GCM_MESSAGE_PARAMS); +STRUCTDEF(CK_GCM_PARAMS); +STRUCTDEF(CK_GOSTR3410_DERIVE_PARAMS); +STRUCTDEF(CK_GOSTR3410_KEY_WRAP_PARAMS); +STRUCTDEF(CK_HKDF_PARAMS); +STRUCTDEF(CK_IKE_PRF_DERIVE_PARAMS); +STRUCTDEF(CK_IKE1_EXTENDED_DERIVE_PARAMS); +STRUCTDEF(CK_IKE1_PRF_DERIVE_PARAMS); +STRUCTDEF(CK_IKE2_PRF_PLUS_DERIVE_PARAMS); +STRUCTDEF(CK_KEA_DERIVE_PARAMS); +STRUCTDEF(CK_KEY_DERIVATION_STRING_DATA); +STRUCTDEF(CK_KEY_WRAP_SET_OAEP_PARAMS); +STRUCTDEF(CK_KIP_PARAMS); +STRUCTDEF(CK_OTP_PARAM); +STRUCTDEF(CK_OTP_PARAMS); +STRUCTDEF(CK_OTP_SIGNATURE_INFO); +STRUCTDEF(CK_PBE_PARAMS); +STRUCTDEF(CK_PKCS5_PBKD2_PARAMS); +STRUCTDEF(CK_PKCS5_PBKD2_PARAMS2); +STRUCTDEF(CK_PRF_DATA_PARAM); +STRUCTDEF(CK_RC2_CBC_PARAMS); +STRUCTDEF(CK_RC2_MAC_GENERAL_PARAMS); +STRUCTDEF(CK_RC5_CBC_PARAMS); +STRUCTDEF(CK_RC5_MAC_GENERAL_PARAMS); +STRUCTDEF(CK_RC5_PARAMS); +STRUCTDEF(CK_RSA_AES_KEY_WRAP_PARAMS); +STRUCTDEF(CK_RSA_PKCS_OAEP_PARAMS); +STRUCTDEF(CK_RSA_PKCS_PSS_PARAMS); +STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS); +STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_PARAMS); +STRUCTDEF(CK_SALSA20_PARAMS); +STRUCTDEF(CK_SEED_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_SKIPJACK_PRIVATE_WRAP_PARAMS); +STRUCTDEF(CK_SKIPJACK_RELAYX_PARAMS); +STRUCTDEF(CK_SP800_108_COUNTER_FORMAT); +STRUCTDEF(CK_SP800_108_DKM_LENGTH_FORMAT); +STRUCTDEF(CK_SP800_108_FEEDBACK_KDF_PARAMS); +STRUCTDEF(CK_SP800_108_KDF_PARAMS); +STRUCTDEF(CK_X2RATCHET_INITIALIZE_PARAMS); +STRUCTDEF(CK_X2RATCHET_RESPOND_PARAMS); +STRUCTDEF(CK_X3DH_INITIATE_PARAMS); +STRUCTDEF(CK_X3DH_RESPOND_PARAMS); +STRUCTDEF(CK_X9_42_DH1_DERIVE_PARAMS); +STRUCTDEF(CK_X9_42_DH2_DERIVE_PARAMS); +STRUCTDEF(CK_X9_42_MQV_DERIVE_PARAMS); +STRUCTDEF(CK_XEDDSA_PARAMS); +STRUCTDEF(specifiedParams); + +struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; -#define ck_date _CK_DATE +struct CK_AES_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; -#define ck_mechanism_type_t CK_MECHANISM_TYPE +struct CK_AES_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +}; -#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE +struct CK_AES_GCM_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; -#define ck_generator_function_t CK_GENERATOR_FUNCTION +struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; -#define ck_mechanism _CK_MECHANISM -#define parameter pParameter -#define parameter_len ulParameterLen +struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; -#define ck_mechanism_info _CK_MECHANISM_INFO -#define min_key_size ulMinKeySize -#define max_key_size ulMaxKeySize +struct CK_CAMELLIA_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +}; -#define ck_rv_t CK_RV -#define ck_notify_t CK_NOTIFY +struct CK_CCM_MESSAGE_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; + CK_GENERATOR_FUNCTION nonceGenerator; + CK_BYTE * pMAC; + CK_ULONG ulMACLen; +}; -#define ck_interface CK_INTERFACE +struct CK_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; -#define ck_function_list _CK_FUNCTION_LIST -#define ck_function_list_3_0 _CK_FUNCTION_LIST_3_0 +struct CK_CHACHA20_PARAMS { + CK_BYTE * pBlockCounter; + CK_ULONG blockCounterBits; + CK_BYTE * pNonce; + CK_ULONG ulNonceBits; +}; -#define ck_createmutex_t CK_CREATEMUTEX -#define ck_destroymutex_t CK_DESTROYMUTEX -#define ck_lockmutex_t CK_LOCKMUTEX -#define ck_unlockmutex_t CK_UNLOCKMUTEX +struct CK_CMS_SIG_PARAMS { + CK_OBJECT_HANDLE certificateHandle; + CK_MECHANISM * pSigningMechanism; + CK_MECHANISM * pDigestMechanism; + CK_UTF8CHAR * pContentType; + CK_BYTE * pRequestedAttributes; + CK_ULONG ulRequestedAttributesLen; + CK_BYTE * pRequiredAttributes; + CK_ULONG ulRequiredAttributesLen; +}; -#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS -#define create_mutex CreateMutex -#define destroy_mutex DestroyMutex -#define lock_mutex LockMutex -#define unlock_mutex UnlockMutex -#define reserved pReserved +struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[8]; + CK_BYTE * pData; + CK_ULONG length; +}; -#endif /* CRYPTOKI_COMPAT */ +struct CK_DSA_PARAMETER_GEN_PARAM { + CK_MECHANISM_TYPE hash; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_ULONG ulIndex; +}; +struct CK_ECDH_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; +}; -typedef unsigned long ck_flags_t; +struct CK_ECDH1_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; +}; -struct ck_version -{ - unsigned char major; - unsigned char minor; +struct CK_ECDH2_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; }; +struct CK_ECMQV_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; + CK_OBJECT_HANDLE publicKey; +}; -struct ck_info -{ - struct ck_version cryptoki_version; - unsigned char manufacturer_id[32]; - ck_flags_t flags; - unsigned char library_description[32]; - struct ck_version library_version; +struct CK_EDDSA_PARAMS { + CK_BBOOL phFlag; + CK_ULONG ulContextDataLen; + CK_BYTE * pContextData; }; +struct CK_GCM_MESSAGE_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + CK_BYTE * pTag; + CK_ULONG ulTagBits; +}; -typedef unsigned long ck_notification_t; +struct CK_GCM_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; -#define CKN_SURRENDER (0UL) +struct CK_GOSTR3410_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_BYTE * pPublicData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pUKM; + CK_ULONG ulUKMLen; +}; +struct CK_GOSTR3410_KEY_WRAP_PARAMS { + CK_BYTE * pWrapOID; + CK_ULONG ulWrapOIDLen; + CK_BYTE * pUKM; + CK_ULONG ulUKMLen; + CK_OBJECT_HANDLE hKey; +}; -typedef unsigned long ck_slot_id_t; +struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE * pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE * pInfo; + CK_ULONG ulInfoLen; +}; +struct CK_IKE_PRF_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bDataAsKey; + CK_BBOOL bRekey; + CK_BYTE * pNi; + CK_ULONG ulNiLen; + CK_BYTE * pNr; + CK_ULONG ulNrLen; + CK_OBJECT_HANDLE hNewKey; +}; -struct ck_slot_info -{ - unsigned char slot_description[64]; - unsigned char manufacturer_id[32]; - ck_flags_t flags; - struct ck_version hardware_version; - struct ck_version firmware_version; +struct CK_IKE1_EXTENDED_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasKeygxy; + CK_OBJECT_HANDLE hKeygxy; + CK_BYTE * pExtraData; + CK_ULONG ulExtraDataLen; }; +struct CK_IKE1_PRF_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasPrevKey; + CK_OBJECT_HANDLE hKeygxy; + CK_OBJECT_HANDLE hPrevKey; + CK_BYTE * pCKYi; + CK_ULONG ulCKYiLen; + CK_BYTE * pCKYr; + CK_ULONG ulCKYrLen; + CK_BYTE keyNumber; +}; -#define CKF_TOKEN_PRESENT (1UL << 0) -#define CKF_REMOVABLE_DEVICE (1UL << 1) -#define CKF_HW_SLOT (1UL << 2) -#define CKF_ARRAY_ATTRIBUTE (1UL << 30) +struct CK_IKE2_PRF_PLUS_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasSeedKey; + CK_OBJECT_HANDLE hSeedKey; + CK_BYTE * pSeedData; + CK_ULONG ulSeedDataLen; +}; +struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE * RandomA; + CK_BYTE * RandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE * PublicData; +}; -struct ck_token_info -{ - unsigned char label[32]; - unsigned char manufacturer_id[32]; - unsigned char model[16]; - unsigned char serial_number[16]; - ck_flags_t flags; - unsigned long max_session_count; - unsigned long session_count; - unsigned long max_rw_session_count; - unsigned long rw_session_count; - unsigned long max_pin_len; - unsigned long min_pin_len; - unsigned long total_public_memory; - unsigned long free_public_memory; - unsigned long total_private_memory; - unsigned long free_private_memory; - struct ck_version hardware_version; - struct ck_version firmware_version; - unsigned char utc_time[16]; -}; - - -#define CKF_RNG (1UL << 0) -#define CKF_WRITE_PROTECTED (1UL << 1) -#define CKF_LOGIN_REQUIRED (1UL << 2) -#define CKF_USER_PIN_INITIALIZED (1UL << 3) -#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) -#define CKF_CLOCK_ON_TOKEN (1UL << 6) -#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) -#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) -#define CKF_TOKEN_INITIALIZED (1UL << 10) -#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) -#define CKF_USER_PIN_COUNT_LOW (1UL << 16) -#define CKF_USER_PIN_FINAL_TRY (1UL << 17) -#define CKF_USER_PIN_LOCKED (1UL << 18) -#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) -#define CKF_SO_PIN_COUNT_LOW (1UL << 20) -#define CKF_SO_PIN_FINAL_TRY (1UL << 21) -#define CKF_SO_PIN_LOCKED (1UL << 22) -#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) - -#define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) -#define CK_EFFECTIVELY_INFINITE (0UL) - - -typedef unsigned long ck_session_handle_t; - -#define CK_INVALID_HANDLE (0UL) - - -typedef unsigned long ck_user_type_t; - -#define CKU_SO (0UL) -#define CKU_USER (1UL) -#define CKU_CONTEXT_SPECIFIC (2UL) - - -typedef unsigned long ck_state_t; - -#define CKS_RO_PUBLIC_SESSION (0UL) -#define CKS_RO_USER_FUNCTIONS (1UL) -#define CKS_RW_PUBLIC_SESSION (2UL) -#define CKS_RW_USER_FUNCTIONS (3UL) -#define CKS_RW_SO_FUNCTIONS (4UL) - - -struct ck_session_info -{ - ck_slot_id_t slot_id; - ck_state_t state; - ck_flags_t flags; - unsigned long device_error; -}; - -#define CKF_RW_SESSION (1UL << 1) -#define CKF_SERIAL_SESSION (1UL << 2) - - -typedef unsigned long ck_object_handle_t; - - -typedef unsigned long ck_object_class_t; - -#define CKO_DATA (0UL) -#define CKO_CERTIFICATE (1UL) -#define CKO_PUBLIC_KEY (2UL) -#define CKO_PRIVATE_KEY (3UL) -#define CKO_SECRET_KEY (4UL) -#define CKO_HW_FEATURE (5UL) -#define CKO_DOMAIN_PARAMETERS (6UL) -#define CKO_MECHANISM (7UL) -#define CKO_OTP_KEY (8UL) -#define CKO_PROFILE (9UL) -#define CKO_VENDOR_DEFINED (1UL << 31) - -#define CKP_INVALID_ID (0UL) -#define CKP_BASELINE_PROVIDER (1UL) -#define CKP_EXTENDED_PROVIDER (2UL) -#define CKP_AUTHENTICATION_TOKEN (3UL) -#define CKP_PUBLIC_CERTIFICATES_TOKEN (4UL) -#define CKP_VENDOR_DEFINED (1UL << 31) - -typedef unsigned long ck_hw_feature_type_t; - -#define CKH_MONOTONIC_COUNTER (1UL) -#define CKH_CLOCK (2UL) -#define CKH_USER_INTERFACE (3UL) -#define CKH_VENDOR_DEFINED (1UL << 31) - - -typedef unsigned long ck_key_type_t; - -#define CKK_RSA (0UL) -#define CKK_DSA (1UL) -#define CKK_DH (2UL) -#define CKK_ECDSA (3UL) -#define CKK_EC (3UL) -#define CKK_X9_42_DH (4UL) -#define CKK_KEA (5UL) -#define CKK_GENERIC_SECRET (0x10UL) -#define CKK_RC2 (0x11UL) -#define CKK_RC4 (0x12UL) -#define CKK_DES (0x13UL) -#define CKK_DES2 (0x14UL) -#define CKK_DES3 (0x15UL) -#define CKK_CAST (0x16UL) -#define CKK_CAST3 (0x17UL) -#define CKK_CAST128 (0x18UL) -#define CKK_RC5 (0x19UL) -#define CKK_IDEA (0x1aUL) -#define CKK_SKIPJACK (0x1bUL) -#define CKK_BATON (0x1cUL) -#define CKK_JUNIPER (0x1dUL) -#define CKK_CDMF (0x1eUL) -#define CKK_AES (0x1fUL) -#define CKK_BLOWFISH (0x20UL) -#define CKK_TWOFISH (0x21UL) -#define CKK_GOSTR3410 (0x30UL) -#define CKK_GOSTR3411 (0x31UL) -#define CKK_GOST28147 (0x32UL) -#define CKK_CHACHA20 (0x33UL) -#define CKK_POLY1305 (0x34UL) -#define CKK_EC_EDWARDS (0x40UL) -#define CKK_EC_MONTGOMERY (0x41UL) -#define CKK_HKDF (0x42UL) -#define CKK_VENDOR_DEFINED (1UL << 31) +struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE * pData; + CK_ULONG ulLen; +}; -/* - * A mask for new GOST algorithms. - * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html - */ -#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) -#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM +struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; + CK_BYTE * pX; + CK_ULONG ulXLen; +}; -#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) +struct CK_KIP_PARAMS { + CK_MECHANISM * pMechanism; + CK_OBJECT_HANDLE hKey; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; +}; -typedef unsigned long ck_certificate_type_t; - -#define CKC_X_509 (0UL) -#define CKC_X_509_ATTR_CERT (1UL) -#define CKC_WTLS (2UL) -#define CKC_VENDOR_DEFINED (1UL << 31) - - -typedef unsigned long ck_attribute_type_t; - -#define CKA_CLASS (0UL) -#define CKA_TOKEN (1UL) -#define CKA_PRIVATE (2UL) -#define CKA_LABEL (3UL) -#define CKA_UNIQUE_ID (4UL) -#define CKA_APPLICATION (0x10UL) -#define CKA_VALUE (0x11UL) -#define CKA_OBJECT_ID (0x12UL) -#define CKA_CERTIFICATE_TYPE (0x80UL) -#define CKA_ISSUER (0x81UL) -#define CKA_SERIAL_NUMBER (0x82UL) -#define CKA_AC_ISSUER (0x83UL) -#define CKA_OWNER (0x84UL) -#define CKA_ATTR_TYPES (0x85UL) -#define CKA_TRUSTED (0x86UL) -#define CKA_CERTIFICATE_CATEGORY (0x87UL) -#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) -#define CKA_URL (0x89UL) -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) -#define CKA_CHECK_VALUE (0x90UL) -#define CKA_KEY_TYPE (0x100UL) -#define CKA_SUBJECT (0x101UL) -#define CKA_ID (0x102UL) -#define CKA_SENSITIVE (0x103UL) -#define CKA_ENCRYPT (0x104UL) -#define CKA_DECRYPT (0x105UL) -#define CKA_WRAP (0x106UL) -#define CKA_UNWRAP (0x107UL) -#define CKA_SIGN (0x108UL) -#define CKA_SIGN_RECOVER (0x109UL) -#define CKA_VERIFY (0x10aUL) -#define CKA_VERIFY_RECOVER (0x10bUL) -#define CKA_DERIVE (0x10cUL) -#define CKA_START_DATE (0x110UL) -#define CKA_END_DATE (0x111UL) -#define CKA_MODULUS (0x120UL) -#define CKA_MODULUS_BITS (0x121UL) -#define CKA_PUBLIC_EXPONENT (0x122UL) -#define CKA_PRIVATE_EXPONENT (0x123UL) -#define CKA_PRIME_1 (0x124UL) -#define CKA_PRIME_2 (0x125UL) -#define CKA_EXPONENT_1 (0x126UL) -#define CKA_EXPONENT_2 (0x127UL) -#define CKA_COEFFICIENT (0x128UL) -#define CKA_PUBLIC_KEY_INFO (0x129UL) -#define CKA_PRIME (0x130UL) -#define CKA_SUBPRIME (0x131UL) -#define CKA_BASE (0x132UL) -#define CKA_PRIME_BITS (0x133UL) -#define CKA_SUB_PRIME_BITS (0x134UL) -#define CKA_VALUE_BITS (0x160UL) -#define CKA_VALUE_LEN (0x161UL) -#define CKA_EXTRACTABLE (0x162UL) -#define CKA_LOCAL (0x163UL) -#define CKA_NEVER_EXTRACTABLE (0x164UL) -#define CKA_ALWAYS_SENSITIVE (0x165UL) -#define CKA_KEY_GEN_MECHANISM (0x166UL) -#define CKA_MODIFIABLE (0x170UL) -#define CKA_COPYABLE (0x171UL) -#define CKA_DESTROYABLE (0x172UL) -#define CKA_ECDSA_PARAMS (0x180UL) -#define CKA_EC_PARAMS (0x180UL) -#define CKA_EC_POINT (0x181UL) -#define CKA_SECONDARY_AUTH (0x200UL) -#define CKA_AUTH_PIN_FLAGS (0x201UL) -#define CKA_ALWAYS_AUTHENTICATE (0x202UL) -#define CKA_WRAP_WITH_TRUSTED (0x210UL) -#define CKA_GOSTR3410_PARAMS (0x250UL) -#define CKA_GOSTR3411_PARAMS (0x251UL) -#define CKA_GOST28147_PARAMS (0x252UL) -#define CKA_HW_FEATURE_TYPE (0x300UL) -#define CKA_RESET_ON_INIT (0x301UL) -#define CKA_HAS_RESET (0x302UL) -#define CKA_PIXEL_X (0x400UL) -#define CKA_PIXEL_Y (0x401UL) -#define CKA_RESOLUTION (0x402UL) -#define CKA_CHAR_ROWS (0x403UL) -#define CKA_CHAR_COLUMNS (0x404UL) -#define CKA_COLOR (0x405UL) -#define CKA_BITS_PER_PIXEL (0x406UL) -#define CKA_CHAR_SETS (0x480UL) -#define CKA_ENCODING_METHODS (0x481UL) -#define CKA_MIME_TYPES (0x482UL) -#define CKA_MECHANISM_TYPE (0x500UL) -#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) -#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) -#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) -#define CKA_OTP_FORMAT (0x220UL) -#define CKA_OTP_LENGTH (0x221UL) -#define CKA_OTP_TIME_INTERVAL (0x222UL) -#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) -#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) -#define CKA_OTP_TIME_REQUIREMENT (0x225UL) -#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) -#define CKA_OTP_PIN_REQUIREMENT (0x227UL) -#define CKA_OTP_USER_IDENTIFIER (0x22AUL) -#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) -#define CKA_OTP_SERVICE_LOGO (0x22CUL) -#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) -#define CKA_OTP_COUNTER (0x22EUL) -#define CKA_OTP_TIME (0x22FUL) -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) -#define CKA_PROFILE_ID (0x601UL) -#define CKA_VENDOR_DEFINED (1UL << 31) - - -struct ck_attribute -{ - ck_attribute_type_t type; - void *value; - unsigned long value_len; +struct CK_OTP_PARAM { + CK_OTP_PARAM_TYPE type; + void * pValue; + CK_ULONG ulValueLen; }; +struct CK_OTP_PARAMS { + CK_OTP_PARAM * pParams; + CK_ULONG ulCount; +}; -struct ck_date -{ - unsigned char year[4]; - unsigned char month[2]; - unsigned char day[2]; -}; - - -typedef unsigned long ck_mechanism_type_t; - -#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) -#define CKM_RSA_PKCS (1UL) -#define CKM_RSA_9796 (2UL) -#define CKM_RSA_X_509 (3UL) -#define CKM_MD2_RSA_PKCS (4UL) -#define CKM_MD5_RSA_PKCS (5UL) -#define CKM_SHA1_RSA_PKCS (6UL) -#define CKM_RIPEMD128_RSA_PKCS (7UL) -#define CKM_RIPEMD160_RSA_PKCS (8UL) -#define CKM_RSA_PKCS_OAEP (9UL) -#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) -#define CKM_RSA_X9_31 (0xbUL) -#define CKM_SHA1_RSA_X9_31 (0xcUL) -#define CKM_RSA_PKCS_PSS (0xdUL) -#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) -#define CKM_DSA_KEY_PAIR_GEN (0x10UL) -#define CKM_DSA (0x11UL) -#define CKM_DSA_SHA1 (0x12UL) -#define CKM_DSA_SHA224 (0x13UL) -#define CKM_DSA_SHA256 (0x14UL) -#define CKM_DSA_SHA384 (0x15UL) -#define CKM_DSA_SHA512 (0x16UL) -#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) -#define CKM_DH_PKCS_DERIVE (0x21UL) -#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) -#define CKM_X9_42_DH_DERIVE (0x31UL) -#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) -#define CKM_X9_42_MQV_DERIVE (0x33UL) -#define CKM_SHA256_RSA_PKCS (0x40UL) -#define CKM_SHA384_RSA_PKCS (0x41UL) -#define CKM_SHA512_RSA_PKCS (0x42UL) -#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) -#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) -#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) -#define CKM_SHA224_RSA_PKCS (0x46UL) -#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) -#define CKM_SHA3_256_RSA_PKCS (0x60UL) -#define CKM_SHA3_384_RSA_PKCS (0x61UL) -#define CKM_SHA3_512_RSA_PKCS (0x62UL) -#define CKM_SHA3_256_RSA_PKCS_PSS (0x63UL) -#define CKM_SHA3_384_RSA_PKCS_PSS (0x64UL) -#define CKM_SHA3_512_RSA_PKCS_PSS (0x65UL) -#define CKM_SHA3_224_RSA_PKCS (0x66UL) -#define CKM_SHA3_224_RSA_PKCS_PSS (0x67UL) -#define CKM_RC2_KEY_GEN (0x100UL) -#define CKM_RC2_ECB (0x101UL) -#define CKM_RC2_CBC (0x102UL) -#define CKM_RC2_MAC (0x103UL) -#define CKM_RC2_MAC_GENERAL (0x104UL) -#define CKM_RC2_CBC_PAD (0x105UL) -#define CKM_RC4_KEY_GEN (0x110UL) -#define CKM_RC4 (0x111UL) -#define CKM_DES_KEY_GEN (0x120UL) -#define CKM_DES_ECB (0x121UL) -#define CKM_DES_CBC (0x122UL) -#define CKM_DES_MAC (0x123UL) -#define CKM_DES_MAC_GENERAL (0x124UL) -#define CKM_DES_CBC_PAD (0x125UL) -#define CKM_DES2_KEY_GEN (0x130UL) -#define CKM_DES3_KEY_GEN (0x131UL) -#define CKM_DES3_ECB (0x132UL) -#define CKM_DES3_CBC (0x133UL) -#define CKM_DES3_MAC (0x134UL) -#define CKM_DES3_MAC_GENERAL (0x135UL) -#define CKM_DES3_CBC_PAD (0x136UL) -#define CKM_DES3_CMAC_GENERAL (0x137UL) -#define CKM_DES3_CMAC (0x138UL) -#define CKM_CDMF_KEY_GEN (0x140UL) -#define CKM_CDMF_ECB (0x141UL) -#define CKM_CDMF_CBC (0x142UL) -#define CKM_CDMF_MAC (0x143UL) -#define CKM_CDMF_MAC_GENERAL (0x144UL) -#define CKM_CDMF_CBC_PAD (0x145UL) -#define CKM_MD2 (0x200UL) -#define CKM_MD2_HMAC (0x201UL) -#define CKM_MD2_HMAC_GENERAL (0x202UL) -#define CKM_MD5 (0x210UL) -#define CKM_MD5_HMAC (0x211UL) -#define CKM_MD5_HMAC_GENERAL (0x212UL) -#define CKM_SHA_1 (0x220UL) -#define CKM_SHA_1_HMAC (0x221UL) -#define CKM_SHA_1_HMAC_GENERAL (0x222UL) -#define CKM_RIPEMD128 (0x230UL) -#define CKM_RIPEMD128_HMAC (0x231UL) -#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) -#define CKM_RIPEMD160 (0x240UL) -#define CKM_RIPEMD160_HMAC (0x241UL) -#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) -#define CKM_SHA256 (0x250UL) -#define CKM_SHA256_HMAC (0x251UL) -#define CKM_SHA256_HMAC_GENERAL (0x252UL) -#define CKM_SHA224 (0x255UL) -#define CKM_SHA224_HMAC (0x256UL) -#define CKM_SHA224_HMAC_GENERAL (0x257UL) -#define CKM_SHA384 (0x260UL) -#define CKM_SHA384_HMAC (0x261UL) -#define CKM_SHA384_HMAC_GENERAL (0x262UL) -#define CKM_SHA512 (0x270UL) -#define CKM_SHA512_HMAC (0x271UL) -#define CKM_SHA512_HMAC_GENERAL (0x272UL) -#define CKM_SHA3_256 (0x2B0UL) -#define CKM_SHA3_256_HMAC (0x2B1UL) -#define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL) -#define CKM_SHA3_256_KEY_GEN (0x2B3UL) -#define CKM_SHA3_224 (0x2B5UL) -#define CKM_SHA3_224_HMAC (0x2B6UL) -#define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL) -#define CKM_SHA3_224_KEY_GEN (0x2B8UL) -#define CKM_SHA3_384 (0x2C0UL) -#define CKM_SHA3_384_HMAC (0x2C1UL) -#define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL) -#define CKM_SHA3_384_KEY_GEN (0x2C3UL) -#define CKM_SHA3_512 (0x2D0UL) -#define CKM_SHA3_512_HMAC (0x2D1UL) -#define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL) -#define CKM_SHA3_512_KEY_GEN (0x2D3UL) -#define CKM_CAST_KEY_GEN (0x300UL) -#define CKM_CAST_ECB (0x301UL) -#define CKM_CAST_CBC (0x302UL) -#define CKM_CAST_MAC (0x303UL) -#define CKM_CAST_MAC_GENERAL (0x304UL) -#define CKM_CAST_CBC_PAD (0x305UL) -#define CKM_CAST3_KEY_GEN (0x310UL) -#define CKM_CAST3_ECB (0x311UL) -#define CKM_CAST3_CBC (0x312UL) -#define CKM_CAST3_MAC (0x313UL) -#define CKM_CAST3_MAC_GENERAL (0x314UL) -#define CKM_CAST3_CBC_PAD (0x315UL) -#define CKM_CAST5_KEY_GEN (0x320UL) -#define CKM_CAST128_KEY_GEN (0x320UL) -#define CKM_CAST5_ECB (0x321UL) -#define CKM_CAST128_ECB (0x321UL) -#define CKM_CAST5_CBC (0x322UL) -#define CKM_CAST128_CBC (0x322UL) -#define CKM_CAST5_MAC (0x323UL) -#define CKM_CAST128_MAC (0x323UL) -#define CKM_CAST5_MAC_GENERAL (0x324UL) -#define CKM_CAST128_MAC_GENERAL (0x324UL) -#define CKM_CAST5_CBC_PAD (0x325UL) -#define CKM_CAST128_CBC_PAD (0x325UL) -#define CKM_RC5_KEY_GEN (0x330UL) -#define CKM_RC5_ECB (0x331UL) -#define CKM_RC5_CBC (0x332UL) -#define CKM_RC5_MAC (0x333UL) -#define CKM_RC5_MAC_GENERAL (0x334UL) -#define CKM_RC5_CBC_PAD (0x335UL) -#define CKM_IDEA_KEY_GEN (0x340UL) -#define CKM_IDEA_ECB (0x341UL) -#define CKM_IDEA_CBC (0x342UL) -#define CKM_IDEA_MAC (0x343UL) -#define CKM_IDEA_MAC_GENERAL (0x344UL) -#define CKM_IDEA_CBC_PAD (0x345UL) -#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) -#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) -#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) -#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) -#define CKM_XOR_BASE_AND_DATA (0x364UL) -#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) -#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) -#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) -#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) -#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) -#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) -#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) -#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) -#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) -#define CKM_SSL3_MD5_MAC (0x380UL) -#define CKM_SSL3_SHA1_MAC (0x381UL) -#define CKM_MD5_KEY_DERIVATION (0x390UL) -#define CKM_MD2_KEY_DERIVATION (0x391UL) -#define CKM_SHA1_KEY_DERIVATION (0x392UL) -#define CKM_PBE_MD2_DES_CBC (0x3a0UL) -#define CKM_PBE_MD5_DES_CBC (0x3a1UL) -#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) -#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) -#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) -#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) -#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) -#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) -#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) -#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) -#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) -#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) -#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) -#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) -#define CKM_PKCS5_PBKD2 (0x3b0UL) -#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) -#define CKM_KEY_WRAP_LYNKS (0x400UL) -#define CKM_KEY_WRAP_SET_OAEP (0x401UL) -#define CKM_SKIPJACK_KEY_GEN (0x1000UL) -#define CKM_SKIPJACK_ECB64 (0x1001UL) -#define CKM_SKIPJACK_CBC64 (0x1002UL) -#define CKM_SKIPJACK_OFB64 (0x1003UL) -#define CKM_SKIPJACK_CFB64 (0x1004UL) -#define CKM_SKIPJACK_CFB32 (0x1005UL) -#define CKM_SKIPJACK_CFB16 (0x1006UL) -#define CKM_SKIPJACK_CFB8 (0x1007UL) -#define CKM_SKIPJACK_WRAP (0x1008UL) -#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) -#define CKM_SKIPJACK_RELAYX (0x100aUL) -#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) -#define CKM_KEA_KEY_DERIVE (0x1011UL) -#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) -#define CKM_BATON_KEY_GEN (0x1030UL) -#define CKM_BATON_ECB128 (0x1031UL) -#define CKM_BATON_ECB96 (0x1032UL) -#define CKM_BATON_CBC128 (0x1033UL) -#define CKM_BATON_COUNTER (0x1034UL) -#define CKM_BATON_SHUFFLE (0x1035UL) -#define CKM_BATON_WRAP (0x1036UL) -#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) -#define CKM_EC_KEY_PAIR_GEN (0x1040UL) -#define CKM_ECDSA (0x1041UL) -#define CKM_ECDSA_SHA1 (0x1042UL) -#define CKM_ECDSA_SHA224 (0x1043UL) -#define CKM_ECDSA_SHA256 (0x1044UL) -#define CKM_ECDSA_SHA384 (0x1045UL) -#define CKM_ECDSA_SHA512 (0x1046UL) -#define CKM_ECDSA_SHA3_224 (0x1047UL) -#define CKM_ECDSA_SHA3_256 (0x1048UL) -#define CKM_ECDSA_SHA3_384 (0x1049UL) -#define CKM_ECDSA_SHA3_512 (0x104AUL) -#define CKM_ECDH1_DERIVE (0x1050UL) -#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) -#define CKM_ECMQV_DERIVE (0x1052UL) -#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL) -#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN (0x1056UL) -#define CKM_EDDSA (0x1057UL) -#define CKM_JUNIPER_KEY_GEN (0x1060UL) -#define CKM_JUNIPER_ECB128 (0x1061UL) -#define CKM_JUNIPER_CBC128 (0x1062UL) -#define CKM_JUNIPER_COUNTER (0x1063UL) -#define CKM_JUNIPER_SHUFFLE (0x1064UL) -#define CKM_JUNIPER_WRAP (0x1065UL) -#define CKM_FASTHASH (0x1070UL) -#define CKM_AES_KEY_GEN (0x1080UL) -#define CKM_AES_ECB (0x1081UL) -#define CKM_AES_CBC (0x1082UL) -#define CKM_AES_MAC (0x1083UL) -#define CKM_AES_MAC_GENERAL (0x1084UL) -#define CKM_AES_CBC_PAD (0x1085UL) -#define CKM_AES_CTR (0x1086UL) -#define CKM_AES_GCM (0x1087UL) -#define CKM_AES_CCM (0x1088UL) -#define CKM_AES_CTS (0x1089UL) -#define CKM_AES_CMAC (0x108AUL) -#define CKM_AES_CMAC_GENERAL (0x108BUL) -#define CKM_AES_XCBC_MAC (0x108CUL) -#define CKM_AES_XCBC_MAC_96 (0x108DUL) -#define CKM_AES_GMAC (0x108EUL) -#define CKM_BLOWFISH_KEY_GEN (0x1090UL) -#define CKM_BLOWFISH_CBC (0x1091UL) -#define CKM_TWOFISH_KEY_GEN (0x1092UL) -#define CKM_TWOFISH_CBC (0x1093UL) -#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) -#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) -#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) -#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) -#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) -#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) -#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) -#define CKM_GOSTR3410 (0x1201UL) -#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) -#define CKM_GOSTR3410_KEY_WRAP (0x1203UL) -#define CKM_GOSTR3410_DERIVE (0x1204UL) -#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) -#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) -#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) -#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) -#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) -#define CKM_GOSTR3411 (0x1210UL) -#define CKM_GOSTR3411_HMAC (0x1211UL) -#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) -#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) -#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) -#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) -#define CKM_GOST28147_KEY_GEN (0x1220UL) -#define CKM_GOST28147_ECB (0x1221UL) -#define CKM_GOST28147 (0x1222UL) -#define CKM_GOST28147_MAC (0x1223UL) -#define CKM_GOST28147_KEY_WRAP (0x1224UL) -#define CKM_CHACHA20_KEY_GEN (0x1225UL) -#define CKM_CHACHA20 (0x1226UL) -#define CKM_POLY1305_KEY_GEN (0x1227UL) -#define CKM_POLY1305 (0x1228UL) - -#define CKM_DSA_PARAMETER_GEN (0x2000UL) -#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) -#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) -#define CKM_AES_OFB (0x2104UL) -#define CKM_AES_CFB64 (0x2105UL) -#define CKM_AES_CFB8 (0x2106UL) -#define CKM_AES_CFB128 (0x2107UL) -#define CKM_AES_CFB1 (0x2108UL) -#define CKM_AES_KEY_WRAP (0x2109UL) -#define CKM_AES_KEY_WRAP_PAD (0x210AUL) -#define CKM_CHACHA20_POLY1305 (0x4021UL) -#define CKM_XEDDSA (0x4029UL) -#define CKM_HKDF_DERIVE (0x402AUL) -#define CKM_HKDF_DATA (0x402BUL) -#define CKM_HKDF_KEY_GEN (0x402CUL) - -#define CKM_VENDOR_DEFINED (1UL << 31) - -struct ck_mechanism -{ - ck_mechanism_type_t mechanism; - void *parameter; - unsigned long parameter_len; +struct CK_OTP_SIGNATURE_INFO { + CK_OTP_PARAM * pParams; + CK_ULONG ulCount; }; +struct CK_PBE_PARAMS { + CK_BYTE * pInitVector; + CK_UTF8CHAR * pPassword; + CK_ULONG ulPasswordLen; + CK_BYTE * pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; +}; -struct ck_mechanism_info -{ - unsigned long min_key_size; - unsigned long max_key_size; - ck_flags_t flags; -}; - -#define CKF_HW (1UL << 0) - -#define CKF_MESSAGE_ENCRYPT (1UL << 1) -#define CKF_MESSAGE_DECRYPT (1UL << 2) -#define CKF_MESSAGE_SIGN (1UL << 3) -#define CKF_MESSAGE_VERIFY (1UL << 4) -#define CKF_MULTI_MESSAGE (1UL << 5) -#define CKF_FIND_OBJECTS (1UL << 6) - -#define CKF_ENCRYPT (1UL << 8) -#define CKF_DECRYPT (1UL << 9) -#define CKF_DIGEST (1UL << 10) -#define CKF_SIGN (1UL << 11) -#define CKF_SIGN_RECOVER (1UL << 12) -#define CKF_VERIFY (1UL << 13) -#define CKF_VERIFY_RECOVER (1UL << 14) -#define CKF_GENERATE (1UL << 15) -#define CKF_GENERATE_KEY_PAIR (1UL << 16) -#define CKF_WRAP (1UL << 17) -#define CKF_UNWRAP (1UL << 18) -#define CKF_DERIVE (1UL << 19) -#define CKF_EXTENSION (1UL << 31) - -#define CKF_EC_F_P (1UL << 20) -#define CKF_EC_F_2M (1UL << 21) -#define CKF_EC_ECPARAMETERS (1UL << 22) -#define CKF_EC_OID (1UL << 23) -#define CKF_EC_NAMEDCURVE CKF_EC_OID -#define CKF_EC_UNCOMPRESS (1UL << 24) -#define CKF_EC_COMPRESS (1UL << 25) -#define CKF_EC_CURVENAME (1UL << 26) - -/* Flags for C_WaitForSlotEvent. */ -#define CKF_DONT_BLOCK (1UL) - -/* Flags for Key derivation */ -#define CKD_NULL (0x1UL) -#define CKD_SHA1_KDF (0x2UL) -#define CKD_SHA224_KDF (0x5UL) -#define CKD_SHA256_KDF (0x6UL) -#define CKD_SHA384_KDF (0x7UL) -#define CKD_SHA512_KDF (0x8UL) - -typedef struct CK_ECDH1_DERIVE_PARAMS { - unsigned long kdf; - unsigned long ulSharedDataLen; - unsigned char * pSharedData; - unsigned long ulPublicDataLen; - unsigned char * pPublicData; -} CK_ECDH1_DERIVE_PARAMS; - -typedef struct CK_ECMQV_DERIVE_PARAMS { - unsigned long kdf; - unsigned long ulSharedDataLen; - unsigned char * pSharedData; - unsigned long ulPublicDataLen; - unsigned char * pPublicData; - unsigned long ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - unsigned long ulPublicDataLen2; - unsigned char * pPublicData2; - CK_OBJECT_HANDLE publicKey; -} CK_ECMQV_DERIVE_PARAMS; - -typedef unsigned long ck_rsa_pkcs_mgf_type_t; -typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; - -typedef unsigned long ck_generator_function_t; - -typedef struct CK_RSA_PKCS_OAEP_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; - void *pSourceData; - unsigned long ulSourceDataLen; -} CK_RSA_PKCS_OAEP_PARAMS; - -typedef struct CK_RSA_PKCS_PSS_PARAMS { - ck_mechanism_type_t hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - unsigned long sLen; -} CK_RSA_PKCS_PSS_PARAMS; - -#define CKG_MGF1_SHA1 (0x00000001UL) -#define CKG_MGF1_SHA224 (0x00000005UL) -#define CKG_MGF1_SHA256 (0x00000002UL) -#define CKG_MGF1_SHA384 (0x00000003UL) -#define CKG_MGF1_SHA512 (0x00000004UL) -#define CKG_MGF1_SHA3_224 (0x00000006UL) -#define CKG_MGF1_SHA3_256 (0x00000007UL) -#define CKG_MGF1_SHA3_384 (0x00000008UL) -#define CKG_MGF1_SHA3_512 (0x00000009UL) - -#define CKZ_DATA_SPECIFIED (0x00000001UL) - -typedef struct CK_GCM_PARAMS { - void * pIv; - unsigned long ulIvLen; - unsigned long ulIvBits; - void * pAAD; - unsigned long ulAADLen; - unsigned long ulTagBits; -} CK_GCM_PARAMS; +struct CK_PKCS5_PBKD2_PARAMS { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + void * pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + void * pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR * pPassword; + CK_ULONG * ulPasswordLen; +}; -/* CKG (GCM) */ -#define CKG_NO_GENERATE (0x00000000UL) -#define CKG_GENERATE (0x00000001UL) -#define CKG_GENERATE_COUNTER (0x00000002UL) -#define CKG_GENERATE_RANDOM (0x00000003UL) -#define CKG_GENERATE_COUNTER_XOR (0x00000004UL) - -typedef struct CK_GCM_MESSAGE_PARAMS { - void *pIv; - unsigned long ulIvLen; - unsigned long ulIvFixedBits; - CK_GENERATOR_FUNCTION ivGenerator; - void *pTag; - unsigned long ulTagBits; -} CK_GCM_MESSAGE_PARAMS; - -typedef struct CK_CCM_PARAMS { - unsigned long ulDataLen; - unsigned char *pNonce; - unsigned long ulNonceLen; - unsigned char *pAAD; - unsigned long ulAADLen; - unsigned long ulMACLen; -} CK_CCM_PARAMS; - -/* EDDSA */ -typedef struct CK_EDDSA_PARAMS { - unsigned char phFlag; - unsigned long ulContextDataLen; - unsigned char *pContextData; -} CK_EDDSA_PARAMS; - -typedef CK_EDDSA_PARAMS *CK_EDDSA_PARAMS_PTR; - -/* XEDDSA */ -typedef struct CK_XEDDSA_PARAMS { - unsigned long hash; -} CK_XEDDSA_PARAMS; - -typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR; - -typedef struct CK_CHACHA20_PARAMS { - unsigned char *pBlockCounter; - unsigned long blockCounterBits; - unsigned char *pNonce; - unsigned long ulNonceBits; -} CK_CHACHA20_PARAMS; - -typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { - unsigned char *pNonce; - unsigned long ulNonceLen; - unsigned char *pAAD; - unsigned long ulAADLen; -} CK_SALSA20_CHACHA20_POLY1305_PARAMS; - -typedef struct CK_AES_CTR_PARAMS { - unsigned long ulCounterBits; - unsigned char cb[16]; -} CK_AES_CTR_PARAMS; - -typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR; - -typedef unsigned long CK_MAC_GENERAL_PARAMS; - -typedef CK_MAC_GENERAL_PARAMS *CK_MAC_GENERAL_PARAMS_PTR; - -typedef unsigned long ck_rv_t; - - -typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, - ck_notification_t event, void *application); - -struct ck_interface { - char * pInterfaceName; - void * pFunctionList; - ck_flags_t flags; -}; - -#define CKF_INTERFACE_FORK_SAFE (0x00000001UL) - -/* Forward reference. */ -struct ck_function_list; -struct ck_function_list_3_0; - -#define _CK_DECLARE_FUNCTION(name, args) \ -typedef ck_rv_t (*CK_ ## name) args; \ -ck_rv_t CK_SPEC name args - -_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); -_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); -_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); -_CK_DECLARE_FUNCTION (C_GetFunctionList, - (struct ck_function_list **function_list)); - -_CK_DECLARE_FUNCTION (C_GetSlotList, - (unsigned char token_present, ck_slot_id_t *slot_list, - unsigned long *count)); -_CK_DECLARE_FUNCTION (C_GetSlotInfo, - (ck_slot_id_t slot_id, struct ck_slot_info *info)); -_CK_DECLARE_FUNCTION (C_GetTokenInfo, - (ck_slot_id_t slot_id, struct ck_token_info *info)); -_CK_DECLARE_FUNCTION (C_WaitForSlotEvent, - (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); -_CK_DECLARE_FUNCTION (C_GetMechanismList, - (ck_slot_id_t slot_id, - ck_mechanism_type_t *mechanism_list, - unsigned long *count)); -_CK_DECLARE_FUNCTION (C_GetMechanismInfo, - (ck_slot_id_t slot_id, ck_mechanism_type_t type, - struct ck_mechanism_info *info)); -_CK_DECLARE_FUNCTION (C_InitToken, - (ck_slot_id_t slot_id, unsigned char *pin, - unsigned long pin_len, unsigned char *label)); -_CK_DECLARE_FUNCTION (C_InitPIN, - (ck_session_handle_t session, unsigned char *pin, - unsigned long pin_len)); -_CK_DECLARE_FUNCTION (C_SetPIN, - (ck_session_handle_t session, unsigned char *old_pin, - unsigned long old_len, unsigned char *new_pin, - unsigned long new_len)); - -_CK_DECLARE_FUNCTION (C_OpenSession, - (ck_slot_id_t slot_id, ck_flags_t flags, - void *application, ck_notify_t notify, - ck_session_handle_t *session)); -_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); -_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); -_CK_DECLARE_FUNCTION (C_GetSessionInfo, - (ck_session_handle_t session, - struct ck_session_info *info)); -_CK_DECLARE_FUNCTION (C_GetOperationState, - (ck_session_handle_t session, - unsigned char *operation_state, - unsigned long *operation_state_len)); -_CK_DECLARE_FUNCTION (C_SetOperationState, - (ck_session_handle_t session, - unsigned char *operation_state, - unsigned long operation_state_len, - ck_object_handle_t encryption_key, - ck_object_handle_t authentication_key)); -_CK_DECLARE_FUNCTION (C_Login, - (ck_session_handle_t session, ck_user_type_t user_type, - unsigned char *pin, unsigned long pin_len)); -_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_CreateObject, - (ck_session_handle_t session, - struct ck_attribute *templ, - unsigned long count, ck_object_handle_t *object)); -_CK_DECLARE_FUNCTION (C_CopyObject, - (ck_session_handle_t session, ck_object_handle_t object, - struct ck_attribute *templ, unsigned long count, - ck_object_handle_t *new_object)); -_CK_DECLARE_FUNCTION (C_DestroyObject, - (ck_session_handle_t session, - ck_object_handle_t object)); -_CK_DECLARE_FUNCTION (C_GetObjectSize, - (ck_session_handle_t session, - ck_object_handle_t object, - unsigned long *size)); -_CK_DECLARE_FUNCTION (C_GetAttributeValue, - (ck_session_handle_t session, - ck_object_handle_t object, - struct ck_attribute *templ, - unsigned long count)); -_CK_DECLARE_FUNCTION (C_SetAttributeValue, - (ck_session_handle_t session, - ck_object_handle_t object, - struct ck_attribute *templ, - unsigned long count)); -_CK_DECLARE_FUNCTION (C_FindObjectsInit, - (ck_session_handle_t session, - struct ck_attribute *templ, - unsigned long count)); -_CK_DECLARE_FUNCTION (C_FindObjects, - (ck_session_handle_t session, - ck_object_handle_t *object, - unsigned long max_object_count, - unsigned long *object_count)); -_CK_DECLARE_FUNCTION (C_FindObjectsFinal, - (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_EncryptInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_Encrypt, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *encrypted_data, - unsigned long *encrypted_data_len)); -_CK_DECLARE_FUNCTION (C_EncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); -_CK_DECLARE_FUNCTION (C_EncryptFinal, - (ck_session_handle_t session, - unsigned char *last_encrypted_part, - unsigned long *last_encrypted_part_len)); - -_CK_DECLARE_FUNCTION (C_DecryptInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_Decrypt, - (ck_session_handle_t session, - unsigned char *encrypted_data, - unsigned long encrypted_data_len, - unsigned char *data, unsigned long *data_len)); -_CK_DECLARE_FUNCTION (C_DecryptUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, unsigned long *part_len)); -_CK_DECLARE_FUNCTION (C_DecryptFinal, - (ck_session_handle_t session, - unsigned char *last_part, - unsigned long *last_part_len)); - -_CK_DECLARE_FUNCTION (C_DigestInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism)); -_CK_DECLARE_FUNCTION (C_Digest, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *digest, - unsigned long *digest_len)); -_CK_DECLARE_FUNCTION (C_DigestUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); -_CK_DECLARE_FUNCTION (C_DigestKey, - (ck_session_handle_t session, ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_DigestFinal, - (ck_session_handle_t session, - unsigned char *digest, - unsigned long *digest_len)); - -_CK_DECLARE_FUNCTION (C_SignInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_Sign, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); -_CK_DECLARE_FUNCTION (C_SignUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); -_CK_DECLARE_FUNCTION (C_SignFinal, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long *signature_len)); -_CK_DECLARE_FUNCTION (C_SignRecoverInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_SignRecover, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); - -_CK_DECLARE_FUNCTION (C_VerifyInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_Verify, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long signature_len)); -_CK_DECLARE_FUNCTION (C_VerifyUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); -_CK_DECLARE_FUNCTION (C_VerifyFinal, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long signature_len)); -_CK_DECLARE_FUNCTION (C_VerifyRecoverInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_VerifyRecover, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long signature_len, - unsigned char *data, - unsigned long *data_len)); - -_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); -_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, - unsigned long *part_len)); -_CK_DECLARE_FUNCTION (C_SignEncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); -_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, - unsigned long *part_len)); - -_CK_DECLARE_FUNCTION (C_GenerateKey, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - struct ck_attribute *templ, - unsigned long count, - ck_object_handle_t *key)); -_CK_DECLARE_FUNCTION (C_GenerateKeyPair, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - struct ck_attribute *public_key_template, - unsigned long public_key_attribute_count, - struct ck_attribute *private_key_template, - unsigned long private_key_attribute_count, - ck_object_handle_t *public_key, - ck_object_handle_t *private_key)); -_CK_DECLARE_FUNCTION (C_WrapKey, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t wrapping_key, - ck_object_handle_t key, - unsigned char *wrapped_key, - unsigned long *wrapped_key_len)); -_CK_DECLARE_FUNCTION (C_UnwrapKey, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t unwrapping_key, - unsigned char *wrapped_key, - unsigned long wrapped_key_len, - struct ck_attribute *templ, - unsigned long attribute_count, - ck_object_handle_t *key)); -_CK_DECLARE_FUNCTION (C_DeriveKey, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t base_key, - struct ck_attribute *templ, - unsigned long attribute_count, - ck_object_handle_t *key)); - -_CK_DECLARE_FUNCTION (C_SeedRandom, - (ck_session_handle_t session, unsigned char *seed, - unsigned long seed_len)); -_CK_DECLARE_FUNCTION (C_GenerateRandom, - (ck_session_handle_t session, - unsigned char *random_data, - unsigned long random_len)); - -_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); -_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_GetInterfaceList, - (struct ck_interface *interfaces_list, - unsigned long *count)); -_CK_DECLARE_FUNCTION (C_GetInterface, - (unsigned char *interface_name, - struct ck_version *version, - struct ck_interface **interface_ptr, - ck_flags_t flags)); - -_CK_DECLARE_FUNCTION (C_LoginUser, - (ck_session_handle_t session, - ck_user_type_t user_type, - unsigned char *pin, - unsigned long pin_len, - unsigned char *username, - unsigned long username_len)); - -_CK_DECLARE_FUNCTION (C_SessionCancel, - (ck_session_handle_t session, - ck_flags_t flags)); - -_CK_DECLARE_FUNCTION (C_MessageEncryptInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_EncryptMessage, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *associated_data, - unsigned long associated_data_len, - unsigned char *plaintext, - unsigned long plaintext_len, - unsigned char *ciphertext, - unsigned long *ciphertext_len)); -_CK_DECLARE_FUNCTION (C_EncryptMessageBegin, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *associated_data, - unsigned long associated_data_len)); -_CK_DECLARE_FUNCTION (C_EncryptMessageNext, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *plaintext_part, - unsigned long plaintext_part_len, - unsigned char *ciphertext_part, - unsigned long *ciphertext_part_len, - ck_flags_t flags)); -_CK_DECLARE_FUNCTION (C_MessageEncryptFinal, - (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_MessageDecryptInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_DecryptMessage, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *associated_data, - unsigned long associated_data_len, - unsigned char *ciphertext, - unsigned long ciphertext_len, - unsigned char *plaintext, - unsigned long *plaintext_len)); -_CK_DECLARE_FUNCTION (C_DecryptMessageBegin, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *associated_data, - unsigned long associated_data_len)); -_CK_DECLARE_FUNCTION (C_DecryptMessageNext, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *ciphertext_part, - unsigned long ciphertext_part_len, - unsigned char *plaintext_part, - unsigned long *plaintext_part_len, - ck_flags_t flags)); -_CK_DECLARE_FUNCTION (C_MessageDecryptFinal, - (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_MessageSignInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_SignMessage, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *data, - unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); -_CK_DECLARE_FUNCTION (C_SignMessageBegin, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len)); -_CK_DECLARE_FUNCTION (C_SignMessageNext, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *data, - unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); -_CK_DECLARE_FUNCTION (C_MessageSignFinal, - (ck_session_handle_t session)); - -_CK_DECLARE_FUNCTION (C_MessageVerifyInit, - (ck_session_handle_t session, - struct ck_mechanism *mechanism, - ck_object_handle_t key)); -_CK_DECLARE_FUNCTION (C_VerifyMessage, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *data, - unsigned long data_len, - unsigned char *signature, - unsigned long signature_len)); -_CK_DECLARE_FUNCTION (C_VerifyMessageBegin, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len)); -_CK_DECLARE_FUNCTION (C_VerifyMessageNext, - (ck_session_handle_t session, - void *parameter, - unsigned long parameter_len, - unsigned char *data, - unsigned long data_len, - unsigned char *signature, - unsigned long signature_len)); -_CK_DECLARE_FUNCTION (C_MessageVerifyFinal, - (ck_session_handle_t session)); - -/* Flags in Message-based encryption/decryption API */ -#define CKF_END_OF_MESSAGE (0x00000001UL) - -struct ck_function_list -{ - struct ck_version version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; -}; - -struct ck_function_list_3_0 -{ - struct ck_version version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; - /* PKCS #11 3.0 functions */ - CK_C_GetInterfaceList C_GetInterfaceList; - CK_C_GetInterface C_GetInterface; - CK_C_LoginUser C_LoginUser; - CK_C_SessionCancel C_SessionCancel; - CK_C_MessageEncryptInit C_MessageEncryptInit; - CK_C_EncryptMessage C_EncryptMessage; - CK_C_EncryptMessageBegin C_EncryptMessageBegin; - CK_C_EncryptMessageNext C_EncryptMessageNext; - CK_C_MessageEncryptFinal C_MessageEncryptFinal; - CK_C_MessageDecryptInit C_MessageDecryptInit; - CK_C_DecryptMessage C_DecryptMessage; - CK_C_DecryptMessageBegin C_DecryptMessageBegin; - CK_C_DecryptMessageNext C_DecryptMessageNext; - CK_C_MessageDecryptFinal C_MessageDecryptFinal; - CK_C_MessageSignInit C_MessageSignInit; - CK_C_SignMessage C_SignMessage; - CK_C_SignMessageBegin C_SignMessageBegin; - CK_C_SignMessageNext C_SignMessageNext; - CK_C_MessageSignFinal C_MessageSignFinal; - CK_C_MessageVerifyInit C_MessageVerifyInit; - CK_C_VerifyMessage C_VerifyMessage; - CK_C_VerifyMessageBegin C_VerifyMessageBegin; - CK_C_VerifyMessageNext C_VerifyMessageNext; - CK_C_MessageVerifyFinal C_MessageVerifyFinal; -}; - - - -typedef ck_rv_t (*ck_createmutex_t) (void **mutex); -typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); -typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); -typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); - - -struct ck_c_initialize_args -{ - ck_createmutex_t create_mutex; - ck_destroymutex_t destroy_mutex; - ck_lockmutex_t lock_mutex; - ck_unlockmutex_t unlock_mutex; - ck_flags_t flags; - void *reserved; -}; - - -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) -#define CKF_OS_LOCKING_OK (1UL << 1) - -#define CKR_OK (0UL) -#define CKR_CANCEL (1UL) -#define CKR_HOST_MEMORY (2UL) -#define CKR_SLOT_ID_INVALID (3UL) -#define CKR_GENERAL_ERROR (5UL) -#define CKR_FUNCTION_FAILED (6UL) -#define CKR_ARGUMENTS_BAD (7UL) -#define CKR_NO_EVENT (8UL) -#define CKR_NEED_TO_CREATE_THREADS (9UL) -#define CKR_CANT_LOCK (0xaUL) -#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) -#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) -#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) -#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) -#define CKR_ACTION_PROHIBITED (0x1BUL) -#define CKR_DATA_INVALID (0x20UL) -#define CKR_DATA_LEN_RANGE (0x21UL) -#define CKR_DEVICE_ERROR (0x30UL) -#define CKR_DEVICE_MEMORY (0x31UL) -#define CKR_DEVICE_REMOVED (0x32UL) -#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) -#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) -#define CKR_FUNCTION_CANCELED (0x50UL) -#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) -#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) -#define CKR_KEY_HANDLE_INVALID (0x60UL) -#define CKR_KEY_SIZE_RANGE (0x62UL) -#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) -#define CKR_KEY_NOT_NEEDED (0x64UL) -#define CKR_KEY_CHANGED (0x65UL) -#define CKR_KEY_NEEDED (0x66UL) -#define CKR_KEY_INDIGESTIBLE (0x67UL) -#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) -#define CKR_KEY_NOT_WRAPPABLE (0x69UL) -#define CKR_KEY_UNEXTRACTABLE (0x6aUL) -#define CKR_MECHANISM_INVALID (0x70UL) -#define CKR_MECHANISM_PARAM_INVALID (0x71UL) -#define CKR_OBJECT_HANDLE_INVALID (0x82UL) -#define CKR_OPERATION_ACTIVE (0x90UL) -#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) -#define CKR_PIN_INCORRECT (0xa0UL) -#define CKR_PIN_INVALID (0xa1UL) -#define CKR_PIN_LEN_RANGE (0xa2UL) -#define CKR_PIN_EXPIRED (0xa3UL) -#define CKR_PIN_LOCKED (0xa4UL) -#define CKR_SESSION_CLOSED (0xb0UL) -#define CKR_SESSION_COUNT (0xb1UL) -#define CKR_SESSION_HANDLE_INVALID (0xb3UL) -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) -#define CKR_SESSION_READ_ONLY (0xb5UL) -#define CKR_SESSION_EXISTS (0xb6UL) -#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) -#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) -#define CKR_SIGNATURE_INVALID (0xc0UL) -#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) -#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) -#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) -#define CKR_TOKEN_NOT_PRESENT (0xe0UL) -#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) -#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) -#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) -#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) -#define CKR_USER_NOT_LOGGED_IN (0x101UL) -#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) -#define CKR_USER_TYPE_INVALID (0x103UL) -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) -#define CKR_USER_TOO_MANY_TYPES (0x105UL) -#define CKR_WRAPPED_KEY_INVALID (0x110UL) -#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) -#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) -#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) -#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) -#define CKR_RANDOM_NO_RNG (0x121UL) -#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) -#define CKR_CURVE_NOT_SUPPORTED (0x140UL) -#define CKR_BUFFER_TOO_SMALL (0x150UL) -#define CKR_SAVED_STATE_INVALID (0x160UL) -#define CKR_INFORMATION_SENSITIVE (0x170UL) -#define CKR_STATE_UNSAVEABLE (0x180UL) -#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) -#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) -#define CKR_MUTEX_BAD (0x1a0UL) -#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) -#define CKR_FUNCTION_REJECTED (0x200UL) -#define CKR_VENDOR_DEFINED (1UL << 31) - - -/* Compatibility layer. */ - -#ifdef CRYPTOKI_COMPAT - -#undef CK_DEFINE_FUNCTION -#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name - -/* For NULL. */ -#include +struct CK_PKCS5_PBKD2_PARAMS2 { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + void * pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + void * pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR * pPassword; + CK_ULONG ulPasswordLen; +}; -typedef unsigned char CK_BYTE; -typedef unsigned char CK_CHAR; -typedef unsigned char CK_UTF8CHAR; -typedef unsigned char CK_BBOOL; -typedef unsigned long int CK_ULONG; -typedef long int CK_LONG; -typedef CK_BYTE *CK_BYTE_PTR; -typedef CK_CHAR *CK_CHAR_PTR; -typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; -typedef CK_ULONG *CK_ULONG_PTR; -typedef void *CK_VOID_PTR; -typedef void **CK_VOID_PTR_PTR; -#define CK_FALSE 0 -#define CK_TRUE 1 -#ifndef CK_DISABLE_TRUE_FALSE -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#endif +struct CK_PRF_DATA_PARAM { + CK_PRF_DATA_TYPE type; + void * pValue; + CK_ULONG ulValueLen; +}; -typedef struct CK_HKDF_PARAMS { - CK_BBOOL bExtract; - CK_BBOOL bExpand; - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulSaltType; - CK_BYTE_PTR pSalt; - CK_ULONG ulSaltLen; - CK_OBJECT_HANDLE hSaltKey; - CK_BYTE_PTR pInfo; - CK_ULONG ulInfoLen; -} CK_HKDF_PARAMS; +struct CK_RC2_CBC_PARAMS { + CK_ULONG ulEffectiveBits; + CK_BYTE iv[8]; +}; -#define CKF_HKDF_SALT_NULL 0x00000001UL -#define CKF_HKDF_SALT_DATA 0x00000002UL -#define CKF_HKDF_SALT_KEY 0x00000004UL +struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG ulEffectiveBits; + CK_ULONG ulMacLength; +}; -typedef struct ck_version CK_VERSION; -typedef struct ck_version *CK_VERSION_PTR; +struct CK_RC5_CBC_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; + CK_BYTE * pIv; + CK_ULONG ulIvLen; +}; -typedef struct ck_info CK_INFO; -typedef struct ck_info *CK_INFO_PTR; +struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; + CK_ULONG ulMacLength; +}; -typedef ck_slot_id_t *CK_SLOT_ID_PTR; +struct CK_RC5_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; +}; + +struct CK_RSA_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_RSA_PKCS_OAEP_PARAMS * pOAEPParams; +}; -typedef struct ck_slot_info CK_SLOT_INFO; -typedef struct ck_slot_info *CK_SLOT_INFO_PTR; +struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + void * pSourceData; + CK_ULONG ulSourceDataLen; +}; + +struct CK_RSA_PKCS_PSS_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_ULONG sLen; +}; -typedef struct ck_token_info CK_TOKEN_INFO; -typedef struct ck_token_info *CK_TOKEN_INFO_PTR; +struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pTag; +}; -typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; +struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; +}; -typedef struct ck_session_info CK_SESSION_INFO; -typedef struct ck_session_info *CK_SESSION_INFO_PTR; +struct CK_SALSA20_PARAMS { + CK_BYTE * pBlockCounter; + CK_BYTE * pNonce; + CK_ULONG ulNonceBits; +}; -typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; +struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; -typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; +struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE * pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE * pRandomA; + CK_BYTE * pPrimeP; + CK_BYTE * pBaseG; + CK_BYTE * pSubprimeQ; +}; -typedef struct ck_attribute CK_ATTRIBUTE; -typedef struct ck_attribute *CK_ATTRIBUTE_PTR; +struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE * pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE * pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE * pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE * pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE * pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE * pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE * pNewRandomA; +}; -typedef struct ck_date CK_DATE; -typedef struct ck_date *CK_DATE_PTR; +struct CK_SP800_108_COUNTER_FORMAT { + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; +}; -typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; +struct CK_SP800_108_DKM_LENGTH_FORMAT { + CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; +}; -typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; +typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; -typedef ck_generator_function_t *CK_GENERATOR_FUNCTION_PTR; +struct CK_SP800_108_FEEDBACK_KDF_PARAMS +{ + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM * pDataParams; + CK_ULONG ulIVLen; + CK_BYTE * pIV; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY * pAdditionalDerivedKeys; +}; -typedef struct ck_mechanism CK_MECHANISM; -typedef struct ck_mechanism *CK_MECHANISM_PTR; +struct CK_SP800_108_KDF_PARAMS +{ + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM * pDataParams; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY * pAdditionalDerivedKeys; +}; -typedef struct ck_mechanism_info CK_MECHANISM_INFO; -typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; +struct CK_X2RATCHET_INITIALIZE_PARAMS { + CK_BYTE * sk; + CK_OBJECT_HANDLE peer_public_prekey; + CK_OBJECT_HANDLE peer_public_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; +}; -typedef struct ck_interface CK_INTERFACE; -typedef struct ck_interface *CK_INTERFACE_PTR; -typedef struct ck_interface **CK_INTERFACE_PTR_PTR; +struct CK_X2RATCHET_RESPOND_PARAMS { + CK_BYTE * sk; + CK_OBJECT_HANDLE own_prekey; + CK_OBJECT_HANDLE initiator_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; +}; -typedef struct ck_function_list CK_FUNCTION_LIST; -typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; -typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; +struct CK_X3DH_INITIATE_PARAMS { + CK_X3DH_KDF_TYPE kdf; + CK_OBJECT_HANDLE pPeer_identity; + CK_OBJECT_HANDLE pPeer_prekey; + CK_BYTE * pPrekey_signature; + CK_BYTE * pOnetime_key; + CK_OBJECT_HANDLE pOwn_identity; + CK_OBJECT_HANDLE pOwn_ephemeral; +}; -typedef struct ck_function_list_3_0 CK_FUNCTION_LIST_3_0; -typedef struct ck_function_list_3_0 *CK_FUNCTION_LIST_3_0_PTR; -typedef struct ck_function_list_3_0 **CK_FUNCTION_LIST_3_0_PTR_PTR; +struct CK_X3DH_RESPOND_PARAMS { + CK_X3DH_KDF_TYPE kdf; + CK_BYTE * pIdentity_id; + CK_BYTE * pPrekey_id; + CK_BYTE * pOnetime_id; + CK_OBJECT_HANDLE pInitiator_identity; + CK_BYTE * pInitiator_ephemeral; +}; -typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; -typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; +struct CK_X9_42_DH1_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; +}; -#define NULL_PTR NULL +struct CK_X9_42_DH2_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; +}; -/* Delete the helper macros defined at the top of the file. */ -#undef ck_flags_t -#undef ck_version +struct CK_X9_42_MQV_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * OtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * PublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * PublicData2; + CK_OBJECT_HANDLE publicKey; +}; -#undef ck_info -#undef cryptoki_version -#undef manufacturer_id -#undef library_description -#undef library_version +struct CK_XEDDSA_PARAMS { + CK_XEDDSA_HASH_TYPE hash; +}; -#undef ck_notification_t -#undef ck_slot_id_t +struct specifiedParams { + CK_HSS_LEVELS levels; + CK_LMS_TYPE lm_type[8]; + CK_LMOTS_TYPE lm_ots_type[8]; +}; -#undef ck_slot_info -#undef slot_description -#undef hardware_version -#undef firmware_version +/* TLS related structure definitions */ +STRUCTDEF(CK_SSL3_KEY_MAT_OUT); +STRUCTDEF(CK_SSL3_KEY_MAT_PARAMS); +STRUCTDEF(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_SSL3_RANDOM_DATA); +STRUCTDEF(CK_TLS_KDF_PARAMS); +STRUCTDEF(CK_TLS_MAC_PARAMS); +STRUCTDEF(CK_TLS_PRF_PARAMS); +STRUCTDEF(CK_TLS12_KEY_MAT_PARAMS); +STRUCTDEF(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_WTLS_KEY_MAT_OUT); +STRUCTDEF(CK_WTLS_KEY_MAT_PARAMS); +STRUCTDEF(CK_WTLS_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_WTLS_PRF_PARAMS); +STRUCTDEF(CK_WTLS_RANDOM_DATA); + +struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE * pIVClient; + CK_BYTE * pIVServer; +}; -#undef ck_token_info -#undef serial_number -#undef max_session_count -#undef session_count -#undef max_rw_session_count -#undef rw_session_count -#undef max_pin_len -#undef min_pin_len -#undef total_public_memory -#undef free_public_memory -#undef total_private_memory -#undef free_private_memory -#undef utc_time +struct CK_SSL3_RANDOM_DATA { + CK_BYTE * pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE * pServerRandom; + CK_ULONG ulServerRandomLen; +}; -#undef ck_session_handle_t -#undef ck_user_type_t -#undef ck_state_t +struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; +}; -#undef ck_session_info -#undef slot_id -#undef device_error +struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION * pVersion; +}; -#undef ck_object_handle_t -#undef ck_object_class_t -#undef ck_hw_feature_type_t -#undef ck_key_type_t -#undef ck_certificate_type_t -#undef ck_attribute_type_t +struct CK_TLS_KDF_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BYTE * pLabel; + CK_ULONG ulLabelLength; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_BYTE * pContextData; + CK_ULONG ulContextDataLength; +}; -#undef ck_attribute -#undef value -#undef value_len +struct CK_TLS_MAC_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulMacLength; + CK_ULONG ulServerOrClient; +}; -#undef ck_date +struct CK_TLS_PRF_PARAMS { + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_BYTE * pLabel; + CK_ULONG ulLabelLen; + CK_BYTE * pOutput; + CK_ULONG * pulOutputLen; +}; -#undef ck_mechanism_type_t +struct CK_TLS12_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; + CK_MECHANISM_TYPE prfHashMechanism; +}; -#undef ck_rsa_pkcs_mgf_type_t +struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION * pVersion; + CK_MECHANISM_TYPE prfHashMechanism; +}; -#undef ck_generator_function_t +struct CK_WTLS_KEY_MAT_OUT { + CK_OBJECT_HANDLE hMacSecret; + CK_OBJECT_HANDLE hKey; + CK_BYTE * pIV; +}; -#undef ck_mechanism -#undef parameter -#undef parameter_len +struct CK_WTLS_RANDOM_DATA { + CK_BYTE * pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE * pServerRandom; + CK_ULONG ulServerRandomLen; +}; -#undef ck_mechanism_info -#undef min_key_size -#undef max_key_size +struct CK_WTLS_KEY_MAT_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_ULONG ulSequenceNumber; + CK_BBOOL bIsExport; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_WTLS_KEY_MAT_OUT * pReturnedKeyMaterial; +}; -#undef ck_rv_t -#undef ck_notify_t +struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_BYTE * pVersion; +}; -#undef ck_interface +struct CK_WTLS_PRF_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_BYTE * pLabel; + CK_ULONG ulLabelLen; + CK_BYTE * pOutput; + CK_ULONG * pulOutputLen; +}; -#undef ck_function_list -#undef ck_function_list_3_0 +/* PKCS11 Functions */ +extern CK_RV C_Initialize(void *); +extern CK_RV C_Finalize(void *); +extern CK_RV C_GetInfo(CK_INFO *); +extern CK_RV C_GetFunctionList(CK_FUNCTION_LIST **); +extern CK_RV C_GetSlotList(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); +extern CK_RV C_GetSlotInfo(CK_SLOT_ID, CK_SLOT_INFO *); +extern CK_RV C_GetTokenInfo(CK_SLOT_ID, CK_TOKEN_INFO *); +extern CK_RV C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE *, CK_ULONG *); +extern CK_RV C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO *); +extern CK_RV C_InitToken(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *); +extern CK_RV C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *, + CK_ULONG); +extern CK_RV C_OpenSession(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, + CK_SESSION_HANDLE *); +extern CK_RV C_CloseSession(CK_SESSION_HANDLE); +extern CK_RV C_CloseAllSessions(CK_SLOT_ID); +extern CK_RV C_GetSessionInfo(CK_SESSION_HANDLE, CK_SESSION_INFO *); +extern CK_RV C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_Logout(CK_SESSION_HANDLE); +extern CK_RV C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +extern CK_RV C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG *); +extern CK_RV C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_ULONG, + CK_ULONG *); +extern CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE); +extern CK_RV C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Encrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Decrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM *); +extern CK_RV C_Digest(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE); +extern CK_RV C_Sign(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_SignFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_SignRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Verify(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +extern CK_RV C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *, + CK_OBJECT_HANDLE *); +extern CK_RV C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +extern CK_RV C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE); +extern CK_RV C_CancelFunction(CK_SESSION_HANDLE); +extern CK_RV C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID *, void *); +extern CK_RV C_GetInterfaceList(CK_INTERFACE *, CK_ULONG *); +extern CK_RV C_GetInterface(CK_UTF8CHAR *, CK_VERSION *, CK_INTERFACE **, + CK_FLAGS); +extern CK_RV C_LoginUser(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_SessionCancel(CK_SESSION_HANDLE, CK_FLAGS); +extern CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_EncryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +extern CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_FLAGS); +extern CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_DecryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +extern CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_FLAGS); +extern CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageSignInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_SignMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); +extern CK_RV C_SignMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); +extern CK_RV C_MessageSignFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_VerifyMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); +extern CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); +extern CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE); + +typedef CK_RV (* CK_C_Initialize)(void *); +typedef CK_RV (* CK_C_Finalize)(void *); +typedef CK_RV (* CK_C_GetInfo)(CK_INFO *); +typedef CK_RV (* CK_C_GetFunctionList)(CK_FUNCTION_LIST **); +typedef CK_RV (* CK_C_GetSlotList)(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); +typedef CK_RV (* CK_C_GetSlotInfo)(CK_SLOT_ID, CK_SLOT_INFO *); +typedef CK_RV (* CK_C_GetTokenInfo)(CK_SLOT_ID, CK_TOKEN_INFO *); +typedef CK_RV (* CK_C_GetMechanismList)(CK_SLOT_ID, CK_MECHANISM_TYPE *, + CK_ULONG *); +typedef CK_RV (* CK_C_GetMechanismInfo)(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO *); +typedef CK_RV (* CK_C_InitToken)(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, + CK_UTF8CHAR *); +typedef CK_RV (* CK_C_InitPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_SetPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, + CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_OpenSession)(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, + CK_SESSION_HANDLE *); +typedef CK_RV (* CK_C_CloseSession)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CloseAllSessions)(CK_SLOT_ID); +typedef CK_RV (* CK_C_GetSessionInfo)(CK_SESSION_HANDLE, CK_SESSION_INFO *); +typedef CK_RV (* CK_C_GetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_SetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Login)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG); +typedef CK_RV (* CK_C_Logout)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CreateObject)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_CopyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DestroyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_GetObjectSize)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ULONG *); +typedef CK_RV (* CK_C_GetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +typedef CK_RV (* CK_C_SetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +typedef CK_RV (* CK_C_FindObjectsInit)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, + CK_ULONG); +typedef CK_RV (* CK_C_FindObjects)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, + CK_ULONG, CK_ULONG *); +typedef CK_RV (* CK_C_FindObjectsFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_EncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Encrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Decrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DigestInit)(CK_SESSION_HANDLE, CK_MECHANISM *); +typedef CK_RV (* CK_C_Digest)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_DigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_DigestKey)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_DigestFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Sign)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_SignUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_SignFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_SignRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_VerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Verify)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_VerifyRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DigestEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptDigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptVerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_GenerateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_GenerateKeyPair)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_WrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_UnwrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DeriveKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_SeedRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_GenerateRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_GetFunctionStatus)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CancelFunction)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_WaitForSlotEvent)(CK_FLAGS, CK_SLOT_ID *, void *); +typedef CK_RV (* CK_C_GetInterfaceList)(CK_INTERFACE *, CK_ULONG *); +typedef CK_RV (* CK_C_GetInterface)(CK_UTF8CHAR *, CK_VERSION *, + CK_INTERFACE **, CK_FLAGS); +typedef CK_RV (* CK_C_LoginUser)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG, CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_SessionCancel)(CK_SESSION_HANDLE, CK_FLAGS); +typedef CK_RV (* CK_C_MessageEncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_EncryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_EncryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *, CK_FLAGS); +typedef CK_RV (* CK_C_MessageEncryptFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageDecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_DecryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_DecryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *, CK_FLAGS); +typedef CK_RV (* CK_C_MessageDecryptFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageSignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_SignMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); +typedef CK_RV (* CK_C_SignMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_MessageSignFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageVerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_VerifyMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_MessageVerifyFinal)(CK_SESSION_HANDLE); + +struct CK_FUNCTION_LIST_3_0 { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; +}; -#undef ck_createmutex_t -#undef ck_destroymutex_t -#undef ck_lockmutex_t -#undef ck_unlockmutex_t +struct CK_FUNCTION_LIST { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; +}; -#undef ck_c_initialize_args -#undef create_mutex -#undef destroy_mutex -#undef lock_mutex -#undef unlock_mutex -#undef reserved +/* + * A mask for new GOST algorithms. + * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html + */ +#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) +#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM -#endif /* CRYPTOKI_COMPAT */ +#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) +#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) +#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) +#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) +#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) +#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) +#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) +#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) diff --git a/src/tests/p11test/p11test_case_interface.c b/src/tests/p11test/p11test_case_interface.c index fa606f2952..c132ed813f 100644 --- a/src/tests/p11test/p11test_case_interface.c +++ b/src/tests/p11test/p11test_case_interface.c @@ -75,11 +75,11 @@ void interface_test(void **state) /* run the rest only if we have 2 interfaces (assume OpenSC) */ if (count == 2) { CK_VERSION version2; - assert_string_equal(interfaces[0].pInterfaceName, "PKCS 11"); + assert_string_equal((char *)interfaces[0].pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interfaces[0].pFunctionList)->major, 3); assert_int_equal(((CK_VERSION *)interfaces[0].pFunctionList)->minor, 0); assert_int_equal(interfaces[0].flags, 0); - assert_string_equal(interfaces[1].pInterfaceName, "PKCS 11"); + assert_string_equal((char *)interfaces[1].pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interfaces[1].pFunctionList)->major, 2); // assert_int_equal(((CK_VERSION *)interfaces[1].pFunctionList)->minor, 20); assert_int_equal(interfaces[1].flags, 0); @@ -88,7 +88,7 @@ void interface_test(void **state) /* GetInterface with NULL name should give us default PKCS 11 one */ rv = C_GetInterface(NULL, NULL, &interface, 0); assert_int_equal(rv, CKR_OK); - assert_string_equal(interface->pInterfaceName, "PKCS 11"); + assert_string_equal((char *)interface->pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->major, 3); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->minor, 0); assert_int_equal(interface->flags, 0); @@ -98,9 +98,9 @@ void interface_test(void **state) /* GetInterface with explicit 3.0 version */ version.major = 3; version.minor = 0; - rv = C_GetInterface((unsigned char *)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_OK); - assert_string_equal(interface->pInterfaceName, "PKCS 11"); + assert_string_equal((char *)interface->pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->major, 3); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->minor, 0); assert_int_equal(interface->flags, 0); @@ -110,9 +110,9 @@ void interface_test(void **state) /* GetInterface the other interface (with explicit 2.x version) */ version.major = 2; /* assumed 2 */ version.minor = version2.minor; - rv = C_GetInterface((unsigned char *)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_OK); - assert_string_equal(interface->pInterfaceName, "PKCS 11"); + assert_string_equal((char *)interface->pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->major, 2); // assert_int_equal(((CK_VERSION *)interface->pFunctionList)->minor, 20); assert_int_equal(interface->flags, 0); @@ -121,17 +121,17 @@ void interface_test(void **state) } /* GetInterface with unknown interface */ - rv = C_GetInterface((unsigned char *)"PKCS 11 other", NULL, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11 other", NULL, &interface, 0); assert_int_equal(rv, CKR_ARGUMENTS_BAD); /* GetInterface with wrong version */ version.major = 4; version.minor = 50; - rv = C_GetInterface((unsigned char *)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_ARGUMENTS_BAD); /* GetInterface with unknown flags */ - rv = C_GetInterface((unsigned char *)"PKCS 11", NULL, &interface, 2); + rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", NULL, &interface, 2); assert_int_equal(rv, CKR_ARGUMENTS_BAD); free(interfaces); From 3f5a5b68020b00974b0fcd0df926738e9b320f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 31 Jul 2025 09:34:03 +0200 Subject: [PATCH 4023/4321] Update PKCS#11 header file to v3.2 --- src/pkcs11/pkcs11.h | 392 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 378 insertions(+), 14 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 254809a86c..fe59782614 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -39,10 +39,12 @@ extern "C" { typedef long int CK_LONG; -/* This file is in the Public Domain */ +/* + * The following part comes from https://github.com/latchset/pkcs11-headers + */ #define CRYPTOKI_VERSION_MAJOR 3 -#define CRYPTOKI_VERSION_MINOR 1 +#define CRYPTOKI_VERSION_MINOR 2 #define CRYPTOKI_VERSION_AMENDMENT 0 /* Basic types */ @@ -81,6 +83,7 @@ ULONGDEF(CK_EC_KDF_TYPE); ULONGDEF(CK_EXTRACT_PARAMS); ULONGDEF(CK_FLAGS); ULONGDEF(CK_GENERATOR_FUNCTION); +ULONGDEF(CK_HEDGE_TYPE); ULONGDEF(CK_HSS_LEVELS); ULONGDEF(CK_HW_FEATURE_TYPE); ULONGDEF(CK_JAVA_MIDP_SECURITY_DOMAIN); @@ -89,6 +92,8 @@ ULONGDEF(CK_LMS_TYPE); ULONGDEF(CK_LMOTS_TYPE); ULONGDEF(CK_MAC_GENERAL_PARAMS); ULONGDEF(CK_MECHANISM_TYPE); +ULONGDEF(CK_ML_DSA_PARAMETER_SET_TYPE); +ULONGDEF(CK_ML_KEM_PARAMETER_SET_TYPE); ULONGDEF(CK_NOTIFICATION); ULONGDEF(CK_OBJECT_CLASS); ULONGDEF(CK_OBJECT_HANDLE); @@ -102,14 +107,21 @@ ULONGDEF(CK_RSA_PKCS_MGF_TYPE); ULONGDEF(CK_RSA_PKCS_OAEP_SOURCE_TYPE); ULONGDEF(CK_RV); ULONGDEF(CK_SESSION_HANDLE); +ULONGDEF(CK_SESSION_VALIDATION_FLAGS_TYPE); +ULONGDEF(CK_SLH_DSA_PARAMETER_SET_TYPE); ULONGDEF(CK_SLOT_ID); ULONGDEF(CK_SP800_108_DKM_LENGTH_METHOD); ULONGDEF(CK_STATE); +ULONGDEF(CK_TRUST); ULONGDEF(CK_USER_TYPE); +ULONGDEF(CK_VALIDATION_AUTHORITY_TYPE); +ULONGDEF(CK_VALIDATION_TYPE); ULONGDEF(CK_X2RATCHET_KDF_TYPE); ULONGDEF(CK_X3DH_KDF_TYPE); ULONGDEF(CK_X9_42_DH_KDF_TYPE); ULONGDEF(CK_XEDDSA_HASH_TYPE); +ULONGDEF(CK_XMSSMT_PARAMETER_SET_TYPE); +ULONGDEF(CK_XMSS_PARAMETER_SET_TYPE); /* domain specific values and constants */ @@ -152,6 +164,7 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CK_SP800_108_COUNTER 0x00000002UL #define CK_SP800_108_DKM_LENGTH 0x00000003UL #define CK_SP800_108_BYTE_ARRAY 0x00000004UL +#define CK_SP800_108_KEY_HANDLE 0x00000005UL /* CK (SP800 DKM) */ #define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL @@ -283,6 +296,33 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKA_HSS_LMS_TYPES 0x0000061AUL #define CKA_HSS_LMOTS_TYPES 0x0000061BUL #define CKA_HSS_KEYS_REMAINING 0x0000061CUL +#define CKA_PARAMETER_SET 0x0000061DUL +#define CKA_OBJECT_VALIDATION_FLAGS 0x0000061EUL +#define CKA_VALIDATION_TYPE 0x0000061FUL +#define CKA_VALIDATION_VERSION 0x00000620UL +#define CKA_VALIDATION_LEVEL 0x00000621UL +#define CKA_VALIDATION_MODULE_ID 0x00000622UL +#define CKA_VALIDATION_FLAG 0x00000623UL +#define CKA_VALIDATION_AUTHORITY_TYPE 0x00000624UL +#define CKA_VALIDATION_COUNTRY 0x00000625UL +#define CKA_VALIDATION_CERTIFICATE_IDENTIFIER 0x00000626UL +#define CKA_VALIDATION_CERTIFICATE_URI 0x00000627UL +#define CKA_VALIDATION_VENDOR_URI 0x00000628UL +#define CKA_VALIDATION_PROFILE 0x00000629UL +#define CKA_ENCAPSULATE_TEMPLATE 0x0000062AUL +#define CKA_DECAPSULATE_TEMPLATE 0x0000062BUL +#define CKA_TRUST_SERVER_AUTH 0x0000062CUL +#define CKA_TRUST_CLIENT_AUTH 0x0000062DUL +#define CKA_TRUST_CODE_SIGNING 0x0000062EUL +#define CKA_TRUST_EMAIL_PROTECTION 0x0000062FUL +#define CKA_TRUST_IPSEC_IKE 0x00000630UL +#define CKA_TRUST_TIME_STAMPING 0x00000631UL +#define CKA_TRUST_OCSP_SIGNING 0x00000632UL +#define CKA_ENCAPSULATE 0x00000633UL +#define CKA_DECAPSULATE 0x00000634UL +#define CKA_HASH_OF_CERTIFICATE 0x00000635UL +#define CKA_PUBLIC_CRC64_VALUE 0x00000636UL +#define CKA_SEED 0x00000637UL #define CKA_VENDOR_DEFINED 0x80000000UL /* Array attributes */ #define CKA_WRAP_TEMPLATE 0x40000211UL @@ -373,6 +413,8 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKF_EC_UNCOMPRESS 0x01000000UL #define CKF_EC_COMPRESS 0x02000000UL #define CKF_EC_CURVENAME 0x04000000UL +#define CKF_ENCAPSULATE 0x10000000UL +#define CKF_DECAPSULATE 0x20000000UL #define CKF_EXTENSION 0x80000000UL /* Deprecated */ #ifdef PKCS11_DEPRECATED @@ -396,6 +438,7 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); /* CKF (session) */ #define CKF_RW_SESSION 0x00000002UL #define CKF_SERIAL_SESSION 0x00000004UL +#define CKF_ASYNC_SESSION 0x00000008UL /* CFK (slot) */ #define CKF_TOKEN_PRESENT 0x00000001UL @@ -422,6 +465,8 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKF_SO_PIN_LOCKED 0x00400000UL #define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL #define CKF_ERROR_STATE 0x01000000UL +#define CKF_SEED_RANDOM_REQUIRED 0x02000000UL +#define CKF_ASYNC_SESSION_SUPPORTED 0x04000000UL /* CKG (GCM) */ #define CKG_NO_GENERATE 0x00000000UL @@ -441,12 +486,17 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKG_MGF1_SHA3_384 0x00000008UL #define CKG_MGF1_SHA3_512 0x00000009UL -/* CKH */ +/* CKH (clock) */ #define CKH_MONOTONIC_COUNTER 0x00000001UL #define CKH_CLOCK 0x00000002UL #define CKH_USER_INTERFACE 0x00000003UL #define CKH_VENDOR_DEFINED 0x80000000UL +/* CKH (hedge type) */ +#define CKH_HEDGE_PREFERRED 0x00000000UL +#define CKH_HEDGE_REQUIRED 0x00000001UL +#define CKH_DETERMINISTIC_REQUIRED 0x00000002UL + /* CKK */ #define CKK_RSA 0x00000000UL #define CKK_DSA 0x00000001UL @@ -509,6 +559,11 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKK_SHA512_256_HMAC 0x00000044UL #define CKK_SHA512_T_HMAC 0x00000045UL #define CKK_HSS 0x00000046UL +#define CKK_XMSS 0x00000047UL +#define CKK_XMSSMT 0x00000048UL +#define CKK_ML_KEM 0x00000049UL +#define CKK_ML_DSA 0x0000004AUL +#define CKK_SLH_DSA 0x0000004BUL #define CKK_VENDOR_DEFINED 0x80000000UL /* Deprecated */ #ifdef PKCS11_DEPRECATED @@ -532,6 +587,7 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_SHA1_RSA_X9_31 0x0000000CUL #define CKM_RSA_PKCS_PSS 0x0000000DUL #define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL +#define CKM_ML_KEM_KEY_PAIR_GEN 0x0000000FUL #define CKM_DSA_KEY_PAIR_GEN 0x00000010UL #define CKM_DSA 0x00000011UL #define CKM_DSA_SHA1 0x00000012UL @@ -539,16 +595,43 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_DSA_SHA256 0x00000014UL #define CKM_DSA_SHA384 0x00000015UL #define CKM_DSA_SHA512 0x00000016UL +#define CKM_ML_KEM 0x00000017UL #define CKM_DSA_SHA3_224 0x00000018UL #define CKM_DSA_SHA3_256 0x00000019UL #define CKM_DSA_SHA3_384 0x0000001AUL #define CKM_DSA_SHA3_512 0x0000001BUL +#define CKM_ML_DSA_KEY_PAIR_GEN 0x0000001CUL +#define CKM_ML_DSA 0x0000001DUL +#define CKM_HASH_ML_DSA 0x0000001FUL #define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL #define CKM_DH_PKCS_DERIVE 0x00000021UL +#define CKM_HASH_ML_DSA_SHA224 0x00000023UL +#define CKM_HASH_ML_DSA_SHA256 0x00000024UL +#define CKM_HASH_ML_DSA_SHA384 0x00000025UL +#define CKM_HASH_ML_DSA_SHA512 0x00000026UL +#define CKM_HASH_ML_DSA_SHA3_224 0x00000027UL +#define CKM_HASH_ML_DSA_SHA3_256 0x00000028UL +#define CKM_HASH_ML_DSA_SHA3_384 0x00000029UL +#define CKM_HASH_ML_DSA_SHA3_512 0x0000002AUL +#define CKM_HASH_ML_DSA_SHAKE128 0x0000002BUL +#define CKM_HASH_ML_DSA_SHAKE256 0x0000002CUL +#define CKM_SLH_DSA_KEY_PAIR_GEN 0x0000002DUL +#define CKM_SLH_DSA 0x0000002EUL #define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL #define CKM_X9_42_DH_DERIVE 0x00000031UL #define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL #define CKM_X9_42_MQV_DERIVE 0x00000033UL +#define CKM_HASH_SLH_DSA 0x00000034UL +#define CKM_HASH_SLH_DSA_SHA224 0x00000036UL +#define CKM_HASH_SLH_DSA_SHA256 0x00000037UL +#define CKM_HASH_SLH_DSA_SHA384 0x00000038UL +#define CKM_HASH_SLH_DSA_SHA512 0x00000039UL +#define CKM_HASH_SLH_DSA_SHA3_224 0x0000003AUL +#define CKM_HASH_SLH_DSA_SHA3_256 0x0000003BUL +#define CKM_HASH_SLH_DSA_SHA3_384 0x0000003CUL +#define CKM_HASH_SLH_DSA_SHA3_512 0x0000003DUL +#define CKM_HASH_SLH_DSA_SHAKE128 0x0000003EUL +#define CKM_HASH_SLH_DSA_SHAKE256 0x0000003FUL #define CKM_SHA256_RSA_PKCS 0x00000040UL #define CKM_SHA384_RSA_PKCS 0x00000041UL #define CKM_SHA512_RSA_PKCS 0x00000042UL @@ -569,6 +652,8 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_SHA512_T_HMAC 0x00000051UL #define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL #define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE 0x00000056UL +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH 0x00000057UL #define CKM_SHA3_256_RSA_PKCS 0x00000060UL #define CKM_SHA3_384_RSA_PKCS 0x00000061UL #define CKM_SHA3_512_RSA_PKCS 0x00000062UL @@ -672,7 +757,6 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_CAST3_MAC_GENERAL 0x00000314UL #define CKM_CAST3_CBC_PAD 0x00000315UL #define CKM_CAST128_KEY_GEN 0x00000320UL -#define CKM_CAST5_ECB 0x00000321UL #define CKM_CAST128_ECB 0x00000321UL #define CKM_CAST128_MAC 0x00000323UL #define CKM_CAST128_CBC 0x00000322UL @@ -878,7 +962,6 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL #define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL #define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL -#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL #define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL #define CKM_DSA_FIPS_G_GEN 0x00002005UL #define CKM_AES_OFB 0x00002104UL @@ -951,10 +1034,18 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_IKE1_EXTENDED_DERIVE 0x00004031UL #define CKM_HSS_KEY_PAIR_GEN 0x00004032UL #define CKM_HSS 0x00004033UL -#define CKM_VENDOR_DEFINED 0x80000000UL +#define CKM_XMSS_KEY_PAIR_GEN 0x00004034UL +#define CKM_XMSSMT_KEY_PAIR_GEN 0x00004035UL +#define CKM_XMSS 0x00004036UL +#define CKM_XMSSMT 0x00004037UL +#define CKM_ECDH_X_AES_KEY_WRAP 0x00004038UL +#define CKM_ECDH_COF_AES_KEY_WRAP 0x00004039UL +#define CKM_PUB_KEY_FROM_PRIV_KEY 0x0000403AUL +#define CKM_VENDOR_DEFINED 0x80000000UL /* Deprecated */ #ifdef PKCS11_DEPRECATED #define CKM_CAST5_KEY_GEN 0x00000320UL +#define CKM_CAST5_ECB 0x00000321UL #define CKM_CAST5_CBC 0x00000322UL #define CKM_CAST5_MAC 0x00000323UL #define CKM_CAST5_MAC_GENERAL 0x00000324UL @@ -962,6 +1053,7 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL #define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL #endif /* CKN */ @@ -979,6 +1071,8 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKO_MECHANISM 0x00000007UL #define CKO_OTP_KEY 0x00000008UL #define CKO_PROFILE 0x00000009UL +#define CKO_VALIDATION 0x0000000AUL +#define CKO_TRUST 0x0000000BUL #define CKO_VENDOR_DEFINED 0x80000000UL /* CKP (profile) */ @@ -1001,6 +1095,30 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL #define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL +/* CKP (ML-DSA) */ +#define CKP_ML_DSA_44 0x00000001UL +#define CKP_ML_DSA_65 0x00000002UL +#define CKP_ML_DSA_87 0x00000003UL + +/* CKP (ML_KEM) */ +#define CKP_ML_KEM_512 0x00000001UL +#define CKP_ML_KEM_768 0x00000002UL +#define CKP_ML_KEM_1024 0x00000003UL + +/* CKP (SLH-DSA) */ +#define CKP_SLH_DSA_SHA2_128S 0x00000001UL +#define CKP_SLH_DSA_SHAKE_128S 0x00000002UL +#define CKP_SLH_DSA_SHA2_128F 0x00000003UL +#define CKP_SLH_DSA_SHAKE_128F 0x00000004UL +#define CKP_SLH_DSA_SHA2_192S 0x00000005UL +#define CKP_SLH_DSA_SHAKE_192S 0x00000006UL +#define CKP_SLH_DSA_SHA2_192F 0x00000007UL +#define CKP_SLH_DSA_SHAKE_192F 0x00000008UL +#define CKP_SLH_DSA_SHA2_256S 0x00000009UL +#define CKP_SLH_DSA_SHAKE_256S 0x0000000AUL +#define CKP_SLH_DSA_SHA2_256F 0x0000000BUL +#define CKP_SLH_DSA_SHAKE_256F 0x0000000CUL + /* CKR */ #define CKR_OK 0x00000000UL #define CKR_CANCEL 0x00000001UL @@ -1100,9 +1218,14 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL #define CKR_OPERATION_CANCEL_FAILED 0x00000202UL #define CKR_KEY_EXHAUSTED 0x00000203UL +#define CKR_PENDING 0x00000204UL +#define CKR_SESSION_ASYNC_NOT_SUPPORTED 0x00000205UL +#define CKR_SEED_RANDOM_REQUIRED 0x00000206UL +#define CKR_OPERATION_NOT_VALIDATED 0x00000207UL +#define CKR_TOKEN_NOT_INITIALIZED 0x00000208UL +#define CKR_PARAMETER_SET_NOT_SUPPORTED 0x00000209UL #define CKR_VENDOR_DEFINED 0x80000000UL - /* CKS */ #define CKS_RO_PUBLIC_SESSION 0UL #define CKS_RO_USER_FUNCTIONS 1UL @@ -1110,11 +1233,33 @@ ULONGDEF(CK_XEDDSA_HASH_TYPE); #define CKS_RW_USER_FUNCTIONS 3UL #define CKS_RW_SO_FUNCTIONS 4UL +/* CKS (validation) */ +#define CKS_LAST_VALIDATION_OK 0x00000001UL + +/* CKT (trust) */ +#define CKT_TRUST_UNKNOWN 0x00000000UL +#define CKT_TRUSTED 0x00000001UL +#define CKT_TRUST_ANCHOR 0x00000002UL +#define CKT_NOT_TRUSTED 0x00000003UL +#define CKT_TRUST_MUST_VERIFY_TRUST 0x00000004UL + /* CKU */ #define CKU_SO 0UL #define CKU_USER 1UL #define CKU_CONTEXT_SPECIFIC 2UL +/* CKV (validation authority) */ +#define CKV_AUTHORITY_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_AUTHORITY_TYPE_NIST_CMVP 0x00000001UL +#define CKV_AUTHORITY_TYPE_COMMON_CRITERIA 0x00000002UL + +/* CKV (validation type) */ +#define CKV_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_TYPE_SOFTWARE 0x00000001UL +#define CKV_TYPE_HARDWARE 0x00000002UL +#define CKV_TYPE_FIRMWARE 0x00000003UL +#define CKV_TYPE_HYBRID 0x00000004UL + /* CKZ (data) */ #define CKZ_DATA_SPECIFIED 0x00000001UL @@ -1134,6 +1279,7 @@ STRUCTDEF(CK_DATE); STRUCTDEF(CK_DERIVED_KEY); STRUCTDEF(CK_FUNCTION_LIST); STRUCTDEF(CK_FUNCTION_LIST_3_0); +STRUCTDEF(CK_FUNCTION_LIST_3_2); STRUCTDEF(CK_INFO); STRUCTDEF(CK_INTERFACE); STRUCTDEF(CK_MECHANISM); @@ -1193,7 +1339,7 @@ struct CK_INFO { }; struct CK_INTERFACE { - CK_CHAR * pInterfaceName; + CK_UTF8CHAR * pInterfaceName; void * pFunctionList; CK_FLAGS flags; }; @@ -1252,10 +1398,12 @@ STRUCTDEF(CK_AES_CCM_PARAMS); STRUCTDEF(CK_AES_CTR_PARAMS); STRUCTDEF(CK_AES_GCM_PARAMS); STRUCTDEF(CK_ARIA_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_ASYNC_DATA); STRUCTDEF(CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS); STRUCTDEF(CK_CAMELLIA_CTR_PARAMS); STRUCTDEF(CK_CCM_MESSAGE_PARAMS); STRUCTDEF(CK_CCM_PARAMS); +STRUCTDEF(CK_CCM_WRAP_PARAMS); STRUCTDEF(CK_CHACHA20_PARAMS); STRUCTDEF(CK_CMS_SIG_PARAMS); STRUCTDEF(CK_DES_CBC_ENCRYPT_DATA_PARAMS); @@ -1267,8 +1415,10 @@ STRUCTDEF(CK_ECMQV_DERIVE_PARAMS); STRUCTDEF(CK_EDDSA_PARAMS); STRUCTDEF(CK_GCM_MESSAGE_PARAMS); STRUCTDEF(CK_GCM_PARAMS); +STRUCTDEF(CK_GCM_WRAP_PARAMS); STRUCTDEF(CK_GOSTR3410_DERIVE_PARAMS); STRUCTDEF(CK_GOSTR3410_KEY_WRAP_PARAMS); +STRUCTDEF(CK_HASH_SIGN_ADDITIONAL_CONTEXT); STRUCTDEF(CK_HKDF_PARAMS); STRUCTDEF(CK_IKE_PRF_DERIVE_PARAMS); STRUCTDEF(CK_IKE1_EXTENDED_DERIVE_PARAMS); @@ -1297,12 +1447,14 @@ STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS); STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_PARAMS); STRUCTDEF(CK_SALSA20_PARAMS); STRUCTDEF(CK_SEED_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_SIGN_ADDITIONAL_CONTEXT); STRUCTDEF(CK_SKIPJACK_PRIVATE_WRAP_PARAMS); STRUCTDEF(CK_SKIPJACK_RELAYX_PARAMS); STRUCTDEF(CK_SP800_108_COUNTER_FORMAT); STRUCTDEF(CK_SP800_108_DKM_LENGTH_FORMAT); STRUCTDEF(CK_SP800_108_FEEDBACK_KDF_PARAMS); STRUCTDEF(CK_SP800_108_KDF_PARAMS); +STRUCTDEF(CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS); STRUCTDEF(CK_X2RATCHET_INITIALIZE_PARAMS); STRUCTDEF(CK_X2RATCHET_RESPOND_PARAMS); STRUCTDEF(CK_X3DH_INITIATE_PARAMS); @@ -1348,6 +1500,14 @@ struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { CK_ULONG length; }; +struct CK_ASYNC_DATA { + CK_ULONG ulVersion; + CK_BYTE * pValue; + CK_ULONG ulValue; + CK_OBJECT_HANDLE hObject; + CK_OBJECT_HANDLE hAdditionalObject; +}; + struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { CK_BYTE iv[16]; CK_BYTE * pData; @@ -1377,6 +1537,16 @@ struct CK_CCM_PARAMS { CK_ULONG ulAADLen; CK_ULONG ulMACLen; }; +struct CK_CCM_WRAP_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; + CK_GENERATOR_FUNCTION nonceGenerator; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; struct CK_CHACHA20_PARAMS { CK_BYTE * pBlockCounter; @@ -1473,6 +1643,16 @@ struct CK_GCM_PARAMS { CK_ULONG ulTagBits; }; +struct CK_GCM_WRAP_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; + struct CK_GOSTR3410_DERIVE_PARAMS { CK_EC_KDF_TYPE kdf; CK_BYTE * pPublicData; @@ -1489,6 +1669,13 @@ struct CK_GOSTR3410_KEY_WRAP_PARAMS { CK_OBJECT_HANDLE hKey; }; +struct CK_HASH_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE * pContext; + CK_ULONG ulContextLen; + CK_MECHANISM_TYPE hash; +}; + struct CK_HKDF_PARAMS { CK_BBOOL bExtract; CK_BBOOL bExpand; @@ -1694,6 +1881,12 @@ struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { CK_ULONG length; }; +struct CK_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE * pContext; + CK_ULONG ulContextLen; +}; + struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { CK_ULONG ulPasswordLen; CK_BYTE * pPassword; @@ -1749,6 +1942,13 @@ struct CK_SP800_108_FEEDBACK_KDF_PARAMS CK_DERIVED_KEY * pAdditionalDerivedKeys; }; +struct CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_BYTE * pSessionHash; + CK_ULONG ulSessionHashLen; + CK_VERSION * pVersion; +}; + struct CK_SP800_108_KDF_PARAMS { CK_SP800_108_PRF_TYPE prfType; @@ -1836,12 +2036,6 @@ struct CK_XEDDSA_PARAMS { CK_XEDDSA_HASH_TYPE hash; }; -struct specifiedParams { - CK_HSS_LEVELS levels; - CK_LMS_TYPE lm_type[8]; - CK_LMOTS_TYPE lm_ots_type[8]; -}; - /* TLS related structure definitions */ STRUCTDEF(CK_SSL3_KEY_MAT_OUT); STRUCTDEF(CK_SSL3_KEY_MAT_PARAMS); @@ -2116,6 +2310,34 @@ extern CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); extern CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); extern CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE); +extern CK_RV C_EncapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *, CK_OBJECT_HANDLE *); +extern CK_RV C_DecapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignature(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE); +extern CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE, + CK_SESSION_VALIDATION_FLAGS_TYPE, + CK_FLAGS *); +extern CK_RV C_AsyncComplete(CK_SESSION_HANDLE, CK_UTF8CHAR *, + CK_ASYNC_DATA *); +extern CK_RV C_AsyncGetID(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); +extern CK_RV C_AsyncJoin(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_BYTE *, + CK_ULONG); +extern CK_RV C_WrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG *, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); typedef CK_RV (* CK_C_Initialize)(void *); typedef CK_RV (* CK_C_Finalize)(void *); @@ -2276,6 +2498,146 @@ typedef CK_RV (* CK_C_VerifyMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); typedef CK_RV (* CK_C_MessageVerifyFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_EncapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DecapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_VerifySignatureInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifySignature)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifySignatureUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifySignatureFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_GetSessionValidationFlags)(CK_SESSION_HANDLE, + CK_SESSION_VALIDATION_FLAGS_TYPE, + CK_FLAGS *); +typedef CK_RV (* CK_C_AsyncComplete)(CK_SESSION_HANDLE, CK_UTF8CHAR *, + CK_ASYNC_DATA *); +typedef CK_RV (* CK_C_AsyncGetID)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); +typedef CK_RV (* CK_C_AsyncJoin)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_WrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG *, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_UnwrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); + +struct CK_FUNCTION_LIST_3_2 { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; + CK_C_EncapsulateKey C_EncapsulateKey; + CK_C_DecapsulateKey C_DecapsulateKey; + CK_C_VerifySignatureInit C_VerifySignatureInit; + CK_C_VerifySignature C_VerifySignature; + CK_C_VerifySignatureUpdate C_VerifySignatureUpdate; + CK_C_VerifySignatureFinal C_VerifySignatureFinal; + CK_C_GetSessionValidationFlags C_GetSessionValidationFlags; + CK_C_AsyncComplete C_AsyncComplete; + CK_C_AsyncGetID C_AsyncGetID; + CK_C_AsyncJoin C_AsyncJoin; + CK_C_WrapKeyAuthenticated C_WrapKeyAuthenticated ; + CK_C_UnwrapKeyAuthenticated C_UnwrapKeyAuthenticated ; +}; struct CK_FUNCTION_LIST_3_0 { CK_VERSION version; @@ -2445,6 +2807,8 @@ struct CK_FUNCTION_LIST { CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; +/* End of header from https://github.com/latchset/pkcs11-headers */ + /* * A mask for new GOST algorithms. * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html From a9d054c1e324dd99fc8cb63c27bf421049dd1a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 31 Jul 2025 09:39:28 +0200 Subject: [PATCH 4024/4321] Adjust NSS-defined attributes --- src/pkcs11/pkcs11-display.c | 149 ++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 9c9b538dda..2ac82aa293 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -29,63 +29,62 @@ #include "pkcs11-display.h" -/* Some Netscape/Mozilla-specific stuff: - * http://www.opensource.apple.com/darwinsource/10.3/SecurityNssAsn1-11/nssDER/Source/pkcs11n.h */ +/* NSS-specific stuff: + * https://github.com/nss-dev/nss/blob/d86f709bb4974d10b343c746b6f89dd1ef80259b/lib/util/pkcs11n.h + */ /* - * Netscape-defined object classes - * + * NSS-defined object classes */ -#define CKO_NETSCAPE 0xCE534350 +#define CKO_NSS 0xCE534350 -#define CKO_NETSCAPE_CRL (CKO_NETSCAPE + 1) -#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2) -#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3) -#define CKO_NETSCAPE_BUILTIN_ROOT_LIST (CKO_NETSCAPE + 4) +#define CKO_NSS_CRL (CKO_NSS + 1) +#define CKO_NSS_SMIME (CKO_NSS + 2) +#define CKO_NSS_TRUST (CKO_NSS + 3) +#define CKO_NSS_BUILTIN_ROOT_LIST (CKO_NSS + 4) /* - * Netscape-defined object attributes - * + * NSS-defined object attributes */ -#define CKA_NETSCAPE 0xCE534350 +#define CKA_NSS 0xCE534350 -#define CKA_NETSCAPE_URL (CKA_NETSCAPE + 1) -#define CKA_NETSCAPE_EMAIL (CKA_NETSCAPE + 2) -#define CKA_NETSCAPE_SMIME_INFO (CKA_NETSCAPE + 3) -#define CKA_NETSCAPE_SMIME_TIMESTAMP (CKA_NETSCAPE + 4) -#define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5) -#define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6) -#define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7) -#define CKA_NETSCAPE_KRL (CKA_NETSCAPE + 8) +#define CKA_NSS_URL (CKA_NSS + 1) +#define CKA_NSS_EMAIL (CKA_NSS + 2) +#define CKA_NSS_SMIME_INFO (CKA_NSS + 3) +#define CKA_NSS_SMIME_TIMESTAMP (CKA_NSS + 4) +#define CKA_NSS_PKCS8_SALT (CKA_NSS + 5) +#define CKA_NSS_PASSWORD_CHECK (CKA_NSS + 6) +#define CKA_NSS_EXPIRES (CKA_NSS + 7) +#define CKA_NSS_KRL (CKA_NSS + 8) -#define CKA_NETSCAPE_PQG_COUNTER (CKA_NETSCAPE + 20) -#define CKA_NETSCAPE_PQG_SEED (CKA_NETSCAPE + 21) -#define CKA_NETSCAPE_PQG_H (CKA_NETSCAPE + 22) -#define CKA_NETSCAPE_PQG_SEED_BITS (CKA_NETSCAPE + 23) +#define CKA_NSS_PQG_COUNTER (CKA_NSS + 20) +#define CKA_NSS_PQG_SEED (CKA_NSS + 21) +#define CKA_NSS_PQG_H (CKA_NSS + 22) +#define CKA_NSS_PQG_SEED_BITS (CKA_NSS + 23) -#define CKA_TRUST (CKA_NETSCAPE + 0x2000) +#define CKA_NSS_TRUST_BASE (CKA_NSS + 0x2000) /* "Usage" key information */ -#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1) -#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2) -#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3) -#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4) -#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5) -#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6) -#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7) +#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_NSS_TRUST_BASE + 1) +#define CKA_TRUST_NON_REPUDIATION (CKA_NSS_TRUST_BASE + 2) +#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 3) +#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 4) +#define CKA_TRUST_KEY_AGREEMENT (CKA_NSS_TRUST_BASE + 5) +#define CKA_TRUST_KEY_CERT_SIGN (CKA_NSS_TRUST_BASE + 6) +#define CKA_TRUST_CRL_SIGN (CKA_NSS_TRUST_BASE + 7) /* "Purpose" trust information */ -#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8) -#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9) -#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10) -#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11) -#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12) -#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13) -#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14) -#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15) -#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100) -#define CKA_CERT_MD5_HASH (CKA_TRUST + 101) +#define CKA_NSS_TRUST_SERVER_AUTH (CKA_NSS_TRUST_BASE + 8) +#define CKA_NSS_TRUST_CLIENT_AUTH (CKA_NSS_TRUST_BASE + 9) +#define CKA_NSS_TRUST_CODE_SIGNING (CKA_NSS_TRUST_BASE + 10) +#define CKA_NSS_TRUST_EMAIL_PROTECTION (CKA_NSS_TRUST_BASE + 11) +#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_NSS_TRUST_BASE + 12) +#define CKA_TRUST_IPSEC_TUNNEL (CKA_NSS_TRUST_BASE + 13) +#define CKA_TRUST_IPSEC_USER (CKA_NSS_TRUST_BASE + 14) +#define CKA_NSS_TRUST_TIME_STAMPING (CKA_NSS_TRUST_BASE + 15) +#define CKA_CERT_SHA1_HASH (CKA_NSS_TRUST_BASE + 100) +#define CKA_CERT_MD5_HASH (CKA_NSS_TRUST_BASE + 101) static char * @@ -255,10 +254,10 @@ static enum_specs ck_cls_s[] = { { CKO_PROFILE , "CKO_PROFILE " }, { CKO_HW_FEATURE , "CKO_HW_FEATURE " }, { CKO_DOMAIN_PARAMETERS, "CKO_DOMAIN_PARAMETERS" }, - { CKO_NETSCAPE_CRL, "CKO_NETSCAPE_CRL " }, - { CKO_NETSCAPE_SMIME , "CKO_NETSCAPE_SMIME " }, - { CKO_NETSCAPE_TRUST, "CKO_NETSCAPE_TRUST " }, - { CKO_NETSCAPE_BUILTIN_ROOT_LIST, "CKO_NETSCAPE_BUILTIN_ROOT_LIST" }, + { CKO_NSS_CRL, "CKO_NSS_CRL " }, + { CKO_NSS_SMIME , "CKO_NSS_SMIME " }, + { CKO_NSS_TRUST, "CKO_NSS_TRUST " }, + { CKO_NSS_BUILTIN_ROOT_LIST, "CKO_NSS_BUILTIN_ROOT_LIST" }, { CKO_VENDOR_DEFINED , "CKO_VENDOR_DEFINED " } }; @@ -849,35 +848,35 @@ type_spec ck_attribute_specs[] = { { CKA_DEFAULT_CMS_ATTRIBUTES, "CKA_DEFAULT_CMS_ATTRIBUTES ", print_generic, NULL }, { CKA_SUPPORTED_CMS_ATTRIBUTES, "CKA_SUPPORTED_CMS_ATTRIBUTES ", print_generic, NULL }, { CKA_ALLOWED_MECHANISMS, "CKA_ALLOWED_MECHANISMS ", print_generic, NULL }, - { CKA_NETSCAPE_URL, "CKA_NETSCAPE_URL(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_EMAIL, "CKA_NETSCAPE_EMAIL(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_SMIME_INFO, "CKA_NETSCAPE_SMIME_INFO(Netsc) ", print_boolean, NULL }, - { CKA_NETSCAPE_SMIME_TIMESTAMP, "CKA_NETSCAPE_SMIME_TIMESTAMP(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PKCS8_SALT, "CKA_NETSCAPE_PKCS8_SALT(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PASSWORD_CHECK, "CKA_NETSCAPE_PASSWORD_CHECK(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_EXPIRES, "CKA_NETSCAPE_EXPIRES(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_KRL, "CKA_NETSCAPE_KRL(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PQG_COUNTER, "CKA_NETSCAPE_PQG_COUNTER(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PQG_SEED, "CKA_NETSCAPE_PQG_SEED(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PQG_H, "CKA_NETSCAPE_PQG_H(Netsc) ", print_generic, NULL }, - { CKA_NETSCAPE_PQG_SEED_BITS, "CKA_NETSCAPE_PQG_SEED_BITS(Netsc) ", print_generic, NULL }, - { CKA_TRUST_DIGITAL_SIGNATURE, "CKA_TRUST_DIGITAL_SIGNATURE(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_NON_REPUDIATION, "CKA_TRUST_NON_REPUDIATION(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_KEY_ENCIPHERMENT, "CKA_TRUST_KEY_ENCIPHERMENT(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_DATA_ENCIPHERMENT, "CKA_TRUST_DATA_ENCIPHERMENT(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_KEY_AGREEMENT, "CKA_TRUST_KEY_AGREEMENT(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_KEY_CERT_SIGN, "CKA_TRUST_KEY_CERT_SIGN(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_CRL_SIGN, "CKA_TRUST_CRL_SIGN(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_SERVER_AUTH, "CKA_TRUST_SERVER_AUTH(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_CLIENT_AUTH, "CKA_TRUST_CLIENT_AUTH(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_CODE_SIGNING, "CKA_TRUST_CODE_SIGNING(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_EMAIL_PROTECTION, "CKA_TRUST_EMAIL_PROTECTION(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_END_SYSTEM, "CKA_TRUST_IPSEC_END_SYSTEM(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_TUNNEL, "CKA_TRUST_IPSEC_TUNNEL(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_USER, "CKA_TRUST_IPSEC_USER(Netsc) ", print_boolean, NULL }, - { CKA_TRUST_TIME_STAMPING, "CKA_TRUST_TIME_STAMPING(Netsc) ", print_boolean, NULL }, - { CKA_CERT_SHA1_HASH, "CKA_CERT_SHA1_HASH(Netsc) ", print_generic, NULL }, - { CKA_CERT_MD5_HASH, "CKA_CERT_MD5_HASH(Netsc) ", print_generic, NULL }, + { CKA_NSS_URL, "CKA_NSS_URL(NSS) ", print_generic, NULL }, + { CKA_NSS_EMAIL, "CKA_NSS_EMAIL(NSS) ", print_generic, NULL }, + { CKA_NSS_SMIME_INFO, "CKA_NSS_SMIME_INFO(NSS) ", print_boolean, NULL }, + { CKA_NSS_SMIME_TIMESTAMP, "CKA_NSS_SMIME_TIMESTAMP(NSS) ", print_generic, NULL }, + { CKA_NSS_PKCS8_SALT, "CKA_NSS_PKCS8_SALT(NSS) ", print_generic, NULL }, + { CKA_NSS_PASSWORD_CHECK, "CKA_NSS_PASSWORD_CHECK(NSS) ", print_generic, NULL }, + { CKA_NSS_EXPIRES, "CKA_NSS_EXPIRES(NSS) ", print_generic, NULL }, + { CKA_NSS_KRL, "CKA_NSS_KRL(NSS) ", print_generic, NULL }, + { CKA_NSS_PQG_COUNTER, "CKA_NSS_PQG_COUNTER(NSS) ", print_generic, NULL }, + { CKA_NSS_PQG_SEED, "CKA_NSS_PQG_SEED(NSS) ", print_generic, NULL }, + { CKA_NSS_PQG_H, "CKA_NSS_PQG_H(NSS) ", print_generic, NULL }, + { CKA_NSS_PQG_SEED_BITS, "CKA_NSS_PQG_SEED_BITS(NSS) ", print_generic, NULL }, + { CKA_TRUST_DIGITAL_SIGNATURE, "CKA_TRUST_DIGITAL_SIGNATURE(NSS) ", print_boolean, NULL }, + { CKA_TRUST_NON_REPUDIATION, "CKA_TRUST_NON_REPUDIATION(NSS) ", print_boolean, NULL }, + { CKA_TRUST_KEY_ENCIPHERMENT, "CKA_TRUST_KEY_ENCIPHERMENT(NSS) ", print_boolean, NULL }, + { CKA_TRUST_DATA_ENCIPHERMENT, "CKA_TRUST_DATA_ENCIPHERMENT(NSS) ", print_boolean, NULL }, + { CKA_TRUST_KEY_AGREEMENT, "CKA_TRUST_KEY_AGREEMENT(NSS) ", print_boolean, NULL }, + { CKA_TRUST_KEY_CERT_SIGN, "CKA_TRUST_KEY_CERT_SIGN(NSS) ", print_boolean, NULL }, + { CKA_TRUST_CRL_SIGN, "CKA_TRUST_CRL_SIGN(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_SERVER_AUTH, "CKA_TRUST_SERVER_AUTH(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_CLIENT_AUTH, "CKA_TRUST_CLIENT_AUTH(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_CODE_SIGNING, "CKA_TRUST_CODE_SIGNING(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_EMAIL_PROTECTION, "CKA_TRUST_EMAIL_PROTECTION(NSS) ", print_boolean, NULL }, + { CKA_TRUST_IPSEC_END_SYSTEM, "CKA_TRUST_IPSEC_END_SYSTEM(NSS) ", print_boolean, NULL }, + { CKA_TRUST_IPSEC_TUNNEL, "CKA_TRUST_IPSEC_TUNNEL(NSS) ", print_boolean, NULL }, + { CKA_TRUST_IPSEC_USER, "CKA_TRUST_IPSEC_USER(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_TIME_STAMPING, "CKA_TRUST_TIME_STAMPING(NSS) ", print_boolean, NULL }, + { CKA_CERT_SHA1_HASH, "CKA_CERT_SHA1_HASH(NSS) ", print_generic, NULL }, + { CKA_CERT_MD5_HASH, "CKA_CERT_MD5_HASH(NSS) ", print_generic, NULL }, }; // clang-format on From e288c69b7f215af2cfd0d3b15f9eaa1b1e21bf26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 5 Aug 2025 10:25:09 +0200 Subject: [PATCH 4025/4321] Update dispaying of name for PKCS#11 values --- src/pkcs11/pkcs11-display.c | 1413 +++++++++++++++++++++++------------ src/pkcs11/pkcs11-display.h | 11 +- 2 files changed, 935 insertions(+), 489 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 2ac82aa293..436258dc01 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -66,25 +66,25 @@ #define CKA_NSS_TRUST_BASE (CKA_NSS + 0x2000) /* "Usage" key information */ -#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_NSS_TRUST_BASE + 1) -#define CKA_TRUST_NON_REPUDIATION (CKA_NSS_TRUST_BASE + 2) -#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 3) -#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 4) -#define CKA_TRUST_KEY_AGREEMENT (CKA_NSS_TRUST_BASE + 5) -#define CKA_TRUST_KEY_CERT_SIGN (CKA_NSS_TRUST_BASE + 6) -#define CKA_TRUST_CRL_SIGN (CKA_NSS_TRUST_BASE + 7) +#define CKA_NSS_TRUST_DIGITAL_SIGNATURE (CKA_NSS_TRUST_BASE + 1) +#define CKA_NSS_TRUST_NON_REPUDIATION (CKA_NSS_TRUST_BASE + 2) +#define CKA_NSS_TRUST_KEY_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 3) +#define CKA_NSS_TRUST_DATA_ENCIPHERMENT (CKA_NSS_TRUST_BASE + 4) +#define CKA_NSS_TRUST_KEY_AGREEMENT (CKA_NSS_TRUST_BASE + 5) +#define CKA_NSS_TRUST_KEY_CERT_SIGN (CKA_NSS_TRUST_BASE + 6) +#define CKA_NSS_TRUST_CRL_SIGN (CKA_NSS_TRUST_BASE + 7) /* "Purpose" trust information */ #define CKA_NSS_TRUST_SERVER_AUTH (CKA_NSS_TRUST_BASE + 8) #define CKA_NSS_TRUST_CLIENT_AUTH (CKA_NSS_TRUST_BASE + 9) #define CKA_NSS_TRUST_CODE_SIGNING (CKA_NSS_TRUST_BASE + 10) #define CKA_NSS_TRUST_EMAIL_PROTECTION (CKA_NSS_TRUST_BASE + 11) -#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_NSS_TRUST_BASE + 12) -#define CKA_TRUST_IPSEC_TUNNEL (CKA_NSS_TRUST_BASE + 13) -#define CKA_TRUST_IPSEC_USER (CKA_NSS_TRUST_BASE + 14) +#define CKA_NSS_TRUST_IPSEC_END_SYSTEM (CKA_NSS_TRUST_BASE + 12) +#define CKA_NSS_TRUST_IPSEC_TUNNEL (CKA_NSS_TRUST_BASE + 13) +#define CKA_NSS_TRUST_IPSEC_USER (CKA_NSS_TRUST_BASE + 14) #define CKA_NSS_TRUST_TIME_STAMPING (CKA_NSS_TRUST_BASE + 15) -#define CKA_CERT_SHA1_HASH (CKA_NSS_TRUST_BASE + 100) -#define CKA_CERT_MD5_HASH (CKA_NSS_TRUST_BASE + 101) +#define CKA_NSS_CERT_SHA1_HASH (CKA_NSS_TRUST_BASE + 100) +#define CKA_NSS_CERT_MD5_HASH (CKA_NSS_TRUST_BASE + 101) static char * @@ -243,336 +243,615 @@ print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR } fprintf(f, "\n"); } +static enum_specs ck_mldsa_s[] = { + {CKP_ML_DSA_44, "CKP_ML_DSA_44"}, + {CKP_ML_DSA_65, "CKP_ML_DSA_65"}, + {CKP_ML_DSA_87, "CKP_ML_DSA_87"}, +}; + +static enum_specs ck_mlkem_s[] = { + {CKP_ML_KEM_512, "CKP_ML_KEM_512"}, + {CKP_ML_KEM_768, "CKP_ML_KEM_768"}, + {CKP_ML_KEM_1024, "CKP_ML_KEM_1024"}, +}; + +static enum_specs ck_slh_dsa_s[] = { + {CKP_SLH_DSA_SHA2_128S, "CKP_SLH_DSA_SHA2_128S"}, + {CKP_SLH_DSA_SHAKE_128S, "CKP_SLH_DSA_SHAKE_128S"}, + {CKP_SLH_DSA_SHA2_128F, "CKP_SLH_DSA_SHA2_128F"}, + {CKP_SLH_DSA_SHAKE_128F, "CKP_SLH_DSA_SHAKE_128F"}, + {CKP_SLH_DSA_SHA2_192S, "CKP_SLH_DSA_SHA2_192S"}, + {CKP_SLH_DSA_SHAKE_192S, "CKP_SLH_DSA_SHAKE_192S"}, + {CKP_SLH_DSA_SHA2_192F, "CKP_SLH_DSA_SHA2_192F"}, + {CKP_SLH_DSA_SHAKE_192F, "CKP_SLH_DSA_SHAKE_192F"}, + {CKP_SLH_DSA_SHA2_256S, "CKP_SLH_DSA_SHA2_256S"}, + {CKP_SLH_DSA_SHAKE_256S, "CKP_SLH_DSA_SHAKE_256S"}, + {CKP_SLH_DSA_SHA2_256F, "CKP_SLH_DSA_SHA2_256F"}, + {CKP_SLH_DSA_SHAKE_256F, "CKP_SLH_DSA_SHAKE_256F"}, +}; // clang-format off static enum_specs ck_cls_s[] = { - { CKO_DATA , "CKO_DATA " }, - { CKO_CERTIFICATE , "CKO_CERTIFICATE " }, - { CKO_PUBLIC_KEY , "CKO_PUBLIC_KEY " }, - { CKO_PRIVATE_KEY , "CKO_PRIVATE_KEY " }, - { CKO_SECRET_KEY , "CKO_SECRET_KEY " }, - { CKO_PROFILE , "CKO_PROFILE " }, - { CKO_HW_FEATURE , "CKO_HW_FEATURE " }, - { CKO_DOMAIN_PARAMETERS, "CKO_DOMAIN_PARAMETERS" }, - { CKO_NSS_CRL, "CKO_NSS_CRL " }, - { CKO_NSS_SMIME , "CKO_NSS_SMIME " }, - { CKO_NSS_TRUST, "CKO_NSS_TRUST " }, - { CKO_NSS_BUILTIN_ROOT_LIST, "CKO_NSS_BUILTIN_ROOT_LIST" }, - { CKO_VENDOR_DEFINED , "CKO_VENDOR_DEFINED " } + {CKO_DATA , "CKO_DATA "}, + {CKO_CERTIFICATE , "CKO_CERTIFICATE "}, + {CKO_PUBLIC_KEY , "CKO_PUBLIC_KEY "}, + {CKO_PRIVATE_KEY , "CKO_PRIVATE_KEY "}, + {CKO_SECRET_KEY , "CKO_SECRET_KEY "}, + {CKO_PROFILE , "CKO_PROFILE "}, + {CKO_HW_FEATURE , "CKO_HW_FEATURE "}, + {CKO_DOMAIN_PARAMETERS , "CKO_DOMAIN_PARAMETERS "}, + {CKO_MECHANISM , "CKO_MECHANISM "}, + {CKO_OTP_KEY , "CKO_OTP_KEY "}, + {CKO_PROFILE , "CKO_PROFILE "}, + {CKO_VALIDATION , "CKO_VALIDATION "}, + {CKO_TRUST , "CKO_TRUST "}, + {CKO_NSS_CRL , "CKO_NSS_CRL "}, + {CKO_NSS_SMIME , "CKO_NSS_SMIME "}, + {CKO_NSS_TRUST , "CKO_NSS_TRUST "}, + {CKO_NSS_BUILTIN_ROOT_LIST, "CKO_NSS_BUILTIN_ROOT_LIST"}, + {CKO_VENDOR_DEFINED , "CKO_VENDOR_DEFINED "} }; enum_specs ck_profile_s[] = { - { CKP_INVALID_ID , "CKP_INVALID_ID " }, - { CKP_BASELINE_PROVIDER , "CKP_BASELINE_PROVIDER " }, - { CKP_EXTENDED_PROVIDER , "CKP_EXTENDED_PROVIDER " }, - { CKP_AUTHENTICATION_TOKEN , "CKP_AUTHENTICATION_TOKEN " }, - { CKP_PUBLIC_CERTIFICATES_TOKEN, "CKP_PUBLIC_CERTIFICATES_TOKEN" }, - { CKP_VENDOR_DEFINED , "CKP_VENDOR_DEFINED " } + {CKP_INVALID_ID , "CKP_INVALID_ID "}, + {CKP_BASELINE_PROVIDER , "CKP_BASELINE_PROVIDER "}, + {CKP_EXTENDED_PROVIDER , "CKP_EXTENDED_PROVIDER "}, + {CKP_AUTHENTICATION_TOKEN , "CKP_AUTHENTICATION_TOKEN "}, + {CKP_PUBLIC_CERTIFICATES_TOKEN, "CKP_PUBLIC_CERTIFICATES_TOKEN"}, + {CKP_COMPLETE_PROVIDER , "CKP_COMPLETE_PROVIDER "}, + {CKP_HKDF_TLS_TOKEN , "CKP_HKDF_TLS_TOKEN "}, + {CKP_VENDOR_DEFINED , "CKP_VENDOR_DEFINED "} }; static enum_specs ck_crt_s[] = { - { CKC_X_509, "CKC_X_509" }, - { CKC_X_509_ATTR_CERT, "CKC_X_509_ATTR_CERT" }, + {CKC_X_509 , "CKC_X_509 "}, + {CKC_X_509_ATTR_CERT, "CKC_X_509_ATTR_CERT"}, + {CKC_WTLS , "CKC_WTLS "}, }; static enum_specs ck_key_s[] = { - { CKK_RSA , "CKK_RSA " }, - { CKK_DSA , "CKK_DSA " }, - { CKK_DH , "CKK_DH " }, - { CKK_EC , "CKK_EC " }, - { CKK_EC_EDWARDS , "CKK_EC_EDWARDS " }, - { CKK_EC_MONTGOMERY , "CKK_EC_MONTOGMERY " }, - { CKK_X9_42_DH , "CKK_X9_42_DH " }, - { CKK_KEA , "CKK_KEA " }, - { CKK_GENERIC_SECRET, "CKK_GENERIC_SECRET " }, - { CKK_RC2 , "CKK_RC2 " }, - { CKK_RC4 , "CKK_RC4 " }, - { CKK_DES , "CKK_DES " }, - { CKK_DES2 , "CKK_DES2 " }, - { CKK_DES3 , "CKK_DES3 " }, - { CKK_CAST , "CKK_CAST " }, - { CKK_CAST3 , "CKK_CAST3 " }, - { CKK_CAST128 , "CKK_CAST128 " }, - { CKK_RC5 , "CKK_RC5 " }, - { CKK_IDEA , "CKK_IDEA " }, - { CKK_SKIPJACK , "CKK_SKIPJACK " }, - { CKK_BATON , "CKK_BATON " }, - { CKK_JUNIPER , "CKK_JUNIPER " }, - { CKK_CDMF , "CKK_CDMF " }, - { CKK_AES , "CKK_AES " }, - { CKK_BLOWFISH , "CKK_BLOWFISH " }, - { CKK_TWOFISH , "CKK_TWOFISH " }, - { CKK_GOSTR3410 , "CKK_GOSTR3410 " }, - { CKK_GOSTR3411 , "CKK_GOSTR3411 " }, - { CKK_GOST28147 , "CKK_GOST28147 " } + {CKK_RSA , "CKK_RSA "}, + {CKK_DSA , "CKK_DSA "}, + {CKK_DH , "CKK_DH "}, + {CKK_EC , "CKK_EC "}, + {CKK_X9_42_DH , "CKK_X9_42_DH "}, + {CKK_KEA , "CKK_KEA "}, + {CKK_GENERIC_SECRET , "CKK_GENERIC_SECRET "}, + {CKK_RC2 , "CKK_RC2 "}, + {CKK_RC4 , "CKK_RC4 "}, + {CKK_DES , "CKK_DES "}, + {CKK_DES2 , "CKK_DES2 "}, + {CKK_DES3 , "CKK_DES3 "}, + {CKK_CAST , "CKK_CAST "}, + {CKK_CAST3 , "CKK_CAST3 "}, + {CKK_CAST128 , "CKK_CAST128 "}, + {CKK_RC5 , "CKK_RC5 "}, + {CKK_IDEA , "CKK_IDEA "}, + {CKK_SKIPJACK , "CKK_SKIPJACK "}, + {CKK_BATON , "CKK_BATON "}, + {CKK_JUNIPER , "CKK_JUNIPER "}, + {CKK_CDMF , "CKK_CDMF "}, + {CKK_AES , "CKK_AES "}, + {CKK_BLOWFISH , "CKK_BLOWFISH "}, + {CKK_TWOFISH , "CKK_TWOFISH "}, + {CKK_SECURID , "CKK_SECURID "}, + {CKK_HOTP , "CKK_HOTP "}, + {CKK_ACTI , "CKK_ACTI "}, + {CKK_CAMELLIA , "CKK_CAMELLIA "}, + {CKK_ARIA , "CKK_ARIA "}, + {CKK_MD5_HMAC , "CKK_MD5_HMAC "}, + {CKK_SHA_1_HMAC , "CKK_SHA_1_HMAC "}, + {CKK_RIPEMD128_HMAC , "CKK_RIPEMD128_HMAC "}, + {CKK_RIPEMD160_HMAC , "CKK_RIPEMD160_HMAC "}, + {CKK_SHA256_HMAC , "CKK_SHA256_HMAC "}, + {CKK_SHA384_HMAC , "CKK_SHA384_HMAC "}, + {CKK_SHA512_HMAC , "CKK_SHA512_HMAC "}, + {CKK_SHA224_HMAC , "CKK_SHA224_HMAC "}, + {CKK_SEED , "CKK_SEED "}, + {CKK_GOSTR3410 , "CKK_GOSTR3410 "}, + {CKK_GOSTR3411 , "CKK_GOSTR3411 "}, + {CKK_GOST28147 , "CKK_GOST28147 "}, + {CKK_CHACHA20 , "CKK_CHACHA20 "}, + {CKK_POLY1305 , "CKK_POLY1305 "}, + {CKK_AES_XTS , "CKK_AES_XTS "}, + {CKK_SHA3_224_HMAC , "CKK_SHA3_224_HMAC "}, + {CKK_SHA3_256_HMAC , "CKK_SHA3_256_HMAC "}, + {CKK_SHA3_384_HMAC , "CKK_SHA3_384_HMAC "}, + {CKK_SHA3_512_HMAC , "CKK_SHA3_512_HMAC "}, + {CKK_BLAKE2B_160_HMAC, "CKK_BLAKE2B_160_HMAC"}, + {CKK_BLAKE2B_256_HMAC, "CKK_BLAKE2B_256_HMAC"}, + {CKK_BLAKE2B_384_HMAC, "CKK_BLAKE2B_384_HMAC"}, + {CKK_BLAKE2B_512_HMAC, "CKK_BLAKE2B_512_HMAC"}, + {CKK_SALSA20 , "CKK_SALSA20 "}, + {CKK_X2RATCHET , "CKK_X2RATCHET "}, + {CKK_EC_EDWARDS , "CKK_EC_EDWARDS "}, + {CKK_EC_MONTGOMERY , "CKK_EC_MONTOGMERY "}, + {CKK_HKDF , "CKK_HKDF "}, + {CKK_SHA512_224_HMAC , "CKK_SHA512_224_HMAC "}, + {CKK_SHA512_256_HMAC , "CKK_SHA512_256_HMAC "}, + {CKK_SHA512_T_HMAC , "CKK_SHA512_T_HMAC "}, + {CKK_HSS , "CKK_HSS "}, + {CKK_XMSS , "CKK_XMSS "}, + {CKK_XMSSMT , "CKK_XMSSMT "}, + {CKK_ML_KEM , "CKK_ML_KEM "}, + {CKK_ML_DSA , "CKK_ML_DSA "}, + {CKK_SLH_DSA , "CKK_SLH_DSA "} }; static enum_specs ck_mec_s[] = { - { CKM_RSA_PKCS_KEY_PAIR_GEN , "CKM_RSA_PKCS_KEY_PAIR_GEN " }, - { CKM_RSA_PKCS , "CKM_RSA_PKCS " }, - { CKM_RSA_9796 , "CKM_RSA_9796 " }, - { CKM_RSA_X_509 , "CKM_RSA_X_509 " }, - { CKM_MD2_RSA_PKCS , "CKM_MD2_RSA_PKCS " }, - { CKM_MD5_RSA_PKCS , "CKM_MD5_RSA_PKCS " }, - { CKM_SHA1_RSA_PKCS , "CKM_SHA1_RSA_PKCS " }, - { CKM_SHA224_RSA_PKCS , "CKM_SHA224_RSA_PKCS " }, - { CKM_SHA256_RSA_PKCS , "CKM_SHA256_RSA_PKCS " }, - { CKM_SHA384_RSA_PKCS , "CKM_SHA384_RSA_PKCS " }, - { CKM_SHA512_RSA_PKCS , "CKM_SHA512_RSA_PKCS " }, - { CKM_SHA3_224_RSA_PKCS , "CKM_SHA3_224_RSA_PKCS " }, - { CKM_SHA3_256_RSA_PKCS , "CKM_SHA3_256_RSA_PKCS " }, - { CKM_SHA3_384_RSA_PKCS , "CKM_SHA3_383_RSA_PKCS " }, - { CKM_SHA3_512_RSA_PKCS , "CKM_SHA3_512_RSA_PKCS " }, - { CKM_RIPEMD128_RSA_PKCS , "CKM_RIPEMD128_RSA_PKCS " }, - { CKM_RIPEMD160_RSA_PKCS , "CKM_RIPEMD160_RSA_PKCS " }, - { CKM_RSA_PKCS_OAEP , "CKM_RSA_PKCS_OAEP " }, - { CKM_RSA_X9_31_KEY_PAIR_GEN , "CKM_RSA_X9_31_KEY_PAIR_GEN " }, - { CKM_RSA_X9_31 , "CKM_RSA_X9_31 " }, - { CKM_SHA1_RSA_X9_31 , "CKM_SHA1_RSA_X9_31 " }, - { CKM_RSA_PKCS_PSS , "CKM_RSA_PKCS_PSS " }, - { CKM_SHA1_RSA_PKCS_PSS , "CKM_SHA1_RSA_PKCS_PSS " }, - { CKM_SHA224_RSA_PKCS_PSS , "CKM_SHA224_RSA_PKCS_PSS " }, - { CKM_SHA256_RSA_PKCS_PSS , "CKM_SHA256_RSA_PKCS_PSS " }, - { CKM_SHA384_RSA_PKCS_PSS , "CKM_SHA384_RSA_PKCS_PSS " }, - { CKM_SHA512_RSA_PKCS_PSS , "CKM_SHA512_RSA_PKCS_PSS " }, - { CKM_SHA3_224_RSA_PKCS_PSS , "CKM_SHA3_224_RSA_PKCS_PSS " }, - { CKM_SHA3_256_RSA_PKCS_PSS , "CKM_SHA3_256_RSA_PKCS_PSS " }, - { CKM_SHA3_384_RSA_PKCS_PSS , "CKM_SHA3_384_RSA_PKCS_PSS " }, - { CKM_SHA3_512_RSA_PKCS_PSS , "CKM_SHA3_512_RSA_PKCS_PSS " }, - { CKM_DSA_KEY_PAIR_GEN , "CKM_DSA_KEY_PAIR_GEN " }, - { CKM_DSA , "CKM_DSA " }, - { CKM_DSA_SHA1 , "CKM_DSA_SHA1 " }, - { CKM_DSA_SHA224 , "CKM_DSA_SHA224 " }, - { CKM_DSA_SHA256 , "CKM_DSA_SHA256 " }, - { CKM_DSA_SHA384 , "CKM_DSA_SHA384 " }, - { CKM_DSA_SHA512 , "CKM_DSA_SHA512 " }, - { CKM_DH_PKCS_KEY_PAIR_GEN , "CKM_DH_PKCS_KEY_PAIR_GEN " }, - { CKM_DH_PKCS_DERIVE , "CKM_DH_PKCS_DERIVE " }, - { CKM_X9_42_DH_KEY_PAIR_GEN , "CKM_X9_42_DH_KEY_PAIR_GEN " }, - { CKM_X9_42_DH_DERIVE , "CKM_X9_42_DH_DERIVE " }, - { CKM_X9_42_DH_HYBRID_DERIVE , "CKM_X9_42_DH_HYBRID_DERIVE " }, - { CKM_X9_42_MQV_DERIVE , "CKM_X9_42_MQV_DERIVE " }, - { CKM_RC2_KEY_GEN , "CKM_RC2_KEY_GEN " }, - { CKM_RC2_ECB , "CKM_RC2_ECB " }, - { CKM_RC2_CBC , "CKM_RC2_CBC " }, - { CKM_RC2_MAC , "CKM_RC2_MAC " }, - { CKM_RC2_MAC_GENERAL , "CKM_RC2_MAC_GENERAL " }, - { CKM_RC2_CBC_PAD , "CKM_RC2_CBC_PAD " }, - { CKM_RC4_KEY_GEN , "CKM_RC4_KEY_GEN " }, - { CKM_RC4 , "CKM_RC4 " }, - { CKM_DES_KEY_GEN , "CKM_DES_KEY_GEN " }, - { CKM_DES_ECB , "CKM_DES_ECB " }, - { CKM_DES_CBC , "CKM_DES_CBC " }, - { CKM_DES_MAC , "CKM_DES_MAC " }, - { CKM_DES_MAC_GENERAL , "CKM_DES_MAC_GENERAL " }, - { CKM_DES_CBC_PAD , "CKM_DES_CBC_PAD " }, - { CKM_DES2_KEY_GEN , "CKM_DES2_KEY_GEN " }, - { CKM_DES3_KEY_GEN , "CKM_DES3_KEY_GEN " }, - { CKM_DES3_ECB , "CKM_DES3_ECB " }, - { CKM_DES3_CBC , "CKM_DES3_CBC " }, - { CKM_DES3_MAC , "CKM_DES3_MAC " }, - { CKM_DES3_MAC_GENERAL , "CKM_DES3_MAC_GENERAL " }, - { CKM_DES3_CBC_PAD , "CKM_DES3_CBC_PAD " }, - { CKM_DES3_CMAC , "CKM_DES3_CMAC " }, - { CKM_CDMF_KEY_GEN , "CKM_CDMF_KEY_GEN " }, - { CKM_CDMF_ECB , "CKM_CDMF_ECB " }, - { CKM_CDMF_CBC , "CKM_CDMF_CBC " }, - { CKM_CDMF_MAC , "CKM_CDMF_MAC " }, - { CKM_CDMF_MAC_GENERAL , "CKM_CDMF_MAC_GENERAL " }, - { CKM_CDMF_CBC_PAD , "CKM_CDMF_CBC_PAD " }, - { CKM_MD2 , "CKM_MD2 " }, - { CKM_MD2_HMAC , "CKM_MD2_HMAC " }, - { CKM_MD2_HMAC_GENERAL , "CKM_MD2_HMAC_GENERAL " }, - { CKM_MD5 , "CKM_MD5 " }, - { CKM_MD5_HMAC , "CKM_MD5_HMAC " }, - { CKM_MD5_HMAC_GENERAL , "CKM_MD5_HMAC_GENERAL " }, - { CKM_SHA_1 , "CKM_SHA_1 " }, - { CKM_SHA_1_HMAC , "CKM_SHA_1_HMAC " }, - { CKM_SHA_1_HMAC_GENERAL , "CKM_SHA_1_HMAC_GENERAL " }, - { CKM_SHA256 , "CKM_SHA256 " }, - { CKM_SHA256_HMAC , "CKM_SHA256_HMAC " }, - { CKM_SHA256_HMAC_GENERAL , "CKM_SHA256_HMAC_GENERAL " }, - { CKM_SHA384 , "CKM_SHA384 " }, - { CKM_SHA384_HMAC , "CKM_SHA384_HMAC " }, - { CKM_SHA384_HMAC_GENERAL , "CKM_SHA384_HMAC_GENERAL " }, - { CKM_SHA512 , "CKM_SHA512 " }, - { CKM_SHA512_HMAC , "CKM_SHA512_HMAC " }, - { CKM_SHA512_HMAC_GENERAL , "CKM_SHA512_HMAC_GENERAL " }, - { CKM_RIPEMD128 , "CKM_RIPEMD128 " }, - { CKM_RIPEMD128_HMAC , "CKM_RIPEMD128_HMAC " }, - { CKM_RIPEMD128_HMAC_GENERAL , "CKM_RIPEMD128_HMAC_GENERAL " }, - { CKM_RIPEMD160 , "CKM_RIPEMD160 " }, - { CKM_RIPEMD160_HMAC , "CKM_RIPEMD160_HMAC " }, - { CKM_RIPEMD160_HMAC_GENERAL , "CKM_RIPEMD160_HMAC_GENERAL " }, - { CKM_SHA224 , "CKM_SHA224 " }, - { CKM_SHA224_HMAC , "CKM_SHA224_HMAC " }, - { CKM_SHA224_HMAC_GENERAL , "CKM_SHA224_HMAC_GENERAL " }, - { CKM_SHA256 , "CKM_SHA256 " }, - { CKM_SHA256_HMAC , "CKM_SHA256_HMAC " }, - { CKM_SHA256_HMAC_GENERAL , "CKM_SHA256_HMAC_GENERAL " }, - { CKM_SHA384 , "CKM_SHA384 " }, - { CKM_SHA384_HMAC , "CKM_SHA384_HMAC " }, - { CKM_SHA384_HMAC_GENERAL , "CKM_SHA384_HMAC_GENERAL " }, - { CKM_CAST_KEY_GEN , "CKM_CAST_KEY_GEN " }, - { CKM_CAST_ECB , "CKM_CAST_ECB " }, - { CKM_CAST_CBC , "CKM_CAST_CBC " }, - { CKM_CAST_MAC , "CKM_CAST_MAC " }, - { CKM_CAST_MAC_GENERAL , "CKM_CAST_MAC_GENERAL " }, - { CKM_CAST_CBC_PAD , "CKM_CAST_CBC_PAD " }, - { CKM_CAST3_KEY_GEN , "CKM_CAST3_KEY_GEN " }, - { CKM_CAST3_ECB , "CKM_CAST3_ECB " }, - { CKM_CAST3_CBC , "CKM_CAST3_CBC " }, - { CKM_CAST3_MAC , "CKM_CAST3_MAC " }, - { CKM_CAST3_MAC_GENERAL , "CKM_CAST3_MAC_GENERAL " }, - { CKM_CAST3_CBC_PAD , "CKM_CAST3_CBC_PAD " }, - { CKM_CAST5_KEY_GEN , "CKM_CAST5_KEY_GEN " }, - { CKM_CAST128_KEY_GEN , "CKM_CAST128_KEY_GEN " }, - { CKM_CAST5_ECB , "CKM_CAST5_ECB " }, - { CKM_CAST128_ECB , "CKM_CAST128_ECB " }, - { CKM_CAST5_CBC , "CKM_CAST5_CBC " }, - { CKM_CAST128_CBC , "CKM_CAST128_CBC " }, - { CKM_CAST5_MAC , "CKM_CAST5_MAC " }, - { CKM_CAST128_MAC , "CKM_CAST128_MAC " }, - { CKM_CAST5_MAC_GENERAL , "CKM_CAST5_MAC_GENERAL " }, - { CKM_CAST128_MAC_GENERAL , "CKM_CAST128_MAC_GENERAL " }, - { CKM_CAST5_CBC_PAD , "CKM_CAST5_CBC_PAD " }, - { CKM_CAST128_CBC_PAD , "CKM_CAST128_CBC_PAD " }, - { CKM_RC5_KEY_GEN , "CKM_RC5_KEY_GEN " }, - { CKM_RC5_ECB , "CKM_RC5_ECB " }, - { CKM_RC5_CBC , "CKM_RC5_CBC " }, - { CKM_RC5_MAC , "CKM_RC5_MAC " }, - { CKM_RC5_MAC_GENERAL , "CKM_RC5_MAC_GENERAL " }, - { CKM_RC5_CBC_PAD , "CKM_RC5_CBC_PAD " }, - { CKM_IDEA_KEY_GEN , "CKM_IDEA_KEY_GEN " }, - { CKM_IDEA_ECB , "CKM_IDEA_ECB " }, - { CKM_IDEA_CBC , "CKM_IDEA_CBC " }, - { CKM_IDEA_MAC , "CKM_IDEA_MAC " }, - { CKM_IDEA_MAC_GENERAL , "CKM_IDEA_MAC_GENERAL " }, - { CKM_IDEA_CBC_PAD , "CKM_IDEA_CBC_PAD " }, - { CKM_GENERIC_SECRET_KEY_GEN , "CKM_GENERIC_SECRET_KEY_GEN " }, - { CKM_CONCATENATE_BASE_AND_KEY , "CKM_CONCATENATE_BASE_AND_KEY " }, - { CKM_CONCATENATE_BASE_AND_DATA, "CKM_CONCATENATE_BASE_AND_DATA" }, - { CKM_CONCATENATE_DATA_AND_BASE, "CKM_CONCATENATE_DATA_AND_BASE" }, - { CKM_XOR_BASE_AND_DATA , "CKM_XOR_BASE_AND_DATA " }, - { CKM_EXTRACT_KEY_FROM_KEY , "CKM_EXTRACT_KEY_FROM_KEY " }, - { CKM_SSL3_PRE_MASTER_KEY_GEN , "CKM_SSL3_PRE_MASTER_KEY_GEN " }, - { CKM_SSL3_MASTER_KEY_DERIVE , "CKM_SSL3_MASTER_KEY_DERIVE " }, - { CKM_SSL3_KEY_AND_MAC_DERIVE , "CKM_SSL3_KEY_AND_MAC_DERIVE " }, - { CKM_SSL3_MASTER_KEY_DERIVE_DH, "CKM_SSL3_MASTER_KEY_DERIVE_DH" }, - { CKM_TLS_PRE_MASTER_KEY_GEN , "CKM_TLS_PRE_MASTER_KEY_GEN " }, - { CKM_TLS_MASTER_KEY_DERIVE , "CKM_TLS_MASTER_KEY_DERIVE " }, - { CKM_TLS_KEY_AND_MAC_DERIVE , "CKM_TLS_KEY_AND_MAC_DERIVE " }, - { CKM_TLS_MASTER_KEY_DERIVE_DH , "CKM_TLS_MASTER_KEY_DERIVE_DH " }, - { CKM_SSL3_MD5_MAC , "CKM_SSL3_MD5_MAC " }, - { CKM_SSL3_SHA1_MAC , "CKM_SSL3_SHA1_MAC " }, - { CKM_MD5_KEY_DERIVATION , "CKM_MD5_KEY_DERIVATION " }, - { CKM_MD2_KEY_DERIVATION , "CKM_MD2_KEY_DERIVATION " }, - { CKM_SHA1_KEY_DERIVATION , "CKM_SHA1_KEY_DERIVATION " }, - { CKM_PBE_MD2_DES_CBC , "CKM_PBE_MD2_DES_CBC " }, - { CKM_PBE_MD5_DES_CBC , "CKM_PBE_MD5_DES_CBC " }, - { CKM_PBE_MD5_CAST_CBC , "CKM_PBE_MD5_CAST_CBC " }, - { CKM_PBE_MD5_CAST3_CBC , "CKM_PBE_MD5_CAST3_CBC " }, - { CKM_PBE_MD5_CAST5_CBC , "CKM_PBE_MD5_CAST5_CBC " }, - { CKM_PBE_MD5_CAST128_CBC , "CKM_PBE_MD5_CAST128_CBC " }, - { CKM_PBE_SHA1_CAST5_CBC , "CKM_PBE_SHA1_CAST5_CBC " }, - { CKM_PBE_SHA1_CAST128_CBC , "CKM_PBE_SHA1_CAST128_CBC " }, - { CKM_PBE_SHA1_RC4_128 , "CKM_PBE_SHA1_RC4_128 " }, - { CKM_PBE_SHA1_RC4_40 , "CKM_PBE_SHA1_RC4_40 " }, - { CKM_PBE_SHA1_DES3_EDE_CBC , "CKM_PBE_SHA1_DES3_EDE_CBC " }, - { CKM_PBE_SHA1_DES2_EDE_CBC , "CKM_PBE_SHA1_DES2_EDE_CBC " }, - { CKM_PBE_SHA1_RC2_128_CBC , "CKM_PBE_SHA1_RC2_128_CBC " }, - { CKM_PBE_SHA1_RC2_40_CBC , "CKM_PBE_SHA1_RC2_40_CBC " }, - { CKM_PKCS5_PBKD2 , "CKM_PKCS5_PBKD2 " }, - { CKM_PBA_SHA1_WITH_SHA1_HMAC , "CKM_PBA_SHA1_WITH_SHA1_HMAC " }, - { CKM_KEY_WRAP_LYNKS , "CKM_KEY_WRAP_LYNKS " }, - { CKM_KEY_WRAP_SET_OAEP , "CKM_KEY_WRAP_SET_OAEP " }, - { CKM_SKIPJACK_KEY_GEN , "CKM_SKIPJACK_KEY_GEN " }, - { CKM_SKIPJACK_ECB64 , "CKM_SKIPJACK_ECB64 " }, - { CKM_SKIPJACK_CBC64 , "CKM_SKIPJACK_CBC64 " }, - { CKM_SKIPJACK_OFB64 , "CKM_SKIPJACK_OFB64 " }, - { CKM_SKIPJACK_CFB64 , "CKM_SKIPJACK_CFB64 " }, - { CKM_SKIPJACK_CFB32 , "CKM_SKIPJACK_CFB32 " }, - { CKM_SKIPJACK_CFB16 , "CKM_SKIPJACK_CFB16 " }, - { CKM_SKIPJACK_CFB8 , "CKM_SKIPJACK_CFB8 " }, - { CKM_SKIPJACK_WRAP , "CKM_SKIPJACK_WRAP " }, - { CKM_SKIPJACK_PRIVATE_WRAP , "CKM_SKIPJACK_PRIVATE_WRAP " }, - { CKM_SKIPJACK_RELAYX , "CKM_SKIPJACK_RELAYX " }, - { CKM_KEA_KEY_PAIR_GEN , "CKM_KEA_KEY_PAIR_GEN " }, - { CKM_KEA_KEY_DERIVE , "CKM_KEA_KEY_DERIVE " }, - { CKM_FORTEZZA_TIMESTAMP , "CKM_FORTEZZA_TIMESTAMP " }, - { CKM_BATON_KEY_GEN , "CKM_BATON_KEY_GEN " }, - { CKM_BATON_ECB128 , "CKM_BATON_ECB128 " }, - { CKM_BATON_ECB96 , "CKM_BATON_ECB96 " }, - { CKM_BATON_CBC128 , "CKM_BATON_CBC128 " }, - { CKM_BATON_COUNTER , "CKM_BATON_COUNTER " }, - { CKM_BATON_SHUFFLE , "CKM_BATON_SHUFFLE " }, - { CKM_BATON_WRAP , "CKM_BATON_WRAP " }, - { CKM_EC_KEY_PAIR_GEN , "CKM_EC_KEY_PAIR_GEN " }, - { CKM_ECDSA , "CKM_ECDSA " }, - { CKM_ECDSA_SHA1 , "CKM_ECDSA_SHA1 " }, - { CKM_ECDSA_SHA224 , "CKM_ECDSA_SHA224 " }, - { CKM_ECDSA_SHA256 , "CKM_ECDSA_SHA256 " }, - { CKM_ECDSA_SHA384 , "CKM_ECDSA_SHA384 " }, - { CKM_ECDSA_SHA512 , "CKM_ECDSA_SHA512 " }, - { CKM_ECDSA_SHA3_224 , "CKM_ECDSA_SHA3_224 " }, - { CKM_ECDSA_SHA3_256 , "CKM_ECDSA_SHA3_256 " }, - { CKM_ECDSA_SHA3_384 , "CKM_ECDSA_SHA3_384 " }, - { CKM_ECDSA_SHA3_512 , "CKM_ECDSA_SHA3_512 " }, - { CKM_ECDH1_DERIVE , "CKM_ECDH1_DERIVE " }, - { CKM_ECDH1_COFACTOR_DERIVE , "CKM_ECDH1_COFACTOR_DERIVE " }, - { CKM_ECMQV_DERIVE , "CKM_ECMQV_DERIVE " }, - { CKM_EDDSA , "CKM_EDDSA " }, - { CKM_XEDDSA , "CKM_XEDDSA " }, - { CKM_JUNIPER_KEY_GEN , "CKM_JUNIPER_KEY_GEN " }, - { CKM_JUNIPER_ECB128 , "CKM_JUNIPER_ECB128 " }, - { CKM_JUNIPER_CBC128 , "CKM_JUNIPER_CBC128 " }, - { CKM_JUNIPER_COUNTER , "CKM_JUNIPER_COUNTER " }, - { CKM_JUNIPER_SHUFFLE , "CKM_JUNIPER_SHUFFLE " }, - { CKM_JUNIPER_WRAP , "CKM_JUNIPER_WRAP " }, - { CKM_FASTHASH , "CKM_FASTHASH " }, - { CKM_AES_KEY_GEN , "CKM_AES_KEY_GEN " }, - { CKM_AES_ECB , "CKM_AES_ECB " }, - { CKM_AES_CBC , "CKM_AES_CBC " }, - { CKM_AES_MAC , "CKM_AES_MAC " }, - { CKM_AES_MAC_GENERAL , "CKM_AES_MAC_GENERAL " }, - { CKM_AES_CBC_PAD , "CKM_AES_CBC_PAD " }, - { CKM_AES_CTR , "CKM_AES_CTR " }, - { CKM_AES_GCM , "CKM_AES_GCM " }, - { CKM_AES_CCM , "CKM_AES_CCM " }, - { CKM_AES_CMAC , "CKM_AES_CMAC " }, - { CKM_AES_CTS , "CKM_AES_CTS " }, - { CKM_AES_OFB , "CKM_AES_OFB " }, - { CKM_AES_CFB64 , "CKM_AES_CFB64 " }, - { CKM_AES_CFB8 , "CKM_AES_CFB8 " }, - { CKM_AES_CFB128 , "CKM_AES_CFB128 " }, - { CKM_AES_CFB1 , "CKM_AES_CFB1 " }, - { CKM_BLOWFISH_KEY_GEN , "CKM_BLOWFISH_KEY_GEN " }, - { CKM_BLOWFISH_CBC , "CKM_BLOWFISH_CBC " }, - { CKM_TWOFISH_KEY_GEN , "CKM_TWOFISH_KEY_GEN " }, - { CKM_TWOFISH_CBC , "CKM_TWOFISH_CBC " }, - { CKM_DES_ECB_ENCRYPT_DATA , "CKM_DES_ECB_ENCRYPT_DATA " }, - { CKM_DES_CBC_ENCRYPT_DATA , "CKM_DES_CBC_ENCRYPT_DATA " }, - { CKM_DES3_ECB_ENCRYPT_DATA , "CKM_DES3_ECB_ENCRYPT_DATA " }, - { CKM_DES3_CBC_ENCRYPT_DATA , "CKM_DES3_CBC_ENCRYPT_DATA " }, - { CKM_AES_ECB_ENCRYPT_DATA , "CKM_AES_ECB_ENCRYPT_DATA " }, - { CKM_AES_CBC_ENCRYPT_DATA , "CKM_AES_CBC_ENCRYPT_DATA " }, - { CKM_GOSTR3410_KEY_PAIR_GEN , "CKM_GOSTR3410_KEY_PAIR_GEN " }, - { CKM_GOSTR3410 , "CKM_GOSTR3410 " }, - { CKM_GOSTR3410_WITH_GOSTR3411 , "CKM_GOSTR3410_WITH_GOSTR3411 " }, - { CKM_GOSTR3410_KEY_WRAP , "CKM_GOSTR3410_KEY_WRAP " }, - { CKM_GOSTR3410_DERIVE , "CKM_GOSTR3410_DERIVE " }, - { CKM_GOSTR3411 , "CKM_GOSTR3411 " }, - { CKM_GOSTR3411_HMAC , "CKM_GOSTR3411_HMAC " }, - { CKM_GOST28147_KEY_GEN , "CKM_GOST28147_KEY_GEN " }, - { CKM_GOST28147_ECB , "CKM_GOST28147_ECB " }, - { CKM_GOST28147 , "CKM_GOST28147 " }, - { CKM_GOST28147_MAC , "CKM_GOST28147_MAC " }, - { CKM_GOST28147_KEY_WRAP , "CKM_GOST28147_KEY_WRAP " }, - { CKM_DSA_PARAMETER_GEN , "CKM_DSA_PARAMETER_GEN " }, - { CKM_DH_PKCS_PARAMETER_GEN , "CKM_DH_PKCS_PARAMETER_GEN " }, - { CKM_X9_42_DH_PARAMETER_GEN , "CKM_X9_42_DH_PARAMETER_GEN " }, - { CKM_AES_KEY_WRAP , "CKM_AES_KEY_WRAP " }, - { CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED " } + {CKM_RSA_PKCS_KEY_PAIR_GEN , "CKM_RSA_PKCS_KEY_PAIR_GEN "}, + {CKM_RSA_PKCS , "CKM_RSA_PKCS "}, + {CKM_RSA_9796 , "CKM_RSA_9796 "}, + {CKM_RSA_X_509 , "CKM_RSA_X_509 "}, + {CKM_MD2_RSA_PKCS , "CKM_MD2_RSA_PKCS "}, + {CKM_MD5_RSA_PKCS , "CKM_MD5_RSA_PKCS "}, + {CKM_SHA1_RSA_PKCS , "CKM_SHA1_RSA_PKCS "}, + {CKM_RIPEMD128_RSA_PKCS , "CKM_RIPEMD128_RSA_PKCS "}, + {CKM_RIPEMD160_RSA_PKCS , "CKM_RIPEMD160_RSA_PKCS "}, + {CKM_RSA_PKCS_OAEP , "CKM_RSA_PKCS_OAEP "}, + {CKM_RSA_X9_31_KEY_PAIR_GEN , "CKM_RSA_X9_31_KEY_PAIR_GEN "}, + {CKM_RSA_X9_31 , "CKM_RSA_X9_31 "}, + {CKM_SHA1_RSA_X9_31 , "CKM_SHA1_RSA_X9_31 "}, + {CKM_RSA_PKCS_PSS , "CKM_RSA_PKCS_PSS "}, + {CKM_SHA1_RSA_PKCS_PSS , "CKM_SHA1_RSA_PKCS_PSS "}, + {CKM_ML_KEM_KEY_PAIR_GEN , "CKM_ML_KEM_KEY_PAIR_GEN "}, + {CKM_DSA_KEY_PAIR_GEN , "CKM_DSA_KEY_PAIR_GEN "}, + {CKM_DSA , "CKM_DSA "}, + {CKM_DSA_SHA1 , "CKM_DSA_SHA1 "}, + {CKM_DSA_SHA224 , "CKM_DSA_SHA224 "}, + {CKM_DSA_SHA256 , "CKM_DSA_SHA256 "}, + {CKM_DSA_SHA384 , "CKM_DSA_SHA384 "}, + {CKM_DSA_SHA512 , "CKM_DSA_SHA512 "}, + {CKM_ML_KEM , "CKM_ML_KEM "}, + {CKM_DSA_SHA3_224 , "CKM_DSA_SHA3_224 "}, + {CKM_DSA_SHA3_256 , "CKM_DSA_SHA3_256 "}, + {CKM_DSA_SHA3_384 , "CKM_DSA_SHA3_384 "}, + {CKM_DSA_SHA3_512 , "CKM_DSA_SHA3_512 "}, + {CKM_ML_DSA_KEY_PAIR_GEN , "CKM_ML_DSA_KEY_PAIR_GEN "}, + {CKM_ML_DSA , "CKM_ML_DSA "}, + {CKM_HASH_ML_DSA , "CKM_HASH_ML_DSA "}, + {CKM_DH_PKCS_KEY_PAIR_GEN , "CKM_DH_PKCS_KEY_PAIR_GEN "}, + {CKM_DH_PKCS_DERIVE , "CKM_DH_PKCS_DERIVE "}, + {CKM_HASH_ML_DSA_SHA224 , "CKM_HASH_ML_DSA_SHA224 "}, + {CKM_HASH_ML_DSA_SHA256 , "CKM_HASH_ML_DSA_SHA256 "}, + {CKM_HASH_ML_DSA_SHA384 , "CKM_HASH_ML_DSA_SHA384 "}, + {CKM_HASH_ML_DSA_SHA512 , "CKM_HASH_ML_DSA_SHA512 "}, + {CKM_HASH_ML_DSA_SHA3_224 , "CKM_HASH_ML_DSA_SHA3_224 "}, + {CKM_HASH_ML_DSA_SHA3_256 , "CKM_HASH_ML_DSA_SHA3_256 "}, + {CKM_HASH_ML_DSA_SHA3_384 , "CKM_HASH_ML_DSA_SHA3_384 "}, + {CKM_HASH_ML_DSA_SHA3_512 , "CKM_HASH_ML_DSA_SHA3_512 "}, + {CKM_HASH_ML_DSA_SHAKE128 , "CKM_HASH_ML_DSA_SHAKE128 "}, + {CKM_HASH_ML_DSA_SHAKE256 , "CKM_HASH_ML_DSA_SHAKE256 "}, + {CKM_SLH_DSA_KEY_PAIR_GEN , "CKM_SLH_DSA_KEY_PAIR_GEN "}, + {CKM_SLH_DSA , "CKM_SLH_DSA "}, + {CKM_X9_42_DH_KEY_PAIR_GEN , "CKM_X9_42_DH_KEY_PAIR_GEN "}, + {CKM_X9_42_DH_DERIVE , "CKM_X9_42_DH_DERIVE "}, + {CKM_X9_42_DH_HYBRID_DERIVE , "CKM_X9_42_DH_HYBRID_DERIVE "}, + {CKM_X9_42_MQV_DERIVE , "CKM_X9_42_MQV_DERIVE "}, + {CKM_HASH_SLH_DSA , "CKM_HASH_SLH_DSA "}, + {CKM_HASH_SLH_DSA_SHA224 , "CKM_HASH_SLH_DSA_SHA224 "}, + {CKM_HASH_SLH_DSA_SHA256 , "CKM_HASH_SLH_DSA_SHA256 "}, + {CKM_HASH_SLH_DSA_SHA384 , "CKM_HASH_SLH_DSA_SHA384 "}, + {CKM_HASH_SLH_DSA_SHA512 , "CKM_HASH_SLH_DSA_SHA512 "}, + {CKM_HASH_SLH_DSA_SHA3_224 , "CKM_HASH_SLH_DSA_SHA3_224 "}, + {CKM_HASH_SLH_DSA_SHA3_256 , "CKM_HASH_SLH_DSA_SHA3_256 "}, + {CKM_HASH_SLH_DSA_SHA3_384 , "CKM_HASH_SLH_DSA_SHA3_384 "}, + {CKM_HASH_SLH_DSA_SHA3_512 , "CKM_HASH_SLH_DSA_SHA3_512 "}, + {CKM_HASH_SLH_DSA_SHAKE128 , "CKM_HASH_SLH_DSA_SHAKE128 "}, + {CKM_HASH_SLH_DSA_SHAKE256 , "CKM_HASH_SLH_DSA_SHAKE256 "}, + {CKM_SHA256_RSA_PKCS , "CKM_SHA256_RSA_PKCS "}, + {CKM_SHA384_RSA_PKCS , "CKM_SHA384_RSA_PKCS "}, + {CKM_SHA512_RSA_PKCS , "CKM_SHA512_RSA_PKCS "}, + {CKM_SHA256_RSA_PKCS_PSS , "CKM_SHA256_RSA_PKCS_PSS "}, + {CKM_SHA384_RSA_PKCS_PSS , "CKM_SHA384_RSA_PKCS_PSS "}, + {CKM_SHA512_RSA_PKCS_PSS , "CKM_SHA512_RSA_PKCS_PSS "}, + {CKM_SHA224_RSA_PKCS , "CKM_SHA224_RSA_PKCS "}, + {CKM_SHA224_RSA_PKCS_PSS , "CKM_SHA224_RSA_PKCS_PSS "}, + {CKM_SHA512_224 , "CKM_SHA512_224 "}, + {CKM_SHA512_224_HMAC , "CKM_SHA512_224_HMAC "}, + {CKM_SHA512_224_HMAC_GENERAL , "CKM_SHA512_224_HMAC_GENERAL "}, + {CKM_SHA512_224_KEY_DERIVATION , "CKM_SHA512_224_KEY_DERIVATION "}, + {CKM_SHA512_256 , "CKM_SHA512_256 "}, + {CKM_SHA512_256 , "CKM_SHA512_256 "}, + {CKM_SHA512_256_HMAC , "CKM_SHA512_256_HMAC "}, + {CKM_SHA512_256_HMAC_GENERAL , "CKM_SHA512_256_HMAC_GENERAL "}, + {CKM_SHA512_256_KEY_DERIVATION , "CKM_SHA512_256_KEY_DERIVATION "}, + {CKM_SHA512_T , "CKM_SHA512_T "}, + {CKM_SHA512_T_HMAC , "CKM_SHA512_T_HMAC "}, + {CKM_SHA512_T_HMAC_GENERAL , "CKM_SHA512_T_HMAC_GENERAL "}, + {CKM_SHA512_T_KEY_DERIVATION , "CKM_SHA512_T_KEY_DERIVATION "}, + {CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE , "CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE "}, + {CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH, "CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH"}, + {CKM_SHA3_256_RSA_PKCS , "CKM_SHA3_256_RSA_PKCS "}, + {CKM_SHA3_384_RSA_PKCS , "CKM_SHA3_383_RSA_PKCS "}, + {CKM_SHA3_512_RSA_PKCS , "CKM_SHA3_512_RSA_PKCS "}, + {CKM_SHA3_256_RSA_PKCS_PSS , "CKM_SHA3_256_RSA_PKCS_PSS "}, + {CKM_SHA3_384_RSA_PKCS_PSS , "CKM_SHA3_384_RSA_PKCS_PSS "}, + {CKM_SHA3_512_RSA_PKCS_PSS , "CKM_SHA3_512_RSA_PKCS_PSS "}, + {CKM_SHA3_224_RSA_PKCS , "CKM_SHA3_224_RSA_PKCS "}, + {CKM_SHA3_224_RSA_PKCS_PSS , "CKM_SHA3_224_RSA_PKCS_PSS "}, + {CKM_RC2_KEY_GEN , "CKM_RC2_KEY_GEN "}, + {CKM_RC2_ECB , "CKM_RC2_ECB "}, + {CKM_RC2_CBC , "CKM_RC2_CBC "}, + {CKM_RC2_MAC , "CKM_RC2_MAC "}, + {CKM_RC2_MAC_GENERAL , "CKM_RC2_MAC_GENERAL "}, + {CKM_RC2_CBC_PAD , "CKM_RC2_CBC_PAD "}, + {CKM_RC4_KEY_GEN , "CKM_RC4_KEY_GEN "}, + {CKM_RC4 , "CKM_RC4 "}, + {CKM_DES_KEY_GEN , "CKM_DES_KEY_GEN "}, + {CKM_DES_ECB , "CKM_DES_ECB "}, + {CKM_DES_CBC , "CKM_DES_CBC "}, + {CKM_DES_MAC , "CKM_DES_MAC "}, + {CKM_DES_MAC_GENERAL , "CKM_DES_MAC_GENERAL "}, + {CKM_DES_CBC_PAD , "CKM_DES_CBC_PAD "}, + {CKM_DES2_KEY_GEN , "CKM_DES2_KEY_GEN "}, + {CKM_DES3_KEY_GEN , "CKM_DES3_KEY_GEN "}, + {CKM_DES3_ECB , "CKM_DES3_ECB "}, + {CKM_DES3_CBC , "CKM_DES3_CBC "}, + {CKM_DES3_MAC , "CKM_DES3_MAC "}, + {CKM_DES3_MAC_GENERAL , "CKM_DES3_MAC_GENERAL "}, + {CKM_DES3_CBC_PAD , "CKM_DES3_CBC_PAD "}, + {CKM_DES3_CMAC , "CKM_DES3_CMAC "}, + {CKM_CDMF_KEY_GEN , "CKM_CDMF_KEY_GEN "}, + {CKM_CDMF_ECB , "CKM_CDMF_ECB "}, + {CKM_CDMF_CBC , "CKM_CDMF_CBC "}, + {CKM_CDMF_MAC , "CKM_CDMF_MAC "}, + {CKM_CDMF_MAC_GENERAL , "CKM_CDMF_MAC_GENERAL "}, + {CKM_CDMF_CBC_PAD , "CKM_CDMF_CBC_PAD "}, + {CKM_DES_OFB64 , "CKM_DES_OFB64 "}, + {CKM_DES_OFB8 , "CKM_DES_OFB8 "}, + {CKM_DES_CFB64 , "CKM_DES_CFB64 "}, + {CKM_DES_CFB8 , "CKM_DES_CFB8 "}, + {CKM_MD2 , "CKM_MD2 "}, + {CKM_MD2_HMAC , "CKM_MD2_HMAC "}, + {CKM_MD2_HMAC_GENERAL , "CKM_MD2_HMAC_GENERAL "}, + {CKM_MD5 , "CKM_MD5 "}, + {CKM_MD5_HMAC , "CKM_MD5_HMAC "}, + {CKM_MD5_HMAC_GENERAL , "CKM_MD5_HMAC_GENERAL "}, + {CKM_SHA_1 , "CKM_SHA_1 "}, + {CKM_SHA_1_HMAC , "CKM_SHA_1_HMAC "}, + {CKM_SHA_1_HMAC_GENERAL , "CKM_SHA_1_HMAC_GENERAL "}, + {CKM_RIPEMD128 , "CKM_RIPEMD128 "}, + {CKM_RIPEMD128_HMAC , "CKM_RIPEMD128_HMAC "}, + {CKM_RIPEMD128_HMAC_GENERAL , "CKM_RIPEMD128_HMAC_GENERAL "}, + {CKM_RIPEMD160 , "CKM_RIPEMD160 "}, + {CKM_RIPEMD160_HMAC , "CKM_RIPEMD160_HMAC "}, + {CKM_RIPEMD160_HMAC_GENERAL , "CKM_RIPEMD160_HMAC_GENERAL "}, + {CKM_SHA256 , "CKM_SHA256 "}, + {CKM_SHA256_HMAC , "CKM_SHA256_HMAC "}, + {CKM_SHA256_HMAC_GENERAL , "CKM_SHA256_HMAC_GENERAL "}, + {CKM_SHA224 , "CKM_SHA224 "}, + {CKM_SHA224_HMAC , "CKM_SHA224_HMAC "}, + {CKM_SHA224_HMAC_GENERAL , "CKM_SHA224_HMAC_GENERAL "}, + {CKM_SHA384 , "CKM_SHA384 "}, + {CKM_SHA384_HMAC , "CKM_SHA384_HMAC "}, + {CKM_SHA384_HMAC_GENERAL , "CKM_SHA384_HMAC_GENERAL "}, + {CKM_SHA512 , "CKM_SHA512 "}, + {CKM_SHA512_HMAC , "CKM_SHA512_HMAC "}, + {CKM_SHA512_HMAC_GENERAL , "CKM_SHA512_HMAC_GENERAL "}, + {CKM_SECURID_KEY_GEN , "CKM_SECURID_KEY_GEN "}, + {CKM_SECURID , "CKM_SECURID "}, + {CKM_HOTP_KEY_GEN , "CKM_HOTP_KEY_GEN "}, + {CKM_HOTP , "CKM_HOTP "}, + {CKM_ACTI , "CKM_ACTI "}, + {CKM_ACTI_KEY_GEN , "CKM_ACTI_KEY_GEN "}, + {CKM_SHA3_256 , "CKM_SHA3_256 "}, + {CKM_SHA3_256_HMAC , "CKM_SHA3_256_HMAC "}, + {CKM_SHA3_256_HMAC_GENERAL , "CKM_SHA3_256_HMAC_GENERAL "}, + {CKM_SHA3_256_KEY_GEN , "CKM_SHA3_256_KEY_GEN "}, + {CKM_SHA3_224 , "CKM_SHA3_224 "}, + {CKM_SHA3_224_HMAC , "CKM_SHA3_224_HMAC "}, + {CKM_SHA3_224_HMAC_GENERAL , "CKM_SHA3_224_HMAC_GENERAL "}, + {CKM_SHA3_224_KEY_GEN , "CKM_SHA3_224_KEY_GEN "}, + {CKM_SHA3_384 , "CKM_SHA3_384 "}, + {CKM_SHA3_384_HMAC , "CKM_SHA3_384_HMAC "}, + {CKM_SHA3_384_HMAC_GENERAL , "CKM_SHA3_384_HMAC_GENERAL "}, + {CKM_SHA3_384_KEY_GEN , "CKM_SHA3_384_KEY_GEN "}, + {CKM_SHA3_512 , "CKM_SHA3_512 "}, + {CKM_SHA3_512_HMAC , "CKM_SHA3_512_HMAC "}, + {CKM_SHA3_512_HMAC_GENERAL , "CKM_SHA3_512_HMAC_GENERAL "}, + {CKM_SHA3_512_KEY_GEN , "CKM_SHA3_512_KEY_GEN "}, + {CKM_CAST_KEY_GEN , "CKM_CAST_KEY_GEN "}, + {CKM_CAST_ECB , "CKM_CAST_ECB "}, + {CKM_CAST_CBC , "CKM_CAST_CBC "}, + {CKM_CAST_MAC , "CKM_CAST_MAC "}, + {CKM_CAST_MAC_GENERAL , "CKM_CAST_MAC_GENERAL "}, + {CKM_CAST_CBC_PAD , "CKM_CAST_CBC_PAD "}, + {CKM_CAST3_KEY_GEN , "CKM_CAST3_KEY_GEN "}, + {CKM_CAST3_ECB , "CKM_CAST3_ECB "}, + {CKM_CAST3_CBC , "CKM_CAST3_CBC "}, + {CKM_CAST3_MAC , "CKM_CAST3_MAC "}, + {CKM_CAST3_MAC_GENERAL , "CKM_CAST3_MAC_GENERAL "}, + {CKM_CAST3_CBC_PAD , "CKM_CAST3_CBC_PAD "}, + {CKM_CAST5_KEY_GEN , "CKM_CAST5_KEY_GEN "}, + {CKM_CAST128_KEY_GEN , "CKM_CAST128_KEY_GEN "}, + {CKM_CAST5_ECB , "CKM_CAST5_ECB "}, + {CKM_CAST128_ECB , "CKM_CAST128_ECB "}, + {CKM_CAST5_CBC , "CKM_CAST5_CBC "}, + {CKM_CAST128_CBC , "CKM_CAST128_CBC "}, + {CKM_CAST5_MAC , "CKM_CAST5_MAC "}, + {CKM_CAST128_MAC , "CKM_CAST128_MAC "}, + {CKM_CAST5_MAC_GENERAL , "CKM_CAST5_MAC_GENERAL "}, + {CKM_CAST128_MAC_GENERAL , "CKM_CAST128_MAC_GENERAL "}, + {CKM_CAST5_CBC_PAD , "CKM_CAST5_CBC_PAD "}, + {CKM_CAST128_CBC_PAD , "CKM_CAST128_CBC_PAD "}, + {CKM_RC5_KEY_GEN , "CKM_RC5_KEY_GEN "}, + {CKM_RC5_ECB , "CKM_RC5_ECB "}, + {CKM_RC5_CBC , "CKM_RC5_CBC "}, + {CKM_RC5_MAC , "CKM_RC5_MAC "}, + {CKM_RC5_MAC_GENERAL , "CKM_RC5_MAC_GENERAL "}, + {CKM_RC5_CBC_PAD , "CKM_RC5_CBC_PAD "}, + {CKM_IDEA_KEY_GEN , "CKM_IDEA_KEY_GEN "}, + {CKM_IDEA_ECB , "CKM_IDEA_ECB "}, + {CKM_IDEA_CBC , "CKM_IDEA_CBC "}, + {CKM_IDEA_MAC , "CKM_IDEA_MAC "}, + {CKM_IDEA_MAC_GENERAL , "CKM_IDEA_MAC_GENERAL "}, + {CKM_IDEA_CBC_PAD , "CKM_IDEA_CBC_PAD "}, + {CKM_GENERIC_SECRET_KEY_GEN , "CKM_GENERIC_SECRET_KEY_GEN "}, + {CKM_CONCATENATE_BASE_AND_KEY , "CKM_CONCATENATE_BASE_AND_KEY "}, + {CKM_CONCATENATE_BASE_AND_DATA , "CKM_CONCATENATE_BASE_AND_DATA "}, + {CKM_CONCATENATE_DATA_AND_BASE , "CKM_CONCATENATE_DATA_AND_BASE "}, + {CKM_XOR_BASE_AND_DATA , "CKM_XOR_BASE_AND_DATA "}, + {CKM_EXTRACT_KEY_FROM_KEY , "CKM_EXTRACT_KEY_FROM_KEY "}, + {CKM_SSL3_PRE_MASTER_KEY_GEN , "CKM_SSL3_PRE_MASTER_KEY_GEN "}, + {CKM_SSL3_MASTER_KEY_DERIVE , "CKM_SSL3_MASTER_KEY_DERIVE "}, + {CKM_SSL3_KEY_AND_MAC_DERIVE , "CKM_SSL3_KEY_AND_MAC_DERIVE "}, + {CKM_SSL3_MASTER_KEY_DERIVE_DH , "CKM_SSL3_MASTER_KEY_DERIVE_DH "}, + {CKM_TLS_PRE_MASTER_KEY_GEN , "CKM_TLS_PRE_MASTER_KEY_GEN "}, + {CKM_TLS_MASTER_KEY_DERIVE , "CKM_TLS_MASTER_KEY_DERIVE "}, + {CKM_TLS_KEY_AND_MAC_DERIVE , "CKM_TLS_KEY_AND_MAC_DERIVE "}, + {CKM_TLS_MASTER_KEY_DERIVE_DH , "CKM_TLS_MASTER_KEY_DERIVE_DH "}, + {CKM_SSL3_MD5_MAC , "CKM_SSL3_MD5_MAC "}, + {CKM_SSL3_SHA1_MAC , "CKM_SSL3_SHA1_MAC "}, + {CKM_MD5_KEY_DERIVATION , "CKM_MD5_KEY_DERIVATION "}, + {CKM_MD2_KEY_DERIVATION , "CKM_MD2_KEY_DERIVATION "}, + {CKM_SHA1_KEY_DERIVATION , "CKM_SHA1_KEY_DERIVATION "}, + {CKM_SHA256_KEY_DERIVATION , "CKM_SHA256_KEY_DERIVATION "}, + {CKM_SHA384_KEY_DERIVATION , "CKM_SHA384_KEY_DERIVATION "}, + {CKM_SHA512_KEY_DERIVATION , "CKM_SHA512_KEY_DERIVATION "}, + {CKM_SHA224_KEY_DERIVATION , "CKM_SHA224_KEY_DERIVATION "}, + {CKM_SHA3_256_KEY_DERIVATION , "CKM_SHA3_256_KEY_DERIVATION "}, + {CKM_SHA3_256_KEY_DERIVE , "CKM_SHA3_256_KEY_DERIVE "}, + {CKM_SHA3_224_KEY_DERIVATION , "CKM_SHA3_224_KEY_DERIVATION "}, + {CKM_SHA3_224_KEY_DERIVE , "CKM_SHA3_224_KEY_DERIVE "}, + {CKM_SHA3_384_KEY_DERIVATION , "CKM_SHA3_384_KEY_DERIVATION "}, + {CKM_SHA3_384_KEY_DERIVE , "CKM_SHA3_384_KEY_DERIVE "}, + {CKM_SHA3_512_KEY_DERIVATION , "CKM_SHA3_512_KEY_DERIVATION "}, + {CKM_SHA3_512_KEY_DERIVE , "CKM_SHA3_512_KEY_DERIVE "}, + {CKM_SHAKE_128_KEY_DERIVATION , "CKM_SHAKE_128_KEY_DERIVATION "}, + {CKM_SHAKE_128_KEY_DERIVE , "CKM_SHAKE_128_KEY_DERIVE "}, + {CKM_SHAKE_256_KEY_DERIVATION , "CKM_SHAKE_256_KEY_DERIVATION "}, + {CKM_SHAKE_256_KEY_DERIVE , "CKM_SHAKE_256_KEY_DERIVE "}, + {CKM_PBE_MD2_DES_CBC , "CKM_PBE_MD2_DES_CBC "}, + {CKM_PBE_MD5_DES_CBC , "CKM_PBE_MD5_DES_CBC "}, + {CKM_PBE_MD5_CAST_CBC , "CKM_PBE_MD5_CAST_CBC "}, + {CKM_PBE_MD5_CAST3_CBC , "CKM_PBE_MD5_CAST3_CBC "}, + {CKM_PBE_MD5_CAST5_CBC , "CKM_PBE_MD5_CAST5_CBC "}, + {CKM_PBE_MD5_CAST128_CBC , "CKM_PBE_MD5_CAST128_CBC "}, + {CKM_PBE_SHA1_CAST5_CBC , "CKM_PBE_SHA1_CAST5_CBC "}, + {CKM_PBE_SHA1_CAST128_CBC , "CKM_PBE_SHA1_CAST128_CBC "}, + {CKM_PBE_SHA1_RC4_128 , "CKM_PBE_SHA1_RC4_128 "}, + {CKM_PBE_SHA1_RC4_40 , "CKM_PBE_SHA1_RC4_40 "}, + {CKM_PBE_SHA1_DES3_EDE_CBC , "CKM_PBE_SHA1_DES3_EDE_CBC "}, + {CKM_PBE_SHA1_DES2_EDE_CBC , "CKM_PBE_SHA1_DES2_EDE_CBC "}, + {CKM_PBE_SHA1_RC2_128_CBC , "CKM_PBE_SHA1_RC2_128_CBC "}, + {CKM_PBE_SHA1_RC2_40_CBC , "CKM_PBE_SHA1_RC2_40_CBC "}, + {CKM_PKCS5_PBKD2 , "CKM_PKCS5_PBKD2 "}, + {CKM_WTLS_PRE_MASTER_KEY_GEN , "CKM_WTLS_PRE_MASTER_KEY_GEN "}, + {CKM_WTLS_MASTER_KEY_DERIVE , "CKM_WTLS_MASTER_KEY_DERIVE "}, + {CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC , "CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC "}, + {CKM_WTLS_PRF , "CKM_WTLS_PRF "}, + {CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE , "CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE "}, + {CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE , "CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE "}, + {CKM_TLS10_MAC_SERVER , "CKM_TLS10_MAC_SERVER "}, + {CKM_TLS10_MAC_CLIENT , "CKM_TLS10_MAC_CLIENT "}, + {CKM_TLS12_MAC , "CKM_TLS12_MAC "}, + {CKM_TLS12_MAC , "CKM_TLS12_MAC "}, + {CKM_TLS12_KDF , "CKM_TLS12_KDF "}, + {CKM_TLS12_MASTER_KEY_DERIVE , "CKM_TLS12_MASTER_KEY_DERIVE "}, + {CKM_TLS12_KEY_AND_MAC_DERIVE , "CKM_TLS12_KEY_AND_MAC_DERIVE "}, + {CKM_TLS12_MASTER_KEY_DERIVE_DH , "CKM_TLS12_MASTER_KEY_DERIVE_DH "}, + {CKM_TLS12_KEY_SAFE_DERIVE , "CKM_TLS12_KEY_SAFE_DERIVE "}, + {CKM_TLS_MAC , "CKM_TLS_MAC "}, + {CKM_TLS_KDF , "CKM_TLS_KDF "}, + {CKM_KEY_WRAP_LYNKS , "CKM_KEY_WRAP_LYNKS "}, + {CKM_KEY_WRAP_SET_OAEP , "CKM_KEY_WRAP_SET_OAEP "}, + {CKM_CMS_SIG , "CKM_CMS_SIG "}, + {CKM_KIP_DERIVE , "CKM_KIP_DERIVE "}, + {CKM_KIP_WRAP , "CKM_KIP_WRAP "}, + {CKM_KIP_MAC , "CKM_KIP_MAC "}, + {CKM_CAMELLIA_KEY_GEN , "CKM_CAMELLIA_KEY_GEN "}, + {CKM_CAMELLIA_ECB , "CKM_CAMELLIA_ECB "}, + {CKM_CAMELLIA_CBC , "CKM_CAMELLIA_CBC "}, + {CKM_CAMELLIA_MAC , "CKM_CAMELLIA_MAC "}, + {CKM_CAMELLIA_MAC_GENERAL , "CKM_CAMELLIA_MAC_GENERAL "}, + {CKM_CAMELLIA_CBC_PAD , "CKM_CAMELLIA_CBC_PAD "}, + {CKM_CAMELLIA_ECB_ENCRYPT_DATA , "CKM_CAMELLIA_ECB_ENCRYPT_DATA "}, + {CKM_CAMELLIA_CBC_ENCRYPT_DATA , "CKM_CAMELLIA_CBC_ENCRYPT_DATA "}, + {CKM_CAMELLIA_CTR , "CKM_CAMELLIA_CTR "}, + {CKM_ARIA_KEY_GEN , "CKM_ARIA_KEY_GEN "}, + {CKM_ARIA_ECB , "CKM_ARIA_ECB "}, + {CKM_ARIA_CBC , "CKM_ARIA_CBC "}, + {CKM_ARIA_MAC , "CKM_ARIA_MAC "}, + {CKM_ARIA_MAC_GENERAL , "CKM_ARIA_MAC_GENERAL "}, + {CKM_ARIA_CBC_PAD , "CKM_ARIA_CBC_PAD "}, + {CKM_ARIA_ECB_ENCRYPT_DATA , "CKM_ARIA_ECB_ENCRYPT_DATA "}, + {CKM_ARIA_CBC_ENCRYPT_DATA , "CKM_ARIA_CBC_ENCRYPT_DATA "}, + {CKM_SKIPJACK_KEY_GEN , "CKM_SKIPJACK_KEY_GEN "}, + {CKM_SKIPJACK_ECB64 , "CKM_SKIPJACK_ECB64 "}, + {CKM_SKIPJACK_CBC64 , "CKM_SKIPJACK_CBC64 "}, + {CKM_SKIPJACK_OFB64 , "CKM_SKIPJACK_OFB64 "}, + {CKM_SKIPJACK_CFB64 , "CKM_SKIPJACK_CFB64 "}, + {CKM_SKIPJACK_CFB32 , "CKM_SKIPJACK_CFB32 "}, + {CKM_SKIPJACK_CFB16 , "CKM_SKIPJACK_CFB16 "}, + {CKM_SKIPJACK_CFB8 , "CKM_SKIPJACK_CFB8 "}, + {CKM_SKIPJACK_WRAP , "CKM_SKIPJACK_WRAP "}, + {CKM_SKIPJACK_PRIVATE_WRAP , "CKM_SKIPJACK_PRIVATE_WRAP "}, + {CKM_SKIPJACK_RELAYX , "CKM_SKIPJACK_RELAYX "}, + {CKM_KEA_KEY_PAIR_GEN , "CKM_KEA_KEY_PAIR_GEN "}, + {CKM_KEA_KEY_DERIVE , "CKM_KEA_KEY_DERIVE "}, + {CKM_FORTEZZA_TIMESTAMP , "CKM_FORTEZZA_TIMESTAMP "}, + {CKM_BATON_KEY_GEN , "CKM_BATON_KEY_GEN "}, + {CKM_BATON_ECB128 , "CKM_BATON_ECB128 "}, + {CKM_BATON_ECB96 , "CKM_BATON_ECB96 "}, + {CKM_BATON_CBC128 , "CKM_BATON_CBC128 "}, + {CKM_BATON_COUNTER , "CKM_BATON_COUNTER "}, + {CKM_BATON_SHUFFLE , "CKM_BATON_SHUFFLE "}, + {CKM_BATON_WRAP , "CKM_BATON_WRAP "}, + {CKM_EC_KEY_PAIR_GEN , "CKM_EC_KEY_PAIR_GEN "}, + {CKM_ECDSA , "CKM_ECDSA "}, + {CKM_ECDSA_SHA1 , "CKM_ECDSA_SHA1 "}, + {CKM_ECDSA_SHA224 , "CKM_ECDSA_SHA224 "}, + {CKM_ECDSA_SHA256 , "CKM_ECDSA_SHA256 "}, + {CKM_ECDSA_SHA384 , "CKM_ECDSA_SHA384 "}, + {CKM_ECDSA_SHA512 , "CKM_ECDSA_SHA512 "}, + {CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS , "CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS "}, + {CKM_ECDH1_DERIVE , "CKM_ECDH1_DERIVE "}, + {CKM_ECDH1_COFACTOR_DERIVE , "CKM_ECDH1_COFACTOR_DERIVE "}, + {CKM_ECMQV_DERIVE , "CKM_ECMQV_DERIVE "}, + {CKM_ECDH_AES_KEY_WRAP , "CKM_ECDH_AES_KEY_WRAP "}, + {CKM_RSA_AES_KEY_WRAP , "CKM_RSA_AES_KEY_WRAP "}, + {CKM_JUNIPER_KEY_GEN , "CKM_JUNIPER_KEY_GEN "}, + {CKM_JUNIPER_ECB128 , "CKM_JUNIPER_ECB128 "}, + {CKM_JUNIPER_CBC128 , "CKM_JUNIPER_CBC128 "}, + {CKM_JUNIPER_COUNTER , "CKM_JUNIPER_COUNTER "}, + {CKM_JUNIPER_SHUFFLE , "CKM_JUNIPER_SHUFFLE "}, + {CKM_JUNIPER_WRAP , "CKM_JUNIPER_WRAP "}, + {CKM_FASTHASH , "CKM_FASTHASH "}, + {CKM_AES_XTS , "CKM_AES_XTS "}, + {CKM_AES_XTS_KEY_GEN , "CKM_AES_XTS_KEY_GEN "}, + {CKM_AES_KEY_GEN , "CKM_AES_KEY_GEN "}, + {CKM_AES_ECB , "CKM_AES_ECB "}, + {CKM_AES_CBC , "CKM_AES_CBC "}, + {CKM_AES_MAC , "CKM_AES_MAC "}, + {CKM_AES_MAC_GENERAL , "CKM_AES_MAC_GENERAL "}, + {CKM_AES_CBC_PAD , "CKM_AES_CBC_PAD "}, + {CKM_AES_CTR , "CKM_AES_CTR "}, + {CKM_AES_GCM , "CKM_AES_GCM "}, + {CKM_AES_CCM , "CKM_AES_CCM "}, + {CKM_AES_CMAC , "CKM_AES_CMAC "}, + {CKM_AES_CTS , "CKM_AES_CTS "}, + {CKM_AES_CMAC_GENERAL , "CKM_AES_CMAC_GENERAL "}, + {CKM_AES_XCBC_MAC , "CKM_AES_XCBC_MAC "}, + {CKM_AES_XCBC_MAC_96 , "CKM_AES_XCBC_MAC_96 "}, + {CKM_AES_GMAC , "CKM_AES_GMAC "}, + {CKM_AES_XCBC_MAC_96 , "CKM_AES_XCBC_MAC_96 "}, + {CKM_BLOWFISH_KEY_GEN , "CKM_BLOWFISH_KEY_GEN "}, + {CKM_BLOWFISH_CBC , "CKM_BLOWFISH_CBC "}, + {CKM_TWOFISH_KEY_GEN , "CKM_TWOFISH_KEY_GEN "}, + {CKM_TWOFISH_CBC , "CKM_TWOFISH_CBC "}, + {CKM_BLOWFISH_CBC_PAD , "CKM_BLOWFISH_CBC_PAD "}, + {CKM_TWOFISH_CBC_PAD , "CKM_TWOFISH_CBC_PAD "}, + {CKM_AES_XCBC_MAC_96 , "CKM_AES_XCBC_MAC_96 "}, + {CKM_DES_ECB_ENCRYPT_DATA , "CKM_DES_ECB_ENCRYPT_DATA "}, + {CKM_DES_CBC_ENCRYPT_DATA , "CKM_DES_CBC_ENCRYPT_DATA "}, + {CKM_DES3_ECB_ENCRYPT_DATA , "CKM_DES3_ECB_ENCRYPT_DATA "}, + {CKM_DES3_CBC_ENCRYPT_DATA , "CKM_DES3_CBC_ENCRYPT_DATA "}, + {CKM_AES_ECB_ENCRYPT_DATA , "CKM_AES_ECB_ENCRYPT_DATA "}, + {CKM_AES_CBC_ENCRYPT_DATA , "CKM_AES_CBC_ENCRYPT_DATA "}, + {CKM_GOSTR3410_KEY_PAIR_GEN , "CKM_GOSTR3410_KEY_PAIR_GEN "}, + {CKM_GOSTR3410 , "CKM_GOSTR3410 "}, + {CKM_GOSTR3410_WITH_GOSTR3411 , "CKM_GOSTR3410_WITH_GOSTR3411 "}, + {CKM_GOSTR3410_KEY_WRAP , "CKM_GOSTR3410_KEY_WRAP "}, + {CKM_GOSTR3410_DERIVE , "CKM_GOSTR3410_DERIVE "}, + {CKM_GOSTR3411 , "CKM_GOSTR3411 "}, + {CKM_GOSTR3411_HMAC , "CKM_GOSTR3411_HMAC "}, + {CKM_GOST28147_KEY_GEN , "CKM_GOST28147_KEY_GEN "}, + {CKM_GOST28147_ECB , "CKM_GOST28147_ECB "}, + {CKM_GOST28147 , "CKM_GOST28147 "}, + {CKM_GOST28147_MAC , "CKM_GOST28147_MAC "}, + {CKM_GOST28147_KEY_WRAP , "CKM_GOST28147_KEY_WRAP "}, + {CKM_CHACHA20_KEY_GEN , "CKM_CHACHA20_KEY_GEN "}, + {CKM_CHACHA20 , "CKM_CHACHA20 "}, + {CKM_POLY1305_KEY_GEN , "CKM_POLY1305_KEY_GEN "}, + {CKM_POLY1305 , "CKM_POLY1305 "}, + {CKM_DSA_PARAMETER_GEN , "CKM_DSA_PARAMETER_GEN "}, + {CKM_DH_PKCS_PARAMETER_GEN , "CKM_DH_PKCS_PARAMETER_GEN "}, + {CKM_X9_42_DH_PARAMETER_GEN , "CKM_X9_42_DH_PARAMETER_GEN "}, + {CKM_DSA_PROBABILISTIC_PARAMETER_GEN , "CKM_DSA_PROBABILISTIC_PARAMETER_GEN "}, + {CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN , "CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN "}, + {CKM_DSA_FIPS_G_GEN , "CKM_DSA_FIPS_G_GEN "}, + {CKM_AES_OFB , "CKM_AES_OFB "}, + {CKM_AES_CFB64 , "CKM_AES_CFB64 "}, + {CKM_AES_CFB8 , "CKM_AES_CFB8 "}, + {CKM_AES_CFB128 , "CKM_AES_CFB128 "}, + {CKM_AES_CFB1 , "CKM_AES_CFB1 "}, + {CKM_AES_KEY_WRAP , "CKM_AES_KEY_WRAP "}, + {CKM_AES_KEY_WRAP_PAD , "CKM_AES_KEY_WRAP_PAD "}, + {CKM_AES_KEY_WRAP_KWP , "CKM_AES_KEY_WRAP_KWP "}, + {CKM_AES_KEY_WRAP_PKCS7 , "CKM_AES_KEY_WRAP_PKCS7 "}, + {CKM_RSA_PKCS_TPM_1_1 , "CKM_RSA_PKCS_TPM_1_1 "}, + {CKM_RSA_PKCS_OAEP_TPM_1_1 , "CKM_RSA_PKCS_OAEP_TPM_1_1 "}, + {CKM_SHA_1_KEY_GEN , "CKM_SHA_1_KEY_GEN "}, + {CKM_SHA224_KEY_GEN , "CKM_SHA224_KEY_GEN "}, + {CKM_SHA256_KEY_GEN , "CKM_SHA256_KEY_GEN "}, + {CKM_SHA384_KEY_GEN , "CKM_SHA384_KEY_GEN "}, + {CKM_SHA512_KEY_GEN , "CKM_SHA512_KEY_GEN "}, + {CKM_SHA512_224_KEY_GEN , "CKM_SHA512_224_KEY_GEN "}, + {CKM_SHA512_256_KEY_GEN , "CKM_SHA512_256_KEY_GEN "}, + {CKM_SHA512_T_KEY_GEN , "CKM_SHA512_T_KEY_GEN "}, + {CKM_NULL , "CKM_NULL "}, + {CKM_BLAKE2B_160 , "CKM_BLAKE2B_160 "}, + {CKM_BLAKE2B_160_HMAC , "CKM_BLAKE2B_160_HMAC "}, + {CKM_BLAKE2B_160_HMAC_GENERAL , "CKM_BLAKE2B_160_HMAC_GENERAL "}, + {CKM_BLAKE2B_160_KEY_DERIVE , "CKM_BLAKE2B_160_KEY_DERIVE "}, + {CKM_BLAKE2B_160_KEY_GEN , "CKM_BLAKE2B_160_KEY_GEN "}, + {CKM_BLAKE2B_256 , "CKM_BLAKE2B_256 "}, + {CKM_BLAKE2B_256_HMAC , "CKM_BLAKE2B_256_HMAC "}, + {CKM_BLAKE2B_256_HMAC_GENERAL , "CKM_BLAKE2B_256_HMAC_GENERAL "}, + {CKM_BLAKE2B_256_KEY_DERIVE , "CKM_BLAKE2B_256_KEY_DERIVE "}, + {CKM_BLAKE2B_256_KEY_GEN , "CKM_BLAKE2B_256_KEY_GEN "}, + {CKM_BLAKE2B_384 , "CKM_BLAKE2B_384 "}, + {CKM_BLAKE2B_384_HMAC , "CKM_BLAKE2B_384_HMAC "}, + {CKM_BLAKE2B_384_HMAC_GENERAL , "CKM_BLAKE2B_384_HMAC_GENERAL "}, + {CKM_BLAKE2B_384_KEY_DERIVE , "CKM_BLAKE2B_384_KEY_DERIVE "}, + {CKM_BLAKE2B_384_KEY_GEN , "CKM_BLAKE2B_384_KEY_GEN "}, + {CKM_BLAKE2B_512 , "CKM_BLAKE2B_512 "}, + {CKM_BLAKE2B_512_HMAC , "CKM_BLAKE2B_512_HMAC "}, + {CKM_BLAKE2B_512_HMAC_GENERAL , "CKM_BLAKE2B_512_HMAC_GENERAL "}, + {CKM_BLAKE2B_512_KEY_DERIVE , "CKM_BLAKE2B_512_KEY_DERIVE "}, + {CKM_BLAKE2B_512_KEY_GEN , "CKM_BLAKE2B_512_KEY_GEN "}, + {CKM_SALSA20 , "CKM_SALSA20 "}, + {CKM_CHACHA20_POLY1305 , "CKM_CHACHA20_POLY1305 "}, + {CKM_SALSA20_POLY1305 , "CKM_SALSA20_POLY1305 "}, + {CKM_X3DH_INITIALIZE , "CKM_X3DH_INITIALIZE "}, + {CKM_X3DH_RESPOND , "CKM_X3DH_RESPOND "}, + {CKM_X2RATCHET_INITIALIZE , "CKM_X2RATCHET_INITIALIZE "}, + {CKM_X2RATCHET_RESPOND , "CKM_X2RATCHET_RESPOND "}, + {CKM_X2RATCHET_ENCRYPT , "CKM_X2RATCHET_ENCRYPT "}, + {CKM_X2RATCHET_DECRYPT , "CKM_X2RATCHET_DECRYPT "}, + {CKM_XEDDSA , "CKM_XEDDSA "}, + {CKM_HKDF_DERIVE , "CKM_HKDF_DERIVE "}, + {CKM_HKDF_DATA , "CKM_HKDF_DATA "}, + {CKM_HKDF_KEY_GEN , "CKM_HKDF_KEY_GEN "}, + {CKM_SALSA20_KEY_GEN , "CKM_SALSA20_KEY_GEN "}, + {CKM_ECDSA_SHA3_224 , "CKM_ECDSA_SHA3_224 "}, + {CKM_ECDSA_SHA3_256 , "CKM_ECDSA_SHA3_256 "}, + {CKM_ECDSA_SHA3_384 , "CKM_ECDSA_SHA3_384 "}, + {CKM_ECDSA_SHA3_512 , "CKM_ECDSA_SHA3_512 "}, + {CKM_EC_EDWARDS_KEY_PAIR_GEN , "CKM_EC_EDWARDS_KEY_PAIR_GEN "}, + {CKM_EC_MONTGOMERY_KEY_PAIR_GEN , "CKM_EC_MONTGOMERY_KEY_PAIR_GEN "}, + {CKM_EDDSA , "CKM_EDDSA "}, + {CKM_SP800_108_COUNTER_KDF , "CKM_SP800_108_COUNTER_KDF "}, + {CKM_SP800_108_FEEDBACK_KDF , "CKM_SP800_108_FEEDBACK_KDF "}, + {CKM_SP800_108_DOUBLE_PIPELINE_KDF , "CKM_SP800_108_DOUBLE_PIPELINE_KDF "}, + {CKM_IKE2_PRF_PLUS_DERIVE , "CKM_IKE2_PRF_PLUS_DERIVE "}, + {CKM_IKE_PRF_DERIVE , "CKM_IKE_PRF_DERIVE "}, + {CKM_IKE1_PRF_DERIVE , "CKM_IKE1_PRF_DERIVE "}, + {CKM_IKE1_EXTENDED_DERIVE , "CKM_IKE1_EXTENDED_DERIVE "}, + {CKM_HSS_KEY_PAIR_GEN , "CKM_HSS_KEY_PAIR_GEN "}, + {CKM_HSS , "CKM_HSS "}, + {CKM_XMSS_KEY_PAIR_GEN , "CKM_XMSS_KEY_PAIR_GEN "}, + {CKM_XMSSMT_KEY_PAIR_GEN , "CKM_XMSSMT_KEY_PAIR_GEN "}, + {CKM_XMSS , "CKM_XMSS "}, + {CKM_XMSSMT , "CKM_XMSSMT "}, + {CKM_ECDH_X_AES_KEY_WRAP , "CKM_ECDH_X_AES_KEY_WRAP "}, + {CKM_ECDH_COF_AES_KEY_WRAP , "CKM_ECDH_COF_AES_KEY_WRAP "}, + {CKM_PUB_KEY_FROM_PRIV_KEY , "CKM_PUB_KEY_FROM_PRIV_KEY "}, + {CKM_XMSS , "CKM_XMSS "}, + {CKM_XMSS , "CKM_XMSS "}, + {CKM_XMSS , "CKM_XMSS "}, + {CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED "} }; static enum_specs ck_mgf_s[] = { @@ -588,143 +867,231 @@ static enum_specs ck_mgf_s[] = { }; static enum_specs ck_generate_s[] = { - { CKG_NO_GENERATE , "CKG_NO_GENERATE " }, - { CKG_GENERATE , "CKG_GENERATE " }, - { CKG_GENERATE_COUNTER , "CKG_GENERATE_COUNTER " }, - { CKG_GENERATE_RANDOM , "CKG_GENERATE_RANDOM " }, - { CKG_GENERATE_COUNTER_XOR, "CKG_GENERATE_COUNTER_XOR" }, + {CKG_NO_GENERATE , "CKG_NO_GENERATE "}, + {CKG_GENERATE , "CKG_GENERATE "}, + {CKG_GENERATE_COUNTER , "CKG_GENERATE_COUNTER "}, + {CKG_GENERATE_RANDOM , "CKG_GENERATE_RANDOM "}, + {CKG_GENERATE_COUNTER_XOR, "CKG_GENERATE_COUNTER_XOR"}, +}; + +static enum_specs ck_hw_s[] = { + {CKH_MONOTONIC_COUNTER, "CKH_MONOTONIC_COUNTER"}, + {CKH_CLOCK , "CKH_CLOCK "}, + {CKH_USER_INTERFACE , "CKH_USER_INTERFACE "} +}; + +static enum_specs ck_hg_s[] = { + {CKH_HEDGE_PREFERRED , "CKH_HEDGE_PREFERRED "}, + {CKH_HEDGE_REQUIRED , "CKH_HEDGE_REQUIRED "}, + {CKH_DETERMINISTIC_REQUIRED, "CKH_DETERMINISTIC_REQUIRED"} +}; + +static enum_specs ck_not_s[] = { + {CKN_SURRENDER , "CKN_SURRENDER "}, + {CKN_OTP_CHANGED, "CKN_OTP_CHANGED "} }; static enum_specs ck_err_s[] = { - { CKR_OK, "CKR_OK" }, - { CKR_CANCEL, "CKR_CANCEL" }, - { CKR_HOST_MEMORY, "CKR_HOST_MEMORY" }, - { CKR_SLOT_ID_INVALID, "CKR_SLOT_ID_INVALID" }, - { CKR_GENERAL_ERROR, "CKR_GENERAL_ERROR" }, - { CKR_FUNCTION_FAILED, "CKR_FUNCTION_FAILED" }, - { CKR_ARGUMENTS_BAD, "CKR_ARGUMENTS_BAD" }, - { CKR_NO_EVENT, "CKR_NO_EVENT" }, - { CKR_NEED_TO_CREATE_THREADS, "CKR_NEED_TO_CREATE_THREADS" }, - { CKR_CANT_LOCK, "CKR_CANT_LOCK" }, - { CKR_ATTRIBUTE_READ_ONLY, "CKR_ATTRIBUTE_READ_ONLY" }, - { CKR_ATTRIBUTE_SENSITIVE, "CKR_ATTRIBUTE_SENSITIVE" }, - { CKR_ATTRIBUTE_TYPE_INVALID, "CKR_ATTRIBUTE_TYPE_INVALID" }, - { CKR_ATTRIBUTE_VALUE_INVALID, "CKR_ATTRIBUTE_VALUE_INVALID" }, - { CKR_ACTION_PROHIBITED, "CKR_ACTION_PROHIBITED" }, - { CKR_DATA_INVALID, "CKR_DATA_INVALID" }, - { CKR_DATA_LEN_RANGE, "CKR_DATA_LEN_RANGE" }, - { CKR_DEVICE_ERROR, "CKR_DEVICE_ERROR" }, - { CKR_DEVICE_MEMORY, "CKR_DEVICE_MEMORY" }, - { CKR_DEVICE_REMOVED, "CKR_DEVICE_REMOVED" }, - { CKR_ENCRYPTED_DATA_INVALID, "CKR_ENCRYPTED_DATA_INVALID" }, - { CKR_ENCRYPTED_DATA_LEN_RANGE, "CKR_ENCRYPTED_DATA_LEN_RANGE" }, - { CKR_FUNCTION_CANCELED, "CKR_FUNCTION_CANCELED" }, - { CKR_FUNCTION_NOT_PARALLEL, "CKR_FUNCTION_NOT_PARALLEL" }, - { CKR_FUNCTION_NOT_SUPPORTED, "CKR_FUNCTION_NOT_SUPPORTED" }, - { CKR_KEY_HANDLE_INVALID, "CKR_KEY_HANDLE_INVALID" }, - { CKR_KEY_SIZE_RANGE, "CKR_KEY_SIZE_RANGE" }, - { CKR_KEY_TYPE_INCONSISTENT, "CKR_KEY_TYPE_INCONSISTENT" }, - { CKR_KEY_NOT_NEEDED, "CKR_KEY_NOT_NEEDED" }, - { CKR_KEY_CHANGED, "CKR_KEY_CHANGED" }, - { CKR_KEY_NEEDED, "CKR_KEY_NEEDED" }, - { CKR_KEY_INDIGESTIBLE, "CKR_KEY_INDIGESTIBLE" }, - { CKR_KEY_FUNCTION_NOT_PERMITTED, "CKR_KEY_FUNCTION_NOT_PERMITTED" }, - { CKR_KEY_NOT_WRAPPABLE, "CKR_KEY_NOT_WRAPPABLE" }, - { CKR_KEY_UNEXTRACTABLE, "CKR_KEY_UNEXTRACTABLE" }, - { CKR_MECHANISM_INVALID, "CKR_MECHANISM_INVALID" }, - { CKR_MECHANISM_PARAM_INVALID, "CKR_MECHANISM_PARAM_INVALID" }, - { CKR_OBJECT_HANDLE_INVALID, "CKR_OBJECT_HANDLE_INVALID" }, - { CKR_OPERATION_ACTIVE, "CKR_OPERATION_ACTIVE" }, - { CKR_OPERATION_NOT_INITIALIZED, "CKR_OPERATION_NOT_INITIALIZED" }, - { CKR_PIN_INCORRECT, "CKR_PIN_INCORRECT" }, - { CKR_PIN_INVALID, "CKR_PIN_INVALID" }, - { CKR_PIN_LEN_RANGE, "CKR_PIN_LEN_RANGE" }, - { CKR_PIN_EXPIRED, "CKR_PIN_EXPIRED" }, - { CKR_PIN_LOCKED, "CKR_PIN_LOCKED" }, - { CKR_SESSION_CLOSED, "CKR_SESSION_CLOSED" }, - { CKR_SESSION_COUNT, "CKR_SESSION_COUNT" }, - { CKR_SESSION_HANDLE_INVALID, "CKR_SESSION_HANDLE_INVALID" }, - { CKR_SESSION_PARALLEL_NOT_SUPPORTED, "CKR_SESSION_PARALLEL_NOT_SUPPORTED" }, - { CKR_SESSION_READ_ONLY, "CKR_SESSION_READ_ONLY" }, - { CKR_SESSION_EXISTS, "CKR_SESSION_EXISTS" }, - { CKR_SESSION_READ_ONLY_EXISTS, "CKR_SESSION_READ_ONLY_EXISTS" }, - { CKR_SESSION_READ_WRITE_SO_EXISTS, "CKR_SESSION_READ_WRITE_SO_EXISTS" }, - { CKR_SIGNATURE_INVALID, "CKR_SIGNATURE_INVALID" }, - { CKR_SIGNATURE_LEN_RANGE, "CKR_SIGNATURE_LEN_RANGE" }, - { CKR_TEMPLATE_INCOMPLETE, "CKR_TEMPLATE_INCOMPLETE" }, - { CKR_TEMPLATE_INCONSISTENT, "CKR_TEMPLATE_INCONSISTENT" }, - { CKR_TOKEN_NOT_PRESENT, "CKR_TOKEN_NOT_PRESENT" }, - { CKR_TOKEN_NOT_RECOGNIZED, "CKR_TOKEN_NOT_RECOGNIZED" }, - { CKR_TOKEN_WRITE_PROTECTED, "CKR_TOKEN_WRITE_PROTECTED" }, - { CKR_UNWRAPPING_KEY_HANDLE_INVALID, "CKR_UNWRAPPING_KEY_HANDLE_INVALID" }, - { CKR_UNWRAPPING_KEY_SIZE_RANGE, "CKR_UNWRAPPING_KEY_SIZE_RANGE" }, - { CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT" }, - { CKR_USER_ALREADY_LOGGED_IN, "CKR_USER_ALREADY_LOGGED_IN" }, - { CKR_USER_NOT_LOGGED_IN, "CKR_USER_NOT_LOGGED_IN" }, - { CKR_USER_PIN_NOT_INITIALIZED, "CKR_USER_PIN_NOT_INITIALIZED" }, - { CKR_USER_TYPE_INVALID, "CKR_USER_TYPE_INVALID" }, - { CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "CKR_USER_ANOTHER_ALREADY_LOGGED_IN" }, - { CKR_USER_TOO_MANY_TYPES, "CKR_USER_TOO_MANY_TYPES" }, - { CKR_WRAPPED_KEY_INVALID, "CKR_WRAPPED_KEY_INVALID" }, - { CKR_WRAPPED_KEY_LEN_RANGE, "CKR_WRAPPED_KEY_LEN_RANGE" }, - { CKR_WRAPPING_KEY_HANDLE_INVALID, "CKR_WRAPPING_KEY_HANDLE_INVALID" }, - { CKR_WRAPPING_KEY_SIZE_RANGE, "CKR_WRAPPING_KEY_SIZE_RANGE" }, - { CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "CKR_WRAPPING_KEY_TYPE_INCONSISTENT" }, - { CKR_RANDOM_SEED_NOT_SUPPORTED, "CKR_RANDOM_SEED_NOT_SUPPORTED" }, - { CKR_RANDOM_NO_RNG, "CKR_RANDOM_NO_RNG" }, - { CKR_DOMAIN_PARAMS_INVALID, "CKR_DOMAIN_PARAMS_INVALID" }, - { CKR_CURVE_NOT_SUPPORTED, "CKR_CURVE_NOT_SUPPORTED" }, - { CKR_BUFFER_TOO_SMALL, "CKR_BUFFER_TOO_SMALL" }, - { CKR_SAVED_STATE_INVALID, "CKR_SAVED_STATE_INVALID" }, - { CKR_INFORMATION_SENSITIVE, "CKR_INFORMATION_SENSITIVE" }, - { CKR_STATE_UNSAVEABLE, "CKR_STATE_UNSAVEABLE" }, - { CKR_CRYPTOKI_NOT_INITIALIZED, "CKR_CRYPTOKI_NOT_INITIALIZED" }, - { CKR_CRYPTOKI_ALREADY_INITIALIZED, "CKR_CRYPTOKI_ALREADY_INITIALIZED" }, - { CKR_MUTEX_BAD, "CKR_MUTEX_BAD" }, - { CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED" }, - { CKR_FUNCTION_REJECTED, "CKR_FUNCTION_REJECTED" }, - { CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED" } + {CKR_OK, "CKR_OK"}, + {CKR_CANCEL, "CKR_CANCEL"}, + {CKR_HOST_MEMORY, "CKR_HOST_MEMORY"}, + {CKR_SLOT_ID_INVALID, "CKR_SLOT_ID_INVALID"}, + {CKR_GENERAL_ERROR, "CKR_GENERAL_ERROR"}, + {CKR_FUNCTION_FAILED, "CKR_FUNCTION_FAILED"}, + {CKR_ARGUMENTS_BAD, "CKR_ARGUMENTS_BAD"}, + {CKR_NO_EVENT, "CKR_NO_EVENT"}, + {CKR_NEED_TO_CREATE_THREADS, "CKR_NEED_TO_CREATE_THREADS"}, + {CKR_CANT_LOCK, "CKR_CANT_LOCK"}, + {CKR_ATTRIBUTE_READ_ONLY, "CKR_ATTRIBUTE_READ_ONLY"}, + {CKR_ATTRIBUTE_SENSITIVE, "CKR_ATTRIBUTE_SENSITIVE"}, + {CKR_ATTRIBUTE_TYPE_INVALID, "CKR_ATTRIBUTE_TYPE_INVALID"}, + {CKR_ATTRIBUTE_VALUE_INVALID, "CKR_ATTRIBUTE_VALUE_INVALID"}, + {CKR_ACTION_PROHIBITED, "CKR_ACTION_PROHIBITED"}, + {CKR_DATA_INVALID, "CKR_DATA_INVALID"}, + {CKR_DATA_LEN_RANGE, "CKR_DATA_LEN_RANGE"}, + {CKR_DEVICE_ERROR, "CKR_DEVICE_ERROR"}, + {CKR_DEVICE_MEMORY, "CKR_DEVICE_MEMORY"}, + {CKR_DEVICE_REMOVED, "CKR_DEVICE_REMOVED"}, + {CKR_ENCRYPTED_DATA_INVALID, "CKR_ENCRYPTED_DATA_INVALID"}, + {CKR_ENCRYPTED_DATA_LEN_RANGE, "CKR_ENCRYPTED_DATA_LEN_RANGE"}, + {CKR_AEAD_DECRYPT_FAILED, "CKR_AEAD_DECRYPT_FAILED"}, + {CKR_FUNCTION_CANCELED, "CKR_FUNCTION_CANCELED"}, + {CKR_FUNCTION_NOT_PARALLEL, "CKR_FUNCTION_NOT_PARALLEL"}, + {CKR_FUNCTION_NOT_SUPPORTED, "CKR_FUNCTION_NOT_SUPPORTED"}, + {CKR_KEY_HANDLE_INVALID, "CKR_KEY_HANDLE_INVALID"}, + {CKR_KEY_SIZE_RANGE, "CKR_KEY_SIZE_RANGE"}, + {CKR_KEY_TYPE_INCONSISTENT, "CKR_KEY_TYPE_INCONSISTENT"}, + {CKR_KEY_NOT_NEEDED, "CKR_KEY_NOT_NEEDED"}, + {CKR_KEY_CHANGED, "CKR_KEY_CHANGED"}, + {CKR_KEY_NEEDED, "CKR_KEY_NEEDED"}, + {CKR_KEY_INDIGESTIBLE, "CKR_KEY_INDIGESTIBLE"}, + {CKR_KEY_FUNCTION_NOT_PERMITTED, "CKR_KEY_FUNCTION_NOT_PERMITTED"}, + {CKR_KEY_NOT_WRAPPABLE, "CKR_KEY_NOT_WRAPPABLE"}, + {CKR_KEY_UNEXTRACTABLE, "CKR_KEY_UNEXTRACTABLE"}, + {CKR_MECHANISM_INVALID, "CKR_MECHANISM_INVALID"}, + {CKR_MECHANISM_PARAM_INVALID, "CKR_MECHANISM_PARAM_INVALID"}, + {CKR_OBJECT_HANDLE_INVALID, "CKR_OBJECT_HANDLE_INVALID"}, + {CKR_OPERATION_ACTIVE, "CKR_OPERATION_ACTIVE"}, + {CKR_OPERATION_NOT_INITIALIZED, "CKR_OPERATION_NOT_INITIALIZED"}, + {CKR_PIN_INCORRECT, "CKR_PIN_INCORRECT"}, + {CKR_PIN_INVALID, "CKR_PIN_INVALID"}, + {CKR_PIN_LEN_RANGE, "CKR_PIN_LEN_RANGE"}, + {CKR_PIN_EXPIRED, "CKR_PIN_EXPIRED"}, + {CKR_PIN_LOCKED, "CKR_PIN_LOCKED"}, + {CKR_SESSION_CLOSED, "CKR_SESSION_CLOSED"}, + {CKR_SESSION_COUNT, "CKR_SESSION_COUNT"}, + {CKR_SESSION_HANDLE_INVALID, "CKR_SESSION_HANDLE_INVALID"}, + {CKR_SESSION_PARALLEL_NOT_SUPPORTED, "CKR_SESSION_PARALLEL_NOT_SUPPORTED"}, + {CKR_SESSION_READ_ONLY, "CKR_SESSION_READ_ONLY"}, + {CKR_SESSION_EXISTS, "CKR_SESSION_EXISTS"}, + {CKR_SESSION_READ_ONLY_EXISTS, "CKR_SESSION_READ_ONLY_EXISTS"}, + {CKR_SESSION_READ_WRITE_SO_EXISTS, "CKR_SESSION_READ_WRITE_SO_EXISTS"}, + {CKR_SIGNATURE_INVALID, "CKR_SIGNATURE_INVALID"}, + {CKR_SIGNATURE_LEN_RANGE, "CKR_SIGNATURE_LEN_RANGE"}, + {CKR_TEMPLATE_INCOMPLETE, "CKR_TEMPLATE_INCOMPLETE"}, + {CKR_TEMPLATE_INCONSISTENT, "CKR_TEMPLATE_INCONSISTENT"}, + {CKR_TOKEN_NOT_PRESENT, "CKR_TOKEN_NOT_PRESENT"}, + {CKR_TOKEN_NOT_RECOGNIZED, "CKR_TOKEN_NOT_RECOGNIZED"}, + {CKR_TOKEN_WRITE_PROTECTED, "CKR_TOKEN_WRITE_PROTECTED"}, + {CKR_UNWRAPPING_KEY_HANDLE_INVALID, "CKR_UNWRAPPING_KEY_HANDLE_INVALID"}, + {CKR_UNWRAPPING_KEY_SIZE_RANGE, "CKR_UNWRAPPING_KEY_SIZE_RANGE"}, + {CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"}, + {CKR_USER_ALREADY_LOGGED_IN, "CKR_USER_ALREADY_LOGGED_IN"}, + {CKR_USER_NOT_LOGGED_IN, "CKR_USER_NOT_LOGGED_IN"}, + {CKR_USER_PIN_NOT_INITIALIZED, "CKR_USER_PIN_NOT_INITIALIZED"}, + {CKR_USER_TYPE_INVALID, "CKR_USER_TYPE_INVALID"}, + {CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "CKR_USER_ANOTHER_ALREADY_LOGGED_IN"}, + {CKR_USER_TOO_MANY_TYPES, "CKR_USER_TOO_MANY_TYPES"}, + {CKR_WRAPPED_KEY_INVALID, "CKR_WRAPPED_KEY_INVALID"}, + {CKR_WRAPPED_KEY_LEN_RANGE, "CKR_WRAPPED_KEY_LEN_RANGE"}, + {CKR_WRAPPING_KEY_HANDLE_INVALID, "CKR_WRAPPING_KEY_HANDLE_INVALID"}, + {CKR_WRAPPING_KEY_SIZE_RANGE, "CKR_WRAPPING_KEY_SIZE_RANGE"}, + {CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"}, + {CKR_RANDOM_SEED_NOT_SUPPORTED, "CKR_RANDOM_SEED_NOT_SUPPORTED"}, + {CKR_RANDOM_NO_RNG, "CKR_RANDOM_NO_RNG"}, + {CKR_DOMAIN_PARAMS_INVALID, "CKR_DOMAIN_PARAMS_INVALID"}, + {CKR_CURVE_NOT_SUPPORTED, "CKR_CURVE_NOT_SUPPORTED"}, + {CKR_BUFFER_TOO_SMALL, "CKR_BUFFER_TOO_SMALL"}, + {CKR_SAVED_STATE_INVALID, "CKR_SAVED_STATE_INVALID"}, + {CKR_INFORMATION_SENSITIVE, "CKR_INFORMATION_SENSITIVE"}, + {CKR_STATE_UNSAVEABLE, "CKR_STATE_UNSAVEABLE"}, + {CKR_CRYPTOKI_NOT_INITIALIZED, "CKR_CRYPTOKI_NOT_INITIALIZED"}, + {CKR_CRYPTOKI_ALREADY_INITIALIZED, "CKR_CRYPTOKI_ALREADY_INITIALIZED"}, + {CKR_MUTEX_BAD, "CKR_MUTEX_BAD"}, + {CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED"}, + {CKR_NEW_PIN_MODE, "CKR_NEW_PIN_MODE"}, + {CKR_NEXT_OTP, "CKR_NEXT_OTP"}, + {CKR_EXCEEDED_MAX_ITERATIONS, "CKR_EXCEEDED_MAX_ITERATIONS"}, + {CKR_FIPS_SELF_TEST_FAILED, "CKR_FIPS_SELF_TEST_FAILED"}, + {CKR_LIBRARY_LOAD_FAILED, "CKR_LIBRARY_LOAD_FAILED"}, + {CKR_PIN_TOO_WEAK, "CKR_PIN_TOO_WEAK"}, + {CKR_PUBLIC_KEY_INVALID, "CKR_PUBLIC_KEY_INVALID"}, + {CKR_FUNCTION_REJECTED, "CKR_FUNCTION_REJECTED"}, + {CKR_TOKEN_RESOURCE_EXCEEDED, "CKR_TOKEN_RESOURCE_EXCEEDED"}, + {CKR_OPERATION_CANCEL_FAILED, "CKR_OPERATION_CANCEL_FAILED"}, + {CKR_KEY_EXHAUSTED, "CKR_KEY_EXHAUSTED"}, + {CKR_PENDING, "CKR_PENDING"}, + {CKR_SESSION_ASYNC_NOT_SUPPORTED, "CKR_SESSION_ASYNC_NOT_SUPPORTED"}, + {CKR_SEED_RANDOM_REQUIRED, "CKR_SEED_RANDOM_REQUIRED"}, + {CKR_OPERATION_NOT_VALIDATED, "CKR_OPERATION_NOT_VALIDATED"}, + {CKR_TOKEN_NOT_INITIALIZED, "CKR_TOKEN_NOT_INITIALIZED"}, + {CKR_PARAMETER_SET_NOT_SUPPORTED, "CKR_PARAMETER_SET_NOT_SUPPORTED"}, + {CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED"} }; static enum_specs ck_usr_s[] = { - { CKU_SO, "CKU_SO" }, - { CKU_USER, "CKU_USER" }, - { CKU_CONTEXT_SPECIFIC, "CKU_CONTEXT_SPECIFIC" } + {CKU_SO, "CKU_SO"}, + {CKU_USER, "CKU_USER"}, + {CKU_CONTEXT_SPECIFIC, "CKU_CONTEXT_SPECIFIC"} }; static enum_specs ck_sta_s[] = { - { CKS_RO_PUBLIC_SESSION, "CKS_RO_PUBLIC_SESSION" }, - { CKS_RO_USER_FUNCTIONS, "CKS_RO_USER_FUNCTIONS" }, - { CKS_RW_PUBLIC_SESSION, "CKS_RW_PUBLIC_SESSION" }, - { CKS_RW_USER_FUNCTIONS, "CKS_RW_USER_FUNCTIONS" }, - { CKS_RW_SO_FUNCTIONS, "CKS_RW_SO_FUNCTIONS" } + {CKS_RO_PUBLIC_SESSION, "CKS_RO_PUBLIC_SESSION"}, + {CKS_RO_USER_FUNCTIONS, "CKS_RO_USER_FUNCTIONS"}, + {CKS_RW_PUBLIC_SESSION, "CKS_RW_PUBLIC_SESSION"}, + {CKS_RW_USER_FUNCTIONS, "CKS_RW_USER_FUNCTIONS"}, + {CKS_RW_SO_FUNCTIONS, "CKS_RW_SO_FUNCTIONS"} +}; + +static enum_specs ck_tru_s[] = { + {CKT_TRUST_UNKNOWN, "CKT_TRUST_UNKNOWN"}, + {CKT_TRUSTED, "CKT_TRUSTED"}, + {CKT_TRUST_ANCHOR, "CKT_TRUST_ANCHOR"}, + {CKT_NOT_TRUSTED, "CKT_NOT_TRUSTED"}, + {CKT_TRUST_MUST_VERIFY_TRUST, "CKT_TRUST_MUST_VERIFY_TRUST"} +}; + +static enum_specs ck_auth_s[] = { + {CKV_AUTHORITY_TYPE_UNSPECIFIED, "CKV_AUTHORITY_TYPE_UNSPECIFIED"}, + {CKV_AUTHORITY_TYPE_NIST_CMVP, "CKV_AUTHORITY_TYPE_NIST_CMVP"}, + {CKV_AUTHORITY_TYPE_COMMON_CRITERIA, "CKV_AUTHORITY_TYPE_COMMON_CRITERIA"} +}; + +static enum_specs ck_val_s[] = { + {CKV_TYPE_UNSPECIFIED, "CKV_TYPE_UNSPECIFIED"}, + {CKV_TYPE_SOFTWARE, "CKV_TYPE_SOFTWARE"}, + {CKV_TYPE_HARDWARE, "CKV_TYPE_HARDWARE"}, + {CKV_TYPE_FIRMWARE, "CKV_TYPE_FIRMWARE"}, + {CKV_TYPE_HYBRID, "CKV_TYPE_HYBRID"} }; static enum_specs ck_ckd_s[] = { - { CKD_NULL, "CKD_NULL" }, - { CKD_SHA1_KDF, "CKD_SHA1_KDF" }, - { CKD_SHA224_KDF, "CKD_SHA224_KDF" }, - { CKD_SHA256_KDF, "CKD_SHA256_KDF" }, - { CKD_SHA384_KDF, "CKD_SHA384_KDF" }, - { CKD_SHA512_KDF, "CKD_SHA512_KDF" }, + {CKD_NULL, "CKD_NULL"}, + {CKD_SHA1_KDF, "CKD_SHA1_KDF"}, + {CKD_SHA1_KDF_ASN1, "CKD_SHA1_KDF_ASN1"}, + {CKD_SHA1_KDF_CONCATENATE, "CKD_SHA1_KDF_CONCATENATE"}, + {CKD_SHA224_KDF, "CKD_SHA224_KDF"}, + {CKD_SHA256_KDF, "CKD_SHA256_KDF"}, + {CKD_SHA384_KDF, "CKD_SHA384_KDF"}, + {CKD_SHA512_KDF, "CKD_SHA512_KDF"}, + {CKD_CPDIVERSIFY_KDF, "CKD_CPDIVERSIFY_KDF"}, + {CKD_SHA3_224_KDF, "CKD_SHA3_224_KDF"}, + {CKD_SHA3_256_KDF, "CKD_SHA3_256_KDF"}, + {CKD_SHA3_384_KDF, "CKD_SHA3_384_KDF"}, + {CKD_SHA3_512_KDF, "CKD_SHA3_512_KDF"}, + {CKD_SHA1_KDF_SP800, "CKD_SHA1_KDF_SP800"}, + {CKD_SHA224_KDF_SP800, "CKD_SHA224_KDF_SP800"}, + {CKD_SHA256_KDF_SP800, "CKD_SHA256_KDF_SP800"}, + {CKD_SHA384_KDF_SP800, "CKD_SHA384_KDF_SP800"}, + {CKD_SHA512_KDF_SP800, "CKD_SHA512_KDF_SP800"}, + {CKD_SHA3_224_KDF_SP800, "CKD_SHA3_224_KDF_SP800"}, + {CKD_SHA3_256_KDF_SP800, "CKD_SHA3_256_KDF_SP800"}, + {CKD_SHA3_384_KDF_SP800, "CKD_SHA3_384_KDF_SP800"}, + {CKD_SHA3_512_KDF_SP800, "CKD_SHA3_512_KDF_SP800"}, + {CKD_BLAKE2B_160_KDF, "CKD_BLAKE2B_160_KDF"}, + {CKD_BLAKE2B_256_KDF, "CKD_BLAKE2B_256_KDF"}, + {CKD_BLAKE2B_384_KDF, "CKD_BLAKE2B_384_KDF"}, + {CKD_BLAKE2B_512_KDF, "CKD_BLAKE2B_512_KDF"} }; #define SZ_SPECS sizeof(enum_specs) enum_spec ck_types[] = { - { OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" }, - { PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE" }, - { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, - { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, - { MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, - { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE" }, - { GENERATE_T, ck_generate_s, sizeof(ck_generate_s) / SZ_SPECS, "CK_GENERATOR_FUNCTION"}, - { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, - { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, - { CKD_T, ck_ckd_s, sizeof(ck_ckd_s) / SZ_SPECS, "CK_EC_KDF_TYPE" }, - { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, + {OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" }, + {PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE" }, + {KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, + {CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, + {MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, + {MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE" }, + {GENERATE_T, ck_generate_s, sizeof(ck_generate_s) / SZ_SPECS, "CK_GENERATOR_FUNCTION" }, + {USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, + {STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, + {CKD_T, ck_ckd_s, sizeof(ck_ckd_s) / SZ_SPECS, "CK_EC_KDF_TYPE" }, + {RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, + {HW_T, ck_hw_s, sizeof(ck_hw_s) / SZ_SPECS, "CK_HW_FEATURE_TYPE" }, + {HG_T, ck_hg_s, sizeof(ck_hg_s) / SZ_SPECS, "CK_HEDGE_TYPE" }, + {NOT_T, ck_not_s, sizeof(ck_not_s) / SZ_SPECS, "CK_NOTIFICATION" }, + /* CKP PBKD2, ML-DSA, ML_KEM, SLH-DSA missing*/ + {TRU_T, ck_tru_s, sizeof(ck_tru_s) / SZ_SPECS, "CK_TRUST" }, + {AUTH_T, ck_auth_s, sizeof(ck_auth_s) / SZ_SPECS, "CK_VALIDATION_AUTHORITY_TYPE" }, + {VAL_T, ck_val_s, sizeof(ck_val_s) / SZ_SPECS, "CK_VALIDATION_TYPE" }, + {ML_DSA_T, ck_mldsa_s, sizeof(ck_mldsa_s) / SZ_SPECS, "CK_ML_DSA_PARAMETER_SET_TYPE" }, + {ML_KEM_T, ck_mlkem_s, sizeof(ck_mlkem_s) / SZ_SPECS, "CK_ML_KEM_PARAMETER_SET_TYPE" }, + {SLH_DSA_T, ck_slh_dsa_s, sizeof(ck_slh_dsa_s) / SZ_SPECS, "CK_SLH_DSA_PARAMETER_SET_TYPE"}, }; + + static enum_spec ck_key_t[] = { { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" } }; static enum_spec ck_cls_t[] = { { OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" } }; static enum_spec ck_crt_t[] = { { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" } }; @@ -810,8 +1177,6 @@ type_spec ck_attribute_specs[] = { { CKA_AUTH_PIN_FLAGS , "CKA_AUTH_PIN_FLAGS ", print_generic, NULL }, { CKA_ALWAYS_AUTHENTICATE, "CKA_ALWAYS_AUTHENTICATE ", print_boolean, NULL }, { CKA_WRAP_WITH_TRUSTED , "CKA_WRAP_WITH_TRUSTED ", print_generic, NULL }, - { CKA_WRAP_TEMPLATE , "CKA_WRAP_TEMPLATE ", print_generic, NULL }, - { CKA_UNWRAP_TEMPLATE , "CKA_UNWRAP_TEMPLATE ", print_generic, NULL }, { CKA_OTP_FORMAT , "CKA_OTP_FORMAT ", print_generic, NULL }, { CKA_OTP_LENGTH , "CKA_OTP_LENGTH ", print_generic, NULL }, { CKA_OTP_TIME_INTERVAL , "CKA_OTP_TIME_INTERVAL ", print_generic, NULL }, @@ -847,6 +1212,62 @@ type_spec ck_attribute_specs[] = { { CKA_REQUIRED_CMS_ATTRIBUTES, "CKA_REQUIRED_CMS_ATTRIBUTES ", print_generic, NULL }, { CKA_DEFAULT_CMS_ATTRIBUTES, "CKA_DEFAULT_CMS_ATTRIBUTES ", print_generic, NULL }, { CKA_SUPPORTED_CMS_ATTRIBUTES, "CKA_SUPPORTED_CMS_ATTRIBUTES ", print_generic, NULL }, + + // NEW in PKCS#11 v3.2 + { CKA_X2RATCHET_BAG , "CKA_X2RATCHET_BAG ", print_generic, NULL }, + { CKA_X2RATCHET_BAGSIZE , "CKA_X2RATCHET_BAGSIZE ", print_generic, NULL }, + { CKA_X2RATCHET_BOBS1STMSG, "CKA_X2RATCHET_BOBS1STMSG ", print_generic, NULL }, + { CKA_X2RATCHET_CKR , "CKA_X2RATCHET_CKR ", print_generic, NULL }, + { CKA_X2RATCHET_CKS , "CKA_X2RATCHET_CKS " , print_generic, NULL }, + { CKA_X2RATCHET_DHP , "CKA_X2RATCHET_DHP " , print_generic, NULL }, + { CKA_X2RATCHET_DHR , "CKA_X2RATCHET_DHR " , print_generic, NULL }, + { CKA_X2RATCHET_DHS , "CKA_X2RATCHET_DHS " , print_generic, NULL }, + { CKA_X2RATCHET_HKR , "CKA_X2RATCHET_HKR ", print_generic, NULL }, + { CKA_X2RATCHET_HKS , "CKA_X2RATCHET_HKS ", print_generic, NULL }, + { CKA_X2RATCHET_ISALICE , "CKA_X2RATCHET_ISALICE ", print_generic, NULL }, + { CKA_X2RATCHET_NHKR , "CKA_X2RATCHET_NHKR ", print_generic, NULL }, + { CKA_X2RATCHET_NHKS , "CKA_X2RATCHET_NHKS ", print_generic, NULL }, + { CKA_X2RATCHET_NR , "CKA_X2RATCHET_NR ", print_generic, NULL }, + { CKA_X2RATCHET_NS , "CKA_X2RATCHET_NS ", print_generic, NULL }, + { CKA_X2RATCHET_PNS , "CKA_X2RATCHET_PNS ", print_generic, NULL }, + { CKA_X2RATCHET_RK , "CKA_X2RATCHET_BAGSIZE ", print_generic, NULL }, + { CKA_HSS_LEVELS , "CKA_HSS_LEVELS ", print_generic, NULL }, + { CKA_HSS_LMS_TYPE , "CKA_HSS_LMS_TYPE ", print_generic, NULL }, + { CKA_HSS_LMOTS_TYPE , "CKA_HSS_LMOTS_TYPE ", print_generic, NULL }, + { CKA_HSS_LMS_TYPES , "CKA_HSS_LMS_TYPES ", print_generic, NULL }, + { CKA_HSS_LMOTS_TYPES , "CKA_HSS_LMOTS_TYPES ", print_generic, NULL }, + { CKA_HSS_KEYS_REMAINING, "CKA_HSS_KEYS_REMAINING ", print_generic, NULL }, + { CKA_PARAMETER_SET , "CKA_PARAMETER_SET ", print_generic, NULL }, + { CKA_OBJECT_VALIDATION_FLAGS , "CKA_OBJECT_VALIDATION_FLAGS ", print_generic, NULL }, + { CKA_VALIDATION_TYPE , "CKA_VALIDATION_TYPE ", print_generic, NULL }, + { CKA_VALIDATION_VERSION , "CKA_VALIDATION_VERSION ", print_generic, NULL }, + { CKA_VALIDATION_LEVEL , "CKA_VALIDATION_LEVEL ", print_generic, NULL }, + { CKA_VALIDATION_MODULE_ID , "CKA_VALIDATION_MODULE_ID ", print_generic, NULL }, + { CKA_VALIDATION_FLAG , "CKA_VALIDATION_FLAG ", print_generic, NULL }, + { CKA_VALIDATION_AUTHORITY_TYPE , "CKA_VALIDATION_AUTHORITY_TYPE ", print_generic, NULL }, + { CKA_VALIDATION_COUNTRY , "CKA_VALIDATION_COUNTRY ", print_generic, NULL }, + { CKA_VALIDATION_CERTIFICATE_IDENTIFIER , "CKA_VALIDATION_CERTIFICATE_IDENTIFIER ", print_generic, NULL }, + { CKA_VALIDATION_CERTIFICATE_URI , "CKA_VALIDATION_CERTIFICATE_URI ", print_generic, NULL }, + { CKA_VALIDATION_VENDOR_URI , "CKA_VALIDATION_VENDOR_URI ", print_generic, NULL }, + { CKA_VALIDATION_PROFILE , "CKA_VALIDATION_PROFILE ", print_generic, NULL }, + { CKA_OBJECT_VALIDATION_FLAGS , "CKA_OBJECT_VALIDATION_FLAGS ", print_generic, NULL }, + { CKA_ENCAPSULATE_TEMPLATE , "CKA_ENCAPSULATE_TEMPLATE ", print_generic, NULL }, + { CKA_DECAPSULATE_TEMPLATE , "CKA_DECAPSULATE_TEMPLATE ", print_generic, NULL }, + { CKA_TRUST_SERVER_AUTH , "CKA_TRUST_SERVER_AUTH ", print_generic, NULL }, + { CKA_TRUST_CLIENT_AUTH , "CKA_TRUST_CLIENT_AUTH ", print_generic, NULL }, + { CKA_TRUST_CODE_SIGNING , "CKA_TRUST_CODE_SIGNING ", print_generic, NULL }, + { CKA_TRUST_EMAIL_PROTECTION , "CKA_TRUST_EMAIL_PROTECTION ", print_generic, NULL }, + { CKA_TRUST_IPSEC_IKE , "CKA_TRUST_IPSEC_IKE ", print_generic, NULL }, + { CKA_TRUST_TIME_STAMPING , "CKA_TRUST_TIME_STAMPING ", print_generic, NULL }, + { CKA_TRUST_OCSP_SIGNING , "CKA_TRUST_OCSP_SIGNING ", print_generic, NULL }, + { CKA_ENCAPSULATE , "CKA_ENCAPSULATE ", print_generic, NULL }, + { CKA_DECAPSULATE , "CKA_DECAPSULATE ", print_generic, NULL }, + { CKA_HASH_OF_CERTIFICATE , "CKA_HASH_OF_CERTIFICATE ", print_generic, NULL }, + { CKA_PUBLIC_CRC64_VALUE , "CKA_PUBLIC_CRC64_VALUE ", print_generic, NULL }, + { CKA_SEED , "CKA_SEED ", print_generic, NULL }, + { CKA_WRAP_TEMPLATE , "CKA_WRAP_TEMPLATE ", print_generic, NULL }, + { CKA_UNWRAP_TEMPLATE , "CKA_UNWRAP_TEMPLATE ", print_generic, NULL }, + { CKA_DERIVE_TEMPLATE , "CKA_DERIVE_TEMPLATE ", print_generic, NULL }, { CKA_ALLOWED_MECHANISMS, "CKA_ALLOWED_MECHANISMS ", print_generic, NULL }, { CKA_NSS_URL, "CKA_NSS_URL(NSS) ", print_generic, NULL }, { CKA_NSS_EMAIL, "CKA_NSS_EMAIL(NSS) ", print_generic, NULL }, @@ -860,23 +1281,23 @@ type_spec ck_attribute_specs[] = { { CKA_NSS_PQG_SEED, "CKA_NSS_PQG_SEED(NSS) ", print_generic, NULL }, { CKA_NSS_PQG_H, "CKA_NSS_PQG_H(NSS) ", print_generic, NULL }, { CKA_NSS_PQG_SEED_BITS, "CKA_NSS_PQG_SEED_BITS(NSS) ", print_generic, NULL }, - { CKA_TRUST_DIGITAL_SIGNATURE, "CKA_TRUST_DIGITAL_SIGNATURE(NSS) ", print_boolean, NULL }, - { CKA_TRUST_NON_REPUDIATION, "CKA_TRUST_NON_REPUDIATION(NSS) ", print_boolean, NULL }, - { CKA_TRUST_KEY_ENCIPHERMENT, "CKA_TRUST_KEY_ENCIPHERMENT(NSS) ", print_boolean, NULL }, - { CKA_TRUST_DATA_ENCIPHERMENT, "CKA_TRUST_DATA_ENCIPHERMENT(NSS) ", print_boolean, NULL }, - { CKA_TRUST_KEY_AGREEMENT, "CKA_TRUST_KEY_AGREEMENT(NSS) ", print_boolean, NULL }, - { CKA_TRUST_KEY_CERT_SIGN, "CKA_TRUST_KEY_CERT_SIGN(NSS) ", print_boolean, NULL }, - { CKA_TRUST_CRL_SIGN, "CKA_TRUST_CRL_SIGN(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_DIGITAL_SIGNATURE, "CKA_NSS_TRUST_DIGITAL_SIGNATURE(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_NON_REPUDIATION, "CKA_TRUST_NON_REPUDIATION(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_KEY_ENCIPHERMENT, "CKA_TRUST_KEY_ENCIPHERMENT(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_DATA_ENCIPHERMENT, "CKA_TRUST_DATA_ENCIPHERMENT(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_KEY_AGREEMENT, "CKA_TRUST_KEY_AGREEMENT(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_KEY_CERT_SIGN, "CKA_TRUST_KEY_CERT_SIGN(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_CRL_SIGN, "CKA_TRUST_CRL_SIGN(NSS) ", print_boolean, NULL }, { CKA_NSS_TRUST_SERVER_AUTH, "CKA_TRUST_SERVER_AUTH(NSS) ", print_boolean, NULL }, { CKA_NSS_TRUST_CLIENT_AUTH, "CKA_TRUST_CLIENT_AUTH(NSS) ", print_boolean, NULL }, { CKA_NSS_TRUST_CODE_SIGNING, "CKA_TRUST_CODE_SIGNING(NSS) ", print_boolean, NULL }, { CKA_NSS_TRUST_EMAIL_PROTECTION, "CKA_TRUST_EMAIL_PROTECTION(NSS) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_END_SYSTEM, "CKA_TRUST_IPSEC_END_SYSTEM(NSS) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_TUNNEL, "CKA_TRUST_IPSEC_TUNNEL(NSS) ", print_boolean, NULL }, - { CKA_TRUST_IPSEC_USER, "CKA_TRUST_IPSEC_USER(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_IPSEC_END_SYSTEM, "CKA_TRUST_IPSEC_END_SYSTEM(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_IPSEC_TUNNEL, "CKA_TRUST_IPSEC_TUNNEL(NSS) ", print_boolean, NULL }, + { CKA_NSS_TRUST_IPSEC_USER, "CKA_TRUST_IPSEC_USER(NSS) ", print_boolean, NULL }, { CKA_NSS_TRUST_TIME_STAMPING, "CKA_TRUST_TIME_STAMPING(NSS) ", print_boolean, NULL }, - { CKA_CERT_SHA1_HASH, "CKA_CERT_SHA1_HASH(NSS) ", print_generic, NULL }, - { CKA_CERT_MD5_HASH, "CKA_CERT_MD5_HASH(NSS) ", print_generic, NULL }, + { CKA_NSS_CERT_SHA1_HASH, "CKA_CERT_SHA1_HASH(NSS) ", print_generic, NULL }, + { CKA_NSS_CERT_MD5_HASH, "CKA_CERT_MD5_HASH(NSS) ", print_generic, NULL }, }; // clang-format on @@ -986,7 +1407,10 @@ print_token_info(FILE *f, CK_TOKEN_INFO *info) { CKF_SO_PIN_COUNT_LOW , "CKF_SO_PIN_COUNT_LOW " }, { CKF_SO_PIN_FINAL_TRY , "CKF_SO_PIN_FINAL_TRY " }, { CKF_SO_PIN_LOCKED , "CKF_SO_PIN_LOCKED " }, - { CKF_SO_PIN_TO_BE_CHANGED , "CKF_SO_PIN_TO_BE_CHANGED " } + { CKF_SO_PIN_TO_BE_CHANGED , "CKF_SO_PIN_TO_BE_CHANGED " }, + { CKF_ERROR_STATE , "CKF_ERROR_STATE " }, + { CKF_SEED_RANDOM_REQUIRED , "CKF_SEED_RANDOM_REQUIRED " }, + { CKF_ASYNC_SESSION_SUPPORTED , "CKF_ASYNC_SESSION_SUPPORTED " } }; fprintf(f, " label: '%32.32s'\n", info->label ); @@ -1038,11 +1462,14 @@ void print_mech_info(FILE *f, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR minfo) { const char *name = lookup_enum(MEC_T, type); - CK_ULONG known_flags = CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_DIGEST | - CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | - CKF_GENERATE | CKF_GENERATE_KEY_PAIR | CKF_WRAP | CKF_UNWRAP | - CKF_DERIVE | CKF_EC_F_P | CKF_EC_F_2M |CKF_EC_ECPARAMETERS | - CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS | CKF_EC_COMPRESS; + CK_ULONG known_flags = CKF_HW | CKF_MESSAGE_ENCRYPT | CKF_MESSAGE_DECRYPT | + CKF_MESSAGE_SIGN | CKF_MESSAGE_VERIFY | CKF_MULTI_MESSAGE | + CKF_FIND_OBJECTS | CKF_ENCRYPT | CKF_DECRYPT | CKF_DIGEST | + CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | + CKF_GENERATE | CKF_GENERATE_KEY_PAIR | CKF_WRAP | CKF_UNWRAP | + CKF_DERIVE | CKF_EC_F_P | CKF_EC_F_2M |CKF_EC_ECPARAMETERS | + CKF_EC_OID | CKF_EC_UNCOMPRESS | CKF_EC_CURVENAME | + CKF_EC_NAMEDCURVE | CKF_ENCAPSULATE | CKF_DECAPSULATE; if (name) fprintf(f, "%s : ", name); @@ -1052,27 +1479,36 @@ print_mech_info(FILE *f, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR minfo) fprintf(f, "min:%lu max:%lu flags:0x%lX ", (unsigned long) minfo->ulMinKeySize, (unsigned long) minfo->ulMaxKeySize, minfo->flags); - fprintf(f, "( %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", - (minfo->flags & CKF_HW) ? "Hardware " : "", - (minfo->flags & CKF_ENCRYPT) ? "Encrypt " : "", - (minfo->flags & CKF_DECRYPT) ? "Decrypt " : "", - (minfo->flags & CKF_DIGEST) ? "Digest " : "", - (minfo->flags & CKF_SIGN) ? "Sign " : "", - (minfo->flags & CKF_SIGN_RECOVER) ? "SigRecov " : "", - (minfo->flags & CKF_VERIFY) ? "Verify " : "", - (minfo->flags & CKF_VERIFY_RECOVER) ? "VerRecov " : "", - (minfo->flags & CKF_GENERATE) ? "Generate " : "", - (minfo->flags & CKF_GENERATE_KEY_PAIR) ? "KeyPair " : "", - (minfo->flags & CKF_WRAP) ? "Wrap " : "", - (minfo->flags & CKF_UNWRAP) ? "Unwrap " : "", - (minfo->flags & CKF_DERIVE) ? "Derive " : "", - (minfo->flags & CKF_EC_F_P) ? "F(P) " : "", - (minfo->flags & CKF_EC_F_2M) ? "F(2^M) " : "", - (minfo->flags & CKF_EC_ECPARAMETERS) ? "EcParams " : "", - (minfo->flags & CKF_EC_NAMEDCURVE) ? "NamedCurve " : "", - (minfo->flags & CKF_EC_UNCOMPRESS) ? "Uncompress " : "", - (minfo->flags & CKF_EC_COMPRESS) ? "Compress " : "", - (minfo->flags & ~known_flags) ? "Unknown " : ""); + fprintf(f, "( %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", + (minfo->flags & CKF_HW) ? "Hardware " : "", + (minfo->flags & CKF_MESSAGE_ENCRYPT) ? "MsgEncrypt " : "", + (minfo->flags & CKF_MESSAGE_DECRYPT) ? "MsgDencrypt " : "", + (minfo->flags & CKF_MESSAGE_SIGN) ? "MsgSign " : "", + (minfo->flags & CKF_MESSAGE_VERIFY) ? "MsgVerify " : "", + (minfo->flags & CKF_MULTI_MESSAGE) ? "MultiMsg " : "", + (minfo->flags & CKF_ENCRYPT) ? "Encrypt " : "", + (minfo->flags & CKF_DECRYPT) ? "Decrypt " : "", + (minfo->flags & CKF_DIGEST) ? "Digest " : "", + (minfo->flags & CKF_SIGN) ? "Sign " : "", + (minfo->flags & CKF_SIGN_RECOVER) ? "SigRecov " : "", + (minfo->flags & CKF_VERIFY) ? "Verify " : "", + (minfo->flags & CKF_VERIFY_RECOVER) ? "VerRecov " : "", + (minfo->flags & CKF_GENERATE) ? "Generate " : "", + (minfo->flags & CKF_GENERATE_KEY_PAIR) ? "KeyPair " : "", + (minfo->flags & CKF_WRAP) ? "Wrap " : "", + (minfo->flags & CKF_UNWRAP) ? "Unwrap " : "", + (minfo->flags & CKF_DERIVE) ? "Derive " : "", + (minfo->flags & CKF_EC_F_P) ? "F(P) " : "", + (minfo->flags & CKF_EC_F_2M) ? "F(2^M) " : "", + (minfo->flags & CKF_EC_ECPARAMETERS) ? "EcParams " : "", + (minfo->flags & CKF_EC_OID) ? "OID " : "", + (minfo->flags & CKF_EC_UNCOMPRESS) ? "Uncompress " : "", + (minfo->flags & CKF_EC_COMPRESS) ? "Compress " : "", + (minfo->flags & CKF_EC_CURVENAME) ? "CurveName " : "", + (minfo->flags & CKF_EC_NAMEDCURVE) ? "NamedCurve " : "", + (minfo->flags & CKF_ENCAPSULATE) ? "Encapsulate " : "", + (minfo->flags & CKF_DECAPSULATE) ? "Decapsulate " : "", + (minfo->flags & ~known_flags) ? "Unknown " : ""); } @@ -1143,8 +1579,9 @@ print_session_info(FILE *f, CK_SESSION_INFO *info) { size_t i; enum_specs ck_flags[] = { - { CKF_RW_SESSION , "CKF_RW_SESSION " }, - { CKF_SERIAL_SESSION , "CKF_SERIAL_SESSION " } + {CKF_RW_SESSION , "CKF_RW_SESSION "}, + {CKF_SERIAL_SESSION , "CKF_SERIAL_SESSION "}, + {CKF_ASYNC_SESSION , "CKF_ASYNC_SESSION "} }; fprintf(f, " slotID: %ld\n", info->slotID ); diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 06d79d8fe2..31d00d3ebd 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -62,7 +62,16 @@ enum ck_type { USR_T, STA_T, CKD_T, - RV_T + RV_T, + HW_T, + HG_T, + NOT_T, + TRU_T, + AUTH_T, + VAL_T, + ML_DSA_T, + ML_KEM_T, + SLH_DSA_T, }; const char *lookup_enum_spec(enum_spec *spec, CK_ULONG value); From 7929fe087a8f2b1cf2f826f88b83e437edc5ed30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 28 Aug 2025 18:09:00 +0200 Subject: [PATCH 4026/4321] Add support for ML-DSA into pkcs11-tool --- src/tools/pkcs11-tool.c | 175 +++++++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 36 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a37410239a..ff1d4b3c29 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -579,7 +579,7 @@ struct rsakey_info { unsigned char *coefficient; int coefficient_len; }; -struct gostkey_info { +struct generalkey_info { struct sc_lv_data param_oid; struct sc_lv_data public; struct sc_lv_data private; @@ -588,6 +588,13 @@ struct gostkey_info { #endif }; +struct pqckey_info { + struct sc_lv_data public; + struct sc_lv_data private; + struct sc_lv_data seed; + long int type; +}; + static void show_cryptoki_info(void); static void list_slots(int, int, int); static void show_token(CK_SLOT_ID); @@ -3567,6 +3574,30 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, n_privkey_attr++; } } + else if (strncmp(type, "ML-DSA-", strlen("ML-DSA-")) == 0 || strncmp(type, "ml-dsa-", strlen("ml-dsa-")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_ML_DSA_KEY_PAIR_GEN}; + size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); + int ii; + CK_ML_DSA_PARAMETER_SET_TYPE parameter_set = 0; + + key_type = CKK_ML_DSA; + + if (strlen(type) != strlen("ML-DSA-") + 2) { + util_fatal("Invalid ML-DSA key type '%s'", type); + } else if (strcmp(type, "ML-DSA-44")) { + parameter_set = CKP_ML_DSA_44; + } else if (strcmp(type, "ML-DSA-44")) { + parameter_set = CKP_ML_DSA_44; + } else if (strcmp(type, "ML-DSA-44")) { + parameter_set = CKP_ML_DSA_44; + } else { + util_fatal("Invalid ML-DSA key type '%s'", type); + } + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate RSA mechanism not supported"); + } else { util_fatal("Unknown key pair type %s", type); } @@ -3946,6 +3977,7 @@ unwrap_key(CK_SESSION_HANDLE session) } else { util_fatal("Unsupported key type %s", opt_key_type); } + /* TODO: Add PQC algorithms*/ FILL_ATTR(keyTemplate[n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type)); n_attr++; @@ -4289,7 +4321,7 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) #if !defined(OPENSSL_NO_EC) static int -parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) +parse_gost_pkey(EVP_PKEY *pkey, int private, struct generalkey_info *gost) { unsigned char *pder; BIGNUM *X, *Y; @@ -4392,19 +4424,19 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) } static int -parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) +parse_ec_pkey(EVP_PKEY *pkey, int private, struct generalkey_info *ec) { #if OPENSSL_VERSION_NUMBER < 0x30000000L const EC_KEY *src = EVP_PKEY_get0_EC_KEY(pkey); const BIGNUM *bignum; if (!src) return -1; - gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gost->param_oid.value); + gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gosect->param_oid.value); #else BIGNUM *bignum = NULL; - gost->param_oid.len = i2d_KeyParams(pkey, &gost->param_oid.value); + ec->param_oid.len = i2d_KeyParams(pkey, &ec->param_oid.value); #endif - if (gost->param_oid.len <= 0) { + if (ec->param_oid.len <= 0) { return -1; } @@ -4416,15 +4448,15 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) return -1; } #endif - gost->private.len = BN_num_bytes(bignum); - gost->private.value = OPENSSL_malloc(gost->private.len); - if (!gost->private.value) { + ec->private.len = BN_num_bytes(bignum); + ec->private.value = OPENSSL_malloc(ec->private.len); + if (!ec->private.value) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(bignum); #endif return -1; } - BN_bn2bin(bignum, gost->private.value); + BN_bn2bin(bignum, ec->private.value); #if OPENSSL_VERSION_NUMBER >= 0x30000000L BN_free(bignum); #endif @@ -4442,16 +4474,16 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #else EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, sizeof(buf), &point_len); #endif - gost->public.value = OPENSSL_malloc(MAX_HEADER_LEN + point_len); - if (!gost->public.value) + ec->public.value = OPENSSL_malloc(MAX_HEADER_LEN + point_len); + if (!ec->public.value) return -1; - point = gost->public.value; + point = ec->public.value; ASN1_put_object(&point, 0, (int)point_len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); - header_len = point-gost->public.value; + header_len = point-ec->public.value; memcpy(point, buf, point_len); - gost->public.len = header_len+point_len; + ec->public.len = header_len+point_len; #ifdef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding - gost->public.len -= header_len; + ec->public.len -= header_len; gost->public.value += header_len; // store header_len to restore public.value before free it gost->header_len = header_len; @@ -4461,6 +4493,58 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) return 0; } +static int +parse_ml_dsa_pkey(EVP_PKEY *pkey, int private, struct pqckey_info *ml_dsa) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30500000L + if ((ml_dsa->type = EVP_PKEY_get_id(pkey)) == -1) { + return -1; + } + if (private) { + size_t priv_len; + + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len) != 1) { + return -1; + } + ml_dsa->private.len = priv_len; + if (!(ml_dsa->private.value = OPENSSL_malloc(priv_len))) { + return -1; + } + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, ml_dsa->private.value, priv_len, NULL) != 1) { + OPENSSL_free(ml_dsa->private.value); + return -1; + } + ml_dsa->seed.len = 32; + if (!(ml_dsa->seed.value = OPENSSL_malloc(ml_dsa->seed.len))) { + OPENSSL_free(ml_dsa->private.value); + return -1; + } + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ML_DSA_SEED, ml_dsa->private.value, priv_len, NULL) != 1) { + OPENSSL_free(ml_dsa->private.value); + OPENSSL_free(ml_dsa->seed.value); + return -1; + } + } else { + size_t pub_len; + + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len) != 1) { + return -1; + } + ml_dsa->public.len = pub_len; + if (!(ml_dsa->public.value = OPENSSL_malloc(pub_len))) { + return -1; + } + if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, ml_dsa->public.value, pub_len, NULL) != 1) { + OPENSSL_free(ml_dsa->public); + return -1; + } + } + return 0; +#else + return -1; +#endif +} + #ifdef ENABLE_OPENSSL /* Return PKCS11 key type based on OpenSSL EVP_PKEY type * which are supported by PKCS11 and OpenSSL used when compiling. @@ -4553,6 +4637,13 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ return CKR_OK; } #endif + +#if defined(EVP_PKEY_ML_DSA_44) && defined(EVP_PKEY_ML_DSA_65) && defined(EVP_PKEY_ML_DSA_87) + if (*pk_type == EVP_PKEY_ML_DSA_44 || *pk_type == EVP_PKEY_ML_DSA_65 || *pk_type == EVP_PKEY_ML_DSA_87) { + *type = CKK_ML_DSA; + return CKR_OK; + } +#endif err: /* unsupported by OpenSSL, PKCS11 or this program */ *type = CKK_OPENSC_UNDEFINED; @@ -4563,7 +4654,7 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ /* Edwards and Montogmery keys have the same format */ static int -parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curve_info *ec_curve_info, int private, struct gostkey_info *gost) +parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curve_info *ec_curve_info, int private, struct generalkey_info *gost) { unsigned char *key; size_t key_size; @@ -4615,7 +4706,7 @@ parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curv } #endif static void -gost_info_free(struct gostkey_info gost) +general_key_info_free(struct generalkey_info gost) { #ifdef EC_POINT_NO_ASN1_OCTET_STRING // restore public.value before free it if (gost.public.value) @@ -4665,14 +4756,15 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #ifdef ENABLE_OPENSSL struct x509cert_info cert; struct rsakey_info rsa; - struct gostkey_info gost; + struct generalkey_info general_key; + struct pqckey_info pqc_key; EVP_PKEY *evp_key = NULL; int pk_type = -1; struct ec_curve_info *ec_curve_info = NULL; memset(&cert, 0, sizeof(cert)); memset(&rsa, 0, sizeof(rsa)); - memset(&gost, 0, sizeof(gost)); + memset(&general_key, 0, sizeof(general_key)); #endif f = fopen(opt_file_to_write, "rb"); @@ -4768,11 +4860,13 @@ static CK_RV write_object(CK_SESSION_HANDLE session) } #if !defined(OPENSSL_NO_EC) else if (type == CKK_GOSTR3410) { - rv = parse_gost_pkey(evp_key, is_private, &gost); + rv = parse_gost_pkey(evp_key, is_private, &general_key); } else if (type == CKK_EC) { - rv = parse_ec_pkey(evp_key, is_private, &gost); + rv = parse_ec_pkey(evp_key, is_private, &general_key); } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { - rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_curve_info, is_private, &gost); + rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_curve_info, is_private, &general_key); + } else if (type == CKK_ML_DSA) { + rv = parse_ml_dsa_pkey(evp_key, is_private, &pqc_key); } #endif else @@ -4902,27 +4996,31 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_COEFFICIENT, rsa.coefficient, rsa.coefficient_len); n_privkey_attr++; - } - - else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { + } else if ((type == CKK_EC) || (type == CKK_EC_EDWARDS) || (type == CKK_EC_MONTGOMERY)) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, general_key.param_oid.value, general_key.param_oid.len); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, general_key.private.value, general_key.private.len); n_privkey_attr++; - } else if (type == CKK_GOSTR3410) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len); + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, general_key.param_oid.value, general_key.param_oid.len); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, general_key.private.value, general_key.private.len); /* CKA_VALUE of the GOST key has to be in the little endian order */ rv = sc_mem_reverse(privkey_templ[n_privkey_attr].pValue, privkey_templ[n_privkey_attr].ulValueLen); if (rv) return rv; n_privkey_attr++; + } else if (type == CKK_ML_DSA) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); + n_privkey_attr++; + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, &pqc_key.private.value, pqc_key.private.len); + n_privkey_attr++; + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SEED, &pqc_key.seed.value, pqc_key.seed.len); + n_privkey_attr++; } else { util_fatal("Unsupported CK_KEY_TYPE, cannot write private key"); } @@ -4989,6 +5087,11 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len); n_pubkey_attr++; + } else if (type == CKK_ML_DSA) { + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); + n_pubkey_attr++; + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, &pqc_key.public.value, pqc_key.public.len); + n_pubkey_attr++; } #if !defined(OPENSSL_NO_EC) @@ -4996,18 +5099,18 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_pubkey_attr++; - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_PARAMS, general_key.param_oid.value, general_key.param_oid.len); n_pubkey_attr++; - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, gost.public.value, gost.public.len); + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, general_key.public.value, general_key.public.len); n_pubkey_attr++; } else if (pk_type == NID_id_GostR3410_2001) { type = CKK_GOSTR3410; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); n_pubkey_attr++; - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len); + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_GOSTR3410_PARAMS, general_key.param_oid.value, general_key.param_oid.len); n_pubkey_attr++; - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, gost.public.value, gost.public.len); + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, general_key.public.value, general_key.public.len); /* CKA_VALUE of the GOST key has to be in the little endian order */ rv = sc_mem_reverse(pubkey_templ[n_pubkey_attr].pValue, pubkey_templ[n_pubkey_attr].ulValueLen); if (rv) @@ -5215,7 +5318,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) } #ifdef ENABLE_OPENSSL - gost_info_free(gost); + general_key_info_free(general_key); rsa_info_free(rsa); EVP_PKEY_free(evp_key); #endif /* ENABLE_OPENSSL */ From ad95c14b110f9c35933fe51f371ba4dc5d467872 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 23 Oct 2025 14:07:49 +0200 Subject: [PATCH 4027/4321] Add missing PKCS#11 3.2 mechanisms, attributes mostly in pkcs11 tool and pkcs11-spy Signed-off-by: Jakub Jelen --- doc/tools/pkcs11-tool.1.xml | 7 + doc/tools/tools.html | 2 + src/libopensc/card-coolkey.c | 1 + src/pkcs11/pkcs11-display.c | 126 ++++++--- src/pkcs11/pkcs11-display.h | 11 +- src/pkcs11/pkcs11-global.c | 437 +++++++++++++++++----------- src/pkcs11/pkcs11-object.c | 116 ++++++++ src/pkcs11/pkcs11-spy.c | 371 ++++++++++++++++++++++-- src/pkcs11/pkcs11.h | 6 +- src/tools/pkcs11-tool.c | 531 +++++++++++++++++++++++++++-------- 10 files changed, 1255 insertions(+), 353 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 4a154722ac..4de768b0af 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -185,6 +185,13 @@ Specify 'wrap' key usage flag. + + + + + Specify 'encapsulate' key usage flag (sets DECAPSULATE in privkey, sets ENCAPSULATE in pubkey). + + name, diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 3667e92913..41b92b1caa 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1503,6 +1503,8 @@

    Specify 'derive' key usage flag (EC only).

    --usage-wrap

    Specify 'wrap' key usage flag.

    + --usage-encapsulate +

    Specify 'encapsulate' key usage flag (sets DECAPSULATE in privkey, sets ENCAPSULATE in pubkey).

    --label name, -a name

    Specify the name of the object to operate on diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 5d547bc960..52760b384c 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 436258dc01..e7b8f824b3 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -110,7 +110,7 @@ buf_spec(CK_VOID_PTR buf_addr, CK_ULONG buf_len) void -print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg) +print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { enum_spec *spec = (enum_spec*)arg; CK_ULONG i; @@ -127,7 +127,7 @@ print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR void -print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg) +print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_BYTE i = *((CK_BYTE *)value); fprintf(f, i ? "True\n" : "False\n"); @@ -135,7 +135,7 @@ print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P void -print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg) +print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_ULONG i; @@ -188,9 +188,9 @@ print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P #ifdef ENABLE_OPENSSL static void -print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg) +print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { - print_generic(f, type, value, size, arg); + print_generic(f, type, value, size, arg, key_type); if(size && value) { X509_NAME *name; const unsigned char *tmp = value; @@ -208,8 +208,67 @@ print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR ar } #endif +static enum_specs ck_mldsa_s[] = { + { CKP_ML_DSA_44, "CKP_ML_DSA_44" }, + { CKP_ML_DSA_65, "CKP_ML_DSA_65" }, + { CKP_ML_DSA_87, "CKP_ML_DSA_87" }, +}; + +static enum_specs ck_mlkem_s[] = { + { CKP_ML_KEM_512, "CKP_ML_KEM_512" }, + { CKP_ML_KEM_768, "CKP_ML_KEM_768" }, + { CKP_ML_KEM_1024, "CKP_ML_KEM_1024" }, +}; + +static enum_specs ck_slh_dsa_s[] = { + { CKP_SLH_DSA_SHA2_128S, "CKP_SLH_DSA_SHA2_128S" }, + { CKP_SLH_DSA_SHAKE_128S, "CKP_SLH_DSA_SHAKE_128S" }, + { CKP_SLH_DSA_SHA2_128F, "CKP_SLH_DSA_SHA2_128F" }, + { CKP_SLH_DSA_SHAKE_128F, "CKP_SLH_DSA_SHAKE_128F" }, + { CKP_SLH_DSA_SHA2_192S, "CKP_SLH_DSA_SHA2_192S" }, + { CKP_SLH_DSA_SHAKE_192S, "CKP_SLH_DSA_SHAKE_192S" }, + { CKP_SLH_DSA_SHA2_192F, "CKP_SLH_DSA_SHA2_192F" }, + { CKP_SLH_DSA_SHAKE_192F, "CKP_SLH_DSA_SHAKE_192F" }, + { CKP_SLH_DSA_SHA2_256S, "CKP_SLH_DSA_SHA2_256S" }, + { CKP_SLH_DSA_SHAKE_256S, "CKP_SLH_DSA_SHAKE_256S" }, + { CKP_SLH_DSA_SHA2_256F, "CKP_SLH_DSA_SHA2_256F" }, + { CKP_SLH_DSA_SHAKE_256F, "CKP_SLH_DSA_SHAKE_256F" }, +}; + +#define SZ_SPECS sizeof(enum_specs) + +static enum_spec ck_ml_dsa_t[] = { + {ML_DSA_T, ck_mldsa_s, sizeof(ck_mldsa_s) / SZ_SPECS, "CK_ML_DSA_PARAMETER_SET_TYPE"}, +}; +static enum_spec ck_ml_kem_t[] = { + {ML_KEM_T, ck_mlkem_s, sizeof(ck_mlkem_s) / SZ_SPECS, "CK_ML_KEM_PARAMETER_SET_TYPE"}, +}; +static enum_spec ck_slh_dsa_t[] = { + {SLH_DSA_T, ck_slh_dsa_s, sizeof(ck_slh_dsa_s) / SZ_SPECS, "CK_SLH_DSA_PARAMETER_SET_TYPE"}, +}; + void -print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg) +print_parameter_set(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, + CK_KEY_TYPE key_type) +{ + switch (key_type) { + case CKK_ML_DSA: + print_enum(f, type, value, size, ck_ml_dsa_t, key_type); + break; + case CKK_ML_KEM: + print_enum(f, type, value, size, ck_ml_kem_t, key_type); + break; + case CKK_SLH_DSA: + print_enum(f, type, value, size, ck_slh_dsa_t, key_type); + break; + default: + print_generic(f, type, value, size, arg, key_type); + break; + } +} + +void +print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_ULONG i, j=0; CK_BYTE c; @@ -243,32 +302,6 @@ print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR } fprintf(f, "\n"); } -static enum_specs ck_mldsa_s[] = { - {CKP_ML_DSA_44, "CKP_ML_DSA_44"}, - {CKP_ML_DSA_65, "CKP_ML_DSA_65"}, - {CKP_ML_DSA_87, "CKP_ML_DSA_87"}, -}; - -static enum_specs ck_mlkem_s[] = { - {CKP_ML_KEM_512, "CKP_ML_KEM_512"}, - {CKP_ML_KEM_768, "CKP_ML_KEM_768"}, - {CKP_ML_KEM_1024, "CKP_ML_KEM_1024"}, -}; - -static enum_specs ck_slh_dsa_s[] = { - {CKP_SLH_DSA_SHA2_128S, "CKP_SLH_DSA_SHA2_128S"}, - {CKP_SLH_DSA_SHAKE_128S, "CKP_SLH_DSA_SHAKE_128S"}, - {CKP_SLH_DSA_SHA2_128F, "CKP_SLH_DSA_SHA2_128F"}, - {CKP_SLH_DSA_SHAKE_128F, "CKP_SLH_DSA_SHAKE_128F"}, - {CKP_SLH_DSA_SHA2_192S, "CKP_SLH_DSA_SHA2_192S"}, - {CKP_SLH_DSA_SHAKE_192S, "CKP_SLH_DSA_SHAKE_192S"}, - {CKP_SLH_DSA_SHA2_192F, "CKP_SLH_DSA_SHA2_192F"}, - {CKP_SLH_DSA_SHAKE_192F, "CKP_SLH_DSA_SHAKE_192F"}, - {CKP_SLH_DSA_SHA2_256S, "CKP_SLH_DSA_SHA2_256S"}, - {CKP_SLH_DSA_SHAKE_256S, "CKP_SLH_DSA_SHAKE_256S"}, - {CKP_SLH_DSA_SHA2_256F, "CKP_SLH_DSA_SHA2_256F"}, - {CKP_SLH_DSA_SHAKE_256F, "CKP_SLH_DSA_SHAKE_256F"}, -}; // clang-format off static enum_specs ck_cls_s[] = { @@ -1064,8 +1097,6 @@ static enum_specs ck_ckd_s[] = { {CKD_BLAKE2B_512_KDF, "CKD_BLAKE2B_512_KDF"} }; -#define SZ_SPECS sizeof(enum_specs) - enum_spec ck_types[] = { {OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" }, {PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE" }, @@ -1237,7 +1268,7 @@ type_spec ck_attribute_specs[] = { { CKA_HSS_LMS_TYPES , "CKA_HSS_LMS_TYPES ", print_generic, NULL }, { CKA_HSS_LMOTS_TYPES , "CKA_HSS_LMOTS_TYPES ", print_generic, NULL }, { CKA_HSS_KEYS_REMAINING, "CKA_HSS_KEYS_REMAINING ", print_generic, NULL }, - { CKA_PARAMETER_SET , "CKA_PARAMETER_SET ", print_generic, NULL }, + { CKA_PARAMETER_SET , "CKA_PARAMETER_SET ", print_parameter_set, NULL }, { CKA_OBJECT_VALIDATION_FLAGS , "CKA_OBJECT_VALIDATION_FLAGS ", print_generic, NULL }, { CKA_VALIDATION_TYPE , "CKA_VALIDATION_TYPE ", print_generic, NULL }, { CKA_VALIDATION_VERSION , "CKA_VALIDATION_VERSION ", print_generic, NULL }, @@ -1260,8 +1291,8 @@ type_spec ck_attribute_specs[] = { { CKA_TRUST_IPSEC_IKE , "CKA_TRUST_IPSEC_IKE ", print_generic, NULL }, { CKA_TRUST_TIME_STAMPING , "CKA_TRUST_TIME_STAMPING ", print_generic, NULL }, { CKA_TRUST_OCSP_SIGNING , "CKA_TRUST_OCSP_SIGNING ", print_generic, NULL }, - { CKA_ENCAPSULATE , "CKA_ENCAPSULATE ", print_generic, NULL }, - { CKA_DECAPSULATE , "CKA_DECAPSULATE ", print_generic, NULL }, + { CKA_ENCAPSULATE , "CKA_ENCAPSULATE ", print_boolean, NULL }, + { CKA_DECAPSULATE , "CKA_DECAPSULATE ", print_boolean, NULL }, { CKA_HASH_OF_CERTIFICATE , "CKA_HASH_OF_CERTIFICATE ", print_generic, NULL }, { CKA_PUBLIC_CRC64_VALUE , "CKA_PUBLIC_CRC64_VALUE ", print_generic, NULL }, { CKA_SEED , "CKA_SEED ", print_generic, NULL }, @@ -1410,7 +1441,7 @@ print_token_info(FILE *f, CK_TOKEN_INFO *info) { CKF_SO_PIN_TO_BE_CHANGED , "CKF_SO_PIN_TO_BE_CHANGED " }, { CKF_ERROR_STATE , "CKF_ERROR_STATE " }, { CKF_SEED_RANDOM_REQUIRED , "CKF_SEED_RANDOM_REQUIRED " }, - { CKF_ASYNC_SESSION_SUPPORTED , "CKF_ASYNC_SESSION_SUPPORTED " } + { CKF_ASYNC_SESSION_SUPPORTED , "CKF_ASYNC_SESSION_SUPPORTED " }, }; fprintf(f, " label: '%32.32s'\n", info->label ); @@ -1516,11 +1547,21 @@ void print_attribute_list(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { CK_ULONG j, k; + CK_KEY_TYPE key_type = -1; int found; if (!pTemplate) return; + /* Some attributes are key type specific -- first check if we have a key type + * in the template and if so, store it */ + for (j = 0; j < ulCount ; j++) { + if (pTemplate[j].type == CKA_KEY_TYPE && pTemplate[j].pValue) { + key_type = *(CK_KEY_TYPE *)pTemplate[j].pValue; + break; + } + } + for(j = 0; j < ulCount ; j++) { found = 0; for(k = 0; k < ck_attribute_num; k++) { @@ -1528,10 +1569,11 @@ print_attribute_list(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) found = 1; fprintf(f, " %s ", ck_attribute_specs[k].name); if(pTemplate[j].pValue && ((CK_LONG) pTemplate[j].ulValueLen) > 0) { - ck_attribute_specs[k].display - (f, pTemplate[j].type, pTemplate[j].pValue, - pTemplate[j].ulValueLen, - ck_attribute_specs[k].arg); + ck_attribute_specs[k].display( + f, pTemplate[j].type, pTemplate[j].pValue, + pTemplate[j].ulValueLen, + ck_attribute_specs[k].arg, + key_type); } else { fprintf(f, "%s\n", buf_spec(pTemplate[j].pValue, pTemplate[j].ulValueLen)); } diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 31d00d3ebd..02b4113316 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -29,8 +29,7 @@ extern "C" { #endif -typedef void (display_func) \ - (FILE *, CK_LONG, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR); +typedef void (display_func) (FILE *, CK_LONG, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR, CK_KEY_TYPE); typedef struct { CK_ULONG type; @@ -76,10 +75,10 @@ enum ck_type { const char *lookup_enum_spec(enum_spec *spec, CK_ULONG value); const char *lookup_enum(CK_ULONG type, CK_ULONG value); -void print_enum (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg); -void print_boolean (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg); -void print_generic (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg); -void print_print (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg); +void print_enum (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_boolean (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_generic (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_print (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); void show_error (FILE *f, char *str, CK_RV rc); void print_ck_info(FILE *f, CK_INFO *info); diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 98d6ef55f8..d274462d40 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -59,6 +59,7 @@ pid_t initialized_pid = (pid_t)-1; static int in_finalize = 0; extern CK_FUNCTION_LIST pkcs11_function_list; extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; +extern CK_FUNCTION_LIST_3_2 pkcs11_function_list_3_2; int nesting = 0; #ifdef PKCS11_THREAD_LOCKING @@ -861,10 +862,11 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */ /* * Interfaces */ -#define NUM_INTERFACES 2 +#define NUM_INTERFACES 3 #define DEFAULT_INTERFACE 0 // clang-format off CK_INTERFACE interfaces[NUM_INTERFACES] = { + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&pkcs11_function_list_3_2, 0}, {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&pkcs11_function_list_3_0, 0}, {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&pkcs11_function_list, 0} }; @@ -1063,170 +1065,279 @@ void sc_pkcs11_free_lock(void) } CK_FUNCTION_LIST pkcs11_function_list = { - { 2, 20 }, /* Note: NSS/Firefox ignores this version number and uses C_GetInfo() */ - C_Initialize, - C_Finalize, - C_GetInfoV2, - C_GetFunctionList, - C_GetSlotList, - C_GetSlotInfo, - C_GetTokenInfo, - C_GetMechanismList, - C_GetMechanismInfo, - C_InitToken, - C_InitPIN, - C_SetPIN, - C_OpenSession, - C_CloseSession, - C_CloseAllSessions, - C_GetSessionInfo, - C_GetOperationState, - C_SetOperationState, - C_Login, - C_Logout, - C_CreateObject, - C_CopyObject, - C_DestroyObject, - C_GetObjectSize, - C_GetAttributeValue, - C_SetAttributeValue, - C_FindObjectsInit, - C_FindObjects, - C_FindObjectsFinal, - C_EncryptInit, - C_Encrypt, - C_EncryptUpdate, - C_EncryptFinal, - C_DecryptInit, - C_Decrypt, - C_DecryptUpdate, - C_DecryptFinal, - C_DigestInit, - C_Digest, - C_DigestUpdate, - C_DigestKey, - C_DigestFinal, - C_SignInit, - C_Sign, - C_SignUpdate, - C_SignFinal, - C_SignRecoverInit, - C_SignRecover, - C_VerifyInit, - C_Verify, - C_VerifyUpdate, - C_VerifyFinal, - C_VerifyRecoverInit, - C_VerifyRecover, - C_DigestEncryptUpdate, - C_DecryptDigestUpdate, - C_SignEncryptUpdate, - C_DecryptVerifyUpdate, - C_GenerateKey, - C_GenerateKeyPair, - C_WrapKey, - C_UnwrapKey, - C_DeriveKey, - C_SeedRandom, - C_GenerateRandom, - C_GetFunctionStatus, - C_CancelFunction, - C_WaitForSlotEvent + {2, 20}, /* Note: NSS/Firefox ignores this version number and uses C_GetInfo() */ + C_Initialize, + C_Finalize, + C_GetInfoV2, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, + C_DigestKey, + C_DigestFinal, + C_SignInit, + C_Sign, + C_SignUpdate, + C_SignFinal, + C_SignRecoverInit, + C_SignRecover, + C_VerifyInit, + C_Verify, + C_VerifyUpdate, + C_VerifyFinal, + C_VerifyRecoverInit, + C_VerifyRecover, + C_DigestEncryptUpdate, + C_DecryptDigestUpdate, + C_SignEncryptUpdate, + C_DecryptVerifyUpdate, + C_GenerateKey, + C_GenerateKeyPair, + C_WrapKey, + C_UnwrapKey, + C_DeriveKey, + C_SeedRandom, + C_GenerateRandom, + C_GetFunctionStatus, + C_CancelFunction, + C_WaitForSlotEvent }; /* Returned from getInterface */ CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0 = { - { 3, 0 }, - C_Initialize, - C_Finalize, - C_GetInfo, - C_GetFunctionList, - C_GetSlotList, - C_GetSlotInfo, - C_GetTokenInfo, - C_GetMechanismList, - C_GetMechanismInfo, - C_InitToken, - C_InitPIN, - C_SetPIN, - C_OpenSession, - C_CloseSession, - C_CloseAllSessions, - C_GetSessionInfo, - C_GetOperationState, - C_SetOperationState, - C_Login, - C_Logout, - C_CreateObject, - C_CopyObject, - C_DestroyObject, - C_GetObjectSize, - C_GetAttributeValue, - C_SetAttributeValue, - C_FindObjectsInit, - C_FindObjects, - C_FindObjectsFinal, - C_EncryptInit, - C_Encrypt, - C_EncryptUpdate, - C_EncryptFinal, - C_DecryptInit, - C_Decrypt, - C_DecryptUpdate, - C_DecryptFinal, - C_DigestInit, - C_Digest, - C_DigestUpdate, - C_DigestKey, - C_DigestFinal, - C_SignInit, - C_Sign, - C_SignUpdate, - C_SignFinal, - C_SignRecoverInit, - C_SignRecover, - C_VerifyInit, - C_Verify, - C_VerifyUpdate, - C_VerifyFinal, - C_VerifyRecoverInit, - C_VerifyRecover, - C_DigestEncryptUpdate, - C_DecryptDigestUpdate, - C_SignEncryptUpdate, - C_DecryptVerifyUpdate, - C_GenerateKey, - C_GenerateKeyPair, - C_WrapKey, - C_UnwrapKey, - C_DeriveKey, - C_SeedRandom, - C_GenerateRandom, - C_GetFunctionStatus, - C_CancelFunction, - C_WaitForSlotEvent, - C_GetInterfaceList, - C_GetInterface, - C_LoginUser, - C_SessionCancel, - C_MessageEncryptInit, - C_EncryptMessage, - C_EncryptMessageBegin, - C_EncryptMessageNext, - C_MessageEncryptFinal, - C_MessageDecryptInit, - C_DecryptMessage, - C_DecryptMessageBegin, - C_DecryptMessageNext, - C_MessageDecryptFinal, - C_MessageSignInit, - C_SignMessage, - C_SignMessageBegin, - C_SignMessageNext, - C_MessageSignFinal, - C_MessageVerifyInit, - C_VerifyMessage, - C_VerifyMessageBegin, - C_VerifyMessageNext, - C_MessageVerifyFinal + {3, 0}, + C_Initialize, + C_Finalize, + C_GetInfo, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, + C_DigestKey, + C_DigestFinal, + C_SignInit, + C_Sign, + C_SignUpdate, + C_SignFinal, + C_SignRecoverInit, + C_SignRecover, + C_VerifyInit, + C_Verify, + C_VerifyUpdate, + C_VerifyFinal, + C_VerifyRecoverInit, + C_VerifyRecover, + C_DigestEncryptUpdate, + C_DecryptDigestUpdate, + C_SignEncryptUpdate, + C_DecryptVerifyUpdate, + C_GenerateKey, + C_GenerateKeyPair, + C_WrapKey, + C_UnwrapKey, + C_DeriveKey, + C_SeedRandom, + C_GenerateRandom, + C_GetFunctionStatus, + C_CancelFunction, + C_WaitForSlotEvent, + C_GetInterfaceList, + C_GetInterface, + C_LoginUser, + C_SessionCancel, + C_MessageEncryptInit, + C_EncryptMessage, + C_EncryptMessageBegin, + C_EncryptMessageNext, + C_MessageEncryptFinal, + C_MessageDecryptInit, + C_DecryptMessage, + C_DecryptMessageBegin, + C_DecryptMessageNext, + C_MessageDecryptFinal, + C_MessageSignInit, + C_SignMessage, + C_SignMessageBegin, + C_SignMessageNext, + C_MessageSignFinal, + C_MessageVerifyInit, + C_VerifyMessage, + C_VerifyMessageBegin, + C_VerifyMessageNext, + C_MessageVerifyFinal +}; + +/* Returned from getInterface */ +CK_FUNCTION_LIST_3_2 pkcs11_function_list_3_2 = { + {3, 2}, + C_Initialize, + C_Finalize, + C_GetInfo, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, + C_DigestKey, + C_DigestFinal, + C_SignInit, + C_Sign, + C_SignUpdate, + C_SignFinal, + C_SignRecoverInit, + C_SignRecover, + C_VerifyInit, + C_Verify, + C_VerifyUpdate, + C_VerifyFinal, + C_VerifyRecoverInit, + C_VerifyRecover, + C_DigestEncryptUpdate, + C_DecryptDigestUpdate, + C_SignEncryptUpdate, + C_DecryptVerifyUpdate, + C_GenerateKey, + C_GenerateKeyPair, + C_WrapKey, + C_UnwrapKey, + C_DeriveKey, + C_SeedRandom, + C_GenerateRandom, + C_GetFunctionStatus, + C_CancelFunction, + C_WaitForSlotEvent, + C_GetInterfaceList, + C_GetInterface, + C_LoginUser, + C_SessionCancel, + C_MessageEncryptInit, + C_EncryptMessage, + C_EncryptMessageBegin, + C_EncryptMessageNext, + C_MessageEncryptFinal, + C_MessageDecryptInit, + C_DecryptMessage, + C_DecryptMessageBegin, + C_DecryptMessageNext, + C_MessageDecryptFinal, + C_MessageSignInit, + C_SignMessage, + C_SignMessageBegin, + C_SignMessageNext, + C_MessageSignFinal, + C_MessageVerifyInit, + C_VerifyMessage, + C_VerifyMessageBegin, + C_VerifyMessageNext, + C_MessageVerifyFinal, + C_EncapsulateKey, + C_DecapsulateKey, + C_VerifySignatureInit, + C_VerifySignature, + C_VerifySignatureUpdate, + C_VerifySignatureFinal, + C_GetSessionValidationFlags, + C_AsyncComplete, + C_AsyncGetID, + C_AsyncJoin, + C_WrapKeyAuthenticated, + C_UnwrapKeyAuthenticated, }; diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index b023911213..c166811ce1 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1786,6 +1786,122 @@ CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession) /* the session's handl return CKR_FUNCTION_NOT_SUPPORTED; } +CK_RV +C_EncapsulateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPublicKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_DecapsulateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPrivateKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_VerifySignatureInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_VerifySignatureFinal(CK_SESSION_HANDLE hSession) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, + CK_SESSION_VALIDATION_FLAGS_TYPE type, + CK_FLAGS_PTR pFlags) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_AsyncComplete(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ASYNC_DATA_PTR pResult) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_AsyncGetID(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG_PTR pulID) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_AsyncJoin(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG ulID, + CK_BYTE_PTR pData, + CK_ULONG ulData) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV +C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + return CKR_FUNCTION_NOT_SUPPORTED; +} + /* * Helper function to compare attributes on any sort of object */ diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index e480c710fa..bdf3e78bc0 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -50,8 +50,9 @@ /* Spy Module Function List */ static CK_FUNCTION_LIST_PTR pkcs11_spy = NULL; static CK_FUNCTION_LIST_3_0_PTR pkcs11_spy_3_0 = NULL; +static CK_FUNCTION_LIST_3_2_PTR pkcs11_spy_3_2 = NULL; /* Real Module Function List */ -static CK_FUNCTION_LIST_3_0_PTR po = NULL; +static CK_FUNCTION_LIST_3_2_PTR po = NULL; /* Real module interface list */ static CK_INTERFACE_PTR orig_interfaces = NULL; static unsigned long num_orig_interfaces = 0; @@ -61,13 +62,16 @@ static void *modhandle = NULL; static FILE *spy_output = NULL; static void * -allocate_function_list(int v3) +allocate_function_list(int v) { CK_FUNCTION_LIST_PTR list = NULL; CK_FUNCTION_LIST_3_0_PTR list_3_0 = NULL; + CK_FUNCTION_LIST_3_2_PTR list_3_2 = NULL; - if (v3) { + if (v == 30) { list = malloc(sizeof(CK_FUNCTION_LIST_3_0)); + } else if (v == 32) { + list = malloc(sizeof(CK_FUNCTION_LIST_3_2)); } else { list = malloc(sizeof(CK_FUNCTION_LIST)); } @@ -145,7 +149,7 @@ allocate_function_list(int v3) list->C_GetFunctionStatus = C_GetFunctionStatus; list->C_CancelFunction = C_CancelFunction; list->C_WaitForSlotEvent = C_WaitForSlotEvent; - if (!v3) { + if (v < 30) { return list; } @@ -178,14 +182,34 @@ allocate_function_list(int v3) list_3_0->C_VerifyMessageNext = C_VerifyMessageNext; list_3_0->C_MessageVerifyFinal = C_MessageVerifyFinal; - return list_3_0; + if (v < 32) { + return list_3_0; + } + + /* Add also PKCS #11 3.2 functions if requested and fixup version */ + list_3_2 = (CK_FUNCTION_LIST_3_2_PTR)list; + list_3_2->version.major = 3; + list_3_2->version.minor = 2; + list_3_2->C_EncapsulateKey = C_EncapsulateKey; + list_3_2->C_DecapsulateKey = C_DecapsulateKey; + list_3_2->C_VerifySignatureInit = C_VerifySignatureInit; + list_3_2->C_VerifySignature = C_VerifySignature; + list_3_2->C_VerifySignatureUpdate = C_VerifySignatureUpdate; + list_3_2->C_VerifySignatureFinal = C_VerifySignatureFinal; + list_3_2->C_GetSessionValidationFlags = C_GetSessionValidationFlags; + list_3_2->C_AsyncComplete = C_AsyncComplete; + list_3_2->C_AsyncGetID = C_AsyncGetID; + list_3_2->C_AsyncJoin = C_AsyncJoin; + list_3_2->C_WrapKeyAuthenticated = C_WrapKeyAuthenticated; + list_3_2->C_UnwrapKeyAuthenticated = C_UnwrapKeyAuthenticated; + return list_3_2; } /* The compatibility interfaces that can be returned from Interface functions * if the V3 API is used, but the proxied module does not support V3 API */ #define NUM_INTERFACES 1 CK_INTERFACE compat_interfaces[NUM_INTERFACES] = { - {(CK_UTF8CHAR_PTR)"PKCS 11", NULL, 0} + {(CK_UTF8CHAR_PTR) "PKCS 11", NULL, 0} }; CK_INTERFACE spy_interface = {(CK_UTF8CHAR_PTR)"PKCS 11", NULL, 0}; @@ -205,16 +229,24 @@ init_spy(void) #endif /* Allocates and initializes the pkcs11_spy structure */ - pkcs11_spy = allocate_function_list(0); + pkcs11_spy = allocate_function_list(2); if (pkcs11_spy == NULL) { return CKR_HOST_MEMORY; } - pkcs11_spy_3_0 = allocate_function_list(1); + pkcs11_spy_3_0 = allocate_function_list(30); if (pkcs11_spy_3_0 == NULL) { free(pkcs11_spy); pkcs11_spy = NULL; return CKR_HOST_MEMORY; } + pkcs11_spy_3_2 = allocate_function_list(32); + if (pkcs11_spy_3_2 == NULL) { + free(pkcs11_spy); + pkcs11_spy = NULL; + free(pkcs11_spy_3_0); + pkcs11_spy_3_0 = NULL; + return CKR_HOST_MEMORY; + } compat_interfaces[0].pFunctionList = pkcs11_spy; @@ -300,10 +332,12 @@ init_spy(void) pkcs11_spy = NULL; free(pkcs11_spy_3_0); pkcs11_spy_3_0 = NULL; + free(pkcs11_spy_3_2); + pkcs11_spy_3_2 = NULL; return CKR_DEVICE_ERROR; } modhandle = C_LoadModule(module, &po_v2); - po = (CK_FUNCTION_LIST_3_0_PTR) po_v2; + po = (CK_FUNCTION_LIST_3_2_PTR) po_v2; if (modhandle && po) { fprintf(spy_output, "Loaded: \"%s\"\n", module); } @@ -311,6 +345,7 @@ init_spy(void) po = NULL; free(pkcs11_spy); free(pkcs11_spy_3_0); + free(pkcs11_spy_3_2); rv = CKR_GENERAL_ERROR; } @@ -360,14 +395,14 @@ static void spy_dump_string_in(const char *name, CK_VOID_PTR data, CK_ULONG size) { fprintf(spy_output, "[in] %s ", name); - print_generic(spy_output, 0, data, size, NULL); + print_generic(spy_output, 0, data, size, NULL, -1); } static void spy_dump_string_out(const char *name, CK_VOID_PTR data, CK_ULONG size) { fprintf(spy_output, "[out] %s ", name); - print_generic(spy_output, 0, data, size, NULL); + print_generic(spy_output, 0, data, size, NULL, -1); } static void @@ -506,9 +541,9 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism, bool is_c_m CK_ECDH1_DERIVE_PARAMS *param = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter; fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); fprintf(spy_output, "[in] %s->pParameter->pSharedData[ulSharedDataLen] = ", name); - print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); + print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL, -1); fprintf(spy_output, "[in] %s->pParameter->pPublicData[ulPublicDataLen] = ", name); - print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); + print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL, -1); break; } case CKM_ECMQV_DERIVE: { @@ -522,13 +557,13 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism, bool is_c_m CK_ECMQV_DERIVE_PARAMS *param = (CK_ECMQV_DERIVE_PARAMS *)pMechanism->pParameter; fprintf(spy_output, "[in] %s->pParameter->kdf = %s\n", name, lookup_enum(CKD_T, param->kdf)); fprintf(spy_output, "%s->pParameter->pSharedData[ulSharedDataLen] = ", name); - print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL); + print_generic(spy_output, 0, param->pSharedData, param->ulSharedDataLen, NULL, -1); fprintf(spy_output, "%s->pParameter->pPublicData[ulPublicDataLen] = ", name); - print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL); + print_generic(spy_output, 0, param->pPublicData, param->ulPublicDataLen, NULL, -1); fprintf(spy_output, "%s->pParameter->ulPrivateDataLen = %lu", name, param->ulPrivateDataLen); fprintf(spy_output, "%s->pParameter->hPrivateData = %lu", name, param->hPrivateData); fprintf(spy_output, "%s->pParameter->pPublicData2[ulPublicDataLen2] = ", name); - print_generic(spy_output, 0, param->pPublicData2, param->ulPublicDataLen2, NULL); + print_generic(spy_output, 0, param->pPublicData2, param->ulPublicDataLen2, NULL, -1); fprintf(spy_output, "%s->pParameter->publicKey = %lu", name, param->publicKey); break; } @@ -566,6 +601,58 @@ spy_dump_mechanism_in(const char *name, CK_MECHANISM_PTR pMechanism, bool is_c_m fprintf(spy_output, "[in] %s->pParameter->sLen = %lu\n", name, param->sLen); break; } + case CKM_ML_DSA: + case CKM_HASH_ML_DSA_SHA224: + case CKM_HASH_ML_DSA_SHA256: + case CKM_HASH_ML_DSA_SHA384: + case CKM_HASH_ML_DSA_SHA512: + case CKM_HASH_ML_DSA_SHA3_224: + case CKM_HASH_ML_DSA_SHA3_256: + case CKM_HASH_ML_DSA_SHA3_384: + case CKM_HASH_ML_DSA_SHA3_512: + case CKM_HASH_ML_DSA_SHAKE128: + case CKM_HASH_ML_DSA_SHAKE256: + case CKM_SLH_DSA: + case CKM_HASH_SLH_DSA_SHA224: + case CKM_HASH_SLH_DSA_SHA256: + case CKM_HASH_SLH_DSA_SHA384: + case CKM_HASH_SLH_DSA_SHA512: + case CKM_HASH_SLH_DSA_SHA3_224: + case CKM_HASH_SLH_DSA_SHA3_256: + case CKM_HASH_SLH_DSA_SHA3_384: + case CKM_HASH_SLH_DSA_SHA3_512: + case CKM_HASH_SLH_DSA_SHAKE128: + case CKM_HASH_SLH_DSA_SHAKE256: { + if (pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); + break; + } + CK_SIGN_ADDITIONAL_CONTEXT *param = (CK_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hedgeVariant = %s\n", name, + lookup_enum(HG_T, param->hedgeVariant)); + fprintf(spy_output, "%s->pParameter->pContent[ulContextLen] = ", name); + print_generic(spy_output, 0, param->pContext, param->ulContextLen, NULL, 1); + break; + } + case CKM_HASH_ML_DSA: + case CKM_HASH_SLH_DSA: { + if (pMechanism->ulParameterLen != sizeof(CK_HASH_SIGN_ADDITIONAL_CONTEXT)) { + snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); + spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); + fprintf(spy_output, "(unknown type -- the length does not match any known type\n"); + break; + } + CK_HASH_SIGN_ADDITIONAL_CONTEXT *param = (CK_HASH_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter; + fprintf(spy_output, "[in] %s->pParameter->hedgeVariant = %s\n", name, + lookup_enum(HG_T, param->hedgeVariant)); + fprintf(spy_output, "%s->pParameter->pContent[ulContextLen] = ", name); + print_generic(spy_output, 0, param->pContext, param->ulContextLen, NULL, -1); + fprintf(spy_output, "[in] %s->pParameter->hash = %s\n", name, + lookup_enum(MEC_T, param->hash)); + break; + } default: snprintf(param_name, sizeof(param_name), "%s->pParameter[ulParameterLen]", name); spy_dump_string_in(param_name, pMechanism->pParameter, pMechanism->ulParameterLen); @@ -2074,7 +2161,7 @@ C_MessageSignFinal(CK_SESSION_HANDLE hSession) } CK_RV -C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) +C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; @@ -2138,3 +2225,253 @@ CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession) rv = po->C_MessageVerifyFinal(hSession); return retne(rv); } + +CK_RV +C_EncapsulateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPublicKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + CK_RV rv; + + enter("C_EncapsulateKey"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_mechanism_in("pMechanism", pMechanism, false); + spy_dump_ulong_in("hPublicKey", hPublicKey); + spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); + rv = po->C_EncapsulateKey(hSession, pMechanism, hPublicKey, pTemplate, ulAttributeCount, + pCiphertext, pulCiphertextLen, phKey); + if (rv == CKR_OK) { + spy_dump_string_out("pCiphertext[*pulCiphertextLen]", + pCiphertext, *pulCiphertextLen); + spy_dump_ulong_out("phKey", *phKey); + } + return retne(rv); +} + + + +CK_RV +C_DecapsulateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPrivateKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + CK_RV rv; + + enter("C_DecapsulateKey"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_mechanism_in("pMechanism", pMechanism, false); + spy_dump_ulong_in("hPrivateKey", hPrivateKey); + spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); + spy_dump_string_in("pCiphertext[ulCiphertextLen]", + pCiphertext, ulCiphertextLen); + rv = po->C_DecapsulateKey(hSession, pMechanism, hPrivateKey, pTemplate, ulAttributeCount, + pCiphertext, ulCiphertextLen, phKey); + if (rv == CKR_OK) { + spy_dump_ulong_out("phKey", *phKey); + } + return retne(rv); +} + +CK_RV +C_VerifySignatureInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + CK_RV rv; + + enter("C_VerifySignatureInit"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_mechanism_in("pMechanism", pMechanism, false); + spy_dump_ulong_in("hKey", hKey); + spy_dump_string_in("pSignature[ulSignatureLen]", + pSignature, ulSignatureLen); + rv = po->C_VerifySignatureInit(hSession, pMechanism, hKey, + pSignature, ulSignatureLen); + return retne(rv); +} + +CK_RV +C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen) +{ + CK_RV rv; + + enter("C_VerifySignature"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_string_in("pData[ulDataLen]", pData, ulDataLen); + rv = po->C_VerifySignature(hSession, pData, ulDataLen); + return retne(rv); +} + +CK_RV +C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) +{ + CK_RV rv; + + enter("C_VerifySignatureUpdate"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_string_in("pPart[ulPartLen]", pPart, ulPartLen); + rv = po->C_VerifySignatureUpdate(hSession, pPart, ulPartLen); + return retne(rv); +} + +CK_RV +C_VerifySignatureFinal(CK_SESSION_HANDLE hSession) +{ + CK_RV rv; + + enter("C_VerifySignatureFinal"); + spy_dump_ulong_in("hSession", hSession); + rv = po->C_VerifySignatureFinal(hSession); + return retne(rv); +} + +CK_RV +C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, + CK_SESSION_VALIDATION_FLAGS_TYPE type, + CK_FLAGS_PTR pFlags) +{ + CK_RV rv; + + enter("C_GetSessionValidationFlags"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_ulong_in("type", type); + rv = po->C_GetSessionValidationFlags(hSession, type, pFlags); + if (rv == CKR_OK) { + spy_dump_ulong_out("pFlags", *pFlags); + } + return retne(rv); +} + +CK_RV +C_AsyncComplete(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ASYNC_DATA_PTR pResult) +{ + CK_RV rv; + + enter("C_AsyncComplete"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_string_in("pFunctionName", pFunctionName, strlen((char *)pFunctionName)); + rv = po->C_AsyncComplete(hSession, pFunctionName, pResult); + if (rv == CKR_OK) { + if (pResult == NULL) { + fprintf(spy_output, "[out] pResult = NULL\n"); + } else { + spy_dump_ulong_out("pResult->ulVersion", pResult->ulVersion); + spy_dump_string_out("pResult->pValue[pResult->ulValue]", + pResult->pValue, pResult->ulValue); + spy_dump_ulong_out("pResult->hObject", pResult->hObject); + spy_dump_ulong_out("pResult->hAdditionalObject", pResult->hAdditionalObject); + } + } + return retne(rv); +} + +CK_RV +C_AsyncGetID(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG_PTR pulID) +{ + CK_RV rv; + + enter("C_AsyncGetID"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_string_in("pFunctionName", pFunctionName, strlen((char *)pFunctionName)); + rv = po->C_AsyncGetID(hSession, pFunctionName, pulID); + if (rv == CKR_OK) { + spy_dump_ulong_out("pulID", *pulID); + } + return retne(rv); +} + +CK_RV +C_AsyncJoin(CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG ulID, + CK_BYTE_PTR pData, + CK_ULONG ulData) +{ + CK_RV rv; + + enter("C_AsyncJoin"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_string_in("pFunctionName", pFunctionName, strlen((char *)pFunctionName)); + spy_dump_ulong_in("ulID", ulID); + rv = po->C_AsyncJoin(hSession, pFunctionName, ulID, pData, ulData); + if (rv == CKR_OK) { + spy_dump_string_out("pData[ulData]", pData, ulData); + } + return retne(rv); +} + +CK_RV +C_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen) +{ + CK_RV rv; + + enter("C_WrapKeyAuthenticated"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_mechanism_in("pMechanism", pMechanism, false); + spy_dump_ulong_in("hWrappingKey", hWrappingKey); + spy_dump_ulong_in("hKey", hKey); + spy_dump_string_in("pAssociatedData[ulAssociatedDataLen]", + pAssociatedData, ulAssociatedDataLen); + rv = po->C_WrapKeyAuthenticated(hSession, pMechanism, hWrappingKey, hKey, + pAssociatedData, ulAssociatedDataLen, pWrappedKey, pulWrappedKeyLen); + if (rv == CKR_OK) { + spy_dump_string_out("pWrappedKey[*pulWrappedKeyLen]", pWrappedKey, *pulWrappedKeyLen); + } else if (rv == CKR_BUFFER_TOO_SMALL) { + spy_dump_ulong_out("pulWrappedKeyLen", *pulWrappedKeyLen); + } + + return retne(rv); +} + +CK_RV +C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_OBJECT_HANDLE_PTR phKey) +{ + CK_RV rv; + + enter("C_UnwrapKeyAuthenticated"); + spy_dump_ulong_in("hSession", hSession); + spy_dump_mechanism_in("pMechanism", pMechanism, false); + spy_dump_ulong_in("hUnwrappingKey", hUnwrappingKey); + spy_dump_string_in("pWrappedKey[ulWrappedKeyLen]", pWrappedKey, ulWrappedKeyLen); + spy_attribute_list_in("pTemplate", pTemplate, ulAttributeCount); + spy_dump_string_in("pAssociatedData[ulAssociatedDataLen]", + pAssociatedData, ulAssociatedDataLen); + rv = po->C_UnwrapKeyAuthenticated(hSession, pMechanism, hUnwrappingKey, + pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, + pAssociatedData, ulAssociatedDataLen, phKey); + if (rv == CKR_OK) + spy_dump_ulong_out("hKey", *phKey); + return retne(rv); +} diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index fe59782614..72e38b722b 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -1,5 +1,6 @@ #ifndef PKCS11_H #define PKCS11_H 1 +// clang-fromat off #if defined(__cplusplus) extern "C" { @@ -2331,7 +2332,7 @@ extern CK_RV C_AsyncJoin(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_BYTE *, CK_ULONG); extern CK_RV C_WrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, - CK_BYTE *, CK_ULONG *, CK_BYTE *, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); extern CK_RV C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, CK_BYTE *, @@ -2523,7 +2524,7 @@ typedef CK_RV (* CK_C_AsyncJoin)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_BYTE *, CK_ULONG); typedef CK_RV (* CK_C_WrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, - CK_BYTE *, CK_ULONG *, CK_BYTE *, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); typedef CK_RV (* CK_C_UnwrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, CK_BYTE *, @@ -2836,4 +2837,5 @@ struct CK_FUNCTION_LIST { } #endif +// clang-fromat on #endif /* PKCS11_H */ diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ff1d4b3c29..24b9b582b5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -197,6 +197,7 @@ enum { OPT_KEY_USAGE_DECRYPT, OPT_KEY_USAGE_DERIVE, OPT_KEY_USAGE_WRAP, + OPT_KEY_USAGE_ENCAPSULATE, OPT_PRIVATE, OPT_SENSITIVE, OPT_EXTRACTABLE, @@ -285,6 +286,7 @@ static const struct option options[] = { { "usage-decrypt", 0, NULL, OPT_KEY_USAGE_DECRYPT }, { "usage-derive", 0, NULL, OPT_KEY_USAGE_DERIVE }, { "usage-wrap", 0, NULL, OPT_KEY_USAGE_WRAP }, + { "usage-encapsulate", 0, NULL, OPT_KEY_USAGE_ENCAPSULATE }, { "write-object", 1, NULL, 'w' }, { "read-object", 0, NULL, 'r' }, { "delete-object", 0, NULL, 'b' }, @@ -480,6 +482,7 @@ static int opt_key_usage_sign = 0; static int opt_key_usage_decrypt = 0; static int opt_key_usage_derive = 0; static int opt_key_usage_wrap = 0; +static int opt_key_usage_encapsulate = 0; static int opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */ static int opt_derive_pass_der = 0; static unsigned long opt_random_bytes = 0; @@ -1133,6 +1136,10 @@ int main(int argc, char * argv[]) opt_key_usage_wrap = 1; opt_key_usage_default = 0; break; + case OPT_KEY_USAGE_ENCAPSULATE: + opt_key_usage_encapsulate = 1; + opt_key_usage_default = 0; + break; case OPT_PRIVATE: opt_is_private = 1; break; @@ -2577,6 +2584,8 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_BYTE_PTR sig_buffer = NULL; CK_MECHANISM mech; CK_RSA_PKCS_PSS_PARAMS pss_params; + CK_SIGN_ADDITIONAL_CONTEXT sign_params = {0}; + CK_HASH_SIGN_ADDITIONAL_CONTEXT hash_sign_params = {0}; CK_MAC_GENERAL_PARAMS mac_gen_param; CK_EDDSA_PARAMS eddsa_params = { .phFlag = CK_FALSE, @@ -2596,8 +2605,18 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.mechanism = opt_mechanism; hashlen = parse_pss_params(session, key, &mech, &pss_params); - /* support pure EdDSA only */ - if (opt_mechanism == CKM_EDDSA) { + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + sz = read(fd, in_buffer, sizeof(in_buffer)); + if (sz < 0) + util_fatal("Cannot read from %s: %m", opt_input); + + switch (opt_mechanism) { + case CKM_EDDSA: { + /* support pure EdDSA only */ const struct ec_curve_info *curve; unsigned char *ec_params; CK_ULONG ec_params_size = 0; @@ -2617,22 +2636,16 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } + break; } - - if (opt_input == NULL) - fd = 0; - else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) - util_fatal("Cannot open %s: %m", opt_input); - - sz = read(fd, in_buffer, sizeof(in_buffer)); - if (sz < 0) - util_fatal("Cannot read from %s: %m", opt_input); - - if (opt_mechanism == CKM_RSA_PKCS_PSS && (size_t)sz != hashlen) { - util_fatal("For %s mechanism, message size (got %zd bytes) " - "must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), sz, hashlen); - } else if (opt_mechanism == CKM_AES_CMAC_GENERAL) { + case CKM_RSA_PKCS_PSS: + if ((size_t)sz != hashlen) { + util_fatal("For %s mechanism, message size (got %zd bytes) " + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } + break; + case CKM_AES_CMAC_GENERAL: if (opt_mac_gen_param == 0 || opt_mac_gen_param > 16) { util_fatal("For %s mechanism, the option --mac-general-param " "is mandatory and its value must be comprised between 1 and " @@ -2642,6 +2655,50 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mac_gen_param = opt_mac_gen_param; mech.pParameter = &mac_gen_param; mech.ulParameterLen = sizeof(CK_MAC_GENERAL_PARAMS); + break; + case CKM_ML_DSA: + case CKM_HASH_ML_DSA_SHA224: + case CKM_HASH_ML_DSA_SHA256: + case CKM_HASH_ML_DSA_SHA384: + case CKM_HASH_ML_DSA_SHA512: + case CKM_HASH_ML_DSA_SHA3_224: + case CKM_HASH_ML_DSA_SHA3_256: + case CKM_HASH_ML_DSA_SHA3_384: + case CKM_HASH_ML_DSA_SHA3_512: + case CKM_HASH_ML_DSA_SHAKE128: + case CKM_HASH_ML_DSA_SHAKE256: + case CKM_SLH_DSA: + case CKM_HASH_SLH_DSA_SHA224: + case CKM_HASH_SLH_DSA_SHA256: + case CKM_HASH_SLH_DSA_SHA384: + case CKM_HASH_SLH_DSA_SHA512: + case CKM_HASH_SLH_DSA_SHA3_224: + case CKM_HASH_SLH_DSA_SHA3_256: + case CKM_HASH_SLH_DSA_SHA3_384: + case CKM_HASH_SLH_DSA_SHA3_512: + case CKM_HASH_SLH_DSA_SHAKE128: + case CKM_HASH_SLH_DSA_SHAKE256: + /* TODO allow setting hedge and context */ + mech.pParameter = &sign_params; + mech.ulParameterLen = sizeof(CK_SIGN_ADDITIONAL_CONTEXT); + break; + case CKM_HASH_ML_DSA: + case CKM_HASH_SLH_DSA: + if (opt_hash_alg == 0) { + util_fatal("The mechanism %s requires a hash-algorithm", + p11_mechanism_to_name(opt_mechanism)); + } + hashlen = hash_length(opt_hash_alg); + if ((size_t)sz != hashlen) { + util_fatal("For %s mechanism, message size (got %zd bytes) " + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } + hash_sign_params.hash = opt_hash_alg; + /* TODO allow setting hedge and context */ + mech.pParameter = &hash_sign_params; + mech.ulParameterLen = sizeof(CK_HASH_SIGN_ADDITIONAL_CONTEXT); + break; } rv = CKR_CANCEL; @@ -2739,6 +2796,8 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_EDDSA_PARAMS eddsa_params = { .phFlag = CK_FALSE, }; + CK_SIGN_ADDITIONAL_CONTEXT sign_params = {0}; + CK_HASH_SIGN_ADDITIONAL_CONTEXT hash_sign_params = {0}; CK_RV rv; CK_ULONG sig_len = 0; int fd, fd2; @@ -2766,8 +2825,36 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } } - /* support pure EdDSA only */ - if (opt_mechanism == CKM_EDDSA) { + /* Open a signature file */ + if (opt_signature_file == NULL) + util_fatal("No file with signature provided. Use --signature-file"); + else if ((fd2 = open(opt_signature_file, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_signature_file); + else if (fstat(fd2, &sig_st) != 0) + util_fatal("Couldn't get size of file \"", opt_signature_file); + sig_len = sig_st.st_size; + sig_buffer = malloc(sig_len); + if (!sig_buffer) + util_fatal("malloc() failure\n"); + sz2 = read(fd2, sig_buffer, sig_len); + if (sz2 < 0) + util_fatal("Cannot read from %s: %m", opt_signature_file); + + close(fd2); + + /* Open the data file */ + if (opt_input == NULL) + fd = 0; + else if ((fd = open(opt_input, O_RDONLY | O_BINARY)) < 0) + util_fatal("Cannot open %s: %m", opt_input); + + sz = read(fd, in_buffer, sizeof(in_buffer)); + if (sz < 0) + util_fatal("Cannot read from %s: %m", opt_input); + + switch (opt_mechanism) { + case CKM_EDDSA: { + /* support pure EdDSA only */ const struct ec_curve_info *curve; unsigned char *ec_params; CK_ULONG ec_params_size = 0; @@ -2787,30 +2874,18 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.pParameter = &eddsa_params; mech.ulParameterLen = (CK_ULONG)sizeof(eddsa_params); } + break; } - - /* Open a signature file */ - if (opt_signature_file == NULL) - util_fatal("No file with signature provided. Use --signature-file"); - else if ((fd2 = open(opt_signature_file, O_RDONLY|O_BINARY)) < 0) - util_fatal("Cannot open %s: %m", opt_signature_file); - else if (fstat(fd2, &sig_st) != 0) - util_fatal("Couldn't get size of file \"", opt_signature_file); - sig_len = sig_st.st_size; - sig_buffer = malloc(sig_len); - if (!sig_buffer) - util_fatal("malloc() failure\n"); - sz2 = read(fd2, sig_buffer, sig_len); - if (sz2 < 0) - util_fatal("Cannot read from %s: %m", opt_signature_file); - - close(fd2); - - if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || - opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || - opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224 || - opt_mechanism == CKM_ECDSA_SHA3_224 || opt_mechanism == CKM_ECDSA_SHA3_256 || - opt_mechanism == CKM_ECDSA_SHA3_384 || opt_mechanism == CKM_ECDSA_SHA3_512) { + case CKM_ECDSA: + case CKM_ECDSA_SHA1: + case CKM_ECDSA_SHA256: + case CKM_ECDSA_SHA384: + case CKM_ECDSA_SHA512: + case CKM_ECDSA_SHA224: + case CKM_ECDSA_SHA3_224: + case CKM_ECDSA_SHA3_256: + case CKM_ECDSA_SHA3_384: + case CKM_ECDSA_SHA3_512: if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { @@ -2844,23 +2919,15 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, memcpy(sig_buffer, rs_buffer, rs_len); sz2 = rs_len; } - } - - /* Open the data file */ - if (opt_input == NULL) - fd = 0; - else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) - util_fatal("Cannot open %s: %m", opt_input); - - sz = read(fd, in_buffer, sizeof(in_buffer)); - if (sz < 0) - util_fatal("Cannot read from %s: %m", opt_input); - - if (opt_mechanism == CKM_RSA_PKCS_PSS && (size_t)sz != hashlen) { - util_fatal("For %s mechanism, message size (got %zd bytes)" - " must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), sz, hashlen); - } else if (opt_mechanism == CKM_AES_CMAC_GENERAL) { + break; + case CKM_RSA_PKCS_PSS: + if ((size_t)sz != hashlen) { + util_fatal("For %s mechanism, message size (got %zd bytes)" + " must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } + break; + case CKM_AES_CMAC_GENERAL: if (opt_mac_gen_param == 0 || opt_mac_gen_param > 16) { util_fatal("For %s mechanism, the option --mac-general-param " "is mandatory and its value must be comprised between 1 and " @@ -2870,6 +2937,50 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mac_gen_param = opt_mac_gen_param; mech.pParameter = &mac_gen_param; mech.ulParameterLen = sizeof(CK_MAC_GENERAL_PARAMS); + break; + case CKM_ML_DSA: + case CKM_HASH_ML_DSA_SHA224: + case CKM_HASH_ML_DSA_SHA256: + case CKM_HASH_ML_DSA_SHA384: + case CKM_HASH_ML_DSA_SHA512: + case CKM_HASH_ML_DSA_SHA3_224: + case CKM_HASH_ML_DSA_SHA3_256: + case CKM_HASH_ML_DSA_SHA3_384: + case CKM_HASH_ML_DSA_SHA3_512: + case CKM_HASH_ML_DSA_SHAKE128: + case CKM_HASH_ML_DSA_SHAKE256: + case CKM_SLH_DSA: + case CKM_HASH_SLH_DSA_SHA224: + case CKM_HASH_SLH_DSA_SHA256: + case CKM_HASH_SLH_DSA_SHA384: + case CKM_HASH_SLH_DSA_SHA512: + case CKM_HASH_SLH_DSA_SHA3_224: + case CKM_HASH_SLH_DSA_SHA3_256: + case CKM_HASH_SLH_DSA_SHA3_384: + case CKM_HASH_SLH_DSA_SHA3_512: + case CKM_HASH_SLH_DSA_SHAKE128: + case CKM_HASH_SLH_DSA_SHAKE256: + /* TODO allow setting hedge and context */ + mech.pParameter = &sign_params; + mech.ulParameterLen = sizeof(CK_SIGN_ADDITIONAL_CONTEXT); + break; + case CKM_HASH_ML_DSA: + case CKM_HASH_SLH_DSA: + if (opt_hash_alg == 0) { + util_fatal("The mechanism %s requires a hash-algorithm", + p11_mechanism_to_name(opt_mechanism)); + } + hashlen = hash_length(opt_hash_alg); + if ((size_t)sz != hashlen) { + util_fatal("For %s mechanism, message size (got %zd bytes) " + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), sz, hashlen); + } + hash_sign_params.hash = opt_hash_alg; + /* TODO allow setting hedge and context */ + mech.pParameter = &hash_sign_params; + mech.ulParameterLen = sizeof(CK_HASH_SIGN_ADDITIONAL_CONTEXT); + break; } rv = CKR_CANCEL; @@ -3339,6 +3450,9 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, {CKA_SENSITIVE, &_true, sizeof(_true)}, }; unsigned long int gost_key_type = -1; + CK_ML_DSA_PARAMETER_SET_TYPE ml_dsa_parameter_set = 0; + CK_ML_KEM_PARAMETER_SET_TYPE ml_kem_parameter_set = 0; + CK_SLH_DSA_PARAMETER_SET_TYPE slh_dsa_parameter_set = 0; int n_privkey_attr = 4; CK_ULONG key_type = CKK_RSA; CK_RV rv; @@ -3573,32 +3687,121 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true)); n_privkey_attr++; } - } - else if (strncmp(type, "ML-DSA-", strlen("ML-DSA-")) == 0 || strncmp(type, "ml-dsa-", strlen("ml-dsa-")) == 0) { + } else if (strncasecmp(type, "ML-DSA-", strlen("ML-DSA-")) == 0) { CK_MECHANISM_TYPE mtypes[] = {CKM_ML_DSA_KEY_PAIR_GEN}; - size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); - int ii; - CK_ML_DSA_PARAMETER_SET_TYPE parameter_set = 0; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); key_type = CKK_ML_DSA; - if (strlen(type) != strlen("ML-DSA-") + 2) { - util_fatal("Invalid ML-DSA key type '%s'", type); - } else if (strcmp(type, "ML-DSA-44")) { - parameter_set = CKP_ML_DSA_44; - } else if (strcmp(type, "ML-DSA-44")) { - parameter_set = CKP_ML_DSA_44; - } else if (strcmp(type, "ML-DSA-44")) { - parameter_set = CKP_ML_DSA_44; + if (strcmp(type, "ML-DSA-44") == 0) { + ml_dsa_parameter_set = CKP_ML_DSA_44; + } else if (strcmp(type, "ML-DSA-65")) { + ml_dsa_parameter_set = CKP_ML_DSA_65; + } else if (strcmp(type, "ML-DSA-87")) { + ml_dsa_parameter_set = CKP_ML_DSA_87; } else { util_fatal("Invalid ML-DSA key type '%s'", type); } if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) - util_fatal("Generate RSA mechanism not supported"); - } - else { + util_fatal("Generate ML-DSA mechanism not supported"); + + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); + n_privkey_attr++; + + if (opt_key_usage_default || opt_key_usage_sign) { + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true)); + n_privkey_attr++; + } + + } else if (strncasecmp(type, "ML-KEM-", strlen("ML-KEM-")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_ML_KEM_KEY_PAIR_GEN}; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); + + key_type = CKK_ML_KEM; + + if (strcmp(type, "ML-KEM-512") == 0) { + ml_kem_parameter_set = CKP_ML_KEM_512; + } else if (strcmp(type, "ML-KEM-768")) { + ml_kem_parameter_set = CKP_ML_KEM_512; + } else if (strcmp(type, "ML-KEM-1024")) { + ml_kem_parameter_set = CKP_ML_KEM_1024; + } else { + util_fatal("Invalid ML-KEM key type '%s'", type); + } + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate ML-KEM mechanism not supported"); + + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + n_privkey_attr++; + + if (opt_key_usage_default || opt_key_usage_encapsulate) { + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ENCAPSULATE, &_true, sizeof(_true)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DECAPSULATE, &_true, sizeof(_true)); + n_privkey_attr++; + } + + } else if (strncasecmp(type, "SLH-DSA-", strlen("SLH-DSA-")) == 0) { + CK_MECHANISM_TYPE mtypes[] = {CKM_SLH_DSA_KEY_PAIR_GEN}; + size_t mtypes_num = sizeof(mtypes) / sizeof(mtypes[0]); + + key_type = CKK_SLH_DSA; + + if (strcmp(type, "SLH-DSA-SHA2-128S") == 0) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_128S; + } else if (strcmp(type, "SLH-DSA-SHAKE-128S")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_128S; + } else if (strcmp(type, "SLH-DSA-SHA2-128F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_128F; + } else if (strcmp(type, "SLH-DSA-SHAKE-128F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_128F; + } else if (strcmp(type, "SLH-DSA-SHA2-192S")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_192S; + } else if (strcmp(type, "SLH-DSA-SHAKE-192S")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_192S; + } else if (strcmp(type, "SLH-DSA-SHA2-192F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_192F; + } else if (strcmp(type, "SLH-DSA-SHAKE-192F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_192F; + } else if (strcmp(type, "SLH-DSA-SHA2-256S")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_256S; + } else if (strcmp(type, "SLH-DSA-SHAKE-256S")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_256S; + } else if (strcmp(type, "SLH-DSA-SHA2-256F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_256F; + } else if (strcmp(type, "SLH-DSA-SHAKE-256F")) { + slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_256F; + } else { + util_fatal("Invalid SLH-DSA key type '%s'", type); + } + + if (!opt_mechanism_used) + if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate SLH-DSA mechanism not supported"); + + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + n_privkey_attr++; + + if (opt_key_usage_default || opt_key_usage_sign) { + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); + n_pubkey_attr++; + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true)); + n_privkey_attr++; + } + + } else { util_fatal("Unknown key pair type %s", type); } @@ -4431,7 +4634,7 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct generalkey_info *ec) const BIGNUM *bignum; if (!src) return -1; - gost->param_oid.len = i2d_ECParameters((EC_KEY *)src, &gosect->param_oid.value); + ec->param_oid.len = i2d_ECParameters((EC_KEY *)src, &ec->param_oid.value); #else BIGNUM *bignum = NULL; ec->param_oid.len = i2d_KeyParams(pkey, &ec->param_oid.value); @@ -4479,71 +4682,101 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct generalkey_info *ec) return -1; point = ec->public.value; ASN1_put_object(&point, 0, (int)point_len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); - header_len = point-ec->public.value; + header_len = point - ec->public.value; memcpy(point, buf, point_len); - ec->public.len = header_len+point_len; + ec->public.len = header_len + point_len; #ifdef EC_POINT_NO_ASN1_OCTET_STRING // workaround for non-compliant cards not expecting DER encoding ec->public.len -= header_len; - gost->public.value += header_len; + ec->public.value += header_len; // store header_len to restore public.value before free it - gost->header_len = header_len; + ec->header_len = header_len; #endif } return 0; } +#if OPENSSL_VERSION_NUMBER >= 0x30500000L static int -parse_ml_dsa_pkey(EVP_PKEY *pkey, int private, struct pqckey_info *ml_dsa) +parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info *pqc) { -#if OPENSSL_VERSION_NUMBER >= 0x30500000L - if ((ml_dsa->type = EVP_PKEY_get_id(pkey)) == -1) { + int rc; + + /* FIXME convert the type to parameter set? */ + if ((pqc->type = EVP_PKEY_get_id(pkey)) == -1) { return -1; } if (private) { size_t priv_len; + char *seed_param = NULL; + + /* Some keys might have only the seed -- skip if not available */ + rc = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len); + if (rc == 1) { + pqc->private.len = priv_len; + if (!(pqc->private.value = OPENSSL_malloc(priv_len))) { + return -1; + } + rc = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, + pqc->private.value, priv_len, NULL); + if (rc != 1) { + OPENSSL_free(pqc->private.value); - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len) != 1) { - return -1; - } - ml_dsa->private.len = priv_len; - if (!(ml_dsa->private.value = OPENSSL_malloc(priv_len))) { - return -1; + return -1; + } } - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, ml_dsa->private.value, priv_len, NULL) != 1) { - OPENSSL_free(ml_dsa->private.value); - return -1; + + switch (type) { + case CKK_ML_DSA: + seed_param = OSSL_PKEY_PARAM_ML_DSA_SEED; + break; + case CKK_SLH_DSA: + seed_param = OSSL_PKEY_PARAM_SLH_DSA_SEED; + break; } - ml_dsa->seed.len = 32; - if (!(ml_dsa->seed.value = OPENSSL_malloc(ml_dsa->seed.len))) { - OPENSSL_free(ml_dsa->private.value); - return -1; + if (seed_param != NULL) { + size_t seed_len = 0; + rc = EVP_PKEY_get_octet_string_param(pkey, seed_param, NULL, 0, &seed_len); + if (rc == 1) { + pqc->seed.len = seed_len; + if (!(pqc->seed.value = OPENSSL_malloc(pqc->seed.len))) { + OPENSSL_free(pqc->private.value); + return -1; + } + rc = EVP_PKEY_get_octet_string_param(pkey, seed_param, pqc->seed.value, + pqc->seed.len, NULL); + if (rc != 1) { + OPENSSL_free(pqc->private.value); + OPENSSL_free(pqc->seed.value); + return -1; + } + } } - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ML_DSA_SEED, ml_dsa->private.value, priv_len, NULL) != 1) { - OPENSSL_free(ml_dsa->private.value); - OPENSSL_free(ml_dsa->seed.value); + /* But we need at least one */ + if (pqc->seed.value == NULL && pqc->private.value == NULL) { return -1; } } else { size_t pub_len; - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len) != 1) { + rc = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len); + if (rc != 1) { return -1; } - ml_dsa->public.len = pub_len; - if (!(ml_dsa->public.value = OPENSSL_malloc(pub_len))) { + pqc->public.len = pub_len; + if (!(pqc->public.value = OPENSSL_malloc(pub_len))) { return -1; } - if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, ml_dsa->public.value, pub_len, NULL) != 1) { - OPENSSL_free(ml_dsa->public); + rc = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, pqc->public.value, + pqc->public.len, NULL); + if (rc != 1) { + OPENSSL_free(pqc->public.value); return -1; } } return 0; -#else - return -1; -#endif } +#endif #ifdef ENABLE_OPENSSL /* Return PKCS11 key type based on OpenSSL EVP_PKEY type @@ -4706,15 +4939,15 @@ parse_ed_mont_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int pk_type, struct ec_curv } #endif static void -general_key_info_free(struct generalkey_info gost) +general_key_info_free(struct generalkey_info key_info) { #ifdef EC_POINT_NO_ASN1_OCTET_STRING // restore public.value before free it - if (gost.public.value) - gost.public.value -= gost.header_len; + if (key_info.public.value) + key_info.public.value -= key_info.header_len; #endif - OPENSSL_free(gost.param_oid.value); - OPENSSL_free(gost.public.value); - OPENSSL_free(gost.private.value); + OPENSSL_free(key_info.param_oid.value); + OPENSSL_free(key_info.public.value); + OPENSSL_free(key_info.private.value); } static void @@ -4731,6 +4964,16 @@ rsa_info_free(struct rsakey_info rsa) } #endif +#ifdef ENABLE_OPENSSL +static void +pqc_key_info_free(struct pqckey_info pqc) +{ + OPENSSL_free(pqc.public.value); + OPENSSL_free(pqc.private.value); + OPENSSL_free(pqc.seed.value); +} +#endif /* ENABLE_OPENSSL */ + /* Currently for certificates (-type cert), private keys (-type privkey), public keys (-type pubkey) and data objects (-type data). */ static CK_RV write_object(CK_SESSION_HANDLE session) @@ -4764,7 +5007,8 @@ static CK_RV write_object(CK_SESSION_HANDLE session) memset(&cert, 0, sizeof(cert)); memset(&rsa, 0, sizeof(rsa)); - memset(&general_key, 0, sizeof(general_key)); + memset(&general_key, 0, sizeof(general_key)); + memset(&pqc_key, 0, sizeof(pqc_key)); #endif f = fopen(opt_file_to_write, "rb"); @@ -4865,11 +5109,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) rv = parse_ec_pkey(evp_key, is_private, &general_key); } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { rv = parse_ed_mont_pkey(evp_key, type, pk_type, ec_curve_info, is_private, &general_key); - } else if (type == CKK_ML_DSA) { - rv = parse_ml_dsa_pkey(evp_key, is_private, &pqc_key); - } #endif - else +#if OPENSSL_VERSION_NUMBER >= 0x30500000L + } else if (type == CKK_ML_DSA || type == CKK_ML_KEM || type == CKK_SLH_DSA) { + rv = parse_pqc_pkey(evp_key, type, is_private, &pqc_key); +#endif + } else util_fatal("Unsupported key type: 0x%X", pk_type); if (rv) @@ -4954,6 +5199,10 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_UNWRAP, &_true, sizeof(_true)); n_privkey_attr++; } + if (opt_key_usage_encapsulate) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_DECAPSULATE, &_true, sizeof(_true)); + n_privkey_attr++; + } if (opt_always_auth != 0) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_ALWAYS_AUTHENTICATE, &_true, sizeof(_true)); @@ -5014,13 +5263,21 @@ static CK_RV write_object(CK_SESSION_HANDLE session) if (rv) return rv; n_privkey_attr++; - } else if (type == CKK_ML_DSA) { + } else if (type == CKK_ML_DSA || type == CKK_SLH_DSA || type == CKK_ML_KEM) { + /* TODO Set the right parameter set! */ + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, &pqc_key.private.value, pqc_key.private.len); - n_privkey_attr++; - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SEED, &pqc_key.seed.value, pqc_key.seed.len); - n_privkey_attr++; + if (pqc_key.private.value != NULL) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, + &pqc_key.private.value, pqc_key.private.len); + n_privkey_attr++; + } + if (pqc_key.seed.value != NULL) { + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SEED, + &pqc_key.seed.value, pqc_key.seed.len); + n_privkey_attr++; + } } else { util_fatal("Unsupported CK_KEY_TYPE, cannot write private key"); } @@ -5073,6 +5330,10 @@ static CK_RV write_object(CK_SESSION_HANDLE session) FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_WRAP, &_true, sizeof(_true)); n_pubkey_attr++; } + if (opt_key_usage_encapsulate) { + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_ENCAPSULATE, &_true, sizeof(_true)); + n_pubkey_attr++; + } if (cert.subject_len != 0) { FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); @@ -5319,6 +5580,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) #ifdef ENABLE_OPENSSL general_key_info_free(general_key); + pqc_key_info_free(pqc_key); rsa_info_free(rsa); EVP_PKEY_free(evp_key); #endif /* ENABLE_OPENSSL */ @@ -9828,6 +10090,29 @@ static struct mech_info p11_mechanisms[] = { { CKM_POLY1305_KEY_GEN, "POLY1305-KEY-GEN", NULL, MF_UNKNOWN}, { CKM_POLY1305, "POLY1305", NULL, MF_GENERIC_HMAC_FLAGS}, { CKM_CHACHA20_POLY1305, "CHACHA20-POLY1305", NULL, MF_UNKNOWN}, + { CKM_ML_DSA, "ML-DSA", "mldsa", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA224, "HASH-ML-DSA-SHA224", "mldsa-sha224", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA256, "HASH-ML-DSA-SHA256", "mldsa-sha256", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA384, "HASH-ML-DSA-SHA384", "mldsa-sha384", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA512, "HASH-ML-DSA-SHA512", "mldsa-sha512", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA3_224, "HASH-ML-DSA-SHA3_224", "mldsa-sha3-224", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA3_256, "HASH-ML-DSA-SHA3_256", "mldsa-sha3-256", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA3_384, "HASH-ML-DSA-SHA3_384", "mldsa-sha3-384", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHA3_512, "HASH-ML-DSA-SHA3_512", "mldsa-sha3-512", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHAKE128, "HASH-ML-DSA-SHAKE128", "mldsa-shake128", MF_UNKNOWN}, + { CKM_HASH_ML_DSA_SHAKE256, "HASH-ML-DSA-SHAKE256", "mldsa-shake256", MF_UNKNOWN}, + { CKM_ML_KEM, "ML-KEM", "mlkem", MF_UNKNOWN}, + { CKM_SLH_DSA, "SLH-DSA", "slhdsa", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA224, "HASH-SLH-DSA-SHA224", "slhdsa-sha224", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA256, "HASH-SLH-DSA-SHA256", "slhdsa-sha256", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA384, "HASH-SLH-DSA-SHA384", "slhdsa-sha384", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA512, "HASH-SLH-DSA-SHA512", "slhdsa-sha512", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA3_224, "HASH-SLH-DSA-SHA3_224", "slhdsa-sha3-224", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA3_256, "HASH-SLH-DSA-SHA3_256", "slhdsa-sha3-256", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA3_384, "HASH-SLH-DSA-SHA3_384", "slhdsa-sha3-384", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHA3_512, "HASH-SLH-DSA-SHA3_512", "slhdsa-sha3-512", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHAKE128, "HASH-SLH-DSA-SHAKE128", "slhdsa-shake128", MF_UNKNOWN}, + { CKM_HASH_SLH_DSA_SHAKE256, "HASH-SLH-DSA-SHAKE256", "slhdsa-shake256", MF_UNKNOWN}, { 0, NULL, NULL, MF_UNKNOWN }, }; From c29ad3208acaf28b880153f9848025d5f362f3c8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 10 Nov 2025 22:06:17 +0100 Subject: [PATCH 4028/4321] Add support for PQC keys to p11test and fixup support in pkcs11-tool --- src/tests/p11test/p11test_case_common.c | 260 +++++++++++++++++++++- src/tests/p11test/p11test_case_common.h | 3 + src/tests/p11test/p11test_case_mechs.c | 49 ++++ src/tests/p11test/p11test_case_readonly.c | 23 +- src/tests/p11test/p11test_common.h | 6 + src/tools/pkcs11-tool.c | 141 ++++++++++-- tests/common.sh | 50 +++-- 7 files changed, 482 insertions(+), 50 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 60b1020f86..6dd70ea782 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -138,7 +138,8 @@ add_supported_mechs(test_cert_t *o) { size_t i; - if (o->type == EVP_PKEY_RSA) { + switch (o->type) { + case EVP_PKEY_RSA: if (token.num_rsa_mechs > 0 ) { /* Get supported mechanisms by token */ o->num_mechs = 0; @@ -167,7 +168,8 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT; } - } else if (o->type == EVP_PKEY_EC) { + break; + case EVP_PKEY_EC: if (token.num_ec_mechs > 0 ) { o->num_mechs = token.num_ec_mechs; for (i = 0; i < token.num_ec_mechs; i++) { @@ -187,8 +189,9 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } + break; #ifdef EVP_PKEY_ED25519 - } else if (o->type == EVP_PKEY_ED25519) { + case EVP_PKEY_ED25519: if (token.num_ed_mechs > 0 ) { o->num_mechs = token.num_ed_mechs; for (i = 0; i < token.num_ed_mechs; i++) { @@ -208,9 +211,10 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } + break; #endif #ifdef EVP_PKEY_X25519 - } else if (o->type == EVP_PKEY_X25519) { + case EVP_PKEY_X25519: if (token.num_montgomery_mechs > 0 ) { o->num_mechs = token.num_montgomery_mechs; for (i = 0; i < token.num_montgomery_mechs; i++) { @@ -230,9 +234,94 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_DERIVE; } + break; #endif +#ifdef EVP_PKEY_ML_DSA_44 + case EVP_PKEY_ML_DSA_44: + case EVP_PKEY_ML_DSA_65: + case EVP_PKEY_ML_DSA_87: + if (token.num_ml_dsa_mechs > 0 ) { + o->num_mechs = token.num_ml_dsa_mechs; + for (i = 0; i < token.num_ml_dsa_mechs; i++) { + o->mechs[i].mech = token.ml_dsa_mechs[i].mech; + o->mechs[i].params = token.ml_dsa_mechs[i].params; + o->mechs[i].params_len = token.ml_dsa_mechs[i].params_len; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = + token.ml_dsa_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_ML_DSA; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; + } + break; +#endif /* EVP_PKEY_ML_DSA_44 */ +#ifdef EVP_PKEY_ML_KEM_512 + case EVP_PKEY_ML_KEM_512: + case EVP_PKEY_ML_KEM_768: + case EVP_PKEY_ML_KEM_1024: + if (token.num_ml_kem_mechs > 0 ) { + o->num_mechs = token.num_ml_kem_mechs; + for (i = 0; i < token.num_ml_kem_mechs; i++) { + o->mechs[i].mech = token.ml_kem_mechs[i].mech; + o->mechs[i].params = token.ml_kem_mechs[i].params; + o->mechs[i].params_len = token.ml_kem_mechs[i].params_len; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = + token.ml_kem_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_ML_KEM; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_ENCAPSULATE | CKF_DECAPSULATE; + } + break; +#endif /* EVP_PKEY_ML_KEM_512 */ +#ifdef EVP_PKEY_SLH_DSA_SHA2_128S + case EVP_PKEY_SLH_DSA_SHA2_128S: + case EVP_PKEY_SLH_DSA_SHAKE_128S: + case EVP_PKEY_SLH_DSA_SHA2_128F: + case EVP_PKEY_SLH_DSA_SHAKE_128F: + case EVP_PKEY_SLH_DSA_SHA2_192S: + case EVP_PKEY_SLH_DSA_SHAKE_192S: + case EVP_PKEY_SLH_DSA_SHA2_192F: + case EVP_PKEY_SLH_DSA_SHAKE_192F: + case EVP_PKEY_SLH_DSA_SHA2_256S: + case EVP_PKEY_SLH_DSA_SHAKE_256S: + case EVP_PKEY_SLH_DSA_SHA2_256F: + case EVP_PKEY_SLH_DSA_SHAKE_256F: + if (token.num_slh_dsa_mechs > 0 ) { + o->num_mechs = token.num_slh_dsa_mechs; + for (i = 0; i < token.num_slh_dsa_mechs; i++) { + o->mechs[i].mech = token.slh_dsa_mechs[i].mech; + o->mechs[i].params = token.slh_dsa_mechs[i].params; + o->mechs[i].params_len = token.slh_dsa_mechs[i].params_len; + o->mechs[i].result_flags = 0; + o->mechs[i].usage_flags = + token.slh_dsa_mechs[i].usage_flags; + } + } else { + /* Use the default list */ + o->num_mechs = 1; + o->mechs[0].mech = CKM_SLH_DSA; + o->mechs[0].params = NULL; + o->mechs[0].params_len = 0; + o->mechs[0].result_flags = 0; + o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; + } + break; +#endif /* EVP_PKEY_SLH_DSA_SHA2_128S */ /* Nothing in the above enum can be used for secret keys */ - } else if (o->key_type == CKK_AES) { + case CKK_AES: if (token.num_aes_mechs > 0 ) { o->num_mechs = token.num_aes_mechs; for (i = 0; i < token.num_aes_mechs; i++) { @@ -251,6 +340,7 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].result_flags = 0; o->mechs[0].usage_flags = CKF_ENCRYPT|CKF_DECRYPT|CKF_WRAP|CKF_UNWRAP; } + break; } } @@ -356,6 +446,10 @@ int callback_private_keys(test_certs_t *objects, ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; o->extractable = (template[8].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; + o->decapsulate = (template[9].ulValueLen == sizeof(CK_BBOOL)) + ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; + o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) + ? *((CK_ULONG *) template[10].pValue) : CK_UNAVAILABLE_INFORMATION; debug_print(" [ OK %s ] Private key loaded successfully S:%d D:%d T:%02lX", o->id_str, o->sign, o->decrypt, o->key_type); @@ -403,6 +497,8 @@ int callback_public_keys(test_certs_t *objects, ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; o->derive_pub = (template[9].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; + o->encapsulate = (template[10].ulValueLen == sizeof(CK_BBOOL)) + ? *((CK_BBOOL *) template[10].pValue) : CK_FALSE; /* check if we get the same public key as from the certificate */ if (o->key_type == CKK_RSA) { @@ -757,6 +853,90 @@ int callback_public_keys(test_certs_t *objects, o->bits = 255; } ASN1_STRING_free(os); +#ifdef EVP_PKEY_ML_DSA_44 + } else if (o->key_type == CKK_ML_DSA) { + o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) + ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; + switch (o->parameter_set) { + case CKP_ML_DSA_44: + o->type = EVP_PKEY_ML_DSA_44; + break; + case CKP_ML_DSA_65: + o->type = EVP_PKEY_ML_DSA_65; + break; + case CKP_ML_DSA_87: + o->type = EVP_PKEY_ML_DSA_87; + break; + default: + return -1; + } + // TODO more processing +#endif /* EVP_PKEY_ML_DSA_44 */ +#ifdef EVP_PKEY_ML_KEM_512 + } else if (o->key_type == CKK_ML_KEM) { + o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) + ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; + switch (o->parameter_set) { + case CKP_ML_KEM_512: + o->key_type = EVP_PKEY_ML_KEM_512; + break; + case CKP_ML_KEM_768: + o->key_type = EVP_PKEY_ML_KEM_768; + break; + case CKP_ML_KEM_1024: + o->key_type = EVP_PKEY_ML_KEM_1024; + break; + default: + return -1; + } + // TODO more processing +#endif /* EVP_PKEY_ML_KEM_512 */ +#ifdef EVP_PKEY_SLH_DSA_SHA2_128S + } else if (o->key_type == CKK_SLH_DSA) { + o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) + ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; + switch (o->parameter_set) { + case CKP_SLH_DSA_SHA2_128S: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_128S; + break; + case CKP_SLH_DSA_SHAKE_128S: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_128S; + break; + case CKP_SLH_DSA_SHA2_128F: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_128F; + break; + case CKP_SLH_DSA_SHAKE_128F: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_128F; + break; + case CKP_SLH_DSA_SHA2_192S: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_192S; + break; + case CKP_SLH_DSA_SHAKE_192S: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_192S; + break; + case CKP_SLH_DSA_SHA2_192F: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_192F; + break; + case CKP_SLH_DSA_SHAKE_192F: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_192F; + break; + case CKP_SLH_DSA_SHA2_256S: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_256S; + break; + case CKP_SLH_DSA_SHAKE_256S: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_256S; + break; + case CKP_SLH_DSA_SHA2_256F: + o->key_type = EVP_PKEY_SLH_DSA_SHA2_256F; + break; + case CKP_SLH_DSA_SHAKE_256F: + o->key_type = EVP_PKEY_SLH_DSA_SHAKE_256F; + break; + default: + return -1; + } + // TODO more processing +#endif /* EVP_PKEY_SLH_DSA_SHA2_128S */ } else { debug_print(" [WARN %s ] unknown key. Key type: %02lX", o->id_str, o->key_type); @@ -960,6 +1140,8 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) { CKA_DERIVE, NULL, 0}, // CK_BBOOL { CKA_LABEL, NULL_PTR, 0}, { CKA_EXTRACTABLE, NULL, 0}, // CK_BBOOL + { CKA_DECAPSULATE, NULL, 0}, // CK_BBOOL + { CKA_PARAMETER_SET, NULL, 0}, // CK_ULONG }; CK_ULONG private_attrs_size = sizeof (private_attrs) / sizeof (CK_ATTRIBUTE); CK_ATTRIBUTE public_attrs[] = { @@ -973,6 +1155,8 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) { CKA_EC_POINT, NULL, 0}, { CKA_WRAP, NULL, 0}, // CK_BBOOL { CKA_DERIVE, NULL, 0}, // CK_BBOOL + { CKA_ENCAPSULATE, NULL, 0}, // CK_BBOOL + { CKA_PARAMETER_SET, NULL, 0}, // CK_ULONG }; CK_ULONG public_attrs_size = sizeof (public_attrs) / sizeof (CK_ATTRIBUTE); CK_ATTRIBUTE secret_attrs[] = { @@ -1218,6 +1402,62 @@ const char *get_mechanism_name(unsigned long mech_id) return "AES_KEY_WRAP"; case CKM_AES_KEY_WRAP_PAD: return "AES_KEY_WRAP_PAD"; + case CKM_ML_DSA_KEY_PAIR_GEN: + return "ML_DSA_KEY_PAIR_GEN"; + case CKM_ML_DSA: + return "ML_DSA"; + case CKM_HASH_ML_DSA: + return "HASH_ML_DSA"; + case CKM_HASH_ML_DSA_SHA224: + return "HASH_ML_DSA_SHA224"; + case CKM_HASH_ML_DSA_SHA256: + return "HASH_ML_DSA_SHA256"; + case CKM_HASH_ML_DSA_SHA384: + return "HASH_ML_DSA_SHA384"; + case CKM_HASH_ML_DSA_SHA512: + return "HASH_ML_DSA_SHA3_512"; + case CKM_HASH_ML_DSA_SHA3_224: + return "HASH_ML_DSA_SHA3_224"; + case CKM_HASH_ML_DSA_SHA3_256: + return "HASH_ML_DSA_SHA3_256"; + case CKM_HASH_ML_DSA_SHA3_384: + return "HASH_ML_DSA_SHA3_384"; + case CKM_HASH_ML_DSA_SHA3_512: + return "HASH_ML_DSA_SHA3_512"; + case CKM_HASH_ML_DSA_SHAKE128: + return "HASH_ML_DSA_SHAKE128"; + case CKM_HASH_ML_DSA_SHAKE256: + return "HASH_ML_DSA_SHAKE256"; + case CKM_ML_KEM_KEY_PAIR_GEN: + return "ML_KEM_KEY_PAIR_GEN"; + case CKM_ML_KEM: + return "ML_KEM"; + case CKM_SLH_DSA_KEY_PAIR_GEN: + return "SLH_DSA_KEY_PAIR_GEN"; + case CKM_SLH_DSA: + return "SLH_DSA"; + case CKM_HASH_SLH_DSA: + return "HASH_SLH_DSA"; + case CKM_HASH_SLH_DSA_SHA224: + return "HASH_SLH_DSA_SHA224"; + case CKM_HASH_SLH_DSA_SHA256: + return "HASH_SLH_DSA_SHA256"; + case CKM_HASH_SLH_DSA_SHA384: + return "HASH_SLH_DSA_SHA384"; + case CKM_HASH_SLH_DSA_SHA512: + return "HASH_SLH_DSA_SHA3_512"; + case CKM_HASH_SLH_DSA_SHA3_224: + return "HASH_SLH_DSA_SHA3_224"; + case CKM_HASH_SLH_DSA_SHA3_256: + return "HASH_SLH_DSA_SHA3_256"; + case CKM_HASH_SLH_DSA_SHA3_384: + return "HASH_SLH_DSA_SHA3_384"; + case CKM_HASH_SLH_DSA_SHA3_512: + return "HASH_SLH_DSA_SHA3_512"; + case CKM_HASH_SLH_DSA_SHAKE128: + return "HASH_SLH_DSA_SHAKE128"; + case CKM_HASH_SLH_DSA_SHAKE256: + return "HASH_SLH_DSA_SHAKE256"; default: sprintf(name_buffer, "0x%.8lX", mech_id); return name_buffer; @@ -1265,6 +1505,12 @@ get_key_type(test_cert_t * key) return "EC_MONTGOMERY"; case CKK_AES: return "AES"; + case CKK_ML_DSA: + return "ML-DSA"; + case CKK_ML_KEM: + return "ML-KEM"; + case CKK_SLH_DSA: + return "SLH-DSA"; default: sprintf(name_buffer, "0x%.8lX", key->key_type); return name_buffer; @@ -1322,6 +1568,10 @@ const char *get_mechanism_flag_name(unsigned long mech_id) return "CKF_EC_COMPRESS"; case CKF_EC_ECPARAMETERS: return "CKF_EC_ECPARAMETERS"; + case CKF_ENCAPSULATE: + return "CKF_ENCAPSULATE"; + case CKF_DECAPSULATE: + return "CKF_DECAPSULATE"; default: sprintf(flag_buffer, "0x%.8lX", mech_id); return flag_buffer; diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 4c1fd4b72a..28a8d61215 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -54,9 +54,12 @@ typedef struct { CK_KEY_TYPE key_type; CK_BBOOL always_auth; CK_BBOOL extractable; + CK_BBOOL decapsulate; + CK_BBOOL encapsulate; char *label; CK_ULONG bits; char *value; + CK_ULONG parameter_set; int verify_public; test_mech_t mechs[MAX_PSS_MECHS]; size_t num_mechs; diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index 3e763789fc..51bd1523f1 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -155,6 +155,55 @@ supported_mechanisms_test(void **state) P11TEST_FAIL(info, "Too many montgomery EC mechanisms (%d)", MAX_MECHS); } + /* We list all known ML-DSA mechanisms */ + if (mechanism_list[i] == CKM_ML_DSA || + mechanism_list[i] == CKM_HASH_ML_DSA || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA224 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA256 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA384 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA512 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA3_224 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA3_256 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA3_384 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHA3_512 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHAKE128 || + mechanism_list[i] == CKM_HASH_ML_DSA_SHAKE256) { + if (token.num_ml_dsa_mechs < MAX_MECHS) { + insert_mechanism(token.ml_dsa_mechs, &token.num_ml_dsa_mechs, + mechanism_list[i], mechanism_info[i]); + } else + P11TEST_FAIL(info, "Too many ML-DSA mechanisms (%d)", MAX_MECHS); + } + + /* We list all known ML-KEM mechanisms */ + if (mechanism_list[i] == CKM_ML_KEM) { + if (token.num_ml_kem_mechs < MAX_MECHS) { + insert_mechanism(token.ml_kem_mechs, &token.num_ml_kem_mechs, + mechanism_list[i], mechanism_info[i]); + } else + P11TEST_FAIL(info, "Too many ML-KEM mechanisms (%d)", MAX_MECHS); + } + + /* We list all known SLH-DSA mechanisms */ + if (mechanism_list[i] == CKM_SLH_DSA || + mechanism_list[i] == CKM_HASH_SLH_DSA || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA224 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA256 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA384 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA512 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA3_224 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA3_256 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA3_384 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHA3_512 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHAKE128 || + mechanism_list[i] == CKM_HASH_SLH_DSA_SHAKE256) { + if (token.num_slh_dsa_mechs < MAX_MECHS) { + insert_mechanism(token.slh_dsa_mechs, &token.num_slh_dsa_mechs, + mechanism_list[i], mechanism_info[i]); + } else + P11TEST_FAIL(info, "Too many SLH-DSA mechanisms (%d)", MAX_MECHS); + } + /* We list all known secret key mechanisms */ if (mechanism_list[i] == CKM_AES_ECB || mechanism_list[i] == CKM_AES_ECB_ENCRYPT_DATA || diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index b453d87c41..465337d405 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -808,24 +808,31 @@ void readonly_tests(void **state) { if (o->key_type != CKK_RSA && o->key_type != CKK_EC && o->key_type != CKK_EC_EDWARDS && - o->key_type != CKK_EC_MONTGOMERY) + o->key_type != CKK_EC_MONTGOMERY && + o->key_type != CKK_ML_DSA && + o->key_type != CKK_SLH_DSA) continue; printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s]\n", - (o->key_type == CKK_RSA ? "RSA " : - o->key_type == CKK_EC ? " EC " : - o->key_type == CKK_EC_EDWARDS ? "EC_E" : - o->key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), + printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s] [%s%s]\n", + (o->key_type == CKK_RSA ? " RSA " : + o->key_type == CKK_EC ? " EC " : + o->key_type == CKK_EC_EDWARDS ? "EDDSA" : + o->key_type == CKK_EC_MONTGOMERY ? "XEDDS" : + o->key_type == CKK_ML_DSA ? "ML-DSA" : + o->key_type == CKK_SLH_DSA ? "SLHDSA" : " ?? "), o->bits, o->verify_public == 1 ? " ./ " : " ", o->sign ? "[./] " : "[ ] ", o->verify ? " [./] " : " [ ] ", o->encrypt ? "[./] " : "[ ] ", - o->decrypt ? " [./] " : " [ ] "); - if (!o->sign && !o->verify && !o->encrypt && !o->decrypt) { + o->decrypt ? " [./] " : " [ ] ", + o->encapsulate ? " [./] " : " [ ] ", + o->decapsulate ? " [./] " : " [ ] "); + if (!o->sign && !o->verify && !o->encrypt && !o->decrypt && + !o->encapsulate && !o->decapsulate) { printf(" no usable attributes found ... ignored\n"); continue; } diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h index d2d6288daf..4a2594fc6a 100644 --- a/src/tests/p11test/p11test_common.h +++ b/src/tests/p11test/p11test_common.h @@ -96,6 +96,12 @@ typedef struct { size_t num_ed_mechs; test_mech_t montgomery_mechs[MAX_MECHS]; size_t num_montgomery_mechs; + test_mech_t ml_dsa_mechs[MAX_MECHS]; + size_t num_ml_dsa_mechs; + test_mech_t ml_kem_mechs[MAX_MECHS]; + size_t num_ml_kem_mechs; + test_mech_t slh_dsa_mechs[MAX_MECHS]; + size_t num_slh_dsa_mechs; test_mech_t aes_mechs[MAX_MECHS]; size_t num_aes_mechs; test_mech_t keygen_mechs[MAX_MECHS]; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 24b9b582b5..261048adcd 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -766,6 +766,7 @@ ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */ ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */ ATTR_METHOD(VALUE_LEN, CK_ULONG); /* getVALUE_LEN */ ATTR_METHOD(PROFILE_ID, CK_ULONG); /* getPROFILE_ID */ +ATTR_METHOD(PARAMETER_SET, CK_ULONG); /* getPARAMETER_SET */ VARATTR_METHOD(LABEL, char); /* getLABEL */ VARATTR_METHOD(UNIQUE_ID, char); /* getUNIQUE_ID */ VARATTR_METHOD(APPLICATION, char); /* getAPPLICATION */ @@ -3728,7 +3729,7 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (strcmp(type, "ML-KEM-512") == 0) { ml_kem_parameter_set = CKP_ML_KEM_512; } else if (strcmp(type, "ML-KEM-768")) { - ml_kem_parameter_set = CKP_ML_KEM_512; + ml_kem_parameter_set = CKP_ML_KEM_768; } else if (strcmp(type, "ML-KEM-1024")) { ml_kem_parameter_set = CKP_ML_KEM_1024; } else { @@ -6372,6 +6373,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) int pub = 1; int sec = 0; CK_TOKEN_INFO info; + CK_ULONG parameter_set; switch(getCLASS(sess, obj)) { case CKO_PRIVATE_KEY: @@ -6559,6 +6561,103 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) free(value); } break; + case CKK_ML_DSA: + case CKK_ML_KEM: + case CKK_SLH_DSA: + parameter_set = getPARAMETER_SET(sess, obj); + switch (key_type) { + case CKK_ML_DSA: + switch (parameter_set) { + case CKP_ML_DSA_44: + printf("; ML-DSA-44\n"); + break; + case CKP_ML_DSA_65: + printf("; ML-DSA-65\n"); + break; + case CKP_ML_DSA_87: + printf("; ML-DSA-87\n"); + break; + default: + printf("; ML-DSA: Unknown PARAMETER_SET\n"); + break; + } + break; + case CKK_ML_KEM: + switch (parameter_set) { + case CKP_ML_KEM_512: + printf("; ML-KEM-512\n"); + break; + case CKP_ML_KEM_768: + printf("; ML-KEM-768\n"); + break; + case CKP_ML_KEM_1024: + printf("; ML-KEM-1024\n"); + break; + default: + printf("; ML-KEM: Unknown PARAMETER_SET\n"); + break; + } + break; + case CKK_SLH_DSA: + switch (parameter_set) { + case CKP_SLH_DSA_SHA2_128S: + printf("; SLH-DSA-SHA2-128S\n"); + break; + case CKP_SLH_DSA_SHAKE_128S: + printf("; SLH-DSA-SHAKE-128S\n"); + break; + case CKP_SLH_DSA_SHA2_128F: + printf("; SLH-DSA-SHA2-128F\n"); + break; + case CKP_SLH_DSA_SHAKE_128F: + printf("; SLH-DSA-SHAKE-128F\n"); + break; + case CKP_SLH_DSA_SHA2_192S: + printf("; SLH-DSA-SHA2-192S\n"); + break; + case CKP_SLH_DSA_SHAKE_192S: + printf("; SLH-DSA-SHAKE-192S\n"); + break; + case CKP_SLH_DSA_SHA2_192F: + printf("; SLH-DSA-SHA2-192F\n"); + break; + case CKP_SLH_DSA_SHAKE_192F: + printf("; SLH-DSA-SHAKE-192F\n"); + break; + case CKP_SLH_DSA_SHA2_256S: + printf("; SLH-DSA-SHA2-256S\n"); + break; + case CKP_SLH_DSA_SHAKE_256S: + printf("; SLH-DSA-SHAKE-256S\n"); + break; + case CKP_SLH_DSA_SHA2_256F: + printf("; SLH-DSA-SHA2-256F\n"); + break; + case CKP_SLH_DSA_SHAKE_256F: + printf("; SLH-DSA-SHAKE-256F\n"); + break; + default: + printf("; SLH-DSA: Unknown PARAMETER_SET\n"); + break; + } + break; + } + if (pub) { + value = getVALUE(sess, obj, &size); + if (value) { + unsigned int n; + + printf(" VALUE: "); + for (n = 0; n < size; n++) { + if (n && (n%32)==0) + printf("\n "); + printf("%02x", value[n]); + } + printf("\n"); + free(value); + } + } + break; default: printf("; unknown key algorithm %lu\n", (unsigned long) key_type); @@ -7202,26 +7301,26 @@ static int read_object(CK_SESSION_HANDLE session) free(value); util_fatal("cannot set OSSL_PARAM"); } - OSSL_PARAM_BLD_free(bld); - if (success) - ASN1_STRING_free(os); - free(value); + OSSL_PARAM_BLD_free(bld); + if (success) + ASN1_STRING_free(os); + free(value); - if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || - EVP_PKEY_fromdata_init(ctx) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot set CTX"); - } - EVP_PKEY_free(pkey); - pkey = NULL; - if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { - OSSL_PARAM_free(p); - EVP_PKEY_CTX_free(ctx); - util_fatal("cannot create EVP_PKEY"); - } - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || + EVP_PKEY_fromdata_init(ctx) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot set CTX"); + } + EVP_PKEY_free(pkey); + pkey = NULL; + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, p) != 1) { + OSSL_PARAM_free(p); + EVP_PKEY_CTX_free(ctx); + util_fatal("cannot create EVP_PKEY"); + } + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); #endif if (!i2d_PUBKEY_bio(pout, pkey)) @@ -7334,6 +7433,8 @@ static int read_object(CK_SESSION_HANDLE session) } EVP_PKEY_free(key); + } else if (type == CKK_ML_DSA || type == CKK_ML_KEM || type == CKK_SLH_DSA) { + // TODO #endif } else util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); diff --git a/tests/common.sh b/tests/common.sh index 56dabdcd9d..647d22e845 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -9,8 +9,8 @@ if [ -n "$VALGRIND" -a -n "$LOG_COMPILER" ]; then VALGRIND="$LOG_COMPILER" fi -export SOPIN="12345678" -export PIN="123456" +export SOPIN="12345678abcdefgh" +export PIN="123456abcdef" PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" if [ "${TOKENTYPE}" == "softhsm" ]; then @@ -46,21 +46,21 @@ function generate_key() { fi # Extract public key from the card - $PKCS11_TOOL "${PUB_ARGS[@]}" --read-object --id $ID --type pubkey --output-file $ID.der - if [[ "$?" -ne "0" ]]; then - echo "Couldn't read generated $TYPE public key" - return 1 - fi + #$PKCS11_TOOL "${PUB_ARGS[@]}" --read-object --id $ID --type pubkey --output-file $ID.der + #if [[ "$?" -ne "0" ]]; then + # echo "Couldn't read generated $TYPE public key" + # return 1 + #fi - # convert it to more digestible PEM format - if [[ ${TYPE:0:3} == "RSA" ]]; then - openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - elif [[ $TYPE == "EC:edwards25519" ]]; then - openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - else - openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - fi - rm $ID.der + ## convert it to more digestible PEM format + #if [[ ${TYPE:0:3} == "RSA" ]]; then + # openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + #elif [[ $TYPE == "EC:edwards25519" ]]; then + # openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + #else + # openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + #fi + #rm $ID.der } function card_setup() { @@ -81,10 +81,26 @@ function card_setup() { echo "Couldn't generate GENERIC key" return 1 fi + if [ "${TOKENTYPE}" == "kryoptic" ]; then + # Generate Ed25519 Key pair + generate_key "EC:ed25519" "06" "ed25519" || return 1 + # Generate x25519 Key pair + generate_key "EC:x25519" "07" "x25519" || return 1 + # Generate x448 Key pair + generate_key "EC:x448" "08" "x448" || return 1 + + # Generate ML-DSA-65 Key pair + generate_key "ML-DSA-65" "09" "ML-DSA-65" || return 1 + # Generate ML-KEM-768 Key pair + generate_key "ML-KEM-768" "10" "ML-KEM-768" || return 1 + # Generate SLH-DSA-SHA2-192S Key pair + generate_key "SLH-DSA-SHA2-192S" "11" "SLH-DSA-SHA2-192S" || return 1 + fi + } function card_cleanup() { token_cleanup - rm 0{1,2,3,4}.pub + #rm 0{1,2,3,4}.pub sleep 1 } From 7169c2288abe364504b0e5e72f08c4b869f9d7a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 10 Nov 2025 22:06:46 +0100 Subject: [PATCH 4029/4321] Add kryoptic reference output from p11test --- tests/kryoptic_ref.json | 4484 ++++++++++++--------------------------- 1 file changed, 1391 insertions(+), 3093 deletions(-) diff --git a/tests/kryoptic_ref.json b/tests/kryoptic_ref.json index 10a76d7d45..b8acf82715 100644 --- a/tests/kryoptic_ref.json +++ b/tests/kryoptic_ref.json @@ -16,91 +16,247 @@ ], [ "RSA_PKCS_KEY_PAIR_GEN", - "1024", + "2048", "16384", "CKF_GENERATE_KEY_PAIR" ], [ "RSA_PKCS", - "1024", + "2048", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" ], [ "RSA_X_509", - "1024", + "2048", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" ], [ "SHA1_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "RSA_PKCS_OAEP", - "1024", + "2048", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" ], [ "RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA1_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], + [ + "0x0000000F", + "800", + "1568", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x00000017", + "800", + "1568", + "" + ], + [ + "0x0000001C", + "1312", + "2592", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x0000001D", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000001F", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000020", + "2048", + "8192", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x00000021", + "2048", + "8192", + "CKF_DERIVE" + ], + [ + "0x00000023", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000024", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000025", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000026", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000027", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000028", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000029", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000002A", + "1312", + "2592", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000002D", + "32", + "64", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x0000002E", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000034", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000036", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000037", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000038", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000039", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000003A", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000003B", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000003C", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x0000003D", + "32", + "64", + "CKF_SIGN,CKF_VERIFY" + ], [ "SHA256_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA256_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], @@ -152,51 +308,63 @@ "0", "CKF_DERIVE" ], + [ + "0x00000056", + "48", + "48", + "CKF_DERIVE" + ], + [ + "0x00000057", + "48", + "48", + "CKF_DERIVE" + ], [ "SHA3_256_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_384_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_512_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_256_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_384_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_512_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_224_RSA_PKCS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_224_RSA_PKCS_PSS", - "1024", + "2048", "16384", "CKF_SIGN,CKF_VERIFY" ], @@ -392,6 +560,36 @@ "0", "CKF_GENERATE" ], + [ + "0x00000360", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x00000362", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x00000363", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x00000364", + "0", + "-1", + "CKF_DERIVE" + ], + [ + "0x00000365", + "0", + "-1", + "CKF_DERIVE" + ], [ "0x00000392", "0", @@ -620,18 +818,6 @@ "32", "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" ], - [ - "AES_MAC", - "16", - "32", - "CKF_SIGN,CKF_VERIFY" - ], - [ - "AES_MAC_GENERAL", - "16", - "32", - "CKF_SIGN,CKF_VERIFY" - ], [ "AES_CBC_PAD", "16", @@ -686,30 +872,6 @@ "32", "CKF_DERIVE" ], - [ - "AES_OFB", - "16", - "32", - "CKF_ENCRYPT,CKF_DECRYPT" - ], - [ - "AES_CFB8", - "16", - "32", - "CKF_ENCRYPT,CKF_DECRYPT" - ], - [ - "AES_CFB128", - "16", - "32", - "CKF_ENCRYPT,CKF_DECRYPT" - ], - [ - "0x00002108", - "16", - "32", - "CKF_ENCRYPT,CKF_DECRYPT" - ], [ "AES_KEY_WRAP", "16", @@ -782,6 +944,12 @@ "0", "CKF_GENERATE" ], + [ + "0x0000403A", + "0", + "0", + "CKF_DERIVE" + ], [ "0x8007678C", "0", @@ -807,18 +975,12 @@ "01", "RSA_PKCS", "YES", - "YES" + "" ], [ "01", "RSA_X_509", "YES", - "YES" - ], - [ - "01", - "SHA1_RSA_PKCS", - "YES", "" ], [ @@ -873,18 +1035,12 @@ "02", "RSA_PKCS", "YES", - "YES" + "" ], [ "02", "RSA_X_509", "YES", - "YES" - ], - [ - "02", - "SHA1_RSA_PKCS", - "YES", "" ], [ @@ -941,12 +1097,6 @@ "YES", "" ], - [ - "03", - "ECDSA_SHA1", - "YES", - "" - ], [ "03", "ECDSA_SHA256", @@ -995,12 +1145,6 @@ "YES", "" ], - [ - "04", - "ECDSA_SHA1", - "YES", - "" - ], [ "04", "ECDSA_SHA256", @@ -1053,11 +1197,6 @@ "MECHANISM", "MULTIPART SIGN&VERIFY WORKS" ], - [ - "01", - "SHA1_RSA_PKCS", - "YES" - ], [ "01", "SHA256_RSA_PKCS", @@ -1098,11 +1237,6 @@ "SHA3_224_RSA_PKCS", "YES" ], - [ - "02", - "SHA1_RSA_PKCS", - "YES" - ], [ "02", "SHA256_RSA_PKCS", @@ -1994,8 +2128,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "SHA224", + "MGF1_SHA224", "-2", "YES", "" @@ -2003,8 +2137,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "SHA224", + "MGF1_SHA224", "-1", "YES", "" @@ -2012,8 +2146,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", + "SHA224", + "MGF1_SHA224", "0", "YES", "" @@ -2021,8 +2155,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", + "SHA224", + "MGF1_SHA256", "-2", "YES", "" @@ -2030,8 +2164,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", + "SHA224", + "MGF1_SHA256", "-1", "YES", "" @@ -2039,8 +2173,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", + "SHA224", + "MGF1_SHA256", "0", "YES", "" @@ -2048,8 +2182,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", + "SHA224", + "MGF1_SHA384", "-2", "YES", "" @@ -2057,8 +2191,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", + "SHA224", + "MGF1_SHA384", "-1", "YES", "" @@ -2066,8 +2200,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", + "SHA224", + "MGF1_SHA384", "0", "YES", "" @@ -2075,34 +2209,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "0", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA512", "-2", "YES", @@ -2111,7 +2218,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA512", "-1", "YES", @@ -2120,7 +2227,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA512", "0", "YES", @@ -2129,7 +2236,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_224", "-2", "YES", @@ -2138,7 +2245,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_224", "-1", "YES", @@ -2147,7 +2254,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_224", "0", "YES", @@ -2156,7 +2263,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_256", "-2", "YES", @@ -2165,7 +2272,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_256", "-1", "YES", @@ -2174,7 +2281,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_256", "0", "YES", @@ -2183,7 +2290,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_384", "-2", "YES", @@ -2192,7 +2299,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_384", "-1", "YES", @@ -2201,44 +2308,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA_1", + "SHA224", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -2247,7 +2327,7 @@ "01", "RSA_PKCS_PSS", "SHA224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -2256,7 +2336,7 @@ "01", "RSA_PKCS_PSS", "SHA224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -2264,7 +2344,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA224", "-2", "YES", @@ -2273,7 +2353,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA224", "-1", "YES", @@ -2282,7 +2362,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA224", "0", "YES", @@ -2291,7 +2371,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA256", "-2", "YES", @@ -2300,7 +2380,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA256", "-1", "YES", @@ -2309,7 +2389,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA256", "0", "YES", @@ -2318,7 +2398,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA384", "-2", "YES", @@ -2327,7 +2407,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA384", "-1", "YES", @@ -2336,7 +2416,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA384", "0", "YES", @@ -2345,7 +2425,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA512", "-2", "YES", @@ -2354,7 +2434,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA512", "-1", "YES", @@ -2363,7 +2443,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA512", "0", "YES", @@ -2372,7 +2452,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_224", "-2", "YES", @@ -2381,7 +2461,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_224", "-1", "YES", @@ -2390,7 +2470,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_224", "0", "YES", @@ -2399,7 +2479,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_256", "-2", "YES", @@ -2408,7 +2488,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_256", "-1", "YES", @@ -2417,7 +2497,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_256", "0", "YES", @@ -2426,7 +2506,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_384", "-2", "YES", @@ -2435,7 +2515,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_384", "-1", "YES", @@ -2444,44 +2524,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA224", + "SHA256", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -2490,7 +2543,7 @@ "01", "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -2499,7 +2552,7 @@ "01", "RSA_PKCS_PSS", "SHA256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -2507,7 +2560,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA224", "-2", "YES", @@ -2516,7 +2569,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA224", "-1", "YES", @@ -2525,7 +2578,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA224", "0", "YES", @@ -2534,7 +2587,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA256", "-2", "YES", @@ -2543,7 +2596,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA256", "-1", "YES", @@ -2552,7 +2605,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA256", "0", "YES", @@ -2561,7 +2614,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA384", "-2", "YES", @@ -2570,7 +2623,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA384", "-1", "YES", @@ -2579,7 +2632,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA384", "0", "YES", @@ -2588,7 +2641,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA512", "-2", "YES", @@ -2597,7 +2650,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA512", "-1", "YES", @@ -2606,7 +2659,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA512", "0", "YES", @@ -2615,7 +2668,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_224", "-2", "YES", @@ -2624,7 +2677,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_224", "-1", "YES", @@ -2633,7 +2686,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_224", "0", "YES", @@ -2642,7 +2695,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_256", "-2", "YES", @@ -2651,7 +2704,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_256", "-1", "YES", @@ -2660,7 +2713,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_256", "0", "YES", @@ -2669,7 +2722,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_384", "-2", "YES", @@ -2678,7 +2731,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_384", "-1", "YES", @@ -2687,44 +2740,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA256", + "SHA384", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -2733,7 +2759,7 @@ "01", "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -2742,7 +2768,7 @@ "01", "RSA_PKCS_PSS", "SHA384", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -2750,7 +2776,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA224", "-2", "YES", @@ -2759,7 +2785,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA224", "-1", "YES", @@ -2768,7 +2794,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA224", "0", "YES", @@ -2777,7 +2803,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA256", "-2", "YES", @@ -2786,7 +2812,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA256", "-1", "YES", @@ -2795,7 +2821,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA256", "0", "YES", @@ -2804,7 +2830,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA384", "-2", "YES", @@ -2813,7 +2839,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA384", "-1", "YES", @@ -2822,7 +2848,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA384", "0", "YES", @@ -2831,7 +2857,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA512", "-2", "YES", @@ -2840,7 +2866,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA512", "-1", "YES", @@ -2849,7 +2875,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA512", "0", "YES", @@ -2858,7 +2884,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_224", "-2", "YES", @@ -2867,7 +2893,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_224", "-1", "YES", @@ -2876,7 +2902,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_224", "0", "YES", @@ -2885,7 +2911,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_256", "-2", "YES", @@ -2894,7 +2920,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_256", "-1", "YES", @@ -2903,7 +2929,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_256", "0", "YES", @@ -2912,7 +2938,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_384", "-2", "YES", @@ -2921,7 +2947,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_384", "-1", "YES", @@ -2930,44 +2956,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA384", + "SHA512", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -2976,7 +2975,7 @@ "01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -2985,7 +2984,7 @@ "01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -2993,7 +2992,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA224", "-2", "YES", @@ -3002,7 +3001,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA224", "-1", "YES", @@ -3011,7 +3010,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA224", "0", "YES", @@ -3020,7 +3019,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA256", "-2", "YES", @@ -3029,7 +3028,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA256", "-1", "YES", @@ -3038,7 +3037,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA256", "0", "YES", @@ -3047,7 +3046,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA384", "-2", "YES", @@ -3056,7 +3055,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA384", "-1", "YES", @@ -3065,7 +3064,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA384", "0", "YES", @@ -3074,7 +3073,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA512", "-2", "YES", @@ -3083,7 +3082,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA512", "-1", "YES", @@ -3092,7 +3091,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA512", "0", "YES", @@ -3101,7 +3100,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_224", "-2", "YES", @@ -3110,7 +3109,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_224", "-1", "YES", @@ -3119,7 +3118,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_224", "0", "YES", @@ -3128,7 +3127,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_256", "-2", "YES", @@ -3137,7 +3136,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_256", "-1", "YES", @@ -3146,7 +3145,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_256", "0", "YES", @@ -3155,7 +3154,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_384", "-2", "YES", @@ -3164,7 +3163,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_384", "-1", "YES", @@ -3173,44 +3172,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", + "SHA3_224", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA3_224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -3219,7 +3191,7 @@ "01", "RSA_PKCS_PSS", "SHA3_224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -3228,7 +3200,7 @@ "01", "RSA_PKCS_PSS", "SHA3_224", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -3236,7 +3208,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA224", "-2", "YES", @@ -3245,7 +3217,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA224", "-1", "YES", @@ -3254,7 +3226,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA224", "0", "YES", @@ -3263,7 +3235,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA256", "-2", "YES", @@ -3272,7 +3244,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA256", "-1", "YES", @@ -3281,7 +3253,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA256", "0", "YES", @@ -3290,7 +3262,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA384", "-2", "YES", @@ -3299,7 +3271,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA384", "-1", "YES", @@ -3308,7 +3280,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA384", "0", "YES", @@ -3317,7 +3289,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA512", "-2", "YES", @@ -3326,7 +3298,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA512", "-1", "YES", @@ -3335,7 +3307,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA512", "0", "YES", @@ -3344,7 +3316,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_224", "-2", "YES", @@ -3353,7 +3325,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_224", "-1", "YES", @@ -3362,7 +3334,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_224", "0", "YES", @@ -3371,7 +3343,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_256", "-2", "YES", @@ -3380,7 +3352,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_256", "-1", "YES", @@ -3389,7 +3361,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_256", "0", "YES", @@ -3398,7 +3370,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_384", "-2", "YES", @@ -3407,7 +3379,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_384", "-1", "YES", @@ -3416,44 +3388,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_224", + "SHA3_256", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA3_256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -3462,7 +3407,7 @@ "01", "RSA_PKCS_PSS", "SHA3_256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -3471,7 +3416,7 @@ "01", "RSA_PKCS_PSS", "SHA3_256", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" @@ -3479,7 +3424,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA224", "-2", "YES", @@ -3488,7 +3433,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA224", "-1", "YES", @@ -3497,7 +3442,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA224", "0", "YES", @@ -3506,7 +3451,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA256", "-2", "YES", @@ -3515,7 +3460,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA256", "-1", "YES", @@ -3524,7 +3469,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA256", "0", "YES", @@ -3533,7 +3478,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA384", "-2", "YES", @@ -3542,7 +3487,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA384", "-1", "YES", @@ -3551,7 +3496,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA384", "0", "YES", @@ -3560,7 +3505,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA512", "-2", "YES", @@ -3569,7 +3514,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA512", "-1", "YES", @@ -3578,7 +3523,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA512", "0", "YES", @@ -3587,7 +3532,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_224", "-2", "YES", @@ -3596,7 +3541,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_224", "-1", "YES", @@ -3605,7 +3550,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_224", "0", "YES", @@ -3614,7 +3559,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_256", "-2", "YES", @@ -3623,7 +3568,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_256", "-1", "YES", @@ -3632,7 +3577,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_256", "0", "YES", @@ -3641,7 +3586,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_384", "-2", "YES", @@ -3650,7 +3595,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_384", "-1", "YES", @@ -3659,7 +3604,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_384", "0", "YES", @@ -3668,7 +3613,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_512", "-2", "YES", @@ -3677,7 +3622,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_512", "-1", "YES", @@ -3686,7 +3631,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_384", "MGF1_SHA3_512", "0", "YES", @@ -3695,8 +3640,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", + "SHA3_512", + "MGF1_SHA224", "-2", "YES", "" @@ -3704,34 +3649,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA224", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA224", "-1", "YES", @@ -3740,7 +3658,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA224", "0", "YES", @@ -3749,7 +3667,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA256", "-2", "YES", @@ -3758,7 +3676,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA256", "-1", "YES", @@ -3767,7 +3685,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA256", "0", "YES", @@ -3776,7 +3694,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA384", "-2", "YES", @@ -3785,7 +3703,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA384", "-1", "YES", @@ -3794,7 +3712,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA384", "0", "YES", @@ -3803,7 +3721,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA512", "-2", "YES", @@ -3812,7 +3730,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA512", "-1", "YES", @@ -3821,7 +3739,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA512", "0", "YES", @@ -3830,7 +3748,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_224", "-2", "YES", @@ -3839,7 +3757,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_224", "-1", "YES", @@ -3848,7 +3766,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_224", "0", "YES", @@ -3857,7 +3775,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_256", "-2", "YES", @@ -3866,7 +3784,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_256", "-1", "YES", @@ -3875,7 +3793,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_256", "0", "YES", @@ -3884,7 +3802,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_384", "-2", "YES", @@ -3893,7 +3811,7 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_384", "-1", "YES", @@ -3902,44 +3820,17 @@ [ "01", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_512", "MGF1_SHA3_384", "0", "YES", "" ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], [ "01", "RSA_PKCS_PSS", "SHA3_512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-2", "YES", "" @@ -3948,7 +3839,7 @@ "01", "RSA_PKCS_PSS", "SHA3_512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "-1", "YES", "" @@ -3957,15 +3848,15 @@ "01", "RSA_PKCS_PSS", "SHA3_512", - "MGF1_SHA_1", + "MGF1_SHA3_512", "0", "YES", "" ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA224", "-2", "YES", @@ -3973,8 +3864,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA224", "-1", "YES", @@ -3982,8 +3873,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA224", "0", "YES", @@ -3991,8 +3882,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA256", "-2", "YES", @@ -4000,8 +3891,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA256", "-1", "YES", @@ -4009,8 +3900,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA256", "0", "YES", @@ -4018,8 +3909,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA384", "-2", "YES", @@ -4027,8 +3918,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA384", "-1", "YES", @@ -4036,8 +3927,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA384", "0", "YES", @@ -4045,8 +3936,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA512", "-2", "YES", @@ -4054,8 +3945,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA512", "-1", "YES", @@ -4063,8 +3954,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA512", "0", "YES", @@ -4072,8 +3963,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_224", "-2", "YES", @@ -4081,8 +3972,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_224", "-1", "YES", @@ -4090,8 +3981,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_224", "0", "YES", @@ -4099,8 +3990,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_256", "-2", "YES", @@ -4108,8 +3999,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_256", "-1", "YES", @@ -4117,8 +4008,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_256", "0", "YES", @@ -4126,8 +4017,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_384", "-2", "YES", @@ -4135,8 +4026,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_384", "-1", "YES", @@ -4144,8 +4035,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_384", "0", "YES", @@ -4153,8 +4044,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_512", "-2", "YES", @@ -4162,8 +4053,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_512", "-1", "YES", @@ -4171,8 +4062,8 @@ ], [ "01", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA256_RSA_PKCS_PSS", + "SHA256", "MGF1_SHA3_512", "0", "YES", @@ -4180,35 +4071,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA224", "-2", "YES", @@ -4216,8 +4080,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA224", "-1", "YES", @@ -4225,8 +4089,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA224", "0", "YES", @@ -4234,8 +4098,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA256", "-2", "YES", @@ -4243,8 +4107,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA256", "-1", "YES", @@ -4252,8 +4116,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA256", "0", "YES", @@ -4261,8 +4125,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA384", "-2", "YES", @@ -4270,8 +4134,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA384", "-1", "YES", @@ -4279,8 +4143,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA384", "0", "YES", @@ -4288,8 +4152,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA512", "-2", "YES", @@ -4297,8 +4161,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA512", "-1", "YES", @@ -4306,8 +4170,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA512", "0", "YES", @@ -4315,8 +4179,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_224", "-2", "YES", @@ -4324,8 +4188,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_224", "-1", "YES", @@ -4333,8 +4197,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_224", "0", "YES", @@ -4342,8 +4206,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_256", "-2", "YES", @@ -4351,8 +4215,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_256", "-1", "YES", @@ -4360,8 +4224,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_256", "0", "YES", @@ -4369,8 +4233,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_384", "-2", "YES", @@ -4378,8 +4242,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_384", "-1", "YES", @@ -4387,8 +4251,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_384", "0", "YES", @@ -4396,8 +4260,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_512", "-2", "YES", @@ -4405,8 +4269,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_512", "-1", "YES", @@ -4414,8 +4278,8 @@ ], [ "01", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "SHA384_RSA_PKCS_PSS", + "SHA384", "MGF1_SHA3_512", "0", "YES", @@ -4423,35 +4287,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA224", "-2", "YES", @@ -4459,8 +4296,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA224", "-1", "YES", @@ -4468,8 +4305,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA224", "0", "YES", @@ -4477,8 +4314,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA256", "-2", "YES", @@ -4486,8 +4323,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA256", "-1", "YES", @@ -4495,8 +4332,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA256", "0", "YES", @@ -4504,8 +4341,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA384", "-2", "YES", @@ -4513,8 +4350,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA384", "-1", "YES", @@ -4522,8 +4359,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA384", "0", "YES", @@ -4531,8 +4368,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA512", "-2", "YES", @@ -4540,8 +4377,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA512", "-1", "YES", @@ -4549,8 +4386,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA512", "0", "YES", @@ -4558,8 +4395,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_224", "-2", "YES", @@ -4567,8 +4404,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_224", "-1", "YES", @@ -4576,8 +4413,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_224", "0", "YES", @@ -4585,8 +4422,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_256", "-2", "YES", @@ -4594,8 +4431,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_256", "-1", "YES", @@ -4603,8 +4440,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_256", "0", "YES", @@ -4612,8 +4449,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_384", "-2", "YES", @@ -4621,8 +4458,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_384", "-1", "YES", @@ -4630,8 +4467,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_384", "0", "YES", @@ -4639,8 +4476,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_512", "-2", "YES", @@ -4648,8 +4485,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_512", "-1", "YES", @@ -4657,8 +4494,8 @@ ], [ "01", - "SHA256_RSA_PKCS_PSS", - "SHA256", + "SHA512_RSA_PKCS_PSS", + "SHA512", "MGF1_SHA3_512", "0", "YES", @@ -4666,35 +4503,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA224", "-2", "YES", @@ -4702,8 +4512,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA224", "-1", "YES", @@ -4711,8 +4521,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA224", "0", "YES", @@ -4720,8 +4530,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA256", "-2", "YES", @@ -4729,8 +4539,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA256", "-1", "YES", @@ -4738,8 +4548,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA256", "0", "YES", @@ -4747,8 +4557,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA384", "-2", "YES", @@ -4756,8 +4566,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA384", "-1", "YES", @@ -4765,8 +4575,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA384", "0", "YES", @@ -4774,8 +4584,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA512", "-2", "YES", @@ -4783,8 +4593,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA512", "-1", "YES", @@ -4792,8 +4602,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA512", "0", "YES", @@ -4801,8 +4611,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_224", "-2", "YES", @@ -4810,8 +4620,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_224", "-1", "YES", @@ -4819,8 +4629,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_224", "0", "YES", @@ -4828,8 +4638,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_256", "-2", "YES", @@ -4837,8 +4647,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_256", "-1", "YES", @@ -4846,8 +4656,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_256", "0", "YES", @@ -4855,8 +4665,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_384", "-2", "YES", @@ -4864,8 +4674,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_384", "-1", "YES", @@ -4873,8 +4683,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_384", "0", "YES", @@ -4882,8 +4692,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_512", "-2", "YES", @@ -4891,8 +4701,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_512", "-1", "YES", @@ -4900,8 +4710,8 @@ ], [ "01", - "SHA384_RSA_PKCS_PSS", - "SHA384", + "SHA224_RSA_PKCS_PSS", + "SHA224", "MGF1_SHA3_512", "0", "YES", @@ -4909,35 +4719,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA224", "-2", "YES", @@ -4945,8 +4728,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA224", "-1", "YES", @@ -4954,8 +4737,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA224", "0", "YES", @@ -4963,8 +4746,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA256", "-2", "YES", @@ -4972,8 +4755,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA256", "-1", "YES", @@ -4981,8 +4764,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA256", "0", "YES", @@ -4990,8 +4773,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA384", "-2", "YES", @@ -4999,8 +4782,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA384", "-1", "YES", @@ -5008,8 +4791,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA384", "0", "YES", @@ -5017,8 +4800,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA512", "-2", "YES", @@ -5026,8 +4809,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA512", "-1", "YES", @@ -5035,8 +4818,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA512", "0", "YES", @@ -5044,8 +4827,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_224", "-2", "YES", @@ -5053,8 +4836,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_224", "-1", "YES", @@ -5062,8 +4845,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_224", "0", "YES", @@ -5071,8 +4854,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_256", "-2", "YES", @@ -5080,8 +4863,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_256", "-1", "YES", @@ -5089,8 +4872,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_256", "0", "YES", @@ -5098,8 +4881,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_384", "-2", "YES", @@ -5107,8 +4890,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_384", "-1", "YES", @@ -5116,8 +4899,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_384", "0", "YES", @@ -5125,8 +4908,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_512", "-2", "YES", @@ -5134,8 +4917,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_512", "-1", "YES", @@ -5143,8 +4926,8 @@ ], [ "01", - "SHA512_RSA_PKCS_PSS", - "SHA512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", "MGF1_SHA3_512", "0", "YES", @@ -5152,35 +4935,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA224", "-2", "YES", @@ -5188,8 +4944,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA224", "-1", "YES", @@ -5197,8 +4953,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA224", "0", "YES", @@ -5206,8 +4962,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA256", "-2", "YES", @@ -5215,8 +4971,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA256", "-1", "YES", @@ -5224,8 +4980,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA256", "0", "YES", @@ -5233,8 +4989,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA384", "-2", "YES", @@ -5242,8 +4998,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA384", "-1", "YES", @@ -5251,8 +5007,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA384", "0", "YES", @@ -5260,8 +5016,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA512", "-2", "YES", @@ -5269,8 +5025,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA512", "-1", "YES", @@ -5278,8 +5034,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA512", "0", "YES", @@ -5287,8 +5043,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_224", "-2", "YES", @@ -5296,8 +5052,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_224", "-1", "YES", @@ -5305,8 +5061,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_224", "0", "YES", @@ -5314,8 +5070,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_256", "-2", "YES", @@ -5323,8 +5079,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_256", "-1", "YES", @@ -5332,8 +5088,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_256", "0", "YES", @@ -5341,8 +5097,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_384", "-2", "YES", @@ -5350,8 +5106,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_384", "-1", "YES", @@ -5359,8 +5115,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_384", "0", "YES", @@ -5368,8 +5124,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_512", "-2", "YES", @@ -5377,8 +5133,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_512", "-1", "YES", @@ -5386,8 +5142,8 @@ ], [ "01", - "SHA224_RSA_PKCS_PSS", - "SHA224", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", "MGF1_SHA3_512", "0", "YES", @@ -5395,35 +5151,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "-2", "YES", @@ -5431,8 +5160,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "-1", "YES", @@ -5440,8 +5169,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "0", "YES", @@ -5449,8 +5178,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "-2", "YES", @@ -5458,8 +5187,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "-1", "YES", @@ -5467,8 +5196,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "0", "YES", @@ -5476,8 +5205,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "-2", "YES", @@ -5485,8 +5214,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "-1", "YES", @@ -5494,8 +5223,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "0", "YES", @@ -5503,8 +5232,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "-2", "YES", @@ -5512,8 +5241,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "-1", "YES", @@ -5521,8 +5250,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "0", "YES", @@ -5530,8 +5259,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "-2", "YES", @@ -5539,8 +5268,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "-1", "YES", @@ -5548,8 +5277,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "0", "YES", @@ -5557,8 +5286,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "-2", "YES", @@ -5566,8 +5295,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "-1", "YES", @@ -5575,8 +5304,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "0", "YES", @@ -5584,8 +5313,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "-2", "YES", @@ -5593,8 +5322,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "-1", "YES", @@ -5602,8 +5331,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "0", "YES", @@ -5611,8 +5340,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "-2", "YES", @@ -5620,8 +5349,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "-1", "YES", @@ -5629,8 +5358,8 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "0", "YES", @@ -5638,35 +5367,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA224", "-2", "YES", @@ -5674,8 +5376,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA224", "-1", "YES", @@ -5683,8 +5385,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA224", "0", "YES", @@ -5692,8 +5394,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA256", "-2", "YES", @@ -5701,8 +5403,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA256", "-1", "YES", @@ -5710,8 +5412,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA256", "0", "YES", @@ -5719,8 +5421,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA384", "-2", "YES", @@ -5728,8 +5430,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA384", "-1", "YES", @@ -5737,8 +5439,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA384", "0", "YES", @@ -5746,8 +5448,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA512", "-2", "YES", @@ -5755,8 +5457,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA512", "-1", "YES", @@ -5764,8 +5466,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA512", "0", "YES", @@ -5773,8 +5475,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_224", "-2", "YES", @@ -5782,8 +5484,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_224", "-1", "YES", @@ -5791,8 +5493,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_224", "0", "YES", @@ -5800,8 +5502,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_256", "-2", "YES", @@ -5809,8 +5511,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_256", "-1", "YES", @@ -5818,8 +5520,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_256", "0", "YES", @@ -5827,8 +5529,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_384", "-2", "YES", @@ -5836,8 +5538,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_384", "-1", "YES", @@ -5845,8 +5547,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_384", "0", "YES", @@ -5854,8 +5556,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_512", "-2", "YES", @@ -5863,8 +5565,8 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_512", "-1", "YES", @@ -5872,971 +5574,161 @@ ], [ "01", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", "MGF1_SHA3_512", "0", "YES", "" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", + "02", + "RSA_PKCS_OAEP", + "SHA_1", "MGF1_SHA_1", "0", - "YES", - "" + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", + "02", + "RSA_PKCS_OAEP", + "SHA_1", "MGF1_SHA224", - "-2", - "YES", - "" + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA224", - "-1", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA256", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA224", + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA384", "0", - "YES", - "" + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA256", - "-2", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA512", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA256", - "-1", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_224", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA256", + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_256", "0", - "YES", - "" + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA384", - "-2", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_384", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA384", - "-1", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA3_512", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA384", + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA_1", "0", - "YES", - "" + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA512", - "-2", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA224", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA512", - "-1", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA256", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA512", + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA384", "0", - "YES", - "" + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_224", - "-2", - "YES", - "" + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA512", + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", + "02", + "RSA_PKCS_OAEP", + "SHA224", "MGF1_SHA3_224", - "-1", - "YES", - "" + "0", + "", + "YES" ], [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_224", + "02", + "RSA_PKCS_OAEP", + "SHA224", + "MGF1_SHA3_256", "0", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_256", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_256", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_256", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_384", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_384", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_384", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA224", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA224", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA224", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA256", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA256", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA256", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA384", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA384", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA384", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA512", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA512", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA512", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_224", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_224", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_224", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_256", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_256", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_256", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_384", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_384", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_384", - "0", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "01", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA3_512", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA_1", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA224", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA3_224", - "0", - "", - "YES" + "", + "YES" ], [ "02", "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA256", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA384", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA512", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA_1", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_224", + "SHA224", "MGF1_SHA3_384", "0", "", @@ -6845,7 +5737,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_224", + "SHA224", "MGF1_SHA3_512", "0", "", @@ -6854,7 +5746,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA_1", "0", "", @@ -6863,7 +5755,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA224", "0", "", @@ -6872,7 +5764,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA256", "0", "", @@ -6881,7 +5773,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA384", "0", "", @@ -6890,7 +5782,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA512", "0", "", @@ -6899,7 +5791,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA3_224", "0", "", @@ -6908,7 +5800,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA3_256", "0", "", @@ -6917,7 +5809,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA3_384", "0", "", @@ -6926,7 +5818,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_256", + "SHA256", "MGF1_SHA3_512", "0", "", @@ -6935,7 +5827,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA_1", "0", "", @@ -6944,7 +5836,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA224", "0", "", @@ -6953,7 +5845,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA256", "0", "", @@ -6962,7 +5854,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA384", "0", "", @@ -6971,7 +5863,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA512", "0", "", @@ -6980,7 +5872,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA3_224", "0", "", @@ -6989,7 +5881,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA3_256", "0", "", @@ -6998,7 +5890,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA3_384", "0", "", @@ -7007,7 +5899,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_384", + "SHA384", "MGF1_SHA3_512", "0", "", @@ -7016,7 +5908,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_512", + "SHA512", "MGF1_SHA_1", "0", "", @@ -7025,7 +5917,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_512", + "SHA512", "MGF1_SHA224", "0", "", @@ -7034,7 +5926,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_512", + "SHA512", "MGF1_SHA256", "0", "", @@ -7043,7 +5935,7 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_512", + "SHA512", "MGF1_SHA384", "0", "", @@ -7052,565 +5944,376 @@ [ "02", "RSA_PKCS_OAEP", - "SHA3_512", - "MGF1_SHA512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_512", - "MGF1_SHA3_224", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_512", - "MGF1_SHA3_256", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_512", - "MGF1_SHA3_384", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_OAEP", - "SHA3_512", - "MGF1_SHA3_512", - "0", - "", - "YES" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA224", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA256", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA384", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA512", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA512", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", + "SHA512", "MGF1_SHA512", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_224", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_224", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_224", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_256", - "-2", - "YES", - "" + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_256", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_OAEP", + "SHA512", "MGF1_SHA3_256", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_OAEP", + "SHA512", "MGF1_SHA3_384", - "-2", - "YES", - "" + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_384", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA512", + "MGF1_SHA3_512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_384", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA_1", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA256", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA3_512", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA384", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_256", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA224", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA224", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_224", + "MGF1_SHA3_512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_256", "MGF1_SHA224", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", + "RSA_PKCS_OAEP", + "SHA3_256", "MGF1_SHA256", - "-2", - "YES", - "" + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA256", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA256", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA512", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_256", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA384", + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_384", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA512", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA512", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA512", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA256", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_224", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_224", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", + "RSA_PKCS_OAEP", + "SHA3_384", "MGF1_SHA3_224", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", + "RSA_PKCS_OAEP", + "SHA3_384", "MGF1_SHA3_256", - "-2", - "YES", - "" + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_256", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_256", + "RSA_PKCS_OAEP", + "SHA3_384", + "MGF1_SHA3_512", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_384", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA_1", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_384", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA224", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_384", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA256", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA512", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA3_512", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_224", "0", - "YES", - "" + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-2", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_256", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-1", - "YES", - "" + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_384", + "0", + "", + "YES" ], [ "02", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", + "RSA_PKCS_OAEP", + "SHA3_512", + "MGF1_SHA3_512", "0", - "YES", - "" + "", + "YES" ], [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA224", "-2", "YES", @@ -7619,7 +6322,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA224", "-1", "YES", @@ -7628,7 +6331,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA224", "0", "YES", @@ -7637,7 +6340,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA256", "-2", "YES", @@ -7646,7 +6349,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA256", "-1", "YES", @@ -7655,7 +6358,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA256", "0", "YES", @@ -7664,7 +6367,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA384", "-2", "YES", @@ -7673,7 +6376,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA384", "-1", "YES", @@ -7682,7 +6385,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA384", "0", "YES", @@ -7691,7 +6394,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA512", "-2", "YES", @@ -7700,7 +6403,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA512", "-1", "YES", @@ -7709,7 +6412,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA512", "0", "YES", @@ -7718,7 +6421,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_224", "-2", "YES", @@ -7727,7 +6430,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_224", "-1", "YES", @@ -7736,7 +6439,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_224", "0", "YES", @@ -7745,7 +6448,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_256", "-2", "YES", @@ -7754,7 +6457,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_256", "-1", "YES", @@ -7763,7 +6466,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_256", "0", "YES", @@ -7772,7 +6475,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_384", "-2", "YES", @@ -7781,7 +6484,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_384", "-1", "YES", @@ -7790,7 +6493,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_384", "0", "YES", @@ -7799,35 +6502,8 @@ [ "02", "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA3_512", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA3_512", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA256", + "SHA224", "MGF1_SHA3_512", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", "-2", "YES", "" @@ -7835,8 +6511,8 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", + "SHA224", + "MGF1_SHA3_512", "-1", "YES", "" @@ -7844,8 +6520,8 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", + "SHA224", + "MGF1_SHA3_512", "0", "YES", "" @@ -7853,7 +6529,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA224", "-2", "YES", @@ -7862,7 +6538,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA224", "-1", "YES", @@ -7871,7 +6547,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA224", "0", "YES", @@ -7880,7 +6556,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA256", "-2", "YES", @@ -7889,7 +6565,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA256", "-1", "YES", @@ -7898,7 +6574,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA256", "0", "YES", @@ -7907,7 +6583,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA384", "-2", "YES", @@ -7916,7 +6592,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA384", "-1", "YES", @@ -7925,7 +6601,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA384", "0", "YES", @@ -7934,7 +6610,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA512", "-2", "YES", @@ -7943,7 +6619,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA512", "-1", "YES", @@ -7952,7 +6628,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA512", "0", "YES", @@ -7961,7 +6637,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_224", "-2", "YES", @@ -7970,7 +6646,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_224", "-1", "YES", @@ -7979,7 +6655,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_224", "0", "YES", @@ -7988,7 +6664,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_256", "-2", "YES", @@ -7997,7 +6673,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_256", "-1", "YES", @@ -8006,7 +6682,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_256", "0", "YES", @@ -8015,7 +6691,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_384", "-2", "YES", @@ -8024,7 +6700,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_384", "-1", "YES", @@ -8033,7 +6709,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_384", "0", "YES", @@ -8042,7 +6718,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_512", "-2", "YES", @@ -8051,7 +6727,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_512", "-1", "YES", @@ -8060,7 +6736,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA384", + "SHA256", "MGF1_SHA3_512", "0", "YES", @@ -8069,34 +6745,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA224", "-2", "YES", @@ -8105,7 +6754,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA224", "-1", "YES", @@ -8114,7 +6763,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA224", "0", "YES", @@ -8123,7 +6772,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA256", "-2", "YES", @@ -8132,7 +6781,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA256", "-1", "YES", @@ -8141,7 +6790,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA256", "0", "YES", @@ -8150,7 +6799,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA384", "-2", "YES", @@ -8159,7 +6808,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA384", "-1", "YES", @@ -8168,7 +6817,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA384", "0", "YES", @@ -8177,7 +6826,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA512", "-2", "YES", @@ -8186,7 +6835,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA512", "-1", "YES", @@ -8195,7 +6844,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA512", "0", "YES", @@ -8204,7 +6853,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_224", "-2", "YES", @@ -8213,7 +6862,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_224", "-1", "YES", @@ -8222,7 +6871,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_224", "0", "YES", @@ -8231,7 +6880,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_256", "-2", "YES", @@ -8240,7 +6889,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_256", "-1", "YES", @@ -8249,7 +6898,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_256", "0", "YES", @@ -8258,7 +6907,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_384", "-2", "YES", @@ -8267,7 +6916,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_384", "-1", "YES", @@ -8276,7 +6925,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_384", "0", "YES", @@ -8285,7 +6934,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_512", "-2", "YES", @@ -8294,7 +6943,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_512", "-1", "YES", @@ -8303,7 +6952,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA512", + "SHA384", "MGF1_SHA3_512", "0", "YES", @@ -8312,34 +6961,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA224", "-2", "YES", @@ -8348,7 +6970,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA224", "-1", "YES", @@ -8357,7 +6979,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA224", "0", "YES", @@ -8366,7 +6988,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA256", "-2", "YES", @@ -8375,7 +6997,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA256", "-1", "YES", @@ -8384,7 +7006,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA256", "0", "YES", @@ -8393,7 +7015,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA384", "-2", "YES", @@ -8402,7 +7024,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA384", "-1", "YES", @@ -8411,7 +7033,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA384", "0", "YES", @@ -8420,7 +7042,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA512", "-2", "YES", @@ -8429,7 +7051,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA512", "-1", "YES", @@ -8438,7 +7060,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA512", "0", "YES", @@ -8447,7 +7069,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_224", "-2", "YES", @@ -8456,7 +7078,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_224", "-1", "YES", @@ -8465,7 +7087,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_224", "0", "YES", @@ -8474,7 +7096,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_256", "-2", "YES", @@ -8483,7 +7105,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_256", "-1", "YES", @@ -8492,7 +7114,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_256", "0", "YES", @@ -8501,7 +7123,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_384", "-2", "YES", @@ -8510,7 +7132,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_384", "-1", "YES", @@ -8519,7 +7141,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_384", "0", "YES", @@ -8528,7 +7150,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_512", "-2", "YES", @@ -8537,7 +7159,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_512", "-1", "YES", @@ -8546,7 +7168,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_224", + "SHA512", "MGF1_SHA3_512", "0", "YES", @@ -8555,34 +7177,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA224", "-2", "YES", @@ -8591,7 +7186,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA224", "-1", "YES", @@ -8600,7 +7195,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA224", "0", "YES", @@ -8609,7 +7204,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA256", "-2", "YES", @@ -8618,7 +7213,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA256", "-1", "YES", @@ -8627,7 +7222,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA256", "0", "YES", @@ -8636,7 +7231,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA384", "-2", "YES", @@ -8645,7 +7240,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA384", "-1", "YES", @@ -8654,7 +7249,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA384", "0", "YES", @@ -8663,7 +7258,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA512", "-2", "YES", @@ -8672,7 +7267,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA512", "-1", "YES", @@ -8681,7 +7276,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA512", "0", "YES", @@ -8690,7 +7285,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_224", "-2", "YES", @@ -8699,7 +7294,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_224", "-1", "YES", @@ -8708,7 +7303,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_224", "0", "YES", @@ -8717,7 +7312,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_256", "-2", "YES", @@ -8726,7 +7321,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_256", "-1", "YES", @@ -8735,7 +7330,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_256", "0", "YES", @@ -8744,7 +7339,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_384", "-2", "YES", @@ -8753,7 +7348,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_384", "-1", "YES", @@ -8762,7 +7357,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_384", "0", "YES", @@ -8771,7 +7366,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_512", "-2", "YES", @@ -8780,7 +7375,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_512", "-1", "YES", @@ -8789,7 +7384,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", + "SHA3_224", "MGF1_SHA3_512", "0", "YES", @@ -8798,34 +7393,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA224", "-2", "YES", @@ -8834,7 +7402,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA224", "-1", "YES", @@ -8843,7 +7411,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA224", "0", "YES", @@ -8852,7 +7420,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA256", "-2", "YES", @@ -8861,7 +7429,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA256", "-1", "YES", @@ -8870,7 +7438,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA256", "0", "YES", @@ -8879,7 +7447,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA384", "-2", "YES", @@ -8888,7 +7456,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA384", "-1", "YES", @@ -8897,7 +7465,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA384", "0", "YES", @@ -8906,7 +7474,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA512", "-2", "YES", @@ -8915,7 +7483,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA512", "-1", "YES", @@ -8924,7 +7492,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA512", "0", "YES", @@ -8933,7 +7501,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_224", "-2", "YES", @@ -8942,7 +7510,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_224", "-1", "YES", @@ -8951,7 +7519,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_224", "0", "YES", @@ -8960,7 +7528,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_256", "-2", "YES", @@ -8969,7 +7537,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_256", "-1", "YES", @@ -8978,7 +7546,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_256", "0", "YES", @@ -8987,7 +7555,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_384", "-2", "YES", @@ -8996,7 +7564,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_384", "-1", "YES", @@ -9005,7 +7573,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_384", "0", "YES", @@ -9014,7 +7582,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_512", "-2", "YES", @@ -9023,7 +7591,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_512", "-1", "YES", @@ -9032,7 +7600,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_384", + "SHA3_256", "MGF1_SHA3_512", "0", "YES", @@ -9041,34 +7609,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA224", "-2", "YES", @@ -9077,7 +7618,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA224", "-1", "YES", @@ -9086,7 +7627,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA224", "0", "YES", @@ -9095,7 +7636,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA256", "-2", "YES", @@ -9104,7 +7645,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA256", "-1", "YES", @@ -9113,7 +7654,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA256", "0", "YES", @@ -9122,7 +7663,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA384", "-2", "YES", @@ -9131,7 +7672,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA384", "-1", "YES", @@ -9140,7 +7681,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA384", "0", "YES", @@ -9149,7 +7690,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA512", "-2", "YES", @@ -9158,7 +7699,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA512", "-1", "YES", @@ -9167,7 +7708,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA512", "0", "YES", @@ -9176,7 +7717,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_224", "-2", "YES", @@ -9185,7 +7726,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_224", "-1", "YES", @@ -9194,7 +7735,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_224", "0", "YES", @@ -9203,7 +7744,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_256", "-2", "YES", @@ -9212,7 +7753,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_256", "-1", "YES", @@ -9221,7 +7762,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_256", "0", "YES", @@ -9230,7 +7771,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_384", "-2", "YES", @@ -9239,7 +7780,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_384", "-1", "YES", @@ -9248,7 +7789,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_384", "0", "YES", @@ -9257,7 +7798,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_512", "-2", "YES", @@ -9266,7 +7807,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_512", "-1", "YES", @@ -9275,7 +7816,7 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_512", + "SHA3_384", "MGF1_SHA3_512", "0", "YES", @@ -9283,35 +7824,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", - "MGF1_SHA_1", - "0", - "YES", - "" - ], - [ - "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "-2", "YES", @@ -9319,8 +7833,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "-1", "YES", @@ -9328,8 +7842,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA224", "0", "YES", @@ -9337,8 +7851,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "-2", "YES", @@ -9346,8 +7860,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "-1", "YES", @@ -9355,8 +7869,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA256", "0", "YES", @@ -9364,8 +7878,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "-2", "YES", @@ -9373,8 +7887,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "-1", "YES", @@ -9382,8 +7896,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA384", "0", "YES", @@ -9391,8 +7905,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "-2", "YES", @@ -9400,8 +7914,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "-1", "YES", @@ -9409,8 +7923,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA512", "0", "YES", @@ -9418,8 +7932,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "-2", "YES", @@ -9427,8 +7941,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "-1", "YES", @@ -9436,8 +7950,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_224", "0", "YES", @@ -9445,8 +7959,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "-2", "YES", @@ -9454,8 +7968,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "-1", "YES", @@ -9463,8 +7977,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_256", "0", "YES", @@ -9472,8 +7986,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "-2", "YES", @@ -9481,8 +7995,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "-1", "YES", @@ -9490,8 +8004,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_384", "0", "YES", @@ -9499,8 +8013,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "-2", "YES", @@ -9508,8 +8022,8 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "-1", "YES", @@ -9517,40 +8031,13 @@ ], [ "02", - "SHA1_RSA_PKCS_PSS", - "SHA_1", + "RSA_PKCS_PSS", + "SHA3_512", "MGF1_SHA3_512", "0", "YES", "" ], - [ - "02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA256_RSA_PKCS_PSS", - "SHA256", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA256_RSA_PKCS_PSS", @@ -9767,33 +8254,6 @@ "YES", "" ], - [ - "02", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA384_RSA_PKCS_PSS", - "SHA384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA384_RSA_PKCS_PSS", @@ -10010,33 +8470,6 @@ "YES", "" ], - [ - "02", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA512_RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA512_RSA_PKCS_PSS", @@ -10253,33 +8686,6 @@ "YES", "" ], - [ - "02", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA224_RSA_PKCS_PSS", - "SHA224", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA224_RSA_PKCS_PSS", @@ -10496,33 +8902,6 @@ "YES", "" ], - [ - "02", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA3_256_RSA_PKCS_PSS", @@ -10739,33 +9118,6 @@ "YES", "" ], - [ - "02", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA3_384_RSA_PKCS_PSS", - "SHA3_384", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA3_384_RSA_PKCS_PSS", @@ -10982,33 +9334,6 @@ "YES", "" ], - [ - "02", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA3_512_RSA_PKCS_PSS", - "SHA3_512", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA3_512_RSA_PKCS_PSS", @@ -11225,33 +9550,6 @@ "YES", "" ], - [ - "02", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-2", - "YES", - "" - ], - [ - "02", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "-1", - "YES", - "" - ], - [ - "02", - "SHA3_224_RSA_PKCS_PSS", - "SHA3_224", - "MGF1_SHA_1", - "0", - "YES", - "" - ], [ "02", "SHA3_224_RSA_PKCS_PSS", From 837d5e254e44b3e46aba1b98913671006e3eb049 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Nov 2025 22:38:10 +0100 Subject: [PATCH 4030/4321] PKCS#11 3.2 mechanisms mostly in the p11test --- src/pkcs11/debug.c | 11 +++ src/pkcs11/pkcs11-display.c | 1 - src/tests/p11test/p11test_case_common.c | 95 ++++++++++++++++------ src/tests/p11test/p11test_case_ec_derive.c | 23 ++++-- src/tests/p11test/p11test_case_readonly.c | 64 +++++++++++---- src/tests/p11test/p11test_case_usage.c | 60 +++++++++----- src/tools/pkcs11-tool.c | 30 +++---- tests/common.sh | 42 +++++----- 8 files changed, 223 insertions(+), 103 deletions(-) diff --git a/src/pkcs11/debug.c b/src/pkcs11/debug.c index 582285a2e2..facd5bdb2b 100644 --- a/src/pkcs11/debug.c +++ b/src/pkcs11/debug.c @@ -62,6 +62,9 @@ static struct fmap map_CKA_CLASS[] = { _(CKO_SECRET_KEY), _(CKO_HW_FEATURE), _(CKO_DOMAIN_PARAMETERS), + _(CKO_PROFILE), + _(CKO_VALIDATION), + _(CKO_TRUST), { 0, NULL, NULL, NULL } }; @@ -81,6 +84,7 @@ static struct fmap map_CKA_KEY_TYPE[] = { _(CKK_EC), _(CKK_EC_EDWARDS), _(CKK_EC_MONTGOMERY), + _(CKK_GENERIC_SECRET), _(CKK_RC2), _(CKK_RC4), _(CKK_RC5), @@ -91,6 +95,9 @@ static struct fmap map_CKA_KEY_TYPE[] = { _(CKK_CAST128), _(CKK_IDEA), _(CKK_AES), + _(CKK_ML_DSA), + _(CKK_ML_KEM), + _(CKK_SLH_DSA), { 0, NULL, NULL, NULL } }; @@ -158,6 +165,10 @@ static struct fmap p11_attr_names[] = { _(CKA_VENDOR_DEFINED), b(CKA_ALWAYS_AUTHENTICATE), _(CKA_GOSTR3410_PARAMS), + ul(CKA_PARAMETER_SET), + b(CKA_ENCAPSULATE), + b(CKA_DECAPSULATE), + _(CKA_SEED), { 0, NULL, NULL, NULL } }; diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index e7b8f824b3..994d64f78b 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -310,7 +310,6 @@ static enum_specs ck_cls_s[] = { {CKO_PUBLIC_KEY , "CKO_PUBLIC_KEY "}, {CKO_PRIVATE_KEY , "CKO_PRIVATE_KEY "}, {CKO_SECRET_KEY , "CKO_SECRET_KEY "}, - {CKO_PROFILE , "CKO_PROFILE "}, {CKO_HW_FEATURE , "CKO_HW_FEATURE "}, {CKO_DOMAIN_PARAMETERS , "CKO_DOMAIN_PARAMETERS "}, {CKO_MECHANISM , "CKO_MECHANISM "}, diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 6dd70ea782..56f35efb7a 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -95,6 +95,8 @@ add_object(test_certs_t *objects, CK_ATTRIBUTE key_id, CK_ATTRIBUTE label) o->verify = 0; o->decrypt = 0; o->encrypt = 0; + o->encapsulate = 0; + o->decapsulate = 0; o->wrap = 0; o->unwrap = 0; o->derive_priv = 0; @@ -192,6 +194,7 @@ add_supported_mechs(test_cert_t *o) break; #ifdef EVP_PKEY_ED25519 case EVP_PKEY_ED25519: + case EVP_PKEY_ED448: if (token.num_ed_mechs > 0 ) { o->num_mechs = token.num_ed_mechs; for (i = 0; i < token.num_ed_mechs; i++) { @@ -215,6 +218,7 @@ add_supported_mechs(test_cert_t *o) #endif #ifdef EVP_PKEY_X25519 case EVP_PKEY_X25519: + case EVP_PKEY_X448: if (token.num_montgomery_mechs > 0 ) { o->num_mechs = token.num_montgomery_mechs; for (i = 0; i < token.num_montgomery_mechs; i++) { @@ -734,27 +738,37 @@ int callback_public_keys(test_certs_t *objects, ASN1_OBJECT *obj = NULL; const unsigned char *a; ASN1_OCTET_STRING *os; - int evp_type; + int evp_type = 0, exp_length = 0; a = template[6].pValue; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)template[6].ulValueLen) != NULL) { switch (o->key_type) { #ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: - if (strcmp((char *)curve->data, "edwards25519")) { - debug_print(" [WARN %s ] Unknown curve name. " - " expected edwards25519, got %s", o->id_str, curve->data); + if (strcmp((char *)curve->data, "edwards25519") == 0) { + evp_type = EVP_PKEY_ED25519; + break; + } else if (strcmp((char *)curve->data, "edwards448") == 0) { + evp_type = EVP_PKEY_ED448; + break; } - evp_type = EVP_PKEY_ED25519; + debug_print(" [WARN %s ] Unknown curve name. " + " expected edwards25519 or edwards448, got %s", + o->id_str, curve->data); break; #endif #ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: - if (strcmp((char *)curve->data, "curve25519")) { - debug_print(" [WARN %s ] Unknown curve name. " - " expected curve25519, got %s", o->id_str, curve->data); + if (strcmp((char *)curve->data, "curve25519") == 0) { + evp_type = EVP_PKEY_X25519; + break; + } else if (strcmp((char *)curve->data, "curve448") == 0) { + evp_type = EVP_PKEY_X448; + break; } - evp_type = EVP_PKEY_X25519; + debug_print(" [WARN %s ] Unknown curve name. " + " expected curve25519 or curve448, got %s", + o->id_str, curve->data); break; #endif default: @@ -771,20 +785,30 @@ int callback_public_keys(test_certs_t *objects, switch (o->key_type) { #ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: - if (nid != NID_ED25519) { - debug_print(" [WARN %s ] Unknown OID. " - " expected NID_ED25519 (%d), got %d", o->id_str, NID_ED25519, nid); + if (nid == NID_ED25519) { + evp_type = EVP_PKEY_ED25519; + break; + } else if (nid == NID_ED448) { + evp_type = EVP_PKEY_ED448; + break; } - evp_type = EVP_PKEY_ED25519; + debug_print(" [WARN %s ] Unknown OID. " + " expected NID_ED25519 (%d) or NID_ED448 (%d), got %d", + o->id_str, NID_ED25519, NID_ED448, nid); break; #endif #ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: - if (nid != NID_X25519) { - debug_print(" [WARN %s ] Unknown OID. " - " expected NID_X25519 (%d), got %d", o->id_str, NID_X25519, nid); + if (nid == NID_X25519) { + evp_type = EVP_PKEY_X25519; + break; + } else if (nid == NID_X448) { + evp_type = EVP_PKEY_X448; + break; } - evp_type = EVP_PKEY_X25519; + debug_print(" [WARN %s ] Unknown OID. " + " expected NID_X25519 (%d) or NID_X448 (%d), got %d", + o->id_str, NID_X25519, NID_X448, nid); break; #endif default: @@ -797,15 +821,38 @@ int callback_public_keys(test_certs_t *objects, return -1; } - /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ + /* PKCS#11-compliant modules should return ASN1_OCTET_STRING or ASN1_BIT_STRING */ a = template[7].pValue; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)template[7].ulValueLen); if (!os) { - debug_print(" [WARN %s ] Cannot decode EC_POINT", o->id_str); - return -1; + os = d2i_ASN1_BIT_STRING(NULL, &a, (long)template[7].ulValueLen); + } + /* or raw bytes as a last resort? */ + if (!os) { + if ((os = ASN1_OCTET_STRING_new()) == NULL) { + debug_print(" [WARN %s ] Out of memory", o->id_str); + return -1; + } + if (ASN1_OCTET_STRING_set(os, template[7].pValue, (int)template[7].ulValueLen) == 0) { + debug_print(" [WARN %s ] Cannot decode EC_POINT", o->id_str); + return -1; + } + } + switch (evp_type) { + case EVP_PKEY_ED25519: + case EVP_PKEY_X25519: + exp_length = 32; + break; + case EVP_PKEY_ED448: + exp_length = 57; + break; + case EVP_PKEY_X448: + exp_length = 56; + break; } - if (os->length != 32) { - debug_print(" [WARN %s ] Invalid length of EC_POINT value", o->id_str); + if (os->length != exp_length) { + debug_print(" [WARN %s ] Invalid length of EC_POINT value. Got %d, expected %d", + o->id_str, os->length, exp_length); return -1; } key = EVP_PKEY_new_raw_public_key(evp_type, NULL, @@ -850,7 +897,7 @@ int callback_public_keys(test_certs_t *objects, } else { /* store the public key for future use */ o->type = evp_type; o->key = key; - o->bits = 255; + o->bits = exp_length * 8; } ASN1_STRING_free(os); #ifdef EVP_PKEY_ML_DSA_44 @@ -1585,7 +1632,7 @@ get_mechanism_all_flag_name(unsigned long mech_id) static char f_buffer[80]; f_buffer[0] = '\0'; - for (j = 1; j <= CKF_EC_COMPRESS; j = j << 1) + for (j = 1; j <= CKF_DECAPSULATE; j = j << 1) /* append the name of the mechanism (only for known mechanisms) */ if ((mech_id & j) != 0 && strncmp("0x", get_mechanism_flag_name(j), 2)) { snprintf(f_buffer + strlen(f_buffer), diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index f1fb5e4a78..44b272dab8 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -97,14 +97,14 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, return get_value.ulValueLen; } -int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) +int test_derive_montgomery(test_cert_t *o, token_info_t *info, test_mech_t *mech) { #ifdef EVP_PKEY_X25519 unsigned char *secret = NULL, *pkcs11_secret = NULL; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; /* This is peer key */ unsigned char *pub = NULL; - size_t pub_len = 0, secret_len = 32, pkcs11_secret_len = 0; + size_t pub_len = 0, secret_len = o->bits/8, pkcs11_secret_len = 0; int rc; if (o->private_handle == CK_INVALID_HANDLE) { @@ -112,13 +112,18 @@ int test_derive_x25519(test_cert_t *o, token_info_t *info, test_mech_t *mech) return 1; } - if (o->type != EVP_PKEY_X25519) { - debug_print(" [ KEY %s ] Skip non-EC key for derive", o->id_str); + switch (o->type) { + case EVP_PKEY_X25519: + case EVP_PKEY_X448: + /* OK */ + break; + default: + debug_print(" [ KEY %s ] Skip non-montgomery key for derive", o->id_str); return 1; } /* First, we need to generate our key */ - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); + pctx = EVP_PKEY_CTX_new_id(o->type, NULL); if (pctx == NULL) { debug_print(" [ KEY %s ] EVP_PKEY_CTX_new_id failed", o->id_str); return 1; @@ -411,7 +416,7 @@ void derive_tests(void **state) { errors += test_derive(o, info, &(o->mechs[j])); break; case CKK_EC_MONTGOMERY: - errors += test_derive_x25519(o, info, &(o->mechs[j])); + errors += test_derive_montgomery(o, info, &(o->mechs[j])); break; default: /* Other keys do not support derivation */ @@ -436,9 +441,9 @@ void derive_tests(void **state) { printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[ %s ] [%6lu] [ %s ] [ %s%s ]\n", - (o->key_type == CKK_EC ? " EC " : - o->key_type == CKK_EC_MONTGOMERY ? "EC_M" : " ?? "), + printf("[%s] [%6lu] [ %s ] [ %s%s ]\n", + (o->key_type == CKK_EC ? "ECDSA " : + o->key_type == CKK_EC_MONTGOMERY ? "XEDDSA" : " ?? "), o->bits, o->verify_public == 1 ? " ./ " : " ", o->derive_pub ? "[./]" : "[ ]", diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 465337d405..5a790346bb 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -397,7 +397,8 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, CK_BYTE *cmp_message = NULL; unsigned int cmp_message_length = 0; - if (o->type == EVP_PKEY_RSA) { + switch (o->type) { + case EVP_PKEY_RSA: { const EVP_MD *md = NULL; EVP_MD_CTX *mdctx = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -481,7 +482,8 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, debug_print(" [ OK %s ] Signature is valid.", o->id_str); EVP_MD_CTX_free(mdctx); return 1; - } else if (o->type == EVP_PKEY_EC) { + } + case EVP_PKEY_EC: { int nlen; const EVP_MD *md = NULL; ECDSA_SIG *sig = ECDSA_SIG_new(); @@ -576,8 +578,11 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, rv, ERR_error_string(ERR_peek_last_error(), NULL)); return -1; } + break; + } #ifdef EVP_PKEY_ED25519 - } else if (o->type == EVP_PKEY_ED25519) { + case EVP_PKEY_ED25519: + case EVP_PKEY_ED448: { /* need to be created even though we do not do any MD */ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); @@ -602,8 +607,10 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, EVP_MD_CTX_free(ctx); return -1; } + break; + } #endif - } else { + default: fprintf(stderr, " [ KEY %s ] Unknown type. Not verifying\n", o->id_str); } return 0; @@ -684,6 +691,11 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, CK_BYTE *message = NULL; CK_BYTE *sign = NULL; CK_ULONG sign_length = 0; + CK_EDDSA_PARAMS eddsa_params = { + .phFlag = CK_FALSE, + .ulContextDataLen = 0, + .pContextData = NULL, + }; int rv = 0; if (message_length > strlen(MESSAGE_TO_SIGN)) { @@ -696,11 +708,39 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (o->type != EVP_PKEY_EC && o->type != EVP_PKEY_RSA + switch (o->type) { + case EVP_PKEY_EC: + case EVP_PKEY_RSA: #ifdef EVP_PKEY_ED25519 - && o->type != EVP_PKEY_ED25519 + case EVP_PKEY_ED448: + /* The Ed448 requires parameter */ + mech->params = &eddsa_params; + mech->params_len = sizeof(CK_EDDSA_PARAMS); + break; + case EVP_PKEY_ED25519: +#endif +#ifdef EVP_PKEY_ML_DSA_44 + case EVP_PKEY_ML_DSA_44: + case EVP_PKEY_ML_DSA_65: + case EVP_PKEY_ML_DSA_87: +#endif +#ifdef EVP_PKEY_SLH_DSA_SHA2_128S + case EVP_PKEY_SLH_DSA_SHA2_128S: + case EVP_PKEY_SLH_DSA_SHAKE_128S: + case EVP_PKEY_SLH_DSA_SHA2_128F: + case EVP_PKEY_SLH_DSA_SHAKE_128F: + case EVP_PKEY_SLH_DSA_SHA2_192S: + case EVP_PKEY_SLH_DSA_SHAKE_192S: + case EVP_PKEY_SLH_DSA_SHA2_192F: + case EVP_PKEY_SLH_DSA_SHAKE_192F: + case EVP_PKEY_SLH_DSA_SHA2_256S: + case EVP_PKEY_SLH_DSA_SHAKE_256S: + case EVP_PKEY_SLH_DSA_SHA2_256F: + case EVP_PKEY_SLH_DSA_SHAKE_256F: #endif - ) { + /* OK */ + break; + default: debug_print(" [SKIP %s ] Skip non-RSA and non-EC key", o->id_str); return 0; } @@ -808,7 +848,6 @@ void readonly_tests(void **state) { if (o->key_type != CKK_RSA && o->key_type != CKK_EC && o->key_type != CKK_EC_EDWARDS && - o->key_type != CKK_EC_MONTGOMERY && o->key_type != CKK_ML_DSA && o->key_type != CKK_SLH_DSA) continue; @@ -816,11 +855,10 @@ void readonly_tests(void **state) { printf("\n[%-6s] [%s]\n", o->id_str, o->label); - printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s] [%s%s]\n", + printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s]\n", (o->key_type == CKK_RSA ? " RSA " : o->key_type == CKK_EC ? " EC " : - o->key_type == CKK_EC_EDWARDS ? "EDDSA" : - o->key_type == CKK_EC_MONTGOMERY ? "XEDDS" : + o->key_type == CKK_EC_EDWARDS ? "EDDSA " : o->key_type == CKK_ML_DSA ? "ML-DSA" : o->key_type == CKK_SLH_DSA ? "SLHDSA" : " ?? "), o->bits, @@ -828,9 +866,7 @@ void readonly_tests(void **state) { o->sign ? "[./] " : "[ ] ", o->verify ? " [./] " : " [ ] ", o->encrypt ? "[./] " : "[ ] ", - o->decrypt ? " [./] " : " [ ] ", - o->encapsulate ? " [./] " : " [ ] ", - o->decapsulate ? " [./] " : " [ ] "); + o->decrypt ? " [./] " : " [ ] "); if (!o->sign && !o->verify && !o->encrypt && !o->decrypt && !o->encapsulate && !o->decapsulate) { printf(" no usable attributes found ... ignored\n"); diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index 3573da6b99..ac3c078ec3 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -53,6 +53,11 @@ void usage_test(void **state) { fprintf(stderr, " [ ERROR %s ] If Unwrap is set, Wrap should be set too.\n", objects.data[i].id_str); } + if (objects.data[i].encapsulate && !objects.data[i].decapsulate) { + errors++; + fprintf(stderr, " [ ERROR %s ] If Encapsulate is set, Decapsulate should be set too.\n", + objects.data[i].id_str); + } if (objects.data[i].derive_pub != objects.data[i].derive_priv) { errors++; fprintf(stderr, " [ ERROR %s ] Derive should be set on both private and public part.\n", @@ -60,10 +65,11 @@ void usage_test(void **state) { } /* We have at least one usage flag for every key group */ - if (! objects.data[i].sign && ! objects.data[i].verify && - ! objects.data[i].encrypt && ! objects.data[i].decrypt && - ! objects.data[i].wrap && ! objects.data[i].unwrap && - ! objects.data[i].derive_pub && ! objects.data[i].derive_priv) { + if (!objects.data[i].sign && !objects.data[i].verify && + !objects.data[i].encrypt && !objects.data[i].decrypt && + !objects.data[i].wrap && !objects.data[i].unwrap && + !objects.data[i].encapsulate && !objects.data[i].decapsulate && + !objects.data[i].derive_pub && !objects.data[i].derive_priv) { errors++; fprintf(stderr, " [ ERROR %s ] Key group should have at least one usage flag.\n", objects.data[i].id_str); @@ -72,8 +78,8 @@ void usage_test(void **state) { /* print summary */ printf("[KEY ID] [LABEL]\n"); - printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ DERIVE ] [ALWAYS_AUTH]\n"); - P11TEST_DATA_ROW(info, 14, + printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ENC&DECAPS] [ DERIVE ] [ALWAYS_AUTH]\n"); + P11TEST_DATA_ROW(info, 16, 's', "KEY ID", 's', "LABEL", 's', "TYPE", @@ -85,6 +91,8 @@ void usage_test(void **state) { 's', "DECRYPT", 's', "WRAP", 's', "UNWRAP", + 's', "ENCAPSULATE", + 's', "DECAPSULATE", 's', "DERIVE PUBLIC", 's', "DERIVE PRIVATE", 's', "ALWAYS AUTH"); @@ -97,12 +105,15 @@ void usage_test(void **state) { if (objects.data[i].private_handle == CK_INVALID_HANDLE) continue; - printf("[ %s ] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s%s] [ %s ]\n", - (o->key_type == CKK_RSA ? "RSA " : o->key_type == CKK_EC ? " EC " - : o->key_type == CKK_EC_EDWARDS ? "EC_E" - : o->key_type == CKK_EC_MONTGOMERY ? "EC_M" - : o->key_type == CKK_AES ? "AES " - : o->key_type == CKK_GENERIC_SECRET ? "GEN " + printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s] [%s %s] [%s %s] [%s%s] [ %s ]\n", + (o->key_type == CKK_RSA ? " RSA " : o->key_type == CKK_EC ? " EC " + : o->key_type == CKK_EC_EDWARDS ? "EDDSA " + : o->key_type == CKK_EC_MONTGOMERY ? "XEDDSA" + : o->key_type == CKK_AES ? " AES " + : o->key_type == CKK_GENERIC_SECRET ? "GENER " + : o->key_type == CKK_ML_DSA ? "ML-DSA" + : o->key_type == CKK_ML_KEM ? "ML-KEM" + : o->key_type == CKK_SLH_DSA ? "SLHDSA" : " ?? "), o->bits, o->verify_public == 1 ? " ./ " : " ", @@ -112,17 +123,22 @@ void usage_test(void **state) { o->decrypt ? " [./] " : " [ ] ", o->wrap ? "[./]" : "[ ]", o->unwrap ? "[./]" : "[ ]", + o->encapsulate ? "[./]" : "[ ]", + o->decapsulate ? "[./]" : "[ ]", o->derive_pub ? "[./]" : "[ ]", o->derive_priv ? "[./]" : "[ ]", o->always_auth ? "[./]" : "[ ]"); - P11TEST_DATA_ROW(info, 14, + P11TEST_DATA_ROW(info, 16, 's', o->id_str, 's', o->label, 's', (o->key_type == CKK_RSA ? "RSA" : o->key_type == CKK_EC ? "EC" - : o->key_type == CKK_EC_EDWARDS ? "EC_E" - : o->key_type == CKK_EC_MONTGOMERY ? "EC_M" + : o->key_type == CKK_EC_EDWARDS ? "EDDSA" + : o->key_type == CKK_EC_MONTGOMERY ? "XEDDSA" : o->key_type == CKK_AES ? "AES" : o->key_type == CKK_GENERIC_SECRET ? "GEN" + : o->key_type == CKK_ML_DSA ? "ML-DSA" + : o->key_type == CKK_ML_KEM ? "ML-KEM" + : o->key_type == CKK_SLH_DSA ? "SLH-DSA" : " ?? "), 'd', o->bits, 's', o->verify_public == 1 ? "YES" : "", @@ -132,15 +148,19 @@ void usage_test(void **state) { 's', o->decrypt ? "YES" : "", 's', o->wrap ? "YES" : "", 's', o->unwrap ? "YES" : "", + 's', o->encapsulate ? "YES" : "", + 's', o->decapsulate ? "YES" : "", 's', o->derive_pub ? "YES" : "", 's', o->derive_priv ? "YES" : "", 's', o->always_auth ? "YES" : ""); } - printf(" Public == Cert -----^ ^-----^ ^-----^ ^----^ ^---^\n"); - printf(" Sign & Verify Attributes ------' | | |\n"); - printf(" Encrypt & Decrypt Attributes ----------------' | |\n"); - printf(" Wrap & Unwrap Attributes ---------------------------------' |\n"); - printf(" Public and Private key Derive Attributes -----------------------------'\n"); + printf(" Public == Cert -----^ ^-----^ ^-----^ ^----^ ^-----^ ^---^ ^\n"); + printf(" Sign & Verify Attributes ------' | | | | |\n"); + printf(" Encrypt & Decrypt Attributes ----------------' | | | |\n"); + printf(" Wrap & Unwrap Attributes ---------------------------------' | | |\n"); + printf(" Encapsulate & Decapsulate Attributes ----------------------------------' | |\n"); + printf(" Public and Private key Derive Attributes ------------------------------------------' |\n"); + printf(" Always Authenticate Attribute ------------------------------------------------------------------'\n"); clean_all_objects(&objects); if (errors > 0) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 261048adcd..b854bcc39e 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3696,9 +3696,9 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (strcmp(type, "ML-DSA-44") == 0) { ml_dsa_parameter_set = CKP_ML_DSA_44; - } else if (strcmp(type, "ML-DSA-65")) { + } else if (strcmp(type, "ML-DSA-65") == 0) { ml_dsa_parameter_set = CKP_ML_DSA_65; - } else if (strcmp(type, "ML-DSA-87")) { + } else if (strcmp(type, "ML-DSA-87") == 0) { ml_dsa_parameter_set = CKP_ML_DSA_87; } else { util_fatal("Invalid ML-DSA key type '%s'", type); @@ -3728,9 +3728,9 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (strcmp(type, "ML-KEM-512") == 0) { ml_kem_parameter_set = CKP_ML_KEM_512; - } else if (strcmp(type, "ML-KEM-768")) { + } else if (strcmp(type, "ML-KEM-768") == 0) { ml_kem_parameter_set = CKP_ML_KEM_768; - } else if (strcmp(type, "ML-KEM-1024")) { + } else if (strcmp(type, "ML-KEM-1024") == 0) { ml_kem_parameter_set = CKP_ML_KEM_1024; } else { util_fatal("Invalid ML-KEM key type '%s'", type); @@ -3760,27 +3760,27 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (strcmp(type, "SLH-DSA-SHA2-128S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_128S; - } else if (strcmp(type, "SLH-DSA-SHAKE-128S")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-128S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_128S; - } else if (strcmp(type, "SLH-DSA-SHA2-128F")) { + } else if (strcmp(type, "SLH-DSA-SHA2-128F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_128F; - } else if (strcmp(type, "SLH-DSA-SHAKE-128F")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-128F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_128F; - } else if (strcmp(type, "SLH-DSA-SHA2-192S")) { + } else if (strcmp(type, "SLH-DSA-SHA2-192S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_192S; - } else if (strcmp(type, "SLH-DSA-SHAKE-192S")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-192S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_192S; - } else if (strcmp(type, "SLH-DSA-SHA2-192F")) { + } else if (strcmp(type, "SLH-DSA-SHA2-192F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_192F; - } else if (strcmp(type, "SLH-DSA-SHAKE-192F")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-192F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_192F; - } else if (strcmp(type, "SLH-DSA-SHA2-256S")) { + } else if (strcmp(type, "SLH-DSA-SHA2-256S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_256S; - } else if (strcmp(type, "SLH-DSA-SHAKE-256S")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-256S") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_256S; - } else if (strcmp(type, "SLH-DSA-SHA2-256F")) { + } else if (strcmp(type, "SLH-DSA-SHA2-256F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHA2_256F; - } else if (strcmp(type, "SLH-DSA-SHAKE-256F")) { + } else if (strcmp(type, "SLH-DSA-SHAKE-256F") == 0) { slh_dsa_parameter_set = CKP_SLH_DSA_SHAKE_256F; } else { util_fatal("Invalid SLH-DSA key type '%s'", type); diff --git a/tests/common.sh b/tests/common.sh index 647d22e845..b0d56e25ff 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -46,21 +46,21 @@ function generate_key() { fi # Extract public key from the card - #$PKCS11_TOOL "${PUB_ARGS[@]}" --read-object --id $ID --type pubkey --output-file $ID.der - #if [[ "$?" -ne "0" ]]; then - # echo "Couldn't read generated $TYPE public key" - # return 1 - #fi + $PKCS11_TOOL "${PUB_ARGS[@]}" --read-object --id $ID --type pubkey --output-file $ID.der + if [[ "$?" -ne "0" ]]; then + echo "Couldn't read generated $TYPE public key" + return 1 + fi - ## convert it to more digestible PEM format - #if [[ ${TYPE:0:3} == "RSA" ]]; then - # openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - #elif [[ $TYPE == "EC:edwards25519" ]]; then - # openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - #else - # openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - #fi - #rm $ID.der + # convert it to more digestible PEM format + if [[ ${TYPE:0:3} == "RSA" ]]; then + openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + elif [[ $TYPE == "EC:edwards25519" ]]; then + openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + else + openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + fi + rm $ID.der } function card_setup() { @@ -84,23 +84,25 @@ function card_setup() { if [ "${TOKENTYPE}" == "kryoptic" ]; then # Generate Ed25519 Key pair generate_key "EC:ed25519" "06" "ed25519" || return 1 + # Generate Ed448 Key pair + generate_key "EC:ed448" "07" "ed448" || return 1 # Generate x25519 Key pair - generate_key "EC:x25519" "07" "x25519" || return 1 + generate_key "EC:x25519" "08" "x25519" || return 1 # Generate x448 Key pair - generate_key "EC:x448" "08" "x448" || return 1 + generate_key "EC:x448" "09" "x448" || return 1 # Generate ML-DSA-65 Key pair - generate_key "ML-DSA-65" "09" "ML-DSA-65" || return 1 + generate_key "ML-DSA-65" "10" "ML-DSA-65" || return 1 # Generate ML-KEM-768 Key pair - generate_key "ML-KEM-768" "10" "ML-KEM-768" || return 1 + generate_key "ML-KEM-768" "11" "ML-KEM-768" || return 1 # Generate SLH-DSA-SHA2-192S Key pair - generate_key "SLH-DSA-SHA2-192S" "11" "SLH-DSA-SHA2-192S" || return 1 + generate_key "SLH-DSA-SHA2-192S" "12" "SLH-DSA-SHA2-192S" || return 1 fi } function card_cleanup() { token_cleanup - #rm 0{1,2,3,4}.pub + rm 0{1,2,3,4}.pub sleep 1 } From 03f3dfa147e7a7d54f2060f7fd353089c951586c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 12 Nov 2025 22:18:15 +0100 Subject: [PATCH 4031/4321] More fixes mostly about import/export --- src/tests/p11test/p11test_case_common.c | 264 +++-- src/tests/p11test/p11test_case_common.h | 3 + src/tests/p11test/p11test_case_mechs.c | 6 +- src/tests/p11test/p11test_case_readonly.c | 40 +- src/tools/pkcs11-tool.c | 315 ++++- tests/common.sh | 4 +- tests/init-kryoptic.sh | 10 +- tests/kryoptic_ref.json | 1320 +++++++++++++++++++-- tests/test-pkcs11-tool-import.sh | 38 +- 9 files changed, 1764 insertions(+), 236 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 56f35efb7a..b183d9cbce 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -358,6 +358,7 @@ int callback_certificates(test_certs_t *objects, EVP_PKEY *evp = NULL; const u_char *cp = NULL; test_cert_t *o = NULL; + int base_id; if (*(CK_CERTIFICATE_TYPE *)template[3].pValue != CKC_X_509) return 0; @@ -380,19 +381,40 @@ int callback_certificates(test_certs_t *objects, return -1; } - if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) { - o->key = evp; - o->type = EVP_PKEY_RSA; - o->bits = EVP_PKEY_bits(evp); - - } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { + base_id = EVP_PKEY_base_id(evp); + switch (base_id) { + case EVP_PKEY_RSA: + case EVP_PKEY_EC: + case EVP_PKEY_ED25519: + case EVP_PKEY_X25519: + case EVP_PKEY_ED448: + case EVP_PKEY_X448: +#ifdef EVP_PKEY_ML_DSA_44 + case EVP_PKEY_ML_DSA_44: + case EVP_PKEY_ML_DSA_65: + case EVP_PKEY_ML_DSA_87: +#endif +#ifdef EVP_PKEY_SLH_DSA_SHA2_128S + case EVP_PKEY_SLH_DSA_SHA2_128S: + case EVP_PKEY_SLH_DSA_SHAKE_128S: + case EVP_PKEY_SLH_DSA_SHA2_128F: + case EVP_PKEY_SLH_DSA_SHAKE_128F: + case EVP_PKEY_SLH_DSA_SHA2_192S: + case EVP_PKEY_SLH_DSA_SHAKE_192S: + case EVP_PKEY_SLH_DSA_SHA2_192F: + case EVP_PKEY_SLH_DSA_SHAKE_192F: + case EVP_PKEY_SLH_DSA_SHA2_256S: + case EVP_PKEY_SLH_DSA_SHAKE_256S: + case EVP_PKEY_SLH_DSA_SHA2_256F: + case EVP_PKEY_SLH_DSA_SHAKE_256F: +#endif o->key = evp; - o->type = EVP_PKEY_EC; + o->type = base_id; o->bits = EVP_PKEY_bits(evp); - - } else { + break; + default: EVP_PKEY_free(evp); - fprintf(stderr, "[WARN %s ]evp->type = 0x%.4X (not RSA, EC)\n", + fprintf(stderr, "[WARN %s ]evp->type = 0x%.4X (not supported)\n", o->id_str, EVP_PKEY_id(evp)); } @@ -900,90 +922,159 @@ int callback_public_keys(test_certs_t *objects, o->bits = exp_length * 8; } ASN1_STRING_free(os); -#ifdef EVP_PKEY_ML_DSA_44 - } else if (o->key_type == CKK_ML_DSA) { - o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) - ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; - switch (o->parameter_set) { - case CKP_ML_DSA_44: - o->type = EVP_PKEY_ML_DSA_44; - break; - case CKP_ML_DSA_65: - o->type = EVP_PKEY_ML_DSA_65; - break; - case CKP_ML_DSA_87: - o->type = EVP_PKEY_ML_DSA_87; +#if defined(EVP_PKEY_ML_DSA_44) || defined(EVP_PKEY_ML_KEM_512) || defined(EVP_PKEY_SLH_DSA_SHA2_128S) + } else if (o->key_type == CKK_ML_DSA || + o->key_type == CKK_ML_KEM || + o->key_type == CKK_SLH_DSA) { + int base_id = 0; + + o->parameter_set = (template[11].ulValueLen == sizeof(CK_ULONG)) + ? *((CK_ULONG *)template[11].pValue) : CK_UNAVAILABLE_INFORMATION; + switch (o->key_type) { + case CKK_ML_DSA: + switch (o->parameter_set) { + case CKP_ML_DSA_44: + base_id = EVP_PKEY_ML_DSA_44; + break; + case CKP_ML_DSA_65: + base_id = EVP_PKEY_ML_DSA_65; + break; + case CKP_ML_DSA_87: + base_id = EVP_PKEY_ML_DSA_87; + break; + default: + debug_print(" [WARN %s ] Unknown parameter set (%lu)", + o->id_str, o->parameter_set); + return -1; + } break; - default: - return -1; - } - // TODO more processing -#endif /* EVP_PKEY_ML_DSA_44 */ #ifdef EVP_PKEY_ML_KEM_512 - } else if (o->key_type == CKK_ML_KEM) { - o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) - ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; - switch (o->parameter_set) { - case CKP_ML_KEM_512: - o->key_type = EVP_PKEY_ML_KEM_512; - break; - case CKP_ML_KEM_768: - o->key_type = EVP_PKEY_ML_KEM_768; + case CKK_ML_KEM: + switch (o->parameter_set) { + case CKP_ML_KEM_512: + base_id = EVP_PKEY_ML_KEM_512; + break; + case CKP_ML_KEM_768: + base_id = EVP_PKEY_ML_KEM_768; + break; + case CKP_ML_KEM_1024: + base_id = EVP_PKEY_ML_KEM_1024; + break; + default: + debug_print(" [WARN %s ] Unknown parameter set (%lu)", + o->id_str, o->parameter_set); + return -1; + } break; - case CKP_ML_KEM_1024: - o->key_type = EVP_PKEY_ML_KEM_1024; +#endif + case CKK_SLH_DSA: + switch (o->parameter_set) { + case CKP_SLH_DSA_SHA2_128S: + base_id = EVP_PKEY_SLH_DSA_SHA2_128S; + break; + case CKP_SLH_DSA_SHAKE_128S: + base_id = EVP_PKEY_SLH_DSA_SHAKE_128S; + break; + case CKP_SLH_DSA_SHA2_128F: + base_id = EVP_PKEY_SLH_DSA_SHA2_128F; + break; + case CKP_SLH_DSA_SHAKE_128F: + base_id = EVP_PKEY_SLH_DSA_SHAKE_128F; + break; + case CKP_SLH_DSA_SHA2_192S: + base_id = EVP_PKEY_SLH_DSA_SHA2_192S; + break; + case CKP_SLH_DSA_SHAKE_192S: + base_id = EVP_PKEY_SLH_DSA_SHAKE_192S; + break; + case CKP_SLH_DSA_SHA2_192F: + base_id = EVP_PKEY_SLH_DSA_SHA2_192F; + break; + case CKP_SLH_DSA_SHAKE_192F: + base_id = EVP_PKEY_SLH_DSA_SHAKE_192F; + break; + case CKP_SLH_DSA_SHA2_256S: + base_id = EVP_PKEY_SLH_DSA_SHA2_256S; + break; + case CKP_SLH_DSA_SHAKE_256S: + base_id = EVP_PKEY_SLH_DSA_SHAKE_256S; + break; + case CKP_SLH_DSA_SHA2_256F: + base_id = EVP_PKEY_SLH_DSA_SHA2_256F; + break; + case CKP_SLH_DSA_SHAKE_256F: + base_id = EVP_PKEY_SLH_DSA_SHAKE_256F; + break; + default: + debug_print(" [WARN %s ] Unknown parameter set (%lu)", + o->id_str, o->parameter_set); + return -1; + } break; default: + debug_print(" [WARN %s ] Unknown key type (%lu)", + o->id_str, o->key_type); return -1; } - // TODO more processing -#endif /* EVP_PKEY_ML_KEM_512 */ -#ifdef EVP_PKEY_SLH_DSA_SHA2_128S - } else if (o->key_type == CKK_SLH_DSA) { - o->parameter_set = (template[10].ulValueLen == sizeof(CK_ULONG)) - ? *((CK_ULONG *)template[10].pValue) : CK_UNAVAILABLE_INFORMATION; - switch (o->parameter_set) { - case CKP_SLH_DSA_SHA2_128S: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_128S; - break; - case CKP_SLH_DSA_SHAKE_128S: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_128S; - break; - case CKP_SLH_DSA_SHA2_128F: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_128F; - break; - case CKP_SLH_DSA_SHAKE_128F: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_128F; - break; - case CKP_SLH_DSA_SHA2_192S: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_192S; - break; - case CKP_SLH_DSA_SHAKE_192S: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_192S; - break; - case CKP_SLH_DSA_SHA2_192F: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_192F; - break; - case CKP_SLH_DSA_SHAKE_192F: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_192F; - break; - case CKP_SLH_DSA_SHA2_256S: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_256S; - break; - case CKP_SLH_DSA_SHAKE_256S: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_256S; - break; - case CKP_SLH_DSA_SHA2_256F: - o->key_type = EVP_PKEY_SLH_DSA_SHA2_256F; - break; - case CKP_SLH_DSA_SHAKE_256F: - o->key_type = EVP_PKEY_SLH_DSA_SHAKE_256F; - break; - default: - return -1; + + if (o->key != NULL) { + // compare with the certificate + unsigned char *cert_pubkey = NULL; + size_t cert_pubkey_len = 0; + + if (base_id != o->type) { + debug_print(" [WARN %s ] Got different key type than certificate " + "(got %d, expected %d)", + o->id_str, base_id, o->type); + } + + if ((EVP_PKEY_get_octet_string_param(o->key, "pub", NULL, 0, &cert_pubkey_len) != 1)) { + fprintf(stderr, "Failed to extract public key length"); + return -1; + } + if ((cert_pubkey = malloc(cert_pubkey_len)) == NULL) { + fprintf(stderr, "Out of memory"); + return -1; + } + if ((EVP_PKEY_get_octet_string_param(o->key, "pub", cert_pubkey, cert_pubkey_len, &cert_pubkey_len) != 1)) { + fprintf(stderr, "Failed to extract public key"); + free(cert_pubkey); + return -1; + } + if (template[12].ulValueLen == cert_pubkey_len || + memcmp(template[12].pValue, cert_pubkey, cert_pubkey_len) == 0) { + o->verify_public = 1; + } else { + debug_print(" [WARN %s ] Got different public key then from the certificate", + o->id_str); + } + free(cert_pubkey); + } else { + // construct the OpenSSL key + o->type = base_id; + if (!(ctx = EVP_PKEY_CTX_new_id(o->type, NULL)) || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", template[12].pValue, + template[12].ulValueLen) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_BLD_free(bld); + fail_msg("Unable to set key params"); + return -1; + } + OSSL_PARAM_BLD_free(bld); + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + fail_msg("Unable to build key"); + return -1; + } + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + o->bits = EVP_PKEY_bits(o->key); } - // TODO more processing -#endif /* EVP_PKEY_SLH_DSA_SHA2_128S */ +#endif /* EVP_PKEY_ML_DSA_44 */ } else { debug_print(" [WARN %s ] unknown key. Key type: %02lX", o->id_str, o->key_type); @@ -1204,6 +1295,7 @@ void search_for_all_objects(test_certs_t *objects, token_info_t *info) { CKA_DERIVE, NULL, 0}, // CK_BBOOL { CKA_ENCAPSULATE, NULL, 0}, // CK_BBOOL { CKA_PARAMETER_SET, NULL, 0}, // CK_ULONG + { CKA_VALUE, NULL, 0}, }; CK_ULONG public_attrs_size = sizeof (public_attrs) / sizeof (CK_ATTRIBUTE); CK_ATTRIBUTE secret_attrs[] = { diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 28a8d61215..20441d3466 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -30,6 +30,9 @@ # include # include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30500000L +# include +#endif #include "p11test_common.h" #define MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index 51bd1523f1..efc6cac00c 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -242,15 +242,15 @@ supported_mechanisms_test(void **state) } } - printf("[ MECHANISM ] [ KEY SIZE ] [ FLAGS ]\n"); - printf("[ CKM_* ] [ MIN][ MAX] [ ]\n"); + printf("[ MECHANISM ] [ KEY SIZE ] [ FLAGS ]\n"); + printf("[ CKM_* ] [ MIN][ MAX ] [ ]\n"); P11TEST_DATA_ROW(info, 4, 's', "MECHANISM", 's', "MIN KEY", 's', "MAX KEY", 's', "FLAGS"); for (i = 0; i < mechanism_count; i++) { - printf("[%-21s] [%4lu][%4lu] [0x%.8lX]", + printf("[%-21s] [%4lu][%5lu] [0x%.8lX]", get_mechanism_name(mechanism_list[i]), mechanism_info[i].ulMinKeySize, mechanism_info[i].ulMaxKeySize, diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 5a790346bb..d9a77c49ca 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -622,7 +622,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 }; + CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; static int verify_support = 1; char *name; @@ -696,6 +696,12 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, .ulContextDataLen = 0, .pContextData = NULL, }; + CK_HASH_SIGN_ADDITIONAL_CONTEXT pqc_params = { + .hedgeVariant = CKH_HEDGE_PREFERRED, + .pContext = NULL, + .ulContextLen = 0, + .hash = CKM_SHA256, + }; int rv = 0; if (message_length > strlen(MESSAGE_TO_SIGN)) { @@ -751,14 +757,22 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, return 0; } - if (mech->mech == CKM_RSA_X_509) /* manually add padding */ + if (mech->mech == CKM_RSA_X_509) { /* manually add padding */ message = rsa_x_509_pad_message(const_message, &message_length, o, 0); - else if (mech->mech == CKM_RSA_PKCS) { + } else if (mech->mech == CKM_RSA_PKCS) { /* DigestInfo + SHA1(message) */ message_length = 35; message = malloc(message_length * sizeof(unsigned char)); memcpy(message, MESSAGE_DIGEST, message_length); + } else if (mech->mech == CKM_HASH_ML_DSA || mech->mech == CKM_HASH_SLH_DSA) { + /* Hash of the message, */ + message_length = 32; + message = malloc(message_length * sizeof(unsigned char)); + memcpy(message, MESSAGE_DIGEST, message_length); + /* and requires parameter */ + mech->params = &pqc_params; + mech->params_len = sizeof(CK_HASH_SIGN_ADDITIONAL_CONTEXT); } else message = (CK_BYTE *) strdup(MESSAGE_TO_SIGN); @@ -856,11 +870,11 @@ void readonly_tests(void **state) { o->id_str, o->label); printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s]\n", - (o->key_type == CKK_RSA ? " RSA " : - o->key_type == CKK_EC ? " EC " : - o->key_type == CKK_EC_EDWARDS ? "EDDSA " : - o->key_type == CKK_ML_DSA ? "ML-DSA" : - o->key_type == CKK_SLH_DSA ? "SLHDSA" : " ?? "), + (o->key_type == CKK_RSA ? " RSA " : + o->key_type == CKK_EC ? " EC " : + o->key_type == CKK_EC_EDWARDS ? " EDDSA " : + o->key_type == CKK_ML_DSA ? "ML-DSA " : + o->key_type == CKK_SLH_DSA ? "SLH-DSA" : " ?? "), o->bits, o->verify_public == 1 ? " ./ " : " ", o->sign ? "[./] " : "[ ] ", @@ -881,7 +895,7 @@ void readonly_tests(void **state) { /* not applicable mechanisms are skipped */ continue; } - printf(" [ %-20s ] [ %s ] [ %s ]\n", + printf(" [ %-21s ] [ %s ] [ %s ]\n", get_mechanism_name(mech->mech), mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); @@ -895,10 +909,10 @@ void readonly_tests(void **state) { 's', mech->result_flags & FLAGS_DECRYPT_ANY ? "YES" : ""); } } - printf(" Public == Cert -----^ ^ ^ ^ ^ ^ ^\n"); - printf(" Sign Attribute -------------' | | | | '---- Decrypt Attribute\n"); - printf(" Sign&Verify functionality -----' | | '------- Enc&Dec functionality\n"); - printf(" Verify Attribute -----------------' '---------- Encrypt Attribute\n"); + printf(" Public == Cert ------^ ^ ^ ^ ^ ^ ^\n"); + printf(" Sign Attribute --------------' | | | | '---- Decrypt Attribute\n"); + printf(" Sign&Verify functionality- -----' | | '------- Enc&Dec functionality\n"); + printf(" Verify Attribute ------------------' '---------- Encrypt Attribute\n"); clean_all_objects(&objects); P11TEST_PASS(info); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b854bcc39e..1a0a31a115 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -761,6 +761,8 @@ ATTR_METHOD(EXTRACTABLE, CK_BBOOL); /* getEXTRACTABLE */ ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL); /* getNEVER_EXTRACTABLE */ ATTR_METHOD(LOCAL, CK_BBOOL); /* getLOCAL */ ATTR_METHOD(OPENSC_NON_REPUDIATION, CK_BBOOL); /* getOPENSC_NON_REPUDIATION */ +ATTR_METHOD(ENCAPSULATE, CK_BBOOL); /* getENCAPSULATE */ +ATTR_METHOD(DECAPSULATE, CK_BBOOL); /* getDECAPSULATE */ ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE); /* getKEY_TYPE */ ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */ ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */ @@ -3708,9 +3710,11 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) util_fatal("Generate ML-DSA mechanism not supported"); - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, + &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, + &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_sign) { @@ -3740,9 +3744,11 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) util_fatal("Generate ML-KEM mechanism not supported"); - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, + &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, + &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_encapsulate) { @@ -3790,9 +3796,11 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) util_fatal("Generate SLH-DSA mechanism not supported"); - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, + &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, + &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_sign) { @@ -4703,9 +4711,43 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info { int rc; - /* FIXME convert the type to parameter set? */ - if ((pqc->type = EVP_PKEY_get_id(pkey)) == -1) { - return -1; + const char *str_name = EVP_PKEY_get0_type_name(pkey); + if (strcmp(str_name, "ML-DSA-44") == 0) { + pqc->type = CKP_ML_DSA_44; + } else if (strcmp(str_name, "ML-DSA-65") == 0) { + pqc->type = CKP_ML_DSA_65; + } else if (strcmp(str_name, "ML-DSA-87") == 0) { + pqc->type = CKP_ML_DSA_87; + } else if (strcmp(str_name, "ML-KEM-512") == 0) { + pqc->type = CKP_ML_KEM_512; + } else if (strcmp(str_name, "ML-KEM-768") == 0) { + pqc->type = CKP_ML_KEM_768; + } else if (strcmp(str_name, "ML-KEM-1024") == 0) { + pqc->type = CKP_ML_KEM_1024; + } else if (strcmp(str_name, "SLH-DSA-SHA2-128f") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_128F; + } else if (strcmp(str_name, "SLH-DSA-SHA2-128s") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_128S; + } else if (strcmp(str_name, "SLH-DSA-SHA2-192f") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_192F; + } else if (strcmp(str_name, "SLH-DSA-SHA2-192s") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_192S; + } else if (strcmp(str_name, "SLH-DSA-SHA2-256f") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_256F; + } else if (strcmp(str_name, "SLH-DSA-SHA2-256s") == 0) { + pqc->type = CKP_SLH_DSA_SHA2_256S; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_128F; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_128S; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_192F; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_192S; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_256F; + } else if (strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { + pqc->type = CKP_SLH_DSA_SHAKE_256S; } if (private) { size_t priv_len; @@ -4725,20 +4767,21 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info return -1; } - } - - switch (type) { - case CKK_ML_DSA: - seed_param = OSSL_PKEY_PARAM_ML_DSA_SEED; - break; - case CKK_SLH_DSA: - seed_param = OSSL_PKEY_PARAM_SLH_DSA_SEED; - break; - } - if (seed_param != NULL) { - size_t seed_len = 0; - rc = EVP_PKEY_get_octet_string_param(pkey, seed_param, NULL, 0, &seed_len); - if (rc == 1) { + } else { + switch (type) { + case CKK_ML_DSA: + seed_param = OSSL_PKEY_PARAM_ML_DSA_SEED; + break; + case CKK_SLH_DSA: + seed_param = OSSL_PKEY_PARAM_SLH_DSA_SEED; + break; + } + if (seed_param != NULL) { + size_t seed_len = 0; + rc = EVP_PKEY_get_octet_string_param(pkey, seed_param, NULL, 0, &seed_len); + if (rc != 1) { + util_fatal("Neither PRIVATE key value nor seed available"); + } pqc->seed.len = seed_len; if (!(pqc->seed.value = OPENSSL_malloc(pqc->seed.len))) { OPENSSL_free(pqc->private.value); @@ -4751,12 +4794,10 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info OPENSSL_free(pqc->seed.value); return -1; } + } else { + util_fatal("PRIVATE key value available"); } } - /* But we need at least one */ - if (pqc->seed.value == NULL && pqc->private.value == NULL) { - return -1; - } } else { size_t pub_len; @@ -4797,89 +4838,141 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ if (ec_curve_info) *ec_curve_info = NULL; + switch (*pk_type) { #if defined(EVP_PKEY_RSA) - if (*pk_type == EVP_PKEY_RSA) { + case EVP_PKEY_RSA: *type = CKK_RSA; return CKR_OK; - } #endif #if defined(EVP_PKEY_EC) - if (*pk_type == EVP_PKEY_EC) { + case EVP_PKEY_EC: *type = CKK_EC; return CKR_OK; - } #endif #if defined(EVP_PKEY_ED25519) - if (*pk_type == EVP_PKEY_ED25519) { + case EVP_PKEY_ED25519: *type = CKK_EC_EDWARDS; if (ec_curve_info == NULL) goto err; *ec_curve_info = match_ec_curve_by_name("Ed25519"); return CKR_OK; - } #endif #if defined(EVP_PKEY_ED448) - if (*pk_type == EVP_PKEY_ED448) { + case EVP_PKEY_ED448: *type = CKK_EC_EDWARDS; if (ec_curve_info == NULL) goto err; *ec_curve_info = match_ec_curve_by_name("Ed448"); return CKR_OK; - } #endif #if defined(EVP_PKEY_X25519) - if (*pk_type == EVP_PKEY_X25519) { + case EVP_PKEY_X25519: *type = CKK_EC_MONTGOMERY; if (ec_curve_info == NULL) goto err; *ec_curve_info = match_ec_curve_by_name("X25519"); return CKR_OK; - } #endif #if defined(EVP_PKEY_X448) - if (*pk_type == EVP_PKEY_X448) { + case EVP_PKEY_X448: *type = CKK_EC_MONTGOMERY; if (ec_curve_info == NULL) goto err; *ec_curve_info = match_ec_curve_by_name("X448"); return CKR_OK; - } #endif #if defined(NID_id_GostR3410_2001) - if (*pk_type == NID_id_GostR3410_2001) { + case NID_id_GostR3410_2001: *type = CKK_GOSTR3410; return CKR_OK; - } #endif #if defined(EVP_PKEY_GOSTR3411) - if (*pk_type == EVP_PKEY_GOSTR3411) { + case EVP_PKEY_GOSTR3411: *type = CKK_GOSTR3411; return CKR_OK; - } #endif #if defined(EVP_PKEY_GOST28147) - if (*pk_type == EVP_PKEY_GOST28147) { + case EVP_PKEY_GOST28147: *type = CKK_GOST28147; return CKR_OK; - } #endif #if defined(EVP_PKEY_ML_DSA_44) && defined(EVP_PKEY_ML_DSA_65) && defined(EVP_PKEY_ML_DSA_87) - if (*pk_type == EVP_PKEY_ML_DSA_44 || *pk_type == EVP_PKEY_ML_DSA_65 || *pk_type == EVP_PKEY_ML_DSA_87) { + case EVP_PKEY_ML_DSA_44: + case EVP_PKEY_ML_DSA_65: + case EVP_PKEY_ML_DSA_87: *type = CKK_ML_DSA; return CKR_OK; +#endif + +#if defined(EVP_PKEY_ML_KEM_512) && defined(EVP_PKEY_ML_KEM_768) && defined(EVP_PKEY_ML_KEM_1024) + case EVP_PKEY_ML_KEM_512: + case EVP_PKEY_ML_KEM_768: + case EVP_PKEY_ML_KEM_1024: + *type = CKK_ML_KEM; + return CKR_OK; +#endif + +#if defined(EVP_PKEY_SLH_DSA_SHA2_128S) + case EVP_PKEY_SLH_DSA_SHA2_128S: + case EVP_PKEY_SLH_DSA_SHAKE_128S: + case EVP_PKEY_SLH_DSA_SHA2_128F: + case EVP_PKEY_SLH_DSA_SHAKE_128F: + case EVP_PKEY_SLH_DSA_SHA2_192S: + case EVP_PKEY_SLH_DSA_SHAKE_192S: + case EVP_PKEY_SLH_DSA_SHA2_192F: + case EVP_PKEY_SLH_DSA_SHAKE_192F: + case EVP_PKEY_SLH_DSA_SHA2_256S: + case EVP_PKEY_SLH_DSA_SHAKE_256S: + case EVP_PKEY_SLH_DSA_SHA2_256F: + case EVP_PKEY_SLH_DSA_SHAKE_256F: + *type = CKK_SLH_DSA; + return CKR_OK; +#endif } + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + /* Still no dice? Try the new OpenSSL 3.0 API */ + const char *str_name = EVP_PKEY_get0_type_name(pkey); + if (strcmp(str_name, "ML-DSA-44") == 0 || + strcmp(str_name, "ML-DSA-65") == 0 || + strcmp(str_name, "ML-DSA-87") == 0) { + *type = CKK_ML_DSA; + return CKR_OK; + } else if (strcmp(str_name, "ML-KEM-512") == 0 || + strcmp(str_name, "ML-KEM-768") == 0 || + strcmp(str_name, "ML-KEM-1024") == 0) { + *type = CKK_ML_KEM; + return CKR_OK; + } else if (strcmp(str_name, "SLH-DSA-SHA2-128f") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-128s") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-192f") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-192s") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-256f") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-256s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { + *type = CKK_SLH_DSA; + return CKR_OK; + } + #endif + err: /* unsupported by OpenSSL, PKCS11 or this program */ + printf(" ERR: Key type %d not supported\n", *pk_type); *type = CKK_OPENSC_UNDEFINED; *pk_type = -1; return CKR_FUNCTION_NOT_SUPPORTED; @@ -5265,8 +5358,9 @@ static CK_RV write_object(CK_SESSION_HANDLE session) return rv; n_privkey_attr++; } else if (type == CKK_ML_DSA || type == CKK_SLH_DSA || type == CKK_ML_KEM) { - /* TODO Set the right parameter set! */ + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); n_privkey_attr++; if (pqc_key.private.value != NULL) { @@ -5349,7 +5443,9 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len); n_pubkey_attr++; - } else if (type == CKK_ML_DSA) { + } else if (type == CKK_ML_DSA || type == CKK_SLH_DSA || type == CKK_ML_KEM) { + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, &pqc_key.public.value, pqc_key.public.len); @@ -6723,6 +6819,14 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("%sderive", sepa); sepa = ", "; } + if (getENCAPSULATE(sess, obj)) { + printf("%sencapsulate", sepa); + sepa = ", "; + } + if (getDECAPSULATE(sess, obj)) { + printf("%sdecapsulate", sepa); + sepa = ", "; + } if (!*sepa) printf("none"); printf("\n"); @@ -7434,7 +7538,120 @@ static int read_object(CK_SESSION_HANDLE session) EVP_PKEY_free(key); } else if (type == CKK_ML_DSA || type == CKK_ML_KEM || type == CKK_SLH_DSA) { - // TODO + unsigned long parameter_set = getPARAMETER_SET(session, obj); + const char *evp_name = NULL; + unsigned char *value = NULL; + size_t value_len = 0; + + switch (type) { + case CKK_ML_DSA: + switch (parameter_set) { + case CKP_ML_DSA_44: + evp_name = "ML-DSA-44"; + break; + case CKP_ML_DSA_65: + evp_name = "ML-DSA-65"; + break; + case CKP_ML_DSA_87: + evp_name = "ML-DSA-87"; + break; + default: + util_fatal("Unknown parameter set (%lu)", + parameter_set); + } + break; + case CKK_ML_KEM: + switch (parameter_set) { + case CKP_ML_KEM_512: + evp_name = "ML-KEM-512"; + break; + case CKP_ML_KEM_768: + evp_name = "ML-KEM-768"; + break; + case CKP_ML_KEM_1024: + evp_name = "ML-KEM-1024"; + break; + default: + util_fatal("Unknown parameter set (%lu)", + parameter_set); + } + break; + case CKK_SLH_DSA: + switch (parameter_set) { + case CKP_SLH_DSA_SHA2_128S: + evp_name = "SLH-DSA-SHA2-128s"; + break; + case CKP_SLH_DSA_SHAKE_128S: + evp_name = "SLH-DSA-SHAKE-128s"; + break; + case CKP_SLH_DSA_SHA2_128F: + evp_name = "SLH-DSA-SHA2-128f"; + break; + case CKP_SLH_DSA_SHAKE_128F: + evp_name = "SLH-DSA-SHAKE-128f"; + break; + case CKP_SLH_DSA_SHA2_192S: + evp_name = "SLH-DSA-SHA2-192s"; + break; + case CKP_SLH_DSA_SHAKE_192S: + evp_name = "SLH-DSA-SHAKE-192s"; + break; + case CKP_SLH_DSA_SHA2_192F: + evp_name = "SLH-DSA-SHA2-192f"; + break; + case CKP_SLH_DSA_SHAKE_192F: + evp_name = "SLH-DSA-SHAKE-192f"; + break; + case CKP_SLH_DSA_SHA2_256S: + evp_name = "SLH-DSA-SHA2-256s"; + break; + case CKP_SLH_DSA_SHAKE_256S: + evp_name = "SLH-DSA-SHAKE-256s"; + break; + case CKP_SLH_DSA_SHA2_256F: + evp_name = "SLH-DSA-SHA2-256f"; + break; + case CKP_SLH_DSA_SHAKE_256F: + evp_name = "SLH-DSA-SHAKE-256f"; + break; + default: + util_fatal("Unknown parameter set (%lu)", + parameter_set); + } + break; + default: + util_fatal("Unknown key type (%lu)", type); + return -1; + } + + /* Public key value */ + value = getVALUE(session, obj, &value_len); + if (value == NULL) { + util_fatal("get CKA_VALUE failed"); + } + + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, evp_name, NULL)) || + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", value, value_len) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_BLD_free(bld); + util_fatal("Unable to set key params"); + } + OSSL_PARAM_BLD_free(bld); + if (EVP_PKEY_fromdata_init(ctx) != 1 || + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + util_fatal("Unable to build key"); + } + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + + if (i2d_PUBKEY_bio(pout, pkey) < 1) { + util_fatal("cannot write public key to output"); + } + EVP_PKEY_free(pkey); #endif } else util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); diff --git a/tests/common.sh b/tests/common.sh index b0d56e25ff..dd98f4c5f7 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -55,10 +55,8 @@ function generate_key() { # convert it to more digestible PEM format if [[ ${TYPE:0:3} == "RSA" ]]; then openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub - elif [[ $TYPE == "EC:edwards25519" ]]; then - openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub else - openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + openssl pkey -inform DER -outform PEM -in $ID.der -pubin > $ID.pub fi rm $ID.der } diff --git a/tests/init-kryoptic.sh b/tests/init-kryoptic.sh index 1a0b5d6bd9..ea25b30ff2 100755 --- a/tests/init-kryoptic.sh +++ b/tests/init-kryoptic.sh @@ -18,13 +18,13 @@ if [[ -z "$P11LIB" ]]; then fi function initialize_token() { - TMPPDIR="$BUILD_PATH/kryoptic/tmp" - export TOKDIR="$TMPPDIR/tokens" + TMPPDIR="kryoptic.tmp" + mkdir -p "$TMPPDIR" + export TOKDIR=$(realpath $TMPPDIR/tokens) if [ -d "${TMPPDIR}" ]; then rm -fr "${TMPPDIR}" fi - mkdir -p "${TMPPDIR}" - mkdir "${TOKDIR}" + mkdir -p "${TOKDIR}" export KRYOPTIC_CONF="${KRYOPTIC_CONF:-$TOKDIR/kryoptic.sql}" export TOKENCONFIGVARS="export KRYOPTIC_CONF=$TOKDIR/kryoptic.sql" @@ -37,6 +37,8 @@ function initialize_token() { $PKCS11_TOOL --module "${P11LIB}" --so-pin "${PIN}" \ --login --login-type so --init-pin --pin "${PIN}" + #export PKCS11SPY=$P11LIB + #export P11LIB="../src/pkcs11/.libs/pkcs11-spy.so" export PUB_ARGS=("--module=${P11LIB}" "--token-label=${TOKENLABEL}") export PRIV_ARGS=("${PUB_ARGS[@]}" "--login" "--pin=${PIN}") export PRIV_ARGS_KRYOPTIC=("${PRIV_ARGS[@]}") diff --git a/tests/kryoptic_ref.json b/tests/kryoptic_ref.json index b8acf82715..3325acdd1c 100644 --- a/tests/kryoptic_ref.json +++ b/tests/kryoptic_ref.json @@ -16,72 +16,72 @@ ], [ "RSA_PKCS_KEY_PAIR_GEN", - "2048", + "1024", "16384", "CKF_GENERATE_KEY_PAIR" ], [ "RSA_PKCS", - "2048", + "1024", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" ], [ "RSA_X_509", - "2048", + "1024", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" ], [ "SHA1_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "RSA_PKCS_OAEP", - "2048", + "1024", "16384", "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" ], [ "RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA1_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000000F", + "ML_KEM_KEY_PAIR_GEN", "800", "1568", "CKF_GENERATE_KEY_PAIR" ], [ - "0x00000017", + "ML_KEM", "800", "1568", - "" + "CKF_ENCAPSULATE,CKF_DECAPSULATE" ], [ - "0x0000001C", + "ML_DSA_KEY_PAIR_GEN", "1312", "2592", "CKF_GENERATE_KEY_PAIR" ], [ - "0x0000001D", + "ML_DSA", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000001F", + "HASH_ML_DSA", "1312", "2592", "CKF_SIGN,CKF_VERIFY" @@ -99,164 +99,164 @@ "CKF_DERIVE" ], [ - "0x00000023", + "HASH_ML_DSA_SHA224", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000024", + "HASH_ML_DSA_SHA256", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000025", + "HASH_ML_DSA_SHA384", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000026", + "HASH_ML_DSA_SHA3_512", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000027", + "HASH_ML_DSA_SHA3_224", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000028", + "HASH_ML_DSA_SHA3_256", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000029", + "HASH_ML_DSA_SHA3_384", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000002A", + "HASH_ML_DSA_SHA3_512", "1312", "2592", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000002D", + "SLH_DSA_KEY_PAIR_GEN", "32", "64", "CKF_GENERATE_KEY_PAIR" ], [ - "0x0000002E", + "SLH_DSA", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000034", + "HASH_SLH_DSA", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000036", + "HASH_SLH_DSA_SHA224", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000037", + "HASH_SLH_DSA_SHA256", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000038", + "HASH_SLH_DSA_SHA384", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x00000039", + "HASH_SLH_DSA_SHA3_512", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000003A", + "HASH_SLH_DSA_SHA3_224", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000003B", + "HASH_SLH_DSA_SHA3_256", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000003C", + "HASH_SLH_DSA_SHA3_384", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ - "0x0000003D", + "HASH_SLH_DSA_SHA3_512", "32", "64", "CKF_SIGN,CKF_VERIFY" ], [ "SHA256_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA256_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], @@ -322,49 +322,49 @@ ], [ "SHA3_256_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_384_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_512_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_256_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_384_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_512_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_224_RSA_PKCS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], [ "SHA3_224_RSA_PKCS_PSS", - "2048", + "1024", "16384", "CKF_SIGN,CKF_VERIFY" ], @@ -818,6 +818,18 @@ "32", "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" ], + [ + "AES_MAC", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_MAC_GENERAL", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], [ "AES_CBC_PAD", "16", @@ -872,6 +884,30 @@ "32", "CKF_DERIVE" ], + [ + "AES_OFB", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CFB8", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CFB128", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00002108", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], [ "AES_KEY_WRAP", "16", @@ -944,12 +980,6 @@ "0", "CKF_GENERATE" ], - [ - "0x0000403A", - "0", - "0", - "CKF_DERIVE" - ], [ "0x8007678C", "0", @@ -975,13 +1005,13 @@ "01", "RSA_PKCS", "YES", - "" + "YES" ], [ "01", "RSA_X_509", "YES", - "" + "YES" ], [ "01", @@ -1035,13 +1065,13 @@ "02", "RSA_PKCS", "YES", - "" + "YES" ], [ "02", "RSA_X_509", "YES", - "" + "YES" ], [ "02", @@ -1186,6 +1216,138 @@ "ECDSA_SHA3_512", "YES", "" + ], + [ + "06", + "ML_DSA", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA224", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA256", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA384", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA3_512", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA3_224", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA3_256", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA3_384", + "YES", + "" + ], + [ + "06", + "HASH_ML_DSA_SHA3_512", + "YES", + "" + ], + [ + "08", + "SLH_DSA", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA224", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA256", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA384", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA3_512", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA3_224", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA3_256", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA3_384", + "YES", + "" + ], + [ + "08", + "HASH_SLH_DSA_SHA3_512", + "YES", + "" + ], + [ + "09", + "EDDSA", + "YES", + "" + ], + [ + "10", + "EDDSA", + "YES", + "" ]], "result": "pass" }, @@ -1298,6 +1460,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -1316,6 +1480,8 @@ "", "", "", + "", + "", "" ], [ @@ -1332,6 +1498,8 @@ "", "", "", + "", + "", "" ], [ @@ -1346,6 +1514,8 @@ "", "", "", + "", + "", "YES", "YES", "" @@ -1362,6 +1532,8 @@ "", "", "", + "", + "", "YES", "YES", "" @@ -1380,6 +1552,134 @@ "", "", "", + "", + "", + "" + ], + [ + "06", + "ML-DSA-65", + "ML-DSA", + "15616", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + [ + "07", + "ML-KEM-768", + "ML-KEM", + "0", + "", + "", + "", + "", + "", + "", + "", + "YES", + "YES", + "", + "", + "" + ], + [ + "08", + "SLH-DSA-SHA2-192S", + "SLH-DSA", + "384", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + [ + "09", + "ed25519", + "EDDSA", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "YES", + "YES", + "" + ], + [ + "10", + "ed448", + "EDDSA", + "456", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "YES", + "YES", + "" + ], + [ + "11", + "x25519", + "XEDDSA", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "YES", + "YES", + "" + ], + [ + "12", + "x448", + "XEDDSA", + "448", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "YES", + "YES", "" ]], "result": "pass" @@ -2125,6 +2425,33 @@ "", "YES" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -2341,6 +2668,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -2557,6 +2911,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -2773,6 +3154,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -2957,7 +3365,34 @@ "01", "RSA_PKCS_PSS", "SHA512", - "MGF1_SHA3_384", + "MGF1_SHA3_384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA3_512", "0", "YES", "" @@ -2965,8 +3400,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", + "SHA3_224", + "MGF1_SHA_1", "-2", "YES", "" @@ -2974,8 +3409,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", + "SHA3_224", + "MGF1_SHA_1", "-1", "YES", "" @@ -2983,8 +3418,8 @@ [ "01", "RSA_PKCS_PSS", - "SHA512", - "MGF1_SHA3_512", + "SHA3_224", + "MGF1_SHA_1", "0", "YES", "" @@ -3205,6 +3640,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -3421,6 +3883,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -3637,6 +4126,33 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -3853,6 +4369,33 @@ "YES", "" ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA256_RSA_PKCS_PSS", @@ -4069,6 +4612,33 @@ "YES", "" ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA384_RSA_PKCS_PSS", @@ -4285,6 +4855,33 @@ "YES", "" ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA512_RSA_PKCS_PSS", @@ -4501,6 +5098,33 @@ "YES", "" ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA224_RSA_PKCS_PSS", @@ -4717,6 +5341,33 @@ "YES", "" ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA3_256_RSA_PKCS_PSS", @@ -4917,18 +5568,45 @@ ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA3_512", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", "-1", "YES", "" ], [ "01", - "SHA3_256_RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA3_512", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", "0", "YES", "" @@ -5149,6 +5827,33 @@ "YES", "" ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA3_512_RSA_PKCS_PSS", @@ -5365,6 +6070,33 @@ "YES", "" ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "01", "SHA3_224_RSA_PKCS_PSS", @@ -6310,6 +7042,33 @@ "", "YES" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -6526,6 +7285,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -6742,6 +7528,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -6958,6 +7771,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -7174,6 +8014,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -7390,6 +8257,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -7600,8 +8494,35 @@ [ "02", "RSA_PKCS_PSS", - "SHA3_256", - "MGF1_SHA3_512", + "SHA3_256", + "MGF1_SHA3_512", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", "0", "YES", "" @@ -7822,6 +8743,33 @@ "YES", "" ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "RSA_PKCS_PSS", @@ -8038,6 +8986,33 @@ "YES", "" ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA256_RSA_PKCS_PSS", @@ -8254,6 +9229,33 @@ "YES", "" ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA384_RSA_PKCS_PSS", @@ -8470,6 +9472,33 @@ "YES", "" ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA512_RSA_PKCS_PSS", @@ -8686,6 +9715,33 @@ "YES", "" ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA224_RSA_PKCS_PSS", @@ -8902,6 +9958,33 @@ "YES", "" ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_256_RSA_PKCS_PSS", + "SHA3_256", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA3_256_RSA_PKCS_PSS", @@ -9118,6 +10201,33 @@ "YES", "" ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_384_RSA_PKCS_PSS", + "SHA3_384", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA3_384_RSA_PKCS_PSS", @@ -9334,6 +10444,33 @@ "YES", "" ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_512_RSA_PKCS_PSS", + "SHA3_512", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA3_512_RSA_PKCS_PSS", @@ -9550,6 +10687,33 @@ "YES", "" ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA3_224_RSA_PKCS_PSS", + "SHA3_224", + "MGF1_SHA_1", + "0", + "YES", + "" + ], [ "02", "SHA3_224_RSA_PKCS_PSS", @@ -9795,6 +10959,16 @@ "04", "ECDH1_COFACTOR_DERIVE", "YES" + ], + [ + "11", + "ECDH1_DERIVE", + "YES" + ], + [ + "12", + "ECDH1_DERIVE", + "YES" ]], "result": "pass" }, diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index 530dacdbcb..915608f384 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 @@ -21,29 +21,57 @@ card_setup assert $? "Failed to set up card" # To add Ed25519 will require OpenSSL 3.2 and use of genpkey -outpubkey -# which will also work for other keys, and will not require openssl pkey +# which will also work for other keys, and will not require openssl pkey -for KEYTYPE in "RSA" "EC"; do +KEYTYPES=("RSA" "EC") +if [[ "$TOKENTYPE" == "kryoptic" ]]; then + KEYTYPES+=("ML-DSA-87" "ML-KEM-512" "SLH-DSA-SHA2-256F" "Ed25519" "Ed448") +fi + +for KEYTYPE in ${KEYTYPES[@]}; do echo "=======================================================" echo "Generate and import $KEYTYPE keys" echo "=======================================================" ID="0100" OPTS="-pkeyopt rsa_keygen_bits:2048" + PKCS11_OPTS="--usage-sign --usage-decrypt" if [ "$KEYTYPE" == "EC" ]; then ID="0200" OPTS="-pkeyopt ec_paramgen_curve:P-256" + PKCS11_OPTS="--usage-sign" + elif [ "$KEYTYPE" == "ML-DSA-87" ]; then + ID="0300" + OPTS="" + PKCS11_OPTS="--usage-sign" + elif [ "$KEYTYPE" == "ML-KEM-512" ]; then + ID="0400" + OPTS="" + PKCS11_OPTS="--usage-encapsulate" + elif [ "$KEYTYPE" == "SLH-DSA-SHA2-256F" ]; then + ID="0500" + OPTS="" + PKCS11_OPTS="--usage-sign" + elif [ "$KEYTYPE" == "Ed25519" ]; then + ID="0600" + OPTS="" + PKCS11_OPTS="--usage-sign" + elif [ "$KEYTYPE" == "Ed448" ]; then + ID="0700" + OPTS="" + PKCS11_OPTS="--usage-sign" fi openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS assert $? "Failed to generate private $KEYTYPE key" $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object "${KEYTYPE}_private.der" --id "$ID" \ - --type privkey --label "$KEYTYPE" + --type privkey --label "$KEYTYPE" $PKCS11_OPTS assert $? "Failed to write private $KEYTYPE key" echo "Private key written" openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER assert $? "Failed to convert private $KEYTYPE key to public" - $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" + $PKCS11_TOOL "${PRIV_ARGS[@]}" --write-object "${KEYTYPE}_public.der" --id "$ID" \ + --type pubkey --label "$KEYTYPE" $PKCS11_OPTS assert $? "Failed to write public $KEYTYPE key" echo "Public key written" From 3a18fc2eebc506568375c73074c62ae6bd347215 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 09:26:44 +0100 Subject: [PATCH 4032/4321] Update softhsm reference files to match new format --- tests/softhsm_fips_ref.json | 12 ++++++++++++ tests/softhsm_ref.json | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/softhsm_fips_ref.json b/tests/softhsm_fips_ref.json index c2bbb1e231..96b9a0fa92 100644 --- a/tests/softhsm_fips_ref.json +++ b/tests/softhsm_fips_ref.json @@ -590,6 +590,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -608,6 +610,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -624,6 +628,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -638,6 +644,8 @@ "YES", "YES", "YES", + "", + "", "YES", "YES", "" @@ -654,6 +662,8 @@ "YES", "YES", "YES", + "", + "", "YES", "YES", "" @@ -672,6 +682,8 @@ "YES", "", "", + "", + "", "" ]], "result": "pass" diff --git a/tests/softhsm_ref.json b/tests/softhsm_ref.json index 03e7d20612..f6d39f58c5 100644 --- a/tests/softhsm_ref.json +++ b/tests/softhsm_ref.json @@ -636,6 +636,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -654,6 +656,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -670,6 +674,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -684,6 +690,8 @@ "YES", "YES", "YES", + "", + "", "YES", "YES", "" @@ -700,6 +708,8 @@ "YES", "YES", "YES", + "", + "", "YES", "YES", "" @@ -718,6 +728,8 @@ "YES", "", "", + "", + "", "" ]], "result": "pass" From 8626435f340720d6240ea563019f954b1fc2aacf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 10:09:17 +0100 Subject: [PATCH 4033/4321] Exclude PQC keys in libressl and fix formatting --- src/common/libpkcs11.c | 2 +- src/pkcs11/debug.c | 220 ++++++++++----------- src/pkcs11/pkcs11-display.c | 46 ++--- src/pkcs11/pkcs11-display.h | 2 +- src/pkcs11/pkcs11-spy.c | 6 +- src/tests/p11test/p11test_case_common.c | 93 +++++---- src/tests/p11test/p11test_case_ec_derive.c | 23 +-- src/tests/p11test/p11test_case_interface.c | 10 +- src/tests/p11test/p11test_case_mechs.c | 8 +- src/tests/p11test/p11test_case_readonly.c | 65 +++--- src/tests/p11test/p11test_case_usage.c | 52 ++--- src/tools/pkcs11-tool.c | 100 +++++----- 12 files changed, 325 insertions(+), 302 deletions(-) diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index cc1fa22403..5ad0dd3e56 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -72,7 +72,7 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) CK_INTERFACE *interface = NULL; /* Get default PKCS #11 interface */ - rv = c_get_interface((CK_UTF8CHAR_PTR)"PKCS 11", NULL, &interface, 0); + rv = c_get_interface((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 0); if (rv == CKR_OK) { /* this is actually 3.0 function list, but it starts * with the same fields. Only for new functions, it diff --git a/src/pkcs11/debug.c b/src/pkcs11/debug.c index facd5bdb2b..a618bd28c6 100644 --- a/src/pkcs11/debug.c +++ b/src/pkcs11/debug.c @@ -54,123 +54,123 @@ static const char * sc_pkcs11_print_bool(int level, struct fmap *, static const char * sc_pkcs11_print_string(int level, struct fmap *, void *, size_t); -static struct fmap map_CKA_CLASS[] = { - _(CKO_DATA), - _(CKO_CERTIFICATE), - _(CKO_PUBLIC_KEY), - _(CKO_PRIVATE_KEY), - _(CKO_SECRET_KEY), - _(CKO_HW_FEATURE), - _(CKO_DOMAIN_PARAMETERS), - _(CKO_PROFILE), - _(CKO_VALIDATION), - _(CKO_TRUST), - - { 0, NULL, NULL, NULL } +static struct fmap map_CKA_CLASS[] = { + _(CKO_DATA), + _(CKO_CERTIFICATE), + _(CKO_PUBLIC_KEY), + _(CKO_PRIVATE_KEY), + _(CKO_SECRET_KEY), + _(CKO_HW_FEATURE), + _(CKO_DOMAIN_PARAMETERS), + _(CKO_PROFILE), + _(CKO_VALIDATION), + _(CKO_TRUST), + + {0, NULL, NULL, NULL} }; -static struct fmap map_CKA_CERTIFICATE_TYPE[] = { - _(CKC_X_509), - _(CKC_X_509_ATTR_CERT), +static struct fmap map_CKA_CERTIFICATE_TYPE[] = { + _(CKC_X_509), + _(CKC_X_509_ATTR_CERT), - { 0, NULL, NULL, NULL } + {0, NULL, NULL, NULL} }; -static struct fmap map_CKA_KEY_TYPE[] = { - _(CKK_RSA), - _(CKK_DSA), - _(CKK_DH), - _(CKK_ECDSA), - _(CKK_EC), - _(CKK_EC_EDWARDS), - _(CKK_EC_MONTGOMERY), - _(CKK_GENERIC_SECRET), - _(CKK_RC2), - _(CKK_RC4), - _(CKK_RC5), - _(CKK_DES), - _(CKK_DES3), - _(CKK_CAST), - _(CKK_CAST3), - _(CKK_CAST128), - _(CKK_IDEA), - _(CKK_AES), - _(CKK_ML_DSA), - _(CKK_ML_KEM), - _(CKK_SLH_DSA), - - { 0, NULL, NULL, NULL } +static struct fmap map_CKA_KEY_TYPE[] = { + _(CKK_RSA), + _(CKK_DSA), + _(CKK_DH), + _(CKK_ECDSA), + _(CKK_EC), + _(CKK_EC_EDWARDS), + _(CKK_EC_MONTGOMERY), + _(CKK_GENERIC_SECRET), + _(CKK_RC2), + _(CKK_RC4), + _(CKK_RC5), + _(CKK_DES), + _(CKK_DES3), + _(CKK_CAST), + _(CKK_CAST3), + _(CKK_CAST128), + _(CKK_IDEA), + _(CKK_AES), + _(CKK_ML_DSA), + _(CKK_ML_KEM), + _(CKK_SLH_DSA), + + {0, NULL, NULL, NULL} }; -static struct fmap p11_attr_names[] = { - ulm(CKA_CLASS), - b(CKA_TOKEN), - b(CKA_PRIVATE), - s(CKA_LABEL), - _(CKA_APPLICATION), - _(CKA_VALUE), - _(CKA_OBJECT_ID), - ulm(CKA_CERTIFICATE_TYPE), - _(CKA_ISSUER), - _(CKA_SERIAL_NUMBER), - _(CKA_AC_ISSUER), - _(CKA_OWNER), - _(CKA_ATTR_TYPES), - b(CKA_TRUSTED), - ulm(CKA_KEY_TYPE), - _(CKA_SUBJECT), - _(CKA_ID), - b(CKA_SENSITIVE), - b(CKA_ENCRYPT), - b(CKA_DECRYPT), - b(CKA_WRAP), - b(CKA_UNWRAP), - b(CKA_SIGN), - b(CKA_SIGN_RECOVER), - b(CKA_VERIFY), - b(CKA_VERIFY_RECOVER), - b(CKA_DERIVE), - _(CKA_START_DATE), - _(CKA_END_DATE), - _(CKA_MODULUS), - ul(CKA_MODULUS_BITS), - _(CKA_PUBLIC_EXPONENT), - _(CKA_PRIVATE_EXPONENT), - _(CKA_PRIME_1), - _(CKA_PRIME_2), - _(CKA_EXPONENT_1), - _(CKA_EXPONENT_2), - _(CKA_COEFFICIENT), - _(CKA_PRIME), - _(CKA_SUBPRIME), - _(CKA_BASE), - _(CKA_PRIME_BITS), - _(CKA_SUB_PRIME_BITS), - _(CKA_VALUE_BITS), - _(CKA_VALUE_LEN), - b(CKA_EXTRACTABLE), - b(CKA_LOCAL), - b(CKA_NEVER_EXTRACTABLE), - b(CKA_ALWAYS_SENSITIVE), - _(CKA_KEY_GEN_MECHANISM), - b(CKA_MODIFIABLE), - _(CKA_EC_PARAMS), - _(CKA_ECDSA_PARAMS), - _(CKA_EC_POINT), - _(CKA_SECONDARY_AUTH), - ul(CKA_AUTH_PIN_FLAGS), - _(CKA_HW_FEATURE_TYPE), - _(CKA_RESET_ON_INIT), - _(CKA_HAS_RESET), - _(CKA_VENDOR_DEFINED), - b(CKA_ALWAYS_AUTHENTICATE), - _(CKA_GOSTR3410_PARAMS), - ul(CKA_PARAMETER_SET), - b(CKA_ENCAPSULATE), - b(CKA_DECAPSULATE), - _(CKA_SEED), - - { 0, NULL, NULL, NULL } +static struct fmap p11_attr_names[] = { + ulm(CKA_CLASS), + b(CKA_TOKEN), + b(CKA_PRIVATE), + s(CKA_LABEL), + _(CKA_APPLICATION), + _(CKA_VALUE), + _(CKA_OBJECT_ID), + ulm(CKA_CERTIFICATE_TYPE), + _(CKA_ISSUER), + _(CKA_SERIAL_NUMBER), + _(CKA_AC_ISSUER), + _(CKA_OWNER), + _(CKA_ATTR_TYPES), + b(CKA_TRUSTED), + ulm(CKA_KEY_TYPE), + _(CKA_SUBJECT), + _(CKA_ID), + b(CKA_SENSITIVE), + b(CKA_ENCRYPT), + b(CKA_DECRYPT), + b(CKA_WRAP), + b(CKA_UNWRAP), + b(CKA_SIGN), + b(CKA_SIGN_RECOVER), + b(CKA_VERIFY), + b(CKA_VERIFY_RECOVER), + b(CKA_DERIVE), + _(CKA_START_DATE), + _(CKA_END_DATE), + _(CKA_MODULUS), + ul(CKA_MODULUS_BITS), + _(CKA_PUBLIC_EXPONENT), + _(CKA_PRIVATE_EXPONENT), + _(CKA_PRIME_1), + _(CKA_PRIME_2), + _(CKA_EXPONENT_1), + _(CKA_EXPONENT_2), + _(CKA_COEFFICIENT), + _(CKA_PRIME), + _(CKA_SUBPRIME), + _(CKA_BASE), + _(CKA_PRIME_BITS), + _(CKA_SUB_PRIME_BITS), + _(CKA_VALUE_BITS), + _(CKA_VALUE_LEN), + b(CKA_EXTRACTABLE), + b(CKA_LOCAL), + b(CKA_NEVER_EXTRACTABLE), + b(CKA_ALWAYS_SENSITIVE), + _(CKA_KEY_GEN_MECHANISM), + b(CKA_MODIFIABLE), + _(CKA_EC_PARAMS), + _(CKA_ECDSA_PARAMS), + _(CKA_EC_POINT), + _(CKA_SECONDARY_AUTH), + ul(CKA_AUTH_PIN_FLAGS), + _(CKA_HW_FEATURE_TYPE), + _(CKA_RESET_ON_INIT), + _(CKA_HAS_RESET), + _(CKA_VENDOR_DEFINED), + b(CKA_ALWAYS_AUTHENTICATE), + _(CKA_GOSTR3410_PARAMS), + ul(CKA_PARAMETER_SET), + b(CKA_ENCAPSULATE), + b(CKA_DECAPSULATE), + _(CKA_SEED), + + {0, NULL, NULL, NULL} }; void sc_pkcs11_print_attrs(int level, const char *file, unsigned int line, diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 994d64f78b..f488c3f763 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -108,7 +108,6 @@ buf_spec(CK_VOID_PTR buf_addr, CK_ULONG buf_len) return ret; } - void print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { @@ -125,7 +124,6 @@ print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR fprintf(f, "Value %lX not found for type %s\n", ctype, spec->name); } - void print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { @@ -133,7 +131,6 @@ print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P fprintf(f, i ? "True\n" : "False\n"); } - void print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { @@ -185,7 +182,6 @@ print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P fprintf(f, "\n"); } - #ifdef ENABLE_OPENSSL static void print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) @@ -209,30 +205,30 @@ print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR ar #endif static enum_specs ck_mldsa_s[] = { - { CKP_ML_DSA_44, "CKP_ML_DSA_44" }, - { CKP_ML_DSA_65, "CKP_ML_DSA_65" }, - { CKP_ML_DSA_87, "CKP_ML_DSA_87" }, + {CKP_ML_DSA_44, "CKP_ML_DSA_44"}, + {CKP_ML_DSA_65, "CKP_ML_DSA_65"}, + {CKP_ML_DSA_87, "CKP_ML_DSA_87"}, }; static enum_specs ck_mlkem_s[] = { - { CKP_ML_KEM_512, "CKP_ML_KEM_512" }, - { CKP_ML_KEM_768, "CKP_ML_KEM_768" }, - { CKP_ML_KEM_1024, "CKP_ML_KEM_1024" }, + {CKP_ML_KEM_512, "CKP_ML_KEM_512"}, + {CKP_ML_KEM_768, "CKP_ML_KEM_768"}, + {CKP_ML_KEM_1024, "CKP_ML_KEM_1024"}, }; static enum_specs ck_slh_dsa_s[] = { - { CKP_SLH_DSA_SHA2_128S, "CKP_SLH_DSA_SHA2_128S" }, - { CKP_SLH_DSA_SHAKE_128S, "CKP_SLH_DSA_SHAKE_128S" }, - { CKP_SLH_DSA_SHA2_128F, "CKP_SLH_DSA_SHA2_128F" }, - { CKP_SLH_DSA_SHAKE_128F, "CKP_SLH_DSA_SHAKE_128F" }, - { CKP_SLH_DSA_SHA2_192S, "CKP_SLH_DSA_SHA2_192S" }, - { CKP_SLH_DSA_SHAKE_192S, "CKP_SLH_DSA_SHAKE_192S" }, - { CKP_SLH_DSA_SHA2_192F, "CKP_SLH_DSA_SHA2_192F" }, - { CKP_SLH_DSA_SHAKE_192F, "CKP_SLH_DSA_SHAKE_192F" }, - { CKP_SLH_DSA_SHA2_256S, "CKP_SLH_DSA_SHA2_256S" }, - { CKP_SLH_DSA_SHAKE_256S, "CKP_SLH_DSA_SHAKE_256S" }, - { CKP_SLH_DSA_SHA2_256F, "CKP_SLH_DSA_SHA2_256F" }, - { CKP_SLH_DSA_SHAKE_256F, "CKP_SLH_DSA_SHAKE_256F" }, + {CKP_SLH_DSA_SHA2_128S, "CKP_SLH_DSA_SHA2_128S"}, + {CKP_SLH_DSA_SHAKE_128S, "CKP_SLH_DSA_SHAKE_128S"}, + {CKP_SLH_DSA_SHA2_128F, "CKP_SLH_DSA_SHA2_128F"}, + {CKP_SLH_DSA_SHAKE_128F, "CKP_SLH_DSA_SHAKE_128F"}, + {CKP_SLH_DSA_SHA2_192S, "CKP_SLH_DSA_SHA2_192S"}, + {CKP_SLH_DSA_SHAKE_192S, "CKP_SLH_DSA_SHAKE_192S"}, + {CKP_SLH_DSA_SHA2_192F, "CKP_SLH_DSA_SHA2_192F"}, + {CKP_SLH_DSA_SHAKE_192F, "CKP_SLH_DSA_SHAKE_192F"}, + {CKP_SLH_DSA_SHA2_256S, "CKP_SLH_DSA_SHA2_256S"}, + {CKP_SLH_DSA_SHAKE_256S, "CKP_SLH_DSA_SHAKE_256S"}, + {CKP_SLH_DSA_SHA2_256F, "CKP_SLH_DSA_SHA2_256F"}, + {CKP_SLH_DSA_SHAKE_256F, "CKP_SLH_DSA_SHAKE_256F"}, }; #define SZ_SPECS sizeof(enum_specs) @@ -1497,7 +1493,7 @@ print_mech_info(FILE *f, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR minfo) CKF_FIND_OBJECTS | CKF_ENCRYPT | CKF_DECRYPT | CKF_DIGEST | CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | CKF_WRAP | CKF_UNWRAP | - CKF_DERIVE | CKF_EC_F_P | CKF_EC_F_2M |CKF_EC_ECPARAMETERS | + CKF_DERIVE | CKF_EC_F_P | CKF_EC_F_2M | CKF_EC_ECPARAMETERS | CKF_EC_OID | CKF_EC_UNCOMPRESS | CKF_EC_CURVENAME | CKF_EC_NAMEDCURVE | CKF_ENCAPSULATE | CKF_DECAPSULATE; @@ -1554,7 +1550,7 @@ print_attribute_list(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) /* Some attributes are key type specific -- first check if we have a key type * in the template and if so, store it */ - for (j = 0; j < ulCount ; j++) { + for (j = 0; j < ulCount; j++) { if (pTemplate[j].type == CKA_KEY_TYPE && pTemplate[j].pValue) { key_type = *(CK_KEY_TYPE *)pTemplate[j].pValue; break; @@ -1622,7 +1618,7 @@ print_session_info(FILE *f, CK_SESSION_INFO *info) enum_specs ck_flags[] = { {CKF_RW_SESSION , "CKF_RW_SESSION "}, {CKF_SERIAL_SESSION , "CKF_SERIAL_SESSION "}, - {CKF_ASYNC_SESSION , "CKF_ASYNC_SESSION "} + {CKF_ASYNC_SESSION , "CKF_ASYNC_SESSION "}, }; fprintf(f, " slotID: %ld\n", info->slotID ); diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 02b4113316..d728c3d554 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -29,7 +29,7 @@ extern "C" { #endif -typedef void (display_func) (FILE *, CK_LONG, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR, CK_KEY_TYPE); +typedef void(display_func) (FILE *, CK_LONG, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR, CK_KEY_TYPE); typedef struct { CK_ULONG type; diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index bdf3e78bc0..2dbfaee005 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -212,7 +212,7 @@ CK_INTERFACE compat_interfaces[NUM_INTERFACES] = { {(CK_UTF8CHAR_PTR) "PKCS 11", NULL, 0} }; -CK_INTERFACE spy_interface = {(CK_UTF8CHAR_PTR)"PKCS 11", NULL, 0}; +CK_INTERFACE spy_interface = {(CK_UTF8CHAR_PTR) "PKCS 11", NULL, 0}; /* Inits the spy. If successful, po != NULL */ static CK_RV @@ -337,7 +337,7 @@ init_spy(void) return CKR_DEVICE_ERROR; } modhandle = C_LoadModule(module, &po_v2); - po = (CK_FUNCTION_LIST_3_2_PTR) po_v2; + po = (CK_FUNCTION_LIST_3_2_PTR)po_v2; if (modhandle && po) { fprintf(spy_output, "Loaded: \"%s\"\n", module); } @@ -2253,8 +2253,6 @@ C_EncapsulateKey(CK_SESSION_HANDLE hSession, return retne(rv); } - - CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index b183d9cbce..588ee98ac4 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -142,7 +142,7 @@ add_supported_mechs(test_cert_t *o) switch (o->type) { case EVP_PKEY_RSA: - if (token.num_rsa_mechs > 0 ) { + if (token.num_rsa_mechs > 0) { /* Get supported mechanisms by token */ o->num_mechs = 0; for (i = 0; i < token.num_rsa_mechs; i++) { @@ -172,7 +172,7 @@ add_supported_mechs(test_cert_t *o) } break; case EVP_PKEY_EC: - if (token.num_ec_mechs > 0 ) { + if (token.num_ec_mechs > 0) { o->num_mechs = token.num_ec_mechs; for (i = 0; i < token.num_ec_mechs; i++) { o->mechs[i].mech = token.ec_mechs[i].mech; @@ -194,8 +194,12 @@ add_supported_mechs(test_cert_t *o) break; #ifdef EVP_PKEY_ED25519 case EVP_PKEY_ED25519: +#endif +#ifdef EVP_PKEY_ED448 case EVP_PKEY_ED448: - if (token.num_ed_mechs > 0 ) { +#endif +#if defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) + if (token.num_ed_mechs > 0) { o->num_mechs = token.num_ed_mechs; for (i = 0; i < token.num_ed_mechs; i++) { o->mechs[i].mech = token.ed_mechs[i].mech; @@ -215,11 +219,15 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].usage_flags = CKF_SIGN | CKF_VERIFY; } break; -#endif +#endif /* defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) */ #ifdef EVP_PKEY_X25519 case EVP_PKEY_X25519: +#endif +#ifdef EVP_PKEY_X448 case EVP_PKEY_X448: - if (token.num_montgomery_mechs > 0 ) { +#endif +#if defined(EVP_PKEY_X25519) || defined(EVP_PKEY_X448) + if (token.num_montgomery_mechs > 0) { o->num_mechs = token.num_montgomery_mechs; for (i = 0; i < token.num_montgomery_mechs; i++) { o->mechs[i].mech = token.montgomery_mechs[i].mech; @@ -239,20 +247,19 @@ add_supported_mechs(test_cert_t *o) o->mechs[0].usage_flags = CKF_DERIVE; } break; -#endif +#endif /* defined(EVP_PKEY_X25519) || defined(EVP_PKEY_X448) */ #ifdef EVP_PKEY_ML_DSA_44 case EVP_PKEY_ML_DSA_44: case EVP_PKEY_ML_DSA_65: case EVP_PKEY_ML_DSA_87: - if (token.num_ml_dsa_mechs > 0 ) { + if (token.num_ml_dsa_mechs > 0) { o->num_mechs = token.num_ml_dsa_mechs; for (i = 0; i < token.num_ml_dsa_mechs; i++) { o->mechs[i].mech = token.ml_dsa_mechs[i].mech; o->mechs[i].params = token.ml_dsa_mechs[i].params; o->mechs[i].params_len = token.ml_dsa_mechs[i].params_len; o->mechs[i].result_flags = 0; - o->mechs[i].usage_flags = - token.ml_dsa_mechs[i].usage_flags; + o->mechs[i].usage_flags = token.ml_dsa_mechs[i].usage_flags; } } else { /* Use the default list */ @@ -269,15 +276,14 @@ add_supported_mechs(test_cert_t *o) case EVP_PKEY_ML_KEM_512: case EVP_PKEY_ML_KEM_768: case EVP_PKEY_ML_KEM_1024: - if (token.num_ml_kem_mechs > 0 ) { + if (token.num_ml_kem_mechs > 0) { o->num_mechs = token.num_ml_kem_mechs; for (i = 0; i < token.num_ml_kem_mechs; i++) { o->mechs[i].mech = token.ml_kem_mechs[i].mech; o->mechs[i].params = token.ml_kem_mechs[i].params; o->mechs[i].params_len = token.ml_kem_mechs[i].params_len; o->mechs[i].result_flags = 0; - o->mechs[i].usage_flags = - token.ml_kem_mechs[i].usage_flags; + o->mechs[i].usage_flags = token.ml_kem_mechs[i].usage_flags; } } else { /* Use the default list */ @@ -303,15 +309,14 @@ add_supported_mechs(test_cert_t *o) case EVP_PKEY_SLH_DSA_SHAKE_256S: case EVP_PKEY_SLH_DSA_SHA2_256F: case EVP_PKEY_SLH_DSA_SHAKE_256F: - if (token.num_slh_dsa_mechs > 0 ) { + if (token.num_slh_dsa_mechs > 0) { o->num_mechs = token.num_slh_dsa_mechs; for (i = 0; i < token.num_slh_dsa_mechs; i++) { o->mechs[i].mech = token.slh_dsa_mechs[i].mech; o->mechs[i].params = token.slh_dsa_mechs[i].params; o->mechs[i].params_len = token.slh_dsa_mechs[i].params_len; o->mechs[i].result_flags = 0; - o->mechs[i].usage_flags = - token.slh_dsa_mechs[i].usage_flags; + o->mechs[i].usage_flags = token.slh_dsa_mechs[i].usage_flags; } } else { /* Use the default list */ @@ -387,8 +392,12 @@ int callback_certificates(test_certs_t *objects, case EVP_PKEY_EC: case EVP_PKEY_ED25519: case EVP_PKEY_X25519: +#ifdef EVP_PKEY_ED448 case EVP_PKEY_ED448: +#endif +#ifdef EVP_PKEY_X448 case EVP_PKEY_X448: +#endif #ifdef EVP_PKEY_ML_DSA_44 case EVP_PKEY_ML_DSA_44: case EVP_PKEY_ML_DSA_65: @@ -415,7 +424,7 @@ int callback_certificates(test_certs_t *objects, default: EVP_PKEY_free(evp); fprintf(stderr, "[WARN %s ]evp->type = 0x%.4X (not supported)\n", - o->id_str, EVP_PKEY_id(evp)); + o->id_str, EVP_PKEY_id(evp)); } debug_print(" [ OK %s ] Certificate with label %s loaded successfully", @@ -770,12 +779,14 @@ int callback_public_keys(test_certs_t *objects, if (strcmp((char *)curve->data, "edwards25519") == 0) { evp_type = EVP_PKEY_ED25519; break; +#ifdef EVP_PKEY_ED448 } else if (strcmp((char *)curve->data, "edwards448") == 0) { evp_type = EVP_PKEY_ED448; break; +#endif /* EVP_PKEY_ED448 */ } debug_print(" [WARN %s ] Unknown curve name. " - " expected edwards25519 or edwards448, got %s", + " expected edwards25519 or edwards448, got %s", o->id_str, curve->data); break; #endif @@ -784,12 +795,14 @@ int callback_public_keys(test_certs_t *objects, if (strcmp((char *)curve->data, "curve25519") == 0) { evp_type = EVP_PKEY_X25519; break; +#ifdef EVP_PKEY_X448 } else if (strcmp((char *)curve->data, "curve448") == 0) { evp_type = EVP_PKEY_X448; break; +#endif /* EVP_PKEY_X448 */ } debug_print(" [WARN %s ] Unknown curve name. " - " expected curve25519 or curve448, got %s", + " expected curve25519 or curve448, got %s", o->id_str, curve->data); break; #endif @@ -810,13 +823,15 @@ int callback_public_keys(test_certs_t *objects, if (nid == NID_ED25519) { evp_type = EVP_PKEY_ED25519; break; +#ifdef EVP_PKEY_ED448 } else if (nid == NID_ED448) { evp_type = EVP_PKEY_ED448; break; +#endif /* EVP_PKEY_ED448 */ } debug_print(" [WARN %s ] Unknown OID. " - " expected NID_ED25519 (%d) or NID_ED448 (%d), got %d", - o->id_str, NID_ED25519, NID_ED448, nid); + " expected NID_ED25519 or NID_ED448, got %d", + o->id_str, nid); break; #endif #ifdef EVP_PKEY_X25519 @@ -824,13 +839,15 @@ int callback_public_keys(test_certs_t *objects, if (nid == NID_X25519) { evp_type = EVP_PKEY_X25519; break; +#ifdef EVP_PKEY_X448 } else if (nid == NID_X448) { evp_type = EVP_PKEY_X448; break; +#endif /* EVP_PKEY_X448 */ } debug_print(" [WARN %s ] Unknown OID. " - " expected NID_X25519 (%d) or NID_X448 (%d), got %d", - o->id_str, NID_X25519, NID_X448, nid); + " expected NID_X25519 or NID_X448, got %d", + o->id_str, nid); break; #endif default: @@ -865,12 +882,16 @@ int callback_public_keys(test_certs_t *objects, case EVP_PKEY_X25519: exp_length = 32; break; +#ifdef EVP_PKEY_ED448 case EVP_PKEY_ED448: exp_length = 57; break; +#endif +#ifdef EVP_PKEY_X448 case EVP_PKEY_X448: exp_length = 56; break; +#endif } if (os->length != exp_length) { debug_print(" [WARN %s ] Invalid length of EC_POINT value. Got %d, expected %d", @@ -944,7 +965,7 @@ int callback_public_keys(test_certs_t *objects, break; default: debug_print(" [WARN %s ] Unknown parameter set (%lu)", - o->id_str, o->parameter_set); + o->id_str, o->parameter_set); return -1; } break; @@ -962,7 +983,7 @@ int callback_public_keys(test_certs_t *objects, break; default: debug_print(" [WARN %s ] Unknown parameter set (%lu)", - o->id_str, o->parameter_set); + o->id_str, o->parameter_set); return -1; } break; @@ -1007,13 +1028,12 @@ int callback_public_keys(test_certs_t *objects, break; default: debug_print(" [WARN %s ] Unknown parameter set (%lu)", - o->id_str, o->parameter_set); + o->id_str, o->parameter_set); return -1; } break; default: - debug_print(" [WARN %s ] Unknown key type (%lu)", - o->id_str, o->key_type); + debug_print(" [WARN %s ] Unknown key type (%lu)", o->id_str, o->key_type); return -1; } @@ -1024,7 +1044,7 @@ int callback_public_keys(test_certs_t *objects, if (base_id != o->type) { debug_print(" [WARN %s ] Got different key type than certificate " - "(got %d, expected %d)", + "(got %d, expected %d)", o->id_str, base_id, o->type); } @@ -1046,17 +1066,17 @@ int callback_public_keys(test_certs_t *objects, o->verify_public = 1; } else { debug_print(" [WARN %s ] Got different public key then from the certificate", - o->id_str); + o->id_str); } free(cert_pubkey); } else { // construct the OpenSSL key o->type = base_id; if (!(ctx = EVP_PKEY_CTX_new_id(o->type, NULL)) || - !(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", template[12].pValue, - template[12].ulValueLen) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", template[12].pValue, + template[12].ulValueLen) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_BLD_free(bld); fail_msg("Unable to set key params"); @@ -1064,10 +1084,10 @@ int callback_public_keys(test_certs_t *objects, } OSSL_PARAM_BLD_free(bld); if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); - fail_msg("Unable to build key"); + fail_msg("Unable to build key"); return -1; } EVP_PKEY_CTX_free(ctx); @@ -1076,8 +1096,7 @@ int callback_public_keys(test_certs_t *objects, } #endif /* EVP_PKEY_ML_DSA_44 */ } else { - debug_print(" [WARN %s ] unknown key. Key type: %02lX", - o->id_str, o->key_type); + debug_print(" [WARN %s ] unknown key. Key type: %02lX", o->id_str, o->key_type); return -1; } diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index 44b272dab8..6d0e0dbcd3 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -97,14 +97,15 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, return get_value.ulValueLen; } -int test_derive_montgomery(test_cert_t *o, token_info_t *info, test_mech_t *mech) +int +test_derive_montgomery(test_cert_t *o, token_info_t *info, test_mech_t *mech) { #ifdef EVP_PKEY_X25519 unsigned char *secret = NULL, *pkcs11_secret = NULL; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; /* This is peer key */ unsigned char *pub = NULL; - size_t pub_len = 0, secret_len = o->bits/8, pkcs11_secret_len = 0; + size_t pub_len = 0, secret_len = o->bits / 8, pkcs11_secret_len = 0; int rc; if (o->private_handle == CK_INVALID_HANDLE) { @@ -114,7 +115,9 @@ int test_derive_montgomery(test_cert_t *o, token_info_t *info, test_mech_t *mech switch (o->type) { case EVP_PKEY_X25519: +#ifdef EVP_PKEY_X448 case EVP_PKEY_X448: +#endif /* OK */ break; default: @@ -438,16 +441,14 @@ void derive_tests(void **state) { continue; test_cert_t *o = &objects.data[i]; - printf("\n[%-6s] [%s]\n", - o->id_str, - o->label); + printf("\n[%-6s] [%s]\n", o->id_str, o->label); printf("[%s] [%6lu] [ %s ] [ %s%s ]\n", - (o->key_type == CKK_EC ? "ECDSA " : - o->key_type == CKK_EC_MONTGOMERY ? "XEDDSA" : " ?? "), - o->bits, - o->verify_public == 1 ? " ./ " : " ", - o->derive_pub ? "[./]" : "[ ]", - o->derive_priv ? "[./]" : "[ ]"); + (o->key_type == CKK_EC ? "ECDSA " : + o->key_type == CKK_EC_MONTGOMERY ? "XEDDSA" : " ?? "), + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->derive_pub ? "[./]" : "[ ]", + o->derive_priv ? "[./]" : "[ ]"); if (!o->derive_pub && !o->derive_priv) { printf(" no usable attributes found ... ignored\n"); continue; diff --git a/src/tests/p11test/p11test_case_interface.c b/src/tests/p11test/p11test_case_interface.c index c132ed813f..97a969182e 100644 --- a/src/tests/p11test/p11test_case_interface.c +++ b/src/tests/p11test/p11test_case_interface.c @@ -98,7 +98,7 @@ void interface_test(void **state) /* GetInterface with explicit 3.0 version */ version.major = 3; version.minor = 0; - rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR) "PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_OK); assert_string_equal((char *)interface->pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->major, 3); @@ -110,7 +110,7 @@ void interface_test(void **state) /* GetInterface the other interface (with explicit 2.x version) */ version.major = 2; /* assumed 2 */ version.minor = version2.minor; - rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR) "PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_OK); assert_string_equal((char *)interface->pInterfaceName, "PKCS 11"); assert_int_equal(((CK_VERSION *)interface->pFunctionList)->major, 2); @@ -121,17 +121,17 @@ void interface_test(void **state) } /* GetInterface with unknown interface */ - rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11 other", NULL, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR) "PKCS 11 other", NULL, &interface, 0); assert_int_equal(rv, CKR_ARGUMENTS_BAD); /* GetInterface with wrong version */ version.major = 4; version.minor = 50; - rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, 0); + rv = C_GetInterface((CK_UTF8CHAR_PTR) "PKCS 11", &version, &interface, 0); assert_int_equal(rv, CKR_ARGUMENTS_BAD); /* GetInterface with unknown flags */ - rv = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", NULL, &interface, 2); + rv = C_GetInterface((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 2); assert_int_equal(rv, CKR_ARGUMENTS_BAD); free(interfaces); diff --git a/src/tests/p11test/p11test_case_mechs.c b/src/tests/p11test/p11test_case_mechs.c index efc6cac00c..b0d084daef 100644 --- a/src/tests/p11test/p11test_case_mechs.c +++ b/src/tests/p11test/p11test_case_mechs.c @@ -251,10 +251,10 @@ supported_mechanisms_test(void **state) 's', "FLAGS"); for (i = 0; i < mechanism_count; i++) { printf("[%-21s] [%4lu][%5lu] [0x%.8lX]", - get_mechanism_name(mechanism_list[i]), - mechanism_info[i].ulMinKeySize, - mechanism_info[i].ulMaxKeySize, - mechanism_info[i].flags); + get_mechanism_name(mechanism_list[i]), + mechanism_info[i].ulMinKeySize, + mechanism_info[i].ulMaxKeySize, + mechanism_info[i].flags); P11TEST_DATA_ROW(info, 4, 's', get_mechanism_name(mechanism_list[i]), 'd', mechanism_info[i].ulMinKeySize, diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index d9a77c49ca..a11bcb5849 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -582,7 +582,12 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, } #ifdef EVP_PKEY_ED25519 case EVP_PKEY_ED25519: - case EVP_PKEY_ED448: { +#endif +#ifdef EVP_PKEY_ED448 + case EVP_PKEY_ED448: +#endif +#if defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) + { /* need to be created even though we do not do any MD */ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); @@ -609,7 +614,7 @@ int verify_message_openssl(test_cert_t *o, token_info_t *info, CK_BYTE *message, } break; } -#endif +#endif /* defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) */ default: fprintf(stderr, " [ KEY %s ] Unknown type. Not verifying\n", o->id_str); } @@ -622,7 +627,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, { CK_RV rv; CK_FUNCTION_LIST_PTR fp = info->function_pointer; - CK_MECHANISM sign_mechanism = { mech->mech, mech->params, mech->params_len }; + CK_MECHANISM sign_mechanism = {mech->mech, mech->params, mech->params_len}; static int verify_support = 1; char *name; @@ -691,11 +696,13 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, CK_BYTE *message = NULL; CK_BYTE *sign = NULL; CK_ULONG sign_length = 0; +#ifdef EVP_PKEY_ED448 CK_EDDSA_PARAMS eddsa_params = { .phFlag = CK_FALSE, .ulContextDataLen = 0, .pContextData = NULL, }; +#endif CK_HASH_SIGN_ADDITIONAL_CONTEXT pqc_params = { .hedgeVariant = CKH_HEDGE_PREFERRED, .pContext = NULL, @@ -715,14 +722,14 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, } switch (o->type) { - case EVP_PKEY_EC: - case EVP_PKEY_RSA: -#ifdef EVP_PKEY_ED25519 +#ifdef EVP_PKEY_ED448 case EVP_PKEY_ED448: /* The Ed448 requires parameter */ mech->params = &eddsa_params; mech->params_len = sizeof(CK_EDDSA_PARAMS); - break; + /* fall through */ +#endif /* EVP_PKEY_ED448 */ +#ifdef EVP_PKEY_ED25519 case EVP_PKEY_ED25519: #endif #ifdef EVP_PKEY_ML_DSA_44 @@ -744,6 +751,8 @@ int sign_verify_test(test_cert_t *o, token_info_t *info, test_mech_t *mech, case EVP_PKEY_SLH_DSA_SHA2_256F: case EVP_PKEY_SLH_DSA_SHAKE_256F: #endif + case EVP_PKEY_EC: + case EVP_PKEY_RSA: /* OK */ break; default: @@ -860,27 +869,25 @@ void readonly_tests(void **state) { test_cert_t *o = &objects.data[i]; if (o->key_type != CKK_RSA && - o->key_type != CKK_EC && - o->key_type != CKK_EC_EDWARDS && - o->key_type != CKK_ML_DSA && - o->key_type != CKK_SLH_DSA) + o->key_type != CKK_EC && + o->key_type != CKK_EC_EDWARDS && + o->key_type != CKK_ML_DSA && + o->key_type != CKK_SLH_DSA) continue; - printf("\n[%-6s] [%s]\n", - o->id_str, - o->label); + printf("\n[%-6s] [%s]\n", o->id_str, o->label); printf("[%s] [%6lu] [ %s ] [%s%s] [%s%s]\n", - (o->key_type == CKK_RSA ? " RSA " : - o->key_type == CKK_EC ? " EC " : - o->key_type == CKK_EC_EDWARDS ? " EDDSA " : - o->key_type == CKK_ML_DSA ? "ML-DSA " : - o->key_type == CKK_SLH_DSA ? "SLH-DSA" : " ?? "), - o->bits, - o->verify_public == 1 ? " ./ " : " ", - o->sign ? "[./] " : "[ ] ", - o->verify ? " [./] " : " [ ] ", - o->encrypt ? "[./] " : "[ ] ", - o->decrypt ? " [./] " : " [ ] "); + (o->key_type == CKK_RSA ? " RSA " : + o->key_type == CKK_EC ? " EC " : + o->key_type == CKK_EC_EDWARDS ? " EDDSA " : + o->key_type == CKK_ML_DSA ? "ML-DSA " : + o->key_type == CKK_SLH_DSA ? "SLH-DSA" : " ?? "), + o->bits, + o->verify_public == 1 ? " ./ " : " ", + o->sign ? "[./] " : "[ ] ", + o->verify ? " [./] " : " [ ] ", + o->encrypt ? "[./] " : "[ ] ", + o->decrypt ? " [./] " : " [ ] "); if (!o->sign && !o->verify && !o->encrypt && !o->decrypt && !o->encapsulate && !o->decapsulate) { printf(" no usable attributes found ... ignored\n"); @@ -896,11 +903,11 @@ void readonly_tests(void **state) { continue; } printf(" [ %-21s ] [ %s ] [ %s ]\n", - get_mechanism_name(mech->mech), - mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", - mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); + get_mechanism_name(mech->mech), + mech->result_flags & FLAGS_SIGN_ANY ? "[./]" : " ", + mech->result_flags & FLAGS_DECRYPT_ANY ? "[./]" : " "); if ((mech->result_flags & FLAGS_SIGN_ANY) == 0 && - (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) + (mech->result_flags & FLAGS_DECRYPT_ANY) == 0) continue; /* skip empty rows for export */ P11TEST_DATA_ROW(info, 4, 's', o->id_str, diff --git a/src/tests/p11test/p11test_case_usage.c b/src/tests/p11test/p11test_case_usage.c index ac3c078ec3..cba1369034 100644 --- a/src/tests/p11test/p11test_case_usage.c +++ b/src/tests/p11test/p11test_case_usage.c @@ -41,38 +41,38 @@ void usage_test(void **state) { if (objects.data[i].sign && !objects.data[i].verify) { errors++; fprintf(stderr, " [ ERROR %s ] If Sign is set, Verify should be set too.\n", - objects.data[i].id_str); + objects.data[i].id_str); } if (objects.data[i].decrypt && !objects.data[i].encrypt) { errors++; fprintf(stderr, " [ ERROR %s ] If Decrypt is set, Encrypt should be set too.\n", - objects.data[i].id_str); + objects.data[i].id_str); } if (objects.data[i].unwrap && !objects.data[i].wrap) { errors++; fprintf(stderr, " [ ERROR %s ] If Unwrap is set, Wrap should be set too.\n", - objects.data[i].id_str); + objects.data[i].id_str); } if (objects.data[i].encapsulate && !objects.data[i].decapsulate) { errors++; fprintf(stderr, " [ ERROR %s ] If Encapsulate is set, Decapsulate should be set too.\n", - objects.data[i].id_str); + objects.data[i].id_str); } if (objects.data[i].derive_pub != objects.data[i].derive_priv) { errors++; fprintf(stderr, " [ ERROR %s ] Derive should be set on both private and public part.\n", - objects.data[i].id_str); + objects.data[i].id_str); } /* We have at least one usage flag for every key group */ if (!objects.data[i].sign && !objects.data[i].verify && - !objects.data[i].encrypt && !objects.data[i].decrypt && - !objects.data[i].wrap && !objects.data[i].unwrap && - !objects.data[i].encapsulate && !objects.data[i].decapsulate && - !objects.data[i].derive_pub && !objects.data[i].derive_priv) { + !objects.data[i].encrypt && !objects.data[i].decrypt && + !objects.data[i].wrap && !objects.data[i].unwrap && + !objects.data[i].encapsulate && !objects.data[i].decapsulate && + !objects.data[i].derive_pub && !objects.data[i].derive_priv) { errors++; fprintf(stderr, " [ ERROR %s ] Key group should have at least one usage flag.\n", - objects.data[i].id_str); + objects.data[i].id_str); } } @@ -80,22 +80,22 @@ void usage_test(void **state) { printf("[KEY ID] [LABEL]\n"); printf("[ TYPE ] [ SIZE ] [PUBLIC] [SIGN&VERIFY] [ENC&DECRYPT] [WRAP&UNWR] [ENC&DECAPS] [ DERIVE ] [ALWAYS_AUTH]\n"); P11TEST_DATA_ROW(info, 16, - 's', "KEY ID", - 's', "LABEL", - 's', "TYPE", - 's', "BITS", - 's', "VERIFY PUBKEY", - 's', "SIGN", - 's', "VERIFY", - 's', "ENCRYPT", - 's', "DECRYPT", - 's', "WRAP", - 's', "UNWRAP", - 's', "ENCAPSULATE", - 's', "DECAPSULATE", - 's', "DERIVE PUBLIC", - 's', "DERIVE PRIVATE", - 's', "ALWAYS AUTH"); + 's', "KEY ID", + 's', "LABEL", + 's', "TYPE", + 's', "BITS", + 's', "VERIFY PUBKEY", + 's', "SIGN", + 's', "VERIFY", + 's', "ENCRYPT", + 's', "DECRYPT", + 's', "WRAP", + 's', "UNWRAP", + 's', "ENCAPSULATE", + 's', "DECAPSULATE", + 's', "DERIVE PUBLIC", + 's', "DERIVE PRIVATE", + 's', "ALWAYS AUTH"); for (i = 0; i < objects.count; i++) { test_cert_t *o = &objects.data[i]; diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1a0a31a115..37f14f93c7 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2976,8 +2976,8 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, hashlen = hash_length(opt_hash_alg); if ((size_t)sz != hashlen) { util_fatal("For %s mechanism, message size (got %zd bytes) " - "must be equal to specified digest length (%lu)\n", - p11_mechanism_to_name(opt_mechanism), sz, hashlen); + "must be equal to specified digest length (%lu)\n", + p11_mechanism_to_name(opt_mechanism), sz, hashlen); } hash_sign_params.hash = opt_hash_alg; /* TODO allow setting hedge and context */ @@ -3745,10 +3745,10 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Generate ML-KEM mechanism not supported"); FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, - &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); n_pubkey_attr++; FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, - &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); + &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_encapsulate) { @@ -3797,10 +3797,10 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, util_fatal("Generate SLH-DSA mechanism not supported"); FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, - &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); n_pubkey_attr++; FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, - &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); + &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_sign) { @@ -4714,7 +4714,7 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info const char *str_name = EVP_PKEY_get0_type_name(pkey); if (strcmp(str_name, "ML-DSA-44") == 0) { pqc->type = CKP_ML_DSA_44; - } else if (strcmp(str_name, "ML-DSA-65") == 0) { + } else if (strcmp(str_name, "ML-DSA-65") == 0) { pqc->type = CKP_ML_DSA_65; } else if (strcmp(str_name, "ML-DSA-87") == 0) { pqc->type = CKP_ML_DSA_87; @@ -4726,27 +4726,27 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info pqc->type = CKP_ML_KEM_1024; } else if (strcmp(str_name, "SLH-DSA-SHA2-128f") == 0) { pqc->type = CKP_SLH_DSA_SHA2_128F; - } else if (strcmp(str_name, "SLH-DSA-SHA2-128s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHA2-128s") == 0) { pqc->type = CKP_SLH_DSA_SHA2_128S; - } else if (strcmp(str_name, "SLH-DSA-SHA2-192f") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHA2-192f") == 0) { pqc->type = CKP_SLH_DSA_SHA2_192F; - } else if (strcmp(str_name, "SLH-DSA-SHA2-192s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHA2-192s") == 0) { pqc->type = CKP_SLH_DSA_SHA2_192S; - } else if (strcmp(str_name, "SLH-DSA-SHA2-256f") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHA2-256f") == 0) { pqc->type = CKP_SLH_DSA_SHA2_256F; - } else if (strcmp(str_name, "SLH-DSA-SHA2-256s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHA2-256s") == 0) { pqc->type = CKP_SLH_DSA_SHA2_256S; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_128F; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_128S; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_192F; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_192S; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_256F; - } else if (strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { + } else if (strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { pqc->type = CKP_SLH_DSA_SHAKE_256S; } if (private) { @@ -4794,7 +4794,7 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info OPENSSL_free(pqc->seed.value); return -1; } - } else { + } else { util_fatal("PRIVATE key value available"); } } @@ -4953,17 +4953,17 @@ evp_pkey2ck_key_type(EVP_PKEY *pkey, CK_KEY_TYPE *type, int *pk_type, struct ec_ *type = CKK_ML_KEM; return CKR_OK; } else if (strcmp(str_name, "SLH-DSA-SHA2-128f") == 0 || - strcmp(str_name, "SLH-DSA-SHA2-128s") == 0 || - strcmp(str_name, "SLH-DSA-SHA2-192f") == 0 || - strcmp(str_name, "SLH-DSA-SHA2-192s") == 0 || - strcmp(str_name, "SLH-DSA-SHA2-256f") == 0 || - strcmp(str_name, "SLH-DSA-SHA2-256s") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0 || - strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { + strcmp(str_name, "SLH-DSA-SHA2-128s") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-192f") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-192s") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-256f") == 0 || + strcmp(str_name, "SLH-DSA-SHA2-256s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-128f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-128s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-192f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-192s") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-256f") == 0 || + strcmp(str_name, "SLH-DSA-SHAKE-256s") == 0) { *type = CKK_SLH_DSA; return CKR_OK; } @@ -6744,8 +6744,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) unsigned int n; printf(" VALUE: "); - for (n = 0; n < size; n++) { - if (n && (n%32)==0) + for (n = 0; n < size; n++) { + if (n && (n % 32) == 0) printf("\n "); printf("%02x", value[n]); } @@ -7432,7 +7432,7 @@ static int read_object(CK_SESSION_HANDLE session) #endif /* only if compiled with a version of OpenSSL or libressl */ /* do more tests for the other 3 as needed */ -#ifdef EVP_PKEY_ED25519 +#if defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) || defined (EVP_PKEY_X25519) || defined(EVP_PKEY_X448) } else if (type == CKK_EC_EDWARDS || type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; CK_BYTE *params = NULL; @@ -7455,26 +7455,26 @@ static int read_object(CK_SESSION_HANDLE session) int nid = OBJ_obj2nid(obj); if (nid != NID_ED25519 && nid != NID_X25519 -#if defined(EVP_PKEY_ED448) +#ifdef EVP_PKEY_ED448 && nid != NID_ED448 #endif -#if defined(EVP_PKEY_X448) +#ifdef EVP_PKEY_X448 && nid != NID_X448 #endif ) { util_fatal("Unknown curve OID, expected NID_ED25519 (%d), NID_X25519 (%d), " -#if defined(EVP_PKEY_ED448) +#ifdef EVP_PKEY_ED448 "NID_ED448 (%d), " #endif -#if defined(EVP_PKEY_X448) +#ifdef EVP_PKEY_X448 "NID_X448 (%d), " #endif "got %d", NID_ED25519, NID_X25519, -#if defined(EVP_PKEY_ED448) +#ifdef EVP_PKEY_ED448 NID_ED448, #endif -#if defined(EVP_PKEY_X448) +#ifdef EVP_PKEY_X44 NID_X448, #endif nid); @@ -7510,15 +7510,15 @@ static int read_object(CK_SESSION_HANDLE session) if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_ED25519; -#if defined(EVP_PKEY_ED448) +#ifdef EVP_PKEY_ED448 else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ -#if defined(EVP_PKEY_X25519) +#ifdef EVP_PKEY_X25519 else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ -#if defined(EVP_PKEY_X448) +#ifdef EVP_PKEY_X448 else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(448)) raw_pk = EVP_PKEY_X448; #endif /* EVP_PKEY_X448 */ @@ -7537,11 +7537,13 @@ static int read_object(CK_SESSION_HANDLE session) } EVP_PKEY_free(key); +#endif /* defined(EVP_PKEY_ED25519) || defined(EVP_PKEY_ED448) || defined (EVP_PKEY_X25519) || defined(EVP_PKEY_X448) */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L } else if (type == CKK_ML_DSA || type == CKK_ML_KEM || type == CKK_SLH_DSA) { unsigned long parameter_set = getPARAMETER_SET(session, obj); const char *evp_name = NULL; unsigned char *value = NULL; - size_t value_len = 0; + unsigned long value_len = 0; switch (type) { case CKK_ML_DSA: @@ -7631,16 +7633,16 @@ static int read_object(CK_SESSION_HANDLE session) } if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, evp_name, NULL)) || - !(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", value, value_len) != 1 || - !(params = OSSL_PARAM_BLD_to_param(bld))) { + !(bld = OSSL_PARAM_BLD_new()) || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", value, value_len) != 1 || + !(params = OSSL_PARAM_BLD_to_param(bld))) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_BLD_free(bld); util_fatal("Unable to set key params"); } OSSL_PARAM_BLD_free(bld); if (EVP_PKEY_fromdata_init(ctx) != 1 || - EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { + EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); util_fatal("Unable to build key"); @@ -7652,7 +7654,7 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot write public key to output"); } EVP_PKEY_free(pkey); -#endif +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ } else util_fatal("Reading public keys of type 0x%lX not (yet) supported", type); value = BIO_copy_data(pout, &derlen); @@ -7660,7 +7662,7 @@ static int read_object(CK_SESSION_HANDLE session) len = derlen; #else util_fatal("No OpenSSL support, cannot read public key"); -#endif +#endif /* ENABLE_OPENSSL */ } /* value is PUBKEY_KEY_INFO */ } else From b7de49173b6782c4e947ba162168c75e1156f33b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:06:35 +0100 Subject: [PATCH 4034/4321] Adjust virt_cacard and oseid applets reference files --- src/tests/p11test/oseid_ref.json | 8 ++++++++ src/tests/p11test/virt_cacard_ref.json | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/tests/p11test/oseid_ref.json b/src/tests/p11test/oseid_ref.json index bce5925e38..d3c473068e 100644 --- a/src/tests/p11test/oseid_ref.json +++ b/src/tests/p11test/oseid_ref.json @@ -413,6 +413,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -431,6 +433,8 @@ "", "", "", + "", + "", "" ], [ @@ -447,6 +451,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -463,6 +469,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" diff --git a/src/tests/p11test/virt_cacard_ref.json b/src/tests/p11test/virt_cacard_ref.json index 5dd4fed34a..6cb70abcf9 100644 --- a/src/tests/p11test/virt_cacard_ref.json +++ b/src/tests/p11test/virt_cacard_ref.json @@ -471,6 +471,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -489,6 +491,8 @@ "", "", "", + "", + "", "" ], [ @@ -505,6 +509,8 @@ "", "", "", + "", + "", "" ], [ @@ -521,6 +527,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" From ef8fa527e25f82bb2e6365d1bbafdee15c26aab6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 13 Nov 2025 13:07:04 +0100 Subject: [PATCH 4035/4321] win32: Avoid specifying object files multiple times this was causing warnings in the appveyor CI: pkcs11-tool.obj : warning LNK4042: object specified more than once; extras ignored --- src/tools/Makefile.mak | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 7a0156f206..8b0711a87c 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -56,11 +56,11 @@ openpgp-tool.exe: openpgp-tool-helpers.obj $(LIBS) sc-hsm-tool.exe: sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /out:$@ $*.obj sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib + link $(LINKFLAGS) /out:$@ $*.obj fread_to_eof.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib pkcs11-tool.exe: pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib .c.exe: cl $(COPTS) /c $< From a94f1e6e991e8c70761e575d2a34f27186eb758b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 09:40:06 +0100 Subject: [PATCH 4036/4321] tests: Remove non-existing source --- tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh index 88ebe63ad3..417d67ddb0 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh @@ -46,7 +46,6 @@ function test_unwrapped_aes_encryption() { rm aes_ciphertext_openssl.data aes_ciphertext_pkcs11.data aes_plain.data } -source $SOURCE_PATH/tests/help.sh # Initialize tokens with their custom pkcs11-tool arguments source $SOURCE_PATH/tests/common.sh softokn initialize_token @@ -124,11 +123,11 @@ for MECH in AES-CBC AES-KEY-WRAP RSA-PKCS; do $PKCS11_TOOL "${ARGS[@]}" --write-object aes.key --id $ID_AES --type secrkey --key-type AES:32 \ --usage-decrypt --extractable --label "stored-aes-32" assert $? "Failed to write AES key on $WRAPPER" - # 2. Wrap + # 2. Wrap $PKCS11_TOOL "${ARGS[@]}" --wrap -m $MECH --id $ID_WRAP --iv $IV --application-id $ID_AES \ --output-file wrapped_key.data assert $? "Failed to wrap AES key with $MECH from $WRAPPER" - + get_priv_args "$UNWRAPPER" #3. Unwrap $PKCS11_TOOL "${ARGS[@]}" --unwrap -m $MECH --id $ID_WRAP --iv $IV --application-id $ID_AES \ From 20e67fc57e3cc5957b09d8ab49a47b880dec77d9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 14:45:03 +0100 Subject: [PATCH 4037/4321] pkcs11: Remove non-standard CK_LONG --- src/pkcs11/pkcs11-display.c | 18 +++++++++--------- src/pkcs11/pkcs11-display.h | 10 +++++----- src/tests/p11test/p11test_case_common.c | 2 +- src/tests/p11test/p11test_case_common.h | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index f488c3f763..096168f819 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -109,7 +109,7 @@ buf_spec(CK_VOID_PTR buf_addr, CK_ULONG buf_len) } void -print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) +print_enum(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { enum_spec *spec = (enum_spec*)arg; CK_ULONG i; @@ -125,18 +125,18 @@ print_enum(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR } void -print_boolean(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) +print_boolean(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_BYTE i = *((CK_BYTE *)value); fprintf(f, i ? "True\n" : "False\n"); } void -print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) +print_generic(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_ULONG i; - if((CK_LONG)size != -1 && value != NULL) { + if((long)size != -1 && value != NULL) { char hex[16*3+1] = {0}; char ascii[16+1]; char *hex_ptr = hex, *ascii_ptr = ascii; @@ -184,7 +184,7 @@ print_generic(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_P #ifdef ENABLE_OPENSSL static void -print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) +print_dn(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { print_generic(f, type, value, size, arg, key_type); if(size && value) { @@ -244,7 +244,7 @@ static enum_spec ck_slh_dsa_t[] = { }; void -print_parameter_set(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, +print_parameter_set(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { switch (key_type) { @@ -264,12 +264,12 @@ print_parameter_set(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_ } void -print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) +print_print(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type) { CK_ULONG i, j=0; CK_BYTE c; - if((CK_LONG)size != -1) { + if((long)size != -1) { fprintf(f, "%s\n ", buf_spec(value, size)); for(i = 0; i < size; i += j) { for(j = 0; ((i + j < size) && (j < 32)); j++) { @@ -1563,7 +1563,7 @@ print_attribute_list(FILE *f, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) if(ck_attribute_specs[k].type == pTemplate[j].type) { found = 1; fprintf(f, " %s ", ck_attribute_specs[k].name); - if(pTemplate[j].pValue && ((CK_LONG) pTemplate[j].ulValueLen) > 0) { + if(pTemplate[j].pValue && ((long)pTemplate[j].ulValueLen) > 0) { ck_attribute_specs[k].display( f, pTemplate[j].type, pTemplate[j].pValue, pTemplate[j].ulValueLen, diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index d728c3d554..a0433b99f7 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -29,7 +29,7 @@ extern "C" { #endif -typedef void(display_func) (FILE *, CK_LONG, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR, CK_KEY_TYPE); +typedef void(display_func) (FILE *, long, CK_VOID_PTR, CK_ULONG, CK_VOID_PTR, CK_KEY_TYPE); typedef struct { CK_ULONG type; @@ -75,10 +75,10 @@ enum ck_type { const char *lookup_enum_spec(enum_spec *spec, CK_ULONG value); const char *lookup_enum(CK_ULONG type, CK_ULONG value); -void print_enum (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); -void print_boolean (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); -void print_generic (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); -void print_print (FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_enum (FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_boolean (FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_generic (FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); +void print_print (FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg, CK_KEY_TYPE key_type); void show_error (FILE *f, char *str, CK_RV rc); void print_ck_info(FILE *f, CK_INFO *info); diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 588ee98ac4..1dd6eaba67 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -1171,7 +1171,7 @@ int callback_secret_keys(test_certs_t *objects, int search_objects(test_certs_t *objects, token_info_t *info, - CK_ATTRIBUTE filter[], CK_LONG filter_size, CK_ATTRIBUTE template[], CK_LONG template_size, + CK_ATTRIBUTE filter[], long filter_size, CK_ATTRIBUTE template[], long template_size, int (*callback)(test_certs_t *, CK_ATTRIBUTE[], unsigned long, CK_OBJECT_HANDLE)) { CK_RV rv; diff --git a/src/tests/p11test/p11test_case_common.h b/src/tests/p11test/p11test_case_common.h index 20441d3466..5681742abd 100644 --- a/src/tests/p11test/p11test_case_common.h +++ b/src/tests/p11test/p11test_case_common.h @@ -79,7 +79,7 @@ void test_certs_init(test_certs_t *objects); void always_authenticate(test_cert_t *o, token_info_t *info); int search_objects(test_certs_t *objects, token_info_t *info, - CK_ATTRIBUTE filter[], CK_LONG filter_size, CK_ATTRIBUTE template[], CK_LONG template_size, + CK_ATTRIBUTE filter[], long filter_size, CK_ATTRIBUTE template[], long template_size, int (*callback)(test_certs_t *, CK_ATTRIBUTE[], unsigned long, CK_OBJECT_HANDLE)); void search_for_all_objects(test_certs_t *objects, token_info_t *info); void clean_all_objects(test_certs_t *objects); From b3c1c8273710cf2ecc5a2304f64e283269ad2c51 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Nov 2025 14:45:41 +0100 Subject: [PATCH 4038/4321] pkcs11: Move public domain pkcs11.h to separate file to simplify updates Source: https://github.com/latchset/pkcs11-headers/blob/main/public-domain/3.2/pkcs11.h --- src/pkcs11/Makefile.am | 2 +- src/pkcs11/pd-pkcs11.h | 2775 +++++++++++++++++++++++++++++++++++++++ src/pkcs11/pkcs11.h | 2793 +--------------------------------------- 3 files changed, 2795 insertions(+), 2775 deletions(-) create mode 100644 src/pkcs11/pd-pkcs11.h diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 7b6e5c6751..97b039e610 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -11,7 +11,7 @@ endif AM_CPPFLAGS = -I$(top_srcdir)/src -OPENSC_PKCS11_INC = sc-pkcs11.h pkcs11.h pkcs11-opensc.h +OPENSC_PKCS11_INC = sc-pkcs11.h pd-pkcs11.h pkcs11.h pkcs11-opensc.h OPENSC_PKCS11_SRC = pkcs11-global.c pkcs11-session.c pkcs11-object.c misc.c slot.c \ mechanism.c openssl.c framework-pkcs15.c \ framework-pkcs15init.c debug.c pkcs11.exports \ diff --git a/src/pkcs11/pd-pkcs11.h b/src/pkcs11/pd-pkcs11.h new file mode 100644 index 0000000000..003bbd307f --- /dev/null +++ b/src/pkcs11/pd-pkcs11.h @@ -0,0 +1,2775 @@ +/* https://github.com/latchset/pkcs11-headers/blob/main/public-domain/3.2/pkcs11.h */ +// clang-format off + +/* This file is in the Public Domain */ + +#ifndef _PD_PKCS11_ +#define _PD_PKCS11_ + +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 2 +#define CRYPTOKI_VERSION_AMENDMENT 0 + +/* Basic types */ +typedef unsigned char CK_BBOOL; +typedef unsigned char CK_BYTE; +typedef unsigned char CK_CHAR; +typedef unsigned char CK_UTF8CHAR; +typedef unsigned long int CK_ULONG; + +typedef CK_BBOOL * CK_BBOOL_PTR; +typedef CK_BYTE * CK_BYTE_PTR; +typedef CK_CHAR * CK_CHAR_PTR; +typedef CK_UTF8CHAR * CK_UTF8CHAR_PTR; +typedef CK_ULONG * CK_ULONG_PTR; + +/* Basic defines */ +#define NULL_PTR ((void *)0) +typedef void * CK_VOID_PTR; +typedef void ** CK_VOID_PTR_PTR; + +#define CK_EFFECTIVELY_INFINITE 0UL +#define CK_UNAVAILABLE_INFORMATION ~0UL +#define CK_INVALID_HANDLE 0UL +#define CK_TRUE 1 +#define CK_FALSE 0 + +/* CK_ types in alphabetical order */ +#define ULONGDEF(__name__) \ +typedef CK_ULONG __name__; \ +typedef __name__ * __name__ ## _PTR; + +ULONGDEF(CK_ATTRIBUTE_TYPE); +ULONGDEF(CK_CERTIFICATE_CATEGORY); +ULONGDEF(CK_CERTIFICATE_TYPE); +ULONGDEF(CK_EC_KDF_TYPE); +ULONGDEF(CK_EXTRACT_PARAMS); +ULONGDEF(CK_FLAGS); +ULONGDEF(CK_GENERATOR_FUNCTION); +ULONGDEF(CK_HEDGE_TYPE); +ULONGDEF(CK_HSS_LEVELS); +ULONGDEF(CK_HW_FEATURE_TYPE); +ULONGDEF(CK_JAVA_MIDP_SECURITY_DOMAIN); +ULONGDEF(CK_KEY_TYPE); +ULONGDEF(CK_LMS_TYPE); +ULONGDEF(CK_LMOTS_TYPE); +ULONGDEF(CK_MAC_GENERAL_PARAMS); +ULONGDEF(CK_MECHANISM_TYPE); +ULONGDEF(CK_ML_DSA_PARAMETER_SET_TYPE); +ULONGDEF(CK_ML_KEM_PARAMETER_SET_TYPE); +ULONGDEF(CK_NOTIFICATION); +ULONGDEF(CK_OBJECT_CLASS); +ULONGDEF(CK_OBJECT_HANDLE); +ULONGDEF(CK_OTP_PARAM_TYPE); +ULONGDEF(CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE); +ULONGDEF(CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE); +ULONGDEF(CK_PRF_DATA_TYPE); +ULONGDEF(CK_PROFILE_ID); +ULONGDEF(CK_RC2_PARAMS); +ULONGDEF(CK_RSA_PKCS_MGF_TYPE); +ULONGDEF(CK_RSA_PKCS_OAEP_SOURCE_TYPE); +ULONGDEF(CK_RV); +ULONGDEF(CK_SESSION_HANDLE); +ULONGDEF(CK_SESSION_VALIDATION_FLAGS_TYPE); +ULONGDEF(CK_SLH_DSA_PARAMETER_SET_TYPE); +ULONGDEF(CK_SLOT_ID); +ULONGDEF(CK_SP800_108_DKM_LENGTH_METHOD); +ULONGDEF(CK_STATE); +ULONGDEF(CK_TRUST); +ULONGDEF(CK_USER_TYPE); +ULONGDEF(CK_VALIDATION_AUTHORITY_TYPE); +ULONGDEF(CK_VALIDATION_TYPE); +ULONGDEF(CK_X2RATCHET_KDF_TYPE); +ULONGDEF(CK_X3DH_KDF_TYPE); +ULONGDEF(CK_X9_42_DH_KDF_TYPE); +ULONGDEF(CK_XEDDSA_HASH_TYPE); +ULONGDEF(CK_XMSSMT_PARAMETER_SET_TYPE); +ULONGDEF(CK_XMSS_PARAMETER_SET_TYPE); + +/* domain specific values and constants */ + +/* CK (certificate) */ +#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL +#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL +#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL +#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL + +/* CK (OTP) */ +#define CK_OTP_VALUE 0UL +#define CK_OTP_PIN 1UL +#define CK_OTP_CHALLENGE 2UL +#define CK_OTP_TIME 3UL +#define CK_OTP_COUNTER 4UL +#define CK_OTP_FLAGS 5UL +#define CK_OTP_OUTPUT_LENGTH 6UL +#define CK_OTP_OUTPUT_FORMAT 7UL + +/* CK (OTP format) */ +#define CK_OTP_FORMAT_DECIMAL 0UL +#define CK_OTP_FORMAT_HEXADECIMAL 1UL +#define CK_OTP_FORMAT_ALPHANUMERIC 2UL +#define CK_OTP_FORMAT_BINARY 3UL + +/* CK (OTP requirement) */ +#define CK_OTP_PARAM_IGNORED 0UL +#define CK_OTP_PARAM_OPTIONAL 1UL +#define CK_OTP_PARAM_MANDATORY 2UL + +/* CK (security) */ +#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL +#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL +#define CK_SECURITY_DOMAIN_OPERATOR 2UL +#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL + +/* CK (SP800 KDF) */ +#define CK_SP800_108_ITERATION_VARIABLE 0x00000001UL +#define CK_SP800_108_OPTIONAL_COUNTER 0x00000002UL +#define CK_SP800_108_COUNTER 0x00000002UL +#define CK_SP800_108_DKM_LENGTH 0x00000003UL +#define CK_SP800_108_BYTE_ARRAY 0x00000004UL +#define CK_SP800_108_KEY_HANDLE 0x00000005UL + +/* CK (SP800 DKM) */ +#define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL +#define CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS 0x00000002UL + +/* CKA */ +#define CKA_CLASS 0x00000000UL +#define CKA_TOKEN 0x00000001UL +#define CKA_PRIVATE 0x00000002UL +#define CKA_LABEL 0x00000003UL +#define CKA_UNIQUE_ID 0x00000004UL +#define CKA_APPLICATION 0x00000010UL +#define CKA_VALUE 0x00000011UL +#define CKA_OBJECT_ID 0x00000012UL +#define CKA_CERTIFICATE_TYPE 0x00000080UL +#define CKA_ISSUER 0x00000081UL +#define CKA_SERIAL_NUMBER 0x00000082UL +#define CKA_AC_ISSUER 0x00000083UL +#define CKA_OWNER 0x00000084UL +#define CKA_ATTR_TYPES 0x00000085UL +#define CKA_TRUSTED 0x00000086UL +#define CKA_CERTIFICATE_CATEGORY 0x00000087UL +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL +#define CKA_URL 0x00000089UL +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL +#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL +#define CKA_CHECK_VALUE 0x00000090UL +#define CKA_KEY_TYPE 0x00000100UL +#define CKA_SUBJECT 0x00000101UL +#define CKA_ID 0x00000102UL +#define CKA_SENSITIVE 0x00000103UL +#define CKA_ENCRYPT 0x00000104UL +#define CKA_DECRYPT 0x00000105UL +#define CKA_WRAP 0x00000106UL +#define CKA_UNWRAP 0x00000107UL +#define CKA_SIGN 0x00000108UL +#define CKA_SIGN_RECOVER 0x00000109UL +#define CKA_VERIFY 0x0000010AUL +#define CKA_VERIFY_RECOVER 0x0000010BUL +#define CKA_DERIVE 0x0000010CUL +#define CKA_START_DATE 0x00000110UL +#define CKA_END_DATE 0x00000111UL +#define CKA_MODULUS 0x00000120UL +#define CKA_MODULUS_BITS 0x00000121UL +#define CKA_PUBLIC_EXPONENT 0x00000122UL +#define CKA_PRIVATE_EXPONENT 0x00000123UL +#define CKA_PRIME_1 0x00000124UL +#define CKA_PRIME_2 0x00000125UL +#define CKA_EXPONENT_1 0x00000126UL +#define CKA_EXPONENT_2 0x00000127UL +#define CKA_COEFFICIENT 0x00000128UL +#define CKA_PUBLIC_KEY_INFO 0x00000129UL +#define CKA_PRIME 0x00000130UL +#define CKA_SUBPRIME 0x00000131UL +#define CKA_BASE 0x00000132UL +#define CKA_PRIME_BITS 0x00000133UL +#define CKA_SUBPRIME_BITS 0x00000134UL +#define CKA_SUB_PRIME_BITS 0x00000134UL +#define CKA_VALUE_BITS 0x00000160UL +#define CKA_VALUE_LEN 0x00000161UL +#define CKA_EXTRACTABLE 0x00000162UL +#define CKA_LOCAL 0x00000163UL +#define CKA_NEVER_EXTRACTABLE 0x00000164UL +#define CKA_ALWAYS_SENSITIVE 0x00000165UL +#define CKA_KEY_GEN_MECHANISM 0x00000166UL +#define CKA_MODIFIABLE 0x00000170UL +#define CKA_COPYABLE 0x00000171UL +#define CKA_DESTROYABLE 0x00000172UL +#define CKA_EC_PARAMS 0x00000180UL +#define CKA_EC_POINT 0x00000181UL +#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL +#define CKA_WRAP_WITH_TRUSTED 0x00000210UL +#define CKA_OTP_FORMAT 0x00000220UL +#define CKA_OTP_LENGTH 0x00000221UL +#define CKA_OTP_TIME_INTERVAL 0x00000222UL +#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL +#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL +#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL +#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL +#define CKA_OTP_COUNTER 0x0000022EUL +#define CKA_OTP_TIME 0x0000022FUL +#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL +#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL +#define CKA_OTP_SERVICE_LOGO 0x0000022CUL +#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL +#define CKA_GOSTR3410_PARAMS 0x00000250UL +#define CKA_GOSTR3411_PARAMS 0x00000251UL +#define CKA_GOST28147_PARAMS 0x00000252UL +#define CKA_HW_FEATURE_TYPE 0x00000300UL +#define CKA_RESET_ON_INIT 0x00000301UL +#define CKA_HAS_RESET 0x00000302UL +#define CKA_PIXEL_X 0x00000400UL +#define CKA_PIXEL_Y 0x00000401UL +#define CKA_RESOLUTION 0x00000402UL +#define CKA_CHAR_ROWS 0x00000403UL +#define CKA_CHAR_COLUMNS 0x00000404UL +#define CKA_COLOR 0x00000405UL +#define CKA_BITS_PER_PIXEL 0x00000406UL +#define CKA_CHAR_SETS 0x00000480UL +#define CKA_ENCODING_METHODS 0x00000481UL +#define CKA_MIME_TYPES 0x00000482UL +#define CKA_MECHANISM_TYPE 0x00000500UL +#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL +#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL +#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL +#define CKA_PROFILE_ID 0x00000601UL +#define CKA_X2RATCHET_BAG 0x00000602UL +#define CKA_X2RATCHET_BAGSIZE 0x00000603UL +#define CKA_X2RATCHET_BOBS1STMSG 0x00000604UL +#define CKA_X2RATCHET_CKR 0x00000605UL +#define CKA_X2RATCHET_CKS 0x00000606UL +#define CKA_X2RATCHET_DHP 0x00000607UL +#define CKA_X2RATCHET_DHR 0x00000608UL +#define CKA_X2RATCHET_DHS 0x00000609UL +#define CKA_X2RATCHET_HKR 0x0000060AUL +#define CKA_X2RATCHET_HKS 0x0000060BUL +#define CKA_X2RATCHET_ISALICE 0x0000060CUL +#define CKA_X2RATCHET_NHKR 0x0000060DUL +#define CKA_X2RATCHET_NHKS 0x0000060EUL +#define CKA_X2RATCHET_NR 0x0000060FUL +#define CKA_X2RATCHET_NS 0x00000610UL +#define CKA_X2RATCHET_PNS 0x00000611UL +#define CKA_X2RATCHET_RK 0x00000612UL +#define CKA_HSS_LEVELS 0x00000617UL +#define CKA_HSS_LMS_TYPE 0x00000618UL +#define CKA_HSS_LMOTS_TYPE 0x00000619UL +#define CKA_HSS_LMS_TYPES 0x0000061AUL +#define CKA_HSS_LMOTS_TYPES 0x0000061BUL +#define CKA_HSS_KEYS_REMAINING 0x0000061CUL +#define CKA_PARAMETER_SET 0x0000061DUL +#define CKA_OBJECT_VALIDATION_FLAGS 0x0000061EUL +#define CKA_VALIDATION_TYPE 0x0000061FUL +#define CKA_VALIDATION_VERSION 0x00000620UL +#define CKA_VALIDATION_LEVEL 0x00000621UL +#define CKA_VALIDATION_MODULE_ID 0x00000622UL +#define CKA_VALIDATION_FLAG 0x00000623UL +#define CKA_VALIDATION_AUTHORITY_TYPE 0x00000624UL +#define CKA_VALIDATION_COUNTRY 0x00000625UL +#define CKA_VALIDATION_CERTIFICATE_IDENTIFIER 0x00000626UL +#define CKA_VALIDATION_CERTIFICATE_URI 0x00000627UL +#define CKA_VALIDATION_VENDOR_URI 0x00000628UL +#define CKA_VALIDATION_PROFILE 0x00000629UL +#define CKA_ENCAPSULATE_TEMPLATE 0x0000062AUL +#define CKA_DECAPSULATE_TEMPLATE 0x0000062BUL +#define CKA_TRUST_SERVER_AUTH 0x0000062CUL +#define CKA_TRUST_CLIENT_AUTH 0x0000062DUL +#define CKA_TRUST_CODE_SIGNING 0x0000062EUL +#define CKA_TRUST_EMAIL_PROTECTION 0x0000062FUL +#define CKA_TRUST_IPSEC_IKE 0x00000630UL +#define CKA_TRUST_TIME_STAMPING 0x00000631UL +#define CKA_TRUST_OCSP_SIGNING 0x00000632UL +#define CKA_ENCAPSULATE 0x00000633UL +#define CKA_DECAPSULATE 0x00000634UL +#define CKA_HASH_OF_CERTIFICATE 0x00000635UL +#define CKA_PUBLIC_CRC64_VALUE 0x00000636UL +#define CKA_SEED 0x00000637UL +#define CKA_VENDOR_DEFINED 0x80000000UL +/* Array attributes */ +#define CKA_WRAP_TEMPLATE 0x40000211UL +#define CKA_UNWRAP_TEMPLATE 0x40000212UL +#define CKA_DERIVE_TEMPLATE 0x40000213UL +#define CKA_ALLOWED_MECHANISMS 0x40000600UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKA_ECDSA_PARAMS 0x00000180UL +#define CKA_SECONDARY_AUTH 0x00000200UL +#define CKA_AUTH_PIN_FLAGS 0x00000201UL +#endif + +/* CKC */ +#define CKC_X_509 0x00000000UL +#define CKC_X_509_ATTR_CERT 0x00000001UL +#define CKC_WTLS 0x00000002UL +#define CKC_VENDOR_DEFINED 0x80000000UL + +/* CKD */ +#define CKD_NULL 0x00000001UL +#define CKD_SHA1_KDF 0x00000002UL +#define CKD_SHA1_KDF_ASN1 0x00000003UL +#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL +#define CKD_SHA224_KDF 0x00000005UL +#define CKD_SHA256_KDF 0x00000006UL +#define CKD_SHA384_KDF 0x00000007UL +#define CKD_SHA512_KDF 0x00000008UL +#define CKD_CPDIVERSIFY_KDF 0x00000009UL +#define CKD_SHA3_224_KDF 0x0000000AUL +#define CKD_SHA3_256_KDF 0x0000000BUL +#define CKD_SHA3_384_KDF 0x0000000CUL +#define CKD_SHA3_512_KDF 0x0000000DUL +#define CKD_SHA1_KDF_SP800 0x0000000EUL +#define CKD_SHA224_KDF_SP800 0x0000000FUL +#define CKD_SHA256_KDF_SP800 0x00000010UL +#define CKD_SHA384_KDF_SP800 0x00000011UL +#define CKD_SHA512_KDF_SP800 0x00000012UL +#define CKD_SHA3_224_KDF_SP800 0x00000013UL +#define CKD_SHA3_256_KDF_SP800 0x00000014UL +#define CKD_SHA3_384_KDF_SP800 0x00000015UL +#define CKD_SHA3_512_KDF_SP800 0x00000016UL +#define CKD_BLAKE2B_160_KDF 0x00000017UL +#define CKD_BLAKE2B_256_KDF 0x00000018UL +#define CKD_BLAKE2B_384_KDF 0x00000019UL +#define CKD_BLAKE2B_512_KDF 0x0000001AUL + +/* CFK (array attributes) */ +#define CKF_ARRAY_ATTRIBUTE 0x40000000UL + +/* CKF (capabilities) */ +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL +#define CKF_OS_LOCKING_OK 0x00000002UL + +/* CKF (HKDF) */ +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + +/* CKF (interface) */ +#define CKF_INTERFACE_FORK_SAFE 0x00000001UL + +/* CKF (mechanism) */ +#define CKF_HW 0x00000001UL +#define CKF_MESSAGE_ENCRYPT 0x00000002UL +#define CKF_MESSAGE_DECRYPT 0x00000004UL +#define CKF_MESSAGE_SIGN 0x00000008UL +#define CKF_MESSAGE_VERIFY 0x00000010UL +#define CKF_MULTI_MESSAGE 0x00000020UL +#define CKF_MULTI_MESSGE 0x00000020UL +#define CKF_FIND_OBJECTS 0x00000040UL +#define CKF_ENCRYPT 0x00000100UL +#define CKF_DECRYPT 0x00000200UL +#define CKF_DIGEST 0x00000400UL +#define CKF_SIGN 0x00000800UL +#define CKF_SIGN_RECOVER 0x00001000UL +#define CKF_VERIFY 0x00002000UL +#define CKF_VERIFY_RECOVER 0x00004000UL +#define CKF_GENERATE 0x00008000UL +#define CKF_GENERATE_KEY_PAIR 0x00010000UL +#define CKF_WRAP 0x00020000UL +#define CKF_UNWRAP 0x00040000UL +#define CKF_DERIVE 0x00080000UL +#define CKF_EC_F_P 0x00100000UL +#define CKF_EC_F_2M 0x00200000UL +#define CKF_EC_ECPARAMETERS 0x00400000UL +#define CKF_EC_OID 0x00800000UL +#define CKF_EC_UNCOMPRESS 0x01000000UL +#define CKF_EC_COMPRESS 0x02000000UL +#define CKF_EC_CURVENAME 0x04000000UL +#define CKF_ENCAPSULATE 0x10000000UL +#define CKF_DECAPSULATE 0x20000000UL +#define CKF_EXTENSION 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKF_EC_NAMEDCURVE 0x00800000U +#endif + +/* CKF (message) */ +#define CKF_END_OF_MESSAGE 0x00000001UL + +/* CKF (OTP) */ +#define CKF_NEXT_OTP 0x00000001UL +#define CKF_EXCLUDE_TIME 0x00000002UL +#define CKF_EXCLUDE_COUNTER 0x00000004UL +#define CKF_EXCLUDE_CHALLENGE 0x00000008UL +#define CKF_EXCLUDE_PIN 0x00000010UL +#define CKF_USER_FRIENDLY_OTP 0x00000020UL + +/* CKF (parameters to functions) */ +#define CKF_DONT_BLOCK 1 + +/* CKF (session) */ +#define CKF_RW_SESSION 0x00000002UL +#define CKF_SERIAL_SESSION 0x00000004UL +#define CKF_ASYNC_SESSION 0x00000008UL + +/* CFK (slot) */ +#define CKF_TOKEN_PRESENT 0x00000001UL +#define CKF_REMOVABLE_DEVICE 0x00000002UL +#define CKF_HW_SLOT 0x00000004UL + +/* CKF (token) */ +#define CKF_RNG 0x00000001UL +#define CKF_WRITE_PROTECTED 0x00000002UL +#define CKF_LOGIN_REQUIRED 0x00000004UL +#define CKF_USER_PIN_INITIALIZED 0x00000008UL +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL +#define CKF_CLOCK_ON_TOKEN 0x00000040UL +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL +#define CKF_TOKEN_INITIALIZED 0x00000400UL +#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL +#define CKF_USER_PIN_COUNT_LOW 0x00010000UL +#define CKF_USER_PIN_FINAL_TRY 0x00020000UL +#define CKF_USER_PIN_LOCKED 0x00040000UL +#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL +#define CKF_SO_PIN_COUNT_LOW 0x00100000UL +#define CKF_SO_PIN_FINAL_TRY 0x00200000UL +#define CKF_SO_PIN_LOCKED 0x00400000UL +#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL +#define CKF_ERROR_STATE 0x01000000UL +#define CKF_SEED_RANDOM_REQUIRED 0x02000000UL +#define CKF_ASYNC_SESSION_SUPPORTED 0x04000000UL + +/* CKG (GCM) */ +#define CKG_NO_GENERATE 0x00000000UL +#define CKG_GENERATE 0x00000001UL +#define CKG_GENERATE_COUNTER 0x00000002UL +#define CKG_GENERATE_RANDOM 0x00000003UL +#define CKG_GENERATE_COUNTER_XOR 0x00000004UL + +/* CKG (MFG) */ +#define CKG_MGF1_SHA1 0x00000001UL +#define CKG_MGF1_SHA256 0x00000002UL +#define CKG_MGF1_SHA384 0x00000003UL +#define CKG_MGF1_SHA512 0x00000004UL +#define CKG_MGF1_SHA224 0x00000005UL +#define CKG_MGF1_SHA3_224 0x00000006UL +#define CKG_MGF1_SHA3_256 0x00000007UL +#define CKG_MGF1_SHA3_384 0x00000008UL +#define CKG_MGF1_SHA3_512 0x00000009UL + +/* CKH (clock) */ +#define CKH_MONOTONIC_COUNTER 0x00000001UL +#define CKH_CLOCK 0x00000002UL +#define CKH_USER_INTERFACE 0x00000003UL +#define CKH_VENDOR_DEFINED 0x80000000UL + +/* CKH (hedge type) */ +#define CKH_HEDGE_PREFERRED 0x00000000UL +#define CKH_HEDGE_REQUIRED 0x00000001UL +#define CKH_DETERMINISTIC_REQUIRED 0x00000002UL + +/* CKK */ +#define CKK_RSA 0x00000000UL +#define CKK_DSA 0x00000001UL +#define CKK_DH 0x00000002UL +#define CKK_EC 0x00000003UL +#define CKK_X9_42_DH 0x00000004UL +#define CKK_KEA 0x00000005UL +#define CKK_GENERIC_SECRET 0x00000010UL +#define CKK_RC2 0x00000011UL +#define CKK_RC4 0x00000012UL +#define CKK_DES 0x00000013UL +#define CKK_DES2 0x00000014UL +#define CKK_DES3 0x00000015UL +#define CKK_CAST 0x00000016UL +#define CKK_CAST3 0x00000017UL +#define CKK_CAST128 0x00000018UL +#define CKK_RC5 0x00000019UL +#define CKK_IDEA 0x0000001AUL +#define CKK_SKIPJACK 0x0000001BUL +#define CKK_BATON 0x0000001CUL +#define CKK_JUNIPER 0x0000001DUL +#define CKK_CDMF 0x0000001EUL +#define CKK_AES 0x0000001FUL +#define CKK_BLOWFISH 0x00000020UL +#define CKK_TWOFISH 0x00000021UL +#define CKK_SECURID 0x00000022UL +#define CKK_HOTP 0x00000023UL +#define CKK_ACTI 0x00000024UL +#define CKK_CAMELLIA 0x00000025UL +#define CKK_ARIA 0x00000026UL +#define CKK_MD5_HMAC 0x00000027UL +#define CKK_SHA_1_HMAC 0x00000028UL +#define CKK_RIPEMD128_HMAC 0x00000029UL +#define CKK_RIPEMD160_HMAC 0x0000002AUL +#define CKK_SHA256_HMAC 0x0000002BUL +#define CKK_SHA384_HMAC 0x0000002CUL +#define CKK_SHA512_HMAC 0x0000002DUL +#define CKK_SHA224_HMAC 0x0000002EUL +#define CKK_SEED 0x0000002FUL +#define CKK_GOSTR3410 0x00000030UL +#define CKK_GOSTR3411 0x00000031UL +#define CKK_GOST28147 0x00000032UL +#define CKK_CHACHA20 0x00000033UL +#define CKK_POLY1305 0x00000034UL +#define CKK_AES_XTS 0x00000035UL +#define CKK_SHA3_224_HMAC 0x00000036UL +#define CKK_SHA3_256_HMAC 0x00000037UL +#define CKK_SHA3_384_HMAC 0x00000038UL +#define CKK_SHA3_512_HMAC 0x00000039UL +#define CKK_BLAKE2B_160_HMAC 0x0000003AUL +#define CKK_BLAKE2B_256_HMAC 0x0000003BUL +#define CKK_BLAKE2B_384_HMAC 0x0000003CUL +#define CKK_BLAKE2B_512_HMAC 0x0000003DUL +#define CKK_SALSA20 0x0000003EUL +#define CKK_X2RATCHET 0x0000003FUL +#define CKK_EC_EDWARDS 0x00000040UL +#define CKK_EC_MONTGOMERY 0x00000041UL +#define CKK_HKDF 0x00000042UL +#define CKK_SHA512_224_HMAC 0x00000043UL +#define CKK_SHA512_256_HMAC 0x00000044UL +#define CKK_SHA512_T_HMAC 0x00000045UL +#define CKK_HSS 0x00000046UL +#define CKK_XMSS 0x00000047UL +#define CKK_XMSSMT 0x00000048UL +#define CKK_ML_KEM 0x00000049UL +#define CKK_ML_DSA 0x0000004AUL +#define CKK_SLH_DSA 0x0000004BUL +#define CKK_VENDOR_DEFINED 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKK_ECDSA 0x00000003UL +#define CKK_CAST5 0x00000018UL +#endif + +/* CKM */ +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL +#define CKM_RSA_PKCS 0x00000001UL +#define CKM_RSA_9796 0x00000002UL +#define CKM_RSA_X_509 0x00000003UL +#define CKM_MD2_RSA_PKCS 0x00000004UL +#define CKM_MD5_RSA_PKCS 0x00000005UL +#define CKM_SHA1_RSA_PKCS 0x00000006UL +#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL +#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL +#define CKM_RSA_PKCS_OAEP 0x00000009UL +#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL +#define CKM_RSA_X9_31 0x0000000BUL +#define CKM_SHA1_RSA_X9_31 0x0000000CUL +#define CKM_RSA_PKCS_PSS 0x0000000DUL +#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL +#define CKM_ML_KEM_KEY_PAIR_GEN 0x0000000FUL +#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL +#define CKM_DSA 0x00000011UL +#define CKM_DSA_SHA1 0x00000012UL +#define CKM_DSA_SHA224 0x00000013UL +#define CKM_DSA_SHA256 0x00000014UL +#define CKM_DSA_SHA384 0x00000015UL +#define CKM_DSA_SHA512 0x00000016UL +#define CKM_ML_KEM 0x00000017UL +#define CKM_DSA_SHA3_224 0x00000018UL +#define CKM_DSA_SHA3_256 0x00000019UL +#define CKM_DSA_SHA3_384 0x0000001AUL +#define CKM_DSA_SHA3_512 0x0000001BUL +#define CKM_ML_DSA_KEY_PAIR_GEN 0x0000001CUL +#define CKM_ML_DSA 0x0000001DUL +#define CKM_HASH_ML_DSA 0x0000001FUL +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL +#define CKM_DH_PKCS_DERIVE 0x00000021UL +#define CKM_HASH_ML_DSA_SHA224 0x00000023UL +#define CKM_HASH_ML_DSA_SHA256 0x00000024UL +#define CKM_HASH_ML_DSA_SHA384 0x00000025UL +#define CKM_HASH_ML_DSA_SHA512 0x00000026UL +#define CKM_HASH_ML_DSA_SHA3_224 0x00000027UL +#define CKM_HASH_ML_DSA_SHA3_256 0x00000028UL +#define CKM_HASH_ML_DSA_SHA3_384 0x00000029UL +#define CKM_HASH_ML_DSA_SHA3_512 0x0000002AUL +#define CKM_HASH_ML_DSA_SHAKE128 0x0000002BUL +#define CKM_HASH_ML_DSA_SHAKE256 0x0000002CUL +#define CKM_SLH_DSA_KEY_PAIR_GEN 0x0000002DUL +#define CKM_SLH_DSA 0x0000002EUL +#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL +#define CKM_X9_42_DH_DERIVE 0x00000031UL +#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL +#define CKM_X9_42_MQV_DERIVE 0x00000033UL +#define CKM_HASH_SLH_DSA 0x00000034UL +#define CKM_HASH_SLH_DSA_SHA224 0x00000036UL +#define CKM_HASH_SLH_DSA_SHA256 0x00000037UL +#define CKM_HASH_SLH_DSA_SHA384 0x00000038UL +#define CKM_HASH_SLH_DSA_SHA512 0x00000039UL +#define CKM_HASH_SLH_DSA_SHA3_224 0x0000003AUL +#define CKM_HASH_SLH_DSA_SHA3_256 0x0000003BUL +#define CKM_HASH_SLH_DSA_SHA3_384 0x0000003CUL +#define CKM_HASH_SLH_DSA_SHA3_512 0x0000003DUL +#define CKM_HASH_SLH_DSA_SHAKE128 0x0000003EUL +#define CKM_HASH_SLH_DSA_SHAKE256 0x0000003FUL +#define CKM_SHA256_RSA_PKCS 0x00000040UL +#define CKM_SHA384_RSA_PKCS 0x00000041UL +#define CKM_SHA512_RSA_PKCS 0x00000042UL +#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL +#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL +#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL +#define CKM_SHA224_RSA_PKCS 0x00000046UL +#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL +#define CKM_SHA512_224 0x00000048UL +#define CKM_SHA512_224_HMAC 0x00000049UL +#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL +#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL +#define CKM_SHA512_256 0x0000004CUL +#define CKM_SHA512_256_HMAC 0x0000004DUL +#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL +#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL +#define CKM_SHA512_T 0x00000050UL +#define CKM_SHA512_T_HMAC 0x00000051UL +#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL +#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE 0x00000056UL +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH 0x00000057UL +#define CKM_SHA3_256_RSA_PKCS 0x00000060UL +#define CKM_SHA3_384_RSA_PKCS 0x00000061UL +#define CKM_SHA3_512_RSA_PKCS 0x00000062UL +#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL +#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL +#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL +#define CKM_SHA3_224_RSA_PKCS 0x00000066UL +#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL +#define CKM_RC2_KEY_GEN 0x00000100UL +#define CKM_RC2_ECB 0x00000101UL +#define CKM_RC2_CBC 0x00000102UL +#define CKM_RC2_MAC 0x00000103UL +#define CKM_RC2_MAC_GENERAL 0x00000104UL +#define CKM_RC2_CBC_PAD 0x00000105UL +#define CKM_RC4_KEY_GEN 0x00000110UL +#define CKM_RC4 0x00000111UL +#define CKM_DES_KEY_GEN 0x00000120UL +#define CKM_DES_ECB 0x00000121UL +#define CKM_DES_CBC 0x00000122UL +#define CKM_DES_MAC 0x00000123UL +#define CKM_DES_MAC_GENERAL 0x00000124UL +#define CKM_DES_CBC_PAD 0x00000125UL +#define CKM_DES2_KEY_GEN 0x00000130UL +#define CKM_DES3_KEY_GEN 0x00000131UL +#define CKM_DES3_ECB 0x00000132UL +#define CKM_DES3_CBC 0x00000133UL +#define CKM_DES3_MAC 0x00000134UL +#define CKM_DES3_MAC_GENERAL 0x00000135UL +#define CKM_DES3_CBC_PAD 0x00000136UL +#define CKM_DES3_CMAC_GENERAL 0x00000137UL +#define CKM_DES3_CMAC 0x00000138UL +#define CKM_CDMF_KEY_GEN 0x00000140UL +#define CKM_CDMF_ECB 0x00000141UL +#define CKM_CDMF_CBC 0x00000142UL +#define CKM_CDMF_MAC 0x00000143UL +#define CKM_CDMF_MAC_GENERAL 0x00000144UL +#define CKM_CDMF_CBC_PAD 0x00000145UL +#define CKM_DES_OFB64 0x00000150UL +#define CKM_DES_OFB8 0x00000151UL +#define CKM_DES_CFB64 0x00000152UL +#define CKM_DES_CFB8 0x00000153UL +#define CKM_MD2 0x00000200UL +#define CKM_MD2_HMAC 0x00000201UL +#define CKM_MD2_HMAC_GENERAL 0x00000202UL +#define CKM_MD5 0x00000210UL +#define CKM_MD5_HMAC 0x00000211UL +#define CKM_MD5_HMAC_GENERAL 0x00000212UL +#define CKM_SHA_1 0x00000220UL +#define CKM_SHA_1_HMAC 0x00000221UL +#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL +#define CKM_RIPEMD128 0x00000230UL +#define CKM_RIPEMD128_HMAC 0x00000231UL +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL +#define CKM_RIPEMD160 0x00000240UL +#define CKM_RIPEMD160_HMAC 0x00000241UL +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL +#define CKM_SHA256 0x00000250UL +#define CKM_SHA256_HMAC 0x00000251UL +#define CKM_SHA256_HMAC_GENERAL 0x00000252UL +#define CKM_SHA224 0x00000255UL +#define CKM_SHA224_HMAC 0x00000256UL +#define CKM_SHA224_HMAC_GENERAL 0x00000257UL +#define CKM_SHA384 0x00000260UL +#define CKM_SHA384_HMAC 0x00000261UL +#define CKM_SHA384_HMAC_GENERAL 0x00000262UL +#define CKM_SHA512 0x00000270UL +#define CKM_SHA512_HMAC 0x00000271UL +#define CKM_SHA512_HMAC_GENERAL 0x00000272UL +#define CKM_SECURID_KEY_GEN 0x00000280UL +#define CKM_SECURID 0x00000282UL +#define CKM_HOTP_KEY_GEN 0x00000290UL +#define CKM_HOTP 0x00000291UL +#define CKM_ACTI 0x000002A0UL +#define CKM_ACTI_KEY_GEN 0x000002A1UL +#define CKM_SHA3_256 0x000002B0UL +#define CKM_SHA3_256_HMAC 0x000002B1UL +#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL +#define CKM_SHA3_256_KEY_GEN 0x000002B3UL +#define CKM_SHA3_224 0x000002B5UL +#define CKM_SHA3_224_HMAC 0x000002B6UL +#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL +#define CKM_SHA3_224_KEY_GEN 0x000002B8UL +#define CKM_SHA3_384 0x000002C0UL +#define CKM_SHA3_384_HMAC 0x000002C1UL +#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL +#define CKM_SHA3_384_KEY_GEN 0x000002C3UL +#define CKM_SHA3_512 0x000002D0UL +#define CKM_SHA3_512_HMAC 0x000002D1UL +#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL +#define CKM_SHA3_512_KEY_GEN 0x000002D3UL +#define CKM_CAST_KEY_GEN 0x00000300UL +#define CKM_CAST_ECB 0x00000301UL +#define CKM_CAST_CBC 0x00000302UL +#define CKM_CAST_MAC 0x00000303UL +#define CKM_CAST_MAC_GENERAL 0x00000304UL +#define CKM_CAST_CBC_PAD 0x00000305UL +#define CKM_CAST3_KEY_GEN 0x00000310UL +#define CKM_CAST3_ECB 0x00000311UL +#define CKM_CAST3_CBC 0x00000312UL +#define CKM_CAST3_MAC 0x00000313UL +#define CKM_CAST3_MAC_GENERAL 0x00000314UL +#define CKM_CAST3_CBC_PAD 0x00000315UL +#define CKM_CAST128_KEY_GEN 0x00000320UL +#define CKM_CAST128_ECB 0x00000321UL +#define CKM_CAST128_MAC 0x00000323UL +#define CKM_CAST128_CBC 0x00000322UL +#define CKM_CAST128_MAC_GENERAL 0x00000324UL +#define CKM_CAST128_CBC_PAD 0x00000325UL +#define CKM_RC5_KEY_GEN 0x00000330UL +#define CKM_RC5_ECB 0x00000331UL +#define CKM_RC5_CBC 0x00000332UL +#define CKM_RC5_MAC 0x00000333UL +#define CKM_RC5_MAC_GENERAL 0x00000334UL +#define CKM_RC5_CBC_PAD 0x00000335UL +#define CKM_IDEA_KEY_GEN 0x00000340UL +#define CKM_IDEA_ECB 0x00000341UL +#define CKM_IDEA_CBC 0x00000342UL +#define CKM_IDEA_MAC 0x00000343UL +#define CKM_IDEA_MAC_GENERAL 0x00000344UL +#define CKM_IDEA_CBC_PAD 0x00000345UL +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL +#define CKM_XOR_BASE_AND_DATA 0x00000364UL +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL +#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL +#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL +#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL +#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL +#define CKM_TLS_PRF 0x00000378UL +#define CKM_SSL3_MD5_MAC 0x00000380UL +#define CKM_SSL3_SHA1_MAC 0x00000381UL +#define CKM_MD5_KEY_DERIVATION 0x00000390UL +#define CKM_MD2_KEY_DERIVATION 0x00000391UL +#define CKM_SHA1_KEY_DERIVATION 0x00000392UL +#define CKM_SHA256_KEY_DERIVATION 0x00000393UL +#define CKM_SHA384_KEY_DERIVATION 0x00000394UL +#define CKM_SHA512_KEY_DERIVATION 0x00000395UL +#define CKM_SHA224_KEY_DERIVATION 0x00000396UL +#define CKM_SHA3_256_KEY_DERIVATION 0x00000397UL +#define CKM_SHA3_256_KEY_DERIVE 0x00000397UL +#define CKM_SHA3_224_KEY_DERIVATION 0x00000398UL +#define CKM_SHA3_224_KEY_DERIVE 0x00000398UL +#define CKM_SHA3_384_KEY_DERIVATION 0x00000399UL +#define CKM_SHA3_384_KEY_DERIVE 0x00000399UL +#define CKM_SHA3_512_KEY_DERIVATION 0x0000039AUL +#define CKM_SHA3_512_KEY_DERIVE 0x0000039AUL +#define CKM_SHAKE_128_KEY_DERIVATION 0x0000039BUL +#define CKM_SHAKE_128_KEY_DERIVE 0x0000039BUL +#define CKM_SHAKE_256_KEY_DERIVATION 0x0000039CUL +#define CKM_SHAKE_256_KEY_DERIVE 0x0000039CUL +#define CKM_PBE_MD2_DES_CBC 0x000003A0UL +#define CKM_PBE_MD5_DES_CBC 0x000003A1UL +#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL +#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL +#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL +#define CKM_PBE_SHA1_RC4_128 0x000003A6UL +#define CKM_PBE_SHA1_RC4_40 0x000003A7UL +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL +#define CKM_PKCS5_PBKD2 0x000003B0UL +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL +#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL +#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL +#define CKM_WTLS_PRF 0x000003D3UL +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL +#define CKM_TLS10_MAC_SERVER 0x000003D6UL +#define CKM_TLS10_MAC_CLIENT 0x000003D7UL +#define CKM_TLS12_MAC 0x000003D8UL +#define CKM_TLS12_KDF 0x000003D9UL +#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL +#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL +#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL +#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL +#define CKM_TLS_MAC 0x000003E4UL +#define CKM_TLS_KDF 0x000003E5UL +#define CKM_KEY_WRAP_LYNKS 0x00000400UL +#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL +#define CKM_CMS_SIG 0x00000500UL +#define CKM_KIP_DERIVE 0x00000510UL +#define CKM_KIP_WRAP 0x00000511UL +#define CKM_KIP_MAC 0x00000512UL +#define CKM_CAMELLIA_KEY_GEN 0x00000550UL +#define CKM_CAMELLIA_ECB 0x00000551UL +#define CKM_CAMELLIA_CBC 0x00000552UL +#define CKM_CAMELLIA_MAC 0x00000553UL +#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL +#define CKM_CAMELLIA_CBC_PAD 0x00000555UL +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL +#define CKM_CAMELLIA_CTR 0x00000558UL +#define CKM_ARIA_KEY_GEN 0x00000560UL +#define CKM_ARIA_ECB 0x00000561UL +#define CKM_ARIA_CBC 0x00000562UL +#define CKM_ARIA_MAC 0x00000563UL +#define CKM_ARIA_MAC_GENERAL 0x00000564UL +#define CKM_ARIA_CBC_PAD 0x00000565UL +#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL +#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL +#define CKM_SEED_KEY_GEN 0x00000650UL +#define CKM_SEED_ECB 0x00000651UL +#define CKM_SEED_CBC 0x00000652UL +#define CKM_SEED_MAC 0x00000653UL +#define CKM_SEED_MAC_GENERAL 0x00000654UL +#define CKM_SEED_CBC_PAD 0x00000655UL +#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL +#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL +#define CKM_SKIPJACK_KEY_GEN 0x00001000UL +#define CKM_SKIPJACK_ECB64 0x00001001UL +#define CKM_SKIPJACK_CBC64 0x00001002UL +#define CKM_SKIPJACK_OFB64 0x00001003UL +#define CKM_SKIPJACK_CFB64 0x00001004UL +#define CKM_SKIPJACK_CFB32 0x00001005UL +#define CKM_SKIPJACK_CFB16 0x00001006UL +#define CKM_SKIPJACK_CFB8 0x00001007UL +#define CKM_SKIPJACK_WRAP 0x00001008UL +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL +#define CKM_SKIPJACK_RELAYX 0x0000100AUL +#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL +#define CKM_KEA_KEY_DERIVE 0x00001011UL +#define CKM_KEA_DERIVE 0x00001012UL +#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL +#define CKM_BATON_KEY_GEN 0x00001030UL +#define CKM_BATON_ECB128 0x00001031UL +#define CKM_BATON_ECB96 0x00001032UL +#define CKM_BATON_CBC128 0x00001033UL +#define CKM_BATON_COUNTER 0x00001034UL +#define CKM_BATON_SHUFFLE 0x00001035UL +#define CKM_BATON_WRAP 0x00001036UL +#define CKM_EC_KEY_PAIR_GEN 0x00001040UL +#define CKM_ECDSA 0x00001041UL +#define CKM_ECDSA_SHA1 0x00001042UL +#define CKM_ECDSA_SHA224 0x00001043UL +#define CKM_ECDSA_SHA256 0x00001044UL +#define CKM_ECDSA_SHA384 0x00001045UL +#define CKM_ECDSA_SHA512 0x00001046UL +#define CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS 0x0000140BUL +#define CKM_ECDH1_DERIVE 0x00001050UL +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL +#define CKM_ECMQV_DERIVE 0x00001052UL +#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL +#define CKM_RSA_AES_KEY_WRAP 0x00001054UL +#define CKM_JUNIPER_KEY_GEN 0x00001060UL +#define CKM_JUNIPER_ECB128 0x00001061UL +#define CKM_JUNIPER_CBC128 0x00001062UL +#define CKM_JUNIPER_COUNTER 0x00001063UL +#define CKM_JUNIPER_SHUFFLE 0x00001064UL +#define CKM_JUNIPER_WRAP 0x00001065UL +#define CKM_FASTHASH 0x00001070UL +#define CKM_AES_XTS 0x00001071UL +#define CKM_AES_XTS_KEY_GEN 0x00001072UL +#define CKM_AES_KEY_GEN 0x00001080UL +#define CKM_AES_ECB 0x00001081UL +#define CKM_AES_CBC 0x00001082UL +#define CKM_AES_MAC 0x00001083UL +#define CKM_AES_MAC_GENERAL 0x00001084UL +#define CKM_AES_CBC_PAD 0x00001085UL +#define CKM_AES_CTR 0x00001086UL +#define CKM_AES_GCM 0x00001087UL +#define CKM_AES_CCM 0x00001088UL +#define CKM_AES_CTS 0x00001089UL +#define CKM_AES_CMAC 0x0000108AUL +#define CKM_AES_CMAC_GENERAL 0x0000108BUL +#define CKM_AES_XCBC_MAC 0x0000108CUL +#define CKM_AES_XCBC_MAC_96 0x0000108DUL +#define CKM_AES_GMAC 0x0000108EUL +#define CKM_BLOWFISH_KEY_GEN 0x00001090UL +#define CKM_BLOWFISH_CBC 0x00001091UL +#define CKM_TWOFISH_KEY_GEN 0x00001092UL +#define CKM_TWOFISH_CBC 0x00001093UL +#define CKM_BLOWFISH_CBC_PAD 0x00001094UL +#define CKM_TWOFISH_CBC_PAD 0x00001095UL +#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL +#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL +#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL +#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL +#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL +#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL +#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL +#define CKM_GOSTR3410 0x00001201UL +#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL +#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL +#define CKM_GOSTR3410_DERIVE 0x00001204UL +#define CKM_GOSTR3411 0x00001210UL +#define CKM_GOSTR3411_HMAC 0x00001211UL +#define CKM_GOST28147_KEY_GEN 0x00001220UL +#define CKM_GOST28147_ECB 0x00001221UL +#define CKM_GOST28147 0x00001222UL +#define CKM_GOST28147_MAC 0x00001223UL +#define CKM_GOST28147_KEY_WRAP 0x00001224UL +#define CKM_CHACHA20_KEY_GEN 0x00001225UL +#define CKM_CHACHA20 0x00001226UL +#define CKM_POLY1305_KEY_GEN 0x00001227UL +#define CKM_POLY1305 0x00001228UL +#define CKM_DSA_PARAMETER_GEN 0x00002000UL +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL +#define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL +#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL +#define CKM_DSA_FIPS_G_GEN 0x00002005UL +#define CKM_AES_OFB 0x00002104UL +#define CKM_AES_CFB64 0x00002105UL +#define CKM_AES_CFB8 0x00002106UL +#define CKM_AES_CFB128 0x00002107UL +#define CKM_AES_CFB1 0x00002108UL +#define CKM_AES_KEY_WRAP 0x00002109UL +#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL +#define CKM_AES_KEY_WRAP_KWP 0x0000210BUL +#define CKM_AES_KEY_WRAP_PKCS7 0x0000210CUL +#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL +#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL +#define CKM_SHA_1_KEY_GEN 0x00004003UL +#define CKM_SHA224_KEY_GEN 0x00004004UL +#define CKM_SHA256_KEY_GEN 0x00004005UL +#define CKM_SHA384_KEY_GEN 0x00004006UL +#define CKM_SHA512_KEY_GEN 0x00004007UL +#define CKM_SHA512_224_KEY_GEN 0x00004008UL +#define CKM_SHA512_256_KEY_GEN 0x00004009UL +#define CKM_SHA512_T_KEY_GEN 0x0000400AUL +#define CKM_NULL 0x0000400BUL +#define CKM_BLAKE2B_160 0x0000400CUL +#define CKM_BLAKE2B_160_HMAC 0x0000400DUL +#define CKM_BLAKE2B_160_HMAC_GENERAL 0x0000400EUL +#define CKM_BLAKE2B_160_KEY_DERIVE 0x0000400FUL +#define CKM_BLAKE2B_160_KEY_GEN 0x00004010UL +#define CKM_BLAKE2B_256 0x00004011UL +#define CKM_BLAKE2B_256_HMAC 0x00004012UL +#define CKM_BLAKE2B_256_HMAC_GENERAL 0x00004013UL +#define CKM_BLAKE2B_256_KEY_DERIVE 0x00004014UL +#define CKM_BLAKE2B_256_KEY_GEN 0x00004015UL +#define CKM_BLAKE2B_384 0x00004016UL +#define CKM_BLAKE2B_384_HMAC 0x00004017UL +#define CKM_BLAKE2B_384_HMAC_GENERAL 0x00004018UL +#define CKM_BLAKE2B_384_KEY_DERIVE 0x00004019UL +#define CKM_BLAKE2B_384_KEY_GEN 0x0000401AUL +#define CKM_BLAKE2B_512 0x0000401BUL +#define CKM_BLAKE2B_512_HMAC 0x0000401CUL +#define CKM_BLAKE2B_512_HMAC_GENERAL 0x0000401DUL +#define CKM_BLAKE2B_512_KEY_DERIVE 0x0000401EUL +#define CKM_BLAKE2B_512_KEY_GEN 0x0000401FUL +#define CKM_SALSA20 0x00004020UL +#define CKM_CHACHA20_POLY1305 0x00004021UL +#define CKM_SALSA20_POLY1305 0x00004022UL +#define CKM_X3DH_INITIALIZE 0x00004023UL +#define CKM_X3DH_RESPOND 0x00004024UL +#define CKM_X2RATCHET_INITIALIZE 0x00004025UL +#define CKM_X2RATCHET_RESPOND 0x00004026UL +#define CKM_X2RATCHET_ENCRYPT 0x00004027UL +#define CKM_X2RATCHET_DECRYPT 0x00004028UL +#define CKM_XEDDSA 0x00004029UL +#define CKM_HKDF_DERIVE 0x0000402AUL +#define CKM_HKDF_DATA 0x0000402BUL +#define CKM_HKDF_KEY_GEN 0x0000402CUL +#define CKM_SALSA20_KEY_GEN 0x0000402DUL +#define CKM_ECDSA_SHA3_224 0x00001047UL +#define CKM_ECDSA_SHA3_256 0x00001048UL +#define CKM_ECDSA_SHA3_384 0x00001049UL +#define CKM_ECDSA_SHA3_512 0x0000104AUL +#define CKM_EC_EDWARDS_KEY_PAIR_GEN 0x00001055UL +#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN 0x00001056UL +#define CKM_EDDSA 0x00001057UL +#define CKM_SP800_108_COUNTER_KDF 0x000003ACUL +#define CKM_SP800_108_FEEDBACK_KDF 0x000003ADUL +#define CKM_SP800_108_DOUBLE_PIPELINE_KDF 0x000003AEUL +#define CKM_IKE2_PRF_PLUS_DERIVE 0x0000402EUL +#define CKM_IKE_PRF_DERIVE 0x0000402FUL +#define CKM_IKE1_PRF_DERIVE 0x00004030UL +#define CKM_IKE1_EXTENDED_DERIVE 0x00004031UL +#define CKM_HSS_KEY_PAIR_GEN 0x00004032UL +#define CKM_HSS 0x00004033UL +#define CKM_XMSS_KEY_PAIR_GEN 0x00004034UL +#define CKM_XMSSMT_KEY_PAIR_GEN 0x00004035UL +#define CKM_XMSS 0x00004036UL +#define CKM_XMSSMT 0x00004037UL +#define CKM_ECDH_X_AES_KEY_WRAP 0x00004038UL +#define CKM_ECDH_COF_AES_KEY_WRAP 0x00004039UL +#define CKM_PUB_KEY_FROM_PRIV_KEY 0x0000403AUL +#define CKM_VENDOR_DEFINED 0x80000000UL +/* Deprecated */ +#ifdef PKCS11_DEPRECATED +#define CKM_CAST5_KEY_GEN 0x00000320UL +#define CKM_CAST5_ECB 0x00000321UL +#define CKM_CAST5_CBC 0x00000322UL +#define CKM_CAST5_MAC 0x00000323UL +#define CKM_CAST5_MAC_GENERAL 0x00000324UL +#define CKM_CAST5_CBC_PAD 0x00000325UL +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL +#endif + +/* CKN */ +#define CKN_SURRENDER 0UL +#define CKN_OTP_CHANGED 1UL + +/* CKO */ +#define CKO_DATA 0x00000000UL +#define CKO_CERTIFICATE 0x00000001UL +#define CKO_PUBLIC_KEY 0x00000002UL +#define CKO_PRIVATE_KEY 0x00000003UL +#define CKO_SECRET_KEY 0x00000004UL +#define CKO_HW_FEATURE 0x00000005UL +#define CKO_DOMAIN_PARAMETERS 0x00000006UL +#define CKO_MECHANISM 0x00000007UL +#define CKO_OTP_KEY 0x00000008UL +#define CKO_PROFILE 0x00000009UL +#define CKO_VALIDATION 0x0000000AUL +#define CKO_TRUST 0x0000000BUL +#define CKO_VENDOR_DEFINED 0x80000000UL + +/* CKP (profile) */ +#define CKP_INVALID_ID 0x00000000UL +#define CKP_BASELINE_PROVIDER 0x00000001UL +#define CKP_EXTENDED_PROVIDER 0x00000002UL +#define CKP_AUTHENTICATION_TOKEN 0x00000003UL +#define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL +#define CKP_COMPLETE_PROVIDER 0x00000005UL +#define CKP_HKDF_TLS_TOKEN 0x00000006UL +#define CKP_VENDOR_DEFINED 0x80000000UL + +/* CKP (PBKD2) */ +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL +#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL +#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL +#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL +#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL +#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL + +/* CKP (ML-DSA) */ +#define CKP_ML_DSA_44 0x00000001UL +#define CKP_ML_DSA_65 0x00000002UL +#define CKP_ML_DSA_87 0x00000003UL + +/* CKP (ML_KEM) */ +#define CKP_ML_KEM_512 0x00000001UL +#define CKP_ML_KEM_768 0x00000002UL +#define CKP_ML_KEM_1024 0x00000003UL + +/* CKP (SLH-DSA) */ +#define CKP_SLH_DSA_SHA2_128S 0x00000001UL +#define CKP_SLH_DSA_SHAKE_128S 0x00000002UL +#define CKP_SLH_DSA_SHA2_128F 0x00000003UL +#define CKP_SLH_DSA_SHAKE_128F 0x00000004UL +#define CKP_SLH_DSA_SHA2_192S 0x00000005UL +#define CKP_SLH_DSA_SHAKE_192S 0x00000006UL +#define CKP_SLH_DSA_SHA2_192F 0x00000007UL +#define CKP_SLH_DSA_SHAKE_192F 0x00000008UL +#define CKP_SLH_DSA_SHA2_256S 0x00000009UL +#define CKP_SLH_DSA_SHAKE_256S 0x0000000AUL +#define CKP_SLH_DSA_SHA2_256F 0x0000000BUL +#define CKP_SLH_DSA_SHAKE_256F 0x0000000CUL + +/* CKR */ +#define CKR_OK 0x00000000UL +#define CKR_CANCEL 0x00000001UL +#define CKR_HOST_MEMORY 0x00000002UL +#define CKR_SLOT_ID_INVALID 0x00000003UL +#define CKR_GENERAL_ERROR 0x00000005UL +#define CKR_FUNCTION_FAILED 0x00000006UL +#define CKR_ARGUMENTS_BAD 0x00000007UL +#define CKR_NO_EVENT 0x00000008UL +#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL +#define CKR_CANT_LOCK 0x0000000AUL +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL +#define CKR_ACTION_PROHIBITED 0x0000001BUL +#define CKR_DATA_INVALID 0x00000020UL +#define CKR_DATA_LEN_RANGE 0x00000021UL +#define CKR_DEVICE_ERROR 0x00000030UL +#define CKR_DEVICE_MEMORY 0x00000031UL +#define CKR_DEVICE_REMOVED 0x00000032UL +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL +#define CKR_AEAD_DECRYPT_FAILED 0x00000042UL +#define CKR_FUNCTION_CANCELED 0x00000050UL +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL +#define CKR_KEY_HANDLE_INVALID 0x00000060UL +#define CKR_KEY_SIZE_RANGE 0x00000062UL +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL +#define CKR_KEY_NOT_NEEDED 0x00000064UL +#define CKR_KEY_CHANGED 0x00000065UL +#define CKR_KEY_NEEDED 0x00000066UL +#define CKR_KEY_INDIGESTIBLE 0x00000067UL +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL +#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL +#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL +#define CKR_MECHANISM_INVALID 0x00000070UL +#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL +#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL +#define CKR_OPERATION_ACTIVE 0x00000090UL +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL +#define CKR_PIN_INCORRECT 0x000000A0UL +#define CKR_PIN_INVALID 0x000000A1UL +#define CKR_PIN_LEN_RANGE 0x000000A2UL +#define CKR_PIN_EXPIRED 0x000000A3UL +#define CKR_PIN_LOCKED 0x000000A4UL +#define CKR_SESSION_CLOSED 0x000000B0UL +#define CKR_SESSION_COUNT 0x000000B1UL +#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL +#define CKR_SESSION_READ_ONLY 0x000000B5UL +#define CKR_SESSION_EXISTS 0x000000B6UL +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL +#define CKR_SIGNATURE_INVALID 0x000000C0UL +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL +#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL +#define CKR_USER_NOT_LOGGED_IN 0x00000101UL +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL +#define CKR_USER_TYPE_INVALID 0x00000103UL +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL +#define CKR_USER_TOO_MANY_TYPES 0x00000105UL +#define CKR_WRAPPED_KEY_INVALID 0x00000110UL +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL +#define CKR_RANDOM_NO_RNG 0x00000121UL +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL +#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL +#define CKR_BUFFER_TOO_SMALL 0x00000150UL +#define CKR_SAVED_STATE_INVALID 0x00000160UL +#define CKR_INFORMATION_SENSITIVE 0x00000170UL +#define CKR_STATE_UNSAVEABLE 0x00000180UL +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL +#define CKR_MUTEX_BAD 0x000001A0UL +#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL +#define CKR_NEW_PIN_MODE 0x000001B0UL +#define CKR_NEXT_OTP 0x000001B1UL +#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL +#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL +#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL +#define CKR_PIN_TOO_WEAK 0x000001B8UL +#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL +#define CKR_FUNCTION_REJECTED 0x00000200UL +#define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL +#define CKR_OPERATION_CANCEL_FAILED 0x00000202UL +#define CKR_KEY_EXHAUSTED 0x00000203UL +#define CKR_PENDING 0x00000204UL +#define CKR_SESSION_ASYNC_NOT_SUPPORTED 0x00000205UL +#define CKR_SEED_RANDOM_REQUIRED 0x00000206UL +#define CKR_OPERATION_NOT_VALIDATED 0x00000207UL +#define CKR_TOKEN_NOT_INITIALIZED 0x00000208UL +#define CKR_PARAMETER_SET_NOT_SUPPORTED 0x00000209UL +#define CKR_VENDOR_DEFINED 0x80000000UL + +/* CKS */ +#define CKS_RO_PUBLIC_SESSION 0UL +#define CKS_RO_USER_FUNCTIONS 1UL +#define CKS_RW_PUBLIC_SESSION 2UL +#define CKS_RW_USER_FUNCTIONS 3UL +#define CKS_RW_SO_FUNCTIONS 4UL + +/* CKS (validation) */ +#define CKS_LAST_VALIDATION_OK 0x00000001UL + +/* CKT (trust) */ +#define CKT_TRUST_UNKNOWN 0x00000000UL +#define CKT_TRUSTED 0x00000001UL +#define CKT_TRUST_ANCHOR 0x00000002UL +#define CKT_NOT_TRUSTED 0x00000003UL +#define CKT_TRUST_MUST_VERIFY_TRUST 0x00000004UL + +/* CKU */ +#define CKU_SO 0UL +#define CKU_USER 1UL +#define CKU_CONTEXT_SPECIFIC 2UL + +/* CKV (validation authority) */ +#define CKV_AUTHORITY_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_AUTHORITY_TYPE_NIST_CMVP 0x00000001UL +#define CKV_AUTHORITY_TYPE_COMMON_CRITERIA 0x00000002UL + +/* CKV (validation type) */ +#define CKV_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_TYPE_SOFTWARE 0x00000001UL +#define CKV_TYPE_HARDWARE 0x00000002UL +#define CKV_TYPE_FIRMWARE 0x00000003UL +#define CKV_TYPE_HYBRID 0x00000004UL + +/* CKZ (data) */ +#define CKZ_DATA_SPECIFIED 0x00000001UL + +/* CKZ (salt) */ +#define CKZ_SALT_SPECIFIED 0x00000001UL + +/* Sundry structures type definition in alphabetical order */ +#define STRUCTDEF(__name__) \ +struct __name__; \ +typedef struct __name__ __name__; \ +typedef struct __name__ * __name__ ## _PTR; \ +typedef struct __name__ ** __name__ ## _PTR_PTR; + +STRUCTDEF(CK_ATTRIBUTE); +STRUCTDEF(CK_C_INITIALIZE_ARGS); +STRUCTDEF(CK_DATE); +STRUCTDEF(CK_DERIVED_KEY); +STRUCTDEF(CK_FUNCTION_LIST); +STRUCTDEF(CK_FUNCTION_LIST_3_0); +STRUCTDEF(CK_FUNCTION_LIST_3_2); +STRUCTDEF(CK_INFO); +STRUCTDEF(CK_INTERFACE); +STRUCTDEF(CK_MECHANISM); +STRUCTDEF(CK_MECHANISM_INFO); +STRUCTDEF(CK_SESSION_INFO); +STRUCTDEF(CK_SLOT_INFO); +STRUCTDEF(CK_TOKEN_INFO); +STRUCTDEF(CK_VERSION); + +/* Function type definitions */ +typedef CK_RV (* CK_NOTIFY)(CK_SESSION_HANDLE, CK_NOTIFICATION, void *); +typedef CK_RV (* CK_CREATEMUTEX)(void **); +typedef CK_RV (* CK_DESTROYMUTEX)(void *); +typedef CK_RV (* CK_LOCKMUTEX)(void *); +typedef CK_RV (* CK_UNLOCKMUTEX)(void *); + +/* General Structure definitions */ +struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + void * pValue; + CK_ULONG ulValueLen; +}; + +struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + void * pReserved; +}; + +struct CK_DATE{ + CK_CHAR year[4]; + CK_CHAR month[2]; + CK_CHAR day[2]; +}; + +struct CK_DERIVED_KEY +{ + CK_ATTRIBUTE * pTemplate; + CK_ULONG ulAttributeCount; + CK_OBJECT_HANDLE * phKey; +}; + +struct CK_VERSION { + CK_BYTE major; + CK_BYTE minor; +}; + +struct CK_INFO { + struct CK_VERSION cryptokiVersion; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + CK_UTF8CHAR libraryDescription[32]; + struct CK_VERSION libraryVersion; +}; + +struct CK_INTERFACE { + CK_UTF8CHAR * pInterfaceName; + void * pFunctionList; + CK_FLAGS flags; +}; + +struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + void * pParameter; + CK_ULONG ulParameterLen; +}; + +struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +}; + +struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; + CK_ULONG ulDeviceError; +}; + +struct CK_SLOT_INFO { + CK_UTF8CHAR slotDescription[64]; + CK_UTF8CHAR manufacturerID[32]; + CK_FLAGS flags; + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; +}; + +struct CK_TOKEN_INFO { + CK_UTF8CHAR label[32]; + CK_UTF8CHAR manufacturerID[32]; + CK_UTF8CHAR model[16]; + CK_CHAR serialNumber[16]; + CK_FLAGS flags; + CK_ULONG ulMaxSessionCount; + CK_ULONG ulSessionCount; + CK_ULONG ulMaxRwSessionCount; + CK_ULONG ulRwSessionCount; + CK_ULONG ulMaxPinLen; + CK_ULONG ulMinPinLen; + CK_ULONG ulTotalPublicMemory; + CK_ULONG ulFreePublicMemory; + CK_ULONG ulTotalPrivateMemory; + CK_ULONG ulFreePrivateMemory; + CK_VERSION hardwareVersion; + CK_VERSION firmwareVersion; + CK_CHAR utcTime[16]; +}; + +/* Param Structure definitions in alphabetical order */ +STRUCTDEF(CK_AES_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_AES_CCM_PARAMS); +STRUCTDEF(CK_AES_CTR_PARAMS); +STRUCTDEF(CK_AES_GCM_PARAMS); +STRUCTDEF(CK_ARIA_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_ASYNC_DATA); +STRUCTDEF(CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_CAMELLIA_CTR_PARAMS); +STRUCTDEF(CK_CCM_MESSAGE_PARAMS); +STRUCTDEF(CK_CCM_PARAMS); +STRUCTDEF(CK_CCM_WRAP_PARAMS); +STRUCTDEF(CK_CHACHA20_PARAMS); +STRUCTDEF(CK_CMS_SIG_PARAMS); +STRUCTDEF(CK_DES_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_DSA_PARAMETER_GEN_PARAM); +STRUCTDEF(CK_ECDH_AES_KEY_WRAP_PARAMS); +STRUCTDEF(CK_ECDH1_DERIVE_PARAMS); +STRUCTDEF(CK_ECDH2_DERIVE_PARAMS); +STRUCTDEF(CK_ECMQV_DERIVE_PARAMS); +STRUCTDEF(CK_EDDSA_PARAMS); +STRUCTDEF(CK_GCM_MESSAGE_PARAMS); +STRUCTDEF(CK_GCM_PARAMS); +STRUCTDEF(CK_GCM_WRAP_PARAMS); +STRUCTDEF(CK_GOSTR3410_DERIVE_PARAMS); +STRUCTDEF(CK_GOSTR3410_KEY_WRAP_PARAMS); +STRUCTDEF(CK_HASH_SIGN_ADDITIONAL_CONTEXT); +STRUCTDEF(CK_HKDF_PARAMS); +STRUCTDEF(CK_IKE_PRF_DERIVE_PARAMS); +STRUCTDEF(CK_IKE1_EXTENDED_DERIVE_PARAMS); +STRUCTDEF(CK_IKE1_PRF_DERIVE_PARAMS); +STRUCTDEF(CK_IKE2_PRF_PLUS_DERIVE_PARAMS); +STRUCTDEF(CK_KEA_DERIVE_PARAMS); +STRUCTDEF(CK_KEY_DERIVATION_STRING_DATA); +STRUCTDEF(CK_KEY_WRAP_SET_OAEP_PARAMS); +STRUCTDEF(CK_KIP_PARAMS); +STRUCTDEF(CK_OTP_PARAM); +STRUCTDEF(CK_OTP_PARAMS); +STRUCTDEF(CK_OTP_SIGNATURE_INFO); +STRUCTDEF(CK_PBE_PARAMS); +STRUCTDEF(CK_PKCS5_PBKD2_PARAMS); +STRUCTDEF(CK_PKCS5_PBKD2_PARAMS2); +STRUCTDEF(CK_PRF_DATA_PARAM); +STRUCTDEF(CK_RC2_CBC_PARAMS); +STRUCTDEF(CK_RC2_MAC_GENERAL_PARAMS); +STRUCTDEF(CK_RC5_CBC_PARAMS); +STRUCTDEF(CK_RC5_MAC_GENERAL_PARAMS); +STRUCTDEF(CK_RC5_PARAMS); +STRUCTDEF(CK_RSA_AES_KEY_WRAP_PARAMS); +STRUCTDEF(CK_RSA_PKCS_OAEP_PARAMS); +STRUCTDEF(CK_RSA_PKCS_PSS_PARAMS); +STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS); +STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_PARAMS); +STRUCTDEF(CK_SALSA20_PARAMS); +STRUCTDEF(CK_SEED_CBC_ENCRYPT_DATA_PARAMS); +STRUCTDEF(CK_SIGN_ADDITIONAL_CONTEXT); +STRUCTDEF(CK_SKIPJACK_PRIVATE_WRAP_PARAMS); +STRUCTDEF(CK_SKIPJACK_RELAYX_PARAMS); +STRUCTDEF(CK_SP800_108_COUNTER_FORMAT); +STRUCTDEF(CK_SP800_108_DKM_LENGTH_FORMAT); +STRUCTDEF(CK_SP800_108_FEEDBACK_KDF_PARAMS); +STRUCTDEF(CK_SP800_108_KDF_PARAMS); +STRUCTDEF(CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_X2RATCHET_INITIALIZE_PARAMS); +STRUCTDEF(CK_X2RATCHET_RESPOND_PARAMS); +STRUCTDEF(CK_X3DH_INITIATE_PARAMS); +STRUCTDEF(CK_X3DH_RESPOND_PARAMS); +STRUCTDEF(CK_X9_42_DH1_DERIVE_PARAMS); +STRUCTDEF(CK_X9_42_DH2_DERIVE_PARAMS); +STRUCTDEF(CK_X9_42_MQV_DERIVE_PARAMS); +STRUCTDEF(CK_XEDDSA_PARAMS); +STRUCTDEF(specifiedParams); + +struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; + +struct CK_AES_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; + +struct CK_AES_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +}; + +struct CK_AES_GCM_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; + +struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; + +struct CK_ASYNC_DATA { + CK_ULONG ulVersion; + CK_BYTE * pValue; + CK_ULONG ulValue; + CK_OBJECT_HANDLE hObject; + CK_OBJECT_HANDLE hAdditionalObject; +}; + +struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; + +struct CK_CAMELLIA_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +}; + +struct CK_CCM_MESSAGE_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; + CK_GENERATOR_FUNCTION nonceGenerator; + CK_BYTE * pMAC; + CK_ULONG ulMACLen; +}; + +struct CK_CCM_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; +struct CK_CCM_WRAP_PARAMS { + CK_ULONG ulDataLen; + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; + CK_GENERATOR_FUNCTION nonceGenerator; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +}; + +struct CK_CHACHA20_PARAMS { + CK_BYTE * pBlockCounter; + CK_ULONG blockCounterBits; + CK_BYTE * pNonce; + CK_ULONG ulNonceBits; +}; + +struct CK_CMS_SIG_PARAMS { + CK_OBJECT_HANDLE certificateHandle; + CK_MECHANISM * pSigningMechanism; + CK_MECHANISM * pDigestMechanism; + CK_UTF8CHAR * pContentType; + CK_BYTE * pRequestedAttributes; + CK_ULONG ulRequestedAttributesLen; + CK_BYTE * pRequiredAttributes; + CK_ULONG ulRequiredAttributesLen; +}; + +struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[8]; + CK_BYTE * pData; + CK_ULONG length; +}; + +struct CK_DSA_PARAMETER_GEN_PARAM { + CK_MECHANISM_TYPE hash; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_ULONG ulIndex; +}; + +struct CK_ECDH_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; +}; + +struct CK_ECDH1_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; +}; + +struct CK_ECDH2_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; +}; + +struct CK_ECMQV_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE * pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; + CK_OBJECT_HANDLE publicKey; +}; + +struct CK_EDDSA_PARAMS { + CK_BBOOL phFlag; + CK_ULONG ulContextDataLen; + CK_BYTE * pContextData; +}; + +struct CK_GCM_MESSAGE_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + CK_BYTE * pTag; + CK_ULONG ulTagBits; +}; + +struct CK_GCM_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; + +struct CK_GCM_WRAP_PARAMS { + CK_BYTE * pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +}; + +struct CK_GOSTR3410_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_BYTE * pPublicData; + CK_ULONG ulPublicDataLen; + CK_BYTE * pUKM; + CK_ULONG ulUKMLen; +}; + +struct CK_GOSTR3410_KEY_WRAP_PARAMS { + CK_BYTE * pWrapOID; + CK_ULONG ulWrapOIDLen; + CK_BYTE * pUKM; + CK_ULONG ulUKMLen; + CK_OBJECT_HANDLE hKey; +}; + +struct CK_HASH_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE * pContext; + CK_ULONG ulContextLen; + CK_MECHANISM_TYPE hash; +}; + +struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE * pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE * pInfo; + CK_ULONG ulInfoLen; +}; + +struct CK_IKE_PRF_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bDataAsKey; + CK_BBOOL bRekey; + CK_BYTE * pNi; + CK_ULONG ulNiLen; + CK_BYTE * pNr; + CK_ULONG ulNrLen; + CK_OBJECT_HANDLE hNewKey; +}; + +struct CK_IKE1_EXTENDED_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasKeygxy; + CK_OBJECT_HANDLE hKeygxy; + CK_BYTE * pExtraData; + CK_ULONG ulExtraDataLen; +}; + +struct CK_IKE1_PRF_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasPrevKey; + CK_OBJECT_HANDLE hKeygxy; + CK_OBJECT_HANDLE hPrevKey; + CK_BYTE * pCKYi; + CK_ULONG ulCKYiLen; + CK_BYTE * pCKYr; + CK_ULONG ulCKYrLen; + CK_BYTE keyNumber; +}; + +struct CK_IKE2_PRF_PLUS_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasSeedKey; + CK_OBJECT_HANDLE hSeedKey; + CK_BYTE * pSeedData; + CK_ULONG ulSeedDataLen; +}; + +struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE * RandomA; + CK_BYTE * RandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE * PublicData; +}; + +struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE * pData; + CK_ULONG ulLen; +}; + +struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; + CK_BYTE * pX; + CK_ULONG ulXLen; +}; + +struct CK_KIP_PARAMS { + CK_MECHANISM * pMechanism; + CK_OBJECT_HANDLE hKey; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; +}; + +struct CK_OTP_PARAM { + CK_OTP_PARAM_TYPE type; + void * pValue; + CK_ULONG ulValueLen; +}; + +struct CK_OTP_PARAMS { + CK_OTP_PARAM * pParams; + CK_ULONG ulCount; +}; + +struct CK_OTP_SIGNATURE_INFO { + CK_OTP_PARAM * pParams; + CK_ULONG ulCount; +}; + +struct CK_PBE_PARAMS { + CK_BYTE * pInitVector; + CK_UTF8CHAR * pPassword; + CK_ULONG ulPasswordLen; + CK_BYTE * pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; +}; + +struct CK_PKCS5_PBKD2_PARAMS { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + void * pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + void * pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR * pPassword; + CK_ULONG * ulPasswordLen; +}; + +struct CK_PKCS5_PBKD2_PARAMS2 { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + void * pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + void * pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR * pPassword; + CK_ULONG ulPasswordLen; +}; + +struct CK_PRF_DATA_PARAM { + CK_PRF_DATA_TYPE type; + void * pValue; + CK_ULONG ulValueLen; +}; + +struct CK_RC2_CBC_PARAMS { + CK_ULONG ulEffectiveBits; + CK_BYTE iv[8]; +}; + +struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG ulEffectiveBits; + CK_ULONG ulMacLength; +}; + +struct CK_RC5_CBC_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; + CK_BYTE * pIv; + CK_ULONG ulIvLen; +}; + +struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; + CK_ULONG ulMacLength; +}; + +struct CK_RC5_PARAMS { + CK_ULONG ulWordsize; + CK_ULONG ulRounds; +}; + +struct CK_RSA_AES_KEY_WRAP_PARAMS { + CK_ULONG ulAESKeyBits; + CK_RSA_PKCS_OAEP_PARAMS * pOAEPParams; +}; + +struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + void * pSourceData; + CK_ULONG ulSourceDataLen; +}; + +struct CK_RSA_PKCS_PSS_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_ULONG sLen; +}; + +struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pTag; +}; + +struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { + CK_BYTE * pNonce; + CK_ULONG ulNonceLen; + CK_BYTE * pAAD; + CK_ULONG ulAADLen; +}; + +struct CK_SALSA20_PARAMS { + CK_BYTE * pBlockCounter; + CK_BYTE * pNonce; + CK_ULONG ulNonceBits; +}; + +struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE * pData; + CK_ULONG length; +}; + +struct CK_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE * pContext; + CK_ULONG ulContextLen; +}; + +struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE * pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE * pRandomA; + CK_BYTE * pPrimeP; + CK_BYTE * pBaseG; + CK_BYTE * pSubprimeQ; +}; + +struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE * pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE * pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE * pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE * pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE * pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE * pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE * pNewRandomA; +}; + +struct CK_SP800_108_COUNTER_FORMAT { + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; +}; + +struct CK_SP800_108_DKM_LENGTH_FORMAT { + CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; +}; + +typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; + +struct CK_SP800_108_FEEDBACK_KDF_PARAMS +{ + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM * pDataParams; + CK_ULONG ulIVLen; + CK_BYTE * pIV; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY * pAdditionalDerivedKeys; +}; + +struct CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_BYTE * pSessionHash; + CK_ULONG ulSessionHashLen; + CK_VERSION * pVersion; +}; + +struct CK_SP800_108_KDF_PARAMS +{ + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM * pDataParams; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY * pAdditionalDerivedKeys; +}; + +struct CK_X2RATCHET_INITIALIZE_PARAMS { + CK_BYTE * sk; + CK_OBJECT_HANDLE peer_public_prekey; + CK_OBJECT_HANDLE peer_public_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; +}; + +struct CK_X2RATCHET_RESPOND_PARAMS { + CK_BYTE * sk; + CK_OBJECT_HANDLE own_prekey; + CK_OBJECT_HANDLE initiator_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; +}; + +struct CK_X3DH_INITIATE_PARAMS { + CK_X3DH_KDF_TYPE kdf; + CK_OBJECT_HANDLE pPeer_identity; + CK_OBJECT_HANDLE pPeer_prekey; + CK_BYTE * pPrekey_signature; + CK_BYTE * pOnetime_key; + CK_OBJECT_HANDLE pOwn_identity; + CK_OBJECT_HANDLE pOwn_ephemeral; +}; + +struct CK_X3DH_RESPOND_PARAMS { + CK_X3DH_KDF_TYPE kdf; + CK_BYTE * pIdentity_id; + CK_BYTE * pPrekey_id; + CK_BYTE * pOnetime_id; + CK_OBJECT_HANDLE pInitiator_identity; + CK_BYTE * pInitiator_ephemeral; +}; + +struct CK_X9_42_DH1_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; +}; + +struct CK_X9_42_DH2_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * pPublicData2; +}; + +struct CK_X9_42_MQV_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE * OtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE * PublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE * PublicData2; + CK_OBJECT_HANDLE publicKey; +}; + +struct CK_XEDDSA_PARAMS { + CK_XEDDSA_HASH_TYPE hash; +}; + +/* TLS related structure definitions */ +STRUCTDEF(CK_SSL3_KEY_MAT_OUT); +STRUCTDEF(CK_SSL3_KEY_MAT_PARAMS); +STRUCTDEF(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_SSL3_RANDOM_DATA); +STRUCTDEF(CK_TLS_KDF_PARAMS); +STRUCTDEF(CK_TLS_MAC_PARAMS); +STRUCTDEF(CK_TLS_PRF_PARAMS); +STRUCTDEF(CK_TLS12_KEY_MAT_PARAMS); +STRUCTDEF(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_WTLS_KEY_MAT_OUT); +STRUCTDEF(CK_WTLS_KEY_MAT_PARAMS); +STRUCTDEF(CK_WTLS_MASTER_KEY_DERIVE_PARAMS); +STRUCTDEF(CK_WTLS_PRF_PARAMS); +STRUCTDEF(CK_WTLS_RANDOM_DATA); + +struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE * pIVClient; + CK_BYTE * pIVServer; +}; + +struct CK_SSL3_RANDOM_DATA { + CK_BYTE * pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE * pServerRandom; + CK_ULONG ulServerRandomLen; +}; + +struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; +}; + +struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION * pVersion; +}; + +struct CK_TLS_KDF_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_BYTE * pLabel; + CK_ULONG ulLabelLength; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_BYTE * pContextData; + CK_ULONG ulContextDataLength; +}; + +struct CK_TLS_MAC_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulMacLength; + CK_ULONG ulServerOrClient; +}; + +struct CK_TLS_PRF_PARAMS { + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_BYTE * pLabel; + CK_ULONG ulLabelLen; + CK_BYTE * pOutput; + CK_ULONG * pulOutputLen; +}; + +struct CK_TLS12_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; + CK_MECHANISM_TYPE prfHashMechanism; +}; + +struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION * pVersion; + CK_MECHANISM_TYPE prfHashMechanism; +}; + +struct CK_WTLS_KEY_MAT_OUT { + CK_OBJECT_HANDLE hMacSecret; + CK_OBJECT_HANDLE hKey; + CK_BYTE * pIV; +}; + +struct CK_WTLS_RANDOM_DATA { + CK_BYTE * pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE * pServerRandom; + CK_ULONG ulServerRandomLen; +}; + +struct CK_WTLS_KEY_MAT_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_ULONG ulSequenceNumber; + CK_BBOOL bIsExport; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_WTLS_KEY_MAT_OUT * pReturnedKeyMaterial; +}; + +struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_BYTE * pVersion; +}; + +struct CK_WTLS_PRF_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_BYTE * pSeed; + CK_ULONG ulSeedLen; + CK_BYTE * pLabel; + CK_ULONG ulLabelLen; + CK_BYTE * pOutput; + CK_ULONG * pulOutputLen; +}; + +/* PKCS11 Functions */ +extern CK_RV C_Initialize(void *); +extern CK_RV C_Finalize(void *); +extern CK_RV C_GetInfo(CK_INFO *); +extern CK_RV C_GetFunctionList(CK_FUNCTION_LIST **); +extern CK_RV C_GetSlotList(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); +extern CK_RV C_GetSlotInfo(CK_SLOT_ID, CK_SLOT_INFO *); +extern CK_RV C_GetTokenInfo(CK_SLOT_ID, CK_TOKEN_INFO *); +extern CK_RV C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE *, CK_ULONG *); +extern CK_RV C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO *); +extern CK_RV C_InitToken(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *); +extern CK_RV C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *, + CK_ULONG); +extern CK_RV C_OpenSession(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, + CK_SESSION_HANDLE *); +extern CK_RV C_CloseSession(CK_SESSION_HANDLE); +extern CK_RV C_CloseAllSessions(CK_SLOT_ID); +extern CK_RV C_GetSessionInfo(CK_SESSION_HANDLE, CK_SESSION_INFO *); +extern CK_RV C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_Logout(CK_SESSION_HANDLE); +extern CK_RV C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +extern CK_RV C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG *); +extern CK_RV C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG); +extern CK_RV C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_ULONG, + CK_ULONG *); +extern CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE); +extern CK_RV C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Encrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Decrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM *); +extern CK_RV C_Digest(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +extern CK_RV C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE); +extern CK_RV C_Sign(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_SignFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_SignRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_Verify(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +extern CK_RV C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +extern CK_RV C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *, + CK_OBJECT_HANDLE *); +extern CK_RV C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG *); +extern CK_RV C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +extern CK_RV C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE); +extern CK_RV C_CancelFunction(CK_SESSION_HANDLE); +extern CK_RV C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID *, void *); +extern CK_RV C_GetInterfaceList(CK_INTERFACE *, CK_ULONG *); +extern CK_RV C_GetInterface(CK_UTF8CHAR *, CK_VERSION *, CK_INTERFACE **, + CK_FLAGS); +extern CK_RV C_LoginUser(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG, CK_UTF8CHAR *, CK_ULONG); +extern CK_RV C_SessionCancel(CK_SESSION_HANDLE, CK_FLAGS); +extern CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_EncryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +extern CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_FLAGS); +extern CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_DecryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +extern CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_FLAGS); +extern CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageSignInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_SignMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +extern CK_RV C_SignMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); +extern CK_RV C_SignMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); +extern CK_RV C_MessageSignFinal(CK_SESSION_HANDLE); +extern CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +extern CK_RV C_VerifyMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); +extern CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); +extern CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE); +extern CK_RV C_EncapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *, CK_OBJECT_HANDLE *); +extern CK_RV C_DecapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_OBJECT_HANDLE *); +extern CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignature(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +extern CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE); +extern CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE, + CK_SESSION_VALIDATION_FLAGS_TYPE, + CK_FLAGS *); +extern CK_RV C_AsyncComplete(CK_SESSION_HANDLE, CK_UTF8CHAR *, + CK_ASYNC_DATA *); +extern CK_RV C_AsyncGetID(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); +extern CK_RV C_AsyncJoin(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_BYTE *, + CK_ULONG); +extern CK_RV C_WrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +extern CK_RV C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); + +typedef CK_RV (* CK_C_Initialize)(void *); +typedef CK_RV (* CK_C_Finalize)(void *); +typedef CK_RV (* CK_C_GetInfo)(CK_INFO *); +typedef CK_RV (* CK_C_GetFunctionList)(CK_FUNCTION_LIST **); +typedef CK_RV (* CK_C_GetSlotList)(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); +typedef CK_RV (* CK_C_GetSlotInfo)(CK_SLOT_ID, CK_SLOT_INFO *); +typedef CK_RV (* CK_C_GetTokenInfo)(CK_SLOT_ID, CK_TOKEN_INFO *); +typedef CK_RV (* CK_C_GetMechanismList)(CK_SLOT_ID, CK_MECHANISM_TYPE *, + CK_ULONG *); +typedef CK_RV (* CK_C_GetMechanismInfo)(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO *); +typedef CK_RV (* CK_C_InitToken)(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, + CK_UTF8CHAR *); +typedef CK_RV (* CK_C_InitPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_SetPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, + CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_OpenSession)(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, + CK_SESSION_HANDLE *); +typedef CK_RV (* CK_C_CloseSession)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CloseAllSessions)(CK_SLOT_ID); +typedef CK_RV (* CK_C_GetSessionInfo)(CK_SESSION_HANDLE, CK_SESSION_INFO *); +typedef CK_RV (* CK_C_GetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_SetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Login)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG); +typedef CK_RV (* CK_C_Logout)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CreateObject)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_CopyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DestroyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_GetObjectSize)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ULONG *); +typedef CK_RV (* CK_C_GetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +typedef CK_RV (* CK_C_SetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE *, CK_ULONG); +typedef CK_RV (* CK_C_FindObjectsInit)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, + CK_ULONG); +typedef CK_RV (* CK_C_FindObjects)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, + CK_ULONG, CK_ULONG *); +typedef CK_RV (* CK_C_FindObjectsFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_EncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Encrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Decrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DigestInit)(CK_SESSION_HANDLE, CK_MECHANISM *); +typedef CK_RV (* CK_C_Digest)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_DigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_DigestKey)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_DigestFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Sign)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_SignUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_SignFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_SignRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_VerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_Verify)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_VerifyRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DigestEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptDigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptVerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_GenerateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_GenerateKeyPair)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_OBJECT_HANDLE *, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_WrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_UnwrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG, + CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DeriveKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_SeedRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_GenerateRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_GetFunctionStatus)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_CancelFunction)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_WaitForSlotEvent)(CK_FLAGS, CK_SLOT_ID *, void *); +typedef CK_RV (* CK_C_GetInterfaceList)(CK_INTERFACE *, CK_ULONG *); +typedef CK_RV (* CK_C_GetInterface)(CK_UTF8CHAR *, CK_VERSION *, + CK_INTERFACE **, CK_FLAGS); +typedef CK_RV (* CK_C_LoginUser)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, + CK_ULONG, CK_UTF8CHAR *, CK_ULONG); +typedef CK_RV (* CK_C_SessionCancel)(CK_SESSION_HANDLE, CK_FLAGS); +typedef CK_RV (* CK_C_MessageEncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_EncryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_EncryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_EncryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *, CK_FLAGS); +typedef CK_RV (* CK_C_MessageEncryptFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageDecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_DecryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, + CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_DecryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_DecryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *, CK_FLAGS); +typedef CK_RV (* CK_C_MessageDecryptFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageSignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_SignMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); +typedef CK_RV (* CK_C_SignMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); +typedef CK_RV (* CK_C_SignMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_MessageSignFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_MessageVerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE); +typedef CK_RV (* CK_C_VerifyMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); +typedef CK_RV (* CK_C_VerifyMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_MessageVerifyFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_EncapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG *, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_DecapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); +typedef CK_RV (* CK_C_VerifySignatureInit)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifySignature)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_VerifySignatureUpdate)(CK_SESSION_HANDLE, CK_BYTE *, + CK_ULONG); +typedef CK_RV (* CK_C_VerifySignatureFinal)(CK_SESSION_HANDLE); +typedef CK_RV (* CK_C_GetSessionValidationFlags)(CK_SESSION_HANDLE, + CK_SESSION_VALIDATION_FLAGS_TYPE, + CK_FLAGS *); +typedef CK_RV (* CK_C_AsyncComplete)(CK_SESSION_HANDLE, CK_UTF8CHAR *, + CK_ASYNC_DATA *); +typedef CK_RV (* CK_C_AsyncGetID)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); +typedef CK_RV (* CK_C_AsyncJoin)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, + CK_BYTE *, CK_ULONG); +typedef CK_RV (* CK_C_WrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, + CK_BYTE *, CK_ULONG, CK_BYTE *, + CK_ULONG *); +typedef CK_RV (* CK_C_UnwrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, + CK_OBJECT_HANDLE, CK_BYTE *, + CK_ULONG, CK_ATTRIBUTE *, + CK_ULONG, CK_BYTE *, CK_ULONG, + CK_OBJECT_HANDLE *); + +struct CK_FUNCTION_LIST_3_2 { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; + CK_C_EncapsulateKey C_EncapsulateKey; + CK_C_DecapsulateKey C_DecapsulateKey; + CK_C_VerifySignatureInit C_VerifySignatureInit; + CK_C_VerifySignature C_VerifySignature; + CK_C_VerifySignatureUpdate C_VerifySignatureUpdate; + CK_C_VerifySignatureFinal C_VerifySignatureFinal; + CK_C_GetSessionValidationFlags C_GetSessionValidationFlags; + CK_C_AsyncComplete C_AsyncComplete; + CK_C_AsyncGetID C_AsyncGetID; + CK_C_AsyncJoin C_AsyncJoin; + CK_C_WrapKeyAuthenticated C_WrapKeyAuthenticated ; + CK_C_UnwrapKeyAuthenticated C_UnwrapKeyAuthenticated ; +}; + +struct CK_FUNCTION_LIST_3_0 { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; +}; + +struct CK_FUNCTION_LIST { + CK_VERSION version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; +}; + + +// clang-format on +#endif diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 72e38b722b..763d212448 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -1,12 +1,28 @@ +/* + * pkcs11.h: OpenSC project's PKCS#11 header + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + #ifndef PKCS11_H #define PKCS11_H 1 -// clang-fromat off #if defined(__cplusplus) extern "C" { #endif - /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) @@ -38,2777 +54,7 @@ extern "C" { #define PKCS11_DEPRECATED -typedef long int CK_LONG; - -/* - * The following part comes from https://github.com/latchset/pkcs11-headers - */ - -#define CRYPTOKI_VERSION_MAJOR 3 -#define CRYPTOKI_VERSION_MINOR 2 -#define CRYPTOKI_VERSION_AMENDMENT 0 - -/* Basic types */ -typedef unsigned char CK_BBOOL; -typedef unsigned char CK_BYTE; -typedef unsigned char CK_CHAR; -typedef unsigned char CK_UTF8CHAR; -typedef unsigned long int CK_ULONG; - -typedef CK_BBOOL * CK_BBOOL_PTR; -typedef CK_BYTE * CK_BYTE_PTR; -typedef CK_CHAR * CK_CHAR_PTR; -typedef CK_UTF8CHAR * CK_UTF8CHAR_PTR; -typedef CK_ULONG * CK_ULONG_PTR; - -/* Basic defines */ -#define NULL_PTR ((void *)0) -typedef void * CK_VOID_PTR; -typedef void ** CK_VOID_PTR_PTR; - -#define CK_EFFECTIVELY_INFINITE 0UL -#define CK_UNAVAILABLE_INFORMATION ~0UL -#define CK_INVALID_HANDLE 0UL -#define CK_TRUE 1 -#define CK_FALSE 0 - -/* CK_ types in alphabetical order */ -#define ULONGDEF(__name__) \ -typedef CK_ULONG __name__; \ -typedef __name__ * __name__ ## _PTR; - -ULONGDEF(CK_ATTRIBUTE_TYPE); -ULONGDEF(CK_CERTIFICATE_CATEGORY); -ULONGDEF(CK_CERTIFICATE_TYPE); -ULONGDEF(CK_EC_KDF_TYPE); -ULONGDEF(CK_EXTRACT_PARAMS); -ULONGDEF(CK_FLAGS); -ULONGDEF(CK_GENERATOR_FUNCTION); -ULONGDEF(CK_HEDGE_TYPE); -ULONGDEF(CK_HSS_LEVELS); -ULONGDEF(CK_HW_FEATURE_TYPE); -ULONGDEF(CK_JAVA_MIDP_SECURITY_DOMAIN); -ULONGDEF(CK_KEY_TYPE); -ULONGDEF(CK_LMS_TYPE); -ULONGDEF(CK_LMOTS_TYPE); -ULONGDEF(CK_MAC_GENERAL_PARAMS); -ULONGDEF(CK_MECHANISM_TYPE); -ULONGDEF(CK_ML_DSA_PARAMETER_SET_TYPE); -ULONGDEF(CK_ML_KEM_PARAMETER_SET_TYPE); -ULONGDEF(CK_NOTIFICATION); -ULONGDEF(CK_OBJECT_CLASS); -ULONGDEF(CK_OBJECT_HANDLE); -ULONGDEF(CK_OTP_PARAM_TYPE); -ULONGDEF(CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE); -ULONGDEF(CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE); -ULONGDEF(CK_PRF_DATA_TYPE); -ULONGDEF(CK_PROFILE_ID); -ULONGDEF(CK_RC2_PARAMS); -ULONGDEF(CK_RSA_PKCS_MGF_TYPE); -ULONGDEF(CK_RSA_PKCS_OAEP_SOURCE_TYPE); -ULONGDEF(CK_RV); -ULONGDEF(CK_SESSION_HANDLE); -ULONGDEF(CK_SESSION_VALIDATION_FLAGS_TYPE); -ULONGDEF(CK_SLH_DSA_PARAMETER_SET_TYPE); -ULONGDEF(CK_SLOT_ID); -ULONGDEF(CK_SP800_108_DKM_LENGTH_METHOD); -ULONGDEF(CK_STATE); -ULONGDEF(CK_TRUST); -ULONGDEF(CK_USER_TYPE); -ULONGDEF(CK_VALIDATION_AUTHORITY_TYPE); -ULONGDEF(CK_VALIDATION_TYPE); -ULONGDEF(CK_X2RATCHET_KDF_TYPE); -ULONGDEF(CK_X3DH_KDF_TYPE); -ULONGDEF(CK_X9_42_DH_KDF_TYPE); -ULONGDEF(CK_XEDDSA_HASH_TYPE); -ULONGDEF(CK_XMSSMT_PARAMETER_SET_TYPE); -ULONGDEF(CK_XMSS_PARAMETER_SET_TYPE); - -/* domain specific values and constants */ - -/* CK (certificate) */ -#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL -#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL -#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL -#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL - -/* CK (OTP) */ -#define CK_OTP_VALUE 0UL -#define CK_OTP_PIN 1UL -#define CK_OTP_CHALLENGE 2UL -#define CK_OTP_TIME 3UL -#define CK_OTP_COUNTER 4UL -#define CK_OTP_FLAGS 5UL -#define CK_OTP_OUTPUT_LENGTH 6UL -#define CK_OTP_OUTPUT_FORMAT 7UL - -/* CK (OTP format) */ -#define CK_OTP_FORMAT_DECIMAL 0UL -#define CK_OTP_FORMAT_HEXADECIMAL 1UL -#define CK_OTP_FORMAT_ALPHANUMERIC 2UL -#define CK_OTP_FORMAT_BINARY 3UL - -/* CK (OTP requirement) */ -#define CK_OTP_PARAM_IGNORED 0UL -#define CK_OTP_PARAM_OPTIONAL 1UL -#define CK_OTP_PARAM_MANDATORY 2UL - -/* CK (security) */ -#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL -#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL -#define CK_SECURITY_DOMAIN_OPERATOR 2UL -#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL - -/* CK (SP800 KDF) */ -#define CK_SP800_108_ITERATION_VARIABLE 0x00000001UL -#define CK_SP800_108_OPTIONAL_COUNTER 0x00000002UL -#define CK_SP800_108_COUNTER 0x00000002UL -#define CK_SP800_108_DKM_LENGTH 0x00000003UL -#define CK_SP800_108_BYTE_ARRAY 0x00000004UL -#define CK_SP800_108_KEY_HANDLE 0x00000005UL - -/* CK (SP800 DKM) */ -#define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL -#define CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS 0x00000002UL - -/* CKA */ -#define CKA_CLASS 0x00000000UL -#define CKA_TOKEN 0x00000001UL -#define CKA_PRIVATE 0x00000002UL -#define CKA_LABEL 0x00000003UL -#define CKA_UNIQUE_ID 0x00000004UL -#define CKA_APPLICATION 0x00000010UL -#define CKA_VALUE 0x00000011UL -#define CKA_OBJECT_ID 0x00000012UL -#define CKA_CERTIFICATE_TYPE 0x00000080UL -#define CKA_ISSUER 0x00000081UL -#define CKA_SERIAL_NUMBER 0x00000082UL -#define CKA_AC_ISSUER 0x00000083UL -#define CKA_OWNER 0x00000084UL -#define CKA_ATTR_TYPES 0x00000085UL -#define CKA_TRUSTED 0x00000086UL -#define CKA_CERTIFICATE_CATEGORY 0x00000087UL -#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL -#define CKA_URL 0x00000089UL -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL -#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL -#define CKA_CHECK_VALUE 0x00000090UL -#define CKA_KEY_TYPE 0x00000100UL -#define CKA_SUBJECT 0x00000101UL -#define CKA_ID 0x00000102UL -#define CKA_SENSITIVE 0x00000103UL -#define CKA_ENCRYPT 0x00000104UL -#define CKA_DECRYPT 0x00000105UL -#define CKA_WRAP 0x00000106UL -#define CKA_UNWRAP 0x00000107UL -#define CKA_SIGN 0x00000108UL -#define CKA_SIGN_RECOVER 0x00000109UL -#define CKA_VERIFY 0x0000010AUL -#define CKA_VERIFY_RECOVER 0x0000010BUL -#define CKA_DERIVE 0x0000010CUL -#define CKA_START_DATE 0x00000110UL -#define CKA_END_DATE 0x00000111UL -#define CKA_MODULUS 0x00000120UL -#define CKA_MODULUS_BITS 0x00000121UL -#define CKA_PUBLIC_EXPONENT 0x00000122UL -#define CKA_PRIVATE_EXPONENT 0x00000123UL -#define CKA_PRIME_1 0x00000124UL -#define CKA_PRIME_2 0x00000125UL -#define CKA_EXPONENT_1 0x00000126UL -#define CKA_EXPONENT_2 0x00000127UL -#define CKA_COEFFICIENT 0x00000128UL -#define CKA_PUBLIC_KEY_INFO 0x00000129UL -#define CKA_PRIME 0x00000130UL -#define CKA_SUBPRIME 0x00000131UL -#define CKA_BASE 0x00000132UL -#define CKA_PRIME_BITS 0x00000133UL -#define CKA_SUBPRIME_BITS 0x00000134UL -#define CKA_SUB_PRIME_BITS 0x00000134UL -#define CKA_VALUE_BITS 0x00000160UL -#define CKA_VALUE_LEN 0x00000161UL -#define CKA_EXTRACTABLE 0x00000162UL -#define CKA_LOCAL 0x00000163UL -#define CKA_NEVER_EXTRACTABLE 0x00000164UL -#define CKA_ALWAYS_SENSITIVE 0x00000165UL -#define CKA_KEY_GEN_MECHANISM 0x00000166UL -#define CKA_MODIFIABLE 0x00000170UL -#define CKA_COPYABLE 0x00000171UL -#define CKA_DESTROYABLE 0x00000172UL -#define CKA_EC_PARAMS 0x00000180UL -#define CKA_EC_POINT 0x00000181UL -#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL -#define CKA_WRAP_WITH_TRUSTED 0x00000210UL -#define CKA_OTP_FORMAT 0x00000220UL -#define CKA_OTP_LENGTH 0x00000221UL -#define CKA_OTP_TIME_INTERVAL 0x00000222UL -#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL -#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL -#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL -#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL -#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL -#define CKA_OTP_COUNTER 0x0000022EUL -#define CKA_OTP_TIME 0x0000022FUL -#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL -#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL -#define CKA_OTP_SERVICE_LOGO 0x0000022CUL -#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL -#define CKA_GOSTR3410_PARAMS 0x00000250UL -#define CKA_GOSTR3411_PARAMS 0x00000251UL -#define CKA_GOST28147_PARAMS 0x00000252UL -#define CKA_HW_FEATURE_TYPE 0x00000300UL -#define CKA_RESET_ON_INIT 0x00000301UL -#define CKA_HAS_RESET 0x00000302UL -#define CKA_PIXEL_X 0x00000400UL -#define CKA_PIXEL_Y 0x00000401UL -#define CKA_RESOLUTION 0x00000402UL -#define CKA_CHAR_ROWS 0x00000403UL -#define CKA_CHAR_COLUMNS 0x00000404UL -#define CKA_COLOR 0x00000405UL -#define CKA_BITS_PER_PIXEL 0x00000406UL -#define CKA_CHAR_SETS 0x00000480UL -#define CKA_ENCODING_METHODS 0x00000481UL -#define CKA_MIME_TYPES 0x00000482UL -#define CKA_MECHANISM_TYPE 0x00000500UL -#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL -#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL -#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL -#define CKA_PROFILE_ID 0x00000601UL -#define CKA_X2RATCHET_BAG 0x00000602UL -#define CKA_X2RATCHET_BAGSIZE 0x00000603UL -#define CKA_X2RATCHET_BOBS1STMSG 0x00000604UL -#define CKA_X2RATCHET_CKR 0x00000605UL -#define CKA_X2RATCHET_CKS 0x00000606UL -#define CKA_X2RATCHET_DHP 0x00000607UL -#define CKA_X2RATCHET_DHR 0x00000608UL -#define CKA_X2RATCHET_DHS 0x00000609UL -#define CKA_X2RATCHET_HKR 0x0000060AUL -#define CKA_X2RATCHET_HKS 0x0000060BUL -#define CKA_X2RATCHET_ISALICE 0x0000060CUL -#define CKA_X2RATCHET_NHKR 0x0000060DUL -#define CKA_X2RATCHET_NHKS 0x0000060EUL -#define CKA_X2RATCHET_NR 0x0000060FUL -#define CKA_X2RATCHET_NS 0x00000610UL -#define CKA_X2RATCHET_PNS 0x00000611UL -#define CKA_X2RATCHET_RK 0x00000612UL -#define CKA_HSS_LEVELS 0x00000617UL -#define CKA_HSS_LMS_TYPE 0x00000618UL -#define CKA_HSS_LMOTS_TYPE 0x00000619UL -#define CKA_HSS_LMS_TYPES 0x0000061AUL -#define CKA_HSS_LMOTS_TYPES 0x0000061BUL -#define CKA_HSS_KEYS_REMAINING 0x0000061CUL -#define CKA_PARAMETER_SET 0x0000061DUL -#define CKA_OBJECT_VALIDATION_FLAGS 0x0000061EUL -#define CKA_VALIDATION_TYPE 0x0000061FUL -#define CKA_VALIDATION_VERSION 0x00000620UL -#define CKA_VALIDATION_LEVEL 0x00000621UL -#define CKA_VALIDATION_MODULE_ID 0x00000622UL -#define CKA_VALIDATION_FLAG 0x00000623UL -#define CKA_VALIDATION_AUTHORITY_TYPE 0x00000624UL -#define CKA_VALIDATION_COUNTRY 0x00000625UL -#define CKA_VALIDATION_CERTIFICATE_IDENTIFIER 0x00000626UL -#define CKA_VALIDATION_CERTIFICATE_URI 0x00000627UL -#define CKA_VALIDATION_VENDOR_URI 0x00000628UL -#define CKA_VALIDATION_PROFILE 0x00000629UL -#define CKA_ENCAPSULATE_TEMPLATE 0x0000062AUL -#define CKA_DECAPSULATE_TEMPLATE 0x0000062BUL -#define CKA_TRUST_SERVER_AUTH 0x0000062CUL -#define CKA_TRUST_CLIENT_AUTH 0x0000062DUL -#define CKA_TRUST_CODE_SIGNING 0x0000062EUL -#define CKA_TRUST_EMAIL_PROTECTION 0x0000062FUL -#define CKA_TRUST_IPSEC_IKE 0x00000630UL -#define CKA_TRUST_TIME_STAMPING 0x00000631UL -#define CKA_TRUST_OCSP_SIGNING 0x00000632UL -#define CKA_ENCAPSULATE 0x00000633UL -#define CKA_DECAPSULATE 0x00000634UL -#define CKA_HASH_OF_CERTIFICATE 0x00000635UL -#define CKA_PUBLIC_CRC64_VALUE 0x00000636UL -#define CKA_SEED 0x00000637UL -#define CKA_VENDOR_DEFINED 0x80000000UL -/* Array attributes */ -#define CKA_WRAP_TEMPLATE 0x40000211UL -#define CKA_UNWRAP_TEMPLATE 0x40000212UL -#define CKA_DERIVE_TEMPLATE 0x40000213UL -#define CKA_ALLOWED_MECHANISMS 0x40000600UL -/* Deprecated */ -#ifdef PKCS11_DEPRECATED -#define CKA_ECDSA_PARAMS 0x00000180UL -#define CKA_SECONDARY_AUTH 0x00000200UL -#define CKA_AUTH_PIN_FLAGS 0x00000201UL -#endif - -/* CKC */ -#define CKC_X_509 0x00000000UL -#define CKC_X_509_ATTR_CERT 0x00000001UL -#define CKC_WTLS 0x00000002UL -#define CKC_VENDOR_DEFINED 0x80000000UL - -/* CKD */ -#define CKD_NULL 0x00000001UL -#define CKD_SHA1_KDF 0x00000002UL -#define CKD_SHA1_KDF_ASN1 0x00000003UL -#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL -#define CKD_SHA224_KDF 0x00000005UL -#define CKD_SHA256_KDF 0x00000006UL -#define CKD_SHA384_KDF 0x00000007UL -#define CKD_SHA512_KDF 0x00000008UL -#define CKD_CPDIVERSIFY_KDF 0x00000009UL -#define CKD_SHA3_224_KDF 0x0000000AUL -#define CKD_SHA3_256_KDF 0x0000000BUL -#define CKD_SHA3_384_KDF 0x0000000CUL -#define CKD_SHA3_512_KDF 0x0000000DUL -#define CKD_SHA1_KDF_SP800 0x0000000EUL -#define CKD_SHA224_KDF_SP800 0x0000000FUL -#define CKD_SHA256_KDF_SP800 0x00000010UL -#define CKD_SHA384_KDF_SP800 0x00000011UL -#define CKD_SHA512_KDF_SP800 0x00000012UL -#define CKD_SHA3_224_KDF_SP800 0x00000013UL -#define CKD_SHA3_256_KDF_SP800 0x00000014UL -#define CKD_SHA3_384_KDF_SP800 0x00000015UL -#define CKD_SHA3_512_KDF_SP800 0x00000016UL -#define CKD_BLAKE2B_160_KDF 0x00000017UL -#define CKD_BLAKE2B_256_KDF 0x00000018UL -#define CKD_BLAKE2B_384_KDF 0x00000019UL -#define CKD_BLAKE2B_512_KDF 0x0000001AUL - -/* CFK (array attributes) */ -#define CKF_ARRAY_ATTRIBUTE 0x40000000UL - -/* CKF (capabilities) */ -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL -#define CKF_OS_LOCKING_OK 0x00000002UL - -/* CKF (HKDF) */ -#define CKF_HKDF_SALT_NULL 0x00000001UL -#define CKF_HKDF_SALT_DATA 0x00000002UL -#define CKF_HKDF_SALT_KEY 0x00000004UL - -/* CKF (interface) */ -#define CKF_INTERFACE_FORK_SAFE 0x00000001UL - -/* CKF (mechanism) */ -#define CKF_HW 0x00000001UL -#define CKF_MESSAGE_ENCRYPT 0x00000002UL -#define CKF_MESSAGE_DECRYPT 0x00000004UL -#define CKF_MESSAGE_SIGN 0x00000008UL -#define CKF_MESSAGE_VERIFY 0x00000010UL -#define CKF_MULTI_MESSAGE 0x00000020UL -#define CKF_MULTI_MESSGE 0x00000020UL -#define CKF_FIND_OBJECTS 0x00000040UL -#define CKF_ENCRYPT 0x00000100UL -#define CKF_DECRYPT 0x00000200UL -#define CKF_DIGEST 0x00000400UL -#define CKF_SIGN 0x00000800UL -#define CKF_SIGN_RECOVER 0x00001000UL -#define CKF_VERIFY 0x00002000UL -#define CKF_VERIFY_RECOVER 0x00004000UL -#define CKF_GENERATE 0x00008000UL -#define CKF_GENERATE_KEY_PAIR 0x00010000UL -#define CKF_WRAP 0x00020000UL -#define CKF_UNWRAP 0x00040000UL -#define CKF_DERIVE 0x00080000UL -#define CKF_EC_F_P 0x00100000UL -#define CKF_EC_F_2M 0x00200000UL -#define CKF_EC_ECPARAMETERS 0x00400000UL -#define CKF_EC_OID 0x00800000UL -#define CKF_EC_UNCOMPRESS 0x01000000UL -#define CKF_EC_COMPRESS 0x02000000UL -#define CKF_EC_CURVENAME 0x04000000UL -#define CKF_ENCAPSULATE 0x10000000UL -#define CKF_DECAPSULATE 0x20000000UL -#define CKF_EXTENSION 0x80000000UL -/* Deprecated */ -#ifdef PKCS11_DEPRECATED -#define CKF_EC_NAMEDCURVE 0x00800000U -#endif - -/* CKF (message) */ -#define CKF_END_OF_MESSAGE 0x00000001UL - -/* CKF (OTP) */ -#define CKF_NEXT_OTP 0x00000001UL -#define CKF_EXCLUDE_TIME 0x00000002UL -#define CKF_EXCLUDE_COUNTER 0x00000004UL -#define CKF_EXCLUDE_CHALLENGE 0x00000008UL -#define CKF_EXCLUDE_PIN 0x00000010UL -#define CKF_USER_FRIENDLY_OTP 0x00000020UL - -/* CKF (parameters to functions) */ -#define CKF_DONT_BLOCK 1 - -/* CKF (session) */ -#define CKF_RW_SESSION 0x00000002UL -#define CKF_SERIAL_SESSION 0x00000004UL -#define CKF_ASYNC_SESSION 0x00000008UL - -/* CFK (slot) */ -#define CKF_TOKEN_PRESENT 0x00000001UL -#define CKF_REMOVABLE_DEVICE 0x00000002UL -#define CKF_HW_SLOT 0x00000004UL - -/* CKF (token) */ -#define CKF_RNG 0x00000001UL -#define CKF_WRITE_PROTECTED 0x00000002UL -#define CKF_LOGIN_REQUIRED 0x00000004UL -#define CKF_USER_PIN_INITIALIZED 0x00000008UL -#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL -#define CKF_CLOCK_ON_TOKEN 0x00000040UL -#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL -#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL -#define CKF_TOKEN_INITIALIZED 0x00000400UL -#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL -#define CKF_USER_PIN_COUNT_LOW 0x00010000UL -#define CKF_USER_PIN_FINAL_TRY 0x00020000UL -#define CKF_USER_PIN_LOCKED 0x00040000UL -#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL -#define CKF_SO_PIN_COUNT_LOW 0x00100000UL -#define CKF_SO_PIN_FINAL_TRY 0x00200000UL -#define CKF_SO_PIN_LOCKED 0x00400000UL -#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL -#define CKF_ERROR_STATE 0x01000000UL -#define CKF_SEED_RANDOM_REQUIRED 0x02000000UL -#define CKF_ASYNC_SESSION_SUPPORTED 0x04000000UL - -/* CKG (GCM) */ -#define CKG_NO_GENERATE 0x00000000UL -#define CKG_GENERATE 0x00000001UL -#define CKG_GENERATE_COUNTER 0x00000002UL -#define CKG_GENERATE_RANDOM 0x00000003UL -#define CKG_GENERATE_COUNTER_XOR 0x00000004UL - -/* CKG (MFG) */ -#define CKG_MGF1_SHA1 0x00000001UL -#define CKG_MGF1_SHA256 0x00000002UL -#define CKG_MGF1_SHA384 0x00000003UL -#define CKG_MGF1_SHA512 0x00000004UL -#define CKG_MGF1_SHA224 0x00000005UL -#define CKG_MGF1_SHA3_224 0x00000006UL -#define CKG_MGF1_SHA3_256 0x00000007UL -#define CKG_MGF1_SHA3_384 0x00000008UL -#define CKG_MGF1_SHA3_512 0x00000009UL - -/* CKH (clock) */ -#define CKH_MONOTONIC_COUNTER 0x00000001UL -#define CKH_CLOCK 0x00000002UL -#define CKH_USER_INTERFACE 0x00000003UL -#define CKH_VENDOR_DEFINED 0x80000000UL - -/* CKH (hedge type) */ -#define CKH_HEDGE_PREFERRED 0x00000000UL -#define CKH_HEDGE_REQUIRED 0x00000001UL -#define CKH_DETERMINISTIC_REQUIRED 0x00000002UL - -/* CKK */ -#define CKK_RSA 0x00000000UL -#define CKK_DSA 0x00000001UL -#define CKK_DH 0x00000002UL -#define CKK_EC 0x00000003UL -#define CKK_X9_42_DH 0x00000004UL -#define CKK_KEA 0x00000005UL -#define CKK_GENERIC_SECRET 0x00000010UL -#define CKK_RC2 0x00000011UL -#define CKK_RC4 0x00000012UL -#define CKK_DES 0x00000013UL -#define CKK_DES2 0x00000014UL -#define CKK_DES3 0x00000015UL -#define CKK_CAST 0x00000016UL -#define CKK_CAST3 0x00000017UL -#define CKK_CAST128 0x00000018UL -#define CKK_RC5 0x00000019UL -#define CKK_IDEA 0x0000001AUL -#define CKK_SKIPJACK 0x0000001BUL -#define CKK_BATON 0x0000001CUL -#define CKK_JUNIPER 0x0000001DUL -#define CKK_CDMF 0x0000001EUL -#define CKK_AES 0x0000001FUL -#define CKK_BLOWFISH 0x00000020UL -#define CKK_TWOFISH 0x00000021UL -#define CKK_SECURID 0x00000022UL -#define CKK_HOTP 0x00000023UL -#define CKK_ACTI 0x00000024UL -#define CKK_CAMELLIA 0x00000025UL -#define CKK_ARIA 0x00000026UL -#define CKK_MD5_HMAC 0x00000027UL -#define CKK_SHA_1_HMAC 0x00000028UL -#define CKK_RIPEMD128_HMAC 0x00000029UL -#define CKK_RIPEMD160_HMAC 0x0000002AUL -#define CKK_SHA256_HMAC 0x0000002BUL -#define CKK_SHA384_HMAC 0x0000002CUL -#define CKK_SHA512_HMAC 0x0000002DUL -#define CKK_SHA224_HMAC 0x0000002EUL -#define CKK_SEED 0x0000002FUL -#define CKK_GOSTR3410 0x00000030UL -#define CKK_GOSTR3411 0x00000031UL -#define CKK_GOST28147 0x00000032UL -#define CKK_CHACHA20 0x00000033UL -#define CKK_POLY1305 0x00000034UL -#define CKK_AES_XTS 0x00000035UL -#define CKK_SHA3_224_HMAC 0x00000036UL -#define CKK_SHA3_256_HMAC 0x00000037UL -#define CKK_SHA3_384_HMAC 0x00000038UL -#define CKK_SHA3_512_HMAC 0x00000039UL -#define CKK_BLAKE2B_160_HMAC 0x0000003AUL -#define CKK_BLAKE2B_256_HMAC 0x0000003BUL -#define CKK_BLAKE2B_384_HMAC 0x0000003CUL -#define CKK_BLAKE2B_512_HMAC 0x0000003DUL -#define CKK_SALSA20 0x0000003EUL -#define CKK_X2RATCHET 0x0000003FUL -#define CKK_EC_EDWARDS 0x00000040UL -#define CKK_EC_MONTGOMERY 0x00000041UL -#define CKK_HKDF 0x00000042UL -#define CKK_SHA512_224_HMAC 0x00000043UL -#define CKK_SHA512_256_HMAC 0x00000044UL -#define CKK_SHA512_T_HMAC 0x00000045UL -#define CKK_HSS 0x00000046UL -#define CKK_XMSS 0x00000047UL -#define CKK_XMSSMT 0x00000048UL -#define CKK_ML_KEM 0x00000049UL -#define CKK_ML_DSA 0x0000004AUL -#define CKK_SLH_DSA 0x0000004BUL -#define CKK_VENDOR_DEFINED 0x80000000UL -/* Deprecated */ -#ifdef PKCS11_DEPRECATED -#define CKK_ECDSA 0x00000003UL -#define CKK_CAST5 0x00000018UL -#endif - -/* CKM */ -#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL -#define CKM_RSA_PKCS 0x00000001UL -#define CKM_RSA_9796 0x00000002UL -#define CKM_RSA_X_509 0x00000003UL -#define CKM_MD2_RSA_PKCS 0x00000004UL -#define CKM_MD5_RSA_PKCS 0x00000005UL -#define CKM_SHA1_RSA_PKCS 0x00000006UL -#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL -#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL -#define CKM_RSA_PKCS_OAEP 0x00000009UL -#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL -#define CKM_RSA_X9_31 0x0000000BUL -#define CKM_SHA1_RSA_X9_31 0x0000000CUL -#define CKM_RSA_PKCS_PSS 0x0000000DUL -#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL -#define CKM_ML_KEM_KEY_PAIR_GEN 0x0000000FUL -#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL -#define CKM_DSA 0x00000011UL -#define CKM_DSA_SHA1 0x00000012UL -#define CKM_DSA_SHA224 0x00000013UL -#define CKM_DSA_SHA256 0x00000014UL -#define CKM_DSA_SHA384 0x00000015UL -#define CKM_DSA_SHA512 0x00000016UL -#define CKM_ML_KEM 0x00000017UL -#define CKM_DSA_SHA3_224 0x00000018UL -#define CKM_DSA_SHA3_256 0x00000019UL -#define CKM_DSA_SHA3_384 0x0000001AUL -#define CKM_DSA_SHA3_512 0x0000001BUL -#define CKM_ML_DSA_KEY_PAIR_GEN 0x0000001CUL -#define CKM_ML_DSA 0x0000001DUL -#define CKM_HASH_ML_DSA 0x0000001FUL -#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL -#define CKM_DH_PKCS_DERIVE 0x00000021UL -#define CKM_HASH_ML_DSA_SHA224 0x00000023UL -#define CKM_HASH_ML_DSA_SHA256 0x00000024UL -#define CKM_HASH_ML_DSA_SHA384 0x00000025UL -#define CKM_HASH_ML_DSA_SHA512 0x00000026UL -#define CKM_HASH_ML_DSA_SHA3_224 0x00000027UL -#define CKM_HASH_ML_DSA_SHA3_256 0x00000028UL -#define CKM_HASH_ML_DSA_SHA3_384 0x00000029UL -#define CKM_HASH_ML_DSA_SHA3_512 0x0000002AUL -#define CKM_HASH_ML_DSA_SHAKE128 0x0000002BUL -#define CKM_HASH_ML_DSA_SHAKE256 0x0000002CUL -#define CKM_SLH_DSA_KEY_PAIR_GEN 0x0000002DUL -#define CKM_SLH_DSA 0x0000002EUL -#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL -#define CKM_X9_42_DH_DERIVE 0x00000031UL -#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL -#define CKM_X9_42_MQV_DERIVE 0x00000033UL -#define CKM_HASH_SLH_DSA 0x00000034UL -#define CKM_HASH_SLH_DSA_SHA224 0x00000036UL -#define CKM_HASH_SLH_DSA_SHA256 0x00000037UL -#define CKM_HASH_SLH_DSA_SHA384 0x00000038UL -#define CKM_HASH_SLH_DSA_SHA512 0x00000039UL -#define CKM_HASH_SLH_DSA_SHA3_224 0x0000003AUL -#define CKM_HASH_SLH_DSA_SHA3_256 0x0000003BUL -#define CKM_HASH_SLH_DSA_SHA3_384 0x0000003CUL -#define CKM_HASH_SLH_DSA_SHA3_512 0x0000003DUL -#define CKM_HASH_SLH_DSA_SHAKE128 0x0000003EUL -#define CKM_HASH_SLH_DSA_SHAKE256 0x0000003FUL -#define CKM_SHA256_RSA_PKCS 0x00000040UL -#define CKM_SHA384_RSA_PKCS 0x00000041UL -#define CKM_SHA512_RSA_PKCS 0x00000042UL -#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL -#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL -#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL -#define CKM_SHA224_RSA_PKCS 0x00000046UL -#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL -#define CKM_SHA512_224 0x00000048UL -#define CKM_SHA512_224_HMAC 0x00000049UL -#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL -#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL -#define CKM_SHA512_256 0x0000004CUL -#define CKM_SHA512_256_HMAC 0x0000004DUL -#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL -#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL -#define CKM_SHA512_T 0x00000050UL -#define CKM_SHA512_T_HMAC 0x00000051UL -#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL -#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL -#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE 0x00000056UL -#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH 0x00000057UL -#define CKM_SHA3_256_RSA_PKCS 0x00000060UL -#define CKM_SHA3_384_RSA_PKCS 0x00000061UL -#define CKM_SHA3_512_RSA_PKCS 0x00000062UL -#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL -#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL -#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL -#define CKM_SHA3_224_RSA_PKCS 0x00000066UL -#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL -#define CKM_RC2_KEY_GEN 0x00000100UL -#define CKM_RC2_ECB 0x00000101UL -#define CKM_RC2_CBC 0x00000102UL -#define CKM_RC2_MAC 0x00000103UL -#define CKM_RC2_MAC_GENERAL 0x00000104UL -#define CKM_RC2_CBC_PAD 0x00000105UL -#define CKM_RC4_KEY_GEN 0x00000110UL -#define CKM_RC4 0x00000111UL -#define CKM_DES_KEY_GEN 0x00000120UL -#define CKM_DES_ECB 0x00000121UL -#define CKM_DES_CBC 0x00000122UL -#define CKM_DES_MAC 0x00000123UL -#define CKM_DES_MAC_GENERAL 0x00000124UL -#define CKM_DES_CBC_PAD 0x00000125UL -#define CKM_DES2_KEY_GEN 0x00000130UL -#define CKM_DES3_KEY_GEN 0x00000131UL -#define CKM_DES3_ECB 0x00000132UL -#define CKM_DES3_CBC 0x00000133UL -#define CKM_DES3_MAC 0x00000134UL -#define CKM_DES3_MAC_GENERAL 0x00000135UL -#define CKM_DES3_CBC_PAD 0x00000136UL -#define CKM_DES3_CMAC_GENERAL 0x00000137UL -#define CKM_DES3_CMAC 0x00000138UL -#define CKM_CDMF_KEY_GEN 0x00000140UL -#define CKM_CDMF_ECB 0x00000141UL -#define CKM_CDMF_CBC 0x00000142UL -#define CKM_CDMF_MAC 0x00000143UL -#define CKM_CDMF_MAC_GENERAL 0x00000144UL -#define CKM_CDMF_CBC_PAD 0x00000145UL -#define CKM_DES_OFB64 0x00000150UL -#define CKM_DES_OFB8 0x00000151UL -#define CKM_DES_CFB64 0x00000152UL -#define CKM_DES_CFB8 0x00000153UL -#define CKM_MD2 0x00000200UL -#define CKM_MD2_HMAC 0x00000201UL -#define CKM_MD2_HMAC_GENERAL 0x00000202UL -#define CKM_MD5 0x00000210UL -#define CKM_MD5_HMAC 0x00000211UL -#define CKM_MD5_HMAC_GENERAL 0x00000212UL -#define CKM_SHA_1 0x00000220UL -#define CKM_SHA_1_HMAC 0x00000221UL -#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL -#define CKM_RIPEMD128 0x00000230UL -#define CKM_RIPEMD128_HMAC 0x00000231UL -#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL -#define CKM_RIPEMD160 0x00000240UL -#define CKM_RIPEMD160_HMAC 0x00000241UL -#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL -#define CKM_SHA256 0x00000250UL -#define CKM_SHA256_HMAC 0x00000251UL -#define CKM_SHA256_HMAC_GENERAL 0x00000252UL -#define CKM_SHA224 0x00000255UL -#define CKM_SHA224_HMAC 0x00000256UL -#define CKM_SHA224_HMAC_GENERAL 0x00000257UL -#define CKM_SHA384 0x00000260UL -#define CKM_SHA384_HMAC 0x00000261UL -#define CKM_SHA384_HMAC_GENERAL 0x00000262UL -#define CKM_SHA512 0x00000270UL -#define CKM_SHA512_HMAC 0x00000271UL -#define CKM_SHA512_HMAC_GENERAL 0x00000272UL -#define CKM_SECURID_KEY_GEN 0x00000280UL -#define CKM_SECURID 0x00000282UL -#define CKM_HOTP_KEY_GEN 0x00000290UL -#define CKM_HOTP 0x00000291UL -#define CKM_ACTI 0x000002A0UL -#define CKM_ACTI_KEY_GEN 0x000002A1UL -#define CKM_SHA3_256 0x000002B0UL -#define CKM_SHA3_256_HMAC 0x000002B1UL -#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL -#define CKM_SHA3_256_KEY_GEN 0x000002B3UL -#define CKM_SHA3_224 0x000002B5UL -#define CKM_SHA3_224_HMAC 0x000002B6UL -#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL -#define CKM_SHA3_224_KEY_GEN 0x000002B8UL -#define CKM_SHA3_384 0x000002C0UL -#define CKM_SHA3_384_HMAC 0x000002C1UL -#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL -#define CKM_SHA3_384_KEY_GEN 0x000002C3UL -#define CKM_SHA3_512 0x000002D0UL -#define CKM_SHA3_512_HMAC 0x000002D1UL -#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL -#define CKM_SHA3_512_KEY_GEN 0x000002D3UL -#define CKM_CAST_KEY_GEN 0x00000300UL -#define CKM_CAST_ECB 0x00000301UL -#define CKM_CAST_CBC 0x00000302UL -#define CKM_CAST_MAC 0x00000303UL -#define CKM_CAST_MAC_GENERAL 0x00000304UL -#define CKM_CAST_CBC_PAD 0x00000305UL -#define CKM_CAST3_KEY_GEN 0x00000310UL -#define CKM_CAST3_ECB 0x00000311UL -#define CKM_CAST3_CBC 0x00000312UL -#define CKM_CAST3_MAC 0x00000313UL -#define CKM_CAST3_MAC_GENERAL 0x00000314UL -#define CKM_CAST3_CBC_PAD 0x00000315UL -#define CKM_CAST128_KEY_GEN 0x00000320UL -#define CKM_CAST128_ECB 0x00000321UL -#define CKM_CAST128_MAC 0x00000323UL -#define CKM_CAST128_CBC 0x00000322UL -#define CKM_CAST128_MAC_GENERAL 0x00000324UL -#define CKM_CAST128_CBC_PAD 0x00000325UL -#define CKM_RC5_KEY_GEN 0x00000330UL -#define CKM_RC5_ECB 0x00000331UL -#define CKM_RC5_CBC 0x00000332UL -#define CKM_RC5_MAC 0x00000333UL -#define CKM_RC5_MAC_GENERAL 0x00000334UL -#define CKM_RC5_CBC_PAD 0x00000335UL -#define CKM_IDEA_KEY_GEN 0x00000340UL -#define CKM_IDEA_ECB 0x00000341UL -#define CKM_IDEA_CBC 0x00000342UL -#define CKM_IDEA_MAC 0x00000343UL -#define CKM_IDEA_MAC_GENERAL 0x00000344UL -#define CKM_IDEA_CBC_PAD 0x00000345UL -#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL -#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL -#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL -#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL -#define CKM_XOR_BASE_AND_DATA 0x00000364UL -#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL -#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL -#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL -#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL -#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL -#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL -#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL -#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL -#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL -#define CKM_TLS_PRF 0x00000378UL -#define CKM_SSL3_MD5_MAC 0x00000380UL -#define CKM_SSL3_SHA1_MAC 0x00000381UL -#define CKM_MD5_KEY_DERIVATION 0x00000390UL -#define CKM_MD2_KEY_DERIVATION 0x00000391UL -#define CKM_SHA1_KEY_DERIVATION 0x00000392UL -#define CKM_SHA256_KEY_DERIVATION 0x00000393UL -#define CKM_SHA384_KEY_DERIVATION 0x00000394UL -#define CKM_SHA512_KEY_DERIVATION 0x00000395UL -#define CKM_SHA224_KEY_DERIVATION 0x00000396UL -#define CKM_SHA3_256_KEY_DERIVATION 0x00000397UL -#define CKM_SHA3_256_KEY_DERIVE 0x00000397UL -#define CKM_SHA3_224_KEY_DERIVATION 0x00000398UL -#define CKM_SHA3_224_KEY_DERIVE 0x00000398UL -#define CKM_SHA3_384_KEY_DERIVATION 0x00000399UL -#define CKM_SHA3_384_KEY_DERIVE 0x00000399UL -#define CKM_SHA3_512_KEY_DERIVATION 0x0000039AUL -#define CKM_SHA3_512_KEY_DERIVE 0x0000039AUL -#define CKM_SHAKE_128_KEY_DERIVATION 0x0000039BUL -#define CKM_SHAKE_128_KEY_DERIVE 0x0000039BUL -#define CKM_SHAKE_256_KEY_DERIVATION 0x0000039CUL -#define CKM_SHAKE_256_KEY_DERIVE 0x0000039CUL -#define CKM_PBE_MD2_DES_CBC 0x000003A0UL -#define CKM_PBE_MD5_DES_CBC 0x000003A1UL -#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL -#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL -#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL -#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL -#define CKM_PBE_SHA1_RC4_128 0x000003A6UL -#define CKM_PBE_SHA1_RC4_40 0x000003A7UL -#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL -#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL -#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL -#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL -#define CKM_PKCS5_PBKD2 0x000003B0UL -#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL -#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL -#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL -#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL -#define CKM_WTLS_PRF 0x000003D3UL -#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL -#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL -#define CKM_TLS10_MAC_SERVER 0x000003D6UL -#define CKM_TLS10_MAC_CLIENT 0x000003D7UL -#define CKM_TLS12_MAC 0x000003D8UL -#define CKM_TLS12_KDF 0x000003D9UL -#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL -#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL -#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL -#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL -#define CKM_TLS_MAC 0x000003E4UL -#define CKM_TLS_KDF 0x000003E5UL -#define CKM_KEY_WRAP_LYNKS 0x00000400UL -#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL -#define CKM_CMS_SIG 0x00000500UL -#define CKM_KIP_DERIVE 0x00000510UL -#define CKM_KIP_WRAP 0x00000511UL -#define CKM_KIP_MAC 0x00000512UL -#define CKM_CAMELLIA_KEY_GEN 0x00000550UL -#define CKM_CAMELLIA_ECB 0x00000551UL -#define CKM_CAMELLIA_CBC 0x00000552UL -#define CKM_CAMELLIA_MAC 0x00000553UL -#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL -#define CKM_CAMELLIA_CBC_PAD 0x00000555UL -#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL -#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL -#define CKM_CAMELLIA_CTR 0x00000558UL -#define CKM_ARIA_KEY_GEN 0x00000560UL -#define CKM_ARIA_ECB 0x00000561UL -#define CKM_ARIA_CBC 0x00000562UL -#define CKM_ARIA_MAC 0x00000563UL -#define CKM_ARIA_MAC_GENERAL 0x00000564UL -#define CKM_ARIA_CBC_PAD 0x00000565UL -#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL -#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL -#define CKM_SEED_KEY_GEN 0x00000650UL -#define CKM_SEED_ECB 0x00000651UL -#define CKM_SEED_CBC 0x00000652UL -#define CKM_SEED_MAC 0x00000653UL -#define CKM_SEED_MAC_GENERAL 0x00000654UL -#define CKM_SEED_CBC_PAD 0x00000655UL -#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL -#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL -#define CKM_SKIPJACK_KEY_GEN 0x00001000UL -#define CKM_SKIPJACK_ECB64 0x00001001UL -#define CKM_SKIPJACK_CBC64 0x00001002UL -#define CKM_SKIPJACK_OFB64 0x00001003UL -#define CKM_SKIPJACK_CFB64 0x00001004UL -#define CKM_SKIPJACK_CFB32 0x00001005UL -#define CKM_SKIPJACK_CFB16 0x00001006UL -#define CKM_SKIPJACK_CFB8 0x00001007UL -#define CKM_SKIPJACK_WRAP 0x00001008UL -#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL -#define CKM_SKIPJACK_RELAYX 0x0000100AUL -#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL -#define CKM_KEA_KEY_DERIVE 0x00001011UL -#define CKM_KEA_DERIVE 0x00001012UL -#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL -#define CKM_BATON_KEY_GEN 0x00001030UL -#define CKM_BATON_ECB128 0x00001031UL -#define CKM_BATON_ECB96 0x00001032UL -#define CKM_BATON_CBC128 0x00001033UL -#define CKM_BATON_COUNTER 0x00001034UL -#define CKM_BATON_SHUFFLE 0x00001035UL -#define CKM_BATON_WRAP 0x00001036UL -#define CKM_EC_KEY_PAIR_GEN 0x00001040UL -#define CKM_ECDSA 0x00001041UL -#define CKM_ECDSA_SHA1 0x00001042UL -#define CKM_ECDSA_SHA224 0x00001043UL -#define CKM_ECDSA_SHA256 0x00001044UL -#define CKM_ECDSA_SHA384 0x00001045UL -#define CKM_ECDSA_SHA512 0x00001046UL -#define CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS 0x0000140BUL -#define CKM_ECDH1_DERIVE 0x00001050UL -#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL -#define CKM_ECMQV_DERIVE 0x00001052UL -#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL -#define CKM_RSA_AES_KEY_WRAP 0x00001054UL -#define CKM_JUNIPER_KEY_GEN 0x00001060UL -#define CKM_JUNIPER_ECB128 0x00001061UL -#define CKM_JUNIPER_CBC128 0x00001062UL -#define CKM_JUNIPER_COUNTER 0x00001063UL -#define CKM_JUNIPER_SHUFFLE 0x00001064UL -#define CKM_JUNIPER_WRAP 0x00001065UL -#define CKM_FASTHASH 0x00001070UL -#define CKM_AES_XTS 0x00001071UL -#define CKM_AES_XTS_KEY_GEN 0x00001072UL -#define CKM_AES_KEY_GEN 0x00001080UL -#define CKM_AES_ECB 0x00001081UL -#define CKM_AES_CBC 0x00001082UL -#define CKM_AES_MAC 0x00001083UL -#define CKM_AES_MAC_GENERAL 0x00001084UL -#define CKM_AES_CBC_PAD 0x00001085UL -#define CKM_AES_CTR 0x00001086UL -#define CKM_AES_GCM 0x00001087UL -#define CKM_AES_CCM 0x00001088UL -#define CKM_AES_CTS 0x00001089UL -#define CKM_AES_CMAC 0x0000108AUL -#define CKM_AES_CMAC_GENERAL 0x0000108BUL -#define CKM_AES_XCBC_MAC 0x0000108CUL -#define CKM_AES_XCBC_MAC_96 0x0000108DUL -#define CKM_AES_GMAC 0x0000108EUL -#define CKM_BLOWFISH_KEY_GEN 0x00001090UL -#define CKM_BLOWFISH_CBC 0x00001091UL -#define CKM_TWOFISH_KEY_GEN 0x00001092UL -#define CKM_TWOFISH_CBC 0x00001093UL -#define CKM_BLOWFISH_CBC_PAD 0x00001094UL -#define CKM_TWOFISH_CBC_PAD 0x00001095UL -#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL -#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL -#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL -#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL -#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL -#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL -#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL -#define CKM_GOSTR3410 0x00001201UL -#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL -#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL -#define CKM_GOSTR3410_DERIVE 0x00001204UL -#define CKM_GOSTR3411 0x00001210UL -#define CKM_GOSTR3411_HMAC 0x00001211UL -#define CKM_GOST28147_KEY_GEN 0x00001220UL -#define CKM_GOST28147_ECB 0x00001221UL -#define CKM_GOST28147 0x00001222UL -#define CKM_GOST28147_MAC 0x00001223UL -#define CKM_GOST28147_KEY_WRAP 0x00001224UL -#define CKM_CHACHA20_KEY_GEN 0x00001225UL -#define CKM_CHACHA20 0x00001226UL -#define CKM_POLY1305_KEY_GEN 0x00001227UL -#define CKM_POLY1305 0x00001228UL -#define CKM_DSA_PARAMETER_GEN 0x00002000UL -#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL -#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL -#define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL -#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL -#define CKM_DSA_FIPS_G_GEN 0x00002005UL -#define CKM_AES_OFB 0x00002104UL -#define CKM_AES_CFB64 0x00002105UL -#define CKM_AES_CFB8 0x00002106UL -#define CKM_AES_CFB128 0x00002107UL -#define CKM_AES_CFB1 0x00002108UL -#define CKM_AES_KEY_WRAP 0x00002109UL -#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL -#define CKM_AES_KEY_WRAP_KWP 0x0000210BUL -#define CKM_AES_KEY_WRAP_PKCS7 0x0000210CUL -#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL -#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL -#define CKM_SHA_1_KEY_GEN 0x00004003UL -#define CKM_SHA224_KEY_GEN 0x00004004UL -#define CKM_SHA256_KEY_GEN 0x00004005UL -#define CKM_SHA384_KEY_GEN 0x00004006UL -#define CKM_SHA512_KEY_GEN 0x00004007UL -#define CKM_SHA512_224_KEY_GEN 0x00004008UL -#define CKM_SHA512_256_KEY_GEN 0x00004009UL -#define CKM_SHA512_T_KEY_GEN 0x0000400AUL -#define CKM_NULL 0x0000400BUL -#define CKM_BLAKE2B_160 0x0000400CUL -#define CKM_BLAKE2B_160_HMAC 0x0000400DUL -#define CKM_BLAKE2B_160_HMAC_GENERAL 0x0000400EUL -#define CKM_BLAKE2B_160_KEY_DERIVE 0x0000400FUL -#define CKM_BLAKE2B_160_KEY_GEN 0x00004010UL -#define CKM_BLAKE2B_256 0x00004011UL -#define CKM_BLAKE2B_256_HMAC 0x00004012UL -#define CKM_BLAKE2B_256_HMAC_GENERAL 0x00004013UL -#define CKM_BLAKE2B_256_KEY_DERIVE 0x00004014UL -#define CKM_BLAKE2B_256_KEY_GEN 0x00004015UL -#define CKM_BLAKE2B_384 0x00004016UL -#define CKM_BLAKE2B_384_HMAC 0x00004017UL -#define CKM_BLAKE2B_384_HMAC_GENERAL 0x00004018UL -#define CKM_BLAKE2B_384_KEY_DERIVE 0x00004019UL -#define CKM_BLAKE2B_384_KEY_GEN 0x0000401AUL -#define CKM_BLAKE2B_512 0x0000401BUL -#define CKM_BLAKE2B_512_HMAC 0x0000401CUL -#define CKM_BLAKE2B_512_HMAC_GENERAL 0x0000401DUL -#define CKM_BLAKE2B_512_KEY_DERIVE 0x0000401EUL -#define CKM_BLAKE2B_512_KEY_GEN 0x0000401FUL -#define CKM_SALSA20 0x00004020UL -#define CKM_CHACHA20_POLY1305 0x00004021UL -#define CKM_SALSA20_POLY1305 0x00004022UL -#define CKM_X3DH_INITIALIZE 0x00004023UL -#define CKM_X3DH_RESPOND 0x00004024UL -#define CKM_X2RATCHET_INITIALIZE 0x00004025UL -#define CKM_X2RATCHET_RESPOND 0x00004026UL -#define CKM_X2RATCHET_ENCRYPT 0x00004027UL -#define CKM_X2RATCHET_DECRYPT 0x00004028UL -#define CKM_XEDDSA 0x00004029UL -#define CKM_HKDF_DERIVE 0x0000402AUL -#define CKM_HKDF_DATA 0x0000402BUL -#define CKM_HKDF_KEY_GEN 0x0000402CUL -#define CKM_SALSA20_KEY_GEN 0x0000402DUL -#define CKM_ECDSA_SHA3_224 0x00001047UL -#define CKM_ECDSA_SHA3_256 0x00001048UL -#define CKM_ECDSA_SHA3_384 0x00001049UL -#define CKM_ECDSA_SHA3_512 0x0000104AUL -#define CKM_EC_EDWARDS_KEY_PAIR_GEN 0x00001055UL -#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN 0x00001056UL -#define CKM_EDDSA 0x00001057UL -#define CKM_SP800_108_COUNTER_KDF 0x000003ACUL -#define CKM_SP800_108_FEEDBACK_KDF 0x000003ADUL -#define CKM_SP800_108_DOUBLE_PIPELINE_KDF 0x000003AEUL -#define CKM_IKE2_PRF_PLUS_DERIVE 0x0000402EUL -#define CKM_IKE_PRF_DERIVE 0x0000402FUL -#define CKM_IKE1_PRF_DERIVE 0x00004030UL -#define CKM_IKE1_EXTENDED_DERIVE 0x00004031UL -#define CKM_HSS_KEY_PAIR_GEN 0x00004032UL -#define CKM_HSS 0x00004033UL -#define CKM_XMSS_KEY_PAIR_GEN 0x00004034UL -#define CKM_XMSSMT_KEY_PAIR_GEN 0x00004035UL -#define CKM_XMSS 0x00004036UL -#define CKM_XMSSMT 0x00004037UL -#define CKM_ECDH_X_AES_KEY_WRAP 0x00004038UL -#define CKM_ECDH_COF_AES_KEY_WRAP 0x00004039UL -#define CKM_PUB_KEY_FROM_PRIV_KEY 0x0000403AUL -#define CKM_VENDOR_DEFINED 0x80000000UL -/* Deprecated */ -#ifdef PKCS11_DEPRECATED -#define CKM_CAST5_KEY_GEN 0x00000320UL -#define CKM_CAST5_ECB 0x00000321UL -#define CKM_CAST5_CBC 0x00000322UL -#define CKM_CAST5_MAC 0x00000323UL -#define CKM_CAST5_MAC_GENERAL 0x00000324UL -#define CKM_CAST5_CBC_PAD 0x00000325UL -#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL -#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL -#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL -#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL -#endif - -/* CKN */ -#define CKN_SURRENDER 0UL -#define CKN_OTP_CHANGED 1UL - -/* CKO */ -#define CKO_DATA 0x00000000UL -#define CKO_CERTIFICATE 0x00000001UL -#define CKO_PUBLIC_KEY 0x00000002UL -#define CKO_PRIVATE_KEY 0x00000003UL -#define CKO_SECRET_KEY 0x00000004UL -#define CKO_HW_FEATURE 0x00000005UL -#define CKO_DOMAIN_PARAMETERS 0x00000006UL -#define CKO_MECHANISM 0x00000007UL -#define CKO_OTP_KEY 0x00000008UL -#define CKO_PROFILE 0x00000009UL -#define CKO_VALIDATION 0x0000000AUL -#define CKO_TRUST 0x0000000BUL -#define CKO_VENDOR_DEFINED 0x80000000UL - -/* CKP (profile) */ -#define CKP_INVALID_ID 0x00000000UL -#define CKP_BASELINE_PROVIDER 0x00000001UL -#define CKP_EXTENDED_PROVIDER 0x00000002UL -#define CKP_AUTHENTICATION_TOKEN 0x00000003UL -#define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL -#define CKP_COMPLETE_PROVIDER 0x00000005UL -#define CKP_HKDF_TLS_TOKEN 0x00000006UL -#define CKP_VENDOR_DEFINED 0x80000000UL - -/* CKP (PBKD2) */ -#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL -#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL -#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL -#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL -#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL - -/* CKP (ML-DSA) */ -#define CKP_ML_DSA_44 0x00000001UL -#define CKP_ML_DSA_65 0x00000002UL -#define CKP_ML_DSA_87 0x00000003UL - -/* CKP (ML_KEM) */ -#define CKP_ML_KEM_512 0x00000001UL -#define CKP_ML_KEM_768 0x00000002UL -#define CKP_ML_KEM_1024 0x00000003UL - -/* CKP (SLH-DSA) */ -#define CKP_SLH_DSA_SHA2_128S 0x00000001UL -#define CKP_SLH_DSA_SHAKE_128S 0x00000002UL -#define CKP_SLH_DSA_SHA2_128F 0x00000003UL -#define CKP_SLH_DSA_SHAKE_128F 0x00000004UL -#define CKP_SLH_DSA_SHA2_192S 0x00000005UL -#define CKP_SLH_DSA_SHAKE_192S 0x00000006UL -#define CKP_SLH_DSA_SHA2_192F 0x00000007UL -#define CKP_SLH_DSA_SHAKE_192F 0x00000008UL -#define CKP_SLH_DSA_SHA2_256S 0x00000009UL -#define CKP_SLH_DSA_SHAKE_256S 0x0000000AUL -#define CKP_SLH_DSA_SHA2_256F 0x0000000BUL -#define CKP_SLH_DSA_SHAKE_256F 0x0000000CUL - -/* CKR */ -#define CKR_OK 0x00000000UL -#define CKR_CANCEL 0x00000001UL -#define CKR_HOST_MEMORY 0x00000002UL -#define CKR_SLOT_ID_INVALID 0x00000003UL -#define CKR_GENERAL_ERROR 0x00000005UL -#define CKR_FUNCTION_FAILED 0x00000006UL -#define CKR_ARGUMENTS_BAD 0x00000007UL -#define CKR_NO_EVENT 0x00000008UL -#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL -#define CKR_CANT_LOCK 0x0000000AUL -#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL -#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL -#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL -#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL -#define CKR_ACTION_PROHIBITED 0x0000001BUL -#define CKR_DATA_INVALID 0x00000020UL -#define CKR_DATA_LEN_RANGE 0x00000021UL -#define CKR_DEVICE_ERROR 0x00000030UL -#define CKR_DEVICE_MEMORY 0x00000031UL -#define CKR_DEVICE_REMOVED 0x00000032UL -#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL -#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL -#define CKR_AEAD_DECRYPT_FAILED 0x00000042UL -#define CKR_FUNCTION_CANCELED 0x00000050UL -#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL -#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL -#define CKR_KEY_HANDLE_INVALID 0x00000060UL -#define CKR_KEY_SIZE_RANGE 0x00000062UL -#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL -#define CKR_KEY_NOT_NEEDED 0x00000064UL -#define CKR_KEY_CHANGED 0x00000065UL -#define CKR_KEY_NEEDED 0x00000066UL -#define CKR_KEY_INDIGESTIBLE 0x00000067UL -#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL -#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL -#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL -#define CKR_MECHANISM_INVALID 0x00000070UL -#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL -#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL -#define CKR_OPERATION_ACTIVE 0x00000090UL -#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL -#define CKR_PIN_INCORRECT 0x000000A0UL -#define CKR_PIN_INVALID 0x000000A1UL -#define CKR_PIN_LEN_RANGE 0x000000A2UL -#define CKR_PIN_EXPIRED 0x000000A3UL -#define CKR_PIN_LOCKED 0x000000A4UL -#define CKR_SESSION_CLOSED 0x000000B0UL -#define CKR_SESSION_COUNT 0x000000B1UL -#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL -#define CKR_SESSION_READ_ONLY 0x000000B5UL -#define CKR_SESSION_EXISTS 0x000000B6UL -#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL -#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL -#define CKR_SIGNATURE_INVALID 0x000000C0UL -#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL -#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL -#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL -#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL -#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL -#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL -#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL -#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL -#define CKR_USER_NOT_LOGGED_IN 0x00000101UL -#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL -#define CKR_USER_TYPE_INVALID 0x00000103UL -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL -#define CKR_USER_TOO_MANY_TYPES 0x00000105UL -#define CKR_WRAPPED_KEY_INVALID 0x00000110UL -#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL -#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL -#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL -#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL -#define CKR_RANDOM_NO_RNG 0x00000121UL -#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL -#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL -#define CKR_BUFFER_TOO_SMALL 0x00000150UL -#define CKR_SAVED_STATE_INVALID 0x00000160UL -#define CKR_INFORMATION_SENSITIVE 0x00000170UL -#define CKR_STATE_UNSAVEABLE 0x00000180UL -#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL -#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL -#define CKR_MUTEX_BAD 0x000001A0UL -#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL -#define CKR_NEW_PIN_MODE 0x000001B0UL -#define CKR_NEXT_OTP 0x000001B1UL -#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL -#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL -#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL -#define CKR_PIN_TOO_WEAK 0x000001B8UL -#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL -#define CKR_FUNCTION_REJECTED 0x00000200UL -#define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL -#define CKR_OPERATION_CANCEL_FAILED 0x00000202UL -#define CKR_KEY_EXHAUSTED 0x00000203UL -#define CKR_PENDING 0x00000204UL -#define CKR_SESSION_ASYNC_NOT_SUPPORTED 0x00000205UL -#define CKR_SEED_RANDOM_REQUIRED 0x00000206UL -#define CKR_OPERATION_NOT_VALIDATED 0x00000207UL -#define CKR_TOKEN_NOT_INITIALIZED 0x00000208UL -#define CKR_PARAMETER_SET_NOT_SUPPORTED 0x00000209UL -#define CKR_VENDOR_DEFINED 0x80000000UL - -/* CKS */ -#define CKS_RO_PUBLIC_SESSION 0UL -#define CKS_RO_USER_FUNCTIONS 1UL -#define CKS_RW_PUBLIC_SESSION 2UL -#define CKS_RW_USER_FUNCTIONS 3UL -#define CKS_RW_SO_FUNCTIONS 4UL - -/* CKS (validation) */ -#define CKS_LAST_VALIDATION_OK 0x00000001UL - -/* CKT (trust) */ -#define CKT_TRUST_UNKNOWN 0x00000000UL -#define CKT_TRUSTED 0x00000001UL -#define CKT_TRUST_ANCHOR 0x00000002UL -#define CKT_NOT_TRUSTED 0x00000003UL -#define CKT_TRUST_MUST_VERIFY_TRUST 0x00000004UL - -/* CKU */ -#define CKU_SO 0UL -#define CKU_USER 1UL -#define CKU_CONTEXT_SPECIFIC 2UL - -/* CKV (validation authority) */ -#define CKV_AUTHORITY_TYPE_UNSPECIFIED 0x00000000UL -#define CKV_AUTHORITY_TYPE_NIST_CMVP 0x00000001UL -#define CKV_AUTHORITY_TYPE_COMMON_CRITERIA 0x00000002UL - -/* CKV (validation type) */ -#define CKV_TYPE_UNSPECIFIED 0x00000000UL -#define CKV_TYPE_SOFTWARE 0x00000001UL -#define CKV_TYPE_HARDWARE 0x00000002UL -#define CKV_TYPE_FIRMWARE 0x00000003UL -#define CKV_TYPE_HYBRID 0x00000004UL - -/* CKZ (data) */ -#define CKZ_DATA_SPECIFIED 0x00000001UL - -/* CKZ (salt) */ -#define CKZ_SALT_SPECIFIED 0x00000001UL - -/* Sundry structures type definition in alphabetical order */ -#define STRUCTDEF(__name__) \ -struct __name__; \ -typedef struct __name__ __name__; \ -typedef struct __name__ * __name__ ## _PTR; \ -typedef struct __name__ ** __name__ ## _PTR_PTR; - -STRUCTDEF(CK_ATTRIBUTE); -STRUCTDEF(CK_C_INITIALIZE_ARGS); -STRUCTDEF(CK_DATE); -STRUCTDEF(CK_DERIVED_KEY); -STRUCTDEF(CK_FUNCTION_LIST); -STRUCTDEF(CK_FUNCTION_LIST_3_0); -STRUCTDEF(CK_FUNCTION_LIST_3_2); -STRUCTDEF(CK_INFO); -STRUCTDEF(CK_INTERFACE); -STRUCTDEF(CK_MECHANISM); -STRUCTDEF(CK_MECHANISM_INFO); -STRUCTDEF(CK_SESSION_INFO); -STRUCTDEF(CK_SLOT_INFO); -STRUCTDEF(CK_TOKEN_INFO); -STRUCTDEF(CK_VERSION); - -/* Function type definitions */ -typedef CK_RV (* CK_NOTIFY)(CK_SESSION_HANDLE, CK_NOTIFICATION, void *); -typedef CK_RV (* CK_CREATEMUTEX)(void **); -typedef CK_RV (* CK_DESTROYMUTEX)(void *); -typedef CK_RV (* CK_LOCKMUTEX)(void *); -typedef CK_RV (* CK_UNLOCKMUTEX)(void *); - -/* General Structure definitions */ -struct CK_ATTRIBUTE { - CK_ATTRIBUTE_TYPE type; - void * pValue; - CK_ULONG ulValueLen; -}; - -struct CK_C_INITIALIZE_ARGS { - CK_CREATEMUTEX CreateMutex; - CK_DESTROYMUTEX DestroyMutex; - CK_LOCKMUTEX LockMutex; - CK_UNLOCKMUTEX UnlockMutex; - CK_FLAGS flags; - void * pReserved; -}; - -struct CK_DATE{ - CK_CHAR year[4]; - CK_CHAR month[2]; - CK_CHAR day[2]; -}; - -struct CK_DERIVED_KEY -{ - CK_ATTRIBUTE * pTemplate; - CK_ULONG ulAttributeCount; - CK_OBJECT_HANDLE * phKey; -}; - -struct CK_VERSION { - CK_BYTE major; - CK_BYTE minor; -}; - -struct CK_INFO { - struct CK_VERSION cryptokiVersion; - CK_UTF8CHAR manufacturerID[32]; - CK_FLAGS flags; - CK_UTF8CHAR libraryDescription[32]; - struct CK_VERSION libraryVersion; -}; - -struct CK_INTERFACE { - CK_UTF8CHAR * pInterfaceName; - void * pFunctionList; - CK_FLAGS flags; -}; - -struct CK_MECHANISM { - CK_MECHANISM_TYPE mechanism; - void * pParameter; - CK_ULONG ulParameterLen; -}; - -struct CK_MECHANISM_INFO { - CK_ULONG ulMinKeySize; - CK_ULONG ulMaxKeySize; - CK_FLAGS flags; -}; - -struct CK_SESSION_INFO { - CK_SLOT_ID slotID; - CK_STATE state; - CK_FLAGS flags; - CK_ULONG ulDeviceError; -}; - -struct CK_SLOT_INFO { - CK_UTF8CHAR slotDescription[64]; - CK_UTF8CHAR manufacturerID[32]; - CK_FLAGS flags; - CK_VERSION hardwareVersion; - CK_VERSION firmwareVersion; -}; - -struct CK_TOKEN_INFO { - CK_UTF8CHAR label[32]; - CK_UTF8CHAR manufacturerID[32]; - CK_UTF8CHAR model[16]; - CK_CHAR serialNumber[16]; - CK_FLAGS flags; - CK_ULONG ulMaxSessionCount; - CK_ULONG ulSessionCount; - CK_ULONG ulMaxRwSessionCount; - CK_ULONG ulRwSessionCount; - CK_ULONG ulMaxPinLen; - CK_ULONG ulMinPinLen; - CK_ULONG ulTotalPublicMemory; - CK_ULONG ulFreePublicMemory; - CK_ULONG ulTotalPrivateMemory; - CK_ULONG ulFreePrivateMemory; - CK_VERSION hardwareVersion; - CK_VERSION firmwareVersion; - CK_CHAR utcTime[16]; -}; - -/* Param Structure definitions in alphabetical order */ -STRUCTDEF(CK_AES_CBC_ENCRYPT_DATA_PARAMS); -STRUCTDEF(CK_AES_CCM_PARAMS); -STRUCTDEF(CK_AES_CTR_PARAMS); -STRUCTDEF(CK_AES_GCM_PARAMS); -STRUCTDEF(CK_ARIA_CBC_ENCRYPT_DATA_PARAMS); -STRUCTDEF(CK_ASYNC_DATA); -STRUCTDEF(CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS); -STRUCTDEF(CK_CAMELLIA_CTR_PARAMS); -STRUCTDEF(CK_CCM_MESSAGE_PARAMS); -STRUCTDEF(CK_CCM_PARAMS); -STRUCTDEF(CK_CCM_WRAP_PARAMS); -STRUCTDEF(CK_CHACHA20_PARAMS); -STRUCTDEF(CK_CMS_SIG_PARAMS); -STRUCTDEF(CK_DES_CBC_ENCRYPT_DATA_PARAMS); -STRUCTDEF(CK_DSA_PARAMETER_GEN_PARAM); -STRUCTDEF(CK_ECDH_AES_KEY_WRAP_PARAMS); -STRUCTDEF(CK_ECDH1_DERIVE_PARAMS); -STRUCTDEF(CK_ECDH2_DERIVE_PARAMS); -STRUCTDEF(CK_ECMQV_DERIVE_PARAMS); -STRUCTDEF(CK_EDDSA_PARAMS); -STRUCTDEF(CK_GCM_MESSAGE_PARAMS); -STRUCTDEF(CK_GCM_PARAMS); -STRUCTDEF(CK_GCM_WRAP_PARAMS); -STRUCTDEF(CK_GOSTR3410_DERIVE_PARAMS); -STRUCTDEF(CK_GOSTR3410_KEY_WRAP_PARAMS); -STRUCTDEF(CK_HASH_SIGN_ADDITIONAL_CONTEXT); -STRUCTDEF(CK_HKDF_PARAMS); -STRUCTDEF(CK_IKE_PRF_DERIVE_PARAMS); -STRUCTDEF(CK_IKE1_EXTENDED_DERIVE_PARAMS); -STRUCTDEF(CK_IKE1_PRF_DERIVE_PARAMS); -STRUCTDEF(CK_IKE2_PRF_PLUS_DERIVE_PARAMS); -STRUCTDEF(CK_KEA_DERIVE_PARAMS); -STRUCTDEF(CK_KEY_DERIVATION_STRING_DATA); -STRUCTDEF(CK_KEY_WRAP_SET_OAEP_PARAMS); -STRUCTDEF(CK_KIP_PARAMS); -STRUCTDEF(CK_OTP_PARAM); -STRUCTDEF(CK_OTP_PARAMS); -STRUCTDEF(CK_OTP_SIGNATURE_INFO); -STRUCTDEF(CK_PBE_PARAMS); -STRUCTDEF(CK_PKCS5_PBKD2_PARAMS); -STRUCTDEF(CK_PKCS5_PBKD2_PARAMS2); -STRUCTDEF(CK_PRF_DATA_PARAM); -STRUCTDEF(CK_RC2_CBC_PARAMS); -STRUCTDEF(CK_RC2_MAC_GENERAL_PARAMS); -STRUCTDEF(CK_RC5_CBC_PARAMS); -STRUCTDEF(CK_RC5_MAC_GENERAL_PARAMS); -STRUCTDEF(CK_RC5_PARAMS); -STRUCTDEF(CK_RSA_AES_KEY_WRAP_PARAMS); -STRUCTDEF(CK_RSA_PKCS_OAEP_PARAMS); -STRUCTDEF(CK_RSA_PKCS_PSS_PARAMS); -STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS); -STRUCTDEF(CK_SALSA20_CHACHA20_POLY1305_PARAMS); -STRUCTDEF(CK_SALSA20_PARAMS); -STRUCTDEF(CK_SEED_CBC_ENCRYPT_DATA_PARAMS); -STRUCTDEF(CK_SIGN_ADDITIONAL_CONTEXT); -STRUCTDEF(CK_SKIPJACK_PRIVATE_WRAP_PARAMS); -STRUCTDEF(CK_SKIPJACK_RELAYX_PARAMS); -STRUCTDEF(CK_SP800_108_COUNTER_FORMAT); -STRUCTDEF(CK_SP800_108_DKM_LENGTH_FORMAT); -STRUCTDEF(CK_SP800_108_FEEDBACK_KDF_PARAMS); -STRUCTDEF(CK_SP800_108_KDF_PARAMS); -STRUCTDEF(CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS); -STRUCTDEF(CK_X2RATCHET_INITIALIZE_PARAMS); -STRUCTDEF(CK_X2RATCHET_RESPOND_PARAMS); -STRUCTDEF(CK_X3DH_INITIATE_PARAMS); -STRUCTDEF(CK_X3DH_RESPOND_PARAMS); -STRUCTDEF(CK_X9_42_DH1_DERIVE_PARAMS); -STRUCTDEF(CK_X9_42_DH2_DERIVE_PARAMS); -STRUCTDEF(CK_X9_42_MQV_DERIVE_PARAMS); -STRUCTDEF(CK_XEDDSA_PARAMS); -STRUCTDEF(specifiedParams); - -struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE * pData; - CK_ULONG length; -}; - -struct CK_AES_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -}; - -struct CK_AES_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -}; - -struct CK_AES_GCM_PARAMS { - CK_BYTE * pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -}; - -struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE * pData; - CK_ULONG length; -}; - -struct CK_ASYNC_DATA { - CK_ULONG ulVersion; - CK_BYTE * pValue; - CK_ULONG ulValue; - CK_OBJECT_HANDLE hObject; - CK_OBJECT_HANDLE hAdditionalObject; -}; - -struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE * pData; - CK_ULONG length; -}; - -struct CK_CAMELLIA_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -}; - -struct CK_CCM_MESSAGE_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_ULONG ulNonceFixedBits; - CK_GENERATOR_FUNCTION nonceGenerator; - CK_BYTE * pMAC; - CK_ULONG ulMACLen; -}; - -struct CK_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -}; -struct CK_CCM_WRAP_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_ULONG ulNonceFixedBits; - CK_GENERATOR_FUNCTION nonceGenerator; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -}; - -struct CK_CHACHA20_PARAMS { - CK_BYTE * pBlockCounter; - CK_ULONG blockCounterBits; - CK_BYTE * pNonce; - CK_ULONG ulNonceBits; -}; - -struct CK_CMS_SIG_PARAMS { - CK_OBJECT_HANDLE certificateHandle; - CK_MECHANISM * pSigningMechanism; - CK_MECHANISM * pDigestMechanism; - CK_UTF8CHAR * pContentType; - CK_BYTE * pRequestedAttributes; - CK_ULONG ulRequestedAttributesLen; - CK_BYTE * pRequiredAttributes; - CK_ULONG ulRequiredAttributesLen; -}; - -struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[8]; - CK_BYTE * pData; - CK_ULONG length; -}; - -struct CK_DSA_PARAMETER_GEN_PARAM { - CK_MECHANISM_TYPE hash; - CK_BYTE * pSeed; - CK_ULONG ulSeedLen; - CK_ULONG ulIndex; -}; - -struct CK_ECDH_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE * pSharedData; -}; - -struct CK_ECDH1_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE * pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; -}; - -struct CK_ECDH2_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE * pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE * pPublicData2; -}; - -struct CK_ECMQV_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE * pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE * pPublicData2; - CK_OBJECT_HANDLE publicKey; -}; - -struct CK_EDDSA_PARAMS { - CK_BBOOL phFlag; - CK_ULONG ulContextDataLen; - CK_BYTE * pContextData; -}; - -struct CK_GCM_MESSAGE_PARAMS { - CK_BYTE * pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvFixedBits; - CK_GENERATOR_FUNCTION ivGenerator; - CK_BYTE * pTag; - CK_ULONG ulTagBits; -}; - -struct CK_GCM_PARAMS { - CK_BYTE * pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -}; - -struct CK_GCM_WRAP_PARAMS { - CK_BYTE * pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvFixedBits; - CK_GENERATOR_FUNCTION ivGenerator; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -}; - -struct CK_GOSTR3410_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_BYTE * pPublicData; - CK_ULONG ulPublicDataLen; - CK_BYTE * pUKM; - CK_ULONG ulUKMLen; -}; - -struct CK_GOSTR3410_KEY_WRAP_PARAMS { - CK_BYTE * pWrapOID; - CK_ULONG ulWrapOIDLen; - CK_BYTE * pUKM; - CK_ULONG ulUKMLen; - CK_OBJECT_HANDLE hKey; -}; - -struct CK_HASH_SIGN_ADDITIONAL_CONTEXT { - CK_HEDGE_TYPE hedgeVariant; - CK_BYTE * pContext; - CK_ULONG ulContextLen; - CK_MECHANISM_TYPE hash; -}; - -struct CK_HKDF_PARAMS { - CK_BBOOL bExtract; - CK_BBOOL bExpand; - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulSaltType; - CK_BYTE * pSalt; - CK_ULONG ulSaltLen; - CK_OBJECT_HANDLE hSaltKey; - CK_BYTE * pInfo; - CK_ULONG ulInfoLen; -}; - -struct CK_IKE_PRF_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bDataAsKey; - CK_BBOOL bRekey; - CK_BYTE * pNi; - CK_ULONG ulNiLen; - CK_BYTE * pNr; - CK_ULONG ulNrLen; - CK_OBJECT_HANDLE hNewKey; -}; - -struct CK_IKE1_EXTENDED_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasKeygxy; - CK_OBJECT_HANDLE hKeygxy; - CK_BYTE * pExtraData; - CK_ULONG ulExtraDataLen; -}; - -struct CK_IKE1_PRF_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasPrevKey; - CK_OBJECT_HANDLE hKeygxy; - CK_OBJECT_HANDLE hPrevKey; - CK_BYTE * pCKYi; - CK_ULONG ulCKYiLen; - CK_BYTE * pCKYr; - CK_ULONG ulCKYrLen; - CK_BYTE keyNumber; -}; - -struct CK_IKE2_PRF_PLUS_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasSeedKey; - CK_OBJECT_HANDLE hSeedKey; - CK_BYTE * pSeedData; - CK_ULONG ulSeedDataLen; -}; - -struct CK_KEA_DERIVE_PARAMS { - CK_BBOOL isSender; - CK_ULONG ulRandomLen; - CK_BYTE * RandomA; - CK_BYTE * RandomB; - CK_ULONG ulPublicDataLen; - CK_BYTE * PublicData; -}; - -struct CK_KEY_DERIVATION_STRING_DATA { - CK_BYTE * pData; - CK_ULONG ulLen; -}; - -struct CK_KEY_WRAP_SET_OAEP_PARAMS { - CK_BYTE bBC; - CK_BYTE * pX; - CK_ULONG ulXLen; -}; - -struct CK_KIP_PARAMS { - CK_MECHANISM * pMechanism; - CK_OBJECT_HANDLE hKey; - CK_BYTE * pSeed; - CK_ULONG ulSeedLen; -}; - -struct CK_OTP_PARAM { - CK_OTP_PARAM_TYPE type; - void * pValue; - CK_ULONG ulValueLen; -}; - -struct CK_OTP_PARAMS { - CK_OTP_PARAM * pParams; - CK_ULONG ulCount; -}; - -struct CK_OTP_SIGNATURE_INFO { - CK_OTP_PARAM * pParams; - CK_ULONG ulCount; -}; - -struct CK_PBE_PARAMS { - CK_BYTE * pInitVector; - CK_UTF8CHAR * pPassword; - CK_ULONG ulPasswordLen; - CK_BYTE * pSalt; - CK_ULONG ulSaltLen; - CK_ULONG ulIteration; -}; - -struct CK_PKCS5_PBKD2_PARAMS { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - void * pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - void * pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR * pPassword; - CK_ULONG * ulPasswordLen; -}; - -struct CK_PKCS5_PBKD2_PARAMS2 { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - void * pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - void * pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR * pPassword; - CK_ULONG ulPasswordLen; -}; - -struct CK_PRF_DATA_PARAM { - CK_PRF_DATA_TYPE type; - void * pValue; - CK_ULONG ulValueLen; -}; - -struct CK_RC2_CBC_PARAMS { - CK_ULONG ulEffectiveBits; - CK_BYTE iv[8]; -}; - -struct CK_RC2_MAC_GENERAL_PARAMS { - CK_ULONG ulEffectiveBits; - CK_ULONG ulMacLength; -}; - -struct CK_RC5_CBC_PARAMS { - CK_ULONG ulWordsize; - CK_ULONG ulRounds; - CK_BYTE * pIv; - CK_ULONG ulIvLen; -}; - -struct CK_RC5_MAC_GENERAL_PARAMS { - CK_ULONG ulWordsize; - CK_ULONG ulRounds; - CK_ULONG ulMacLength; -}; - -struct CK_RC5_PARAMS { - CK_ULONG ulWordsize; - CK_ULONG ulRounds; -}; - -struct CK_RSA_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_RSA_PKCS_OAEP_PARAMS * pOAEPParams; -}; - -struct CK_RSA_PKCS_OAEP_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; - void * pSourceData; - CK_ULONG ulSourceDataLen; -}; - -struct CK_RSA_PKCS_PSS_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_ULONG sLen; -}; - -struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_BYTE * pTag; -}; - -struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { - CK_BYTE * pNonce; - CK_ULONG ulNonceLen; - CK_BYTE * pAAD; - CK_ULONG ulAADLen; -}; - -struct CK_SALSA20_PARAMS { - CK_BYTE * pBlockCounter; - CK_BYTE * pNonce; - CK_ULONG ulNonceBits; -}; - -struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE * pData; - CK_ULONG length; -}; - -struct CK_SIGN_ADDITIONAL_CONTEXT { - CK_HEDGE_TYPE hedgeVariant; - CK_BYTE * pContext; - CK_ULONG ulContextLen; -}; - -struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { - CK_ULONG ulPasswordLen; - CK_BYTE * pPassword; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; - CK_ULONG ulPAndGLen; - CK_ULONG ulQLen; - CK_ULONG ulRandomLen; - CK_BYTE * pRandomA; - CK_BYTE * pPrimeP; - CK_BYTE * pBaseG; - CK_BYTE * pSubprimeQ; -}; - -struct CK_SKIPJACK_RELAYX_PARAMS { - CK_ULONG ulOldWrappedXLen; - CK_BYTE * pOldWrappedX; - CK_ULONG ulOldPasswordLen; - CK_BYTE * pOldPassword; - CK_ULONG ulOldPublicDataLen; - CK_BYTE * pOldPublicData; - CK_ULONG ulOldRandomLen; - CK_BYTE * pOldRandomA; - CK_ULONG ulNewPasswordLen; - CK_BYTE * pNewPassword; - CK_ULONG ulNewPublicDataLen; - CK_BYTE * pNewPublicData; - CK_ULONG ulNewRandomLen; - CK_BYTE * pNewRandomA; -}; - -struct CK_SP800_108_COUNTER_FORMAT { - CK_BBOOL bLittleEndian; - CK_ULONG ulWidthInBits; -}; - -struct CK_SP800_108_DKM_LENGTH_FORMAT { - CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; - CK_BBOOL bLittleEndian; - CK_ULONG ulWidthInBits; -}; - -typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; - -struct CK_SP800_108_FEEDBACK_KDF_PARAMS -{ - CK_SP800_108_PRF_TYPE prfType; - CK_ULONG ulNumberOfDataParams; - CK_PRF_DATA_PARAM * pDataParams; - CK_ULONG ulIVLen; - CK_BYTE * pIV; - CK_ULONG ulAdditionalDerivedKeys; - CK_DERIVED_KEY * pAdditionalDerivedKeys; -}; - -struct CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfHashMechanism; - CK_BYTE * pSessionHash; - CK_ULONG ulSessionHashLen; - CK_VERSION * pVersion; -}; - -struct CK_SP800_108_KDF_PARAMS -{ - CK_SP800_108_PRF_TYPE prfType; - CK_ULONG ulNumberOfDataParams; - CK_PRF_DATA_PARAM * pDataParams; - CK_ULONG ulAdditionalDerivedKeys; - CK_DERIVED_KEY * pAdditionalDerivedKeys; -}; - -struct CK_X2RATCHET_INITIALIZE_PARAMS { - CK_BYTE * sk; - CK_OBJECT_HANDLE peer_public_prekey; - CK_OBJECT_HANDLE peer_public_identity; - CK_OBJECT_HANDLE own_public_identity; - CK_BBOOL bEncryptedHeader; - CK_ULONG eCurve; - CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; -}; - -struct CK_X2RATCHET_RESPOND_PARAMS { - CK_BYTE * sk; - CK_OBJECT_HANDLE own_prekey; - CK_OBJECT_HANDLE initiator_identity; - CK_OBJECT_HANDLE own_public_identity; - CK_BBOOL bEncryptedHeader; - CK_ULONG eCurve; - CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; -}; - -struct CK_X3DH_INITIATE_PARAMS { - CK_X3DH_KDF_TYPE kdf; - CK_OBJECT_HANDLE pPeer_identity; - CK_OBJECT_HANDLE pPeer_prekey; - CK_BYTE * pPrekey_signature; - CK_BYTE * pOnetime_key; - CK_OBJECT_HANDLE pOwn_identity; - CK_OBJECT_HANDLE pOwn_ephemeral; -}; - -struct CK_X3DH_RESPOND_PARAMS { - CK_X3DH_KDF_TYPE kdf; - CK_BYTE * pIdentity_id; - CK_BYTE * pPrekey_id; - CK_BYTE * pOnetime_id; - CK_OBJECT_HANDLE pInitiator_identity; - CK_BYTE * pInitiator_ephemeral; -}; - -struct CK_X9_42_DH1_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE * pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; -}; - -struct CK_X9_42_DH2_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE * pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE * pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE * pPublicData2; -}; - -struct CK_X9_42_MQV_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE * OtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE * PublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE * PublicData2; - CK_OBJECT_HANDLE publicKey; -}; - -struct CK_XEDDSA_PARAMS { - CK_XEDDSA_HASH_TYPE hash; -}; - -/* TLS related structure definitions */ -STRUCTDEF(CK_SSL3_KEY_MAT_OUT); -STRUCTDEF(CK_SSL3_KEY_MAT_PARAMS); -STRUCTDEF(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); -STRUCTDEF(CK_SSL3_RANDOM_DATA); -STRUCTDEF(CK_TLS_KDF_PARAMS); -STRUCTDEF(CK_TLS_MAC_PARAMS); -STRUCTDEF(CK_TLS_PRF_PARAMS); -STRUCTDEF(CK_TLS12_KEY_MAT_PARAMS); -STRUCTDEF(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); -STRUCTDEF(CK_WTLS_KEY_MAT_OUT); -STRUCTDEF(CK_WTLS_KEY_MAT_PARAMS); -STRUCTDEF(CK_WTLS_MASTER_KEY_DERIVE_PARAMS); -STRUCTDEF(CK_WTLS_PRF_PARAMS); -STRUCTDEF(CK_WTLS_RANDOM_DATA); - -struct CK_SSL3_KEY_MAT_OUT { - CK_OBJECT_HANDLE hClientMacSecret; - CK_OBJECT_HANDLE hServerMacSecret; - CK_OBJECT_HANDLE hClientKey; - CK_OBJECT_HANDLE hServerKey; - CK_BYTE * pIVClient; - CK_BYTE * pIVServer; -}; - -struct CK_SSL3_RANDOM_DATA { - CK_BYTE * pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE * pServerRandom; - CK_ULONG ulServerRandomLen; -}; - -struct CK_SSL3_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; -}; - -struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION * pVersion; -}; - -struct CK_TLS_KDF_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BYTE * pLabel; - CK_ULONG ulLabelLength; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_BYTE * pContextData; - CK_ULONG ulContextDataLength; -}; - -struct CK_TLS_MAC_PARAMS { - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulMacLength; - CK_ULONG ulServerOrClient; -}; - -struct CK_TLS_PRF_PARAMS { - CK_BYTE * pSeed; - CK_ULONG ulSeedLen; - CK_BYTE * pLabel; - CK_ULONG ulLabelLen; - CK_BYTE * pOutput; - CK_ULONG * pulOutputLen; -}; - -struct CK_TLS12_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT * pReturnedKeyMaterial; - CK_MECHANISM_TYPE prfHashMechanism; -}; - -struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION * pVersion; - CK_MECHANISM_TYPE prfHashMechanism; -}; - -struct CK_WTLS_KEY_MAT_OUT { - CK_OBJECT_HANDLE hMacSecret; - CK_OBJECT_HANDLE hKey; - CK_BYTE * pIV; -}; - -struct CK_WTLS_RANDOM_DATA { - CK_BYTE * pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE * pServerRandom; - CK_ULONG ulServerRandomLen; -}; - -struct CK_WTLS_KEY_MAT_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_ULONG ulSequenceNumber; - CK_BBOOL bIsExport; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_WTLS_KEY_MAT_OUT * pReturnedKeyMaterial; -}; - -struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_BYTE * pVersion; -}; - -struct CK_WTLS_PRF_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_BYTE * pSeed; - CK_ULONG ulSeedLen; - CK_BYTE * pLabel; - CK_ULONG ulLabelLen; - CK_BYTE * pOutput; - CK_ULONG * pulOutputLen; -}; - -/* PKCS11 Functions */ -extern CK_RV C_Initialize(void *); -extern CK_RV C_Finalize(void *); -extern CK_RV C_GetInfo(CK_INFO *); -extern CK_RV C_GetFunctionList(CK_FUNCTION_LIST **); -extern CK_RV C_GetSlotList(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); -extern CK_RV C_GetSlotInfo(CK_SLOT_ID, CK_SLOT_INFO *); -extern CK_RV C_GetTokenInfo(CK_SLOT_ID, CK_TOKEN_INFO *); -extern CK_RV C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE *, CK_ULONG *); -extern CK_RV C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, - CK_MECHANISM_INFO *); -extern CK_RV C_InitToken(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *); -extern CK_RV C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); -extern CK_RV C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_UTF8CHAR *, - CK_ULONG); -extern CK_RV C_OpenSession(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, - CK_SESSION_HANDLE *); -extern CK_RV C_CloseSession(CK_SESSION_HANDLE); -extern CK_RV C_CloseAllSessions(CK_SLOT_ID); -extern CK_RV C_GetSessionInfo(CK_SESSION_HANDLE, CK_SESSION_INFO *); -extern CK_RV C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); -extern CK_RV C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, CK_ULONG); -extern CK_RV C_Logout(CK_SESSION_HANDLE); -extern CK_RV C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -extern CK_RV C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE *, - CK_ULONG, CK_OBJECT_HANDLE *); -extern CK_RV C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -extern CK_RV C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG *); -extern CK_RV C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG); -extern CK_RV C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG); -extern CK_RV C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG); -extern CK_RV C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, CK_ULONG, - CK_ULONG *); -extern CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE); -extern CK_RV C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_Encrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_Decrypt(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM *); -extern CK_RV C_Digest(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -extern CK_RV C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE); -extern CK_RV C_Sign(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_SignFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_SignRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_Verify(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG); -extern CK_RV C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -extern CK_RV C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_ATTRIBUTE *, - CK_ULONG, CK_OBJECT_HANDLE *); -extern CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, - CK_ULONG, CK_OBJECT_HANDLE *, - CK_OBJECT_HANDLE *); -extern CK_RV C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, - CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG *); -extern CK_RV C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, - CK_BYTE *, CK_ULONG, CK_ATTRIBUTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -extern CK_RV C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM *, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); -extern CK_RV C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE); -extern CK_RV C_CancelFunction(CK_SESSION_HANDLE); -extern CK_RV C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID *, void *); -extern CK_RV C_GetInterfaceList(CK_INTERFACE *, CK_ULONG *); -extern CK_RV C_GetInterface(CK_UTF8CHAR *, CK_VERSION *, CK_INTERFACE **, - CK_FLAGS); -extern CK_RV C_LoginUser(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, - CK_ULONG, CK_UTF8CHAR *, CK_ULONG); -extern CK_RV C_SessionCancel(CK_SESSION_HANDLE, CK_FLAGS); -extern CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_EncryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG); -extern CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, - CK_FLAGS); -extern CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE); -extern CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_DecryptMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG); -extern CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, - CK_FLAGS); -extern CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE); -extern CK_RV C_MessageSignInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_SignMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG *); -extern CK_RV C_SignMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); -extern CK_RV C_SignMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); -extern CK_RV C_MessageSignFinal(CK_SESSION_HANDLE); -extern CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -extern CK_RV C_VerifyMessage(CK_SESSION_HANDLE, void *, CK_ULONG, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE, void *, CK_ULONG); -extern CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); -extern CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE); -extern CK_RV C_EncapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *, CK_OBJECT_HANDLE *); -extern CK_RV C_DecapsulateKey(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_OBJECT_HANDLE *); -extern CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifySignature(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -extern CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE); -extern CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE, - CK_SESSION_VALIDATION_FLAGS_TYPE, - CK_FLAGS *); -extern CK_RV C_AsyncComplete(CK_SESSION_HANDLE, CK_UTF8CHAR *, - CK_ASYNC_DATA *); -extern CK_RV C_AsyncGetID(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); -extern CK_RV C_AsyncJoin(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, CK_BYTE *, - CK_ULONG); -extern CK_RV C_WrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -extern CK_RV C_UnwrapKeyAuthenticated(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_BYTE *, - CK_ULONG, CK_ATTRIBUTE *, - CK_ULONG, CK_BYTE *, CK_ULONG, - CK_OBJECT_HANDLE *); - -typedef CK_RV (* CK_C_Initialize)(void *); -typedef CK_RV (* CK_C_Finalize)(void *); -typedef CK_RV (* CK_C_GetInfo)(CK_INFO *); -typedef CK_RV (* CK_C_GetFunctionList)(CK_FUNCTION_LIST **); -typedef CK_RV (* CK_C_GetSlotList)(CK_BBOOL, CK_SLOT_ID *, CK_ULONG *); -typedef CK_RV (* CK_C_GetSlotInfo)(CK_SLOT_ID, CK_SLOT_INFO *); -typedef CK_RV (* CK_C_GetTokenInfo)(CK_SLOT_ID, CK_TOKEN_INFO *); -typedef CK_RV (* CK_C_GetMechanismList)(CK_SLOT_ID, CK_MECHANISM_TYPE *, - CK_ULONG *); -typedef CK_RV (* CK_C_GetMechanismInfo)(CK_SLOT_ID, CK_MECHANISM_TYPE, - CK_MECHANISM_INFO *); -typedef CK_RV (* CK_C_InitToken)(CK_SLOT_ID, CK_UTF8CHAR *, CK_ULONG, - CK_UTF8CHAR *); -typedef CK_RV (* CK_C_InitPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG); -typedef CK_RV (* CK_C_SetPIN)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, - CK_UTF8CHAR *, CK_ULONG); -typedef CK_RV (* CK_C_OpenSession)(CK_SLOT_ID, CK_FLAGS, void *, CK_NOTIFY, - CK_SESSION_HANDLE *); -typedef CK_RV (* CK_C_CloseSession)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_CloseAllSessions)(CK_SLOT_ID); -typedef CK_RV (* CK_C_GetSessionInfo)(CK_SESSION_HANDLE, CK_SESSION_INFO *); -typedef CK_RV (* CK_C_GetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_SetOperationState)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_OBJECT_HANDLE, CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_Login)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, - CK_ULONG); -typedef CK_RV (* CK_C_Logout)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_CreateObject)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_CopyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_DestroyObject)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_GetObjectSize)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ULONG *); -typedef CK_RV (* CK_C_GetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG); -typedef CK_RV (* CK_C_SetAttributeValue)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, - CK_ATTRIBUTE *, CK_ULONG); -typedef CK_RV (* CK_C_FindObjectsInit)(CK_SESSION_HANDLE, CK_ATTRIBUTE *, - CK_ULONG); -typedef CK_RV (* CK_C_FindObjects)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE *, - CK_ULONG, CK_ULONG *); -typedef CK_RV (* CK_C_FindObjectsFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_EncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_Encrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_EncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_EncryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_Decrypt)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DigestInit)(CK_SESSION_HANDLE, CK_MECHANISM *); -typedef CK_RV (* CK_C_Digest)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_DigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_DigestKey)(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_DigestFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_SignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_Sign)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_SignUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_SignFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_SignRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_SignRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_VerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_Verify)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG); -typedef CK_RV (* CK_C_VerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_VerifyFinal)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_VerifyRecoverInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_VerifyRecover)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DigestEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptDigestUpdate)(CK_SESSION_HANDLE, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_SignEncryptUpdate)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptVerifyUpdate)(CK_SESSION_HANDLE, CK_BYTE *, - CK_ULONG, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_GenerateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_ATTRIBUTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_GenerateKeyPair)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_ATTRIBUTE *, CK_ULONG, CK_ATTRIBUTE *, - CK_ULONG, CK_OBJECT_HANDLE *, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_WrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_UnwrapKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_BYTE *, CK_ULONG, - CK_ATTRIBUTE *, CK_ULONG, CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_DeriveKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_ATTRIBUTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_SeedRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_GenerateRandom)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_GetFunctionStatus)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_CancelFunction)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_WaitForSlotEvent)(CK_FLAGS, CK_SLOT_ID *, void *); -typedef CK_RV (* CK_C_GetInterfaceList)(CK_INTERFACE *, CK_ULONG *); -typedef CK_RV (* CK_C_GetInterface)(CK_UTF8CHAR *, CK_VERSION *, - CK_INTERFACE **, CK_FLAGS); -typedef CK_RV (* CK_C_LoginUser)(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR *, - CK_ULONG, CK_UTF8CHAR *, CK_ULONG); -typedef CK_RV (* CK_C_SessionCancel)(CK_SESSION_HANDLE, CK_FLAGS); -typedef CK_RV (* CK_C_MessageEncryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_EncryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_EncryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_EncryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *, CK_FLAGS); -typedef CK_RV (* CK_C_MessageEncryptFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_MessageDecryptInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_DecryptMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, - CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_DecryptMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_DecryptMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *, CK_FLAGS); -typedef CK_RV (* CK_C_MessageDecryptFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_MessageSignInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_SignMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *); -typedef CK_RV (* CK_C_SignMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); -typedef CK_RV (* CK_C_SignMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_MessageSignFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_MessageVerifyInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE); -typedef CK_RV (* CK_C_VerifyMessage)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_VerifyMessageBegin)(CK_SESSION_HANDLE, void *, CK_ULONG); -typedef CK_RV (* CK_C_VerifyMessageNext)(CK_SESSION_HANDLE, void *, CK_ULONG, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG); -typedef CK_RV (* CK_C_MessageVerifyFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_EncapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_ATTRIBUTE *, - CK_ULONG, CK_BYTE *, CK_ULONG *, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_DecapsulateKey)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_ATTRIBUTE *, - CK_ULONG, CK_BYTE *, CK_ULONG, - CK_OBJECT_HANDLE *); -typedef CK_RV (* CK_C_VerifySignatureInit)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_BYTE *, - CK_ULONG); -typedef CK_RV (* CK_C_VerifySignature)(CK_SESSION_HANDLE, CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_VerifySignatureUpdate)(CK_SESSION_HANDLE, CK_BYTE *, - CK_ULONG); -typedef CK_RV (* CK_C_VerifySignatureFinal)(CK_SESSION_HANDLE); -typedef CK_RV (* CK_C_GetSessionValidationFlags)(CK_SESSION_HANDLE, - CK_SESSION_VALIDATION_FLAGS_TYPE, - CK_FLAGS *); -typedef CK_RV (* CK_C_AsyncComplete)(CK_SESSION_HANDLE, CK_UTF8CHAR *, - CK_ASYNC_DATA *); -typedef CK_RV (* CK_C_AsyncGetID)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG *); -typedef CK_RV (* CK_C_AsyncJoin)(CK_SESSION_HANDLE, CK_UTF8CHAR *, CK_ULONG, - CK_BYTE *, CK_ULONG); -typedef CK_RV (* CK_C_WrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, - CK_BYTE *, CK_ULONG, CK_BYTE *, - CK_ULONG *); -typedef CK_RV (* CK_C_UnwrapKeyAuthenticated)(CK_SESSION_HANDLE, CK_MECHANISM *, - CK_OBJECT_HANDLE, CK_BYTE *, - CK_ULONG, CK_ATTRIBUTE *, - CK_ULONG, CK_BYTE *, CK_ULONG, - CK_OBJECT_HANDLE *); - -struct CK_FUNCTION_LIST_3_2 { - CK_VERSION version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; - CK_C_GetInterfaceList C_GetInterfaceList; - CK_C_GetInterface C_GetInterface; - CK_C_LoginUser C_LoginUser; - CK_C_SessionCancel C_SessionCancel; - CK_C_MessageEncryptInit C_MessageEncryptInit; - CK_C_EncryptMessage C_EncryptMessage; - CK_C_EncryptMessageBegin C_EncryptMessageBegin; - CK_C_EncryptMessageNext C_EncryptMessageNext; - CK_C_MessageEncryptFinal C_MessageEncryptFinal; - CK_C_MessageDecryptInit C_MessageDecryptInit; - CK_C_DecryptMessage C_DecryptMessage; - CK_C_DecryptMessageBegin C_DecryptMessageBegin; - CK_C_DecryptMessageNext C_DecryptMessageNext; - CK_C_MessageDecryptFinal C_MessageDecryptFinal; - CK_C_MessageSignInit C_MessageSignInit; - CK_C_SignMessage C_SignMessage; - CK_C_SignMessageBegin C_SignMessageBegin; - CK_C_SignMessageNext C_SignMessageNext; - CK_C_MessageSignFinal C_MessageSignFinal; - CK_C_MessageVerifyInit C_MessageVerifyInit; - CK_C_VerifyMessage C_VerifyMessage; - CK_C_VerifyMessageBegin C_VerifyMessageBegin; - CK_C_VerifyMessageNext C_VerifyMessageNext; - CK_C_MessageVerifyFinal C_MessageVerifyFinal; - CK_C_EncapsulateKey C_EncapsulateKey; - CK_C_DecapsulateKey C_DecapsulateKey; - CK_C_VerifySignatureInit C_VerifySignatureInit; - CK_C_VerifySignature C_VerifySignature; - CK_C_VerifySignatureUpdate C_VerifySignatureUpdate; - CK_C_VerifySignatureFinal C_VerifySignatureFinal; - CK_C_GetSessionValidationFlags C_GetSessionValidationFlags; - CK_C_AsyncComplete C_AsyncComplete; - CK_C_AsyncGetID C_AsyncGetID; - CK_C_AsyncJoin C_AsyncJoin; - CK_C_WrapKeyAuthenticated C_WrapKeyAuthenticated ; - CK_C_UnwrapKeyAuthenticated C_UnwrapKeyAuthenticated ; -}; - -struct CK_FUNCTION_LIST_3_0 { - CK_VERSION version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; - CK_C_GetInterfaceList C_GetInterfaceList; - CK_C_GetInterface C_GetInterface; - CK_C_LoginUser C_LoginUser; - CK_C_SessionCancel C_SessionCancel; - CK_C_MessageEncryptInit C_MessageEncryptInit; - CK_C_EncryptMessage C_EncryptMessage; - CK_C_EncryptMessageBegin C_EncryptMessageBegin; - CK_C_EncryptMessageNext C_EncryptMessageNext; - CK_C_MessageEncryptFinal C_MessageEncryptFinal; - CK_C_MessageDecryptInit C_MessageDecryptInit; - CK_C_DecryptMessage C_DecryptMessage; - CK_C_DecryptMessageBegin C_DecryptMessageBegin; - CK_C_DecryptMessageNext C_DecryptMessageNext; - CK_C_MessageDecryptFinal C_MessageDecryptFinal; - CK_C_MessageSignInit C_MessageSignInit; - CK_C_SignMessage C_SignMessage; - CK_C_SignMessageBegin C_SignMessageBegin; - CK_C_SignMessageNext C_SignMessageNext; - CK_C_MessageSignFinal C_MessageSignFinal; - CK_C_MessageVerifyInit C_MessageVerifyInit; - CK_C_VerifyMessage C_VerifyMessage; - CK_C_VerifyMessageBegin C_VerifyMessageBegin; - CK_C_VerifyMessageNext C_VerifyMessageNext; - CK_C_MessageVerifyFinal C_MessageVerifyFinal; -}; - -struct CK_FUNCTION_LIST { - CK_VERSION version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; -}; - -/* End of header from https://github.com/latchset/pkcs11-headers */ +#include "pd-pkcs11.h" /* * A mask for new GOST algorithms. @@ -2837,5 +83,4 @@ struct CK_FUNCTION_LIST { } #endif -// clang-fromat on #endif /* PKCS11_H */ From 220bc82e08e71d720d742ce2e8713dc9af14dade Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 17 Dec 2024 21:29:40 +0200 Subject: [PATCH 4039/4321] MSI version number Signed-off-by: Raul Metsma --- .appveyor.yml | 6 +++--- .github/workflows/windows.yml | 21 ++++++++------------- win32/Make.rules.mak | 1 + win32/Makefile.mak | 6 ++++-- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 04d48e35ed..e306e53be5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -36,9 +36,9 @@ install: https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` throw "There are newer queued builds for this pull request, failing early." } - - ps: $env:PACKAGE_NAME=(git describe --tags --abbrev=0) + - ps: $env:PACKAGE_VERSION=(git describe --tags --abbrev=0) - ps: $env:OPENSSL_PF = If ($env:Platform -eq "x86") { "Win32" } Else { "Win64" } - - ps: $env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}_${env:OPENSSL_PF}" + - ps: $env:ARTIFACT="OpenSC-${env:PACKAGE_VERSION}_${env:OPENSSL_PF}" - ps: >- If ($env:Configuration -Like "*Light*") { $env:ARTIFACT+="-Light" @@ -91,7 +91,7 @@ build_script: $env:OPENPACE_DIR="C:\openpace-${env:OPENSSL_PF}" } - nmake /nologo /f Makefile.mak opensc.msi - - move win32\OpenSC.msi %ARTIFACT%.msi + - move win32\OpenSC*.msi %ARTIFACT%.msi # put all pdb files for dump analysis, but this consumes approx 100 MB per build - md %ARTIFACT%-Debug - ps: >- diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ab9d7ae3b6..d4c93d3d77 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -22,7 +22,7 @@ jobs: matrix: platform: [x86, x64, arm64] configuration: [Light, Release] - image: [windows-2022] + image: [windows-2025] include: - platform: x86 setenv: amd64_x86 @@ -37,9 +37,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5 - - name: Git describe - id: ghd - uses: proudust/gh-describe@v2 - name: Package name shell: bash run: | @@ -52,7 +49,7 @@ jobs: else SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" fi - echo ARTIFACT=${{ steps.ghd.outputs.tag }}${SUFFIX}_${{ matrix.platform }}${{ matrix.configuration == 'Light' && '-Light' || '' }} >> $GITHUB_ENV + echo "DIST_SUFFIX=${{ matrix.configuration == 'Light' && '-Light' || '' }}${SUFFIX}" >> $GITHUB_ENV - name: Install CPDK run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Setup dev env @@ -64,7 +61,7 @@ jobs: uses: actions/cache@v4 with: path: ${{ github.workspace }}/vcpkg_cache - key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/workflows/windows.yml', '.github/vcpkg.json') }} + key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json') }} - name: Prepare vcpkg if: matrix.configuration == 'Release' uses: lukka/run-vcpkg@v11 @@ -117,18 +114,16 @@ jobs: echo "OPENPACE_DEF=/DENABLE_OPENPACE" >> $env:GITHUB_ENV echo "OPENPACE_DIR=${env:GITHUB_WORKSPACE}\openpace-${env:OPENPACE_VER}" >> $env:GITHUB_ENV - name: Build OpenSC - run: | - nmake /nologo /f Makefile.mak opensc.msi - move win32\OpenSC.msi OpenSC-${env:ARTIFACT}.msi + run: nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} - path: ./*.msi + path: ./win32/*.msi - name: Archive debug artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: - name: OpenSC-${{ env.ARTIFACT }}-Debug + name: debug_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: | ./src/**/*.pdb ./win32/*.pdb diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index ed3fc87b74..820560d734 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -18,6 +18,7 @@ MINIDRIVER_DEF = /DENABLE_MINIDRIVER WIXFLAGS = -d ENABLE_MINIDRIVER $(WIXFLAGS) #Build MSI with the Windows Installer XML (WIX) toolkit +MSI_NAME = $(PRODUCT_NAME)-$(PACKAGE_VERSION_MAJOR).$(PACKAGE_VERSION_MINOR).$(PACKAGE_VERSION_FIX)_$(PLATFORM)$(DIST_SUFFIX).msi !IF "$(WIX_PACKAGES)" == "" WIX_PACKAGES = $(TOPDIR)\win32\packages WIX_VERSION = 6.0.2 diff --git a/win32/Makefile.mak b/win32/Makefile.mak index 8c42f1c83f..02a37b83d3 100644 --- a/win32/Makefile.mak +++ b/win32/Makefile.mak @@ -10,8 +10,10 @@ config.h: winconfig.h customactions.dll: versioninfo-customactions.res $*.obj $*.def link /dll $(LINKFLAGS) /out:$@ /def:$*.def versioninfo-customactions.res customactions.obj msi.lib $(WIX_LIBS) Advapi32.lib User32.lib Version.lib Shell32.lib -OpenSC.msi: OpenSC.wxs customactions.dll - wix build -arch $(PLATFORM) -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -d SOURCE_DIR=$(TOPDIR) $(WIXFLAGS) OpenSC.wxs +$(MSI_NAME): OpenSC.wxs customactions.dll + wix build -arch $(PLATFORM) -o $(MSI_NAME) -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -d SOURCE_DIR=$(TOPDIR) $(WIXFLAGS) OpenSC.wxs + +OpenSC.msi: $(MSI_NAME) clean:: del /Q config.h *.msi *.wixobj *.wixpdb From 5920fe892f75d644b735b06c4edb476cdd35c8ad Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 10:21:41 +0100 Subject: [PATCH 4040/4321] pkcs11-spy: Avoid invalid assignments CID 500043 Thanks coverity Signed-off-by: Jakub Jelen --- src/pkcs11/pkcs11-spy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 2dbfaee005..0c08646006 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -69,9 +69,9 @@ allocate_function_list(int v) CK_FUNCTION_LIST_3_2_PTR list_3_2 = NULL; if (v == 30) { - list = malloc(sizeof(CK_FUNCTION_LIST_3_0)); + list = (CK_FUNCTION_LIST_PTR)malloc(sizeof(CK_FUNCTION_LIST_3_0)); } else if (v == 32) { - list = malloc(sizeof(CK_FUNCTION_LIST_3_2)); + list = (CK_FUNCTION_LIST_PTR)malloc(sizeof(CK_FUNCTION_LIST_3_2)); } else { list = malloc(sizeof(CK_FUNCTION_LIST)); } From 59b333fa853a85d1da5759fdd3dbf9777c482822 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 17:03:46 +0100 Subject: [PATCH 4041/4321] profile: Avoid discarting const on assignment profile.c:2091:41: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] 2091 | if ((macro_name = strchr(str, '$'))) { | ^ Signed-off-by: Jakub Jelen --- src/pkcs15init/profile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 85bd8438b5..f4c744646c 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2013,9 +2013,9 @@ is_macro_character(char c) } static int -get_inner_word(char *str, char word[WORD_SIZE]) +get_inner_word(const char *str, char word[WORD_SIZE]) { - char *inner = NULL; + const char *inner = NULL; size_t len = 0; inner = str; @@ -2039,7 +2039,7 @@ static int check_macro_reference_loop(const char *start_name, sc_macro_t *macro, sc_profile_t *profile, int depth) { scconf_list *value; - char *name = NULL; + const char *name = NULL; sc_macro_t *m; char word[WORD_SIZE]; @@ -2087,7 +2087,7 @@ build_argv(struct state *cur, const char *cmdname, str = list->data; if (str[0] != '$') { /* When str contains macro inside, macro reference loop needs to be checked */ - char *macro_name = NULL; + const char *macro_name = NULL; if ((macro_name = strchr(str, '$'))) { /* Macro does not to start at the first position */ char word[WORD_SIZE]; From bfc6a0f4b38b021a16f0c992bd89153396d0e124 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 17:28:06 +0100 Subject: [PATCH 4042/4321] opensc-explorer: Avoid assigning const to non-const pointer Signed-off-by: Jakub Jelen --- src/tools/opensc-explorer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 108e4f8764..d05ad5cace 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -477,7 +477,7 @@ static int pattern_match(const char *pattern, const char *string) } /* simple character class matching a single character */ else if (*pattern == '[') { - char *end = strchr(pattern, ']'); + const char *end = strchr(pattern, ']'); int match = 0; for (pattern++; end != NULL && pattern != end; pattern++) { From aeac552280322ea780f0d7482a9ffbe48664bec4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 16:30:14 +0100 Subject: [PATCH 4043/4321] compat: Avoid const -> nonconst assignment compat_getopt_main.c:98:22: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] 98 | if ((match = strchr(letters, tolower(c)))) | ^ Signed-off-by: Jakub Jelen --- src/common/compat_getopt_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/compat_getopt_main.c b/src/common/compat_getopt_main.c index 3546be5a28..d4e91d1739 100644 --- a/src/common/compat_getopt_main.c +++ b/src/common/compat_getopt_main.c @@ -94,7 +94,7 @@ handle(char *progname, if (rotate && isalpha(c)) { const char *letters = "abcdefghijklmnopqrstuvwxyz"; - char *match; + const char *match; if ((match = strchr(letters, tolower(c)))) { char rc = letters[(match - letters + rotate) % 26]; From f729259158fbaa32fa796dbf6dd045c80c453d78 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 12:54:40 +0100 Subject: [PATCH 4044/4321] tests: Rework how external tests are invoked Signed-off-by: Jakub Jelen --- tests/test-kryoptic.sh | 25 +++++++++++++------- tests/test-p11test.sh | 1 + tests/test-pkcs11-tool-allowed-mechanisms.sh | 1 + tests/test-pkcs11-tool-import.sh | 1 + tests/test-pkcs11-tool-sign-verify.sh | 1 + tests/test-pkcs11-tool-sym-crypt-test.sh | 1 + tests/test-pkcs11-tool-test-threads.sh | 1 + tests/test-pkcs11-tool-test.sh | 1 + tests/test-pkcs11-tool-unwrap-wrap-test.sh | 5 ++-- tests/test-pkcs11-tool-uri-with-slot-id.sh | 1 + tests/test-softhsm.sh | 25 +++++++++++++------- tests/test-softokn.sh | 17 +++++++++---- 12 files changed, 58 insertions(+), 22 deletions(-) diff --git a/tests/test-kryoptic.sh b/tests/test-kryoptic.sh index c235da55ca..fc5b2b4b18 100755 --- a/tests/test-kryoptic.sh +++ b/tests/test-kryoptic.sh @@ -1,12 +1,21 @@ -#!/bin/bash -e +#!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for Kryoptic token..." -$SOURCE_PATH/tests/test-p11test.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-import.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh kryoptic -#$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt-test.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-test.sh kryoptic -$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh kryoptic +export TEST_PKCS11_BACKEND=kryoptic +pushd tests +make check \ + TESTS='test-p11test.sh + test-pkcs11-tool-allowed-mechanisms.sh + test-pkcs11-tool-import.sh + test-pkcs11-tool-sign-verify.sh + test-pkcs11-tool-test.sh + test-pkcs11-tool-unwrap-wrap-test.sh' +# test-pkcs11-tool-sym-crypt-test.sh # TODO +RV=$? +popd +if [ $RV -ne 0 ]; then + ./.github/dump-logs.sh + exit $RV +fi diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 69130ae911..fbc413d924 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "softokn" ]; then echo "p11test not supported" diff --git a/tests/test-pkcs11-tool-allowed-mechanisms.sh b/tests/test-pkcs11-tool-allowed-mechanisms.sh index 9fdcd31f77..88a48706ce 100755 --- a/tests/test-pkcs11-tool-allowed-mechanisms.sh +++ b/tests/test-pkcs11-tool-allowed-mechanisms.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "softokn" ]; then echo "Generate key-pair with CKA_ALLOWED_MECHANISMS not supported" diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index 915608f384..244db6327a 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 96674be974..9f0d40511d 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm diff --git a/tests/test-pkcs11-tool-sym-crypt-test.sh b/tests/test-pkcs11-tool-sym-crypt-test.sh index da4a496501..4bda25e3ae 100755 --- a/tests/test-pkcs11-tool-sym-crypt-test.sh +++ b/tests/test-pkcs11-tool-sym-crypt-test.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "softokn" ]; then echo "p11test not supported" diff --git a/tests/test-pkcs11-tool-test-threads.sh b/tests/test-pkcs11-tool-test-threads.sh index a961e634ff..b64c7d4e8c 100755 --- a/tests/test-pkcs11-tool-test-threads.sh +++ b/tests/test-pkcs11-tool-test-threads.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index d84d3e7c2d..c423512409 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index 57d47ac9b9..50d01e8ee5 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -40,6 +40,7 @@ function test_unwrapped_aes_encryption() { } TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm @@ -286,7 +287,7 @@ if [[ -n $is_openssl_3 ]]; then # Wrap with OpenSSL openssl enc -id-aes256-wrap -e -K $AES_WRAP -iv $IV -in aes.key -out openssl_wrapped.data assert $? "OpenSSL / Failed to AES KEY WRAP wrap AES key" - + # Wrap with pkcs11-tool $PKCS11_TOOL "${PRIV_ARGS[@]}" --wrap -m AES-KEY-WRAP --id $ID_AES_WRAP --iv $IV --application-id $ID_AES_UNWRAPPED_4 \ --output-file pkcs11_wrapped.data @@ -349,7 +350,7 @@ if [[ -n $is_openssl_3 ]]; then # Compare original and unwrapped key compare_keys $? aes.key unwrapped.key - + # Check if AES key was correctly unwrapped with encryption test_unwrapped_aes_encryption $AES_256_KEY $ID_AES_UNWRAPPED_4 fi diff --git a/tests/test-pkcs11-tool-uri-with-slot-id.sh b/tests/test-pkcs11-tool-uri-with-slot-id.sh index c8ea54964e..f2bfbe93b6 100755 --- a/tests/test-pkcs11-tool-uri-with-slot-id.sh +++ b/tests/test-pkcs11-tool-uri-with-slot-id.sh @@ -2,6 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 +TOKENTYPE=${TOKENTYPE:-$TEST_PKCS11_BACKEND} if [ "${TOKENTYPE}" == "" ]; then TOKENTYPE=softhsm diff --git a/tests/test-softhsm.sh b/tests/test-softhsm.sh index f456c6dc2e..f8d5957c98 100755 --- a/tests/test-softhsm.sh +++ b/tests/test-softhsm.sh @@ -1,12 +1,21 @@ -#!/bin/bash -e +#!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for SoftHSM token..." -$SOURCE_PATH/tests/test-p11test.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-allowed-mechanisms.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-sym-crypt-test.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-test.sh softhsm -$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softhsm +export TEST_PKCS11_BACKEND=softhsm +pushd tests +make check \ + TESTS='test-p11test.sh + test-pkcs11-tool-allowed-mechanisms.sh + test-pkcs11-tool-import.sh + test-pkcs11-tool-sign-verify.sh + test-pkcs11-tool-sym-crypt-test.sh + test-pkcs11-tool-test.sh + test-pkcs11-tool-unwrap-wrap-test.sh' +RV=$? +popd +if [ $RV -ne 0 ]; then + ./.github/dump-logs.sh + exit $RV +fi diff --git a/tests/test-softokn.sh b/tests/test-softokn.sh index 813aec97ea..9e3c2c409e 100755 --- a/tests/test-softokn.sh +++ b/tests/test-softokn.sh @@ -1,8 +1,17 @@ -#!/bin/bash -e +#!/bin/bash SOURCE_PATH=${SOURCE_PATH:-..} echo "Running all supported tests for NSS Softokn token..." -$SOURCE_PATH/tests/test-pkcs11-tool-sign-verify.sh softokn -$SOURCE_PATH/tests/test-pkcs11-tool-import.sh softokn -$SOURCE_PATH/tests/test-pkcs11-tool-unwrap-wrap-test.sh softokn +export TEST_PKCS11_BACKEND=softokn +pushd tests +make check \ + TESTS='test-pkcs11-tool-import.sh + test-pkcs11-tool-sign-verify.sh + test-pkcs11-tool-unwrap-wrap-test.sh' +RV=$? +popd +if [ $RV -ne 0 ]; then + ./.github/dump-logs.sh + exit $RV +fi From daed264f553f460e820d6b0b5ac4d69339d364b9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 16:41:37 +0100 Subject: [PATCH 4045/4321] tests: Adjust kryoptic test reference file Signed-off-by: Jakub Jelen --- tests/kryoptic_ref.json | 132 ++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/kryoptic_ref.json b/tests/kryoptic_ref.json index 3325acdd1c..0c3c0fa2de 100644 --- a/tests/kryoptic_ref.json +++ b/tests/kryoptic_ref.json @@ -1219,135 +1219,135 @@ ], [ "06", + "EDDSA", + "YES", + "" + ], + [ + "07", + "EDDSA", + "YES", + "" + ], + [ + "10", "ML_DSA", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA224", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA256", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA384", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA3_512", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA3_224", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA3_256", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA3_384", "YES", "" ], [ - "06", + "10", "HASH_ML_DSA_SHA3_512", "YES", "" ], [ - "08", + "12", "SLH_DSA", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA224", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA256", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA384", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA3_512", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA3_224", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA3_256", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA3_384", "YES", "" ], [ - "08", + "12", "HASH_SLH_DSA_SHA3_512", "YES", "" - ], - [ - "09", - "EDDSA", - "YES", - "" - ], - [ - "10", - "EDDSA", - "YES", - "" ]], "result": "pass" }, @@ -1558,9 +1558,9 @@ ], [ "06", - "ML-DSA-65", - "ML-DSA", - "15616", + "ed25519", + "EDDSA", + "256", "", "YES", "YES", @@ -1570,16 +1570,18 @@ "", "", "", - "", - "", + "YES", + "YES", "" ], [ "07", - "ML-KEM-768", - "ML-KEM", - "0", + "ed448", + "EDDSA", + "456", "", + "YES", + "YES", "", "", "", @@ -1588,15 +1590,13 @@ "", "YES", "YES", - "", - "", "" ], [ "08", - "SLH-DSA-SHA2-192S", - "SLH-DSA", - "384", + "x25519", + "XEDDSA", + "256", "", "YES", "YES", @@ -1606,15 +1606,15 @@ "", "", "", - "", - "", + "YES", + "YES", "" ], [ "09", - "ed25519", - "EDDSA", - "256", + "x448", + "XEDDSA", + "448", "", "YES", "YES", @@ -1630,9 +1630,9 @@ ], [ "10", - "ed448", - "EDDSA", - "456", + "ML-DSA-65", + "ML-DSA", + "15616", "", "YES", "YES", @@ -1642,18 +1642,16 @@ "", "", "", - "YES", - "YES", + "", + "", "" ], [ "11", - "x25519", - "XEDDSA", - "256", + "ML-KEM-768", + "ML-KEM", + "0", "", - "YES", - "YES", "", "", "", @@ -1662,13 +1660,15 @@ "", "YES", "YES", + "", + "", "" ], [ "12", - "x448", - "XEDDSA", - "448", + "SLH-DSA-SHA2-192S", + "SLH-DSA", + "384", "", "YES", "YES", @@ -1678,8 +1678,8 @@ "", "", "", - "YES", - "YES", + "", + "", "" ]], "result": "pass" @@ -10961,12 +10961,12 @@ "YES" ], [ - "11", + "08", "ECDH1_DERIVE", "YES" ], [ - "12", + "09", "ECDH1_DERIVE", "YES" ]], From 5bb402f3b34f53847532d9695a4aee73e3f4a3af Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 16:58:02 +0100 Subject: [PATCH 4046/4321] tests: Skip SHA1 tests with kryoptic Signed-off-by: Jakub Jelen --- tests/test-pkcs11-tool-sign-verify.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 9f0d40511d..a7e354b1bd 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -33,6 +33,10 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do if [[ "$ID" == "rhel" || "$ID_LIKE" =~ ".*rhel.*" ]] && [[ "$VERSION" -gt 8 ]] && [[ "$HASH" == "SHA1" ]]; then RETOSSL="1" fi + # Kryoptic does not do SHA1 anymore + if [[ "$TOKENTYPE" == "kryoptic" ]] && [[ "$HASH" == "SHA1" ]]; then + continue; + fi for SIGN_KEY in "01" "02"; do METHOD="RSA-PKCS" # RSA-PKCS works only on small data - generate small data: From f228715c1e686fa78f2ffc6b479600dfdb850162 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 17:49:57 +0100 Subject: [PATCH 4047/4321] tests: Build kryoptic with pqc support This requires Fedora 43, but github images are still stuck on f42 so using quay directly. Signed-off-by: Jakub Jelen --- .github/setup-kryoptic.sh | 2 +- .github/workflows/external-pkcs11.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/setup-kryoptic.sh b/.github/setup-kryoptic.sh index 60a5fecf07..5765b17370 100755 --- a/.github/setup-kryoptic.sh +++ b/.github/setup-kryoptic.sh @@ -5,5 +5,5 @@ if [ ! -d "kryoptic" ]; then git clone https://github.com/latchset/kryoptic.git fi pushd kryoptic -cargo build --features dynamic,standard,nssdb +cargo build --features dynamic,standard,nssdb,pqc popd diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 73fc6d9bad..4442b9da6a 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -33,7 +33,7 @@ jobs: test-kryoptic: runs-on: ubuntu-24.04 container: - image: fedora:latest + image: quay.io/fedora/fedora:latest env: SOURCE_PATH: ./ BUILD_PATH: ./ @@ -90,11 +90,11 @@ jobs: env: LD_LIBRARY_PATH: /usr/local/lib run: tests/test-softhsm.sh - + test-interoperability: runs-on: ubuntu-24.04 container: - image: fedora:latest + image: quay.io/fedora/fedora:latest env: SOURCE_PATH: ./ BUILD_PATH: ./ From 2a816986683bf694cd1f664236104c642b920fd2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 26 Nov 2025 16:44:35 +0100 Subject: [PATCH 4048/4321] pkcs11-tool: Do not query for encapsulate/decapsulate needlessly Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 37f14f93c7..e1a824861b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6819,11 +6819,11 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("%sderive", sepa); sepa = ", "; } - if (getENCAPSULATE(sess, obj)) { + if (pub && getENCAPSULATE(sess, obj)) { printf("%sencapsulate", sepa); sepa = ", "; } - if (getDECAPSULATE(sess, obj)) { + if ((!pub && !sec) && getDECAPSULATE(sess, obj)) { printf("%sdecapsulate", sepa); sepa = ", "; } From 003c55081c516c1d518d5718ffb261e2abd54bfe Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Nov 2025 19:46:18 +0100 Subject: [PATCH 4049/4321] pkcs11-tool: Fix import of PQC private keys Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e1a824861b..29db853262 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4750,7 +4750,7 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info pqc->type = CKP_SLH_DSA_SHAKE_256S; } if (private) { - size_t priv_len; + size_t priv_len = 0; char *seed_param = NULL; /* Some keys might have only the seed -- skip if not available */ @@ -4764,7 +4764,6 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info pqc->private.value, priv_len, NULL); if (rc != 1) { OPENSSL_free(pqc->private.value); - return -1; } } else { @@ -4795,7 +4794,7 @@ parse_pqc_pkey(EVP_PKEY *pkey, CK_KEY_TYPE type, int private, struct pqckey_info return -1; } } else { - util_fatal("PRIVATE key value available"); + util_fatal("PRIVATE key value not available"); } } } else { @@ -5365,12 +5364,12 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_privkey_attr++; if (pqc_key.private.value != NULL) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, - &pqc_key.private.value, pqc_key.private.len); + pqc_key.private.value, pqc_key.private.len); n_privkey_attr++; } if (pqc_key.seed.value != NULL) { FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SEED, - &pqc_key.seed.value, pqc_key.seed.len); + pqc_key.seed.value, pqc_key.seed.len); n_privkey_attr++; } } else { From f51c5d6d8b9ecf539d8fbb3f217d097877047c9d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Nov 2025 21:02:54 +0100 Subject: [PATCH 4050/4321] Makefile.mak: Return back the pkcs11_uri.obj as it is still needed For some reason, missing files do not cause the whole build fail and hide this problem in CI. Thanks @jurajsarinay for the report! Signed-off-by: Jakub Jelen --- src/tools/Makefile.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index 8b0711a87c..75d3727724 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -60,7 +60,7 @@ sc-hsm-tool.exe: sc-hsm-tool.obj fread_to_eof.obj $(OBJECTS) $(LIBS) pkcs11-tool.exe: pkcs11-tool.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) cl $(COPTS) /c $*.c - link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11_uri.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib shlwapi.lib .c.exe: cl $(COPTS) /c $< From baed81be1373d5425f7c9cb7e178bf174b017eb1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Nov 2025 22:37:21 +0100 Subject: [PATCH 4051/4321] pkcs11.exports: Add missing PKCS#11 3.2 functions Signed-off-by: Jakub Jelen --- src/pkcs11/pkcs11.exports | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pkcs11/pkcs11.exports b/src/pkcs11/pkcs11.exports index 1965b5bc21..cff97d1356 100644 --- a/src/pkcs11/pkcs11.exports +++ b/src/pkcs11/pkcs11.exports @@ -90,3 +90,15 @@ C_VerifyMessage C_VerifyMessageBegin C_VerifyMessageNext C_MessageVerifyFinal +C_EncapsulateKey +C_DecapsulateKey +C_VerifySignatureInit +C_VerifySignature +C_VerifySignatureUpdate +C_VerifySignatureFinal +C_GetSessionValidationFlags +C_AsyncComplete +C_AsyncGetID +C_AsyncJoin +C_WrapKeyAuthenticated +C_UnwrapKeyAuthenticated From d631f16e5fa9ec198a05343a87de407c2071c4d2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 28 Nov 2025 10:08:09 +0100 Subject: [PATCH 4052/4321] pkcs11: Include exports for windows libraries Previously, the exports were generated by `__declspec(dllexport)` in the pkcs11.h header itself, but this was accidentally removed by importing a new header file in 11a7777bbf65694d51e310c6f39ba24ad0192da0. This changes the export to work as before 25b52f6, using the pkcs11.def Thanks @jurajsarinay for the report! Signed-off-by: Jakub Jelen --- src/pkcs11/Makefile.mak | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index 1be883fe90..c4df9b3bb7 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -24,8 +24,8 @@ all: $(TARGET1) $(TARGET3) !INCLUDE $(TOPDIR)\win32\Make.rules.mak -$(TARGET1): $(OBJECTS) $(LIBS) - link /dll $(LINKFLAGS) /out:$@ /implib:$*.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib +$(TARGET1): $(OBJECTS) $(LIBS) pkcs11.def + link /dll $(LINKFLAGS) /out:$@ /def:pkcs11.def /implib:$*.lib $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib -$(TARGET3): $(OBJECTS3) $(LIBS3) - link /dll $(LINKFLAGS) /out:$@ /implib:$*.lib $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib +$(TARGET3): $(OBJECTS3) $(LIBS3) pkcs11.def + link /dll $(LINKFLAGS) /out:$@ /def:pkcs11.def /implib:$*.lib $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib From 2b6aafe7e3363971756c2e8a65277cf2524ed2ec Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 29 Nov 2025 00:16:48 +0100 Subject: [PATCH 4053/4321] pkcs11-tool: Fix missing argument from printf format Fixes the following automatic code scanning issue: https://github.com/OpenSC/OpenSC/security/code-scanning/38 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 29db853262..56869c9269 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7473,7 +7473,7 @@ static int read_object(CK_SESSION_HANDLE session) #ifdef EVP_PKEY_ED448 NID_ED448, #endif -#ifdef EVP_PKEY_X44 +#ifdef EVP_PKEY_X448 NID_X448, #endif nid); From 72c29435fdf688d1e6db99434e9f01d714714280 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 29 Nov 2025 00:20:16 +0100 Subject: [PATCH 4054/4321] pkcs11-tool: Remove redundant NULL check Reported by automatic code scanning: https://github.com/OpenSC/OpenSC/security/code-scanning/28 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 56869c9269..f9a5159f1f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2352,7 +2352,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return -1; } - if (!new_pin || !*new_pin || strlen(new_pin) > 20) { + if (strlen(new_pin) > 20) { if (new_pin != opt_new_pin) free(new_pin); return 1; From 9a48e66d9e816f81a14d82261420e64d7b31295d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 29 Nov 2025 00:28:33 +0100 Subject: [PATCH 4055/4321] Remove apt-cache from the CI it looks like it breaks the installation in some configurations ... update the remaining uses Signed-off-by: Jakub Jelen --- .github/setup-linux.sh | 12 ++++---- .github/workflows/external-pkcs11.yaml | 4 +-- .github/workflows/linux.yml | 38 ++++---------------------- 3 files changed, 13 insertions(+), 41 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 1b1a6b2120..6ce37f1792 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -66,14 +66,12 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then $SUDO dpkg --add-architecture i386 fi -if [ -z "$GITHUB_ACTIONS" -o "$FORCE_INSTALL" = "1" ]; then - # make sure we do not get prompts - export DEBIAN_FRONTEND=noninteractive - export DEBCONF_NONINTERACTIVE_SEEN=true - $SUDO apt-get update -qq +# make sure we do not get prompts +export DEBIAN_FRONTEND=noninteractive +export DEBCONF_NONINTERACTIVE_SEEN=true +$SUDO apt-get update -qq - $SUDO apt-get install -y build-essential $DEPS -fi +$SUDO apt-get install -y build-essential $DEPS # install libressl if needed if [ "$1" == "libressl" -o "$2" == "libressl" ]; then diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 4442b9da6a..0b030a73a4 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -56,7 +56,7 @@ jobs: BUILD_PATH: ./ steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-20-base @@ -77,7 +77,7 @@ jobs: BUILD_PATH: ./ steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-20-base diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ca40aba0c6..6a0ace81ed 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -45,12 +45,6 @@ jobs: runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - uses: actions/checkout@v5 - # Create with piv-sm build with java deps - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ matrix.build == 'piv-sm' && env.JAVA_DEPS || '' }} - version: apt-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build == 'piv-sm' && 'java' || 'base' }} - execute_install_scripts: true - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs @@ -79,7 +73,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -91,7 +85,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -103,7 +97,7 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base @@ -128,11 +122,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-latest-base - execute_install_scripts: true - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts @@ -154,11 +143,6 @@ jobs: runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-${{ matrix.dist }}-${{ matrix.arch }}-java - execute_install_scripts: true - run: git clone $JCARDSIM - uses: actions/setup-java@v4 with: @@ -186,11 +170,6 @@ jobs: runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} ${{ env.JAVA_DEPS }} - version: apt-${{ matrix.dist }}-${{ matrix.arch }}-java - execute_install_scripts: true - *use_cache - run: git clone $JCARDSIM - uses: actions/setup-java@v4 @@ -206,7 +185,7 @@ jobs: runs-on: ubuntu-24.04 needs: [build] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base @@ -231,11 +210,6 @@ jobs: runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-${{ matrix.dist }}-${{ matrix.arch }}-base - execute_install_scripts: true - *use_cache - run: .github/setup-linux.sh ${{ matrix.target }} debug - run: .github/test-${{ matrix.target }}.sh @@ -248,7 +222,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -293,7 +267,7 @@ jobs: target: [cac, oseid] needs: [build-libressl] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base From f4d3d750fe6f8feecf1fb79276ec6a5e8c68bb42 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 29 Nov 2025 11:35:18 +0100 Subject: [PATCH 4056/4321] ci: Find the right path to the libpcsclite.so.1 Signed-off-by: Jakub Jelen --- .github/setup-valgrind.sh | 2 +- configure.ac | 7 +++++++ src/tests/unittests/Makefile.am | 2 +- tests/Makefile.am | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/setup-valgrind.sh b/.github/setup-valgrind.sh index 19f765c6df..12617d4463 100644 --- a/.github/setup-valgrind.sh +++ b/.github/setup-valgrind.sh @@ -12,5 +12,5 @@ if [ "$1" == "valgrind" -o "$2" == "valgrind" ]; then # https://github.com/opendnssec/SoftHSMv2/commit/f94aaffc879ade97a51b8e1308af42f86be1885f export VALGRIND="valgrind -q --error-exitcode=1 --leak-check=full --keep-debuginfo=yes --trace-children=yes --gen-suppressions=all --suppressions=$PWD/tests/opensc.supp" # this should help us getting better traces as some of pcsclite and avoid false positives - export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libpcsclite.so.1" + export LD_PRELOAD=$(ldconfig -p | grep libpcsclite.so.1 | tr ' ' '\n' | grep /) fi diff --git a/configure.ac b/configure.ac index f6e5cfe48c..28f765df95 100644 --- a/configure.ac +++ b/configure.ac @@ -142,6 +142,12 @@ AM_CONDITIONAL([HAVE_SHORTEN_WARNING_OPTION], [test "${have_shorten_warning_opti AX_VALGRIND_CHECK() +if test ${VALGRIND_ENABLED} = "yes"; then + # to avoid false positive leaks from pcsclite + PCSCLITE_PATH=$(ldconfig -p | grep libpcsclite.so.1 | tr ' ' '\n' | grep / | head -n 1) + AC_SUBST([PCSCLITE_PATH]) +fi + AC_ARG_ENABLE( [fuzzing], [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CC, CFLAGS and FUZZING_LIBS should be set accordingly, e.g. to something like CC="clang" CFLAGS="-fsanitize=fuzzer-no-link" FUZZING_LIBS="-fsanitize=fuzzer"])], @@ -1282,6 +1288,7 @@ CRYPTOTOKENKIT_CFLAGS: ${CRYPTOTOKENKIT_CFLAGS} GIO2_CFLAGS: ${GIO2_CFLAGS} GIO2_LIBS: ${GIO2_LIBS} FUZZING_LIBS: ${FUZZING_LIBS} +PCSCLITE_PATH: ${PCSCLITE_PATH} EOF diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index aa69a567bf..1ca2dcbc10 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -11,7 +11,7 @@ if VALGRIND_ENABLED #VALGRIND_SUPPRESSIONS_FILES = $(top_srcdir)/tests/opensc.supp VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all # to avoid false positive leaks from pcsclite -TESTS_ENVIRONMENT = LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1' +TESTS_ENVIRONMENT = LD_PRELOAD='$(PCSCLITE_PATH)' endif noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 20f5be73c0..ce2f2c34c1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -20,7 +20,7 @@ LOG_COMPILER = $(LOG_VALGRIND) # the LD_PRELOAD is to avoid false positive leaks from pcsclite AM_TESTS_ENVIRONMENT += \ VALGRIND='$(LOG_VALGRIND)'; \ - LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1'; + LD_PRELOAD='$(PCSCLITE_PATH)' endif dist_noinst_SCRIPTS = common.sh \ From 8b59e8b317e74d74d6d9635b8e749591abd97434 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 1 Dec 2025 20:33:09 +0100 Subject: [PATCH 4057/4321] tests: Adjust reference files to new p11test format --- src/tests/p11test/isoapplet_ref_v0.json | 8 ++++++++ src/tests/p11test/isoapplet_ref_v1.json | 8 ++++++++ src/tests/p11test/openpgp_s0_ref.json | 6 ++++++ src/tests/p11test/openpgp_s1_ref.json | 4 ++++ src/tests/p11test/piv_ref.json | 10 ++++++++++ 5 files changed, 36 insertions(+) diff --git a/src/tests/p11test/isoapplet_ref_v0.json b/src/tests/p11test/isoapplet_ref_v0.json index 085b4a515b..784cafbe0a 100644 --- a/src/tests/p11test/isoapplet_ref_v0.json +++ b/src/tests/p11test/isoapplet_ref_v0.json @@ -269,6 +269,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -287,6 +289,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -303,6 +307,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -319,6 +325,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" diff --git a/src/tests/p11test/isoapplet_ref_v1.json b/src/tests/p11test/isoapplet_ref_v1.json index c0b40f3ee2..c397ced33c 100644 --- a/src/tests/p11test/isoapplet_ref_v1.json +++ b/src/tests/p11test/isoapplet_ref_v1.json @@ -359,6 +359,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -377,6 +379,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -393,6 +397,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -409,6 +415,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" diff --git a/src/tests/p11test/openpgp_s0_ref.json b/src/tests/p11test/openpgp_s0_ref.json index 04898efd65..3699756188 100644 --- a/src/tests/p11test/openpgp_s0_ref.json +++ b/src/tests/p11test/openpgp_s0_ref.json @@ -251,6 +251,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -269,6 +271,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -285,6 +289,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" diff --git a/src/tests/p11test/openpgp_s1_ref.json b/src/tests/p11test/openpgp_s1_ref.json index 37a77bb373..204a1ce4a5 100644 --- a/src/tests/p11test/openpgp_s1_ref.json +++ b/src/tests/p11test/openpgp_s1_ref.json @@ -245,6 +245,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -263,6 +265,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" diff --git a/src/tests/p11test/piv_ref.json b/src/tests/p11test/piv_ref.json index 026959ef36..de5a615baf 100644 --- a/src/tests/p11test/piv_ref.json +++ b/src/tests/p11test/piv_ref.json @@ -460,6 +460,8 @@ "DECRYPT", "WRAP", "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", "DERIVE PUBLIC", "DERIVE PRIVATE", "ALWAYS AUTH" @@ -478,6 +480,8 @@ "YES", "", "", + "", + "", "" ], [ @@ -494,6 +498,8 @@ "", "", "", + "", + "", "YES" ], [ @@ -508,6 +514,8 @@ "", "", "", + "", + "", "YES", "YES", "" @@ -526,6 +534,8 @@ "", "", "", + "", + "", "" ]], "result": "pass" From df4d6e5a1bf5def2cc51aa0d087532813a233f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C5=A0arinay?= Date: Mon, 1 Dec 2025 23:35:51 +0100 Subject: [PATCH 4058/4321] Silence a Microsoft linker warning The library name within pkcs11.def matched neither of the two DLLs where the definition file was used, this resulted in warning LNK4070. The linker gets the output filename as a parameter. Drop it from the definition files, where it is optional. --- win32/Make.rules.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index 820560d734..dd2871cdb4 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -165,7 +165,7 @@ COPTS = /O1 /$(BUILD_TYPE) $(COPTS) rc $(DEFS) /l 0x0409 /I$(TOPDIR)\win32 $< .exports.def: - echo LIBRARY $* > $*.def + echo LIBRARY > $*.def echo EXPORTS >> $*.def type $*.exports >> $*.def From d64f316c10fc8d5d896cdf94160d5d365cf37f37 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 1 Dec 2025 23:02:25 +0100 Subject: [PATCH 4059/4321] ci: Try to use debuginfod instead of manual download of ddebs ... which is fragile given that ubuntu does not have predictable naming pattern for the debuginfo packages and the repositories are most of the time being updated which results in random failures in CI installing these packages. --- .github/setup-linux.sh | 29 ++++------------------------- .github/setup-valgrind.sh | 3 +++ 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 6ce37f1792..b1d2ee0f09 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -32,6 +32,10 @@ else DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2" fi +if [ "$1" == "debug" -o "$2" == "debug" ]; then + DEPS="debuginfod $DEPS" +fi + if [ "$1" == "clang-tidy" ]; then DEPS="$DEPS clang-tidy" elif [ "$1" == "cac" ]; then @@ -81,31 +85,6 @@ if [ "$1" == "libressl" -o "$2" == "libressl" ]; then cat /tmp/libressl.log exit $RET fi -elif [ "$1" == "debug" -o "$2" == "debug" ]; then - # install debug symbols - $SUDO apt-get install -y lsb-release ubuntu-dbgsym-keyring - echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse -deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-updates main restricted universe multiverse -deb http://ddebs.ubuntu.com $(lsb_release -cs 2> /dev/null)-proposed main restricted universe multiverse" | \ - $SUDO tee -a /etc/apt/sources.list.d/ddebs.list - $SUDO apt-get update -qq - - # Github Actions images are terribly large containing a lot of nonsense that takes ages just to upgrade - if [ -n "$GITHUB_ACTIONS" ]; then - $SUDO apt-get autopurge snapd - $SUDO apt-mark hold snapd - $SUDO apt-get remove -y -qq mysql* php* firefox ruby* dotnet* - fi - - $SUDO apt-get upgrade -qq - ARCH_TRIPLET=$(dpkg-architecture -qDEB_HOST_MULTIARCH) - DEP="libssl1.1-dbgsym" - if [ -f "/usr/lib/${ARCH_TRIPLET}/libssl.so.3" ]; then -# libcrypto is in same package as libssl - DEPX=`dpkg -S "/usr/lib/${ARCH_TRIPLET}/libssl.so.3"` - DEP="${DEPX%%:*}-dbgsym" - fi - $SUDO apt-get install -y openssl-dbgsym "$DEP" softhsm2-dbgsym libsofthsm2-dbgsym libc6-dbg fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then diff --git a/.github/setup-valgrind.sh b/.github/setup-valgrind.sh index 12617d4463..5b195a66f6 100644 --- a/.github/setup-valgrind.sh +++ b/.github/setup-valgrind.sh @@ -13,4 +13,7 @@ if [ "$1" == "valgrind" -o "$2" == "valgrind" ]; then export VALGRIND="valgrind -q --error-exitcode=1 --leak-check=full --keep-debuginfo=yes --trace-children=yes --gen-suppressions=all --suppressions=$PWD/tests/opensc.supp" # this should help us getting better traces as some of pcsclite and avoid false positives export LD_PRELOAD=$(ldconfig -p | grep libpcsclite.so.1 | tr ' ' '\n' | grep /) + + # The valgrind should be able to find the debuginfo on the fly + export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com" fi From 7bc19e68654342a3b743e4984864676ce75d93da Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 2 Dec 2025 11:18:36 +0200 Subject: [PATCH 4060/4321] Merge java test targets Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6a0ace81ed..a49c06cabb 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -131,31 +131,8 @@ jobs: path: win32/Output/OpenSC*.exe - test-isoapplet: - name: test-isoapplet-${{ matrix.target }} - strategy: - fail-fast: false - matrix: - dist: ['24.04'] - arch: [amd64] - build: [valgrind] - target: [v0, v1] - runs-on: ubuntu-${{ matrix.dist }} - needs: [build] - steps: - - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 - with: - distribution: 'semeru' - java-version: '8' - cache: 'maven' - - *use_cache - - run: .github/setup-linux.sh isoapplet debug - - run: .github/test-isoapplet.sh ${{ matrix.target }} - - run: .github/test-isoapplet.sh ${{ matrix.target }} valgrind - test-java: - name: test-${{ matrix.target }}-${{ matrix.dist }}-${{ matrix.build }} + name: test-${{ matrix.target }}${{ matrix.ver }}-${{ matrix.dist }}-${{ matrix.build }} strategy: fail-fast: false matrix: @@ -163,9 +140,12 @@ jobs: arch: [amd64] build: [valgrind] target: [piv, gidsapplet, openpgp] + ver: [''] include: [ { dist: '22.04', arch: amd64, build: 'piv-sm', target: 'piv' }, - { dist: '24.04', arch: amd64, build: 'piv-sm', target: 'piv' } + { dist: '24.04', arch: amd64, build: 'piv-sm', target: 'piv' }, + { dist: '24.04', arch: amd64, build: 'valgrind', target: 'isoapplet', ver: 'v0' }, + { dist: '24.04', arch: amd64, build: 'valgrind', target: 'isoapplet', ver: 'v1' } ] runs-on: ubuntu-${{ matrix.dist }} needs: [build] @@ -178,8 +158,8 @@ jobs: java-version: '8' cache: 'maven' - run: .github/setup-linux.sh ${{ matrix.target }} debug - - run: .github/test-${{ matrix.target }}.sh - - run: .github/test-${{ matrix.target }}.sh valgrind + - run: .github/test-${{ matrix.target }}.sh ${{ matrix.ver }} + - run: .github/test-${{ matrix.target }}.sh ${{ matrix.ver }} valgrind build-clang-tidy: runs-on: ubuntu-24.04 From 5ff117b2ee4faee854a13ea9fca12bf1fd241b0a Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 2 Dec 2025 11:19:17 +0200 Subject: [PATCH 4061/4321] Move clang-tidy build task Signed-off-by: Raul Metsma --- .github/workflows/linux.yml | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a49c06cabb..209c60545d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -48,7 +48,7 @@ jobs: - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() with: name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-test-logs @@ -63,7 +63,7 @@ jobs: key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-${{ github.sha }} - name: Upload build artifacts if: matrix.build == 'dist' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: opensc-build-${{ matrix.dist }}-${{ matrix.arch }} path: @@ -72,7 +72,7 @@ jobs: build-no-shared: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -84,7 +84,7 @@ jobs: build-no-openssl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -96,7 +96,7 @@ jobs: build-ix86: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -108,11 +108,11 @@ jobs: build-mingw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: opensc-build-mingw path: @@ -121,16 +121,33 @@ jobs: build-mingw32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: opensc-build-mingw32 path: win32/Output/OpenSC*.exe + build-clang-tidy: + runs-on: ubuntu-24.04 + needs: [build] + steps: + - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + with: + packages: ${{ env.BASE_DEPS }} + version: apt-24.04-amd64-base + execute_install_scripts: true + - uses: actions/cache@v4 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-24.04-amd64-valgrind-${{ github.sha }} + - run: .github/setup-linux.sh clang-tidy + - run: .github/build.sh clang-tidy + test-java: name: test-${{ matrix.target }}${{ matrix.ver }}-${{ matrix.dist }}-${{ matrix.build }} strategy: @@ -161,23 +178,6 @@ jobs: - run: .github/test-${{ matrix.target }}.sh ${{ matrix.ver }} - run: .github/test-${{ matrix.target }}.sh ${{ matrix.ver }} valgrind - build-clang-tidy: - runs-on: ubuntu-24.04 - needs: [build] - steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 - with: - packages: ${{ env.BASE_DEPS }} - version: apt-24.04-amd64-base - execute_install_scripts: true - - uses: actions/cache@v4 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-24.04-amd64-valgrind-${{ github.sha }} - - run: .github/setup-linux.sh clang-tidy - - run: .github/build.sh clang-tidy - test: name: test-${{ matrix.target }}-${{ matrix.dist }} strategy: @@ -201,7 +201,7 @@ jobs: build-libressl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -216,7 +216,7 @@ jobs: key: libressl-${{ env.LIBRESSL_VERSION }} - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 if: failure() with: name: libressl-logs From 767c340a489f17753bf137a12a9c579255c992ea Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Dec 2025 16:21:13 +0100 Subject: [PATCH 4062/4321] pkcs11: Use implicit type conversion to avoid build failure Without this windows build fails silently like this: ``` framework-pkcs15.c Error: framework-pkcs15.c(4697): error C2220: the following warning is treated as an error Warning: framework-pkcs15.c(4697): warning C4319: '~': zero extending 'unsigned int' to 'size_t' of greater size ``` Signed-off-by: Jakub Jelen --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index a01a7f60e3..701c370548 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4694,7 +4694,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, /* only padding error must be handled in constant-time way, * other error can be returned straight away */ - if ((~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv))) + if ((~(size_t)constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv))) return sc_to_cryptoki_error(rv, "C_Decrypt"); /* check rv for padding error */ From ab568f0a420931d5372bc8657f4024ca6d0e3285 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Jun 2025 17:08:20 +0200 Subject: [PATCH 4063/4321] iasecc: Properly set resplen when emulating fcp (1) Previously, this could lead to use uninitialized memory as the caller would handle the returned apdu buffer as longer than it actually is. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/libopensc/card-iasecc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 1806a9c72b..4524275c51 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -862,7 +862,8 @@ iasecc_emulate_fcp(struct sc_context *ctx, struct sc_apdu *apdu) memcpy(dummy_df_fcp + 16, apdu->data, apdu->datalen); dummy_df_fcp[15] = apdu->datalen; dummy_df_fcp[1] = apdu->datalen + 14; - memcpy(apdu->resp, dummy_df_fcp, apdu->datalen + 16); + apdu->resplen = apdu->datalen + 16; + memcpy(apdu->resp, dummy_df_fcp, apdu->resplen); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } From f29e937aa77ad000cd65cc1806972203bd3b0f43 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Jun 2025 17:22:42 +0200 Subject: [PATCH 4064/4321] entersafe: Avoid using uninitialized memory (2) Initialize the variable to prevent accessing uninitialized members when they are encoded into the APDU. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-entersafe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 57be7d2668..e39d28f68a 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -77,7 +77,7 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) {/* MF */ sc_file_t *mf_file; - sc_entersafe_create_data mf_data; + sc_entersafe_create_data mf_data = {0}; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); From 7e3dcae1d14e898dfed00ce8aa1d1bfeaee7c936 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Jun 2025 19:51:17 +0200 Subject: [PATCH 4065/4321] starcert: Avoid using uninitialized values (3) Previously, the read could return small response, which would result in accessin uninitialized parts of the buffer. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-atrust-acos.c | 2 +- src/libopensc/pkcs15-starcert.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index e6b53989e0..a4d4217a1c 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -78,7 +78,7 @@ static int get_cert_len(sc_card_t *card, sc_path_t *path) if (r < 0) return 0; r = sc_read_binary(card, 0, buf, sizeof(buf), 0); - if (r < 0) + if (r < 4) return 0; if (buf[0] != 0x30 || buf[1] != 0x82) return 0; diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index b2beb75530..8aafb1dfab 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -88,7 +88,7 @@ static int get_cert_len(sc_card_t *card, sc_path_t *path) if (r < 0) return 0; r = sc_read_binary(card, 0, buf, sizeof(buf), 0); - if (r < 0) + if (r < 4) return 0; if (buf[0] != 0x30 || buf[1] != 0x82) return 0; From a998551ca19f2bd0e664c59d415675c062e3920b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 4 Jun 2025 21:46:24 +0200 Subject: [PATCH 4066/4321] oberthur: Avoid using uninitialized value (4) The mismatch between the requested pubkey length and returned pubkey could result in using uninitialized memory when the card would return smaller modulus. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-oberthur.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index a97e460a57..7395055551 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -695,6 +695,7 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, } memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len); + pubkey->u.rsa.modulus.len = args.pubkey_len; key_info->key_reference = prkf->path.value[prkf->path.len - 1] & 0xFF; key_info->path = prkf->path; From c1d3ebb130f909eff2aef1924f28f3d4c04786a6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 12:00:38 +0200 Subject: [PATCH 4067/4321] profile: Avoid using uninitialized memory (5) Previously, the get_inner_word() could fail, leaving the second argument uninitialized when the macro name was too long. By checking the return value, we should catch this error and avoid using uninitialized memory. Rest is fixing typos and rewriting for more clarity. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/pkcs15init/profile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index f4c744646c..e6e6b2c6c3 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2089,9 +2089,11 @@ build_argv(struct state *cur, const char *cmdname, /* When str contains macro inside, macro reference loop needs to be checked */ const char *macro_name = NULL; if ((macro_name = strchr(str, '$'))) { - /* Macro does not to start at the first position */ + /* Macro does not have to start at the first position */ char word[WORD_SIZE]; - get_inner_word(macro_name + 1, word); + if (get_inner_word(macro_name + 1, word) != 0) { + return SC_ERROR_SYNTAX_ERROR; + } if ((macro = find_macro(cur->profile, word)) && check_macro_reference_loop(macro->name, macro, cur->profile, 0)) { return SC_ERROR_SYNTAX_ERROR; From 7aafe6f8c4a962d8ee9208a62272b6b38d6db9f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 5 Jun 2025 11:00:21 +0200 Subject: [PATCH 4068/4321] iasecc: Avoid using uninitialized memory (6) The parsed length from data did not take into the account the buffer bounds, which could result in accessing uninitialized memory. This change verifies the parsed size fits into the allocated buffer and following checks make sure we do not go behind the initialized buffer bounds. Thanks Matteo Marini for the report! Signed-off-by: Jakub Jelen --- src/libopensc/iasecc-sdo.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 7c77a0c831..c41217090e 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -776,14 +776,21 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str size_size = iasecc_parse_size(data + 1, data_len - 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); + if (data_len < (size_t)(size_size + 1)) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + } data += size_size + 1; + data_len -= (size_size + 1); + if (size > data_len) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + } data_len = size; sc_log(ctx, "IASECC_SDO_TEMPLATE: size %"SC_FORMAT_LEN_SIZE_T"u, size_size %d", size, size_size); } - if (*data != IASECC_SDO_TAG_HEADER) + if (data_len < 4 || *data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); if (sdo->sdo_class != (*(data + 1) & 0x7F)) From 267111f2e3b766e5ad985105cd1a3416d569ff89 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 14:33:39 +0200 Subject: [PATCH 4069/4321] gemsafeV1: Avoid use of uninitialized memory (fuzz_pkcs15_crypt/1) Signed-off-by: Jakub Jelen --- src/libopensc/card-gemsafeV1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index 04ad57fed1..e9705db02a 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -347,7 +347,7 @@ static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file, sc_log(ctx, "file type: %s\n", type); tag = sc_asn1_find_tag(ctx, p, len, 0x8C, &tlen); - if (tag) { + if (tag && tlen > 1) { r = gemsafe_setacl(card, file, tag, strcmp(type, "DF") ? 0 : 1); if (r < 0) { sc_log(ctx, "unable to set ACL\n"); From 263d29e2f8baf33f329849c82ba9c08ec45f1ad7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 14:51:55 +0200 Subject: [PATCH 4070/4321] tcos: Fix use of uninitialized value (fuzz_pkcs15_crypt/2) Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-tcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 491d9c812c..24e8cee4a1 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -78,7 +78,7 @@ static int insert_cert( } /* some certificates are prefixed by an OID */ - if (cert_len >= 5 && (size_t)(7 + cert[5]) <= cert_len && + if (cert_len > 9 && (size_t)(7 + cert[5]) <= cert_len && cert[4] == 0x06 && cert[5] < 10 && cert[6 + cert[5]] == 0x30 && cert[7 + cert[5]] == 0x82) { if ((size_t)(9 + cert[5]) > cert_len) { From 7000dee0eb7d35246b5e180b39bb4e03b11f1c47 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 14:57:43 +0200 Subject: [PATCH 4071/4321] pkcs15-pubkey: Avoid accessing behind buffer bounds (fuzz_pkcs15_crypt/3) Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 2ff130c22d..496ac5c5d1 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1339,7 +1339,7 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke } memcpy(tmp_buf, buf, buflen); - if ((*tmp_buf & SC_ASN1_TAG_CONTEXT)) + if (buflen > 0 && (*tmp_buf & SC_ASN1_TAG_CONTEXT)) *tmp_buf = SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE; memset(&pk_alg, 0, sizeof(pk_alg)); From 29122ae779fa8ecb201b0c0b3bdad058b9540262 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 16:37:05 +0200 Subject: [PATCH 4072/4321] openpgp: Avoid using uninitialized data in the OID (fuzz_pkcs15_crypt/5) Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index d465724c38..f6fa3248e9 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -315,7 +315,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) /* only add valid keys, i.e. those with a legal algorithm identifier & finger print */ if (j >= 0 && cxdata[0] != 0) { - struct sc_object_id oid; + struct sc_object_id oid = {0}; struct sc_algorithm_info * algorithm_info; /* no need to free */ algorithm_info = NULL; From 5b0cda30e8226c41c69735f95234d98eda1be550 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 16:46:40 +0200 Subject: [PATCH 4073/4321] cac: Avoid using of uninitialized memory (fuzz_pkcs15_crypt/6) Signed-off-by: Jakub Jelen --- src/libopensc/card-cac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 71ab7e482f..63b7b5d861 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1181,7 +1181,7 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc * Do this only if we select applets for reading * (not during driver initialization) */ - cac_properties_t prop; + cac_properties_t prop = {0}; size_t i = -1; r = cac_get_properties(card, &prop); From 61985ce021b386b11a29eb4d27c6a7ae00e8e2a6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 18:48:12 +0200 Subject: [PATCH 4074/4321] cac: Avoid using uninitialized memory (fuzz_pkcs15_crypt/9) Signed-off-by: Jakub Jelen --- src/libopensc/card-cac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 63b7b5d861..d1447a8259 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -229,7 +229,7 @@ static const cac_object_t *cac_find_obj_by_id(unsigned short object_id) */ static int cac_is_cert(cac_private_data_t * priv, const sc_path_t *in_path) { - cac_object_t test_obj; + cac_object_t test_obj = {0}; test_obj.path = *in_path; test_obj.path.index = 0; test_obj.path.count = 0; @@ -1275,7 +1275,7 @@ static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_ static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, const u8 *aid, int aid_len) { cac_object_t new_object; - cac_properties_t prop; + cac_properties_t prop = {0}; size_t i; int r; From bd8687b40f6948278ec115aa7a19ee7274760ce0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 23 Sep 2025 18:52:20 +0200 Subject: [PATCH 4075/4321] esteid218: Avoid buffer overrun (fuzz_pkcs15_decode/1) Signed-off-by: Jakub Jelen --- src/libopensc/card-esteid2018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index ea3b8bbf87..cf83180c8c 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -123,7 +123,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat file = sc_file_new(); if (file == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - r = iso_ops->process_fci(card, file, resp, resplen); + r = iso_ops->process_fci(card, file, resp, apdu.resplen); if (r != SC_SUCCESS) { sc_file_free(file); } else { From a89dff3271da2eccd834553a4c0dfb7c543657c5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 24 Sep 2025 10:18:09 +0200 Subject: [PATCH 4076/4321] iasecc: Fix the length check to avoid usage of uninitialized memory (fuzz_pkcs15_encode/6) Signed-off-by: Jakub Jelen --- src/libopensc/iasecc-sdo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index c41217090e..bb593a3ef1 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -317,6 +317,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru int rv; LOG_FUNC_CALLED(ctx); + sc_log(ctx, "data_len %"SC_FORMAT_LEN_SIZE_T"u", data_len); if (data_len < 1) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); @@ -325,7 +326,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru size_size = iasecc_parse_size(data + 1, data_len - 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); - if (data_len - 1 < size) + if (data_len < size + size_size + 1) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); data += size_size + 1; From 40fbddc46e026618b6a3d0a03e62adc1fb5ca956 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 24 Sep 2025 10:24:33 +0200 Subject: [PATCH 4077/4321] coolkey: Avoid zero-lenght allocations and access of uninitialized memory (fuzz_pkcs15_reader/4) --- src/libopensc/pkcs15-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 44eb84627a..bd92c5508a 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -209,7 +209,7 @@ coolkey_get_attribute_bytes_alloc(sc_card_t *card, sc_cardctl_coolkey_object_t * int r; r = coolkey_get_attribute(card, obj, type, &val, &val_len, NULL); - if (r < 0) { + if (r < 0 || val_len < 1) { return r; } *data = malloc(val_len); From dc4a1f2617867eb3b2c170ec51dd2bbae0212480 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 24 Sep 2025 10:27:42 +0200 Subject: [PATCH 4078/4321] authentic: Avoid buffer overrun (fuzz_pkcs15_reader/6) --- src/libopensc/card-authentic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 297f40e71f..f12670c2d6 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -297,9 +297,9 @@ authentic_parse_credential_data(struct sc_context *ctx, struct sc_pin_cmd_data * rv = authentic_get_tagged_data(ctx, blob, blob_len, AUTHENTIC_TAG_DOCP_MECH, &data, &data_len); LOG_TEST_RET(ctx, rv, "cannot get PIN type"); - if (*data == 0) + if (data_len > 0 && *data == 0) pin_cmd->pin_type = SC_AC_CHV; - else if (*data >= 2 && *data <= 7) + else if (data_len > 0 && *data >= 2 && *data <= 7) pin_cmd->pin_type = SC_AC_AUT; else LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported Credential type"); From 6bee48e00e5f869fefee124dafd620c7ff5ba558 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 24 Sep 2025 13:44:08 +0200 Subject: [PATCH 4079/4321] cac: Improve logging Signed-off-by: Jakub Jelen --- src/libopensc/card-cac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index d1447a8259..3f256d6a88 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -398,6 +398,8 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o size_t len = 0; int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + params[0] = file_type; params[1] = 2; @@ -435,12 +437,12 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o } *out_len = size; *out_buf = out; - return SC_SUCCESS; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); fail: if (out) free(out); *out_len = 0; - return r; + LOG_FUNC_RETURN(card->ctx, r); } From 35b2f54212db0d6adcc337e456ddc728eeabd044 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 24 Sep 2025 13:44:48 +0200 Subject: [PATCH 4080/4321] cac: Fix possible use of uninitialized memory (fuzz_pkcs15_crypt/4) Signed-off-by: Jakub Jelen --- src/libopensc/card-cac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 3f256d6a88..6a0fabf968 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -511,7 +511,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } priv->cache_buf_len = tlv_len; - for (tl_ptr = tl, val_ptr=val, tlv_ptr = priv->cache_buf; + for (tl_ptr = tl, val_ptr = val, tlv_ptr = priv->cache_buf; tl_len >= 2 && tlv_len > 0; val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) { /* get the tag and the length */ @@ -536,6 +536,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } memcpy(tlv_ptr, val_ptr, len); } + /* fixup the cache_buf_le to reflect for the bad data ignored above */ + priv->cache_buf_len = (tlv_ptr - priv->cache_buf); break; case CAC_OBJECT_TYPE_CERT: From 24869e777503bdd948548351f126f01cee1f3d8d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 9 Dec 2025 16:14:08 +0100 Subject: [PATCH 4081/4321] pkcs15init: Avoid buffer overrun The maximum path length is 16 bytes and if we want to extend the path, we need to make sure its not too long. Thanks oss-fuzz. https://issues.oss-fuzz.com/issues/467161860 Signed-off-by: Jakub Jelen --- src/pkcs15init/pkcs15-cflex.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 8ede1ebd4e..a3c1434658 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -539,6 +539,9 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Build the CHV path */ path = *df_path; + if (path.len > SC_MAX_PATH_SIZE - 2) { + return SC_ERROR_INVALID_ARGUMENTS; + } path.value[path.len++] = ref - 1; path.value[path.len++] = 0; From 067ce7b5b238e928e746fe479f7fe3f3f08c146a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 27 Nov 2025 21:32:05 +0100 Subject: [PATCH 4082/4321] ctx: Introduce possibility to use custom openssl config ... to better support FIPS mode Fixes: #3500 Signed-off-by: Jakub Jelen --- doc/files/files.html | 15 +++++++++ doc/files/opensc.conf.5.xml.in | 23 ++++++++++++++ src/libopensc/ctx.c | 56 +++++++++++++++++++++++++--------- src/libopensc/opensc.h | 1 + 4 files changed, 81 insertions(+), 14 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index 32256afe2f..2f3b9474db 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -274,6 +274,21 @@ is disabled both for signatures and decryption (PKCS#1 v1.5 type 1 and 2).

    (Default: decipher). +

    + openssl_config = path; +

    + Specify a OpenSSL configuration file to be loaded into the + OpenSC's library context. This should not be needed for general + operation, but is needed if you need to confirure some + specifics of OpenSSL, without the need to rebuild OpenSC (for + example configure and load a FIPS provider). + For more information about configuring OpenSSL, see + config(5). + + and + fips_config(5). + . + (Default: empty).

    secure_messaging name { block_contents diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index a6d7d8646b..32470dd70d 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -357,6 +357,29 @@ app application { (Default: decipher). + + + + + + Specify a OpenSSL configuration file to be loaded into the + OpenSC's library context. This should not be needed for general + operation, but is needed if you need to confirure some + specifics of OpenSSL, without the need to rebuild OpenSC (for + example configure and load a FIPS provider). + For more information about configuring OpenSSL, see + + config + 5. + + and + + fips_config + 5. + . + (Default: empty). + +

    Specify a OpenSSL configuration file to be loaded into the OpenSC's library context. This should not be needed for general - operation, but is needed if you need to confirure some + operation, but is needed if you need to configure some specifics of OpenSSL, without the need to rebuild OpenSC (for example configure and load a FIPS provider). For more information about configuring OpenSSL, see @@ -1263,7 +1263,7 @@

  • DF(PKCS#15) is directory containing the PKCS#15 files and directories

  • - EF(ODF) (Object Directory File) is elementary file containing pointers + EF(ODF) (Object Directory File) is elementary file containing pointers to other elementary files (PrKDFs, PuKDFs, SKDFs, CDFs, DODFs, AODFs)

  • PrKDF (Private Key Directory File) is elementary file containing diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 32470dd70d..b029f670d0 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -364,7 +364,7 @@ app application { Specify a OpenSSL configuration file to be loaded into the OpenSC's library context. This should not be needed for general - operation, but is needed if you need to confirure some + operation, but is needed if you need to configure some specifics of OpenSSL, without the need to rebuild OpenSC (for example configure and load a FIPS provider). For more information about configuring OpenSSL, see diff --git a/doc/files/pkcs15-profile.5.xml.in b/doc/files/pkcs15-profile.5.xml.in index 8a41ce3429..0681c92053 100644 --- a/doc/files/pkcs15-profile.5.xml.in +++ b/doc/files/pkcs15-profile.5.xml.in @@ -44,7 +44,7 @@ DF(PKCS#15) is directory containing the PKCS#15 files and directories - EF(ODF) (Object Directory File) is elementary file containing pointers + EF(ODF) (Object Directory File) is elementary file containing pointers to other elementary files (PrKDFs, PuKDFs, SKDFs, CDFs, DODFs, AODFs) From 3082984438fe2e3366fd2bd0b4e361e599f02108 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 14 Jan 2026 18:15:21 +0100 Subject: [PATCH 4094/4321] Load FIPS provider by default when system is in FIPS mode --- src/libopensc/ctx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 30bd02c724..2f8c8ef64e 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -866,7 +866,11 @@ static int sc_openssl3_init(sc_context_t *ctx) } else { /* We do not have configuration file specified: load the default * and legacy providers */ - ctx->ossl3ctx->defprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, "default"); + const char *defprov_name = "default"; + if (FIPS_mode()) { + defprov_name = "fips"; + } + ctx->ossl3ctx->defprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, defprov_name); if (ctx->ossl3ctx->defprov == NULL) { OSSL_LIB_CTX_free(ctx->ossl3ctx->libctx); free(ctx->ossl3ctx); From 496d8f091b9601b4bd7dcd4fa1957a80583551ed Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 14 Jan 2026 18:24:10 +0100 Subject: [PATCH 4095/4321] Add CI on CentOS 10 Stream (+FIPS mode) --- .github/build.sh | 3 ++ .github/setup-centos.sh | 38 +++++++++++++++++++++++ .github/workflows/centos.yml | 44 +++++++++++++++++++++++++++ tests/Makefile.am | 2 +- tests/softhsm_fips_ref.json | 26 +++++++++++++--- tests/test-p11test.sh | 3 ++ tests/test-pkcs11-tool-sign-verify.sh | 7 +++++ 7 files changed, 118 insertions(+), 5 deletions(-) create mode 100755 .github/setup-centos.sh create mode 100644 .github/workflows/centos.yml diff --git a/.github/build.sh b/.github/build.sh index 782fe738d9..08d3fab51f 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -57,6 +57,9 @@ else export CFLAGS="-m32" export LDFLAGS="-m32" fi + if [ "$1" == "fips" ]; then + export OPENSSL_FORCE_FIPS_MODE=1 + fi # normal procedure CONFIGURE_FLAGS="--disable-dependency-tracking" diff --git a/.github/setup-centos.sh b/.github/setup-centos.sh new file mode 100755 index 0000000000..80d81d683a --- /dev/null +++ b/.github/setup-centos.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -ex -o xtrace + +# Generic dependencies +DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool bash-completion vim-common softhsm openssl diffutils gawk nss-softokn nss-tools gcc gcc-c++ pcsc-lite-devel readline-devel openssl-devel zlib-ng-devel libcmocka-devel" + +dnf install -y 'dnf-command(config-manager)' +dnf config-manager --set-enabled crb +dnf install -y $DEPS + +XFAIL_TESTS="test-pkcs11-tool-test-threads.sh" + +if [ "$1" == "fips" ]; then + echo "# userspace fips" > /etc/system-fips + # We do not need the kernel part, but in case we ever do: + # mkdir -p /var/tmp/userspace-fips + # echo 1 > /var/tmp/userspace-fips/fips_enabled + # mount --bind /var/tmp/userspace-fips/fips_enabled \ + # /proc/sys/crypto/fips_enabled + update-crypto-policies --set FIPS + + # FIPS mode does not have implementation of 3DES and other ancient algorithms + sed -i -e "/TESTS += sm/a XFAIL_TESTS=sm" src/tests/unittests/Makefile.am + XFAIL_TESTS+=" test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh" +fi + +# In FIPS mode, OpenSSL doesn't allow RSA-PKCS, this is hardcoded into OpenSSL +# and we cannot influence it. Hence, the test is expected to fail in FIPS mode. +if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + XFAIL_TESTS+=" test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh" +fi + +sed -i -e "/XFAIL_TESTS/,$ { + s/.*XFAIL_TESTS.*/XFAIL_TESTS=$XFAIL_TESTS/ + q +}" tests/Makefile.am + diff --git a/.github/workflows/centos.yml b/.github/workflows/centos.yml new file mode 100644 index 0000000000..90dced7dc7 --- /dev/null +++ b/.github/workflows/centos.yml @@ -0,0 +1,44 @@ +name: CentOS Stream Linux + +on: + pull_request: + paths: + - '**.c' + - '**.h' + - '**.sh' + - .github/workflows/centos.yml + - '**.am' + - doc/** + - configure.ac + push: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + c10s: + runs-on: ubuntu-latest + container: + image: quay.io/centos/centos:stream10 + + steps: + - uses: actions/checkout@v4 + - run: .github/setup-centos.sh + - run: .github/build.sh dist + - name: Upload test logs + uses: actions/upload-artifact@v4 + if: failure() + with: + name: c10s-test-logs + path: | + tests/*.log + src/tests/unittests/*.log + + c10s-fips: + runs-on: ubuntu-latest + container: + image: quay.io/centos/centos:stream10 + steps: + - uses: actions/checkout@v4 + - run: .github/setup-centos.sh fips + - run: .github/build.sh fips diff --git a/tests/Makefile.am b/tests/Makefile.am index cbede71d87..073a838c7e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,4 +58,4 @@ endif endif endif # no tests expected to fail -#XFAIL_TESTS = +#XFAIL_TESTS= diff --git a/tests/softhsm_fips_ref.json b/tests/softhsm_fips_ref.json index 96b9a0fa92..eb49efc36f 100644 --- a/tests/softhsm_fips_ref.json +++ b/tests/softhsm_fips_ref.json @@ -598,9 +598,9 @@ ], [ "01", - "RSA_auth", + "RSA2048", "RSA", - "1024", + "2048", "", "YES", "YES", @@ -616,9 +616,9 @@ ], [ "02", - "RSA2048", + "RSA4096", "RSA", - "2048", + "4096", "", "YES", "YES", @@ -826,6 +826,15 @@ "YES", "" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], [ "01", "RSA_PKCS_PSS", @@ -925,6 +934,15 @@ "YES", "" ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], [ "01", "SHA512_RSA_PKCS_PSS", diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 95c006d3da..c0212d04f0 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -46,6 +46,9 @@ fi if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" fi +if [[ -e "/etc/system-fips" ]]; then + REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" +fi echo "Comparing with $REF_FILE" diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index a7e354b1bd..e208e83388 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -180,6 +180,13 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do if [[ ! -z "$HASH" ]]; then continue; fi + # Skip in FIPS mode -- RSA-PKCS encryption is no longer allowed + if [[ -e "/etc/system-fips" ]]; then + continue; + fi + if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + continue; + fi METHOD="RSA-PKCS" # RSA-PKCS works only on small data - generate small data: head -c 64 data From 8e6670358f1674a325d289bae53ad73939c81378 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 23 Jan 2026 14:57:43 +0100 Subject: [PATCH 4096/4321] ci: Use default Fedora image instead of quay.io --- .github/workflows/external-pkcs11.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 0b030a73a4..0262599cf2 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -33,7 +33,7 @@ jobs: test-kryoptic: runs-on: ubuntu-24.04 container: - image: quay.io/fedora/fedora:latest + image: fedora:latest env: SOURCE_PATH: ./ BUILD_PATH: ./ @@ -94,7 +94,7 @@ jobs: test-interoperability: runs-on: ubuntu-24.04 container: - image: quay.io/fedora/fedora:latest + image: fedora:latest env: SOURCE_PATH: ./ BUILD_PATH: ./ From 07a14752f098efe4c5ac2e958ac7cd81aee1b65e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 23 Jan 2026 15:21:09 +0100 Subject: [PATCH 4097/4321] pkcs11-tool: Do not query for the DE/ENCAPSULATE on non-KEM keys --- src/tools/pkcs11-tool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f9a5159f1f..9548685480 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6469,6 +6469,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) int sec = 0; CK_TOKEN_INFO info; CK_ULONG parameter_set; + int kem = 0; switch(getCLASS(sess, obj)) { case CKO_PRIVATE_KEY: @@ -6678,6 +6679,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } break; case CKK_ML_KEM: + kem = 1; switch (parameter_set) { case CKP_ML_KEM_512: printf("; ML-KEM-512\n"); @@ -6818,11 +6820,11 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("%sderive", sepa); sepa = ", "; } - if (pub && getENCAPSULATE(sess, obj)) { + if (pub && kem && getENCAPSULATE(sess, obj)) { printf("%sencapsulate", sepa); sepa = ", "; } - if ((!pub && !sec) && getDECAPSULATE(sess, obj)) { + if (!pub && !sec && kem && getDECAPSULATE(sess, obj)) { printf("%sdecapsulate", sepa); sepa = ", "; } From bc7b005a55932dcb9593dc7f40644e68091f641a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 7 Jan 2026 10:29:45 +0100 Subject: [PATCH 4098/4321] CI: added upload to Signpath.io --- .github/workflows/windows.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f714ae85bf..99a6ceff8a 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -115,10 +115,21 @@ jobs: - name: Build OpenSC run: nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts + id: upload-unsigned-artifact uses: actions/upload-artifact@v5 with: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: ./win32/*.msi + - name: Push to Signpath.io + if: ${{ github.repository == 'OpenSC/OpenSC' }} + uses: signpath/github-action-submit-signing-request@v2 + with: + api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' + organization-id: '8d2463fe-39bd-4a41-bb72-f008b4b1fe17' + project-slug: 'OpenSC' + signing-policy-slug: 'release-signing' + github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}' + wait-for-completion: false - name: Archive debug artifacts uses: actions/upload-artifact@v5 with: From d7007253c70f01d843ea13b1f999d30a87e80cb4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 23 Jan 2026 18:35:50 +0100 Subject: [PATCH 4099/4321] CI: perform Windows signing and macOS notarization for releases only --- .github/workflows/macos.yml | 7 +++++++ .github/workflows/windows.yml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2067e14385..92efb7516e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -46,12 +46,19 @@ jobs: DEV_ID_INSTALLER: ${{ secrets.DEV_ID_INSTALLER }} DEV_ID_APPLICATION: ${{ secrets.DEV_ID_APPLICATION }} - run: .github/build.sh + if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} env: CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} APPLE_ID: ${{ secrets.APPLE_ID }} + - run: .github/build.sh + if: ${{ ! startsWith(github.ref, 'refs/tags/') || github.repository != 'OpenSC/OpenSC' }} + env: + CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} + DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} + INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} - run: .github/cleanup-macos.sh env: KEY_PASSWORD: ${{ secrets.DEV_ID_PASSWORD }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 99a6ceff8a..4d7d21be0f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -121,7 +121,7 @@ jobs: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: ./win32/*.msi - name: Push to Signpath.io - if: ${{ github.repository == 'OpenSC/OpenSC' }} + if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} uses: signpath/github-action-submit-signing-request@v2 with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' From 9ab1daf21029dd18f8828d684ee6151d9238edab Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 19 Jan 2026 14:42:35 +0100 Subject: [PATCH 4100/4321] Remove remaining uses of strcat() Signed-off-by: Jakub Jelen --- src/libopensc/Makefile.am | 3 +-- src/libopensc/card-gids.c | 5 +++-- src/libopensc/card-piv.c | 8 +++++--- src/libopensc/log.c | 13 ++++++++----- src/libopensc/pkcs15.c | 10 ++++++---- src/pkcs11/pkcs11-display.c | 4 +++- src/scconf/Makefile.am | 1 + src/scconf/scconf.c | 5 +++-- src/tests/unittests/Makefile.am | 1 + src/tools/eidenv.c | 14 +++++++++----- src/tools/openpgp-tool.c | 13 ++++++++----- 11 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index eb17dfe7e6..53d4491b4d 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -83,8 +83,7 @@ libopensc_la_LIBADD = $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/ui/libnotify.la \ $(top_builddir)/src/ui/libstrings.la \ - $(top_builddir)/src/sm/libsmeac.la \ - $(top_builddir)/src/common/libcompat.la + $(top_builddir)/src/sm/libsmeac.la if WIN32 libopensc_la_LIBADD += -lws2_32 -lshlwapi -lcomctl32 endif diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index cce235b8a4..9dbce166f6 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -33,7 +33,6 @@ Some features are undocumented like the format used to store certificates. They #include #include -#include "../common/compat_strlcpy.h" #ifdef ENABLE_OPENSSL /* openssl only needed for card administration */ @@ -52,6 +51,8 @@ Some features are undocumented like the format used to store certificates. They // used for changing the default label if used twice #include "../pkcs15init/pkcs15-init.h" #include "card-gids.h" +#include "../common/compat_strlcat.h" +#include "../common/compat_strlcpy.h" #define GIDS_STATE_NONE 0 #define GIDS_STATE_READ_DATA_PRESENT 1 @@ -1359,7 +1360,7 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { char addition[4] = " 00"; addition[1] += containernum % 10; addition[2] += (containernum & 0xFF) / 10; - strcat(object->label, addition); + strlcat(object->label, addition, SC_PKCS15_MAX_LABEL_SIZE); } // convert char to wchar diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a266888cae..eb8114ad2a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -49,6 +49,8 @@ #endif #endif +#include "common/compat_strlcat.h" +#include "common/compat_strlcpy.h" #include "internal.h" /* 800-73-4 SM and VCI need: ECC, SM and OpenSSL or LibreSSL */ @@ -5136,11 +5138,11 @@ piv_process_history(sc_card_t *card) if (r != SC_SUCCESS) goto err; #ifdef _WIN32 - strcat(filename,"\\"); + strlcat(filename, "\\", PATH_MAX); #else - strcat(filename,"/"); + strlcat(filename, "/", PATH_MAX); #endif - strcat(filename,fp); + strlcat(filename, fp, PATH_MAX); r = piv_read_obj_from_file(card, filename, &ocfhfbuf, &ocfhflen); diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 36d24a3e20..61689126f7 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -47,6 +47,7 @@ #ifdef ENABLE_OPENSSL #include #endif /* ENABLE_OPENSSL */ +#include "common/compat_strlcat.h" #include "internal.h" @@ -362,6 +363,7 @@ void _sc_debug_hex(sc_context_t *ctx, int type, const char *file, int line, void sc_hex_dump(const u8 * in, size_t count, char *buf, size_t len) { char *p = buf; + size_t p_len = len; int lines = 0; if (buf == NULL || (in == NULL && count != 0)) { @@ -381,18 +383,19 @@ void sc_hex_dump(const u8 * in, size_t count, char *buf, size_t len) else ascbuf[i] = '.'; p += 3; + p_len -= 3; in++; } count -= i; ascbuf[i] = 0; for (; i < 16 && lines; i++) { - strcat(p, " "); + strlcat(p, " ", p_len); p += 3; + p_len -= 3; } - strcat(p, ascbuf); - p += strlen(p); - sprintf(p, "\n"); - p++; + snprintf(p, p_len, "%s\n", ascbuf); + p += strlen(ascbuf) + 1; + p_len -= strlen(ascbuf) - 1; lines++; } } diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index a932a445cf..a41f7ae49c 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -33,6 +33,8 @@ #include "pkcs15.h" #include "asn1.h" #include "common/libscdl.h" +#include "common/compat_strlcat.h" +#include "common/compat_strlcpy.h" #ifdef ENABLE_OPENSSL #include @@ -2961,19 +2963,19 @@ sc_pkcs15_serialize_guid(unsigned char *in, size_t in_size, unsigned flags, *out = '\0'; if (!flags) - strcpy(out, "{"); + strlcpy(out, "{", out_size); for (ii=0; ii<4; ii++) sprintf(out + strlen(out), "%02x", *(in + offs++)); for (jj=0; jj<3; jj++) { - strcat(out, "-"); + strlcat(out, "-", out_size); for (ii=0; ii<2; ii++) sprintf(out + strlen(out), "%02x", *(in + offs++)); } - strcat(out, "-"); + strlcat(out, "-", out_size); for (ii=0; ii<6; ii++) sprintf(out + strlen(out), "%02x", *(in + offs++)); if (!flags) - strcat(out, "}"); + strlcat(out, "}", out_size); return SC_SUCCESS; } diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 096168f819..62f45d8bce 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -29,6 +29,8 @@ #include "pkcs11-display.h" +#include "common/compat_strlcat.h" + /* NSS-specific stuff: * https://github.com/nss-dev/nss/blob/d86f709bb4974d10b343c746b6f89dd1ef80259b/lib/util/pkcs11n.h */ @@ -170,7 +172,7 @@ print_generic(FILE *f, long type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR /* padding */ while (strlen(hex) < 3*16) - strcat(hex, " "); + strlcat(hex, " ", sizeof(hex)); fprintf(f, "\n %08X %s %s", offset, hex, ascii); } else { diff --git a/src/scconf/Makefile.am b/src/scconf/Makefile.am index af5927dd03..7837945208 100644 --- a/src/scconf/Makefile.am +++ b/src/scconf/Makefile.am @@ -11,3 +11,4 @@ noinst_LTLIBRARIES = libscconf.la AM_CPPFLAGS = -I$(top_srcdir)/src libscconf_la_SOURCES = scconf.c parse.c write.c sclex.c +libscconf_la_LIBADD = $(top_builddir)/src/common/libcompat.la diff --git a/src/scconf/scconf.c b/src/scconf/scconf.c index a220f5c36a..ca13c3c9f4 100644 --- a/src/scconf/scconf.c +++ b/src/scconf/scconf.c @@ -30,6 +30,7 @@ #include #include +#include "common/compat_strlcat.h" #include "scconf.h" scconf_context *scconf_new(const char *filename) @@ -424,9 +425,9 @@ char *scconf_list_strdup(const scconf_list * list, const char *filler) return NULL; } while (list && list->data) { - strcat(buf, list->data); + strlcat(buf, list->data, len); if (filler) { - strcat(buf, filler); + strlcat(buf, filler, len); } list = list->next; } diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 1ca2dcbc10..96ace28569 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -30,6 +30,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/ \ AM_CPPFLAGS =$(CODE_COVERAGE_CPPFLAGS) LDADD = $(top_builddir)/src/libopensc/libopensc.la \ $(top_builddir)/src/common/libscdl.la \ + $(top_builddir)/src/common/libcompat.la \ $(CODE_COVERAGE_LIBS) \ $(OPTIONAL_OPENSSL_LIBS) \ $(CMOCKA_LIBS) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 62ddd2164a..8d6a4f19b2 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -30,6 +30,9 @@ #include #include + +#include "common/compat_strlcat.h" +#include "common/compat_strlcpy.h" #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" @@ -148,12 +151,13 @@ static void bintohex(char *buf, int len) static void exportprint(const char *key, const char *val) { if (exec_program) { - char * cp; - cp = malloc(strlen(key) + strlen(val) + 2); + char *cp; + size_t cp_size = strlen(key) + strlen(val) + 2; + cp = malloc(cp_size); if (cp) { - strcpy(cp, key); - strcat(cp, "="); - strcat(cp, val); + strlcpy(cp, key, cp_size); + strlcat(cp, "=", cp_size); + strlcat(cp, val, cp_size); putenv(cp); free(cp); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 4b7510fd49..946f9db501 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -38,6 +38,9 @@ #include #include + +#include "common/compat_strlcat.h" +#include "common/compat_strlcpy.h" #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/cards.h" @@ -234,13 +237,13 @@ static void display_data(const struct ef_name_map *map, u8 *data, size_t length) if (value != NULL) { if (exec_program) { - char *envvar= malloc(strlen(map->env_name) + - strlen(value) + 2); + size_t envvar_size = strlen(map->env_name) + strlen(value) + 2; + char *envvar = malloc(envvar_size); if (envvar != NULL) { - strcpy(envvar, map->env_name); - strcat(envvar, "="); - strcat(envvar, value); + strlcpy(envvar, map->env_name, envvar_size); + strlcat(envvar, "=", envvar_size); + strlcat(envvar, value, envvar_size); putenv(envvar); /* envvar deliberately kept: see putenv(3) */ } From 33121bede2e73ae6434c9042a69fa4748a81543c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Jan 2026 13:07:01 +0100 Subject: [PATCH 4101/4321] pkcs11: Default to CKA_TOKEN=FALSE according to the specification Signed-off-by: Jakub Jelen --- src/pkcs11/framework-pkcs15.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9352adbaf6..4980e97359 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2576,8 +2576,9 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile /* CKA_TOKEN defaults to false */ rv = attr_find(pTemplate, ulCount, CKA_TOKEN, &_token, NULL); - if (rv != CKR_OK) + if (rv != CKR_TEMPLATE_INCOMPLETE && rv != CKR_OK) { return rv; + } /* See if the "slot" is pin protected. If so, get the PIN id */ if ((pin = slot_data_auth_info(slot->fw_data)) != NULL) @@ -2722,7 +2723,6 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile return rv; } - static CK_RV pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) @@ -3119,24 +3119,12 @@ pkcs15_create_object(struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK return rv; rv = attr_find(pTemplate, ulCount, CKA_TOKEN, &_token, NULL); - if (rv == CKR_TEMPLATE_INCOMPLETE) { - /* TODO OpenSC has not checked CKA_TOKEN == TRUE, so only - * so only enforce for secret_key - */ - if (_class != CKO_SECRET_KEY) - _token = TRUE; /* default if not in template */ - } - else if (rv != CKR_OK) { + if (rv != CKR_TEMPLATE_INCOMPLETE && rv != CKR_OK) { return rv; } - /* TODO The previous code does not check for CKA_TOKEN=TRUE - * PKCS#11 CreatObject examples always have it, but - * PKCS#11 says the default is false. - * for backward compatibility, will default to TRUE - */ - /* Dont need profile id creating session only objects, - except when the card supports temporary on card session objects */ + /* Dont need profile if creating session only objects, + * except when the card supports temporary on card session objects */ p15init_create_object = _token == TRUE || (p11card->card->caps & SC_CARD_CAP_ONCARD_SESSION_OBJECTS) == SC_CARD_CAP_ONCARD_SESSION_OBJECTS; if (p15init_create_object) { From 6c178191ba8ce1393c9b91cfeb2773b51f52b649 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 15 Dec 2025 16:06:47 +0100 Subject: [PATCH 4102/4321] pkcs11-tool: Add missing help option for --usage-encapsulate --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9548685480..6e73d88159 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -383,6 +383,7 @@ static const char *option_help[] = { "Specify 'decrypt' key usage flag (sets DECRYPT in privkey and ENCRYPT in pubkey for RSA, sets both DECRYPT and ENCRYPT for secret keys)", "Specify 'derive' key usage flag (EC only)", "Specify 'wrap' key usage flag", + "Specify 'encapsulate' key usage flag (sets ENCAPSULATE in public and DECAPSULATE in private)", "Write an object (key, cert, data) to the card", "Get object's CKA_VALUE attribute (use with --type)", "Delete an object (use with --type cert/data/privkey/pubkey/secrkey)", From db0450f5eba976a318217eb8d3a4dd6f460518bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 15 Dec 2025 18:03:57 +0100 Subject: [PATCH 4103/4321] pkcs11-tool: Check the the options structures are in sync Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6e73d88159..9cdd4fbe56 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -338,7 +338,7 @@ static const struct option options[] = { { "public-key-info", 0, NULL, OPT_PUBLIC_KEY_INFO}, { "uri", 1, NULL, OPT_URI}, { "uri-with-slot-id", 0, NULL, OPT_URI_WITH_SLOT_ID}, - { NULL, 0, NULL, 0 } + { NULL, 0, NULL, 0 }, }; // clang-format on @@ -434,7 +434,9 @@ static const char *option_help[] = { "Specify the file containing the info for HKDF (optional)", "When reading a public key, try to read PUBLIC_KEY_INFO (DER encoding of SPKI)", "Specify the PKCS#11 URI for module, slot, token or object", - "Include SlotId in PKCS#11 URI"}; + "Include SlotId in PKCS#11 URI", + "", +}; static const char * app_name = "pkcs11-tool"; /* for utils.c */ @@ -834,6 +836,9 @@ int main(int argc, char * argv[]) char *s = NULL; CK_RV rv; + static_assert(sizeof(options) / sizeof(options[0]) == sizeof(option_help) / sizeof(option_help[0]), + "Inconsistent size of the options and options_help structures!"); + #ifdef _WIN32 char expanded_val[PATH_MAX]; DWORD expanded_len; From 20c551abeb1be67e45a93d138162d55948bf709b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 25 Jan 2026 21:21:35 -0600 Subject: [PATCH 4104/4321] card-piv.c test History object URL file name is all hex digits On branch piv-history-fix Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 3ead402597..b9eeb42e1f 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -5139,7 +5139,12 @@ piv_process_history(sc_card_t *card) r = SC_ERROR_INVALID_DATA; goto err; } - + for (i = 0; i < 64; i++) { + if (isxdigit((unsigned char)fp[i]) == 0) { + r = SC_ERROR_INVALID_DATA; + goto err; + } + } /* Use the same directory as used for other OpenSC cached items */ r = sc_get_cache_dir(card->ctx, filename, sizeof(filename) - strlen(fp) - 2); From cb35c5a5018df846d7421daf398bddb000dc4859 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 25 Jan 2026 21:28:37 -0600 Subject: [PATCH 4105/4321] card-piv.c whitespace fixup Changes to be committed: modified: card-piv.c On branch piv-history-fix Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index b9eeb42e1f..414eceb136 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -5135,14 +5135,14 @@ piv_process_history(sc_card_t *card) goto err; } fp++; - if (strlen(fp) != 64) { /* ASCII-HEX encoded SHA-256 */ + if (strlen(fp) != 64) { /* ASCII-HEX encoded SHA-256 */ r = SC_ERROR_INVALID_DATA; goto err; } for (i = 0; i < 64; i++) { if (isxdigit((unsigned char)fp[i]) == 0) { - r = SC_ERROR_INVALID_DATA; - goto err; + r = SC_ERROR_INVALID_DATA; + goto err; } } From 053575dbf87aa194cd4f9e9f537ad19fd626222c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Jan 2026 16:40:25 +0100 Subject: [PATCH 4106/4321] CI: disable Signpath via AppVeyor --- .appveyor.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index e306e53be5..0c5ba37520 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -105,12 +105,6 @@ build_script: - bash -c "git config --global user.name 'AppVeyor'" - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" -a \"$APPVEYOR_REPO_NAME\" = \"OpenSC/OpenSC\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" -deploy: -- provider: Webhook - url: https://app.signpath.io/API/v1/8d2463fe-39bd-4a41-bb72-f008b4b1fe17/Integrations/AppVeyor?ProjectSlug=OpenSC&SigningPolicySlug=release-signing&ArtifactConfigurationSlug=initial - authorization: - secure: 73Qvk9MbD7M7ZcoO6NnSH7zDA+9wSKZqNc602b1UeA5v6GsDyEvpCOlzJ9VvBcUuePTKBRsZ+uGQYKsddABgQA== - cache: - C:\zlib -> .appveyor.yml - C:\zlib-Win32 -> .appveyor.yml From 17172e3974b37077ea79de0ac290d615b94db5d5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Jan 2026 11:43:05 +0100 Subject: [PATCH 4107/4321] CI: updated Github actions Co-authored-by: Raul Metsma --- .github/workflows/macos.yml | 18 +++++++++--------- .github/workflows/windows.yml | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 92efb7516e..e5beeafa9c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -23,9 +23,9 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Checkout OpenSSL sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: repository: openssl/openssl ref: openssl-3.5 @@ -33,7 +33,7 @@ jobs: - name: Get OpenSSL commit hash id: openssl_hash run: echo "hash=$(cd openssl && git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache with: path: openssl_bin @@ -63,13 +63,13 @@ jobs: env: KEY_PASSWORD: ${{ secrets.DEV_ID_PASSWORD }} - name: Cache build artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: opensc-build-${{ matrix.os }} path: OpenSC*.dmg - name: Upload test logs - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: failure() with: name: ${{ matrix.os }}-logs @@ -82,12 +82,12 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: .github/setup-macos.sh libressl - run: .github/build.sh libressl - run: .github/cleanup-macos.sh - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() with: name: ${{ matrix.os }}-libressl-logs @@ -98,9 +98,9 @@ jobs: runs-on: macos-latest needs: [build] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Pull build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: opensc-build-macos-15 - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4d7d21be0f..8f7df319ab 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -37,7 +37,7 @@ jobs: BUILD_NUMBER: ${{ github.run_number }} steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Package name shell: bash run: | @@ -59,7 +59,7 @@ jobs: arch: ${{ matrix.setenv }} - name: Cache vcpkg if: matrix.configuration == 'Release' - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ${{ github.workspace }}/vcpkg_cache key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json') }} @@ -75,7 +75,7 @@ jobs: run: powershell -ExecutionPolicy Bypass -File .github/setup-wix.ps1 - name: Restore Cache if: matrix.configuration == 'Release' - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache with: path: openpace-${{ env.OPENPACE_VER }} @@ -116,7 +116,7 @@ jobs: run: nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts id: upload-unsigned-artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: ./win32/*.msi @@ -131,7 +131,7 @@ jobs: github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}' wait-for-completion: false - name: Archive debug artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: debug_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: | From e7fd828b8894b1494e30d652eee8e6a2ede8b34a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Jan 2026 15:43:13 +0100 Subject: [PATCH 4108/4321] CI: extracted notarization process for better orchestration --- .github/workflows/macos.yml | 11 ++++------- MacOSX/Makefile.am | 1 + MacOSX/build | 7 ++----- MacOSX/notarize | 23 +++++++++++++++++++++++ 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100755 MacOSX/notarize diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e5beeafa9c..15257fa477 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -46,19 +46,16 @@ jobs: DEV_ID_INSTALLER: ${{ secrets.DEV_ID_INSTALLER }} DEV_ID_APPLICATION: ${{ secrets.DEV_ID_APPLICATION }} - run: .github/build.sh - if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} env: CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} - NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} - APPLE_ID: ${{ secrets.APPLE_ID }} - - run: .github/build.sh - if: ${{ ! startsWith(github.ref, 'refs/tags/') || github.repository != 'OpenSC/OpenSC' }} + - run: MacOSX/notarize + if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} env: - CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} - INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} + NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} + APPLE_ID: ${{ secrets.APPLE_ID }} - run: .github/cleanup-macos.sh env: KEY_PASSWORD: ${{ secrets.DEV_ID_PASSWORD }} diff --git a/MacOSX/Makefile.am b/MacOSX/Makefile.am index d186984ae2..b43d69c859 100644 --- a/MacOSX/Makefile.am +++ b/MacOSX/Makefile.am @@ -3,6 +3,7 @@ EXTRA_DIST = build \ build-openssl-macos.sh \ Distribution.xml.in \ libtool-bundle \ + notarize \ OpenSC_applescripts.entitlements \ OpenSC_binaries.entitlements \ OpenSC_Notify.applescript \ diff --git a/MacOSX/build b/MacOSX/build index 49457ac31b..2e1428972c 100755 --- a/MacOSX/build +++ b/MacOSX/build @@ -14,12 +14,14 @@ set -ex test -x ./configure || ./bootstrap BUILDPATH=${PWD} +# keep in sync with MacOSX/notarize while IFS='=' read -r key value; do # Skip empty or comment lines [[ -z "$key" || "$key" =~ ^# ]] && continue export "$key=$value" done < $BUILDPATH/VERSION.mk +# keep in sync with MacOSX/notarize export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX} PREFIX=/Library/OpenSC export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig @@ -189,8 +191,3 @@ do fi done rm -rf ${imagedir} - -if test -n "${NOTARIZATION_PASSWORD}"; then - xcrun notarytool submit --team-id ${DEVELOPMENT_TEAM} --apple-id ${APPLE_ID} --password ${NOTARIZATION_PASSWORD} --wait OpenSC-${PACKAGE_VERSION}.dmg - xcrun stapler staple OpenSC-${PACKAGE_VERSION}.dmg -fi \ No newline at end of file diff --git a/MacOSX/notarize b/MacOSX/notarize new file mode 100755 index 0000000000..e5a6ebfd02 --- /dev/null +++ b/MacOSX/notarize @@ -0,0 +1,23 @@ +#!/bin/bash +# Notarize and staple the macOS installer image. +# +# This is only tested and supported on macOS 10.10 or later, using Xcode 6.0.1. +# Building should also work on older macOS versions with slight changes; YMMV. + +set -ex +BUILDPATH=${PWD} + +# keep in sync with MacOSX/build +while IFS='=' read -r key value; do + # Skip empty or comment lines + [[ -z "$key" || "$key" =~ ^# ]] && continue + export "$key=$value" +done < $BUILDPATH/VERSION.mk + +# keep in sync with MacOSX/build +export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX} + +if test -n "${NOTARIZATION_PASSWORD}" -a -n "${DEVELOPMENT_TEAM}"; then + xcrun notarytool submit --team-id ${DEVELOPMENT_TEAM} --apple-id ${APPLE_ID} --password ${NOTARIZATION_PASSWORD} --wait OpenSC-${PACKAGE_VERSION}.dmg + xcrun stapler staple OpenSC-${PACKAGE_VERSION}.dmg +fi From c1fc88ec250e2b7722399431cc7bcf3de3c070dc Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 22 Jan 2026 09:10:30 -0600 Subject: [PATCH 4109/4321] card-piv.c Fix creation of serial number from FASC-N The PIV CHUID object contains a FASC-N and a GUID. If the FASC-N is all zeros the GUID will be used to create a serial number. The FASC-N is a required field. Card issuers of non-US-government cards should add a FASC-N staring with ";9999" (in ISO 4bit + parity code). i.e. starts with "0xD4 0xE7 0x39" New Token2 tokens with PIV (and maybe others) have an all zero FASC-N which means without this patch the serial number is all zeros. This can lead to problems if more then one card is on the system. Note that the Yubico-piv-tool will create a FASC-N starting with ";9999" so does not have this problem and the serial number will be based on the GUID which is settable. The use of the CHUID goes back to 2005 when both Microsoft and OpenSC would use it for serial number and containerIds. Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 0b8687cc45..faa0a9167e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -4286,7 +4286,8 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) { int r; int i; - u8 gbits; + u8 gbits = 0; /* 0 not present or wrong length or all zeros */ + u8 fbits = 0; /* 0 not present or wrong length or all zeros */ u8 *rbuf = NULL; const u8 *body; const u8 *fascn; @@ -4314,9 +4315,15 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */ if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) { fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */ + + if (fascn && fascnlen == 25) { + for (i = 0; i < 25; i++) { + fbits = fbits || fascn[i]; /* if all are zero, gbits will be zero */ + } + } + guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen); - gbits = 0; /* if guid is valid, gbits will not be zero */ if (guid && guidlen == 16) { for (i = 0; i < 16; i++) { gbits = gbits | guid[i]; /* if all are zero, gbits will be zero */ @@ -4326,8 +4333,9 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) "fascn=%p,fascnlen=%"SC_FORMAT_LEN_SIZE_T"u,guid=%p,guidlen=%"SC_FORMAT_LEN_SIZE_T"u,gbits=%2.2x", fascn, fascnlen, guid, guidlen, gbits); - if (fascn && fascnlen == 25) { + if (fascn && fascnlen == 25 && fbits) { /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ + /* ;9999 is non-gov issued FASC-N, will use FASC-N for gov issued if no guid */ if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { /* fascnlen is 25 */ @@ -4337,8 +4345,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) gbits = 0; /* set to skip using guid below */ } } - if (guid && gbits) { - /* guidlen is 16 */ + if (guid && guidlen == 16 && gbits) { serial->len = guidlen; memcpy (serial->value, guid, serial->len); r = SC_SUCCESS; @@ -4346,6 +4353,12 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) } } + if (fbits == 0 && gbits == 0) { /* were not able to set the serial number */ + serial->len = 16; + memset(serial->value, 0x00, serial->len); + r = SC_ERROR_INTERNAL; + } + card->serialnr = *serial; LOG_FUNC_RETURN(card->ctx, r); } From 44e18bb1d6de62c879103226d01335ec08527472 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Feb 2026 12:47:18 +0100 Subject: [PATCH 4110/4321] CI: updated github actions (#3564) --- .github/workflows/centos.yml | 6 ++--- .github/workflows/cifuzz.yml | 2 +- .github/workflows/codeql.yml | 4 +-- .github/workflows/codespell.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/doc.yml | 2 +- .github/workflows/fedora.yml | 6 ++--- .github/workflows/formatter.yml | 2 +- .github/workflows/linux-strict.yml | 4 +-- .github/workflows/linux.yml | 40 +++++++++++++++--------------- .github/workflows/macos.yml | 18 +++++++------- .github/workflows/windows.yml | 10 ++++---- 12 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.github/workflows/centos.yml b/.github/workflows/centos.yml index 90dced7dc7..3e758f0dc2 100644 --- a/.github/workflows/centos.yml +++ b/.github/workflows/centos.yml @@ -22,11 +22,11 @@ jobs: image: quay.io/centos/centos:stream10 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-centos.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() with: name: c10s-test-logs @@ -39,6 +39,6 @@ jobs: container: image: quay.io/centos/centos:stream10 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-centos.sh fips - run: .github/build.sh fips diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 02590105b3..0d478ba53f 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -22,7 +22,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 16c34e7458..a1ee762862 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -39,7 +39,7 @@ jobs: - run: .github/build.sh - name: Upload test logs - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: failure() with: name: codeql-logs diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 39505eabb7..efeb545774 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: codespell-project/actions-codespell@master with: skip: ./src/tests/fuzzing/corpus,compat_* diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 709c7b2d46..cb5b536592 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -15,7 +15,7 @@ jobs: env: HAS_COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN != '' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-linux.sh force-install - run: ./bootstrap - run: ./configure --disable-dependency-tracking --enable-piv-sm diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index d03605c92d..c3fe23795a 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -16,7 +16,7 @@ jobs: steps: # Do this before checkout otherwise we will not have a git repository - run: dnf install -y git - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-fedora.sh # git checkout to revert changes to tests/Makefile.am done by the setup - run: | diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 0755cd69af..ec2f0fdc65 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -21,11 +21,11 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-fedora.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() with: name: fedora-test-logs @@ -38,6 +38,6 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-fedora.sh ix86 - run: .github/build.sh ix86 diff --git a/.github/workflows/formatter.yml b/.github/workflows/formatter.yml index dfb8b7ae2a..623a495d42 100644 --- a/.github/workflows/formatter.yml +++ b/.github/workflows/formatter.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 100 - uses: yshui/git-clang-format-lint@master diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 9b34bfaa78..90c9f8375c 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -71,14 +71,14 @@ jobs: container: ubuntu:latest container: ${{ matrix.container }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - run: .github/setup-linux.sh ${{ matrix.compiler }} force-install - run: .github/build.sh dist env: CC: ${{ matrix.compiler }} CFLAGS: ${{ env.CFLAGS }} ${{ matrix.compiler == 'clang' && env.CLANG_CFLAGS || '' }} - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() with: name: ${{ matrix.name }}-${{ matrix.compiler }}-strict-test-logs diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 209c60545d..4abe82e2f3 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -44,11 +44,11 @@ jobs: arch: arm64 runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: failure() with: name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-test-logs @@ -56,14 +56,14 @@ jobs: tests/*.log src/tests/unittests/*.log - &use_cache - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache-build with: path: ./* key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-${{ github.sha }} - name: Upload build artifacts if: matrix.build == 'dist' - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: opensc-build-${{ matrix.dist }}-${{ matrix.arch }} path: @@ -72,7 +72,7 @@ jobs: build-no-shared: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -84,7 +84,7 @@ jobs: build-no-openssl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -96,7 +96,7 @@ jobs: build-ix86: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -108,11 +108,11 @@ jobs: build-mingw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: opensc-build-mingw path: @@ -121,11 +121,11 @@ jobs: build-mingw32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: opensc-build-mingw32 path: @@ -140,7 +140,7 @@ jobs: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base execute_install_scripts: true - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache-build with: path: ./* @@ -201,14 +201,14 @@ jobs: build-libressl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base execute_install_scripts: true - name: Restore LibreSSL build - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 id: libressl-cache with: path: | @@ -216,7 +216,7 @@ jobs: key: libressl-${{ env.LIBRESSL_VERSION }} - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 if: failure() with: name: libressl-logs @@ -224,7 +224,7 @@ jobs: config.log tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache-build if: ${{ success() }} with: @@ -232,7 +232,7 @@ jobs: key: ${{ runner.os }}-libressl-${{ github.sha }} - if: ${{ steps.libressl-cache.outputs.cache-hit != 'true' }} name: Cache LibreSSL build - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: | libressl-${{ env.LIBRESSL_VERSION }}/ @@ -252,7 +252,7 @@ jobs: packages: ${{ env.BASE_DEPS }} version: apt-latest-base execute_install_scripts: true - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache-build with: path: ./* @@ -268,13 +268,13 @@ jobs: runs-on: ubuntu-latest needs: [build, build-mingw] steps: - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache-build with: path: ./* key: ${{ runner.os }}-24.04-amd64-dist-${{ github.sha }} - name: Pull mingw build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: opensc-build-mingw - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2067e14385..a0580aa3d1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -23,9 +23,9 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Checkout OpenSSL sources - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: repository: openssl/openssl ref: openssl-3.5 @@ -33,7 +33,7 @@ jobs: - name: Get OpenSSL commit hash id: openssl_hash run: echo "hash=$(cd openssl && git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: cache with: path: openssl_bin @@ -56,13 +56,13 @@ jobs: env: KEY_PASSWORD: ${{ secrets.DEV_ID_PASSWORD }} - name: Cache build artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: opensc-build-${{ matrix.os }} path: OpenSC*.dmg - name: Upload test logs - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: failure() with: name: ${{ matrix.os }}-logs @@ -75,12 +75,12 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: .github/setup-macos.sh libressl - run: .github/build.sh libressl - run: .github/cleanup-macos.sh - name: Upload test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: failure() with: name: ${{ matrix.os }}-libressl-logs @@ -91,9 +91,9 @@ jobs: runs-on: macos-latest needs: [build] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Pull build artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: opensc-build-macos-15 - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f714ae85bf..d88039b39b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -37,7 +37,7 @@ jobs: BUILD_NUMBER: ${{ github.run_number }} steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Package name shell: bash run: | @@ -59,7 +59,7 @@ jobs: arch: ${{ matrix.setenv }} - name: Cache vcpkg if: matrix.configuration == 'Release' - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ${{ github.workspace }}/vcpkg_cache key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json') }} @@ -75,7 +75,7 @@ jobs: run: powershell -ExecutionPolicy Bypass -File .github/setup-wix.ps1 - name: Restore Cache if: matrix.configuration == 'Release' - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache with: path: openpace-${{ env.OPENPACE_VER }} @@ -115,12 +115,12 @@ jobs: - name: Build OpenSC run: nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: ./win32/*.msi - name: Archive debug artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: debug_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} path: | From 45af3fb11db58808ba3cac9574d02bc869fc32fb Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Feb 2026 15:25:31 +0100 Subject: [PATCH 4111/4321] switched to Github issue forms (#3562) --- .github/ISSUE_TEMPLATE.md | 31 ------- .github/ISSUE_TEMPLATE/bug_report.yml | 103 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 21 +++++ .github/ISSUE_TEMPLATE/feature_request.yml | 38 ++++++++ 4 files changed, 162 insertions(+), 31 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 183fb662d6..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,31 +0,0 @@ -### Problem Description - - - -### Proposed Resolution - -### Steps to reproduce - -### Logs - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..ad297efc51 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,103 @@ +name: Bug report +description: Report a problem or unexpected behavior in OpenSC +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug in OpenSC! + Please fill out the sections below to help us diagnose the issue. + See https://github.com/OpenSC/OpenSC/wiki/How-to-write-a-good-bug-report on what to include here. + + - type: textarea + id: description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + placeholder: What went wrong? + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: How can we reproduce the issue? + placeholder: | + 1. + 2. + 3. + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What you expected to happen. + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual behavior + description: What actually happened. + validations: + required: true + + - type: input + id: opensc_version + attributes: + label: OpenSC version + placeholder: e.g. 0.25.1 + description: Only the latest release and development versions are supported. + validations: + required: true + + - type: input + id: os + attributes: + label: Operating system + placeholder: e.g. Ubuntu 22.04, Windows 11, macOS 14 + validations: + required: true + + - type: input + id: card + attributes: + label: Smart card model or security token + placeholder: Try `opensc-tool -n` if unkown + + - type: input + id: card + attributes: + label: Application used with smart card + placeholder: e.g. Firefox, Windows Logon, Apple Mail, ssh, ... + + - type: textarea + id: logs + attributes: + label: Logs and debug output + description: | + Please include relevant logs or debug output. + You can enable verbose output setting the environment variable `OPENSC_DEBUG` to `3`. + - `set OPENSC_DEBUG="3"` (Windows CMD) + - `export OPENSC_DEBUG="3"` (Unix shell) + + Useful commands for getting debug information are: + - `opensc-tool --atr --name -vvv` + - `pkcs11-tool --test --login` + - `certutil -scinfo` (Windows only) + - `sc_auth identities` (macOS only) + render: shell + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I am using a supported OpenSC version + required: true + - label: I have searched existing issues to avoid duplicates + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..3860a6d5d3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,21 @@ +blank_issues_enabled: false + +contact_links: + - name: 🚨 Security vulnerability report + url: https://github.com/OpenSC/OpenSC/security/advisories/new + about: | + Please report security vulnerabilities privately using GitHub Security Advisories. + Do NOT open a public issue for security-related problems. + + - name: 📖 OpenSC documentation + url: https://github.com/OpenSC/OpenSC/wiki + about: Check the documentation and wiki before opening an issue + + - name: 🤔 OpenSC GitHub Discussions + url: https://github.com/OpenSC/OpenSC/discussions + about: | + Ask questions, start discussions, or propose ideas that don't belong in an issue. + + - name: 💬 OpenSC mailing lists + url: https://github.com/OpenSC/OpenSC/wiki/Mailing-lists + about: For general discussion and usage questions diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..e5b5601259 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,38 @@ +name: Feature request +description: Suggest an enhancement or new feature for OpenSC +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Have an idea to improve OpenSC? We'd love to hear it. + + - type: textarea + id: problem + attributes: + label: Problem statement + description: What problem does this feature solve? + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed solution + description: Describe the solution you'd like to see. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: Any alternative solutions or workarounds you've considered. + + - type: textarea + id: context + attributes: + label: Additional context + description: | + Related standards, card types, use cases, or references. + For new smart cards, include the output of `opensc-tool --atr --name -vvv` From 8012a0a15beb8217869f2ec9f87035660e5d46cb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 11 Feb 2026 17:40:26 +0100 Subject: [PATCH 4112/4321] github: Fix id in bug report template --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ad297efc51..99402d1592 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -70,7 +70,7 @@ body: placeholder: Try `opensc-tool -n` if unkown - type: input - id: card + id: application attributes: label: Application used with smart card placeholder: e.g. Firefox, Windows Logon, Apple Mail, ssh, ... From 8c65cfc944470640a30eb04b037e097554e8fa08 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 12 Feb 2026 00:05:55 +0100 Subject: [PATCH 4113/4321] Removed duplicated link to security vulnerabilities --- .github/ISSUE_TEMPLATE/config.yml | 6 ------ SECURITY.md | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3860a6d5d3..9524d9b870 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,12 +1,6 @@ blank_issues_enabled: false contact_links: - - name: 🚨 Security vulnerability report - url: https://github.com/OpenSC/OpenSC/security/advisories/new - about: | - Please report security vulnerabilities privately using GitHub Security Advisories. - Do NOT open a public issue for security-related problems. - - name: 📖 OpenSC documentation url: https://github.com/OpenSC/OpenSC/wiki about: Check the documentation and wiki before opening an issue diff --git a/SECURITY.md b/SECURITY.md index 017dcf92aa..df5c8df2af 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,7 +16,7 @@ backport security fixes into them. Only the last release is supported. If you discovered security vulnerability in supported version of OpenSC, you can either report it with a button "Report a vulnerability" in -[Security tab](https://github.com/OpenSC/OpenSC/security/) +[Security tab](https://github.com/OpenSC/OpenSC/security/advisories/new) (Do not create normal public issue with security relevant information!) or you can send email to any recently active project developers frankmorgner(at)gmail.com, deengert(at)gmail.com and/or From 7f2e1062785d1442bab6f7378823c35ece5a91e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 12 Feb 2026 00:18:50 +0100 Subject: [PATCH 4114/4321] Unify wording of contact_list links with the other issue forms --- .github/ISSUE_TEMPLATE/config.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 9524d9b870..ced270e88c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,15 +1,11 @@ blank_issues_enabled: false contact_links: - - name: 📖 OpenSC documentation - url: https://github.com/OpenSC/OpenSC/wiki - about: Check the documentation and wiki before opening an issue - - - name: 🤔 OpenSC GitHub Discussions - url: https://github.com/OpenSC/OpenSC/discussions + - name: Start a discussion + url: https://github.com/OpenSC/OpenSC/discussions/new/choose about: | Ask questions, start discussions, or propose ideas that don't belong in an issue. - - name: 💬 OpenSC mailing lists + - name: Use the mailing lists url: https://github.com/OpenSC/OpenSC/wiki/Mailing-lists - about: For general discussion and usage questions + about: Write us an email or read the archive. From 4924961ec012989927303fd61033d0be180956a8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Feb 2026 18:27:17 +0100 Subject: [PATCH 4115/4321] Change usage of pin logged_in state to bitfield Signed-off-by: Jakub Jelen --- src/libopensc/card-dtrust.c | 2 +- src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-piv.c | 8 ++++---- src/libopensc/opensc.h | 8 ++++---- src/pkcs11/pkcs11-session.c | 2 +- src/tools/opensc-explorer.c | 24 ++++++++++++++---------- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index d56e341981..f3817200d1 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -734,7 +734,7 @@ dtrust_pin_cmd(struct sc_card *card, data2.pin_type = data->pin_type; r = dtrust_pin_cmd(card, &data2, tries_left); - if (data2.pin1.logged_in == SC_PIN_STATE_LOGGED_IN) { + if (data2.pin1.logged_in & SC_PIN_STATE_LOGGED_IN) { /* Return if we are already authenticated */ sc_log(card->ctx, "PIN 0x%02x already verified. Skipping authentication.", data->pin_reference); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 4524275c51..8c5d840ee3 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -1993,7 +1993,7 @@ iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries LOG_FUNC_RETURN(ctx, rv); if (!rv) { - if (pin_cmd.pin1.logged_in == SC_PIN_STATE_LOGGED_IN) + if (pin_cmd.pin1.logged_in & SC_PIN_STATE_LOGGED_IN) if (iasecc_chv_cache_is_verified(card, &pin_cmd)) LOG_FUNC_RETURN(ctx, SC_SUCCESS); } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index faa0a9167e..a250a91990 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -6078,11 +6078,11 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) * return not logged in. Needed because of logic in e6f7373ef066 */ if (data->pin_type == SC_AC_CONTEXT_SPECIFIC) { - data->pin1.logged_in = 0; + data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - if (priv->logged_in == SC_PIN_STATE_LOGGED_IN) { + if (priv->logged_in & SC_PIN_STATE_LOGGED_IN) { /* Avoid status requests when the user is logged in to handle NIST * 800-73-4 Part 2: * The PKI cryptographic function (see Table 4b) is protected with @@ -6157,7 +6157,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->cmd == SC_PIN_CMD_GET_INFO) { if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) { sc_log(card->ctx, "CI_CANT_USE_GETDATA_FOR_STATE set, assume logged_in=%d", priv->logged_in); - data->pin1.logged_in = priv->logged_in; /* use what ever we saw last */ + data->pin1.logged_in = priv->logged_in; /* use what ever we saw last */ } else if (priv->card_issues & CI_VERIFY_LC0_FAIL && priv->pin_cmd_verify_sw1 == 0x63U ) { /* can not use modified return codes from iso->drv->pin_cmd */ /* try another method, looking at a protected object this may require adding one of these to NEO */ @@ -6281,7 +6281,7 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) goto err; if (was_reset > 0) - priv->logged_in = SC_PIN_STATE_UNKNOWN; + priv->logged_in = SC_PIN_STATE_UNKNOWN; r = 0; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 20fb62ce52..2b639587bb 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -434,10 +434,10 @@ typedef struct sc_reader { #define SC_PIN_ENCODING_GLP 2 /* Global Platform - Card Specification v2.0.1 */ /** Values for sc_pin_cmd_pin.logged_in, can be bitmapped together */ -#define SC_PIN_STATE_UNKNOWN -1 -#define SC_PIN_STATE_LOGGED_OUT 0 -#define SC_PIN_STATE_LOGGED_IN 1 -#define SC_PIN_STATE_NEEDS_CHANGE 2 +#define SC_PIN_STATE_UNKNOWN 0 +#define SC_PIN_STATE_LOGGED_OUT 1 +#define SC_PIN_STATE_LOGGED_IN 2 +#define SC_PIN_STATE_NEEDS_CHANGE 4 /* A card driver receives the sc_pin_cmd_data and sc_pin_cmd_pin structures filled in by the * caller, with the exception of the fields returned by the driver for SC_PIN_CMD_GET_INFO. diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index cc48c83b9d..99e80f312c 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -286,7 +286,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ } /* Check whether the user is logged in the card */ - logged_out = (slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT); + logged_out = (slot_get_logged_in_state(slot) & SC_PIN_STATE_LOGGED_OUT); if (slot->login_user == CKU_SO && !logged_out) { pInfo->state = CKS_RW_SO_FUNCTIONS; } else if ((slot->login_user == CKU_USER && !logged_out) || !(slot->token_info.flags & CKF_LOGIN_REQUIRED)) { diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index d05ad5cace..236ade1b12 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1212,16 +1212,20 @@ static int do_pininfo(int argc, char **argv) fprintf(stderr, "Unable to get PIN info: %s\n", sc_strerror(r)); return -1; } - switch (data.pin1.logged_in) { - case SC_PIN_STATE_LOGGED_IN: - printf("Logged in.\n"); - break; - case SC_PIN_STATE_LOGGED_OUT: - printf("Logged out.\n"); - break; - case SC_PIN_STATE_UNKNOWN: - default: - printf("Login status unknown.\n"); + printf("State:\n\t"); + if (data.pin1.logged_in == SC_PIN_STATE_UNKNOWN) { + printf("Login status unknown."); + } else { + if (data.pin1.logged_in & SC_PIN_STATE_LOGGED_IN) { + printf("Logged in "); + } + if (data.pin1.logged_in & SC_PIN_STATE_LOGGED_OUT) { + printf("Logged out "); + } + if (data.pin1.logged_in & SC_PIN_STATE_NEEDS_CHANGE) { + printf("Needs change "); + } + printf("\n"); } if (tries_left >= 0) printf("%d tries left.\n", tries_left); From 3983c64afbbc44534aae2ebe9eb3fba430519697 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Feb 2026 16:09:53 +0100 Subject: [PATCH 4116/4321] opensc.h: Fix typo in comment --- src/libopensc/opensc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 2b639587bb..73c2700c27 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -403,7 +403,7 @@ typedef struct sc_reader { unsigned long flags, capabilities; unsigned int supported_protocols, active_protocol; size_t max_send_size; /* Max Lc supported by the reader layer */ - size_t max_recv_size; /* Mac Le supported by the reader layer */ + size_t max_recv_size; /* Max Le supported by the reader layer */ struct sc_atr atr; struct sc_uid uid; From b3cd8feec736e2d6fd13ae7c2f2177c4d2308fdc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Feb 2026 16:11:03 +0100 Subject: [PATCH 4117/4321] sc-hsm: Add max APDU sizes for 4.* versions from #3567 --- src/libopensc/card-sc-hsm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index d2e5bc6fd8..8190d2b197 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1824,6 +1824,7 @@ static int sc_hsm_init(struct sc_card *card) // JCOP 2.4.1r3 1462 // JCOP 2.4.2r3 1454 // JCOP 3 1232 + // JCOP 4 1454 // MicroSD with JCOP 3 478 / 506 - handled in reader-pcsc.c // Reiner SCT 1014 - handled in reader-pcsc.c From d6a10b7132054dfabaf038307bb458644bfb43c5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Feb 2026 17:03:21 +0100 Subject: [PATCH 4118/4321] sc-hsm: Adjust size limits to reflect APDU overhead --- src/libopensc/card-sc-hsm.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 8190d2b197..528c61cfd9 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1820,16 +1820,23 @@ static int sc_hsm_init(struct sc_card *card) card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO; - // APDU Buffer limits + // APDU Size limits // JCOP 2.4.1r3 1462 // JCOP 2.4.2r3 1454 // JCOP 3 1232 // JCOP 4 1454 // MicroSD with JCOP 3 478 / 506 - handled in reader-pcsc.c // Reiner SCT 1014 - handled in reader-pcsc.c - - // Use JCOP 3 card limits for sending - card->max_send_size = 1232; + // + // Note, that these are limits for the whole APDU, but the semantics of max_send_size + // is the size of the APDU send buffer so to get the right value from them, we need + // to subtract APDU headers (CLA, INS, P1, P2, Lc (3B)), 7 bytes altogether for + // class 3 APDU + // (or 9 bytes for case 4 when we pass in >255 B data and expect return of more than 255 B) + + // Use JCOP 3 (smallest unhandled by reader limitation) card limits for sending + // And make it 9 smaller to make sure we fit the rest of the APDU. + card->max_send_size = 1232 - 9; // Assume that card supports sending with extended length APDU and without limit card->max_recv_size = 0; From c7b3d41676e0ba8104775a785bc6eba366002877 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 1 Dec 2025 15:36:34 +0100 Subject: [PATCH 4119/4321] OpenSC 0.27.0 --- .appveyor.yml | 2 +- NEWS | 59 +++++++++++++++++++++++++++++++++++++++++ VERSION.mk | 8 +++--- configure.ac | 6 ++--- src/tools/pkcs11-tool.c | 4 +-- 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0c5ba37520..89e31ee4c0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.26.1.{build} +version: 0.27.0.{build} platform: - x86 diff --git a/NEWS b/NEWS index b014da5bc9..f0f4bb86fd 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,64 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.27.0; 2026-02-XX + +## Security +* Several uses of potentially uninitialized memory detected by fuzzers + +## General improvements +* Added support for PKCS#11 3.2 in tools and pkcs11-spy and p11test(#3510) +* Added support for Ed448, X448 mechanisms and improve support for + Edwards and montgomery keys in general (#3090) +* Support CKA_PUBKEY_KEY_INFO PKCS#11 attribute (#3090) +* Various refactoring of autotools build system +* Remove obsolete tokend support (#3285) +* Run tests against different software PKCS#11 tokens kryoptic and NSS softokn (#3365) +* Removed internal caching for current EF/DF (#3403) +* Correctly detect OS-level FIPS mode in OpenSSL automatically (#3551) + or through custom configuration file (#3525) + +## PC/SC +* Handle case when smart card is removed and inserted between two subsequent calls to + `refresh_attributes()` (#2803) + +## EsteID +* Add support for EstEID 2025 (#3392) +* Implement FinEID 4.0/4.1 support (#3505) +* Add Latvian IDEMIA Cosmo X card support (#3503) +* Check if PIN is locked and hint CKF_USER_PIN_TO_BE_CHANGED (#3490) +* Remove obsolete FinEID cards (#3522) +* Add Latvian Cosmo 8.2 card support (#3521) + +## D-Trust +* Prevent unncecessary pin prompts on pinpad readers (#3266) +* Support for D-Trust Card 5.1 & 5.4 (#3137) +* Implement PIN change and unblock in dtrust-tool (#3137) + +## Belpic +* Add supports for belpic applet version 1.8 (#3308) + +## OpenPGP +* Implement key derived PIN format (KDF-DO) as per OpenPGP card spec v3.3 (#3398) + +## IDPrime +* Implement 5110+ FIPS and 5110 CC (940) derive support (#3483) + +## Windows +* Update to Wix 6 (#3435) +* Fix C_WaitForSlotEvent() not working in Windows (#2919) +* remove pkcs11-register from autostart (#3354) + +## MacOS +* Installer images are now notarized (#3536) + +## pkcs11-tool +* Added support for ML-DSA, ML-KEM, SLH-DSA keys from PKCS#11 3.2 (#3510) +* Improve support for Edwards and montgomery keys and + add derive key support for CKK_MONTGOMERY (#3090) +* Add support for ChaCha20 and Poly1305 (#3339) +* Add support for AES CTR in decrypt_data() and encrypt_data() (#3338) +* Add initial support for PKCS#11 URIs (#3289) + # New in 0.26.1; 2025-01-14 ## General improvements diff --git a/VERSION.mk b/VERSION.mk index ab56d02199..4eaf6f5b8c 100644 --- a/VERSION.mk +++ b/VERSION.mk @@ -3,10 +3,10 @@ PRODUCT_TARNAME=opensc PRODUCT_BUGREPORT=https://github.com/OpenSC/OpenSC/issues PRODUCT_URL=https://github.com/OpenSC/OpenSC PACKAGE_VERSION_MAJOR=0 -PACKAGE_VERSION_MINOR=26 -PACKAGE_VERSION_FIX=1 +PACKAGE_VERSION_MINOR=27 +PACKAGE_VERSION_FIX=0 PACKAGE_VERSION_REVISION=0 -PACKAGE_SUFFIX= +PACKAGE_SUFFIX=rc1 PACKAGE_SCM_REVISION=No Git revision info available VS_FF_LEGAL_COPYRIGHT=OpenSC Project @@ -14,4 +14,4 @@ VS_FF_LEGAL_COMPANY_NAME=OpenSC Project VS_FF_LEGAL_COMPANY_URL=https://github.com/OpenSC VS_FF_COMMENTS=Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+). VS_FF_PRODUCT_NAME=OpenSC smartcard framework -VS_FF_PRODUCT_UPDATES=https://github.com/OpenSC/OpenSC/releases \ No newline at end of file +VS_FF_PRODUCT_UPDATES=https://github.com/OpenSC/OpenSC/releases diff --git a/configure.ac b/configure.ac index 20ed6b22a8..7428cea5c5 100644 --- a/configure.ac +++ b/configure.ac @@ -39,9 +39,9 @@ OPENSC_VS_FF_PRODUCT_UPDATES="VS_FF_PRODUCT_UPDATES" # (Code changed: REVISION++) # (Oldest interface changed/removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) -OPENSC_LT_CURRENT="12" -OPENSC_LT_OLDEST="12" -OPENSC_LT_REVISION="2" +OPENSC_LT_CURRENT="13" +OPENSC_LT_OLDEST="13" +OPENSC_LT_REVISION="0" OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libopensc/sc.c]) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9cdd4fbe56..c73a1c89e2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -8890,7 +8890,7 @@ static int test_verify(CK_SESSION_HANDLE sess) return errors; } -#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 26 +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 27 #else #ifdef ENABLE_OPENSSL static int wrap_unwrap(CK_SESSION_HANDLE session, @@ -9014,7 +9014,7 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, */ static int test_unwrap(CK_SESSION_HANDLE sess) { -#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 26 +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 27 /* temporarily disable test, see https://github.com/OpenSC/OpenSC/issues/1796 */ return 0; #else From 67278266ec6b69b47a64685dd52936ae96b84b03 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 24 Feb 2026 17:41:27 +0100 Subject: [PATCH 4120/4321] macos: Include package suffix in package version Fixes: #3581 --- MacOSX/build | 2 +- MacOSX/notarize | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build b/MacOSX/build index 2e1428972c..7507d160f6 100755 --- a/MacOSX/build +++ b/MacOSX/build @@ -22,7 +22,7 @@ while IFS='=' read -r key value; do done < $BUILDPATH/VERSION.mk # keep in sync with MacOSX/notarize -export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX} +export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX}${PACKAGE_SUFFIX} PREFIX=/Library/OpenSC export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig diff --git a/MacOSX/notarize b/MacOSX/notarize index e5a6ebfd02..42c9e20f27 100755 --- a/MacOSX/notarize +++ b/MacOSX/notarize @@ -15,7 +15,7 @@ while IFS='=' read -r key value; do done < $BUILDPATH/VERSION.mk # keep in sync with MacOSX/build -export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX} +export PACKAGE_VERSION=${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX}${PACKAGE_SUFFIX} if test -n "${NOTARIZATION_PASSWORD}" -a -n "${DEVELOPMENT_TEAM}"; then xcrun notarytool submit --team-id ${DEVELOPMENT_TEAM} --apple-id ${APPLE_ID} --password ${NOTARIZATION_PASSWORD} --wait OpenSC-${PACKAGE_VERSION}.dmg From 306a4251386adfea38ade2af9972b86ea9b46087 Mon Sep 17 00:00:00 2001 From: Jozsef Dojcsak Date: Wed, 18 Feb 2026 15:35:25 +0100 Subject: [PATCH 4121/4321] Add Windows Build Option hint to disable asserts --- win32/Make.rules.mak | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index dd2871cdb4..d645ae857e 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -36,6 +36,8 @@ SM_DEF = /DENABLE_SM #Build with debugging support #DEBUG_DEF = /DDEBUG +#Release build, disable asserts +#DEBUG_DEF = /DNDEBUG !IF "$(BUILD_TYPE)" == "" !IF "$(DEBUG_DEF)" == "/DDEBUG" From 3b2919b8fb6d11b22ace53ae2e926caecef6a8ea Mon Sep 17 00:00:00 2001 From: Loic d'Anterroches Date: Sun, 1 Mar 2026 10:56:25 +0100 Subject: [PATCH 4122/4321] libopensc: guard NULL tries_left in dtrust PIN info sc_pkcs15_get_pin_info() passes tries_left == NULL to sc_pin_cmd(). In dtrust_pin_cmd_get_info(), the CAN branch dereferenced tries_left unconditionally, which caused a SIGSEGV during pkcs11-tool -L token enumeration. Guard the write with a NULL check. Fixes #3586 --- src/libopensc/card-dtrust.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index f3817200d1..0eca4447f3 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -609,7 +609,9 @@ dtrust_pin_cmd_get_info(struct sc_card *card, switch (data->pin_reference) { case PACE_PIN_ID_CAN: /* unlimited number of retries */ - *tries_left = -1; + if (tries_left != NULL) { + *tries_left = -1; + } data->pin1.max_tries = -1; data->pin1.tries_left = -1; r = SC_SUCCESS; From c8b09077e0a6377ebfdac93a4b8da24a45699d3f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 25 Feb 2026 11:12:22 +0200 Subject: [PATCH 4123/4321] Normalize windows package name and strip version number from git tag Signed-off-by: Raul Metsma --- .github/build.sh | 4 +++- .github/workflows/windows.yml | 26 ++++++++++++++++---------- .gitignore | 2 +- bootstrap.ci | 4 ++-- configure.ac | 2 -- m4/version.m4 | 5 ----- win32/Make.rules.mak | 2 +- 7 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 m4/version.m4 diff --git a/.github/build.sh b/.github/build.sh index 08d3fab51f..7c1dcf26bf 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -17,7 +17,9 @@ if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then fi else BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$BRANCH" != "master" ]; then + if [ "$GITHUB_REF_TYPE" == "tag" ] && [[ "$BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + SUFFIX="${BASH_REMATCH[1]}" + elif [ "$BRANCH" != "master" ]; then SUFFIX="$BRANCH" fi fi diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8f7df319ab..37caaf6d69 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -38,19 +38,25 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - - name: Package name + - name: Package suffix shell: bash run: | - if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "master" ]]; then - SUFFIX="" - elif [[ "${{ github.event_name }}" == "push" ]]; then - SUFFIX="-${{ github.ref_name }}" - elif [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "master" ]]; then - SUFFIX="-pr${{ github.event.number }}" - else - SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" + if [[ "${{ github.event_name }}" == "push" ]]; then + if [[ "${{ github.ref_type }}" == "tag" && "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + SUFFIX="${BASH_REMATCH[1]}" + elif [[ "${{ github.ref_name }}" != "master" ]]; then + SUFFIX="-${{ github.ref_name }}" + fi + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + if [[ "${{ github.base_ref }}" == "master" ]]; then + SUFFIX="-pr${{ github.event.number }}" + else + SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" + fi fi - echo "DIST_SUFFIX=${{ matrix.configuration == 'Light' && '-Light' || '' }}${SUFFIX}" >> $GITHUB_ENV + PACKAGE_SUFFIX="${{ matrix.configuration == 'Light' && '-Light' || '' }}${SUFFIX}" + sed -i.bak "s/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX=$PACKAGE_SUFFIX/g" VERSION.mk + cat VERSION.mk - name: Install CPDK run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Setup dev env diff --git a/.gitignore b/.gitignore index 46b0c19b71..1843f0564f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ ChangeLog .cache compile_commands.json .dirstamp +VERSION.mk.bak doc/tools/*-tool doc/tools/eidenv @@ -150,7 +151,6 @@ src/tests/fuzzing/fuzz_pkcs15_tool src/tests/fuzzing/fuzz_pkcs15init src/tests/fuzzing/fuzz_scconf_parse_string -version.m4.ci openssl_arm64 openssl_bin openpace_bin diff --git a/bootstrap.ci b/bootstrap.ci index 6a3a27792f..fb7e0692b7 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -41,12 +41,12 @@ if [ -f Makefile ]; then make distclean fi -rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmain.sh m4/version.m4.ci +rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmain.sh VERSION.mk.bak if [ -n "$SUFFIX" ] then echo Set package suffix "$SUFFIX" - sed 's/^define(\[PACKAGE_SUFFIX\],\s*\[\([-~]*[0-9a-zA-Z]*\)\])$/define(\[PACKAGE_SUFFIX\], \['$SUFFIX'\])/g' < m4/version.m4 > m4/version.m4.ci + sed -i.bak 's/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX='$SUFFIX'/g' VERSION.mk fi ./bootstrap diff --git a/configure.ac b/configure.ac index 7428cea5c5..85b761ab14 100644 --- a/configure.ac +++ b/configure.ac @@ -13,8 +13,6 @@ m4_esyscmd([awk -F= ' } ' "VERSION.mk"]) -m4_sinclude(m4/version.m4.ci) - # Hint: MacOSX/build contains minimum OpenSSL reference m4_define([openssl_minimum_version], [1.1.1]) diff --git a/m4/version.m4 b/m4/version.m4 deleted file mode 100644 index f493f837ce..0000000000 --- a/m4/version.m4 +++ /dev/null @@ -1,5 +0,0 @@ -dnl version.m4 - source for version.m4.ci generated by bootstrap.ci -dnl * bootstrap.ci generates version.m4.ci based on this file -dnl * if version.m4.ci exists, it is included in configure.ac -define([PACKAGE_SUFFIX], []) - diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index d645ae857e..a9a1041cba 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -18,7 +18,7 @@ MINIDRIVER_DEF = /DENABLE_MINIDRIVER WIXFLAGS = -d ENABLE_MINIDRIVER $(WIXFLAGS) #Build MSI with the Windows Installer XML (WIX) toolkit -MSI_NAME = $(PRODUCT_NAME)-$(PACKAGE_VERSION_MAJOR).$(PACKAGE_VERSION_MINOR).$(PACKAGE_VERSION_FIX)_$(PLATFORM)$(DIST_SUFFIX).msi +MSI_NAME = $(PRODUCT_NAME)-$(PACKAGE_VERSION_MAJOR).$(PACKAGE_VERSION_MINOR).$(PACKAGE_VERSION_FIX)$(PACKAGE_SUFFIX)_$(PLATFORM).msi !IF "$(WIX_PACKAGES)" == "" WIX_PACKAGES = $(TOPDIR)\win32\packages WIX_VERSION = 6.0.2 From 033f594cca12efdc33eb23d4ee4181f98fa5a2ac Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 10 Mar 2026 17:07:17 +0100 Subject: [PATCH 4124/4321] fixed typo --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 4980e97359..0ab154ed75 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1609,7 +1609,7 @@ _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data) /* Ignore 'private' object */ if (obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) { /* If we found some non-accessible public object, - * we can no longer claim Public Ceritificate Token conformance */ + * we can no longer claim Public Certificate Token conformance */ if ((obj->p15_object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PUBKEY || (obj->p15_object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT) { public_certificates = 0; From a46d33ab17cb1f17b158652191e6ac90b54d70bd Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Fri, 6 Mar 2026 12:01:56 +0200 Subject: [PATCH 4125/4321] Rename Windows artifacts Signed-off-by: Raul Metsma Co-authored-by: Jakub Jelen --- .github/workflows/windows.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 37caaf6d69..ae89863260 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -57,6 +57,12 @@ jobs: PACKAGE_SUFFIX="${{ matrix.configuration == 'Light' && '-Light' || '' }}${SUFFIX}" sed -i.bak "s/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX=$PACKAGE_SUFFIX/g" VERSION.mk cat VERSION.mk + while IFS='=' read -r key value; do + # Skip empty or comment lines + [[ -z "$key" || "$key" =~ ^# ]] && continue + export "$key=$value" + done < VERSION.mk + echo "ARTIFACT_NAME=${PRODUCT_NAME}-${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX}${PACKAGE_SUFFIX}_${{ matrix.platform }}" >> $GITHUB_ENV - name: Install CPDK run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Setup dev env @@ -124,7 +130,7 @@ jobs: id: upload-unsigned-artifact uses: actions/upload-artifact@v6 with: - name: msi_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} + name: ${{ env.ARTIFACT_NAME }}.zip path: ./win32/*.msi - name: Push to Signpath.io if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} @@ -139,7 +145,7 @@ jobs: - name: Archive debug artifacts uses: actions/upload-artifact@v6 with: - name: debug_${{ matrix.image }}_${{ matrix.platform }}_${{ matrix.configuration }} + name: ${{ env.ARTIFACT_NAME }}-dbg.zip path: | ./src/**/*.pdb ./win32/*.pdb From 1df21be0fb8f3e23bee113f913046f9384ac5a7f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Mar 2026 16:15:00 +0100 Subject: [PATCH 4126/4321] OpenSC 0.27.0-rc2 --- NEWS | 2 +- VERSION.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index f0f4bb86fd..27062c4f7a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.27.0; 2026-02-XX +# New in 0.27.0; 2026-03-XX ## Security * Several uses of potentially uninitialized memory detected by fuzzers diff --git a/VERSION.mk b/VERSION.mk index 4eaf6f5b8c..1a11ea72c2 100644 --- a/VERSION.mk +++ b/VERSION.mk @@ -6,7 +6,7 @@ PACKAGE_VERSION_MAJOR=0 PACKAGE_VERSION_MINOR=27 PACKAGE_VERSION_FIX=0 PACKAGE_VERSION_REVISION=0 -PACKAGE_SUFFIX=rc1 +PACKAGE_SUFFIX=-rc2 PACKAGE_SCM_REVISION=No Git revision info available VS_FF_LEGAL_COPYRIGHT=OpenSC Project From 02b14f246b4db6327ef1329ba049cce731293c0f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 17 Mar 2026 16:24:30 +0100 Subject: [PATCH 4127/4321] README: Fix artifact names in release --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d222721486..299b0c081a 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ The [OpenSC Wiki](https://github.com/OpenSC/OpenSC/wiki) includes, among others, The [latest stable version of OpenSC](https://github.com/OpenSC/OpenSC/releases/latest) is available on Github. It is available as - * Windows installer for 64 bit and 32 bit programs (`OpenSC*_win64.msi` and `OpenSC*_win32.msi`) + * Windows installer for Intel 64 bit and 32 bit programs (`OpenSC*_x64.msi` and `OpenSC*_x86.msi`) and Arm + (`OpenSC*_arm64.msi`) * macOS installer (`OpenSC*.dmg`) * Source code distribution (`opensc*.tar.gz`) From 937f183224f2e0eb1d40537217084e2f41058b3e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 17 Mar 2026 16:24:46 +0100 Subject: [PATCH 4128/4321] README: Add Windows build status badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 299b0c081a..6bec2ec177 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Nightly builds are available by their git hash in branches of [OpenSC/Nightly](h # Build and testing status [![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) +[![Windows build](https://github.com/OpenSC/OpenSC/actions/workflows/windows.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/windows.yml) [![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/frankmorgner/opensc/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) From 34d750abc84dda3ee1f8c76144f080927edd38e0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 12 Mar 2026 16:37:23 +0100 Subject: [PATCH 4129/4321] ci: Remove broken packit and build RPMs from scratch --- .github/actions/packit/Dockerfile | 5 --- .github/actions/packit/action.yml | 5 --- .github/workflows/packit.yaml | 42 ------------------- .github/workflows/rpmbuild.yaml | 67 +++++++++++++++++++++++++++++++ packaging/opensc.spec | 20 +++++---- 5 files changed, 79 insertions(+), 60 deletions(-) delete mode 100644 .github/actions/packit/Dockerfile delete mode 100644 .github/actions/packit/action.yml delete mode 100644 .github/workflows/packit.yaml create mode 100644 .github/workflows/rpmbuild.yaml diff --git a/.github/actions/packit/Dockerfile b/.github/actions/packit/Dockerfile deleted file mode 100644 index 540526545e..0000000000 --- a/.github/actions/packit/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM quay.io/packit/packit - -RUN git config --system --add safe.directory /github/workspace - -ENTRYPOINT ["./.github/test-packit.sh"] diff --git a/.github/actions/packit/action.yml b/.github/actions/packit/action.yml deleted file mode 100644 index a07eb40133..0000000000 --- a/.github/actions/packit/action.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: Packit RPM build -description: Action that provides Packit RPM build -runs: - using: "docker" - image: "Dockerfile" diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml deleted file mode 100644 index 95676a693f..0000000000 --- a/.github/workflows/packit.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: Packit -on: - pull_request: - paths: - - '**.c' - - '**.h' - - '**.am' - - '**.sh' - - .github/workflows/packit.yaml - - packaging/opensc.spec - - configure.ac - push: - -jobs: - packit_srpm: - runs-on: ubuntu-latest - name: Packit SRPM - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: packit/actions/srpm@main - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: opensc-srpm - path: - opensc*.src.rpm - packit_rpm: - runs-on: ubuntu-latest - name: Packit RPM - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: ./.github/actions/packit - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: opensc-rpm - path: - x86_64/opensc*.rpm diff --git a/.github/workflows/rpmbuild.yaml b/.github/workflows/rpmbuild.yaml new file mode 100644 index 0000000000..74d59bf233 --- /dev/null +++ b/.github/workflows/rpmbuild.yaml @@ -0,0 +1,67 @@ +name: RPM Build +on: + pull_request: + paths: + - '**.c' + - '**.h' + - '**.am' + - '**.sh' + - .github/workflows/rpmbuild.yaml + - packaging/opensc.spec + - configure.ac + push: + +jobs: + rpmbuild: + name: Release tarball and run RPM Build + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + name: [fedora, centos10] + include: + - name: fedora + container: quay.io/fedora/fedora:rawhide + - name: centos10 + container: quay.io/centos/centos:stream10 + container: ${{ matrix.container }} + steps: + - name: Get Date for DNF cache entry + id: get-date + run: | + echo "date=$(/bin/date -u "+%Y%V")" >> $GITHUB_OUTPUT + shell: bash + + - name: Cache DNF packages (separate from the main job -- different dependencies) + uses: actions/cache@v4 + with: + path: | + /var/cache/libdnf5 + /var/cache/dnf + key: ${{ runner.os }}-${{ matrix.container }}-dnf-${{ steps.get-date.outputs.date }} + + - name: Install git to have sensible checkout + run: | + dnf -y install git rpm-build + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Install Dependencies + run: | + if [ "${{ matrix.name }}" = "centos10" ]; then + dnf install -y 'dnf-command(config-manager)' + dnf config-manager --set-enabled crb + fi + dnf -y builddep packaging/opensc.spec + + - name: RPM Build + run: | + git config --global --add safe.directory /__w/opensc/opensc + ./bootstrap + ./configure + make dist + mkdir -p rpmbuild/SOURCES + cp opensc-*.tar.gz src/pkcs11/opensc.module rpmbuild/SOURCES/ + rpmbuild --define "_topdir $PWD/rpmbuild" -ba packaging/opensc.spec diff --git a/packaging/opensc.spec b/packaging/opensc.spec index e886581ee0..b938f32696 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -1,11 +1,12 @@ Name: opensc -Version: 0.1.0 -Release: 1%{?dist} +Version: 0.27.0 +Release: %autorelease Summary: Smart card library and applications License: LGPL-2.1-or-later AND BSD-3-Clause URL: https://github.com/OpenSC/OpenSC/wiki -Source0: opensc-0.1.0.tar.gz +Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}-rc2.tar.gz +Source1: opensc.module BuildRequires: make BuildRequires: pcsc-lite-devel @@ -14,7 +15,7 @@ BuildRequires: openssl-devel BuildRequires: /usr/bin/xsltproc BuildRequires: docbook-style-xsl BuildRequires: autoconf automake libtool gcc -%if 0%{?fedora} > 40 || 0%{?rhel} > 10 +%if 0%{?fedora} || 0%{?rhel} > 10 BuildRequires: bash-completion-devel %else BuildRequires: bash-completion @@ -25,10 +26,10 @@ BuildRequires: p11-kit-devel BuildRequires: libcmocka-devel BuildRequires: vim-common %if ! 0%{?rhel} -BuildRequires: softhsm -BuildRequires: openssl BuildRequires: openpace-devel %endif +BuildRequires: softhsm +BuildRequires: openssl Requires: %{name}-libs = %{version}-%{release} Requires: pcsc-lite-libs%{?_isa} Requires: pcsc-lite @@ -56,9 +57,8 @@ OpenSC libraries. %prep -%setup -q +%setup -q -n opensc-%{version}-rc2 -# The test-pkcs11-tool-allowed-mechanisms already works in Fedora XFAIL_TESTS="test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh" # In FIPS mode, OpenSSL doesn't allow RSA-PKCS, this is hardcoded into OpenSSL @@ -102,6 +102,7 @@ make check || (cat tests/*.log src/tests/unittests/*.log && exit 1) %install %make_install +install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module %ifarch %{ix86} # To avoid multilib issues, move these files on 32b intel architectures @@ -227,3 +228,6 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %config(noreplace) %{_sysconfdir}/eac/cvc/DESCHSMCVCA00001 %config(noreplace) %{_sysconfdir}/eac/cvc/DESRCACC100001 %endif + +%changelog +%autochangelog From c2b9d672a6d263bd123fdd912c487cf6b980ef07 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 22 Mar 2026 22:22:11 +0200 Subject: [PATCH 4130/4321] Build with no-modules to include legacy provider in static build Fixes #3612 Signed-off-by: Raul Metsma --- MacOSX/build-openssl-macos.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-openssl-macos.sh b/MacOSX/build-openssl-macos.sh index 6e3b1076de..01dc5a958a 100644 --- a/MacOSX/build-openssl-macos.sh +++ b/MacOSX/build-openssl-macos.sh @@ -29,13 +29,13 @@ if ! test -e openssl; then fi pushd openssl -./Configure darwin64-x86_64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 +./Configure darwin64-x86_64 no-shared no-module no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 make clean make -j 4 make DESTDIR=$BUILDPATH/openssl_bin install_sw make clean -./Configure darwin64-arm64 no-shared no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 +./Configure darwin64-arm64 no-shared no-module no-apps --prefix=$PREFIX enable-ec_nistp_64_gcc_128 make -j 4 make DESTDIR=$BUILDPATH/openssl_arm64 install_sw From 13b849c861ffdd0d29551c547502050dc6550968 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 20 Mar 2026 06:16:16 -0500 Subject: [PATCH 4131/4321] pkcs15-sc-hsm.c Comparing Brainpool EC parameters Brainpool regular and twisted use the same prime number P. sc_pkcs15emu_sc_hsm_get_curve_oid was only comparing P to determine the OID. It now also compares A because the twisted versions use a different A called A'. The table of EC parameters used in the compare is in libopensc/pkcs15-sc-hsm.c. On branch PR-3601 Changes to be committed: modified: libopensc/pkcs15-sc-hsm.c --- src/libopensc/pkcs15-sc-hsm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index a0c6146fff..371dede19c 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -838,7 +838,11 @@ int sc_pkcs15emu_sc_hsm_get_curve_oid(sc_cvc_t *cvc, const struct sc_lv_data **o int i; for (i = 0; curves[i].oid.value; i++) { - if ((curves[i].prime.len == cvc->primeOrModuluslen) && !memcmp(curves[i].prime.value, cvc->primeOrModulus, cvc->primeOrModuluslen)) { + if ((curves[i].prime.len == cvc->primeOrModuluslen) && + !memcmp(curves[i].prime.value, cvc->primeOrModulus, cvc->primeOrModuluslen) && + (curves[i].coefficientA.len == cvc->coefficientAorExponentlen) && + !memcmp(curves[i].coefficientA.value, + cvc->coefficientAorExponent, cvc->coefficientAorExponentlen)) { *oid = &curves[i].oid; return SC_SUCCESS; } From 8dd386463c4f2896be6d440e492dc07efe0168f4 Mon Sep 17 00:00:00 2001 From: Ayoub Zaki Date: Thu, 12 Mar 2026 10:28:59 +0100 Subject: [PATCH 4132/4321] Add brainpoolPxxxt1 (twisted) curve OIDs definitions Add OIDs missing definitions for the brainpool twisted curves as defined in RFC 5639 - brainpoolP192t1 (1.3.36.3.3.2.8.1.1.4) - brainpoolP224t1 (1.3.36.3.3.2.8.1.1.6) - brainpoolP256t1 (1.3.36.3.3.2.8.1.1.8) - brainpoolP320t1 (1.3.36.3.3.2.8.1.1.10) - brainpoolP384t1 (1.3.36.3.3.2.8.1.1.12) - brainpoolP512t1 (1.3.36.3.3.2.8.1.1.14) Signed-off-by: Ayoub Zaki --- src/libopensc/card-openpgp.c | 3 ++ src/libopensc/pkcs15-pubkey.c | 7 ++++ src/libopensc/pkcs15-sc-hsm.c | 60 ++++++++++++++++++++++++++++++++--- src/tools/pkcs11-tool.c | 7 ++++ 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0dde7903f5..2e99e93191 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -102,6 +102,9 @@ static pgp_ec_curves_t ec_curves_openpgp34[] = { {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 7, -1}}, 256, SC_ALGORITHM_EC}, /* brainpoolP256r1 */ {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 11, -1}}, 384, SC_ALGORITHM_EC}, /* brainpoolP384r1 */ {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 13, -1}}, 512, SC_ALGORITHM_EC}, /* brainpoolP512r1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 8, -1}}, 256, SC_ALGORITHM_EC}, /* brainpoolP256t1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 12, -1}}, 384, SC_ALGORITHM_EC}, /* brainpoolP384t1 */ + {{{1, 3, 36, 3, 3, 2, 8, 1, 1, 14, -1}}, 512, SC_ALGORITHM_EC}, /* brainpoolP512t1 */ {{{-1}}, 0, 0 } /* This entry must not be touched. */ }; diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 496ac5c5d1..e55296582e 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1519,6 +1519,13 @@ static struct ec_curve_info { {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 11}, 384, SC_ALGORITHM_EC}, {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 11}, 512, SC_ALGORITHM_EC}, + {"brainpoolP192t1", "1.3.36.3.3.2.8.1.1.4", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x04", 11}, 192, SC_ALGORITHM_EC}, + {"brainpoolP224t1", "1.3.36.3.3.2.8.1.1.6", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x06", 11}, 224, SC_ALGORITHM_EC}, + {"brainpoolP256t1", "1.3.36.3.3.2.8.1.1.8", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x08", 11}, 256, SC_ALGORITHM_EC}, + {"brainpoolP320t1", "1.3.36.3.3.2.8.1.1.10", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0A", 11}, 320, SC_ALGORITHM_EC}, + {"brainpoolP384t1", "1.3.36.3.3.2.8.1.1.12", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0C", 11}, 384, SC_ALGORITHM_EC}, + {"brainpoolP512t1", "1.3.36.3.3.2.8.1.1.14", {(u8 *)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0E", 11}, 512, SC_ALGORITHM_EC}, + {"secp192k1", "1.3.132.0.31", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x1F", 7}, 192, SC_ALGORITHM_EC}, {"secp256k1", "1.3.132.0.10", {(u8 *)"\x06\x05\x2B\x81\x04\x00\x0A", 7}, 256, SC_ALGORITHM_EC}, diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 371dede19c..51f1ec5768 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -40,8 +40,7 @@ extern struct sc_aid sc_hsm_aid; void sc_hsm_set_serialnr(sc_card_t *card, char *serial); - - +// clang-format off static struct ec_curve curves[] = { { { (unsigned char *) "\x2A\x86\x48\xCE\x3D\x03\x01\x01", 8}, // secp192r1 aka prime192r1 @@ -133,6 +132,60 @@ static struct ec_curve curves[] = { { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x70\x55\x3E\x5C\x41\x4C\xA9\x26\x19\x41\x86\x61\x19\x7F\xAC\x10\x47\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD\xB5\x87\x96\x82\x9C\xA9\x00\x69", 64}, { (unsigned char *) "\x01", 1} }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x04", 9}, // brainpoolP192t1 + { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x30\x93\xD1\x8D\xB7\x8F\xCE\x47\x6D\xE1\xA8\x62\x97", 24}, + { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x30\x93\xD1\x8D\xB7\x8F\xCE\x47\x6D\xE1\xA8\x62\x94", 24}, + { (unsigned char *) "\x13\xD5\x6F\xFA\xEC\x78\x68\x1E\x68\xF9\xDE\xB4\x3B\x35\xBE\xC2\xFB\x68\x54\x2E\x27\x89\x7B\x79", 24}, + { (unsigned char *) "\x04\x3A\xE9\xE5\x8C\x82\xF6\x3C\x30\x28\x2E\x1F\xE7\xBB\xF4\x3F\xA7\x2C\x44\x6A\xF6\xF4\x61\x81\x29\x09\x7E\x2C\x56\x67\xC2\x22\x3A\x90\x2A\xB5\xCA\x44\x9D\x00\x84\xB7\xE5\xB3\xDE\x7C\xCC\x01\xC9", 49}, + { (unsigned char *) "\xC3\x02\xF4\x1D\x93\x2A\x36\xCD\xA7\xA3\x46\x2F\x9E\x9E\x91\x6B\x5B\xE8\xF1\x02\x9A\xC4\xAC\xC1", 24}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x06", 9}, // brainpoolP224t1 + { (unsigned char *) "\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFF", 28}, + { (unsigned char *) "\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD1\xD7\x87\xB0\x9F\x07\x57\x97\xDA\x89\xF5\x7E\xC8\xC0\xFC", 28}, + { (unsigned char *) "\x4B\x33\x7D\x93\x41\x04\xCD\x7B\xEF\x27\x1B\xF6\x0C\xED\x1E\xD2\x0D\xA1\x4C\x08\xB3\xBB\x64\xF1\x8A\x60\x88\x8D", 28}, + { (unsigned char *) "\x04\x6A\xB1\xE3\x44\xCE\x25\xFF\x38\x96\x42\x4E\x7F\xFE\x14\x76\x2E\xCB\x49\xF8\x92\x8A\xC0\xC7\x60\x29\xB4\xD5\x80\x03\x74\xE9\xF5\x14\x3E\x56\x8C\xD2\x3F\x3F\x4D\x7C\x0D\x4B\x1E\x41\xC8\xCC\x0D\x1C\x6A\xBD\x5F\x1A\x46\xDB\x4C", 57}, + { (unsigned char *) "\xD7\xC1\x34\xAA\x26\x43\x66\x86\x2A\x18\x30\x25\x75\xD0\xFB\x98\xD1\x16\xBC\x4B\x6D\xDE\xBC\xA3\xA5\xA7\x93\x9F", 28}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x08", 9}, // brainpoolP256t1 + { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x72\x6E\x3B\xF6\x23\xD5\x26\x20\x28\x20\x13\x48\x1D\x1F\x6E\x53\x77", 32}, + { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x72\x6E\x3B\xF6\x23\xD5\x26\x20\x28\x20\x13\x48\x1D\x1F\x6E\x53\x74", 32}, + { (unsigned char *) "\x66\x2C\x61\xC4\x30\xD8\x4E\xA4\xFE\x66\xA7\x73\x3D\x0B\x76\xB7\xBF\x93\xEB\xC4\xAF\x2F\x49\x25\x6A\xE5\x81\x01\xFE\xE9\x2B\x04", 32}, + { (unsigned char *) "\x04\xA3\xE8\xEB\x3C\xC1\xCF\xE7\xB7\x73\x22\x13\xB2\x3A\x65\x61\x49\xAF\xA1\x42\xC4\x7A\xAF\xBC\x2B\x79\xA1\x91\x56\x2E\x13\x05\xF4\x2D\x99\x6C\x82\x34\x39\xC5\x6D\x7F\x7B\x22\xE1\x46\x44\x41\x7E\x69\xBC\xB6\xDE\x39\xD0\x27\x00\x1D\xAB\xE8\xF3\x5B\x25\xC9\xBE", 65}, + { (unsigned char *) "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC\x3E\x66\x0A\x90\x9D\x83\x8D\x71\x8C\x39\x7A\xA3\xB5\x61\xA6\xF7\x90\x1E\x0E\x82\x97\x48\x56\xA7", 32}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0A", 9}, // brainpoolP320t1 + { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA6\xF6\xF4\x0D\xEF\x4F\x92\xB9\xEC\x78\x93\xEC\x28\xFC\xD4\x12\xB1\xF1\xB3\x2E\x27", 40}, + { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA6\xF6\xF4\x0D\xEF\x4F\x92\xB9\xEC\x78\x93\xEC\x28\xFC\xD4\x12\xB1\xF1\xB3\x2E\x24", 40}, + { (unsigned char *) "\xA7\xF5\x61\xE0\x38\xEB\x1E\xD5\x60\xB3\xD1\x47\xDB\x78\x20\x13\x06\x4C\x19\xF2\x7E\xD2\x7C\x67\x80\xAA\xF7\x7F\xB8\xA5\x47\xCE\xB5\xB4\xFE\xF4\x22\x34\x03\x53", 40}, + { (unsigned char *) "\x04\x92\x5B\xE9\xFB\x01\xAF\xC6\xFB\x4D\x3E\x7D\x49\x90\x01\x0F\x81\x34\x08\xAB\x10\x6C\x4F\x09\xCB\x7E\xE0\x78\x68\xCC\x13\x6F\xFF\x33\x57\xF6\x24\xA2\x1B\xED\x52\x63\xBA\x3A\x7A\x27\x48\x3E\xBF\x66\x71\xDB\xEF\x7A\xBB\x30\xEB\xEE\x08\x4E\x58\xA0\xB0\x77\xAD\x42\xA5\xA0\x98\x9D\x1E\xE7\x1B\x1B\x9B\xC0\x45\x5F\xB0\xD2\xC3", 81}, + { (unsigned char *) "\xD3\x5E\x47\x20\x36\xBC\x4F\xB7\xE1\x3C\x78\x5E\xD2\x01\xE0\x65\xF9\x8F\xCF\xA5\xB6\x8F\x12\xA3\x2D\x48\x2E\xC7\xEE\x86\x58\xE9\x86\x91\x55\x5B\x44\xC5\x93\x11", 40}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0C", 9}, // brainpoolP384t1 + { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x53", 48}, + { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB4\x12\xB1\xDA\x19\x7F\xB7\x11\x23\xAC\xD3\xA7\x29\x90\x1D\x1A\x71\x87\x47\x00\x13\x31\x07\xEC\x50", 48}, + { (unsigned char *) "\x7F\x51\x9E\xAD\xA7\xBD\xA8\x1B\xD8\x26\xDB\xA6\x47\x91\x0F\x8C\x4B\x93\x46\xED\x8C\xCD\xC6\x4E\x4B\x1A\xBD\x11\x75\x6D\xCE\x1D\x20\x74\xAA\x26\x3B\x88\x80\x5C\xED\x70\x35\x5A\x33\xB4\x71\xEE", 48}, + { (unsigned char *) "\x04\x18\xDE\x98\xB0\x2D\xB9\xA3\x06\xF2\xAF\xCD\x72\x35\xF7\x2A\x81\x9B\x80\xAB\x12\xEB\xD6\x53\x17\x24\x76\xFE\xCD\x46\x2A\xAB\xFF\xC4\xFF\x19\x1B\x94\x6A\x5F\x54\xD8\xD0\xAA\x2F\x41\x88\x08\xCC\x25\xAB\x05\x69\x62\xD3\x06\x51\xA1\x14\xAF\xD2\x75\x5A\xD3\x36\x74\x7F\x93\x47\x5B\x7A\x1F\xCA\x3B\x88\xF2\xB6\xA2\x08\xCC\xFE\x46\x94\x08\x58\x4D\xC2\xB2\x91\x26\x75\xBF\x5B\x9E\x58\x29\x28", 97}, + { (unsigned char *) "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF\x15\x2F\x71\x09\xED\x54\x56\xB3\x1F\x16\x6E\x6C\xAC\x04\x25\xA7\xCF\x3A\xB6\xAF\x6B\x7F\xC3\x10\x3B\x88\x32\x02\xE9\x04\x65\x65", 48}, + { (unsigned char *) "\x01", 1} + }, + { + { (unsigned char *) "\x2B\x24\x03\x03\x02\x08\x01\x01\x0E", 9}, // brainpoolP512t1 + { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF3", 64}, + { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x71\x7D\x4D\x9B\x00\x9B\xC6\x68\x42\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6\x28\x81\xFF\x2F\x2D\x82\xC6\x85\x28\xAA\x60\x56\x58\x3A\x48\xF0", 64}, + { (unsigned char *) "\x7C\xBB\xBC\xF9\x44\x1C\xFA\xB7\x6E\x18\x90\xE4\x68\x84\xEA\xE3\x21\xF7\x0C\x0B\xCB\x49\x81\x52\x78\x97\x50\x4B\xEC\x3E\x36\xA6\x2B\xCD\xFA\x23\x04\x97\x65\x40\xF6\x45\x00\x85\xF2\xDA\xE1\x45\xC2\x25\x53\xB4\x65\x76\x36\x89\x18\x0E\xA2\x57\x18\x67\x42\x3E", 64}, + { (unsigned char *) "\x04\x64\x0E\xCE\x5C\x12\x78\x87\x17\xB9\xC1\xBA\x06\xCB\xC2\xA6\xFE\xBA\x85\x84\x24\x58\xC5\x6D\xDE\x9D\xB1\x75\x8D\x39\xC0\x31\x3D\x82\xBA\x51\x73\x5C\xDB\x3E\xA4\x99\xAA\x77\xA7\xD6\x94\x3A\x64\xF7\xA3\xF2\x5F\xE2\x6F\x06\xB5\x1B\xAA\x26\x96\xFA\x90\x35\xDA\x5B\x53\x4B\xD5\x95\xF5\xAF\x0F\xA2\xC8\x92\x37\x6C\x84\xAC\xE1\xBB\x4E\x30\x19\xB7\x16\x34\xC0\x11\x31\x15\x9C\xAE\x03\xCE\xE9\xD9\x93\x21\x84\xBE\xEF\x21\x6B\xD7\x1D\xF2\xDA\xDF\x86\xA6\x27\x30\x6E\xCF\xF9\x6D\xBB\x8B\xAC\xE1\x98\xB6\x1E\x00\xF8\xB3\x32", 129}, + { (unsigned char *) "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E\xD6\x63\x9C\xCA\x70\x33\x08\x70\x55\x3E\x5C\x41\x4C\xA9\x26\x19\x41\x86\x61\x19\x7F\xAC\x10\x47\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD\xB5\x87\x96\x82\x9C\xA9\x00\x69", 64}, + { (unsigned char *) "\x01", 1} + }, { { (unsigned char *) "\x2B\x81\x04\x00\x1F", 5}, // secp192k1 { (unsigned char *) "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xEE\x37", 24}, @@ -161,8 +214,7 @@ static struct ec_curve curves[] = { { NULL, 0} } }; - - +// clang-format on #define C_ASN1_CVC_PUBKEY_SIZE 10 static const struct sc_asn1_entry c_asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE] = { diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index c73a1c89e2..16b1382d34 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -148,6 +148,13 @@ static struct ec_curve_info { {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0B", 11, 384, 0}, {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0D", 11, 512, 0}, + {"brainpoolP192t1", "1.3.36.3.3.2.8.1.1.4", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x04", 11, 192, 0}, + {"brainpoolP224t1", "1.3.36.3.3.2.8.1.1.6", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x06", 11, 224, 0}, + {"brainpoolP256t1", "1.3.36.3.3.2.8.1.1.8", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x08", 11, 256, 0}, + {"brainpoolP320t1", "1.3.36.3.3.2.8.1.1.10", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0A", 11, 320, 0}, + {"brainpoolP384t1", "1.3.36.3.3.2.8.1.1.12", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0C", 11, 384, 0}, + {"brainpoolP512t1", "1.3.36.3.3.2.8.1.1.14", (unsigned char*)"\x06\x09\x2B\x24\x03\x03\x02\x08\x01\x01\x0E", 11, 512, 0}, + {"secp192k1", "1.3.132.0.31", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x1F", 7, 192, 0}, {"secp256k1", "1.3.132.0.10", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x0A", 7, 256, 0}, {"secp521k1", "1.3.132.0.35", (unsigned char*)"\x06\x05\x2B\x81\x04\x00\x23", 7, 521, 0}, From 61119f50fd0182c08db1474d1b566d0a66a8dd8a Mon Sep 17 00:00:00 2001 From: Ayoub Zaki Date: Fri, 13 Mar 2026 09:23:47 +0100 Subject: [PATCH 4133/4321] tests: add brainpoolP256r1/brainpoolP256t1 sign/verify tests We need separate reference files for different SoftHSM versions as well as for LibreSSL build, which does not support Brainpool. We also do not generate these keys in FIPS mode for obvious reasons. Signed-off-by: Ayoub Zaki Co-authored-by: Jakub Jelen --- tests/common.sh | 18 +- tests/softhsm_2.6.1_ref.json | 58 ++ tests/softhsm_2.7.0_ref.json | 106 ++ tests/softhsm_libressl_ref.json | 1351 +++++++++++++++++++++++++ tests/test-p11test.sh | 3 + tests/test-pkcs11-tool-sign-verify.sh | 47 + 6 files changed, 1582 insertions(+), 1 deletion(-) create mode 100644 tests/softhsm_libressl_ref.json diff --git a/tests/common.sh b/tests/common.sh index dd98f4c5f7..9fb39db8d5 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -97,10 +97,26 @@ function card_setup() { generate_key "SLH-DSA-SHA2-192S" "12" "SLH-DSA-SHA2-192S" || return 1 fi + # Skip in FIPS mode -- Brainpool curves are not supported + if [[ -e "/etc/system-fips" ]]; then + return + fi + if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + return + fi + if [[ -n "$LIBRESSL_VERSION" ]]; then + return + fi + + # Generate brainpoolP256r1 Key pair + generate_key "EC:brainpoolP256r1" "13" "brainpoolP256r1" || echo "WARNING: brainpoolP256r1 not supported, skipping" + # Generate brainpoolP256t1 Key pair + generate_key "EC:brainpoolP256t1" "14" "brainpoolP256t1" || echo "WARNING: brainpoolP256t1 not supported, skipping" + } function card_cleanup() { token_cleanup - rm 0{1,2,3,4}.pub + rm -f 0{1,2,3,4}.pub 1{3,4}.pub sleep 1 } diff --git a/tests/softhsm_2.6.1_ref.json b/tests/softhsm_2.6.1_ref.json index f6d39f58c5..014d42c7d8 100644 --- a/tests/softhsm_2.6.1_ref.json +++ b/tests/softhsm_2.6.1_ref.json @@ -544,6 +544,18 @@ "ECDSA", "YES", "" + ], + [ + "13", + "ECDSA", + "YES", + "" + ], + [ + "14", + "ECDSA", + "YES", + "" ]], "result": "pass" }, @@ -731,6 +743,42 @@ "", "", "" + ], + [ + "13", + "brainpoolP256r1", + "EC", + "256", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" + ], + [ + "14", + "brainpoolP256t1", + "EC", + "256", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" ]], "result": "pass" }, @@ -1323,6 +1371,16 @@ "04", "ECDH1_DERIVE", "YES" + ], + [ + "13", + "ECDH1_DERIVE", + "YES" + ], + [ + "14", + "ECDH1_DERIVE", + "YES" ]], "result": "pass" }, diff --git a/tests/softhsm_2.7.0_ref.json b/tests/softhsm_2.7.0_ref.json index e813679889..ae8ea04c7e 100644 --- a/tests/softhsm_2.7.0_ref.json +++ b/tests/softhsm_2.7.0_ref.json @@ -592,6 +592,66 @@ "ECDSA_SHA512", "YES", "" + ], + [ + "13", + "ECDSA", + "YES", + "" + ], + [ + "13", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "13", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "13", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "13", + "ECDSA_SHA512", + "YES", + "" + ], + [ + "14", + "ECDSA", + "YES", + "" + ], + [ + "14", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "14", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "14", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "14", + "ECDSA_SHA512", + "YES", + "" ]], "result": "pass" }, @@ -779,6 +839,42 @@ "", "", "" + ], + [ + "13", + "brainpoolP256r1", + "EC", + "256", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" + ], + [ + "14", + "brainpoolP256t1", + "EC", + "256", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" ]], "result": "pass" }, @@ -1371,6 +1467,16 @@ "04", "ECDH1_DERIVE", "YES" + ], + [ + "13", + "ECDH1_DERIVE", + "YES" + ], + [ + "14", + "ECDH1_DERIVE", + "YES" ]], "result": "pass" }, diff --git a/tests/softhsm_libressl_ref.json b/tests/softhsm_libressl_ref.json new file mode 100644 index 0000000000..f6d39f58c5 --- /dev/null +++ b/tests/softhsm_libressl_ref.json @@ -0,0 +1,1351 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5_HMAC", + "16", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA_1_HMAC", + "20", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224_HMAC", + "28", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_HMAC", + "32", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_HMAC", + "48", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_HMAC", + "64", + "512", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "512", + "16384", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "RSA_PKCS", + "512", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY,CKF_WRAP,CKF_UNWRAP" + ], + [ + "RSA_X_509", + "512", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY" + ], + [ + "MD5_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA1_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_OAEP", + "512", + "16384", + "CKF_ENCRYPT,CKF_DECRYPT,CKF_WRAP,CKF_UNWRAP" + ], + [ + "SHA224_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA1_RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA224_RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS_PSS", + "512", + "16384", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "GENERIC_SECRET_KEY_GEN", + "1", + "-2147483648", + "CKF_GENERATE" + ], + [ + "0x00000120", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00000130", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00000131", + "0", + "0", + "CKF_GENERATE" + ], + [ + "0x00000121", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00000122", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00000125", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00001100", + "0", + "0", + "CKF_DERIVE" + ], + [ + "0x00001101", + "0", + "0", + "CKF_DERIVE" + ], + [ + "DES3_ECB", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "DES3_CBC", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "DES3_CBC_PAD", + "0", + "0", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "0x00001102", + "0", + "0", + "CKF_DERIVE" + ], + [ + "DES3_CBC_ENCRYPT_DATA", + "0", + "0", + "CKF_DERIVE" + ], + [ + "DES3_CMAC", + "0", + "0", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "AES_KEY_GEN", + "16", + "32", + "CKF_GENERATE" + ], + [ + "AES_ECB", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CBC", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CBC_PAD", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_CTR", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_GCM", + "16", + "32", + "CKF_ENCRYPT,CKF_DECRYPT" + ], + [ + "AES_KEY_WRAP", + "16", + "-2147483648", + "CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_KEY_WRAP_PAD", + "1", + "-2147483648", + "CKF_WRAP,CKF_UNWRAP" + ], + [ + "AES_ECB_ENCRYPT_DATA", + "0", + "0", + "CKF_DERIVE" + ], + [ + "AES_CBC_ENCRYPT_DATA", + "0", + "0", + "CKF_DERIVE" + ], + [ + "AES_CMAC", + "16", + "32", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00002000", + "512", + "1024", + "CKF_GENERATE" + ], + [ + "0x00000010", + "512", + "1024", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x00000011", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000012", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000013", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000014", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000015", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000016", + "512", + "1024", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "0x00000020", + "512", + "10000", + "CKF_GENERATE_KEY_PAIR" + ], + [ + "0x00002001", + "512", + "10000", + "CKF_GENERATE" + ], + [ + "0x00000021", + "512", + "10000", + "CKF_DERIVE" + ], + [ + "EC_KEY_PAIR_GEN", + "112", + "521", + "CKF_GENERATE_KEY_PAIR,CKF_EC_F_P,CKF_EC_NAMEDCURVE,CKF_EC_UNCOMPRESS" + ], + [ + "ECDSA", + "112", + "521", + "CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_NAMEDCURVE,CKF_EC_UNCOMPRESS" + ], + [ + "ECDH1_DERIVE", + "112", + "521", + "CKF_DERIVE" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "01", + "RSA_X_509", + "YES", + "YES" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "02", + "RSA_X_509", + "YES", + "YES" + ], + [ + "02", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "03", + "ECDSA", + "YES", + "" + ], + [ + "04", + "ECDSA", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "02", + "MD5_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "02", + "SHA224_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "result": "pass" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "01", + "RSA2048", + "RSA", + "2048", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "02", + "RSA4096", + "RSA", + "4096", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ], + [ + "03", + "ECC_auth", + "EC", + "256", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" + ], + [ + "04", + "ECC521", + "EC", + "521", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "YES", + "YES", + "" + ], + [ + "05", + "HMAC-SHA256", + "GEN", + "512", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "data": [ + [ + "KEY ID", + "MECHANISM", + "HASH", + "MGF", + "SALT", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_OAEP", + "SHA_1", + "MGF1_SHA_1", + "0", + "", + "YES" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-1", + "YES", + "" + ], + [ + "02", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "0", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "02", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "0", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "02", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "0", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], + [ + "02", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "0", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "02", + "SHA224_RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "0", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ], + [ + "03", + "ECDH1_DERIVE", + "YES" + ], + [ + "04", + "ECDH1_DERIVE", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" +}] +} diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index c0212d04f0..d803c80a26 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -49,6 +49,9 @@ fi if [[ -e "/etc/system-fips" ]]; then REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_fips_ref.json" fi +if [[ -n "$LIBRESSL_VERSION" ]]; then + REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_libressl_ref.json" +fi echo "Comparing with $REF_FILE" diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index e208e83388..8e604a62f0 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -247,6 +247,53 @@ for SIGN_KEY in "03" "04"; do rm data.sig{,.openssl} data.hash done +echo "=======================================================" +echo "Test brainpool ECDSA keys" +echo "=======================================================" +# operations with ECDSA keys should work on data > 512 bytes; generate data: +head -c 1024 data +for SIGN_KEY in "13" "14"; do + # Skip brainpool tests in FIPS mode -- brainpool curves are not FIPS approved + if [[ -e "/etc/system-fips" ]]; then + continue; + fi + if [[ -f "/proc/sys/crypto/fips_enabled" && $(cat /proc/sys/crypto/fips_enabled) == "1" ]]; then + continue; + fi + # Skip if the key was not generated (token does not support this curve) + if [[ ! -f $SIGN_KEY.pub ]]; then + echo "Skipping brainpool key $SIGN_KEY: not supported by $TOKENTYPE" + continue + fi + METHOD="ECDSA" + + echo + echo "=======================================================" + echo "$METHOD: Sign & Verify (KEY $SIGN_KEY)" + echo "=======================================================" + openssl dgst -binary -sha256 data > data.hash + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD \ + --input-file data.hash --output-file data.sig + assert $? "Failed to Sign data" + $PKCS11_TOOL "${PRIV_ARGS[@]}" --id $SIGN_KEY -s -m $METHOD \ + --input-file data.hash --output-file data.sig.openssl \ + --signature-format openssl + assert $? "Failed to Sign data into OpenSSL format" + + # OpenSSL verification + echo -n "Verification by OpenSSL: " + openssl dgst -keyform PEM -verify $SIGN_KEY.pub -sha256 \ + -signature data.sig.openssl data + assert $? "Failed to Verify signature using OpenSSL" + + # pkcs11-tool verification + echo "Verification by pkcs11-tool:" + $PKCS11_TOOL "${PUB_ARGS[@]}" --id $SIGN_KEY --verify -m $METHOD \ + --input-file data.hash --signature-file data.sig + assert $? "Failed to Verify signature using pkcs11-tool" + rm data.sig{,.openssl} data.hash +done + echo "=======================================================" echo "Test GENERIC keys" echo "=======================================================" From 3b4f198e45d6618d3354871f2837628d92117103 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 13 Mar 2026 15:25:52 +0100 Subject: [PATCH 4134/4321] tests: Fail gracefully when reference file is not resent --- tests/test-p11test.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index d803c80a26..5bf5cf2d57 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -54,8 +54,13 @@ if [[ -n "$LIBRESSL_VERSION" ]]; then fi echo "Comparing with $REF_FILE" -diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) -assert $? "Unexpected results" +if [[ -e "$REF_FILE" ]]; then + diff -U5 <(filter_log $REF_FILE) <(filter_log $TOKENTYPE.json) + assert $? "Unexpected results" +else + echo "ERROR: Rerefence file $REF_FILE does not exist!" + exit 1 +fi echo "=======================================================" echo "Run p11test with PKCS11SPY" From 5fab888c1d0ff4873b619177c8454991f6ccae87 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 13 Mar 2026 12:27:06 +0100 Subject: [PATCH 4135/4321] ci: Fixup artifact names * Do not include the zip extension (included automatically) * Put the Light suffix only after the original suffix (-rcX) --- .github/workflows/windows.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ae89863260..d03988129f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -54,7 +54,7 @@ jobs: SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" fi fi - PACKAGE_SUFFIX="${{ matrix.configuration == 'Light' && '-Light' || '' }}${SUFFIX}" + PACKAGE_SUFFIX="${SUFFIX}${{ matrix.configuration == 'Light' && '-Light' || '' }}" sed -i.bak "s/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX=$PACKAGE_SUFFIX/g" VERSION.mk cat VERSION.mk while IFS='=' read -r key value; do @@ -130,7 +130,7 @@ jobs: id: upload-unsigned-artifact uses: actions/upload-artifact@v6 with: - name: ${{ env.ARTIFACT_NAME }}.zip + name: ${{ env.ARTIFACT_NAME }} path: ./win32/*.msi - name: Push to Signpath.io if: ${{ startsWith(github.ref, 'refs/tags/') && github.repository == 'OpenSC/OpenSC' }} @@ -145,7 +145,7 @@ jobs: - name: Archive debug artifacts uses: actions/upload-artifact@v6 with: - name: ${{ env.ARTIFACT_NAME }}-dbg.zip + name: ${{ env.ARTIFACT_NAME }}-dbg path: | ./src/**/*.pdb ./win32/*.pdb From 6c7b8af0c2e4da1962efc10786ca9f4af90cf1d6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Mar 2026 16:55:50 +0100 Subject: [PATCH 4136/4321] pkcs11-tool: Fix public ML-DSA Key import Fixes: #3618 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 16b1382d34..1d87fdb8cb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5460,7 +5460,7 @@ static CK_RV write_object(CK_SESSION_HANDLE session) n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PARAMETER_SET, &pqc_key.type, sizeof(pqc_key.type)); n_pubkey_attr++; - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, &pqc_key.public.value, pqc_key.public.len); + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, pqc_key.public.value, pqc_key.public.len); n_pubkey_attr++; } #if !defined(OPENSSL_NO_EC) From 0e92fc7478c8bab6387258baafb8b547eb85aac0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 13 Mar 2026 15:10:00 +0100 Subject: [PATCH 4137/4321] ci: Update to latest libressl 4.2.1 --- .github/setup-libressl.sh | 2 +- .github/workflows/linux.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh index fd80d7699d..8f38966ae4 100755 --- a/.github/setup-libressl.sh +++ b/.github/setup-libressl.sh @@ -3,7 +3,7 @@ set -ex -o xtrace # WARNING: Change this also in .github/workflows/linux.yml -V=libressl-4.0.0 +V=libressl-4.2.1 sudo apt-get remove -y libssl-dev diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 4abe82e2f3..1937ddc2ca 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -28,7 +28,7 @@ env: JAVA_DEPS: | ant openjdk-8-jdk maven cmake JCARDSIM: https://github.com/Jakuje/jcardsim.git - LIBRESSL_VERSION: 4.0.0 + LIBRESSL_VERSION: 4.2.1 jobs: build: From 36851e3d347ea84c8625d0e6e0b9c00142dd4aa4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Mar 2026 17:04:26 +0100 Subject: [PATCH 4138/4321] ci: Simplify kryoptic tests by using packaged version --- .github/setup-fedora.sh | 2 +- .github/setup-kryoptic.sh | 9 --------- .github/workflows/external-pkcs11.yaml | 5 ----- 3 files changed, 1 insertion(+), 15 deletions(-) delete mode 100755 .github/setup-kryoptic.sh diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index a5806ac13a..6349b1fc03 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -19,7 +19,7 @@ else fi if [ "$1" == "kryoptic" ]; then - DEPS="$DEPS clang meson cargo expect pkgconf-pkg-config openssl-devel p11-kit-devel gnutls-utils g++ sqlite-devel python3-six git" + DEPS="$DEPS kryoptic" fi sudo dnf install -y $DEPS diff --git a/.github/setup-kryoptic.sh b/.github/setup-kryoptic.sh deleted file mode 100755 index 5765b17370..0000000000 --- a/.github/setup-kryoptic.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# build kryoptic -if [ ! -d "kryoptic" ]; then - git clone https://github.com/latchset/kryoptic.git -fi -pushd kryoptic -cargo build --features dynamic,standard,nssdb,pqc -popd diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 0262599cf2..313d6fc422 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -23,7 +23,6 @@ env: libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2 - KRYOPTIC: https://github.com/latchset/kryoptic.git jobs: ####################### @@ -44,8 +43,6 @@ jobs: run: .github/setup-fedora.sh kryoptic - name: Install OpenSC run: .github/build.sh - - name: Setup Kryoptic - run: .github/setup-kryoptic.sh - name: Test with Kryoptic run: tests/test-kryoptic.sh @@ -105,7 +102,5 @@ jobs: run: .github/setup-fedora.sh kryoptic - name: Install OpenSC run: .github/build.sh - - name: Setup Kryoptic - run: .github/setup-kryoptic.sh - name: Interoperability tests run: tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh From 776e4cd2874108acc1b563be573dd96aaab58cdb Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 24 Mar 2026 16:12:22 +0200 Subject: [PATCH 4139/4321] Workaround for RTLD_DEEPBIND crashes Firefox/Chrome Fixes #3624 Signed-off-by: Raul Metsma --- src/common/libpkcs11.c | 4 ++-- src/common/libscdl.c | 11 +++++++++++ src/common/libscdl.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index 5ad0dd3e56..487f7eeab5 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -60,9 +60,9 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) free(mod); return NULL; } - mod->handle = sc_dlopen(mspec); + mod->handle = sc_dlopen_deep(mspec); if (mod->handle == NULL) { - fprintf(stderr, "sc_dlopen failed: %s\n", sc_dlerror()); + fprintf(stderr, "sc_dlopen_deep failed: %s\n", sc_dlerror()); goto failed; } diff --git a/src/common/libscdl.c b/src/common/libscdl.c index ec96a68fae..97526fb747 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -34,6 +34,11 @@ void *sc_dlopen(const char *filename) DWORD flags = PathIsRelativeA(filename) ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH; return (void *)LoadLibraryExA(filename, NULL, flags); } +void * +sc_dlopen_deep(const char *filename) +{ + return sc_dlopen(filename); +} void *sc_dlsym(void *handle, const char *symbol) { @@ -69,6 +74,12 @@ int sc_dlclose(void *handle) #include void *sc_dlopen(const char *filename) +{ + return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); +} + +void * +sc_dlopen_deep(const char *filename) { return dlopen(filename, RTLD_LAZY | RTLD_LOCAL #ifdef RTLD_DEEPBIND diff --git a/src/common/libscdl.h b/src/common/libscdl.h index b649994620..15928fadba 100644 --- a/src/common/libscdl.h +++ b/src/common/libscdl.h @@ -21,6 +21,7 @@ #ifndef __LIBSCDL_H #define __LIBSCDL_H void *sc_dlopen(const char *filename); +void *sc_dlopen_deep(const char *filename); void *sc_dlsym(void *handle, const char *symbol); int sc_dlclose(void *handle); const char *sc_dlerror(void); From 0913b1920a3850a0f51ac9acd8176f763dbf12fe Mon Sep 17 00:00:00 2001 From: George Kapetanakis Date: Mon, 23 Mar 2026 15:36:28 -0400 Subject: [PATCH 4140/4321] MacOSX/build-openssl: Fix infinite loop on missing CLI arg --- MacOSX/build-openssl-macos.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/MacOSX/build-openssl-macos.sh b/MacOSX/build-openssl-macos.sh index 01dc5a958a..dd2b63fefe 100644 --- a/MacOSX/build-openssl-macos.sh +++ b/MacOSX/build-openssl-macos.sh @@ -9,11 +9,17 @@ while [ $# -gt 0 ]; do case "$1" in -b|--buildpath) BUILDPATH="$2" - shift 2 + if ! shift 2; then + echo "Error: Missing argument for $1" >&2 + exit 1 + fi ;; -p|--prefix) PREFIX="$2" - shift 2 + if ! shift 2; then + echo "Error: Missing argument for $1" >&2 + exit 1 + fi ;; *) echo "Unknown option: $1" >&2 From cc6664d38e733b91b02af0757eee471acf39391a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Mar 2026 17:38:54 +0100 Subject: [PATCH 4141/4321] pkcs11-tool: Print more information about RSA keys Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 46 +++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1d87fdb8cb..f8559daeeb 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -788,8 +788,8 @@ VARATTR_METHOD(MODULUS, CK_BYTE); /* getMODULUS */ #ifdef ENABLE_OPENSSL VARATTR_METHOD(SUBJECT, unsigned char); /* getSUBJECT */ VARATTR_METHOD(SERIAL_NUMBER, unsigned char); /* getSERIAL_NUMBER */ -VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ #endif +VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ VARATTR_METHOD(GOSTR3410_PARAMS, unsigned char); /* getGOSTR3410_PARAMS */ VARATTR_METHOD(GOSTR3411_PARAMS, unsigned char); /* getGOSTR3411_PARAMS */ @@ -6507,11 +6507,45 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) /* uninitialized secret key (type 0) */ printf("\n"); } else { - if (pub) - printf("; RSA %lu bits\n", - (unsigned long) getMODULUS_BITS(sess, obj)); - else - printf("; RSA \n"); + unsigned char *modulus = NULL, *public_exponent = NULL; + CK_ULONG modulus_len, public_exponent_len; + unsigned long modulus_bits = 0; + + printf("; RSA "); + modulus = getMODULUS(sess, obj, &modulus_len); + + if (pub && (modulus_bits = getMODULUS_BITS(sess, obj)) != 0) { + printf(" %lu bits", modulus_bits); + } else if (modulus != NULL) { + /* estimate, for private key or missing*/ + printf(" %lu bits", modulus_len * 8); + } + printf("\n"); + if (modulus) { + unsigned int n; + + printf(" MODULUS: "); + for (n = 0; n < modulus_len; n++) { + if (n && (n % 32) == 0) + printf("\n "); + printf("%02x", modulus[n]); + } + printf("\n"); + free(modulus); + } + public_exponent = getPUBLIC_EXPONENT(sess, obj, &public_exponent_len); + if (public_exponent) { + unsigned int n; + + printf(" PUBLIC_EXPONENT: "); + for (n = 0; n < public_exponent_len; n++) { + if (n && (n % 32) == 0) + printf("\n "); + printf("%02x", public_exponent[n]); + } + printf("\n"); + free(public_exponent); + } } break; case CKK_GOSTR3410: From 5f2cfaf5878a062a6fdf919e7c5bcf4170dfc2f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Mar 2026 19:09:47 +0100 Subject: [PATCH 4142/4321] pkcs11-tool: Common function to print hexadecimal strings Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 114 ++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f8559daeeb..edea436aa5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -6467,6 +6468,23 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) } } +#define BYTES_PER_LINE 32 +void +print_hex(const u8 *bin_input, size_t input_size, int separator, bool newline) +{ + char out[BYTES_PER_LINE * 3] = {0}; + size_t out_len = BYTES_PER_LINE * 3; + unsigned int n; + + for (n = 0; n < input_size; n += BYTES_PER_LINE) { + size_t chunk_len = MIN(input_size - n, BYTES_PER_LINE); + const char *indent = n + chunk_len < input_size + ? "\n " /* continuation of block */ + : (newline ? "\n" : ""); /* end of the block */ + sc_bin_to_hex(bin_input + n, chunk_len, out, out_len, separator); + printf("%s%s", out, indent); + } +} static void show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) @@ -6522,28 +6540,14 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } printf("\n"); if (modulus) { - unsigned int n; - - printf(" MODULUS: "); - for (n = 0; n < modulus_len; n++) { - if (n && (n % 32) == 0) - printf("\n "); - printf("%02x", modulus[n]); - } - printf("\n"); + printf(" Modulus: "); + print_hex(modulus, modulus_len, 0, true); free(modulus); } public_exponent = getPUBLIC_EXPONENT(sess, obj, &public_exponent_len); if (public_exponent) { - unsigned int n; - - printf(" PUBLIC_EXPONENT: "); - for (n = 0; n < public_exponent_len; n++) { - if (n && (n % 32) == 0) - printf("\n "); - printf("%02x", public_exponent[n]); - } - printf("\n"); + printf(" Public exponent: "); + print_hex(public_exponent, public_exponent_len, ':', true); free(public_exponent); } } @@ -6567,27 +6571,16 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) oid = getGOSTR3410_PARAMS(sess, obj, &size); if (oid) { - unsigned int n; - - printf(" PARAMS OID: "); - for (n = 0; n < size; n++) - printf("%02x", oid[n]); - printf("\n"); + printf(" Params OID: "); + print_hex(oid, size, ':', true); free(oid); } if (pub) { value = getVALUE(sess, obj, &size); if (value) { - unsigned int n; - - printf(" VALUE: "); - for (n = 0; n < size; n++) { - if (n && (n%32)==0) - printf("\n "); - printf("%02x", value[n]); - } - printf("\n"); + printf(" Value: "); + print_hex(value, size, 0, true); free(value); } } @@ -6626,18 +6619,15 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) * "ECPoint ::= OCTET STRING" */ if (point_bytes && point_size) { - printf(" EC_POINT: "); - for (n = 0; n < point_size; n++) - printf("%02x", point_bytes[n]); - printf("\n"); + printf(" EC Point: "); + print_hex(point_bytes, point_size, 0, true); } if (params_bytes && params_size > 0) { struct sc_object_id oid; - printf(" EC_PARAMS: "); - for (n = 0; n < params_size; n++) - printf("%02x", params_bytes[n]); + printf(" EC Params: "); + print_hex(params_bytes, params_size, ':', false); if (curve_info) { /* we matched it above, use printable OID */ printf(" (\"%s\" OID:\"%s\")\n", curve_info->name, curve_info->oid); @@ -6692,15 +6682,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); value = getVALUE(sess, obj, &size); if (value) { - unsigned int n; - - printf(" VALUE: "); - for (n = 0; n < size; n++) { - if (n && (n%32)==0) - printf("\n "); - printf("%02x", value[n]); - } - printf("\n"); + printf(" Value: "); + print_hex(value, size, 0, true); free(value); } break; @@ -6789,15 +6772,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) if (pub) { value = getVALUE(sess, obj, &size); if (value) { - unsigned int n; - - printf(" VALUE: "); - for (n = 0; n < size; n++) { - if (n && (n % 32) == 0) - printf("\n "); - printf("%02x", value[n]); - } - printf("\n"); + printf(" Value: "); + print_hex(value, size, 0, true); free(value); } } @@ -6813,12 +6789,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } if ((id = getID(sess, obj, &idsize)) != NULL && idsize) { - unsigned int n; - printf(" ID: "); - for (n = 0; n < idsize; n++) - printf("%02x", id[n]); - printf("\n"); + print_hex(id, idsize, ':', true); } printf(" Usage: "); @@ -7018,12 +6990,8 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) #endif /* ENABLE_OPENSSL */ if ((id = getID(sess, obj, &size)) != NULL && size) { - unsigned int n; - printf(" ID: "); - for (n = 0; n < size; n++) - printf("%02x", id[n]); - printf("\n"); + print_hex(id, size, ':', true); } if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { printf(" Unique ID: %s\n", unique_id); @@ -9346,17 +9314,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, failed = data_len != in_len || memcmp(orig_data, data, data_len); if (failed) { - CK_ULONG n; - printf("resulting cleartext doesn't match input\n"); printf(" Original:"); - for (n = 0; n < in_len; n++) - printf(" %02x", orig_data[n]); - printf("\n"); + print_hex(orig_data, in_len, 0, true); printf(" Decrypted:"); - for (n = 0; n < data_len; n++) - printf(" %02x", data[n]); - printf("\n"); + print_hex(data, data_len, 0, true); return 1; } From c4abf2084ade24382f7c98a83004e968c260c768 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 26 Mar 2026 12:13:08 +0100 Subject: [PATCH 4143/4321] pkcs11-tool: Print small values as integers (such as RSA public exponent) --- src/tools/pkcs11-tool.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index edea436aa5..a5f63d9d35 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6474,7 +6474,18 @@ print_hex(const u8 *bin_input, size_t input_size, int separator, bool newline) { char out[BYTES_PER_LINE * 3] = {0}; size_t out_len = BYTES_PER_LINE * 3; - unsigned int n; + unsigned int dec = 0; + unsigned int n, i; + + /* If it is small enough number, convert it to deccimal */ + if (input_size <= sizeof(unsigned int)) { + for (i = 0; i < input_size; i++) { + dec = (dec << 8) + (bin_input[i] & 0xff); + } + if (dec != 0) { + printf("%u (0x", dec); + } + } for (n = 0; n < input_size; n += BYTES_PER_LINE) { size_t chunk_len = MIN(input_size - n, BYTES_PER_LINE); @@ -6482,7 +6493,7 @@ print_hex(const u8 *bin_input, size_t input_size, int separator, bool newline) ? "\n " /* continuation of block */ : (newline ? "\n" : ""); /* end of the block */ sc_bin_to_hex(bin_input + n, chunk_len, out, out_len, separator); - printf("%s%s", out, indent); + printf("%s%s%s", out, (dec != 0 ? ")" : ""), indent); } } @@ -6546,8 +6557,8 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } public_exponent = getPUBLIC_EXPONENT(sess, obj, &public_exponent_len); if (public_exponent) { - printf(" Public exponent: "); - print_hex(public_exponent, public_exponent_len, ':', true); + printf(" Public exp: "); + print_hex(public_exponent, public_exponent_len, 0, true); free(public_exponent); } } From 7cd18ef951fef8dd0243c1a68b9b333c22a1ea96 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 12:20:08 +0200 Subject: [PATCH 4144/4321] tests: Exclude p11test when built without cmocka --- tests/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 073a838c7e..e59a5615d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -53,9 +53,11 @@ TESTS += \ test-pkcs11-tool-uri-with-slot-id.sh if ENABLE_TESTS if ENABLE_SHARED +if ENABLE_CMOCKA TESTS += test-p11test.sh endif endif endif +endif # no tests expected to fail #XFAIL_TESTS= From 55cba1a38313d35dc529cb1f03e9de5152c62a02 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 12:38:40 +0200 Subject: [PATCH 4145/4321] tests: Add missing scripts to dist tarball --- tests/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index e59a5615d6..6cf4d7082c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,6 +24,9 @@ AM_TESTS_ENVIRONMENT += \ endif dist_noinst_SCRIPTS = common.sh \ + init-softhsm.sh \ + init-softokn.sh \ + init-kryoptic.sh \ test-manpage.sh \ test-duplicate-symbols.sh \ test-fuzzing.sh \ From c6b4bc019222b1d71158152f8865500d0a7708d5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 12:52:30 +0200 Subject: [PATCH 4146/4321] tests: Fix reference to scripts for out-of-source build --- tests/common.sh | 7 ++++--- tests/test-p11test.sh | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index 9fb39db8d5..7e63016036 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -1,6 +1,7 @@ #!/bin/bash ## from OpenSC/src/tests/p11test/runtest.sh BUILD_PATH=${BUILD_PATH:-..} +SOURCE_PATH=${SOURCE_PATH:-..} TOKENTYPE=$1 @@ -14,11 +15,11 @@ export PIN="123456abcdef" PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" if [ "${TOKENTYPE}" == "softhsm" ]; then - source "${BUILD_PATH}/tests/init-softhsm.sh" + source "${SOURCE_PATH}/tests/init-softhsm.sh" elif [ "${TOKENTYPE}" == "softokn" ]; then - source "${BUILD_PATH}/tests/init-softokn.sh" + source "${SOURCE_PATH}/tests/init-softokn.sh" elif [ "${TOKENTYPE}" == "kryoptic" ]; then - source "${BUILD_PATH}/tests/init-kryoptic.sh" + source "${SOURCE_PATH}/tests/init-kryoptic.sh" else echo "Unknown token type: $1" exit 1 diff --git a/tests/test-p11test.sh b/tests/test-p11test.sh index 5bf5cf2d57..100a4cd913 100755 --- a/tests/test-p11test.sh +++ b/tests/test-p11test.sh @@ -38,7 +38,7 @@ function filter_log() { sed -n '/readonly_tests/,$p' $1 } -REF_FILE="$BUILD_PATH/tests/${TOKENTYPE}_ref.json" +REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_ref.json" if [[ "$TOKENTYPE" == "softhsm" ]]; then VERSION=$(softhsm2-util --version) REF_FILE="$SOURCE_PATH/tests/${TOKENTYPE}_${VERSION}_ref.json" From f423ce10a307ac0c1c67a511f9c6b947a291e142 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 13:46:16 +0200 Subject: [PATCH 4147/4321] tests: Avoid leaving test files in build directory --- tests/test-pkcs11-tool-unwrap-wrap-test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-test.sh index c79d3028d8..ab43e4f7c7 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-test.sh @@ -379,7 +379,7 @@ function test_unwrapped_rsa_pkcs_decryption() { # Compare plaintexts cmp plaintext.data decrypted_plaintext.data >/dev/null 2>/dev/null assert $? "RSA decrypted plaintexts do not match" - rm plaintext.data decrypted_plaintext.data + rm plaintext.data decrypted_plaintext.data ciphertext.data } ID_AES_WRAP="0200" @@ -467,6 +467,7 @@ fi echo "=======================================================" echo "Cleanup" echo "=======================================================" +rm -f aes_kek.key token_cleanup exit $ERRORS From 273cf88fcf463a924836035039907c2ce48d3d55 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 13:46:34 +0200 Subject: [PATCH 4148/4321] tests: Package libssh reference file to release tarball --- tests/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 6cf4d7082c..d803c33cee 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = softhsm_2.6.1_ref.json softhsm_2.7.0_ref.json softhsm_fips_ref.json +EXTRA_DIST = softhsm_2.6.1_ref.json softhsm_2.7.0_ref.json softhsm_fips_ref.json softhsm_libressl_ref.json TEST_EXTENSIONS = .sh # This pushes the valgrind command to the test environment From f7efb3addec7b4bff0c3dadba68448f43cdd1202 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 13:45:08 +0200 Subject: [PATCH 4149/4321] ci: Define LIBRESSL_VERSION only for the libressl jobs --- .github/workflows/linux.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1937ddc2ca..e9ebae767b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -28,7 +28,6 @@ env: JAVA_DEPS: | ant openjdk-8-jdk maven cmake JCARDSIM: https://github.com/Jakuje/jcardsim.git - LIBRESSL_VERSION: 4.2.1 jobs: build: @@ -200,6 +199,8 @@ jobs: ####################### build-libressl: runs-on: ubuntu-latest + env: + LIBRESSL_VERSION: 4.2.1 steps: - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 From 65fc211015cfcac27b10d0876054156c97225f50 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Nov 2025 15:58:02 +0100 Subject: [PATCH 4150/4321] pkcs15: Avoid buffer overrun on invalid data Invalid data can contain zero-length buffer, which after copying was dereferenced without length check Credit: Aldo Ristori Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-pubkey.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e55296582e..72d207bfb5 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1332,6 +1332,10 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke "sc_pkcs15_pubkey_from_spki_fields() called: %p:%"SC_FORMAT_LEN_SIZE_T"u\n%s", buf, buflen, sc_dump_hex(buf, buflen)); + if (buflen < 1) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "subjectPublicKeyInfo can not be empty"); + } + tmp_buf = malloc(buflen); if (!tmp_buf) { r = SC_ERROR_OUT_OF_MEMORY; From 0358817ec74aeca654f83e7709c7720b14c5db59 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 3 Mar 2026 15:04:33 +0100 Subject: [PATCH 4151/4321] profile: Avoid possible buffer overrun Profile file of the following format will cause buffer overrun when parsed during the pkcs15-init invocation: ``` cardinfo { key CHV1 { value = "=XXXX..."; // 200+ X characters } } ``` This will cause both stack and heap buffer overrun. Thanks Nicholas Carlini from Anthropic for the report. --- src/pkcs15init/profile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index a6e89b0afb..aa72cf688a 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -992,6 +992,10 @@ do_key_value(struct state *cur, int argc, char **argv) if (key[0] == '=') { ++key; key_len = strlen(key); + if (key_len > sizeof(keybuf)) { + parse_error(cur, "Key value too long (%zu > %zu)\n", key_len, sizeof(keybuf)); + return 1; + } memcpy(keybuf, key, key_len); } else { key_len = sizeof(keybuf); From 73fe9c9b2ddd98cc75b32e5e4b98398af4ce1215 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 25 Mar 2026 21:33:11 +0100 Subject: [PATCH 4152/4321] rtecp: Avoid stack buffer overrun Reported and patch provided by Kevin Valerio of Trail of Bits, issue found by Anthropic's Claude. The report included the fuzzer reproducer, that is added to the corpus. Signed-off-by: Jakub Jelen --- src/libopensc/card-rtecp.c | 5 +++++ .../e9907948b6c2a8a0f82b160ebbafd7bb47325792 | Bin 0 -> 16463 bytes 2 files changed, 5 insertions(+) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs11/e9907948b6c2a8a0f82b160ebbafd7bb47325792 diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 338961cd6b..70e27153bd 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -437,6 +437,11 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, { if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + if (apdu.resplen > out_len) { + free(buf_out); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, + SC_ERROR_BUFFER_TOO_SMALL); + } for (i = 0; i < apdu.resplen; ++i) out[i] = buf_out[apdu.resplen - 1 - i]; r = (i > 0) ? (int)i : SC_ERROR_INTERNAL; diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs11/e9907948b6c2a8a0f82b160ebbafd7bb47325792 b/src/tests/fuzzing/corpus/fuzz_pkcs11/e9907948b6c2a8a0f82b160ebbafd7bb47325792 new file mode 100644 index 0000000000000000000000000000000000000000..a9690b98472fab61a0135e138db75c8afd38d7db GIT binary patch literal 16463 zcmeIzze)o^5XbSExg&{Z;@JemKX{#p%_gQ0EG&$b&EY%PD40h3aDt6Z9wF((C-Cvy z&3b2ZkO#o44?o5ApvFq4p4vrW&s9b0&D~% zun{m25?~hK00kIe7GNMIz(zm<8vz3$0cHUXP=Enu0S00MYy>2*5ik%EU>4v21sGr! sU?3*IMnD1^0RtfcW&sXRfB|L!24Vti1SGH#Fc1=87T^E{7>Kjr7pU8o$p8QV literal 0 HcmV?d00001 From b675b9b4b8f33d519574606afe54147f5535bd1f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 25 Mar 2026 21:41:56 +0100 Subject: [PATCH 4153/4321] pkcs15-crypt: Avoid possible stack buffer overrun This is only theoretical, as OpenSC does not support any ECC curve with signature R and S values that would not fit into 1024 B buffer. Reported and patch provided by Kevin Valerio of Trail of Bits, issue found by Anthropic's Claude. The report included the fuzzer reproducer, that is added to the corpus. Signed-off-by: Jakub Jelen --- .../46aca342dc91118357b5cfd40aec995d2b53bd02 | Bin 0 -> 1258 bytes src/tools/pkcs15-crypt.c | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/46aca342dc91118357b5cfd40aec995d2b53bd02 diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/46aca342dc91118357b5cfd40aec995d2b53bd02 b/src/tests/fuzzing/corpus/fuzz_pkcs15_crypt/46aca342dc91118357b5cfd40aec995d2b53bd02 new file mode 100644 index 0000000000000000000000000000000000000000..51ce43b706283071daf8312fff9ac19eb622b138 GIT binary patch literal 1258 zcmZQFG%_|}U}j)sU{GLiBmhJhtm~&SFf423!U#EKDwpOhA sizeof(out)) { + free(seq); + fprintf(stderr, "Signature sequence too large\n"); + return 2; + } + memcpy(out, seq, seqlen); len = seqlen; From 502d0c01fd45e5c20212874f9c1c32f254f9ffeb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 25 Mar 2026 22:05:05 +0100 Subject: [PATCH 4154/4321] asn1: Avoid stack buffer overrun The successful exploit would require 8 access modes when encoding PKCS#15 object for writing to the card (usually coming from profile file during card enrollment). Reported and patch provided by Kevin Valerio of Trail of Bits, issue found by Anthropic's Claude. The report included the fuzzer reproducer, that is added to the corpus. --- src/libopensc/asn1.c | 2 +- .../636b70af193cecc86033282774e8b8bc3aa39f4c | Bin 0 -> 295 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/tests/fuzzing/corpus/fuzz_pkcs15_encode/636b70af193cecc86033282774e8b8bc3aa39f4c diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 262308930b..5b1ba88c41 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1467,7 +1467,7 @@ static int asn1_encode_p15_object(sc_context_t *ctx, const struct sc_asn1_pkcs15 sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj.user_consent, NULL, 1); if (p15_obj.access_rules[0].access_mode) { - for (ii=0; p15_obj.access_rules[ii].access_mode; ii++) { + for (ii = 0; ii < SC_PKCS15_MAX_ACCESS_RULES && p15_obj.access_rules[ii].access_mode; ii++) { access_mode_len = sizeof(p15_obj.access_rules[ii].access_mode); sc_format_asn1_entry(asn1_ac_rule[ii] + 0, (void *) &p15_obj.access_rules[ii].access_mode, &access_mode_len, 1); sc_format_asn1_entry(asn1_ac_rule[ii] + 1, (void *) &p15_obj.access_rules[ii].auth_id, NULL, 1); diff --git a/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/636b70af193cecc86033282774e8b8bc3aa39f4c b/src/tests/fuzzing/corpus/fuzz_pkcs15_encode/636b70af193cecc86033282774e8b8bc3aa39f4c new file mode 100644 index 0000000000000000000000000000000000000000..5e2c2a9c87c8cecdda2ed8fde4908ce03dfc913e GIT binary patch literal 295 zcmWe&u&$lTz|dgWkh-B+@W9Gu1}26HP@L7o&5+ODz{J4N#K<^-0m|V8bNCqyxS1Fk zSeS%Nn3>oc;IbTGSuTbZYz8bWOaUfvi4?Fz8iPTSftP`Y0Xs++3nL??3}&Di3;7Lr ULB?@0GBPo;Ffnq#JU~4f0A_tEzyJUM literal 0 HcmV?d00001 From aca07679a6dd281ee6411f5e7de2ed0ee796bee8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 1 Dec 2025 15:36:34 +0100 Subject: [PATCH 4155/4321] OpenSC 0.27.0 --- NEWS | 11 +++++++++-- SECURITY.md | 4 ++-- VERSION.mk | 2 +- packaging/opensc.spec | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 27062c4f7a..e55f1eca10 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,14 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.27.0; 2026-03-XX +# New in 0.27.0; 2026-03-30 ## Security -* Several uses of potentially uninitialized memory detected by fuzzers +* CVE-2025-13763: Several uses of potentially uninitialized memory detected by fuzzers +* CVE-2025-49010: Possible write beyond buffer bounds during processing of GET RESPONSE APDU +* CVE-2025-66215: Possible write beyond buffer bounds in oberthur driver +* CVE-2025-66038: Possible read beyond buffer bounds when parsing historical bytes in PIV driver +* CVE-2025-66037: Possible buffer overrun while parsing SPKI +* More low-severity data handling issues when parsing profile configuration ## General improvements * Added support for PKCS#11 3.2 in tools and pkcs11-spy and p11test(#3510) @@ -16,6 +21,7 @@ NEWS for OpenSC -- History of user visible changes * Removed internal caching for current EF/DF (#3403) * Correctly detect OS-level FIPS mode in OpenSSL automatically (#3551) or through custom configuration file (#3525) +* Added support for Brainpool twisted curves to pkcs11-tool and SC-HSM (#3601) ## PC/SC * Handle case when smart card is removed and inserted between two subsequent calls to @@ -58,6 +64,7 @@ NEWS for OpenSC -- History of user visible changes * Add support for ChaCha20 and Poly1305 (#3339) * Add support for AES CTR in decrypt_data() and encrypt_data() (#3338) * Add initial support for PKCS#11 URIs (#3289) +* Print more information about RSA keys (#3623) # New in 0.26.1; 2025-01-14 diff --git a/SECURITY.md b/SECURITY.md index df5c8df2af..aaed4e3c37 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,8 +9,8 @@ backport security fixes into them. Only the last release is supported. | Version | Supported | | -------- | ------------------ | -| 0.26.1 | :white_check_mark: | -| < 0.26.1 | :x: | +| 0.27.0 | :white_check_mark: | +| < 0.27.0 | :x: | ## Reporting a Vulnerability diff --git a/VERSION.mk b/VERSION.mk index 1a11ea72c2..8662a49a45 100644 --- a/VERSION.mk +++ b/VERSION.mk @@ -6,7 +6,7 @@ PACKAGE_VERSION_MAJOR=0 PACKAGE_VERSION_MINOR=27 PACKAGE_VERSION_FIX=0 PACKAGE_VERSION_REVISION=0 -PACKAGE_SUFFIX=-rc2 +PACKAGE_SUFFIX= PACKAGE_SCM_REVISION=No Git revision info available VS_FF_LEGAL_COPYRIGHT=OpenSC Project diff --git a/packaging/opensc.spec b/packaging/opensc.spec index b938f32696..2a6da1ec4a 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -5,7 +5,7 @@ Summary: Smart card library and applications License: LGPL-2.1-or-later AND BSD-3-Clause URL: https://github.com/OpenSC/OpenSC/wiki -Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}-rc2.tar.gz +Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz Source1: opensc.module BuildRequires: make @@ -57,7 +57,7 @@ OpenSC libraries. %prep -%setup -q -n opensc-%{version}-rc2 +%setup -q -n opensc-%{version} XFAIL_TESTS="test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh" From 19868984dc4dc697af6a86d65ab32a1f19a43ea4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Mar 2026 22:24:58 +0200 Subject: [PATCH 4156/4321] OpenSC 0.27.1 Fixup release to clean up artifact names --- .appveyor.yml | 2 +- .github/build.sh | 18 +++++++++++++----- .github/workflows/windows.yml | 20 +++++++++++++------- NEWS | 4 ++++ SECURITY.md | 2 +- VERSION.mk | 2 +- packaging/opensc.spec | 2 +- 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 89e31ee4c0..4a96db47bf 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.27.0.{build} +version: 0.27.1.{build} platform: - x86 diff --git a/.github/build.sh b/.github/build.sh index 7c1dcf26bf..4b4434967f 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -16,11 +16,19 @@ if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then SUFFIX="$GITHUB_BASE_REF-pr$PR_NUMBER" fi else - BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$GITHUB_REF_TYPE" == "tag" ] && [[ "$BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then - SUFFIX="${BASH_REMATCH[1]}" - elif [ "$BRANCH" != "master" ]; then - SUFFIX="$BRANCH" + TAG_OR_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') + if [ "$GITHUB_REF_TYPE" == "tag" ]; then + if [[ "$TAG_OR_BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # Tag matches the version scheme without suffix -- no suffix needed + SUFFIX="" + elif [[ "$TAG_OR_BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + # rc suffix after version. Use the suffix part only + SUFFIX="${BASH_REMATCH[1]}" + else + SUFFIX="-$TAG_OR_BRANCH" + fi + elif [ "$TAG_OR_BRANCH" != "master" ]; then + SUFFIX="-$TAG_OR_BRANCH" fi fi if [ -n "$SUFFIX" ]; then diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d03988129f..6f2cf6611a 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -41,18 +41,24 @@ jobs: - name: Package suffix shell: bash run: | - if [[ "${{ github.event_name }}" == "push" ]]; then - if [[ "${{ github.ref_type }}" == "tag" && "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then - SUFFIX="${BASH_REMATCH[1]}" - elif [[ "${{ github.ref_name }}" != "master" ]]; then - SUFFIX="-${{ github.ref_name }}" - fi - elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + if [[ "${{ github.event_name }}" == "pull_request" ]]; then if [[ "${{ github.base_ref }}" == "master" ]]; then SUFFIX="-pr${{ github.event.number }}" else SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" fi + elif [[ "${{ github.event_name }}" == "push" ]]; then + if [[ "${{ github.ref_type }}" == "tag" ]]; then + if [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + SUFFIX="" # regular release tag + elif [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + SUFFIX="${BASH_REMATCH[1]}" # rc release tag + else + SUFFIX="-${{ github.ref_name }}" + fi + elif [[ "${{ github.ref_name }}" != "master" ]]; then + SUFFIX="-${{ github.ref_name }}" + fi fi PACKAGE_SUFFIX="${SUFFIX}${{ matrix.configuration == 'Light' && '-Light' || '' }}" sed -i.bak "s/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX=$PACKAGE_SUFFIX/g" VERSION.mk diff --git a/NEWS b/NEWS index e55f1eca10..13d19b1571 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ NEWS for OpenSC -- History of user visible changes +# New in 0.27.1; 2026-03-31 + +* Bugfix release to fix up infrastructure issues. + # New in 0.27.0; 2026-03-30 ## Security diff --git a/SECURITY.md b/SECURITY.md index aaed4e3c37..5e0c95891f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,7 +9,7 @@ backport security fixes into them. Only the last release is supported. | Version | Supported | | -------- | ------------------ | -| 0.27.0 | :white_check_mark: | +| 0.27.0+ | :white_check_mark: | | < 0.27.0 | :x: | ## Reporting a Vulnerability diff --git a/VERSION.mk b/VERSION.mk index 8662a49a45..37c7e74d5e 100644 --- a/VERSION.mk +++ b/VERSION.mk @@ -4,7 +4,7 @@ PRODUCT_BUGREPORT=https://github.com/OpenSC/OpenSC/issues PRODUCT_URL=https://github.com/OpenSC/OpenSC PACKAGE_VERSION_MAJOR=0 PACKAGE_VERSION_MINOR=27 -PACKAGE_VERSION_FIX=0 +PACKAGE_VERSION_FIX=1 PACKAGE_VERSION_REVISION=0 PACKAGE_SUFFIX= PACKAGE_SCM_REVISION=No Git revision info available diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 2a6da1ec4a..2c74fba897 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -1,5 +1,5 @@ Name: opensc -Version: 0.27.0 +Version: 0.27.1 Release: %autorelease Summary: Smart card library and applications From 1b8c0cb727a2f37adeaedf3474f937ea0605d507 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 10 Mar 2026 17:19:50 +0100 Subject: [PATCH 4157/4321] CI: updated OpenPACE --- .appveyor.yml | 2 +- .github/workflows/windows.yml | 2 +- MacOSX/build | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 4a96db47bf..150a4fc061 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,7 +10,7 @@ configuration: environment: PATH: C:\cygwin\bin;%PATH% - OPENPACE_VER: 1.1.3 + OPENPACE_VER: 1.1.4 ZLIB_VER_DOT: 1.3.1 matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6f2cf6611a..c6eb406a90 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -31,7 +31,7 @@ jobs: - platform: arm64 setenv: amd64_arm64 env: - OPENPACE_VER: 1.1.3 + OPENPACE_VER: 1.1.4 VCPKG_INSTALLED: ${{ github.workspace }}\vcpkg_installed VCPKG_DEFAULT_TRIPLET: ${{ matrix.platform }}-windows-static BUILD_NUMBER: ${{ github.run_number }} diff --git a/MacOSX/build b/MacOSX/build index 7507d160f6..58d49b9a61 100755 --- a/MacOSX/build +++ b/MacOSX/build @@ -45,7 +45,7 @@ export OBJCFLAGS=$CFLAGS if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then if ! test -e openpace; then - git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.3 + git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.4 fi cd openpace autoreconf -vis From a36025a92739ee3d477d880540f08afb0ef16574 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 10 Mar 2026 17:23:08 +0100 Subject: [PATCH 4158/4321] AppVeyor: updated zlib --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 150a4fc061..f74f7f6c23 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -11,7 +11,7 @@ configuration: environment: PATH: C:\cygwin\bin;%PATH% OPENPACE_VER: 1.1.4 - ZLIB_VER_DOT: 1.3.1 + ZLIB_VER_DOT: 1.3.2 matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" From fc45d4f3b67261c4edbb7e3fcdafefcb3654a1a3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 9 Feb 2026 17:22:30 -0600 Subject: [PATCH 4159/4321] piv-tool.c pkcs15-piv.c allow creating retired key management keys 82-95 piv-tool.c and pkcs15.c are updated to allow creation of private keys with keyrefs 0x82 - 0x94. These are associated with public keys and certs PIV "retired KEY MAN NN" keys where NN is 1 to 20, with PIV cert and pubkey pkcs11 CK_IDs of 05-24, (looking like decimal as no hex a-f are used) and labels of "Retired KEY MAN nn" where nn is 1 to 20. On branch piv-tool-retired-keys Changes to be committed: modified: src/libopensc/pkcs15-piv.c modified: src/tools/piv-tool.c --- src/libopensc/pkcs15-piv.c | 42 +++++++++++++++++++------------------- src/tools/piv-tool.c | 26 ++++++++++++++++++++--- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 9c2689bb86..6bad33b52b 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -4,7 +4,7 @@ * * Copyright (C) 2005,2006,2007,2008,2009,2010 * Douglas E. Engert - * Copyright (C) 2020 Douglas E. Engert + * Copyright (C) 2020-2026 Douglas E. Engert * 2004, Nils Larsch * Copyright (C) 2006, Identity Alliance, * Thomas Harning @@ -451,83 +451,83 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) { "05", "Retired KEY MAN 1", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8206", 0x82, NULL, 0, NULL}, + "8206", 0x82, NULL, 0, "PIV_82_KEY"}, { "06", "Retired KEY MAN 2", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8306", 0x83, NULL, 0, NULL}, + "8306", 0x83, NULL, 0, "PIV_83_KEY"}, { "07", "Retired KEY MAN 3", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8406", 0x84, NULL, 0, NULL}, + "8406", 0x84, NULL, 0, "PIV_84_KEY"}, { "08", "Retired KEY MAN 4", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8506", 0x85, NULL, 0, NULL}, + "8506", 0x85, NULL, 0, "PIV_85_KEY"}, { "09", "Retired KEY MAN 5", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8606", 0x86, NULL, 0, NULL}, + "8606", 0x86, NULL, 0, "PIV_86_KEY"}, { "10", "Retired KEY MAN 6", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8706", 0x87, NULL, 0, NULL}, + "8706", 0x87, NULL, 0, "PIV_87_KEY"}, { "11", "Retired KEY MAN 7", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8806", 0x88, NULL, 0, NULL}, + "8806", 0x88, NULL, 0, "PIV_88_KEY"}, { "12", "Retired KEY MAN 8", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8906", 0x89, NULL, 0, NULL}, + "8906", 0x89, NULL, 0, "PIV_89_KEY"}, { "13", "Retired KEY MAN 9", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8A06", 0x8A, NULL, 0, NULL}, + "8A06", 0x8A, NULL, 0, "PIV_8A_KEY"}, { "14", "Retired KEY MAN 10", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8B06", 0x8B, NULL, 0, NULL}, + "8B06", 0x8B, NULL, 0, "PIV_8B_KEY"}, { "15", "Retired KEY MAN 11", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8C06", 0x8C, NULL, 0, NULL}, + "8C06", 0x8C, NULL, 0, "PIV_8C_KEY"}, { "16", "Retired KEY MAN 12", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8D06", 0x8D, NULL, 0, NULL}, + "8D06", 0x8D, NULL, 0, "PIV_8D_KEY"}, { "17", "Retired KEY MAN 13", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8E06", 0x8E, NULL, 0, NULL}, + "8E06", 0x8E, NULL, 0, "PIV_8E_KEY"}, { "18", "Retired KEY MAN 14", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "8F06", 0x8F, NULL, 0, NULL}, + "8F06", 0x8F, NULL, 0, "PIV_8F_KEY"}, { "19", "Retired KEY MAN 15", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9006", 0x90, NULL, 0, NULL}, + "9006", 0x90, NULL, 0, "PIV_90_KEY"}, { "20", "Retired KEY MAN 16", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9106", 0x91, NULL, 0, NULL}, + "9106", 0x91, NULL, 0, "PIV_91_KEY"}, { "21", "Retired KEY MAN 17", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9206", 0x92, NULL, 0, NULL}, + "9206", 0x92, NULL, 0, "PIV_92_KEY"}, { "22", "Retired KEY MAN 18", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9306", 0x93, NULL, 0, NULL}, + "9306", 0x93, NULL, 0, "PIV_93_KEY"}, { "23", "Retired KEY MAN 19", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9406", 0x94, NULL, 0, NULL}, + "9406", 0x94, NULL, 0, "PIV_94_KEY"}, { "24", "Retired KEY MAN 20", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, - "9506", 0x95, NULL, 0, NULL} + "9506", 0x95, NULL, 0, "PIV_95_KEY"} }; // clang-format on diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 1c2d912a84..b8dd8153c7 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -2,7 +2,7 @@ * piv-tool.c: Tool for accessing smart cards with libopensc * * Copyright (C) 2001 Juha Yrjölä - * Copyright (C) 2005,2010 Douglas E. Engert + * Copyright (C) 2005,2010-2026 Douglas E. Engert * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -295,7 +295,7 @@ static int gen_key(const char * key_info) sc_hex_to_bin(key_info, buf, &buflen); if (buflen != 2) { - fprintf(stderr, ": invalid, example: 9A:06\n"); + fprintf(stderr, ": invalid, example: 9A:07 9A ker with RSA 2048\n"); return 2; } switch (buf[0]) { @@ -303,10 +303,30 @@ static int gen_key(const char * key_info) case 0x9c: case 0x9d: case 0x9e: + case 0x82: /* retired keys */ + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: keydata.key_num = buf[0]; break; default: - fprintf(stderr, ": must be 9A, 9C, 9D or 9E\n"); + fprintf(stderr, ": must be 9A, 9C, 9D, or 82-95 \n"); return 2; } From 7141e79af71a37e31b85e0dd0e9186a45063850c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 10 Feb 2026 11:09:50 -0600 Subject: [PATCH 4160/4321] piv-tool.1.xml - Create Retired Keys and History object On branch piv-tool-retired-keys Changes to be committed: modified: ../doc/tools/piv-tool.1.xml --- doc/tools/piv-tool.1.xml | 47 ++++++++++++++++++++++++++-------------- src/tools/piv-tool.c | 2 +- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index cc38089e21..b774ae4d5f 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -21,10 +21,15 @@ + Description + The piv-tool utility can be used from the command line to perform - miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. - It is intended for use with test cards only. It can be used to load objects, and generate + miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in + + NIST SP 800-73-5 a multi-part document. + + It is intended for use with test cards only. It can load objects and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor. @@ -66,7 +71,7 @@ PIV_EXT_AUTH_KEY must point to either a binary file matching the length of the key or a text file containing the key in the format: - XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX + XX:XX:XX:XX:XX... @@ -78,10 +83,15 @@ The argument of the form ref:alg is required, where ref is 9A, - 9C, 9D or 9E and - alg is 06, + 9C, 9D, 9E and + 82-95 for retired keys. + alg is 05, 06, 07, 11 or 14 - for RSA 1024, RSA 2048, ECC 256 or ECC 384 respectively. + for RSA 3072, RSA 1024, RSA 2048, ECC 256 or ECC 384 respectively. + Some non standard cards/tokens also support + 16, E0, E1 + for RSA 4096, EDDSA 25519 or XEDDSA 25519. + @@ -89,8 +99,9 @@ ContainerID Load an object onto the card. - The ContainerID is as defined in NIST 800-73-n - without leading 0x. Example: CHUID object is 3000 + The ContainerID is as defined in + NIST SP 800-73-5 Part 1 Table 2. "Data Model Containers" + (without leading 0x). Example: CHUID object is 3000 @@ -100,9 +111,8 @@ ref Load a certificate onto the card. - ref is 9A, - 9C, 9D or - 9E + ref as in + @@ -111,16 +121,15 @@ ref Load a certificate that has been gzipped onto the card. - ref is 9A, - 9C, 9D or - 9E + ref as in + file, file - + Description Output file for any operation that produces output. @@ -150,7 +159,7 @@ Sends an arbitrary APDU to the card in the format AA:BB:CC:DD:EE:FF.... This option may be repeated. - + Description @@ -186,6 +195,12 @@ + + Examples + create History Object to use the 20 retired keys + piv-tool argument -s "00:DB:3F:FF:0F:5C:03:5F:C1:0C:53:08:C1:01:14:C2:01:00:FE:00" + + See also diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index b8dd8153c7..78782e5db7 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -303,7 +303,7 @@ static int gen_key(const char * key_info) case 0x9c: case 0x9d: case 0x9e: - case 0x82: /* retired keys */ + case 0x82: /* retired keys */ case 0x83: case 0x84: case 0x85: From 7d3213388f615a16b7ab428600d11a59fc7be571 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 15 Feb 2026 17:02:18 -0600 Subject: [PATCH 4161/4321] piv-tool.c - fix error messages and improve error responses Changes not staged for commit: modified: ../doc/tools/piv-tool.1.xml --- src/tools/piv-tool.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 78782e5db7..326a11bd44 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -276,7 +276,7 @@ static int admin_mode(const char* admin_info) r = sc_card_ctl(card, SC_CARDCTL_PIV_AUTHENTICATE, &opts); if (r) - fprintf(stderr, " admin_mode failed %d\n", r); + fprintf(stderr, " admin_mode failed %s\n", sc_strerror(r)); return r; } @@ -295,7 +295,7 @@ static int gen_key(const char * key_info) sc_hex_to_bin(key_info, buf, &buflen); if (buflen != 2) { - fprintf(stderr, ": invalid, example: 9A:07 9A ker with RSA 2048\n"); + fprintf(stderr, ": invalid. Example: 9A:07 to create 9A key with RSA 2048\n"); return 2; } switch (buf[0]) { @@ -326,7 +326,7 @@ static int gen_key(const char * key_info) keydata.key_num = buf[0]; break; default: - fprintf(stderr, ": must be 9A, 9C, 9D, or 82-95 \n"); + fprintf(stderr, " must be 9A, 9C, 9D, 9E or 82-95 \n"); return 2; } @@ -351,7 +351,7 @@ static int gen_key(const char * key_info) break; #endif default: - fprintf(stderr, ": algid=RSA - 05, 06, 07 for 3072, 1024, 2048;EC - 11, 14 for 256, 384\n"); + fprintf(stderr, " must be: RSA - 05, 06, 07 for 3072, 1024, 2048; EC - 11, 14 for 256, 384; E0 for ED25519; or E1 X25519\n"); return 2; } @@ -360,7 +360,7 @@ static int gen_key(const char * key_info) r = sc_card_ctl(card, SC_CARDCTL_PIV_GENERATE_KEY, &keydata); if (r) { - fprintf(stderr, "gen_key failed %d\n", r); + fprintf(stderr, "gen_key failed %s\n", sc_strerror(r)); return 1; } @@ -385,7 +385,7 @@ static int gen_key(const char * key_info) #endif if (!keydata.pubkey || !keydata.exponent) { - fprintf(stderr, "gen_key failed %d\n", r); + fprintf(stderr, "gen_key failed %s\n", sc_strerror(r)); r = 1; goto out; } @@ -713,7 +713,7 @@ static void print_serial(sc_card_t *in_card) r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial); if (r < 0) - fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed %d\n", r); + fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed %s\n", sc_strerror(r)); else util_hex_dump_asc(stdout, serial.value, serial.len, -1); } From e6b76871d6975998501f956ad80421baeb2d5cee Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 15 Feb 2026 17:03:49 -0600 Subject: [PATCH 4162/4321] piv-tool.1.xml - fix wording of example --- doc/tools/piv-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/piv-tool.1.xml b/doc/tools/piv-tool.1.xml index b774ae4d5f..d2ca7eed28 100644 --- a/doc/tools/piv-tool.1.xml +++ b/doc/tools/piv-tool.1.xml @@ -197,7 +197,7 @@ Examples - create History Object to use the 20 retired keys + Authenticate to the card and create History Object to use the 20 retired keys piv-tool argument -s "00:DB:3F:FF:0F:5C:03:5F:C1:0C:53:08:C1:01:14:C2:01:00:FE:00" From 8954f5ee4d31ce12e03cc29758822890a1363c4c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 16 Feb 2026 20:08:33 -0600 Subject: [PATCH 4163/4321] tools.html Building in out of source directory. build dir $build source dir $source rm $source/doc/tools/tools.html cd $build/doc/tools/ make tools.html cp $build/doc/tools/tools.html $source/doc/tools/ On branch piv-tool-retired-keys Changes to be committed: modified: doc/tools/tools.html --- doc/tools/tools.html | 75 ++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 41b92b1caa..ca71e96be6 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -47,7 +47,7 @@

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
    dnie-tool — displays information about DNIe based security tokens
    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK)
    eidenv — utility for accessing visible data from electronic identity cards
    gids-tool — smart card utility for GIDS cards
    iasecc-tool — displays information about IAS/ECC card -
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). +
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information of an ID card or ePassport.
    openpgp-tool — utility for accessing visible data OpenPGP smart cards and compatible tokens
    opensc-asn1 — parse ASN.1 data
    opensc-explorer — @@ -459,15 +459,17 @@

    See also

    opensc-explorer(1)

    Authors

    netkey-tool was written by - Peter Koch .


    Name

    npa-tool — displays information on the German eID card (neuer Personalausweis, nPA). + Peter Koch .


    Name

    npa-tool — displays information of an ID card or ePassport.

    Synopsis

    npa-tool [OPTIONS]

    Description

    The npa-tool utility is used to display information - stored on the German eID card (neuer Personalausweis, nPA), - and to perform some write and verification operations. + stored on an ID card or on a passport and to perform some write and + verification operations.

    Extended Access Control version 2 is performed according to ICAO Doc - 9303 or BSI TR-03110 so that other identity cards and machine - readable travel documents (MRTDs) may be read as well. + 9303 or BSI TR-03110 so that an ICAO compliant machine readable + travel document (MRTD) as well as EAC compliant ID + cards, for example the German ID card (neuer Personalausweis, + nPA), may be read.

    Options

    --help, @@ -576,17 +578,21 @@ (default=off)

  • --disable-ca-checks

    Disable passive authentication. (default=off) -

    Read and write data groups

    --read-dg1

    Read data group 1: Document Type.

    --read-dg2

    Read data group 2: Issuing State.

    --read-dg3

    Read data group 3: Date of Expiry.

    --read-dg4

    Read data group 4: Given Name(s).

    --read-dg5

    Read data group 5: Family Name.

    --read-dg6

    Read data group 6: Religious/Artistic Name.

    --read-dg7

    Read data group 7: Academic Title.

    --read-dg8

    Read data group 8: Date of Birth.

    --read-dg9

    Read data group 9: Place of Birth.

    --read-dg10

    Read data group 10: Nationality.

    --read-dg11

    Read data group 11: Sex.

    --read-dg12

    Read data group 12: Optional Data.

    --read-dg13

    Read data group 13: Birth Name.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17: Normal Place of Residence.

    --read-dg18

    Read data group 18: Community ID.

    --read-dg19

    Read data group 19: Residence Permit I.

    --read-dg20

    Read data group 20: Residence Permit II.

    --read-dg21

    Read data group 21: Optional Data.

    - --write-dg17 HEX_STRING

    Write data group 17: Normal Place of Residence.

    - --write-dg18 HEX_STRING

    Write data group 18: Community ID.

    - --write-dg19 HEX_STRING

    Write data group 19: Residence Permit I.

    - --write-dg20 HEX_STRING

    Write data group 20: Residence Permit II.

    --write-dg21 HEX_STRING

    Write data group 21: Optional Data.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    +

    Card application

    --application app

    + What application to select on the card, use eID for the + electronic identification application and eMRTD for the + ePassport application. (default=eID) +

    Read and write data groups

    --read-all-dgs

    Read all available data groups.

    --read-dg1

    Read data group 1.

    --read-dg2

    Read data group 2.

    --read-dg3

    Read data group 3.

    --read-dg4

    Read data group 4.

    --read-dg5

    Read data group 5.

    --read-dg6

    Read data group 6.

    --read-dg7

    Read data group 7.

    --read-dg8

    Read data group 8.

    --read-dg9

    Read data group 9.

    --read-dg10

    Read data group 10.

    --read-dg11

    Read data group 11.

    --read-dg12

    Read data group 12.

    --read-dg13

    Read data group 13.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17.

    --read-dg18

    Read data group 18.

    --read-dg19

    Read data group 19.

    --read-dg20

    Read data group 20.

    --read-dg21

    Read data group 21.

    + --write-dg17 HEX_STRING

    Write data group 17.

    + --write-dg18 HEX_STRING

    Write data group 18.

    + --write-dg19 HEX_STRING

    Write data group 19.

    + --write-dg20 HEX_STRING

    Write data group 20.

    --write-dg21 HEX_STRING

    Write data group 21.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    Verify chip's validity with a reference date.

    --older-than YYYYMMDD

    Verify age with a reference date.

    --verify-community HEX_STRING

    Verify community ID with a reference ID. -

    Special options, not always useful

    +

    Special options, not always useful

    --break, -b

    @@ -1336,14 +1342,17 @@

    See also

    opensc-explorer(1)

    Authors

    opensc-tool was written by - Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    + Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    Description

    The piv-tool utility can be used from the command line to perform - miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. - It is intended for use with test cards only. It can be used to load objects, and generate + miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in + + NIST SP 800-73-5 a multi-part document. + + It is intended for use with test cards only. It can load objects and generate key pairs, as well as send arbitrary APDU commands to a card after having authenticated to the card using the card key provided by the card vendor.

    Options

    -

    +

    Description

    --serial

    Print the card serial number derived from the CHUID object, if any. Output is in hex byte format.

    @@ -1365,7 +1374,7 @@ PIV_EXT_AUTH_KEY must point to either a binary file matching the length of the key or a text file containing the key in the format: - XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX + XX:XX:XX:XX:XX...

    --genkey argument, -G argument @@ -1373,31 +1382,35 @@ The argument of the form

    ref:alg

    is required, where ref is 9A, - 9C, 9D or 9E and - alg is 06, + 9C, 9D, 9E and + 82-95 for retired keys. + alg is 05, 06, 07, 11 or 14 - for RSA 1024, RSA 2048, ECC 256 or ECC 384 respectively.

    + for RSA 3072, RSA 1024, RSA 2048, ECC 256 or ECC 384 respectively. + Some non standard cards/tokens also support + 16, E0, E1 + for RSA 4096, EDDSA 25519 or XEDDSA 25519. +

    --object ContainerID, -O ContainerID

    Load an object onto the card. - The ContainerID is as defined in NIST 800-73-n - without leading 0x. Example: CHUID object is 3000 + The ContainerID is as defined in + NIST SP 800-73-5 Part 1 Table 2. "Data Model Containers" + (without leading 0x). Example: CHUID object is 3000

    --cert ref, -C ref

    Load a certificate onto the card. - ref is 9A, - 9C, 9D or - 9E

    + ref as in --genkey +

    --compresscert ref, -Z ref

    Load a certificate that has been gzipped onto the card. - ref is 9A, - 9C, 9D or - 9E

    + ref as in --genkey +

    --out file, -o file -

    Output file for any operation that produces output. + <title>Description</title>

    Output file for any operation that produces output.

    --in file, -i file @@ -1427,9 +1440,9 @@

    Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    See also

    +

    Examples

    Authenticate to the card and create History Object to use the 20 retired keys

    piv-tool -A argument -s "00:DB:3F:FF:0F:5C:03:5F:C1:0C:53:08:C1:01:14:C2:01:00:FE:00"

    See also

    opensc-tool(1) -

    Authors

    piv-tool was written by +

    Authors

    piv-tool was written by Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. From c98951f427bf8dd8805787eb48fc7dbd5cf1b0df Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 17 Feb 2026 08:26:49 -0600 Subject: [PATCH 4164/4321] Build doc/tools/tools.xml and doc/files/files.xml in source directory When building using an out of source directory, these two files are built in the source directory as both are tracked by git. --- doc/files/Makefile.am | 2 +- doc/files/files.html | 14 +++++++------- doc/tools/Makefile.am | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/files/Makefile.am b/doc/files/Makefile.am index 0a8a498b7b..e2d11f6d5a 100644 --- a/doc/files/Makefile.am +++ b/doc/files/Makefile.am @@ -28,7 +28,7 @@ pkcs15-profile.5.xml pkcs15-profile.5: $(srcdir)/pkcs15-profile.5.xml.in $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl pkcs15-profile.5.xml 2>/dev/null files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml pkcs15-profile.5.xml - $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< 2>/dev/null + $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $(srcdir)/$@ html.xsl $< 2>/dev/null %.5: $(srcdir)/%.5.xml $(AM_V_GEN)sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ diff --git a/doc/files/files.html b/doc/files/files.html index 11cfcba84c..c0868375a2 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -57,7 +57,7 @@ HKEY_LOCAL_MACHINE (if available)

  • system-wide configuration file - (/etc/opensc.conf) + (/opt/ossl-3.5.4/etc/opensc.conf)

  • The configuration file, opensc.conf, is composed @@ -146,7 +146,7 @@ directory for pkcs15-init(1). - (Default: /usr/share/opensc). + (Default: /opt/ossl-3.5.4/share/opensc).

    If this configuration value is not found on Windows, the registry key @@ -304,7 +304,7 @@ module_path = filename;

    Directory with external SM module - (Default: /usr/lib64). + (Default: /opt/ossl-3.5.4/lib).

    If this configuration value is not found on Windows, the registry key @@ -469,7 +469,7 @@

    Use specific PC/SC provider (Default: - libpcsclite.so.1). + /usr/lib/x86_64-linux-gnu/libpcsclite.so).

    Configuration of OpenCT Readers

    readers = num;

    @@ -1233,11 +1233,11 @@ PIV configuration during initialization See Configuration Options for PIV Card.

    Files

    - /etc/opensc.conf + /opt/ossl-3.5.4/etc/opensc.conf

    System-wide configuration file

    - /usr/share/doc/opensc/opensc.conf + /opt/ossl-3.5.4/share/doc/opensc/opensc.conf

    Extended example configuration file


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    @@ -1255,7 +1255,7 @@

    The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. - Profiles currently reside in /usr/share/opensc + Profiles currently reside in /opt/ossl-3.5.4/share/opensc

    Basic PKCS#15 terminology:

    1. diff --git a/doc/tools/Makefile.am b/doc/tools/Makefile.am index 6edf52510f..6b70dbaab4 100644 --- a/doc/tools/Makefile.am +++ b/doc/tools/Makefile.am @@ -14,7 +14,7 @@ endif completion_DATA = $(patsubst $(srcdir)/%.1.xml, %, $(wildcard $(srcdir)/*.1.xml)) tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml) - $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< 2>/dev/null + $(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $(srcdir)/$@ html.xsl $< 2>/dev/null %.1: $(srcdir)/%.1.xml $(AM_V_GEN)sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \ From 9171d92c41b526022f25a8b546083c4f13396599 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 18 Feb 2026 10:14:19 -0600 Subject: [PATCH 4165/4321] doc/files/files.html - match this CI --- doc/files/files.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index c0868375a2..11cfcba84c 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -57,7 +57,7 @@ HKEY_LOCAL_MACHINE (if available)

    2. system-wide configuration file - (/opt/ossl-3.5.4/etc/opensc.conf) + (/etc/opensc.conf)

    The configuration file, opensc.conf, is composed @@ -146,7 +146,7 @@ directory for pkcs15-init(1). - (Default: /opt/ossl-3.5.4/share/opensc). + (Default: /usr/share/opensc).

    If this configuration value is not found on Windows, the registry key @@ -304,7 +304,7 @@ module_path = filename;

    Directory with external SM module - (Default: /opt/ossl-3.5.4/lib). + (Default: /usr/lib64).

    If this configuration value is not found on Windows, the registry key @@ -469,7 +469,7 @@

    Use specific PC/SC provider (Default: - /usr/lib/x86_64-linux-gnu/libpcsclite.so). + libpcsclite.so.1).

    Configuration of OpenCT Readers

    readers = num;

    @@ -1233,11 +1233,11 @@ PIV configuration during initialization See Configuration Options for PIV Card.

    Files

    - /opt/ossl-3.5.4/etc/opensc.conf + /etc/opensc.conf

    System-wide configuration file

    - /opt/ossl-3.5.4/share/doc/opensc/opensc.conf + /usr/share/doc/opensc/opensc.conf

    Extended example configuration file


    Name

    pkcs15-profile — format of profile for pkcs15-init

    Description

    @@ -1255,7 +1255,7 @@

    The card specific profile contains additional information required during card initialization, such as location of PIN files, key references etc. - Profiles currently reside in /opt/ossl-3.5.4/share/opensc + Profiles currently reside in /usr/share/opensc

    Basic PKCS#15 terminology:

    1. From 5f68d370e02c8a25c1af6d10b0e0349efee9b66e Mon Sep 17 00:00:00 2001 From: Tadas Sasnauskas Date: Mon, 19 Jan 2026 16:55:24 +0200 Subject: [PATCH 4166/4321] Lithuanian Identity Card driver As far as I know there's no official/public documentation available for the card. So this is based on all kinds of guesswork, looking at other drivers, looking at Finnish, Estonian eIDs documentation. Card uses PACE authentication, so to get even the most basic details we need 6 digit card access number (CAN). On successful CAN verification pin in stored in OpenSC cache. Officially it is documented to have a single PIN code, but under the hood it's two PINs that are kept in sync. One pin is for authentication key, other - for signatures. PIN change and unblock is implemented in the 'lteid-tool'. Card ATR unfortunately does not have anything that uniquely identifies it as Lithuanian eID. To enable the driver opensc.conf should include 'card_atr' section: card_atr 3b:9d:18:81:31:fc:35:80:31:c0:69:4d:54:43:4f:53:73:02:00:00:00 { atrmask = ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00; driver = lteid; type = 43000; } Card also includes card holder details like full name, date of birth, national identification number, black and white photo. But for now that's not implemented. My goal here is authentication with public gov services. Confirmed working with: - TLS client certificates - was able to sign in to a gov website. - SSH, both key for signatures and for auth. SSH working is not really a goal of this, but it's a reasonable test. - Gov document signing app at https://adoc.archyvai.lt/eais-lpp/ (requires additional software). --- doc/files/files.html | 14 +- doc/files/opensc.conf.5.xml.in | 22 ++ doc/tools/lteid-tool.1.xml | 200 +++++++++++ doc/tools/tools.html | 227 +++++++++---- doc/tools/tools.xml | 1 + packaging/opensc.spec | 2 + src/libopensc/Makefile.am | 10 +- src/libopensc/Makefile.mak | 3 +- src/libopensc/card-lteid.c | 591 +++++++++++++++++++++++++++++++++ src/libopensc/cards.h | 4 + src/libopensc/ctx.c | 1 + src/libopensc/pkcs15-lteid.c | 76 +++++ src/libopensc/pkcs15-syn.c | 2 + src/libopensc/pkcs15-syn.h | 1 + src/libopensc/pkcs15.c | 1 + src/tools/Makefile.am | 6 +- src/tools/lteid-tool.c | 562 +++++++++++++++++++++++++++++++ win32/Make.rules.mak | 2 +- 18 files changed, 1644 insertions(+), 81 deletions(-) create mode 100644 doc/tools/lteid-tool.1.xml create mode 100644 src/libopensc/card-lteid.c create mode 100644 src/libopensc/pkcs15-lteid.c create mode 100644 src/tools/lteid-tool.c diff --git a/doc/files/files.html b/doc/files/files.html index 11cfcba84c..b3c66049f2 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -584,7 +584,19 @@ directory file_cache_dir. The cached CAN is used later to avoid interactively prompting for the CAN. This feature is enabled by default. -

    Configuration Options for PIV Card

    Configuration based on ATR

    +

    Configuration Options for PIV Card

    Configuration Options for Lithuanian ID Card

    + can = value; +

    + Lithuanian ID card requires the card access + number (CAN) to be verified before reading it or + performing any operation. It is printed on the + front side bottom right corner of the card. +

    + Note that alternatively it can also be set by + lteid-tool. For command + line tools it can also be provided via + LTEID_CAN environment variable. +

    Configuration based on ATR

    atrmask = hexstring;

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index b029f670d0..a91bef92d3 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -929,6 +929,28 @@ app application { + + Configuration Options for Lithuanian ID Card + + + + + + + Lithuanian ID card requires the card access + number (CAN) to be verified before reading it or + performing any operation. It is printed on the + front side bottom right corner of the card. + + Note that alternatively it can also be set by + lteid-tool. For command + line tools it can also be provided via + LTEID_CAN environment variable. + + + + + Configuration based on ATR diff --git a/doc/tools/lteid-tool.1.xml b/doc/tools/lteid-tool.1.xml new file mode 100644 index 0000000000..02a9cca314 --- /dev/null +++ b/doc/tools/lteid-tool.1.xml @@ -0,0 +1,200 @@ + + + + lteid-tool + 1 + OpenSC + OpenSC Tools + opensc + + + + lteid-tool + Lithuanian National eID card (asmens tapatybÄ—s kortelÄ—) utility + + + + + lteid-tool + OPTIONS + + + + + Description + + The lteid-tool utility is used to set up Lithuanian National eID card access; + unblock it after incorrect PIN entry attempts. + + + When invoked without any options, lteid-tool will try to determine if card is + ready for use or card access number (CAN) needs to be entered first. Card access number is a 6 + digit number printed on the front side bottom right corner of the card. Type it in and it will + be persisted for subsequent uses of the card. + + + + + Options + + + + + , + + + Display tool options. + + + + + , + + + Causes lteid-tool to be more verbose. + Specify this flag several times to enable debug output. + + + + + arg, + arg + + + + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen. + + + + + + + , + + + Causes lteid-tool to wait for the token + to be inserted into reader. + + + + + + can + can + + + + This option can be used to specify the CAN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. + + + + + + + pin + pin + + + + This option can be used to specify the PIN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. + + + + + + + puk + puk + + + + This option can be used to specify the PUK value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. + + + + + + + + + + + + Change PIN. + + + + + + + + + + + + Resume eID PIN use after 2 incorrect attempts using current PIN. + + + + + + + + + + + + Unblock eID PIN use after 3 incorrect attempts using PUK. + + + + + + + + + + + + Verify Card Access Number (CAN). Use with + --can=XXXXXX option to + non-interactively verify and store CAN. + + + + + + + + + See also + + + opensc.conf + 5 + + + + + + Authors + lteid-tool was written by + Tadas Sasnauskas tadas@yoyo.lt. + + + diff --git a/doc/tools/tools.html b/doc/tools/tools.html index ca71e96be6..f34b9992ac 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -47,7 +47,7 @@

    cryptoflex-tool — utility for manipulating Schlumberger Cryptoflex data structures
    dnie-tool — displays information about DNIe based security tokens
    egk-tool — displays information on the German electronic health card (elektronische Gesundheitskarte, eGK)
    eidenv — utility for accessing visible data from electronic identity cards
    gids-tool — smart card utility for GIDS cards
    iasecc-tool — displays information about IAS/ECC card -
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information of an ID card or ePassport. +
    lteid-tool — Lithuanian National eID card (asmens tapatybės kortelė) utility
    netkey-tool — administrative utility for Netkey E4 cards
    npa-tool — displays information of an ID card or ePassport.
    openpgp-tool — utility for accessing visible data OpenPGP smart cards and compatible tokens
    opensc-asn1 — parse ASN.1 data
    opensc-explorer — @@ -376,11 +376,92 @@

    Causes iasecc-tool to wait for the token to be inserted into reader.

    Authors

    iasecc-tool was written by - Viktor Tarasov .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the + Viktor Tarasov .


    Name

    lteid-tool — Lithuanian National eID card (asmens tapatybės kortelė) utility

    Synopsis

    lteid-tool [OPTIONS]

    Description

    + The lteid-tool utility is used to set up Lithuanian National eID card access; + unblock it after incorrect PIN entry attempts. +

    + When invoked without any options, lteid-tool will try to determine if card is + ready for use or card access number (CAN) needs to be entered first. Card access number is a 6 + digit number printed on the front side bottom right corner of the card. Type it in and it will + be persisted for subsequent uses of the card. +

    Options

    +

    + --help, + -h +

    Display tool options.

    + --verbose, + -v +

    Causes lteid-tool to be more verbose. + Specify this flag several times to enable debug output.

    + --reader arg, + -r arg +

    + Number of the reader to use. By default, the first + reader with a present card is used. If + arg is an ATR, the + reader with a matching card will be chosen. +

    + --wait, + -w +

    Causes lteid-tool to wait for the token + to be inserted into reader.

    + --can can + -c can +

    + This option can be used to specify the CAN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + --pin pin + -p pin +

    + This option can be used to specify the PIN value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + --puk puk + -u puk +

    + This option can be used to specify the PUK value + on the command line. If the value is set to + env:VARIABLE, the value + of the specified environment variable is used. By default, + the code is prompted on the command line if needed. +

    + --change-pin + -C +

    + Change PIN. +

    + --resume + -R +

    + Resume eID PIN use after 2 incorrect attempts using current PIN. +

    + --unblock + -U +

    + Unblock eID PIN use after 3 incorrect attempts using PUK. +

    + --verify-can + -V +

    + Verify Card Access Number (CAN). Use with + --can=XXXXXX option to + non-interactively verify and store CAN. +

    +

    See also

    + opensc.conf(5) +

    Authors

    lteid-tool was written by + Tadas Sasnauskas .


    Name

    netkey-tool — administrative utility for Netkey E4 cards

    Synopsis

    netkey-tool [OPTIONS] [COMMAND]

    Description

    The netkey-tool utility can be used from the command line to perform some smart card operations with NetKey E4 cards that cannot be done easily with other OpenSC-tools, such as changing local PINs, storing certificates into empty NetKey E4 cert-files or displaying - the initial PUK-value.

    Options

    + the initial PUK-value.

    Options

    --help, -h @@ -408,11 +489,11 @@ -v

    Causes netkey-tool to be more verbose. This options may be specified multiple times to increase verbosity.

    -

    PIN format

    With the -p, -u, -0 or the -1 +

    PIN format

    With the -p, -u, -0 or the -1 one of the cards pins may be specified. You may use plain ascii-strings (i.e. 123456) or a hex-string (i.e. 31:32:33:34:35:36). A hex-string must consist of exactly n 2-digit hexnumbers separated by n-1 colons. Otherwise it will be interpreted as an ascii string. For example :12:34: and 1:2:3:4 are both pins of - length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

    Commands

    When used without any options or commands, netkey-tool will + length 7, while 12:34 and 01:02:03:04 are pins of length 2 and 4.

    Commands

    When used without any options or commands, netkey-tool will display information about the smart cards pins and certificates. This will not change your card in any aspect (assumed there are no bugs in netkey-tool). In particular the tries-left counters of the pins are investigated without doing @@ -456,11 +537,11 @@

    This unblocks the specified pin. You must specify another pin to be able to do this and if you don't specify a correct one, netkey-tool will tell you which one is needed.

    -

    See also

    +

    See also

    opensc-explorer(1) -

    Authors

    netkey-tool was written by +

    Authors

    netkey-tool was written by Peter Koch .


    Name

    npa-tool — displays information of an ID card or ePassport. -

    Synopsis

    npa-tool [OPTIONS]

    Description

    +

    Synopsis

    npa-tool [OPTIONS]

    Description

    The npa-tool utility is used to display information stored on an ID card or on a passport and to perform some write and verification operations. @@ -470,7 +551,7 @@ travel document (MRTD) as well as EAC compliant ID cards, for example the German ID card (neuer Personalausweis, nPA), may be read. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    @@ -490,7 +571,7 @@ Causes npa-tool to be more verbose. Specify this flag several times to be more verbose.

    -

    Password Authenticated Connection Establishment (PACE)

    +

    Password Authenticated Connection Establishment (PACE)

    --pin [STRING], -p [STRING]

    @@ -517,7 +598,7 @@ and NEWPIN. You may want to clean your environment before enabling this. (default=off) -

    PIN management

    +

    PIN management

    --new-pin [STRING], -N [STRING]

    @@ -534,7 +615,7 @@

    Unblock PIN (uses PUK to activate three more retries). (default=off) -

    Terminal Authentication (TA) and Chip Authentication (CA)

    +

    Terminal Authentication (TA) and Chip Authentication (CA)

    --cv-certificate FILENAME, -C FILENAME

    @@ -578,21 +659,21 @@ (default=off)

    --disable-ca-checks

    Disable passive authentication. (default=off) -

    Card application

    --application app

    +

    Card application

    --application app

    What application to select on the card, use eID for the electronic identification application and eMRTD for the ePassport application. (default=eID) -

    Read and write data groups

    --read-all-dgs

    Read all available data groups.

    --read-dg1

    Read data group 1.

    --read-dg2

    Read data group 2.

    --read-dg3

    Read data group 3.

    --read-dg4

    Read data group 4.

    --read-dg5

    Read data group 5.

    --read-dg6

    Read data group 6.

    --read-dg7

    Read data group 7.

    --read-dg8

    Read data group 8.

    --read-dg9

    Read data group 9.

    --read-dg10

    Read data group 10.

    --read-dg11

    Read data group 11.

    --read-dg12

    Read data group 12.

    --read-dg13

    Read data group 13.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17.

    --read-dg18

    Read data group 18.

    --read-dg19

    Read data group 19.

    --read-dg20

    Read data group 20.

    --read-dg21

    Read data group 21.

    +

    Read and write data groups

    --read-all-dgs

    Read all available data groups.

    --read-dg1

    Read data group 1.

    --read-dg2

    Read data group 2.

    --read-dg3

    Read data group 3.

    --read-dg4

    Read data group 4.

    --read-dg5

    Read data group 5.

    --read-dg6

    Read data group 6.

    --read-dg7

    Read data group 7.

    --read-dg8

    Read data group 8.

    --read-dg9

    Read data group 9.

    --read-dg10

    Read data group 10.

    --read-dg11

    Read data group 11.

    --read-dg12

    Read data group 12.

    --read-dg13

    Read data group 13.

    --read-dg14

    Read data group 14.

    --read-dg15

    Read data group 15.

    --read-dg16

    Read data group 16.

    --read-dg17

    Read data group 17.

    --read-dg18

    Read data group 18.

    --read-dg19

    Read data group 19.

    --read-dg20

    Read data group 20.

    --read-dg21

    Read data group 21.

    --write-dg17 HEX_STRING

    Write data group 17.

    --write-dg18 HEX_STRING

    Write data group 18.

    --write-dg19 HEX_STRING

    Write data group 19.

    - --write-dg20 HEX_STRING

    Write data group 20.

    --write-dg21 HEX_STRING

    Write data group 21.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    + --write-dg20 HEX_STRING

    Write data group 20.

    --write-dg21 HEX_STRING

    Write data group 21.

    Verification of validity, age and community ID

    --verify-validity YYYYMMDD

    Verify chip's validity with a reference date.

    --older-than YYYYMMDD

    Verify age with a reference date.

    --verify-community HEX_STRING

    Verify community ID with a reference ID. -

    Special options, not always useful

    +

    Special options, not always useful

    --break, -b

    @@ -611,9 +692,9 @@ Force compliance to BSI TR-03110 version 2.01. (default=off)

    --disable-all-checks

    Disable all checking of fly-by-data. (default=off) -

    Authors

    npa-tool was written by +

    Authors

    npa-tool was written by Frank Morgner .


    Name

    openpgp-tool — utility for accessing visible data OpenPGP smart cards - and compatible tokens

    Synopsis

    openpgp-tool [OPTIONS]

    Description

    + and compatible tokens

    Synopsis

    openpgp-tool [OPTIONS]

    Description

    The openpgp-tool utility is used for accessing data from the OpenPGP v1.1 and v2.0 smart cards and compatible tokens like e.g. GPF CryptoStick v1.x, @@ -621,7 +702,7 @@ PKCS#15 objects but available in custom files on the card. The data can be printed on screen or used by other programs via environment variables. -

    Options

    +

    Options

    --card-info, -C @@ -742,21 +823,21 @@

    Wait for a card to be inserted.

    -

    Authors

    openpgp-tool utility was written by +

    Authors

    openpgp-tool utility was written by Peter Marschall .


    Name

    opensc-asn1 — parse ASN.1 data -

    Synopsis

    opensc-asn1 [OPTIONS] [FILES]

    Description

    +

    Synopsis

    opensc-asn1 [OPTIONS] [FILES]

    Description

    The opensc-asn1 utility is used to parse ASN.1 data. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    --version, -V

    Print version and exit.

    -

    Authors

    opensc-asn1 was written by +

    Authors

    opensc-asn1 was written by Frank Morgner .


    Name

    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions -

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    +

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    The opensc-explorer utility can be used to perform miscellaneous operations such as exploring the contents of or sending arbitrary @@ -768,7 +849,7 @@ one command per line. If no script is given, opensc-explorer runs in interactive mode, reading commands from standard input. -

    Options

    +

    Options

    The following are the command-line options for opensc-explorer. There are additional interactive commands available once it is running. @@ -809,7 +890,7 @@

    Wait for a card to be inserted.

    -

    Commands

    +

    Commands

    opensc-explorer supports commands with arguments at its interactive prompt or in script files passed via the command line parameter SCRIPT. @@ -1214,20 +1295,20 @@ Call the card's open or close Secure Messaging handler.

    -

    See also

    +

    See also

    opensc-tool(1) -

    Authors

    opensc-explorer was written by +

    Authors

    opensc-explorer was written by Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications -

    Synopsis

    opensc-notify [OPTIONS]

    Description

    +

    Synopsis

    opensc-notify [OPTIONS]

    Description

    The opensc-notify utility is used to monitor smart card events and send the appropriate notification. -

    Options

    +

    Options

    --help, -h

    Print help and exit.

    --version, -V

    Print version and exit.

    -

    Mode: customized

    +

    Mode: customized

    Send customized notifications.

    --title [STRING], @@ -1239,7 +1320,7 @@ -m [STRING]

    Specify the main text of the notification. -

    Mode: standard

    +

    Mode: standard

    Manually send standard notifications.

    --notify-card-inserted, @@ -1261,12 +1342,12 @@ -B

    See notify_pin_bad in opensc.conf (default=off). -

    Authors

    opensc-notify was written by - Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    +

    Authors

    opensc-notify was written by + Frank Morgner .


    Name

    opensc-tool — generic smart card utility

    Synopsis

    opensc-tool [OPTIONS]

    Description

    The opensc-tool utility can be used from the command line to perform miscellaneous smart card operations such as getting the card ATR or sending arbitrary APDU commands to a card. -

    Options

    +

    Options

    --version

    Print the OpenSC package release version.

    @@ -1339,10 +1420,10 @@ --wait, -w

    Wait for a card to be inserted.

    -

    See also

    +

    See also

    opensc-explorer(1) -

    Authors

    opensc-tool was written by - Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    Description

    +

    Authors

    opensc-tool was written by + Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    Options

    +

    Options

    Description

    --serial

    Print the card serial number derived from the CHUID object, @@ -1440,16 +1521,16 @@

    Causes piv-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    Examples

    Authenticate to the card and create History Object to use the 20 retired keys

    piv-tool -A argument -s "00:DB:3F:FF:0F:5C:03:5F:C1:0C:53:08:C1:01:14:C2:01:00:FE:00"

    See also

    +

    Examples

    Authenticate to the card and create History Object to use the 20 retired keys

    piv-tool -A argument -s "00:DB:3F:FF:0F:5C:03:5F:C1:0C:53:08:C1:01:14:C2:01:00:FE:00"

    See also

    opensc-tool(1) -

    Authors

    piv-tool was written by - Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    +

    Authors

    piv-tool was written by + Douglas E. Engert .


    Name

    pkcs11-tool — utility for managing and using PKCS #11 security tokens

    Synopsis

    pkcs11-tool [OPTIONS]

    Description

    The pkcs11-tool utility is used to manage the data objects on smart cards and similar PKCS #11 security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --attr-from filename

    Extract information from filename @@ -1755,7 +1836,7 @@

    Specify the PKCS#11 URI for module, slot, token or object

    --uri-with-slot-id

    Include SlotId in PKCS#11 URI

    -

    Examples

    +

    Examples

    Perform a basic functionality test of the card:

    pkcs11-tool --test --login

    @@ -1850,13 +1931,13 @@

     pkcs11-tool --login --login-type so --init-pin
     				

    -

    Authors

    pkcs11-tool was written by - Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    +

    Authors

    pkcs11-tool was written by + Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing digital signatures or decrypting data, using keys stored on a PKCS#15 compliant smart card. -

    Options

    +

    Options

    --version,

    Print the OpenSC package release version.

    @@ -1953,18 +2034,18 @@

    Causes pkcs15-crypt to be more verbose. Specify this flag several times to enable debug output in the OpenSC library.

    -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-tool(1) -

    Authors

    pkcs15-crypt was written by - Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    +

    Authors

    pkcs15-crypt was written by + Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles.

    The profile used by default is pkcs15. Alternative profiles can be specified via the -p switch. -

    PIN Usage

    +

    PIN Usage

    pkcs15-init can be used to create a PKCS #15 structure on your smart card, create PINs, and install keys and certificates on the card. This process is also called personalization. @@ -1996,7 +2077,7 @@ are protected and cannot be parsed without authentication (usually with User PIN). This authentication need to be done immediately after the card binding. In such cases --verify-pin has to be used. -

    Modes of operation

    Initialization

    This is the first step during card personalization, and will create the +

    Modes of operation

    Initialization

    This is the first step during card personalization, and will create the basic files on the card. To create the initial PKCS #15 structure, invoke the utility as

    @@ -2006,7 +2087,7 @@

    If the card supports it, you should erase the contents of the card with pkcs15-init --erase-card before creating the PKCS#15 structure. -

    User PIN Installation

    +

    User PIN Installation

    Before installing any user objects such as private keys, you need at least one PIN to protect these objects. you can do this using

    @@ -2020,7 +2101,7 @@

    To set a label for this PIN object (which can be used by applications to display a meaningful prompt to the user), use the --label command line option. -

    Key generation

    +

    Key generation

    pkcs15-init lets you generate a new key and store it on the card. You can do this using:

    @@ -2045,7 +2126,7 @@ In addition to storing the private portion of the key on the card, pkcs15-init will also store the public portion of the key as a PKCS #15 public key object. -

    Private Key Upload

    +

    Private Key Upload

    You can use a private key generated by other means and upload it to the card. For instance, to upload a private key contained in a file named okir.pem, which is in PEM format, you would use @@ -2069,7 +2150,7 @@ a file. A PKCS #12 file usually contains the X.509 certificate corresponding to the private key. If that is the case, pkcs15-init will store the certificate instead of the public key portion. -

    Public Key Upload

    +

    Public Key Upload

    You can also upload individual public keys to the card using the --store-public-key option, which takes a filename as an argument. This file is supposed to contain the public key. If you don't @@ -2080,12 +2161,12 @@ Since the corresponding public keys are always uploaded automatically when generating a new key, or when uploading a private key, you will probably use this option only very rarely. -

    Certificate Upload

    +

    Certificate Upload

    You can upload certificates to the card using the --store-certificate option, which takes a filename as an argument. This file is supposed to contain the PEM encoded X.509 certificate. -

    Uploading PKCS #12 bags

    +

    Uploading PKCS #12 bags

    Most browsers nowadays use PKCS #12 format files when you ask them to export your key and certificate to a file. pkcs15-init is capable of parsing these files, and storing their contents on the @@ -2099,7 +2180,7 @@ and protect it with the PIN referenced by authentication ID 01. It will also store any X.509 certificates contained in the file, which is usually the user certificate that goes with the key, as well as the CA certificate. -

    Secret Key Upload

    +

    Secret Key Upload

    You can use a secret key generated by other means and upload it to the card. For instance, to upload an AES-secret key generated by the system random generator you would use @@ -2108,7 +2189,7 @@

    By default a random ID is generated for the secret key. You may specify an ID with the --id if needed. -

    Options

    +

    Options

    --version,

    Print the OpenSC package release version.

    @@ -2447,17 +2528,17 @@

    Display help message

    -

    See also

    +

    See also

    pkcs15-profile(5) -

    Authors

    pkcs15-init was written by +

    Authors

    pkcs15-init was written by Olaf Kirch .


    Name

    pkcs15-tool — utility for manipulating PKCS #15 data structures - on smart cards and similar security tokens

    Synopsis

    pkcs15-tool [OPTIONS]

    Description

    + on smart cards and similar security tokens

    Synopsis

    pkcs15-tool [OPTIONS]

    Description

    The pkcs15-tool utility is used to manipulate the PKCS #15 data structures on smart cards and similar security tokens. Users can list and read PINs, keys and certificates stored on the token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --version

    Print the OpenSC package release version.

    @@ -2605,16 +2686,16 @@ wait for a card insertion.

    --use-pinpad

    Do not prompt the user; if no PINs supplied, pinpad will be used.

    -

    See also

    +

    See also

    pkcs15-init(1), pkcs15-crypt(1) -

    Authors

    pkcs15-tool was written by - Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    +

    Authors

    pkcs15-tool was written by + Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import Device Key Encryption Key (DKEK) shares and to wrap and unwrap keys. -

    Options

    +

    Options

    --initialize, -X @@ -2727,16 +2808,16 @@

    Causes sc-hsm-tool to be more verbose. Specify this flag several times to enable debug output in the opensc library.

    -

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    Initialize SmartCard-HSM to use M-of-N public key authentication with M=2 and N=5

    sc-hsm-tool --initialize --required-pub-keys 2 --public-key-auth 5

    Export a public key for M-of-N public key authentication to a file

    sc-hsm-tool --key-reference 1 --export-for-pub-key-auth ./public_key1.asn1

    Register a public key for M-of-N public key authentication from a file

    sc-hsm-tool --register-public-key ./public_key1.asn1

    See also

    +

    Examples

    Create a DKEK share:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe

    Create a DKEK share with random password split up using a (3, 5) threshold scheme:

    sc-hsm-tool --create-dkek-share dkek-share-1.pbe --pwd-shares-threshold 3 --pwd-shares-total 5

    Initialize SmartCard-HSM to use a single DKEK share:

    sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1 --label mytoken

    Import DKEK share:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe

    Import DKEK share using a password split up using a (3, 5) threshold scheme for encryption:

    sc-hsm-tool --import-dkek-share dkek-share-1.pbe --pwd-shares-total 3

    Wrap referenced key, description and certificate:

    sc-hsm-tool --wrap-key wrap-key.bin --key-reference 1 --pin 648219

    Unwrap key into same or in different SmartCard-HSM with the same DKEK:

    sc-hsm-tool --unwrap-key wrap-key.bin --key-reference 10 --pin 648219 --force

    Initialize SmartCard-HSM to use M-of-N public key authentication with M=2 and N=5

    sc-hsm-tool --initialize --required-pub-keys 2 --public-key-auth 5

    Export a public key for M-of-N public key authentication to a file

    sc-hsm-tool --key-reference 1 --export-for-pub-key-auth ./public_key1.asn1

    Register a public key for M-of-N public key authentication from a file

    sc-hsm-tool --register-public-key ./public_key1.asn1

    See also

    opensc-tool(1) -

    Authors

    sc-hsm-tool was written by +

    Authors

    sc-hsm-tool was written by Andreas Schwier .


    Name

    westcos-tool — utility for manipulating data structures - on westcos smart cards

    Synopsis

    westcos-tool [OPTIONS]

    Description

    + on westcos smart cards

    Synopsis

    westcos-tool [OPTIONS]

    Description

    The westcos-tool utility is used to manipulate the westcos data structures on 2 Ko smart cards / tokens. Users can create PINs, keys and certificates stored on the card / token. User PIN authentication is performed for those operations that require it. -

    Options

    +

    Options

    --change-pin, -n @@ -2824,5 +2905,5 @@ from disk to card. On the card the file is written in filename. User authentication is required for this operation.

    -

    Authors

    westcos-tool was written by +

    Authors

    westcos-tool was written by Francois Leblanc .

    diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml index 36d39c8cfe..d23ab7a5fd 100644 --- a/doc/tools/tools.xml +++ b/doc/tools/tools.xml @@ -12,6 +12,7 @@ + diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 2c74fba897..4141bc06a2 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -174,6 +174,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_bindir}/egk-tool %{_bindir}/goid-tool %{_bindir}/dtrust-tool +%{_bindir}/lteid-tool %{_datadir}/opensc/ %{_mandir}/man1/cardos-tool.1* %{_mandir}/man1/cryptoflex-tool.1* @@ -199,6 +200,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_mandir}/man1/dnie-tool.1* %{_mandir}/man1/egk-tool.1* %{_mandir}/man1/dtrust-tool.1* +%{_mandir}/man1/lteid-tool.1* %{_mandir}/man5/pkcs15-profile.5* %files libs diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 53d4491b4d..148a50707d 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -51,6 +51,7 @@ libopensc_la_SOURCES_BASE = \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c card-esteid2018.c card-esteid2025.c card-idprime.c \ card-edo.c card-nqApplet.c card-skeid.c card-eoi.c card-dtrust.c \ + card-lteid.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c pkcs15-tcos.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ @@ -58,8 +59,8 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c pkcs15-dtrust.c compression.c sm.c \ - aux-data.c + pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c pkcs15-dtrust.c pkcs15-lteid.c \ + compression.c sm.c aux-data.c if ENABLE_CRYPTOTOKENKIT # most platforms don't support objective C the way we needed. @@ -132,6 +133,7 @@ TIDY_FILES = \ card-isoApplet.c card-masktech.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ card-edo.c card-nqApplet.c card-skeid.c card-eoi.c card-dtrust.c \ + card-lteid.c \ \ pkcs15-openpgp.c pkcs15-cardos.c pkcs15-tcos.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c \ @@ -139,8 +141,8 @@ TIDY_FILES = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-dtrust.c compression.c sm.c \ - aux-data.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-dtrust.c pkcs15-lteid.c \ + compression.c sm.c aux-data.c \ #$(SOURCES) check-local: diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 026fe52b80..6bb0fa4dae 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -29,6 +29,7 @@ OBJECTS = \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj card-esteid2018.obj card-esteid2025.obj card-idprime.obj \ card-edo.obj card-nqApplet.obj card-skeid.obj card-eoi.obj card-dtrust.obj \ + card-lteid.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj pkcs15-tcos.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ @@ -37,7 +38,7 @@ OBJECTS = \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-esteid2025.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj pkcs15-dtrust.obj \ - compression.obj sm.obj aux-data.obj \ + pkcs15-lteid.obj compression.obj sm.obj aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\common\common.lib \ diff --git a/src/libopensc/card-lteid.c b/src/libopensc/card-lteid.c new file mode 100644 index 0000000000..ba9d54376b --- /dev/null +++ b/src/libopensc/card-lteid.c @@ -0,0 +1,591 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) + +#include +#include + +#include "asn1.h" +#include "common/compat_strlcat.h" +#include "internal.h" +#include "opensc.h" +#include "sm/sm-eac.h" + +static const struct sc_card_operations *iso_ops = NULL; +static struct sc_card_operations lteid_ops; + +static struct sc_card_driver lteid_drv = { + "Lithuanian eID card (asmens tapatybÄ—s kortelÄ—)", "lteid", + <eid_ops, NULL, 0, NULL}; + +#define DRVDATA(card) ((struct lteid_drv_data *)((card)->drv_data)) +#define LTEID_CAN_LENGTH 6 + +struct lteid_drv_data { + unsigned char pace; + unsigned char pace_pin_ref; + unsigned char can[LTEID_CAN_LENGTH]; + unsigned char can_from_cache; +}; + +void +lteid_get_can_cache_path(sc_card_t *card, char *buf, size_t buf_len) +{ + sc_get_cache_dir(card->ctx, buf, buf_len); + +#ifdef _WIN32 + strlcat(buf, "\\", buf_len); +#else + strlcat(buf, "/", buf_len); +#endif + + strlcat(buf, "lteid_can", buf_len); +} + +static int +lteid_get_cached_can(sc_card_t *card, unsigned char *can) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + char path[PATH_MAX]; + + lteid_get_can_cache_path(card, path, sizeof(path)); + + FILE *fd = fopen(path, "r"); + + if (!fd) { + LOG_FUNC_RETURN(card->ctx, 0); + } + + if (LTEID_CAN_LENGTH != fread(can, 1, LTEID_CAN_LENGTH, fd)) { + LOG_FUNC_RETURN(card->ctx, 0); + } + + fclose(fd); + + LOG_FUNC_RETURN(card->ctx, 1); +} + +static int +lteid_cache_can(sc_card_t *card, const char *can) +{ + int rv; + char path[PATH_MAX]; + + lteid_get_can_cache_path(card, path, sizeof(path)); + + FILE *fd = fopen(path, "w"); + + if (!fd && errno == ENOENT) { + if ((rv = sc_make_cache_dir(card->ctx)) < 0) + return rv; + + fd = fopen(path, "w"); + } + + if (!fd) { + return SC_ERROR_INTERNAL; + } + + fwrite(can, 1, 6, fd); + fclose(fd); + + return SC_SUCCESS; +} + +static int +lteid_clear_cached_can(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + char path[PATH_MAX]; + + lteid_get_can_cache_path(card, path, sizeof(path)); + + if (!unlink(path)) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_get_can(sc_card_t *card, struct establish_pace_channel_input *pace_input) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + struct lteid_drv_data *drv_data = DRVDATA(card); + int got_can = 0; + + drv_data->can_from_cache = 0; + + // Try env variables first + const char *can_from_env = getenv("LTEID_CAN"); + if (can_from_env && strlen(can_from_env) == LTEID_CAN_LENGTH) { + got_can = 1; + memcpy(drv_data->can, can_from_env, LTEID_CAN_LENGTH); + } + + // Try getting one from the cache + if (!got_can && lteid_get_cached_can(card, drv_data->can)) { + got_can = 1; + drv_data->can_from_cache = 1; + } + + // Finally see if there is a default in configuration + if (!got_can) { + const char *can_from_config = NULL; + + for (size_t i = 0; card->ctx->conf_blocks[i]; ++i) { + scconf_block **blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], "card_driver", "lteid"); + if (!blocks) + continue; + for (size_t j = 0; blocks[j]; ++j) + if ((can_from_config = scconf_get_str(blocks[j], "can", NULL))) + break; + free(blocks); + } + + if (can_from_config && strlen(can_from_config) == LTEID_CAN_LENGTH) { + got_can = 1; + memcpy(drv_data->can, can_from_config, LTEID_CAN_LENGTH); + } + } + + if (!got_can) { + sc_log(card->ctx, "Missing or invalid CAN. 6 digits required."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN); + } + + pace_input->pin_id = PACE_PIN_ID_CAN; + pace_input->pin = drv_data->can; + pace_input->pin_length = LTEID_CAN_LENGTH; + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_perform_pace(struct sc_card *card, const int ref, const unsigned char *pin, size_t pinlen, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + struct lteid_drv_data *drv_data = DRVDATA(card); + struct establish_pace_channel_input pace_input = {0}; + struct establish_pace_channel_output pace_output = {0}; + + if (drv_data->pace) { + sc_sm_stop(card); + drv_data->pace = 0; + drv_data->pace_pin_ref = 0; + } + + if (ref == PACE_PIN_ID_CAN && !pin) { + if (SC_SUCCESS != lteid_get_can(card, &pace_input)) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN); + } + } else { + pace_input.pin_id = ref; + pace_input.pin = pin; + pace_input.pin_length = pinlen; + } + + int rv = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); + if (rv != SC_SUCCESS) { + sc_log(card->ctx, "Error performing PACE for pin ref 0x%02x.", ref); + + drv_data->pace = 0; + drv_data->pace_pin_ref = 0; + + // Special case after entering incorrect PACE PIN twice. Card locks with 1 PIN attempt remaining. + if (ref == PACE_PIN_ID_PIN && rv == SC_ERROR_NO_CARD_SUPPORT) { + rv = SC_ERROR_AUTH_METHOD_BLOCKED; + } + + // When CAN code authentication fails and CAN code comes from cache - clear it. + // We don't want to make multiple attempts if code is wrong. User should run lteid-tool + // again to set up the card. + if (ref == PACE_PIN_ID_CAN && drv_data->can_from_cache && rv != SC_ERROR_INTERNAL) { + if (lteid_clear_cached_can(card)) { + drv_data->can_from_cache = 0; + } + } + + LOG_FUNC_RETURN(card->ctx, rv); + } + + // If caller provided CAN is valid - cache it. + if (ref == PACE_PIN_ID_CAN && pin) { + lteid_cache_can(card, (const char *)pin); + } + + // Track PACE status + drv_data->pace = 1; + drv_data->pace_pin_ref = ref; + + free(pace_output.ef_cardaccess); + free(pace_output.recent_car); + free(pace_output.previous_car); + free(pace_output.id_icc); + free(pace_output.id_pcd); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_unlock(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (SC_SUCCESS != lteid_perform_pace(card, PACE_PIN_ID_CAN, NULL, 0, NULL)) { + sc_log(card->ctx, "Unlock with CAN code failed. No CAN found in environment, opensc.conf nor cache."); + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_init(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + int rv; + + struct lteid_drv_data *drv_data = calloc(1, sizeof(struct lteid_drv_data)); + + if (drv_data == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + + drv_data->pace = 0; + drv_data->pace_pin_ref = 0; + card->drv_data = drv_data; + + memset(&card->sm_ctx, 0, sizeof card->sm_ctx); + + card->max_send_size = 65535; + card->max_recv_size = 65535; + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO | SC_CARD_CAP_APDU_EXT; + + _sc_card_add_ec_alg(card, 384, SC_ALGORITHM_ECDSA_HASH_NONE | SC_ALGORITHM_ECDSA_RAW, 0, NULL); + + rv = sc_enum_apps(card); + LOG_TEST_RET(card->ctx, rv, "Enumerate apps failed"); + + rv = lteid_unlock(card); + LOG_TEST_RET(card->ctx, rv, "Unlock card failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_finish(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + sc_sm_stop(card); + + free(card->drv_data); + card->drv_data = NULL; + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_logout(sc_card_t *card) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + sc_sm_stop(card); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + int rv; + + // Authentication key refers to PACE PIN -> 0x03 + // Meanwhile, signing key refers to PIN.QES -> 0x81. This pin is verifiable via regular iso7816 cmd verify call. + switch (data->pin_reference) { + case PACE_PIN_ID_CAN: + case PACE_PIN_ID_PIN: + case PACE_PIN_ID_PUK: + rv = lteid_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, tries_left); + break; + default: + rv = iso_ops->pin_cmd(card, data, tries_left); + break; + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int +lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + struct lteid_drv_data *drv_data = DRVDATA(card); + int rv; + + // PACE CAN code info: as far as we know there's no limit to CAN verification attempts + if (data->pin_reference == PACE_PIN_ID_CAN) { + data->pin1.max_tries = -1; + data->pin1.tries_left = -1; + + if (tries_left) { + *tries_left = -1; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + + // PACE PIN and PUK codes: max and remaining attempts are stored in ACE3 and ACE4 files. + if (data->pin_reference == PACE_PIN_ID_PIN || data->pin_reference == PACE_PIN_ID_PUK) { + struct sc_apdu apdu; + unsigned char buf[0xbe] = {0}; + u8 id[] = {0xac, 0x00}; + size_t taglen = 0; + + switch (data->pin_reference) { + case PACE_PIN_ID_PIN: + id[1] = 0xe3; + break; + case PACE_PIN_ID_PUK: + id[1] = 0xe4; + break; + default: + break; + } + + sc_format_apdu_ex(&apdu, 0x00, 0xa4, 0x00, 0x04, id, sizeof(id), buf, sizeof(buf)); + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + const u8 *tag = sc_asn1_find_tag(card->ctx, buf, apdu.resplen, 0x62, &taglen); + tag = sc_asn1_find_tag(card->ctx, tag, taglen, 0xa5, &taglen); + tag = sc_asn1_find_tag(card->ctx, tag, taglen, 0xa2, &taglen); + tag = sc_asn1_find_tag(card->ctx, tag, taglen, 0xa3, &taglen); + tag = sc_asn1_find_tag(card->ctx, tag, taglen, 0x82, &taglen); + + if (tag && taglen == 2) { + data->pin1.tries_left = tag[0]; + data->pin1.max_tries = tag[1]; + + if (tries_left) { + *tries_left = data->pin1.tries_left; + } + } else { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); + } + + if (drv_data->pace_pin_ref == data->pin_reference) { + data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN; + } else { + data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + + // PIN.QES is a regular iso7816 pin + if (data->pin_reference == 0x81) { + rv = iso_ops->pin_cmd(card, data, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); + } + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); +} + +static int +lteid_pin_cmd_unblock(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + int rv; + + // PACE PIN for unblocking command is known as pin ref 0x07 + if (data->pin_reference == PACE_PIN_ID_PIN) { + struct sc_pin_cmd_data with_changed_pin_ref = *data; + + with_changed_pin_ref.pin_reference = 0x07; + rv = iso_ops->pin_cmd(card, &with_changed_pin_ref, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); + } + + // PIN.QES is a regular iso7816 pin + if (data->pin_reference == 0x81) { + rv = iso_ops->pin_cmd(card, data, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); + } + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); +} + +static int +lteid_pin_cmd_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + int rv; + + // PACE PIN for unblocking command is known as pin ref 0x07 + if (data->pin_reference == PACE_PIN_ID_PIN) { + struct sc_pin_cmd_data with_changed_pin_ref = *data; + + with_changed_pin_ref.pin_reference = 0x07; + rv = iso_ops->pin_cmd(card, &with_changed_pin_ref, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); + } + + // PIN.QES is a regular iso7816 pin + if (data->pin_reference == 0x81) { + rv = iso_ops->pin_cmd(card, data, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); + } + + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); +} + +static int +lteid_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + int rv; + + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + rv = lteid_pin_cmd_verify(card, data, tries_left); + break; + case SC_PIN_CMD_GET_INFO: + rv = lteid_pin_cmd_get_info(card, data, tries_left); + break; + case SC_PIN_CMD_UNBLOCK: + rv = lteid_pin_cmd_unblock(card, data, tries_left); + break; + case SC_PIN_CMD_CHANGE: + rv = lteid_pin_cmd_change(card, data, tries_left); + break; + default: + rv = SC_ERROR_NOT_SUPPORTED; + break; + } + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int +lteid_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) +{ + LOG_FUNC_CALLED(card->ctx); + + struct sc_apdu apdu; + int rv; + + if (env == NULL || env->key_ref_len != 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + sc_log(card->ctx, "algo: %lu operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]); + + if (env->algorithm != SC_ALGORITHM_EC || env->operation != SC_SEC_OPERATION_SIGN) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + const u8 data[] = {0x84, 0x01, env->key_ref[0]}; + sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, data, sizeof(data), NULL, 0); + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, rv, "SET SECURITY ENV failed"); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int +lteid_compute_signature(struct sc_card *card, const u8 *data, size_t data_len, u8 *out, size_t outlen) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + // Usually this is called with 104 bytes buffer. But we expect card to return 96 byte hash. + if (outlen < 96) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); + + memset(out, 0, outlen); + + const int rv = iso_ops->compute_signature(card, data, data_len, out, 96); + + LOG_FUNC_RETURN(card->ctx, rv); +} + +static int +lteid_process_fci(struct sc_card *card, struct sc_file *file, const u8 *buf, size_t buflen) +{ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + int rv = iso_ops->process_fci(card, file, buf, buflen); + + if (rv != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, rv); + } + + // Card reports most of the file size as 0, even if they're not empty. + // This confuses PKCS#15 loader, and it fails to load/init keys/certs/pins/etc. + // As a quick workaround - lets report size to be something large enough to fit any object. + if (file->size == 0) { + file->size = 2048; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +struct sc_card_driver * +sc_get_lteid_driver(void) +{ + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + + if (iso_ops == NULL) + iso_ops = iso_drv->ops; + + lteid_ops = *iso_ops; + lteid_ops.init = lteid_init; + lteid_ops.finish = lteid_finish; + lteid_ops.set_security_env = lteid_set_security_env; + lteid_ops.compute_signature = lteid_compute_signature; + lteid_ops.pin_cmd = lteid_pin_cmd; + lteid_ops.logout = lteid_logout; + lteid_ops.process_fci = lteid_process_fci; + + return <eid_drv; +} + +#else + +#include "opensc.h" + +struct sc_card_driver * +sc_get_lteid_driver(void) +{ + return NULL; +} + +#endif \ No newline at end of file diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 8405fba1a6..ac063d1f48 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -278,6 +278,9 @@ enum { SC_CARD_TYPE_DTRUST_V5_1_M100, SC_CARD_TYPE_DTRUST_V5_4_STD, SC_CARD_TYPE_DTRUST_V5_4_MULTI, + + /* Lithuanian eID cards */ + SC_CARD_TYPE_LTEID = 43000, }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -322,6 +325,7 @@ extern sc_card_driver_t *sc_get_nqApplet_driver(void); extern sc_card_driver_t *sc_get_skeid_driver(void); extern sc_card_driver_t *sc_get_eoi_driver(void); extern sc_card_driver_t *sc_get_dtrust_driver(void); +extern sc_card_driver_t *sc_get_lteid_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 2f8c8ef64e..aa2f523808 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -137,6 +137,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "idprime", (void *(*)(void)) sc_get_idprime_driver }, #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) { "edo", (void *(*)(void)) sc_get_edo_driver }, + { "lteid", (void *(*)(void)) sc_get_lteid_driver }, #endif /* Here should be placed drivers that need some APDU transactions in the diff --git a/src/libopensc/pkcs15-lteid.c b/src/libopensc/pkcs15-lteid.c new file mode 100644 index 0000000000..87ec8e17a9 --- /dev/null +++ b/src/libopensc/pkcs15-lteid.c @@ -0,0 +1,76 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "internal.h" +#include "pkcs15.h" + +static int +lteid_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) +{ + struct sc_context *ctx = p15card->card->ctx; + struct sc_pkcs15_object *pkobjs[32]; + int rv, count; + + LOG_FUNC_CALLED(ctx); + + if (!df) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + + if (df->enumerated) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + + rv = sc_pkcs15_parse_df(p15card, df); + LOG_TEST_RET(ctx, rv, "DF parse error"); + + if (df->type != SC_PKCS15_PRKDF) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); + + rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, pkobjs, sizeof(pkobjs) / sizeof(pkobjs[0])); + LOG_TEST_RET(ctx, rv, "Cannot get PRKEY objects list"); + + count = rv; + for (int i = 0; i < count; i++) { + struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)pkobjs[i]->data; + prkey_info->field_length = 384; + } + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + +static int +sc_pkcs15emu_lteid_init(struct sc_pkcs15_card *p15card, struct sc_aid *aid) +{ + LOG_FUNC_CALLED(p15card->card->ctx); + + int rv = sc_pkcs15_bind_internal(p15card, aid); + p15card->ops.parse_df = lteid_parse_df; + + LOG_FUNC_RETURN(p15card->card->ctx, rv); +} + +int +sc_pkcs15emu_lteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + if (p15card->card->type == SC_CARD_TYPE_LTEID) { + return sc_pkcs15emu_lteid_init(p15card, aid); + } + + return SC_ERROR_WRONG_CARD; +} \ No newline at end of file diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 45d28eba81..177f795752 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -63,6 +63,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "esign", sc_pkcs15emu_starcos_esign_init_ex }, { "eOI", sc_pkcs15emu_eoi_init_ex }, { "dtrust", sc_pkcs15emu_dtrust_init_ex }, + { "lteid", sc_pkcs15emu_lteid_init_ex }, { NULL, NULL } }; @@ -126,6 +127,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_DTRUST_V5_1_MULTI: case SC_CARD_TYPE_DTRUST_V5_1_M100: case SC_CARD_TYPE_DTRUST_V5_4_MULTI: + case SC_CARD_TYPE_LTEID: return 1; default: return 0; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index ed144b84c8..b6883190d1 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -58,6 +58,7 @@ int sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_eoi_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_dtrust_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_lteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index a41f7ae49c..c1edaed7ff 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1250,6 +1250,7 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) "nqapplet", "tcos", "dtrust", + "lteid", }; if (NULL == card || NULL == card->driver || NULL == card->driver->short_name) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index dbfc518dc5..49fe622ef6 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -25,7 +25,7 @@ noinst_HEADERS = util.h fread_to_eof.h \ bin_PROGRAMS = opensc-tool opensc-explorer opensc-asn1 \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ cardos-tool eidenv openpgp-tool iasecc-tool egk-tool goid-tool \ - dtrust-tool + dtrust-tool lteid-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool @@ -105,6 +105,10 @@ if HAVE_SHORTEN_WARNING_OPTION npa_tool_CFLAGS += -Wno-shorten-64-to-32 endif +lteid_tool_SOURCES = lteid-tool.c util.c +lteid_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(OPENPACE_LIBS) +lteid_tool_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPENPACE_CFLAGS) + opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION diff --git a/src/tools/lteid-tool.c b/src/tools/lteid-tool.c new file mode 100644 index 0000000000..8e0dd0d68e --- /dev/null +++ b/src/tools/lteid-tool.c @@ -0,0 +1,562 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "common/compat_strlcat.h" +#include "libopensc/opensc.h" +#include "libopensc/pkcs15.h" +#include "sm/sm-eac.h" +#include "util.h" + +/* win32 needs this in open(2) */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static const char *app_name = "lteid-tool"; + +#define OP_NONE 0 /* no operation requested */ +#define OP_RESUME 1 /* resume pin entry using CAN code */ +#define OP_UNBLOCK 2 /* unblock using PUK code */ +#define OP_CHANGE_PIN 3 + +static const struct option options[] = { + {"help", 0, NULL, 'h'}, + {"verbose", 0, NULL, 'v'}, + {"reader", 1, NULL, 'r'}, + {"wait", 0, NULL, 'w'}, + {"can", 1, NULL, 'c'}, + {"pin", 1, NULL, 'p'}, + {"puk", 1, NULL, 'u'}, + {"change-pin", 0, NULL, 'C'}, + {"resume", 0, NULL, 'R'}, + {"unblock", 0, NULL, 'U'}, + {"verify-can", 0, NULL, 'V'}, + {NULL, 0, NULL, 0 } +}; + +static const char *option_help[] = { + "Display tool options", + "Display all the information available", + "Uses reader number [0]", + "Wait for a card to be inserted", + "Specify CAN", + "Specify PIN", + "Specify PUK", + "Change PIN", + "Resume authentication key PIN after 2 incorrect attempts", + "Unblock PIN using PUK", + "Verify Card Access Number (CAN)", +}; + +static int +get_tries_left(sc_pkcs15_card_t *p15card, u8 pin_reference, int *pin_tries_left) +{ + int rv, i; + struct sc_pkcs15_object *objs[32]; + + *pin_tries_left = -1; + + rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 32); + if (rv < 0) { + fprintf(stderr, "AUTH objects enumeration failed: %s\n", sc_strerror(rv)); + return 1; + } + + for (i = 0; i < rv; i++) { + sc_pkcs15_get_pin_info(p15card, objs[i]); + + const struct sc_pkcs15_auth_info *auth_info = (const struct sc_pkcs15_auth_info *)objs[i]->data; + + if (auth_info->auth_id.len == 1 && auth_info->auth_id.value[0] == pin_reference) { + *pin_tries_left = auth_info->tries_left; + return SC_SUCCESS; + } + } + + return SC_ERROR_OBJECT_NOT_FOUND; +} + +static int +display_pin_tries_left(sc_pkcs15_card_t *p15card) +{ + int pace_pin_tries_left, qes_pin_tries_left, puk_tries_left; + + get_tries_left(p15card, PACE_PIN_ID_PUK, &puk_tries_left); + get_tries_left(p15card, PACE_PIN_ID_PIN, &pace_pin_tries_left); + get_tries_left(p15card, 0x81, &qes_pin_tries_left); + + printf("\n"); + printf("PUK tries left: %i\n", puk_tries_left); + printf("PIN (for authentication) tries left: %i\n", pace_pin_tries_left); + printf("PIN (for electronic signatures) tries left: %i\n", qes_pin_tries_left); + printf("\n"); + + return SC_SUCCESS; +} + +static int +display_basic_details(sc_pkcs15_card_t *p15card) +{ + printf("\nCard label: %s\n", p15card->tokeninfo->label); + printf("Serial number: %s\n", p15card->tokeninfo->serial_number); + + display_pin_tries_left(p15card); + + return SC_SUCCESS; +} + +int +input_number(const char *description, size_t min_len, size_t max_len, const char *provided_via_cli, char **number) +{ + size_t number_len = 0; + + if (provided_via_cli && strlen(provided_via_cli) >= min_len && strlen(provided_via_cli) <= max_len) { + *number = strdup(provided_via_cli); + + printf("Using %s provided via command line arguments.\n", description); + + return SC_SUCCESS; + } + + printf("Enter %s ", description); + + if (min_len == max_len) { + printf("(%zu digits): ", min_len); + } else { + printf("(%zu..%zu digits): ", min_len, max_len); + } + + number_len = util_getpass(number, NULL, stdin); + + if (number_len < min_len || number_len > max_len) { + return SC_ERROR_INTERNAL; + } + + for (size_t i = 0; i < number_len; i++) { + if ((*number)[i] < '0' || (*number)[i] > '9') { + return SC_ERROR_INTERNAL; + } + } + + return SC_SUCCESS; +} + +int +verify_and_cache_pace_can(sc_card_t *card, const char *opt_can) +{ + int rv; + struct sc_path path; + char *can = NULL; + + rv = input_number("number from the bottom right corner of the card", 6, 6, opt_can, &can); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "CAN number blank, too short or too long.\n"); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + sc_format_path("3F00", &path); + sc_select_file(card, &path, NULL); + + struct sc_pin_cmd_data can_verify_cmd = {0}; + can_verify_cmd.cmd = SC_PIN_CMD_VERIFY; + can_verify_cmd.pin_type = SC_AC_CHV; + can_verify_cmd.pin_reference = PACE_PIN_ID_CAN; + can_verify_cmd.pin1.data = (unsigned char *)can; + can_verify_cmd.pin1.len = strlen(can); + + rv = card->ops->pin_cmd(card, &can_verify_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "CAN number verification failed: %s\nCheck the number and try again.\n", sc_strerror(rv)); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + printf("\nThe new CAN code is now persisted.\n"); + printf("\nIf you are about to use the card in your web browser - you may have to remove and re-insert it.\n"); + + return SC_SUCCESS; +} + +/* + * Officially card has a single PIN. But under the hood it's really two separate PINs: + * + * - PACE-PIN with ID 0x03, tied to the key intended for authentication. + * - PIN.QES with ID 0x81, tied to the key intended for signature + * + * The procedure below follows this and applies change to both PINs. + */ +int +change_pin(sc_card_t *card, const char *opt_pin) +{ + int rv; + struct sc_path path; + char *pin = NULL; + char *new_pin = NULL; + char *new_pin_repeated = NULL; + unsigned char pace_pin_changed = 0, qes_pin_changed = 0; + + rv = input_number("Current PIN", 6, 12, opt_pin, &pin); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN number blank, too short or too long.\n"); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + sc_format_path("3F00", &path); + sc_select_file(card, &path, NULL); + + struct sc_pin_cmd_data pin_verify_cmd = {0}; + pin_verify_cmd.cmd = SC_PIN_CMD_VERIFY; + pin_verify_cmd.pin_type = SC_AC_CHV; + pin_verify_cmd.pin_reference = PACE_PIN_ID_PIN; + pin_verify_cmd.pin1.data = (unsigned char *)pin; + pin_verify_cmd.pin1.len = strlen(pin); + + rv = card->ops->pin_cmd(card, &pin_verify_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(rv)); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + rv = input_number("New PIN", 6, 12, NULL, &new_pin); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN number blank, too short or too long.\n"); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + input_number("New PIN (repeat)", 6, 12, NULL, &new_pin_repeated); + + if (new_pin_repeated == NULL || strcmp(new_pin, new_pin_repeated) != 0) { + fprintf(stderr, "New PIN and repeated entry do not match. PIN was not changed.\n"); + return SC_ERROR_INTERNAL; + } + + printf("\n"); + + struct sc_pin_cmd_data pace_pin_cmd = {0}; + pace_pin_cmd.cmd = SC_PIN_CMD_CHANGE; + pace_pin_cmd.pin_type = SC_AC_CHV; + pace_pin_cmd.pin_reference = PACE_PIN_ID_PIN; + pace_pin_cmd.pin2.data = (unsigned char *)new_pin; + pace_pin_cmd.pin2.len = strlen(new_pin); + + rv = card->ops->pin_cmd(card, &pace_pin_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN for authentication change failed: %s\n", sc_strerror(rv)); + } else { + printf("PIN for authentication changed.\n"); + pace_pin_changed = 1; + } + + sc_format_path("3F00DF02", &path); + sc_select_file(card, &path, NULL); + + struct sc_pin_cmd_data qes_pin_cmd = {0}; + qes_pin_cmd.cmd = SC_PIN_CMD_CHANGE; + qes_pin_cmd.pin_type = SC_AC_CHV; + qes_pin_cmd.pin_reference = 0x81; + qes_pin_cmd.pin1.data = (unsigned char *)pin; + qes_pin_cmd.pin1.len = strlen(pin); + qes_pin_cmd.pin2.data = (unsigned char *)new_pin; + qes_pin_cmd.pin2.len = strlen(new_pin); + + rv = card->ops->pin_cmd(card, &qes_pin_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN for signature change failed: %s\n", sc_strerror(rv)); + } else { + printf("PIN for signature changed.\n"); + qes_pin_changed = 1; + } + + return (pace_pin_changed && qes_pin_changed) ? SC_SUCCESS : SC_ERROR_INTERNAL; +} + +int +resume(sc_pkcs15_card_t *p15card, const char *opt_can, const char *opt_pin) +{ + int rv; + struct sc_card *card = p15card->card; + struct establish_pace_channel_input pace_input = {0}; + struct establish_pace_channel_output pace_output = {0}; + struct sc_path path; + char *pin = NULL; + int tries_left; + + rv = get_tries_left(p15card, PACE_PIN_ID_PIN, &tries_left); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "Cannot get remaining tries left: %s\n", sc_strerror(rv)); + return rv; + } + + if (tries_left > 1) { + fprintf(stderr, "PIN for authentication is not blocked, there's %i tries remaining.\n", tries_left); + return SC_ERROR_NOT_ALLOWED; + } + + if (tries_left == 0) { + fprintf(stderr, "PIN for authentication is fully blocked with 0 attempts remaining. Use 'lteid-tool --unblock' instead.\n"); + return SC_ERROR_NOT_ALLOWED; + } + + rv = input_number("PIN number", 6, 12, opt_pin, &pin); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN number blank, too short or too long.\n"); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + sc_format_path("3F00", &path); + sc_select_file(card, &path, NULL); + + struct sc_pin_cmd_data can_verify_cmd = {0}; + can_verify_cmd.cmd = SC_PIN_CMD_VERIFY; + can_verify_cmd.pin_type = SC_AC_CHV; + can_verify_cmd.pin_reference = PACE_PIN_ID_CAN; + can_verify_cmd.pin1.data = (unsigned char *)opt_can; + if (opt_can) + can_verify_cmd.pin1.len = strlen(opt_can); + + rv = card->ops->pin_cmd(card, &can_verify_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "CAN code verification failed: %s\n", sc_strerror(rv)); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + pace_input.pin_id = PACE_PIN_ID_PIN; + pace_input.pin = (unsigned char *)pin; + pace_input.pin_length = strlen(pin); + + rv = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(rv)); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + printf("PIN for authentication unblocked.\n"); + + return SC_SUCCESS; +} + +int +unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) +{ + int rv; + struct sc_card *card = p15card->card; + struct sc_path path; + char *puk = NULL; + int pace_pin_tries_left, qes_pin_tries_left; + + get_tries_left(p15card, PACE_PIN_ID_PIN, &pace_pin_tries_left); + get_tries_left(p15card, 0x81, &qes_pin_tries_left); + + if (pace_pin_tries_left > 0 && qes_pin_tries_left > 0) { + fprintf(stderr, "None of the PINs require unblocking.\n"); + return SC_ERROR_INTERNAL; + } + + rv = input_number("PUK number", 8, 12, opt_puk, &puk); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN number blank, too short or too long.\n"); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + sc_format_path("3F00", &path); + sc_select_file(card, &path, NULL); + + struct sc_pin_cmd_data puk_verify_cmd = {0}; + puk_verify_cmd.cmd = SC_PIN_CMD_VERIFY; + puk_verify_cmd.pin_type = SC_AC_CHV; + puk_verify_cmd.pin_reference = PACE_PIN_ID_PUK; + puk_verify_cmd.pin1.data = (unsigned char *)puk; + puk_verify_cmd.pin1.len = strlen(puk); + + rv = card->ops->pin_cmd(card, &puk_verify_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PUK code verification failed: %s\n", sc_strerror(rv)); + return SC_ERROR_PIN_CODE_INCORRECT; + } + + if (pace_pin_tries_left == 0) { + struct sc_pin_cmd_data pace_pin_cmd = {0}; + pace_pin_cmd.cmd = SC_PIN_CMD_UNBLOCK; + pace_pin_cmd.pin_type = SC_AC_CHV; + pace_pin_cmd.pin_reference = PACE_PIN_ID_PIN; + + rv = card->ops->pin_cmd(card, &pace_pin_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN for authentication reset failed: %s\n", sc_strerror(rv)); + return rv; + } + } + + if (qes_pin_tries_left == 0) { + struct sc_pin_cmd_data qes_pin_cmd = {0}; + qes_pin_cmd.cmd = SC_PIN_CMD_UNBLOCK; + qes_pin_cmd.pin_type = SC_AC_CHV; + qes_pin_cmd.pin_reference = 0x81; + + sc_format_path("3F00DF02", &path); + sc_select_file(card, &path, NULL); + + rv = card->ops->pin_cmd(card, &qes_pin_cmd, NULL); + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PIN for signature reset failed: %s\n", sc_strerror(rv)); + return rv; + } + } + + printf("PIN unblocked.\n"); + + return SC_SUCCESS; +} + +int +main(int argc, char *argv[]) +{ + int opt_wait = 0; + const char *opt_can = NULL; + const char *opt_pin = NULL; + const char *opt_puk = NULL; + const char *opt_reader = NULL; + int verbose = 0; + int opt_change_pin = 0; + int opt_resume = 0; + int opt_unblock = 0; + int opt_verify_can = 0; + + int err = 0; + sc_context_t *ctx = NULL; + sc_context_param_t ctx_param = {0}; + sc_card_t *card = NULL; + struct sc_pkcs15_card *p15card = NULL; + int c, rv; + + while ((c = getopt_long(argc, argv, "hr:wc:p:u:vCRUV", options, (int *)0)) != -1) { + switch (c) { + case 'r': + opt_reader = optarg; + break; + case 'w': + opt_wait = 1; + break; + case 'c': + util_get_pin(optarg, &opt_can); + break; + case 'p': + util_get_pin(optarg, &opt_pin); + break; + case 'u': + util_get_pin(optarg, &opt_puk); + break; + case 'v': + verbose++; + break; + case 'C': + opt_change_pin = 1; + break; + case 'R': + opt_resume = 1; + break; + case 'U': + opt_unblock = 1; + break; + case 'V': + opt_verify_can = 1; + break; + case 'h': + default: + util_print_usage_and_die(app_name, options, option_help, NULL); + } + } + + ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; + rv = sc_context_create(&ctx, &ctx_param); + if (rv) { + fprintf(stderr, "Error: Failed to establish context: %s\n", sc_strerror(rv)); + err = -1; + goto cleanup; + } + + if (util_connect_card(ctx, &card, opt_reader, opt_wait)) { + fprintf(stderr, "Error: Cannot connect with card\n"); + err = -1; + goto cleanup; + } + + if (strcmp("lteid", card->driver->short_name) != 0) { + fprintf(stderr, "Error: Card in the reader does not appear to be Lithuanian identity card.\n"); + err = -1; + goto cleanup; + } + + rv = sc_pkcs15_bind(card, NULL, &p15card); + + if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED || opt_verify_can) { + printf("\nCAN number is not set/stored.\n\n"); + err = verify_and_cache_pace_can(card, opt_can); + goto cleanup; + } + + if (rv != SC_SUCCESS) { + fprintf(stderr, "PKCS#15 binding failed: %s\n", sc_strerror(rv)); + err = -1; + goto cleanup; + } + + display_basic_details(p15card); + + if (opt_change_pin) { + err = change_pin(card, opt_pin); + } else if (opt_resume) { + err = resume(p15card, opt_can, opt_pin); + } else if (opt_unblock) { + err = unblock_using_puk(p15card, opt_puk); + } + +cleanup: + if (card) { + sc_unlock(card); + sc_disconnect_card(card); + } + sc_release_context(ctx); + return err; +} diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index a9a1041cba..a61568753c 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -77,7 +77,7 @@ OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(PLATFORM)\$(BUILD_TYPE)\libcrypto_static.l OPENSSL_LIB = $(OPENSSL_LIB) user32.lib advapi32.lib crypt32.lib ws2_32.lib PROGRAMS_OPENSSL = cryptoflex-tool.exe pkcs15-init.exe netkey-tool.exe piv-tool.exe \ - westcos-tool.exe sc-hsm-tool.exe dnie-tool.exe gids-tool.exe + westcos-tool.exe sc-hsm-tool.exe dnie-tool.exe gids-tool.exe lteid-tool.exe OPENSC_FEATURES = $(OPENSC_FEATURES) openssl WIXFLAGS = -d OpenSSL="$(OPENSSL_DIR)" $(WIXFLAGS) !ENDIF From dc28c2fdd8354c16aa2c2e7a009a479e5227d592 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 2 Mar 2026 10:56:03 +0100 Subject: [PATCH 4167/4321] switch to portable bit fields The C standard only guarantees bit fields for `unsigned int`, `signed int`, `int` or `_Bool` (since C99), even though in practice major compilers also support more types. --- src/libopensc/card-coolkey.c | 34 +++++++++++++++++----------------- src/libopensc/card-dtrust.c | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 52760b384c..0cbc498c8a 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -255,23 +255,23 @@ typedef struct coolkey_attribute_header { struct coolkey_fixed_attributes_values { uint32_t cka_id:4; uint32_t cka_class:3; - uint32_t cka_token:1; - uint32_t cka_private:1; - uint32_t cka_modifiable:1; - uint32_t cka_derive:1; - uint32_t cka_local:1; - uint32_t cka_encrypt:1; - uint32_t cka_decrypt:1; - uint32_t cka_wrap:1; - uint32_t cka_unwrap:1; - uint32_t cka_sign:1; - uint32_t cka_sign_recover:1; - uint32_t cka_verify:1; - uint32_t cka_verify_recover:1; - uint32_t cka_sensitive:1; - uint32_t cka_always_sensitive:1; - uint32_t cka_extractable:1; - uint32_t cka_never_extractable:1; + unsigned int cka_token:1; + unsigned int cka_private:1; + unsigned int cka_modifiable:1; + unsigned int cka_derive:1; + unsigned int cka_local:1; + unsigned int cka_encrypt:1; + unsigned int cka_decrypt:1; + unsigned int cka_wrap:1; + unsigned int cka_unwrap:1; + unsigned int cka_sign:1; + unsigned int cka_sign_recover:1; + unsigned int cka_verify:1; + unsigned int cka_verify_recover:1; + unsigned int cka_sensitive:1; + unsigned int cka_always_sensitive:1; + unsigned int cka_extractable:1; + unsigned int cka_never_extractable:1; uint32_t reserved:8; }; diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 0eca4447f3..3a7c5a070d 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -65,12 +65,12 @@ static struct sc_card_driver dtrust_drv = { struct dtrust_drv_data_t { /* track PACE state */ - unsigned char pace : 1; - unsigned char can : 1; + unsigned int pace : 1; + unsigned int can : 1; /* global CAN from configuration file */ char *can_value; /* use CAN cache */ - unsigned char can_cache : 1; + unsigned int can_cache : 1; /* PKCS#15 context for CAN caching */ struct sc_pkcs15_card *p15card; /* save the current security environment */ From c8157c3b60629fc1589cb84ea6faac9d5953ad87 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 2 Mar 2026 14:57:33 +0100 Subject: [PATCH 4168/4321] more fields --- src/libopensc/card-coolkey.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 0cbc498c8a..3df119ad5d 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -253,8 +253,8 @@ typedef struct coolkey_attribute_header { * Definitions: * struct coolkey_fixed_attributes_values { - uint32_t cka_id:4; - uint32_t cka_class:3; + unsigned int cka_id:4; + unsigned int cka_class:3; unsigned int cka_token:1; unsigned int cka_private:1; unsigned int cka_modifiable:1; @@ -272,7 +272,7 @@ struct coolkey_fixed_attributes_values { unsigned int cka_always_sensitive:1; unsigned int cka_extractable:1; unsigned int cka_never_extractable:1; - uint32_t reserved:8; + unsigned int reserved:8; }; * cka_class is used to determine which booleans are valid. Any attributes in the full attribute list From dfcf9e378e50d0796acd8792022f7e1a2e0503c3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 2 Apr 2026 09:06:14 +0200 Subject: [PATCH 4169/4321] lteid-tool: Check return value of select file Thanks coverity! CID 502581, CID 502578, CID 502577 Signed-off-by: Jakub Jelen --- src/tools/lteid-tool.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/tools/lteid-tool.c b/src/tools/lteid-tool.c index 8e0dd0d68e..4c922a8841 100644 --- a/src/tools/lteid-tool.c +++ b/src/tools/lteid-tool.c @@ -180,7 +180,11 @@ verify_and_cache_pace_can(sc_card_t *card, const char *opt_can) } sc_format_path("3F00", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select MF.\n"); + return rv; + } struct sc_pin_cmd_data can_verify_cmd = {0}; can_verify_cmd.cmd = SC_PIN_CMD_VERIFY; @@ -228,7 +232,11 @@ change_pin(sc_card_t *card, const char *opt_pin) } sc_format_path("3F00", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select MF.\n"); + return rv; + } struct sc_pin_cmd_data pin_verify_cmd = {0}; pin_verify_cmd.cmd = SC_PIN_CMD_VERIFY; @@ -277,7 +285,11 @@ change_pin(sc_card_t *card, const char *opt_pin) } sc_format_path("3F00DF02", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select 3F:00:DF:02.\n"); + return rv; + } struct sc_pin_cmd_data qes_pin_cmd = {0}; qes_pin_cmd.cmd = SC_PIN_CMD_CHANGE; @@ -336,7 +348,11 @@ resume(sc_pkcs15_card_t *p15card, const char *opt_can, const char *opt_pin) } sc_format_path("3F00", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select MF.\n"); + return rv; + } struct sc_pin_cmd_data can_verify_cmd = {0}; can_verify_cmd.cmd = SC_PIN_CMD_VERIFY; @@ -394,7 +410,11 @@ unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) } sc_format_path("3F00", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select MF.\n"); + return rv; + } struct sc_pin_cmd_data puk_verify_cmd = {0}; puk_verify_cmd.cmd = SC_PIN_CMD_VERIFY; @@ -431,7 +451,11 @@ unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) qes_pin_cmd.pin_reference = 0x81; sc_format_path("3F00DF02", &path); - sc_select_file(card, &path, NULL); + rv = sc_select_file(card, &path, NULL); + if (rv != SC_SUCCESS) { + fprintf(stderr, "Failed to select 3F:00:DF:02.\n"); + return rv; + } rv = card->ops->pin_cmd(card, &qes_pin_cmd, NULL); From 8fdc27699cdba5b2655985d2f8bfba7434be5744 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 2 Apr 2026 09:10:24 +0200 Subject: [PATCH 4170/4321] lteid-tool: Fix possible memory leak on error paths Thanks coverity CID 502580, CID 502579 Signed-off-by: Jakub Jelen --- src/tools/lteid-tool.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tools/lteid-tool.c b/src/tools/lteid-tool.c index 4c922a8841..6b0e1c041c 100644 --- a/src/tools/lteid-tool.c +++ b/src/tools/lteid-tool.c @@ -153,11 +153,15 @@ input_number(const char *description, size_t min_len, size_t max_len, const char number_len = util_getpass(number, NULL, stdin); if (number_len < min_len || number_len > max_len) { + free(*number); + *number = NULL; return SC_ERROR_INTERNAL; } for (size_t i = 0; i < number_len; i++) { if ((*number)[i] < '0' || (*number)[i] > '9') { + free(*number); + *number = NULL; return SC_ERROR_INTERNAL; } } @@ -366,6 +370,7 @@ resume(sc_pkcs15_card_t *p15card, const char *opt_can, const char *opt_pin) if (rv != SC_SUCCESS) { fprintf(stderr, "CAN code verification failed: %s\n", sc_strerror(rv)); + free(pin); return SC_ERROR_PIN_CODE_INCORRECT; } @@ -374,7 +379,7 @@ resume(sc_pkcs15_card_t *p15card, const char *opt_can, const char *opt_pin) pace_input.pin_length = strlen(pin); rv = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); - + free(pin); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(rv)); return SC_ERROR_PIN_CODE_INCORRECT; From b02b63ae0a1aa3b1cf95f03fb6a8a4c76e2b45fb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 7 Apr 2026 18:03:01 +0200 Subject: [PATCH 4171/4321] pkcs11-tool: Do not set PARAMETER_SET on private key template during key generation The attribute is defined in the list with the footnote 4 (from Table 13) with the description: > MUST not be specified when object is generated with C_GenerateKey This matches what EC_PARAMS have and how they are (correctly) handled. https://github.com/softhsm/SoftHSMv2/pull/850 Signed-off-by: Jakub Jelen --- src/tools/pkcs11-tool.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index a5f63d9d35..2cc967ff52 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3727,9 +3727,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, - &ml_dsa_parameter_set, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); - n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_sign) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); @@ -3761,9 +3758,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, - &ml_kem_parameter_set, sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); - n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_encapsulate) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_ENCAPSULATE, &_true, sizeof(_true)); @@ -3813,9 +3807,6 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_PARAMETER_SET, &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_PARAMETER_SET, - &slh_dsa_parameter_set, sizeof(CK_SLH_DSA_PARAMETER_SET_TYPE)); - n_privkey_attr++; if (opt_key_usage_default || opt_key_usage_sign) { FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true)); From 96e39e7e0631f1b52c938a32b6d0d4d703e49c89 Mon Sep 17 00:00:00 2001 From: El Mostafa IDRASSI Date: Mon, 6 Apr 2026 18:40:28 +0200 Subject: [PATCH 4172/4321] pkcs11-tool: fix CKA_VERIFY_RECOVER queried on secret key objects In show_key(), the `pub` flag defaults to 1 and is never cleared for CKO_SECRET_KEY objects (only `sec` is set). This caused getVERIFY_RECOVER() to be called on secret keys, resulting in C_GetAttributeValue returning CKR_ATTRIBUTE_TYPE_INVALID since CKA_VERIFY_RECOVER is a public-key-only attribute. Guard the check with !sec to restrict it to public keys only. --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2cc967ff52..f3ac4e6bf1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6825,7 +6825,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("%sverify", sepa); sepa = ", "; } - if (pub && getVERIFY_RECOVER(sess, obj)) { + if (pub && !sec && getVERIFY_RECOVER(sess, obj)) { printf("%sverifyRecover", sepa); sepa = ", "; } From 82d8fb8956bd3d0326c70b54b4236404268e00eb Mon Sep 17 00:00:00 2001 From: hirashix0 Date: Thu, 2 Apr 2026 00:27:03 +0200 Subject: [PATCH 4173/4321] Serbian CardEdge card driver Driver for Serbian smart cards that use the CardEdge PKCS#15 applet (AID A0:00:00:00:63:50:4B:43:53:2D:31:35). Gemalto (2014+) Serbian eID is matched by ATR (3B:FF:94 ...); all other CardEdge-based cards are identified via AID selection in match_card(). The driver handles CardEdge's proprietary 10-byte FCI in select_file(), MSE SET for key selection, PSO COMPUTE DIGITAL SIGNATURE with P2=0x00 (instead of ISO 7816-8's 0x9A), and PSO DECIPHER without the padding indicator byte. PKCS#15 emulator enumerates certificates from the mscp/cmapfile container map, reads zlib-compressed or raw DER certificate files, and registers PIN, private key, and certificate objects. Confirmed working with: - pkcs11-tool --sign (SHA256-RSA-PKCS) and pkcs15-crypt --sign. - TLS client certificate authentication (Firefox mTLS). - Tested on Linux and macOS (PCSC and CryptoTokenKit). --- src/libopensc/Makefile.am | 8 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-srbeid.c | 322 +++++++++++++++++++ src/libopensc/cards.h | 4 + src/libopensc/ctx.c | 3 + src/libopensc/pkcs15-srbeid.c | 584 ++++++++++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 1 + src/libopensc/pkcs15-syn.h | 1 + 8 files changed, 921 insertions(+), 6 deletions(-) create mode 100644 src/libopensc/card-srbeid.c create mode 100644 src/libopensc/pkcs15-srbeid.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 148a50707d..31ef4b7635 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -51,7 +51,7 @@ libopensc_la_SOURCES_BASE = \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c card-esteid2018.c card-esteid2025.c card-idprime.c \ card-edo.c card-nqApplet.c card-skeid.c card-eoi.c card-dtrust.c \ - card-lteid.c \ + card-lteid.c card-srbeid.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c pkcs15-tcos.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ @@ -60,7 +60,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c pkcs15-dtrust.c pkcs15-lteid.c \ - compression.c sm.c aux-data.c + pkcs15-srbeid.c compression.c sm.c aux-data.c if ENABLE_CRYPTOTOKENKIT # most platforms don't support objective C the way we needed. @@ -133,7 +133,7 @@ TIDY_FILES = \ card-isoApplet.c card-masktech.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ card-edo.c card-nqApplet.c card-skeid.c card-eoi.c card-dtrust.c \ - card-lteid.c \ + card-lteid.c card-srbeid.c \ \ pkcs15-openpgp.c pkcs15-cardos.c pkcs15-tcos.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c \ @@ -142,7 +142,7 @@ TIDY_FILES = \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-dtrust.c pkcs15-lteid.c \ - compression.c sm.c aux-data.c \ + pkcs15-srbeid.c compression.c sm.c aux-data.c \ #$(SOURCES) check-local: diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 6bb0fa4dae..460b5332d5 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -29,7 +29,7 @@ OBJECTS = \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj card-esteid2018.obj card-esteid2025.obj card-idprime.obj \ card-edo.obj card-nqApplet.obj card-skeid.obj card-eoi.obj card-dtrust.obj \ - card-lteid.obj \ + card-lteid.obj card-srbeid.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj pkcs15-tcos.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ @@ -38,7 +38,7 @@ OBJECTS = \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-esteid2025.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj pkcs15-dtrust.obj \ - pkcs15-lteid.obj compression.obj sm.obj aux-data.obj \ + pkcs15-lteid.obj pkcs15-srbeid.obj compression.obj sm.obj aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ $(TOPDIR)\src\common\common.lib \ diff --git a/src/libopensc/card-srbeid.c b/src/libopensc/card-srbeid.c new file mode 100644 index 0000000000..16a71c43ee --- /dev/null +++ b/src/libopensc/card-srbeid.c @@ -0,0 +1,322 @@ +/* + * card-srbeid.c: Driver for Serbian cards using the CardEdge PKI applet. + * + * Serbian eID, health insurance, and Chamber of Commerce cards use the + * same CardEdge PKCS#15 applet. Cards are matched either by ATR + * (Gemalto 2014+ eID) or by AID selection. + * + * Copyright (C) 2026 LibreSCRS contributors + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "internal.h" +#include "log.h" + +/* CardEdge PKI applet AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) */ +static const u8 AID_PKCS15[] = { + 0xA0, 0x00, 0x00, 0x00, 0x63, + 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; +#define AID_PKCS15_LEN (sizeof(AID_PKCS15)) + +/* MSE algorithm byte for RSA-2048 PKCS#1 v1.5 */ +#define CE_MSE_ALG_RSA2048 0x02u + +/* Base address of key files: key FID = CE_KEYS_BASE_FID | container/type bits */ +#define CE_KEYS_BASE_FID 0x6000u + +static struct sc_card_operations srbeid_ops; +static const struct sc_card_operations *iso_ops; + +static struct sc_card_driver srbeid_drv = { + "Serbian CardEdge driver", + "srbeid", + &srbeid_ops, + NULL, 0, NULL}; + +/* + * ATR table. + * + * Gemalto (2014+) Serbian eID: 3B:FF:94 ... + * Mask FF:FF:FF matches the first 3 bytes; remaining bytes vary between + * individual cards and are don't-cares. + * + * Other CardEdge cards have no distinct ATR and are identified via AID + * selection in match_card(). + * + * Apollo 2008 ATR 3B:B9:18 ... is intentionally absent — no CardEdge applet. + */ +static const struct sc_atr_table srbeid_atrs[] = { + {"3B:FF:94", "FF:FF:FF", "Serbian eID (Gemalto 2014+)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; + +static int +srbeid_match_card(sc_card_t *card) +{ + /* ATR hit: Gemalto 2014+ Serbian eID (3B:FF:94 ...) */ + if (_sc_match_atr(card, srbeid_atrs, &card->type) >= 0) + return 1; + + /* AID-based match for cards without a distinct ATR. */ + if (iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) == SC_SUCCESS) { + sc_log(card->ctx, "srbeid: CardEdge applet found via AID"); + card->type = SC_CARD_TYPE_SRBEID_BASE; + return 1; + } + + return 0; +} + +static int +srbeid_init(sc_card_t *card) +{ + LOG_FUNC_CALLED(card->ctx); + + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + + _sc_card_add_rsa_alg(card, 2048, + SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +/* + * select_file — handle CardEdge's proprietary 10-byte FCI response. + * + * CardEdge FCI layout (10 bytes, big-endian): + * [FID_H FID_L Size_H Size_L ACL*6] + * + * iso7816_select_file() would try to parse this as ISO 7816-4 TLV (tag 0x6F) + * and fail with SC_ERROR_UNKNOWN_DATA_RECEIVED. + * + * DF_NAME (AID) selection is delegated to the ISO layer. + */ +static int +srbeid_select_file(sc_card_t *card, const sc_path_t *in_path, + sc_file_t **file_out) +{ + sc_apdu_t apdu; + u8 fci[16]; + sc_file_t *file; + int r; + + if (in_path->type == SC_PATH_TYPE_DF_NAME) + return iso_ops->select_file(card, in_path, file_out); + + /* AID-only path (path.len==0, path.aid.len>0): PKCS#15 layer wants + * to select the applet before a PIN or key operation. */ + if (in_path->len == 0 && in_path->aid.len > 0) + return iso7816_select_aid(card, in_path->aid.value, + in_path->aid.len, NULL, NULL); + + if (in_path->len != 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00); + apdu.data = in_path->value; + apdu.datalen = 2; + apdu.lc = 2; + apdu.resp = fci; + apdu.resplen = sizeof(fci); + apdu.le = 10; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "SELECT FILE failed"); + + if (apdu.resplen < 4) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); + + if (file_out) { + file = sc_file_new(); + if (!file) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + + file->id = ((unsigned)in_path->value[0] << 8) | in_path->value[1]; + file->path = *in_path; + file->size = ((size_t)fci[2] << 8) | (size_t)fci[3]; + file->type = SC_FILE_TYPE_WORKING_EF; + *file_out = file; + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +/* + * set_security_env — send MSE SET to the card. + * + * The PKCS#15 layer selects the PKI applet via the AID attached to + * key_info.path before calling this function (see select_key_file() + * in pkcs15-sec.c). + * + * OpenSC populates env->key_ref[0] from key_info.key_reference (low byte). + * The high byte is always 0x60 (CE_KEYS_BASE_FID >> 8) for all CardEdge + * key FIDs, so the full 2-byte FID is reconstructed here. + * + * MSE SET template P2: 0xB6 for signing, 0xB8 for deciphering. + */ +static int +srbeid_set_security_env(sc_card_t *card, + const struct sc_security_env *env, int se_num) +{ + sc_apdu_t apdu; + u8 mse_data[7]; + unsigned key_ref; + u8 p2; + int r; + + LOG_FUNC_CALLED(card->ctx); + (void)se_num; + + /* Extract key FID. */ + if ((env->flags & SC_SEC_ENV_FILE_REF_PRESENT) && env->file_ref.len >= 2) { + key_ref = ((unsigned)env->file_ref.value[0] << 8) | (unsigned)env->file_ref.value[1]; + } else if ((env->flags & SC_SEC_ENV_KEY_REF_PRESENT) && env->key_ref_len >= 1) { + key_ref = CE_KEYS_BASE_FID | (unsigned)env->key_ref[0]; + } else { + sc_log(card->ctx, "srbeid: set_security_env: no key reference"); + return SC_ERROR_INCORRECT_PARAMETERS; + } + + /* Determine MSE SET template from operation type. */ + switch (env->operation) { + case SC_SEC_OPERATION_SIGN: + p2 = 0xB6; + break; + case SC_SEC_OPERATION_DECIPHER: + p2 = 0xB8; + break; + default: + return SC_ERROR_NOT_SUPPORTED; + } + + /* MSE SET: tag 0x80 = algorithm (RSA2048), tag 0x84 = key ref (2 bytes BE) */ + mse_data[0] = 0x80; + mse_data[1] = 0x01; + mse_data[2] = CE_MSE_ALG_RSA2048; + mse_data[3] = 0x84; + mse_data[4] = 0x02; + mse_data[5] = (u8)((key_ref >> 8) & 0xFF); + mse_data[6] = (u8)(key_ref & 0xFF); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, p2); + apdu.data = mse_data; + apdu.datalen = sizeof(mse_data); + apdu.lc = sizeof(mse_data); + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "MSE SET failed"); + + sc_log(card->ctx, "srbeid: set_security_env: key_ref=0x%04x p2=0x%02x", key_ref, p2); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +/* + * compute_signature — PSO COMPUTE DIGITAL SIGNATURE (00 2A 9E 00). + * + * MSE SET has already been sent by set_security_env(). + * CardEdge uses P2=0x00 (not 0x9A as in ISO 7816-8), so we cannot + * delegate to iso7816_compute_signature(). + */ +static int +srbeid_compute_signature(sc_card_t *card, + const u8 *data, size_t datalen, u8 *out, size_t outlen) +{ + sc_apdu_t apdu; + u8 resp[256]; + int r; + + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x00); + apdu.data = data; + apdu.datalen = datalen; + apdu.lc = datalen; + apdu.resp = resp; + apdu.resplen = sizeof(resp); + apdu.le = 256; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "PSO COMPUTE DIGITAL SIGNATURE failed"); + + if (apdu.resplen > outlen) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); + memcpy(out, resp, apdu.resplen); + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); +} + +/* + * decipher — PSO DECIPHER (00 2A 80 86). + * + * MSE SET has already been sent by set_security_env(). + * CardEdge does not use a padding indicator byte, so we cannot + * delegate to iso7816_decipher(). + */ +static int +srbeid_decipher(sc_card_t *card, + const u8 *crgram, size_t crgram_len, u8 *out, size_t outlen) +{ + sc_apdu_t apdu; + u8 resp[256]; + int r; + + LOG_FUNC_CALLED(card->ctx); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); + apdu.data = crgram; + apdu.datalen = crgram_len; + apdu.lc = crgram_len; + apdu.resp = resp; + apdu.resplen = sizeof(resp); + apdu.le = 256; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "PSO DECIPHER failed"); + + if (apdu.resplen > outlen) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); + memcpy(out, resp, apdu.resplen); + LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); +} + +struct sc_card_driver * +sc_get_srbeid_driver(void) +{ + /* Save ISO ops for delegation, then override what we handle. */ + iso_ops = sc_get_iso7816_driver()->ops; + srbeid_ops = *iso_ops; + srbeid_ops.match_card = srbeid_match_card; + srbeid_ops.init = srbeid_init; + srbeid_ops.select_file = srbeid_select_file; + srbeid_ops.set_security_env = srbeid_set_security_env; + srbeid_ops.compute_signature = srbeid_compute_signature; + srbeid_ops.decipher = srbeid_decipher; + + return &srbeid_drv; +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index ac063d1f48..fecac4cbf6 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -281,6 +281,9 @@ enum { /* Lithuanian eID cards */ SC_CARD_TYPE_LTEID = 43000, + + /* Serbian cards (CardEdge PKI applet) */ + SC_CARD_TYPE_SRBEID_BASE = 44000, }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -326,6 +329,7 @@ extern sc_card_driver_t *sc_get_skeid_driver(void); extern sc_card_driver_t *sc_get_eoi_driver(void); extern sc_card_driver_t *sc_get_dtrust_driver(void); extern sc_card_driver_t *sc_get_lteid_driver(void); +extern sc_card_driver_t *sc_get_srbeid_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index aa2f523808..cbcbdcee91 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -144,6 +144,9 @@ static const struct _sc_driver_entry internal_card_drivers[] = { * driver's `match_card()` function. */ { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver }, { "esteid2025", (void *(*)(void)) sc_get_esteid2025_driver }, + /* srbeid: Serbian cards with CardEdge PKI applet (eID, health, PKS). + * Uses AID selection in match_card() for cards without a distinct ATR. */ + { "srbeid", (void *(*)(void)) sc_get_srbeid_driver }, { "coolkey", (void *(*)(void)) sc_get_coolkey_driver }, /* MUSCLE card applet returns 9000 on whatever AID is selected, see * https://github.com/JavaCardOS/MuscleCard-Applet/blob/master/musclecard/src/com/musclecard/CardEdge/CardEdge.java#L326 diff --git a/src/libopensc/pkcs15-srbeid.c b/src/libopensc/pkcs15-srbeid.c new file mode 100644 index 0000000000..a17e8d1182 --- /dev/null +++ b/src/libopensc/pkcs15-srbeid.c @@ -0,0 +1,584 @@ +/* + * pkcs15-srbeid.c: PKCS#15 emulation for Serbian cards using the + * CardEdge PKI applet. + * + * Copyright (C) 2026 LibreSCRS contributors + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#ifdef ENABLE_ZLIB +#include "compression.h" +#endif +#include "internal.h" +#include "log.h" +#include "pkcs15.h" + +/* CardEdge PKI applet AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) */ +static const u8 AID_PKCS15[] = { + 0xA0, 0x00, 0x00, 0x00, 0x63, + 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; +#define AID_PKCS15_LEN (sizeof(AID_PKCS15)) + +/* CardEdge cmapfile constants. */ +#define CE_CMAP_RECORD_SIZE 86u +#define CE_CMAP_FLAGS_OFFSET 80u +#define CE_CMAP_SIG_SIZE_OFFSET 82u +#define CE_CMAP_KX_SIZE_OFFSET 84u +#define CE_CMAP_VALID_CONTAINER 0x01u +#define CE_KEYS_BASE_FID 0x6000u +#define CE_KEY_KIND_PRIVATE 1u +#define CE_AT_KEYEXCHANGE 1u +#define CE_AT_SIGNATURE 2u +#define CE_PKI_ROOT_DIR_FID 0x7000u +#define CE_DIR_HEADER_SIZE 10u +#define CE_DIR_ENTRY_SIZE 12u + +/* CardEdge PIN constants */ +#define CE_PIN_REFERENCE 0x80u +#define CE_PIN_MAX_LENGTH 8u + +/* Private key FID formula. */ +static unsigned int +ce_private_key_fid(unsigned int cont_idx, + unsigned int key_pair_id) +{ + return CE_KEYS_BASE_FID | ((cont_idx << 4) & 0x0FF0u) | ((key_pair_id << 2) & 0x000Cu) | CE_KEY_KIND_PRIVATE; +} + +/* + * Select FID and read the entire file into a malloc'd buffer. + * Uses sc_select_file() (dispatched to card driver's select_file which + * handles CardEdge's proprietary FCI) and sc_read_binary(). + * + * *out_len receives the byte count; caller must free() the buffer. + * Returns SC_SUCCESS or a negative SC_ERROR_* code. + */ +static int +srbeid_read_file(sc_card_t *card, unsigned int fid, + u8 **buf_out, size_t *out_len) +{ + sc_path_t path = {0}; + sc_file_t *file = NULL; + u8 *buf; + int r; + + *buf_out = NULL; + *out_len = 0; + + path.value[0] = (u8)((fid >> 8) & 0xFF); + path.value[1] = (u8)(fid & 0xFF); + path.len = 2; + path.type = SC_PATH_TYPE_FILE_ID; + + r = sc_select_file(card, &path, &file); + if (r < 0) + return r; + + if (!file || file->size == 0) { + sc_file_free(file); + return SC_SUCCESS; + } + + if (file->size > 65536) { + sc_file_free(file); + return SC_ERROR_INVALID_DATA; + } + + buf = malloc(file->size); + if (!buf) { + sc_file_free(file); + return SC_ERROR_OUT_OF_MEMORY; + } + + r = sc_read_binary(card, 0, buf, file->size, 0); + sc_file_free(file); + if (r < 0) { + free(buf); + return r; + } + + *buf_out = buf; + *out_len = (size_t)r; + return SC_SUCCESS; +} + +/* One entry from a CardEdge directory file. */ +typedef struct ce_dir_entry { + char name[9]; /* 8-char name + NUL */ + unsigned fid; + int is_dir; +} ce_dir_entry_t; + +/* + * Parse a CardEdge directory file into an array of ce_dir_entry_t. + * + * CardEdge directories use a proprietary binary format: + * [10-byte header] [12-byte entries...] + * This is NOT ISO 7816-4 EF.DIR (ASN.1 BER-TLV application templates), + * so standard sc_enum_apps() / iso7816_read_ef_dir() cannot be used. + * + * *entries_out: caller must free(). Returns entry count or -1 on error. + */ +static int +ce_parse_dir(const u8 *data, size_t len, ce_dir_entry_t **entries_out) +{ + size_t count, i; + ce_dir_entry_t *entries; + + *entries_out = NULL; + if (len < CE_DIR_HEADER_SIZE) + return -1; + + count = (size_t)data[6] | ((size_t)data[7] << 8); + if (count == 0) + return 0; + + entries = calloc(count, sizeof(ce_dir_entry_t)); + if (!entries) + return -1; + + for (i = 0; i < count; i++) { + size_t off = CE_DIR_HEADER_SIZE + i * CE_DIR_ENTRY_SIZE; + int k; + + if (off + CE_DIR_ENTRY_SIZE > len) { + free(entries); + return -1; + } + /* Name: up to 8 ASCII chars, may not be NUL-terminated on card. */ + memcpy(entries[i].name, data + off, 8); + entries[i].name[8] = '\0'; + /* Strip trailing spaces/NULs. */ + k = 7; + while (k >= 0 && (entries[i].name[k] == ' ' || entries[i].name[k] == '\0')) + entries[i].name[k--] = '\0'; + entries[i].fid = (unsigned)data[off + 8] | ((unsigned)data[off + 9] << 8); + entries[i].is_dir = (data[off + 10] != 0); + } + + *entries_out = entries; + return (int)count; +} + +typedef struct cert_entry { + char label[32]; + unsigned cert_fid; + unsigned key_fid; + unsigned key_size_bits; + unsigned cont_id; + unsigned key_pair_id; /* CE_AT_KEYEXCHANGE or CE_AT_SIGNATURE */ +} cert_entry_t; + +/* Select AID_PKCS15 and enumerate certificates from mscp/cmapfile. + * *certs_out: caller must free(). Returns cert count or negative error. */ +static int +srbeid_enum_certs(sc_card_t *card, cert_entry_t **certs_out) +{ + u8 *dir_buf = NULL, *mscp_buf = NULL, *cmap_buf = NULL; + size_t dir_len = 0, mscp_len = 0, cmap_len = 0; + ce_dir_entry_t *root_entries = NULL, *mscp_entries = NULL; + int root_count = 0, mscp_count = 0; + unsigned mscp_fid = 0, cmap_fid = 0; + cert_entry_t *certs = NULL; + int ncerts = 0, cap = 8; + int r, i; + size_t cmap_offset = 0, cmap_nrec = 0; + + *certs_out = NULL; + + /* Select PKI applet. */ + if (iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) != SC_SUCCESS) { + r = SC_ERROR_CARD_CMD_FAILED; + goto out; + } + + /* Read root directory (FID 0x7000). */ + r = srbeid_read_file(card, CE_PKI_ROOT_DIR_FID, &dir_buf, &dir_len); + if (r < 0) + goto out; + + root_count = ce_parse_dir(dir_buf, dir_len, &root_entries); + if (root_count < 0) { + r = SC_ERROR_INVALID_DATA; + goto out; + } + + for (i = 0; i < root_count; i++) { + if (root_entries[i].is_dir && strcmp(root_entries[i].name, "mscp") == 0) { + mscp_fid = root_entries[i].fid; + break; + } + } + if (mscp_fid == 0) { + r = SC_ERROR_FILE_NOT_FOUND; + goto out; + } + + /* Read mscp directory. */ + r = srbeid_read_file(card, mscp_fid, &mscp_buf, &mscp_len); + if (r < 0) + goto out; + + mscp_count = ce_parse_dir(mscp_buf, mscp_len, &mscp_entries); + if (mscp_count < 0) { + r = SC_ERROR_INVALID_DATA; + goto out; + } + + certs = calloc((size_t)cap, sizeof(cert_entry_t)); + if (!certs) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + + for (i = 0; i < mscp_count; i++) { + ce_dir_entry_t *e = &mscp_entries[i]; + if (e->is_dir) + continue; + + if (strcmp(e->name, "cmapfile") == 0) { + cmap_fid = e->fid; + } else if (strlen(e->name) == 5) { + unsigned kp_id; + const char *lbl; + + if (strncmp(e->name, "kxc", 3) == 0) { + kp_id = CE_AT_KEYEXCHANGE; + lbl = "Key Exchange Certificate"; + } else if (strncmp(e->name, "ksc", 3) == 0) { + kp_id = CE_AT_SIGNATURE; + lbl = "Digital Signature Certificate"; + } else { + continue; + } + + if (ncerts >= cap) { + cert_entry_t *tmp = realloc(certs, + (size_t)(cap * 2) * sizeof(cert_entry_t)); + if (!tmp) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + certs = tmp; + cap *= 2; + } + + certs[ncerts].cont_id = (unsigned)(e->name[3] - '0') * 10 + (unsigned)(e->name[4] - '0'); + certs[ncerts].cert_fid = e->fid; + certs[ncerts].key_pair_id = kp_id; + snprintf(certs[ncerts].label, sizeof(certs[ncerts].label), "%s", lbl); + ncerts++; + } + } + + /* Read cmapfile and resolve key FIDs. */ + if (cmap_fid != 0) { + r = srbeid_read_file(card, cmap_fid, &cmap_buf, &cmap_len); + if (r == SC_SUCCESS) { + /* Optional 2-byte prefix present when (len-2) is a multiple of 86. */ + if (cmap_len >= 2 && (cmap_len - 2) % CE_CMAP_RECORD_SIZE == 0) + cmap_offset = 2; + cmap_nrec = (cmap_len - cmap_offset) / CE_CMAP_RECORD_SIZE; + } + } + + for (i = 0; i < ncerts; i++) { + unsigned ci = certs[i].cont_id; + + if (cmap_buf && ci < cmap_nrec) { + size_t rec = cmap_offset + (size_t)ci * CE_CMAP_RECORD_SIZE; + u8 flags = cmap_buf[rec + CE_CMAP_FLAGS_OFFSET]; + + if (flags & CE_CMAP_VALID_CONTAINER) { + size_t sz_off = (certs[i].key_pair_id == CE_AT_KEYEXCHANGE) + ? rec + CE_CMAP_KX_SIZE_OFFSET + : rec + CE_CMAP_SIG_SIZE_OFFSET; + unsigned kbits = (unsigned)cmap_buf[sz_off] | ((unsigned)cmap_buf[sz_off + 1] << 8); + if (kbits != 0) { + certs[i].key_size_bits = kbits; + certs[i].key_fid = ce_private_key_fid(ci, certs[i].key_pair_id); + } + } + } + sc_log(card->ctx, + "srbeid: cert[%d] \"%s\" cert_fid=0x%04x key_fid=0x%04x key_size=%u", + i, certs[i].label, certs[i].cert_fid, + certs[i].key_fid, certs[i].key_size_bits); + } + + *certs_out = certs; + certs = NULL; + r = ncerts; + +out: + free(dir_buf); + free(mscp_buf); + free(cmap_buf); + free(root_entries); + free(mscp_entries); + free(certs); + return r; +} + +/* + * Read the raw (possibly zlib-compressed) cert file and return DER bytes. + * + * CardEdge cert file layout: + * [CardFS len prefix: 2 bytes LE] + * [0x01 0x00] [uncompressed len: 2 bytes LE] [zlib data] — compressed + * OR [0x30 ...] — raw DER + */ +static int +srbeid_read_cert_der(sc_card_t *card, unsigned cert_fid, + u8 **der_out, size_t *der_len_out) +{ + u8 *raw = NULL; + size_t raw_len = 0; + const u8 *data; + size_t dlen; + int r; + + *der_out = NULL; + *der_len_out = 0; + + r = srbeid_read_file(card, cert_fid, &raw, &raw_len); + if (r < 0) + return r; + + if (raw_len < 6) { + free(raw); + return SC_ERROR_INVALID_DATA; + } + + /* Skip 2-byte CardFS length prefix. */ + data = raw + 2; + dlen = raw_len - 2; + + if (dlen >= 4 && data[0] == 0x01 && data[1] == 0x00) { + /* zlib-compressed DER */ +#ifdef ENABLE_ZLIB + size_t uncompressed_len = (size_t)data[2] | ((size_t)data[3] << 8); + u8 *der = NULL; + + r = sc_decompress_alloc(&der, &uncompressed_len, + data + 4, dlen - 4, COMPRESSION_ZLIB); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "srbeid: zlib decompress failed (ret=%d)", r); + free(raw); + return SC_ERROR_INVALID_DATA; + } + *der_out = der; + *der_len_out = uncompressed_len; +#else + sc_log(card->ctx, "srbeid: cert is zlib-compressed but zlib not available"); + free(raw); + return SC_ERROR_NOT_SUPPORTED; +#endif + } else if (dlen >= 1 && data[0] == 0x30) { + /* Uncompressed DER (ASN.1 SEQUENCE tag). */ + u8 *der = malloc(dlen); + if (!der) { + free(raw); + return SC_ERROR_OUT_OF_MEMORY; + } + memcpy(der, data, dlen); + *der_out = der; + *der_len_out = dlen; + } else { + sc_log(card->ctx, + "srbeid: cert FID 0x%04x: unknown format (byte0=0x%02x)", + cert_fid, data[0]); + free(raw); + return SC_ERROR_INVALID_DATA; + } + + free(raw); + return SC_SUCCESS; +} + +static int +sc_pkcs15emu_srbeid_init(sc_pkcs15_card_t *p15card) +{ + sc_card_t *card = p15card->card; + cert_entry_t *certs = NULL; + int ncerts, i, r = SC_SUCCESS; + + sc_log(card->ctx, "srbeid: pkcs15 bind"); + + ncerts = srbeid_enum_certs(card, &certs); + if (ncerts < 0) { + sc_log(card->ctx, "srbeid: cert enumeration failed: %d", ncerts); + return ncerts; + } + if (ncerts == 0) { + sc_log(card->ctx, "srbeid: no certificates found"); + goto out; + } + + /* Set card label and manufacturer. */ + set_string(&p15card->tokeninfo->label, "Serbian CardEdge"); + set_string(&p15card->tokeninfo->manufacturer_id, "CardEdge"); + + /* Query PIN tries_left via card driver's pin_cmd. */ + { + struct sc_pin_cmd_data pin_data = {0}; + int pin_tries_left = -1; + + pin_data.cmd = SC_PIN_CMD_GET_INFO; + pin_data.pin_type = SC_AC_CHV; + pin_data.pin_reference = CE_PIN_REFERENCE; + + /* Best-effort: failure to query PIN status is not fatal. */ + if (sc_pin_cmd(card, &pin_data, &pin_tries_left) >= 0 && pin_tries_left < 0) + pin_tries_left = pin_data.pin1.tries_left; + sc_log(card->ctx, "srbeid: PIN tries_left=%d", pin_tries_left); + + /* ---- PIN auth object ---- + * Must be registered before private keys so auth_id links work. */ + { + sc_pkcs15_auth_info_t auth_info = {0}; + sc_pkcs15_object_t auth_obj = {0}; + + auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + auth_info.auth_method = SC_AC_CHV; + auth_info.tries_left = pin_tries_left; + auth_info.attrs.pin.reference = CE_PIN_REFERENCE; + auth_info.attrs.pin.min_length = 4; + auth_info.attrs.pin.max_length = CE_PIN_MAX_LENGTH; + auth_info.attrs.pin.stored_length = CE_PIN_MAX_LENGTH; + auth_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + auth_info.attrs.pin.pad_char = 0x00; + auth_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_NEEDS_PADDING; + auth_info.path.aid.len = AID_PKCS15_LEN; + memcpy(auth_info.path.aid.value, AID_PKCS15, AID_PKCS15_LEN); + auth_info.auth_id.len = 1; + auth_info.auth_id.value[0] = 1; + + strncpy(auth_obj.label, "User PIN", sizeof(auth_obj.label) - 1); + auth_obj.auth_id.len = 0; + auth_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; + + r = sc_pkcs15emu_add_pin_obj(p15card, &auth_obj, &auth_info); + if (r < 0) { + sc_log(card->ctx, "srbeid: add PIN obj failed: %d", r); + goto out; + } + } + } + + for (i = 0; i < ncerts; i++) { + sc_pkcs15_prkey_info_t key_info = {0}; + sc_pkcs15_object_t key_obj = {0}; + sc_pkcs15_cert_info_t cert_info = {0}; + sc_pkcs15_object_t cert_obj = {0}; + u8 *der = NULL; + size_t der_len = 0; + int is_kxc = (certs[i].key_pair_id == CE_AT_KEYEXCHANGE); + + /* ---- Private key object ---- */ + + key_info.id.len = 1; + key_info.id.value[0] = (u8)(i + 1); + key_info.native = 1; + key_info.key_reference = (int)certs[i].key_fid; + key_info.modulus_length = certs[i].key_size_bits + ? certs[i].key_size_bits + : 2048; + + /* + * Key usage flags by type: + * kxc (AT_KEYEXCHANGE) — encryption / key wrapping / decryption + signing + * (TLS client auth uses the key exchange cert for signing) + * ksc (AT_SIGNATURE) — digital signature / non-repudiation only + */ + if (is_kxc) { + key_info.usage = SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_WRAP | SC_PKCS15_PRKEY_USAGE_UNWRAP | SC_PKCS15_PRKEY_USAGE_SIGN; + } else { + key_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; + } + + /* + * Set only the AID on key_info.path (path.len stays 0). + * This makes select_key_file() select the PKI applet via AID + * before calling set_security_env(), without appending a file + * path that would fail on CardEdge's non-TLV FCI. + * + * The key FID is passed via key_info.key_reference and + * reconstructed in set_security_env() from the low byte. + */ + key_info.path.aid.len = AID_PKCS15_LEN; + memcpy(key_info.path.aid.value, AID_PKCS15, AID_PKCS15_LEN); + + strncpy(key_obj.label, certs[i].label, sizeof(key_obj.label) - 1); + key_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + key_obj.auth_id.len = 1; + key_obj.auth_id.value[0] = 1; + + r = sc_pkcs15emu_add_rsa_prkey(p15card, &key_obj, &key_info); + if (r < 0) { + sc_log(card->ctx, "srbeid: add prkey[%d] failed: %d", i, r); + goto out; + } + + /* ---- Certificate object ---- */ + if (srbeid_read_cert_der(card, certs[i].cert_fid, &der, &der_len) < 0) { + sc_log(card->ctx, "srbeid: could not read cert[%d] DER", i); + continue; + } + + cert_info.id.len = 1; + cert_info.id.value[0] = (u8)(i + 1); + cert_info.authority = 0; + + /* Store DER directly in the PKCS#15 value buffer. */ + cert_info.value.value = der; /* ownership transferred */ + cert_info.value.len = der_len; + + strncpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label) - 1); + + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + if (r < 0) { + sc_log(card->ctx, "srbeid: add cert[%d] failed: %d", i, r); + free(der); + goto out; + } + /* der ownership now belongs to p15card; do not free. */ + } + + sc_log(card->ctx, "srbeid: pkcs15 bind OK (%d certs)", ncerts); + +out: + free(certs); + return r; +} + +int +sc_pkcs15emu_srbeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + (void)aid; + + if (p15card->card->type != SC_CARD_TYPE_SRBEID_BASE) + return SC_ERROR_WRONG_CARD; + + return sc_pkcs15emu_srbeid_init(p15card); +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 177f795752..bcfdf690f8 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -64,6 +64,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "eOI", sc_pkcs15emu_eoi_init_ex }, { "dtrust", sc_pkcs15emu_dtrust_init_ex }, { "lteid", sc_pkcs15emu_lteid_init_ex }, + { "srbeid", sc_pkcs15emu_srbeid_init_ex }, { NULL, NULL } }; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index b6883190d1..fcbf861823 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -59,6 +59,7 @@ int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_eoi_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_dtrust_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_lteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_srbeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From 28ace0595ee505af34940627c7f3ab8b45f6a90b Mon Sep 17 00:00:00 2001 From: hirashix0 Date: Thu, 2 Apr 2026 14:21:29 +0200 Subject: [PATCH 4174/4321] srbeid: Address review comments Move shared constants (AID_PKCS15, AID_PKCS15_LEN, CE_KEYS_BASE_FID) into card-srbeid.h, following the pattern used by card-eoi.h and card-cac-common.h. Replace magic 256 with sizeof(resp) for apdu.le in compute_signature and decipher. Fix double space in copyright lines. --- src/libopensc/Makefile.am | 2 +- src/libopensc/card-srbeid.c | 16 ++++------------ src/libopensc/card-srbeid.h | 35 +++++++++++++++++++++++++++++++++++ src/libopensc/pkcs15-srbeid.c | 10 ++-------- 4 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 src/libopensc/card-srbeid.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 31ef4b7635..2132affd4b 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -13,7 +13,7 @@ noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \ pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ jpki.h sc-ossl-compat.h card-npa.h card-openpgp.h \ - card-eoi.h card-dtrust.h ccid-types.h reader-tr03119.h \ + card-eoi.h card-dtrust.h card-srbeid.h ccid-types.h reader-tr03119.h \ card-cac-common.h card-cardos-common.h AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ diff --git a/src/libopensc/card-srbeid.c b/src/libopensc/card-srbeid.c index 16a71c43ee..b50ecc4dea 100644 --- a/src/libopensc/card-srbeid.c +++ b/src/libopensc/card-srbeid.c @@ -5,7 +5,7 @@ * same CardEdge PKCS#15 applet. Cards are matched either by ATR * (Gemalto 2014+ eID) or by AID selection. * - * Copyright (C) 2026 LibreSCRS contributors + * Copyright (C) 2026 LibreSCRS contributors * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,21 +28,13 @@ #include +#include "card-srbeid.h" #include "internal.h" #include "log.h" -/* CardEdge PKI applet AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) */ -static const u8 AID_PKCS15[] = { - 0xA0, 0x00, 0x00, 0x00, 0x63, - 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; -#define AID_PKCS15_LEN (sizeof(AID_PKCS15)) - /* MSE algorithm byte for RSA-2048 PKCS#1 v1.5 */ #define CE_MSE_ALG_RSA2048 0x02u -/* Base address of key files: key FID = CE_KEYS_BASE_FID | container/type bits */ -#define CE_KEYS_BASE_FID 0x6000u - static struct sc_card_operations srbeid_ops; static const struct sc_card_operations *iso_ops; @@ -256,7 +248,7 @@ srbeid_compute_signature(sc_card_t *card, apdu.lc = datalen; apdu.resp = resp; apdu.resplen = sizeof(resp); - apdu.le = 256; + apdu.le = sizeof(resp); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -292,7 +284,7 @@ srbeid_decipher(sc_card_t *card, apdu.lc = crgram_len; apdu.resp = resp; apdu.resplen = sizeof(resp); - apdu.le = 256; + apdu.le = sizeof(resp); r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/card-srbeid.h b/src/libopensc/card-srbeid.h new file mode 100644 index 0000000000..64f3fd0d50 --- /dev/null +++ b/src/libopensc/card-srbeid.h @@ -0,0 +1,35 @@ +/* + * card-srbeid.h: Shared definitions for Serbian CardEdge card and PKCS#15 drivers. + * + * Copyright (C) 2026 LibreSCRS contributors + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CARD_SRBEID_H +#define CARD_SRBEID_H + +#include "types.h" + +/* CardEdge PKI applet AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) */ +static const u8 AID_PKCS15[] = { + 0xA0, 0x00, 0x00, 0x00, 0x63, + 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; +#define AID_PKCS15_LEN (sizeof(AID_PKCS15)) + +/* Base address of key files: key FID = CE_KEYS_BASE_FID | container/type bits */ +#define CE_KEYS_BASE_FID 0x6000u + +#endif /* CARD_SRBEID_H */ diff --git a/src/libopensc/pkcs15-srbeid.c b/src/libopensc/pkcs15-srbeid.c index a17e8d1182..1eb207559a 100644 --- a/src/libopensc/pkcs15-srbeid.c +++ b/src/libopensc/pkcs15-srbeid.c @@ -2,7 +2,7 @@ * pkcs15-srbeid.c: PKCS#15 emulation for Serbian cards using the * CardEdge PKI applet. * - * Copyright (C) 2026 LibreSCRS contributors + * Copyright (C) 2026 LibreSCRS contributors * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,23 +29,17 @@ #ifdef ENABLE_ZLIB #include "compression.h" #endif +#include "card-srbeid.h" #include "internal.h" #include "log.h" #include "pkcs15.h" -/* CardEdge PKI applet AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) */ -static const u8 AID_PKCS15[] = { - 0xA0, 0x00, 0x00, 0x00, 0x63, - 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; -#define AID_PKCS15_LEN (sizeof(AID_PKCS15)) - /* CardEdge cmapfile constants. */ #define CE_CMAP_RECORD_SIZE 86u #define CE_CMAP_FLAGS_OFFSET 80u #define CE_CMAP_SIG_SIZE_OFFSET 82u #define CE_CMAP_KX_SIZE_OFFSET 84u #define CE_CMAP_VALID_CONTAINER 0x01u -#define CE_KEYS_BASE_FID 0x6000u #define CE_KEY_KIND_PRIVATE 1u #define CE_AT_KEYEXCHANGE 1u #define CE_AT_SIGNATURE 2u From 34658c498917d2fdba05202129ede63b955fcb0f Mon Sep 17 00:00:00 2001 From: Denis Aleksandrov Date: Fri, 3 Apr 2026 09:41:02 -0400 Subject: [PATCH 4175/4321] pkcs11-tool: honor --label when selecting keys for sign/decrypt/encrypt/verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit find_object() and find_object_flags() passed a hardcoded NULL for the label parameter to find_object_type_or_id_or_label(), so --label was silently ignored during all key-lookup operations that go through those helpers. Only the PKCS#11-URI code paths already forwarded opt_object_label correctly. Add a const char *label parameter to both find_object() and find_object_flags() and thread it through to find_object_type_or_id_or_label(). Update the four action-dispatch blocks (sign, decrypt, encrypt, verify) to pass opt_object_label on Path A2 (mf_flags known, no URI) and Path C (legacy fallback). All other callers — iteration loops, wrap/unwrap, internal helpers — pass NULL explicitly, preserving existing behaviour. Reproducer: create an RSA and an ECC private key on the same token, then sign with --label ecc_key --mechanism ECDSA-SHA1. Before this fix, C_FindObjectsInit received only {CKA_CLASS=CKO_PRIVATE_KEY} and the first key (RSA) was always returned, causing C_SignInit to fail with CKR_MECHANISM_INVALID. After this fix the correct key is selected. --- src/tools/pkcs11-tool.c | 70 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f3ac4e6bf1..452ac49617 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -648,10 +648,10 @@ static int find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, const char *, int obj_index); static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, CK_OBJECT_HANDLE_PTR, - const unsigned char *, size_t id_len, int obj_index); + const unsigned char *, size_t id_len, const char *label, int obj_index); static int find_object_flags(CK_SESSION_HANDLE, uint16_t flags, CK_OBJECT_HANDLE_PTR, - const unsigned char *, size_t id_len, int obj_index); + const unsigned char *, size_t id_len, const char *label, int obj_index); static int find_object_flags_and_type_or_id_or_label(CK_SESSION_HANDLE sess, uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, CK_OBJECT_CLASS cls, int cls_set, @@ -1540,7 +1540,7 @@ int main(int argc, char * argv[]) } else { find_object_flags(session, mf_flags, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + opt_object_id_len, opt_object_label, 0); } } else if (opt_uri && opt_uri->type) { /* If type in PKCS#11 URI is set, check the type and use it */ @@ -1552,9 +1552,9 @@ int main(int argc, char * argv[]) util_fatal("Private/secret key not found"); } } else if (!find_object(session, CKO_PRIVATE_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) { + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) { if (!find_object(session, CKO_SECRET_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) util_fatal("Private/secret key not found"); } } @@ -1574,7 +1574,7 @@ int main(int argc, char * argv[]) } else { find_object_flags(session, mf_flags, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + opt_object_id_len, opt_object_label, 0); } } else if (opt_uri && opt_uri->type) { /* If type in PKCS#11 URI is set, check the type and use it */ @@ -1586,9 +1586,9 @@ int main(int argc, char * argv[]) util_fatal("Private/secret key not found"); } } else if (!find_object(session, CKO_PRIVATE_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) if (!find_object(session, CKO_SECRET_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) util_fatal("Private/secret key not found"); } @@ -1608,7 +1608,7 @@ int main(int argc, char * argv[]) } else { find_object_flags(session, mf_flags, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + opt_object_id_len, opt_object_label, 0); } } else if (opt_uri && opt_uri->type) { /* If type in PKCS#11 URI is set, check the type and use it */ @@ -1620,9 +1620,9 @@ int main(int argc, char * argv[]) util_fatal("Public/Secret key not found"); } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) if (!find_object(session, CKO_SECRET_KEY, &object, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, opt_object_label, 0)) util_fatal("Public/Secret key not found"); } @@ -1642,7 +1642,7 @@ int main(int argc, char * argv[]) } else { find_object_flags(session, mf_flags, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0); + opt_object_id_len, opt_object_label, 0); } } else if (opt_uri && opt_uri->type) { /* If type in PKCS#11 URI is set, check the type and use it */ @@ -1655,10 +1655,10 @@ int main(int argc, char * argv[]) } } else if (!find_object(session, CKO_PUBLIC_KEY, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0) && + opt_object_id_len, opt_object_label, 0) && !find_object(session, CKO_CERTIFICATE, &object, opt_object_id_len ? opt_object_id : NULL, - opt_object_id_len, 0)) + opt_object_id_len, opt_object_label, 0)) util_fatal("Public key nor certificate not found"); } @@ -4144,9 +4144,9 @@ unwrap_key(CK_SESSION_HANDLE session) ssize_t sz; if (!find_object(session, CKO_PRIVATE_KEY, &hUnwrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) if (!find_object(session, CKO_SECRET_KEY, &hUnwrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) util_fatal("Private/secret key not found"); if (!opt_mechanism_used) @@ -4308,14 +4308,14 @@ wrap_key(CK_SESSION_HANDLE session) if (sc_hex_to_bin(opt_application_id, hkey_id, &hkey_id_len)) util_fatal("Invalid application-id \"%s\"\n", opt_application_id); - if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, 0)) - if (!find_object(session, CKO_PRIVATE_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, 0)) + if (!find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, NULL, 0)) + if (!find_object(session, CKO_PRIVATE_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len, NULL, 0)) util_fatal("Key to be wrapped not found"); if (!find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) if (!find_object(session, CKO_SECRET_KEY, &hWrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) util_fatal("Wrapping key not found"); rv = p11->C_WrapKey(session, &mechanism, hWrappingKey, hkey, pWrappedKey, &pulWrappedKeyLen); @@ -5886,20 +5886,20 @@ find_object_type_or_id_or_label(CK_SESSION_HANDLE sess, static int find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, CK_OBJECT_HANDLE_PTR ret, - const unsigned char *id, size_t id_len, int obj_index) + const unsigned char *id, size_t id_len, const char *label, int obj_index) { - return find_object_type_or_id_or_label(sess, cls, 1, ret, id, id_len, NULL, obj_index); + return find_object_type_or_id_or_label(sess, cls, 1, ret, id, id_len, label, obj_index); } static int find_object_flags(CK_SESSION_HANDLE sess, uint16_t mf_flags, CK_OBJECT_HANDLE_PTR ret, - const unsigned char *id, size_t id_len, int obj_index) + const unsigned char *id, size_t id_len, const char *label, int obj_index) { int count; char err_key_types[1024] = {0}; if (mf_flags & MF_CKO_SECRET_KEY) { - count = find_object(sess, CKO_SECRET_KEY, ret, id, id_len, obj_index); + count = find_object(sess, CKO_SECRET_KEY, ret, id, id_len, label, obj_index); if (count) return count; @@ -7786,7 +7786,7 @@ static CK_ULONG get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE return 0; } - if (!find_object(sess, CKO_PUBLIC_KEY, &pubkey, id, idLen, 0)) { + if (!find_object(sess, CKO_PUBLIC_KEY, &pubkey, id, idLen, NULL, 0)) { free(id); fprintf(stderr, "couldn't find the corresponding pubkey\n"); return 0; @@ -8256,7 +8256,7 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv return NULL; } - if (!find_object(session, CKO_PUBLIC_KEY, &pubkeyObject, id, idLen, 0)) { + if (!find_object(session, CKO_PUBLIC_KEY, &pubkeyObject, id, idLen, NULL, 0)) { free(id); fprintf(stderr, "couldn't find the corresponding pubkey for validation\n"); return NULL; @@ -8511,7 +8511,7 @@ static int test_signature(CK_SESSION_HANDLE sess) } printf("Signatures (currently only for RSA)\n"); - for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) { + for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, NULL, j); j++) { printf(" testing key %d ", j); if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) { printf("(%s) ", label); @@ -8683,7 +8683,7 @@ static int test_signature(CK_SESSION_HANDLE sess) break; ck_mech.mechanism = mechTypes[i]; j = 1; /* j-th signature key */ - while (find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j++) != 0) { + while (find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, NULL, j++) != 0) { unsigned char *id; CK_ULONG idLen; CK_ULONG modLenBits; @@ -8707,7 +8707,7 @@ static int test_signature(CK_SESSION_HANDLE sess) if ((id = getID(sess, privKeyObject, &idLen)) != NULL) { int r; - r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, idLen, 0); + r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, idLen, NULL, 0); free(id); if (r == 0) { printf(" -- can't find corresponding public key, skipping\n"); @@ -8849,7 +8849,7 @@ static int test_verify(CK_SESSION_HANDLE sess) printf("Verify (currently only for RSA)\n"); - for (i = 0; find_object(sess, CKO_PRIVATE_KEY, &priv_key, NULL, 0, i); i++) { + for (i = 0; find_object(sess, CKO_PRIVATE_KEY, &priv_key, NULL, 0, NULL, i); i++) { char *label; unsigned char *id; CK_ULONG id_len; @@ -8873,7 +8873,7 @@ static int test_verify(CK_SESSION_HANDLE sess) if ((id = getID(sess, priv_key, &id_len)) != NULL) { int r; - r = find_object(sess, CKO_PUBLIC_KEY, &pub_key, id, id_len, 0); + r = find_object(sess, CKO_PUBLIC_KEY, &pub_key, id, id_len, NULL, 0); free(id); if (r == 0) { printf(" -- can't find corresponding public key, skipping\n"); @@ -9051,7 +9051,7 @@ static int test_unwrap(CK_SESSION_HANDLE sess) } printf("Key unwrap (currently only for RSA)\n"); - for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) { + for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, NULL, j); j++) { printf(" testing key %d ", j); if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) { printf("(%s) ", label); @@ -9363,7 +9363,7 @@ static int test_decrypt(CK_SESSION_HANDLE sess) } printf("Decryption (currently only for RSA)\n"); - for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) { + for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, NULL, j); j++) { printf(" testing key %d", j); if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) { printf(" (%s)", label); @@ -9381,7 +9381,7 @@ static int test_decrypt(CK_SESSION_HANDLE sess) if ((id = getID(sess, privKeyObject, &id_len)) != NULL) { int r; - r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, id_len, 0); + r = find_object(sess, CKO_PUBLIC_KEY, &pubKeyObject, id, id_len, NULL, 0); free(id); if (r == 0) { printf(" -- can't find corresponding public key, skipping\n"); @@ -9592,7 +9592,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE fclose(f); /* Get for a not-yet-existing ID */ - while(find_object(session, CKO_PRIVATE_KEY, &priv_key, id, id_len, 0)) + while(find_object(session, CKO_PRIVATE_KEY, &priv_key, id, id_len, NULL, 0)) id[0]++; printf("\n*** Generating a %s key pair ***\n", opt_key_type); From 2b204ecf5938861be98f34d197fd8408cde25671 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 10 Mar 2026 17:03:38 +0100 Subject: [PATCH 4176/4321] CI: enable Dependabot for actions and vcpkg --- .github/dependabot.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..251ff26b4a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + # https://learn.microsoft.com/en-us/vcpkg/concepts/dependabot + - package-ecosystem: "vcpkg" + directory: "/.github/" # Location of vcpkg.json file + schedule: + interval: "weekly" + + # https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/keeping-your-actions-up-to-date-with-dependabot + - package-ecosystem: "github-actions" + # Workflow files stored in the default location of `.github/workflows` + # You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`. + directory: "/" + schedule: + interval: "weekly" From 2690f6aaeba5ea54cf211e36ac54dc0513cf269b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 14 Apr 2026 16:34:49 +0200 Subject: [PATCH 4177/4321] Specify what types of bugs are expected for private reporting --- SECURITY.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 5e0c95891f..c73efb1834 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,3 +23,24 @@ project developers frankmorgner(at)gmail.com, deengert(at)gmail.com and/or jakuje(at)gmail.com . You can expect update on the issue no later than in two weeks. + +## What Qualifies as a Security Issue + +Please use the private vulnerability reporting process only for issues that have **security impact**. This includes, but is not limited to: + +- Memory safety issues such as buffer overflows, use-after-free, or out-of-bounds writes +- Authentication or authorization bypasses +- Cryptographic weaknesses +- Information disclosure vulnerabilities (e.g., private keys, or PINs) +- Privilege escalation or unintended access to protected functionality +- Code execution vulnerabilities, including arbitrary code execution or command injection + +The following types of issues should not be reported as security vulnerabilities and should instead be filed as normal public issues: + +- Build failures or installation problems +- General bugs without security impact +- Feature requests or usability improvements +- Performance issues +- Minor crashes without a clear security implication + +If you are unsure whether your finding qualifies as a security issue, please err on the side of caution and report it through the private channel. From 8ad96adc5fea0cef923a2a679600f3a5c4c5bfce Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 15 Apr 2026 15:10:42 -0500 Subject: [PATCH 4178/4321] Changes for OpenSSL-4.0.0 Changes to get OpenSC to compile with OpenSSl-4.0.0 OpenSSL says: "Opaque Structures: ASN1_STRING has been made opaque, and further work has been done to make X509 structures more memory-efficient and const-correct." ASN1_STRING was made opaque thus requiring the use of ASN1_STRING_get0_data, and ASN1_STRING_length. These routines have been in OpenSSL since 1.1.1 and are also in libressl. ASN1_STRING_get0_data returns a const pointer, so the data can not be changed. There are a number of reverse() functions one of which was reversing the bytes in a EC pubkey. Changes not addressed: "Global Cleanup: libcrypto no longer uses atexit() for cleanup; OPENSSL_cleanup() now runs in a global destructor." On branch OpenSSL-4.0.0 Changes to be committed: modified: src/libopensc/cwa-dnie.c modified: src/pkcs11/openssl.c modified: src/pkcs15init/pkcs15-oberthur-awp.c modified: src/tests/p11test/p11test_case_common.c modified: src/tools/netkey-tool.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c --- src/libopensc/cwa-dnie.c | 2 +- src/pkcs11/openssl.c | 14 ++++++---- src/pkcs15init/pkcs15-oberthur-awp.c | 16 +++++------ src/tests/p11test/p11test_case_common.c | 24 ++++++++-------- src/tools/netkey-tool.c | 37 +++++++++++++++++-------- src/tools/pkcs11-tool.c | 22 +++++++-------- src/tools/pkcs15-init.c | 4 +-- 7 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 47f3792dad..6020921dbc 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -646,7 +646,7 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce dnie_private_data_t *priv_data = GET_DNIE_PRIV_DATA(card); LOG_FUNC_CALLED(card->ctx); - X509_NAME *issuer = X509_get_issuer_name(icc_intermediate_ca_cert); + const X509_NAME *issuer = X509_get_issuer_name(icc_intermediate_ca_cert); if (issuer) { buf = X509_NAME_oneline(issuer, buf, 0); if (!buf) { diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 0a5d4394a2..a4027339b2 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -463,6 +463,7 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len EC_POINT *P; BIGNUM *X, *Y; ASN1_OCTET_STRING *octet = NULL; + unsigned char *octet_rev = NULL; char paramset[2] = "A"; int r = -1, ret_vrf = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -516,13 +517,16 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len if (group && pubkey_len <= LONG_MAX) { const unsigned char *p = pubkey; octet = d2i_ASN1_OCTET_STRING(NULL, &p, (long)pubkey_len); + if (octet) + octet_rev = malloc(ASN1_STRING_length(octet)); } - if (group && octet) { - reverse(octet->data, octet->length); - Y = BN_bin2bn(octet->data, octet->length / 2, NULL); - X = BN_bin2bn((const unsigned char*)octet->data + - octet->length / 2, octet->length / 2, NULL); + if (group && octet && octet_rev) { + memcpy(octet_rev, ASN1_STRING_get0_data(octet), ASN1_STRING_length(octet)); + reverse(octet_rev, ASN1_STRING_length(octet)); + Y = BN_bin2bn(octet_rev, ASN1_STRING_length(octet) / 2, NULL); + X = BN_bin2bn(octet_rev + ASN1_STRING_length(octet) / 2, ASN1_STRING_length(octet) / 2, NULL); ASN1_OCTET_STRING_free(octet); + free(octet_rev); P = EC_POINT_new(group); if (P && X && Y) r = EC_POINT_set_affine_coordinates(group, P, X, Y, NULL); diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 22c943127b..fdb06ab6b4 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -51,21 +51,21 @@ awp_get_commonName(X509 *x) r = X509_NAME_get_index_by_NID(X509_get_subject_name(x), NID_commonName, -1); if (r >= 0) { - X509_NAME_ENTRY *ne; - ASN1_STRING *a_str; + const X509_NAME_ENTRY *ne; + const ASN1_STRING *a_str; if (!(ne = X509_NAME_get_entry(X509_get_subject_name(x), r))) ; else if (!(a_str = X509_NAME_ENTRY_get_data(ne))) ; - else if (a_str->type == 0x0C) { - ret = malloc(a_str->length + 1); + else if (ASN1_STRING_type(a_str) == V_ASN1_UTF8STRING) { + ret = malloc(ASN1_STRING_length(a_str) + 1); if (ret) { - memcpy(ret, a_str->data, a_str->length); - *(ret + a_str->length) = '\0'; + memcpy(ret, ASN1_STRING_get0_data(a_str), ASN1_STRING_length(a_str)); + + *(ret + ASN1_STRING_length(a_str)) = '\0'; } - } - else { + } else { unsigned char *tmp = NULL; r = ASN1_STRING_to_UTF8(&tmp, a_str); diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 1dd6eaba67..f571cd1598 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -776,34 +776,34 @@ int callback_public_keys(test_certs_t *objects, switch (o->key_type) { #ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: - if (strcmp((char *)curve->data, "edwards25519") == 0) { + if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards25519") == 0) { evp_type = EVP_PKEY_ED25519; break; #ifdef EVP_PKEY_ED448 - } else if (strcmp((char *)curve->data, "edwards448") == 0) { + } else if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards448") == 0) { evp_type = EVP_PKEY_ED448; break; #endif /* EVP_PKEY_ED448 */ } debug_print(" [WARN %s ] Unknown curve name. " " expected edwards25519 or edwards448, got %s", - o->id_str, curve->data); + o->id_str, ASN1_STRING_get0_data(curve)); break; #endif #ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: - if (strcmp((char *)curve->data, "curve25519") == 0) { + if (strcmp((char *)ASN1_STRING_get0_data(curve), "curve25519") == 0) { evp_type = EVP_PKEY_X25519; break; #ifdef EVP_PKEY_X448 - } else if (strcmp((char *)curve->data, "curve448") == 0) { + } else if (strcmp((char *)ASN1_STRING_get0_data(curve), "curve448") == 0) { evp_type = EVP_PKEY_X448; break; #endif /* EVP_PKEY_X448 */ } debug_print(" [WARN %s ] Unknown curve name. " " expected curve25519 or curve448, got %s", - o->id_str, curve->data); + o->id_str, ASN1_STRING_get0_data(curve)); break; #endif default: @@ -893,14 +893,14 @@ int callback_public_keys(test_certs_t *objects, break; #endif } - if (os->length != exp_length) { + if (ASN1_STRING_length(os) != exp_length) { debug_print(" [WARN %s ] Invalid length of EC_POINT value. Got %d, expected %d", - o->id_str, os->length, exp_length); + o->id_str, ASN1_STRING_length(os), exp_length); return -1; } key = EVP_PKEY_new_raw_public_key(evp_type, NULL, - (const uint8_t *)os->data, - os->length); + (const uint8_t *)ASN1_STRING_get0_data(os), + ASN1_STRING_length(os)); if (key == NULL) { debug_print(" [WARN %s ] Out of memory", o->id_str); ASN1_STRING_free(os); @@ -925,8 +925,8 @@ int callback_public_keys(test_certs_t *objects, } if (EVP_PKEY_get_raw_public_key(o->key, pub, &publen) != 1 || - publen != (size_t)os->length || - memcmp(pub, os->data, publen) != 0) { + publen != (size_t)ASN1_STRING_length(os) || + memcmp(pub, ASN1_STRING_get0_data(os), publen) != 0) { debug_print(" [WARN %s ] Got different public" "key then from the certificate", o->id_str); diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 23bab2a8ec..683ac182bd 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -144,25 +144,38 @@ static void show_certs(sc_card_t *card) if(q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6; printf(", Len=%d\n", (q[2]<<8)|q[3]); if((c=d2i_X509(NULL,&q,f->size))){ - char buf2[2000]; - if (X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + int idx; + const X509_NAME_ENTRY *ne = NULL; /* no free */ + const ASN1_STRING *a_str = NULL; /* no free */ + int out_len = 0; + unsigned char *tmp = NULL; + + idx = X509_NAME_get_index_by_NID(X509_get_subject_name(c), NID_commonName, -1); + if (idx >= 0 && + ((ne = X509_NAME_get_entry(X509_get_subject_name(c), idx)) != NULL) && + ((a_str = X509_NAME_ENTRY_get_data(ne)) != NULL) && + ((out_len = ASN1_STRING_to_UTF8(&tmp, a_str)) > 0)) { + printf(" Subject-CN: %s\n", tmp); + OPENSSL_free(tmp); + tmp = NULL; + } else { sc_log_openssl(card->ctx); printf(" Invalid Subject-CN\n"); - X509_free(c); - continue; } - printf(" Subject-CN: %s\n", buf2); - if (X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + + idx = X509_NAME_get_index_by_NID(X509_get_issuer_name(c), NID_commonName, -1); + if (idx >= 0 && + ((ne = X509_NAME_get_entry(X509_get_issuer_name(c), idx)) != NULL) && + ((a_str = X509_NAME_ENTRY_get_data(ne)) != NULL) && + ((out_len = ASN1_STRING_to_UTF8(&tmp, a_str)) > 0)) { + printf(" Issuer-CN: %s\n", tmp); + OPENSSL_free(tmp); + tmp = NULL; + } else { sc_log_openssl(card->ctx); printf(" Invalid Issuer-CN\n"); - X509_free(c); - continue; } - printf(" Issuer-CN: %s\n", buf2); X509_free(c); - } else { - sc_log_openssl(card->ctx); - printf(" Invalid Certificate-Data\n"); } } else printf(", empty\n"); } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 452ac49617..cfc7486faa 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7389,8 +7389,8 @@ static int read_object(CK_SESSION_HANDLE session) #endif point = EC_POINT_new(group); if (os) { - a = os->data; - a_len = os->length; + a = ASN1_STRING_get0_data(os); + a_len = ASN1_STRING_length(os); success = EC_POINT_oct2point(group, point, a, a_len, NULL); } if (!success) { /* Workaround for broken PKCS#11 modules */ @@ -7464,9 +7464,9 @@ static int read_object(CK_SESSION_HANDLE session) a = params; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { - if (strcmp((char *)curve->data, "edwards25519") && - strcmp((char *)curve->data, "curve25519")) { - util_fatal("Unknown curve name \"%si\"", curve->data); + if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards25519") && + strcmp((char *)ASN1_STRING_get0_data(curve), "curve25519")) { + util_fatal("Unknown curve name \"%si\"", (char *)ASN1_STRING_get0_data(curve)); } ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { @@ -7526,26 +7526,26 @@ static int read_object(CK_SESSION_HANDLE session) } } - if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) /* note extra bit */ + if (type == CKK_EC_EDWARDS && len == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_ED25519; #ifdef EVP_PKEY_ED448 - else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) + else if (type == CKK_EC_EDWARDS && len == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #ifdef EVP_PKEY_X25519 - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) /* note extra bit */ + else if (type == CKK_EC_MONTGOMERY && len == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ #ifdef EVP_PKEY_X448 - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(448)) + else if (type == CKK_EC_MONTGOMERY && len == BYTES4BITS(448)) raw_pk = EVP_PKEY_X448; #endif /* EVP_PKEY_X448 */ else util_fatal("Invalid or not supported CKK_EC_EDWARDS or CKK_EC_MONTGOMERY public key"); key = EVP_PKEY_new_raw_public_key(raw_pk, NULL, - (const uint8_t *)os->data, - os->length); + (const uint8_t *)ASN1_STRING_get0_data(os), + ASN1_STRING_length(os)); ASN1_STRING_free(os); if (key == NULL) { util_fatal("out of memory"); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e011232987..b978e0677a 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -2593,8 +2593,8 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen, size_t expected) static char * cert_common_name(X509 *x509) { - X509_NAME_ENTRY *ne = NULL; - ASN1_STRING *a_str = NULL; + const X509_NAME_ENTRY *ne = NULL; + const ASN1_STRING *a_str = NULL; char *out = NULL; unsigned char *tmp = NULL; int idx, out_len = 0; From c1b5267e886177517df0a12c004ff2c3fb720086 Mon Sep 17 00:00:00 2001 From: hirashix0 Date: Mon, 20 Apr 2026 10:28:57 +0200 Subject: [PATCH 4179/4321] srbeid: bound CardEdge dir entry count before allocation The entry count is read from card data and used as a calloc() size, which Coverity (CID 503167) flagged as a tainted allocation. Validate count against the available buffer length before allocating; this makes the per-iteration offset check in the parse loop redundant. --- src/libopensc/pkcs15-srbeid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15-srbeid.c b/src/libopensc/pkcs15-srbeid.c index 1eb207559a..447a934e2c 100644 --- a/src/libopensc/pkcs15-srbeid.c +++ b/src/libopensc/pkcs15-srbeid.c @@ -147,6 +147,10 @@ ce_parse_dir(const u8 *data, size_t len, ce_dir_entry_t **entries_out) if (count == 0) return 0; + /* Bound count against buffer size before allocation. */ + if (count > (len - CE_DIR_HEADER_SIZE) / CE_DIR_ENTRY_SIZE) + return -1; + entries = calloc(count, sizeof(ce_dir_entry_t)); if (!entries) return -1; @@ -155,10 +159,6 @@ ce_parse_dir(const u8 *data, size_t len, ce_dir_entry_t **entries_out) size_t off = CE_DIR_HEADER_SIZE + i * CE_DIR_ENTRY_SIZE; int k; - if (off + CE_DIR_ENTRY_SIZE > len) { - free(entries); - return -1; - } /* Name: up to 8 ASCII chars, may not be NUL-terminated on card. */ memcpy(entries[i].name, data + off, 8); entries[i].name[8] = '\0'; From a5f0dde0282201fd287bb645d79e90f42f3cc040 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 16:45:21 +0200 Subject: [PATCH 4180/4321] coolkey: Avoid reading uninitialized memory from response buffer Reported by Alex Kelchin (@Medoedus) --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 3df119ad5d..958ff12e11 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1774,7 +1774,7 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, goto done; } out_length = bebytes2ushort(buf); - if (out_length > sizeof buf - 2) { + if (out_length > buf_len) { r = SC_ERROR_WRONG_LENGTH; goto done; } From ef53bbee1d29c616eea4dc52004951ef5d17d4b9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 16:47:56 +0200 Subject: [PATCH 4181/4321] coolkey: Verify datalen is not too large --- src/libopensc/card-coolkey.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 958ff12e11..e5095fee38 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1696,6 +1696,11 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, max_out_len); + if (datalen > 0xFFFF) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto done; + } + if (priv->key_id > 0xff) { r = SC_ERROR_NO_DEFAULT_KEY; goto done; From 43a5a936eb4e6aa804a5aafbd28a09dbe15c4855 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 17:59:16 +0200 Subject: [PATCH 4182/4321] sccardos: Avoid integer overflow and buffer overrun during cardinfo parsing Reported by @qp-x-qp Fixes: https://github.com/OpenSC/OpenSC/security/advisories/GHSA-mr9x-jw5q-hr3w Signed-off-by: Jakub Jelen --- src/libopensc/pkcs15-tccardos.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index 4091c4cc52..4ffe8b1539 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -213,7 +213,7 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) size_t i; unsigned int key_num; struct sc_context *ctx = p15card->card->ctx; - size_t offset; + size_t offset, available_space; /* read EF_CardInfo1 */ r = read_file(p15card->card, "3F001003b200", info1, &info1_len); @@ -228,23 +228,30 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) | (((unsigned int) info1[info1_len-2]) << 8) | (((unsigned int) info1[info1_len-3]) << 16) | (((unsigned int) info1[info1_len-4]) << 24); - sc_log(ctx, - "found %d private keys\n", (int)key_num); - /* set p1 to the address of the first key descriptor */ - offset = info1_len - 4 - key_num * 2; - if (offset >= info1_len) + sc_log(ctx, "found %u private keys", key_num); + available_space = info1_len - 4; + + /* Verify bounds for the following loop + * - the info1 has 2 bytes for each key + * - the info2 has at least 14 bytes for each key (16 bytes at some cases -- checked later) + */ + if (key_num > available_space / 2 || key_num > info2_len / 14) { return SC_ERROR_INVALID_DATA; + } + offset = available_space - key_num * 2; + /* set p1 to the address of the first key descriptor */ p1 = info1 + offset; p2 = info2; - /* This is the minimum amount of data expected by the following code without - * overunning the buffer without additional condition for cert_count == 4 */ - if (info2_len < key_num * 14) - return SC_ERROR_INVALID_DATA; for (i=0; i info2_len) { + return SC_ERROR_INVALID_DATA; + } /* evaluate CertInfo2 */ cert_count = *p2++; p2 += 2; /* ignore cert DF (it's always 1002) */ @@ -259,6 +266,9 @@ static int parse_EF_CardInfo(sc_pkcs15_card_t *p15card) r1_cert = (p2[0] << 8) | p2[1]; p2 += 2; if (cert_count == 4) { + if ((size_t)(p2 - info2) + 2 > info2_len) { + return SC_ERROR_INVALID_DATA; + } r2_cert = (p2[0] << 8) | p2[1]; p2 += 2; } From 46c26ef3ffc24e6491e66eca644e26d31555e24b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 18:12:27 +0200 Subject: [PATCH 4183/4321] build: Use delimiter character less likely appearing in branch name --- .github/workflows/windows.yml | 2 +- bootstrap.ci | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c6eb406a90..717d287815 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -61,7 +61,7 @@ jobs: fi fi PACKAGE_SUFFIX="${SUFFIX}${{ matrix.configuration == 'Light' && '-Light' || '' }}" - sed -i.bak "s/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX=$PACKAGE_SUFFIX/g" VERSION.mk + sed -i.bak "s|^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$|PACKAGE_SUFFIX=$PACKAGE_SUFFIX|g" VERSION.mk cat VERSION.mk while IFS='=' read -r key value; do # Skip empty or comment lines diff --git a/bootstrap.ci b/bootstrap.ci index fb7e0692b7..f062445ed5 100755 --- a/bootstrap.ci +++ b/bootstrap.ci @@ -46,7 +46,7 @@ rm -rf *~ *.cache config.guess config.log config.status config.sub depcomp ltmai if [ -n "$SUFFIX" ] then echo Set package suffix "$SUFFIX" - sed -i.bak 's/^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$/PACKAGE_SUFFIX='$SUFFIX'/g' VERSION.mk + sed -i.bak 's|^PACKAGE_SUFFIX=\([-~]*[0-9a-zA-Z]*\)$|PACKAGE_SUFFIX='$SUFFIX'|g' VERSION.mk fi ./bootstrap From 6c5dde6577f6fd441bf0d4ecd3a40e889a374f99 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 21:09:38 +0200 Subject: [PATCH 4184/4321] entersafe: Avoid write buffer overrun on long input Signed-off-by: Jakub Jelen --- src/libopensc/card-entersafe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 10d3b81f2a..216f44f266 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -814,7 +814,7 @@ static int entersafe_compute_with_prkey(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (!data) + if (!data || datalen > SC_MAX_APDU_BUFFER_SIZE) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); memcpy(p,data,size); From 8ceb8ae8bc50362658b5a14ac3a7d667f751e6ff Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 21:21:25 +0200 Subject: [PATCH 4185/4321] entersafe: Check bounds when encoding RSA keys Signed-off-by: Jakub Jelen --- src/libopensc/card-entersafe.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 216f44f266..c43affb433 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -962,13 +962,21 @@ static int entersafe_erase_card(sc_card_t *card) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); } -static void entersafe_encode_bignum(u8 tag, sc_pkcs15_bignum_t bignum, u8 **ptr) +static int +entersafe_encode_bignum(u8 tag, sc_pkcs15_bignum_t bignum, u8 **ptr, size_t *ptrlen) { u8 *p = *ptr; + /* lower bound for 1B length encoding */ + if (*ptrlen < bignum.len + 2) { + return SC_ERROR_INVALID_DATA; + } + *p++ = tag; + *ptrlen -= 1; if (bignum.len < 128) { *p++ = (u8)bignum.len; + *ptrlen -= 1; } else { u8 bytes = 1; size_t len = bignum.len; @@ -978,15 +986,25 @@ static void entersafe_encode_bignum(u8 tag, sc_pkcs15_bignum_t bignum, u8 **ptr) } bytes &= 0x0F; *p++ = 0x80 | bytes; + *ptrlen -= 1; while (bytes) { *p++ = bignum.len >> ((bytes - 1) * 8); + *ptrlen -= 1; --bytes; } } + /* Tag and length bytes already counted and checked */ + if (*ptrlen < bignum.len) { + return SC_ERROR_INVALID_DATA; + } + memcpy(p, bignum.data, bignum.len); entersafe_reverse_buffer(p, bignum.len); p += bignum.len; *ptr = p; + *ptrlen -= bignum.len; + + return SC_SUCCESS; } static int entersafe_write_small_rsa_key(sc_card_t *card, u8 key_id, struct sc_pkcs15_prkey_rsa *rsa) @@ -995,14 +1013,17 @@ static int entersafe_write_small_rsa_key(sc_card_t *card, u8 key_id, struct sc_p u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; int r; u8 *p = sbuff; + size_t buflen = sizeof(sbuff); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); { /* write prkey */ *p++ = 0x00; /* EC */ *p++ = 0x00; /* ver */ - entersafe_encode_bignum('E', rsa->exponent, &p); - entersafe_encode_bignum('D', rsa->d, &p); + r = entersafe_encode_bignum('E', rsa->exponent, &p, &buflen); + LOG_TEST_RET(card->ctx, r, "Failed to encode bignum. Buffer too small?"); + r = entersafe_encode_bignum('D', rsa->d, &p, &buflen); + LOG_TEST_RET(card->ctx, r, "Failed to encode bignum. Buffer too small?"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x22, key_id); apdu.cla = 0x84; @@ -1018,8 +1039,10 @@ static int entersafe_write_small_rsa_key(sc_card_t *card, u8 key_id, struct sc_p { /* write pukey */ *p++ = 0x00; /* EC */ *p++ = 0x00; /* ver */ - entersafe_encode_bignum('E', rsa->exponent, &p); - entersafe_encode_bignum('N', rsa->modulus, &p); + r = entersafe_encode_bignum('E', rsa->exponent, &p, &buflen); + LOG_TEST_RET(card->ctx, r, "Failed to encode bignum. Buffer too small?"); + r = entersafe_encode_bignum('N', rsa->modulus, &p, &buflen); + LOG_TEST_RET(card->ctx, r, "Failed to encode bignum. Buffer too small?"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x2A, key_id); apdu.cla = 0x84; From fc3a8eee37ca5df4fb9eafa25bbf9cd9b432c58f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 21:25:39 +0200 Subject: [PATCH 4186/4321] entersafe: Avoid buffer overrun while copying MAC Signed-off-by: Jakub Jelen --- src/libopensc/card-entersafe.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index c43affb433..87091ef809 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -347,8 +347,13 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, } } + if (apdu->lc + 4 > buffsize) { + r = SC_ERROR_INVALID_DATA; + goto out; + } + memcpy(buff, apdu->data, apdu->lc); - /* use first 4 bytes of last block as mac value*/ + /* use first 4 bytes of last block as mac value */ memcpy(buff + apdu->lc, tmp_rounded + tmpsize_rounded - 8, 4); apdu->data = buff; apdu->lc += 4; From ed4e53c5839abdddc8db8adfe45178b80eccad2a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 22:07:52 +0200 Subject: [PATCH 4187/4321] authentic: Avoid pointer leaving the scope of a block Defining the pin_buff in the block and assigning the pointer to the buffer to apdu leaves dangling pointer and causes likely unexpected behavior. Signed-off-by: Jakub Jelen --- src/libopensc/card-authentic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index f12670c2d6..0e7d187c92 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1021,6 +1021,8 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, struct sc_context *ctx = card->ctx; struct sc_apdu apdu; struct sc_pin_cmd_pin *pin1 = &pin_cmd->pin1; + unsigned char pin_buff[SC_MAX_APDU_BUFFER_SIZE]; + size_t pin_len; int rv; LOG_FUNC_CALLED(ctx); @@ -1030,9 +1032,6 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_cmd->pin_reference); } else if (pin1->data && pin1->len) { - unsigned char pin_buff[SC_MAX_APDU_BUFFER_SIZE]; - size_t pin_len; - memcpy(pin_buff, pin1->data, pin1->len); pin_len = pin1->len; From 4d81d00b9c84d87e665024422c88d1f08d811054 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 22:10:51 +0200 Subject: [PATCH 4188/4321] authetnic: Avoid buffer overrun for long PIN Signed-off-by: Jakub Jelen --- src/libopensc/card-authentic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 0e7d187c92..807629bda1 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1032,6 +1032,9 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_cmd->pin_reference); } else if (pin1->data && pin1->len) { + if (pin1->len > sizeof(pin_buff)) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_LENGTH); + } memcpy(pin_buff, pin1->data, pin1->len); pin_len = pin1->len; From d6d62c63572a79868ccc42f17198f88cdc4d61e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 21:58:20 +0200 Subject: [PATCH 4189/4321] entersafe: Avoid buffer overrun with too long PINs Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-entersafe.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 87091ef809..193ec59ece 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -892,6 +892,10 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, sc_apdu_t apdu; u8 sbuf[0x10] = {0}; + if (data->pin1.len > sizeof(sbuf)) { + return SC_ERROR_INVALID_DATA; + } + memcpy(sbuf, data->pin1.data, data->pin1.len); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, data->pin_reference + 1); apdu.lc = apdu.datalen = sizeof(sbuf); @@ -905,6 +909,10 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, sc_apdu_t apdu; u8 sbuf[0x12] = {0}; + if (data->pin2.len + 2 > sizeof(sbuf)) { + return SC_ERROR_INVALID_DATA; + } + sbuf[0] = 0x33; sbuf[1] = 0x00; memcpy(sbuf + 2, data->pin2.data, data->pin2.len); From 97c514e86d6da9e11a4b405f7e4d7f1babdca26f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 22:14:34 +0200 Subject: [PATCH 4190/4321] authentic: Avoid unsigned integer underflow Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-authentic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 807629bda1..96088d86fc 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1039,6 +1039,9 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, pin_len = pin1->len; if (pin1->pad_length && pin_cmd->flags & SC_PIN_CMD_NEED_PADDING) { + if (pin1->len > pin1->pad_length || pin1->pad_length > sizeof(pin_buff)) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_LENGTH); + } memset(pin_buff + pin1->len, pin1->pad_char, pin1->pad_length - pin1->len); pin_len = pin1->pad_length; } From 2dcfa4ac92c4f8be8ec59d03751595f8fddc9aac Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 22:24:15 +0200 Subject: [PATCH 4191/4321] authentic: Avoid buffer overrun when accessing pins_sha1 Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-authentic.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 96088d86fc..e1a7f9b5fd 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -61,13 +61,14 @@ static struct sc_card_driver authentic_drv = { NULL, 0, NULL }; +#define AUTHENTIC_N_PINS 8 /* * FIXME: use dynamic allocation for the PIN data to reduce memory usage * actually size of 'authentic_private_data' 140kb */ struct authentic_private_data { - struct sc_pin_cmd_data pins[8]; - unsigned char pins_sha1[8][SHA_DIGEST_LENGTH]; + struct sc_pin_cmd_data pins[AUTHENTIC_N_PINS]; + unsigned char pins_sha1[AUTHENTIC_N_PINS][SHA_DIGEST_LENGTH]; struct sc_cplc cplc; }; @@ -1110,6 +1111,10 @@ authentic_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) sc_log(ctx, "PIN(type:%X,reference:%X,data:%p,length:%zu)", pin_cmd->pin_type, pin_cmd->pin_reference, pin_cmd->pin1.data, pin_cmd->pin1.len); + if (pin_cmd->pin_reference < 0 || pin_cmd->pin_reference >= AUTHENTIC_N_PINS) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "PIN reference out of bounds"); + } + if (pin_cmd->pin1.data && !pin_cmd->pin1.len) { pin_cmd->pin1.tries_left = -1; rv = authentic_pin_is_verified(card, pin_cmd, &pin_cmd->pin1.tries_left); @@ -1206,6 +1211,10 @@ authentic_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr rv = authentic_pin_get_policy(card, data, NULL); LOG_TEST_RET(ctx, rv, "Get 'PIN policy' error"); + if (data->pin_reference < 0 || data->pin_reference >= AUTHENTIC_N_PINS) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "PIN reference out of bounds"); + } + memset(prv_data->pins_sha1[data->pin_reference], 0, sizeof(prv_data->pins_sha1[0])); if (!data->pin1.data && !data->pin1.len && !data->pin2.data && !data->pin2.len) { @@ -1350,6 +1359,10 @@ authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri LOG_FUNC_CALLED(ctx); sc_log(ctx, "reset PIN (ref:%i,lengths %zu/%zu)", data->pin_reference, data->pin1.len, data->pin2.len); + if (data->pin_reference < 0 || data->pin_reference >= AUTHENTIC_N_PINS) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "PIN reference out of bounds"); + } + memset(prv_data->pins_sha1[data->pin_reference], 0, sizeof(prv_data->pins_sha1[0])); memset(&pin_cmd, 0, sizeof(pin_cmd)); From 14f81d3728b8ee98b1c57aecd8d02dce19b2dfd0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 22:30:56 +0200 Subject: [PATCH 4192/4321] authentic: Avoid buffer overrun when constructing PIN change buffer Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-authentic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index e1a7f9b5fd..ee9e3ae025 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1231,11 +1231,18 @@ authentic_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr memset(pin_data, data->pin1.pad_char, sizeof(pin_data)); offs = 0; if (data->pin1.data && data->pin1.len) { + if (data->pin1.len > sizeof(pin_data)) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "PIN length exceeds buffer"); + } memcpy(pin_data, data->pin1.data, data->pin1.len); offs += data->pin1.pad_length; } - if (data->pin2.data && data->pin2.len) + if (data->pin2.data && data->pin2.len) { + if (data->pin2.len + offs > sizeof(pin_data)) { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "PIN2 length exceeds buffer"); + } memcpy(pin_data + offs, data->pin2.data, data->pin2.len); + } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, offs ? 0x00 : 0x01, data->pin_reference); apdu.data = pin_data; From 64b760cc620707ae1380500388cc2bc9329b8c69 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 Apr 2026 09:02:18 +0200 Subject: [PATCH 4193/4321] coolkey: Check ECC input length bounds Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-coolkey.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index e5095fee38..828c4c26b7 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1811,6 +1811,11 @@ static int coolkey_ecc_op(sc_card_t *card, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, outlen); + if (datalen > sizeof(params.buf)) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto done; + } + crypt_in = data; crypt_in_len = datalen; From fc7afff8ff1f7f249bb2532d46ffcee088e9483e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 Apr 2026 09:21:18 +0200 Subject: [PATCH 4194/4321] gids: Avoid heap buffer over-read Reported by Alex Kelchin (Medoedus) Signed-off-by: Jakub Jelen --- src/libopensc/card-gids.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 9dbce166f6..260618629d 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1055,8 +1055,8 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, if (flags) *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB; /* compressed data are starting on position buffer + 4 */ - data->buffersize = sizeof(data->buffer) - 4; - memcpy(data->buffer, buffer + 4, buffersize); + data->buffersize = buffersize - 4; + memcpy(data->buffer, buffer + 4, buffersize - 4); } else { sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] << 8)); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); From ca789c786bb853224dce483087f253c93326a2f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:06:42 +0000 Subject: [PATCH 4195/4321] build(deps): bump actions/checkout from 4 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/external-pkcs11.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 313d6fc422..1d31a174d0 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -38,7 +38,7 @@ jobs: BUILD_PATH: ./ steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Fedora run: .github/setup-fedora.sh kryoptic - name: Install OpenSC @@ -52,7 +52,7 @@ jobs: SOURCE_PATH: ./ BUILD_PATH: ./ steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -73,7 +73,7 @@ jobs: SOURCE_PATH: ./ BUILD_PATH: ./ steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: ${{ env.BASE_DEPS }} @@ -97,7 +97,7 @@ jobs: BUILD_PATH: ./ steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Fedora run: .github/setup-fedora.sh kryoptic - name: Install OpenSC From d9cea5646972595c7658bd5c4a3cc5b32fe64c73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:06:30 +0000 Subject: [PATCH 4196/4321] build(deps): bump actions/cache from 4 to 5 Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/rpmbuild.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rpmbuild.yaml b/.github/workflows/rpmbuild.yaml index 74d59bf233..974fa19bb2 100644 --- a/.github/workflows/rpmbuild.yaml +++ b/.github/workflows/rpmbuild.yaml @@ -33,7 +33,7 @@ jobs: shell: bash - name: Cache DNF packages (separate from the main job -- different dependencies) - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | /var/cache/libdnf5 From 7d5d10ef37806d408cc8871026faec7f8c069991 Mon Sep 17 00:00:00 2001 From: hirashix0 Date: Mon, 20 Apr 2026 14:21:45 +0200 Subject: [PATCH 4197/4321] srbeid: match by ATR whitelist, drop AID fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old fallback selected the PKCS#15 AID (A0 00 00 00 63 50 4B 43 53 2D 31 35) whenever ATR didn't match. That is the standard PKCS#15 AID defined in ISO/IEC 7816-15, hosted by every compliant applet — which caused the false match on a Lithuanian eID reported in #3663. Replace the fallback with a 15-entry ATR whitelist covering all Serbian CardEdge deployments (citizen eID, foreigner eID, PKS Chamber of Commerce, health insurance). After ATR match, select the applet AID to confirm it's there — same pattern as card-esteid2018. Fixes #3663. --- src/libopensc/card-srbeid.c | 49 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-srbeid.c b/src/libopensc/card-srbeid.c index b50ecc4dea..716a310ea9 100644 --- a/src/libopensc/card-srbeid.c +++ b/src/libopensc/card-srbeid.c @@ -2,8 +2,8 @@ * card-srbeid.c: Driver for Serbian cards using the CardEdge PKI applet. * * Serbian eID, health insurance, and Chamber of Commerce cards use the - * same CardEdge PKCS#15 applet. Cards are matched either by ATR - * (Gemalto 2014+ eID) or by AID selection. + * same CardEdge PKCS#15 applet. Cards are matched by ATR whitelist, + * with a PKCS#15 AID select as a confirmation step. * * Copyright (C) 2026 LibreSCRS contributors * @@ -44,37 +44,36 @@ static struct sc_card_driver srbeid_drv = { &srbeid_ops, NULL, 0, NULL}; -/* - * ATR table. - * - * Gemalto (2014+) Serbian eID: 3B:FF:94 ... - * Mask FF:FF:FF matches the first 3 bytes; remaining bytes vary between - * individual cards and are don't-cares. - * - * Other CardEdge cards have no distinct ATR and are identified via AID - * selection in match_card(). - * - * Apollo 2008 ATR 3B:B9:18 ... is intentionally absent — no CardEdge applet. - */ +/* Full ATR list provided by NetSeT (the CardEdge PKI applet vendor). Covers + * citizen eID, foreigner eID, PKS Chamber of Commerce, and RFZO health + * insurance cards across their various underlying card platforms. */ static const struct sc_atr_table srbeid_atrs[] = { - {"3B:FF:94", "FF:FF:FF", "Serbian eID (Gemalto 2014+)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, - {NULL, NULL, NULL, 0, 0, NULL} + {"3B:FF:94:00:00:81:31:80:43:80:31:80:65:B0:85:02:01:F3:12:0F:FF:82:90:00:79", NULL, "Serbian eID (Gemalto Multiapp 80K)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:F8:13:00:00:81:31:FE:45:4A:43:4F:50:76:32:34:31:B7", NULL, "Serbian eID (NXP JCOP v2.4.1 80K)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:FA:13:00:00:81:31:FE:45:4A:43:4F:50:32:31:56:32:33:31:91", NULL, "Serbian eID (NXP JCOP21 v2.3.1)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:F4:13:00:00:81:31:FE:45:52:46:5A:4F:ED", NULL, "Serbian health card (NXP JCOP21 v2.4.1)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:7A:96:00:00:80:65:A2:01:01:02:3D:72:D6:43", NULL, "Serbian eID (Gemalto Multiapp 80K IDCore10)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:F9:96:00:00:80:31:FE:45:53:43:45:37:20:47:43:4E:33:5E", NULL, "Serbian eID (SmartCafe Expert v7.0)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:FD:94:00:00:81:31:80:43:80:31:80:65:B1:F3:01:07:0F:83:01:90:00:17", NULL, "Serbian eID (Gemalto Dual-Interface 144K Contact)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:89:80:01:53:43:45:2E:37:20:20:20:20:44", NULL, "Serbian eID (SmartCafe Expert v7.0 Contactless)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:F9:96:00:00:80:31:FE:45:53:43:45:37:20:20:00:20:20:07", NULL, "Serbian eID (SmartCafe Expert v7.1)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:DE:97:00:80:31:FE:45:53:43:45:20:38:2E:30:2D:43:31:56:30:0D:0A:2E", NULL, "Serbian PKS card (SmartCafe Expert v8.0 B)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:9E:96:80:31:FE:45:53:43:45:20:38:2E:30:2D:43:31:56:30:0D:0A:6F", NULL, "Serbian eID (SmartCafe Expert v8.0)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:9E:96:80:31:FE:45:53:43:45:20:38:2E:30:2D:43:32:56:30:0D:0A:6C", NULL, "Serbian eID (SmartCafe Expert v8.0 C2)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:D5:18:FF:81:91:FE:1F:C3:80:73:C8:21:10:0A", NULL, "Serbian eID (NXP JCOP4 P71)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:DE:97:00:80:31:FE:45:53:43:45:20:38:2E:30:2D:43:32:56:30:0D:0A:2D", NULL, "Serbian PKS card (SmartCafe Expert v8.0 C2 B)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {"3B:9E:97:80:31:FE:45:53:43:45:20:38:2E:30:2D:43:31:56:30:0D:0A:6E", NULL, "Serbian health card (SmartCafe Expert v8.0 S)", SC_CARD_TYPE_SRBEID_BASE, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} }; static int srbeid_match_card(sc_card_t *card) { - /* ATR hit: Gemalto 2014+ Serbian eID (3B:FF:94 ...) */ - if (_sc_match_atr(card, srbeid_atrs, &card->type) >= 0) - return 1; - - /* AID-based match for cards without a distinct ATR. */ - if (iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) == SC_SUCCESS) { - sc_log(card->ctx, "srbeid: CardEdge applet found via AID"); - card->type = SC_CARD_TYPE_SRBEID_BASE; + int i = _sc_match_atr(card, srbeid_atrs, &card->type); + if (i >= 0 && iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) == SC_SUCCESS) { + card->name = srbeid_atrs[i].name; return 1; } - return 0; } From 95ae550858fc0a808e4f6d6d3c6007cc9f15cc11 Mon Sep 17 00:00:00 2001 From: Michael Litvine <130777255+michalitv21@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:08:47 +0200 Subject: [PATCH 4198/4321] Added missing null checks after dynamic memory allocation (#3664) --------- Co-authored-by: Litvine --- src/libopensc/pkcs15-gemsafeV1.c | 3 +++ src/libopensc/pkcs15-pubkey.c | 5 +++++ src/pkcs15init/pkcs15-lib.c | 4 ++++ src/pkcs15init/pkcs15-myeid.c | 4 ++++ src/pkcs15init/pkcs15-setcos.c | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 9fb8956fe9..389e56667d 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -493,6 +493,9 @@ sc_pkcs15emu_add_object(sc_pkcs15_card_t *p15card, int type, int df_type; obj = calloc(1, sizeof(*obj)); + if (!obj) { + LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY); + } obj->type = type; obj->data = data; diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 72d207bfb5..b59869683f 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1422,6 +1422,11 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke LOG_TEST_GOTO_ERR(ctx, r, "failed to fix EC parameters"); pubkey->u.ec.ecpointQ.value = malloc(pk.len); + if (pubkey->u.ec.ecpointQ.value == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "failed to malloc() memory"); + } + memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len); pubkey->u.ec.ecpointQ.len = pk.len; } else { diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 202db2daf4..0f67cc7b04 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3469,6 +3469,10 @@ sc_pkcs15init_new_object(int type, const char *label, struct sc_pkcs15_id *auth_ if (data_size) { object->data = calloc(1, data_size); + if (!object->data) { + return NULL; + } + if (data) memcpy(object->data, data, data_size); } diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 805966abc5..612efd7493 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -851,8 +851,12 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = BYTES4BITS(keybits); pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); + if (pubkey->u.rsa.modulus.data == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); pubkey->u.rsa.exponent.len = MYEID_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(MYEID_DEFAULT_PUBKEY_LEN); + if (pubkey->u.rsa.exponent.data == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(pubkey->u.rsa.exponent.data, MYEID_DEFAULT_PUBKEY, MYEID_DEFAULT_PUBKEY_LEN); /* Get public key modulus */ diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 73be2b7a6a..3f4d4f6684 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -491,8 +491,12 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = BYTES4BITS(keybits); pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); + if (pubkey->u.rsa.modulus.data == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); pubkey->u.rsa.exponent.len = SETCOS_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(SETCOS_DEFAULT_PUBKEY_LEN); + if (pubkey->u.rsa.exponent.data == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(pubkey->u.rsa.exponent.data, SETCOS_DEFAULT_PUBKEY, SETCOS_DEFAULT_PUBKEY_LEN); /* Get public key modulus */ From ed8575062d6093290087061cdf7d5b1e5b4e606a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 13 Apr 2026 15:30:02 +0200 Subject: [PATCH 4199/4321] pkcs11: Improve logging message when registering mechanism --- src/pkcs11/mechanism.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 6b879fa529..da056d7136 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1786,7 +1786,7 @@ sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, CK_RV rv; LOG_FUNC_CALLED(p11card->card->ctx); - sc_log(p11card->card->ctx, "mech = %lx, hash_mech = %lx", mech, hash_mech); + sc_log(p11card->card->ctx, "mech = 0x%lx, hash_mech = 0x%lx", mech, hash_mech); if (!sign_type) LOG_FUNC_RETURN(p11card->card->ctx, CKR_MECHANISM_INVALID); From efe2e91dfb8291fbe031357fef57195974b628cf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sun, 19 Apr 2026 20:42:44 +0200 Subject: [PATCH 4200/4321] Revert "Do not register SHA1-based mechanisms in FIPS mode" This reverts commit 91e61b9a7667ce0bf62e4b0e872e39a34295eb89. Not registering SHA1 in the OpenSSL module fails later on when registering hash + sign mechanisms, leading to unexpected issues. Alternative solution was to not register the compound mechanisms, but reverting this change looks cleaner. When we will really have FIPS provider without SHA1, it can be resurrected. --- src/pkcs11/openssl.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index a4027339b2..81affb76dd 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -305,14 +305,12 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) #endif #endif /* !defined(OPENSSL_NO_ENGINE) */ - if (!FIPS_mode()) { - openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); - openssl_sha1_mech.free_mech_data = ossl_md_free; - openssl_sha1_mech.copy_mech_data = ossl_md_copy; - mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); - sc_pkcs11_register_mechanism(p11card, mt, NULL); - sc_pkcs11_free_mechanism(&mt); - } + openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); + openssl_sha1_mech.free_mech_data = ossl_md_free; + openssl_sha1_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); openssl_sha224_mech.mech_data = sc_evp_md(context, "sha224"); openssl_sha224_mech.free_mech_data = ossl_md_free; From de11c271f30b81cfe86f1510f5f0ec4914cc2cea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:06:33 +0000 Subject: [PATCH 4201/4321] build(deps): bump actions/setup-java from 4 to 5 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index e9ebae767b..523f88f192 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -168,7 +168,7 @@ jobs: steps: - *use_cache - run: git clone $JCARDSIM - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: 'semeru' java-version: '8' From adc68845963976584ae517fffb8b1396e533ba85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 08:28:11 +0000 Subject: [PATCH 4202/4321] build(deps): bump actions/upload-artifact from 6 to 7 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/centos.yml | 2 +- .github/workflows/cifuzz.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/fedora.yml | 2 +- .github/workflows/linux-strict.yml | 2 +- .github/workflows/linux.yml | 10 +++++----- .github/workflows/macos.yml | 6 +++--- .github/workflows/windows.yml | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/centos.yml b/.github/workflows/centos.yml index 3e758f0dc2..67ba936d15 100644 --- a/.github/workflows/centos.yml +++ b/.github/workflows/centos.yml @@ -26,7 +26,7 @@ jobs: - run: .github/setup-centos.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: c10s-test-logs diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 0d478ba53f..e7c248cb07 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -22,7 +22,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a1ee762862..0384372f93 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -39,7 +39,7 @@ jobs: - run: .github/build.sh - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: codeql-logs diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index ec2f0fdc65..37eeaecf90 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -25,7 +25,7 @@ jobs: - run: .github/setup-fedora.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: fedora-test-logs diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 90c9f8375c..23d361d992 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -78,7 +78,7 @@ jobs: CC: ${{ matrix.compiler }} CFLAGS: ${{ env.CFLAGS }} ${{ matrix.compiler == 'clang' && env.CLANG_CFLAGS || '' }} - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: ${{ matrix.name }}-${{ matrix.compiler }}-strict-test-logs diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 523f88f192..954712c91a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -47,7 +47,7 @@ jobs: - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: ubuntu-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-test-logs @@ -62,7 +62,7 @@ jobs: key: ${{ runner.os }}-${{ matrix.dist }}-${{ matrix.arch }}-${{ matrix.build }}-${{ github.sha }} - name: Upload build artifacts if: matrix.build == 'dist' - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: opensc-build-${{ matrix.dist }}-${{ matrix.arch }} path: @@ -111,7 +111,7 @@ jobs: - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: opensc-build-mingw path: @@ -124,7 +124,7 @@ jobs: - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: opensc-build-mingw32 path: @@ -217,7 +217,7 @@ jobs: key: libressl-${{ env.LIBRESSL_VERSION }} - run: .github/setup-linux.sh libressl - run: .github/build.sh dist libressl valgrind - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 if: failure() with: name: libressl-logs diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 15257fa477..642de8a418 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -60,13 +60,13 @@ jobs: env: KEY_PASSWORD: ${{ secrets.DEV_ID_PASSWORD }} - name: Cache build artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: opensc-build-${{ matrix.os }} path: OpenSC*.dmg - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: ${{ matrix.os }}-logs @@ -84,7 +84,7 @@ jobs: - run: .github/build.sh libressl - run: .github/cleanup-macos.sh - name: Upload test logs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: failure() with: name: ${{ matrix.os }}-libressl-logs diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 717d287815..c2f98845af 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -134,7 +134,7 @@ jobs: run: nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts id: upload-unsigned-artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ env.ARTIFACT_NAME }} path: ./win32/*.msi @@ -149,7 +149,7 @@ jobs: github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}' wait-for-completion: false - name: Archive debug artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ env.ARTIFACT_NAME }}-dbg path: | From 09c15aaddfb3d0a0bcd92a325325372e5bdd4ea7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 21 Apr 2026 10:54:36 +0200 Subject: [PATCH 4203/4321] CI: removed AppVeyor provider AppVeyor is flaky and slower than GH actions, unfortunately. All functionality is now also available via the Windows CI run in GH actions. --- .appveyor.yml | 115 -------------------------------------------------- README.md | 1 - 2 files changed, 116 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index f74f7f6c23..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,115 +0,0 @@ -version: 0.27.1.{build} - -platform: - - x86 - - x64 - -configuration: - - Release - - Light - -environment: - PATH: C:\cygwin\bin;%PATH% - OPENPACE_VER: 1.1.4 - ZLIB_VER_DOT: 1.3.2 - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" - OPENSSL_VER: "1.1.1" - OPENSSL_DIR: "C:\\OpenSSL-v111" - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" - OPENSSL_DIR: "C:\\OpenSSL-v30" - OPENSSL_FLAGS: "/DHAVE_EVP_PKEY_DUP" - DO_PUSH_ARTIFACT: yes - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - VCVARSALL: "%ProgramFiles%/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" - OPENSSL_DIR: "C:\\OpenSSL-v30" - OPENSSL_FLAGS: "/DHAVE_EVP_PKEY_DUP" - -init: - # Fixes "fatal: detected dubious ownership in repository at '/cygdrive/c/projects/opensc'" with recent images - - git config --global --add safe.directory /cygdrive/c/projects/opensc - -install: - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` - https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` - Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` - throw "There are newer queued builds for this pull request, failing early." } - - ps: $env:PACKAGE_VERSION=(git describe --tags --abbrev=0) - - ps: $env:OPENSSL_PF = If ($env:Platform -eq "x86") { "Win32" } Else { "Win64" } - - ps: $env:ARTIFACT="OpenSC-${env:PACKAGE_VERSION}_${env:OPENSSL_PF}" - - ps: >- - If ($env:Configuration -Like "*Light*") { - $env:ARTIFACT+="-Light" - } Else { - If (!(Test-Path C:\zlib )) { - appveyor DownloadFile "https://github.com/madler/zlib/archive/v${env:ZLIB_VER_DOT}.zip" -FileName zlib.zip - 7z x zlib.zip -oC:\ - Rename-Item -path "c:\zlib-${env:ZLIB_VER_DOT}" -newName "zlib" - } - If (!(Test-Path C:\openpace )) { - appveyor DownloadFile "https://github.com/frankmorgner/openpace/archive/${env:OPENPACE_VER}.zip" -FileName openpace.zip - 7z x openpace.zip -oC:\ - Rename-Item -path "c:\openpace-${env:OPENPACE_VER}" -newName "openpace" - } - } - If (!(Test-Path cpdksetup.exe )) { - appveyor DownloadFile "https://download.microsoft.com/download/1/7/6/176909B0-50F2-4DF3-B29B-830A17EA7E38/CPDK_RELEASE_UPDATE/cpdksetup.exe" - } - - cpdksetup.exe /quiet - - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" choco install dotnet-sdk --version=6.0.100 -y - - ps: .\.github\setup-wix.ps1 - -build_script: - - echo "Using %APPVEYOR_BUILD_WORKER_IMAGE% with %VCVARSALL%" - - call "%VCVARSALL%" %Platform% - - ps: >- - if (!($env:Configuration -Like "*Light*")) { - If (!(Test-Path -Path "C:\zlib-${env:OPENSSL_PF}" )) { - # build zlib.lib as a static library - xcopy C:\zlib C:\zlib-${env:OPENSSL_PF} /e /i /y /s - cd C:\zlib-${env:OPENSSL_PF} - (Get-Content win32/Makefile.msc).replace('-MD', '-MT') | Set-Content win32/Makefile.msc - nmake /nologo -f win32/Makefile.msc zlib.lib - } - If (!(Test-Path -Path "C:\openpace-${env:OPENSSL_PF}" )) { - # build libeac.lib as a static library - xcopy C:\openpace C:\openpace-${env:OPENSSL_PF} /e /i /y /s - cd C:\openpace-${env:OPENSSL_PF}\src - cl /nologo /I${env:OPENSSL_DIR}-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /DHAVE_EC_POINT_GET_AFFINE_COORDINATES=1 /DHAVE_EC_POINT_SET_AFFINE_COORDINATES=1 ${env:OPENSSL_FLAGS} /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c - lib /nologo /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj - cd ${env:APPVEYOR_BUILD_FOLDER} - } - $env:ZLIBSTATIC_DEF="/DENABLE_ZLIB_STATIC" - $env:ZLIB_INCL_DIR="/IC:\zlib-${env:OPENSSL_PF}" - $env:ZLIB_LIB="C:\zlib-${env:OPENSSL_PF}\zlib.lib" - $env:OPENSSL_DEF="/DENABLE_OPENSSL" - $env:OPENSSL_DIR="${env:OPENSSL_DIR}-${env:OPENSSL_PF}" - $env:OPENSSL_EXTRA_CFLAGS="/DOPENSSL_SECURE_MALLOC_SIZE=65536" - $env:OPENPACE_DEF="/DENABLE_OPENPACE" - $env:OPENPACE_DIR="C:\openpace-${env:OPENSSL_PF}" - } - - nmake /nologo /f Makefile.mak opensc.msi - - move win32\OpenSC*.msi %ARTIFACT%.msi - # put all pdb files for dump analysis, but this consumes approx 100 MB per build - - md %ARTIFACT%-Debug - - ps: >- - Get-ChildItem -recurse ${env:APPVEYOR_BUILD_FOLDER} -exclude vc*.pdb *.pdb | % { - 7z a -tzip ${env:ARTIFACT}-Debug.zip $_.FullName - } - - appveyor PushArtifact %ARTIFACT%.msi - - appveyor PushArtifact %ARTIFACT%-Debug.zip - # keep in sync with .travis.yml - - bash -c "git config --global user.email 'no-reply@appveyor.com'" - - bash -c "git config --global user.name 'AppVeyor'" - - bash -c "if [ \"$DO_PUSH_ARTIFACT\" = yes -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" -a \"$APPVEYOR_REPO_NAME\" = \"OpenSC/OpenSC\" ]; then .github/push_artifacts.sh \"AppVeyor build ${APPVEYOR_BUILD_NUMBER}.${APPVEYOR_JOB_NUMBER}\"; fi" - -cache: - - C:\zlib -> .appveyor.yml - - C:\zlib-Win32 -> .appveyor.yml - - C:\zlib-Win64 -> .appveyor.yml - - C:\openpace -> .appveyor.yml - - C:\openpace-Win32 -> .appveyor.yml - - C:\openpace-Win64 -> .appveyor.yml - - cpdksetup.exe -> .appveyor.yml diff --git a/README.md b/README.md index 6bec2ec177..39ca02d110 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ Nightly builds are available by their git hash in branches of [OpenSC/Nightly](h [![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) [![Windows build](https://github.com/OpenSC/OpenSC/actions/workflows/windows.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/windows.yml) [![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) -[![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/frankmorgner/opensc/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) [![CodeQL](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml/badge.svg?event=push)](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opensc.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:opensc) From 6c101a4cb4ade7be74a618b47bb2b5d7558e60f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:35:00 +0000 Subject: [PATCH 4204/4321] build(deps): bump actions/download-artifact from 7 to 8 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 954712c91a..d645549eb9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -275,7 +275,7 @@ jobs: path: ./* key: ${{ runner.os }}-24.04-amd64-dist-${{ github.sha }} - name: Pull mingw build artifacts - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: opensc-build-mingw - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 642de8a418..2de5fed521 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -97,7 +97,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Pull build artifacts - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: opensc-build-macos-15 - run: git config --global user.email "builds@github.com" From a060894610945a4c297b04122b94c51fb224bcc3 Mon Sep 17 00:00:00 2001 From: Shawn C Date: Wed, 22 Apr 2026 21:24:48 +0800 Subject: [PATCH 4205/4321] Add a NULL check at the entry of `sc_pkcs11_find_mechanism`. This ensures that callers who pass `slot->p11card` (which may be NULL if no card is present in the slot) do not trigger a crash. Signed-off-by: Shawn C --- src/pkcs11/mechanism.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index da056d7136..f58ba6c0c3 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -203,6 +203,8 @@ sc_pkcs11_find_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, sc_pkcs11_mechanism_type_t *mt; unsigned int n; + if (p11card == NULL) + return NULL; for (n = 0; n < p11card->nmechanisms; n++) { mt = p11card->mechanisms[n]; if (mt && mt->mech == mech && ((mt->mech_info.flags & flags) == flags)) From 24d4bf95f3323eaa210a1f5fedc652303d392f90 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 20 Apr 2026 10:49:34 -0500 Subject: [PATCH 4206/4321] linux-strict.yml - test with --enable-piv-sm As suggested in https://github.com/OpenSC/OpenSC/pull/3661#issuecomment-4276558016 On branch Wshorten-64-to-32 Changes to be committed: modified: .github/workflows/linux-strict.yml --- .github/workflows/linux-strict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 23d361d992..8f6a5a71b0 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -73,7 +73,7 @@ jobs: steps: - uses: actions/checkout@v6 - run: .github/setup-linux.sh ${{ matrix.compiler }} force-install - - run: .github/build.sh dist + - run: .github/build.sh piv-sm dist env: CC: ${{ matrix.compiler }} CFLAGS: ${{ env.CFLAGS }} ${{ matrix.compiler == 'clang' && env.CLANG_CFLAGS || '' }} From b41e08aa84e8e6b46f69d5c561054fb216b30c59 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 23 Apr 2026 07:34:09 -0500 Subject: [PATCH 4207/4321] card-piv.c - fix -Wshorten-64-to-32 errors Add typecasts and reformat the multiline if statement to meet clang code style. The changes are only compiled when using --enable-piv-sm Please enter the commit message for your changes. Lines starting Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a250a91990..c0d43e743b 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -871,10 +871,10 @@ static void piv_inc(u8 *counter, size_t size) unsigned int c = 1; unsigned int b; int i; - for (i = size - 1; c != 0 && i >= 0; i--){ - b = c + counter[i]; - counter[i] = b & 0xff; - c = b>>8; + for (i = (int)size - 1; c != 0 && i >= 0; i--) { + b = c + counter[i]; + counter[i] = b & 0xff; + c = b >> 8; } } @@ -995,8 +995,8 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu T87len = 0; padlen = 0; } else { - enc_datalen = ((plain->datalen + 15) / 16) * 16; /* may add extra 16 bytes */ - padlen = enc_datalen - plain->datalen; + enc_datalen = (int)(((plain->datalen + 15) / 16) * 16); /* may add extra 16 bytes */ + padlen = enc_datalen - (int)plain->datalen; r = T87len = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, NULL, 0, NULL); if (r < 0) goto err; @@ -1022,13 +1022,13 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu *p++ = 0x01; /* padding context indicator */ /* first round encryptes Enc counter with zero IV, and does not save the output */ - if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 - || EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 - || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 - || EVP_EncryptUpdate(ed_ctx, p ,&outl, plain->data, plain->datalen) != 1 - || EVP_EncryptUpdate(ed_ctx, p + outl, &outll, pad, padlen) != 1 - || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 - || outdl != 0) { /* should not happen */ + if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 || + EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 || + EVP_EncryptUpdate(ed_ctx, p, &outl, plain->data, (int)plain->datalen) != 1 || + EVP_EncryptUpdate(ed_ctx, p + outl, &outll, pad, padlen) != 1 || + EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || + outdl != 0) { /* should not happen */ sc_log_openssl(card->ctx); sc_log(card->ctx,"SM _encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; @@ -1042,7 +1042,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu *p++ = 0x01; *p++ = plain->le; } - macdatalen = p - sbuf; + macdatalen = (int)(p - sbuf); memcpy(priv->sm_session.C_MCV_last, priv->sm_session.C_MCV, MCVlen); /* save is case fails */ @@ -1272,7 +1272,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu #endif /* MCV is first, then BER TLV Encoded Encrypted PIV Data and Status */ - macdatalen = status.value + status.len - sm_apdu->resp; + macdatalen = (int)(status.value + status.len - sm_apdu->resp); #if OPENSSL_VERSION_NUMBER < 0x30000000L if (CMAC_Init(cmac_ctx, priv->sm_session.SKrmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 @@ -1324,7 +1324,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu plain->resplen = 0; } else { p = ee.value; - inlen = ee.len; + inlen = (int)ee.len; if (inlen < 17 || *p != 0x01) { /*padding and padding indicator are required */ sc_log(card->ctx, "SM padding indicator not 0x01"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2594,7 +2594,7 @@ static int piv_sm_open(struct sc_card *card) memcpy(p, Qeh_OS, Qeh_OSlen); p += Qeh_OSlen; - MacDatalen = p - MacData; + MacDatalen = (int)(p - MacData); #if OPENSSL_VERSION_NUMBER < 0x30000000L if ((cmac_ctx = CMAC_CTX_new()) == NULL From 5fb109f9216d7d6f2ef22a05cc47ea3598937c59 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 23 Apr 2026 07:40:00 -0500 Subject: [PATCH 4208/4321] fuzz_pkcs11.c - fix -Wshorten-64-to-32 errors Changes to be committed: modified: src/tests/fuzzing/fuzz_pkcs11.c --- src/tests/fuzzing/fuzz_pkcs11.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index f440a7b701..2fd1a5febd 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -56,7 +56,8 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t struct sc_reader *reader = NULL; struct sc_app_info *app_generic = NULL; sc_pkcs11_slot_t *slot = NULL; - int rv = CKR_OK, free_p11card = 0; + CK_RV rv = CKR_OK; + int free_p11card = 0; /* Erase possible virtual slots*/ list_clear(&virtual_slots); @@ -81,7 +82,7 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t /* Locate a slot related to the reader */ for (size_t i = 0; i < list_size(&virtual_slots); i++) { - slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); + slot = (sc_pkcs11_slot_t *)list_get_at(&virtual_slots, (int)i); if (slot->reader == reader) { p11card = slot->p11card; break; @@ -143,7 +144,7 @@ static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t if (free_p11card) { sc_pkcs11_card_free(p11card); } - return rv; + return (int)rv; } #endif @@ -292,7 +293,8 @@ static void test_digest_update(const uint8_t *data, size_t size) CK_MECHANISM mech = {0, NULL_PTR, 0}; unsigned char buffer[64] = {0}; CK_ULONG hash_len = sizeof(buffer); - int to_process = 0, rv = 0; + size_t to_process = 0; + CK_RV rv = 0; if (set_mechanism(&data, &size, &mech)) return; @@ -387,7 +389,7 @@ static int fuzz_find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls, if (count == 0) *ret = CK_INVALID_HANDLE; p11->C_FindObjectsFinal(sess); - return count; + return (int)count; } static void test_sign(const uint8_t *data, size_t size) From a807d69706ee6d88f7e57f4b455e5631f331d5a1 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Apr 2026 17:49:33 +0200 Subject: [PATCH 4209/4321] replaced assert() with error handling (#3659) Co-authored-by: Jakub Jelen --- src/libopensc/asn1.c | 12 +++-- src/libopensc/card-atrust-acos.c | 3 +- src/libopensc/card-belpic.c | 9 ++-- src/libopensc/card-cac.c | 3 +- src/libopensc/card-cac1.c | 3 +- src/libopensc/card-cardos.c | 7 +-- src/libopensc/card-coolkey.c | 8 +-- src/libopensc/card-entersafe.c | 42 ++++++++-------- src/libopensc/card-gids.c | 37 +++++++++----- src/libopensc/card-isoApplet.c | 9 ++-- src/libopensc/card-itacns.c | 3 +- src/libopensc/card-masktech.c | 6 ++- src/libopensc/card-mcrd.c | 2 +- src/libopensc/card-muscle.c | 6 ++- src/libopensc/card-myeid.c | 22 +++++--- src/libopensc/card-oberthur.c | 3 +- src/libopensc/card-openpgp.c | 6 ++- src/libopensc/card-piv.c | 3 +- src/libopensc/card-rutoken.c | 56 ++++++++++++++------- src/libopensc/card-sc-hsm.c | 9 ++-- src/libopensc/card-setcos.c | 6 ++- src/libopensc/card-skeid.c | 3 +- src/libopensc/card-tcos.c | 9 ++-- src/libopensc/iso7816.c | 9 ++-- src/libopensc/muscle-filesystem.c | 3 +- src/libopensc/pkcs15-cache.c | 3 +- src/libopensc/pkcs15-gemsafeV1.c | 3 +- src/libopensc/pkcs15-pubkey.c | 9 ++-- src/libopensc/pkcs15-sc-hsm.c | 3 +- src/libopensc/pkcs15-syn.c | 3 +- src/pkcs15init/pkcs15-lib.c | 9 ++-- src/pkcs15init/pkcs15-rtecp.c | 84 ++++++++++++++++++------------- src/pkcs15init/pkcs15-rutoken.c | 6 --- src/pkcs15init/profile.c | 6 ++- src/sm/sm-common.c | 2 +- src/tests/print.c | 3 +- src/tools/pkcs15-init.c | 18 ++++--- src/tools/pkcs15-tool.c | 6 ++- 38 files changed, 270 insertions(+), 164 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 5b1ba88c41..71b9cb0c94 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1533,7 +1533,8 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_BIT_STRING: if (parm != NULL) { int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0; - assert(len != NULL); + if (len == NULL) + return SC_ERROR_INTERNAL; if (objlen < 1) { r = SC_ERROR_INVALID_ASN1_OBJECT; break; @@ -1564,7 +1565,8 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_OCTET_STRING: if (parm != NULL) { size_t c; - assert(len != NULL); + if (len == NULL) + return SC_ERROR_INTERNAL; /* Strip off padding zero */ if ((entry->flags & SC_ASN1_UNSIGNED) @@ -1595,7 +1597,8 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_GENERALIZEDTIME: if (parm != NULL) { size_t c; - assert(len != NULL); + if (len == NULL) + return SC_ERROR_INTERNAL; if (entry->flags & SC_ASN1_ALLOC) { u8 **buf = (u8 **) parm; if (objlen > 0) { @@ -1621,7 +1624,8 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_PRINTABLESTRING: case SC_ASN1_UTF8STRING: if (parm != NULL) { - assert(len != NULL); + if (len == NULL) + return SC_ERROR_INTERNAL; if (entry->flags & SC_ASN1_ALLOC) { u8 **buf = (u8 **) parm; *buf = malloc(objlen+1); diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 43a498e2a7..f56f4488d4 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -655,7 +655,8 @@ static int atrust_acos_decipher(struct sc_card *card, u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - assert(card != NULL && crgram != NULL && out != NULL); + if (card == NULL || crgram == NULL || out == NULL) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); if (crgram_len > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index b8166ae9cc..50d9c8f0da 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -172,7 +172,8 @@ static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddata u8 carddata_cmd[] = { 0x80, 0xE4, 0x00, 0x00, 0x1C }; int r; - assert(carddataloc_len == BELPIC_CARDDATA_RESP_LEN); + if (carddataloc_len != BELPIC_CARDDATA_RESP_LEN) + return SC_ERROR_INTERNAL; r = sc_bytes2apdu(card->ctx, carddata_cmd, sizeof(carddata_cmd), &apdu); if(r) { @@ -264,7 +265,8 @@ static int belpic_select_file(sc_card_t *card, size_t pathlen; sc_file_t *file = NULL; - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; @@ -353,7 +355,8 @@ static int belpic_set_security_env(sc_card_t *card, sc_log(card->ctx, "belpic_set_security_env(), keyRef = 0x%0x, algo = 0x%0lx\n", *env->key_ref, env->algorithm_flags); - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); switch (env->operation) { case SC_SEC_OPERATION_SIGN: diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 6a0fabf968..cde94587fd 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1056,7 +1056,8 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc struct sc_file *file = NULL; cac_private_data_t * priv = CAC_DATA(card); - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 06b2671f43..156d61d013 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -211,7 +211,8 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc struct sc_file *file = NULL; cac_private_data_t * priv = CAC_DATA(card); - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 2e9e59f06e..2b94b3c86b 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -927,7 +927,8 @@ cardos_set_security_env(sc_card_t *card, u8 data[9]; int key_id, r; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { sc_log(card->ctx, "No or invalid key reference\n"); @@ -1081,8 +1082,8 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, int do_rsa_sig = 0; size_t i; - - assert(card != NULL && data != NULL && out != NULL); + if (card == NULL || data == NULL || out == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; priv = (cardos_data_t*)card->drv_data; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 828c4c26b7..9539d6f9f4 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -476,7 +476,8 @@ coolkey_v0_get_attribute_count(const u8 *obj, size_t buf_len) * If the assert is true, you can easily see that the loop * will eventually break with len == 0, even if attribute_data_len * was invalid */ - assert(len <= buf_len); + if (len > buf_len) + return SC_ERROR_INTERNAL; count++; attr += len; buf_len -= len; @@ -1447,7 +1448,7 @@ coolkey_find_attribute(sc_card_t *card, sc_cardctl_coolkey_attribute_t *attribut } /* should be a static assert so we catch this at compile time */ - assert(sizeof(coolkey_object_header_t) >= sizeof(coolkey_v0_object_header_t)); + static_assert(sizeof(coolkey_object_header_t) >= sizeof(coolkey_v0_object_header_t), "internal error"); /* make sure we have enough of the object to read the record_type */ if (buf_len <= sizeof(coolkey_v0_object_header_t)) { return SC_ERROR_CORRUPTED_DATA; @@ -1915,7 +1916,8 @@ static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil coolkey_private_data_t * priv = COOLKEY_DATA(card); unsigned long object_id; - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 193ec59ece..da888500fd 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -203,10 +203,8 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card); - assert(apdu); - assert(key); - assert(buff); + if (card == NULL || apdu == NULL || key == NULL || buff == NULL) + return SC_ERROR_INTERNAL; /* padding as 0x80 0x00 0x00...... */ memset(buff, 0, buffsize); @@ -276,10 +274,8 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card); - assert(apdu); - assert(key); - assert(buff); + if (card == NULL || apdu == NULL || key == NULL || buff == NULL) + return SC_ERROR_INTERNAL; if (apdu->cse != SC_APDU_CASE_3_SHORT) return SC_ERROR_INTERNAL; @@ -380,8 +376,8 @@ static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card); - assert(apdu); + if (card == NULL || apdu == NULL) + return SC_ERROR_INTERNAL; if ((cipher || mac) && (!key || (keylen != 8 && keylen != 16))) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); @@ -435,7 +431,8 @@ static int entersafe_read_binary(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(count <= card->max_recv_size); + if (count > card->max_recv_size) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (idx >> 8) & 0xFF, idx & 0xFF); apdu.cla = idx > 0x7fff ? 0x80 : 0x00; @@ -461,7 +458,8 @@ static int entersafe_update_binary(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(count <= card->max_send_size); + if (count > card->max_send_size) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0xFF, idx & 0xFF); apdu.cla = idx > 0x7fff ? 0x80 : 0x00; @@ -481,7 +479,8 @@ static int entersafe_process_fci(struct sc_card *card, struct sc_file *file, { int r; - assert(file); + if (file == NULL) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); r = iso_ops->process_fci(card, file, buf, buflen); @@ -537,7 +536,8 @@ static int entersafe_select_aid(sc_card_t *card, if (file_out) { sc_file_t *file = *file_out; - assert(file); + if (file == NULL) + return SC_ERROR_INTERNAL; file->type = SC_FILE_TYPE_DF; file->ef_structure = SC_FILE_EF_UNKNOWN; @@ -588,8 +588,8 @@ static int entersafe_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - assert(card); - assert(in_path); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); switch (in_path->type) { @@ -730,7 +730,8 @@ static int entersafe_internal_set_security_env(sc_card_t *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: @@ -781,8 +782,8 @@ static int entersafe_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { - assert(card); - assert(env); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1350,7 +1351,8 @@ static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(serial); + if (serial == NULL) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xEA, 0x00, 0x00); apdu.cla = 0x80; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 260618629d..13c0c192b9 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -164,7 +164,8 @@ static int gids_get_identifiers(sc_card_t* card, u8* masterfile, size_t masterfi gids_mf_record_t *records = (gids_mf_record_t *) (masterfile+1); size_t recordcount = ((masterfilesize-1) / sizeof(gids_mf_record_t)); size_t i; - assert(masterfilesize >= 1); + if (masterfilesize < 1) + return SC_ERROR_INTERNAL; for (i = 0; i < recordcount; i++) { if (strcmp(directory, records[i].directory) == 0 && strcmp(filename, records[i].filename) == 0) { @@ -187,7 +188,8 @@ static int gids_find_available_DO(sc_card_t *card, u8* masterfile, size_t master size_t recordcount = (masterfilesize / sizeof(gids_mf_record_t)); size_t i; - assert(masterfilesize >= 1); + if (masterfilesize < 1) + return SC_ERROR_INTERNAL; *fileIdentifier = CERT_FI; @@ -751,7 +753,8 @@ static int gids_set_security_env(sc_card_t *card, u8 *p; int r, locked = 0; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); memset(sbuf, 0, sizeof(sbuf)); @@ -789,7 +792,8 @@ static int gids_set_security_env(sc_card_t *card, else *p++ = 0x84; *p++ = (u8) env->key_ref_len; - assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len); + if (sizeof(sbuf) - (p - sbuf) < env->key_ref_len) + return SC_ERROR_INTERNAL; memcpy(p, env->key_ref, env->key_ref_len); p += env->key_ref_len; @@ -876,7 +880,8 @@ static int gids_logout(sc_card_t *card) { struct sc_apdu apdu; int r; - assert(card && card->ctx); + if (card == NULL || card->ctx == NULL) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); @@ -1283,7 +1288,8 @@ static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); // sanity check - assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); + if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) + return SC_ERROR_INTERNAL; if (!algid) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); @@ -1408,7 +1414,8 @@ static int gids_generate_key(sc_card_t *card, sc_pkcs15_object_t *object, struct size_t buffersize = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); + if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) + return SC_ERROR_INTERNAL; if ((key_info->key_reference > GIDS_FIRST_KEY_IDENTIFIER + GIDS_MAX_CONTAINER) || (kid < GIDS_FIRST_KEY_IDENTIFIER)) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); @@ -1476,7 +1483,8 @@ static int gids_import_key(sc_card_t *card, sc_pkcs15_object_t *object, sc_pkcs1 { NULL, 0, 0, 0, NULL, NULL } }; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); + if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) + return SC_ERROR_INTERNAL; if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) { sc_log(card->ctx, "GIDS supports RSA keys only (but may support ECC one day)."); @@ -1567,8 +1575,10 @@ static int gids_save_certificate(sc_card_t *card, sc_pkcs15_object_t *certobject struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) privkeyobject->data; unsigned char containernum; char filename[9]; - assert((certobject->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT); - assert((privkeyobject->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); + if ((certobject->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_CERT) + return SC_ERROR_INTERNAL; + if ((privkeyobject->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) + return SC_ERROR_INTERNAL; // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); @@ -1674,8 +1684,8 @@ static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) { size_t recordcount, recordnum = (size_t) -1; size_t i; - - assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT); + if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_CERT) + return SC_ERROR_INTERNAL; // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); @@ -1729,7 +1739,8 @@ static int gids_delete_key(sc_card_t *card, sc_pkcs15_object_t* object) { size_t containernum; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data; - assert((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY); + if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY) + return SC_ERROR_INTERNAL; // refresh the cached data in case some thing has been modified r = gids_read_masterfile(card); LOG_TEST_RET(card->ctx, r, "gids read masterfile failed"); diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index e0f5c70f64..4dfaaa6e4e 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1072,7 +1072,8 @@ isoApplet_set_security_env(sc_card_t *card, LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet does not support storing of security environments."); } - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); switch (env->operation) { @@ -1126,7 +1127,8 @@ isoApplet_set_security_env(sc_card_t *card, { *p++ = 0x81; *p++ = env->file_ref.len; - assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len); + if (sizeof(sbuf) - (p - sbuf) < env->file_ref.len) + return SC_ERROR_INTERNAL; memcpy(p, env->file_ref.value, env->file_ref.len); p += env->file_ref.len; } @@ -1138,7 +1140,8 @@ isoApplet_set_security_env(sc_card_t *card, else *p++ = 0x84; *p++ = env->key_ref_len; - assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len); + if (sizeof(sbuf) - (p - sbuf) < env->key_ref_len) + return SC_ERROR_INTERNAL; memcpy(p, env->key_ref, env->key_ref_len); p += env->key_ref_len; } diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 87cc3ef820..778ad42ecc 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -238,7 +238,8 @@ static int itacns_set_security_env(sc_card_t *card, /* Do not complain about se_num; the argument is part of the API. */ (void) se_num; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index 03cb769279..9ecb0510d6 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -136,7 +136,8 @@ static int masktech_compute_signature(sc_card_t *card, 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; - assert(card != NULL && data != NULL && out != NULL); + if (card == NULL || data == NULL || out == NULL) + return SC_ERROR_INTERNAL; sc_log(card->ctx, "masktech_compute_signature()\n"); /* retrieve the key reference */ @@ -175,7 +176,8 @@ static int masktech_decipher(sc_card_t *card, sc_apdu_t apdu; u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; - assert(card != NULL && crgram != NULL && out != NULL); + if (card == NULL || crgram == NULL || out == NULL) + return SC_ERROR_INTERNAL; sc_log(card->ctx, "masktech_decipher()\n"); if (crgram_len > SC_MAX_EXT_APDU_BUFFER_SIZE) { diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 4790caa182..16f34602cc 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -113,7 +113,7 @@ static struct df_info_s *get_df_info(sc_card_t * card) struct mcrd_priv_data *priv = DRVDATA(card); struct df_info_s *dfi; - if(!(!priv->is_ef)) + if (priv->is_ef) return NULL; if (!priv->curpathlen) { diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index fc0b1fa3e1..455c37488a 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -136,7 +136,8 @@ static unsigned short muscle_parse_singleAcl(const sc_acl_entry_t* acl) static void muscle_parse_acls(const sc_file_t* file, unsigned short* read_perm, unsigned short* write_perm, unsigned short* delete_perm) { - assert(read_perm && write_perm && delete_perm); + if (read_perm == NULL || write_perm == NULL || delete_perm == NULL) + return; *read_perm = muscle_parse_singleAcl(sc_file_get_acl_entry(file, SC_AC_OP_READ)); *write_perm = muscle_parse_singleAcl(sc_file_get_acl_entry(file, SC_AC_OP_UPDATE)); *delete_perm = muscle_parse_singleAcl(sc_file_get_acl_entry(file, SC_AC_OP_DELETE)); @@ -433,7 +434,8 @@ static int muscle_select_file(sc_card_t *card, const sc_path_t *path_in, { int r; - assert(card != NULL && path_in != NULL); + if (card == NULL || path_in == NULL) + return SC_ERROR_INTERNAL; switch (path_in->type) { case SC_PATH_TYPE_FILE_ID: diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index b8bb46b2c1..8d10bd9a82 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -699,7 +699,8 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t * size_t i, sz; sc_path_t *target_file; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) @@ -849,7 +850,8 @@ static int myeid_set_security_env_ec(sc_card_t *card, const sc_security_env_t *e size_t sz; int r; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) @@ -1023,7 +1025,8 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char * size_t len_size = 1; size_t sig_len = 0; - assert(data && datalen && datalen > 3); + if (!data || !datalen || datalen <= 3) + return SC_ERROR_INTERNAL; /* * When validating the signature data, we have to consider that length of the signature @@ -1153,8 +1156,8 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen, size_t field_length = 0; size_t pad_chars = 0; - - assert(card != NULL && data != NULL && out != NULL); + if (card == NULL || data == NULL || out == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -1383,7 +1386,8 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, LOG_FUNC_CALLED(card->ctx); - assert(card != NULL && crgram != NULL && out != NULL); + if (card == NULL || crgram == NULL || out == NULL) + return SC_ERROR_INTERNAL; priv = (myeid_private_data_t*) card->drv_data; @@ -1408,7 +1412,8 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - assert(card != NULL); + if (card == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; LOG_FUNC_CALLED(ctx); @@ -1874,7 +1879,8 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, size_t max_apdu_datalen; size_t apdu_datalen; - assert(card != NULL); + if (card == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; LOG_FUNC_CALLED(ctx); diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 8a103757e5..754d17afde 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -449,7 +449,8 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, int rv; LOG_FUNC_CALLED(card->ctx); - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; memcpy(&path, in_path, sizeof(struct sc_path)); diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 2e99e93191..ce317810a6 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3570,7 +3570,8 @@ set_taglength_tlv(u8 *buffer, unsigned int tag, size_t length) { u8 *p = buffer; - assert(tag <= 0xffff); + if (tag > 0xffff) + return SC_ERROR_INTERNAL; if (tag > 0xff) *p++ = (tag >> 8) & 0xFF; *p++ = tag; @@ -3672,7 +3673,8 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store memset(pritemplate, 0, max_prtem_len); /* maximum 32 bit exponent length allowed on OpenPGP Card */ - assert(key_info->u.rsa.exponent_len <= SC_OPENPGP_MAX_EXP_BITS); + if (key_info->u.rsa.exponent_len > SC_OPENPGP_MAX_EXP_BITS) + return SC_ERROR_INTERNAL; /* We need to right justify the exponent with allowed exponent length, * e.g. from '01 00 01' to '00 01 00 01' */ diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c0d43e743b..5ad14d76ef 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3124,7 +3124,8 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); + if (enumtag < 0 || enumtag > PIV_OBJ_LAST_ENUM) + return SC_ERROR_INTERNAL; sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name); diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 3fa2d46d03..7a591f8ccf 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -93,7 +93,8 @@ static const struct sc_atr_table rutoken_atrs[] = { static int rutoken_finish(sc_card_t *card) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(card->drv_data); + if (!card->drv_data) + return SC_ERROR_INTERNAL; free(card->drv_data); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -246,9 +247,11 @@ static int rutoken_list_files(sc_card_t *card, u8 *buf, size_t buflen) size_t taglen, len = 0; int ret; - assert(card && card->ctx); + if (!card || !card->ctx) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(buf); + if (!buf) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0, 0); for (;;) @@ -364,10 +367,12 @@ static int rutoken_select_file(sc_card_t *card, size_t pathlen; int ret; - assert(card && card->ctx); + if (!card || !card->ctx) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(in_path && sizeof(pathbuf) >= in_path->len); + if (in_path == NULL || sizeof(pathbuf) < in_path->len) + return SC_ERROR_INTERNAL; memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; @@ -440,7 +445,8 @@ static int rutoken_select_file(sc_card_t *card, sc_file_free(file); else { - assert(file_out); + if (!file_out) + return SC_ERROR_INTERNAL; *file_out = file; } LOG_FUNC_RETURN(card->ctx, ret); @@ -478,11 +484,14 @@ static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, { u8 buf[64], *p = out; - assert(card && card->ctx); + if (!card || !card->ctx) + return SC_ERROR_INTERNAL; LOG_FUNC_CALLED(card->ctx); - assert(file && out && outlen); - assert(*outlen >= (size_t)(p - out) + 2); + if (!file || !out || !outlen) + return SC_ERROR_INTERNAL; + if (*outlen < (size_t)(p - out) + 2) + return SC_ERROR_INTERNAL; *p++ = 0x62; /* FCP template */ p++; /* for length */ @@ -494,7 +503,8 @@ static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, /* 0x82 - File descriptor byte */ if (file->type_attr_len) { - assert(sizeof(buf) >= file->type_attr_len); + if (sizeof(buf) < file->type_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->type_attr, file->type_attr_len); sc_asn1_put_tag(0x82, buf, file->type_attr_len, p, *outlen - (p - out), &p); @@ -523,14 +533,16 @@ static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, if (file->prop_attr_len) { - assert(sizeof(buf) >= file->prop_attr_len); + if (sizeof(buf) < file->prop_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->prop_attr, file->prop_attr_len); sc_asn1_put_tag(0x85, buf, file->prop_attr_len, p, *outlen - (p - out), &p); } if (file->sec_attr_len) { - assert(sizeof(buf) >= file->sec_attr_len); + if (sizeof(buf) < file->sec_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->sec_attr, file->sec_attr_len); sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p); @@ -598,16 +610,19 @@ static int rutoken_create_file(sc_card_t *card, sc_file_t *file) { int ret; - assert(card && card->ctx); + if (!card || !card->ctx) + return SC_ERROR_INTERNAL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - assert(file); + if (!file) + return SC_ERROR_INTERNAL; if (file->sec_attr_len == 0) { ret = set_sec_attr_from_acl(card, file); LOG_TEST_RET(card->ctx, ret, "Set sec_attr from ACL failed"); } - assert(iso_ops && iso_ops->create_file); + if (!iso_ops || !iso_ops->create_file) + return SC_ERROR_INTERNAL; ret = iso_ops->create_file(card, file); LOG_FUNC_RETURN(card->ctx, ret); } @@ -817,7 +832,8 @@ static void rutoken_set_do_hdr(u8 *data, size_t *data_len, sc_DOHdrV2_t *hdr) { u8 buf[64], *p = data; - assert(hdr && data && data_len); + if (!hdr || !data || !data_len) + return; /* 0x80 - Number of data bytes in the file, excluding structural information */ buf[1] = (hdr->wDOBodyLen >> 8) & 0xFF; @@ -835,11 +851,12 @@ static void rutoken_set_do_hdr(u8 *data, size_t *data_len, sc_DOHdrV2_t *hdr) buf[2] = hdr->OP.byObjectTry; sc_asn1_put_tag(0x85, buf, 3, p, *data_len - (p - data), &p); - assert(sizeof(buf) >= sizeof(hdr->SA_V2)); + static_assert(sizeof(buf) >= sizeof(hdr->SA_V2), "internal error"); memcpy(buf, hdr->SA_V2, sizeof(hdr->SA_V2)); sc_asn1_put_tag(0x86, buf, sizeof(hdr->SA_V2), p, *data_len - (p - data), &p); - assert(*data_len >= (size_t)(p - data)); + if (*data_len < (size_t)(p - data)) + return; *data_len = p - data; } @@ -904,7 +921,8 @@ static int rutoken_create_do(sc_card_t *card, sc_DO_V2_t * pDO) else { rutoken_set_do_hdr(data, &data_len, &pDO->HDR); - assert(sizeof(data) >= data_len + pDO->HDR.wDOBodyLen + 2); + if (sizeof(data) < data_len + pDO->HDR.wDOBodyLen + 2) + return SC_ERROR_INTERNAL; ret = sc_asn1_put_tag(0xA5, pDO->abyDOBody, pDO->HDR.wDOBodyLen, data + data_len, sizeof(data) - data_len, NULL); if (ret == SC_SUCCESS) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 528c61cfd9..26f3e07478 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -812,7 +812,8 @@ static int sc_hsm_read_binary(sc_card_t *card, cmdbuff[2] = (idx >> 8) & 0xFF; cmdbuff[3] = idx & 0xFF; - assert(count <= sc_get_max_recv_size(card)); + if (count > sc_get_max_recv_size(card)) + return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00); apdu.data = cmdbuff; apdu.datalen = 4; @@ -1162,7 +1163,8 @@ static int sc_hsm_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len // // The SmartCard-HSM returns the point result of the DH operation // with a leading '04' - assert(apdu.resplen > 0); + if (apdu.resplen <= 0) + return SC_ERROR_INTERNAL; len = apdu.resplen - 1 > outlen ? outlen : apdu.resplen - 1; memcpy(out, apdu.resp + 1, len); LOG_FUNC_RETURN(card->ctx, (int)len); @@ -1358,7 +1360,8 @@ static int sc_hsm_import_dkek_share(sc_card_t *card, sc_cardctl_sc_hsm_dkek_t *p LOG_TEST_RET(ctx, r, "Check SW error"); - assert(apdu.resplen >= (sizeof(params->key_check_value) + 2)); + if (apdu.resplen < (sizeof(params->key_check_value) + 2)) + return SC_ERROR_INTERNAL; params->dkek_shares = status[0]; params->outstanding_shares = status[1]; diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 0ebe7c34f7..145ad3781b 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -371,7 +371,8 @@ static int setcos_pin_index_44(int *pins, int len, int pin) return i; } } - assert(i != len); /* Too much PINs, shouldn't happen */ + if (i == len) + return SC_ERROR_INTERNAL; return 0; } @@ -539,7 +540,8 @@ static int setcos_set_security_env2(sc_card_t *card, u8 *p; int r, locked = 0; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; if (card->type == SC_CARD_TYPE_SETCOS_44 || card->type == SC_CARD_TYPE_SETCOS_NIDEL || diff --git a/src/libopensc/card-skeid.c b/src/libopensc/card-skeid.c index 4062ee485c..882d53b84b 100644 --- a/src/libopensc/card-skeid.c +++ b/src/libopensc/card-skeid.c @@ -147,7 +147,8 @@ static int skeid_set_security_env(sc_card_t *card, int key_id; int r; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { sc_log(card->ctx, "No or invalid key reference"); diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 80527a6366..6eedd99c53 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -341,7 +341,8 @@ static int tcos_select_file(sc_card_t *card, int r; size_t pathlen; - assert(card != NULL && in_path != NULL); + if (card == NULL || in_path == NULL) + return SC_ERROR_INTERNAL; ctx=card->ctx; memcpy(path, in_path->value, in_path->len); pathlen = in_path->len; @@ -417,7 +418,8 @@ static int tcos_list_files(sc_card_t *card, u8 *buf, size_t buflen) u8 rbuf[SC_MAX_APDU_BUFFER_SIZE], p1; int r, count = 0; - assert(card != NULL); + if (card == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; for (p1=1; p1<=2; p1++) { @@ -478,7 +480,8 @@ static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, int r, default_key, tcos3; tcos_data *data; - assert(card != NULL && env != NULL); + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; ctx = card->ctx; tcos3=(card->type==SC_CARD_TYPE_TCOS_V3); data=(tcos_data *)card->drv_data; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index d91ab4a80c..2d509920c8 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -825,7 +825,8 @@ iso7816_construct_fci(struct sc_card *card, const sc_file_t *file, sc_asn1_put_tag(0x81, buf, 2, p, *outlen - (p - out), &p); if (file->type_attr_len) { - assert(sizeof(buf) >= file->type_attr_len); + if (sizeof(buf) < file->type_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->type_attr, file->type_attr_len); sc_asn1_put_tag(0x82, buf, file->type_attr_len, p, *outlen - (p - out), &p); @@ -851,13 +852,15 @@ iso7816_construct_fci(struct sc_card *card, const sc_file_t *file, sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p); /* 0x84 = DF name */ if (file->prop_attr_len) { - assert(sizeof(buf) >= file->prop_attr_len); + if (sizeof(buf) < file->prop_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->prop_attr, file->prop_attr_len); sc_asn1_put_tag(0x85, buf, file->prop_attr_len, p, *outlen - (p - out), &p); } if (file->sec_attr_len) { - assert(sizeof(buf) >= file->sec_attr_len); + if (sizeof(buf) < file->sec_attr_len) + return SC_ERROR_INTERNAL; memcpy(buf, file->sec_attr, file->sec_attr_len); sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p); diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 2e65b4576d..99a5fe162f 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -216,7 +216,8 @@ int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, size_t pathlen, mscfs_file_t { msc_id fullPath = {{0, 0, 0, 0}}; int x, rc; - assert(fs != NULL && path != NULL && file_data != NULL); + if (fs == NULL || path == NULL || file_data == NULL) + return SC_ERROR_INTERNAL; rc = mscfs_lookup_path(fs, path, pathlen, &fullPath, 0); if (rc != SC_SUCCESS) { return rc; diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index 6e0f70735c..394be867cd 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -53,7 +53,8 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card, || p15card->card->uid.value[0] == RANDOM_UID_INDICATOR)) return SC_ERROR_INVALID_ARGUMENTS; - assert(path->len <= SC_MAX_PATH_SIZE); + if (path->len > SC_MAX_PATH_SIZE) + return SC_ERROR_INTERNAL; r = sc_get_cache_dir(p15card->card->ctx, dir, sizeof(dir)); if (r) return r; diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 389e56667d..317c4bb1be 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -472,7 +472,8 @@ sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type) } } - assert(created == 0); + if (created != 0) + return NULL; file = sc_file_new(); if (!file) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index b59869683f..e9539dbe9d 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -295,16 +295,19 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; } else if (asn1_pubkey_choice[1].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; - assert(info->modulus_length == 0); + if (info->modulus_length != 0) + return SC_ERROR_INTERNAL; info->modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; - assert(info->params.len == 0); + if (info->params.len != 0) + return SC_ERROR_INTERNAL; info->params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); info->params.data = malloc(info->params.len); if (info->params.data == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - assert(sizeof(*keyinfo_gostparams) == info->params.len); + if (sizeof(*keyinfo_gostparams) != info->params.len) + return SC_ERROR_INTERNAL; keyinfo_gostparams = info->params.data; keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0]; keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1]; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 51f1ec5768..13151ca387 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1444,7 +1444,8 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) } len = strnlen(devcert.chr, sizeof devcert.chr); /* Strip last 5 digit sequence number from CHR */ - assert(len >= 8); + if (len < 8) + return SC_ERROR_INTERNAL; len -= 5; free(p15card->tokeninfo->serial_number); diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index bcfdf690f8..375c3e7f3e 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -349,7 +349,8 @@ static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, } } - assert(created == 0); + if (created != 0) + return NULL; file = sc_file_new(); if (!file) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 0f67cc7b04..2643e3ac0b 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3392,7 +3392,8 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof } sc_pkcs15_add_df(p15card, df_type, &file->path); df = find_df_by_type(p15card, df_type); - assert(df != NULL); + if (df == NULL) + return SC_ERROR_INTERNAL; is_new = 1; /* Mark the df as enumerated, so libopensc doesn't try @@ -3412,7 +3413,8 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof } else { sc_log(ctx, "Reuse existing object"); - assert(object->df == df); + if (object->df != df) + return SC_ERROR_INTERNAL; } if (profile->ops->emu_update_any_df) @@ -4084,7 +4086,8 @@ sc_pkcs15init_authenticate(struct sc_profile *profile, struct sc_pkcs15_card *p1 int r = 0; LOG_FUNC_CALLED(ctx); - assert(file != NULL); + if (file == NULL) + return SC_ERROR_INTERNAL; sc_log(ctx, "path '%s', op=%u", sc_print_path(&file->path), op); if (file->acl_inactive) { diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 0378937340..e4946565a6 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -55,13 +55,16 @@ static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name sc_path_t path; int r; - assert(profile && card && card->ctx && name); + if (profile == NULL || card == NULL || card->ctx == NULL || name == NULL) + return SC_ERROR_INTERNAL; r = sc_profile_get_file(profile, name, &file); if (r == SC_SUCCESS) { - assert(file); + if (!file) + return SC_ERROR_INTERNAL; path = file->path; - assert(path.len > 2); + if (path.len <= 2) + return SC_ERROR_INTERNAL; if (path.len > 2) path.len -= 2; r = sc_select_file(card, &path, NULL); @@ -75,8 +78,7 @@ static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name r = sc_create_file(card, file); sc_file_free(file); } - sc_log(card->ctx, - "Create %s failed: %s\n", name, sc_strerror(r)); + sc_log(card->ctx, "Create %s failed: %s\n", name, sc_strerror(r)); return r; } @@ -96,14 +98,16 @@ static int rtecp_init(sc_profile_t *profile, sc_pkcs15_card_t *p15card) r = sc_profile_get_file(profile, "MF", &file); LOG_TEST_RET(card->ctx, r, "Get MF info failed"); - assert(file); + if (file == NULL) + return SC_ERROR_INTERNAL; r = sc_create_file(card, file); sc_file_free(file); LOG_TEST_RET(card->ctx, r, "Create MF failed"); r = sc_profile_get_file(profile, "DIR", &file); LOG_TEST_RET(card->ctx, r, "Get DIR file info failed"); - assert(file); + if (!file) + return SC_ERROR_INTERNAL; r = sc_create_file(card, file); sc_file_free(file); LOG_TEST_RET(card->ctx, r, "Create DIR file failed"); @@ -230,13 +234,13 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); file->id = auth_info->attrs.pin.reference; file->size = pin_len; - assert(sizeof(sec)/sizeof(sec[0]) > 2); + static_assert(sizeof(prop) / sizeof(prop[0]) > 3, "internal error"); sec[1] = (auth_info->attrs.pin.reference == RTECP_SO_PIN_REF) ? 0xFF : RTECP_SO_PIN_REF; sec[2] = (unsigned char)auth_info->attrs.pin.reference | (reset_by_sopin ? RTECP_SO_PIN_REF : 0); r = sc_file_set_sec_attr(file, sec, sizeof(sec)); if (r == SC_SUCCESS) { - assert(sizeof(prop)/sizeof(prop[0]) > 3); + static_assert(sizeof(prop) / sizeof(prop[0]) > 3, "internal error"); prop[1] = (unsigned char)auth_info->attrs.pin.min_length; prop[3] = 0x11 * (unsigned char)(auth_info->tries_left & 0x0F); r = sc_file_set_prop_attr(file, prop, sizeof(prop)); @@ -272,7 +276,8 @@ static int rtecp_select_key_reference(sc_profile_t *profile, r = sc_profile_get_file(profile, "PrKey-DF", &df); LOG_TEST_RET(p15card->card->ctx, r, "Get PrKey-DF info failed"); - assert(df); + if (!df) + return SC_ERROR_INTERNAL; key_info->path = df->path; sc_file_free(df); r = sc_append_file_id(&key_info->path, key_info->key_reference); @@ -316,16 +321,15 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, auth_id = obj->auth_id.value[0]; key_info = (sc_pkcs15_prkey_info_t *)obj->data; - assert(key_info); + if (!key_info) + return SC_ERROR_INTERNAL; if ((obj->type == SC_PKCS15_TYPE_PRKEY_RSA && key_info->modulus_length % 128 != 0) || (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410 && key_info->modulus_length != SC_PKCS15_GOSTR3410_KEYSIZE)) { - sc_log(ctx, - "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", - key_info->modulus_length); + sc_log(ctx, "Unsupported key size %" SC_FORMAT_LEN_SIZE_T "u\n", key_info->modulus_length); return SC_ERROR_INVALID_ARGUMENTS; } if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) @@ -336,8 +340,8 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, || ((int*)key_info->params.data)[0] > 3) return SC_ERROR_INVALID_ARGUMENTS; paramset = ((unsigned int*)key_info->params.data)[0] & 0x03; - assert(sizeof(prgkey_prop)/sizeof(prgkey_prop[0]) > 1); - assert(sizeof(pbgkey_prop)/sizeof(pbgkey_prop[0]) > 1); + static_assert(sizeof(prgkey_prop) / sizeof(prgkey_prop[0]) > 1, "internal error"); + static_assert(sizeof(pbgkey_prop) / sizeof(pbgkey_prop[0]) > 1, "internal error"); prgkey_prop[1] = 0x10 + (paramset << 4); pbgkey_prop[1] = prgkey_prop[1]; } @@ -363,7 +367,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, file->size = key_info->modulus_length / 8; if (r == SC_SUCCESS) { - assert(sizeof(prkey_sec)/sizeof(prkey_sec[0]) > 7); + static_assert(sizeof(prkey_sec) / sizeof(prkey_sec[0]) > 7, "internal error"); prkey_sec[2] = auth_id; prkey_sec[3] = auth_id; prkey_sec[7] = auth_id; @@ -387,7 +391,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, file->size = key_info->modulus_length / 8 * 2; if (r == SC_SUCCESS) { - assert(sizeof(pbkey_sec)/sizeof(pbkey_sec[0]) > 7); + static_assert(sizeof(pbkey_sec) / sizeof(pbkey_sec[0]) > 7, "internal error"); pbkey_sec[2] = auth_id; pbkey_sec[7] = auth_id; r = sc_file_set_sec_attr(file, pbkey_sec, sizeof(pbkey_sec)); @@ -434,18 +438,21 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return SC_ERROR_NOT_SUPPORTED; key_info = (sc_pkcs15_prkey_info_t *)obj->data; - assert(key_info); + if (!key_info) + return SC_ERROR_INTERNAL; if (key->algorithm == SC_ALGORITHM_RSA) { - assert(key_info->modulus_length % 128 == 0); + if (key_info->modulus_length % 128 != 0) + return SC_ERROR_INTERNAL; len = key_info->modulus_length / 8 / 2; key_len = len * 5 + 8; buf_len = key_len; } else { - assert(key_info->modulus_length == SC_PKCS15_GOSTR3410_KEYSIZE); + if (key_info->modulus_length != SC_PKCS15_GOSTR3410_KEYSIZE) + return SC_ERROR_INTERNAL; len = key_info->modulus_length / 8; key_len = len; buf_len = len; @@ -465,7 +472,8 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, buf = calloc(1, buf_len); if (!buf) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - assert(key_len <= buf_len); + if (key_len > buf_len) + return SC_ERROR_INTERNAL; if (key->algorithm == SC_ALGORITHM_RSA) { /* p */ @@ -495,14 +503,16 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, key_len, NULL); - assert(buf); + if (!buf) + return SC_ERROR_INTERNAL; sc_mem_clear(buf, key_len); /* store public key */ if (key->algorithm == SC_ALGORITHM_RSA) key_len = len * 3; else goto end; - assert(key_len <= buf_len); + if (key_len > buf_len) + return SC_ERROR_INTERNAL; if (key->algorithm == SC_ALGORITHM_RSA) { /* modulus */ @@ -518,7 +528,8 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_profile_get_file(profile, "PuKey-DF", &pukey_df); if (r == SC_SUCCESS) { - assert(pukey_df); + if (!pukey_df) + return SC_ERROR_INTERNAL; path = pukey_df->path; r = sc_append_file_id(&path, key_info->key_reference); sc_file_free(pukey_df); @@ -536,7 +547,8 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_log(card->ctx, "%s\n", "Store public key failed"); } end: - assert(buf); + if (!buf) + return SC_ERROR_INTERNAL; free(buf); LOG_FUNC_RETURN(card->ctx, r); } @@ -570,13 +582,16 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return SC_ERROR_NOT_SUPPORTED; } key_info = (sc_pkcs15_prkey_info_t *)obj->data; - assert(key_info); + if (!key_info) + return SC_ERROR_INTERNAL; data.key_id = key_info->key_reference; - assert(data.key_id != 0); + if (data.key_id == 0) + return SC_ERROR_INTERNAL; switch (data.type) { case SC_ALGORITHM_RSA: - assert(key_info->modulus_length % 128 == 0); + if (key_info->modulus_length % 128 != 0) + return SC_ERROR_INTERNAL; data.u.rsa.modulus_len = key_info->modulus_length / 8; data.u.rsa.modulus = calloc(1, data.u.rsa.modulus_len); data.u.rsa.exponent_len = key_info->modulus_length / 8 / 2; @@ -589,7 +604,8 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } break; case SC_ALGORITHM_GOSTR3410: - assert(key_info->modulus_length == SC_PKCS15_GOSTR3410_KEYSIZE); + if (key_info->modulus_length != SC_PKCS15_GOSTR3410_KEYSIZE) + return SC_ERROR_INTERNAL; data.u.gostr3410.xy_len = key_info->modulus_length / 8 * 2; data.u.gostr3410.xy = calloc(1, data.u.gostr3410.xy_len); if (!data.u.gostr3410.xy) @@ -599,12 +615,13 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, } break; default: - assert(0); + return SC_ERROR_INTERNAL; } r = sc_card_ctl(p15card->card, SC_CARDCTL_RTECP_GENERATE_KEY, &data); if (r == SC_SUCCESS) { - assert(pubkey); + if (!pubkey) + return SC_ERROR_INTERNAL; pubkey->algorithm = data.type; switch (data.type) { @@ -634,10 +651,9 @@ static int rtecp_finalize(sc_card_t *card) return sc_card_ctl(card, SC_CARDCTL_RTECP_INIT_END, NULL); } - /* * Delete object - * + * * Applied to private key: used to delete public part internal file */ static int rtecp_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card, diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 2cab2fe9b8..fc83954d65 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -181,14 +181,8 @@ static int create_pins(sc_card_t *card) param_do.HDR.OP.byObjectFlags = do_pins[i].flags; param_do.HDR.OP.byObjectTry = do_pins[i].try; param_do.HDR.wDOBodyLen = sizeof(do_pins[i].pass); - /* assert(do_pins[i].p_sattr != NULL); */ - /* assert(sizeof(*param_do.HDR.SA_V2)) */ - /* assert(sizeof(param_do.HDR.SA_V2) == sizeof(*do_pins[i].p_sattr)); */ memcpy(param_do.HDR.SA_V2, *do_pins[i].p_sattr, sizeof(*do_pins[i].p_sattr)); - /* assert(do_pins[i].pass); */ - /* assert(sizeof(*param_do.abyDOBody)) */ - /* assert(sizeof(param_do.abyDOBody) >= sizeof(do_pins[i].pass)); */ memcpy(param_do.abyDOBody, do_pins[i].pass, sizeof(do_pins[i].pass)); r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_CREATE_DO, ¶m_do); diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index aa72cf688a..13258a4868 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -720,7 +720,8 @@ sc_profile_instantiate_template(sc_profile_t *profile, /* This loop relies on the fact that new files are always * appended to the list, after the parent files they refer to */ - assert(base_file->instance); + if (base_file->instance == NULL) + return SC_ERROR_INTERNAL; for (fi = tmpl->ef_list; fi; fi = fi->next) { struct file_info *parent, *instance; unsigned int skew = 0; @@ -1277,7 +1278,8 @@ new_file(struct state *cur, const char *name, unsigned int type) profile->df[df_type] = file; free_file = 1; } - assert(file); + if (!file) + return NULL; if (file->type != type) { parse_error(cur, "inconsistent file type (should be %s)", file->type == SC_FILE_TYPE_DF diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index faa9107b54..1a9f5d24b8 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -465,7 +465,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, decrypted_len -= decrypted_len % 8; decrypted = malloc(decrypted_len); - if (!(decrypted)) + if (!decrypted) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM decrypt_des_cbc3: allocation error"); #if OPENSSL_VERSION_NUMBER < 0x30000000L diff --git a/src/tests/print.c b/src/tests/print.c index 31b2e715f5..163c686297 100644 --- a/src/tests/print.c +++ b/src/tests/print.c @@ -24,7 +24,8 @@ void sc_test_print_card(const sc_pkcs15_card_t *mycard) }; int i, count = 0; - assert(mycard != NULL); + if (mycard == NULL) + return; printf("PKCS#15 Card [%s]:\n", mycard->tokeninfo->label); printf("\tVersion : %d\n", mycard->tokeninfo->version); printf("\tSerial number : %s\n", mycard->tokeninfo->serial_number); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index b978e0677a..2cba803c4b 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1937,19 +1937,25 @@ init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey #endif int nid = NID_undef; - assert(pkey); + if (!pkey) + return; if (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { - assert(params); + if (!params) + return; #if OPENSSL_VERSION_NUMBER < 0x30000000L key = EVP_PKEY_get0(pkey); - assert(key); - assert(EC_KEY_get0_group(key)); + if (!key) + return; + if (!EC_KEY_get0_group(key)) + return; nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key)); #else - assert(EVP_PKEY_get_group_name(pkey, name, sizeof(name), NULL)); + if (!EVP_PKEY_get_group_name(pkey, name, sizeof(name), NULL)) + return; nid = OBJ_txt2nid(name); #endif - assert(nid > 0); + if (nid <= 0) + return; switch (nid) { case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_A; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index fc5df6b5eb..c48175db98 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1508,7 +1508,8 @@ static void print_pin_info(const struct sc_pkcs15_object *obj) const size_t pf_count = NELEMENTS(pin_flags); size_t i; - assert(obj->type == SC_PKCS15_TYPE_AUTH_PIN || obj->type == SC_PKCS15_TYPE_AUTH_AUTHKEY); + if (obj->type != SC_PKCS15_TYPE_AUTH_PIN && obj->type != SC_PKCS15_TYPE_AUTH_AUTHKEY) + return; if (compact) { printf("\t%-3s ID:%s", obj->type == SC_PKCS15_TYPE_AUTH_PIN ? "PIN" : "Key", @@ -2152,7 +2153,8 @@ int main(int argc, char *argv[]) int action_count = 0; sc_context_param_t ctx_param; - assert(sizeof(option_help)/sizeof(char *)==sizeof(options)/sizeof(struct option)); + static_assert(sizeof(option_help) / sizeof(char *) == sizeof(options) / sizeof(struct option), + "internal error"); while (1) { c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind); From 6a8b1b65714ecb99c6ecc35e95aec4fc27002776 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:06:44 +0000 Subject: [PATCH 4210/4321] build(deps): bump vapier/coverity-scan-action from 0 to 1 Bumps [vapier/coverity-scan-action](https://github.com/vapier/coverity-scan-action) from 0 to 1. - [Release notes](https://github.com/vapier/coverity-scan-action/releases) - [Commits](https://github.com/vapier/coverity-scan-action/compare/v0...v1) --- updated-dependencies: - dependency-name: vapier/coverity-scan-action dependency-version: '1' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/coverity.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index cb5b536592..ab4794fcdc 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -19,7 +19,7 @@ jobs: - run: .github/setup-linux.sh force-install - run: ./bootstrap - run: ./configure --disable-dependency-tracking --enable-piv-sm - - uses: vapier/coverity-scan-action@v0 + - uses: vapier/coverity-scan-action@v1 if: ${{ env.HAS_COVERITY_SCAN_TOKEN == 'true' }} with: project: OpenSC%2FOpenSC From 80ea44e9fcd01785742dea8df62fecd755be14fd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 20 Apr 2026 19:54:29 +0200 Subject: [PATCH 4211/4321] authentic: Make coverity happy about bounds Coverity thinks about this as illegal access, when pin1->len == pin1->pad_length == sizeof(pin_buff) but this would really result only in the memset of 0-length, which should not really access that memory. But this call is technically not needed so lets skip it. CID 503305 --- src/libopensc/card-authentic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index ee9e3ae025..b0dce1873c 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1043,7 +1043,10 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, if (pin1->len > pin1->pad_length || pin1->pad_length > sizeof(pin_buff)) { LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_LENGTH); } - memset(pin_buff + pin1->len, pin1->pad_char, pin1->pad_length - pin1->len); + if (pin1->len < sizeof(pin_buff)) { + memset(pin_buff + pin1->len, pin1->pad_char, + pin1->pad_length - pin1->len); + } pin_len = pin1->pad_length; } From a5f0f407497655e4468c515a7ac37066baabea32 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 Apr 2026 12:10:12 +0200 Subject: [PATCH 4212/4321] pkcs15init: Avoid memory leak Thanks coverity CID 503351 --- src/pkcs15init/pkcs15-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 2643e3ac0b..b5f02971e1 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3472,6 +3472,7 @@ sc_pkcs15init_new_object(int type, const char *label, struct sc_pkcs15_id *auth_ if (data_size) { object->data = calloc(1, data_size); if (!object->data) { + free(object); return NULL; } From f47791e76d1dc26db94c2857685fea14ab26fff0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:40:44 +0200 Subject: [PATCH 4213/4321] isoapplet: Avoid possible NULL dereference by moving the NULL check before all uses of the card pointer CID 503459 --- src/libopensc/card-isoApplet.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 4dfaaa6e4e..55355c682b 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1063,17 +1063,21 @@ isoApplet_set_security_env(sc_card_t *card, u8 *p; int r; size_t sz; - struct isoApplet_drv_data *drvdata = DRVDATA(card); + struct isoApplet_drv_data *drvdata = NULL; + + if (card == NULL || env == NULL) { + return SC_ERROR_INTERNAL; + } LOG_FUNC_CALLED(card->ctx); + drvdata = DRVDATA(card); + if(se_num != 0) { LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet does not support storing of security environments."); } - if (card == NULL || env == NULL) - return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); switch (env->operation) { From fc72a397c4d669fa797eaf95046c27482ce5d130 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:40:00 +0200 Subject: [PATCH 4214/4321] rutoken: Remove dead code CID 503460 The file_out is already checked its not NULL before. --- src/libopensc/card-rutoken.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 7a591f8ccf..21bc1c8dad 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -445,8 +445,6 @@ static int rutoken_select_file(sc_card_t *card, sc_file_free(file); else { - if (!file_out) - return SC_ERROR_INTERNAL; *file_out = file; } LOG_FUNC_RETURN(card->ctx, ret); From 3715c068a6f4a4f9c82b4519cf4587332283d770 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:45:34 +0200 Subject: [PATCH 4215/4321] setcos: Avoid negative indexing CID 503461 --- src/libopensc/card-setcos.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 145ad3781b..4b1d1773a2 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -430,6 +430,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) /* Get enabled commands + required Keys/Pins */ memset(bCommands_pin, 0, sizeof(bCommands_pin)); for (i = 7; i >= 0; i--) { /* for each AC Setcos operation */ + int pin_index; bCommands_always <<= 1; bCommands_key <<= 1; @@ -447,7 +448,11 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) sc_log(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n"); return SC_ERROR_INVALID_ARGUMENTS; } - bCommands_pin[setcos_pin_index_44(pins, sizeof(pins)/sizeof(pins[0]), (int) bNumber)] |= 1 << i; + pin_index = setcos_pin_index_44(pins, sizeof(pins) / sizeof(pins[0]), (int)bNumber); + if (pin_index < 0) { + return SC_ERROR_INTERNAL; + } + bCommands_pin[pin_index] |= 1 << i; break; case SC_AC_TERM: /* key */ bKeyNumber = bNumber; /* There should be only 1 key */ From cf9e46bc2977f5bcd3e7e8a7c7b8ad697bcc0cfd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:47:00 +0200 Subject: [PATCH 4216/4321] myeid: Avoid possible NULL pointer dereference by moving the check before using the pointer CID 503462 --- src/libopensc/card-myeid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 8d10bd9a82..0f0fd287e8 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1384,12 +1384,12 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, int r; myeid_private_data_t* priv; - LOG_FUNC_CALLED(card->ctx); - if (card == NULL || crgram == NULL || out == NULL) return SC_ERROR_INTERNAL; - priv = (myeid_private_data_t*) card->drv_data; + LOG_FUNC_CALLED(card->ctx); + + priv = (myeid_private_data_t*)card->drv_data; if (priv->sec_env && priv->sec_env->algorithm == SC_ALGORITHM_EC && priv->sec_env->operation == SC_SEC_OPERATION_DERIVE From 3ad3d13730f6d72917c4f1d6fee9ae95fe9c2584 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:48:07 +0200 Subject: [PATCH 4217/4321] entersafe: Fis possible NULL pointer dereference by moving the check before dereferencing the pointer CID 503463 --- src/libopensc/card-entersafe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index da888500fd..59f5cf4225 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -201,11 +201,11 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 iv[8] = {0}; int len; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card == NULL || apdu == NULL || key == NULL || buff == NULL) return SC_ERROR_INTERNAL; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* padding as 0x80 0x00 0x00...... */ memset(buff, 0, buffsize); buff[0] = apdu->lc; From b14ea2f85b8bd421357293a7387b53490850aa16 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:57:28 +0200 Subject: [PATCH 4218/4321] cardos: Avoid NULL dereference by moving the check before using the pointer CID 503464 --- src/libopensc/card-cardos.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 2b94b3c86b..7236444a92 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -922,7 +922,7 @@ cardos_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { - cardos_data_t* priv = (cardos_data_t*)card->drv_data; + cardos_data_t *priv; sc_apdu_t apdu; u8 data[9]; int key_id, r; @@ -930,6 +930,8 @@ cardos_set_security_env(sc_card_t *card, if (card == NULL || env == NULL) return SC_ERROR_INTERNAL; + priv = (cardos_data_t*)card->drv_data; + if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { sc_log(card->ctx, "No or invalid key reference\n"); return SC_ERROR_INVALID_ARGUMENTS; From 3a5b551fc2f76e6330a0998249b781fa1ddb3115 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 19:58:24 +0200 Subject: [PATCH 4219/4321] belpic: Avoid NULL dereference by moving the ckeck before using the pointer CID 503465, CID 503466 --- src/libopensc/card-belpic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 50d9c8f0da..51aa49cf6d 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -352,11 +352,12 @@ static int belpic_set_security_env(sc_card_t *card, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; + if (card == NULL || env == NULL) + return SC_ERROR_INTERNAL; + sc_log(card->ctx, "belpic_set_security_env(), keyRef = 0x%0x, algo = 0x%0lx\n", *env->key_ref, env->algorithm_flags); - if (card == NULL || env == NULL) - return SC_ERROR_INTERNAL; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); switch (env->operation) { case SC_SEC_OPERATION_SIGN: From 5919be38397d22dd4ee4748ee95d40bfe9c9680e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:00:06 +0200 Subject: [PATCH 4220/4321] entersafe: Avoid NULL dereference by moving the check before using the pointer CID 503467 --- src/libopensc/card-entersafe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 59f5cf4225..c0444a61da 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -272,11 +272,11 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *alg = NULL; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card == NULL || apdu == NULL || key == NULL || buff == NULL) return SC_ERROR_INTERNAL; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (apdu->cse != SC_APDU_CASE_3_SHORT) return SC_ERROR_INTERNAL; if (keylen != 8 && keylen != 16) From 607aa2a1ab1827bd22b8d40f029302a4a46f58cb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:01:20 +0200 Subject: [PATCH 4221/4321] coolkey: Avoid NULL deference by moving the check after using the pointer CID 503468 --- src/libopensc/card-coolkey.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 9539d6f9f4..c0d94fb6e0 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1913,7 +1913,7 @@ static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil { int r; struct sc_file *file = NULL; - coolkey_private_data_t * priv = COOLKEY_DATA(card); + coolkey_private_data_t *priv; unsigned long object_id; if (card == NULL || in_path == NULL) @@ -1921,6 +1921,8 @@ static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + priv = COOLKEY_DATA(card); + if (in_path->len != 4) { return SC_ERROR_OBJECT_NOT_FOUND; } From 679a9873fc426299c4cb23fc2160c99c6e6c558a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:02:11 +0200 Subject: [PATCH 4222/4321] entersafe: Avoid NULL dereference by moving the check before using the pointer CID 503469 --- src/libopensc/card-entersafe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index c0444a61da..9a363e3311 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -728,11 +728,11 @@ static int entersafe_internal_set_security_env(sc_card_t *card, u8 *p = sbuf; int r; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card == NULL || env == NULL) return SC_ERROR_INTERNAL; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: case SC_SEC_OPERATION_SIGN: From 554beb4b6d9864a35b2ddd9d6ab5854a97e26085 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:03:29 +0200 Subject: [PATCH 4223/4321] rtecp: Avoid memory leak on error CID 503470 --- src/pkcs15init/pkcs15-rtecp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index e4946565a6..72b893d3a8 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -63,8 +63,10 @@ static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name if (!file) return SC_ERROR_INTERNAL; path = file->path; - if (path.len <= 2) + if (path.len <= 2) { + sc_file_free(file); return SC_ERROR_INTERNAL; + } if (path.len > 2) path.len -= 2; r = sc_select_file(card, &path, NULL); From a6a311a1df4d7dfb23035c99fb1f6b61db976de2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:05:05 +0200 Subject: [PATCH 4224/4321] cac: Avoid NULL dereference by moving the NULL check before the pointer usage CID 503471 --- src/libopensc/card-cac.c | 4 +++- src/libopensc/card-cac1.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index cde94587fd..cd80eb46c7 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1054,10 +1054,12 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc int r, pathtype; size_t pathlen; struct sc_file *file = NULL; - cac_private_data_t * priv = CAC_DATA(card); + cac_private_data_t *priv; if (card == NULL || in_path == NULL) return SC_ERROR_INTERNAL; + + priv = CAC_DATA(card); ctx = card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 156d61d013..bca08ca3a2 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -209,11 +209,13 @@ static int cac_select_file_by_type(sc_card_t *card, const sc_path_t *in_path, sc int r, pathtype; size_t pathlen; struct sc_file *file = NULL; - cac_private_data_t * priv = CAC_DATA(card); + cac_private_data_t *priv; if (card == NULL || in_path == NULL) return SC_ERROR_INTERNAL; + ctx = card->ctx; + priv = CAC_DATA(card); SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); From 7e0c63c0bad28aafae67117cb895e5249a3abb1c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:07:00 +0200 Subject: [PATCH 4225/4321] rtecp: Remove dead code CID 503472 --- src/pkcs15init/pkcs15-rtecp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 72b893d3a8..651e1d878d 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -505,8 +505,6 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, key_len, NULL); - if (!buf) - return SC_ERROR_INTERNAL; sc_mem_clear(buf, key_len); /* store public key */ if (key->algorithm == SC_ALGORITHM_RSA) @@ -549,8 +547,6 @@ static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_log(card->ctx, "%s\n", "Store public key failed"); } end: - if (!buf) - return SC_ERROR_INTERNAL; free(buf); LOG_FUNC_RETURN(card->ctx, r); } From e7fbecbe5ec261d39fb35eaf76ef05cfde4f8061 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:11:21 +0200 Subject: [PATCH 4226/4321] openpgp: Avoid invalid integer handling Fixes-up a807d69706ee6d88f7e57f4b455e5631f331d5a1, which made the set_taglength_tlv() return negative value, which was not expected by the caller. CID 503473 --- src/libopensc/card-openpgp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index ce317810a6..645d3c3cfa 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3570,8 +3570,6 @@ set_taglength_tlv(u8 *buffer, unsigned int tag, size_t length) { u8 *p = buffer; - if (tag > 0xffff) - return SC_ERROR_INTERNAL; if (tag > 0xff) *p++ = (tag >> 8) & 0xFF; *p++ = tag; @@ -3726,6 +3724,9 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store for (i = 0; i < comp_to_add; i++) { sc_log(ctx, "Set Tag+Length for %s (%X).", componentnames[i], componenttags[i]); + if (componenttags[i] > 0xffff) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); + } len = set_taglength_tlv(p, componenttags[i], componentlens[i]); tpl_len += len; From 7e0a2c0f40f1f00084738077e4942deb917bea58 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:12:52 +0200 Subject: [PATCH 4227/4321] entersafe: Fix NULL dereference by moving the check before pointer use CID 503474 --- src/libopensc/card-entersafe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 9a363e3311..0fefdab686 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -374,11 +374,11 @@ static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *sbuf = NULL; size_t ssize = 0; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card == NULL || apdu == NULL) return SC_ERROR_INTERNAL; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if ((cipher || mac) && (!key || (keylen != 8 && keylen != 16))) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); From bb62549a7d8de7b51bdcf6c63e3ac70df48f62dd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:13:38 +0200 Subject: [PATCH 4228/4321] oberthur: Fix NULL dereference CID 503475 --- src/libopensc/card-oberthur.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 754d17afde..4976e6c72c 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -448,10 +448,11 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, size_t offs, ii; int rv; - LOG_FUNC_CALLED(card->ctx); if (card == NULL || in_path == NULL) return SC_ERROR_INTERNAL; + LOG_FUNC_CALLED(card->ctx); + memcpy(&path, in_path, sizeof(struct sc_path)); if (!auth_current_df) From cf1c82bdc0ecfc0bcc12d22e2aa69bdff8d8ef77 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:14:42 +0200 Subject: [PATCH 4229/4321] rtecp: Remove dead code the variable was already checked for NULL before CID 503476 --- src/pkcs15init/pkcs15-rtecp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 651e1d878d..dc013613ae 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -618,8 +618,6 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, r = sc_card_ctl(p15card->card, SC_CARDCTL_RTECP_GENERATE_KEY, &data); if (r == SC_SUCCESS) { - if (!pubkey) - return SC_ERROR_INTERNAL; pubkey->algorithm = data.type; switch (data.type) { From 5c6f4b831ab29a9d754d7f8a65d4dc2d4d4d742c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 24 Apr 2026 20:18:44 +0200 Subject: [PATCH 4230/4321] piv: Fix Off-by-one comparison Introduced in previous commit rewriting asserts (a807d69706ee6d88f7e57f4b455e5631f331d5a1) CID 503477 --- src/libopensc/card-piv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 5ad14d76ef..df79c6473e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3124,7 +3124,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (enumtag < 0 || enumtag > PIV_OBJ_LAST_ENUM) + if (enumtag < 0 || enumtag >= PIV_OBJ_LAST_ENUM) return SC_ERROR_INTERNAL; sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name); From 7de20377ef5a51d7f97725294a3a68f8fdeb2d6c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 15 Apr 2026 14:19:58 +0200 Subject: [PATCH 4231/4321] pkcs11: enable C_WaitForSlotEvent for all platforms --- configure.ac | 7 ------- src/pkcs11/pkcs11-global.c | 5 ----- 2 files changed, 12 deletions(-) diff --git a/configure.ac b/configure.ac index 85b761ab14..495271cf0c 100644 --- a/configure.ac +++ b/configure.ac @@ -884,13 +884,6 @@ fi if test "${enable_pcsc}" = "yes"; then if test "${WIN32}" != "yes"; then - PKG_CHECK_EXISTS( - [libpcsclite], - [PKG_CHECK_MODULES([PCSC], [libpcsclite >= 1.8.22], - [AC_DEFINE([PCSCLITE_GOOD], [1], [Sufficient version of PCSC-Lite with all the required features])], - [:] - )] - ) if test -z "${PCSC_CFLAGS}"; then case "${host}" in *-*-darwin*) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index d274462d40..cc9313008c 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -805,11 +805,6 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */ return CKR_ARGUMENTS_BAD; sc_log(context, "C_WaitForSlotEvent(block=%d)", !(flags & CKF_DONT_BLOCK)); -#ifndef PCSCLITE_GOOD - /* Not all pcsc-lite versions implement consistently used functions as they are */ - if (!(flags & CKF_DONT_BLOCK)) - return CKR_FUNCTION_NOT_SUPPORTED; -#endif /* PCSCLITE_GOOD */ rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; From 549f2479c8137328011e99835513384904b0042d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 29 Apr 2026 16:21:59 -0400 Subject: [PATCH 4232/4321] Prevent in-place modification of verify data The reverse function previously modified buffers in-place, which unintentionally altered the caller's input data during GOST R 34.10 verification. This updates the function to allocate and return a reversed copy instead. It also simplifies public key parsing by replacing manual byte reversal with OpenSSL BN_lebin2bn, making the code cleaner and preventing input data corruption. Co-authored-by: Gemini Signed-off-by: Simo Sorce --- src/pkcs11/openssl.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 81affb76dd..be70f70dad 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -439,16 +439,23 @@ static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *op) #if !defined(OPENSSL_NO_EC) -static void reverse(unsigned char *buf, size_t len) +static unsigned char * +reverse(const unsigned char *buf, size_t len) { + unsigned char *out = malloc(len); unsigned char tmp; size_t i; + if (out == NULL) + return NULL; + + memcpy(out, buf, len); for (i = 0; i < len / 2; ++i) { - tmp = buf[i]; - buf[i] = buf[len - 1 - i]; - buf[len - 1 - i] = tmp; + tmp = out[i]; + out[i] = out[len - 1 - i]; + out[len - 1 - i] = tmp; } + return out; } static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, @@ -461,7 +468,6 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len EC_POINT *P; BIGNUM *X, *Y; ASN1_OCTET_STRING *octet = NULL; - unsigned char *octet_rev = NULL; char paramset[2] = "A"; int r = -1, ret_vrf = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -515,16 +521,11 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len if (group && pubkey_len <= LONG_MAX) { const unsigned char *p = pubkey; octet = d2i_ASN1_OCTET_STRING(NULL, &p, (long)pubkey_len); - if (octet) - octet_rev = malloc(ASN1_STRING_length(octet)); } - if (group && octet && octet_rev) { - memcpy(octet_rev, ASN1_STRING_get0_data(octet), ASN1_STRING_length(octet)); - reverse(octet_rev, ASN1_STRING_length(octet)); - Y = BN_bin2bn(octet_rev, ASN1_STRING_length(octet) / 2, NULL); - X = BN_bin2bn(octet_rev + ASN1_STRING_length(octet) / 2, ASN1_STRING_length(octet) / 2, NULL); + if (group && octet) { + X = BN_lebin2bn(ASN1_STRING_get0_data(octet), ASN1_STRING_length(octet) / 2, NULL); + Y = BN_lebin2bn(ASN1_STRING_get0_data(octet) + ASN1_STRING_length(octet) / 2, ASN1_STRING_length(octet) / 2, NULL); ASN1_OCTET_STRING_free(octet); - free(octet_rev); P = EC_POINT_new(group); if (P && X && Y) r = EC_POINT_set_affine_coordinates(group, P, X, Y, NULL); @@ -580,11 +581,16 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len EC_POINT_free(P); } if (r == 1) { - r = EVP_PKEY_verify_init(pkey_ctx); - reverse(data, data_len); - if (r == 1) - ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len, - data, data_len); + unsigned char *rev_data = reverse(data, data_len); + if (rev_data == NULL) { + r = -1; + } else { + r = EVP_PKEY_verify_init(pkey_ctx); + if (r == 1) + ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len, + rev_data, data_len); + free(rev_data); + } } } EVP_PKEY_CTX_free(pkey_ctx); From 86c5005b246360f8e0ab1edfac19d568a949bfa1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 29 Apr 2026 16:36:41 -0400 Subject: [PATCH 4233/4321] Replace direct ASN1_STRING field access Update the terminal authentication code to use ASN1_STRING_get0_data and ASN1_STRING_length instead of directly reading the data and length fields. This ensures compatibility with modern OpenSSL versions where these structures are opaque and must be accessed via their official API to prevent compilation errors. Co-authored-by: Gemini Signed-off-by: Simo Sorce --- src/sm/sm-eac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 123f90a36c..9ba3f81cda 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -1186,8 +1186,8 @@ int perform_terminal_authentication(sc_card_t *card, cert = *certs; r = eac_mse_set_dst(card, - cvc_cert->body->certificate_authority_reference->data, - cvc_cert->body->certificate_authority_reference->length); + ASN1_STRING_get0_data(cvc_cert->body->certificate_authority_reference), + ASN1_STRING_length(cvc_cert->body->certificate_authority_reference)); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol properties " "(MSE: Set AT failed)."); @@ -1198,8 +1198,8 @@ int perform_terminal_authentication(sc_card_t *card, if (r < 0) goto err; - chr = cvc_cert->body->certificate_holder_reference->data; - chr_len = cvc_cert->body->certificate_holder_reference->length; + chr = ASN1_STRING_get0_data(cvc_cert->body->certificate_holder_reference); + chr_len = ASN1_STRING_length(cvc_cert->body->certificate_holder_reference); certs++; certs_lens++; From 680d44478b997253e5c7d342a9b980d57768e939 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Apr 2026 03:25:18 +0200 Subject: [PATCH 4234/4321] gids: fixed possible CWE-125 on non-null-terminated GIDS directory strings thanks to Alex Kelchin (@Medoedus) for reporting Fixes https://github.com/OpenSC/OpenSC/security/advisories/GHSA-324p-w2mr-xmrg --- src/libopensc/card-gids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 13c0c192b9..f42bf6b126 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -168,7 +168,7 @@ static int gids_get_identifiers(sc_card_t* card, u8* masterfile, size_t masterfi return SC_ERROR_INTERNAL; for (i = 0; i < recordcount; i++) { - if (strcmp(directory, records[i].directory) == 0 && strcmp(filename, records[i].filename) == 0) { + if (strncmp(directory, records[i].directory, sizeof(records[i].directory)) == 0 && strncmp(filename, records[i].filename, sizeof(records[i].filename)) == 0) { *fileIdentifier = records[i].fileIdentifier; *dataObjectIdentifier = records[i].dataObjectIdentifier; sc_log(card->ctx, From 52ba3c81d1e7ec3c5e2416f3f1976b68bea34a11 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Apr 2026 21:53:11 +0200 Subject: [PATCH 4235/4321] openpgp: fixed possible overflow thanks to Alex Kelchin (@Medoedus) for reporting fixes https://github.com/OpenSC/OpenSC/security/advisories/GHSA-4pf9-2w58-mgxm --- src/libopensc/card-openpgp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 645d3c3cfa..0d1c3e1112 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3730,6 +3730,8 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store len = set_taglength_tlv(p, componenttags[i], componentlens[i]); tpl_len += len; + if (kdata_len + componentlens[i] > sizeof(kdata)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); /* * <-- kdata_len --><-- Copy here --> * kdata |===============|___________________ From 11326df92b823095e2fdebdaadd4b5c110e4c6f3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Apr 2026 22:13:09 +0200 Subject: [PATCH 4236/4321] fixed Off-by-One OOB Write in reader-tr03119.c reported by @qp-x-qp patch from Jakub Jelen (@Jakuje) fixes https://github.com/OpenSC/OpenSC/security/advisories/GHSA-g7xr-h79f-h7pq --- src/libopensc/reader-tr03119.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index af363578cb..178e546264 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -928,10 +928,11 @@ int escape_pace_capabilities_to_buf(sc_context_t *ctx, return sc_asn1_encode(ctx, PACECapabilities, asn1, asn1_len); } +#define MAX_RESPLEN 0xFF void sc_detect_escape_cmds(sc_reader_t *reader) { int error = 0; - u8 rbuf[0xff+1]; + u8 rbuf[MAX_RESPLEN + 1]; sc_apdu_t apdu; unsigned long capabilities; @@ -943,8 +944,8 @@ void sc_detect_escape_cmds(sc_reader_t *reader) apdu.p1 = escape_p1_PIN; apdu.p2 = escape_p2_GetReaderPACECapabilities; apdu.resp = rbuf; - apdu.resplen = sizeof rbuf; - apdu.le = sizeof rbuf; + apdu.resplen = MAX_RESPLEN; + apdu.le = MAX_RESPLEN; if (reader->ops->transmit(reader, &apdu) == SC_SUCCESS && apdu.sw1 == 0x90 && apdu.sw2 == 0x00 @@ -975,7 +976,7 @@ void sc_detect_escape_cmds(sc_reader_t *reader) apdu.p1 = escape_p1_IFD; apdu.p2 = escape_p2_vendor; - apdu.resplen = sizeof rbuf; + apdu.resplen = MAX_RESPLEN; if (reader->ops->transmit(reader, &apdu) == SC_SUCCESS && apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { if (!reader->vendor) { @@ -989,7 +990,7 @@ void sc_detect_escape_cmds(sc_reader_t *reader) apdu.p1 = escape_p1_IFD; apdu.p2 = escape_p2_version_firmware; - apdu.resplen = sizeof rbuf; + apdu.resplen = MAX_RESPLEN; if (reader->ops->transmit(reader, &apdu) == SC_SUCCESS && apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { if (!reader->version_major && !reader->version_minor) { From 5ebb04ded3e8a54a9544a3745b3b5bd566d1e0b2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 10 Apr 2026 00:57:36 +0200 Subject: [PATCH 4237/4321] epass2003/iasecc: fixed possible heap over-reads thanks to Alex Kelchin (@Medoedus) for reporting patch partially from Jakub Jelen (@Jakuje) fixes https://github.com/OpenSC/OpenSC/security/advisories/GHSA-7xf3-32f8-23h9 --- src/libopensc/card-epass2003.c | 31 +++++++++++-------------------- src/libopensc/iasecc-sdo.c | 17 ++++++++++++----- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 2b884049b1..5524c844f7 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1439,8 +1439,9 @@ epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm) static int decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned char *out, size_t * out_len) { + unsigned int cla = 0, tag = 0; + const unsigned char *p = in; size_t cipher_len; - size_t i; unsigned char iv[16] = {0}; unsigned char plaintext[4096] = {0}; epass2003_exdata *exdata = NULL; @@ -1450,33 +1451,23 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned exdata = (epass2003_exdata *)card->drv_data; - /* no cipher */ - if (in[0] == 0x99) - return 0; - - /* parse cipher length */ - if (0x01 == in[2] && 0x82 != in[1]) { - cipher_len = in[1]; - i = 3; - } else if (0x01 == in[3] && 0x81 == in[1]) { - cipher_len = in[2]; - i = 4; - } else if (0x01 == in[4] && 0x82 == in[1]) { - cipher_len = in[2] * 0x100; - cipher_len += in[3]; - i = 5; - } else { + if (SC_SUCCESS != sc_asn1_read_tag(&p, inlen, &cla, &tag, &cipher_len) + || p == NULL) { return -1; } + if ((cla | tag) == 0x99) + return 0; + if ((cla | tag) != 0x87) + return -1; - if (cipher_len < 2 || i + cipher_len > inlen || cipher_len > sizeof plaintext) + if (cipher_len < 2 || cipher_len > sizeof plaintext) return -1; /* decrypt */ if (KEY_TYPE_AES == exdata->smtype) - aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, p, cipher_len - 1, plaintext); else - des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, p, cipher_len - 1, plaintext); /* unpadding */ while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2)) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index bb593a3ef1..84e2a448b3 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -1263,7 +1263,7 @@ int iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t data_len, struct iasecc_sm_card_answer *out) { - int have_mac = 0, have_status = 0; + int rc, have_mac = 0, have_status = 0; size_t size = 0, size_size, offs; LOG_FUNC_CALLED(ctx); @@ -1271,8 +1271,15 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); memset(out, 0, sizeof(*out)); - for (offs=0; offs data_len) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + } if (*(data + offs) == IASECC_CARD_ANSWER_TAG_DATA ) { if (size > sizeof(out->data)) @@ -1283,7 +1290,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t offs += 1 + size_size + size; } else if (*(data + offs) == IASECC_CARD_ANSWER_TAG_SW ) { - if (*(data + offs + 1) != 2) + if (size_size != 1 || size != 2) LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "iasecc_sm_decode_answer() SW length not 2"); out->sw = *(data + offs + 2) * 0x100 + *(data + offs + 3); @@ -1293,7 +1300,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t have_status = 1; } else if (*(data + offs) == IASECC_CARD_ANSWER_TAG_MAC ) { - if (*(data + offs + 1) != 8) + if (size_size != 1 || size != 8) LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "iasecc_sm_decode_answer() MAC length not 8"); memcpy(out->mac, data + offs + 2, 8); From 0254d273784b62fa48cba5e52af1ebcf8db7b7ee Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 11 Apr 2026 00:43:23 +0200 Subject: [PATCH 4238/4321] fixed possible Null-dereference READ Fixes https://issues.oss-fuzz.com/issues/501179374 --- src/libopensc/pkcs15-pubkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e9539dbe9d..2995a7c93f 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -991,7 +991,7 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj LOG_TEST_GOTO_ERR(ctx, r, "Failed to read public key file."); if ((algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA) - && *data == (SC_ASN1_TAG_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED)) + && len > 0 && *data == (SC_ASN1_TAG_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED)) r = sc_pkcs15_pubkey_from_spki_sequence(ctx, data, len, &pubkey); else r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len); From 6852460211aab8a074af68d4e4e89ef1f5c554d3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 11 Apr 2026 15:04:17 +0200 Subject: [PATCH 4239/4321] fixed formatting --- src/libopensc/card-epass2003.c | 3 +-- src/libopensc/iasecc-sdo.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 5524c844f7..d2e172e3e3 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1451,8 +1451,7 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned exdata = (epass2003_exdata *)card->drv_data; - if (SC_SUCCESS != sc_asn1_read_tag(&p, inlen, &cla, &tag, &cipher_len) - || p == NULL) { + if (SC_SUCCESS != sc_asn1_read_tag(&p, inlen, &cla, &tag, &cipher_len) || p == NULL) { return -1; } if ((cla | tag) == 0x99) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 84e2a448b3..c839c2d3d2 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -1271,7 +1271,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); memset(out, 0, sizeof(*out)); - for (offs = 0; offs + 1 < data_len; ) { + for (offs = 0; offs + 1 < data_len;) { rc = iasecc_parse_size(data + offs + 1, data_len - offs - 1, &size); if (rc <= 0) { LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); From a7586e080720f946a6bdb31d2d4641a4a9493a6f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Wed, 29 Apr 2026 12:03:57 +0300 Subject: [PATCH 4240/4321] Add new paths to pkcs11-register https://bugzilla.mozilla.org/show_bug.cgi?id=259356 https://issues.chromium.org/issues/40666379 https://issues.chromium.org/issues/41424903 Signed-off-by: Raul Metsma --- src/tools/pkcs11-register.c | 16 ++++++++++++++-- src/tools/pkcs11-register.desktop.in | 2 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index 02ecb6b109..20a86213e6 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -230,8 +230,10 @@ add_module_firefox(const char *module_path, const char *module_name, const char #elif defined(_WIN32) {"APPDATA", "Mozilla\\Firefox"}, #else - {"HOME", ".mozilla/firefox"}, - {"HOME", ".mozilla/firefox-esr"}, + {"XDG_CONFIG_HOME", "mozilla/firefox"}, /* Firefox >= 147 XDG profile */ + {"HOME", ".config/mozilla/firefox"}, /* XDG default when XDG_CONFIG_HOME unset */ + {"HOME", ".mozilla/firefox"}, + {"HOME", ".mozilla/firefox-esr"}, #endif }; @@ -294,6 +296,16 @@ add_module_chrome(const char *module_path, const char *module_name, const char * "%s%c%s", home, path_sep, ".pki/nssdb")) { add_module_pkcs11_txt(profile_path, module_path, module_name, exclude_module_path); } + + /* Chrome M146+ uses XDG_DATA_HOME/pki/nssdb when ~/.pki doesn't exist */ + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home && 0 <= snprintf(profile_path, sizeof profile_path, + "%s%c%s", xdg_data_home, path_sep, "pki/nssdb")) { + add_module_pkcs11_txt(profile_path, module_path, module_name, exclude_module_path); + } else if (home && 0 <= snprintf(profile_path, sizeof profile_path, + "%s%c%s", home, path_sep, ".local/share/pki/nssdb")) { + add_module_pkcs11_txt(profile_path, module_path, module_name, exclude_module_path); + } #endif } diff --git a/src/tools/pkcs11-register.desktop.in b/src/tools/pkcs11-register.desktop.in index 0f350d33ef..3a2e55907d 100644 --- a/src/tools/pkcs11-register.desktop.in +++ b/src/tools/pkcs11-register.desktop.in @@ -3,6 +3,4 @@ Name=Install OpenSC PKCS#11 module Type=Application Exec=@bindir@/pkcs11-register --skip-chrome=off --skip-firefox=off Categories=Security;System; -X-GNOME-AutoRestart=true -X-GNOME-Autostart-Phase=Initialization NoDisplay=true From afbc8632eae65bfd912293b5c7075e40ca9588f5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 11 May 2026 08:57:21 +0200 Subject: [PATCH 4241/4321] pkcs15-tool: prevent buffer overflow on RSA key parsing Attribution This vulnerability was discovered by Claude, Anthropic's AI assistant, with OSS-Fuzz fuzzing and triaged by Ada Logics manually in collaboration with Anthropic Research. reborted by @arthurscchan Arthur Chan --- src/tools/pkcs15-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index c48175db98..01b368c8d3 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1132,7 +1132,7 @@ static int read_ssh_key(void) len = sprintf((char *) buf+4,"ssh-rsa"); len+=4; - if (sizeof(buf)-len < 4+pubkey->u.rsa.exponent.len) + if (sizeof(buf)-len < 5+pubkey->u.rsa.exponent.len) goto fail; n = pubkey->u.rsa.exponent.len; From 123f11eb34cf90d027d97228b8c57bee84b7e85d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 May 2026 10:46:19 +0200 Subject: [PATCH 4242/4321] oberthur: Avoid memory leak while writing public keys Thanks oss-fuzz https://issues.oss-fuzz.com/issues/510130167 Signed-off-by: Jakub Jelen --- src/libopensc/card-oberthur.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 4976e6c72c..c36580094e 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2050,7 +2050,11 @@ write_publickey (struct sc_card *card, unsigned int offset, args.data = key.modulus.data; args.len = key.modulus.len; rv = auth_update_component(card, &args); - LOG_TEST_RET(card->ctx, rv, "Update component failed"); + free(args.data); + if (rv != SC_SUCCESS) { + free(key.exponent.data); + LOG_TEST_RET(card->ctx, rv, "Update component failed"); + } memset(&args, 0, sizeof(args)); args.type = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; @@ -2058,6 +2062,7 @@ write_publickey (struct sc_card *card, unsigned int offset, args.data = key.exponent.data; args.len = key.exponent.len; rv = auth_update_component(card, &args); + free(args.data); LOG_TEST_RET(card->ctx, rv, "Update component failed"); LOG_FUNC_RETURN(card->ctx, (int)len); From 3f3d484c4508d4265d0519fbe5a85b30c1469497 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 May 2026 11:05:36 +0200 Subject: [PATCH 4243/4321] ci: Fix 32b Fedora build --- .github/setup-fedora.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index 6349b1fc03..0c97dafc4a 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -13,7 +13,7 @@ fi # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then - DEPS="$DEPS pcsc-lite-devel*.i686 readline-devel*.i686 openssl-devel*.i686 zlib-ng-devel*.i686 libcmocka-devel*.i686 glibc-devel*i686" + DEPS="$DEPS pcsc-lite-devel*.i686 readline-devel*.i686 openssl-devel*.i686 zlib-ng-devel*.i686 libcmocka-devel*.i686 glibc-devel*i686 libgcc.i686 libatomic.i686" else DEPS="$DEPS pcsc-lite-devel readline-devel openssl-devel zlib-ng-devel libcmocka-devel" fi From 814f745b3b6d100295f65f1935edd33d520d33ab Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 11 May 2026 11:00:28 +0200 Subject: [PATCH 4244/4321] pkcs11-tool: prevent buffer overflow Reported by @HMF2021 hippofu999 --- src/tools/pkcs11-tool.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index cfc7486faa..9de15c1869 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1342,6 +1342,8 @@ int main(int argc, char * argv[]) } if (opt_uri->id) { opt_object_id_len = opt_uri->id_len; + if (opt_object_id_len > sizeof(opt_object_id)) + util_fatal("URI's object ID too long"); memcpy(opt_object_id, opt_uri->id, opt_object_id_len); } } @@ -9608,6 +9610,10 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE return session; } opt_object_id_len = (size_t) i; + if (opt_object_id_len > sizeof(opt_object_id)) { + fprintf(stderr, "ERR: object ID too long\n"); + return session; + } memcpy(opt_object_id, tmp, opt_object_id_len); /* This is done in NSS */ From 2a31d3c0f21e590909d630d46647e8eb92f53daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Sun, 10 May 2026 06:15:48 +0300 Subject: [PATCH 4245/4321] pkcs15: mark AlgorithmInfo parameters CHOICE as optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PKCS#15 v1.1 AlgorithmInfo.parameters field is an Information Object Class (IOC) field whose presence depends on whether the referenced algorithm's class object defines &Parameters. AES algorithms are not part of the PKCS#15 v1.1 AlgorithmSet; cards encode them using NIST OIDs (2.16.840.1.101.3.4.1.*) as a de-facto extension, and no &Parameters is defined for those OIDs, so the field is correctly absent from AES entries. Mark the parameters CHOICE as SC_ASN1_OPTIONAL so that cards whose EF(TokenInfo) contains only AES AlgorithmInfo entries do not fail with "Required ASN.1 object not found" during PKCS#15 binding. Add a clang-format guard around c_asn1_algorithm_info to preserve its tab-column layout, consistent with similar guards elsewhere in the tree. Signed-off-by: Vesa Jääskeläinen --- src/libopensc/pkcs15.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index c1edaed7ff..2dc91843df 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -53,15 +53,17 @@ static const struct sc_asn1_entry c_asn1_twlabel[] = { { NULL, 0, 0, 0, NULL, NULL } }; +// clang-format off static const struct sc_asn1_entry c_asn1_algorithm_info[7] = { - { "reference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { "algorithmPKCS#11", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, - { "parameters", SC_ASN1_CHOICE, 0, 0, NULL, NULL }, - { "supportedOperations",SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, + { "reference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "algorithmPKCS#11", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "parameters", SC_ASN1_CHOICE, 0, SC_ASN1_OPTIONAL, NULL, NULL }, + { "supportedOperations",SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, { "objId", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL }, { "algRef", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; +// clang-format on static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = { { "PKCS15RSAParameters",SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, From 0d967c303f0f0b3c11d89ccb7126b82294bee616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Sun, 10 May 2026 06:15:58 +0300 Subject: [PATCH 4246/4321] asn1: honour SC_ASN1_OPTIONAL for CHOICE entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit asn1_decode() has a fast path for SC_ASN1_CHOICE entries (which carry no tag of their own) that returns the inner decoder's error directly, without ever inspecting the entry's SC_ASN1_OPTIONAL flag. The general optional-skip logic that follows the fast path is therefore never reached for CHOICE entries. When the inner call fails it returns before writing back to *newp and *len_left, so the caller's p/left are unchanged. Swallowing the error for an optional CHOICE is therefore safe: the next field will be attempted at the same position. Signed-off-by: Vesa Jääskeläinen --- src/libopensc/asn1.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 71b9cb0c94..033aa898dc 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1758,7 +1758,12 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, r = asn1_decode(ctx, (struct sc_asn1_entry *) entry->parm, p, left, &p, &left, 1, depth + 1); - if (r >= 0) + /* When the inner call fails it returns before writing + * back to *newp and *len_left, so the caller's p/left are + * unchanged. Swallowing the error for an optional + * CHOICE is therefore safe: the next field will be + * attempted at the same position. */ + if (r >= 0 || (entry->flags & SC_ASN1_OPTIONAL)) r = 0; goto decode_ok; } From e794eddab10b25d014d52dfd199e6730b8685832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?= Date: Sun, 10 May 2026 06:19:24 +0300 Subject: [PATCH 4247/4321] tests/unittests: add tests for optional CHOICE in asn1_decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add five cmocka unit tests covering asn1_decode() behaviour for SC_ASN1_CHOICE entries marked SC_ASN1_OPTIONAL: - torture_asn1_decode_optional_choice_absent: optional CHOICE absent from the byte stream -> SC_SUCCESS, surrounding fields decoded - torture_asn1_decode_optional_choice_present: optional CHOICE present -> SC_SUCCESS, alternative consumed normally - torture_asn1_decode_mandatory_choice_absent: mandatory CHOICE absent -> SC_ERROR_ASN1_OBJECT_NOT_FOUND - torture_asn1_decode_optional_choice_malformed: tag matches a CHOICE alternative but content is malformed; a real storage pointer is needed so content is actually validated -> error swallowed by the optional CHOICE with position unchanged, next mandatory field fails - torture_asn1_decode_optional_choice_end_of_stream: optional CHOICE at end of stream -> SC_SUCCESS Add clang-format guards around the struct array initializers and the main() test registration block to preserve tab-column layout. Signed-off-by: Vesa Jääskeläinen --- src/tests/unittests/asn1.c | 202 +++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/src/tests/unittests/asn1.c b/src/tests/unittests/asn1.c index 1196f3d61e..dc8dccd4e0 100644 --- a/src/tests/unittests/asn1.c +++ b/src/tests/unittests/asn1.c @@ -599,9 +599,199 @@ static void torture_asn1_encode_simple(void **state) free(outptr); } +/* + * Tests for SC_ASN1_OPTIONAL on SC_ASN1_CHOICE entries. + * + * Schema used in the first four tests (outer has three entries): + * before INTEGER mandatory + * choice CHOICE(NULL|OID) optional in tests 1,2,4; mandatory in test 3 + * after INTEGER mandatory + * + * The end-of-stream test (test 5) omits the "after" field. + */ +static void +torture_asn1_decode_optional_choice_absent(void **state) +{ + sc_context_t *ctx = *state; + // clang-format off + struct sc_asn1_entry choice_alts[3] = { + { "null_alt", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "object_alt", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry outer[4] = { + { "before", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "choice", SC_ASN1_CHOICE, 0, SC_ASN1_OPTIONAL, NULL, NULL }, + { "after", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + // clang-format on + /* INTEGER(1), no CHOICE tag, INTEGER(2) */ + const u8 data[] = {0x02, 0x01, 0x01, 0x02, 0x01, 0x02}; + int before = 0, after = 0; + int rv; + + sc_format_asn1_entry(&outer[0], &before, NULL, 0); + sc_format_asn1_entry(&outer[1], choice_alts, NULL, 0); + sc_format_asn1_entry(&outer[2], &after, NULL, 0); + + rv = sc_asn1_decode(ctx, outer, data, sizeof(data), NULL, NULL); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(before, 1); + assert_int_equal(after, 2); + assert_false(choice_alts[0].flags & SC_ASN1_PRESENT); + assert_false(choice_alts[1].flags & SC_ASN1_PRESENT); +} + +static void +torture_asn1_decode_optional_choice_present(void **state) +{ + sc_context_t *ctx = *state; + struct sc_object_id oid_val; + // clang-format off + struct sc_asn1_entry choice_alts[3] = { + { "null_alt", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "object_alt", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry outer[4] = { + { "before", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "choice", SC_ASN1_CHOICE, 0, SC_ASN1_OPTIONAL, NULL, NULL }, + { "after", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + // clang-format on + /* INTEGER(1), OID {1.2} (0x06 0x01 0x2a — matches second CHOICE alternative), INTEGER(2) */ + const u8 data[] = {0x02, 0x01, 0x01, 0x06, 0x01, 0x2a, 0x02, 0x01, 0x02}; + int before = 0, after = 0; + int rv; + + sc_format_asn1_entry(&choice_alts[1], &oid_val, NULL, 0); + sc_format_asn1_entry(&outer[0], &before, NULL, 0); + sc_format_asn1_entry(&outer[1], choice_alts, NULL, 0); + sc_format_asn1_entry(&outer[2], &after, NULL, 0); + + rv = sc_asn1_decode(ctx, outer, data, sizeof(data), NULL, NULL); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(before, 1); + assert_int_equal(after, 2); + assert_false(choice_alts[0].flags & SC_ASN1_PRESENT); + assert_true(choice_alts[1].flags & SC_ASN1_PRESENT); + assert_int_equal(oid_val.value[0], 1); + assert_int_equal(oid_val.value[1], 2); +} + +static void +torture_asn1_decode_mandatory_choice_absent(void **state) +{ + sc_context_t *ctx = *state; + // clang-format off + struct sc_asn1_entry choice_alts[3] = { + { "null_alt", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "object_alt", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry outer[4] = { + { "before", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "choice", SC_ASN1_CHOICE, 0, 0, NULL, NULL }, /* NOT optional */ + { "after", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + // clang-format on + /* INTEGER(1), no CHOICE tag, INTEGER(2) — CHOICE is mandatory so this must fail */ + const u8 data[] = {0x02, 0x01, 0x01, 0x02, 0x01, 0x02}; + int before = 0, after = 0; + int rv; + + sc_format_asn1_entry(&outer[0], &before, NULL, 0); + sc_format_asn1_entry(&outer[1], choice_alts, NULL, 0); + sc_format_asn1_entry(&outer[2], &after, NULL, 0); + + rv = sc_asn1_decode(ctx, outer, data, sizeof(data), NULL, NULL); + assert_int_equal(rv, SC_ERROR_ASN1_OBJECT_NOT_FOUND); + assert_int_equal(before, 1); + assert_int_equal(after, 0); + assert_false(choice_alts[0].flags & SC_ASN1_PRESENT); + assert_false(choice_alts[1].flags & SC_ASN1_PRESENT); +} + +static void +torture_asn1_decode_optional_choice_malformed(void **state) +{ + sc_context_t *ctx = *state; + struct sc_object_id oid_val; + // clang-format off + struct sc_asn1_entry choice_alts[3] = { + { "null_alt", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "object_alt", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry outer[4] = { + { "before", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "choice", SC_ASN1_CHOICE, 0, SC_ASN1_OPTIONAL, NULL, NULL }, + { "after", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + // clang-format on + /* INTEGER(1), OID tag with malformed content (0x81 has the multi-byte continuation + * bit set but no following byte), INTEGER(2). A real storage pointer is required on + * the OID alternative: with parm=NULL asn1_decode_entry skips content validation and + * the TLV is silently consumed. With parm set, sc_asn1_decode_object_id returns an + * error; the inner decoder exits before writing back p/left, so the optional CHOICE + * swallows the error and the position is unchanged. "after" then sees 0x06 (OID tag) + * where INTEGER (0x02) was expected → SC_ERROR_ASN1_OBJECT_NOT_FOUND. */ + const u8 data[] = {0x02, 0x01, 0x01, 0x06, 0x01, 0x81, 0x02, 0x01, 0x02}; + int before = 0, after = 0; + int rv; + + sc_format_asn1_entry(&choice_alts[1], &oid_val, NULL, 0); + sc_format_asn1_entry(&outer[0], &before, NULL, 0); + sc_format_asn1_entry(&outer[1], choice_alts, NULL, 0); + sc_format_asn1_entry(&outer[2], &after, NULL, 0); + + rv = sc_asn1_decode(ctx, outer, data, sizeof(data), NULL, NULL); + assert_int_equal(rv, SC_ERROR_ASN1_OBJECT_NOT_FOUND); + assert_int_equal(before, 1); + assert_int_equal(after, 0); + assert_false(choice_alts[0].flags & SC_ASN1_PRESENT); + assert_false(choice_alts[1].flags & SC_ASN1_PRESENT); +} + +static void +torture_asn1_decode_optional_choice_end_of_stream(void **state) +{ + sc_context_t *ctx = *state; + // clang-format off + struct sc_asn1_entry choice_alts[3] = { + { "null_alt", SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL }, + { "object_alt", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry outer[3] = { + { "before", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "choice", SC_ASN1_CHOICE, 0, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + // clang-format on + /* INTEGER(1) only — stream ends before the optional CHOICE */ + const u8 data[] = {0x02, 0x01, 0x01}; + int before = 0; + int rv; + + sc_format_asn1_entry(&outer[0], &before, NULL, 0); + sc_format_asn1_entry(&outer[1], choice_alts, NULL, 0); + + rv = sc_asn1_decode(ctx, outer, data, sizeof(data), NULL, NULL); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(before, 1); + assert_false(choice_alts[0].flags & SC_ASN1_PRESENT); + assert_false(choice_alts[1].flags & SC_ASN1_PRESENT); +} + int main(void) { int rc; + // clang-format off struct CMUnitTest tests[] = { /* INTEGER */ cmocka_unit_test(torture_asn1_integer_zero), @@ -669,7 +859,19 @@ int main(void) /* encode() */ cmocka_unit_test_setup_teardown(torture_asn1_encode_simple, setup_sc_context, teardown_sc_context), + /* decode(): optional CHOICE */ + cmocka_unit_test_setup_teardown(torture_asn1_decode_optional_choice_absent, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_asn1_decode_optional_choice_present, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_asn1_decode_mandatory_choice_absent, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_asn1_decode_optional_choice_malformed, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_asn1_decode_optional_choice_end_of_stream, + setup_sc_context, teardown_sc_context), }; + // clang-format on rc = cmocka_run_group_tests(tests, NULL, NULL); return rc; From 04d9b35619625f8460447f2e47b12c4a00478c9e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 3 May 2026 03:25:00 +0200 Subject: [PATCH 4248/4321] oberthur-awp: fixed possible out of bounds write on card initialization --- src/pkcs15init/pkcs15-oberthur-awp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index fdb06ab6b4..ced9eb9765 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -724,12 +724,17 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil if (rv < 0) goto done; + if (lst_file->size < 5) { + rv = SC_ERROR_UNKNOWN_DATA_RECEIVED; + goto done; + } + flags = lst_file->ef_structure; rv = sc_read_binary(p15card->card, 0, buff, lst_file->size, &flags); if (rv < 0) goto done; - for (ii=0; ii < lst_file->size; ii+=5) + for (ii=0; ii <= lst_file->size-5; ii+=5) if (*(buff + ii) != COSM_LIST_TAG) break; if (ii>=lst_file->size) { From 7aa03ca79db627b508766e04ce94ec8c4acc9cb7 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 3 May 2026 13:18:54 -0500 Subject: [PATCH 4249/4321] .clang-format - Do not change *.json files The '.json' files used in testing scripts all have a frist line: of a single "{" charactor. With no Language chosen the default rules designed for '.c' files and the clang-format would indent following lines with a tab. This would then cause a diff statements in the test scripts to fail. Changes to be committed: modified: .clang-format --- .clang-format | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.clang-format b/.clang-format index a07d98b0ad..4d2bb184e7 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,4 @@ +--- BasedOnStyle: LLVM # defaults from LLVM # BreakBeforeBraces: Attach @@ -40,3 +41,7 @@ BraceWrapping: AfterObjCDeclaration: true AfterUnion: true AfterFunction: true + +--- +Language: Json +DisableFormat: true From 72cbeac1ee5b7602ec751e59b06da5e6ffecc4c2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 30 Apr 2026 10:24:33 -0500 Subject: [PATCH 4250/4321] test-piv.sh no longer needs opensc-piv.conf opensc-piv.conf is deleted. With the changes to card-piv.c, the PivApplet used in test-piv.sh is correctly identifying the PivApplet by using the response to select AID. Previously the ATR did not have Historical data so it was not possible to identify the applet. test-piv.sh no longer needs a special opensc-piv.conf which was forcing the ATR and the card type. The same ATR was also used by a PIVKey card listed in the known ATRs causing the setting of the wrong algorithims. The select AID response also include "AC" algorithm Identifies which are used to define the 3 types algorithms supported by the applet and NIST: RSA 2048, EC P256 and EC 384 piv_ref.json was updated to match algorithms supported by card. Changes to be committed: deleted: .github/opensc-piv.conf modified: .github/test-piv.sh modified: src/tests/p11test/piv_ref.json --- .github/opensc-piv.conf | 10 ------ .github/test-piv.sh | 6 +--- src/tests/p11test/piv_ref.json | 64 +++++++++++++++++----------------- 3 files changed, 33 insertions(+), 47 deletions(-) delete mode 100644 .github/opensc-piv.conf diff --git a/.github/opensc-piv.conf b/.github/opensc-piv.conf deleted file mode 100644 index 3a9d5e0df9..0000000000 --- a/.github/opensc-piv.conf +++ /dev/null @@ -1,10 +0,0 @@ -# Configuration for virtual PIV card to enforce mapping of ATR to type supporting EC -app default { - framework pkcs15 { - use_file_caching = no; - } - card_atr 3b:80:80:01:01 { - driver = "PIV-II"; - type = "14001"; # SC_CARD_TYPE_PIV_II_GENERIC - } -} diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 2444b5f808..b926f1ecd3 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -46,10 +46,6 @@ java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar co PID=$! sleep 5 -# enforce the setting of different PIV type to support EC mechanisms -# which are disabled for the generic ATR mapping to older Yubico devices -export OPENSC_CONF="${PWD}/.github/opensc-piv.conf" - $VALGRIND opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f $VALGRIND opensc-tool -n @@ -78,6 +74,6 @@ pushd src/tests/p11test/ sleep 5 $VALGRIND ./p11test -v -s 0 -p "$PIN" -o piv.json popd -diff -u3 src/tests/p11test/piv{_ref,}.json +diff -u3 src/tests/p11test/piv{_ref,}.json kill -9 $PID diff --git a/src/tests/p11test/piv_ref.json b/src/tests/p11test/piv_ref.json index de5a615baf..8c57a893a2 100644 --- a/src/tests/p11test/piv_ref.json +++ b/src/tests/p11test/piv_ref.json @@ -112,98 +112,98 @@ ], [ "RSA_X_509", - "1024", - "3072", + "2048", + "2048", "CKF_HW,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY" ], [ "RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_HW,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY" ], [ "SHA1_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA256_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "MD5_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "RIPEMD160_RSA_PKCS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_HW,CKF_SIGN,CKF_VERIFY" ], [ "SHA1_RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA224_RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA256_RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA384_RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "SHA512_RSA_PKCS_PSS", - "1024", - "3072", + "2048", + "2048", "CKF_SIGN,CKF_VERIFY" ], [ "RSA_PKCS_OAEP", - "1024", - "3072", + "2048", + "2048", "CKF_HW,CKF_DECRYPT" ]], "result": "pass" From ccaaf5491400d6531efe3d05b66f856b3d740d30 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 10 Feb 2025 10:20:06 -0600 Subject: [PATCH 4251/4321] card-piv.c - Major PIV card improvements Add support for Nitrokey PIV, Token2 PIV and PivApplet These cards were recognized as standard PIV cards but they each have special features and algorithms. SELECT PIV AID response may contain Algorithm Identifier "AC" entries and Application Label which can now be used to detect supported Algorithms and identify different PIV applet features including cards not seen before. A number of cards are now following the Yubico extension to read the version number from the card. These include Yubikey, NitroKey, Token2 and PivApplet. The Yubico version number has only been read for cards known to be Yubico or "Yubico like" cards in the past. But if an unknown PIV card is found, card-piv.c will attempt to read the Yubico version number. Official NIST demo cards will ignore the request and respond with 6D00. This then allows for using new cards that follow Yubico versions and/or Algorithms. The main use of the Yubico version number was to set the known algorithms as Yubico cards so far have not provided Algorithm Identifiers. The Algorithms supported by a card is a combination of: o In response to SELECT AID in "AC" Algorithm Identifiers. o NIST required algorithms, if no "AC" non SM entries are found. o Yubico versions numbers and whats new in a version. o Minus any algorithms known to not be supported. Since NIST left it up to card vendors on how to provision a card, the list of supported Algorithms is more informational and shown by pkcs11-tool. If a card has a certificate with a public key it should still work. If card type is not specified by the user or by ATR matching of by ATR historical bytes an additional match of the Application Label in the response to Select AID is used. This is an optional field and some but not all card vendors fill in this field. There are 14 PIV type cards in cards.h which can be used to force a card type in opensc.conf if needed for cards we have not seen before. An older PIVKey card with ATR "3b:80:80:01:01" was the same as that used by PivApplet (at least when run from virtual card in .github/test_piv.sh) This was causing misidentification of the PivApplet. The PivApplet can now be identified from Select AID response Application Label which starts with "PivApplet v". It is also a Yubico like card which follows Yubico version numbers. Similarly, Token2 Application Label is "PivApplet" which is different from "PivApplet v". On contactless, do not test for Discovery before AID. NIST standards require the card applet to not allow use of PIN or crypto over contactless unless using NIST Secure Messaging. Some card vendor's ignored this security restriction and treat contact and contactless the same. env: PIV_USE_SM=always will follow the NIST security restriction and on such a card and not attempt to send the PIN. Otherwise It will attempt to send the PIN or crypto in the clear if the card will accept it. The "manually reformat long if statements" and "clang-format" are separate commits to make code review easier as suggested in comments on PR. --- src/libopensc/card-piv.c | 374 +++++++++++++++++++++++++++------------ src/libopensc/cards.h | 3 + 2 files changed, 259 insertions(+), 118 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index df79c6473e..ee569b8c9e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3,7 +3,7 @@ * card-default.c: Support for cards with no driver * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2005-2024 Douglas E. Engert + * Copyright (C) 2005-2026 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner * @@ -63,6 +63,8 @@ #include "cardctl.h" #include "simpletlv.h" +// clang-format off + enum { PIV_OBJ_CCC = 0, PIV_OBJ_CHUI, @@ -213,7 +215,6 @@ enum { char *curve_group; } cipher_suite_t; -// clang-fromat off #define PIV_CSS_SIZE 2 static cipher_suite_t css[PIV_CSS_SIZE] = { {PIV_CS_CS2, 256, NID_X9_62_prime256v1, {{1, 2, 840, 10045, 3, 1, 7, -1}}, @@ -236,7 +237,6 @@ static cipher_suite_t css[PIV_CSS_SIZE] = { "aes-256-cbc", "aes-256-ecb", "secp384r1"} }; -// clang-format on /* 800-73-4 4.1.5 Card Verifiable Certificates */ typedef struct piv_cvc { @@ -375,7 +375,7 @@ static const struct sc_card_error piv_sm_errors[] = { /* init_flags */ #define PIV_INIT_AID_PARSED 0x00000001u -#define PIV_INIT_AID_AC 0x00000002u +#define PIV_INIT_AID_AC_SM 0x00000002u #define PIV_INIT_DISCOVERY_PARSED 0x00000004u #define PIV_INIT_DISCOVERY_PP 0x00000008u #define PIV_INIT_IN_READER_LOCK_OBTAINED 0x00000010u @@ -394,6 +394,9 @@ typedef struct piv_private_data { unsigned long algorithm; /* saved from set_security_env */ int key_ref; /* saved from set_security_env and */ int alg_id; /* used in decrypt, signature, derive */ + unsigned int alg_ids; /* from AID response, NIST required, card version */ + unsigned char * al_label; /* from Select AID Application Label */ + int al_labellen; int key_size; /* RSA: modulus_bits EC: field_length in bits */ u8* w_buf; /* write_binary buffer */ size_t w_buf_len; /* length of w_buff */ @@ -454,6 +457,9 @@ struct piv_aid { */ /* ATRs of cards known to have PIV applet. But must still be tested for a PIV applet */ +/* Yubico, NitroKey, Token2 are identified by ATR historic bytes */ +/* PivApplet does not provide ATR historic bytes */ + static const struct sc_atr_table piv_atrs[] = { /* CAC cards with PIV from: CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc */ /* @@ -520,8 +526,12 @@ static const struct sc_atr_table piv_atrs[] = { { "3b:89:80:01:53:50:49:56:4b:45:59:37:30:44", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, /* PIVKey SLE78 (57B) */ { "3b:fd:96:00:00:81:31:fe:45:53:4c:4a:35:32:47:44:4c:31:32:38:43:52:57", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* This ATR is too generic. It will be accepted if Application Label in AID response matches */ + /* Which looks like there is no Application Label in AID response of these cards */ + /* PivApplet (at least when run in virtual machine) uses the same ATR */ /* PIVKey uTrust (01) ISO 14443 Type B without historical bytes */ - { "3b:80:80:01:01", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, + /* { "3b:80:80:01:01", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, */ + /* PIVKey uTrust (73) */ { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, /* PIVKey uTrust FIDO2 (73) */ @@ -571,11 +581,47 @@ static struct piv_aid piv_aids[] = { #define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */ #define CI_NFC_EXPOSE_TOO_MUCH 0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */ -#define CI_NO_RSA2048 0x00010000U /* does not have RSA 2048 */ -#define CI_NO_EC384 0x00020000U /* does not have EC 384 */ -#define CI_NO_EC 0x00040000U /* No EC at all */ -#define CI_RSA_4096 0x00080000U /* Card supports rsa 4096 */ -#define CI_25519 0x00100000U /* Card supports ED25519 and X25519 */ +#define CI_NO_EC384 0x00000400U /* does not have EC 384 */ +#define CI_NO_EC 0x00000800U /* No EC at all */ + +/* PIV and PIV like cards are know to support these asymmetric algorithm identifiers used in alg_ids */ +#define AI_RSA_1024 0x00000001U +#define AI_RSA_2048 0x00000002U +#define AI_RSA_3072 0x00000004U +#define AI_RSA_4096 0x00000008U +#define AI_EC_256 0x00000100U +#define AI_EC_384 0x00000200U +#define AI_25519 0x00100000U +#define AI_X25519 0x00200000U +/* NIST cards have or do support these (non SM) algorithm identifiers */ +#define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384) + +static struct { + unsigned long ai_flag; + unsigned char ai_id; + unsigned long ai_sc_type; + int ai_bits; +} ai_map[] = { + { AI_RSA_3072, 0x05, SC_ALGORITHM_RSA, 3072 }, + { AI_RSA_1024, 0x06, SC_ALGORITHM_RSA, 1024 }, + { AI_RSA_2048, 0x07, SC_ALGORITHM_RSA, 2048 }, + { AI_RSA_4096, 0x16, SC_ALGORITHM_RSA,4096 }, + { AI_EC_256, 0x11, SC_ALGORITHM_EC, 256 }, + { AI_EC_384, 0x14, SC_ALGORITHM_EC, 384 }, + { AI_25519, 0xE0, SC_ALGORITHM_EDDSA, 255 }, + { AI_X25519, 0xE1, SC_ALGORITHM_XEDDSA, 255 }, + { 0, 0, 0, 0 } + }; + +/* Application Label from select AID response where ATR can not be matched */ +static struct { + int al_type; + unsigned char * al_label; + int al_labellen; +} al_map[] = { + { SC_CARD_TYPE_PIV_II_PIVAPPLET, (u8 *)"PivApplet v", 11 }, + { 0, NULL, 0 } + }; /* * Flags in the piv_object: @@ -603,7 +649,6 @@ struct piv_object { }; /* Must be in order, and one per enumerated PIV_OBJ */ -// clang-format off static const struct piv_object piv_objects[] = { { PIV_OBJ_CCC, "Card Capability Container", SC_ASN1_APP | 0x13, @@ -844,6 +889,8 @@ static int piv_cache_internal_data(sc_card_t *card, int enumtag); static int piv_logout(sc_card_t *card); static int piv_match_card_continued(sc_card_t *card); static int piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags); +static int piv_ai_map_find_by_id(sc_card_t *card, u8); + #ifdef ENABLE_PIV_SM static void piv_inc(u8 *counter, size_t size); @@ -1665,11 +1712,6 @@ static int piv_load_options(sc_card_t *card) for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { #ifdef ENABLE_PIV_SM - -/* - * FIXME TODO - Names and locations of piv_pairing_code and piv_use_sm are likely to change in the future. - * See https://github.com/OpenSC/OpenSC/pull/2053/files#r1267388721 - */ /* * "piv_use_sm" if card supports NIST sp800-73-4 sm, when should it be used * never - use card like 800-73-3, i.e. contactless is very limited on @@ -1942,10 +1984,6 @@ static int piv_sm_verify_certs(struct sc_card *card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* TODO if already verified we could return - * may need to verify again, if card reset? - */ - if (cs == NULL) { r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -2062,22 +2100,7 @@ static int piv_sm_verify_certs(struct sc_card *card) } /* cert chain signatures match for oncard certs */ - /* TODO check dates and other info as per 800-73-4 */ - - /* TODO check against off card CA chain if present, - * Need opensc.conf options: - * where is CA cert chain? - * is it required? - * check for revocation? - * How often to check for revocation? - * When is SM used? - * Using NFC? - * (yes, main point of using SM) - * Should reading certificates be done in clear? - * (performance vs security) - * All crypto operations and PIN ? - * (yes for security) - */ + err: X509_free(cert); free(cert_blob_unzipped); @@ -2241,7 +2264,7 @@ static int piv_sm_open(struct sc_card *card) eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "point-format","uncompressed", 0); eph_params[eph_params_n] = OSSL_PARAM_construct_end(); - if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) /* TODO should be FIPS */ + if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) || !EVP_PKEY_keygen_init(eph_ctx) || !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) || !EVP_PKEY_generate(eph_ctx, &eph_pkey) @@ -2835,6 +2858,19 @@ static int piv_generate_key(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } +static int +piv_ai_map_find_by_id(sc_card_t *card, u8 id) +{ + /* piv_private_data_t * priv = PIV_DATA(card); */ + int i; + + for (i = 0; ai_map[i].ai_id != 0; i++) { + if (ai_map[i].ai_id == id) + return i; + } + return -1; +} + /* find the PIV AID on the card. If card->type already filled in, * then look for specific AID only */ @@ -2843,12 +2879,15 @@ static int piv_find_aid(sc_card_t * card) { piv_private_data_t * priv = PIV_DATA(card); u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - int r,i; + int r, i, j; const u8 *tag; size_t taglen; const u8 *nextac; + const u8 *next80; const u8 *pix; size_t pixlen; + const u8 *al_label; + size_t al_labellen; const u8 *actag; /* Cipher Suite */ size_t actaglen; const u8 *csai; /* Cipher Suite Algorithm Identifier */ @@ -2875,18 +2914,30 @@ static int piv_find_aid(sc_card_t * card) if (tag != NULL) { priv->init_flags |= PIV_INIT_AID_PARSED; /* look for 800-73-4 0xAC for Cipher Suite Algorithm Identifier Table 14 */ - /* There may be more than one 0xAC tag, loop to find all */ - + /* 800-73-4 only expects 1 0xAC tag len 6 with a 80 01 xx 06 01 00 + * where xx is the SM csID either 27 or 2E. + * Some vendors may include entries for supported Algorithms even when + * not required. We will use these if possible + * Will look for multiple 0x80 with in 0xAC value too. + */ nextac = tag; while((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag), 0xAC, &actaglen)) != NULL) { nextac = actag + actaglen; - csai = sc_asn1_find_tag(card->ctx, actag, actaglen, 0x80, &csailen); - if (csai != NULL) { - if (csailen == 1) { - sc_log(card->ctx,"found csID=0x%2.2x",*csai); + next80 = actag; + while((csai = sc_asn1_find_tag(card->ctx, next80, actaglen - (next80 - actag), + 0x80, &csailen)) != NULL) { + next80 = csai + csailen; + if (csailen == 1) { + sc_log(card->ctx,"0xAC 0x80 entry:0x%2.2x found", *csai); + j = piv_ai_map_find_by_id(card, *csai); + if (j >= 0) { + priv->alg_ids |= ai_map[j].ai_flag; + continue; + } #ifdef ENABLE_PIV_SM + /* check if id is NIST SM */ for (i = 0; i < PIV_CSS_SIZE; i++) { if (*csai != css[i].id) continue; @@ -2896,7 +2947,7 @@ static int piv_find_aid(sc_card_t * card) priv->cs = &css[i]; priv->csID = *csai; found_csai++; - priv->init_flags |= PIV_INIT_AID_AC; + priv->init_flags |= PIV_INIT_AID_AC_SM; } } #endif /* ENABLE_PIV_SM */ @@ -2904,8 +2955,19 @@ static int piv_find_aid(sc_card_t * card) } } + /* Last chance to distinguish card type based on Application Label '50' */ + al_label = sc_asn1_find_tag(card->ctx, tag, taglen, 0x50, &al_labellen); + if (al_label != NULL) { + sc_log_hex(card->ctx,"Application Label", al_label, al_labellen); + if ((priv->al_label = malloc(al_labellen)) == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + memcpy(priv->al_label, al_label, al_labellen); + priv->al_labellen = (int)al_labellen; + } + pix = sc_asn1_find_tag(card->ctx, tag, taglen, 0x4F, &pixlen); - if (pix != NULL ) { + if (pix != NULL) { sc_log(card->ctx, "found PIX"); /* early cards returned full AID, rather then just the pix */ @@ -3346,8 +3408,6 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co goto err; } - /* TODO Biometric Information Templates Group Template uses tag 7f61 */ - body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, rbuf[0], &bodylen); if (body == NULL) { /* if missing, assume its the body */ @@ -3568,7 +3628,6 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, r = piv_write_certificate(card, priv->w_buf, priv->w_buf_len, flags & 0x10); break; case 2: /* pubkey to be added to cache, it should have 0x53 and 0x99 tags. */ - /* TODO: -DEE this is not fully implemented and not used */ r = (int)priv->w_buf_len; break; default: @@ -5019,11 +5078,9 @@ static int piv_find_discovery(sc_card_t *card) /* * The history object lists what retired keys and certs are on the card - * or listed in the offCardCertURL. The user may have read the offCardURL file, - * ahead of time, and if so will use it for the certs listed. - * TODO: -DEE - * If the offCardCertURL is not cached by the user, should we wget it here? - * Its may be out of scope to have OpenSC read the URL. + * or listed in the offCardCertURL. The user will need to download the + * the offCardURL file. + * If the offCardCertURL is not cached by the user it will not be used. */ static int piv_process_history(sc_card_t *card) @@ -5305,6 +5362,7 @@ piv_finish(sc_card_t *card) sc_unlock(card); } free(priv->aid_der.value); + free(priv->al_label); if (priv->w_buf) free(priv->w_buf); if (priv->offCardCertURL) @@ -5347,6 +5405,9 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_PIVKEY: case SC_CARD_TYPE_PIV_II_SWISSBIT: case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: break; default: return 0; /* can not handle the card */ @@ -5398,6 +5459,9 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_PIVKEY: case SC_CARD_TYPE_PIV_II_SWISSBIT: case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: type = card->type; break; default: @@ -5425,15 +5489,22 @@ static int piv_match_card_continued(sc_card_t *card) !(memcmp(card->reader->atr_info.hist_bytes, "PIVKEY", 6))) { type = SC_CARD_TYPE_PIV_II_PIVKEY; } + else if (card->reader->atr_info.hist_bytes_len >= 6 && + !(memcmp(card->reader->atr_info.hist_bytes, (u8 *)"TK\x00PIV", 6))) { + type = SC_CARD_TYPE_PIV_II_TOKEN2; + } /* look for TLV historic data */ else if (card->reader->atr_info.hist_bytes_len > 0 && card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ size_t datalen; const u8 *data; + /* look for card issuer's data: tag 5X where X is datalen */ if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1, card->reader->atr_info.hist_bytes_len - 1, 0x50, &datalen))) { - if (datalen == 7 && !(memcmp(data, "YubiKey", 7))) { + if (datalen >= 8 && !(memcmp(data, "Nitrokey", 8))) { /* first 8 are Nitrokey */ + type = SC_CARD_TYPE_PIV_II_NITROKEY; + } else if (datalen == 7 && !(memcmp(data, "YubiKey", 7))) { type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */ } /* Yubikey 5 NFC ATR using ACR122 contactless reader does not match @@ -5458,10 +5529,11 @@ static int piv_match_card_continued(sc_card_t *card) } } } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); if (type == -1) { - /* use known ATRs */ + /* use known ATRs which changes the type */ i = _sc_match_atr(card, piv_atrs, &type); if (i < 0) type = SC_CARD_TYPE_PIV_II_BASE; /* May be some newer unknown card including CAC or PIV-like card */ @@ -5489,7 +5561,6 @@ static int piv_match_card_continued(sc_card_t *card) priv->max_object_size = MAX_FILE_SIZE - 256; /* fix SM apdu resplen issue */ priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ - /* TODO Dual CAC/PIV are bases on 800-73-1 where priv->pin_preference = 0. need to check later */ priv->logged_in = SC_PIN_STATE_UNKNOWN; priv->pstate = PIV_STATE_MATCH; @@ -5501,7 +5572,8 @@ static int piv_match_card_continued(sc_card_t *card) card->sm_ctx.ops.close = piv_sm_close; #endif /* ENABLE_PIV_SM */ - /* see if contactless */ + /* See if contactless or run as virtual card */ + /* PivApplet in .github/test_piv.sh for example */ if (card->reader->atr.len >= 4 && card->reader->atr.value[0] == 0x3b && (card->reader->atr.value[1] & 0xF0) == 0x80 @@ -5528,28 +5600,59 @@ static int piv_match_card_continued(sc_card_t *card) /* * if ATR matched or user forced card type - * test if PIV is active applet without using AID If fails use the AID + * test if PIV is active applet without using AID If fails try AID */ - if (card->type != SC_CARD_TYPE_PIV_II_BASE) + if (card->type > SC_CARD_TYPE_PIV_II_BASE && + !(priv->init_flags & PIV_INIT_CONTACTLESS)) { r = piv_find_discovery(card); - else - r = SC_CARD_TYPE_UNKNOWN; - - if (r < 0) { - piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache on failure */ + if (r < 0) { + piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache on failure */ + r = piv_find_aid(card); + LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card"); + } + } else { + /* piv_find_aid saves al_label from response */ r = piv_find_aid(card); + LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card"); } - /*if both fail, its not a PIV card */ - if (r < 0) { - goto err; + /* Know to be PIV card but not the type */ + + /* If card type still unknown, see if Application Label is known and set card->type */ + if (priv->al_label && priv->al_labellen) { + switch (card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + for (i = 0; al_map[i].al_label; i++) { + if ((priv->al_labellen >= al_map[i].al_labellen) && + (!memcmp(priv->al_label, al_map[i].al_label, al_map[i].al_labellen))) { + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "AL match i:%d type:%d", i, al_map[i].al_type); + card->type = al_map[i].al_type; + break; + } + } + break; + } } - /* Assumes all Yubikey cards are identified via ATR Historic bytes */ + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d AI:%08x\n", + card->type, priv->card_issues, r, priv->alg_ids); + + /* + * Assumes all Yubikey/Nitrokey/Token2/PivApplet cards are all "Yubico like" + * via ATR, ATR Historic bytes or Application Label + * Will also check if BASE cards are Yubikey like card and return a version number + * SC_CARD_TYPE_PIV_II_GENERIC can be set by user to not test for Yubico version + */ switch (card->type) { case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_BASE: /* unknown PIV card */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00); apdu.lc = 0; apdu.data = NULL; @@ -5557,13 +5660,16 @@ static int piv_match_card_continued(sc_card_t *card) apdu.resp = yubico_version_buf; apdu.resplen = sizeof(yubico_version_buf); apdu.le = apdu.resplen; - r2 = sc_transmit_apdu(card, &apdu); /* on error yubico_version == 0 */ + r2 = sc_transmit_apdu(card, &apdu); /* if not supported yubico_version == 0 */ if (apdu.resplen == 3) { priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; - sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); + sc_log(card->ctx, "Yubikey version test card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); } + break; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); /* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */ /* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */ @@ -5580,8 +5686,8 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GEMALTO: case SC_CARD_TYPE_PIV_II_OBERTHUR: r2 = piv_process_ccc(card); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d ccc_flags:%08x CI:%08x r:%d\n", - card->type, r2, priv->ccc_flags, priv->card_issues, r); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); /* Ignore any error. */ /* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { @@ -5615,31 +5721,54 @@ static int piv_match_card_continued(sc_card_t *card) priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); + + /* If contactless or run as virtual card try to get alg refs from AC entries in response to SELECT AID */ + if (!(priv->init_flags & PIV_INIT_AID_PARSED) && priv->init_flags & PIV_INIT_CONTACTLESS) { + r2 = piv_find_aid(card); + } /* Read AID if needed for these cards types */ if (!(priv->init_flags & PIV_INIT_AID_PARSED)) { switch(card->type) { case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: r2 = piv_find_aid(card); } } - /* If SM is supported, set SC_CARD_TYPE_PIV_II_800_73_4 */ - if (priv->init_flags & PIV_INIT_AID_AC) { - card->type = SC_CARD_TYPE_PIV_II_800_73_4; + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); + + /* if card did not specify any of the NIST basic alg_ids add them */ + if ((priv->alg_ids & AI_NIST) == 0) { + priv->alg_ids |= AI_NIST; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + /* If unknown card has 800-73-4 features, it must be based on 800-73-4 or above */ + switch(card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + if (priv->init_flags & PIV_INIT_AID_AC_SM) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } #ifdef ENABLE_PIV_SM - /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */ - if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) { - card->type = SC_CARD_TYPE_PIV_II_800_73_4; - } + /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */ + if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } #endif - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + break; + } + + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); /* * Set card_issues flags based card->type and version numbers if available. @@ -5656,7 +5785,8 @@ static int piv_match_card_continued(sc_card_t *card) * may be set earlier or later then in the following code. */ - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); switch(card->type) { case SC_CARD_TYPE_PIV_II_NEO: priv->card_issues |= CI_NO_EC384 @@ -5669,13 +5799,25 @@ static int piv_match_card_continued(sc_card_t *card) break; case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + case SC_CARD_TYPE_PIV_II_TOKEN2: priv->card_issues |= CI_OTHER_AID_LOSE_STATE | CI_LEAKS_FILE_NOT_FOUND; if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; - /* TODO may need to relocate when I get card to test */ - if (priv->yubico_version >= 0x00050700) - priv->card_issues |= CI_RSA_4096 | CI_25519; + if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */ + priv->alg_ids |= AI_RSA_4096 | AI_25519; + break; + + case SC_CARD_TYPE_PIV_II_NITROKEY: + priv->card_issues |= CI_OTHER_AID_LOSE_STATE; +<<<<<<< HEAD + if (priv->yubico_version >= 0x00010802) + priv->card_issues |= CI_RSA_4096; +======= + if (priv->yubico_version >= 0x00010802) /* use for NitroKey too */ + priv->alg_ids |= AI_RSA_4096; +>>>>>>> 21681946a (card-piv.c cards.h - Improved PIV card identification) break; case SC_CARD_TYPE_PIV_II_GI_DE: @@ -5698,7 +5840,6 @@ static int piv_match_card_continued(sc_card_t *card) | CI_PIV_AID_LOSE_STATE | CI_NO_RANDOM | CI_OTHER_AID_LOSE_STATE; - /* TODO may need more research */ break; case SC_CARD_TYPE_PIV_II_GENERIC: @@ -5709,10 +5850,8 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_PIVKEY: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_PIV_AID_LOSE_STATE /* be conservative */ - | CI_NO_EC384 | CI_NO_EC | CI_NO_RANDOM; /* does not have 9B key */ /* Discovery object returns 6A 82 so is not on card by default */ - /* TODO may need more research */ break; default: @@ -5722,8 +5861,8 @@ static int piv_match_card_continued(sc_card_t *card) sc_log(card->ctx, "Unknown PIV card->type %d", card->type); card->type = SC_CARD_TYPE_PIV_II_GENERIC; } - sc_log(card->ctx, "PIV card-type=%d card_issues=0x%08x", card->type, priv->card_issues); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED) ) { /* @@ -5741,12 +5880,14 @@ static int piv_match_card_continued(sc_card_t *card) } } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); /* Matched, caller will use or free priv and sc_lock as needed */ LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); err: - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH failed card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); /* don't match. Does not have a PIV applet. */ piv_finish(card); card->type = saved_type; @@ -5787,8 +5928,8 @@ static int piv_init(sc_card_t *card) priv->pstate=PIV_STATE_INIT; sc_log(card->ctx, - "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type = %d", - card->max_send_size, card->max_recv_size, card->type); + "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type:%d, CI:%08x AI:%08x", + card->max_send_size, card->max_recv_size, card->type, priv->card_issues, priv->alg_ids); card->cla = 0x00; if (card->name == NULL) card->name = card->driver->name; @@ -5806,11 +5947,17 @@ static int piv_init(sc_card_t *card) flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; } - _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ - _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ - _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ - if (priv->card_issues & CI_RSA_4096) - _sc_card_add_rsa_alg(card, 4096, flags, 0); /* some Yubikeys support this */ + if (priv->alg_ids & AI_RSA_1024) + _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ + + if (priv->alg_ids & AI_RSA_2048) + _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ + + if (priv->alg_ids & AI_RSA_3072) + _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */ + + if (priv->alg_ids & AI_RSA_4096) + _sc_card_add_rsa_alg(card, 4096, flags, 0); /* non standard */ if (!(priv->card_issues & CI_NO_EC)) { int i; @@ -5823,14 +5970,13 @@ static int piv_init(sc_card_t *card) if (ec_curves[i].key_type == SC_ALGORITHM_EC) { if (!(priv->card_issues & CI_NO_EC384 && ec_curves[i].size == 384)) _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid); + } - } else if (priv->card_issues & CI_25519) { - if (ec_curves[i].key_type == SC_ALGORITHM_EDDSA) { + else if (priv->alg_ids & AI_25519 && ec_curves[i].key_type == SC_ALGORITHM_EDDSA) _sc_card_add_eddsa_alg(card, ec_curves[i].size, flags_eddsa, ext_flags, &ec_curves[i].oid); - } else if (ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) { + + else if (priv->alg_ids & AI_X25519 &&ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) _sc_card_add_xeddsa_alg(card, ec_curves[i].size, flags_xeddsa, ext_flags, &ec_curves[i].oid); - } - } } } @@ -5852,7 +5998,6 @@ static int piv_init(sc_card_t *card) */ if (priv->csID && priv->cs != NULL) { /* - * TODO look closer at reset of card by other process * Main point in SM and VCI is to allow contactless access */ /* Only piv_init and piv_reader_lock_obtained should call piv_sm_open */ @@ -6006,7 +6151,6 @@ piv_check_protected_objects(sc_card_t *card) buf_len = sizeof(buf); rbuf = buf; r = piv_get_data(card, protected_objects[i], &rbuf, &buf_len); - /* TODO may need to check sw1 and sw2 to see what really happened */ if (r >= 0 || r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { /* we can use this object next time if needed */ @@ -6035,7 +6179,8 @@ piv_check_protected_objects(sc_card_t *card) else if (r > 0) r = SC_SUCCESS; - sc_log(card->ctx, "object_test_verify=%d, card_issues = 0x%08x", priv->object_test_verify, priv->card_issues); + sc_log(card->ctx, "card->type:%d CI:%08x r:%d AI:%08x\n", + card->type, priv->card_issues, r, priv->alg_ids); LOG_FUNC_RETURN(card->ctx, r); } @@ -6122,7 +6267,6 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) && priv->init_flags & PIV_INIT_CONTACTLESS && card->type == SC_CARD_TYPE_PIV_II_800_73_4) { sc_log(card->ctx, "Token does not support pin verify over contacless reader"); - /* TODO maybe true for other contactless cards */ r = SC_ERROR_NOT_SUPPORTED; } @@ -6169,7 +6313,6 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) { /* we still can not determine login state */ data->pin1.logged_in = priv->logged_in; /* may have be set from SC_PIN_CMD_VERIFY */ - /* TODO a reset may have logged us out. need to detect resets */ } else { data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT; } @@ -6214,15 +6357,11 @@ static int piv_logout(sc_card_t *card) * this is very similar to what the piv_match routine does, */ -/* TODO card.c also calls piv_sm_open before this if a reset was done, but +/* card.c also calls piv_sm_open before this if a reset was done, but * does not say if a reset was done or not. May need to ignore the call * the piv_sm_open in this case, but how? may need a open is active flag, * in case it is the APDU done from open caused triggered the case. */ - /* TODO may be called recursively to handle reset. - * need we are active, and if called again with was_reset save this - * and return to let first call handle the reset - */ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) { int r = 0; @@ -6259,7 +6398,6 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) * Discovery object can be read with contact or contactless * If read with SM and fails with 69 88 SC_ERROR_SM_INVALID_SESSION_KEY * sm.c will close the SM connectrion, and set defer - * TODO may be with reset? */ if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { sc_log(card->ctx,"SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN"); diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index fecac4cbf6..c897d6f9d9 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -119,6 +119,9 @@ enum { SC_CARD_TYPE_PIV_II_PIVKEY, SC_CARD_TYPE_PIV_II_SWISSBIT, SC_CARD_TYPE_PIV_II_800_73_4, + SC_CARD_TYPE_PIV_II_NITROKEY, + SC_CARD_TYPE_PIV_II_TOKEN2, + SC_CARD_TYPE_PIV_II_PIVAPPLET, /* MuscleApplet */ SC_CARD_TYPE_MUSCLE_BASE = 15000, From 35b77ae98433f18394b77dbe1d35919b6710f4a0 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 13 May 2026 08:17:32 -0500 Subject: [PATCH 4252/4321] card-piv.c manually reformat long if statements before clang-format Many long statements were writen into multiple lines readability. Thwy were seperated placing "||", "&&", "|" or "&" at the start of the next line. clang-format would then combine the multiple line into a single long unreadable line as it likes to seperate lines after "||", "&&", "|" or "&" This then lets clang-format still chage whitaspace in each line without combineing lines. On branch Nitrokey-PIV Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 410 +++++++++++++++++++-------------------- 1 file changed, 204 insertions(+), 206 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index ee569b8c9e..c99e8960fd 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -980,8 +980,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu cmac_params_n = 0; cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); - if (mac == NULL - || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { + if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; @@ -994,11 +993,11 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } - if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 - || EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 - || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.enc_counter, 16) != 1 - || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 - || outdl != 0) { + if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 || + EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.enc_counter, 16) != 1 || + EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || + outdl != 0) { sc_log_openssl(card->ctx); sc_log(card->ctx,"SM encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; @@ -1094,22 +1093,22 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu memcpy(priv->sm_session.C_MCV_last, priv->sm_session.C_MCV, MCVlen); /* save is case fails */ #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (CMAC_Init(cmac_ctx, priv->sm_session.SKmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 - || CMAC_Update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) != 1 - || CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 - || CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 - || CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) { + if (CMAC_Init(cmac_ctx, priv->sm_session.SKmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 || + CMAC_Update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) != 1 || + CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 || + CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 || + CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } #else if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKmac, - priv->sm_session.aes_size, cmac_params) - || !EVP_MAC_update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) - || !EVP_MAC_update(cmac_ctx, header, sizeof(header)) - || !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) - || !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) { + priv->sm_session.aes_size, cmac_params) || + !EVP_MAC_update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) || + !EVP_MAC_update(cmac_ctx, header, sizeof(header)) || + !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) || + !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; @@ -1180,9 +1179,9 @@ static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apd /* If not contactless, could read in clear */ /* Discovery object never has PIV_SM_GET_DATA_IN_CLEAR set */ sc_log(card->ctx,"init_flags:0x%8.8x sm_flags:0x%8.8lx",priv->init_flags,priv->sm_flags); - if (!(priv->init_flags & PIV_INIT_CONTACTLESS) - && !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) - && (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) { + if (!(priv->init_flags & PIV_INIT_CONTACTLESS) && + !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) && + (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) { priv->sm_flags &= ~PIV_SM_GET_DATA_IN_CLEAR; LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); } @@ -1277,24 +1276,24 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } - if (asn1_sm_response[0].flags & SC_ASN1_PRESENT /* optional */ - && ( ee.value == NULL || ee.len <= 2)) { + if (asn1_sm_response[0].flags & SC_ASN1_PRESENT && /* optional */ + ( ee.value == NULL || ee.len <= 2)) { sc_log(card->ctx,"SM BER-TLV not valid"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } - if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 - || (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) { + if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 || + (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) { sc_log(card->ctx,"SM missing status or R-MAC"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } - if (status.len != 2 - || status.value == NULL - || rmac8.len != 8 - || rmac8.value == NULL) { + if (status.len != 2 || + status.value == NULL || + rmac8.len != 8 || + rmac8.value == NULL) { sc_log(card->ctx,"SM status or R-MAC length invalid"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -1322,20 +1321,20 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu macdatalen = (int)(status.value + status.len - sm_apdu->resp); #if OPENSSL_VERSION_NUMBER < 0x30000000L - if (CMAC_Init(cmac_ctx, priv->sm_session.SKrmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 - || CMAC_Update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) != 1 - || CMAC_Update(cmac_ctx, sm_apdu->resp, macdatalen) != 1 - || CMAC_Final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen) != 1) { + if (CMAC_Init(cmac_ctx, priv->sm_session.SKrmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 || + CMAC_Update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) != 1 || + CMAC_Update(cmac_ctx, sm_apdu->resp, macdatalen) != 1 || + CMAC_Final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen) != 1) { sc_log_openssl(card->ctx); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } #else if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKrmac, - priv->sm_session.aes_size, cmac_params) - || !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) - || !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) - || !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) { + priv->sm_session.aes_size, cmac_params) || + !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) || + !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) || + !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; @@ -1355,11 +1354,11 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu } /* generate same IV used to encrypt response on card */ - if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 - || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 - || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 - || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 - || outdl != 0) { + if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 || + EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 || + EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || + outdl != 0) { sc_log_openssl(card->ctx); sc_log(card->ctx,"SM encode failed in OpenSSL"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -1403,14 +1402,14 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu q = plain->resp; /* first round encryptes counter with zero IV, and does not save the output */ - if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 - || EVP_DecryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 - || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 - || EVP_DecryptUpdate(ed_ctx, q ,&outl, p, inlen) != 1 - || EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16 ) != 1 - || EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 - || outdl != 0 - || outll != 16) { /* should not happen */ + if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 || + EVP_DecryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 || + EVP_DecryptUpdate(ed_ctx, q ,&outl, p, inlen) != 1 || + EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16 ) != 1 || + EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 || + outdl != 0 || + outll != 16) { /* should not happen */ sc_log_openssl(card->ctx); sc_log(card->ctx,"SM _decode failed in OpenSSL"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -1484,8 +1483,8 @@ static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_ap if (plain) { plain->sw1 = (*sm_apdu)->sw1; plain->sw2 = (*sm_apdu)->sw2; - if (((*sm_apdu)->sw1 == 0x90 && (*sm_apdu)->sw2 == 00) - || (*sm_apdu)->sw1 == 61){ + if (((*sm_apdu)->sw1 == 0x90 && (*sm_apdu)->sw2 == 00) || + (*sm_apdu)->sw1 == 61){ r = piv_decode_apdu(card, plain, *sm_apdu); goto err; } @@ -1936,10 +1935,10 @@ static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, goto err; } - if ((md_ctx = EVP_MD_CTX_new()) == NULL - || EVP_DigestVerifyInit(md_ctx, NULL, type, NULL, pkey) != 1 - || EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 - || EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) { + if ((md_ctx = EVP_MD_CTX_new()) == NULL || + EVP_DigestVerifyInit(md_ctx, NULL, type, NULL, pkey) != 1 || + EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 || + EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) { sc_log_openssl(card->ctx); sc_log (card->ctx, "EVP_DigestVerifyFinal failed"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2034,8 +2033,8 @@ static int piv_sm_verify_certs(struct sc_card *card) goto err; } - if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL - || (cert_pkey = X509_get0_pubkey(cert)) == NULL) { + if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL || + (cert_pkey = X509_get0_pubkey(cert)) == NULL) { sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to get pubkey from SM_CERT_SIGNER"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2054,14 +2053,14 @@ static int piv_sm_verify_certs(struct sc_card *card) } #if OPENSSL_VERSION_NUMBER < 0x30000000L - if ((in_cvc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL - || (in_cvc_pkey = EVP_PKEY_new()) == NULL - || (in_cvc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL - || (in_cvc_point = EC_POINT_new(in_cvc_group)) == NULL - || EC_POINT_oct2point(in_cvc_group, in_cvc_point, - priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 - || EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 - || EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) { + if ((in_cvc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL || + (in_cvc_pkey = EVP_PKEY_new()) == NULL || + (in_cvc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL || + (in_cvc_point = EC_POINT_new(in_cvc_group)) == NULL || + EC_POINT_oct2point(in_cvc_group, in_cvc_point, + priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 || + EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 || + EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) { sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2074,10 +2073,10 @@ static int piv_sm_verify_certs(struct sc_card *card) priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen); params[params_n] = OSSL_PARAM_construct_end(); - if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) - || !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) - || !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) - || !in_cvc_pkey) { + if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) || + !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) || + !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) || + !in_cvc_pkey) { sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2241,18 +2240,18 @@ static int piv_sm_open(struct sc_card *card) /* Step H2 generate ephemeral EC */ #if OPENSSL_VERSION_NUMBER < 0x30000000L - if ((eph_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL - || EVP_PKEY_keygen_init(eph_ctx) <= 0 - || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(eph_ctx, cs->nid) <= 0 - || EVP_PKEY_keygen(eph_ctx, &eph_pkey) <= 0 - || (eph_eckey = EVP_PKEY_get0_EC_KEY(eph_pkey)) == NULL - || (eph_group = EC_KEY_get0_group(eph_eckey)) == NULL - || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), - POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 /* get length */ - || Qehlen > cs->Qlen - || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), - POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 - || Qehlen > cs->Qlen) { + if ((eph_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL || + EVP_PKEY_keygen_init(eph_ctx) <= 0 || + EVP_PKEY_CTX_set_ec_paramgen_curve_nid(eph_ctx, cs->nid) <= 0 || + EVP_PKEY_keygen(eph_ctx, &eph_pkey) <= 0 || + (eph_eckey = EVP_PKEY_get0_EC_KEY(eph_pkey)) == NULL || + (eph_group = EC_KEY_get0_group(eph_eckey)) == NULL || + (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), + POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 || /* get length */ + Qehlen > cs->Qlen || + (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), + POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 || + Qehlen > cs->Qlen) { sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2264,14 +2263,13 @@ static int piv_sm_open(struct sc_card *card) eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "point-format","uncompressed", 0); eph_params[eph_params_n] = OSSL_PARAM_construct_end(); - if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) - || !EVP_PKEY_keygen_init(eph_ctx) - || !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) - || !EVP_PKEY_generate(eph_ctx, &eph_pkey) - || !(Qehxlen = EVP_PKEY_get1_encoded_public_key(eph_pkey, &Qehx)) - || !Qehx - || Qehxlen > cs->Qlen - ) { + if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) || + !EVP_PKEY_keygen_init(eph_ctx) || + !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) || + !EVP_PKEY_generate(eph_ctx, &eph_pkey) || + !(Qehxlen = EVP_PKEY_get1_encoded_public_key(eph_pkey, &Qehx)) || + !Qehx || + Qehxlen > cs->Qlen) { sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2409,8 +2407,8 @@ static int piv_sm_open(struct sc_card *card) const u8* tmpder; size_t tmpderlen; - if ((tag = sc_asn1_find_tag(card->ctx, cvcder, cvclen, 0x7F21, &taglen)) == NULL - || *cvcder != 0x7F || *(cvcder + 1) != 0x21) { + if ((tag = sc_asn1_find_tag(card->ctx, cvcder, cvclen, 0x7F21, &taglen)) == NULL || + *cvcder != 0x7F || *(cvcder + 1) != 0x21) { r = SC_ERROR_INTERNAL; goto err; @@ -2420,9 +2418,9 @@ static int piv_sm_open(struct sc_card *card) tmpder = cvcder; tmpderlen = cvclen; - if (EVP_DigestInit(hash_ctx,EVP_sha256()) != 1 - || EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 - || EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) { + if (EVP_DigestInit(hash_ctx,EVP_sha256()) != 1 || + EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 || + EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) { sc_log_openssl(card->ctx); sc_log(card->ctx,"IDsicc hash failed"); r = SC_ERROR_INTERNAL; @@ -2434,15 +2432,15 @@ static int piv_sm_open(struct sc_card *card) /* Step H7 get the cards public key Qsicc into OpenSSL Cicc_eckey */ #if OPENSSL_VERSION_NUMBER < 0x30000000L - if ((Cicc_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL - || (Cicc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL - || (Cicc_pkey = EVP_PKEY_new()) == NULL - || (Cicc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL - || (Cicc_point = EC_POINT_new(Cicc_group)) == NULL - || EC_POINT_oct2point(Cicc_group, Cicc_point, - priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 - || EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 - || EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) { + if ((Cicc_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL || + (Cicc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL || + (Cicc_pkey = EVP_PKEY_new()) == NULL || + (Cicc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL || + (Cicc_point = EC_POINT_new(Cicc_group)) == NULL || + EC_POINT_oct2point(Cicc_group, Cicc_point, + priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 || + EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 || + EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) { sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to get card's EC pubkey"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2455,10 +2453,10 @@ static int piv_sm_open(struct sc_card *card) priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen); Cicc_params[Cicc_params_n] = OSSL_PARAM_construct_end(); - if (!(Cicc_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) - || !EVP_PKEY_fromdata_init(Cicc_ctx) - || !EVP_PKEY_fromdata(Cicc_ctx, &Cicc_pkey, EVP_PKEY_PUBLIC_KEY, Cicc_params) - || !Cicc_pkey) { + if (!(Cicc_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) || + !EVP_PKEY_fromdata_init(Cicc_ctx) || + !EVP_PKEY_fromdata(Cicc_ctx, &Cicc_pkey, EVP_PKEY_PUBLIC_KEY, Cicc_params) || + !Cicc_pkey) { sc_log_openssl(card->ctx); sc_log(card->ctx, "OpenSSL failed to set EC pubkey for Cicc"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2475,14 +2473,14 @@ static int piv_sm_open(struct sc_card *card) } /* Step H8 Compute the shared secret Z */ - if ((Z_ctx = EVP_PKEY_CTX_new(eph_pkey, NULL)) == NULL - || EVP_PKEY_derive_init(Z_ctx) <= 0 - || EVP_PKEY_derive_set_peer(Z_ctx, Cicc_pkey) <= 0 - || EVP_PKEY_derive(Z_ctx, NULL, &Zlen) <= 0 - || Zlen != cs->Zlen - || (Z = malloc(Zlen)) == NULL - || EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 - || Zlen != cs->Zlen) { + if ((Z_ctx = EVP_PKEY_CTX_new(eph_pkey, NULL)) == NULL || + EVP_PKEY_derive_init(Z_ctx) <= 0 || + EVP_PKEY_derive_set_peer(Z_ctx, Cicc_pkey) <= 0 || + EVP_PKEY_derive(Z_ctx, NULL, &Zlen) <= 0 || + Zlen != cs->Zlen || + (Z = malloc(Zlen)) == NULL || + EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 || + Zlen != cs->Zlen) { sc_log_openssl(card->ctx); sc_log(card->ctx,"OpenSSL failed to create secret Z"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; @@ -2555,9 +2553,9 @@ static int piv_sm_open(struct sc_card *card) EVP_MD_CTX_reset(hash_ctx); for (i = 0; i < reps; i++) { - if (EVP_DigestInit(hash_ctx,(*cs->kdf_md)()) != 1 - || EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 - || EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) { + if (EVP_DigestInit(hash_ctx,(*cs->kdf_md)()) != 1 || + EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 || + EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) { sc_log_openssl(card->ctx); sc_log(card->ctx,"KDF hash failed"); r = SC_ERROR_INTERNAL; @@ -2620,10 +2618,10 @@ static int piv_sm_open(struct sc_card *card) MacDatalen = (int)(p - MacData); #if OPENSSL_VERSION_NUMBER < 0x30000000L - if ((cmac_ctx = CMAC_CTX_new()) == NULL - || CMAC_Init(cmac_ctx, priv->sm_session.SKcfrm, cs->aeskeylen, (*cs->cipher_cbc)(), NULL) != 1 - || CMAC_Update(cmac_ctx, MacData, MacDatalen) != 1 - || CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) { + if ((cmac_ctx = CMAC_CTX_new()) == NULL || + CMAC_Init(cmac_ctx, priv->sm_session.SKcfrm, cs->aeskeylen, (*cs->cipher_cbc)(), NULL) != 1 || + CMAC_Update(cmac_ctx, MacData, MacDatalen) != 1 || + CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) { r = SC_ERROR_INTERNAL; sc_log_openssl(card->ctx); sc_log(card->ctx,"AES_CMAC failed %d",r); @@ -2634,12 +2632,12 @@ static int piv_sm_open(struct sc_card *card) cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); - if (mac == NULL - || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL - || !EVP_MAC_init(cmac_ctx, priv->sm_session.SKcfrm, - priv->sm_session.aes_size, cmac_params) - || !EVP_MAC_update( cmac_ctx, MacData, MacDatalen) - || !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) { + if (mac == NULL || + (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL || + !EVP_MAC_init(cmac_ctx, priv->sm_session.SKcfrm, + priv->sm_session.aes_size, cmac_params) || + !EVP_MAC_update( cmac_ctx, MacData, MacDatalen) || + !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; sc_log(card->ctx,"AES_CMAC failed %d",r); @@ -2972,8 +2970,8 @@ static int piv_find_aid(sc_card_t * card) /* early cards returned full AID, rather then just the pix */ for (i = 0; piv_aids[i].len_long != 0; i++) { - if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5 ) == 0) - || ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, + if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5 ) == 0) || + ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, piv_aids[i].len_short) == 0))) { free(priv->aid_der.value); /* free previous value if any */ if ((priv->aid_der.value = malloc(resplen)) == NULL) { @@ -3029,8 +3027,8 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, body = tagbuf; /* accept any tag for now, just get length */ r_tag = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen); - if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) - || body == NULL) { + if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) || + body == NULL) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_FILE_NOT_FOUND; goto err; @@ -3120,12 +3118,12 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) */ sc_log(card->ctx,"enumtag:%d sm_ctx.sm_mode:%d piv_objects[enumtag].flags:0x%8.8x sm_flags:0x%8.8lx it_flags:0x%8.8x", enumtag, card->sm_ctx.sm_mode, piv_objects[enumtag].flags, priv->sm_flags, priv->init_flags); - if (priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE - && enumtag != PIV_OBJ_DISCOVERY - && card->sm_ctx.sm_mode == SM_MODE_TRANSMIT - && !(piv_objects[enumtag].flags & PIV_OBJECT_NEEDS_PIN) - && !(priv->sm_flags & (PIV_SM_FLAGS_NEVER | PIV_SM_FLAGS_ALWAYS)) - && !(priv->init_flags & ( PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) { + if (priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE && + enumtag != PIV_OBJ_DISCOVERY && + card->sm_ctx.sm_mode == SM_MODE_TRANSMIT && + !(piv_objects[enumtag].flags & PIV_OBJECT_NEEDS_PIN) && + !(priv->sm_flags & (PIV_SM_FLAGS_NEVER | PIV_SM_FLAGS_ALWAYS)) && + !(priv->init_flags & ( PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) { sc_log(card->ctx,"Set PIV_SM_GET_DATA_IN_CLEAR"); priv->sm_flags |= PIV_SM_GET_DATA_IN_CLEAR; } @@ -3138,9 +3136,8 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) size_t bodylen = 0; const u8 *body = *buf; r_tag = sc_asn1_read_tag(&body, r, &cla_out, &tag_out, &bodylen); - if (r_tag != SC_SUCCESS - || body == NULL - || ((cla_out << 24 | tag_out) != piv_objects[enumtag].resp_tag)) { + if (r_tag != SC_SUCCESS || body == NULL || + ((cla_out << 24 | tag_out) != piv_objects[enumtag].resp_tag)) { sc_log(card->ctx, "invalid tag or length r_tag:%d body:%p", r_tag, body); r = SC_ERROR_FILE_NOT_FOUND; goto err; @@ -3333,9 +3330,10 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) * Could reconstruct ASN1 of (T)(L) stating location from length and known tag. * as the size of (L) depends on the length of value */ - if ((tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x7F21, &taglen)) != NULL - && cvc_start && cvc_start < tag - && cvc_start[0] == 0x7f && cvc_start[1] == 0x21) { + if ((tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x7F21, &taglen)) != NULL && + cvc_start && + cvc_start < tag && + cvc_start[0] == 0x7f && cvc_start[1] == 0x21) { cvc_len = tag - cvc_start + taglen; /* decode the intermediate CVC */ r = piv_decode_cvc(card, &cvc_start, &cvc_len, &priv->sm_in_cvc); @@ -4396,8 +4394,8 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) if (fascn && fascnlen == 25 && fbits) { /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ /* ;9999 is non-gov issued FASC-N, will use FASC-N for gov issued if no guid */ - if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 - && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { + if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 && + fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { /* fascnlen is 25 */ serial->len = fascnlen; memcpy (serial->value, fascn, serial->len); @@ -4880,10 +4878,10 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS - || body == NULL - || bodylen == 0 - || ((cla_out|tag_out) != 0x7E)) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + body == NULL || + bodylen == 0 || + ((cla_out|tag_out) != 0x7E)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -4907,8 +4905,8 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a priv->pin_policy = (*pinp << 8) + *(pinp + 1); sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); if ((priv->pin_policy & (PIV_PP_PIN | PIV_PP_GLOBAL)) - == (PIV_PP_PIN | PIV_PP_GLOBAL) - && priv->pin_policy & PIV_PP_GLOBAL_PRIMARY) { + == (PIV_PP_PIN | PIV_PP_GLOBAL) && + priv->pin_policy & PIV_PP_GLOBAL_PRIMARY) { sc_log(card->ctx, "Pin Preference - Global"); priv->pin_preference = 0x00; } @@ -4969,10 +4967,10 @@ static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) /* Outer layer is a DER tlv */ body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS - || body == NULL - || bodylen == 0 - || ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_CCC].resp_tag)) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + body == NULL || + bodylen == 0 || + ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_CCC].resp_tag)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5059,9 +5057,9 @@ static int piv_find_discovery(sc_card_t *card) if ( r == 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == 0) goto end; - if (r >= 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == rbuflen - && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data - && !memcmp(rbuf, priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data, rbuflen)) { + if (r >= 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == rbuflen && + priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data && + !memcmp(rbuf, priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data, rbuflen)) { goto end; } /* This should not happen bad card */ @@ -5125,8 +5123,8 @@ piv_process_history(sc_card_t *card) /* the object is now cached, see what we have */ if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS - || ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_HISTORY].resp_tag)) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_HISTORY].resp_tag)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5242,10 +5240,10 @@ piv_process_history(sc_card_t *card) */ body = ocfhfbuf; - if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS - || body == NULL - || bodylen == 0 - || (cla_out|tag_out) != 0x30) { + if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS || + body == NULL || + bodylen == 0 || + (cla_out|tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5253,10 +5251,10 @@ piv_process_history(sc_card_t *card) seq = body; while (bodylen > 0) { seqtag = seq; - if (sc_asn1_read_tag(&seq, bodylen, &cla_out, &tag_out, &seqlen) != SC_SUCCESS - || seq == 0 - || seqlen == 0 - || (cla_out|tag_out) != 0x30) { + if (sc_asn1_read_tag(&seq, bodylen, &cla_out, &tag_out, &seqlen) != SC_SUCCESS || + seq == 0 || + seqlen == 0 || + (cla_out|tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5494,8 +5492,8 @@ static int piv_match_card_continued(sc_card_t *card) type = SC_CARD_TYPE_PIV_II_TOKEN2; } /* look for TLV historic data */ - else if (card->reader->atr_info.hist_bytes_len > 0 - && card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ + else if (card->reader->atr_info.hist_bytes_len > 0 && + card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ size_t datalen; const u8 *data; @@ -5520,8 +5518,8 @@ static int piv_match_card_continued(sc_card_t *card) int k; for (k = 0; piv_aids[k].len_long != 0; k++) { - if (datalen == piv_aids[k].len_long - && !memcmp(data, piv_aids[k].value, datalen)) { + if (datalen == piv_aids[k].len_long && + !memcmp(data, piv_aids[k].value, datalen)) { type = SC_CARD_TYPE_PIV_II_HIST; break; } @@ -5574,11 +5572,11 @@ static int piv_match_card_continued(sc_card_t *card) /* See if contactless or run as virtual card */ /* PivApplet in .github/test_piv.sh for example */ - if (card->reader->atr.len >= 4 - && card->reader->atr.value[0] == 0x3b - && (card->reader->atr.value[1] & 0xF0) == 0x80 - && card->reader->atr.value[2] == 0x80 - && card->reader->atr.value[3] == 0x01) { + if (card->reader->atr.len >= 4 && + card->reader->atr.value[0] == 0x3b && + (card->reader->atr.value[1] & 0xF0) == 0x80 && + card->reader->atr.value[2] == 0x80 && + card->reader->atr.value[3] == 0x01) { priv->init_flags |= PIV_INIT_CONTACTLESS; } @@ -5789,11 +5787,11 @@ static int piv_match_card_continued(sc_card_t *card) card->type, r2, priv->card_issues, r, priv->alg_ids); switch(card->type) { case SC_CARD_TYPE_PIV_II_NEO: - priv->card_issues |= CI_NO_EC384 - | CI_VERIFY_630X - | CI_OTHER_AID_LOSE_STATE - | CI_LEAKS_FILE_NOT_FOUND - | CI_NFC_EXPOSE_TOO_MUCH; + priv->card_issues |= CI_NO_EC384 | + CI_VERIFY_630X | + CI_OTHER_AID_LOSE_STATE | + CI_LEAKS_FILE_NOT_FOUND | + CI_NFC_EXPOSE_TOO_MUCH; if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; break; @@ -5801,8 +5799,8 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_YUBIKEY4: case SC_CARD_TYPE_PIV_II_PIVAPPLET: case SC_CARD_TYPE_PIV_II_TOKEN2: - priv->card_issues |= CI_OTHER_AID_LOSE_STATE - | CI_LEAKS_FILE_NOT_FOUND; + priv->card_issues |= CI_OTHER_AID_LOSE_STATE | + CI_LEAKS_FILE_NOT_FOUND; if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */ @@ -5836,27 +5834,27 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - priv->card_issues |= CI_VERIFY_LC0_FAIL - | CI_PIV_AID_LOSE_STATE - | CI_NO_RANDOM - | CI_OTHER_AID_LOSE_STATE; + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_PIV_AID_LOSE_STATE | + CI_NO_RANDOM | + CI_OTHER_AID_LOSE_STATE; break; case SC_CARD_TYPE_PIV_II_GENERIC: - priv->card_issues |= CI_VERIFY_LC0_FAIL - | CI_OTHER_AID_LOSE_STATE; + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_OTHER_AID_LOSE_STATE; break; case SC_CARD_TYPE_PIV_II_PIVKEY: - priv->card_issues |= CI_VERIFY_LC0_FAIL - | CI_PIV_AID_LOSE_STATE /* be conservative */ - | CI_NO_RANDOM; /* does not have 9B key */ + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_PIV_AID_LOSE_STATE | /* be conservative */ + CI_NO_RANDOM; /* does not have 9B key */ /* Discovery object returns 6A 82 so is not on card by default */ break; default: - priv->card_issues |= CI_VERIFY_LC0_FAIL - | CI_OTHER_AID_LOSE_STATE; + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_OTHER_AID_LOSE_STATE; /* opensc.conf may have it wrong, continue anyway */ sc_log(card->ctx, "Unknown PIV card->type %d", card->type); card->type = SC_CARD_TYPE_PIV_II_GENERIC; @@ -6007,14 +6005,14 @@ static int piv_init(sc_card_t *card) sc_log(card->ctx,"User has requested PIV_SM_FLAGS_NEVER"); r = SC_SUCCESS; /* Users choice */ - } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) - && !(priv->pin_policy & PIV_PP_VCI_IMPL)) { + } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) && + !(priv->pin_policy & PIV_PP_VCI_IMPL)) { sc_log(card->ctx,"Contactless and no card support for VCI"); r = SC_SUCCESS; /* User should know VCI is not possible with their card; use like 800-73-3 contactless */ - } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) - && !(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) - && (priv->pairing_code[0] == 0x00)) { + } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) && + !(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) && + (priv->pairing_code[0] == 0x00)) { sc_log(card->ctx,"Contactless, pairing_code required and no pairing code"); r = SC_ERROR_PIN_CODE_INCORRECT; /* User should know they need to set pairing code */ @@ -6263,9 +6261,9 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) priv->pin_cmd_verify = 0; /* tell user verify not supported on contactless without VCI */ - if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 - && priv->init_flags & PIV_INIT_CONTACTLESS - && card->type == SC_CARD_TYPE_PIV_II_800_73_4) { + if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 && + priv->init_flags & PIV_INIT_CONTACTLESS && + card->type == SC_CARD_TYPE_PIV_II_800_73_4) { sc_log(card->ctx, "Token does not support pin verify over contacless reader"); r = SC_ERROR_NOT_SUPPORTED; } @@ -6303,8 +6301,8 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) { sc_log(card->ctx, "CI_CANT_USE_GETDATA_FOR_STATE set, assume logged_in=%d", priv->logged_in); data->pin1.logged_in = priv->logged_in; /* use what ever we saw last */ - } else if (priv->card_issues & CI_VERIFY_LC0_FAIL - && priv->pin_cmd_verify_sw1 == 0x63U ) { /* can not use modified return codes from iso->drv->pin_cmd */ + } else if (priv->card_issues & CI_VERIFY_LC0_FAIL && + priv->pin_cmd_verify_sw1 == 0x63U ) { /* can not use modified return codes from iso->drv->pin_cmd */ /* try another method, looking at a protected object this may require adding one of these to NEO */ r = piv_check_protected_objects(card); if (r == SC_SUCCESS) From 97e3d993b42c84d68f401bebec6696e23f830ae0 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 13 May 2026 10:33:15 -0500 Subject: [PATCH 4253/4321] card-piv.c - clang-format Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 1776 +++++++++++++++++++------------------- 1 file changed, 894 insertions(+), 882 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c99e8960fd..005cf5633a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -55,8 +55,8 @@ /* 800-73-4 SM and VCI need: ECC, SM and OpenSSL or LibreSSL */ #if defined(ENABLE_PIV_SM) -#include #include "compression.h" +#include #endif #include "asn1.h" @@ -878,42 +878,40 @@ static const struct piv_object piv_objects[] = { static struct sc_card_operations piv_ops; static struct sc_card_driver piv_drv = { - "Personal Identity Verification Card", - "PIV-II", - &piv_ops, - NULL, 0, NULL -}; + "Personal Identity Verification Card", + "PIV-II", + &piv_ops, + NULL, 0, NULL}; -static int piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len); +static int piv_get_cached_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len); static int piv_cache_internal_data(sc_card_t *card, int enumtag); static int piv_logout(sc_card_t *card); static int piv_match_card_continued(sc_card_t *card); static int piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags); static int piv_ai_map_find_by_id(sc_card_t *card, u8); - #ifdef ENABLE_PIV_SM static void piv_inc(u8 *counter, size_t size); static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu); static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu); static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu); -static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth); +static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth); static int piv_sm_open(struct sc_card *card); static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu); static int piv_sm_close(sc_card_t *card); static void piv_clear_cvc_content(piv_cvc_t *cvc); static void piv_clear_sm_session(piv_sm_session_t *session); -static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, piv_cvc_t *cvc); +static int piv_decode_cvc(sc_card_t *card, u8 **buf, size_t *buflen, piv_cvc_t *cvc); static int piv_parse_pairing_code(sc_card_t *card, const char *option); -static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 * OS, size_t *OSlen); +static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 *OS, size_t *OSlen); static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code); static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, EVP_PKEY *pkey, u8 *data, size_t data_size, unsigned char *sig, size_t siglen); static int piv_sm_verify_certs(struct sc_card *card); - -static void piv_inc(u8 *counter, size_t size) +static void +piv_inc(u8 *counter, size_t size) { unsigned int c = 1; unsigned int b; @@ -929,12 +927,13 @@ static void piv_inc(u8 *counter, size_t size) * Construct SM protected APDU */ -static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) +static int +piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) { int r = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; - u8 pad[16] ={0x80}; + u8 pad[16] = {0x80}; u8 zeros[16] = {0x00}; u8 IV[16]; u8 header[16]; @@ -958,7 +957,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu u8 *p; EVP_CIPHER_CTX *ed_ctx = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - CMAC_CTX *cmac_ctx = NULL; + CMAC_CTX *cmac_ctx = NULL; #else EVP_MAC_CTX *cmac_ctx = NULL; EVP_MAC *mac = NULL; @@ -999,7 +998,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"SM encode failed in OpenSSL"); + sc_log(card->ctx, "SM encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; goto err; } @@ -1061,8 +1060,8 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu p = sbuf; if (T87len != 0) { - r = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, sbuf, sbuflen, &p); - if (r != SC_SUCCESS) + r = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, sbuf, sbuflen, &p); + if (r != SC_SUCCESS) goto err; *p++ = 0x01; /* padding context indicator */ @@ -1076,7 +1075,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { /* should not happen */ sc_log_openssl(card->ctx); - sc_log(card->ctx,"SM _encode failed in OpenSSL"); + sc_log(card->ctx, "SM _encode failed in OpenSSL"); r = SC_ERROR_INTERNAL; goto err; } @@ -1096,18 +1095,18 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu if (CMAC_Init(cmac_ctx, priv->sm_session.SKmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 || CMAC_Update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) != 1 || CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 || - CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 || + CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 || CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } #else - if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKmac, - priv->sm_session.aes_size, cmac_params) || + if (!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKmac, + priv->sm_session.aes_size, cmac_params) || !EVP_MAC_update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) || !EVP_MAC_update(cmac_ctx, header, sizeof(header)) || - !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) || + !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) || !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; @@ -1134,7 +1133,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu sm_apdu->resplen = plain->resplen + 40; /* expect at least tagged status and rmac8 */ sm_apdu->resp = malloc(sm_apdu->resplen); if (sm_apdu->resp == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; + r = SC_ERROR_OUT_OF_MEMORY; goto err; } sm_apdu->le = 256; /* always ask for 256 */ @@ -1158,11 +1157,11 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) +static int +piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) { int r = SC_SUCCESS; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1175,25 +1174,25 @@ static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apd LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); switch (plain->ins) { - case 0xCB: /* GET_DATA */ - /* If not contactless, could read in clear */ - /* Discovery object never has PIV_SM_GET_DATA_IN_CLEAR set */ - sc_log(card->ctx,"init_flags:0x%8.8x sm_flags:0x%8.8lx",priv->init_flags,priv->sm_flags); - if (!(priv->init_flags & PIV_INIT_CONTACTLESS) && - !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) && - (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) { - priv->sm_flags &= ~PIV_SM_GET_DATA_IN_CLEAR; - LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); - } - break; - case 0x20: /* VERIFY */ - break; - case 0x24: /* CHANGE REFERENCE DATA */ - break; - case 0x87: /* GENERAL AUTHENTICATE */ - break; - default: /* just issue the plain apdu */ + case 0xCB: /* GET_DATA */ + /* If not contactless, could read in clear */ + /* Discovery object never has PIV_SM_GET_DATA_IN_CLEAR set */ + sc_log(card->ctx, "init_flags:0x%8.8x sm_flags:0x%8.8lx", priv->init_flags, priv->sm_flags); + if (!(priv->init_flags & PIV_INIT_CONTACTLESS) && + !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) && + (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) { + priv->sm_flags &= ~PIV_SM_GET_DATA_IN_CLEAR; LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); + } + break; + case 0x20: /* VERIFY */ + break; + case 0x24: /* CHANGE REFERENCE DATA */ + break; + case 0x87: /* GENERAL AUTHENTICATE */ + break; + default: /* just issue the plain apdu */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); } *sm_apdu = calloc(1, sizeof(sc_apdu_t)); @@ -1209,9 +1208,9 @@ static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apd LOG_FUNC_RETURN(card->ctx, r); } - /* ASN1 callback to save address and len of the object */ -static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth) +static int +piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth) { struct sc_lv_data *al = arg; @@ -1223,11 +1222,12 @@ static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t return SC_SUCCESS; } -static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) +static int +piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) { int r = SC_SUCCESS; int i; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; struct sc_lv_data ee = {NULL, 0}; struct sc_lv_data status = {NULL, 0}; @@ -1250,7 +1250,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu EVP_CIPHER_CTX *ed_ctx = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - CMAC_CTX *cmac_ctx = NULL; + CMAC_CTX *cmac_ctx = NULL; #else EVP_MAC *mac = NULL; EVP_MAC_CTX *cmac_ctx = NULL; @@ -1271,21 +1271,21 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu r = sc_asn1_decode(card->ctx, asn1_sm_response, sm_apdu->resp, sm_apdu->resplen, NULL, NULL); if (r < 0) { - sc_log(card->ctx,"SM decode failed"); + sc_log(card->ctx, "SM decode failed"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } if (asn1_sm_response[0].flags & SC_ASN1_PRESENT && /* optional */ - ( ee.value == NULL || ee.len <= 2)) { - sc_log(card->ctx,"SM BER-TLV not valid"); + (ee.value == NULL || ee.len <= 2)) { + sc_log(card->ctx, "SM BER-TLV not valid"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 || (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) { - sc_log(card->ctx,"SM missing status or R-MAC"); + sc_log(card->ctx, "SM missing status or R-MAC"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1294,7 +1294,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu status.value == NULL || rmac8.len != 8 || rmac8.value == NULL) { - sc_log(card->ctx,"SM status or R-MAC length invalid"); + sc_log(card->ctx, "SM status or R-MAC length invalid"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1330,8 +1330,8 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } #else - if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKrmac, - priv->sm_session.aes_size, cmac_params) || + if (!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKrmac, + priv->sm_session.aes_size, cmac_params) || !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) || !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) || !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) { @@ -1355,12 +1355,12 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu /* generate same IV used to encrypt response on card */ if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 || - EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"SM encode failed in OpenSSL"); + sc_log(card->ctx, "SM encode failed in OpenSSL"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1378,10 +1378,10 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu } p++; /* skip padding indicator */ - inlen --; + inlen--; if ((inlen % 16) != 0) { - sc_log(card->ctx,"SM encrypted data not multiple of 16"); + sc_log(card->ctx, "SM encrypted data not multiple of 16"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1393,7 +1393,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu */ inlen -= 16; - if (plain->resplen < (unsigned) inlen || plain->resp == NULL) { + if (plain->resplen < (unsigned)inlen || plain->resp == NULL) { sc_log(card->ctx, "SM response will not fit in resp,resplen"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -1404,20 +1404,20 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu /* first round encryptes counter with zero IV, and does not save the output */ if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 || EVP_DecryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 || - EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 || - EVP_DecryptUpdate(ed_ctx, q ,&outl, p, inlen) != 1 || - EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16 ) != 1 || + EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 || + EVP_DecryptUpdate(ed_ctx, q, &outl, p, inlen) != 1 || + EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16) != 1 || EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 || outdl != 0 || - outll != 16) { /* should not happen */ + outll != 16) { /* should not happen */ sc_log_openssl(card->ctx); - sc_log(card->ctx,"SM _decode failed in OpenSSL"); + sc_log(card->ctx, "SM _decode failed in OpenSSL"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } /* unpad last block and get bytes in last block */ - for (i = 15; i > 0 ; i--) { + for (i = 15; i > 0; i--) { if (lastb[i] == 0x80) break; if (lastb[i] == 0x00) @@ -1435,7 +1435,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu /* will response fit in plain resp buffer */ if ((unsigned)inlen + i > plain->resplen || plain->resp == NULL) { - sc_log(card->ctx,"SM response bigger then resplen"); + sc_log(card->ctx, "SM response bigger then resplen"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1469,7 +1469,8 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu LOG_FUNC_RETURN(card->ctx, r); } -static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) +static int +piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) { int r = SC_SUCCESS; @@ -1484,11 +1485,11 @@ static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_ap plain->sw1 = (*sm_apdu)->sw1; plain->sw2 = (*sm_apdu)->sw2; if (((*sm_apdu)->sw1 == 0x90 && (*sm_apdu)->sw2 == 00) || - (*sm_apdu)->sw1 == 61){ - r = piv_decode_apdu(card, plain, *sm_apdu); + (*sm_apdu)->sw1 == 61) { + r = piv_decode_apdu(card, plain, *sm_apdu); goto err; } - sc_log(card->ctx,"SM response sw1:0x%2.2x sw2:0x%2.2x", plain->sw1, plain->sw2); + sc_log(card->ctx, "SM response sw1:0x%2.2x sw2:0x%2.2x", plain->sw1, plain->sw2); if (plain->sw1 == 0x69 && plain->sw2 == 0x88) { /* BUT plain->sw1 and sw2 are not passed back as expected */ r = SC_ERROR_SM_INVALID_CHECKSUM; /* will use this one one for now */ @@ -1508,11 +1509,11 @@ static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_ap LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_sm_close(sc_card_t *card) +static int +piv_sm_close(sc_card_t *card) { int r = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, "priv->sm_flags: 0x%8.8lu", priv->sm_flags); @@ -1526,7 +1527,8 @@ static int piv_sm_close(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } -static void piv_clear_cvc_content(piv_cvc_t *cvc) +static void +piv_clear_cvc_content(piv_cvc_t *cvc) { if (!cvc) return; @@ -1538,7 +1540,8 @@ static void piv_clear_cvc_content(piv_cvc_t *cvc) return; } -static void piv_clear_sm_session(piv_sm_session_t *session) +static void +piv_clear_sm_session(piv_sm_session_t *session) { if (!session) return; @@ -1549,8 +1552,9 @@ static void piv_clear_sm_session(piv_sm_session_t *session) /* * Decode a card verifiable certificate as defined in NIST 800-73-4 */ -static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, - piv_cvc_t *cvc) +static int +piv_decode_cvc(sc_card_t *card, u8 **buf, size_t *buflen, + piv_cvc_t *cvc) { struct sc_asn1_entry asn1_piv_cvc[C_ASN1_PIV_CVC_SIZE]; struct sc_asn1_entry asn1_piv_cvc_body[C_ASN1_PIV_CVC_BODY_SIZE]; @@ -1588,18 +1592,18 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, sc_copy_asn1_entry(c_asn1_piv_cvc_dssig, asn1_piv_cvc_dssig); sc_copy_asn1_entry(c_asn1_piv_cvc_alg_id, asn1_piv_cvc_alg_id); - sc_format_asn1_entry(asn1_piv_cvc_alg_id , &cvc->signatureAlgOID, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_alg_id, &cvc->signatureAlgOID, NULL, 1); sc_format_asn1_entry(asn1_piv_cvc_alg_id + 1, NULL, NULL, 1); /* NULL */ - sc_format_asn1_entry(asn1_piv_cvc_dssig , &asn1_piv_cvc_alg_id, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_dssig, &asn1_piv_cvc_alg_id, NULL, 1); sc_format_asn1_entry(asn1_piv_cvc_dssig + 1, &cvc->signature, &signaturebits, 1); - sc_format_asn1_entry(asn1_piv_cvc_dsobj , &asn1_piv_cvc_dssig, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_dsobj, &asn1_piv_cvc_dssig, NULL, 1); - sc_format_asn1_entry(asn1_piv_cvc_pubkey , &cvc->pubKeyOID, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_pubkey, &cvc->pubKeyOID, NULL, 1); sc_format_asn1_entry(asn1_piv_cvc_pubkey + 1, &cvc->publicPoint, &cvc->publicPointlen, 1); - sc_format_asn1_entry(asn1_piv_cvc_body , &cvc->cpi, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_body, &cvc->cpi, NULL, 1); sc_format_asn1_entry(asn1_piv_cvc_body + 1, &cvc->issuerID, &cvc->issuerIDlen, 1); sc_format_asn1_entry(asn1_piv_cvc_body + 2, &cvc->subjectID, &cvc->subjectIDlen, 1); sc_format_asn1_entry(asn1_piv_cvc_body + 3, &asn1_piv_cvc_pubkey, NULL, 1); @@ -1608,7 +1612,7 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, sc_format_asn1_entry(asn1_piv_cvc, &asn1_piv_cvc_body, NULL, 1); - r = sc_asn1_decode(card->ctx, asn1_piv_cvc, *buf, *buflen, NULL, NULL) ; /*(const u8 **) &buf_tmp, &len);*/ + r = sc_asn1_decode(card->ctx, asn1_piv_cvc, *buf, *buflen, NULL, NULL); /*(const u8 **) &buf_tmp, &len);*/ if (r < 0) { piv_clear_cvc_content(cvc); sc_log(card->ctx, "Could not decode card verifiable certificate"); @@ -1625,7 +1629,7 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, /* save body der for verification */ buf_tmp = *buf; r = sc_asn1_read_tag(&buf_tmp, *buflen, &cla_out, &tag_out, &taglen); - LOG_TEST_RET(card->ctx, r," failed to read tag"); + LOG_TEST_RET(card->ctx, r, " failed to read tag"); cvc->bodylen = (roleIDder.value + roleIDder.len) - buf_tmp; @@ -1646,8 +1650,8 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - -static int piv_parse_pairing_code(sc_card_t *card, const char *option) +static int +piv_parse_pairing_code(sc_card_t *card, const char *option) { size_t i; @@ -1657,7 +1661,7 @@ static int piv_parse_pairing_code(sc_card_t *card, const char *option) } for (i = 0; i < PIV_PAIRING_CODE_LEN; i++) { if (!isdigit(option[i])) { - sc_log(card->ctx, "pairing code must be %d decimal digits",PIV_PAIRING_CODE_LEN); + sc_log(card->ctx, "pairing code must be %d decimal digits", PIV_PAIRING_CODE_LEN); return SC_ERROR_INVALID_ARGUMENTS; } } @@ -1665,39 +1669,38 @@ static int piv_parse_pairing_code(sc_card_t *card, const char *option) } #endif -static int piv_load_options(sc_card_t *card) +static int +piv_load_options(sc_card_t *card) { int r; size_t i, j; scconf_block **found_blocks, *block; #ifdef ENABLE_PIV_SM - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); const char *option = NULL; int piv_pairing_code_found = 0; int piv_use_sm_found = 0; /* pairing code is 8 decimal digits and is card specific */ if ((option = getenv("PIV_PAIRING_CODE")) != NULL) { - sc_log(card->ctx,"getenv(\"PIV_PAIRING_CODE\") found"); + sc_log(card->ctx, "getenv(\"PIV_PAIRING_CODE\") found"); if (piv_parse_pairing_code(card, option) == SC_SUCCESS) { memcpy(priv->pairing_code, option, PIV_PAIRING_CODE_LEN); piv_pairing_code_found = 1; } } - if ((option = getenv("PIV_USE_SM"))!= NULL) { - sc_log(card->ctx,"getenv(\"PIV_USE_SM\")=\"%s\"", option); + if ((option = getenv("PIV_USE_SM")) != NULL) { + sc_log(card->ctx, "getenv(\"PIV_USE_SM\")=\"%s\"", option); if (!strcmp(option, "never")) { priv->sm_flags |= PIV_SM_FLAGS_NEVER; piv_use_sm_found = 1; - } - else if (!strcmp(option, "always")) { + } else if (!strcmp(option, "always")) { priv->sm_flags |= PIV_SM_FLAGS_ALWAYS; piv_use_sm_found = 1; - } - else { - sc_log(card->ctx,"Invalid piv_use_sm: \"%s\"", option); + } else { + sc_log(card->ctx, "Invalid piv_use_sm: \"%s\"", option); } } #endif @@ -1723,18 +1726,15 @@ static int piv_load_options(sc_card_t *card) if (piv_use_sm_found == 0) { option = scconf_get_str(block, "piv_use_sm", "default"); - sc_log(card->ctx,"conf: \"piv_use_sm\"=\"%s\"", option); - if (!strcmp(option,"default")) { + sc_log(card->ctx, "conf: \"piv_use_sm\"=\"%s\"", option); + if (!strcmp(option, "default")) { /* no new flags */ - } - else if (!strcmp(option, "never")) { + } else if (!strcmp(option, "never")) { priv->sm_flags |= PIV_SM_FLAGS_NEVER; - } - else if (!strcmp(option, "always")) { + } else if (!strcmp(option, "always")) { priv->sm_flags |= PIV_SM_FLAGS_ALWAYS; - } - else { - sc_log(card->ctx,"Invalid piv_use_sm: \"%s\"", option); + } else { + sc_log(card->ctx, "Invalid piv_use_sm: \"%s\"", option); } } @@ -1748,13 +1748,13 @@ static int piv_load_options(sc_card_t *card) #endif } free(found_blocks); - } - r = SC_SUCCESS; - return r; + } + r = SC_SUCCESS; + return r; } static int -piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) +piv_find_obj_by_containerid(sc_card_t *card, const u8 *str) { int i; @@ -1762,7 +1762,7 @@ piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) sc_log(card->ctx, "str=0x%02X%02X\n", str[0], str[1]); for (i = 0; piv_objects[i].enumtag < PIV_OBJ_LAST_ENUM; i++) { - if ( str[0] == piv_objects[i].containerid[0] && str[1] == piv_objects[i].containerid[1]) + if (str[0] == piv_objects[i].containerid[0] && str[1] == piv_objects[i].containerid[1]) LOG_FUNC_RETURN(card->ctx, i); } @@ -1775,9 +1775,10 @@ piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) * and GENERATE ASYMMETRIC KEY PAIR. */ -static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, - const u8 * sendbuf, size_t sendbuflen, u8 *recvbuf, - size_t recvbuflen) +static int +piv_general_io(sc_card_t *card, int ins, int p1, int p2, + const u8 *sendbuf, size_t sendbuflen, u8 *recvbuf, + size_t recvbuflen) { int r; sc_apdu_t apdu; @@ -1789,7 +1790,7 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, LOG_FUNC_RETURN(card->ctx, r); sc_format_apdu(card, &apdu, - recvbuf ? SC_APDU_CASE_4_SHORT: SC_APDU_CASE_3_SHORT, + recvbuf ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, ins, p1, p2); apdu.flags |= SC_APDU_FLAGS_CHAINING; #ifdef ENABLE_PIV_SM @@ -1809,7 +1810,7 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, apdu.le = 0; apdu.resplen = 0; } - apdu.resp = recvbuf; + apdu.resp = recvbuf; /* with new adpu.c and chaining, this actually reads the whole object */ r = sc_transmit_apdu(card, &apdu); @@ -1820,13 +1821,13 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, goto err; } - if (apdu.sw1 == 0x69 && apdu.sw2 == 0x88) + if (apdu.sw1 == 0x69 && apdu.sw2 == 0x88) r = SC_ERROR_SM_INVALID_SESSION_KEY; else r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) { - sc_log(card->ctx, "Card returned error "); + sc_log(card->ctx, "Card returned error "); goto err; } @@ -1837,7 +1838,6 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, LOG_FUNC_RETURN(card->ctx, r); } - #ifdef ENABLE_PIV_SM /* convert q as 04||x||y used in standard point formats to expanded leading * zeros and concatenated X||Y as specified in SP80056A Appendix C.2 @@ -1845,12 +1845,13 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, * OpenSSL has already converted X and Y to big endian and skipped leading * zero bytes. */ -static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 * OS, size_t *OSlen) +static int +Q2OS(int fsize, u8 *Q, size_t Qlen, u8 *OS, size_t *OSlen) { size_t i; - size_t f = fsize/8; + size_t f = fsize / 8; - i = (Qlen - 1)/2; + i = (Qlen - 1) / 2; if (!OS || *OSlen < f * 2 || !Q || i > f) return SC_ERROR_INTERNAL; @@ -1869,10 +1870,11 @@ static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 * OS, size_t *OSlen) * if needed, send VCI pairing code to card just after the * SM key establishment. Called from piv_sm_open under same lock */ -static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code) +static int +piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code) { int r; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); sc_apdu_t plain; sc_apdu_t sm_apdu; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1889,7 +1891,7 @@ static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code) plain.resp = NULL; plain.resplen = plain.le = 0; - memset(&sm_apdu,0,sizeof(sm_apdu)); + memset(&sm_apdu, 0, sizeof(sm_apdu)); /* build sm_apdu and set alloc sm_apdu.resp */ r = piv_encode_apdu(card, &plain, &sm_apdu); if (r < 0) { @@ -1918,12 +1920,13 @@ static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code) } /* Verify one signature using pubkey */ -static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, +static int +piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, EVP_PKEY *pkey, u8 *data, size_t data_size, unsigned char *sig, size_t siglen) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; int r = 0; EVP_MD_CTX *md_ctx = NULL; @@ -1940,7 +1943,7 @@ static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 || EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) { sc_log_openssl(card->ctx); - sc_log (card->ctx, "EVP_DigestVerifyFinal failed"); + sc_log(card->ctx, "EVP_DigestVerifyFinal failed"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1956,20 +1959,20 @@ static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, * If sm_in_cvc is not present verify PIV_OBJ_SM_CERT_SIGNER signed sm_cvc. */ - -static int piv_sm_verify_certs(struct sc_card *card) +static int +piv_sm_verify_certs(struct sc_card *card) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; int r = 0; u8 *cert_blob_unzipped = NULL; /* free */ - u8 *cert_blob = NULL; /* do not free */ + u8 *cert_blob = NULL; /* do not free */ size_t cert_bloblen = 0; u8 *rbuf; /* do not free*/ size_t rbuflen; X509 *cert = NULL; - EVP_PKEY *cert_pkey = NULL; /* do not free */ + EVP_PKEY *cert_pkey = NULL; /* do not free */ EVP_PKEY *in_cvc_pkey = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_GROUP *in_cvc_group = NULL; @@ -1998,7 +2001,7 @@ static int piv_sm_verify_certs(struct sc_card *card) r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } - r = piv_cache_internal_data(card,PIV_OBJ_SM_CERT_SIGNER); + r = piv_cache_internal_data(card, PIV_OBJ_SM_CERT_SIGNER); if (r < 0) { r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -2010,9 +2013,9 @@ static int piv_sm_verify_certs(struct sc_card *card) if (priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].flags & PIV_OBJ_CACHE_COMPRESSED) { #ifdef ENABLE_ZLIB if (SC_SUCCESS != sc_decompress_alloc(&cert_blob_unzipped, &cert_bloblen, - priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data, - priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len, - COMPRESSION_AUTO)) { + priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data, + priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len, + COMPRESSION_AUTO)) { sc_log(card->ctx, "PIV decompression of SM CERT_SIGNER failed"); r = SC_ERROR_OBJECT_NOT_VALID; goto err; @@ -2036,7 +2039,7 @@ static int piv_sm_verify_certs(struct sc_card *card) if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL || (cert_pkey = X509_get0_pubkey(cert)) == NULL) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"OpenSSL failed to get pubkey from SM_CERT_SIGNER"); + sc_log(card->ctx, "OpenSSL failed to get pubkey from SM_CERT_SIGNER"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2045,10 +2048,10 @@ static int piv_sm_verify_certs(struct sc_card *card) if (priv->sm_flags & PIV_SM_FLAGS_SM_IN_CVC_PRESENT) { r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey, priv->sm_in_cvc.body, priv->sm_in_cvc.bodylen, - priv->sm_in_cvc.signature,priv->sm_in_cvc.signaturelen); + priv->sm_in_cvc.signature, priv->sm_in_cvc.signaturelen); if (r < 0) { - sc_log(card->ctx,"sm_in_cvc signature invalid"); - r = SC_ERROR_SM_AUTHENTICATION_FAILED; + sc_log(card->ctx, "sm_in_cvc signature invalid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2058,7 +2061,7 @@ static int piv_sm_verify_certs(struct sc_card *card) (in_cvc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL || (in_cvc_point = EC_POINT_new(in_cvc_group)) == NULL || EC_POINT_oct2point(in_cvc_group, in_cvc_point, - priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 || + priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 || EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 || EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) { sc_log_openssl(card->ctx); @@ -2085,16 +2088,16 @@ static int piv_sm_verify_certs(struct sc_card *card) #endif r = piv_sm_verify_sig(card, cs->kdf_md(), in_cvc_pkey, priv->sm_cvc.body, priv->sm_cvc.bodylen, - priv->sm_cvc.signature,priv->sm_cvc.signaturelen); + priv->sm_cvc.signature, priv->sm_cvc.signaturelen); } else { /* cert signed sm_cvc */ r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey, priv->sm_cvc.body, priv->sm_cvc.bodylen, - priv->sm_cvc.signature,priv->sm_cvc.signaturelen); + priv->sm_cvc.signature, priv->sm_cvc.signaturelen); } if (r < 0) { - sc_log(card->ctx,"sm_cvc signature invalid"); - r = SC_ERROR_SM_AUTHENTICATION_FAILED; + sc_log(card->ctx, "sm_cvc signature invalid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2115,16 +2118,16 @@ static int piv_sm_verify_certs(struct sc_card *card) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } - /* * NIST SP800-73-4 4.1 The key Establishment Protocol * Variable names and Steps are based on Client Application (h) * and PIV Card Application (icc) * Capital leters used for variable, and lower case for subscript names */ -static int piv_sm_open(struct sc_card *card) +static int +piv_sm_open(struct sc_card *card) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; int r = 0; int i; @@ -2137,7 +2140,7 @@ static int piv_sm_open(struct sc_card *card) EVP_PKEY_CTX *eph_ctx = NULL; EVP_PKEY *eph_pkey = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - EC_KEY *eph_eckey = NULL; /* don't free _get0_*/ + EC_KEY *eph_eckey = NULL; /* don't free _get0_*/ const EC_GROUP *eph_group = NULL; /* don't free _get0_ */ #else OSSL_PARAM eph_params[5]; @@ -2146,11 +2149,11 @@ static int piv_sm_open(struct sc_card *card) u8 *Qehx = NULL; #endif size_t Qehlen = 0; - u8 Qeh[2 * PIV_SM_MAX_FIELD_LENGTH/8 + 1]; /* big enough for 384 04||x||y if x and y have leading zeros, length may be less */ + u8 Qeh[2 * PIV_SM_MAX_FIELD_LENGTH / 8 + 1]; /* big enough for 384 04||x||y if x and y have leading zeros, length may be less */ size_t Qeh_OSlen = 0; - u8 Qeh_OS[2 * PIV_SM_MAX_FIELD_LENGTH/8]; /* no leading 04, with leading zeros in X and Y */ + u8 Qeh_OS[2 * PIV_SM_MAX_FIELD_LENGTH / 8]; /* no leading 04, with leading zeros in X and Y */ size_t Qsicc_OSlen = 0; - u8 Qsicc_OS[2 * PIV_SM_MAX_FIELD_LENGTH/8]; /* no leading 04, with leading zeros in X and Y */ + u8 Qsicc_OS[2 * PIV_SM_MAX_FIELD_LENGTH / 8]; /* no leading 04, with leading zeros in X and Y */ /* pub EC key from card Cicc in sm_cvc */ EVP_PKEY_CTX *Cicc_ctx = NULL; @@ -2166,8 +2169,8 @@ static int piv_sm_open(struct sc_card *card) u8 *Z = NULL; size_t Zlen = 0; - u8 IDsh[8] = {0}; - unsigned long pid; + u8 IDsh[8] = {0}; + unsigned long pid; u8 *sbuf = NULL; size_t sbuflen; @@ -2191,7 +2194,7 @@ static int piv_sm_open(struct sc_card *card) u8 aeskeys[SHA384_DIGEST_LENGTH * 3] = {0}; /* 4 keys, Hash function is run 2 or 3 times max is 3 * 384/8 see below */ EVP_MD_CTX *hash_ctx = NULL; #if OPENSSL_VERSION_NUMBER < 0x30000000L - CMAC_CTX *cmac_ctx = NULL; + CMAC_CTX *cmac_ctx = NULL; #else EVP_MAC *mac = NULL; EVP_MAC_CTX *cmac_ctx = NULL; @@ -2217,7 +2220,7 @@ static int piv_sm_open(struct sc_card *card) * a loop, each trying to reestablish a SM session and run command. */ if (!(priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { - LOG_FUNC_RETURN(card->ctx,SC_ERROR_NOT_ALLOWED); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); } if (cs == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); @@ -2247,21 +2250,21 @@ static int piv_sm_open(struct sc_card *card) (eph_eckey = EVP_PKEY_get0_EC_KEY(eph_pkey)) == NULL || (eph_group = EC_KEY_get0_group(eph_eckey)) == NULL || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), - POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 || /* get length */ + POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 || /* get length */ Qehlen > cs->Qlen || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), - POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 || + POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 || Qehlen > cs->Qlen) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); + sc_log(card->ctx, "OpenSSL failed to create ephemeral EC key"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } #else /* generate Qeh */ eph_params_n = 0; - eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); - eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "point-format","uncompressed", 0); + eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0); + eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string("point-format", "uncompressed", 0); eph_params[eph_params_n] = OSSL_PARAM_construct_end(); if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) || !EVP_PKEY_keygen_init(eph_ctx) || @@ -2271,7 +2274,7 @@ static int piv_sm_open(struct sc_card *card) !Qehx || Qehxlen > cs->Qlen) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); + sc_log(card->ctx, "OpenSSL failed to create ephemeral EC key"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2282,7 +2285,7 @@ static int piv_sm_open(struct sc_card *card) /* For later use, get Qeh without 04 and full size X || Y */ Qeh_OSlen = sizeof(Qeh_OS); if (Q2OS(cs->field_length, Qeh, Qehlen, Qeh_OS, &Qeh_OSlen)) { - sc_log(card->ctx,"Q2OS for Qeh failed"); + sc_log(card->ctx, "Q2OS for Qeh failed"); r = SC_ERROR_INTERNAL; goto err; } @@ -2304,7 +2307,7 @@ static int piv_sm_open(struct sc_card *card) } p = sbuf; - r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, sbuf, sbuflen, &p); + r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, sbuf, sbuflen, &p); if (r != SC_SUCCESS) goto err; @@ -2316,9 +2319,9 @@ static int piv_sm_open(struct sc_card *card) *p++ = CBh; #ifdef WIN32 - pid = (unsigned long) GetCurrentProcessId(); + pid = (unsigned long)GetCurrentProcessId(); #else - pid = (unsigned long) getpid(); /* use PID as our ID so different from other processes */ + pid = (unsigned long)getpid(); /* use PID as our ID so different from other processes */ #endif memcpy(IDsh, &pid, MIN(sizeof(pid), sizeof(IDsh))); memcpy(p, IDsh, sizeof(IDsh)); @@ -2354,11 +2357,11 @@ static int piv_sm_open(struct sc_card *card) } /* payload is CBicc (1) || Nicc (16 or 24) || AuthCryptogram (CMAC 16 or 16) ||Cicc (variable) */ - p = (u8 *) payload; + p = (u8 *)payload; /* Step H4 check CBicc == 0x00 */ CBicc = *p++; - if (CBicc != 0x00) { /* CBicc must be zero */ + if (CBicc != 0x00) { /* CBicc must be zero */ sc_log(card->ctx, "SM card did not accept request"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -2402,9 +2405,9 @@ static int piv_sm_open(struct sc_card *card) /* Step H6 need left most 8 bytes of hash of sm_cvc */ { u8 hash[SHA256_DIGEST_LENGTH] = {0}; - const u8* tag; + const u8 *tag; size_t taglen; - const u8* tmpder; + const u8 *tmpder; size_t tmpderlen; if ((tag = sc_asn1_find_tag(card->ctx, cvcder, cvclen, 0x7F21, &taglen)) == NULL || @@ -2415,14 +2418,14 @@ static int piv_sm_open(struct sc_card *card) } /* debug choice */ - tmpder = cvcder; + tmpder = cvcder; tmpderlen = cvclen; - if (EVP_DigestInit(hash_ctx,EVP_sha256()) != 1 || + if (EVP_DigestInit(hash_ctx, EVP_sha256()) != 1 || EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 || EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"IDsicc hash failed"); + sc_log(card->ctx, "IDsicc hash failed"); r = SC_ERROR_INTERNAL; goto err; } @@ -2438,17 +2441,17 @@ static int piv_sm_open(struct sc_card *card) (Cicc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL || (Cicc_point = EC_POINT_new(Cicc_group)) == NULL || EC_POINT_oct2point(Cicc_group, Cicc_point, - priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 || + priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 || EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 || EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"OpenSSL failed to get card's EC pubkey"); + sc_log(card->ctx, "OpenSSL failed to get card's EC pubkey"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } #else Cicc_params_n = 0; - Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); + Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0); Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_octet_string("pub", priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen); Cicc_params[Cicc_params_n] = OSSL_PARAM_construct_end(); @@ -2467,7 +2470,7 @@ static int piv_sm_open(struct sc_card *card) /* Qsicc without 04 and expanded x||y */ Qsicc_OSlen = sizeof(Qsicc_OS); if (Q2OS(cs->field_length, priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, Qsicc_OS, &Qsicc_OSlen)) { - sc_log(card->ctx,"Q2OS for Qsicc failed"); + sc_log(card->ctx, "Q2OS for Qsicc failed"); r = SC_ERROR_INTERNAL; goto err; } @@ -2482,12 +2485,12 @@ static int piv_sm_open(struct sc_card *card) EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 || Zlen != cs->Zlen) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"OpenSSL failed to create secret Z"); + sc_log(card->ctx, "OpenSSL failed to create secret Z"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } - sc_log(card->ctx, "debug Zlen:%"SC_FORMAT_LEN_SIZE_T"u Z[0]:0x%2.2x", Zlen, Z[0]); + sc_log(card->ctx, "debug Zlen:%" SC_FORMAT_LEN_SIZE_T "u Z[0]:0x%2.2x", Zlen, Z[0]); /* Step H9 zeroize deh from step H2 */ EVP_PKEY_free(eph_pkey); /* OpenSSL BN_clear_free calls OPENSSL_cleanse */ @@ -2512,7 +2515,7 @@ static int piv_sm_open(struct sc_card *card) /* otherinfo */ *p++ = cs->o0len; - for (i = 0; i < cs->o0len; i++) + for (i = 0; i < cs->o0len; i++) *p++ = cs->o0_char; /* 0x09 or 0x0d */ *p++ = sizeof(IDsh); @@ -2553,15 +2556,15 @@ static int piv_sm_open(struct sc_card *card) EVP_MD_CTX_reset(hash_ctx); for (i = 0; i < reps; i++) { - if (EVP_DigestInit(hash_ctx,(*cs->kdf_md)()) != 1 || + if (EVP_DigestInit(hash_ctx, (*cs->kdf_md)()) != 1 || EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 || EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) { sc_log_openssl(card->ctx); - sc_log(card->ctx,"KDF hash failed"); + sc_log(card->ctx, "KDF hash failed"); r = SC_ERROR_INTERNAL; goto err; } - kdf_in[3]++; /* inc the counter */ + kdf_in[3]++; /* inc the counter */ p += cs->kdf_hash_size; } @@ -2584,7 +2587,7 @@ static int piv_sm_open(struct sc_card *card) if (Z && Zlen) { sc_mem_clear(Z, Zlen); free(Z); - Z=NULL; + Z = NULL; Zlen = 0; } if (kdf_in && kdf_inlen) { @@ -2624,7 +2627,7 @@ static int piv_sm_open(struct sc_card *card) CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) { r = SC_ERROR_INTERNAL; sc_log_openssl(card->ctx); - sc_log(card->ctx,"AES_CMAC failed %d",r); + sc_log(card->ctx, "AES_CMAC failed %d", r); goto err; } #else @@ -2635,21 +2638,21 @@ static int piv_sm_open(struct sc_card *card) if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL || !EVP_MAC_init(cmac_ctx, priv->sm_session.SKcfrm, - priv->sm_session.aes_size, cmac_params) || - !EVP_MAC_update( cmac_ctx, MacData, MacDatalen) || + priv->sm_session.aes_size, cmac_params) || + !EVP_MAC_update(cmac_ctx, MacData, MacDatalen) || !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; - sc_log(card->ctx,"AES_CMAC failed %d",r); + sc_log(card->ctx, "AES_CMAC failed %d", r); goto err; } #endif if (0 == memcmp(AuthCryptogram, Check_AuthCryptogram, cs->AuthCryptogramlen)) { - sc_log(card->ctx,"AuthCryptogram compare"); + sc_log(card->ctx, "AuthCryptogram compare"); r = 0; } else { - sc_log(card->ctx,"AuthCryptogram compare failed"); + sc_log(card->ctx, "AuthCryptogram compare failed"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -2711,7 +2714,8 @@ static int piv_sm_open(struct sc_card *card) /* Should use our own keydata, actually should be common to all cards */ /* RSA and EC are added. */ -static int piv_generate_key(sc_card_t *card, +static int +piv_generate_key(sc_card_t *card, sc_cardctl_piv_genkey_info_t *keydata) { int r; @@ -2741,28 +2745,36 @@ static int piv_generate_key(sc_card_t *card, outdata[1] = 0x01; outdata[2] = keydata->key_algid; switch (keydata->key_algid) { - case 0x05: keydata->key_bits = 3072; break; - case 0x06: keydata->key_bits = 1024; break; - case 0x07: keydata->key_bits = 2048; break; - case 0x16: /* Yubico 5.7 support for 4096 */ - keydata->key_bits = 4096; - break; - case 0x11: keydata->key_bits = 0; - keydata->ecparam = 0; /* we only support prime256v1 */ - keydata->ecparam_len = 0; - break; - case 0x14: keydata->key_bits = 0; - keydata->ecparam = 0; /* we only support secp384r1 */ - keydata->ecparam_len = 0; - break; - case 0xE0: /* Yubico 5.7 support for EDDSA 25519 */ - case 0xE1: /* Yubico 5.7 support for XEDDSA 25519 */ - keydata->key_bits = 0; - keydata->ecparam = 0; - keydata->ecparam_len = 0; - break; - default: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + case 0x05: + keydata->key_bits = 3072; + break; + case 0x06: + keydata->key_bits = 1024; + break; + case 0x07: + keydata->key_bits = 2048; + break; + case 0x16: /* Yubico 5.7 support for 4096 */ + keydata->key_bits = 4096; + break; + case 0x11: + keydata->key_bits = 0; + keydata->ecparam = 0; /* we only support prime256v1 */ + keydata->ecparam_len = 0; + break; + case 0x14: + keydata->key_bits = 0; + keydata->ecparam = 0; /* we only support secp384r1 */ + keydata->ecparam_len = 0; + break; + case 0xE0: /* Yubico 5.7 support for EDDSA 25519 */ + case 0xE1: /* Yubico 5.7 support for XEDDSA 25519 */ + keydata->key_bits = 0; + keydata->ecparam = 0; + keydata->ecparam_len = 0; + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } p = tagbuf; @@ -2793,7 +2805,7 @@ static int piv_generate_key(sc_card_t *card, } /* if RSA vs EC, ED25519 or X25519 */ - if (keydata->key_bits > 0 ) { + if (keydata->key_bits > 0) { tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen); if (tag != NULL && taglen <= 4) { keydata->exponent = malloc(taglen); @@ -2873,9 +2885,10 @@ piv_ai_map_find_by_id(sc_card_t *card, u8 id) * then look for specific AID only */ -static int piv_find_aid(sc_card_t * card) +static int +piv_find_aid(sc_card_t *card) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r, i, j; const u8 *tag; @@ -2885,8 +2898,8 @@ static int piv_find_aid(sc_card_t * card) const u8 *pix; size_t pixlen; const u8 *al_label; - size_t al_labellen; - const u8 *actag; /* Cipher Suite */ + size_t al_labellen; + const u8 *actag; /* Cipher Suite */ size_t actaglen; const u8 *csai; /* Cipher Suite Algorithm Identifier */ size_t csailen; @@ -2897,17 +2910,16 @@ static int piv_find_aid(sc_card_t * card) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* first see if the default application will return a template * that we know about. */ r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen); - if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) { - LOG_FUNC_RETURN(card->ctx,SC_SUCCESS); + if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) { + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); /* no need to parse again, same as last time */ } - if (r >= 0 && resplen > 2 ) { + if (r >= 0 && resplen > 2) { tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, 0x61, &taglen); if (tag != NULL) { priv->init_flags |= PIV_INIT_AID_PARSED; @@ -2915,20 +2927,20 @@ static int piv_find_aid(sc_card_t * card) /* 800-73-4 only expects 1 0xAC tag len 6 with a 80 01 xx 06 01 00 * where xx is the SM csID either 27 or 2E. * Some vendors may include entries for supported Algorithms even when - * not required. We will use these if possible + * not required. We will use these if possible * Will look for multiple 0x80 with in 0xAC value too. */ nextac = tag; - while((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag), - 0xAC, &actaglen)) != NULL) { + while ((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag), + 0xAC, &actaglen)) != NULL) { nextac = actag + actaglen; next80 = actag; - while((csai = sc_asn1_find_tag(card->ctx, next80, actaglen - (next80 - actag), - 0x80, &csailen)) != NULL) { - next80 = csai + csailen; - if (csailen == 1) { - sc_log(card->ctx,"0xAC 0x80 entry:0x%2.2x found", *csai); + while ((csai = sc_asn1_find_tag(card->ctx, next80, actaglen - (next80 - actag), + 0x80, &csailen)) != NULL) { + next80 = csai + csailen; + if (csailen == 1) { + sc_log(card->ctx, "0xAC 0x80 entry:0x%2.2x found", *csai); j = piv_ai_map_find_by_id(card, *csai); if (j >= 0) { priv->alg_ids |= ai_map[j].ai_flag; @@ -2940,7 +2952,7 @@ static int piv_find_aid(sc_card_t * card) if (*csai != css[i].id) continue; if (found_csai) { - sc_log(card->ctx,"found multiple csIDs, using first"); + sc_log(card->ctx, "found multiple csIDs, using first"); } else { priv->cs = &css[i]; priv->csID = *csai; @@ -2956,12 +2968,12 @@ static int piv_find_aid(sc_card_t * card) /* Last chance to distinguish card type based on Application Label '50' */ al_label = sc_asn1_find_tag(card->ctx, tag, taglen, 0x50, &al_labellen); if (al_label != NULL) { - sc_log_hex(card->ctx,"Application Label", al_label, al_labellen); - if ((priv->al_label = malloc(al_labellen)) == NULL) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - memcpy(priv->al_label, al_label, al_labellen); - priv->al_labellen = (int)al_labellen; + sc_log_hex(card->ctx, "Application Label", al_label, al_labellen); + if ((priv->al_label = malloc(al_labellen)) == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + memcpy(priv->al_label, al_label, al_labellen); + priv->al_labellen = (int)al_labellen; } pix = sc_asn1_find_tag(card->ctx, tag, taglen, 0x4F, &pixlen); @@ -2970,16 +2982,16 @@ static int piv_find_aid(sc_card_t * card) /* early cards returned full AID, rather then just the pix */ for (i = 0; piv_aids[i].len_long != 0; i++) { - if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5 ) == 0) || - ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, - piv_aids[i].len_short) == 0))) { - free(priv->aid_der.value); /* free previous value if any */ + if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5) == 0) || + ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, + piv_aids[i].len_short) == 0))) { + free(priv->aid_der.value); /* free previous value if any */ if ((priv->aid_der.value = malloc(resplen)) == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } memcpy(priv->aid_der.value, rbuf, resplen); priv->aid_der.len = resplen; - LOG_FUNC_RETURN(card->ctx,i); + LOG_FUNC_RETURN(card->ctx, i); } } } @@ -2995,8 +3007,9 @@ static int piv_find_aid(sc_card_t * card) * Also used for testing of History and Discovery objects from a file * when testing with a card that does not support these new objects. */ -static int piv_read_obj_from_file(sc_card_t * card, char * filename, - u8 **buf, size_t *buf_len) +static int +piv_read_obj_from_file(sc_card_t *card, char *filename, + u8 **buf, size_t *buf_len) { int r; int r_tag; @@ -3004,7 +3017,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, size_t len; u8 tagbuf[16]; size_t rbuflen; - const u8 * body; + const u8 *body; unsigned int cla_out, tag_out; size_t bodylen; @@ -3014,14 +3027,14 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, *buf_len = 0; f = open(filename, O_RDONLY); if (f < 0) { - sc_log(card->ctx, "Unable to load PIV off card file: \"%s\"",filename); - r = SC_ERROR_FILE_NOT_FOUND; - goto err; + sc_log(card->ctx, "Unable to load PIV off card file: \"%s\"", filename); + r = SC_ERROR_FILE_NOT_FOUND; + goto err; } len = read(f, tagbuf, sizeof(tagbuf)); /* get tag and length */ if (len < 2 || len > sizeof(tagbuf)) { - sc_log(card->ctx, "Problem with \"%s\"",filename); - r = SC_ERROR_DATA_OBJECT_NOT_FOUND; + sc_log(card->ctx, "Problem with \"%s\"", filename); + r = SC_ERROR_DATA_OBJECT_NOT_FOUND; goto err; } body = tagbuf; @@ -3045,7 +3058,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, len = read(f, *buf + sizeof(tagbuf), rbuflen - sizeof(tagbuf)); /* read rest */ if (len != rbuflen - sizeof(tagbuf)) { r = SC_ERROR_INVALID_ASN1_OBJECT; - free (*buf); + free(*buf); *buf = NULL; goto err; } @@ -3060,9 +3073,9 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, /* the tag is the PIV_OBJ_* */ static int -piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) +piv_get_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); u8 *p; u8 *tbuf; int r = 0; @@ -3089,14 +3102,14 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) goto err; } - if (*buf_len == 1 && *buf == NULL){ + if (*buf_len == 1 && *buf == NULL) { *buf_len = priv->max_object_size; /* will allocate below */ alloc_buf = 1; } sc_log(card->ctx, - "buffer for #%d *buf=0x%p len=%"SC_FORMAT_LEN_SIZE_T"u", - enumtag, *buf, *buf_len); + "buffer for #%d *buf=0x%p len=%" SC_FORMAT_LEN_SIZE_T "u", + enumtag, *buf, *buf_len); if (*buf == NULL && *buf_len > 0) { if (*buf_len > MAX_FILE_SIZE) { r = SC_ERROR_INTERNAL; @@ -3116,20 +3129,20 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) * Discovery object will use SM from reader_lock_obtained to catch if SM is still valid * i.e. no interference from other applications */ - sc_log(card->ctx,"enumtag:%d sm_ctx.sm_mode:%d piv_objects[enumtag].flags:0x%8.8x sm_flags:0x%8.8lx it_flags:0x%8.8x", + sc_log(card->ctx, "enumtag:%d sm_ctx.sm_mode:%d piv_objects[enumtag].flags:0x%8.8x sm_flags:0x%8.8lx it_flags:0x%8.8x", enumtag, card->sm_ctx.sm_mode, piv_objects[enumtag].flags, priv->sm_flags, priv->init_flags); if (priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE && enumtag != PIV_OBJ_DISCOVERY && card->sm_ctx.sm_mode == SM_MODE_TRANSMIT && !(piv_objects[enumtag].flags & PIV_OBJECT_NEEDS_PIN) && !(priv->sm_flags & (PIV_SM_FLAGS_NEVER | PIV_SM_FLAGS_ALWAYS)) && - !(priv->init_flags & ( PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) { - sc_log(card->ctx,"Set PIV_SM_GET_DATA_IN_CLEAR"); + !(priv->init_flags & (PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) { + sc_log(card->ctx, "Set PIV_SM_GET_DATA_IN_CLEAR"); priv->sm_flags |= PIV_SM_GET_DATA_IN_CLEAR; } #endif /* ENABLE_PIV_SM */ - r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, *buf, *buf_len); + r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, *buf, *buf_len); if (r > 0) { int r_tag; unsigned int cla_out, tag_out; @@ -3143,7 +3156,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) goto err; } *buf_len = (body - *buf) + bodylen; - } else if ( r == 0 ) { + } else if (r == 0) { r = SC_ERROR_FILE_NOT_FOUND; goto err; } else { @@ -3157,7 +3170,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) goto err; } memcpy(tbuf, *buf, r); - free (*buf); + free(*buf); alloc_buf = 0; *buf = tbuf; } @@ -3171,12 +3184,11 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) LOG_FUNC_RETURN(card->ctx, r); } - static int -piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) +piv_get_cached_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r; u8 *rbuf = NULL; size_t rbuflen; @@ -3192,7 +3204,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_VALID) { sc_log(card->ctx, - "found #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", + "found #%d %p:%" SC_FORMAT_LEN_SIZE_T "u %p:%" SC_FORMAT_LEN_SIZE_T "u", enumtag, priv->obj_cache[enumtag].obj_data, priv->obj_cache[enumtag].obj_len, @@ -3224,7 +3236,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) } /* Not cached, try to get it, piv_get_data will allocate a buf */ - sc_log(card->ctx, "get #%d", enumtag); + sc_log(card->ctx, "get #%d", enumtag); rbuflen = 1; r = piv_get_data(card, enumtag, &rbuf, &rbuflen); if (r > 0) { @@ -3235,7 +3247,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) *buf_len = r; sc_log(card->ctx, - "added #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", + "added #%d %p:%" SC_FORMAT_LEN_SIZE_T "u %p:%" SC_FORMAT_LEN_SIZE_T "u", enumtag, priv->obj_cache[enumtag].obj_data, priv->obj_cache[enumtag].obj_len, @@ -3258,26 +3270,25 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) LOG_FUNC_RETURN(card->ctx, r); } - static int piv_cache_internal_data(sc_card_t *card, int enumtag) { - piv_private_data_t * priv = PIV_DATA(card); - const u8* tag; - const u8* body; + piv_private_data_t *priv = PIV_DATA(card); + const u8 *tag; + const u8 *body; size_t taglen; size_t bodylen; int compressed = 0; int r = SC_SUCCESS; #ifdef ENABLE_PIV_SM - u8* cvc_start = NULL; + u8 *cvc_start = NULL; size_t cvc_len = 0; #endif /* if already cached */ if (priv->obj_cache[enumtag].internal_obj_data && priv->obj_cache[enumtag].internal_obj_len) { sc_log(card->ctx, - "#%d found internal %p:%"SC_FORMAT_LEN_SIZE_T"u", + "#%d found internal %p:%" SC_FORMAT_LEN_SIZE_T "u", enumtag, priv->obj_cache[enumtag].internal_obj_data, priv->obj_cache[enumtag].internal_obj_len); @@ -3293,7 +3304,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); /* get the certificate out */ - if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_CERT) { + if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_CERT) { tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x71, &taglen); /* 800-72-1 not clear if this is 80 or 01 Sent comment to NIST for 800-72-2 */ @@ -3312,7 +3323,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) if (taglen == 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); - if(compressed) { + if (compressed) { priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_COMPRESSED; } /* internal certificate remains compressed */ @@ -3338,16 +3349,15 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) /* decode the intermediate CVC */ r = piv_decode_cvc(card, &cvc_start, &cvc_len, &priv->sm_in_cvc); if (r < 0) { - sc_log(card->ctx,"unable to parse intermediate CVC: %d skipping",r); + sc_log(card->ctx, "unable to parse intermediate CVC: %d skipping", r); } priv->sm_flags |= PIV_SM_FLAGS_SM_IN_CVC_PRESENT; } } #endif /* ENABLE_PIV_SM */ - /* convert pub key to internal */ - } - else if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) { + /* convert pub key to internal */ + } else if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) { tag = sc_asn1_find_tag(card->ctx, body, bodylen, *body, &taglen); if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); @@ -3360,20 +3370,18 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen); priv->obj_cache[enumtag].internal_obj_len = taglen; - } - else { + } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - sc_log(card->ctx, "added #%d internal %p:%"SC_FORMAT_LEN_SIZE_T"u", - enumtag, - priv->obj_cache[enumtag].internal_obj_data, - priv->obj_cache[enumtag].internal_obj_len); + sc_log(card->ctx, "added #%d internal %p:%" SC_FORMAT_LEN_SIZE_T "u", + enumtag, + priv->obj_cache[enumtag].internal_obj_data, + priv->obj_cache[enumtag].internal_obj_len); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - /* * Callers of this may be expecting a certificate, * select file will have saved the object type for us @@ -3382,7 +3390,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) static int piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t count, unsigned long *flags) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int enumtag; int r; u8 *rbuf = NULL; @@ -3398,10 +3406,10 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co if (priv->rwb_state == -1) { r = piv_get_cached_data(card, enumtag, &rbuf, &rbuflen); - if (r >=0) { + if (r >= 0) { /* an object with no data will be considered not found */ /* Discovery tag = 0x73, all others are 0x53 */ - if (!rbuf || rbuf[0] == 0x00 || ((rbuf[0]&0xDF) == 0x53 && rbuf[1] == 0x00)) { + if (!rbuf || rbuf[0] == 0x00 || ((rbuf[0] & 0xDF) == 0x53 && rbuf[1] == 0x00)) { r = SC_ERROR_FILE_NOT_FOUND; goto err; } @@ -3416,7 +3424,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co } if (bodylen > body - rbuf + rbuflen) { sc_log(card->ctx, - " ***** tag length > then data: %"SC_FORMAT_LEN_SIZE_T"u>%"SC_FORMAT_LEN_PTRDIFF_T"u+%"SC_FORMAT_LEN_SIZE_T"u", + " ***** tag length > then data: %" SC_FORMAT_LEN_SIZE_T "u>%" SC_FORMAT_LEN_PTRDIFF_T "u+%" SC_FORMAT_LEN_SIZE_T "u", bodylen, body - rbuf, rbuflen); r = SC_ERROR_INVALID_DATA; goto err; @@ -3427,7 +3435,6 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co if (r < 0) goto err; } - } priv->rwb_state = 0; } @@ -3444,7 +3451,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co } /* rbuf rbuflen has pointer and length to cached data */ - if ( rbuflen < idx + count) + if (rbuflen < idx + count) count = rbuflen - idx; if (count <= 0) { r = 0; @@ -3458,7 +3465,6 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co LOG_FUNC_RETURN(card->ctx, r); } - /* * the tag is the PIV_OBJ_* * The buf should have the 0x53 tag+len+tags and data @@ -3468,9 +3474,9 @@ static int piv_put_data(sc_card_t *card, int tag, const u8 *buf, size_t buf_len) { int r; - u8 * sbuf; + u8 *sbuf; size_t sbuflen; - u8 * p; + u8 *p; size_t tag_len; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -3502,11 +3508,10 @@ piv_put_data(sc_card_t *card, int tag, const u8 *buf, size_t buf_len) LOG_FUNC_RETURN(card->ctx, r); } - static int -piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned long flags) +piv_write_certificate(sc_card_t *card, const u8 *buf, size_t count, unsigned long flags) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int enumtag, tmplen, tmplen2, tmplen3; int r = SC_SUCCESS; u8 *sbuf = NULL; @@ -3532,8 +3537,8 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); p = sbuf; if ((r = sc_asn1_put_tag(0x53, NULL, taglen, sbuf, sbuflen, &p)) != SC_SUCCESS || - (r = sc_asn1_put_tag(0x70, buf, count, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS || - (r = sc_asn1_put_tag(0x71, NULL, 1, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) { + (r = sc_asn1_put_tag(0x70, buf, count, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS || + (r = sc_asn1_put_tag(0x71, NULL, 1, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) { goto out; } /* Use 01 as per NIST 800-73-3 */ @@ -3571,10 +3576,11 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon * When the last chuck of the data is sent, we will write it. */ -static int piv_write_binary(sc_card_t *card, unsigned int idx, +static int +piv_write_binary(sc_card_t *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r; int enumtag; @@ -3585,7 +3591,7 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, enumtag = piv_objects[priv->selected_obj].enumtag; - if (priv->rwb_state == 1) /* trying to write at end */ + if (priv->rwb_state == 1) /* trying to write at end */ LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); if (priv->rwb_state == -1) { @@ -3598,12 +3604,12 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, if (idx != 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT); - priv->w_buf_len = flags>>8; + priv->w_buf_len = flags >> 8; if (priv->w_buf_len == 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); priv->w_buf = malloc(priv->w_buf_len); - priv-> rwb_state = 0; + priv->rwb_state = 0; } /* on each pass make sure we have w_buf */ @@ -3619,18 +3625,18 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, if (idx + count < priv->w_buf_len) LOG_FUNC_RETURN(card->ctx, (int)count); - priv-> rwb_state = 1; /* at end of object */ + priv->rwb_state = 1; /* at end of object */ switch (flags & 0x0f) { - case 1: - r = piv_write_certificate(card, priv->w_buf, priv->w_buf_len, flags & 0x10); - break; - case 2: /* pubkey to be added to cache, it should have 0x53 and 0x99 tags. */ - r = (int)priv->w_buf_len; - break; - default: - r = piv_put_data(card, enumtag, priv->w_buf, priv->w_buf_len); - break; + case 1: + r = piv_write_certificate(card, priv->w_buf, priv->w_buf_len, flags & 0x10); + break; + case 2: /* pubkey to be added to cache, it should have 0x53 and 0x99 tags. */ + r = (int)priv->w_buf_len; + break; + default: + r = piv_put_data(card, enumtag, priv->w_buf, priv->w_buf_len); + break; } /* if it worked, will cache it */ if (r >= 0 && priv->w_buf) { @@ -3643,7 +3649,7 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, } priv->w_buf = NULL; priv->w_buf_len = 0; - LOG_FUNC_RETURN(card->ctx, (r < 0)? r : (int)count); + LOG_FUNC_RETURN(card->ctx, (r < 0) ? r : (int)count); } /* @@ -3654,42 +3660,50 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, */ #ifdef ENABLE_OPENSSL -static EVP_CIPHER *get_cipher_for_algo(sc_card_t *card, int alg_id) +static EVP_CIPHER * +get_cipher_for_algo(sc_card_t *card, int alg_id) { const char *algo; switch (alg_id) { - case 0x0: - case 0x1: /* 2TDES */ - case 0x3: - algo = "DES-EDE3-ECB"; - break; - case 0x8: - algo = "AES-128-ECB"; - break; - case 0xA: - algo = "AES-192-ECB"; - break; - case 0xC: - algo = "AES-256-ECB"; - break; - default: return NULL; + case 0x0: + case 0x1: /* 2TDES */ + case 0x3: + algo = "DES-EDE3-ECB"; + break; + case 0x8: + algo = "AES-128-ECB"; + break; + case 0xA: + algo = "AES-192-ECB"; + break; + case 0xC: + algo = "AES-256-ECB"; + break; + default: + return NULL; } return sc_evp_cipher(card->ctx, algo); } -static int get_keylen(unsigned int alg_id, size_t *size) +static int +get_keylen(unsigned int alg_id, size_t *size) { - switch(alg_id) { - case 0x01: *size = 192/8; /* 2TDES still has 3 single des keys phase out by 12/31/2010 */ + switch (alg_id) { + case 0x01: + *size = 192 / 8; /* 2TDES still has 3 single des keys phase out by 12/31/2010 */ break; case 0x00: - case 0x03: *size = 192/8; + case 0x03: + *size = 192 / 8; break; - case 0x08: *size = 128/8; + case 0x08: + *size = 128 / 8; break; - case 0x0A: *size = 192/8; + case 0x0A: + *size = 192 / 8; break; - case 0x0C: *size = 256/8; + case 0x0C: + *size = 256 / 8; break; default: return SC_ERROR_INVALID_ARGUMENTS; @@ -3697,17 +3711,18 @@ static int get_keylen(unsigned int alg_id, size_t *size) return SC_SUCCESS; } -static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *len) +static int +piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *len) { int r; size_t fsize; FILE *f = NULL; - char * keyfilename = NULL; + char *keyfilename = NULL; size_t expected_keylen; size_t keylen, readlen; - u8 * keybuf = NULL; - u8 * tkey = NULL; + u8 *keybuf = NULL; + u8 *tkey = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -3715,13 +3730,13 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l if (keyfilename == NULL) { sc_log(card->ctx, - "Unable to get PIV_EXT_AUTH_KEY=(null) for general_external_authenticate"); + "Unable to get PIV_EXT_AUTH_KEY=(null) for general_external_authenticate"); r = SC_ERROR_FILE_NOT_FOUND; goto err; } r = get_keylen(alg_id, &expected_keylen); - if(r) { + if (r) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; goto err; @@ -3737,22 +3752,22 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l if (0 > fseek(f, 0L, SEEK_END)) r = SC_ERROR_INTERNAL; fsize = ftell(f); - if (0 > (long) fsize) + if (0 > (long)fsize) r = SC_ERROR_INTERNAL; if (0 > fseek(f, 0L, SEEK_SET)) r = SC_ERROR_INTERNAL; - if(r) { + if (r) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s\n", keyfilename); goto err; } - keybuf = malloc(fsize+1); /* if not binary, need null to make it a string */ + keybuf = malloc(fsize + 1); /* if not binary, need null to make it a string */ if (!keybuf) { sc_log(card->ctx, " Unable to allocate key memory"); r = SC_ERROR_OUT_OF_MEMORY; goto err; } - keybuf[fsize] = 0x00; /* in case it is text need null */ + keybuf[fsize] = 0x00; /* in case it is text need null */ if ((readlen = fread(keybuf, 1, fsize, f)) != fsize) { sc_log(card->ctx, " Unable to read key\n"); @@ -3776,7 +3791,7 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l sc_right_trim(keybuf, fsize); keylen = expected_keylen; r = sc_hex_to_bin((char *)keybuf, tkey, &keylen); - if (keylen !=expected_keylen || r != 0 ) { + if (keylen != expected_keylen || r != 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error formatting key\n"); if (r == 0) r = SC_ERROR_INCOMPATIBLE_KEY; @@ -3810,8 +3825,9 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l * challenges, nonces etc from card are less then 114 (keeps tags simple) */ -static int piv_general_mutual_authenticate(sc_card_t *card, - unsigned int key_ref, unsigned int alg_id) +static int +piv_general_mutual_authenticate(sc_card_t *card, + unsigned int key_ref, unsigned int alg_id) { int r; #ifdef ENABLE_OPENSSL @@ -3837,7 +3853,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, size_t challenge_response_len; u8 *decrypted_reponse = NULL; size_t decrypted_reponse_len; - EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER_CTX *ctx = NULL; u8 sbuf[255]; EVP_CIPHER *cipher = NULL; @@ -3852,7 +3868,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, } cipher = get_cipher_for_algo(card, alg_id); - if(!cipher) { + if (!cipher) { sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; @@ -3881,23 +3897,24 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* get the encrypted nonce */ r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf); - if (r < 0) goto err; + if (r < 0) + goto err; /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, - r, 0x7C, &body_len); + r, 0x7C, &body_len); if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } /* Get the witness data indicated by the TAG 0x80 */ witness_data = sc_asn1_find_tag(card->ctx, body, - body_len, 0x80, &witness_len); + body_len, 0x80, &witness_len); if (!witness_len || body_len == 0 || body[0] != 0x80) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data none found in TLV\n"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } @@ -3916,7 +3933,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - EVP_CIPHER_CTX_set_padding(ctx,0); + EVP_CIPHER_CTX_set_padding(ctx, 0); p = plain_text; if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, (int)witness_len)) { @@ -3927,7 +3944,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, plain_text_len = tmplen = N; p += tmplen; - if(!EVP_DecryptFinal(ctx, p, &N)) { + if (!EVP_DecryptFinal(ctx, p, &N)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; @@ -3937,8 +3954,8 @@ static int piv_general_mutual_authenticate(sc_card_t *card, if (plain_text_len != witness_len) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Encrypted and decrypted lengths do not match: %"SC_FORMAT_LEN_SIZE_T"u:%"SC_FORMAT_LEN_SIZE_T"u\n", - witness_len, plain_text_len); + "Encrypted and decrypted lengths do not match: %" SC_FORMAT_LEN_SIZE_T "u:%" SC_FORMAT_LEN_SIZE_T "u\n", + witness_len, plain_text_len); r = SC_ERROR_INTERNAL; goto err; } @@ -3950,21 +3967,21 @@ static int piv_general_mutual_authenticate(sc_card_t *card, * the card. */ nonce = malloc(witness_len); - if(!nonce) { + if (!nonce) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "OOM allocating nonce (%"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u)\n", - witness_len, plain_text_len); + "OOM allocating nonce (%" SC_FORMAT_LEN_SIZE_T "u : %" SC_FORMAT_LEN_SIZE_T "u)\n", + witness_len, plain_text_len); r = SC_ERROR_INTERNAL; goto err; } nonce_len = witness_len; r = RAND_bytes(nonce, (int)witness_len); - if(!r) { + if (!r) { sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Generating random for nonce (%"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u)\n", - witness_len, plain_text_len); + "Generating random for nonce (%" SC_FORMAT_LEN_SIZE_T "u : %" SC_FORMAT_LEN_SIZE_T "u)\n", + witness_len, plain_text_len); r = SC_ERROR_INTERNAL; goto err; } @@ -3997,7 +4014,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Build the response buffer */ p = built = malloc(built_len); - if(!built) { + if (!built) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "OOM Building witness response and challenge\n"); r = SC_ERROR_INTERNAL; goto err; @@ -4031,31 +4048,31 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, - r, 0x7C, &body_len); - if(!body || rbuf[0] != 0x7C) { + r, 0x7C, &body_len); + if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } /* SP800-73 not clear if 80 or 82 */ challenge_response = sc_asn1_find_tag(card->ctx, body, - body_len, 0x82, &challenge_response_len); - if(!challenge_response) { + body_len, 0x82, &challenge_response_len); + if (!challenge_response) { challenge_response = sc_asn1_find_tag(card->ctx, body, body_len, 0x80, &challenge_response_len); - if(!challenge_response) { + if (!challenge_response) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find tag 0x82 or 0x80 in response"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } } /* Decrypt challenge and check against nonce */ decrypted_reponse = malloc(challenge_response_len); - if(!decrypted_reponse) { + if (!decrypted_reponse) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "OOM Allocating decryption buffer"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } @@ -4066,7 +4083,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = SC_ERROR_INTERNAL; goto err; } - EVP_CIPHER_CTX_set_padding(ctx,0); + EVP_CIPHER_CTX_set_padding(ctx, 0); tmp = decrypted_reponse; if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, (int)challenge_response_len)) { @@ -4077,7 +4094,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, decrypted_reponse_len = tmplen = N; tmp += tmplen; - if(!EVP_DecryptFinal(ctx, tmp, &N)) { + if (!EVP_DecryptFinal(ctx, tmp, &N)) { sc_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; @@ -4087,7 +4104,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, if (decrypted_reponse_len != nonce_len || memcmp(nonce, decrypted_reponse, nonce_len) != 0) { sc_log(card->ctx, - "mutual authentication failed, card returned wrong value %"SC_FORMAT_LEN_SIZE_T"u:%"SC_FORMAT_LEN_SIZE_T"u", + "mutual authentication failed, card returned wrong value %" SC_FORMAT_LEN_SIZE_T "u:%" SC_FORMAT_LEN_SIZE_T "u", decrypted_reponse_len, nonce_len); r = SC_ERROR_DECRYPT_FAILED; goto err; @@ -4119,9 +4136,9 @@ static int piv_general_mutual_authenticate(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } - /* Currently only used for card administration */ -static int piv_general_external_authenticate(sc_card_t *card, +static int +piv_general_external_authenticate(sc_card_t *card, unsigned int key_ref, unsigned int alg_id) { int r; @@ -4142,7 +4159,7 @@ static int piv_general_external_authenticate(sc_card_t *card, size_t keylen = 0; size_t cipher_text_len = 0; u8 sbuf[255]; - EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *cipher = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -4157,7 +4174,7 @@ static int piv_general_external_authenticate(sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id); cipher = get_cipher_for_algo(card, alg_id); - if(!cipher) { + if (!cipher) { sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; @@ -4198,19 +4215,19 @@ static int piv_general_external_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, - r, 0x7C, &body_len); + r, 0x7C, &body_len); if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } /* Get the challenge data indicated by the TAG 0x81 */ challenge_data = sc_asn1_find_tag(card->ctx, body, - body_len, 0x81, &challenge_len); + body_len, 0x81, &challenge_len); if (!challenge_data) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data none found in TLV\n"); - r = SC_ERROR_INVALID_DATA; + r = SC_ERROR_INVALID_DATA; goto err; } @@ -4232,7 +4249,7 @@ static int piv_general_external_authenticate(sc_card_t *card, goto err; } - EVP_CIPHER_CTX_set_padding(ctx,0); + EVP_CIPHER_CTX_set_padding(ctx, 0); if (!EVP_EncryptUpdate(ctx, cipher_text, &outlen, challenge_data, (int)challenge_len)) { sc_log_openssl(card->ctx); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n"); @@ -4261,7 +4278,7 @@ static int piv_general_external_authenticate(sc_card_t *card, } output_buf = malloc(output_len); - if(!output_buf) { + if (!output_buf) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not allocate output buffer: %s\n", strerror(errno)); r = SC_ERROR_INTERNAL; @@ -4301,7 +4318,8 @@ static int piv_general_external_authenticate(sc_card_t *card, tmplen = sc_asn1_put_tag(0x7C, NULL, tmplen, NULL, 0, NULL); if (output_len != (size_t)tmplen) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Allocated and computed lengths do not match! " - "Expected %"SC_FORMAT_LEN_SIZE_T"d, found: %zu\n", output_len, tmplen); + "Expected %" SC_FORMAT_LEN_SIZE_T "d, found: %zu\n", + output_len, tmplen); r = SC_ERROR_INTERNAL; goto err; } @@ -4335,12 +4353,11 @@ static int piv_general_external_authenticate(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } - /* * with sp800-73-4 and SM GUID is also in sm_cvc.subjectID */ static int -piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) +piv_get_serial_nr_from_CHUI(sc_card_t *card, sc_serial_number_t *serial) { int r; int i; @@ -4353,7 +4370,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) size_t rbuflen = 0, bodylen, fascnlen, guidlen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card->serialnr.len) { + if (card->serialnr.len) { *serial = card->serialnr; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -4388,24 +4405,24 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) } } sc_log(card->ctx, - "fascn=%p,fascnlen=%"SC_FORMAT_LEN_SIZE_T"u,guid=%p,guidlen=%"SC_FORMAT_LEN_SIZE_T"u,gbits=%2.2x", + "fascn=%p,fascnlen=%" SC_FORMAT_LEN_SIZE_T "u,guid=%p,guidlen=%" SC_FORMAT_LEN_SIZE_T "u,gbits=%2.2x", fascn, fascnlen, guid, guidlen, gbits); if (fascn && fascnlen == 25 && fbits) { /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ /* ;9999 is non-gov issued FASC-N, will use FASC-N for gov issued if no guid */ if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 && - fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { + fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { /* fascnlen is 25 */ serial->len = fascnlen; - memcpy (serial->value, fascn, serial->len); + memcpy(serial->value, fascn, serial->len); r = SC_SUCCESS; gbits = 0; /* set to skip using guid below */ } } if (guid && guidlen == 16 && gbits) { serial->len = guidlen; - memcpy (serial->value, guid, serial->len); + memcpy(serial->value, guid, serial->len); r = SC_SUCCESS; } } @@ -4432,9 +4449,10 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) * pkcs15-piv.c calls this via cardctl. */ -static int piv_is_object_present(sc_card_t *card, u8 *ptr) +static int +piv_is_object_present(sc_card_t *card, u8 *ptr) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r = 0; int enumtag; @@ -4450,57 +4468,60 @@ static int piv_is_object_present(sc_card_t *card, u8 *ptr) * or the global pin for the card 0x00. Look at Discovery object to get this. * called by pkcs15-piv.c via cardctl when setting up the pins. */ -static int piv_get_pin_preference(sc_card_t *card, int *pin_ref) +static int +piv_get_pin_preference(sc_card_t *card, int *pin_ref) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); *pin_ref = priv->pin_preference; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) +static int +piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) { - piv_private_data_t * priv = PIV_DATA(card); - u8 * opts; /* A or M, key_ref, alg_id */ + piv_private_data_t *priv = PIV_DATA(card); + u8 *opts; /* A or M, key_ref, alg_id */ LOG_FUNC_CALLED(card->ctx); if (priv == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - switch(cmd) { - case SC_CARDCTL_PIV_AUTHENTICATE: - opts = (u8 *)ptr; - switch (*opts) { - case 'A': - return piv_general_external_authenticate(card, - *(opts+1), *(opts+2)); - break; - case 'M': - return piv_general_mutual_authenticate(card, - *(opts+1), *(opts+2)); - break; - } - break; - case SC_CARDCTL_PIV_GENERATE_KEY: - return piv_generate_key(card, - (sc_cardctl_piv_genkey_info_t *) ptr); + switch (cmd) { + case SC_CARDCTL_PIV_AUTHENTICATE: + opts = (u8 *)ptr; + switch (*opts) { + case 'A': + return piv_general_external_authenticate(card, + *(opts + 1), *(opts + 2)); break; - case SC_CARDCTL_GET_SERIALNR: - return piv_get_serial_nr_from_CHUI(card, (sc_serial_number_t *) ptr); - break; - case SC_CARDCTL_PIV_PIN_PREFERENCE: - return piv_get_pin_preference(card, ptr); - break; - case SC_CARDCTL_PIV_OBJECT_PRESENT: - return piv_is_object_present(card, ptr); + case 'M': + return piv_general_mutual_authenticate(card, + *(opts + 1), *(opts + 2)); break; + } + break; + case SC_CARDCTL_PIV_GENERATE_KEY: + return piv_generate_key(card, + (sc_cardctl_piv_genkey_info_t *)ptr); + break; + case SC_CARDCTL_GET_SERIALNR: + return piv_get_serial_nr_from_CHUI(card, (sc_serial_number_t *)ptr); + break; + case SC_CARDCTL_PIV_PIN_PREFERENCE: + return piv_get_pin_preference(card, ptr); + break; + case SC_CARDCTL_PIV_OBJECT_PRESENT: + return piv_is_object_present(card, ptr); + break; } LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } -static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) +static int +piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) { /* Dynamic Authentication Template (Challenge) */ u8 sbuf[] = {0x7c, 0x02, 0x81, 0x00}; @@ -4509,7 +4530,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) size_t out_len = 0; int r; unsigned int tag_out = 0, cla_out = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); @@ -4527,7 +4548,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) * and return "6A 80" if last command was a get_challenge. * Now that the card returned error, we can try one more time. */ - if (r == SC_ERROR_INCORRECT_PARAMETERS) { + if (r == SC_ERROR_INCORRECT_PARAMETERS) { r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, rbuf, sizeof rbuf); if (r == SC_ERROR_INCORRECT_PARAMETERS) { r = SC_ERROR_NOT_SUPPORTED; @@ -4537,12 +4558,12 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) p = rbuf; r = sc_asn1_read_tag(&p, r, &cla_out, &tag_out, &out_len); - if (r < 0 || (cla_out|tag_out) != 0x7C) { + if (r < 0 || (cla_out | tag_out) != 0x7C) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template"); } r = sc_asn1_read_tag(&p, out_len, &cla_out, &tag_out, &out_len); - if (r < 0 || (cla_out|tag_out) != 0x81) { + if (r < 0 || (cla_out | tag_out) != 0x81) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge"); } @@ -4551,23 +4572,22 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) } memcpy(rnd, p, out_len); - r = (int) out_len; + r = (int)out_len; err: LOG_FUNC_RETURN(card->ctx, r); - } static int piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, - "flags=%08lx op=%d alg=%lu algf=%08lx algr=%08lx kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u", + "flags=%08lx op=%d alg=%lu algf=%08lx algr=%08lx kr0=%02x, krfl=%" SC_FORMAT_LEN_SIZE_T "u", env->flags, env->operation, env->algorithm, env->algorithm_flags, env->algorithm_ref, env->key_ref[0], env->key_ref_len); @@ -4579,16 +4599,16 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) } else if (env->algorithm == SC_ALGORITHM_EC) { if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) { switch (env->algorithm_ref) { - case 256: - priv->alg_id = 0x11; /* Say it is EC 256 */ - priv->key_size = 256; - break; - case 384: - priv->alg_id = 0x14; - priv->key_size = 384; - break; - default: - r = SC_ERROR_NO_CARD_SUPPORT; + case 256: + priv->alg_id = 0x11; /* Say it is EC 256 */ + priv->key_size = 256; + break; + case 384: + priv->alg_id = 0x14; + priv->key_size = 384; + break; + default: + r = SC_ERROR_NO_CARD_SUPPORT; } } else r = SC_ERROR_NO_CARD_SUPPORT; @@ -4605,20 +4625,20 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_restore_security_env(sc_card_t *card, int se_num) +static int +piv_restore_security_env(sc_card_t *card, int se_num) { LOG_FUNC_CALLED(card->ctx); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - -static int piv_validate_general_authentication(sc_card_t *card, - const u8 * data, size_t datalen, - u8 * out, size_t outlen) +static int +piv_validate_general_authentication(sc_card_t *card, + const u8 *data, size_t datalen, + u8 *out, size_t outlen) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r, tmplen, tmplen2; u8 *p; const unsigned char *p2; @@ -4642,7 +4662,7 @@ static int piv_validate_general_authentication(sc_card_t *card, } tmplen += tmplen2; if ((r = sc_asn1_put_tag(0x7c, NULL, tmplen, p, sbuflen, &p)) != SC_SUCCESS || - (r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) { + (r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) { LOG_FUNC_RETURN(card->ctx, r); } if (priv->operation == SC_SEC_OPERATION_DERIVE && (priv->algorithm == SC_ALGORITHM_EC || priv->algorithm == SC_ALGORITHM_XEDDSA)) { @@ -4664,15 +4684,21 @@ static int piv_validate_general_authentication(sc_card_t *card, real_alg_id = priv->alg_id; if (priv->alg_id == 0x06) { - switch (datalen) { - case 128: real_alg_id = 0x06; break; - case 256: real_alg_id = 0x07; break; - case 384: real_alg_id = 0x05; break; - case 512: - real_alg_id = 0x16; - break; - default: - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); + switch (datalen) { + case 128: + real_alg_id = 0x06; + break; + case 256: + real_alg_id = 0x07; + break; + case 384: + real_alg_id = 0x05; + break; + case 512: + real_alg_id = 0x16; + break; + default: + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); } } /* EC and ED alg_id was already set */ @@ -4684,12 +4710,12 @@ static int piv_validate_general_authentication(sc_card_t *card, p2 = rbuf; r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen); - if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) { + if (p2 == NULL || r < 0 || bodylen == 0 || (cla | tag) != 0x7C) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C"); } r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen); - if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) { + if (p2 == NULL || r < 0 || taglen == 0 || (cla | tag) != 0x82) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82"); } @@ -4704,12 +4730,11 @@ static int piv_validate_general_authentication(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, r); } - static int -piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, - u8 * out, size_t outlen) +piv_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + u8 *out, size_t outlen) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r; size_t nLen; u8 rbuf[128]; /* For EC conversions 384 will fit */ @@ -4722,11 +4747,11 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, * and pad on left if too short. */ - if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) { + if (priv->alg_id == 0x11 || priv->alg_id == 0x14) { nLen = BYTES4BITS(priv->key_size); - if (outlen < 2*nLen) { + if (outlen < 2 * nLen) { sc_log(card->ctx, - " output too small for EC signature %"SC_FORMAT_LEN_SIZE_T"u < %"SC_FORMAT_LEN_SIZE_T"u", + " output too small for EC signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u", outlen, 2 * nLen); r = SC_ERROR_INVALID_DATA; goto err; @@ -4757,9 +4782,8 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } - static int -piv_decipher(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen) +piv_decipher(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -4776,16 +4800,17 @@ piv_decipher(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t * All other requests should be to read. * Only if file_out != null, will we read to get length. */ -static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, - sc_file_t **file_out) +static int +piv_select_file(sc_card_t *card, const sc_path_t *in_path, + sc_file_t **file_out) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r; int i; const u8 *path; size_t pathlen; sc_file_t *file = NULL; - u8 * rbuf = NULL; + u8 *rbuf = NULL; size_t rbuflen = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -4847,7 +4872,7 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, file->path = *in_path; /* this could be like the FCI */ - file->type = SC_FILE_TYPE_DF; + file->type = SC_FILE_TYPE_DF; file->shareable = 0; file->ef_structure = 0; if (priv->return_only_cert) @@ -4855,45 +4880,45 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, else file->size = priv->obj_cache[i].obj_len; - file->id = (piv_objects[i].containerid[0]<<8) + piv_objects[i].containerid[1]; + file->id = (piv_objects[i].containerid[0] << 8) + piv_objects[i].containerid[1]; *file_out = file; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); - } -static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int aid_only) +static int +piv_parse_discovery(sc_card_t *card, u8 *rbuf, size_t rbuflen, int aid_only) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r = 0; - const u8 * body; + const u8 *body; size_t bodylen; - const u8 * aid; + const u8 *aid; size_t aidlen; - const u8 * pinp; + const u8 *pinp; size_t pinplen; unsigned int cla_out, tag_out; if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || body == NULL || bodylen == 0 || - ((cla_out|tag_out) != 0x7E)) { - sc_log(card->ctx, "DER problem %d",r); + ((cla_out | tag_out) != 0x7E)) { + sc_log(card->ctx, "DER problem %d", r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } sc_log(card->ctx, - "Discovery 0x%2.2x 0x%2.2x %p:%"SC_FORMAT_LEN_SIZE_T"u", + "Discovery 0x%2.2x 0x%2.2x %p:%" SC_FORMAT_LEN_SIZE_T "u", cla_out, tag_out, body, bodylen); aidlen = 0; aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen); if (aid == NULL || aidlen < piv_aids[0].len_short || - memcmp(aid,piv_aids[0].value,piv_aids[0].len_short) != 0) { + memcmp(aid, piv_aids[0].value, piv_aids[0].len_short) != 0) { sc_log(card->ctx, "Discovery object not PIV"); r = SC_ERROR_INVALID_CARD; /* This is an error */ goto err; @@ -4903,9 +4928,8 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a if (pinp && pinplen == 2) { priv->init_flags |= PIV_INIT_DISCOVERY_PP; priv->pin_policy = (*pinp << 8) + *(pinp + 1); - sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); - if ((priv->pin_policy & (PIV_PP_PIN | PIV_PP_GLOBAL)) - == (PIV_PP_PIN | PIV_PP_GLOBAL) && + sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x", *pinp, *(pinp + 1)); + if ((priv->pin_policy & (PIV_PP_PIN | PIV_PP_GLOBAL)) == (PIV_PP_PIN | PIV_PP_GLOBAL) && priv->pin_policy & PIV_PP_GLOBAL_PRIMARY) { sc_log(card->ctx, "Pin Preference - Global"); priv->pin_preference = 0x00; @@ -4920,12 +4944,12 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a LOG_FUNC_RETURN(card->ctx, r); } - /* normal way to get the discovery object via cache */ -static int piv_process_discovery(sc_card_t *card) +static int +piv_process_discovery(sc_card_t *card) { int r; - u8 * rbuf = NULL; + u8 *rbuf = NULL; size_t rbuflen = 0; r = piv_get_cached_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen); @@ -4945,33 +4969,34 @@ static int piv_process_discovery(sc_card_t *card) * We read the CCC using the PIV API. * Look for CAC RID=A0 00 00 00 79 */ -static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) +static int +piv_parse_ccc(sc_card_t *card, u8 *rbuf, size_t rbuflen) { int r = 0; - const u8 * body; + const u8 *body; size_t bodylen; unsigned int cla_out, tag_out; - u8 tag; - const u8 * end; + u8 tag; + const u8 *end; size_t len; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (rbuf == NULL || rbuflen == 0) { r = SC_ERROR_WRONG_LENGTH; - goto err; + goto err; } /* Outer layer is a DER tlv */ body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || body == NULL || bodylen == 0 || ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_CCC].resp_tag)) { - sc_log(card->ctx, "DER problem %d",r); + sc_log(card->ctx, "DER problem %d", r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -4980,27 +5005,27 @@ static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) /* CCC entries are simple tlv */ end = body + bodylen; - for(; (body < end); body += len) { - r = sc_simpletlv_read_tag(&body, end - body , &tag, &len); + for (; (body < end); body += len) { + r = sc_simpletlv_read_tag(&body, end - body, &tag, &len); if (r < 0) goto err; switch (tag) { - case PIV_CCC_TAG_F0: - if (len == 0x15) { - if (memcmp(body ,"\xA0\x00\x00\x03\08", 5) == 0) - priv->ccc_flags |= PIV_CCC_F0_PIV; - else if (memcmp(body ,"\xA0\x00\x00\x00\x79", 5) == 0) - priv->ccc_flags |= PIV_CCC_F0_CAC; - if (*(body + 6) == 0x02) - priv->ccc_flags |= PIV_CCC_F0_JAVA; - } - break; - case PIV_CCC_TAG_F3: - if (len == 0x10) { - if (memcmp(body ,"\xA0\x00\x00\x00\x79\x04", 6) == 0) - priv->ccc_flags |= PIV_CCC_F3_CAC_PKI; - } - break; + case PIV_CCC_TAG_F0: + if (len == 0x15) { + if (memcmp(body, "\xA0\x00\x00\x03\08", 5) == 0) + priv->ccc_flags |= PIV_CCC_F0_PIV; + else if (memcmp(body, "\xA0\x00\x00\x00\x79", 5) == 0) + priv->ccc_flags |= PIV_CCC_F0_CAC; + if (*(body + 6) == 0x02) + priv->ccc_flags |= PIV_CCC_F0_JAVA; + } + break; + case PIV_CCC_TAG_F3: + if (len == 0x10) { + if (memcmp(body, "\xA0\x00\x00\x00\x79\x04", 6) == 0) + priv->ccc_flags |= PIV_CCC_F3_CAC_PKI; + } + break; } } @@ -5008,10 +5033,11 @@ static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) LOG_FUNC_RETURN(card->ctx, r); } -static int piv_process_ccc(sc_card_t *card) +static int +piv_process_ccc(sc_card_t *card) { int r = 0; - u8 * rbuf = NULL; + u8 *rbuf = NULL; size_t rbuflen = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -5026,13 +5052,13 @@ static int piv_process_ccc(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_find_discovery(sc_card_t *card) +static int +piv_find_discovery(sc_card_t *card) { int r = 0; size_t rbuflen; - u8 * rbuf = NULL; - piv_private_data_t * priv = PIV_DATA(card); + u8 *rbuf = NULL; + piv_private_data_t *priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -5054,16 +5080,16 @@ static int piv_find_discovery(sc_card_t *card) rbuflen = 1; r = piv_get_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen); /* if same response as last, no need to parse */ - if ( r == 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == 0) + if (r == 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == 0) goto end; if (r >= 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == rbuflen && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data && !memcmp(rbuf, priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data, rbuflen)) { - goto end; + goto end; } /* This should not happen bad card */ - sc_log(card->ctx,"Discovery not the same as previously read object"); + sc_log(card->ctx, "Discovery not the same as previously read object"); r = SC_ERROR_CORRUPTED_DATA; goto end; } @@ -5073,7 +5099,6 @@ static int piv_find_discovery(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - /* * The history object lists what retired keys and certs are on the card * or listed in the offCardCertURL. The user will need to download the @@ -5083,49 +5108,48 @@ static int piv_find_discovery(sc_card_t *card) static int piv_process_history(sc_card_t *card) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int r; int i, tmplen, tmplen2, tmplen3; int enumtag; - u8 * rbuf = NULL; + u8 *rbuf = NULL; size_t rbuflen = 0; - const u8 * body; + const u8 *body; size_t bodylen; - const u8 * num; + const u8 *num; size_t numlen; - const u8 * url = NULL; + const u8 *url = NULL; size_t urllen; - u8 * ocfhfbuf = NULL; + u8 *ocfhfbuf = NULL; unsigned int cla_out, tag_out; size_t ocfhflen; - const u8 * seq; - const u8 * seqtag; + const u8 *seq; + const u8 *seqtag; size_t seqlen; - const u8 * keyref; + const u8 *keyref; size_t keyreflen; - const u8 * cert; + const u8 *cert; size_t certlen; size_t certobjlen, i2; - u8 * certobj; - u8 * cp; - + u8 *certobj; + u8 *cp; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); r = piv_get_cached_data(card, PIV_OBJ_HISTORY, &rbuf, &rbuflen); if (r == SC_ERROR_FILE_NOT_FOUND) - r = 0; /* OK if not found */ + r = 0; /* OK if not found */ if (r <= 0) { priv->obj_cache[PIV_OBJ_HISTORY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - goto err; /* no file, must be pre 800-73-3 card and not on card */ + goto err; /* no file, must be pre 800-73-3 card and not on card */ } /* the object is now cached, see what we have */ if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS || ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_HISTORY].resp_tag)) { - sc_log(card->ctx, "DER problem %d",r); + sc_log(card->ctx, "DER problem %d", r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -5134,7 +5158,7 @@ piv_process_history(sc_card_t *card) numlen = 0; num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC1, &numlen); if (num) { - if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20-PIV_OBJ_RETIRED_X509_1+1) { + if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20 - PIV_OBJ_RETIRED_X509_1 + 1) { r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -5145,7 +5169,7 @@ piv_process_history(sc_card_t *card) numlen = 0; num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC2, &numlen); if (num) { - if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20-PIV_OBJ_RETIRED_X509_1+1) { + if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20 - PIV_OBJ_RETIRED_X509_1 + 1) { r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -5159,25 +5183,24 @@ piv_process_history(sc_card_t *card) r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } - priv->offCardCertURL = calloc(1,urllen+1); + priv->offCardCertURL = calloc(1, urllen + 1); if (priv->offCardCertURL == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(priv->offCardCertURL, url, urllen); } - } - else { + } else { sc_log(card->ctx, "Problem with History object\n"); - r = SC_SUCCESS; /* OK if not found */ + r = SC_SUCCESS; /* OK if not found */ goto err; } } sc_log(card->ctx, "History on=%d off=%d URL=%s", priv->keysWithOnCardCerts, priv->keysWithOffCardCerts, - priv->offCardCertURL ? priv->offCardCertURL:"NONE"); + priv->offCardCertURL ? priv->offCardCertURL : "NONE"); /* now mark what objects are on the card */ - for (i=0; ikeysWithOnCardCerts; i++) - priv->obj_cache[PIV_OBJ_RETIRED_X509_1+i].flags &= ~PIV_OBJ_CACHE_NOT_PRESENT; + for (i = 0; i < priv->keysWithOnCardCerts; i++) + priv->obj_cache[PIV_OBJ_RETIRED_X509_1 + i].flags &= ~PIV_OBJ_CACHE_NOT_PRESENT; /* * If user has gotten copy of the file from the offCardCertsURL, @@ -5192,7 +5215,7 @@ piv_process_history(sc_card_t *card) r = 0; if (priv->offCardCertURL) { - char * fp; + char *fp; char filename[PATH_MAX]; if (strncmp("http://", priv->offCardCertURL, 7)) { @@ -5200,7 +5223,7 @@ piv_process_history(sc_card_t *card) goto err; } /* find the last / so we have the filename part */ - fp = strrchr(priv->offCardCertURL + 7,'/'); + fp = strrchr(priv->offCardCertURL + 7, '/'); if (fp == NULL) { r = SC_ERROR_INVALID_DATA; goto err; @@ -5229,7 +5252,7 @@ piv_process_history(sc_card_t *card) strlcat(filename, fp, PATH_MAX); r = piv_read_obj_from_file(card, filename, - &ocfhfbuf, &ocfhflen); + &ocfhfbuf, &ocfhflen); if (r == SC_ERROR_FILE_NOT_FOUND) { r = 0; goto err; @@ -5243,7 +5266,7 @@ piv_process_history(sc_card_t *card) if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS || body == NULL || bodylen == 0 || - (cla_out|tag_out) != 0x30) { + (cla_out | tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5254,7 +5277,7 @@ piv_process_history(sc_card_t *card) if (sc_asn1_read_tag(&seq, bodylen, &cla_out, &tag_out, &seqlen) != SC_SUCCESS || seq == 0 || seqlen == 0 || - (cla_out|tag_out) != 0x30) { + (cla_out | tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -5273,8 +5296,8 @@ piv_process_history(sc_card_t *card) /* now add the cert like another object */ if ((tmplen = sc_asn1_put_tag(0x70, NULL, certlen, NULL, 0, NULL)) <= 0 || - (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 || - (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) { + (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 || + (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) { r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -5293,8 +5316,8 @@ piv_process_history(sc_card_t *card) } cp = certobj; if ((r = sc_asn1_put_tag(0x53, NULL, i2, cp, certobjlen, &cp)) != SC_SUCCESS || - (r = sc_asn1_put_tag(0x70, cert, certlen, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS || - (r = sc_asn1_put_tag(0x71, NULL, 1, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS) { + (r = sc_asn1_put_tag(0x70, cert, certlen, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS || + (r = sc_asn1_put_tag(0x71, NULL, 1, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS) { goto err; } *cp++ = 0x00; @@ -5309,13 +5332,13 @@ piv_process_history(sc_card_t *card) priv->obj_cache[enumtag].flags &= ~PIV_OBJ_CACHE_NOT_PRESENT; r = piv_cache_internal_data(card, enumtag); - sc_log(card->ctx, "got internal r=%d",r); + sc_log(card->ctx, "got internal r=%d", r); sc_log(card->ctx, - "Added from off card file #%d %p:%"SC_FORMAT_LEN_SIZE_T"u 0x%02X", - enumtag, - priv->obj_cache[enumtag].obj_data, - priv->obj_cache[enumtag].obj_len, *keyref); + "Added from off card file #%d %p:%" SC_FORMAT_LEN_SIZE_T "u 0x%02X", + enumtag, + priv->obj_cache[enumtag].obj_data, + priv->obj_cache[enumtag].obj_len, *keyref); bodylen -= (seqlen + seq - seqtag); seq += seqlen; @@ -5330,7 +5353,7 @@ piv_process_history(sc_card_t *card) static int piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); if (priv->obj_cache[enumtag].obj_data) free(priv->obj_cache[enumtag].obj_data); @@ -5343,13 +5366,13 @@ piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags) priv->obj_cache[enumtag].internal_obj_len = 0; priv->obj_cache[enumtag].flags = flags; -return SC_SUCCESS; + return SC_SUCCESS; } static int piv_finish(sc_card_t *card) { - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); int i; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -5380,35 +5403,36 @@ piv_finish(sc_card_t *card) return 0; } -static int piv_match_card(sc_card_t *card) +static int +piv_match_card(sc_card_t *card) { int r = 0; - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type); /* piv_match_card may be called with card->type, set by opensc.conf */ /* user provided card type must be one we know */ switch (card->type) { - case -1: - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_NEO: - case SC_CARD_TYPE_PIV_II_YUBIKEY4: - case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GI_DE: - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO: - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - case SC_CARD_TYPE_PIV_II_PIVKEY: - case SC_CARD_TYPE_PIV_II_SWISSBIT: - case SC_CARD_TYPE_PIV_II_800_73_4: - case SC_CARD_TYPE_PIV_II_NITROKEY: - case SC_CARD_TYPE_PIV_II_TOKEN2: - case SC_CARD_TYPE_PIV_II_PIVAPPLET: - break; - default: - return 0; /* can not handle the card */ + case -1: + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_PIVKEY: + case SC_CARD_TYPE_PIV_II_SWISSBIT: + case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + break; + default: + return 0; /* can not handle the card */ } r = sc_lock(card); @@ -5424,15 +5448,15 @@ static int piv_match_card(sc_card_t *card) return 0; /* match failed */ } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type,r); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type, r); return 1; /* matched */ } - -static int piv_match_card_continued(sc_card_t *card) +static int +piv_match_card_continued(sc_card_t *card) { int i, r = 0, r2 = 0; - int type = -1; + int type = -1; piv_private_data_t *priv = NULL; int saved_type = card->type; sc_apdu_t apdu; @@ -5442,30 +5466,30 @@ static int piv_match_card_continued(sc_card_t *card) /* User provided card type must be one we know */ switch (card->type) { - case -1: - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_NEO: - case SC_CARD_TYPE_PIV_II_YUBIKEY4: - case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GI_DE: - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO: - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - case SC_CARD_TYPE_PIV_II_PIVKEY: - case SC_CARD_TYPE_PIV_II_SWISSBIT: - case SC_CARD_TYPE_PIV_II_800_73_4: - case SC_CARD_TYPE_PIV_II_NITROKEY: - case SC_CARD_TYPE_PIV_II_TOKEN2: - case SC_CARD_TYPE_PIV_II_PIVAPPLET: - type = card->type; - break; - default: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); + case -1: + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_PIVKEY: + case SC_CARD_TYPE_PIV_II_SWISSBIT: + case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + type = card->type; + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); if (type == -1) { /* * Try to identify card by ATR or historical data in ATR @@ -5478,16 +5502,13 @@ static int piv_match_card_continued(sc_card_t *card) if (card->reader->atr_info.hist_bytes_len == 8 && !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey4", 8))) { type = SC_CARD_TYPE_PIV_II_YUBIKEY4; - } - else if (card->reader->atr_info.hist_bytes_len >= 7 && + } else if (card->reader->atr_info.hist_bytes_len >= 7 && !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) { type = SC_CARD_TYPE_PIV_II_NEO; - } - else if (card->reader->atr_info.hist_bytes_len >= 6 && + } else if (card->reader->atr_info.hist_bytes_len >= 6 && !(memcmp(card->reader->atr_info.hist_bytes, "PIVKEY", 6))) { type = SC_CARD_TYPE_PIV_II_PIVKEY; - } - else if (card->reader->atr_info.hist_bytes_len >= 6 && + } else if (card->reader->atr_info.hist_bytes_len >= 6 && !(memcmp(card->reader->atr_info.hist_bytes, (u8 *)"TK\x00PIV", 6))) { type = SC_CARD_TYPE_PIV_II_TOKEN2; } @@ -5499,11 +5520,11 @@ static int piv_match_card_continued(sc_card_t *card) /* look for card issuer's data: tag 5X where X is datalen */ if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1, - card->reader->atr_info.hist_bytes_len - 1, 0x50, &datalen))) { + card->reader->atr_info.hist_bytes_len - 1, 0x50, &datalen))) { if (datalen >= 8 && !(memcmp(data, "Nitrokey", 8))) { /* first 8 are Nitrokey */ type = SC_CARD_TYPE_PIV_II_NITROKEY; } else if (datalen == 7 && !(memcmp(data, "YubiKey", 7))) { - type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */ + type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */ } /* Yubikey 5 NFC ATR using ACR122 contactless reader does not match * https://developers.yubico.com/PIV/Introduction/Yubico_extensions.html @@ -5511,15 +5532,15 @@ static int piv_match_card_continued(sc_card_t *card) * will look at only 6 bytes that do match */ else if (datalen == 7 && !(memcmp(data, "YubiKe", 6))) { - type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */ + type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */ } } else if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1, - card->reader->atr_info.hist_bytes_len - 1, 0xF0, &datalen))) { + card->reader->atr_info.hist_bytes_len - 1, 0xF0, &datalen))) { int k; for (k = 0; piv_aids[k].len_long != 0; k++) { if (datalen == piv_aids[k].len_long && - !memcmp(data, piv_aids[k].value, datalen)) { + !memcmp(data, piv_aids[k].value, datalen)) { type = SC_CARD_TYPE_PIV_II_HIST; break; } @@ -5528,21 +5549,20 @@ static int piv_match_card_continued(sc_card_t *card) } } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); if (type == -1) { /* use known ATRs which changes the type */ i = _sc_match_atr(card, piv_atrs, &type); if (i < 0) type = SC_CARD_TYPE_PIV_II_BASE; /* May be some newer unknown card including CAC or PIV-like card */ - } } card->type = type; /* we either found via ATR historic bytes or ATR directly */ - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); /* allocate and init basic fields */ priv = calloc(1, sizeof(piv_private_data_t)); @@ -5564,7 +5584,7 @@ static int piv_match_card_continued(sc_card_t *card) #ifdef ENABLE_PIV_SM memset(&card->sm_ctx, 0, sizeof card->sm_ctx); - card->sm_ctx.ops.open = piv_sm_open; + card->sm_ctx.ops.open = piv_sm_open; card->sm_ctx.ops.get_sm_apdu = piv_get_sm_apdu; card->sm_ctx.ops.free_sm_apdu = piv_free_sm_apdu; card->sm_ctx.ops.close = piv_sm_close; @@ -5580,8 +5600,8 @@ static int piv_match_card_continued(sc_card_t *card) priv->init_flags |= PIV_INIT_CONTACTLESS; } - for (i=0; i < PIV_OBJ_LAST_ENUM -1; i++) - if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) + for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++) + if (piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; /* * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card @@ -5620,21 +5640,21 @@ static int piv_match_card_continued(sc_card_t *card) /* If card type still unknown, see if Application Label is known and set card->type */ if (priv->al_label && priv->al_labellen) { switch (card->type) { - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - for (i = 0; al_map[i].al_label; i++) { - if ((priv->al_labellen >= al_map[i].al_labellen) && - (!memcmp(priv->al_label, al_map[i].al_label, al_map[i].al_labellen))) { - sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "AL match i:%d type:%d", i, al_map[i].al_type); - card->type = al_map[i].al_type; - break; - } + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + for (i = 0; al_map[i].al_label; i++) { + if ((priv->al_labellen >= al_map[i].al_labellen) && + (!memcmp(priv->al_label, al_map[i].al_label, al_map[i].al_labellen))) { + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "AL match i:%d type:%d", i, al_map[i].al_type); + card->type = al_map[i].al_type; + break; } - break; + } + break; } } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d AI:%08x\n", card->type, priv->card_issues, r, priv->alg_ids); /* @@ -5644,82 +5664,82 @@ static int piv_match_card_continued(sc_card_t *card) * SC_CARD_TYPE_PIV_II_GENERIC can be set by user to not test for Yubico version */ switch (card->type) { - case SC_CARD_TYPE_PIV_II_NEO: - case SC_CARD_TYPE_PIV_II_YUBIKEY4: - case SC_CARD_TYPE_PIV_II_NITROKEY: - case SC_CARD_TYPE_PIV_II_TOKEN2: - case SC_CARD_TYPE_PIV_II_PIVAPPLET: - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_BASE: /* unknown PIV card */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00); - apdu.lc = 0; - apdu.data = NULL; - apdu.datalen = 0; - apdu.resp = yubico_version_buf; - apdu.resplen = sizeof(yubico_version_buf); - apdu.le = apdu.resplen; - r2 = sc_transmit_apdu(card, &apdu); /* if not supported yubico_version == 0 */ - if (apdu.resplen == 3) { - priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; - sc_log(card->ctx, "Yubikey version test card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); - } - break; + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_BASE: /* unknown PIV card */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00); + apdu.lc = 0; + apdu.data = NULL; + apdu.datalen = 0; + apdu.resp = yubico_version_buf; + apdu.resplen = sizeof(yubico_version_buf); + apdu.le = apdu.resplen; + r2 = sc_transmit_apdu(card, &apdu); /* if not supported yubico_version == 0 */ + if (apdu.resplen == 3) { + priv->yubico_version = (yubico_version_buf[0] << 16) | (yubico_version_buf[1] << 8) | yubico_version_buf[2]; + sc_log(card->ctx, "Yubikey version test card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); + } + break; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); - /* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */ - /* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */ + /* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */ + /* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */ switch (card->type) { - /* - * For cards that may also be CAC, try and read the CCC - * CCC is required and all Dual PIV/CAC will have a CCC - * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History - */ - case SC_CARD_TYPE_PIV_II_BASE: /* i.e. really dont know what this is */ - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_GI_DE: - case SC_CARD_TYPE_PIV_II_GEMALTO: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - r2 = piv_process_ccc(card); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", - card->type, r2, priv->card_issues, r, priv->alg_ids); - /* Ignore any error. */ - /* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ - if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { - switch (card->type) { - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_GI_DE: - card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - case SC_CARD_TYPE_PIV_II_GEMALTO: - card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - case SC_CARD_TYPE_PIV_II_OBERTHUR: - card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - } + /* + * For cards that may also be CAC, try and read the CCC + * CCC is required and all Dual PIV/CAC will have a CCC + * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History + */ + case SC_CARD_TYPE_PIV_II_BASE: /* i.e. really dont know what this is */ + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + r2 = piv_process_ccc(card); + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + card->type, r2, priv->card_issues, r, priv->alg_ids); + /* Ignore any error. */ + /* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ + if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { + switch (card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_GEMALTO: + card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_OBERTHUR: + card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; } - break; + } + break; - case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); /* If contactless or run as virtual card try to get alg refs from AC entries in response to SELECT AID */ @@ -5729,18 +5749,18 @@ static int piv_match_card_continued(sc_card_t *card) /* Read AID if needed for these cards types */ if (!(priv->init_flags & PIV_INIT_AID_PARSED)) { - switch(card->type) { - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_800_73_4: - case SC_CARD_TYPE_PIV_II_NITROKEY: - case SC_CARD_TYPE_PIV_II_TOKEN2: - case SC_CARD_TYPE_PIV_II_PIVAPPLET: - r2 = piv_find_aid(card); + switch (card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_800_73_4: + case SC_CARD_TYPE_PIV_II_NITROKEY: + case SC_CARD_TYPE_PIV_II_TOKEN2: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + r2 = piv_find_aid(card); } } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); /* if card did not specify any of the NIST basic alg_ids add them */ @@ -5749,23 +5769,23 @@ static int piv_match_card_continued(sc_card_t *card) } /* If unknown card has 800-73-4 features, it must be based on 800-73-4 or above */ - switch(card->type) { - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_GENERIC: - if (priv->init_flags & PIV_INIT_AID_AC_SM) { - card->type = SC_CARD_TYPE_PIV_II_800_73_4; - } + switch (card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + if (priv->init_flags & PIV_INIT_AID_AC_SM) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } #ifdef ENABLE_PIV_SM - /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */ - if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) { - card->type = SC_CARD_TYPE_PIV_II_800_73_4; - } + /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */ + if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } #endif - break; + break; } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); /* @@ -5783,86 +5803,81 @@ static int piv_match_card_continued(sc_card_t *card) * may be set earlier or later then in the following code. */ - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); - switch(card->type) { - case SC_CARD_TYPE_PIV_II_NEO: - priv->card_issues |= CI_NO_EC384 | - CI_VERIFY_630X | - CI_OTHER_AID_LOSE_STATE | - CI_LEAKS_FILE_NOT_FOUND | - CI_NFC_EXPOSE_TOO_MUCH; - if (priv->yubico_version < 0x00040302) - priv->card_issues |= CI_VERIFY_LC0_FAIL; - break; + switch (card->type) { + case SC_CARD_TYPE_PIV_II_NEO: + priv->card_issues |= CI_NO_EC384 | + CI_VERIFY_630X | + CI_OTHER_AID_LOSE_STATE | + CI_LEAKS_FILE_NOT_FOUND | + CI_NFC_EXPOSE_TOO_MUCH; + if (priv->yubico_version < 0x00040302) + priv->card_issues |= CI_VERIFY_LC0_FAIL; + break; - case SC_CARD_TYPE_PIV_II_YUBIKEY4: - case SC_CARD_TYPE_PIV_II_PIVAPPLET: - case SC_CARD_TYPE_PIV_II_TOKEN2: - priv->card_issues |= CI_OTHER_AID_LOSE_STATE | - CI_LEAKS_FILE_NOT_FOUND; - if (priv->yubico_version < 0x00040302) - priv->card_issues |= CI_VERIFY_LC0_FAIL; - if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */ - priv->alg_ids |= AI_RSA_4096 | AI_25519; - break; + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_PIVAPPLET: + case SC_CARD_TYPE_PIV_II_TOKEN2: + priv->card_issues |= CI_OTHER_AID_LOSE_STATE | + CI_LEAKS_FILE_NOT_FOUND; + if (priv->yubico_version < 0x00040302) + priv->card_issues |= CI_VERIFY_LC0_FAIL; + if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */ + priv->alg_ids |= AI_RSA_4096 | AI_25519; + break; - case SC_CARD_TYPE_PIV_II_NITROKEY: - priv->card_issues |= CI_OTHER_AID_LOSE_STATE; -<<<<<<< HEAD - if (priv->yubico_version >= 0x00010802) - priv->card_issues |= CI_RSA_4096; -======= - if (priv->yubico_version >= 0x00010802) /* use for NitroKey too */ - priv->alg_ids |= AI_RSA_4096; ->>>>>>> 21681946a (card-piv.c cards.h - Improved PIV card identification) - break; + case SC_CARD_TYPE_PIV_II_NITROKEY: + priv->card_issues |= CI_OTHER_AID_LOSE_STATE; + if (priv->yubico_version >= 0x00010802) /* use for NitroKey too */ + priv->alg_ids |= AI_RSA_4096; + break; - case SC_CARD_TYPE_PIV_II_GI_DE: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - case SC_CARD_TYPE_PIV_II_GEMALTO: - case SC_CARD_TYPE_PIV_II_SWISSBIT: - priv->card_issues |= 0; /* could add others here */ - break; + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_SWISSBIT: + priv->card_issues |= 0; /* could add others here */ + break; - case SC_CARD_TYPE_PIV_II_BASE: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_800_73_4: - priv->card_issues |= 0; /* could add others here */ - break; + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_800_73_4: + priv->card_issues |= 0; /* could add others here */ + break; - case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - priv->card_issues |= CI_VERIFY_LC0_FAIL | - CI_PIV_AID_LOSE_STATE | - CI_NO_RANDOM | - CI_OTHER_AID_LOSE_STATE; - break; + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_PIV_AID_LOSE_STATE | + CI_NO_RANDOM | + CI_OTHER_AID_LOSE_STATE; + break; - case SC_CARD_TYPE_PIV_II_GENERIC: - priv->card_issues |= CI_VERIFY_LC0_FAIL | - CI_OTHER_AID_LOSE_STATE; - break; + case SC_CARD_TYPE_PIV_II_GENERIC: + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_OTHER_AID_LOSE_STATE; + break; - case SC_CARD_TYPE_PIV_II_PIVKEY: - priv->card_issues |= CI_VERIFY_LC0_FAIL | - CI_PIV_AID_LOSE_STATE | /* be conservative */ - CI_NO_RANDOM; /* does not have 9B key */ - /* Discovery object returns 6A 82 so is not on card by default */ - break; + case SC_CARD_TYPE_PIV_II_PIVKEY: + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_PIV_AID_LOSE_STATE | /* be conservative */ + CI_NO_RANDOM; /* does not have 9B key */ + /* Discovery object returns 6A 82 so is not on card by default */ + break; - default: - priv->card_issues |= CI_VERIFY_LC0_FAIL | - CI_OTHER_AID_LOSE_STATE; - /* opensc.conf may have it wrong, continue anyway */ - sc_log(card->ctx, "Unknown PIV card->type %d", card->type); - card->type = SC_CARD_TYPE_PIV_II_GENERIC; + default: + priv->card_issues |= CI_VERIFY_LC0_FAIL | + CI_OTHER_AID_LOSE_STATE; + /* opensc.conf may have it wrong, continue anyway */ + sc_log(card->ctx, "Unknown PIV card->type %d", card->type); + card->type = SC_CARD_TYPE_PIV_II_GENERIC; } sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); - if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED) ) { + if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED)) { /* * We now know PIV AID is active, test DISCOVERY object again * Some PIV don't support DISCOVERY and return @@ -5874,7 +5889,7 @@ static int piv_match_card_continued(sc_card_t *card) if (r2 < 0) { priv->card_issues |= CI_DISCOVERY_USELESS; - piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY,PIV_OBJ_CACHE_NOT_PRESENT); + piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, PIV_OBJ_CACHE_NOT_PRESENT); } } @@ -5884,7 +5899,7 @@ static int piv_match_card_continued(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); err: - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH failed card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", + sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH failed card->type:%d r2:%d CI:%08x r:%d AI:%08x\n", card->type, r2, priv->card_issues, r, priv->alg_ids); /* don't match. Does not have a PIV applet. */ piv_finish(card); @@ -5892,11 +5907,11 @@ static int piv_match_card_continued(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_init(sc_card_t *card) +static int +piv_init(sc_card_t *card) { int r = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); unsigned long flags; unsigned long flags_eddsa; unsigned long flags_xeddsa; @@ -5912,7 +5927,7 @@ static int piv_init(sc_card_t *card) r = piv_match_card_continued(card); priv = PIV_DATA(card); if (r < 0 || !priv) { - sc_log(card->ctx,"piv_match_card_continued failed card->type:%d", card->type); + sc_log(card->ctx, "piv_match_card_continued failed card->type:%d", card->type); sc_unlock(card); piv_finish(card); /* tell sc_connect_card to try other driver */ @@ -5923,10 +5938,10 @@ static int piv_init(sc_card_t *card) /* read "card_driver PIV-II" opensc.conf options, and env parameters */ piv_load_options(card); - priv->pstate=PIV_STATE_INIT; + priv->pstate = PIV_STATE_INIT; sc_log(card->ctx, - "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type:%d, CI:%08x AI:%08x", + "Max send = %" SC_FORMAT_LEN_SIZE_T "u recv = %" SC_FORMAT_LEN_SIZE_T "u card->type:%d, CI:%08x AI:%08x", card->max_send_size, card->max_recv_size, card->type, priv->card_issues, priv->alg_ids); card->cla = 0x00; if (card->name == NULL) @@ -5971,10 +5986,10 @@ static int piv_init(sc_card_t *card) } else if (priv->alg_ids & AI_25519 && ec_curves[i].key_type == SC_ALGORITHM_EDDSA) - _sc_card_add_eddsa_alg(card, ec_curves[i].size, flags_eddsa, ext_flags, &ec_curves[i].oid); + _sc_card_add_eddsa_alg(card, ec_curves[i].size, flags_eddsa, ext_flags, &ec_curves[i].oid); - else if (priv->alg_ids & AI_X25519 &&ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) - _sc_card_add_xeddsa_alg(card, ec_curves[i].size, flags_xeddsa, ext_flags, &ec_curves[i].oid); + else if (priv->alg_ids & AI_X25519 && ec_curves[i].key_type == SC_ALGORITHM_XEDDSA) + _sc_card_add_xeddsa_alg(card, ec_curves[i].size, flags_xeddsa, ext_flags, &ec_curves[i].oid); } } @@ -5982,7 +5997,7 @@ static int piv_init(sc_card_t *card) card->caps |= SC_CARD_CAP_RNG; /* May turn off SC_CARD_CAP_ISO7816_PIN_INFO later */ - card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; /* * 800-73-3 cards may have discovery. "piv-like cards may or may not. @@ -6002,29 +6017,29 @@ static int piv_init(sc_card_t *card) /* If user said PIV_SM_FLAGS_NEVER, dont start SM; implies limited contatless access */ if (priv->sm_flags & PIV_SM_FLAGS_NEVER) { - sc_log(card->ctx,"User has requested PIV_SM_FLAGS_NEVER"); + sc_log(card->ctx, "User has requested PIV_SM_FLAGS_NEVER"); r = SC_SUCCESS; /* Users choice */ } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) && !(priv->pin_policy & PIV_PP_VCI_IMPL)) { - sc_log(card->ctx,"Contactless and no card support for VCI"); + sc_log(card->ctx, "Contactless and no card support for VCI"); r = SC_SUCCESS; /* User should know VCI is not possible with their card; use like 800-73-3 contactless */ } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) && !(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) && (priv->pairing_code[0] == 0x00)) { - sc_log(card->ctx,"Contactless, pairing_code required and no pairing code"); + sc_log(card->ctx, "Contactless, pairing_code required and no pairing code"); r = SC_ERROR_PIN_CODE_INCORRECT; /* User should know they need to set pairing code */ } else { priv->sm_flags |= PIV_SM_FLAGS_DEFER_OPEN; /* tell priv_sm_open, OK to open */ r = piv_sm_open(card); - sc_log(card->ctx,"piv_sm_open returned:%d", r); + sc_log(card->ctx, "piv_sm_open returned:%d", r); } /* If failed, and user said PIV_SM_FLAGS_ALWAYS quit */ if (priv->sm_flags & PIV_SM_FLAGS_ALWAYS && r < 0) { - sc_log(card->ctx,"User has requested PIV_SM_FLAGS_ALWAYS, SM has failed to start, don't use the card"); + sc_log(card->ctx, "User has requested PIV_SM_FLAGS_ALWAYS, SM has failed to start, don't use the card"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); } @@ -6043,13 +6058,13 @@ static int piv_init(sc_card_t *card) */ piv_process_history(card); - priv->pstate=PIV_STATE_NORMAL; + priv->pstate = PIV_STATE_NORMAL; sc_unlock(card); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } - -static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) +static int +piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -6057,7 +6072,7 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 #ifdef ENABLE_PIV_SM int i; #endif - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -6074,7 +6089,7 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 * This just decrements the extra lock count */ if (priv->context_specific) { - sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC lock"); + sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock"); priv->context_specific = 0; sc_unlock(card); } @@ -6082,10 +6097,10 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 if (priv->card_issues & CI_VERIFY_630X) { - /* Handle the Yubikey NEO or any other PIV card which returns in response to a verify - * 63 0X rather than 63 CX indicate the number of remaining PIN retries. - * Perhaps they misread the spec and thought 0xCX meant "clear" or "don't care", not a literal 0xC! - */ + /* Handle the Yubikey NEO or any other PIV card which returns in response to a verify + * 63 0X rather than 63 CX indicate the number of remaining PIN retries. + * Perhaps they misread the spec and thought 0xCX meant "clear" or "don't care", not a literal 0xC! + */ if (priv->pin_cmd_verify && sw1 == 0x63U) { priv->pin_cmd_verify_sw2 |= 0xC0U; /* make it easier to test in other code */ if ((sw2 & ~0x0fU) == 0x00U) { @@ -6112,15 +6127,14 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 return r; } - static int piv_check_protected_objects(sc_card_t *card) { int r = 0; int i; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); u8 buf[8]; /* tag of 53 with 82 xx xx will fit in 4 */ - u8 * rbuf; + u8 *rbuf; size_t buf_len; static int protected_objects[] = {PIV_OBJ_PI, PIV_OBJ_CHF, PIV_OBJ_IRIS_IMAGE}; @@ -6145,7 +6159,7 @@ piv_check_protected_objects(sc_card_t *card) * */ if (priv->object_test_verify == 0) { - for (i = 0; i < (int)(sizeof(protected_objects)/sizeof(int)); i++) { + for (i = 0; i < (int)(sizeof(protected_objects) / sizeof(int)); i++) { buf_len = sizeof(buf); rbuf = buf; r = piv_get_data(card, protected_objects[i], &rbuf, &buf_len); @@ -6182,12 +6196,11 @@ piv_check_protected_objects(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - static int piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { int r = 0; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); /* Extra validation of (new) PIN during a PIN change request, to * ensure it's not outside the FIPS 201 4.1.6.1 (numeric only) and @@ -6202,7 +6215,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->pin2.len < 6) { return SC_ERROR_INVALID_PIN_LENGTH; } - for(i=0; i < data->pin2.len; ++i) { + for (i = 0; i < data->pin2.len; ++i) { if (!isdigit(data->pin2.data[i])) { return SC_ERROR_INVALID_DATA; } @@ -6223,7 +6236,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) */ if (data->pin_type == SC_AC_CONTEXT_SPECIFIC) { data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT; - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } if (priv->logged_in & SC_PIN_STATE_LOGGED_IN) { @@ -6248,7 +6261,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) */ if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) { priv->context_specific = 1; - sc_log(card->ctx,"Starting CONTEXT_SPECIFIC verify"); + sc_log(card->ctx, "Starting CONTEXT_SPECIFIC verify"); r = sc_lock(card); if (r != SC_SUCCESS) { sc_log(card->ctx, "sc_lock failed"); @@ -6264,20 +6277,19 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 && priv->init_flags & PIV_INIT_CONTACTLESS && card->type == SC_CARD_TYPE_PIV_II_800_73_4) { - sc_log(card->ctx, "Token does not support pin verify over contacless reader"); - r = SC_ERROR_NOT_SUPPORTED; + sc_log(card->ctx, "Token does not support pin verify over contacless reader"); + r = SC_ERROR_NOT_SUPPORTED; } - /* if verify failed, release the lock */ - if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) { - sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC"); + if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) { + sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC"); priv->context_specific = 0; sc_unlock(card); } /* if access to applet is know to be reset by other driver we select_aid and try again */ - if ( priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) { + if (priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) { sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd"); piv_find_aid(card); @@ -6302,12 +6314,12 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) sc_log(card->ctx, "CI_CANT_USE_GETDATA_FOR_STATE set, assume logged_in=%d", priv->logged_in); data->pin1.logged_in = priv->logged_in; /* use what ever we saw last */ } else if (priv->card_issues & CI_VERIFY_LC0_FAIL && - priv->pin_cmd_verify_sw1 == 0x63U ) { /* can not use modified return codes from iso->drv->pin_cmd */ + priv->pin_cmd_verify_sw1 == 0x63U) { /* can not use modified return codes from iso->drv->pin_cmd */ /* try another method, looking at a protected object this may require adding one of these to NEO */ r = piv_check_protected_objects(card); if (r == SC_SUCCESS) data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN; - else if (r == SC_ERROR_PIN_CODE_INCORRECT) { + else if (r == SC_ERROR_PIN_CODE_INCORRECT) { if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) { /* we still can not determine login state */ data->pin1.logged_in = priv->logged_in; /* may have be set from SC_PIN_CMD_VERIFY */ @@ -6321,15 +6333,15 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) priv->tries_left = data->pin1.tries_left; } - sc_log(card->ctx, "piv_pin_cmd tries_left=%d, logged_in=%d",priv->tries_left, priv->logged_in); + sc_log(card->ctx, "piv_pin_cmd tries_left=%d, logged_in=%d", priv->tries_left, priv->logged_in); LOG_FUNC_RETURN(card->ctx, r); } - -static int piv_logout(sc_card_t *card) +static int +piv_logout(sc_card_t *card) { int r = SC_ERROR_INTERNAL; - piv_private_data_t * priv = PIV_DATA(card); + piv_private_data_t *priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); @@ -6360,12 +6372,13 @@ static int piv_logout(sc_card_t *card) * the piv_sm_open in this case, but how? may need a open is active flag, * in case it is the APDU done from open caused triggered the case. */ -static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) +static int +piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) { int r = 0; u8 temp[SC_MAX_APDU_BUFFER_SIZE]; size_t templen = sizeof(temp); - piv_private_data_t * priv = PIV_DATA(card); /* may be null */ + piv_private_data_t *priv = PIV_DATA(card); /* may be null */ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -6386,7 +6399,7 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) /* but if card does not support DISCOVERY object we can not use it */ if (priv->card_issues & CI_DISCOVERY_USELESS) { - r = SC_ERROR_NO_CARD_SUPPORT; + r = SC_ERROR_NO_CARD_SUPPORT; } else { r = piv_find_discovery(card); #ifdef ENABLE_PIV_SM @@ -6397,11 +6410,11 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) * If read with SM and fails with 69 88 SC_ERROR_SM_INVALID_SESSION_KEY * sm.c will close the SM connectrion, and set defer */ - if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { - sc_log(card->ctx,"SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN"); + if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { + sc_log(card->ctx, "SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN"); piv_sm_open(card); r = piv_find_discovery(card); - } + } #endif /* ENABLE_PIV_SM */ } @@ -6428,9 +6441,8 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } - - -static struct sc_card_driver * sc_get_driver(void) +static struct sc_card_driver * +sc_get_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -6439,7 +6451,7 @@ static struct sc_card_driver * sc_get_driver(void) piv_ops.init = piv_init; piv_ops.finish = piv_finish; - piv_ops.select_file = piv_select_file; /* must use get/put, could emulate? */ + piv_ops.select_file = piv_select_file; /* must use get/put, could emulate? */ piv_ops.get_challenge = piv_get_challenge; piv_ops.logout = piv_logout; piv_ops.read_binary = piv_read_binary; @@ -6447,7 +6459,7 @@ static struct sc_card_driver * sc_get_driver(void) piv_ops.set_security_env = piv_set_security_env; piv_ops.restore_security_env = piv_restore_security_env; piv_ops.compute_signature = piv_compute_signature; - piv_ops.decipher = piv_decipher; + piv_ops.decipher = piv_decipher; piv_ops.check_sw = piv_check_sw; piv_ops.card_ctl = piv_card_ctl; piv_ops.pin_cmd = piv_pin_cmd; @@ -6456,8 +6468,8 @@ static struct sc_card_driver * sc_get_driver(void) return &piv_drv; } -struct sc_card_driver * sc_get_piv_driver(void) +struct sc_card_driver * +sc_get_piv_driver(void) { return sc_get_driver(); } - From d08a0b9a48ecfd8dbf207f900694176c608abef9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 May 2026 13:12:49 +0200 Subject: [PATCH 4254/4321] iasecc: fixed possible Stack Buffer Overflow Attribution Reported by @qp-x-qp --- src/libopensc/card-iasecc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 8c5d840ee3..b64256efed 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -3303,6 +3303,8 @@ iasecc_compute_signature_dst(struct sc_card *card, LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "It's not SC_SEC_OPERATION_SIGN"); else if (!(prv->key_size & 0x1E0) || (prv->key_size & ~0x1E0)) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key size for SC_SEC_OPERATION_SIGN"); + if (sizeof(rbuf) < prv->key_size) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); memset(&qsign_data, 0, sizeof(qsign_data)); if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) { From 1c8b70f893948ab1e5c6fe856dacd20bebdb311c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 May 2026 13:05:49 +0200 Subject: [PATCH 4255/4321] esteid2018: fixed possible Global-buffer-overflow Attribution Reported by @arthurscchan Arthur Chan . This vulnerability was discovered by Claude, Anthropic's AI assistant, with OSS-Fuzz fuzzing and triaged by Ada Logics manually in collaboration with Anthropic Research. --- src/libopensc/pkcs15-esteid2018.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index 0cddbe21a5..48edbdeacc 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -94,6 +94,11 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) { cert_info = (struct sc_pkcs15_cert_info *)obj.data; if (cert_info && cert_info->path.len > 0) { cert_slot = cert_info->path.value[cert_info->path.len - 1] - 1; + if (cert_slot != 0 && cert_slot != 1) { + /* unknown slot, see `cert_paths` below */ + r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + LOG_TEST_GOTO_ERR(card->ctx, r, "Unknown certificate path"); + } } sc_pkcs15_free_cert_info(cert_info); From 79963b71ba7618d40bbf3d6e9b76717b1beb78c3 Mon Sep 17 00:00:00 2001 From: Jiami Lin Date: Thu, 28 May 2026 00:35:38 +0800 Subject: [PATCH 4256/4321] asn1: avoid uninitialized read of INTEGER/ENUMERATED debug output (#3690) * asn1: avoid uninitialized read of INTEGER/ENUMERATED debug output sc_asn1_decode_integer() has several early-return paths (inlen == 0, inlen > sizeof(int), strict-mode rejection, overflow in the accumulation loop) that return an error without writing to *out. Callers such as asn1_decode_path() pass addresses of uninitialized stack ints as entry->parm, so when the decode fails the storage stays uninitialized. asn1_decode_entry() previously formatted *entry->parm in the SC_LOG_DEBUG_ASN1 message unconditionally, which leaks uninitialized stack contents into the high-debug log. Only log the decoded value on success; on failure log the error code instead. No functional change to the decoder itself or to the success-path log format. Fixes #3685 * Update src/libopensc/asn1.c I looked at the rest of the logic, you're right. Co-authored-by: Frank Morgner * Fix spacing around pointer dereferences Remove space between cast and identifier as required by clang-format CI. * asn1: revert unrelated whitespace, fix continuation indent Restore (size_t *) entry->arg cast spacing (unrelated to this PR) and add the continuation indent required by clang-format for the sc_debug() call. --------- Co-authored-by: Frank Morgner --- src/libopensc/asn1.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 033aa898dc..32d7ff8564 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1525,8 +1525,10 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_ENUMERATED: if (parm != NULL) { r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 0); - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "", - entry->name, *((int *) entry->parm)); + if (r == SC_SUCCESS) { + sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", + depth, depth, "", entry->name, *((int *)entry->parm)); + } } break; case SC_ASN1_BIT_STRING_NI: From bc2c29c4b3f205c00ca132491d577adab964e569 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 28 May 2026 09:05:44 +0200 Subject: [PATCH 4257/4321] Fix epass2003 regression with SM There is 0x01 separator between the tag and value, which was breaking the encryption for last couple of weeks. Fixup of 5ebb04ded3e8a54a9544a3745b3b5bd566d1e0b2 Fixes: #3693 --- src/libopensc/card-epass2003.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index d2e172e3e3..9a13e6a440 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1462,6 +1462,8 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned if (cipher_len < 2 || cipher_len > sizeof plaintext) return -1; + /* Skip the 0x01 separator between tag and ciphertext */ + p++; /* decrypt */ if (KEY_TYPE_AES == exdata->smtype) aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, p, cipher_len - 1, plaintext); From 7ac299a8c1fd514119db888326c99a0a5a987e0d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 25 May 2026 15:42:58 +0200 Subject: [PATCH 4258/4321] netkey-tool: Check buffer bounds during certificate reading Malicious card can return large size from FCI, which is not checked against the size of local buffers, which are used to gather the read data. Malicious card returning larger data can corrupt stack and crash the process. netkey-tool is used only to manage specific cards so this is very hardly exploitable. Found by AISLE in partnership with Red Hat --- src/tools/netkey-tool.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 683ac182bd..3dae4bc881 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -134,6 +134,10 @@ static void show_certs(sc_card_t *card) printf(", Invalid Cert-file: Type=%d, EF-Structure=%d\n", f->type, f->ef_structure); continue; } + if (f->size > sizeof(buf)) { + printf(", Certificate too large for buffer (%zu > %zu)\n", f->size, sizeof(buf)); + continue; + } if((j=sc_read_binary(card,0,buf,f->size,0))<0){ printf(", Cannot read Cert-file, %s\n", sc_strerror(j)); continue; @@ -359,6 +363,10 @@ static void handle_readcert(sc_card_t *card, long cert, char *file) printf("cannot select certfile, %s\n", sc_strerror(i)); return; } + if (f->size > sizeof(buf)) { + printf("Certificate too large for buffer (%zu > %zu)\n", f->size, sizeof(buf)); + return; + } if((len=sc_read_binary(card,0,buf,f->size,0))<0){ printf("Cannot read Cert, %s\n", sc_strerror(len)); return; From d306b1380643fd5469d0602e1528b76843ba922e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 May 2026 15:55:19 +0200 Subject: [PATCH 4259/4321] muscle: Check buffer bounds to prevent heap overflow https://github.com/OpenSC/OpenSC/security/advisories/GHSA-mqrp-f57m-gh66 Found by AISLE in partnership with Red Hat --- src/libopensc/muscle.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index de85a611ff..d2ae6419ec 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -688,11 +688,15 @@ int msc_compute_crypt_init(sc_card_t *card, r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; - *outputDataLength = receivedData; - + size_t receivedData = outputBuffer[0] << 8 | outputBuffer[1]; if (receivedData > MSC_MAX_APDU) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); + if (receivedData > *outputDataLength) { + *outputDataLength = receivedData; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); + } + *outputDataLength = receivedData; + memcpy(outputData, outputBuffer + 2, receivedData); return 0; } @@ -740,11 +744,15 @@ int msc_compute_crypt_final( r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - short receivedData = outputBuffer[0] << 8 | outputBuffer[1]; - *outputDataLength = receivedData; - + size_t receivedData = outputBuffer[0] << 8 | outputBuffer[1]; if (receivedData > MSC_MAX_APDU) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); + if (receivedData > *outputDataLength) { + *outputDataLength = receivedData; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); + } + *outputDataLength = receivedData; + memcpy(outputData, outputBuffer + 2, receivedData); return 0; } @@ -839,13 +847,13 @@ int msc_compute_crypt(sc_card_t *card, size_t dataLength, size_t outputDataLength) { - size_t left = dataLength; + size_t left = dataLength, outLeft = outputDataLength; const u8* inPtr = data; u8* outPtr = outputData; int toSend; int r; - size_t received = 0; + size_t received = outputDataLength; if (outputDataLength < dataLength) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -863,6 +871,7 @@ int msc_compute_crypt(sc_card_t *card, if(r < 0) LOG_FUNC_RETURN(card->ctx, r); left -= toSend; inPtr += toSend; + outLeft -= received; outPtr += received; toSend = MIN((int)left, MSC_MAX_APDU - 5); @@ -874,7 +883,7 @@ int msc_compute_crypt(sc_card_t *card, inPtr, outPtr, toSend, - &received); + &outLeft); if(r < 0) LOG_FUNC_RETURN(card->ctx, r); } else { /* Data is too big: use objects */ r = msc_compute_crypt_final_object(card, @@ -882,10 +891,10 @@ int msc_compute_crypt(sc_card_t *card, inPtr, outPtr, toSend, - &received); + &outLeft); if(r < 0) LOG_FUNC_RETURN(card->ctx, r); } - outPtr += received; + outPtr += outLeft; return (int)(outPtr - outputData); /* Amt received */ } From b423c2dbe8decebb2da7369d4fbf34db5a69662e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 May 2026 15:57:55 +0200 Subject: [PATCH 4260/4321] eidenv: Use correct types to prevent buffer overflow in ASN1 parser The eidenv tool is not used on critical path so this is not practically exploitable. Found by AISLE in partnership with Red Hat --- src/tools/eidenv.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 8d6a4f19b2..0a75ae863f 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -139,10 +139,10 @@ static int read_transp(sc_card_t *card, const char *pathstring, unsigned char *b /* Hex-encode the buf, 2*len+1 bytes must be reserved. E.g. {'1','2'} -> {'3','1','3','2','\0'} */ static const char hextable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'E'}; -static void bintohex(char *buf, int len) +static void bintohex(char *buf, size_t len) { - int i; - for (i = len - 1; i >= 0; i--) { + size_t i; + for (i = 0; i < len; i++) { buf[2 * i + 1] = hextable[((unsigned char) buf[i]) % 16]; buf[2 * i] = hextable[((unsigned char) buf[i]) / 16]; } @@ -186,22 +186,22 @@ static void do_belpic(sc_card_t *card) char documenttype[5 + 1]; char specialstatus[5 + 1]; } id_data; - int cardnumberlen = sizeof(id_data.cardnumber); - int chipnumberlen = sizeof(id_data.chipnumber); - int validfromlen = sizeof(id_data.validfrom); - int validtilllen = sizeof(id_data.validtill); - int deliveringmunicipalitylen = sizeof(id_data.deliveringmunicipality); - int nationalnumberlen = sizeof(id_data.nationalnumber); - int namelen = sizeof(id_data.name); - int firstnameslen = sizeof(id_data.firstnames); - int initiallen = sizeof(id_data.initial); - int nationalitylen = sizeof(id_data.nationality); - int birthlocationlen = sizeof(id_data.birthlocation); - int birthdatelen = sizeof(id_data.birthdate); - int sexlen = sizeof(id_data.sex); - int nobleconditionlen = sizeof(id_data.noblecondition); - int documenttypelen = sizeof(id_data.documenttype); - int specialstatuslen = sizeof(id_data.specialstatus); + size_t cardnumberlen = sizeof(id_data.cardnumber); + size_t chipnumberlen = sizeof(id_data.chipnumber); + size_t validfromlen = sizeof(id_data.validfrom); + size_t validtilllen = sizeof(id_data.validtill); + size_t deliveringmunicipalitylen = sizeof(id_data.deliveringmunicipality); + size_t nationalnumberlen = sizeof(id_data.nationalnumber); + size_t namelen = sizeof(id_data.name); + size_t firstnameslen = sizeof(id_data.firstnames); + size_t initiallen = sizeof(id_data.initial); + size_t nationalitylen = sizeof(id_data.nationality); + size_t birthlocationlen = sizeof(id_data.birthlocation); + size_t birthdatelen = sizeof(id_data.birthdate); + size_t sexlen = sizeof(id_data.sex); + size_t nobleconditionlen = sizeof(id_data.noblecondition); + size_t documenttypelen = sizeof(id_data.documenttype); + size_t specialstatuslen = sizeof(id_data.specialstatus); struct sc_asn1_entry id[] = { {"cardnumber", SC_ASN1_UTF8STRING, 1, 0, id_data.cardnumber, &cardnumberlen}, @@ -229,9 +229,9 @@ static void do_belpic(sc_card_t *card) char zipcode[4 + 1]; char municipality[40 + 1]; /* UTF8 */ } address_data; - int streetandnumberlen = sizeof(address_data.streetandnumber); - int zipcodelen = sizeof(address_data.zipcode); - int municipalitylen = sizeof(address_data.municipality); + size_t streetandnumberlen = sizeof(address_data.streetandnumber); + size_t zipcodelen = sizeof(address_data.zipcode); + size_t municipalitylen = sizeof(address_data.municipality); struct sc_asn1_entry address[] = { {"streetandnumber", SC_ASN1_UTF8STRING, 1, 0, address_data.streetandnumber, &streetandnumberlen}, {"zipcode", SC_ASN1_UTF8STRING, 2, 0, address_data.zipcode, &zipcodelen}, From b25b78845e8a5983d9c1bd96d34b3c89e00f07fd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 May 2026 17:49:56 +0200 Subject: [PATCH 4261/4321] coolkey: Avoid reading behind buffer bounds Thanks oss-fuzz https://issues.oss-fuzz.com/issues/517058311 Signed-off-by: Jakub Jelen --- src/libopensc/card-coolkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index c0d94fb6e0..a4356f584a 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1780,7 +1780,7 @@ static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen, goto done; } out_length = bebytes2ushort(buf); - if (out_length > buf_len) { + if (out_length > (buf_len - 2)) { r = SC_ERROR_WRONG_LENGTH; goto done; } From c930b22e7f84684d076575fb2d447134f1e68a9c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 May 2026 18:23:37 +0200 Subject: [PATCH 4262/4321] dnie: Avoid buffer overrun while processing EF(CFD) The function findPattern() correctly checks bounds fro the OID search but does not verify the data is valid and provided length is followed by enough data. Originally reported by Mitchell Benjamin from Revamp Studio --- src/libopensc/card-dnie.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index b57db099ef..fbb2095b39 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -492,6 +492,10 @@ static char *findPattern(u8 *pat, u8 *buf, size_t len) data_found: /* assume length is less than 128 bytes, so is coded in 1 byte */ size = 0x000000ff & (int) *(from+6); + if (from + 7 + size > buf + len) { + /* not enough data in the source buffer -- invalid data received */ + return NULL; + } if ( size == 0 ) return NULL; /* empty data */ res = calloc( size+1, sizeof(char) ); if ( res == NULL) return NULL; /* calloc() error */ From 1fc51e2718b500b548d2eae9c6ad383552fbbd11 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 27 Apr 2026 15:11:35 +0200 Subject: [PATCH 4263/4321] common: Add a way to exclude the RTLD_DEEPBIND from dlopen flags The address sanitizer does not work with DEEPBIND so we provide way to exclude this flag from the OpenSC operations based on environment variable. --- doc/files/files.html | 23 ++++++++++++++++++++ doc/files/opensc.conf.5.xml.in | 32 ++++++++++++++++++++++++++++ doc/tools/pkcs11-tool.1.xml | 38 ++++++++++++++++++++++++++++++++++ doc/tools/tools.html | 27 ++++++++++++++++++++++-- src/common/libpkcs11.c | 4 ++-- src/common/libscdl.c | 26 +++++++++++------------ src/common/libscdl.h | 1 - 7 files changed, 132 insertions(+), 19 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index b3c66049f2..7ad0b79132 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -1217,6 +1217,29 @@ See card_drivers = name... ; +

    + OPENSC_DEEPBIND +

    + The OpenSC and its tools are dynamically loading various + libraries (pcsclite, dynamic drivers and other pkcs11 + modules) using + dlopen(3). +

    + When this environment variable is set to + 1 + for the process running OpenSC, the calls will include + RTLD_DEEPBIND flag, which should + cause better symbol isolation between OpenSC and + loaded libraries. On the other hand, this is incompatible + with various static analysis tools as well as some + browser builds. +

    + This option may be useful, if OpenSC needs to load a library + that pollutes the processes' global namespace and thereby + causes the unintended use of a different function with the + same name. In particular, this may happen when + pkcs11-spy + is used for logging between application and PKCS#11 library.

    CARDMOD_LOW_LEVEL_DEBUG

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index a91bef92d3..5019eead8c 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1884,6 +1884,38 @@ app application { See + + + OPENSC_DEEPBIND + + + The OpenSC and its tools are dynamically loading various + libraries (pcsclite, dynamic drivers and other pkcs11 + modules) using + + dlopen + 3 + . + + + When this environment variable is set to + 1 + for the process running OpenSC, the calls will include + RTLD_DEEPBIND flag, which should + cause better symbol isolation between OpenSC and + loaded libraries. On the other hand, this is incompatible + with various static analysis tools as well as some + browser builds. + + + This option may be useful, if OpenSC needs to load a library + that pollutes the processes' global namespace and thereby + causes the unintended use of a different function with the + same name. In particular, this may happen when + pkcs11-spy + is used for logging between application and PKCS#11 library. + + CARDMOD_LOW_LEVEL_DEBUG diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 4de768b0af..c69b0d41f1 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -776,6 +776,44 @@ + + Environment + + + + OPENSC_DEEPBIND + + + The OpenSC and its tools are dynamically loading various + libraries (pcsclite, dynamic drivers and other pkcs11 + modules) using + + dlopen + 3 + . + + + When this environment variable is set to + 1 + for the process running OpenSC, the calls will include + RTLD_DEEPBIND flag, which should + cause better symbol isolation between OpenSC and + loaded libraries. On the other hand, this is incompatible + with various static analysis tools as well as some + browser builds. + + + This option may be useful, if OpenSC needs to load a library + that pollutes the processes' global namespace and thereby + causes the unintended use of a different function with the + same name. In particular, this may happen when + pkcs11-spy + is used for logging between application and PKCS#11 library. + + + + + Examples diff --git a/doc/tools/tools.html b/doc/tools/tools.html index f34b9992ac..f71547dfcf 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1836,7 +1836,30 @@

    Specify the PKCS#11 URI for module, slot, token or object

    --uri-with-slot-id

    Include SlotId in PKCS#11 URI

    -

    Examples

    +

    Environment

    + OPENSC_DEEPBIND +

    + The OpenSC and its tools are dynamically loading various + libraries (pcsclite, dynamic drivers and other pkcs11 + modules) using + dlopen(3). +

    + When this environment variable is set to + 1 + for the process running OpenSC, the calls will include + RTLD_DEEPBIND flag, which should + cause better symbol isolation between OpenSC and + loaded libraries. On the other hand, this is incompatible + with various static analysis tools as well as some + browser builds. +

    + This option may be useful, if OpenSC needs to load a library + that pollutes the processes' global namespace and thereby + causes the unintended use of a different function with the + same name. In particular, this may happen when + pkcs11-spy + is used for logging between application and PKCS#11 library. +

    Examples

    Perform a basic functionality test of the card:

    pkcs11-tool --test --login

    @@ -1931,7 +1954,7 @@

     pkcs11-tool --login --login-type so --init-pin
     				

    -

    Authors

    pkcs11-tool was written by +

    Authors

    pkcs11-tool was written by Olaf Kirch .


    Name

    pkcs15-crypt — perform crypto operations using PKCS#15 smart cards

    Synopsis

    pkcs15-crypt [OPTIONS]

    Description

    The pkcs15-crypt utility can be used from the command line to perform cryptographic operations such as computing diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index 487f7eeab5..5ad0dd3e56 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -60,9 +60,9 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) free(mod); return NULL; } - mod->handle = sc_dlopen_deep(mspec); + mod->handle = sc_dlopen(mspec); if (mod->handle == NULL) { - fprintf(stderr, "sc_dlopen_deep failed: %s\n", sc_dlerror()); + fprintf(stderr, "sc_dlopen failed: %s\n", sc_dlerror()); goto failed; } diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 97526fb747..226d56c85d 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -34,11 +34,6 @@ void *sc_dlopen(const char *filename) DWORD flags = PathIsRelativeA(filename) ? 0 : LOAD_WITH_ALTERED_SEARCH_PATH; return (void *)LoadLibraryExA(filename, NULL, flags); } -void * -sc_dlopen_deep(const char *filename) -{ - return sc_dlopen(filename); -} void *sc_dlsym(void *handle, const char *symbol) { @@ -72,20 +67,23 @@ int sc_dlclose(void *handle) #else #include +#include void *sc_dlopen(const char *filename) { - return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); -} - -void * -sc_dlopen_deep(const char *filename) -{ - return dlopen(filename, RTLD_LAZY | RTLD_LOCAL + int flags = RTLD_LAZY | RTLD_LOCAL; #ifdef RTLD_DEEPBIND - | RTLD_DEEPBIND + /* By default, the pkcs11 modules and pcsclite are opened without RTLD_DEEPBIND. + * Using RTLD_DEEPBIND causes issues for dynamic analysis tools such as ASAN. + * When the OPENSC_DEEPBIND is set to "1", the flag is included in the calls + * that normally do not use RTLD_DEEPBIND. + */ + char *deep = getenv("OPENSC_DEEPBIND"); + if (deep != NULL && deep[0] == '1') { + flags |= RTLD_DEEPBIND; + } #endif - ); + return dlopen(filename, flags); } void *sc_dlsym(void *handle, const char *symbol) diff --git a/src/common/libscdl.h b/src/common/libscdl.h index 15928fadba..b649994620 100644 --- a/src/common/libscdl.h +++ b/src/common/libscdl.h @@ -21,7 +21,6 @@ #ifndef __LIBSCDL_H #define __LIBSCDL_H void *sc_dlopen(const char *filename); -void *sc_dlopen_deep(const char *filename); void *sc_dlsym(void *handle, const char *symbol); int sc_dlclose(void *handle); const char *sc_dlerror(void); From 03220470c89e95a118b77c31132e060f87fddbfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 10:11:30 +0000 Subject: [PATCH 4264/4321] build(deps): bump github.com/microsoft/vcpkg in /.github Bumps [github.com/microsoft/vcpkg](https://github.com/microsoft/vcpkg) from master to 2026.04.27. This release includes the previously tagged commit. - [Release notes](https://github.com/microsoft/vcpkg/releases) - [Commits](https://github.com/microsoft/vcpkg/compare/bc38a15b0bee8bc48a49ea267cc32fbb49aedfc4...56bb2411609227288b70117ead2c47585ba07713) --- updated-dependencies: - dependency-name: github.com/microsoft/vcpkg dependency-version: 2026.04.27 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/vcpkg.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/vcpkg.json b/.github/vcpkg.json index 4b4941a7da..b3622f24e2 100644 --- a/.github/vcpkg.json +++ b/.github/vcpkg.json @@ -1,8 +1,8 @@ { - "name": "opensc", - "dependencies": [ - "openssl", - "zlib" - ], - "builtin-baseline": "bc38a15b0bee8bc48a49ea267cc32fbb49aedfc4" -} + "name": "opensc", + "dependencies": [ + "openssl", + "zlib" + ], + "builtin-baseline": "56bb2411609227288b70117ead2c47585ba07713" +} \ No newline at end of file From 6f898a152b7217023058180b819aef88d4a9fc69 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 3 Jun 2026 10:19:00 +0200 Subject: [PATCH 4265/4321] refactored pin commands to avoid tries_left as additional parameter (#3589) * refactored pin commands to avoid tries_left as additional parameter * adapted changes --- src/libopensc/card-asepcos.c | 10 ++--- src/libopensc/card-authentic.c | 46 +++++++++------------- src/libopensc/card-belpic.c | 4 +- src/libopensc/card-cac.c | 4 +- src/libopensc/card-cardos.c | 5 +-- src/libopensc/card-coolkey.c | 5 +-- src/libopensc/card-dnie.c | 16 +++----- src/libopensc/card-dtrust.c | 33 ++++++---------- src/libopensc/card-entersafe.c | 5 +-- src/libopensc/card-eoi.c | 8 ++-- src/libopensc/card-epass2003.c | 4 +- src/libopensc/card-esteid2018.c | 8 ++-- src/libopensc/card-esteid2025.c | 4 +- src/libopensc/card-flex.c | 8 ++-- src/libopensc/card-gids.c | 6 +-- src/libopensc/card-iasecc.c | 58 +++++++++++++-------------- src/libopensc/card-itacns.c | 5 +-- src/libopensc/card-jpki.c | 9 +---- src/libopensc/card-lteid.c | 42 ++++++++------------ src/libopensc/card-masktech.c | 23 +++++------ src/libopensc/card-mcrd.c | 5 +-- src/libopensc/card-muscle.c | 9 ++--- src/libopensc/card-myeid.c | 5 +-- src/libopensc/card-npa.c | 67 ++++++++++++++------------------ src/libopensc/card-nqApplet.c | 6 +-- src/libopensc/card-oberthur.c | 49 ++++++++++++----------- src/libopensc/card-openpgp.c | 14 +++---- src/libopensc/card-piv.c | 8 ++-- src/libopensc/card-sc-hsm.c | 24 +++++------- src/libopensc/card-starcos.c | 5 +-- src/libopensc/iasecc-sdo.h | 2 +- src/libopensc/iasecc-sm.c | 6 +-- src/libopensc/iso7816.c | 8 +--- src/libopensc/opensc.h | 5 +-- src/libopensc/pkcs15-din-66291.c | 2 +- src/libopensc/pkcs15-gids.c | 4 +- src/libopensc/pkcs15-jpki.c | 3 +- src/libopensc/pkcs15-pin.c | 12 +++--- src/libopensc/pkcs15-pteid.c | 2 +- src/libopensc/pkcs15-sc-hsm.c | 4 +- src/libopensc/pkcs15-srbeid.c | 9 ++--- src/libopensc/sec.c | 23 +++++++---- src/pkcs15init/pkcs15-cflex.c | 2 +- src/pkcs15init/pkcs15-lib.c | 2 +- src/tools/dtrust-tool.c | 43 +++++++++----------- src/tools/gids-tool.c | 2 +- src/tools/lteid-tool.c | 16 ++++---- src/tools/openpgp-tool.c | 3 +- src/tools/opensc-explorer.c | 26 ++++++------- src/tools/sc-hsm-tool.c | 24 ++++++------ src/tools/westcos-tool.c | 24 ++++++------ 51 files changed, 316 insertions(+), 401 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 27e0c22578..32fa926829 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -929,16 +929,12 @@ static int asepcos_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, /* generic function to handle the different PIN operations, i.e verify * change and unblock. */ -static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, - int *tries_left) +static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata) { sc_apdu_t apdu; int r = SC_SUCCESS; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - if (tries_left) - *tries_left = -1; - /* only PIN verification is supported at the moment */ /* check PIN length */ @@ -1025,8 +1021,8 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, /* check for remaining tries if verification failed */ if (r == SC_SUCCESS) { if (apdu.sw1 == 0x63) { - if ((apdu.sw2 & 0xF0) == 0xC0 && tries_left != NULL) - *tries_left = apdu.sw2 & 0x0F; + if ((apdu.sw2 & 0xF0) == 0xC0) + pdata->pin1.tries_left = apdu.sw2 & 0x0F; r = SC_ERROR_PIN_CODE_INCORRECT; return r; } diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index b0dce1873c..c7982a39f0 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -87,7 +87,7 @@ static int authentic_select_file(struct sc_card *card, const struct sc_path *pat static int authentic_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *buf, size_t buflen); static int authentic_get_serialnr(struct sc_card *card, struct sc_serial_number *serial); static int authentic_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct sc_acl_entry *acls); -static int authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, int *tries_left); +static int authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd); static int authentic_select_mf(struct sc_card *card, struct sc_file **file_out); static int authentic_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr); @@ -981,7 +981,7 @@ authentic_delete_file(struct sc_card *card, const struct sc_path *path) static int -authentic_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, int *tries_left) +authentic_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) { struct sc_context *ctx = card->ctx; unsigned char buffer[0x100]; @@ -991,7 +991,7 @@ authentic_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cm LOG_FUNC_CALLED(ctx); sc_log(ctx, "Verify PIN(ref:%i) with pin-pad", pin_cmd->pin_reference); - rv = authentic_pin_is_verified(card, pin_cmd, tries_left); + rv = authentic_pin_is_verified(card, pin_cmd); if (!rv) LOG_FUNC_RETURN(ctx, rv); @@ -1009,15 +1009,14 @@ authentic_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cm pin_cmd->cmd = SC_PIN_CMD_VERIFY; pin_cmd->flags |= SC_PIN_CMD_USE_PINPAD; - rv = iso_ops->pin_cmd(card, pin_cmd, tries_left); + rv = iso_ops->pin_cmd(card, pin_cmd); LOG_FUNC_RETURN(ctx, rv); } static int -authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, - int *tries_left) +authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) { struct sc_context *ctx = card->ctx; struct sc_apdu apdu; @@ -1056,7 +1055,7 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, apdu.lc = pin_len; } else if ((card->reader->capabilities & SC_READER_CAP_PIN_PAD) && !pin1->data && !pin1->len) { - rv = authentic_chv_verify_pinpad(card, pin_cmd, tries_left); + rv = authentic_chv_verify_pinpad(card, pin_cmd); sc_log(ctx, "authentic_chv_verify() authentic_chv_verify_pinpad returned %i", rv); LOG_FUNC_RETURN(ctx, rv); } @@ -1069,8 +1068,6 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, if (apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) { pin1->tries_left = apdu.sw2 & 0x0F; - if (tries_left) - *tries_left = apdu.sw2 & 0x0F; } rv = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1080,8 +1077,7 @@ authentic_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, static int -authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd_data, - int *tries_left) +authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd_data) { struct sc_context *ctx = card->ctx; struct sc_pin_cmd_data pin_cmd; @@ -1096,7 +1092,7 @@ authentic_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd_ pin_cmd.pin1.data = (unsigned char *)""; pin_cmd.pin1.len = 0; - rv = authentic_chv_verify(card, &pin_cmd, tries_left); + rv = authentic_chv_verify(card, &pin_cmd); LOG_FUNC_RETURN(ctx, rv); } @@ -1120,7 +1116,7 @@ authentic_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) if (pin_cmd->pin1.data && !pin_cmd->pin1.len) { pin_cmd->pin1.tries_left = -1; - rv = authentic_pin_is_verified(card, pin_cmd, &pin_cmd->pin1.tries_left); + rv = authentic_pin_is_verified(card, pin_cmd); LOG_FUNC_RETURN(ctx, rv); } @@ -1143,7 +1139,7 @@ authentic_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd) LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_LENGTH, "PIN policy check failed"); pin_cmd->pin1.tries_left = -1; - rv = authentic_chv_verify(card, pin_cmd, &pin_cmd->pin1.tries_left); + rv = authentic_chv_verify(card, pin_cmd); LOG_TEST_RET(ctx, rv, "PIN CHV verification error"); memcpy(prv_data->pins_sha1[pin_cmd->pin_reference], pin_sha1, SHA_DIGEST_LENGTH); @@ -1195,14 +1191,14 @@ authentic_pin_change_pinpad(struct sc_card *card, unsigned reference, int *tries pin_cmd.pin2.max_length, pin_cmd.pin2.min_length, pin_cmd.pin2.pad_length); - rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left); + rv = iso_ops->pin_cmd(card, &pin_cmd); LOG_FUNC_RETURN(ctx, rv); } static int -authentic_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +authentic_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct authentic_private_data *prv_data = (struct authentic_private_data *) card->drv_data; @@ -1223,7 +1219,7 @@ authentic_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr if (!data->pin1.data && !data->pin1.len && !data->pin2.data && !data->pin2.len) { if (!(card->reader->capabilities & SC_READER_CAP_PIN_PAD)) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "PIN pad not supported"); - rv = authentic_pin_change_pinpad(card, data->pin_reference, tries_left); + rv = authentic_pin_change_pinpad(card, data->pin_reference, &data->pin1.tries_left); sc_log(ctx, "authentic_pin_cmd(SC_PIN_CMD_CHANGE) chv_change_pinpad returned %i", rv); LOG_FUNC_RETURN(ctx, rv); } @@ -1298,7 +1294,7 @@ authentic_chv_set_pinpad(struct sc_card *card, unsigned char reference) "PIN2 max/min/pad %"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u", pin_cmd.pin2.max_length, pin_cmd.pin2.min_length, pin_cmd.pin2.pad_length); - rv = iso_ops->pin_cmd(card, &pin_cmd, NULL); + rv = iso_ops->pin_cmd(card, &pin_cmd); LOG_FUNC_RETURN(ctx, rv); } @@ -1356,7 +1352,7 @@ authentic_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, st static int -authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct authentic_private_data *prv_data = (struct authentic_private_data *) card->drv_data; @@ -1404,9 +1400,6 @@ authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri rv = authentic_pin_verify(card, &puk_cmd); - if (tries_left && rv == SC_ERROR_PIN_CODE_INCORRECT) - *tries_left = puk_cmd.pin1.tries_left; - LOG_TEST_RET(ctx, rv, "Cannot verify PUK"); } } @@ -1446,7 +1439,7 @@ authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri static int -authentic_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +authentic_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; int rv = SC_ERROR_INTERNAL; @@ -1461,10 +1454,10 @@ authentic_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries rv = authentic_pin_verify(card, data); break; case SC_PIN_CMD_CHANGE: - rv = authentic_pin_change(card, data, tries_left); + rv = authentic_pin_change(card, data); break; case SC_PIN_CMD_UNBLOCK: - rv = authentic_pin_reset(card, data, tries_left); + rv = authentic_pin_reset(card, data); break; case SC_PIN_CMD_GET_INFO: rv = authentic_pin_get_policy(card, data, NULL); @@ -1473,9 +1466,6 @@ authentic_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported PIN command"); } - if (rv == SC_ERROR_PIN_CODE_INCORRECT && tries_left) - *tries_left = data->pin1.tries_left; - LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 51aa49cf6d..e12cb5b90c 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -334,7 +334,7 @@ static int belpic_read_binary(sc_card_t *card, return r; } -static int belpic_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +static int belpic_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { data->pin1.encoding = data->pin2.encoding = BELPIC_PIN_ENCODING; data->pin1.pad_char = data->pin2.pad_char = BELPIC_PAD_CHAR; @@ -342,7 +342,7 @@ static int belpic_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tr data->pin1.max_length = data->pin2.max_length = BELPIC_MAX_USER_PIN_LEN; data->apdu = NULL; - return iso_ops->pin_cmd(card, data, tries_left); + return iso_ops->pin_cmd(card, data); } static int belpic_set_security_env(sc_card_t *card, diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index cd80eb46c7..3ae300bb0e 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1863,7 +1863,7 @@ static int cac_logout(sc_card_t *card) return cac_find_first_pki_applet(card, &index); } -static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { /* CAC, like PIV needs Extra validation of (new) PIN during * a PIN change request, to ensure it's not outside the @@ -1899,7 +1899,7 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries } } - rv = iso_drv->ops->pin_cmd(card, data, tries_left); + rv = iso_drv->ops->pin_cmd(card, data); data->apdu = NULL; return rv; diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 7236444a92..0e58f43b29 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -1478,8 +1478,7 @@ cardos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) * Unfortunately, it doesn't seem to work without this flag :-/ */ static int -cardos_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, - int *tries_left) +cardos_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; int rv; @@ -1504,7 +1503,7 @@ cardos_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, if (data->pin2.max_length == 0) data->pin2.max_length = 8; - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index a4356f584a..4864686772 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2354,7 +2354,7 @@ static int coolkey_init(sc_card_t *card) static int -coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r; coolkey_private_data_t * priv = COOLKEY_DATA(card); @@ -2377,9 +2377,6 @@ coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) */ data->pin1.tries_left = 0xf; } - if (tries_left) { - *tries_left = data->pin1.tries_left; - } r = SC_SUCCESS; break; diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index fbb2095b39..b2ab102741 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -2105,8 +2105,7 @@ static int dnie_pin_change(struct sc_card *card, struct sc_pin_cmd_data * data) * @param tries_left; on fail stores the number of tries left before car lock * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left */ -static int dnie_pin_verify(struct sc_card *card, - struct sc_pin_cmd_data *data, int *tries_left) +static int dnie_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data) { int res=SC_SUCCESS; sc_apdu_t apdu; @@ -2145,11 +2144,9 @@ static int dnie_pin_verify(struct sc_card *card, } /* check response and if requested setup tries_left */ - if (tries_left != NULL) { /* returning tries_left count is requested */ - if ((apdu.sw1 == 0x63) && ((apdu.sw2 & 0xF0) == 0xC0)) { - *tries_left = apdu.sw2 & 0x0F; - LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); - } + if ((apdu.sw1 == 0x63) && ((apdu.sw2 & 0xF0) == 0xC0)) { + data->pin1.tries_left = apdu.sw2 & 0x0F; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } res = dnie_check_sw(card, apdu.sw1, apdu.sw2); /* not a pinerr: parse result */ @@ -2177,8 +2174,7 @@ static int dnie_pin_verify(struct sc_card *card, * @param tries_left; if pin_verify() operation, on incorrect pin stores the number of tries left before car lock * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left */ -static int dnie_pin_cmd(struct sc_card *card, - struct sc_pin_cmd_data *data, int *tries_left) +static int dnie_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { int res = SC_SUCCESS; int lc = SC_CARDCTRL_LIFECYCLE_USER; @@ -2215,7 +2211,7 @@ static int dnie_pin_cmd(struct sc_card *card, /* This DNIe driver only supports VERIFY operation */ switch (data->cmd) { case SC_PIN_CMD_VERIFY: - res = dnie_pin_verify(card,data,tries_left); + res = dnie_pin_verify(card,data); break; case SC_PIN_CMD_CHANGE: res = dnie_pin_change(card,data); diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 3a7c5a070d..0569b5c8a0 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -596,8 +596,7 @@ dtrust_perform_pace(struct sc_card *card, static int dtrust_pin_cmd_get_info(struct sc_card *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { struct dtrust_drv_data_t *drv_data; int r; @@ -609,9 +608,6 @@ dtrust_pin_cmd_get_info(struct sc_card *card, switch (data->pin_reference) { case PACE_PIN_ID_CAN: /* unlimited number of retries */ - if (tries_left != NULL) { - *tries_left = -1; - } data->pin1.max_tries = -1; data->pin1.tries_left = -1; r = SC_SUCCESS; @@ -627,9 +623,6 @@ dtrust_pin_cmd_get_info(struct sc_card *card, /* FIXME: Doesn't work. Returns SW1=69 SW2=85 (Conditions of use not satisfied) instead. */ data->pin1.max_tries = 3; r = eac_pace_get_tries_left(card, data->pin_reference, &data->pin1.tries_left); - if (tries_left != NULL) { - *tries_left = data->pin1.tries_left; - } break; default: @@ -645,7 +638,7 @@ dtrust_pin_cmd_get_info(struct sc_card *card, } /* Now query PIN information */ - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); break; } @@ -654,8 +647,7 @@ dtrust_pin_cmd_get_info(struct sc_card *card, static int dtrust_pin_cmd_verify(struct sc_card *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { struct dtrust_drv_data_t *drv_data; int r; @@ -676,7 +668,7 @@ dtrust_pin_cmd_verify(struct sc_card *card, case DTRUST5_PIN_ID_PIN_T: case DTRUST5_PIN_ID_PIN_T_AUT: /* Establish secure channel via PACE */ - r = dtrust_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, tries_left); + r = dtrust_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, &data->pin1.tries_left); break; default: @@ -692,7 +684,7 @@ dtrust_pin_cmd_verify(struct sc_card *card, } /* Now verify the PIN */ - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); break; } @@ -702,8 +694,7 @@ dtrust_pin_cmd_verify(struct sc_card *card, static int dtrust_pin_cmd(struct sc_card *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { struct dtrust_drv_data_t *drv_data; int r; @@ -734,7 +725,7 @@ dtrust_pin_cmd(struct sc_card *card, /* Check verification state */ data2.cmd = SC_PIN_CMD_GET_INFO; data2.pin_type = data->pin_type; - r = dtrust_pin_cmd(card, &data2, tries_left); + r = dtrust_pin_cmd(card, &data2); if (data2.pin1.logged_in & SC_PIN_STATE_LOGGED_IN) { /* Return if we are already authenticated */ @@ -749,17 +740,17 @@ dtrust_pin_cmd(struct sc_card *card, /* No special handling for D-Trust Card 4.1/4.4 */ if (card->type >= SC_CARD_TYPE_DTRUST_V4_1_STD && card->type <= SC_CARD_TYPE_DTRUST_V4_4_MULTI) { - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); LOG_FUNC_RETURN(card->ctx, r); } switch (data->cmd) { case SC_PIN_CMD_GET_INFO: - r = dtrust_pin_cmd_get_info(card, data, tries_left); + r = dtrust_pin_cmd_get_info(card, data); break; case SC_PIN_CMD_VERIFY: - r = dtrust_pin_cmd_verify(card, data, tries_left); + r = dtrust_pin_cmd_verify(card, data); break; case SC_PIN_CMD_CHANGE: @@ -784,7 +775,7 @@ dtrust_pin_cmd(struct sc_card *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); break; case SC_PIN_CMD_UNBLOCK: @@ -796,7 +787,7 @@ dtrust_pin_cmd(struct sc_card *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); break; default: diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 0fefdab686..00ea9c8a9e 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -876,8 +876,7 @@ static void entersafe_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num pin->pad_char = 0x00; } -static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -886,7 +885,7 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->flags |= SC_PIN_CMD_NEED_PADDING; if (data->cmd != SC_PIN_CMD_UNBLOCK) { - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); sc_log(card->ctx, "Verify rv:%i", r); } else { { /*verify*/ diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index a1e4884893..b10da71994 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -377,7 +377,7 @@ static int eoi_logout(struct sc_card *card) LOG_FUNC_RETURN(card->ctx, r); } -static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { int r; @@ -396,7 +396,7 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * /* Verify PUK, establish SM if necessary */ data->cmd = SC_PIN_CMD_VERIFY; data->pin_reference = data->puk_reference; - r = eoi_pin_cmd(card, data, tries_left); + r = eoi_pin_cmd(card, data); if (r != SC_SUCCESS) LOG_FUNC_RETURN(card->ctx, r); /* RESET RETRY COUNTER */ @@ -404,7 +404,7 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * data->pin_reference = 0x80|pin_reference; data->pin1.len = 0; data->pin2.len = 0; - r = sc_get_iso7816_driver()->ops->pin_cmd(card, data, tries_left); + r = sc_get_iso7816_driver()->ops->pin_cmd(card, data); if (r != SC_SUCCESS) LOG_FUNC_RETURN(card->ctx, r); /* Continue as CHANGE PIN */ @@ -416,7 +416,7 @@ static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int * if (data->cmd == SC_PIN_CMD_CHANGE) data->pin1.len = 0; - LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->pin_cmd(card, data)); } static int diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 9a13e6a440..5a7b073624 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -3178,7 +3178,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, /* use external auth secret as pin */ static int -epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { int r; u8 kid; @@ -3202,8 +3202,6 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries r = get_external_key_retries(card, 0x80 | kid, &retries); if (r == SC_SUCCESS) { data->pin1.tries_left = retries; - if (tries_left) - *tries_left = retries; r = get_external_key_maxtries(card, &maxtries); LOG_TEST_RET(card->ctx, r, "get max counter failed"); diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index cf83180c8c..e7b204ae26 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -229,7 +229,7 @@ static int esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference) { return (int)apdu_resp[13]; } -static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { +static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r; struct sc_pin_cmd_data tmp; LOG_FUNC_CALLED(card->ctx); @@ -250,7 +250,7 @@ static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tr tmp.cmd = SC_PIN_CMD_VERIFY; tmp.pin_reference = PUK_REF; tmp.pin2.len = 0; - r = iso_ops->pin_cmd(card, &tmp, tries_left); + r = iso_ops->pin_cmd(card, &tmp); LOG_TEST_RET(card->ctx, r, "VERIFY during unblock failed"); if (data->pin_reference == PIN2_REF) { @@ -260,12 +260,12 @@ static int esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tr tmp = *data; tmp.cmd = SC_PIN_CMD_UNBLOCK; tmp.pin1.len = 0; - r = iso_ops->pin_cmd(card, &tmp, tries_left); + r = iso_ops->pin_cmd(card, &tmp); sc_mem_clear(&tmp, sizeof(tmp)); LOG_FUNC_RETURN(card->ctx, r); } - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data)); } static int esteid_init(sc_card_t *card) { diff --git a/src/libopensc/card-esteid2025.c b/src/libopensc/card-esteid2025.c index ae8e6cb467..4ebcdc93db 100644 --- a/src/libopensc/card-esteid2025.c +++ b/src/libopensc/card-esteid2025.c @@ -185,7 +185,7 @@ esteid_get_pin_info(sc_card_t *card, struct sc_pin_cmd_data *data) } static int -esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { LOG_FUNC_CALLED(card->ctx); sc_log(card->ctx, "PIN CMD is %d", data->cmd); @@ -193,7 +193,7 @@ esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) sc_log(card->ctx, "SC_PIN_CMD_GET_INFO for %d", data->pin_reference); LOG_FUNC_RETURN(card->ctx, esteid_get_pin_info(card, data)); } - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data)); } static int diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 8490a8351c..47fb7f33f7 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -1160,8 +1160,7 @@ static void flex_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num) pin->offset = 5 + num * 8; } -static int flex_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int flex_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { sc_apdu_t apdu; int r; @@ -1187,9 +1186,8 @@ static int flex_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, /* According to the Cryptoflex documentation, the card * does not return the number of attempts left using - * the 63C0xx convention, hence we don't pass the - * tries_left pointer. */ - r = iso_ops->pin_cmd(card, data, NULL); + * the 63C0xx convention */ + r = iso_ops->pin_cmd(card, data); if (old_cla != -1) card->cla = old_cla; data->apdu = NULL; diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index f42bf6b126..cca53728e4 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1026,11 +1026,11 @@ static int gids_get_pin_policy(struct sc_card *card, struct sc_pin_cmd_data *dat } static int -gids_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) { +gids_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { if (data->cmd == SC_PIN_CMD_GET_INFO) { return gids_get_pin_policy(card, data); } else { - return iso_ops->pin_cmd(card, data, tries_left); + return iso_ops->pin_cmd(card, data); } } @@ -1856,7 +1856,7 @@ static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) pindata.pin2.data = param->user_pin; pindata.pin_reference = 0x80; - r = sc_pin_cmd(card, &pindata, NULL); + r = sc_pin_cmd(card, &pindata); LOG_TEST_RET(card->ctx, r, "gids set pin"); // create file diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index b64256efed..d24d4b6837 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -144,8 +144,8 @@ static int iasecc_process_fci(struct sc_card *card, struct sc_file *file, const static int iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial); static int iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo); static int iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin); -static int iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left); -static int iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left); +static int iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data); +static int iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data); static int iasecc_check_update_pin(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin); static void iasecc_set_pin_padding(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin, size_t pad_len); @@ -1858,8 +1858,7 @@ iasecc_set_security_env(struct sc_card *card, static int -iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigned char *scbs, - int *tries_left) +iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigned char *scbs) { struct sc_context *ctx = card->ctx; unsigned char scb = scbs[IASECC_ACLS_CHV_VERIFY]; @@ -1870,11 +1869,11 @@ iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigne scb); if (scb & IASECC_SCB_METHOD_SM) { - rv = iasecc_sm_pin_verify(card, scb & IASECC_SCB_METHOD_MASK_REF, pin_cmd, tries_left); + rv = iasecc_sm_pin_verify(card, scb & IASECC_SCB_METHOD_MASK_REF, pin_cmd); LOG_FUNC_RETURN(ctx, rv); } - rv = iso_ops->pin_cmd(card, pin_cmd, tries_left); + rv = iso_ops->pin_cmd(card, pin_cmd); LOG_FUNC_RETURN(ctx, rv); } @@ -1917,7 +1916,7 @@ iasecc_se_at_to_chv_reference(struct sc_card *card, unsigned reference, static int -iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct sc_pin_cmd_data info; @@ -1933,7 +1932,7 @@ iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *t info.pin_type = data->pin_type; info.pin_reference = data->pin_reference; - rv = iso_ops->pin_cmd(card, &info, tries_left); + rv = iso_ops->pin_cmd(card, &info); LOG_TEST_RET(ctx, rv, "Failed to get PIN info"); data->pin1.max_tries = info.pin1.max_tries; @@ -1945,7 +1944,7 @@ iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *t static int -iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; unsigned type = data->pin_type; @@ -1961,7 +1960,7 @@ iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries type, reference, data->pin1.len, data->pin1.data); if (type == SC_AC_AUT) { - rv = iasecc_sm_external_authentication(card, reference, tries_left); + rv = iasecc_sm_external_authentication(card, reference, &data->pin1.tries_left); LOG_FUNC_RETURN(ctx, rv); } @@ -1988,7 +1987,7 @@ iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries pin_cmd.pin_reference = reference; pin_cmd.cmd = SC_PIN_CMD_VERIFY; - rv = iasecc_pin_get_status(card, &pin_cmd, tries_left); + rv = iasecc_pin_get_status(card, &pin_cmd); if (data->pin1.data && !data->pin1.len) LOG_FUNC_RETURN(ctx, rv); @@ -2013,7 +2012,7 @@ iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries iasecc_set_pin_padding(&pin_cmd, &pin_cmd.pin1, policy.stored_length); } - rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left); + rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs); /* * Detect and log PIN-pads which don't handle variable-length PIN - special case where they @@ -2140,7 +2139,7 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struc static int -iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct iasecc_pin_policy policy; @@ -2155,7 +2154,7 @@ iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri * tries, and the second one for the maximum tries. If a field is present in both, the * policy takes precedence. */ - rv = iasecc_pin_get_status(card, data, tries_left); + rv = iasecc_pin_get_status(card, data); LOG_TEST_RET(ctx, rv, "Failed to get PIN status"); rv = iasecc_pin_get_policy(card, data, &policy); @@ -2171,9 +2170,6 @@ iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri if (policy.tries_remaining >= 0) data->pin1.tries_left = policy.tries_remaining; - if (tries_left) - *tries_left = data->pin1.tries_left; - LOG_FUNC_RETURN(ctx, rv); } @@ -2256,7 +2252,7 @@ iasecc_pin_merge_policy(struct sc_card *card, struct sc_pin_cmd_data *data, static int -iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct iasecc_sdo_update update; @@ -2318,7 +2314,7 @@ iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr * Absent Absent Both PINs are input. */ static int -iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; struct sc_pin_cmd_data pin_cmd; @@ -2348,7 +2344,7 @@ iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries LOG_TEST_RET(ctx, rv, "Failed to update PIN1 info"); if (!(pin_cmd.flags & SC_PIN_CMD_USE_PINPAD)) { - rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left); + rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs); LOG_TEST_RET(ctx, rv, "PIN CHV verification error"); } @@ -2374,7 +2370,7 @@ iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries rv = iasecc_check_update_pin(&pin_cmd, &pin_cmd.pin2); LOG_TEST_RET(ctx, rv, "Invalid PIN2"); - rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left); + rv = iso_ops->pin_cmd(card, &pin_cmd); LOG_FUNC_RETURN(ctx, rv); } @@ -2389,7 +2385,7 @@ iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries * Absent Absent Both PUK and new PIN are input. */ static int -iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; unsigned char scb; @@ -2422,7 +2418,7 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_ pin_cmd.pin_type = SC_AC_SEN; pin_cmd.pin_reference = se_num; } - rv = iasecc_pin_verify(card, &pin_cmd, tries_left); + rv = iasecc_pin_verify(card, &pin_cmd); LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() verify PUK error"); if (!need_all) @@ -2435,7 +2431,7 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_ } if (scb & IASECC_SCB_METHOD_EXT_AUTH) { - rv = iasecc_sm_external_authentication(card, data->pin_reference, tries_left); + rv = iasecc_sm_external_authentication(card, data->pin_reference, &data->pin1.tries_left); LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() external authentication error"); } } while(0); @@ -2449,14 +2445,14 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_ rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin2, &policy); LOG_TEST_RET(ctx, rv, "Failed to update PIN2 info"); - rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left); + rv = iso_ops->pin_cmd(card, &pin_cmd); LOG_FUNC_RETURN(ctx, rv); } static int -iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; int rv; @@ -2468,19 +2464,19 @@ iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_le switch (data->cmd) { case SC_PIN_CMD_VERIFY: - rv = iasecc_pin_verify(card, data, tries_left); + rv = iasecc_pin_verify(card, data); break; case SC_PIN_CMD_CHANGE: if (data->pin_type == SC_AC_AUT) - rv = iasecc_keyset_change(card, data, tries_left); + rv = iasecc_keyset_change(card, data); else - rv = iasecc_pin_change(card, data, tries_left); + rv = iasecc_pin_change(card, data); break; case SC_PIN_CMD_UNBLOCK: - rv = iasecc_pin_reset(card, data, tries_left); + rv = iasecc_pin_reset(card, data); break; case SC_PIN_CMD_GET_INFO: - rv = iasecc_pin_get_info(card, data, tries_left); + rv = iasecc_pin_get_info(card, data); break; default: sc_log(ctx, "Other pin commands not supported yet: 0x%X", data->cmd); diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 778ad42ecc..095ce97bd0 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -293,8 +293,7 @@ static int itacns_set_security_env(sc_card_t *card, * cards by STIncard. */ static int -itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { data->flags |= SC_PIN_CMD_NEED_PADDING; /* Enable backtracking for STIncard cards. */ @@ -308,7 +307,7 @@ itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->pin1.max_length = 8; if (data->pin2.max_length == 0) data->pin2.max_length = 8; - return default_ops->pin_cmd(card, data, tries_left); + return default_ops->pin_cmd(card, data); } static int itacns_read_binary(sc_card_t *card, diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 71339491d1..195c8e84c6 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -209,7 +209,7 @@ jpki_select_file(struct sc_card *card, } static int -jpki_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +jpki_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int rc; sc_path_t path; @@ -219,10 +219,6 @@ jpki_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) LOG_FUNC_CALLED(card->ctx); - if (tries_left) { - *tries_left = -1; - } - switch (data->pin_reference) { case 1: sc_format_path(JPKI_AUTH_PIN, &path); @@ -274,9 +270,6 @@ jpki_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } data->pin1.logged_in = priv->logged_in; data->pin1.tries_left = apdu.sw2 & 0xF; - if (tries_left) { - *tries_left = data->pin1.tries_left; - } break; default: sc_log(card->ctx, "Card does not support PIN command: %d", data->cmd); diff --git a/src/libopensc/card-lteid.c b/src/libopensc/card-lteid.c index ba9d54376b..a582eb7b94 100644 --- a/src/libopensc/card-lteid.c +++ b/src/libopensc/card-lteid.c @@ -315,7 +315,7 @@ lteid_logout(sc_card_t *card) } static int -lteid_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +lteid_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -327,10 +327,10 @@ lteid_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr case PACE_PIN_ID_CAN: case PACE_PIN_ID_PIN: case PACE_PIN_ID_PUK: - rv = lteid_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, tries_left); + rv = lteid_perform_pace(card, data->pin_reference, data->pin1.data, data->pin1.len, &data->pin1.tries_left); break; default: - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); break; } @@ -338,7 +338,7 @@ lteid_pin_cmd_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr } static int -lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -350,10 +350,6 @@ lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int * data->pin1.max_tries = -1; data->pin1.tries_left = -1; - if (tries_left) { - *tries_left = -1; - } - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -389,10 +385,6 @@ lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int * if (tag && taglen == 2) { data->pin1.tries_left = tag[0]; data->pin1.max_tries = tag[1]; - - if (tries_left) { - *tries_left = data->pin1.tries_left; - } } else { LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND); } @@ -408,7 +400,7 @@ lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int * // PIN.QES is a regular iso7816 pin if (data->pin_reference == 0x81) { - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); LOG_FUNC_RETURN(card->ctx, rv); } @@ -416,7 +408,7 @@ lteid_pin_cmd_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int * } static int -lteid_pin_cmd_unblock(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +lteid_pin_cmd_unblock(struct sc_card *card, struct sc_pin_cmd_data *data) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -427,13 +419,13 @@ lteid_pin_cmd_unblock(struct sc_card *card, struct sc_pin_cmd_data *data, int *t struct sc_pin_cmd_data with_changed_pin_ref = *data; with_changed_pin_ref.pin_reference = 0x07; - rv = iso_ops->pin_cmd(card, &with_changed_pin_ref, tries_left); + rv = iso_ops->pin_cmd(card, &with_changed_pin_ref); LOG_FUNC_RETURN(card->ctx, rv); } // PIN.QES is a regular iso7816 pin if (data->pin_reference == 0x81) { - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); LOG_FUNC_RETURN(card->ctx, rv); } @@ -441,7 +433,7 @@ lteid_pin_cmd_unblock(struct sc_card *card, struct sc_pin_cmd_data *data, int *t } static int -lteid_pin_cmd_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +lteid_pin_cmd_change(struct sc_card *card, struct sc_pin_cmd_data *data) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -452,13 +444,13 @@ lteid_pin_cmd_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr struct sc_pin_cmd_data with_changed_pin_ref = *data; with_changed_pin_ref.pin_reference = 0x07; - rv = iso_ops->pin_cmd(card, &with_changed_pin_ref, tries_left); + rv = iso_ops->pin_cmd(card, &with_changed_pin_ref); LOG_FUNC_RETURN(card->ctx, rv); } // PIN.QES is a regular iso7816 pin if (data->pin_reference == 0x81) { - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); LOG_FUNC_RETURN(card->ctx, rv); } @@ -466,7 +458,7 @@ lteid_pin_cmd_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tr } static int -lteid_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +lteid_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -474,16 +466,16 @@ lteid_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_lef switch (data->cmd) { case SC_PIN_CMD_VERIFY: - rv = lteid_pin_cmd_verify(card, data, tries_left); + rv = lteid_pin_cmd_verify(card, data); break; case SC_PIN_CMD_GET_INFO: - rv = lteid_pin_cmd_get_info(card, data, tries_left); + rv = lteid_pin_cmd_get_info(card, data); break; case SC_PIN_CMD_UNBLOCK: - rv = lteid_pin_cmd_unblock(card, data, tries_left); + rv = lteid_pin_cmd_unblock(card, data); break; case SC_PIN_CMD_CHANGE: - rv = lteid_pin_cmd_change(card, data, tries_left); + rv = lteid_pin_cmd_change(card, data); break; default: rv = SC_ERROR_NOT_SUPPORTED; @@ -588,4 +580,4 @@ sc_get_lteid_driver(void) return NULL; } -#endif \ No newline at end of file +#endif diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index 9ecb0510d6..a1dca7b9be 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -207,8 +207,7 @@ static int masktech_decipher(sc_card_t *card, /* unblock pin cmd */ static int masktech_pin_unblock(sc_card_t *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { int rv = 0; struct sc_pin_cmd_data verify_data; @@ -223,7 +222,7 @@ static int masktech_pin_unblock(sc_card_t *card, verify_data.flags = data->flags; verify_data.pin1.prompt = data->pin1.prompt; - rv = iso_ops->pin_cmd(card, &verify_data, tries_left); + rv = iso_ops->pin_cmd(card, &verify_data); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify unblock PIN"); /* Build a SC_PIN_CMD_UNBLOCK APDU */ @@ -237,15 +236,14 @@ static int masktech_pin_unblock(sc_card_t *card, reset_data.flags = data->flags | SC_PIN_CMD_IMPLICIT_CHANGE; reset_data.pin2.prompt = data->pin2.prompt; - rv = iso_ops->pin_cmd(card, &reset_data, tries_left); + rv = iso_ops->pin_cmd(card, &reset_data); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - reset unblock PIN"); return 0; } static int masktech_pin_change(sc_card_t *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { int rv = 0; struct sc_pin_cmd_data verify_data; @@ -260,7 +258,7 @@ static int masktech_pin_change(sc_card_t *card, verify_data.flags = data->flags; verify_data.pin1.prompt = data->pin1.prompt; - rv = iso_ops->pin_cmd(card, &verify_data, tries_left); + rv = iso_ops->pin_cmd(card, &verify_data); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify change PIN"); /* Build a SC_PIN_CMD_CHANGE APDU */ @@ -274,15 +272,14 @@ static int masktech_pin_change(sc_card_t *card, change_data.flags = data->flags | SC_PIN_CMD_IMPLICIT_CHANGE; change_data.pin2.prompt = data->pin2.prompt; - rv = iso_ops->pin_cmd(card, &change_data, tries_left); + rv = iso_ops->pin_cmd(card, &change_data); LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - change PIN"); return 0; } static int masktech_pin_cmd(sc_card_t *card, - struct sc_pin_cmd_data *data, - int *tries_left) + struct sc_pin_cmd_data *data) { int rv; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -290,13 +287,13 @@ static int masktech_pin_cmd(sc_card_t *card, switch(data->cmd) { case SC_PIN_CMD_UNBLOCK: - rv = masktech_pin_unblock(card, data, tries_left); + rv = masktech_pin_unblock(card, data); break; case SC_PIN_CMD_CHANGE: - rv = masktech_pin_change(card, data, tries_left); + rv = masktech_pin_change(card, data); break; default: - rv = iso_ops->pin_cmd(card, data, tries_left); + rv = iso_ops->pin_cmd(card, data); break; } return rv; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 16f34602cc..6f9462a44a 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1025,8 +1025,7 @@ static int mcrd_compute_signature(sc_card_t * card, } /* added by -mp, to give pin information in the card driver (pkcs15emu->driver needed) */ -static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, - int *tries_left) +static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data) { LOG_FUNC_CALLED(card->ctx); data->pin1.offset = 5; @@ -1037,7 +1036,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, if (data->pin_reference == 0x02) data->pin_reference = data->pin_reference | 0x80; } - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->pin_cmd(card, data, tries_left)); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->pin_cmd(card, data)); } static int mcrd_logout(sc_card_t * card) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 455c37488a..18ca233a90 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -549,8 +549,7 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) return count; } -static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, - int *tries_left) +static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd) { muscle_private_t* priv = MUSCLE_DATA(card); const int bufferLength = MSC_MAX_PIN_COMMAND_LENGTH; @@ -566,7 +565,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, return r; cmd->apdu = &apdu; cmd->pin1.offset = 5; - r = iso_ops->pin_cmd(card, cmd, tries_left); + r = iso_ops->pin_cmd(card, cmd); if(r >= 0) priv->verifiedPins |= (1 << cmd->pin_reference); return r; @@ -588,7 +587,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, if (r < 0) return r; cmd->apdu = &apdu; - return iso_ops->pin_cmd(card, cmd, tries_left); + return iso_ops->pin_cmd(card, cmd); } case SC_AC_TERM: case SC_AC_PRO: @@ -607,7 +606,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, if (r < 0) return r; cmd->apdu = &apdu; - return iso_ops->pin_cmd(card, cmd, tries_left); + return iso_ops->pin_cmd(card, cmd); } case SC_AC_TERM: case SC_AC_PRO: diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 0f0fd287e8..b933676810 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -663,8 +663,7 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); } -static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { myeid_private_data_t *priv = (myeid_private_data_t *) card->drv_data; @@ -684,7 +683,7 @@ static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, return SC_SUCCESS; } - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data)); } #define IS_SYMETRIC_CRYPT(x) ((x) == SC_SEC_OPERATION_ENCRYPT_SYM || (x) == SC_SEC_OPERATION_DECRYPT_SYM) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index a32b6cfc68..deef8b9cda 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -472,12 +472,12 @@ static int npa_set_security_env(struct sc_card *card, } static int npa_pin_cmd_get_info(struct sc_card *card, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { int r; u8 pin_reference; - if (!data || data->pin_type != SC_AC_CHV || !tries_left) { + if (!data || data->pin_type != SC_AC_CHV) { r = SC_ERROR_INVALID_ARGUMENTS; goto err; } @@ -487,28 +487,25 @@ static int npa_pin_cmd_get_info(struct sc_card *card, case PACE_PIN_ID_CAN: case PACE_PIN_ID_MRZ: /* usually unlimited number of retries */ - *tries_left = -1; - data->pin1.max_tries = -1; data->pin1.tries_left = -1; + data->pin1.max_tries = -1; r = SC_SUCCESS; break; case PACE_PIN_ID_PUK: /* usually 10 tries */ - *tries_left = 10; + data->pin1.tries_left = 10; data->pin1.max_tries = 10; r = eac_pace_get_tries_left(card, - pin_reference, tries_left); - data->pin1.tries_left = *tries_left; + pin_reference, &data->pin1.tries_left); break; case PACE_PIN_ID_PIN: /* usually 3 tries */ - *tries_left = 3; + data->pin1.tries_left = 3; data->pin1.max_tries = 3; r = eac_pace_get_tries_left(card, - pin_reference, tries_left); - data->pin1.tries_left = *tries_left; + pin_reference, &data->pin1.tries_left); break; default: @@ -522,7 +519,7 @@ static int npa_pin_cmd_get_info(struct sc_card *card, static int npa_pace_verify(struct sc_card *card, unsigned char pin_reference, struct sc_pin_cmd_pin *pin, - const unsigned char *chat, size_t chat_length, int *tries_left) + const unsigned char *chat, size_t chat_length) { int r; struct establish_pace_channel_input pace_input; @@ -543,13 +540,11 @@ static int npa_pace_verify(struct sc_card *card, r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); - if (tries_left) { - if (pace_output.mse_set_at_sw1 == 0x63 - && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) { - *tries_left = pace_output.mse_set_at_sw2 & 0x0f; - } else { - *tries_left = -1; - } + if (pace_output.mse_set_at_sw1 == 0x63 + && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) { + pin->tries_left = pace_output.mse_set_at_sw2 & 0x0f; + } else { + pin->tries_left = -1; } /* resume the PIN if needed */ @@ -579,27 +574,23 @@ static int npa_pace_verify(struct sc_card *card, if (r == SC_SUCCESS) { sc_log(card->ctx, "%s resumed.\n", eac_secret_name(pin_reference)); - if (tries_left) { - *tries_left = EAC_MAX_PIN_TRIES; - } + pin->tries_left = EAC_MAX_PIN_TRIES; } else { - if (tries_left) { - if (pace_output.mse_set_at_sw1 == 0x63 - && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) { - *tries_left = pace_output.mse_set_at_sw2 & 0x0f; - } else { - *tries_left = -1; - } + if (pace_output.mse_set_at_sw1 == 0x63 + && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) { + pin->tries_left = pace_output.mse_set_at_sw2 & 0x0f; + } else { + pin->tries_left = -1; } } } } - if (pin_reference == PACE_PIN_ID_PIN && tries_left) { - if (*tries_left == 0) { + if (pin_reference == PACE_PIN_ID_PIN) { + if (pin->tries_left == 0) { sc_log(card->ctx, "%s is suspended and must be resumed.\n", eac_secret_name(pin_reference)); - } else if (*tries_left == 1) { + } else if (pin->tries_left == 1) { sc_log(card->ctx, "%s is blocked and must be unblocked.\n", eac_secret_name(pin_reference)); } @@ -616,7 +607,7 @@ static int npa_pace_verify(struct sc_card *card, } static int npa_standard_pin_cmd(struct sc_card *card, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { int r; struct sc_card_driver *iso_drv; @@ -626,7 +617,7 @@ static int npa_standard_pin_cmd(struct sc_card *card, if (!iso_drv || !iso_drv->ops || !iso_drv->ops->pin_cmd) { r = SC_ERROR_INTERNAL; } else { - r = iso_drv->ops->pin_cmd(card, data, tries_left); + r = iso_drv->ops->pin_cmd(card, data); } return r; @@ -704,7 +695,7 @@ npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id, } static int npa_pin_cmd(struct sc_card *card, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { int r; @@ -720,7 +711,7 @@ static int npa_pin_cmd(struct sc_card *card, switch (data->cmd) { case SC_PIN_CMD_GET_INFO: - r = npa_pin_cmd_get_info(card, data, tries_left); + r = npa_pin_cmd_get_info(card, data); if (r != SC_SUCCESS) goto err; break; @@ -737,7 +728,7 @@ static int npa_pin_cmd(struct sc_card *card, if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { /* PUK has not yet been verified */ r = npa_pace_verify(card, PACE_PIN_ID_PUK, &(data->pin1), NULL, - 0, NULL); + 0); if (r != SC_SUCCESS) goto err; } @@ -756,7 +747,7 @@ static int npa_pin_cmd(struct sc_card *card, case PACE_PIN_ID_MRZ: case PACE_PIN_ID_PIN: r = npa_pace_verify(card, data->pin_reference, - &(data->pin1), NULL, 0, tries_left); + &(data->pin1), NULL, 0); if (r != SC_SUCCESS) goto err; break; @@ -768,7 +759,7 @@ static int npa_pin_cmd(struct sc_card *card, * unlocked, see npa_init(). * * Now, verify the QES PIN. */ - r = npa_standard_pin_cmd(card, data, tries_left); + r = npa_standard_pin_cmd(card, data); if (r != SC_SUCCESS) goto err; break; diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index 37ee057cca..233741a3cb 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -451,17 +451,17 @@ static int nqapplet_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) } static int -nqapplet_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +nqapplet_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r; LOG_FUNC_CALLED(card->ctx); - r = iso_operations->pin_cmd(card, data, tries_left); + r = iso_operations->pin_cmd(card, data); if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* it is possible that the NQ-Applet is not active, try to activate it */ r = select_nqapplet(card, NULL, NULL, NULL, 0, NULL); if (r == SC_SUCCESS) { - r = iso_operations->pin_cmd(card, data, tries_left); + r = iso_operations->pin_cmd(card, data); } } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index c36580094e..3e0e181960 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -122,9 +122,9 @@ static int auth_read_component(struct sc_card *card, static int auth_pin_is_verified(struct sc_card *card, int pin_reference, int *tries_left); static int auth_pin_verify(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left); + struct sc_pin_cmd_data *data); static int auth_pin_reset(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left); + struct sc_pin_cmd_data *data); static int auth_create_reference_data (struct sc_card *card, struct sc_cardctl_oberthur_createpin_info *args); static int auth_get_serialnr(struct sc_card *card, struct sc_serial_number *serial); @@ -1566,8 +1566,8 @@ auth_pin_verify_pinpad(struct sc_card *card, int pin_reference, int *tries_left) memset(ffs1, 0xFF, sizeof(ffs1)); memset(&pin_cmd, 0, sizeof(pin_cmd)); - rv = auth_pin_is_verified(card, pin_reference, tries_left); - sc_log(card->ctx, "auth_pin_is_verified returned rv %i", rv); + rv = auth_pin_is_verified(card, pin_reference, tries_left); + sc_log(card->ctx, "auth_pin_is_verified returned rv %i", rv); /* Return SUCCESS without verifying if * PIN has been already verified and PIN pad has to be used. */ @@ -1601,7 +1601,7 @@ auth_pin_verify_pinpad(struct sc_card *card, int pin_reference, int *tries_left) pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PIN; pin_cmd.pin1.pad_length = OBERTHUR_AUTH_MAX_LENGTH_PIN; - rv = iso_drv->ops->pin_cmd(card, &pin_cmd, tries_left); + rv = iso_drv->ops->pin_cmd(card, &pin_cmd); LOG_TEST_RET(card->ctx, rv, "PIN CMD 'VERIFY' with pinpad failed"); LOG_FUNC_RETURN(card->ctx, rv); @@ -1610,7 +1610,7 @@ auth_pin_verify_pinpad(struct sc_card *card, int pin_reference, int *tries_left) static int auth_pin_verify(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); int rv; @@ -1629,7 +1629,7 @@ auth_pin_verify(struct sc_card *card, unsigned int type, || data->pin_reference == OBERTHUR_PIN_REFERENCE_ONETIME) data->pin_reference |= OBERTHUR_PIN_LOCAL; - rv = auth_pin_is_verified(card, data->pin_reference, tries_left); + rv = auth_pin_is_verified(card, data->pin_reference, &data->pin1.tries_left); sc_log(card->ctx, "auth_pin_is_verified returned rv %i", rv); /* Return if only PIN status has been asked. */ @@ -1642,9 +1642,9 @@ auth_pin_verify(struct sc_card *card, unsigned int type, LOG_FUNC_RETURN(card->ctx, rv); if (!data->pin1.data && !data->pin1.len) - rv = auth_pin_verify_pinpad(card, data->pin_reference, tries_left); + rv = auth_pin_verify_pinpad(card, data->pin_reference, &data->pin1.tries_left); else - rv = iso_drv->ops->pin_cmd(card, data, tries_left); + rv = iso_drv->ops->pin_cmd(card, data); LOG_FUNC_RETURN(card->ctx, rv); } @@ -1677,8 +1677,7 @@ auth_pin_is_verified(struct sc_card *card, int pin_reference, int *tries_left) static int -auth_pin_change_pinpad(struct sc_card *card, struct sc_pin_cmd_data *data, - int *tries_left) +auth_pin_change_pinpad(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); struct sc_pin_cmd_data pin_cmd; @@ -1726,7 +1725,7 @@ auth_pin_change_pinpad(struct sc_card *card, struct sc_pin_cmd_data *data, pin_cmd.pin1.offset = 5; pin_cmd.pin2.data = ffs2; - rv = iso_drv->ops->pin_cmd(card, &pin_cmd, tries_left); + rv = iso_drv->ops->pin_cmd(card, &pin_cmd); LOG_TEST_RET(card->ctx, rv, "PIN CMD 'VERIFY' with pinpad failed"); LOG_FUNC_RETURN(card->ctx, rv); @@ -1735,7 +1734,7 @@ auth_pin_change_pinpad(struct sc_card *card, struct sc_pin_cmd_data *data, static int auth_pin_change(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); int rv = SC_ERROR_INTERNAL; @@ -1753,11 +1752,11 @@ auth_pin_change(struct sc_card *card, unsigned int type, auth_init_pin_info(card, &data->pin1, OBERTHUR_AUTH_TYPE_PIN); auth_init_pin_info(card, &data->pin2, OBERTHUR_AUTH_TYPE_PIN); - rv = iso_drv->ops->pin_cmd(card, data, tries_left); + rv = iso_drv->ops->pin_cmd(card, data); LOG_TEST_RET(card->ctx, rv, "CMD 'PIN CHANGE' failed"); } else if (!data->pin1.len && !data->pin2.len) { /* Oberthur unblock style with PIN pad. */ - rv = auth_pin_change_pinpad(card, data, tries_left); + rv = auth_pin_change_pinpad(card, data); LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failed: SOPIN verify with pinpad failed"); } else { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed"); @@ -1769,7 +1768,7 @@ auth_pin_change(struct sc_card *card, unsigned int type, static int auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); struct sc_pin_cmd_data pin_cmd; @@ -1795,7 +1794,7 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, pin_cmd.pin_reference = OBERTHUR_PIN_REFERENCE_PUK; memcpy(&pin_cmd.pin1, &data->pin1, sizeof(pin_cmd.pin1)); - rv = auth_pin_verify(card, SC_AC_CHV, &pin_cmd, tries_left); + rv = auth_pin_verify(card, SC_AC_CHV, &pin_cmd); LOG_TEST_RET(card->ctx, rv, "Oberthur style 'PIN RESET' failed: SOPIN verify error"); sc_format_path("2000", &tmp_path); @@ -1827,7 +1826,7 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, if (data->pin2.data) { memcpy(&pin_cmd.pin2, &data->pin2, sizeof(pin_cmd.pin2)); - rv = auth_pin_reset(card, SC_AC_CHV, &pin_cmd, tries_left); + rv = auth_pin_reset(card, SC_AC_CHV, &pin_cmd); LOG_FUNC_RETURN(card->ctx, rv); } @@ -1851,7 +1850,7 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, pin_cmd.pin2.max_length = 8; pin_cmd.pin2.encoding = SC_PIN_ENCODING_ASCII; - rvv = iso_drv->ops->pin_cmd(card, &pin_cmd, tries_left); + rvv = iso_drv->ops->pin_cmd(card, &pin_cmd); if (rvv) sc_log(card->ctx, "%s: PIN CMD 'VERIFY' with pinpad failed", @@ -1876,14 +1875,14 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, static int auth_pin_reset(struct sc_card *card, unsigned int type, - struct sc_pin_cmd_data *data, int *tries_left) + struct sc_pin_cmd_data *data) { int rv; LOG_FUNC_CALLED(card->ctx); /* Oberthur unblock style: PUK value is a SOPIN */ - rv = auth_pin_reset_oberthur_style(card, SC_AC_CHV, data, tries_left); + rv = auth_pin_reset_oberthur_style(card, SC_AC_CHV, data); LOG_TEST_RET(card->ctx, rv, "Oberthur style 'PIN RESET' failed"); LOG_FUNC_RETURN(card->ctx, rv); @@ -1891,7 +1890,7 @@ auth_pin_reset(struct sc_card *card, unsigned int type, static int -auth_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +auth_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { int rv = SC_ERROR_INTERNAL; @@ -1904,15 +1903,15 @@ auth_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left data->pin2.data, data->pin2.len); switch (data->cmd) { case SC_PIN_CMD_VERIFY: - rv = auth_pin_verify(card, SC_AC_CHV, data, tries_left); + rv = auth_pin_verify(card, SC_AC_CHV, data); LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed"); break; case SC_PIN_CMD_CHANGE: - rv = auth_pin_change(card, SC_AC_CHV, data, tries_left); + rv = auth_pin_change(card, SC_AC_CHV, data); LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed"); break; case SC_PIN_CMD_UNBLOCK: - rv = auth_pin_reset(card, SC_AC_CHV, data, tries_left); + rv = auth_pin_reset(card, SC_AC_CHV, data); LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed"); break; default: diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0d1c3e1112..4874c80fbb 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2300,7 +2300,7 @@ kdf_itersalted_s2k(struct sc_context *ctx, const char *hash, const uint8_t *pin, } static int -pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r = SC_ERROR_INVALID_ARGUMENTS; struct pgp_priv_data *priv = DRVDATA(card); @@ -2322,7 +2322,7 @@ pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_lef case SC_PIN_CMD_UNBLOCK: break; default: - LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data)); } if (!info) { return r; @@ -2365,7 +2365,7 @@ pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_lef } if (r == SC_SUCCESS) { - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); } if (pin1_derived) { data->pin1.data = pin1; @@ -2385,7 +2385,7 @@ pgp_kdf_do_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_lef * ABI: ISO 7816-9 PIN CMD - verify/change/unblock a PIN. */ static int -pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { struct pgp_priv_data *priv = DRVDATA(card); struct sc_card_operations ops = {.pin_cmd = iso_ops->pin_cmd}; @@ -2482,10 +2482,8 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) data->pin1.tries_left = c4data[3 + (data->pin_reference & 0x0F)]; data->pin1.max_tries = 3; data->pin1.logged_in = SC_PIN_STATE_UNKNOWN; - if (tries_left != NULL) - *tries_left = data->pin1.tries_left; - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } #ifdef ENABLE_OPENSSL @@ -2494,7 +2492,7 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } #endif /* ENABLE_OPENSSL */ - LOG_FUNC_RETURN(card->ctx, ops.pin_cmd(card, data, tries_left)); + LOG_FUNC_RETURN(card->ctx, ops.pin_cmd(card, data)); } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 005cf5633a..3d9a829727 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -6197,7 +6197,7 @@ piv_check_protected_objects(sc_card_t *card) } static int -piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) +piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r = 0; piv_private_data_t *priv = PIV_DATA(card); @@ -6227,8 +6227,6 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (data->cmd == SC_PIN_CMD_GET_INFO) { /* fill in what we think it should be */ data->pin1.logged_in = priv->logged_in; data->pin1.tries_left = priv->tries_left; - if (tries_left) - *tries_left = priv->tries_left; /* * If called to check on the login state for a context specific login @@ -6270,7 +6268,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) } priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ - r = iso_drv->ops->pin_cmd(card, data, tries_left); + r = iso_drv->ops->pin_cmd(card, data); priv->pin_cmd_verify = 0; /* tell user verify not supported on contactless without VCI */ @@ -6294,7 +6292,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) piv_find_aid(card); priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */ - r = iso_drv->ops->pin_cmd(card, data, tries_left); + r = iso_drv->ops->pin_cmd(card, data); priv->pin_cmd_verify = 0; } diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 26f3e07478..b22ca52174 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -343,8 +343,7 @@ static int sc_hsm_soc_select_minbioclient(sc_card_t *card) return iso7816_select_aid(card, minBioClient_aid.value, minBioClient_aid.len, NULL, NULL); } -static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data) { sc_apdu_t apdu; sc_path_t path; @@ -410,8 +409,7 @@ static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data, return r; } -static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data) { sc_apdu_t apdu; sc_path_t path; @@ -449,8 +447,7 @@ static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data, return r; } -static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data) { sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; @@ -615,8 +612,7 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) -static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; sc_apdu_t apdu; @@ -640,12 +636,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, && (data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x81) && (!data->pin1.data || data->pin1.len <= 0)) { - return sc_hsm_soc_change(card, data, tries_left); + return sc_hsm_soc_change(card, data); } else if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH) && (data->cmd == SC_PIN_CMD_UNBLOCK) && (data->pin_reference == 0x81) && (!data->pin1.data || data->pin1.len <= 0)) { - return sc_hsm_soc_unblock(card, data, tries_left); + return sc_hsm_soc_unblock(card, data); } #ifdef ENABLE_SM @@ -664,7 +660,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, r = SC_ERROR_NOT_ALLOWED; if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) { /* check if the existing SM channel is still valid */ - r = sc_pin_cmd(card, &check_sm_pin_data, NULL); + r = sc_pin_cmd(card, &check_sm_pin_data); } if (r == SC_ERROR_ASN1_OBJECT_NOT_FOUND || r == SC_ERROR_NOT_ALLOWED) { /* need to establish a new SM channel */ @@ -679,7 +675,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, && (data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x81) && (!data->pin1.data || data->pin1.len <= 0)) { - r = sc_hsm_soc_biomatch(card, data, tries_left); + r = sc_hsm_soc_biomatch(card, data); } else { if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) { if (data->pin1.len != 16) @@ -724,7 +720,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->pin1.offset = 5; data->pin2.offset = 5; - r = (*iso_ops->pin_cmd)(card, data, tries_left); + r = (*iso_ops->pin_cmd)(card, data); data->apdu = NULL; } LOG_TEST_RET(card->ctx, r, "Verification failed"); @@ -1318,7 +1314,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa pincmd.pin1.data = params->user_pin; pincmd.pin1.len = params->user_pin_len; - r = (*iso_ops->pin_cmd)(card, &pincmd, NULL); + r = (*iso_ops->pin_cmd)(card, &pincmd); LOG_TEST_RET(ctx, r, "Could not verify PIN"); r = sc_hsm_write_ef(card, 0x2F03, 0, p, tilen); diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 204c9fefc0..429e5237fa 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -2075,8 +2075,7 @@ static int starcos_logout(sc_card_t *card) return sc_check_sw(card, apdu.sw1, apdu.sw2); } -static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r; @@ -2086,7 +2085,7 @@ static int starcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->flags |= SC_PIN_CMD_NEED_PADDING; data->pin1.encoding = ex_data->pin_encoding; } - r = iso_ops->pin_cmd(card, data, tries_left); + r = iso_ops->pin_cmd(card, data); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } diff --git a/src/libopensc/iasecc-sdo.h b/src/libopensc/iasecc-sdo.h index 5787398619..1d9f0d27df 100644 --- a/src/libopensc/iasecc-sdo.h +++ b/src/libopensc/iasecc-sdo.h @@ -322,7 +322,7 @@ int iasecc_docp_copy(struct sc_context *, struct iasecc_sdo_docp *, struct iasec int iasecc_se_get_info(struct sc_card *card, struct iasecc_se_info *se); int iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *tries_left); -int iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data, int *tries_left); +int iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data); int iasecc_sm_pin_reset(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data); int iasecc_sm_update_binary(struct sc_card *card, unsigned se_num, size_t offs, const unsigned char *buff, size_t count); int iasecc_sm_read_binary(struct sc_card *card, unsigned se_num, size_t offs, unsigned char *buff, size_t count); diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index 6e3d8b5223..e589e8d7ae 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -447,7 +447,7 @@ iasecc_sm_rsa_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_rs int -iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data, int *tries_left) +iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data) { struct sc_context *ctx = card->ctx; #ifdef ENABLE_SM @@ -465,9 +465,9 @@ iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_da sc_remote_data_init(&rdata); rv = iasecc_sm_cmd(card, &rdata); - if (rv && rdata.length && tries_left) + if (rv && rdata.length) if (rdata.data->apdu.sw1 == 0x63 && (rdata.data->apdu.sw2 & 0xF0) == 0xC0) - *tries_left = rdata.data->apdu.sw2 & 0x0F; + data->pin1.tries_left = rdata.data->apdu.sw2 & 0x0F; LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM 'PIN VERIFY' failed"); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 2d509920c8..3097eeadd6 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1284,16 +1284,13 @@ iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu, static int -iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) { struct sc_apdu local_apdu, *apdu; int r; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; data->pin1.tries_left = -1; - if (tries_left != NULL) { - *tries_left = data->pin1.tries_left; - } /* Many cards do support PIN status queries, but some cards don't and * mistakenly count the command as a failed PIN attempt, so for now we @@ -1363,9 +1360,6 @@ iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_l if (data->cmd == SC_PIN_CMD_GET_INFO) r = SC_SUCCESS; } - if (tries_left != NULL) { - *tries_left = data->pin1.tries_left; - } return r; } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 73c2700c27..144e8012c0 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -800,8 +800,7 @@ struct sc_card_operations { /* pin_cmd: verify/change/unblock command; optionally using the * card's pin pad if supported. */ - int (*pin_cmd)(struct sc_card *, struct sc_pin_cmd_data *, - int *tries_left); + int (*pin_cmd)(struct sc_card *, struct sc_pin_cmd_data *); int (*get_data)(struct sc_card *, unsigned int, u8 *, size_t); int (*put_data)(struct sc_card *, unsigned int, const u8 *, size_t); @@ -1389,7 +1388,7 @@ int sc_verify(struct sc_card *card, unsigned int type, int ref, const u8 *pin, * doesn't support a logout command and an error code otherwise */ int sc_logout(struct sc_card *card); -int sc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *, int *tries_left); +int sc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *); int sc_change_reference_data(struct sc_card *card, unsigned int type, int ref, const u8 *old, size_t oldlen, const u8 *newref, size_t newlen, diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index 74f2eec8a7..c0565b66c4 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -68,7 +68,7 @@ sc_pkcs15emu_din_66291_init(sc_pkcs15_card_t *p15card) data.pin_type = SC_AC_CHV; data.pin_reference = user_pin_ref; - if (SC_SUCCESS == sc_pin_cmd(p15card->card, &data, NULL)) { + if (SC_SUCCESS == sc_pin_cmd(p15card->card, &data)) { const unsigned char user_pin_id = 1; for (i = 0; i < 2; i++) { diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index dcae178bd6..99571fd0d6 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -182,7 +182,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) pin_cmd_data.pin_type = SC_AC_CHV; pin_cmd_data.pin_reference = pin_info.attrs.pin.reference; - r = sc_pin_cmd(card, &pin_cmd_data, NULL); + r = sc_pin_cmd(card, &pin_cmd_data); if (r == SC_SUCCESS) { pin_info.max_tries = pin_cmd_data.pin1.max_tries; pin_info.tries_left = pin_cmd_data.pin1.tries_left; @@ -196,7 +196,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card) * link PIN with PUK. */ pin_cmd_data.pin_reference = 0x81; - has_puk = sc_pin_cmd(card, &pin_cmd_data, NULL) == SC_SUCCESS; + has_puk = sc_pin_cmd(card, &pin_cmd_data) == SC_SUCCESS; if (has_puk) { pin_obj.auth_id.len = 1; pin_obj.auth_id.value[0] = 0x81; diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index 5711e739bf..05e1cb330c 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -142,7 +142,8 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card) pin_cmd_data.cmd = SC_PIN_CMD_GET_INFO; pin_cmd_data.pin_type = SC_AC_CHV; pin_cmd_data.pin_reference = jpki_pin_ref[i]; - rc = sc_pin_cmd(card, &pin_cmd_data, &pin_info.tries_left); + rc = sc_pin_cmd(card, &pin_cmd_data); + pin_info.tries_left = pin_cmd_data.pin1.tries_left; LOG_TEST_RET(card->ctx, rc, "sc_pin_cmd failed"); strlcpy(pin_obj.label, jpki_pin_names[i], sizeof(pin_obj.label)); pin_obj.flags = jpki_pin_flags[i]; diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 1203478260..816ddb9b7f 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -439,7 +439,8 @@ int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card, goto out; } - r = sc_pin_cmd(card, &data, &auth_info->tries_left); + r = sc_pin_cmd(card, &data); + auth_info->tries_left = data.pin1.tries_left; sc_log(ctx, "PIN cmd result %i", r); if (r == SC_SUCCESS) { sc_pkcs15_pincache_add(p15card, pin_obj, pincode, pinlen); @@ -548,7 +549,8 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card, } } - r = sc_pin_cmd(card, &data, &auth_info->tries_left); + r = sc_pin_cmd(card, &data); + auth_info->tries_left = data.pin1.tries_left; if (r == SC_SUCCESS) sc_pkcs15_pincache_add(p15card, pin_obj, newpin, newpinlen); @@ -674,7 +676,8 @@ int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *p15card, } } - r = sc_pin_cmd(card, &data, &auth_info->tries_left); + r = sc_pin_cmd(card, &data); + auth_info->tries_left = data.pin1.tries_left; if (r == SC_SUCCESS) sc_pkcs15_pincache_add(p15card, pin_obj, newpin, newpinlen); @@ -716,11 +719,10 @@ int sc_pkcs15_get_pin_info(struct sc_pkcs15_card *p15card, data.pin_type = pin_info->auth_method; data.pin_reference = pin_info->attrs.pin.reference; - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r == SC_SUCCESS) { if (data.pin1.max_tries > 0) pin_info->max_tries = data.pin1.max_tries; - /* tries_left must be supported or sc_pin_cmd should not return SC_SUCCESS */ pin_info->tries_left = data.pin1.tries_left; pin_info->logged_in = data.pin1.logged_in; } diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index 37b2d2ec71..42b8412226 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -274,7 +274,7 @@ static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card) pin_cmd_data.cmd = SC_PIN_CMD_GET_INFO; pin_cmd_data.pin_type = pin_info->attrs.pin.type; pin_cmd_data.pin_reference = pin_info->attrs.pin.reference; - rv = sc_pin_cmd(p15card->card, &pin_cmd_data, NULL); + rv = sc_pin_cmd(p15card->card, &pin_cmd_data); if (rv == SC_SUCCESS) { pin_info->tries_left = pin_cmd_data.pin1.tries_left; pin_info->logged_in = pin_cmd_data.pin1.logged_in; diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 13151ca387..614c43cbad 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1555,7 +1555,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pindata.pin_type = SC_AC_CHV; pindata.pin_reference = 0x85; - r = sc_pin_cmd(card, &pindata, NULL); + r = sc_pin_cmd(card, &pindata); } if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) { memset(&pindata, 0, sizeof(pindata)); @@ -1563,7 +1563,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pindata.pin_type = SC_AC_CHV; pindata.pin_reference = 0x86; - r = sc_pin_cmd(card, &pindata, NULL); + r = sc_pin_cmd(card, &pindata); } if ((r != SC_ERROR_DATA_OBJECT_NOT_FOUND) && (r != SC_ERROR_INCORRECT_PARAMETERS) && (r != SC_ERROR_REF_DATA_NOT_USABLE)) diff --git a/src/libopensc/pkcs15-srbeid.c b/src/libopensc/pkcs15-srbeid.c index 447a934e2c..7846d51505 100644 --- a/src/libopensc/pkcs15-srbeid.c +++ b/src/libopensc/pkcs15-srbeid.c @@ -436,16 +436,15 @@ sc_pkcs15emu_srbeid_init(sc_pkcs15_card_t *p15card) /* Query PIN tries_left via card driver's pin_cmd. */ { struct sc_pin_cmd_data pin_data = {0}; - int pin_tries_left = -1; pin_data.cmd = SC_PIN_CMD_GET_INFO; pin_data.pin_type = SC_AC_CHV; pin_data.pin_reference = CE_PIN_REFERENCE; + pin_data.pin1.tries_left = -1; /* Best-effort: failure to query PIN status is not fatal. */ - if (sc_pin_cmd(card, &pin_data, &pin_tries_left) >= 0 && pin_tries_left < 0) - pin_tries_left = pin_data.pin1.tries_left; - sc_log(card->ctx, "srbeid: PIN tries_left=%d", pin_tries_left); + sc_pin_cmd(card, &pin_data); + sc_log(card->ctx, "srbeid: PIN tries_left=%d", pin_data.pin1.tries_left); /* ---- PIN auth object ---- * Must be registered before private keys so auth_id links work. */ @@ -455,7 +454,7 @@ sc_pkcs15emu_srbeid_init(sc_pkcs15_card_t *p15card) auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; auth_info.auth_method = SC_AC_CHV; - auth_info.tries_left = pin_tries_left; + auth_info.tries_left = pin_data.pin1.tries_left; auth_info.attrs.pin.reference = CE_PIN_REFERENCE; auth_info.attrs.pin.min_length = 4; auth_info.attrs.pin.max_length = CE_PIN_MAX_LENGTH; diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 6bd319e739..c2719161c4 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -138,7 +138,11 @@ int sc_verify(sc_card_t *card, unsigned int type, int ref, data.pin1.data = pin; data.pin1.len = pinlen; - return sc_pin_cmd(card, &data, tries_left); + int r = sc_pin_cmd(card, &data); + if (tries_left) + *tries_left = data.pin1.tries_left; + + return r; } int sc_logout(sc_card_t *card) @@ -164,7 +168,11 @@ int sc_change_reference_data(sc_card_t *card, unsigned int type, data.pin2.data = newref; data.pin2.len = newlen; - return sc_pin_cmd(card, &data, tries_left); + int r = sc_pin_cmd(card, &data); + if (tries_left) + *tries_left = data.pin1.tries_left; + + return r; } int sc_reset_retry_counter(sc_card_t *card, unsigned int type, int ref, @@ -182,7 +190,7 @@ int sc_reset_retry_counter(sc_card_t *card, unsigned int type, int ref, data.pin2.data = newref; data.pin2.len = newlen; - return sc_pin_cmd(card, &data, NULL); + return sc_pin_cmd(card, &data); } /* @@ -192,8 +200,7 @@ int sc_reset_retry_counter(sc_card_t *card, unsigned int type, int ref, * send this PIN to the card. If no PIN was given, the driver should * ask the reader to obtain the pin(s) via the pin pad */ -int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, - int *tries_left) +int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data) { int r, debug; @@ -209,7 +216,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, } if (card->ops->pin_cmd) { - r = card->ops->pin_cmd(card, data, tries_left); + r = card->ops->pin_cmd(card, data); } else if (!(data->flags & SC_PIN_CMD_USE_PINPAD)) { /* Card driver doesn't support new style pin_cmd, fall * back to old interface */ @@ -223,7 +230,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data->pin_reference, data->pin1.data, (size_t) data->pin1.len, - tries_left); + &data->pin1.tries_left); break; case SC_PIN_CMD_CHANGE: if (card->ops->change_reference_data != NULL) @@ -234,7 +241,7 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, (size_t) data->pin1.len, data->pin2.data, (size_t) data->pin2.len, - tries_left); + &data->pin1.tries_left); break; case SC_PIN_CMD_UNBLOCK: if (card->ops->reset_retry_counter != NULL) diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index a3c1434658..03b51c4a1b 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -588,7 +588,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, pin_cmd.pin1.data = dummy_pin_value; pin_cmd.pin1.len = sizeof(dummy_pin_value); - r = sc_pin_cmd(p15card->card, &pin_cmd, NULL); + r = sc_pin_cmd(p15card->card, &pin_cmd); if (r < 0) sc_file_free(file); LOG_TEST_RET(ctx, r, "Cannot verify dummy PIN"); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index b5f02971e1..faa9037bc7 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -4056,7 +4056,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p pin_cmd.pin1.data = use_pinpad ? NULL : pinbuf; pin_cmd.pin1.len = use_pinpad ? 0: pinsize; - r = sc_pin_cmd(p15card->card, &pin_cmd, NULL); + r = sc_pin_cmd(p15card->card, &pin_cmd); LOG_TEST_RET(ctx, r, "'VERIFY' pin cmd failed"); } diff --git a/src/tools/dtrust-tool.c b/src/tools/dtrust-tool.c index 4596c4617a..e6dee122fc 100644 --- a/src/tools/dtrust-tool.c +++ b/src/tools/dtrust-tool.c @@ -211,20 +211,19 @@ pin_status(sc_card_t *card, int ref, const char *pin_label, unsigned char transp { int r; struct sc_pin_cmd_data data; - int tries_left = 0; memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_GET_INFO; data.pin_type = SC_AC_CHV; data.pin_reference = ref; - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r == SC_SUCCESS) { - if (tries_left < 0) + if (data.pin1.tries_left < 0) printf("%s: usable\n", pin_label); else - printf("%s: usable (%d tries left)\n", pin_label, tries_left); + printf("%s: usable (%d tries left)\n", pin_label, data.pin1.tries_left); } else if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) printf("%s: not usable (transport protection still in force)\n", pin_label); else if (r == SC_ERROR_AUTH_METHOD_BLOCKED) @@ -292,7 +291,6 @@ unlock_transport_protection4(sc_card_t *card) int r; char *tpin = NULL; char *qespin = NULL; - int tries_left; memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_CHANGE; @@ -323,12 +321,12 @@ unlock_transport_protection4(sc_card_t *card) data.pin2.len = strlen(qespin); } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r == SC_SUCCESS) printf("Transport protection removed. You can now use your Signature PIN.\n"); else if (r == SC_ERROR_PIN_CODE_INCORRECT) - printf("Wrong pin. %d attempts left.\n", tries_left); + printf("Wrong pin. %d attempts left.\n", data.pin1.tries_left); else printf("Can't change pin: %s\n", sc_strerror(r)); @@ -352,7 +350,6 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c struct sc_pin_cmd_data data; char *tpin = NULL; char *newpin = NULL; - int tries_left; printf("Unlocking %s\n", pin_label); @@ -387,11 +384,11 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c data.pin1.len = strlen(tpin); } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r) { fprintf(stderr, "Error verifying Transport PIN: %s\n", sc_strerror(r)); - if (tries_left >= 0) - fprintf(stderr, "%d attempts left.\n", tries_left); + if (data.pin1.tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", data.pin1.tries_left); goto fail; } @@ -424,7 +421,7 @@ unlock_transport_protection5(sc_card_t *card, int ref_pace, int ref_pin, const c * continue as long as the new PIN is set successfully or the user * aborts the program and renders its card unusable as a consequence. */ do { - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r == SC_SUCCESS) { printf("Transport protection removed. You can now use your %s.\n", pin_label); break; @@ -457,7 +454,6 @@ change_pin(sc_card_t *card, int ref_verify, int ref_change) char *newpin = NULL; sc_path_t path; int r; - int tries_left; memset(&data_verify, 0, sizeof(struct sc_pin_cmd_data)); memset(&data_change, 0, sizeof(struct sc_pin_cmd_data)); @@ -573,11 +569,11 @@ change_pin(sc_card_t *card, int ref_verify, int ref_change) goto fail; } - r = sc_pin_cmd(card, &data_verify, &tries_left); + r = sc_pin_cmd(card, &data_verify); if (r) { fprintf(stderr, "Error verifying PIN: %s\n", sc_strerror(r)); - if (tries_left >= 0) - fprintf(stderr, "%d attempts left.\n", tries_left); + if (data_verify.pin1.tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", data_verify.pin1.tries_left); goto fail; } @@ -589,7 +585,7 @@ change_pin(sc_card_t *card, int ref_verify, int ref_change) } } - r = sc_pin_cmd(card, &data_change, NULL); + r = sc_pin_cmd(card, &data_change); if (r) { fprintf(stderr, "Error changing PIN: %s\n", sc_strerror(r)); goto fail; @@ -658,7 +654,7 @@ resume_pin(sc_card_t *card, int ref_pin) goto fail; } - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r) { fprintf(stderr, "Error resuming PIN: %s\n", sc_strerror(r)); goto fail; @@ -677,7 +673,6 @@ unblock_pin(sc_card_t *card, int ref_pin) char *puk = NULL; sc_path_t path; int r; - int tries_left; memset(&data_verify, 0, sizeof(struct sc_pin_cmd_data)); memset(&data_unblock, 0, sizeof(struct sc_pin_cmd_data)); @@ -759,11 +754,11 @@ unblock_pin(sc_card_t *card, int ref_pin) goto fail; } - r = sc_pin_cmd(card, &data_verify, &tries_left); + r = sc_pin_cmd(card, &data_verify); if (r) { fprintf(stderr, "Error verifying PUK: %s\n", sc_strerror(r)); - if (tries_left >= 0) - fprintf(stderr, "%d attempts left.\n", tries_left); + if (data_verify.pin1.tries_left >= 0) + fprintf(stderr, "%d attempts left.\n", data_verify.pin1.tries_left); goto fail; } @@ -775,7 +770,7 @@ unblock_pin(sc_card_t *card, int ref_pin) } } - r = sc_pin_cmd(card, &data_unblock, NULL); + r = sc_pin_cmd(card, &data_unblock); if (r) { fprintf(stderr, "Error unblocking PIN: %s\n", sc_strerror(r)); goto fail; @@ -939,7 +934,7 @@ main(int argc, char *argv[]) if (r) goto out; - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r) { fprintf(stderr, "Error verifying CAN.\n"); goto out; diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 96fe63a980..8c30628fd9 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -228,7 +228,7 @@ static int unblock(sc_card_t* card, const char *so_pin, const char *user_pin) { data.pin2.len = strlen(_user_pin); data.pin2.data = (unsigned char*) _user_pin; data.pin_reference = 0x80; - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r < 0) { fprintf(stderr, "reset pin failed with %s\n", sc_strerror(r)); return -1; diff --git a/src/tools/lteid-tool.c b/src/tools/lteid-tool.c index 6b0e1c041c..3a8c6e9c42 100644 --- a/src/tools/lteid-tool.c +++ b/src/tools/lteid-tool.c @@ -197,7 +197,7 @@ verify_and_cache_pace_can(sc_card_t *card, const char *opt_can) can_verify_cmd.pin1.data = (unsigned char *)can; can_verify_cmd.pin1.len = strlen(can); - rv = card->ops->pin_cmd(card, &can_verify_cmd, NULL); + rv = card->ops->pin_cmd(card, &can_verify_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "CAN number verification failed: %s\nCheck the number and try again.\n", sc_strerror(rv)); @@ -249,7 +249,7 @@ change_pin(sc_card_t *card, const char *opt_pin) pin_verify_cmd.pin1.data = (unsigned char *)pin; pin_verify_cmd.pin1.len = strlen(pin); - rv = card->ops->pin_cmd(card, &pin_verify_cmd, NULL); + rv = card->ops->pin_cmd(card, &pin_verify_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(rv)); @@ -279,7 +279,7 @@ change_pin(sc_card_t *card, const char *opt_pin) pace_pin_cmd.pin2.data = (unsigned char *)new_pin; pace_pin_cmd.pin2.len = strlen(new_pin); - rv = card->ops->pin_cmd(card, &pace_pin_cmd, NULL); + rv = card->ops->pin_cmd(card, &pace_pin_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN for authentication change failed: %s\n", sc_strerror(rv)); @@ -304,7 +304,7 @@ change_pin(sc_card_t *card, const char *opt_pin) qes_pin_cmd.pin2.data = (unsigned char *)new_pin; qes_pin_cmd.pin2.len = strlen(new_pin); - rv = card->ops->pin_cmd(card, &qes_pin_cmd, NULL); + rv = card->ops->pin_cmd(card, &qes_pin_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN for signature change failed: %s\n", sc_strerror(rv)); @@ -366,7 +366,7 @@ resume(sc_pkcs15_card_t *p15card, const char *opt_can, const char *opt_pin) if (opt_can) can_verify_cmd.pin1.len = strlen(opt_can); - rv = card->ops->pin_cmd(card, &can_verify_cmd, NULL); + rv = card->ops->pin_cmd(card, &can_verify_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "CAN code verification failed: %s\n", sc_strerror(rv)); @@ -428,7 +428,7 @@ unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) puk_verify_cmd.pin1.data = (unsigned char *)puk; puk_verify_cmd.pin1.len = strlen(puk); - rv = card->ops->pin_cmd(card, &puk_verify_cmd, NULL); + rv = card->ops->pin_cmd(card, &puk_verify_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PUK code verification failed: %s\n", sc_strerror(rv)); @@ -441,7 +441,7 @@ unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) pace_pin_cmd.pin_type = SC_AC_CHV; pace_pin_cmd.pin_reference = PACE_PIN_ID_PIN; - rv = card->ops->pin_cmd(card, &pace_pin_cmd, NULL); + rv = card->ops->pin_cmd(card, &pace_pin_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN for authentication reset failed: %s\n", sc_strerror(rv)); @@ -462,7 +462,7 @@ unblock_using_puk(sc_pkcs15_card_t *p15card, const char *opt_puk) return rv; } - rv = card->ops->pin_cmd(card, &qes_pin_cmd, NULL); + rv = card->ops->pin_cmd(card, &qes_pin_cmd); if (rv != SC_SUCCESS) { fprintf(stderr, "PIN for signature reset failed: %s\n", sc_strerror(rv)); diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 946f9db501..3a694d69af 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -576,7 +576,6 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) int do_verify(sc_card_t *card, char *type, const char *in_pin) { struct sc_pin_cmd_data data; - int tries_left; int r; if (!type || !in_pin) return SC_ERROR_INVALID_ARGUMENTS; @@ -597,7 +596,7 @@ int do_verify(sc_card_t *card, char *type, const char *in_pin) data.pin_reference = type[3] - '0'; data.pin1.data = (unsigned char *) in_pin; data.pin1.len = (int)strlen(in_pin); - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); return r; } diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 236ade1b12..0341652020 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1175,7 +1175,7 @@ static int do_pininfo(int argc, char **argv) { SC_AC_PRO, "PRO" }, { SC_AC_NONE, NULL, } }; - int r, tries_left = -1; + int r; size_t i; struct sc_pin_cmd_data data; size_t prefix_len = 0; @@ -1205,7 +1205,7 @@ static int do_pininfo(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); sc_unlock(card); if (r) { @@ -1227,8 +1227,8 @@ static int do_pininfo(int argc, char **argv) } printf("\n"); } - if (tries_left >= 0) - printf("%d tries left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("%d tries left.\n", data.pin1.tries_left); return 0; } @@ -1241,7 +1241,7 @@ static int do_verify(int argc, char **argv) { SC_AC_PRO, "PRO" }, { SC_AC_NONE, NULL, } }; - int r, tries_left = -1; + int r; u8 buf[SC_MAX_PIN_SIZE]; size_t buflen = sizeof(buf), i; struct sc_pin_cmd_data data; @@ -1307,13 +1307,13 @@ static int do_verify(int argc, char **argv) } r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (tries_left >= 0) - printf("Incorrect code, %d tries left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("Incorrect code, %d tries left.\n", data.pin1.tries_left); else printf("Incorrect code.\n"); } else @@ -1326,7 +1326,7 @@ static int do_verify(int argc, char **argv) static int do_change(int argc, char **argv) { - int ref, r, tries_left = -1; + int ref, r; u8 oldpin[SC_MAX_PIN_SIZE]; u8 newpin[SC_MAX_PIN_SIZE]; size_t oldpinlen = 0; @@ -1372,12 +1372,12 @@ static int do_change(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (tries_left >= 0) - printf("Incorrect code, %d tries left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("Incorrect code, %d tries left.\n", data.pin1.tries_left); else printf("Incorrect code.\n"); } @@ -1437,7 +1437,7 @@ static int do_unblock(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); sc_unlock(card); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index accadf772c..73546fbf1b 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -480,7 +480,7 @@ static void print_dkek_info(sc_cardctl_sc_hsm_dkek_t *dkekinfo) static void print_info(sc_card_t *card, sc_file_t *file) { - int r, tries_left; + int r; struct sc_pin_cmd_data data; sc_cardctl_sc_hsm_dkek_t dkekinfo; @@ -508,14 +508,14 @@ static void print_info(sc_card_t *card, sc_file_t *file) data.pin_type = SC_AC_CHV; data.pin_reference = ID_SO_PIN; - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) { printf("SmartCard-HSM has never been initialized. Please use --initialize to set SO-PIN and user PIN.\n"); } else { - if (tries_left == 0) { + if (data.pin1.tries_left == 0) { printf("SO-PIN locked\n"); } else { - printf("SO-PIN tries left : %d\n", tries_left); + printf("SO-PIN tries left : %d\n", data.pin1.tries_left); } /* Try to update PIN info from card */ memset(&data, 0, sizeof(data)); @@ -523,16 +523,16 @@ static void print_info(sc_card_t *card, sc_file_t *file) data.pin_type = SC_AC_CHV; data.pin_reference = ID_USER_PIN; - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r == SC_ERROR_CARD_CMD_FAILED) { printf("Public key authentication active.\n"); } else if (r == SC_ERROR_REF_DATA_NOT_USABLE) { printf("Transport-PIN active. Please change to user selected PIN first.\n"); } else { - if (tries_left == 0) { + if (data.pin1.tries_left == 0) { printf("User PIN locked\n"); } else { - printf("User PIN tries left : %d\n", tries_left); + printf("User PIN tries left : %d\n", data.pin1.tries_left); } } } @@ -543,15 +543,15 @@ static void print_info(sc_card_t *card, sc_file_t *file) data.pin_type = SC_AC_CHV; data.pin_reference = ID_USER_PIN; - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r == SC_ERROR_REF_DATA_NOT_USABLE) { printf("SmartCard-HSM has never been initialized. Please use --initialize to set SO-PIN and user PIN.\n"); } else { - if (tries_left == 0) { + if (data.pin1.tries_left == 0) { printf("User PIN locked\n"); } else { - printf("User PIN tries left : %d\n", tries_left); + printf("User PIN tries left : %d\n", data.pin1.tries_left); } } } @@ -1364,7 +1364,7 @@ static int wrap_key(sc_context_t *ctx, sc_card_t *card, int keyid, const char *o data.pin1.data = (unsigned char *)lpin; data.pin1.len = strlen(lpin); - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r < 0) { fprintf(stderr, "PIN verification failed with %s\n", sc_strerror(r)); @@ -1653,7 +1653,7 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p data.pin1.data = (u8 *)lpin; data.pin1.len = strlen(lpin); - r = sc_pin_cmd(card, &data, NULL); + r = sc_pin_cmd(card, &data); if (r < 0) { fprintf(stderr, "PIN verification failed with %s\n", sc_strerror(r)); diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index b3ee3da42b..1b2ec41e61 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -121,7 +121,7 @@ static void print_openssl_error(void) static int verify_pin(sc_card_t *card, int pin_reference, const char *pin_value) { - int r, tries_left = -1; + int r; struct sc_pin_cmd_data data; memset(&data, 0, sizeof(data)); @@ -150,14 +150,14 @@ static int verify_pin(sc_card_t *card, int pin_reference, const char *pin_value) data.pin1.len = strlen(pin_value); } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (tries_left >= 0) - printf("Error %d attempts left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("Error %d attempts left.\n", data.pin1.tries_left); else printf("Wrong pin.\n"); } @@ -174,7 +174,7 @@ static int change_pin(sc_card_t *card, const char *pin_value1, const char *pin_value2) { - int r, tries_left = -1; + int r; struct sc_pin_cmd_data data; memset(&data, 0, sizeof(data)); @@ -207,14 +207,14 @@ static int change_pin(sc_card_t *card, } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (tries_left >= 0) - printf("Error %d attempts left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("Error %d attempts left.\n", data.pin1.tries_left); else printf("Wrong pin.\n"); } @@ -232,7 +232,7 @@ static int unlock_pin(sc_card_t *card, const char *puk_value, const char *pin_value) { - int r, tries_left = -1; + int r; struct sc_pin_cmd_data data; memset(&data, 0, sizeof(data)); @@ -265,14 +265,14 @@ static int unlock_pin(sc_card_t *card, } - r = sc_pin_cmd(card, &data, &tries_left); + r = sc_pin_cmd(card, &data); if (r) { if (r == SC_ERROR_PIN_CODE_INCORRECT) { - if (tries_left >= 0) - printf("Error %d attempts left.\n", tries_left); + if (data.pin1.tries_left >= 0) + printf("Error %d attempts left.\n", data.pin1.tries_left); else printf("Wrong pin.\n"); } From 4fa2c65b0950e72f687f23936e465850772791e8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 3 Jun 2026 10:24:37 +0200 Subject: [PATCH 4266/4321] ui: fixed detecting default language (#3561) * ui: fixed detecting default language fixes https://github.com/OpenSC/OpenSC/issues/2008 * fixed formatting --- src/ui/char_str_from_wchar.h | 2 ++ src/ui/strings.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ui/char_str_from_wchar.h b/src/ui/char_str_from_wchar.h index b0b584673d..1e0570daf6 100644 --- a/src/ui/char_str_from_wchar.h +++ b/src/ui/char_str_from_wchar.h @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef _WIN32 #include static char *char_str_from_wchar(const WCHAR *in) @@ -44,3 +45,4 @@ static char *char_str_from_wchar(const WCHAR *in) return out; } +#endif diff --git a/src/ui/strings.c b/src/ui/strings.c index 1eedb905c0..123806a7a4 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -18,9 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "ui/strings.h" #include "libopensc/internal.h" #include "libopensc/log.h" -#include "ui/strings.h" +#include "ui/char_str_from_wchar.h" #include #include #include @@ -161,11 +162,14 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr, if (!p15card || !p15card->tokeninfo || !find_lang_str(p15card->tokeninfo->preferred_language, &lang)) { #ifdef _WIN32 - LANGID langid = GetUserDefaultUILanguage(); - if ((langid & LANG_GERMAN) == LANG_GERMAN) { - lang = DE; - sc_log(ctx, "Using the system's language for user messages (German)."); - } + WCHAR language_wc[LOCALE_NAME_MAX_LENGTH]; + LCIDToLocaleName( + MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT), + language_wc, LOCALE_NAME_MAX_LENGTH, 0); + char *language = char_str_from_wchar(language_wc); + if (find_lang_str(language, &lang)) + sc_log(ctx, "Using the system's native environment locale for user messages (%s).", language); + LocalFree(language); #else const char *language = getenv("LANGUAGE"); /* LANGUAGE supersedes locale */ From 08b1c11099ff209a6e26fef46e01985c29024213 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jun 2026 14:34:42 +0200 Subject: [PATCH 4267/4321] Draft AGENTS.md --- AGENTS.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..05125187f7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,25 @@ +# AI Agent Instructions for OpenSC + +Welcome, autonomous agents. If you are analyzing the OpenSC repository, finding bugs, or preparing to submit +an issue or pull request, you MUST adhere strictly to the following rules: + +## 1. Issue Verification (Test Against `master`) +- **Rule:** Do NOT report bugs based solely on a release version. + OpenSC only supports the latest release and does not backport fixes. +- **Action:** Before preparing a report, you must pull the latest `master` branch, + build the project, and verify the bug is still present. + If the issue is already fixed in `master`, discard your report entirely. + +## 2. Security Vulnerabilities MUST Remain Private +- **Rule:** Do NOT submit public issues, public pull requests, or public comments regarding anything that + could be construed as a security vulnerability. + AI agents are strictly prohibited from publicly disclosing security reports. +- **Action:** If you suspect you have found a security vulnerability, **STOP**. + You must read `SECURITY.md` in the root of this repository and instruct your human operator to follow + the private disclosure steps outlined there. + +## 3. Proposing Solutions for Non-Security Bugs +- **Rule:** Do NOT submit "bug reports" without proposing a concrete fix. +- **Action:** If you find a verified, non-security bug on the `master` branch, analyze the root cause. + Your output must include a functional solution, ideally provided as a unified diff (patch) or submitted + directly as a Pull Request. From 4965113913d85333604644b07d292584c1f20a93 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jun 2026 15:27:56 +0200 Subject: [PATCH 4268/4321] AGENTS: Request specific references to code --- AGENTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 05125187f7..875a102bef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,8 @@ an issue or pull request, you MUST adhere strictly to the following rules: OpenSC only supports the latest release and does not backport fixes. - **Action:** Before preparing a report, you must pull the latest `master` branch, build the project, and verify the bug is still present. + In the report, include function names, source code files and line numbers (ideally with link to github) + where the issue is demonstrated. If the issue is already fixed in `master`, discard your report entirely. ## 2. Security Vulnerabilities MUST Remain Private From 7a7a73d2db8d4373d5c2cd6080d19fb391102643 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jun 2026 15:28:18 +0200 Subject: [PATCH 4269/4321] SECURITY: Require one advisory per issue --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index c73efb1834..cede552696 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -24,6 +24,11 @@ jakuje(at)gmail.com . You can expect update on the issue no later than in two weeks. +If you use GitHub's private vulnerability reporting, make sure to submit +ONE advisory per issue. The CVE assignment requires that the issue is +self-contained. Assigning a CVE number for multiple issues (even if from +similar class of weaknesses) is complicated. + ## What Qualifies as a Security Issue Please use the private vulnerability reporting process only for issues that have **security impact**. This includes, but is not limited to: From 758c0bfae1cca6a5a4d96896746ae50c70db9b9d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 19 May 2026 21:30:51 +0200 Subject: [PATCH 4270/4321] CI: Artifacts contain release (candidate) tags or short hash otherwise fixes problem with artifact upload when ref_name contains invalid characters such as "/" --- .github/build.sh | 29 ++++++++--------------------- .github/workflows/windows.yml | 23 ++++++----------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index 4b4434967f..314267dd5b 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -8,27 +8,14 @@ if [ -x "/bin/sudo" ]; then SUDO="sudo" fi -if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then - PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$GITHUB_BASE_REF" == "master" ]; then - SUFFIX="-pr$PR_NUMBER" - else - SUFFIX="$GITHUB_BASE_REF-pr$PR_NUMBER" - fi -else - TAG_OR_BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$GITHUB_REF_TYPE" == "tag" ]; then - if [[ "$TAG_OR_BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - # Tag matches the version scheme without suffix -- no suffix needed - SUFFIX="" - elif [[ "$TAG_OR_BRANCH" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then - # rc suffix after version. Use the suffix part only - SUFFIX="${BASH_REMATCH[1]}" - else - SUFFIX="-$TAG_OR_BRANCH" - fi - elif [ "$TAG_OR_BRANCH" != "master" ]; then - SUFFIX="-$TAG_OR_BRANCH" +SUFFIX="-${GITHUB_SHA:0:7}" +if [ "$GITHUB_REF_TYPE" == "tag" ]; then + if [[ "$GITHUB_REF_NAME" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # Tag matches the version scheme without suffix -- no suffix needed + SUFFIX="" + elif [[ "$GITHUB_REF_NAME" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + # rc suffix after version. Use the suffix part only + SUFFIX="${BASH_REMATCH[1]}" fi fi if [ -n "$SUFFIX" ]; then diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c2f98845af..39b0716d1a 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -41,23 +41,12 @@ jobs: - name: Package suffix shell: bash run: | - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - if [[ "${{ github.base_ref }}" == "master" ]]; then - SUFFIX="-pr${{ github.event.number }}" - else - SUFFIX="-${{ github.base_ref }}-pr${{ github.event.number }}" - fi - elif [[ "${{ github.event_name }}" == "push" ]]; then - if [[ "${{ github.ref_type }}" == "tag" ]]; then - if [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - SUFFIX="" # regular release tag - elif [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then - SUFFIX="${BASH_REMATCH[1]}" # rc release tag - else - SUFFIX="-${{ github.ref_name }}" - fi - elif [[ "${{ github.ref_name }}" != "master" ]]; then - SUFFIX="-${{ github.ref_name }}" + SUFFIX="-${GITHUB_SHA:0:7}" + if [[ "${{ github.ref_type }}" == "tag" ]]; then + if [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + SUFFIX="" # regular release tag + elif [[ "${{ github.ref_name }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(.+)$ ]]; then + SUFFIX="${BASH_REMATCH[1]}" # rc release tag fi fi PACKAGE_SUFFIX="${SUFFIX}${{ matrix.configuration == 'Light' && '-Light' || '' }}" From e78ad8633e6c73a8ffdbd07447feb71c246b7a6d Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Sun, 14 Jun 2026 22:23:35 +0300 Subject: [PATCH 4271/4321] Update windows build * Cleanup Github Actions build * WIX 7.0 * Build libeac with vcpkg * Disable asserts all release builds * Zlib renamed dll zlib to z in 1.3.2 windows build Signed-off-by: Raul Metsma --- .github/ports/openpace/CMakeLists.txt | 60 +++++++++++++++++++++++++++ .github/ports/openpace/portfile.cmake | 17 ++++++++ .github/ports/openpace/vcpkg.json | 18 ++++++++ .github/setup-wix.ps1 | 25 +++++++---- .github/vcpkg.json | 15 +++++-- .github/workflows/windows.yml | 58 +++++--------------------- win32/Make.rules.mak | 43 +++++++++++++------ 7 files changed, 165 insertions(+), 71 deletions(-) create mode 100644 .github/ports/openpace/CMakeLists.txt create mode 100644 .github/ports/openpace/portfile.cmake create mode 100644 .github/ports/openpace/vcpkg.json diff --git a/.github/ports/openpace/CMakeLists.txt b/.github/ports/openpace/CMakeLists.txt new file mode 100644 index 0000000000..253e91c10d --- /dev/null +++ b/.github/ports/openpace/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.15) +project(openpace C) + +find_package(OpenSSL REQUIRED) + +add_library(eac STATIC + ca_lib.c + cv_cert.c + cvc_lookup.c + x509_lookup.c + eac_asn1.c + eac.c + eac_ca.c + eac_dh.c + eac_ecdh.c + eac_kdf.c + eac_lib.c + eac_print.c + eac_util.c + misc.c + objects.c + pace.c + pace_lib.c + pace_mappings.c + ri.c + ri_lib.c + ssl_compat.c + ta.c + ta_lib.c +) + +target_include_directories(eac + PUBLIC + $ + $ +) + +target_link_libraries(eac PUBLIC OpenSSL::Crypto) + +target_compile_definitions(eac PRIVATE + HAVE_ASN1_STRING_GET0_DATA + HAVE_DECL_OPENSSL_ZALLOC + HAVE_DH_GET0_KEY + HAVE_DH_GET0_PQG + HAVE_DH_SET0_KEY + HAVE_DH_SET0_PQG + HAVE_ECDSA_SIG_GET0 + HAVE_ECDSA_SIG_SET0 + HAVE_EC_KEY_METHOD + HAVE_RSA_GET0_KEY + HAVE_RSA_SET0_KEY + HAVE_EC_POINT_GET_AFFINE_COORDINATES + HAVE_EC_POINT_SET_AFFINE_COORDINATES + HAVE_EVP_PKEY_DUP + "X509DIR=\"/\"" + "CVCDIR=\"/\"" +) + +install(TARGETS eac ARCHIVE DESTINATION lib) +install(DIRECTORY eac DESTINATION include) diff --git a/.github/ports/openpace/portfile.cmake b/.github/ports/openpace/portfile.cmake new file mode 100644 index 0000000000..5333965238 --- /dev/null +++ b/.github/ports/openpace/portfile.cmake @@ -0,0 +1,17 @@ +vcpkg_check_linkage(ONLY_STATIC_LIBRARY) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO frankmorgner/openpace + REF ${VERSION} + SHA512 9236de244e4c306223c7051f3c2cd0df155ca473d69d55b22f97e4050ed9c30a037511851e3afcb75745f3e95c5b79d2d96e3e2f8e23e692a07f3e0530cf5b40 + HEAD_REF master +) + +file(COPY "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" DESTINATION "${SOURCE_PATH}/src") + +vcpkg_cmake_configure(SOURCE_PATH "${SOURCE_PATH}/src") +vcpkg_cmake_install() + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/COPYING") diff --git a/.github/ports/openpace/vcpkg.json b/.github/ports/openpace/vcpkg.json new file mode 100644 index 0000000000..29290da4ef --- /dev/null +++ b/.github/ports/openpace/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "openpace", + "version": "1.1.4", + "description": "C implementation of the PACE protocol as defined in BSI TR-03110", + "homepage": "https://github.com/frankmorgner/openpace", + "license": "GPL-3.0-or-later", + "dependencies": [ + "openssl", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/.github/setup-wix.ps1 b/.github/setup-wix.ps1 index ce05d70d9e..7123e03d48 100644 --- a/.github/setup-wix.ps1 +++ b/.github/setup-wix.ps1 @@ -1,10 +1,19 @@ param( - [string]$version = '6.0.2' + [string]$version = '7.0.0' ) -& dotnet tool install -g --version $version wix -& wix extension add -g WixToolset.UI.wixext/$version -& wix extension add -g WixToolset.Util.wixext/$version -& cd win32 -& dotnet new console --force --name CustomAction -& dotnet add CustomAction package WixToolset.WcaUtil --version $version --package-directory packages -& cd .. \ No newline at end of file + +$ErrorActionPreference = 'Stop' + +function Exec([scriptblock]$cmd) { + & $cmd + if ($LASTEXITCODE -ne 0) { throw "Command failed (exit $LASTEXITCODE)" } +} + +Exec { dotnet tool install -g --version $version wix } +Exec { wix eula accept wix7 } +Exec { wix extension add -g WixToolset.UI.wixext/$version } +Exec { wix extension add -g WixToolset.Util.wixext/$version } +Set-Location win32 +Exec { dotnet new console --force --name CustomAction } +Exec { dotnet add CustomAction package WixToolset.WcaUtil --version $version --package-directory packages } +Set-Location .. diff --git a/.github/vcpkg.json b/.github/vcpkg.json index b3622f24e2..b756fd0377 100644 --- a/.github/vcpkg.json +++ b/.github/vcpkg.json @@ -1,8 +1,17 @@ { "name": "opensc", "dependencies": [ - "openssl", - "zlib" + "openssl" ], + "features": { + "zlib": { + "description": "Compressed data support (PIV, actalis)", + "dependencies": ["zlib"] + }, + "openpace": { + "description": "EAC/PACE support via OpenPACE", + "dependencies": ["openpace"] + } + }, "builtin-baseline": "56bb2411609227288b70117ead2c47585ba07713" -} \ No newline at end of file +} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 39b0716d1a..1c218cb5b8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -31,8 +31,6 @@ jobs: - platform: arm64 setenv: amd64_arm64 env: - OPENPACE_VER: 1.1.4 - VCPKG_INSTALLED: ${{ github.workspace }}\vcpkg_installed VCPKG_DEFAULT_TRIPLET: ${{ matrix.platform }}-windows-static BUILD_NUMBER: ${{ github.run_number }} steps: @@ -60,67 +58,31 @@ jobs: echo "ARTIFACT_NAME=${PRODUCT_NAME}-${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_FIX}${PACKAGE_SUFFIX}_${{ matrix.platform }}" >> $GITHUB_ENV - name: Install CPDK run: choco install windows-cryptographic-provider-development-kit -y > $null - - name: Setup dev env - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.setenv }} - name: Cache vcpkg if: matrix.configuration == 'Release' uses: actions/cache@v5 with: path: ${{ github.workspace }}/vcpkg_cache - key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json') }} + key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json', '.github/ports/**') }} - name: Prepare vcpkg if: matrix.configuration == 'Release' env: VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite run: | + $installed = "${{ github.workspace }}\vcpkg_installed" + echo "VCPKG_INSTALLED=$installed" >> $env:GITHUB_ENV C:\vcpkg\vcpkg install ` + --overlay-ports=${{ github.workspace }}/.github/ports ` + --x-feature=zlib ` + --x-feature=openpace ` --x-manifest-root ${{ github.workspace }}/.github ` - --x-install-root ${env:VCPKG_INSTALLED} + --x-install-root $installed - name: Install WIX run: powershell -ExecutionPolicy Bypass -File .github/setup-wix.ps1 - - name: Restore Cache - if: matrix.configuration == 'Release' - uses: actions/cache@v5 - id: cache - with: - path: openpace-${{ env.OPENPACE_VER }} - key: OpenPACE-${{ env.OPENPACE_VER }}-${{ matrix.image }}-${{ matrix.platform }} - - name: Build OpenPACE - if: matrix.configuration == 'Release' && steps.cache.outputs.cache-hit != 'true' - run: | - Invoke-WebRequest "https://github.com/frankmorgner/openpace/archive/${env:OPENPACE_VER}.zip" -OutFile openpace.zip - tar xf openpace.zip - cd openpace-${env:OPENPACE_VER}\src - cl /nologo /O1 /Zi /W3 /GS /MT /I${env:VCPKG_INSTALLED}\${env:VCPKG_DEFAULT_TRIPLET}\include /I. ` - /DX509DIR=`"/`" /DCVCDIR=`"/`" /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN ` - /DHAVE_ASN1_STRING_GET0_DATA /DHAVE_DECL_OPENSSL_ZALLOC /DHAVE_DH_GET0_KEY /DHAVE_DH_GET0_PQG ` - /DHAVE_DH_SET0_KEY /DHAVE_DH_SET0_PQG /DHAVE_ECDSA_SIG_GET0 /DHAVE_ECDSA_SIG_SET0 ` - /DHAVE_EC_KEY_METHOD /DHAVE_RSA_GET0_KEY /DHAVE_RSA_SET0_KEY /DHAVE_EC_POINT_GET_AFFINE_COORDINATES ` - /DHAVE_EC_POINT_SET_AFFINE_COORDINATES /DHAVE_EVP_PKEY_DUP /c ` - ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c ` - eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c ` - pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c - lib /nologo /out:libeac.lib ` - ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj ` - eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj ` - pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj - - name: Set NMake Variables - if: matrix.configuration == 'Release' - run: | - $VCPKG_DIR="${env:VCPKG_INSTALLED}\${env:VCPKG_DEFAULT_TRIPLET}" - echo "ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC" >> $env:GITHUB_ENV - echo "ZLIB_INCL_DIR=/I${VCPKG_DIR}\include" >> $env:GITHUB_ENV - echo "ZLIB_LIB=${VCPKG_DIR}\lib\zlib.lib" >> $env:GITHUB_ENV - echo "OPENSSL_DEF=/DENABLE_OPENSSL" >> $env:GITHUB_ENV - echo "OPENSSL_DIR=${VCPKG_DIR}" >> $env:GITHUB_ENV - echo "OPENSSL_LIB=${VCPKG_DIR}\lib\libcrypto.lib" >> $env:GITHUB_ENV - echo "OPENSSL_EXTRA_CFLAGS=/DOPENSSL_SECURE_MALLOC_SIZE=65536" >> $env:GITHUB_ENV - echo "OPENPACE_DEF=/DENABLE_OPENPACE" >> $env:GITHUB_ENV - echo "OPENPACE_DIR=${env:GITHUB_WORKSPACE}\openpace-${env:OPENPACE_VER}" >> $env:GITHUB_ENV - name: Build OpenSC - run: nmake /nologo /f Makefile.mak opensc.msi + run: | + $vsPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath + & "$vsPath\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.setenv }} "&&" nmake /nologo /f Makefile.mak opensc.msi - name: Archive artifacts id: upload-unsigned-artifact uses: actions/upload-artifact@v7 diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index a61568753c..376383f96d 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -21,7 +21,7 @@ WIXFLAGS = -d ENABLE_MINIDRIVER $(WIXFLAGS) MSI_NAME = $(PRODUCT_NAME)-$(PACKAGE_VERSION_MAJOR).$(PACKAGE_VERSION_MINOR).$(PACKAGE_VERSION_FIX)$(PACKAGE_SUFFIX)_$(PLATFORM).msi !IF "$(WIX_PACKAGES)" == "" WIX_PACKAGES = $(TOPDIR)\win32\packages -WIX_VERSION = 6.0.2 +WIX_VERSION = 7.0.0 !ENDIF WIX_INCL_DIR = "/I$(WIX_PACKAGES)/wixtoolset.dutil/$(WIX_VERSION)/build/native/include" \ "/I$(WIX_PACKAGES)/wixtoolset.wcautil/$(WIX_VERSION)/build/native/include" @@ -36,8 +36,6 @@ SM_DEF = /DENABLE_SM #Build with debugging support #DEBUG_DEF = /DDEBUG -#Release build, disable asserts -#DEBUG_DEF = /DNDEBUG !IF "$(BUILD_TYPE)" == "" !IF "$(DEBUG_DEF)" == "/DDEBUG" @@ -47,6 +45,30 @@ BUILD_TYPE = MT !ENDIF !ENDIF +# If vcpkg is configured, automatically detect and enable installed dependencies +!IF "$(VCPKG_INSTALLED)" != "" +!IF "$(VCPKG_DEFAULT_TRIPLET)" == "" +VCPKG_DEFAULT_TRIPLET = x64-windows-static +!ENDIF +VCPKG_DIR = $(VCPKG_INSTALLED)\$(VCPKG_DEFAULT_TRIPLET) +!IF EXIST("$(VCPKG_DIR)\lib\libcrypto.lib") +OPENSSL_DEF = /DENABLE_OPENSSL +OPENSSL_DIR = $(VCPKG_DIR) +OPENSSL_LIB = $(VCPKG_DIR)\lib\libcrypto.lib +OPENSSL_EXTRA_CFLAGS = /DOPENSSL_SECURE_MALLOC_SIZE=65536 +!ENDIF +!IF EXIST("$(VCPKG_DIR)\lib\zs.lib") +ZLIBSTATIC_DEF = /DENABLE_ZLIB_STATIC +ZLIB_INCL_DIR = /I$(VCPKG_DIR)\include +ZLIB_LIB = $(VCPKG_DIR)\lib\zs.lib +!ENDIF +!IF EXIST("$(VCPKG_DIR)\lib\eac.lib") +OPENPACE_DEF = /DENABLE_OPENPACE +OPENPACE_INCL_DIR = /I$(VCPKG_DIR)\include +OPENPACE_LIB = $(VCPKG_DIR)\lib\eac.lib +!ENDIF +!ENDIF + # If you want support for OpenSSL (needed for pkcs15-init tool, software hashing in PKCS#11 library and verification): # - download and build OpenSSL # - uncomment the line starting with OPENSSL_DEF @@ -64,16 +86,8 @@ OPENSSL_DIR = C:\OpenSSL-Win64 OPENSSL_INCL_DIR = /I$(OPENSSL_DIR)\include !IF "$(OPENSSL_LIB)" == "" -!IF "$(OPENSSL_VER)" == "1.1.1" -!IF "$(PLATFORM)" == "x86" -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\static\libcrypto32$(BUILD_TYPE).lib -!ELSE -OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\static\libcrypto64$(BUILD_TYPE).lib -!ENDIF -!ELSE OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(PLATFORM)\$(BUILD_TYPE)\libcrypto_static.lib !ENDIF -!ENDIF OPENSSL_LIB = $(OPENSSL_LIB) user32.lib advapi32.lib crypt32.lib ws2_32.lib PROGRAMS_OPENSSL = cryptoflex-tool.exe pkcs15-init.exe netkey-tool.exe piv-tool.exe \ @@ -120,8 +134,12 @@ WIXFLAGS = -d zlib="C:\zlib-dll" $(WIXFLAGS) !IF "$(OPENPACE_DIR)" == "" OPENPACE_DIR = C:\openpace !ENDIF +!IF "$(OPENPACE_INCL_DIR)" == "" OPENPACE_INCL_DIR = /I$(OPENPACE_DIR)\src +!ENDIF +!IF "$(OPENPACE_LIB)" == "" OPENPACE_LIB = $(OPENPACE_DIR)\src\libeac.lib +!ENDIF !IF "$(OPENSSL_DEF)" == "/DENABLE_OPENSSL" # Build only when OpenPACE and OpenSSL are available PROGRAMS_OPENPACE = npa-tool.exe @@ -152,7 +170,8 @@ LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMT COPTS = /Od /$(BUILD_TYPE) $(COPTS) !ELSE LINKFLAGS = $(LINKFLAGS) /NODEFAULTLIB:LIBCMTD /OPT:REF /OPT:ICF -COPTS = /O1 /$(BUILD_TYPE) $(COPTS) +# Release build: optimize and disable asserts +COPTS = /O1 /$(BUILD_TYPE) /DNDEBUG $(COPTS) !ENDIF .SUFFIXES: .exports .def From 5517bba189f3760cbeedf2b2fa9177442c744c6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 08:21:17 +0000 Subject: [PATCH 4272/4321] build(deps): bump awalsh128/cache-apt-pkgs-action from 1.6.0 to 1.6.1 Bumps [awalsh128/cache-apt-pkgs-action](https://github.com/awalsh128/cache-apt-pkgs-action) from 1.6.0 to 1.6.1. - [Release notes](https://github.com/awalsh128/cache-apt-pkgs-action/releases) - [Commits](https://github.com/awalsh128/cache-apt-pkgs-action/compare/v1.6.0...v1.6.1) --- updated-dependencies: - dependency-name: awalsh128/cache-apt-pkgs-action dependency-version: 1.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/external-pkcs11.yaml | 4 ++-- .github/workflows/linux.yml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 1d31a174d0..b6328a090f 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -53,7 +53,7 @@ jobs: BUILD_PATH: ./ steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-20-base @@ -74,7 +74,7 @@ jobs: BUILD_PATH: ./ steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-20-base diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index d645549eb9..43b03da993 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -72,7 +72,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -84,7 +84,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -96,7 +96,7 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base @@ -134,7 +134,7 @@ jobs: runs-on: ubuntu-24.04 needs: [build] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base @@ -203,7 +203,7 @@ jobs: LIBRESSL_VERSION: 4.2.1 steps: - uses: actions/checkout@v6 - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base @@ -248,7 +248,7 @@ jobs: target: [cac, oseid] needs: [build-libressl] steps: - - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} version: apt-latest-base From f587e307c0c026231f38600f23a95708bf1d0145 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 10 Jun 2026 11:01:09 -0500 Subject: [PATCH 4273/4321] card-piv.c - circumvent problem with G&D card response to select aid As documented in #3072, The G&D card response to SELECT AID was: 61 0F 4F 06 00 10 00 01 00 00 79 05 A0 00 00 03 08 The 00 10 00 01 00 00 should have been 01 00 10 00 01 00 The code will accept either 01 00 10 00 or 00 10 00 01 The last two bytes are a version number that is not tested. this is a replacement PR. On branch GD-pix Changes to be committed: modified: src/libopensc/card-piv.c --- src/libopensc/card-piv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 3d9a829727..a65e0a406e 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -484,8 +484,10 @@ static const struct sc_atr_table piv_atrs[] = { { "3B:7A:18:00:00:73:66:74:65:20:63:64:31:34:34", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL }, /* Giesecke & Devrient (CAC PIV Endpoint) 2019 */ { "3B:F9:18:00:00:00:53:43:45:37:20:03:00:20:46", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL }, + /* Giesecke & Devrient SCE7 (PIV-only) (DoD Alternate Token G+D Sm@rtCafe Expert v7.0 144K DI 2025) */ + { "3B:F9:96:00:00:80:31:FE:45:53:43:45:37:20:0F:00:20:46:4E", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE, 0, NULL }, - /* IDEMIA (new name for Oberthur) (DoD Alternate Token IDEMIA Cosmo V8.0 2019*/ + /* IDEMIA (new name for Oberthur) (DoD Alternate Token IDEMIA Cosmo V8.0 2025 */ { "3B:D8:18:00:80:B1:FE:45:1F:07:80:31:C1:64:08:06:92:0F:D5", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, { "3b:86:80:01:80:31:c1:52:41:1a:7e", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */ @@ -561,10 +563,12 @@ static struct piv_supported_ec_curves { {{{-1}}, 0, 0 } /* This entry must not be touched. */ }; -/* all have same AID */ +/* all cards must respond to entry 0, some may return different PIX which will accept */ static struct piv_aid piv_aids[] = { {SC_CARD_TYPE_PIV_II_GENERIC, /* Not really card type but what PIV AID is supported */ 9, 9, (u8 *) "\xA0\x00\x00\x03\x08\x00\x00\x10\x00" }, + {SC_CARD_TYPE_PIV_II_GI_DE, /* bug in some G&D cards in response to select aid */ + 9, 9, (u8 *) "\xA0\x00\x00\x03\x08\x00\x10\x00\x01" }, {0, 9, 0, NULL } }; @@ -2982,7 +2986,8 @@ piv_find_aid(sc_card_t *card) /* early cards returned full AID, rather then just the pix */ for (i = 0; piv_aids[i].len_long != 0; i++) { - if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5) == 0) || + if ((pixlen >= piv_aids[i].len_long - 5 && + memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5) == 0) || ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, piv_aids[i].len_short) == 0))) { free(priv->aid_der.value); /* free previous value if any */ From 08b3debefed5c2d904dc45fe43a2cff4a9e6c3ba Mon Sep 17 00:00:00 2001 From: hirashix0 Date: Wed, 10 Jun 2026 14:25:48 +0200 Subject: [PATCH 4274/4321] srbeid: support RSA-2048 raw signing and decryption This adds raw RSA alongside the card's existing (unchanged) PKCS#1 signing. The 256-byte block is sent with its first byte in P2, and decryption uses the card's PSO DECIPHER. Tested on a Serbian eID: card-side, SHA-256 and raw signing, plus decryption. --- src/libopensc/card-srbeid.c | 96 +++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/src/libopensc/card-srbeid.c b/src/libopensc/card-srbeid.c index 716a310ea9..22406a21ae 100644 --- a/src/libopensc/card-srbeid.c +++ b/src/libopensc/card-srbeid.c @@ -32,8 +32,9 @@ #include "internal.h" #include "log.h" -/* MSE algorithm byte for RSA-2048 PKCS#1 v1.5 */ -#define CE_MSE_ALG_RSA2048 0x02u +/* MSE SET algorithm byte (tag 0x80). */ +#define CE_MSE_ALG_RSA_PKCS1 0x02u /* card adds PKCS#1 padding */ +#define CE_MSE_ALG_RSA_RAW 0x00u /* raw RSA; OpenSC pads */ static struct sc_card_operations srbeid_ops; static const struct sc_card_operations *iso_ops; @@ -84,8 +85,12 @@ srbeid_init(sc_card_t *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; + /* Keep the card's own PKCS#1 signing, and add raw RSA on top: that gives + * CKM_RSA_X_509 and makes 2048-bit decrypt work (OpenSC does the padding). */ _sc_card_add_rsa_alg(card, 2048, - SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); + SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01 | SC_ALGORITHM_RSA_RAW | + SC_ALGORITHM_RSA_HASH_NONE, + 0); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -201,10 +206,13 @@ srbeid_set_security_env(sc_card_t *card, return SC_ERROR_NOT_SUPPORTED; } - /* MSE SET: tag 0x80 = algorithm (RSA2048), tag 0x84 = key ref (2 bytes BE) */ + /* MSE SET: tag 0x80 = algorithm, tag 0x84 = key ref (2 bytes BE). + * The algorithm byte tells the card to pad (PKCS#1) or not (raw RSA). */ mse_data[0] = 0x80; mse_data[1] = 0x01; - mse_data[2] = CE_MSE_ALG_RSA2048; + mse_data[2] = (env->algorithm_flags & SC_ALGORITHM_RSA_RAW) + ? CE_MSE_ALG_RSA_RAW + : CE_MSE_ALG_RSA_PKCS1; mse_data[3] = 0x84; mse_data[4] = 0x02; mse_data[5] = (u8)((key_ref >> 8) & 0xFF); @@ -220,31 +228,38 @@ srbeid_set_security_env(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "MSE SET failed"); - sc_log(card->ctx, "srbeid: set_security_env: key_ref=0x%04x p2=0x%02x", key_ref, p2); + sc_log(card->ctx, "srbeid: set_security_env: key_ref=0x%04x p2=0x%02x algo=0x%02x", + key_ref, p2, mse_data[2]); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } /* - * compute_signature — PSO COMPUTE DIGITAL SIGNATURE (00 2A 9E 00). - * - * MSE SET has already been sent by set_security_env(). - * CardEdge uses P2=0x00 (not 0x9A as in ISO 7816-8), so we cannot - * delegate to iso7816_compute_signature(). + * One PSO (INS=0x2A, given P1). A 256-byte block exceeds the short-APDU Lc, so + * its first byte is carried in P2; a smaller DigestInfo is sent as-is. */ static int -srbeid_compute_signature(sc_card_t *card, - const u8 *data, size_t datalen, u8 *out, size_t outlen) +srbeid_pso(sc_card_t *card, u8 p1, const u8 *data, size_t datalen, u8 *out, + size_t outlen) { sc_apdu_t apdu; u8 resp[256]; + u8 p2 = 0x00; int r; LOG_FUNC_CALLED(card->ctx); - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x00); + if (datalen == 0 || datalen > sizeof(resp)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + if (datalen > SC_MAX_APDU_DATA_SIZE) { + p2 = data[0]; + ++data; + --datalen; + } + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, p1, p2); apdu.data = data; - apdu.datalen = datalen; - apdu.lc = datalen; + apdu.datalen = apdu.lc = datalen; apdu.resp = resp; apdu.resplen = sizeof(resp); apdu.le = sizeof(resp); @@ -252,7 +267,7 @@ srbeid_compute_signature(sc_card_t *card, r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, "PSO COMPUTE DIGITAL SIGNATURE failed"); + LOG_TEST_RET(card->ctx, r, "PSO failed"); if (apdu.resplen > outlen) LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); @@ -260,40 +275,29 @@ srbeid_compute_signature(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); } +/* Signing: PSO COMPUTE SIGNATURE (00 2A 9E). */ +static int +srbeid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + u8 *out, size_t outlen) +{ + return srbeid_pso(card, 0x9E, data, datalen, out, outlen); +} + /* - * decipher — PSO DECIPHER (00 2A 80 86). - * - * MSE SET has already been sent by set_security_env(). - * CardEdge does not use a padding indicator byte, so we cannot - * delegate to iso7816_decipher(). + * Decryption: PSO DECIPHER (00 2A 80) so the card is told the operation. The + * applet reads P2 as an ISO template and rejects a cryptogram starting with + * 0x86, so fall back to COMPUTE SIGNATURE (00 2A 9E), which is the same RSA + * operation on this card. */ static int -srbeid_decipher(sc_card_t *card, - const u8 *crgram, size_t crgram_len, u8 *out, size_t outlen) +srbeid_decipher(sc_card_t *card, const u8 *crgram, size_t crgram_len, u8 *out, + size_t outlen) { - sc_apdu_t apdu; - u8 resp[256]; - int r; + int r = srbeid_pso(card, 0x80, crgram, crgram_len, out, outlen); - LOG_FUNC_CALLED(card->ctx); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); - apdu.data = crgram; - apdu.datalen = crgram_len; - apdu.lc = crgram_len; - apdu.resp = resp; - apdu.resplen = sizeof(resp); - apdu.le = sizeof(resp); - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, "PSO DECIPHER failed"); - - if (apdu.resplen > outlen) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL); - memcpy(out, resp, apdu.resplen); - LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); + if (r == SC_ERROR_INCORRECT_PARAMETERS) + r = srbeid_pso(card, 0x9E, crgram, crgram_len, out, outlen); + return r; } struct sc_card_driver * From 39e8771238adf2e3ea0c3b23285b6825a8feaceb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 5 Jun 2026 11:00:33 +0200 Subject: [PATCH 4275/4321] oberthur: Validate we parsed non-empty modulus and exponent Thanks oss-fuzz. This is a fixup of the previous incomplete fix that landed few months back in 123f11eb34cf90d027d97228b8c57bee84b7e85d. https://issues.oss-fuzz.com/issues/519999729 --- src/libopensc/card-oberthur.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 3e0e181960..c3b6f0b60e 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2042,6 +2042,15 @@ write_publickey (struct sc_card *card, unsigned int offset, rsa_der_len = 0; memset(rsa_der, 0, sizeof(rsa_der)); LOG_TEST_RET(card->ctx, rv, "cannot decode public key"); + if (key.modulus.len == 0 || key.exponent.len == 0) { + if (key.modulus.len > 0) { + free(key.modulus.data); + } + if (key.exponent.len > 0) { + free(key.exponent.data); + } + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key decoded from DER"); + } memset(&args, 0, sizeof(args)); args.type = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; From 2edec19f7407ebc42615c660a537c14b0d2653b5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 5 Jun 2026 11:46:36 +0200 Subject: [PATCH 4276/4321] cwa: Refactor to use ASN1 decoding functions Originally reported by Mitchell Benjamin from Revamp Studio --- src/libopensc/cwa14890.c | 74 ++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index a5ff0061f8..0c1c491170 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -33,6 +33,7 @@ #include #include +#include "asn1.h" #include "opensc.h" #include "cardctl.h" #include "internal.h" @@ -235,8 +236,8 @@ static int cwa_parse_tlv(sc_card_t * card, cwa_tlv_t tlv_array[] ) { - size_t n = 0; - size_t next = 0; + const u8 *p = buffer; + size_t left = datalen; sc_context_t *ctx = NULL; /* preliminary checks */ @@ -249,10 +250,24 @@ static int cwa_parse_tlv(sc_card_t * card, if (!tlv_array) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - for (n = 0; n < datalen; n += next) { - cwa_tlv_t *tlv = NULL; /* pointer to TLV structure to store info */ - size_t j = 2; /* TLV has at least two bytes */ - switch (*(buffer + n)) { + while (left > 0) { + unsigned int cla = 0, tag_val = 0; + size_t tag_len = 0, header_len; + const u8 *tlv_start = p; + cwa_tlv_t *tlv = NULL; + u8 raw_tag; + + int r = sc_asn1_read_tag(&p, left, &cla, &tag_val, &tag_len); + if (r != SC_SUCCESS) { + sc_log(ctx, "Failed to parse ASN.1 tag"); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + } + + header_len = (p - tlv_start); + left -= header_len; + + raw_tag = (cla | tag_val); + switch (raw_tag) { case CWA_SM_PLAIN_TAG: tlv = &tlv_array[0]; break; /* 0x81 Plain */ @@ -266,50 +281,19 @@ static int cwa_parse_tlv(sc_card_t * card, tlv = &tlv_array[3]; break; /* 0x99 Status */ default: /* CWA_SM_LE_TAG (0x97) is not valid here */ - sc_log(ctx, "Invalid TLV Tag type: '0x%02X'", - *(buffer + n)); + sc_log(ctx, "Invalid TLV Tag type: '0x%02X'", raw_tag); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); } - tlv->buf = buffer + n; - tlv->tag = 0xff & *(buffer + n); - tlv->len = 0; /* temporary */ - /* evaluate len and start of data */ - switch (0xff & *(buffer + n + 1)) { - case 0x84: - tlv->len = (0xff & *(buffer + n + j++)); - /* fall through */ - case 0x83: - tlv->len = - (tlv->len << 8) + (0xff & *(buffer + n + j++)); - /* fall through */ - case 0x82: - tlv->len = - (tlv->len << 8) + (0xff & *(buffer + n + j++)); - /* fall through */ - case 0x81: - tlv->len = - (tlv->len << 8) + (0xff & *(buffer + n + j++)); - break; - /* case 0x80 is not standard, but official code uses it */ - case 0x80: - tlv->len = - (tlv->len << 8) + (0xff & *(buffer + n + j++)); - break; - default: - if ((*(buffer + n + 1) & 0xff) < 0x80) { - tlv->len = 0xff & *(buffer + n + 1); - } else { - sc_log(ctx, "Invalid tag length indicator: %d", - *(buffer + n + 1)); - LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH); - } - } - tlv->data = buffer + n + j; - tlv->buflen = j + tlv->len; + tlv->buf = (u8 *)tlv_start; + tlv->tag = raw_tag; + tlv->len = tag_len; + tlv->data = (u8 *)p; + tlv->buflen = header_len + tag_len; sc_log(ctx, "Found Tag: '0x%02X': Length: '%"SC_FORMAT_LEN_SIZE_T"u' Value:\n%s", tlv->tag, tlv->len, sc_dump_hex(tlv->data, tlv->len)); /* set index to next Tag to jump to */ - next = tlv->buflen; + p += tag_len; + left -= tag_len; } LOG_FUNC_RETURN(ctx, SC_SUCCESS); /* mark no error */ } From ec07582d7887fcfffc060d7948721e6dcf00e8c0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 5 Jun 2026 12:00:24 +0200 Subject: [PATCH 4277/4321] eoi: Avoid writing behind the buffer bounds if mapping was already initialized Originally reported by Mitchell Benjamin from Revamp Studio --- src/libopensc/pkcs15-eoi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-eoi.c b/src/libopensc/pkcs15-eoi.c index 2691e4fd61..8430ef5987 100644 --- a/src/libopensc/pkcs15-eoi.c +++ b/src/libopensc/pkcs15-eoi.c @@ -49,7 +49,7 @@ int sc_pkcs15emu_eoi_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) /* * Some of the data is not accessible over the unencrypted channel - * when contactless reader is used. So start SM now (if not yet establisahed). + * when contactless reader is used. So start SM now (if not yet established). */ if (card->type == SC_CARD_TYPE_EOI_CONTACTLESS && card->sm_ctx.sm_mode == SM_MODE_NONE) { int r = card->sm_ctx.ops.open(card); @@ -119,7 +119,7 @@ int sc_pkcs15emu_eoi_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) * If both PKCS#15 apps are enabled, prkey_mappings can already be partially filled up from the first PKCS#15 app * as the privdata is shared between both apps which use the same driver */ - for (j = 0; privdata->prkey_mappings[j][1] != 0; j++) { + for (j = 0; j < MAX_OBJECTS && privdata->prkey_mappings[j][1] != 0; j++) { /* NOP */ } for (i = 0; i < len; i++) { @@ -127,7 +127,7 @@ int sc_pkcs15emu_eoi_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) if ((objs[i]->auth_id.len == 8) && !strncmp((char*)objs[i]->auth_id.value, "Card PIN", 8)) { memcpy(objs[i]->auth_id.value, "Norm PIN", 8); } - if (prkey_info) { + if (prkey_info && j < MAX_OBJECTS) { privdata->prkey_mappings[j][0] = prkey_info->key_reference; privdata->prkey_mappings[j++][1] = 0xA0 + (i + 1); } From 4ded8e10c12788fa99722c1dcaf7340837196097 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 4 Jun 2026 00:21:08 +0200 Subject: [PATCH 4278/4321] doc: updated info about file caching closes https://github.com/OpenSC/OpenSC/issues/3593 --- doc/files/opensc.conf.5.xml.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 5019eead8c..58ab8e88a9 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1352,6 +1352,13 @@ app application { cached information. Note that the cached files may contain personal data such as name and mail address. + + + The file cache may need to be wiped in order to + detect changes, e.g. after renewal of an on-card + certificate. This is the reason why caching is only + activated for tokens which are known to have a + static profile. From c869a0eb2b90bfda08f92bcf42fb7604720b5e72 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 4 Jun 2026 10:38:17 +0200 Subject: [PATCH 4279/4321] opensc-explorer: document decimal notation for pin/key references fixes https://github.com/OpenSC/OpenSC/issues/3565 --- doc/tools/opensc-explorer.1.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/tools/opensc-explorer.1.xml b/doc/tools/opensc-explorer.1.xml index 1f0d4243ea..ca05934094 100644 --- a/doc/tools/opensc-explorer.1.xml +++ b/doc/tools/opensc-explorer.1.xml @@ -248,7 +248,8 @@ Change the PIN specified by pin-ref from the value given by old-pin and - change its value to new-pin. + change its value to new-pin. References + should be given in decimal notation. old-pin and @@ -567,7 +568,7 @@ CHV, KEY, AUT or PRO. key-id is a number - representing the key or PIN reference. + representing the key or PIN reference (decimal notation). @@ -637,6 +638,7 @@ Unblock the PIN denoted by pin-ref + (decimal notation) using the PUK puk, and potentially change its value to new-pin. @@ -759,7 +761,7 @@ CHV, KEY, AUT or PRO. key-id is a number representing - the key or PIN reference. + the key or PIN reference (decimal notation). key is the key or PIN to be verified, formatted as a colon-separated sequence of hexadecimal values or a string enclosed in double quotes ("..."). From 39aec8698778b1adb5716d46fba2587b05fba4f8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Sep 2025 00:09:07 +0200 Subject: [PATCH 4280/4321] PC/SC: fixed missing events of sc_wait_for_event() pcsc_wait_for_event now exports an opaque structure which not only holds the reader states but also indicates the SCARDCONTEXT, which is used to query for events. This context is exclusively for these event requests, which fixes the problem of events being swallowed by the primary SCARDCONTEXT that is used for standard card/reader interaction. It seems to be consistent across macOS, Windows and Linux that SCardGetStatusChange returns new events based on those that have been detected with the same context rather than those events that are based on the input of LPSCARD_READERSTATE. --- src/libopensc/reader-pcsc.c | 198 +++++++++++++++++++++++++----------- 1 file changed, 137 insertions(+), 61 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 25d038ed58..8cad8fc1ca 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -101,10 +101,21 @@ void APDU_LOG(u8 *rbuf, uint16_t rsize) #define APDU_LOG(rbuf, rsize) #endif +#define MAX_PCSC_EVENT_LISTENERS +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + struct pcsc_global_private_data { int cardmod; SCARDCONTEXT pcsc_ctx; - SCARDCONTEXT pcsc_wait_ctx; + /** `SCARDCONTEXT`s dedicated for detecting reader events. Each calling + * thread will get one free slot assigned. We use global tracking of all + * slots to allow pcsc_cancel to abort each blocking operation. PC/SC + * events are tied to the SCARDCONTEXT, which is why we cannot reuse + * pcsc_ctx for watching events as that may interfere with its usage of + * in `refresh_attributes()`, that may swallow events from a different + * waiting thread. For PKCS#11 we need at least 16 contexts for each + * virtual slot. */ + SCARDCONTEXT pcsc_wait_ctx[32]; int enable_pinpad; int fixed_pinlength; int enable_pace; @@ -800,9 +811,9 @@ static int pcsc_reset(sc_reader_t *reader, int do_cold_reset) return r; } - static int pcsc_cancel(sc_context_t *ctx) { + size_t i; LONG rv = SCARD_S_SUCCESS; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)ctx->reader_drv_data; @@ -811,18 +822,16 @@ static int pcsc_cancel(sc_context_t *ctx) if (ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; -#ifndef _WIN32 - if (gpriv->pcsc_wait_ctx != (SCARDCONTEXT)-1) { - rv = gpriv->SCardCancel(gpriv->pcsc_wait_ctx); - if (rv == SCARD_S_SUCCESS) { - /* Also close and clear the waiting context */ - rv = gpriv->SCardReleaseContext(gpriv->pcsc_wait_ctx); - gpriv->pcsc_wait_ctx = -1; + for (i = 0; i < ARRAY_SIZE(gpriv->pcsc_wait_ctx); i++) { + if (gpriv->pcsc_wait_ctx[i] != (SCARDCONTEXT)-1) { + rv = gpriv->SCardCancel(gpriv->pcsc_wait_ctx[i]); + if (rv == SCARD_S_SUCCESS) { + /* Also close and clear the waiting context */ + rv = gpriv->SCardReleaseContext(gpriv->pcsc_wait_ctx[i]); + gpriv->pcsc_wait_ctx[i] = -1; + } } } -#else - rv = gpriv->SCardCancel(gpriv->pcsc_ctx); -#endif if (rv != SCARD_S_SUCCESS) { PCSC_LOG(ctx, "SCardCancel/SCardReleaseContext failed", rv); return pcsc_to_opensc_error(rv); @@ -844,7 +853,7 @@ static int pcsc_init(sc_context_t *ctx) struct pcsc_global_private_data *gpriv; scconf_block *conf_block = NULL; int ret = SC_ERROR_INTERNAL; - + size_t i; gpriv = calloc(1, sizeof(struct pcsc_global_private_data)); if (gpriv == NULL) { @@ -866,7 +875,9 @@ static int pcsc_init(sc_context_t *ctx) gpriv->fixed_pinlength = 0; gpriv->enable_pace = 1; gpriv->pcsc_ctx = -1; - gpriv->pcsc_wait_ctx = -1; + for (i = 0; i < ARRAY_SIZE(gpriv->pcsc_wait_ctx); i++) { + gpriv->pcsc_wait_ctx[i] = -1; + } /* max send/receive sizes: if exist in configuration these options overwrite * the values by default and values declared by reader */ gpriv->force_max_send_size = 0; @@ -1466,7 +1477,9 @@ static int pcsc_detect_readers(sc_context_t *ctx) if ((rv == (LONG)SCARD_E_NO_SERVICE) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) { gpriv->SCardReleaseContext(gpriv->pcsc_ctx); gpriv->pcsc_ctx = -1; - gpriv->pcsc_wait_ctx = -1; + for (i = 0; i < ARRAY_SIZE(gpriv->pcsc_wait_ctx); i++) { + gpriv->pcsc_wait_ctx[i] = -1; + } /* reconnecting below may may restart PC/SC service */ rv = SCARD_E_INVALID_HANDLE; } @@ -1597,48 +1610,106 @@ static int pcsc_detect_readers(sc_context_t *ctx) LOG_FUNC_RETURN(ctx, ret); } +struct pcsc_reader_states { + size_t pcsc_wait_ctx_index; + SCARD_READERSTATE *reader_states; +}; + +static void +pcsc_reader_states_free(sc_context_t *ctx, struct pcsc_reader_states *states) +{ + if (states) { + if (ctx) { + struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)ctx->reader_drv_data; + if (states->pcsc_wait_ctx_index < ARRAY_SIZE(gpriv->pcsc_wait_ctx)) { + gpriv->SCardReleaseContext(gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index]); + gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index] = -1; + } + } + free(states->reader_states); + free(states); + } +} /* Wait for an event to occur. */ +/** Summary Table + +| PC/SC State Change | Condition | Returned Event | Return Code | +|------------------------------|----------------------------|-----------------------------------------------------------------|-----------------------------| +| Card inserted | `PRESENT ↑` | `SC_EVENT_CARD_INSERTED` | `SC_SUCCESS` | +| Card removed | `PRESENT ↓` | `SC_EVENT_CARD_REMOVED` | `SC_SUCCESS` | +| Reader attached | `UNKNOWN ↓` | `SC_EVENT_READER_ATTACHED` | `SC_SUCCESS` | +| Reader detached | `UNKNOWN ↑` or `IGNORE ↑` | `SC_EVENT_READER_DETACHED` | `SC_SUCCESS` | +| PnP hotplug attach | via pseudo-reader | `SC_EVENT_READER_ATTACHED` (+ optional `SC_EVENT_CARD_INSERTED`) | `SC_SUCCESS` | +| PnP hotplug detach (Windows) | via pseudo-reader | `SC_EVENT_READER_DETACHED` | `SC_SUCCESS` | +| Timeout | `SCARD_E_TIMEOUT` | none | `SC_ERROR_EVENT_TIMEOUT` | +| Cancel | `SCARD_E_CANCELLED` | none | `SC_ERROR_EVENT_TIMEOUT` | +| PC/SC error | `rv != SCARD_S_SUCCESS` | none | `pcsc_to_opensc_error(rv)` | +| No readers | `num_watch == 0` | none | `SC_ERROR_NO_READERS_FOUND` | + */ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, int timeout, void **reader_states) { struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)ctx->reader_drv_data; LONG rv; - SCARD_READERSTATE *rgReaderStates; unsigned int num_watch, count, i; int r = SC_ERROR_INTERNAL, detect_readers = 0, detected_hotplug = 0; DWORD dwtimeout; + struct pcsc_reader_states *states; LOG_FUNC_CALLED(ctx); if (!event_reader && !event && reader_states) { + /* delete reader states and release all associated resources */ sc_log(ctx, "free allocated reader states"); - free(*reader_states); + pcsc_reader_states_free(ctx, *reader_states); *reader_states = NULL; LOG_FUNC_RETURN(ctx, SC_SUCCESS); } if (reader_states == NULL || *reader_states == NULL) { - rgReaderStates = calloc(sc_ctx_get_reader_count(ctx) + 2, sizeof(SCARD_READERSTATE)); - if (!rgReaderStates) + /* initialize new reader states */ + states = calloc(1, sizeof *states); + if (!states) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + /* find an empty slot for the new listener */ + for (states->pcsc_wait_ctx_index = 0; states->pcsc_wait_ctx_index < ARRAY_SIZE(gpriv->pcsc_wait_ctx); states->pcsc_wait_ctx_index++) { + if (gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index] == (SCARDCONTEXT)-1) + /* empty slot found */ + break; + } + if (states->pcsc_wait_ctx_index == ARRAY_SIZE(gpriv->pcsc_wait_ctx)) { + sc_log(ctx, "too many listeners active already"); + r = SC_ERROR_INTERNAL; + goto out; + } else { + sc_log(ctx, "PC/SC event listener %" SC_FORMAT_LEN_SIZE_T "d", states->pcsc_wait_ctx_index); + } + + count = sc_ctx_get_reader_count(ctx); + + states->reader_states = calloc(count + 2, sizeof(SCARD_READERSTATE)); + if (!states->reader_states) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto out; + } + /* Find out the current status */ num_watch = 0; - count = sc_ctx_get_reader_count(ctx); for (i = 0; i < count; i++) { sc_reader_t *reader = sc_ctx_get_reader(ctx, i); if (reader->flags & SC_READER_REMOVED) continue; struct pcsc_private_data *priv = reader->drv_data; - rgReaderStates[num_watch].szReader = reader->name; + states->reader_states[num_watch].szReader = reader->name; if (priv->reader_state.szReader == NULL) { - rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE; + states->reader_states[num_watch].dwCurrentState = SCARD_STATE_UNAWARE; } else { - rgReaderStates[num_watch].dwCurrentState = priv->reader_state.dwEventState; + states->reader_states[num_watch].dwCurrentState = priv->reader_state.dwEventState; } - rgReaderStates[num_watch].dwEventState = SCARD_STATE_UNAWARE; + states->reader_states[num_watch].dwEventState = SCARD_STATE_UNAWARE; num_watch++; } sc_log(ctx, "Trying to watch %d reader%s", num_watch, num_watch == 1 ? "" : "s"); @@ -1653,40 +1724,43 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re detect_readers = 1; detected_hotplug = 1; #else - rgReaderStates[num_watch].szReader = "\\\\?PnP?\\Notification"; - rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE; + states->reader_states[num_watch].szReader = "\\\\?PnP?\\Notification"; + states->reader_states[num_watch].dwCurrentState = SCARD_STATE_UNAWARE; #ifdef _WIN32 /* Windows expects number of readers in HiWord of dwCurrentState. * See https://stackoverflow.com/questions/16370909. */ - rgReaderStates[num_watch].dwCurrentState |= (num_watch << 16); + states->reader_states[num_watch].dwCurrentState |= (num_watch << 16); #endif - rgReaderStates[num_watch].dwEventState = SCARD_STATE_UNAWARE; + states->reader_states[num_watch].dwEventState = SCARD_STATE_UNAWARE; num_watch++; sc_log(ctx, "Trying to detect new readers"); #endif } + } else { + /* reader states already initialized */ + states = *reader_states; + + if (states->pcsc_wait_ctx_index >= ARRAY_SIZE(gpriv->pcsc_wait_ctx)) { + sc_log(ctx, "PC/SC event listener %" SC_FORMAT_LEN_SIZE_T "d not available", states->pcsc_wait_ctx_index); + r = SC_ERROR_INTERNAL; + goto out; + } + + for (num_watch = 0; states->reader_states[num_watch].szReader; num_watch++) + sc_log(ctx, "reuse reader '%s'", states->reader_states[num_watch].szReader); } - else { - rgReaderStates = (SCARD_READERSTATE *)(*reader_states); - for (num_watch = 0; rgReaderStates[num_watch].szReader; num_watch++) - sc_log(ctx, "reuse reader '%s'", rgReaderStates[num_watch].szReader); - } -#ifndef _WIN32 - /* Establish a new context, assuming that it is called from a different thread with pcsc-lite */ - if (gpriv->pcsc_wait_ctx == (SCARDCONTEXT)-1) { - rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &gpriv->pcsc_wait_ctx); + + if (gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index] == (SCARDCONTEXT)-1) { + rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index]); if (rv != SCARD_S_SUCCESS) { - gpriv->pcsc_wait_ctx = -1; + gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index] = -1; PCSC_LOG(ctx, "SCardEstablishContext(wait) failed", rv); r = pcsc_to_opensc_error(rv); goto out; } } -#else - gpriv->pcsc_wait_ctx = gpriv->pcsc_ctx; -#endif - if (!event_reader || !event) - { + + if (!event_reader || !event) { r = SC_ERROR_INTERNAL; goto out; } @@ -1700,7 +1774,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re goto out; } - rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx, 0, rgReaderStates, num_watch); + rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index], 0, states->reader_states, num_watch); if (rv != SCARD_S_SUCCESS) { if (rv != (LONG)SCARD_E_TIMEOUT) { PCSC_LOG(ctx, "SCardGetStatusChange(1) failed", rv); @@ -1717,7 +1791,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re /* Scan the current state of all readers to see if they * match any of the events we're polling for */ - for (i = 0, rsp = rgReaderStates; i < num_watch; i++, rsp++) { + for (i = 0, rsp = states->reader_states; i < num_watch; i++, rsp++) { DWORD state, prev_state; sc_log(ctx, "'%s' before=0x%08X now=0x%08X", rsp->szReader, @@ -1746,13 +1820,6 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re /* Windows wants us to manually reset the changed state */ rsp->dwEventState &= ~SCARD_STATE_CHANGED; - - /* By default, ignore a hotplug event as if a timeout - * occurred, since it may be an unrequested removal or - * false alarm. Just continue to loop and check at the end - * of this function whether we need to return the attached - * reader or not. */ - r = SC_ERROR_EVENT_TIMEOUT; } else { sc_reader_t *reader = sc_ctx_get_reader_by_name(ctx, rsp->szReader); @@ -1797,8 +1864,15 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re } /* if a reader was detected, we need to create a new list of readers */ - if (detected_hotplug) + if (detected_hotplug) { + /* By default, ignore a hotplug event as if a timeout + * occurred, since it may be an unrequested removal or + * false alarm. Just continue to loop and check at the end + * of this function whether we need to return the attached + * reader or not. */ + r = SC_ERROR_EVENT_TIMEOUT; goto out; + } /* Set the timeout if caller wants to time out */ if (timeout == -1) { @@ -1807,10 +1881,10 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re else dwtimeout = timeout; - rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx, dwtimeout, rgReaderStates, num_watch); + rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx[states->pcsc_wait_ctx_index], dwtimeout, states->reader_states, num_watch); if (rv == (LONG)SCARD_E_CANCELLED) { - /* C_Finalize was called, events don't matter */ + /* pcsc_cancel was called, events don't matter */ r = SC_ERROR_EVENT_TIMEOUT; goto out; } @@ -1826,6 +1900,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re goto out; } } + out: /* in case of an error re-detect all readers */ if (r < 0 && r != SC_ERROR_EVENT_TIMEOUT) @@ -1868,16 +1943,17 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re } if (detect_readers) { - free(rgReaderStates); - if (reader_states && *reader_states) + pcsc_cancel(ctx); + pcsc_reader_states_free(ctx, states); + if (reader_states) { *reader_states = NULL; + } } else { if (!reader_states) { - free(rgReaderStates); - } - else if (*reader_states == NULL) { + pcsc_reader_states_free(ctx, states); + } else if (*reader_states == NULL) { sc_log(ctx, "return allocated reader states"); - *reader_states = rgReaderStates; + *reader_states = states; } } From e1e11cebc9a8dfefee01ed27b7b45c9872e0fd7f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jun 2026 13:49:38 +0200 Subject: [PATCH 4281/4321] pkcs11-tool: fixed possible buffer overflow (#3710) * pkcs11-tool: fixed possible buffer overflow identical to CVE-2026-10275, but for ECC rather than for RSA keys: - https://github.com/OpenSC/OpenSC/pull/3684 - https://github.com/advisories/GHSA-c758-vvqj-x96q fixes https://github.com/OpenSC/OpenSC/issues/3705 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch assignment # Changes to be committed: # modified: src/tools/pkcs11-tool.c # # Untracked files: # .aider.chat.history.md # .aider.input.history # .aider.tags.cache.v4/ # .vs/ # MacOSX/build-package # NotificationProxy/ # OpenSCToken # ctk-tool.diff # files # formatting # openpace/ # openssl/ # patch.diff.txt # src/.DS_Store # src/pkcs11/logins # src/pkcs11/opensc.module # src/tools/Frank_Morgner_B9684C4.cer # src/tools/Frank_Morgner_F505282.cer # src/tools/ctk-tool_entitlements.plist # src/tools/normal # * a * fixed formatting --- src/tools/pkcs11-tool.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9de15c1869..d75ec958ba 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -9797,7 +9797,11 @@ static void test_ec(CK_SLOT_ID slot, CK_SESSION_HANDLE session) printf("ERR: newly generated private key has no (or an empty) CKA_ID\n"); return; } - i = (size_t) opt_object_id_len; + opt_object_id_len = (size_t)i; + if (opt_object_id_len > sizeof(opt_object_id)) { + fprintf(stderr, "ERR: object ID too long\n"); + return; + } memcpy(opt_object_id, tmp, opt_object_id_len); /* This is done in NSS */ From eaf9d6acee41c605a3cfbed9b7303d5e33ba3dc8 Mon Sep 17 00:00:00 2001 From: Stanislaw Wawszczak <35380086+Wawszczak@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:53:40 +0200 Subject: [PATCH 4282/4321] pkcs11-tool: increase input buffer of unwrap_key to 16384 bytes (#3696) * Function unwrap_key reads to dynamically allocated buffer with length 8192 instead of static one with length 2048. * adding free(in_buffer) to unwrap_key() in pkcs11-tool * pkcs11-tool: unwrap_key() reads input into dynamically growing buffer Replace fixed 8192-byte malloc + single read() with a do-while loop that starts at 512 bytes and doubles via realloc() until EOF, handling both regular files and stdin correctly. Co-Authored-By: Claude Sonnet 4.6 * Undo dynamic buffer changes in unwrap_key() and set up fixed length in_buffer[16384] --------- Co-authored-by: Claude Sonnet 4.6 --- src/tools/pkcs11-tool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index d75ec958ba..57ed6dd299 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4136,7 +4136,7 @@ unwrap_key(CK_SESSION_HANDLE session) int n_attr = 2; CK_RV rv; int fd; - unsigned char in_buffer[2048]; + unsigned char in_buffer[16384]; CK_ULONG wrapped_key_length; CK_BYTE_PTR pWrappedKey; params_t params = {0}; @@ -4146,9 +4146,9 @@ unwrap_key(CK_SESSION_HANDLE session) ssize_t sz; if (!find_object(session, CKO_PRIVATE_KEY, &hUnwrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) if (!find_object(session, CKO_SECRET_KEY, &hUnwrappingKey, - opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) + opt_object_id_len ? opt_object_id : NULL, opt_object_id_len, NULL, 0)) util_fatal("Private/secret key not found"); if (!opt_mechanism_used) @@ -4263,11 +4263,11 @@ unwrap_key(CK_SESSION_HANDLE session) if (opt_allowed_mechanisms_len > 0) { FILL_ATTR(keyTemplate[n_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, - sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); + sizeof(CK_MECHANISM_TYPE) * opt_allowed_mechanisms_len); n_attr++; } rv = p11->C_UnwrapKey(session, &mechanism, hUnwrappingKey, - pWrappedKey, wrapped_key_length, keyTemplate, n_attr, &hSecretKey); + pWrappedKey, wrapped_key_length, keyTemplate, n_attr, &hSecretKey); if (rv != CKR_OK) p11_fatal("C_UnwrapKey", rv); From 708dddbc516736ad979e383327ab5c31edb65be2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jun 2026 12:58:37 +0200 Subject: [PATCH 4283/4321] IAS/ECC: add bounds checking reported by @TristanInSec --- src/libopensc/card-iasecc.c | 4 ++++ src/libopensc/iasecc-sdo.c | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index d24d4b6837..f508f1eb87 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -1719,6 +1719,8 @@ iasecc_set_security_env(struct sc_card *card, rv = iasecc_sdo_get_data(card, &sdo); LOG_TEST_RET(ctx, rv, "Cannot get RSA PRIVATE SDO data"); + if (sdo.docp.size.size < 2) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); /* To made by iasecc_sdo_convert_to_file() */ prv->key_size = *(sdo.docp.size.value + 0) * 0x100 + *(sdo.docp.size.value + 1); sc_log(ctx, "prv->key_size 0x%"SC_FORMAT_LEN_SIZE_T"X", prv->key_size); @@ -3562,6 +3564,8 @@ iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_refer LOG_FUNC_RETURN(ctx, rv); } + if (sdo->docp.size.size < 2) + continue; sz = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1); sc_log(ctx, "SDO(idx:%i) size %"SC_FORMAT_LEN_SIZE_T"u; key_size %"SC_FORMAT_LEN_SIZE_T"u", diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index c839c2d3d2..b4f6486fb2 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -844,10 +844,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t LOG_FUNC_CALLED(ctx); - if (*data != IASECC_SDO_TAG_HEADER) - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); - - if (data_len < 3) + if (data_len < 3 || !data || *data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); sdo = calloc(1, sizeof(struct iasecc_sdo)); From 3aa01dbccbcead442b5671f61efcafd5157aefc4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jun 2026 13:07:03 +0200 Subject: [PATCH 4284/4321] PC/SC: fixed length checking for PACE escaped commands reported by @TristanInSec --- src/libopensc/reader-pcsc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 8cad8fc1ca..c7e04e0e79 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -2526,6 +2526,8 @@ static int transform_pace_output(u8 *rbuf, size_t rbuflen, parsed += ui8; /* length_CARprev */ + if (parsed+1 > rbuflen) + return SC_ERROR_UNKNOWN_DATA_RECEIVED; ui8 = rbuf[parsed]; /* do not just yet copy ui8 to pace_output->previous_car_length */ parsed += 1; From 9670795d0a5b9b1951046c0ef2501aba3f481826 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jun 2026 13:14:32 +0200 Subject: [PATCH 4285/4321] CAC: fixed possible NULL dereference reported by @TristanInSec --- src/libopensc/card-cac1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index bca08ca3a2..4bf440bce3 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -168,7 +168,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { - *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; + if (flags) + *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; } if (cert_len > 0) { priv->cache_buf = malloc(cert_len); From 03c8bfa1ab70ba77929cd537e68b2a37e6448d2e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 22 Jun 2026 13:30:14 +0200 Subject: [PATCH 4286/4321] PC/SC: added bounds check when parsing reader capabilities reported by @TristanInSec --- src/libopensc/reader-pcsc.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index c7e04e0e79..0cc7f781d1 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -2182,16 +2182,14 @@ static int part10_build_modify_pin_block(struct sc_reader *reader, u8 * buf, siz /* Find a given PCSC v2 part 10 property */ static int part10_find_property_by_tag(unsigned char buffer[], DWORD length, - int tag_searched) + int tag_searched) { unsigned char *p; int found = 0, len, value = -1; p = buffer; - while (p-buffer < (long)length) - { - if (*p++ == tag_searched) - { + while (p - buffer < (long)length) { + if (*p++ == tag_searched) { found = 1; break; } @@ -2201,12 +2199,11 @@ part10_find_property_by_tag(unsigned char buffer[], DWORD length, p += len; } - if (found) - { + if (found && p - buffer < (long)length) { len = *p++; - switch(len) - { + if (p - buffer + len <= (long)length) { + switch (len) { case 1: value = *p; break; @@ -2218,11 +2215,12 @@ part10_find_property_by_tag(unsigned char buffer[], DWORD length, break; default: value = -1; + } } } return value; -} /* part10_find_property_by_tag */ +} /* Make sure the pin min and max are supported by the reader * and fix the values if needed */ @@ -2526,7 +2524,7 @@ static int transform_pace_output(u8 *rbuf, size_t rbuflen, parsed += ui8; /* length_CARprev */ - if (parsed+1 > rbuflen) + if (parsed + 1 > rbuflen) return SC_ERROR_UNKNOWN_DATA_RECEIVED; ui8 = rbuf[parsed]; /* do not just yet copy ui8 to pace_output->previous_car_length */ From e71f01b705dafa73337c46547b678ac1a6c6e5d8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 10 Jun 2026 12:36:05 +0200 Subject: [PATCH 4287/4321] pkcs11: fixed possible memory corruption reproted by David Linder david_linder@genua.de --- src/pkcs11/mechanism.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index f58ba6c0c3..2f11c066d2 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -395,7 +395,7 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani LOG_FUNC_RETURN(context, (int) rv); if (pMechanism->pParameter && - pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) + pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); @@ -405,7 +405,7 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); if (pMechanism->pParameter) { memcpy(&operation->mechanism_params, pMechanism->pParameter, - pMechanism->ulParameterLen); + pMechanism->ulParameterLen); operation->mechanism.pParameter = &operation->mechanism_params; } rv = mt->sign_init(operation, key); @@ -693,6 +693,10 @@ sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechan if (rv != CKR_OK) LOG_FUNC_RETURN(context, (int) rv); + if (pMechanism->pParameter && + pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) + LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); + rv = session_start_operation(session, SC_PKCS11_OPERATION_VERIFY, mt, &operation); if (rv != CKR_OK) return rv; @@ -700,7 +704,7 @@ sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechan memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); if (pMechanism->pParameter) { memcpy(&operation->mechanism_params, pMechanism->pParameter, - pMechanism->ulParameterLen); + pMechanism->ulParameterLen); operation->mechanism.pParameter = &operation->mechanism_params; } @@ -926,6 +930,10 @@ sc_pkcs11_encr_init(struct sc_pkcs11_session *session, if (rv != CKR_OK) LOG_FUNC_RETURN(context, (int)rv); + if (pMechanism->pParameter && + pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) + LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); + rv = session_start_operation(session, SC_PKCS11_OPERATION_ENCRYPT, mt, &operation); if (rv != CKR_OK) return rv; @@ -1054,6 +1062,10 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session, if (rv != CKR_OK) LOG_FUNC_RETURN(context, (int) rv); + if (pMechanism->pParameter && + pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) + LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); + rv = session_start_operation(session, SC_PKCS11_OPERATION_DECRYPT, mt, &operation); if (rv != CKR_OK) return rv; @@ -1061,7 +1073,7 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session, memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); if (pMechanism->pParameter) { memcpy(&operation->mechanism_params, pMechanism->pParameter, - pMechanism->ulParameterLen); + pMechanism->ulParameterLen); operation->mechanism.pParameter = &operation->mechanism_params; } rv = mt->decrypt_init(operation, key); From 0fa519f07baaa41c3d55aad1e538b89350f9de84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 08:13:52 +0000 Subject: [PATCH 4288/4321] build(deps): bump actions/checkout from 6 to 7 Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/centos.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/codespell.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/doc.yml | 2 +- .github/workflows/external-pkcs11.yaml | 8 ++++---- .github/workflows/fedora.yml | 4 ++-- .github/workflows/formatter.yml | 2 +- .github/workflows/linux-strict.yml | 2 +- .github/workflows/linux.yml | 14 +++++++------- .github/workflows/macos.yml | 8 ++++---- .github/workflows/rpmbuild.yaml | 2 +- .github/workflows/windows.yml | 2 +- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/centos.yml b/.github/workflows/centos.yml index 67ba936d15..ef286374bd 100644 --- a/.github/workflows/centos.yml +++ b/.github/workflows/centos.yml @@ -22,7 +22,7 @@ jobs: image: quay.io/centos/centos:stream10 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-centos.sh - run: .github/build.sh dist - name: Upload test logs @@ -39,6 +39,6 @@ jobs: container: image: quay.io/centos/centos:stream10 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-centos.sh fips - run: .github/build.sh fips diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0384372f93..72bc715afc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index efeb545774..3ee6866dfa 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: codespell-project/actions-codespell@master with: skip: ./src/tests/fuzzing/corpus,compat_* diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index ab4794fcdc..873c7d52e0 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -15,7 +15,7 @@ jobs: env: HAS_COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN != '' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-linux.sh force-install - run: ./bootstrap - run: ./configure --disable-dependency-tracking --enable-piv-sm diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index c3fe23795a..fc0453657c 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -16,7 +16,7 @@ jobs: steps: # Do this before checkout otherwise we will not have a git repository - run: dnf install -y git - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-fedora.sh # git checkout to revert changes to tests/Makefile.am done by the setup - run: | diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index b6328a090f..026d990914 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -38,7 +38,7 @@ jobs: BUILD_PATH: ./ steps: - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Setup Fedora run: .github/setup-fedora.sh kryoptic - name: Install OpenSC @@ -52,7 +52,7 @@ jobs: SOURCE_PATH: ./ BUILD_PATH: ./ steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} @@ -73,7 +73,7 @@ jobs: SOURCE_PATH: ./ BUILD_PATH: ./ steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} @@ -97,7 +97,7 @@ jobs: BUILD_PATH: ./ steps: - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Setup Fedora run: .github/setup-fedora.sh kryoptic - name: Install OpenSC diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 37eeaecf90..2ba53bbecf 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -21,7 +21,7 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-fedora.sh - run: .github/build.sh dist - name: Upload test logs @@ -38,6 +38,6 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-fedora.sh ix86 - run: .github/build.sh ix86 diff --git a/.github/workflows/formatter.yml b/.github/workflows/formatter.yml index 623a495d42..0ed80a355d 100644 --- a/.github/workflows/formatter.yml +++ b/.github/workflows/formatter.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: fetch-depth: 100 - uses: yshui/git-clang-format-lint@master diff --git a/.github/workflows/linux-strict.yml b/.github/workflows/linux-strict.yml index 8f6a5a71b0..6901bd398c 100644 --- a/.github/workflows/linux-strict.yml +++ b/.github/workflows/linux-strict.yml @@ -71,7 +71,7 @@ jobs: container: ubuntu:latest container: ${{ matrix.container }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-linux.sh ${{ matrix.compiler }} force-install - run: .github/build.sh piv-sm dist env: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 43b03da993..5658b2e52a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -43,7 +43,7 @@ jobs: arch: arm64 runs-on: ubuntu-${{ matrix.dist }}${{ matrix.arch == 'arm64' && '-arm' || '' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-linux.sh ${{ matrix.build != 'dist' && 'debug' || '' }} # install debug with valgrind builds - run: .github/build.sh ${{ matrix.build }} ${{ matrix.build == 'piv-sm' && 'valgrind' || '' }} # configure piv-sm with valgrind tests - name: Upload test logs @@ -71,7 +71,7 @@ jobs: build-no-shared: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} @@ -83,7 +83,7 @@ jobs: build-no-openssl: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} @@ -95,7 +95,7 @@ jobs: build-ix86: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} @@ -107,7 +107,7 @@ jobs: build-mingw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-linux.sh mingw force-install - run: .github/build.sh mingw - name: Cache build artifacts @@ -120,7 +120,7 @@ jobs: build-mingw32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts @@ -202,7 +202,7 @@ jobs: env: LIBRESSL_VERSION: 4.2.1 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: ${{ env.BASE_DEPS }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2de5fed521..6e23487323 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -23,9 +23,9 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Checkout OpenSSL sources - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: openssl/openssl ref: openssl-3.5 @@ -79,7 +79,7 @@ jobs: os: [macos-26, macos-15, macos-14] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: .github/setup-macos.sh libressl - run: .github/build.sh libressl - run: .github/cleanup-macos.sh @@ -95,7 +95,7 @@ jobs: runs-on: macos-latest needs: [build] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Pull build artifacts uses: actions/download-artifact@v8 with: diff --git a/.github/workflows/rpmbuild.yaml b/.github/workflows/rpmbuild.yaml index 974fa19bb2..9138deb153 100644 --- a/.github/workflows/rpmbuild.yaml +++ b/.github/workflows/rpmbuild.yaml @@ -44,7 +44,7 @@ jobs: run: | dnf -y install git rpm-build - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: fetch-depth: 0 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1c218cb5b8..1c9e020528 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -35,7 +35,7 @@ jobs: BUILD_NUMBER: ${{ github.run_number }} steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Package suffix shell: bash run: | From 6d08c5b987a1f90bc215a84f17494ae2fd1694d3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 5 Jun 2026 00:13:35 +0200 Subject: [PATCH 4289/4321] CI: test sc-hsm with pico-hsm --- .github/setup-linux.sh | 2 + .github/test-pico-hsm.sh | 46 +++++ .github/workflows/linux.yml | 2 +- src/tests/p11test/pico-hsm_ref.json | 274 ++++++++++++++++++++++++++++ 4 files changed, 323 insertions(+), 1 deletion(-) create mode 100755 .github/test-pico-hsm.sh create mode 100644 src/tests/p11test/pico-hsm_ref.json diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index b1d2ee0f09..bb031e9c39 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -42,6 +42,8 @@ elif [ "$1" == "cac" ]; then DEPS="$DEPS libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools" elif [ "$1" == "oseid" ]; then DEPS="$DEPS socat gawk" +elif [ "$1" == "pico-hsm" ]; then + DEPS="$DEPS cmake" elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == "openpgp" ]; then if [ "$1" == "piv" ]; then DEPS="$DEPS cmake" diff --git a/.github/test-pico-hsm.sh b/.github/test-pico-hsm.sh new file mode 100755 index 0000000000..6ec0883172 --- /dev/null +++ b/.github/test-pico-hsm.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -ex -o xtrace + +source .github/setup-valgrind.sh + +# install the opensc +sudo make install +export LD_LIBRARY_PATH=/usr/local/lib + +# vsmartcard +./.github/setup-vsmartcard.sh + +if [ ! -d pico-hsm ]; then + git clone https://github.com/polhenarejos/pico-hsm.git + git -C pico-hsm submodule update --init --recursive +fi +if [ ! -d pico-hsm/build ]; then + mkdir pico-hsm/build + cmake -DENABLE_EMULATION=1 -S pico-hsm -B pico-hsm/build +fi +if [ ! -f pico-hsm/build/pico_hsm ]; then + make -C pico-hsm/build +fi + +# prepare pcscd +#PCSCD_DEBUG="-d -a" +. .github/restart-pcscd.sh + +sleep 2 +rm -f memory.flash +tar -xf pico-hsm/tests/memory.tar.gz +pico-hsm/build/pico_hsm & +PID=$! +sleep 2 + +# run the tests +pushd src/tests/p11test/ +sleep 5 +$VALGRIND sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 +$VALGRIND ./p11test -s 0 -p 648219 -o pico-hsm.json +diff -u3 pico-hsm_ref.json pico-hsm.json +popd + +# cleanup -- this would break later uses of pcscd +kill -9 $PID diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5658b2e52a..a500dd67fe 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -185,7 +185,7 @@ jobs: dist: ['22.04', '24.04'] arch: [amd64] build: [valgrind] - target: [cac, oseid] + target: [cac, oseid, pico-hsm] runs-on: ubuntu-${{ matrix.dist }} needs: [build] steps: diff --git a/src/tests/p11test/pico-hsm_ref.json b/src/tests/p11test/pico-hsm_ref.json new file mode 100644 index 0000000000..e1472734db --- /dev/null +++ b/src/tests/p11test/pico-hsm_ref.json @@ -0,0 +1,274 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RIPEMD160", + "0", + "0", + "CKF_DIGEST" + ], + [ + "GOSTR3411", + "0", + "0", + "CKF_DIGEST" + ], + [ + "ECDSA", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDSA_SHA1", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDSA_SHA224", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDSA_SHA256", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDSA_SHA384", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDSA_SHA512", + "192", + "521", + "CKF_HW,CKF_SIGN,CKF_VERIFY,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF" + ], + [ + "ECDH1_COFACTOR_DERIVE", + "192", + "521", + "CKF_HW,CKF_DERIVE,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF_EC_UNCOM" + ], + [ + "ECDH1_DERIVE", + "192", + "521", + "CKF_HW,CKF_DERIVE,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,CKF_EC_UNCOM" + ], + [ + "EC_KEY_PAIR_GEN", + "192", + "521", + "CKF_HW,CKF_GENERATE_KEY_PAIR,CKF_EC_F_P,CKF_EC_ECPARAMETERS,CKF_EC_NAMEDCURVE,C" + ], + [ + "RSA_X_509", + "1024", + "4096", + "CKF_HW,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS", + "1024", + "4096", + "CKF_HW,CKF_DECRYPT,CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA1_RSA_PKCS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_PSS", + "1024", + "4096", + "CKF_HW,CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA1_RSA_PKCS_PSS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA256_RSA_PKCS_PSS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA384_RSA_PKCS_PSS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "SHA512_RSA_PKCS_PSS", + "1024", + "4096", + "CKF_SIGN,CKF_VERIFY" + ], + [ + "RSA_PKCS_OAEP", + "1024", + "4096", + "CKF_HW,CKF_DECRYPT" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "1024", + "4096", + "CKF_HW,CKF_GENERATE_KEY_PAIR" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "result": "unknown" +}, +{ + "test_id": "multipart_tests", + "result": "unknown" +}, +{ + "test_id": "ec_sign_size_test", + "result": "pass" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "ENCAPSULATE", + "DECAPSULATE", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "result": "unknown" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" +}] +} From eb0f7223351cb82891469db4a7d311b427b4ca0a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 20 Jun 2026 21:16:42 +0200 Subject: [PATCH 4290/4321] sc-hsm-tool: free resources at end --- src/tools/sc-hsm-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 73546fbf1b..2b410fd4de 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -2186,6 +2186,7 @@ int main(int argc, char *argv[]) fail: err = 1; end: + sc_file_free(file); sc_disconnect_card(card); sc_release_context(ctx); From d88e6b51f76652369c02f0f667400190653ef679 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 21 Jun 2026 15:25:04 +0200 Subject: [PATCH 4291/4321] added Pico HSM to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39ca02d110..90b1f05434 100644 --- a/README.md +++ b/README.md @@ -52,5 +52,6 @@ Build and test status of specific cards: | [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | | [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | | [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | -| SmartCardHSM | [![SmartCardHSM](https://gitlab.com/redhat-crypto/OpenSC/badges/sc-hsm/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| SmartCard-HSM | [![SmartCard-HSM](https://gitlab.com/redhat-crypto/OpenSC/badges/sc-hsm/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | +| [Pico HSM](https://github.com/polhenarejos/pico-hsm/) | [![Pico HSM](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) | | ePass2003 | [![ePass2003](https://gitlab.com/redhat-crypto/OpenSC/badges/epass2003/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) | From bbd66138617c5faa410e9d50f14d21bba9b5b6f2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 23 Jun 2026 11:20:49 +0200 Subject: [PATCH 4292/4321] doc: updated html files --- doc/files/files.html | 6 ++++++ doc/tools/tools.html | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/files/files.html b/doc/files/files.html index 7ad0b79132..8373b5c3cc 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -867,6 +867,12 @@ cached information. Note that the cached files may contain personal data such as name and mail address. +

    + The file cache may need to be wiped in order to + detect changes, e.g. after renewal of an on-card + certificate. This is the reason why caching is only + activated for tokens which are known to have a + static profile.

    file_cache_dir = filename;

    diff --git a/doc/tools/tools.html b/doc/tools/tools.html index f71547dfcf..689ff076b4 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -971,7 +971,8 @@

    Change the PIN specified by pin-ref from the value given by old-pin and - change its value to new-pin. + change its value to new-pin. References + should be given in decimal notation.

    old-pin and new-pin can be @@ -1156,7 +1157,7 @@ CHV, KEY, AUT or PRO. key-id is a number - representing the key or PIN reference. + representing the key or PIN reference (decimal notation).

    put file-id @@ -1193,6 +1194,7 @@ ]

    Unblock the PIN denoted by pin-ref + (decimal notation) using the PUK puk, and potentially change its value to new-pin.

    @@ -1265,7 +1267,7 @@ CHV, KEY, AUT or PRO. key-id is a number representing - the key or PIN reference. + the key or PIN reference (decimal notation). key is the key or PIN to be verified, formatted as a colon-separated sequence of hexadecimal values or a string enclosed in double quotes ("..."). From ac436b4c6cb176bea08deb431b8d46ea47c00ef7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Apr 2026 00:56:27 +0200 Subject: [PATCH 4293/4321] pkcs11: add PC/SC status to each slot to detect changes This detects changes of reader/card without actually querying the device and avoids IO latencies. --- src/pkcs11/pkcs11-global.c | 3 ++- src/pkcs11/sc-pkcs11.h | 3 ++- src/pkcs11/slot.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index cc9313008c..1cef976ec0 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -427,6 +427,7 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) list_destroy(&sessions); while ((slot = list_fetch(&virtual_slots))) { + sc_wait_for_event(context, 0, NULL, NULL, 0, &slot->reader_events); list_destroy(&slot->objects); list_destroy(&slot->logins); free(slot); @@ -648,7 +649,7 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) now = get_current_time(); if (now >= slot->slot_state_expires || now == 0) { /* Update slot status */ - rv = card_detect(slot->reader); + rv = card_detect(slot->reader, slot->reader_events); sc_log(context, "C_GetSlotInfo() card detect rv 0x%lX", rv); if (rv == CKR_TOKEN_NOT_RECOGNIZED || rv == CKR_OK) diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 4334f58fff..3538f8ae66 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -218,6 +218,7 @@ struct sc_pkcs11_slot { CK_SLOT_INFO slot_info; /* Slot specific information (information about reader) */ CK_TOKEN_INFO token_info; /* Token specific information (information about card) */ sc_reader_t *reader; /* same as card->reader if there's a card present */ + void *reader_events; struct sc_pkcs11_card *p11card; /* The card associated with this slot */ unsigned int events; /* Card events SC_EVENT_CARD_{INSERTED,REMOVED} */ void *fw_data; /* Framework specific data */ /* TODO: get know how it used */ @@ -415,7 +416,7 @@ CK_RV card_removed(sc_reader_t *reader); CK_RV card_detect_all(void); CK_RV create_slot(sc_reader_t *reader); void init_slot_info(CK_SLOT_INFO_PTR pInfo, sc_reader_t *reader); -CK_RV card_detect(sc_reader_t *reader); +CK_RV card_detect(sc_reader_t *reader, void *reader_states); CK_RV slot_get_slot(CK_SLOT_ID id, struct sc_pkcs11_slot **); CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot **); CK_RV slot_token_removed(CK_SLOT_ID id); diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 27e4b6ba8c..6233d46478 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -120,6 +120,8 @@ static int object_list_seeker(const void *el, const void *key) CK_RV create_slot(sc_reader_t *reader) { + unsigned int events; + sc_reader_t *found; /* find unused slots previously allocated for the same reader */ struct sc_pkcs11_slot *slot = reader_reclaim_slot(reader); @@ -159,6 +161,7 @@ CK_RV create_slot(sc_reader_t *reader) slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot); init_slot_info(&slot->slot_info, reader); slot->reader = reader; + sc_wait_for_event(context, SC_EVENT_CARD_EVENTS | SC_EVENT_READER_EVENTS, &found, &events, 0, &slot->reader_events); DEBUG_VSS(slot, "Finished initializing this slot"); @@ -206,12 +209,13 @@ CK_RV card_removed(sc_reader_t * reader) return CKR_OK; } - -CK_RV card_detect(sc_reader_t *reader) +CK_RV +card_detect(sc_reader_t *reader, void *reader_states) { struct sc_pkcs11_card *p11card = NULL; int free_p11card = 0; int rc; + int no_change = 0; CK_RV rv; unsigned int i; int j; @@ -219,6 +223,22 @@ CK_RV card_detect(sc_reader_t *reader) sc_log(context, "%s: Detecting smart card", reader->name); /* Check if someone inserted a card */ + + if (reader_states != NULL) { + /* check if any event has occurred since last invocation of `card_detect()` */ + unsigned int mask, events; + sc_reader_t *event_reader; + /* Detect card and reader events */ + mask = SC_EVENT_CARD_EVENTS | SC_EVENT_READER_EVENTS; + int r = sc_wait_for_event(context, mask, &event_reader, &events, 0, &reader_states); + if (r == SC_ERROR_EVENT_TIMEOUT || reader != event_reader) + /* no change happened */ + no_change = 1; + else + /* if some error occurred or there actually was a change, continue with detection routine */ + no_change = 0; + } + again: rc = sc_detect_card_presence(reader); if (rc < 0) { @@ -231,6 +251,11 @@ CK_RV card_detect(sc_reader_t *reader) return CKR_TOKEN_NOT_PRESENT; } + if (no_change == 1) { + sc_log(context, "%s: card present, no change detected", reader->name); + return CKR_OK; + } + /* If the card was changed, disconnect the current one */ if (rc & SC_READER_CARD_CHANGED) { sc_log(context, "%s: Card changed", reader->name); @@ -410,6 +435,7 @@ card_detect_all(void) sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, j); if (slot->reader == reader) { slot->reader = NULL; + sc_wait_for_event(context, 0, NULL, NULL, 0, &slot->reader_events); } } } else { @@ -419,6 +445,7 @@ card_detect_all(void) sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, j); if (slot->reader == reader) { found = 1; + card_detect(slot->reader, slot->reader_events); break; } } @@ -428,8 +455,8 @@ card_detect_all(void) if (rv != CKR_OK) return rv; } + card_detect(reader, NULL); } - card_detect(reader); } } sc_log(context, "All cards detected"); @@ -481,7 +508,7 @@ CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot) if ((*slot)->reader == NULL) return CKR_TOKEN_NOT_PRESENT; sc_log(context, "Slot(id=0x%lX): get token: now detect card", id); - rv = card_detect((*slot)->reader); + rv = card_detect((*slot)->reader, (*slot)->reader_events); if (rv != CKR_OK) return rv; } From 5e9f58db513428e58d097b086ee4a108a01b2065 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 21 Jun 2026 15:29:19 +0200 Subject: [PATCH 4294/4321] oseid: disable broken encryption test case see https://github.com/OpenSC/OpenSC/pull/3711 --- .github/test-oseid.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index a56a2721fd..d422ef1a7c 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -51,7 +51,7 @@ echo | ./OsEID-tool INIT ./OsEID-tool EC-ECDH-TEST ./OsEID-tool UNWRAP-WRAP-TEST ./OsEID-tool DES-AES-UPLOAD-KEYS -./OsEID-tool SYM-CRYPT-TEST +#./OsEID-tool SYM-CRYPT-TEST ./OsEID-tool ERASE-CARD # initialize card for p11test From 6a9a6c6062ed989a0e8073ee67ac7242c9a9b3e3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 25 Jun 2026 22:55:56 +0200 Subject: [PATCH 4295/4321] CI: Added workflow to manage inactive PR/Issues automatically (#3697) * CI: Added workflow to manage inactive PR/Issues automatically * removed unnecessary permissions * updated timeframes per discussion --- .github/workflows/stale.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..b3f681540a --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,21 @@ +name: 'Close stale issues and PRs' + +permissions: + issues: write + pull-requests: write + +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v10 + with: + stale-issue-message: 'This issue has been marked as stale due to inactivity. If there is no further activity, comment, or update within the next 30 days, this issue will be automatically closed. If this issue is still relevant, please leave a comment or provide an update to keep it open. Thank you for your contributions.' + stale-pr-message: 'This pull request has been marked as stale due to inactivity. If there are outstanding review comments, requested changes, failing tests, or missing information, please address them and provide the necessary updates. If no further activity occurs within the next 30 days, this pull request will be automatically closed. If this pull request is still active, please leave a comment or push an update to keep it open. Thank you for your contribution.' + start-date: '2026-07-01T00:00:00Z' # ISO 8601 or RFC 2822 + days-before-stale: 120 + days-before-close: 30 From 07d0d40b0e4051f6fe11f3a92cec56d320670d85 Mon Sep 17 00:00:00 2001 From: Martin Vogt Date: Sun, 19 Apr 2026 16:41:40 +0200 Subject: [PATCH 4296/4321] Certain operating systems (fedora,..) block weak algorithms, eg: SHA1. If we detect an OpenSSL error print out the OpenSSL error message. --- src/tools/pkcs11-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 57ed6dd299..e74c180e20 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -8435,6 +8435,7 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, errors++; } else if (err != 1) { printf("openssl error during verification: 0x%0x (%d)\n", err, err); + ERR_print_errors_fp(stdout); } else printf("OK\n"); From 868b4c72de20457a6ff550056648c1bac996464e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 Jun 2026 15:17:42 +0200 Subject: [PATCH 4297/4321] piv: Avoid buffer overrun when parsing ASN1 from files Originally reported by @TristanInSec. Signed-off-by: Jakub Jelen --- src/libopensc/card-piv.c | 2 +- src/libopensc/pkcs15-pubkey.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a65e0a406e..92c997c855 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3057,7 +3057,7 @@ piv_read_obj_from_file(sc_card_t *card, char *filename, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - memcpy(*buf, tagbuf, len); /* copy first or only part */ + memcpy(*buf, tagbuf, MIN(len, rbuflen)); /* copy first or only part */ /* read rest of file */ if (rbuflen > len + sizeof(tagbuf)) { len = read(f, *buf + sizeof(tagbuf), rbuflen - sizeof(tagbuf)); /* read rest */ diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 2995a7c93f..db51a9b13e 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1293,7 +1293,7 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename, r = SC_ERROR_OUT_OF_MEMORY; goto out; } - memcpy(rbuf, tagbuf, len); /* copy first or only part */ + memcpy(rbuf, tagbuf, MIN(len, rbuflen)); /* copy first or only part */ if (rbuflen > len) { /* read rest of file */ sz = read(f, rbuf + len, rbuflen - len); From 93239549a4303c6b6bd35dae0604f09c0dd77873 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 Jun 2026 16:06:09 +0200 Subject: [PATCH 4298/4321] openpgp: Fix possible buffer overrun with unlike 32bit public exponents Originally reported by @TristanInSec. Signed-off-by: Jakub Jelen --- src/libopensc/card-openpgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 4874c80fbb..89ece9636b 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3634,7 +3634,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_key_gen_store components[0] = key_info->u.rsa.exponent; components[1] = key_info->u.rsa.p; components[2] = key_info->u.rsa.q; - componentlens[0] = key_info->u.rsa.exponent_len; + componentlens[0] = BYTES4BITS(key_info->u.rsa.exponent_len); componentlens[1] = key_info->u.rsa.p_len; componentlens[2] = key_info->u.rsa.q_len; componenttags[0] = 0x91; From 566118a911888014df82b5d3ba2dbc3b45fc1259 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 Jun 2026 16:27:36 +0200 Subject: [PATCH 4299/4321] dtrust: Avoid memory leak on initialization errors Thanks oss-fuzz https://issues.oss-fuzz.com/issues/525823616 Signed-off-by: Jakub Jelen --- src/libopensc/card-dtrust.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-dtrust.c b/src/libopensc/card-dtrust.c index 0569b5c8a0..ab905fe4b3 100644 --- a/src/libopensc/card-dtrust.c +++ b/src/libopensc/card-dtrust.c @@ -227,6 +227,8 @@ _dtrust_match_profile(sc_card_t *card) return SC_SUCCESS; } +static int dtrust_finish(sc_card_t *card); + static int dtrust_match_card(sc_card_t *card) { @@ -326,7 +328,10 @@ dtrust_init(sc_card_t *card) card->drv_data = drv_data; r = _dtrust_get_serialnr(card); - LOG_TEST_RET(card->ctx, r, "Error reading serial number."); + if (r != SC_SUCCESS) { + dtrust_finish(card); + LOG_TEST_RET(card->ctx, r, "Error reading serial number."); + } card->caps |= SC_CARD_CAP_APDU_EXT | SC_CARD_CAP_ISO7816_PIN_INFO; @@ -395,7 +400,10 @@ dtrust_init(sc_card_t *card) case SC_CARD_TYPE_DTRUST_V5_1_M100: case SC_CARD_TYPE_DTRUST_V5_4_MULTI: r = sc_pkcs15_bind(card, NULL, &drv_data->p15card); - LOG_TEST_RET(card->ctx, r, "Binding PKCS#15 context failed"); + if (r != SC_SUCCESS) { + dtrust_finish(card); + LOG_TEST_RET(card->ctx, r, "Binding PKCS#15 context failed"); + } break; } From 274678942db3df42aa3967a79cf946af1dee8e4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 08:13:35 +0000 Subject: [PATCH 4300/4321] build(deps): bump actions/cache from 5 to 6 Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/linux.yml | 14 +++++++------- .github/workflows/macos.yml | 2 +- .github/workflows/rpmbuild.yaml | 2 +- .github/workflows/windows.yml | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a500dd67fe..eaaa814958 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -55,7 +55,7 @@ jobs: tests/*.log src/tests/unittests/*.log - &use_cache - uses: actions/cache@v5 + uses: actions/cache@v6 id: cache-build with: path: ./* @@ -139,7 +139,7 @@ jobs: packages: ${{ env.BASE_DEPS }} version: apt-24.04-amd64-base execute_install_scripts: true - - uses: actions/cache@v5 + - uses: actions/cache@v6 id: cache-build with: path: ./* @@ -209,7 +209,7 @@ jobs: version: apt-latest-base execute_install_scripts: true - name: Restore LibreSSL build - uses: actions/cache/restore@v5 + uses: actions/cache/restore@v6 id: libressl-cache with: path: | @@ -225,7 +225,7 @@ jobs: config.log tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v5 + - uses: actions/cache@v6 id: cache-build if: ${{ success() }} with: @@ -233,7 +233,7 @@ jobs: key: ${{ runner.os }}-libressl-${{ github.sha }} - if: ${{ steps.libressl-cache.outputs.cache-hit != 'true' }} name: Cache LibreSSL build - uses: actions/cache/save@v5 + uses: actions/cache/save@v6 with: path: | libressl-${{ env.LIBRESSL_VERSION }}/ @@ -253,7 +253,7 @@ jobs: packages: ${{ env.BASE_DEPS }} version: apt-latest-base execute_install_scripts: true - - uses: actions/cache@v5 + - uses: actions/cache@v6 id: cache-build with: path: ./* @@ -269,7 +269,7 @@ jobs: runs-on: ubuntu-latest needs: [build, build-mingw] steps: - - uses: actions/cache@v5 + - uses: actions/cache@v6 id: cache-build with: path: ./* diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6e23487323..95f615e8e0 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -33,7 +33,7 @@ jobs: - name: Get OpenSSL commit hash id: openssl_hash run: echo "hash=$(cd openssl && git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - - uses: actions/cache@v5 + - uses: actions/cache@v6 id: cache with: path: openssl_bin diff --git a/.github/workflows/rpmbuild.yaml b/.github/workflows/rpmbuild.yaml index 9138deb153..a0093c2027 100644 --- a/.github/workflows/rpmbuild.yaml +++ b/.github/workflows/rpmbuild.yaml @@ -33,7 +33,7 @@ jobs: shell: bash - name: Cache DNF packages (separate from the main job -- different dependencies) - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: | /var/cache/libdnf5 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1c9e020528..51bc439ae8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -60,7 +60,7 @@ jobs: run: choco install windows-cryptographic-provider-development-kit -y > $null - name: Cache vcpkg if: matrix.configuration == 'Release' - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{ github.workspace }}/vcpkg_cache key: vcpkg-${{ matrix.configuration }}-${{ matrix.platform }}-${{ hashFiles('.github/vcpkg.json', '.github/ports/**') }} From dc5754aab6106865d589c63544188836a29ca42b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jun 2026 16:22:29 +0200 Subject: [PATCH 4301/4321] minidriver: fixed recognition of ECC keys when also RSA is supported fixes https://github.com/OpenSC/OpenSC/issues/3228 reported by @MadeNetwork --- src/minidriver/minidriver.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 1ffc74489b..1d397cf46d 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -2891,17 +2891,17 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi break; } } - if (keysize) { - pKeySizes->dwMinimumBitlen = keysize; - pKeySizes->dwDefaultBitlen = keysize; - pKeySizes->dwMaximumBitlen = keysize; - pKeySizes->dwIncrementalBitlen = 1; - } else { - logprintf(pCardData, 0, - "No ECC key found (keyspec=%lu)\n", - (unsigned long)dwKeySpec); - return SCARD_E_INVALID_PARAMETER; - } + } + if (keysize) { + pKeySizes->dwMinimumBitlen = keysize; + pKeySizes->dwDefaultBitlen = keysize; + pKeySizes->dwMaximumBitlen = keysize; + pKeySizes->dwIncrementalBitlen = 1; + } else { + logprintf(pCardData, 0, + "No ECC key found (keyspec=%lu)\n", + (unsigned long)dwKeySpec); + return SCARD_E_INVALID_PARAMETER; } } From 5f94fdc2ba3821c22bbfca3ad48281ec96214d0a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jun 2026 22:57:22 +0200 Subject: [PATCH 4302/4321] reader-ctk: added guards against missing card object fixes https://github.com/OpenSC/OpenSC/issues/2519 --- src/libopensc/reader-cryptotokenkit.m | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index bf8a1a52c6..f963a1710c 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -180,7 +180,7 @@ static int cryptotokenkit_connect(sc_reader_t *reader) } if (!priv->tksmartcard || !priv->tksmartcard.valid) - return SC_ERROR_CARD_NOT_PRESENT; + return SC_ERROR_CARD_REMOVED; /* if tksmartcard.context is set to nil, we know that the card has been * reset or acquired by a different session */ @@ -212,6 +212,8 @@ static int cryptotokenkit_lock(sc_reader_t *reader) if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) goto err; + if (!priv->tksmartcard) + return SC_ERROR_CARD_REMOVED; if (priv->tksmartcard.context == nil) { r = SC_ERROR_CARD_RESET; @@ -239,8 +241,11 @@ static int cryptotokenkit_unlock(sc_reader_t *reader) LOG_FUNC_CALLED(reader->ctx); + if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; + if (!priv->tksmartcard) + return SC_ERROR_CARD_REMOVED; [priv->tksmartcard endSession]; @@ -259,6 +264,9 @@ static int cryptotokenkit_transmit(sc_reader_t *reader, sc_apdu_t *apdu) LOG_FUNC_CALLED(reader->ctx); + if (!priv->tksmartcard) + return SC_ERROR_CARD_REMOVED; + r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, reader->active_protocol); if (r != SC_SUCCESS) goto err; @@ -343,6 +351,8 @@ int cryptotokenkit_perform_verify(struct sc_reader *reader, struct sc_pin_cmd_da if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; + if (!priv->tksmartcard) + return SC_ERROR_CARD_REMOVED; /* The APDU must be provided by the card driver */ if (!data->apdu) { From 727fa9caaea9f8926da2b57ee3fb556e1d9f4ce4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 26 Jun 2026 23:50:12 +0200 Subject: [PATCH 4303/4321] PKCS#11: fixed possible use of uninitialized pointer fixes https://github.com/OpenSC/OpenSC/issues/2976 --- src/pkcs11/framework-pkcs15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 0ab154ed75..7feab16195 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -6547,7 +6547,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) CK_ULONG ec_min_key_size, ec_max_key_size, aes_min_key_size, aes_max_key_size; unsigned long ec_ext_flags; - sc_pkcs11_mechanism_type_t *mt, *registered_mt; + sc_pkcs11_mechanism_type_t *mt = NULL, *registered_mt = NULL; unsigned int num; int rsa_flags = 0, ec_flags = 0, eddsa_flags = 0, xeddsa_flags = 0; int ec_found = 0, gostr_flags = 0, aes_flags = 0; From d6d2dfad7c8438635533dd42c4701b1032e0a631 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 27 Jun 2026 15:28:37 +0200 Subject: [PATCH 4304/4321] CI: Pin IsoApplet v1 to its latest working version It is not working with jCardSim anymore, see https://github.com/OpenSC/OpenSC/pull/3632#issuecomment-4818353292 --- .github/test-isoapplet.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 08b9c0277e..6c211440a3 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -5,14 +5,6 @@ set -ex -o xtrace source .github/setup-valgrind.sh isoapplet_version="$1" -if [ "$isoapplet_version" = "v0" ]; then - isoapplet_branch="main-javacard-v2.2.2" -elif [ "$isoapplet_version" = "v1" ]; then - isoapplet_branch="main" -else - echo "Unknown IsoApplet version: $isoapplet_version" - exit 1 -fi isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" @@ -25,7 +17,17 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch --depth 1 + if [ "$isoapplet_version" = "v0" ]; then + isoapplet_branch="main-javacard-v2.2.2" + git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch --depth 1 + elif [ "$isoapplet_version" = "v1" ]; then + #isoapplet_branch="main" + git clone https://github.com/philipWendland/IsoApplet.git --revision 9cf87af45dc2949730a700a52a2dceb87353734c --depth 1 + else + echo "Unknown IsoApplet version: $isoapplet_version" + exit 1 + fi + # enable IsoApplet key import patch sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" fi From f164e2b2f60055afcb2a3e378f907577289679d7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 Jul 2026 16:08:16 +0200 Subject: [PATCH 4305/4321] ci: Fix filename in workflow file --- .github/workflows/external-pkcs11.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/external-pkcs11.yaml b/.github/workflows/external-pkcs11.yaml index 026d990914..bc9f71a06d 100644 --- a/.github/workflows/external-pkcs11.yaml +++ b/.github/workflows/external-pkcs11.yaml @@ -6,7 +6,7 @@ on: - '**.c' - '**.h' - '**.sh' - - .github/workflows/fedora.yml + - .github/workflows/external-pkcs11.yaml - '**.am' - doc/** - configure.ac From 5e2191a27a0a247b4f40d8adf36174fb03229834 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 16 Jul 2026 16:08:35 +0200 Subject: [PATCH 4306/4321] tests: Disable SoftHSM wrapping tests as it crashes Fixes: #3728 --- tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh index 417d67ddb0..c0e48538cc 100755 --- a/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh +++ b/tests/test-pkcs11-tool-unwrap-wrap-interoperability-test.sh @@ -107,7 +107,7 @@ for MECH in AES-CBC AES-KEY-WRAP RSA-PKCS; do if [ "$MECH" == "RSA-PKCS" ]; then ID_WRAP=$ID_RSA_WRAP fi - for WRAPPER in SoftHSM Kryoptic Softokn; do + for WRAPPER in Kryoptic Softokn; do # SoftHSM removed temporarily as it crashes for UNWRAPPER in SoftHSM Kryoptic Softokn; do if [ "$WRAPPER" == "$UNWRAPPER" ]; then continue; From c6c940542ffb3c7fa48a2efa58dc50ef4a28a870 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Jun 2026 11:23:07 +0200 Subject: [PATCH 4307/4321] epass2003: Fix potential stack buffer overflow when encoding SM APDU Origianlly reported and patch provided by Mitchell Benjamin of Revamp Studio --- src/libopensc/card-epass2003.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 5a7b073624..9838008589 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -961,6 +961,11 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap exdata = (epass2003_exdata *)card->drv_data; + /* we encrypt the pad buffer and then write it to the apdu_buf at offset block_size + tlv_more */ + if (apdu->lc >= sizeof(pad) - block_size - 5) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, + "ePass2003 secure messaging APDU data too large"); + /* padding */ apdu_buf[block_size] = 0x87; memcpy(pad, apdu->data, apdu->lc); From ed27f12d1371fcde1027ed25c92570618217b711 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Jun 2026 11:38:46 +0200 Subject: [PATCH 4308/4321] iasecc: Avoid reading behind data buffer bounds Origianlly reported by Mitchell Benjamin of Revamp Studio --- src/libopensc/pkcs15-iasecc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index 417549ba14..1b987fbea7 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -62,15 +62,26 @@ _iasecc_md_update_keyinfo(struct sc_pkcs15_card *p15card, struct sc_pkcs15_objec rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobj->data, private_obj, &ddata); LOG_TEST_RET(ctx, rv, "Failed to read container DATA object data"); + /* [0] = 0x01 + * [1] = length + * [2 .. 2 + length] = ID + * [2 + length] = 0x02 + * [2 + length + 1] = 0x01 + * [3 + length + 2] = flags + */ offs = 0; - if (*(ddata->data + offs++) != 0x01) { + if (ddata->data_len < 2 || *(ddata->data + offs++) != 0x01) { sc_pkcs15_free_data_object(ddata); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); } id.len = *(ddata->data + offs++); + if (id.len > sizeof(id.value) || ddata->data_len < offs + id.len + 3) { + sc_pkcs15_free_data_object(ddata); + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + } memcpy(id.value, ddata->data + offs, id.len); - offs += (int) id.len; + offs += (int)id.len; if (*(ddata->data + offs++) != 0x02) { sc_pkcs15_free_data_object(ddata); From d913ce10ac94e585d5d7fc4eb5f2e4db9383627a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Jun 2026 11:55:29 +0200 Subject: [PATCH 4309/4321] myeid: Fix stack buffer overflow Origianlly reported and initial patch provided by Mitchell Benjamin of Revamp Studio --- src/libopensc/card-myeid.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index b933676810..8ce80ab3a2 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1220,11 +1220,13 @@ int myeid_ecdh_derive(struct sc_card *card, const u8* pubkey, size_t pubkey_len, /* MyEID uses GENERAL AUTHENTICATE ISO command for ECDH */ struct sc_apdu apdu; + u8 pbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - size_t ext_len_bytes; + size_t pbuf_len = sizeof(pbuf); + u8 *ptr; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x86, 0x00, 0x00); @@ -1233,33 +1235,19 @@ int myeid_ecdh_derive(struct sc_card *card, const u8* pubkey, size_t pubkey_len, /* Fill in "Data objects in dynamic authentication template" (tag 0x7C) structure * - * TODO: encode the structure using OpenSC's ASN1-functions. - * * Size of the structure depends on key length. With 521 bit keys two bytes are needed for defining length of a point. */ - sbuf[0] = 0x7C; - ext_len_bytes = 0; - - if (pubkey_len > 127) - { - sbuf[1] = 0x81; - sbuf[2] = (u8) (pubkey_len + 3); - sbuf[3] = 0x85; - sbuf[4] = 0x81; - sbuf[5] = (u8) (pubkey_len); - ext_len_bytes = 2; - } - else - { - sbuf[1] = pubkey_len + 2; - sbuf[2] = 0x85; - sbuf[3] = pubkey_len; - } + /* Inner TLV 0x85 | LEN | pubkey */ + r = sc_asn1_put_tag(0x85, pubkey, pubkey_len, pbuf, sizeof(pbuf), &ptr); + LOG_TEST_RET(card->ctx, r, "Failed to encode inner tlv"); + pbuf_len = (ptr - pbuf); - memcpy(&sbuf[4 + ext_len_bytes], pubkey, pubkey_len); + /* Outer TLV 0x7C | LEN | Inner TLV */ + r = sc_asn1_put_tag(0x7C, pbuf, pbuf_len, sbuf, sizeof(sbuf), &ptr); + LOG_TEST_RET(card->ctx, r, "Failed to encode outer tlv"); - apdu.lc = pubkey_len + 4 + ext_len_bytes; + apdu.lc = (ptr - sbuf); apdu.le = pubkey_len / 2; apdu.datalen = apdu.lc; apdu.data = sbuf; From cedd862957e13ae443f34fe03a78fd5680a48830 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 2 Jun 2026 13:36:43 +0200 Subject: [PATCH 4310/4321] libopensc: avoid heap buffer overflow Origianlly reported by Mitchell Benjamin of Revamp Studio --- src/libopensc/pkcs15-pubkey.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index db51a9b13e..8d6f4d9546 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1293,7 +1293,8 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename, r = SC_ERROR_OUT_OF_MEMORY; goto out; } - memcpy(rbuf, tagbuf, MIN(len, rbuflen)); /* copy first or only part */ + len = MIN(len, rbuflen); + memcpy(rbuf, tagbuf, len); /* copy first or only part */ if (rbuflen > len) { /* read rest of file */ sz = read(f, rbuf + len, rbuflen - len); From fb7cea4f49a8a58b3182a4cc3bada3941d3ad7d9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jun 2026 12:14:42 +0200 Subject: [PATCH 4311/4321] starcos: Avoid buffer overrun during writing 3k RSA key Origianlly reported by Mitchell Benjamin of Revamp Studio --- src/pkcs15init/pkcs15-starcos.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index 267ad2b04a..b385e211de 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -652,7 +652,7 @@ static int starcos_write_pukey(sc_profile_t *profile, sc_card_t *card, { int r; size_t len, keylen, endpos; - u8 *buf, key[280], *p, num_keys; + u8 *buf, key[512], *p, num_keys; sc_file_t *tfile = NULL; sc_path_t tpath; @@ -691,6 +691,11 @@ static int starcos_write_pukey(sc_profile_t *profile, sc_card_t *card, free(buf); return SC_ERROR_INTERNAL; } + /* The fixed buffer `key` should fit 3k RSA key + the header and footer added in this function */ + if (keylen + 12 > sizeof(key)) { + free(buf); + return SC_ERROR_INTERNAL; + } p = key; *p++ = (u8) kinfo->key_reference; *p++ = (keylen >> 8) & 0xff; From 67320599cb6204c2b9e7f5522251bf700ad3d166 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jun 2026 13:19:48 +0200 Subject: [PATCH 4312/4321] scarcos: Avoid buffer overrun while enclding larger RSA private keys This fixes the overrun, but writing 2k nor 3k RSA keys is not possible due to the fixed buffer being too small, see the FIXME comment. Origianlly reported by Mitchell Benjamin of Revamp Studio --- src/pkcs15init/pkcs15-starcos.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index b385e211de..f20e8b5e07 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -500,11 +500,13 @@ static int starcos_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15car return SC_SUCCESS; } +/* FIXME This buffer does not fit the 2k nor 3k RSA key components. For them to work, + * this constant needs to be bumped to 1024 but we do not have a way to test it */ #define STARCOS_MAX_PR_KEYSIZE 370 static int starcos_encode_prkey(struct sc_pkcs15_prkey_rsa *rsa, u8 *buf) { - size_t i = 0; + size_t i = 0, len; u8 *p = buf; /* clear key buffer */ @@ -513,9 +515,12 @@ static int starcos_encode_prkey(struct sc_pkcs15_prkey_rsa *rsa, u8 *buf) if (rsa->p.len && rsa->q.len && rsa->dmp1.len && rsa->dmq1.len && rsa->iqmp.len) { /* CRT RSA key */ + len = 13 + rsa->q.len + rsa->p.len + 16 + rsa->dmq1.len + 16 + rsa->dmp1.len + rsa->p.len; + if (len > STARCOS_MAX_PR_KEYSIZE) { + return SC_ERROR_INTERNAL; + } /* get number of 0x00 bytes */ - i = STARCOS_MAX_PR_KEYSIZE - rsa->p.len - rsa->q.len - - rsa->dmp1.len - rsa->dmq1.len - 45 - rsa->p.len; + i = STARCOS_MAX_PR_KEYSIZE - len; /* key format list */ *p++ = 0x0c; @@ -538,11 +543,11 @@ static int starcos_encode_prkey(struct sc_pkcs15_prkey_rsa *rsa, u8 *buf) *p++ = rsa->p.data[i - 1]; for (i = 16; i != 0; i--) *p++ = 0x00; - for (i = rsa->dmp1.len; i != 0; i--) + for (i = rsa->dmq1.len; i != 0; i--) *p++ = rsa->dmq1.data[i - 1]; for (i = 16; i != 0; i--) *p++ = 0x00; - for (i = rsa->dmq1.len; i != 0; i--) + for (i = rsa->dmp1.len; i != 0; i--) *p++ = rsa->dmp1.data[i - 1]; for (i = rsa->iqmp.len; i != 0; i--) *p++ = rsa->iqmp.data[i - 1]; @@ -550,8 +555,12 @@ static int starcos_encode_prkey(struct sc_pkcs15_prkey_rsa *rsa, u8 *buf) *p++ = 0x00; } else if (rsa->modulus.len && rsa->d.len) { /* normal RSA key */ - i = STARCOS_MAX_PR_KEYSIZE - 7 - rsa->modulus.len - - rsa->d.len - 16; + len = 7 + rsa->modulus.len + 16 + rsa->d.len; + if (len > STARCOS_MAX_PR_KEYSIZE) { + return SC_ERROR_INTERNAL; + } + /* get number of 0x00 bytes */ + i = STARCOS_MAX_PR_KEYSIZE - len; /* key format list */ *p++ = 6; *p++ = 0x90; From 8eacca5fc56cdea8fb8bd1bea8b11628297e929b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 4 Jun 2026 14:15:45 +0200 Subject: [PATCH 4313/4321] epass2003: Fix more possible buffer overruns while encoding SM APDUs --- src/libopensc/card-epass2003.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 9838008589..52f9c30772 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1048,6 +1048,10 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv exdata = (epass2003_exdata *)card->drv_data; + if (data_tlv_len + le_tlv_len + block_size + 1 > sizeof(mac)) { + return SC_ERROR_BUFFER_TOO_SMALL; + } + if (0 == data_tlv_len && 0 == le_tlv_len) { mac_len = block_size; } else { @@ -1127,6 +1131,10 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da exdata = (epass2003_exdata *)card->drv_data; + if (data_tlv_len + le_tlv_len + block_size + 1 > sizeof(mac)) { + return SC_ERROR_BUFFER_TOO_SMALL; + } + if (0 == data_tlv_len && 0 == le_tlv_len) { mac_len = block_size; } else { @@ -1200,6 +1208,7 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, size_t mac_tlv_len = 10; size_t tmp_lc = 0; size_t tmp_le = 0; + size_t expected_total_len; unsigned char mac_tlv[256] = {0}; epass2003_exdata *exdata = NULL; @@ -1256,6 +1265,13 @@ encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm, tmp_lc = 1; } + /* 2 is for Le extension in the worst case */ + expected_total_len = 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + 2; + + if (expected_total_len > *apdu_buf_len) { + return SC_ERROR_BUFFER_TOO_SMALL; + } + memcpy(apdu_buf + 4 + tmp_lc, dataTLV, data_tlv_len); memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len, le_tlv, le_tlv_len); memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len + le_tlv_len, mac_tlv, mac_tlv_len); From d1941c2bc43027f07de8f853a4cbea53e4d9da4f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Jul 2026 10:36:22 +0200 Subject: [PATCH 4314/4321] iasecc: Add NULL guards to prevent NULL dereferennce Thanks oss-fuzz https://issues.oss-fuzz.com/issues/529229967 --- src/libopensc/iasecc-sdo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index b4f6486fb2..4d17b84c9a 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -148,6 +148,10 @@ iasecc_sdo_convert_acl(struct sc_card *card, struct iasecc_sdo *sdo, void iasecc_sdo_free_fields(struct sc_card *card, struct iasecc_sdo *sdo) { + if (sdo == NULL) { + return; + } + free(sdo->docp.tries_maximum.value); free(sdo->docp.tries_remaining.value); free(sdo->docp.usage_remaining.value); From aae270aa96d920aceffb3a76ad2bdc13a58e74b5 Mon Sep 17 00:00:00 2001 From: olszomal Date: Thu, 16 Jul 2026 09:01:55 +0200 Subject: [PATCH 4315/4321] PIV: enable X25519 key derivation for YubiKey 5.7+ Signed-off-by: olszomal --- src/libopensc/card-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 92c997c855..8db549b672 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -5829,7 +5829,7 @@ piv_match_card_continued(sc_card_t *card) if (priv->yubico_version < 0x00040302) priv->card_issues |= CI_VERIFY_LC0_FAIL; if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */ - priv->alg_ids |= AI_RSA_4096 | AI_25519; + priv->alg_ids |= AI_RSA_4096 | AI_25519 | AI_X25519; break; case SC_CARD_TYPE_PIV_II_NITROKEY: @@ -5982,7 +5982,7 @@ piv_init(sc_card_t *card) flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; flags_eddsa = SC_ALGORITHM_EDDSA_RAW; - flags_xeddsa = SC_ALGORITHM_XEDDSA_RAW; + flags_xeddsa = SC_ALGORITHM_XEDDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW; for (i = 0; ec_curves[i].oid.value[0] >= 0; i++) { if (ec_curves[i].key_type == SC_ALGORITHM_EC) { From 3f2dded54cdc292c782a9f5a7fc0260d865fc17d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 17 Jul 2026 00:17:02 +0200 Subject: [PATCH 4316/4321] CI: pin pico-hsm to its latest version --- .github/test-pico-hsm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-pico-hsm.sh b/.github/test-pico-hsm.sh index 6ec0883172..ed6ae1f071 100755 --- a/.github/test-pico-hsm.sh +++ b/.github/test-pico-hsm.sh @@ -12,7 +12,7 @@ export LD_LIBRARY_PATH=/usr/local/lib ./.github/setup-vsmartcard.sh if [ ! -d pico-hsm ]; then - git clone https://github.com/polhenarejos/pico-hsm.git + git clone --depth 1 --branch v6.6 https://github.com/polhenarejos/pico-hsm.git git -C pico-hsm submodule update --init --recursive fi if [ ! -d pico-hsm/build ]; then From a379e9d6327827c665c95e408b99473bbda9e01d Mon Sep 17 00:00:00 2001 From: Vyacheslav Yurkov Date: Sun, 21 Jun 2026 17:29:02 +0000 Subject: [PATCH 4317/4321] configure.ac: Fix reader detection The configure.ac tries to make sure that at most 1 reader is selected, but misses the cases when all are disabled. Signed-off-by: Vyacheslav Yurkov --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 495271cf0c..02ffc6b94f 100644 --- a/configure.ac +++ b/configure.ac @@ -349,8 +349,8 @@ reader_count="" for rdriver in "${enable_pcsc}" "${enable_cryptotokenkit}" "${enable_openct}" "${enable_ctapi}"; do test "${rdriver}" = "yes" && reader_count="${reader_count}x" done -if test "${reader_count}" != "x"; then - AC_MSG_ERROR([Only one of --enable-pcsc, --enable-cryptotokenkit, --enable-openct, --enable-ctapi can be specified!]) +if test -n "${reader_count}" && test "${reader_count}" != "x"; then + AC_MSG_ERROR([At most one of --enable-pcsc, --enable-cryptotokenkit, --enable-openct, --enable-ctapi can be specified!]) fi dnl Checks for programs. From dfe4e4ae88328627c05172927cbee5b100c1ab73 Mon Sep 17 00:00:00 2001 From: Vyacheslav Yurkov Date: Thu, 25 Jun 2026 19:49:56 +0000 Subject: [PATCH 4318/4321] ci: Add a configuration that doesn't use any readers Signed-off-by: Vyacheslav Yurkov --- .github/build.sh | 3 +++ .github/workflows/linux.yml | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/.github/build.sh b/.github/build.sh index 314267dd5b..0fad7fc550 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -78,6 +78,9 @@ else if [ "$1" == "no-openssl" ]; then CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-openssl" fi + if [ "$1" == "no-readers" ]; then + CONFIGURE_FLAGS="$CONFIGURE_FLAGS --disable-pcsc --disable-cryptotokenkit --disable-openct --disable-ctapi" + fi export CFLAGS="-DDEBUG_PROFILE=1 $CFLAGS" ./configure $CONFIGURE_FLAGS make -j 4 V=1 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index eaaa814958..b11347f2f7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -80,6 +80,13 @@ jobs: - run: .github/setup-linux.sh - run: .github/build.sh no-shared valgrind + build-no-readers: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: .github/setup-linux.sh + - run: .github/build.sh no-readers + build-no-openssl: runs-on: ubuntu-latest steps: From d0f842febad1e3550bcd59269fb23bd93ff58684 Mon Sep 17 00:00:00 2001 From: Vyacheslav Yurkov Date: Mon, 20 Jul 2026 12:26:53 +0000 Subject: [PATCH 4319/4321] Add empty reader implementation that always succeeds Signed-off-by: Vyacheslav Yurkov --- src/libopensc/Makefile.am | 4 +- src/libopensc/ctx.c | 2 + src/libopensc/internal.h | 1 + src/libopensc/reader-empty.c | 159 +++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 src/libopensc/reader-empty.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 2132affd4b..e5411a0143 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -35,7 +35,7 @@ libopensc_la_SOURCES_BASE = \ \ muscle.c muscle-filesystem.c \ \ - ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ + ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c reader-empty.c \ \ card-setcos.c card-flex.c \ card-cardos.c card-cardos-common.c card-tcos.c card-default.c \ @@ -117,7 +117,7 @@ TIDY_FILES = \ \ muscle.c muscle-filesystem.c \ \ - ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ + ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c reader-empty.c \ \ card-setcos.c card-flex.c \ card-cardos.c card-tcos.c card-default.c \ diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index cbcbdcee91..e987d001c3 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -1029,6 +1029,8 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) ctx->reader_driver = sc_get_ctapi_driver(); #elif defined(ENABLE_OPENCT) ctx->reader_driver = sc_get_openct_driver(); +#else + ctx->reader_driver = sc_get_empty_driver(); #endif r = ctx->reader_driver->ops->init(ctx); diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 2a98f0e966..2b65b9984f 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -295,6 +295,7 @@ extern struct sc_reader_driver *sc_get_pcsc_driver(void); extern struct sc_reader_driver *sc_get_ctapi_driver(void); extern struct sc_reader_driver *sc_get_openct_driver(void); extern struct sc_reader_driver *sc_get_cryptotokenkit_driver(void); +extern struct sc_reader_driver *sc_get_empty_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/reader-empty.c b/src/libopensc/reader-empty.c new file mode 100644 index 0000000000..4e7c04c452 --- /dev/null +++ b/src/libopensc/reader-empty.c @@ -0,0 +1,159 @@ +/* + * reader-none.c: Reader driver stub with no functionality + * + * Copyright (C) 2026 Vyacheslav Yurkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "internal.h" + +static int +empty_transmit(sc_reader_t *reader, sc_apdu_t *apdu) +{ + return 0; +} + +static int +empty_detect_card_presence(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int +empty_connect(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int +empty_disconnect(sc_reader_t * reader) +{ + return SC_SUCCESS; +} + +static int +empty_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) +{ + return SC_SUCCESS; +} + +static int +empty_lock(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int +empty_unlock(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int +empty_release(sc_reader_t *reader) +{ + return SC_SUCCESS; +} + +static int +empty_reset(sc_reader_t *reader, int do_cold_reset) +{ + return SC_SUCCESS; +} + +static int +empty_cancel(sc_context_t *ctx) +{ + return SC_SUCCESS; +} + +static int +empty_init(sc_context_t *ctx) +{ + return SC_SUCCESS; +} + +static int +empty_finish(sc_context_t *ctx) +{ + return SC_SUCCESS; +} + +static int +empty_detect_readers(sc_context_t *ctx) +{ + return SC_SUCCESS; +} + +static int +empty_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, + int timeout, void **reader_states) +{ + return SC_SUCCESS; +} + +int +empty_perform_pace(struct sc_reader *reader, void *input_pace, void *output_pace) +{ + return SC_SUCCESS; +} + +int +empty_use_reader(sc_context_t *ctx, void *empty_context_handle, void *empty_card_handle) +{ + return SC_SUCCESS; +} + +static struct sc_reader_operations empty_ops; + +static struct sc_reader_driver empty_drv = { + "Empty reader", + "none", + &empty_ops, + NULL +}; + +struct sc_reader_driver * +sc_get_empty_driver(void) +{ + empty_ops.init = empty_init; + empty_ops.finish = empty_finish; + empty_ops.detect_readers = empty_detect_readers; + empty_ops.transmit = empty_transmit; + empty_ops.detect_card_presence = empty_detect_card_presence; + empty_ops.lock = empty_lock; + empty_ops.unlock = empty_unlock; + empty_ops.release = empty_release; + empty_ops.connect = empty_connect; + empty_ops.disconnect = empty_disconnect; + empty_ops.perform_verify = empty_pin_cmd; + empty_ops.wait_for_event = empty_wait_for_event; + empty_ops.cancel = empty_cancel; + empty_ops.reset = empty_reset; + empty_ops.use_reader = empty_use_reader; + empty_ops.perform_pace = empty_perform_pace; + + return &empty_drv; +} From aea995bec9e03efb798f81f60021188e0a8ab065 Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Thu, 23 Jul 2026 21:26:54 +0900 Subject: [PATCH 4320/4321] minidriver: Add ATRs for Japanese Individual Number Card (My Number Card) Windows selects the smart card minidriver primarily by ATR, so the minidriver registration needs the ATRs of the JPKI cards. Add the contact and contactless ATRs of the My Number Card. The contactless ATRs are those constructed from the ATQB by PC/SC part 3 compliant readers, which are stable per card type. Readers that embed the random PUPI into the ATR cannot be matched this way. Card detection in card-jpki.c continues to rely on AID selection; this only affects the Windows minidriver registration. Refs: https://github.com/OpenSC/OpenSC/issues/3021 --- win32/customactions.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 71bf0a0456..98eddba948 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -162,6 +162,26 @@ MD_REGISTRATION minidriver_registration[] = { 11, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("JPKI"), {0x3b,0xe0,0x00,0xff,0x81,0x31,0xfe,0x45,0x14}, 9, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + /* Japanese Individual Number Card (My Number Card), contact interface */ + {TEXT("JPKI (02)"), {0x3b,0xda,0x13,0xff,0x81,0x31,0xfb,0x46,0x80,0x12,0x39,0x2f,0x31,0xc1,0x73,0xc6,0x01,0xc0,0x3b}, + 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (03)"), {0x3b,0xc5,0xff,0x81,0x31,0xfb,0x45,0x80,0x73,0xc6,0x01,0x00,0x00}, + 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (04)"), {0x3b,0xf5,0x91,0x00,0xff,0x91,0x81,0x71,0xfe,0x40,0x00,0x42,0x00,0x01,0x00,0xd1,0xd6}, + 17, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (05)"), {0x3b,0xf5,0x91,0x00,0xff,0x91,0x81,0x71,0xfe,0x40,0x00,0x42,0x00,0x01,0xb3,0xa1,0x15}, + 17, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + /* Japanese Individual Number Card (My Number Card), contactless interface. + * ATR constructed from ATQB by PC/SC part 3 compliant readers. + * Readers that include the (random) PUPI in the ATR cannot be matched. */ + {TEXT("JPKI (06)"), {0x3b,0x88,0x80,0x01,0x00,0x00,0x05,0xe0,0xb3,0x81,0xa1,0x00,0x7f}, + 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (07)"), {0x3b,0x88,0x80,0x01,0x00,0x00,0x41,0xe0,0xb3,0x81,0xa1,0x00,0x3b}, + 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (08)"), {0x3b,0x88,0x80,0x01,0x00,0x4b,0x51,0xff,0x00,0x81,0xd1,0x00,0xbc}, + 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + {TEXT("JPKI (09)"), {0x3b,0x88,0x80,0x01,0x00,0x4b,0x51,0xff,0xb3,0x81,0xd1,0x00,0x0f}, + 13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, /* from card-starcos.c */ {TEXT("STARCOS (a)"), {0x3B,0xB7,0x94,0x00,0xc0,0x24,0x31,0xfe,0x65,0x53,0x50,0x4b,0x32,0x33,0x90,0x00,0xb4}, From ce60e6a4d96766254e9716d68cba66823499fbd8 Mon Sep 17 00:00:00 2001 From: HAMANO Tsukasa Date: Thu, 23 Jul 2026 21:45:31 +0900 Subject: [PATCH 4321/4321] card-jpki: Use sc_file_free() to release virtual MF jpki_finish() released drvdata->mf with plain free(), but the file is created by sc_file_new() in jpki_init() and has five ACL entries attached via sc_file_add_acl_entry(). Plain free() releases only the top-level struct, leaking the ACL entries (and any *_attr allocations). Use sc_file_free(), which properly clears ACL entries and sub-allocations. It also handles NULL internally, so the explicit NULL check is dropped. --- src/libopensc/card-jpki.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 195c8e84c6..7a5e7f2ab1 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -83,9 +83,7 @@ jpki_finish(sc_card_t * card) LOG_FUNC_CALLED(card->ctx); if (drvdata) { - if (drvdata->mf) { - free(drvdata->mf); - } + sc_file_free(drvdata->mf); free(drvdata); card->drv_data = NULL; }


    Name

    opensc-explorer — generic interactive utility for accessing smart card and similar security token functions

    Synopsis

    opensc-explorer [OPTIONS] [SCRIPT]

    Description

    @@ -812,14 +812,14 @@ The following commands are supported:

    # - ... + ...

    Treat line as a comment. Ignore anything until the end of the line introduced by #.

    apdu - data... + data...

    Send a custom APDU command to the card. data is a series of @@ -872,7 +872,7 @@ DF-name.

    change - CHVpin-ref + CHVpin-ref [ [old-pin] new-pin @@ -951,7 +951,7 @@ in double quotes ("...").

    echo - string... + string...

    Print the strings given.

    @@ -1013,7 +1013,7 @@ List files in the current DF. If no pattern is given, then all files are listed. - If one ore more patterns are given, + If one or more patterns are given, only files matching at least one pattern are listed.

    @@ -1207,7 +1207,7 @@

    See also

    opensc-tool(1)

    Authors

    opensc-explorer was written by - Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications + Juha Yrjölä .


    Name

    opensc-notify — monitor smart card events and send notifications

    Synopsis

    opensc-notify [OPTIONS]

    Description

    The opensc-notify utility is used to monitor smart card events and send the appropriate notification. @@ -1324,7 +1324,7 @@

    See also

    opensc-explorer(1)

    Authors

    opensc-tool was written by - Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    + Juha Yrjölä .


    Name

    piv-tool — smart card utility for HSPD-12 PIV cards

    Synopsis

    piv-tool [OPTIONS]

    The piv-tool utility can be used from the command line to perform miscellaneous smart card operations on a HSPD-12 PIV smart card as defined in NIST 800-73-3. It is intended for use with test cards only. It can be used to load objects, and generate @@ -1442,16 +1442,16 @@ --hash-algorithm mechanism

    Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. - Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may also allow "SHA224". Default is "SHA-1". -

    +

    Note that the input to RSA-PKCS-PSS has to be of the size equal to the specified hash algorithm. E.g., for SHA256 the signature input must be exactly 32 bytes long (for mechanisms SHA256-RSA-PKCS-PSS there is no such restriction). For RSA-OAEP, the plaintext input size mLen must be at most keyLen - 2 - 2*hashLen. For example, for RSA 3072-bit key and SHA384, the longest plaintext to encrypt with RSA-OAEP is (with all - sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes. + sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes.

    --id id, -d id @@ -1633,7 +1633,7 @@ -y type

    Specify the type of object to operate on. Valid value are cert, privkey, - pubkey, secrkey + pubkey, secrkey and data.

    --verbose, -v

    Cause pkcs11-tool to be @@ -1802,7 +1802,7 @@ pkcs15-init(1), pkcs15-tool(1)

    Authors

    pkcs15-crypt was written by - Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    + Juha Yrjölä .


    Name

    pkcs15-init — smart card personalization utility

    Synopsis

    pkcs15-init [OPTIONS]

    Description

    The pkcs15-init utility can be used to create a PKCS #15 structure on a smart card, and add key or certificate objects. Details of the structure that will be created are controlled via profiles. @@ -2445,7 +2445,7 @@ pkcs15-init(1), pkcs15-crypt(1)

    Authors

    pkcs15-tool was written by - Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    + Juha Yrjölä .


    Name

    sc-hsm-tool — smart card utility for SmartCard-HSM

    Synopsis

    sc-hsm-tool [OPTIONS]

    The sc-hsm-tool utility can be used from the command line to perform extended maintenance tasks not available via PKCS#11 or other tools in the OpenSC package. It can be used to query the status of a SmartCard-HSM, initialize a device, generate and import @@ -2460,20 +2460,20 @@ -C filename

    Create a DKEK share encrypted under a password and save it to the file given as parameter.

    Use --password to provide a password for encryption rather than prompting for one.

    Use --pwd-shares-threshold and --pwd-shares-total to randomly generate a password and split is using a (t, n) threshold scheme.

    - --import-dkek-share filename, + --import-dkek-share filename, -I filename

    Prompt for user password, read and decrypt DKEK share and import into SmartCard-HSM.

    Use --password to provide a password for decryption rather than prompting for one.

    Use --pwd-shares-total to specify the number of shares that should be entered to reconstruct the password.

    - --wrap-key filename, + --wrap-key filename, -W filename

    Wrap the key referenced in --key-reference and save with it together with the key description and certificate to the given file.

    Use --pin to provide the user PIN on the command line.

    - --unwrap-key filename, + --unwrap-key filename, -U filename

    Read wrapped key, description and certificate from file and import into SmartCard-HSM under the key reference given in --key-reference.

    Determine the key reference using the output of pkcs15-tool -D.

    Use --pin to provide a user PIN on the command line.

    Use --force to remove any key, key description or certificate in the way.

    - --dkek-shares number-of-shares, + --dkek-shares number-of-shares, -s number-of-shares -

    Define the number of DKEK shares to use for recreating the DKEK.

    This is an optional parameter. Using --initialize without +

    Define the number of DKEK shares to use for recreating the DKEK.

    This is an optional parameter. Using --initialize without --dkek-shares will disable the DKEK completely.

    Using --dkek-shares with 0 shares requests the SmartCard-HSM to generate a random DKEK. Keys wrapped with this DKEK can only be unwrapped in the same SmartCard-HSM.

    After using --initialize with one or more DKEK shares, the From 45e3daacb2380f38b7d09b3cfd6ec1e3240e24fb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 17 Oct 2022 10:30:42 +0200 Subject: [PATCH 2584/4321] Reformat to UTF8 --- src/libopensc/card-belpic.c | 4 ++-- src/pkcs15init/pkcs15-oberthur.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 2ce5674577..c281f67b54 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -111,7 +111,7 @@ static long t1, t2, tot_read = 0, tot_dur = 0, dur; /* Data in the return value for the GET CARD DATA command: * All fields are one byte, except when noted otherwise. * - * See §6.9 in + * See §6.9 in * https://github.com/Fedict/eid-mw/blob/master/doc/sdk/documentation/Public_Belpic_Applet_v1%207_Ref_Manual%20-%20A01.pdf * for the full documentation on the GET CARD DATA command. */ @@ -195,7 +195,7 @@ static int get_carddata(sc_card_t *card, u8* carddata_loc, unsigned int carddata return r; } if(apdu.resplen < carddataloc_len) { - sc_log(card->ctx, + sc_log(card->ctx, "GetCardData: card returned %"SC_FORMAT_LEN_SIZE_T"u bytes rather than expected %d\n", apdu.resplen, carddataloc_len); return SC_ERROR_WRONG_LENGTH; diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 047683bf3c..9239541d07 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -1,7 +1,7 @@ /* * Oberthur specific operation for PKCS #15 initialization * - * Copyright (C) 2002 Juha Yrjölä + * Copyright (C) 2002 Juha Yrjölä * Copyright (C) 2009 Viktor Tarasov , * OpenTrust * @@ -277,7 +277,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 }; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(ctx, + sc_log(ctx, "pin lens %"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u", pin_len, puk_len); if (!pin || pin_len>0x40) @@ -533,7 +533,7 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, file->ef_structure = structure; } - sc_log(card->ctx, + sc_log(card->ctx, "cosm_new_file() file size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X", file->size, file->type, file->ef_structure, file->id); *out = file; From f0bd269251ff64dc2b260059254b1374a91b0c87 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 18 Oct 2022 09:41:57 +0200 Subject: [PATCH 2585/4321] pkcs11-tool: disable wrap/unwrap test until OpenSC issue #1796 is resolved --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8c2736a679..ccd5e7f450 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6652,7 +6652,7 @@ static int test_verify(CK_SESSION_HANDLE sess) return errors; } -#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 22 +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 23 #else #ifdef ENABLE_OPENSSL static int wrap_unwrap(CK_SESSION_HANDLE session, @@ -6776,7 +6776,7 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, */ static int test_unwrap(CK_SESSION_HANDLE sess) { -#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 22 +#if OPENSC_VERSION_MAJOR == 0 && OPENSC_VERSION_MINOR <= 23 /* temporarily disable test, see https://github.com/OpenSC/OpenSC/issues/1796 */ return 0; #else From 97feb205ccaf0552f542f82e5bdb90c96db83aeb Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 17 Oct 2022 09:27:07 +0300 Subject: [PATCH 2586/4321] Make code more readable Signed-off-by: Raul Metsma --- MacOSX/Distribution.xml.in | 40 +++++++--------------------- MacOSX/Distribution_universal.xml.in | 40 +++++++--------------------- 2 files changed, 20 insertions(+), 60 deletions(-) diff --git a/MacOSX/Distribution.xml.in b/MacOSX/Distribution.xml.in index fed08a1036..83874467be 100644 --- a/MacOSX/Distribution.xml.in +++ b/MacOSX/Distribution.xml.in @@ -1,6 +1,7 @@ @@ -12,36 +13,15 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D diff --git a/MacOSX/Distribution_universal.xml.in b/MacOSX/Distribution_universal.xml.in index f834088fe5..40ea3949e3 100644 --- a/MacOSX/Distribution_universal.xml.in +++ b/MacOSX/Distribution_universal.xml.in @@ -1,6 +1,7 @@ @@ -12,36 +13,15 @@ https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/D From e9f20c49eb94c05bae4b63d8e79b514dc0ffbc92 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 21 Jul 2022 13:56:24 +0200 Subject: [PATCH 2587/4321] Link libsm.la with -lcrypto Now it worked just because it was linked in the one existing usage? -> unittests/sm --- src/sm/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sm/Makefile.am b/src/sm/Makefile.am index 215013c1f2..80c12b97b8 100644 --- a/src/sm/Makefile.am +++ b/src/sm/Makefile.am @@ -20,6 +20,8 @@ AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src/include libsm_la_SOURCES = sm-common.c sm-common.h +libsm_la_LIBADD = $(OPENSSL_LIBS) +libsm_la_CFLAGS = $(OPENSSL_CFLAGS) libsmiso_la_SOURCES = sm-iso.c From 0b5f8130303e810e8291ecaed24646680777ab51 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Sun, 31 Jul 2022 11:54:03 +0200 Subject: [PATCH 2588/4321] libsmm-local: Remove redundant dependency --- src/smm/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smm/Makefile.am b/src/smm/Makefile.am index 09dcbd47ee..097f045f28 100644 --- a/src/smm/Makefile.am +++ b/src/smm/Makefile.am @@ -20,7 +20,7 @@ libsmm_local_la_SOURCES = smm-local.c sm-module.h \ sm-global-platform.c sm-cwa14890.c \ sm-card-authentic.c sm-card-iasecc.c \ smm-local.exports -libsmm_local_la_LIBADD = $(OPTIONAL_OPENSSL_LIBS) ../libopensc/libopensc.la +libsmm_local_la_LIBADD = $(OPTIONAL_OPENSSL_LIBS) libsmm_local_la_LDFLAGS = -module -shared -no-undefined -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@ # noinst_HEADERS = sm.h From deb1234fe1eb8f457eff5c923e28c9ed4a8d9430 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 7 Sep 2022 14:04:17 +0200 Subject: [PATCH 2589/4321] Remove -ldl from LIBS --- configure.ac | 18 +++++++++++++++--- src/common/Makefile.am | 1 + src/tests/p11test/Makefile.am | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 87f93a25e9..ae74dd9568 100644 --- a/configure.ac +++ b/configure.ac @@ -466,9 +466,20 @@ AC_CHECK_LIB( if test "${WIN32}" = "no"; then dnl dl support - AC_SEARCH_LIBS([dlopen], [dl dld], [], [ - AC_MSG_ERROR([unable to find the dlopen() function]) - ]) + AC_ARG_VAR([LDL_LIBS], [linker flags for ldl]) + if test -z "${LDL_LIBS}"; then + AC_CHECK_LIB( + [dl], + [dlopen], + [LDL_LIBS="-ldl"], + AC_CHECK_LIB( + [dld], + [dlopen], + [LDL_LIBS="-ldld"], + AC_MSG_ERROR([unable to find the dlopen() function]) + ) + ) + fi dnl Special check for pthread support. AX_PTHREAD( @@ -1209,6 +1220,7 @@ Compiler flags: ${CFLAGS} Linker flags: ${LDFLAGS} Libraries: ${LIBS} +LDL_LIBS: ${LDL_LIBS} READLINE_CFLAGS: ${READLINE_CFLAGS} READLINE_LIBS: ${READLINE_LIBS} ZLIB_CFLAGS: ${ZLIB_CFLAGS} diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 83a40e1c29..8171edd2fa 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -28,6 +28,7 @@ compat_getopt_main_LDADD = libcompat.la libpkcs11_la_SOURCES = libpkcs11.c libscdl_la_SOURCES = libscdl.c +libscdl_la_LIBADD = $(LDL_LIBS) TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) TIDY_FILES = \ diff --git a/src/tests/p11test/Makefile.am b/src/tests/p11test/Makefile.am index c88968ef94..f5300b22df 100644 --- a/src/tests/p11test/Makefile.am +++ b/src/tests/p11test/Makefile.am @@ -35,7 +35,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \ p11test_case_secret.c \ p11test_helpers.c p11test_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(CMOCKA_CFLAGS) -p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) +p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS) $(LDL_LIBS) if WIN32 p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc From 299dd6eea4312d552a474c6232fb7ef7a8cd6c5b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 30 Sep 2022 16:56:30 +0200 Subject: [PATCH 2590/4321] Remove PTHREAD_CFLAGS from libs of pkcs11-tool --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index fe61fcd40e..4d131c1e6c 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -60,7 +60,7 @@ pkcs11_tool_SOURCES = pkcs11-tool.c util.c pkcs11_tool_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) pkcs11_tool_LDADD = \ $(top_builddir)/src/common/libpkcs11.la \ - $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_CFLAGS) + $(OPTIONAL_OPENSSL_LIBS) if ENABLE_SHARED else pkcs11_tool_LDADD += \ From 7aedf9cad5f21e74e9afeaf43e08b016e3772a4c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 30 Sep 2022 17:02:42 +0200 Subject: [PATCH 2591/4321] Remove unneeded OPENSSL_CFLAGS Already in AM_CFLAGS --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 4d131c1e6c..2b18349c99 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -93,7 +93,7 @@ gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c npa-tool-cmdline.c npa_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la \ $(OPENPACE_LIBS) -npa_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) $(OPENSSL_CFLAGS) +npa_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) npa_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option From 97479e4df9952e3ec7122ff7d288e61499db9130 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Oct 2022 11:34:28 +0200 Subject: [PATCH 2592/4321] Remove redundant linking of opensc-asn1 to zlib --- src/tools/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 2b18349c99..e9d0f8451b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -124,8 +124,8 @@ goid_tool_CFLAGS += -Wno-unknown-warning-option endif opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c -opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) -opensc_asn1_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) +opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la +opensc_asn1_CFLAGS = -I$(top_srcdir)/src opensc_asn1_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION opensc_asn1_CFLAGS += -Wno-unknown-warning-option From 615ca1dbe58c5af7389eff323b282ab216ea212a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Oct 2022 11:38:39 +0200 Subject: [PATCH 2593/4321] Remove redundant preprocessor flag from CFLAGS Already in AM_CPPFLAGS --- src/tools/Makefile.am | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index e9d0f8451b..54b7d49c93 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -93,7 +93,7 @@ gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c npa-tool-cmdline.c npa_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la \ $(OPENPACE_LIBS) -npa_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) +npa_tool_CFLAGS = -$(OPENPACE_CFLAGS) npa_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option @@ -101,7 +101,7 @@ endif opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) -opensc_notify_CFLAGS = -I$(top_srcdir)/src $(PTHREAD_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) +opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) opensc_notify_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION opensc_notify_CFLAGS += -Wno-unknown-warning-option @@ -109,7 +109,7 @@ endif egk_tool_SOURCES = egk-tool.c util.c egk-tool-cmdline.c egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) -egk_tool_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_ZLIB_CFLAGS) +egk_tool_CFLAGS = $(OPTIONAL_ZLIB_CFLAGS) egk_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION egk_tool_CFLAGS += -Wno-unknown-warning-option @@ -117,7 +117,7 @@ endif goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c goid-tool-cmdline.c goid_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPENPACE_LIBS) -goid_tool_CFLAGS = -I$(top_srcdir)/src $(OPENPACE_CFLAGS) +goid_tool_CFLAGS = $(OPENPACE_CFLAGS) goid_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION goid_tool_CFLAGS += -Wno-unknown-warning-option @@ -125,15 +125,13 @@ endif opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la -opensc_asn1_CFLAGS = -I$(top_srcdir)/src -opensc_asn1_CFLAGS += -Wno-unused-but-set-variable +opensc_asn1_CFLAGS = -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION opensc_asn1_CFLAGS += -Wno-unknown-warning-option endif pkcs11_register_SOURCES = pkcs11-register.c fread_to_eof.c pkcs11-register-cmdline.c -pkcs11_register_CFLAGS = -I$(top_srcdir)/src -pkcs11_register_CFLAGS += -Wno-unused-but-set-variable -Wno-unused-function +pkcs11_register_CFLAGS = -Wno-unused-but-set-variable -Wno-unused-function pkcs11_register_LDADD = \ $(top_builddir)/src/common/libpkcs11.la if HAVE_UNKNOWN_WARNING_OPTION From f9944bd47365e1698eb8cc0627ad7e6ad3c56450 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Oct 2022 11:46:50 +0200 Subject: [PATCH 2594/4321] Remove libopensc.la from _LDADD As it is already in LIBS --- src/tools/Makefile.am | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 54b7d49c93..25f0a429af 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -91,16 +91,15 @@ gids_tool_SOURCES = gids-tool.c util.c gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c npa-tool-cmdline.c -npa_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la \ - $(OPENPACE_LIBS) -npa_tool_CFLAGS = -$(OPENPACE_CFLAGS) +npa_tool_LDADD = $(OPENPACE_LIBS) +npa_tool_CFLAGS = $(OPENPACE_CFLAGS) npa_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option endif opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c -opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS) +opensc_notify_LDADD = $(OPTIONAL_NOTIFY_LIBS) opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) opensc_notify_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION @@ -108,7 +107,7 @@ opensc_notify_CFLAGS += -Wno-unknown-warning-option endif egk_tool_SOURCES = egk-tool.c util.c egk-tool-cmdline.c -egk_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_ZLIB_LIBS) +egk_tool_LDADD = $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = $(OPTIONAL_ZLIB_CFLAGS) egk_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION @@ -116,7 +115,7 @@ egk_tool_CFLAGS += -Wno-unknown-warning-option endif goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c goid-tool-cmdline.c -goid_tool_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPENPACE_LIBS) +goid_tool_LDADD = $(OPENPACE_LIBS) goid_tool_CFLAGS = $(OPENPACE_CFLAGS) goid_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION @@ -124,7 +123,6 @@ goid_tool_CFLAGS += -Wno-unknown-warning-option endif opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c -opensc_asn1_LDADD = $(top_builddir)/src/libopensc/libopensc.la opensc_asn1_CFLAGS = -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION opensc_asn1_CFLAGS += -Wno-unknown-warning-option From cb7183c1049be9ae1612130fd8ed9260f1444bd1 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Oct 2022 16:36:01 +0200 Subject: [PATCH 2595/4321] Remove -pthread from tool CFLAGS --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 25f0a429af..b2c338e4a1 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -38,7 +38,7 @@ bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb -AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) $(PTHREAD_CFLAGS) +AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' -D'DEFAULT_ONEPIN_PKCS11_PROVIDER="$(DEFAULT_ONEPIN_PKCS11_PROVIDER)"' LIBS = \ $(top_builddir)/src/libopensc/libopensc.la \ From f43169a8d7dc9dc9df99c15bcec0c804b8efd856 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 3 Oct 2022 17:51:09 +0200 Subject: [PATCH 2596/4321] Remove redundant -lglib-2.0 library --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index ae74dd9568..b43808bdae 100644 --- a/configure.ac +++ b/configure.ac @@ -554,6 +554,10 @@ case "${host}" in have_notify="no" have_gio2="no" ]) LIBS="$saved_LIBS" + if test "${have_gio2}" = "yes"; then + # we do not need lglib-2.0 + GIO2_LIBS="-lgio-2.0 -lgobject-2.0" + fi ;; esac From 74768e5c6ab4d86a1cbf6a979f5796a9d9504c3e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 10 Oct 2022 11:42:39 +0200 Subject: [PATCH 2597/4321] Remove CFLAGS for unused variables and functions --- src/tools/Makefile.am | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index b2c338e4a1..ae1874c5bd 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -93,7 +93,6 @@ gids_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) npa_tool_SOURCES = npa-tool.c fread_to_eof.c util.c npa-tool-cmdline.c npa_tool_LDADD = $(OPENPACE_LIBS) npa_tool_CFLAGS = $(OPENPACE_CFLAGS) -npa_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION npa_tool_CFLAGS += -Wno-unknown-warning-option endif @@ -101,7 +100,6 @@ endif opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c opensc_notify_LDADD = $(OPTIONAL_NOTIFY_LIBS) opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) -opensc_notify_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION opensc_notify_CFLAGS += -Wno-unknown-warning-option endif @@ -109,7 +107,6 @@ endif egk_tool_SOURCES = egk-tool.c util.c egk-tool-cmdline.c egk_tool_LDADD = $(OPTIONAL_ZLIB_LIBS) egk_tool_CFLAGS = $(OPTIONAL_ZLIB_CFLAGS) -egk_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION egk_tool_CFLAGS += -Wno-unknown-warning-option endif @@ -117,23 +114,19 @@ endif goid_tool_SOURCES = goid-tool.c util.c fread_to_eof.c goid-tool-cmdline.c goid_tool_LDADD = $(OPENPACE_LIBS) goid_tool_CFLAGS = $(OPENPACE_CFLAGS) -goid_tool_CFLAGS += -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION goid_tool_CFLAGS += -Wno-unknown-warning-option endif opensc_asn1_SOURCES = opensc-asn1.c fread_to_eof.c opensc-asn1-cmdline.c -opensc_asn1_CFLAGS = -Wno-unused-but-set-variable if HAVE_UNKNOWN_WARNING_OPTION -opensc_asn1_CFLAGS += -Wno-unknown-warning-option +opensc_asn1_CFLAGS = -Wno-unknown-warning-option endif pkcs11_register_SOURCES = pkcs11-register.c fread_to_eof.c pkcs11-register-cmdline.c -pkcs11_register_CFLAGS = -Wno-unused-but-set-variable -Wno-unused-function -pkcs11_register_LDADD = \ - $(top_builddir)/src/common/libpkcs11.la +pkcs11_register_LDADD = $(top_builddir)/src/common/libpkcs11.la if HAVE_UNKNOWN_WARNING_OPTION -pkcs11_register_CFLAGS += -Wno-unknown-warning-option +pkcs11_register_CFLAGS = -Wno-unknown-warning-option endif .PHONY: cmdline From c17bd11bd4bd9c708c2b7ccf5db828d491bbefc0 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 10 Oct 2022 11:54:03 +0200 Subject: [PATCH 2598/4321] Remove linking to OPTIONAL_NOTIFY_LIBS As it is already linked to libnotify --- src/tools/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index ae1874c5bd..dcfd283317 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -98,8 +98,7 @@ npa_tool_CFLAGS += -Wno-unknown-warning-option endif opensc_notify_SOURCES = opensc-notify.c opensc-notify-cmdline.c -opensc_notify_LDADD = $(OPTIONAL_NOTIFY_LIBS) -opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) $(OPTIONAL_NOTIFY_CFLAGS) +opensc_notify_CFLAGS = $(PTHREAD_CFLAGS) if HAVE_UNKNOWN_WARNING_OPTION opensc_notify_CFLAGS += -Wno-unknown-warning-option endif From 0e315cea6112110fa618d366d9268787c4f9ae34 Mon Sep 17 00:00:00 2001 From: Eitot Date: Fri, 14 Oct 2022 11:41:42 +0200 Subject: [PATCH 2599/4321] macOS: Update workflow to include MacOSX/ directory --- .github/workflows/macos.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4a93d45212..be499ef461 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -12,8 +12,7 @@ on: - .github/build.sh - .github/push-artifacts.sh - '**.am' - - MacOSX/build-package.in - - 'MacOSX/Distribution*.xml.in' + - MacOSX/** push: jobs: From 4e2713e6210a9da3fda0a150cbc12d635ef9d3fa Mon Sep 17 00:00:00 2001 From: Eitot Date: Fri, 14 Oct 2022 11:41:50 +0200 Subject: [PATCH 2600/4321] macOS: Correct LaunchAgent paths in opensc-uninstall script This fixes an omission in e05574d94217e6fbd9186509a1b494fb30ee1431. The names of these files have changed, so they are not deregistered from LaunchServices and uninstalled when running the opensc-uninstall script. --- MacOSX/opensc-uninstall | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index 419a6011f9..a3e4f28f2e 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -32,13 +32,13 @@ rm -rf /Applications/Utilities/OpenSCTokenApp.app rm -rf "/Applications/Utilities/OpenSC Notify.app" rm -rf /Library/OpenSC rm -rf /Library/Security/tokend/OpenSC.tokend -rm -f /Library/LaunchAgents/pkcs11-register.plist -rm -f /Library/LaunchAgents/opensc-notify.plist +rm -f /Library/LaunchAgents/org.opensc-project.mac.pkcs11-register.plist +rm -f /Library/LaunchAgents/org.opensc-project.mac.opensc-notify.plist rm -rf /System/Library/Security/tokend/OpenSC.tokend # Unload launchagents -launchctl remove pkcs11-register -launchctl remove opensc-notify +launchctl remove org.opensc-project.mac.pkcs11-register +launchctl remove org.opensc-project.mac.opensc-notify # delete receipts on 10.6+ pkgutil --forget org.opensc-project.mac > /dev/null 2>/dev/null From aafe3c1db4aceef4c0da4e359b456771ededfb0b Mon Sep 17 00:00:00 2001 From: Eitot Date: Sat, 15 Oct 2022 15:43:43 +0200 Subject: [PATCH 2601/4321] macOS: Fix LaunchAgent removal in opensc-uninstall script `launchctl remove` is executed by the root user. This will not affect loaded LaunchAgents of the logged-in user. --- MacOSX/opensc-uninstall | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MacOSX/opensc-uninstall b/MacOSX/opensc-uninstall index a3e4f28f2e..317c919ece 100755 --- a/MacOSX/opensc-uninstall +++ b/MacOSX/opensc-uninstall @@ -36,9 +36,13 @@ rm -f /Library/LaunchAgents/org.opensc-project.mac.pkcs11-register.plist rm -f /Library/LaunchAgents/org.opensc-project.mac.opensc-notify.plist rm -rf /System/Library/Security/tokend/OpenSC.tokend -# Unload launchagents -launchctl remove org.opensc-project.mac.pkcs11-register -launchctl remove org.opensc-project.mac.opensc-notify +# Remove LaunchAgents +for label in \ + org.opensc-project.mac.pkcs11-register \ + org.opensc-project.mac.opensc-notify +do + launchctl asuser "$(id -u "${SUDO_USER:-$USER}")" launchctl remove "$label" +done # delete receipts on 10.6+ pkgutil --forget org.opensc-project.mac > /dev/null 2>/dev/null From 854f68c6fcdd1be5ee56672ae69e2266bcd9467a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 7 Oct 2022 09:53:02 +0200 Subject: [PATCH 2602/4321] Do not build npa-tool when OpenPACE is missing --- src/tools/Makefile.am | 5 ++++- src/tools/Makefile.mak | 2 +- src/tools/npa-tool.c | 11 ----------- win32/Make.rules.mak | 6 +++++- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index dcfd283317..12444ac49a 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -34,7 +34,10 @@ bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 goid-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ - westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool + westcos-tool sc-hsm-tool dnie-tool gids-tool +if ENABLE_OPENPACE +bin_PROGRAMS += npa-tool +endif endif # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index a42c5e3c2e..27021b8aab 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -7,7 +7,7 @@ default: all TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-tool.exe eidenv.exe openpgp-tool.exe iasecc-tool.exe \ opensc-notify.exe egk-tool.exe goid-tool.exe paccess-tool.exe opensc-asn1.exe \ - pkcs11-register.exe $(PROGRAMS_OPENSSL) + pkcs11-register.exe $(PROGRAMS_OPENSSL) $(PROGRAMS_OPENPACE) OBJECTS = util.obj versioninfo-tools.res diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 134d643438..34bb1a8779 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -21,7 +21,6 @@ #include "config.h" #endif -#ifdef ENABLE_OPENPACE #include "fread_to_eof.h" #include "npa-tool-cmdline.h" #include "sm/sm-eac.h" @@ -863,14 +862,4 @@ main (int argc, char **argv) return -r; } -#else - -#include -int -main (int argc, char **argv) -{ - fprintf(stderr, "OpenPACE is needed for npa-tool\n"); - return 1; -} -#endif diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index a55a3dce95..5948d9779a 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -81,7 +81,7 @@ OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\$(OPENSSL_STATIC_DIR)\libcrypto64MT.lib user !ENDIF PROGRAMS_OPENSSL = cryptoflex-tool.exe pkcs15-init.exe netkey-tool.exe piv-tool.exe \ - westcos-tool.exe sc-hsm-tool.exe dnie-tool.exe gids-tool.exe npa-tool.exe + westcos-tool.exe sc-hsm-tool.exe dnie-tool.exe gids-tool.exe OPENSC_FEATURES = $(OPENSC_FEATURES) openssl CANDLEFLAGS = -dOpenSSL="$(OPENSSL_DIR)" $(CANDLEFLAGS) !ENDIF @@ -126,6 +126,10 @@ OPENPACE_DIR = C:\openpace !ENDIF OPENPACE_INCL_DIR = /I$(OPENPACE_DIR)\src OPENPACE_LIB = $(OPENPACE_DIR)\src\libeac.lib +!IF "$(OPENSSL_DEF)" == "/DENABLE_OPENSSL" +# Build only when OpenPACE and OpenSSL are available +PROGRAMS_OPENPACE = npa-tool.exe +!ENDIF CANDLEFLAGS = -dOpenPACE="$(OPENPACE_DIR)" $(CANDLEFLAGS) !ENDIF From 8045aa37475917f4ce7ffd1180942282c6f298b9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 7 Oct 2022 15:30:10 +0200 Subject: [PATCH 2603/4321] Do not build sceac-example if OpenPACE is missing --- src/tools/Makefile.am | 5 ++++- src/tools/sceac-example.c | 9 +-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 12444ac49a..d2425214ce 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -28,7 +28,6 @@ noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h \ openpgp-tool-helpers.h -noinst_PROGRAMS = sceac-example bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 goid-tool @@ -40,6 +39,10 @@ bin_PROGRAMS += npa-tool endif endif +if ENABLE_OPENPACE +noinst_PROGRAMS = sceac-example +endif + # compile with $(PTHREAD_CFLAGS) to allow debugging with gdb AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPTIONAL_READLINE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/src -D'DEFAULT_PKCS11_PROVIDER="$(DEFAULT_PKCS11_PROVIDER)"' -D'DEFAULT_ONEPIN_PKCS11_PROVIDER="$(DEFAULT_ONEPIN_PKCS11_PROVIDER)"' diff --git a/src/tools/sceac-example.c b/src/tools/sceac-example.c index 15f1b526d6..f3875c184d 100644 --- a/src/tools/sceac-example.c +++ b/src/tools/sceac-example.c @@ -26,7 +26,6 @@ #include "config.h" #endif -#ifdef ENABLE_OPENPACE #include "libopensc/sm.h" #include "sm/sm-iso.h" #include "sm/sm-eac.h" @@ -134,10 +133,4 @@ main (int argc, char **argv) return -r; } -#else -int -main (int argc, char **argv) -{ - return 1; -} -#endif + From e9a2de55dc9fbfbe987709f0d54497ae40004daa Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 10 Oct 2022 16:31:50 +0200 Subject: [PATCH 2604/4321] Do not build opensc-notify when dependencies are missing --- configure.ac | 1 + src/tools/Makefile.am | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index b43808bdae..8d26a73405 100644 --- a/configure.ac +++ b/configure.ac @@ -1099,6 +1099,7 @@ AM_CONDITIONAL([ENABLE_ZLIB], [test "${enable_zlib}" = "yes"]) AM_CONDITIONAL([ENABLE_READLINE], [test "${enable_readline}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENSSL], [test "${enable_openssl}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENPACE], [test "${enable_openpace}" = "yes"]) +AM_CONDITIONAL([ENABLE_NOTIFY], [test "${enable_notify}" = "yes"]) AM_CONDITIONAL([ENABLE_CRYPTOTOKENKIT], [test "${enable_cryptotokenkit}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"]) AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"]) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index d2425214ce..1d6589225f 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -28,9 +28,9 @@ noinst_HEADERS = util.h fread_to_eof.h \ egk-tool-cmdline.h goid-tool-cmdline.h npa-tool-cmdline.h \ opensc-asn1-cmdline.h opensc-notify-cmdline.h pkcs11-register-cmdline.h \ openpgp-tool-helpers.h -bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \ +bin_PROGRAMS = opensc-tool opensc-explorer opensc-asn1 \ pkcs15-tool pkcs15-crypt pkcs11-tool pkcs11-register \ - cardos-tool eidenv openpgp-tool iasecc-tool egk-tool opensc-asn1 goid-tool + cardos-tool eidenv openpgp-tool iasecc-tool egk-tool goid-tool if ENABLE_OPENSSL bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \ westcos-tool sc-hsm-tool dnie-tool gids-tool @@ -39,6 +39,10 @@ bin_PROGRAMS += npa-tool endif endif +if ENABLE_NOTIFY +bin_PROGRAMS += opensc-notify +endif + if ENABLE_OPENPACE noinst_PROGRAMS = sceac-example endif From ec6d7b198d51c3c9f4b01fe7791137eded1a76b2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 14 Oct 2022 11:28:09 +0200 Subject: [PATCH 2605/4321] Skip checking of GIO2 on Windows --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8d26a73405..439b0967bf 100644 --- a/configure.ac +++ b/configure.ac @@ -530,7 +530,7 @@ if test "${enable_dnie_ui}" = "yes"; then fi case "${host}" in - *-*-darwin*) + *-*-darwin*|*-mingw*|*-winnt*|*-cygwin*) have_notify="yes" ;; *) From a82f7fac0af94b46abe83f11edf052390227ace8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 10 Oct 2022 17:29:27 +0200 Subject: [PATCH 2606/4321] Add srpm build --- .github/workflows/packit.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/packit.yaml diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml new file mode 100644 index 0000000000..d7037947ab --- /dev/null +++ b/.github/workflows/packit.yaml @@ -0,0 +1,24 @@ +name: Packit +on: + pull_request: + paths: + - '**.c' + - '**.h' + - '**.am' + push: + +jobs: + packit_srpm: + runs-on: ubuntu-latest + name: Packit SRPM + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: packit/actions/srpm@main + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: opensc-srpm + path: + opensc*.src.rpm From 1e46ef9cd581acdbbb624626f2cb2174a5e9f1cb Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 17 Oct 2022 11:30:11 +0200 Subject: [PATCH 2607/4321] Add RPM build --- .github/actions/packit/Dockerfile | 5 +++++ .github/actions/packit/action.yml | 5 +++++ .github/test-packit.sh | 8 ++++++++ .github/workflows/packit.yaml | 14 ++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 .github/actions/packit/Dockerfile create mode 100644 .github/actions/packit/action.yml create mode 100755 .github/test-packit.sh diff --git a/.github/actions/packit/Dockerfile b/.github/actions/packit/Dockerfile new file mode 100644 index 0000000000..540526545e --- /dev/null +++ b/.github/actions/packit/Dockerfile @@ -0,0 +1,5 @@ +FROM quay.io/packit/packit + +RUN git config --system --add safe.directory /github/workspace + +ENTRYPOINT ["./.github/test-packit.sh"] diff --git a/.github/actions/packit/action.yml b/.github/actions/packit/action.yml new file mode 100644 index 0000000000..a07eb40133 --- /dev/null +++ b/.github/actions/packit/action.yml @@ -0,0 +1,5 @@ +name: Packit RPM build +description: Action that provides Packit RPM build +runs: + using: "docker" + image: "Dockerfile" diff --git a/.github/test-packit.sh b/.github/test-packit.sh new file mode 100755 index 0000000000..07a8ff8e7b --- /dev/null +++ b/.github/test-packit.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Install build requirements +REQUIREMENTS=$(sed -n -e '/^BuildRequires*/p' packaging/opensc.spec | sed 's/[^ ]* //') +sudo dnf install -y ${REQUIREMENTS} + +# Run packit +packit --debug build locally diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index d7037947ab..29d95898bc 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -22,3 +22,17 @@ jobs: name: opensc-srpm path: opensc*.src.rpm + packit_rpm: + runs-on: ubuntu-latest + name: Packit RPM + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: ./.github/actions/packit + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: opensc-rpm + path: + x86_64/opensc*.rpm From 782e93e54dc250259f6db14eb7c459ee6996d09f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 24 Oct 2022 14:53:53 +0200 Subject: [PATCH 2608/4321] Trigger GH actions on packit.yaml --- .github/workflows/packit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index 29d95898bc..665af978d6 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -5,6 +5,7 @@ on: - '**.c' - '**.h' - '**.am' + - .github/workflows/packit.yaml push: jobs: From 7eb0ec34c87fee640d977fdc396feca3bbb30217 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 31 Oct 2022 10:46:43 +0100 Subject: [PATCH 2609/4321] rpm: Remove the opensc-notify --- packaging/opensc.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 6a4d45e929..6b45c24a07 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -117,7 +117,6 @@ rm -rf %{buildroot}%{_bindir}/pkcs11-register rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1* # Remove the notification files -rm %{buildroot}%{_bindir}/opensc-notify rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop rm %{buildroot}%{_mandir}/man1/opensc-notify.1* From 123accfab0fcb727f1c8414efdceea7ff0055361 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 14 Oct 2022 17:18:56 +0200 Subject: [PATCH 2610/4321] Run CI with Ubuntu 20.04 --- .github/workflows/linux.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 26860a6d3e..c5c4cae414 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -52,8 +52,8 @@ jobs: - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 - build-ubuntu-18: - runs-on: ubuntu-18.04 + build-ubuntu-20: + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - run: .github/setup-linux.sh @@ -62,14 +62,14 @@ jobs: uses: actions/upload-artifact@v2 if: failure() with: - name: ubuntu-18-test-logs + name: ubuntu-20-test-logs path: tests/*.log - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} + key: ${{ runner.os }}-20-${{ github.sha }} build-mingw: runs-on: ubuntu-latest @@ -98,54 +98,54 @@ jobs: win32/Output/OpenSC*.exe test-piv: - runs-on: ubuntu-18.04 - needs: [build-ubuntu-18] + runs-on: ubuntu-20.04 + needs: [build-ubuntu-20] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} + key: ${{ runner.os }}-20-${{ github.sha }} - run: .github/setup-linux.sh piv - run: .github/test-piv.sh test-isoapplet: - runs-on: ubuntu-18.04 - needs: [build-ubuntu-18] + runs-on: ubuntu-20.04 + needs: [build-ubuntu-20] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} + key: ${{ runner.os }}-20-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh test-gidsapplet: - runs-on: ubuntu-18.04 - needs: [build-ubuntu-18] + runs-on: ubuntu-20.04 + needs: [build-ubuntu-20] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} + key: ${{ runner.os }}-20-${{ github.sha }} - run: .github/setup-linux.sh gidsapplet - run: .github/test-gidsapplet.sh test-openpgp: - runs-on: ubuntu-18.04 - needs: [build-ubuntu-18] + runs-on: ubuntu-20.04 + needs: [build-ubuntu-20] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-18-${{ github.sha }} + key: ${{ runner.os }}-20-${{ github.sha }} - run: .github/setup-linux.sh openpgp - run: .github/test-openpgp.sh From 9661a9fb4e3bb2d47797379ada5f278975c7ddf6 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 21 Oct 2022 13:10:17 +0200 Subject: [PATCH 2611/4321] Run all test on ubuntu-latest --- .github/workflows/linux.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c5c4cae414..12bfb09f2c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -98,54 +98,54 @@ jobs: win32/Output/OpenSC*.exe test-piv: - runs-on: ubuntu-20.04 - needs: [build-ubuntu-20] + runs-on: ubuntu-latest + needs: [build] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-20-${{ github.sha }} + key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh piv - run: .github/test-piv.sh test-isoapplet: - runs-on: ubuntu-20.04 - needs: [build-ubuntu-20] + runs-on: ubuntu-latest + needs: [build] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-20-${{ github.sha }} + key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh test-gidsapplet: - runs-on: ubuntu-20.04 - needs: [build-ubuntu-20] + runs-on: ubuntu-latest + needs: [build] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-20-${{ github.sha }} + key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh gidsapplet - run: .github/test-gidsapplet.sh test-openpgp: - runs-on: ubuntu-20.04 - needs: [build-ubuntu-20] + runs-on: ubuntu-latest + needs: [build] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 id: cache-build with: path: ./* - key: ${{ runner.os }}-20-${{ github.sha }} + key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh openpgp - run: .github/test-openpgp.sh From 1d1f0c0a1c0a72604f8a571adffa0e147855052b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 21 Oct 2022 13:19:16 +0200 Subject: [PATCH 2612/4321] Run OpenSSL 3.0 tests on Ubuntu 22.04 --- .github/setup-linux.sh | 12 +------- .github/workflows/linux.yml | 60 +++++++++++++------------------------ 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index ea96030b6b..e137e00716 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -3,12 +3,7 @@ set -ex -o xtrace # Generic dependencies -DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd" - -# Add openssl or install openssl3.0 -if [ "$1" != "ossl3" -a "$2" != "ossl3" ]; then - DEPS="$DEPS openssl" -fi +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd openssl" # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then @@ -56,11 +51,6 @@ export DEBCONF_NONINTERACTIVE_SEEN=true sudo apt-get update sudo apt-get install -y build-essential $DEPS -# install openssl 3.0 if needed -if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - ./.github/setup-openssl.sh &> /tmp/openssl.log || cat /tmp/openssl.log -fi - # install libressl if needed if [ "$1" == "libressl" -o "$2" == "libressl" ]; then ./.github/setup-libressl.sh &> /tmp/libressl.log || cat /tmp/libressl.log diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 12bfb09f2c..7b2d3d95ce 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -52,25 +52,6 @@ jobs: - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 - build-ubuntu-20: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - run: .github/setup-linux.sh - - run: .github/build.sh - - name: Upload test logs - uses: actions/upload-artifact@v2 - if: failure() - with: - name: ubuntu-20-test-logs - path: - tests/*.log - - uses: actions/cache@v2 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-20-${{ github.sha }} - build-mingw: runs-on: ubuntu-latest steps: @@ -188,28 +169,27 @@ jobs: - run: .github/setup-linux.sh oseid - run: .github/test-oseid.sh - ########################## - ## OpenSSL 3.0 pipeline ## - ########################## - build-openssl-3: - runs-on: ubuntu-latest + ############################################ + ## Ubuntu 22.04 with OpenSSL 3.0 pipeline ## + ############################################ + build-ubuntu-22: + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - - run: .github/setup-linux.sh ossl3 - - run: .github/build.sh dist ossl3 + - run: .github/setup-linux.sh + - run: .github/build.sh dist - uses: actions/upload-artifact@v3 if: failure() with: - name: openssl-3-logs - path: | + name: ubuntu-22-test-logs + path: tests/*.log - config.log - uses: actions/cache@v2 id: cache-build if: ${{ success() }} with: path: ./* - key: ${{ runner.os }}-ossl3-${{ github.sha }} + key: ${{ runner.os }}-22-${{ github.sha }} - name: Upload artifacts uses: actions/upload-artifact@v2 if: ${{ success() }} @@ -218,30 +198,30 @@ jobs: path: opensc*.tar.gz - test-cac-openssl-3: - runs-on: ubuntu-latest - needs: [build-openssl-3] + test-cac-ubuntu-22: + runs-on: ubuntu-22.04 + needs: [build-ubuntu-22] steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 id: cache-build with: path: ./* - key: ${{ runner.os }}-ossl3-${{ github.sha }} - - run: .github/setup-linux.sh cac ossl3 + key: ${{ runner.os }}-22-${{ github.sha }} + - run: .github/setup-linux.sh cac - run: .github/test-cac.sh - test-oseid-openssl-3: - runs-on: ubuntu-latest - needs: [build-openssl-3] + test-oseid-ubuntu-22: + runs-on: ubuntu-22.04 + needs: [build-ubuntu-22] steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 id: cache-build with: path: ./* - key: ${{ runner.os }}-ossl3-${{ github.sha }} - - run: .github/setup-linux.sh oseid ossl3 + key: ${{ runner.os }}-22-${{ github.sha }} + - run: .github/setup-linux.sh oseid - run: .github/test-oseid.sh ####################### From d12eda0e5b99af45e41953f8019a419899648edc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 21 Oct 2022 13:22:58 +0200 Subject: [PATCH 2613/4321] Remove OpenSSL 3.0 setup scripts --- .github/build.sh | 12 ++---------- .github/setup-openssl.sh | 18 ------------------ 2 files changed, 2 insertions(+), 28 deletions(-) delete mode 100755 .github/setup-openssl.sh diff --git a/.github/build.sh b/.github/build.sh index 3fc887768a..c1fd2df7ff 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -2,11 +2,7 @@ set -ex -o xtrace -if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig; -else - export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; -fi +export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') @@ -61,11 +57,7 @@ fi # this is broken in old ubuntu if [ "$1" == "dist" ]; then - if [ "$1" == "ossl3" -o "$2" == "ossl3" ]; then - make distcheck DISTCHECK_CONFIGURE_FLAGS="--disable-strict CFLAGS=\"-Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing=2\"" - else - make distcheck - fi + make distcheck make dist fi diff --git a/.github/setup-openssl.sh b/.github/setup-openssl.sh deleted file mode 100755 index c37ebc9f34..0000000000 --- a/.github/setup-openssl.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -set -ex -o xtrace - -sudo apt-get remove -y libssl-dev - -if [ ! -d "openssl" ]; then - git clone --single-branch --branch=openssl-3.0 --depth 1 https://github.com/openssl/openssl -fi -pushd openssl -./Configure --prefix=/usr/local linux-x86_64 -make -j $(nproc) -sudo make install -popd - -# update dynamic linker to find the libraries in non-standard path -echo "/usr/local/lib64" | sudo tee /etc/ld.so.conf.d/openssl.conf -sudo ldconfig From a2cc2d14727b47f33888e001a7fb0d59fca26662 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 24 Oct 2022 15:04:22 +0200 Subject: [PATCH 2614/4321] Remove containers with OpenSSL3 --- containers/opensc-build-ossl3/Containerfile | 12 ------------ containers/opensc-test-cac-ossl3/Containerfile | 13 ------------- containers/opensc-test-oseid-ossl3/Containerfile | 13 ------------- 3 files changed, 38 deletions(-) delete mode 100644 containers/opensc-build-ossl3/Containerfile delete mode 100644 containers/opensc-test-cac-ossl3/Containerfile delete mode 100644 containers/opensc-test-oseid-ossl3/Containerfile diff --git a/containers/opensc-build-ossl3/Containerfile b/containers/opensc-build-ossl3/Containerfile deleted file mode 100644 index a71e79df8e..0000000000 --- a/containers/opensc-build-ossl3/Containerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM ubuntu:latest -RUN apt update -# Install sudo to mimic Github Actions runnner -# Install tzdata to avoid messing up with interactive prompts later -RUN export DEBIAN_FRONTEND=noninteractive; \ - export DEBCONF_NONINTERACTIVE_SEEN=true; \ - echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ - echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ - apt-get install -y --no-install-recommends tzdata sudo -WORKDIR /src -RUN /src/.github/setup-linux.sh ossl3 -CMD /src/.github/build.sh dist ossl3 diff --git a/containers/opensc-test-cac-ossl3/Containerfile b/containers/opensc-test-cac-ossl3/Containerfile deleted file mode 100644 index 47fc47ffd0..0000000000 --- a/containers/opensc-test-cac-ossl3/Containerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ubuntu:latest -RUN apt update -# Install sudo to mimic Github Actions runnner -# Install tzdata to avoid messing up with interactive prompts later -RUN export DEBIAN_FRONTEND=noninteractive; \ - export DEBCONF_NONINTERACTIVE_SEEN=true; \ - echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ - echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ - apt-get install -y --no-install-recommends tzdata sudo -WORKDIR /src -RUN /src/.github/setup-linux.sh cac ossl3 -RUN /src/.github/build.sh ossl3 -CMD /src/.github/test-cac.sh diff --git a/containers/opensc-test-oseid-ossl3/Containerfile b/containers/opensc-test-oseid-ossl3/Containerfile deleted file mode 100644 index 6dbbd3b161..0000000000 --- a/containers/opensc-test-oseid-ossl3/Containerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ubuntu:latest -RUN apt update -# Install sudo to mimic Github Actions runnner -# Install tzdata to avoid messing up with interactive prompts later -RUN export DEBIAN_FRONTEND=noninteractive; \ - export DEBCONF_NONINTERACTIVE_SEEN=true; \ - echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ - echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ - apt-get install -y --no-install-recommends tzdata sudo -WORKDIR /src -RUN /src/.github/setup-linux.sh oseid ossl3 -RUN /src/.github/build.sh ossl3 -CMD /src/.github/test-oseid.sh From cb8f78ce5e9cc3e5ecc47163c3ec89f6c8e4a203 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Tue, 25 Oct 2022 11:40:13 +0200 Subject: [PATCH 2615/4321] Run build job on Ubuntu 20.04 --- .github/workflows/linux.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7b2d3d95ce..e99cc256e7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -14,7 +14,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - run: .github/setup-linux.sh @@ -79,7 +79,7 @@ jobs: win32/Output/OpenSC*.exe test-piv: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -92,7 +92,7 @@ jobs: - run: .github/test-piv.sh test-isoapplet: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -105,7 +105,7 @@ jobs: - run: .github/test-isoapplet.sh test-gidsapplet: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -118,7 +118,7 @@ jobs: - run: .github/test-gidsapplet.sh test-openpgp: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -131,7 +131,7 @@ jobs: - run: .github/test-openpgp.sh build-clang-tidy: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -144,7 +144,7 @@ jobs: - run: .github/build.sh test-cac: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 @@ -157,7 +157,7 @@ jobs: - run: .github/test-cac.sh test-oseid: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: [build] steps: - uses: actions/checkout@v2 From 97dc5997a20e51331982d767774382898e4549f2 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Tue, 1 Nov 2022 17:03:31 +0100 Subject: [PATCH 2616/4321] Make certificationAuthorityReference optional (Fixes #2634) --- src/libopensc/pkcs15-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 17a1a204a3..25a1fb4823 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -181,7 +181,7 @@ static const struct sc_asn1_entry c_asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE] = { #define C_ASN1_CVC_BODY_SIZE 5 static const struct sc_asn1_entry c_asn1_cvc_body[C_ASN1_CVC_BODY_SIZE] = { { "certificateProfileIdentifier", SC_ASN1_INTEGER, SC_ASN1_APP | 0x1F29, 0, NULL, NULL }, - { "certificationAuthorityReference", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 2, 0, NULL, NULL }, + { "certificationAuthorityReference", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 2, SC_ASN1_OPTIONAL, NULL, NULL }, { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F49, 0, NULL, NULL }, { "certificateHolderReference", SC_ASN1_PRINTABLESTRING, SC_ASN1_APP | 0x1F20, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } From a48d7cbbcbc4b0ab7b567b82a0d8c797d5744318 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 4 Nov 2022 01:39:52 +0200 Subject: [PATCH 2617/4321] build: harden codespell.yml permissions Signed-off-by: Alex --- .github/workflows/codespell.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 20debc29b0..e10dcf1b75 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -5,6 +5,9 @@ on: pull_request: push: +permissions: + contents: read # to fetch code (actions/checkout) + jobs: codespell: name: Check for spelling errors From 298879ac97a4227fdb2ab20b1d264473575bf4dc Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 4 Nov 2022 01:40:13 +0200 Subject: [PATCH 2618/4321] build: harden coverity.yml permissions Signed-off-by: Alex --- .github/workflows/coverity.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index f56805a447..caf6b262a5 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -6,6 +6,9 @@ on: branches: [master, coverity] +permissions: + contents: read # to fetch code (actions/checkout) + jobs: build: runs-on: ubuntu-latest From a3063dee49e9afa29aae1068588676bd490c94f3 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 4 Nov 2022 01:41:11 +0200 Subject: [PATCH 2619/4321] build: harden macos.yml permissions Signed-off-by: Alex --- .github/workflows/macos.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index be499ef461..7843e8b9fe 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -15,6 +15,9 @@ on: - MacOSX/** push: +permissions: + contents: read # to fetch code (actions/checkout) + jobs: build: runs-on: macos-latest From 2e2c683327787d39e41e8ec7aa09bfbbf3508829 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 4 Nov 2022 01:42:12 +0200 Subject: [PATCH 2620/4321] build: harden linux.yml permissions Signed-off-by: Alex --- .github/workflows/linux.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index e99cc256e7..81250febec 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,6 +12,9 @@ on: - '**.am' push: +permissions: + contents: read # to fetch code (actions/checkout) + jobs: build: runs-on: ubuntu-20.04 From 80ec11f8e6a73ba644e1348b0f27e20747aef9e0 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 26 Oct 2022 14:42:45 -0500 Subject: [PATCH 2621/4321] customactions.cpp - fix atrs before adding to registry Include a fix for #2625 OpenSC definitions of ATRs have been lax in "sc_atr_table" entries by allowing 1 bits in the ATR that need to be 0 bits when used with Windows compare Do the equivalent reduction of the table ATR done in card.c by "tbin[s] = (tbin[s] & mbin[s]);" before adding to registry. This will then allow lax definitions of ATRs to be copied to customactions.cpp and fixed before adding to registry. Changes to be committed: modified: win32/customactions.cpp --- win32/customactions.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index c6afe04dc3..c332949bef 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -130,6 +130,9 @@ MD_REGISTRATION minidriver_registration[] = { /* from card-cardos.c */ {TEXT("CardOS 4.0"), {0x3b,0xe2,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0xc8,0x02,0x9c}, 12, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, + /* note: */ + {TEXT("CardOS 4.2+"), {0x3b,0xf2,0x08,0x00,0x00,0xc1,0x00,0x31,0xfe,0x00,0x00,0x00,0x00}, + 13, {0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0x00,0x00}}, {TEXT("Italian CNS (a)"), {0x3b,0xe9,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x00,0xc8,0x02,0x31,0x80,0x00,0x47}, 19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}}, {TEXT("Italian CNS (b)"), {0x3b,0xfb,0x98,0x00,0xff,0xc1,0x10,0x31,0xfe,0x55,0x00,0x64,0x05,0x20,0x47,0x03,0x31,0x80,0x00,0x90,0x00,0xf3}, @@ -321,6 +324,8 @@ VOID RegisterSmartCard(PMD_REGISTRATION registration) { DWORD expanded_len = PATH_MAX; TCHAR expanded_val[PATH_MAX]; + BYTE pbAtrReduced[256]; + DWORD i; PTSTR szPath = TEXT("C:\\Program Files\\OpenSC Project\\OpenSC\\minidriver\\opensc-minidriver.dll"); /* cope with x86 installation on x64 */ @@ -330,7 +335,17 @@ VOID RegisterSmartCard(PMD_REGISTRATION registration) if (0 < expanded_len && expanded_len < sizeof expanded_val) szPath = expanded_val; - RegisterCardWithKey(SC_DATABASE, registration->szName, szPath, registration->pbAtr, registration->dwAtrSize, registration->pbAtrMask ); + /* + * OpenSC definitions of ATR have been lax in "sc_atr_table" entries by allowing + * 1 bits in the ATR that need to be 0 bits when used with Windows compare + * Do the equivalent reduction of the table ATR done in card.c by "tbin[s] = (tbin[s] & mbin[s]);" + * before adding to registry. + */ + for (i = 0; i < registration->dwAtrSize; i++) { + pbAtrReduced[i] = (registration->pbAtr[i] & registration->pbAtrMask[i]); + } + + RegisterCardWithKey(SC_DATABASE, registration->szName, szPath, pbAtrReduced, registration->dwAtrSize, registration->pbAtrMask ); } UINT WINAPI AddSmartCardConfiguration(MSIHANDLE hInstall) From f8ad86cd7df9ddeee1fbd528225d99344a1c431d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 9 Nov 2022 10:49:13 +0100 Subject: [PATCH 2622/4321] OpenSC 0.23.0-rc2 --- NEWS | 5 ++++- configure.ac | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 94f4b2ae0a..d5ae93c931 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.23.0; 2022-10-11 +# New in 0.23.0; 2022-11-09 ## General improvements * Support signing of data with a length of more than 512 bytes (#2314) * By default, disable support for old card drivers (#2391) and remove support for old drivers MioCOS and JCOP (#2374) @@ -19,6 +19,8 @@ NEWS for OpenSC -- History of user visible changes * Stop building support for Gost algorithms with OpenSSL 3.0 as they require deprecated API (#2586) * Fix detection of disconnected readers in PCSC (#2600) * Add configuration option for on-disk caching of private data (#2588) +* Skip building empty binaries when dependencies are missing and remove needless linking (#2617) +* Define arm64 as a supported architecture in the Installer package (#2610) ## PKCS#11 * Implement `C_CreateObject` for EC keys and fix signature verification for `CKM_ECDSA_SHAx` cards (#2420) ## pkcs11-tool @@ -35,6 +37,7 @@ NEWS for OpenSC -- History of user visible changes * Fix reinit of the card (#2525) * Add an entry for Italian CNS (e) (#2548) * Fix detection of ECC mechanisms (#2523) +* Fix ATRs before adding them to the windows registry (#2628) ## NQ-Applet * Add support for the JCOP4 Cards with NQ-Applet (#2425) ## ItaCNS diff --git a/configure.ac b/configure.ac index 439b0967bf..2b9a3f0f5e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [23]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc1]) +define([PACKAGE_SUFFIX], [-rc2]) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) From f12c766309bcaa4ca1321835938e4dc85ac9535f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 15 Jan 2022 23:01:20 +0100 Subject: [PATCH 2623/4321] itacns: simplify ATR matching ... and modify internal data only during initialization --- src/libopensc/card-itacns.c | 135 ++++++++---------------------------- 1 file changed, 30 insertions(+), 105 deletions(-) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index b26f9d3317..fe1be5b330 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -57,138 +57,58 @@ static const struct sc_atr_table itacns_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL} }; -/* Output debug info */ -#define matchdebug(idx, c) do { \ - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, \ - "Matching %x against atr[%d] == %x", c, idx, atr[idx]); \ - } while(0); - -/* Check that we are not looking at values beyond the ATR's length. - * If we are, then the card does not match. */ -#define itacns_atr_l(idx) do {if (idx >= card->atr.len) return 0;} while(0); - -/* Match byte exactly and increment index. */ -#define itacns_atr_match(idx, c) do { \ - itacns_atr_l(idx); \ - matchdebug(idx, c); \ - if (((u8)atr[idx]) != c) return 0; \ - idx++; \ - } while(0); - -/* Match masked bits and increment index. */ -#define itacns_atr_mmatch(idx, c, mask) do { \ - itacns_atr_l(idx); \ - if ((((u8)atr[idx]) & mask) != c) return 0; \ - idx ++; \ - } while(0); - /* Macro to access private driver data. */ #define DRVDATA(card) ((itacns_drv_data_t *) card->drv_data) - -static int itacns_match_cns_card(sc_card_t *card, unsigned int i) +static void itacns_init_cns_card(sc_card_t *card) { - unsigned char *atr = card->atr.value; - sc_context_t *ctx; - ctx = card->ctx; - + if (15 != card->reader->atr_info.hist_bytes_len) + return; - itacns_atr_match(i, 0x01); /* H7 */ - i += 2; /* H8, H9 */ - itacns_atr_match(i, 'C'); /* H10 */ - itacns_atr_match(i, 'N'); /* H11 */ - itacns_atr_match(i, 'S'); /* H12 */ - - /* H13 */ - /* Version byte: h.l, h in the high nibble, l in the low nibble. */ - if(card->driver) { - DRVDATA(card)->cns_version = atr[i]; - } /* Warn if version is not 1.X. */ - if(atr[i] != 0x10 && atr[i] != 0x11) { + u8 cns_version = card->reader->atr_info.hist_bytes[12]; + if(cns_version != 0x10 && cns_version != 0x11) { char version[8]; - snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); + snprintf(version, sizeof(version), "%d.%d", (cns_version >> 4) & 0x0f, cns_version & 0x0f); sc_log(card->ctx, "CNS card version %s; no official specifications " - "are published. Proceeding anyway.\n", version); + "are published. Proceeding anyway.\n", version); } - i++; + DRVDATA(card)->cns_version = cns_version; +} - itacns_atr_match(i, 0x31); /* H14 */ - itacns_atr_match(i, 0x80); /* H15 */ +static int itacns_match_cns_card(sc_card_t *card) +{ + if (15 != card->reader->atr_info.hist_bytes_len || + 0 != memcmp(card->reader->atr_info.hist_bytes+9, "CNS", 3)) + return 0; card->type = SC_CARD_TYPE_ITACNS_CNS; return 1; } -static int itacns_match_cie_card(sc_card_t *card, unsigned int i) +static int itacns_match_cie_card(sc_card_t *card) { - unsigned char *atr = card->atr.value; - sc_context_t *ctx; - ctx = card->ctx; - - itacns_atr_match(i, 0x02); /* H7 */ - itacns_atr_match(i, 'I'); /* H8 */ - itacns_atr_match(i, 'T'); /* H9 */ - itacns_atr_match(i, 'I'); /* H10 */ - itacns_atr_match(i, 'D'); /* H11 */ - itacns_atr_match(i, 0x20); /* H12 */ - itacns_atr_match(i, 0x20); /* H13 */ - itacns_atr_match(i, 0x31); /* H14 */ - itacns_atr_match(i, 0x80); /* H15 */ + u8 h7_to_h15[] = { 0x02, 'I', 'T', 'I', 'D', 0x20, 0x20, 0x31, 0x80, }; + if (15 != card->reader->atr_info.hist_bytes_len || + 0 != memcmp(card->reader->atr_info.hist_bytes+6, + h7_to_h15, sizeof h7_to_h15)) + return 0; card->type = SC_CARD_TYPE_ITACNS_CIE_V2; - return 1; } static int itacns_match_card(sc_card_t *card) { - unsigned int i = 0; - int r; - unsigned char *atr = card->atr.value; - int td1_idx; - sc_context_t *ctx; - ctx = card->ctx; + int r = 0; /* Try table first */ r = _sc_match_atr(card, itacns_atrs, &card->type); if(r >= 0) return 1; - /* The ATR was not recognized; try to match it - according to the official specs. */ - - /* Check ATR up to byte H6 */ - itacns_atr_match(i, 0x3b); /* TS */ - itacns_atr_mmatch(i, 0x8f, 0x8f); /* T0 */ - /* TA1, TB1, TC1 */ - if(atr[1] & 0x40) i++; - if(atr[1] & 0x20) i++; - if(atr[1] & 0x10) i++; - /* TD1 */ - td1_idx = i; - itacns_atr_mmatch(i, 0x81, 0x8f); - /* TA2, TB2, TC2 */ - if(atr[td1_idx] & 0x40) i++; - if(atr[td1_idx] & 0x20) i++; - if(atr[td1_idx] & 0x10) i++; - /* TD2 */ - itacns_atr_match(i, 0x31); - i += 2; /* TA3, TB3 */ - itacns_atr_match(i, 0x00); /* H1 */ - itacns_atr_match(i, 0x6b); /* H2 */ - /* Store interesting data */ - if(card->driver) { - DRVDATA(card)->ic_manufacturer_code = card->atr.value[i]; - DRVDATA(card)->mask_manufacturer_code = card->atr.value[i+1]; - DRVDATA(card)->os_version_h = card->atr.value[i+2]; - DRVDATA(card)->os_version_l = card->atr.value[i+3]; - } - i += 4; /* H3, H4, H5, H6 */ - - /* Check final part. */ - if (itacns_match_cns_card(card, i)) return 1; - if (itacns_match_cie_card(card, i)) return 1; + if (itacns_match_cns_card(card)) return 1; + if (itacns_match_cie_card(card)) return 1; /* No card type was matched. */ return 0; @@ -211,8 +131,13 @@ static int itacns_init(sc_card_t *card) if (!card->drv_data) return SC_ERROR_OUT_OF_MEMORY; - /* Match ATR again to find the card data. */ - itacns_match_card(card); + if (card->type == SC_CARD_TYPE_ITACNS_CNS) + itacns_init_cns_card(card); + + DRVDATA(card)->ic_manufacturer_code = card->reader->atr_info.hist_bytes[2]; + DRVDATA(card)->mask_manufacturer_code = card->reader->atr_info.hist_bytes[3]; + DRVDATA(card)->os_version_h = card->reader->atr_info.hist_bytes[4]; + DRVDATA(card)->os_version_l = card->reader->atr_info.hist_bytes[5]; /* Set up algorithm info. */ flags = SC_ALGORITHM_NEED_USAGE From 0ab6233d0c051624c0d91e41347e352ea0a19201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 12 Jan 2022 04:10:54 +0100 Subject: [PATCH 2624/4321] card-itacns: Use generic card fields to store hw and fw versions There's no need to use custom values, while in this way we can expose such information to the card users --- src/libopensc/card-itacns.c | 16 +++++++++------- src/libopensc/itacns.h | 3 --- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index fe1be5b330..71267d83e8 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -65,15 +65,17 @@ static void itacns_init_cns_card(sc_card_t *card) if (15 != card->reader->atr_info.hist_bytes_len) return; - /* Warn if version is not 1.X. */ u8 cns_version = card->reader->atr_info.hist_bytes[12]; - if(cns_version != 0x10 && cns_version != 0x11) { + card->version.hw_major = (cns_version >> 4) & 0x0f; + card->version.hw_minor = cns_version & 0x0f; + + /* Warn if version is not 1.X. */ + if (cns_version != 0x10 && cns_version != 0x11) { char version[8]; - snprintf(version, sizeof(version), "%d.%d", (cns_version >> 4) & 0x0f, cns_version & 0x0f); + snprintf(version, sizeof(version), "%d.%d", card->version.hw_major, card->version.hw_minor); sc_log(card->ctx, "CNS card version %s; no official specifications " "are published. Proceeding anyway.\n", version); } - DRVDATA(card)->cns_version = cns_version; } static int itacns_match_cns_card(sc_card_t *card) @@ -136,8 +138,8 @@ static int itacns_init(sc_card_t *card) DRVDATA(card)->ic_manufacturer_code = card->reader->atr_info.hist_bytes[2]; DRVDATA(card)->mask_manufacturer_code = card->reader->atr_info.hist_bytes[3]; - DRVDATA(card)->os_version_h = card->reader->atr_info.hist_bytes[4]; - DRVDATA(card)->os_version_l = card->reader->atr_info.hist_bytes[5]; + card->version.fw_major = card->reader->atr_info.hist_bytes[4]; + card->version.fw_minor = card->reader->atr_info.hist_bytes[5]; /* Set up algorithm info. */ flags = SC_ALGORITHM_NEED_USAGE @@ -147,7 +149,7 @@ static int itacns_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); - if (DRVDATA(card)->cns_version == 0x11) { + if (card->version.hw_major >= 1 && card->version.hw_minor >= 1) { card->caps |= SC_CARD_CAP_APDU_EXT; _sc_card_add_rsa_alg(card, 2048, flags, 0); } diff --git a/src/libopensc/itacns.h b/src/libopensc/itacns.h index 742627b45b..4b0a5a33f3 100644 --- a/src/libopensc/itacns.h +++ b/src/libopensc/itacns.h @@ -4,9 +4,6 @@ typedef struct { u8 ic_manufacturer_code; u8 mask_manufacturer_code; - u8 os_version_h; - u8 os_version_l; - u8 cns_version; } itacns_drv_data_t; #define ITACNS_MASKMAN_SIEMENS 0x08 From cff00cadf40d312bf1b6063d8b237c6638b8280c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 12 Jan 2022 03:10:06 +0100 Subject: [PATCH 2625/4321] pkcs15-itacns: Update mask manufacturers to match last definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gemalto was added in the last reference of CNS – Carta Nazionale dei Servizi Functional Specification [1], while Oberthur is now named IDEMIA. [1] https://www.agid.gov.it/sites/default/files/repository_files/documentazione_trasparenza/cns_functional_specification_1.1.6_02042011.pdf --- src/libopensc/pkcs15-itacns.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 5563f5cb27..2f337e4e8b 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -62,14 +62,15 @@ const char * itacns_mask_manufacturers[] = { "Gemplus", "Ghirlanda", "Giesecke & Devrient", - "Oberthur Card Systems", + "IDEMIA (Oberthur)", "Orga", "Axalto", "Siemens", "STIncard", "GEP", "EPS Corp", - "Athena" + "Athena", + "Gemalto", }; const char * iso7816_ic_manufacturers[] = { From 5115785acace52bb4e98ade69258b823aa209d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 12 Jan 2022 03:16:38 +0100 Subject: [PATCH 2626/4321] pkcs15-itacns: Only add x509 certificate if it is a valid one In case a card has some contents in the fetched path, but that's not an X.509 certificate, we're accepting it anyways until it's actually going to be used, and so will be listed as an available object. Instead ensure whether this is valid through openssl before adding it. --- src/libopensc/pkcs15-itacns.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 2f337e4e8b..fddd10a32d 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -222,11 +222,6 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, info.path = *path; strlcpy(obj.label, label, sizeof(obj.label)); - obj.flags = obj_flags; - - r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); - LOG_TEST_RET(p15card->card->ctx, r, - "Could not add X.509 certificate"); /* If we have OpenSSL, read keyUsage */ #ifdef ENABLE_OPENSSL @@ -255,14 +250,14 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, } OPENSSL_free(x509); - return SC_SUCCESS; - -#else /* ENABLE_OPENSSL */ - - return SC_SUCCESS; - #endif /* ENABLE_OPENSSL */ + obj.flags = obj_flags; + r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); + LOG_TEST_RET(p15card->card->ctx, r, + "Could not add X.509 certificate"); + + return r; } static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, From 3365f3a09a77bd95fe781431d6adb7314f7b9e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Sat, 15 Jan 2022 00:03:31 +0100 Subject: [PATCH 2627/4321] card-itacns: Support creating random numbers in smaller chunks Some cards can generate very small random numbers, so perform the action multiple times to get up to the requested value. This is handled by OpenSC, when the returned size is just less than expected. --- src/libopensc/card-itacns.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 71267d83e8..dd555a102e 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -471,6 +471,15 @@ itacns_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return SC_ERROR_NOT_SUPPORTED; } +static int +itacns_get_challenge(sc_card_t *card, u8 *rnd, size_t len) +{ + if (card->type == SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021) + len = MIN (0x20, len); + + return default_ops->get_challenge(card, rnd, len); +} + static struct sc_card_driver * sc_get_driver(void) { if (!default_ops) @@ -486,6 +495,7 @@ static struct sc_card_driver * sc_get_driver(void) itacns_ops.list_files = itacns_list_files; itacns_ops.select_file = itacns_select_file; itacns_ops.card_ctl = itacns_card_ctl; + itacns_ops.get_challenge = itacns_get_challenge; return &itacns_drv; } From a4eed9597729d7d73f7b17a9264b05ae40b78606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 12 Jan 2022 03:47:07 +0100 Subject: [PATCH 2628/4321] itacns: Add support for 2021 Idemia CNS cards New Idemia / Oberthur cards have been provided to people and they use a slightly different protocol, as per the reverse engineering of the new protocol, I've adapted the missing bits. Main key points: - Certificate path is 140090012002 - Public key path is 11001102 - The certificate has a size of 2048 - Private key path is 14009002 - The random number generator can only provide up to 32 bytes, so we just request multiple chunks in case a bigger number is requested. Also, official driver uses chained APDU commands to handle signing operations, however the card also supports extended APDU, so we can just use that instead of using chained commands (that would require some adjustments on the main library) Fixes: #2445 --- src/libopensc/card-itacns.c | 21 ++++++++++++++++++--- src/libopensc/cards.h | 1 + src/libopensc/itacns.h | 3 +++ src/libopensc/pkcs15-itacns.c | 8 ++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index dd555a102e..bb044ca725 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -80,12 +80,26 @@ static void itacns_init_cns_card(sc_card_t *card) static int itacns_match_cns_card(sc_card_t *card) { + u8 manufacturer_code; + u8 manufacturer_mask; + u8 fw_major; + if (15 != card->reader->atr_info.hist_bytes_len || 0 != memcmp(card->reader->atr_info.hist_bytes+9, "CNS", 3)) return 0; card->type = SC_CARD_TYPE_ITACNS_CNS; + manufacturer_code = card->reader->atr_info.hist_bytes[2]; + manufacturer_mask = card->reader->atr_info.hist_bytes[3]; + fw_major = card->reader->atr_info.hist_bytes[4]; + + if (manufacturer_code == ITACNS_ICMAN_INFINEON && + manufacturer_mask == ITACNS_MASKMAN_IDEMIA && + fw_major >= 32) { + card->type = SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021; + } + return 1; } @@ -147,11 +161,12 @@ static int itacns_init(sc_card_t *card) | SC_ALGORITHM_RSA_HASHES ; - _sc_card_add_rsa_alg(card, 1024, flags, 0); - - if (card->version.hw_major >= 1 && card->version.hw_minor >= 1) { + if ((card->version.hw_major >= 1 && card->version.hw_minor >= 1) || + card->type == SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021) { card->caps |= SC_CARD_CAP_APDU_EXT; _sc_card_add_rsa_alg(card, 2048, flags, 0); + } else { + _sc_card_add_rsa_alg(card, 1024, flags, 0); } return SC_SUCCESS; } diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 3e3f8dd268..5e65b8b2e9 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -184,6 +184,7 @@ enum { SC_CARD_TYPE_ITACNS_BASE = 23000, SC_CARD_TYPE_ITACNS_GENERIC, SC_CARD_TYPE_ITACNS_CNS, + SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021, SC_CARD_TYPE_ITACNS_CIE_V2, SC_CARD_TYPE_ITACNS_CIE_V1, diff --git a/src/libopensc/itacns.h b/src/libopensc/itacns.h index 4b0a5a33f3..8c5aed0edb 100644 --- a/src/libopensc/itacns.h +++ b/src/libopensc/itacns.h @@ -6,6 +6,9 @@ typedef struct { u8 mask_manufacturer_code; } itacns_drv_data_t; +#define ITACNS_ICMAN_INFINEON 0x05 + +#define ITACNS_MASKMAN_IDEMIA 0x05 #define ITACNS_MASKMAN_SIEMENS 0x08 #define ITACNS_MASKMAN_STINCARD 0x09 diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index fddd10a32d..c32df51446 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -852,6 +852,14 @@ static int itacns_init(sc_pkcs15_card_t *p15card) "Could not add CNS1"); certificate_count += found_certs; + /* Idemia card */ + r = itacns_check_and_add_keyset(p15card, "CNS1", 0x02, + 0, "3F00140090012002", "3F0011001102", "3F0014009002", + 0x10, &found_certs); + LOG_TEST_RET(p15card->card->ctx, r, + "Could not add CNS1"); + certificate_count += found_certs; + /* Did we find anything? */ if (certificate_count == 0) sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, From 1708c065f1ff2f754e9756de69ab3a3139a255bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 12 Jan 2022 17:58:39 +0100 Subject: [PATCH 2629/4321] card-itacns: Add NFC ATR for Idemia CNS When using the card with a NFC reader the ATR is different, so we need to use hard matching. --- src/libopensc/card-itacns.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index bb044ca725..68548f1abb 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -54,6 +54,9 @@ static struct sc_card_driver itacns_drv = { static const struct sc_atr_table itacns_atrs[] = { { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL, SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL}, + { "3b:8b:80:01:00:31:c1:64:00:00:00:00:00:00:00:00", + "ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00", + "Idemia (Oberthur)", SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021, 0, NULL}, { NULL, NULL, NULL, 0, 0, NULL} }; From 659aeea5a4673b2daafcd1627d29210c47c7d9fe Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 8 Nov 2022 12:07:40 +0000 Subject: [PATCH 2630/4321] Create .codeql.yml --- .github/.codeql.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/.codeql.yml diff --git a/.github/.codeql.yml b/.github/.codeql.yml new file mode 100644 index 0000000000..49d36ddd8a --- /dev/null +++ b/.github/.codeql.yml @@ -0,0 +1,13 @@ +name: "CodeQL configuration file" + +paths: + - tests/ + - src/tests/ +paths-ignore: + - 'src/tools/*-cmdline.*' + +query-filters: + - exclude: + # This reports all the uses of the DES, but this is needed for + # interoperability with cards not supporting AES + id: cpp/weak-cryptographic-algorithm From 93628426f64989c95bd83acd766831529c658ac5 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 8 Nov 2022 12:08:11 +0000 Subject: [PATCH 2631/4321] Create codeql.yml --- .github/workflows/codeql.yml | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..8be0a3af35 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,44 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '30 16 * * 0' + +permissions: {} +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/.codeql.yml + + - run: .github/setup-linux.sh + - run: .github/build.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From c06587ac6520acffa256f4f2cce1d1d7f4032096 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 8 Nov 2022 12:08:34 +0000 Subject: [PATCH 2632/4321] Delete .lgtm.yml --- .lgtm.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .lgtm.yml diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 676cc5cc2f..0000000000 --- a/.lgtm.yml +++ /dev/null @@ -1,15 +0,0 @@ -path_classifiers: - test: - - tests/ - - src/tests/ - generated: - - "src/tools/*-cmdline.*" -queries: - # This reports all the uses of the DES, but this is needed for - # interoperability with cards not supporting AES - - exclude: cpp/weak-cryptographic-algorithm -extraction: - javascript: - index: - filters: - exclude: **/ From a52786bcd9016b231b34faea33e5eef73fc56e16 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 8 Nov 2022 12:17:54 +0000 Subject: [PATCH 2633/4321] Update .codeql.yml --- .github/.codeql.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/.codeql.yml b/.github/.codeql.yml index 49d36ddd8a..48b40e2728 100644 --- a/.github/.codeql.yml +++ b/.github/.codeql.yml @@ -1,10 +1,11 @@ name: "CodeQL configuration file" paths: - - tests/ - - src/tests/ + - src/ paths-ignore: - 'src/tools/*-cmdline.*' + - src/tests/ + - tests/ query-filters: - exclude: From 32db85d0669f562c18503960730f3dedb132f6dd Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 9 Nov 2022 17:40:37 +0000 Subject: [PATCH 2634/4321] Replace lgtm.com badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 31b781d944..c19bf028dc 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Nightly builds are available by their git hash in branches of [OpenSC/Nightly](h [![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml) [![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026) -[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp) +[![CodeQL](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml/badge.svg?event=push)](https://github.com/OpenSC/OpenSC/actions/workflows/codeql.yml) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opensc.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:opensc) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3908/badge)](https://bestpractices.coreinfrastructure.org/projects/3908) From 2ea0fe49e8354f6f571a0762755f263f4ea05dce Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 28 Oct 2022 10:30:56 +0200 Subject: [PATCH 2635/4321] feat(pkcs11-tool): print serial number when reading certificates --- src/tools/pkcs11-tool.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index ccd5e7f450..4e0dce2ad4 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -683,6 +683,7 @@ VARATTR_METHOD(OBJECT_ID, unsigned char); /* getOBJECT_ID */ VARATTR_METHOD(MODULUS, CK_BYTE); /* getMODULUS */ #ifdef ENABLE_OPENSSL VARATTR_METHOD(SUBJECT, unsigned char); /* getSUBJECT */ +VARATTR_METHOD(SERIAL_NUMBER, unsigned char); /* getSERIAL_NUMBER */ VARATTR_METHOD(PUBLIC_EXPONENT, CK_BYTE); /* getPUBLIC_EXPONENT */ #endif VARATTR_METHOD(VALUE, unsigned char); /* getVALUE */ @@ -5177,6 +5178,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) char *label; #if defined(ENABLE_OPENSSL) unsigned char *subject; + unsigned char *serial_number; #endif /* ENABLE_OPENSSL */ printf("Certificate Object; type = "); @@ -5216,6 +5218,21 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) } free(subject); } + if ((serial_number = getSERIAL_NUMBER(sess, obj, &size)) != NULL) { + ASN1_INTEGER* serial = NULL; + const unsigned char *tmp = serial_number; + serial = d2i_ASN1_INTEGER(NULL, &tmp, size); + if (serial) { + BIO *bio = BIO_new(BIO_s_file()); + BIO_set_fp(bio, stdout, BIO_NOCLOSE); + BIO_printf(bio, " serial: "); + i2a_ASN1_INTEGER(bio, serial); + BIO_printf(bio, "\n"); + BIO_free(bio); + ASN1_INTEGER_free(serial); + } + free(serial_number); + } #endif /* ENABLE_OPENSSL */ if ((id = getID(sess, obj, &size)) != NULL && size) { From e6593b237eea851072e0d545795ee23ec0b4b524 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 3 Nov 2022 10:21:47 +0100 Subject: [PATCH 2636/4321] Check buffer size before dereferencing Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52662 --- src/libopensc/card-authentic.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index f0ee675719..563210d8e6 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -152,9 +152,9 @@ authentic_update_blob(struct sc_context *ctx, unsigned tag, unsigned char *data, static int -authentic_parse_size(unsigned char *in, size_t *out) +authentic_parse_size(unsigned char *in, size_t in_len, size_t *out) { - if (!in || !out) + if (!in || !out || in_len < 1) return SC_ERROR_INVALID_ARGUMENTS; if (*in < 0x80) { @@ -162,10 +162,14 @@ authentic_parse_size(unsigned char *in, size_t *out) return 1; } else if (*in == 0x81) { + if (in_len < 2) + return SC_ERROR_INVALID_DATA; *out = *(in + 1); return 2; } else if (*in == 0x82) { + if (in_len < 3) + return SC_ERROR_INVALID_DATA; *out = *(in + 1) * 0x100 + *(in + 2); return 3; } @@ -194,10 +198,16 @@ authentic_get_tagged_data(struct sc_context *ctx, unsigned char *in, size_t in_l tag_len = 1; } - size_len = authentic_parse_size(in + offs + tag_len, &size); + if (offs + tag_len >= in_len) + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "parse error: invalid data"); + + size_len = authentic_parse_size(in + offs + tag_len, in_len - (offs + tag_len), &size); LOG_TEST_RET(ctx, size_len, "parse error: invalid size data"); if (tag == in_tag) { + if (offs + tag_len + size_len >= in_len) + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "parse error: invalid data"); + *out = in + offs + tag_len + size_len; *out_len = size; From 2e5ead9d2e3776bd8c7e24ccf1695d062f7c3d14 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 3 Nov 2022 10:55:48 +0100 Subject: [PATCH 2637/4321] Free files in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52466 --- src/pkcs15init/pkcs15-iasecc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index ed4e09830f..84cdb0fe8e 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1777,43 +1777,43 @@ iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof } while(0); rv = iasecc_file_convert_acls(ctx, profile, file); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot convert profile ACLs"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot convert profile ACLs"); rv = sc_profile_get_parent(profile, "public-data", &parent); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot get object parent"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot get object parent"); sc_log(ctx, "iasecc_store_data_object() parent path '%s'\n", sc_print_path(&parent->path)); rv = sc_select_file(card, &parent->path, NULL); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot select parent"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot select parent"); rv = sc_select_file(card, &file->path, &cfile); if (!rv) { rv = sc_pkcs15init_authenticate(profile, p15card, cfile, SC_AC_OP_DELETE); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() DELETE authentication failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() DELETE authentication failed"); rv = iasecc_pkcs15_delete_file(p15card, profile, cfile); - LOG_TEST_RET(ctx, rv, "s_pkcs15init_store_data_object() delete pkcs15 file error"); + LOG_TEST_GOTO_ERR(ctx, rv, "s_pkcs15init_store_data_object() delete pkcs15 file error"); } else if (rv != SC_ERROR_FILE_NOT_FOUND) { LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() select file error"); } rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() parent CREATE authentication failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() parent CREATE authentication failed"); file->size = data->len; rv = sc_create_file(card, file); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot create DATA file"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot create DATA file"); rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() data file UPDATE authentication failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() data file UPDATE authentication failed"); rv = sc_update_binary(card, 0, data->value, data->len, 0); - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() update DATA file failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() update DATA file failed"); if (path) *path = file->path; - +err: sc_file_free(parent); sc_file_free(file); sc_file_free(cfile); From 4ac3539c3794c050001e38e23df6c51db8bfeb9b Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 3 Nov 2022 16:00:54 +0100 Subject: [PATCH 2638/4321] Free ASN.1 entry when object not found Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50483 --- src/libopensc/asn1.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index df1f1c8fa7..fc75d74949 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1679,6 +1679,38 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, return 0; } +static void sc_free_entry(struct sc_asn1_entry *asn1) { + int idx = 0; + struct sc_asn1_entry *entry = asn1; + + if (!asn1) + return; + + for (idx = 0; asn1[idx].name != NULL; idx++) { + entry = &asn1[idx]; + switch (entry->type) { + case SC_ASN1_CHOICE: + case SC_ASN1_STRUCT: + sc_free_entry((struct sc_asn1_entry *) entry->parm); + break; + case SC_ASN1_OCTET_STRING: + case SC_ASN1_BIT_STRING_NI: + case SC_ASN1_BIT_STRING: + case SC_ASN1_GENERALIZEDTIME: + case SC_ASN1_PRINTABLESTRING: + case SC_ASN1_UTF8STRING: + if ((entry->flags & SC_ASN1_ALLOC) && (entry->flags & SC_ASN1_PRESENT)) { + u8 **buf = (u8 **)entry->parm; + free(*buf); + *buf = NULL; + } + break; + default: + break; + } + } +} + static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, const u8 *in, size_t len, const u8 **newp, size_t *len_left, int choice, int depth) @@ -1745,6 +1777,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, } sc_debug(ctx, SC_LOG_DEBUG_ASN1, "next tag: %s\n", line); } + sc_free_entry(asn1); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND); } r = asn1_decode_entry(ctx, entry, obj, objlen, depth); From c8a5a5f938cadb6847bd42b6c7f1d5accd35f1a9 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 3 Nov 2022 17:25:54 +0100 Subject: [PATCH 2639/4321] Add check for cycles in macro expansion When expanding macros, macro references might have a loop, such as `a=$b b=$a`, which would not be detected. Calling `check_macro_reference_loop` get starting macro and tries to find the reference loop by checking the chain of the following references. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=50331 --- src/pkcs15init/profile.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 33a141c943..b1a4de6798 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1975,6 +1975,19 @@ static struct block root_ops = { "root", process_block, NULL, root_blocks }; +static int +check_macro_reference_loop(scconf_list *start, scconf_list *current, struct state *cur) { + sc_macro_t *mac = NULL; + const char *str = current->data; + if (str[0] != '$') + return 0; + if (!(mac = find_macro(cur->profile, str + 1))) + return 0; + if (!strcmp(mac->name, start->data + 1)) + return 1; + return check_macro_reference_loop(start, mac->value, cur); +} + static int build_argv(struct state *cur, const char *cmdname, scconf_list *list, char **argv, unsigned int max) @@ -2006,6 +2019,9 @@ build_argv(struct state *cur, const char *cmdname, if (list == mac->value) { return SC_ERROR_SYNTAX_ERROR; } + if (check_macro_reference_loop(list, mac->value, cur)) { + return SC_ERROR_SYNTAX_ERROR; + } #ifdef DEBUG_PROFILE { scconf_list *list; From c5feda3715adb6072b538fbc3d3f1592728ac4c0 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 4 Nov 2022 14:41:10 +0100 Subject: [PATCH 2640/4321] Limit number of opening brackets in expression to avoid stack overflow Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=46778 --- src/pkcs15init/profile.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index b1a4de6798..101ff2c62b 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2369,7 +2369,7 @@ struct num_exp_ctx { char ** argv; }; -static void expr_eval(struct num_exp_ctx *, unsigned int *, unsigned int); +static void expr_eval(struct num_exp_ctx *, unsigned int *, unsigned int, int); static void expr_fail(struct num_exp_ctx *ctx) @@ -2457,14 +2457,19 @@ expr_expect(struct num_exp_ctx *ctx, int c) expr_fail(ctx); } +#define MAX_BRACKETS 32 static void -expr_term(struct num_exp_ctx *ctx, unsigned int *vp) +expr_term(struct num_exp_ctx *ctx, unsigned int *vp, int opening_brackets) { char *tok; tok = expr_get(ctx); if (*tok == '(') { - expr_eval(ctx, vp, 1); + if (opening_brackets + 1 > MAX_BRACKETS) { + parse_error(ctx->state, "Too many \"%s\" in expression", tok); + expr_fail(ctx); + } + expr_eval(ctx, vp, 1, opening_brackets + 1); expr_expect(ctx, ')'); } else if (isdigit((unsigned char)*tok)) { @@ -2492,12 +2497,12 @@ expr_term(struct num_exp_ctx *ctx, unsigned int *vp) } static void -expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri) +expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri, int opening_brackets) { unsigned int left, right, new_pri; char *tok, op; - expr_term(ctx, &left); + expr_term(ctx, &left, opening_brackets); while (1) { tok = __expr_get(ctx, 1); @@ -2534,7 +2539,7 @@ expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri) } pri = new_pri; - expr_eval(ctx, &right, new_pri + 1); + expr_eval(ctx, &right, new_pri + 1, opening_brackets); switch (op) { case '*': left *= right; break; case '/': @@ -2567,7 +2572,7 @@ get_uint_eval(struct state *cur, int argc, char **argv, unsigned int *vp) return SC_ERROR_SYNTAX_ERROR; } - expr_eval(&ctx, vp, 0); + expr_eval(&ctx, vp, 0, 0); if (ctx.str[0] || ctx.argc) expr_fail(&ctx); From e4cbf6a412f97c0770f612c0cd6a49ae2062204d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 4 Nov 2022 15:51:03 +0100 Subject: [PATCH 2641/4321] Check valid PIN reference Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52991 --- src/pkcs15init/pkcs15-setcos.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 56bc5bdece..52b234fa2f 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -181,10 +181,13 @@ setcos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* sc_pkcs15init_create_pin() starts checking if -1 is an acceptable * pin reference, which isn't for the SetCOS cards. And since the * value 1 has been assigned to the SO pin, we'll jump to 2. */ - else if (auth_info->attrs.pin.reference <= 0) + else if (auth_info->attrs.pin.reference <= 0) { + if (auth_info_prof.attrs.pin.reference != 1) + return SC_ERROR_INVALID_PIN_REFERENCE; auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference + 1; + } - return 0; + return SC_SUCCESS; } /* From efd4eff7f9934134e404ffc12445da997cde6b11 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 7 Nov 2022 15:10:49 +0100 Subject: [PATCH 2642/4321] Fix memory leak when freeing filesystem When freeing blobs with pgp_iterate_blobs(), blobs in the tree with a height higher than the given level will not be released. Since blobs should form a tree without cycles, counting levels can be omitted. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52671 --- src/libopensc/card-openpgp.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 5ec4463756..261873f25a 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -129,7 +129,7 @@ static pgp_ec_curves_t ec_curves_gnuk[] = { static int pgp_get_card_features(sc_card_t *card); static int pgp_finish(sc_card_t *card); -static void pgp_iterate_blobs(pgp_blob_t *, int, void (*func)()); +static void pgp_iterate_blobs(pgp_blob_t *, void (*func)()); static int pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, unsigned int id, pgp_blob_t **ret); @@ -947,7 +947,7 @@ pgp_finish(sc_card_t *card) if (priv != NULL) { /* delete fake file hierarchy */ - pgp_iterate_blobs(priv->mf, 99, pgp_free_blob); + pgp_iterate_blobs(priv->mf, pgp_free_blob); /* delete private data */ free(priv); @@ -1150,18 +1150,16 @@ pgp_free_blob(pgp_blob_t *blob) * Internal: iterate through the blob tree, calling a function for each blob. */ static void -pgp_iterate_blobs(pgp_blob_t *blob, int level, void (*func)()) +pgp_iterate_blobs(pgp_blob_t *blob, void (*func)()) { if (blob) { - if (level > 0) { - pgp_blob_t *child = blob->files; + pgp_blob_t *child = blob->files; - while (child != NULL) { - pgp_blob_t *next = child->next; + while (child != NULL) { + pgp_blob_t *next = child->next; - pgp_iterate_blobs(child, level-1, func); - child = next; - } + pgp_iterate_blobs(child, func); + child = next; } func(blob); } @@ -1226,6 +1224,7 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) { const u8 *in; int r; + sc_file_t *file = NULL; if (blob->files != NULL) return SC_SUCCESS; @@ -1282,9 +1281,15 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) /* create fake file system hierarchy by * using constructed DOs as DF */ - if ((new = pgp_new_blob(card, blob, tag, sc_file_new())) == NULL) + file = sc_file_new(); + if ((new = pgp_new_blob(card, blob, tag, file)) == NULL) { + sc_file_free(file); return SC_ERROR_OUT_OF_MEMORY; - pgp_set_blob(new, data, len); + } + if (pgp_set_blob(new, data, len) != SC_SUCCESS) { + sc_file_free(file); + return SC_ERROR_OUT_OF_MEMORY; + } in = data + len; } From d18c85add229dd79d65b2a8989cf2e366d7df388 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 7 Nov 2022 16:09:53 +0100 Subject: [PATCH 2643/4321] Check file size before allocation Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53090 --- src/pkcs15init/pkcs15-entersafe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 44f2f9e3c0..07fdd57f68 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -130,6 +130,8 @@ static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) /* fill file by 0 */ + if (size > MAX_FILE_SIZE) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "Initialize EF(DIR) failed with file size too large"); buff = calloc(1,size); if(!buff) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS); From a6eecaa30fc0323967bbd4d82093a45c7ef2d422 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 7 Nov 2022 17:24:51 +0100 Subject: [PATCH 2644/4321] Check arguments --- src/pkcs15init/profile.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 101ff2c62b..b8b3ddbd08 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1978,7 +1978,12 @@ static struct block root_ops = { static int check_macro_reference_loop(scconf_list *start, scconf_list *current, struct state *cur) { sc_macro_t *mac = NULL; - const char *str = current->data; + const char *str = NULL; + + if (!start || !current || !cur) + return 0; + + str = current->data; if (str[0] != '$') return 0; if (!(mac = find_macro(cur->profile, str + 1))) From 1e776994b9bfdabfb102fe81fa82b4d26b3a6de9 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 28 Oct 2022 11:23:39 +0200 Subject: [PATCH 2645/4321] feat(pkcs11-tool): add new --undestroyable option to specify that a CKO_CERTIFICATE is not destroyable --- doc/tools/pkcs11-tool.1.xml | 15 +++++++++++---- doc/tools/tools.html | 2 ++ src/pkcs11/pkcs11.h | 1 + src/tools/pkcs11-tool.c | 15 +++++++++++++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 97ec5d673f..e05065e6c8 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -78,17 +78,17 @@ Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption. - Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may + Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may also allow "SHA224". Default is "SHA-1". - + Note that the input to RSA-PKCS-PSS has to be of the size equal to the specified hash algorithm. E.g., for SHA256 the signature input must be exactly 32 bytes long (for mechanisms SHA256-RSA-PKCS-PSS there is no such restriction). For RSA-OAEP, the plaintext input size mLen must be at most keyLen - 2 - 2*hashLen. For example, for RSA 3072-bit key and SHA384, the longest plaintext to encrypt with RSA-OAEP is (with all - sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes. + sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes. @@ -355,6 +355,13 @@ Set the CKA_EXTRACTABLE attribute (object can be extracted) + + + + + Set the CKA_DESTROYABLE attribute to false (object cannot be destroyed) + + id, @@ -566,7 +573,7 @@ Specify the type of object to operate on. Valid value are cert, privkey, - pubkey, secrkey + pubkey, secrkey and data. diff --git a/doc/tools/tools.html b/doc/tools/tools.html index 1dd92c0a7c..63d2c6a3f5 100644 --- a/doc/tools/tools.html +++ b/doc/tools/tools.html @@ -1557,6 +1557,8 @@

    Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext).

    --extractable

    Set the CKA_EXTRACTABLE attribute (object can be extracted)

    + --undestroyable +

    Set the CKA_DESTROYABLE attribute to false (object cannot be destroyed)

    --set-id id, -e id

    Set the CKA_ID of the object.

    diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 1ea46d3c74..e298038f79 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -450,6 +450,7 @@ typedef unsigned long ck_attribute_type_t; #define CKA_ALWAYS_SENSITIVE (0x165UL) #define CKA_KEY_GEN_MECHANISM (0x166UL) #define CKA_MODIFIABLE (0x170UL) +#define CKA_DESTROYABLE (0x172UL) #define CKA_ECDSA_PARAMS (0x180UL) #define CKA_EC_PARAMS (0x180UL) #define CKA_EC_POINT (0x181UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4e0dce2ad4..726cb7b60d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -167,6 +167,7 @@ enum { OPT_PRIVATE, OPT_SENSITIVE, OPT_EXTRACTABLE, + OPT_UNDESTROYABLE, OPT_TEST_HOTPLUG, OPT_UNLOCK_PIN, OPT_PUK, @@ -272,6 +273,7 @@ static const struct option options[] = { { "private", 0, NULL, OPT_PRIVATE }, { "sensitive", 0, NULL, OPT_SENSITIVE }, { "extractable", 0, NULL, OPT_EXTRACTABLE }, + { "undestroyable", 0, NULL, OPT_UNDESTROYABLE }, { "always-auth", 0, NULL, OPT_ALWAYS_AUTH }, { "test-ec", 0, NULL, OPT_TEST_EC }, #ifndef _WIN32 @@ -359,6 +361,7 @@ static const char *option_help[] = { "Set the CKA_PRIVATE attribute (object is only viewable after a login)", "Set the CKA_SENSITIVE attribute (object cannot be revealed in plaintext)", "Set the CKA_EXTRACTABLE attribute (object can be extracted)", + "Set the CKA_DESTROYABLE attribute to false (object cannot be destroyed)", "Set the CKA_ALWAYS_AUTHENTICATE attribute to a key object (require PIN verification for each use)", "Test EC (best used with the --login or --pin option)", #ifndef _WIN32 @@ -413,6 +416,7 @@ static size_t opt_allowed_mechanisms_len = 0; static int opt_is_private = 0; static int opt_is_sensitive = 0; static int opt_is_extractable = 0; +static int opt_is_destroyable = 1; static int opt_test_hotplug = 0; static int opt_login_type = -1; static int opt_key_usage_sign = 0; @@ -1043,6 +1047,9 @@ int main(int argc, char * argv[]) case OPT_EXTRACTABLE: opt_is_extractable = 1; break; + case OPT_UNDESTROYABLE: + opt_is_destroyable = 0; + break; case OPT_TEST_HOTPLUG: opt_test_hotplug = 1; action_count++; @@ -4005,6 +4012,10 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(cert_templ[n_cert_attr], CKA_ID, opt_object_id, opt_object_id_len); n_cert_attr++; } + if (opt_is_destroyable == 0) { + FILL_ATTR(cert_templ[n_cert_attr], CKA_DESTROYABLE, &_false, sizeof(_false)); + n_cert_attr++; + } #ifdef ENABLE_OPENSSL /* according to PKCS #11 CKA_SUBJECT MUST be specified */ FILL_ATTR(cert_templ[n_cert_attr], CKA_SUBJECT, cert.subject, cert.subject_len); @@ -6082,7 +6093,7 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv return NULL; } OSSL_PARAM_BLD_free(bld); - + if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { @@ -8154,7 +8165,7 @@ static struct mech_info p11_mgf[] = { { CKG_MGF1_SHA3_256, "MGF1-SHA3_256", NULL, MF_MGF }, { CKG_MGF1_SHA3_384, "MGF1-SHA3_384", NULL, MF_MGF }, { CKG_MGF1_SHA3_512, "MGF1-SHA3_512", NULL, MF_MGF }, - + { 0, NULL, NULL, MF_UNKNOWN } }; From f547dbee126ab749783bf968972fa03597eea0b8 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Thu, 3 Nov 2022 10:13:01 +0100 Subject: [PATCH 2646/4321] feat(pkcs11-tool): add CKM_SHA3_XXX_HMAC mechanisms --- src/tools/pkcs11-tool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 726cb7b60d..59b3786160 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7993,9 +7993,13 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA512, "SHA512", NULL, MF_UNKNOWN }, { CKM_SHA512_HMAC, "SHA512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA3_224, "SHA3-224", NULL, MF_UNKNOWN }, + { CKM_SHA3_224_HMAC, "SHA3-224-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA3_256, "SHA3-256", NULL, MF_UNKNOWN }, + { CKM_SHA3_256_HMAC, "SHA3-256-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA3_384, "SHA3-384", NULL, MF_UNKNOWN }, + { CKM_SHA3_384_HMAC, "SHA3-384-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA3_512, "SHA3-512", NULL, MF_UNKNOWN }, + { CKM_SHA3_512_HMAC, "SHA3-512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_RIPEMD128, "RIPEMD128", NULL, MF_UNKNOWN }, { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL, MF_UNKNOWN }, { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL, MF_UNKNOWN }, From 05b76552248f78b40b24237b06b2f0211ee65b58 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Thu, 3 Nov 2022 11:22:35 +0100 Subject: [PATCH 2647/4321] feat(pkcs11-tool): --usage-sign is also for secret keys --- src/tools/pkcs11-tool.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 59b3786160..4749d02b6d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3276,6 +3276,13 @@ gen_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hSecretKey n_attr++; } + if (opt_key_usage_sign != 0) { + FILL_ATTR(keyTemplate[n_attr], CKA_SIGN, &_true, sizeof(_true)); + n_attr++; + FILL_ATTR(keyTemplate[n_attr], CKA_VERIFY, &_true, sizeof(_true)); + n_attr++; + } + FILL_ATTR(keyTemplate[n_attr], CKA_VALUE_LEN, &key_length, sizeof(key_length)); n_attr++; @@ -4291,6 +4298,13 @@ static int write_object(CK_SESSION_HANDLE session) n_seckey_attr++; } + if (opt_key_usage_sign != 0) { + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_SIGN, &_true, sizeof(_true)); + n_seckey_attr++; + FILL_ATTR(seckey_templ[n_seckey_attr], CKA_VERIFY, &_true, sizeof(_true)); + n_seckey_attr++; + } + if (opt_object_label != NULL) { FILL_ATTR(seckey_templ[n_seckey_attr], CKA_LABEL, opt_object_label, strlen(opt_object_label)); n_seckey_attr++; From 0114bb38ae79397ac251425e4e2f8ae43e3adf42 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 4 Nov 2022 09:29:02 +0100 Subject: [PATCH 2648/4321] feat(pkcs11-tool): add MF_GENERIC_HMAC_FLAGS for CKM_MD5_HMAC --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4749d02b6d..25cf07cc7a 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7993,7 +7993,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_MD2_HMAC, "MD2-HMAC", NULL, MF_UNKNOWN }, { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL", NULL, MF_UNKNOWN }, { CKM_MD5, "MD5", NULL, MF_UNKNOWN }, - { CKM_MD5_HMAC, "MD5-HMAC", NULL, MF_UNKNOWN }, + { CKM_MD5_HMAC, "MD5-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL", NULL, MF_UNKNOWN }, { CKM_SHA_1, "SHA-1", NULL, MF_UNKNOWN }, { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, From 454d8b575da57552be4d45a85384e8efa11764d6 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Mon, 14 Nov 2022 17:21:27 +0100 Subject: [PATCH 2649/4321] feat(pkcs11-tool): add MF_GENERIC_HMAC_FLAGS wherever it is required --- src/tools/pkcs11-tool.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 25cf07cc7a..0ef8e950d6 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7990,14 +7990,14 @@ static struct mech_info p11_mechanisms[] = { { CKM_CDMF_MAC_GENERAL, "CDMF-MAC-GENERAL", NULL, MF_UNKNOWN }, { CKM_CDMF_CBC_PAD, "CDMF-CBC-PAD", NULL, MF_UNKNOWN }, { CKM_MD2, "MD2", NULL, MF_UNKNOWN }, - { CKM_MD2_HMAC, "MD2-HMAC", NULL, MF_UNKNOWN }, - { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_MD2_HMAC, "MD2-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_MD5, "MD5", NULL, MF_UNKNOWN }, { CKM_MD5_HMAC, "MD5-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, - { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA_1, "SHA-1", NULL, MF_UNKNOWN }, { CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, - { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA224, "SHA224", NULL, MF_UNKNOWN }, { CKM_SHA224_HMAC, "SHA224-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA256, "SHA256", NULL, MF_UNKNOWN }, @@ -8014,12 +8014,12 @@ static struct mech_info p11_mechanisms[] = { { CKM_SHA3_384_HMAC, "SHA3-384-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_SHA3_512, "SHA3-512", NULL, MF_UNKNOWN }, { CKM_SHA3_512_HMAC, "SHA3-512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, - { CKM_RIPEMD128, "RIPEMD128", NULL, MF_UNKNOWN }, - { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL, MF_UNKNOWN }, - { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_RIPEMD128, "RIPEMD128", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_RIPEMD160, "RIPEMD160", NULL, MF_UNKNOWN }, - { CKM_RIPEMD160_HMAC, "RIPEMD160-HMAC", NULL, MF_UNKNOWN }, - { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL", NULL, MF_UNKNOWN }, + { CKM_RIPEMD160_HMAC, "RIPEMD160-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_CAST_KEY_GEN, "CAST-KEY-GEN", NULL, MF_UNKNOWN }, { CKM_CAST_ECB, "CAST-ECB", NULL, MF_UNKNOWN }, { CKM_CAST_CBC, "CAST-CBC", NULL, MF_UNKNOWN }, @@ -8082,7 +8082,7 @@ static struct mech_info p11_mechanisms[] = { { CKM_PBE_SHA1_RC2_128_CBC,"PBE-SHA1-RC2-128-CBC", NULL, MF_UNKNOWN }, { CKM_PBE_SHA1_RC2_40_CBC,"PBE-SHA1-RC2-40-CBC", NULL, MF_UNKNOWN }, { CKM_PKCS5_PBKD2, "PKCS5-PBKD2", NULL, MF_UNKNOWN }, - { CKM_PBA_SHA1_WITH_SHA1_HMAC,"PBA-SHA1-WITH-SHA1-HMAC", NULL, MF_UNKNOWN }, + { CKM_PBA_SHA1_WITH_SHA1_HMAC,"PBA-SHA1-WITH-SHA1-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_KEY_WRAP_LYNKS, "KEY-WRAP-LYNKS", NULL, MF_UNKNOWN }, { CKM_KEY_WRAP_SET_OAEP, "KEY-WRAP-SET-OAEP", NULL, MF_UNKNOWN }, { CKM_SKIPJACK_KEY_GEN, "SKIPJACK-KEY-GEN", NULL, MF_UNKNOWN }, @@ -8161,11 +8161,11 @@ static struct mech_info p11_mechanisms[] = { { CKM_GOSTR3410_WITH_GOSTR3411_12_256, "GOSTR3410-WITH-GOSTR3411-12-256", NULL, MF_UNKNOWN }, { CKM_GOSTR3410_WITH_GOSTR3411_12_512, "GOSTR3410-WITH-GOSTR3411-12-512", NULL, MF_UNKNOWN }, { CKM_GOSTR3411, "GOSTR3411", NULL, MF_UNKNOWN }, - { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_HMAC, "GOSTR3411-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_GOSTR3411_12_256, "GOSTR3411-12-256", NULL, MF_UNKNOWN }, { CKM_GOSTR3411_12_512, "GOSTR3411-12-512", NULL, MF_UNKNOWN }, - { CKM_GOSTR3411_12_256_HMAC, "GOSTR3411-12-256-HMAC", NULL, MF_UNKNOWN }, - { CKM_GOSTR3411_12_512_HMAC, "GOSTR3411-12-512-HMAC", NULL, MF_UNKNOWN }, + { CKM_GOSTR3411_12_256_HMAC, "GOSTR3411-12-256-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, + { CKM_GOSTR3411_12_512_HMAC, "GOSTR3411-12-512-HMAC", NULL, MF_GENERIC_HMAC_FLAGS }, { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL, MF_UNKNOWN }, { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL, MF_UNKNOWN }, { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL, MF_UNKNOWN }, From e8233a8cba2af206fa44d040a0f22d9776580ef5 Mon Sep 17 00:00:00 2001 From: alegon01 Date: Fri, 28 Oct 2022 10:42:04 +0200 Subject: [PATCH 2650/4321] feat(pkcs11-tool): print CKA_UNIQUE_ID value for keys and certificates --- src/pkcs11/pkcs11.h | 1 + src/tools/pkcs11-tool.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index e298038f79..cf9e9c6bfd 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -397,6 +397,7 @@ typedef unsigned long ck_attribute_type_t; #define CKA_TOKEN (1UL) #define CKA_PRIVATE (2UL) #define CKA_LABEL (3UL) +#define CKA_UNIQUE_ID (4UL) #define CKA_APPLICATION (0x10UL) #define CKA_VALUE (0x11UL) #define CKA_OBJECT_ID (0x12UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0ef8e950d6..aae205fe2c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -681,6 +681,7 @@ ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */ ATTR_METHOD(VALUE_LEN, CK_ULONG); /* getVALUE_LEN */ ATTR_METHOD(PROFILE_ID, CK_ULONG); /* getPROFILE_ID */ VARATTR_METHOD(LABEL, char); /* getLABEL */ +VARATTR_METHOD(UNIQUE_ID, char); /* getUNIQUE_ID */ VARATTR_METHOD(APPLICATION, char); /* getAPPLICATION */ VARATTR_METHOD(ID, unsigned char); /* getID */ VARATTR_METHOD(OBJECT_ID, unsigned char); /* getOBJECT_ID */ @@ -4876,6 +4877,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) unsigned char *id, *oid, *value; const char *sepa; char *label; + char *unique_id; int pub = 1; int sec = 0; @@ -5191,6 +5193,10 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); } } + if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { + printf(" Unique ID: %s\n", unique_id); + free(unique_id); + } suppress_warn = 0; } @@ -5201,6 +5207,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) CK_ULONG size; unsigned char *id; char *label; + char *unique_id; #if defined(ENABLE_OPENSSL) unsigned char *subject; unsigned char *serial_number; @@ -5269,6 +5276,10 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) printf("\n"); free(id); } + if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) { + printf(" Unique ID: %s\n", unique_id); + free(unique_id); + } } static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) From 9e33f53c82dd9d218eda194812ee7c48de5adb04 Mon Sep 17 00:00:00 2001 From: Markus Meissner Date: Fri, 14 Sep 2018 17:58:33 +0200 Subject: [PATCH 2651/4321] Fixes #1399, 3 certs support OpenPGP (pksc15-tool) --- src/libopensc/card-openpgp.c | 48 +++++++++++++++++++--- src/libopensc/cardctl.h | 1 + src/libopensc/pkcs15-openpgp.c | 70 ++++++++++++++++++++++++++++----- src/pkcs15init/pkcs15-openpgp.c | 22 +++++++++-- 4 files changed, 124 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 261873f25a..fad32f0ce7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -258,7 +258,7 @@ static pgp_do_info_t pgp34_objects[] = { /**** OpenPGP card spec 3.4 ****/ { 0x5f50, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, { 0x5f52, SIMPLE, READ_ALWAYS | WRITE_NEVER, sc_get_data, NULL }, /* DO 7F21 is CONSTRUCTED in spec; we treat it as SIMPLE: no need to parse TLV */ - { DO_CERT, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, + { DO_CERT, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, { 0x7f48, CONSTRUCTED, READ_NEVER | WRITE_NEVER, NULL, NULL }, { 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, { DO_AUTH, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, @@ -1760,7 +1760,7 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) p15pubkey.u.eddsa.pubkey.len = 0; } sc_pkcs15_erase_pubkey(&p15pubkey); - + LOG_TEST_RET(card->ctx, r, "public key encoding failed"); if (len > buf_len) @@ -1772,6 +1772,43 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) } +/** + * Internal: SELECT DATA - selects a DO within a DO tag with several instances + * (supported since OpenPGP Card v3 for DO 7F21 only, see section 7.2.5 of the specification; + * this enables us to store multiple Card holder certificates in DO 7F21) + * + * p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG) + */ +static int +pgp_select_data(sc_card_t *card, u8 p1){ + sc_apdu_t apdu; + u8 apdu_data[6]; + int r; + + LOG_FUNC_CALLED(card->ctx); + + sc_log(card->ctx, "select data with: %u", p1); + + // create apdu data (taken from spec: SELECT DATA 7.2.5.) + apdu_data[0] = 0x60; + apdu_data[1] = 0x04; + apdu_data[2] = 0x5c; + apdu_data[3] = 0x02; + apdu_data[4] = 0x7f; + apdu_data[5] = 0x21; + + // apdu, cla, ins, p1, p2, data, datalen, resp, resplen + sc_format_apdu_ex(&apdu, 0x00, 0xA5, p1, 0x04, apdu_data, sizeof(apdu_data), NULL, 0); + + // transmit apdu + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, r, "Card returned error"); + LOG_FUNC_RETURN(card->ctx, r); +} + + /** * ABI: ISO 7816-4 GET DATA - get contents of a DO. */ @@ -1811,7 +1848,6 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen); } - /** * Internal: write certificate for Gnuk. */ @@ -3519,13 +3555,15 @@ pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) memmove((sc_serial_number_t *) ptr, &card->serialnr, sizeof(card->serialnr)); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); break; - + case SC_CARDCTL_OPENPGP_SELECT_DATA: + r = pgp_select_data(card, *((u8 *) ptr)); + LOG_FUNC_RETURN(card->ctx, r); + break; #ifdef ENABLE_OPENSSL case SC_CARDCTL_OPENPGP_GENERATE_KEY: r = pgp_gen_key(card, (sc_cardctl_openpgp_keygen_info_t *) ptr); LOG_FUNC_RETURN(card->ctx, r); break; - case SC_CARDCTL_OPENPGP_STORE_KEY: r = pgp_store_key(card, (sc_cardctl_openpgp_keystore_info_t *) ptr); LOG_FUNC_RETURN(card->ctx, r); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 760b6c5e9b..2ec2852c46 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -252,6 +252,7 @@ enum { SC_CARDCTL_OPENPGP_BASE = _CTL_PREFIX('P', 'G', 'P'), SC_CARDCTL_OPENPGP_GENERATE_KEY, SC_CARDCTL_OPENPGP_STORE_KEY, + SC_CARDCTL_OPENPGP_SELECT_DATA, /* * SmartCard-HSM diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 78255d3b61..e2f3442238 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -32,6 +32,7 @@ #include "internal.h" #include "pkcs15.h" #include "log.h" +#include "card-openpgp.h" static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *); @@ -44,6 +45,7 @@ static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *); | SC_PKCS15_PIN_FLAG_SO_PIN) #define PGP_NUM_PRIVDO 4 +#define PGP_MAX_NUM_CERTS 3 typedef struct _pgp_pin_cfg { const char *label; @@ -93,12 +95,25 @@ typedef struct _pgp_key_cfg { int pubkey_usage; } pgp_key_cfg_t; +typedef struct cdata_st { + const char *label; + int authority; + const char *path; + const char *id; + int obj_flags; +} cdata; + static const pgp_key_cfg_t key_cfg[3] = { { "Signature key", "B601", 1, PGP_SIG_PRKEY_USAGE, PGP_SIG_PUBKEY_USAGE }, { "Encryption key", "B801", 2, PGP_ENC_PRKEY_USAGE, PGP_ENC_PUBKEY_USAGE }, { "Authentication key", "A401", 2, PGP_AUTH_PRKEY_USAGE | PGP_ENC_PRKEY_USAGE, PGP_AUTH_PUBKEY_USAGE | PGP_ENC_PUBKEY_USAGE } }; +static const cdata certs[PGP_MAX_NUM_CERTS] = { + {"AUT certificate", 0, "3F007F21", "3", SC_PKCS15_CO_FLAG_MODIFIABLE}, + {"DEC certificate", 0, "3F007F21", "2", SC_PKCS15_CO_FLAG_MODIFIABLE}, + {"SIG certificate", 0, "3F007F21", "1", SC_PKCS15_CO_FLAG_MODIFIABLE} +}; typedef struct _pgp_manuf_map { unsigned short id; @@ -529,26 +544,63 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if (r < 0) goto failed; - /* If DO 7F21 holds data, we declare a cert object for pkcs15 */ - if (file->size > 0) { + for(u8 i=0; i= v3 */ + if (card->type >= SC_CARD_TYPE_OPENPGP_V3) { + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i); + if (r < 0) { + free(buffer); + LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data"); + } + } + sc_format_path(certs[i].path, &cert_info.path); + /* Certificate ID. We use the same ID as the authentication key */ - cert_info.id.value[0] = 3; - cert_info.id.len = 1; - /* Authority, flag is zero */ - /* The path following which PKCS15 will find the content of the object */ - sc_format_path("3F007F21", &cert_info.path); + sc_pkcs15_format_id(certs[i].id, &cert_info.id); + + resp_len = sc_get_data(card, 0x7F21, buffer, MAX_OPENPGP_DO_SIZE); + + /* Response length => free buffer and continue with next id */ + if (resp_len == 0) { + free(buffer); + continue; + } + + /* Catch error during sc_get_data */ + if (resp_len < 0) { + free(buffer); + goto failed; + } + + /* Assemble certificate info struct, based on `certs` array */ + cert_info.value.len = resp_len; + cert_info.value.value = buffer; + cert_info.authority = certs[i].authority; + cert_obj.flags = certs[i].obj_flags; + /* Object label */ - strlcpy(cert_obj.label, "Cardholder certificate", sizeof(cert_obj.label)); + strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label)); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if (r < 0) + if (r < 0) { + free(buffer); goto failed; + } + + /* only iterate, for OpenPGP >= v3, thus break on < v3 */ + if (card->type < SC_CARD_TYPE_OPENPGP_V3) + break; } /* Add PKCS#15 DATA objects from other OpenPGP card DOs. The return diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 6736f8e8db..c75bcbdaba 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -443,6 +443,7 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile case SC_PKCS15_TYPE_CERT: cinfo = (sc_pkcs15_cert_info_t *) obj->data; cid = &(cinfo->id); + unsigned int tag = 0x7F21; if (cid->len != 1) { sc_log(card->ctx, "ID=%s is not valid.", sc_dump_hex(cid->value, cid->len)); @@ -450,22 +451,37 @@ static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile } /* OpenPGP card v.2 contains only 1 certificate */ - if (cid->value[0] != 3) { + if (cid->value[0] != 3 && p15card->card->type < SC_CARD_TYPE_OPENPGP_V3) { sc_log(card->ctx, "This version does not support certificate ID = %d (only ID=3 is supported).", cid->value[0]); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } - /* Just update the certificate DO */ + + /* OpenPGP card < v.3 does not support SELECT DATA calls */ + if (p15card->card->type >= SC_CARD_TYPE_OPENPGP_V3) { + /* Mapping [3..1] passed --id to [0..2] for param */ + u8 param = (u8) (2 - (cid->value[0] - 1)); + /* check for unsigned underflow */ + if (param > 2) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } + + /* Just update the certificate DO */ + r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, ¶m); + LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data"); + } + sc_format_path("7F21", path); r = sc_select_file(card, path, &file); + LOG_TEST_RET(card->ctx, r, "Cannot select cert file"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); sc_log(card->ctx, "Data to write is %"SC_FORMAT_LEN_SIZE_T"u long", content->len); if (r >= 0 && content->len) - r = sc_put_data(p15card->card, 0x7F21, (const unsigned char *) content->value, content->len); + r = sc_put_data(p15card->card, tag, (const unsigned char *) content->value, content->len); break; case SC_PKCS15_TYPE_DATA_OBJECT: From bb9bd627462af4d61943a33d6e54308e103618f0 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 20 Dec 2021 08:43:49 +0100 Subject: [PATCH 2652/4321] Preparing to implement the C_DecryptFinalize and C_DecryptUpdate functions. The C_Decrypt() and pkcs15_prkey_decrypt() functions have been changed to allow pkcs15_prkey_decrypt() to be called from C_DecryptInit(), C_DecryptUpdate() and C_DecryptFinalize(). --- src/pkcs11/framework-pkcs15.c | 15 +++++++++++++ src/pkcs11/mechanism.c | 42 ++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 688cd84fdc..18f94271ed 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -4398,6 +4398,21 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj, unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */ int buff_too_small, rv, flags = 0, prkey_has_path = 0; + if (pulDataLen == NULL) { + /* This is call from the C_DecyptInit function */ + sc_log(context, "C_DecryptInit..."); + return CKR_OK; + } + if (pEncryptedData == NULL && ulEncryptedDataLen == 0) { + /* This is call from the C_DecryptFinalize function */ + sc_log(context, "C_DecryptFinalize..."); + *pulDataLen = 0; + return CKR_OK; + } + /* DecryptUpdate: we assume this code is called only once per session, either + * from the C_Decrypt function or from an application using the C_DecryptUpdate call + */ + sc_log(context, "Initiating decryption."); if (!p11card) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 3035e8a763..a81b58fea6 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1449,9 +1449,11 @@ sc_pkcs11_decrypt_init(sc_pkcs11_operation_t *operation, LOG_FUNC_RETURN(context, (int) rv); } } - operation->priv_data = data; - return CKR_OK; + + /* The last parameter is NULL - this is call to INIT code in underlying functions */ + return key->ops->decrypt(operation->session, + key, &operation->mechanism, NULL, 0, NULL, NULL); } static CK_RV @@ -1461,14 +1463,42 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation, { struct operation_data *data; struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulDataLen, ulLastDataLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pData && !pulDataLen) + return CKR_ARGUMENTS_BAD; + + ulDataLen = pulDataLen ? *pulDataLen : 0; + ulLastDataLen = ulDataLen; data = (struct operation_data *)operation->priv_data; key = data->key; - return key->ops->decrypt(operation->session, - key, &operation->mechanism, - pEncryptedData, ulEncryptedDataLen, - pData, pulDataLen); + + /* Decrypt */ + rv = key->ops->decrypt(operation->session, key, &operation->mechanism, + pEncryptedData, ulEncryptedDataLen, pData, &ulDataLen); + + if (pulDataLen) + *pulDataLen = ulDataLen; + + if (rv != CKR_OK) + return rv; + + /* recalculate buffer space */ + if (ulDataLen <= ulLastDataLen) + ulLastDataLen -= ulDataLen; + else + ulLastDataLen = 0; + + /* DecryptFinalize */ + rv = key->ops->decrypt(operation->session, key, &operation->mechanism, + NULL, 0, pData + ulDataLen, &ulLastDataLen); + if (pulDataLen) + *pulDataLen = ulDataLen + ulLastDataLen; + return rv; } static CK_RV From 839f266b5a81fab3e18650f768484ca0e8792680 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 18 Sep 2022 20:14:54 +0200 Subject: [PATCH 2653/4321] symmetric decryption pkcs#11: C_DecryptUpdate() and C_DecryptFinal() implementation pkcs#15: pkcs15_skey_decrypt, sc_pkcs15_decrypt_sym also implements: sc_decrypt_sym --- src/libopensc/iso7816.c | 3 +- src/libopensc/libopensc.exports | 2 + src/libopensc/opensc.h | 5 ++ src/libopensc/pkcs15-sec.c | 87 +++++++++++++++++++++++++ src/libopensc/pkcs15.h | 6 ++ src/libopensc/sec.c | 16 +++++ src/pkcs11/framework-pkcs15.c | 80 ++++++++++++++++++++++- src/pkcs11/mechanism.c | 108 ++++++++++++++++++++++++++++++++ src/pkcs11/openssl.c | 16 ++--- src/pkcs11/pkcs11-object.c | 75 ++++++++++++++++------ src/pkcs11/sc-pkcs11.h | 7 +++ 11 files changed, 376 insertions(+), 29 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 8c69176372..c5093812bc 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1325,7 +1325,8 @@ static struct sc_card_operations iso_ops = { NULL, /* card_reader_lock_obtained */ NULL, /* wrap */ NULL, /* unwrap */ - NULL /* encrypt_sym */ + NULL, /* encrypt_sym */ + NULL /* decrypt_sym */ }; static struct sc_card_driver iso_driver = { diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 07fa764679..bb27348418 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -83,6 +83,7 @@ sc_ctx_use_reader sc_ctx_win32_get_config_value _sc_delete_reader sc_decipher +sc_decrypt_sym sc_delete_file sc_delete_record sc_der_copy @@ -183,6 +184,7 @@ sc_pkcs15_encode_tokeninfo sc_pkcs15_encode_unusedspace sc_pkcs15_encrypt_sym sc_pkcs15_erase_pubkey +sc_pkcs15_decrypt_sym sc_pkcs15_dup_pubkey sc_pkcs15_find_cert_by_id sc_pkcs15_find_data_object_by_app_oid diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index d0f67a95ba..c58550d602 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -818,6 +818,8 @@ struct sc_card_operations { int (*encrypt_sym)(struct sc_card *card, const u8 *plaintext, size_t plaintext_len, u8 *out, size_t *outlen); + int (*decrypt_sym)(struct sc_card *card, const u8 *EncryptedData, size_t EncryptedDataLen, + u8 *out, size_t *outlen); }; typedef struct sc_card_driver { @@ -1385,6 +1387,9 @@ int sc_build_pin(u8 *buf, size_t buflen, struct sc_pin_cmd_pin *pin, int pad); int sc_encrypt_sym(struct sc_card *card, const u8 *Data, size_t DataLen, u8 *out, size_t *outlen); +int sc_decrypt_sym(struct sc_card *card, const u8 *EncryptedData, size_t EncryptedDataLen, + u8 *out, size_t *outlen); + /********************************************************************/ /* ISO 7816-9 related functions */ /********************************************************************/ diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 3675a1b616..f408556af4 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -870,3 +870,90 @@ sc_pkcs15_encrypt_sym(struct sc_pkcs15_card *p15card, LOG_FUNC_RETURN(ctx, r); } + +int +sc_pkcs15_decrypt_sym(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *obj, + unsigned long flags, + const u8 *in, size_t inlen, u8 *out, size_t *outlen, + const u8 *param, size_t paramlen) +{ + + sc_context_t *ctx = p15card->card->ctx; + + int i, r; + sc_algorithm_info_t *alg_info = NULL; + sc_security_env_t senv; + sc_sec_env_param_t senv_param; + const struct sc_pkcs15_skey_info *skey; + unsigned long pad_flags = 0, sec_flags = 0; + int revalidated_cached_pin = 0; + sc_path_t path; + + sc_log(ctx, "called with flags 0x%lX", flags); + + skey = (const struct sc_pkcs15_skey_info *)obj->data; + if (!(skey->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT)) + LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for encryption"); + + r = format_senv(p15card, obj, &senv, &alg_info); + LOG_TEST_RET(ctx, r, "Could not initialize security environment"); + senv.operation = SC_SEC_OPERATION_DECRYPT_SYM; + + r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags); + LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); + senv.algorithm_flags = sec_flags; + + for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS && senv.supported_algos[i].reference; i++) { + if ((senv.supported_algos[i].mechanism == CKM_AES_ECB && sec_flags == SC_ALGORITHM_AES_ECB) || + (senv.supported_algos[i].mechanism == CKM_AES_CBC && sec_flags == SC_ALGORITHM_AES_CBC) || + (senv.supported_algos[i].mechanism == CKM_AES_CBC_PAD && sec_flags == SC_ALGORITHM_AES_CBC_PAD)) { + senv.algorithm_ref = senv.supported_algos[i].algo_ref; + senv.flags |= SC_SEC_ENV_ALG_REF_PRESENT; + break; + } + } + + if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { + senv_param = (sc_sec_env_param_t){ + SC_SEC_ENV_PARAM_IV, (void *)param, paramlen}; + LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); + } + + LOG_TEST_RET(p15card->card->ctx, get_file_path(obj, &path), "Failed to get key file path."); + + LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed"); + + do { + r = SC_SUCCESS; + if (outlen == NULL) { + /* C_DecryptInit */ + /* select key file and set sec env */ + if (path.len != 0 || path.aid.len != 0) { + r = select_key_file(p15card, obj, &senv); + if (r < 0) + sc_log(p15card->card->ctx, "Unable to select key file"); + } + if (r == SC_SUCCESS) { + r = sc_set_security_env(p15card->card, &senv, 0); + if (r < 0) + sc_log(p15card->card->ctx, "Unable to set security env"); + } + } + + if (r == SC_SUCCESS) + r = sc_decrypt_sym(p15card->card, in, inlen, out, outlen); + + if (revalidated_cached_pin) + /* only re-validate once */ + break; + if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { + r = sc_pkcs15_pincache_revalidate(p15card, obj); + if (r < 0) + break; + revalidated_cached_pin = 1; + } + } while (revalidated_cached_pin); + + LOG_FUNC_RETURN(ctx, r); +} diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 0c768be62b..5a0a19c5a6 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -691,6 +691,12 @@ int sc_pkcs15_encrypt_sym(struct sc_pkcs15_card *p15card, const u8 *in, size_t inlen, u8 *out, size_t *outlen, const u8 *param, size_t paramlen); +int sc_pkcs15_decrypt_sym(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_object *obj, + unsigned long flags, + const u8 *in, size_t inlen, u8 *out, size_t *outlen, + const u8 *param, size_t paramlen); + int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *, const struct sc_pkcs15_object *, struct sc_pkcs15_pubkey **); int sc_pkcs15_decode_pubkey_rsa(struct sc_context *, diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 39904f292c..894c55eba8 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -353,3 +353,19 @@ sc_encrypt_sym(struct sc_card *card, const u8 *plaintext, size_t plaintext_len, r = card->ops->encrypt_sym(card, plaintext, plaintext_len, out, outlen); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } + +int +sc_decrypt_sym(struct sc_card *card, const u8 *data, size_t data_len, + u8 *out, size_t *outlen) +{ + int r; + + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + + LOG_FUNC_CALLED(card->ctx); + if (card->ops->decrypt_sym == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED); + r = card->ops->decrypt_sym(card, data, data_len, out, outlen); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 18f94271ed..39c0417be9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2389,7 +2389,6 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil out: return rv; } - /* * Secret key objects can be stored on card, if the card supports them * @@ -5620,6 +5619,83 @@ pkcs15_skey_encrypt(struct sc_pkcs11_session *session, void *obj, return sc_to_cryptoki_error(rv, "C_Encrypt..."); } +static CK_RV +pkcs15_skey_decrypt(struct sc_pkcs11_session *session, void *obj, + CK_MECHANISM_PTR pMechanism, + CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) +{ + struct sc_pkcs11_card *p11card = session->slot->p11card; + struct pkcs15_fw_data *fw_data = NULL; + struct pkcs15_skey_object *skey = (struct pkcs15_skey_object *)obj; + int rv, flags = 0; + size_t lDataLen, *lpDataLen; + + if (!p11card) + return sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_Decrypt..."); + fw_data = (struct pkcs15_fw_data *)p11card->fws_data[session->slot->fw_data_idx]; + if (!fw_data) + return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_Decrypt..."); + if (!fw_data->p15_card) + return sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_Decrypt..."); + + if (pMechanism == NULL) { + sc_log(context, "No mechanism specified\n"); + return CKR_ARGUMENTS_BAD; + } + + /* do not check NULL/0 in Data/DecryptedData here, this + can be an init operation or final operation..*/ + + if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT)) + skey = NULL; + + /* Please read comments in pkcs15_skey_unwrap() and pkcs15_skey_wrap() */ + + if (skey == NULL) + return CKR_KEY_FUNCTION_NOT_PERMITTED; + + sc_log(context, "Using mechanism %lx.", pMechanism->mechanism); + + switch (pMechanism->mechanism) { + case CKM_AES_ECB: + /* handle this in card driver + if (ulDataLen % 16) + return CKR_DATA_LEN_RANGE; */ + flags |= SC_ALGORITHM_AES_ECB; + break; + case CKM_AES_CBC: + /* handle this in card driver + if (ulDataLen % 16) + return CKR_DATA_LEN_RANGE; */ + flags |= SC_ALGORITHM_AES_CBC; + break; + case CKM_AES_CBC_PAD: + flags |= SC_ALGORITHM_AES_CBC_PAD; + break; + default: + return CKR_MECHANISM_INVALID; + } + + rv = sc_lock(p11card->card); + + if (rv < 0) + return sc_to_cryptoki_error(rv, "C_Decrypt..."); + + /* pointer CK_ULONG_PTR to size_t conversion */ + lpDataLen = pulDataLen ? &lDataLen : NULL; + + rv = sc_pkcs15_decrypt_sym(fw_data->p15_card, skey->prv_p15obj, flags, + pEncryptedData, ulEncryptedDataLen, pData, lpDataLen, + pMechanism->pParameter, pMechanism->ulParameterLen); + + if (pulDataLen) + *pulDataLen = *lpDataLen; + + sc_unlock(p11card->card); + return sc_to_cryptoki_error(rv, "C_Decrypt..."); +} + /* * Secret key objects, currently used only to retrieve derived session key */ @@ -5632,7 +5708,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { NULL, /* get_size */ NULL, /* sign */ pkcs15_skey_unwrap, - NULL, /* decrypt */ + pkcs15_skey_decrypt, /* decrypt */ pkcs15_skey_encrypt, /* encrypt */ NULL, /* derive */ NULL, /* can_do */ diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index a81b58fea6..eb4b451ab0 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1095,6 +1095,52 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session, return rv; } +CK_RV +sc_pkcs11_decr_update(struct sc_pkcs11_session *session, + CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) +{ + sc_pkcs11_operation_t *op; + CK_RV rv; + + rv = session_get_operation(session, SC_PKCS11_OPERATION_DECRYPT, &op); + if (rv != CKR_OK) + return rv; + + rv = op->type->decrypt_update(op, pEncryptedData, ulEncryptedDataLen, + pData, pulDataLen); + + /* terminate session for any error except CKR_BUFFER_TOO_SMALL */ + if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) + session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} + +CK_RV +sc_pkcs11_decr_final(struct sc_pkcs11_session *session, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) +{ + sc_pkcs11_operation_t *op; + CK_RV rv; + + rv = session_get_operation(session, SC_PKCS11_OPERATION_DECRYPT, &op); + if (rv != CKR_OK) + return rv; + + rv = op->type->decrypt_final(op, pData, pulDataLen); + + /* application is requesting buffer size ? */ + if (pData == NULL) { + /* do not terminate session for CKR_OK */ + if (rv == CKR_OK) + LOG_FUNC_RETURN(context, CKR_OK); + } else if (rv == CKR_BUFFER_TOO_SMALL) + LOG_FUNC_RETURN(context, CKR_BUFFER_TOO_SMALL); + + session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT); + LOG_FUNC_RETURN(context, (int)rv); +} + CK_RV sc_pkcs11_wrap(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, @@ -1501,6 +1547,66 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation, return rv; } +static CK_RV +sc_pkcs11_decrypt_update(sc_pkcs11_operation_t *operation, + CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) +{ + struct operation_data *data; + struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulPartLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pPart && !pulPartLen) + return CKR_ARGUMENTS_BAD; + + ulPartLen = pulPartLen ? *pulPartLen : 0; + + data = (struct operation_data *)operation->priv_data; + + key = data->key; + + rv = key->ops->decrypt(operation->session, + key, &operation->mechanism, + pEncryptedPart, ulEncryptedPartLen, + pPart, &ulPartLen); + + if (pulPartLen) + *pulPartLen = ulPartLen; + return rv; +} + +static CK_RV +sc_pkcs11_decrypt_final(sc_pkcs11_operation_t *operation, + CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen) +{ + struct operation_data *data; + struct sc_pkcs11_object *key; + CK_RV rv; + CK_ULONG ulLastPartLen; + + /* PKCS#11: If pBuf is not NULL_PTR, then *pulBufLen must contain the size in bytes.. */ + if (pLastPart && !pulLastPartLen) + return CKR_ARGUMENTS_BAD; + + ulLastPartLen = pulLastPartLen ? *pulLastPartLen : 0; + + data = (struct operation_data *)operation->priv_data; + + key = data->key; + + rv = key->ops->decrypt(operation->session, + key, &operation->mechanism, + NULL, 0, + pLastPart, &ulLastPartLen); + + if (pulLastPartLen) + *pulLastPartLen = ulLastPartLen; + return rv; +} + static CK_RV sc_pkcs11_derive(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *basekey, @@ -1599,6 +1705,8 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, if (pInfo->flags & CKF_DECRYPT) { mt->decrypt_init = sc_pkcs11_decrypt_init; mt->decrypt = sc_pkcs11_decrypt; + mt->decrypt_update = sc_pkcs11_decrypt_update; + mt->decrypt_final = sc_pkcs11_decrypt_final; } if (pInfo->flags & CKF_ENCRYPT) { mt->encrypt_init = sc_pkcs11_encrypt_init; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 30204d0901..6e2e421222 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -66,7 +66,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL,NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -87,7 +87,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -108,7 +108,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -129,7 +129,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -150,7 +150,7 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -171,7 +171,7 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL,NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -192,7 +192,7 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ @@ -213,7 +213,7 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { sc_pkcs11_openssl_md_final, NULL, NULL, NULL, NULL, /* sign_* */ NULL, NULL, NULL, /* verif_* */ - NULL, NULL, /* decrypt_* */ + NULL, NULL, NULL, NULL, /* decrypt_* */ NULL, NULL, NULL, NULL, /* encrypt */ NULL, /* derive */ NULL, /* wrap */ diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 907f0ad6b1..07cd57eb57 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -46,6 +46,8 @@ static sc_pkcs11_mechanism_type_t find_mechanism = { NULL, /* verif_final */ NULL, /* decrypt_init */ NULL, /* decrypt */ + NULL, /* decrypt_update */ + NULL, /* decrypt_final */ NULL, /* derive */ NULL, /* wrap */ NULL, /* unwrap */ @@ -1008,12 +1010,13 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */ return rv; } -CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pEncryptedData, /* input encrypted data */ - CK_ULONG ulEncryptedDataLen, /* count of bytes of input */ - CK_BYTE_PTR pData, /* receives decrypted output */ - CK_ULONG_PTR pulDataLen) -{ /* receives decrypted byte count */ +CK_RV +C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedData, /* input encrypted data */ + CK_ULONG ulEncryptedDataLen, /* count of bytes of input */ + CK_BYTE_PTR pData, /* receives decrypted output */ + CK_ULONG_PTR pulDataLen) /* receives decrypted byte count */ +{ CK_RV rv; struct sc_pkcs11_session *session; @@ -1036,20 +1039,56 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */ return rv; } -CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pEncryptedPart, /* input encrypted data */ - CK_ULONG ulEncryptedPartLen, /* count of bytes of input */ - CK_BYTE_PTR pPart, /* receives decrypted output */ - CK_ULONG_PTR pulPartLen) -{ /* receives decrypted byte count */ - return CKR_FUNCTION_NOT_SUPPORTED; +CK_RV +C_DecryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedPart, /* input encrypted data */ + CK_ULONG ulEncryptedPartLen, /* count of bytes of input */ + CK_BYTE_PTR pPart, /* receives decrypted output */ + CK_ULONG_PTR pulPartLen) /* receives decrypted byte count */ +{ + CK_RV rv; + struct sc_pkcs11_session *session; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_session(hSession, &session); + if (rv == CKR_OK) + rv = sc_pkcs11_decr_update(session, pEncryptedPart, ulEncryptedPartLen, + pPart, pulPartLen); + + SC_LOG_RV("C_DecryptUpdate() = %s", rv); + sc_pkcs11_unlock(); + return rv; } -CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pLastPart, /* receives decrypted output */ - CK_ULONG_PTR pulLastPartLen) -{ /* receives decrypted byte count */ - return CKR_FUNCTION_NOT_SUPPORTED; +CK_RV +C_DecryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastPart, /* receives decrypted output */ + CK_ULONG_PTR pulLastPartLen) /* receives decrypted byte count */ +{ + CK_RV rv; + struct sc_pkcs11_session *session; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + rv = get_session(hSession, &session); + if (rv == CKR_OK) { + rv = restore_login_state(session->slot); + if (rv == CKR_OK) { + rv = sc_pkcs11_decr_final(session, + pLastPart, + pulLastPartLen); + } + rv = reset_login_state(session->slot, rv); + } + + SC_LOG_RV("C_DecryptFinal() = %s", rv); + sc_pkcs11_unlock(); + return rv; } CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 4412bc4b75..0b42358e46 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -303,6 +303,11 @@ struct sc_pkcs11_mechanism_type { CK_BYTE_PTR, CK_ULONG); CK_RV (*decrypt_init)(sc_pkcs11_operation_t *, struct sc_pkcs11_object *); + CK_RV (*decrypt_update)(sc_pkcs11_operation_t *, + CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR); + CK_RV (*decrypt_final)(sc_pkcs11_operation_t *, + CK_BYTE_PTR, CK_ULONG_PTR); CK_RV (*decrypt)(sc_pkcs11_operation_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); @@ -470,6 +475,8 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG); #endif CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE); CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_decr_update(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); +CK_RV sc_pkcs11_decr_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG_PTR); CK_RV sc_pkcs11_encr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE); CK_RV sc_pkcs11_encr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR); From cb4e46a176087a970af5e6ff62a740b3b70d7d7b Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 18 Sep 2022 20:18:49 +0200 Subject: [PATCH 2654/4321] MyEID driver - symmetric decryption support --- src/libopensc/card-myeid.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 6b17f97534..de9ec7eb2e 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -2095,13 +2095,12 @@ myeid_encrypt_sym(struct sc_card *card, const u8 *data, size_t datalen, u8 *out, { return myeid_enc_dec_sym(card, data, datalen, out, outlen, 0); } -/* + static int myeid_decrypt_sym(struct sc_card *card, const u8 *data, size_t datalen, u8 *out, size_t *outlen) { return myeid_enc_dec_sym(card, data, datalen, out, outlen, 1); } -*/ static struct sc_card_driver * sc_get_driver(void) { @@ -2134,7 +2133,7 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.wrap = myeid_wrap_key; myeid_ops.unwrap = myeid_unwrap_key; myeid_ops.encrypt_sym = myeid_encrypt_sym; -/* myeid_ops.decrypt_sym = myeid_decrypt_sym;*/ + myeid_ops.decrypt_sym = myeid_decrypt_sym; return &myeid_drv; } From 8eda7587958b4bdb8afd2556f6e56398b0cc6db4 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Sun, 18 Sep 2022 20:20:20 +0200 Subject: [PATCH 2655/4321] Github actions: AES encrypt/decrypt test (OsEID/MyEID) --- .github/test-oseid.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-oseid.sh b/.github/test-oseid.sh index 1c992c9304..feb917d9e1 100755 --- a/.github/test-oseid.sh +++ b/.github/test-oseid.sh @@ -44,7 +44,7 @@ echo | ./OsEID-tool INIT ./OsEID-tool EC-ECDH-TEST ./OsEID-tool UNWRAP-WRAP-TEST ./OsEID-tool DES-AES-UPLOAD-KEYS -./OsEID-tool SYM-ENCRYPT-TEST +./OsEID-tool SYM-CRYPT-TEST popd # this does not work as we have random key IDs in here From ecd057bab93ab3493aede4f57feee221465e78a0 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Sat, 26 Nov 2022 21:23:17 +0100 Subject: [PATCH 2656/4321] Add missing sc_unlock() see https://github.com/OpenSC/OpenSC/pull/2646#discussion_r1032779787 --- src/libopensc/iso7816.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index c5093812bc..93b2707958 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -933,8 +933,10 @@ iso7816_set_security_env(struct sc_card *card, goto err; } } - if (se_num <= 0) - return 0; + if (se_num <= 0) { + r = SC_SUCCESS; + goto err; + } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num); r = sc_transmit_apdu(card, &apdu); sc_unlock(card); From d3c393c21a95333e0109aa115779f8a5064c3bfc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Nov 2022 17:33:53 +0100 Subject: [PATCH 2657/4321] ci: Fix misplaced comment --- .github/setup-java.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-java.sh b/.github/setup-java.sh index 00394718aa..5d7aff7270 100755 --- a/.github/setup-java.sh +++ b/.github/setup-java.sh @@ -14,7 +14,6 @@ env | grep -i openjdk # Javacard SDKs if [ ! -d "oracle_javacard_sdks" ]; then - # https://github.com/licel/jcardsim/pull/174 git clone https://github.com/martinpaljak/oracle_javacard_sdks.git fi export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit @@ -22,6 +21,7 @@ export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit # jCardSim if [ ! -d "jcardsim" ]; then + # https://github.com/licel/jcardsim/pull/174 git clone https://github.com/Jakuje/jcardsim.git fi pushd jcardsim From 5497519ea6b4af596628f8f8f2f904bacaa3148f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Nov 2022 09:34:43 +0100 Subject: [PATCH 2658/4321] OpenSC 0.23.0 --- NEWS | 10 +++++++--- configure.ac | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index d5ae93c931..e5d01337be 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ NEWS for OpenSC -- History of user visible changes -# New in 0.23.0; 2022-11-09 +# New in 0.23.0; 2022-11-29 ## General improvements * Support signing of data with a length of more than 512 bytes (#2314) * By default, disable support for old card drivers (#2391) and remove support for old drivers MioCOS and JCOP (#2374) @@ -11,11 +11,11 @@ NEWS for OpenSC -- History of user visible changes * Notice detached reader on macOS (#2418) * Support for OAEP padding (#2475, #2484) * Fix for PSS salt length (#2478) -* Improve fuzzing by adding new tests (#2417, #2500, #2520, #2550) +* Improve fuzzing by adding new tests (#2417, #2500, #2520, #2550, #2637) * Fixed various issues reported by OSS-Fuzz and Coverity regarding card drivers, PKCS#11 and PKCS#15 init * Fix issues with OpenPACE (#2472) * Containers support for local testing -* Add support for encryption using symmetric keys (#2473) +* Add support for encryption and decryption using symmetric keys (#2473, #2607) * Stop building support for Gost algorithms with OpenSSL 3.0 as they require deprecated API (#2586) * Fix detection of disconnected readers in PCSC (#2600) * Add configuration option for on-disk caching of private data (#2588) @@ -31,6 +31,8 @@ NEWS for OpenSC -- History of user visible changes * Add support for SHA3 (#2467) * Make object selectable via label (#2570) * Do not require an R/W session for some operations and add `--session-rw` option (#2579) +* Print more information: CKA_UNIQUE_ID attribute, SHA3 HMACs and serial number for certificates (#2644, #2643, #2641) +* Add new option --undestroyable to create keys with CKA_DESTROYABLE=FALSE (#2645) ## sc-hsm-tool * Add options for public key authentication (#2301) ## Minidriver @@ -53,10 +55,12 @@ NEWS for OpenSC -- History of user visible changes * Fix matching with newer versions and tokens initialized with OpenSC (#2575) ## MyEID * Support logout operation (#2557) +* Support for symmetric encryption and decryption (#2473, #2607) ## GIDS * Fix decipher for TPM (#1881) ## OpenPGP * Get the list of supported algorithms from algorithm information on the card (#2287) +* Support for 3 certificates with OpenPGP 3+ (#2103) ## nPA * Fix card detection (#2463) ## Rutoken diff --git a/configure.ac b/configure.ac index 2b9a3f0f5e..d5c7da6a0a 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [23]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-rc2]) +define([PACKAGE_SUFFIX], []) define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project]) define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project]) From 72acb01f570711ac62dbb2b1ef8198651d7b6d81 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Nov 2022 12:52:22 +0100 Subject: [PATCH 2659/4321] Update readme with download links --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c19bf028dc..03209e0cfd 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,14 @@ Do NOT use any links from wiki to download the OpenSC because wiki can be modifi # Downloads -[OpenSC 0.22.0](https://github.com/OpenSC/OpenSC/releases/tag/0.22.0) is the latest stable version released on 10.08.2021. It is available as +[OpenSC 0.23.0](https://github.com/OpenSC/OpenSC/releases/tag/0.23.0) is the latest stable version released on +29.11.2022. It is available as * Windows installer - * [OpenSC-0.22.0_win64.msi](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0_win64.msi) for 64 bit programs - * [OpenSC-0.22.0_win32.msi](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0_win32.msi) for 32 bit programs - * [OpenSC-0.22.0.dmg](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/OpenSC-0.22.0.dmg): macOS installer - * [opensc-0.22.0.tar.gz](https://github.com/OpenSC/OpenSC/releases/download/0.22.0/opensc-0.22.0.tar.gz): Source code distribution + * [OpenSC-0.23.0_win64.msi](https://github.com/OpenSC/OpenSC/releases/download/0.23.0/OpenSC-0.23.0_win64.msi) for 64 bit programs + * [OpenSC-0.23.0_win32.msi](https://github.com/OpenSC/OpenSC/releases/download/0.23.0/OpenSC-0.23.0_win32.msi) for 32 bit programs + * [OpenSC-0.23.0.dmg](https://github.com/OpenSC/OpenSC/releases/download/0.23.0/OpenSC-0.23.0.dmg): macOS installer + * [opensc-0.23.0.tar.gz](https://github.com/OpenSC/OpenSC/releases/download/0.23.0/opensc-0.23.0.tar.gz): Source code distribution ## Nightly build From 9294183e07ff4944e3f5e590f343f5727636767e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 1 Dec 2022 20:08:53 +0100 Subject: [PATCH 2660/4321] pkcs11-tool: Fix private key import --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index aae205fe2c..cfee8526d5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3669,13 +3669,13 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) RSA_get0_factors(r, &r_p, &r_q); RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp); #else - if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_d) != 1 || + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &r_d) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_p) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 || - EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT3, &r_iqmp) != 1) { util_fatal("OpenSSL error during RSA private key parsing"); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) { } #endif RSA_GET_BN(rsa, private_exponent, r_d); From cff91cf6167743bdd59285150c4ef19802ed2644 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 1 Dec 2022 20:11:41 +0100 Subject: [PATCH 2661/4321] pkcs11-tool: Log more information on OpenSSL errors --- src/tools/pkcs11-tool.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index cfee8526d5..f2e6b1dd91 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3641,10 +3641,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; r = EVP_PKEY_get1_RSA(pkey); if (!r) { - if (private) - util_fatal("OpenSSL error during RSA private key parsing"); - else - util_fatal("OpenSSL error during RSA public key parsing"); + util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public", + ERR_error_string(ERR_peek_last_error(), NULL)); } RSA_get0_key(r, &r_n, &r_e, NULL); @@ -3654,10 +3652,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) BIGNUM *r_dmp1 = NULL, *r_dmq1 = NULL, *r_iqmp = NULL; if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) { - if (private) - util_fatal("OpenSSL error during RSA private key parsing"); - else - util_fatal("OpenSSL error during RSA public key parsing"); + util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public", + ERR_error_string(ERR_peek_last_error(), NULL)); } #endif RSA_GET_BN(rsa, modulus, r_n); @@ -3674,8 +3670,9 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 || EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 || - util_fatal("OpenSSL error during RSA private key parsing"); EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) { + util_fatal("OpenSSL error during RSA private key parsing: %s", + ERR_error_string(ERR_peek_last_error(), NULL)); } #endif RSA_GET_BN(rsa, private_exponent, r_d); From a8b95a8dc1ff3bb69ed66fa17f8f02c35792c760 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 1 Dec 2022 20:38:31 +0100 Subject: [PATCH 2662/4321] Reproducer for broken pkcs11-tool key import --- tests/Makefile.am | 10 ++++--- tests/test-pkcs11-tool-import.sh | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100755 tests/test-pkcs11-tool-import.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index d378e2ee00..9d8a24c321 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,8 +14,9 @@ dist_noinst_SCRIPTS = common.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-sign-verify.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ - test-pkcs11-tool-sym-crypt-test.sh\ - test-pkcs11-tool-unwrap-wrap-test.sh + test-pkcs11-tool-sym-crypt-test.sh \ + test-pkcs11-tool-unwrap-wrap-test.sh \ + test-pkcs11-tool-import.sh .NOTPARALLEL: TESTS = \ @@ -25,8 +26,9 @@ TESTS = \ test-pkcs11-tool-test.sh \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-allowed-mechanisms.sh \ - test-pkcs11-tool-sym-crypt-test.sh\ - test-pkcs11-tool-unwrap-wrap-test.sh + test-pkcs11-tool-sym-crypt-test.sh \ + test-pkcs11-tool-unwrap-wrap-test.sh \ + test-pkcs11-tool-import.sh XFAIL_TESTS = \ test-pkcs11-tool-test-threads.sh \ test-pkcs11-tool-test.sh diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh new file mode 100755 index 0000000000..76ff8e51be --- /dev/null +++ b/tests/test-pkcs11-tool-import.sh @@ -0,0 +1,48 @@ +#!/bin/bash +SOURCE_PATH=${SOURCE_PATH:-..} + +source $SOURCE_PATH/tests/common.sh + +echo "=======================================================" +echo "Setup SoftHSM" +echo "=======================================================" +if [[ ! -f $P11LIB ]]; then + echo "WARNING: The SoftHSM is not installed. Can not run this test" + exit 77; +fi +card_setup + +ID="0100" +OPTS="" +for KEYTYPE in "RSA" "EC"; do + echo "=======================================================" + echo "Generate and import $KEYTYPE keys" + echo "=======================================================" + if [ "$KEYTYPE" == "RSA" ]; then + ID="0100" + elif [ "$KEYTYPE" == "EC" ]; then + ID="0200" + OPTS="-pkeyopt ec_paramgen_curve:P-521" + fi + openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS + assert $? "Failed to generate private $KEYTYPE key" + $PKCS11_TOOL --write-object "${KEYTYPE}_private.der" --id "$ID" --type privkey \ + --label "$KEYTYPE" -p "$PIN" --module "$P11LIB" + assert $? "Failed to write private $KEYTYPE key" + + openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER + assert $? "Failed to convert private $KEYTYPE key to public" + $PKCS11_TOOL --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" \ + -p $PIN --module $P11LIB + assert $? "Failed to write public $KEYTYPE key" + # certificate import already tested in all other tests + + rm "${KEYTYPE}_private.der" "${KEYTYPE}_public.der" +done + +echo "=======================================================" +echo "Cleanup" +echo "=======================================================" +card_cleanup + +exit $ERRORS From 7b2b50591622a0fd1e388440ca5f56f354da6fa3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 2 Dec 2022 18:07:43 +0100 Subject: [PATCH 2663/4321] Simplify the new test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Veronika Hanulíková <61348757+xhanulik@users.noreply.github.com> --- tests/test-pkcs11-tool-import.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index 76ff8e51be..c90b3b4926 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -12,15 +12,13 @@ if [[ ! -f $P11LIB ]]; then fi card_setup -ID="0100" -OPTS="" for KEYTYPE in "RSA" "EC"; do echo "=======================================================" echo "Generate and import $KEYTYPE keys" echo "=======================================================" - if [ "$KEYTYPE" == "RSA" ]; then - ID="0100" - elif [ "$KEYTYPE" == "EC" ]; then + ID="0100" + OPTS="" + if [ "$KEYTYPE" == "EC" ]; then ID="0200" OPTS="-pkeyopt ec_paramgen_curve:P-521" fi From 6a3448861769d365bbf62edd22930e7f677a1a78 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 11:02:23 +0100 Subject: [PATCH 2664/4321] Sync spec file from Fedora --- packaging/opensc.spec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 6b45c24a07..77939154d7 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -19,6 +19,7 @@ BuildRequires: bash-completion BuildRequires: zlib-devel # For tests BuildRequires: libcmocka-devel +BuildRequires: vim-common BuildRequires: softhsm BuildRequires: openssl Requires: pcsc-lite-libs%{?_isa} @@ -44,7 +45,7 @@ every software/card that does so, too. # The test-pkcs11-tool-allowed-mechanisms already works in Fedora sed -i -e '/XFAIL_TESTS/,$ { - s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh/ + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh/ q }' tests/Makefile.am @@ -63,7 +64,7 @@ sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths %set_build_flags CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations" -%configure --disable-static\ +%configure --disable-static \ --disable-autostart-items \ --disable-notify \ --disable-assert \ From 5f6f619d8f2b5b412da9f38e4e713e78c9b5f67d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 11:16:09 +0100 Subject: [PATCH 2665/4321] packaging: Remove needless configure option (#2633) --- packaging/opensc.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 77939154d7..fe3d84db01 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -70,8 +70,7 @@ CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations" --disable-assert \ --enable-pcsc \ --enable-cmocka \ - --enable-sm \ - --with-pcsc-provider=libpcsclite.so.1 + --enable-sm %make_build From a1c8841f2d2554bd237c17f03987b1266bb1a01b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 11:22:31 +0100 Subject: [PATCH 2666/4321] Run packit CI also on the spec file change --- .github/workflows/packit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index 665af978d6..17a2529db6 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -6,6 +6,7 @@ on: - '**.h' - '**.am' - .github/workflows/packit.yaml + - packaging/opensc.spec push: jobs: From cc147181c22251b6478dd421c6c8bee62be7144f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 13:54:40 +0100 Subject: [PATCH 2667/4321] rtecp: Make the boundaries check more explicit --- src/libopensc/card-rtecp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index db70fba808..2fd84fe82d 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -741,7 +741,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) } else if (!r && request == SC_CARDCTL_GET_SERIALNR) { - if (serial->len >= apdu.resplen) + if (apdu.resplen <= sizeof(serial->value)) { memcpy(serial->value, apdu.resp, apdu.resplen); serial->len = apdu.resplen; From 50099a90efa98cb92e861f6938d5a8a66a14101b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 14:49:18 +0100 Subject: [PATCH 2668/4321] rtecp: Remove trailing whitespace --- src/libopensc/card-rtecp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 2fd84fe82d..5ce15b6e6c 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -173,7 +173,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 6]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 6]); - sc_log(card->ctx, + sc_log(card->ctx, "SC_AC_OP_DELETE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_DELETE, method, key_ref); @@ -182,7 +182,7 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 0]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 0]); - sc_log(card->ctx, + sc_log(card->ctx, (file->type == SC_FILE_TYPE_DF) ? "SC_AC_OP_CREATE %i %lu\n" : "SC_AC_OP_READ %i %lu\n", @@ -200,11 +200,11 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) { method = sec_attr_to_method(file->sec_attr[1 + 1]); key_ref = sec_attr_to_key_ref(file->sec_attr[1 + 1]); - sc_log(card->ctx, + sc_log(card->ctx, "SC_AC_OP_UPDATE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, method, key_ref); - sc_log(card->ctx, + sc_log(card->ctx, "SC_AC_OP_WRITE %i %lu\n", (int)method, key_ref); sc_file_add_acl_entry(file, SC_AC_OP_WRITE, method, key_ref); @@ -482,12 +482,12 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, const u8 *newref, size_t newlen, int *tries_left) { sc_apdu_t apdu; - u8 rsf_length[2], *buf, *buf_end, *p; + u8 rsf_length[2], *buf, *buf_end, *p; size_t val_length, buf_length, max_transmit_length; int transmits_num, r; assert(card && card->ctx && newref); - sc_log(card->ctx, + sc_log(card->ctx, "newlen = %"SC_FORMAT_LEN_SIZE_T"u\n", newlen); if (newlen > 0xFFFF) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -496,7 +496,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, r = sc_verify(card, type, ref_qualifier, old, oldlen, tries_left); LOG_TEST_RET(card->ctx, r, "Verify old pin failed"); } - + max_transmit_length = sc_get_max_send_size(card); assert(max_transmit_length > 2); /* @@ -505,13 +505,13 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, */ transmits_num = (2 + sizeof(rsf_length) + newlen) / (max_transmit_length - 2) + 1; /* buffer length = size of 0x80 TLV + size of RSF-file + (size of Tag and Length)*(number of APDUs) */ - buf_length = (2 + sizeof(rsf_length)) + newlen + 2*(transmits_num); + buf_length = (2 + sizeof(rsf_length)) + newlen + 2*(transmits_num); p = buf = (u8 *)malloc(buf_length); if (buf == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - buf_end = buf + buf_length; + buf_end = buf + buf_length; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref_qualifier); /* put 0x80 TLV */ rsf_length[0] = (newlen >> 8) & 0xFF; rsf_length[1] = newlen & 0xFF; @@ -563,7 +563,7 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, r, "Unblock card failed"); - + if (newref && newlen) { u8 tmp[2], buf[SC_MAX_APDU_BUFFER_SIZE]; u8 *p = buf; @@ -710,7 +710,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) /* no call sc_debug (SC_FUNC_RETURN) */ return SC_ERROR_NOT_SUPPORTED; default: - sc_log(card->ctx, + sc_log(card->ctx, "request = 0x%lx\n", request); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } From ec7889e4b8403f173d4589f38daf50cf3d869db8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 15:06:22 +0100 Subject: [PATCH 2669/4321] codeql: Remove unapplicable checks The github Actions complain with the following warning: > The "paths"/"paths-ignore" fields of the config only have effect for JavaScript, Python, and Ruby --- .github/.codeql.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/.codeql.yml b/.github/.codeql.yml index 48b40e2728..5f103122cd 100644 --- a/.github/.codeql.yml +++ b/.github/.codeql.yml @@ -1,12 +1,5 @@ name: "CodeQL configuration file" -paths: - - src/ -paths-ignore: - - 'src/tools/*-cmdline.*' - - src/tests/ - - tests/ - query-filters: - exclude: # This reports all the uses of the DES, but this is needed for From e7693226a31f02a48e01203d7f0d22ba56f8d68e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 30 Nov 2022 15:20:56 +0100 Subject: [PATCH 2670/4321] codespell: Ignore conversion warning for the fuzzing corpus files The action complains with > Check for spelling errors: src/tests/fuzzing/corpus/fuzz_pkcs15init/6ce966ee0f311e1a63f2bb693caeba1b0fd1160e#L1 > Decoding file using encoding=utf-8 failed --- .github/workflows/codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index e10dcf1b75..912f4b3d02 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -17,5 +17,5 @@ jobs: - uses: actions/checkout@v2 - uses: codespell-project/actions-codespell@master with: - skip: compat_* + skip: ./src/tests/fuzzing/corpus,compat_* ignore_words_file: .github/codespell_ignore_words.txt From f7f90c4856a30854a85bca0aba4b90b3109ef821 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Fri, 9 Dec 2022 11:13:55 +0100 Subject: [PATCH 2671/4321] Update actions/virtual-environments#4589 workaround The workaround for i386 that is necessary to install wine has to be changed again. See PR#2584 and https://github.com/actions/runner-images/issues/4589#issuecomment-1260157764 for reference. --- .github/setup-linux.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index e137e00716..aa771656ce 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -41,7 +41,6 @@ fi if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo apt-get update -qq - sudo apt-get install -yqq --allow-downgrades libgd3/focal libpcre2-8-0/focal libpcre2-16-0/focal libpcre2-32-0/focal libpcre2-posix2/focal sudo apt-get purge -yqq libmono* moby* mono* php* libgdiplus libpcre2-posix3 libzip4 fi From b4e7a381e368ce9f0088c0479e3c7986546d0730 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 29 Nov 2022 08:49:54 +0100 Subject: [PATCH 2672/4321] simplify iso7816 write/read_binary_sfid don't clutter it with SM handling, it's handled good enough automatically --- src/libopensc/iso7816.c | 36 ++++++++---------------------------- src/sm/sm-eac.c | 8 ++++---- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 93b2707958..b1e27c8dd1 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1349,7 +1349,7 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, u8 **ef, size_t *ef_len) { int r; - size_t read = MAX_SM_APDU_RESP_SIZE; + size_t read; sc_apdu_t apdu; u8 *p; @@ -1359,13 +1359,9 @@ int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid, } *ef_len = 0; -#if MAX_SM_APDU_RESP_SIZE > (0xff+1) - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, + read = card->max_recv_size; + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); -#else - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, - ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); -#endif p = realloc(*ef, read); if (!p) { r = SC_ERROR_OUT_OF_MEMORY; @@ -1422,34 +1418,18 @@ int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid, u8 *ef, size_t ef_len) { int r; - size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0; + size_t write, wrote = 0; sc_apdu_t apdu; -#ifdef ENABLE_SM - struct iso_sm_ctx *iso_sm_ctx; -#endif if (!card) { r = SC_ERROR_INVALID_ARGUMENTS; goto err; } -#ifdef ENABLE_SM - iso_sm_ctx = card->sm_ctx.info.cmd_data; - if (write > SC_MAX_APDU_BUFFER_SIZE-2 - || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT - && write > (((SC_MAX_APDU_BUFFER_SIZE-2 - /* for encrypted APDUs we usually get authenticated status - * bytes (4B), a MAC (11B) and a cryptogram with padding - * indicator (3B without data). The cryptogram is always - * padded to the block size. */ - -18) / iso_sm_ctx->block_length) - * iso_sm_ctx->block_length - 1))) - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, - ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); - else -#endif - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, - ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + write = card->max_send_size; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, + ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); if (write > ef_len) { apdu.datalen = ef_len; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 8f8c3b30ef..6bfd26202a 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -2388,7 +2388,7 @@ int perform_pace(sc_card_t *card, r = SC_ERROR_NOT_SUPPORTED; } - return r; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); } int perform_terminal_authentication(sc_card_t *card, @@ -2396,19 +2396,19 @@ int perform_terminal_authentication(sc_card_t *card, const unsigned char *privkey, size_t privkey_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_NOT_SUPPORTED); } int perform_chip_authentication(sc_card_t *card, unsigned char **ef_cardsecurity, size_t *ef_cardsecurity_len) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_NOT_SUPPORTED); } int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, unsigned char *picc_pubkey, size_t picc_pubkey_len) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_NOT_SUPPORTED); } #endif From 578aed8391ef117ca64a9e0cba8e5c264368a0ec Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Dec 2022 00:27:18 +0100 Subject: [PATCH 2673/4321] sc_pkcs15init_rmdir: prevent out of bounds write fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53927 --- src/pkcs15init/pkcs15-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 91cee37310..3df03c6e1f 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -685,6 +685,8 @@ sc_pkcs15init_rmdir(struct sc_pkcs15_card *p15card, struct sc_profile *profile, path = df->path; path.len += 2; + if (path.len > SC_MAX_PATH_SIZE) + return SC_ERROR_INTERNAL; nfids = r / 2; while (r >= 0 && nfids--) { From e7f81d86dcdc751f4737f4b29a99bfc54d29c5c9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Dec 2022 00:45:31 +0100 Subject: [PATCH 2674/4321] muscle: prevent out of bounds write fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53631 --- src/libopensc/muscle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 7af279a0aa..61a4ec24d8 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -127,7 +127,7 @@ int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength) { u8 zeroBuffer[MSC_MAX_APDU]; size_t i; - size_t max_write_unit = MSC_MAX_SEND - 9; /* - 9 for object ID+length */ + size_t max_write_unit = MIN(MSC_MAX_APDU, MSC_MAX_SEND - 9); /* - 9 for object ID+length */ memset(zeroBuffer, 0, max_write_unit); for(i = 0; i < dataLength; i += max_write_unit) { From a0aef25c7f2ce0ec2c7e1014f959f0fe86ff0479 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 8 Dec 2022 10:09:58 -0600 Subject: [PATCH 2675/4321] card-piv.c fix auth length check --- src/libopensc/card-piv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 6bf740221e..dffb9e3ebc 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2047,8 +2047,7 @@ static int piv_general_external_authenticate(sc_card_t *card, } /* Sanity check the lengths again */ - tmplen = sc_asn1_put_tag(0x7C, NULL, tmplen, NULL, 0, NULL) - + sc_asn1_put_tag(0x82, NULL, cypher_text_len, NULL, 0, NULL); + tmplen = sc_asn1_put_tag(0x7C, NULL, tmplen, NULL, 0, NULL); if (output_len != (size_t)tmplen) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Allocated and computed lengths do not match! " "Expected %"SC_FORMAT_LEN_SIZE_T"d, found: %d\n", output_len, tmplen); From d9253551301d21942ed825cc835eb809c1063bbc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 14 Dec 2022 08:55:47 +0100 Subject: [PATCH 2676/4321] CI: upgrade to latest libressl 3.6.1 --- .github/setup-libressl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh index eed62cbc30..2a95c9759b 100755 --- a/.github/setup-libressl.sh +++ b/.github/setup-libressl.sh @@ -2,7 +2,7 @@ set -ex -o xtrace -V=libressl-3.4.2 +V=libressl-3.6.1 sudo apt-get remove -y libssl-dev From 93a6daa4317bfa59fb68cc85fbef04fe83c3d638 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 14 Dec 2022 09:04:36 +0100 Subject: [PATCH 2677/4321] CI: run linux workflow when changing LibreSSL setup --- .github/workflows/linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 81250febec..1ad6b2aaba 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -7,6 +7,7 @@ on: - '**.h' - .github/workflows/linux.yml - .github/setup-linux.sh + - .github/setup-libressl.sh - .github/build.sh - .github/push-artifacts.sh - '**.am' From da01e5fab9be9865db1aac203e574e0edbfd6584 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 14 Dec 2022 09:31:29 +0100 Subject: [PATCH 2678/4321] fixed compatibility with LibreSSL >= 3.5.0 fixes https://github.com/OpenSC/OpenSC/issues/2664 --- src/libopensc/card-iasecc.c | 12 +----------- src/libopensc/sc-ossl-compat.h | 1 + 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 480c1cf87b..1347ed2393 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -38,21 +38,11 @@ #include #include -/* - * OpenSSL-3.0.0 does not allow access to the SHA data - * so this driver can not produces signatures - * OpenSSL 1.1.1 uses EVP_MD_CTX_md_data - * LibreSSL - */ - -#if defined(LIBRESSL_VERSION_NUMBER) -# define EVP_MD_CTX_md_data(x) (x->md_data) -#endif - #include "internal.h" #include "asn1.h" #include "cardctl.h" #include "opensc.h" +#include "sc-ossl-compat.h" /* #include "sm.h" */ #include "pkcs15.h" /* #include "hash-strings.h" */ diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index da53ca8cee..8c0f96701c 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -42,6 +42,7 @@ extern "C" { #define X509_get_extension_flags(x) (x->ex_flags) #define X509_get_key_usage(x) (x->ex_kusage) #define X509_get_extended_key_usage(x) (x->ex_xkusage) +#define EVP_MD_CTX_md_data(x) (x->md_data) #endif #if defined(LIBRESSL_VERSION_NUMBER) From 98ad0f93b0a7673cdce82e1b3faa7dc314c64dd6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 16 Dec 2022 11:56:28 +0100 Subject: [PATCH 2679/4321] fixed compatibility with LibreSSL 3.7.0 --- src/libopensc/sc-ossl-compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 8c0f96701c..4425da93f3 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -54,9 +54,11 @@ extern "C" { #define EVP_sha3_256() (NULL) #define EVP_sha3_384() (NULL) #define EVP_sha3_512() (NULL) +#if LIBRESSL_VERSION_NUMBER < 0x3070000fL #define EVP_PKEY_new_raw_public_key(t, e, p, l) (NULL) #define EVP_PKEY_get_raw_public_key(p, pu, l) (0) #endif +#endif /* OpenSSL 1.1.1 has FIPS_mode function */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L From 4e52cebeeda823709aa31f684125f1ce92b4c67d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 1 Dec 2022 16:50:42 +0100 Subject: [PATCH 2680/4321] Remove asserts from pkcs15-cardos.c Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53357 --- src/pkcs15init/pkcs15-cardos.c | 150 +++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 64 deletions(-) diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index a13b73f61b..a91a13cf90 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -91,19 +91,23 @@ static void tlv_init(struct tlv *tlv, u8 *base, size_t size) tlv->current = tlv->next = base; } -static void tlv_next(struct tlv *tlv, u8 tag) +static int tlv_next(struct tlv *tlv, u8 tag) { - assert(tlv->next + 2 < tlv->end); + if (tlv->next + 2 >= tlv->end) + return SC_ERROR_INTERNAL; tlv->current = tlv->next; *(tlv->next++) = tag; *(tlv->next++) = 0; + return SC_SUCCESS; } -static void tlv_add(struct tlv *tlv, u8 val) +static int tlv_add(struct tlv *tlv, u8 val) { - assert(tlv->next + 1 < tlv->end); + if (tlv->next + 1 >= tlv->end) + return SC_ERROR_INTERNAL; *(tlv->next++) = val; tlv->current[1]++; + return SC_SUCCESS; } static size_t @@ -497,49 +501,60 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card, tlv_init(&tlv, buffer, sizeof(buffer)); /* object address: class, id */ - tlv_next(&tlv, 0x83); - tlv_add(&tlv, 0x00); /* class byte: usage TEST, k=0 */ - tlv_add(&tlv, auth_info->attrs.pin.reference & 0x7f); + if (tlv_next(&tlv, 0x83) != SC_SUCCESS + || tlv_add(&tlv, 0x00) != SC_SUCCESS /* class byte: usage TEST, k=0 */ + || tlv_add(&tlv, auth_info->attrs.pin.reference & 0x7f) != SC_SUCCESS) + return SC_ERROR_INTERNAL; /* parameters */ - tlv_next(&tlv, 0x85); - tlv_add(&tlv, 0x02); /* options byte */ + if (tlv_next(&tlv, 0x85) + || tlv_add(&tlv, 0x02) /* options byte */) + return SC_ERROR_INTERNAL; + hasverifyrc = cardos_have_verifyrc_package(card); if (hasverifyrc == 1) /* Use 9 byte OCI parameters to be able to set VerifyRC bit */ - tlv_add(&tlv, 0x04); /* options_2 byte with bit 2 set to return CurrentErrorCounter */ - tlv_add(&tlv, attempts & 0xf); /* flags byte */ - tlv_add(&tlv, CARDOS_ALGO_PIN); /* algorithm = pin-test */ - tlv_add(&tlv, attempts & 0xf); /* errcount = attempts */ + if (tlv_add(&tlv, 0x04) != SC_SUCCESS /* options_2 byte with bit 2 set to return CurrentErrorCounter */) + return SC_ERROR_INTERNAL; + + if (tlv_add(&tlv, attempts & 0xf) != SC_SUCCESS /* flags byte */ + || tlv_add(&tlv, CARDOS_ALGO_PIN) != SC_SUCCESS /* algorithm = pin-test */ + || tlv_add(&tlv, attempts & 0xf) != SC_SUCCESS /* errcount = attempts */) + return SC_ERROR_INTERNAL; /* usecount: not documented, but seems to work like this: * - value of 0xff means pin can be presented any number * of times * - anything less: max # of times before BS object is blocked. */ - tlv_add(&tlv, 0xff); + if (tlv_add(&tlv, 0xff) != SC_SUCCESS) + return SC_ERROR_INTERNAL; /* DEK: not documented, no idea what it means */ - tlv_add(&tlv, 0xff); + if (tlv_add(&tlv, 0xff) != SC_SUCCESS) + return SC_ERROR_INTERNAL; /* ARA counter: number of times the test object can be used before * another verification is required (~ user consent) * (0x00 unlimited usage) */ - tlv_add(&tlv, 0x00); - - tlv_add(&tlv, minlen); /* minlen */ + if (tlv_add(&tlv, 0x00) != SC_SUCCESS + || tlv_add(&tlv, minlen) != SC_SUCCESS /* minlen */) + return SC_ERROR_INTERNAL; /* AC conditions */ - tlv_next(&tlv, 0x86); - tlv_add(&tlv, 0x00); /* use: always */ - tlv_add(&tlv, auth_info->attrs.pin.reference); /* change: PIN */ - tlv_add(&tlv, puk_id); /* unblock: PUK */ + if (tlv_next(&tlv, 0x86) != SC_SUCCESS + || tlv_add(&tlv, 0x00) != SC_SUCCESS /* use: always */ + || tlv_add(&tlv, auth_info->attrs.pin.reference) != SC_SUCCESS /* change: PIN */ + || tlv_add(&tlv, puk_id) != SC_SUCCESS /* unblock: PUK */) + return SC_ERROR_INTERNAL; /* data: PIN */ - tlv_next(&tlv, 0x8f); + if (tlv_next(&tlv, 0x8f) != SC_SUCCESS) + return SC_ERROR_INTERNAL; while (pin_len--) - tlv_add(&tlv, *pin++); + if (tlv_add(&tlv, *pin++) != SC_SUCCESS) + return SC_ERROR_INTERNAL; args.data = buffer; args.len = tlv_len(&tlv); @@ -565,20 +580,19 @@ cardos_create_sec_env(struct sc_profile *profile, sc_card_t *card, int r; tlv_init(&tlv, buffer, sizeof(buffer)); - tlv_next(&tlv, 0x83); - tlv_add(&tlv, se_id); - - tlv_next(&tlv, 0x86); - tlv_add(&tlv, 0); - tlv_add(&tlv, 0); - - tlv_next(&tlv, 0x8f); - tlv_add(&tlv, key_id); - tlv_add(&tlv, key_id); - tlv_add(&tlv, key_id); - tlv_add(&tlv, key_id); - tlv_add(&tlv, key_id); - tlv_add(&tlv, key_id); + if (tlv_next(&tlv, 0x83) != SC_SUCCESS + || tlv_add(&tlv, se_id) != SC_SUCCESS + || tlv_next(&tlv, 0x86) != SC_SUCCESS + || tlv_add(&tlv, 0) != SC_SUCCESS + || tlv_add(&tlv, 0) != SC_SUCCESS + || tlv_next(&tlv, 0x8f) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS + || tlv_add(&tlv, key_id) != SC_SUCCESS) + return SC_ERROR_INTERNAL; args.data = buffer; args.len = tlv_len(&tlv); @@ -646,47 +660,55 @@ cardos_store_key_component(sc_card_t *card, tlv_init(&tlv, buffer, sizeof(buffer)); /* Object address */ - tlv_next(&tlv, 0x83); - tlv_add(&tlv, 0x20|num); /* PSO, n-th component */ - tlv_add(&tlv, key_id); + if (tlv_next(&tlv, 0x83) != SC_SUCCESS + || tlv_add(&tlv, 0x20|num) != SC_SUCCESS /* PSO, n-th component */ + || tlv_add(&tlv, key_id) != SC_SUCCESS) + return SC_ERROR_INTERNAL; /* Object parameters */ - tlv_next(&tlv, 0x85); - tlv_add(&tlv, CARDOS_KEY_OPTIONS|(last? 0x00 : 0x20)); - tlv_add(&tlv, CARDOS_KEY_FLAGS); - tlv_add(&tlv, algorithm); - tlv_add(&tlv, 0x00); - tlv_add(&tlv, 0xFF); /* use count */ - tlv_add(&tlv, 0xFF); /* DEK (whatever this is) */ - tlv_add(&tlv, 0x00); - tlv_add(&tlv, 0x00); + if (tlv_next(&tlv, 0x85) != SC_SUCCESS + || tlv_add(&tlv, CARDOS_KEY_OPTIONS|(last? 0x00 : 0x20)) != SC_SUCCESS + || tlv_add(&tlv, CARDOS_KEY_FLAGS) != SC_SUCCESS + || tlv_add(&tlv, algorithm) != SC_SUCCESS + || tlv_add(&tlv, 0x00) != SC_SUCCESS + || tlv_add(&tlv, 0xFF) != SC_SUCCESS /* use count */ + || tlv_add(&tlv, 0xFF) != SC_SUCCESS /* DEK (whatever this is) */ + || tlv_add(&tlv, 0x00) != SC_SUCCESS + || tlv_add(&tlv, 0x00) != SC_SUCCESS) + return SC_ERROR_INTERNAL; /* AC bytes */ - tlv_next(&tlv, 0x86); - tlv_add(&tlv, pin_id); /* AC USE */ - tlv_add(&tlv, pin_id); /* AC CHANGE */ - tlv_add(&tlv, pin_id); /* UNKNOWN */ - tlv_add(&tlv, 0); /* rfu */ - tlv_add(&tlv, 0); /* rfu */ - tlv_add(&tlv, 0); /* rfu */ - tlv_add(&tlv, 0); + if (tlv_next(&tlv, 0x86) != SC_SUCCESS + || tlv_add(&tlv, pin_id) != SC_SUCCESS /* AC USE */ + || tlv_add(&tlv, pin_id) != SC_SUCCESS /* AC CHANGE */ + || tlv_add(&tlv, pin_id) != SC_SUCCESS /* UNKNOWN */ + || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */ + || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */ + || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */ + || tlv_add(&tlv, 0) != SC_SUCCESS) + return SC_ERROR_INTERNAL; #ifdef SET_SM_BYTES /* it shouldn't be necessary to set the default value */ /* SM bytes */ - tlv_next(&tlv, 0x8B); + if (tlv_next(&tlv, 0x8B) != SC_SUCCESS) + return SC_ERROR_INTERNAL; for (n = 0; n < 16; n++) - tlv_add(&tlv, 0xFF); + if (tlv_add(&tlv, 0xFF) != SC_SUCCESS) + return SC_ERROR_INTERNAL; #endif /* key component */ - tlv_next(&tlv, 0x8f); + if (tlv_next(&tlv, 0x8f) != SC_SUCCESS) + return SC_ERROR_INTERNAL; if (use_prefix != 0) { - tlv_add(&tlv, len+1); - tlv_add(&tlv, 0); + if (tlv_add(&tlv, len+1) != SC_SUCCESS + || tlv_add(&tlv, 0) != SC_SUCCESS) + return SC_ERROR_INTERNAL; } while (len--) - tlv_add(&tlv, *data++); + if (tlv_add(&tlv, *data++) != SC_SUCCESS) + return SC_ERROR_INTERNAL; args.data = buffer; args.len = tlv_len(&tlv); From ad33a3ac9bbe0b3c9978f154e5ff66190b4043e4 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 2 Dec 2022 12:05:51 +0100 Subject: [PATCH 2681/4321] Add max depth when checking macro reference loop Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53448 --- src/pkcs15init/profile.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index b8b3ddbd08..dbdc535efe 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1976,12 +1976,15 @@ static struct block root_ops = { }; static int -check_macro_reference_loop(scconf_list *start, scconf_list *current, struct state *cur) { +check_macro_reference_loop(scconf_list *start, scconf_list *current, struct state *cur, int depth) { sc_macro_t *mac = NULL; const char *str = NULL; if (!start || !current || !cur) - return 0; + return 1; + + if (depth == 16) + return 1; str = current->data; if (str[0] != '$') @@ -1990,7 +1993,7 @@ check_macro_reference_loop(scconf_list *start, scconf_list *current, struct stat return 0; if (!strcmp(mac->name, start->data + 1)) return 1; - return check_macro_reference_loop(start, mac->value, cur); + return check_macro_reference_loop(start, mac->value, cur, depth + 1); } static int @@ -2024,7 +2027,7 @@ build_argv(struct state *cur, const char *cmdname, if (list == mac->value) { return SC_ERROR_SYNTAX_ERROR; } - if (check_macro_reference_loop(list, mac->value, cur)) { + if (check_macro_reference_loop(list, mac->value, cur, 0)) { return SC_ERROR_SYNTAX_ERROR; } #ifdef DEBUG_PROFILE From ce773aaaaedd37a66329e0eea3c45f30cb567fe2 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 5 Dec 2022 12:16:38 +0100 Subject: [PATCH 2682/4321] Fix stack-buffer-overflow When tag is found, check that output size is withing the bounds of the buffer. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53536 --- src/libopensc/card-authentic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 563210d8e6..4f5ed67918 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -190,6 +190,8 @@ authentic_get_tagged_data(struct sc_context *ctx, unsigned char *in, size_t in_l for (offs = 0; offs < in_len; ) { if ((*(in + offs) == 0x7F) || (*(in + offs) == 0x5F)) { + if (offs + 1 >= in_len) + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "parse error: invalid data"); tag = *(in + offs) * 0x100 + *(in + offs + 1); tag_len = 2; } @@ -205,7 +207,8 @@ authentic_get_tagged_data(struct sc_context *ctx, unsigned char *in, size_t in_l LOG_TEST_RET(ctx, size_len, "parse error: invalid size data"); if (tag == in_tag) { - if (offs + tag_len + size_len >= in_len) + if (offs + tag_len + size_len >= in_len + || in_len - (offs + tag_len + size_len) < size) LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "parse error: invalid data"); *out = in + offs + tag_len + size_len; From 0cc7f841616eddd5b02008f25b5c1422cac1b072 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 12 Dec 2022 11:31:11 +0100 Subject: [PATCH 2683/4321] Free file in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53467 --- src/pkcs15init/pkcs15-iasecc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 84cdb0fe8e..ac3c900aec 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1746,10 +1746,11 @@ iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof if (ii == nn_objs) break; sc_file_free(file); + file = NULL; } if (indx == MAX_DATA_OBJS) - LOG_TEST_RET(ctx, SC_ERROR_TOO_MANY_OBJECTS, "iasecc_store_data_object() too many DATA objects."); + LOG_TEST_GOTO_ERR(ctx, SC_ERROR_TOO_MANY_OBJECTS, "iasecc_store_data_object() too many DATA objects."); do { const struct sc_acl_entry *acl; @@ -1795,7 +1796,7 @@ iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *prof LOG_TEST_GOTO_ERR(ctx, rv, "s_pkcs15init_store_data_object() delete pkcs15 file error"); } else if (rv != SC_ERROR_FILE_NOT_FOUND) { - LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() select file error"); + LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() select file error"); } rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE); From beaffda81006b27d0076e3d9f57038615b995bd1 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 12 Dec 2022 11:39:29 +0100 Subject: [PATCH 2684/4321] Fix memory leak when overwritting file In `starcos_select_file()` when first selecting aid via `starcos_select_aid()`, the file_out can be overwritten by subsequent calls to `starcos_select_aid()` or `starcos_select_fid()` --- src/libopensc/card-starcos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 4705726903..60d876986b 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -781,6 +781,8 @@ static int starcos_select_aid(sc_card_t *card, file->namelen = len; file->id = 0x0000; file->magic = SC_FILE_MAGIC; + + free(*file_out); *file_out = file; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); @@ -897,6 +899,7 @@ static int starcos_select_fid(sc_card_t *card, file->size = 0; file->namelen = 0; file->magic = SC_FILE_MAGIC; + free(*file_out); *file_out = file; } else { /* ok, assume we have a EF */ @@ -917,6 +920,7 @@ static int starcos_select_fid(sc_card_t *card, return r; } + free(*file_out); *file_out = file; } } From a231201393367aa281cbc4a5b6c52422b3a6d942 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 12 Dec 2022 15:18:59 +0100 Subject: [PATCH 2685/4321] Simplify the condition --- src/libopensc/card-authentic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 4f5ed67918..2c16144de6 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -207,8 +207,7 @@ authentic_get_tagged_data(struct sc_context *ctx, unsigned char *in, size_t in_l LOG_TEST_RET(ctx, size_len, "parse error: invalid size data"); if (tag == in_tag) { - if (offs + tag_len + size_len >= in_len - || in_len - (offs + tag_len + size_len) < size) + if (in_len - (offs + tag_len + size_len) < size) LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "parse error: invalid data"); *out = in + offs + tag_len + size_len; From 93d033b1bd85a481126b987892063a07ba908910 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 12:16:17 +0100 Subject: [PATCH 2686/4321] p11test: Fix error detection when reading bool attributes --- src/tests/p11test/p11test_case_common.c | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 929d3661e3..28e780f884 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -309,19 +309,19 @@ int callback_private_keys(test_certs_t *objects, /* Store attributes, flags and handles */ o->private_handle = object_handle; - o->sign = (template[0].ulValueLen != (CK_ULONG) -1) + o->sign = (template[0].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[0].pValue) : CK_FALSE; - o->decrypt = (template[1].ulValueLen != (CK_ULONG) -1) + o->decrypt = (template[1].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[1].pValue) : CK_FALSE; - o->key_type = (template[2].ulValueLen != (CK_ULONG) -1) + o->key_type = (template[2].ulValueLen == sizeof(CK_KEY_TYPE)) ? *((CK_KEY_TYPE *) template[2].pValue) : (CK_KEY_TYPE) -1; - o->always_auth = (template[4].ulValueLen != (CK_ULONG) -1) + o->always_auth = (template[4].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; - o->unwrap = (template[5].ulValueLen != (CK_ULONG) -1) + o->unwrap = (template[5].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; - o->derive_priv = (template[6].ulValueLen != (CK_ULONG) -1) + o->derive_priv = (template[6].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; - o->extractable = (template[8].ulValueLen != (CK_ULONG) -1) + o->extractable = (template[8].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; debug_print(" [ OK %s ] Private key loaded successfully S:%d D:%d T:%02lX", @@ -359,16 +359,16 @@ int callback_public_keys(test_certs_t *objects, } o->public_handle = object_handle; - o->verify = (template[0].ulValueLen != (CK_ULONG) -1) + o->verify = (template[0].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[0].pValue) : CK_FALSE; - o->encrypt = (template[1].ulValueLen != (CK_ULONG) -1) + o->encrypt = (template[1].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[1].pValue) : CK_FALSE; /* store key type in case there is no corresponding private key */ - o->key_type = (template[2].ulValueLen != (CK_ULONG) -1) + o->key_type = (template[2].ulValueLen == sizeof(CK_KEY_TYPE)) ? *((CK_KEY_TYPE *) template[2].pValue) : (CK_KEY_TYPE) -1; - o->wrap = (template[8].ulValueLen != (CK_ULONG) -1) + o->wrap = (template[8].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; - o->derive_pub = (template[9].ulValueLen != (CK_ULONG) -1) + o->derive_pub = (template[9].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; /* check if we get the same public key as from the certificate */ @@ -390,7 +390,7 @@ int callback_public_keys(test_certs_t *objects, BN_free(cert_n); BN_free(n); BN_free(e); - return -1; + return -1; } #endif rv = BN_cmp(cert_n, n) == 0 && BN_cmp(cert_e, e) == 0; @@ -751,23 +751,23 @@ int callback_secret_keys(test_certs_t *objects, o->private_handle = object_handle; /* For verification/encryption, we use the same key */ o->public_handle = object_handle; - o->key_type = (template[0].ulValueLen != (CK_ULONG) -1) + o->key_type = (template[0].ulValueLen == sizeof(CK_KEY_TYPE)) ? *((CK_KEY_TYPE *) template[0].pValue) : (CK_KEY_TYPE) -1; - o->sign = (template[3].ulValueLen != (CK_ULONG) -1) + o->sign = (template[3].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[3].pValue) : CK_FALSE; - o->sign = (template[4].ulValueLen != (CK_ULONG) -1) + o->sign = (template[4].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; - o->encrypt = (template[5].ulValueLen != (CK_ULONG) -1) + o->encrypt = (template[5].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; - o->decrypt = (template[6].ulValueLen != (CK_ULONG) -1) + o->decrypt = (template[6].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[6].pValue) : CK_FALSE; - o->derive_priv = (template[7].ulValueLen != (CK_ULONG) -1) + o->derive_priv = (template[7].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[7].pValue) : CK_FALSE; - o->wrap = (template[8].ulValueLen != (CK_ULONG) -1) + o->wrap = (template[8].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[8].pValue) : CK_FALSE; - o->unwrap = (template[9].ulValueLen != (CK_ULONG) -1) + o->unwrap = (template[9].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[9].pValue) : CK_FALSE; - o->extractable = (template[12].ulValueLen != (CK_ULONG) -1) + o->extractable = (template[12].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[12].pValue) : CK_FALSE; if (template[10].ulValueLen > 0) { From dd7db66af32ace5ab0206d6236361362833feea3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 12:16:59 +0100 Subject: [PATCH 2687/4321] p11test: Make the convert_byte_string more readable --- src/tests/p11test/p11test_case_common.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 28e780f884..b6a4fb604c 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -1220,10 +1220,21 @@ const char *get_mechanism_flag_name(int mech_id) char *convert_byte_string(unsigned char *id, unsigned long length) { unsigned int i; - char *data = malloc(3 * length * sizeof(char) + 1); - for (i = 0; i < length; i++) - sprintf(&data[i*3], "%02X:", id[i]); - data[length*3-1] = '\0'; + char *data; + if (length == 0) { + return NULL; + } + + data = malloc(3 * length * sizeof(char) + 1); + if (data == NULL) { + return NULL; + } + + for (i = 0; i < length; i++) { + sprintf(&data[i * 3], "%02X:", id[i]); + } + + data[length * 3 - 1] = '\0'; return data; } From cd85348c652ac1e1a36ef0b2aa8f1a9ec02ed388 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 12:17:26 +0100 Subject: [PATCH 2688/4321] p11test: Ignore also CKR_DEVICE_ERROR when reading attributes this is returned by the SAC pkcs11 module when asked for unknown attribute. --- src/tests/p11test/p11test_case_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index b6a4fb604c..f5d6bbb92d 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -847,7 +847,8 @@ int search_objects(test_certs_t *objects, token_info_t *info, rv = fp->C_GetAttributeValue(info->session_handle, object_handles[i], &(template[j]), 1); if (rv == CKR_ATTRIBUTE_TYPE_INVALID || - rv == CKR_ATTRIBUTE_SENSITIVE) { + rv == CKR_ATTRIBUTE_SENSITIVE || + rv == CKR_DEVICE_ERROR) { continue; } else if (rv != CKR_OK) { fail_msg("C_GetAttributeValue: rv = 0x%.8lX\n", rv); From 790a94f09924f4968732392fcf31640033f22ad6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 12:18:10 +0100 Subject: [PATCH 2689/4321] p11test: Remove trailing whitespace --- src/tests/p11test/p11test_case_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index f5d6bbb92d..f9f24c9847 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -492,7 +492,7 @@ int callback_public_keys(test_certs_t *objects, ecpoint = EC_POINT_hex2point(ecgroup, BN_bn2hex(bn), NULL, NULL); BN_free(bn); - + if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " BIGNUM to OpenSSL format", o->id_str); @@ -566,7 +566,7 @@ int callback_public_keys(test_certs_t *objects, EC_POINT_free(ecpoint); return -1; } - + if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, curve_name_len) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || From 739fa81050989c3f85ca883ec76542b71cae7edc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 12:23:20 +0100 Subject: [PATCH 2690/4321] Avoid memory leak Thanks coverity: CID 382262 --- src/sm/sm-common.c | 24 ++++++++++++++---------- src/smm/sm-global-platform.c | 3 +-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index ce60a83a43..caada2b7ee 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -363,11 +363,9 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, int tmplen; #endif - if (!out || !out_len) return -1; - *out_len = data_len + 7; *out_len -= *out_len % 8; @@ -385,29 +383,35 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, for (ii=0; iicard_challenge + 4, 4); @@ -108,7 +108,6 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) { if (ctx) sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error"); - free(out); return NULL; } else if (out==NULL || out_len!=16) { From 83380d06348738164b58c60b6020c004ed7b50f2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 13:03:53 +0100 Subject: [PATCH 2691/4321] openssl: Avoid unused value when creating gost keys Thanks coverity: CID 382260 --- src/pkcs11/openssl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 6e2e421222..6513dbe8f3 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -462,8 +462,10 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub if (r == 1 && EVP_PKEY_get0(pkey) != NULL) group = EC_KEY_get0_group(EVP_PKEY_get0(pkey)); #else - EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, group_name, sizeof(group_name), NULL); - group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); + if (r == 1) { + EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, group_name, sizeof(group_name), NULL); + group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(group_name)); + } #endif r = -1; if (group) From 1e1c1b27692a54a943ab99a21f5896d8005386f5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 13:06:57 +0100 Subject: [PATCH 2692/4321] pkcs15-pubkey: Check return values of openssl functions Thanks coverity: CID 382259 --- src/libopensc/pkcs15-pubkey.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index ee4ee4620a..a8c154e7b1 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1652,8 +1652,12 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) int nid = 0; unsigned char *pub = NULL; size_t pub_len = 0; char *group_name = NULL; size_t group_name_len = 0; - EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len); - EVP_PKEY_get_group_name(pk, NULL, 0, &group_name_len); + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len) != 1) { + return SC_ERROR_INTERNAL; + } + if (EVP_PKEY_get_group_name(pk, NULL, 0, &group_name_len) != 1) { + return SC_ERROR_INTERNAL; + } if (!(pub = malloc(pub_len)) || !(group_name = malloc(group_name_len))) { free(pub); return SC_ERROR_OUT_OF_MEMORY; From 2b83b55985a433b6ff06bb27f264a3ba66192af7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 13:10:28 +0100 Subject: [PATCH 2693/4321] cwa: Fix never read result Thanks coverity: CID 382258 --- src/libopensc/cwa14890.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 6441c4ed6e..de3d79507a 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1008,7 +1008,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1) { msg = "Verify Signature: BN get param failed"; res = SC_ERROR_INTERNAL; - goto verify_internal_ok; + goto verify_internal_done; } #endif res = BN_sub(sigbn, icc_pubkey_n, bn); /* eval N.ICC-SIG */ From c358fc4dac4f32bb0fa04e5c05ebf4b3070ff7e3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 13:13:38 +0100 Subject: [PATCH 2694/4321] sm-eac: Avoid NULL pointer dereference Thanks coverity: CID 382263 --- src/sm/sm-eac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 6bfd26202a..3dc7c32089 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -2380,7 +2380,10 @@ int perform_pace(sc_card_t *card, { int r; - if (card && card->reader + if (!card) + return SC_ERROR_INVALID_ARGUMENTS; + + if (card->reader && card->reader->capabilities & SC_READER_CAP_PACE_GENERIC && card->reader->ops->perform_pace) { r = card->reader->ops->perform_pace(card->reader, &pace_input, pace_output); From 70771735ae10180bb039043b9a1b00b66bf00fc1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Dec 2022 13:12:03 +0100 Subject: [PATCH 2695/4321] Remove trailing whitespace and reformat to improve readability --- src/libopensc/cwa14890.c | 36 +++++++++++++++++------------------ src/libopensc/pkcs15-pubkey.c | 9 ++++++--- src/pkcs11/openssl.c | 4 ++-- src/sm/sm-eac.c | 12 ++++++------ src/smm/sm-card-authentic.c | 26 +++++++++++++------------ 5 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index de3d79507a..c859a956bd 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1,10 +1,10 @@ /** * cwa14890.c: Implementation of Secure Messaging according CWA-14890-1 and CWA-14890-2 standards. - * + * * Copyright (C) 2010 Juan Antonio Martinez * * This work is derived from many sources at OpenSC Project site, - * (see references) and the information made public by Spanish + * (see references) and the information made public by Spanish * Direccion General de la Policia y de la Guardia Civil * * This library is free software; you can redistribute it and/or @@ -142,7 +142,7 @@ static int cwa_increase_ssc(sc_card_t * card) /** * ISO 7816 padding. * - * Adds an 0x80 at the end of buffer and as many zeroes to get len + * Adds an 0x80 at the end of buffer and as many zeroes to get len * multiple of 8 * Buffer must be long enough to store additional bytes * @@ -393,7 +393,7 @@ static int cwa_verify_icc_certificates(sc_card_t * card, /** * Verify CVC certificates in SM establishment process. * - * This is done by mean of 00 2A 00 AE + * This is done by mean of 00 2A 00 AE * (Perform Security Operation: Verify Certificate ) * * @param card pointer to card data @@ -434,7 +434,7 @@ static int cwa_verify_cvc_certificate(sc_card_t * card, * Standard set_security_env() method has sc_security_env->buffer limited * to 8 bytes; so cannot send some of required SM commands. * - * @param card pointer to card data + * @param card pointer to card data * @param p1 apdu P1 parameter * @param p2 apdu P2 parameter * @param buffer raw data to be inserted in apdu @@ -472,7 +472,7 @@ static int cwa_set_security_env(sc_card_t * card, * * Internal (Card) authentication (let the card verify sent ifd certs) * - * @param card pointer to card data + * @param card pointer to card data * @param sig signature buffer * @param dig_len signature buffer length * @param data data to be sent in apdu @@ -513,7 +513,7 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da /** * Compose signature data for external auth according CWA-14890. - * + * * This code prepares data to be sent to ICC for external * authentication procedure * @@ -541,11 +541,11 @@ static int cwa_prepare_external_auth(sc_card_t * card, PRND2 || - (74 bytes) random data to make buffer 128 bytes length Kifd || - (32 bytes)- ifd random generated key sha1_hash( - PRND2 || - Kifd || + PRND2 || + Kifd || RND.ICC || - (8 bytes) response to get_challenge() cmd SN.ICC - (8 bytes) serial number from get_serialnr() cmd - ) || + ) || 0xBC - iso 9796-2 padding ) - total: 128 bytes @@ -723,7 +723,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, * * Perform external (IFD) authenticate procedure (8.4.1.2) * - * @param card pointer to card data + * @param card pointer to card data * @param sig signature buffer * @param sig signature buffer length * @return SC_SUCCESS if OK: else error code @@ -873,7 +873,7 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data) return res; } -/** +/** * check the result of internal_authenticate operation. * * Checks icc received data from internal auth procedure against @@ -943,7 +943,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, goto verify_internal_done; } - /* + /* We have received data with this format: sigbuf = E[PK.IFD.AUT](SIGMIN) SIGMIN = min ( SIG, N.ICC-SIG ) @@ -952,7 +952,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, PRND1 || Kicc || sha1_hash(PRND1 || Kicc || RND.IFD || SN.IFD) || - 0xBC + 0xBC ) So we should reverse the process and try to get valid results */ @@ -991,8 +991,8 @@ static int cwa_verify_internal_auth(sc_card_t * card, goto verify_internal_ok; verify_nicc_sig: - /* - * Arriving here means need to evaluate N.ICC-SIG + /* + * Arriving here means need to evaluate N.ICC-SIG * So convert buffers to bignums to operate */ bn = BN_bin2bn(buf1, len1, NULL); /* create BN data */ @@ -1166,7 +1166,7 @@ int cwa_create_secure_channel(sc_card_t * card, goto csc_end; } - /* + /* * Notice that this code inverts ICC and IFD certificate standard * checking sequence. */ @@ -1340,7 +1340,7 @@ int cwa_create_secure_channel(sc_card_t * card, goto csc_end; } - /* Internal (Card) authentication (let the card verify sent ifd certs) + /* Internal (Card) authentication (let the card verify sent ifd certs) SN.IFD equals 8 lsb bytes of ifd.pubk ref according cwa14890 sec 8.4.1 */ sc_log(ctx, "Step 8.4.1.10: Perform Internal authentication"); res = provider->cwa_get_sn_ifd(card); diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index a8c154e7b1..e53a6d41af 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -1650,8 +1650,11 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) EC_POINT *point = NULL; EC_GROUP *group = NULL; int nid = 0; - unsigned char *pub = NULL; size_t pub_len = 0; - char *group_name = NULL; size_t group_name_len = 0; + unsigned char *pub = NULL; + size_t pub_len = 0; + char *group_name = NULL; + size_t group_name_len = 0; + if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pub_len) != 1) { return SC_ERROR_INTERNAL; } @@ -1745,7 +1748,7 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) if (EVP_PKEY_get_group_name(pk, group_name, sizeof(group_name), NULL) != 1) return SC_ERROR_INTERNAL; dst->params.named_curve = strdup(group_name); - + /* Decode EC_POINT from a octet string */ if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, &buflen) != 1) { return SC_ERROR_INCOMPATIBLE_KEY; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 6513dbe8f3..6879e9e061 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -570,7 +570,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len * PKCS#11 does not define CKA_VALUE for public keys, and different cards * return either the raw or spki versions as defined in PKCS#15 * And we need to support more then just RSA. - * We can use d2i_PUBKEY which works for SPKI and any key type. + * We can use d2i_PUBKEY which works for SPKI and any key type. */ pubkey_tmp = pubkey; /* pass in so pubkey pointer is not modified */ @@ -612,7 +612,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len res = -1; } free(signat_tmp); - } else + } else res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); } else { res = -1; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 3dc7c32089..56acdf2116 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -47,7 +47,7 @@ char eac_default_flags = 0; /* 0x67 * Auxiliary authenticated data */ -ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) = +ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) = ASN1_EX_TEMPLATE_TYPE( ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, 7, AuxiliaryAuthenticatedData, CVC_DISCRETIONARY_DATA_TEMPLATE) @@ -524,7 +524,7 @@ static int eac_mse(sc_card_t *card, r = SC_ERROR_INVALID_ARGUMENTS; goto err; } - + r = format_mse_cdata(card->ctx, protocol, key_reference1, key_reference1_len, key_reference2, key_reference2_len, eph_pub_key, eph_pub_key_len, auxiliary_data, auxiliary_data_len, @@ -574,7 +574,7 @@ static int eac_mse_set_at_pace(sc_card_t *card, int protocol, { int r, tries; unsigned char key = secret_key; - + r = eac_mse_set_at(card, 0xC1, protocol, &key, sizeof key, NULL, 0, NULL, 0, NULL, 0, chat, sw1, sw2); if (0 > r) @@ -2053,7 +2053,7 @@ eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, goto err; } - my_mac = EAC_authenticate(eacsmctx->ctx, inbuf); + my_mac = EAC_authenticate(eacsmctx->ctx, inbuf); if (!my_mac) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute message authentication code (MAC) for verification."); @@ -2308,7 +2308,7 @@ static int eac_sm_post_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu) { - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, increment_ssc(ctx->priv_data)); } @@ -2320,7 +2320,7 @@ eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, if (!card) return SC_ERROR_INVALID_ARGUMENTS; if(!ctx || !ctx->priv_data || !apdu) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_INVALID_ARGUMENTS); eacsmctx = ctx->priv_data; diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index 2776e451c2..b5fc420b15 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -59,11 +59,10 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, unsigned char *tmp; int rv = 0, ii, tmp_len; - if (gp_keyset->kmc_len == 48) { + if (gp_keyset->kmc_len == 48) { for (ii=0; ii<3; ii++) memcpy(keys[ii], gp_keyset->kmc + 16*ii, 16); - } - else if (gp_keyset->kmc_len == 16 || gp_keyset->kmc_len == 0) { + } else if (gp_keyset->kmc_len == 16 || gp_keyset->kmc_len == 0) { if (gp_keyset->kmc_len == 16) memcpy(master_key, gp_keyset->kmc, 16); sc_debug(ctx, SC_LOG_DEBUG_SM, "KMC: %s", sc_dump_hex(master_key, sizeof(master_key))); @@ -85,14 +84,15 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, memcpy(keys[ii], tmp, sizeof(gp_keyset->enc)); free(tmp); } - } - else { + } else { LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "GP init session: invalid KMC data"); } - if (!rv && ctx) { - sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Card challenge", gp_session->card_challenge, sizeof(gp_session->card_challenge)); - sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Host challenge", gp_session->host_challenge, sizeof(gp_session->host_challenge)); + if (!rv && ctx) { + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Card challenge", gp_session->card_challenge, + sizeof(gp_session->card_challenge)); + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "Host challenge", gp_session->host_challenge, + sizeof(gp_session->host_challenge)); sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "ENC", gp_keyset->enc, sizeof(gp_keyset->enc)); sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MAC", gp_keyset->mac, sizeof(gp_keyset->mac)); sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "KEK", gp_keyset->kek, sizeof(gp_keyset->kek)); @@ -132,14 +132,16 @@ sm_authentic_get_apdus(struct sc_context *ctx, struct sm_info *sm_info, sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: rdata:%p, init_len:%"SC_FORMAT_LEN_SIZE_T"u", rdata, init_len); - sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: serial %s", sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM get APDUs: serial %s", + sc_dump_hex(sm_info->serialnr.value, sm_info->serialnr.len)); - if (init_data) { - rv = sm_gp_external_authentication(ctx, sm_info, init_data, init_len, rdata, sm_oberthur_diversify_keyset); + if (init_data) { + rv = sm_gp_external_authentication(ctx, sm_info, init_data, init_len, rdata, + sm_oberthur_diversify_keyset); LOG_TEST_RET(ctx, rv, "SM get APDUs: cannot authenticate card"); } - switch (sm_info->cmd) { + switch (sm_info->cmd) { case SM_CMD_APDU_TRANSMIT: rv = sm_authentic_encode_apdu(ctx, sm_info); LOG_TEST_RET(ctx, rv, "SM get APDUs: cannot encode APDU"); From b6ee58e15bcb15c96cdbe66a5bd003ee7ee1ae82 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Fri, 25 Nov 2022 09:24:13 +0100 Subject: [PATCH 2696/4321] Report PIN retry status at PKCS15 layer (Fixes #2647) --- src/libopensc/pkcs15-sc-hsm.c | 38 ++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 25a1fb4823..56119b2522 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -1394,6 +1394,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pin_info.auth_id.value[0] = 1; pin_info.path.aid = sc_hsm_aid; pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.auth_method = SC_AC_CHV; pin_info.attrs.pin.reference = 0x81; pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_INITIALIZED|SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; @@ -1409,10 +1410,21 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label)); pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE|SC_PKCS15_CO_FLAG_MODIFIABLE; - r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - if (r < 0) { - sc_pkcs15_card_clear(p15card); - LOG_FUNC_RETURN(card->ctx, r); + pin_obj.data = &pin_info; + + r = sc_pkcs15_get_pin_info(p15card, &pin_obj); + + if (r != SC_ERROR_DATA_OBJECT_NOT_FOUND) { + if (r < 0) { + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); + } + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + if (r < 0) { + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); + } } memset(&pin_info, 0, sizeof(pin_info)); @@ -1422,8 +1434,9 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) pin_info.auth_id.value[0] = 2; pin_info.path.aid = sc_hsm_aid; pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.auth_method = SC_AC_CHV; pin_info.attrs.pin.reference = 0x88; - pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_INITIALIZED|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED|SC_PKCS15_PIN_FLAG_SO_PIN; + pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED|SC_PKCS15_PIN_FLAG_SO_PIN; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_BCD; pin_info.attrs.pin.min_length = 16; pin_info.attrs.pin.stored_length = 0; @@ -1435,6 +1448,21 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card) strlcpy(pin_obj.label, "SOPIN", sizeof(pin_obj.label)); pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + pin_obj.data = &pin_info; + + r = sc_pkcs15_get_pin_info(p15card, &pin_obj); + + if (r != SC_ERROR_DATA_OBJECT_NOT_FOUND) { + pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_INITIALIZED; + } else { + r = SC_SUCCESS; + } + + if (r < 0) { + sc_pkcs15_card_clear(p15card); + LOG_FUNC_RETURN(card->ctx, r); + } + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) { sc_pkcs15_card_clear(p15card); From cb925b6949ee6cb05b4812aea99e1bc23a06d2f7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 18 Jan 2023 12:12:12 +0100 Subject: [PATCH 2697/4321] pkcs11-register: disable autostart by default on Linux In macOS and Windows it is still added by default via the installers fixes https://github.com/OpenSC/OpenSC/issues/2060 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d5c7da6a0a..d7d9cb6be3 100644 --- a/configure.ac +++ b/configure.ac @@ -288,7 +288,7 @@ AC_ARG_ENABLE( [autostart-items], [AS_HELP_STRING([--enable-autostart-items],[enable autostart items @<:@enabled@:>@])], , - [enable_autostart="yes"] + [enable_autostart="no"] ) AC_ARG_ENABLE( From cdf868ca1a0a7afe67e03472ace42e31fac4d437 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 18 Jan 2023 13:17:13 +0100 Subject: [PATCH 2698/4321] pkcs11-register: add support for profiles with spaces fixes https://github.com/OpenSC/OpenSC/issues/2087 --- src/tools/pkcs11-register.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index 8cc2dceb52..ab86ef87b7 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -106,7 +106,7 @@ get_next_profile_path(const char **profiles_ini, const char *home, const char *b } /* adjust format to respect the maximum length of profile_path */ char format[32]; - if (0 > snprintf(format, sizeof(format), "Path=%%%ds", (int)(p_len-1)) + if (0 > snprintf(format, sizeof(format), "Path=%%%d[^\n]", (int)(p_len-1)) || 1 != sscanf(path, format, p)) continue; From 5e59daacd502ffa7618486e81840e8d2c605a836 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 19 Jan 2023 20:11:34 +0100 Subject: [PATCH 2699/4321] pkcs11-spy: add process/thread id to log (#2678) fixes https://github.com/OpenSC/OpenSC/issues/1984 --- src/pkcs11/Makefile.am | 4 ++-- src/pkcs11/pkcs11-spy.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 7872cc0579..622c074515 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -51,12 +51,12 @@ onepin_opensc_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) \ -module -shared -avoid-version -no-undefined pkcs11_spy_la_SOURCES = pkcs11-spy.c pkcs11-display.c pkcs11-display.h pkcs11.exports -pkcs11_spy_la_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) +pkcs11_spy_la_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPENSC_PKCS11_PTHREAD_CFLAGS) pkcs11_spy_la_LIBADD = \ $(top_builddir)/src/common/libpkcs11.la \ $(top_builddir)/src/common/libscdl.la \ $(top_builddir)/src/common/libcompat.la \ - $(OPTIONAL_OPENSSL_LIBS) + $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) pkcs11_spy_la_LDFLAGS = $(AM_LDFLAGS) \ -export-symbols "$(srcdir)/pkcs11.exports" \ -module -shared -avoid-version -no-undefined diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 1da2069eae..56dd2eaf7f 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -32,6 +32,10 @@ #include #endif #include +#include +#endif +#ifdef HAVE_PTHREAD +#include #endif #define CRYPTOKI_EXPORTS @@ -317,14 +321,17 @@ enter(const char *function) fprintf(spy_output, "\n%d: %s\n", count++, function); #ifdef _WIN32 - GetLocalTime(&st); - fprintf(spy_output, "%i-%02i-%02i %02i:%02i:%02i.%03i\n", st.wYear, st.wMonth, st.wDay, - st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); + GetLocalTime(&st); + fprintf(spy_output, "P:%lu; T:%lu %i-%02i-%02i %02i:%02i:%02i.%03i\n", + (unsigned long)GetCurrentProcessId(), (unsigned long)GetCurrentThreadId(), + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); #else gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); strftime (time_string, sizeof(time_string), "%F %H:%M:%S", tm); - fprintf(spy_output, "%s.%03ld\n", time_string, (long)tv.tv_usec / 1000); + fprintf(spy_output, "P:%lu; T:0x%lu %s.%03ld\n", + (unsigned long)getpid(), (unsigned long)pthread_self(), + time_string, (long)tv.tv_usec / 1000); #endif } From 4b5f922890ad4d371ca652ea344096a8949fa1a6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Jan 2023 22:58:04 +0100 Subject: [PATCH 2700/4321] doc: added info about offCardCertURL fixes https://github.com/OpenSC/OpenSC/issues/1587 --- doc/files/opensc.conf.5.xml.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 7e6699bd08..02bcea76b2 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1185,6 +1185,16 @@ app application { cached information. Note that the cached files may contain personal data such as name and mail address. + + + The PIV-II card driver supports the history object's + list of retired keys and certificates if they are + readable in the file cache directory. + If the specified object's URL is + "http://"DNS name"/"ASCII-HEX OffCardKeyHistoryFile, + then the searches for the file name + OffCardKeyHistoryFile + in the cache directory. From 9869c896135ba4d5d69df4731d31b8a14804b964 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Jan 2023 22:19:33 +0100 Subject: [PATCH 2701/4321] pkcs11: fixed bad return types fixes https://github.com/frankmorgner/OpenSCToken/issues/48#issuecomment-1386050986 --- src/pkcs11/framework-pkcs15.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 39c0417be9..996cbdf0e9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -3265,7 +3265,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, der->value = (unsigned char *) ptr; if (rv != CKR_OK) { sc_unlock(p11card->card); - return sc_to_cryptoki_error(rv, "C_GenerateKeyPair"); + return rv; } keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EC; @@ -6279,10 +6279,10 @@ static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flag return CKR_OK; } -static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int flags, +static CK_RV sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int flags, CK_ULONG min_key_size, CK_ULONG max_key_size) { - int rc; + CK_RV rc; CK_MECHANISM_INFO mech_info; sc_pkcs11_mechanism_type_t *mt; sc_card_t* card = p11card->card; From 53c1e730c10a2d53f6eb4a003c9e12dcf6643b20 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 17 Jan 2023 23:03:14 +0100 Subject: [PATCH 2702/4321] pkcs11: fixed type conversions fixes https://github.com/frankmorgner/OpenSCToken/issues/48#issuecomment-1386074232 --- src/pkcs11/mechanism.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index eb4b451ab0..e563bb0859 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -60,7 +60,7 @@ operation_data_release(struct operation_data *data) static CK_RV signature_data_buffer_append(struct operation_data *data, - const CK_BYTE *in, unsigned int in_len) + const CK_BYTE *in, CK_ULONG in_len) { if (!data) return CKR_ARGUMENTS_BAD; @@ -97,7 +97,7 @@ static CK_RV sc_pkcs11_copy_mechanism(sc_pkcs11_mechanism_type_t *mt, sc_pkcs11_mechanism_type_t **new_mt) { - int rv; + CK_RV rv; *new_mt = calloc(1, sizeof(sc_pkcs11_mechanism_type_t)); if (!(*new_mt)) @@ -127,7 +127,8 @@ sc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card, sc_pkcs11_mechanism_type_t *existing_mt; sc_pkcs11_mechanism_type_t *copy_mt = NULL; sc_pkcs11_mechanism_type_t **p; - int i, rv; + int i; + CK_RV rv; if (mt == NULL) return CKR_HOST_MEMORY; From c4236720008f94b234cc8f58b0f885dab1180396 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 20 Jan 2023 09:14:49 +0100 Subject: [PATCH 2703/4321] sc-hsm: add support for `opensc-tool --serial` (#2675) fixes https://github.com/OpenSC/OpenSC/issues/2648 --- src/libopensc/card-sc-hsm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 6999e71426..60d5895127 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1180,6 +1180,16 @@ static int sc_hsm_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) LOG_FUNC_CALLED(card->ctx); + if (!priv->serialno && 0 == strcmp(card->ctx->app_name, "opensc-tool")) { + /* sc-hsm initializes the serial number via its PKCS#15 layer. + * Create and destroy a dummy card to get this initialized. Only do + * this for `opensc-tool --serial` to avoid unnecessary card commands + * in all other cases. */ + sc_pkcs15_card_t *p15card = NULL; + sc_pkcs15_bind(card, NULL, &p15card); + sc_pkcs15_unbind(p15card); + } + if (!priv->serialno) { return SC_ERROR_OBJECT_NOT_FOUND; } From ac8e50e2a464e5f9ad47dd823bfead19476e8cdc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 18 Jan 2023 11:51:02 +0100 Subject: [PATCH 2704/4321] goid-tool: added missing documentation fixes https://github.com/OpenSC/OpenSC/issues/2025 --- doc/tools/goid-tool.1.xml | 161 ++++++++++++++++++++++++++++++++++--- src/tools/goid-tool.ggo.in | 4 +- 2 files changed, 152 insertions(+), 13 deletions(-) diff --git a/doc/tools/goid-tool.1.xml b/doc/tools/goid-tool.1.xml index c9e9d152f9..3ac2841eed 100644 --- a/doc/tools/goid-tool.1.xml +++ b/doc/tools/goid-tool.1.xml @@ -10,7 +10,7 @@ goid-tool - ??? + smart card utility for GoID fingerprint card @@ -25,7 +25,9 @@ Description The goid-tool utility can be used from - the command line to ??? + the command line to read and write data of the + + GoID fingerprint card. @@ -99,14 +101,154 @@ - + + + Options for SoCManager Applet + + + + + + + Change PIN + + + + + + Use (several times) to change one or more biometric templates + + + + + + Dump Information about the SoCManager's configuration + + + + + + + Options for PAccess Applet + + + + + filename, + filename + + Use (several times) to pass CV certificates + + + + , + , + + Private key for the CV certificate + + + + + + Print the card ID + + + + data + + Write the specified card ID + + + + + + Print the PAccess ID + + + + data + + Write the specified PAccess ID + + + + id + + Read the specified data group; use several times to read out multiple files + + + + filename + + Write output to a file instead of printing it; use once for each use of + + + + id + + Write the specified data group; use several times to write multiple files + + + + filename + + Read input from a file; use once for each use of + + + + id + + Delete the specified data group; use several times to delete multiple files + + + + id + + Create the specified data group; use several times to create multiple files + + + + size + + File size of newly created DGs + + + + condition + + Access condition for reading newly created DGs + + + + condition + + Access condition for reading newly created DGs + + + + index + + Required access bit in certificate's CHAT for reading newly created DGs + + + + condition + + Access condition for writing newly created DGs + + + + index + + Required access bit in certificate's CHAT for writing newly created DGs + + + + + See also - - pkcs11-tool - 1 - opensc.conf 5 @@ -116,11 +258,8 @@ Authors - pkcs11-register was written by + goid-tool was written by Frank Morgner frankmorgner@gmail.com. - - - diff --git a/src/tools/goid-tool.ggo.in b/src/tools/goid-tool.ggo.in index e606da76b4..fcf3a05b15 100644 --- a/src/tools/goid-tool.ggo.in +++ b/src/tools/goid-tool.ggo.in @@ -72,13 +72,13 @@ modeoption "new-read-ac" - "Access condition for reading newly created DGs" values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" modeoption "new-read-ac-chatbit" - - "Required access bits in certificate's CHAT for reading newly created DGs" + "Required access bit in certificate's CHAT for reading newly created DGs" int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" modeoption "new-write-ac" - "Access condition for writing newly created DGs" values="always","never","ta","sm" default="sm" mode="pxs" optional dependon="create-dg" modeoption "new-write-ac-chatbit" - - "Required access bits in certificate's CHAT for reading newly created DGs" + "Required access bit in certificate's CHAT for reading newly created DGs" int mode="pxs" optional dependon="create-dg" multiple typestr="INDEX" text " From 688712859db734a1c4dc60301d91b685e18686f9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 19 Jan 2023 20:10:03 +0100 Subject: [PATCH 2705/4321] tests: enable goid-tool for test-manpage --- tests/test-manpage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-manpage.sh b/tests/test-manpage.sh index 152c2c8712..da36a88693 100755 --- a/tests/test-manpage.sh +++ b/tests/test-manpage.sh @@ -2,7 +2,7 @@ SOURCE_PATH=${SOURCE_PATH:-..} # find all the manual pages in doc/tools -TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|" | grep -v goid-tool` +TOOLS=`find "${SOURCE_PATH}/doc/tools" -name "*.1.xml" | sed -E -e "s|.*/([a-z0-9-]*).*|\1|"` ALL=1 for T in $TOOLS; do From 076a8856a6565e4d8b7be77f15d02db13b4c70c9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 19 Jan 2023 21:59:18 +0100 Subject: [PATCH 2706/4321] CI: monitor everything in doc for changes --- .github/workflows/linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1ad6b2aaba..333a57a358 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,6 +11,7 @@ on: - .github/build.sh - .github/push-artifacts.sh - '**.am' + - doc/** push: permissions: From f11c26db71250da429d0e839620fc744b7b20c17 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 25 Dec 2022 14:47:25 +0100 Subject: [PATCH 2707/4321] SM/EAC: Removed checking of APDUs contents The content of the APDUs is still verified by the card. In OpenSC, checking the certificate validity, and the signatures matching some portions of the content was implemented, but never enabled. Since this is only useful in few corner cases, we now remove this functionality. --- src/libopensc/card-npa.c | 1 - src/sm/sm-eac.c | 215 ----------------------------------- src/sm/sm-eac.h | 3 - src/tools/npa-tool-cmdline.c | 19 ---- src/tools/npa-tool-cmdline.h | 3 - src/tools/npa-tool.c | 2 - src/tools/npa-tool.ggo.in | 3 - 7 files changed, 246 deletions(-) diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index b5ec070ebf..658f09e803 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -302,7 +302,6 @@ static int npa_unlock_esign(sc_card_t *card) } /* FIXME set flags with opensc.conf */ - eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL; eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA; eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA; diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 56acdf2116..d81f66d4c6 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -2083,30 +2083,6 @@ eac_sm_verify_authentication(sc_card_t *card, const struct iso_sm_ctx *ctx, return r; } -static int -add_tag(unsigned char **asn1new, int constructed, int tag, - int xclass, const unsigned char *data, size_t len) -{ - unsigned char *p; - int newlen; - - if (!asn1new || !data) - return -1; - - newlen = ASN1_object_size(constructed, len, tag); - if (newlen <= 0) - return newlen; - - p = OPENSSL_realloc(*asn1new, newlen); - if (!p) - return -1; - *asn1new = p; - - ASN1_put_object(&p, constructed, len, tag, xclass); - memcpy(p, data, len); - - return newlen; -} static int eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu) @@ -2114,12 +2090,8 @@ eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, int r; CVC_CERT *cvc_cert = NULL; unsigned char *cert = NULL; - int len; BUF_MEM *signature = NULL; unsigned char *sequence = NULL; - EAC_MSE_C *msesetat = NULL; - const unsigned char *p; - struct eac_sm_ctx *eacsmctx; if (!card) return SC_ERROR_INVALID_ARGUMENTS; @@ -2127,165 +2099,6 @@ eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, r = SC_ERROR_INVALID_ARGUMENTS; goto err; } - eacsmctx = ctx->priv_data; - - if (!(eacsmctx->flags & EAC_FLAG_DISABLE_CHECK_ALL)) { - if (apdu->ins == 0x2a && apdu->p1 == 0x00 && apdu->p2 == 0xbe) { - /* PSO:Verify Certificate - * check certificate description to match given certificate */ - - len = add_tag(&cert, 1, 0x21, V_ASN1_APPLICATION, apdu->data, apdu->datalen); - p = cert; - if (len < 0 || !CVC_d2i_CVC_CERT(&cvc_cert, &p, len) - || !cvc_cert || !cvc_cert->body) { - r = SC_ERROR_INVALID_DATA; - goto err; - } - - switch (CVC_get_role(cvc_cert->body->chat)) { - case CVC_CVCA: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing CVCA certificate"); - break; - - case CVC_DV: - case CVC_DocVer: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing DV certificate"); - break; - - case CVC_Terminal: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing Terminal certificate"); - - if (eacsmctx->certificate_description) { - switch (CVC_check_description(cvc_cert, - (unsigned char *) eacsmctx->certificate_description->data, - eacsmctx->certificate_description->length)) { - case 1: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Certificate Description matches Certificate"); - break; - case 0: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Certificate Description doesn't match Certificate"); - r = SC_ERROR_INVALID_DATA; - goto err; - break; - default: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Error verifying Certificate Description"); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - break; - } - } else { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Warning: Certificate Description missing"); - } - break; - - default: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unknown type of certificate"); - r = SC_ERROR_INVALID_DATA; - goto err; - break; - } - - if (!TA_STEP2_import_certificate(eacsmctx->ctx, cert, len)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Error importing certificate"); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - } else if (apdu->ins == ISO_MSE && apdu->p2 == 0xa4) { - /* MSE:Set AT */ - - len = add_tag(&sequence, 1, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, apdu->data, apdu->datalen); - p = sequence; - if (len < 0 || !d2i_EAC_MSE_C(&msesetat, &p, len)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse MSE:Set AT."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - if (apdu->p1 == 0x81) { - /* CA: fetch auxiliary data and terminal's compressed ephemeral - * public key */ - - if (msesetat->auxiliary_data) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's auxiliary data"); - if (eacsmctx->auxiliary_data) - BUF_MEM_free(eacsmctx->auxiliary_data); - eacsmctx->auxiliary_data = BUF_MEM_new(); - if (!eacsmctx->auxiliary_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - eacsmctx->auxiliary_data->length = i2d_ASN1_AUXILIARY_DATA( - msesetat->auxiliary_data, - (unsigned char **) &eacsmctx->auxiliary_data->data); - if ((int) eacsmctx->auxiliary_data->length < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding auxiliary data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - eacsmctx->auxiliary_data->max = eacsmctx->auxiliary_data->length; - } - if (msesetat->eph_pub_key) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's compressed ephemeral public key"); - if (eacsmctx->eph_pub_key) - BUF_MEM_free(eacsmctx->eph_pub_key); - eacsmctx->eph_pub_key = - BUF_MEM_create_init(msesetat->eph_pub_key->data, - msesetat->eph_pub_key->length); - if (!eacsmctx->eph_pub_key) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - } - } else if (apdu->p1 == 0x41) { - /* TA: Set CAR */ - - if (msesetat->key_reference1 && msesetat->key_reference1->data && - msesetat->key_reference1->length) { - /* do nothing. The trust anchor matching this CAR will be - * looked up when the certificate chain is imported */ - } - } - } else if (apdu->ins == 0x82 && apdu->p1 == 0x00 && apdu->p2 == 0x00) { - /* External Authenticate - * check terminal's signature */ - - signature = BUF_MEM_create_init(apdu->data, apdu->datalen); - if (!signature) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - switch (TA_STEP6_verify(eacsmctx->ctx, eacsmctx->eph_pub_key, - eacsmctx->id_icc, eacsmctx->auxiliary_data, signature)) { - case 1: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Verified Terminal's signature"); - break; - case 0: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Terminal's signature not verified"); - r = SC_ERROR_INVALID_DATA; - goto err; - break; - default: - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, - "Error verifying terminal's signature"); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - break; - } - } - } r = increment_ssc(ctx->priv_data); @@ -2298,8 +2111,6 @@ eac_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, OPENSSL_free(cert); if (sequence) OPENSSL_free(sequence); - if (msesetat) - EAC_MSE_C_free(msesetat); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, r); } @@ -2316,37 +2127,11 @@ static int eac_sm_finish(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu) { - struct eac_sm_ctx *eacsmctx; if (!card) return SC_ERROR_INVALID_ARGUMENTS; if(!ctx || !ctx->priv_data || !apdu) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_INVALID_ARGUMENTS); - eacsmctx = ctx->priv_data; - - if (!(eacsmctx->flags & EAC_FLAG_DISABLE_CHECK_ALL)) { - if (apdu->sw1 == 0x90 && apdu->sw2 == 0x00) { - if (apdu->ins == 0x84 && apdu->p1 == 0x00 && apdu->p2 == 0x00 - && apdu->le == 8 && apdu->resplen == 8) { - BUF_MEM *nonce; - int r; - /* Get Challenge - * copy challenge to EAC context */ - - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving MRTD's nonce to later verify Terminal's signature"); - - nonce = BUF_MEM_create_init(apdu->resp, apdu->resplen); - r = TA_STEP4_set_nonce(eacsmctx->ctx, nonce); - if (nonce) - BUF_MEM_free(nonce); - - if (!r) { - ssl_error(card->ctx); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); - } - } - } - } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } diff --git a/src/sm/sm-eac.h b/src/sm/sm-eac.h index bf6b4dc569..54dd387168 100644 --- a/src/sm/sm-eac.h +++ b/src/sm/sm-eac.h @@ -178,9 +178,6 @@ int perform_chip_authentication(sc_card_t *card, int perform_chip_authentication_ex(sc_card_t *card, void *eacsmctx, unsigned char *picc_pubkey, size_t picc_pubkey_len); -/** @brief Disable all sanity checks done by OpenSC */ -#define EAC_FLAG_DISABLE_CHECK_ALL 1 - /** * @brief Sends an MSE:Set AT to determine the number of remaining tries * diff --git a/src/tools/npa-tool-cmdline.c b/src/tools/npa-tool-cmdline.c index 68a4b94b67..c617dca7e2 100644 --- a/src/tools/npa-tool-cmdline.c +++ b/src/tools/npa-tool-cmdline.c @@ -93,7 +93,6 @@ const char *gengetopt_args_info_help[] = { " -b, --break Brute force PIN, CAN or PUK. Use together with\n -p, -a or -u (default=off)", " -t, --translate=FILENAME File with APDUs of HEX_STRINGs to send through\n the secure channel (default=`stdin')", " --tr-03110v201 Force compliance to BSI TR-03110 version 2.01\n (default=off)", - " --disable-all-checks Disable all checking of fly-by-data\n (default=off)", "\nReport bugs to https://github.com/OpenSC/OpenSC/issues\n\nWritten by Frank Morgner ", 0 }; @@ -174,7 +173,6 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->break_given = 0 ; args_info->translate_given = 0 ; args_info->tr_03110v201_given = 0 ; - args_info->disable_all_checks_given = 0 ; } static @@ -253,7 +251,6 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->translate_arg = gengetopt_strdup ("stdin"); args_info->translate_orig = NULL; args_info->tr_03110v201_flag = 0; - args_info->disable_all_checks_flag = 0; } @@ -319,7 +316,6 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->break_help = gengetopt_args_info_help[56] ; args_info->translate_help = gengetopt_args_info_help[57] ; args_info->tr_03110v201_help = gengetopt_args_info_help[58] ; - args_info->disable_all_checks_help = gengetopt_args_info_help[59] ; } @@ -638,8 +634,6 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "translate", args_info->translate_orig, 0); if (args_info->tr_03110v201_given) write_into_file(outfile, "tr-03110v201", 0, 0 ); - if (args_info->disable_all_checks_given) - write_into_file(outfile, "disable-all-checks", 0, 0 ); i = EXIT_SUCCESS; @@ -1225,7 +1219,6 @@ cmdline_parser_internal ( { "break", 0, NULL, 'b' }, { "translate", 1, NULL, 't' }, { "tr-03110v201", 0, NULL, 0 }, - { "disable-all-checks", 0, NULL, 0 }, { 0, 0, 0, 0 } }; @@ -1866,18 +1859,6 @@ cmdline_parser_internal ( additional_error)) goto failure; - } - /* Disable all checking of fly-by-data. */ - else if (strcmp (long_options[option_index].name, "disable-all-checks") == 0) - { - - - if (update_arg((void *)&(args_info->disable_all_checks_flag), 0, &(args_info->disable_all_checks_given), - &(local_args_info.disable_all_checks_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "disable-all-checks", '-', - additional_error)) - goto failure; - } break; diff --git a/src/tools/npa-tool-cmdline.h b/src/tools/npa-tool-cmdline.h index 6412362f37..e38e1e69a8 100644 --- a/src/tools/npa-tool-cmdline.h +++ b/src/tools/npa-tool-cmdline.h @@ -166,8 +166,6 @@ struct gengetopt_args_info const char *translate_help; /**< @brief File with APDUs of HEX_STRINGs to send through the secure channel help description. */ int tr_03110v201_flag; /**< @brief Force compliance to BSI TR-03110 version 2.01 (default=off). */ const char *tr_03110v201_help; /**< @brief Force compliance to BSI TR-03110 version 2.01 help description. */ - int disable_all_checks_flag; /**< @brief Disable all checking of fly-by-data (default=off). */ - const char *disable_all_checks_help; /**< @brief Disable all checking of fly-by-data help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -222,7 +220,6 @@ struct gengetopt_args_info unsigned int break_given ; /**< @brief Whether break was given. */ unsigned int translate_given ; /**< @brief Whether translate was given. */ unsigned int tr_03110v201_given ; /**< @brief Whether tr-03110v201 was given. */ - unsigned int disable_all_checks_given ; /**< @brief Whether disable-all-checks was given. */ } ; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index 34bb1a8779..cdec50efa3 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -370,8 +370,6 @@ main (int argc, char **argv) } if (cmdline.tr_03110v201_flag) tr_version = EAC_TR_VERSION_2_01; - if (cmdline.disable_all_checks_flag) - eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL; if (cmdline.disable_ta_checks_flag) eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA; if (cmdline.disable_ca_checks_flag) diff --git a/src/tools/npa-tool.ggo.in b/src/tools/npa-tool.ggo.in index f2439a7249..45a5bf0d79 100644 --- a/src/tools/npa-tool.ggo.in +++ b/src/tools/npa-tool.ggo.in @@ -214,9 +214,6 @@ option "translate" t option "tr-03110v201" - "Force compliance to BSI TR-03110 version 2.01" flag off -option "disable-all-checks" - - "Disable all checking of fly-by-data" - flag off text " Report bugs to @PACKAGE_BUGREPORT@ From 511bd4c75e1a0cdc5b4b1e567f18db2ec2a2ae5b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 25 Dec 2022 18:10:44 +0100 Subject: [PATCH 2708/4321] removed flawfinder comments --- src/sm/sm-eac.c | 12 ------------ src/sm/sm-iso.c | 4 ---- 2 files changed, 16 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index d81f66d4c6..524a3018c7 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -674,7 +674,6 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*enc_nonce, p, l); *enc_nonce_len = l; @@ -760,7 +759,6 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*map_data_out, p, l); *map_data_out_len = l; @@ -846,7 +844,6 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*eph_pub_key_out, p, l); *eph_pub_key_out_len = l; @@ -934,7 +931,6 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*recent_car, r_data->cur_car->data, r_data->cur_car->length); *recent_car_len = r_data->cur_car->length; } else @@ -947,7 +943,6 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*prev_car, r_data->prev_car->data, r_data->prev_car->length); *prev_car_len = r_data->prev_car->length; } else @@ -958,7 +953,6 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(*auth_token_out, p, l); *auth_token_out_len = l; @@ -977,7 +971,6 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id { char *p = NULL; PACE_SEC *r; - /* Flawfinder: ignore */ char buf[EAC_MAX_MRZ_LEN > 32 ? EAC_MAX_MRZ_LEN : 32]; if (!length_pin || !pin) { @@ -1312,7 +1305,6 @@ int perform_pace(sc_card_t *card, } pace_output->id_icc = p; pace_output->id_icc_length = comp_pub_opp->length; - /* Flawfinder: ignore */ memcpy(pace_output->id_icc, comp_pub_opp->data, comp_pub_opp->length); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID ICC", pace_output->id_icc, pace_output->id_icc_length); @@ -1328,7 +1320,6 @@ int perform_pace(sc_card_t *card, } pace_output->id_pcd = p; pace_output->id_pcd_length = comp_pub->length; - /* Flawfinder: ignore */ memcpy(pace_output->id_pcd, comp_pub->data, comp_pub->length); sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID PCD", pace_output->id_pcd, pace_output->id_pcd_length); @@ -1929,7 +1920,6 @@ eac_sm_encrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, goto err; } *enc = p; - /* Flawfinder: ignore */ memcpy(*enc, encbuf->data, encbuf->length); r = encbuf->length; @@ -1971,7 +1961,6 @@ eac_sm_decrypt(sc_card_t *card, const struct iso_sm_ctx *ctx, goto err; } *data = p; - /* Flawfinder: ignore */ memcpy(*data, databuf->data, databuf->length); r = databuf->length; @@ -2019,7 +2008,6 @@ eac_sm_authenticate(sc_card_t *card, const struct iso_sm_ctx *ctx, goto err; } *macdata = p; - /* Flawfinder: ignore */ memcpy(*macdata, macbuf->data, macbuf->length); r = macbuf->length; diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index bfc1d57f52..7d9a79c98d 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -71,7 +71,6 @@ add_iso_pad(const u8 *data, size_t datalen, int block_size, u8 **padded) return SC_ERROR_OUT_OF_MEMORY; if (*padded != data) - /* Flawfinder: ignore */ memcpy(p, data, datalen); *padded = p; @@ -191,7 +190,6 @@ static int prefix_buf(u8 prefix, u8 *buf, size_t buflen, u8 **cat) if (ptr_same) { memmove(p + 1, p, buflen); } else { - /* Flawfinder: ignore */ memcpy(p + 1, buf, buflen); } p[0] = prefix; @@ -440,7 +438,6 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, goto err; } mac_data = p; - /* Flawfinder: ignore */ memcpy(mac_data + mac_data_len, asn1, asn1_len); mac_data_len += asn1_len; r = add_padding(ctx, mac_data, mac_data_len, &mac_data); @@ -591,7 +588,6 @@ static int sm_decrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto err; } - /* Flawfinder: ignore */ memcpy(apdu->resp, data, r); apdu->resplen = r; } else { From d9a4267522adafa3e37bf813f7d0b00e745fcd09 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 25 Dec 2022 18:02:57 +0100 Subject: [PATCH 2709/4321] sm-eac: switched to OpenSC style ASN.1 parsing --- src/sm/sm-eac.c | 821 ++++++++++++++---------------------------------- 1 file changed, 239 insertions(+), 582 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 524a3018c7..71b3cf0020 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -39,22 +39,6 @@ char eac_default_flags = 0; #define ISO_MSE 0x22 -#if defined(ENABLE_OPENPACE) -#include - -#define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type) -#define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type) - -/* 0x67 - * Auxiliary authenticated data */ -ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) = - ASN1_EX_TEMPLATE_TYPE( - ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 7, AuxiliaryAuthenticatedData, CVC_DISCRETIONARY_DATA_TEMPLATE) -ASN1_ITEM_TEMPLATE_END(ASN1_AUXILIARY_DATA) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) -#endif - #if defined(ENABLE_OPENPACE) && defined(ENABLE_SM) #include #include @@ -69,187 +53,6 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) #include -/* - * MSE:Set AT - */ - -typedef struct { - ASN1_OBJECT *cryptographic_mechanism_reference; - ASN1_OCTET_STRING *key_reference1; - ASN1_OCTET_STRING *key_reference2; - ASN1_OCTET_STRING *eph_pub_key; - ASN1_AUXILIARY_DATA *auxiliary_data; - CVC_CHAT *chat; -} EAC_MSE_C; -/* Note that we can not use ASN1_AUXILIARY_DATA for the auxiliary_data element - * here. Due to limitations of OpenSSL it is not possible to *encode* an - * optional item template (such as auxiliary_data) in an other item template - * (such as ASN1_AUXILIARY_DATA). However, we can do - * - * EAC_MSE_C->auxiliary_data = d2i_ASN1_AUXILIARY_DATA(...) - * - * because they both use the same underlying struct. - * - * See also openssl/crypto/asn1/tasn_dec.c:183 - */ -ASN1_SEQUENCE(EAC_MSE_C) = { - /* 0x80 - * Cryptographic mechanism reference */ - ASN1_IMP_OPT(EAC_MSE_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0), - /* 0x83 - * Reference of a public key / secret key */ - ASN1_IMP_OPT(EAC_MSE_C, key_reference1, ASN1_OCTET_STRING, 3), - /* 0x84 - * Reference of a private key / Reference for computing a session key */ - ASN1_IMP_OPT(EAC_MSE_C, key_reference2, ASN1_OCTET_STRING, 4), - /* 0x91 - * Ephemeral Public Key */ - ASN1_IMP_OPT(EAC_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11), - /* 0x67 - * Auxiliary authenticated data. See note above. */ - ASN1_APP_IMP_SEQUENCE_OF_OPT(EAC_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATE, 7), - /* Certificate Holder Authorization Template */ - ASN1_OPT(EAC_MSE_C, chat, CVC_CHAT), -} ASN1_SEQUENCE_END(EAC_MSE_C) -DECLARE_ASN1_FUNCTIONS(EAC_MSE_C) -IMPLEMENT_ASN1_FUNCTIONS(EAC_MSE_C) - - -/* - * General Authenticate for PACE - */ - -/* Protocol Command Data */ -typedef struct { - ASN1_OCTET_STRING *mapping_data; - ASN1_OCTET_STRING *eph_pub_key; - ASN1_OCTET_STRING *auth_token; -} EAC_GEN_AUTH_PACE_C_BODY; -ASN1_SEQUENCE(EAC_GEN_AUTH_PACE_C_BODY) = { - /* 0x81 - * Mapping Data */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, mapping_data, ASN1_OCTET_STRING, 1), - /* 0x83 - * Ephemeral Public Key */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 3), - /* 0x85 - * Authentication Token */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_C_BODY, auth_token, ASN1_OCTET_STRING, 5), -} ASN1_SEQUENCE_END(EAC_GEN_AUTH_PACE_C_BODY) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C_BODY) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C_BODY) - -typedef EAC_GEN_AUTH_PACE_C_BODY EAC_GEN_AUTH_PACE_C; -/* 0x7C - * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_PACE_C) = - ASN1_EX_TEMPLATE_TYPE( - ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, EAC_GEN_AUTH_PACE_C, EAC_GEN_AUTH_PACE_C_BODY) -ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_PACE_C) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_C) - -/* Protocol Response Data */ -typedef struct { - ASN1_OCTET_STRING *enc_nonce; - ASN1_OCTET_STRING *mapping_data; - ASN1_OCTET_STRING *eph_pub_key; - ASN1_OCTET_STRING *auth_token; - ASN1_OCTET_STRING *cur_car; - ASN1_OCTET_STRING *prev_car; -} EAC_GEN_AUTH_PACE_R_BODY; -ASN1_SEQUENCE(EAC_GEN_AUTH_PACE_R_BODY) = { - /* 0x80 - * Encrypted Nonce */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, enc_nonce, ASN1_OCTET_STRING, 0), - /* 0x82 - * Mapping Data */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, mapping_data, ASN1_OCTET_STRING, 2), - /* 0x84 - * Ephemeral Public Key */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, eph_pub_key, ASN1_OCTET_STRING, 4), - /* 0x86 - * Authentication Token */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, auth_token, ASN1_OCTET_STRING, 6), - /* 0x87 - * Most recent Certification Authority Reference */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, cur_car, ASN1_OCTET_STRING, 7), - /* 0x88 - * Previous Certification Authority Reference */ - ASN1_IMP_OPT(EAC_GEN_AUTH_PACE_R_BODY, prev_car, ASN1_OCTET_STRING, 8), -} ASN1_SEQUENCE_END(EAC_GEN_AUTH_PACE_R_BODY) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R_BODY) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R_BODY) - -typedef EAC_GEN_AUTH_PACE_R_BODY EAC_GEN_AUTH_PACE_R; -/* 0x7C - * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_PACE_R) = - ASN1_EX_TEMPLATE_TYPE( - ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, EAC_GEN_AUTH_PACE_R, EAC_GEN_AUTH_PACE_R_BODY) -ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_PACE_R) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_PACE_R) - - -/* - * General Authenticate for CA - */ - -/* Protocol Command Data */ -typedef struct eac_gen_auth_ca_cd_st { - ASN1_OCTET_STRING *eph_pub_key; -} EAC_GEN_AUTH_CA_C_BODY; -ASN1_SEQUENCE(EAC_GEN_AUTH_CA_C_BODY) = { - /* 0x80 - * Ephemeral Public Key */ - ASN1_IMP_OPT(EAC_GEN_AUTH_CA_C_BODY, eph_pub_key, ASN1_OCTET_STRING, 0), -} ASN1_SEQUENCE_END(EAC_GEN_AUTH_CA_C_BODY) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C_BODY) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C_BODY) - -typedef EAC_GEN_AUTH_CA_C_BODY EAC_GEN_AUTH_CA_C; -/* 0x7C - * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_CA_C) = - ASN1_EX_TEMPLATE_TYPE( - ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, EAC_GEN_AUTH_CA_C, EAC_GEN_AUTH_CA_C_BODY) -ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_CA_C) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_C) - -/* Protocol Response Data */ -typedef struct eac_gen_auth_ca_rapdu_body_st { - ASN1_OCTET_STRING *nonce; - ASN1_OCTET_STRING *auth_token; -} EAC_GEN_AUTH_CA_R_BODY; -ASN1_SEQUENCE(EAC_GEN_AUTH_CA_R_BODY) = { - /* 0x81 - * Nonce */ - ASN1_IMP_OPT(EAC_GEN_AUTH_CA_R_BODY, nonce, ASN1_OCTET_STRING, 1), - /* 0x82 - * Authentication Token */ - ASN1_IMP_OPT(EAC_GEN_AUTH_CA_R_BODY, auth_token, ASN1_OCTET_STRING, 2), -} ASN1_SEQUENCE_END(EAC_GEN_AUTH_CA_R_BODY) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R_BODY) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R_BODY) - -typedef EAC_GEN_AUTH_CA_R_BODY EAC_GEN_AUTH_CA_R; -/* 0x7C - * Dynamic Authentication Data */ -ASN1_ITEM_TEMPLATE(EAC_GEN_AUTH_CA_R) = - ASN1_EX_TEMPLATE_TYPE( - ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, - 0x1c, EAC_GEN_AUTH_CA_R, EAC_GEN_AUTH_CA_R_BODY) -ASN1_ITEM_TEMPLATE_END(EAC_GEN_AUTH_CA_R) -DECLARE_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R) -IMPLEMENT_ASN1_FUNCTIONS(EAC_GEN_AUTH_CA_R) - - - /** @brief NPA secure messaging context */ struct eac_sm_ctx { /** @brief EAC context */ @@ -388,122 +191,91 @@ static int get_ef_card_access(sc_card_t *card, return iso7816_read_binary_sfid(card, SFID_EF_CARDACCESS, ef_cardaccess, length_ef_cardaccess); } -static int format_mse_cdata(struct sc_context *ctx, int protocol, +/* + * MSE:Set AT + */ +static int encode_mse_cdata(struct sc_context *ctx, int protocol, const unsigned char *key_reference1, size_t key_reference1_len, const unsigned char *key_reference2, size_t key_reference2_len, const unsigned char *eph_pub_key, size_t eph_pub_key_len, const unsigned char *auxiliary_data, size_t auxiliary_data_len, const CVC_CHAT *chat, unsigned char **cdata) { - EAC_MSE_C *data = NULL; - unsigned char *data_sequence = NULL; - const unsigned char *data_no_sequence; - unsigned char *p; - long length; - int r, class, tag; + unsigned char *data = NULL, *encoded_chat = NULL, oid[16], *p = NULL; + size_t data_len = 0, oid_len = 0; + int r, encoded_chat_len = 0; + + struct sc_asn1_entry capdu_eac_mse[] = { + { "Cryptographic mechanism reference", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x00, 0, NULL, NULL }, + { "Reference of a public key / secret key", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x03, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Reference of a private key / Reference for computing a session key", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x04, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Ephemeral Public Key", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x11, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Auxiliary authenticated data", + SC_ASN1_OCTET_STRING, SC_ASN1_APP|SC_ASN1_CONS|0x07, SC_ASN1_OPTIONAL, NULL, NULL }, + /* "Certificate Holder Authorization Template", */ + { NULL , 0 , 0 , 0 , NULL , NULL } + }; if (!cdata) { r = SC_ERROR_INVALID_ARGUMENTS; goto err; } - data = EAC_MSE_C_new(); - if (!data) { - ssl_error(ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - if (protocol) { + ASN1_OBJECT *object = NULL; #ifndef HAVE_EAC_OBJ_NID2OBJ - data->cryptographic_mechanism_reference = OBJ_nid2obj(protocol); + object = OBJ_nid2obj(protocol); #else - data->cryptographic_mechanism_reference = EAC_OBJ_nid2obj(protocol); + object = EAC_OBJ_nid2obj(protocol); #endif - if (!data->cryptographic_mechanism_reference) { + if (!object) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting Cryptographic mechanism reference of MSE:Set AT data"); r = SC_ERROR_INTERNAL; goto err; } + oid_len = OBJ_length(object); + memcpy(oid, OBJ_get0_data(object), oid_len); } - if (key_reference1 && key_reference1_len) { - data->key_reference1 = ASN1_OCTET_STRING_new(); - if (!data->key_reference1 - || !ASN1_OCTET_STRING_set( - data->key_reference1, key_reference1, key_reference1_len)) { - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 1 of MSE:Set AT data"); - r = SC_ERROR_INTERNAL; - goto err; - } - } + sc_format_asn1_entry(capdu_eac_mse + 0, oid, &oid_len, oid_len > 0); + sc_format_asn1_entry(capdu_eac_mse + 1, (unsigned char *) key_reference1, &key_reference1_len, key_reference1 && key_reference1_len); + sc_format_asn1_entry(capdu_eac_mse + 2, (unsigned char *) key_reference2, &key_reference2_len, key_reference2 && key_reference2_len); + sc_format_asn1_entry(capdu_eac_mse + 3, (unsigned char *) eph_pub_key, &eph_pub_key_len, eph_pub_key && eph_pub_key_len); + sc_format_asn1_entry(capdu_eac_mse + 4, (unsigned char *) auxiliary_data, &auxiliary_data_len, auxiliary_data && auxiliary_data_len); - if (key_reference2 && key_reference2_len) { - data->key_reference2 = ASN1_OCTET_STRING_new(); - if (!data->key_reference2 - || !ASN1_OCTET_STRING_set( - data->key_reference2, key_reference2, key_reference2_len)) { - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 2 of MSE:Set AT data"); - r = SC_ERROR_INTERNAL; - goto err; - } - } - - if (eph_pub_key && eph_pub_key_len) { - data->eph_pub_key = ASN1_OCTET_STRING_new(); - if (!data->eph_pub_key - || !ASN1_OCTET_STRING_set( - data->eph_pub_key, eph_pub_key, eph_pub_key_len)) { - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting ephemeral Public Key of MSE:Set AT data"); - r = SC_ERROR_INTERNAL; - goto err; - } - } + r = sc_asn1_encode(ctx, capdu_eac_mse, &data, &data_len); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, r, "Error encoding MSE:Set AT APDU data"); - if (auxiliary_data && auxiliary_data_len) { - if (!d2i_ASN1_AUXILIARY_DATA(&data->auxiliary_data, &auxiliary_data, auxiliary_data_len)) { - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting authenticated auxiliary data of MSE:Set AT data"); + if (chat) { + encoded_chat_len = i2d_CVC_CHAT((CVC_CHAT *) chat, &encoded_chat); + if (encoded_chat_len < 0) { ssl_error(ctx); r = SC_ERROR_INTERNAL; goto err; } } - data->chat = (CVC_CHAT *) chat; - - length = i2d_EAC_MSE_C(data, &data_sequence); - data_no_sequence = data_sequence; - if (length < 0 - || (0x80 & ASN1_get_object(&data_no_sequence, &length, &tag, &class, length))) { - sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding MSE:Set AT APDU data"); - ssl_error(ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - if (length <= 0) { - r = SC_ERROR_INTERNAL; - goto err; - } - sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MSE command data", data_no_sequence, length); - - - p = realloc(*cdata, length); + p = realloc(*cdata, data_len + encoded_chat_len); if (!p) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } - memcpy(p, data_no_sequence, length); + memcpy(p, data, data_len); + memcpy(p+data_len, encoded_chat, encoded_chat_len); *cdata = p; - r = length; + r = data_len + encoded_chat_len; + + sc_debug_hex(ctx, SC_LOG_DEBUG_SM, "MSE command data", p, r); err: - if (data) { - /* do not free the functions parameter chat */ - data->chat = NULL; - EAC_MSE_C_free(data); - } - OPENSSL_free(data_sequence); + free(data); + if (encoded_chat) + OPENSSL_free(encoded_chat); return r; } @@ -525,7 +297,7 @@ static int eac_mse(sc_card_t *card, goto err; } - r = format_mse_cdata(card->ctx, protocol, key_reference1, + r = encode_mse_cdata(card->ctx, protocol, key_reference1, key_reference1_len, key_reference2, key_reference2_len, eph_pub_key, eph_pub_key_len, auxiliary_data, auxiliary_data_len, chat, &d); @@ -607,36 +379,113 @@ static int eac_mse_set_at_pace(sc_card_t *card, int protocol, } +/* + * General Authenticate + */ +static int encode_gen_auth_cdata(struct sc_context *ctx, + const unsigned char *ca_eph_pub_key, size_t ca_eph_pub_key_len, + const unsigned char *mapping_data, size_t mapping_data_len, + const unsigned char *eph_pub_key, size_t eph_pub_key_len, + const unsigned char *auth_token, size_t auth_token_len, + unsigned char **cdata) +{ + size_t data_len = 0; + int r; + + struct sc_asn1_entry capdu_eac_gen_auth_data[] = { + { "Ephemeral Public Key (CA)", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x00, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Mapping Data", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x01, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Ephemeral Public Key (PACE)", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x03, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Authentication Token", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x05, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + struct sc_asn1_entry capdu_eac_gen_auth[] = { + { "Dynamic Authentication Data", SC_ASN1_STRUCT, SC_ASN1_APP|SC_ASN1_CONS|0x1c, 0, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + if (!cdata) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } + + sc_format_asn1_entry(capdu_eac_gen_auth + 0, capdu_eac_gen_auth_data, &capdu_eac_gen_auth_data, 1); + + sc_format_asn1_entry(capdu_eac_gen_auth_data + 0, (unsigned char *) ca_eph_pub_key, &ca_eph_pub_key_len, ca_eph_pub_key && ca_eph_pub_key_len); + sc_format_asn1_entry(capdu_eac_gen_auth_data + 1, (unsigned char *) mapping_data, &mapping_data_len, mapping_data && mapping_data_len); + sc_format_asn1_entry(capdu_eac_gen_auth_data + 2, (unsigned char *) eph_pub_key, &eph_pub_key_len, eph_pub_key && eph_pub_key_len); + sc_format_asn1_entry(capdu_eac_gen_auth_data + 3, (unsigned char *) auth_token, &auth_token_len, auth_token && auth_token_len); + + r = sc_asn1_encode(ctx, capdu_eac_gen_auth, cdata, &data_len); + SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE, r, "Error encoding General Authenticate APDU data"); + r = data_len; + +err: + return r; +} +static int decode_gen_auth_rdata(struct sc_context *ctx, + const unsigned char *rdata, size_t rdata_len, + unsigned char **enc_nonce, size_t *enc_nonce_len, + unsigned char **mapping_data, size_t *mapping_data_len, + unsigned char **eph_pub_key, size_t *eph_pub_key_len, + unsigned char **auth_token, size_t *auth_token_len, + unsigned char **cur_car, size_t *cur_car_len, + unsigned char **prev_car, size_t *prev_car_len) +{ + struct sc_asn1_entry rapdu_eac_gen_auth_data[] = { + { "Encrypted Nonce", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x00, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Mapping Data", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x02, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Ephemeral Public Key", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x04, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Authentication Token", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x06, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Most recent Certification Authority Reference", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Pverious recent Certification Authority Reference", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + struct sc_asn1_entry rapdu_eac_gen_auth[] = { + { "Dynamic Authentication Data", SC_ASN1_STRUCT, SC_ASN1_APP|SC_ASN1_CONS|0x1c, 0, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + sc_format_asn1_entry(rapdu_eac_gen_auth + 0, rapdu_eac_gen_auth_data, &rapdu_eac_gen_auth_data, 1); + + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 0, enc_nonce, enc_nonce_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 1, mapping_data, mapping_data_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 2, eph_pub_key, eph_pub_key_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 3, auth_token, auth_token_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 4, cur_car, cur_car_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_data + 5, prev_car, prev_car_len, 0); + + return sc_asn1_decode(ctx, rapdu_eac_gen_auth, rdata, rdata_len, NULL, NULL); +} #define ISO_GENERAL_AUTHENTICATE 0x86 #define ISO_COMMAND_CHAINING 0x10 static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, u8 **enc_nonce, size_t *enc_nonce_len) { sc_apdu_t apdu; - EAC_GEN_AUTH_PACE_C *c_data = NULL; - EAC_GEN_AUTH_PACE_R *r_data = NULL; - unsigned char *d = NULL, *p; - int r, l; + unsigned char *d = NULL; + int r; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; - c_data = EAC_GEN_AUTH_PACE_C_new(); - if (!c_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); - if (r < 0) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + r = encode_gen_auth_cdata(card->ctx, NULL, 0, NULL, 0, NULL, 0, NULL, 0, &d); + if (r < 0) goto err; - } - sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) command data", apdu.data, apdu.datalen); - r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -644,45 +493,16 @@ static int eac_gen_auth_1_encrypted_nonce(sc_card_t *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (r < 0) goto err; - - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Encrypted Nonce) response data", apdu.resp, apdu.resplen); - - if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, - (const unsigned char **) &apdu.resp, apdu.resplen)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - if (!r_data->enc_nonce - || r_data->mapping_data - || r_data->eph_pub_key - || r_data->auth_token - || r_data->cur_car - || r_data->prev_car) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for " - "step 1 should (only) contain the encrypted nonce."); - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - goto err; - } - p = r_data->enc_nonce->data; - l = r_data->enc_nonce->length; - - *enc_nonce = malloc(l); - if (!*enc_nonce) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*enc_nonce, p, l); - *enc_nonce_len = l; + r = decode_gen_auth_rdata(card->ctx, apdu.resp, apdu.resplen, + enc_nonce, enc_nonce_len, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL); err: - if (c_data) - EAC_GEN_AUTH_PACE_C_free(c_data); - OPENSSL_free(d); - if (r_data) - EAC_GEN_AUTH_PACE_R_free(r_data); + free(d); return r; } @@ -691,37 +511,17 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, u8 **map_data_out, size_t *map_data_out_len) { sc_apdu_t apdu; - EAC_GEN_AUTH_PACE_C *c_data = NULL; - EAC_GEN_AUTH_PACE_R *r_data = NULL; - unsigned char *d = NULL, *p; - int r, l; + unsigned char *d = NULL; + int r; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; - c_data = EAC_GEN_AUTH_PACE_C_new(); - if (!c_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - c_data->mapping_data = ASN1_OCTET_STRING_new(); - if (!c_data->mapping_data - || !ASN1_OCTET_STRING_set( - c_data->mapping_data, in, in_len)) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); - if (r < 0) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + r = encode_gen_auth_cdata(card->ctx, NULL, 0, in, in_len, NULL, 0, NULL, 0, &d); + if (r < 0) goto err; - } sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Map Nonce) command data", apdu.data, apdu.datalen); - r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -730,44 +530,16 @@ static int eac_gen_auth_2_map_nonce(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Map Nonce) response data", apdu.resp, apdu.resplen); - - if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, - (const unsigned char **) &apdu.resp, apdu.resplen)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - if (r_data->enc_nonce - || !r_data->mapping_data - || r_data->eph_pub_key - || r_data->auth_token - || r_data->cur_car - || r_data->prev_car) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for " - "step 2 should (only) contain the mapping data."); - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - goto err; - } - p = r_data->mapping_data->data; - l = r_data->mapping_data->length; - - *map_data_out = malloc(l); - if (!*map_data_out) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*map_data_out, p, l); - *map_data_out_len = l; + r = decode_gen_auth_rdata(card->ctx, apdu.resp, apdu.resplen, + NULL, NULL, + map_data_out, map_data_out_len, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL); err: - if (c_data) - EAC_GEN_AUTH_PACE_C_free(c_data); - OPENSSL_free(d); - if (r_data) - EAC_GEN_AUTH_PACE_R_free(r_data); + free(d); return r; } @@ -776,37 +548,17 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, u8 **eph_pub_key_out, size_t *eph_pub_key_out_len) { sc_apdu_t apdu; - EAC_GEN_AUTH_PACE_C *c_data = NULL; - EAC_GEN_AUTH_PACE_R *r_data = NULL; - unsigned char *d = NULL, *p; - int r, l; + unsigned char *d = NULL; + int r; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; - c_data = EAC_GEN_AUTH_PACE_C_new(); - if (!c_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - c_data->eph_pub_key = ASN1_OCTET_STRING_new(); - if (!c_data->eph_pub_key - || !ASN1_OCTET_STRING_set( - c_data->eph_pub_key, in, in_len)) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); - if (r < 0) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + r = encode_gen_auth_cdata(card->ctx, NULL, 0, NULL, 0, in, in_len, NULL, 0, &d); + if (r < 0) goto err; - } sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); apdu.cla = ISO_COMMAND_CHAINING; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -815,85 +567,36 @@ static int eac_gen_auth_3_perform_key_agreement(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - - if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, - (const unsigned char **) &apdu.resp, apdu.resplen)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - if (r_data->enc_nonce - || r_data->mapping_data - || !r_data->eph_pub_key - || r_data->auth_token - || r_data->cur_car - || r_data->prev_car) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for " - "step 3 should (only) contain the ephemeral public key."); - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - goto err; - } - p = r_data->eph_pub_key->data; - l = r_data->eph_pub_key->length; - - *eph_pub_key_out = malloc(l); - if (!*eph_pub_key_out) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*eph_pub_key_out, p, l); - *eph_pub_key_out_len = l; + r = decode_gen_auth_rdata(card->ctx, apdu.resp, apdu.resplen, + NULL, NULL, + NULL, NULL, + eph_pub_key_out, eph_pub_key_out_len, + NULL, NULL, + NULL, NULL, + NULL, NULL); err: - if (c_data) - EAC_GEN_AUTH_PACE_C_free(c_data); - OPENSSL_free(d); - if (r_data) - EAC_GEN_AUTH_PACE_R_free(r_data); + free(d); return r; } static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, const u8 *in, size_t in_len, u8 **auth_token_out, size_t *auth_token_out_len, - u8 **recent_car, size_t *recent_car_len, - u8 **prev_car, size_t *prev_car_len) + u8 **recent_car_out, size_t *recent_car_len, + u8 **prev_car_out, size_t *prev_car_len) { sc_apdu_t apdu; - EAC_GEN_AUTH_PACE_C *c_data = NULL; - EAC_GEN_AUTH_PACE_R *r_data = NULL; - unsigned char *d = NULL, *p; - int r, l; + unsigned char *d = NULL; + int r; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; - c_data = EAC_GEN_AUTH_PACE_C_new(); - if (!c_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - c_data->auth_token = ASN1_OCTET_STRING_new(); - if (!c_data->auth_token - || !ASN1_OCTET_STRING_set( - c_data->auth_token, in, in_len)) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - r = i2d_EAC_GEN_AUTH_PACE_C(c_data, &d); - if (r < 0) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + r = encode_gen_auth_cdata(card->ctx, NULL, 0, NULL, 0, NULL, 0, in, in_len, &d); + if (r < 0) goto err; - } - sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0x00, 0x00, d, r, resp, sizeof resp); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -902,66 +605,16 @@ static int eac_gen_auth_4_mutual_authentication(sc_card_t *card, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - - if (!d2i_EAC_GEN_AUTH_PACE_R(&r_data, - (const unsigned char **) &apdu.resp, apdu.resplen)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; - goto err; - } - - if (r_data->enc_nonce - || r_data->mapping_data - || r_data->eph_pub_key - || !r_data->auth_token) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for " - "step 4 should (only) contain the authentication token."); - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; - goto err; - } - p = r_data->auth_token->data; - l = r_data->auth_token->length; - if (r_data->cur_car) { - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Most recent Certificate Authority Reference", - r_data->cur_car->data, r_data->cur_car->length); - *recent_car = malloc(r_data->cur_car->length); - if (!*recent_car) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*recent_car, r_data->cur_car->data, r_data->cur_car->length); - *recent_car_len = r_data->cur_car->length; - } else - *recent_car_len = 0; - if (r_data->prev_car) { - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "Previous Certificate Authority Reference", - r_data->prev_car->data, r_data->prev_car->length); - *prev_car = malloc(r_data->prev_car->length); - if (!*prev_car) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*prev_car, r_data->prev_car->data, r_data->prev_car->length); - *prev_car_len = r_data->prev_car->length; - } else - *prev_car_len = 0; - - *auth_token_out = malloc(l); - if (!*auth_token_out) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - memcpy(*auth_token_out, p, l); - *auth_token_out_len = l; + r = decode_gen_auth_rdata(card->ctx, apdu.resp, apdu.resplen, + NULL, NULL, + NULL, NULL, + NULL, NULL, + auth_token_out, auth_token_out_len, + recent_car_out, recent_car_len, + prev_car_out, prev_car_len); err: - if (c_data) - EAC_GEN_AUTH_PACE_C_free(c_data); - OPENSSL_free(d); - if (r_data) - EAC_GEN_AUTH_PACE_R_free(r_data); + free(d); return r; } @@ -1658,40 +1311,50 @@ static int eac_mse_set_at_ca(sc_card_t *card, int protocol) NULL, 0, NULL, NULL, NULL); } +static int decode_gen_auth_ca_rdata(struct sc_context *ctx, + const unsigned char *rdata, size_t rdata_len, + unsigned char **nonce, size_t *enc_nonce_len, + unsigned char **auth_token, size_t *auth_token_len) +{ + struct sc_asn1_entry rapdu_eac_gen_auth_ca_data[] = { + { "Nonce", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x01, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { "Authentication Token", + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x02, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + struct sc_asn1_entry rapdu_eac_gen_auth_ca[] = { + { "Dynamic Authentication Data", SC_ASN1_STRUCT, SC_ASN1_APP|SC_ASN1_CONS|0x1c, 0, NULL, NULL }, + { NULL , 0 , 0 , 0 , NULL , NULL } + }; + + sc_format_asn1_entry(rapdu_eac_gen_auth_ca + 0, rapdu_eac_gen_auth_ca_data, &rapdu_eac_gen_auth_ca_data, 1); + + sc_format_asn1_entry(rapdu_eac_gen_auth_ca_data + 0, nonce, enc_nonce_len, 0); + sc_format_asn1_entry(rapdu_eac_gen_auth_ca_data + 1, auth_token, auth_token_len, 0); + + return sc_asn1_decode(ctx, rapdu_eac_gen_auth_ca, rdata, rdata_len, NULL, NULL); +} static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, BUF_MEM **nonce, BUF_MEM **token) { sc_apdu_t apdu; - EAC_GEN_AUTH_CA_C *c_data = NULL; - EAC_GEN_AUTH_CA_R *r_data = NULL; - unsigned char *d = NULL; + unsigned char *d = NULL, *p, *q; int r; unsigned char resp[SC_MAX_APDU_RESP_SIZE]; + BUF_MEM *nonce_out = NULL, *token_out = NULL; - c_data = EAC_GEN_AUTH_CA_C_new(); - if (!c_data) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - c_data->eph_pub_key = ASN1_OCTET_STRING_new(); - if (!c_data->eph_pub_key - || !ASN1_OCTET_STRING_set(c_data->eph_pub_key, - (const unsigned char *) eph_pub_key->data, - eph_pub_key->length)) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + if (!eph_pub_key) { + r = SC_ERROR_INVALID_ARGUMENTS; goto err; } - r = i2d_EAC_GEN_AUTH_CA_C(c_data, &d); - if (r < 0) { - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + + r = encode_gen_auth_cdata(card->ctx, (unsigned char *) eph_pub_key->data, eph_pub_key->length, NULL, 0, NULL, 0, NULL, 0, &d); + if (r < 0) goto err; - } sc_format_apdu_ex(&apdu, 0x00, ISO_GENERAL_AUTHENTICATE, 0, 0, d, r, resp, sizeof resp); - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) command data", apdu.data, apdu.datalen); - r = sc_transmit_apdu(card, &apdu); if (r < 0) goto err; @@ -1700,42 +1363,36 @@ static int eac_gen_auth_ca(sc_card_t *card, const BUF_MEM *eph_pub_key, if (r < 0) goto err; - sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "General authenticate (Perform Key Agreement) response data", apdu.resp, apdu.resplen); - - if (!d2i_EAC_GEN_AUTH_CA_R(&r_data, - (const unsigned char **) &apdu.resp, apdu.resplen)) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse general authenticate response data."); - ssl_error(card->ctx); - r = SC_ERROR_INTERNAL; + nonce_out = BUF_MEM_new(); + token_out = BUF_MEM_new(); + if (!nonce_out || !token_out) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; goto err; } - if (!r_data->nonce || !r_data->auth_token) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Response data of general authenticate for CA" - "should contain the nonce and the authentication token."); - r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + p = (u8 *) nonce_out->data; + q = (u8 *) token_out->data; + r = decode_gen_auth_ca_rdata(card->ctx, apdu.resp, apdu.resplen, + &p, &nonce_out->length, + &q, &token_out->length); + nonce_out->data = (char *) p; + token_out->data = (char *) q; + if (r < 0) goto err; - } if (*nonce) BUF_MEM_free(*nonce); - *nonce = BUF_MEM_create_init(r_data->nonce->data, - r_data->nonce->length); if (*token) BUF_MEM_free(*token); - *token = BUF_MEM_create_init(r_data->auth_token->data, - r_data->auth_token->length); - if (!*nonce || !*token) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } + *nonce = nonce_out; + *token = token_out; + nonce_out = NULL; + token_out = NULL; err: - if (c_data) - EAC_GEN_AUTH_CA_C_free(c_data); - if (r_data) - EAC_GEN_AUTH_CA_R_free(r_data); - OPENSSL_free(d); + BUF_MEM_free(nonce_out); + BUF_MEM_free(token_out); + free(d); return r; } From c45aa4bb00d009972efcc9cb0867556e8c2a93be Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Jan 2023 02:33:56 +0100 Subject: [PATCH 2710/4321] sm-eac: removed certificate description from sm context certificate description has no long term use anymore --- src/sm/sm-eac.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 71b3cf0020..826f78312e 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -57,8 +57,6 @@ char eac_default_flags = 0; struct eac_sm_ctx { /** @brief EAC context */ EAC_CTX *ctx; - /** @brief Certificate Description given on initialization of PACE */ - BUF_MEM *certificate_description; /** @brief picc's compressed ephemeral public key of PACE */ BUF_MEM *id_icc; /** @brief PCD's compressed ephemeral public key of CA */ @@ -95,8 +93,7 @@ static void eac_sm_clear_free(const struct iso_sm_ctx *ctx); static struct eac_sm_ctx * -eac_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, - size_t certificate_description_length, +eac_sm_ctx_create(EAC_CTX *ctx, const unsigned char *id_icc, size_t id_icc_length) { struct eac_sm_ctx *out = malloc(sizeof *out); @@ -105,15 +102,6 @@ eac_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, out->ctx = ctx; - if (certificate_description && certificate_description_length) { - out->certificate_description = - BUF_MEM_create_init(certificate_description, - certificate_description_length); - if (!out->certificate_description) - goto err; - } else - out->certificate_description = NULL; - if (id_icc && id_icc_length) { out->id_icc = BUF_MEM_create_init(id_icc, id_icc_length); if (!out->id_icc) @@ -139,8 +127,6 @@ eac_sm_ctx_create(EAC_CTX *ctx, const unsigned char *certificate_description, static int eac_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, - const unsigned char *certificate_description, - size_t certificate_description_length, const unsigned char *id_icc, size_t id_icc_length) { int r; @@ -158,7 +144,6 @@ eac_sm_start(sc_card_t *card, EAC_CTX *eac_ctx, } sctx->priv_data = eac_sm_ctx_create(eac_ctx, - certificate_description, certificate_description_length, id_icc, id_icc_length); if (!sctx->priv_data) { r = SC_ERROR_OUT_OF_MEMORY; @@ -977,9 +962,7 @@ int perform_pace(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "ID PCD", pace_output->id_pcd, pace_output->id_pcd_length); - r = eac_sm_start(card, eac_ctx, pace_input.certificate_description, - pace_input.certificate_description_length, pace_output->id_icc, - pace_output->id_icc_length); + r = eac_sm_start(card, eac_ctx, pace_output->id_icc, pace_output->id_icc_length); } err: @@ -1181,7 +1164,7 @@ int perform_terminal_authentication(sc_card_t *card, goto err; } - isosmctx->priv_data = eac_sm_ctx_create(eac_ctx, NULL, 0, NULL, 0); + isosmctx->priv_data = eac_sm_ctx_create(eac_ctx, NULL, 0); if (!isosmctx->priv_data) { r = SC_ERROR_INTERNAL; goto err; @@ -1520,7 +1503,7 @@ int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx, } if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - r = eac_sm_start(card, ctx, NULL, 0, NULL, 0); + r = eac_sm_start(card, ctx, NULL, 0); } err: @@ -1788,8 +1771,6 @@ eac_sm_clear_free(const struct iso_sm_ctx *ctx) struct eac_sm_ctx *eacsmctx = ctx->priv_data; if (eacsmctx) { EAC_CTX_clear_free(eacsmctx->ctx); - if (eacsmctx->certificate_description) - BUF_MEM_free(eacsmctx->certificate_description); if (eacsmctx->id_icc) BUF_MEM_free(eacsmctx->id_icc); if (eacsmctx->eph_pub_key) From 7e30ecc09356fbb0aee05a547ae6879a441d5eff Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Jan 2023 02:35:35 +0100 Subject: [PATCH 2711/4321] sm-eac: avoid modifying card capabilities opensc is now patched with all necessities in order to avoid this hack --- src/sm/sm-eac.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 826f78312e..4ca94a3506 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -53,7 +53,7 @@ char eac_default_flags = 0; #include -/** @brief NPA secure messaging context */ +/** @brief EAC secure messaging context */ struct eac_sm_ctx { /** @brief EAC context */ EAC_CTX *ctx; @@ -1147,12 +1147,6 @@ int perform_terminal_authentication(sc_card_t *card, sc_debug_hex(card->ctx, SC_LOG_DEBUG_SM, "EF.CardAccess", ef_cardaccess, ef_cardaccess_length); - /* XXX Card capabilities should be determined by the OpenSC card driver. We - * set it here to be able to use the nPA without patching OpenSC. By - * now we have read the EF.CardAccess so the assumption to have an nPA - * seems valid. */ - card->caps |= SC_CARD_CAP_APDU_EXT; - EAC_init(); eac_ctx = EAC_CTX_new(); if (!eac_ctx From 023aa0de982bd1d1f402bc698c5bd95cac8cf1fa Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Jan 2023 11:24:34 +0100 Subject: [PATCH 2712/4321] fixed missing AC_SUBST for pkcs11-register flag --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index d7d9cb6be3..03b546f8a3 100644 --- a/configure.ac +++ b/configure.ac @@ -1074,6 +1074,7 @@ AC_SUBST([WIN_LIBPREFIX]) AC_SUBST([DEFAULT_PCSC_PROVIDER]) AC_SUBST([DEFAULT_PKCS11_PROVIDER]) AC_SUBST([DEFAULT_ONEPIN_PKCS11_PROVIDER]) +AC_SUBST([PKCS11_REGISTER_SKIP_FIREFOX]) AC_SUBST([OPTIONAL_ZLIB_CFLAGS]) AC_SUBST([OPTIONAL_ZLIB_LIBS]) AC_SUBST([OPTIONAL_READLINE_CFLAGS]) From f2497d97f406a2810de9cbeaea5117cbc0d7eed8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 9 Jan 2023 11:43:27 +0100 Subject: [PATCH 2713/4321] fixed accepting parameters (files) to opensc-asn1 commandline --- src/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 1d6589225f..f9ce5bf2ea 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -142,7 +142,7 @@ endif cmdline: @for f in *.ggo.in; do $(do_subst) < "$$f" > "$${f%.in}"; done @for f in *.ggo; do $(GENGETOPT) --file-name="$${f%.ggo}-cmdline" --output-dir=$(builddir) < "$$f"; done - $(AM_V_GEN)$(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) < opensc-asn1.ggo --unamed-opts + $(AM_V_GEN)$(GENGETOPT) --file-name=opensc-asn1-cmdline --output-dir=$(builddir) --unamed-opts < opensc-asn1.ggo if WIN32 LIBS += -lshlwapi From 945b692cb61e7248e76fccf9fdac7186d8cc3e77 Mon Sep 17 00:00:00 2001 From: Philip Wendland Date: Mon, 26 Oct 2015 20:54:49 +0100 Subject: [PATCH 2714/4321] IsoApplet: Obtain applet info using GET DATA In previous versions of IsoApplet, the applet returned the applet version and feature bitmap upon selection. However, this special select command leads to problems with cards that were until now not tested. In future versions of IsoApplet, the behavior will change: - The Select APDU is a normal case 3 apdu - Applet info is obtained using a seperate GET DATA apdu. --- src/libopensc/card-isoApplet.c | 123 ++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index d7656f8eea..7ed96d62dc 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -32,14 +32,12 @@ #define ISOAPPLET_ALG_REF_ECDSA 0x21 #define ISOAPPLET_ALG_REF_RSA_PAD_PKCS1 0x11 -#define ISOAPPLET_API_VERSION_MAJOR 0x00 -#define ISOAPPLET_API_VERSION_MINOR 0x06 +#define ISOAPPLET_VERSION 0x0006 #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 #define ISOAPPLET_API_FEATURE_ECC 0x04 -#define ISOAPPLET_AID_LEN 12 static const u8 isoApplet_aid[] = {0xf2,0x76,0xa2,0x88,0xbc,0xfb,0xa6,0x9d,0x34,0xf3,0x10,0x01}; struct isoApplet_drv_data @@ -52,6 +50,7 @@ struct isoApplet_drv_data unsigned int sec_env_alg_ref; unsigned int sec_env_ec_field_length; unsigned int isoapplet_version; + unsigned int isoapplet_features; }; #define DRVDATA(card) ((struct isoApplet_drv_data *) ((card)->drv_data)) @@ -96,8 +95,6 @@ static struct isoapplet_supported_ec_curves { * @param[in] card * @param[in] aid The applet ID. * @param[in] aid_len The length of aid. - * @param[out] resp The response of the applet upon selection. - * @param[in,out] resp_len In: The buffer size of resp. Out: The length of the response. * * @return SC_SUCCESS: The applet is present and could be selected. * any other: Transmit failure or the card returned an error. @@ -105,7 +102,7 @@ static struct isoapplet_supported_ec_curves { * not present. */ static int -isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len, u8 *resp, size_t *resp_len) +isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len) { int rv; sc_context_t *ctx = card->ctx; @@ -120,9 +117,6 @@ isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len, u8 apdu.lc = aid_len; apdu.data = aid; apdu.datalen = aid_len; - apdu.resp = resp; - apdu.resplen = *resp_len; - apdu.le = 0; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, rv, "APDU transmit failure."); @@ -130,7 +124,6 @@ isoApplet_select_applet(sc_card_t *card, const u8 *aid, const size_t aid_len, u8 rv = sc_check_sw(card, apdu.sw1, apdu.sw2); LOG_TEST_RET(card->ctx, rv, "Card returned error"); - *resp_len = apdu.resplen; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -151,53 +144,69 @@ isoApplet_finish(sc_card_t *card) static int isoApplet_match_card(sc_card_t *card) { - size_t rlen = SC_MAX_APDU_BUFFER_SIZE; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int rv; - rv = isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen); - + rv = isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); if(rv != SC_SUCCESS) { return 0; } - /* The IsoApplet should return an API version (major and minor) and a feature bitmap. - * We expect 3 bytes: MAJOR API version - MINOR API version - API feature bitmap. - * If applet does not return API version, versions 0x00 will match */ - if(rlen < 3) - { - assert(sizeof(rbuf) >= 3); - memset(rbuf, 0x00, 3); - } + return 1; +} - if(rbuf[0] != ISOAPPLET_API_VERSION_MAJOR) - { - sc_log(card->ctx, "IsoApplet: Mismatching major API version. Not proceeding. " - "API versions: Driver (%02X-%02X), applet (%02X-%02X). Please update accordingly.", - ISOAPPLET_API_VERSION_MAJOR, ISOAPPLET_API_VERSION_MINOR, rbuf[0], rbuf[1]); - return 0; +static int +isoApplet_get_info(sc_card_t * card, struct isoApplet_drv_data * drvdata) { + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + sc_apdu_t apdu; + int rv; + sc_context_t * ctx = card->ctx; + + /* Get response with P1P2 proprietary (get applet version and features) */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x01); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, rv, "APDU transmit faiure."); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + if(rv < 0) { + if(apdu.sw1 == 0x6D && apdu.sw2 == 0x00) { + /* INS not supported. This is an older IsoApplet that might return the + * applet information upon selection. For backward compatibility, try this. */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); + apdu.lc = sizeof(isoApplet_aid); + apdu.data = isoApplet_aid; + apdu.datalen = sizeof(isoApplet_aid); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, rv, "APDU transmit faiure."); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(ctx, rv, "Error selecting applet."); + } else { + LOG_TEST_RET(ctx, rv, "Card returned error."); + } } - if(rbuf[1] != ISOAPPLET_API_VERSION_MINOR) + /* Fill up drvdata */ + if(apdu.resplen >= 3) { - sc_log(card->ctx, "IsoApplet: Mismatching minor API version. Proceeding anyway. " - "API versions: Driver (%02X-%02X), applet (%02X-%02X). " - "Please update accordingly whenever possible.", - ISOAPPLET_API_VERSION_MAJOR, ISOAPPLET_API_VERSION_MINOR, rbuf[0], rbuf[1]); + drvdata->isoapplet_version = apdu.resp[0] << 8 | apdu.resp[1]; + drvdata->isoapplet_features = apdu.resp[2]; } - return 1; + return SC_SUCCESS; } static int isoApplet_init(sc_card_t *card) { - int i; + int i, r; unsigned long flags = 0; unsigned long ext_flags = 0; - size_t rlen = SC_MAX_APDU_BUFFER_SIZE; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; struct isoApplet_drv_data *drvdata; LOG_FUNC_CALLED(card->ctx); @@ -210,22 +219,30 @@ isoApplet_init(sc_card_t *card) card->cla = 0x00; /* Obtain applet version and specific features */ - if (0 > isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen)) { - free(card->drv_data); - card->drv_data = NULL; - LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Error obtaining applet version."); + r = isoApplet_get_info(card, drvdata); + LOG_TEST_RET(card->ctx, r, "Error obtaining information about applet."); + + if((drvdata->isoapplet_version & 0xFF00) != (ISOAPPLET_VERSION & 0xFF00)) + { + sc_log(card->ctx, "IsoApplet: Mismatching major API version. Not proceeding. " + "API versions: Driver (%04X), applet (%04X). Please update accordingly.", + ISOAPPLET_VERSION, drvdata->isoapplet_version); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } - if(rlen < 3) + else if(drvdata->isoapplet_version != ISOAPPLET_VERSION) { - assert(sizeof(rbuf) >= 3); - memset(rbuf, 0x00, 3); + sc_log(card->ctx, "IsoApplet: Mismatching minor version. Proceeding anyway. " + "API versions: Driver (%04X), applet (%04X)." + "Please update accordingly whenever possible.", + ISOAPPLET_VERSION, drvdata->isoapplet_version); } - drvdata->isoapplet_version = ((unsigned int)rbuf[0] << 8) | rbuf[1]; - if(rbuf[2] & ISOAPPLET_API_FEATURE_EXT_APDU) - card->caps |= SC_CARD_CAP_APDU_EXT; - if(rbuf[2] & ISOAPPLET_API_FEATURE_SECURE_RANDOM) - card->caps |= SC_CARD_CAP_RNG; - if(drvdata->isoapplet_version <= 0x0005 || rbuf[2] & ISOAPPLET_API_FEATURE_ECC) + + if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_EXT_APDU) + card->caps |= SC_CARD_CAP_APDU_EXT; + if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_SECURE_RANDOM) + card->caps |= SC_CARD_CAP_RNG; + if(drvdata->isoapplet_version <= 0x0005 + || drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_ECC) { /* There are Java Cards that do not support ECDSA at all. The IsoApplet * started to report this with version 00.06. @@ -237,7 +254,7 @@ isoApplet_init(sc_card_t *card) flags |= SC_ALGORITHM_ECDSA_HASH_SHA1; flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_UNCOMPRESES; - ext_flags |= SC_ALGORITHM_EXT_EC_NAMEDCURVE; + ext_flags |= SC_ALGORITHM_EXT_EC_NAMEDCURVE; ext_flags |= SC_ALGORITHM_EXT_EC_F_P; for (i=0; ec_curves[i].oid.value[0] >= 0; i++) { @@ -1236,9 +1253,7 @@ static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (was_reset > 0) { - size_t rlen = SC_MAX_APDU_BUFFER_SIZE; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - r = isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen); + r = isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); } LOG_FUNC_RETURN(card->ctx, r); From 1e606bc884cee466e79e3bf99bc91caf935d03d8 Mon Sep 17 00:00:00 2001 From: Philip Wendland Date: Tue, 19 May 2020 20:56:50 +0200 Subject: [PATCH 2715/4321] isoApplet: add RSA PSS features if supported by applet --- src/libopensc/card-isoApplet.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 7ed96d62dc..10c1ee620a 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -37,6 +37,8 @@ #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 #define ISOAPPLET_API_FEATURE_ECC 0x04 +#define ISOAPPLET_API_FEATURE_RSA_SHA256_PSS 0x08 +#define ISOAPPLET_API_FEATURE_RSA_SHA512_PSS 0x10 static const u8 isoApplet_aid[] = {0xf2,0x76,0xa2,0x88,0xbc,0xfb,0xa6,0x9d,0x34,0xf3,0x10,0x01}; @@ -265,6 +267,14 @@ isoApplet_init(sc_card_t *card) /* RSA */ flags = 0; + if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA256_PSS) { + flags |= SC_ALGORITHM_RSA_PAD_PSS; + flags |= SC_ALGORITHM_RSA_HASH_SHA256; + } + if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA512_PSS) { + flags |= SC_ALGORITHM_RSA_PAD_PSS; + flags |= SC_ALGORITHM_RSA_HASH_SHA512; + } /* Padding schemes: */ flags |= SC_ALGORITHM_RSA_PAD_PKCS1; /* Hashes are to be done by the host for RSA */ From 3f4c4dd7acd8d113256550c4a28a495bb6977295 Mon Sep 17 00:00:00 2001 From: Philip Wendland Date: Wed, 10 Jun 2020 21:24:01 +0200 Subject: [PATCH 2716/4321] isoApplet: announce PSS capabilities --- src/libopensc/card-isoApplet.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 10c1ee620a..707c3a4391 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -31,6 +31,8 @@ #define ISOAPPLET_ALG_REF_ECDSA 0x21 #define ISOAPPLET_ALG_REF_RSA_PAD_PKCS1 0x11 +#define ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS 0x12 +#define ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS 0x13 #define ISOAPPLET_VERSION 0x0006 @@ -267,18 +269,17 @@ isoApplet_init(sc_card_t *card) /* RSA */ flags = 0; + flags |= SC_ALGORITHM_RSA_PAD_PKCS1; + flags |= SC_ALGORITHM_RSA_HASH_NONE; + flags |= SC_ALGORITHM_RSA_HASH_SHA256; if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA256_PSS) { flags |= SC_ALGORITHM_RSA_PAD_PSS; - flags |= SC_ALGORITHM_RSA_HASH_SHA256; + flags |= SC_ALGORITHM_MGF1_SHA256; } if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA512_PSS) { flags |= SC_ALGORITHM_RSA_PAD_PSS; - flags |= SC_ALGORITHM_RSA_HASH_SHA512; + flags |= SC_ALGORITHM_MGF1_SHA512; } - /* Padding schemes: */ - flags |= SC_ALGORITHM_RSA_PAD_PKCS1; - /* Hashes are to be done by the host for RSA */ - flags |= SC_ALGORITHM_RSA_HASH_NONE; /* Key-generation: */ flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; /* Modulus lengths: */ @@ -1135,9 +1136,17 @@ isoApplet_set_security_env(sc_card_t *card, { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_PAD_PKCS1; } + else if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS && env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256 ) + { + drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS; + } + else if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS && env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA512 ) + { + drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS; + } else { - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports RSA with PKCS1 padding."); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet does not support requested padding/hash combination"); } break; From 51182a268cc4bea90d1c86ba0aa55993cc1d3bf2 Mon Sep 17 00:00:00 2001 From: swissbit-okaufmann <110035298+swissbit-okaufmann@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:30:00 +0200 Subject: [PATCH 2717/4321] IsoApplet: create hash off card to support more ECDSA mechanisms Use IsoApplet version 1.0 which no longer computes the hash on card. The previous version of the IsoApplet only supported ECDSA-SHA1. With supports also ECDSA, ECDSA-SHA224, ECDSA-SHA256, ECDSA-SHA384, ECDSA-SHA512. Co-authored-by: Claus Steuer --- .github/build.sh | 2 +- .github/test-isoapplet.sh | 9 ++-- src/libopensc/card-isoApplet.c | 33 +++++++++----- src/tests/p11test/isoapplet_ref.json | 65 ++++++++++++++++++++++++++-- src/tools/pkcs11-tool.c | 2 +- 5 files changed, 91 insertions(+), 20 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index c1fd2df7ff..ca73d3d45c 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -6,7 +6,7 @@ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$GITHUB_BASE_REF" == "master" ]; then + if [ "$GITHUB_BASE_REF" == "swissbit-master" ]; then ./bootstrap.ci -s "-pr$PR_NUMBER" else ./bootstrap.ci -s "$GITHUB_BASE_REF-pr$PR_NUMBER" diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 5a4e03a02e..10d22aceb1 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -11,7 +11,7 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git + git clone https://github.com/swissbit-eis/IsoApplet.git # enable IsoApplet key import patch sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i IsoApplet/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java fi @@ -65,7 +65,7 @@ pkcs11-tool -l -t -p 123456 # run the tests pushd src/tests/p11test/ sleep 5 -./p11test -s 0 -p 123456 -o isoapplet.json || true # ec_sign_size_test is failing here +./p11test -s 0 -p 123456 -o isoapplet.json popd # random data to be signed @@ -85,4 +85,7 @@ rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig kill -9 $PID -diff -u3 src/tests/p11test/isoapplet{_ref,}.json +if ! diff -u3 src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref.json; then + echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." + exit 1 +fi diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 707c3a4391..7f574947d3 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -34,7 +34,7 @@ #define ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS 0x12 #define ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS 0x13 -#define ISOAPPLET_VERSION 0x0006 +#define ISOAPPLET_VERSION 0x0100 #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 @@ -157,7 +157,7 @@ isoApplet_match_card(sc_card_t *card) } return 1; -} + } static int isoApplet_get_info(sc_card_t * card, struct isoApplet_drv_data * drvdata) { @@ -242,9 +242,9 @@ isoApplet_init(sc_card_t *card) } if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_EXT_APDU) - card->caps |= SC_CARD_CAP_APDU_EXT; + card->caps |= SC_CARD_CAP_APDU_EXT; if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_SECURE_RANDOM) - card->caps |= SC_CARD_CAP_RNG; + card->caps |= SC_CARD_CAP_RNG; if(drvdata->isoapplet_version <= 0x0005 || drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_ECC) { @@ -255,10 +255,11 @@ isoApplet_init(sc_card_t *card) * should be kept in sync with the explicit parameters in the pkcs15-init * driver. */ flags = 0; - flags |= SC_ALGORITHM_ECDSA_HASH_SHA1; + flags |= SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDSA_HASH_NONE; flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_UNCOMPRESES; - ext_flags |= SC_ALGORITHM_EXT_EC_NAMEDCURVE; + ext_flags |= SC_ALGORITHM_EXT_EC_NAMEDCURVE; ext_flags |= SC_ALGORITHM_EXT_EC_F_P; for (i=0; ec_curves[i].oid.value[0] >= 0; i++) { @@ -1151,14 +1152,14 @@ isoApplet_set_security_env(sc_card_t *card, break; case SC_ALGORITHM_EC: - if( env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1 ) + if( env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW ) { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; drvdata->sec_env_ec_field_length = env->algorithm_ref; } else { - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports ECDSA with on-card SHA1."); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports raw ECDSA."); } break; @@ -1214,11 +1215,16 @@ isoApplet_compute_signature(struct sc_card *card, { struct sc_context *ctx = card->ctx; struct isoApplet_drv_data *drvdata = DRVDATA(card); + /* No more than 256 byte are needed for the signature. The IsoApplet + * supports no larger key sizes than for RSA-2048 or EC:secp384r1 leading + * to 256 byte or 104 byte, respectively, in ASN.1 sequence. */ + static u8 seqbuf[256]; + size_t seqlen = sizeof(seqbuf); int r; LOG_FUNC_CALLED(ctx); - r = iso_ops->compute_signature(card, data, datalen, out, outlen); + r = iso_ops->compute_signature(card, data, datalen, seqbuf, seqlen); if(r < 0) { LOG_FUNC_RETURN(ctx, r); @@ -1231,21 +1237,24 @@ isoApplet_compute_signature(struct sc_card *card, u8* p = NULL; size_t len = (drvdata->sec_env_ec_field_length + 7) / 8 * 2; - if (len > outlen) + if (len > seqlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); p = calloc(1,len); if (!p) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - r = sc_asn1_sig_value_sequence_to_rs(ctx, out, r, p, len); + r = sc_asn1_sig_value_sequence_to_rs(ctx, seqbuf, r, p, len); if (!r) { - memcpy(out, p, len); + memcpy(seqbuf, p, len); r = len; } free(p); } + if ((size_t) r > outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + memcpy(out, seqbuf, r); LOG_FUNC_RETURN(ctx, r); } diff --git a/src/tests/p11test/isoapplet_ref.json b/src/tests/p11test/isoapplet_ref.json index 8a922b6ce4..295b2d76db 100644 --- a/src/tests/p11test/isoapplet_ref.json +++ b/src/tests/p11test/isoapplet_ref.json @@ -63,11 +63,41 @@ "CKF_DIGEST" ], [ - "ECDSA_SHA1", + "ECDSA", "192", "384", "0x01902801" ], + [ + "ECDSA_SHA1", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA224", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA256", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA384", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA512", + "192", + "384", + "0x00002800" + ], [ "EC_KEY_PAIR_GEN", "192", @@ -196,6 +226,36 @@ "RSA_PKCS", "", "YES" + ], + [ + "03", + "ECDSA", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA512", + "YES", + "" ]], "result": "pass" }, @@ -251,8 +311,7 @@ }, { "test_id": "ec_sign_size_test", - "fail_reason": "Some signatures were not verified successfully. Please review the log", - "result": "fail" + "result": "pass" }, { "test_id": "usage_test", diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f2e6b1dd91..0d548bfa41 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2273,7 +2273,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } rv = CKR_CANCEL; - if (r < (int) sizeof(in_buffer)) { + if (r < (int) sizeof(in_buffer) || opt_mechanism == CKM_ECDSA) { rv = p11->C_SignInit(session, &mech, key); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); From 7af2f4e0cd14a5bd363e8b5367b6860de4664f79 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Mon, 14 Nov 2022 13:13:45 +0100 Subject: [PATCH 2718/4321] undo ci build changes --- .github/build.sh | 2 +- .github/test-isoapplet.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/build.sh b/.github/build.sh index ca73d3d45c..c1fd2df7ff 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -6,7 +6,7 @@ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig; if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }') - if [ "$GITHUB_BASE_REF" == "swissbit-master" ]; then + if [ "$GITHUB_BASE_REF" == "master" ]; then ./bootstrap.ci -s "-pr$PR_NUMBER" else ./bootstrap.ci -s "$GITHUB_BASE_REF-pr$PR_NUMBER" diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 10d22aceb1..29324d4748 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -11,7 +11,7 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/swissbit-eis/IsoApplet.git + git clone https://github.com/philipWendland/IsoApplet.git # enable IsoApplet key import patch sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i IsoApplet/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java fi From 6d61c8f1bc677c7eb90b67e95c6c46a81ab977fd Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Wed, 23 Nov 2022 10:29:09 +0100 Subject: [PATCH 2719/4321] undo changes in pkcs11-tool --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0d548bfa41..f2e6b1dd91 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -2273,7 +2273,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } rv = CKR_CANCEL; - if (r < (int) sizeof(in_buffer) || opt_mechanism == CKM_ECDSA) { + if (r < (int) sizeof(in_buffer)) { rv = p11->C_SignInit(session, &mech, key); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); From b08f6cd639b4dc46c3545760df80b687b53e2cf0 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Wed, 23 Nov 2022 15:52:50 +0100 Subject: [PATCH 2720/4321] add backwards compatibility for ISOApplet 0.6.x --- .github/test-isoapplet.sh | 12 +- .github/workflows/linux.yml | 17 +- src/libopensc/card-isoApplet.c | 85 ++-- .../{isoapplet_ref.json => isoapplet.json} | 0 src/tests/p11test/isoapplet_ref_v0.json | 361 +++++++++++++++ src/tests/p11test/isoapplet_ref_v1.json | 421 ++++++++++++++++++ 6 files changed, 846 insertions(+), 50 deletions(-) rename src/tests/p11test/{isoapplet_ref.json => isoapplet.json} (100%) create mode 100644 src/tests/p11test/isoapplet_ref_v0.json create mode 100644 src/tests/p11test/isoapplet_ref_v1.json diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 29324d4748..1c2520b806 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -2,6 +2,14 @@ set -ex -o xtrace +isoapplet_version="v0" +isoapplet_branch="main" +if [ $1=="v1" ]; then + isoapplet_branch="isoapplet-v1" + isoapplet_version="v1" +fi + + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -11,7 +19,7 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git + git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch # enable IsoApplet key import patch sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i IsoApplet/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java fi @@ -85,7 +93,7 @@ rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig kill -9 $PID -if ! diff -u3 src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref.json; then +if ! diff -u3 "src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref_${isoapplet_version.json}"; then echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." exit 1 fi diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 333a57a358..2e871b7c5e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -96,7 +96,7 @@ jobs: - run: .github/setup-linux.sh piv - run: .github/test-piv.sh - test-isoapplet: + test-isoapplet-v0: runs-on: ubuntu-20.04 needs: [build] steps: @@ -107,7 +107,20 @@ jobs: path: ./* key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - - run: .github/test-isoapplet.sh + - run: .github/test-isoapplet.sh v0 + + test-isoapplet-v1: + runs-on: ubuntu-20.04 + needs: [build] + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - run: .github/setup-linux.sh isoapplet + - run: .github/test-isoapplet.sh v1 test-gidsapplet: runs-on: ubuntu-20.04 diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 7f574947d3..35cd601529 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -34,7 +34,8 @@ #define ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS 0x12 #define ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS 0x13 -#define ISOAPPLET_VERSION 0x0100 +#define ISOAPPLET_VERSION_V0 0x0060 +#define ISOAPPLET_VERSION_V1 0x0100 #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 @@ -162,44 +163,37 @@ isoApplet_match_card(sc_card_t *card) static int isoApplet_get_info(sc_card_t * card, struct isoApplet_drv_data * drvdata) { u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - sc_apdu_t apdu; int rv; sc_context_t * ctx = card->ctx; - /* Get response with P1P2 proprietary (get applet version and features) */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x01); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; + rv = sc_get_data(card, 0x0101, rbuf, 3); + if(rv == SC_ERROR_INS_NOT_SUPPORTED) { + /* INS not supported. This is an older IsoApplet that might return the + * applet information upon selection. For backward compatibility, try this. */ + sc_apdu_t apdu; + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); + apdu.lc = sizeof(isoApplet_aid); + apdu.data = isoApplet_aid; + apdu.datalen = sizeof(isoApplet_aid); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, rv, "APDU transmit failure."); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(ctx, rv, "Error selecting applet."); + rv = (int) apdu.resplen; + } - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit faiure."); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - if(rv < 0) { - if(apdu.sw1 == 0x6D && apdu.sw2 == 0x00) { - /* INS not supported. This is an older IsoApplet that might return the - * applet information upon selection. For backward compatibility, try this. */ - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00); - apdu.lc = sizeof(isoApplet_aid); - apdu.data = isoApplet_aid; - apdu.datalen = sizeof(isoApplet_aid); - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - rv = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(ctx, rv, "APDU transmit faiure."); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, rv, "Error selecting applet."); - } else { - LOG_TEST_RET(ctx, rv, "Card returned error."); - } + if (rv < 0) { + LOG_TEST_RET(ctx, rv, "Card returned error."); } /* Fill up drvdata */ - if(apdu.resplen >= 3) + if(rv >= 3) { - drvdata->isoapplet_version = apdu.resp[0] << 8 | apdu.resp[1]; - drvdata->isoapplet_features = apdu.resp[2]; + drvdata->isoapplet_version = rbuf[0] << 8 | rbuf[1]; + drvdata->isoapplet_features = rbuf[2]; } return SC_SUCCESS; @@ -226,19 +220,21 @@ isoApplet_init(sc_card_t *card) r = isoApplet_get_info(card, drvdata); LOG_TEST_RET(card->ctx, r, "Error obtaining information about applet."); - if((drvdata->isoapplet_version & 0xFF00) != (ISOAPPLET_VERSION & 0xFF00)) + + unsigned int major_version = drvdata->isoapplet_version & 0xFF00; + if(major_version != (ISOAPPLET_VERSION_V0 & 0xFF00) && major_version != (ISOAPPLET_VERSION_V1 & 0xFF00)) { sc_log(card->ctx, "IsoApplet: Mismatching major API version. Not proceeding. " - "API versions: Driver (%04X), applet (%04X). Please update accordingly.", - ISOAPPLET_VERSION, drvdata->isoapplet_version); + "API versions: Driver (%04X or %04X), applet (%04X). Please update accordingly.", + ISOAPPLET_VERSION_V0, ISOAPPLET_VERSION_V1, drvdata->isoapplet_version); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); } - else if(drvdata->isoapplet_version != ISOAPPLET_VERSION) + else if(drvdata->isoapplet_version != ISOAPPLET_VERSION_V0 && drvdata->isoapplet_version != ISOAPPLET_VERSION_V1) { sc_log(card->ctx, "IsoApplet: Mismatching minor version. Proceeding anyway. " - "API versions: Driver (%04X), applet (%04X)." + "API versions: Driver (%04X or %04X), applet (%04X)." "Please update accordingly whenever possible.", - ISOAPPLET_VERSION, drvdata->isoapplet_version); + ISOAPPLET_VERSION_V0, ISOAPPLET_VERSION_V1, drvdata->isoapplet_version); } if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_EXT_APDU) @@ -255,8 +251,12 @@ isoApplet_init(sc_card_t *card) * should be kept in sync with the explicit parameters in the pkcs15-init * driver. */ flags = 0; - flags |= SC_ALGORITHM_ECDSA_RAW; - flags |= SC_ALGORITHM_ECDSA_HASH_NONE; + if (major_version == (ISOAPPLET_VERSION_V0 & 0xFF00)) { + flags |= SC_ALGORITHM_ECDSA_HASH_SHA1; + } else { // ISOAPPLET_VERSION_V1 + flags |= SC_ALGORITHM_ECDSA_RAW; + flags |= SC_ALGORITHM_ECDSA_HASH_NONE; + } flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; ext_flags = SC_ALGORITHM_EXT_EC_UNCOMPRESES; ext_flags |= SC_ALGORITHM_EXT_EC_NAMEDCURVE; @@ -1152,15 +1152,8 @@ isoApplet_set_security_env(sc_card_t *card, break; case SC_ALGORITHM_EC: - if( env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW ) - { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; drvdata->sec_env_ec_field_length = env->algorithm_ref; - } - else - { - LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports raw ECDSA."); - } break; default: diff --git a/src/tests/p11test/isoapplet_ref.json b/src/tests/p11test/isoapplet.json similarity index 100% rename from src/tests/p11test/isoapplet_ref.json rename to src/tests/p11test/isoapplet.json diff --git a/src/tests/p11test/isoapplet_ref_v0.json b/src/tests/p11test/isoapplet_ref_v0.json new file mode 100644 index 0000000000..845fa24477 --- /dev/null +++ b/src/tests/p11test/isoapplet_ref_v0.json @@ -0,0 +1,361 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RIPEMD160", + "0", + "0", + "CKF_DIGEST" + ], + [ + "GOSTR3411", + "0", + "0", + "CKF_DIGEST" + ], + [ + "ECDSA_SHA1", + "192", + "384", + "0x01902801" + ], + [ + "EC_KEY_PAIR_GEN", + "192", + "384", + "0x01910001" + ], + [ + "RSA_PKCS", + "2048", + "2048", + "0x00002A01" + ], + [ + "SHA1_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA224_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "MD5_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RIPEMD160_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "2048", + "2048", + "CKF_GENERATE_KEY_PAIR" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "RSA_PKCS", + "", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "result": "fail" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "01", + "Private Key", + "RSA", + "2048", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "02", + "Private Key", + "RSA", + "2048", + "", + "", + "", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "03", + "Private Key", + "EC", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "result": "unknown" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" +}] +} diff --git a/src/tests/p11test/isoapplet_ref_v1.json b/src/tests/p11test/isoapplet_ref_v1.json new file mode 100644 index 0000000000..295b2d76db --- /dev/null +++ b/src/tests/p11test/isoapplet_ref_v1.json @@ -0,0 +1,421 @@ +{ +"time": 0, +"results": [ +{ + "test_id": "wait_test", + "result": "skip" +}, +{ + "test_id": "supported_mechanisms_test", + "data": [ + [ + "MECHANISM", + "MIN KEY", + "MAX KEY", + "FLAGS" + ], + [ + "SHA_1", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA224", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA256", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA384", + "0", + "0", + "CKF_DIGEST" + ], + [ + "SHA512", + "0", + "0", + "CKF_DIGEST" + ], + [ + "MD5", + "0", + "0", + "CKF_DIGEST" + ], + [ + "RIPEMD160", + "0", + "0", + "CKF_DIGEST" + ], + [ + "GOSTR3411", + "0", + "0", + "CKF_DIGEST" + ], + [ + "ECDSA", + "192", + "384", + "0x01902801" + ], + [ + "ECDSA_SHA1", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA224", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA256", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA384", + "192", + "384", + "0x00002800" + ], + [ + "ECDSA_SHA512", + "192", + "384", + "0x00002800" + ], + [ + "EC_KEY_PAIR_GEN", + "192", + "384", + "0x01910001" + ], + [ + "RSA_PKCS", + "2048", + "2048", + "0x00002A01" + ], + [ + "SHA1_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA224_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "MD5_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RIPEMD160_RSA_PKCS", + "2048", + "2048", + "0x00002800" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", + "2048", + "2048", + "CKF_GENERATE_KEY_PAIR" + ]], + "result": "pass" +}, +{ + "test_id": "interface_test", + "result": "pass" +}, +{ + "test_id": "readonly_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES", + "" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES", + "" + ], + [ + "02", + "RSA_PKCS", + "", + "YES" + ], + [ + "03", + "ECDSA", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA1", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA256", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA384", + "YES", + "" + ], + [ + "03", + "ECDSA_SHA512", + "YES", + "" + ]], + "result": "pass" +}, +{ + "test_id": "multipart_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "MULTIPART SIGN&VERIFY WORKS" + ], + [ + "01", + "RSA_PKCS", + "YES" + ], + [ + "01", + "SHA1_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA224_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA256_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA384_RSA_PKCS", + "YES" + ], + [ + "01", + "SHA512_RSA_PKCS", + "YES" + ], + [ + "01", + "MD5_RSA_PKCS", + "YES" + ], + [ + "01", + "RIPEMD160_RSA_PKCS", + "YES" + ]], + "result": "pass" +}, +{ + "test_id": "ec_sign_size_test", + "result": "pass" +}, +{ + "test_id": "usage_test", + "data": [ + [ + "KEY ID", + "LABEL", + "TYPE", + "BITS", + "VERIFY PUBKEY", + "SIGN", + "VERIFY", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "DERIVE PUBLIC", + "DERIVE PRIVATE", + "ALWAYS AUTH" + ], + [ + "01", + "Private Key", + "RSA", + "2048", + "", + "YES", + "YES", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "02", + "Private Key", + "RSA", + "2048", + "", + "", + "", + "YES", + "YES", + "YES", + "YES", + "", + "", + "" + ], + [ + "03", + "Private Key", + "EC", + "256", + "", + "YES", + "YES", + "", + "", + "", + "", + "", + "", + "" + ]], + "result": "pass" +}, +{ + "test_id": "pss_oaep_test", + "result": "unknown" +}, +{ + "test_id": "derive_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "DERIVE WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "secret_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ]], + "result": "pass" +}, +{ + "test_id": "wrap_tests", + "data": [ + [ + "KEY ID", + "MECHANISM", + "WRAP WORKS", + "UNWRAP WORKS" + ]], + "result": "pass" +}] +} From bda08048bfb47e7b1d52c777cdd1fc598a2cbfa9 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Mon, 5 Dec 2022 17:39:43 +0100 Subject: [PATCH 2721/4321] fix isoapplet test script --- .github/test-isoapplet.sh | 13 +++++++------ src/tests/p11test/isoapplet_ref_v0.json | 8 +++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 1c2520b806..f7ec2e0bf1 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -4,12 +4,13 @@ set -ex -o xtrace isoapplet_version="v0" isoapplet_branch="main" -if [ $1=="v1" ]; then +isoapplet_pkgdir="net/pwendland/javacard/pki/isoapplet" +if [ "$1" = "v1" ]; then isoapplet_branch="isoapplet-v1" isoapplet_version="v1" + isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" fi - # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -21,11 +22,11 @@ export LD_LIBRARY_PATH=/usr/local/lib if [ ! -d IsoApplet ]; then git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch # enable IsoApplet key import patch - sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i IsoApplet/src/net/pwendland/javacard/pki/isoapplet/IsoApplet.java + sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" fi -javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java +javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/${isoapplet_pkgdir}/*.java echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg -echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg +echo "com.licel.jcardsim.card.applet.0.Class=${isoapplet_pkgdir//\//.}.IsoApplet" >> isoapplet_jcardsim.cfg echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg @@ -93,7 +94,7 @@ rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig kill -9 $PID -if ! diff -u3 "src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref_${isoapplet_version.json}"; then +if ! diff -u3 src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref_${isoapplet_version}.json; then echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." exit 1 fi diff --git a/src/tests/p11test/isoapplet_ref_v0.json b/src/tests/p11test/isoapplet_ref_v0.json index 845fa24477..e474fa5202 100644 --- a/src/tests/p11test/isoapplet_ref_v0.json +++ b/src/tests/p11test/isoapplet_ref_v0.json @@ -196,6 +196,12 @@ "RSA_PKCS", "", "YES" + ], + [ + "03", + "ECDSA_SHA1", + "YES", + "" ]], "result": "pass" }, @@ -251,7 +257,7 @@ }, { "test_id": "ec_sign_size_test", - "result": "fail" + "result": "pass" }, { "test_id": "usage_test", From 5103aad51d60ca15edf5ba0290aae3fe447897a4 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Fri, 25 Nov 2022 18:56:30 +0100 Subject: [PATCH 2722/4321] adapt to isoapplet-v1 changes - set correct request and response buffer length for extended APDUs --- .github/test-isoapplet.sh | 6 +++--- src/libopensc/card-isoApplet.c | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index f7ec2e0bf1..ce068acebd 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -20,9 +20,9 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch - # enable IsoApplet key import patch - sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" + git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch + # enable IsoApplet key import patch + sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" fi javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/${isoapplet_pkgdir}/*.java echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 35cd601529..e1078c2cf3 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -158,7 +158,7 @@ isoApplet_match_card(sc_card_t *card) } return 1; - } +} static int isoApplet_get_info(sc_card_t * card, struct isoApplet_drv_data * drvdata) { @@ -576,8 +576,8 @@ isoApplet_ctl_generate_key(sc_card_t *card, sc_cardctl_isoApplet_genkey_t *args) { int r; sc_apdu_t apdu; - u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; - u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 rbuf[SC_MAX_EXT_APDU_RESP_SIZE]; + u8 sbuf[SC_MAX_EXT_APDU_DATA_SIZE]; u8 *p; const u8 *inner_tag_value; const u8 *outer_tag_value; @@ -645,7 +645,11 @@ isoApplet_ctl_generate_key(sc_card_t *card, sc_cardctl_isoApplet_genkey_t *args) apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = 256; + if (card->caps & SC_CARD_CAP_APDU_EXT) { + apdu.le = apdu.resplen; + } else { + apdu.le = 256; + } r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -769,7 +773,7 @@ static int isoApplet_put_data_prkey_rsa(sc_card_t *card, sc_cardctl_isoApplet_import_key_t *args) { sc_apdu_t apdu; - u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_EXT_APDU_DATA_SIZE]; u8 *p = NULL; int r; size_t tags_len; @@ -894,7 +898,7 @@ static int isoApplet_put_data_prkey_ec(sc_card_t *card, sc_cardctl_isoApplet_import_key_t *args) { sc_apdu_t apdu; - u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_EXT_APDU_DATA_SIZE]; int r; u8 *p; size_t tags_len; @@ -1152,8 +1156,8 @@ isoApplet_set_security_env(sc_card_t *card, break; case SC_ALGORITHM_EC: - drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; - drvdata->sec_env_ec_field_length = env->algorithm_ref; + drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; + drvdata->sec_env_ec_field_length = env->algorithm_ref; break; default: @@ -1209,7 +1213,7 @@ isoApplet_compute_signature(struct sc_card *card, struct sc_context *ctx = card->ctx; struct isoApplet_drv_data *drvdata = DRVDATA(card); /* No more than 256 byte are needed for the signature. The IsoApplet - * supports no larger key sizes than for RSA-2048 or EC:secp384r1 leading + * supports no larger key sizes than for RSA-4096 or EC:secp384r1 leading * to 256 byte or 104 byte, respectively, in ASN.1 sequence. */ static u8 seqbuf[256]; size_t seqlen = sizeof(seqbuf); From 4e59e4eec17386377e926430866d303156b56e82 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Tue, 6 Dec 2022 16:51:49 +0100 Subject: [PATCH 2723/4321] fix rsa-pss - adapt to change in iso applet that only signal PSS support if all hash schemes are supported - strip PKCS#1 digest info when using RSA PSS so that only the hash is sent to the applet --- src/libopensc/card-isoApplet.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index e1078c2cf3..25df1bf1c3 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -31,8 +31,7 @@ #define ISOAPPLET_ALG_REF_ECDSA 0x21 #define ISOAPPLET_ALG_REF_RSA_PAD_PKCS1 0x11 -#define ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS 0x12 -#define ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS 0x13 +#define ISOAPPLET_ALG_REF_RSA_PAD_PSS 0x12 #define ISOAPPLET_VERSION_V0 0x0060 #define ISOAPPLET_VERSION_V1 0x0100 @@ -40,8 +39,7 @@ #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 #define ISOAPPLET_API_FEATURE_ECC 0x04 -#define ISOAPPLET_API_FEATURE_RSA_SHA256_PSS 0x08 -#define ISOAPPLET_API_FEATURE_RSA_SHA512_PSS 0x10 +#define ISOAPPLET_API_FEATURE_RSA_PSS 0x08 static const u8 isoApplet_aid[] = {0xf2,0x76,0xa2,0x88,0xbc,0xfb,0xa6,0x9d,0x34,0xf3,0x10,0x01}; @@ -272,14 +270,8 @@ isoApplet_init(sc_card_t *card) flags = 0; flags |= SC_ALGORITHM_RSA_PAD_PKCS1; flags |= SC_ALGORITHM_RSA_HASH_NONE; - flags |= SC_ALGORITHM_RSA_HASH_SHA256; - if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA256_PSS) { + if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_PSS) { flags |= SC_ALGORITHM_RSA_PAD_PSS; - flags |= SC_ALGORITHM_MGF1_SHA256; - } - if(drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_SHA512_PSS) { - flags |= SC_ALGORITHM_RSA_PAD_PSS; - flags |= SC_ALGORITHM_MGF1_SHA512; } /* Key-generation: */ flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; @@ -1141,13 +1133,9 @@ isoApplet_set_security_env(sc_card_t *card, { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_PAD_PKCS1; } - else if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS && env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256 ) - { - drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_SHA256_PAD_PSS; - } - else if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS && env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA512 ) + else if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS ) { - drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_SHA512_PAD_PSS; + drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_PAD_PSS; } else { @@ -1221,7 +1209,16 @@ isoApplet_compute_signature(struct sc_card *card, LOG_FUNC_CALLED(ctx); - r = iso_ops->compute_signature(card, data, datalen, seqbuf, seqlen); + if (drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_RSA_PAD_PSS) { + // For RSA-PSS signature schemes the IsoApplet expects only the hash. + u8 tmp[64]; // large enough for SHA512 + size_t tmplen = sizeof(tmp); + sc_pkcs1_strip_digest_info_prefix(NULL, data, datalen, tmp, &tmplen); + r = iso_ops->compute_signature(card, tmp, tmplen, seqbuf, seqlen); + } else { + r = iso_ops->compute_signature(card, data, datalen, seqbuf, seqlen); + } + if(r < 0) { LOG_FUNC_RETURN(ctx, r); From abc67e6eaa1658e8f0d4198c2e47a761f8e746f4 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Wed, 7 Dec 2022 14:07:42 +0100 Subject: [PATCH 2724/4321] fix memory leak when init fails --- src/libopensc/card-isoApplet.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 25df1bf1c3..cb2fbedee6 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -216,7 +216,7 @@ isoApplet_init(sc_card_t *card) /* Obtain applet version and specific features */ r = isoApplet_get_info(card, drvdata); - LOG_TEST_RET(card->ctx, r, "Error obtaining information about applet."); + LOG_TEST_GOTO_ERR(card->ctx, r, "Error obtaining information about applet."); unsigned int major_version = drvdata->isoapplet_version & 0xFF00; @@ -225,7 +225,8 @@ isoApplet_init(sc_card_t *card) sc_log(card->ctx, "IsoApplet: Mismatching major API version. Not proceeding. " "API versions: Driver (%04X or %04X), applet (%04X). Please update accordingly.", ISOAPPLET_VERSION_V0, ISOAPPLET_VERSION_V1, drvdata->isoapplet_version); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + r = SC_ERROR_INVALID_CARD; + goto err; } else if(drvdata->isoapplet_version != ISOAPPLET_VERSION_V0 && drvdata->isoapplet_version != ISOAPPLET_VERSION_V1) { @@ -279,6 +280,9 @@ isoApplet_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 2048, flags, 0); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +err: + free(drvdata); + LOG_FUNC_RETURN(card->ctx, r); } /* From 71080f87fafca949ae86aff3ead775b77daaae56 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 14:30:18 +0100 Subject: [PATCH 2725/4321] replace spaces with tabs --- .github/test-isoapplet.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index ce068acebd..2eced243e9 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -6,9 +6,9 @@ isoapplet_version="v0" isoapplet_branch="main" isoapplet_pkgdir="net/pwendland/javacard/pki/isoapplet" if [ "$1" = "v1" ]; then - isoapplet_branch="isoapplet-v1" - isoapplet_version="v1" - isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" + isoapplet_branch="isoapplet-v1" + isoapplet_version="v1" + isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" fi # install the opensc @@ -20,9 +20,9 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch - # enable IsoApplet key import patch - sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" + git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch + # enable IsoApplet key import patch + sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" fi javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/${isoapplet_pkgdir}/*.java echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg @@ -95,6 +95,6 @@ rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig kill -9 $PID if ! diff -u3 src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref_${isoapplet_version}.json; then - echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." - exit 1 + echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." + exit 1 fi From fb1370aac0c1d953d4db9a429bd30e1a03b6e679 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 14:32:07 +0100 Subject: [PATCH 2726/4321] remove p11test result file --- src/tests/p11test/isoapplet.json | 421 ------------------------------- 1 file changed, 421 deletions(-) delete mode 100644 src/tests/p11test/isoapplet.json diff --git a/src/tests/p11test/isoapplet.json b/src/tests/p11test/isoapplet.json deleted file mode 100644 index 295b2d76db..0000000000 --- a/src/tests/p11test/isoapplet.json +++ /dev/null @@ -1,421 +0,0 @@ -{ -"time": 0, -"results": [ -{ - "test_id": "wait_test", - "result": "skip" -}, -{ - "test_id": "supported_mechanisms_test", - "data": [ - [ - "MECHANISM", - "MIN KEY", - "MAX KEY", - "FLAGS" - ], - [ - "SHA_1", - "0", - "0", - "CKF_DIGEST" - ], - [ - "SHA224", - "0", - "0", - "CKF_DIGEST" - ], - [ - "SHA256", - "0", - "0", - "CKF_DIGEST" - ], - [ - "SHA384", - "0", - "0", - "CKF_DIGEST" - ], - [ - "SHA512", - "0", - "0", - "CKF_DIGEST" - ], - [ - "MD5", - "0", - "0", - "CKF_DIGEST" - ], - [ - "RIPEMD160", - "0", - "0", - "CKF_DIGEST" - ], - [ - "GOSTR3411", - "0", - "0", - "CKF_DIGEST" - ], - [ - "ECDSA", - "192", - "384", - "0x01902801" - ], - [ - "ECDSA_SHA1", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA224", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA256", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA384", - "192", - "384", - "0x00002800" - ], - [ - "ECDSA_SHA512", - "192", - "384", - "0x00002800" - ], - [ - "EC_KEY_PAIR_GEN", - "192", - "384", - "0x01910001" - ], - [ - "RSA_PKCS", - "2048", - "2048", - "0x00002A01" - ], - [ - "SHA1_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "SHA224_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "SHA256_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "SHA384_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "SHA512_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "MD5_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "RIPEMD160_RSA_PKCS", - "2048", - "2048", - "0x00002800" - ], - [ - "RSA_PKCS_KEY_PAIR_GEN", - "2048", - "2048", - "CKF_GENERATE_KEY_PAIR" - ]], - "result": "pass" -}, -{ - "test_id": "interface_test", - "result": "pass" -}, -{ - "test_id": "readonly_tests", - "data": [ - [ - "KEY ID", - "MECHANISM", - "SIGN&VERIFY WORKS", - "ENCRYPT&DECRYPT WORKS" - ], - [ - "01", - "RSA_PKCS", - "YES", - "YES" - ], - [ - "01", - "SHA1_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "SHA224_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "SHA256_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "SHA384_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "SHA512_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "MD5_RSA_PKCS", - "YES", - "" - ], - [ - "01", - "RIPEMD160_RSA_PKCS", - "YES", - "" - ], - [ - "02", - "RSA_PKCS", - "", - "YES" - ], - [ - "03", - "ECDSA", - "YES", - "" - ], - [ - "03", - "ECDSA_SHA1", - "YES", - "" - ], - [ - "03", - "ECDSA_SHA256", - "YES", - "" - ], - [ - "03", - "ECDSA_SHA384", - "YES", - "" - ], - [ - "03", - "ECDSA_SHA512", - "YES", - "" - ]], - "result": "pass" -}, -{ - "test_id": "multipart_tests", - "data": [ - [ - "KEY ID", - "MECHANISM", - "MULTIPART SIGN&VERIFY WORKS" - ], - [ - "01", - "RSA_PKCS", - "YES" - ], - [ - "01", - "SHA1_RSA_PKCS", - "YES" - ], - [ - "01", - "SHA224_RSA_PKCS", - "YES" - ], - [ - "01", - "SHA256_RSA_PKCS", - "YES" - ], - [ - "01", - "SHA384_RSA_PKCS", - "YES" - ], - [ - "01", - "SHA512_RSA_PKCS", - "YES" - ], - [ - "01", - "MD5_RSA_PKCS", - "YES" - ], - [ - "01", - "RIPEMD160_RSA_PKCS", - "YES" - ]], - "result": "pass" -}, -{ - "test_id": "ec_sign_size_test", - "result": "pass" -}, -{ - "test_id": "usage_test", - "data": [ - [ - "KEY ID", - "LABEL", - "TYPE", - "BITS", - "VERIFY PUBKEY", - "SIGN", - "VERIFY", - "ENCRYPT", - "DECRYPT", - "WRAP", - "UNWRAP", - "DERIVE PUBLIC", - "DERIVE PRIVATE", - "ALWAYS AUTH" - ], - [ - "01", - "Private Key", - "RSA", - "2048", - "", - "YES", - "YES", - "YES", - "YES", - "YES", - "YES", - "", - "", - "" - ], - [ - "02", - "Private Key", - "RSA", - "2048", - "", - "", - "", - "YES", - "YES", - "YES", - "YES", - "", - "", - "" - ], - [ - "03", - "Private Key", - "EC", - "256", - "", - "YES", - "YES", - "", - "", - "", - "", - "", - "", - "" - ]], - "result": "pass" -}, -{ - "test_id": "pss_oaep_test", - "result": "unknown" -}, -{ - "test_id": "derive_tests", - "data": [ - [ - "KEY ID", - "MECHANISM", - "DERIVE WORKS" - ]], - "result": "pass" -}, -{ - "test_id": "secret_tests", - "data": [ - [ - "KEY ID", - "MECHANISM", - "SIGN&VERIFY WORKS", - "ENCRYPT&DECRYPT WORKS" - ]], - "result": "pass" -}, -{ - "test_id": "wrap_tests", - "data": [ - [ - "KEY ID", - "MECHANISM", - "WRAP WORKS", - "UNWRAP WORKS" - ]], - "result": "pass" -}] -} From e1eab74179a35ac592317d63bdd2081e8132a09d Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 15:28:56 +0100 Subject: [PATCH 2727/4321] remove static keyword from temporary signature buffer --- src/libopensc/card-isoApplet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index cb2fbedee6..bcaab24453 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1207,7 +1207,7 @@ isoApplet_compute_signature(struct sc_card *card, /* No more than 256 byte are needed for the signature. The IsoApplet * supports no larger key sizes than for RSA-4096 or EC:secp384r1 leading * to 256 byte or 104 byte, respectively, in ASN.1 sequence. */ - static u8 seqbuf[256]; + u8 seqbuf[256]; size_t seqlen = sizeof(seqbuf); int r; From 8a59e0d390b3d5d56ae75f736eb9ef5c99afb51c Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 17:25:47 +0100 Subject: [PATCH 2728/4321] refactor isoApplet_compute_signature --- src/libopensc/card-isoApplet.c | 57 ++++++++++++++-------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index bcaab24453..4bccf8bcbd 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1204,11 +1204,6 @@ isoApplet_compute_signature(struct sc_card *card, { struct sc_context *ctx = card->ctx; struct isoApplet_drv_data *drvdata = DRVDATA(card); - /* No more than 256 byte are needed for the signature. The IsoApplet - * supports no larger key sizes than for RSA-4096 or EC:secp384r1 leading - * to 256 byte or 104 byte, respectively, in ASN.1 sequence. */ - u8 seqbuf[256]; - size_t seqlen = sizeof(seqbuf); int r; LOG_FUNC_CALLED(ctx); @@ -1218,41 +1213,37 @@ isoApplet_compute_signature(struct sc_card *card, u8 tmp[64]; // large enough for SHA512 size_t tmplen = sizeof(tmp); sc_pkcs1_strip_digest_info_prefix(NULL, data, datalen, tmp, &tmplen); - r = iso_ops->compute_signature(card, tmp, tmplen, seqbuf, seqlen); - } else { + r = iso_ops->compute_signature(card, tmp, tmplen, out, outlen); + } else if (drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_ECDSA) { + /* + * The card returns ECDSA signatures as an ASN.1 sequence of integers R,S + * while PKCS#11 expects the raw concatenation of R,S for PKCS#11. + * We cannot expect the caller to provide an out buffer that is large enough for the ASN.1 sequence. + * Therefore, we allocate a temporary buffer for the card output, and then convert it to raw R,S. + * The card supports no curves with field sizes larger than 384bit (EC:secp384r1 which yields an ASN.1 + * encoded signature of 104 byte: + * R and S = 384 bit = 48 byte + 1 zero byte if the first bit is set (otherwise they are interpreted as negative). + * Seq-Tag&Len (2 bytes) + R-Tag&Len (2 bytes) + R (49 bytes) + S-Tag&Len (2 bytes) + S (49 bytes) + */ + u8 seqbuf[104]; + size_t seqlen = sizeof(seqbuf); r = iso_ops->compute_signature(card, data, datalen, seqbuf, seqlen); - } - if(r < 0) - { - LOG_FUNC_RETURN(ctx, r); - } + if (r < 0) { + LOG_FUNC_RETURN(ctx, r); + } - /* If ECDSA was used, the ASN.1 sequence of integers R,S returned by the - * card needs to be converted to the raw concatenation of R,S for PKCS#11. */ - if(drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_ECDSA) - { - u8* p = NULL; + /* Convert ASN.1 sequence of integers R,S to the raw concatenation of R,S for PKCS#11. */ size_t len = (drvdata->sec_env_ec_field_length + 7) / 8 * 2; - - if (len > seqlen) + if (len > outlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); - p = calloc(1,len); - if (!p) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); - - r = sc_asn1_sig_value_sequence_to_rs(ctx, seqbuf, r, p, len); - if (!r) { - memcpy(seqbuf, p, len); - r = len; - } - - free(p); + r = sc_asn1_sig_value_sequence_to_rs(ctx, seqbuf, r, out, len); + LOG_TEST_RET(ctx, r, "Failed to convert ASN.1 signature to raw RS"); + r = len; + } else { + r = iso_ops->compute_signature(card, data, datalen, out, outlen); } - if ((size_t) r > outlen) - LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); - memcpy(out, seqbuf, r); LOG_FUNC_RETURN(ctx, r); } From bbedfa48d53830fb5dabe82ca4d08c3e67cd457a Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 18:04:05 +0100 Subject: [PATCH 2729/4321] move decleration of major_version to the top of the init func --- src/libopensc/card-isoApplet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 4bccf8bcbd..fc2d5b23de 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -201,6 +201,7 @@ static int isoApplet_init(sc_card_t *card) { int i, r; + unsigned int major_version = 0; unsigned long flags = 0; unsigned long ext_flags = 0; struct isoApplet_drv_data *drvdata; @@ -218,8 +219,7 @@ isoApplet_init(sc_card_t *card) r = isoApplet_get_info(card, drvdata); LOG_TEST_GOTO_ERR(card->ctx, r, "Error obtaining information about applet."); - - unsigned int major_version = drvdata->isoapplet_version & 0xFF00; + major_version = drvdata->isoapplet_version & 0xFF00; if(major_version != (ISOAPPLET_VERSION_V0 & 0xFF00) && major_version != (ISOAPPLET_VERSION_V1 & 0xFF00)) { sc_log(card->ctx, "IsoApplet: Mismatching major API version. Not proceeding. " From 84320d2f6d2b05e54286ca565617d010d73a2adb Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 8 Dec 2022 18:21:29 +0100 Subject: [PATCH 2730/4321] add rsa 4096 support --- src/libopensc/card-isoApplet.c | 8 +++++++- src/libopensc/cardctl.h | 1 + src/pkcs15init/pkcs15-isoApplet.c | 8 ++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index fc2d5b23de..36ea7636bf 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -40,6 +40,7 @@ #define ISOAPPLET_API_FEATURE_SECURE_RANDOM 0x02 #define ISOAPPLET_API_FEATURE_ECC 0x04 #define ISOAPPLET_API_FEATURE_RSA_PSS 0x08 +#define ISOAPPLET_API_FEATURE_RSA_4096 0x20 static const u8 isoApplet_aid[] = {0xf2,0x76,0xa2,0x88,0xbc,0xfb,0xa6,0x9d,0x34,0xf3,0x10,0x01}; @@ -278,6 +279,9 @@ isoApplet_init(sc_card_t *card) flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; /* Modulus lengths: */ _sc_card_add_rsa_alg(card, 2048, flags, 0); + if (drvdata->isoapplet_features & ISOAPPLET_API_FEATURE_RSA_4096) { + _sc_card_add_rsa_alg(card, 4096, flags, 0); + } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); err: @@ -674,9 +678,11 @@ isoApplet_ctl_generate_key(sc_card_t *card, sc_cardctl_isoApplet_genkey_t *args) { case SC_ISOAPPLET_ALG_REF_RSA_GEN_2048: + case SC_ISOAPPLET_ALG_REF_RSA_GEN_4096: /* Search for the modulus tag (81). */ inner_tag_value = sc_asn1_find_tag(card->ctx, outer_tag_value, outer_tag_len, (unsigned int) 0x81, &inner_tag_len); - if(inner_tag_value == NULL || inner_tag_len != 256) + const size_t expected_modulus_len = args->algorithm_ref == SC_ISOAPPLET_ALG_REF_RSA_GEN_2048 ? 256 : 512; + if(inner_tag_value == NULL || inner_tag_len != expected_modulus_len) { LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "Card returned no or a invalid modulus."); } diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 2ec2852c46..c3acbbcb67 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -1056,6 +1056,7 @@ typedef struct sc_cardctl_sc_hsm_pka_register { */ #define SC_ISOAPPLET_ALG_REF_RSA_GEN_2048 0xF3 +#define SC_ISOAPPLET_ALG_REF_RSA_GEN_4096 0xF5 #define SC_ISOAPPLET_ALG_REF_EC_GEN 0xEC typedef struct sc_cardctl_isoApplet_ec_parameters { diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index d724eda2b3..506edc2adf 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -362,17 +362,17 @@ isoApplet_generate_key_rsa(sc_pkcs15_prkey_info_t *key_info, sc_card_t *card, /* Check key size: */ keybits = key_info->modulus_length; - if (keybits != 2048) + if (keybits != 2048 && keybits != 4096) { rv = SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, "%s: RSA private key length is unsupported, correct length is 2048", sc_strerror(rv)); + sc_log(card->ctx, "%s: RSA private key length is unsupported, correct length is 2048 or 4096", sc_strerror(rv)); goto err; } /* Generate the key. * Note: key size is not explicitly passed to the card. - * It assumes 2048 along with the algorithm reference. */ - args.algorithm_ref = SC_ISOAPPLET_ALG_REF_RSA_GEN_2048; + * Its derived from the algorithm reference. */ + args.algorithm_ref = keybits == 2048 ? SC_ISOAPPLET_ALG_REF_RSA_GEN_2048 : SC_ISOAPPLET_ALG_REF_RSA_GEN_4096; args.priv_key_ref = key_info->key_reference; args.pubkey.rsa.modulus.len = keybits / 8; From 4c951104205757a24ec475d507598c1dea4afb22 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 12 Jan 2023 15:48:25 +0100 Subject: [PATCH 2731/4321] perform shallow clone of IsoApplet repository for testing --- .github/test-isoapplet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 2eced243e9..c48501c09b 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -20,7 +20,7 @@ export LD_LIBRARY_PATH=/usr/local/lib # The ISO applet if [ ! -d IsoApplet ]; then - git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch + git clone https://github.com/philipWendland/IsoApplet.git --branch $isoapplet_branch --depth 1 # enable IsoApplet key import patch sed "s/DEF_PRIVATE_KEY_IMPORT_ALLOWED = false/DEF_PRIVATE_KEY_IMPORT_ALLOWED = true/g" -i "IsoApplet/src/${isoapplet_pkgdir}/IsoApplet.java" fi From 9dd5a8bd62a356091bb8e67492ca9171c4deba34 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Thu, 19 Jan 2023 10:28:01 +0100 Subject: [PATCH 2732/4321] update p11test reference result for v1 isoapplet --- .github/test-isoapplet.sh | 2 +- src/tests/p11test/isoapplet_ref_v1.json | 127 ++++++++++++++++++++++-- 2 files changed, 119 insertions(+), 10 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index c48501c09b..8009c41aed 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -94,7 +94,7 @@ rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig kill -9 $PID -if ! diff -u3 src/tests/p11test/isoapplet.json src/tests/p11test/isoapplet_ref_${isoapplet_version}.json; then +if ! diff -u3 src/tests/p11test/isoapplet_ref_${isoapplet_version}.json src/tests/p11test/isoapplet.json; then echo "The output of p11test has changed (see diff above). If that is expected, update the reference file. Otherwise, fix the error." exit 1 fi diff --git a/src/tests/p11test/isoapplet_ref_v1.json b/src/tests/p11test/isoapplet_ref_v1.json index 295b2d76db..ebb2ab8ad2 100644 --- a/src/tests/p11test/isoapplet_ref_v1.json +++ b/src/tests/p11test/isoapplet_ref_v1.json @@ -107,55 +107,91 @@ [ "RSA_PKCS", "2048", - "2048", + "4096", "0x00002A01" ], [ "SHA1_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "SHA224_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "SHA256_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "SHA384_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "SHA512_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "MD5_RSA_PKCS", "2048", - "2048", + "4096", "0x00002800" ], [ "RIPEMD160_RSA_PKCS", "2048", + "4096", + "0x00002800" + ], + [ + "RSA_PKCS_PSS", + "2048", + "4096", + "0x00002801" + ], + [ + "SHA1_RSA_PKCS_PSS", "2048", + "4096", "0x00002800" ], [ - "RSA_PKCS_KEY_PAIR_GEN", + "SHA224_RSA_PKCS_PSS", + "2048", + "4096", + "0x00002800" + ], + [ + "SHA256_RSA_PKCS_PSS", + "2048", + "4096", + "0x00002800" + ], + [ + "SHA384_RSA_PKCS_PSS", + "2048", + "4096", + "0x00002800" + ], + [ + "SHA512_RSA_PKCS_PSS", "2048", + "4096", + "0x00002800" + ], + [ + "RSA_PKCS_KEY_PAIR_GEN", "2048", + "4096", "CKF_GENERATE_KEY_PAIR" ]], "result": "pass" @@ -384,7 +420,80 @@ }, { "test_id": "pss_oaep_test", - "result": "unknown" + "data": [ + [ + "KEY ID", + "MECHANISM", + "HASH", + "MGF", + "SALT", + "SIGN&VERIFY WORKS", + "ENCRYPT&DECRYPT WORKS" + ], + [ + "01", + "SHA1_RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "SHA256_RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "SHA384_RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "SHA512_RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ]], + "result": "pass" }, { "test_id": "derive_tests", From 20899a14a38a8be036e284573a4b4c3908793b1c Mon Sep 17 00:00:00 2001 From: Philip Wendland Date: Fri, 27 Jan 2023 17:14:56 +0100 Subject: [PATCH 2733/4321] Github test: adjust package dir and git branch of IsoApplet versions --- .github/test-isoapplet.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 8009c41aed..552545314e 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -2,15 +2,18 @@ set -ex -o xtrace -isoapplet_version="v0" -isoapplet_branch="main" -isoapplet_pkgdir="net/pwendland/javacard/pki/isoapplet" -if [ "$1" = "v1" ]; then - isoapplet_branch="isoapplet-v1" - isoapplet_version="v1" - isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" +isoapplet_version="$1" +if [ "$isoapplet_version" = "v0" ]; then + isoapplet_branch="main-javacard-v2.2.2" +elif [ "$isoapplet_version" = "v1" ]; then + isoapplet_branch="main" +else + echo "Unknown IsoApplet version: $isoapplet_version" + exit 1 fi +isoapplet_pkgdir="xyz/wendland/javacard/pki/isoapplet" + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib From aadd82bb071e574fc57263a103e3bf06ebbd8de7 Mon Sep 17 00:00:00 2001 From: "Ingo Struck (git commits)" Date: Sat, 21 Jan 2023 22:15:10 +0100 Subject: [PATCH 2734/4321] Handle reader limits for SC Card unwrap operations Fixes #2514 --- src/libopensc/card-sc-hsm.c | 181 ++++++++++++++----------- src/libopensc/reader-pcsc.c | 91 ++++++++----- src/tests/fuzzing/fuzz_pkcs15_decode.c | 3 +- src/tests/fuzzing/fuzz_pkcs15_encode.c | 2 +- 4 files changed, 159 insertions(+), 118 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 60d5895127..1b707f08df 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -145,9 +145,7 @@ static int sc_hsm_select_file_ex(sc_card_t *card, if (file_out == NULL) { // Versions before 0.16 of the SmartCard-HSM do not support P2='0C' rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file); - if (file != NULL) { - sc_file_free(file); - } + sc_file_free(file); return rv; } @@ -181,9 +179,7 @@ static int sc_hsm_select_file_ex(sc_card_t *card, LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application"); if (priv) { - if (priv->dffcp != NULL) { - sc_file_free(priv->dffcp); - } + sc_file_free(priv->dffcp); // Cache the FCP returned when selecting the applet sc_file_dup(&priv->dffcp, *file_out); } @@ -730,12 +726,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; #ifdef ENABLE_SM if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { - sc_log(card->ctx, + sc_log(card->ctx, "Session PIN generation only supported in SM"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } #else - sc_log(card->ctx, + sc_log(card->ctx, "Session PIN generation only supported in SM"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); #endif @@ -746,7 +742,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.le = 0; if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS || sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) { - sc_log(card->ctx, + sc_log(card->ctx, "Generating session PIN failed"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -756,12 +752,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, apdu.resplen); data->pin2.len = apdu.resplen; } else { - sc_log(card->ctx, + sc_log(card->ctx, "Buffer too small for session PIN"); } } } else { - sc_log(card->ctx, + sc_log(card->ctx, "Session PIN not supported for this PIN (0x%02X)", data->pin_reference); } @@ -848,47 +844,61 @@ static int sc_hsm_write_ef(sc_card_t *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } - p = cmdbuff; - *p++ = 0x54; - *p++ = 0x02; - *p++ = (idx >> 8) & 0xFF; - *p++ = idx & 0xFF; - *p++ = 0x53; - if (count < 128) { - *p++ = (u8) count; - len = 6; - } else if (count < 256) { - *p++ = 0x81; - *p++ = (u8) count; - len = 7; - } else { - *p++ = 0x82; - *p++ = (count >> 8) & 0xFF; - *p++ = count & 0xFF; - len = 8; - } + size_t bytes_left = count; + // 8 bytes are required for T54(4) and T53(4) + size_t blk_size = card->max_send_size - 8; + size_t to_send = 0; + size_t offset = (size_t) idx; + do { + len = 0; + to_send = bytes_left >= blk_size ? blk_size : bytes_left; + p = cmdbuff; + // ASN1 0x54 offset + *p++ = 0x54; + *p++ = 0x02; + *p++ = (offset >> 8) & 0xFF; + *p++ = offset & 0xFF; + // ASN1 0x53 to_send + *p++ = 0x53; + if (to_send < 128) { + *p++ = (u8)to_send; + len = 6; + } else if (to_send < 256) { + *p++ = 0x81; + *p++ = (u8)to_send; + len = 7; + } else { + *p++ = 0x82; + *p++ = (to_send >> 8) & 0xFF; + *p++ = to_send & 0xFF; + len = 8; + } - if (buf != NULL) - memcpy(p, buf, count); - len += count; + if (buf != NULL) + memcpy(p, buf+offset, to_send); + len += to_send; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF); - apdu.data = cmdbuff; - apdu.datalen = len; - apdu.lc = len; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF); + apdu.data = cmdbuff; + apdu.datalen = len; + apdu.lc = len; - r = sc_transmit_apdu(card, &apdu); - free(cmdbuff); - LOG_TEST_RET(ctx, r, "APDU transmit failed"); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_GOTO_ERR(ctx, r, "Check SW error"); - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(ctx, r, "Check SW error"); + bytes_left -= to_send; + offset += to_send; + } while (0 < bytes_left); + +err: + free(cmdbuff); LOG_FUNC_RETURN(ctx, count); } - static int sc_hsm_update_binary(sc_card_t *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) @@ -1227,7 +1237,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa return SC_ERROR_INVALID_ARGUMENTS; } *p++ = 0x81; // User PIN - *p++ = (u8) params->user_pin_len; + *p++ = (u8)params->user_pin_len; memcpy(p, params->user_pin, params->user_pin_len); p += params->user_pin_len; @@ -1400,12 +1410,11 @@ static int sc_hsm_unwrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *p LOG_FUNC_CALLED(card->ctx); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, 0x74, params->key_id, 0x93); - apdu.cla = 0x80; - apdu.lc = params->wrapped_key_length; - apdu.data = params->wrapped_key; - apdu.datalen = params->wrapped_key_length; + r = sc_hsm_write_ef(card, 0x2F10, 0, params->wrapped_key, params->wrapped_key_length); + LOG_TEST_RET(card->ctx, r, "Create EF failed"); + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x74, params->key_id, 0x93); + apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); @@ -1765,17 +1774,10 @@ static int sc_hsm_init(struct sc_card *card) int flags,ext_flags; sc_file_t *file = NULL; sc_path_t path; - sc_hsm_private_data_t *priv = card->drv_data; + sc_hsm_private_data_t *priv = NULL; LOG_FUNC_CALLED(card->ctx); - if (!priv) { - priv = calloc(1, sizeof(sc_hsm_private_data_t)); - if (!priv) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - card->drv_data = priv; - } - flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN; _sc_card_add_rsa_alg(card, 1024, flags, 0); @@ -1807,6 +1809,46 @@ static int sc_hsm_init(struct sc_card *card) card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO; + // APDU Buffer limits + // JCOP 2.4.1r3 1462 + // JCOP 2.4.2r3 1454 + // JCOP 3 1232 + // MicroSD with JCOP 3 478 / 506 - handled in reader-pcsc.c + // Reiner SCT 1014 - handled in reader-pcsc.c + + // Use JCOP 3 card limits for sending + card->max_send_size = 1232; + // Assume that card supports sending with extended length APDU and without limit + card->max_recv_size = 0; + + if (card->type == SC_CARD_TYPE_SC_HSM_SOC + || card->type == SC_CARD_TYPE_SC_HSM_GOID) { + card->max_recv_size = 0x0630; // SoC Proxy forces this limit + } else { + // Adjust to the limits set by the reader + if (card->reader->max_send_size < card->max_send_size) { + if (18 >= card->reader->max_send_size) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION); + + // 17 byte header and TLV because of odd ins in UPDATE BINARY + card->max_send_size = card->reader->max_send_size - 17; + } + + if (0 < card->reader->max_recv_size) { + if (3 >= card->reader->max_recv_size) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION); + card->max_recv_size = card->reader->max_recv_size - 2; + } + } + + priv = card->drv_data; + if (!priv) { + priv = calloc(1, sizeof(sc_hsm_private_data_t)); + if (!priv) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + card->drv_data = priv; + } + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS && file && file->prop_attr && file->prop_attr_len >= 2) { @@ -1839,25 +1881,6 @@ static int sc_hsm_init(struct sc_card *card) } sc_file_free(file); - // APDU Buffer limits - // JCOP 2.4.1r3 1462 - // JCOP 2.4.2r3 1454 - // JCOP 3 1232 - // MicroSD with JCOP 3 478 / 506 - // Reiner SCT 1014 - - card->max_send_size = 1232 - 17; // 1232 buffer size - 17 byte header and TLV because of odd ins in UPDATE BINARY - - if (!strncmp("Secure Flash Card", card->reader->name, 17)) { - card->max_send_size = 478 - 17; - card->max_recv_size = 506 - 2; - } else if (card->type == SC_CARD_TYPE_SC_HSM_SOC - || card->type == SC_CARD_TYPE_SC_HSM_GOID) { - card->max_recv_size = 0x0630; // SoC Proxy forces this limit - } else { - card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit - } - priv->EF_C_DevAut = NULL; priv->EF_C_DevAut_len = 0; @@ -1883,13 +1906,11 @@ static int sc_hsm_finish(sc_card_t * card) #ifdef ENABLE_SM sc_sm_stop(card); #endif - if (priv->serialno) { + if (priv) { free(priv->serialno); - } - if (priv->dffcp) { sc_file_free(priv->dffcp); + free(priv->EF_C_DevAut); } - free(priv->EF_C_DevAut); free(priv); return SC_SUCCESS; diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 40bfd293d3..04d5ac8fdd 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -311,7 +311,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_apdu_t *apdu) * The buffer for the returned data needs to be at least 2 bytes * larger than the expected data length to store SW1 and SW2. */ rsize = rbuflen = apdu->resplen <= 256 ? 258 : apdu->resplen + 2; - rbuf = malloc(rbuflen); + rbuf = malloc(rbuflen); if (rbuf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; @@ -386,7 +386,7 @@ static int refresh_attributes(sc_reader_t *reader) } LOG_FUNC_RETURN(reader->ctx, SC_SUCCESS); } - + /* the system could not detect the reader. It means, the prevoiusly attached reader is disconnected. */ if (rv == (LONG)SCARD_E_UNKNOWN_READER #ifdef SCARD_E_NO_READERS_AVAILABLE @@ -424,7 +424,7 @@ static int refresh_attributes(sc_reader_t *reader) if (priv->reader_state.cbAtr > SC_MAX_ATR_SIZE) return SC_ERROR_INTERNAL; - /* Some cards have a different cold (after a powerup) and warm (after a reset) ATR */ + /* Some cards have a different cold (after a powerup) and warm (after a reset) ATR */ if (memcmp(priv->reader_state.rgbAtr, reader->atr.value, priv->reader_state.cbAtr) != 0) { reader->atr.len = priv->reader_state.cbAtr; memcpy(reader->atr.value, priv->reader_state.rgbAtr, reader->atr.len); @@ -556,7 +556,7 @@ static int pcsc_reconnect(sc_reader_t * reader, DWORD action) priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED, protocol, action, &active_proto); - + PCSC_TRACE(reader, "SCardReconnect returned", rv); if (rv != SCARD_S_SUCCESS) { PCSC_TRACE(reader, "SCardReconnect failed", rv); @@ -593,7 +593,7 @@ static void initialize_uid(sc_reader_t *reader) sc_log_hex(reader->ctx, "UID", reader->uid.value, reader->uid.len); } else { - sc_log(reader->ctx, "unable to get UID"); + sc_log(reader->ctx, "unable to get UID"); } } } @@ -1177,7 +1177,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) priv->modify_ioctl_finish = ntohl(pcsc_tlv->value); } else if (pcsc_tlv->tag == FEATURE_IFD_PIN_PROPERTIES) { priv->pin_properties_ioctl = ntohl(pcsc_tlv->value); - } else if (pcsc_tlv->tag == FEATURE_GET_TLV_PROPERTIES) { + } else if (pcsc_tlv->tag == FEATURE_GET_TLV_PROPERTIES) { priv->get_tlv_properties = ntohl(pcsc_tlv->value); } else if (pcsc_tlv->tag == FEATURE_EXECUTE_PACE) { priv->pace_ioctl = ntohl(pcsc_tlv->value); @@ -1240,11 +1240,11 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) sc_log(ctx, "Reader has a display: %04X", caps->wLcdLayout); reader->capabilities |= SC_READER_CAP_DISPLAY; } - else { + else { sc_log(ctx, "Reader does not have a display."); } } - else { + else { sc_log(ctx, "Returned PIN properties structure has bad length (%lu/%"SC_FORMAT_LEN_SIZE_T"u)", (unsigned long)rcount, @@ -1266,34 +1266,55 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } } + size_t max_send_size = 0; + size_t max_recv_size = 0; if (priv->get_tlv_properties) { /* Try to set reader max_send_size and max_recv_size based on * detected max_data */ - int max_data = part10_detect_max_data(reader, card_handle); - - if (max_data > 0) { - sc_log(ctx, "Reader supports transceiving %d bytes of data", - max_data); - if (!priv->gpriv->force_max_send_size) - reader->max_send_size = max_data; - else - sc_log(ctx, "Sending is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" - " in configuration file", reader->max_send_size); - if (!priv->gpriv->force_max_recv_size) - reader->max_recv_size = max_data; - else - sc_log(ctx, "Receiving is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" - " in configuration file", reader->max_recv_size); - } else { - sc_log(ctx, "Assuming that the reader supports transceiving " - "short length APDUs only"); - } + max_send_size = max_recv_size = part10_detect_max_data(reader, card_handle); /* debug the product and vendor ID of the reader */ part10_get_vendor_product(reader, card_handle, NULL, NULL); } + else { + /* Try to set default limits based on device name */ + if (!strncmp("REINER SCT cyberJack", reader->name, 20)) { + max_send_size = 1014; + max_recv_size = 1014; + } + else if (!strncmp("Secure Flash Card", reader->name, 17)) { + max_send_size = 478; + max_recv_size = 506; + } + } - if(gpriv->SCardGetAttrib != NULL) { + if (max_send_size > 0) { + sc_log(ctx, "Reader supports sending %"SC_FORMAT_LEN_SIZE_T"u bytes of data", + max_send_size); + if (!priv->gpriv->force_max_send_size) + reader->max_send_size = max_send_size; + else + sc_log(ctx, "Sending is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" + " in configuration file", reader->max_send_size); + } else { + sc_log(ctx, "Assuming that the reader supports sending " + "short length APDUs only"); + } + + if (max_recv_size > 0) { + sc_log(ctx, "Reader supports receiving %"SC_FORMAT_LEN_SIZE_T"u bytes of data", + max_recv_size); + if (!priv->gpriv->force_max_recv_size) + reader->max_recv_size = max_recv_size; + else + sc_log(ctx, "Receiving is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" + " in configuration file", reader->max_recv_size); + } else { + sc_log(ctx, "Assuming that the reader supports receiving " + "short length APDUs only"); + } + + if (gpriv->SCardGetAttrib != NULL) { rcount = sizeof(buf); if (gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_NAME, buf, &rcount) == SCARD_S_SUCCESS @@ -1304,7 +1325,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } rcount = sizeof i; - if(gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_IFD_VERSION, + if (gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_IFD_VERSION, (u8 *) &i, &rcount) == SCARD_S_SUCCESS && rcount == sizeof i) { reader->version_major = (i >> 24) & 0xFF; @@ -1314,7 +1335,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } int pcsc_add_reader(sc_context_t *ctx, - char *reader_name, size_t reader_name_len, + char *reader_name, size_t reader_name_len, sc_reader_t **out_reader) { int ret = SC_ERROR_INTERNAL; @@ -1574,7 +1595,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re LOG_FUNC_CALLED(ctx); - if (!event_reader && !event && reader_states) { + if (!event_reader && !event && reader_states) { sc_log(ctx, "free allocated reader states"); free(*reader_states); *reader_states = NULL; @@ -1684,7 +1705,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re state = rsp->dwEventState; rsp->dwCurrentState = rsp->dwEventState; if (state & SCARD_STATE_CHANGED) { - /* check for hotplug events */ + /* check for hotplug events */ if (!strcmp(rsp->szReader, "\\\\?PnP?\\Notification")) { sc_log(ctx, "detected hotplug event"); /* Windows sends hotplug event on both, attaching and @@ -1859,7 +1880,7 @@ static int part10_build_verify_pin_block(struct sc_reader *reader, u8 * buf, siz u8 tmp; unsigned int tmp16; unsigned int off; - PIN_VERIFY_STRUCTURE *pin_verify = (PIN_VERIFY_STRUCTURE *)buf; + PIN_VERIFY_STRUCTURE *pin_verify = (PIN_VERIFY_STRUCTURE *)buf; /* PIN verification control message */ pin_verify->bTimerOut = SC_CCID_PIN_TIMEOUT; @@ -1958,7 +1979,7 @@ static int part10_build_modify_pin_block(struct sc_reader *reader, u8 * buf, siz sc_apdu_t *apdu = data->apdu; u8 tmp; unsigned int tmp16; - PIN_MODIFY_STRUCTURE *pin_modify = (PIN_MODIFY_STRUCTURE *)buf; + PIN_MODIFY_STRUCTURE *pin_modify = (PIN_MODIFY_STRUCTURE *)buf; struct sc_pin_cmd_pin *pin_ref = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? &data->pin2 : &data->pin1; @@ -2569,7 +2590,7 @@ int pcsc_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_c gpriv->attached_reader = NULL; gpriv->pcsc_ctx = *(SCARDCONTEXT *)pcsc_context_handle; - card_handle = *(SCARDHANDLE *)pcsc_card_handle; + card_handle = *(SCARDHANDLE *)pcsc_card_handle; if(SCARD_S_SUCCESS == gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_DEVICE_SYSTEM_NAME_A, (LPBYTE) diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index a83c719cb9..e5758ba4d5 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -108,9 +108,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_parse_unusedspace(buf, buf_len, p15card); - sc_pkcs15_card_free(p15card); - err: + sc_pkcs15_card_free(p15card); sc_disconnect_card(card); sc_release_context(ctx); return 0; diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c index eb3436dae2..a10ecf5645 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_encode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c @@ -80,8 +80,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) sc_pkcs15_encode_unusedspace(ctx, p15card, &unused_space, &unused_space_len); free(unused_space); - sc_pkcs15_card_free(p15card); err: + sc_pkcs15_card_free(p15card); sc_disconnect_card(card); sc_release_context(ctx); From 2655e9e01bc58062d2f9cd83384fa0355e4bed4b Mon Sep 17 00:00:00 2001 From: David Legault Date: Tue, 7 Feb 2023 10:01:33 -0500 Subject: [PATCH 2735/4321] Add support for basic attribute filtering to list objects (#2687) fixes #2627 --- doc/tools/pkcs11-tool.1.xml | 7 ++++++- src/tools/pkcs11-tool.c | 38 +++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index e05065e6c8..a27a4b1c2b 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -208,7 +208,12 @@ , - Display a list of objects. + + Display a list of objects. + The options , + , or can be + used to filter the listed objects. + diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f2e6b1dd91..4c4a6dd287 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -526,7 +526,7 @@ static void show_cryptoki_info(void); static void list_slots(int, int, int); static void show_token(CK_SLOT_ID); static void list_mechs(CK_SLOT_ID); -static void list_objects(CK_SESSION_HANDLE, CK_OBJECT_CLASS); +static void list_objects(CK_SESSION_HANDLE); static void list_interfaces(void); static int login(CK_SESSION_HANDLE, int); static void init_token(CK_SLOT_ID); @@ -1400,7 +1400,7 @@ int main(int argc, char * argv[]) derive_key(opt_slot, session, object); if (do_list_objects) - list_objects(session, opt_object_class); + list_objects(session); if (do_sign) sign_data(opt_slot, session, object); @@ -4628,13 +4628,39 @@ find_mechanism(CK_SLOT_ID slot, CK_FLAGS flags, } -static void list_objects(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS object_class) +static void list_objects(CK_SESSION_HANDLE sess) { CK_OBJECT_HANDLE object; CK_ULONG count; + CK_ATTRIBUTE attrs[10]; + CK_ULONG nn_attrs = 0; CK_RV rv; - rv = p11->C_FindObjectsInit(sess, NULL, 0); + if (opt_object_class_str != NULL) { + FILL_ATTR(attrs[nn_attrs], CKA_CLASS, + &opt_object_class, sizeof(opt_object_class)); + nn_attrs++; + } + + if (opt_object_id_len != 0) { + FILL_ATTR(attrs[nn_attrs], CKA_ID, + opt_object_id, opt_object_id_len); + nn_attrs++; + } + + if (opt_object_label != NULL) { + FILL_ATTR(attrs[nn_attrs], CKA_LABEL, + opt_object_label, strlen(opt_object_label)); + nn_attrs++; + } + + if (opt_application_label != NULL) { + FILL_ATTR(attrs[nn_attrs], CKA_APPLICATION, + opt_application_label, strlen(opt_application_label)); + nn_attrs++; + } + + rv = p11->C_FindObjectsInit(sess, attrs, nn_attrs); if (rv != CKR_OK) p11_fatal("C_FindObjectsInit", rv); @@ -4644,8 +4670,8 @@ static void list_objects(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS object_class) p11_fatal("C_FindObjects", rv); if (count == 0) break; - if ((int) object_class == -1 || object_class == getCLASS(sess, object)) - show_object(sess, object); + + show_object(sess, object); } p11->C_FindObjectsFinal(sess); } From 87bb953b519b875458f81aa07df7b9d37c3da959 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 10 Jan 2023 14:59:43 +0100 Subject: [PATCH 2736/4321] pkcs11-spy: Add missing newline --- src/pkcs11/pkcs11-spy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 56dd2eaf7f..fa407fbf1f 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -696,7 +696,7 @@ C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, enter("C_GetMechanismInfo"); spy_dump_ulong_in("slotID", slotID); - FPRINTF_LOOKUP_ENUM("[in] type = %s", MEC_T, type); + FPRINTF_LOOKUP_ENUM("[in] type = %s\n", MEC_T, type); rv = po->C_GetMechanismInfo(slotID, type, pInfo); if(rv == CKR_OK) { From fe7cc6982abd81b3c5a1b566434bcb05adf6d026 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 26 Jan 2023 15:48:50 +0100 Subject: [PATCH 2737/4321] tests: Add missing module for sign/verify test --- tests/test-pkcs11-tool-sign-verify.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 9de0879920..69a794e356 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -157,9 +157,9 @@ for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do echo "=======================================================" $PKCS11_TOOL --login --pin=1234 --sign --mechanism=$MECHANISM \ - --input-file=data.msg --output-file=data.sig + --input-file=data.msg --output-file=data.sig --module $P11LIB $PKCS11_TOOL --login --pin=1234 --verify --mechanism=$MECHANISM \ - --input-file=data.msg --signature-file=data.sig + --input-file=data.msg --signature-file=data.sig --module $P11LIB rm data.sig done; From 7e882ae62d923cb65ecabd5f7d9f542f3f0f2434 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 26 Jan 2023 07:59:41 -0600 Subject: [PATCH 2738/4321] setup-linux.sh - do wine install last reorder "sudo dpkg --add-architecture i386" till after first update and the https://github.com/actions/virtual-environments/issues/4589 which removes a number of packages. Then do "sudo dpkg --add-architecture i386" so next update will add all the i386 packages Install any wine packages last. Previous code would fail when called to build-ix86 but work with build-mingw32 and build-mingw All 3 call setup-linux.sh Date: Thu Jan 26 07:59:41 2023 -0600 Changes to be committed: modified: .github/setup-linux.sh --- .github/setup-linux.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index aa771656ce..7d7c9ebce3 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -2,12 +2,12 @@ set -ex -o xtrace +WINE_DEPS="" # Generic dependencies DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd openssl" # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then - sudo dpkg --add-architecture i386 DEPS="$DEPS gcc-multilib libpcsclite-dev:i386 libcmocka-dev:i386 libssl-dev:i386 zlib1g-dev:i386 libreadline-dev:i386 softhsm2:i386" else DEPS="$DEPS libpcsclite-dev libcmocka-dev libssl-dev zlib1g-dev libreadline-dev softhsm2" @@ -27,27 +27,28 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then # Note, that this list is somehow magic and adding libwine, libwine:i386 or wine64 # will make the following sections break without any useful logs. See GH#2458 - DEPS="$DEPS wine wine32 xvfb wget" - sudo dpkg --add-architecture i386 + WINE_DEPS="wine wine32 xvfb wget" if [ "$1" == "mingw" ]; then - DEPS="$DEPS binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" + WINE_DEPS="$WINE_DEPS binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" elif [ "$1" == "mingw32" ]; then - DEPS="$DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686" + WINE_DEPS="$WINE_DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686" fi fi -# The Github's Ubuntu images since 20211122.1 are broken +# The Github Ubuntu images since 20211122.1 are broken # https://github.com/actions/virtual-environments/issues/4589 if [ "$1" == "mingw" -o "$1" == "mingw32" -o "$1" == "ix86" ]; then sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo apt-get update -qq sudo apt-get purge -yqq libmono* moby* mono* php* libgdiplus libpcre2-posix3 libzip4 + sudo dpkg --add-architecture i386 fi # make sure we do not get prompts export DEBIAN_FRONTEND=noninteractive export DEBCONF_NONINTERACTIVE_SEEN=true -sudo apt-get update +sudo apt-get update -qq + sudo apt-get install -y build-essential $DEPS # install libressl if needed @@ -56,6 +57,7 @@ if [ "$1" == "libressl" -o "$2" == "libressl" ]; then fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then + sudo apt-get install -y $WINE_DEPS if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 export DISPLAY=:99.0 From 1b2ab29c908e559c3919a443ac5da7f6f7e4cfb3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 26 Jan 2023 10:45:39 +0100 Subject: [PATCH 2739/4321] Run builds and tests directly on Fedora The default ubuntu images on the Github are more frequently broken than working for this use case and Fedora was suggested as an easy replacement. Based on suggestion from https://github.com/OpenSC/OpenSC/pull/2661 --- .github/setup-fedora.sh | 21 +++++++++++++++++++++ .github/workflows/fedora.yml | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100755 .github/setup-fedora.sh create mode 100644 .github/workflows/fedora.yml diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh new file mode 100755 index 0000000000..d194e6259e --- /dev/null +++ b/.github/setup-fedora.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -ex -o xtrace + +# Generic dependencies +DEPS="make /usr/bin/xsltproc docbook-style-xsl autoconf automake libtool gcc bash-completion vim-common softhsm openssl diffutils gcc-c++" + +# 64bit or 32bit dependencies +if [ "$1" == "ix86" ]; then + DEPS="$DEPS pcsc-lite-devel*.i686 readline-devel*.i686 openssl-devel*.i686 zlib-devel*.i686 libcmocka-devel*.i686 glibc-devel*i686" +else + DEPS="$DEPS pcsc-lite-devel readline-devel openssl-devel zlib-devel libcmocka-devel" +fi + +sudo dnf install -y $DEPS + +# The test-pkcs11-tool-unwrap-wrap-test.sh is broken in Fedora for some reason +sed -i -e '/XFAIL_TESTS/,$ { + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh/ + q +}' tests/Makefile.am diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml new file mode 100644 index 0000000000..c7ec024e9f --- /dev/null +++ b/.github/workflows/fedora.yml @@ -0,0 +1,36 @@ +name: Fedora Linux + +on: + pull_request: + paths: + - '**.c' + - '**.h' + - .github/workflows/fedora.yml + - .github/setup-fedora.sh + - .github/build.sh + - .github/push-artifacts.sh + - '**.am' + - doc/** + push: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + fedora: + runs-on: ubuntu-latest + container: + image: fedora:latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-fedora.sh + - run: .github/build.sh dist + + fedora-ix86: + runs-on: ubuntu-latest + container: + image: fedora:latest + steps: + - uses: actions/checkout@v2 + - run: .github/setup-fedora.sh ix86 + - run: .github/build.sh ix86 From 9581294ad71efb18201ae135df8ece9df33ea4a7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Jan 2023 15:25:37 +0100 Subject: [PATCH 2740/4321] ci: Update all actions to v3 --- .github/workflows/codespell.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/fedora.yml | 4 +-- .github/workflows/linux.yml | 60 ++++++++++++++++----------------- .github/workflows/macos.yml | 8 ++--- .github/workflows/packit.yaml | 4 +-- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 912f4b3d02..8a3a4ac764 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: codespell-project/actions-codespell@master with: skip: ./src/tests/fuzzing/corpus,compat_* diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index caf6b262a5..d3b61914bd 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -13,7 +13,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh - run: ./bootstrap - run: ./configure --disable-dependency-tracking diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index c7ec024e9f..15d9b468f2 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -22,7 +22,7 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-fedora.sh - run: .github/build.sh dist @@ -31,6 +31,6 @@ jobs: container: image: fedora:latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-fedora.sh ix86 - run: .github/build.sh ix86 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2e871b7c5e..84bdbcb6c9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -21,23 +21,23 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh - run: .github/build.sh dist - name: Upload test logs - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: name: ubuntu-test-logs path: tests/*.log - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache-build with: path: ./* key: ${{ runner.os }}-${{ github.sha }} - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-build path: @@ -46,25 +46,25 @@ jobs: build-no-shared: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh - run: .github/build.sh no-shared build-ix86: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh ix86 - run: .github/build.sh ix86 build-mingw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh mingw - run: .github/build.sh mingw - name: Cache build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-build-mingw path: @@ -73,11 +73,11 @@ jobs: build-mingw32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-linux.sh mingw32 - run: .github/build.sh mingw32 - name: Cache build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-build-mingw32 path: @@ -87,8 +87,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -100,8 +100,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -126,8 +126,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -139,8 +139,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -152,8 +152,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -165,8 +165,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -178,8 +178,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* @@ -202,14 +202,14 @@ jobs: name: ubuntu-22-test-logs path: tests/*.log - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache-build if: ${{ success() }} with: path: ./* key: ${{ runner.os }}-22-${{ github.sha }} - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ success() }} with: name: opensc-build @@ -258,7 +258,7 @@ jobs: path: | tests/test-suite.log config.log - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache-build if: ${{ success() }} with: @@ -298,14 +298,14 @@ jobs: runs-on: ubuntu-latest needs: [build, build-mingw] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* key: ${{ runner.os }}-${{ github.sha }} - name: Pull mingw build artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: opensc-build-mingw - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7843e8b9fe..0fe2139ea2 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -22,7 +22,7 @@ jobs: build: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: .github/setup-macos.sh env: KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} @@ -33,7 +33,7 @@ jobs: DEVELOPMENT_TEAM: ${{ secrets.DEVELOPMENT_TEAM }} INSTALLER_SIGN_IDENTITY: ${{ secrets.INSTALLER_SIGN_IDENTITY }} - name: Cache build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-build-macos path: @@ -47,9 +47,9 @@ jobs: runs-on: macos-latest needs: [build] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Pull build artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: opensc-build-macos - run: git config --global user.email "builds@github.com" diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index 17a2529db6..f2f7e5dbc1 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -19,7 +19,7 @@ jobs: fetch-depth: 0 - uses: packit/actions/srpm@main - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-srpm path: @@ -33,7 +33,7 @@ jobs: fetch-depth: 0 - uses: ./.github/actions/packit - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: opensc-rpm path: From 49379b0f0fa6895f2ab0e12462cc6ef9f7512b5c Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Mon, 6 Feb 2023 07:07:42 +0100 Subject: [PATCH 2741/4321] WRAP operation fix for MyEID driver (T0 protocol) apdu.le must be greater than 0, because we expect a result (wrapped key). Although the value 0 seems to be correct in this case (function sc_apdu2bytes() generates the correct field 'Le'), the operation fails in sc_get_response() where Le == 0 generates only SW. From the point of view of the sc_get_response() function, apdu.le here represents the value "Ne" (see ISO 7816-3 section 12.1.2), and thus apdu.le cannot be 0 in this case. Fixes #2694 --- src/libopensc/card-myeid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index de9ec7eb2e..31dd209f3e 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1446,7 +1446,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x84, 0x00); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = 0; + apdu.le = sizeof(rbuf) <= 256 ? sizeof(rbuf) : 256; apdu.lc = 0; r = sc_transmit_apdu(card, &apdu); From b53fc5cdb326d2a3f101980be2a0ae3537617037 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Feb 2023 10:34:11 +0100 Subject: [PATCH 2742/4321] westcos: Generate 2k RSA keys by default Bump the default RSA key size in the westcos tool. The 2k is supported by the driver and using smaller values is no longer recommended and flagged by the github scanning tool as a potential security issue: https://github.com/OpenSC/OpenSC/security/code-scanning/5 --- doc/tools/westcos-tool.1.xml | 2 +- src/tools/westcos-tool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tools/westcos-tool.1.xml b/doc/tools/westcos-tool.1.xml index 9950ecf2cd..6b894a6fd3 100644 --- a/doc/tools/westcos-tool.1.xml +++ b/doc/tools/westcos-tool.1.xml @@ -75,7 +75,7 @@ Generate a private key on the card. The card must not have been finalized and a PIN must be installed (i.e. the file for the PIN must have been created, see option ). - By default the key length is 1536 bits. User authentication is required for + By default the key length is 2048 bits. User authentication is required for this operation. diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 1c87446117..dd4e00bee4 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -384,7 +384,7 @@ int main(int argc, char *argv[]) opt_wait = 1; break; case 'g': - if(keylen == 0) keylen = 1536; + if(keylen == 0) keylen = 2048; break; case 'o': overwrite = 1; From 282ff95532b2479e2316937f5fab734147330bd2 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Wed, 15 Feb 2023 13:54:09 +0100 Subject: [PATCH 2743/4321] fix isoapplet v0 version check --- src/libopensc/card-isoApplet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 36ea7636bf..4e4b06eb36 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -33,7 +33,7 @@ #define ISOAPPLET_ALG_REF_RSA_PAD_PKCS1 0x11 #define ISOAPPLET_ALG_REF_RSA_PAD_PSS 0x12 -#define ISOAPPLET_VERSION_V0 0x0060 +#define ISOAPPLET_VERSION_V0 0x0006 #define ISOAPPLET_VERSION_V1 0x0100 #define ISOAPPLET_API_FEATURE_EXT_APDU 0x01 @@ -232,7 +232,7 @@ isoApplet_init(sc_card_t *card) else if(drvdata->isoapplet_version != ISOAPPLET_VERSION_V0 && drvdata->isoapplet_version != ISOAPPLET_VERSION_V1) { sc_log(card->ctx, "IsoApplet: Mismatching minor version. Proceeding anyway. " - "API versions: Driver (%04X or %04X), applet (%04X)." + "API versions: Driver (%04X or %04X), applet (%04X). " "Please update accordingly whenever possible.", ISOAPPLET_VERSION_V0, ISOAPPLET_VERSION_V1, drvdata->isoapplet_version); } From c18fb0978ecb9080f82d14e546e43e51ad0e9cad Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 9 Feb 2023 14:59:25 +0100 Subject: [PATCH 2744/4321] Remove only -lglib-2.0 from GIO_LIBS2 given by pkg-config --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 03b546f8a3..ab6cc587ef 100644 --- a/configure.ac +++ b/configure.ac @@ -554,10 +554,8 @@ case "${host}" in have_notify="no" have_gio2="no" ]) LIBS="$saved_LIBS" - if test "${have_gio2}" = "yes"; then - # we do not need lglib-2.0 - GIO2_LIBS="-lgio-2.0 -lgobject-2.0" - fi + # we do not need glib-2.0 + GIO2_LIBS=$(echo "$GIO2_LIBS" | sed 's/-lglib-2.0//g') ;; esac From 01ccd42a6624be0127c090631b8f702a8bb70870 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 09:28:59 +0100 Subject: [PATCH 2745/4321] Run github CI on changes of configure.ac --- .github/workflows/fedora.yml | 1 + .github/workflows/linux.yml | 1 + .github/workflows/macos.yml | 1 + .github/workflows/packit.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 15d9b468f2..158b34587f 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -11,6 +11,7 @@ on: - .github/push-artifacts.sh - '**.am' - doc/** + - configure.ac push: permissions: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 84bdbcb6c9..8a2458a5cb 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,6 +12,7 @@ on: - .github/push-artifacts.sh - '**.am' - doc/** + - configure.ac push: permissions: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0fe2139ea2..dc2296eaa7 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,6 +13,7 @@ on: - .github/push-artifacts.sh - '**.am' - MacOSX/** + - configure.ac push: permissions: diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index f2f7e5dbc1..e8c0f5b5d6 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -7,6 +7,7 @@ on: - '**.am' - .github/workflows/packit.yaml - packaging/opensc.spec + - configure.ac push: jobs: From 88ff714e0ea16a462ff5538d3634a10ed729a1d5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 Feb 2023 21:06:21 +0100 Subject: [PATCH 2746/4321] update ax_pthread to version 31 (autoconf-archive-2022.02.11) The OSX build was failing with the old version giving the following errors: autoreconf: running: /usr/local/Cellar/autoconf/2.71/bin/autoconf --force configure.ac:485: warning: $as_echo is obsolete; use AS_ECHO(["message"]) instead Signed-off-by: Jakub Jelen --- m4/ax_pthread.m4 | 251 +++++++++++++++++++++++++++-------------------- 1 file changed, 144 insertions(+), 107 deletions(-) diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 index 5fbf9fe0d6..9f35d13914 100644 --- a/m4/ax_pthread.m4 +++ b/m4/ax_pthread.m4 @@ -14,20 +14,24 @@ # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to @@ -55,6 +59,7 @@ # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -82,7 +87,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 24 +#serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -104,6 +109,7 @@ if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) @@ -123,10 +129,12 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" @@ -194,14 +202,47 @@ case $host_os in # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + AS_IF([test "x$GCC" = "xyes"], - [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is @@ -224,25 +265,86 @@ AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -# Are we compiling with Clang? -AC_CACHE_CHECK([whether $CC is Clang], - [ax_cv_PTHREAD_CLANG], - [ax_cv_PTHREAD_CLANG=no - # Note that Autoconf sets GCC=yes for Clang as well as GCC - if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) - fi - ]) -ax_pthread_clang="$ax_cv_PTHREAD_CLANG" +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi -ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way @@ -261,11 +363,6 @@ if test "x$ax_pthread_clang" = "xyes"; then # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - - ax_pthread_ok=yes - # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused @@ -294,7 +391,7 @@ if test "x$ax_pthread_clang" = "xyes"; then # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do @@ -320,78 +417,7 @@ if test "x$ax_pthread_clang" = "xyes"; then fi # $ax_pthread_clang = yes -if test "x$ax_pthread_ok" = "xno"; then -for ax_pthread_try_flag in $ax_pthread_flags; do - - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac - - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then @@ -438,7 +464,8 @@ if test "x$ax_pthread_ok" = "xyes"; then AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) @@ -460,18 +487,28 @@ if test "x$ax_pthread_ok" = "xyes"; then [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then From 7013628c9e1167fd21d087eebc6b01091ff28726 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 Feb 2023 21:20:27 +0100 Subject: [PATCH 2747/4321] ci: Install pkgconfig for OSX --- .github/setup-macos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-macos.sh b/.github/setup-macos.sh index 3743d94b3b..ac1770f187 100755 --- a/.github/setup-macos.sh +++ b/.github/setup-macos.sh @@ -2,7 +2,7 @@ set -ex -o xtrace -brew install automake gengetopt help2man +brew install automake gengetopt help2man pkgconfig # openSCToken export PATH="/usr/local/opt/ccache/libexec:$PATH" From 3fdba8821239e3131ad834f2d23d2f86d319c32d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 22 Feb 2023 21:47:39 +0100 Subject: [PATCH 2748/4321] ci: Update isoapplet v1 cache action to v3 to work with the rest of the pipeline --- .github/workflows/linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 8a2458a5cb..36cdc904ea 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -114,8 +114,8 @@ jobs: runs-on: ubuntu-20.04 needs: [build] steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 id: cache-build with: path: ./* From 396856843f887f1f524fe76cf91ec6027c9a9a5b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Feb 2023 09:06:59 +0100 Subject: [PATCH 2749/4321] CI: pin macos-12 to allow building for macOS 10.12 Xcode 14 is the last version which ships the SDK for 10.12. So we are pinning the Github Runner to macos-12, which still has this version installed. This avoids the following warning: /Users/runner/work/OpenSC/OpenSC/OpenSCToken/OpenSCTokenApp.xcodeproj: warning: The macOS deployment target 'MACOSX_DEPLOYMENT_TARGET' is set to 10.12, but the range of supported deployment target versions is 10.13 to 13.1.99. (in target 'OpenSCTokenApp' from project 'OpenSCTokenApp') warning: ONLY_ACTIVE_ARCH=YES requested with multiple ARCHS and no active architecture could be computed; building for all applicable architectures (in target 'OpenSCTokenApp' from project 'OpenSCTokenApp') --- .github/workflows/macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index dc2296eaa7..4c8ab1fa72 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -21,7 +21,7 @@ permissions: jobs: build: - runs-on: macos-latest + runs-on: macos-12 steps: - uses: actions/checkout@v3 - run: .github/setup-macos.sh @@ -45,7 +45,7 @@ jobs: PASS_SECRETS_TAR_ENC: ${{ secrets.PASS_SECRETS_TAR_ENC }} push-artifacts: - runs-on: macos-latest + runs-on: macos-12 needs: [build] steps: - uses: actions/checkout@v3 From 16fdd70a7e02bc87c14d363ca21777b293cdcf2c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 28 Jan 2022 23:17:50 +0100 Subject: [PATCH 2750/4321] enable use_file_cache for static cards use_file_cache is initially only activated for cards that can't be modified with OpenSC (i.e. with pkcs15-init). However, don't enable cache for PIV by default as many people are experimenting with a Yubikey. This also fixes a syntax error in opensc.conf.5.xml.in in the documentation for `use_file_caching` fixes https://github.com/OpenSC/OpenSC/issues/2444 --- README.md | 1 + doc/files/files.html | 27 ++++++++++++++++++--- doc/files/opensc.conf.5.xml.in | 29 ++++++++++++++++++---- etc/opensc.conf | 3 --- etc/opensc.conf.example.in | 2 +- src/libopensc/pkcs15.c | 44 ++++++++++++++++++++++++++++++++-- 6 files changed, 93 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 03209e0cfd..ff41e9fd71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # OpenSC documentation + Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki) Please take a look at the documentation before trying to use OpenSC. diff --git a/doc/files/files.html b/doc/files/files.html index 836aa933ec..68b8a6e9b7 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -745,7 +745,7 @@ locked").

    Configuration of PKCS#15 Framework

    - use_file_caching = bool; + use_file_caching = value;

    Whether to cache the card's files (e.g. certificates) on disk in @@ -758,7 +758,28 @@

  • no: File caching disabled.

  • - (Default:no). + (Default: public + for the following card drivers + akis, + atrust-acos, + belpic, + cac1, + cac, + coolkey, + dnie, + edo, + esteid2018, + flex, + cyberflex, + gemsafeV1, + idprime, + itacns, + jpki, + MaskTech, + mcrd, + npa, + nqapplet, + tcos and otherwise no).

    If caching is done by a system process, the cached files may be placed inaccessible from @@ -847,7 +868,7 @@ List of the builtin pkcs15 emulators to test (Default: internal)

    - Special value internal will try all not disabled builtin pkcs15 emulators. + Special value of internal will try all not disabled builtin pkcs15 emulators.

    Special value of old will try all disabled pkcs15 emulators.

    diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 02bcea76b2..44ffce2d51 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1123,7 +1123,7 @@ app application { - + Whether to cache the card's files (e.g. @@ -1134,14 +1134,35 @@ app application { yes: Cache all files (public and private). - public: Cache only public files. + public: Cache only public files. - no: File caching disabled. + no: File caching disabled. - (Default: no). + (Default: public + for the following card drivers + akis, + atrust-acos, + belpic, + cac1, + cac, + coolkey, + dnie, + edo, + esteid2018, + flex, + cyberflex, + gemsafeV1, + idprime, + itacns, + jpki, + MaskTech, + mcrd, + npa, + nqapplet, + tcos and otherwise no). If caching is done by a system process, the diff --git a/etc/opensc.conf b/etc/opensc.conf index fd88538b84..8162091961 100644 --- a/etc/opensc.conf +++ b/etc/opensc.conf @@ -1,7 +1,4 @@ app default { # debug = 3; # debug_file = opensc-debug.txt; - framework pkcs15 { - # use_file_caching = public; - } } diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index b8c621a5d1..6f70d87f1f 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -883,7 +883,7 @@ app default { # inaccessible from the user account. Use a global caching directory if # you wish to share the cached information. # - # Default: no + # Default: `public` for static cards, `false` otherwise # use_file_caching = public; # # set a path for caching diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 4054f8e8ea..1e96137bbc 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1212,6 +1212,46 @@ sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid) } +const char *pkcs15_get_default_use_file_cache(struct sc_card *card) +{ + /* enable file caching by default for cards with static content to avoid + * synchronization problems. + * + * The following list was initialized with the cards that can't be modified + * with OpenSC i.e. which don't have a profile/driver for pkcs15-init. */ + const char *card_drivers_with_file_cache[] = { + "akis", + "atrust-acos", + "belpic", + "cac1", + "cac", + "coolkey", + "dnie", + "edo", + "esteid2018", + "flex", + "cyberflex", + "gemsafeV1", + "idprime", + "itacns", + "jpki", + "MaskTech", + "mcrd", + "npa", + "nqapplet", + "tcos", + }; + + if (NULL == card || NULL == card->driver || NULL == card->driver->short_name) + return "no"; + for (size_t i = 0; i < (sizeof card_drivers_with_file_cache / sizeof *card_drivers_with_file_cache); i++) { + if (0 == strcmp(card->driver->short_name, card_drivers_with_file_cache[i])) + return "public"; + } + + return "no"; +} + int sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, struct sc_pkcs15_card **p15card_out) @@ -1237,11 +1277,11 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->card = card; p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES; - use_file_cache = "no"; + use_file_cache = pkcs15_get_default_use_file_cache(card); p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; - if(0 == strcmp(ctx->app_name, "tokend")) { + if (0 == strcmp(ctx->app_name, "tokend")) { private_certificate = "ignore"; p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; } else { From 9e1b5b2836cadde19cbf58e771f6a93c7811f977 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 26 Feb 2023 15:58:15 -0600 Subject: [PATCH 2751/4321] Minidriver - handle pin ROLE_EVERYONE Needed for private keys that do not require a PIN Changes to be committed: modified: minidriver/minidriver.c --- src/minidriver/minidriver.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 4790f31de4..1c98fb0be3 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -6381,7 +6381,7 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, if (dwFlags >= MD_MAX_PINS) MD_FUNC_RETURN(pCardData, 1, SCARD_E_INVALID_PARAMETER); - if (!vs->pin_objs[dwFlags]) + if (dwFlags != ROLE_EVERYONE && vs->pin_objs[dwFlags] == NULL) MD_FUNC_RETURN(pCardData, 1, SCARD_E_INVALID_PARAMETER); p->PinType = vs->reader->capabilities & SC_READER_CAP_PIN_PAD @@ -6389,6 +6389,18 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData, ? ExternalPinType : AlphaNumericPinType; p->dwFlags = 0; switch (dwFlags) { + case ROLE_EVERYONE: + logprintf(pCardData, 2, + "returning info on PIN ROLE_EVERYONE [%lu]\n", + (unsigned long)dwFlags); + p->PinType = 0; /* There is no pin, so don't need reader capabilities */ + p->PinPurpose = 0; /* It can not be PrimaryCardPin */ + p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION; + p->PinCachePolicy.PinCachePolicyType = PinCacheNone; + p->PinCachePolicy.dwPinCachePolicyInfo = 0; + p->dwChangePermission = 0; + break; + case ROLE_ADMIN: logprintf(pCardData, 2, "returning info on PIN ROLE_ADMIN ( Unblock ) [%lu]\n", From beeb83a120bc8ab9e22db31906d17b4795e8f67b Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 27 Feb 2023 13:03:20 -0600 Subject: [PATCH 2752/4321] Minidriver - Don't use RSA PAD flags with EC keys SC_ALGORITHM_RSA_HASH_SHA* are also SC_ALGORITHM_ECDSA_HASH_SHA* Turn off any RSA PAD flags if key is EC On branch minidriver-EC-2 Changes to be committed: modified: minidriver/minidriver.c --- src/minidriver/minidriver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 1c98fb0be3..4cec696b10 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4696,7 +4696,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO ALG_ID hashAlg; sc_pkcs15_prkey_info_t *prkey_info; BYTE dataToSign[0x200]; - int opt_crypt_flags; + int opt_crypt_flags = 0; size_t dataToSignLen = sizeof(dataToSign); sc_pkcs15_object_t *pkey; @@ -4788,7 +4788,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO * padding and use the value in aiHashAlg. */ logprintf(pCardData, 3, "CARD_PADDING_INFO_PRESENT not set\n"); - opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; /* turn off later if key is EC */ if (hashAlg == CALG_MD5) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; else if (hashAlg == CALG_SHA1) @@ -4912,6 +4912,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO dwret = SCARD_E_INVALID_VALUE; goto err; } + opt_crypt_flags &= ~SC_ALGORITHM_RSA_PADS; /* EC does not use this */ } else { logprintf(pCardData, 0, "invalid private key\n"); dwret = SCARD_E_INVALID_VALUE; From c16d4e6588a19f4b85aa584174335f62efe28aaf Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 8 Feb 2023 14:34:03 +0100 Subject: [PATCH 2753/4321] Check path length to prevent buffer underflow Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53417 --- src/pkcs15init/pkcs15-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 3df03c6e1f..ee27abb0f8 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -708,6 +708,8 @@ sc_pkcs15init_rmdir(struct sc_pkcs15_card *p15card, struct sc_profile *profile, /* Select the parent DF */ path = df->path; + if (path.len <= 2) + return SC_ERROR_INVALID_ARGUMENTS; path.len -= 2; r = sc_select_file(p15card->card, &path, &parent); if (r < 0) From cfb35259357c210bfea461dac4ca31dae7faaa7d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 9 Feb 2023 13:27:17 +0100 Subject: [PATCH 2754/4321] Fix memory leak Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54082 --- src/libopensc/card-coolkey.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index ff3ffd9a75..918dfdc4f0 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2031,7 +2031,8 @@ coolkey_process_combined_object(sc_card_t *card, coolkey_private_data_t *priv, u decompressed_header = (coolkey_decompressed_header_t *)decompressed_object; if (decompressed_object_len < sizeof(coolkey_decompressed_header_t)) { - return SC_ERROR_CORRUPTED_DATA; + r = SC_ERROR_CORRUPTED_DATA; + goto done; } object_offset = bebytes2ushort(decompressed_header->object_offset); object_count = bebytes2ushort(decompressed_header->object_count); From df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 11:47:34 +0100 Subject: [PATCH 2755/4321] Check array bounds Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54312 --- src/libopensc/muscle.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 61a4ec24d8..9d01e0c113 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -181,6 +181,9 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons sc_apdu_t apdu; int r; + if (dataLength + 9 > MSC_MAX_APDU) + return SC_ERROR_INVALID_ARGUMENTS; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x54, 0x00, 0x00); apdu.lc = dataLength + 9; if (card->ctx->debug >= 2) From 475b4fce8fc4d2bbb4d42c446877820539413d85 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 11:57:02 +0100 Subject: [PATCH 2756/4321] Free file in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54456 --- src/libopensc/card-oberthur.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 1fc40f7b35..7e36118c56 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1802,8 +1802,11 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, rv = iso_ops->select_file(card, &tmp_path, &tmp_file); LOG_TEST_RET(card->ctx, rv, "select PUK file"); - if (!tmp_file || tmp_file->size < OBERTHUR_AUTH_MAX_LENGTH_PUK) + if (!tmp_file || tmp_file->size < OBERTHUR_AUTH_MAX_LENGTH_PUK) { + sc_file_free(tmp_file); LOG_TEST_RET(card->ctx, SC_ERROR_FILE_TOO_SMALL, "Oberthur style 'PIN RESET' failed"); + } + sc_file_free(tmp_file); rv = iso_ops->read_binary(card, 0, puk, OBERTHUR_AUTH_MAX_LENGTH_PUK, 0); LOG_TEST_RET(card->ctx, rv, "read PUK file error"); From 4bed31d9f88e92e1466d25c1ccd2b83f7ad805c1 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 12:20:18 +0100 Subject: [PATCH 2757/4321] Fix memory leaks when reading of file fails Free file `tmp_file` when subsequent call to `starcos_select_fid` or `starcos_select_aid` fails. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54508 --- src/libopensc/card-starcos.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 60d876986b..b350374020 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -782,7 +782,6 @@ static int starcos_select_aid(sc_card_t *card, file->id = 0x0000; file->magic = SC_FILE_MAGIC; - free(*file_out); *file_out = file; } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); @@ -899,7 +898,6 @@ static int starcos_select_fid(sc_card_t *card, file->size = 0; file->namelen = 0; file->magic = SC_FILE_MAGIC; - free(*file_out); *file_out = file; } else { /* ok, assume we have a EF */ @@ -920,7 +918,6 @@ static int starcos_select_fid(sc_card_t *card, return r; } - free(*file_out); *file_out = file; } } @@ -973,7 +970,7 @@ static int starcos_select_file(sc_card_t *card, || card->cache.current_path.type != SC_PATH_TYPE_DF_NAME || card->cache.current_path.len != pathlen || memcmp(card->cache.current_path.value, in_path->aid.value, in_path->aid.len) != 0 ) { - r = starcos_select_aid(card, in_path->aid.value, in_path->aid.len, file_out); + r = starcos_select_aid(card, in_path->aid.value, in_path->aid.len, NULL); LOG_TEST_RET(card->ctx, r, "Could not select AID!"); } @@ -988,10 +985,11 @@ static int starcos_select_file(sc_card_t *card, /* Select with 2byte File-ID */ if (pathlen != 2) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); - return starcos_select_fid(card, path[0], path[1], file_out, 1); + r = starcos_select_fid(card, path[0], path[1], file_out, 1); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } else if (pathtype == SC_PATH_TYPE_DF_NAME) - { /* SELECT DF with AID */ + { /* SELECT DF with AID */ /* Select with 1-16byte Application-ID */ if (cache_valid && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME @@ -1002,7 +1000,10 @@ static int starcos_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } else - return starcos_select_aid(card, pathbuf, pathlen, file_out); + { + r = starcos_select_aid(card, pathbuf, pathlen, file_out); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + } } else if (pathtype == SC_PATH_TYPE_PATH) { @@ -1056,8 +1057,11 @@ static int starcos_select_file(sc_card_t *card, if ( cache_valid && bMatch >= 0 ) { if ( pathlen - bMatch == 2 ) + { /* we are in the right directory */ - return starcos_select_fid(card, path[bMatch], path[bMatch+1], file_out, 1); + r = starcos_select_fid(card, path[bMatch], path[bMatch+1], file_out, 1); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + } else if ( pathlen - bMatch > 2 ) { /* two more steps to go */ @@ -1072,7 +1076,8 @@ static int starcos_select_file(sc_card_t *card, new_path.len = pathlen - bMatch-2; memcpy(new_path.value, &(path[bMatch+2]), new_path.len); /* final step: select file */ - return starcos_select_file(card, &new_path, file_out); + r = starcos_select_file(card, &new_path, file_out); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } else /* if (bMatch - pathlen == 0) */ { @@ -1096,7 +1101,7 @@ static int starcos_select_file(sc_card_t *card, *file_out = file; } /* nothing left to do */ - return SC_SUCCESS; + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } } else @@ -1107,7 +1112,8 @@ static int starcos_select_file(sc_card_t *card, r = starcos_select_fid(card, path[i], path[i+1], NULL, 0); LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } - return starcos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out, 1); + r = starcos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out, 1); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } } else From 4a4836b936150e129ce0e525aae1ed64b74caa89 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 14:27:26 +0100 Subject: [PATCH 2758/4321] Free allocated data when the length is 0 Allocated data has size from the selected file, but the resulting length is given by bytes read by sc_read_binary. This prevents memory leaks when freeing pkcs15 object data in sc_pkcs15_free_data_info. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54858 --- src/libopensc/pkcs15.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 1e96137bbc..097e390633 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2504,6 +2504,10 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) { sc_pkcs15_cache_file(p15card, in_path, data, len); } + if (len == 0) { + free(data); + data = NULL; + } } *buf = data; *buflen = len; From 3cc75727177bcabf7dbcf34d0f3177e5d66ef7f3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 14:39:35 +0100 Subject: [PATCH 2759/4321] Check pointer before dereferencing Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55074 --- src/libopensc/card-authentic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 2c16144de6..2e4eba05a8 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -1135,6 +1135,8 @@ authentic_create_file(struct sc_card *card, struct sc_file *file) if (card->cache.valid && card->cache.current_df) { const struct sc_acl_entry *entry = sc_file_get_acl_entry(card->cache.current_df, SC_AC_OP_CREATE); + if (!entry) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); sc_log(ctx, "CREATE method/reference %X/%X", entry->method, entry->key_ref); if (entry->method == SC_AC_SCB) From bdb89174cd5441a279feea258c2792abbbe024ac Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 17 Feb 2023 16:43:32 +0100 Subject: [PATCH 2760/4321] Use sc_file_free() for freeing files Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55567 --- src/pkcs15init/pkcs15-starcos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index b24dc5c9fb..ff89d1224c 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -158,7 +158,7 @@ static int starcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) *p = ipf_file->size & 0xff; ret = sc_card_ctl(card, SC_CARDCTL_STARCOS_CREATE_FILE, &ipf_data); if (ret != SC_SUCCESS) { - free(ipf_file); + sc_file_free(ipf_file); return ret; } /* init IPF */ @@ -239,7 +239,7 @@ static int starcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, *p = ipf_file->size & 0xff; ret = sc_card_ctl(card, SC_CARDCTL_STARCOS_CREATE_FILE, &ipf_data); if (ret != SC_SUCCESS) { - free(ipf_file); + sc_file_free(ipf_file); return ret; } /* init IPF */ From 4985762eaff529afcb4f7ac8e85e0d9f8c4d2ffb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 13:29:42 -0500 Subject: [PATCH 2761/4321] Add support to initialize custom OpenSSL context Add an openssl custom libcontext to sc_context_t and intitalize it if we are using OpenSSL 3.0+ Signed-off-by: Simo Sorce --- src/libopensc/ctx.c | 47 +++++++++++++++++++++++++++++++++- src/libopensc/opensc.h | 6 +++++ src/libopensc/sc-ossl-compat.h | 14 ++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 5b637b8e88..c1643bc489 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -804,6 +804,40 @@ int sc_context_repair(sc_context_t **ctx_out) return SC_SUCCESS; } +#ifdef USE_OPENSSL3_LIBCTX +static int sc_openssl3_init(sc_context_t *ctx) +{ + ctx->ossl3ctx = calloc(1, sizeof(ossl3ctx_t)); + if (ctx->ossl3ctx == NULL) + return SC_ERROR_OUT_OF_MEMORY; + ctx->ossl3ctx->libctx = OSSL_LIB_CTX_new(); + if (ctx->ossl3ctx->libctx == NULL) { + return SC_ERROR_INTERNAL; + } + ctx->ossl3ctx->defprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, + "default"); + if (ctx->ossl3ctx->defprov == NULL) { + OSSL_LIB_CTX_free(ctx->ossl3ctx->libctx); + free(ctx->ossl3ctx); + ctx->ossl3ctx = NULL; + return SC_ERROR_INTERNAL; + } + return SC_SUCCESS; +} + +static void sc_openssl3_deinit(sc_context_t *ctx) +{ + if (ctx->ossl3ctx == NULL) + return; + if (ctx->ossl3ctx->defprov) + OSSL_PROVIDER_unload(ctx->ossl3ctx->defprov); + if (ctx->ossl3ctx->libctx) + OSSL_LIB_CTX_free(ctx->ossl3ctx->libctx); + free(ctx->ossl3ctx); + ctx->ossl3ctx = NULL; +} +#endif + int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) { sc_context_t *ctx; @@ -858,6 +892,15 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) sc_log(ctx, "==================================="); /* first thing in the log */ sc_log(ctx, "opensc version: %s", sc_get_version()); +#ifdef USE_OPENSSL3_LIBCTX + r = sc_openssl3_init(ctx); + if (r != SC_SUCCESS) { + del_drvs(&opts); + sc_release_context(ctx); + return r; + } +#endif + #ifdef ENABLE_PCSC ctx->reader_driver = sc_get_pcsc_driver(); #elif defined(ENABLE_CRYPTOTOKENKIT) @@ -923,7 +966,6 @@ int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t ** return SC_ERROR_NOT_SUPPORTED; } - int sc_release_context(sc_context_t *ctx) { unsigned int i; @@ -948,6 +990,9 @@ int sc_release_context(sc_context_t *ctx) if (drv->dll) sc_dlclose(drv->dll); } +#ifdef USE_OPENSSL3_LIBCTX + sc_openssl3_deinit(ctx); +#endif if (ctx->preferred_language != NULL) free(ctx->preferred_language); if (ctx->mutex != NULL) { diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index c58550d602..958edcb98d 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -867,6 +867,8 @@ typedef struct { #define SC_CTX_FLAG_DISABLE_POPUPS 0x00000010 #define SC_CTX_FLAG_DISABLE_COLORS 0x00000020 +typedef struct ossl3ctx ossl3ctx_t; + typedef struct sc_context { scconf_context *conf; scconf_block *conf_blocks[3]; @@ -889,6 +891,10 @@ typedef struct sc_context { sc_thread_context_t *thread_ctx; void *mutex; +#ifdef ENABLE_OPENSSL + ossl3ctx_t *ossl3ctx; +#endif + unsigned int magic; } sc_context_t; diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 4425da93f3..1b98b9f04d 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -65,6 +65,20 @@ extern "C" { #define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL) #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + +#define USE_OPENSSL3_LIBCTX + +#include +#include + +typedef struct ossl3ctx { + OSSL_LIB_CTX *libctx; + OSSL_PROVIDER *defprov; +} ossl3ctx_t; + +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ From df81788d3bbaa179c577c21b335cf1f06bc1da78 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 13:30:48 -0500 Subject: [PATCH 2762/4321] Convert pkcs11/openssl.c to use the custom osslctx Signed-off-by: Simo Sorce --- src/libopensc/sc-ossl-compat.h | 40 ++++++++++++++ src/pkcs11/openssl.c | 96 ++++++++++++++++++++++++---------- 2 files changed, 109 insertions(+), 27 deletions(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 1b98b9f04d..8e976184b6 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -71,14 +71,54 @@ extern "C" { #include #include +#include typedef struct ossl3ctx { OSSL_LIB_CTX *libctx; OSSL_PROVIDER *defprov; } ossl3ctx_t; +static inline EVP_MD *_sc_evp_md(ossl3ctx_t *ctx, const char *algorithm) +{ + return EVP_MD_fetch(ctx->libctx, algorithm, NULL); +} +#define sc_evp_md(ctx, alg) _sc_evp_md((ctx)->ossl3ctx, alg) + +static inline void sc_evp_md_free(EVP_MD *md) +{ + EVP_MD_free(md); +} + +static inline EVP_PKEY_CTX *_sc_evp_pkey_ctx_new(ossl3ctx_t *ctx, + EVP_PKEY *pkey) +{ + return EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, NULL); +} +#define sc_evp_pkey_ctx_new(ctx, pkey) \ + _sc_evp_pkey_ctx_new((ctx)->ossl3ctx, pkey) + +#else /* OPENSSL < 3 */ + +#include + +static inline EVP_MD *sc_evp_md(void *unused, const char *algorithm) +{ + return (EVP_MD *)EVP_get_digestbyname(algorithm); +} + +static inline void sc_evp_md_free(EVP_MD *md) +{ + return; +} + +static inline EVP_PKEY_CTX *sc_evp_pkey_ctx_new(void *unused, EVP_PKEY *pkey) +{ + return EVP_PKEY_CTX_new(pkey, NULL); +} + #endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 6879e9e061..f62c32fa3f 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -231,6 +231,23 @@ static void * dup_mem(void *in, size_t in_len) return out; } +static CK_RV ossl_md_copy(const void *src, void **dst) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int ret = EVP_MD_up_ref((EVP_MD *)src); + if (ret != 1) { + return CKR_GENERAL_ERROR; + } +#endif + *dst = (EVP_MD *)src; + return CKR_OK; +} + +static void ossl_md_free(const void *md) +{ + sc_evp_md_free((EVP_MD *)md); +} + void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) { @@ -287,38 +304,52 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) #endif /* !defined(OPENSSL_NO_ENGINE) */ #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ - openssl_sha1_mech.mech_data = EVP_sha1(); + openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); + openssl_sha1_mech.free_mech_data = ossl_md_free; + openssl_sha1_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); - openssl_sha224_mech.mech_data = EVP_sha224(); + openssl_sha224_mech.mech_data = sc_evp_md(context, "sha224"); + openssl_sha224_mech.free_mech_data = ossl_md_free; + openssl_sha224_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); - openssl_sha256_mech.mech_data = EVP_sha256(); + openssl_sha256_mech.mech_data = sc_evp_md(context, "sha256"); + openssl_sha256_mech.free_mech_data = ossl_md_free; + openssl_sha256_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); - openssl_sha384_mech.mech_data = EVP_sha384(); + openssl_sha384_mech.mech_data = sc_evp_md(context, "sha384"); + openssl_sha384_mech.free_mech_data = ossl_md_free; + openssl_sha384_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); - openssl_sha512_mech.mech_data = EVP_sha512(); + openssl_sha512_mech.mech_data = sc_evp_md(context, "sha512"); + openssl_sha512_mech.free_mech_data = ossl_md_free; + openssl_sha512_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); if (!FIPS_mode()) { - openssl_md5_mech.mech_data = EVP_md5(); + openssl_md5_mech.mech_data = sc_evp_md(context, "md5"); + openssl_md5_mech.free_mech_data = ossl_md_free; + openssl_md5_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); - openssl_ripemd160_mech.mech_data = EVP_ripemd160(); + openssl_ripemd160_mech.mech_data = sc_evp_md(context, "ripemd160"); + openssl_ripemd160_mech.free_mech_data = ossl_md_free; + openssl_ripemd160_mech.copy_mech_data = ossl_md_copy; mt = dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech); sc_pkcs11_register_mechanism(p11card, mt, NULL); sc_pkcs11_free_mechanism(&mt); @@ -654,22 +685,22 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len || mech->mechanism == CKM_ECDSA_SHA384 || mech->mechanism == CKM_ECDSA_SHA512) { EVP_MD_CTX *mdctx; - const EVP_MD *md; + EVP_MD *md = NULL; switch (mech->mechanism) { case CKM_ECDSA_SHA1: - md = EVP_sha1(); + md = sc_evp_md(context, "sha1"); break; case CKM_ECDSA_SHA224: - md = EVP_sha224(); + md = sc_evp_md(context, "sha224"); break; case CKM_ECDSA_SHA256: - md = EVP_sha256(); + md = sc_evp_md(context, "sha256"); break; case CKM_ECDSA_SHA384: - md = EVP_sha384(); + md = sc_evp_md(context, "sha384"); break; case CKM_ECDSA_SHA512: - md = EVP_sha512(); + md = sc_evp_md(context, "sha512"); break; default: EVP_PKEY_free(pkey); @@ -679,11 +710,13 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len mdbuf = calloc(1, mdbuf_len); if (mdbuf == NULL) { EVP_PKEY_free(pkey); + sc_evp_md_free(md); return CKR_DEVICE_MEMORY; } if ((mdctx = EVP_MD_CTX_new()) == NULL) { free(mdbuf); EVP_PKEY_free(pkey); + sc_evp_md_free(md); return CKR_GENERAL_ERROR; } if (!EVP_DigestInit(mdctx, md) @@ -691,10 +724,12 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len || !EVP_DigestFinal(mdctx, mdbuf, &mdbuf_len)) { EVP_PKEY_free(pkey); EVP_MD_CTX_free(mdctx); + sc_evp_md_free(md); free(mdbuf); return CKR_GENERAL_ERROR; } EVP_MD_CTX_free(mdctx); + sc_evp_md_free(md); data = mdbuf; data_len = mdbuf_len; } @@ -702,7 +737,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len res = 0; r = sc_asn1_sig_value_rs_to_sequence(NULL, signat, signat_len, &signat_tmp, &signat_len_tmp); - ctx = EVP_PKEY_CTX_new(pkey, NULL); + ctx = sc_evp_pkey_ctx_new(context, pkey); if (r == 0 && EVP_PKEY_base_id(pkey) == EVP_PKEY_EC && ctx && EVP_PKEY_verify_init(ctx) == 1) res = EVP_PKEY_verify(ctx, signat_tmp, signat_len_tmp, data, data_len); @@ -721,7 +756,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len } else { unsigned char *rsa_out = NULL, pad; size_t rsa_outlen = 0; - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); + EVP_PKEY_CTX *ctx = sc_evp_pkey_ctx_new(context, pkey); if (!ctx) { EVP_PKEY_free(pkey); return CKR_DEVICE_MEMORY; @@ -783,7 +818,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len mech->mechanism == CKM_SHA384_RSA_PKCS_PSS || mech->mechanism == CKM_SHA512_RSA_PKCS_PSS) { CK_RSA_PKCS_PSS_PARAMS* param = NULL; - const EVP_MD *mgf_md, *pss_md; + EVP_MD *mgf_md = NULL, *pss_md = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; if (mech->pParameter == NULL) { @@ -796,19 +831,19 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len param = (CK_RSA_PKCS_PSS_PARAMS*)mech->pParameter; switch (param->mgf) { case CKG_MGF1_SHA1: - mgf_md = EVP_sha1(); + mgf_md = sc_evp_md(context, "sha1"); break; case CKG_MGF1_SHA224: - mgf_md = EVP_sha224(); + mgf_md = sc_evp_md(context, "sha224"); break; case CKG_MGF1_SHA256: - mgf_md = EVP_sha256(); + mgf_md = sc_evp_md(context, "sha256"); break; case CKG_MGF1_SHA384: - mgf_md = EVP_sha384(); + mgf_md = sc_evp_md(context, "sha384"); break; case CKG_MGF1_SHA512: - mgf_md = EVP_sha512(); + mgf_md = sc_evp_md(context, "sha512"); break; default: free(rsa_out); @@ -818,21 +853,22 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len switch (param->hashAlg) { case CKM_SHA_1: - pss_md = EVP_sha1(); + pss_md = sc_evp_md(context, "sha1"); break; case CKM_SHA224: - pss_md = EVP_sha224(); + pss_md = sc_evp_md(context, "sha224"); break; case CKM_SHA256: - pss_md = EVP_sha256(); + pss_md = sc_evp_md(context, "sha256"); break; case CKM_SHA384: - pss_md = EVP_sha384(); + pss_md = sc_evp_md(context, "sha384"); break; case CKM_SHA512: - pss_md = EVP_sha512(); + pss_md = sc_evp_md(context, "sha512"); break; default: + sc_evp_md_free(mgf_md); free(rsa_out); EVP_PKEY_free(pkey); return CKR_MECHANISM_PARAM_INVALID; @@ -848,6 +884,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len unsigned int tmp_len; if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { + sc_evp_md_free(mgf_md); + sc_evp_md_free(pss_md); free(rsa_out); EVP_PKEY_free(pkey); return CKR_GENERAL_ERROR; @@ -865,13 +903,15 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len else sLen = param->sLen; - if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || + if ((ctx = sc_evp_pkey_ctx_new(context, pkey)) == NULL || EVP_PKEY_verify_init(ctx) != 1 || EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) != 1 || EVP_PKEY_CTX_set_signature_md(ctx, pss_md) != 1 || EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sLen) != 1 || EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf_md) != 1) { sc_log(context, "Failed to initialize EVP_PKEY_CTX"); + sc_evp_md_free(mgf_md); + sc_evp_md_free(pss_md); free(rsa_out); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); @@ -883,6 +923,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len rv = CKR_OK; EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); + sc_evp_md_free(mgf_md); + sc_evp_md_free(pss_md); free(rsa_out); sc_log(context, "Returning %lu", rv); return rv; From 0d34432a9150491c1d3fe9c9bcb0029e2ac59f59 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 15:05:13 -0500 Subject: [PATCH 2763/4321] Load also the legacy provider This is not ideal, but some of the code uses legacy algorithms that are not available without this provider. The code that depends on those legacy algorithms will fail if the legacy provider is not available (which is a legitimate choice by the admin and/or system integrator). Therefore we just report an error but do not fail initialization if the legacy provider is not available. Signed-off-by: Simo Sorce --- src/libopensc/ctx.c | 7 +++++++ src/libopensc/sc-ossl-compat.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index c1643bc489..6d4a7c5593 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -822,6 +822,11 @@ static int sc_openssl3_init(sc_context_t *ctx) ctx->ossl3ctx = NULL; return SC_ERROR_INTERNAL; } + ctx->ossl3ctx->legacyprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, + "legacy"); + if (ctx->ossl3ctx->legacyprov == NULL) { + sc_log(ctx, "Failed to load OpenSSL Legacy provider"); + } return SC_SUCCESS; } @@ -829,6 +834,8 @@ static void sc_openssl3_deinit(sc_context_t *ctx) { if (ctx->ossl3ctx == NULL) return; + if (ctx->ossl3ctx->legacyprov) + OSSL_PROVIDER_unload(ctx->ossl3ctx->legacyprov); if (ctx->ossl3ctx->defprov) OSSL_PROVIDER_unload(ctx->ossl3ctx->defprov); if (ctx->ossl3ctx->libctx) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 8e976184b6..579d7f83f9 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -76,6 +76,7 @@ extern "C" { typedef struct ossl3ctx { OSSL_LIB_CTX *libctx; OSSL_PROVIDER *defprov; + OSSL_PROVIDER *legacyprov; } ossl3ctx_t; static inline EVP_MD *_sc_evp_md(ossl3ctx_t *ctx, const char *algorithm) From 30fad6e1243f7442bda9a0326515624fc90a0cf7 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 14:47:26 -0500 Subject: [PATCH 2764/4321] Add wrappers for EVP_CIPHERs Signed-off-by: Simo Sorce --- src/libopensc/sc-ossl-compat.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 579d7f83f9..942de1175f 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -98,6 +98,17 @@ static inline EVP_PKEY_CTX *_sc_evp_pkey_ctx_new(ossl3ctx_t *ctx, #define sc_evp_pkey_ctx_new(ctx, pkey) \ _sc_evp_pkey_ctx_new((ctx)->ossl3ctx, pkey) +static inline EVP_CIPHER *_sc_evp_cipher(ossl3ctx_t *ctx, const char *algorithm) +{ + return EVP_CIPHER_fetch(ctx->libctx, algorithm, NULL); +} +#define sc_evp_cipher(ctx, alg) _sc_evp_cipher((ctx)->ossl3ctx, alg) + +static inline void sc_evp_cipher_free(EVP_CIPHER *cipher) +{ + EVP_CIPHER_free(cipher); +} + #else /* OPENSSL < 3 */ #include @@ -117,6 +128,16 @@ static inline EVP_PKEY_CTX *sc_evp_pkey_ctx_new(void *unused, EVP_PKEY *pkey) return EVP_PKEY_CTX_new(pkey, NULL); } +static inline EVP_CIPHER *sc_evp_cipher(void *unused, const char *algorithm) +{ + return (EVP_CIPHER *)EVP_get_cipherbyname(algorithm); +} + +static inline void sc_evp_cipher_free(EVP_CIPHER *cipher) +{ + return; +} + #endif From 4b793c3ca055f3d05c2044e5e87fd880287f5f1d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 14:48:46 -0500 Subject: [PATCH 2765/4321] Convert card entersafe to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-entersafe.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 24f2c75877..ec81f0eaa1 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -199,6 +199,8 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *buff, size_t buffsize) { EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER *alg = NULL; + u8 iv[8]={0}; int len; @@ -220,20 +222,27 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); EVP_CIPHER_CTX_set_padding(ctx,0); - if(keylen == 8) - EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, iv); - else if (keylen == 16) - EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv); - else + if (keylen == 8) { + alg = sc_evp_cipher(card->ctx, "DES-ECB"); + EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); + } else if (keylen == 16) { + alg = sc_evp_cipher(card->ctx, "DES-EDE"); + EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); + } else { + EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - + } + len = apdu->lc; if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){ + sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(ctx); sc_log(card->ctx, "entersafe encryption error."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } apdu->lc = len; + sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(ctx); if(apdu->lc!=buffsize) @@ -258,6 +267,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, size_t tmpsize=0,tmpsize_rounded=0; int outl=0; EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER *alg = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -301,7 +311,8 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, goto out; } EVP_CIPHER_CTX_set_padding(ctx,0); - EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, key, iv); + alg = sc_evp_cipher(card->ctx, "DES-CBC"); + EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); if(tmpsize_rounded>8){ if(!EVP_EncryptUpdate(ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){ @@ -338,8 +349,10 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, free(tmp); if(tmp_rounded) free(tmp_rounded); - if (ctx) + if (ctx) { + sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(ctx); + } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } From 870b47fb22fd4fa720b6feb6c83854f3aeb66ff3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 15:41:59 -0500 Subject: [PATCH 2766/4321] Convert card epass2003 to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-epass2003.c | 188 +++++++++++++++++++++------------ 1 file changed, 119 insertions(+), 69 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index d8a88fa376..335dba7dfb 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -238,7 +238,7 @@ static const sec_attr_to_acl_entries_t sec_attr_to_acl_entry[] = { static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out); int epass2003_refresh(struct sc_card *card); -static int hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType); +static int hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType); static int epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) @@ -337,8 +337,8 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned } static int -aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, - const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) +aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysize, + const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) { unsigned char data1[32] = {0}; unsigned char data2[32] = {0}; @@ -354,10 +354,13 @@ aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, int r = SC_ERROR_INTERNAL; unsigned char out[32] = {0}; unsigned char iv0[EVP_MAX_IV_LENGTH] = {0}; - r = openssl_enc(EVP_aes_128_ecb(), key, iv0, data1, 16, out); - if( r != SC_SUCCESS) + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); + r = openssl_enc(alg, key, iv0, data1, 16, out); + if (r != SC_SUCCESS) { + sc_evp_cipher_free(alg); return r; - + } + check = out[0]; enc1 = BN_new(); lenc1 = BN_new(); @@ -396,12 +399,14 @@ aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, for (int i=0;i<16;i++){ data2[i]=data2[i]^k2Bin[offset + i]; } - return openssl_enc(EVP_aes_128_cbc(), key, iv, data2, 16, output); + r = openssl_enc(alg, key, iv, data2, 16, output); + sc_evp_cipher_free(alg); + return r; } static int -aes128_encrypt_cmac(const unsigned char *key, int keysize, - const unsigned char *input, size_t length, unsigned char *output) +aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, + const unsigned char *input, size_t length, unsigned char *output) { size_t mactlen = 0; int r = SC_ERROR_INTERNAL; @@ -424,7 +429,7 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, err: CMAC_CTX_free(ctx); #else - EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL); + EVP_MAC *mac = EVP_MAC_fetch(card->ctx->ossl3ctx->libctx, "cmac", NULL); if(mac == NULL){ return r; } @@ -456,36 +461,50 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, } static int -aes128_encrypt_ecb(const unsigned char *key, int keysize, +aes128_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, const unsigned char *input, size_t length, unsigned char *output) { unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; - return openssl_enc(EVP_aes_128_ecb(), key, iv, input, length, output); + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); + int r; + r = openssl_enc(alg, key, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -aes128_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[16], +aes128_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16], const unsigned char *input, size_t length, unsigned char *output) { - return openssl_enc(EVP_aes_128_cbc(), key, iv, input, length, output); + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC"); + int r; + r = openssl_enc(alg, key, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -aes128_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[16], +aes128_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16], const unsigned char *input, size_t length, unsigned char *output) { - return openssl_dec(EVP_aes_128_cbc(), key, iv, input, length, output); + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC"); + int r; + r = openssl_dec(alg, key, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -des3_encrypt_ecb(const unsigned char *key, int keysize, +des3_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, const unsigned char *input, int length, unsigned char *output) { unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; unsigned char bKey[24] = { 0 }; + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3"); + int r; if (keysize == 16) { memcpy(&bKey[0], key, 16); @@ -495,15 +514,19 @@ des3_encrypt_ecb(const unsigned char *key, int keysize, memcpy(&bKey[0], key, 24); } - return openssl_enc(EVP_des_ede3(), bKey, iv, input, length, output); + r = openssl_enc(alg, bKey, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -des3_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], +des3_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { unsigned char bKey[24] = { 0 }; + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); + int r; if (keysize == 16) { memcpy(&bKey[0], key, 16); @@ -513,15 +536,20 @@ des3_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX memcpy(&bKey[0], key, 24); } - return openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output); + r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -des3_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], +des3_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { unsigned char bKey[24] = { 0 }; + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); + int r; + if (keysize == 16) { memcpy(&bKey[0], key, 16); memcpy(&bKey[16], key, 8); @@ -530,23 +558,35 @@ des3_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX memcpy(&bKey[0], key, 24); } - return openssl_dec(EVP_des_ede3_cbc(), bKey, iv, input, length, output); + r = openssl_dec(alg, bKey, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -des_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], +des_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { - return openssl_enc(EVP_des_cbc(), key, iv, input, length, output); + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC"); + int r; + + r = openssl_enc(alg, key, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } static int -des_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], +des_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], const unsigned char *input, size_t length, unsigned char *output) { - return openssl_dec(EVP_des_cbc(), key, iv, input, length, output); + EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC"); + int r; + + r = openssl_dec(alg, key, iv, input, length, output); + sc_evp_cipher_free(alg); + return r; } @@ -585,15 +625,25 @@ openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length, static int -sha1_digest(const unsigned char *input, size_t length, unsigned char *output) +sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output) { - return openssl_dig(EVP_sha1(), input, length, output); + EVP_MD *md = sc_evp_md(card->ctx, "SHA1"); + int r; + + r = openssl_dig(md, input, length, output); + sc_evp_md_free(md); + return r; } static int -sha256_digest(const unsigned char *input, size_t length, unsigned char *output) +sha256_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output) { - return openssl_dig(EVP_sha256(), input, length, output); + EVP_MD *md = sc_evp_md(card->ctx, "SHA256"); + int r; + + r = openssl_dig(md, input, length, output); + sc_evp_md_free(md); + return r; } @@ -658,22 +708,22 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma /* Step 2,3 - Create S-ENC/S-MAC Session Key */ if (KEY_TYPE_AES == key_type) { if(isFips){ - r = aes128_encrypt_cmac(key_enc, 128, data, 32, exdata->sk_enc); + r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); memset(&data[11], 0x06, 1); - r = aes128_encrypt_cmac(key_mac, 128, data, 32, exdata->sk_mac); + r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); }else{ - r = aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); + r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc failed"); - r = aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac failed"); } } else { - r = des3_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); + r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); - r = des3_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); + r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); } @@ -693,14 +743,14 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma if (KEY_TYPE_AES == key_type) { if(isFips){ - r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); + r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); } else{ - r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); } } else - r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); @@ -758,13 +808,13 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ /* calculate host cryptogram */ if (KEY_TYPE_AES == key_type) { if(isFips){ - r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); + r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); } else{ - r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); + r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); } } else { - r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); + r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); } LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); @@ -783,14 +833,14 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ memset(iv, 0x00, 16); if (KEY_TYPE_AES == key_type) { if(isFips){ - r = aes128_encrypt_cmac(exdata->sk_mac, 128, data, 13, mac); + r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, data, 13, mac); } else{ - r = aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); + r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac); } i = 0; } else { - r = des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); + r = des3_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac); i = 8; } @@ -923,10 +973,10 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap /* encrypt Data */ if (KEY_TYPE_AES == key_type) { - r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); } else { - r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed"); } @@ -1018,7 +1068,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv { apdu_buf[i]=apdu_buf[i]^icv[i]; } - r = aes128_encrypt_cmac(exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); + r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); for (int j=0;j<4;j++) @@ -1027,7 +1077,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv } } else{ - r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); } @@ -1035,12 +1085,12 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv else { unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; unsigned char tmp[8] = { 0 }; - r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed"); - r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); memset(iv, 0x00, sizeof iv); - r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed"); } @@ -1051,7 +1101,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv /* MAC(TLV case 1) */ static int construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len, - unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) + unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) { int r; size_t block_size = 4; @@ -1100,13 +1150,13 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da if (KEY_TYPE_AES == key_type) { if(exdata->bFipsCertification) { - r = aes128_encrypt_cmac_ft(exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); + r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); } else { - r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); } @@ -1115,12 +1165,12 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da { unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; unsigned char tmp[8] = { 0 }; - r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); - r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); memset(iv, 0x00, sizeof iv); - r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); } @@ -1329,9 +1379,9 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned /* decrypt */ if (KEY_TYPE_AES == exdata->smtype) - aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); else - des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); /* unpadding */ while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2)) @@ -2118,7 +2168,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data { if(exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) { - r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); + r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash_data failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); apdu.data = sbuf; @@ -2127,7 +2177,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) { - r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); + r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); LOG_TEST_RET(card->ctx, r, "hash_data failed"); sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); apdu.data = sbuf; @@ -2717,7 +2767,7 @@ internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs1 static int -hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType) +hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType) { if ((NULL == data) || (NULL == hash)) @@ -2728,7 +2778,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign unsigned char data_hash[24] = { 0 }; size_t len = 0; - sha1_digest(data, datalen, data_hash); + sha1_digest(card, data, datalen, data_hash); len = REVERSE_ORDER4(datalen); memcpy(&data_hash[20], &len, 4); memcpy(hash, data_hash, 24); @@ -2738,7 +2788,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign unsigned char data_hash[36] = { 0 }; size_t len = 0; - sha256_digest(data, datalen, data_hash); + sha256_digest(card, data, datalen, data_hash); len = REVERSE_ORDER4(datalen); memcpy(&data_hash[32], &len, 4); memcpy(hash, data_hash, 36); @@ -2819,7 +2869,7 @@ internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin) int r; unsigned char hash[HASH_LEN] = { 0 }; - r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + r = hash_data(card, pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid, @@ -3165,10 +3215,10 @@ external_key_auth(struct sc_card *card, unsigned char kid, r = sc_get_challenge(card, random, 8); LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed"); - r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); - des3_encrypt_cbc(hash, HASH_LEN, iv, random, 8, tmp_data); + des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x01, 0x80 | kid); apdu.lc = apdu.datalen = 8; apdu.data = tmp_data; @@ -3192,7 +3242,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, unsigned char tmp_data[256] = { 0 }; unsigned char maxtries = 0; - r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); LOG_TEST_RET(card->ctx, r, "hash data failed"); r = get_external_key_maxtries(card, &maxtries); From 84a3552fef90b87bc20366b6bdf04618123b7586 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:09:15 -0500 Subject: [PATCH 2767/4321] Remove call to load legacy provider from cwa14890 Library code should *never* arbitrarily load the legacy provider in the default application context. It may literally break or make an application vulnerable by sneaking in unexpected algorithms. This is not needed anymore given we will use an opensc specific context that will not affect the rest of the application (or other libraries). Signed-off-by: Simo Sorce --- src/libopensc/card-authentic.c | 1 - src/libopensc/cwa14890.c | 24 ------------------------ 2 files changed, 25 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 2e4eba05a8..34b36a2121 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -39,7 +39,6 @@ #include "authentic.h" #include -#include #include #include #include diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index c859a956bd..f3f0c5859c 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -49,10 +49,6 @@ # include #endif -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - static OSSL_PROVIDER *legacy_provider = NULL; -#endif - #define MAX_RESP_BUFFER_SIZE 2048 /** @@ -1618,16 +1614,6 @@ int cwa_encode_apdu(sc_card_t * card, tmplen = 0; key = sm_session->session_mac; -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { - msg = "Failed to load legacy provider"; - res = SC_ERROR_INTERNAL; - goto encode_end; - } - } -#endif - if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; @@ -1860,16 +1846,6 @@ int cwa_decode_response(sc_card_t * card, /* set up key for mac computing */ key = sm_session->session_mac; -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { - msg = "Failed to load legacy provider"; - res = SC_ERROR_INTERNAL; - goto response_decode_end; - } - } -#endif - if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; From d5029d41e0dee3e84ed5ac70f5cc7759f696c9f1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:26:54 -0500 Subject: [PATCH 2768/4321] Convert card cwa14890 to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/cwa-dnie.c | 6 +++--- src/libopensc/cwa14890.c | 30 ++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 81092c6b9c..fff0e13df1 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -695,8 +695,8 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; - - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + + ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL); if (!ctx) { #endif sc_log(card->ctx, "Cannot create data for root CA public key"); @@ -895,7 +895,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, EVP_PKEY_CTX *ctx = NULL; LOG_FUNC_CALLED(card->ctx); - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL); if (!ctx) { #endif diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index f3f0c5859c..b8662f4ff1 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -1471,6 +1471,7 @@ int cwa_encode_apdu(sc_card_t * card, u8 *cryptbuf = NULL; EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; unsigned char *key = NULL; int tmplen = 0; @@ -1561,7 +1562,9 @@ int cwa_encode_apdu(sc_card_t * card, *cryptbuf = 0x01; key = sm_session->session_enc; - if (EVP_EncryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || + alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); + + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { @@ -1614,7 +1617,9 @@ int cwa_encode_apdu(sc_card_t * card, tmplen = 0; key = sm_session->session_mac; - if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + sc_evp_cipher_free(alg); + alg = sc_evp_cipher(card->ctx, "DES-ECB"); + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; @@ -1639,7 +1644,10 @@ int cwa_encode_apdu(sc_card_t * card, } /* and apply 3DES to result */ - if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || + sc_evp_cipher_free(alg); + alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); + + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { @@ -1673,6 +1681,7 @@ int cwa_encode_apdu(sc_card_t * card, if (from->resp != to->resp) free(to->resp); encode_end_apdu_valid: + sc_evp_cipher_free(alg); if (cctx) EVP_CIPHER_CTX_free(cctx); if (msg) @@ -1718,6 +1727,7 @@ int cwa_decode_response(sc_card_t * card, struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa; EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; unsigned char *key = NULL; int tmplen = 0; @@ -1846,7 +1856,8 @@ int cwa_decode_response(sc_card_t * card, /* set up key for mac computing */ key = sm_session->session_mac; - if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + alg = sc_evp_cipher(card->ctx, "DES-ECB"); + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { msg = "Error in DES ECB encryption"; res = SC_ERROR_INTERNAL; @@ -1872,7 +1883,10 @@ int cwa_decode_response(sc_card_t * card, } /* finally apply 3DES to result */ - if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || + sc_evp_cipher_free(alg); + alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); + + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { @@ -1928,7 +1942,10 @@ int cwa_decode_response(sc_card_t * card, /* decrypt into response buffer * by using 3DES CBC by mean of kenc and iv={0,...0} */ - if (EVP_DecryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || + sc_evp_cipher_free(alg); + alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); + + if (EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 || EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], e_tlv->len - 1) != 1 || EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) { @@ -1957,6 +1974,7 @@ int cwa_decode_response(sc_card_t * card, res = SC_SUCCESS; response_decode_end: + sc_evp_cipher_free(alg); EVP_CIPHER_CTX_free(cctx); if (buffer) free(buffer); From 23c71da7647d84a6e28ea836ada9c05646cb30de Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:34:53 -0500 Subject: [PATCH 2769/4321] Convert card GIDS to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-gids.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index f25e37de45..f41af2707e 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1959,14 +1959,9 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { u8 buffer3[16+16+8]; int buffer3size = 40; sc_apdu_t apdu; - const EVP_CIPHER *cipher; + EVP_CIPHER *cipher; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - // this is CBC instead of ECB - cipher = EVP_des_ede3_cbc(); - if (!cipher) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); - } // select the admin key sc_format_apdu(card, &apdu, SC_APDU_CASE_3, INS_MANAGE_SECURITY_ENVIRONMENT, 0xC1, 0xA4); @@ -2008,23 +2003,28 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { if (ctx == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } - + cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { EVP_CIPHER_CTX_free(ctx); + sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { EVP_CIPHER_CTX_free(ctx); + sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { EVP_CIPHER_CTX_free(ctx); + sc_evp_cipher_free(cipher); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_free(ctx); ctx = NULL; + sc_evp_cipher_free(cipher); + cipher = NULL; // send it to the card sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00); apdu.lc = sizeof(apduSendReponse); @@ -2047,36 +2047,48 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { if (ctx == NULL) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } + cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { + sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) { sc_log(card->ctx, "unable to decrypt data"); + sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { sc_log(card->ctx, "unable to decrypt final data"); + sc_evp_cipher_free(cipher); EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } sc_log(card->ctx, "data has been decrypted using the key"); if (memcmp(buffer3, randomR1, 16) != 0) { sc_log(card->ctx, "R1 doesn't match"); + sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (memcmp(buffer3 + 16, randomR2, 16) != 0) { sc_log(card->ctx, "R2 doesn't match"); + sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } if (buffer[39] != 0x80) { sc_log(card->ctx, "Padding not found"); + sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); } EVP_CIPHER_CTX_free(ctx); ctx = NULL; + sc_evp_cipher_free(cipher); + cipher = NULL; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); #endif From 48e92e467bd52e0d520f854b39c50471e5b5cd7b Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:40:29 -0500 Subject: [PATCH 2770/4321] Convert card GPK to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-gpk.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 7571e0c042..2e5673359f 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -733,6 +733,7 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, unsigned int len = 0, i; int r = SC_SUCCESS, outl; EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *alg = NULL; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) @@ -756,7 +757,8 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, /* Set IV */ memset(in, 0x00, 8); - EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, priv->key, in); + alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); + EVP_EncryptInit_ex(ctx, alg, NULL, priv->key, in); for (i = 0; i < len; i += 8) { if (!EVP_EncryptUpdate(ctx, out, &outl, &block[i], 8)) { r = SC_ERROR_INTERNAL; @@ -764,6 +766,7 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, } } EVP_CIPHER_CTX_free(ctx); + sc_evp_cipher_free(alg); memcpy((u8 *) (apdu->data + apdu->datalen), out + 5, 3); apdu->datalen += 3; @@ -885,11 +888,12 @@ gpk_create_file(sc_card_t *card, sc_file_t *file) * Set the secure messaging key following a Select FileKey */ static int -gpk_set_filekey(const u8 *key, const u8 *challenge, +gpk_set_filekey(sc_card_t *card, const u8 *key, const u8 *challenge, const u8 *r_rn, u8 *kats) { int r = SC_SUCCESS, outl; EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER * alg = NULL; u8 out[16]; memcpy(out, key+8, 8); @@ -899,7 +903,8 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, if (ctx == NULL) return SC_ERROR_INTERNAL; - EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, NULL); + alg = sc_evp_cipher(card->ctx, "DES-EDE"); + EVP_EncryptInit_ex(ctx, alg, NULL, key, NULL); if (!EVP_EncryptUpdate(ctx, kats, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; @@ -907,7 +912,7 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, r = SC_ERROR_INTERNAL; if (r == SC_SUCCESS) { EVP_CIPHER_CTX_reset(ctx); - EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, out, NULL); + EVP_EncryptInit_ex(ctx, alg, NULL, out, NULL); if (!EVP_EncryptUpdate(ctx, kats+8, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; if (!EVP_CIPHER_CTX_reset(ctx)) @@ -921,13 +926,14 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, */ if (r == SC_SUCCESS) { EVP_CIPHER_CTX_reset(ctx); - EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, kats, NULL); + EVP_EncryptInit_ex(ctx, alg, NULL, kats, NULL); if (!EVP_EncryptUpdate(ctx, out, &outl, challenge, 8)) r = SC_ERROR_INTERNAL; if (memcmp(r_rn, out+4, 4) != 0) r = SC_ERROR_INVALID_ARGUMENTS; } + sc_evp_cipher_free(alg); if (ctx) EVP_CIPHER_CTX_free(ctx); @@ -974,7 +980,7 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen) if (apdu.resplen != 12) { r = SC_ERROR_UNKNOWN_DATA_RECEIVED; } else - if ((r = gpk_set_filekey(buf, rnd, resp, priv->key)) == 0) { + if ((r = gpk_set_filekey(card, buf, rnd, resp, priv->key)) == 0) { priv->key_set = 1; priv->key_reference = key_sfi; } @@ -1521,6 +1527,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) u8 temp[256]; int r = SC_SUCCESS, outl; EVP_CIPHER_CTX * ctx; + EVP_CIPHER * alg; sc_log(card->ctx, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n", args->file->id, args->len, args->datalen); @@ -1549,6 +1556,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } + alg = sc_evp_cipher(card->ctx, "DES-EDE"); EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, priv->key, NULL); for (n = 0; n < args->datalen; n += 8) { if (!EVP_EncryptUpdate(ctx, temp+n, &outl, args->data + n, 8)) { @@ -1556,6 +1564,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) break; } } + sc_evp_cipher_free(alg); if (ctx) EVP_CIPHER_CTX_free(ctx); if (r != SC_SUCCESS) From 2de1a7171171c960528e419e7dc754b75a00c545 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:42:47 -0500 Subject: [PATCH 2771/4321] Convert card IASECC to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-iasecc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 1347ed2393..d8c0863b99 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -3169,7 +3169,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i int r = SC_ERROR_INTERNAL; EVP_MD_CTX *mdctx = NULL; - const EVP_MD *md = NULL; + EVP_MD *md = NULL; SHA_CTX *md_data = NULL; unsigned int md_out_len; SHA_LONG pre_hash_Nl, *hh[5] = {NULL, NULL, NULL, NULL, NULL}; @@ -3186,9 +3186,9 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i in_len); memset(out, 0, sizeof(struct iasecc_qsign_data)); - md = EVP_get_digestbyname("SHA1"); + md = sc_evp_md(ctx, "SHA1"); mdctx = EVP_MD_CTX_new(); - if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { sc_log(ctx, "EVP_DigestInit_ex failed"); goto err; } @@ -3250,6 +3250,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); + sc_evp_md_free(md); LOG_FUNC_RETURN(ctx, r); @@ -3267,7 +3268,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t int r = SC_ERROR_INTERNAL; EVP_MD_CTX *mdctx = NULL; - const EVP_MD *md = NULL; + EVP_MD *md = NULL; SHA256_CTX *md_data; unsigned int md_out_len; @@ -3284,7 +3285,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len); memset(out, 0, sizeof(struct iasecc_qsign_data)); - md = EVP_get_digestbyname("SHA256"); + md = sc_evp_md(ctx, "SHA256"); mdctx = EVP_MD_CTX_new(); if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { sc_log(ctx, "EVP_DigestInit_ex failed"); @@ -3342,6 +3343,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t ERR_print_errors_fp(ctx->debug_file); end: EVP_MD_CTX_free(mdctx); + sc_evp_md_free(md); LOG_FUNC_RETURN(ctx, r); From 410b9b4c451f8b360468b921faa5a186f62c3dea Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:45:15 -0500 Subject: [PATCH 2772/4321] Convert card oberthur to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-oberthur.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 7e36118c56..5455b5aea7 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1336,6 +1336,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a const unsigned char in[8] = {0,0,0,0,0,0,0,0}; unsigned char out[8]; EVP_CIPHER_CTX * ctx = NULL; + EVP_CIPHER *alg = NULL; if (args->len!=8 && args->len!=24) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); @@ -1346,11 +1347,13 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a p2 = 0; if (args->len == 24) - EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, args->data, NULL); + alg = sc_evp_cipher(card->ctx, "DES-EDE"); else - EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, args->data, NULL); + alg = sc_evp_cipher(card->ctx, "DES-ECB"); + EVP_EncryptInit_ex(ctx, alg, NULL, args->data, NULL); rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8); EVP_CIPHER_CTX_free(ctx); + sc_evp_cipher_free(alg); if (rv == 0) { sc_log(card->ctx, "OpenSSL encryption error."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); From bbb53979a57b1ec384806a499f54e3ad79c2be44 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:53:37 -0500 Subject: [PATCH 2773/4321] Convert card PIV to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-piv.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index dffb9e3ebc..aadd4ec242 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1428,17 +1428,27 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, */ #ifdef ENABLE_OPENSSL -static const EVP_CIPHER *get_cipher_for_algo(int alg_id) +static EVP_CIPHER *get_cipher_for_algo(sc_card_t *card, int alg_id) { + const char *algo; switch (alg_id) { - case 0x0: return EVP_des_ede3_ecb(); - case 0x1: return EVP_des_ede3_ecb(); /* 2TDES */ - case 0x3: return EVP_des_ede3_ecb(); - case 0x8: return EVP_aes_128_ecb(); - case 0xA: return EVP_aes_192_ecb(); - case 0xC: return EVP_aes_256_ecb(); + case 0x0: + case 0x1: /* 2TDES */ + case 0x3: + algo = "DES-EDE3-ECB"; + break; + case 0x8: + algo = "AES-128-ECB"; + break; + case 0xA: + algo = "AES-192-ECB"; + break; + case 0xC: + algo = "AES-256-ECB"; + break; default: return NULL; } + return sc_evp_cipher(card->ctx, algo); } static int get_keylen(unsigned int alg_id, size_t *size) @@ -1604,7 +1614,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, EVP_CIPHER_CTX * ctx = NULL; u8 sbuf[255]; - const EVP_CIPHER *cipher; + EVP_CIPHER *cipher = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1614,7 +1624,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, goto err; } - cipher = get_cipher_for_algo(alg_id); + cipher = get_cipher_for_algo(card, alg_id); if(!cipher) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; @@ -1850,6 +1860,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = SC_SUCCESS; err: + sc_evp_cipher_free(cipher); if (ctx) EVP_CIPHER_CTX_free(ctx); if (locked) @@ -1897,7 +1908,7 @@ static int piv_general_external_authenticate(sc_card_t *card, size_t cypher_text_len = 0; u8 sbuf[255]; EVP_CIPHER_CTX * ctx = NULL; - const EVP_CIPHER *cipher; + EVP_CIPHER *cipher = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1909,7 +1920,7 @@ static int piv_general_external_authenticate(sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id); - cipher = get_cipher_for_algo(alg_id); + cipher = get_cipher_for_algo(card, alg_id); if(!cipher) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); r = SC_ERROR_INVALID_ARGUMENTS; @@ -2059,6 +2070,7 @@ static int piv_general_external_authenticate(sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response challenge\n"); err: + sc_evp_cipher_free(cipher); if (ctx) EVP_CIPHER_CTX_free(ctx); From 264b23aff5b01acebe9627dff4468fa42eb5a825 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 16:59:16 -0500 Subject: [PATCH 2774/4321] Convert card westcos to use openssl libctx Signed-off-by: Simo Sorce --- src/libopensc/card-westcos.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 633d471d73..108599336b 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -659,6 +659,7 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, int r; #ifdef ENABLE_OPENSSL EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; int tmplen = 0; if ((cctx = EVP_CIPHER_CTX_new()) == NULL) return SC_ERROR_INTERNAL; @@ -671,19 +672,25 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, if (r) return r; #ifdef ENABLE_OPENSSL - if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + return SC_ERROR_INTERNAL; + alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); + if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || EVP_CIPHER_CTX_set_padding(cctx,0) != 1 || EVP_EncryptUpdate(cctx, result, &tmplen, buf, *len) != 1) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } *len = tmplen; if (EVP_EncryptFinal_ex(cctx, result + tmplen, &tmplen) != 1) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } *len += tmplen; EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_SUCCESS; #else return SC_ERROR_NOT_SUPPORTED; @@ -1185,7 +1192,11 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, idx += r; } while (1); BIO_set_mem_eof_return(mem, -1); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (!(pkey = d2i_PrivateKey_bio(mem, NULL))) { +#else + if (!(pkey = d2i_PrivateKey_ex_bio(mem, NULL, card->ctx->ossl3ctx->libctx, NULL))) { +#endif sc_log(card->ctx, "RSA key invalid, %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; From fceeca13e9fb811896648456d44ef9c5d1c7ffcd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 17:17:03 -0500 Subject: [PATCH 2775/4321] Convert padding.c to use openssllibctx Signed-off-by: Simo Sorce --- src/libopensc/padding.c | 90 ++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 826e726783..17745d61a4 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -231,8 +231,8 @@ static int mgf1(u8 *mask, size_t len, u8 *seed, size_t seedLen, const EVP_MD *dg } /* forward declarations */ -static const EVP_MD *mgf1_flag2md(unsigned int mgf1); -static const EVP_MD *hash_flag2md(unsigned int hash); +static EVP_MD *mgf1_flag2md(sc_context_t *ctx, unsigned int mgf1); +static EVP_MD *hash_flag2md(sc_context_t *ctx, unsigned int hash); /* check/remove OAEP - RFC 8017 padding */ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigned long flags, uint8_t *param, size_t paramlen) @@ -240,7 +240,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne size_t i,j; size_t mdlen, dblen; u8 seed[EVP_MAX_MD_SIZE]; - const EVP_MD *mgf1_md, *hash_md; + EVP_MD *mgf1_md = NULL, *hash_md = NULL; u8 db[512]; /* up to RSA 4096 */ u8 label[EVP_MAX_MD_SIZE]; EVP_MD_CTX *md_ctx; @@ -251,7 +251,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); /* https://www.rfc-editor.org/rfc/pdfrfc/rfc8017.txt.pdf, page 26, 3.a. */ - hash_md = hash_flag2md(flags); + hash_md = hash_flag2md(ctx, flags); if (!hash_md) return SC_ERROR_NOT_SUPPORTED; @@ -263,32 +263,45 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne hash_len = 0; EVP_MD_CTX_free(md_ctx); } + sc_evp_md_free(hash_md); + hash_md = NULL; if (!hash_len) LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); - mgf1_md = mgf1_flag2md(flags); + mgf1_md = mgf1_flag2md(ctx, flags); if (!mgf1_md) return SC_ERROR_NOT_SUPPORTED; mdlen = EVP_MD_size(mgf1_md); - if (len < 2 * mdlen + 2) + if (len < 2 * mdlen + 2) { + sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + } - if (*data != 0) + if (*data != 0) { + sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + } dblen = len - 1 - mdlen; - if (dblen > sizeof(db)) + if (dblen > sizeof(db)) { + sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + } - if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) + if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) { + sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + } for (i = 0; i < mdlen; i++) seed[i] ^= data[i + 1]; - if (mgf1(db, dblen, seed, mdlen, mgf1_md)) + if (mgf1(db, dblen, seed, mdlen, mgf1_md)) { + sc_evp_md_free(mgf1_md); LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + } + sc_evp_md_free(mgf1_md); for (i = 0; i < dblen; i++) { db[i] ^= data[i + mdlen + 1]; /* clear lHash' if same as lHash */ @@ -369,37 +382,37 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, #ifdef ENABLE_OPENSSL -static const EVP_MD* hash_flag2md(unsigned int hash) +static EVP_MD* hash_flag2md(sc_context_t *ctx, unsigned int hash) { switch (hash & SC_ALGORITHM_RSA_HASHES) { case SC_ALGORITHM_RSA_HASH_SHA1: - return EVP_sha1(); + return sc_evp_md(ctx, "SHA1"); case SC_ALGORITHM_RSA_HASH_SHA224: - return EVP_sha224(); + return sc_evp_md(ctx, "SHA224"); case SC_ALGORITHM_RSA_HASH_SHA256: - return EVP_sha256(); + return sc_evp_md(ctx, "SHA256"); case SC_ALGORITHM_RSA_HASH_SHA384: - return EVP_sha384(); + return sc_evp_md(ctx, "SHA384"); case SC_ALGORITHM_RSA_HASH_SHA512: - return EVP_sha512(); + return sc_evp_md(ctx, "SHA512"); default: return NULL; } } -static const EVP_MD* mgf1_flag2md(unsigned int mgf1) +static EVP_MD* mgf1_flag2md(sc_context_t *ctx, unsigned int mgf1) { switch (mgf1 & SC_ALGORITHM_MGF1_HASHES) { case SC_ALGORITHM_MGF1_SHA1: - return EVP_sha1(); + return sc_evp_md(ctx, "SHA1"); case SC_ALGORITHM_MGF1_SHA224: - return EVP_sha224(); + return sc_evp_md(ctx, "SHA224"); case SC_ALGORITHM_MGF1_SHA256: - return EVP_sha256(); + return sc_evp_md(ctx, "SHA256"); case SC_ALGORITHM_MGF1_SHA384: - return EVP_sha384(); + return sc_evp_md(ctx, "SHA384"); case SC_ALGORITHM_MGF1_SHA512: - return EVP_sha512(); + return sc_evp_md(ctx, "SHA512"); default: return NULL; } @@ -408,13 +421,13 @@ static const EVP_MD* mgf1_flag2md(unsigned int mgf1) /* large enough up to RSA 4096 */ #define PSS_MAX_SALT_SIZE 512 /* add PKCS#1 v2.0 PSS padding */ -static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, +static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsigned int mgf1_hash, const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits, size_t sLen) { /* hLen = sLen in our case */ int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds; int mgf1_hlen; - const EVP_MD* md, *mgf1_md; + EVP_MD* md = NULL, *mgf1_md = NULL; EVP_MD_CTX* ctx = NULL; u8 buf[8]; u8 salt[PSS_MAX_SALT_SIZE], mask[EVP_MAX_MD_SIZE]; @@ -423,22 +436,30 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, if (*out_len < mod_length) return SC_ERROR_BUFFER_TOO_SMALL; - md = hash_flag2md(hash); + md = hash_flag2md(scctx, hash); if (md == NULL) return SC_ERROR_NOT_SUPPORTED; hlen = EVP_MD_size(md); dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ plen = mod_length - sLen - hlen - 1; - if (in_len != (unsigned)hlen) + if (in_len != (unsigned)hlen) { + sc_evp_md_free(md); return SC_ERROR_INVALID_ARGUMENTS; - if (sLen + (unsigned)hlen + 2 > mod_length) + } + if (sLen + (unsigned)hlen + 2 > mod_length) { /* RSA key too small for chosen hash (1296 bits or higher needed for * signing SHA-512 hashes) */ + sc_evp_md_free(md); return SC_ERROR_NOT_SUPPORTED; - if (sLen > PSS_MAX_SALT_SIZE) + } + if (sLen > PSS_MAX_SALT_SIZE) { + sc_evp_md_free(md); return SC_ERROR_INVALID_ARGUMENTS; - if (RAND_bytes(salt, sLen) != 1) + } + if (RAND_bytes(salt, sLen) != 1) { + sc_evp_md_free(md); return SC_ERROR_INTERNAL; + } /* Hash M' to create H */ if (!(ctx = EVP_MD_CTX_create())) @@ -464,7 +485,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, * *the first part is masked later */ /* Construct the DB mask block by block and XOR it in. */ - mgf1_md = mgf1_flag2md(mgf1_hash); + mgf1_md = mgf1_flag2md(scctx, mgf1_hash); if (mgf1_md == NULL) return SC_ERROR_NOT_SUPPORTED; mgf1_hlen = EVP_MD_size(mgf1_md); @@ -499,6 +520,8 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, done: OPENSSL_cleanse(salt, sizeof(salt)); OPENSSL_cleanse(mask, sizeof(mask)); + sc_evp_md_free(md); + sc_evp_md_free(mgf1_md); if (ctx) { EVP_MD_CTX_destroy(ctx); } @@ -537,7 +560,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, size_t mod_len = (mod_bits + 7) / 8; #ifdef ENABLE_OPENSSL size_t sLen; - const EVP_MD* md; + EVP_MD* md = NULL; unsigned int mgf1_hash; #endif @@ -586,9 +609,10 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, hash_algo = hash_len2algo(tmp_len); } /* sLen is by default same as hash length */ - if (!(md = hash_flag2md(hash_algo))) + if (!(md = hash_flag2md(ctx, hash_algo))) return SC_ERROR_NOT_SUPPORTED; sLen = EVP_MD_size(md); + sc_evp_md_free(md); /* if application provide sLen, use it */ if (pMechanism != NULL) { CK_MECHANISM *mech = (CK_MECHANISM *)pMechanism; @@ -598,7 +622,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, sLen = pss_params->sLen; } } - rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash, + rv = sc_pkcs1_add_pss_padding(ctx, hash_algo, mgf1_hash, tmp, tmp_len, out, out_len, mod_bits, sLen); #else rv = SC_ERROR_NOT_SUPPORTED; From 75dc92a57d53268fe6b549e840a3e278ad7bf03e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 17:51:52 -0500 Subject: [PATCH 2776/4321] Convert pkcs15-westcos.c to use OpenSSL libctx Signed-off-by: Simo Sorce --- src/pkcs15init/pkcs15-westcos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index fb8f8bda83..6f55c90744 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -235,7 +235,11 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, return SC_ERROR_NOT_SUPPORTED; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); +#else + pctx = EVP_PKEY_CTX_new_from_name(profile->card->ctx->ossl3ctx->libctx, "RSA", NULL); +#endif mem = BIO_new(BIO_s_mem()); bn = BN_new(); if (pctx == NULL || mem == NULL || bn == NULL) { From a931d8835f0ddc1f2aba31421e9274f4c347d525 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 18:05:10 -0500 Subject: [PATCH 2777/4321] Remove call to load legacy provider from libsm Library code should *never* arbitrarily load the legacy provider in the default application context. It may literally break or make an application vulnerable by sneaking in unexpected algorithms. This is not needed anymore given we will use an opensc specific context that will not affect the rest of the application (or other libraries). Signed-off-by: Simo Sorce --- src/sm/sm-common.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index caada2b7ee..af16d44cab 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -122,13 +122,6 @@ DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, } memcpy(*iv,icv_out,sizeof(sm_des_cblock)); } -#else -#include - -/* The single-DES algorithm is not available in the default provider anymore - * so we need to load the legacy provider. This is not done on the application - * start, but only as needed */ -static OSSL_PROVIDER *legacy_provider = NULL; #endif @@ -206,12 +199,6 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, cctx = EVP_CIPHER_CTX_new(); if (l > 8) { - if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { - EVP_CIPHER_CTX_free(cctx); - return SC_ERROR_INTERNAL; - } - } if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { EVP_CIPHER_CTX_free(cctx); return SC_ERROR_INTERNAL; From 3934f6febc5b951b0b4d1f804c9ba22ec4f84ef7 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 15 Feb 2023 18:27:08 -0500 Subject: [PATCH 2778/4321] Convert libsm to use openssl libctx Signed-off-by: Simo Sorce --- src/sm/sm-common.c | 56 +++++++++++++++++++++++++++------ src/sm/sm-common.h | 9 ++++-- src/smm/sm-card-authentic.c | 2 +- src/smm/sm-cwa14890.c | 2 +- src/smm/sm-global-platform.c | 18 +++++------ src/smm/sm-module.h | 7 +++-- src/tests/unittests/sm.c | 60 ++++++++++++++++++------------------ 7 files changed, 99 insertions(+), 55 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index af16d44cab..c488c50e33 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -47,6 +47,7 @@ #include "libopensc/opensc.h" #include "libopensc/asn1.h" #include "libopensc/log.h" +#include "libopensc/sc-ossl-compat.h" #include "sm-common.h" @@ -126,7 +127,8 @@ DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, unsigned int -DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, +DES_cbc_cksum_3des_emv96(struct sc_context *ctx, + const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, sm_const_des_cblock *ivec) { @@ -191,6 +193,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, return(tout1); #else EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; unsigned char outv[8], tmpout[4]; int tmplen; @@ -199,8 +202,10 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, cctx = EVP_CIPHER_CTX_new(); if (l > 8) { - if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { + alg = sc_evp_cipher(ctx, "DES-CBC"); + if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ @@ -208,29 +213,37 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, for (; l > 8; l -= 8, in += 8) { if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } + sc_evp_cipher_free(alg); + alg = NULL; } /* We need to return first 4 bytes from here */ memcpy(tmpout, outv, 4); - if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, outv, NULL)) { + alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); + if (!EVP_EncryptInit_ex2(cctx, alg, key, outv, NULL)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, l)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } if (out != NULL) { @@ -238,6 +251,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, memcpy(out+4, outv+4, 4); } EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return ((outv[7] << 0L) & 0x000000FF) | ((outv[6] << 8L) & 0x0000FF00) | ((outv[5] << 16L) & 0x00FF0000) | @@ -247,7 +261,8 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, unsigned int -DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, +DES_cbc_cksum_3des(struct sc_context *ctx, + const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, sm_const_des_cblock *ivec) { @@ -302,6 +317,7 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, return(tout1); #else EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; unsigned char outv[8]; int tmplen = 0; @@ -309,8 +325,10 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, memcpy(outv, iv, sizeof outv); cctx = EVP_CIPHER_CTX_new(); - if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, iv, NULL)) { + alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); + if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ @@ -318,17 +336,20 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, for (; l > 0; l -= 8, in += 8) { if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } } if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_ERROR_INTERNAL; } if (out != NULL) { memcpy(out, outv, sizeof outv); } EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return ((outv[7] << 0L) & 0x000000FF) | ((outv[6] << 8L) & 0x0000FF00) | ((outv[5] << 16L) & 0x00FF0000) | @@ -338,7 +359,8 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, int -sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, +sm_encrypt_des_ecb3(struct sc_context *ctx, + unsigned char *key, unsigned char *data, int data_len, unsigned char **out, int *out_len) { #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -347,6 +369,7 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, DES_key_schedule ks,ks2; #else EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; int tmplen; #endif @@ -377,7 +400,8 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, if (cctx == NULL) { goto err; } - if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_ecb(), key, NULL, NULL)) { + alg = sc_evp_cipher(ctx, "DES-EDE-ECB"); + if (!EVP_EncryptInit_ex2(cctx, alg, key, NULL, NULL)) { goto err; } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ @@ -392,10 +416,12 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, } *out_len += tmplen; EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); return SC_SUCCESS; err: EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); free(*out); return SC_ERROR_INTERNAL; #endif @@ -415,6 +441,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, #else unsigned char icv[] = {0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; int tmplen; #endif @@ -441,24 +468,29 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, (sm_des_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_DECRYPT); #else cctx = EVP_CIPHER_CTX_new(); - if (!EVP_DecryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { + alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); + if (!EVP_DecryptInit_ex2(cctx, alg, key, icv, NULL)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_DecryptUpdate(cctx, *out, &tmplen, data, data_len)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len = tmplen; if (!EVP_DecryptFinal_ex(cctx, *out + *out_len, &tmplen)) { EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len += tmplen; EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); #endif SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); } @@ -477,6 +509,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, #else unsigned char icv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; EVP_CIPHER_CTX *cctx = NULL; + EVP_CIPHER *alg = NULL; int tmplen; #endif unsigned char *data; @@ -527,9 +560,11 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, DES_3cbc_encrypt((sm_des_cblock *)(data + st), (sm_des_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_ENCRYPT); #else cctx = EVP_CIPHER_CTX_new(); - if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { + alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); + if (!EVP_EncryptInit_ex2(cctx, alg, key, icv, NULL)) { free(*out); EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ @@ -537,6 +572,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) { free(*out); EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len = tmplen; @@ -544,10 +580,12 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { free(*out); EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); } *out_len += tmplen; EVP_CIPHER_CTX_free(cctx); + sc_evp_cipher_free(alg); #endif free(data); diff --git a/src/sm/sm-common.h b/src/sm/sm-common.h index af096865cb..750c38b9a0 100644 --- a/src/sm/sm-common.h +++ b/src/sm/sm-common.h @@ -30,12 +30,15 @@ extern "C" { #include "libopensc/sm.h" -unsigned int DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, long length, +unsigned int DES_cbc_cksum_3des(struct sc_context *ctx, + const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, sm_const_des_cblock *ivec); -unsigned int DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, +unsigned int DES_cbc_cksum_3des_emv96(struct sc_context *ctx, + const unsigned char *in, sm_des_cblock *output, long length, unsigned char *key, sm_const_des_cblock *ivec); -int sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, +int sm_encrypt_des_ecb3(struct sc_context *ctx, + unsigned char *key, unsigned char *data, int data_len, unsigned char **out, int *out_len); int sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, const unsigned char *in, size_t in_len, diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index b5fc420b15..a58ff5d4c5 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -78,7 +78,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, sc_debug(ctx, SC_LOG_DEBUG_SM, "key_buf:%s", sc_dump_hex(key_buff, 16)); - rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); + rv = sm_encrypt_des_ecb3(ctx, master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); LOG_TEST_RET(ctx, rv, "GP init session: cannot derive key"); memcpy(keys[ii], tmp, sizeof(gp_keyset->enc)); diff --git a/src/smm/sm-cwa14890.c b/src/smm/sm-cwa14890.c index c245ae3989..3d58ddad1b 100644 --- a/src/smm/sm-cwa14890.c +++ b/src/smm/sm-cwa14890.c @@ -71,7 +71,7 @@ sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, sm_des_cblock *icv, sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() data to MAC(%i) %s", in_len, sc_dump_hex(buf, in_len)); sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() ICV %s", sc_dump_hex((unsigned char *)icv, 8)); - DES_cbc_cksum_3des_emv96(buf, out, in_len, key, icv); + DES_cbc_cksum_3des_emv96(ctx, buf, out, in_len, key, icv); free(buf); LOG_FUNC_RETURN(ctx, SC_SUCCESS); diff --git a/src/smm/sm-global-platform.c b/src/smm/sm-global-platform.c index d91c9a7e4a..a8f8a8bc94 100644 --- a/src/smm/sm-global-platform.c +++ b/src/smm/sm-global-platform.c @@ -105,7 +105,7 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, memcpy(deriv + 8, gp_session->card_challenge, 4); memcpy(deriv + 12, gp_session->host_challenge + 4, 4); - if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) { + if (sm_encrypt_des_ecb3(ctx, key, deriv, 16, &out, &out_len)) { if (ctx) sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error"); return NULL; @@ -123,7 +123,7 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, int -sm_gp_get_cryptogram(unsigned char *session_key, +sm_gp_get_cryptogram(struct sc_context *ctx, unsigned char *session_key, unsigned char *left, unsigned char *right, unsigned char *out, int out_len) { @@ -137,7 +137,7 @@ sm_gp_get_cryptogram(unsigned char *session_key, memcpy(block + 8, right, 8); memcpy(block + 16, "\x80\0\0\0\0\0\0\0",8); - DES_cbc_cksum_3des(block,&cksum, sizeof(block), session_key, &cksum); + DES_cbc_cksum_3des(ctx, block, &cksum, sizeof(block), session_key, &cksum); memcpy(out, cksum, 8); @@ -146,7 +146,7 @@ sm_gp_get_cryptogram(unsigned char *session_key, int -sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, +sm_gp_get_mac(struct sc_context *ctx, unsigned char *key, sm_des_cblock *icv, unsigned char *in, int in_len, sm_des_cblock *out) { int len; @@ -161,7 +161,7 @@ sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, len = in_len + 8; len -= (len%8); - DES_cbc_cksum_3des(block, out, len, key, icv); + DES_cbc_cksum_3des(ctx, block, out, len, key, icv); free(block); return 0; @@ -211,7 +211,7 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_gp_session *gp_session, sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: session KEK: %s", sc_dump_hex(gp_session->session_kek, 16)); memset(cksum, 0, sizeof(cksum)); - rv = sm_gp_get_cryptogram(gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum)); + rv = sm_gp_get_cryptogram(ctx, gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum)); LOG_TEST_RET(ctx, rv, "SM GP init session: cannot get cryptogram"); sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: cryptogram: %s", sc_dump_hex(cksum, 8)); @@ -264,7 +264,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, rv = sm_gp_init_session(ctx, gp_session, init_data + 20, 8); LOG_TEST_RET(ctx, rv, "SM GP authentication: init session error"); - rv = sm_gp_get_cryptogram(gp_session->session_enc, + rv = sm_gp_get_cryptogram(ctx, gp_session->session_enc, gp_session->card_challenge, gp_session->host_challenge, host_cryptogram, sizeof(host_cryptogram)); LOG_TEST_RET(ctx, rv, "SM GP authentication: get host cryptogram error"); @@ -286,7 +286,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, memcpy(raw_apdu + offs, host_cryptogram, 8); offs += 8; - rv = sm_gp_get_mac(gp_session->session_mac, &gp_session->mac_icv, raw_apdu, offs, &mac); + rv = sm_gp_get_mac(ctx, gp_session->session_mac, &gp_session->mac_icv, raw_apdu, offs, &mac); LOG_TEST_RET(ctx, rv, "SM GP authentication: get MAC error"); memcpy(new_rapdu->sbuf, host_cryptogram, 8); @@ -391,7 +391,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, memcpy(buff + 5, apdu_data, apdu->datalen); - rv = sm_gp_get_mac(gp_session->session_mac, &gp_session->mac_icv, buff, 5 + apdu->datalen, &mac); + rv = sm_gp_get_mac(ctx, gp_session->session_mac, &gp_session->mac_icv, buff, 5 + apdu->datalen, &mac); LOG_TEST_GOTO_ERR(ctx, rv, "SM GP securize APDU: get MAC error"); if (gp_level == SM_GP_SECURITY_MAC) { diff --git a/src/smm/sm-module.h b/src/smm/sm-module.h index c12734a36d..4d11ee994d 100644 --- a/src/smm/sm-module.h +++ b/src/smm/sm-module.h @@ -34,9 +34,12 @@ extern "C" { #include "sm/sm-common.h" /* Global Platform definitions */ -int sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, unsigned char *in, int in_len, +int sm_gp_get_mac(struct sc_context *ctx, + unsigned char *key, sm_des_cblock *icv, + unsigned char *in, int in_len, sm_des_cblock *out); -int sm_gp_get_cryptogram(unsigned char *session_key, unsigned char *left, unsigned char *right, +int sm_gp_get_cryptogram(struct sc_context *ctx, unsigned char *session_key, + unsigned char *left, unsigned char *right, unsigned char *out, int out_len); int sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, unsigned char *init_data, size_t init_len, diff --git a/src/tests/unittests/sm.c b/src/tests/unittests/sm.c index ab6e819e40..a21661e6b5 100644 --- a/src/tests/unittests/sm.c +++ b/src/tests/unittests/sm.c @@ -174,6 +174,7 @@ static void torture_sm_crypt_des_cbc3_force_pad(void **state) static void torture_sm_encrypt_des_ecb3(void **state) { + sc_context_t *ctx = *state; /* Test vector from * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode @@ -187,9 +188,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) int out_len = 0; int rv; - (void)state; - - rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + rv = sm_encrypt_des_ecb3(ctx, key, plain, sizeof(plain), &out, &out_len); assert_int_equal(rv, SC_SUCCESS); assert_int_equal(out_len, sizeof(ciphertext)); assert_memory_equal(out, ciphertext, sizeof(ciphertext)); @@ -197,7 +196,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) out = NULL; out_len = 0; - rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + rv = sm_encrypt_des_ecb3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); assert_int_equal(rv, SC_SUCCESS); assert_memory_equal(out, plain, sizeof(plain)); free(out); @@ -205,6 +204,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) static void torture_sm_encrypt_des_ecb3_multiblock(void **state) { + sc_context_t *ctx = *state; /* not a test vector -- generated by openssl 1.1.1 */ unsigned char key[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ @@ -219,9 +219,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) int out_len = 0; int rv; - (void)state; - - rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + rv = sm_encrypt_des_ecb3(ctx, key, plain, sizeof(plain), &out, &out_len); assert_int_equal(rv, SC_SUCCESS); assert_int_equal(out_len, sizeof(ciphertext)); assert_memory_equal(out, ciphertext, sizeof(ciphertext)); @@ -229,7 +227,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) out = NULL; out_len = 0; - rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + rv = sm_encrypt_des_ecb3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); assert_int_equal(rv, SC_SUCCESS); assert_memory_equal(out, plain, sizeof(plain)); free(out); @@ -237,6 +235,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) static void torture_DES_cbc_cksum_3des(void **state) { + sc_context_t *ctx = *state; /* not a test vector -- generated by openssl 1.1.1 */ unsigned char key[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ @@ -251,19 +250,18 @@ static void torture_DES_cbc_cksum_3des(void **state) unsigned char checksum[8]; unsigned long sum; - (void)state; - - sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des(ctx, plain, &checksum, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); /* The checksum argument is not required */ - sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des(ctx, plain, NULL, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); } static void torture_DES_cbc_cksum_3des_multiblock(void **state) { + sc_context_t *ctx = *state; /* not a test vector -- generated by openssl 1.1.1 */ unsigned char key[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ @@ -280,19 +278,18 @@ static void torture_DES_cbc_cksum_3des_multiblock(void **state) unsigned char checksum[8]; unsigned long sum; - (void)state; - - sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des(ctx, plain, &checksum, sizeof(plain), key, &iv); assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); assert_int_equal(sum, sum_ref); /* The checksum argument is not required */ - sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des(ctx, plain, NULL, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); } static void torture_DES_cbc_cksum_3des_emv96(void **state) { + sc_context_t *ctx = *state; /* not a test vector -- generated by openssl 1.1.1 */ unsigned char key[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ @@ -307,19 +304,18 @@ static void torture_DES_cbc_cksum_3des_emv96(void **state) unsigned char checksum[8]; unsigned long sum; - (void)state; - - sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des_emv96(ctx, plain, &checksum, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); /* The checksum argument is not required */ - sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des_emv96(ctx, plain, NULL, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); } static void torture_DES_cbc_cksum_3des_emv96_multiblock(void **state) { + sc_context_t *ctx = *state; /* not a test vector -- generated by openssl 1.1.1 */ unsigned char key[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ @@ -336,14 +332,12 @@ static void torture_DES_cbc_cksum_3des_emv96_multiblock(void **state) unsigned char checksum[8] = {0}; unsigned long sum; - (void)state; - - sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des_emv96(ctx, plain, &checksum, sizeof(plain), key, &iv); assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); assert_int_equal(sum, sum_ref); /* The checksum argument is not required */ - sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv); + sum = DES_cbc_cksum_3des_emv96(ctx, plain, NULL, sizeof(plain), key, &iv); assert_int_equal(sum, sum_ref); } @@ -361,14 +355,20 @@ int main(void) cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_force_pad, setup_sc_context, teardown_sc_context), /* sm_encrypt_des_ecb3 */ - cmocka_unit_test(torture_sm_encrypt_des_ecb3), - cmocka_unit_test(torture_sm_encrypt_des_ecb3_multiblock), + cmocka_unit_test_setup_teardown(torture_sm_encrypt_des_ecb3, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_sm_encrypt_des_ecb3_multiblock, + setup_sc_context, teardown_sc_context), /* DES_cbc_cksum_3des */ - cmocka_unit_test(torture_DES_cbc_cksum_3des), - cmocka_unit_test(torture_DES_cbc_cksum_3des_multiblock), + cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_multiblock, + setup_sc_context, teardown_sc_context), /* DES_cbc_cksum_3des_emv96 */ - cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96), - cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96_multiblock), + cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_emv96, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_emv96_multiblock, + setup_sc_context, teardown_sc_context), }; rc = cmocka_run_group_tests(tests, NULL, NULL); From fe58e93d6d55537649e687ccc4cbf5f13e2af92d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 16 Feb 2023 09:05:56 -0500 Subject: [PATCH 2779/4321] Protect from nested initializations If a library used by the module itself tries, somehow to also initializae the module, return a hard error. Nested Initializations are not permitted. Signed-off-by: Simo Sorce --- src/pkcs11/pkcs11-global.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 48ef7823f0..e47f644b0a 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -59,6 +59,7 @@ pid_t initialized_pid = (pid_t)-1; static int in_finalize = 0; extern CK_FUNCTION_LIST pkcs11_function_list; extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; +int nesting = 0; #ifdef PKCS11_THREAD_LOCKING @@ -306,12 +307,21 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) in_finalize = 0; #endif + /* protect from nesting */ + nesting++; + if (nesting > 1) { + sc_log(context, "C_Initialize(): Nested init detected"); + nesting--; + return CKR_GENERAL_ERROR; + } + /* protect from multiple threads tryng to setup locking */ C_INITIALIZE_M_LOCK if (context != NULL) { sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); C_INITIALIZE_M_UNLOCK + nesting--; return CKR_CRYPTOKI_ALREADY_INITIALIZED; } @@ -366,6 +376,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) /* protect from multiple threads tryng to setup locking */ C_INITIALIZE_M_UNLOCK + nesting--; return rv; } From b09e371906f49a40b7886b440cb3b937094fd8b4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 16 Feb 2023 17:13:19 -0500 Subject: [PATCH 2780/4321] Add thread locking protection for nesting check Signed-off-by: Simo Sorce --- src/pkcs11/pkcs11-global.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index e47f644b0a..cbc7445bb9 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -308,20 +308,24 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) #endif /* protect from nesting */ + C_INITIALIZE_M_LOCK nesting++; if (nesting > 1) { sc_log(context, "C_Initialize(): Nested init detected"); nesting--; + C_INITIALIZE_M_UNLOCK return CKR_GENERAL_ERROR; } + C_INITIALIZE_M_UNLOCK + /* protect from nesting */ /* protect from multiple threads tryng to setup locking */ C_INITIALIZE_M_LOCK if (context != NULL) { sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); - C_INITIALIZE_M_UNLOCK nesting--; + C_INITIALIZE_M_UNLOCK return CKR_CRYPTOKI_ALREADY_INITIALIZED; } @@ -374,9 +378,9 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) } /* protect from multiple threads tryng to setup locking */ + nesting--; C_INITIALIZE_M_UNLOCK - nesting--; return rv; } From 37045afc6dd7cf9f98ca056acfca972e2be5c2e7 Mon Sep 17 00:00:00 2001 From: Claus Steuer Date: Wed, 1 Mar 2023 16:08:15 +0100 Subject: [PATCH 2781/4321] fix OpenSSL library detection if pkgconfig not found If pkg-config fails to find OpenSSL, autoconf tries to check for the presence of the RSA_version symbol in the libcrypto library. However, it turns out that RSA_version was never actually part of OpenSSL, so this check will always fail. To fix this issue, autoconf can search for the RSA_get_version symbol instead, which should be present in OpenSSL since version 1.1.1 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ab6cc587ef..9c29530b04 100644 --- a/configure.ac +++ b/configure.ac @@ -678,7 +678,7 @@ PKG_CHECK_MODULES( [have_openssl="yes"], [AC_CHECK_LIB( [crypto], - [RSA_version], + [RSA_get_version], [ have_openssl="yes" OPENSSL_LIBS="-lcrypto" From 7aa06c15c2e977ad0df834245b14ca2c4c90c9bc Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 14 Feb 2023 12:22:01 +0100 Subject: [PATCH 2782/4321] epass2003: Invalid APDU fix If sc_transmit_apdu_t() needs to retransmit the APDU, the response buffer size must be refreshed. Fixes #2705 --- src/libopensc/card-epass2003.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 335dba7dfb..03f08402e0 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -267,10 +267,13 @@ epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) static int sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu) { + size_t resplen = apdu->resplen; int r = sc_transmit_apdu(card, apdu); if ( ((0x69 == apdu->sw1) && (0x85 == apdu->sw2)) || ((0x69 == apdu->sw1) && (0x88 == apdu->sw2))) { epass2003_refresh(card); + /* renew old resplen */ + apdu->resplen = resplen; r = sc_transmit_apdu(card, apdu); } return r; From 7937f694b9ee6cbd426b76ec35c193bf2d22c35a Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Fri, 23 Dec 2022 12:08:32 +0100 Subject: [PATCH 2783/4321] added Swissbit iShield FIDO2 Authenticator --- src/libopensc/card-piv.c | 43 +++++++++++++++++++++++++++++++------- src/libopensc/cardctl.h | 3 ++- src/libopensc/cards.h | 2 ++ src/libopensc/pkcs15-syn.c | 1 + src/tools/piv-tool.c | 13 ++++-------- win32/customactions.cpp | 3 +++ 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index aadd4ec242..7a9ab052c1 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -115,6 +115,7 @@ enum { PIV_OBJ_9306, PIV_OBJ_9406, PIV_OBJ_9506, + PIV_OBJ_PRIV, PIV_OBJ_LAST_ENUM }; @@ -287,6 +288,9 @@ static const struct sc_atr_table piv_atrs[] = { { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, { "3b:86:80:01:80:31:c1:52:41:12:76", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */ + /* Swissbit iShield FIDO2 with PIV endpoint applet */ + { "3b:97:11:81:21:75:69:53:68:69:65:6c:64:05", NULL, NULL, SC_CARD_TYPE_PIV_II_SWISSBIT, 0, NULL }, + { NULL, NULL, NULL, 0, 0, NULL } }; @@ -493,6 +497,7 @@ static const struct piv_object piv_objects[] = { "2.16.840.1.101.3.7.2.9999.119", 2, "\x94\x06", "\x94\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9506, "Pub 95 key ", "2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_PRIV, "Priv key ", "", 0, "", "\x50\x15", 0}, { PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0} }; // clang-format on @@ -596,14 +601,15 @@ static int piv_generate_key(sc_card_t *card, const u8 *tag; u8 tagbuf[16]; u8 outdata[3]; /* we could also add tag 81 for exponent */ - size_t taglen, i; + size_t taglen; size_t out_len; size_t in_len; unsigned int cla_out, tag_out; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - keydata->exponent = 0; + keydata->exponent = NULL; + keydata->exponent_len = 0; keydata->pubkey = NULL; keydata->pubkey_len = 0; keydata->ecparam = NULL; /* will show size as we only support 2 curves */ @@ -645,7 +651,6 @@ static int piv_generate_key(sc_card_t *card, if (r >= 0) { const u8 *cp; - keydata->exponent = 0; cp = rbuf; in_len = r; @@ -664,16 +669,20 @@ static int piv_generate_key(sc_card_t *card, if (keydata->key_bits > 0 ) { tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen); if (tag != NULL && taglen <= 4) { - keydata->exponent = 0; - for (i = 0; i < taglen;i++) - keydata->exponent = (keydata->exponent<<8) + tag[i]; + keydata->exponent = malloc(taglen); + if (keydata->exponent == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + keydata->exponent_len = taglen; + memcpy (keydata->exponent, tag, taglen); } tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x81, &taglen); if (tag != NULL && taglen > 0) { keydata->pubkey = malloc(taglen); - if (keydata->pubkey == NULL) + if (keydata->pubkey == NULL) { + free(keydata->exponent); LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } keydata->pubkey_len = taglen; memcpy (keydata->pubkey, tag, taglen); } @@ -3063,6 +3072,8 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: + case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_SWISSBIT: break; default: return 0; /* can not handle the card */ @@ -3112,6 +3123,8 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: + case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_SWISSBIT: type = card->type; break; default: @@ -3251,6 +3264,7 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE: case SC_CARD_TYPE_PIV_II_GEMALTO: case SC_CARD_TYPE_PIV_II_OBERTHUR: + case SC_CARD_TYPE_PIV_II_SWISSBIT: iccc = piv_process_ccc(card); sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d iccc:%d ccc_flags:%08x CI:%08x r:%d\n", card->type, iccc, priv->ccc_flags, priv->card_issues, r); @@ -3277,6 +3291,12 @@ static int piv_match_card_continued(sc_card_t *card) priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; + case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_SWISSBIT: + card->type = SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; } } break; @@ -3285,6 +3305,7 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; @@ -3415,6 +3436,7 @@ static int piv_init(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE: case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_SWISSBIT: priv->card_issues |= 0; /* could add others here */ break; @@ -3425,6 +3447,7 @@ static int piv_init(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_PIV_AID_LOSE_STATE | CI_NO_RANDOM @@ -3466,7 +3489,11 @@ static int piv_init(sc_card_t *card) * piv-tool can still do this, just don't tell PKCS#11 */ - flags = SC_ALGORITHM_RSA_RAW; + flags = SC_ALGORITHM_RSA_RAW; + + if (card->type == SC_CARD_TYPE_PIV_II_SWISSBIT || card->type == SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC) { + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + } _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */ _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */ diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index c3acbbcb67..a1ce7c0d1b 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -916,7 +916,8 @@ typedef struct sc_cardctl_piv_genkey_info_st { unsigned int key_num; unsigned int key_algid; /* RSA 5, 6, 7; EC 11, 14 */ unsigned int key_bits; /* RSA */ - unsigned long exponent; /* RSA */ + unsigned char * exponent; /* RSA */ + unsigned long exponent_len; /* RSA */ unsigned char * pubkey; /* RSA */ unsigned int pubkey_len; /* RSA */ unsigned char * ecparam; /* EC */ diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 3e3f8dd268..99e03def34 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -137,6 +137,8 @@ enum { SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC, SC_CARD_TYPE_PIV_II_OBERTHUR, SC_CARD_TYPE_PIV_II_PIVKEY, + SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC, + SC_CARD_TYPE_PIV_II_SWISSBIT, /* MuscleApplet */ SC_CARD_TYPE_MUSCLE_BASE = 15000, diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index c4e99b97e4..b71fcfa064 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -103,6 +103,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_PIV_II_SWISSBIT: case SC_CARD_TYPE_ESTEID_2018: case SC_CARD_TYPE_CARDOS_V5_0: case SC_CARD_TYPE_CARDOS_V5_3: diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index f8a39b5a49..159b826a4f 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -288,9 +288,7 @@ static int gen_key(const char * key_info) u8 buf[2]; size_t buflen = 2; sc_cardctl_piv_genkey_info_t - keydata = {0, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0}; - unsigned long expl; - u8 expc[4]; + keydata = {0, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; #if !defined(OPENSSL_NO_EC) int nid = -1; #endif @@ -369,14 +367,11 @@ static int gen_key(const char * key_info) } newkey_n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, NULL); - expl = keydata.exponent; - expc[3] = (u8) expl & 0xff; - expc[2] = (u8) (expl >>8) & 0xff; - expc[1] = (u8) (expl >>16) & 0xff; - expc[0] = (u8) (expl >>24) & 0xff; - newkey_e = BN_bin2bn(expc, 4, NULL); + newkey_e = BN_bin2bn(keydata.exponent, keydata.exponent_len, NULL); free(keydata.pubkey); keydata.pubkey_len = 0; + free(keydata.exponent); + keydata.exponent_len = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { diff --git a/win32/customactions.cpp b/win32/customactions.cpp index c332949bef..cca4356229 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -201,6 +201,9 @@ MD_REGISTRATION minidriver_registration[] = { 17, {0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF}}, {TEXT("IAS/ECC CPxCL"), {0x3B,0X8F,0x80,0x01,0x00,0x31,0xB8,0x64,0x00,0x00,0xEC,0xC0,0x73,0x94,0x01,0x80,0x82,0x90,0x00,0x0E}, 20, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, + /* from card-piv.c */ + {TEXT("Swissbit iShield FIDO2"), {0x3b,0x97,0x11,0x81,0x21,0x75,0x69,0x53,0x68,0x69,0x65,0x6c,0x64,0x05}, + 14, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, }; From a100df00298153e3317a3c1d69176be403f125f7 Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Fri, 23 Dec 2022 16:27:45 +0100 Subject: [PATCH 2784/4321] fixup --- src/tools/piv-tool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 159b826a4f..1793a2a327 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -347,6 +347,7 @@ static int gen_key(const char * key_info) if (newkey == NULL) { EVP_PKEY_free(evpkey); free(keydata.pubkey); + free(keydata.exponent); fprintf(stderr, "gen_key RSA_new failed %d\n",r); return -1; } @@ -356,9 +357,10 @@ static int gen_key(const char * key_info) OSSL_PARAM *params = NULL; #endif - if (!keydata.pubkey) { + if (!keydata.pubkey || !keydata.exponent) { fprintf(stderr, "gen_key failed %d\n", r); free(keydata.pubkey); + free(keydata.exponent); EVP_PKEY_free(evpkey); #if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_free(newkey); From 0b333575c9796bf5ce32c6c820d78b08b69c0d4c Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Thu, 12 Jan 2023 17:06:46 +0100 Subject: [PATCH 2785/4321] changes from review --- src/libopensc/card-piv.c | 23 ++++++++++------------- src/libopensc/cardctl.h | 2 +- src/libopensc/cards.h | 1 - 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 7a9ab052c1..cdbe203cd5 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -115,7 +115,7 @@ enum { PIV_OBJ_9306, PIV_OBJ_9406, PIV_OBJ_9506, - PIV_OBJ_PRIV, + PIV_OBJ_PRIV_SWISSBIT_2900, PIV_OBJ_LAST_ENUM }; @@ -497,7 +497,7 @@ static const struct piv_object piv_objects[] = { "2.16.840.1.101.3.7.2.9999.119", 2, "\x94\x06", "\x94\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9506, "Pub 95 key ", "2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY}, - { PIV_OBJ_PRIV, "Priv key ", "", 0, "", "\x50\x15", 0}, + { PIV_OBJ_PRIV_SWISSBIT_2900, "Priv key ", "", 0, "", "\x29\x00", 0}, { PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0} }; // clang-format on @@ -2543,6 +2543,13 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, } } + if (memcmp(path, "\x50\x15", 2) == 0) { + if (pathlen > 2) { + path += 2; + pathlen -= 2; + } + } + i = piv_find_obj_by_containerid(card, path); if (i < 0) @@ -3072,7 +3079,6 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: - case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: case SC_CARD_TYPE_PIV_II_SWISSBIT: break; default: @@ -3123,7 +3129,6 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: - case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: case SC_CARD_TYPE_PIV_II_SWISSBIT: type = card->type; break; @@ -3291,12 +3296,6 @@ static int piv_match_card_continued(sc_card_t *card) priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; - case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_SWISSBIT: - card->type = SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; } } break; @@ -3305,7 +3304,6 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: priv->card_issues |= CI_DISCOVERY_USELESS; priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; @@ -3447,7 +3445,6 @@ static int piv_init(sc_card_t *card) case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_PIV_AID_LOSE_STATE | CI_NO_RANDOM @@ -3491,7 +3488,7 @@ static int piv_init(sc_card_t *card) flags = SC_ALGORITHM_RSA_RAW; - if (card->type == SC_CARD_TYPE_PIV_II_SWISSBIT || card->type == SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC) { + if (card->type == SC_CARD_TYPE_PIV_II_SWISSBIT) { flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; } diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index a1ce7c0d1b..4dc586f635 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -917,7 +917,7 @@ typedef struct sc_cardctl_piv_genkey_info_st { unsigned int key_algid; /* RSA 5, 6, 7; EC 11, 14 */ unsigned int key_bits; /* RSA */ unsigned char * exponent; /* RSA */ - unsigned long exponent_len; /* RSA */ + unsigned int exponent_len; /* RSA */ unsigned char * pubkey; /* RSA */ unsigned int pubkey_len; /* RSA */ unsigned char * ecparam; /* EC */ diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 99e03def34..9b18f7ead0 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -137,7 +137,6 @@ enum { SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC, SC_CARD_TYPE_PIV_II_OBERTHUR, SC_CARD_TYPE_PIV_II_PIVKEY, - SC_CARD_TYPE_PIV_II_SWISSBIT_DUAL_CAC, SC_CARD_TYPE_PIV_II_SWISSBIT, /* MuscleApplet */ From d61adef2b656bcf174eb271911e432942203c972 Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Thu, 19 Jan 2023 11:35:24 +0100 Subject: [PATCH 2786/4321] enable card specific private key object path selection --- src/libopensc/card-piv.c | 9 --------- src/pkcs15init/pkcs15-asepcos.c | 1 + src/pkcs15init/pkcs15-authentic.c | 1 + src/pkcs15init/pkcs15-cardos.c | 1 + src/pkcs15init/pkcs15-cflex.c | 2 ++ src/pkcs15init/pkcs15-entersafe.c | 1 + src/pkcs15init/pkcs15-epass2003.c | 1 + src/pkcs15init/pkcs15-gids.c | 1 + src/pkcs15init/pkcs15-gpk.c | 1 + src/pkcs15init/pkcs15-iasecc.c | 1 + src/pkcs15init/pkcs15-incrypto34.c | 1 + src/pkcs15init/pkcs15-init.h | 6 ++++++ src/pkcs15init/pkcs15-isoApplet.c | 1 + src/pkcs15init/pkcs15-lib.c | 6 +++++- src/pkcs15init/pkcs15-muscle.c | 1 + src/pkcs15init/pkcs15-myeid.c | 1 + src/pkcs15init/pkcs15-oberthur.c | 1 + src/pkcs15init/pkcs15-openpgp.c | 1 + src/pkcs15init/pkcs15-rtecp.c | 1 + src/pkcs15init/pkcs15-rutoken.c | 1 + src/pkcs15init/pkcs15-sc-hsm.c | 1 + src/pkcs15init/pkcs15-setcos.c | 1 + src/pkcs15init/pkcs15-starcos.c | 1 + src/pkcs15init/pkcs15-westcos.c | 1 + 24 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index cdbe203cd5..2285d47989 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -115,7 +115,6 @@ enum { PIV_OBJ_9306, PIV_OBJ_9406, PIV_OBJ_9506, - PIV_OBJ_PRIV_SWISSBIT_2900, PIV_OBJ_LAST_ENUM }; @@ -497,7 +496,6 @@ static const struct piv_object piv_objects[] = { "2.16.840.1.101.3.7.2.9999.119", 2, "\x94\x06", "\x94\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9506, "Pub 95 key ", "2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY}, - { PIV_OBJ_PRIV_SWISSBIT_2900, "Priv key ", "", 0, "", "\x29\x00", 0}, { PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0} }; // clang-format on @@ -2543,13 +2541,6 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, } } - if (memcmp(path, "\x50\x15", 2) == 0) { - if (pathlen > 2) { - path += 2; - pathlen -= 2; - } - } - i = piv_find_obj_by_containerid(card, path); if (i < 0) diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index bc0efb5ce6..07dde2c9af 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -810,6 +810,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_asepcos_operations = { NULL, /* create_domain */ asepcos_select_pin_reference, asepcos_create_pin, + NULL, /* select object path */ NULL, /* select key reference */ asepcos_create_key, asepcos_store_key, diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index c6894dd374..143735d55c 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -903,6 +903,7 @@ sc_pkcs15init_authentic_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ authentic_pkcs15_create_pin, + NULL, /* select_object_path */ authentic_pkcs15_select_key_reference, authentic_pkcs15_create_key, authentic_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index a91a13cf90..1715a7276b 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -924,6 +924,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = { NULL, /* create_domain */ cardos_select_pin_reference, cardos_create_pin, + NULL, /* select_object_path */ cardos_select_key_reference, cardos_create_key, cardos_store_key, diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 1cb55c1507..50c530b32d 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -905,6 +905,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cryptoflex_operations = { cflex_create_domain, cflex_select_pin_reference, cflex_create_pin, + NULL, /* select_object_path */ NULL, /* select_key_reference */ cflex_create_key, cflex_store_key, @@ -924,6 +925,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cyberflex_operations = { cflex_create_domain, cflex_select_pin_reference, cflex_create_pin, + NULL, /* select_object_path */ NULL, /* select_key_reference */ cflex_create_key, cflex_store_key, diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 07fdd57f68..2552248dc2 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -523,6 +523,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_entersafe_operations = { NULL, /* create_domain */ entersafe_pin_reference, entersafe_create_pin, + NULL, /* select_object_path */ entersafe_key_reference, entersafe_create_key, entersafe_store_key, diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 91d406c022..40211d4ff0 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -787,6 +787,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_epass2003_operations = { NULL, /* create_domain */ epass2003_pkcs15_pin_reference, epass2003_pkcs15_create_pin, + NULL, /* select_object_path */ epass2003_pkcs15_key_reference, epass2003_pkcs15_create_key, epass2003_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-gids.c b/src/pkcs15init/pkcs15-gids.c index df1bc93b06..39aa1eef56 100644 --- a/src/pkcs15init/pkcs15-gids.c +++ b/src/pkcs15init/pkcs15-gids.c @@ -170,6 +170,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_gids_operations = NULL, /* create_domain */ NULL, /* pin_reference*/ NULL, /* create_pin */ + NULL, /* select_object_path */ gids_select_key_reference, /* key_reference */ gids_create_key, /* create_key */ gids_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 5b6e89ffb0..543c27100e 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -1073,6 +1073,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_gpk_operations = { NULL, /* create_domain */ gpk_select_pin_reference, gpk_create_pin, + NULL, /* select_object_path */ NULL, /* select_key_reference */ gpk_create_key, gpk_store_key, diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index ac3c900aec..1c5e31677b 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1865,6 +1865,7 @@ sc_pkcs15init_iasecc_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ NULL, /* create_pin */ + NULL, /* select_object_path */ iasecc_pkcs15_select_key_reference, iasecc_pkcs15_create_key, iasecc_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index 1119e6b793..0d7044e79a 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -683,6 +683,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_incrypto34_operations = { NULL, /* create_domain */ incrypto34_select_pin_reference, incrypto34_create_pin, + NULL, /* select_object_path */ incrypto34_select_key_reference, incrypto34_create_key, incrypto34_store_key, diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 77a518682b..1cb79c4650 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -88,6 +88,12 @@ struct sc_pkcs15init_operations { const unsigned char *, size_t, const unsigned char *, size_t); + /* + * Select a object path + */ + int (*select_object_path)(struct sc_profile *, struct sc_pkcs15_card *, + struct sc_pkcs15_object *); + /* * Select a reference for a private key object */ diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 506edc2adf..71779bea22 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -787,6 +787,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_isoApplet_operations = NULL, /* create_domain */ isoApplet_select_pin_reference, /* pin_reference*/ isoApplet_create_pin, /* create_pin */ + NULL, /* select_object_path */ isoApplet_select_key_reference, /* key_reference */ isoApplet_create_key, /* create_key */ isoApplet_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index ee27abb0f8..4a706116d6 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1325,7 +1325,11 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof key_info->modulus_length = 0; } - r = select_object_path(p15card, profile, object, &key_info->path); + if (profile->ops->select_object_path) { + r = profile->ops->select_object_path(profile, p15card, object); + } else { + r = select_object_path(p15card, profile, object, &key_info->path); + } LOG_TEST_GOTO_ERR(ctx, r, "Failed to select private key object path"); /* See if we need to select a key reference for this object */ diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index ef821c73df..23f40923c8 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -306,6 +306,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_muscle_operations = { NULL, /* create_domain */ muscle_select_pin_reference, /* select pin reference */ muscle_create_pin, /* Create PIN */ + NULL, /* select_object_path */ muscle_select_key_reference, /* select_key_reference */ muscle_create_key, /* create_key */ muscle_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index ecf09ea3b3..96c7d4bf89 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -958,6 +958,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = { NULL, /* create_domain */ myeid_select_pin_reference, myeid_create_pin, + NULL, /* select_object_path */ NULL, /* select_key_reference */ myeid_create_key, myeid_store_key, diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 9239541d07..11228a856b 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -864,6 +864,7 @@ sc_pkcs15init_oberthur_operations = { NULL, /* create_domain */ cosm_select_pin_reference, cosm_create_pin, + NULL, /* select_object_path */ NULL, /* select_key_reference */ cosm_create_key, /* create_key */ cosm_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index c75bcbdaba..e5169bcc6e 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -531,6 +531,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = { NULL, /* create_domain */ openpgp_select_pin_reference, openpgp_create_pin, + NULL, /* select object path */ NULL, /* select key reference */ openpgp_create_key, openpgp_store_key, diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 843448af14..e728c5f2d0 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -686,6 +686,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_rtecp_operations = { NULL, /* create_domain */ rtecp_select_pin_reference, /* select_pin_reference */ rtecp_create_pin, /* create_pin */ + NULL, /* select_object_path */ rtecp_select_key_reference, /* select_key_reference */ rtecp_create_key, /* create_key */ rtecp_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 856ff7c113..09b945658b 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -314,6 +314,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_rutoken_operations = { NULL, /* create_domain */ rutoken_select_pin_reference, /* select_pin_reference */ rutoken_create_pin, /* create_pin */ + NULL, /* select_object_path */ NULL, /* select_key_reference */ NULL, /* create_key */ NULL, /* store_key */ diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index fa57ce1dd4..47145782a4 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -619,6 +619,7 @@ sc_pkcs15init_sc_hsm_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ NULL, /* create_pin */ + NULL, /* select object path */ NULL, /* select key reference */ sc_hsm_create_key, sc_hsm_store_key, diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 52b234fa2f..e63b68e594 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -584,6 +584,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = { NULL, /* create_domain */ setcos_select_pin_reference, /* select_pin_reference */ setcos_create_pin, /* create_pin */ + NULL, /* select_object_path */ NULL, /* select_key_reference */ setcos_create_key, /* create_key */ setcos_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index ff89d1224c..8d43de8a48 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -929,6 +929,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_starcos_operations = { NULL, /* create_domain */ starcos_pin_reference, starcos_create_pin, + NULL, /* select_object_path */ starcos_key_reference, starcos_create_key, starcos_store_key, diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 6f55c90744..38015c1236 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -352,6 +352,7 @@ static struct sc_pkcs15init_operations sc_pkcs15init_westcos_operations = { NULL, /* create_domain */ westcos_pkcs15_select_pin_reference, /* select_pin_reference */ westcos_pkcs15_create_pin, /* create_pin */ + NULL, /* select_object_path */ NULL, /* select_key_reference */ westcos_pkcs15init_create_key, /* create_key */ westcos_pkcs15init_store_key, /* store_key */ From 4c95817d4090f6cd50066b4a38b6de441466b200 Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Thu, 16 Feb 2023 18:22:37 +0100 Subject: [PATCH 2787/4321] remove added select object path callback in pkcs15init operations --- src/pkcs15init/pkcs15-asepcos.c | 1 - src/pkcs15init/pkcs15-authentic.c | 1 - src/pkcs15init/pkcs15-cardos.c | 1 - src/pkcs15init/pkcs15-cflex.c | 2 -- src/pkcs15init/pkcs15-entersafe.c | 1 - src/pkcs15init/pkcs15-epass2003.c | 1 - src/pkcs15init/pkcs15-gids.c | 1 - src/pkcs15init/pkcs15-gpk.c | 1 - src/pkcs15init/pkcs15-iasecc.c | 1 - src/pkcs15init/pkcs15-incrypto34.c | 1 - src/pkcs15init/pkcs15-init.h | 6 ------ src/pkcs15init/pkcs15-isoApplet.c | 1 - src/pkcs15init/pkcs15-lib.c | 6 +----- src/pkcs15init/pkcs15-muscle.c | 1 - src/pkcs15init/pkcs15-myeid.c | 1 - src/pkcs15init/pkcs15-oberthur.c | 1 - src/pkcs15init/pkcs15-openpgp.c | 1 - src/pkcs15init/pkcs15-rtecp.c | 1 - src/pkcs15init/pkcs15-rutoken.c | 1 - src/pkcs15init/pkcs15-sc-hsm.c | 1 - src/pkcs15init/pkcs15-setcos.c | 1 - src/pkcs15init/pkcs15-starcos.c | 1 - src/pkcs15init/pkcs15-westcos.c | 1 - 23 files changed, 1 insertion(+), 33 deletions(-) diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index 07dde2c9af..bc0efb5ce6 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -810,7 +810,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_asepcos_operations = { NULL, /* create_domain */ asepcos_select_pin_reference, asepcos_create_pin, - NULL, /* select object path */ NULL, /* select key reference */ asepcos_create_key, asepcos_store_key, diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index 143735d55c..c6894dd374 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -903,7 +903,6 @@ sc_pkcs15init_authentic_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ authentic_pkcs15_create_pin, - NULL, /* select_object_path */ authentic_pkcs15_select_key_reference, authentic_pkcs15_create_key, authentic_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 1715a7276b..a91a13cf90 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -924,7 +924,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = { NULL, /* create_domain */ cardos_select_pin_reference, cardos_create_pin, - NULL, /* select_object_path */ cardos_select_key_reference, cardos_create_key, cardos_store_key, diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 50c530b32d..1cb55c1507 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -905,7 +905,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cryptoflex_operations = { cflex_create_domain, cflex_select_pin_reference, cflex_create_pin, - NULL, /* select_object_path */ NULL, /* select_key_reference */ cflex_create_key, cflex_store_key, @@ -925,7 +924,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cyberflex_operations = { cflex_create_domain, cflex_select_pin_reference, cflex_create_pin, - NULL, /* select_object_path */ NULL, /* select_key_reference */ cflex_create_key, cflex_store_key, diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 2552248dc2..07fdd57f68 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -523,7 +523,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_entersafe_operations = { NULL, /* create_domain */ entersafe_pin_reference, entersafe_create_pin, - NULL, /* select_object_path */ entersafe_key_reference, entersafe_create_key, entersafe_store_key, diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 40211d4ff0..91d406c022 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -787,7 +787,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_epass2003_operations = { NULL, /* create_domain */ epass2003_pkcs15_pin_reference, epass2003_pkcs15_create_pin, - NULL, /* select_object_path */ epass2003_pkcs15_key_reference, epass2003_pkcs15_create_key, epass2003_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-gids.c b/src/pkcs15init/pkcs15-gids.c index 39aa1eef56..df1bc93b06 100644 --- a/src/pkcs15init/pkcs15-gids.c +++ b/src/pkcs15init/pkcs15-gids.c @@ -170,7 +170,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_gids_operations = NULL, /* create_domain */ NULL, /* pin_reference*/ NULL, /* create_pin */ - NULL, /* select_object_path */ gids_select_key_reference, /* key_reference */ gids_create_key, /* create_key */ gids_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 543c27100e..5b6e89ffb0 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -1073,7 +1073,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_gpk_operations = { NULL, /* create_domain */ gpk_select_pin_reference, gpk_create_pin, - NULL, /* select_object_path */ NULL, /* select_key_reference */ gpk_create_key, gpk_store_key, diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 1c5e31677b..ac3c900aec 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -1865,7 +1865,6 @@ sc_pkcs15init_iasecc_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ NULL, /* create_pin */ - NULL, /* select_object_path */ iasecc_pkcs15_select_key_reference, iasecc_pkcs15_create_key, iasecc_pkcs15_store_key, diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index 0d7044e79a..1119e6b793 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -683,7 +683,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_incrypto34_operations = { NULL, /* create_domain */ incrypto34_select_pin_reference, incrypto34_create_pin, - NULL, /* select_object_path */ incrypto34_select_key_reference, incrypto34_create_key, incrypto34_store_key, diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 1cb79c4650..77a518682b 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -88,12 +88,6 @@ struct sc_pkcs15init_operations { const unsigned char *, size_t, const unsigned char *, size_t); - /* - * Select a object path - */ - int (*select_object_path)(struct sc_profile *, struct sc_pkcs15_card *, - struct sc_pkcs15_object *); - /* * Select a reference for a private key object */ diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 71779bea22..506edc2adf 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -787,7 +787,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_isoApplet_operations = NULL, /* create_domain */ isoApplet_select_pin_reference, /* pin_reference*/ isoApplet_create_pin, /* create_pin */ - NULL, /* select_object_path */ isoApplet_select_key_reference, /* key_reference */ isoApplet_create_key, /* create_key */ isoApplet_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 4a706116d6..ee27abb0f8 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1325,11 +1325,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card, struct sc_profile *prof key_info->modulus_length = 0; } - if (profile->ops->select_object_path) { - r = profile->ops->select_object_path(profile, p15card, object); - } else { - r = select_object_path(p15card, profile, object, &key_info->path); - } + r = select_object_path(p15card, profile, object, &key_info->path); LOG_TEST_GOTO_ERR(ctx, r, "Failed to select private key object path"); /* See if we need to select a key reference for this object */ diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index 23f40923c8..ef821c73df 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -306,7 +306,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_muscle_operations = { NULL, /* create_domain */ muscle_select_pin_reference, /* select pin reference */ muscle_create_pin, /* Create PIN */ - NULL, /* select_object_path */ muscle_select_key_reference, /* select_key_reference */ muscle_create_key, /* create_key */ muscle_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 96c7d4bf89..ecf09ea3b3 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -958,7 +958,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = { NULL, /* create_domain */ myeid_select_pin_reference, myeid_create_pin, - NULL, /* select_object_path */ NULL, /* select_key_reference */ myeid_create_key, myeid_store_key, diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 11228a856b..9239541d07 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -864,7 +864,6 @@ sc_pkcs15init_oberthur_operations = { NULL, /* create_domain */ cosm_select_pin_reference, cosm_create_pin, - NULL, /* select_object_path */ NULL, /* select_key_reference */ cosm_create_key, /* create_key */ cosm_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index e5169bcc6e..c75bcbdaba 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -531,7 +531,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = { NULL, /* create_domain */ openpgp_select_pin_reference, openpgp_create_pin, - NULL, /* select object path */ NULL, /* select key reference */ openpgp_create_key, openpgp_store_key, diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index e728c5f2d0..843448af14 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -686,7 +686,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_rtecp_operations = { NULL, /* create_domain */ rtecp_select_pin_reference, /* select_pin_reference */ rtecp_create_pin, /* create_pin */ - NULL, /* select_object_path */ rtecp_select_key_reference, /* select_key_reference */ rtecp_create_key, /* create_key */ rtecp_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 09b945658b..856ff7c113 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -314,7 +314,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_rutoken_operations = { NULL, /* create_domain */ rutoken_select_pin_reference, /* select_pin_reference */ rutoken_create_pin, /* create_pin */ - NULL, /* select_object_path */ NULL, /* select_key_reference */ NULL, /* create_key */ NULL, /* store_key */ diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index 47145782a4..fa57ce1dd4 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -619,7 +619,6 @@ sc_pkcs15init_sc_hsm_operations = { NULL, /* create_domain */ NULL, /* select_pin_reference */ NULL, /* create_pin */ - NULL, /* select object path */ NULL, /* select key reference */ sc_hsm_create_key, sc_hsm_store_key, diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index e63b68e594..52b234fa2f 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -584,7 +584,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = { NULL, /* create_domain */ setcos_select_pin_reference, /* select_pin_reference */ setcos_create_pin, /* create_pin */ - NULL, /* select_object_path */ NULL, /* select_key_reference */ setcos_create_key, /* create_key */ setcos_store_key, /* store_key */ diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index 8d43de8a48..ff89d1224c 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -929,7 +929,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_starcos_operations = { NULL, /* create_domain */ starcos_pin_reference, starcos_create_pin, - NULL, /* select_object_path */ starcos_key_reference, starcos_create_key, starcos_store_key, diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 38015c1236..6f55c90744 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -352,7 +352,6 @@ static struct sc_pkcs15init_operations sc_pkcs15init_westcos_operations = { NULL, /* create_domain */ westcos_pkcs15_select_pin_reference, /* select_pin_reference */ westcos_pkcs15_create_pin, /* create_pin */ - NULL, /* select_object_path */ NULL, /* select_key_reference */ westcos_pkcs15init_create_key, /* create_key */ westcos_pkcs15init_store_key, /* store_key */ From 6677dbecd61492b4e1ca4abfcc380875dd915b01 Mon Sep 17 00:00:00 2001 From: Olivia Kaufmann Date: Thu, 9 Mar 2023 14:35:47 +0100 Subject: [PATCH 2788/4321] update product name --- src/libopensc/card-piv.c | 2 +- win32/customactions.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 2285d47989..727725111a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -287,7 +287,7 @@ static const struct sc_atr_table piv_atrs[] = { { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, { "3b:86:80:01:80:31:c1:52:41:12:76", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */ - /* Swissbit iShield FIDO2 with PIV endpoint applet */ + /* Swissbit iShield Key Pro with PIV endpoint applet */ { "3b:97:11:81:21:75:69:53:68:69:65:6c:64:05", NULL, NULL, SC_CARD_TYPE_PIV_II_SWISSBIT, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } diff --git a/win32/customactions.cpp b/win32/customactions.cpp index cca4356229..6a544bd3cf 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -202,7 +202,7 @@ MD_REGISTRATION minidriver_registration[] = { {TEXT("IAS/ECC CPxCL"), {0x3B,0X8F,0x80,0x01,0x00,0x31,0xB8,0x64,0x00,0x00,0xEC,0xC0,0x73,0x94,0x01,0x80,0x82,0x90,0x00,0x0E}, 20, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, /* from card-piv.c */ - {TEXT("Swissbit iShield FIDO2"), {0x3b,0x97,0x11,0x81,0x21,0x75,0x69,0x53,0x68,0x69,0x65,0x6c,0x64,0x05}, + {TEXT("Swissbit iShield Key Pro"), {0x3b,0x97,0x11,0x81,0x21,0x75,0x69,0x53,0x68,0x69,0x65,0x6c,0x64,0x05}, 14, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, }; From a97e702bb8e66b4f5b6230b9962b7d36869237bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20H=C3=BCnseler?= Date: Mon, 6 Mar 2023 13:23:52 +0100 Subject: [PATCH 2789/4321] sm-eac: mark cryptographic mechanism field as optional and fix asn.1 encode error in encode_mse_cdata during terminal authentication. Fixes #2726 --- src/sm/sm-eac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index 4ca94a3506..ea1256bb9a 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -192,7 +192,7 @@ static int encode_mse_cdata(struct sc_context *ctx, int protocol, struct sc_asn1_entry capdu_eac_mse[] = { { "Cryptographic mechanism reference", - SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x00, 0, NULL, NULL }, + SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x00, SC_ASN1_OPTIONAL, NULL, NULL }, { "Reference of a public key / secret key", SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x03, SC_ASN1_OPTIONAL, NULL, NULL }, { "Reference of a private key / Reference for computing a session key", From 930fa0acb483e2e67fe6ff39a8c149c94e8339b2 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 21 Feb 2023 08:39:24 -0600 Subject: [PATCH 2790/4321] pkcs11-tool to use OpenSSL libctx This is in addition to "Introduce use of custom ossl libctx with OpenSSL >= 3.0" https://github.com/OpenSC/OpenSC/pull/2712 pkcs11-tool uses some functions found in libopensc, but does not create a sc_context like other OpenSC tools as the pkcs11 module can be any pkscs11 module. There is one OpenSSL function "d2i_PUBKEY_bio" that does not have an equivalent "d2i_PUBKEY_ex_bio" in 3.0.8. It is listed in OpenSSL master. See: https://github.com/openssl/openssl/pull/18427 On branch ossl_lib_ctx-pkcs11-tool Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 53 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4c4a6dd287..197bb72e39 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -73,8 +73,13 @@ #include "util.h" #include "libopensc/sc-ossl-compat.h" +/* pkcs11-tool uses libopensc routines that do not use an sc_context + * but does use some OpenSSL routines + */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L static OSSL_PROVIDER *legacy_provider = NULL; + static OSSL_PROVIDER *default_provider = NULL; + static OSSL_LIB_CTX *osslctx = NULL; #endif #ifdef _WIN32 @@ -753,6 +758,19 @@ int main(int argc, char * argv[]) util_fatal("Cannot set FMODE to O_BINARY"); #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!osslctx) { + if (!(osslctx = OSSL_LIB_CTX_new())) { + util_fatal("Failed to create OpenSSL OSSL_LIB_CTX\n"); + } + } + if (!default_provider) { + if (!(default_provider = OSSL_PROVIDER_load(osslctx, "default"))) { + util_fatal("Failed to load OpenSSL \"default\" provider\n"); + } + } +#endif + while (1) { c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r", options, &long_optind); @@ -3600,15 +3618,32 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) if (private) { if (!strstr((char *)data, "-----BEGIN ")) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + *key = d2i_PrivateKey_ex_bio(mem, NULL, osslctx, NULL); +#else *key = d2i_PrivateKey_bio(mem, NULL); +#endif else +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + *key = PEM_read_bio_PrivateKey_ex(mem, NULL, NULL, NULL, osslctx, NULL); +#else *key = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL); +#endif } else { if (!strstr((char *)data, "-----BEGIN ")) + /* TODO following is in OpenSSL master not 3.0.8 */ +#if OPENSSL_VERSION_NUMBER >= 0x30200000L + *key = d2i_PUBKEY_ex_bio(mem, NULL, osslctx, NULL); +#else *key = d2i_PUBKEY_bio(mem, NULL); +#endif else +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + *key = PEM_read_bio_PUBKEY_ex(mem, NULL, NULL, NULL, osslctx, NULL); +#else *key = PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL); +#endif } BIO_free(mem); @@ -3767,7 +3802,7 @@ parse_gost_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) #if OPENSSL_VERSION_NUMBER < 0x30000000L point = EC_KEY_get0_public_key(src); #else - group = EC_GROUP_new_by_curve_name(nid); + group = EC_GROUP_new_by_curve_name_ex(osslctx, NULL, nid); EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &pubkey_len); if (!(pubkey = malloc(pubkey_len)) || EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey, pubkey_len, NULL) != 1 || @@ -4755,7 +4790,12 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE if (BIO_read_filename(bio_in, opt_input) <= 0) util_fatal("Cannot open %s: %m", opt_input); +#if OPENSSL_VERSION_NUMBER >= 0x30200000L +/* TODO following is in OpenSSL master not 3.0.8 */ + pkey = d2i_PUBKEY_ex_bio(bio_in, NULL, osslctx, NULL); +#else pkey = d2i_PUBKEY_bio(bio_in, NULL); +#endif if (!pkey) util_fatal("Cannot read EC key from %s", opt_input); @@ -5576,7 +5616,7 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot convert RSA public key to DER"); RSA_free(rsa); #else - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + ctx = EVP_PKEY_CTX_new_from_name(osslctx, "RSA", NULL); if (!ctx) util_fatal("out of memory"); if (!(bld = OSSL_PARAM_BLD_new()) || @@ -5630,6 +5670,7 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot parse EC_PARAMS"); EVP_PKEY_assign_EC_KEY(pkey, ec); #else +/* TODO needs debugging */ if (!d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len)) util_fatal("cannot parse EC_PARAMS"); #endif @@ -5691,7 +5732,7 @@ static int read_object(CK_SESSION_HANDLE session) ASN1_STRING_free(os); free(value); - if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) || + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "EC", NULL)) || EVP_PKEY_fromdata_init(ctx) != 1) { OSSL_PARAM_free(p); EVP_PKEY_CTX_free(ctx); @@ -6142,7 +6183,7 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv } OSSL_PARAM_BLD_free(bld); - if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || + if (!(ctx = EVP_PKEY_CTX_new_from_name(osslctx, "RSA", NULL)) || EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != 1) { fprintf(stderr, "public key not extractable\n"); @@ -7026,7 +7067,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session, } EVP_PKEY_CTX *ctx; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + ctx = EVP_PKEY_CTX_new_from_pkey(osslctx, pkey, NULL); +#else ctx = EVP_PKEY_CTX_new(pkey, NULL); +#endif if (!ctx) { EVP_PKEY_free(pkey); printf("EVP_PKEY_CTX_new failed, returning\n"); From 540f3da3db3ced6fd8586223faee27e5ca7d958c Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 23 Feb 2023 13:46:06 -0600 Subject: [PATCH 2791/4321] pkcs11-tool.c comments on d2i_PUBKEY_ex_bio Requested https://github.com/OpenSC/OpenSC/pull/2715#pullrequestreview-1310924929 On branch ossl_lib_ctx-pkcs11-tool Changes to be committed: modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 197bb72e39..e105898d21 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3632,7 +3632,17 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) } else { if (!strstr((char *)data, "-----BEGIN ")) - /* TODO following is in OpenSSL master not 3.0.8 */ + /* + * d2i_PUBKEY_ex_bio is in OpenSSL master not not 3.1 as of 02/23/2023 + * as 820723dde0 originally written 2022-05-29 + * related issues: + * https://github.com/openssl/openssl/issues/18372 + * https://github.com/openssl/openssl/issues/18372#issuecomment-1134336570 + * Says using the default provider should work + * https://github.com/openssl/openssl/pull/18427 + * https://github.com/beldmit/openssl/commit/1ca99e04d1113268da6a8a8d1f99962b29910910 + * committed Dec 26, 2022 + */ #if OPENSSL_VERSION_NUMBER >= 0x30200000L *key = d2i_PUBKEY_ex_bio(mem, NULL, osslctx, NULL); #else From 58a1cbd0f2cdc08a9d1cff6e1232441c54fdabee Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 8 Mar 2023 11:58:01 -0600 Subject: [PATCH 2792/4321] pkcs11-tool.c Address comments On branch ossl_lib_ctx-pkcs11-tool Changes to be committed: modified: pkcs11-tool.c --- src/tools/pkcs11-tool.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e105898d21..e964c2f774 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -759,16 +759,12 @@ int main(int argc, char * argv[]) #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L - if (!osslctx) { - if (!(osslctx = OSSL_LIB_CTX_new())) { - util_fatal("Failed to create OpenSSL OSSL_LIB_CTX\n"); - } - } - if (!default_provider) { - if (!(default_provider = OSSL_PROVIDER_load(osslctx, "default"))) { - util_fatal("Failed to load OpenSSL \"default\" provider\n"); - } - } + if (!(osslctx = OSSL_LIB_CTX_new())) { + util_fatal("Failed to create OpenSSL OSSL_LIB_CTX\n"); + } + if (!(default_provider = OSSL_PROVIDER_load(osslctx, "default"))) { + util_fatal("Failed to load OpenSSL \"default\" provider\n"); + } #endif while (1) { @@ -3633,15 +3629,8 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) else { if (!strstr((char *)data, "-----BEGIN ")) /* - * d2i_PUBKEY_ex_bio is in OpenSSL master not not 3.1 as of 02/23/2023 - * as 820723dde0 originally written 2022-05-29 - * related issues: - * https://github.com/openssl/openssl/issues/18372 - * https://github.com/openssl/openssl/issues/18372#issuecomment-1134336570 - * Says using the default provider should work - * https://github.com/openssl/openssl/pull/18427 - * https://github.com/beldmit/openssl/commit/1ca99e04d1113268da6a8a8d1f99962b29910910 - * committed Dec 26, 2022 + * d2i_PUBKEY_ex_bio is in OpenSSL master of 02/23/2023 + * committed Dec 26, 2022 expected in 3.2.0 */ #if OPENSSL_VERSION_NUMBER >= 0x30200000L *key = d2i_PUBKEY_ex_bio(mem, NULL, osslctx, NULL); @@ -4801,7 +4790,6 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE util_fatal("Cannot open %s: %m", opt_input); #if OPENSSL_VERSION_NUMBER >= 0x30200000L -/* TODO following is in OpenSSL master not 3.0.8 */ pkey = d2i_PUBKEY_ex_bio(bio_in, NULL, osslctx, NULL); #else pkey = d2i_PUBKEY_bio(bio_in, NULL); @@ -5680,7 +5668,6 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot parse EC_PARAMS"); EVP_PKEY_assign_EC_KEY(pkey, ec); #else -/* TODO needs debugging */ if (!d2i_KeyParams(EVP_PKEY_EC, &pkey, &a, len)) util_fatal("cannot parse EC_PARAMS"); #endif From eba22f2135924c0471e6c408e9150ae5ddb77443 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 8 Mar 2023 11:14:02 +0100 Subject: [PATCH 2793/4321] pkcs11: Add missing attributes used by pkcs11-provider --- src/pkcs11/pkcs11-display.c | 2 ++ src/pkcs11/pkcs11.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index da4cb528cf..f9e44834ba 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -745,6 +745,7 @@ type_spec ck_attribute_specs[] = { { CKA_EXPONENT_1 , "CKA_EXPONENT_1 ", print_generic, NULL }, { CKA_EXPONENT_2 , "CKA_EXPONENT_2 ", print_generic, NULL }, { CKA_COEFFICIENT , "CKA_COEFFICIENT ", print_generic, NULL }, + { CKA_PUBLIC_KEY_INFO , "CKA_PUBLIC_KEY_INFO ", print_generic, NULL }, { CKA_PRIME , "CKA_PRIME ", print_generic, NULL }, { CKA_SUBPRIME , "CKA_SUBPRIME ", print_generic, NULL }, { CKA_BASE , "CKA_BASE ", print_generic, NULL }, @@ -758,6 +759,7 @@ type_spec ck_attribute_specs[] = { { CKA_ALWAYS_SENSITIVE , "CKA_ALWAYS_SENSITIVE ", print_boolean, NULL }, { CKA_KEY_GEN_MECHANISM , "CKA_KEY_GEN_MECHANISM", print_boolean, NULL }, { CKA_MODIFIABLE , "CKA_MODIFIABLE ", print_boolean, NULL }, + { CKA_COPYABLE , "CKA_COPYABLE ", print_boolean, NULL }, { CKA_EC_PARAMS , "CKA_EC_PARAMS ", print_generic, NULL }, { CKA_ECDSA_PARAMS , "CKA_ECDSA_PARAMS ", print_generic, NULL }, { CKA_EC_POINT , "CKA_EC_POINT ", print_generic, NULL }, diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index cf9e9c6bfd..b5bbd8e2c9 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -438,6 +438,7 @@ typedef unsigned long ck_attribute_type_t; #define CKA_EXPONENT_1 (0x126UL) #define CKA_EXPONENT_2 (0x127UL) #define CKA_COEFFICIENT (0x128UL) +#define CKA_PUBLIC_KEY_INFO (0x129UL) #define CKA_PRIME (0x130UL) #define CKA_SUBPRIME (0x131UL) #define CKA_BASE (0x132UL) @@ -451,6 +452,7 @@ typedef unsigned long ck_attribute_type_t; #define CKA_ALWAYS_SENSITIVE (0x165UL) #define CKA_KEY_GEN_MECHANISM (0x166UL) #define CKA_MODIFIABLE (0x170UL) +#define CKA_COPYABLE (0x171UL) #define CKA_DESTROYABLE (0x172UL) #define CKA_ECDSA_PARAMS (0x180UL) #define CKA_EC_PARAMS (0x180UL) From 5d3657f76b0f0645a41bde948aa5adb6d1826995 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 9 Mar 2023 14:41:12 +0100 Subject: [PATCH 2794/4321] fixed typos --- src/pkcs15init/pkcs15-oberthur-awp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index bdffeaec1c..879977d3bb 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -325,13 +325,13 @@ awp_create_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); LOG_TEST_RET(ctx, rv, "Create container failed"); - sc_log(ctx, "contaner cfile(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", clist->record_count, clist->record_length); + sc_log(ctx, "container cfile(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", clist->record_count, clist->record_length); rv = sc_select_file(p15card->card, &clist->path, &file); LOG_TEST_RET(ctx, rv, "Create container failed: cannot select container's list"); file->record_length = clist->record_length; - sc_log(ctx, "contaner file(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", file->record_count, file->record_length); + sc_log(ctx, "container file(rcount:%"SC_FORMAT_LEN_SIZE_T"u,rlength:%"SC_FORMAT_LEN_SIZE_T"u)", file->record_count, file->record_length); sc_log(ctx, "Append new record %"SC_FORMAT_LEN_SIZE_T"u for private key", file->record_count + 1); rv = awp_create_container_record(p15card, profile, file, acc); @@ -1649,10 +1649,10 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, sc_log(ctx, "update container entry (type:%X,file-id:%X)", type, file_id); rv = awp_new_file(p15card, profile, COSM_CONTAINER_LIST, 0, &clist, NULL); - LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot get allocate AWP file"); + LOG_TEST_RET(ctx, rv, "AWP update container entry: cannot get allocate AWP file"); rv = sc_select_file(p15card->card, &clist->path, &file); - LOG_TEST_RET(ctx, rv, "AWP update contaner entry: cannot select container list file"); + LOG_TEST_RET(ctx, rv, "AWP update container entry: cannot select container list file"); buff = malloc(file->record_length); if (!buff) @@ -1661,7 +1661,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, for (rec = 1; rec <= (unsigned)file->record_count; rec++) { rv = sc_read_record(p15card->card, rec, buff, file->record_length, SC_RECORD_BY_REC_NR); if (rv < 0) { - sc_log(ctx, "AWP update contaner entry: read record error %i", rv); + sc_log(ctx, "AWP update container entry: read record error %i", rv); break; } rec_len = rv; @@ -1680,26 +1680,26 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, if (!memcmp(buff,"\0\0\0\0\0\0\0\0\0\0\0\0",12)) { rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_ERASE); if (rv < 0) { - sc_log(ctx, "AWP update contaner entry: 'erase' authentication error %i", rv); + sc_log(ctx, "AWP update container entry: 'erase' authentication error %i", rv); break; } rv = sc_delete_record(p15card->card, rec); if (rv < 0) { - sc_log(ctx, "AWP update contaner entry: delete record error %i", rv); + sc_log(ctx, "AWP update container entry: delete record error %i", rv); break; } } else { rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); if (rv < 0) { - sc_log(ctx, "AWP update contaner entry: 'update' authentication error %i", rv); + sc_log(ctx, "AWP update container entry: 'update' authentication error %i", rv); break; } rv = sc_update_record(p15card->card, rec, buff, rec_len, SC_RECORD_BY_REC_NR); if (rv < 0) { - sc_log(ctx, "AWP update contaner entry: update record error %i", rv); + sc_log(ctx, "AWP update container entry: update record error %i", rv); break; } } From a285b300305ab19a706dac158695c8d92b96d1ff Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 17 Mar 2023 15:10:29 +0100 Subject: [PATCH 2795/4321] Check nested macros when parsing pkcs15init profile When processing macros in pkcs15init profile, the macros may contain nested macros, which causes recursion loop. In this particular case found by OSS-Fuzz, the problem was caused by macro e =1)$e Thank you OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53545 --- src/pkcs15init/profile.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index dbdc535efe..c69f9fbfbb 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1976,24 +1976,23 @@ static struct block root_ops = { }; static int -check_macro_reference_loop(scconf_list *start, scconf_list *current, struct state *cur, int depth) { +check_macro_reference_loop(char *start, char *str, struct state *cur, int depth) { sc_macro_t *mac = NULL; - const char *str = NULL; + char *mac_name = NULL; - if (!start || !current || !cur) + if (!start || !str || !cur) return 1; if (depth == 16) return 1; - str = current->data; - if (str[0] != '$') + if (!(mac_name = strchr(str, '$'))) return 0; - if (!(mac = find_macro(cur->profile, str + 1))) + if (!(mac = find_macro(cur->profile, mac_name + 1))) return 0; - if (!strcmp(mac->name, start->data + 1)) + if (!strcmp(mac->name, start + 1)) return 1; - return check_macro_reference_loop(start, mac->value, cur, depth + 1); + return check_macro_reference_loop(start, mac->value->data, cur, depth + 1); } static int @@ -2013,6 +2012,15 @@ build_argv(struct state *cur, const char *cmdname, str = list->data; if (str[0] != '$') { + /* When str contains macro inside, macro reference loop needs to be checked */ + char *mac_name = NULL; + if ((mac_name = strchr(str, '$'))) { + if ((mac = find_macro(cur->profile, mac_name + 1)) + && check_macro_reference_loop(mac_name + 1, mac->value->data, cur, 0)) { + return SC_ERROR_SYNTAX_ERROR; + } + } + argv[argc++] = list->data; continue; } @@ -2027,7 +2035,7 @@ build_argv(struct state *cur, const char *cmdname, if (list == mac->value) { return SC_ERROR_SYNTAX_ERROR; } - if (check_macro_reference_loop(list, mac->value, cur, 0)) { + if (check_macro_reference_loop(list->data, mac->value->data, cur, 0)) { return SC_ERROR_SYNTAX_ERROR; } #ifdef DEBUG_PROFILE From fd4754b101a50541d41216ba4d9d57bc9e2991cc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 15 Feb 2023 10:28:11 +0100 Subject: [PATCH 2796/4321] Handle errors when processing macros --- src/pkcs15init/profile.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index c69f9fbfbb..2b793b0282 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -259,7 +259,7 @@ static struct auth_info * new_key(struct sc_profile *, unsigned int, unsigned int); static void set_pin_defaults(struct sc_profile *, struct pin_info *); -static void new_macro(sc_profile_t *, const char *, scconf_list *); +static int new_macro(sc_profile_t *, const char *, scconf_list *); static sc_macro_t * find_macro(sc_profile_t *, const char *); static sc_file_t * @@ -1826,6 +1826,7 @@ process_macros(struct state *cur, struct block *info, { scconf_item *item; const char *name; + int r; for (item = blk->items; item; item = item->next) { name = item->key; @@ -1834,27 +1835,33 @@ process_macros(struct state *cur, struct block *info, #ifdef DEBUG_PROFILE printf("Defining %s\n", name); #endif - new_macro(cur->profile, name, item->value.list); + r = new_macro(cur->profile, name, item->value.list); + if (r != SC_SUCCESS) + return r; } - return 0; + return SC_SUCCESS; } -static void +static int new_macro(sc_profile_t *profile, const char *name, scconf_list *value) { sc_macro_t *mac; + if (!profile || !name || !value) + return SC_ERROR_INVALID_ARGUMENTS; + if ((mac = find_macro(profile, name)) == NULL) { mac = calloc(1, sizeof(*mac)); if (mac == NULL) - return; + return SC_ERROR_OUT_OF_MEMORY; mac->name = strdup(name); mac->next = profile->macro_list; profile->macro_list = mac; } mac->value = value; + return SC_SUCCESS; } static sc_macro_t * From b6dc20b29ba5da4cac6ebb0a4539233e58fa5fcc Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 17 Feb 2023 16:24:24 +0100 Subject: [PATCH 2797/4321] muscle-filesystem: Do not process too deep filesystem Given test-case causes the creation of too deep filesystem, which processing recursive leads to stack-overflow. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54592 --- src/libopensc/muscle-filesystem.c | 19 ++++++++++++++----- src/libopensc/muscle-filesystem.h | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index 3bfbaf3690..e4f43e4bf7 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -78,9 +78,12 @@ static int mscfs_is_ignored(mscfs_t* fs, msc_id objectId) return ignored; } +#define MAX_FILES 10000 int mscfs_push_file(mscfs_t* fs, mscfs_file_t *file) { mscfs_cache_t *cache = &fs->cache; + if (cache->size >= MAX_FILES) + return SC_ERROR_INTERNAL; if(!cache->array || cache->size == cache->totalSize) { int length = cache->totalSize + MSCFS_CACHE_INCREMENT; mscfs_file_t *oldArray; @@ -96,7 +99,7 @@ int mscfs_push_file(mscfs_t* fs, mscfs_file_t *file) } cache->array[cache->size] = *file; cache->size++; - return 0; + return SC_SUCCESS; } int mscfs_update_cache(mscfs_t* fs) { @@ -122,7 +125,9 @@ int mscfs_update_cache(mscfs_t* fs) { file.ef = 1; /* File is a working elementary file */ } - mscfs_push_file(fs, &file); + r = mscfs_push_file(fs, &file); + if (r != SC_SUCCESS) + return r; } r = fs->listFile(&file, 0, fs->udata); if(r == 0) @@ -133,11 +138,13 @@ int mscfs_update_cache(mscfs_t* fs) { return fs->cache.size; } -void mscfs_check_cache(mscfs_t* fs) +int mscfs_check_cache(mscfs_t* fs) { + int r = SC_SUCCESS; if(!fs->cache.array) { - mscfs_update_cache(fs); + r = mscfs_update_cache(fs); } + return r; } int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory) @@ -216,7 +223,9 @@ int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t ** } /* Obtain file information while checking if it exists */ - mscfs_check_cache(fs); + rc = mscfs_check_cache(fs); + if (rc < 0) + return rc; if(idx) *idx = -1; for(x = 0; x < fs->cache.size; x++) { *file_data = &fs->cache.array[x]; diff --git a/src/libopensc/muscle-filesystem.h b/src/libopensc/muscle-filesystem.h index 59243711d7..da7d74eb5a 100644 --- a/src/libopensc/muscle-filesystem.h +++ b/src/libopensc/muscle-filesystem.h @@ -58,7 +58,7 @@ void mscfs_clear_cache(mscfs_t* fs); int mscfs_push_file(mscfs_t* fs, mscfs_file_t *file); int mscfs_update_cache(mscfs_t* fs); -void mscfs_check_cache(mscfs_t* fs); +int mscfs_check_cache(mscfs_t* fs); int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory); From f169e3f56b4e061267d188c66c7223ba12177211 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 17 Mar 2023 15:11:15 +0100 Subject: [PATCH 2798/4321] Add error checking in muscle driver --- src/libopensc/card-muscle.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 7b0bf64e5a..5a868115b5 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -278,7 +278,8 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) int x; mscfs_file_t *childFile; /* Delete children */ - mscfs_check_cache(fs); + r = mscfs_check_cache(fs); + if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); sc_log(card->ctx, "DELETING Children of: %02X%02X%02X%02X\n", @@ -377,7 +378,8 @@ static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** f int objectIndex; u8* oid; - mscfs_check_cache(fs); + r = mscfs_check_cache(fs); + if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); r = mscfs_loadFileInfo(fs, path_in->value, path_in->len, &file_data, &objectIndex); if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); @@ -524,10 +526,11 @@ static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) { muscle_private_t* priv = MUSCLE_DATA(card); mscfs_t *fs = priv->fs; - int x; + int x, r; int count = 0; - mscfs_check_cache(priv->fs); + r = mscfs_check_cache(priv->fs); + if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); for(x = 0; x < fs->cache.size; x++) { u8* oid = fs->cache.array[x].objectId.id; From 5631e9843c832a99769def85b7b9b68b4e3e3959 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 3 Mar 2023 16:07:38 +0100 Subject: [PATCH 2799/4321] Check length of string before making copy Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55851 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55998 --- src/pkcs15init/profile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 2b793b0282..3bad1e8536 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1575,7 +1575,10 @@ do_acl(struct state *cur, int argc, char **argv) while (argc--) { unsigned int op, method, id; + if (strlen(*argv) >= sizeof(oper)) + goto bad; strlcpy(oper, *argv++, sizeof(oper)); + if ((what = strchr(oper, '=')) == NULL) goto bad; *what++ = '\0'; @@ -2288,6 +2291,9 @@ get_authid(struct state *cur, const char *value, return get_uint(cur, value, type); } + if (strlen(value) >= sizeof(temp)) + return 1; + n = strcspn(value, "0123456789x"); strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp)); From eac9f21202377cb2b34246f2920504dfbd92b139 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 8 Mar 2023 10:06:08 +0100 Subject: [PATCH 2800/4321] Fix file memory leak Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56736 --- src/pkcs15init/pkcs15-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index ee27abb0f8..cd3daf57c6 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -3993,6 +3993,7 @@ sc_pkcs15init_authenticate(struct sc_profile *profile, struct sc_pkcs15_card *p1 for (; r == 0 && acl; acl = acl->next) { if (acl->method == SC_AC_NEVER) { + sc_file_free(file_tmp); LOG_TEST_RET(ctx, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Authentication failed: never allowed"); } else if (acl->method == SC_AC_NONE) { From d0a2bdaac5dcecc905c7aad6579c46624cc0ebde Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 8 Mar 2023 10:33:40 +0100 Subject: [PATCH 2801/4321] Check length of path Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56781 --- src/pkcs15init/pkcs15-oberthur.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 9239541d07..990aa9c7d2 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -134,6 +134,9 @@ cosm_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, /* Select the parent DF */ path = df->path; + if (path.len < 2) { + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + } path.len -= 2; rv = sc_select_file(p15card->card, &path, &parent); From 34f6ca6ed1cdd6eeb0faac4087634467ff604a26 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 17 Mar 2023 15:35:51 +0100 Subject: [PATCH 2802/4321] Use better naming for macro-related variables --- src/pkcs15init/profile.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 3bad1e8536..fe1b46e66f 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1987,8 +1987,8 @@ static struct block root_ops = { static int check_macro_reference_loop(char *start, char *str, struct state *cur, int depth) { - sc_macro_t *mac = NULL; - char *mac_name = NULL; + sc_macro_t *macro = NULL; + char *name = NULL; if (!start || !str || !cur) return 1; @@ -1996,13 +1996,13 @@ check_macro_reference_loop(char *start, char *str, struct state *cur, int depth) if (depth == 16) return 1; - if (!(mac_name = strchr(str, '$'))) + if (!(name = strchr(str, '$'))) return 0; - if (!(mac = find_macro(cur->profile, mac_name + 1))) + if (!(macro = find_macro(cur->profile, name + 1))) return 0; - if (!strcmp(mac->name, start + 1)) + if (!strcmp(macro->name, start + 1)) return 1; - return check_macro_reference_loop(start, mac->value->data, cur, depth + 1); + return check_macro_reference_loop(start, macro->value->data, cur, depth + 1); } static int @@ -2011,7 +2011,7 @@ build_argv(struct state *cur, const char *cmdname, { unsigned int argc; const char *str; - sc_macro_t *mac; + sc_macro_t *macro; int r; for (argc = 0; list; list = list->next) { @@ -2023,10 +2023,10 @@ build_argv(struct state *cur, const char *cmdname, str = list->data; if (str[0] != '$') { /* When str contains macro inside, macro reference loop needs to be checked */ - char *mac_name = NULL; - if ((mac_name = strchr(str, '$'))) { - if ((mac = find_macro(cur->profile, mac_name + 1)) - && check_macro_reference_loop(mac_name + 1, mac->value->data, cur, 0)) { + char *macro_name = NULL; + if ((macro_name = strchr(str, '$'))) { + if ((macro = find_macro(cur->profile, macro_name + 1)) + && check_macro_reference_loop(macro_name + 1, macro->value->data, cur, 0)) { return SC_ERROR_SYNTAX_ERROR; } } @@ -2036,16 +2036,16 @@ build_argv(struct state *cur, const char *cmdname, } /* Expand macro reference */ - if (!(mac = find_macro(cur->profile, str + 1))) { + if (!(macro = find_macro(cur->profile, str + 1))) { parse_error(cur, "%s: unknown macro \"%s\"", cmdname, str); return SC_ERROR_SYNTAX_ERROR; } - if (list == mac->value) { + if (list == macro->value) { return SC_ERROR_SYNTAX_ERROR; } - if (check_macro_reference_loop(list->data, mac->value->data, cur, 0)) { + if (check_macro_reference_loop(list->data, macro->value->data, cur, 0)) { return SC_ERROR_SYNTAX_ERROR; } #ifdef DEBUG_PROFILE @@ -2058,7 +2058,7 @@ build_argv(struct state *cur, const char *cmdname, printf("\n"); } #endif - r = build_argv(cur, cmdname, mac->value, + r = build_argv(cur, cmdname, macro->value, argv + argc, max - argc); if (r < 0) return r; From d952a9fa3d0e2becc684c3a2529173d3d151f817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C5=A0arinay?= Date: Wed, 22 Mar 2023 09:20:41 +0100 Subject: [PATCH 2803/4321] support for Slovak eID cards (#2672) ## Driver The card runs CardOS 5.4, the new driver is therefore a stripped-down version of ```card-cardos.c``` The only place where I have to diverge from the original driver is ```set_security_env```, because the card expects ```MSE RESTORE``` instead of ```MSE SET```. I abuse ```key_ref``` to store the corresponding ```seIdentifier```, as our pkcs\#15 structures do not include the entry. Because the card shares the ATR with other CardOS 5.4 cards, the new driver precedes ```cardos-driver``` within ```internal_card_drivers[]```. ## PKCS\#15 emulation Within EF.DIR there are 5 applications. The last two carry (apparently not entirely usable) PKCS\#15 structures. ```pkcs15-skeid.c``` binds the _fourth_ application in the list. Otherwise ```sc_pkcs15_bind_internal``` would get called and create an unusable token. In the case of the fifth application this is prevented by ```SC_PKCS11_FRAMEWORK_DATA_MAX_NUM = 4```. Because there is no point in calling ```sc_pkcs15_bind_internal``` for this card, I added it to ```sc_pkcs15_is_emulation_only```. This does not prevent ```sc_pkcs15_bind_internal``` from [getting called](https://github.com/OpenSC/OpenSC/blob/70771735ae10180bb039043b9a1b00b66bf00fc1/src/libopensc/pkcs15.c#L1296 ) though (if synthetic binding was unsuccessful). I consider this behaviour a bit counterintuitive. I mention it here to report on and justify what I have done, it has no noticeable effect on my driver (any more). Let me know if ```sc_pkcs15_is_emulation_only``` warrants a separate GitHub issue. ## PINs There is a global User PIN labeled BOK. The qualified certificate (key) requires user consent and a separate (local) Signature PIN labeled KEP. The "official" proprietary PKCS\#11 module requires both the codes for every signature. Fortunately, the card is happy with the Signature PIN only, as there seems to be no convenient way to have multiple PIN codes per slot. I considered emulating (parts of) the "official" behaviour wihtin a custom ```pin_cmd``` that contained the following: ```C if (data->pin_reference == 0x87 && data->cmd != SC_PIN_CMD_CHANGE && data->pin_type != SC_AC_CONTEXT_SPECIFIC) { sc_log(card->ctx, "Non-specific KEP PIN encountered, handling it as BOK instead."); data->pin_reference = 0x03; } ``` I ultimately decided against the idea. It adds complexity (or confusion) and provides little benefit. I mention the issue because it is connected to a failure in ```pkcs11-tool --test --slot 1 --login```: [log](https://github.com/OpenSC/OpenSC/files/10326667/pkcs11-tool_test_slot_1.log). Because the local Signature PIN is used for the session, ```test_verify()``` fails [here](https://github.com/OpenSC/OpenSC/blob/70771735ae10180bb039043b9a1b00b66bf00fc1/src/tools/pkcs11-tool.c#L6639). The card enforces CKA_ALWAYS_AUTHENTICATE and therefore reports that the Signature PIN is (no longer) verified, apparently because signatures have been computed during ```test_signature()```. The only effect of this is that the built-in test fails even though the token works (reasonably) well. The above ```pin_cmd``` hack would result in a passed ```pkcs11-tool --test --slot 1 --login```. I include this information mainly to justify a PR with a failed test attached. If the behaviour of ```pkcs11-tool --test``` in the context of a local Signature PIN and ```user_consent``` warrants a separate GitHub issue, do please let me know. For completeness, [here](https://github.com/OpenSC/OpenSC/files/10326703/pkcs11-tool_test_slot_0.log) is the output of ```pkcs11-tool --test --slot 0 --login```. --- src/libopensc/Makefile.am | 8 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-skeid.c | 186 ++++++++++++++++++++++++++++++++++ src/libopensc/cards.h | 7 +- src/libopensc/ctx.c | 4 + src/libopensc/pkcs15-skeid.c | 189 +++++++++++++++++++++++++++++++++++ src/libopensc/pkcs15-syn.c | 2 + src/libopensc/pkcs15-syn.h | 1 + 8 files changed, 394 insertions(+), 7 deletions(-) create mode 100644 src/libopensc/card-skeid.c create mode 100644 src/libopensc/pkcs15-skeid.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 16209a4b53..e07cd3219a 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -50,7 +50,7 @@ libopensc_la_SOURCES_BASE = \ card-dnie.c cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c card-nqApplet.c \ + card-edo.c card-nqApplet.c card-skeid.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-gemsafeGPK.c \ @@ -59,7 +59,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c compression.c sm.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c compression.c sm.c \ aux-data.c if ENABLE_CRYPTOTOKENKIT @@ -133,7 +133,7 @@ TIDY_FILES = \ cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c card-nqApplet.c \ + card-edo.c card-nqApplet.c card-skeid.c \ \ pkcs15-openpgp.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c \ @@ -142,7 +142,7 @@ TIDY_FILES = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c compression.c sm.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c compression.c sm.c \ aux-data.c \ #$(SOURCES) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index d1961b1d84..856cce5201 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -28,7 +28,7 @@ OBJECTS = \ card-sc-hsm.obj card-dnie.obj card-isoApplet.obj pkcs15-coolkey.obj \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj card-esteid2018.obj card-idprime.obj \ - card-edo.obj card-nqApplet.obj \ + card-edo.obj card-nqApplet.obj card-skeid.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ @@ -37,7 +37,7 @@ OBJECTS = \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ - pkcs15-starcos-esign.obj compression.obj sm.obj \ + pkcs15-starcos-esign.obj pkcs15-skeid.obj compression.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ diff --git a/src/libopensc/card-skeid.c b/src/libopensc/card-skeid.c new file mode 100644 index 0000000000..02000359ae --- /dev/null +++ b/src/libopensc/card-skeid.c @@ -0,0 +1,186 @@ +/* + * card-skeid.c: Support for (CardOS based) cards issued as identity documents in Slovakia + * + * Copyright (C) 2022 Juraj Å arinay + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * based on card-cardos.c + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "internal.h" + +#define SKEID_KNOWN_URL_LEN 46 + +static const struct sc_card_operations *iso_ops = NULL; + +static struct sc_card_operations skeid_ops; +static struct sc_card_driver skeid_drv = { + "Slovak eID card", + "skeid", + &skeid_ops, + NULL, 0, NULL +}; + +static const struct sc_atr_table skeid_atrs[] = { + /* Slovak eID v3 - CardOS 5.4 + * + * The ATR was intentionally omitted from minidriver_registration[] within win32/customactions.cpp + * as it is identical to that of CardOS v5.4 and therefore already included. + * Any new ATR may need an entry in minidriver_registration[]. */ + {"3b:d2:18:00:81:31:fe:58:c9:04:11", NULL, NULL, SC_CARD_TYPE_SKEID_V3, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; + +static int skeid_known_url(sc_card_t * card) +{ + const struct sc_aid skeid_aid_eid = {{0xE8, 0x07, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x03, 0x02}, 9}; + const char *known_url = "\x80\x01\x00\x5F\x50\x28http://www.minv.sk/cif/cif-sk-eid-v3.xml"; + u8 buf[SKEID_KNOWN_URL_LEN]; + + sc_path_t url_path; + + int r = SC_ERROR_WRONG_CARD; + + sc_path_set(&url_path, SC_PATH_TYPE_DF_NAME, skeid_aid_eid.value, skeid_aid_eid.len, 0, 0); + + if (sc_select_file(card, &url_path, NULL) == SC_SUCCESS + && sc_get_data(card, 0x7F62, buf, SKEID_KNOWN_URL_LEN) == SKEID_KNOWN_URL_LEN + && !memcmp(buf, known_url, SKEID_KNOWN_URL_LEN)) + r = SC_SUCCESS; + + return r; +} + +static int skeid_match_card(sc_card_t *card) +{ + if (_sc_match_atr(card, skeid_atrs, &card->type) < 0 || skeid_known_url(card) != SC_SUCCESS) + return 0; + + sc_log(card->ctx, "Slovak eID card v3 (CardOS 5.4)"); + + return 1; +} + +static int skeid_get_serialnr(sc_card_t *card) +{ + int r; + sc_apdu_t apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x81); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + return SC_ERROR_INTERNAL; + if (apdu.resplen == 8) { + /* cache serial number */ + memcpy(card->serialnr.value, rbuf, 8); + card->serialnr.len = 8; + } else { + sc_log(card->ctx, "unexpected response to GET DATA serial number"); + return SC_ERROR_INTERNAL; + } + return SC_SUCCESS; +} + +static int skeid_init(sc_card_t *card) +{ + const unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; + const size_t data_field_length = 437; + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + card->name = "Slovak eID (CardOS)"; + card->type = SC_CARD_TYPE_SKEID_V3; + card->cla = 0x00; + + r = skeid_get_serialnr(card); + LOG_TEST_RET(card->ctx, r, "Error reading serial number."); + + card->caps |= SC_CARD_CAP_APDU_EXT | SC_CARD_CAP_ISO7816_PIN_INFO; + + card->max_send_size = data_field_length - 6; +#ifdef _WIN32 + /* see card-cardos.c */ + if (card->reader->max_send_size == 255 && card->reader->max_recv_size == 256) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "resetting reader to use data_field_length"); + card->reader->max_send_size = data_field_length - 6; + card->reader->max_recv_size = data_field_length - 3; + } +#endif + + card->max_send_size = sc_get_max_send_size(card); /* see card-cardos.c */ + card->max_recv_size = data_field_length - 2; + card->max_recv_size = sc_get_max_recv_size(card); + + r = _sc_card_add_rsa_alg(card, 3072, flags, 0); + + LOG_FUNC_RETURN(card->ctx, r); +} + +static int skeid_set_security_env(sc_card_t *card, + const sc_security_env_t *env, + int se_num) +{ + int key_id; + int r; + + assert(card != NULL && env != NULL); + + if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { + sc_log(card->ctx, "No or invalid key reference"); + return SC_ERROR_INVALID_ARGUMENTS; + } + + /* here we follow the behaviour of the proprietary driver accompanying the card + * where security operations are preceded by MSE RESTORE rather than MSE SET + */ + key_id = env->key_ref[0]; + r = sc_restore_security_env(card, key_id); + + return r; +} + +static int skeid_logout(sc_card_t *card) +{ + int r; + sc_path_t path; + + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, NULL); + return r; + +} + +struct sc_card_driver * sc_get_skeid_driver(void) +{ + if (iso_ops == NULL) iso_ops = sc_get_iso7816_driver()->ops; + skeid_ops = *iso_ops; + skeid_ops.match_card = skeid_match_card; + skeid_ops.init = skeid_init; + skeid_ops.set_security_env = skeid_set_security_env; + skeid_ops.logout = skeid_logout; + return &skeid_drv; +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 3e3f8dd268..2c408c0711 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -270,7 +270,11 @@ enum { SC_CARD_TYPE_EDO = 38000, /* JCOP4 cards with NQ-Applet */ - SC_CARD_TYPE_NQ_APPLET = 39000 + SC_CARD_TYPE_NQ_APPLET = 39000, + + /* Slovak eID cards */ + SC_CARD_TYPE_SKEID_BASE = 40000, + SC_CARD_TYPE_SKEID_V3 }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -315,6 +319,7 @@ extern sc_card_driver_t *sc_get_esteid2018_driver(void); extern sc_card_driver_t *sc_get_idprime_driver(void); extern sc_card_driver_t *sc_get_edo_driver(void); extern sc_card_driver_t *sc_get_nqApplet_driver(void); +extern sc_card_driver_t *sc_get_skeid_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 6d4a7c5593..78d119b7de 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -98,6 +98,10 @@ struct _sc_driver_entry { }; static const struct _sc_driver_entry internal_card_drivers[] = { + /* The card handled by skeid shares the ATR with other cards running CardOS 5.4. + * In order to prevent the cardos driver from matching skeid cards, skeid driver + * precedes cardos and matches no other CardOS 5.4 card. */ + { "skeid", (void *(*)(void)) sc_get_skeid_driver }, { "cardos", (void *(*)(void)) sc_get_cardos_driver }, { "cyberflex", (void *(*)(void)) sc_get_cyberflex_driver }, { "gemsafeV1", (void *(*)(void)) sc_get_gemsafeV1_driver }, diff --git a/src/libopensc/pkcs15-skeid.c b/src/libopensc/pkcs15-skeid.c new file mode 100644 index 0000000000..54b65e6e4d --- /dev/null +++ b/src/libopensc/pkcs15-skeid.c @@ -0,0 +1,189 @@ +/* + * PKCS15 emulation layer for Slovak eID card + * + * Copyright (C) 2022 Juraj Å arinay + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * based on the PKCS15 emulation layer for EstEID card by Martin Paljak + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "common/compat_strlcpy.h" + +#include "internal.h" +#include "log.h" +#include "pkcs15.h" + +static const struct sc_aid skeid_aid_qes = {{0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, 0x08, 0x51, 0x00, 0x00, 0x11}, 13}; + +static int sc_pkcs15emu_skeid_init(sc_pkcs15_card_t * p15card) +{ + int r; + int i; + int sn_len; + char *buf; + + set_string(&p15card->tokeninfo->label, "eID karta"); + set_string(&p15card->tokeninfo->manufacturer_id, "Atos Information Technology GmbH"); + + sn_len = p15card->card->serialnr.len; + if (sn_len > 0) { + buf = malloc(2 * sn_len + 1); + if (!buf) return SC_ERROR_OUT_OF_MEMORY; + sc_bin_to_hex(p15card->card->serialnr.value, sn_len, buf, + 2 * sn_len + 1, 0); + p15card->tokeninfo->serial_number = buf; + } + + p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_READONLY; + + /* add certificates */ + const char *skeid_cert_names[3] = { + "Kvalifikovany certifikat pre elektronicky podpis", + "Certifikat pre elektronicky podpis", + "Sifrovaci certifikat" + }; + + const char *skeid_cert_paths[3] = { + "3f0001030201", + "3f0001030202", + "3f0001030203" + }; + + for (i = 0; i < 3; i++) { + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + cert_info.id.value[0] = i + 1; + cert_info.id.len = 1; + + sc_format_path(skeid_cert_paths[i], &cert_info.path); + strlcpy(cert_obj.label, skeid_cert_names[i], sizeof(cert_obj.label)); + + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + + LOG_TEST_RET(p15card->card->ctx, r, "Error adding certificate."); + } + + /* add pins */ + const char *skeid_pin_names[2] = { + "BOK", + "Podpisovy PIN" + }; + + const unsigned int skeid_pin_max_length[2] = {6, 10}; + const unsigned int skeid_pin_max_tries[2] = {5, 3}; + const int skeid_pin_ref[2] = {0x03, 0x87}; + const char *skeid_pin_paths[2] = {"3F00", "3F000101"}; + + const unsigned int skeid_pin_flags[2] = {SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA | SC_PKCS15_PIN_FLAG_INITIALIZED, + SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA | SC_PKCS15_PIN_FLAG_INITIALIZED}; + + for (i = 0; i < 2; i++) { + struct sc_pkcs15_auth_info pin_info; + struct sc_pkcs15_object pin_obj; + + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + pin_info.auth_id.len = 1; + pin_info.auth_id.value[0] = i + 1; + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + pin_info.attrs.pin.reference = skeid_pin_ref[i]; + pin_info.attrs.pin.flags = skeid_pin_flags[i]; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.attrs.pin.min_length = 6; + pin_info.attrs.pin.max_length = skeid_pin_max_length[i]; + pin_info.max_tries = skeid_pin_max_tries[i]; + + strlcpy(pin_obj.label, skeid_pin_names[i], sizeof(pin_obj.label)); + pin_obj.flags = skeid_pin_flags[i]; + + sc_format_path(skeid_pin_paths[i], &pin_info.path); + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + + LOG_TEST_RET(p15card->card->ctx, r, "Error adding PIN."); + } + + /* add private keys */ + const u8 skeid_prkey_pin[3] = {2, 1, 1}; + + /* store seIdentifier rather than keyReference */ + const int skeid_prkey_ref[3] = {0x01, 0x34, 0x44}; + const int skeid_prkey_usage[3] = + { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION | SC_PKCS15_PRKEY_USAGE_SIGN, + SC_PKCS15_PRKEY_USAGE_SIGN, + SC_PKCS15_PRKEY_USAGE_DECRYPT + }; + + const char *skeid_prkey_paths[3] = {"3F000101", "3F000102", "3F000102"}; + + const char *skeid_prkey_name[3] = { + "Podpisovy kluc (KEP)", + "Podpisovy kluc", + "Sifrovaci kluc", + }; + + for (i = 0; i < 3; i++) { + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + prkey_info.id.len = 1; + prkey_info.id.value[0] = i + 1; + prkey_info.native = 1; + prkey_info.key_reference = skeid_prkey_ref[i]; + prkey_info.modulus_length = 3072; + sc_format_path(skeid_prkey_paths[i], &prkey_info.path); + + prkey_info.usage = skeid_prkey_usage[i]; + + strlcpy(prkey_obj.label, skeid_prkey_name[i], sizeof(prkey_obj.label)); + prkey_obj.auth_id.len = 1; + prkey_obj.auth_id.value[0] = skeid_prkey_pin[i]; + if (i == 0) prkey_obj.user_consent = 1; + + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + + LOG_TEST_RET(p15card->card->ctx, r, "Error adding private key."); + } + LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS); +} + +int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid) +{ + int r = SC_ERROR_WRONG_CARD; + + if (p15card->card->type == SC_CARD_TYPE_SKEID_V3 + && (aid == NULL || (aid->len == skeid_aid_qes.len && !memcmp(aid->value, &skeid_aid_qes.value, skeid_aid_qes.len)))) + r = sc_pkcs15emu_skeid_init(p15card); + + return r; +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index c4e99b97e4..719525bbc0 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -56,6 +56,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "coolkey", sc_pkcs15emu_coolkey_init_ex }, { "din66291", sc_pkcs15emu_din_66291_init_ex }, { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, + { "skeid", sc_pkcs15emu_skeid_init_ex }, { "cardos", sc_pkcs15emu_cardos_init_ex }, { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, { "esign", sc_pkcs15emu_starcos_esign_init_ex }, @@ -109,6 +110,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_NQ_APPLET: case SC_CARD_TYPE_STARCOS_V3_4_ESIGN: case SC_CARD_TYPE_STARCOS_V3_5_ESIGN: + case SC_CARD_TYPE_SKEID_V3: return 1; default: diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index af7257ae9e..a853320af4 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -57,6 +57,7 @@ int sc_pkcs15emu_idprime_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_cardos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From dd138d0600a1acd7991989127f36827e5836b24e Mon Sep 17 00:00:00 2001 From: "Ingo Struck (git commits)" Date: Thu, 16 Mar 2023 22:12:49 +0100 Subject: [PATCH 2804/4321] Fixed loop in sc_hsm_write_ef, handle offset into buf and into EF separately --- src/libopensc/card-sc-hsm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 1b707f08df..c100a87c2a 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -782,7 +782,7 @@ static int sc_hsm_logout(sc_card_t * card) } - +/* NOTE: idx is an offset into the card's file, not into buf */ static int sc_hsm_read_binary(sc_card_t *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags) @@ -823,7 +823,7 @@ static int sc_hsm_read_binary(sc_card_t *card, } - +/* NOTE: idx is an offset into the card's file, not into buf */ static int sc_hsm_write_ef(sc_card_t *card, int fid, unsigned int idx, const u8 *buf, size_t count) @@ -848,7 +848,8 @@ static int sc_hsm_write_ef(sc_card_t *card, // 8 bytes are required for T54(4) and T53(4) size_t blk_size = card->max_send_size - 8; size_t to_send = 0; - size_t offset = (size_t) idx; + size_t file_offset = (size_t) idx; + size_t offset = 0; do { len = 0; to_send = bytes_left >= blk_size ? blk_size : bytes_left; @@ -856,8 +857,8 @@ static int sc_hsm_write_ef(sc_card_t *card, // ASN1 0x54 offset *p++ = 0x54; *p++ = 0x02; - *p++ = (offset >> 8) & 0xFF; - *p++ = offset & 0xFF; + *p++ = (file_offset >> 8) & 0xFF; + *p++ = file_offset & 0xFF; // ASN1 0x53 to_send *p++ = 0x53; if (to_send < 128) { @@ -890,6 +891,7 @@ static int sc_hsm_write_ef(sc_card_t *card, bytes_left -= to_send; offset += to_send; + file_offset += to_send; } while (0 < bytes_left); err: From 12a9122aada77f5dc11bed8b9ac76ca954ea2704 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 8 Mar 2023 10:56:32 +0100 Subject: [PATCH 2805/4321] use proper define for PSS salt length auto detection --- src/pkcs11/openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index f62c32fa3f..6fe3fa5445 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -899,7 +899,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len /* https://github.com/openssl/openssl/blob/master/crypto/rsa/rsa_pss.c */ /* there is no way to pass negative value here, we using maximal value for this */ if (((CK_ULONG) 1 ) << (sizeof(CK_ULONG) * CHAR_BIT -1) == param->sLen) - sLen = -2; + sLen = RSA_PSS_SALTLEN_AUTO; else sLen = param->sLen; From 63f67576dd44905c8af243ecdf9186f0d2cede91 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 8 Mar 2023 11:00:14 +0100 Subject: [PATCH 2806/4321] fixed implicit conversion loses integer precision - use pkcs#11 types in sc_pkcs11_verify_data - this reduces the number of type conversions needed - this fixes a possible data corruption when gost is used with a very long public key --- src/pkcs11/mechanism.c | 10 +++++----- src/pkcs11/openssl.c | 36 ++++++++++++++++++++---------------- src/pkcs11/sc-pkcs11.h | 10 +++++----- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index e563bb0859..9350343934 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -39,7 +39,7 @@ struct operation_data { struct hash_signature_info *info; sc_pkcs11_operation_t *md; CK_BYTE *buffer; - unsigned int buffer_len; + CK_ULONG buffer_len; }; static struct operation_data * @@ -67,7 +67,7 @@ signature_data_buffer_append(struct operation_data *data, if (in_len == 0) return CKR_OK; - unsigned int new_len = data->buffer_len + in_len; + CK_ULONG new_len = data->buffer_len + in_len; CK_BYTE *new_buffer = sc_mem_secure_alloc(new_len); if (!new_buffer) return CKR_HOST_MEMORY; @@ -193,7 +193,7 @@ _validate_key_type(sc_pkcs11_mechanism_type_t *mech, CK_KEY_TYPE key_type) { * Look up a mechanism */ sc_pkcs11_mechanism_type_t * -sc_pkcs11_find_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, unsigned int flags) +sc_pkcs11_find_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, CK_FLAGS flags) { sc_pkcs11_mechanism_type_t *mt; unsigned int n; @@ -881,10 +881,10 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, goto done; } - rv = sc_pkcs11_verify_data(pubkey_value, (unsigned int) attr.ulValueLen, + rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, params, sizeof(params), &operation->mechanism, data->md, - data->buffer, data->buffer_len, pSignature, (unsigned int) ulSignatureLen); + data->buffer, data->buffer_len, pSignature, ulSignatureLen); done: free(pubkey_value); diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 6fe3fa5445..736423537c 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -442,10 +442,10 @@ static void reverse(unsigned char *buf, size_t len) } } -static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, - const unsigned char *params, unsigned int params_len, - unsigned char *data, unsigned int data_len, - unsigned char *signat, unsigned int signat_len) +static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, + const CK_BYTE_PTR params, CK_ULONG params_len, + CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR signat, CK_ULONG signat_len) { EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx = NULL; @@ -499,8 +499,10 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub } #endif r = -1; - if (group) - octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey, (long)pubkey_len); + if (group && pubkey_len <= LONG_MAX) { + const unsigned char *p = pubkey; + octet = d2i_ASN1_OCTET_STRING(NULL, &p, (long)pubkey_len); + } if (group && octet) { reverse(octet->data, octet->length); Y = BN_bin2bn(octet->data, octet->length / 2, NULL); @@ -573,11 +575,11 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, unsigned int pub * If a hash function was used, we can make a big shortcut by * finishing with EVP_VerifyFinal(). */ -CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, - const unsigned char *pubkey_params, unsigned int pubkey_params_len, +CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, + const CK_BYTE_PTR pubkey_params, CK_ULONG pubkey_params_len, CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *data, unsigned int data_len, - unsigned char *signat, unsigned int signat_len) + CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR signat, CK_ULONG signat_len) { int res; CK_RV rv = CKR_GENERAL_ERROR; @@ -636,15 +638,17 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len int r; r = sc_asn1_sig_value_rs_to_sequence(NULL, signat, signat_len, &signat_tmp, &signat_len_tmp); - if (r == 0) { - res = EVP_VerifyFinal(md_ctx, signat_tmp, signat_len_tmp, pkey); + if (r == 0 && signat_len_tmp < UINT_MAX) { + res = EVP_VerifyFinal(md_ctx, signat_tmp, (unsigned int) signat_len_tmp, pkey); } else { - sc_log(context, "sc_asn1_sig_value_rs_to_sequence failed r:%d",r); + sc_log(context, "sc_asn1_sig_value_rs_to_sequence failed r:%d " + "or output too long signat_len_tmp:%"SC_FORMAT_LEN_SIZE_T"u", + r, signat_len_tmp); res = -1; } free(signat_tmp); } else - res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); + res = EVP_VerifyFinal(md_ctx, signat, (unsigned int) signat_len, pkey); } else { res = -1; } @@ -898,10 +902,10 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len /* special mode - autodetect sLen from signature */ /* https://github.com/openssl/openssl/blob/master/crypto/rsa/rsa_pss.c */ /* there is no way to pass negative value here, we using maximal value for this */ - if (((CK_ULONG) 1 ) << (sizeof(CK_ULONG) * CHAR_BIT -1) == param->sLen) + if (((CK_ULONG) 1 ) << (sizeof(CK_ULONG) * CHAR_BIT -1) == param->sLen || param->sLen > INT_MAX) sLen = RSA_PSS_SALTLEN_AUTO; else - sLen = param->sLen; + sLen = (int) param->sLen; if ((ctx = sc_evp_pkey_ctx_new(context, pkey)) == NULL || EVP_PKEY_verify_init(ctx) != 1 || diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 0b42358e46..bc7baa7e74 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -489,7 +489,7 @@ CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_KEY_TYPE, CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *); sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *, - CK_MECHANISM_TYPE, unsigned int); + CK_MECHANISM_TYPE, CK_FLAGS); sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR, CK_KEY_TYPE, const void *, void (*)(const void *), CK_RV (*)(const void *, void **)); @@ -506,11 +506,11 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *, sc_pkcs11_mechanism_type_t *); #ifdef ENABLE_OPENSSL -CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len, - const unsigned char *pubkey_params, unsigned int pubkey_params_len, +CK_RV sc_pkcs11_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len, + const CK_BYTE_PTR pubkey_params, CK_ULONG pubkey_params_len, CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *inp, unsigned int inp_len, - unsigned char *signat, unsigned int signat_len); + CK_BYTE_PTR inp, CK_ULONG inp_len, + CK_BYTE_PTR signat, CK_ULONG signat_len); #endif /* Load configuration defaults */ From d4a42acc4d79f26f351686d26845939ffa331a0f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 17 Mar 2023 11:24:13 +0100 Subject: [PATCH 2807/4321] added wrappers for checked arithmetic builtins of clang/gcc --- configure.ac | 15 ++++++++++ src/common/Makefile.am | 4 ++- src/common/Makefile.mak | 2 +- src/common/compat_overflow.c | 44 +++++++++++++++++++++++++++++ src/common/compat_overflow.h | 55 ++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/common/compat_overflow.c create mode 100644 src/common/compat_overflow.h diff --git a/configure.ac b/configure.ac index 9c29530b04..35688b4d16 100644 --- a/configure.ac +++ b/configure.ac @@ -431,6 +431,21 @@ AC_CHECK_FUNCS([ \ strnlen sigaction ]) +# +# Check for __builtin_uadd_overflow +# +AC_MSG_CHECKING([compiler support for __builtin_*_overflow()]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[return (__builtin_uadd_overflow(UINT_MAX, UINT_MAX, &(unsigned int){ 0 }));]] + )], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_BUILTIN_OVERFLOW], [1], [define if the compiler supports __builtin_*_overflow().]) + ], + [AC_MSG_RESULT([no]) + ]) + # Do not check for strlcpy and strlcat in Linux because it is not implemented # and autotools can not detect it in AC_CHECK_DECLS because build does not fail # in this test. diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 8171edd2fa..2f3b0fd301 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -8,7 +8,7 @@ dist_noinst_DATA = \ LICENSE.compat_getopt compat_getopt.txt \ compat_getopt_main.c \ README.compat_strlcpy compat_strlcpy.3 -noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h +noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h compat_overflow.h AM_CPPFLAGS = -I$(top_srcdir)/src @@ -21,6 +21,7 @@ libcompat_la_SOURCES = \ compat_getopt.c \ compat_report_rangecheckfailure.c \ compat___iob_func.c \ + compat_overflow.c \ simclist.c compat_getopt_main_LDADD = libcompat.la @@ -40,6 +41,7 @@ TIDY_FILES = \ compat_getopt.h compat_getopt.c \ compat_report_rangecheckfailure.c \ compat___iob_func.c \ + compat_overflow.h compat_overflow.c \ simclist.c simclist.h \ libpkcs11.c libscdl.c diff --git a/src/common/Makefile.mak b/src/common/Makefile.mak index a777eea291..d4f00df820 100644 --- a/src/common/Makefile.mak +++ b/src/common/Makefile.mak @@ -1,6 +1,6 @@ TOPDIR = ..\.. -COMMON_OBJECTS = compat_getpass.obj compat_getopt.obj compat_strlcpy.obj compat_strlcat.obj simclist.obj compat_report_rangecheckfailure.obj compat___iob_func.obj +COMMON_OBJECTS = compat_getpass.obj compat_getopt.obj compat_strlcpy.obj compat_strlcat.obj simclist.obj compat_report_rangecheckfailure.obj compat___iob_func.obj compat_overflow.obj all: common.lib libpkcs11.lib libscdl.lib diff --git a/src/common/compat_overflow.c b/src/common/compat_overflow.c new file mode 100644 index 0000000000..cb402bfc5a --- /dev/null +++ b/src/common/compat_overflow.c @@ -0,0 +1,44 @@ +/* + * compat_overflow.h: Reimplementation of GCC/Clang's built-in + * functions to perform arithmetic with overflow checking + * + * Copyright (C) Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_BUILTIN_OVERFLOW +#include +#include +#include + +#define ADD_OVERFLOW(func, type, max) \ + bool func (type x, type y, type *sum) \ + { \ + if (NULL == sum || max - x < y) \ + return true; \ + *sum = x + y; \ + return false; \ + } + +ADD_OVERFLOW(__builtin_uadd_overflow, unsigned, UINT_MAX) +ADD_OVERFLOW(__builtin_uaddl_overflow, unsigned long, ULONG_MAX) +ADD_OVERFLOW(__builtin_uaddll_overflow, unsigned long long, ULLONG_MAX) +#endif diff --git a/src/common/compat_overflow.h b/src/common/compat_overflow.h new file mode 100644 index 0000000000..49bb52c240 --- /dev/null +++ b/src/common/compat_overflow.h @@ -0,0 +1,55 @@ +/* + * compat_overflow.h: Reimplementation of GCC/Clang's built-in + * functions to perform arithmetic with overflow checking + * + * Copyright (C) Frank Morgner + * + * This file is part of OpenSC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __COMPAT_OVERFLOW_H +#define __COMPAT_OVERFLOW_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_BUILTIN_OVERFLOW +#include + +bool __builtin_uadd_overflow (unsigned x, unsigned y, unsigned *sum); +bool __builtin_uaddl_overflow (unsigned long x, unsigned long y, unsigned long *sum); +bool __builtin_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *sum); +#endif +/* TODO +bool __builtin_usub_overflow (unsigned x, unsigned y, unsigned *diff); +bool __builtin_usubl_overflow (unsigned long x, unsigned long y, unsigned long *diff); +bool __builtin_usubll_overflow(unsigned long long x, unsigned long long y, unsigned long long *diff); +bool __builtin_umul_overflow (unsigned x, unsigned y, unsigned *prod); +bool __builtin_umull_overflow (unsigned long x, unsigned long y, unsigned long *prod); +bool __builtin_umulll_overflow(unsigned long long x, unsigned long long y, unsigned long long *prod); +bool __builtin_sadd_overflow (int x, int y, int *sum); +bool __builtin_saddl_overflow (long x, long y, long *sum); +bool __builtin_saddll_overflow(long long x, long long y, long long *sum); +bool __builtin_ssub_overflow (int x, int y, int *diff); +bool __builtin_ssubl_overflow (long x, long y, long *diff); +bool __builtin_ssubll_overflow(long long x, long long y, long long *diff); +bool __builtin_smul_overflow (int x, int y, int *prod); +bool __builtin_smull_overflow (long x, long y, long *prod); +bool __builtin_smulll_overflow(long long x, long long y, long long *prod); +*/ + +#endif From f947652b3fa806c9964ca9a3db644c7cf64a7f4a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 17 Mar 2023 11:29:42 +0100 Subject: [PATCH 2808/4321] fixed possible integer overflow --- src/pkcs11/mechanism.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 9350343934..ca1936006e 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -24,6 +24,7 @@ #include #include "sc-pkcs11.h" +#include "common/compat_overflow.h" /* Also used for verification data */ struct hash_signature_info { @@ -67,7 +68,9 @@ signature_data_buffer_append(struct operation_data *data, if (in_len == 0) return CKR_OK; - CK_ULONG new_len = data->buffer_len + in_len; + CK_ULONG new_len; + if (__builtin_uaddl_overflow(data->buffer_len, in_len, &new_len)) + return CKR_ARGUMENTS_BAD; CK_BYTE *new_buffer = sc_mem_secure_alloc(new_len); if (!new_buffer) return CKR_HOST_MEMORY; From c17b432d9814d7a32526b35ae7107cead60c2425 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 17 Mar 2023 22:39:15 +0100 Subject: [PATCH 2809/4321] fixed setting CKP_PUBLIC_CERTIFICATES_TOKEN Due to a bug in checking the object bitmask, a *private* data object would be considered to be a private certificate and the CKP_PUBLIC_CERTIFICATES_TOKEN would not be set to this slot. --- src/pkcs11/framework-pkcs15.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 996cbdf0e9..33fdac4308 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1538,8 +1538,8 @@ _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data) if (obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) { /* If we found some non-accessible public object, * we can no longer claim Public Ceritificate Token conformance */ - if (obj->p15_object->type & SC_PKCS15_TYPE_PUBKEY || - obj->p15_object->type & SC_PKCS15_TYPE_CERT) { + if ((obj->p15_object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PUBKEY || + (obj->p15_object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT) { public_certificates = 0; } continue; From a7b3ea3e70ee197f9c0f8aa57e56308b1e9b5fa3 Mon Sep 17 00:00:00 2001 From: Normann Cunz Date: Thu, 10 Feb 2022 16:47:30 +0100 Subject: [PATCH 2810/4321] Fixes #2504 for record based files with index option as record number. --- src/libopensc/pkcs15.c | 105 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 097e390633..fd690c140f 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2392,6 +2392,28 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p } +int +sc_decode_do53(sc_context_t *ctx, u8 **data, size_t *data_len, + const u8 *buf, size_t buflen) +{ + struct sc_asn1_entry c_asn1_do53[] = { + { "do53", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x13, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } + }; + struct sc_asn1_entry asn1_do53[2]; + int r; + + LOG_FUNC_CALLED(ctx); + sc_copy_asn1_entry(c_asn1_do53, asn1_do53); + sc_format_asn1_entry(asn1_do53, data, data_len, 0); + + r = sc_asn1_decode(ctx, asn1_do53, buf, buflen, NULL, NULL); + LOG_TEST_RET(ctx, r, "ASN.1 parsing of do-53 failed"); + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + + int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_path, unsigned char **buf, size_t *buflen, int private_data) @@ -2434,22 +2456,41 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat /* Handle the case where the ASN.1 Path object specified * index and length values */ - if (in_path->count < 0) { - if (file->size) - len = file->size; - else - len = 1024; - offset = 0; - } - else { - offset = in_path->index; - len = in_path->count; - /* Make sure we're within proper bounds */ - if (offset >= file->size || offset + len > file->size) { + + if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + + // in_path->index = record_no, in_path->count ignored! + if(file->record_length > 0) { + len = file->record_length + 5; + } else { + len = 0x2000 + 5; + } + + if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) { r = SC_ERROR_INVALID_ASN1_OBJECT; goto fail_unlock; } + + } else { + + if (in_path->count < 0) { + if (file->size) + len = file->size; + else + len = 1024; + offset = 0; + } + else { + offset = in_path->index; + len = in_path->count; + /* Make sure we're within proper bounds */ + if (offset >= file->size || offset + len > file->size) { + r = SC_ERROR_INVALID_ASN1_OBJECT; + goto fail_unlock; + } + } } + data = malloc(len); if (data == NULL) { r = SC_ERROR_OUT_OF_MEMORY; @@ -2488,6 +2529,46 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat } len = head-data; } + else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + + u8 offset_buffer[] = {0x54, 0x02, 0x00, 0x00}; + struct sc_apdu apdu; + uint16_t offset_u16 = 0; + u8 *data_do; + size_t data_do_len; + + do { + + offset_buffer[2] = (u8) (offset_u16 >> 8); + offset_buffer[3] = (u8) (offset_u16 & 0x00ff); + + sc_format_apdu(p15card->card, &apdu, SC_APDU_CASE_4_SHORT, 0xB3, in_path->index, 4); + + apdu.data = offset_buffer; + apdu.datalen = 4; + apdu.lc = 4; + apdu.le = 0; + + apdu.resp = data + offset_u16; + apdu.resplen = len - offset_u16; + + r = sc_transmit_apdu(p15card->card, &apdu); + if(r < 0 || apdu.resplen == 0) break; + + data_do = NULL; + r = sc_decode_do53(ctx, &data_do, &data_do_len, apdu.resp, apdu.resplen); + if (r < 0) goto fail_unlock; + + if(data_do) { + memcpy(data + offset_u16, data_do, data_do_len); + offset_u16 += data_do_len; + free(data_do); + } + + } while(r == SC_SUCCESS); + + len = offset_u16; + } else { r = sc_read_binary(p15card->card, offset, data, len, 0); if (r < 0) { From 49887a0e6a6dcf119b7db26114aa18a505cb69b9 Mon Sep 17 00:00:00 2001 From: Normann Cunz Date: Tue, 15 Feb 2022 10:48:16 +0100 Subject: [PATCH 2811/4321] Fixes #2505. Decode FCI tag as negative file size. --- src/libopensc/iso7816.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index b1e27c8dd1..4ae74ced8b 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -329,7 +329,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *p, *end; unsigned int cla = 0, tag = 0; size_t length; - int size; + uint32_t size; file->status = SC_FILE_STATUS_UNKNOWN; @@ -350,11 +350,17 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, /* fall through */ case 0x80: /* determine the file size */ - if (sc_asn1_decode_integer(p, length, &size, 0) == 0 && size >= 0) { + file->size = 0; + if(p && length < 5) { + size = 0; + for(size_t i=0; isize = size; - sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", - file->size); } + + sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); break; case 0x82: From 0d214c423ef093f9374c1ed677c4c835ab8435dc Mon Sep 17 00:00:00 2001 From: Normann Cunz Date: Fri, 18 Feb 2022 10:28:06 +0100 Subject: [PATCH 2812/4321] Limit file size in iso7816_process_fci() to MAX_FILE_SIZE ... due to failed fuzzing. Also limit record and file size in sc_pkcs15_read_file(). Change result code for record out of bounds. --- src/libopensc/iso7816.c | 2 +- src/libopensc/pkcs15.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 4ae74ced8b..27151620f8 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -357,7 +357,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, size <<= 8; size |= (uint32_t) p[i]; } - file->size = size; + file->size = (size > MAX_FILE_SIZE)? MAX_FILE_SIZE:size; } sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index fd690c140f..499933ad40 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2459,15 +2459,17 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { - // in_path->index = record_no, in_path->count ignored! + // in_path->index: record_no + // in_path->count: ignored! + if(file->record_length > 0) { - len = file->record_length + 5; + len = (file->record_length > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->record_length + 5; } else { len = 0x2000 + 5; } if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) { - r = SC_ERROR_INVALID_ASN1_OBJECT; + r = SC_ERROR_RECORD_NOT_FOUND; goto fail_unlock; } @@ -2475,7 +2477,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat if (in_path->count < 0) { if (file->size) - len = file->size; + len = (file->size > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->size; else len = 1024; offset = 0; From 3843ffd2bdca264a32f1fa1418f8b5493fcd81d8 Mon Sep 17 00:00:00 2001 From: Normann Cunz Date: Sun, 3 Apr 2022 19:43:10 +0200 Subject: [PATCH 2813/4321] Remarks considered. Refers to #2504 and #2505 --- src/libopensc/iso7816.c | 16 ++++++++++------ src/libopensc/pkcs15.c | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 27151620f8..0ffb81313e 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -329,7 +329,6 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *p, *end; unsigned int cla = 0, tag = 0; size_t length; - uint32_t size; file->status = SC_FILE_STATUS_UNKNOWN; @@ -351,13 +350,18 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, case 0x80: /* determine the file size */ file->size = 0; - if(p && length < 5) { - size = 0; - for(size_t i=0; i MAX_FILE_SIZE) { + file->size = MAX_FILE_SIZE; + sc_log(ctx, " file size truncated, encoded length: %"SC_FORMAT_LEN_SIZE_T"u", size); + } else { + file->size = size; } - file->size = (size > MAX_FILE_SIZE)? MAX_FILE_SIZE:size; } sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 499933ad40..e9f875b1e3 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2463,12 +2463,18 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat // in_path->count: ignored! if(file->record_length > 0) { - len = (file->record_length > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->record_length + 5; + if(file->record_length > MAX_FILE_SIZE) { + len = MAX_FILE_SIZE; + sc_log(ctx, " record size truncated, encoded length: %"SC_FORMAT_LEN_SIZE_T"u", file->record_length); + } else { + len = file->record_length; + } } else { - len = 0x2000 + 5; + len = MAX_FILE_SIZE; } if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) { + sc_log(ctx, " record number out of bounds: %d", in_path->index); r = SC_ERROR_RECORD_NOT_FOUND; goto fail_unlock; } @@ -2534,6 +2540,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { u8 offset_buffer[] = {0x54, 0x02, 0x00, 0x00}; + u8 response_buffer[SC_MAX_APDU_RESP_SIZE]; struct sc_apdu apdu; uint16_t offset_u16 = 0; u8 *data_do; @@ -2547,15 +2554,16 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat sc_format_apdu(p15card->card, &apdu, SC_APDU_CASE_4_SHORT, 0xB3, in_path->index, 4); apdu.data = offset_buffer; - apdu.datalen = 4; - apdu.lc = 4; + apdu.datalen = sizeof(offset_buffer); + apdu.lc = sizeof(offset_buffer); apdu.le = 0; - apdu.resp = data + offset_u16; - apdu.resplen = len - offset_u16; + apdu.resp = response_buffer; + apdu.resplen = sizeof(response_buffer); r = sc_transmit_apdu(p15card->card, &apdu); - if(r < 0 || apdu.resplen == 0) break; + if (r < 0 || apdu.resplen == 0) + break; data_do = NULL; r = sc_decode_do53(ctx, &data_do, &data_do_len, apdu.resp, apdu.resplen); From 440376bfecad30ada077425139ac615bfd35272a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 12 Sep 2022 11:40:25 +0200 Subject: [PATCH 2814/4321] added idx parameter to sc_[read|update]_record --- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-mcrd.c | 6 +++--- src/libopensc/card-oberthur.c | 4 ++-- src/libopensc/card-starcos.c | 4 ++-- src/libopensc/card.c | 12 ++++++------ src/libopensc/dir.c | 6 +++--- src/libopensc/iso7816.c | 11 +++++++---- src/libopensc/opensc.h | 14 ++++++++------ src/libopensc/pkcs15-esteid.c | 4 ++-- src/libopensc/pkcs15-gemsafeGPK.c | 4 ++-- src/libopensc/pkcs15-oberthur.c | 2 +- src/libopensc/pkcs15-tcos.c | 4 ++-- src/libopensc/pkcs15.c | 2 +- src/pkcs15init/pkcs15-cardos.c | 2 +- src/pkcs15init/pkcs15-gpk.c | 10 +++++----- src/pkcs15init/pkcs15-incrypto34.c | 2 +- src/pkcs15init/pkcs15-oberthur-awp.c | 10 +++++----- src/tools/eidenv.c | 4 ++-- src/tools/opensc-explorer.c | 10 +++++----- src/tools/opensc-tool.c | 2 +- 20 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 2e5673359f..2bdaf474a2 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -1095,7 +1095,7 @@ gpk_set_security_env(sc_card_t *card, LOG_TEST_RET(card->ctx, r, "Failed to select PK file"); /* Read the sys record of the PK file to find out the key length */ - r = sc_read_record(card, 1, sysrec, sizeof(sysrec), + r = sc_read_record(card, 1, 0, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); LOG_TEST_RET(card->ctx, r, "Failed to read PK sysrec"); if (r != 7 || sysrec[0] != 0) { diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index fb5d02f89a..d54a98cb3d 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -314,7 +314,7 @@ static int load_special_files(sc_card_t * card) for (recno = 1;; recno++) { u8 recbuf[256]; - r = sc_read_record(card, recno, recbuf, sizeof(recbuf), + r = sc_read_record(card, recno, 0, recbuf, sizeof(recbuf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) @@ -345,7 +345,7 @@ static int load_special_files(sc_card_t * card) for (recno = 1;; recno++) { u8 recbuf[256]; - r = sc_read_record(card, recno, recbuf, sizeof(recbuf), + r = sc_read_record(card, recno, 0, recbuf, sizeof(recbuf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) @@ -1155,7 +1155,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, return SC_ERROR_INTERNAL; /* read the number of tries left for the PIN */ - r = sc_read_record (card, ref_to_record[data->pin_reference], buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record (card, ref_to_record[data->pin_reference], 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r < 0) return SC_ERROR_INTERNAL; if (buf[0] != 0x80 || buf[3] != 0x90) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 5455b5aea7..cf39fec5f9 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2201,7 +2201,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, static int -auth_read_record(struct sc_card *card, unsigned int nr_rec, +auth_read_record(struct sc_card *card, unsigned int nr_rec, unsigned int idx, unsigned char *buf, size_t count, unsigned long flags) { struct sc_apdu apdu; @@ -2212,7 +2212,7 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec, "auth_read_record(): nr_rec %i; count %"SC_FORMAT_LEN_SIZE_T"u", nr_rec, count); - if (nr_rec > 0xFF) + if (nr_rec > 0xFF || idx != 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, nr_rec, 0); diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index b350374020..a51c4b1e0d 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -199,7 +199,7 @@ static int starcos_determine_pin_format34(sc_card_t *card, unsigned int * pin_fo rv = sc_select_file(card, &path, &file); LOG_TEST_RET(ctx, rv, "Cannot select EF.PWDD file"); - if ( (rv = sc_read_record(card, rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0 ) { + if ( (rv = sc_read_record(card, rec_no, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0 ) { starcos_ctrl_ref_template ctrl_ref_template; memset((void*)&ctrl_ref_template, 0, sizeof(ctrl_ref_template)); rv = starcos_parse_supported_sec_mechanisms(card, buf, rv, &ctrl_ref_template); @@ -236,7 +236,7 @@ static int starcos_determine_pin_format35(sc_card_t *card, unsigned int * pin_fo rv = sc_select_file(card, &path, &file); LOG_TEST_RET(ctx, rv, "Cannot select EF.KEYD file"); - while ( (rv = sc_read_record(card, rec_no++, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0 ) { + while ( (rv = sc_read_record(card, rec_no++, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0 ) { if ( buf[0] != TAG_STARCOS35_PIN_REFERENCE ) continue; memset((void*)&ctrl_ref_template, 0, sizeof(ctrl_ref_template)); diff --git a/src/libopensc/card.c b/src/libopensc/card.c index ac21d2b56b..6f42ca6c4f 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -950,8 +950,8 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } -int sc_read_record(sc_card_t *card, unsigned int rec_nr, u8 *buf, - size_t count, unsigned long flags) +int sc_read_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, + u8 *buf ,size_t count, unsigned long flags) { int r; @@ -963,7 +963,7 @@ int sc_read_record(sc_card_t *card, unsigned int rec_nr, u8 *buf, if (card->ops->read_record == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->read_record(card, rec_nr, buf, count, flags); + r = card->ops->read_record(card, rec_nr, idx, buf, count, flags); if (r == SC_SUCCESS) { r = count; } @@ -1013,8 +1013,8 @@ int sc_append_record(sc_card_t *card, const u8 * buf, size_t count, LOG_FUNC_RETURN(card->ctx, r); } -int sc_update_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf, - size_t count, unsigned long flags) +int sc_update_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, + const u8 * buf, size_t count, unsigned long flags) { int r; @@ -1026,7 +1026,7 @@ int sc_update_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf, if (card->ops->update_record == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->update_record(card, rec_nr, buf, count, flags); + r = card->ops->update_record(card, rec_nr, idx, buf, count, flags); if (r == SC_SUCCESS) { r = count; } diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 6863ff57fe..da3355f519 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -227,7 +227,7 @@ int sc_enum_apps(sc_card_t *card) /* Arbitrary set '16' as maximal number of records to check out: * to avoid endless loop because of some incomplete cards/drivers */ for (rec_nr = 1; rec_nr < 16; rec_nr++) { - r = sc_read_record(card, rec_nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, rec_nr, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; LOG_TEST_RET(ctx, r, "read_record() failed"); @@ -361,7 +361,7 @@ static int update_single_record(sc_card_t *card, sc_app_info_t *app) if (r) return r; if (app->rec_nr > 0) - r = sc_update_record(card, (unsigned int)app->rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR); + r = sc_update_record(card, (unsigned int)app->rec_nr, 0, rec, rec_size, SC_RECORD_BY_REC_NR); else if (app->rec_nr == 0) { /* create new record entry */ r = sc_append_record(card, rec, rec_size, 0); @@ -375,7 +375,7 @@ static int update_single_record(sc_card_t *card, sc_app_info_t *app) if (card->app[i]->rec_nr > rec_nr) rec_nr = card->app[i]->rec_nr; rec_nr++; - r = sc_update_record(card, (unsigned int)rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR); + r = sc_update_record(card, (unsigned int)rec_nr, 0, rec, rec_size, SC_RECORD_BY_REC_NR); } } else { sc_log(card->ctx, "invalid record number\n"); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 0ffb81313e..cff66b02d9 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -166,13 +166,13 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun static int -iso7816_read_record(struct sc_card *card, - unsigned int rec_nr, u8 *buf, size_t count, unsigned long flags) +iso7816_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, + u8 *buf, size_t count, unsigned long flags) { struct sc_apdu apdu; int r; - if (rec_nr > 0xFF) + if (rec_nr > 0xFF || idx != 0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0); @@ -242,12 +242,15 @@ iso7816_append_record(struct sc_card *card, static int -iso7816_update_record(struct sc_card *card, unsigned int rec_nr, +iso7816_update_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { struct sc_apdu apdu; int r; + if (rec_nr > 0xFF || idx != 0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDC, rec_nr, 0); apdu.lc = count; apdu.datalen = count; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 958edcb98d..2c5e77d67a 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -706,13 +706,13 @@ struct sc_card_operations { int (*erase_binary)(struct sc_card *card, unsigned int idx, size_t count, unsigned long flags); - int (*read_record)(struct sc_card *card, unsigned int rec_nr, + int (*read_record)(struct sc_card *card, unsigned int rec_nr, unsigned int idx, u8 * buf, size_t count, unsigned long flags); int (*write_record)(struct sc_card *card, unsigned int rec_nr, const u8 * buf, size_t count, unsigned long flags); int (*append_record)(struct sc_card *card, const u8 * buf, size_t count, unsigned long flags); - int (*update_record)(struct sc_card *card, unsigned int rec_nr, + int (*update_record)(struct sc_card *card, unsigned int rec_nr, unsigned int idx, const u8 * buf, size_t count, unsigned long flags); /* select_file: Does the equivalent of SELECT FILE command specified @@ -1304,13 +1304,14 @@ int sc_erase_binary(struct sc_card *card, unsigned int idx, * Reads a record from the current (i.e. selected) file. * @param card struct sc_card object on which to issue the command * @param rec_nr SC_READ_RECORD_CURRENT or a record number starting from 1 + * @param idx index within the record with the data to read * @param buf Pointer to a buffer for storing the data * @param count Number of bytes to read * @param flags flags (may contain a short file id of a file to select) * @retval number of bytes read or an error value */ -int sc_read_record(struct sc_card *card, unsigned int rec_nr, u8 * buf, - size_t count, unsigned long flags); +int sc_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, + u8 * buf, size_t count, unsigned long flags); /** * Writes data to a record from the current (i.e. selected) file. * @param card struct sc_card object on which to issue the command @@ -1336,13 +1337,14 @@ int sc_append_record(struct sc_card *card, const u8 * buf, size_t count, * Updates the data of a record from the current (i.e. selected) file. * @param card struct sc_card object on which to issue the command * @param rec_nr SC_READ_RECORD_CURRENT or a record number starting from 1 + * @param idx index within the record with the data to read * @param buf buffer with to the new data to be written * @param count number of bytes to update * @param flags flags (may contain a short file id of a file to select) * @retval number of bytes written or an error value */ -int sc_update_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf, - size_t count, unsigned long flags); +int sc_update_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, + const u8 * buf, size_t count, unsigned long flags); int sc_delete_record(struct sc_card *card, unsigned int rec_nr); /* get/put data functions */ diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 74c1c71699..c7b6586821 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -54,7 +54,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) LOG_TEST_GOTO_ERR(card->ctx, r, "select esteid PD failed"); /* read the serial (document number) */ - r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); + r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, 0, buff, sizeof(buff), SC_RECORD_BY_REC_NR); LOG_TEST_GOTO_ERR(card->ctx, r, "read document number failed"); buff[MIN((size_t) r, (sizeof buff)-1)] = '\0'; set_string(&p15card->tokeninfo->serial_number, (const char *)buff); @@ -136,7 +136,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) memset(&pin_obj, 0, sizeof(pin_obj)); /* read the number of tries left for the PIN */ - r = sc_read_record (card, (unsigned int) i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); + r = sc_read_record (card, (unsigned int) i + 1, 0, buff, sizeof(buff), SC_RECORD_BY_REC_NR); if (r < 6) goto err; diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index ae86ee00f3..c68393a1f1 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -271,7 +271,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) r = sc_select_file(card, &path, NULL); if (r < 0) continue; - r = sc_read_record(card, 1, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, 1, 0, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); if (r != 7 || sysrec[0] != 0) { continue; } @@ -292,7 +292,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) sc_pkcs15_format_id("", &kinfo[num_keyinfo].id); sc_log(card->ctx, "reading modulus"); - r = sc_read_record(card, 2, modulus_buf, + r = sc_read_record(card, 2, 0, modulus_buf, kinfo[num_keyinfo].modulus_len+1, SC_RECORD_BY_REC_NR); if (r < 0) continue; diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index efa4c8883d..248699dc45 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -281,7 +281,7 @@ sc_oberthur_read_file(struct sc_pkcs15_card *p15card, const char *in_path, rv = 0; break; } - rv = sc_read_record(card, rec, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR); + rv = sc_read_record(card, rec, 0, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR); if (rv == SC_ERROR_RECORD_NOT_FOUND) { rv = 0; break; diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index a78b9aee56..15fe522064 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -137,7 +137,7 @@ static int insert_key( } sc_log(ctx, "Searching for Key-Ref %02X\n", key_reference); - while ((r = sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { + while ((r = sc_read_record(card, ++rec_no, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { int found = 0; if (buf[0] != 0xA0 || r < 2) continue; @@ -240,7 +240,7 @@ static int insert_pin( } sc_log(ctx, "Searching for PIN-Ref %02X\n", pin_reference); - while ((r = sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { + while ((r = sc_read_record(card, ++rec_no, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { int found = 0, fbz = -1; if (r < 2 || buf[0] != 0xA0) continue; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index e9f875b1e3..fca816b838 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2515,7 +2515,7 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat if (l > 256) { l = 256; } - r = sc_read_record(p15card->card, i, head, l, SC_RECORD_BY_REC_NR); + r = sc_read_record(p15card->card, i, 0, head, l, SC_RECORD_BY_REC_NR); if (r == SC_ERROR_RECORD_NOT_FOUND) break; if (r < 0) { diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index a91a13cf90..9715cf390f 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -819,7 +819,7 @@ do_cardos_extract_pubkey(sc_card_t *card, int nr, u8 tag, u8 buf[256]; int r, count; - r = sc_read_record(card, nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, nr, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r < 0) return r; count = r - 4; diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 5b6e89ffb0..afca72d171 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -702,7 +702,7 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file for (n = 0; n < 6; n++) sysrec[6] ^= sysrec[n]; - r = sc_read_record(p15card->card, 1, buffer, sizeof(buffer), + r = sc_read_record(p15card->card, 1, 0, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); if (r >= 0) { if (r != 7 || buffer[0] != 0) { @@ -711,7 +711,7 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file goto out; } - r = sc_update_record(p15card->card, 1, sysrec, sizeof(sysrec), + r = sc_update_record(p15card->card, 1, 0, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); } else { r = sc_append_record(p15card->card, sysrec, sizeof(sysrec), 0); @@ -735,7 +735,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, /* If we've been given a key with public parts, write them now */ for (n = 2; n < 256; n++) { - r = sc_read_record(p15card->card, n, buffer, sizeof(buffer), + r = sc_read_record(p15card->card, n, 0, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); if (r < 0) { r = 0; @@ -755,7 +755,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, for (m = 0, found = 0; m < part->count; m++) { pe = part->components + m; if (pe->tag == tag) { - r = sc_update_record(p15card->card, n, + r = sc_update_record(p15card->card, n, 0, pe->data, pe->size, SC_RECORD_BY_REC_NR); if (r < 0) @@ -1046,7 +1046,7 @@ gpk_read_rsa_key(sc_card_t *card, struct sc_pkcs15_pubkey_rsa *rsa) u8 buffer[256]; size_t m; - r = sc_read_record(card, n, buffer, sizeof(buffer), + r = sc_read_record(card, n, 0, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); if (r < 1) break; diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index 1119e6b793..c031342d4a 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -656,7 +656,7 @@ incrypto34_extract_pubkey(sc_card_t *card, int nr, u8 tag, u8 buf[256]; int r, count; - r = sc_read_record(card, nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, nr, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r < 0) return r; count = r - 4; diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 879977d3bb..97d1e65240 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -371,7 +371,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p else { rv = sc_select_file(p15card->card, &list_file->path, NULL); if (!rv) - rv = sc_read_record(p15card->card, rec, buff, list_file->record_length, SC_RECORD_BY_REC_NR); + rv = sc_read_record(p15card->card, rec, 0, buff, list_file->record_length, SC_RECORD_BY_REC_NR); } if (rv < 0) { free(buff); @@ -415,7 +415,7 @@ awp_update_container_entry (struct sc_pkcs15_card *p15card, struct sc_profile *p rv = sc_append_record(p15card->card, buff, list_file->record_length, SC_RECORD_BY_REC_NR); } else { - rv = sc_update_record(p15card->card, rec, buff, list_file->record_length, SC_RECORD_BY_REC_NR); + rv = sc_update_record(p15card->card, rec, 0, buff, list_file->record_length, SC_RECORD_BY_REC_NR); } free(buff); @@ -477,7 +477,7 @@ awp_update_container(struct sc_pkcs15_card *p15card, struct sc_profile *profile, for (rec=0; rec < file->record_count; rec++) { unsigned char tmp[256]; - rv = sc_read_record(p15card->card, rec + 1, tmp, sizeof(tmp), SC_RECORD_BY_REC_NR); + rv = sc_read_record(p15card->card, rec + 1, 0, tmp, sizeof(tmp), SC_RECORD_BY_REC_NR); if (rv >= AWP_CONTAINER_RECORD_LEN) memcpy(list + rec*AWP_CONTAINER_RECORD_LEN, tmp, AWP_CONTAINER_RECORD_LEN); else @@ -1659,7 +1659,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "AWP update container entry: allocation error"); for (rec = 1; rec <= (unsigned)file->record_count; rec++) { - rv = sc_read_record(p15card->card, rec, buff, file->record_length, SC_RECORD_BY_REC_NR); + rv = sc_read_record(p15card->card, rec, 0, buff, file->record_length, SC_RECORD_BY_REC_NR); if (rv < 0) { sc_log(ctx, "AWP update container entry: read record error %i", rv); break; @@ -1697,7 +1697,7 @@ awp_delete_from_container(struct sc_pkcs15_card *p15card, break; } - rv = sc_update_record(p15card->card, rec, buff, rec_len, SC_RECORD_BY_REC_NR); + rv = sc_update_record(p15card->card, rec, 0, buff, rec_len, SC_RECORD_BY_REC_NR); if (rv < 0) { sc_log(ctx, "AWP update container entry: update record error %i", rv); break; diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index f336017e8f..1297482c36 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -156,7 +156,7 @@ static void do_esteid(sc_card_t *card) /* print the counters */ for (i = 1; i <= 4; i++) { - r = sc_read_record(card, i, buff, 128, SC_RECORD_BY_REC_NR); + r = sc_read_record(card, i, 0, buff, 128, SC_RECORD_BY_REC_NR); if (r < 0) goto out; key_used[i - 1] = 0xffffff - ((unsigned char) buff[0xc] * 65536 @@ -180,7 +180,7 @@ static void do_esteid(sc_card_t *card) } for (i = 0; esteid_data[i].recno != 0; i++) { - r = sc_read_record(card, esteid_data[i].recno, buff, 50, SC_RECORD_BY_REC_NR); + r = sc_read_record(card, esteid_data[i].recno, 0, buff, 50, SC_RECORD_BY_REC_NR); if (r < 0) { fprintf (stderr, "Failed to read record %d from card: %s\n", esteid_data[i].recno, sc_strerror (r)); diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index c2c2e4e4be..5ff65cd0d9 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -803,7 +803,7 @@ static int read_and_print_record_file(sc_file_t *file, unsigned char sfi, unsign for (rec = (wanted > 0) ? wanted : 1; wanted == 0 || wanted == rec; rec++) { r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_read_record(card, rec, buf, sizeof(buf), + r = sc_read_record(card, rec, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR | sfi); else r = SC_ERROR_READER_LOCKED; @@ -1582,7 +1582,7 @@ static int do_get_record(int argc, char **argv) goto err; } - r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, rec, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r < 0) { fprintf(stderr, "Cannot read record %"SC_FORMAT_LEN_SIZE_T"u; return %i\n", rec, r); goto err; @@ -1710,7 +1710,7 @@ static int do_update_record(int argc, char **argv) goto err; } - r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, rec, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); if (r < 0) { fprintf(stderr, "Cannot read record %"SC_FORMAT_LEN_SIZE_T"u of %04X: %s\n", rec, file->id, sc_strerror(r)); @@ -1732,7 +1732,7 @@ static int do_update_record(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_update_record(card, rec, buf, buflen, SC_RECORD_BY_REC_NR); + r = sc_update_record(card, rec, 0, buf, buflen, SC_RECORD_BY_REC_NR); sc_unlock(card); if (r < 0) { fprintf(stderr, "Cannot update record %"SC_FORMAT_LEN_SIZE_T"u of %04X: %s\n.", @@ -2174,7 +2174,7 @@ static int do_asn1(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(card, rec, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); else r = SC_ERROR_READER_LOCKED; sc_unlock(card); diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index d97e11e2b0..eebe87bf40 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -428,7 +428,7 @@ static int print_file(sc_card_t *in_card, const sc_file_t *file, printf("Record %"SC_FORMAT_LEN_SIZE_T"u\n", rec_nr); r = sc_lock(card); if (r == SC_SUCCESS) - r = sc_read_record(in_card, rec_nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); + r = sc_read_record(in_card, rec_nr, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR); sc_unlock(card); if (r > 0) util_hex_dump_asc(stdout, buf, r, 0); From 3d5bf0bc0cfdb44c9fe005a3e4c8a6f3261bad30 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 12 Sep 2022 13:58:51 +0200 Subject: [PATCH 2815/4321] iso7816: added support for updating/reading record with offset --- src/libopensc/iso7816.c | 132 ++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 17 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index cff66b02d9..10d166709e 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -165,31 +165,115 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun } +const struct sc_asn1_entry c_asn1_do_data[] = { + { "Offset Data Object", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x14, SC_ASN1_OPTIONAL, NULL, NULL }, + { "Discretionary Data Object", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x13, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +int encode_do_data(struct sc_context *ctx, + unsigned int idx, const unsigned char *data, size_t data_len, + u8 **out, size_t *outlen) +{ + unsigned char offset_buffer[2]; + size_t offset_buffer_len = sizeof offset_buffer; + struct sc_asn1_entry asn1_do_data[sizeof c_asn1_do_data / sizeof *c_asn1_do_data]; + sc_copy_asn1_entry(c_asn1_do_data, asn1_do_data); + + if (idx > 0xFFFF) + LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Offset beyond 0xFFFF not supported"); + offset_buffer[0] = (u8) (idx >> 8); + offset_buffer[1] = (u8) (idx & 0x00FF); + sc_format_asn1_entry(asn1_do_data + 0, offset_buffer, &offset_buffer_len, 1); + + if (data && data_len) { + sc_format_asn1_entry(asn1_do_data + 1, (void *) &data, &data_len, 1); + } else { + sc_format_asn1_entry(asn1_do_data + 1, NULL, NULL, 0); + } + + LOG_TEST_RET(ctx, + sc_asn1_encode(ctx, asn1_do_data, out, outlen), + "sc_asn1_encode() failed"); + + return SC_SUCCESS; +} + +int decode_do_data(struct sc_context *ctx, + const unsigned char *encoded_data, size_t encoded_data_len, + u8 **out, size_t *outlen) +{ + struct sc_asn1_entry asn1_do_data[sizeof c_asn1_do_data / sizeof *c_asn1_do_data]; + sc_copy_asn1_entry(c_asn1_do_data, asn1_do_data); + + sc_format_asn1_entry(asn1_do_data + 0, NULL, NULL, 0); + sc_format_asn1_entry(asn1_do_data + 1, out, outlen, 0); + + LOG_TEST_RET(ctx, + sc_asn1_decode(ctx, asn1_do_data, encoded_data, encoded_data_len, NULL, NULL), + "sc_asn1_decode() failed"); + + return SC_SUCCESS; +} + static int iso7816_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, u8 *buf, size_t count, unsigned long flags) { struct sc_apdu apdu; int r; + /* XXX maybe use some bigger buffer */ + unsigned char resp[SC_MAX_APDU_RESP_SIZE]; + unsigned char *encoded_data = NULL, *decoded_data = NULL; + size_t encoded_data_len = 0, decoded_data_len = 0; - if (rec_nr > 0xFF || idx != 0) + if (rec_nr > 0xFF) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0); - apdu.le = count; - apdu.resplen = count; - apdu.resp = buf; + if (idx == 0) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0); + apdu.le = count; + apdu.resplen = count; + apdu.resp = buf; + } else { + r = encode_do_data(card->ctx, idx, NULL, 0, &encoded_data, &encoded_data_len); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not encode data objects"); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB3, rec_nr, 0); + apdu.lc = encoded_data_len; + apdu.datalen = encoded_data_len; + apdu.data = encoded_data; + apdu.le = sizeof resp; + apdu.resplen = sizeof resp; + apdu.resp = resp; + } apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if (apdu.resplen == 0) - LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_GOTO_ERR(card->ctx, r, "Card returned error"); - LOG_FUNC_RETURN(card->ctx, apdu.resplen); + if (idx == 0) { + r = apdu.resplen; + } else { + r = decode_do_data(card->ctx, apdu.resp, apdu.resplen, + &decoded_data, &decoded_data_len); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not decode data objects"); + if (decoded_data_len <= count) { + count = decoded_data_len; + } + memcpy(buf, decoded_data, count); + r = count; + } + +err: + free(encoded_data); + free(decoded_data); + LOG_FUNC_RETURN(card->ctx, r); } @@ -247,28 +331,42 @@ iso7816_update_record(struct sc_card *card, unsigned int rec_nr, unsigned int id { struct sc_apdu apdu; int r; + unsigned char *encoded_data = NULL; + size_t encoded_data_len = 0; - if (rec_nr > 0xFF || idx != 0) + if (rec_nr > 0xFF) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDC, rec_nr, 0); - apdu.lc = count; - apdu.datalen = count; - apdu.data = buf; + if (idx == 0) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDC, rec_nr, 0); + apdu.lc = count; + apdu.datalen = count; + apdu.data = buf; + } else { + r = encode_do_data(card->ctx, idx, buf, count, &encoded_data, &encoded_data_len); + LOG_TEST_GOTO_ERR(card->ctx, r, "Could not encode data objects"); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDD, rec_nr, 0); + apdu.lc = encoded_data_len; + apdu.datalen = encoded_data_len; + apdu.data = encoded_data; + } apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; fixup_transceive_length(card, &apdu); r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - LOG_TEST_RET(card->ctx, r, "Card returned error"); + LOG_TEST_GOTO_ERR(card->ctx, r, "Card returned error"); + r = count; +err: + free(encoded_data); LOG_FUNC_RETURN(card->ctx, count); } - static int iso7816_write_binary(struct sc_card *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) From 5e06acb3f2e95448248b75aaf2e033131e46510d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 13 Sep 2022 12:20:56 +0200 Subject: [PATCH 2816/4321] run update_record/read_record multiple times with offset if needed --- src/libopensc/card.c | 76 ++++++++++++++++++++++++++++++++++-------- src/libopensc/pkcs15.c | 46 ++++--------------------- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 6f42ca6c4f..7b0ebc8019 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -654,7 +654,7 @@ int sc_read_binary(sc_card_t *card, unsigned int idx, LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); while (todo > 0) { - size_t chunk = todo > max_le ? max_le : todo; + size_t chunk = MIN(todo, max_le); r = card->ops->read_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) @@ -702,7 +702,7 @@ int sc_write_binary(sc_card_t *card, unsigned int idx, LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); while (todo > 0) { - size_t chunk = todo > max_lc ? max_lc : todo; + size_t chunk = MIN(todo, max_lc); r = card->ops->write_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) @@ -758,7 +758,7 @@ int sc_update_binary(sc_card_t *card, unsigned int idx, LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); while (todo > 0) { - size_t chunk = todo > max_lc ? max_lc : todo; + size_t chunk = MIN(todo, max_lc); r = card->ops->update_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) @@ -953,22 +953,47 @@ int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len) int sc_read_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, u8 *buf ,size_t count, unsigned long flags) { + size_t max_le = sc_get_max_recv_size(card); + size_t todo = count; int r; - if (card == NULL) { + if (card == NULL || card->ops == NULL || buf == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } LOG_FUNC_CALLED(card->ctx); + if (count == 0) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); if (card->ops->read_record == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->read_record(card, rec_nr, idx, buf, count, flags); - if (r == SC_SUCCESS) { - r = count; + /* lock the card now to avoid deselection of the file */ + r = sc_lock(card); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); + + while (todo > 0) { + size_t chunk = MIN(todo, max_le); + + r = card->ops->read_record(card, rec_nr, idx, buf, chunk, flags); + if (r == 0 || r == SC_ERROR_FILE_END_REACHED) + break; + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + r = SC_ERROR_OFFSET_TOO_LARGE; + } + if (r < 0) { + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, r); + } + + todo -= (size_t) r; + buf += (size_t) r; + idx += (size_t) r; } - LOG_FUNC_RETURN(card->ctx, r); + sc_unlock(card); + + LOG_FUNC_RETURN(card->ctx, count - todo); } int sc_write_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf, @@ -1016,22 +1041,47 @@ int sc_append_record(sc_card_t *card, const u8 * buf, size_t count, int sc_update_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, const u8 * buf, size_t count, unsigned long flags) { + size_t max_lc = sc_get_max_send_size(card); + size_t todo = count; int r; - if (card == NULL) { + if (card == NULL || card->ops == NULL || buf == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } LOG_FUNC_CALLED(card->ctx); + if (count == 0) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); if (card->ops->update_record == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); - r = card->ops->update_record(card, rec_nr, idx, buf, count, flags); - if (r == SC_SUCCESS) { - r = count; + /* lock the card now to avoid deselection of the file */ + r = sc_lock(card); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); + + while (todo > 0) { + size_t chunk = MIN(todo, max_lc); + + r = card->ops->update_record(card, rec_nr, idx, buf, chunk, flags); + if (r == 0 || r == SC_ERROR_FILE_END_REACHED) + break; + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + r = SC_ERROR_OFFSET_TOO_LARGE; + } + if (r < 0) { + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, r); + } + + todo -= (size_t) r; + buf += (size_t) r; + idx += (size_t) r; } - LOG_FUNC_RETURN(card->ctx, r); + sc_unlock(card); + + LOG_FUNC_RETURN(card->ctx, count - todo); } int sc_delete_record(sc_card_t *card, unsigned int rec_nr) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index fca816b838..fc880ea3e1 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2538,46 +2538,12 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat len = head-data; } else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { - - u8 offset_buffer[] = {0x54, 0x02, 0x00, 0x00}; - u8 response_buffer[SC_MAX_APDU_RESP_SIZE]; - struct sc_apdu apdu; - uint16_t offset_u16 = 0; - u8 *data_do; - size_t data_do_len; - - do { - - offset_buffer[2] = (u8) (offset_u16 >> 8); - offset_buffer[3] = (u8) (offset_u16 & 0x00ff); - - sc_format_apdu(p15card->card, &apdu, SC_APDU_CASE_4_SHORT, 0xB3, in_path->index, 4); - - apdu.data = offset_buffer; - apdu.datalen = sizeof(offset_buffer); - apdu.lc = sizeof(offset_buffer); - apdu.le = 0; - - apdu.resp = response_buffer; - apdu.resplen = sizeof(response_buffer); - - r = sc_transmit_apdu(p15card->card, &apdu); - if (r < 0 || apdu.resplen == 0) - break; - - data_do = NULL; - r = sc_decode_do53(ctx, &data_do, &data_do_len, apdu.resp, apdu.resplen); - if (r < 0) goto fail_unlock; - - if(data_do) { - memcpy(data + offset_u16, data_do, data_do_len); - offset_u16 += data_do_len; - free(data_do); - } - - } while(r == SC_SUCCESS); - - len = offset_u16; + r = sc_read_record(p15card->card, in_path->index, offset, data, len, SC_RECORD_BY_REC_NR); + if (r < 0) { + goto fail_unlock; + } + /* sc_read_record may return less than requested */ + len = r; } else { r = sc_read_binary(p15card->card, offset, data, len, 0); From 6af6bdf1b16e5855f7061899a39bf7f9cd173574 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 16 Nov 2022 10:01:23 +0100 Subject: [PATCH 2817/4321] Don't stop on gaps when parsing PKCS#15 DF files Slovenian eID card has gaps between consecutive PKCS#15 objects in xDF (PrKDF, CDF) files. Currently parsing stops when it reaches EOC. With this patch parsing continues until whole file is processed and end-of-file reached. This way, all the objects that are stored on a Slovenian eID card are read properly. --- src/libopensc/pkcs15.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index fc880ea3e1..c33b4d2e74 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2184,6 +2184,10 @@ sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) sc_log(ctx, "%s: Error adding object", sc_strerror(r)); goto ret; } + while (bufsize > 0 && *p == 00) { + bufsize--; + p++; + } }; if (r > 0) From 1d5c81e85baaa82973e1080dfb34876830bee067 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 16 Nov 2022 10:01:23 +0100 Subject: [PATCH 2818/4321] Add some more logic to decide if login is required Currently CKF_LOGIN_REQUIRED flag is set if any PIN objects exist. But Slovenian eID card (at least the 'low level' app) has PIN objects and still doesn't require PIN. So, set CKF_LOGIN_REQUIRED only if PIN objects exist AND TokenInfo has TOKEN_LOGIN_REQUIRED set. --- src/pkcs11/framework-pkcs15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 33fdac4308..faf2738311 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1207,7 +1207,8 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, p15card->tokeninfo ? p15card->tokeninfo->label : "", 32); } - slot->token_info.flags |= CKF_LOGIN_REQUIRED; + if (p15card->tokeninfo->flags & SC_PKCS15_TOKEN_LOGIN_REQUIRED) + slot->token_info.flags |= CKF_LOGIN_REQUIRED; } } From 4a4fbeb472fbd273f436d42a90b48cfeda81a9ea Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 23 Nov 2022 13:09:10 +0100 Subject: [PATCH 2819/4321] Make PKCS#11 PIN objects selectable via the opensc.conf Currently the first suitable PIN is used as a PKCS#11 'User PIN'. However Slovenian eID's first PIN object is 'Card CAN' which is not used for accessing on-card files. With this patch per PKCS#15 application 'user_pin' and 'sign_pin' options are implemented, which can be used to precisely specify which PIN objects should be used instead of the ones library automagically picked. The same also applies to the minidriver code. --- doc/files/opensc.conf.5.xml.in | 16 +++++++++++ etc/opensc.conf.example.in | 2 ++ src/minidriver/minidriver.c | 51 ++++++++++++++++++++++++++++++++++ src/pkcs11/framework-pkcs15.c | 37 +++++++++++++++++++++--- 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 44ffce2d51..83eb15c676 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1427,6 +1427,22 @@ app application { false) + + + + + + Name of the User PIN object that will be used as the main PIN. + + + + + + + + Name of the PIN object that will be used for signing. + + diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 6f70d87f1f..16f7610ef9 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -958,6 +958,8 @@ app default { # # - disable: do not expose application in PKCS15 framework # default 'false' + # - user_pin and sign_pin: labels of PIN objects that will be used as + # user & sign PINs. Otherwise the first suitable one will be used. application E828BD080FD25047656E65726963 { type = generic; model = "ECC Generic PKI"; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 4790f31de4..de84f49edf 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -482,6 +482,52 @@ check_card_reader_status(PCARD_DATA pCardData, const char *name) MD_FUNC_RETURN(pCardData, 1, SCARD_S_SUCCESS); } +static DWORD +get_pin_by_name(PCARD_DATA pCardData, struct sc_pkcs15_card *p15card, int role, struct sc_pkcs15_object **ret_obj) +{ + scconf_block *conf_block = NULL; + scconf_block **blocks = NULL; + char *pin_type; + char str_path[SC_MAX_AID_STRING_SIZE]; + char *pin = NULL; + struct sc_pkcs15_id id; + + MD_FUNC_CALLED(pCardData, 1); + + switch (role) { + case ROLE_USER: + pin_type = "user_pin"; + break; + case MD_ROLE_USER_SIGN: + pin_type = "sign_pin"; + break; + default: + MD_FUNC_RETURN(pCardData, 1, SCARD_E_INVALID_PARAMETER); + } + + conf_block = sc_get_conf_block(p15card->card->ctx, "framework", "pkcs15", 1); + if (!conf_block) + MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); + + memset(str_path, 0, sizeof(str_path)); + sc_bin_to_hex(p15card->app->path.value, p15card->app->path.len, str_path, sizeof(str_path), 0); + blocks = scconf_find_blocks(p15card->card->ctx->conf, conf_block, "application", str_path); + if (blocks) { + if (blocks[0]) { + pin = (char *)scconf_get_str(blocks[0], pin_type, NULL); + } + free(blocks); + } + if (!pin) + MD_FUNC_RETURN(pCardData, 1, SCARD_F_INTERNAL_ERROR); + + strncpy((char*)id.value, pin, sizeof(id.value) - 1); + id.len = strlen(pin); + if (id.len > sizeof(id.value)) + id.len = sizeof(id.value); + MD_FUNC_RETURN(pCardData, 1, sc_pkcs15_find_pin_by_auth_id(p15card, &id, ret_obj) ? SCARD_F_INTERNAL_ERROR : SCARD_S_SUCCESS); +} + static DWORD md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object **ret_obj) { @@ -497,6 +543,10 @@ md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object ** if (!ret_obj) MD_FUNC_RETURN(pCardData, 1, SCARD_E_INVALID_PARAMETER); + rv = get_pin_by_name(pCardData, vs->p15card, role, ret_obj); + if (!rv) + goto out; + /* please keep me in sync with _get_auth_object_by_name() in pkcs11/framework-pkcs15.c */ if (role == ROLE_USER) { /* Get 'global' User PIN; if no, get the 'local' one */ @@ -546,6 +596,7 @@ md_get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object ** MD_FUNC_RETURN(pCardData, 1, SCARD_E_UNSUPPORTED_FEATURE); } +out: if (rv) MD_FUNC_RETURN(pCardData, 1, SCARD_E_UNSUPPORTED_FEATURE); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index faf2738311..8457e1fcd0 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1397,13 +1397,23 @@ int slot_get_logged_in_state(struct sc_pkcs11_slot *slot) struct sc_pkcs15_object * -_get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name) +_get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name, char *label) { struct sc_pkcs15_object *out = NULL; int rv = SC_ERROR_OBJECT_NOT_FOUND; /* please keep me in sync with md_get_pin_by_role() in minidriver */ - if (!strcmp(name, "UserPIN")) { + + /* If 'label' is set, then search for PIN with that label */ + if (label) { + struct sc_pkcs15_id id; + strncpy((char*)id.value, label, sizeof(id.value) - 1); + id.len = strlen(label); + if (id.len > sizeof(id.value)) + id.len = sizeof(id.value); + rv = sc_pkcs15_find_pin_by_auth_id(p15card, &id, &out); + } + else if (!strcmp(name, "UserPIN")) { /* Try to get 'global' PIN; if no, get the 'local' one */ rv = sc_pkcs15_find_pin_by_flags(p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, &out); @@ -1579,6 +1589,8 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf unsigned int cs_flags = sc_pkcs11_conf.create_slots_flags; CK_RV rv; int rc, i, idx; + scconf_block *conf_block = NULL; + char *user_pin = NULL, *sign_pin = NULL; if (p11card) { sc_log(context, "create PKCS#15 tokens; fws:%p,%p,%p", p11card->fws_data[0], p11card->fws_data[1], p11card->fws_data[2]); @@ -1596,10 +1608,27 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf } sc_log(context, "Use FW data with index %i; fw_data->p15_card %p", idx, fw_data->p15_card); + conf_block = sc_get_conf_block(p11card->card->ctx, "framework", "pkcs15", 1); + if (conf_block && app_info) { + scconf_block **blocks = NULL; + char str_path[SC_MAX_AID_STRING_SIZE]; + + memset(str_path, 0, sizeof(str_path)); + sc_bin_to_hex(app_info->path.value, app_info->path.len, str_path, sizeof(str_path), 0); + blocks = scconf_find_blocks(p11card->card->ctx->conf, conf_block, "application", str_path); + if (blocks) { + if (blocks[0]) { + user_pin = (char *)scconf_get_str(blocks[0], "user_pin", NULL); + sign_pin = (char *)scconf_get_str(blocks[0], "sign_pin", NULL); + } + free(blocks); + } + } + /* Try to identify UserPIN and SignPIN by their symbolic name */ - auth_user_pin = _get_auth_object_by_name(fw_data->p15_card, "UserPIN"); + auth_user_pin = _get_auth_object_by_name(fw_data->p15_card, "UserPIN", user_pin); if (cs_flags & SC_PKCS11_SLOT_FOR_PIN_SIGN) - auth_sign_pin = _get_auth_object_by_name(fw_data->p15_card, "SignPIN"); + auth_sign_pin = _get_auth_object_by_name(fw_data->p15_card, "SignPIN", sign_pin); sc_log(context, "Flags:0x%X; Auth User/Sign PINs %p/%p", cs_flags, auth_user_pin, auth_sign_pin); /* Add PKCS#15 objects of the known types to the framework data */ From d58e261a91617bbb393853cf386cf26966c966e5 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 23 Nov 2022 13:09:10 +0100 Subject: [PATCH 2820/4321] RESET RETRY COUNTER can also send case 1 APDU Data field is absent when P1 is 0x03 --- src/libopensc/iso7816.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 10d166709e..af84e8a171 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1244,6 +1244,10 @@ iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu, } else { p1 |= 0x01; } + if (p1 == 0x03) { + /* No data to send or to receive */ + cse = SC_APDU_CASE_1; + } break; case SC_PIN_CMD_GET_INFO: ins = 0x20; From 4b2ef66cd254c6c3743897ded241cc39be19fdba Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 23 Nov 2022 13:09:10 +0100 Subject: [PATCH 2821/4321] Expand PrKDF parsing to include Slovenian eID specific data Slovenian eID card has ECC curve OID included in the PrKDF key object data. By parsing this data one can get the private key length which will be needed later. --- src/libopensc/pkcs15-prkey.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 09f3130dd7..7b87877429 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -128,11 +128,13 @@ static const struct sc_asn1_entry c_asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410 * the size of the underlying ECC field. This value is required for determine a proper size for * buffer allocations. The field follows the definition for modulusLength in RSA keys */ -#define C_ASN1_ECCKEY_ATTR 4 +#define C_ASN1_ECCKEY_ATTR 5 static const struct sc_asn1_entry c_asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR] = { { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL }, { "fieldSize", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, { "keyInfo", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + /* Slovenian eID card also specifies ECC curve OID */ + { "ecDomain", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL}, { NULL, 0, 0, 0, NULL, NULL } }; @@ -174,6 +176,8 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_pkcs15_object rsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr}; struct sc_asn1_pkcs15_object gostr3410_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_gostr3410_attr}; struct sc_asn1_pkcs15_object ecc_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_ecc_attr }; + u8 ec_domain[32]; + size_t ec_domain_len = sizeof(ec_domain); sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms); @@ -206,6 +210,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_ecckey_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_ecckey_attr + 1, &info.field_length, NULL, 0); + sc_format_asn1_entry(asn1_ecckey_attr + 3, ec_domain, &ec_domain_len, 0); sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); @@ -234,6 +239,33 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, } else if (asn1_prkey[1].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PRKEY_EC; +#ifdef ENABLE_OPENSSL + if (!info.field_length && ec_domain_len) { + const unsigned char *p = ec_domain; + const ASN1_OBJECT *object = d2i_ASN1_OBJECT(NULL, &p, ec_domain_len); + int nid; + const EC_GROUP *group; + if (!object) { + r = SC_ERROR_INVALID_ASN1_OBJECT; + goto err; + } + nid = OBJ_obj2nid(object); + if (nid == NID_undef) { + r = SC_ERROR_OBJECT_NOT_FOUND; + goto err; + } + group = EC_GROUP_new_by_curve_name(nid); + if (!group) { + r = SC_ERROR_INVALID_DATA; + goto err; + } + info.field_length = EC_GROUP_order_bits(group); + if (!info.field_length) { + r = SC_ERROR_CORRUPTED_DATA; + goto err; + } + } +#endif } else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) { /* FIXME proper handling of gost parameters without the need of From 4340b757e0d93e5593f8a6062ed2b93b38f3e303 Mon Sep 17 00:00:00 2001 From: Luka Logar Date: Wed, 15 Feb 2023 12:52:20 +0100 Subject: [PATCH 2822/4321] Add support for Slovenian eID card ('eOI' in Slovenian language, OpenSC driver name 'eoi') It mostly follows the PKCS#15 model with some quirks which are handled by the provided code. Installed on the eID card are 2 applications (that are of interest to OpenSC): 1. app:E8:28:BD:08:0F:01:4E:58:50:31 (Prijava brez PIN-a) which can be used for Low assurance authentication that does not require PIN entry. It includes 1 private key/certificate and several PIN objects, but it looks like they are not needed for normal operation. 2. app:E8:28:BD:08:0F:01:4E:58:50:30 (Podpis in prijava) which can be used to make QES signatures and High assurance authentication and includes 2 private keys/certificates and several PINs, including 'Norm PIN' & 'Sig PIN' PINs, which should probably be exposed as 2 PKCS#11 slots. Both applications also include full certificate chains needed to verify respective user certificates. 'Norm PIN' is shared between both applications, so 'Norm PIN' change in one also applies to the other. SM with PACE authentication is used for establishing a secure communication with the card. In case of contact reader, CAN is read from the card (where it's stored in an encrypted form), decrypted and used for authentication. In case of contactless reader, CAN has to be provided via the opensc.conf file or EOI_CAN environment variable. The following functionalities have been implemented: - secure login - PIN change - PIN unblock using "pkcs15-tool --unblock ..." and/or "pkcs11-tool --unlock-pin ..." (user_pin_unblock_style must be set to set_pin_in_unlogged_session for the later) - digital signatures, SHA1, SHA256 and raw data are supported Not implemented: - card activation The card has been tested on Ubuntu 22.04 and with both contact (pinpad readers will probably have some issues) and contactless readers. --- doc/files/opensc.conf.5.xml.in | 25 ++ etc/opensc.conf.example.in | 30 ++ src/libopensc/Makefile.am | 8 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-eoi.c | 558 +++++++++++++++++++++++++++++++++ src/libopensc/card-eoi.h | 41 +++ src/libopensc/cards.h | 7 +- src/libopensc/ctx.c | 3 + src/libopensc/pkcs15-eoi.c | 146 +++++++++ src/libopensc/pkcs15-syn.c | 4 +- src/libopensc/pkcs15-syn.h | 1 + 11 files changed, 819 insertions(+), 8 deletions(-) create mode 100644 src/libopensc/card-eoi.c create mode 100644 src/libopensc/card-eoi.h create mode 100644 src/libopensc/pkcs15-eoi.c diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 83eb15c676..2a764cfa87 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -296,6 +296,9 @@ app application { edo: See + + eoi: See + myeid: See @@ -772,6 +775,28 @@ app application { + + Configuration Options for Slovenian eID Card + + + + + + + CAN (Card Access Number – 6 digit number + printed on the right bottom corner of the + front side of the document) is required + to establish connection with the card. + It might be overwritten by EOI_CAN + environment variable. As CAN is also stored on the card + (in encrypted form) it can be used to automatically establish + secure connection, but only if the card is accessed over the + contact interface. + + + + + Configuration based on ATR diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 16f7610ef9..037a099667 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -211,6 +211,21 @@ app default { #can = 123456; } + card_driver eoi { + # CAN is required to establish connection + # with the card. When using contact reader + # it is read (and decrypted) from the card. + # When using contactless reader, CAN has to + # be specified here or using the EOI_CAN + # environment variable. + #can = 123456; + # + # To hide unneeded slots it's also + # recommended to set + # create_slots_for_pins = "user,sign"; + # in the 'pkcs11' section below + } + # In addition to the built-in list of known cards in the # card driver, you can configure a new card for the driver # using the card_atr block. The goal is to centralize @@ -980,6 +995,21 @@ app default { type = protected; model = "Adèle Admin-2"; } + + # Slovenian eID - low level (pinless, "Prijava brez PIN-a") + application E828BD080F014E585031 { + model = "ChipDocLite"; + disable = true; + user_pin = "Norm PIN"; + } + + # Slovenian eID - high level (QES, "Podpis in prijava") + application E828BD080F014E585030 { + model = "ChipDocLite"; + # disable = true; + user_pin = "Norm PIN"; + sign_pin = "Sig PIN"; + } } } diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index e07cd3219a..926e510c1e 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -13,7 +13,7 @@ noinst_HEADERS = cards.h ctbcs.h internal.h muscle.h muscle-filesystem.h \ authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \ pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h \ jpki.h sc-ossl-compat.h card-npa.h card-openpgp.h \ - ccid-types.h reader-tr03119.h \ + card-eoi.h ccid-types.h reader-tr03119.h \ card-cac-common.h AM_CPPFLAGS = -D'OPENSC_CONF_PATH="$(sysconfdir)/opensc.conf"' \ @@ -50,7 +50,7 @@ libopensc_la_SOURCES_BASE = \ card-dnie.c cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-gids.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c card-nqApplet.c card-skeid.c \ + card-edo.c card-nqApplet.c card-skeid.c card-eoi.c \ \ pkcs15-openpgp.c pkcs15-starcert.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-gemsafeGPK.c \ @@ -59,7 +59,7 @@ libopensc_la_SOURCES_BASE = \ pkcs15-oberthur.c pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \ pkcs15-coolkey.c pkcs15-din-66291.c pkcs15-idprime.c pkcs15-nqApplet.c \ pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c pkcs15-jpki.c pkcs15-esteid2018.c \ - pkcs15-starcos-esign.c pkcs15-skeid.c compression.c sm.c \ + pkcs15-starcos-esign.c pkcs15-skeid.c pkcs15-eoi.c compression.c sm.c \ aux-data.c if ENABLE_CRYPTOTOKENKIT @@ -133,7 +133,7 @@ TIDY_FILES = \ cwa14890.c cwa-dnie.c \ card-isoApplet.c card-masktech.c card-jpki.c \ card-npa.c card-esteid2018.c card-idprime.c \ - card-edo.c card-nqApplet.c card-skeid.c \ + card-edo.c card-nqApplet.c card-skeid.c card-eoi.c \ \ pkcs15-openpgp.c pkcs15-cardos.c \ pkcs15-tcos.c pkcs15-esteid.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 856cce5201..c58ecdd759 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -28,7 +28,7 @@ OBJECTS = \ card-sc-hsm.obj card-dnie.obj card-isoApplet.obj pkcs15-coolkey.obj \ card-masktech.obj card-gids.obj card-jpki.obj \ card-npa.obj card-esteid2018.obj card-idprime.obj \ - card-edo.obj card-nqApplet.obj card-skeid.obj \ + card-edo.obj card-nqApplet.obj card-skeid.obj card-eoi.obj \ \ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ @@ -37,7 +37,7 @@ OBJECTS = \ pkcs15-oberthur.obj pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \ pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj pkcs15-jpki.obj \ pkcs15-esteid2018.obj pkcs15-idprime.obj pkcs15-nqApplet.obj \ - pkcs15-starcos-esign.obj pkcs15-skeid.obj compression.obj sm.obj \ + pkcs15-starcos-esign.obj pkcs15-skeid.obj pkcs15-eoi.obj compression.obj sm.obj \ aux-data.obj \ $(TOPDIR)\win32\versioninfo.res LIBS = $(TOPDIR)\src\scconf\scconf.lib \ diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c new file mode 100644 index 0000000000..bc2d5e6950 --- /dev/null +++ b/src/libopensc/card-eoi.c @@ -0,0 +1,558 @@ +/* + * Support for the eOI card + * + * Copyright (C) 2022 Luka Logar + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "opensc.h" + +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) + +#include +#include +#include "internal.h" +#include "sm/sm-eac.h" +#include "common/compat_strlcpy.h" +#include "card-eoi.h" + +static struct sc_card_operations eoi_ops; + +static struct { + int len; + struct sc_object_id oid; +} eoi_curves[] = { + /* secp384r1 */ + {384, {{1, 3, 132, 0, 34, -1}}} +}; + +/* The description of the driver. */ +static struct sc_card_driver eoi_drv = +{ + "eOI (Slovenian eID card)", + "eOI", + &eoi_ops, + NULL, 0, NULL +}; + +static const struct sc_atr_table eoi_atrs[] = { + /* Contact interface */ + { "3b:d5:18:ff:81:91:fe:1f:c3:80:73:c8:21:10:0a", NULL, NULL, SC_CARD_TYPE_EOI, 0, NULL }, + /* Contactless interface */ + { "3b:85:80:01:80:73:c8:21:10:0e", NULL, NULL, SC_CARD_TYPE_EOI_CONTACTLESS, 0, NULL }, + { NULL, NULL, NULL, 0, 0, NULL } +}; + +/* + * CAN is stored encrypted in a file that (looks like) is pointed to by 'Card CAN' PIN object. + * eoi_decrypt_can() decrypts CAN from it's encrypted form + */ + +static void rol(u8 *to, const u8 *from) +{ + int i; + u8 b = from[0] & 0x80; + for (i = 15; i >= 0; i--) { + u8 bo = b; + b = from[i] & 0x80; + to[i] = (from[i] << 1) | (bo ? 1 : 0); + if ((i == 15) && bo) + to[i] = (to[i] ^ 0x87) | 1; + } +} + +static int aes256_ecb_encrypt(const u8 *key, const u8 input[AES_BLOCK_SIZE], u8 output[AES_BLOCK_SIZE]) +{ + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + int r = 0, pos, len = pos = AES_BLOCK_SIZE; + if (!ctx) + goto err; + if (!EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key, NULL)) + goto err; + /* Disable padding, otherwise EVP_EncryptFinal() will fail */ + if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) + goto err; + if (!EVP_EncryptUpdate(ctx, output, &pos, input, len)) + goto err; + len -= pos; + if (!EVP_EncryptFinal(ctx, output + pos, &len)) + goto err; + r = 1; +err: + if (ctx) + EVP_CIPHER_CTX_free(ctx); + return r; +} + +static int aes256_ecb_decrypt(const u8 *key, const u8 input[AES_BLOCK_SIZE], u8 output[AES_BLOCK_SIZE]) +{ + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + int r = 0, pos, len = pos = AES_BLOCK_SIZE; + if (!ctx) + goto err; + if (!EVP_DecryptInit(ctx, EVP_aes_256_ecb(), key, NULL)) + goto err; + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) + goto err; + if (!EVP_DecryptUpdate(ctx, output, &pos, input, len)) + goto err; + len -= pos; + if (!EVP_DecryptFinal(ctx, output + pos, &len)) + goto err; + r = 1; +err: + if (ctx) + EVP_CIPHER_CTX_free(ctx); + return r; +} + +/* + * CAN decrypt magic... + */ +static int get_can_key(const u8 *key, const u8 round, const u8 *input, u8 *output) +{ + size_t i; + u8 tmp[3][AES_BLOCK_SIZE]; + memset(tmp[0], 0, AES_BLOCK_SIZE); + if (!aes256_ecb_encrypt(key, tmp[0], tmp[0])) + return 0; + rol(tmp[1], tmp[0]); + rol(tmp[0], tmp[1]); + memset(tmp[1], 0, AES_BLOCK_SIZE); + tmp[1][11] = 4; + tmp[1][13] = 1; + tmp[1][15] = round; + if (!aes256_ecb_encrypt(key, tmp[1], tmp[2])) + return 0; + memset(tmp[1], 0, AES_BLOCK_SIZE); + memcpy(tmp[1], &input[AES_BLOCK_SIZE], 8); + tmp[1][8] = 0x80; + for (i = 0; i < AES_BLOCK_SIZE; i++) + tmp[0][i] = tmp[0][i] ^ tmp[1][i] ^ tmp[2][i]; + if (!aes256_ecb_encrypt(key, tmp[0], output)) + return 0; + return 1; +} + +#define AES256_KEY_LEN 32 + +static int eoi_decrypt_can(struct sc_pkcs15_u8 *enc_can, char *can) { + /* Magic key that is used to decrypt CAN */ + const u8 magic_key[AES256_KEY_LEN] = {0xC8, 0x12, 0x0F, 0xD8, 0x21, 0x20, 0x1F, 0x77, 0xF1, 0x83, 0x9D, 0xD8, 0x86, 0xB0, 0x5C, 0xF2, 0x4F, 0x7E, 0x52, 0x66, 0xE5, 0x87, 0x89, 0x2B, 0xF4, 0xC5, 0xE5, 0x4C, 0x54, 0xA1, 0x55, 0x30}; + u8 can_key[AES256_KEY_LEN] = { 0 }; + + if (!can || !enc_can || !enc_can->value || enc_can->len != 24) + return SC_ERROR_INVALID_ARGUMENTS; + + if (!get_can_key(magic_key, 0x01, enc_can->value, &can_key[0])) + return SC_ERROR_INTERNAL; + if (!get_can_key(magic_key, 0x02, enc_can->value, &can_key[AES_BLOCK_SIZE])) + return SC_ERROR_INTERNAL; + + if (!aes256_ecb_decrypt(can_key, enc_can->value, (u8 *)can)) + return SC_ERROR_INTERNAL; + can[AES_BLOCK_SIZE - 1] = 0; + + return SC_SUCCESS; +} + +static int eoi_sm_open(struct sc_card *card) +{ + int r; + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + struct establish_pace_channel_input pace_input; + struct establish_pace_channel_output pace_output; + + if (!privdata) + return SC_ERROR_INTERNAL; + + if (!privdata->can[0]) { + /* If no CAN is specified in conf, try to decrypt it from enc_can file */ + r = eoi_decrypt_can(&privdata->enc_can, privdata->can); + LOG_TEST_RET(card->ctx, r, "Cannot decrypt CAN"); + } + /* CAN should be 6 chars long */ + if (strlen(privdata->can) != 6) + return SC_ERROR_DECRYPT_FAILED; + + memset(&pace_input, 0, sizeof pace_input); + memset(&pace_output, 0, sizeof pace_output); + + pace_input.pin_id = PACE_PIN_ID_CAN; + pace_input.pin = (u8 *)privdata->can; + pace_input.pin_length = strlen(privdata->can); + + /* EF.CardAccess can only be read from MF */ + r = sc_select_file(card, sc_get_mf_path(), NULL); + LOG_TEST_RET(card->ctx, r, "sc_select_file failed"); + + r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); + LOG_TEST_RET(card->ctx, r, "Error verifying CAN"); + + return SC_SUCCESS; +} + +static int eoi_get_data(sc_card_t *card, u8 data_id, u8 *buf, size_t len) +{ + int r; + sc_apdu_t apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, data_id); + apdu.resp = buf; + apdu.resplen = len; + apdu.le = len; + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + return r; +} + +#define ATR_MATCH 1 + +static int eoi_match_card(sc_card_t* card) { + LOG_FUNC_CALLED(card->ctx); + if (_sc_match_atr(card, eoi_atrs, &card->type) >= 0) { + sc_log(card->ctx, "ATR recognized as Slovenian eID card"); + LOG_FUNC_RETURN(card->ctx, ATR_MATCH); + } + LOG_FUNC_RETURN(card->ctx, !ATR_MATCH); +} + +static int eoi_init(sc_card_t* card) { + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + u8 version[6]; + size_t i, j; + scconf_block **found_blocks, *block; + int r; + char *can; + + LOG_FUNC_CALLED(card->ctx); + + if (eoi_get_data(card, 0x16, version, sizeof(version)) != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); + + if (privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + privdata = sc_mem_secure_alloc(sizeof(struct eoi_privdata)); + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + /* sc_mem_secure_alloc()-ed memory may not be zeroized */ + memset(privdata, 0, sizeof(struct eoi_privdata)); + card->drv_data = privdata; + + sprintf(privdata->version, "%X%02X.%02X%02X", version[0], version[1], version[2], version[3]); + sc_log(card->ctx, "App version: %s", privdata->version); + + memset(&card->sm_ctx, 0, sizeof card->sm_ctx); + card->sm_ctx.ops.open = eoi_sm_open; + + card->max_send_size = SC_MAX_APDU_DATA_SIZE; + card->max_recv_size = SC_MAX_APDU_RESP_SIZE; + + for (i = 0; i < sizeof eoi_curves / sizeof * eoi_curves; ++i) { + r = _sc_card_add_ec_alg(card, eoi_curves[i].len, SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE, 0, &eoi_curves[i].oid); + LOG_TEST_GOTO_ERR(card->ctx, r, "Add EC alg failed"); + } + + can = getenv("EOI_CAN"); + if (can) + strlcpy(privdata->can, can, sizeof(privdata->can)); + for (i = 0; card->ctx->conf_blocks[i]; i++) { + found_blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], + "card_driver", "eoi"); + if (!found_blocks) + continue; + + for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { + if (!privdata->can[0]) { + const char *can = scconf_get_str(block, "can", NULL); + if (can) + strlcpy(privdata->can, can, sizeof(privdata->can)); + } + } + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + +err: + if (privdata) { + sc_mem_clear(privdata, sizeof(struct eoi_privdata)); + sc_mem_secure_free(privdata, sizeof(struct eoi_privdata)); + } + card->drv_data = NULL; + + LOG_FUNC_RETURN(card->ctx, r); +} + +static int eoi_finish(sc_card_t* card) +{ + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + + LOG_FUNC_CALLED(card->ctx); + + if (privdata) { + sc_mem_clear(privdata, sizeof(struct eoi_privdata)); + sc_mem_secure_free(privdata, sizeof(struct eoi_privdata)); + } + + card->drv_data = NULL; + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +static int eoi_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) +{ + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + int i; + + LOG_FUNC_CALLED(card->ctx); + + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + for (i = 0; i < MAX_OBJECTS && privdata->pin_paths[i]; i++) { + if (privdata->pin_paths[i] && sc_compare_path(privdata->pin_paths[i], in_path)) { + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + } + + LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->select_file(card, in_path, file_out)); +} + +static int eoi_logout(struct sc_card *card) +{ + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + struct sc_apdu apdu; + u8 buf[256]; + int r = SC_SUCCESS; + + LOG_FUNC_CALLED(card->ctx); + + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + iso_sm_close(card); + card->sm_ctx.sm_mode = SM_MODE_NONE; + + if (card->reader->flags & SC_READER_ENABLE_ESCAPE) { + /* + * Get the UID of the ISO 14443 A card. (see PCSC Part 3) + * The "official" PKCS#11 does it and we do the same. + */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x00, 0x00); + apdu.cla = 0xFF; + apdu.resp = buf; + apdu.resplen = 256; + apdu.lc = 0; + apdu.le = 256; + + r = sc_transmit_apdu(card, &apdu); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + +static int eoi_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + int r; + + LOG_FUNC_CALLED(card->ctx); + + if (data->cmd == SC_PIN_CMD_VERIFY && card->sm_ctx.sm_mode == SM_MODE_NONE) { + /* Establish SM before any PIN VERIFY command */ + r = eoi_sm_open(card); + if (r != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, r); + } + + if (data->cmd == SC_PIN_CMD_UNBLOCK) { + int pin_reference = data->pin_reference; + int pin2_len = data->pin2.len; + /* Verify PUK, establish SM if necessary */ + data->cmd = SC_PIN_CMD_VERIFY; + data->pin_reference = data->puk_reference; + r = eoi_pin_cmd(card, data, tries_left); + if (r != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, r); + /* RESET RETRY COUNTER */ + data->cmd = SC_PIN_CMD_UNBLOCK; + data->pin_reference = 0x80|pin_reference; + data->pin1.len = 0; + data->pin2.len = 0; + r = sc_get_iso7816_driver()->ops->pin_cmd(card, data, tries_left); + if (r != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, r); + /* Continue as CHANGE PIN */ + data->cmd = SC_PIN_CMD_CHANGE; + data->pin2.len = pin2_len; + } + + /* CHANGE PIN command does not send the old PIN as it should already be verified */ + if (data->cmd == SC_PIN_CMD_CHANGE) + data->pin1.len = 0; + + LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->pin_cmd(card, data, tries_left)); +} + +#define ALREADY_PROCESSED 0x80000000 + +static int eoi_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) +{ + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + struct sc_apdu apdu; + u8 sbuf[4]; + int i, r, locked = 0; + + LOG_FUNC_CALLED(card->ctx); + + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + if (!card || !env) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + /* We don't know yet which hash is used. So just store the security_env data and return */ + if (!(env->algorithm_flags & ALREADY_PROCESSED)) { + privdata->key_len = (env->algorithm_ref + 7)/8; + memcpy(&privdata->sec_env, env, sizeof(struct sc_security_env)); + privdata->se_num = se_num; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + + if (env->operation != SC_SEC_OPERATION_SIGN) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + if (env->key_ref_len != 1) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + if (env->algorithm != SC_ALGORITHM_EC) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x81, 0xB6); + sbuf[0] = 0x91; + sbuf[1] = 0x02; + if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) + sbuf[2] = 0x11; + else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) + sbuf[2] = 0x21; + else if (env->algorithm_flags & (SC_ALGORITHM_ECDSA_RAW|SC_ALGORITHM_ECDSA_HASH_NONE)) + sbuf[2] = 0x22; + else + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + for (i = 0; i < MAX_OBJECTS && privdata->prkey_mappings[i][1]; i++) { + if (privdata->prkey_mappings[i][0] == env->key_ref[0]) + break; + } + if (i == MAX_OBJECTS) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + sbuf[3] = privdata->prkey_mappings[i][1]; + apdu.lc = 4; + apdu.datalen = 4; + apdu.data = sbuf; + if (se_num > 0) { + r = sc_lock(card); + LOG_TEST_RET(card->ctx, r, "sc_lock() failed"); + locked = 1; + } + if (apdu.datalen) { + r = sc_transmit_apdu(card, &apdu); + if (r) { + sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r)); + goto err; + } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) { + sc_log(card->ctx, "%s: Card returned error", sc_strerror(r)); + goto err; + } + } + if (se_num <= 0) { + r = SC_SUCCESS; + goto err; + } + sc_unlock(card); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +err: + if (locked) + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, r); +} + +static int eoi_compute_signature(struct sc_card *card, const u8 * data, size_t data_len, u8 *out, size_t outlen) +{ + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + int r; + + LOG_FUNC_CALLED(card->ctx); + + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + /* + * Guess the correct mode. If the size is less than the full-key-len, it must be a hash then + */ + if (privdata->key_len != data_len) { + switch (data_len) { + case SHA_DIGEST_LENGTH: + privdata->sec_env.algorithm_flags = SC_ALGORITHM_ECDSA_HASH_SHA1; + break; + case SHA256_DIGEST_LENGTH: + privdata->sec_env.algorithm_flags = SC_ALGORITHM_ECDSA_HASH_SHA256; + break; + } + } + /* Now we know which hash is used */ + privdata->sec_env.algorithm_flags |= ALREADY_PROCESSED; + + /* Perform the true set_security_env */ + r = eoi_set_security_env(card, &privdata->sec_env, privdata->se_num); + LOG_TEST_RET(card->ctx, r, "set_security_env failed"); + + LOG_FUNC_RETURN(card->ctx, sc_get_iso7816_driver()->ops->compute_signature(card, data, data_len, out, outlen)); +} + +struct sc_card_driver *sc_get_eoi_driver(void) +{ + eoi_ops = *sc_get_iso7816_driver()->ops; + + eoi_ops.match_card = eoi_match_card; + eoi_ops.init = eoi_init; + eoi_ops.finish = eoi_finish; + eoi_ops.select_file = eoi_select_file; + eoi_ops.logout = eoi_logout; + eoi_ops.pin_cmd = eoi_pin_cmd; + eoi_ops.set_security_env = eoi_set_security_env; + eoi_ops.compute_signature = eoi_compute_signature; + + return &eoi_drv; +} + +#else + +struct sc_card_driver* sc_get_eoi_driver(void) { + return NULL; +} + +#endif diff --git a/src/libopensc/card-eoi.h b/src/libopensc/card-eoi.h new file mode 100644 index 0000000000..3f5da8defb --- /dev/null +++ b/src/libopensc/card-eoi.h @@ -0,0 +1,41 @@ +/* + * Support for the eOI card + * + * Copyright (C) 2022 Luka Logar + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "pkcs15.h" + +#define MAX_OBJECTS 8 + +struct eoi_privdata { + /* App version */ + char version[10]; + /* Serial + encrypted CAN */ + struct sc_pkcs15_u8 enc_can; + /* CAN from the conf file */ + char can[AES_BLOCK_SIZE]; + /* Cached data for signing operation */ + size_t key_len; + struct sc_security_env sec_env; + int se_num; + /* PINs that shouldn't report an error when selected */ + struct sc_path *pin_paths[MAX_OBJECTS]; + /* PrKey reference to eOI mappings */ + int prkey_mappings[MAX_OBJECTS][2]; +}; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 2c408c0711..64b550ce68 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -274,7 +274,11 @@ enum { /* Slovak eID cards */ SC_CARD_TYPE_SKEID_BASE = 40000, - SC_CARD_TYPE_SKEID_V3 + SC_CARD_TYPE_SKEID_V3, + + /* eOI cards */ + SC_CARD_TYPE_EOI = 41000, + SC_CARD_TYPE_EOI_CONTACTLESS }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -320,6 +324,7 @@ extern sc_card_driver_t *sc_get_idprime_driver(void); extern sc_card_driver_t *sc_get_edo_driver(void); extern sc_card_driver_t *sc_get_nqApplet_driver(void); extern sc_card_driver_t *sc_get_skeid_driver(void); +extern sc_card_driver_t *sc_get_eoi_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 78d119b7de..27987c3e95 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -154,6 +154,9 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "npa", (void *(*)(void)) sc_get_npa_driver }, { "cac1", (void *(*)(void)) sc_get_cac1_driver }, { "nqapplet", (void *(*)(void)) sc_get_nqApplet_driver }, +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) + { "eOI", (void *(*)(void)) sc_get_eoi_driver }, +#endif /* The default driver should be last, as it handles all the * unrecognized cards. */ { "default", (void *(*)(void)) sc_get_default_driver }, diff --git a/src/libopensc/pkcs15-eoi.c b/src/libopensc/pkcs15-eoi.c new file mode 100644 index 0000000000..e39a3b8963 --- /dev/null +++ b/src/libopensc/pkcs15-eoi.c @@ -0,0 +1,146 @@ +/* + * Support for the eOI card. + * + * Copyright (C) 2022 Luka Logar + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "log.h" +#include "pkcs15.h" + +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) + +#include "cards.h" +#include "card-eoi.h" + +int sc_pkcs15emu_eoi_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) +{ + struct sc_card *card = p15card->card; + struct eoi_privdata *privdata = (struct eoi_privdata *)card->drv_data; + struct sc_pkcs15_search_key sk; + struct sc_pkcs15_object *objs[MAX_OBJECTS]; + int i, j, len; + + LOG_FUNC_CALLED(card->ctx); + + if (card->type != SC_CARD_TYPE_EOI && card->type != SC_CARD_TYPE_EOI_CONTACTLESS) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); + + if (!privdata) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + + /* + * Some of the data is not accessible over the unencrypted channel + * when contactless reader is used. So start SM now (if not yet establisahed). + */ + if (card->type == SC_CARD_TYPE_EOI_CONTACTLESS && card->sm_ctx.sm_mode == SM_MODE_NONE) { + int r = card->sm_ctx.ops.open(card); + if (r != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, r); + } + + /* + * Get the card objects, so we can manipulate them. See below + */ + LOG_TEST_RET(card->ctx, sc_pkcs15_bind_internal(p15card, aid), + "sc_pkcs15_bind_internal failed"); + + /* + * PIN objects: + * 1) Find the "Card CAN" PIN and store it's path, so we'll be able to fetch the CAN and do the PACE auth + * 2) Add PIN's auth_info->path to the list of paths that can fail on select. sc_pin_cmd would break otherwise + */ + memset(&sk, 0, sizeof(sk)); + sk.class_mask = SC_PKCS15_SEARCH_CLASS_AUTH; + len = sc_pkcs15_search_objects(p15card, &sk, (struct sc_pkcs15_object **)&objs, MAX_OBJECTS); + for (i = 0, j = 0; i < len; i++) { + struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)objs[i]->data; + if (auth_info && auth_info->auth_id.len == 8 && !strcmp((char*)auth_info->auth_id.value, "Card CAN")) { + auth_info->path.type = SC_PATH_TYPE_PATH; + /* Read the file that contains serial and encrypted CAN */ + if (sc_pkcs15_read_file(p15card, &auth_info->path, &privdata->enc_can.value, &privdata->enc_can.len, 0) == SC_SUCCESS) { + /* File should be 24 bytes long */ + if (privdata->enc_can.len != 24) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CORRUPTED_DATA); + if (strlen(p15card->tokeninfo->serial_number) != 20) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_CORRUPTED_DATA); + /* First 8 bytes are used as serial number */ + sc_bin_to_hex(privdata->enc_can.value, 8, &p15card->tokeninfo->serial_number[4], 17, 0); + } + /* Do not add "Card CAN" to the list of PIN paths to ignore, otherwise the 2nd PKCS#15 app can not access it */ + auth_info = NULL; + /* Mark "Card CAN" as NOT a PIN object, so that it doesn't get it's own PKCS#11 slot */ + objs[i]->type &= ~SC_PKCS15_TYPE_AUTH_PIN; + } + /* + * For some reason QES app has "Norm PUK" not flagged as unblocking PIN and thus "Norm PUK" appears as a slot in + * PKCS#11. Flag it as unblockingPin, so it doesn't appear as a separate slot. + */ + if (auth_info && auth_info->auth_id.len == 8 && !strcmp((char*)auth_info->auth_id.value, "Norm PUK")) { + auth_info->attrs.pin.flags |= SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN; + } + if (auth_info) { + privdata->pin_paths[j++] = &auth_info->path; + } + } + + /* + * Private key objects: + * 1) Rename "Card PIN" to "Norm PIN" as it's the later name that is used throughout the PKCS#15 objects + * 2) Add the key references to the prkey_mappings array, as it seems that eOI expects them counted from 0xA0 up (starting from 1 within each app) + * Currently there are 3 private keys on the card + * key_ref + * 2 - for pinless entry (Prijava brez PIN-a), maps to 0xA1 + * 1 - for authentication in QES app (Podpis in prijava), maps to 0xA1 + * 3 - for signing in QES app (Podpis in prijava), maps to 0xA2 + */ + memset(&sk, 0, sizeof(sk)); + sk.class_mask = SC_PKCS15_SEARCH_CLASS_PRKEY; + len = sc_pkcs15_search_objects(p15card, &sk, (struct sc_pkcs15_object **)&objs, MAX_OBJECTS); + /* + * If both PKCS#15 apps are enabled, prkey_mappings can already be partially filled up from the first PKCS#15 app + * as the privdata is shared between both apps which use the same driver + */ + for (j = 0; privdata->prkey_mappings[j][1] != 0; j++) { + /* NOP */ + } + for (i = 0; i < len; i++) { + struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)objs[i]->data; + if ((objs[i]->auth_id.len == 8) && !strncmp((char*)objs[i]->auth_id.value, "Card PIN", 8)) { + memcpy(objs[i]->auth_id.value, "Norm PIN", 8); + } + if (prkey_info) { + privdata->prkey_mappings[j][0] = prkey_info->key_reference; + privdata->prkey_mappings[j++][1] = 0xA0 + (i + 1); + } + } + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + +#else + +int sc_pkcs15emu_eoi_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) +{ + LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_WRONG_CARD); +} + +#endif diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 719525bbc0..cd2c13fdf4 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -60,6 +60,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { { "cardos", sc_pkcs15emu_cardos_init_ex }, { "nqapplet", sc_pkcs15emu_nqapplet_init_ex }, { "esign", sc_pkcs15emu_starcos_esign_init_ex }, + { "eOI", sc_pkcs15emu_eoi_init_ex }, { NULL, NULL } }; @@ -111,7 +112,8 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) case SC_CARD_TYPE_STARCOS_V3_4_ESIGN: case SC_CARD_TYPE_STARCOS_V3_5_ESIGN: case SC_CARD_TYPE_SKEID_V3: - + case SC_CARD_TYPE_EOI: + case SC_CARD_TYPE_EOI_CONTACTLESS: return 1; default: return 0; diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index a853320af4..d4964ca6d1 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -58,6 +58,7 @@ int sc_pkcs15emu_cardos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_nqapplet_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_starcos_esign_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); int sc_pkcs15emu_skeid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); +int sc_pkcs15emu_eoi_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); struct sc_pkcs15_emulator_handler { const char *name; From fd474fb7a1de7494c513b4b5df8bd6b135e79cea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Mar 2023 10:33:02 +0100 Subject: [PATCH 2823/4321] log errors for sc_unlock --- src/libopensc/card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 7b0ebc8019..2e1c773b9f 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -531,10 +531,10 @@ int sc_unlock(sc_card_t *card) r = sc_mutex_lock(card->ctx, card->mutex); if (r != SC_SUCCESS) - return r; + LOG_FUNC_RETURN(card->ctx, r); if (card->lock_count < 1) { - return SC_ERROR_INVALID_ARGUMENTS; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } if (--card->lock_count == 0) { if (card->flags & SC_CARD_FLAG_KEEP_ALIVE) { From b9d5ac45f111910fc9e32600ce26b58350c81790 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Mar 2023 15:13:39 +0100 Subject: [PATCH 2824/4321] pkcs#11: fixed multiple race conditions during C_Initialize --- src/pkcs11/pkcs11-global.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index cbc7445bb9..8767bd6df2 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -291,27 +291,31 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { CK_RV rv; #if !defined(_WIN32) - pid_t current_pid = getpid(); + pid_t current_pid; #endif int rc; sc_context_param_t ctx_opts; #if !defined(_WIN32) /* Handle fork() exception */ + C_INITIALIZE_M_LOCK + current_pid = getpid(); if (current_pid != initialized_pid) { - if (context) + if (context && CKR_OK == sc_pkcs11_lock()) { context->flags |= SC_CTX_FLAG_TERMINATE; + sc_pkcs11_unlock(); + } C_Finalize(NULL_PTR); } initialized_pid = current_pid; in_finalize = 0; + C_INITIALIZE_M_UNLOCK #endif /* protect from nesting */ C_INITIALIZE_M_LOCK nesting++; if (nesting > 1) { - sc_log(context, "C_Initialize(): Nested init detected"); nesting--; C_INITIALIZE_M_UNLOCK return CKR_GENERAL_ERROR; @@ -323,7 +327,10 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) C_INITIALIZE_M_LOCK if (context != NULL) { - sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); + if (CKR_OK == sc_pkcs11_lock()) { + sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); + sc_pkcs11_unlock(); + } nesting--; C_INITIALIZE_M_UNLOCK return CKR_CRYPTOKI_ALREADY_INITIALIZED; From d449feeda6b3d8ec27a184417d9b5d1ba73df6d7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 23 Mar 2023 16:16:35 +0100 Subject: [PATCH 2825/4321] fixed race conditions in sc_lock() card->mutex is used to protect card->lock_count, so let's limit the scope of the mutex to where the lock_count is used. First and foremost, this fixes https://github.com/OpenSC/OpenSC/issues/2707, which is caused by PIV's failing card_reader_lock_obtained, which would have caused sc_lock to change lock_count while *not* locking the mutex, which creates a race condition with other threads using and modifying lock_count. Secondly, this fixes a possible dead lock when sc_lock is used inside the card's card->sm_ctx.ops.open, which previously would be called in sc_lock when the mutex was locked. --- src/libopensc/card.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 2e1c773b9f..5cdc302fff 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -491,6 +491,12 @@ int sc_lock(sc_card_t *card) if (r == 0) card->lock_count++; + r2 = sc_mutex_unlock(card->ctx, card->mutex); + if (r2 != SC_SUCCESS) { + sc_log(card->ctx, "unable to release card->mutex lock"); + r = r != SC_SUCCESS ? r : r2; + } + if (r == 0 && was_reset > 0) { #ifdef ENABLE_SM if (card->sm_ctx.ops.open) @@ -498,23 +504,10 @@ int sc_lock(sc_card_t *card) #endif } - r2 = sc_mutex_unlock(card->ctx, card->mutex); - if (r2 != SC_SUCCESS) { - sc_log(card->ctx, "unable to release card->mutex lock"); - r = r != SC_SUCCESS ? r : r2; - } - /* give card driver a chance to do something when reader lock first obtained */ if (r == 0 && reader_lock_obtained == 1 && card->ops->card_reader_lock_obtained) { - r = card->ops->card_reader_lock_obtained(card, was_reset); - /* return value of card->reader->ops->lock is overwritten here - by card->ops->card_reader_lock_obtained */ - if (r != 0) { - /* unlock reader and get the card to its original state in case of failure*/ - if (card->reader->ops->unlock != NULL) - r = card->reader->ops->unlock(card->reader); - card->lock_count--; - } + if (SC_SUCCESS != card->ops->card_reader_lock_obtained(card, was_reset)) + sc_log(card->ctx, "card_reader_lock_obtained failed"); } LOG_FUNC_RETURN(card->ctx, r); From cf753d53b07b28f2a89ac51be29c42519afec143 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Mar 2023 15:25:56 +0100 Subject: [PATCH 2826/4321] pkcs11-tool: allow interactive thread tests Threads can now run the same tests as if pkcs11-tool was started with `--test`, e.g. ``` pkcs11-tool --use-locking --pin=123456 --test-threads LT --test-threads LT ``` --- src/tools/pkcs11-tool.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index e964c2f774..145e4e68f0 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1175,11 +1175,6 @@ int main(int argc, char * argv[]) if (do_list_interfaces) list_interfaces(); -#if defined(_WIN32) || defined(HAVE_PTHREAD) - if (do_test_threads) - test_threads(); -#endif - rv = p11->C_Initialize(c_initialize_args_ptr); #if defined(_WIN32) || defined(HAVE_PTHREAD) @@ -1506,8 +1501,13 @@ int main(int argc, char * argv[]) } #if defined(_WIN32) || defined(HAVE_PTHREAD) - if (do_test_threads) + if (do_test_threads) { + /* running threading tests is deliberately placed after opt_slot was + * initialized so that the command line options allow detailed + * configuration when running with `--test-threads LT` */ + test_threads(); test_threads_cleanup(); + } #endif /* defined(_WIN32) || defined(HAVE_PTHREAD) */ if (p11) @@ -1847,7 +1847,7 @@ static int login(CK_SESSION_HANDLE session, int login_type) rv = p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin)); - if (rv != CKR_OK) + if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) p11_fatal("C_Login", rv); if (pin_allocated) free(pin); @@ -8570,8 +8570,8 @@ static void * test_threads_run(void * pttd) #endif } - /* IN - C_Initialize with NULL args */ else if (*pctest == 'I') { + /* IN - C_Initialize with NULL args */ if (*(pctest + 1) == 'N') { fprintf(stderr, "Test thread %d C_Initialize(NULL)\n", ttd->tnum); rv = p11->C_Initialize(NULL); @@ -8635,6 +8635,24 @@ static void * test_threads_run(void * pttd) } } + /* LT login and test, just like as if `--login --test` was specified. + * May be combined with `--pin=123456` */ + else if (*pctest == 'L' && *(pctest + 1) == 'T') { + CK_SESSION_HANDLE session = CK_INVALID_HANDLE; + + rv = p11->C_OpenSession(opt_slot, CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL, NULL, &session); + if (rv == CKR_OK) { + if (opt_login_type == -1) + opt_login_type = CKU_USER; + login(session, opt_login_type); + + if (p11_test(session)) + rv = CKR_GENERAL_ERROR; + else + rv = CKR_OK; + } + } + else { err: rv = CKR_GENERAL_ERROR; /* could be vendor error, */ From ee7fb476d6c72fc53cf6d844be24a4f42a4e9cb5 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Mar 2023 16:40:17 +0100 Subject: [PATCH 2827/4321] pkcs#11: fixed race condition in C_GetTokenInfo --- src/pkcs11/framework-pkcs15.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 33fdac4308..f9b9b23642 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -552,13 +552,13 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) const char *name; CK_RV rv; - sc_log(context, "C_GetTokenInfo(%lx)", slotID); if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; + sc_log(context, "C_GetTokenInfo(%lx)", slotID); rv = slot_get_token(slotID, &slot); if (rv != CKR_OK) { @@ -610,14 +610,15 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) } } memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO)); -out: - sc_pkcs11_unlock(); +out: name = lookup_enum(RV_T, rv); if (name) sc_log(context, "C_GetTokenInfo(%lx) returns %s", slotID, name); else sc_log(context, "C_GetTokenInfo(%lx) returns 0x%08lX", slotID, rv); + sc_pkcs11_unlock(); + return rv; } From 22aa65ca51674f0c2921aa4d8a2b5d9e4ff549a8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Mar 2023 16:45:30 +0100 Subject: [PATCH 2828/4321] pkcs#11: fixed race condition in C_GenerateRandom --- src/pkcs11/pkcs11-object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 07cd57eb57..b7c31c4cb3 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -1448,8 +1448,8 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */ rv = slot->p11card->framework->get_random(slot, RandomData, ulRandomLen); } - sc_pkcs11_unlock(); SC_LOG_RV("C_GenerateRandom() = %s", rv); + sc_pkcs11_unlock(); return rv; } From 7b1729a1bc69f3139500246d807098d43994cbc4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Mar 2023 16:59:21 +0100 Subject: [PATCH 2829/4321] pkcs11-tool: fixed race condition for loading openssl's legacy provider --- src/tools/pkcs11-tool.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 145e4e68f0..49f832893d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -765,6 +765,7 @@ int main(int argc, char * argv[]) if (!(default_provider = OSSL_PROVIDER_load(osslctx, "default"))) { util_fatal("Failed to load OpenSSL \"default\" provider\n"); } + legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1); #endif while (1) { @@ -6040,10 +6041,8 @@ static int test_digest(CK_SESSION_HANDLE session) #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { - printf("Failed to load legacy provider\n"); - return errors; - } + printf("Failed to load legacy provider\n"); + return errors; } #endif for (; mechTypes[i] != 0xffffff; i++) { @@ -6247,10 +6246,8 @@ static int sign_verify_openssl(CK_SESSION_HANDLE session, #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(OPENSSL_NO_RIPEMD) if (!legacy_provider) { - if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { - printf("Failed to load legacy provider"); - return errors; - } + printf("Failed to load legacy provider"); + return errors; } #endif From aa394f2576adf9950d98f4994e7680574139854b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 24 Mar 2023 17:16:31 +0100 Subject: [PATCH 2830/4321] pkcs11-tool: fixed race condition in --test-threads --- src/tools/pkcs11-tool.c | 61 +++-------------------------------------- 1 file changed, 4 insertions(+), 57 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 49f832893d..4d14ba687f 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -456,8 +456,6 @@ static pthread_t test_threads_handles[MAX_TEST_THREADS]; struct test_threads_data { int tnum; char * tests; - volatile int state; - volatile CK_RV rv; }; static struct test_threads_data test_threads_datas[MAX_TEST_THREADS]; static int test_threads_num = 0; @@ -8539,11 +8537,9 @@ static DWORD WINAPI test_threads_run(_In_ LPVOID pttd) static void * test_threads_run(void * pttd) #endif { - int r = 0; CK_RV rv = CKR_OK; CK_INFO info; int l_slots = 0; - int state = 0; CK_ULONG l_p11_num_slots = 0; CK_SLOT_ID_PTR l_p11_slots = NULL; char * pctest; @@ -8555,8 +8551,6 @@ static void * test_threads_run(void * pttd) /* series of two character commands */ while (pctest && *pctest && *(pctest + 1)) { - ttd->state = state++; - /* Pn - pause where n is 0 to 9 iseconds */ if (*pctest == 'P' && *(pctest + 1) >= '0' && *(pctest + 1) <= '9') { fprintf(stderr, "Test thread %d pauseing for %d seconds\n", ttd->tnum, (*(pctest + 1) - '0')); @@ -8572,14 +8566,12 @@ static void * test_threads_run(void * pttd) if (*(pctest + 1) == 'N') { fprintf(stderr, "Test thread %d C_Initialize(NULL)\n", ttd->tnum); rv = p11->C_Initialize(NULL); - ttd->rv = rv; fprintf(stderr, "Test thread %d C_Initialize returned %s\n", ttd->tnum, CKR2Str(rv)); } /* IL C_Initialize with CKF_OS_LOCKING_OK */ else if (*(pctest + 1) == 'L') { fprintf(stderr, "Test thread %d C_Initialize CKF_OS_LOCKING_OK \n", ttd->tnum); rv = p11->C_Initialize(&c_initialize_args_OS); - ttd->rv = rv; fprintf(stderr, "Test thread %d C_Initialize returned %s\n", ttd->tnum, CKR2Str(rv)); } else @@ -8590,7 +8582,6 @@ static void * test_threads_run(void * pttd) else if (*pctest == 'G' && *(pctest + 1) == 'I') { fprintf(stderr, "Test thread %d C_GetInfo\n", ttd->tnum); rv = p11->C_GetInfo(&info); - ttd->rv = rv; fprintf(stderr, "Test thread %d C_GetInfo returned %s\n", ttd->tnum, CKR2Str(rv)); } @@ -8598,7 +8589,6 @@ static void * test_threads_run(void * pttd) else if (*pctest == 'S' && *(pctest + 1) == 'L') { fprintf(stderr, "Test thread %d C_GetSlotList to get l_p11_num_slots\n", ttd->tnum); rv = p11->C_GetSlotList(1, NULL, &l_p11_num_slots); - ttd->rv = rv; fprintf(stderr, "Test thread %d C_GetSlotList returned %s\n", ttd->tnum, CKR2Str(rv)); fprintf(stderr, "Test thread %d l_p11_num_slots:%ld\n", ttd->tnum, l_p11_num_slots); if (rv == CKR_OK) { @@ -8611,7 +8601,6 @@ static void * test_threads_run(void * pttd) } fprintf(stderr, "Test thread %d C_GetSlotList\n", ttd->tnum); rv = p11->C_GetSlotList(1, l_p11_slots, &l_p11_num_slots); - ttd->rv = rv; fprintf(stderr, "Test thread %d C_GetSlotList returned %s\n", ttd->tnum, CKR2Str(rv)); fprintf(stderr, "Test thread %d l_p11_num_slots:%ld\n", ttd->tnum, l_p11_num_slots); if (rv == CKR_OK && l_p11_num_slots && l_p11_slots) @@ -8653,7 +8642,6 @@ static void * test_threads_run(void * pttd) else { err: rv = CKR_GENERAL_ERROR; /* could be vendor error, */ - ttd->rv = rv; fprintf(stderr, "Test thread %d Unknown test '%c%c'\n", ttd->tnum, *pctest, *(pctest + 1)); break; } @@ -8671,9 +8659,7 @@ static void * test_threads_run(void * pttd) } free(l_p11_slots); - fprintf(stderr, "Test thread %d returning rv = %d\n", ttd->tnum, r); - ttd->state = -1; /* done */ - ttd->rv = rv; + fprintf(stderr, "Test thread %d returning rv:%s\n", ttd->tnum, CKR2Str(rv)); #ifdef _WIN32 ExitThread(0); #else @@ -8684,55 +8670,16 @@ static void * test_threads_run(void * pttd) static int test_threads_cleanup() { - int i, j; - int ended = 0; - int ended_ok = 0; + int i; fprintf(stderr,"test_threads cleanup starting\n"); - for (j = 0; j < 4; j++) { - ended = 0; - ended_ok = 0; - - for (i = 0; i < test_threads_num; i++) { - if (test_threads_datas[i].state == -1) { - ended++; - } - if (test_threads_datas[i].rv == CKR_OK) { - ended_ok++; - } - } - - if (ended == test_threads_num) { - fprintf(stderr,"test_threads all threads have ended %s\n", - (ended_ok == test_threads_num)? "with CKR_OK": "some errors"); - break; - } else { - fprintf(stderr,"test_threads threads stills active:%d\n", (test_threads_num - ended)); - for (i = 0; i < test_threads_num; i++) { - fprintf(stderr,"test_threads thread:%d state:%d, rv:%s\n", - i, test_threads_datas[i].state, CKR2Str(test_threads_datas[i].rv)); - } - fprintf(stderr,"\ntest_threads waiting for 30 seconds ...\n"); -#ifdef _WIN32 - Sleep(30*1000); -#else - sleep(30); -#endif - } - } for (i = 0; i < test_threads_num; i++) { - fprintf(stderr,"test_threads thread:%d state:%d, rv:%s\n", - i, test_threads_datas[i].state, CKR2Str(test_threads_datas[i].rv)); - if (test_threads_datas[i].state == -1) { #ifdef _WIN32 - TerminateThread(test_threads_handles[i], 0); + WaitForSingleObject(test_threads_handles[i], INFINITE); #else - pthread_join(test_threads_handles[i], NULL); - } else { - pthread_cancel(test_threads_handles[i]); + pthread_join(test_threads_handles[i], NULL); #endif - } } fprintf(stderr,"test_threads cleanup finished\n"); From 3f485ff28cecf0cdddecef369442df2efed80a99 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Apr 2023 21:51:19 +0200 Subject: [PATCH 2831/4321] pgp: avoid calling functions without prototype which is deprecated in all versions of C --- src/libopensc/card-openpgp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index fad32f0ce7..e4e6cc4d20 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -129,7 +129,7 @@ static pgp_ec_curves_t ec_curves_gnuk[] = { static int pgp_get_card_features(sc_card_t *card); static int pgp_finish(sc_card_t *card); -static void pgp_iterate_blobs(pgp_blob_t *, void (*func)()); +static void pgp_free_blobs(pgp_blob_t *); static int pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, unsigned int id, pgp_blob_t **ret); @@ -947,7 +947,7 @@ pgp_finish(sc_card_t *card) if (priv != NULL) { /* delete fake file hierarchy */ - pgp_iterate_blobs(priv->mf, pgp_free_blob); + pgp_free_blobs(priv->mf); /* delete private data */ free(priv); @@ -1147,10 +1147,10 @@ pgp_free_blob(pgp_blob_t *blob) /** - * Internal: iterate through the blob tree, calling a function for each blob. + * Internal: iterate through the blob tree, calling pgp_free_blob for each blob. */ static void -pgp_iterate_blobs(pgp_blob_t *blob, void (*func)()) +pgp_free_blobs(pgp_blob_t *blob) { if (blob) { pgp_blob_t *child = blob->files; @@ -1158,10 +1158,10 @@ pgp_iterate_blobs(pgp_blob_t *blob, void (*func)()) while (child != NULL) { pgp_blob_t *next = child->next; - pgp_iterate_blobs(child, func); + pgp_free_blobs(child); child = next; } - func(blob); + pgp_free_blob(blob); } } From 076567a9cf16a9cc2dbda4b57d65d970ce624ae9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 13 Apr 2023 15:54:23 +0200 Subject: [PATCH 2832/4321] pkcs11-tool: accumulate all errors when testing C_GenerateRandom fixes warning about unused variable --- src/tools/pkcs11-tool.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4d14ba687f..667c7c123c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7375,31 +7375,31 @@ static int test_random(CK_SESSION_HANDLE session) printf(" seeding (C_SeedRandom) not supported\n"); else if (rv != CKR_OK) { p11_perror("C_SeedRandom", rv); - return 1; + errors++; } rv = p11->C_GenerateRandom(session, buf1, 10); if (rv != CKR_OK) { p11_perror("C_GenerateRandom", rv); - return 1; + errors++; } rv = p11->C_GenerateRandom(session, buf1, 100); if (rv != CKR_OK) { p11_perror("C_GenerateRandom(buf1,100)", rv); - return 1; + errors++; } rv = p11->C_GenerateRandom(session, buf1, 0); if (rv != CKR_OK) { p11_perror("C_GenerateRandom(buf1,0)", rv); - return 1; + errors++; } rv = p11->C_GenerateRandom(session, buf2, 100); if (rv != CKR_OK) { p11_perror("C_GenerateRandom(buf2,100)", rv); - return 1; + errors++; } if (memcmp(buf1, buf2, 100) == 0) { @@ -7407,9 +7407,10 @@ static int test_random(CK_SESSION_HANDLE session) errors++; } - printf(" seems to be OK\n"); + if (!errors) + printf(" seems to be OK\n"); - return 0; + return errors; } static int test_card_detection(int wait_for_event) From 01acc11439d92e537dc2d61b6b5d50e604cf5dc4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 11 Apr 2023 15:22:58 +0200 Subject: [PATCH 2833/4321] iso7816: Fixed reading with discretionary data object fixes https://github.com/OpenSC/OpenSC/issues/2738 --- src/libopensc/iso7816.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index af84e8a171..b606dbac5b 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -167,7 +167,7 @@ iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t coun const struct sc_asn1_entry c_asn1_do_data[] = { { "Offset Data Object", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x14, SC_ASN1_OPTIONAL, NULL, NULL }, - { "Discretionary Data Object", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x13, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL }, + { "Discretionary Data Object", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x13, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED|SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; @@ -213,6 +213,9 @@ int decode_do_data(struct sc_context *ctx, sc_asn1_decode(ctx, asn1_do_data, encoded_data, encoded_data_len, NULL, NULL), "sc_asn1_decode() failed"); + if (!(asn1_do_data[1].flags & SC_ASN1_PRESENT)) + return SC_ERROR_INVALID_ASN1_OBJECT; + return SC_SUCCESS; } From 9d18f3dd71ae878a4a33727222e0106ba72fed9b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 11 Apr 2023 21:03:18 +0200 Subject: [PATCH 2834/4321] iso7816: fixed APDU case for read record with DO --- src/libopensc/iso7816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index b606dbac5b..80a6885d62 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -242,7 +242,7 @@ iso7816_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int idx, r = encode_do_data(card->ctx, idx, NULL, 0, &encoded_data, &encoded_data_len); LOG_TEST_GOTO_ERR(card->ctx, r, "Could not encode data objects"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB3, rec_nr, 0); + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB3, rec_nr, 0); apdu.lc = encoded_data_len; apdu.datalen = encoded_data_len; apdu.data = encoded_data; From cbf4ecdce87a3ce2a706496720802c21d97d1699 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Apr 2023 23:23:07 +0200 Subject: [PATCH 2835/4321] sc_read_binary/record: only require the first command to succeed If some subsequent APDU fails, we relax and just return what we've successfully read hoping that this will be enough to proceed. --- src/libopensc/card.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5cdc302fff..5822747922 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -652,6 +652,12 @@ int sc_read_binary(sc_card_t *card, unsigned int idx, r = card->ops->read_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; + if (r < 0 && todo != count) { + /* the last command failed, but previous ones succeeded. + * Let's just return what we've successfully read. */ + sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r); + break; + } if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { /* `idx + r` or `todo - r` would overflow */ @@ -970,6 +976,12 @@ int sc_read_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, r = card->ops->read_record(card, rec_nr, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; + if (r < 0 && todo != count) { + /* the last command failed, but previous ones succeeded. + * Let's just return what we've successfully read. */ + sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r); + break; + } if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { /* `idx + r` or `todo - r` would overflow */ r = SC_ERROR_OFFSET_TOO_LARGE; From ee578a10669f9ede73e7325c0c5312aa96684faa Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Apr 2023 23:36:32 +0200 Subject: [PATCH 2836/4321] implemented __builtin_zuadd_overflow --- src/common/compat_overflow.c | 1 + src/common/compat_overflow.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/common/compat_overflow.c b/src/common/compat_overflow.c index cb402bfc5a..3a30802b6a 100644 --- a/src/common/compat_overflow.c +++ b/src/common/compat_overflow.c @@ -41,4 +41,5 @@ ADD_OVERFLOW(__builtin_uadd_overflow, unsigned, UINT_MAX) ADD_OVERFLOW(__builtin_uaddl_overflow, unsigned long, ULONG_MAX) ADD_OVERFLOW(__builtin_uaddll_overflow, unsigned long long, ULLONG_MAX) +ADD_OVERFLOW(__builtin_zuadd_overflow, size_t, SIZE_MAX) #endif diff --git a/src/common/compat_overflow.h b/src/common/compat_overflow.h index 49bb52c240..14e2b4759a 100644 --- a/src/common/compat_overflow.h +++ b/src/common/compat_overflow.h @@ -33,6 +33,12 @@ bool __builtin_uadd_overflow (unsigned x, unsigned y, unsigned *sum); bool __builtin_uaddl_overflow (unsigned long x, unsigned long y, unsigned long *sum); bool __builtin_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *sum); + +bool __builtin_zuadd_overflow (size_t x, size_t y, size_t *sum); +#else + +#define __builtin_zuadd_overflow __builtin_add_overflow + #endif /* TODO bool __builtin_usub_overflow (unsigned x, unsigned y, unsigned *diff); From dec16d62cafc036ac882e62c2a6234019e1f0704 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Apr 2023 23:42:04 +0200 Subject: [PATCH 2837/4321] avoid hiding errors in card commands with SC_ERROR_OFFSET_TOO_LARGE --- src/libopensc/card.c | 58 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5822747922..5a5adb8e35 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -658,15 +658,15 @@ int sc_read_binary(sc_card_t *card, unsigned int idx, sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r); break; } - if ((idx > SIZE_MAX - (size_t) r) - || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; buf += (size_t) r; @@ -706,15 +706,15 @@ int sc_write_binary(sc_card_t *card, unsigned int idx, r = card->ops->write_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; - if ((idx > SIZE_MAX - (size_t) r) - || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; buf += (size_t) r; @@ -762,15 +762,15 @@ int sc_update_binary(sc_card_t *card, unsigned int idx, r = card->ops->update_binary(card, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; - if ((idx > SIZE_MAX - (size_t) r) - || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; buf += (size_t) r; @@ -808,15 +808,15 @@ int sc_erase_binary(struct sc_card *card, unsigned int idx, size_t count, unsig r = card->ops->erase_binary(card, idx, todo, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; - if ((idx > SIZE_MAX - (size_t) r) - || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; idx += (size_t) r; @@ -982,14 +982,15 @@ int sc_read_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r); break; } - if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; buf += (size_t) r; @@ -1070,14 +1071,15 @@ int sc_update_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx, r = card->ops->update_record(card, rec_nr, idx, buf, chunk, flags); if (r == 0 || r == SC_ERROR_FILE_END_REACHED) break; - if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { - /* `idx + r` or `todo - r` would overflow */ - r = SC_ERROR_OFFSET_TOO_LARGE; - } if (r < 0) { sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } + if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) { + /* `idx + r` or `todo - r` would overflow */ + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE); + } todo -= (size_t) r; buf += (size_t) r; From 4e9f4e0ed2955b4ab52f829309ef51d8900564f9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 14 Apr 2023 12:02:54 +0200 Subject: [PATCH 2838/4321] openpgp: identify OpenPGP compliance with bcd_version rather than card type --- src/libopensc/card-openpgp.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e4e6cc4d20..9e2f12f5d2 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1780,13 +1780,18 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) * p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG) */ static int -pgp_select_data(sc_card_t *card, u8 p1){ +pgp_select_data(sc_card_t *card, u8 p1) +{ sc_apdu_t apdu; u8 apdu_data[6]; int r; + struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); + if (priv->bcd_version < OPENPGP_CARD_3_0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + sc_log(card->ctx, "select data with: %u", p1); // create apdu data (taken from spec: SELECT DATA 7.2.5.) @@ -2179,8 +2184,7 @@ pgp_set_security_env(sc_card_t *card, /* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */ if ((env->flags & SC_SEC_ENV_ALG_PRESENT) && (env->algorithm != SC_ALGORITHM_RSA) - && (priv->bcd_version < OPENPGP_CARD_3_0) - && (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) + && (priv->bcd_version < OPENPGP_CARD_3_0)) LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "only RSA algorithm supported"); @@ -2944,13 +2948,13 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke { sc_algorithm_info_t *algo; u8 id = key_info->key_id; + struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && card->type < SC_CARD_TYPE_OPENPGP_V3 - && card->type != SC_CARD_TYPE_OPENPGP_GNUK) + && priv->bcd_version < OPENPGP_CARD_3_0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); if (id > card->algorithm_count) { @@ -2992,13 +2996,13 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) size_t apdu_le; size_t resplen = 0; int r = SC_SUCCESS; + struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && card->type < SC_CARD_TYPE_OPENPGP_V3 - && card->type != SC_CARD_TYPE_OPENPGP_GNUK) + && priv->bcd_version < OPENPGP_CARD_3_0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA && card->type != SC_CARD_TYPE_OPENPGP_GNUK) @@ -3358,13 +3362,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) u8 *data = NULL; size_t len = 0; int r; + struct pgp_priv_data *priv = DRVDATA(card); LOG_FUNC_CALLED(card->ctx); /* protect incompatible cards against non-RSA */ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA - && card->type < SC_CARD_TYPE_OPENPGP_V3 - && card->type != SC_CARD_TYPE_OPENPGP_GNUK) + && priv->bcd_version < OPENPGP_CARD_3_0) LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); /* Validate */ From b83c3586a23856c1cd984725b97e78cdd7c2f622 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 14 Apr 2023 12:09:55 +0200 Subject: [PATCH 2839/4321] openpgp: ignore errors on SELECT DATA for OpenPGP 2 and below fixes https://github.com/OpenSC/OpenSC/issues/2752 --- src/libopensc/pkcs15-openpgp.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index e2f3442238..9d3fd746a0 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -556,14 +556,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); - /* only try to SELECT DATA for OpenPGP >= v3 */ - if (card->type >= SC_CARD_TYPE_OPENPGP_V3) { - r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i); - if (r < 0) { - free(buffer); - LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data"); - } - } + /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */ + sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i); + sc_format_path(certs[i].path, &cert_info.path); /* Certificate ID. We use the same ID as the authentication key */ From 0e0c125a2f05ff32fb4670eec7902ed66a765ff7 Mon Sep 17 00:00:00 2001 From: Mathias Olsson Date: Mon, 17 Apr 2023 07:58:18 +0200 Subject: [PATCH 2840/4321] Update pkcs11-tool.c Use opt_object_index in read_object() --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 667c7c123c..1fa2b5ab3b 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5555,7 +5555,7 @@ static int read_object(CK_SESSION_HANDLE session) nn_attrs++; } - rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, 0); + rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, opt_object_index); if (rv != CKR_OK) p11_fatal("find_object_with_attributes()", rv); else if (obj==CK_INVALID_HANDLE) From c615380d6d1409ae1d16add86c81d2ebbc045cd4 Mon Sep 17 00:00:00 2001 From: Mukesh Bharsakle Date: Thu, 13 Apr 2023 15:17:34 +0100 Subject: [PATCH 2841/4321] exit if no action specified cardos-tool Signed-off-by: Mukesh Bharsakle --- src/tools/cardos-tool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 4e6dd55480..eaee498416 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1182,6 +1182,9 @@ int main(int argc, char *argv[]) util_print_usage_and_die(app_name, options, option_help, NULL); } } + + if(action_count == 0) + util_print_usage_and_die(app_name, options, option_help, NULL); /* create sc_context_t object */ memset(&ctx_param, 0, sizeof(ctx_param)); From aedf3e7acfbd5e4acfc25d9392cf5d7fda033b29 Mon Sep 17 00:00:00 2001 From: Mukesh Bharsakle Date: Thu, 13 Apr 2023 16:12:04 +0100 Subject: [PATCH 2842/4321] Update src/tools/cardos-tool.c Co-authored-by: Jakub Jelen --- src/tools/cardos-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index eaee498416..3a969ac255 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1183,7 +1183,7 @@ int main(int argc, char *argv[]) } } - if(action_count == 0) + if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); /* create sc_context_t object */ From 895e07c9160973f170b3040792bf0911c9ee28c2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 20 Jan 2023 15:55:19 +0100 Subject: [PATCH 2843/4321] added path of executable to context --- configure.ac | 2 +- src/libopensc/ctx.c | 55 +++++++++++++++++++++++++++++++++---- src/libopensc/opensc.h | 1 + src/minidriver/minidriver.c | 12 ++++---- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 35688b4d16..202e3d4aa1 100644 --- a/configure.ac +++ b/configure.ac @@ -428,7 +428,7 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([ \ getpass gettimeofday getline memset mkdir \ strdup strerror memset_s explicit_bzero \ - strnlen sigaction + strnlen sigaction getprogname ]) # diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 78d119b7de..a55c03051c 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -37,6 +37,10 @@ #include #endif +#ifdef __APPLE__ +#include +#endif + #include "common/libscdl.h" #include "common/compat_strlcpy.h" #include "internal.h" @@ -849,6 +853,41 @@ static void sc_openssl3_deinit(sc_context_t *ctx) } #endif +static char *get_exe_path() +{ + /* Find the executable's path which runs this code. + * See https://github.com/gpakosz/whereami/ for + * potentially more platforms */ + char exe_path[PATH_MAX] = "unknown executable path"; + int path_found = 0; + +#if defined(_WIN32) + if (0 < GetModuleFileNameA(NULL, exe_path, sizeof exe_path)) + path_found = 1; +#elif defined(__APPLE__) + if (0 < proc_pidpath(getpid(), exe_path, sizeof exe_path)) + path_found = 1; +#elif defined(__linux__) || defined(__CYGWIN__) + if (NULL != realpath("/proc/self/exe", exe_path)) + path_found = 1; +#endif + +#if defined(HAVE_GETPROGNAME) + if (!path_found) { + /* getprogname is unreliable and typically only returns the basename. + * However, this should be enough for our purposes */ + const char *prog = getprogname(); + if (prog) + strlcpy(exe_path, prog, sizeof exe_path); + } +#else + /* avoid warning "set but not used" */ + (void) path_found; +#endif + + return strdup(exe_path); +} + int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) { sc_context_t *ctx; @@ -874,6 +913,12 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) return SC_ERROR_OUT_OF_MEMORY; } + ctx->exe_path = get_exe_path(); + if (ctx->exe_path == NULL) { + sc_release_context(ctx); + return SC_ERROR_OUT_OF_MEMORY; + } + ctx->flags = parm->flags; set_defaults(ctx, &opts); @@ -901,7 +946,8 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) process_config_file(ctx, &opts); sc_log(ctx, "==================================="); /* first thing in the log */ - sc_log(ctx, "opensc version: %s", sc_get_version()); + sc_log(ctx, "OpenSC version: %s", sc_get_version()); + sc_log(ctx, "Configured for %s (%s)", ctx->app_name, ctx->exe_path); #ifdef USE_OPENSSL3_LIBCTX r = sc_openssl3_init(ctx); @@ -1017,10 +1063,9 @@ int sc_release_context(sc_context_t *ctx) scconf_free(ctx->conf); if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr)) fclose(ctx->debug_file); - if (ctx->debug_filename != NULL) - free(ctx->debug_filename); - if (ctx->app_name != NULL) - free(ctx->app_name); + free(ctx->debug_filename); + free(ctx->app_name); + free(ctx->exe_path); list_destroy(&ctx->readers); sc_mem_clear(ctx, sizeof(*ctx)); free(ctx); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 2c5e77d67a..4248350619 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -873,6 +873,7 @@ typedef struct sc_context { scconf_context *conf; scconf_block *conf_blocks[3]; char *app_name; + char *exe_path; int debug; unsigned long flags; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 4790f31de4..b36b5088b8 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -698,15 +698,16 @@ md_get_config_bool(PCARD_DATA pCardData, char *flag_name, BOOL ret_default) static BOOL md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData) { - TCHAR path[MAX_PATH]={0}; + VENDOR_SPECIFIC *vs; logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enabled?\n"); - if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { + vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + if (vs && vs->ctx && vs->ctx->exe_path) { DWORD enable_cancel; size_t sz = sizeof enable_cancel; - if (SC_SUCCESS == sc_ctx_win32_get_config_value(NULL, path, + if (SC_SUCCESS == sc_ctx_win32_get_config_value(NULL, vs->ctx->exe_path, SUBKEY_ENABLE_CANCEL, (char *)(&enable_cancel), &sz)) { switch (enable_cancel) { @@ -3107,8 +3108,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p result = TaskDialogIndirect(&tc, NULL, NULL, &user_checked); if (user_checked != checked) { - TCHAR path[MAX_PATH]={0}; - if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) { + if (pv && pv->ctx && pv->ctx->exe_path) { HKEY hKey; LSTATUS lstatus = RegOpenKeyExA(HKEY_CURRENT_USER, SUBKEY_ENABLE_CANCEL, 0, KEY_WRITE, &hKey); @@ -3122,7 +3122,7 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p if (user_checked == FALSE) { enable_cancel = 1; } - lstatus = RegSetValueEx(hKey, path, 0, REG_DWORD, + lstatus = RegSetValueEx(hKey, pv->ctx->exe_path, 0, REG_DWORD, (const BYTE*)&enable_cancel, sizeof(enable_cancel)); RegCloseKey(hKey); } From 3f4e32f24b4b72a023a430c52bc5dccc8bfee796 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 20 Jan 2023 16:22:35 +0100 Subject: [PATCH 2844/4321] pkcs11: identify "onepin" configuration based on processname Identifies Firefox, Chrome, Chromium for using the previous onepin-mode --- configure.ac | 2 +- doc/files/opensc.conf.5.xml.in | 9 ++++++--- src/pkcs11/misc.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 202e3d4aa1..35688b4d16 100644 --- a/configure.ac +++ b/configure.ac @@ -428,7 +428,7 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([ \ getpass gettimeofday getline memset mkdir \ strdup strerror memset_s explicit_bzero \ - strnlen sigaction getprogname + strnlen sigaction ]) # diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 44ffce2d51..be76747448 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1468,10 +1468,13 @@ app application { - Maximum number of slots per smart card (Default: - 4). If the card has fewer keys + Maximum number of PIN slots per smart card (Default: + 4). If the card has fewer PINs than defined here, the remaining number of slots - will be empty. + will be empty. For Firefox, the + is set to 1, because the browser has issues + handling multiple PINs. Typically, this effectively disables + signature PINs and keys in Firefox. diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 642338b4bb..4339e41e01 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -448,6 +448,31 @@ CK_RV attr_find_var(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, return attr_extract(pTemplate, ptr, sizep); } +static int is_nss_browser(sc_context_t * ctx) +{ + const char *basename; +#ifdef _WIN32 + const char sep = '\\'; +#else + const char sep = '/'; +#endif + if (!ctx || !ctx->exe_path) + return 0; + + basename = strrchr(ctx->exe_path, sep); + if (!basename) + basename = ctx->exe_path; + else + /* discard the separator */ + basename += sizeof(char); + + if (strstr(basename, "chromium") || strstr(basename, "chrome") + || strstr(basename, "firefox")) + return 1; + + return 0; +} + void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) { scconf_block *conf_block = NULL; @@ -456,7 +481,11 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) /* Set defaults */ conf->max_virtual_slots = 16; - if (strcmp(ctx->app_name, "onepin-opensc-pkcs11") == 0) { + if (is_nss_browser(ctx)) { + /* NSS verifies *every* PIN even though only a single one would be + * needed to use one specific key. In known NSS browsers, we set + * slots_per_card to `1` to only look at the authentication PIN, i.e. + * ignoring a potential signature PIN. */ conf->slots_per_card = 1; } else { conf->slots_per_card = 4; From 76ebe42d4e75d85c2a4197938f203311e2f3222a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 20 Jan 2023 16:31:08 +0100 Subject: [PATCH 2845/4321] remove onepin module as it is not needed anymore --- src/pkcs11/Makefile.am | 15 ++++----------- src/pkcs11/Makefile.mak | 9 +-------- src/tools/pkcs11-register.c | 5 ----- win32/OpenSC.wxs.in | 4 ---- 4 files changed, 5 insertions(+), 28 deletions(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 622c074515..2d71c6d5be 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -1,10 +1,10 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-pkcs11.rc $(srcdir)/versioninfo-pkcs11-spy.rc -EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest onepin-opensc-pkcs11.dll.manifest +EXTRA_DIST = Makefile.mak versioninfo-pkcs11.rc.in versioninfo-pkcs11-spy.rc.in opensc-pkcs11.pc.in opensc-pkcs11.dll.manifest if ENABLE_SHARED -lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la onepin-opensc-pkcs11.la +lib_LTLIBRARIES = opensc-pkcs11.la pkcs11-spy.la else noinst_LTLIBRARIES = libopensc-pkcs11.la endif @@ -43,13 +43,6 @@ libopensc_pkcs11_la_CFLAGS = $(OPENSC_PKCS11_CFLAGS) libopensc_pkcs11_la_LIBADD = $(OPENSC_PKCS11_LIBS) libopensc_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) -onepin_opensc_pkcs11_la_SOURCES = $(OPENSC_PKCS11_SRC) $(OPENSC_PKCS11_INC) -onepin_opensc_pkcs11_la_CFLAGS = -DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" $(OPENSC_PKCS11_CFLAGS) -onepin_opensc_pkcs11_la_LIBADD = $(OPENSC_PKCS11_LIBS) -onepin_opensc_pkcs11_la_LDFLAGS = $(AM_LDFLAGS) \ - -export-symbols "$(srcdir)/pkcs11.exports" \ - -module -shared -avoid-version -no-undefined - pkcs11_spy_la_SOURCES = pkcs11-spy.c pkcs11-display.c pkcs11-display.h pkcs11.exports pkcs11_spy_la_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(OPENSC_PKCS11_PTHREAD_CFLAGS) pkcs11_spy_la_LIBADD = \ @@ -82,13 +75,13 @@ else # see http://wiki.cacert.org/wiki/Pkcs11TaskForce install-exec-hook: $(MKDIR_P) "$(DESTDIR)$(pkcs11dir)" - for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ + for l in opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ $(LN_S) ../$$l "$(DESTDIR)$(pkcs11dir)/$$l"; \ done uninstall-hook: - for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ + for l in opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ done rm -df "$(DESTDIR)$(pkcs11dir)" || true diff --git a/src/pkcs11/Makefile.mak b/src/pkcs11/Makefile.mak index 753c8004ca..bbcd856c01 100644 --- a/src/pkcs11/Makefile.mak +++ b/src/pkcs11/Makefile.mak @@ -1,7 +1,6 @@ TOPDIR = ..\.. TARGET1 = opensc-pkcs11.dll -TARGET2 = onepin-opensc-pkcs11.dll TARGET3 = pkcs11-spy.dll OBJECTS = pkcs11-global.obj pkcs11-session.obj pkcs11-object.obj misc.obj slot.obj \ @@ -21,7 +20,7 @@ LIBS = $(TOPDIR)\src\libopensc\opensc_a.lib \ $(TOPDIR)\src\pkcs15init\pkcs15init.lib LIBS3 = $(TOPDIR)\src\common\libpkcs11.lib $(TOPDIR)\src\common\libscdl.lib $(TOPDIR)\src\common\common.lib -all: $(TARGET1) $(TARGET2) $(TARGET3) +all: $(TARGET1) $(TARGET3) !INCLUDE $(TOPDIR)\win32\Make.rules.mak @@ -29,12 +28,6 @@ $(TARGET1): $(OBJECTS) $(LIBS) link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib if EXIST $(TARGET1).manifest mt -manifest $(TARGET1).manifest -outputresource:$(TARGET1);2 -$(TARGET2): $(OBJECTS) $(LIBS) - del pkcs11-global.obj - cl $(CODE_OPTIMIZATION) $(COPTS) /DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" /c pkcs11-global.c - link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib Comctl32.lib Shell32.lib user32.lib advapi32.lib ws2_32.lib Shell32.lib Comctl32.lib shlwapi.lib - if EXIST $(TARGET2).manifest mt -manifest $(TARGET2).manifest -outputresource:$(TARGET2);2 - $(TARGET3): $(OBJECTS3) $(LIBS3) link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib shlwapi.lib if EXIST $(TARGET3).manifest mt -manifest $(TARGET3).manifest -outputresource:$(TARGET3);2 diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index ab86ef87b7..00f1140e55 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -235,11 +235,6 @@ add_module_firefox(const char *module_path, const char *module_name, const char #endif }; - if (0 == strcmp(module_path, default_pkcs11_provider)) { - module_path = default_onepin_pkcs11_provider; - exclude_module_path = default_pkcs11_provider; - } - add_module_mozilla(locations, sizeof locations/sizeof *locations, module_path, module_name, exclude_module_path); } diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index fe2bdc47d1..fe1d4d3728 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -118,9 +118,6 @@ - - - @@ -367,7 +364,6 @@ - From b9b5dc99223d74ad0e0df5ca38b48b41190346d4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 20 Jan 2023 19:36:08 +0100 Subject: [PATCH 2846/4321] tool: allow verbose logging before connecting to reader --- src/libopensc/ctx.c | 11 +++++++++++ src/libopensc/opensc.h | 2 ++ src/tests/fuzzing/fuzz_piv_tool.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_crypt.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_tool.c | 2 +- src/tools/cardos-tool.c | 6 +++++- src/tools/cryptoflex-tool.c | 5 ++++- src/tools/dnie-tool.c | 5 ++++- src/tools/egk-tool.c | 10 ++++------ src/tools/eidenv.c | 2 +- src/tools/gids-tool.c | 5 ++++- src/tools/goid-tool.c | 10 ++++------ src/tools/iasecc-tool.c | 5 ++++- src/tools/npa-tool.c | 5 ++++- src/tools/openpgp-tool.c | 5 ++++- src/tools/opensc-explorer.c | 5 ++++- src/tools/opensc-tool.c | 5 ++++- src/tools/piv-tool.c | 5 ++++- src/tools/pkcs15-crypt.c | 5 ++++- src/tools/pkcs15-init.c | 5 ++++- src/tools/pkcs15-tool.c | 7 ++++++- src/tools/sc-hsm-tool.c | 5 ++++- src/tools/util.c | 19 +++++++------------ src/tools/util.h | 6 +++--- src/tools/westcos-tool.c | 5 ++++- 25 files changed, 98 insertions(+), 46 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index a55c03051c..a14c3d066b 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -945,6 +945,17 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) #endif process_config_file(ctx, &opts); + + /* overwrite with caller's parameters if explicitly given */ + if (parm->debug) { + ctx->debug = parm->debug; + } + if (parm->debug_file) { + if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) + fclose(ctx->debug_file); + ctx->debug_file = parm->debug_file; + } + sc_log(ctx, "==================================="); /* first thing in the log */ sc_log(ctx, "OpenSC version: %s", sc_get_version()); sc_log(ctx, "Configured for %s (%s)", ctx->app_name, ctx->exe_path); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 4248350619..bb3e40b520 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -987,6 +987,8 @@ typedef struct { unsigned long flags; /** mutex functions to use (optional) */ sc_thread_context_t *thread_ctx; + int debug; + FILE *debug_file; } sc_context_param_t; /** diff --git a/src/tests/fuzzing/fuzz_piv_tool.c b/src/tests/fuzzing/fuzz_piv_tool.c index f5770d035d..616f098327 100644 --- a/src/tests/fuzzing/fuzz_piv_tool.c +++ b/src/tests/fuzzing/fuzz_piv_tool.c @@ -35,7 +35,7 @@ /* Rename main for calling in fuzz target */ #define main _main /* Connect to virtual reader instead of real card*/ -#define util_connect_card(ctx, card, id, do_wait, verbose) fuzz_util_connect_card(ctx, card) +#define util_connect_card(ctx, card, id, do_wait) fuzz_util_connect_card(ctx, card) # include "tools/piv-tool.c" #undef main diff --git a/src/tests/fuzzing/fuzz_pkcs15_crypt.c b/src/tests/fuzzing/fuzz_pkcs15_crypt.c index f940e786b4..6824087000 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_crypt.c +++ b/src/tests/fuzzing/fuzz_pkcs15_crypt.c @@ -34,7 +34,7 @@ /* Rename main to call it in fuzz target */ #define main _main -#define util_connect_card_ex(ctx, card, id, do_wait, do_lock, verbose) fuzz_util_connect_card(ctx, card) +#define util_connect_card_ex(ctx, card, id, do_wait, do_lock) fuzz_util_connect_card(ctx, card) # include "tools/pkcs15-crypt.c" #undef main diff --git a/src/tests/fuzzing/fuzz_pkcs15_tool.c b/src/tests/fuzzing/fuzz_pkcs15_tool.c index c57c8a9a45..089aaf431e 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_tool.c +++ b/src/tests/fuzzing/fuzz_pkcs15_tool.c @@ -40,7 +40,7 @@ /* Rename main to call it in fuzz target */ #define main _main -#define util_connect_card_ex(ctx, card, id, do_wait, do_lock, verbose) fuzz_util_connect_card(ctx, card) +#define util_connect_card_ex(ctx, card, id, do_wait, do_lock) fuzz_util_connect_card(ctx, card) # include "tools/pkcs15-tool.c" #undef main diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 4e6dd55480..1afbf09d6f 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -1187,6 +1187,10 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; + r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Failed to establish context: %s\n", @@ -1202,7 +1206,7 @@ int main(int argc, char *argv[]) goto end; } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card(ctx, &card, opt_reader, opt_wait); if (err) goto end; diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index d28dd9ba02..7ee2260d79 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -1236,6 +1236,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -1243,7 +1246,7 @@ int main(int argc, char *argv[]) return 1; } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card(ctx, &card, opt_reader, opt_wait); if (err) goto end; printf("Using card driver: %s\n", card->driver->name); diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index cafe854318..a8dc554690 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -133,6 +133,9 @@ int main(int argc, char* argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Error: Failed to establish context: %s\n", @@ -149,7 +152,7 @@ int main(int argc, char* argv[]) goto dnie_tool_end; } - if (util_connect_card(ctx, &card, opt_reader, opt_wait, verbose) ) { + if (util_connect_card(ctx, &card, opt_reader, opt_wait) ) { fprintf(stderr, "Error: Cannot connect with card\n"); err = -1; goto dnie_tool_end; diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index b3a8365ec5..fb6cff1f63 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -157,6 +157,9 @@ main (int argc, char **argv) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = cmdline.verbose_given; + if (cmdline.verbose_given > 1) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -164,12 +167,7 @@ main (int argc, char **argv) exit(1); } - if (cmdline.verbose_given > 1) { - ctx->debug = cmdline.verbose_given; - sc_ctx_log_to_file(ctx, "stderr"); - } - - r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0); if (r) goto err; diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 1297482c36..94aaf3ac66 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -401,7 +401,7 @@ int main(int argc, char **argv) sc_strerror(r)); return 1; } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); + r = util_connect_card(ctx, &card, opt_reader, opt_wait); if (r) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); sc_release_context(ctx); diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 5765472e9c..8651fbf3ab 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -529,6 +529,9 @@ int main(int argc, char * argv[]) memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { @@ -536,7 +539,7 @@ int main(int argc, char * argv[]) exit(1); } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + r = util_connect_card(ctx, &card, opt_reader, opt_wait); if (r != SC_SUCCESS) { if (r < 0) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(err)); diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index e6a3bd041d..57a2ebbd9e 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -855,6 +855,9 @@ main(int argc, char **argv) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = cmdline.verbose_given; + if (cmdline.verbose_given > 1) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -862,16 +865,11 @@ main(int argc, char **argv) exit(1); } - if (cmdline.verbose_given > 1) { - ctx->debug = cmdline.verbose_given; - sc_ctx_log_to_file(ctx, "stderr"); - } - r = sc_set_card_driver(ctx, "default"); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, "Error selecting card driver."); - r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0); SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_VERBOSE_TOOL, r, "Error connecting to card."); diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 301ad89d0a..c008ca12d5 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -237,6 +237,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { @@ -247,7 +250,7 @@ int main(int argc, char *argv[]) if (action_count <= 0) goto end; - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card(ctx, &card, opt_reader, opt_wait); if (err) goto end; diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index cdec50efa3..0ac83d2795 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -379,6 +379,9 @@ main (int argc, char **argv) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = cmdline.verbose_given; + if (cmdline.verbose_given) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -390,7 +393,7 @@ main (int argc, char **argv) if (r) goto err; - r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0, cmdline.verbose_given); + r = util_connect_card_ex(ctx, &card, cmdline.reader_arg, 0, 0); if (r) goto err; diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 1f3be0fb94..3cc0f1eec5 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -699,6 +699,9 @@ int main(int argc, char **argv) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -714,7 +717,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + r = util_connect_card(ctx, &card, opt_reader, opt_wait); if (r) { sc_release_context(ctx); util_fatal("failed to connect to card: %s", sc_strerror(r)); diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 5ff65cd0d9..11884fcd77 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2382,6 +2382,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -2411,7 +2414,7 @@ int main(int argc, char *argv[]) } } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, 0); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0); if (err) goto end; diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index eebe87bf40..e9594068ab 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -811,6 +811,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -843,7 +846,7 @@ int main(int argc, char *argv[]) if (action_count <= 0) goto end; - err = util_connect_reader(ctx, &reader, opt_reader, opt_wait, verbose); + err = util_connect_reader(ctx, &reader, opt_reader, opt_wait); if (err) { fprintf(stderr, "Failed to connect to reader: %s\n", sc_strerror(err)); err = 1; diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 1793a2a327..4b1b21911f 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -707,6 +707,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { @@ -725,7 +728,7 @@ int main(int argc, char *argv[]) goto end; } - err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); + err = util_connect_card(ctx, &card, opt_reader, opt_wait); if (err) goto end; diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index f714f037b8..ea794933eb 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -476,6 +476,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -483,7 +486,7 @@ int main(int argc, char *argv[]) return 1; } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0); if (err) goto end; diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index f8a62c442f..9df67ae261 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -647,6 +647,9 @@ open_reader_and_card(char *reader) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&g_ctx, &ctx_param); if (r) { @@ -654,7 +657,7 @@ open_reader_and_card(char *reader) return 0; } - if (util_connect_card_ex(g_ctx, &g_card, reader, opt_wait, 0, verbose)) + if (util_connect_card_ex(g_ctx, &g_card, reader, opt_wait, 0)) return 0; return 1; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index f68d99ed6a..33bb26a70b 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -2176,6 +2176,8 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + if (verbose) + ctx_param.debug_file = stderr; if (SC_SUCCESS == sc_context_create(&ctx, &ctx_param)) { /* attempt to connect reader, on error, -r is used for read-certificate operation */ @@ -2359,6 +2361,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) { @@ -2372,7 +2377,7 @@ int main(int argc, char *argv[]) action_count--; } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); + err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0); if (err) goto end; diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 0c64e03f6c..3c0f4b3b9d 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -2079,6 +2079,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { @@ -2086,7 +2089,7 @@ int main(int argc, char *argv[]) exit(1); } - r = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); + r = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0); if (r != SC_SUCCESS) { if (r < 0) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(err)); diff --git a/src/tools/util.c b/src/tools/util.c index 3bb95bcfac..4c21112c65 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -49,7 +49,7 @@ is_string_valid_atr(const char *atr_str) } int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, - const char *reader_id, int do_wait, int verbose) + const char *reader_id, int do_wait) { struct sc_reader *found = NULL; int r; @@ -59,11 +59,6 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, sc_notify_init(); - if (verbose) { - ctx->debug = verbose; - sc_ctx_log_to_file(ctx, "stderr"); - } - if (do_wait) { unsigned int event = 0; @@ -163,16 +158,16 @@ int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, } int util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, - const char *reader_id, int do_wait, int do_lock, int verbose) + const char *reader_id, int do_wait, int do_lock) { struct sc_reader *reader = NULL; struct sc_card *card = NULL; int r; - r = util_connect_reader(ctx, &reader, reader_id, do_wait, verbose); + r = util_connect_reader(ctx, &reader, reader_id, do_wait); if(r) return r; - if (verbose) + if (ctx->debug) printf("Connecting to card in reader %s...\n", reader->name); r = sc_connect_card(reader, &card); if (r < 0) { @@ -180,7 +175,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, return r; } - if (verbose) + if (ctx->debug) printf("Using card driver %s.\n", card->driver->name); if (do_lock) { @@ -198,9 +193,9 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, int util_connect_card(sc_context_t *ctx, sc_card_t **cardp, - const char *reader_id, int do_wait, int verbose) + const char *reader_id, int do_wait) { - return util_connect_card_ex(ctx, cardp, reader_id, do_wait, 1, verbose); + return util_connect_card_ex(ctx, cardp, reader_id, do_wait, 1); } void util_print_binary(FILE *f, const u8 *buf, int count) diff --git a/src/tools/util.h b/src/tools/util.h index 49c8da3ff7..c910ed32e7 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -49,10 +49,10 @@ void util_warn(const char *fmt, ...); void util_error(const char *fmt, ...); NORETURN void util_fatal(const char *fmt, ...); -int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, const char *reader_id, int do_wait, int verbose); +int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, const char *reader_id, int do_wait); /* All singing all dancing card connect routine */ -int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose); -int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose); +int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock); +int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait); int util_getpass (char **lineptr, size_t *n, FILE *stream); diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index dd4e00bee4..30f94f97ec 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -428,6 +428,9 @@ int main(int argc, char *argv[]) memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = argv[0]; + ctx_param.debug = verbose; + if (verbose) + ctx_param.debug_file = stderr; r = sc_context_create(&ctx, &ctx_param); if (r) @@ -446,7 +449,7 @@ int main(int argc, char *argv[]) } } - r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); + r = util_connect_card(ctx, &card, opt_reader, opt_wait); if (r) goto out; From ef8a6abb9584f134c54348c93e79a2e29a5af6ac Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 23 Jan 2023 13:08:25 +0100 Subject: [PATCH 2847/4321] pkcs11: log (default) options if pkcs11 conf block was not found --- src/pkcs11/misc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 4339e41e01..d890495e83 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -499,7 +499,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1); if (!conf_block) - return; + goto out; /* contains the defaults, if there is a "pkcs11" config block */ conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots); @@ -535,6 +535,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) } free(tmp); +out: sc_log(ctx, "PKCS#11 options: max_virtual_slots=%d slots_per_card=%d " "lock_login=%d atomic=%d pin_unblock_style=%d " "create_slots_flags=0x%X", From 234fcf48b98cf75703708381025d39bcc5e4a6e9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 24 Jan 2023 09:30:17 +0100 Subject: [PATCH 2848/4321] pkcs11: remove notification for insertion/removal this is getting too annoying with multiple PKCS#11 applications running. We'll let the insertion/removal events be handled by opensc-notify. --- src/pkcs11/framework-pkcs15.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index f9b9b23642..ca0ce50898 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -350,12 +350,6 @@ pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info) } } - if (idx == 0) { - /* send a notification only for the first application that's bound */ - sc_notify_id(p11card->card->ctx, &p11card->reader->atr, fw_data->p15_card, - NOTIFY_CARD_INSERTED); - } - return CKR_OK; } @@ -386,17 +380,6 @@ pkcs15_unbind(struct sc_pkcs11_card *p11card) unlock_card(fw_data); if (fw_data->p15_card) { - if (fw_data->p15_card->card && idx == 0) { - int rc = sc_detect_card_presence(fw_data->p15_card->card->reader); - if (rc <= 0 || rc & SC_READER_CARD_CHANGED) { - /* send a notification only if the card was removed/changed - * and only for the first application that's unbound */ - sc_notify_id(fw_data->p15_card->card->ctx, - &fw_data->p15_card->card->reader->atr, - fw_data->p15_card, - NOTIFY_CARD_REMOVED); - } - } rv = sc_pkcs15_unbind(fw_data->p15_card); } fw_data->p15_card = NULL; From 55c40af86e791ace1a14ab56c38bbeb3d1ad7191 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 25 Jan 2023 08:31:13 +0100 Subject: [PATCH 2849/4321] remove onepin module from packaging --- packaging/opensc.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index fe3d84db01..79fe73125b 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -161,10 +161,8 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_libdir}/lib*.so.* %{_libdir}/opensc-pkcs11.so %{_libdir}/pkcs11-spy.so -%{_libdir}/onepin-opensc-pkcs11.so %dir %{_libdir}/pkcs11 %{_libdir}/pkcs11/opensc-pkcs11.so -%{_libdir}/pkcs11/onepin-opensc-pkcs11.so %{_libdir}/pkcs11/pkcs11-spy.so %{_datadir}/opensc/ %{_mandir}/man1/cardos-tool.1* From c787c1ff6ef2d786fa0635a4be568d7cde505fdc Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sat, 11 Feb 2023 14:32:25 +0100 Subject: [PATCH 2850/4321] pkcs11: added onepin module as link/copy for backward compatibility --- src/pkcs11/Makefile.am | 6 ++++-- win32/OpenSC.wxs.in | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 2d71c6d5be..e4f5dc2d81 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -74,17 +74,19 @@ uninstall-hook: else # see http://wiki.cacert.org/wiki/Pkcs11TaskForce install-exec-hook: + $(LN_S) "$(DESTDIR)$(libdir)/opensc-pkcs11$(DYN_LIB_EXT)" "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" $(MKDIR_P) "$(DESTDIR)$(pkcs11dir)" - for l in opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ + for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ $(LN_S) ../$$l "$(DESTDIR)$(pkcs11dir)/$$l"; \ done uninstall-hook: - for l in opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ + for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ done rm -df "$(DESTDIR)$(pkcs11dir)" || true + rm -f "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" endif TIDY_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(OPENSC_PKCS11_CFLAGS) diff --git a/win32/OpenSC.wxs.in b/win32/OpenSC.wxs.in index fe1d4d3728..34cc8eddda 100644 --- a/win32/OpenSC.wxs.in +++ b/win32/OpenSC.wxs.in @@ -118,6 +118,9 @@ + + + @@ -364,6 +367,7 @@ + From 71c0936c595561eed0a4d7671aa23917597b17c3 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 15 Feb 2023 02:45:39 +0100 Subject: [PATCH 2851/4321] fixed subsequent executions of `make install` --- src/pkcs11/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index e4f5dc2d81..54ac8ab88a 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -74,6 +74,7 @@ uninstall-hook: else # see http://wiki.cacert.org/wiki/Pkcs11TaskForce install-exec-hook: + rm -f "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" $(LN_S) "$(DESTDIR)$(libdir)/opensc-pkcs11$(DYN_LIB_EXT)" "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" $(MKDIR_P) "$(DESTDIR)$(pkcs11dir)" for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ From 889ad2aba6ebcd704173e8a853e13d7da4631e9c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 24 Apr 2023 22:54:09 +0200 Subject: [PATCH 2852/4321] westcos: fixed reading configuration through all possible app's --- src/libopensc/card-westcos.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 108599336b..77801c3a71 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -82,15 +82,22 @@ static struct sc_card_driver westcos_drv = { static int westcos_get_default_key(sc_card_t * card, struct sc_cardctl_default_key *data) { - const char *default_key; + const char *default_key = NULL; + size_t i; sc_log(card->ctx, "westcos_get_default_key:data->method=%d, data->key_ref=%d\n", data->method, data->key_ref); if (data->method != SC_AC_AUT || data->key_ref != 0) return SC_ERROR_NO_DEFAULT_KEY; - default_key = - scconf_get_str(card->ctx->conf_blocks[0], "westcos_default_key", - DEFAULT_TRANSPORT_KEY); + + for (i = 0; card->ctx->conf_blocks[i]; i++) { + default_key = scconf_get_str(card->ctx->conf_blocks[i], "westcos_default_key", NULL); + if (default_key) + break; + } + if (!default_key) + default_key = DEFAULT_TRANSPORT_KEY; + return sc_hex_to_bin(default_key, data->key_data, &data->len); } From b1f7233a8bb42f5a23197de04d9a77e71edf9383 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 24 Apr 2023 23:45:28 +0200 Subject: [PATCH 2853/4321] opensc.conf: allow configuration for an application with a certain file path --- doc/files/opensc.conf.5.xml.in | 11 +++++++---- etc/opensc.conf.example.in | 2 +- src/libopensc/ctx.c | 6 +++++- src/libopensc/opensc.h | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index be76747448..2d77bb1ddf 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -73,6 +73,9 @@ app application { application specifies one of: + + filename: Configuration block for the application with specified file path. + default: The fall-back configuration block for all applications @@ -1471,10 +1474,10 @@ app application { Maximum number of PIN slots per smart card (Default: 4). If the card has fewer PINs than defined here, the remaining number of slots - will be empty. For Firefox, the - is set to 1, because the browser has issues - handling multiple PINs. Typically, this effectively disables - signature PINs and keys in Firefox. + will be empty. For Firefox, Chrome and Chromium, the + is set to 1, + to avoid prompting for unrelated PINs. Typically, this + effectively disables signature PINs and keys. diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 6f70d87f1f..4f50ae84ae 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -1106,7 +1106,7 @@ app opensc-pkcs11 { } } -app onepin-opensc-pkcs11 { +app "C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe" { pkcs11 { slots_per_card = 1; } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index a14c3d066b..91a51db186 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -733,6 +733,10 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) } /* needs to be after the log file is known */ sc_log(ctx, "Used configuration file '%s'", conf_path); + blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->exe_path); + if (blocks && blocks[0]) + ctx->conf_blocks[count++] = blocks[0]; + free(blocks); blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name); if (blocks && blocks[0]) ctx->conf_blocks[count++] = blocks[0]; @@ -743,7 +747,7 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) ctx->conf_blocks[count] = blocks[0]; free(blocks); } - /* Above we add 2 blocks at most, but conf_blocks has 3 elements, + /* Above we add 3 blocks at most, but conf_blocks has 4 elements, * so at least one is NULL */ for (i = 0; ctx->conf_blocks[i]; i++) load_parameters(ctx, ctx->conf_blocks[i], opts); diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index bb3e40b520..a51a337a27 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -871,7 +871,7 @@ typedef struct ossl3ctx ossl3ctx_t; typedef struct sc_context { scconf_context *conf; - scconf_block *conf_blocks[3]; + scconf_block *conf_blocks[4]; char *app_name; char *exe_path; int debug; From e58bca0a33e1e972728902566ee2641c5f1430d0 Mon Sep 17 00:00:00 2001 From: AlexBear Date: Mon, 24 Apr 2023 11:13:32 +0800 Subject: [PATCH 2854/4321] Update card-epass2003.c 1,When change the pin, it is necessary to verify the pin. 2,repqair the error of when calculating cmac of k1 and k2. --- src/libopensc/card-epass2003.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 03f08402e0..32a29af617 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -370,7 +370,7 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi BN_bin2bn(out,16,enc1); BN_lshift1(lenc1,enc1); BN_bn2bin(lenc1,k1Bin); - if(check > 0x80){ + if(check & 0x80){ offset = 1; k1Bin[15+offset] ^= 0x87; } @@ -386,7 +386,7 @@ aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysi offset = 0; BN_lshift1(lenc2,enc2); BN_bn2bin(lenc2,k2Bin); - if(check > 0x80){ + if(check & 0x80){ offset = 1; k2Bin[15+offset] ^= 0x87; } @@ -3308,9 +3308,13 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries LOG_TEST_RET(card->ctx, r, "verify pin failed"); } else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */ + r = external_key_auth(card, kid, (unsigned char *)data->pin1.data, + data->pin1.len); + LOG_TEST_RET(card->ctx, r, "verify pin failed"); + r = update_secret_key(card, 0x04, kid, data->pin2.data, (unsigned long)data->pin2.len); - LOG_TEST_RET(card->ctx, r, "verify pin failed"); + LOG_TEST_RET(card->ctx, r, "change pin failed"); } else { r = external_key_auth(card, kid, (unsigned char *)data->pin1.data, From 34d1b06997ac65f1e7cbfe8c4456579d2d9fdba3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Apr 2023 14:09:01 +0200 Subject: [PATCH 2855/4321] pkcs11: Do not use colons in the token info label The NSS can not handle tokens with colons in token info labels because it is using colon as a separator for token info label and object label. Fixes: #2725 More information available in the following NSS bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1817553 --- src/pkcs11/framework-pkcs15.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 62bb9a7a9b..022933146a 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1176,7 +1176,6 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, size_t pin_len = 0; if (auth->label[0] && strncmp(auth->label, "PIN", 4) != 0) pin_len = strlen(auth->label); - if (pin_len) { size_t tokeninfo_len = 0; if (p15card->tokeninfo && p15card->tokeninfo->label) @@ -1208,6 +1207,13 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, p15card->tokeninfo ? p15card->tokeninfo->label : "", 32); } + /* Some applications (NSS) do not like the colons in the + * TOKEN_INFO label so replace them here */ + for (int i = 0; i < 32; i++) { + if (slot->token_info.label[i] == ':') { + slot->token_info.label[i] = '.'; + } + } if (p15card->tokeninfo->flags & SC_PKCS15_TOKEN_LOGIN_REQUIRED) slot->token_info.flags |= CKF_LOGIN_REQUIRED; } @@ -1413,7 +1419,7 @@ _get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name, char *label if (id.len > sizeof(id.value)) id.len = sizeof(id.value); rv = sc_pkcs15_find_pin_by_auth_id(p15card, &id, &out); - } + } else if (!strcmp(name, "UserPIN")) { /* Try to get 'global' PIN; if no, get the 'local' one */ rv = sc_pkcs15_find_pin_by_flags(p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL, @@ -3649,7 +3655,7 @@ pkcs15_set_attrib(struct sc_pkcs11_session *session, struct sc_pkcs15_object *p1 ck_rv = CKR_ATTRIBUTE_READ_ONLY; goto set_attr_done; } - rv = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object, + rv = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object, P15_ATTR_TYPE_VALUE, attr->pValue, (unsigned int) attr->ulValueLen); break; default: @@ -4936,7 +4942,7 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ return get_modulus_bits(pubkey->pub_data, attr); case CKA_PUBLIC_EXPONENT: return get_public_exponent(pubkey->pub_data, attr); - /* + /* * PKCS#11 does not define a CKA_VALUE for a CKO_PUBLIC_KEY. * OpenSC does, but it is not consistent it what it returns * Internally to do verify, with OpenSSL, we need a SPKI that From 7b782d5ce3ec1b1d78251332ab391122b6da0cc6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 2 May 2023 13:59:46 +0200 Subject: [PATCH 2856/4321] Revert "Add some more logic to decide if login is required" This reverts commit 1d5c81e85baaa82973e1080dfb34876830bee067 as per discussion from here: https://github.com/OpenSC/OpenSC/pull/2646/commits/1d5c81e85baaa82973e1080dfb34876830bee067#r1177160095 --- src/pkcs11/framework-pkcs15.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 022933146a..97daefcb47 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1214,8 +1214,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot, slot->token_info.label[i] = '.'; } } - if (p15card->tokeninfo->flags & SC_PKCS15_TOKEN_LOGIN_REQUIRED) - slot->token_info.flags |= CKF_LOGIN_REQUIRED; + slot->token_info.flags |= CKF_LOGIN_REQUIRED; } } From cdb6905e0f7356b59c23368cb759c99c2cd769ed Mon Sep 17 00:00:00 2001 From: misodengaku Date: Mon, 1 May 2023 10:09:01 +0900 Subject: [PATCH 2857/4321] Fixes #2767 --- src/tools/pkcs11-tool.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1fa2b5ab3b..890ca27060 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -4039,7 +4039,11 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(cert_templ[1], CKA_VALUE, contents, contents_len); FILL_ATTR(cert_templ[2], CKA_CLASS, &clazz, sizeof(clazz)); FILL_ATTR(cert_templ[3], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); - FILL_ATTR(cert_templ[4], CKA_PRIVATE, &_false, sizeof(_false)); + if (opt_is_private == 1) { + FILL_ATTR(cert_templ[4], CKA_PRIVATE, &_true, sizeof(_true)); + } else { + FILL_ATTR(cert_templ[4], CKA_PRIVATE, &_false, sizeof(_false)); + } n_cert_attr = 5; if (opt_object_label != NULL) { From 1e6f2334e9b9d0ac21ef5abbffb268fa3d352fb9 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 28 Apr 2023 14:35:50 +0200 Subject: [PATCH 2858/4321] epass2003: use true random number for mutual authentication for SM. modified: src/libopensc/card-epass2003.c --- src/libopensc/card-epass2003.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 32a29af617..5d9109f4d2 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -39,9 +39,9 @@ #include #include -#include -#include #include +#include +#include #include "internal.h" #include "asn1.h" @@ -101,9 +101,7 @@ static unsigned char g_init_key_mac[16] = { 0x0D, 0x0E, 0x0F, 0x10 }; -static unsigned char g_random[8] = { - 0xBF, 0xC3, 0x29, 0x11, 0xC7, 0x18, 0xC3, 0x40 -}; +static unsigned char g_random[8]; typedef struct epass2003_exdata_st { unsigned char sm; /* SM_PLAIN or SM_SCP01 */ @@ -672,6 +670,9 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma LOG_FUNC_CALLED(card->ctx); + if (1 != RAND_bytes(g_random, sizeof(g_random))) + return SC_ERROR_INTERNAL; + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x50, 0x00, 0x00); apdu.cla = 0x80; apdu.lc = apdu.datalen = sizeof(g_random); From 36178c8188521f2627d2eea428a7e53d149eed58 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 28 Apr 2023 10:50:25 +0200 Subject: [PATCH 2859/4321] Fix pkcs11-tool unwrap / incorrect CKA_ID "object_id[]" and "id_len" must be allocated so that it is not deallocated or overwritten (on the stack) at the time of the C_UnwrapKey() call. modified: src/tools/pkcs11-tool.c --- src/tools/pkcs11-tool.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 890ca27060..f3a01ab4cf 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3347,6 +3347,8 @@ unwrap_key(CK_SESSION_HANDLE session) {CKA_CLASS, &secret_key_class, sizeof(secret_key_class)}, {CKA_TOKEN, &_true, sizeof(_true)}, }; + CK_BYTE object_id[100]; + size_t id_len; CK_OBJECT_HANDLE hSecretKey; int n_attr = 2; CK_RV rv; @@ -3450,9 +3452,6 @@ unwrap_key(CK_SESSION_HANDLE session) } if (opt_application_id != NULL) { - CK_BYTE object_id[100]; - size_t id_len; - id_len = sizeof(object_id); if (!sc_hex_to_bin(opt_application_id, object_id, &id_len)) { FILL_ATTR(keyTemplate[n_attr], CKA_ID, object_id, id_len); From 961bd8c68d328bad44c99912ff7057e10cbb138f Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 28 Apr 2023 11:35:59 +0200 Subject: [PATCH 2860/4321] Fedora: enable test-pkcs11-tool-unwrap-wrap-test.sh modified: .github/setup-fedora.sh --- .github/setup-fedora.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/setup-fedora.sh b/.github/setup-fedora.sh index d194e6259e..ea5084721e 100755 --- a/.github/setup-fedora.sh +++ b/.github/setup-fedora.sh @@ -14,8 +14,7 @@ fi sudo dnf install -y $DEPS -# The test-pkcs11-tool-unwrap-wrap-test.sh is broken in Fedora for some reason sed -i -e '/XFAIL_TESTS/,$ { - s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh test-pkcs11-tool-unwrap-wrap-test.sh/ + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test-threads.sh test-pkcs11-tool-test.sh/ q }' tests/Makefile.am From cde2e050ec4f2f1b7db38429aa4e9c0f4656308c Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 26 Apr 2023 13:22:09 +0200 Subject: [PATCH 2861/4321] NULL pointer fix Thanks to the clang analyzer: Null pointer passed to 2nd parameter expecting 'nonnull' [clang-analyzer-core.NonNullParamChecker] modified: src/libopensc/card-myeid.c --- src/libopensc/card-myeid.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 31dd209f3e..951c179f1b 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1973,6 +1973,9 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, return_len = block_size - pad_byte; } *outlen = return_len; + /* application can request buffer size or actual buffer size is too small */ + if (out == NULL) + LOG_FUNC_RETURN(ctx, SC_SUCCESS); if (return_len > *outlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); memcpy(out, priv->sym_plain_buffer, return_len); @@ -2042,10 +2045,11 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, priv->sym_crypt_buffer_len = 0; rest_len = 0; } - memcpy(sdata, data, apdu_datalen); - data += apdu_datalen; - datalen -= apdu_datalen; - + if (data) { + memcpy(sdata, data, apdu_datalen); + data += apdu_datalen; + datalen -= apdu_datalen; + } r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -2084,7 +2088,8 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, /* save rest of data for next run */ priv->sym_crypt_buffer_len = datalen; sc_log(ctx, "rest data len = %zu", datalen); - memcpy(priv->sym_crypt_buffer, data, datalen); + if (data) + memcpy(priv->sym_crypt_buffer, data, datalen); sc_log(ctx, "return data len = %zu", return_len); *outlen = return_len; return SC_SUCCESS; From b45549373520287bc1bb62feb79d1e59519b6871 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 23 Apr 2023 15:14:07 +0200 Subject: [PATCH 2862/4321] pkcs15-tool: update PIN status before printing it --- src/tools/pkcs15-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index f68d99ed6a..3d911ef0c9 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1587,6 +1587,7 @@ static int list_pins(void) printf("Card has %d Authentication object(s).\n\n", r); for (i = 0; i < r; i++) { + sc_pkcs15_get_pin_info(p15card, objs[i]); print_pin_info(objs[i]); printf("\n"); } From f26363f66c38aa09a46c88f0aff5bd04a2216ab8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 24 Apr 2023 03:11:40 +0200 Subject: [PATCH 2863/4321] piv: don't initialize the retry counter since its value is vendor defined --- src/libopensc/card-piv.c | 1 - src/libopensc/pkcs15-piv.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 727725111a..d7b58f51cd 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3203,7 +3203,6 @@ static int piv_match_card_continued(sc_card_t *card) priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ /* TODO Dual CAC/PIV are bases on 800-73-1 where priv->pin_preference = 0. need to check later */ priv->logged_in = SC_PIN_STATE_UNKNOWN; - priv->tries_left = 10; /* will assume OK at start */ priv->pstate = PIV_STATE_MATCH; /* Some objects will only be present if History object says so */ diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 2c5e291631..97eeb15aeb 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -958,8 +958,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.stored_length = pins[i].storedlen; pin_info.attrs.pin.max_length = pins[i].maxlen; pin_info.attrs.pin.pad_char = pins[i].pad_char; + pin_info.tries_left = pins[i].tries_left; sc_format_path(pins[i].path, &pin_info.path); - pin_info.tries_left = -1; label = pins[i].label; if (i == 0 && @@ -970,7 +970,6 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; label = "Global PIN"; } -sc_log(card->ctx, "DEE Adding pin %d label=%s",i, label); strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1); pin_obj.flags = pins[i].obj_flags; if (i == 0 && pin_info.attrs.pin.reference == 0x80) { From 12ac33d6e0f01a334c792b341b7ea27f10ba0b98 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 22 Mar 2023 16:19:07 +0100 Subject: [PATCH 2864/4321] Add function for getting current card status in PKCS15 layer By using sc_detect_card_presence() function and observing status flags. --- src/pkcs11/framework-pkcs15.c | 29 +++++++++++++++++++++++++++++ src/pkcs11/sc-pkcs11.h | 1 + 2 files changed, 30 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 97daefcb47..11ea867023 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1401,6 +1401,35 @@ int slot_get_logged_in_state(struct sc_pkcs11_slot *slot) return logged_in; } +int slot_get_card_state(struct sc_pkcs11_slot *slot) +{ + struct pkcs15_fw_data *fw_data = NULL; + struct sc_pkcs15_card *p15card = NULL; + int rv = 0; + + if (slot->p11card == NULL) { + goto out; + } + + fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx]; + if (!fw_data) + goto out; + p15card = fw_data->p15_card; + if (!p15card) + goto out; + + if ((rv = sc_detect_card_presence(p15card->card->reader)) <= 0) + goto out; + if (rv & SC_READER_CARD_CHANGED) + return SC_READER_CARD_CHANGED; + else if (rv & SC_READER_REMOVED) + return SC_READER_REMOVED; + else if (rv & SC_READER_CARD_PRESENT) + return SC_READER_CARD_PRESENT; +out: + return 0; +} + struct sc_pkcs15_object * _get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name, char *label) diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index bc7baa7e74..4a8dac8de6 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -413,6 +413,7 @@ CK_RV slot_token_removed(CK_SLOT_ID id); CK_RV slot_allocate(struct sc_pkcs11_slot **, struct sc_pkcs11_card *); CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask); int slot_get_logged_in_state(struct sc_pkcs11_slot *slot); +int slot_get_card_state(struct sc_pkcs11_slot *slot); /* Login tracking functions */ CK_RV restore_login_state(struct sc_pkcs11_slot *slot); From 2dcb0ee396c5283380a76fa1c4518176e832e6c0 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 22 Mar 2023 16:19:25 +0100 Subject: [PATCH 2865/4321] Differentiate between changed and logged out card in C_GetSessionInfo Do not delete all sessions, when the card was logged out during operation. Instead, check whether the card was changed and by logging out only set correct flag. --- src/pkcs11/pkcs11-session.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index e938818376..d32e7a5789 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -253,6 +253,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ struct sc_pkcs11_session *session; struct sc_pkcs11_slot *slot; const char *name; + int card_status = 0, logged_out = 0; if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD; @@ -275,16 +276,20 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ pInfo->ulDeviceError = 0; slot = session->slot; - if (!sc_pkcs11_conf.atomic && slot->login_user >= 0 && - slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT) { + card_status = slot_get_card_state(slot); + if (card_status != SC_READER_CARD_PRESENT) { + /* Card was removed or reinserted, invalidate all sessions */ slot->login_user = -1; sc_pkcs11_close_all_sessions(session->slot->id); rv = CKR_SESSION_HANDLE_INVALID; goto out; } - if (slot->login_user == CKU_SO) { + + /* Check whether the user is logged in the card */ + logged_out = (slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT); + if (slot->login_user == CKU_SO && !logged_out) { pInfo->state = CKS_RW_SO_FUNCTIONS; - } else if (slot->login_user == CKU_USER || !(slot->token_info.flags & CKF_LOGIN_REQUIRED)) { + } else if ((slot->login_user == CKU_USER && !logged_out) || !(slot->token_info.flags & CKF_LOGIN_REQUIRED)) { pInfo->state = (session->flags & CKF_RW_SESSION) ? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS; } else { From c528c27616881e6cc3afef2da50193603a572c00 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 14 Apr 2023 14:52:10 +0200 Subject: [PATCH 2866/4321] Return all flags when checking the card presence --- src/pkcs11/framework-pkcs15.c | 7 +------ src/pkcs11/pkcs11-session.c | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 11ea867023..e35324c805 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1420,12 +1420,7 @@ int slot_get_card_state(struct sc_pkcs11_slot *slot) if ((rv = sc_detect_card_presence(p15card->card->reader)) <= 0) goto out; - if (rv & SC_READER_CARD_CHANGED) - return SC_READER_CARD_CHANGED; - else if (rv & SC_READER_REMOVED) - return SC_READER_REMOVED; - else if (rv & SC_READER_CARD_PRESENT) - return SC_READER_CARD_PRESENT; + return rv; out: return 0; } diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index d32e7a5789..01ce7676c9 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -277,7 +277,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ slot = session->slot; card_status = slot_get_card_state(slot); - if (card_status != SC_READER_CARD_PRESENT) { + if (!(card_status & SC_READER_CARD_PRESENT)) { /* Card was removed or reinserted, invalidate all sessions */ slot->login_user = -1; sc_pkcs11_close_all_sessions(session->slot->id); From 3d21cba957cc6972a1a672e8a508e1e6b5f5bba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 9 May 2023 09:52:51 +0200 Subject: [PATCH 2867/4321] Remove session when card is changed --- src/pkcs11/pkcs11-session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 01ce7676c9..68b6c57b8d 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -277,7 +277,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */ slot = session->slot; card_status = slot_get_card_state(slot); - if (!(card_status & SC_READER_CARD_PRESENT)) { + if (!(card_status & SC_READER_CARD_PRESENT) || card_status & SC_READER_CARD_CHANGED) { /* Card was removed or reinserted, invalidate all sessions */ slot->login_user = -1; sc_pkcs11_close_all_sessions(session->slot->id); From ecd845c2f7190afc46f39ebbae0dda7b55019994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 9 May 2023 09:53:20 +0200 Subject: [PATCH 2868/4321] Fix PCSC handling when reader is removed --- src/libopensc/reader-pcsc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 04d5ac8fdd..8c2f98c9b1 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -364,7 +364,7 @@ static int refresh_attributes(sc_reader_t *reader) if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE) return SC_ERROR_NOT_ALLOWED; - if (priv->reader_state.szReader == NULL || reader->ctx->flags & SC_READER_REMOVED) { + if (priv->reader_state.szReader == NULL || reader->flags & SC_READER_REMOVED) { priv->reader_state.szReader = reader->name; priv->reader_state.dwCurrentState = SCARD_STATE_UNAWARE; priv->reader_state.dwEventState = SCARD_STATE_UNAWARE; @@ -394,6 +394,8 @@ static int refresh_attributes(sc_reader_t *reader) #endif || rv == (LONG)SCARD_E_SERVICE_STOPPED) { reader->flags &= ~(SC_READER_CARD_PRESENT); + reader->flags |= SC_READER_REMOVED; + priv->gpriv->removed_reader = reader; SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } From f7e5c05d1217c2c62835ad4416454e0ee7879cf0 Mon Sep 17 00:00:00 2001 From: dlegault Date: Fri, 12 May 2023 09:56:06 -0400 Subject: [PATCH 2869/4321] CI: tie ix86 to ubuntu-20.04 to avoid dependency problem in github image --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 36cdc904ea..9d921de165 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -52,7 +52,7 @@ jobs: - run: .github/build.sh no-shared build-ix86: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - run: .github/setup-linux.sh ix86 From b9b354ea3bd8408088be5f59c1d5cd01b91b2e2d Mon Sep 17 00:00:00 2001 From: dlegault Date: Thu, 11 May 2023 08:09:14 -0400 Subject: [PATCH 2870/4321] pkcs11-tool: add cipher test mode Add support for non-AEAD ciphers to the tool test mode to assert that Encrypt/Decrypt APIs work correctly using established test vectors. --- src/tools/pkcs11-tool.c | 264 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f3a01ab4cf..58872320b3 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -99,6 +99,8 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; #define NEED_SESSION_RO 0x01 #define NEED_SESSION_RW 0x02 +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + static struct ec_curve_info { const char *name; const char *oid; @@ -6104,6 +6106,266 @@ static int test_digest(CK_SESSION_HANDLE session) return errors; } +static CK_RV test_load_cipher_key(CK_SESSION_HANDLE session, uint8_t *key, size_t keysize, + CK_KEY_TYPE keytype, CK_OBJECT_HANDLE *hkey) +{ + CK_OBJECT_CLASS class = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = keytype; + CK_UTF8CHAR label[] = "testkey"; + CK_BBOOL _true = CK_TRUE; + CK_ULONG keylen = (CK_ULONG)keysize; + CK_ATTRIBUTE template[] = { + { CKA_CLASS, &class, sizeof(class) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_LABEL, label, sizeof(label)-1 }, + { CKA_ENCRYPT, &_true, sizeof(_true) }, + { CKA_DECRYPT, &_true, sizeof(_true) }, + { CKA_VALUE, key, keysize }, + { CKA_VALUE_LEN, &keylen, sizeof(keylen) }, + }; + + /* create a session key only */ + return p11->C_CreateObject(session, template, ARRAY_SIZE(template), hkey); +} + +static void test_delete_cipher_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE hkey) +{ + p11->C_DestroyObject(session, hkey); +} + +static int test_cipher(CK_SESSION_HANDLE session) +{ + CK_RV rv; + CK_SESSION_INFO sessionInfo; + static struct { + CK_MECHANISM_TYPE type; + uint8_t *key; + CK_ULONG keysz; + CK_KEY_TYPE keytype; + uint8_t *iv; + CK_ULONG ivsz; + uint8_t *plaintext; + CK_ULONG ptsz; + uint8_t *ciphertext; + CK_ULONG ctsz; + } cipher_algs[] = { + { + .type = CKM_AES_ECB, + .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .keysz = 16, + .keytype = CKK_AES, + .plaintext = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", + .ptsz = 16, + .ciphertext = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a", + .ctsz = 16, + }, + { + .type = CKM_AES_CBC, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .keysz = 16, + .keytype = CKK_AES, + .iv = "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d", + .ivsz = 16, + .plaintext = "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + .ptsz = 16, + .ciphertext = "\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2", + .ctsz = 16, + }, + }; + int errors = 0; + int supported = 0; + + rv = p11->C_GetSessionInfo(session, &sessionInfo); + if (rv != CKR_OK) { + p11_fatal("C_GetSessionInfo", rv); + } + + /* encryption */ + for (size_t i = 0; i < ARRAY_SIZE(cipher_algs); ++i) { + + CK_OBJECT_HANDLE hkey = CK_INVALID_HANDLE; + CK_MECHANISM mech = { + .mechanism = cipher_algs[i].type, + .pParameter = cipher_algs[i].iv, + .ulParameterLen = cipher_algs[i].ivsz, + }; + const char *fct; + uint8_t ptext1[128] = {0}; + uint8_t ptext2[128] = {0}; + uint8_t ctext1[128] = {0}; + uint8_t ctext2[128] = {0}; + CK_ULONG coff = 0; + CK_ULONG poff = 0; + + rv = test_load_cipher_key(session, cipher_algs[i].key, cipher_algs[i].keysz, cipher_algs[i].keytype, &hkey); + if (rv != CKR_OK) { + continue; + } + + /* Testing Encryption */ + + fct = "C_EncryptInit"; + rv = p11->C_EncryptInit(session, &mech, hkey); + if (rv == CKR_MECHANISM_INVALID) + continue; /* mechanism not implemented, don't test */ + if (rv != CKR_OK) { + goto cipher_clup; + } + ++supported; + if (supported == 1) { + printf("Ciphers:\n"); + } + printf(" %s: ", p11_mechanism_to_name(mech.mechanism)); + +#define CIPHER_CHUNK (13) /* used to split input in sizes which are not block aligned */ + for (CK_ULONG ptlen = 0; ptlen < cipher_algs[i].ptsz;) { + + CK_ULONG isize = min(cipher_algs[i].ptsz - ptlen, CIPHER_CHUNK); + CK_ULONG osize = sizeof(ctext1) - coff; + + fct = "C_EncryptUpdate"; + rv = p11->C_EncryptUpdate(session, cipher_algs[i].plaintext + ptlen, isize, + ctext1 + coff, &osize); + if (rv == CKR_FUNCTION_NOT_SUPPORTED) { + printf(" Note: C_EncryptUpdate(), C_EncryptFinal() not supported\n"); + break; + } + if (rv != CKR_OK) { + goto cipher_clup; + } + + /* move offsets */ + ptlen += isize; + coff += osize; + } + + /* Only do final if update is supported */ + if (rv == CKR_OK) { + CK_ULONG osize = sizeof(ctext1) - coff; + fct = "C_EncryptFinal"; + rv = p11->C_EncryptFinal(session, ctext1 + coff, &osize); + if (rv != CKR_OK) { + goto cipher_clup; + } + + /* compare values for match */ + if (memcmp(ctext1, cipher_algs[i].ciphertext, cipher_algs[i].ctsz) != 0) { + printf("ERR: wrong ciphertext value\n"); + rv = CKR_GENERAL_ERROR; + goto cipher_clup; + } + } + + /* Second test is encrypt one shot */ + fct = "C_EncryptInit"; + rv = p11->C_EncryptInit(session, &mech, hkey); + if (rv != CKR_OK) { + goto cipher_clup; + } + + coff = sizeof(ctext2); + fct = "C_Encrypt"; + rv = p11->C_Encrypt(session, cipher_algs[i].plaintext, cipher_algs[i].ptsz, + ctext2, &coff); + if (rv == CKR_FUNCTION_NOT_SUPPORTED) { + printf(" Note: C_Encrypt() not supported\n"); + goto cipher_clup; + } + + /* compare values for match */ + if (memcmp(ctext2, cipher_algs[i].ciphertext, cipher_algs[i].ctsz) != 0) { + printf("ERR: wrong ciphertext value\n"); + rv = CKR_GENERAL_ERROR; + goto cipher_clup; + } + + /* Testing Decryption */ + + fct = "C_DecryptInit"; + rv = p11->C_DecryptInit(session, &mech, hkey); + if (rv == CKR_MECHANISM_INVALID) + continue; /* mechanism not implemented, don't test */ + if (rv != CKR_OK) { + goto cipher_clup; + } + + for (CK_ULONG ctlen = 0; ctlen < cipher_algs[i].ctsz;) { + + CK_ULONG isize = min(cipher_algs[i].ctsz - ctlen, CIPHER_CHUNK); + CK_ULONG osize = sizeof(ptext1) - poff; + + fct = "C_DecryptUpdate"; + rv = p11->C_DecryptUpdate(session, cipher_algs[i].ciphertext + ctlen, isize, + ptext1 + poff, &osize); + if (rv == CKR_FUNCTION_NOT_SUPPORTED) { + printf(" Note: C_DecryptUpdate(), C_DecryptFinal() not supported\n"); + break; + } + if (rv != CKR_OK) { + goto cipher_clup; + } + + /* move offsets */ + ctlen += isize; + poff += osize; + } + + /* Only do final if update is supported */ + if (rv == CKR_OK) { + CK_ULONG osize = sizeof(ptext1) - poff; + fct = "C_DecryptFinal"; + rv = p11->C_DecryptFinal(session, ptext1 + poff, &osize); + if (rv != CKR_OK) { + goto cipher_clup; + } + + /* compare values for match */ + if (memcmp(ptext1, cipher_algs[i].plaintext, cipher_algs[i].ptsz) != 0) { + printf("ERR: wrong plaintext value\n"); + rv = CKR_GENERAL_ERROR; + goto cipher_clup; + } + } + + /* Second test is decrypt one shot */ + fct = "C_DecryptInit"; + rv = p11->C_DecryptInit(session, &mech, hkey); + if (rv != CKR_OK) { + goto cipher_clup; + } + + poff = sizeof(ptext2); + fct = "C_Decrypt"; + rv = p11->C_Decrypt(session, cipher_algs[i].ciphertext, cipher_algs[i].ctsz, + ptext2, &poff); + if (rv == CKR_FUNCTION_NOT_SUPPORTED) { + printf(" Note: C_Decrypt() not supported\n"); + goto cipher_clup; + } + + /* compare values for match */ + if (memcmp(ptext2, cipher_algs[i].plaintext, cipher_algs[i].ptsz) != 0) { + printf("ERR: wrong plaintext value\n"); + rv = CKR_GENERAL_ERROR; + goto cipher_clup; + } + +cipher_clup: + test_delete_cipher_key(session, hkey); + if (rv != CKR_OK) { + p11_fatal(fct, rv); + } else { + printf("OK\n"); + } + } + + if (supported == 0) { + fprintf(stderr, "Ciphers: not implemented\n"); + } + + return errors; +} + #ifdef ENABLE_OPENSSL static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject) { @@ -7457,6 +7719,8 @@ static int p11_test(CK_SESSION_HANDLE session) errors += test_digest(session); + errors += test_cipher(session); + errors += test_signature(session); errors += test_verify(session); From f863110149c5b66aba70fd9efa2b3a3efc182b82 Mon Sep 17 00:00:00 2001 From: dlegault Date: Fri, 12 May 2023 09:15:54 -0400 Subject: [PATCH 2871/4321] rework for missing function and binary data declaration --- src/tools/pkcs11-tool.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 58872320b3..28620aecb8 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -96,6 +96,8 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; #define MAX_TEST_THREADS 10 #endif +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) + #define NEED_SESSION_RO 0x01 #define NEED_SESSION_RW 0x02 @@ -3630,7 +3632,7 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) if (!strstr((char *)data, "-----BEGIN ")) /* * d2i_PUBKEY_ex_bio is in OpenSSL master of 02/23/2023 - * committed Dec 26, 2022 expected in 3.2.0 + * committed Dec 26, 2022 expected in 3.2.0 */ #if OPENSSL_VERSION_NUMBER >= 0x30200000L *key = d2i_PUBKEY_ex_bio(mem, NULL, osslctx, NULL); @@ -6139,36 +6141,36 @@ static int test_cipher(CK_SESSION_HANDLE session) CK_SESSION_INFO sessionInfo; static struct { CK_MECHANISM_TYPE type; - uint8_t *key; + uint8_t key[32]; CK_ULONG keysz; CK_KEY_TYPE keytype; - uint8_t *iv; + uint8_t iv[16]; CK_ULONG ivsz; - uint8_t *plaintext; + uint8_t plaintext[128]; CK_ULONG ptsz; - uint8_t *ciphertext; + uint8_t ciphertext[128]; CK_ULONG ctsz; } cipher_algs[] = { { .type = CKM_AES_ECB, - .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .key = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}, .keysz = 16, .keytype = CKK_AES, - .plaintext = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", + .plaintext = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}, .ptsz = 16, - .ciphertext = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a", + .ciphertext = {0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30,0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a}, .ctsz = 16, }, { .type = CKM_AES_CBC, - .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .key = {0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c}, .keysz = 16, .keytype = CKK_AES, - .iv = "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d", + .iv = {0x76,0x49,0xab,0xac,0x81,0x19,0xb2,0x46,0xce,0xe9,0x8e,0x9b,0x12,0xe9,0x19,0x7d}, .ivsz = 16, - .plaintext = "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + .plaintext = {0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}, .ptsz = 16, - .ciphertext = "\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2", + .ciphertext = {0x50,0x86,0xcb,0x9b,0x50,0x72,0x19,0xee,0x95,0xdb,0x11,0x3a,0x91,0x76,0x78,0xb2}, .ctsz = 16, }, }; @@ -6220,7 +6222,7 @@ static int test_cipher(CK_SESSION_HANDLE session) #define CIPHER_CHUNK (13) /* used to split input in sizes which are not block aligned */ for (CK_ULONG ptlen = 0; ptlen < cipher_algs[i].ptsz;) { - CK_ULONG isize = min(cipher_algs[i].ptsz - ptlen, CIPHER_CHUNK); + CK_ULONG isize = MIN(cipher_algs[i].ptsz - ptlen, CIPHER_CHUNK); CK_ULONG osize = sizeof(ctext1) - coff; fct = "C_EncryptUpdate"; From 009a2329945d5d317bc7455722a774442db92c1c Mon Sep 17 00:00:00 2001 From: dlegault Date: Fri, 12 May 2023 09:33:04 -0400 Subject: [PATCH 2872/4321] change MIN macro declaration --- src/tools/pkcs11-tool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 28620aecb8..6a4e12291d 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -96,7 +96,9 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; #define MAX_TEST_THREADS 10 #endif -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#ifndef MIN +# define MIN(a, b) (((a) < (b))? (a) : (b)) +#endif #define NEED_SESSION_RO 0x01 #define NEED_SESSION_RW 0x02 From f0a5c62b85ae93a73c97c353f481e66f97c7395f Mon Sep 17 00:00:00 2001 From: dlegault Date: Fri, 12 May 2023 10:15:19 -0400 Subject: [PATCH 2873/4321] missed a min -> MIN --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 6a4e12291d..d5e8053a11 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -6295,7 +6295,7 @@ static int test_cipher(CK_SESSION_HANDLE session) for (CK_ULONG ctlen = 0; ctlen < cipher_algs[i].ctsz;) { - CK_ULONG isize = min(cipher_algs[i].ctsz - ctlen, CIPHER_CHUNK); + CK_ULONG isize = MIN(cipher_algs[i].ctsz - ctlen, CIPHER_CHUNK); CK_ULONG osize = sizeof(ptext1) - poff; fct = "C_DecryptUpdate"; From 493a3d4b5c99b282e0ec5304021041a22e0ae0c2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 12 May 2023 11:46:51 +0200 Subject: [PATCH 2874/4321] CI: tie ix86 to ubuntu-20.04 to avoid dependency problem in github image --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 36cdc904ea..9d921de165 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -52,7 +52,7 @@ jobs: - run: .github/build.sh no-shared build-ix86: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - run: .github/setup-linux.sh ix86 From 33b7736c7dbae8c15809a97fee644da574e2823a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 10 May 2023 11:03:03 +0200 Subject: [PATCH 2875/4321] sm: added more documentation to ISO 7816 SM workflow --- src/sm/sm-iso.h | 117 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 5 deletions(-) diff --git a/src/sm/sm-iso.h b/src/sm/sm-iso.h index 57f9ab3257..8d166a12f1 100644 --- a/src/sm/sm-iso.h +++ b/src/sm/sm-iso.h @@ -50,7 +50,112 @@ extern "C" { /** @brief Padding indicator: use no padding */ #define SM_NO_PADDING 0x02 -/** @brief Secure messaging context */ +/** @brief Secure messaging context + * + * This module provides *encoding and decoding* of secure messaging APDUs. The + * actual cryptographic operations need to be specified via the call backs of + * `struct iso_sm_ctx`. + * + * + * Initialization of ISO 7816 Secure Messaging: + * 1. Create the secure messaging context with iso_sm_ctx_create() + * 2. Customize `struct iso_sm_ctx` with the needed cryptographic callbacks + * and data + * 3. Run `iso_sm_start()`, which enables `SM_MODE_TRANSMIT`, so that all + * subsequent calls to sc_transmit_apdu() will be encrypted transparently. + * Memory ownership of `struct iso_sm_ctx` is transferred to the internal + * secure messaging context. + * + * + * Deinitialization of ISO 7816 Secure Messaging: + * 1. Run `sc_sm_stop()` + * 2. `clear_free()` hook is called + * 3. `struct iso_sm_ctx` is `free()`d + * + * + * Sending and receiving ISO 7816 Secure Messaging data: + * 1. Call `sc_transmit_apdu()` with an unencrypted APDU + * 2. `pre_transmit()` hook is called + * 3. Command APDU is encrypted (see workflow below) + * 4. Encrypted APDU is sent to the card + * 5. `post_transmit()` hook is called + * 6. Encrypted response is decrypted (see workflow below) + * 7. `finish()` hook is called + * + * + * Workflow for encrypting a command APDU: + * + * ┌───────────────┬────┬──────┬────┠+ * │ Header │ │ │ │ + * â–¶ Unencrypted command APDU │ CLA,INS,P1,P2 │ Lc │ Data │ Le │ + * └───────────────┴────┴──────┴────┘ + * ╱ ╱ │ ╲ + * 1. Add padding to `block_size` according to `padding_indicator` + * ╱ ╱ │ ╲ + * ╱ ╱ â–¼ â—¢ + * ╱ ╱ ┌───────────┠+ * ╱ ╱ │Padded Data│ + * ╱ ╱ └───────────┘ + * ╱ ╱ │ ╲ + * 2. Data encryption ╱ ╱ │ `encrypt()` ╲ + * ╱ ╱ â–¼ â—¢ + * ╱ ┌────┬──────┬─────────────────┬───────────────┬────┬──────┬──┠+ * ╱ │0x87│Length│Padding Indicator│Encrypted Data │0x97│Length│Le│ + * ╱ └────┴──────┴─────────────────┴───────────────┴────┴──────┴──┘ + * ╱ │ ╱ ╲ + * ╱ │ ╱ ╲ + * ╱ │ ╱ ╲ + * 3. Add padding to header and formatted encrypted data according to `padding_indicator` + * ╱ │ ╱ ╲ + * ╱ │ ╱ ╲ + * ╱ │ ╱ ╲ + * ╱ │ ╱ ╲ + * â—£ â–¼ â—£ â—¢ + * ┌─────────────┬────┬──────┬─────────────────┬───────────────┬────┬──────┬──┬─────────┠+ * │Padded Header│0x87│Length│Padding Indicator│Encrypted Data │0x97│Length│Le│ Padding │ + * └─────────────┴────┴──────┴─────────────────┴───────────────┴────┴──────┴──┴─────────┘ + * ╲ │ + * ──────────────────────────────────────────────────────────────── │ + * 4. MAC calculation `authenticate()` │ + * ╲ │ + * â—¢ â–¼ + * ┌────────┬────┬────┬──────┬─────────────────┬───────────────┬────┬──────┬──┬────┬──────┬───┬──────┠+ * │ Header │ Lc │0x87│Length│Padding Indicator│Encrypted Data │0x97│Length│Le│0x8E│Length│MAC│ 0x00 │ + * └────────┴────┴────┴──────┴─────────────────┴───────────────┴────┴──────┴──┴────┴──────┴───┴──────┘ + * â–¶ Encrypted command APDU + * + * + * Workflow for decrypting a response APDU + * + * â–¶ Encrypted response APDU + * ┌────┬──────┬─────────────────┬──────────────┬────┬────┬───────┬────┬──────┬───┬─────────┠+ * │0x87│Length│Padding Indicator│Encrypted Data│0x99│0x02│SW1/SW2│0x8E│Length│MAC│ SW1/SW2 │ + * └────┴──────┴─────────────────┴──────────────┴────┴────┴───────┴────┴──────┴───┴─────────┘ + * ╲ │ │ ╱ ╱ ╲ + * â—¢ │ │ â—£ â—£ â—¢ + * ┌────────────────────────────────────────────────────────┠┌─────────┠+ * │ `mac_data` │ │ `mac` │ + * └────────────────────────────────────────────────────────┘ └─────────┘ + * │ │ ╲ ╱ + * │ │ â—¢ â—£ + * 1. MAC verification │ │ `verify_authenticate()` + * â–¼ â–¼ + * ┌──────────────┠+ * │Encrypted Data│ + * └──────────────┘ + * 2. Decrypt data │ `decrypt()` ╱ + * â–¼ â—£ + * ┌───────────┠+ * │Padded Data│ + * └───────────┘ + * │ ╱ + * 3. Remove padding from data according to `padding_indicator` + * │ ╱ + * â–¼ â—£ + * ┌──────┬─────────┠+ * â–¶ Unencrypted response APDU │ Data │ SW1/SW2 │ + * └──────┴─────────┘ + **/ struct iso_sm_ctx { /** @brief data of the specific crypto implementation */ void *priv_data; @@ -60,10 +165,10 @@ struct iso_sm_ctx { /** @brief Pad to this block length */ size_t block_length; - /** @brief Call back function for authentication of data */ + /** @brief Call back function for authentication of data, i.e. MAC creation */ int (*authenticate)(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen, u8 **outdata); - /** @brief Call back function for verifying authentication data */ + /** @brief Call back function for verifying authentication data, i.e. MAC verification */ int (*verify_authentication)(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *mac, size_t maclen, const u8 *macdata, size_t macdatalen); @@ -75,10 +180,12 @@ struct iso_sm_ctx { int (*decrypt)(sc_card_t *card, const struct iso_sm_ctx *ctx, const u8 *enc, size_t enclen, u8 **data); - /** @brief Call back function for actions before encoding and encryption of \a apdu */ + /** @brief Call back function for actions before encoding and encryption of \a apdu, + * e.g. for incrementing a send sequence counter */ int (*pre_transmit)(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *apdu); - /** @brief Call back function for actions before decryption and decoding of \a sm_apdu */ + /** @brief Call back function for actions before decryption and decoding of \a sm_apdu, + * e.g. for incrementing a send sequence counter */ int (*post_transmit)(sc_card_t *card, const struct iso_sm_ctx *ctx, sc_apdu_t *sm_apdu); /** @brief Call back function for actions after decrypting SM protected APDU */ From d04ec3ea3c7cb3b47de28492b4eea5ed1be2cc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 May 2023 14:18:04 +0200 Subject: [PATCH 2876/4321] Remove unnecessary goto statement --- src/pkcs11/framework-pkcs15.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index e35324c805..9c7ec67fb4 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1408,21 +1408,19 @@ int slot_get_card_state(struct sc_pkcs11_slot *slot) int rv = 0; if (slot->p11card == NULL) { - goto out; + return 0; } fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx]; if (!fw_data) - goto out; + return 0; p15card = fw_data->p15_card; if (!p15card) - goto out; + return 0; if ((rv = sc_detect_card_presence(p15card->card->reader)) <= 0) - goto out; + return 0; return rv; -out: - return 0; } From 3864aafbbf92067bbcb654c00c3b386ec87cf96c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:24:47 +0100 Subject: [PATCH 2877/4321] pkcs15.c: add decompression into pkcs15 layer --- src/libopensc/pkcs15.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index c33b4d2e74..e1c42d5447 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -42,6 +42,10 @@ #include #endif +#ifdef ENABLE_ZLIB +#include "compression.h" +#endif + static const struct sc_asn1_entry c_asn1_twlabel[] = { { "twlabel", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } @@ -2395,6 +2399,23 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p return 0; } +static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, + unsigned char **out, size_t *outlen) +{ + LOG_FUNC_CALLED(card->ctx); +#ifdef ENABLE_ZLIB + int rv = SC_SUCCESS; + + rv = sc_decompress_alloc(out, outlen, buf, buflen, COMPRESSION_AUTO); + if (rv != SC_SUCCESS) { + sc_log(card->ctx, "Decompression failed: %d", rv); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); + } + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +#endif + sc_log(card->ctx, "Compression not supported, no zlib"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +} int sc_decode_do53(sc_context_t *ctx, u8 **data, size_t *data_len, @@ -2550,12 +2571,25 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat len = r; } else { - r = sc_read_binary(p15card->card, offset, data, len, 0); + unsigned long flags = 0; + r = sc_read_binary(p15card->card, offset, data, len, &flags); if (r < 0) { goto fail_unlock; } /* sc_read_binary may return less than requested */ len = r; + + if (flags & SC_FILE_COMPRESSED) { + unsigned char *decompressed_buf = NULL; + size_t decompressed_len = 0; + r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len); + if (r != SC_SUCCESS) { + goto fail_unlock; + } + free(data); + data = decompressed_buf; + len = decompressed_len; + } } sc_unlock(p15card->card); From 3fa1c6685d645582fb5f77e45e4d59b22c46f662 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 26 Jan 2023 10:31:02 +0100 Subject: [PATCH 2878/4321] Add flag for data compression --- src/libopensc/types.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libopensc/types.h b/src/libopensc/types.h index e0a615f3fc..36b00a159e 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -225,6 +225,9 @@ typedef struct sc_acl_entry { #define SC_FILE_EF_CYCLIC 0x06 #define SC_FILE_EF_CYCLIC_TLV 0x07 +/* Data compression */ +#define SC_FILE_COMPRESSED 0x08 + /* File status flags */ /* ISO7816-4: Unless otherwise specified, the security attributes are valid for the operational state.*/ #define SC_FILE_STATUS_ACTIVATED 0x00 /* ISO7816-4: Operational state (activated) (5, 7) */ From d21b4cece7a34fee8d45e408bc3602145d2d9701 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:06:50 +0100 Subject: [PATCH 2879/4321] card-cac.c: remove decompression from driver --- src/libopensc/card-cac.c | 16 +++------------- src/libopensc/card-cac1.c | 16 +++------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 1d1b616c86..cbecba27eb 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -49,9 +49,6 @@ #include "internal.h" #include "simpletlv.h" #include "cardctl.h" -#ifdef ENABLE_ZLIB -#include "compression.h" -#endif #include "iso7816.h" #include "card-cac-common.h" #include "pkcs15.h" @@ -577,16 +574,9 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { -#ifdef ENABLE_ZLIB - r = sc_decompress_alloc(&priv->cache_buf, &priv->cache_buf_len, - cert_ptr, cert_len, COMPRESSION_AUTO); -#else - sc_log(card->ctx, "CAC compression not supported, no zlib"); - r = SC_ERROR_NOT_SUPPORTED; -#endif - if (r) - goto done; - } else if (cert_len > 0) { + *flags |= SC_FILE_COMPRESSED; + } + if (cert_len > 0) { priv->cache_buf = malloc(cert_len); if (priv->cache_buf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 50c0928f54..da42213b03 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -49,9 +49,6 @@ #include "internal.h" #include "simpletlv.h" #include "cardctl.h" -#ifdef ENABLE_ZLIB -#include "compression.h" -#endif #include "iso7816.h" #include "card-cac-common.h" #include "pkcs15.h" @@ -171,16 +168,9 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { -#ifdef ENABLE_ZLIB - r = sc_decompress_alloc(&priv->cache_buf, &priv->cache_buf_len, - cert_ptr, cert_len, COMPRESSION_AUTO); -#else - sc_log(card->ctx, "CAC compression not supported, no zlib"); - r = SC_ERROR_NOT_SUPPORTED; -#endif - if (r) - goto done; - } else if (cert_len > 0) { + *flags |= SC_FILE_COMPRESSED; + } + if (cert_len > 0) { priv->cache_buf = malloc(cert_len); if (priv->cache_buf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; From e1c0029e3dd0adc76c539d6e5af4c6dd10fe7f9d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:08:23 +0100 Subject: [PATCH 2880/4321] card-dnie.c: remove decompression from driver --- src/libopensc/card-dnie.c | 69 ++++++++++++--------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 2c36ddf5c3..f810ae89d1 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -38,7 +38,6 @@ #include "opensc.h" #include "cardctl.h" #include "internal.h" -#include "compression.h" #include "cwa14890.h" #include "cwa-dnie.h" @@ -904,34 +903,32 @@ static int dnie_finish(struct sc_card *card) /* ISO 7816-4 functions */ /** - * Uncompress data if in compressed format. + * Check whether data are compressed. * * @param card pointer to sc_card_t structure * @param from buffer to get data from - * @param len pointer to buffer length - * @return uncompressed or original buffer; len points to new buffer length - * on error return null + * @param len buffer length + * @return 1 if data are compressed, 0 otherwise; len points to expected length of decompressed data */ -static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) + +static int dnie_is_compressed(sc_card_t * card, u8 * from, size_t len) { - u8 *upt = from; #ifdef ENABLE_ZLIB - int res = SC_SUCCESS; size_t uncompressed = 0L; size_t compressed = 0L; if (!card || !card->ctx || !from || !len) - return NULL; + return 0; LOG_FUNC_CALLED(card->ctx); /* if data size not enough for compression header assume uncompressed */ - if (*len < 8) + if (len < 8) goto compress_exit; /* evaluate compressed an uncompressed sizes (little endian format) */ uncompressed = lebytes2ulong(from); compressed = lebytes2ulong(from + 4); /* if compressed size doesn't match data length assume not compressed */ - if (compressed != (*len) - 8) + if (compressed != len - 8) goto compress_exit; /* if compressed size greater than uncompressed, assume uncompressed data */ if (uncompressed < compressed) @@ -940,32 +937,14 @@ static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) if (uncompressed > MAX_FILE_SIZE) goto compress_exit; - sc_log(card->ctx, "Data seems to be compressed. calling uncompress"); - /* ok: data seems to be compressed */ - upt = calloc(uncompressed, sizeof(u8)); - if (!upt) { - sc_log(card->ctx, "alloc() for uncompressed buffer failed"); - return NULL; - } - *len = uncompressed; - res = sc_decompress(upt, /* try to uncompress by calling sc_xx routine */ - len, - from + 8, (size_t) compressed, COMPRESSION_ZLIB); - if (res != SC_SUCCESS) { - sc_log(card->ctx, "Uncompress() failed or data not compressed"); - goto compress_exit; /* assume not need uncompression */ - } - /* Done; update buffer len and return pt to uncompressed data */ - sc_log_hex(card->ctx, "Compressed data", from + 8, compressed); - sc_log_hex(card->ctx, "Uncompressed data", upt, uncompressed); - compress_exit: - + sc_log(card->ctx, "Data seems to be compressed."); + return 1; +compress_exit: #endif - sc_log(card->ctx, "uncompress: returning with%s de-compression ", - (upt == from) ? "out" : ""); - return upt; -} + sc_log(card->ctx, "Data not compressed."); + return 0; +} /** * Fill file cache for read_binary() operation. @@ -985,14 +964,14 @@ static u8 *dnie_uncompress(sc_card_t * card, u8 * from, size_t *len) * @param card Pointer to card structure * @return SC_SUCCESS if OK; else error code */ -static int dnie_fill_cache(sc_card_t * card) +static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) { u8 tmp[MAX_RESP_BUFFER_SIZE]; sc_apdu_t apdu; size_t count = 0; size_t len = 0; u8 *buffer = NULL; - u8 *pt = NULL, *p; + u8 *p; sc_context_t *ctx = NULL; if (!card || !card->ctx) @@ -1068,21 +1047,15 @@ static int dnie_fill_cache(sc_card_t * card) } read_done: - /* no more data to read: check if data is compressed */ - pt = dnie_uncompress(card, buffer, &len); + if (dnie_is_compressed(card, buffer, len)) { + *flags |= SC_FILE_COMPRESSED; + } free((void *)apdu.data); if (apdu.resp != tmp) free(apdu.resp); - if (pt == NULL) { - sc_log(ctx, "Uncompress process failed"); - free(buffer); - LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); - } - if (pt != buffer) - free(buffer); /* ok: as final step, set correct cache data into dnie_priv structures */ - GET_DNIE_PRIV_DATA(card)->cache = pt; + GET_DNIE_PRIV_DATA(card)->cache = buffer; GET_DNIE_PRIV_DATA(card)->cachelen = len; sc_log(ctx, "fill_cache() done. length '%"SC_FORMAT_LEN_SIZE_T"u' bytes", @@ -1117,7 +1090,7 @@ static int dnie_read_binary(struct sc_card *card, LOG_FUNC_CALLED(ctx); if (idx == 0 || GET_DNIE_PRIV_DATA(card)->cache == NULL) { /* on first block or no cache, try to fill */ - res = dnie_fill_cache(card); + res = dnie_fill_cache(card, flags); if (res < 0) { sc_log(ctx, "Cannot fill cache. using iso_read_binary()"); return iso_ops->read_binary(card, idx, buf, count, flags); From ba2dad675174ba53886602bb2494bf618a34d77c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:13:29 +0100 Subject: [PATCH 2881/4321] card-gids.c: remove decompression from driver --- src/libopensc/card-gids.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index f41af2707e..bb23f8e7e6 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1069,19 +1069,10 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } if (buffer[0] == 1 && buffer[1] == 0) { - size_t expectedsize = buffer[2] + buffer[3] * 0x100; - data->buffersize = sizeof(data->buffer); - r = sc_decompress(data->buffer, &(data->buffersize), buffer+4, buffersize-4, COMPRESSION_ZLIB); - if (r != SC_SUCCESS) { - sc_log(card->ctx, "Zlib error: %d", r); - LOG_FUNC_RETURN(card->ctx, r); - } - if (data->buffersize != expectedsize) { - sc_log(card->ctx, - "expected size: %"SC_FORMAT_LEN_SIZE_T"u real size: %"SC_FORMAT_LEN_SIZE_T"u", - expectedsize, data->buffersize); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); - } + *flags |= SC_FILE_COMPRESSED; + /* compressed data are starting on position buffer + 4 */ + data->buffersize = sizeof(data->buffer) - 4; + memcpy(data->buffer, buffer + 4, buffersize); } else { sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] <<8)); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); From c335afecd020c6beda42e23473b66db44512b892 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:18:44 +0100 Subject: [PATCH 2882/4321] card-idprime.c: remove decompression from driver --- src/libopensc/card-idprime.c | 42 ++++++++++-------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index c20f82f11a..ee735969e9 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -28,9 +28,6 @@ #include #include #include -#ifdef ENABLE_ZLIB -#include "compression.h" -#endif #include "cardctl.h" #include "pkcs15.h" @@ -550,8 +547,6 @@ static int idprime_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil if (len == HEADER_LEN && data[0] == 0x01 && data[1] == 0x00) { /* Cache the real file size for the caching read_binary() */ priv->file_size = (*file_out)->size; - /* Fix the information in the file structure to not confuse upper layers */ - (*file_out)->size = (data[3]<<8) | data[2]; } } /* Return the exit code of the select command */ @@ -576,6 +571,7 @@ static int idprime_read_binary(sc_card_t *card, unsigned int offset, // this function is called to read and uncompress the certificate u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE]; + u8 *data_buffer = buffer; if (sizeof(buffer) < count || sizeof(buffer) < priv->file_size) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -591,33 +587,17 @@ static int idprime_read_binary(sc_card_t *card, unsigned int offset, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } if (buffer[0] == 1 && buffer[1] == 0) { -#ifdef ENABLE_ZLIB - size_t expectedsize = buffer[2] + buffer[3] * 0x100; - r = sc_decompress_alloc(&priv->cache_buf, &(priv->cache_buf_len), - buffer+4, priv->file_size-4, COMPRESSION_AUTO); - if (r != SC_SUCCESS) { - sc_log(card->ctx, "Zlib error: %d", r); - LOG_FUNC_RETURN(card->ctx, r); - } - if (priv->cache_buf_len != expectedsize) { - sc_log(card->ctx, - "expected size: %"SC_FORMAT_LEN_SIZE_T"u real size: %"SC_FORMAT_LEN_SIZE_T"u", - expectedsize, priv->cache_buf_len); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); - } -#else - sc_log(card->ctx, "compression not supported, no zlib"); - return SC_ERROR_NOT_SUPPORTED; -#endif /* ENABLE_ZLIB */ - } else { - /* assuming uncompressed certificate */ - priv->cache_buf = malloc(r); - if (priv->cache_buf == NULL) { - return SC_ERROR_OUT_OF_MEMORY; - } - memcpy(priv->cache_buf, buffer, r); - priv->cache_buf_len = r; + /* Data will be decompressed later */ + data_buffer += 4; + r = priv->file_size - 4; + *flags |= SC_FILE_COMPRESSED; + } + priv->cache_buf = malloc(r); + if (priv->cache_buf == NULL) { + return SC_ERROR_OUT_OF_MEMORY; } + memcpy(priv->cache_buf, data_buffer, r); + priv->cache_buf_len = r; priv->cached = 1; } if (offset >= priv->cache_buf_len) { From 9730900cbe3af71e32991d809f4ca25f005ba89c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 10:23:35 +0100 Subject: [PATCH 2883/4321] card-piv.c: remove decompression from driver --- src/libopensc/card-piv.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index d7b58f51cd..3cb23704ea 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -50,9 +50,6 @@ #include "internal.h" #include "asn1.h" #include "cardctl.h" -#ifdef ENABLE_ZLIB -#include "compression.h" -#endif #include "simpletlv.h" enum { @@ -131,6 +128,7 @@ enum { */ #define PIV_OBJ_CACHE_VALID 1 +#define PIV_OBJ_CACHE_COMPRESSED 2 #define PIV_OBJ_CACHE_NOT_PRESENT 8 typedef struct piv_obj_cache { @@ -1096,27 +1094,14 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); if(compressed) { -#ifdef ENABLE_ZLIB - size_t len; - u8* newBuf = NULL; - - if(SC_SUCCESS != sc_decompress_alloc(&newBuf, &len, tag, taglen, COMPRESSION_AUTO)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); - - priv->obj_cache[enumtag].internal_obj_data = newBuf; - priv->obj_cache[enumtag].internal_obj_len = len; -#else - sc_log(card->ctx, "PIV compression not supported, no zlib"); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); -#endif + priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_COMPRESSED; } - else { - if (!(priv->obj_cache[enumtag].internal_obj_data = malloc(taglen))) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + /* internal certificate remains compressed */ + if (!(priv->obj_cache[enumtag].internal_obj_data = malloc(taglen))) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen); - priv->obj_cache[enumtag].internal_obj_len = taglen; - } + memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen); + priv->obj_cache[enumtag].internal_obj_len = taglen; /* convert pub key to internal */ /* TODO: -DEE need to fix ... would only be used if we cache the pub key, but we don't today */ @@ -1208,6 +1193,9 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co if (priv->return_only_cert || piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) { rbuf = priv->obj_cache[enumtag].internal_obj_data; rbuflen = priv->obj_cache[enumtag].internal_obj_len; + if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) { + *flags |= SC_FILE_COMPRESSED; + } } else { rbuf = priv->obj_cache[enumtag].obj_data; rbuflen = priv->obj_cache[enumtag].obj_len; From 8d62e28426720cfe07b5fe25f8ab5ac8c0bff04e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 24 Mar 2023 17:23:31 +0100 Subject: [PATCH 2884/4321] Update sc_read_binary() parameters --- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-belpic.c | 2 +- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cac1.c | 2 +- src/libopensc/card-coolkey.c | 2 +- src/libopensc/card-dnie.c | 2 +- src/libopensc/card-entersafe.c | 2 +- src/libopensc/card-esteid2018.c | 2 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-idprime.c | 2 +- src/libopensc/card-itacns.c | 2 +- src/libopensc/card-muscle.c | 2 +- src/libopensc/card-oberthur.c | 4 ++-- src/libopensc/card-openpgp.c | 2 +- src/libopensc/card-piv.c | 2 +- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/card.c | 2 +- src/libopensc/iso7816.c | 2 +- src/libopensc/opensc.h | 4 ++-- src/pkcs15init/pkcs15-oberthur-awp.c | 4 +++- 22 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 34b36a2121..5be9aa1662 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -841,7 +841,7 @@ authentic_select_file(struct sc_card *card, const struct sc_path *path, static int authentic_read_binary(struct sc_card *card, unsigned int idx, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { struct sc_context *ctx = card->ctx; struct sc_apdu apdu; diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index c281f67b54..4064a074d5 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -296,7 +296,7 @@ static int belpic_select_file(sc_card_t *card, } static int belpic_read_binary(sc_card_t *card, - unsigned int idx, u8 * buf, size_t count, unsigned long flags) + unsigned int idx, u8 * buf, size_t count, unsigned long *flags) { int r; diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index cbecba27eb..3b932ada4a 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -450,7 +450,7 @@ static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *o * as well as set that we want the cert from the object. */ static int cac_read_binary(sc_card_t *card, unsigned int idx, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { cac_private_data_t * priv = CAC_DATA(card); int r = 0; diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index da42213b03..5ebfb2ebe3 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -122,7 +122,7 @@ static int cac_cac1_get_certificate(sc_card_t *card, u8 **out_buf, size_t *out_l * as well as set that we want the cert from the object. */ static int cac_read_binary(sc_card_t *card, unsigned int idx, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { cac_private_data_t * priv = CAC_DATA(card); int r = 0; diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 918dfdc4f0..3aa1897d6a 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -1175,7 +1175,7 @@ static int coolkey_write_object(sc_card_t *card, unsigned long object_id, * translate the objects into their PKCS #15 equivalent data structures. */ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, - u8 *buf, size_t count, unsigned long flags) + u8 *buf, size_t count, unsigned long *flags) { coolkey_private_data_t * priv = COOLKEY_DATA(card); int r = 0, len; diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index f810ae89d1..2b8b9903f2 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1078,7 +1078,7 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) */ static int dnie_read_binary(struct sc_card *card, unsigned int idx, - u8 * buf, size_t count, unsigned long flags) + u8 * buf, size_t count, unsigned long *flags) { int res = 0; sc_context_t *ctx = NULL; diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index ec81f0eaa1..bcc3224961 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -423,7 +423,7 @@ static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, static int entersafe_read_binary(sc_card_t *card, unsigned int idx, u8 *buf, size_t count, - unsigned long flags) + unsigned long *flags) { sc_apdu_t apdu; u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index e4b9baa2be..db2d18e714 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -143,7 +143,7 @@ static int esteid_select_file(struct sc_card *card, const struct sc_path *in_pat } // temporary hack, overload 6B00 SW processing -static int esteid_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags) { +static int esteid_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long *flags) { int r; int (*saved)(struct sc_card *, unsigned int, unsigned int) = card->ops->check_sw; LOG_FUNC_CALLED(card->ctx); diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index bb23f8e7e6..2c9b55a343 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1048,7 +1048,7 @@ gids_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left // used to read existing certificates static int gids_read_binary(sc_card_t *card, unsigned int offset, - unsigned char *buf, size_t count, unsigned long flags) { + unsigned char *buf, size_t count, unsigned long *flags) { struct gids_private_data *data = (struct gids_private_data *) card->drv_data; struct sc_context *ctx = card->ctx; int r; diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 2bdaf474a2..59ab0a531e 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -678,7 +678,7 @@ gpk_select_file(sc_card_t *card, const sc_path_t *path, */ static int gpk_read_binary(sc_card_t *card, unsigned int offset, - u8 *buf, size_t count, unsigned long flags) + u8 *buf, size_t count, unsigned long *flags) { struct gpk_private_data *priv = DRVDATA(card); diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index d8c0863b99..dc3b673ead 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -726,7 +726,7 @@ iasecc_init(struct sc_card *card) static int iasecc_read_binary(struct sc_card *card, unsigned int offs, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { struct sc_context *ctx = card->ctx; struct sc_apdu apdu; diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index ee735969e9..be445896b2 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -555,7 +555,7 @@ static int idprime_select_file(sc_card_t *card, const sc_path_t *in_path, sc_fil // used to read existing certificates static int idprime_read_binary(sc_card_t *card, unsigned int offset, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { struct idprime_private_data *priv = card->drv_data; int r = 0; diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 68548f1abb..3d8c0f3b07 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -312,7 +312,7 @@ itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, static int itacns_read_binary(sc_card_t *card, unsigned int idx, u8 *buf, size_t count, - unsigned long flags) + unsigned long *flags) { size_t already_read = 0; int requested; diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 5a868115b5..bbdee63b30 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -198,7 +198,7 @@ static int muscle_create_file(sc_card_t *card, sc_file_t *file) return r; } -static int muscle_read_binary(sc_card_t *card, unsigned int idx, u8* buf, size_t count, unsigned long flags) +static int muscle_read_binary(sc_card_t *card, unsigned int idx, u8* buf, size_t count, unsigned long *flags) { mscfs_t *fs = MUSCLE_FS(card); int r; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index cf39fec5f9..6098e65e01 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2110,7 +2110,7 @@ auth_update_binary(struct sc_card *card, unsigned int offset, static int auth_read_binary(struct sc_card *card, unsigned int offset, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { int rv; struct sc_pkcs15_bignum bn[2]; @@ -2125,7 +2125,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, sc_log(card->ctx, "offset %i; size %"SC_FORMAT_LEN_SIZE_T"u; flags 0x%lX", - offset, count, flags); + offset, count, *flags); sc_log(card->ctx,"last selected : magic %X; ef %X", auth_current_ef->magic, auth_current_ef->ef_structure); diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 9e2f12f5d2..e51e33b721 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1577,7 +1577,7 @@ pgp_get_challenge(struct sc_card *card, u8 *rnd, size_t len) */ static int pgp_read_binary(sc_card_t *card, unsigned int idx, - u8 *buf, size_t count, unsigned long flags) + u8 *buf, size_t count, unsigned long *flags) { struct pgp_priv_data *priv = DRVDATA(card); pgp_blob_t *blob; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 3cb23704ea..896957305b 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1139,7 +1139,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) * as well as set that we want the cert from the object. */ static int -piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t count, unsigned long flags) +piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t count, unsigned long *flags) { piv_private_data_t * priv = PIV_DATA(card); int enumtag; diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index c100a87c2a..5a848c1701 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -785,7 +785,7 @@ static int sc_hsm_logout(sc_card_t * card) /* NOTE: idx is an offset into the card's file, not into buf */ static int sc_hsm_read_binary(sc_card_t *card, unsigned int idx, u8 *buf, size_t count, - unsigned long flags) + unsigned long *flags) { sc_context_t *ctx = card->ctx; sc_apdu_t apdu; diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 5a5adb8e35..164498a53d 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -617,7 +617,7 @@ int sc_delete_file(sc_card_t *card, const sc_path_t *path) } int sc_read_binary(sc_card_t *card, unsigned int idx, - unsigned char *buf, size_t count, unsigned long flags) + unsigned char *buf, size_t count, unsigned long *flags) { size_t max_le = sc_get_max_recv_size(card); size_t todo = count; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 80a6885d62..0535222a36 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -136,7 +136,7 @@ iso7816_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) static int -iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags) +iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long *flags) { struct sc_context *ctx = card->ctx; struct sc_apdu apdu; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 2c5e77d67a..4b0fb3d0ad 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -658,7 +658,7 @@ struct sc_card_operations { * @see sc_read_binary() */ int (*read_binary)(struct sc_card *card, unsigned int idx, - u8 * buf, size_t count, unsigned long flags); + u8 * buf, size_t count, unsigned long *flags); /** * @brief Write data to a binary EF with a single command * @@ -1250,7 +1250,7 @@ int sc_list_files(struct sc_card *card, u8 *buf, size_t buflen); * @return number of bytes read or an error code */ int sc_read_binary(struct sc_card *card, unsigned int idx, u8 * buf, - size_t count, unsigned long flags); + size_t count, unsigned long *flags); /** * @brief Write data to a binary EF * diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 97d1e65240..2e74325786 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -643,6 +643,7 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil unsigned char *buff = NULL; int rv; unsigned ii; + unsigned long flags; LOG_FUNC_CALLED(ctx); sc_log(ctx, "type %i, num %i", type, num); @@ -722,7 +723,8 @@ awp_update_object_list(struct sc_pkcs15_card *p15card, struct sc_profile *profil if (rv < 0) goto done; - rv = sc_read_binary(p15card->card, 0, buff, lst_file->size, lst_file->ef_structure); + flags = lst_file->ef_structure; + rv = sc_read_binary(p15card->card, 0, buff, lst_file->size, &flags); if (rv < 0) goto done; From ec03221e60704fe18de957fdc709a7b3cf255b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 28 Apr 2023 16:16:39 +0200 Subject: [PATCH 2885/4321] pkcs15.c: enclose missing zlib log message into else branch --- src/libopensc/pkcs15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index e1c42d5447..3e278024af 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2412,9 +2412,10 @@ static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); -#endif +#else sc_log(card->ctx, "Compression not supported, no zlib"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +#endif } int From c3366e2dc968a2500585f76482e75d7afafd6e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 28 Apr 2023 16:17:51 +0200 Subject: [PATCH 2886/4321] card-dnie.c: remove first 8 bytes from buffer for decompression --- src/libopensc/card-dnie.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 2b8b9903f2..949afcbd11 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1049,6 +1049,8 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) read_done: if (dnie_is_compressed(card, buffer, len)) { *flags |= SC_FILE_COMPRESSED; + buffer += 8; + len -= 8; } free((void *)apdu.data); if (apdu.resp != tmp) From d20578676226c39ad64d6faf2e0c117b174a8170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 28 Apr 2023 15:51:18 +0200 Subject: [PATCH 2887/4321] Differentiate between different types of decompression --- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cac1.c | 2 +- src/libopensc/card-dnie.c | 2 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-idprime.c | 2 +- src/libopensc/card-piv.c | 2 +- src/libopensc/pkcs15.c | 19 +++++++++++++++---- src/libopensc/types.h | 4 +++- 8 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 3b932ada4a..a031917e29 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -574,7 +574,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_AUTO; } if (cert_len > 0) { priv->cache_buf = malloc(cert_len); diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 5ebfb2ebe3..d018354597 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -168,7 +168,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_AUTO; } if (cert_len > 0) { priv->cache_buf = malloc(cert_len); diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 949afcbd11..d46482b280 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1048,7 +1048,7 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) read_done: if (dnie_is_compressed(card, buffer, len)) { - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_ZLIB; buffer += 8; len -= 8; } diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 2c9b55a343..a2879dd0fd 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1069,7 +1069,7 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } if (buffer[0] == 1 && buffer[1] == 0) { - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_ZLIB; /* compressed data are starting on position buffer + 4 */ data->buffersize = sizeof(data->buffer) - 4; memcpy(data->buffer, buffer + 4, buffersize); diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index be445896b2..1c405dfd2e 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -590,7 +590,7 @@ static int idprime_read_binary(sc_card_t *card, unsigned int offset, /* Data will be decompressed later */ data_buffer += 4; r = priv->file_size - 4; - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_AUTO; } priv->cache_buf = malloc(r); if (priv->cache_buf == NULL) { diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 896957305b..780d683e41 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1194,7 +1194,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co rbuf = priv->obj_cache[enumtag].internal_obj_data; rbuflen = priv->obj_cache[enumtag].internal_obj_len; if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) { - *flags |= SC_FILE_COMPRESSED; + *flags |= SC_FILE_COMPRESSED_AUTO; } } else { rbuf = priv->obj_cache[enumtag].obj_data; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 3e278024af..d819e1147d 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2400,13 +2400,22 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p } static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, - unsigned char **out, size_t *outlen) + unsigned char **out, size_t *outlen, unsigned long flags) { LOG_FUNC_CALLED(card->ctx); #ifdef ENABLE_ZLIB int rv = SC_SUCCESS; + int method = 0; - rv = sc_decompress_alloc(out, outlen, buf, buflen, COMPRESSION_AUTO); + if (flags & SC_FILE_COMPRESSED_GZIP) { + method = COMPRESSION_GZIP; + } else if (flags & SC_FILE_COMPRESSED_ZLIB) { + method = COMPRESSION_ZLIB; + } else { + method = COMPRESSION_AUTO; + } + + rv = sc_decompress_alloc(out, outlen, buf, buflen, method); if (rv != SC_SUCCESS) { sc_log(card->ctx, "Decompression failed: %d", rv); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); @@ -2580,10 +2589,12 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat /* sc_read_binary may return less than requested */ len = r; - if (flags & SC_FILE_COMPRESSED) { + if (flags & SC_FILE_COMPRESSED_AUTO + || flags & SC_FILE_COMPRESSED_ZLIB + || flags & SC_FILE_COMPRESSED_GZIP) { unsigned char *decompressed_buf = NULL; size_t decompressed_len = 0; - r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len); + r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len, flags); if (r != SC_SUCCESS) { goto fail_unlock; } diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 36b00a159e..1c9bf315d4 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -226,7 +226,9 @@ typedef struct sc_acl_entry { #define SC_FILE_EF_CYCLIC_TLV 0x07 /* Data compression */ -#define SC_FILE_COMPRESSED 0x08 +#define SC_FILE_COMPRESSED_AUTO 0x08 +#define SC_FILE_COMPRESSED_ZLIB 0x09 +#define SC_FILE_COMPRESSED_GZIP 0x0a /* File status flags */ /* ISO7816-4: Unless otherwise specified, the security attributes are valid for the operational state.*/ From 26d8315746fc6d1b8d0338eee3ffeeff94a121dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 28 Apr 2023 16:27:12 +0200 Subject: [PATCH 2888/4321] Do not dereference NULL pointer --- src/libopensc/card-oberthur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 6098e65e01..acda8be59c 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -2125,7 +2125,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, sc_log(card->ctx, "offset %i; size %"SC_FORMAT_LEN_SIZE_T"u; flags 0x%lX", - offset, count, *flags); + offset, count, flags ? *flags : 0); sc_log(card->ctx,"last selected : magic %X; ef %X", auth_current_ef->magic, auth_current_ef->ef_structure); From ab9451b903c620e0d5f115d57e5796c8978b370c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 28 Apr 2023 16:46:05 +0200 Subject: [PATCH 2889/4321] card-dnie.c: NULL dereference when reading binary --- src/libopensc/card-dnie.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index d46482b280..d609b5958f 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1048,7 +1048,8 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) read_done: if (dnie_is_compressed(card, buffer, len)) { - *flags |= SC_FILE_COMPRESSED_ZLIB; + if (flags) + *flags |= SC_FILE_COMPRESSED_ZLIB; buffer += 8; len -= 8; } From 83524863d48b1fa8bae2d49d72cd39baeab4a236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 May 2023 10:58:10 +0200 Subject: [PATCH 2890/4321] card-dnie.c: remove first 8 bytes from compressed data Allocate new buffer and copy only compressed data without first 8 bytes used for determination of compression. --- src/libopensc/card-dnie.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index d609b5958f..5873478bcc 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1047,15 +1047,25 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) } read_done: + free((void *)apdu.data); + if (apdu.resp != tmp) + free(apdu.resp); + if (dnie_is_compressed(card, buffer, len)) { if (flags) *flags |= SC_FILE_COMPRESSED_ZLIB; - buffer += 8; + /* Remove first 8 bytes with compression info*/ len -= 8; + p = malloc(len); + if (!p) { + free(buffer); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } + memcpy(p, buffer + 8, len); + free(buffer); + buffer = p; } - free((void *)apdu.data); - if (apdu.resp != tmp) - free(apdu.resp); + /* ok: as final step, set correct cache data into dnie_priv structures */ GET_DNIE_PRIV_DATA(card)->cache = buffer; From 0fa815e1f314b9b0865095c44a52ae2ac4fa542c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 May 2023 11:21:01 +0200 Subject: [PATCH 2891/4321] Check flags before dereference --- src/libopensc/card-cac.c | 2 +- src/libopensc/card-gids.c | 3 ++- src/libopensc/card-idprime.c | 3 ++- src/libopensc/card-piv.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index a031917e29..89b94c8672 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -573,7 +573,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } } /* if the info byte is 1, then the cert is compressed, decompress it */ - if ((cert_type & 0x3) == 1) { + if ((cert_type & 0x3) == 1 && flags) { *flags |= SC_FILE_COMPRESSED_AUTO; } if (cert_len > 0) { diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index a2879dd0fd..b68592b80e 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1069,7 +1069,8 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA); } if (buffer[0] == 1 && buffer[1] == 0) { - *flags |= SC_FILE_COMPRESSED_ZLIB; + if (flags) + *flags |= SC_FILE_COMPRESSED_ZLIB; /* compressed data are starting on position buffer + 4 */ data->buffersize = sizeof(data->buffer) - 4; memcpy(data->buffer, buffer + 4, buffersize); diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 1c405dfd2e..0d927c1d5f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -590,7 +590,8 @@ static int idprime_read_binary(sc_card_t *card, unsigned int offset, /* Data will be decompressed later */ data_buffer += 4; r = priv->file_size - 4; - *flags |= SC_FILE_COMPRESSED_AUTO; + if (flags) + *flags |= SC_FILE_COMPRESSED_AUTO; } priv->cache_buf = malloc(r); if (priv->cache_buf == NULL) { diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 780d683e41..c2670b4595 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1193,7 +1193,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co if (priv->return_only_cert || piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) { rbuf = priv->obj_cache[enumtag].internal_obj_data; rbuflen = priv->obj_cache[enumtag].internal_obj_len; - if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) { + if ((priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) && flags) { *flags |= SC_FILE_COMPRESSED_AUTO; } } else { From e9d7b52b7483299ee259c0f0a2b3b8ae6aa5c543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 10 May 2023 15:49:39 +0200 Subject: [PATCH 2892/4321] Use separate naming for compression file flags --- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cac1.c | 2 +- src/libopensc/card-dnie.c | 2 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-idprime.c | 2 +- src/libopensc/card-piv.c | 2 +- src/libopensc/pkcs15.c | 10 +++++----- src/libopensc/types.h | 8 ++++---- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 89b94c8672..b565feeefd 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -574,7 +574,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, } /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1 && flags) { - *flags |= SC_FILE_COMPRESSED_AUTO; + *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; } if (cert_len > 0) { priv->cache_buf = malloc(cert_len); diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index d018354597..60c979908b 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -168,7 +168,7 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) { - *flags |= SC_FILE_COMPRESSED_AUTO; + *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; } if (cert_len > 0) { priv->cache_buf = malloc(cert_len); diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 5873478bcc..36d168463f 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -1053,7 +1053,7 @@ static int dnie_fill_cache(sc_card_t * card,unsigned long *flags) if (dnie_is_compressed(card, buffer, len)) { if (flags) - *flags |= SC_FILE_COMPRESSED_ZLIB; + *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB; /* Remove first 8 bytes with compression info*/ len -= 8; p = malloc(len); diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index b68592b80e..ed122c89cd 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1070,7 +1070,7 @@ static int gids_read_binary(sc_card_t *card, unsigned int offset, } if (buffer[0] == 1 && buffer[1] == 0) { if (flags) - *flags |= SC_FILE_COMPRESSED_ZLIB; + *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB; /* compressed data are starting on position buffer + 4 */ data->buffersize = sizeof(data->buffer) - 4; memcpy(data->buffer, buffer + 4, buffersize); diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 0d927c1d5f..2a8d42f8f1 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -591,7 +591,7 @@ static int idprime_read_binary(sc_card_t *card, unsigned int offset, data_buffer += 4; r = priv->file_size - 4; if (flags) - *flags |= SC_FILE_COMPRESSED_AUTO; + *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; } priv->cache_buf = malloc(r); if (priv->cache_buf == NULL) { diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c2670b4595..a4fea759e4 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1194,7 +1194,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co rbuf = priv->obj_cache[enumtag].internal_obj_data; rbuflen = priv->obj_cache[enumtag].internal_obj_len; if ((priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) && flags) { - *flags |= SC_FILE_COMPRESSED_AUTO; + *flags |= SC_FILE_FLAG_COMPRESSED_AUTO; } } else { rbuf = priv->obj_cache[enumtag].obj_data; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index d819e1147d..199d1a6082 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -2407,9 +2407,9 @@ static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, int rv = SC_SUCCESS; int method = 0; - if (flags & SC_FILE_COMPRESSED_GZIP) { + if (flags & SC_FILE_FLAG_COMPRESSED_GZIP) { method = COMPRESSION_GZIP; - } else if (flags & SC_FILE_COMPRESSED_ZLIB) { + } else if (flags & SC_FILE_FLAG_COMPRESSED_ZLIB) { method = COMPRESSION_ZLIB; } else { method = COMPRESSION_AUTO; @@ -2589,9 +2589,9 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat /* sc_read_binary may return less than requested */ len = r; - if (flags & SC_FILE_COMPRESSED_AUTO - || flags & SC_FILE_COMPRESSED_ZLIB - || flags & SC_FILE_COMPRESSED_GZIP) { + if (flags & SC_FILE_FLAG_COMPRESSED_AUTO + || flags & SC_FILE_FLAG_COMPRESSED_ZLIB + || flags & SC_FILE_FLAG_COMPRESSED_GZIP) { unsigned char *decompressed_buf = NULL; size_t decompressed_len = 0; r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len, flags); diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 1c9bf315d4..af4ced71bd 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -225,10 +225,10 @@ typedef struct sc_acl_entry { #define SC_FILE_EF_CYCLIC 0x06 #define SC_FILE_EF_CYCLIC_TLV 0x07 -/* Data compression */ -#define SC_FILE_COMPRESSED_AUTO 0x08 -#define SC_FILE_COMPRESSED_ZLIB 0x09 -#define SC_FILE_COMPRESSED_GZIP 0x0a +/* File flags */ +#define SC_FILE_FLAG_COMPRESSED_AUTO 0x01 +#define SC_FILE_FLAG_COMPRESSED_ZLIB 0x02 +#define SC_FILE_FLAG_COMPRESSED_GZIP 0x04 /* File status flags */ /* ISO7816-4: Unless otherwise specified, the security attributes are valid for the operational state.*/ From eb9c14c99e9dae38c20190cd86ab4e012a9dd5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 10 May 2023 15:51:03 +0200 Subject: [PATCH 2893/4321] Update API documentation for read_binary() --- src/libopensc/opensc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 4b0fb3d0ad..2596cdb061 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -652,7 +652,7 @@ struct sc_card_operations { * @param idx index within the file with the data to read * @param buf buffer to the read data * @param count number of bytes to read - * @param flags flags for the READ BINARY command (currently not used) + * @param flags flags for the READ BINARY command (optional) * @return number of bytes read or an error code * * @see sc_read_binary() From a7a30b7805c3c68ad519a54291f0fc0bd830461f Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Wed, 3 May 2023 22:21:14 +0200 Subject: [PATCH 2894/4321] cardos-tool: correctly identify CardOS v5.4 cards --- src/tools/cardos-tool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 3a969ac255..039457395e 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -198,6 +198,8 @@ static int cardos_info(void) } else if (apdu.resp[0] == 0xc9 && (apdu.resp[1] == 0x02 || apdu.resp[1] == 0x03)) { printf(" (that's CardOS V5.3)\n"); + } else if (apdu.resp[0] == 0xc9 && apdu.resp[1] == 0x04) { + printf(" (that's CardOS V5.4)\n"); } else { printf(" (unknown Version)\n"); } From 350fa68146c4384b4b9b4500e4de55726d39e7a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 May 2023 15:30:29 +0200 Subject: [PATCH 2895/4321] card-rtecp.c: Remove asserts and add better error handling Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57901 --- src/libopensc/card-rtecp.c | 119 +++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 5ce15b6e6c..09c92a17d7 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -22,7 +22,6 @@ #include "config.h" #endif -#include #include #include #include @@ -86,12 +85,14 @@ static int rtecp_init(sc_card_t *card) sc_algorithm_info_t info; unsigned long flags; - assert(card && card->ctx); + if (!card || !card->ctx) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + card->cla = 0; if (card->type == SC_CARD_TYPE_RUTOKEN_LITE || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); card->caps |= SC_CARD_CAP_RNG; @@ -114,7 +115,7 @@ static int rtecp_init(sc_card_t *card) | SC_ALGORITHM_GOSTR3410_HASH_NONE; _sc_card_add_algorithm(card, &info); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); } static void reverse(unsigned char *buf, size_t len) @@ -122,7 +123,9 @@ static void reverse(unsigned char *buf, size_t len) unsigned char tmp; size_t i; - assert(buf || len == 0); + if ((!buf && len != 0) || (buf && len == 0)) + return; + for (i = 0; i < len / 2; ++i) { tmp = buf[i]; @@ -164,9 +167,13 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) unsigned int method; unsigned long key_ref; - assert(card && card->ctx && file); - assert(file->sec_attr && file->sec_attr_len == SC_RTECP_SEC_ATTR_SIZE); - assert(1 + 6 < SC_RTECP_SEC_ATTR_SIZE); + if (!card || !card->ctx || !file || !file->sec_attr + || file->sec_attr_len != SC_RTECP_SEC_ATTR_SIZE + || 1 + 6 >= SC_RTECP_SEC_ATTR_SIZE) + { + sc_log(card->ctx, "Invalid arguments for set_acl_from_sec_attr()\n"); + return; + } sc_file_add_acl_entry(file, SC_AC_OP_SELECT, SC_AC_NONE, SC_AC_KEY_REF_NONE); if (file->sec_attr[0] & 0x40) /* if AccessMode.6 */ @@ -217,9 +224,12 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) u8 sec_attr[SC_RTECP_SEC_ATTR_SIZE] = { 0 }; int r; - assert(card && card->ctx && file); - assert(!file->sec_attr && file->sec_attr_len == 0); - assert(1 + 6 < sizeof(sec_attr)); + if (!card || !card->ctx || !file + || file->sec_attr || file->sec_attr_len != 0) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + + if (1 + 6 >= sizeof(sec_attr)) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); entry = sc_file_get_acl_entry(file, SC_AC_OP_DELETE); if (entry) @@ -279,11 +289,11 @@ static int rtecp_select_file(sc_card_t *card, sc_file_t *file = NULL; int r = SC_SUCCESS; - if (!card || !card->ctx || !in_path) - return SC_ERROR_INVALID_ARGUMENTS; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + if (!card || !card->ctx || !in_path) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + switch (in_path->type) { case SC_PATH_TYPE_DF_NAME: @@ -321,7 +331,10 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier, int r, send_logout = 0; (void)type; /* no warning */ - assert(card && card->ctx && data); + + if (!card || !card->ctx || !data) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + for (;;) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, @@ -357,7 +370,9 @@ static int rtecp_logout(sc_card_t *card) sc_apdu_t apdu; int r; - assert(card && card->ctx); + if (!card || !card->ctx) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x40, 0, 0); apdu.cla = 0x80; r = sc_transmit_apdu(card, &apdu); @@ -387,7 +402,9 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, size_t i; int r; - assert(card && card->ctx && data && out); + if (!card || !card->ctx || !data || !out) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + buf_out = malloc(out_len + 2); buf = malloc(data_len); if (!buf || !buf_out) @@ -414,11 +431,8 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, apdu.flags |= SC_APDU_FLAGS_CHAINING; r = sc_transmit_apdu(card, &apdu); if (!sign) - { - assert(buf); sc_mem_clear(buf, data_len); - } - assert(buf); + free(buf); if (r) sc_log(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r)); @@ -426,7 +440,6 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, { if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - assert(buf_out); for (i = 0; i < apdu.resplen; ++i) out[i] = buf_out[apdu.resplen - 1 - i]; r = (i > 0) ? (int)i : SC_ERROR_INTERNAL; @@ -435,11 +448,8 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, r = sc_check_sw(card, apdu.sw1, apdu.sw2); } if (!sign) - { - assert(buf_out); sc_mem_clear(buf_out, out_len + 2); - } - assert(buf_out); + free(buf_out); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); @@ -450,7 +460,8 @@ static int rtecp_decipher(sc_card_t *card, { int r; - assert(card && card->ctx && data && out); + if (!card || !card->ctx || !data || !out) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); if (card->type == SC_CARD_TYPE_RUTOKEN_LITE || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) @@ -466,7 +477,8 @@ static int rtecp_compute_signature(sc_card_t *card, { int r; - assert(card && card->ctx && data && out); + if (!card || !card->ctx || !data || !out) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); if (card->type == SC_CARD_TYPE_RUTOKEN_LITE || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) @@ -486,7 +498,9 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, size_t val_length, buf_length, max_transmit_length; int transmits_num, r; - assert(card && card->ctx && newref); + if (!card || !card->ctx || !newref) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + sc_log(card->ctx, "newlen = %"SC_FORMAT_LEN_SIZE_T"u\n", newlen); if (newlen > 0xFFFF) @@ -498,7 +512,8 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, } max_transmit_length = sc_get_max_send_size(card); - assert(max_transmit_length > 2); + if (max_transmit_length <= 2) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); /* * (2 + sizeof(rsf_length) + newlen) - total length of data we need to transfer, * (max_transmit_length - 2) - amount of useful data we can transfer in one transmit (2 bytes for 0xA5 tag) @@ -515,12 +530,16 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, /* put 0x80 TLV */ rsf_length[0] = (newlen >> 8) & 0xFF; rsf_length[1] = newlen & 0xFF; - assert(buf_end - p >= (int)(2 + sizeof(rsf_length))); + + if (buf_end - p < (int)(2 + sizeof(rsf_length))) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + sc_asn1_put_tag(0x80, rsf_length, sizeof(rsf_length), p, buf_end - p, &p); /* put 0xA5 TLVs (one or more); each transmit must begin with 0xA5 TLV */ while (newlen) { - assert(buf_end - p >= (int)(newlen + 2)); + if (buf_end - p < (int)(newlen + 2)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); if ((p - buf) % max_transmit_length + newlen + 2 > max_transmit_length) val_length = max_transmit_length - (p - buf) % max_transmit_length - 2; else @@ -528,7 +547,8 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, /* not using sc_asn1_put_tag(...) because rtecp do not support asn1 properly (when val_length > 127) */ *p++ = 0xA5; *p++ = (u8)val_length; - assert(val_length <= newlen); + if (val_length > newlen) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); memcpy(p, newref, val_length); p += val_length; newref += val_length; @@ -556,7 +576,9 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, int r; (void)type, (void)puk, (void)puklen; /* no warning */ - assert(card && card->ctx); + + if (!card || !card->ctx) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x03, ref_qualifier); r = sc_transmit_apdu(card, &apdu); @@ -592,13 +614,15 @@ static int rtecp_create_file(sc_card_t *card, sc_file_t *file) { int r; - assert(card && card->ctx && file); + if (!card || !card->ctx || !file) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + if (file->sec_attr_len == 0) { r = set_sec_attr_from_acl(card, file); LOG_TEST_RET(card->ctx, r, "Set sec_attr from ACL failed"); } - assert(iso_ops && iso_ops->create_file); + r = iso_ops->create_file(card, file); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } @@ -611,7 +635,9 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) size_t taglen, len = 0; int r; - assert(card && card->ctx && buf); + if (!card || !card->ctx || !buf) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0, 0); for (;;) { @@ -675,7 +701,9 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) sc_serial_number_t *serial = data; int r; - assert(card && card->ctx); + if (!card || !card->ctx) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + switch (request) { case SC_CARDCTL_RTECP_INIT: @@ -757,8 +785,10 @@ static int rtecp_construct_fci(sc_card_t *card, const sc_file_t *file, { u8 buf[64], *p = out; - assert(card && card->ctx && file && out && outlen); - assert(*outlen >= (size_t)(p - out) + 2); + if (!card || !card->ctx || !file || !out || !outlen + || (*outlen < (size_t)(p - out) + 2)) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + *p++ = 0x6F; /* FCI template */ p++; /* for length */ @@ -770,7 +800,8 @@ static int rtecp_construct_fci(sc_card_t *card, const sc_file_t *file, /* 0x82 - File descriptor byte */ if (file->type_attr_len) { - assert(sizeof(buf) >= file->type_attr_len); + if (sizeof(buf) < file->type_attr_len) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); memcpy(buf, file->type_attr, file->type_attr_len); sc_asn1_put_tag(0x82, buf, file->type_attr_len, p, *outlen - (p - out), &p); @@ -799,14 +830,16 @@ static int rtecp_construct_fci(sc_card_t *card, const sc_file_t *file, if (file->prop_attr_len) { - assert(sizeof(buf) >= file->prop_attr_len); + if (sizeof(buf) < file->prop_attr_len) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); memcpy(buf, file->prop_attr, file->prop_attr_len); sc_asn1_put_tag(0x85, buf, file->prop_attr_len, p, *outlen - (p - out), &p); } if (file->sec_attr_len) { - assert(sizeof(buf) >= file->sec_attr_len); + if (sizeof(buf) < file->sec_attr_len) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); memcpy(buf, file->sec_attr, file->sec_attr_len); sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p); From 9a15da8ee6a5222abd4c97ee83dffbd2b7f53917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 May 2023 16:13:20 +0200 Subject: [PATCH 2896/4321] Free ASN1 object Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58113 --- src/libopensc/pkcs15-prkey.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 7b87877429..4892b5a52e 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -242,7 +242,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, #ifdef ENABLE_OPENSSL if (!info.field_length && ec_domain_len) { const unsigned char *p = ec_domain; - const ASN1_OBJECT *object = d2i_ASN1_OBJECT(NULL, &p, ec_domain_len); + ASN1_OBJECT *object = d2i_ASN1_OBJECT(NULL, &p, ec_domain_len); int nid; const EC_GROUP *group; if (!object) { @@ -250,6 +250,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, goto err; } nid = OBJ_obj2nid(object); + ASN1_OBJECT_free(object); if (nid == NID_undef) { r = SC_ERROR_OBJECT_NOT_FOUND; goto err; From b5f6370a35f151497838628f78111087eb8e7ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 3 May 2023 16:47:44 +0200 Subject: [PATCH 2897/4321] Fix cycling fuzz pkcs11 test --- src/tests/fuzzing/fuzz_pkcs11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index b2a4c985e9..b6e05c9ad5 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -509,7 +509,7 @@ static void test_verify(const uint8_t *data, size_t size) memcpy(in_buffer, verify_data, verify_data_size); p11->C_Verify(session, in_buffer, verify_data_size, sig_buffer, sig_len); } else { - while (size > 0) { + while (verify_data_size > 0) { to_process = verify_data_size < sizeof(in_buffer) ? verify_data_size : sizeof(in_buffer); verify_data_size -= to_process; memcpy(in_buffer, data, to_process); From 2e63a80c8a08d4259152638eb3f8c008e57b3218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 10 May 2023 11:07:13 +0200 Subject: [PATCH 2898/4321] Fix configure command according the build in CIFuzz --- src/tests/fuzzing/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md index 0fdc72a43a..d7f425a0dc 100644 --- a/src/tests/fuzzing/README.md +++ b/src/tests/fuzzing/README.md @@ -12,12 +12,12 @@ Successful build of fuzz targets requires `./configure` run with correctly set C Example configuration for libFuzzer: ``` -./configure --disable-optimization --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing CC=clang CFLAGS=-fsanitize=fuzzer-no-link FUZZING_LIBS=-fuzzer +./configure --disable-optimization --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing CC=clang CFLAGS=-fsanitize=fuzzer-no-link FUZZING_LIBS=-fsanitize=fuzzer ``` To add some of the LLVM Sanitizers, modify `FUZZING_LIBS`: ``` -FUZZING_LIBS=-fuzzer,address,undefined +FUZZING_LIBS=-fsanitize=fuzzer,address,undefined ``` Sanitizers can also be modified by [flags](https://github.com/google/sanitizers/wiki/SanitizerCommonFlags). From 8609fcc5083a66a64f3e3604f897e08b3ddc49cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 May 2023 10:04:58 +0200 Subject: [PATCH 2899/4321] card-rtecp.c: Remove logging when checking for invalid arguments --- src/libopensc/card-rtecp.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 09c92a17d7..a39b797d58 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -86,7 +86,7 @@ static int rtecp_init(sc_card_t *card) unsigned long flags; if (!card || !card->ctx) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; card->cla = 0; @@ -171,7 +171,6 @@ static void set_acl_from_sec_attr(sc_card_t *card, sc_file_t *file) || file->sec_attr_len != SC_RTECP_SEC_ATTR_SIZE || 1 + 6 >= SC_RTECP_SEC_ATTR_SIZE) { - sc_log(card->ctx, "Invalid arguments for set_acl_from_sec_attr()\n"); return; } @@ -226,7 +225,7 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) if (!card || !card->ctx || !file || file->sec_attr || file->sec_attr_len != 0) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; if (1 + 6 >= sizeof(sec_attr)) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); @@ -289,10 +288,10 @@ static int rtecp_select_file(sc_card_t *card, sc_file_t *file = NULL; int r = SC_SUCCESS; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (!card || !card->ctx || !in_path) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); switch (in_path->type) { @@ -333,7 +332,7 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier, (void)type; /* no warning */ if (!card || !card->ctx || !data) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; for (;;) { @@ -371,7 +370,7 @@ static int rtecp_logout(sc_card_t *card) int r; if (!card || !card->ctx) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x40, 0, 0); apdu.cla = 0x80; @@ -403,7 +402,7 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, int r; if (!card || !card->ctx || !data || !out) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; buf_out = malloc(out_len + 2); buf = malloc(data_len); @@ -461,7 +460,7 @@ static int rtecp_decipher(sc_card_t *card, int r; if (!card || !card->ctx || !data || !out) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; if (card->type == SC_CARD_TYPE_RUTOKEN_LITE || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) @@ -478,7 +477,7 @@ static int rtecp_compute_signature(sc_card_t *card, int r; if (!card || !card->ctx || !data || !out) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; if (card->type == SC_CARD_TYPE_RUTOKEN_LITE || card->type == SC_CARD_TYPE_RUTOKEN_LITE_SC) @@ -499,7 +498,7 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, int transmits_num, r; if (!card || !card->ctx || !newref) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; sc_log(card->ctx, "newlen = %"SC_FORMAT_LEN_SIZE_T"u\n", newlen); @@ -578,7 +577,7 @@ static int rtecp_reset_retry_counter(sc_card_t *card, unsigned int type, (void)type, (void)puk, (void)puklen; /* no warning */ if (!card || !card->ctx) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x03, ref_qualifier); r = sc_transmit_apdu(card, &apdu); @@ -615,7 +614,7 @@ static int rtecp_create_file(sc_card_t *card, sc_file_t *file) int r; if (!card || !card->ctx || !file) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; if (file->sec_attr_len == 0) { @@ -636,7 +635,7 @@ static int rtecp_list_files(sc_card_t *card, u8 *buf, size_t buflen) int r; if (!card || !card->ctx || !buf) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xA4, 0, 0); for (;;) @@ -702,7 +701,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) int r; if (!card || !card->ctx) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; switch (request) { @@ -787,7 +786,7 @@ static int rtecp_construct_fci(sc_card_t *card, const sc_file_t *file, if (!card || !card->ctx || !file || !out || !outlen || (*outlen < (size_t)(p - out) + 2)) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + return SC_ERROR_INVALID_ARGUMENTS; *p++ = 0x6F; /* FCI template */ p++; /* for length */ From a1f6887e4bd31143747a6c738e34a979cd003fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 May 2023 10:20:20 +0200 Subject: [PATCH 2900/4321] Free file before overwritting Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58237 --- src/libopensc/card-oberthur.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index cf39fec5f9..36260d5ac2 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -554,12 +554,15 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, } } else if (path.len - offs == 0 && file_out) { - if (sc_compare_path(&path, &auth_current_df->path)) + if (sc_compare_path(&path, &auth_current_df->path) && file_out) { + sc_file_free(*file_out); sc_file_dup(file_out, auth_current_df); - else if (auth_current_ef) + } else if (auth_current_ef && file_out) { + sc_file_free(*file_out); sc_file_dup(file_out, auth_current_ef); - else + } else { LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "No current EF"); + } } } From 1e41ed32d1d4a4a9656cf18bbc6b40fdcd2cc2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 16 May 2023 10:21:11 +0200 Subject: [PATCH 2901/4321] Remove unneeded check --- src/libopensc/card-rtecp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index a39b797d58..f8125b3367 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -123,7 +123,7 @@ static void reverse(unsigned char *buf, size_t len) unsigned char tmp; size_t i; - if ((!buf && len != 0) || (buf && len == 0)) + if (!buf && len != 0) return; for (i = 0; i < len / 2; ++i) @@ -227,9 +227,6 @@ static int set_sec_attr_from_acl(sc_card_t *card, sc_file_t *file) || file->sec_attr || file->sec_attr_len != 0) return SC_ERROR_INVALID_ARGUMENTS; - if (1 + 6 >= sizeof(sec_attr)) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL); - entry = sc_file_get_acl_entry(file, SC_AC_OP_DELETE); if (entry) { From fe7cb4983d8c019705ced409b4a7339d73c7b4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 18 May 2023 15:12:59 +0200 Subject: [PATCH 2902/4321] card-rtecp.c: Free buffer in case of error --- src/libopensc/card-rtecp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index f8125b3367..753b7415bc 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -527,15 +527,19 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, rsf_length[0] = (newlen >> 8) & 0xFF; rsf_length[1] = newlen & 0xFF; - if (buf_end - p < (int)(2 + sizeof(rsf_length))) + if (buf_end - p < (int)(2 + sizeof(rsf_length))) { + free(buf); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } sc_asn1_put_tag(0x80, rsf_length, sizeof(rsf_length), p, buf_end - p, &p); /* put 0xA5 TLVs (one or more); each transmit must begin with 0xA5 TLV */ while (newlen) { - if (buf_end - p < (int)(newlen + 2)) + if (buf_end - p < (int)(newlen + 2)) { + free(buf); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } if ((p - buf) % max_transmit_length + newlen + 2 > max_transmit_length) val_length = max_transmit_length - (p - buf) % max_transmit_length - 2; else @@ -543,8 +547,10 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, /* not using sc_asn1_put_tag(...) because rtecp do not support asn1 properly (when val_length > 127) */ *p++ = 0xA5; *p++ = (u8)val_length; - if (val_length > newlen) + if (val_length > newlen) { + free(buf); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } memcpy(p, newref, val_length); p += val_length; newref += val_length; From 81944d1529202bd28359bede57c0a15deb65ba8a Mon Sep 17 00:00:00 2001 From: fullwaywang Date: Mon, 29 May 2023 10:38:48 +0800 Subject: [PATCH 2903/4321] pkcs15init: correct left length calculation to fix buffer overrun bug. Fixes #2785 --- src/pkcs15init/pkcs15-cardos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 9715cf390f..f41f73c349 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -872,7 +872,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card) sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - const u8 *p = rbuf, *q; + const u8 *p = rbuf, *q, *pp; size_t len, tlen = 0, ilen = 0; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88); @@ -888,13 +888,13 @@ static int cardos_have_verifyrc_package(sc_card_t *card) return 0; while (len != 0) { - p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); - if (p == NULL) + pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); + if (pp == NULL) return 0; if (card->type == SC_CARD_TYPE_CARDOS_M4_3) { /* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */ /* and Package Number 0x07 */ - q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen); + q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen); if (q == NULL || ilen != 4) return 0; if (q[0] == 0x07) @@ -902,7 +902,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card) } else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) { /* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */ /* and Package Number 0x02 */ - q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen); + q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x03, &ilen); if (q == NULL || ilen != 4) return 0; if (q[0] == 0x02) From ea6273f4b9fb0082857f6dfd54f30ba00ba81d1d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 25 Apr 2023 17:32:45 +0200 Subject: [PATCH 2904/4321] .editorconfig: Use tabs in shell scripts too --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 51ac6a487a..2e82737504 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,7 @@ end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true -[*.{c,h}] +[*.{c,h,sh}] indent_style = tab tab_width = 4 From e0f737f1dcbb7cb643afc0c1d6ab8f6cc002b7f0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 16:58:24 +0200 Subject: [PATCH 2905/4321] Remove trainling whitespace --- src/libopensc/card-westcos.c | 62 +++++++++++++++++------------------ src/pkcs11/framework-pkcs15.c | 3 +- src/pkcs11/pkcs11-global.c | 2 +- src/pkcs15init/pkcs15-lib.c | 6 ++-- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 108599336b..5b4f031eca 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -1,7 +1,7 @@ /* * card-westcos.c: support for westcos card * - * Copyright (C) 2009 francois.leblanc@cev-sa.com + * Copyright (C) 2009 francois.leblanc@cev-sa.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -83,7 +83,7 @@ static int westcos_get_default_key(sc_card_t * card, struct sc_cardctl_default_key *data) { const char *default_key; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_get_default_key:data->method=%d, data->key_ref=%d\n", data->method, data->key_ref); if (data->method != SC_AC_AUT || data->key_ref != 0) @@ -108,7 +108,7 @@ static unsigned short westcos_update_crc(unsigned char ch, unsigned short *lpwCr return (*lpwCrc); } -static void westcos_compute_aetb_crc(int CRCType, +static void westcos_compute_aetb_crc(int CRCType, unsigned char *Data, size_t Length, unsigned char * TransmitFirst, @@ -173,9 +173,9 @@ static int westcos_match_card(sc_card_t * card) i = _sc_match_atr(card, westcos_atrs, &card->type); if (i < 0) return 0; - + /* JAVACARD, look for westcos applet */ - if (i == 1) { + if (i == 1) { int r; sc_apdu_t apdu; u8 aid[] = { @@ -195,7 +195,7 @@ static int westcos_match_card(sc_card_t * card) if (r) return 0; } - + return 1; } @@ -208,12 +208,12 @@ static int westcos_init(sc_card_t * card) if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - + card->drv_data = malloc(sizeof(priv_data_t)); if (card->drv_data == NULL) return SC_ERROR_OUT_OF_MEMORY; memset(card->drv_data, 0, sizeof(priv_data_t)); - + priv_data = (priv_data_t *) card->drv_data; default_key = @@ -236,13 +236,13 @@ static int westcos_init(sc_card_t * card) if (card->type & JAVACARD) { priv_data->flags |= JAVACARD; } - + /* check for crypto component */ if(card->atr.value[9] == 0xD0) { priv_data->flags |= RSA_CRYPTO_COMPONENT; } - + card->cla = 0x00; card->max_send_size = 240; card->max_recv_size = 240; @@ -298,13 +298,13 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); if (tag != NULL && taglen == 2) { file->id = (tag[0] << 8) | tag[1]; - sc_log(card->ctx, + sc_log(card->ctx, " file identifier: 0x%02X%02X\n", tag[0], tag[1]); } tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_log(card->ctx, + sc_log(card->ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -312,7 +312,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen); if (tag != NULL && taglen >= 2) { int bytes = (tag[0] << 8) + tag[1]; - sc_log(card->ctx, + sc_log(card->ctx, " bytes in file: %d\n", bytes); file->size = bytes; } @@ -323,7 +323,7 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, unsigned char byte = tag[0]; const char *type; file->shareable = 0; - sc_log(card->ctx, + sc_log(card->ctx, " shareable: %s\n", (file->shareable) ? "yes" : "no"); file->ef_structure = SC_FILE_EF_UNKNOWN; @@ -350,9 +350,9 @@ static int westcos_process_fci(sc_card_t * card, sc_file_t * file, default: type = "unknown"; } - sc_log(card->ctx, + sc_log(card->ctx, " type: %s\n", type); - sc_log(card->ctx, + sc_log(card->ctx, " EF structure: %d\n", file->ef_structure); } } @@ -592,7 +592,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) p1 = (file->id) / 256; p2 = (file->id) % 256; } - sc_log(card->ctx, + sc_log(card->ctx, "create file %s, id %X size %"SC_FORMAT_LEN_SIZE_T"u\n", file->path.value, file->id, file->size); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, p1, p2); @@ -707,7 +707,7 @@ static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int pad = 0, use_pin_pad = 0, ins, p1 = 0; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_pin_cmd:data->pin_type=%X, data->cmd=%X\n", data->pin_type, data->cmd); if (tries_left) @@ -879,7 +879,7 @@ static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) priv_data_t *priv_data = NULL; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_card_ctl cmd = %lX\n", cmd); priv_data = (priv_data_t *) card->drv_data; switch (cmd) { @@ -1064,11 +1064,11 @@ static int westcos_set_security_env(sc_card_t *card, priv_data_t *priv_data = NULL; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_set_security_env\n"); priv_data = (priv_data_t *) card->drv_data; priv_data->env = *env; - + if(priv_data->flags & RSA_CRYPTO_COMPONENT) { sc_apdu_t apdu; @@ -1083,7 +1083,7 @@ static int westcos_set_security_env(sc_card_t *card, r = sc_path_print((char *)buf, sizeof(buf), &(env->file_ref)); if(r) return r; - + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xf0, mode); apdu.cla = 0x00; apdu.lc = strlen((char *)buf); @@ -1102,7 +1102,7 @@ static int westcos_restore_security_env(sc_card_t *card, int se_num) { if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_restore_security_env\n"); return 0; } @@ -1127,7 +1127,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; - sc_log(card->ctx, + sc_log(card->ctx, "westcos_sign_decipher outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", outlen); @@ -1144,7 +1144,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, if(priv_data->flags & RSA_CRYPTO_COMPONENT) { sc_apdu_t apdu; - + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x00, mode); apdu.datalen = data_len; apdu.data = data; @@ -1152,14 +1152,14 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, apdu.le = outlen > 240 ? 240 : outlen; apdu.resp = out; apdu.resplen = outlen; - + r = sc_transmit_apdu(card, &apdu); if (r) goto out2; r = sc_check_sw(card, apdu.sw1, apdu.sw2); if(r) goto out2; - + /* correct */ r = apdu.resplen; goto out2; @@ -1183,7 +1183,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, alire = min(((keyfile->size) - idx), sizeof(buf)); if (alire <= 0) break; - sc_log(card->ctx, + sc_log(card->ctx, "idx = %d, alire=%d\n", idx, alire); r = sc_read_binary(card, idx, buf, alire, 0); if (r < 0) @@ -1197,7 +1197,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, #else if (!(pkey = d2i_PrivateKey_ex_bio(mem, NULL, card->ctx->ossl3ctx->libctx, NULL))) { #endif - sc_log(card->ctx, + sc_log(card->ctx, "RSA key invalid, %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; @@ -1223,7 +1223,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, #ifdef DEBUG_SSL print_openssl_error(); #endif - sc_log(card->ctx, + sc_log(card->ctx, "Decipher error %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; @@ -1238,7 +1238,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, #ifdef DEBUG_SSL print_openssl_error(); #endif - sc_log(card->ctx, + sc_log(card->ctx, "Signature error %lu\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 9c7ec67fb4..cfbc7d1cc9 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2444,7 +2444,8 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil rv = CKR_OK; -out: return rv; +out: + return rv; } /* diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 8767bd6df2..b38016f24b 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -666,7 +666,7 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) memcpy(pInfo, &slot->slot_info, sizeof(CK_SLOT_INFO)); sc_log(context, "C_GetSlotInfo() flags 0x%lX", pInfo->flags); - + name = lookup_enum(RV_T, rv); if (name) sc_log(context, "C_GetSlotInfo(0x%lx) = %s", slotID, name); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index cd3daf57c6..e838bf92e2 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2043,7 +2043,7 @@ sc_pkcs15init_store_secret_key(struct sc_pkcs15_card *p15card, struct sc_profile r = profile->ops->create_key(profile, p15card, object); LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'create key' failed"); - /* If no key data, only an empty EF is created. + /* If no key data, only an empty EF is created. * It can be used to receive an unwrapped key later. */ if (keyargs->key.data_len > 0) { if (profile->ops->store_key) { @@ -3462,7 +3462,7 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p struct sc_pkcs15_der new_data; new_data.len = new_len; new_data.value = (u8 *) new_value; - + /* save new data as a new data file on token */ r = sc_pkcs15init_store_data(p15card, profile, object, &new_data, &new_data_path); profile->dirty = 1; @@ -3479,7 +3479,7 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p info->data.len = new_len; info->data.value = nv; info->path = new_data_path; - + /* delete old data file from token */ r = sc_pkcs15init_delete_by_path(profile, p15card, &old_data_path); LOG_TEST_RET(ctx, r, "Failed to delete old data"); From b53977a5274e86c6a58b5939367b8496a2ec84f9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Apr 2023 15:57:11 +0200 Subject: [PATCH 2906/4321] tests: Extract the PIN to separate variable --- .github/test-piv.sh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index a0f2282d17..1bc3d78b3b 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -17,7 +17,7 @@ pushd PivApplet JC_HOME=${JC_CLASSIC_HOME} ant dist popd -# yubico-piv-tool is needed for PIV Applet management +# yubico-piv-tool is needed for PIV Applet management if [ ! -d "yubico-piv-tool" ]; then git clone https://github.com/Yubico/yubico-piv-tool.git fi @@ -43,14 +43,15 @@ sleep 5 opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f opensc-tool -n -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048 | tee 9e.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify -aselfsign < 9e.pub | tee 9e.cert -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -aimport-certificate <9e.cert +PIN="123456" +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -a generate -A RSA2048 | tee 9e.pub +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -S'/CN=barCard/OU=test/O=example.com/' -averify -aselfsign < 9e.pub | tee 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -aimport-certificate <9e.cert -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256 | tee 9a.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9e.cert -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -aimport-certificate < 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -a generate -A ECCP256 | tee 9a.pub +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9e.cert -pkcs11-tool -l -O -p 123456 -pkcs11-tool -l -t -p 123456 +pkcs11-tool -l -O -p "$PIN" +pkcs11-tool -l -t -p "$PIN" kill -9 $PID From 352aba0e3794c46a98232a50572f285106f5d8a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Apr 2023 15:57:55 +0200 Subject: [PATCH 2907/4321] tests: Use separate file for the second cert --- .github/test-piv.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 1bc3d78b3b..c8916eb420 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -49,8 +49,8 @@ yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -S'/CN=barCard/OU yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -aimport-certificate <9e.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -a generate -A ECCP256 | tee 9a.pub -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9e.cert -yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9e.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9a.cert +yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9a.cert pkcs11-tool -l -O -p "$PIN" pkcs11-tool -l -t -p "$PIN" From c6d461c2d19ae07adb1a2604384bf0fccb9e7a4a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Apr 2023 16:47:37 +0200 Subject: [PATCH 2908/4321] ci: Split code download and build This is useful for running the CI locally in containers, which makes things much faster than it would need to download, build and install all the test tools. --- .github/setup-vsmartcard.sh | 5 ++++- .github/test-cac.sh | 9 +++++++-- .github/test-gidsapplet.sh | 4 +++- .github/test-openpgp.sh | 4 +++- .github/test-piv.sh | 19 +++++++++++-------- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/.github/setup-vsmartcard.sh b/.github/setup-vsmartcard.sh index a9049d24a5..0684ef1bbe 100755 --- a/.github/setup-vsmartcard.sh +++ b/.github/setup-vsmartcard.sh @@ -4,7 +4,10 @@ set -ex -o xtrace if [ ! -d "vsmartcard" ]; then git clone https://github.com/frankmorgner/vsmartcard.git + pushd vsmartcard/virtualsmartcard + autoreconf -vis && ./configure && make -j2 + popd fi pushd vsmartcard/virtualsmartcard -autoreconf -vis && ./configure && make -j2 && sudo make install +sudo make install popd diff --git a/.github/test-cac.sh b/.github/test-cac.sh index ee30039b30..8607d9815f 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -12,9 +12,12 @@ export LD_LIBRARY_PATH=/usr/local/lib # libcacard if [ ! -d "libcacard" ]; then git clone https://gitlab.freedesktop.org/spice/libcacard.git + pushd libcacard + ./autogen.sh --prefix=/usr && make -j2 + popd fi pushd libcacard -./autogen.sh --prefix=/usr && make -j2 && sudo make install +sudo make install popd # prepare pcscd @@ -23,9 +26,11 @@ popd # virt_cacard if [ ! -d "virt_cacard" ]; then git clone https://github.com/Jakuje/virt_cacard.git + pushd virt_cacard + ./autogen.sh && ./configure && make + popd fi pushd virt_cacard -./autogen.sh && ./configure && make ./setup-softhsm2.sh export SOFTHSM2_CONF=$PWD/softhsm2.conf # register cleanup function on exit diff --git a/.github/test-gidsapplet.sh b/.github/test-gidsapplet.sh index baa60b8083..f102df2fa1 100755 --- a/.github/test-gidsapplet.sh +++ b/.github/test-gidsapplet.sh @@ -10,7 +10,9 @@ export LD_LIBRARY_PATH=/usr/local/lib . .github/setup-java.sh # GidsApplet -git clone https://github.com/vletoux/GidsApplet.git; +if [ ! -d "GidsApplet" ]; then + git clone https://github.com/vletoux/GidsApplet.git; +fi javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar GidsApplet/src/com/mysmartlogon/gidsApplet/*.java; echo "com.licel.jcardsim.card.applet.0.AID=A000000397425446590201" > gids_jcardsim.cfg; echo "com.licel.jcardsim.card.applet.0.Class=com.mysmartlogon.gidsApplet.GidsApplet" >> gids_jcardsim.cfg; diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh index d1b3ab0217..e2f4be0200 100755 --- a/.github/test-openpgp.sh +++ b/.github/test-openpgp.sh @@ -10,7 +10,9 @@ export LD_LIBRARY_PATH=/usr/local/lib . .github/setup-java.sh # The OpenPGP applet -git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; +if [ ! -d "ykneo-openpgp" ]; then + git clone --recursive https://github.com/Yubico/ykneo-openpgp.git; +fi pushd ykneo-openpgp; ant -DJAVACARD_HOME=${JC_HOME}; popd diff --git a/.github/test-piv.sh b/.github/test-piv.sh index c8916eb420..9dcfe52a42 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -20,15 +20,18 @@ popd # yubico-piv-tool is needed for PIV Applet management if [ ! -d "yubico-piv-tool" ]; then git clone https://github.com/Yubico/yubico-piv-tool.git + pushd yubico-piv-tool + if [ ! -d "build" ]; then + mkdir build + pushd build + cmake .. && make + popd + fi + popd fi -pushd yubico-piv-tool -if [ ! -d "build" ]; then - mkdir build -fi -pushd build -cmake .. && make && sudo make install -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/x86_64-linux-gnu -popd +pushd yubico-piv-tool/build + sudo make install + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/x86_64-linux-gnu popd From d42d10c88e7e3456f19fc083e30543958e3cb2f8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 16:06:58 +0200 Subject: [PATCH 2909/4321] pkcs11-tool: Avoid memory leaks --- src/tools/pkcs11-tool.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index f3a01ab4cf..fa0cd6d41c 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3587,7 +3587,7 @@ static void parse_certificate(struct x509cert_info *cert, util_fatal("issuer name too long"); /* green light, actually do it */ p = cert->issuer; - n =i2d_X509_NAME(X509_get_issuer_name(x), &p); + n = i2d_X509_NAME(X509_get_issuer_name(x), &p); cert->issuer_len = n; /* check length first */ @@ -3600,6 +3600,8 @@ static void parse_certificate(struct x509cert_info *cert, p = cert->serialnum; n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &p); cert->serialnum_len = n; + + X509_free(x); } static int @@ -3628,7 +3630,7 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) if (!strstr((char *)data, "-----BEGIN ")) /* * d2i_PUBKEY_ex_bio is in OpenSSL master of 02/23/2023 - * committed Dec 26, 2022 expected in 3.2.0 + * committed Dec 26, 2022 expected in 3.2.0 */ #if OPENSSL_VERSION_NUMBER >= 0x30200000L *key = d2i_PUBKEY_ex_bio(mem, NULL, osslctx, NULL); @@ -3904,6 +3906,12 @@ parse_ec_pkey(EVP_PKEY *pkey, int private, struct gostkey_info *gost) return 0; } #endif +static void gost_info_free(struct gostkey_info gost) +{ + OPENSSL_free(gost.param_oid.value); + OPENSSL_free(gost.public.value); + OPENSSL_free(gost.private.value); +} #endif #define MAX_OBJECT_SIZE 5000 @@ -4438,6 +4446,11 @@ static int write_object(CK_SESSION_HANDLE session) show_object(session, seckey_obj); } +#ifdef ENABLE_OPENSSL + gost_info_free(gost); + EVP_PKEY_free(evp_key); +#endif /* ENABLE_OPENSSL */ + if (oid_buf) free(oid_buf); return 1; @@ -5310,6 +5323,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) X509_NAME_print(bio, name, XN_FLAG_RFC2253); printf("\n"); BIO_free(bio); + X509_NAME_free(name); } free(subject); } From 5241ce853403da775e37ecb36fb6a968001ef115 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 16:08:54 +0200 Subject: [PATCH 2910/4321] pkcs11-tool: Do not compare uninitialized memory if GetRandom fails --- src/tools/pkcs11-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index fa0cd6d41c..85c500e223 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7419,7 +7419,7 @@ static int test_random(CK_SESSION_HANDLE session) errors++; } - if (memcmp(buf1, buf2, 100) == 0) { + if (errors == 0 && memcmp(buf1, buf2, 100) == 0) { printf(" ERR: C_GenerateRandom returned twice the same value!!!\n"); errors++; } From afae9fcc2f4ead520fdb2de4b768e260b7c97a2b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 17:03:07 +0200 Subject: [PATCH 2911/4321] containers: Sync with CI --- containers/opensc-test-cac/Containerfile | 3 ++- containers/opensc-test-gidsapplet/Containerfile | 14 ++++++++++++++ containers/opensc-test-piv/Containerfile | 5 +++-- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 containers/opensc-test-gidsapplet/Containerfile diff --git a/containers/opensc-test-cac/Containerfile b/containers/opensc-test-cac/Containerfile index 6d6065ed5d..7dde899311 100644 --- a/containers/opensc-test-cac/Containerfile +++ b/containers/opensc-test-cac/Containerfile @@ -10,4 +10,5 @@ RUN export DEBIAN_FRONTEND=noninteractive; \ WORKDIR /src RUN /src/.github/setup-linux.sh cac RUN /src/.github/build.sh -CMD /src/.github/test-cac.sh +#CMD /src/.github/test-cac.sh +CMD /src/.github/test-cac.sh valgrind diff --git a/containers/opensc-test-gidsapplet/Containerfile b/containers/opensc-test-gidsapplet/Containerfile new file mode 100644 index 0000000000..eee792f9e9 --- /dev/null +++ b/containers/opensc-test-gidsapplet/Containerfile @@ -0,0 +1,14 @@ +FROM ubuntu:latest +RUN apt update +# Install sudo to mimic Github Actions runnner +# Install tzdata to avoid messing up with interactive prompts later +RUN export DEBIAN_FRONTEND=noninteractive; \ + export DEBCONF_NONINTERACTIVE_SEEN=true; \ + echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \ + echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \ + apt-get install -y --no-install-recommends tzdata sudo +WORKDIR /src +RUN /src/.github/setup-linux.sh gidsapplet +RUN /src/.github/build.sh +#CMD /src/.github/test-gidsapplet.sh +CMD /src/.github/test-gidsapplet.sh valgrind diff --git a/containers/opensc-test-piv/Containerfile b/containers/opensc-test-piv/Containerfile index a83f377ccc..ccf70628f5 100644 --- a/containers/opensc-test-piv/Containerfile +++ b/containers/opensc-test-piv/Containerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM ubuntu:20.04 RUN apt update # Install sudo to mimic Github Actions runnner # Install tzdata to avoid messing up with interactive prompts later @@ -10,4 +10,5 @@ RUN export DEBIAN_FRONTEND=noninteractive; \ WORKDIR /src RUN /src/.github/setup-linux.sh piv RUN /src/.github/build.sh -CMD /src/.github/test-piv.sh +#CMD /src/.github/test-piv.sh +CMD /src/.github/test-piv.sh valgrind From e1d7e967b550b3e66ceacc0ca7decc3fd6cb8452 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 17:03:36 +0200 Subject: [PATCH 2912/4321] pkcs15init: Remove duplicate cleanup --- src/pkcs15init/pkcs15-lib.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index e838bf92e2..6192f8cb81 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1605,18 +1605,9 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr /* Generate the private key on card */ r = profile->ops->create_key(profile, p15card, object); - if (r < 0 && algorithm == SC_ALGORITHM_EC) { - /* pubkey->alg_id->algorithm is not set yet, needs to be freed independently */ - free(pubkey_args.key.u.ec.params.der.value); - free(pubkey_args.key.u.ec.params.named_curve); - } LOG_TEST_GOTO_ERR(ctx, r, "Cannot generate key: create key failed"); r = profile->ops->generate_key(profile, p15card, object, &pubkey_args.key); - if (r < 0 && algorithm == SC_ALGORITHM_EC) { - free(pubkey_args.key.u.ec.params.der.value); - free(pubkey_args.key.u.ec.params.named_curve); - } LOG_TEST_GOTO_ERR(ctx, r, "Failed to generate key"); /* update PrKDF entry */ @@ -1628,8 +1619,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr memset(&iid, 0, sizeof(iid)); r = sc_pkcs15init_select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key); if (r < 0 && algorithm == SC_ALGORITHM_EC) { - free(pubkey_args.key.u.ec.params.der.value); - free(pubkey_args.key.u.ec.params.named_curve); free(pubkey_args.key.u.ec.ecpointQ.value); /* allocated in profile->ops->generate_key */ } LOG_TEST_GOTO_ERR(ctx, r, "Select intrinsic ID error"); @@ -1642,10 +1631,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr if (!pubkey->alg_id) { pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id)); if (!pubkey->alg_id) { - if (algorithm == SC_ALGORITHM_EC) { - free(pubkey_args.key.u.ec.params.der.value); - free(pubkey_args.key.u.ec.params.named_curve); - } r = SC_ERROR_OUT_OF_MEMORY; LOG_TEST_GOTO_ERR(ctx, r, "Can not allocate memory for algorithm id"); } @@ -1677,14 +1662,15 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr *res_obj = object; object = NULL; - sc_pkcs15_erase_pubkey(pubkey); - profile->dirty = 1; err: sc_pkcs15_erase_pubkey(pubkey); sc_pkcs15_free_object(object); if (algorithm == SC_ALGORITHM_EC) { + /* Allocated in sc_copy_ec_params() */ + free(pubkey_args.key.u.ec.params.der.value); + free(pubkey_args.key.u.ec.params.named_curve); /* allocated in check_keygen_params_consistency() */ free(keygen_args->prkey_args.key.u.ec.params.der.value); keygen_args->prkey_args.key.u.ec.params.der.value = NULL; From 2b2bf39feb8ad899364b563e7c588efbca68f419 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Apr 2023 17:28:45 +0200 Subject: [PATCH 2913/4321] p11test: Avoid memory leaks deteted by valgrind --- src/tests/p11test/p11test_case_common.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index f9f24c9847..6038725f2a 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -413,9 +413,11 @@ int callback_public_keys(test_certs_t *objects, RSA *rsa = RSA_new(); if (RSA_set0_key(rsa, n, e, NULL) != 1 || EVP_PKEY_set1_RSA(o->key, rsa) != 1) { + RSA_free(rsa); fail_msg("Unable to set key params"); return -1; } + RSA_free(rsa); #else if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || !(bld = OSSL_PARAM_BLD_new()) || @@ -449,8 +451,9 @@ int callback_public_keys(test_certs_t *objects, ASN1_OBJECT *oid = NULL; ASN1_OCTET_STRING *s = NULL; const unsigned char *pub, *p; + char *hex = NULL; BIGNUM *bn = NULL; - EC_POINT *ecpoint; + EC_POINT *ecpoint = NULL; EC_GROUP *ecgroup = NULL; int nid, pub_len; @@ -490,9 +493,16 @@ int callback_public_keys(test_certs_t *objects, return -1; } - ecpoint = EC_POINT_hex2point(ecgroup, BN_bn2hex(bn), NULL, NULL); + hex = BN_bn2hex(bn); BN_free(bn); - + if (hex == NULL) { + debug_print(" [WARN %s ] Can not convert EC_POINT from" + " BIGNUM hex representation", o->id_str); + EC_GROUP_free(ecgroup); + return -1; + } + ecpoint = EC_POINT_hex2point(ecgroup, hex, NULL, NULL); + OPENSSL_free(hex); if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " BIGNUM to OpenSSL format", o->id_str); @@ -553,8 +563,11 @@ int callback_public_keys(test_certs_t *objects, #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *ec = EC_KEY_new_by_curve_name(nid); EC_KEY_set_public_key(ec, ecpoint); + EC_POINT_free(ecpoint); EC_KEY_set_group(ec, ecgroup); + EC_GROUP_free(ecgroup); EVP_PKEY_set1_EC_KEY(o->key, ec); + EC_KEY_free(ec); #else ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); char curve_name[80]; size_t curve_name_len = 0; From b46d387019dbe8ea658f422dcb87c61355713d16 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Apr 2023 14:29:33 +0200 Subject: [PATCH 2914/4321] pkcs15init: Revise cleanup after keygen and storing keys There were needless assignment immediately rewritten with copy function, some of the structures were not copied and not freed from the target contexts and similar issues. --- src/pkcs15init/pkcs15-lib.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 6192f8cb81..7122e5da7b 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1539,6 +1539,9 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr int algorithm = keygen_args->prkey_args.key.algorithm; LOG_FUNC_CALLED(ctx); + + memset(&pubkey_args, 0, sizeof(pubkey_args)); + /* check supported key size */ r = check_keygen_params_consistency(p15card->card, algorithm, &keygen_args->prkey_args, @@ -1585,7 +1588,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr /* Set up the PuKDF info. The public key will be filled in * by the card driver's generate_key function called below. * Auth.ID of the public key object is left empty. */ - memset(&pubkey_args, 0, sizeof(pubkey_args)); pubkey_args.id = keygen_args->prkey_args.id; pubkey_args.label = keygen_args->pubkey_label ? keygen_args->pubkey_label : object->label; pubkey_args.usage = keygen_args->prkey_args.usage; @@ -1598,7 +1600,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr } else if (algorithm == SC_ALGORITHM_EC) { /* needs to be freed in case of failure when pubkey is not set yet */ - pubkey_args.key.u.ec.params = keygen_args->prkey_args.key.u.ec.params; r = sc_copy_ec_params(&pubkey_args.key.u.ec.params, &keygen_args->prkey_args.key.u.ec.params); LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC parameters"); } @@ -1618,9 +1619,6 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr * if intrinsic ID can be calculated -- overwrite the native one */ memset(&iid, 0, sizeof(iid)); r = sc_pkcs15init_select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key); - if (r < 0 && algorithm == SC_ALGORITHM_EC) { - free(pubkey_args.key.u.ec.ecpointQ.value); /* allocated in profile->ops->generate_key */ - } LOG_TEST_GOTO_ERR(ctx, r, "Select intrinsic ID error"); if (iid.len) @@ -1665,15 +1663,17 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr profile->dirty = 1; err: - sc_pkcs15_erase_pubkey(pubkey); sc_pkcs15_free_object(object); if (algorithm == SC_ALGORITHM_EC) { /* Allocated in sc_copy_ec_params() */ - free(pubkey_args.key.u.ec.params.der.value); free(pubkey_args.key.u.ec.params.named_curve); + free(pubkey_args.key.u.ec.params.der.value); /* allocated in check_keygen_params_consistency() */ free(keygen_args->prkey_args.key.u.ec.params.der.value); keygen_args->prkey_args.key.u.ec.params.der.value = NULL; + /* can be allocated in driver-specific generate_key() */ + free(pubkey_args.key.u.ec.ecpointQ.value); + pubkey_args.key.u.ec.ecpointQ.value = NULL; } LOG_FUNC_RETURN(ctx, r); } @@ -1869,9 +1869,10 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile case SC_ALGORITHM_EC: type = SC_PKCS15_TYPE_PUBKEY_EC; - key.u.ec.params = keyargs->key.u.ec.params; + r = sc_copy_ec_params(&key.u.ec.params, &keyargs->key.u.ec.params); + LOG_TEST_RET(ctx, r, "Failed to copy EC public key parameters"); r = sc_pkcs15_fix_ec_parameters(ctx, &key.u.ec.params); - LOG_TEST_RET(ctx, r, "Failed to fix EC public key parameters"); + LOG_TEST_GOTO_ERR(ctx, r, "Failed to fix EC public key parameters"); keybits = key.u.ec.params.field_length; break; @@ -1922,6 +1923,15 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile key_info->params.len = key.u.ec.params.der.len; memcpy(key_info->params.data, key.u.ec.params.der.value, key.u.ec.params.der.len); } + if (keyargs->key.u.ec.ecpointQ.value) { + key.u.ec.ecpointQ.value = malloc(keyargs->key.u.ec.ecpointQ.len); + if (!key.u.ec.ecpointQ.value) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC params"); + } + key.u.ec.ecpointQ.len = key.u.ec.ecpointQ.len; + memcpy(key.u.ec.ecpointQ.value, keyargs->key.u.ec.ecpointQ.value, key.u.ec.ecpointQ.len); + } } /* Select a intrinsic Key ID if the user didn't specify one */ @@ -1979,6 +1989,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile profile->dirty = 1; err: + sc_pkcs15_erase_pubkey(&key); sc_pkcs15_free_object(object); LOG_FUNC_RETURN(ctx, r); } From fbc8bd114a549b347255391d26259207b66d1c6b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Apr 2023 20:21:19 +0200 Subject: [PATCH 2915/4321] pkcs11: Free memory after storing keys --- src/pkcs11/framework-pkcs15.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cfbc7d1cc9..315f9cb784 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2433,6 +2433,13 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil } rc = sc_pkcs15init_store_private_key(fw_data->p15_card, profile, &args, &key_obj); + /* free args now */ + if (key_type == CKK_EC) { + /* allocated above */ + free(ec->params.der.value); + /* in sc_pkcs15_fix_ec_parameters() */ + free(ec->params.named_curve); + } if (rc < 0) { rv = sc_to_cryptoki_error(rc, "C_CreateObject"); goto out; @@ -2770,6 +2777,15 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile } rc = sc_pkcs15init_store_public_key(fw_data->p15_card, profile, &args, &key_obj); + /* free args now */ + if (key_type == CKK_EC) { + /* allocated above */ + free(ec->params.der.value); + /* in sc_pkcs15_fix_ec_parameters() */ + free(ec->params.named_curve); + /* in sc_pkcs15_decode_pubkey_ec() */ + free(ec->ecpointQ.value); + } if (rc < 0) return sc_to_cryptoki_error(rc, "C_CreateObject"); From 79efc06fe2aff9313fa587c09190109aaeb521b5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 24 Apr 2023 20:22:40 +0200 Subject: [PATCH 2916/4321] isoapplet: Do not leak memory if params were allocated already --- src/pkcs15init/pkcs15-isoApplet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 506edc2adf..5e4dd7da57 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -548,6 +548,7 @@ isoApplet_generate_key_ec(const sc_pkcs15_prkey_info_t *key_info, sc_card_t *car memcpy(pubkey->u.ec.ecpointQ.value, args.pubkey.ec.ecPointQ.value, args.pubkey.ec.ecPointQ.len); /* The OID is also written to the pubkey->u.ec.params */ + free(pubkey->u.ec.params.der.value); pubkey->u.ec.params.der.value = malloc(alg_id_params->der.len); if(!pubkey->u.ec.params.der.value) { From d5fbee7a7b502c796fa89da61c87a0dff1ad229a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 26 Apr 2023 11:09:53 +0200 Subject: [PATCH 2917/4321] Mark clang-tidy warnings errors --- src/common/Makefile.am | 2 +- src/libopensc/Makefile.am | 2 +- src/pkcs11/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 2f3b0fd301..5153428dce 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -46,4 +46,4 @@ TIDY_FILES = \ libpkcs11.c libscdl.c check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' --warnings-as-errors='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 926e510c1e..e63796de80 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -147,4 +147,4 @@ TIDY_FILES = \ #$(SOURCES) check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' --warnings-as-errors='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index 622c074515..09f307ac2e 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -101,4 +101,4 @@ TIDY_FILES = \ framework-pkcs15init.c debug.c check-local: - if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi + if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' --warnings-as-errors='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi From b8a0c6dd10308ddcd4d878d1a9029fe2d93bd3da Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 26 Apr 2023 11:10:28 +0200 Subject: [PATCH 2918/4321] iso7816: Return errors on failure Reported by clang-tidy as set-but never read variable: /home/runner/work/OpenSC/OpenSC/src/libopensc/iso7816.c:366:2: warning: Value stored to 'r' is never read [clang-analyzer-deadcode.DeadStores] r = count; ^ /home/runner/work/OpenSC/OpenSC/src/libopensc/iso7816.c:366:2: note: Value stored to 'r' is never read --- src/libopensc/iso7816.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 80a6885d62..2c66820ecd 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -367,7 +367,7 @@ iso7816_update_record(struct sc_card *card, unsigned int rec_nr, unsigned int id err: free(encoded_data); - LOG_FUNC_RETURN(card->ctx, count); + LOG_FUNC_RETURN(card->ctx, r); } static int @@ -467,7 +467,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file, file->size = size; } } - + sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); break; @@ -802,7 +802,7 @@ iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len) if (len < apdu.resplen) { return (int) len; } - + return (int) apdu.resplen; } From 478d5911e56352e2a3ac69693da8355b284c7a66 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 26 Apr 2023 11:17:17 +0200 Subject: [PATCH 2919/4321] westcos: Avoid memory leak Accidentally introduced with 264b23aff5b01acebe9627dff4468fa42eb5a825, reported by clang-tidy /home/runner/work/OpenSC/OpenSC/src/libopensc/card-westcos.c:664:7: warning: Although the value stored to 'cctx' is used in the enclosing expression, the value is never actually read from 'cctx' [clang-analyzer-deadcode.DeadStores] if ((cctx = EVP_CIPHER_CTX_new()) == NULL) ^ /home/runner/work/OpenSC/OpenSC/src/libopensc/card-westcos.c:664:7: note: Although the value stored to 'cctx' is used in the enclosing expression, the value is never actually read from 'cctx' --- src/libopensc/card-westcos.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 5b4f031eca..9c10fc8cc6 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -661,8 +661,6 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, EVP_CIPHER_CTX *cctx = NULL; EVP_CIPHER *alg = NULL; int tmplen = 0; - if ((cctx = EVP_CIPHER_CTX_new()) == NULL) - return SC_ERROR_INTERNAL; #endif u8 buf[8]; if ((*len) < sizeof(buf)) From 18b63d279aa65133429b2b5024f4eddf6c87e42c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 26 Apr 2023 11:19:41 +0200 Subject: [PATCH 2920/4321] card-sc-hsm: Remove dead code Reported by clang-tidy: /home/runner/work/OpenSC/OpenSC/src/libopensc/card-sc-hsm.c:854:3: warning: Value stored to 'len' is never read [clang-analyzer-deadcode.DeadStores] len = 0; ^ /home/runner/work/OpenSC/OpenSC/src/libopensc/card-sc-hsm.c:854:3: note: Value stored to 'len' is never read --- src/libopensc/card-sc-hsm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index c100a87c2a..d41642492f 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -851,7 +851,6 @@ static int sc_hsm_write_ef(sc_card_t *card, size_t file_offset = (size_t) idx; size_t offset = 0; do { - len = 0; to_send = bytes_left >= blk_size ? blk_size : bytes_left; p = cmdbuff; // ASN1 0x54 offset From f4891aabd169a2c72ea97110d46f093570d48679 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 May 2023 15:30:12 +0200 Subject: [PATCH 2921/4321] tools: Avoid set-but-not-used variable in netkey-tool --- src/tools/netkey-tool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index f2904ad1f9..f43fced329 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -535,6 +535,7 @@ int main( fprintf(stderr,"Establish-Context failed: %s\n", sc_strerror(r)); exit(1); } + ctx->debug = debug; if(ctx->debug>0) printf("Context for application \"%s\" created, Debug=%d\n", ctx->app_name, ctx->debug); From 1952e2e2b249c109049c050c141001fdceda84e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 May 2023 16:10:56 +0200 Subject: [PATCH 2922/4321] ci: Fail early if we can not set up libressl --- .github/setup-linux.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 7d7c9ebce3..63a57ad81a 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -53,7 +53,12 @@ sudo apt-get install -y build-essential $DEPS # install libressl if needed if [ "$1" == "libressl" -o "$2" == "libressl" ]; then - ./.github/setup-libressl.sh &> /tmp/libressl.log || cat /tmp/libressl.log + ./.github/setup-libressl.sh &> /tmp/libressl.log + RET=$? + if [ $RET -ne 0 ]; then + cat /tmp/libressl.log + exit $RET + fi fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then From 6a1ff88d5c45e0b927922928cd947a95caccd4ed Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 18 May 2023 14:25:56 +0200 Subject: [PATCH 2923/4321] tests: Fix the secret key test that never worked --- tests/common.sh | 6 +++++- tests/test-pkcs11-tool-sign-verify.sh | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index 9466c8fd6d..ba7b797826 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -78,8 +78,12 @@ function card_setup() { # Generate 521b ECC Key pair generate_key "EC:secp521r1" "04" "ECC521" # Generate an HMAC:SHA256 key - $PKCS11_TOOL --keypairgen --key-type="GENERIC:64" --login --pin=$PIN \ + $PKCS11_TOOL --keygen --key-type="GENERIC:64" --login --pin=$PIN \ --module="$P11LIB" --label="HMAC-SHA256" + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate GENERIC key" + return 1 + fi } function softhsm_cleanup() { diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 69a794e356..3382771fdc 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -156,10 +156,12 @@ for MECHANISM in "SHA-1-HMAC" "SHA256-HMAC" "SHA384-HMAC" "SHA512-HMAC"; do echo "$MECHANISM: Sign & Verify (KEY (First Found))" echo "=======================================================" - $PKCS11_TOOL --login --pin=1234 --sign --mechanism=$MECHANISM \ + $PKCS11_TOOL --login --pin=$PIN --sign --mechanism=$MECHANISM \ --input-file=data.msg --output-file=data.sig --module $P11LIB - $PKCS11_TOOL --login --pin=1234 --verify --mechanism=$MECHANISM \ + assert $? "Failed to Sign data" + $PKCS11_TOOL --login --pin=$PIN --verify --mechanism=$MECHANISM \ --input-file=data.msg --signature-file=data.sig --module $P11LIB + assert $? "Failed to Verify signature using pkcs11-tool" rm data.sig done; From 28a1bf19833d95aa759b8f8984edbea6234fd10c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 18 May 2023 18:34:25 +0200 Subject: [PATCH 2924/4321] unittests: Avoid memory leaks or invalid memory access --- src/tests/unittests/asn1.c | 5 ++ src/tests/unittests/compression.c | 2 + src/tests/unittests/decode_ecdsa_signature.c | 87 +++++++++++--------- src/tests/unittests/pkcs15-emulator-filter.c | 5 +- 4 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/tests/unittests/asn1.c b/src/tests/unittests/asn1.c index f6c3744843..1196f3d61e 100644 --- a/src/tests/unittests/asn1.c +++ b/src/tests/unittests/asn1.c @@ -304,6 +304,7 @@ static void torture_asn1_decode_entry_octet_string_short(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(resultlen, sizeof(octet_string)); assert_memory_equal(result, octet_string, resultlen); + free(result); } /* In case of we expect UNSIGNED value from this, the parser already takes @@ -329,6 +330,7 @@ static void torture_asn1_decode_entry_octet_string_unsigned(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(resultlen, sizeof(octet_string) -1); assert_memory_equal(result, octet_string + 1, resultlen); + free(result); } static void torture_asn1_decode_entry_octet_string_pre_allocated(void **state) @@ -415,6 +417,7 @@ static void torture_asn1_decode_entry_bit_string_short(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(resultlen, 8); assert_memory_equal(exp_result, result, resultlen/8); + free(result); } /* This modification does not invert the bit order */ @@ -437,6 +440,7 @@ static void torture_asn1_decode_entry_bit_string_ni(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(resultlen, 8); assert_memory_equal(bit_string + 1, result, resultlen/8); + free(result); } static void torture_asn1_put_tag_short(void **state) @@ -592,6 +596,7 @@ static void torture_asn1_encode_simple(void **state) /* Context is not needed */ rv = sc_asn1_encode(NULL, asn1, &outptr, &outlen); assert_int_equal(rv, SC_SUCCESS); + free(outptr); } int main(void) diff --git a/src/tests/unittests/compression.c b/src/tests/unittests/compression.c index 07fea8e6e6..ddd34a6d41 100644 --- a/src/tests/unittests/compression.c +++ b/src/tests/unittests/compression.c @@ -177,6 +177,7 @@ static void torture_compression_decompress_alloc_valid(void **state) assert_int_equal(rv, SC_SUCCESS); assert_int_equal(buflen, 5); assert_memory_equal(buf, "test\x0a", 5); + free(buf); } static void torture_compression_decompress_alloc_invalid_suffix(void **state) @@ -194,6 +195,7 @@ static void torture_compression_decompress_alloc_invalid_suffix(void **state) assert_int_equal(rv, SC_SUCCESS); /* TODO Is this fine? */ assert_int_equal(buflen, 5); assert_memory_equal(buf, "test\x0a", 5); + free(buf); } diff --git a/src/tests/unittests/decode_ecdsa_signature.c b/src/tests/unittests/decode_ecdsa_signature.c index 984970ea93..f20ef44e9d 100644 --- a/src/tests/unittests/decode_ecdsa_signature.c +++ b/src/tests/unittests/decode_ecdsa_signature.c @@ -22,16 +22,34 @@ #include "torture.h" #include "libopensc/log.c" #include "libopensc/asn1.c" +#include + +static int setup(void **state) +{ + struct sc_context *ctx = NULL; + + sc_establish_context(&ctx, "test"); + *state = ctx; + return 0; +} + +static int teardown(void **state) +{ + struct sc_context *ctx = *state; + + sc_release_context(ctx); + + return 0; +} static void torture_empty_rs(void **state) { int r = 0; size_t fieldsize = 24; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); char data[] = { 0x30, 0x04, 0x02, 0x00, 0x02, 0x00}; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 6, fieldsize, (u8 ** ) &out, 2); free(out); assert_int_equal(r, SC_ERROR_INVALID_DATA); @@ -41,7 +59,7 @@ static void torture_valid_format(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); u8 result[2] = { 0x03, 0x04}; char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; @@ -49,10 +67,9 @@ static void torture_valid_format(void **state) if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, 2 * fieldsize); + assert_int_equal(r, 2 * fieldsize); assert_memory_equal(result, out, 2); free(out); } @@ -61,7 +78,7 @@ static void torture_valid_format_leading00(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); u8 result[2] = { 0x03, 0x04}; char data[] = { 0x30, 0x07, 0x02, 0x02, 0x00, 0x03, 0x02, 0x01, 0x04}; @@ -69,10 +86,9 @@ static void torture_valid_format_leading00(void **state) if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, 2 * fieldsize); + assert_int_equal(r, 2 * fieldsize); assert_memory_equal(result, out, 2); free(out); } @@ -81,7 +97,7 @@ static void torture_valid_format_long_fieldsize(void **state) { int r = 0; size_t fieldsize = 3; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(6); u8 result[6] = { 0x00, 0x00, 0x03, 0x00, 0x00, 0x04}; char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; @@ -89,10 +105,9 @@ static void torture_valid_format_long_fieldsize(void **state) if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 6); - assert_int_equal(r, 2 * fieldsize); + assert_int_equal(r, 2 * fieldsize); assert_memory_equal(result, out, 6); free(out); } @@ -101,17 +116,16 @@ static void torture_wrong_tag_len(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); char data[] = { 0x30, 0x05, 0x02, 0x01, 0x03, 0x02, 0x01, 0x04}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } @@ -119,17 +133,16 @@ static void torture_wrong_integer_tag_len(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); char data[] = { 0x30, 0x06, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 8, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } @@ -137,17 +150,16 @@ static void torture_small_fieldsize(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(3); char data[] = { 0x30, 0x07, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 3); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } @@ -155,17 +167,16 @@ static void torture_long_leading00(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(3); char data[] = { 0x30, 0x07, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x04}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 10, fieldsize, (u8 **) &out, 3); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } @@ -173,17 +184,16 @@ static void torture_missing_tag(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); char data[] = { 0x20, 0x07, 0x02, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } @@ -192,33 +202,32 @@ static void torture_missing_integer_tag(void **state) { int r = 0; size_t fieldsize = 1; - struct sc_context *ctx = NULL; + struct sc_context *ctx = *state; u8 *out = malloc(2); char data[] = { 0x30, 0x07, 0x01, 0x01, 0x03, 0x02, 0x02, 0x04, 0x05}; if (!out) return; - sc_establish_context(&ctx, "test"); r = sc_asn1_decode_ecdsa_signature(ctx, (u8 *) data, 9, fieldsize, (u8 **) &out, 2); - assert_int_equal(r, SC_ERROR_INVALID_DATA); + assert_int_equal(r, SC_ERROR_INVALID_DATA); free(out); } int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test(torture_empty_rs), - cmocka_unit_test(torture_valid_format), - cmocka_unit_test(torture_valid_format_leading00), - cmocka_unit_test(torture_valid_format_long_fieldsize), - cmocka_unit_test(torture_wrong_tag_len), - cmocka_unit_test(torture_wrong_integer_tag_len), - cmocka_unit_test(torture_small_fieldsize), - cmocka_unit_test(torture_long_leading00), - cmocka_unit_test(torture_missing_tag), - cmocka_unit_test(torture_missing_integer_tag), + cmocka_unit_test_setup_teardown(torture_empty_rs, setup, teardown), + cmocka_unit_test_setup_teardown(torture_valid_format, setup, teardown), + cmocka_unit_test_setup_teardown(torture_valid_format_leading00, setup, teardown), + cmocka_unit_test_setup_teardown(torture_valid_format_long_fieldsize, setup, teardown), + cmocka_unit_test_setup_teardown(torture_wrong_tag_len, setup, teardown), + cmocka_unit_test_setup_teardown(torture_wrong_integer_tag_len, setup, teardown), + cmocka_unit_test_setup_teardown(torture_small_fieldsize, setup, teardown), + cmocka_unit_test_setup_teardown(torture_long_leading00, setup, teardown), + cmocka_unit_test_setup_teardown(torture_missing_tag, setup, teardown), + cmocka_unit_test_setup_teardown(torture_missing_integer_tag, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } diff --git a/src/tests/unittests/pkcs15-emulator-filter.c b/src/tests/unittests/pkcs15-emulator-filter.c index 531ef7dd1a..0fe2ba67df 100644 --- a/src/tests/unittests/pkcs15-emulator-filter.c +++ b/src/tests/unittests/pkcs15-emulator-filter.c @@ -213,7 +213,6 @@ static void torture_one_to_full_add_emul_list(void **state) assert_int_equal(rv, SC_ERROR_TOO_MANY_OBJECTS); assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[0]); assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); - assert_ptr_not_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS], &old[0]); } static void torture_overfilled_add_emul_list(void **state) @@ -288,6 +287,7 @@ static void torture_internal_name(void **state) assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(&builtin[0], filtered_emulators.list_of_handlers[0]); assert_null(filtered_emulators.list_of_handlers[1]); + free(list.data); } static void torture_old_name(void **state) @@ -301,6 +301,7 @@ static void torture_old_name(void **state) assert_int_equal(rv, SC_SUCCESS); assert_ptr_equal(&old[0], filtered_emulators.list_of_handlers[0]); assert_null(filtered_emulators.list_of_handlers[1]); + free(list.data); } static void torture_internal_and_name(void **state) @@ -434,6 +435,7 @@ static void torture_one_to_full2_set_emul(void **state) assert_ptr_equal(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS - 1], &old[1]); assert_null(filtered_emulators.list_of_handlers[SC_MAX_PKCS15_EMULATORS]); assert_int_equal(filtered_emulators.ccount, SC_MAX_PKCS15_EMULATORS); + free(list1.data); } static void torture_overfilled_set_emul(void **state) @@ -448,6 +450,7 @@ static void torture_overfilled_set_emul(void **state) rv = set_emulators(NULL, &filtered_emulators, &list1, builtin, old); assert_int_equal(rv, SC_ERROR_INVALID_ARGUMENTS); + free(list1.data); } int main(void) From fbc4ebbc8ebdb5f15663576e33b97f7588a90643 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 18 May 2023 19:12:01 +0200 Subject: [PATCH 2925/4321] ci: Try to address another breakage of 32b images --- .github/setup-linux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index 63a57ad81a..c05a644659 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -27,7 +27,7 @@ elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == " elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then # Note, that this list is somehow magic and adding libwine, libwine:i386 or wine64 # will make the following sections break without any useful logs. See GH#2458 - WINE_DEPS="wine wine32 xvfb wget" + WINE_DEPS="wine wine32 xvfb wget libc6:i386 libgcc-s1:i386 libstdc++6:i386" if [ "$1" == "mingw" ]; then WINE_DEPS="$WINE_DEPS binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64" elif [ "$1" == "mingw32" ]; then @@ -62,7 +62,7 @@ if [ "$1" == "libressl" -o "$2" == "libressl" ]; then fi if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then - sudo apt-get install -y $WINE_DEPS + sudo apt-get install --allow-downgrades -y $WINE_DEPS if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 export DISPLAY=:99.0 From 2b4958e49e00b064ad91475a55897a3d63033a1d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 18 May 2023 21:04:45 +0200 Subject: [PATCH 2926/4321] m4: Use up-to-date valgrind from current autoconf-archive --- m4/ax_valgrind_check.m4 | 239 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 m4/ax_valgrind_check.m4 diff --git a/m4/ax_valgrind_check.m4 b/m4/ax_valgrind_check.m4 new file mode 100644 index 0000000000..e0d8a2f3ae --- /dev/null +++ b/m4/ax_valgrind_check.m4 @@ -0,0 +1,239 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off) +# AX_VALGRIND_CHECK() +# +# DESCRIPTION +# +# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows +# running `make check` under a variety of Valgrind tools to check for +# memory and threading errors. +# +# Defines VALGRIND_CHECK_RULES which should be substituted in your +# Makefile; and $enable_valgrind which can be used in subsequent configure +# output. VALGRIND_ENABLED is defined and substituted, and corresponds to +# the value of the --enable-valgrind option, which defaults to being +# enabled if Valgrind is installed and disabled otherwise. Individual +# Valgrind tools can be disabled via --disable-valgrind-, the +# default is configurable via the AX_VALGRIND_DFLT command or is to use +# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT +# calls must be made before the call to AX_VALGRIND_CHECK. +# +# If unit tests are written using a shell script and automake's +# LOG_COMPILER system, the $(VALGRIND) variable can be used within the +# shell scripts to enable Valgrind, as described here: +# +# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html +# +# Usage example: +# +# configure.ac: +# +# AX_VALGRIND_DFLT([sgcheck], [off]) +# AX_VALGRIND_CHECK +# +# in each Makefile.am with tests: +# +# @VALGRIND_CHECK_RULES@ +# VALGRIND_SUPPRESSIONS_FILES = my-project.supp +# EXTRA_DIST = my-project.supp +# +# This results in a "check-valgrind" rule being added. Running `make +# check-valgrind` in that directory will recursively run the module's test +# suite (`make check`) once for each of the available Valgrind tools (out +# of memcheck, helgrind and drd) while the sgcheck will be skipped unless +# enabled again on the commandline with --enable-valgrind-sgcheck. The +# results for each check will be output to test-suite-$toolname.log. The +# target will succeed if there are zero errors and fail otherwise. +# +# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in +# memcheck, helgrind, drd and sgcheck. These are useful because often only +# some of those tools can be ran cleanly on a codebase. +# +# The macro supports running with and without libtool. +# +# LICENSE +# +# Copyright (c) 2014, 2015, 2016 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 23 + +dnl Configured tools +m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]]) +m4_set_add_all([valgrind_exp_tool_set], [sgcheck]) +m4_foreach([vgtool], [valgrind_tool_list], + [m4_define([en_dflt_valgrind_]vgtool, [on])]) + +AC_DEFUN([AX_VALGRIND_DFLT],[ + m4_define([en_dflt_valgrind_$1], [$2]) +])dnl + +AC_DEFUN([AX_VALGRIND_CHECK],[ + AM_EXTRA_RECURSIVE_TARGETS([check-valgrind]) + m4_foreach([vgtool], [valgrind_tool_list], + [AM_EXTRA_RECURSIVE_TARGETS([check-valgrind-]vgtool)]) + + dnl Check for --enable-valgrind + AC_ARG_ENABLE([valgrind], + [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], + [enable_valgrind=$enableval],[enable_valgrind=]) + + AS_IF([test "$enable_valgrind" != "no"],[ + # Check for Valgrind. + AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) + AS_IF([test "$VALGRIND" = ""],[ + AS_IF([test "$enable_valgrind" = "yes"],[ + AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) + ],[ + enable_valgrind=no + ]) + ],[ + enable_valgrind=yes + ]) + ]) + + AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) + AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) + + # Check for Valgrind tools we care about. + [valgrind_enabled_tools=] + m4_foreach([vgtool],[valgrind_tool_list],[ + AC_ARG_ENABLE([valgrind-]vgtool, + m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl +[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl +[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]), + [enable_valgrind_]vgtool[=$enableval], + [enable_valgrind_]vgtool[=]) + AS_IF([test "$enable_valgrind" = "no"],[ + enable_valgrind_]vgtool[=no], + [test "$enable_valgrind_]vgtool[" ]dnl +m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[ + AC_CACHE_CHECK([for Valgrind tool ]vgtool, + [ax_cv_valgrind_tool_]vgtool,[ + ax_cv_valgrind_tool_]vgtool[=no + m4_set_contains([valgrind_exp_tool_set],vgtool, + [m4_define([vgtoolx],[exp-]vgtool)], + [m4_define([vgtoolx],vgtool)]) + AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[ + ax_cv_valgrind_tool_]vgtool[=yes + ]) + ]) + AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[ + AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ + AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool) + ],[ + enable_valgrind_]vgtool[=no + ]) + ],[ + enable_valgrind_]vgtool[=yes + ]) + ]) + AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ + valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[" + ]) + AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool) + ]) + AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["]) + AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools]) + +[VALGRIND_CHECK_RULES=' +# Valgrind check +# +# Optional: +# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions +# files to load. (Default: empty) +# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. +# (Default: --num-callers=30) +# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: +# memcheck, helgrind, drd, sgcheck). (Default: various) + +# Optional variables +VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) +VALGRIND_FLAGS ?= --num-callers=30 +VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no +VALGRIND_helgrind_FLAGS ?= --history-level=approx +VALGRIND_drd_FLAGS ?= +VALGRIND_sgcheck_FLAGS ?= + +# Internal use +valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) + +valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) +valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) +valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) +valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) + +valgrind_quiet = $(valgrind_quiet_$(V)) +valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) +valgrind_quiet_0 = --quiet +valgrind_v_use = $(valgrind_v_use_$(V)) +valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) +valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-local,%,$''@):; + +# Support running with and without libtool. +ifneq ($(LIBTOOL),) +valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute +else +valgrind_lt = +endif + +# Use recursive makes in order to ignore errors during check +check-valgrind-local: +ifeq ($(VALGRIND_ENABLED),yes) + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \ + $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool)) +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +# Valgrind running +VALGRIND_TESTS_ENVIRONMENT = \ + $(TESTS_ENVIRONMENT) \ + env VALGRIND=$(VALGRIND) \ + G_SLICE=always-malloc,debug-blocks \ + G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly + +VALGRIND_LOG_COMPILER = \ + $(valgrind_lt) \ + $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) + +define valgrind_tool_rule +check-valgrind-$(1)-local: +ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) +ifneq ($$(TESTS),) + $$(valgrind_v_use)$$(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$$(valgrind_$(1)_flags)" \ + TEST_SUITE_LOG=test-suite-$(1).log +endif +else ifeq ($$(VALGRIND_ENABLED),yes) + @echo "Need to reconfigure with --enable-valgrind-$(1)" +else + @echo "Need to reconfigure with --enable-valgrind" +endif +endef + +$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind + +MOSTLYCLEANFILES ?= +MOSTLYCLEANFILES += $(valgrind_log_files) + +.PHONY: check-valgrind $(addprefix check-valgrind-,$(valgrind_tools)) +'] + + AC_SUBST([VALGRIND_CHECK_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) +]) From c80d63a3d080ffabfba069b4a9114a3c7f2afae3 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 10:31:27 +0200 Subject: [PATCH 2927/4321] ci: Upload also unit tests results --- .github/workflows/linux.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9d921de165..b38fa9548b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -30,8 +30,9 @@ jobs: if: failure() with: name: ubuntu-test-logs - path: + path: | tests/*.log + src/tests/unittests/*.log - uses: actions/cache@v3 id: cache-build with: @@ -201,8 +202,9 @@ jobs: if: failure() with: name: ubuntu-22-test-logs - path: + path: | tests/*.log + src/tests/unittests/*.log - uses: actions/cache@v3 id: cache-build if: ${{ success() }} From 3cca65baa152ce327970e5892417f65a09a464a8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 14:12:27 +0200 Subject: [PATCH 2928/4321] p11test: Free message on exit path --- src/tests/p11test/p11test_case_pss_oaep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 0102db0dcc..1eb0bb431a 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -583,8 +583,8 @@ int pss_verify_message_openssl(test_cert_t *o, token_info_t *info, o->id_str, ERR_error_string(ERR_peek_last_error(), NULL)); goto out; } - free(free_message); out: + free(free_message); EVP_PKEY_CTX_free(pctx); return rv; } @@ -709,7 +709,7 @@ void fill_object_pss_mechanisms(token_info_t *info, test_cert_t *o) test_mech_t *source_mech = &token.rsa_mechs[j]; /* skip non-RSA-PSS mechs early */ - if (!is_pss_mechanism(source_mech->mech) && + if (!is_pss_mechanism(source_mech->mech) && source_mech->mech != CKM_RSA_PKCS_OAEP) { continue; } From ef56df67eee3f84ee91d0b283a6206515c88a5bb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 14:13:06 +0200 Subject: [PATCH 2929/4321] openpgp: Free allocated memory --- src/libopensc/card-openpgp.c | 6 +++++- src/tools/openpgp-tool.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 9e2f12f5d2..cc454cef59 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2837,10 +2837,14 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); r = sc_pkcs15_encode_pubkey(card->ctx, &p15pubkey, &data, &len); - LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); + if (r != 0) { + free(data); + LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); + } sc_log(card->ctx, "Updating blob %04X's content.", blob_id); r = pgp_set_blob(pk_blob, data, len); + free(data); LOG_TEST_RET(card->ctx, r, "Cannot update blob content"); LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 1f3be0fb94..5f9451b6d3 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -520,6 +520,7 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) if (sc_select_file(card, &path, &file) >= 0) { u8 attrs[6]; /* algorithm attrs DO for RSA is <= 6 bytes */ + sc_file_free(file); r = sc_read_binary(card, 0, attrs, sizeof(attrs), 0); if (r >= 5 && attrs[0] == SC_OPENPGP_KEYALGO_RSA) { expolen = (unsigned short) attrs[3] << 8 @@ -554,6 +555,7 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); + sc_file_free(file); if (r < 0) { util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); return EXIT_FAILURE; From e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 16:49:00 +0200 Subject: [PATCH 2930/4321] openpgp: Fix fingerprint calculation fixes https://github.com/OpenSC/OpenSC/issues/2775 --- src/libopensc/card-openpgp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index cc454cef59..496e38e6d1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2697,15 +2697,23 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, /* RSA */ if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { + unsigned short bytes_length = 0; + *p = 1; /* Algorithm ID, RSA */ p += 1; + + /* Modulus */ + bytes_length = BYTES4BITS(key_info->u.rsa.modulus_len); ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len); p += 2; - memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len))); - p += (key_info->u.rsa.modulus_len >> 3); - ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len); + memcpy(p, key_info->u.rsa.modulus, bytes_length); + p += bytes_length; + + /* Exponent */ + bytes_length = BYTES4BITS(key_info->u.rsa.exponent_len); + ushort2bebytes(p, (unsigned short)key_info->u.rsa.exponent_len); p += 2; - memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len))); + memcpy(p, key_info->u.rsa.exponent, bytes_length); } /* ECC */ else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH From 6f4c270060f556ff01ebc53fac4e6d4ab5249c91 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 17:09:59 +0200 Subject: [PATCH 2931/4321] isoapplet: Fix RSA-PSS calculation when the data does not contain digestinfo This lead to using of uninitialized memory (tmp array) when talking to the pcsc and inevitable failure to verify the signature throughout the tests. --- src/libopensc/card-isoApplet.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 4e4b06eb36..f17bdb34f8 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1218,8 +1218,13 @@ isoApplet_compute_signature(struct sc_card *card, // For RSA-PSS signature schemes the IsoApplet expects only the hash. u8 tmp[64]; // large enough for SHA512 size_t tmplen = sizeof(tmp); - sc_pkcs1_strip_digest_info_prefix(NULL, data, datalen, tmp, &tmplen); - r = iso_ops->compute_signature(card, tmp, tmplen, out, outlen); + r = sc_pkcs1_strip_digest_info_prefix(NULL, data, datalen, tmp, &tmplen); + if (r == SC_SUCCESS) { + r = iso_ops->compute_signature(card, tmp, tmplen, out, outlen); + } else { + /* No digest info present? Use the value as it is */ + r = iso_ops->compute_signature(card, data, datalen, out, outlen); + } } else if (drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_ECDSA) { /* * The card returns ECDSA signatures as an ASN.1 sequence of integers R,S From 9a8a442d482865f88e70dd3d7b9b916fdfc297ed Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 17:52:41 +0200 Subject: [PATCH 2932/4321] tests: Update isoapplet v1 reference p11test log --- src/tests/p11test/isoapplet_ref_v1.json | 81 +++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/tests/p11test/isoapplet_ref_v1.json b/src/tests/p11test/isoapplet_ref_v1.json index ebb2ab8ad2..97d8f62f1a 100644 --- a/src/tests/p11test/isoapplet_ref_v1.json +++ b/src/tests/p11test/isoapplet_ref_v1.json @@ -430,6 +430,87 @@ "SIGN&VERIFY WORKS", "ENCRYPT&DECRYPT WORKS" ], + [ + "01", + "RSA_PKCS_PSS", + "SHA_1", + "MGF1_SHA_1", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA224", + "MGF1_SHA224", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA256", + "MGF1_SHA256", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA384", + "MGF1_SHA384", + "-1", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-2", + "YES", + "" + ], + [ + "01", + "RSA_PKCS_PSS", + "SHA512", + "MGF1_SHA512", + "-1", + "YES", + "" + ], [ "01", "SHA1_RSA_PKCS_PSS", From 891f10e49de1a5ee038b1cb2fb59dce40429e6c2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 17:53:35 +0200 Subject: [PATCH 2933/4321] openpgp: Fix modulus length calculation in pkc15init layer --- src/libopensc/pkcs15.h | 2 +- src/pkcs15init/pkcs15-openpgp.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 5a0a19c5a6..ba685a30f0 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -373,7 +373,7 @@ struct sc_pkcs15_prkey_info { unsigned int usage, access_flags; int native, key_reference; /* convert to union if other types are supported */ - size_t modulus_length; /* RSA */ + size_t modulus_length; /* RSA, in bits */ size_t field_length; /* EC in bits */ unsigned int algo_refs[SC_MAX_SUPPORTED_ALGORITHMS]; diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index c75bcbdaba..3e060be5a4 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -235,7 +235,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, /* Prepare buffer */ key_info.u.rsa.modulus_len = required->modulus_length; - key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1); + key_info.u.rsa.modulus = calloc(BYTES4BITS(required->modulus_length), 1); if (key_info.u.rsa.modulus == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); @@ -252,18 +252,18 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, pubkey->algorithm = SC_ALGORITHM_RSA; sc_log(ctx, "Set output modulus info"); - pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len; - pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1); + pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len); + pubkey->u.rsa.modulus.data = calloc(pubkey->u.rsa.modulus.len, 1); if (pubkey->u.rsa.modulus.data == NULL) goto err; - memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len); + memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len)); sc_log(ctx, "Set output exponent info"); - pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len; - pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1); + pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len); + pubkey->u.rsa.exponent.data = calloc(pubkey->u.rsa.exponent.len, 1); if (pubkey->u.rsa.exponent.data == NULL) goto err; - memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len)); + memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len); err: free(key_info.u.rsa.modulus); From f38ea19d33f5799232795d6d9b471287b782c140 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 19 May 2023 21:21:45 +0200 Subject: [PATCH 2934/4321] openpgp: Avoid leaking file structure --- src/libopensc/card-openpgp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 496e38e6d1..c304c321fe 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -3657,8 +3657,10 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path) blob = priv->current; /* don't try to delete MF */ - if (blob == priv->mf) + if (blob == priv->mf) { + sc_file_free(file); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && (file->id == DO_SIGN_SYM || file->id == DO_ENCR_SYM || file->id == DO_AUTH_SYM)) { @@ -3678,6 +3680,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path) /* call pgp_put_data() with zero-sized NULL-buffer to zap the DO contents */ r = pgp_put_data(card, file->id, NULL, 0); } + sc_file_free(file); /* set "current" blob to parent */ priv->current = blob->parent; From bc114501faacfc69eaa98b789463d180a1b71da7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Apr 2023 15:58:47 +0200 Subject: [PATCH 2935/4321] tests: Support running under valgrind both tests executed during `make check` as well as the integration tests ran from the github CI with java card simulator or other software implementations. --- .github/build.sh | 22 +++++++++++++---- .github/dump-logs.sh | 10 ++++++++ .github/setup-linux.sh | 2 +- .github/setup-valgrind.sh | 17 +++++++++++++ .github/test-cac.sh | 14 +++++------ .github/test-gidsapplet.sh | 8 ++++--- .github/test-isoapplet.sh | 38 +++++++++++++++-------------- .github/test-openpgp.sh | 12 ++++++---- .github/test-piv.sh | 10 ++++---- .github/workflows/linux.yml | 42 ++++++++++++++++++++++++++++++--- configure.ac | 2 ++ src/tests/unittests/Makefile.am | 6 +++++ tests/Makefile.am | 14 ++++++++++- tests/common.sh | 6 ++++- 14 files changed, 155 insertions(+), 48 deletions(-) create mode 100644 .github/dump-logs.sh create mode 100644 .github/setup-valgrind.sh diff --git a/.github/build.sh b/.github/build.sh index c1fd2df7ff..ffe0ff28a7 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -34,7 +34,7 @@ if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then unset CC unset CXX ./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=$PWD/win32/opensc || cat config.log; - make -j 2 V=1 + make -j 4 V=1 # no point in running tests on mingw else if [ "$1" == "ix86" ]; then @@ -43,15 +43,29 @@ else fi # normal procedure - if [ "$1" == "no-shared" ]; then + if [ "$1" == "valgrind" ]; then + ./configure --disable-notify --enable-valgrind + elif [ "$1" == "no-shared" ]; then ./configure --disable-shared else ./configure --disable-dependency-tracking fi - make -j 2 V=1 + make -j 4 V=1 # 32b build has some issues to find openssl correctly - if [ "$1" != "ix86" ]; then + if [ "$1" == "valgrind" ]; then + make check-valgrind-memcheck + RV=$? + source .github/dump-logs.sh + if [ $RV -ne 0 ]; then + exit $RV + fi + elif [ "$1" != "ix86" ]; then make check + RV=$? + source .github/dump-logs.sh + if [ $RV -ne 0 ]; then + exit $RV + fi fi fi diff --git a/.github/dump-logs.sh b/.github/dump-logs.sh new file mode 100644 index 0000000000..690a4df836 --- /dev/null +++ b/.github/dump-logs.sh @@ -0,0 +1,10 @@ +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +for F in tests/*.log src/tests/unittests/*.log; do + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + echo $F + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + cat $F + echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" +done +echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" + diff --git a/.github/setup-linux.sh b/.github/setup-linux.sh index c05a644659..58ce030379 100755 --- a/.github/setup-linux.sh +++ b/.github/setup-linux.sh @@ -4,7 +4,7 @@ set -ex -o xtrace WINE_DEPS="" # Generic dependencies -DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd openssl" +DEPS="docbook-xsl xsltproc gengetopt help2man pcscd check pcsc-tools libtool make autoconf autoconf-archive automake pkg-config git xxd openssl valgrind" # 64bit or 32bit dependencies if [ "$1" == "ix86" ]; then diff --git a/.github/setup-valgrind.sh b/.github/setup-valgrind.sh new file mode 100644 index 0000000000..c5aa9b4636 --- /dev/null +++ b/.github/setup-valgrind.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# +# To be sourced to the test scripts to run the OpenSC tools under valgrind +# +if [ "$1" == "valgrind" -o "$2" == "valgrind" ]; then + # the glib raises dozens of memory related issues so we will rebuild opensc without notify support + ./configure --disable-notify + make clean && make -j 4 V=1 + + # suppression file contains supressions for the notification support which leaks memory + # The other option would be to build without the notification support. + # export VALGRIND="valgrind --error-exitcode=1 --leak-check=full --keep-debuginfo=yes --suppressions=$PWD/tests/opensc.supp" + export VALGRIND="valgrind --error-exitcode=1 --leak-check=full --keep-debuginfo=yes --trace-children=yes --gen-suppressions=all" + # this should help us getting better traces as some of pcsclite and avoid false positives + export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libpcsclite.so.1" +fi diff --git a/.github/test-cac.sh b/.github/test-cac.sh index 8607d9815f..4fd23f4317 100755 --- a/.github/test-cac.sh +++ b/.github/test-cac.sh @@ -2,6 +2,8 @@ set -ex -o xtrace +source .github/setup-valgrind.sh + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -33,20 +35,16 @@ fi pushd virt_cacard ./setup-softhsm2.sh export SOFTHSM2_CONF=$PWD/softhsm2.conf -# register cleanup function on exit -trap "pkill -9 virt_cacard" EXIT ./virt_cacard 2>&1 | sed -e 's/^/virt_cacard: /;' & +PID=$! popd # run the tests pushd src/tests/p11test/ sleep 5 -./p11test -s 0 -p 12345678 -o virt_cacard.json -popd - -# cleanup -- this would break later uses of pcscd -pushd vsmartcard/virtualsmartcard -sudo make uninstall +$VALGRIND ./p11test -s 0 -p 12345678 -o virt_cacard.json popd diff -u3 src/tests/p11test/virt_cacard{_ref,}.json + +kill -9 $PID diff --git a/.github/test-gidsapplet.sh b/.github/test-gidsapplet.sh index f102df2fa1..9ee0eadd5a 100755 --- a/.github/test-gidsapplet.sh +++ b/.github/test-gidsapplet.sh @@ -2,6 +2,8 @@ set -ex -o xtrace +source .github/setup-valgrind.sh + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -29,7 +31,7 @@ echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg; java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null & PID=$!; sleep 5; -opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100; -opensc-tool -n; -gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; +$VALGRIND opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100; +$VALGRIND opensc-tool -n; +$VALGRIND gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000; kill -9 $PID diff --git a/.github/test-isoapplet.sh b/.github/test-isoapplet.sh index 552545314e..08b9c0277e 100755 --- a/.github/test-isoapplet.sh +++ b/.github/test-isoapplet.sh @@ -2,6 +2,8 @@ set -ex -o xtrace +source .github/setup-valgrind.sh + isoapplet_version="$1" if [ "$isoapplet_version" = "v0" ]; then isoapplet_branch="main-javacard-v2.2.2" @@ -45,7 +47,7 @@ PID=$! sleep 5 # Does OpenSC see the uninitialized card? -pkcs11-tool -L | tee opensc.log +$VALGRIND pkcs11-tool -L | tee opensc.log # report as "token not recognized" grep "(token not recognized)" opensc.log @@ -63,35 +65,35 @@ OPENSC_CONF=opensc.conf pkcs11-tool -L | tee opensc.log # report as "token not recognized" grep "uninitialized" opensc.log -opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100 -opensc-tool -n -pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef -pkcs15-tool --change-pin --pin 123456 --new-pin 654321 -pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456 -pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456 -pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456 -pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456 -pkcs15-tool -D -pkcs11-tool -l -t -p 123456 +$VALGRIND opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100 +$VALGRIND opensc-tool -n +$VALGRIND pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef +$VALGRIND pkcs15-tool --change-pin --pin 123456 --new-pin 654321 +$VALGRIND pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456 +$VALGRIND pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456 +$VALGRIND pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456 +$VALGRIND pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456 +$VALGRIND pkcs15-tool -D +$VALGRIND pkcs11-tool -l -t -p 123456 # run the tests pushd src/tests/p11test/ sleep 5 -./p11test -s 0 -p 123456 -o isoapplet.json +$VALGRIND ./p11test -s 0 -p 123456 -o isoapplet.json popd # random data to be signed dd if=/dev/random of=/tmp/data.bin bs=300 count=1 # sign & verify using secp256r1 key -pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 3 -i /tmp/data.bin -o /tmp/data.sig -pkcs11-tool --verify -m ECDSA-SHA1 -d 3 -i /tmp/data.bin --signature-file /tmp/data.sig +$VALGRIND pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 3 -i /tmp/data.bin -o /tmp/data.sig +$VALGRIND pkcs11-tool --verify -m ECDSA-SHA1 -d 3 -i /tmp/data.bin --signature-file /tmp/data.sig # import, sign & verify using another secp256r1 key openssl ecparam -name secp256r1 -genkey -noout -out /tmp/ECprivKey.pem openssl ec -in /tmp/ECprivKey.pem -pubout -out /tmp/ECpubKey.pem -pkcs11-tool -l -p 123456 -w /tmp/ECprivKey.pem -y privkey -d 4 -pkcs11-tool -l -p 123456 -w /tmp/ECpubKey.pem -y pubkey -d 4 -pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 4 -i /tmp/data.bin -o /tmp/data.sig -pkcs11-tool --verify -m ECDSA-SHA1 -d 4 -i /tmp/data.bin --signature-file /tmp/data.sig +$VALGRIND pkcs11-tool -l -p 123456 -w /tmp/ECprivKey.pem -y privkey -d 4 +$VALGRIND pkcs11-tool -l -p 123456 -w /tmp/ECpubKey.pem -y pubkey -d 4 +$VALGRIND pkcs11-tool -l -p 123456 -s -m ECDSA-SHA1 -d 4 -i /tmp/data.bin -o /tmp/data.sig +$VALGRIND pkcs11-tool --verify -m ECDSA-SHA1 -d 4 -i /tmp/data.bin --signature-file /tmp/data.sig # cleanup rm /tmp/ECprivKey.pem /tmp/ECpubKey.pem /tmp/data.bin /tmp/data.sig diff --git a/.github/test-openpgp.sh b/.github/test-openpgp.sh index e2f4be0200..74ed6a227d 100755 --- a/.github/test-openpgp.sh +++ b/.github/test-openpgp.sh @@ -2,6 +2,8 @@ set -ex -o xtrace +source .github/setup-valgrind.sh + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -31,9 +33,9 @@ echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg; java -noverify -cp ykneo-openpgp/applet/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard openpgp_jcardsim.cfg >/dev/null & PID=$!; sleep 5; -opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; -opensc-tool -n; -openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; -pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; -pkcs11-tool -l -t -p 123456; +$VALGRIND opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000; +$VALGRIND opensc-tool -n; +$VALGRIND openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2; +$VALGRIND pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048; +$VALGRIND pkcs11-tool -l -t -p 123456; kill -9 $PID diff --git a/.github/test-piv.sh b/.github/test-piv.sh index 9dcfe52a42..43058f3d60 100755 --- a/.github/test-piv.sh +++ b/.github/test-piv.sh @@ -2,6 +2,8 @@ set -ex -o xtrace +source .github/setup-valgrind.sh + # install the opensc sudo make install export LD_LIBRARY_PATH=/usr/local/lib @@ -43,8 +45,8 @@ popd java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard PivApplet/test/jcardsim.cfg >/dev/null & PID=$! sleep 5 -opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f -opensc-tool -n +$VALGRIND opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f +$VALGRIND opensc-tool -n PIN="123456" yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9e -a generate -A RSA2048 | tee 9e.pub @@ -55,6 +57,6 @@ yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -a generate -A EC yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -S'/CN=bar/OU=test/O=example.com/' -averify -aselfsign < 9a.pub | tee 9a.cert yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P "$PIN" -s 9a -aimport-certificate < 9a.cert -pkcs11-tool -l -O -p "$PIN" -pkcs11-tool -l -t -p "$PIN" +$VALGRIND pkcs11-tool -l -O -p "$PIN" +$VALGRIND pkcs11-tool -l -t -p "$PIN" kill -9 $PID diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b38fa9548b..bb3b06368b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -1,3 +1,4 @@ +--- name: Linux on: @@ -18,6 +19,7 @@ on: permissions: contents: read # to fetch code (actions/checkout) + jobs: build: runs-on: ubuntu-20.04 @@ -45,12 +47,38 @@ jobs: path: opensc*.tar.gz + valgrind: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: .github/setup-linux.sh + - run: .github/build.sh valgrind + - name: Upload test logs + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ubuntu-valgrind-logs + path: | + tests/*.log + src/tests/unittests/*.log + - uses: actions/cache@v3 + id: cache-build + with: + path: ./* + key: ${{ runner.os }}-${{ github.sha }} + - name: Upload build artifacts + uses: actions/upload-artifact@v3 + with: + name: opensc-build + path: + opensc*.tar.gz + build-no-shared: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: .github/setup-linux.sh - - run: .github/build.sh no-shared + - run: .github/build.sh no-shared valgrind build-ix86: runs-on: ubuntu-20.04 @@ -97,6 +125,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh piv - run: .github/test-piv.sh + - run: .github/test-piv.sh valgrind test-isoapplet-v0: runs-on: ubuntu-20.04 @@ -110,6 +139,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh v0 + - run: .github/test-isoapplet.sh v0 valgrind test-isoapplet-v1: runs-on: ubuntu-20.04 @@ -123,6 +153,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh isoapplet - run: .github/test-isoapplet.sh v1 + - run: .github/test-isoapplet.sh v1 valgrind test-gidsapplet: runs-on: ubuntu-20.04 @@ -136,6 +167,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh gidsapplet - run: .github/test-gidsapplet.sh + - run: .github/test-gidsapplet.sh valgrind test-openpgp: runs-on: ubuntu-20.04 @@ -149,6 +181,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh openpgp - run: .github/test-openpgp.sh + - run: .github/test-openpgp.sh valgrind build-clang-tidy: runs-on: ubuntu-20.04 @@ -175,6 +208,7 @@ jobs: key: ${{ runner.os }}-${{ github.sha }} - run: .github/setup-linux.sh cac - run: .github/test-cac.sh + - run: .github/test-cac.sh valgrind test-oseid: runs-on: ubuntu-20.04 @@ -197,7 +231,7 @@ jobs: steps: - uses: actions/checkout@v3 - run: .github/setup-linux.sh - - run: .github/build.sh dist + - run: .github/build.sh dist valgrind - uses: actions/upload-artifact@v3 if: failure() with: @@ -231,6 +265,7 @@ jobs: key: ${{ runner.os }}-22-${{ github.sha }} - run: .github/setup-linux.sh cac - run: .github/test-cac.sh + - run: .github/test-cac.sh valgrind test-oseid-ubuntu-22: runs-on: ubuntu-22.04 @@ -253,7 +288,7 @@ jobs: steps: - uses: actions/checkout@v3 - run: .github/setup-linux.sh libressl - - run: .github/build.sh dist libressl + - run: .github/build.sh dist libressl valgrind - uses: actions/upload-artifact@v3 if: failure() with: @@ -280,6 +315,7 @@ jobs: key: ${{ runner.os }}-libressl-${{ github.sha }} - run: .github/setup-linux.sh cac libressl - run: .github/test-cac.sh + - run: .github/test-cac.sh valgrind test-oseid-libressl: runs-on: ubuntu-latest diff --git a/configure.ac b/configure.ac index 35688b4d16..0a90445b9e 100644 --- a/configure.ac +++ b/configure.ac @@ -149,6 +149,8 @@ AX_CODE_COVERAGE() AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"]) AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"]) +AX_VALGRIND_CHECK() + AC_ARG_ENABLE( [fuzzing], [AS_HELP_STRING([--enable-fuzzing],[enable compile of fuzzing tests @<:@disabled@:>@, note that CC, CFLAGS and FUZZING_LIBS should be set accordingly, e.g. to something like CC="clang" CFLAGS="-fsanitize=fuzzer-no-link" FUZZING_LIBS="-fsanitize=fuzzer"])], diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 3c168b8764..61f86b43f4 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -6,6 +6,12 @@ include $(top_srcdir)/aminclude_static.am clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean +@VALGRIND_CHECK_RULES@ +#VALGRIND_SUPPRESSIONS_FILES = $(top_srcdir)/tests/opensc.supp +VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all +# to avoid false positive leaks from pcsclite +TESTS_ENVIRONMENT = LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1' + noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature diff --git a/tests/Makefile.am b/tests/Makefile.am index 9d8a24c321..3fafd27fb3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,10 +1,22 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +@VALGRIND_CHECK_RULES@ +#VALGRIND_SUPPRESSIONS_FILES = opensc.supp +#EXTRA_DIST = opensc.supp +VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all +# Do not run the bash scripts under valgrind +TEST_EXTENSIONS = .sh +LOG_COMPILER = $(LOG_VALGRIND) + +# This pushes the valgrind command to the test environment +# the LD_PRELOAD is to avoid false positive leaks from pcsclite AM_TESTS_ENVIRONMENT = \ SOURCE_PATH='$(top_srcdir)'; \ export SOURCE_PATH; \ BUILD_PATH='$(top_builddir)'; \ - export BUILD_PATH; + export BUILD_PATH; \ + VALGRIND='$(LOG_VALGRIND)'; \ + LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1'; dist_noinst_SCRIPTS = common.sh \ test-manpage.sh \ diff --git a/tests/common.sh b/tests/common.sh index ba7b797826..19461b98be 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -1,9 +1,10 @@ #!/bin/bash ## from OpenSC/src/tests/p11test/runtest.sh +BUILD_PATH=${BUILD_PATH:-..} SOPIN="12345678" PIN="123456" -PKCS11_TOOL="$BUILD_PATH/src/tools/pkcs11-tool" +PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ /usr/lib/softhsm/libsofthsm2.so @@ -60,6 +61,9 @@ function generate_key() { function softhsm_initialize() { echo "directories.tokendir = .tokens/" > .softhsm2.conf + if [ -d ".tokens" ]; then + rm -rf ".tokens" + fi mkdir ".tokens" export SOFTHSM2_CONF=".softhsm2.conf" # Init token From 481951b90b042b43fb5bd92cd3cd8d0f7e200b89 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 May 2023 14:47:37 +0200 Subject: [PATCH 2936/4321] tests: Properly propagate the VALGRIND env variable to the shell tests The valgrind macros set the VALGRIND variable without any arguments, which prevents it from failing if some issue is detected. --- tests/common.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/common.sh b/tests/common.sh index 19461b98be..fa1296921b 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -2,6 +2,11 @@ ## from OpenSC/src/tests/p11test/runtest.sh BUILD_PATH=${BUILD_PATH:-..} +# run valgrind with all the switches we are interested in +if [ -n "$VALGRIND" -a -n "$LOG_COMPILER" ]; then + VALGRIND="$LOG_COMPILER" +fi + SOPIN="12345678" PIN="123456" PKCS11_TOOL="$VALGRIND $BUILD_PATH/src/tools/pkcs11-tool" From 63d4bd3d3900682c8d2511e259abec63ce904895 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 May 2023 14:58:40 +0200 Subject: [PATCH 2937/4321] pkcs11-tool: Avoid dereferencing freed members when reading public keys --- src/tools/pkcs11-tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 85c500e223..1e9bf4bff5 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5739,8 +5739,6 @@ static int read_object(CK_SESSION_HANDLE session) util_fatal("cannot set OSSL_PARAM"); } OSSL_PARAM_BLD_free(bld); - OSSL_PARAM_free(old); - OSSL_PARAM_free(new); if (success) ASN1_STRING_free(os); free(value); @@ -5758,6 +5756,8 @@ static int read_object(CK_SESSION_HANDLE session) EVP_PKEY_CTX_free(ctx); util_fatal("cannot create EVP_PKEY"); } + OSSL_PARAM_free(old); + OSSL_PARAM_free(new); #endif if (!i2d_PUBKEY_bio(pout, pkey)) From e53f61ff145ea9de49c0858c0067078da68d6373 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 22 May 2023 14:59:10 +0200 Subject: [PATCH 2938/4321] tests: Check exit codes of helper functions --- tests/common.sh | 13 ++++++++----- tests/test-pkcs11-tool-import.sh | 1 + tests/test-pkcs11-tool-sign-verify.sh | 1 + tests/test-pkcs11-tool-test.sh | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/common.sh b/tests/common.sh index fa1296921b..8a5f090316 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -45,7 +45,6 @@ function generate_key() { # Generate key pair $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ --module="$P11LIB" --label="$LABEL" --id=$ID - if [[ "$?" -ne "0" ]]; then echo "Couldn't generate $TYPE key pair" return 1 @@ -54,6 +53,10 @@ function generate_key() { # Extract public key from the card $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ --module="$P11LIB" + if [[ "$?" -ne "0" ]]; then + echo "Couldn't read generated $TYPE public key" + return 1 + fi # convert it to more digestible PEM format if [[ ${TYPE:0:3} == "RSA" ]]; then @@ -79,13 +82,13 @@ function card_setup() { softhsm_initialize # Generate 1024b RSA Key pair - generate_key "RSA:1024" "01" "RSA_auth" + generate_key "RSA:1024" "01" "RSA_auth" || return 1 # Generate 2048b RSA Key pair - generate_key "RSA:2048" "02" "RSA2048" + generate_key "RSA:2048" "02" "RSA2048" || return 1 # Generate 256b ECC Key pair - generate_key "EC:secp256r1" "03" "ECC_auth" + generate_key "EC:secp256r1" "03" "ECC_auth" || return 1 # Generate 521b ECC Key pair - generate_key "EC:secp521r1" "04" "ECC521" + generate_key "EC:secp521r1" "04" "ECC521" || return 1 # Generate an HMAC:SHA256 key $PKCS11_TOOL --keygen --key-type="GENERIC:64" --login --pin=$PIN \ --module="$P11LIB" --label="HMAC-SHA256" diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh index c90b3b4926..653d0491ae 100755 --- a/tests/test-pkcs11-tool-import.sh +++ b/tests/test-pkcs11-tool-import.sh @@ -11,6 +11,7 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi card_setup +assert $? "Failed to set up card" for KEYTYPE in "RSA" "EC"; do echo "=======================================================" diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 3382771fdc..bcec7ee9b7 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -11,6 +11,7 @@ if [[ ! -f $P11LIB ]]; then exit 77; fi card_setup +assert $? "Failed to set up card" echo "data to sign (max 100 bytes)" > data echo "=======================================================" diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh index 0ab5f19bfe..2a1f43b8bc 100755 --- a/tests/test-pkcs11-tool-test.sh +++ b/tests/test-pkcs11-tool-test.sh @@ -15,6 +15,7 @@ fi grep "Ubuntu 18.04" /etc/issue && echo "WARNING: Not supported on Ubuntu 18.04" && exit 77 card_setup +assert $? "Failed to set up card" echo "=======================================================" echo "Test" From 646d8f5d5f02c7e472a3390d9b24177b19a556c7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 May 2023 16:15:28 +0200 Subject: [PATCH 2939/4321] fixup! p11test: Avoid memory leaks deteted by valgrind --- src/tests/p11test/p11test_case_common.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 6038725f2a..30c0b8611c 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -409,15 +409,29 @@ int callback_public_keys(test_certs_t *objects, } else { /* store the public key for future use */ o->type = EVP_PKEY_RSA; #if OPENSSL_VERSION_NUMBER < 0x30000000L - o->key = EVP_PKEY_new(); RSA *rsa = RSA_new(); - if (RSA_set0_key(rsa, n, e, NULL) != 1 || - EVP_PKEY_set1_RSA(o->key, rsa) != 1) { + if (rsa == NULL) { + fail_msg("Unable to allocate RSA key"); + return -1; + } + o->key = EVP_PKEY_new(); + if (o->key == NULL) { + fail_msg("Unable to allocate EVP_PKEY"); RSA_free(rsa); - fail_msg("Unable to set key params"); return -1; } - RSA_free(rsa); + if (RSA_set0_key(rsa, n, e, NULL) != 1) { + fail_msg("Unable set RSA key params"); + EVP_PKEY_free(o->key); + RSA_free(rsa); + return -1; + } + if (EVP_PKEY_assign_RSA(o->key, rsa) != 1) { + EVP_PKEY_free(o->key); + RSA_free(rsa); + fail_msg("Unable to assign RSA to EVP_PKEY"); + return -1; + } #else if (!(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) || !(bld = OSSL_PARAM_BLD_new()) || From 9f7e83fed024a18333bd4e7a31286cec104bb0bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 May 2023 16:16:39 +0200 Subject: [PATCH 2940/4321] fixup! openpgp: Free allocated memory --- src/libopensc/card-openpgp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index c304c321fe..5ab45742e1 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -2845,10 +2845,7 @@ pgp_update_pubkey_blob(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); r = sc_pkcs15_encode_pubkey(card->ctx, &p15pubkey, &data, &len); - if (r != 0) { - free(data); - LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); - } + LOG_TEST_RET(card->ctx, r, "Cannot encode pubkey"); sc_log(card->ctx, "Updating blob %04X's content.", blob_id); r = pgp_set_blob(pk_blob, data, len); From be5061303e7d6291e980082dc8896eef8fd78feb Mon Sep 17 00:00:00 2001 From: Marek Havrila Date: Wed, 31 May 2023 13:05:36 +0200 Subject: [PATCH 2941/4321] tests: Test signing more than 512 bytes of data Modify test-pkcs11-tool-sign-verify.sh to test on data bigger than 512 bytes to add test coverage for PR#2314 --- tests/test-pkcs11-tool-sign-verify.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index bcec7ee9b7..6b974fb2a0 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -12,7 +12,6 @@ if [[ ! -f $P11LIB ]]; then fi card_setup assert $? "Failed to set up card" -echo "data to sign (max 100 bytes)" > data echo "=======================================================" echo "Test RSA keys" @@ -20,8 +19,12 @@ echo "=======================================================" for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do for SIGN_KEY in "01" "02"; do METHOD="RSA-PKCS" + # RSA-PKCS works only on small data - generate small data: + head -c 64 data if [[ ! -z $HASH ]]; then METHOD="$HASH-$METHOD" + # hash- methods should work on data > 512 bytes + head -c 1024 data fi echo echo "=======================================================" @@ -47,6 +50,8 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do rm data.sig METHOD="$METHOD-PSS" + # -PSS methods should work on data > 512 bytes; generate data: + head -c 1024 data if [[ "$HASH" == "SHA512" ]]; then continue; # This one is broken fi @@ -95,6 +100,8 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do continue; fi METHOD="RSA-PKCS" + # RSA-PKCS works only on small data - generate small data: + head -c 64 data for ENC_KEY in "01" "02"; do echo echo "=======================================================" @@ -117,6 +124,8 @@ done echo "=======================================================" echo "Test ECDSA keys" echo "=======================================================" +# operations with ECDSA keys should work on data > 512 bytes; generate data: +head -c 1024 data for SIGN_KEY in "03" "04"; do METHOD="ECDSA" From 00305636c3733e96e97a587f2cce75592fb6db36 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 May 2023 13:23:34 +0200 Subject: [PATCH 2942/4321] ci: Run CI on any shell scripts change --- .github/workflows/fedora.yml | 4 +--- .github/workflows/linux.yml | 5 +---- .github/workflows/macos.yml | 5 +---- .github/workflows/packit.yaml | 1 + 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index 158b34587f..b33c82bfa3 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -5,10 +5,8 @@ on: paths: - '**.c' - '**.h' + - '**.sh' - .github/workflows/fedora.yml - - .github/setup-fedora.sh - - .github/build.sh - - .github/push-artifacts.sh - '**.am' - doc/** - configure.ac diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index bb3b06368b..5a7b54bc66 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,11 +6,8 @@ on: paths: - '**.c' - '**.h' + - '**.sh' - .github/workflows/linux.yml - - .github/setup-linux.sh - - .github/setup-libressl.sh - - .github/build.sh - - .github/push-artifacts.sh - '**.am' - doc/** - configure.ac diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4c8ab1fa72..55be1522ca 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -6,11 +6,8 @@ on: - '**.c' - '**.h' - '**.m' + - '**.sh' - .github/workflows/macos.yml - - .github/setup-macos.sh - - .github/cleanup-macos.sh - - .github/build.sh - - .github/push-artifacts.sh - '**.am' - MacOSX/** - configure.ac diff --git a/.github/workflows/packit.yaml b/.github/workflows/packit.yaml index e8c0f5b5d6..f77a1e5ff7 100644 --- a/.github/workflows/packit.yaml +++ b/.github/workflows/packit.yaml @@ -5,6 +5,7 @@ on: - '**.c' - '**.h' - '**.am' + - '**.sh' - .github/workflows/packit.yaml - packaging/opensc.spec - configure.ac From a28f4092004bc82f0ea6db2cc22064529b8d8b96 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 May 2023 14:31:32 +0200 Subject: [PATCH 2943/4321] ci: Do not cache valgrind build --- .github/workflows/linux.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5a7b54bc66..a8a31ce871 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -58,17 +58,6 @@ jobs: path: | tests/*.log src/tests/unittests/*.log - - uses: actions/cache@v3 - id: cache-build - with: - path: ./* - key: ${{ runner.os }}-${{ github.sha }} - - name: Upload build artifacts - uses: actions/upload-artifact@v3 - with: - name: opensc-build - path: - opensc*.tar.gz build-no-shared: runs-on: ubuntu-latest From 506d7f646f6dee02f08ff1a112062b7149421b19 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 31 May 2023 14:43:46 +0200 Subject: [PATCH 2944/4321] pkcs15init: Fix statement with no effect (CID 385152) Thanks coverity --- src/pkcs15init/pkcs15-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 7122e5da7b..c840df8cff 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1929,7 +1929,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile r = SC_ERROR_OUT_OF_MEMORY; LOG_TEST_GOTO_ERR(ctx, r, "Cannot allocate EC params"); } - key.u.ec.ecpointQ.len = key.u.ec.ecpointQ.len; + key.u.ec.ecpointQ.len = keyargs->key.u.ec.ecpointQ.len; memcpy(key.u.ec.ecpointQ.value, keyargs->key.u.ec.ecpointQ.value, key.u.ec.ecpointQ.len); } } From 6341c1984c043dbd68dd7d62b743c02f3534301b Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 26 Apr 2023 09:02:51 +0200 Subject: [PATCH 2945/4321] epass2003: SM checking (MAC and SW) This patch introduces basic verification of data coming from the token in the secure messaging mode: 1. compare raw SW and SW encoded in SM 2. verify MAC MAC verification is working only for DES and AES-CBC-MAC. Code for checking MAC in FIPS mode is still missing. modified: src/libopensc/card-epass2003.c --- src/libopensc/card-epass2003.c | 110 +++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 5d9109f4d2..f105c77fa1 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -1330,6 +1330,109 @@ epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_ap return SC_SUCCESS; } +static int +epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm) +{ + unsigned char iv[16]; + unsigned char *data = NULL, *mac = NULL; + size_t blocksize, mac_len; + int ret = -1; + size_t taglen; + const u8 *tag; + epass2003_exdata *exdata; + unsigned char *in = sm->resp; + unsigned char *alt_in; + size_t inlen = sm->resplen; + size_t len_correction; + + /* card/ctx/drv_data is already checked by caller */ + exdata = (epass2003_exdata *)card->drv_data; + + /* The SM must contain at least TLV encoded SW and MAC fields. */ + if (inlen < 14 ) + return ret; + + /* compare BER-TLV encoded SW (TAG 0x99) and raw SW */ + alt_in = in; + tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen); + if (tag == NULL || taglen != 2) { + /* + * It seems that the EPASS2003 firmware has some problem with BER-TLV encoding. + * Instead of (correct) TLV 87 81 81 [01 .. ..] incorrect TLV 87 81 [01 .. ..] + * is returned. There seems to be some proprietary fix for the faulty encoding + * in the decrypt_response() function, similar fix here: + */ + if (0x01 == in[2] && 0x82 != in[1]) { + sc_log(card->ctx, "Workaround, wrong BER-TLV ?"); + len_correction = in[1] + 2; + if (inlen < len_correction) + return ret; + inlen -= len_correction; + alt_in += len_correction; + tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen); + if (tag == NULL || taglen != 2) + return ret; + } else + return ret; + } + if (sm->sw1 != tag[0] || sm->sw2 != tag[1]) + return ret; + + /* no documentation/real hardware to test, the response is accepted without MAC check */ + if (exdata->bFipsCertification) { + sc_log(card->ctx, "Warning, MAC is not checked"); + return 0; + } + tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x8e, &taglen); + if (tag == NULL || taglen != 8) + return ret; + + if (KEY_TYPE_AES == exdata->smtype) + blocksize = 16; + else + blocksize = 8; + + mac_len = tag - in - 2; + if (NULL == (data = calloc(1, mac_len + blocksize))) + goto end; + if (NULL == (mac = malloc(mac_len + blocksize))) + goto end; + + /* copy response to buffer and append padding */ + memcpy(data, in, mac_len); + data[mac_len++] = 0x80; + + if (mac_len % blocksize) + mac_len += (blocksize - (mac_len % blocksize)); + + /* calculate MAC */ + memcpy(iv, exdata->icv_mac, blocksize); + + if (KEY_TYPE_AES == exdata->smtype) { + if (aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, mac_len, mac)) + goto end; + } else { + uint8_t tmp[8]; + uint8_t iv0[EVP_MAX_IV_LENGTH]; + if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv, data, mac_len, mac)) + goto end; + memset(iv0, 0, EVP_MAX_IV_LENGTH); + if (des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv0, &mac[mac_len - 8], 8, tmp)) + goto end; + memset(iv0, 0, EVP_MAX_IV_LENGTH); + if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv0, tmp, 8, &mac[mac_len - 8])) + goto end; + } + /* compare MAC */ + if (!memcmp(tag, mac + mac_len - blocksize, 8)) + ret = 0; +end: + if (data) + free(data); + if (mac) + free(mac); + return ret; +} /* According to GlobalPlatform Card Specification's SCP01 * decrypt APDU response from @@ -1414,6 +1517,13 @@ epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apd LOG_FUNC_CALLED(card->ctx); + /* verify MAC, and check if SW1,2 match SW1,2 encapsulated in SM */ + if (exdata->sm) { + if (epass2003_check_response_mac_and_sw(card, sm)) { + sc_log(card->ctx, "MAC or SW incorrect"); + return SC_ERROR_CARD_CMD_FAILED; + } + } r = sc_check_sw(card, sm->sw1, sm->sw2); if (r == SC_SUCCESS) { if (exdata->sm) { From 509e3922bd0eefd0e3f5f0174ba754da8d11bb68 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 18 Nov 2022 16:16:51 +0100 Subject: [PATCH 2946/4321] Add ATRs for IDPrime cards --- src/libopensc/card-idprime.c | 64 +++++++++++++++++++++++----------- src/libopensc/cards.h | 9 ++--- src/libopensc/pkcs15-idprime.c | 5 +-- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 2a8d42f8f1..c891a0652b 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -46,8 +46,28 @@ static struct sc_card_driver idprime_drv = { * are not useful here */ static const struct sc_atr_table idprime_atrs[] = { { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff", - "Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime 3810", + SC_CARD_TYPE_IDPRIME_3810, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime 830", + SC_CARD_TYPE_IDPRIME_830, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime 930/3930", + SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime 940", + SC_CARD_TYPE_IDPRIME_940, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime 840", + SC_CARD_TYPE_IDPRIME_840, 0, NULL }, + { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:00:ff:ff:ff", + "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards", SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -196,7 +216,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) && (memcmp(&start[12], "mscp", 5) == 0)) { new_object.fd++; - if (card->type == SC_CARD_TYPE_IDPRIME_V1) { + if (card->type == SC_CARD_TYPE_IDPRIME_3810) { /* The key reference is one bigger than the value found here for some reason */ new_object.key_reference = start[8] + 1; } else { @@ -205,13 +225,18 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, key_id = start[8] - '0'; } switch (card->type) { - case SC_CARD_TYPE_IDPRIME_V2: + case SC_CARD_TYPE_IDPRIME_830: + new_object.key_reference = 0x41 + key_id; + break; + case SC_CARD_TYPE_IDPRIME_930: new_object.key_reference = 0x11 + key_id; break; - case SC_CARD_TYPE_IDPRIME_V3: - new_object.key_reference = 0xF7 + key_id; + case SC_CARD_TYPE_IDPRIME_940: + new_object.key_reference = 0x60 + key_id; break; - case SC_CARD_TYPE_IDPRIME_V4: + case SC_CARD_TYPE_IDPRIME_840: + new_object.key_reference = 0xf7 + key_id; + break default: new_object.key_reference = 0x56 + key_id; break; @@ -251,24 +276,19 @@ static int idprime_init(sc_card_t *card) apdu.resplen = rbuflen; apdu.le = rbuflen; r = sc_transmit_apdu(card, &apdu); - card->type = SC_CARD_TYPE_IDPRIME_GENERIC; if (r == SC_SUCCESS && apdu.resplen == CPLC_LENGTH) { /* We are interested in the OS release level here */ switch (rbuf[11]) { case 0x01: - card->type = SC_CARD_TYPE_IDPRIME_V1; sc_log(card->ctx, "Detected IDPrime applet version 1"); break; case 0x02: - card->type = SC_CARD_TYPE_IDPRIME_V2; sc_log(card->ctx, "Detected IDPrime applet version 2"); break; case 0x03: - card->type = SC_CARD_TYPE_IDPRIME_V3; sc_log(card->ctx, "Detected IDPrime applet version 3"); break; case 0x04: - card->type = SC_CARD_TYPE_IDPRIME_V4; sc_log(card->ctx, "Detected IDPrime applet version 4"); break; default: @@ -303,17 +323,20 @@ static int idprime_init(sc_card_t *card) card->drv_data = priv; switch (card->type) { - case SC_CARD_TYPE_IDPRIME_V1: - card->name = "Gemalto IDPrime (OSv1)"; + case SC_CARD_TYPE_IDPRIME_3810: + card->name = "Gemalto IDPrime 3810"; + break; + case SC_CARD_TYPE_IDPRIME_830: + card->name = "Gemalto IDPrime MD 830"; break; - case SC_CARD_TYPE_IDPRIME_V2: - card->name = "Gemalto IDPrime (OSv2)"; + case SC_CARD_TYPE_IDPRIME_930: + card->name = "Gemalto IDPrime 930/3930"; break; - case SC_CARD_TYPE_IDPRIME_V3: - card->name = "Gemalto IDPrime (OSv3)"; + case SC_CARD_TYPE_IDPRIME_940: + card->name = "Gemalto IDPrime 940"; break; - case SC_CARD_TYPE_IDPRIME_V4: - card->name = "Gemalto IDPrime (OSv4)"; + case SC_CARD_TYPE_IDPRIME_840: + card->name = "Gemalto IDPrime 840"; break; case SC_CARD_TYPE_IDPRIME_GENERIC: default: @@ -333,6 +356,7 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); + _sc_card_add_rsa_alg(card, 4096, flags, 0); card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 50f6a9e4df..3a2350960d 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -262,10 +262,11 @@ enum { /* IDPrime cards */ SC_CARD_TYPE_IDPRIME_BASE = 37000, - SC_CARD_TYPE_IDPRIME_V1, - SC_CARD_TYPE_IDPRIME_V2, - SC_CARD_TYPE_IDPRIME_V3, - SC_CARD_TYPE_IDPRIME_V4, + SC_CARD_TYPE_IDPRIME_3810, + SC_CARD_TYPE_IDPRIME_830, + SC_CARD_TYPE_IDPRIME_930, + SC_CARD_TYPE_IDPRIME_940, + SC_CARD_TYPE_IDPRIME_840, SC_CARD_TYPE_IDPRIME_GENERIC, /* eDO cards */ diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 2d09b01a50..3246f16361 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -98,8 +98,9 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) pin_info.attrs.pin.max_length = 16; pin_info.tries_left = -1; - if (card->type == SC_CARD_TYPE_IDPRIME_V3 || - card->type == SC_CARD_TYPE_IDPRIME_V4) { + if (card->type == SC_CARD_TYPE_IDPRIME_840 + || card->type == SC_CARD_TYPE_IDPRIME_940 + || card->type == SC_CARD_TYPE_IDPRIME_GENERIC) { pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_NEEDS_PADDING; pin_info.attrs.pin.stored_length = 16; pin_info.attrs.pin.pad_char = 0x00; From d7e099db49921193c66a12d2fd7ae1f5e55d944f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 24 Nov 2022 10:40:30 +0100 Subject: [PATCH 2947/4321] Add RSA alg with 4096b only for idprime 930 and 940 --- src/libopensc/card-idprime.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index c891a0652b..c6a7c3e018 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -236,7 +236,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, break; case SC_CARD_TYPE_IDPRIME_840: new_object.key_reference = 0xf7 + key_id; - break + break; default: new_object.key_reference = 0x56 + key_id; break; @@ -345,7 +345,7 @@ static int idprime_init(sc_card_t *card) } card->cla = 0x00; - /* Set up algorithm info. */ + /* Set up algorithm info for RSA. */ flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_PAD_OAEP @@ -356,7 +356,10 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); - _sc_card_add_rsa_alg(card, 4096, flags, 0); + if (card->type == SC_CARD_TYPE_IDPRIME_930 + || card->type == SC_CARD_TYPE_IDPRIME_940) { + _sc_card_add_rsa_alg(card, 4096, flags, 0); + } card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; From 8d5c2c26577247fb1cfdf94c83c009ede9424a84 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 24 Nov 2022 10:52:10 +0100 Subject: [PATCH 2948/4321] Add EC objects to p15card --- src/libopensc/pkcs15-idprime.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 3246f16361..a31dc12016 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -249,12 +249,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_log(card->ctx, "cert %s: cert_usage=0x%x, pub_usage=0x%x priv_usage=0x%x\n", sc_dump_hex(cert_info.id.value, cert_info.id.len), usage, pubkey_info.usage, prkey_info.usage); - if (cert_out->key->algorithm != SC_ALGORITHM_RSA) { - sc_log(card->ctx, "unsupported key.algorithm %d", cert_out->key->algorithm); - sc_pkcs15_free_certificate(cert_out); - free(pubkey_info.direct.spki.value); - continue; - } else { + + if (cert_out->key->algorithm == SC_ALGORITHM_RSA) { pubkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; prkey_info.modulus_length = cert_out->key->u.rsa.modulus.len * 8; sc_log(card->ctx, "adding rsa public key r=%d usage=%x",r, pubkey_info.usage); @@ -269,6 +265,26 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) goto fail; + } else if (cert_out->key->algorithm == SC_ALGORITHM_EC) { + pubkey_info.field_length = cert_out->key->u.ec.params.field_length; + prkey_info.field_length = cert_out->key->u.ec.params.field_length; + sc_log(card->ctx, "adding ec public key r=%d usage=%x",r, pubkey_info.usage); + r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info); + if (r < 0) { + free(pubkey_info.direct.spki.value); + goto fail; + } + pubkey_info.direct.spki.value = NULL; + pubkey_info.direct.spki.len = 0; + sc_log(card->ctx, "adding ec private key r=%d usage=%x",r, prkey_info.usage); + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + if (r < 0) + goto fail; + } else { + sc_log(card->ctx, "unsupported key.algorithm %d", cert_out->key->algorithm); + sc_pkcs15_free_certificate(cert_out); + free(pubkey_info.direct.spki.value); + continue; } cert_out->key = NULL; From f70a302a418c0eaecac90330e1a9c2557e7e45db Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 24 Nov 2022 11:19:10 +0100 Subject: [PATCH 2949/4321] Add EC algorithm into idprime_init --- src/libopensc/card-idprime.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index c6a7c3e018..e766d2718f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -264,7 +264,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, static int idprime_init(sc_card_t *card) { int r; - unsigned long flags; + unsigned long flags, ext_flags; idprime_private_data_t *priv = NULL; struct sc_apdu apdu; u8 rbuf[CPLC_LENGTH]; @@ -361,6 +361,16 @@ static int idprime_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 4096, flags, 0); } + /* Set up algorithm info for EC */ + flags = SC_ALGORITHM_ECDSA_RAW + | SC_ALGORITHM_ECDH_CDH_RAW + | (SC_ALGORITHM_ECDSA_HASH_SHA256 | SC_ALGORITHM_ECDSA_HASH_SHA384 | SC_ALGORITHM_ECDSA_HASH_SHA512) + ; + ext_flags = 0; // TODO: fix flags + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL); + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; card->caps |= SC_CARD_CAP_RNG; From 23cf827e934824e70221079fbbbb89afcb0ae490 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 28 Nov 2022 17:10:21 +0100 Subject: [PATCH 2950/4321] Parsing of IDPrime index file `kxc` and `ksc` objects denote certificates. Certificate objects can be standalone - then we expect that they have public and private keys on the card, or there can be `priprk` and `pubksc` denoting corresponding private a public keys. --- src/libopensc/card-idprime.c | 143 ++++++++++++++++++++++++++------- src/libopensc/pkcs15-idprime.c | 16 +++- 2 files changed, 124 insertions(+), 35 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index e766d2718f..2b28a3877c 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -82,6 +82,7 @@ static const sc_path_t idprime_path = { typedef struct idprime_object { int fd; unsigned char key_reference; + int valid_key_ref; u8 df[2]; unsigned short length; } idprime_object_t; @@ -179,6 +180,9 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int r = SC_ERROR_OUT_OF_MEMORY; int i, num_entries; idprime_object_t new_object; + idprime_object_t cert_object; + int prkey_id = -1; + int cert_id = -1; buf = malloc(length); if (buf == NULL) { @@ -212,40 +216,102 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.length = bebytes2ushort(&start[2]); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "df=%s, len=%u", sc_dump_hex(new_object.df, sizeof(new_object.df)), new_object.length); + + if ((memcmp(&start[4], "priprk", 6) == 0)) { + if (cert_id != -1) { + /* No public key was found, add previous certificate */ + /* If pubkey is missing, there should be also no private key */ + if (prkey_id != -1) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); + } else { + /* Here we know, that no pubkey or prkey was found for certificate */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", + cert_object.fd, cert_object.key_reference); + idprime_add_object_to_list(&priv->pki_list, &cert_object); + } + prkey_id = -1; + cert_id = -1; + } + /* Found private key, certificate and public key should have same id */ + prkey_id = (start[10] - '0') * 10 + (start[11] - '0'); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found private key with id=%d", prkey_id); + continue; + } /* in minidriver, mscp/kxcNN or kscNN lists certificates */ - if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) + else if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) && (memcmp(&start[12], "mscp", 5) == 0)) { - new_object.fd++; - if (card->type == SC_CARD_TYPE_IDPRIME_3810) { - /* The key reference is one bigger than the value found here for some reason */ - new_object.key_reference = start[8] + 1; - } else { - int key_id = 0; - if (start[8] >= '0' && start[8] <= '9') { - key_id = start[8] - '0'; - } - switch (card->type) { - case SC_CARD_TYPE_IDPRIME_830: - new_object.key_reference = 0x41 + key_id; - break; - case SC_CARD_TYPE_IDPRIME_930: - new_object.key_reference = 0x11 + key_id; - break; - case SC_CARD_TYPE_IDPRIME_940: - new_object.key_reference = 0x60 + key_id; - break; - case SC_CARD_TYPE_IDPRIME_840: - new_object.key_reference = 0xf7 + key_id; - break; - default: - new_object.key_reference = 0x56 + key_id; - break; + + if (cert_id != -1) { + /* Previously found certificate but no corresponding public key object */ + /* If pubkey is missing, there should be also no private key */ + if (prkey_id != -1) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); + } else { + /* Here we know, that no pubkey or prkey was found for certificate */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", + cert_object.fd, cert_object.key_reference); + idprime_add_object_to_list(&priv->pki_list, &cert_object); } + prkey_id = -1; + cert_id = -1; + } + + /* Continue with processing current certificate */ + if (start[8] >= '0' && start[8] <= '9') { + cert_id = (start[7] - '0') * 10 + start[8] - '0'; } - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d", - new_object.fd, new_object.key_reference); - idprime_add_object_to_list(&priv->pki_list, &new_object); + new_object.fd++; + cert_object.valid_key_ref = 1; + switch (card->type) { + case SC_CARD_TYPE_IDPRIME_3810: + cert_object.key_reference = 0x31 + cert_id; + break; + case SC_CARD_TYPE_IDPRIME_830: + cert_object.key_reference = 0x41 + cert_id; + break; + case SC_CARD_TYPE_IDPRIME_930: + cert_object.key_reference = 0x11 + cert_id * 2; + break; + case SC_CARD_TYPE_IDPRIME_940: + cert_object.key_reference = 0x60 + cert_id; + break; + case SC_CARD_TYPE_IDPRIME_840: + cert_object.key_reference = 0xf7 + cert_id; + break; + default: + cert_object.key_reference = 0x56 + cert_id; + break; + } + cert_object.fd = new_object.fd; + cert_object.df[0] = new_object.df[0]; + cert_object.df[1] = new_object.df[1]; + cert_object.length = new_object.length; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d", + cert_object.fd, cert_object.key_reference); + } else if ((memcmp(&start[4], "pubksc", 6) == 0) || (memcmp(&start[4], "pubkxc", 6) == 0)) { + /* Found public key on card*/ + int pubkey_id = (start[10] - '0') * 10 + (start[11] - '0'); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found public key with id=%d", pubkey_id); + + /* There should be already found certificate */ + if (cert_id == -1) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Public key (id=%d) without certificate", pubkey_id); + prkey_id = -1; + continue; + } + /* Certificate is on the card, check for corresponding private key */ + if (prkey_id == -1 || cert_id != prkey_id || prkey_id != pubkey_id) { + /* Object is added, but missing private key */ + cert_object.key_reference = -1; + cert_object.valid_key_ref = 0; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate and public key without corresponding private key"); + } + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", + cert_object.fd, cert_object.key_reference); + idprime_add_object_to_list(&priv->pki_list, &cert_object); + prkey_id = -1; + cert_id = -1; /* This looks like non-standard extension listing pkcs11 token info label in my card */ } else if ((memcmp(&start[4], "tinfo", 6) == 0) && (memcmp(&start[12], "p11", 4) == 0)) { memcpy(priv->tinfo_df, new_object.df, sizeof(priv->tinfo_df)); @@ -253,6 +319,18 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found p11/tinfo object"); } } + + if (cert_id != -1) { + /* Found certificate but no corresponding public key object */ + if (prkey_id != -1) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); + } else { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", + cert_object.fd, cert_object.key_reference); + idprime_add_object_to_list(&priv->pki_list, &cert_object); + } + } + r = SC_SUCCESS; done: free(buf); @@ -336,7 +414,7 @@ static int idprime_init(sc_card_t *card) card->name = "Gemalto IDPrime 940"; break; case SC_CARD_TYPE_IDPRIME_840: - card->name = "Gemalto IDPrime 840"; + card->name = "Gemalto IDPrime MD 840"; break; case SC_CARD_TYPE_IDPRIME_GENERIC: default: @@ -439,7 +517,10 @@ static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pk prkey_info->id.value[0] = ((*entry)->fd >> 8) & 0xff; prkey_info->id.value[1] = (*entry)->fd & 0xff; prkey_info->id.len = 2; - prkey_info->key_reference = (*entry)->key_reference; + if ((*entry)->valid_key_ref) + prkey_info->key_reference = (*entry)->key_reference; + else + prkey_info->key_reference = -1; *entry = list_iterator_next(list); return SC_SUCCESS; } diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index a31dc12016..0124dd0ddd 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -261,8 +261,12 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) } pubkey_info.direct.spki.value = NULL; /* moved to the pubkey object on p15card */ pubkey_info.direct.spki.len = 0; - sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); - r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + if (prkey_info.key_reference >= 0) { + sc_log(card->ctx, "adding rsa private key r=%d usage=%x",r, prkey_info.usage); + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + } else { + sc_log(card->ctx, "missing rsa private key r=%d usage=%x",r, prkey_info.usage); + } if (r < 0) goto fail; } else if (cert_out->key->algorithm == SC_ALGORITHM_EC) { @@ -276,8 +280,12 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) } pubkey_info.direct.spki.value = NULL; pubkey_info.direct.spki.len = 0; - sc_log(card->ctx, "adding ec private key r=%d usage=%x",r, prkey_info.usage); - r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + if (prkey_info.key_reference >= 0) { + sc_log(card->ctx, "adding ec private key r=%d usage=%x",r, prkey_info.usage); + r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info); + } else { + sc_log(card->ctx, "missing ec private key r=%d usage=%x",r, prkey_info.usage); + } if (r < 0) goto fail; } else { From 969ca74001fded9fe2b7901032549e81c01e920d Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 8 Dec 2022 17:47:56 +0100 Subject: [PATCH 2951/4321] Add ECC --- src/libopensc/card-idprime.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 2b28a3877c..4c30fccfa6 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -232,6 +232,9 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, prkey_id = -1; cert_id = -1; } + free(buf); + return SC_SUCCESS; + /* Found private key, certificate and public key should have same id */ prkey_id = (start[10] - '0') * 10 + (start[11] - '0'); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found private key with id=%d", prkey_id); @@ -274,7 +277,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, cert_object.key_reference = 0x11 + cert_id * 2; break; case SC_CARD_TYPE_IDPRIME_940: - cert_object.key_reference = 0x60 + cert_id; + cert_object.key_reference = 0x62 + cert_id; break; case SC_CARD_TYPE_IDPRIME_840: cert_object.key_reference = 0xf7 + cert_id; @@ -440,14 +443,17 @@ static int idprime_init(sc_card_t *card) } /* Set up algorithm info for EC */ - flags = SC_ALGORITHM_ECDSA_RAW - | SC_ALGORITHM_ECDH_CDH_RAW - | (SC_ALGORITHM_ECDSA_HASH_SHA256 | SC_ALGORITHM_ECDSA_HASH_SHA384 | SC_ALGORITHM_ECDSA_HASH_SHA512) - ; - ext_flags = 0; // TODO: fix flags - _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); - _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); - _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL); + if (card->type == SC_CARD_TYPE_IDPRIME_940) { + flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE; + ext_flags = SC_ALGORITHM_EXT_EC_F_P + | SC_ALGORITHM_EXT_EC_ECPARAMETERS + | SC_ALGORITHM_EXT_EC_NAMEDCURVE + | SC_ALGORITHM_EXT_EC_UNCOMPRESES + ; + _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL); + _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL); + } card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; @@ -769,7 +775,7 @@ idprime_set_security_env(struct sc_card *card, } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) { new_env.algorithm_ref = 0x65; } - } else { /* RSA-PKCS */ + } else if (env->algorithm_flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_OAEP)) { if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) { new_env.algorithm_ref = 0x42; } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) { @@ -779,6 +785,8 @@ idprime_set_security_env(struct sc_card *card, } else { /* RSA-PKCS without hashing */ new_env.algorithm_ref = 0x02; } + } else if (env->algorithm == SC_ALGORITHM_EC) { + new_env.algorithm_ref = 0x44; } break; default: From a4b469f19ed497b12bf71059841bed92dd9e7835 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 9 Dec 2022 10:49:29 +0100 Subject: [PATCH 2952/4321] Fix double free in OAEP test --- src/tests/p11test/p11test_case_pss_oaep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c index 1eb0bb431a..3d54aaeffd 100644 --- a/src/tests/p11test/p11test_case_pss_oaep.c +++ b/src/tests/p11test/p11test_case_pss_oaep.c @@ -534,6 +534,7 @@ int pss_sign_message(test_cert_t *o, token_info_t *info, CK_BYTE *message, if (rv != CKR_OK) { free(*sign); + *sign = NULL; fprintf(stderr, " C_Sign: rv = 0x%.8lX\n", rv); return -1; } From 570d66d6d8ea807cd5718eb1b348c41e8ca52868 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 14 Dec 2022 11:14:03 +0100 Subject: [PATCH 2953/4321] Remove testing code --- src/libopensc/card-idprime.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 4c30fccfa6..5616119c38 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -232,8 +232,6 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, prkey_id = -1; cert_id = -1; } - free(buf); - return SC_SUCCESS; /* Found private key, certificate and public key should have same id */ prkey_id = (start[10] - '0') * 10 + (start[11] - '0'); @@ -277,7 +275,8 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, cert_object.key_reference = 0x11 + cert_id * 2; break; case SC_CARD_TYPE_IDPRIME_940: - cert_object.key_reference = 0x62 + cert_id; + /* offset should be 0x62 for other 940 card */ + cert_object.key_reference = 0x60 + cert_id; break; case SC_CARD_TYPE_IDPRIME_840: cert_object.key_reference = 0xf7 + cert_id; From c1828520d0c1e234eb848e3a5c9f46e8ed49553a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 14 Dec 2022 17:51:14 +0100 Subject: [PATCH 2954/4321] Pad messages with various length before signing with ECDSA --- src/libopensc/card-idprime.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 5616119c38..e8ba8df783 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -99,6 +99,7 @@ typedef struct idprime_private_data { idprime_object_t *pki_current; /* current pki object _ctl function */ int tinfo_present; /* Token Info Label object is present*/ u8 tinfo_df[2]; /* DF of object with Token Info Label */ + unsigned long current_op; /* current operation set by idprime_set_security_env */ } idprime_private_data_t; /* For SimCList autocopy, we need to know the size of the data elements */ @@ -275,7 +276,6 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, cert_object.key_reference = 0x11 + cert_id * 2; break; case SC_CARD_TYPE_IDPRIME_940: - /* offset should be 0x62 for other 940 card */ cert_object.key_reference = 0x60 + cert_id; break; case SC_CARD_TYPE_IDPRIME_840: @@ -738,6 +738,7 @@ idprime_set_security_env(struct sc_card *card, { int r; struct sc_security_env new_env; + idprime_private_data_t *priv = card->drv_data; if (card == NULL || env == NULL) { return SC_ERROR_INVALID_ARGUMENTS; @@ -774,6 +775,7 @@ idprime_set_security_env(struct sc_card *card, } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) { new_env.algorithm_ref = 0x65; } + priv->current_op = SC_ALGORITHM_RSA; } else if (env->algorithm_flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_OAEP)) { if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) { new_env.algorithm_ref = 0x42; @@ -784,8 +786,10 @@ idprime_set_security_env(struct sc_card *card, } else { /* RSA-PKCS without hashing */ new_env.algorithm_ref = 0x02; } + priv->current_op = SC_ALGORITHM_RSA; } else if (env->algorithm == SC_ALGORITHM_EC) { new_env.algorithm_ref = 0x44; + priv->current_op = SC_ALGORITHM_EC; } break; default: @@ -805,9 +809,10 @@ idprime_compute_signature(struct sc_card *card, int r; struct sc_apdu apdu; u8 *p; - u8 sbuf[128]; /* For SHA-512 we need 64 + 2 bytes */ + u8 sbuf[128] = {0}; /* For SHA-512 we need 64 + 2 bytes */ u8 rbuf[4096]; /* needs work. for 3072 keys, needs 384+2 or so */ size_t rbuflen = sizeof(rbuf); + idprime_private_data_t *priv = card->drv_data; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -816,10 +821,17 @@ idprime_compute_signature(struct sc_card *card, LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } + /* The data for ECDSA should be padded to the length of a multiple of 8 */ + size_t pad = 0; + if (priv->current_op == SC_ALGORITHM_EC && datalen % 8 != 0) { + pad = 8 - (datalen % 8); + datalen += pad; + } + p = sbuf; *(p++) = 0x90; *(p++) = datalen; - memcpy(p, data, datalen); + memcpy(p + pad, data, datalen - pad); p += datalen; /* INS: 0x2A PERFORM SECURITY OPERATION @@ -838,7 +850,7 @@ idprime_compute_signature(struct sc_card *card, LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* This just returns the passed data (hash code) (for verification?) */ - if (apdu.resplen != datalen || memcmp(rbuf, data, datalen) != 0) { + if (apdu.resplen != datalen || memcmp(rbuf + pad, data, datalen - pad) != 0) { sc_log(card->ctx, "The initial APDU did not return the same data"); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } From 5a394b7b5d3db251d21638b34b9d5dbae8771019 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 12 Jan 2023 14:49:36 +0100 Subject: [PATCH 2955/4321] Fix ATR mask to take country code as two bytes --- src/libopensc/card-idprime.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index e8ba8df783..1b334c7dbf 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -46,27 +46,27 @@ static struct sc_card_driver idprime_drv = { * are not useful here */ static const struct sc_atr_table idprime_atrs[] = { { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 3810", SC_CARD_TYPE_IDPRIME_3810, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 830", SC_CARD_TYPE_IDPRIME_830, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 930/3930", SC_CARD_TYPE_IDPRIME_930, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940", SC_CARD_TYPE_IDPRIME_940, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 840", SC_CARD_TYPE_IDPRIME_840, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00", - "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:00:ff:ff:ff", + "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards", SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } From 0e9a74fa01dc473723e3adbbba5da7a180ee634e Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 23 Jan 2023 11:20:02 +0100 Subject: [PATCH 2956/4321] Use container map to identify certificates without private keys Cmap file contains records denoting container name and the record index corresponds to the index of certificate. --- src/libopensc/card-idprime.c | 307 +++++++++++++++++++++++------------ 1 file changed, 203 insertions(+), 104 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 1b334c7dbf..22d1b01e50 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -87,19 +87,32 @@ typedef struct idprime_object { unsigned short length; } idprime_object_t; +/* + * IDPrime Container structure + * Simplification of auxiliary data from aux-data.c + */ +#define MAX_CONTAINER_NAME_LEN 39 +#define CONTAINER_OBJ_LEN 86 +typedef struct idprime_container { + int index; /* Index of the container */ + char guid[MAX_CONTAINER_NAME_LEN + 1]; /* Container name */ + struct idprime_container *next; +} idprime_container_t; + /* * IDPrime private data per card state */ typedef struct idprime_private_data { - u8 *cache_buf; /* cached version of the currently selected file */ - size_t cache_buf_len; /* length of the cached selected file */ - int cached; /* is the cached selected file valid */ - size_t file_size; /* this is real file size since IDPrime is quite strict about lengths */ - list_t pki_list; /* list of pki containers */ - idprime_object_t *pki_current; /* current pki object _ctl function */ - int tinfo_present; /* Token Info Label object is present*/ - u8 tinfo_df[2]; /* DF of object with Token Info Label */ - unsigned long current_op; /* current operation set by idprime_set_security_env */ + u8 *cache_buf; /* cached version of the currently selected file */ + size_t cache_buf_len; /* length of the cached selected file */ + int cached; /* is the cached selected file valid */ + size_t file_size; /* this is real file size since IDPrime is quite strict about lengths */ + list_t pki_list; /* list of pki containers */ + idprime_object_t *pki_current; /* current pki object _ctl function */ + int tinfo_present; /* Token Info Label object is present*/ + u8 tinfo_df[2]; /* DF of object with Token Info Label */ + unsigned long current_op; /* current operation set by idprime_set_security_env */ + idprime_container_t *containers; /* list of private key containers */ } idprime_private_data_t; /* For SimCList autocopy, we need to know the size of the data elements */ @@ -107,10 +120,21 @@ static size_t idprime_list_meter(const void *el) { return sizeof(idprime_object_t); } +static void idprime_free_containermap(idprime_container_t *containers) +{ + idprime_container_t *next = NULL; + while (containers) { + next = containers->next; + free(containers); + containers = next; + } +} + void idprime_free_private_data(idprime_private_data_t *priv) { free(priv->cache_buf); list_destroy(&priv->pki_list); + idprime_free_containermap(priv->containers); free(priv); return; } @@ -147,6 +171,121 @@ static int idprime_select_idprime(sc_card_t *card) return iso_ops->select_file(card, &idprime_path, NULL); } +/* This select container map file, which is useful for certificate indexes on the card */ +static int idprime_select_containermap(sc_card_t *card) +{ + int r; + sc_file_t *file = NULL; + sc_path_t index_path; + + /* First, we need to make sure the IDPrime AID is selected */ + r = idprime_select_idprime(card); + if (r != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, r); + } + + /* Returns FCI with expected length of data */ + sc_format_path("0204", &index_path); + r = iso_ops->select_file(card, &index_path, &file); + if (r == SC_SUCCESS) { + r = file->size; + } + sc_file_free(file); + /* Ignore too large files */ + if (r <= 0 || r > MAX_FILE_SIZE) { + r = SC_ERROR_INVALID_DATA; + } + return r; +} + +static int idprime_process_containermap(sc_card_t *card, idprime_container_t **containers, int length) +{ + u8 *buf = NULL; + int r = SC_ERROR_OUT_OF_MEMORY; + int i, max_entries; + idprime_container_t *current = NULL; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (!containers) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + buf = malloc(length); + if (buf == NULL) { + goto done; + } + + r = 0; + do { + if (length == r) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + const int got = iso_ops->read_binary(card, r, buf + r, CONTAINER_OBJ_LEN, 0); + if (got < 1) { + r = SC_ERROR_WRONG_LENGTH; + goto done; + } + + r += got; + /* Try to read chunks of container size and stop when container looks empty */ + } while(length - r > 0 && buf[(r / CONTAINER_OBJ_LEN - 1) * CONTAINER_OBJ_LEN] != 0); + max_entries = r / CONTAINER_OBJ_LEN; + + for (i = 0; i < max_entries; i++) { + u8 *start = &buf[i * CONTAINER_OBJ_LEN]; + if (start[0] == 0) /* Empty record */ + goto end; + + idprime_container_t *new_container = calloc(1, sizeof(idprime_container_t)); + if (!new_container) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + new_container->index = i; + + /* Reading UNICODE characters but skipping second byte */ + int j = 0; + for (j = 0; j < MAX_CONTAINER_NAME_LEN + 1; j++) { + if (start[2 * j] == 0) + break; + new_container->guid[j] = start[2 * j]; + } + + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container->index, new_container->guid); + + /* Chain containers */ + if (!current) { + *containers = new_container; + } else { + current->next = new_container; + } + current = new_container; + } + +end: + r = SC_SUCCESS; +done: + free(buf); + LOG_FUNC_RETURN(card->ctx, r); +} + +static idprime_container_t *idprime_search_container(int index, idprime_container_t *containers) +{ + idprime_container_t *current = containers; + if (index < 0 || !containers) { + return NULL; + } + while(current) { + if (current->index == index) { + return current; + } + current = current->next; + } + return NULL; +} + /* This select some index file, which is useful for enumerating other files * on the card */ static int idprime_select_index(sc_card_t *card) @@ -181,9 +320,12 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int r = SC_ERROR_OUT_OF_MEMORY; int i, num_entries; idprime_object_t new_object; - idprime_object_t cert_object; - int prkey_id = -1; - int cert_id = -1; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (!priv->containers) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } buf = malloc(length); if (buf == NULL) { @@ -217,103 +359,53 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.length = bebytes2ushort(&start[2]); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "df=%s, len=%u", sc_dump_hex(new_object.df, sizeof(new_object.df)), new_object.length); - - if ((memcmp(&start[4], "priprk", 6) == 0)) { - if (cert_id != -1) { - /* No public key was found, add previous certificate */ - /* If pubkey is missing, there should be also no private key */ - if (prkey_id != -1) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); - } else { - /* Here we know, that no pubkey or prkey was found for certificate */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", - cert_object.fd, cert_object.key_reference); - idprime_add_object_to_list(&priv->pki_list, &cert_object); - } - prkey_id = -1; - cert_id = -1; - } - - /* Found private key, certificate and public key should have same id */ - prkey_id = (start[10] - '0') * 10 + (start[11] - '0'); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found private key with id=%d", prkey_id); - continue; - } /* in minidriver, mscp/kxcNN or kscNN lists certificates */ - else if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) + if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) && (memcmp(&start[12], "mscp", 5) == 0)) { + int cert_id = 0; + idprime_container_t *container = NULL; - if (cert_id != -1) { - /* Previously found certificate but no corresponding public key object */ - /* If pubkey is missing, there should be also no private key */ - if (prkey_id != -1) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); - } else { - /* Here we know, that no pubkey or prkey was found for certificate */ - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", - cert_object.fd, cert_object.key_reference); - idprime_add_object_to_list(&priv->pki_list, &cert_object); - } - prkey_id = -1; - cert_id = -1; - } - - /* Continue with processing current certificate */ if (start[8] >= '0' && start[8] <= '9') { cert_id = (start[7] - '0') * 10 + start[8] - '0'; } - new_object.fd++; - cert_object.valid_key_ref = 1; + new_object.key_reference = -1; + new_object.valid_key_ref = 0; + + container = idprime_search_container(cert_id, priv->containers); + if (!container) { + /* Object is added, but missing private key */ + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding container with private key found for certificate with id=%d", cert_id); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd); + idprime_add_object_to_list(&priv->pki_list, &new_object); + continue; + } + switch (card->type) { case SC_CARD_TYPE_IDPRIME_3810: - cert_object.key_reference = 0x31 + cert_id; + new_object.key_reference = 0x31 + cert_id; break; case SC_CARD_TYPE_IDPRIME_830: - cert_object.key_reference = 0x41 + cert_id; + new_object.key_reference = 0x41 + cert_id; break; case SC_CARD_TYPE_IDPRIME_930: - cert_object.key_reference = 0x11 + cert_id * 2; + new_object.key_reference = 0x11 + cert_id * 2; break; case SC_CARD_TYPE_IDPRIME_940: - cert_object.key_reference = 0x60 + cert_id; + new_object.key_reference = 0x60 + cert_id; break; case SC_CARD_TYPE_IDPRIME_840: - cert_object.key_reference = 0xf7 + cert_id; + new_object.key_reference = 0xf7 + cert_id; break; default: - cert_object.key_reference = 0x56 + cert_id; + new_object.key_reference = 0x56 + cert_id; break; } - cert_object.fd = new_object.fd; - cert_object.df[0] = new_object.df[0]; - cert_object.df[1] = new_object.df[1]; - cert_object.length = new_object.length; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d", - cert_object.fd, cert_object.key_reference); - } else if ((memcmp(&start[4], "pubksc", 6) == 0) || (memcmp(&start[4], "pubkxc", 6) == 0)) { - /* Found public key on card*/ - int pubkey_id = (start[10] - '0') * 10 + (start[11] - '0'); - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found public key with id=%d", pubkey_id); - - /* There should be already found certificate */ - if (cert_id == -1) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Public key (id=%d) without certificate", pubkey_id); - prkey_id = -1; - continue; - } - /* Certificate is on the card, check for corresponding private key */ - if (prkey_id == -1 || cert_id != prkey_id || prkey_id != pubkey_id) { - /* Object is added, but missing private key */ - cert_object.key_reference = -1; - cert_object.valid_key_ref = 0; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate and public key without corresponding private key"); - } - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", - cert_object.fd, cert_object.key_reference); - idprime_add_object_to_list(&priv->pki_list, &cert_object); - prkey_id = -1; - cert_id = -1; + new_object.valid_key_ref = 1; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d corresponding to container \"%s\"", + new_object.fd, new_object.key_reference, container->guid); + idprime_add_object_to_list(&priv->pki_list, &new_object); + /* This looks like non-standard extension listing pkcs11 token info label in my card */ } else if ((memcmp(&start[4], "tinfo", 6) == 0) && (memcmp(&start[12], "p11", 4) == 0)) { memcpy(priv->tinfo_df, new_object.df, sizeof(priv->tinfo_df)); @@ -322,17 +414,6 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, } } - if (cert_id != -1) { - /* Found certificate but no corresponding public key object */ - if (prkey_id != -1) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate id=%d missing public key object", cert_id); - } else { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d, key_ref=%d", - cert_object.fd, cert_object.key_reference); - idprime_add_object_to_list(&priv->pki_list, &cert_object); - } - } - r = SC_SUCCESS; done: free(buf); @@ -350,6 +431,8 @@ static int idprime_init(sc_card_t *card) u8 rbuf[CPLC_LENGTH]; size_t rbuflen = sizeof(rbuf); + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* We need to differentiate the OS version since they behave slightly differently */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xCA, 0x9F, 0x7F); apdu.resp = rbuf; @@ -381,19 +464,35 @@ static int idprime_init(sc_card_t *card) r, apdu.resplen); } - /* Now, select and process the index file */ - r = idprime_select_index(card); + priv = idprime_new_private_data(); + if (!priv) { + return SC_ERROR_OUT_OF_MEMORY; + } + + /* Select and process container file */ + r = idprime_select_containermap(card); if (r <= 0) { + idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found"); - priv = idprime_new_private_data(); - if (!priv) { - return SC_ERROR_OUT_OF_MEMORY; + r = idprime_process_containermap(card, &priv->containers, r); + if (r != SC_SUCCESS) { + idprime_free_private_data(priv); + LOG_FUNC_RETURN(card->ctx, r); } + /* Select and process the index file */ + r = idprime_select_index(card); + if (r <= 0) { + idprime_free_private_data(priv); + LOG_FUNC_RETURN(card->ctx, r); + } + + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found"); + r = idprime_process_index(card, priv, r); if (r != SC_SUCCESS) { idprime_free_private_data(priv); From e2c6313af0e43e64483ce39ae58b8dc43ac4b5b3 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 25 Jan 2023 15:45:35 +0100 Subject: [PATCH 2957/4321] Add digital signature PIN for IDPrime 940 cards IDPrime 940 uses digital signature pin for accessing CC certificates --- src/libopensc/pkcs15-idprime.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 0124dd0ddd..201e0bb409 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -113,6 +113,36 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add pin object"); + /* set signature pin for 940 cards */ + if (card->type == SC_CARD_TYPE_IDPRIME_940) { + const char sig_pin_label[] = "Digital Signature PIN"; + const char *sig_pin_id = "83"; + sc_log(card->ctx, "IDPrime adding Digital Signature pin..."); + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; + sc_pkcs15_format_id(sig_pin_id, &pin_info.auth_id); + pin_info.attrs.pin.reference = 0x83; + pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_INITIALIZED; + pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.attrs.pin.min_length = 4; + pin_info.attrs.pin.stored_length = 0; + pin_info.attrs.pin.max_length = 16; + pin_info.tries_left = -1; + + pin_info.attrs.pin.flags |= SC_PKCS15_PIN_FLAG_NEEDS_PADDING; + pin_info.attrs.pin.stored_length = 16; + pin_info.attrs.pin.pad_char = 0x00; + + sc_log(card->ctx, "IDPrime Adding Digital Signature pin with label=%s", sig_pin_label); + strncpy(pin_obj.label, pin_label, SC_PKCS15_MAX_LABEL_SIZE - 1); + pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add Digital Signature pin object"); + } + /* * get token name if provided */ @@ -172,6 +202,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) snprintf(pubkey_obj.label, SC_PKCS15_MAX_LABEL_SIZE, PUBKEY_LABEL_TEMPLATE, i+1); snprintf(prkey_obj.label, SC_PKCS15_MAX_LABEL_SIZE, PRIVKEY_LABEL_TEMPLATE, i+1); prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + /* Diferentiate somehow between objects accesible with normal and with digital signature pin */ sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, 0); From 01acd4d836c81c751d4c5c772b236b1852b005d7 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 30 Jan 2023 09:44:28 +0100 Subject: [PATCH 2958/4321] Read key reference map on IDPrime 940 File 0x0005 on IDPrime 940 contains 8 bytes records, which probably denote key reference and PIN index associated with certificate index. --- src/libopensc/card-idprime.c | 157 ++++++++++++++++++++++++++++++++- src/libopensc/pkcs15-idprime.c | 5 +- 2 files changed, 156 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 22d1b01e50..4a337e60c1 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -85,6 +85,7 @@ typedef struct idprime_object { int valid_key_ref; u8 df[2]; unsigned short length; + int pin_index; } idprime_object_t; /* @@ -99,6 +100,17 @@ typedef struct idprime_container { struct idprime_container *next; } idprime_container_t; +/* + * IDPrime key reference structure + */ +#define KEYREF_OBJ_LEN 8 +typedef struct idprime_keyref { + int index; /* Index of the key reference */ + int pin_index; /* Index of the auth pin used for accessing key */ + unsigned char key_reference; /* Key reference used for accessing key */ + struct idprime_keyref *next; +} idprime_keyref_t; + /* * IDPrime private data per card state */ @@ -113,6 +125,7 @@ typedef struct idprime_private_data { u8 tinfo_df[2]; /* DF of object with Token Info Label */ unsigned long current_op; /* current operation set by idprime_set_security_env */ idprime_container_t *containers; /* list of private key containers */ + idprime_keyref_t *keyrefmap; /* list of key references for private keys */ } idprime_private_data_t; /* For SimCList autocopy, we need to know the size of the data elements */ @@ -130,11 +143,23 @@ static void idprime_free_containermap(idprime_container_t *containers) } } + +static void idprime_free_keyref(idprime_keyref_t *keyrefmap) +{ + idprime_keyref_t *next = NULL; + while (keyrefmap) { + next = keyrefmap->next; + free(keyrefmap); + keyrefmap = next; + } +} + void idprime_free_private_data(idprime_private_data_t *priv) { free(priv->cache_buf); list_destroy(&priv->pki_list); idprime_free_containermap(priv->containers); + idprime_free_keyref(priv->keyrefmap); free(priv); return; } @@ -286,6 +311,107 @@ static idprime_container_t *idprime_search_container(int index, idprime_containe return NULL; } +static int idprime_select_keyrefmap(sc_card_t *card) +{ + int r; + sc_file_t *file = NULL; + sc_path_t index_path; + + /* First, we need to make sure the IDPrime AID is selected */ + r = idprime_select_idprime(card); + if (r != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, r); + } + + /* Returns FCI with expected length of data */ + sc_format_path("0005", &index_path); + r = iso_ops->select_file(card, &index_path, &file); + if (r == SC_SUCCESS) { + r = file->size; + } + sc_file_free(file); + /* Ignore too large files */ + if (r <= 0 || r > MAX_FILE_SIZE) { + r = SC_ERROR_INVALID_DATA; + } + return r; +} + +static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefmap, int length) +{ + u8 *buf = NULL; + int r = SC_ERROR_OUT_OF_MEMORY; + int i, max_entries; + idprime_keyref_t *current = NULL; + + if (!keyrefmap) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + buf = malloc(length); + if (buf == NULL) { + goto done; + } + + r = 0; + do { + if (length == r) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0); + if (got < 1) { + r = SC_ERROR_WRONG_LENGTH; + goto done; + } + + r += got; + } while(length - r > 0); + max_entries = r / KEYREF_OBJ_LEN; + + for (i = 0; i < max_entries; i++) { + u8 *start = &buf[i * KEYREF_OBJ_LEN]; + if (start[0] == 0) /* Empty key ref */ + continue; + + idprime_keyref_t *new_keyref = calloc(1, sizeof(idprime_keyref_t)); + if (!new_keyref) { + r = SC_ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + new_keyref->index = start[2]; + new_keyref->key_reference = start[1]; + new_keyref->pin_index = start[0]; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref->index, new_keyref->pin_index, new_keyref->key_reference); + + if (!current) { + *keyrefmap = new_keyref; + } else { + current->next = new_keyref; + } + current = new_keyref; + } + r = SC_SUCCESS; +done: + free(buf); + LOG_FUNC_RETURN(card->ctx, r); +} + +static idprime_keyref_t *idprime_get_keyreference(int index, idprime_keyref_t *keyrefmap) +{ + idprime_keyref_t *current = keyrefmap; + if (index < 0 || !keyrefmap) { + return NULL; + } + while(current) { + if (current->index == index) { + return current; + } + current = current->next; + } + return NULL; +} + /* This select some index file, which is useful for enumerating other files * on the card */ static int idprime_select_index(sc_card_t *card) @@ -323,7 +449,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (!priv->containers) { + if (!priv->containers || (card->type == SC_CARD_TYPE_IDPRIME_940 && !priv->keyrefmap)) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -371,6 +497,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.fd++; new_object.key_reference = -1; new_object.valid_key_ref = 0; + new_object.pin_index = 1; container = idprime_search_container(cert_id, priv->containers); if (!container) { @@ -391,9 +518,16 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, case SC_CARD_TYPE_IDPRIME_930: new_object.key_reference = 0x11 + cert_id * 2; break; - case SC_CARD_TYPE_IDPRIME_940: - new_object.key_reference = 0x60 + cert_id; - break; + case SC_CARD_TYPE_IDPRIME_940: { + idprime_keyref_t *keyref = idprime_get_keyreference(cert_id, priv->keyrefmap); + if (!keyref) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d, skipping", cert_id); + continue; + } + new_object.key_reference = keyref->key_reference; + new_object.pin_index = keyref->pin_index; + break; + } case SC_CARD_TYPE_IDPRIME_840: new_object.key_reference = 0xf7 + cert_id; break; @@ -484,6 +618,18 @@ static int idprime_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } + if (card->type == SC_CARD_TYPE_IDPRIME_940) { + if ((r = idprime_select_keyrefmap(card)) <= 0) { + idprime_free_private_data(priv); + LOG_FUNC_RETURN(card->ctx, r); + } + + if ((r = idprime_process_keyrefmap(card, &priv->keyrefmap, r)) != SC_SUCCESS) { + idprime_free_private_data(priv); + LOG_FUNC_RETURN(card->ctx, r); + } + } + /* Select and process the index file */ r = idprime_select_index(card); if (r <= 0) { @@ -621,6 +767,9 @@ static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pk prkey_info->id.value[0] = ((*entry)->fd >> 8) & 0xff; prkey_info->id.value[1] = (*entry)->fd & 0xff; prkey_info->id.len = 2; + prkey_info->pin_id = "11"; + if ((*entry)->pin_index != 1) + prkey_info->pin_id = "83"; if ((*entry)->valid_key_ref) prkey_info->key_reference = (*entry)->key_reference; else diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 201e0bb409..403a303678 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -203,8 +203,9 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) snprintf(prkey_obj.label, SC_PKCS15_MAX_LABEL_SIZE, PRIVKEY_LABEL_TEMPLATE, i+1); prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; - /* Diferentiate somehow between objects accesible with normal and with digital signature pin */ - sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); + /* Differentiate between objects accessible with normal and with digital signature pin */ + sc_pkcs15_format_id(prkey_info.pin_id, &prkey_obj.auth_id); + sc_log(card->ctx, "Pin ID r=%s", prkey_info.pin_id); r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, 0); From 50711a5154a807293dc0a106b4baf1b403442da8 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Wed, 1 Feb 2023 16:01:32 +0100 Subject: [PATCH 2959/4321] Add ctl for getting PIN id --- src/libopensc/card-idprime.c | 18 +++++++++++++++--- src/libopensc/cardctl.h | 1 + src/libopensc/pkcs15-idprime.c | 14 ++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 4a337e60c1..d30cd0803a 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -767,9 +767,6 @@ static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pk prkey_info->id.value[0] = ((*entry)->fd >> 8) & 0xff; prkey_info->id.value[1] = (*entry)->fd & 0xff; prkey_info->id.len = 2; - prkey_info->pin_id = "11"; - if ((*entry)->pin_index != 1) - prkey_info->pin_id = "83"; if ((*entry)->valid_key_ref) prkey_info->key_reference = (*entry)->key_reference; else @@ -778,6 +775,18 @@ static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pk return SC_SUCCESS; } +/* get PIN id of the current object on the list */ +static int idprime_get_pin_id(list_t *list, idprime_object_t **entry, char **pin_id) +{ + if (pin_id == NULL || entry == NULL) { + return SC_ERROR_INVALID_ARGUMENTS; + } + *pin_id = "11"; // normal PIN id + if ((*entry)->pin_index != 1) + *pin_id = "83"; // signature PIN id + return SC_SUCCESS; +} + #define IDPRIME_CARDID_LEN 16 static int idprime_get_serial(sc_card_t* card, sc_serial_number_t* serial) @@ -886,6 +895,9 @@ static int idprime_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) (sc_pkcs15_prkey_info_t *)ptr); case SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS: return idprime_final_iterator(&priv->pki_list); + case SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID: + return idprime_get_pin_id(&priv->pki_list, &priv->pki_current, + (char **)ptr); } LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 4dc586f635..17d08b987f 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -305,6 +305,7 @@ enum { SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, SC_CARDCTL_IDPRIME_GET_TOKEN_NAME, + SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID, }; diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 403a303678..99ffe382ad 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -60,6 +60,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object pin_obj; const char pin_label[] = "PIN"; const char *pin_id = "11"; + const char sig_pin_label[] = "Digital Signature PIN"; + const char *sig_pin_id = "83"; /* oid for key usage */ static const struct sc_object_id usage_type = {{ 2, 5, 29, 15, -1 }}; @@ -115,8 +117,6 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) /* set signature pin for 940 cards */ if (card->type == SC_CARD_TYPE_IDPRIME_940) { - const char sig_pin_label[] = "Digital Signature PIN"; - const char *sig_pin_id = "83"; sc_log(card->ctx, "IDPrime adding Digital Signature pin..."); memset(&pin_info, 0, sizeof(pin_info)); memset(&pin_obj, 0, sizeof(pin_obj)); @@ -174,7 +174,10 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object prkey_obj; sc_pkcs15_der_t cert_der; sc_pkcs15_cert_t *cert_out = NULL; + char *pin_id = NULL; + r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID, &pin_id); + LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get PIN id of next object "); r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, &prkey_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object"); @@ -204,8 +207,11 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; /* Differentiate between objects accessible with normal and with digital signature pin */ - sc_pkcs15_format_id(prkey_info.pin_id, &prkey_obj.auth_id); - sc_log(card->ctx, "Pin ID r=%s", prkey_info.pin_id); + sc_pkcs15_format_id(pin_id, &prkey_obj.auth_id); + sc_log(card->ctx, "Pin ID r=%s", pin_id); + + if (memcmp(pin_id, sig_pin_id, 2) == 0) + prkey_obj.user_consent = 1; r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, 0); From 42d30ecee796352284f64c8d004270bccdadd9e5 Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 09:50:45 +0100 Subject: [PATCH 2960/4321] Check two-digit certificate index --- src/libopensc/card-idprime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index d30cd0803a..91c7107b1a 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -491,7 +491,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int cert_id = 0; idprime_container_t *container = NULL; - if (start[8] >= '0' && start[8] <= '9') { + if (start[7] >= '0' && start[7] <= '9' && start[8] >= '0' && start[8] <= '9') { cert_id = (start[7] - '0') * 10 + start[8] - '0'; } new_object.fd++; From 848eafe7cd7831e6d56835e3aedd693d06efe94a Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 10 Feb 2023 10:37:38 +0100 Subject: [PATCH 2961/4321] Add generic function for selecting file by string path --- src/libopensc/card-idprime.c | 80 +++++++----------------------------- 1 file changed, 14 insertions(+), 66 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 91c7107b1a..0bde61fd0d 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -196,8 +196,8 @@ static int idprime_select_idprime(sc_card_t *card) return iso_ops->select_file(card, &idprime_path, NULL); } -/* This select container map file, which is useful for certificate indexes on the card */ -static int idprime_select_containermap(sc_card_t *card) +/* Select file by string path */ +static int idprime_select_file_by_path(sc_card_t *card, const char *str_path) { int r; sc_file_t *file = NULL; @@ -210,17 +210,19 @@ static int idprime_select_containermap(sc_card_t *card) } /* Returns FCI with expected length of data */ - sc_format_path("0204", &index_path); + sc_format_path(str_path, &index_path); r = iso_ops->select_file(card, &index_path, &file); - if (r == SC_SUCCESS) { - r = file->size; + + if (r != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, r); } + r = file->size; sc_file_free(file); /* Ignore too large files */ - if (r <= 0 || r > MAX_FILE_SIZE) { + if (r > MAX_FILE_SIZE) { r = SC_ERROR_INVALID_DATA; } - return r; + LOG_FUNC_RETURN(card->ctx, r); } static int idprime_process_containermap(sc_card_t *card, idprime_container_t **containers, int length) @@ -311,32 +313,6 @@ static idprime_container_t *idprime_search_container(int index, idprime_containe return NULL; } -static int idprime_select_keyrefmap(sc_card_t *card) -{ - int r; - sc_file_t *file = NULL; - sc_path_t index_path; - - /* First, we need to make sure the IDPrime AID is selected */ - r = idprime_select_idprime(card); - if (r != SC_SUCCESS) { - LOG_FUNC_RETURN(card->ctx, r); - } - - /* Returns FCI with expected length of data */ - sc_format_path("0005", &index_path); - r = iso_ops->select_file(card, &index_path, &file); - if (r == SC_SUCCESS) { - r = file->size; - } - sc_file_free(file); - /* Ignore too large files */ - if (r <= 0 || r > MAX_FILE_SIZE) { - r = SC_ERROR_INVALID_DATA; - } - return r; -} - static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefmap, int length) { u8 *buf = NULL; @@ -412,34 +388,6 @@ static idprime_keyref_t *idprime_get_keyreference(int index, idprime_keyref_t *k return NULL; } -/* This select some index file, which is useful for enumerating other files - * on the card */ -static int idprime_select_index(sc_card_t *card) -{ - int r; - sc_file_t *file = NULL; - sc_path_t index_path; - - /* First, we need to make sure the IDPrime AID is selected */ - r = idprime_select_idprime(card); - if (r != SC_SUCCESS) { - LOG_FUNC_RETURN(card->ctx, r); - } - - /* Returns FCI with expected length of data */ - sc_format_path("0101", &index_path); - r = iso_ops->select_file(card, &index_path, &file); - if (r == SC_SUCCESS) { - r = file->size; - } - sc_file_free(file); - /* Ignore too large files */ - if (r <= 0 || r > MAX_FILE_SIZE) { - r = SC_ERROR_INVALID_DATA; - } - return r; -} - static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int length) { u8 *buf = NULL; @@ -604,7 +552,7 @@ static int idprime_init(sc_card_t *card) } /* Select and process container file */ - r = idprime_select_containermap(card); + r = idprime_select_file_by_path(card, "0204");; if (r <= 0) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); @@ -619,7 +567,7 @@ static int idprime_init(sc_card_t *card) } if (card->type == SC_CARD_TYPE_IDPRIME_940) { - if ((r = idprime_select_keyrefmap(card)) <= 0) { + if ((r = idprime_select_file_by_path(card, "0005")) <= 0) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); } @@ -631,7 +579,7 @@ static int idprime_init(sc_card_t *card) } /* Select and process the index file */ - r = idprime_select_index(card); + r = idprime_select_file_by_path(card, "0101"); if (r <= 0) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); @@ -726,8 +674,8 @@ static int idprime_match_card(sc_card_t *card) if (i < 0) return 0; - r = idprime_select_index(card); - return (r > 0); + r = idprime_select_file_by_path(card, "0101"); + LOG_FUNC_RETURN(card->ctx, r > 0); } /* initialize getting a list and return the number of elements in the list */ From fc659ab65b3b1501903bf24b7e3add7b615e55ff Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 27 Feb 2023 20:34:59 +0100 Subject: [PATCH 2962/4321] Set error code before return --- src/libopensc/card-idprime.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 0bde61fd0d..4939327203 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -548,13 +548,15 @@ static int idprime_init(sc_card_t *card) priv = idprime_new_private_data(); if (!priv) { - return SC_ERROR_OUT_OF_MEMORY; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } /* Select and process container file */ r = idprime_select_file_by_path(card, "0204");; if (r <= 0) { idprime_free_private_data(priv); + if (r == 0) + r = SC_ERROR_INVALID_DATA; LOG_FUNC_RETURN(card->ctx, r); } @@ -569,6 +571,8 @@ static int idprime_init(sc_card_t *card) if (card->type == SC_CARD_TYPE_IDPRIME_940) { if ((r = idprime_select_file_by_path(card, "0005")) <= 0) { idprime_free_private_data(priv); + if (r == 0) + r = SC_ERROR_INVALID_DATA; LOG_FUNC_RETURN(card->ctx, r); } @@ -582,6 +586,8 @@ static int idprime_init(sc_card_t *card) r = idprime_select_file_by_path(card, "0101"); if (r <= 0) { idprime_free_private_data(priv); + if (r == 0) + r = SC_ERROR_INVALID_DATA; LOG_FUNC_RETURN(card->ctx, r); } From 38b73902a3975e6383c185ec584e66241efe391f Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Thu, 2 Mar 2023 18:27:47 +0100 Subject: [PATCH 2963/4321] Do not overflow buffer when reading containermap --- src/libopensc/card-idprime.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 4939327203..eec9ff2666 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -229,7 +229,7 @@ static int idprime_process_containermap(sc_card_t *card, idprime_container_t **c { u8 *buf = NULL; int r = SC_ERROR_OUT_OF_MEMORY; - int i, max_entries; + int i, max_entries, container_index; idprime_container_t *current = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -245,19 +245,22 @@ static int idprime_process_containermap(sc_card_t *card, idprime_container_t **c r = 0; do { + /* Read at most CONTAINER_OBJ_LEN bytes */ + int read_length = length - r > CONTAINER_OBJ_LEN ? CONTAINER_OBJ_LEN : length - r; if (length == r) { r = SC_ERROR_NOT_ENOUGH_MEMORY; goto done; } - const int got = iso_ops->read_binary(card, r, buf + r, CONTAINER_OBJ_LEN, 0); + const int got = iso_ops->read_binary(card, r, buf + r, read_length, 0); if (got < 1) { r = SC_ERROR_WRONG_LENGTH; goto done; } r += got; - /* Try to read chunks of container size and stop when container looks empty */ - } while(length - r > 0 && buf[(r / CONTAINER_OBJ_LEN - 1) * CONTAINER_OBJ_LEN] != 0); + /* Try to read chunks of container size and stop when last container looks empty */ + container_index = r > CONTAINER_OBJ_LEN ? (r / CONTAINER_OBJ_LEN - 1) * CONTAINER_OBJ_LEN : 0; + } while(length - r > 0 && buf[container_index] != 0); max_entries = r / CONTAINER_OBJ_LEN; for (i = 0; i < max_entries; i++) { From 32e1fa7619fbb02eb423c92ae614f69bcd64bc7c Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Mon, 13 Mar 2023 20:08:21 +0100 Subject: [PATCH 2964/4321] Look at different byte when parsing file with keyreferences --- src/libopensc/card-idprime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index eec9ff2666..c97142f04f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -360,7 +360,7 @@ static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefm } new_keyref->index = start[2]; new_keyref->key_reference = start[1]; - new_keyref->pin_index = start[0]; + new_keyref->pin_index = start[7]; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref->index, new_keyref->pin_index, new_keyref->key_reference); if (!current) { From 957fd5c5f18140c87b75d3aea4ccd6aae89303bb Mon Sep 17 00:00:00 2001 From: Veronika Hanulikova Date: Fri, 14 Apr 2023 17:40:50 +0200 Subject: [PATCH 2965/4321] Use linked lists from simclist implementation --- src/libopensc/card-idprime.c | 189 +++++++++++++++++------------------ 1 file changed, 94 insertions(+), 95 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index c97142f04f..70cc9653c3 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -124,8 +124,8 @@ typedef struct idprime_private_data { int tinfo_present; /* Token Info Label object is present*/ u8 tinfo_df[2]; /* DF of object with Token Info Label */ unsigned long current_op; /* current operation set by idprime_set_security_env */ - idprime_container_t *containers; /* list of private key containers */ - idprime_keyref_t *keyrefmap; /* list of key references for private keys */ + list_t containers; /* list of private key containers */ + list_t keyrefmap; /* list of key references for private keys */ } idprime_private_data_t; /* For SimCList autocopy, we need to know the size of the data elements */ @@ -133,33 +133,70 @@ static size_t idprime_list_meter(const void *el) { return sizeof(idprime_object_t); } -static void idprime_free_containermap(idprime_container_t *containers) +static size_t idprime_container_list_meter(const void *el) { + return sizeof(idprime_container_t); +} + +static size_t idprime_keyref_list_meter(const void *el) { + return sizeof(idprime_keyref_t); +} + +static int idprime_add_container_to_list(list_t *list, const idprime_container_t *container) { - idprime_container_t *next = NULL; - while (containers) { - next = containers->next; - free(containers); - containers = next; - } + if (list_append(list, container) < 0) + return SC_ERROR_INTERNAL; + return SC_SUCCESS; } +static int idprime_list_compare_containers(const void *a, const void *b) +{ + if (a == NULL || b == NULL) + return 1; + return ((idprime_container_t *) a)->index == ((idprime_container_t *) b)->index; +} -static void idprime_free_keyref(idprime_keyref_t *keyrefmap) +static int idprime_container_list_seeker(const void *el, const void *key) { - idprime_keyref_t *next = NULL; - while (keyrefmap) { - next = keyrefmap->next; - free(keyrefmap); - keyrefmap = next; - } + const idprime_container_t *container = (idprime_container_t *)el; + + if ((el == NULL) || (key == NULL)) + return 0; + if (container->index == *(int*)key) + return 1; + return 0; +} + +static int idprime_add_keyref_to_list(list_t *list, const idprime_keyref_t *keyref) +{ + if (list_append(list, keyref) < 0) + return SC_ERROR_INTERNAL; + return SC_SUCCESS; +} + +static int idprime_list_compare_keyrefs(const void *a, const void *b) +{ + if (a == NULL || b == NULL) + return 1; + return ((idprime_keyref_t *) a)->index == ((idprime_keyref_t *) b)->index; +} + +static int idprime_keyref_list_seeker(const void *el, const void *key) +{ + const idprime_keyref_t *keyref = (idprime_keyref_t *)el; + + if ((el == NULL) || (key == NULL)) + return 0; + if (keyref->index == *(int*)key) + return 1; + return 0; } void idprime_free_private_data(idprime_private_data_t *priv) { free(priv->cache_buf); list_destroy(&priv->pki_list); - idprime_free_containermap(priv->containers); - idprime_free_keyref(priv->keyrefmap); + list_destroy(&priv->containers); + list_destroy(&priv->keyrefmap); free(priv); return; } @@ -179,6 +216,23 @@ idprime_private_data_t *idprime_new_private_data(void) return NULL; } + /* Initialize container list */ + if (list_init(&priv->containers) != 0 || + list_attributes_comparator(&priv->containers, idprime_list_compare_containers) != 0 || + list_attributes_copy(&priv->containers, idprime_container_list_meter, 1) != 0 || + list_attributes_seeker(&priv->containers, idprime_container_list_seeker) != 0) { + idprime_free_private_data(priv); + return NULL; + } + + /* Initialize keyref list */ + if (list_init(&priv->keyrefmap) != 0 || + list_attributes_comparator(&priv->keyrefmap, idprime_list_compare_keyrefs) != 0 || + list_attributes_copy(&priv->keyrefmap, idprime_keyref_list_meter, 1) != 0 || + list_attributes_seeker(&priv->keyrefmap, idprime_keyref_list_seeker) != 0) { + idprime_free_private_data(priv); + return NULL; + } return priv; } @@ -225,19 +279,14 @@ static int idprime_select_file_by_path(sc_card_t *card, const char *str_path) LOG_FUNC_RETURN(card->ctx, r); } -static int idprime_process_containermap(sc_card_t *card, idprime_container_t **containers, int length) +static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t *priv, int length) { u8 *buf = NULL; int r = SC_ERROR_OUT_OF_MEMORY; int i, max_entries, container_index; - idprime_container_t *current = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (!containers) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } - buf = malloc(length); if (buf == NULL) { goto done; @@ -265,33 +314,25 @@ static int idprime_process_containermap(sc_card_t *card, idprime_container_t **c for (i = 0; i < max_entries; i++) { u8 *start = &buf[i * CONTAINER_OBJ_LEN]; + idprime_container_t new_container; if (start[0] == 0) /* Empty record */ goto end; - idprime_container_t *new_container = calloc(1, sizeof(idprime_container_t)); - if (!new_container) { - r = SC_ERROR_NOT_ENOUGH_MEMORY; - goto done; - } - new_container->index = i; - + + new_container.index = i; /* Reading UNICODE characters but skipping second byte */ int j = 0; for (j = 0; j < MAX_CONTAINER_NAME_LEN + 1; j++) { if (start[2 * j] == 0) break; - new_container->guid[j] = start[2 * j]; + new_container.guid[j] = start[2 * j]; } - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container->index, new_container->guid); + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container.index, new_container.guid); - /* Chain containers */ - if (!current) { - *containers = new_container; - } else { - current->next = new_container; + if (idprime_add_container_to_list(&priv->containers, &new_container) != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, r); } - current = new_container; } end: @@ -301,31 +342,11 @@ static int idprime_process_containermap(sc_card_t *card, idprime_container_t **c LOG_FUNC_RETURN(card->ctx, r); } -static idprime_container_t *idprime_search_container(int index, idprime_container_t *containers) -{ - idprime_container_t *current = containers; - if (index < 0 || !containers) { - return NULL; - } - while(current) { - if (current->index == index) { - return current; - } - current = current->next; - } - return NULL; -} - -static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefmap, int length) +static int idprime_process_keyrefmap(sc_card_t *card, idprime_private_data_t *priv, int length) { u8 *buf = NULL; int r = SC_ERROR_OUT_OF_MEMORY; int i, max_entries; - idprime_keyref_t *current = NULL; - - if (!keyrefmap) { - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); - } buf = malloc(length); if (buf == NULL) { @@ -349,26 +370,19 @@ static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefm max_entries = r / KEYREF_OBJ_LEN; for (i = 0; i < max_entries; i++) { + idprime_keyref_t new_keyref; u8 *start = &buf[i * KEYREF_OBJ_LEN]; if (start[0] == 0) /* Empty key ref */ continue; + + new_keyref.index = start[2]; + new_keyref.key_reference = start[1]; + new_keyref.pin_index = start[7]; + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref.index, new_keyref.pin_index, new_keyref.key_reference); - idprime_keyref_t *new_keyref = calloc(1, sizeof(idprime_keyref_t)); - if (!new_keyref) { - r = SC_ERROR_NOT_ENOUGH_MEMORY; - goto done; - } - new_keyref->index = start[2]; - new_keyref->key_reference = start[1]; - new_keyref->pin_index = start[7]; - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref->index, new_keyref->pin_index, new_keyref->key_reference); - - if (!current) { - *keyrefmap = new_keyref; - } else { - current->next = new_keyref; + if (idprime_add_keyref_to_list(&priv->keyrefmap, &new_keyref) != SC_SUCCESS) { + LOG_FUNC_RETURN(card->ctx, r); } - current = new_keyref; } r = SC_SUCCESS; done: @@ -376,21 +390,6 @@ static int idprime_process_keyrefmap(sc_card_t *card, idprime_keyref_t **keyrefm LOG_FUNC_RETURN(card->ctx, r); } -static idprime_keyref_t *idprime_get_keyreference(int index, idprime_keyref_t *keyrefmap) -{ - idprime_keyref_t *current = keyrefmap; - if (index < 0 || !keyrefmap) { - return NULL; - } - while(current) { - if (current->index == index) { - return current; - } - current = current->next; - } - return NULL; -} - static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int length) { u8 *buf = NULL; @@ -400,7 +399,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (!priv->containers || (card->type == SC_CARD_TYPE_IDPRIME_940 && !priv->keyrefmap)) { + if (card->type == SC_CARD_TYPE_IDPRIME_940 && list_empty(&priv->keyrefmap)) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } @@ -450,7 +449,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.valid_key_ref = 0; new_object.pin_index = 1; - container = idprime_search_container(cert_id, priv->containers); + container = (idprime_container_t *) list_seek(&priv->containers, &cert_id); if (!container) { /* Object is added, but missing private key */ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding container with private key found for certificate with id=%d", cert_id); @@ -470,7 +469,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, new_object.key_reference = 0x11 + cert_id * 2; break; case SC_CARD_TYPE_IDPRIME_940: { - idprime_keyref_t *keyref = idprime_get_keyreference(cert_id, priv->keyrefmap); + idprime_keyref_t *keyref = (idprime_keyref_t *) list_seek(&priv->keyrefmap, &cert_id); if (!keyref) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d, skipping", cert_id); continue; @@ -565,7 +564,7 @@ static int idprime_init(sc_card_t *card) sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found"); - r = idprime_process_containermap(card, &priv->containers, r); + r = idprime_process_containermap(card, priv, r); if (r != SC_SUCCESS) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); @@ -579,7 +578,7 @@ static int idprime_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - if ((r = idprime_process_keyrefmap(card, &priv->keyrefmap, r)) != SC_SUCCESS) { + if ((r = idprime_process_keyrefmap(card, priv, r)) != SC_SUCCESS) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); } From 17f2d2e839d348d5f46e9933fe6f154fc5c4c001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 May 2023 11:22:59 +0200 Subject: [PATCH 2966/4321] Remove uneeded pointers from container and keyref object --- src/libopensc/card-idprime.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 70cc9653c3..b038de3582 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -97,7 +97,6 @@ typedef struct idprime_object { typedef struct idprime_container { int index; /* Index of the container */ char guid[MAX_CONTAINER_NAME_LEN + 1]; /* Container name */ - struct idprime_container *next; } idprime_container_t; /* @@ -108,7 +107,6 @@ typedef struct idprime_keyref { int index; /* Index of the key reference */ int pin_index; /* Index of the auth pin used for accessing key */ unsigned char key_reference; /* Key reference used for accessing key */ - struct idprime_keyref *next; } idprime_keyref_t; /* From 61927fd3692a081d940f98867ce1371a33052b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 May 2023 13:12:39 +0200 Subject: [PATCH 2967/4321] Store key indexes as one byte --- src/libopensc/card-idprime.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index b038de3582..6c308f4aca 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -95,7 +95,7 @@ typedef struct idprime_object { #define MAX_CONTAINER_NAME_LEN 39 #define CONTAINER_OBJ_LEN 86 typedef struct idprime_container { - int index; /* Index of the container */ + uint8_t index; /* Index of the container */ char guid[MAX_CONTAINER_NAME_LEN + 1]; /* Container name */ } idprime_container_t; @@ -104,9 +104,9 @@ typedef struct idprime_container { */ #define KEYREF_OBJ_LEN 8 typedef struct idprime_keyref { - int index; /* Index of the key reference */ - int pin_index; /* Index of the auth pin used for accessing key */ - unsigned char key_reference; /* Key reference used for accessing key */ + uint8_t index; /* Index of the key reference */ + uint8_t pin_index; /* Index of the auth pin used for accessing key */ + unsigned char key_reference; /* Key reference used for accessing key */ } idprime_keyref_t; /* @@ -146,20 +146,13 @@ static int idprime_add_container_to_list(list_t *list, const idprime_container_t return SC_SUCCESS; } -static int idprime_list_compare_containers(const void *a, const void *b) -{ - if (a == NULL || b == NULL) - return 1; - return ((idprime_container_t *) a)->index == ((idprime_container_t *) b)->index; -} - static int idprime_container_list_seeker(const void *el, const void *key) { const idprime_container_t *container = (idprime_container_t *)el; if ((el == NULL) || (key == NULL)) return 0; - if (container->index == *(int*)key) + if (container->index == *(uint8_t *)key) return 1; return 0; } @@ -171,20 +164,13 @@ static int idprime_add_keyref_to_list(list_t *list, const idprime_keyref_t *keyr return SC_SUCCESS; } -static int idprime_list_compare_keyrefs(const void *a, const void *b) -{ - if (a == NULL || b == NULL) - return 1; - return ((idprime_keyref_t *) a)->index == ((idprime_keyref_t *) b)->index; -} - static int idprime_keyref_list_seeker(const void *el, const void *key) { const idprime_keyref_t *keyref = (idprime_keyref_t *)el; if ((el == NULL) || (key == NULL)) return 0; - if (keyref->index == *(int*)key) + if (keyref->index == *(uint8_t *)key) return 1; return 0; } @@ -216,7 +202,6 @@ idprime_private_data_t *idprime_new_private_data(void) /* Initialize container list */ if (list_init(&priv->containers) != 0 || - list_attributes_comparator(&priv->containers, idprime_list_compare_containers) != 0 || list_attributes_copy(&priv->containers, idprime_container_list_meter, 1) != 0 || list_attributes_seeker(&priv->containers, idprime_container_list_seeker) != 0) { idprime_free_private_data(priv); @@ -225,7 +210,6 @@ idprime_private_data_t *idprime_new_private_data(void) /* Initialize keyref list */ if (list_init(&priv->keyrefmap) != 0 || - list_attributes_comparator(&priv->keyrefmap, idprime_list_compare_keyrefs) != 0 || list_attributes_copy(&priv->keyrefmap, idprime_keyref_list_meter, 1) != 0 || list_attributes_seeker(&priv->keyrefmap, idprime_keyref_list_seeker) != 0) { idprime_free_private_data(priv); @@ -281,7 +265,8 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t { u8 *buf = NULL; int r = SC_ERROR_OUT_OF_MEMORY; - int i, max_entries, container_index; + int i; + uint8_t max_entries, container_index; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -316,7 +301,6 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t if (start[0] == 0) /* Empty record */ goto end; - new_container.index = i; /* Reading UNICODE characters but skipping second byte */ int j = 0; @@ -436,7 +420,7 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, /* in minidriver, mscp/kxcNN or kscNN lists certificates */ if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0) && (memcmp(&start[12], "mscp", 5) == 0)) { - int cert_id = 0; + uint8_t cert_id = 0; idprime_container_t *container = NULL; if (start[7] >= '0' && start[7] <= '9' && start[8] >= '0' && start[8] <= '9') { From f1a81e11caaf9fac426f9d755c5efc58eb9d8d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 May 2023 13:14:11 +0200 Subject: [PATCH 2968/4321] Retype key reference to match sc_pkcs15_prkey_info_t --- src/libopensc/card-idprime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 6c308f4aca..63c455cd11 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -81,7 +81,7 @@ static const sc_path_t idprime_path = { /* data structures to store meta data about IDPrime objects */ typedef struct idprime_object { int fd; - unsigned char key_reference; + int key_reference; int valid_key_ref; u8 df[2]; unsigned short length; @@ -106,7 +106,7 @@ typedef struct idprime_container { typedef struct idprime_keyref { uint8_t index; /* Index of the key reference */ uint8_t pin_index; /* Index of the auth pin used for accessing key */ - unsigned char key_reference; /* Key reference used for accessing key */ + int key_reference; /* Key reference used for accessing key */ } idprime_keyref_t; /* From eb1257dafcb541792af4aa069ae05c9b4fee5e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 May 2023 13:16:54 +0200 Subject: [PATCH 2969/4321] Remove unnecessary goto statement --- src/libopensc/card-idprime.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 63c455cd11..d6ffef8b28 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -299,7 +299,7 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t u8 *start = &buf[i * CONTAINER_OBJ_LEN]; idprime_container_t new_container; if (start[0] == 0) /* Empty record */ - goto end; + break; new_container.index = i; /* Reading UNICODE characters but skipping second byte */ @@ -317,7 +317,6 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t } } -end: r = SC_SUCCESS; done: free(buf); From 75c791a2dba293cbdb99cd347f7bb5b71260129b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 5 May 2023 13:19:28 +0200 Subject: [PATCH 2970/4321] Free buffer in case of failure --- src/libopensc/card-idprime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index d6ffef8b28..7f4629b663 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -361,8 +361,8 @@ static int idprime_process_keyrefmap(sc_card_t *card, idprime_private_data_t *pr new_keyref.pin_index = start[7]; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref.index, new_keyref.pin_index, new_keyref.key_reference); - if (idprime_add_keyref_to_list(&priv->keyrefmap, &new_keyref) != SC_SUCCESS) { - LOG_FUNC_RETURN(card->ctx, r); + if ((r = idprime_add_keyref_to_list(&priv->keyrefmap, &new_keyref)) != SC_SUCCESS) { + goto done; } } r = SC_SUCCESS; From b94fbcd49c161f367d33328dbc5693494c4ffaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 10 May 2023 14:09:28 +0200 Subject: [PATCH 2971/4321] Fix PIN ctl macro name --- src/libopensc/card-idprime.c | 2 +- src/libopensc/cardctl.h | 2 +- src/libopensc/pkcs15-idprime.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 7f4629b663..6624070662 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -832,7 +832,7 @@ static int idprime_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) (sc_pkcs15_prkey_info_t *)ptr); case SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS: return idprime_final_iterator(&priv->pki_list); - case SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID: + case SC_CARDCTL_IDPRIME_GET_PIN_ID: return idprime_get_pin_id(&priv->pki_list, &priv->pki_current, (char **)ptr); } diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 17d08b987f..6c7a631eeb 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -305,7 +305,7 @@ enum { SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS, SC_CARDCTL_IDPRIME_GET_TOKEN_NAME, - SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID, + SC_CARDCTL_IDPRIME_GET_PIN_ID, }; diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 99ffe382ad..6aa6b961f5 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -176,7 +176,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_cert_t *cert_out = NULL; char *pin_id = NULL; - r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_FINAL_GET_PIN_ID, &pin_id); + r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_PIN_ID, &pin_id); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get PIN id of next object "); r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, &prkey_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object"); From e62b874f18947e81f13e3fa23f95ebd5eb75dfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 2 Jun 2023 16:07:53 +0200 Subject: [PATCH 2972/4321] Fix memory leak --- src/libopensc/card-idprime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 6624070662..6549196b74 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -312,8 +312,8 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container.index, new_container.guid); - if (idprime_add_container_to_list(&priv->containers, &new_container) != SC_SUCCESS) { - LOG_FUNC_RETURN(card->ctx, r); + if ((r = idprime_add_container_to_list(&priv->containers, &new_container)) != SC_SUCCESS) { + goto done; } } From 87aedd3a940b8ea0cb7b1b7e93a3883aa22adb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 2 Jun 2023 16:23:08 +0200 Subject: [PATCH 2973/4321] Make PIN ID const To indicate that the returned memory does not need to be free'd. --- src/libopensc/card-idprime.c | 4 ++-- src/libopensc/pkcs15-idprime.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 6549196b74..1f725fad68 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -713,7 +713,7 @@ static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pk } /* get PIN id of the current object on the list */ -static int idprime_get_pin_id(list_t *list, idprime_object_t **entry, char **pin_id) +static int idprime_get_pin_id(list_t *list, idprime_object_t **entry, const char **pin_id) { if (pin_id == NULL || entry == NULL) { return SC_ERROR_INVALID_ARGUMENTS; @@ -834,7 +834,7 @@ static int idprime_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return idprime_final_iterator(&priv->pki_list); case SC_CARDCTL_IDPRIME_GET_PIN_ID: return idprime_get_pin_id(&priv->pki_list, &priv->pki_current, - (char **)ptr); + (const char **)ptr); } LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 6aa6b961f5..36f939325e 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -174,7 +174,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) struct sc_pkcs15_object prkey_obj; sc_pkcs15_der_t cert_der; sc_pkcs15_cert_t *cert_out = NULL; - char *pin_id = NULL; + const char *pin_id = NULL; r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_PIN_ID, &pin_id); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get PIN id of next object "); From df0975eb39c83513b90fffa392cb118ab3c2446b Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Jun 2023 09:35:10 +0200 Subject: [PATCH 2974/4321] update to OpenPACE 1.1.3 fixes https://github.com/frankmorgner/openpace/issues/63 --- .appveyor.yml | 2 +- MacOSX/build-package.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 4943394f1f..88120cd0c4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,7 +12,7 @@ environment: GH_TOKEN: secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY PATH: C:\cygwin\bin;%PATH% - OPENPACE_VER: 1.1.2 + OPENPACE_VER: 1.1.3 ZLIB_VER_DOT: 1.2.12 matrix: # not compatible with OpenSSL 1.1.1: diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index ba28bd8559..09e5aad840 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -66,7 +66,7 @@ export OBJCFLAGS=$CFLAGS if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then if ! test -e openpace; then - git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.2 + git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.3 fi cd openpace autoreconf -vis From 3e461badc99b75e07c302f0078d12498521b1a72 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Jun 2023 09:42:55 +0200 Subject: [PATCH 2975/4321] fixed compiler warning fixes https://github.com/OpenSC/OpenSC/issues/2794 --- src/libopensc/card-sc-hsm.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index f46dd73036..05ce914b17 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -36,6 +36,17 @@ #include "card-sc-hsm.h" +#ifdef ENABLE_SM +#ifdef ENABLE_OPENPACE +#include "sm/sm-eac.h" +#include +#include +#include +#include +#include +#endif +#endif + /* Static reference to ISO driver */ static const struct sc_card_operations *iso_ops = NULL; @@ -476,12 +487,6 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, #ifdef ENABLE_SM #ifdef ENABLE_OPENPACE -#include "sm/sm-eac.h" -#include -#include -#include -#include -#include static int sc_hsm_perform_chip_authentication(sc_card_t *card) { From 8df28efe9a742ae1d0a4aaa88fe7675fd381070a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Jun 2023 11:16:14 +0200 Subject: [PATCH 2976/4321] appveyor: fixed cd to build folder --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 88120cd0c4..0369789aba 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -90,7 +90,7 @@ build_script: # OpenSSL 1.0.2 #cl /nologo /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c lib /nologo /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj - cd C:\projects\OpenSC + cd ${env:APPVEYOR_BUILD_FOLDER} } $env:NMAKE_EXTRA+=" OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=C:\openpace-${env:OPENSSL_PF}" } From 3f34c3208a902f33726ac23d55b724bd3a7cb309 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 8 Jun 2023 15:03:12 +0200 Subject: [PATCH 2977/4321] fixed compiler warning --- src/libopensc/pkcs15-idprime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 36f939325e..05de0d38c0 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -176,7 +176,7 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card) sc_pkcs15_cert_t *cert_out = NULL; const char *pin_id = NULL; - r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_PIN_ID, &pin_id); + r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_PIN_ID, (void *) &pin_id); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get PIN id of next object "); r = (card->ops->card_ctl)(card, SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT, &prkey_info); LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object"); From 6f29e41e383d127d5afe2cb3effe144f4a27bb13 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Jun 2023 16:44:02 +0200 Subject: [PATCH 2978/4321] fuzz: Document workaround for useless backtraces --- src/tests/fuzzing/README.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/tests/fuzzing/README.md b/src/tests/fuzzing/README.md index d7f425a0dc..9dcd82bc75 100644 --- a/src/tests/fuzzing/README.md +++ b/src/tests/fuzzing/README.md @@ -15,7 +15,7 @@ Example configuration for libFuzzer: ./configure --disable-optimization --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing CC=clang CFLAGS=-fsanitize=fuzzer-no-link FUZZING_LIBS=-fsanitize=fuzzer ``` -To add some of the LLVM Sanitizers, modify `FUZZING_LIBS`: +To add some of the LLVM Sanitizers, modify `FUZZING_LIBS`: ``` FUZZING_LIBS=-fsanitize=fuzzer,address,undefined ``` @@ -29,13 +29,41 @@ Example of testing without fuzzing: ./fuzz_pkcs15_reader ./input_file ``` +## Reproducing issues +Some of the issues are not reproducible when build outside of the fuzzing images. In that case, the safest +option is to reproduce them with the python/docker helpers provided by [oss-fuzz](https://github.com/google/oss-fuzz/). +You can build latest fuzzers in the oss-fuzz containers with the following steps: +``` +python3 infra/helper.py pull_images +python3 infra/helper.py build_image opensc +python3 infra/helper.py build_fuzzers opensc +``` +After that, you can download reproducer from the oss-fuzz dashboard and run it locally in the container: +``` +python3 infra/helper.py reproduce opensc fuzz_pkcs15_decode /path/to/testcase +``` + +### Expanding incomplete backtraces +Sometimes the backtrace visible in the oss-fuzz dashboard is not useful, for example showing only part of the +trace ending inside of (outdated) openssl code: +``` +Direct leak of 168 byte(s) in 1 object(s) allocated from: + #0 0x5318e6 in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3 + #1 0x7faca8714c0d in CRYPTO_zalloc +``` +In that case, you can use the address sanitizer option `fast_unwind_on_malloc=0` in `ASAN_OPTIONS` environment +variable to expand this trace, for example: +``` +python3 infra/helper.py reproduce -eASAN_OPTIONS='fast_unwind_on_malloc=0' opensc fuzz_pkcs15_decode testcase +``` + ## Fuzzing ### libFuzzer See libFuzzer [documentation](https://llvm.org/docs/LibFuzzer.html) for details. Fuzzing with a predefined corpus can be run like this: ``` -./fuzz_pkcs15_reader corpus/fuzz_pkcs15_reader +./fuzz_pkcs15_reader corpus/fuzz_pkcs15_reader ``` Newly generated input files are stored in the corpus directory. From e0ca63eccb12868f8a518ce952ecc814eec08e78 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Jun 2023 16:52:04 +0200 Subject: [PATCH 2979/4321] idprime: Avoid pointer dereference before checking for NULL CID 385356 Thanks Coverity --- src/libopensc/card-idprime.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 1f725fad68..d413b312eb 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -56,7 +56,7 @@ static const struct sc_atr_table idprime_atrs[] = { { "3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 930/3930", - SC_CARD_TYPE_IDPRIME_930, 0, NULL }, + SC_CARD_TYPE_IDPRIME_930, 0, NULL }, { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00", "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff", "Gemalto IDPrime 940", @@ -355,7 +355,7 @@ static int idprime_process_keyrefmap(sc_card_t *card, idprime_private_data_t *pr u8 *start = &buf[i * KEYREF_OBJ_LEN]; if (start[0] == 0) /* Empty key ref */ continue; - + new_keyref.index = start[2]; new_keyref.key_reference = start[1]; new_keyref.pin_index = start[7]; @@ -558,7 +558,7 @@ static int idprime_init(sc_card_t *card) r = SC_ERROR_INVALID_DATA; LOG_FUNC_RETURN(card->ctx, r); } - + if ((r = idprime_process_keyrefmap(card, priv, r)) != SC_SUCCESS) { idprime_free_private_data(priv); LOG_FUNC_RETURN(card->ctx, r); @@ -935,7 +935,7 @@ idprime_set_security_env(struct sc_card *card, { int r; struct sc_security_env new_env; - idprime_private_data_t *priv = card->drv_data; + idprime_private_data_t *priv = NULL; if (card == NULL || env == NULL) { return SC_ERROR_INVALID_ARGUMENTS; @@ -943,6 +943,8 @@ idprime_set_security_env(struct sc_card *card, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + priv = card->drv_data; + /* The card requires algorithm reference here */ new_env = *env; new_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT; From 83c468d33726a9db422f0f9013fa8c6c86bad82f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Jun 2023 16:53:04 +0200 Subject: [PATCH 2980/4321] pkcs15-prkey: Avoid memory leaks Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58193 --- src/libopensc/pkcs15-prkey.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 4892b5a52e..7609e5ee49 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -244,7 +244,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, const unsigned char *p = ec_domain; ASN1_OBJECT *object = d2i_ASN1_OBJECT(NULL, &p, ec_domain_len); int nid; - const EC_GROUP *group; + EC_GROUP *group; if (!object) { r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -261,6 +261,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, goto err; } info.field_length = EC_GROUP_order_bits(group); + EC_GROUP_free(group); if (!info.field_length) { r = SC_ERROR_CORRUPTED_DATA; goto err; @@ -627,7 +628,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) switch (pk_type) { case EVP_PKEY_RSA: { struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa; - + #if OPENSSL_VERSION_NUMBER < 0x30000000L const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1; RSA *src = NULL; @@ -791,7 +792,7 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) /* * In OpenSC the field_length is in bits. Not all curves are a multiple of 8. * EC_POINT_point2oct handles this and returns octstrings that can handle - * these curves. Get real field_length from OpenSSL. + * these curves. Get real field_length from OpenSSL. */ dst->params.field_length = EC_GROUP_get_degree(grp); From d7fadae950f6d33b32f979759c06ab78a3475c22 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 21 Jun 2023 13:49:40 +0200 Subject: [PATCH 2981/4321] PIV: implemented logout --- src/libopensc/card-piv.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a4fea759e4..b4d92098ec 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -2189,11 +2189,11 @@ static int piv_is_object_present(sc_card_t *card, u8 *ptr) * or the global pin for the card 0x00. Look at Discovery object to get this. * called by pkcs15-piv.c via cardctl when setting up the pins. */ -static int piv_get_pin_preference(sc_card_t *card, int *ptr) +static int piv_get_pin_preference(sc_card_t *card, int *pin_ref) { piv_private_data_t * priv = PIV_DATA(card); - *ptr = priv->pin_preference; + *pin_ref = priv->pin_preference; LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -3760,12 +3760,18 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) static int piv_logout(sc_card_t *card) { - int r = SC_ERROR_NOT_SUPPORTED; /* TODO Some PIV cards may support a logout */ - /* piv_private_data_t * priv = PIV_DATA(card); */ + int r = SC_ERROR_NOT_SUPPORTED; + piv_private_data_t * priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); - /* TODO 800-73-3 does not define a logout, 800-73-4 does */ + if (priv) { + /* logout defined since 800-73-4 */ + r = iso7816_logout(card, priv->pin_preference); + if (r == SC_SUCCESS) { + priv->logged_in = SC_PIN_STATE_LOGGED_OUT; + } + } LOG_FUNC_RETURN(card->ctx, r); } From e86a30d6dfb068a63707d0ed729203f5a01a5076 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 22 Sep 2022 10:32:37 +0200 Subject: [PATCH 2982/4321] Use "change counter" value from card (if available) for filename in cache. The card's file cache needs a timestamp so that we know when the cache does not match the card's content. The solution used so far is based on information from EF.Tokeninfo, where the time of the last modification of the card is recorded. However, EF.Tokeninfo does not provide sufficient granularity of the timestamp and is not updated atomically for changes on the card. Some of the cards provide an internal "change counter", which is incremented after each change of the card's content. If such information is available, it is used as a timestamp for the name of the card's cached file. modified: src/libopensc/cardctl.h modified: src/libopensc/pkcs15-cache.c --- src/libopensc/cardctl.h | 1 + src/libopensc/pkcs15-cache.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 6c7a631eeb..553b282e6b 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -41,6 +41,7 @@ enum { SC_CARDCTL_LIFECYCLE_GET, SC_CARDCTL_LIFECYCLE_SET, SC_CARDCTL_GET_SERIALNR, + SC_CARDCTL_GET_CHANGE_COUNTER, SC_CARDCTL_GET_SE_INFO, SC_CARDCTL_GET_CHV_REFERENCE_IN_SE, SC_CARDCTL_PKCS11_INIT_TOKEN, diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index 8c83ddb6a5..a545d056fb 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -46,6 +46,7 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card, char *last_update = NULL; int r; unsigned u; + size_t change_counter; if (p15card->tokeninfo->serial_number == NULL && (p15card->card->uid.len == 0 @@ -73,6 +74,9 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card, p15card->card->uid.len), last_update); } + if (SC_SUCCESS == sc_card_ctl(p15card->card, SC_CARDCTL_GET_CHANGE_COUNTER, &change_counter)) + snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir), "_%" SC_FORMAT_LEN_SIZE_T "u", change_counter); + if (path->aid.len && (path->type == SC_PATH_TYPE_FILE_ID || path->type == SC_PATH_TYPE_PATH)) { snprintf(dir + strlen(dir), sizeof(dir) - strlen(dir), "_"); From d5e7459a3580a5486b43fffb66bd1aabddf5f504 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 22 Sep 2022 12:50:05 +0200 Subject: [PATCH 2983/4321] MyEID: added implementation for SC_CARDCTL_GET_CHANGE_COUNTER --- src/libopensc/card-myeid.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 951c179f1b..58782a1b02 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1784,6 +1784,23 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) LOG_FUNC_RETURN(card->ctx, r); } +static int +myeid_get_change_counter(sc_card_t *card, size_t *change_counter) +{ + int r; + u8 rbuf[256]; + + LOG_FUNC_CALLED(card->ctx); + + /* get change counter from card */ + r = myeid_get_info(card, rbuf, sizeof(rbuf)); + LOG_TEST_RET(card->ctx, r, "Get applet info failed"); + + *change_counter = rbuf[18] * 256 + rbuf[19]; + + LOG_FUNC_RETURN(card->ctx, r); +} + /* Get information of features that the card supports. MyEID 4.x cards are available on different hardware and maximum key sizes cannot be determined simply from the version number anymore. @@ -1847,6 +1864,9 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) case SC_CARDCTL_GET_SERIALNR: r = myeid_get_serialnr(card, (sc_serial_number_t *)ptr); break; + case SC_CARDCTL_GET_CHANGE_COUNTER: + r = myeid_get_change_counter(card, (size_t *)ptr); + break; case SC_CARDCTL_GET_DEFAULT_KEY: case SC_CARDCTL_LIFECYCLE_SET: case SC_CARDCTL_LIFECYCLE_GET: From df693351f8ca823d6e118ff751b649eeb3f540d5 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Thu, 8 Jun 2023 08:23:29 +0200 Subject: [PATCH 2984/4321] enable use_file_cache for MyEID card --- doc/files/files.html | 1 + src/libopensc/pkcs15.c | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/files/files.html b/doc/files/files.html index 68b8a6e9b7..3bcb8136d4 100644 --- a/doc/files/files.html +++ b/doc/files/files.html @@ -777,6 +777,7 @@ jpki, MaskTech, mcrd, + MyEID, npa, nqapplet, tcos and otherwise no). diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 199d1a6082..39117ed2d0 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1241,6 +1241,7 @@ const char *pkcs15_get_default_use_file_cache(struct sc_card *card) "jpki", "MaskTech", "mcrd", + "myeid", "npa", "nqapplet", "tcos", From 66f7c34517723ee0aded01d697a210c00f3e85f2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Jun 2023 14:29:33 +0200 Subject: [PATCH 2985/4321] misc: Update address in the LGPL 2.1 license headers Based on https://spdx.org/licenses/LGPL-2.1-or-later.html --- src/common/compat_overflow.c | 4 ++-- src/common/compat_overflow.h | 2 +- src/common/compat_report_rangecheckfailure.c | 2 +- src/common/libpkcs11.c | 2 +- src/common/libpkcs11.h | 2 +- src/common/libscdl.c | 2 +- src/common/libscdl.h | 2 +- src/libopensc/apdu.c | 2 +- src/libopensc/asn1.c | 2 +- src/libopensc/asn1.h | 2 +- src/libopensc/authentic.h | 2 +- src/libopensc/aux-data.c | 2 +- src/libopensc/aux-data.h | 2 +- src/libopensc/base64.c | 2 +- src/libopensc/card-akis.c | 2 +- src/libopensc/card-asepcos.c | 2 +- src/libopensc/card-atrust-acos.c | 2 +- src/libopensc/card-authentic.c | 2 +- src/libopensc/card-belpic.c | 2 +- src/libopensc/card-cac-common.c | 2 +- src/libopensc/card-cac-common.h | 2 +- src/libopensc/card-cac.c | 2 +- src/libopensc/card-cac1.c | 2 +- src/libopensc/card-cardos.c | 2 +- src/libopensc/card-coolkey.c | 2 +- src/libopensc/card-default.c | 2 +- src/libopensc/card-dnie.c | 2 +- src/libopensc/card-edo.c | 2 +- src/libopensc/card-entersafe.c | 2 +- src/libopensc/card-eoi.c | 2 +- src/libopensc/card-eoi.h | 2 +- src/libopensc/card-epass2003.c | 2 +- src/libopensc/card-esteid2018.c | 2 +- src/libopensc/card-flex.c | 2 +- src/libopensc/card-gemsafeV1.c | 2 +- src/libopensc/card-gids.c | 2 +- src/libopensc/card-gids.h | 2 +- src/libopensc/card-gpk.c | 2 +- src/libopensc/card-iasecc.c | 2 +- src/libopensc/card-idprime.c | 2 +- src/libopensc/card-incrypto34.c | 2 +- src/libopensc/card-isoApplet.c | 2 +- src/libopensc/card-itacns.c | 2 +- src/libopensc/card-jpki.c | 2 +- src/libopensc/card-masktech.c | 2 +- src/libopensc/card-mcrd.c | 2 +- src/libopensc/card-muscle.c | 2 +- src/libopensc/card-myeid.c | 2 +- src/libopensc/card-npa.c | 2 +- src/libopensc/card-npa.h | 2 +- src/libopensc/card-nqApplet.c | 2 +- src/libopensc/card-oberthur.c | 2 +- src/libopensc/card-openpgp.c | 2 +- src/libopensc/card-openpgp.h | 2 +- src/libopensc/card-piv.c | 2 +- src/libopensc/card-rtecp.c | 2 +- src/libopensc/card-rutoken.c | 2 +- src/libopensc/card-sc-hsm.c | 2 +- src/libopensc/card-sc-hsm.h | 2 +- src/libopensc/card-setcos.c | 2 +- src/libopensc/card-skeid.c | 2 +- src/libopensc/card-starcos.c | 2 +- src/libopensc/card-tcos.c | 2 +- src/libopensc/card-westcos.c | 2 +- src/libopensc/card.c | 2 +- src/libopensc/cardctl.h | 2 +- src/libopensc/cards.h | 2 +- src/libopensc/ccid-types.h | 2 +- src/libopensc/compression.c | 2 +- src/libopensc/compression.h | 2 +- src/libopensc/ctbcs.c | 2 +- src/libopensc/ctbcs.h | 2 +- src/libopensc/ctx.c | 2 +- src/libopensc/cwa-dnie.c | 2 +- src/libopensc/cwa-dnie.h | 2 +- src/libopensc/cwa14890.c | 2 +- src/libopensc/cwa14890.h | 2 +- src/libopensc/dir.c | 2 +- src/libopensc/ef-atr.c | 2 +- src/libopensc/ef-gdo.c | 2 +- src/libopensc/errors.c | 2 +- src/libopensc/errors.h | 2 +- src/libopensc/gp.c | 2 +- src/libopensc/gp.h | 2 +- src/libopensc/iasecc-sdo.c | 2 +- src/libopensc/iasecc-sdo.h | 2 +- src/libopensc/iasecc-sm.c | 2 +- src/libopensc/iasecc.h | 2 +- src/libopensc/internal.h | 2 +- src/libopensc/iso7816.c | 2 +- src/libopensc/jpki.h | 2 +- src/libopensc/log.c | 2 +- src/libopensc/log.h | 2 +- src/libopensc/muscle-filesystem.c | 2 +- src/libopensc/muscle-filesystem.h | 2 +- src/libopensc/muscle.c | 2 +- src/libopensc/muscle.h | 2 +- src/libopensc/opensc.h | 2 +- src/libopensc/pace.h | 2 +- src/libopensc/padding.c | 2 +- src/libopensc/pkcs15-actalis.c | 2 +- src/libopensc/pkcs15-algo.c | 2 +- src/libopensc/pkcs15-atrust-acos.c | 2 +- src/libopensc/pkcs15-cac.c | 2 +- src/libopensc/pkcs15-cache.c | 2 +- src/libopensc/pkcs15-cardos.c | 2 +- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15-coolkey.c | 2 +- src/libopensc/pkcs15-data.c | 2 +- src/libopensc/pkcs15-din-66291.c | 2 +- src/libopensc/pkcs15-dnie.c | 2 +- src/libopensc/pkcs15-eoi.c | 2 +- src/libopensc/pkcs15-esinit.c | 2 +- src/libopensc/pkcs15-esteid.c | 2 +- src/libopensc/pkcs15-esteid2018.c | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 2 +- src/libopensc/pkcs15-gemsafeV1.c | 2 +- src/libopensc/pkcs15-gids.c | 2 +- src/libopensc/pkcs15-iasecc.c | 2 +- src/libopensc/pkcs15-idprime.c | 2 +- src/libopensc/pkcs15-itacns.c | 2 +- src/libopensc/pkcs15-jpki.c | 2 +- src/libopensc/pkcs15-nqApplet.c | 2 +- src/libopensc/pkcs15-oberthur.c | 2 +- src/libopensc/pkcs15-openpgp.c | 2 +- src/libopensc/pkcs15-pin.c | 2 +- src/libopensc/pkcs15-piv.c | 2 +- src/libopensc/pkcs15-prkey.c | 2 +- src/libopensc/pkcs15-pteid.c | 2 +- src/libopensc/pkcs15-pubkey.c | 2 +- src/libopensc/pkcs15-sc-hsm.c | 2 +- src/libopensc/pkcs15-sec.c | 2 +- src/libopensc/pkcs15-skeid.c | 2 +- src/libopensc/pkcs15-skey.c | 2 +- src/libopensc/pkcs15-starcert.c | 2 +- src/libopensc/pkcs15-starcos-esign.c | 2 +- src/libopensc/pkcs15-syn.c | 2 +- src/libopensc/pkcs15-syn.h | 2 +- src/libopensc/pkcs15-tccardos.c | 2 +- src/libopensc/pkcs15-tcos.c | 2 +- src/libopensc/pkcs15-westcos.c | 2 +- src/libopensc/pkcs15.c | 2 +- src/libopensc/pkcs15.h | 2 +- src/libopensc/reader-cryptotokenkit.m | 2 +- src/libopensc/reader-ctapi.c | 2 +- src/libopensc/reader-openct.c | 2 +- src/libopensc/reader-pcsc.c | 2 +- src/libopensc/reader-tr03119.c | 2 +- src/libopensc/reader-tr03119.h | 2 +- src/libopensc/sc-ossl-compat.h | 2 +- src/libopensc/sc.c | 2 +- src/libopensc/sec.c | 2 +- src/libopensc/simpletlv.c | 2 +- src/libopensc/simpletlv.h | 2 +- src/libopensc/sm.c | 2 +- src/libopensc/sm.h | 2 +- src/libopensc/types.h | 2 +- src/minidriver/cardmod-mingw-compat.h | 2 +- src/minidriver/minidriver.c | 2 +- src/pkcs11/debug.c | 2 +- src/pkcs11/framework-pkcs15.c | 2 +- src/pkcs11/framework-pkcs15init.c | 2 +- src/pkcs11/mechanism.c | 2 +- src/pkcs11/misc.c | 2 +- src/pkcs11/openssl.c | 2 +- src/pkcs11/pkcs11-display.c | 2 +- src/pkcs11/pkcs11-display.h | 2 +- src/pkcs11/pkcs11-global.c | 2 +- src/pkcs11/pkcs11-object.c | 2 +- src/pkcs11/pkcs11-session.c | 2 +- src/pkcs11/pkcs11-spy.c | 2 +- src/pkcs11/sc-pkcs11.h | 2 +- src/pkcs11/slot.c | 2 +- src/pkcs15init/pkcs15-asepcos.c | 2 +- src/pkcs15init/pkcs15-authentic.c | 2 +- src/pkcs15init/pkcs15-cardos.c | 2 +- src/pkcs15init/pkcs15-cflex.c | 2 +- src/pkcs15init/pkcs15-entersafe.c | 2 +- src/pkcs15init/pkcs15-epass2003.c | 2 +- src/pkcs15init/pkcs15-gids.c | 2 +- src/pkcs15init/pkcs15-gpk.c | 2 +- src/pkcs15init/pkcs15-iasecc.c | 2 +- src/pkcs15init/pkcs15-iasecc.h | 2 +- src/pkcs15init/pkcs15-incrypto34.c | 2 +- src/pkcs15init/pkcs15-init.h | 2 +- src/pkcs15init/pkcs15-isoApplet.c | 2 +- src/pkcs15init/pkcs15-lib.c | 2 +- src/pkcs15init/pkcs15-muscle.c | 2 +- src/pkcs15init/pkcs15-myeid.c | 2 +- src/pkcs15init/pkcs15-oberthur-awp.c | 2 +- src/pkcs15init/pkcs15-oberthur.c | 2 +- src/pkcs15init/pkcs15-openpgp.c | 2 +- src/pkcs15init/pkcs15-rtecp.c | 2 +- src/pkcs15init/pkcs15-rutoken.c | 2 +- src/pkcs15init/pkcs15-sc-hsm.c | 2 +- src/pkcs15init/pkcs15-setcos.c | 2 +- src/pkcs15init/pkcs15-starcos.c | 2 +- src/pkcs15init/pkcs15-westcos.c | 2 +- src/pkcs15init/profile.c | 2 +- src/pkcs15init/profile.h | 2 +- src/scconf/internal.h | 2 +- src/scconf/lex-parse.l | 2 +- src/scconf/parse.c | 2 +- src/scconf/scconf.c | 2 +- src/scconf/scconf.h | 2 +- src/scconf/sclex.c | 2 +- src/scconf/write.c | 2 +- src/sm/sm-common.c | 2 +- src/sm/sm-common.h | 2 +- src/sm/sm-eac.c | 2 +- src/sm/sm-eac.h | 2 +- src/sm/sm-iso-internal.h | 2 +- src/sm/sm-iso.c | 2 +- src/sm/sm-iso.h | 2 +- src/sm/sslutil.h | 2 +- src/smm/sm-card-authentic.c | 2 +- src/smm/sm-card-iasecc.c | 2 +- src/smm/sm-cwa14890.c | 2 +- src/smm/sm-global-platform.c | 2 +- src/smm/sm-module.h | 2 +- src/smm/smm-local.c | 2 +- src/tests/fuzzing/fuzz_asn1_print.c | 2 +- src/tests/fuzzing/fuzz_asn1_sig_value.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_decode.c | 2 +- src/tests/fuzzing/fuzz_pkcs15_reader.c | 2 +- src/tests/fuzzing/fuzzer_reader.c | 2 +- src/tests/fuzzing/fuzzer_reader.h | 2 +- src/tools/cardos-tool.c | 2 +- src/tools/cryptoflex-tool.c | 2 +- src/tools/dnie-tool.c | 2 +- src/tools/egk-tool.c | 2 +- src/tools/eidenv.c | 2 +- src/tools/fread_to_eof.c | 2 +- src/tools/fread_to_eof.h | 2 +- src/tools/gids-tool.c | 2 +- src/tools/goid-tool.c | 2 +- src/tools/iasecc-tool.c | 2 +- src/tools/netkey-tool.c | 2 +- src/tools/npa-tool.c | 2 +- src/tools/openpgp-tool-helpers.c | 2 +- src/tools/openpgp-tool-helpers.h | 2 +- src/tools/openpgp-tool.c | 2 +- src/tools/opensc-asn1.c | 2 +- src/tools/opensc-explorer.c | 2 +- src/tools/opensc-notify.c | 2 +- src/tools/opensc-tool.c | 2 +- src/tools/piv-tool.c | 2 +- src/tools/pkcs11-register.c | 2 +- src/tools/pkcs11-tool.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- src/tools/pkcs15-init.c | 2 +- src/tools/pkcs15-tool.c | 2 +- src/tools/sc-hsm-tool.c | 2 +- src/tools/sceac-example.c | 2 +- src/tools/util.c | 2 +- src/tools/westcos-tool.c | 2 +- src/ui/char_str_from_wchar.h | 2 +- src/ui/invisible_window.h | 2 +- src/ui/notify.c | 2 +- src/ui/notify.h | 2 +- src/ui/strings.c | 2 +- src/ui/strings.h | 2 +- src/ui/wchar_from_char_str.h | 2 +- win32/customactions.cpp | 2 +- 264 files changed, 265 insertions(+), 265 deletions(-) diff --git a/src/common/compat_overflow.c b/src/common/compat_overflow.c index 3a30802b6a..4f64c141cc 100644 --- a/src/common/compat_overflow.c +++ b/src/common/compat_overflow.c @@ -1,5 +1,5 @@ /* - * compat_overflow.h: Reimplementation of GCC/Clang's built-in + * compat_overflow.c: Reimplementation of GCC/Clang's built-in * functions to perform arithmetic with overflow checking * * Copyright (C) Frank Morgner @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H #include "config.h" diff --git a/src/common/compat_overflow.h b/src/common/compat_overflow.h index 14e2b4759a..3133324521 100644 --- a/src/common/compat_overflow.h +++ b/src/common/compat_overflow.h @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __COMPAT_OVERFLOW_H #define __COMPAT_OVERFLOW_H diff --git a/src/common/compat_report_rangecheckfailure.c b/src/common/compat_report_rangecheckfailure.c index f90e87a851..4fb48ec4e5 100644 --- a/src/common/compat_report_rangecheckfailure.c +++ b/src/common/compat_report_rangecheckfailure.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H #include "config.h" diff --git a/src/common/libpkcs11.c b/src/common/libpkcs11.c index ef57347a95..e4b7533039 100644 --- a/src/common/libpkcs11.c +++ b/src/common/libpkcs11.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/common/libpkcs11.h b/src/common/libpkcs11.h index f7cbc95d95..b6bae88f9d 100644 --- a/src/common/libpkcs11.h +++ b/src/common/libpkcs11.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LIBPKCS11_H diff --git a/src/common/libscdl.c b/src/common/libscdl.c index 81feab3309..64ff43c6fb 100644 --- a/src/common/libscdl.c +++ b/src/common/libscdl.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/common/libscdl.h b/src/common/libscdl.h index 983683dde1..b649994620 100644 --- a/src/common/libscdl.h +++ b/src/common/libscdl.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LIBSCDL_H diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index e73aea6064..3c13a6f241 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index fc75d74949..eab9fd5e2b 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/asn1.h b/src/libopensc/asn1.h index 4490eff18f..734c03ad38 100644 --- a/src/libopensc/asn1.h +++ b/src/libopensc/asn1.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_ASN1_H diff --git a/src/libopensc/authentic.h b/src/libopensc/authentic.h index 805ad9c8f2..e6e9cf1c1c 100644 --- a/src/libopensc/authentic.h +++ b/src/libopensc/authentic.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_AUTHENTIC_V3_H diff --git a/src/libopensc/aux-data.c b/src/libopensc/aux-data.c index 7e96e37210..d978d2a179 100644 --- a/src/libopensc/aux-data.c +++ b/src/libopensc/aux-data.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/aux-data.h b/src/libopensc/aux-data.h index 9564bfde2e..173876338b 100644 --- a/src/libopensc/aux-data.h +++ b/src/libopensc/aux-data.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _AUX_DATA_H diff --git a/src/libopensc/base64.c b/src/libopensc/base64.c index 1aa1c941ee..b42e452801 100644 --- a/src/libopensc/base64.c +++ b/src/libopensc/base64.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 9defca7f25..c66ed14b29 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index f40b96d5b2..99f14de1ab 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index ecc1b23abc..057186265b 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 5be9aa1662..3604a19812 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 4064a074d5..2402a06a3e 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* About the Belpic (Belgian Personal Identity Card) card diff --git a/src/libopensc/card-cac-common.c b/src/libopensc/card-cac-common.c index b4e66e9bd3..6a5289c638 100644 --- a/src/libopensc/card-cac-common.c +++ b/src/libopensc/card-cac-common.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-cac-common.h b/src/libopensc/card-cac-common.h index 77f1476104..f3cbd678a6 100644 --- a/src/libopensc/card-cac-common.h +++ b/src/libopensc/card-cac-common.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HAVE_CARD_CAC_COMMON_H diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index b565feeefd..b6fe3a40b8 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -23,7 +23,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 60c979908b..0ba8c1e73d 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -23,7 +23,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 0d8e2651d7..b65a60d7c7 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 3aa1897d6a..3990705fd2 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -21,7 +21,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index a17c2acb56..89a8ec50c2 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c index 36d168463f..a7de0b0189 100644 --- a/src/libopensc/card-dnie.c +++ b/src/libopensc/card-dnie.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define __CARD_DNIE_C__ diff --git a/src/libopensc/card-edo.c b/src/libopensc/card-edo.c index 3306f9c060..8438cbec62 100644 --- a/src/libopensc/card-edo.c +++ b/src/libopensc/card-edo.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index bcc3224961..eb31f71460 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -11,7 +11,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Initially written by Weitao Sun (weitao@ftsafe.com) 2008 */ diff --git a/src/libopensc/card-eoi.c b/src/libopensc/card-eoi.c index bc2d5e6950..1a568f2e9a 100644 --- a/src/libopensc/card-eoi.c +++ b/src/libopensc/card-eoi.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/card-eoi.h b/src/libopensc/card-eoi.h index 3f5da8defb..16abdf0d91 100644 --- a/src/libopensc/card-eoi.h +++ b/src/libopensc/card-eoi.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index f105c77fa1..b2d359668a 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index db2d18e714..fba4e70b79 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 6d636700e7..b860986a8b 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index af802f5f50..6fade6da9d 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -11,7 +11,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Initially written by David Mattes (david.mattes@boeing.com) */ diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index ed122c89cd..b6a0c84647 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* diff --git a/src/libopensc/card-gids.h b/src/libopensc/card-gids.h index 03ab85a2ce..f9ea51ba6c 100644 --- a/src/libopensc/card-gids.h +++ b/src/libopensc/card-gids.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CARD_GIDS_H_ diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 59ab0a531e..c4b446caed 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index dc3b673ead..e5476d7b7a 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index d413b312eb..cd3961406f 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index f3ded62fa9..2784b326c4 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index f17bdb34f8..03a6953e45 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c index 3d8c0f3b07..673923c494 100644 --- a/src/libopensc/card-itacns.c +++ b/src/libopensc/card-itacns.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 79a69f8c9c..4f64fb339f 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-masktech.c b/src/libopensc/card-masktech.c index 3dfdfb34b4..2ee429cd86 100644 --- a/src/libopensc/card-masktech.c +++ b/src/libopensc/card-masktech.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index d54a98cb3d..9702718b89 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index bbdee63b30..a36c2d7c02 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 58782a1b02..4ee4246840 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-npa.c b/src/libopensc/card-npa.c index 658f09e803..98fe43b63a 100644 --- a/src/libopensc/card-npa.c +++ b/src/libopensc/card-npa.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/libopensc/card-npa.h b/src/libopensc/card-npa.h index 9cce7a06af..46b9ae00d1 100644 --- a/src/libopensc/card-npa.h +++ b/src/libopensc/card-npa.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _CARD_NPA_H diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c index b19743257e..4188b20e09 100644 --- a/src/libopensc/card-nqApplet.c +++ b/src/libopensc/card-nqApplet.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index e0a012c5a8..5036ebbdf6 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * best view with tabstop=4 */ diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index e178af7875..40ceef1ea9 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* diff --git a/src/libopensc/card-openpgp.h b/src/libopensc/card-openpgp.h index e76ab99c7b..36a84086bf 100644 --- a/src/libopensc/card-openpgp.h +++ b/src/libopensc/card-openpgp.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _CARD_OPENPGP_H diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index a4fea759e4..428c0fc0fa 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 753b7415bc..7df37a5bea 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 918031957f..5d203b9d1f 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 05ce914b17..8397c717b3 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-sc-hsm.h b/src/libopensc/card-sc-hsm.h index 47620c5cb2..5b2734015d 100644 --- a/src/libopensc/card-sc-hsm.h +++ b/src/libopensc/card-sc-hsm.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SC_HSM_H_ diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 5d72dc126c..92f64c78b2 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-skeid.c b/src/libopensc/card-skeid.c index 02000359ae..573133879f 100644 --- a/src/libopensc/card-skeid.c +++ b/src/libopensc/card-skeid.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * based on card-cardos.c */ diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index a51c4b1e0d..b33c67fca2 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index 8c7eff755a..50f765a068 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 9c10fc8cc6..a0f993f9d3 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 164498a53d..817d2b5199 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 553b282e6b..9ce90ec15e 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_CARDCTL_H diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 3a2350960d..250b4331d0 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_CARDS_H diff --git a/src/libopensc/ccid-types.h b/src/libopensc/ccid-types.h index 59d3cf3fc2..fae0ebdc57 100644 --- a/src/libopensc/ccid-types.h +++ b/src/libopensc/ccid-types.h @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file diff --git a/src/libopensc/compression.c b/src/libopensc/compression.c index 19d1a98493..8535175ec1 100644 --- a/src/libopensc/compression.c +++ b/src/libopensc/compression.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/compression.h b/src/libopensc/compression.h index c27b2d55ab..55885baca2 100644 --- a/src/libopensc/compression.h +++ b/src/libopensc/compression.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef COMPRESSION_H #define COMPRESSION_H diff --git a/src/libopensc/ctbcs.c b/src/libopensc/ctbcs.c index a5d49d3d7d..4376aa14d0 100644 --- a/src/libopensc/ctbcs.c +++ b/src/libopensc/ctbcs.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/ctbcs.h b/src/libopensc/ctbcs.h index 7879eb309e..40c68daf9d 100644 --- a/src/libopensc/ctbcs.h +++ b/src/libopensc/ctbcs.h @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _CTBCS_ diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 27987c3e95..5041dc41df 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index fff0e13df1..8ffaafa8d2 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define __SM_DNIE_C__ diff --git a/src/libopensc/cwa-dnie.h b/src/libopensc/cwa-dnie.h index 2edbf52ba1..b19265a9fe 100644 --- a/src/libopensc/cwa-dnie.h +++ b/src/libopensc/cwa-dnie.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CWADNIE_H__ diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index b8662f4ff1..b4af0dd79e 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define __CWA14890_C__ diff --git a/src/libopensc/cwa14890.h b/src/libopensc/cwa14890.h index 5e9bd870d9..013f4aa883 100644 --- a/src/libopensc/cwa14890.h +++ b/src/libopensc/cwa14890.h @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CWA14890_H__ diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index da3355f519..7648f6860e 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/ef-atr.c b/src/libopensc/ef-atr.c index fec2b68cc1..8265188165 100644 --- a/src/libopensc/ef-atr.c +++ b/src/libopensc/ef-atr.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index 7888fd4954..c7392c09af 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index bd5ed085f3..3d6fbeff76 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/errors.h b/src/libopensc/errors.h index e0330a9324..0f770871e9 100644 --- a/src/libopensc/errors.h +++ b/src/libopensc/errors.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_ERRORS_H diff --git a/src/libopensc/gp.c b/src/libopensc/gp.c index 3abea28a8b..2d69442dc6 100644 --- a/src/libopensc/gp.c +++ b/src/libopensc/gp.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/gp.h b/src/libopensc/gp.h index 3e0ff1c924..e6c91a1fd4 100644 --- a/src/libopensc/gp.h +++ b/src/libopensc/gp.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _LIBOPENSC_GP_H diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index 8a938505e0..b3e567dd54 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/iasecc-sdo.h b/src/libopensc/iasecc-sdo.h index bb9e70c7c6..5787398619 100644 --- a/src/libopensc/iasecc-sdo.h +++ b/src/libopensc/iasecc-sdo.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SC_IASECC_SDO_H diff --git a/src/libopensc/iasecc-sm.c b/src/libopensc/iasecc-sm.c index 4587065035..d469902ab0 100644 --- a/src/libopensc/iasecc-sm.c +++ b/src/libopensc/iasecc-sm.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/iasecc.h b/src/libopensc/iasecc.h index 4e59f69ac2..7362e5d5be 100644 --- a/src/libopensc/iasecc.h +++ b/src/libopensc/iasecc.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_IASECC_H diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 44378a4e48..74014235ac 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SC_INTERNAL_H diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 3dc7acedfc..91a35b93e3 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/libopensc/jpki.h b/src/libopensc/jpki.h index 7d9c22c071..011bf0f883 100644 --- a/src/libopensc/jpki.h +++ b/src/libopensc/jpki.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_JPKI_H diff --git a/src/libopensc/log.c b/src/libopensc/log.c index b5a3f1635b..875c801839 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 790a846289..a670fdb41d 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_LOG_H diff --git a/src/libopensc/muscle-filesystem.c b/src/libopensc/muscle-filesystem.c index e4f43e4bf7..620e2bee66 100644 --- a/src/libopensc/muscle-filesystem.c +++ b/src/libopensc/muscle-filesystem.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/muscle-filesystem.h b/src/libopensc/muscle-filesystem.h index da7d74eb5a..4320aeeb90 100644 --- a/src/libopensc/muscle-filesystem.h +++ b/src/libopensc/muscle-filesystem.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MUSCLE_FILESYSTEM_H diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index 9d01e0c113..d881c137d0 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/muscle.h b/src/libopensc/muscle.h index e87bebc10e..6e656cb869 100644 --- a/src/libopensc/muscle.h +++ b/src/libopensc/muscle.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MUSCLE_H_ #define MUSCLE_H_ diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 2596cdb061..307c246d56 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** diff --git a/src/libopensc/pace.h b/src/libopensc/pace.h index bec5022837..032d5b1152 100644 --- a/src/libopensc/pace.h +++ b/src/libopensc/pace.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PACE_H diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 17745d61a4..2837466992 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index ae355732de..e949ecc2c9 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index a16daffe1f..0e500b643b 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index 6be9c7a64e..298f5f32b8 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c index e4a6219a8c..9faf7cefef 100644 --- a/src/libopensc/pkcs15-cac.c +++ b/src/libopensc/pkcs15-cac.c @@ -24,7 +24,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index a545d056fb..6ebe35a8af 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-cardos.c b/src/libopensc/pkcs15-cardos.c index d6c143fec2..ab33b18265 100644 --- a/src/libopensc/pkcs15-cardos.c +++ b/src/libopensc/pkcs15-cardos.c @@ -20,7 +20,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 1faa9cc771..7c164980cb 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 5d8c8de4a1..54404e22c2 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -23,7 +23,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-data.c b/src/libopensc/pkcs15-data.c index 6dd748888a..63b6b90028 100644 --- a/src/libopensc/pkcs15-data.c +++ b/src/libopensc/pkcs15-data.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-din-66291.c b/src/libopensc/pkcs15-din-66291.c index c8d1530018..2efababb54 100644 --- a/src/libopensc/pkcs15-din-66291.c +++ b/src/libopensc/pkcs15-din-66291.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/src/libopensc/pkcs15-dnie.c b/src/libopensc/pkcs15-dnie.c index 87bf449c30..e59a03f5b4 100644 --- a/src/libopensc/pkcs15-dnie.c +++ b/src/libopensc/pkcs15-dnie.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/pkcs15-eoi.c b/src/libopensc/pkcs15-eoi.c index e39a3b8963..2691e4fd61 100644 --- a/src/libopensc/pkcs15-eoi.c +++ b/src/libopensc/pkcs15-eoi.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index 81f88a471c..84b0db3ea7 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -11,7 +11,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Initially written by Weitao Sun (weitao@ftsafe.com) 2008*/ diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index c7b6586821..4aba469d0a 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-esteid2018.c b/src/libopensc/pkcs15-esteid2018.c index e3076b144d..1f2aa6b815 100644 --- a/src/libopensc/pkcs15-esteid2018.c +++ b/src/libopensc/pkcs15-esteid2018.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index c68393a1f1..0e0a932919 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index add4c3e689..1d238ac0eb 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -11,7 +11,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Initially written by David Mattes */ diff --git a/src/libopensc/pkcs15-gids.c b/src/libopensc/pkcs15-gids.c index 04b57f4e74..66e4a3f45f 100644 --- a/src/libopensc/pkcs15-gids.c +++ b/src/libopensc/pkcs15-gids.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/src/libopensc/pkcs15-iasecc.c b/src/libopensc/pkcs15-iasecc.c index 8c4941b896..1faac3ce3a 100644 --- a/src/libopensc/pkcs15-iasecc.c +++ b/src/libopensc/pkcs15-iasecc.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-idprime.c b/src/libopensc/pkcs15-idprime.c index 05de0d38c0..b3c7c774c8 100644 --- a/src/libopensc/pkcs15-idprime.c +++ b/src/libopensc/pkcs15-idprime.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index c32df51446..4c9fb5f329 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* diff --git a/src/libopensc/pkcs15-jpki.c b/src/libopensc/pkcs15-jpki.c index da2f8997e5..6be0e5049d 100644 --- a/src/libopensc/pkcs15-jpki.c +++ b/src/libopensc/pkcs15-jpki.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-nqApplet.c b/src/libopensc/pkcs15-nqApplet.c index ec15f0e521..37103389c0 100644 --- a/src/libopensc/pkcs15-nqApplet.c +++ b/src/libopensc/pkcs15-nqApplet.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c index 248699dc45..ab2aacb0d2 100644 --- a/src/libopensc/pkcs15-oberthur.c +++ b/src/libopensc/pkcs15-oberthur.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 9d3fd746a0..20fc20e639 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 48e16fdc1c..80a185fecd 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 97eeb15aeb..266136335d 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -21,7 +21,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index 7609e5ee49..909e34c300 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index 1f4ca4531e..df05465aaf 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Based on the PKCS#15 emulation layer for EstEID card by Martin Paljak * diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index e53a6d41af..4a0ddffbeb 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-sc-hsm.c b/src/libopensc/pkcs15-sc-hsm.c index 56119b2522..7dbc748342 100644 --- a/src/libopensc/pkcs15-sc-hsm.c +++ b/src/libopensc/pkcs15-sc-hsm.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index f408556af4..7c3a39432f 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-skeid.c b/src/libopensc/pkcs15-skeid.c index 54b65e6e4d..b747941fa2 100644 --- a/src/libopensc/pkcs15-skeid.c +++ b/src/libopensc/pkcs15-skeid.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * based on the PKCS15 emulation layer for EstEID card by Martin Paljak */ diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c index 4e58355ad7..8d9fbcaf18 100644 --- a/src/libopensc/pkcs15-skey.c +++ b/src/libopensc/pkcs15-skey.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "internal.h" #include "pkcs15.h" diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index 75c409503f..c79f0fa7a2 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-starcos-esign.c b/src/libopensc/pkcs15-starcos-esign.c index 62322eca1b..9af8de4ab1 100644 --- a/src/libopensc/pkcs15-starcos-esign.c +++ b/src/libopensc/pkcs15-starcos-esign.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 520952d90d..fb082e2072 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h index d4964ca6d1..5d32718113 100644 --- a/src/libopensc/pkcs15-syn.h +++ b/src/libopensc/pkcs15-syn.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PKCS15_SYN_H diff --git a/src/libopensc/pkcs15-tccardos.c b/src/libopensc/pkcs15-tccardos.c index 08d2fc12d3..a86633e9de 100644 --- a/src/libopensc/pkcs15-tccardos.c +++ b/src/libopensc/pkcs15-tccardos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 15fe522064..a5666c9b78 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15-westcos.c b/src/libopensc/pkcs15-westcos.c index 1e6d7f1d62..c1ca80a353 100644 --- a/src/libopensc/pkcs15-westcos.c +++ b/src/libopensc/pkcs15-westcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 39117ed2d0..a8f91ddf33 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index ba685a30f0..a065e1478d 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_PKCS15_H diff --git a/src/libopensc/reader-cryptotokenkit.m b/src/libopensc/reader-cryptotokenkit.m index 1bf85bfc5d..848216b23a 100644 --- a/src/libopensc/reader-cryptotokenkit.m +++ b/src/libopensc/reader-cryptotokenkit.m @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index 5ca8c04d4d..eb2ee4000e 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index c28e45f54c..958476b4b2 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 8c2f98c9b1..9e35bac60b 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/reader-tr03119.c b/src/libopensc/reader-tr03119.c index 0a425a50fb..1c1de3db40 100644 --- a/src/libopensc/reader-tr03119.c +++ b/src/libopensc/reader-tr03119.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "reader-tr03119.h" diff --git a/src/libopensc/reader-tr03119.h b/src/libopensc/reader-tr03119.h index d8f60a2034..8c8db27eb5 100644 --- a/src/libopensc/reader-tr03119.h +++ b/src/libopensc/reader-tr03119.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _READER_TR03119_H diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 942de1175f..df0cebbce2 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SC_OSSL_COMPAT_H diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index f6afcd1c2c..946ed6f7be 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 894c55eba8..c4b9801270 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/simpletlv.c b/src/libopensc/simpletlv.c index 18799253fe..12c8bf6a79 100644 --- a/src/libopensc/simpletlv.c +++ b/src/libopensc/simpletlv.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/simpletlv.h b/src/libopensc/simpletlv.h index 6bcd4f0856..df094d2f40 100644 --- a/src/libopensc/simpletlv.h +++ b/src/libopensc/simpletlv.h @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_SIMPLETLV_H diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c index 877a5ef120..9839b3d834 100644 --- a/src/libopensc/sm.c +++ b/src/libopensc/sm.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/libopensc/sm.h b/src/libopensc/sm.h index fb5637e3cc..a49dcac7e9 100644 --- a/src/libopensc/sm.h +++ b/src/libopensc/sm.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SM_H diff --git a/src/libopensc/types.h b/src/libopensc/types.h index af4ced71bd..878ace7842 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_TYPES_H diff --git a/src/minidriver/cardmod-mingw-compat.h b/src/minidriver/cardmod-mingw-compat.h index 2bf01a7f37..e66d90b955 100644 --- a/src/minidriver/cardmod-mingw-compat.h +++ b/src/minidriver/cardmod-mingw-compat.h @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define __deref diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index de84f49edf..a78a757b4d 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* diff --git a/src/pkcs11/debug.c b/src/pkcs11/debug.c index 3e823934be..582285a2e2 100644 --- a/src/pkcs11/debug.c +++ b/src/pkcs11/debug.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 315f9cb784..08e85903e7 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/framework-pkcs15init.c b/src/pkcs11/framework-pkcs15init.c index 1883e6b985..52205c5a20 100644 --- a/src/pkcs11/framework-pkcs15init.c +++ b/src/pkcs11/framework-pkcs15init.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index ca1936006e..39ec464f68 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 642338b4bb..499b41ae1b 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 736423537c..48d382dbcb 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index f9e44834ba..9a4f2188f9 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 5e31530253..cc6510f434 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index b38016f24b..eed4c850a8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index b7c31c4cb3..f04c0b4c56 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c index 68b6c57b8d..cc48c83b9d 100644 --- a/src/pkcs11/pkcs11-session.c +++ b/src/pkcs11/pkcs11-session.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index fa407fbf1f..a5877cc3e7 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 4a8dac8de6..c0c5af7377 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __sc_pkcs11_h__ diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c index 86cb3b884b..0020a4002d 100644 --- a/src/pkcs11/slot.c +++ b/src/pkcs11/slot.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index bc0efb5ce6..761f6dee8f 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index c6894dd374..1a8b9d7d55 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index f41f73c349..540f3e0be3 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 1cb55c1507..d06568073d 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 07fdd57f68..986f120b02 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -11,7 +11,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Initially written by Weitao Sun (weitao@ftsafe.com) 2008*/ /* Disable RSA:512bits by Shengchao Niu (shengchao@ftsafe.com) 2012 */ diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index 91d406c022..e70bbf8733 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-gids.c b/src/pkcs15init/pkcs15-gids.c index df1bc93b06..b40ab61aed 100644 --- a/src/pkcs15init/pkcs15-gids.c +++ b/src/pkcs15init/pkcs15-gids.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index afca72d171..952dbd3d76 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index ac3c900aec..0066b0852e 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/pkcs15init/pkcs15-iasecc.h b/src/pkcs15init/pkcs15-iasecc.h index 65ee0eae86..7b81e41f00 100644 --- a/src/pkcs15init/pkcs15-iasecc.h +++ b/src/pkcs15init/pkcs15-iasecc.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef pkcs15_iasecc_h diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index c031342d4a..db6d89d6a5 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 77a518682b..6312fe758f 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PKCS15_INIT_H diff --git a/src/pkcs15init/pkcs15-isoApplet.c b/src/pkcs15init/pkcs15-isoApplet.c index 5e4dd7da57..632989d142 100644 --- a/src/pkcs15init/pkcs15-isoApplet.c +++ b/src/pkcs15init/pkcs15-isoApplet.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index c840df8cff..700c61739c 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -26,7 +26,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index ef821c73df..81eb0f2acb 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index ecf09ea3b3..74e2c72f75 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 2e74325786..00768a0b7e 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * best view with tabstop=4 * diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 990aa9c7d2..e61377501e 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pkcs15-oberthur.h" diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c index 3e060be5a4..d7259f2d35 100644 --- a/src/pkcs15init/pkcs15-openpgp.c +++ b/src/pkcs15init/pkcs15-openpgp.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 843448af14..0378937340 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 856ff7c113..2cab2fe9b8 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-sc-hsm.c b/src/pkcs15init/pkcs15-sc-hsm.c index fa57ce1dd4..cd63197c4f 100644 --- a/src/pkcs15init/pkcs15-sc-hsm.c +++ b/src/pkcs15init/pkcs15-sc-hsm.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 52b234fa2f..450ad595fa 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index ff89d1224c..e915baf16c 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 6f55c90744..8cbe94c1b8 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index fe1b46e66f..3358d6c515 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Random notes * - the "key" command should go away, it's obsolete diff --git a/src/pkcs15init/profile.h b/src/pkcs15init/profile.h index ad538ed621..2d27b161c0 100644 --- a/src/pkcs15init/profile.h +++ b/src/pkcs15init/profile.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _OPENSC_PROFILE_H diff --git a/src/scconf/internal.h b/src/scconf/internal.h index a795784ef3..97d1ddf0b2 100644 --- a/src/scconf/internal.h +++ b/src/scconf/internal.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SCCONF_INTERNAL_H diff --git a/src/scconf/lex-parse.l b/src/scconf/lex-parse.l index 39b5ffe959..81f2d63529 100644 --- a/src/scconf/lex-parse.l +++ b/src/scconf/lex-parse.l @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/scconf/parse.c b/src/scconf/parse.c index e02daf4296..8358496d2d 100644 --- a/src/scconf/parse.c +++ b/src/scconf/parse.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/scconf/scconf.c b/src/scconf/scconf.c index aaa3fb1c00..a7795cfbfb 100644 --- a/src/scconf/scconf.c +++ b/src/scconf/scconf.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/scconf/scconf.h b/src/scconf/scconf.h index f6cdd9f53b..083e79916e 100644 --- a/src/scconf/scconf.h +++ b/src/scconf/scconf.h @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SC_CONF_H diff --git a/src/scconf/sclex.c b/src/scconf/sclex.c index ff6cc1777c..55a6702d99 100644 --- a/src/scconf/sclex.c +++ b/src/scconf/sclex.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/scconf/write.c b/src/scconf/write.c index 7ef3a2d706..2992419543 100644 --- a/src/scconf/write.c +++ b/src/scconf/write.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index c488c50e33..d9f335e687 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/sm/sm-common.h b/src/sm/sm-common.h index 750c38b9a0..16be17ac47 100644 --- a/src/sm/sm-common.h +++ b/src/sm/sm-common.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SM_COMMON_H diff --git a/src/sm/sm-eac.c b/src/sm/sm-eac.c index ea1256bb9a..7ddbc605dc 100644 --- a/src/sm/sm-eac.c +++ b/src/sm/sm-eac.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/sm/sm-eac.h b/src/sm/sm-eac.h index 54dd387168..dff65aa4f7 100644 --- a/src/sm/sm-eac.h +++ b/src/sm/sm-eac.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file diff --git a/src/sm/sm-iso-internal.h b/src/sm/sm-iso-internal.h index 43650340a1..8f3d7e22df 100644 --- a/src/sm/sm-iso-internal.h +++ b/src/sm/sm-iso-internal.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file diff --git a/src/sm/sm-iso.c b/src/sm/sm-iso.c index 7d9a79c98d..226d1cee88 100644 --- a/src/sm/sm-iso.c +++ b/src/sm/sm-iso.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/sm/sm-iso.h b/src/sm/sm-iso.h index 8d166a12f1..88a2778696 100644 --- a/src/sm/sm-iso.h +++ b/src/sm/sm-iso.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file diff --git a/src/sm/sslutil.h b/src/sm/sslutil.h index 5752aa5134..2b194a77ab 100644 --- a/src/sm/sslutil.h +++ b/src/sm/sslutil.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SC_SSLUTIL_H #define _SC_SSLUTIL_H diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c index a58ff5d4c5..e458a21c48 100644 --- a/src/smm/sm-card-authentic.c +++ b/src/smm/sm-card-authentic.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/smm/sm-card-iasecc.c b/src/smm/sm-card-iasecc.c index 83538e4e10..bd7e07ee8b 100644 --- a/src/smm/sm-card-iasecc.c +++ b/src/smm/sm-card-iasecc.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/smm/sm-cwa14890.c b/src/smm/sm-cwa14890.c index 3d58ddad1b..47bc7a7e7f 100644 --- a/src/smm/sm-cwa14890.c +++ b/src/smm/sm-cwa14890.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/smm/sm-global-platform.c b/src/smm/sm-global-platform.c index a8f8a8bc94..6c16e910b8 100644 --- a/src/smm/sm-global-platform.c +++ b/src/smm/sm-global-platform.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/smm/sm-module.h b/src/smm/sm-module.h index 4d11ee994d..64c3326338 100644 --- a/src/smm/sm-module.h +++ b/src/smm/sm-module.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SM_MODULE_H diff --git a/src/smm/smm-local.c b/src/smm/smm-local.c index c923c89d97..3a84fa4253 100644 --- a/src/smm/smm-local.c +++ b/src/smm/smm-local.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H diff --git a/src/tests/fuzzing/fuzz_asn1_print.c b/src/tests/fuzzing/fuzz_asn1_print.c index 974923476c..b6ebdd549c 100644 --- a/src/tests/fuzzing/fuzz_asn1_print.c +++ b/src/tests/fuzzing/fuzz_asn1_print.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/tests/fuzzing/fuzz_asn1_sig_value.c b/src/tests/fuzzing/fuzz_asn1_sig_value.c index 98914152e2..db17aee6cf 100644 --- a/src/tests/fuzzing/fuzz_asn1_sig_value.c +++ b/src/tests/fuzzing/fuzz_asn1_sig_value.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c index e5758ba4d5..f359cfe381 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_decode.c +++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/tests/fuzzing/fuzz_pkcs15_reader.c b/src/tests/fuzzing/fuzz_pkcs15_reader.c index 36ed08a4e7..a790097781 100644 --- a/src/tests/fuzzing/fuzz_pkcs15_reader.c +++ b/src/tests/fuzzing/fuzz_pkcs15_reader.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/tests/fuzzing/fuzzer_reader.c b/src/tests/fuzzing/fuzzer_reader.c index aea171aaa1..8fbd6ef647 100644 --- a/src/tests/fuzzing/fuzzer_reader.c +++ b/src/tests/fuzzing/fuzzer_reader.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "fuzzer_reader.h" diff --git a/src/tests/fuzzing/fuzzer_reader.h b/src/tests/fuzzing/fuzzer_reader.h index 5441deac7a..89e40db7bf 100644 --- a/src/tests/fuzzing/fuzzer_reader.h +++ b/src/tests/fuzzing/fuzzer_reader.h @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FUZZER_READER_H diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index 039457395e..40dc054982 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index d28dd9ba02..1a1c8e37e9 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/dnie-tool.c b/src/tools/dnie-tool.c index cafe854318..9e7484ec9c 100644 --- a/src/tools/dnie-tool.c +++ b/src/tools/dnie-tool.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/egk-tool.c b/src/tools/egk-tool.c index b3a8365ec5..d98ecf854e 100644 --- a/src/tools/egk-tool.c +++ b/src/tools/egk-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index 1297482c36..3caac3d1d2 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/fread_to_eof.c b/src/tools/fread_to_eof.c index a563e46ffc..12f07e8ce9 100644 --- a/src/tools/fread_to_eof.c +++ b/src/tools/fread_to_eof.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/fread_to_eof.h b/src/tools/fread_to_eof.h index 7f5520fe41..cb52a20729 100644 --- a/src/tools/fread_to_eof.h +++ b/src/tools/fread_to_eof.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _FREAD_TO_EOF_H #define _FREAD_TO_EOF_H diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index 5765472e9c..ac81e31358 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/tools/goid-tool.c b/src/tools/goid-tool.c index e6a3bd041d..309768cef5 100644 --- a/src/tools/goid-tool.c +++ b/src/tools/goid-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/iasecc-tool.c b/src/tools/iasecc-tool.c index 301ad89d0a..8d970e646b 100644 --- a/src/tools/iasecc-tool.c +++ b/src/tools/iasecc-tool.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index f43fced329..5e66322791 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/npa-tool.c b/src/tools/npa-tool.c index cdec50efa3..ca79342318 100644 --- a/src/tools/npa-tool.c +++ b/src/tools/npa-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/openpgp-tool-helpers.c b/src/tools/openpgp-tool-helpers.c index 082b0e474b..c29b4ad288 100644 --- a/src/tools/openpgp-tool-helpers.c +++ b/src/tools/openpgp-tool-helpers.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/openpgp-tool-helpers.h b/src/tools/openpgp-tool-helpers.h index 1c47b6e207..d2986ef0b1 100644 --- a/src/tools/openpgp-tool-helpers.h +++ b/src/tools/openpgp-tool-helpers.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef OPENPGP_TOOL_HELPERS_H diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c index 5f9451b6d3..70732c18e2 100644 --- a/src/tools/openpgp-tool.c +++ b/src/tools/openpgp-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/opensc-asn1.c b/src/tools/opensc-asn1.c index 18ca680349..a26e94fc23 100644 --- a/src/tools/opensc-asn1.c +++ b/src/tools/opensc-asn1.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 5ff65cd0d9..8fd1e0e684 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/opensc-notify.c b/src/tools/opensc-notify.c index 1f153f2a4a..7e72e91506 100644 --- a/src/tools/opensc-notify.c +++ b/src/tools/opensc-notify.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index eebe87bf40..ec9af08428 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 1793a2a327..c1ca1356d8 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/pkcs11-register.c b/src/tools/pkcs11-register.c index ab86ef87b7..cf93ad6a74 100644 --- a/src/tools/pkcs11-register.c +++ b/src/tools/pkcs11-register.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1e9bf4bff5..3fb8a191ce 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index f714f037b8..2701979b33 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index f8a62c442f..f2dd971a88 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -26,7 +26,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 3d911ef0c9..831018393d 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 0c64e03f6c..004f2007ac 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/sceac-example.c b/src/tools/sceac-example.c index f3875c184d..27134d2044 100644 --- a/src/tools/sceac-example.c +++ b/src/tools/sceac-example.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* This example shows how to use the library functions perform_pace to diff --git a/src/tools/util.c b/src/tools/util.c index 3bb95bcfac..1baa5f2fa1 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index dd4e00bee4..771fa929d4 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/src/ui/char_str_from_wchar.h b/src/ui/char_str_from_wchar.h index 270251c0dd..b0b584673d 100644 --- a/src/ui/char_str_from_wchar.h +++ b/src/ui/char_str_from_wchar.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/ui/invisible_window.h b/src/ui/invisible_window.h index bf20dfc8e3..f7f0121111 100644 --- a/src/ui/invisible_window.h +++ b/src/ui/invisible_window.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff --git a/src/ui/notify.c b/src/ui/notify.c index 897ea21ca3..9aadc6d155 100644 --- a/src/ui/notify.c +++ b/src/ui/notify.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if HAVE_CONFIG_H diff --git a/src/ui/notify.h b/src/ui/notify.h index 859d8084db..19dfddb275 100644 --- a/src/ui/notify.h +++ b/src/ui/notify.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _NOTIFY_H diff --git a/src/ui/strings.c b/src/ui/strings.c index 90dbc0f964..b06434b9ec 100644 --- a/src/ui/strings.c +++ b/src/ui/strings.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libopensc/internal.h" diff --git a/src/ui/strings.h b/src/ui/strings.h index 488dd62c54..1139193965 100644 --- a/src/ui/strings.h +++ b/src/ui/strings.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SC_STRINGS_H diff --git a/src/ui/wchar_from_char_str.h b/src/ui/wchar_from_char_str.h index 359f16da2f..72fe517534 100644 --- a/src/ui/wchar_from_char_str.h +++ b/src/ui/wchar_from_char_str.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ static WCHAR *wchar_from_char_str(const char *in) diff --git a/win32/customactions.cpp b/win32/customactions.cpp index 6a544bd3cf..b4e1f32f96 100644 --- a/win32/customactions.cpp +++ b/win32/customactions.cpp @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* From 874d6d6c5b03faf2b39c17ebec0915846dca1d13 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Jun 2023 16:50:22 +0200 Subject: [PATCH 2986/4321] fixed CID 13698 (#1 of 1): Dereference after null check (FORWARD_NULL) --- src/libopensc/asn1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index eab9fd5e2b..c7dcc1a866 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -2098,6 +2098,8 @@ sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src) return SC_ERROR_INVALID_ARGUMENTS; memset(dst, 0, sizeof(*dst)); if (src->len) { + if (!src->value) + return SC_ERROR_INVALID_ARGUMENTS; dst->value = malloc(src->len); if (!dst->value) return SC_ERROR_OUT_OF_MEMORY; From 1f38417591db37ec9a4fbc8a3c1f3b02c4ae2596 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Jun 2023 17:12:57 +0200 Subject: [PATCH 2987/4321] fixed CID 13779 (#1-2 of 2): Resource leak (RESOURCE_LEAK) --- src/sm/sm-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index d9f335e687..bfe4703b2e 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -563,6 +563,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); if (!EVP_EncryptInit_ex2(cctx, alg, key, icv, NULL)) { free(*out); + free(data); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); @@ -571,6 +572,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, EVP_CIPHER_CTX_set_padding(cctx, 0); if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) { free(*out); + free(data); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); @@ -579,6 +581,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { free(*out); + free(data); EVP_CIPHER_CTX_free(cctx); sc_evp_cipher_free(alg); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); From d053b293eefed007cf712d49eb8b8a91a80667ea Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 26 Jun 2023 17:17:44 +0200 Subject: [PATCH 2988/4321] fixed CID 13829 (#1 of 1): Resource leak (RESOURCE_LEAK) --- src/sm/sm-common.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c index bfe4703b2e..05d8776d2a 100644 --- a/src/sm/sm-common.c +++ b/src/sm/sm-common.c @@ -444,16 +444,18 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, EVP_CIPHER *alg = NULL; int tmplen; #endif + size_t decrypted_len; + unsigned char *decrypted; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_SM); if (!out || !out_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "SM decrypt_des_cbc3: invalid input arguments"); - *out_len = data_len + 7; - *out_len -= *out_len % 8; + decrypted_len = data_len + 7; + decrypted_len -= decrypted_len % 8; - *out = malloc(*out_len); - if (!(*out)) + decrypted = malloc(decrypted_len); + if (!(decrypted)) LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM decrypt_des_cbc3: allocation error"); #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -465,33 +467,38 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, for (st=0; st Date: Tue, 27 Jun 2023 00:00:37 +0200 Subject: [PATCH 2989/4321] Starcos: removed handling of cached file path The logic is unused since d85ac12a7b fixes CID 379259 (#4 of 4): 'Constant' variable guards dead code (DEADCODE) --- src/libopensc/card-starcos.c | 118 ++++------------------------------- 1 file changed, 11 insertions(+), 107 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index b33c67fca2..4fa517e121 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -933,9 +933,6 @@ static int starcos_select_file(sc_card_t *card, int r, pathtype; size_t i, pathlen; char pbuf[SC_MAX_PATH_STRING_SIZE]; - /* option for path caching, it is deactivated by default, - but it can be enabled by setting cache_valid to option: card->cache.valid */ - int cache_valid = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -944,11 +941,9 @@ static int starcos_select_file(sc_card_t *card, pbuf[0] = '\0'; sc_log(card->ctx, - "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", + "current path (%s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n", card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ? - "aid" : "path", - cache_valid ? "valid" : "invalid", pbuf, - card->cache.current_path.len); + "aid" : "path", pbuf, card->cache.current_path.len); if ( in_path->len > sizeof(pathbuf) ) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); @@ -966,13 +961,8 @@ static int starcos_select_file(sc_card_t *card, pathlen = in_path->aid.len; pathtype = SC_PATH_TYPE_DF_NAME; } else { - if (!cache_valid - || card->cache.current_path.type != SC_PATH_TYPE_DF_NAME - || card->cache.current_path.len != pathlen - || memcmp(card->cache.current_path.value, in_path->aid.value, in_path->aid.len) != 0 ) { - r = starcos_select_aid(card, in_path->aid.value, in_path->aid.len, NULL); - LOG_TEST_RET(card->ctx, r, "Could not select AID!"); - } + r = starcos_select_aid(card, in_path->aid.value, in_path->aid.len, NULL); + LOG_TEST_RET(card->ctx, r, "Could not select AID!"); if (pathtype == SC_PATH_TYPE_DF_NAME) { pathtype = SC_PATH_TYPE_FILE_ID; @@ -991,24 +981,12 @@ static int starcos_select_file(sc_card_t *card, else if (pathtype == SC_PATH_TYPE_DF_NAME) { /* SELECT DF with AID */ /* Select with 1-16byte Application-ID */ - if (cache_valid - && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME - && card->cache.current_path.len == pathlen - && memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 ) - { - sc_log(card->ctx, "cache hit\n"); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); - } - else - { - r = starcos_select_aid(card, pathbuf, pathlen, file_out); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); - } + r = starcos_select_aid(card, pathbuf, pathlen, file_out); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } else if (pathtype == SC_PATH_TYPE_PATH) { u8 n_pathbuf[SC_MAX_PATH_SIZE]; - int bMatch = -1; /* Select with path (sequence of File-IDs) */ /* Starcos (S 2.1 and SPK 2.3) only supports one @@ -1034,87 +1012,13 @@ static int starcos_select_file(sc_card_t *card, } } - /* check current working directory */ - if (cache_valid - && card->cache.current_path.type == SC_PATH_TYPE_PATH - && card->cache.current_path.len >= 2 - && card->cache.current_path.len <= pathlen ) - { - bMatch = 0; - for (i=0; i < card->cache.current_path.len; i+=2) - if (card->cache.current_path.value[i] == path[i] - && card->cache.current_path.value[i+1] == path[i+1] ) - bMatch += 2; - - if ((IS_V3x(card)) - && bMatch > 0 && (size_t) bMatch < card->cache.current_path.len) { - /* we're in the wrong folder, start traversing from root */ - bMatch = 0; - card->cache.current_path.len = 0; - } - } - - if ( cache_valid && bMatch >= 0 ) - { - if ( pathlen - bMatch == 2 ) - { - /* we are in the right directory */ - r = starcos_select_fid(card, path[bMatch], path[bMatch+1], file_out, 1); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); - } - else if ( pathlen - bMatch > 2 ) - { - /* two more steps to go */ - sc_path_t new_path; - - /* first step: change directory */ - r = starcos_select_fid(card, path[bMatch], path[bMatch+1], NULL, 0); - LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); - - memset(&new_path, 0, sizeof(sc_path_t)); - new_path.type = SC_PATH_TYPE_PATH; - new_path.len = pathlen - bMatch-2; - memcpy(new_path.value, &(path[bMatch+2]), new_path.len); - /* final step: select file */ - r = starcos_select_file(card, &new_path, file_out); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); - } - else /* if (bMatch - pathlen == 0) */ - { - /* done: we are already in the - * requested directory */ - sc_log(card->ctx, - "cache hit\n"); - /* copy file info (if necessary) */ - if (file_out) { - sc_file_t *file = sc_file_new(); - if (!file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - file->id = (path[pathlen-2] << 8) + - path[pathlen-1]; - file->path = card->cache.current_path; - file->type = SC_FILE_TYPE_DF; - file->ef_structure = SC_FILE_EF_UNKNOWN; - file->size = 0; - file->namelen = 0; - file->magic = SC_FILE_MAGIC; - *file_out = file; - } - /* nothing left to do */ - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); - } - } - else + for ( i=0; ictx, r, "SELECT FILE (DF-ID) failed"); - } - r = starcos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out, 1); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + r = starcos_select_fid(card, path[i], path[i+1], NULL, 0); + LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed"); } + r = starcos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out, 1); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } else SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); From 98f640c49a34895a3071bdf5a4172b6969befe5e Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Jun 2023 00:12:22 +0200 Subject: [PATCH 2990/4321] piv-tool: fixed CID 380538 (#1 of 1): Out-of-bounds read (OVERRUN) --- src/tools/piv-tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index c1ca1356d8..d5b7377090 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -507,7 +507,7 @@ static int gen_key(const char * key_info) EC_POINT_free(ecpoint); if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, sizeof(group_name)) != 1 || + OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name)) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { OSSL_PARAM_BLD_free(bld); From 9628e06ad70def92aaa776217164fac57791d123 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 27 Jun 2023 00:15:59 +0200 Subject: [PATCH 2991/4321] sc-hsm: fixed CID 383006 (#1 of 1): Unchecked return value (CHECKED_RETURN) --- src/libopensc/card-sc-hsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 8397c717b3..920093b2a8 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1202,7 +1202,7 @@ static int sc_hsm_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) * this for `opensc-tool --serial` to avoid unnecessary card commands * in all other cases. */ sc_pkcs15_card_t *p15card = NULL; - sc_pkcs15_bind(card, NULL, &p15card); + (void)sc_pkcs15_bind(card, NULL, &p15card); sc_pkcs15_unbind(p15card); } From 235100b57a6a9774b5c478b33105c4891a99a822 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 08:17:30 +0200 Subject: [PATCH 2992/4321] asepcos: implemented logout --- src/libopensc/card-asepcos.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index f40b96d5b2..48d1262576 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -1050,6 +1050,20 @@ static int asepcos_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } +static int asepcos_logout(sc_card_t *card) +{ + int r = SC_ERROR_NOT_SUPPORTED; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (card->type == SC_CARD_TYPE_ASEPCOS_JAVA) { + /* in case of a Java card try to select the ASEPCOS applet */ + r = asepcos_select_asepcos_applet(card); + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver * sc_get_driver(void) { if (iso_ops == NULL) @@ -1066,6 +1080,7 @@ static struct sc_card_driver * sc_get_driver(void) asepcos_ops.list_files = asepcos_list_files; asepcos_ops.card_ctl = asepcos_card_ctl; asepcos_ops.pin_cmd = asepcos_pin_cmd; + asepcos_ops.logout = asepcos_logout; asepcos_ops.card_reader_lock_obtained = asepcos_card_reader_lock_obtained; return &asepcos_drv; From 0680d741fdc192092900e1df10377e39fadbd71a Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 08:24:46 +0200 Subject: [PATCH 2993/4321] authentic: implemented logout --- src/libopensc/card-authentic.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c index 5be9aa1662..d580f7a20b 100644 --- a/src/libopensc/card-authentic.c +++ b/src/libopensc/card-authentic.c @@ -2314,6 +2314,17 @@ authentic_sm_get_wrapped_apdu(struct sc_card *card, struct sc_apdu *plain, struc } #endif +int authentic_logout(sc_card_t *card) +{ + int r = SC_ERROR_NOT_SUPPORTED; + + if (card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { + r = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); + } + + return r; +} + static struct sc_card_driver * sc_get_driver(void) { From 5e29488193e3deae4b0a3b16fb374179bbb87741 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 09:21:29 +0200 Subject: [PATCH 2994/4321] CAC: implemented logout --- src/libopensc/card-cac.c | 7 +++++++ src/libopensc/card-cac1.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index b565feeefd..e16a2e27d4 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1852,6 +1852,12 @@ static int cac_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +static int cac_logout(sc_card_t *card) +{ + int index; + return cac_find_first_pki_applet(card, &index); +} + static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { /* CAC, like PIV needs Extra validation of (new) PIN during @@ -1923,6 +1929,7 @@ static struct sc_card_driver * sc_get_driver(void) cac_ops.decipher = cac_decipher; cac_ops.card_ctl = cac_card_ctl; cac_ops.pin_cmd = cac_pin_cmd; + cac_ops.logout = cac_logout; return &cac_drv; } diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 60c979908b..55adc9bd07 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -519,6 +519,12 @@ static int cac_init(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } +static int cac_logout(sc_card_t *card) +{ + int index; + return cac_find_first_pki_applet(card, &index); +} + static struct sc_card_operations cac_ops; static struct sc_card_driver cac1_drv = { @@ -540,6 +546,7 @@ static struct sc_card_driver * sc_get_driver(void) cac_ops.select_file = cac_select_file; /* need to record object type */ cac_ops.read_binary = cac_read_binary; + cac_ops.logout = cac_logout; return &cac1_drv; } From ed50ea144baba972a9efb930f1a1d1e71085c4d2 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 09:33:01 +0200 Subject: [PATCH 2995/4321] EDO: implemented logout --- src/libopensc/card-edo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libopensc/card-edo.c b/src/libopensc/card-edo.c index 3306f9c060..54419e4b95 100644 --- a/src/libopensc/card-edo.c +++ b/src/libopensc/card-edo.c @@ -302,6 +302,12 @@ static int edo_init(sc_card_t* card) { } +static int edo_logout(sc_card_t* card) { + sc_sm_stop(card); + return edo_unlock(card); +} + + struct sc_card_driver* sc_get_edo_driver(void) { edo_ops = *sc_get_iso7816_driver()->ops; edo_ops.match_card = edo_match_card; @@ -309,6 +315,7 @@ struct sc_card_driver* sc_get_edo_driver(void) { edo_ops.select_file = edo_select_file; edo_ops.set_security_env = edo_set_security_env; edo_ops.compute_signature = edo_compute_signature; + edo_ops.logout = edo_logout; return &edo_drv; } From 1f5c47ab9854d1a323e8e5899f4a5cce1d8e631f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 09:46:28 +0200 Subject: [PATCH 2996/4321] epass2003: implemented logout --- src/libopensc/card-epass2003.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index f105c77fa1..6ae968a9fb 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -3446,6 +3446,23 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries return r; } +static int +epass2003_logout(struct sc_card *card) +{ + epass2003_exdata *exdata = NULL; + + if (!card->drv_data) + return SC_ERROR_INVALID_ARGUMENTS; + + exdata = (epass2003_exdata *)card->drv_data; + if (exdata->sm) { + sc_sm_stop(card); + return epass2003_refresh(card); + } + + return SC_ERROR_NOT_SUPPORTED; +} + static struct sc_card_driver *sc_get_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -3475,6 +3492,7 @@ static struct sc_card_driver *sc_get_driver(void) epass2003_ops.pin_cmd = epass2003_pin_cmd; epass2003_ops.check_sw = epass2003_check_sw; epass2003_ops.get_challenge = epass2003_get_challenge; + epass2003_ops.logout = epass2003_logout; return &epass2003_drv; } From b8d9b01b22bc5436534a5ad68f339cdb74be3b16 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 09:48:11 +0200 Subject: [PATCH 2997/4321] esteid2018: implemented logout --- src/libopensc/card-esteid2018.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libopensc/card-esteid2018.c b/src/libopensc/card-esteid2018.c index db2d18e714..fd58d6b846 100644 --- a/src/libopensc/card-esteid2018.c +++ b/src/libopensc/card-esteid2018.c @@ -306,6 +306,10 @@ static int esteid_finish(sc_card_t *card) { return 0; } +static int esteid_logout(sc_card_t *card) { + return gp_select_aid(card, &IASECC_AID); +} + struct sc_card_driver *sc_get_esteid2018_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -323,6 +327,7 @@ struct sc_card_driver *sc_get_esteid2018_driver(void) { esteid_ops.set_security_env = esteid_set_security_env; esteid_ops.compute_signature = esteid_compute_signature; esteid_ops.pin_cmd = esteid_pin_cmd; + esteid_ops.logout = esteid_logout; return &esteid2018_driver; } From d7e4eddf4cc7f61b05f4bb9f28eb4bcf4412cf67 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 09:49:39 +0200 Subject: [PATCH 2998/4321] gemsafev1: implemented logout --- src/libopensc/card-gemsafeV1.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index af802f5f50..78e7c5068a 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -582,6 +582,13 @@ static int gemsafe_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } +static int gemsafe_logout(sc_card_t *card) +{ + gemsafe_exdata *exdata = (gemsafe_exdata *)card->drv_data; + + return gp_select_applet(card, exdata->aid, exdata->aid_len); +} + static struct sc_card_driver *sc_get_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -602,6 +609,7 @@ static struct sc_card_driver *sc_get_driver(void) gemsafe_ops.process_fci = gemsafe_process_fci; gemsafe_ops.pin_cmd = iso_ops->pin_cmd; gemsafe_ops.card_reader_lock_obtained = gemsafe_card_reader_lock_obtained; + gemsafe_ops.logout = gemsafe_logout; return &gemsafe_drv; } From 8e40e2f89aef5681fcffb069edd3a836d77aa627 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:16:44 +0200 Subject: [PATCH 2999/4321] isoapplet: implemented logout --- src/libopensc/card-isoApplet.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index f17bdb34f8..26d50bef13 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -1287,6 +1287,11 @@ static int isoApplet_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } +static int isoApplet_logout(sc_card_t *card) +{ + return isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid)); +} + static struct sc_card_driver *sc_get_driver(void) { sc_card_driver_t *iso_drv = sc_get_iso7816_driver(); @@ -1310,6 +1315,7 @@ static struct sc_card_driver *sc_get_driver(void) isoApplet_ops.compute_signature = isoApplet_compute_signature; isoApplet_ops.get_challenge = isoApplet_get_challenge; isoApplet_ops.card_reader_lock_obtained = isoApplet_card_reader_lock_obtained; + isoApplet_ops.logout = isoApplet_logout; /* unsupported functions */ isoApplet_ops.write_binary = NULL; From 4ea26f1a228d4872523ca7d101b22c2b3d6b93d9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:17:54 +0200 Subject: [PATCH 3000/4321] jpki: implemented logout --- src/libopensc/card-jpki.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libopensc/card-jpki.c b/src/libopensc/card-jpki.c index 79a69f8c9c..8351cbb52a 100644 --- a/src/libopensc/card-jpki.c +++ b/src/libopensc/card-jpki.c @@ -361,6 +361,11 @@ static int jpki_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } +static int jpki_logout(sc_card_t *card) +{ + return jpki_select_ap(card); +} + static struct sc_card_driver * sc_get_driver(void) { @@ -375,6 +380,7 @@ sc_get_driver(void) jpki_ops.set_security_env = jpki_set_security_env; jpki_ops.compute_signature = jpki_compute_signature; jpki_ops.card_reader_lock_obtained = jpki_card_reader_lock_obtained; + jpki_ops.logout = jpki_logout; return &jpki_drv; } From a5148e9457014031fcd282ea9f9e0c7875b9dc60 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:22:41 +0200 Subject: [PATCH 3001/4321] mcrd: implemented logout --- src/libopensc/card-mcrd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index d54a98cb3d..430098614c 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1174,6 +1174,15 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->pin_cmd(card, data, tries_left)); } +static int mcrd_logout(sc_card_t * card) +{ + if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) { + return gp_select_aid(card, &EstEID_v35_AID); + } else { + return SC_ERROR_NOT_SUPPORTED; + } +} + /* Driver binding */ static struct sc_card_driver *sc_get_driver(void) { @@ -1190,6 +1199,7 @@ static struct sc_card_driver *sc_get_driver(void) mcrd_ops.compute_signature = mcrd_compute_signature; mcrd_ops.decipher = mcrd_decipher; mcrd_ops.pin_cmd = mcrd_pin_cmd; + mcrd_ops.logout = mcrd_logout; return &mcrd_drv; } From 7deb2f5f9721adf380deda7655144714f4a1b1c9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:24:10 +0200 Subject: [PATCH 3002/4321] muscle: implemented logout --- src/libopensc/card-muscle.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index bbdee63b30..54271a8173 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -856,6 +856,19 @@ static int muscle_card_reader_lock_obtained(sc_card_t *card, int was_reset) LOG_FUNC_RETURN(card->ctx, r); } +static int muscle_logout(sc_card_t *card) +{ + int r = SC_ERROR_NOT_SUPPORTED; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) { + r = SC_SUCCESS; + } + + LOG_FUNC_RETURN(card->ctx, r); +} + static struct sc_card_driver * sc_get_driver(void) { @@ -884,6 +897,7 @@ static struct sc_card_driver * sc_get_driver(void) muscle_ops.delete_file = muscle_delete_file; muscle_ops.list_files = muscle_list_files; muscle_ops.card_reader_lock_obtained = muscle_card_reader_lock_obtained; + muscle_ops.logout = muscle_logout; return &muscle_drv; } From 383850f432f2518c43c4646060dfa3e57dd7e482 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:28:11 +0200 Subject: [PATCH 3003/4321] starcos 3.x: fixed comment about logout handling --- src/libopensc/card-starcos.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index a51c4b1e0d..857f57e960 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -2160,18 +2160,9 @@ static int starcos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) } } -/** - * starcos_logout_v3_x() - * StarCOS 3.x cards will not clear the security status by selecting MF. - * Returning NOT_SUPPORTED would cause card reset, effectively invalidating - * the security status. - */ static int starcos_logout_v3_x(sc_card_t *card) { - int r = SC_ERROR_NOT_SUPPORTED; - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); - - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + return SC_ERROR_NOT_SUPPORTED; } static int starcos_logout(sc_card_t *card) From b7053f74295f65f4ca77b677484dfe8ce1646b4d Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 22 Jun 2023 11:34:09 +0200 Subject: [PATCH 3004/4321] westcos: implemented logout --- src/libopensc/card-westcos.c | 44 ++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 9c10fc8cc6..38927732da 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -166,6 +166,26 @@ static int westcos_finish(sc_card_t * card) return 0; } +static int select_westcos_applet(sc_card_t *card) +{ + int r; + sc_apdu_t apdu; + u8 aid[] = { + 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 + }; + sc_format_apdu(card, &apdu, + SC_APDU_CASE_3_SHORT, 0xA4, 0x04, + 0); + apdu.cla = 0x00; + apdu.lc = sizeof(aid); + apdu.datalen = sizeof(aid); + apdu.data = aid; + r = sc_transmit_apdu(card, &apdu); + if (r) + return r; + return sc_check_sw(card, apdu.sw1, apdu.sw2); +} + static int westcos_match_card(sc_card_t * card) { int i; @@ -176,23 +196,7 @@ static int westcos_match_card(sc_card_t * card) /* JAVACARD, look for westcos applet */ if (i == 1) { - int r; - sc_apdu_t apdu; - u8 aid[] = { - 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 - }; - sc_format_apdu(card, &apdu, - SC_APDU_CASE_3_SHORT, 0xA4, 0x04, - 0); - apdu.cla = 0x00; - apdu.lc = sizeof(aid); - apdu.datalen = sizeof(aid); - apdu.data = aid; - r = sc_transmit_apdu(card, &apdu); - if (r) - return 0; - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) + if (select_westcos_applet(card)) return 0; } @@ -1266,6 +1270,11 @@ static int westcos_decipher(sc_card_t *card, const u8 * crgram, return westcos_sign_decipher(1, card, crgram, crgram_len, out, outlen); } +static int westcos_logout(sc_card_t *card) +{ + return select_westcos_applet(card); +} + struct sc_card_driver *sc_get_westcos_driver(void) { if (iso_ops == NULL) @@ -1297,6 +1306,7 @@ struct sc_card_driver *sc_get_westcos_driver(void) westcos_ops.process_fci = westcos_process_fci; westcos_ops.construct_fci = NULL; westcos_ops.pin_cmd = westcos_pin_cmd; + westcos_ops.logout = westcos_logout; return &westcos_drv; } From 1c41950289372cce56f9720afa7d28f6046df35f Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 28 Jun 2023 00:15:26 +0200 Subject: [PATCH 3005/4321] PIV/CAC/Coolkey/muscle: fixed overwriting logout function in match_card --- src/libopensc/card-cac.c | 3 --- src/libopensc/card-cac1.c | 3 --- src/libopensc/card-coolkey.c | 3 --- src/libopensc/card-muscle.c | 4 ---- src/libopensc/card-piv.c | 4 ---- 5 files changed, 17 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index e16a2e27d4..0ad1d60798 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -1821,9 +1821,6 @@ static int cac_match_card(sc_card_t *card) { int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* Since we send an APDU, the card's logout function may be called... - * however it may be in dirty memory */ - card->ops->logout = NULL; r = cac_find_and_initialize(card, 0); return (r == SC_SUCCESS); /* never match */ diff --git a/src/libopensc/card-cac1.c b/src/libopensc/card-cac1.c index 55adc9bd07..f6f7dd87de 100644 --- a/src/libopensc/card-cac1.c +++ b/src/libopensc/card-cac1.c @@ -488,9 +488,6 @@ static int cac_match_card(sc_card_t *card) { int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* Since we send an APDU, the card's logout function may be called... - * however it may be in dirty memory */ - card->ops->logout = NULL; r = cac_find_and_initialize(card, 0); return (r == SC_SUCCESS); /* never match */ diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 3aa1897d6a..68dcf1d6d3 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -2265,9 +2265,6 @@ static int coolkey_match_card(sc_card_t *card) int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* Since we send an APDU, the card's logout function may be called... - * however it may be in dirty memory */ - card->ops->logout = NULL; r = coolkey_select_applet(card); if (r == SC_SUCCESS) { diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index 54271a8173..7ecc7050c6 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -81,10 +81,6 @@ static int muscle_match_card(sc_card_t *card) u8 response[64]; int r; - /* Since we send an APDU, the card's logout function may be called... - * however it's not always properly nulled out... */ - card->ops->logout = NULL; - if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) { /* Muscle applet is present, check the protocol version to be sure */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x3C, 0x00, 0x00); diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index b4d92098ec..27d5479253 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3089,10 +3089,6 @@ static int piv_match_card_continued(sc_card_t *card) piv_private_data_t *priv = NULL; int saved_type = card->type; - /* Since we send an APDU, the card's logout function may be called... - * however it may be in dirty memory */ - card->ops->logout = NULL; - /* piv_match_card may be called with card->type, set by opensc.conf */ /* user provide card type must be one we know */ switch (card->type) { From 868f76fb31255fd3fdacfc3e476452efeb61c3e7 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 21 Jun 2023 12:27:23 +0200 Subject: [PATCH 3006/4321] Fixed PIN authentication bypass If two processes are accessing a token, then one process may leave the card usable with an authenticated PIN so that a key may sign/decrypt any data. This is especially the case if the token does not support a way of resetting the authentication status (logout). We have some tracking of the authentication status in software via PKCS#11, Minidriver (os-wise) and CryptoTokenKit, which is why a PIN-prompt will appear even though the card may technically be unlocked as described in the above example. However, before this change, an empty PIN was not verified (likely yielding an error during PIN-verification), but it was just checked whether the PIN is authenticated. This defeats the purpose of the PIN verification, because an empty PIN is not the correct one. Especially during OS Logon, we don't want that kind of shortcut, but we want the user to verify the correct PIN (even though the token was left unattended and authentication at the computer). This essentially reverts commit e6f7373ef066cfab6e3162e8b5f692683db23864. --- src/libopensc/pkcs15-pin.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 80a185fecd..393234efe4 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -307,19 +307,6 @@ sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pi LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_REFERENCE); auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; - /* - * if pin cache is disabled, we can get here with no PIN data. - * in this case, to avoid error or unnecessary pin prompting on pinpad, - * check if the PIN has been already verified and the access condition - * is still open on card. - */ - if (pinlen == 0) { - r = sc_pkcs15_get_pin_info(p15card, pin_obj); - - if (r == SC_SUCCESS && auth_info->logged_in == SC_PIN_STATE_LOGGED_IN) - LOG_FUNC_RETURN(ctx, r); - } - r = _validate_pin(p15card, auth_info, pinlen); if (r) From 232265dadfad61501478b2dda58cf72ca4379259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C5=A0arinay?= Date: Sun, 25 Jun 2023 15:47:42 +0200 Subject: [PATCH 3007/4321] include ATR of SafeNet eToken 5110 (USB) --- src/libopensc/card-idprime.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index cd3961406f..962f2aad4d 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -69,6 +69,10 @@ static const struct sc_atr_table idprime_atrs[] = { "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:00:00:ff:ff:ff", "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards", SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, + { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00", + "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00", + "Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards", + SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL }, { NULL, NULL, NULL, 0, 0, NULL } }; From f1993dc4e0b33050b8f72a3558ee88b24c4063b2 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Tue, 27 Jun 2023 09:50:42 +0200 Subject: [PATCH 3008/4321] myeid: fixed CID 380538 Out-of-bounds read (OVERRUN) also fixes output buffer size checking --- src/libopensc/card-myeid.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 4ee4246840..50e78ff1d8 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -1986,18 +1986,20 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, sc_log(ctx, "Found padding byte %02x", pad_byte); if (pad_byte == 0 || pad_byte > block_size) LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); - sdata = priv->sym_plain_buffer + block_size - pad_byte; + sdata = priv->sym_plain_buffer + block_size; for (i = 0; i < pad_byte; i++) - if (sdata[i] != pad_byte) + if (*(--sdata) != pad_byte) LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); return_len = block_size - pad_byte; } - *outlen = return_len; /* application can request buffer size or actual buffer size is too small */ - if (out == NULL) + if (out == NULL) { + *outlen = return_len; LOG_FUNC_RETURN(ctx, SC_SUCCESS); + } if (return_len > *outlen) LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + *outlen = return_len; memcpy(out, priv->sym_plain_buffer, return_len); sc_log(ctx, "C_DecryptFinal %zu bytes", *outlen); return SC_SUCCESS; From 79bec702662f8f35f76b1cd15f61d81f7ca9ea66 Mon Sep 17 00:00:00 2001 From: Theo Buehler Date: Thu, 29 Jun 2023 02:08:30 +0300 Subject: [PATCH 3009/4321] LibreSSL: Use OPENSSL_cleanup() CRYPTO_secure_malloc_done() does not exist in LibreSSL, but OPENSSL_cleanup() does which wraps EVP_cleanup(3) and others. Compile- and run-tested on OpenBSD/amd64 7.3-current. Windows-only minidriver included for completeness since LibreSSL is also available on Windows. Courtesy of Theo Buehler . --- src/minidriver/minidriver.c | 6 +++++- src/pkcs11/pkcs11-global.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index a78a757b4d..5892bedcee 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -7230,8 +7230,12 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, case DLL_PROCESS_DETACH: sc_notify_close(); if (lpReserved == NULL) { -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) +#if defined(ENABLE_OPENSSL) +#if defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); +#else + OPENSSL_cleanup(); +#endif #endif #ifdef ENABLE_OPENPACE EAC_cleanup(); diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index eed4c850a8..b581974be5 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -252,8 +252,12 @@ __attribute__((destructor)) int module_close() { sc_notify_close(); -#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) +#if defined(ENABLE_OPENSSL) +#if defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); +#else + OPENSSL_cleanup(); +#endif #endif #ifdef ENABLE_OPENPACE EAC_cleanup(); From e015242590ad9131e124232cc5a2fd02d525ef2c Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 29 Jun 2023 02:41:43 +0300 Subject: [PATCH 3010/4321] LibreSSL does provide EVP_sha3_*() after 3.7.3 Support was added in 16.04.2023. Compile- and run-tested on OpenBSD/amd64 7.3-current. --- src/libopensc/sc-ossl-compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index df0cebbce2..8012cd4c0f 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -50,10 +50,12 @@ extern "C" { #if LIBRESSL_VERSION_NUMBER < 0x30500000L #define FIPS_mode() (0) #endif +#ifndef EVP_sha3_224 #define EVP_sha3_224() (NULL) #define EVP_sha3_256() (NULL) #define EVP_sha3_384() (NULL) #define EVP_sha3_512() (NULL) +#endif #if LIBRESSL_VERSION_NUMBER < 0x3070000fL #define EVP_PKEY_new_raw_public_key(t, e, p, l) (NULL) #define EVP_PKEY_get_raw_public_key(p, pu, l) (0) From 2f7cbb935bdac37df92bc980e35c707218427966 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Fri, 30 Jun 2023 15:12:09 +0300 Subject: [PATCH 3011/4321] CI: upgrade to latest LibreSSL 3.7.3 --- .github/setup-libressl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/setup-libressl.sh b/.github/setup-libressl.sh index 2a95c9759b..3234b441ec 100755 --- a/.github/setup-libressl.sh +++ b/.github/setup-libressl.sh @@ -2,7 +2,7 @@ set -ex -o xtrace -V=libressl-3.6.1 +V=libressl-3.7.3 sudo apt-get remove -y libssl-dev From b7fe5b2e2198cc25fb2e996b73c53bcb3f04b2eb Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sat, 1 Jul 2023 17:57:52 +0300 Subject: [PATCH 3012/4321] fix spelling to silence Codespell CI job It cannot cope with such constructs and turns up false positive CI failures in entirely unrelated PRs. Stop the noise. --- src/libopensc/card-starcos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 4fa517e121..258ca6c1a1 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1115,7 +1115,7 @@ static int starcos_process_acl(sc_card_t *card, sc_file_t *file, memcpy(p, file->name, (u8)file->namelen); p += 16; } else { - /* (mis)use the fid as aid */ + /* use the fid as aid */ *p++ = 2; memset(p, 0, 16); *p++ = (file->id >> 8) & 0xff; From 6226a625c35923a911d26eacb2b904901bfe24ce Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sat, 1 Jul 2023 18:06:29 +0300 Subject: [PATCH 3013/4321] fix macro guard comment wrt. LibreSSL specific code --- src/pkcs11/openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 48d382dbcb..3f2bd59e17 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -290,7 +290,7 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) ENGINE_free(e); e = NULL; } -#endif /* !OPENSSL_NO_STATIC_ENGINE && !OPENSSL_NO_GOST */ +#endif /* !OPENSSL_NO_STATIC_ENGINE && !OPENSSL_NO_GOST && !LIBRESSL_VERSION_NUMBER */ } if (e) { ENGINE_set_default(e, ENGINE_METHOD_ALL); From c449a181a6988cc1e8dc8764d23574e48cdc3fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 19 Jun 2023 16:14:51 +0200 Subject: [PATCH 3014/4321] pkcs15-cflex: check path length to prevent underflow Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58932 --- src/pkcs15init/pkcs15-cflex.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index d06568073d..ce1d48e62c 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -56,6 +56,9 @@ cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d int r = 0; /* Select the parent DF */ path = df->path; + if (path.len < 2) { + return SC_ERROR_INVALID_ARGUMENTS; + } path.len -= 2; r = sc_select_file(p15card->card, &path, &parent); if (r < 0) From 0cee2ab676ca7ff10bb15a9afab34156d8a24d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 19 Jun 2023 16:24:45 +0200 Subject: [PATCH 3015/4321] pkcs15-authentic: free file in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59441 --- src/pkcs15init/pkcs15-authentic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index 1a8b9d7d55..75d4984a54 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -191,13 +191,16 @@ authentic_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p rv = sc_erase_binary(p15card->card, 0, file->size, 0); if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); + if (rv < 0) + sc_file_free(file); + LOG_TEST_RET(ctx, rv, "'UPDATE' authentication failed"); rv = sc_erase_binary(p15card->card, 0, file->size, 0); } - LOG_TEST_RET(ctx, rv, "Binary erase error"); sc_file_free(file); + LOG_TEST_RET(ctx, rv, "Binary erase error"); profile->dirty = 1; } From 543317d14c984923ab66b226acb76fb7836f6b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 21 Jun 2023 10:52:16 +0200 Subject: [PATCH 3016/4321] profile: check also macros inside the strings Check macro value for loop also when the macro name is hidden inside the value string, such as `macro = xx$other_macro` Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57338 --- src/pkcs15init/profile.c | 51 ++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 3358d6c515..a0a1908206 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -54,6 +54,8 @@ #define TEMPLATE_FILEID_MIN_DIFF 0x20 +#define WORD_SIZE 64 + /* #define DEBUG_PROFILE */ @@ -1985,24 +1987,44 @@ static struct block root_ops = { "root", process_block, NULL, root_blocks }; +static void +get_inner_word(char *str, char word[WORD_SIZE]) { + char *inner = NULL; + size_t len = 0; + + inner = str; + while (isalnum((unsigned char)*inner) || *inner == '-' || *inner == '_') { + inner++; + len++; + } + len = len >= WORD_SIZE ? WORD_SIZE - 1 : len; + memcpy(word, str, len); + word[len] = '\0'; +} + +/* + * Checks for a reference loop in macro definitions. + * Function returns 1 if a reference loop is detected, 0 otherwise. + */ static int -check_macro_reference_loop(char *start, char *str, struct state *cur, int depth) { +check_macro_reference_loop(const char *start_name, char *value, sc_profile_t *profile, int depth) { sc_macro_t *macro = NULL; char *name = NULL; + char word[WORD_SIZE]; - if (!start || !str || !cur) + if (!start_name || !value || !profile || depth == 16) return 1; - if (depth == 16) - return 1; - - if (!(name = strchr(str, '$'))) + if (!(name = strchr(value, '$'))) return 0; - if (!(macro = find_macro(cur->profile, name + 1))) + + /* Extract the macro name from the string*/ + get_inner_word(name + 1, word); + if (!(macro = find_macro(profile, word))) return 0; - if (!strcmp(macro->name, start + 1)) + if (!strcmp(macro->name, start_name + 1)) return 1; - return check_macro_reference_loop(start, macro->value->data, cur, depth + 1); + return check_macro_reference_loop(start_name, macro->value->data, profile, depth + 1); } static int @@ -2025,8 +2047,11 @@ build_argv(struct state *cur, const char *cmdname, /* When str contains macro inside, macro reference loop needs to be checked */ char *macro_name = NULL; if ((macro_name = strchr(str, '$'))) { - if ((macro = find_macro(cur->profile, macro_name + 1)) - && check_macro_reference_loop(macro_name + 1, macro->value->data, cur, 0)) { + /* Macro does not to start at the first position */ + char word[WORD_SIZE]; + get_inner_word(macro_name + 1, word); + if ((macro = find_macro(cur->profile, word)) + && check_macro_reference_loop(word, macro->value->data, cur->profile, 0)) { return SC_ERROR_SYNTAX_ERROR; } } @@ -2045,7 +2070,7 @@ build_argv(struct state *cur, const char *cmdname, if (list == macro->value) { return SC_ERROR_SYNTAX_ERROR; } - if (check_macro_reference_loop(list->data, macro->value->data, cur, 0)) { + if (check_macro_reference_loop(list->data, macro->value->data, cur->profile, 0)) { return SC_ERROR_SYNTAX_ERROR; } #ifdef DEBUG_PROFILE @@ -2390,7 +2415,7 @@ struct num_exp_ctx { jmp_buf error; int j; - char word[64]; + char word[WORD_SIZE]; char * unget; char * str; From 88880db0307a07e33cf2e1592bb029e9c170dfea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Wed, 21 Jun 2023 15:48:27 +0200 Subject: [PATCH 3017/4321] pkcs15-pubkey: free DER value when parsing public key fails The der value might be allocated in asn1_decode_entry() but it is not released when errror occurs. Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59615 --- src/libopensc/pkcs15-pubkey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 4a0ddffbeb..7107c47cbc 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -351,6 +351,8 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, err: if (r < 0) { sc_pkcs15_free_pubkey_info(info); + if (der->len) + free(der->value); } LOG_FUNC_RETURN(ctx, r); From 6a69746239887dae23cf34800d6e0a98abc478b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 23 Jun 2023 13:42:06 +0200 Subject: [PATCH 3018/4321] profile: separate condition for checking macro character --- src/pkcs15init/profile.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index a0a1908206..716ad21a45 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -1987,13 +1987,20 @@ static struct block root_ops = { "root", process_block, NULL, root_blocks }; +static int +is_macro_character(char c) { + if (isalnum(c) || c == '-' || c == '_') + return 1; + return 0; +} + static void get_inner_word(char *str, char word[WORD_SIZE]) { char *inner = NULL; size_t len = 0; inner = str; - while (isalnum((unsigned char)*inner) || *inner == '-' || *inner == '_') { + while (is_macro_character(*inner)) { inner++; len++; } @@ -2472,7 +2479,7 @@ __expr_get(struct num_exp_ctx *ctx, int eof_okay) } else if (*s == '$') { expr_put(ctx, *s++); - while (isalnum((unsigned char)*s) || *s == '-' || *s == '_') + while (is_macro_character(*s)) expr_put(ctx, *s++); } else if (strchr("*/+-()|&", *s)) { From 651017db5e9cb16c217a61cbf45807cd67be6020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 23 Jun 2023 16:35:34 +0200 Subject: [PATCH 3019/4321] profile: refactor check for macro loops --- src/pkcs15init/profile.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 716ad21a45..b398604fbd 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -2010,28 +2010,31 @@ get_inner_word(char *str, char word[WORD_SIZE]) { } /* - * Checks for a reference loop in macro definitions. + * Checks for a reference loop for macro named start_name in macro definitions. * Function returns 1 if a reference loop is detected, 0 otherwise. */ static int -check_macro_reference_loop(const char *start_name, char *value, sc_profile_t *profile, int depth) { - sc_macro_t *macro = NULL; +check_macro_reference_loop(const char *start_name, sc_macro_t *macro, sc_profile_t *profile, int depth) { + char *macro_value = NULL; char *name = NULL; char word[WORD_SIZE]; - if (!start_name || !value || !profile || depth == 16) + if (!start_name || !macro || !profile || depth == 16) return 1; - if (!(name = strchr(value, '$'))) + /* Find name in macro value */ + macro_value = macro->value->data; + if (!(name = strchr(macro_value, '$'))) return 0; - - /* Extract the macro name from the string*/ + /* Extract the macro name from the string */ get_inner_word(name + 1, word); + /* Find whether name corresponds to some other macro */ if (!(macro = find_macro(profile, word))) return 0; - if (!strcmp(macro->name, start_name + 1)) + /* Check for loop */ + if (!strcmp(macro->name, start_name)) return 1; - return check_macro_reference_loop(start_name, macro->value->data, profile, depth + 1); + return check_macro_reference_loop(start_name, macro, profile, depth + 1); } static int @@ -2058,7 +2061,7 @@ build_argv(struct state *cur, const char *cmdname, char word[WORD_SIZE]; get_inner_word(macro_name + 1, word); if ((macro = find_macro(cur->profile, word)) - && check_macro_reference_loop(word, macro->value->data, cur->profile, 0)) { + && check_macro_reference_loop(macro->name, macro, cur->profile, 0)) { return SC_ERROR_SYNTAX_ERROR; } } @@ -2077,7 +2080,7 @@ build_argv(struct state *cur, const char *cmdname, if (list == macro->value) { return SC_ERROR_SYNTAX_ERROR; } - if (check_macro_reference_loop(list->data, macro->value->data, cur->profile, 0)) { + if (check_macro_reference_loop(macro->name, macro, cur->profile, 0)) { return SC_ERROR_SYNTAX_ERROR; } #ifdef DEBUG_PROFILE From 9572808baeb8b8e7cdde61f7c8ddc21454bf77cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 23 Jun 2023 16:36:04 +0200 Subject: [PATCH 3020/4321] tests: add unit tests for macro reference loop check --- src/tests/unittests/Makefile.am | 5 +- src/tests/unittests/Makefile.mak | 5 +- .../unittests/check_macro_reference_loop.c | 113 ++++++++++++++++++ 3 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 src/tests/unittests/check_macro_reference_loop.c diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 61f86b43f4..54e05ecdbd 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -12,8 +12,8 @@ VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all # to avoid false positive leaks from pcsclite TESTS_ENVIRONMENT = LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1' -noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature -TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature +noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature check_macro_reference_loop +TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature check_macro_reference_loop noinst_HEADERS = torture.h @@ -34,6 +34,7 @@ pkcs15filter_SOURCES = pkcs15-emulator-filter.c openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c hextobin_SOURCES = hextobin.c decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c +check_macro_reference_loop = check_macro_reference_loop.c if ENABLE_ZLIB noinst_PROGRAMS += compression diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak index 83d52b59e1..2607546f57 100644 --- a/src/tests/unittests/Makefile.mak +++ b/src/tests/unittests/Makefile.mak @@ -1,10 +1,11 @@ TOPDIR = ..\..\.. -TARGETS = asn1 compression pkcs15filter +TARGETS = asn1 compression pkcs15filter check_macro_reference_loop OBJECTS = asn1.obj \ compression.obj \ - pkcs15-emulator-filter.obj + pkcs15-emulator-filter.obj \ + check_macro_reference_loop.obj $(TOPDIR)\win32\versioninfo.res all: $(TARGETS) diff --git a/src/tests/unittests/check_macro_reference_loop.c b/src/tests/unittests/check_macro_reference_loop.c new file mode 100644 index 0000000000..593e2a9d37 --- /dev/null +++ b/src/tests/unittests/check_macro_reference_loop.c @@ -0,0 +1,113 @@ +/* + * check_macro_reference_loop.c: Unit tests checking macro reference loop + * + * Copyright (C) 2023 Red Hat, Inc. + * + * Author: Veronika Hanulikova + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define SC_PKCS15_PROFILE_DIRECTORY "" + +#include "torture.h" +#include "libopensc/log.c" +#include "pkcs15init/profile.c" +#include "common/compat_strlcpy.c" +#include + +static void torture_no_loop(void **state) +{ + scconf_list value = { .data = "value" }; + sc_macro_t macro = { .name = "name", .value = &value }; + sc_profile_t profile = { .macro_list = ¯o }; + + int r = check_macro_reference_loop("name", ¯o, &profile, 10); + assert_int_equal(r, 0); +} + +static void torture_one_macro_no_loop(void **state) +{ + scconf_list value = { .data = "value" }; + sc_macro_t macro = { .name = "name", .value = &value }; + sc_profile_t profile = { .macro_list = ¯o }; + + int r = check_macro_reference_loop("name", ¯o, &profile, 10); + assert_int_equal(r, 0); +} + +static void torture_one_macro_loop(void **state) +{ + scconf_list value = { .data = "$name" }; + sc_macro_t macro = { .name = "name", .value = &value }; + sc_profile_t profile = { .macro_list = ¯o }; + + int r = check_macro_reference_loop("name", ¯o, &profile, 10); + assert_int_equal(r, 1); +} + +static void torture_long_macro_loop(void **state) +{ + scconf_list value1 = { .data = "$second" }; + scconf_list value2 = { .data = "$third" }; + scconf_list value3 = { .data = "$first" }; + sc_macro_t macro3 = { .name = "third", .value = &value3 }; + sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; + sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; + sc_profile_t profile = { .macro_list = ¯o1 }; + + int r = check_macro_reference_loop("first", ¯o1, &profile, 10); + assert_int_equal(r, 1); +} + +static void torture_long_macro_loop_too_deep(void **state) +{ + scconf_list value1 = { .data = "$second" }; + scconf_list value2 = { .data = "$third" }; + scconf_list value3 = { .data = "value" }; + sc_macro_t macro3 = { .name = "third", .value = &value3 }; + sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; + sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; + sc_profile_t profile = { .macro_list = ¯o1 }; + + int r = check_macro_reference_loop("first", ¯o1, &profile, 14); + assert_int_equal(r, 1); +} + +static void torture_macro_loop_inner_string(void **state) +{ + scconf_list value1 = { .data = "xx$second" }; + scconf_list value2 = { .data = "$third" }; + scconf_list value3 = { .data = "$first\0" }; + sc_macro_t macro3 = { .name = "third", .value = &value3 }; + sc_macro_t macro2 = { .name = "second", .value = &value2, .next = ¯o3 }; + sc_macro_t macro1 = { .name = "first", .value = &value1, .next = ¯o2 }; + sc_profile_t profile = { .macro_list = ¯o1 }; + + int r = check_macro_reference_loop("first", ¯o1, &profile, 10); + assert_int_equal(r, 1); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_no_loop), + cmocka_unit_test(torture_one_macro_no_loop), + cmocka_unit_test(torture_one_macro_loop), + cmocka_unit_test(torture_long_macro_loop), + cmocka_unit_test(torture_long_macro_loop_too_deep), + cmocka_unit_test(torture_macro_loop_inner_string) + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} From 6790e0e7225fdada6af8fb8c219955f8b68f82e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 23 Jun 2023 17:23:02 +0200 Subject: [PATCH 3021/4321] pkcs15-lib: free alg id in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59531 --- src/pkcs15init/pkcs15-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 700c61739c..c8cab992b9 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1664,6 +1664,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr err: sc_pkcs15_free_object(object); + free(pubkey_args.key.alg_id); if (algorithm == SC_ALGORITHM_EC) { /* Allocated in sc_copy_ec_params() */ free(pubkey_args.key.u.ec.params.named_curve); From ca66274159833065bb03cfc10ba6394d67fa83f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 29 Jun 2023 11:32:03 +0200 Subject: [PATCH 3022/4321] pkcs15-lib: copy and release whole pubkey When creating copy of the pubkey in sc_pkcs15init_store_public_key(), copy whole structure and allocated new memory for algorithm based parameters. Release the whole copy in sc_pkcs15init_store_public_key(). The sc_pkcs15init_generate_key() can then release the original pubkey structure. --- src/pkcs15init/pkcs15-lib.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index c8cab992b9..663d39b10a 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1664,17 +1664,11 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr err: sc_pkcs15_free_object(object); - free(pubkey_args.key.alg_id); + sc_pkcs15_erase_pubkey(&pubkey_args.key); if (algorithm == SC_ALGORITHM_EC) { - /* Allocated in sc_copy_ec_params() */ - free(pubkey_args.key.u.ec.params.named_curve); - free(pubkey_args.key.u.ec.params.der.value); /* allocated in check_keygen_params_consistency() */ free(keygen_args->prkey_args.key.u.ec.params.der.value); keygen_args->prkey_args.key.u.ec.params.der.value = NULL; - /* can be allocated in driver-specific generate_key() */ - free(pubkey_args.key.u.ec.ecpointQ.value); - pubkey_args.key.u.ec.ecpointQ.value = NULL; } LOG_FUNC_RETURN(ctx, r); } @@ -1855,15 +1849,42 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile if (!keyargs) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store public key aborted"); - /* Create a copy of the key first */ + /* Create shallow a copy of the key first */ key = keyargs->key; + /* Copy algorithm id structure */ + if (keyargs->key.alg_id) { + key.alg_id = calloc(1, sizeof(struct sc_algorithm_id)); + if (!key.alg_id) + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Can not allocate memory for algorithm id"); + + key.alg_id->algorithm = keyargs->key.alg_id->algorithm; + memcpy(&key.alg_id->oid, &keyargs->key.alg_id->oid, sizeof(struct sc_object_id)); + } + + /* Copy algorithm related parameters */ switch (key.algorithm) { case SC_ALGORITHM_RSA: + key.u.rsa.modulus.data = NULL; + key.u.rsa.exponent.data = NULL; + // copy RSA params + if (!(key.u.rsa.modulus.data = malloc(keyargs->key.u.rsa.modulus.len))) + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to copy RSA public key parameters"); + memcpy(key.u.rsa.modulus.data, keyargs->key.u.rsa.modulus.data, keyargs->key.u.rsa.modulus.len); + if (!(key.u.rsa.exponent.data = malloc(keyargs->key.u.rsa.exponent.len))) { + r = SC_ERROR_OUT_OF_MEMORY; + LOG_TEST_GOTO_ERR(ctx, r, "Failed to copy RSA public key parameters"); + } + memcpy(key.u.rsa.exponent.data, keyargs->key.u.rsa.exponent.data, keyargs->key.u.rsa.exponent.len); keybits = sc_pkcs15init_keybits(&key.u.rsa.modulus); type = SC_PKCS15_TYPE_PUBKEY_RSA; break; case SC_ALGORITHM_GOSTR3410: + key.u.gostr3410.xy.data = NULL; + // copy GOSTR params + if (!(key.u.gostr3410.xy.data = malloc(keyargs->key.u.gostr3410.xy.len))) + LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to copy GOSTR public key parameters"); + memcpy(key.u.gostr3410.xy.data, keyargs->key.u.gostr3410.xy.data, keyargs->key.u.gostr3410.xy.len); keybits = SC_PKCS15_GOSTR3410_KEYSIZE; type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; break; From 22f73781706a293d10ebe982ece863a73fd62bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 29 Jun 2023 13:53:59 +0200 Subject: [PATCH 3023/4321] fuzz_pkcs15init: test also generating of RSA keys --- src/tests/fuzzing/fuzz_pkcs15init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c index 7b091de011..e44e3aae35 100644 --- a/src/tests/fuzzing/fuzz_pkcs15init.c +++ b/src/tests/fuzzing/fuzz_pkcs15init.c @@ -200,7 +200,7 @@ void do_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE | SC_PKCS15_PRKEY_ACCESS_LOCAL; - for (int i = 1; i < 2; i++) { + for (int i = 0; i < 2; i++) { keygen_args.prkey_args.key.algorithm = algorithms[i]; if (algorithms[i] == SC_ALGORITHM_EC) /* strdup called also in parse_alg_spec() */ keygen_args.prkey_args.key.u.ec.params.named_curve = strdup("prime256v1"); From b17d4a4dfb02ac6f0476b280588bca022d989e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 29 Jun 2023 13:54:28 +0200 Subject: [PATCH 3024/4321] pkcs15-lib: set algorithm to pubkey args --- src/pkcs15init/pkcs15-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 663d39b10a..7bd1ac66bc 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1592,6 +1592,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr pubkey_args.label = keygen_args->pubkey_label ? keygen_args->pubkey_label : object->label; pubkey_args.usage = keygen_args->prkey_args.usage; pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage; + pubkey_args.key.algorithm = algorithm; if (algorithm == SC_ALGORITHM_GOSTR3410) { pubkey_args.params.gost = keygen_args->prkey_args.params.gost; From dd712f529be0064c7326683876c8d89b6080ddcb Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Jul 2023 20:48:31 +0200 Subject: [PATCH 3025/4321] coolkey: Use packed structure to fix coverity warning The way how data is loaded into the structures and usage of offsetof depends on the structure being packed. This is compiler-dependent. Thanks coverity. CID 353967 Fixes #2811 --- src/libopensc/card-coolkey.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c index 3990705fd2..10fcd843a8 100644 --- a/src/libopensc/card-coolkey.c +++ b/src/libopensc/card-coolkey.c @@ -61,7 +61,12 @@ #include "gp.h" #include "../pkcs11/pkcs11.h" - +#ifdef _MSC_VER +#define PACKED +#pragma pack(push,1) +#elif defined(__GNUC__) +#define PACKED __attribute__ ((__packed__)) +#endif #define COOLKEY_MAX_SIZE 4096 /* arbitrary, just needs to be 'large enough' */ @@ -190,7 +195,7 @@ typedef struct coolkey_decompressed_header { u8 object_count[2]; u8 token_name_length; u8 token_name[255]; /* arbitrary size up to token_name_length */ -} coolkey_decompressed_header_t; +} PACKED coolkey_decompressed_header_t; /* * header for an object. There are 2 types of object headers, v1 and v0. @@ -238,6 +243,13 @@ typedef struct coolkey_attribute_header { /* optional attribute data, or attribute len+data, depending on the value of data_type */ } coolkey_attribute_header_t; +#ifdef _MSC_VER +#undef PACKED +#pragma pack(pop) +#elif defined(__GNUC__) +#undef PACKED +#endif + /* values for attribute_data_type */ #define COOLKEY_ATTR_TYPE_STRING 0 #define COOLKEY_ATTR_TYPE_INTEGER 1 @@ -869,7 +881,7 @@ coolkey_number_of_error_codes = sizeof(coolkey_error_codes)/sizeof(coolkey_error static int coolkey_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) { - sc_log(card->ctx, + sc_log(card->ctx, "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2); if (sw1 == 0x90 && sw2 == 0x00) @@ -916,7 +928,7 @@ static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2, SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, + sc_log(card->ctx, "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n", ins, p1, p2, sendbuflen, card->max_send_size, card->max_recv_size); @@ -981,14 +993,14 @@ static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2, apdu.resplen = 0; } - sc_log(card->ctx, + sc_log(card->ctx, "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p", apdu.flags, apdu.le, apdu.resplen, apdu.resp); /* with new adpu.c and chaining, this actually reads the whole object */ r = sc_transmit_apdu(card, &apdu); - sc_log(card->ctx, + sc_log(card->ctx, "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x", r, apdu.resplen, apdu.sw1, apdu.sw2); @@ -1188,7 +1200,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, /* if we've already read the data, just return it */ if (priv->obj->data) { - sc_log(card->ctx, + sc_log(card->ctx, "returning cached value idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); len = MIN(count, priv->obj->length-idx); @@ -1196,7 +1208,7 @@ static int coolkey_read_binary(sc_card_t *card, unsigned int idx, LOG_FUNC_RETURN(card->ctx, len); } - sc_log(card->ctx, + sc_log(card->ctx, "clearing cache idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u", idx, count); @@ -1631,7 +1643,7 @@ static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *en SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, + sc_log(card->ctx, "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u\n", env->flags, env->operation, env->algorithm, env->algorithm_flags, env->algorithm_ref, env->key_ref[0], @@ -1792,7 +1804,7 @@ static int coolkey_ecc_op(sc_card_t *card, u8 key_number; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, + sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n", datalen, outlen); @@ -2044,13 +2056,13 @@ coolkey_process_combined_object(sc_card_t *card, coolkey_private_data_t *priv, u */ /* make sure token_name doesn't overrun the buffer */ if (decompressed_header->token_name_length + - offsetof(coolkey_decompressed_header_t,token_name) > decompressed_object_len) { + offsetof(coolkey_decompressed_header_t, token_name) > decompressed_object_len) { r = SC_ERROR_CORRUPTED_DATA; goto done; } /* make sure it doesn't overlap the object space */ if (decompressed_header->token_name_length + - offsetof(coolkey_decompressed_header_t,token_name) > object_offset) { + offsetof(coolkey_decompressed_header_t, token_name) > object_offset) { r = SC_ERROR_CORRUPTED_DATA; goto done; } From 075d482c07b581e11ea5165cff5c973dab8a5808 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Jul 2023 20:59:15 +0200 Subject: [PATCH 3026/4321] apdu: Avoid setting value without reading (and misplaced comment) The Lc is the length of the data, which can not be null with chainging as we try to pass more data. The comment corresponds to the Le or resplen fields. Thanks coverity CID 384376 --- src/libopensc/apdu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 3c13a6f241..b1083eed9e 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -402,8 +402,8 @@ sc_set_le_and_transmit(struct sc_card *card, struct sc_apdu *apdu, size_t olen) apdu->resplen = olen; apdu->le = nlen; #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* Belpic V1 applets have a problem: if the card sends a 6C XX (only XX bytes available), - * and we resend the command too soon (i.e. the reader is too fast), the card doesn't respond. + /* Belpic V1 applets have a problem: if the card sends a 6C XX (only XX bytes available), + * and we resend the command too soon (i.e. the reader is too fast), the card doesn't respond. * So we build in a delay. */ if (card->type == SC_CARD_TYPE_BELPIC_EID) msleep(40); @@ -587,9 +587,8 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) * secure messaging is used */ plen = max_send_size; tapdu.cla |= 0x10; + /* the intermediate APDU don't expect response data */ tapdu.le = 0; - /* the intermediate APDU don't expect data */ - tapdu.lc = 0; tapdu.resplen = 0; tapdu.resp = NULL; } else { From 4c8221ca9120d45e4605114d7b28da5339ecdbf5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Jul 2023 21:08:09 +0200 Subject: [PATCH 3027/4321] p11test: Fix copy&paste error while handling secret key attributes Thanks coverity CID 374845 --- src/tests/p11test/p11test_case_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 30c0b8611c..001a91f6c4 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -782,7 +782,7 @@ int callback_secret_keys(test_certs_t *objects, ? *((CK_KEY_TYPE *) template[0].pValue) : (CK_KEY_TYPE) -1; o->sign = (template[3].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[3].pValue) : CK_FALSE; - o->sign = (template[4].ulValueLen == sizeof(CK_BBOOL)) + o->verify = (template[4].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[4].pValue) : CK_FALSE; o->encrypt = (template[5].ulValueLen == sizeof(CK_BBOOL)) ? *((CK_BBOOL *) template[5].pValue) : CK_FALSE; From 09ba9cf370a4e3defbb049337f1ee6defdd3cbc8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Jul 2023 21:13:44 +0200 Subject: [PATCH 3028/4321] tools: Avoid using uninitialized buffers When sc_lock would return (for some reason) positive integer, we would end up using uninitilized buffer. Make sure it is initialized and make sure we fail early if the lock fails. Thanks coverity CID 367545 --- src/tools/opensc-explorer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 8fd1e0e684..9dfbeda11f 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -2092,7 +2092,7 @@ static int do_asn1(int argc, char **argv) sc_path_t path; sc_file_t *file = NULL; int not_current = 1; - u8 buf[SC_MAX_EXT_APDU_DATA_SIZE]; + u8 buf[SC_MAX_EXT_APDU_DATA_SIZE] = {0}; if (argc > 3) return usage(do_asn1); @@ -2138,6 +2138,8 @@ static int do_asn1(int argc, char **argv) r = sc_lock(card); if (r == SC_SUCCESS) r = sc_read_binary(card, 0, buf, MIN(size, sizeof(buf)), 0); + else + r = SC_ERROR_READER_LOCKED; sc_unlock(card); if (r < 0) { check_ret(r, SC_AC_OP_READ, "read failed", file); From 09e18802ac64e4365e1487b5c1f004d5b88f70d4 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 19 Jul 2023 00:52:22 +0200 Subject: [PATCH 3029/4321] fixed https://github.com/OpenSC/OpenSC/issues/2794 (again) --- src/libopensc/card-sc-hsm.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 920093b2a8..cd17fe18ce 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -36,8 +36,7 @@ #include "card-sc-hsm.h" -#ifdef ENABLE_SM -#ifdef ENABLE_OPENPACE +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) #include "sm/sm-eac.h" #include #include @@ -45,7 +44,6 @@ #include #include #endif -#endif /* Static reference to ISO driver */ @@ -485,8 +483,7 @@ static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data, -#ifdef ENABLE_SM -#ifdef ENABLE_OPENPACE +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) static int sc_hsm_perform_chip_authentication(sc_card_t *card) { @@ -606,7 +603,6 @@ static int sc_hsm_perform_chip_authentication(sc_card_t *card) return SC_ERROR_NOT_SUPPORTED; } #endif -#endif @@ -1773,7 +1769,7 @@ static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int sc_hsm_init(struct sc_card *card) { -#if defined(ENABLE_OPENPACE) && defined(_WIN32) +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) && defined(_WIN32) char expanded_val[PATH_MAX]; size_t expanded_len = PATH_MAX; #endif @@ -1890,7 +1886,7 @@ static int sc_hsm_init(struct sc_card *card) priv->EF_C_DevAut = NULL; priv->EF_C_DevAut_len = 0; -#ifdef ENABLE_OPENPACE +#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) EAC_init(); #ifdef _WIN32 expanded_len = ExpandEnvironmentStringsA(CVCDIR, expanded_val, sizeof expanded_val); From 6e3908fb655d3266397bfebdb328ff8f3c7206e8 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Fri, 21 Jul 2023 12:45:44 +0200 Subject: [PATCH 3030/4321] Revert "LibreSSL: Use OPENSSL_cleanup()" This reverts commit 79bec702662f8f35f76b1cd15f61d81f7ca9ea66. (See the discussion of issue #2819....) Fixes #2819 --- src/minidriver/minidriver.c | 6 +----- src/pkcs11/pkcs11-global.c | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 5892bedcee..a78a757b4d 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -7230,12 +7230,8 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, case DLL_PROCESS_DETACH: sc_notify_close(); if (lpReserved == NULL) { -#if defined(ENABLE_OPENSSL) -#if defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); -#else - OPENSSL_cleanup(); -#endif #endif #ifdef ENABLE_OPENPACE EAC_cleanup(); diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index b581974be5..eed4c850a8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -252,12 +252,8 @@ __attribute__((destructor)) int module_close() { sc_notify_close(); -#if defined(ENABLE_OPENSSL) -#if defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) +#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER) CRYPTO_secure_malloc_done(); -#else - OPENSSL_cleanup(); -#endif #endif #ifdef ENABLE_OPENPACE EAC_cleanup(); From c548daae3b6af4a5d0176e8aaf655418df1c1a01 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 10 Aug 2023 17:40:58 +0200 Subject: [PATCH 3031/4321] fixed CI pushes to OpenSC/Nightly --- .appveyor.yml | 2 +- .github/workflows/macos.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0369789aba..ba42032c0d 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,7 +10,7 @@ configuration: environment: GH_TOKEN: - secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY + secure: jeReA6BNx/dXVMGfroKadgVyPPLNrGL1pvLfc+sizlOLebm/+chuB9AcOi5mTdqHIb3E+TGIR+9fZ+kJotsjCF63ElwE8oJni0Ugrrs16SFwHLAnLpzZBQ5uuIOTVh1X PATH: C:\cygwin\bin;%PATH% OPENPACE_VER: 1.1.3 ZLIB_VER_DOT: 1.2.12 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 55be1522ca..30610096f6 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -53,4 +53,6 @@ jobs: - run: git config --global user.email "builds@github.com" - run: git config --global user.name "Github Actions"; - run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}" + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} if: ${{ github.repository == 'OpenSC/OpenSC' }} From a5f3b3bedb56a1d56f8d0a81c61a49885c498320 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 10 Aug 2023 19:45:56 +0200 Subject: [PATCH 3032/4321] fixed macOS build with OpenSSL pre-installed --- MacOSX/build-package.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 09e5aad840..e2618cb244 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -49,6 +49,8 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then fi export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`" export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`" + export CRYPTO_CFLAGS="$OPENSSL_CFLAGS" + export CRYPTO_LIBS="$OPENSSL_LIBS" fi # Locate the latest OSX SDK @@ -70,7 +72,7 @@ if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then fi cd openpace autoreconf -vis - ./configure --disable-shared --prefix=$PREFIX CRYPTO_CFLAGS="$OPENSSL_CFLAGS" CRYPTO_LIBS="$OPENSSL_LIBS" HELP2MAN=/usr/bin/true + ./configure --disable-shared --prefix=$PREFIX HELP2MAN=/usr/bin/true touch src/cvc-create.1 src/cvc-print.1 make DESTDIR=$BUILDPATH/openpace_bin install cd .. From 9821ef1814a9934a901c614412a28c46d0cc5113 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 11 Aug 2023 00:42:24 +0200 Subject: [PATCH 3033/4321] macos: always build OpenSSL by default locally installed versions of OpenSSL are likely not built with multi-arch support that we use in our build. For example, brew installations of OpenSSL (as in the CI pipeline) don't support multiple architectures. This fixes the CI macOS build. --- MacOSX/build-package.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index e2618cb244..16ffe2a3fe 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -8,6 +8,7 @@ # autoconf automake libtool pkg-config help2man gengetopt export MACOSX_DEPLOYMENT_TARGET="10.10" +FORCE_OPENSSL_BUILD="1" set -ex test -x ./configure || ./bootstrap @@ -23,7 +24,7 @@ export SED=/usr/bin/sed PREFIX=/Library/OpenSC export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig -if ! pkg-config libcrypto --atleast-version=1.0.1; then +if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-version=1.0.1; then # OpenSSL is not installed if ! test -e $BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig; then # Build OpenSSL manually, because Apple's binaries are deprecated From 772a0acad98008404c6408f34dd2b780b6a42a7c Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Fri, 11 Aug 2023 02:20:04 +0200 Subject: [PATCH 3034/4321] CI: fixed sleep syntax --- .github/push_artifacts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/push_artifacts.sh b/.github/push_artifacts.sh index 61d9f0702b..873c306c74 100755 --- a/.github/push_artifacts.sh +++ b/.github/push_artifacts.sh @@ -33,7 +33,7 @@ git commit --message "$1" i=0 while [ $i -le 10 ] && ! git push --quiet --set-upstream origin "${BRANCH}" do - sleep $[ ( $RANDOM % 32 ) + 1 ]s + sleep $[ ( $RANDOM % 32 ) + 1 ] git pull --rebase origin --strategy-option ours "${BRANCH}" i=$(( $i + 1 )) done From 5a95275ff06d55182c6203fa88a82d40dc74c032 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Thu, 3 Aug 2023 17:58:05 +0200 Subject: [PATCH 3035/4321] Indicate supported hashes and MGF1s (Fixes #2826) --- src/libopensc/card-sc-hsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index cd17fe18ce..4bcb660891 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1780,7 +1780,9 @@ static int sc_hsm_init(struct sc_card *card) LOG_FUNC_CALLED(card->ctx); - flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN; + flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN + |SC_ALGORITHM_RSA_HASH_SHA256|SC_ALGORITHM_RSA_HASH_SHA384|SC_ALGORITHM_RSA_HASH_SHA512 + |SC_ALGORITHM_MGF1_SHA256|SC_ALGORITHM_MGF1_SHA384|SC_ALGORITHM_MGF1_SHA512; _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 1536, flags, 0); From a5b4950c623d465ea46a06856cdcd55d0a8d0820 Mon Sep 17 00:00:00 2001 From: Andreas Schwier Date: Mon, 7 Aug 2023 13:33:02 +0200 Subject: [PATCH 3036/4321] Reject unsupported MGF/hash combinations --- src/libopensc/card-sc-hsm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 4bcb660891..e68975077e 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -1007,6 +1007,10 @@ static int sc_hsm_set_security_env(sc_card_t *card, priv->algorithm = ALGO_RSA_PKCS1; } } else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) { + if ((env->algorithm_flags & SC_ALGORITHM_RSA_HASHES) && + (((env->algorithm_flags & SC_ALGORITHM_MGF1_HASHES) >> 8) != (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES))) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } priv->algorithm = ALGO_RSA_PSS; } else { if (env->operation == SC_SEC_OPERATION_DECIPHER) { From 47e7e4f31affc6852e082b2b1fc28877ab36459f Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 14 Aug 2023 11:11:07 +0300 Subject: [PATCH 3037/4321] According configure.ac minumum OpenSSL is 1.1.1 Signed-off-by: Raul Metsma --- MacOSX/build-package.in | 2 +- configure.ac | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/MacOSX/build-package.in b/MacOSX/build-package.in index 16ffe2a3fe..dfde05dcf2 100755 --- a/MacOSX/build-package.in +++ b/MacOSX/build-package.in @@ -24,7 +24,7 @@ export SED=/usr/bin/sed PREFIX=/Library/OpenSC export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig -if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-version=1.0.1; then +if test "$FORCE_OPENSSL_BUILD" == "1" || ! pkg-config libcrypto --atleast-version=1.1.1; then # OpenSSL is not installed if ! test -e $BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig; then # Build OpenSSL manually, because Apple's binaries are deprecated diff --git a/configure.ac b/configure.ac index 0a90445b9e..d7cac8a3a7 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,7 @@ define([VS_FF_PRODUCT_URL], [https://github.com/OpenSC/OpenSC]) m4_sinclude(m4/version.m4.ci) +# Hint: MacOSX/build-package.in contains minimum OpenSSL reference m4_define([openssl_minimum_version], [1.1.1]) AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX],[PRODUCT_BUGREPORT],[PRODUCT_TARNAME],[PRODUCT_URL]) From 720de5ddaca089c093e20ce3ad5fbba982e0bf92 Mon Sep 17 00:00:00 2001 From: Bernd Kuhls Date: Mon, 24 Jul 2023 22:28:11 +0200 Subject: [PATCH 3038/4321] configure: add option to disable tests --- configure.ac | 9 +++++++++ src/Makefile.am | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d7cac8a3a7..de7e57ae6d 100644 --- a/configure.ac +++ b/configure.ac @@ -273,6 +273,13 @@ AC_ARG_ENABLE( [enable_doc="no"] ) +AC_ARG_ENABLE( + [tests], + [AS_HELP_STRING([--enable-tests],[enable tests @<:@enabled@:>@])], + , + [enable_tests="yes"] +) + AC_ARG_ENABLE( [dnie-ui], [AS_HELP_STRING([--enable-dnie-ui],[enable use of external user interface program to request DNIe pin@<:@disabled@:>@])], @@ -1120,6 +1127,7 @@ AM_CONDITIONAL([ENABLE_NOTIFY], [test "${enable_notify}" = "yes"]) AM_CONDITIONAL([ENABLE_CRYPTOTOKENKIT], [test "${enable_cryptotokenkit}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"]) AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"]) +AM_CONDITIONAL([ENABLE_TESTS], [test "${enable_tests}" = "yes"]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"]) AM_CONDITIONAL([ENABLE_MINIDRIVER], [test "${enable_minidriver}" = "yes"]) @@ -1214,6 +1222,7 @@ XSL stylesheets: ${xslstylesheetsdir} man support: ${enable_man} doc support: ${enable_doc} +tests: ${enable_tests} thread locking support: ${enable_thread_locking} zlib support: ${enable_zlib} readline support: ${enable_readline} diff --git a/src/Makefile.am b/src/Makefile.am index 3ce465bfdb..bf71b61f7c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,11 @@ EXTRA_DIST = Makefile.mak # Order IS important SUBDIRS = common scconf ui pkcs15init sm \ - libopensc pkcs11 tools minidriver tests + libopensc pkcs11 tools minidriver + +if ENABLE_TESTS +SUBDIRS += tests +endif if ENABLE_SM SUBDIRS += smm From 02b37bf38d5cfbe68088de647553c36e00b5b02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Mon, 7 Aug 2023 15:08:37 +0200 Subject: [PATCH 3039/4321] pkcs15.c: Fix memory leaks in sc_pkcs15_get_lastupdate Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60497 --- src/libopensc/pkcs15.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index a8f91ddf33..eb7fc6afcd 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -548,18 +548,19 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card) return NULL; size = file->size ? file->size : 1024; + sc_file_free(file); content = calloc(size, 1); if (!content) return NULL; r = sc_read_binary(p15card->card, 0, content, size, 0); - if (r < 0) + if (r < 0) { + free(content); return NULL; + } content_len = r; - sc_file_free(file); - sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update); sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0); From 638a5007a5d240d6fa901aa822cfeef94fe36e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 12:20:33 +0200 Subject: [PATCH 3040/4321] pkcs15-pubkey.c: Avoid double-free Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60616 --- src/libopensc/pkcs15-pubkey.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 7107c47cbc..49b514968b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -351,8 +351,12 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, err: if (r < 0) { sc_pkcs15_free_pubkey_info(info); - if (der->len) + if (der->len) { free(der->value); + /* der points to obj->content */ + obj->content.value = NULL; + obj->content.len = 0; + } } LOG_FUNC_RETURN(ctx, r); From 6287fe3dfc7b44982b341150a56cb769655b6fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 12:44:23 +0200 Subject: [PATCH 3041/4321] card-oberthur.c: Free file before overwritting Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60667 --- src/libopensc/card-oberthur.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 5036ebbdf6..9757dc86fc 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -534,6 +534,11 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, memcpy(&tmp_path, &auth_current_df->path, sizeof(struct sc_path)); tmp_path.type = SC_PATH_TYPE_PARENT; + if (file_out) { + sc_file_free(*file_out); + *file_out = NULL; + } + rv = auth_select_file (card, &tmp_path, file_out); LOG_TEST_RET(card->ctx, rv, "select file failed"); } @@ -549,6 +554,11 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, for (ii=0; ii < path.len - offs; ii+=2) { memcpy(tmp_path.value, path.value + offs + ii, 2); + if (file_out) { + sc_file_free(*file_out); + *file_out = NULL; + } + rv = auth_select_file(card, &tmp_path, file_out); LOG_TEST_RET(card->ctx, rv, "select file failed"); } From aa4b47e33c43716877b8fa6e671125530d5b12ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 13:44:49 +0200 Subject: [PATCH 3042/4321] pkcs15-setcos.c: Free file in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6067 --- src/pkcs15init/pkcs15-setcos.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 450ad595fa..b570305189 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -348,20 +348,23 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, file->size = 512; /* Replace the path of instantiated key template by the path from the object data. */ - memcpy(&file->path, &key_info->path, sizeof(file->path)); - file->id = file->path.value[file->path.len - 2] * 0x100 - + file->path.value[file->path.len - 1]; + memcpy(&file->path, &key_info->path, sizeof(file->path)); + file->id = file->path.value[file->path.len - 2] * 0x100 + + file->path.value[file->path.len - 1]; key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF; - sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); + sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); - r = sc_select_file(p15card->card, &file->path, NULL); - if (!r) { + r = sc_select_file(p15card->card, &file->path, NULL); + if (!r) { r = sc_pkcs15init_delete_by_path(profile, p15card, &file->path); + if (r != SC_SUCCESS) + sc_file_free(file); LOG_TEST_RET(ctx, r, "Failed to delete private key file"); } else if (r != SC_ERROR_FILE_NOT_FOUND) { + sc_file_free(file); LOG_TEST_RET(ctx, r, "Select private key file error"); } From 6085994384a7171c5c68f6718d9db10ed77c5af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 13:56:24 +0200 Subject: [PATCH 3043/4321] card-entersafe.c: Free modulus buffer in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60680 --- src/libopensc/card-entersafe.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index eb31f71460..168894abd9 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -1423,12 +1423,18 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY); p=rbuf; - if (*p!='E') + if (*p!='E') { + free(data->modulus); + data->modulus = NULL; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); + } p+=2+p[1]; /* N */ - if (*p!='N') + if (*p!='N') { + free(data->modulus); + data->modulus = NULL; SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); + } ++p; if(*p++>0x80) { From 1443ff6cc76a9cf7f72d0b670f366a5ac07255f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 14:02:31 +0200 Subject: [PATCH 3044/4321] muscle.c: Free modulus in case of error Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60717 --- src/libopensc/muscle.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index d881c137d0..0ea07077e0 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -627,8 +627,10 @@ int msc_extract_rsa_public_key(sc_card_t *card, if(!*modulus) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(*modulus, buffer, *modLength); *expLength = (buffer[*modLength] << 8) | buffer[*modLength + 1]; - if (*expLength > sizeof buffer) + if (*expLength > sizeof buffer) { + free(*modulus); *modulus = NULL; return SC_ERROR_OUT_OF_MEMORY; + } r = msc_read_object(card, inputId, fileLocation, buffer, *expLength); if(r < 0) { free(*modulus); *modulus = NULL; From 04be2e6799cd33dcdad9d88df76493d5e80440b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 10 Aug 2023 14:19:35 +0200 Subject: [PATCH 3045/4321] pkcs15-oberthur.c: Fix memory leaks when generating key Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60754 --- src/pkcs15init/pkcs15-oberthur.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index e61377501e..377e28948e 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -572,6 +572,10 @@ cosm_get_temporary_public_key_file(struct sc_card *card, file->size = prvkey_file->size; entry = sc_file_get_acl_entry(prvkey_file, SC_AC_OP_UPDATE); + if (!entry) { + sc_file_free(file); + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Failed to find ACL entry"); + } rv = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, entry->method, entry->key_ref); if (!rv) rv = sc_file_add_acl_entry(file, SC_AC_OP_PSO_ENCRYPT, SC_AC_NONE, 0); @@ -625,9 +629,13 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, /* In the private key DF create the temporary public RSA file. */ rv = cosm_get_temporary_public_key_file(p15card->card, prkf, &tmpf); + if (rv != SC_SUCCESS) + sc_file_free(prkf); LOG_TEST_RET(ctx, rv, "Error while getting temporary public key file"); rv = sc_pkcs15init_create_file(profile, p15card, tmpf); + if (rv != SC_SUCCESS) + sc_file_free(prkf); LOG_TEST_RET(ctx, rv, "cosm_generate_key() failed to create temporary public key EF"); memset(&args, 0, sizeof(args)); @@ -637,24 +645,41 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, args.key_bits = key_info->modulus_length; args.pubkey_len = key_info->modulus_length / 8; args.pubkey = malloc(key_info->modulus_length / 8); - if (!args.pubkey) + if (!args.pubkey) { + sc_file_free(prkf); + sc_file_free(tmpf); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey"); + } rv = sc_card_ctl(p15card->card, SC_CARDCTL_OBERTHUR_GENERATE_KEY, &args); + if (rv != SC_SUCCESS) { + sc_file_free(prkf); + sc_file_free(tmpf); + free(args.pubkey); + } LOG_TEST_RET(ctx, rv, "cosm_generate_key() CARDCTL_OBERTHUR_GENERATE_KEY failed"); /* extract public key */ pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = key_info->modulus_length / 8; pubkey->u.rsa.modulus.data = malloc(key_info->modulus_length / 8); - if (!pubkey->u.rsa.modulus.data) + if (!pubkey->u.rsa.modulus.data) { + sc_file_free(prkf); + sc_file_free(tmpf); + free(args.pubkey); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf"); + } /* FIXME and if the exponent length is not 3? */ pubkey->u.rsa.exponent.len = 3; pubkey->u.rsa.exponent.data = malloc(3); - if (!pubkey->u.rsa.exponent.data) + if (!pubkey->u.rsa.exponent.data) { + sc_file_free(prkf); + sc_file_free(tmpf); + free(args.pubkey); + free(pubkey->u.rsa.modulus.data); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate exponent buf"); + } memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len); @@ -666,6 +691,7 @@ cosm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_file_free(tmpf); sc_file_free(prkf); + free(args.pubkey); LOG_FUNC_RETURN(ctx, rv); } From ffbff25ec6c6d0ad3f8df76f57210698f7947fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 11 Aug 2023 09:44:57 +0200 Subject: [PATCH 3046/4321] fuzz_pkcs11.c: Use valid data for verify Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60971 --- src/tests/fuzzing/fuzz_pkcs11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/fuzzing/fuzz_pkcs11.c b/src/tests/fuzzing/fuzz_pkcs11.c index b6e05c9ad5..fdc163b485 100644 --- a/src/tests/fuzzing/fuzz_pkcs11.c +++ b/src/tests/fuzzing/fuzz_pkcs11.c @@ -512,7 +512,7 @@ static void test_verify(const uint8_t *data, size_t size) while (verify_data_size > 0) { to_process = verify_data_size < sizeof(in_buffer) ? verify_data_size : sizeof(in_buffer); verify_data_size -= to_process; - memcpy(in_buffer, data, to_process); + memcpy(in_buffer, verify_data, to_process); verify_data += to_process; if (p11->C_VerifyUpdate(session, in_buffer, to_process) != CKR_OK) From f895de895e4c743251516f611b117b2a4f4df237 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Aug 2023 15:24:59 +0200 Subject: [PATCH 3047/4321] doc: Remove wrong copy&paste configuration option --- doc/tools/pkcs15-init.1.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/tools/pkcs15-init.1.xml b/doc/tools/pkcs15-init.1.xml index 5dfdb2a914..197d11be5f 100644 --- a/doc/tools/pkcs15-init.1.xml +++ b/doc/tools/pkcs15-init.1.xml @@ -611,8 +611,7 @@ - , - + From 0864d1cab15451135c910df5d68c048173fac92c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Aug 2023 12:12:57 +0200 Subject: [PATCH 3048/4321] ci: Fix building packit action and improve error reporting --- .github/test-packit.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/test-packit.sh b/.github/test-packit.sh index 07a8ff8e7b..e721059175 100755 --- a/.github/test-packit.sh +++ b/.github/test-packit.sh @@ -1,8 +1,10 @@ #!/bin/bash +set -ex -o xtrace + # Install build requirements REQUIREMENTS=$(sed -n -e '/^BuildRequires*/p' packaging/opensc.spec | sed 's/[^ ]* //') -sudo dnf install -y ${REQUIREMENTS} +dnf install -y ${REQUIREMENTS} # Run packit packit --debug build locally From afd768b924e82340875106fb71330a5f47e20b63 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Aug 2023 12:31:31 +0200 Subject: [PATCH 3049/4321] tests: Do not use valgrind-related environment when running without valgrind --- src/tests/unittests/Makefile.am | 2 ++ tests/Makefile.am | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 54e05ecdbd..7019ca7ba8 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -7,10 +7,12 @@ clean-local: code-coverage-clean distclean-local: code-coverage-dist-clean @VALGRIND_CHECK_RULES@ +if VALGRIND_ENABLED #VALGRIND_SUPPRESSIONS_FILES = $(top_srcdir)/tests/opensc.supp VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all # to avoid false positive leaks from pcsclite TESTS_ENVIRONMENT = LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1' +endif noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature check_macro_reference_loop TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature check_macro_reference_loop diff --git a/tests/Makefile.am b/tests/Makefile.am index 3fafd27fb3..e44da8588e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,22 +1,25 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +TEST_EXTENSIONS = .sh +# This pushes the valgrind command to the test environment +AM_TESTS_ENVIRONMENT = \ + SOURCE_PATH='$(top_srcdir)'; \ + export SOURCE_PATH; \ + BUILD_PATH='$(top_builddir)'; \ + export BUILD_PATH; + @VALGRIND_CHECK_RULES@ +if VALGRIND_ENABLED #VALGRIND_SUPPRESSIONS_FILES = opensc.supp #EXTRA_DIST = opensc.supp VALGRIND_FLAGS = --num-callers=30 -q --keep-debuginfo=yes --gen-suppressions=all # Do not run the bash scripts under valgrind -TEST_EXTENSIONS = .sh LOG_COMPILER = $(LOG_VALGRIND) - -# This pushes the valgrind command to the test environment # the LD_PRELOAD is to avoid false positive leaks from pcsclite -AM_TESTS_ENVIRONMENT = \ - SOURCE_PATH='$(top_srcdir)'; \ - export SOURCE_PATH; \ - BUILD_PATH='$(top_builddir)'; \ - export BUILD_PATH; \ +AM_TESTS_ENVIRONMENT += \ VALGRIND='$(LOG_VALGRIND)'; \ LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libpcsclite.so.1'; +endif dist_noinst_SCRIPTS = common.sh \ test-manpage.sh \ From 4393910602376b2da9225b568562884a8e17d0aa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Aug 2023 12:56:58 +0200 Subject: [PATCH 3050/4321] packaging: dump logs on failure during RPM build --- packaging/opensc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 79fe73125b..6f3005b685 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -75,7 +75,7 @@ CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations" %check -make check +make check || (cat tests/*.log src/tests/unittests/*.log && exit 1) %install From fe5b82f0c1b4649d53ebf420af7a6bf5169a1daa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Aug 2023 16:53:56 +0200 Subject: [PATCH 3051/4321] tests: Use openssl pkeyutl instead of deprecated rsautl --- tests/test-pkcs11-tool-sign-verify.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 6b974fb2a0..514611e5a0 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -37,6 +37,8 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do # OpenSSL verification if [[ -z $HASH ]]; then openssl rsautl -verify -inkey $SIGN_KEY.pub -in data.sig -pubin + # pkeyutl does not work with libressl + #openssl pkeyutl -verify -inkey $SIGN_KEY.pub -in data -sigfile data.sig -pubin else openssl dgst -keyform PEM -verify $SIGN_KEY.pub -${HASH,,*} \ -signature data.sig data @@ -110,6 +112,9 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do # OpenSSL Encryption openssl rsautl -encrypt -inkey $ENC_KEY.pub -in data \ -pubin -out data.crypt + # pkeyutl does not work with libressl + #openssl pkeyutl -encrypt -inkey $ENC_KEY.pub -in data \ + # -pubin -out data.crypt assert $? "Failed to encrypt data using OpenSSL" $PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN -m $METHOD \ --module $P11LIB --input-file data.crypt > data.decrypted From 8b197fc455dc7fb5ca4bdccaec89cb7e27845253 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 14 Aug 2023 21:19:29 +0200 Subject: [PATCH 3052/4321] tests: Make the sign/verify test aware of the OS and expect the SHA1 operations to fail --- tests/test-pkcs11-tool-sign-verify.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/test-pkcs11-tool-sign-verify.sh b/tests/test-pkcs11-tool-sign-verify.sh index 514611e5a0..8f8df6dd3c 100755 --- a/tests/test-pkcs11-tool-sign-verify.sh +++ b/tests/test-pkcs11-tool-sign-verify.sh @@ -13,10 +13,18 @@ fi card_setup assert $? "Failed to set up card" +# get informaation about OS +source /etc/os-release || true + echo "=======================================================" echo "Test RSA keys" echo "=======================================================" for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do + RETOSSL="0" + + if [[ "$ID" == "rhel" || "$ID_LIKE" =~ ".*rhel.*" ]] && [[ "$VERSION" -gt 8 ]] && [[ "$HASH" == "SHA1" ]]; then + RETOSSL="1" + fi for SIGN_KEY in "01" "02"; do METHOD="RSA-PKCS" # RSA-PKCS works only on small data - generate small data: @@ -43,7 +51,11 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do openssl dgst -keyform PEM -verify $SIGN_KEY.pub -${HASH,,*} \ -signature data.sig data fi - assert $? "Failed to Verify signature using OpenSSL" + if [[ "$RETOSSL" == "0" ]]; then + assert $? "Failed to Verify signature using OpenSSL" + elif [[ "$?" == "0" ]]; then + assert 1 "Unexpectedly Verified signature using OpenSSL" + fi # pkcs11-tool verification $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ @@ -87,7 +99,11 @@ for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ -sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ -signature data.sig data - assert $? "Failed to Verify signature using openssl" + if [[ "$RETOSSL" == "0" ]]; then + assert $? "Failed to Verify signature using openssl" + elif [[ "$?" == "0" ]]; then + assert 1 "Unexpectedly Verified signature using OpenSSL" + fi # pkcs11-tool verification $PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ From f8f0356bc7ed3c1ffad49e723d3b5814dca1a2ca Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Aug 2023 16:49:02 +0200 Subject: [PATCH 3053/4321] pkcs11: Create relative symlinks when installing compat onepin --- src/pkcs11/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/Makefile.am b/src/pkcs11/Makefile.am index cd8798356b..8fb404a09a 100644 --- a/src/pkcs11/Makefile.am +++ b/src/pkcs11/Makefile.am @@ -74,8 +74,9 @@ uninstall-hook: else # see http://wiki.cacert.org/wiki/Pkcs11TaskForce install-exec-hook: - rm -f "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" - $(LN_S) "$(DESTDIR)$(libdir)/opensc-pkcs11$(DYN_LIB_EXT)" "$(DESTDIR)$(libdir)/onepin-opensc-pkcs11$(DYN_LIB_EXT)" + cd $(DESTDIR)$(libdir) && \ + rm -f "onepin-opensc-pkcs11$(DYN_LIB_EXT)" && \ + $(LN_S) "opensc-pkcs11$(DYN_LIB_EXT)" "onepin-opensc-pkcs11$(DYN_LIB_EXT)" $(MKDIR_P) "$(DESTDIR)$(pkcs11dir)" for l in opensc-pkcs11$(DYN_LIB_EXT) onepin-opensc-pkcs11$(DYN_LIB_EXT) pkcs11-spy$(DYN_LIB_EXT); do \ rm -f "$(DESTDIR)$(pkcs11dir)/$$l"; \ From abdfcdddcb93b7ec916774d7769b7892f666c342 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Aug 2023 16:50:52 +0200 Subject: [PATCH 3054/4321] Revert "remove onepin module from packaging" This reverts commit 55c40af86e791ace1a14ab56c38bbeb3d1ad7191. --- packaging/opensc.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/opensc.spec b/packaging/opensc.spec index 6f3005b685..f7de26d673 100644 --- a/packaging/opensc.spec +++ b/packaging/opensc.spec @@ -161,8 +161,10 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_libdir}/lib*.so.* %{_libdir}/opensc-pkcs11.so %{_libdir}/pkcs11-spy.so +%{_libdir}/onepin-opensc-pkcs11.so %dir %{_libdir}/pkcs11 %{_libdir}/pkcs11/opensc-pkcs11.so +%{_libdir}/pkcs11/onepin-opensc-pkcs11.so %{_libdir}/pkcs11/pkcs11-spy.so %{_datadir}/opensc/ %{_mandir}/man1/cardos-tool.1* From 33351d91aa22fa8077847ba3f19abb5a00b04600 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 15 Aug 2023 17:58:21 +0200 Subject: [PATCH 3055/4321] fixed detection of SHA3 compatibility fixes https://github.com/OpenSC/OpenSC/issues/2836 --- src/libopensc/sc-ossl-compat.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h index 8012cd4c0f..96ec4bd736 100644 --- a/src/libopensc/sc-ossl-compat.h +++ b/src/libopensc/sc-ossl-compat.h @@ -50,7 +50,8 @@ extern "C" { #if LIBRESSL_VERSION_NUMBER < 0x30500000L #define FIPS_mode() (0) #endif -#ifndef EVP_sha3_224 +/* OpenSSL 1.1.1 has EVP_sha3_* */ +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x30800000L #define EVP_sha3_224() (NULL) #define EVP_sha3_256() (NULL) #define EVP_sha3_384() (NULL) From c60410c5c4aaab96a0893ea34eedf4498dfdc08d Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Sat, 19 Aug 2023 02:17:58 +0300 Subject: [PATCH 3056/4321] sc_pkcs11_en/decrypt: do not add to null pointer which might then get dereferenced by the card driver --- src/pkcs11/mechanism.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 39ec464f68..03495265a4 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -1410,7 +1410,9 @@ sc_pkcs11_encrypt(sc_pkcs11_operation_t *operation, /* EncryptFinalize */ rv = key->ops->encrypt(operation->session, key, &operation->mechanism, - NULL, 0, pEncryptedData + ulEncryptedDataLen, &ulLastEncryptedPartLen); + NULL, 0, + pEncryptedData ? pEncryptedData + ulEncryptedDataLen : NULL, + &ulLastEncryptedPartLen); if (pulEncryptedDataLen) *pulEncryptedDataLen = ulEncryptedDataLen + ulLastEncryptedPartLen; @@ -1545,7 +1547,8 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation, /* DecryptFinalize */ rv = key->ops->decrypt(operation->session, key, &operation->mechanism, - NULL, 0, pData + ulDataLen, &ulLastDataLen); + NULL, 0, pData ? pData + ulDataLen : NULL, + &ulLastDataLen); if (pulDataLen) *pulDataLen = ulDataLen + ulLastDataLen; return rv; From 38f437f182475ec01c52ff1bce725c14dfcbdf92 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 11:21:36 +0200 Subject: [PATCH 3057/4321] setcos: Reformat for readability --- src/pkcs15init/pkcs15-setcos.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index b570305189..ea1d42438a 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -334,10 +334,10 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); /* Parameter check */ - if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) + if ((keybits < 512) || (keybits > 1024) || (keybits & 0x7)) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); - sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); + sc_log(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id)); /* Get the private key file */ r = setcos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file); @@ -350,20 +350,19 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Replace the path of instantiated key template by the path from the object data. */ memcpy(&file->path, &key_info->path, sizeof(file->path)); file->id = file->path.value[file->path.len - 2] * 0x100 - + file->path.value[file->path.len - 1]; + + file->path.value[file->path.len - 1]; key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF; sc_log(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path)); r = sc_select_file(p15card->card, &file->path, NULL); - if (!r) { + if (!r) { r = sc_pkcs15init_delete_by_path(profile, p15card, &file->path); if (r != SC_SUCCESS) sc_file_free(file); LOG_TEST_RET(ctx, r, "Failed to delete private key file"); - } - else if (r != SC_ERROR_FILE_NOT_FOUND) { + } else if (r != SC_ERROR_FILE_NOT_FOUND) { sc_file_free(file); LOG_TEST_RET(ctx, r, "Select private key file error"); } @@ -492,7 +491,7 @@ setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (keybits != key_info->modulus_length) { - sc_log(ctx, + sc_log(ctx, "key-size from card[%"SC_FORMAT_LEN_SIZE_T"u] does not match[%"SC_FORMAT_LEN_SIZE_T"u]\n", keybits, key_info->modulus_length); LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key"); From ef42ab7c2f0159b45963a04927c754f4453d94c2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 11:31:05 +0200 Subject: [PATCH 3058/4321] setcos: Avoid use after free This issue can happen only in case the sc_select_file() would return positive value, which should never happen. Resetting the value to NULL should resolve even this theoretical use after free. Thanks coverity CID 398496 --- src/pkcs15init/pkcs15-setcos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index ea1d42438a..1b56afe6d9 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -364,6 +364,7 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, LOG_TEST_RET(ctx, r, "Failed to delete private key file"); } else if (r != SC_ERROR_FILE_NOT_FOUND) { sc_file_free(file); + file = NULL; LOG_TEST_RET(ctx, r, "Select private key file error"); } From 010d3f4a5b3fdbf9c393b1a85d261fcb3ff5d207 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 11:54:38 +0200 Subject: [PATCH 3059/4321] profile: Reformat for readability --- src/pkcs15init/profile.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index b398604fbd..ba2b22ee56 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -646,8 +646,7 @@ sc_profile_add_file(sc_profile_t *profile, const char *name, sc_file_t *file) LOG_FUNC_CALLED(ctx); if (!path.len) { parent = profile->df_info; - } - else { + } else { path.len -= 2; parent = sc_profile_find_file_by_path(profile, &path); } From ce7fcdaa35196706a83fe982900228e15464f928 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 11:55:06 +0200 Subject: [PATCH 3060/4321] oberthur: Avoid heap buffer overflow Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60650 --- src/pkcs15init/pkcs15-oberthur.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 377e28948e..b20bd6e6c4 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -531,7 +531,9 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, } file->id |= (num & 0xFF); - file->path.value[file->path.len-1] |= (num & 0xFF); + if (file->path.len) { + file->path.value[file->path.len - 1] |= (num & 0xFF); + } if (file->type == SC_FILE_TYPE_INTERNAL_EF) { file->ef_structure = structure; } From 440ca666eff10cc7011901252d20f3fc4ea23651 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 13:41:36 +0200 Subject: [PATCH 3061/4321] setcos: Avoid buffer underflow Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60672 --- src/pkcs15init/pkcs15-setcos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 1b56afe6d9..1907b47f9d 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -349,6 +349,10 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Replace the path of instantiated key template by the path from the object data. */ memcpy(&file->path, &key_info->path, sizeof(file->path)); + if (file->path.len < 2) { + sc_file_free(file); + LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid path"); + } file->id = file->path.value[file->path.len - 2] * 0x100 + file->path.value[file->path.len - 1]; From 245efe608d083fd4e4ec96793fdefd218e26fde7 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 17 Aug 2023 13:54:42 +0200 Subject: [PATCH 3062/4321] pkcs15: Avoid buffer overflow when getting last update Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60769 --- src/libopensc/pkcs15.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index eb7fc6afcd..4215b733a8 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -532,7 +532,7 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card) struct sc_context *ctx = p15card->card->ctx; struct sc_file *file = NULL; struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE]; - unsigned char *content, last_update[32]; + unsigned char *content, last_update[32] = {0}; size_t lupdate_len = sizeof(last_update) - 1; int r, content_len; size_t size; @@ -569,9 +569,11 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card) if (r < 0) return NULL; - p15card->tokeninfo->last_update.gtime = strdup((char *)last_update); - if (!p15card->tokeninfo->last_update.gtime) - return NULL; + if (asn1_last_update[0].flags & SC_ASN1_PRESENT) { + p15card->tokeninfo->last_update.gtime = strdup((char *)last_update); + if (!p15card->tokeninfo->last_update.gtime) + return NULL; + } done: sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime); return p15card->tokeninfo->last_update.gtime; @@ -2401,7 +2403,7 @@ sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_p return 0; } -static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, +static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen, unsigned char **out, size_t *outlen, unsigned long flags) { LOG_FUNC_CALLED(card->ctx); @@ -2509,13 +2511,13 @@ sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_pat } else { len = MAX_FILE_SIZE; } - + if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) { sc_log(ctx, " record number out of bounds: %d", in_path->index); r = SC_ERROR_RECORD_NOT_FOUND; goto fail_unlock; } - + } else { if (in_path->count < 0) { From 42d32d350dfdcb4008546479ba6859a1bdec92d9 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 17:24:55 +0300 Subject: [PATCH 3063/4321] p11test: fix init for myeid --- src/tests/p11test/runtest.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index ae5e97b1ef..8e4f3728ef 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -129,15 +129,15 @@ function card_setup() { ;; "myeid") GENERATE_KEYS=0 # we generate them directly here - P11LIB="../pkcs11/.libs/opensc-pkcs11.so" - PKCS15_INIT --erase-card --so-pin $SOPIN - PKCS15_INIT -C --pin $PIN --puk $SOPIN --so-pin $SOPIN --so-puk $SOPIN - PKCS15_INIT -P -a 1 -l "Basic PIN" --pin $PIN --puk $PIN - INIT=$PKCS15_INIT --auth-id 01 --so-pin $SOPIN --pin $PIN - INIT --generate-key ec:prime256v1 --id 01 --label="EC key" - INIT --generate-key rsa:2048 --id 02 --label="RSA key" --key-usage=sign,decrypt - INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES key" --key-usage=sign,decrypt - PKCS15_INIT -F + P11LIB="../../pkcs11/.libs/opensc-pkcs11.so" + $PKCS15_INIT --erase-card --so-pin $SOPIN + $PKCS15_INIT -C --pin $PIN --puk $SOPIN --so-pin $SOPIN --so-puk $SOPIN + $PKCS15_INIT -P -a 1 -l "Basic PIN" --pin $PIN --puk $PIN + INIT="$PKCS15_INIT --auth-id 01 --so-pin $SOPIN --pin $PIN" + $INIT --generate-key ec:prime256v1 --id 01 --label="EC key" + $INIT --generate-key rsa:2048 --id 02 --label="RSA key" --key-usage=sign,decrypt + $INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES key" --key-usage=sign,decrypt + $PKCS15_INIT -F ;; *) echo "Error: Missing argument." From 36ce2724cab8a06216072571342f7f9ccdc68f75 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 20:08:18 +0300 Subject: [PATCH 3064/4321] p11test: use ECDH key on myeid --- src/tests/p11test/runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index 8e4f3728ef..90af942561 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -134,7 +134,7 @@ function card_setup() { $PKCS15_INIT -C --pin $PIN --puk $SOPIN --so-pin $SOPIN --so-puk $SOPIN $PKCS15_INIT -P -a 1 -l "Basic PIN" --pin $PIN --puk $PIN INIT="$PKCS15_INIT --auth-id 01 --so-pin $SOPIN --pin $PIN" - $INIT --generate-key ec:prime256v1 --id 01 --label="EC key" + $INIT --generate-key ec:prime256v1 --id 01 --label="EC key" --key-usage=sign,keyAgreement $INIT --generate-key rsa:2048 --id 02 --label="RSA key" --key-usage=sign,decrypt $INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES key" --key-usage=sign,decrypt $PKCS15_INIT -F From c74ab646af2767417d03e1a5679c40f806a7649c Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Sat, 19 Aug 2023 11:13:13 +0300 Subject: [PATCH 3065/4321] p11test: add AES128 key for myeid --- src/tests/p11test/runtest.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/runtest.sh b/src/tests/p11test/runtest.sh index 90af942561..994a2d8a2b 100755 --- a/src/tests/p11test/runtest.sh +++ b/src/tests/p11test/runtest.sh @@ -136,7 +136,8 @@ function card_setup() { INIT="$PKCS15_INIT --auth-id 01 --so-pin $SOPIN --pin $PIN" $INIT --generate-key ec:prime256v1 --id 01 --label="EC key" --key-usage=sign,keyAgreement $INIT --generate-key rsa:2048 --id 02 --label="RSA key" --key-usage=sign,decrypt - $INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES key" --key-usage=sign,decrypt + $INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --extractable --id 03 --label="AES256 key" --key-usage=sign,decrypt + $INIT --store-secret-key /dev/urandom --secret-key-algorithm aes:128 --extractable --id 04 --label="AES128 key" --key-usage=sign,decrypt $PKCS15_INIT -F ;; *) From e7b9306329809939bef718f5c6996fe6345a925b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Thu, 24 Aug 2023 16:10:10 +0200 Subject: [PATCH 3066/4321] iasecc: Fix memory leaks when creating key Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61547 --- src/pkcs15init/pkcs15-iasecc.c | 44 ++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 0066b0852e..31250d0d9f 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -470,25 +470,33 @@ iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, sdo->not_on_card = 1; rv = iasecc_sdo_set_key_acls_from_profile(profile, card, "private-key", sdo); + if (rv != SC_SUCCESS) + iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "IasEcc: cannot set ACLs for SDO from the 'private-key'"); /* FIXME: set here sdo->docp.name and sdo->docp.idata */ sdo->docp.non_repudiation.value = calloc(1, 1); - if (!sdo->docp.non_repudiation.value) + if (!sdo->docp.non_repudiation.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->docp.non_repudiation.tag = IASECC_DOCP_TAG_NON_REPUDIATION; sdo->docp.non_repudiation.size = 1; sdo->data.prv_key.compulsory.value = calloc(1, 1); - if (!sdo->data.prv_key.compulsory.value) + if (!sdo->data.prv_key.compulsory.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->data.prv_key.compulsory.tag = IASECC_SDO_PRVKEY_TAG_COMPULSORY; sdo->data.prv_key.compulsory.size = 1; sdo->docp.size.value = calloc(1, 2); - if (!sdo->docp.size.value) + if (!sdo->docp.size.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->docp.size.tag = IASECC_DOCP_TAG_SIZE; sdo->docp.size.size = 2; *(sdo->docp.size.value + 0) = (sz >> 8) & 0xFF; @@ -513,13 +521,14 @@ iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, sc_log(ctx, "compulsory 0x%X", *(sdo->data.prv_key.compulsory.value + 0)); } else { + iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "IasEcc: error while getting private key SDO data"); } if (out) *out = sdo; else - free(sdo); + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -549,11 +558,15 @@ iasecc_sdo_allocate_pubkey(struct sc_profile *profile, struct sc_card *card, str sdo->not_on_card = 1; rv = iasecc_sdo_set_key_acls_from_profile(profile, card, "public-key", sdo); + if (rv != SC_SUCCESS) + iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "iasecc_sdo_allocate_pubkey() cannot set ACLs for SDO from the 'public-key'"); sdo->docp.size.value = calloc(1, 2); - if (!sdo->docp.size.value) + if (!sdo->docp.size.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->docp.size.size = 2; sdo->docp.size.tag = IASECC_DOCP_TAG_SIZE; *(sdo->docp.size.value + 0) = (sz >> 8) & 0xFF; @@ -564,26 +577,31 @@ iasecc_sdo_allocate_pubkey(struct sc_profile *profile, struct sc_card *card, str } else { sdo->data.pub_key.cha.value = calloc(1, 2); - if (!sdo->data.pub_key.cha.value) + if (!sdo->data.pub_key.cha.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->data.pub_key.cha.size = 2; sdo->data.pub_key.cha.tag = IASECC_SDO_PUBKEY_TAG_CHA; } sdo->data.pub_key.compulsory.value = calloc(1, 1); - if (!sdo->data.pub_key.compulsory.value) + if (!sdo->data.pub_key.compulsory.value) { + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + } sdo->data.pub_key.compulsory.tag = IASECC_SDO_PUBKEY_TAG_COMPULSORY; sdo->data.pub_key.compulsory.size = 1; } else { + iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "iasecc_sdo_allocate_pubkey() error while getting public key SDO data"); } if (out) *out = sdo; else - free(sdo); + iasecc_sdo_free(card, sdo); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } @@ -1079,7 +1097,7 @@ iasecc_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15c sc_log(ctx, "iasecc_pkcs15_create_key() sdo_pubkey->not_on_card %i", sdo_pubkey->not_on_card); rv = iasecc_sdo_allocate_prvkey(profile, card, key_info, &sdo_prvkey); - LOG_TEST_RET(ctx, rv, "IasEcc: init SDO private key failed"); + LOG_TEST_GOTO_ERR(ctx, rv, "IasEcc: init SDO private key failed"); sc_log(ctx, "iasecc_pkcs15_create_key() sdo_prvkey->not_on_card %i", sdo_prvkey->not_on_card); if (!sdo_prvkey->not_on_card && !sdo_pubkey->not_on_card) { @@ -1087,18 +1105,20 @@ iasecc_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15c } else { rv = iasecc_pkcs15_create_key_slot(profile, p15card, sdo_prvkey, sdo_pubkey, key_info); - LOG_TEST_RET(ctx, rv, "Cannot create key slot"); + LOG_TEST_GOTO_ERR(ctx, rv, "Cannot create key slot"); } rv = sc_pkcs15_allocate_object_content(ctx, object, (unsigned char *)sdo_prvkey, sizeof(struct iasecc_sdo)); - LOG_TEST_RET(ctx, rv, "Failed to allocate PrvKey SDO as object content"); + LOG_TEST_GOTO_ERR(ctx, rv, "Failed to allocate PrvKey SDO as object content"); rv = iasecc_pkcs15_fix_private_key_attributes(profile, p15card, object, (struct iasecc_sdo *)object->content.value); - LOG_TEST_RET(ctx, rv, "Failed to fix private key PKCS#15 attributes"); + LOG_TEST_GOTO_ERR(ctx, rv, "Failed to fix private key PKCS#15 attributes"); key_info->path.len = 0; +err: iasecc_sdo_free(card, sdo_pubkey); + iasecc_sdo_free(card, sdo_prvkey); LOG_FUNC_RETURN(ctx, rv); } From 78be048f478c40f49a970342261229ffa2c78817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 25 Aug 2023 14:49:33 +0200 Subject: [PATCH 3067/4321] authentic: Fix memory leaks when creating keys Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61563 --- src/pkcs15init/pkcs15-authentic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pkcs15init/pkcs15-authentic.c b/src/pkcs15init/pkcs15-authentic.c index 75d4984a54..a660b66269 100644 --- a/src/pkcs15init/pkcs15-authentic.c +++ b/src/pkcs15init/pkcs15-authentic.c @@ -546,12 +546,15 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p key_info->key_reference |= AUTHENTIC_OBJECT_REF_FLAG_LOCAL; rv = sc_select_file(card, &file_p_prvkey->path, &parent); + if (rv != SC_SUCCESS) + sc_file_free(file_p_prvkey); LOG_TEST_RET(ctx, rv, "DF for the private objects not defined"); rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CRYPTO); - LOG_TEST_RET(ctx, rv, "SC_AC_OP_CRYPTO authentication failed for parent DF"); - sc_file_free(parent); + if (rv != SC_SUCCESS) + sc_file_free(file_p_prvkey); + LOG_TEST_RET(ctx, rv, "SC_AC_OP_CRYPTO authentication failed for parent DF"); key_info->access_flags = SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE @@ -560,6 +563,7 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p rv = authentic_sdo_allocate_prvkey(profile, card, key_info, &sdo); if (rv != SC_SUCCESS || sdo == NULL) { sc_log(ctx, "IasEcc: init SDO private key failed"); + sc_file_free(file_p_prvkey); LOG_FUNC_RETURN(ctx, rv); } @@ -596,7 +600,9 @@ authentic_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p LOG_TEST_GOTO_ERR(ctx, rv, "Failed to allocate PrvKey SDO as object content"); err: - free(sdo); + if (sdo == NULL || sdo->file != file_p_prvkey) + sc_file_free(file_p_prvkey); + authentic_free_sdo_data(sdo); LOG_FUNC_RETURN(ctx, rv); } From fa8ad362852dbefad5b6796c32f2a33859b8a8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Fri, 25 Aug 2023 16:31:03 +0200 Subject: [PATCH 3068/4321] idprime: Store container guid as string Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61750 --- src/libopensc/card-idprime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c index 962f2aad4d..c33fa8d44b 100644 --- a/src/libopensc/card-idprime.c +++ b/src/libopensc/card-idprime.c @@ -301,14 +301,14 @@ static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t for (i = 0; i < max_entries; i++) { u8 *start = &buf[i * CONTAINER_OBJ_LEN]; - idprime_container_t new_container; + idprime_container_t new_container = {0}; if (start[0] == 0) /* Empty record */ break; new_container.index = i; /* Reading UNICODE characters but skipping second byte */ int j = 0; - for (j = 0; j < MAX_CONTAINER_NAME_LEN + 1; j++) { + for (j = 0; j < MAX_CONTAINER_NAME_LEN; j++) { if (start[2 * j] == 0) break; new_container.guid[j] = start[2 * j]; From 2a4921ab23fd0853f327517636c50de947548161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= Date: Tue, 29 Aug 2023 14:40:21 +0200 Subject: [PATCH 3069/4321] iasecc: Check length of data when parsing crt Thanks OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61797 --- src/libopensc/iasecc-sdo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c index b3e567dd54..3eeb03b910 100644 --- a/src/libopensc/iasecc-sdo.c +++ b/src/libopensc/iasecc-sdo.c @@ -204,7 +204,7 @@ iasecc_sdo_free(struct sc_card *card, struct iasecc_sdo *sdo) static int -iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_info *se) +iasecc_crt_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_se_info *se) { struct sc_context *ctx = card->ctx; struct sc_crt crt; @@ -212,11 +212,16 @@ iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_inf sc_log(ctx, "iasecc_crt_parse(0x%X) called", *data); + if (data_len < 2) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); + memset(&crt, 0, sizeof(crt)); crt.tag = *(data + 0); len = *(data + 1); for(offs = 2; offs < len + 2; offs += 3) { + if ((size_t) offs + 2 >= data_len) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); sc_log(ctx, "iasecc_crt_parse(0x%X) CRT %X -> %X", *data, *(data + offs), *(data + offs + 2)); if (*(data + offs) == IASECC_CRT_TAG_USAGE) { crt.usage = *(data + offs + 2); @@ -368,7 +373,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru offs = 1 + size_size; for (; offs < data_len;) { - rv = iasecc_crt_parse(card, data + offs, se); + rv = iasecc_crt_parse(card, data + offs, data_len - offs, se); LOG_TEST_RET(ctx, rv, "parse error: invalid SE data"); offs += rv; From a6efa69f4683a7731d5ffe345776b1d8d1423804 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 31 Aug 2023 14:28:34 +0200 Subject: [PATCH 3070/4321] iasecc: Avoid double free Thanks coverity. CID399716 CID399717 --- src/pkcs15init/pkcs15-iasecc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 31250d0d9f..e41fbd9718 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -520,7 +520,7 @@ iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card, sc_log(ctx, "non_repudiation %i", *(sdo->docp.non_repudiation.value + 0)); sc_log(ctx, "compulsory 0x%X", *(sdo->data.prv_key.compulsory.value + 0)); } - else { + else if (rv < 0) { iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "IasEcc: error while getting private key SDO data"); } @@ -593,7 +593,7 @@ iasecc_sdo_allocate_pubkey(struct sc_profile *profile, struct sc_card *card, str sdo->data.pub_key.compulsory.tag = IASECC_SDO_PUBKEY_TAG_COMPULSORY; sdo->data.pub_key.compulsory.size = 1; } - else { + else if (rv < 0) { iasecc_sdo_free(card, sdo); LOG_TEST_RET(ctx, rv, "iasecc_sdo_allocate_pubkey() error while getting public key SDO data"); } From 90a15d4757b42ee5573bab92acc6553f4d88e002 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 17:46:18 +0300 Subject: [PATCH 3071/4321] p11test: fix memory leak with OpenSSL 3 when the public key is successfully saved for future use --- src/tests/p11test/p11test_case_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 001a91f6c4..38080c0543 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -567,8 +567,6 @@ int callback_public_keys(test_certs_t *objects, EC_POINT_free(ecpoint); return -1; } - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); o->verify_public = 1; } else { /* store the public key for future use */ o->type = EVP_PKEY_EC; @@ -577,9 +575,7 @@ int callback_public_keys(test_certs_t *objects, #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *ec = EC_KEY_new_by_curve_name(nid); EC_KEY_set_public_key(ec, ecpoint); - EC_POINT_free(ecpoint); EC_KEY_set_group(ec, ecgroup); - EC_GROUP_free(ecgroup); EVP_PKEY_set1_EC_KEY(o->key, ec); EC_KEY_free(ec); #else @@ -620,6 +616,8 @@ int callback_public_keys(test_certs_t *objects, OSSL_PARAM_free(params); #endif } + EC_GROUP_free(ecgroup); + EC_POINT_free(ecpoint); } else if (o->key_type == CKK_EC_EDWARDS || o->key_type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; From f2e6f919a64bf85b98548e1b97af153051ada1f4 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Aug 2023 15:57:15 +0300 Subject: [PATCH 3072/4321] p11test: free EC param objects in one place --- src/tests/p11test/p11test_case_common.c | 69 +++++++++++-------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 38080c0543..cc02c1ebfd 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -462,6 +462,7 @@ int callback_public_keys(test_certs_t *objects, o->bits = EVP_PKEY_bits(o->key); } } else if (o->key_type == CKK_EC) { + int ec_error = 1; ASN1_OBJECT *oid = NULL; ASN1_OCTET_STRING *s = NULL; const unsigned char *pub, *p; @@ -470,6 +471,10 @@ int callback_public_keys(test_certs_t *objects, EC_POINT *ecpoint = NULL; EC_GROUP *ecgroup = NULL; int nid, pub_len; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EC_GROUP *cert_group = NULL; + EC_POINT *cert_point = NULL; +#endif /* Parse the nid out of the EC_PARAMS */ p = template[6].pValue; @@ -477,20 +482,20 @@ int callback_public_keys(test_certs_t *objects, if (oid == NULL) { debug_print(" [WARN %s ] Failed to convert EC_PARAMS" " to OpenSSL format", o->id_str); - return -1; + goto ec_out; } nid = OBJ_obj2nid(oid); ASN1_OBJECT_free(oid); if (nid == NID_undef) { debug_print(" [WARN %s ] Failed to convert EC_PARAMS" " to NID", o->id_str); - return -1; + goto ec_out; } ecgroup = EC_GROUP_new_by_curve_name(nid); if (ecgroup == NULL) { debug_print(" [WARN %s ] Failed to create new EC_GROUP" " from NID", o->id_str); - return -1; + goto ec_out; } EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); @@ -503,8 +508,7 @@ int callback_public_keys(test_certs_t *objects, if (bn == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " PKCS#11 to BIGNUM", o->id_str); - EC_GROUP_free(ecgroup); - return -1; + goto ec_out; } hex = BN_bn2hex(bn); @@ -512,16 +516,14 @@ int callback_public_keys(test_certs_t *objects, if (hex == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " BIGNUM hex representation", o->id_str); - EC_GROUP_free(ecgroup); - return -1; + goto ec_out; } ecpoint = EC_POINT_hex2point(ecgroup, hex, NULL, NULL); OPENSSL_free(hex); if (ecpoint == NULL) { debug_print(" [WARN %s ] Can not convert EC_POINT from" " BIGNUM to OpenSSL format", o->id_str); - EC_GROUP_free(ecgroup); - return -1; + goto ec_out; } if (o->key != NULL) { @@ -531,8 +533,6 @@ int callback_public_keys(test_certs_t *objects, const EC_POINT *cert_point = EC_KEY_get0_public_key(ec); int cert_nid = EC_GROUP_get_curve_name(cert_group); #else - EC_GROUP *cert_group = NULL; - EC_POINT *cert_point = NULL; char curve_name[80]; size_t curve_name_len = 0; unsigned char pubkey[80]; size_t pubkey_len = 0; int cert_nid = 0; @@ -540,21 +540,14 @@ int callback_public_keys(test_certs_t *objects, (cert_nid = OBJ_txt2nid(curve_name)) == NID_undef || (cert_group = EC_GROUP_new_by_curve_name(cert_nid)) == NULL) { fprintf(stderr, "Can not get EC_GROUP from EVP_PKEY"); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - EC_GROUP_free(cert_group); - return -1; + goto ec_out; } cert_point = EC_POINT_new(cert_group); if (!cert_point || EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1 || EC_POINT_oct2point(cert_group, cert_point, pubkey, pubkey_len, NULL) != 1) { fprintf(stderr, "Can not get EC_POINT from EVP_PKEY"); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - EC_POINT_free(cert_point); - EC_GROUP_free(cert_group); - return -1; + goto ec_out; } #endif if (cert_nid != nid || @@ -563,9 +556,7 @@ int callback_public_keys(test_certs_t *objects, debug_print(" [WARN %s ] Got different public" "key then from the certificate", o->id_str); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - return -1; + goto ec_out; } o->verify_public = 1; } else { /* store the public key for future use */ @@ -585,9 +576,7 @@ int callback_public_keys(test_certs_t *objects, if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len)|| EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { debug_print(" [WARN %s ] Can not get params from EVP_PKEY", o->id_str); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - return -1; + goto ec_out; } if (!(bld = OSSL_PARAM_BLD_new()) || @@ -595,29 +584,33 @@ int callback_public_keys(test_certs_t *objects, OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { debug_print(" [WARN %s ] Can not set params from EVP_PKEY", o->id_str); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - OSSL_PARAM_BLD_free(bld); - EVP_PKEY_CTX_free(ctx); - return -1; + goto ec_out; } - OSSL_PARAM_BLD_free(bld); if (ctx == NULL || params == NULL || EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { debug_print(" [WARN %s ] Can not set params for EVP_PKEY", o->id_str); - EC_GROUP_free(ecgroup); - EC_POINT_free(ecpoint); - EVP_PKEY_CTX_free(ctx); - return -1; + goto ec_out; } - EVP_PKEY_CTX_free(ctx); - OSSL_PARAM_free(params); #endif } + + ec_error = 0; + + ec_out: EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_free(params); + EC_GROUP_free(cert_group); + EC_POINT_free(cert_point); +#endif + + if (ec_error) return -1; + } else if (o->key_type == CKK_EC_EDWARDS || o->key_type == CKK_EC_MONTGOMERY) { EVP_PKEY *key = NULL; From 44f9c86b82042165bf312aae82817bffe8584ff2 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Aug 2023 16:06:37 +0300 Subject: [PATCH 3073/4321] p11test: fix spelling errors --- src/tests/p11test/p11test_case_common.c | 20 ++++++++++---------- src/tests/p11test/p11test_case_ec_derive.c | 4 ++-- src/tests/p11test/p11test_case_readonly.c | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index cc02c1ebfd..9e282c733d 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -506,7 +506,7 @@ int callback_public_keys(test_certs_t *objects, bn = BN_bin2bn(pub, pub_len, NULL); ASN1_STRING_free(s); if (bn == NULL) { - debug_print(" [WARN %s ] Can not convert EC_POINT from" + debug_print(" [WARN %s ] Cannot convert EC_POINT from" " PKCS#11 to BIGNUM", o->id_str); goto ec_out; } @@ -514,14 +514,14 @@ int callback_public_keys(test_certs_t *objects, hex = BN_bn2hex(bn); BN_free(bn); if (hex == NULL) { - debug_print(" [WARN %s ] Can not convert EC_POINT from" + debug_print(" [WARN %s ] Cannot convert EC_POINT from" " BIGNUM hex representation", o->id_str); goto ec_out; } ecpoint = EC_POINT_hex2point(ecgroup, hex, NULL, NULL); OPENSSL_free(hex); if (ecpoint == NULL) { - debug_print(" [WARN %s ] Can not convert EC_POINT from" + debug_print(" [WARN %s ] Cannot convert EC_POINT from" " BIGNUM to OpenSSL format", o->id_str); goto ec_out; } @@ -539,14 +539,14 @@ int callback_public_keys(test_certs_t *objects, if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len) != 1 || (cert_nid = OBJ_txt2nid(curve_name)) == NID_undef || (cert_group = EC_GROUP_new_by_curve_name(cert_nid)) == NULL) { - fprintf(stderr, "Can not get EC_GROUP from EVP_PKEY"); + fprintf(stderr, "Cannot get EC_GROUP from EVP_PKEY"); goto ec_out; } cert_point = EC_POINT_new(cert_group); if (!cert_point || EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1 || EC_POINT_oct2point(cert_group, cert_point, pubkey, pubkey_len, NULL) != 1) { - fprintf(stderr, "Can not get EC_POINT from EVP_PKEY"); + fprintf(stderr, "Cannot get EC_POINT from EVP_PKEY"); goto ec_out; } #endif @@ -575,7 +575,7 @@ int callback_public_keys(test_certs_t *objects, unsigned char pubkey[80]; size_t pubkey_len = 0; if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len)|| EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { - debug_print(" [WARN %s ] Can not get params from EVP_PKEY", o->id_str); + debug_print(" [WARN %s ] Cannot get params from EVP_PKEY", o->id_str); goto ec_out; } @@ -583,14 +583,14 @@ int callback_public_keys(test_certs_t *objects, OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, curve_name_len) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { - debug_print(" [WARN %s ] Can not set params from EVP_PKEY", o->id_str); + debug_print(" [WARN %s ] Cannot set params from EVP_PKEY", o->id_str); goto ec_out; } if (ctx == NULL || params == NULL || EVP_PKEY_fromdata_init(ctx) != 1 || EVP_PKEY_fromdata(ctx, &o->key, EVP_PKEY_PUBLIC_KEY, params) != 1) { - debug_print(" [WARN %s ] Can not set params for EVP_PKEY", o->id_str); + debug_print(" [WARN %s ] Cannot set params for EVP_PKEY", o->id_str); goto ec_out; } #endif @@ -685,7 +685,7 @@ int callback_public_keys(test_certs_t *objects, a = template[7].pValue; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)template[7].ulValueLen); if (!os) { - debug_print(" [WARN %s ] Can not decode EC_POINT", o->id_str); + debug_print(" [WARN %s ] Cannot decode EC_POINT", o->id_str); return -1; } if (os->length != 32) { @@ -707,7 +707,7 @@ int callback_public_keys(test_certs_t *objects, /* TODO check EVP_PKEY type */ if (EVP_PKEY_get_raw_public_key(o->key, NULL, &publen) != 1) { - debug_print(" [WARN %s ] Can not get size of the key", o->id_str); + debug_print(" [WARN %s ] Cannot get size of the key", o->id_str); ASN1_STRING_free(os); return -1; } diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index f46d9c0f20..a7f7a42103 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -281,7 +281,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) if (pctx == NULL || EVP_PKEY_derive_init(pctx) != 1 || EVP_PKEY_derive_set_peer(pctx, o->key) != 1) { - debug_print(" [ KEY %s ] Can not derive key", o->id_str); + debug_print(" [ KEY %s ] Cannot derive key", o->id_str); EVP_PKEY_free(evp_pkey); return 1; } @@ -346,7 +346,7 @@ int test_derive(test_cert_t *o, token_info_t *info, test_mech_t *mech) #else if (EVP_PKEY_get_octet_string_param(evp_pkey, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, pub, pub_len, NULL) != 1) { #endif - debug_print(" [ KEY %s ] Can not get public key", o->id_str); + debug_print(" [ KEY %s ] Cannot get public key", o->id_str); EVP_PKEY_free(evp_pkey); free(secret); free(pub); diff --git a/src/tests/p11test/p11test_case_readonly.c b/src/tests/p11test/p11test_case_readonly.c index 38c5dc29b7..a6fdb1f509 100644 --- a/src/tests/p11test/p11test_case_readonly.c +++ b/src/tests/p11test/p11test_case_readonly.c @@ -70,7 +70,7 @@ rsa_x_509_pad_message(const unsigned char *message, size_t padding_len = pad_message_length - (*message_length) - 3; if (pad_message_length - (*message_length) <= 11) { - debug_print("Can not pad message - buffer to small"); + debug_print("Cannot pad message - buffer too small"); return NULL; } if ((pad_message = malloc(pad_message_length)) == NULL) { @@ -86,7 +86,7 @@ rsa_x_509_pad_message(const unsigned char *message, } else { pad_message[1] = 0x02; if (RAND_bytes(pad_message + 2, padding_len) != 1) { - debug_print("Can not generate random bytes."); + debug_print("Cannot generate random bytes."); } } memcpy(pad_message + 2 + padding_len, message, (*message_length) * sizeof(unsigned char)); From d6836796b7fc72d771662bf03bae756d61b22224 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 18:12:19 +0300 Subject: [PATCH 3074/4321] p11test: rename ASN.1 octet string variable --- src/tests/p11test/p11test_case_common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 9e282c733d..1aaaaced9d 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -464,7 +464,7 @@ int callback_public_keys(test_certs_t *objects, } else if (o->key_type == CKK_EC) { int ec_error = 1; ASN1_OBJECT *oid = NULL; - ASN1_OCTET_STRING *s = NULL; + ASN1_OCTET_STRING *pub_asn1 = NULL; const unsigned char *pub, *p; char *hex = NULL; BIGNUM *bn = NULL; @@ -500,11 +500,11 @@ int callback_public_keys(test_certs_t *objects, EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); p = template[7].pValue; - s = d2i_ASN1_OCTET_STRING(NULL, &p, template[7].ulValueLen); - pub = ASN1_STRING_get0_data(s); - pub_len = ASN1_STRING_length(s); + pub_asn1 = d2i_ASN1_OCTET_STRING(NULL, &p, template[7].ulValueLen); + pub = ASN1_STRING_get0_data(pub_asn1); + pub_len = ASN1_STRING_length(pub_asn1); bn = BN_bin2bn(pub, pub_len, NULL); - ASN1_STRING_free(s); + ASN1_STRING_free(pub_asn1); if (bn == NULL) { debug_print(" [WARN %s ] Cannot convert EC_POINT from" " PKCS#11 to BIGNUM", o->id_str); From 9730c93cfb4f8ed34b9f15f4ae5ab76983c41f7c Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 18:28:43 +0300 Subject: [PATCH 3075/4321] p11test: simplify EC cert parsing --- src/tests/p11test/p11test_case_common.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 1aaaaced9d..1923bb36ef 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -466,8 +466,6 @@ int callback_public_keys(test_certs_t *objects, ASN1_OBJECT *oid = NULL; ASN1_OCTET_STRING *pub_asn1 = NULL; const unsigned char *pub, *p; - char *hex = NULL; - BIGNUM *bn = NULL; EC_POINT *ecpoint = NULL; EC_GROUP *ecgroup = NULL; int nid, pub_len; @@ -503,26 +501,14 @@ int callback_public_keys(test_certs_t *objects, pub_asn1 = d2i_ASN1_OCTET_STRING(NULL, &p, template[7].ulValueLen); pub = ASN1_STRING_get0_data(pub_asn1); pub_len = ASN1_STRING_length(pub_asn1); - bn = BN_bin2bn(pub, pub_len, NULL); - ASN1_STRING_free(pub_asn1); - if (bn == NULL) { - debug_print(" [WARN %s ] Cannot convert EC_POINT from" - " PKCS#11 to BIGNUM", o->id_str); - goto ec_out; - } - hex = BN_bn2hex(bn); - BN_free(bn); - if (hex == NULL) { - debug_print(" [WARN %s ] Cannot convert EC_POINT from" - " BIGNUM hex representation", o->id_str); + if (!(ecpoint = EC_POINT_new(ecgroup))) { + debug_print(" [WARN %s ] Cannot allocate EC_POINT", o->id_str); goto ec_out; } - ecpoint = EC_POINT_hex2point(ecgroup, hex, NULL, NULL); - OPENSSL_free(hex); - if (ecpoint == NULL) { - debug_print(" [WARN %s ] Cannot convert EC_POINT from" - " BIGNUM to OpenSSL format", o->id_str); + + if (EC_POINT_oct2point(ecgroup, ecpoint, pub, pub_len, NULL) != 1) { + debug_print(" [WARN %s ] Cannot parse EC_POINT", o->id_str); goto ec_out; } @@ -599,6 +585,7 @@ int callback_public_keys(test_certs_t *objects, ec_error = 0; ec_out: + ASN1_STRING_free(pub_asn1); EC_GROUP_free(ecgroup); EC_POINT_free(ecpoint); #if OPENSSL_VERSION_NUMBER >= 0x30000000L From 9773ed3cde1bd299f88f006d348fb059ad3c1fd3 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 17:34:37 +0300 Subject: [PATCH 3076/4321] p11test: fix curve_name with OpenSSL 3 It cannot be read from the new EC key instance where it is to be written later. --- src/tests/p11test/p11test_case_common.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 1923bb36ef..3f210a2ed9 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -557,16 +557,15 @@ int callback_public_keys(test_certs_t *objects, EC_KEY_free(ec); #else ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); - char curve_name[80]; size_t curve_name_len = 0; unsigned char pubkey[80]; size_t pubkey_len = 0; - if (EVP_PKEY_get_group_name(o->key, curve_name, sizeof(curve_name), &curve_name_len)|| - EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { + if (EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { debug_print(" [WARN %s ] Cannot get params from EVP_PKEY", o->id_str); goto ec_out; } + const char *curve_name = OBJ_nid2sn(nid); if (!(bld = OSSL_PARAM_BLD_new()) || - OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, curve_name_len) != 1 || + OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, strlen(curve_name)) != 1 || OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { debug_print(" [WARN %s ] Cannot set params from EVP_PKEY", o->id_str); From f8eb3d31021f6513bcf91a2e07e0f5e9159028a4 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Aug 2023 17:41:03 +0300 Subject: [PATCH 3077/4321] p11test: fix pubkey with OpenSSL 3 It cannot be read from the new EC key instance where it is to be written later. --- src/tests/p11test/p11test_case_common.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 3f210a2ed9..bab782c373 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -557,16 +557,11 @@ int callback_public_keys(test_certs_t *objects, EC_KEY_free(ec); #else ctx = EVP_PKEY_CTX_new_from_name(0, "EC", 0); - unsigned char pubkey[80]; size_t pubkey_len = 0; - if (EVP_PKEY_get_octet_string_param(o->key, OSSL_PKEY_PARAM_PUB_KEY, pubkey, sizeof(pubkey), &pubkey_len) != 1) { - debug_print(" [WARN %s ] Cannot get params from EVP_PKEY", o->id_str); - goto ec_out; - } const char *curve_name = OBJ_nid2sn(nid); if (!(bld = OSSL_PARAM_BLD_new()) || OSSL_PARAM_BLD_push_utf8_string(bld, "group", curve_name, strlen(curve_name)) != 1 || - OSSL_PARAM_BLD_push_octet_string(bld, "pub", pubkey, pubkey_len) != 1 || + OSSL_PARAM_BLD_push_octet_string(bld, "pub", pub, pub_len) != 1 || !(params = OSSL_PARAM_BLD_to_param(bld))) { debug_print(" [WARN %s ] Cannot set params from EVP_PKEY", o->id_str); goto ec_out; From b36754bc0d58452778ca6fb5c624edfef435f81f Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Sat, 19 Aug 2023 00:51:32 +0300 Subject: [PATCH 3078/4321] p11test: fix ECDH test sc_pkcs15init_init_skdf fails unless the key length has been set. --- src/tests/p11test/p11test_case_ec_derive.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/p11test/p11test_case_ec_derive.c b/src/tests/p11test/p11test_case_ec_derive.c index a7f7a42103..b08941d282 100644 --- a/src/tests/p11test/p11test_case_ec_derive.c +++ b/src/tests/p11test/p11test_case_ec_derive.c @@ -31,12 +31,14 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, CK_OBJECT_HANDLE newkey; CK_OBJECT_CLASS newkey_class = CKO_SECRET_KEY; CK_KEY_TYPE newkey_type = CKK_GENERIC_SECRET; + CK_ULONG newkey_len = o->bits / 8; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_ATTRIBUTE template[] = { {CKA_TOKEN, &false, sizeof(false)}, /* session only object */ {CKA_CLASS, &newkey_class, sizeof(newkey_class)}, {CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)}, + {CKA_VALUE_LEN, &newkey_len, sizeof(newkey_len)}, {CKA_SENSITIVE, &false, sizeof(false)}, {CKA_EXTRACTABLE, &true, sizeof(true)}, {CKA_ENCRYPT, &true, sizeof(true)}, @@ -45,7 +47,7 @@ pkcs11_derive(test_cert_t *o, token_info_t * info, {CKA_UNWRAP, &true, sizeof(true)} }; CK_ATTRIBUTE get_value = {CKA_VALUE, NULL_PTR, 0}; - CK_ULONG template_len = 9; + CK_ULONG template_len = 10; params.pSharedData = NULL; params.ulSharedDataLen = 0; From 00214628a08f65ccf6597b6c9c2c02f5f2feffa9 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Tue, 5 Sep 2023 13:01:15 +0200 Subject: [PATCH 3079/4321] Added missing CVEs to NEWS (#2855) * Added missing CVEs to NEWS fixes https://github.com/OpenSC/OpenSC/issues/2841 * added CVE-2021-34193 as duplicate --- NEWS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS b/NEWS index e5d01337be..ba19f1cc92 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ NEWS for OpenSC -- History of user visible changes +# Addendum for 0.22.0; 2023-09-01 +* fixed security problems + * CVE-2021-42778 Heap double free in sc_pkcs15_free_tokeninfo + * CVE-2021-42779 Heap use after free in sc_file_valid + * CVE-2021-42780 Use after return in insert_pin function + * CVE-2021-42781 Heap buffer overflow in pkcs15-oberthur.c + * CVE-2021-42782 Stack buffer overflow issues in various places + * CVE-2021-34193 is a duplicate CVE covering the 5 individual CVEs listed above + # New in 0.23.0; 2022-11-29 ## General improvements * Support signing of data with a length of more than 512 bytes (#2314) From dc1d0196b41df5461a7187171effba96c6e692f5 Mon Sep 17 00:00:00 2001 From: Gianfranco Costamagna Date: Mon, 28 Aug 2023 22:59:09 +0200 Subject: [PATCH 3080/4321] libopensc, pkcs15init: silence some gcc errors spotted on Ubuntu 23.10 development release with gcc-13, lto and O3 optimization level E.g. of error: libtool: link: gcc -g -O0 -Wall -Wextra -Wno-unused-parameter -Werror -Wstrict-aliasing=2 -g -O2 -ffile-prefix-map=/<>=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fdebug-prefix-map=/<>=/usr/src/opensc-0.23.0-1 -Wno-error=deprecated-declarations -Wno-error=stringop-overflow -Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -Wl,-z -Wl,relro -o fuzz_pkcs15init fuzz_pkcs15init.o fuzzer_reader.o fuzzer.o ../../../src/libopensc/.libs/libopensc.a -lz -lgio-2.0 -lgobject-2.0 -leac -lcrypto ../../../src/common/.libs/libscdl.a -ldl ../../../src/pkcs15init/.libs/libpkcs15init.a ../../../src/common/.libs/libcompat.a -pthread ../../../src/pkcs15init/pkcs15-lib.c: In function 'sc_pkcs15init_update_any_df': ../../../src/pkcs15init/pkcs15-lib.c:3247:21: error: 'bufsize' may be used uninitialized [-Werror=maybe-uninitialized] 3247 | r = sc_pkcs15init_update_file(profile, p15card, file, buf, bufsize); | ^ ../../../src/pkcs15init/pkcs15-lib.c:3234:25: note: 'bufsize' was declared here 3234 | size_t bufsize; | ^ lto1: all warnings being treated as errors --- src/libopensc/card-asepcos.c | 6 +++--- src/libopensc/card-starcos.c | 2 +- src/libopensc/iso7816.c | 2 +- src/pkcs15init/pkcs15-asepcos.c | 8 ++++---- src/pkcs15init/pkcs15-cardos.c | 2 +- src/pkcs15init/pkcs15-entersafe.c | 2 +- src/pkcs15init/pkcs15-epass2003.c | 2 +- src/pkcs15init/pkcs15-incrypto34.c | 2 +- src/pkcs15init/pkcs15-lib.c | 13 +++++++++++-- src/pkcs15init/pkcs15-myeid.c | 2 +- src/pkcs15init/pkcs15-oberthur.c | 2 +- src/pkcs15init/pkcs15-setcos.c | 8 ++++---- src/pkcs15init/pkcs15-starcos.c | 8 ++++---- 13 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 301f931569..3596172532 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -336,7 +336,7 @@ static int asepcos_akn_to_fileid(sc_card_t *card, sc_cardctl_asepcos_akn2fileid_ { int r; u8 sbuf[32], rbuf[SC_MAX_APDU_BUFFER_SIZE]; - sc_apdu_t apdu; + sc_apdu_t apdu = {0}; sbuf[0] = p->akn & 0xff; sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x28, 0x02, 0x01); @@ -365,7 +365,7 @@ static int asepcos_set_sec_attributes(sc_card_t *card, const u8 *data, size_t le int is_ef) { int r, type = is_ef != 0 ? 0x02 : 0x04; - sc_apdu_t apdu; + sc_apdu_t apdu = {0}; sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x8a, type, 0xab); apdu.cla |= 0x80; @@ -537,7 +537,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) { if (file->type == SC_FILE_TYPE_DF) { int r, type; - sc_apdu_t apdu; + sc_apdu_t apdu = {0}; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE], *p = &sbuf[0]; *p++ = (file->id >> 8) & 0xff; diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index 8170293e64..8596d3269a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1388,7 +1388,7 @@ static int starcos_erase_card(sc_card_t *card) { /* restore the delivery state */ int r; u8 sbuf[2]; - sc_apdu_t apdu; + sc_apdu_t apdu = {0}; sbuf[0] = 0x3f; sbuf[1] = 0x00; diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 91a35b93e3..1e3bd3ba13 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -900,7 +900,7 @@ iso7816_create_file(struct sc_card *card, sc_file_t *file) static int iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf) { - struct sc_apdu apdu; + struct sc_apdu apdu = {0}; int r; size_t rlen; diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index 761f6dee8f..92169d4424 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -223,7 +223,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, u8 buf[64], sbuf[64], *p = buf, *q = sbuf; int r, akn = 0; - if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) + if (auth_info == NULL || auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; /* outer tag */ @@ -318,7 +318,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, */ static int have_onepin(sc_profile_t *profile) { - sc_pkcs15_auth_info_t sopin; + sc_pkcs15_auth_info_t sopin = {0}; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin); @@ -354,7 +354,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, if (!pin || !pin_len) return SC_ERROR_INVALID_ARGUMENTS; - if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) + if (auth_info == NULL || auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; pid = (auth_info->attrs.pin.reference & 0xff) | (((tpath.len >> 1) - 1) << 16); @@ -393,7 +393,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, /* Create PUK (if specified). Note: we need to create the PUK * the PIN as the PUK fileid is used in the PIN acl. */ - struct sc_pkcs15_auth_info puk_ainfo; + struct sc_pkcs15_auth_info puk_ainfo = {0}; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PUK, &puk_ainfo); diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 540f3e0be3..1b79b324e7 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -210,7 +210,7 @@ cardos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d return r; if (puk && puk_len) { - struct sc_pkcs15_auth_info puk_ainfo; + struct sc_pkcs15_auth_info puk_ainfo = {0}; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &puk_ainfo); diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index 986f120b02..57be7d2668 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -472,7 +472,7 @@ static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15ca static int entersafe_sanity_check(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_auth_info profile_auth; + struct sc_pkcs15_auth_info profile_auth = {0}; struct sc_pkcs15_object *objs[32]; int rv, nn, ii, update_df = 0; diff --git a/src/pkcs15init/pkcs15-epass2003.c b/src/pkcs15init/pkcs15-epass2003.c index e70bbf8733..b9b9a1156f 100644 --- a/src/pkcs15init/pkcs15-epass2003.c +++ b/src/pkcs15init/pkcs15-epass2003.c @@ -729,7 +729,7 @@ static int epass2003_pkcs15_sanity_check(sc_profile_t * profile, sc_pkcs15_card_t * p15card) { struct sc_context *ctx = p15card->card->ctx; - struct sc_pkcs15_auth_info profile_auth; + struct sc_pkcs15_auth_info profile_auth = {0}; struct sc_pkcs15_object *objs[32]; int rv, nn, ii, update_df = 0; diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index db6d89d6a5..5267cb2ea5 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -224,7 +224,7 @@ incrypto34_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return r; if (puk && puk_len) { - struct sc_pkcs15_auth_info puk_ainfo; + struct sc_pkcs15_auth_info puk_ainfo = {0}; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &puk_ainfo); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 7bd1ac66bc..6ee58b0bc2 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1014,6 +1014,9 @@ sc_pkcs15init_store_puk(struct sc_pkcs15_card *p15card, auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, auth_info); + if (auth_info == NULL) + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Failed to retrieve auth_info"); + auth_info->auth_id = args->puk_id; /* Now store the PINs */ @@ -1078,6 +1081,9 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profi auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, auth_info); + if (auth_info == NULL) + LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Failed to retrieve auth_info"); + auth_info->auth_id = args->auth_id; /* Now store the PINs */ @@ -3255,7 +3261,7 @@ sc_pkcs15init_update_any_df(struct sc_pkcs15_card *p15card, struct sc_card *card = p15card->card; struct sc_file *file = NULL; unsigned char *buf = NULL; - size_t bufsize; + size_t bufsize = 0; int update_odf = is_new, r = 0; LOG_FUNC_CALLED(ctx); @@ -3429,7 +3435,7 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card, struct sc_profile *p struct sc_context *ctx = p15card->card->ctx; struct sc_card *card = p15card->card; unsigned char *buf = NULL; - size_t bufsize; + size_t bufsize = 0; int df_type, r = 0; struct sc_pkcs15_df *df; struct sc_pkcs15_id new_id = *((struct sc_pkcs15_id *) new_value); @@ -4397,6 +4403,9 @@ sc_pkcs15init_qualify_pin(struct sc_card *card, const char *pin_name, struct sc_pkcs15_pin_attributes *pin_attrs; LOG_FUNC_CALLED(ctx); + if (auth_info == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND); + if (pin_len == 0 || auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) LOG_FUNC_RETURN(ctx, SC_SUCCESS); diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 74e2c72f75..5b07fc062d 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -312,7 +312,7 @@ myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, unsigned char data[20]; struct sc_cardctl_myeid_data_obj data_obj; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data; - struct sc_pkcs15_auth_info puk_ainfo; + struct sc_pkcs15_auth_info puk_ainfo = {0}; int r; LOG_FUNC_CALLED(ctx); diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index b20bd6e6c4..ad2cabd530 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -271,7 +271,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_pkcs15_card *p1 { struct sc_context *ctx = p15card->card->ctx; struct sc_card *card = p15card->card; - struct sc_pkcs15_auth_info profile_auth_pin, profile_auth_puk; + struct sc_pkcs15_auth_info profile_auth_pin = {0}, profile_auth_puk = {0}; struct sc_cardctl_oberthur_createpin_info args; int rv; unsigned char oberthur_puk[16] = { diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index 1907b47f9d..8541f9f955 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -42,7 +42,7 @@ static int setcos_create_pin_internal(sc_profile_t *, sc_pkcs15_card_t *, static int setcos_puk_retries(sc_profile_t *profile, int pin_ref) { - sc_pkcs15_auth_info_t auth_info; + sc_pkcs15_auth_info_t auth_info = {0}; auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; auth_info.attrs.pin.reference = 1; /* Default SO PIN ref. */ @@ -169,19 +169,19 @@ static int setcos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_auth_info_t *auth_info) { - sc_pkcs15_auth_info_t auth_info_prof; + sc_pkcs15_auth_info_t auth_info_prof = {0}; auth_info_prof.attrs.pin.reference = 1; /* Default SO PIN ref. */ auth_info_prof.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info_prof); /* For the SO pin, we take the first available pin reference = 1 */ - if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) + if (auth_info != NULL && auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference; /* sc_pkcs15init_create_pin() starts checking if -1 is an acceptable * pin reference, which isn't for the SetCOS cards. And since the * value 1 has been assigned to the SO pin, we'll jump to 2. */ - else if (auth_info->attrs.pin.reference <= 0) { + else if (auth_info != NULL && auth_info->attrs.pin.reference <= 0) { if (auth_info_prof.attrs.pin.reference != 1) return SC_ERROR_INVALID_PIN_REFERENCE; auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference + 1; diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index e915baf16c..21ed03aa10 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -83,7 +83,7 @@ static int starcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) sc_file_t *mf_file, *isf_file, *ipf_file; sc_path_t tpath; u8 *p = mf_data.data.mf.header, tmp = 0; - sc_pkcs15_auth_info_t sopin; + sc_pkcs15_auth_info_t sopin = {0}; /* test if we already have a MF */ memset(&tpath, 0, sizeof(sc_path_t)); @@ -180,7 +180,7 @@ static int starcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_starcos_create_data df_data, ipf_data; sc_file_t *isf_file, *ipf_file; u8 *p = df_data.data.df.header, tmp = 0; - sc_pkcs15_auth_info_t sopin; + sc_pkcs15_auth_info_t sopin = {0}; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin); @@ -255,7 +255,7 @@ static int starcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, static int have_onepin(sc_profile_t *profile) { - sc_pkcs15_auth_info_t sopin; + sc_pkcs15_auth_info_t sopin = {0}; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin); @@ -428,7 +428,7 @@ static int starcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, return r; if (puk && puk_len) { - sc_pkcs15_auth_info_t puk_info; + sc_pkcs15_auth_info_t puk_info = {0}; if (puk_len > 8) return SC_ERROR_INVALID_ARGUMENTS; From 9933d620544f691acbcd04dba23cd8a27e3bbd90 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Thu, 4 Jun 2020 14:22:38 -0500 Subject: [PATCH 3081/4321] Fix SM handling of command chaining for short apdus Allow driver to tell apdu.c to pass to sm_get_apdus to have it do the chaining. Without this change, apdu.c will do the command chaining and pass each chained apdu to SM. This may be OK for some, but not PIV which uses short APDUs and encryption and MAC for data before doing the chaining. The driver sets SC_APDU_FLAGS_SM_CHAINING flag and SC_APDU_FLAGS_CHAINING. which causes apdu.c to pass the plain adpu to card->sm_ctx.ops.get_sm_apdu. Without the SC_APDU_FLAGS_SM_CHAINING the flow of SM is not changed. On branch PIV-4-extensions Changes to be committed: modified: apdu.c modified: types.h --- src/libopensc/apdu.c | 8 ++++++++ src/libopensc/types.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index b1083eed9e..d18dcd0075 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -563,6 +563,14 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) return r; } +#if ENABLE_SM + if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT + && (apdu->flags & SC_APDU_FLAGS_CHAINING) != 0 + && (apdu->flags & SC_APDU_FLAGS_SM_CHAINING) != 0) { + sc_log(card->ctx,"Let SM do the chaining"); + r = sc_transmit(card, apdu); + } else +#endif if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) { /* divide et impera: transmit APDU in chunks with Lc <= max_send_size * bytes using command chaining */ diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 878ace7842..6f7494ca2d 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -311,6 +311,8 @@ typedef struct sc_file { #define SC_APDU_FLAGS_NO_RETRY_WL 0x00000004UL /* APDU is from Secure Messaging */ #define SC_APDU_FLAGS_NO_SM 0x00000008UL +/* let SM do the comand haining */ +#define SC_APDU_FLAGS_SM_CHAINING 0x00000010UL #define SC_APDU_ALLOCATE_FLAG 0x01 #define SC_APDU_ALLOCATE_FLAG_DATA 0x02 From 26b24c7c17a153e4697187f5145ac632472184f9 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sun, 7 Jun 2020 11:07:58 -0500 Subject: [PATCH 3082/4321] apdu.c log apdu->flags for debugging On branch PIV-4-extensions Changes to be committed: modified: apdu.c --- src/libopensc/apdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index d18dcd0075..82e55f7a8b 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -322,13 +322,13 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) error: sc_log(card->ctx, "Invalid Case %d %s APDU:\n" "cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n" - "resp=%p resplen=%lu data=%p datalen=%lu", + "resp=%p resplen=%lu data=%p datalen=%lu flags=0x%8.8lx", apdu->cse & SC_APDU_SHORT_MASK, (apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short", apdu->cse, apdu->cla, apdu->ins, apdu->p1, apdu->p2, (unsigned long) apdu->lc, (unsigned long) apdu->le, apdu->resp, (unsigned long) apdu->resplen, - apdu->data, (unsigned long) apdu->datalen); + apdu->data, (unsigned long) apdu->datalen, apdu->flags); return SC_ERROR_INVALID_ARGUMENTS; } From f6b4a2e6582d5c1a37a04be475df88bee86f0bc3 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 27 Jan 2023 20:09:53 -0600 Subject: [PATCH 3083/4321] PIV Secure Messaging as defined in NIST 800-73-4 5/2015 Looking for other users who have cards that support PIV SM and VCI for testing. Changes to PIV code for SM as defined in NIST 800-73-4. Section 4.1 The Key Establishment Protocol is done in piv_sm_open. Step names and variable names were chosen to match the names used used in 800-73-4. piv_get_sm_apdu, piv_free_sm_apdu, and piv_sm_close use the builtin SM apdu handling. This version calls piv_sm_open once from piv_init. and card->sm_ctx.sm_mode is set. See TODO below. PR has been tested with pkcs11-tool -O and --test --login using a "IDEMIA ID-One PIV 2.4 on Cosmo V8.1" with vendor provided certificates (about 25 certificates and keys) and other data objects. The test card does not have a "pairing code object" need for VCI for use over a contactless interface (NFC), But code has been added to support pairing to allow testing. The PIV SM code is only enabled if ENABLE_SM, ENABLE_OPENSSL and OPENSSL_NO_EC is not defined. It was tested with --disable_sm A card indicates it can suport SM in the response to SELECT_AID. If card can support SM, but OpenSC was built without ENABLE_SM a sc_log message will say so. card-piv.c use SC_APDU_FLAGS_SM_CHAINING from previous commit. This allows the PIV to pass a plain ADPU which needs command chaining, to SM and piv_get_sm_apdu and will encrypt and MAC the data before command chaining is done in apdu.c NIST sp800-73-4 3.3.2 extends pin policy usage flags for optional VCI and OCC are defined. Checked with valgrind, pkcs11 -O and pkcs11-tool --test --login If card supports SM it is turned on in piv_init, so if card is reset or interfered with from other process, SM will not restart. Signer certificates and CVC certificates are verified. If interfered with by other processes, and SM session is lost, it is restarted. TODO Need a way to give user paring code from card over usb after login if it is not printed on card or distributed in some other way. MD_MAX_KEY_CONTAINERS 32 add piv_logout PIV test card have more the 12 keys. "card_driver PIV_II {" block in opensc.conf See: etc/opensc.conf.example.in piv_max_object_size - removes the code to read first 8 bytes to get object size and use piv_max_object_size as read buffer size. default is 16K, max is 65K piv_use_sm - default, never, always default - use it for PIN, crypto and reading objects that are PIN protected Other objects are read in the clear for performance. never - Don't use SM, even if card supports it. Can help is situations were problems ith SM, and to debug other PIN or cryto problems. always -Like default, but read all objects using SM. piv_pairing_code - Card may require user to enter 8 digit pairing code to use VCI so card can be used over contactless as if using contact reader. VCI requires SM, and encrypts everything. All can be set via env. PIV_USE_SM= PIV_PAIRING_CODE= Used of a contactless reader is identified by the ATR 3B 8X 80 01 .... Rework PIV card matching and init for less overhead. piv_match_card_continued was committed in 4222036a6 2018-02-28 to handle limitations in card.c on not allowing *_match_card to pass anything other the card->type to *_init routines. These restrictions were removed in 2c0d1b9ab 2018-07-05. piv_match_card_continued is only called once, from piv_match_card does some checks, sets card->type, allocates piv_private_data_t, saves it in card->drv_data, calls sc_lock. If piv_match_card_continued fails, piv_match_card will call sc_lock, piv_finish and return 0 (failed to match). And just in case piv_match_card is not called, piv_init will call piv_match_card_continued. And if it fails will call sc_unlock, piv_finish and return SC_ERROR_INVALID_CARD. The card lock is finally released at end of piv_init. This allows no interference from other process during piv_match_card and piv_init. If CSAI 0xAC tag is found in the response to a SELECT AID and is used to say the card supports SM. It will still do this even if built without SM so it will show up in debug logs. PIV specs are vague and some PIV applets and a 0xAC tag for every algorithm and not just for SM. PIV Secure Messaging requires at least OpenSSL-1.1.1 or OpenSSL-3.0.0 Added equivelent code from PR 2366. Pairing code is optional, and only used when creating a VCI over contetless reader. It can be provided via env PIV_PAIRING_CODE or in opensc.conf. In any case the paring code, if provided, must be 8 ASCII digits. There is no not easy way to tell the user the code is invalid. "piv_parse_pairing_code" is added to check the length and digits. The caller will add a debug log entry if it is invalid so there is a record of the failure. With 800-73-4 Secure Messaging the SELECT AID response specifies which cryptographic algorithms under tag 0xAC are supported for Secure Messaging. The code was using the discovery object to test if the PIV applet is active as some cards have a card issue of losing the login state if the SELECT AID is used instead. (None of these cards support SM so reading the discovey object was as good as doing SELECT_AID.) The problme was found while running in contactless mode, card would work the first time becaus the discovery object would not find the PIV applet so a SELECT AID was done and it would also update the the cryptographic algorithms. When run a second time, reading the discovery object would work but the SELECT AID would only be done near the end of match routine for card types the may support 800-73-4. The duplicate "sc_atr" was not listed as one the need to have SELECT AID done. PIV change processing of CVC certificates At the request of others va github comment, the method to used to extract an optional intermediate CVC certificate was changed. Unlike other certificate objects in 800-73-4, "Table 42. Secure Messaging Certificate Signer" the "Intermediate CVC (Conditional)" does not have an enclosing tag, but uses the 0x7F21 tag. Later the 0x7F21 tag is considered part of the certificate and a hash of the the full certificate is sent to the card as part of SM. OpenSC has a number of asn1 routines such as "sc_asn1_find" to find tags but once found, they only return the address of the value(V) and its length(L) but do not return the address of the found tag(T). The previous code reconstructed the address of the found tag be calculating the number of bytes it took to encode (L) and known tag(T). 800-73-4 says the "Intermediate CVC (Conditional)" immediately follows the "CertInfo" so the address of the following byte is saved to locate where the "Intermediate CVC (Conditional)" could start. Rename dec_counter to resp_enc_counter as name was misleading 800-74-4 says: "(i.e., the IV used to encrypt the first response after successful completion of the key establishment protocol shall be generated by encrypting '80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01' with SKENC)." Use the same (encrypted) IV the card used to encrypt the response when decrypting the response. Explain how SM APDU case is derived Added comment and used defines to show how the APDU for SM is derived from the plain APDU. and how it will allow for extended APDUs if NIST allows them or card vendor in known to support them. Changes to be committed: modified: etc/opensc.conf.example.in modified: src/libopensc/card-piv.c modified: src/libopensc/cards.h modified: src/libopensc/pkcs15-piv.c modified: src/libopensc/types.h --- etc/opensc.conf.example.in | 38 + src/libopensc/card-piv.c | 3512 ++++++++++++++++++++++++++++++------ src/libopensc/cards.h | 1 + src/libopensc/pkcs15-piv.c | 50 +- src/libopensc/types.h | 2 +- 5 files changed, 3000 insertions(+), 603 deletions(-) diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index f7c603b455..2d02b54cee 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -226,6 +226,44 @@ app default { # in the 'pkcs11' section below } + card_driver PIV-II { + # "piv_max_object_size" + # defines the buffer size used to read PIV objects + # Although NIST sp800-73-4 lists object sizes, these are not hard limits. + # Other PIV-like cards may have larger objects. + # Maximum: 65535 + # Minimum: 16384 + # Default: 16384 + # piv_max_object_size = 16384; + # May be set via environment: PIV_MAX_OBJECT_SIZE=16384 + + # "piv_use_sm" + # NIST sp800-73-4 supports Secure Messaging (SM), an optional feature. + # + # "piv_use_sm" may be set to: + # never - Don't use it. Card will react the same as cards without SM. + # always - Always use SM if card supports it for contact and contactless + # default - If card supports SM use for contactless (NFC) and for PIN, crypto, + # and sensitive objects with contact. + # piv_use_sm = "default"; + # May be set via environment: PIV_USE_SM=default + + # "piv_pairing_code" + # Virtual Contact Interface (VCI) an optional feature, to allow + # contactless access to card as if it was using the contact reader. + # VCI requires SM. It may also require a pairing code which may be printed on the + # card, given to card owner when card issued or available from the card when used + # with a contact reader. Contact your card issuing agency for details on what your + # card supports. + # Pairing code can be set in opensc.conf or via environment (recommended). + # It is an 8 digit string. + # Default: no pairing code. + # piv_pairing_code = 12345678; + # May be set via environment: PIV_PAIRING_CODE=12345678 + + # Environment variables override opensc.conf + } + # In addition to the built-in list of known cards in the # card driver, you can configure a new card for the driver # using the card_atr block. The goal is to centralize diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 4a2196ed51..ae0dcfaa4c 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3,7 +3,7 @@ * card-default.c: Support for cards with no driver * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2005-2020 Douglas E. Engert + * Copyright (C) 2005-2023 Douglas E. Engert * Copyright (C) 2006, Identity Alliance, Thomas Harning * Copyright (C) 2007, EMC, Russell Larner * @@ -39,14 +39,30 @@ #endif #ifdef ENABLE_OPENSSL - /* openssl only needed for card administration */ + /* openssl needed for card administration */ #include #include #include #include #include +#include +#if !defined(OPENSSL_NO_EC) +#include +#endif +#include + +#define piv_log_openssl(C) \ + do { if (C && C->debug > 0 && C->debug_file != 0) \ + { ERR_print_errors_fp(C->debug_file); } \ + } while(0) #endif /* ENABLE_OPENSSL */ +/* 800-73-4 SM and VCI need: ECC, SM and real OpenSSL >= 1.1 */ +#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) && !defined(OPENSSL_NO_EC) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L +#define ENABLE_PIV_SM +#include +#endif + #include "internal.h" #include "asn1.h" #include "cardctl.h" @@ -87,6 +103,9 @@ enum { PIV_OBJ_RETIRED_X509_19, PIV_OBJ_RETIRED_X509_20, PIV_OBJ_IRIS_IMAGE, + PIV_OBJ_BITGT, + PIV_OBJ_SM_CERT_SIGNER, + PIV_OBJ_PCRDCS, PIV_OBJ_9B03, PIV_OBJ_9A06, PIV_OBJ_9C06, @@ -120,16 +139,19 @@ enum { * PIV_OBJ_CACHE_VALID means the data in the cache can be used. * It might have zero length indicating that the object was not found. * PIV_OBJ_CACHE_NOT_PRESENT means do not even try to read the object. - * These objects will only be present if the history object says + * Either because the object did not parse or + * these objects will only be present if the history object says * they are on the card, or the discovery or history object in not present. - * If the file lilsted in the history object offCardCertURL was found, + * If the file listed in the history object offCardCertURL was found, * its certs will be read into the cache and PIV_OBJ_CACHE_VALID set * and PIV_OBJ_CACHE_NOT_PRESENT unset. + * */ -#define PIV_OBJ_CACHE_VALID 1 +#define PIV_OBJ_CACHE_VALID 1 #define PIV_OBJ_CACHE_COMPRESSED 2 #define PIV_OBJ_CACHE_NOT_PRESENT 8 +#define PIV_MAX_OBJECT_SIZE 16384 typedef struct piv_obj_cache { u8* obj_data; @@ -155,11 +177,220 @@ enum { #define PIV_CCC_TAG_F0 0xF0 #define PIV_CCC_TAG_F3 0xF3 +/* 800-73-4 Cipher Suite Table 14 */ +#define PIV_CS_CS2 0x27 +#define PIV_CS_CS7 0x2E + +#ifdef ENABLE_PIV_SM + /* Table 14 and other constants */ + typedef struct cipher_suite { + u8 id; /* taken from AID "AC" tag */ + int field_length; + int nid; /* for OpenSSL curves */ + struct sc_object_id oid; /* for opensc */ + int p1; /* for APDU */ + size_t Qlen; /* size of pubkey 04||x||y for all keys */ + size_t AuthCryptogramlen; /* both H and ICC must match */ + size_t Zlen; /* size of shared secret from ECDH */ + size_t otherinfolen; /* used in 4.1.6 Key Derivation */ + + int o0len; /* first in otherinfo */ + u8 o0_char; + size_t IDshlen; + size_t CBhlen; + size_t T16Qehlen; + size_t IDsicclen; + size_t Nicclen; + size_t CBicclen; /* last in otherinfo */ + + int naeskeys; /* number of aes key generated */ + int aeskeylen; /* size of aes key bytes*/ + int kdf_hash_size; /* size of hash in bytes */ + EVP_MD *(*kdf_md)(void); + const EVP_CIPHER *(*cipher_cbc)(void); + const EVP_CIPHER *(*cipher_ecb)(void); + char *cipher_cbc_name; + char *cipher_ecb_name; + char *curve_group; /* curve name TODO or is this just p-256 or p-384?*/ + } cipher_suite_t; + +// clang-fromat off +#define PIV_CSS_SIZE 2 +static cipher_suite_t css[PIV_CSS_SIZE] = { + {PIV_CS_CS2, 256, NID_X9_62_prime256v1, {{1, 2, 840, 10045, 3, 1, 7, -1}}, + PIV_CS_CS2, 65, 16, 32, 61, + 4, 0x09, 8, 1, 16, 8, 16, 1, + 4, 128/8, SHA256_DIGEST_LENGTH, + (EVP_MD *(*)(void)) EVP_sha256, + (const EVP_CIPHER *(*)(void)) EVP_aes_128_cbc, + (const EVP_CIPHER *(*)(void)) EVP_aes_128_ecb, + "aes-128-cbc", "aes-128-ecb", + "prime256v1"}, + + {PIV_CS_CS7, 384, NID_secp384r1, {{1, 3, 132, 0, 34, -1}}, + PIV_CS_CS7, 97, 16, 48, 69, + 4, 0x0D, 8, 1, 16, 8, 24, 1, + 4, 256/8, SHA384_DIGEST_LENGTH, + (EVP_MD *(*)(void)) EVP_sha384, + (const EVP_CIPHER *(*)(void)) EVP_aes_256_cbc, + (const EVP_CIPHER *(*)(void)) EVP_aes_256_ecb, + "aes-256-cbc", "aes-256-ecb", + "secp384r1"} + }; +// clang-format on + +/* 800-73-4 4.1.5 Card Verifiable Certificates */ +typedef struct piv_cvc { + sc_pkcs15_der_t der; // Previous read der + int cpi; // Certificate profile indicator (0x80) + char issuerID[8]; // Issuer Identification Number + size_t issuerIDlen; // 8 bytes of sha-1 or 16 byte for GUID + u8 subjectID[16]; // Subject Identifier (8) or GUID (16) == CHUI + size_t subjectIDlen; // 8 bytes of sha-1 or 16 byte for GUID + struct sc_object_id pubKeyOID; // Public key algorithm object identifier + u8 *publicPoint; // Public point for ECC + size_t publicPointlen; + int roleID; // Role Identifier 0x00 or 0x12 + u8 *body; // signed part of CVC in DER + size_t bodylen; + struct sc_object_id signatureAlgOID; // Signature Algroithm Identifier + u8 *signature; // Certificate signature DER + size_t signaturelen; +} piv_cvc_t; + +#define PIV_SM_MAX_FIELD_LENGTH 384 +#define PIV_SM_MAX_MD_LENGTH SHA384_DIGEST_LENGTH + +#define PIV_SM_FLAGS_SM_CERT_SIGNER_VERIFIED 0x000000001lu +#define PIV_SM_FLAGS_SM_CVC_VERIFIED 0X000000002lu +#define PIV_SM_FLAGS_SM_IN_CVC_VERIFIED 0x000000004lu +#define PIV_SM_FLAGS_SM_CERT_SIGNER_PRESENT 0x000000010lu +#define PIV_SM_FLAGS_SM_CVC_PRESENT 0X000000020lu +#define PIV_SM_FLAGS_SM_IN_CVC_PRESENT 0x000000040lu +#define PIV_SM_FLAGS_SM_IS_ACTIVE 0x000000080lu /* SM has been started */ + /* if card supports SP800-73-4 SM: */ +#define PIV_SM_FLAGS_NEVER 0x000000100lu /* Don't use SM even if card support it */ + /* Default is use if card supports it */ + /* will use VCI if card supports it for contactless */ +#define PIV_SM_FLAGS_ALWAYS 0x000000200lu /* Use SM or quit, VCI requires SM */ +#define PIV_SM_FLAGS_DEFER_OPEN 0x000001000lu /* call sm_open from reader_lock_obtained */ +#define PIV_SM_VCI_ACTIVE 0x000002000lu /* VCI is active */ +#define PIV_SM_GET_DATA_IN_CLEAR 0x000004000lu /* OK to do this GET DATA in the clear */ + +typedef struct piv_sm_session { + /* set by piv_sm_open */ + int aes_size; /* 128 or 256 */ + + u8 SKcfrm[32]; + u8 SKmac[32]; + u8 SKenc[32]; /* keys are either AES 128 or AES 256 */ + u8 SKrmac[32]; + u8 enc_counter[16]; + u8 enc_counter_last[16]; + + u8 resp_enc_counter[16]; + u8 C_MCV[16]; + u8 C_MCV_last[16]; + u8 R_MCV[16]; + u8 R_MCV_last[16]; +} piv_sm_session_t; + +#define C_ASN1_PIV_CVC_PUBKEY_SIZE 3 + /* ECC key only */ +static const struct sc_asn1_entry c_asn1_piv_cvc_pubkey[C_ASN1_PIV_CVC_PUBKEY_SIZE] = { + { "publicKeyOID", SC_ASN1_OBJECT, SC_ASN1_UNI | SC_ASN1_OBJECT, 0, NULL, NULL }, + { "publicPoint", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 6, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_PIV_CVC_DSOBJ_SIZE 2 +static const struct sc_asn1_entry c_asn1_piv_cvc_dsobj[C_ASN1_PIV_CVC_DSOBJ_SIZE] = { + { "DigitalSignature", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_PIV_CVC_DSSIG_SIZE 3 +static const struct sc_asn1_entry c_asn1_piv_cvc_dssig[C_ASN1_PIV_CVC_DSSIG_SIZE] = { + { "signatureAlgorithmID", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL }, + { "signatureValue", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_ALLOC, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_PIV_CVC_ALG_ID_SIZE 3 +static const struct sc_asn1_entry c_asn1_piv_cvc_alg_id[C_ASN1_PIV_CVC_ALG_ID_SIZE] = { + { "signatureAlgorithmOID", SC_ASN1_OBJECT, SC_ASN1_UNI | SC_ASN1_OBJECT, 0, NULL, NULL }, + { "nullParam", SC_ASN1_NULL, SC_ASN1_UNI | SC_ASN1_TAG_NULL, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_PIV_CVC_BODY_SIZE 7 +static const struct sc_asn1_entry c_asn1_piv_cvc_body[C_ASN1_PIV_CVC_BODY_SIZE] = { + { "certificateProfileIdentifier", SC_ASN1_INTEGER, SC_ASN1_APP | 0x1F29, 0, NULL, NULL }, + { "Issuer ID Number", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 2, 0, NULL, NULL }, + { "Subject Identifier", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x1F20, 0, NULL, NULL }, + { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F49, 0, NULL, NULL }, + { "roleIdentifier", SC_ASN1_CALLBACK, SC_ASN1_APP | 0x1F4C, 0, NULL, NULL }, + /* signature is over the above 5 entries treat roleIdentifier special to get end */ + { "DSignatureObject", SC_ASN1_STRUCT, SC_ASN1_APP | 0x1F37, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + + +#define C_ASN1_PIV_CVC_SIZE 2 +static const struct sc_asn1_entry c_asn1_piv_cvc[C_ASN1_PIV_CVC_SIZE] = { + { "CVC certificate", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_PIV_SM_RESPONSE_SIZE 4 +static const struct sc_asn1_entry c_asn1_sm_response[C_ASN1_PIV_SM_RESPONSE_SIZE] = { + { "encryptedData", SC_ASN1_CALLBACK, SC_ASN1_CTX | 7, SC_ASN1_OPTIONAL, NULL, NULL }, + { "statusWord", SC_ASN1_CALLBACK, SC_ASN1_CTX | 0x19, 0, NULL, NULL }, + { "mac", SC_ASN1_CALLBACK, SC_ASN1_CTX | 0x0E, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +/* + * SW internal apdu response table. + * + * Override APDU response error codes from iso7816.c to allow + * handling of SM specific error + */ +static const struct sc_card_error piv_sm_errors[] = { + {0x6882, SC_ERROR_SM, "SM not supported"}, + {0x6982, SC_ERROR_SM_NO_SESSION_KEYS, "SM Security status not satisfied"}, /* no session established */ + {0x6987, SC_ERROR_SM, "Expected SM Data Object missing"}, + {0x6988, SC_ERROR_SM_INVALID_SESSION_KEY, "SM Data Object incorrect"}, /* other process interference */ + {0, 0, NULL} +}; +#endif /* ENABLE_PIV_SM */ + +/* 800-73-4 3.3.2 Discovery Object - PIN Usage Policy */ +#define PIV_PP_PIN 0x00004000u +#define PIV_PP_GLOBAL 0x00002000u +#define PIV_PP_OCC 0x00001000u +#define PIV_PP_VCI_IMPL 0x00000800u +#define PIV_PP_VCI_WITHOUT_PC 0x00000400u +#define PIV_PP_PIV_PRIMARY 0x00000010u +#define PIV_PP_GLOBAL_PRIMARY 0x00000020u + +/* init_flags */ +#define PIV_INIT_AID_PARSED 0x00000001u +#define PIV_INIT_AID_AC 0x00000002u +#define PIV_INIT_DISCOVERY_PARSED 0x00000004u +#define PIV_INIT_DISCOVERY_PP 0x00000008u +#define PIV_INIT_IN_READER_LOCK_OBTAINED 0x00000010u +#define PIV_INIT_CONTACTLESS 0x00000020u + +#define PIV_PAIRING_CODE_LEN 8 + typedef struct piv_private_data { + struct sc_lv_data aid_der; /* previous aid response to compare */ int enumtag; - int selected_obj; /* The index into the piv_objects last selected */ - int return_only_cert; /* return the cert from the object */ - int rwb_state; /* first time -1, 0, in middle, 1 at eof */ + int max_object_size; /* use setable option. In case objects get bigger */ + int selected_obj; /* The index into the piv_objects last selected */ + int return_only_cert; /* return the cert from the object */ + int rwb_state; /* first time -1, 0, in middle, 1 at eof */ int operation; /* saved from set_security_env */ int algorithm; /* saved from set_security_env */ int key_ref; /* saved from set_security_env and */ @@ -183,6 +414,17 @@ typedef struct piv_private_data { int object_test_verify; /* Can test this object to set verification state of card */ int yubico_version; /* 3 byte version number of NEO or Yubikey4 as integer */ unsigned int ccc_flags; /* From CCC indicate if CAC card */ + unsigned int pin_policy; /* from discovery */ + unsigned int init_flags; + u8 csID; /* 800-73-4 Cipher Suite ID 0x27 or 0x2E */ +#ifdef ENABLE_PIV_SM + cipher_suite_t *cs; /* active cypher_suite */ + piv_cvc_t sm_cvc; /* 800-73-4: SM CVC Table 15 */ + piv_cvc_t sm_in_cvc; /* Intermediate CVC Table 16 */ + unsigned long sm_flags; + unsigned char pairing_code[PIV_PAIRING_CODE_LEN]; /* 8 ASCII digits */ + piv_sm_session_t sm_session; +#endif /* ENABLE_PIV_SM */ } piv_private_data_t; #define PIV_DATA(card) ((piv_private_data_t*)card->drv_data) @@ -195,27 +437,32 @@ struct piv_aid { }; /* - * The Generic entry should be the "A0 00 00 03 08 00 00 10 00 " - * NIST published this on 10/6/2005 - * 800-73-2 Part 1 now refers to version "02 00" + * The Generic AID entry should be the "A0 00 00 03 08 00 00 10 00 " + * NIST published 800-73 on 10/6/2005 + * 800-73-1 March 2006 included Errata + * 800-73-2 Part 1 implies version is "02 00" * i.e. "A0 00 00 03 08 00 00 01 00 02 00". - * but we don't need the version number. but could get it from the PIX. + * but we don't need the version number. But could get it from the PIX. + * Discovery object was added. * * 800-73-3 Part 1 now refers to "01 00" i.e. going back to 800-73-1. - * The main differences between 73-1, and 73-3 are the addition of the - * key History object and keys, as well as Discovery and Iris objects. - * These can be discovered by trying GET DATA + * The main differences between 73-2, and 73-3 are the addition of the + * key History object, certs and keys and Iris objects. + * These can be discovered using GET DATA + + * 800-73-4 Has many changs, including optional Secure Messaging, + * optional Virtial Contact Interface and pairing code. */ /* ATRs of cards known to have PIV applet. But must still be tested for a PIV applet */ static const struct sc_atr_table piv_atrs[] = { /* CAC cards with PIV from: CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc */ /* - * https://www.cac.mil/Common-Access-Card/Developer-Resources/ - * https://www.cac.mil/Portals/53/Documents/DoD%20Token%20utilziation%20and%20variation%20matrix%20v2_06_17October2019.docx?ver=2019-10-18-102519-120 - */ + * https://www.cac.mil/Common-Access-Card/Developer-Resources/ + * https://www.cac.mil/Portals/53/Documents/DoD%20Token%20utilziation%20and%20variation%20matrix%20v2_06_17October2019.docx?ver=2019-10-18-102519-120 + */ /* Oberthur Card Systems (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */ - { "3B:DB:96:00:80:1F:03:00:31:C0:64:77:E3:03:00:82:90.00:C1", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, + { "3B:DB:96:00:80:1F:03:00:31:C0:64:77:E3:03:00:82:90:00:C1", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* Gemalto (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */ { "3B 7D 96 00 00 80 31 80 65 B0 83 11 13 AC 83 00 90 00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL }, @@ -281,13 +528,13 @@ static const struct sc_atr_table piv_atrs[] = { /* PIVKey uTrust FIDO2 (73) */ { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, - /* ID-One PIV 2.4.1 on Cosmo V8.1 */ - { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, - { "3b:86:80:01:80:31:c1:52:41:12:76", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */ - /* Swissbit iShield Key Pro with PIV endpoint applet */ { "3b:97:11:81:21:75:69:53:68:69:65:6c:64:05", NULL, NULL, SC_CARD_TYPE_PIV_II_SWISSBIT, 0, NULL }, + /* ID-One PIV 2.4.1 on Cosmo V8.1 NIST sp800-73-4 with Secure Messaging and VCI 2020 */ + { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_800_73_4, 0, NULL }, + { "3b:86:80:01:80:31:c1:52:41:12:76", NULL, NULL, SC_CARD_TYPE_PIV_II_800_73_4, 0, NULL }, /* contactless */ + { NULL, NULL, NULL, 0, 0, NULL } }; @@ -302,7 +549,7 @@ static struct piv_supported_ec_curves { /* all have same AID */ static struct piv_aid piv_aids[] = { - {SC_CARD_TYPE_PIV_II_GENERIC, /* TODO not really card type but what PIV AID is supported */ + {SC_CARD_TYPE_PIV_II_GENERIC, /* Not really card type but what PIV AID is supported */ 9, 9, (u8 *) "\xA0\x00\x00\x03\x08\x00\x00\x10\x00" }, {0, 9, 0, NULL } }; @@ -330,13 +577,18 @@ static struct piv_aid piv_aids[] = { * indicated by the History object. */ -#define PIV_OBJECT_TYPE_CERT 1 -#define PIV_OBJECT_TYPE_PUBKEY 2 -#define PIV_OBJECT_NOT_PRESENT 4 +#define PIV_OBJECT_TYPE_CERT 0x01 +#define PIV_OBJECT_TYPE_PUBKEY 0x02 +#define PIV_OBJECT_NOT_PRESENT 0x04 +#define PIV_OBJECT_TYPE_CVC 0x08 /* is in cert object */ +#define PIV_OBJECT_NEEDS_PIN 0x10 /* On both contact and contactless */ +#define PIV_OBJECT_NEEDS_VCI 0x20 /* NIST sp800-73-4 Requires VCI on contactless and card enforces this. */ + /* But also See CI_NFC_EXPOSE_TOO_MUCH for non approved PIV-like cards */ struct piv_object { int enumtag; const char * name; + unsigned int resp_tag; const char * oidstring; size_t tag_len; u8 tag_value[3]; @@ -348,97 +600,143 @@ struct piv_object { // clang-format off static const struct piv_object piv_objects[] = { { PIV_OBJ_CCC, "Card Capability Container", - "2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_CHUI, "Card Holder Unique Identifier", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 0}, { PIV_OBJ_X509_PIV_AUTH, "X.509 Certificate for PIV Authentication", - "2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01", PIV_OBJECT_TYPE_CERT} , + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01", PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI} , { PIV_OBJ_CHF, "Card Holder Fingerprints", - "2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10", PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_PI, "Printed Information", - "2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01", PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_CHFI, "Cardholder Facial Images", - "2.16.840.1.101.3.7.2.96.48", 3, "\x5F\xC1\x08", "\x60\x30", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.96.48", 3, "\x5F\xC1\x08", "\x60\x30", PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_X509_DS, "X.509 Certificate for Digital Signature", - "2.16.840.1.101.3.7.2.1.0", 3, "\x5F\xC1\x0A", "\x01\x00", PIV_OBJECT_TYPE_CERT}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.1.0", 3, "\x5F\xC1\x0A", "\x01\x00", PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_X509_KM, "X.509 Certificate for Key Management", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.1.2", 3, "\x5F\xC1\x0B", "\x01\x02", PIV_OBJECT_TYPE_CERT}, { PIV_OBJ_X509_CARD_AUTH, "X.509 Certificate for Card Authentication", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.5.0", 3, "\x5F\xC1\x01", "\x05\x00", PIV_OBJECT_TYPE_CERT}, { PIV_OBJ_SEC_OBJ, "Security Object", - "2.16.840.1.101.3.7.2.144.0", 3, "\x5F\xC1\x06", "\x90\x00", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.144.0", 3, "\x5F\xC1\x06", "\x90\x00", PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_DISCOVERY, "Discovery Object", + SC_ASN1_APP | SC_ASN1_CONS | 0x1E, "2.16.840.1.101.3.7.2.96.80", 1, "\x7E", "\x60\x50", 0}, { PIV_OBJ_HISTORY, "Key History Object", - "2.16.840.1.101.3.7.2.96.96", 3, "\x5F\xC1\x0C", "\x60\x60", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.96.96", 3, "\x5F\xC1\x0C", "\x60\x60", PIV_OBJECT_NEEDS_VCI}, /* 800-73-3, 21 new objects, 20 history certificates */ { PIV_OBJ_RETIRED_X509_1, "Retired X.509 Certificate for Key Management 1", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.1", 3, "\x5F\xC1\x0D", "\x10\x01", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_2, "Retired X.509 Certificate for Key Management 2", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.2", 3, "\x5F\xC1\x0E", "\x10\x02", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_3, "Retired X.509 Certificate for Key Management 3", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.3", 3, "\x5F\xC1\x0F", "\x10\x03", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_4, "Retired X.509 Certificate for Key Management 4", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.4", 3, "\x5F\xC1\x10", "\x10\x04", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_5, "Retired X.509 Certificate for Key Management 5", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.5", 3, "\x5F\xC1\x11", "\x10\x05", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_6, "Retired X.509 Certificate for Key Management 6", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.6", 3, "\x5F\xC1\x12", "\x10\x06", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_7, "Retired X.509 Certificate for Key Management 7", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.7", 3, "\x5F\xC1\x13", "\x10\x07", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_8, "Retired X.509 Certificate for Key Management 8", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.8", 3, "\x5F\xC1\x14", "\x10\x08", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_9, "Retired X.509 Certificate for Key Management 9", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.9", 3, "\x5F\xC1\x15", "\x10\x09", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_10, "Retired X.509 Certificate for Key Management 10", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.10", 3, "\x5F\xC1\x16", "\x10\x0A", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_11, "Retired X.509 Certificate for Key Management 11", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.11", 3, "\x5F\xC1\x17", "\x10\x0B", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_12, "Retired X.509 Certificate for Key Management 12", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.12", 3, "\x5F\xC1\x18", "\x10\x0C", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_13, "Retired X.509 Certificate for Key Management 13", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.13", 3, "\x5F\xC1\x19", "\x10\x0D", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_14, "Retired X.509 Certificate for Key Management 14", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.14", 3, "\x5F\xC1\x1A", "\x10\x0E", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_15, "Retired X.509 Certificate for Key Management 15", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.15", 3, "\x5F\xC1\x1B", "\x10\x0F", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_16, "Retired X.509 Certificate for Key Management 16", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.16", 3, "\x5F\xC1\x1C", "\x10\x10", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_17, "Retired X.509 Certificate for Key Management 17", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.17", 3, "\x5F\xC1\x1D", "\x10\x11", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_18, "Retired X.509 Certificate for Key Management 18", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.18", 3, "\x5F\xC1\x1E", "\x10\x12", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_19, "Retired X.509 Certificate for Key Management 19", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.19", 3, "\x5F\xC1\x1F", "\x10\x13", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_RETIRED_X509_20, "Retired X.509 Certificate for Key Management 20", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.16.20", 3, "\x5F\xC1\x20", "\x10\x14", - PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI}, { PIV_OBJ_IRIS_IMAGE, "Cardholder Iris Images", - "2.16.840.1.101.3.7.2.16.21", 3, "\x5F\xC1\x21", "\x10\x15", 0}, + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.16.21", 3, "\x5F\xC1\x21", "\x10\x15", PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI}, + +/* 800-73-4, 3 new objects */ + { PIV_OBJ_BITGT, "Biometric Information Templates Group Template", + SC_ASN1_APP | SC_ASN1_CONS | 0x1F61, + "2.16.840.1.101.3.7.2.16.22", 2, "\x7F\x61", "\x10\x16", 0}, + { PIV_OBJ_SM_CERT_SIGNER, "Secure Messaging Certificate Signer", + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.16.23", 3, "\x5F\xC1\x22", "\x10\x17", + PIV_OBJECT_TYPE_CERT | PIV_OBJECT_TYPE_CVC}, + {PIV_OBJ_PCRDCS, "Pairing Code Reference Data Container", + SC_ASN1_APP | 0x13, + "2.16.840.1.101.3.7.2.16.24", 3, "\x5F\xC1\x23", "\x10\x18", PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI}, /* following not standard , to be used by piv-tool only for testing */ { PIV_OBJ_9B03, "3DES-ECB ADM", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.3", 2, "\x9B\x03", "\x9B\x03", 0}, /* Only used when signing a cert req, usually from engine * after piv-tool generated the key and saved the pub key @@ -446,55 +744,83 @@ static const struct piv_object piv_objects[] = { * but still use the "9x06" name. */ { PIV_OBJ_9A06, "RSA 9A Pub key from last genkey", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.20", 2, "\x9A\x06", "\x9A\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9C06, "Pub 9C key from last genkey", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.21", 2, "\x9C\x06", "\x9C\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9D06, "Pub 9D key from last genkey", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.22", 2, "\x9D\x06", "\x9D\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9E06, "Pub 9E key from last genkey", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.23", 2, "\x9E\x06", "\x9E\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8206, "Pub 82 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.101", 2, "\x82\x06", "\x82\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8306, "Pub 83 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.102", 2, "\x83\x06", "\x83\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8406, "Pub 84 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.103", 2, "\x84\x06", "\x84\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8506, "Pub 85 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.104", 2, "\x85\x06", "\x85\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8606, "Pub 86 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.105", 2, "\x86\x06", "\x86\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8706, "Pub 87 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.106", 2, "\x87\x06", "\x87\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8806, "Pub 88 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.107", 2, "\x88\x06", "\x88\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8906, "Pub 89 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.108", 2, "\x89\x06", "\x89\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8A06, "Pub 8A key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.109", 2, "\x8A\x06", "\x8A\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8B06, "Pub 8B key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.110", 2, "\x8B\x06", "\x8B\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8C06, "Pub 8C key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.111", 2, "\x8C\x06", "\x8C\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8D06, "Pub 8D key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.112", 2, "\x8D\x06", "\x8D\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8E06, "Pub 8E key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.113", 2, "\x8E\x06", "\x8E\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_8F06, "Pub 8F key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.114", 2, "\x8F\x06", "\x8F\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9006, "Pub 90 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.115", 2, "\x90\x06", "\x90\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9106, "Pub 91 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.116", 2, "\x91\x06", "\x91\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9206, "Pub 92 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.117", 2, "\x92\x06", "\x92\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9306, "Pub 93 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.118", 2, "\x93\x06", "\x93\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9406, "Pub 94 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.119", 2, "\x94\x06", "\x94\x06", PIV_OBJECT_TYPE_PUBKEY}, { PIV_OBJ_9506, "Pub 95 key ", + SC_ASN1_APP | 0x13, "2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY}, - { PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0} + /* + * "Secure Messaging Certificate Signer" is just a certificate. + * No pub or private key on the card. + */ + { PIV_OBJ_LAST_ENUM, "", 0, "", 0, "", "", 0} }; // clang-format on @@ -507,201 +833,1953 @@ static struct sc_card_driver piv_drv = { NULL, 0, NULL }; +static int piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len); +static int piv_cache_internal_data(sc_card_t *card, int enumtag); +static int piv_logout(sc_card_t *card); static int piv_match_card_continued(sc_card_t *card); +static int piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags); -static int -piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) +/* compare sc_asn1_read_tag to expected tag_long */ +/* after #2079 can be converted to inline "if ((cla<<24 ! tag) == tag_long))" */ +static int piv_is_expected_tag(unsigned int cla, unsigned int tag, unsigned int tag_long) { - int i; + unsigned int tag_read = tag; - LOG_FUNC_CALLED(card->ctx); - sc_log(card->ctx, "str=0x%02X%02X\n", str[0], str[1]); + /* UNIVERSAL is 0, PRIVATE is both APPLICATION and CONTEXT */ + tag_read |= ((cla & SC_ASN1_TAG_APPLICATION) ? SC_ASN1_APP : 0); + tag_read |= ((cla & SC_ASN1_TAG_CONTEXT) ? SC_ASN1_CTX : 0); + tag_read |= ((cla & SC_ASN1_TAG_CONSTRUCTED) ? SC_ASN1_CONS : 0); + return (tag_read == tag_long); +} - for (i = 0; piv_objects[i].enumtag < PIV_OBJ_LAST_ENUM; i++) { - if ( str[0] == piv_objects[i].containerid[0] && str[1] == piv_objects[i].containerid[1]) - LOG_FUNC_RETURN(card->ctx, i); +#ifdef ENABLE_PIV_SM +static void piv_inc(u8 *counter, size_t size) +{ + unsigned int c = 1; + unsigned int b; + int i; + for (i = size - 1; c != 0 && i >= 0; i--){ + b = c + counter[i]; + counter[i] = b & 0xff; + c = b>>8; } - - LOG_FUNC_RETURN(card->ctx, -1); } /* - * Send a command and receive data. There is always something to send. - * Used by GET DATA, PUT DATA, GENERAL AUTHENTICATE - * and GENERATE ASYMMETRIC KEY PAIR. - * GET DATA may call to get the first 128 bytes to get the length from the tag. + * Construct SM protected APDU */ -static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, - const u8 * sendbuf, size_t sendbuflen, u8 *recvbuf, - size_t recvbuflen) +static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) { - int r; - sc_apdu_t apdu; + int r = 0; + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; + u8 pad[16] ={0x80}; + u8 zeros[16] = {0x00}; + u8 IV[16]; + u8 header[16]; + int padlen = 16; /* may be less */ + u8 *sbuf = NULL; + size_t sbuflen = 0; + int MCVlen = 16; + int enc_datalen = 0; + int T87len; + int T97len = 2 + 1; + int T8Elen = 2 + 8; + + int outli = 0; + int outl = 0; + int outll = 0; + int outdl = 0; + u8 discard[16]; + int macdatalen; + size_t C_MCVlen = 16; /* debugging*/ + + u8 *p; + EVP_CIPHER_CTX *ed_ctx = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX *cmac_ctx = NULL; +#else + EVP_MAC_CTX *cmac_ctx = NULL; + EVP_MAC *mac = NULL; + OSSL_PARAM cmac_params[2]; + size_t cmac_params_n; +#endif SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - r = sc_lock(card); - if (r != SC_SUCCESS) - LOG_FUNC_RETURN(card->ctx, r); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + cmac_ctx = CMAC_CTX_new(); + if (cmac_ctx == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } +#else + mac = EVP_MAC_fetch(NULL, "cmac", NULL); + cmac_params_n = 0; + cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); + cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); + if (mac == NULL + || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } +#endif - sc_format_apdu(card, &apdu, - recvbuf ? SC_APDU_CASE_4_SHORT: SC_APDU_CASE_3_SHORT, - ins, p1, p2); - apdu.flags |= SC_APDU_FLAGS_CHAINING; - apdu.lc = sendbuflen; - apdu.datalen = sendbuflen; - apdu.data = sendbuf; + ed_ctx = EVP_CIPHER_CTX_new(); + if (ed_ctx == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } - if (recvbuf && recvbuflen) { - apdu.le = (recvbuflen > 256) ? 256 : recvbuflen; - apdu.resplen = recvbuflen; + if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 + || EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 + || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.enc_counter, 16) != 1 + || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 + || outdl != 0) { + sc_log(card->ctx,"SM encode failed in OpenSSL"); + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } + + sm_apdu->cla = 0x0c; + sm_apdu->ins = plain->ins; + sm_apdu->p1 = plain->p1; + sm_apdu->p2 = plain->p2; + + /* + * All APDUs will be converted to case as SM data is always sent and received + * if plain->cse == SC_APDU_CASE_1 it never has the the 0x20 bit set + * which "let OpenSC decides whether to use short or extended APDUs" + * PIV SM data added for plain->cse == SC_APDU_CASE_1 will not need extended APDUs. + * + * NIST 800-73-4 does not say if cards can or must support extended APDUs + * they must support command chaining and multiple get response APDUs and + * all examples use short APDUs. The following keep the option open to use extended + * APDUs in future specifications or "PIV like" cards are know to + * support extended APDUs. + * + * Turn off the CASE bits, and set CASE 4 in sm_apdu. + */ + + sm_apdu->cse = (plain->cse & ~SC_APDU_SHORT_MASK) | SC_APDU_CASE_4_SHORT; + + p = header; /* to be included in CMAC */ + *p++ = 0x0c; + *p++ = plain->ins; + *p++ = plain->p1; + *p++ = plain->p2; + memcpy(p, pad, 12); + + /* 800-73-4 say padding is 1 to 16 bytes, with 0x80 0x00... */ + + /* may not need enc_data for cse 1 or 2 */ + if (plain->datalen == 0) { + enc_datalen = 0; + T87len = 0; + padlen = 0; } else { - apdu.le = 0; - apdu.resplen = 0; + enc_datalen = ((plain->datalen + 15) / 16) * 16; /* may add extra 16 bytes */ + padlen = enc_datalen - plain->datalen; + r = T87len = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, NULL, 0, NULL); + if (r < 0) + goto err; } - apdu.resp = recvbuf; - /* with new adpu.c and chaining, this actually reads the whole object */ - r = sc_transmit_apdu(card, &apdu); + if (plain->resplen == 0 || plain->le == 0) + T97len = 0; - if (r < 0) { - sc_log(card->ctx, "Transmit failed"); + sbuflen = T87len + T97len + T8Elen; + + sbuf = calloc(1, sbuflen); + if (sbuf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; goto err; } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); + p = sbuf; + if (T87len != 0) { + r = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, sbuf, sbuflen, &p); + if (r != SC_SUCCESS) + goto err; - if (r < 0) { - sc_log(card->ctx, "Card returned error "); + *p++ = 0x01; /* padding context indicator */ + + /* first round encryptes Enc counter with zero IV, and does not save the output */ + if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 + || EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 + || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 + || EVP_EncryptUpdate(ed_ctx, p ,&outl, plain->data, plain->datalen) != 1 + || EVP_EncryptUpdate(ed_ctx, p + outl, &outll, pad, padlen) != 1 + || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 + || outdl != 0) { /* should not happen */ + sc_log(card->ctx,"SM _encode failed in OpenSSL"); + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } + p += enc_datalen; + } + + if (T97len) { + *p++ = 0x97; + *p++ = 0x01; + *p++ = plain->le; + } + macdatalen = p - sbuf; + + memcpy(priv->sm_session.C_MCV_last, priv->sm_session.C_MCV, MCVlen); /* save is case fails */ + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (CMAC_Init(cmac_ctx, priv->sm_session.SKmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 + || CMAC_Update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) != 1 + || CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 + || CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 + || CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) { + r = SC_ERROR_INTERNAL; + goto err; + } +#else + if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKmac, + priv->sm_session.aes_size, cmac_params) + || !EVP_MAC_update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) + || !EVP_MAC_update(cmac_ctx, header, sizeof(header)) + || !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) + || !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) { + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; goto err; } +#endif - r = apdu.resplen; + *p++ = 0x8E; + *p++ = 0x08; + memcpy(p, priv->sm_session.C_MCV, 8); + p += 8; + if (p != sbuf + sbuflen) { /* debugging */ + r = SC_ERROR_INTERNAL; + goto err; + } + sm_apdu->data = sbuf; + sm_apdu->datalen = sbuflen; + sbuf = NULL; + sm_apdu->lc = sm_apdu->datalen; + if (sm_apdu->datalen > 255) + sm_apdu->flags |= SC_APDU_FLAGS_CHAINING; + + sm_apdu->resplen = plain->resplen + 40; /* expect at least tagged status and rmac8 */ + sm_apdu->resp = malloc(sm_apdu->resplen); + if (sm_apdu->resp == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + sm_apdu->le = 256; /* always ask for 256 */ + + memcpy(priv->sm_session.enc_counter_last, priv->sm_session.enc_counter, sizeof(priv->sm_session.enc_counter)); + piv_inc(priv->sm_session.enc_counter, sizeof(priv->sm_session.enc_counter)); + + r = SC_SUCCESS; err: - sc_unlock(card); + + free(sbuf); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX_free(cmac_ctx); +#else + EVP_MAC_CTX_free(cmac_ctx); + EVP_MAC_free(mac); +#endif + + EVP_CIPHER_CTX_free(ed_ctx); + LOG_FUNC_RETURN(card->ctx, r); } -/* Add the PIV-II operations */ -/* Should use our own keydata, actually should be common to all cards */ -/* RSA and EC are added. */ -static int piv_generate_key(sc_card_t *card, - sc_cardctl_piv_genkey_info_t *keydata) +static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) { - int r; - u8 rbuf[4096]; - u8 *p; - const u8 *tag; - u8 tagbuf[16]; - u8 outdata[3]; /* we could also add tag 81 for exponent */ - size_t taglen; - size_t out_len; - size_t in_len; - unsigned int cla_out, tag_out; + int r = SC_SUCCESS; + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - keydata->exponent = NULL; - keydata->exponent_len = 0; - keydata->pubkey = NULL; - keydata->pubkey_len = 0; - keydata->ecparam = NULL; /* will show size as we only support 2 curves */ - keydata->ecparam_len = 0; - keydata->ecpoint = NULL; - keydata->ecpoint_len = 0; - - out_len = 3; - outdata[0] = 0x80; - outdata[1] = 0x01; - outdata[2] = keydata->key_algid; - switch (keydata->key_algid) { - case 0x05: keydata->key_bits = 3072; break; - case 0x06: keydata->key_bits = 1024; break; - case 0x07: keydata->key_bits = 2048; break; - /* TODO: - DEE For EC, also set the curve parameter as the OID */ - case 0x11: keydata->key_bits = 0; - keydata->ecparam =0; /* we only support prime256v1 for 11 */ - keydata->ecparam_len =0; + if (!plain || !sm_apdu) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + + /* Does card support SM? Should not be here */ + if (priv->csID == 0 || cs == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); + + switch (plain->ins) { + case 0xCB: /* GET_DATA */ + /* If not contactless, could read in clear */ + /* Discovery object never has PIV_SM_GET_DATA_IN_CLEAR set */ + sc_log(card->ctx,"init_flags:0x%8.8x sm_flags:0x%8.8lx",priv->init_flags,priv->sm_flags); + if (!(priv->init_flags & PIV_INIT_CONTACTLESS) + && !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) + && (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) { + priv->sm_flags &= ~PIV_SM_GET_DATA_IN_CLEAR; + LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); + } break; - case 0x14: keydata->key_bits = 0; - keydata->ecparam = 0; /* we only support secp384r1 */ - keydata->ecparam_len = 0; + case 0x20: /* VERIFY */ break; - default: - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + case 0x24: /* CHANGE REFERENCE DATA */ + break; + case 0x87: /* GENERAL AUTHENTICATE */ + break; + default: /* just issue the plain apdu */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED); } - p = tagbuf; + *sm_apdu = calloc(1, sizeof(sc_apdu_t)); + if (*sm_apdu == NULL) { + return SC_ERROR_OUT_OF_MEMORY; + } - r = sc_asn1_put_tag(0xAC, outdata, out_len, tagbuf, sizeof(tagbuf), &p); - if (r != SC_SUCCESS) { - sc_log(card->ctx, "Failed to encode ASN1 tag"); - goto err; + r = piv_encode_apdu(card, plain, *sm_apdu); + if (r < 0 && *sm_apdu) { + free((*sm_apdu)->resp); + free(*sm_apdu); + *sm_apdu = NULL; } - r = piv_general_io(card, 0x47, 0x00, keydata->key_num, - tagbuf, p - tagbuf, rbuf, sizeof rbuf); + LOG_FUNC_RETURN(card->ctx, r); +} - if (r >= 0) { - const u8 *cp; - cp = rbuf; - in_len = r; +/* ASN1 callback to save address and len of the object */ +static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth) +{ + struct sc_lv_data *al = arg; - /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */ - r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len); - if (cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) { - r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; - } - if (r != SC_SUCCESS) { - sc_log(card->ctx, "Tag buffer not found"); - goto err; - } + if (!arg) + return SC_ERROR_INTERNAL; - /* if RSA vs EC */ - if (keydata->key_bits > 0 ) { - tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen); - if (tag != NULL && taglen <= 4) { - keydata->exponent = malloc(taglen); - if (keydata->exponent == NULL) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - keydata->exponent_len = taglen; - memcpy (keydata->exponent, tag, taglen); - } + al->value = (u8 *)obj; + al->len = len; + return SC_SUCCESS; +} - tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x81, &taglen); - if (tag != NULL && taglen > 0) { - keydata->pubkey = malloc(taglen); - if (keydata->pubkey == NULL) { - free(keydata->exponent); - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - } - keydata->pubkey_len = taglen; - memcpy (keydata->pubkey, tag, taglen); - } - } - else { /* must be EC */ - tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x86, &taglen); - if (tag != NULL && taglen > 0) { - keydata->ecpoint = malloc(taglen); - if (keydata->ecpoint == NULL) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - keydata->ecpoint_len = taglen; - memcpy (keydata->ecpoint, tag, taglen); - } - } +static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu) +{ + int r = SC_SUCCESS; + int i; + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; + struct sc_lv_data ee = {NULL, 0}; + struct sc_lv_data status = {NULL, 0}; + struct sc_lv_data rmac8 = {NULL, 0}; + u8 zeros[16] = {0}; + u8 IV[16]; + u8 *p; + int outl; + int outli; + int outll; + int outdl; + u8 lastb[16]; + u8 discard[8]; + u8 *q = NULL; + int inlen; + int macdatalen; + + size_t MCVlen = 16; + size_t R_MCVlen = 0; + + EVP_CIPHER_CTX *ed_ctx = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX *cmac_ctx = NULL; +#else + EVP_MAC *mac = NULL; + EVP_MAC_CTX *cmac_ctx = NULL; + OSSL_PARAM cmac_params[2]; + size_t cmac_params_n = 0; +#endif - /* TODO: -DEE Could add key to cache so could use engine to generate key, - * and sign req in single operation */ - r = 0; - } + struct sc_asn1_entry asn1_sm_response[C_ASN1_PIV_SM_RESPONSE_SIZE]; -err: - LOG_FUNC_RETURN(card->ctx, r); -} + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + sc_copy_asn1_entry(c_asn1_sm_response, asn1_sm_response); + + sc_format_asn1_entry(asn1_sm_response + 0, piv_get_asn1_obj, &ee, 0); + sc_format_asn1_entry(asn1_sm_response + 1, piv_get_asn1_obj, &status, 0); + sc_format_asn1_entry(asn1_sm_response + 2, piv_get_asn1_obj, &rmac8, 0); + + r = sc_asn1_decode(card->ctx, asn1_sm_response, sm_apdu->resp, sm_apdu->resplen, NULL, NULL); + + if (r < 0) { + sc_log(card->ctx,"SM decode failed"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if (asn1_sm_response[0].flags & SC_ASN1_PRESENT /* optional */ + && ( ee.value == NULL || ee.len <= 2)) { + sc_log(card->ctx,"SM BER-TLV not valid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 + || (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) { + sc_log(card->ctx,"SM missing status or R-MAC"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if (status.len != 2 + || status.value == NULL + || rmac8.len != 8 + || rmac8.value == NULL) { + sc_log(card->ctx,"SM status or R-MAC length invalid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + cmac_ctx = CMAC_CTX_new(); + if (cmac_ctx == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } +#else + mac = EVP_MAC_fetch(NULL, "cmac", NULL); + cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); + cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); + if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } +#endif + + /* MCV is first, then BER TLV Encoded Encrypted PIV Data and Status */ + macdatalen = status.value + status.len - sm_apdu->resp; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (CMAC_Init(cmac_ctx, priv->sm_session.SKrmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 + || CMAC_Update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) != 1 + || CMAC_Update(cmac_ctx, sm_apdu->resp, macdatalen) != 1 + || CMAC_Final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen) != 1) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#else + if(!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKrmac, + priv->sm_session.aes_size, cmac_params) + || !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) + || !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) + || !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) { + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } +#endif + + if (memcmp(priv->sm_session.R_MCV, rmac8.value, 8) != 0) { + sc_log(card->ctx, "SM 8 bytes of R-MAC do not match received R-MAC"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + ed_ctx = EVP_CIPHER_CTX_new(); + if (ed_ctx == NULL) { + r = SC_ERROR_INTERNAL; + goto err; + } + + /* generate same IV used to encrypt response on card */ + if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 + || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 + || EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 + || EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 + || outdl != 0) { + sc_log(card->ctx,"SM encode failed in OpenSSL"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* some commands do not have response data */ + if (ee.value != NULL) { + p = ee.value; + inlen = ee.len; + if (inlen < 17 || *p != 0x01) { /*padding indicator is required */ + sc_log(card->ctx, "SM padding indicatior not 0x01"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + p++; /* skip padding indicator */ + inlen --; + + if ((inlen % 16) != 0) { + sc_log(card->ctx,"SM encrypted data not multiple of 16"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* + * Encrypted data has 1 to 16 pad bytes, so may be 1 to 16 bytes longer + * then expected. i.e. plain->resp and resplen.So will do last block + * and recombine. + */ + + inlen -= 16; + if (plain->resplen < (unsigned) inlen) { + sc_log(card->ctx, "SM response will not fit in resp,resplen"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + q = plain->resp; + + /* first round encryptes counter with zero IV, and does not save the output */ + if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 + || EVP_DecryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 + || EVP_CIPHER_CTX_set_padding(ed_ctx,0) != 1 + || EVP_DecryptUpdate(ed_ctx, q ,&outl, p, inlen) != 1 + || EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16 ) != 1 + || EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 + || outdl != 0 + || outll != 16) { /* should not happen */ + sc_log(card->ctx,"SM _decode failed in OpenSSL"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* unpad last block and get bytes in last block */ + for (i = 15; i >= 0 ; i--) { + if (lastb[i] == 0x80) + break; + if (lastb[i] == 0x00) + continue; + sc_log(card->ctx, "SM Padding not correct"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if (lastb[i] != 0x80) { + sc_log(card->ctx, "SM Padding not correct"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* will response fit in plain resp buffer */ + if ((unsigned)inlen + i > plain->resplen || plain->resp == NULL) { + sc_log(card->ctx,"SM response bigger then resplen"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* copy bytes in last block if any */ + memcpy(plain->resp + inlen, lastb, i); + plain->resplen = inlen + i; + } + + plain->sw1 = *(status.value); + plain->sw2 = *(status.value + 1); + + piv_inc(priv->sm_session.resp_enc_counter, sizeof(priv->sm_session.resp_enc_counter)); + + r = SC_SUCCESS; +err: + if (r != 0 && plain) { + plain->sw1 = 0x69; + plain->sw2 = 0x88; + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX_free(cmac_ctx); +#else + EVP_MAC_CTX_free(cmac_ctx); + EVP_MAC_free(mac); +#endif + + EVP_CIPHER_CTX_free(ed_ctx); + + LOG_FUNC_RETURN(card->ctx, r); +} + +static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu) +{ + int r = SC_SUCCESS; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (!sm_apdu) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + if (!(*sm_apdu)) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + + if (plain) { + plain->sw1 = (*sm_apdu)->sw1; + plain->sw2 = (*sm_apdu)->sw2; + if (((*sm_apdu)->sw1 == 0x90 && (*sm_apdu)->sw2 == 00) + || (*sm_apdu)->sw1 == 61){ + r = piv_decode_apdu(card, plain, *sm_apdu); + goto err; + } + sc_log(card->ctx,"SM response sw1:0x%2.2x sw2:0x%2.2x", plain->sw1, plain->sw2); + if (plain->sw1 == 0x69 && plain->sw2 == 0x88) { + /* BUT plain->sw1 and sw2 are not passed back as expected */ + r = SC_ERROR_SM_INVALID_CHECKSUM; /* will use this one one for now */ + goto err; + } else { + r = SC_ERROR_SM; + goto err; + } + } + +err: + free((unsigned char **)(*sm_apdu)->data); + free((*sm_apdu)->resp); + free(*sm_apdu); + *sm_apdu = NULL; + + LOG_FUNC_RETURN(card->ctx, r); +} + + +static int piv_sm_close(sc_card_t *card) +{ + int r = 0; + piv_private_data_t * priv = PIV_DATA(card); + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + sc_log(card->ctx, "priv->sm_flags: 0x%8.8lu", priv->sm_flags); + + /* sm.c tries to restart sm. Will defer */ + if ((priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE)) { + priv->sm_flags |= PIV_SM_FLAGS_DEFER_OPEN; + priv->sm_flags &= ~PIV_SM_FLAGS_SM_IS_ACTIVE; + } + + LOG_FUNC_RETURN(card->ctx, r); +} + +static void piv_clear_cvc_content(piv_cvc_t *cvc) +{ + if (!cvc) + return; + free(cvc->body); + free(cvc->signature); + free(cvc->publicPoint); + free(cvc->der.value); + memset(cvc, 0, sizeof(piv_cvc_t)); + return; +} + +static void piv_clear_sm_session(piv_sm_session_t *session) +{ + if (!session) + return; + sc_mem_clear(session, sizeof(piv_sm_session_t)); + return; +} + +/* + * Decode a card verifiable certificate as defined in NIST 800-73-4 + */ +static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, + piv_cvc_t *cvc) +{ + struct sc_asn1_entry asn1_piv_cvc[C_ASN1_PIV_CVC_SIZE]; + struct sc_asn1_entry asn1_piv_cvc_body[C_ASN1_PIV_CVC_BODY_SIZE]; + struct sc_asn1_entry asn1_piv_cvc_pubkey[C_ASN1_PIV_CVC_PUBKEY_SIZE]; + struct sc_asn1_entry asn1_piv_cvc_dsobj[C_ASN1_PIV_CVC_DSOBJ_SIZE]; + struct sc_asn1_entry asn1_piv_cvc_dssig[C_ASN1_PIV_CVC_DSSIG_SIZE]; + struct sc_asn1_entry asn1_piv_cvc_alg_id[C_ASN1_PIV_CVC_ALG_ID_SIZE]; + struct sc_lv_data roleIDder = {NULL, 0}; + int r; + const u8 *buf_tmp; + unsigned int cla_out, tag_out; + size_t taglen; + size_t signaturebits; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* If already read and matches previous version return SC_SUCCESS */ + if (cvc->der.value && (cvc->der.len == *buflen) && buf && *buf + && (memcmp(cvc->der.value, *buf, *buflen) == 0)) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + + piv_clear_cvc_content(cvc); + + memset(cvc, 0, sizeof(piv_cvc_t)); + cvc->issuerIDlen = sizeof(cvc->issuerID); + cvc->subjectIDlen = sizeof(cvc->subjectID); + + sc_copy_asn1_entry(c_asn1_piv_cvc, asn1_piv_cvc); + sc_copy_asn1_entry(c_asn1_piv_cvc_body, asn1_piv_cvc_body); + sc_copy_asn1_entry(c_asn1_piv_cvc_pubkey, asn1_piv_cvc_pubkey); + sc_copy_asn1_entry(c_asn1_piv_cvc_dsobj, asn1_piv_cvc_dsobj); + sc_copy_asn1_entry(c_asn1_piv_cvc_dssig, asn1_piv_cvc_dssig); + sc_copy_asn1_entry(c_asn1_piv_cvc_alg_id, asn1_piv_cvc_alg_id); + + sc_format_asn1_entry(asn1_piv_cvc_alg_id , &cvc->signatureAlgOID, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_alg_id + 1, NULL, NULL, 1); /* NULL */ + + sc_format_asn1_entry(asn1_piv_cvc_dssig , &asn1_piv_cvc_alg_id, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_dssig + 1, &cvc->signature, &signaturebits, 1); + + sc_format_asn1_entry(asn1_piv_cvc_dsobj , &asn1_piv_cvc_dssig, NULL, 1); + + sc_format_asn1_entry(asn1_piv_cvc_pubkey , &cvc->pubKeyOID, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_pubkey + 1, &cvc->publicPoint, &cvc->publicPointlen, 1); + + sc_format_asn1_entry(asn1_piv_cvc_body , &cvc->cpi, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_body + 1, &cvc->issuerID, &cvc->issuerIDlen, 1); + sc_format_asn1_entry(asn1_piv_cvc_body + 2, &cvc->subjectID, &cvc->subjectIDlen, 1); + sc_format_asn1_entry(asn1_piv_cvc_body + 3, &asn1_piv_cvc_pubkey, NULL, 1); + sc_format_asn1_entry(asn1_piv_cvc_body + 4, piv_get_asn1_obj, &roleIDder, 1); + sc_format_asn1_entry(asn1_piv_cvc_body + 5, &asn1_piv_cvc_dsobj, NULL, 1); + + sc_format_asn1_entry(asn1_piv_cvc, &asn1_piv_cvc_body, NULL, 1); + + r = sc_asn1_decode(card->ctx, asn1_piv_cvc, *buf, *buflen, NULL, NULL) ; /*(const u8 **) &buf_tmp, &len);*/ + LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate"); + + cvc->signaturelen = signaturebits / 8; + + if (roleIDder.len != 1) + LOG_TEST_RET(card->ctx, SC_ERROR_SM_AUTHENTICATION_FAILED, "roleID wrong length"); + + cvc->roleID = *roleIDder.value; + + /* save body der for verification */ + buf_tmp = *buf; + r = sc_asn1_read_tag(&buf_tmp, *buflen, &cla_out, &tag_out, &taglen); + LOG_TEST_RET(card->ctx, r," failed to read tag"); + + cvc->bodylen = (roleIDder.value + roleIDder.len) - buf_tmp; + + cvc->body = malloc(cvc->bodylen); + if (cvc->body == NULL) + return SC_ERROR_OUT_OF_MEMORY; + memcpy(cvc->body, buf_tmp, cvc->bodylen); + + /* save to reuse */ + cvc->der.value = malloc(*buflen); + if (cvc->der.value == NULL) { + free(cvc->body); + return SC_ERROR_OUT_OF_MEMORY; + } + cvc->der.len = *buflen; + memcpy(cvc->der.value, *buf, cvc->der.len); + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); +} + + +int piv_parse_pairing_code(sc_card_t *card, const char *option) +{ + size_t i; + + if (strlen(option) != PIV_PAIRING_CODE_LEN) { + sc_log(card->ctx, "pairing code length invalid must be %d", PIV_PAIRING_CODE_LEN); + return SC_ERROR_INVALID_ARGUMENTS; + } + for (i = 0; i < PIV_PAIRING_CODE_LEN; i++) { + if (!isdigit(option[i])) { + sc_log(card->ctx, "pairing code must be %d decimal digits",PIV_PAIRING_CODE_LEN); + return SC_ERROR_INVALID_ARGUMENTS; + } + } + return SC_SUCCESS; +} +#endif + +static int piv_load_options(sc_card_t *card) +{ + int r; + piv_private_data_t * priv = PIV_DATA(card); + size_t i, j; + scconf_block **found_blocks, *block; + + const char *option = NULL; + int piv_max_object_size_found = 0; +#ifdef ENABLE_PIV_SM + int piv_pairing_code_found = 0; + int piv_use_sm_found = 0; +#endif + + option = getenv("PIV_MAX_OBJECT_SIZE"); + if (option && option[0] != '\0') { + sc_log(card->ctx, "getenv(\"PIV_MAX_OBJECT_SIZE\")=\"%s\"", option); + priv->max_object_size = atoi(option); + if (priv->max_object_size < PIV_MAX_OBJECT_SIZE || priv->max_object_size > MAX_FILE_SIZE) { + sc_log(card->ctx,"Invalid max_object_size: \"%d\"", priv->max_object_size); + if (priv->max_object_size < PIV_MAX_OBJECT_SIZE) + priv->max_object_size = PIV_MAX_OBJECT_SIZE; + else + priv->max_object_size = MAX_FILE_SIZE; /* conserative value if error */ + } else + piv_max_object_size_found = 1; + sc_log(card->ctx," priv->max_object_size:%d", priv->max_object_size); + } + +#ifdef ENABLE_PIV_SM + /* pairing code is 8 decimal digits and is card specific */ + if ((option = getenv("PIV_PAIRING_CODE")) != NULL) { + sc_log(card->ctx,"getenv(\"PIV_PAIRING_CODE\") found"); + if (piv_parse_pairing_code(card, option) == SC_SUCCESS) { + memcpy(priv->pairing_code, option, PIV_PAIRING_CODE_LEN); + piv_pairing_code_found = 1; + } + } + + if ((option = getenv("PIV_USE_SM"))!= NULL) { + sc_log(card->ctx,"getenv(\"PIV_USE_SM\")=\"%s\"", option); + if (!strcmp(option, "never")) { + priv->sm_flags |= PIV_SM_FLAGS_NEVER; + piv_use_sm_found = 1; + } + else if (!strcmp(option, "always")) { + priv->sm_flags |= PIV_SM_FLAGS_ALWAYS; + piv_use_sm_found = 1; + } + else { + sc_log(card->ctx,"Invalid piv_use_sm: \"%s\"", option); + } + } +#endif + + for (i = 0; card->ctx->conf_blocks[i]; i++) { + found_blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], + "card_driver", "PIV-II"); + if (!found_blocks) + continue; + + for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { + +#ifdef ENABLE_PIV_SM + /* + * "piv_use_sm" if card supports NIST sp800-73-4 sm, when should it be used + * never - use card like 800-73-3, i.e. contactless is very limited on + * true PIV cards. Some PIV-like" card may allow this. + * this security risk + * always - Use even for contact interface. + * PINS, crypto and reading of object will not show up in logs + * or over network. + */ + + if (piv_use_sm_found == 0) { + option = scconf_get_str(block, "piv_use_sm", "default"); + sc_log(card->ctx,"conf: \"piv_use_sm\"=\"%s\"", option); + if (!strcmp(option,"default")) { + /* no new flags */ + } + else if (!strcmp(option, "never")) { + priv->sm_flags |= PIV_SM_FLAGS_NEVER; + } + else if (!strcmp(option, "always")) { + priv->sm_flags |= PIV_SM_FLAGS_ALWAYS; + } + else { + sc_log(card->ctx,"Invalid piv_use_sm: \"%s\"", option); + } + } + + /* This is really a card specific value and should not be in the conf file */ + if (piv_pairing_code_found == 0) { + option = scconf_get_str(block, "piv_pairing_code", NULL); + if (option && piv_parse_pairing_code(card, option) == SC_SUCCESS) { + memcpy(priv->pairing_code, option, PIV_PAIRING_CODE_LEN); + } + } +#endif + /* + * Largest object defined in NIST sp800-73-3 and sp800-73-4 is 12710 bytes + * If for some reason future cards have larger objects, the buffer size can be changed. + * (This not not max_read_size) + */ + if (piv_max_object_size_found == 0) { + priv->max_object_size = scconf_get_int(block, "piv_max_object_size", PIV_MAX_OBJECT_SIZE); + if (priv->max_object_size < PIV_MAX_OBJECT_SIZE || priv->max_object_size > MAX_FILE_SIZE) { + sc_log(card->ctx,"Invalid max_object_size:=\"%d\"", priv->max_object_size); + if (priv->max_object_size < PIV_MAX_OBJECT_SIZE) + priv->max_object_size = PIV_MAX_OBJECT_SIZE; + else + priv->max_object_size = MAX_FILE_SIZE; + } + sc_log(card->ctx,"piv_max_object_size: %d",priv->max_object_size); + } + } + free(found_blocks); + } + r = SC_SUCCESS; + return r; +} + +static int +piv_find_obj_by_containerid(sc_card_t *card, const u8 * str) +{ + int i; + + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "str=0x%02X%02X\n", str[0], str[1]); + + for (i = 0; piv_objects[i].enumtag < PIV_OBJ_LAST_ENUM; i++) { + if ( str[0] == piv_objects[i].containerid[0] && str[1] == piv_objects[i].containerid[1]) + LOG_FUNC_RETURN(card->ctx, i); + } + + LOG_FUNC_RETURN(card->ctx, -1); +} + +/* + * Send a command and receive data. There is always something to send. + * Used by GET DATA, PUT DATA, GENERAL AUTHENTICATE + * and GENERATE ASYMMETRIC KEY PAIR. + */ + +static int piv_general_io(sc_card_t *card, int ins, int p1, int p2, + const u8 * sendbuf, size_t sendbuflen, u8 *recvbuf, + size_t recvbuflen) +{ + int r; + sc_apdu_t apdu; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + r = sc_lock(card); + if (r != SC_SUCCESS) + LOG_FUNC_RETURN(card->ctx, r); + + sc_format_apdu(card, &apdu, + recvbuf ? SC_APDU_CASE_4_SHORT: SC_APDU_CASE_3_SHORT, + ins, p1, p2); + apdu.flags |= SC_APDU_FLAGS_CHAINING; +#ifdef ENABLE_PIV_SM + if (card->sm_ctx.sm_mode != SM_MODE_NONE && sendbuflen > 255) { + /* tell apdu.c to not do the chaining, let the SM get_apdu do it */ + apdu.flags |= SC_APDU_FLAGS_SM_CHAINING; + } +#endif + apdu.lc = sendbuflen; + apdu.datalen = sendbuflen; + apdu.data = sendbuf; + + if (recvbuf && recvbuflen) { + apdu.le = (recvbuflen > 256) ? 256 : recvbuflen; + apdu.resplen = recvbuflen; + } else { + apdu.le = 0; + apdu.resplen = 0; + } + apdu.resp = recvbuf; + + /* with new adpu.c and chaining, this actually reads the whole object */ + r = sc_transmit_apdu(card, &apdu); + + /* adpu will not have sw1,sw2 set because sc_sm_single_transmit called sc_sm_stop, */ + if (r < 0) { + sc_log(card->ctx, "Transmit failed"); + goto err; + } + + if (apdu.sw1 == 0x69 && apdu.sw2 == 0x88) + r = SC_ERROR_SM_INVALID_SESSION_KEY; + else + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + + if (r < 0) { + sc_log(card->ctx, "Card returned error "); + goto err; + } + + r = apdu.resplen; + +err: + sc_unlock(card); + LOG_FUNC_RETURN(card->ctx, r); +} + + +#ifdef ENABLE_PIV_SM +/* convert q as 04||x||y used in standard point formats to expanded leading + * zeros and concatenated X||Y as specified in SP80056A Appendix C.2 + * Field-Element-to-Byte-String Conversion which + * OpenSSL has already converted X and Y to big endian and skipped leading + * zero bytes. + */ +static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 * OS, size_t *OSlen) +{ + size_t i; + size_t f = fsize/8; + + i = (Qlen - 1)/2; + + if (!OS || *OSlen < f * 2 || !Q || i > f) + return SC_ERROR_INTERNAL; + + memset(OS, 0, f * 2); + /* Check this if x and y have leading zero bytes, + * In UNCOMPRESSED FORMAT, x and Y must be same length, to tell when + * one ends and the other starts */ + memcpy(OS + f - i, Q + 1, i); + memcpy(OS + 2 * f - i, Q + f + 1, i); + *OSlen = f * 2; + return 0; +} + +/* + * if needed, send VCI pairing code to card just after the + * SM key establishment. Called from piv_sm_open under same lock + */ +static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code) +{ + int r; + piv_private_data_t * priv = PIV_DATA(card); + sc_apdu_t plain; + sc_apdu_t sm_apdu; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); /* Not needed */ + + if ((priv->pin_policy & PIV_PP_VCI_IMPL) == 0) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); + + sc_format_apdu(card, &plain, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x98); + plain.datalen = plain.lc = 8; + plain.data = paring_code; + plain.resp = NULL; + plain.resplen = plain.le = 0; + + memset(&sm_apdu,0,sizeof(sm_apdu)); + /* build sm_apdu and set alloc sm_apdu.resp */ + r = piv_encode_apdu(card, &plain, &sm_apdu); + if (r < 0) { + free(sm_apdu.resp); + sc_log(card->ctx, "piv_encode_apdu failed"); + LOG_FUNC_RETURN(card->ctx, r); + } + + sm_apdu.flags += SC_APDU_FLAGS_NO_SM; /* run as is */ + r = sc_transmit_apdu(card, &sm_apdu); + if (r < 0) { + free(sm_apdu.resp); + sc_log(card->ctx, "transmit failed"); + LOG_FUNC_RETURN(card->ctx, r); + } + + r = piv_decode_apdu(card, &plain, &sm_apdu); + free(sm_apdu.resp); + LOG_TEST_RET(card->ctx, r, "piv_decode_apdu failed"); + + r = sc_check_sw(card, plain.sw1, plain.sw2); + if (r < 0) + r = SC_ERROR_PIN_CODE_INCORRECT; + + LOG_FUNC_RETURN(card->ctx, r); +} + +/* Verify one signature using pubkey */ +static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, + EVP_PKEY *pkey, + u8 *data, size_t data_size, + unsigned char *sig, size_t siglen) +{ + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; + int r = 0; + EVP_MD_CTX *md_ctx = NULL; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + if (cs == NULL) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if ((md_ctx = EVP_MD_CTX_new()) == NULL + || EVP_DigestVerifyInit(md_ctx, NULL, type, NULL, pkey) != 1 + || EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 + || EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) { + sc_log (card->ctx, "EVP_DigestVerifyFinal failed"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + r = SC_SUCCESS; +err: + EVP_MD_CTX_free(md_ctx); + LOG_FUNC_RETURN(card->ctx, r); +} + +/* + * If sm_in_cvc is present, verify PIV_OBJ_SM_CERT_SIGNER signed sm_in_cvc + * and sm_in_cvc signed sm_cvc. + * If sm_in_cvc is not present verify PIV_OBJ_SM_CERT_SIGNER signed sm_cvc. + */ + + +static int piv_sm_verify_certs(struct sc_card *card) +{ + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; + int r = 0; + const u8 *cert_blob = {0}; + size_t cert_bloblen = 0; + u8 *rbuf; /* do not free*/ + size_t rbuflen; + X509 *cert = NULL; + EVP_PKEY *cert_pkey = NULL; /* do not free */ + EVP_PKEY *in_cvc_pkey = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_GROUP *in_cvc_group = NULL; + EC_POINT *in_cvc_point = NULL; + EC_KEY *in_cvc_eckey = NULL; +#else + EVP_PKEY_CTX *in_cvc_pkey_ctx = NULL; + OSSL_PARAM params[3]; + size_t params_n; +#endif + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* TODO if already verified we could return + * may need to verify again, if card reset? + */ + + if (cs == NULL) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* + * Get the PIV_OBJ_SM_CERT_SIGNER and optional sm_in_cvc in cache + * both are in same object. Rbuf, and rbuflen are needed but not used here + * sm_cvc and sm_in_cvc both have EC_keys sm_in_cvc may have RSA sginature + */ + r = piv_get_cached_data(card, PIV_OBJ_SM_CERT_SIGNER, &rbuf, &rbuflen); + if (r < 0) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + r = piv_cache_internal_data(card,PIV_OBJ_SM_CERT_SIGNER); + if (r < 0) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + priv->sm_flags |= PIV_SM_FLAGS_SM_CERT_SIGNER_PRESENT; /* set for debugging */ + + /* get PIV_OBJ_SM_CERT_SIGNER cert DER from cache */ + cert_blob = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data; + cert_bloblen = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len; + + if (cert_blob == NULL || cert_bloblen == 0) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + if ((cert = d2i_X509(NULL, &cert_blob, cert_bloblen)) == NULL + || (cert_pkey = X509_get0_pubkey(cert)) == NULL) { + sc_log(card->ctx,"OpenSSL failed to get pubkey from SM_CERT_SIGNER"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* if intermediate sm_in_cvc present, cert signed it and sm_cvc is signed by sm_in_cvc */ + if (priv->sm_flags & PIV_SM_FLAGS_SM_IN_CVC_PRESENT) { + r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey, + priv->sm_in_cvc.body, priv->sm_in_cvc.bodylen, + priv->sm_in_cvc.signature,priv->sm_in_cvc.signaturelen); + if (r < 0) { + sc_log(card->ctx,"sm_in_cvc signature invalid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if ((in_cvc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL + || (in_cvc_pkey = EVP_PKEY_new()) == NULL + || (in_cvc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL + || (in_cvc_point = EC_POINT_new(in_cvc_group)) == NULL + || EC_POINT_oct2point(in_cvc_group, in_cvc_point, + priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 + || EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 + || EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) { + sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#else + params_n = 0; + params[params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0); + params[params_n++] = OSSL_PARAM_construct_octet_string("pub", + priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen); + params[params_n] = OSSL_PARAM_construct_end(); + + if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) + || !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) + || !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) + || !in_cvc_pkey) { + sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#endif + r = piv_sm_verify_sig(card, cs->kdf_md(), in_cvc_pkey, + priv->sm_cvc.body, priv->sm_cvc.bodylen, + priv->sm_cvc.signature,priv->sm_cvc.signaturelen); + + } else { /* cert signed sm_cvc */ + r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey, + priv->sm_cvc.body, priv->sm_cvc.bodylen, + priv->sm_cvc.signature,priv->sm_cvc.signaturelen); + } + if (r < 0) { + sc_log(card->ctx,"sm_cvc signature invalid"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* cert chain signatures match for oncard certs */ + /* TODO check dates and other info as per 800-73-4 */ + + /* TODO check against off card CA chain if present, + * Need opensc.conf options: + * where is CA cert chain? + * is it required? + * check for revocation? + * How often to check for revocation? + * When is SM used? + * Using NFC? + * (yes, main point of using SM) + * Should reading certificates be done in clear? + * (performance vs security) + * All crypto operations and PIN ? + * (yes for security) + */ +err: + X509_free(cert); +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_GROUP_free(in_cvc_group); + EC_POINT_free(in_cvc_point); + EC_KEY_free(in_cvc_eckey); +#else + EVP_PKEY_CTX_free(in_cvc_pkey_ctx); +#endif + EVP_PKEY_free(in_cvc_pkey); + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); +} + + +/* + * NIST SP800-73-4 4.1 The key Establishment Protocol + * Variable names and Steps are based on Client Application (h) + * and PIV Card Application (icc) + * Capital leters used for variable, and lower case for subscript names + */ +static int piv_sm_open(struct sc_card *card) +{ + piv_private_data_t * priv = PIV_DATA(card); + cipher_suite_t *cs = priv->cs; + int r = 0; + int rc = 0; + int i; + int reps; + u8 CBh; + u8 CBicc; + u8 *p; + + /* ephemeral EC key */ + EVP_PKEY_CTX *eph_ctx = NULL; + EVP_PKEY *eph_pkey = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *eph_eckey = NULL; /* don't free _get0_*/ + const EC_GROUP *eph_group = NULL; /* don't free _get0_ */ +#else + OSSL_PARAM eph_params[5]; + size_t eph_params_n; + size_t Qehxlen = 0; + u8 *Qehx = NULL; +#endif + size_t Qehlen = 0; + u8 Qeh[2 * PIV_SM_MAX_FIELD_LENGTH/8 + 1]; /* big enough for 384 04||x||y if x and y have leading zeros, length may be less */ + size_t Qeh_OSlen = 0; + u8 Qeh_OS[2 * PIV_SM_MAX_FIELD_LENGTH/8]; /* no leading 04, with leading zeros in X and Y */ + size_t Qsicc_OSlen = 0; + u8 Qsicc_OS[2 * PIV_SM_MAX_FIELD_LENGTH/8]; /* no leading 04, with leading zeros in X and Y */ + + /* pub EC key from card Cicc in sm_cvc */ + EVP_PKEY_CTX *Cicc_ctx = NULL; + EVP_PKEY *Cicc_pkey = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY *Cicc_eckey = NULL; + EC_POINT *Cicc_point = NULL; + EC_GROUP *Cicc_group = NULL; +#endif + + /* shared secret key Z */ + EVP_PKEY_CTX *Z_ctx = NULL; + u8 *Z = NULL; + size_t Zlen = 0; + + u8 IDsh[8] = {0}; + unsigned long pid; + + u8 *sbuf = NULL; + size_t sbuflen; + int len2a, len2b; + + u8 rbuf[4096]; + size_t rbuflen = sizeof(rbuf); + + const u8 *body, *payload; + size_t bodylen, payloadlen; + u8 Nicc[24]; /* nonce */ + u8 AuthCryptogram[16]; + + u8 *cvcder = NULL; + size_t cvclen = 0; + size_t len; /* temp len */ + + u8 *kdf_in = NULL; + size_t kdf_inlen = 0; + unsigned int hashlen = 0; + u8 aeskeys[SHA384_DIGEST_LENGTH * 3] = {0}; /* 4 keys, Hash function is run 2 or 3 times max is 3 * 384/8 see below */ + EVP_MD_CTX *hash_ctx = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX *cmac_ctx = NULL; +#else + EVP_MAC *mac = NULL; + EVP_MAC_CTX *cmac_ctx = NULL; + OSSL_PARAM cmac_params[2]; + size_t cmac_params_n = 0; + OSSL_PARAM Cicc_params[3]; + size_t Cicc_params_n = 0; +#endif + + u8 IDsicc[8]; /* will only use 8 bytes for step H6 */ + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* + * The SM routines try and call this on their own. + * This routine should only be called by the card driver. + * which has set PIV_SM_FLAGS_DEFER_OPEN and unset in + * in reader_lock_obtained + * after testing PIC applet is active so SM is setup in same transaction + * as the command we are trying to run with SM. + * this avoids situation where the SM is established, and then reset by + * some other application without getting anything done or in + * a loop, each trying to reestablish a SM session and run command. + */ + if (!(priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { + LOG_FUNC_RETURN(card->ctx,SC_ERROR_NOT_ALLOWED); + } + if (cs == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + sc_lock(card); + + /* use for several hash operations */ + if ((hash_ctx = EVP_MD_CTX_new()) == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + + /* Step 1 set CBh = 0 */ + CBh = 0; + + /* Step H2 generate ephemeral EC */ + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if ((eph_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL + || EVP_PKEY_keygen_init(eph_ctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(eph_ctx, cs->nid) <= 0 + || EVP_PKEY_keygen(eph_ctx, &eph_pkey) <= 0 + || (eph_eckey = EVP_PKEY_get0_EC_KEY(eph_pkey)) == NULL + || (eph_group = EC_KEY_get0_group(eph_eckey)) == NULL + || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), + POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 /* get length */ + || Qehlen > cs->Qlen + || (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey), + POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 + || Qehlen > cs->Qlen) { + sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#else + /* generate Qeh */ + eph_params_n = 0; + eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); + eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "point-format","uncompressed", 0); + eph_params[eph_params_n] = OSSL_PARAM_construct_end(); + if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) /* TODO should be FIPS */ + || !EVP_PKEY_keygen_init(eph_ctx) + || !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) + || !EVP_PKEY_generate(eph_ctx, &eph_pkey) + || !(Qehxlen = EVP_PKEY_get1_encoded_public_key(eph_pkey, &Qehx)) + || !Qehx + || Qehxlen > cs->Qlen + ) { + sc_log(card->ctx,"OpenSSL failed to create ephemeral EC key"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + memcpy(Qeh, Qehx, Qehxlen); + Qehlen = Qehxlen; +#endif + + /* For later use, get Qeh without 04 and full size X || Y */ + Qeh_OSlen = sizeof(Qeh_OS); + if (Q2OS(cs->field_length, Qeh, Qehlen, Qeh_OS, &Qeh_OSlen)) { + sc_log(card->ctx,"Q2OS for Qeh failed"); + r = SC_ERROR_INTERNAL; + goto err; + } + + r = len2a = sc_asn1_put_tag(0x81, NULL, 1 + cs->IDshlen + Qehlen, NULL, 0, NULL); + if (r < 0) + goto err; + r = len2b = sc_asn1_put_tag(0x80, NULL, 0, NULL, 0, NULL); + if (r < 0) + goto err; + r = sbuflen = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, NULL, 0, NULL); + if (r < 0) + goto err; + + sbuf = malloc(sbuflen); + if (sbuf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + p = sbuf; + + r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, sbuf, sbuflen, &p); + if (r != SC_SUCCESS) + goto err; + + r = sc_asn1_put_tag(0x81, NULL, 1 + cs->IDshlen + Qehlen, p, sbuflen - (p - sbuf), &p); + if (r != SC_SUCCESS) + goto err; + + /* Step H1 set CBh to 0x00 */ + *p++ = CBh; + +#ifdef WIN32 + pid = (unsigned long) GetCurrentProcessId(); +#else + pid = (unsigned long) getpid(); /* use PID as our ID so different from other processes */ +#endif + memcpy(IDsh, &pid, MIN(sizeof(pid), cs->IDshlen)); + memcpy(p, IDsh, cs->IDshlen); + p += cs->IDshlen; + memcpy(p, Qeh, Qehlen); + p += Qehlen; + + r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p); /* null data */ + if (r != SC_SUCCESS) + goto err; + + /* Step H3 send CBh||IDsh|| Qeh Qeh in 04||x||y */ + /* Or call sc_transmit directly */ + r = piv_general_io(card, 0x87, cs->p1, 0x04, sbuf, (p - sbuf), rbuf, rbuflen); + if (r <= 0) + goto err; + + rbuflen = r; + p = rbuf; + + body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7C, &bodylen); + if (body == NULL || bodylen < 20 || rbuf[0] != 0x7C) { + sc_log(card->ctx, "SM response data to short"); + r = SC_ERROR_SM_NO_SESSION_KEYS; + goto err; + } + + payload = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &payloadlen); + if (payload == NULL || payloadlen < 1 + cs->Nicclen + cs->AuthCryptogramlen || *body != 0x82) { + sc_log(card->ctx, "SM response data to short"); + r = SC_ERROR_SM_NO_SESSION_KEYS; + goto err; + } + + /* payload is CBicc (1) || Nicc (16 or 24) || AuthCryptogram (CMAC 16 or 16) ||Cicc (variable) */ + p = (u8 *) payload; + + /* Step H4 check CBicc == 0x00 */ + CBicc = *p++; + if (CBicc != 0x00) { /* CBicc must be zero */ + sc_log(card->ctx, "SM card did not accept request"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + memcpy(Nicc, p, cs->Nicclen); + p += cs->Nicclen; + + memcpy(AuthCryptogram, p, cs->AuthCryptogramlen); + p += cs->AuthCryptogramlen; + + if (p > payload + payloadlen) { + sc_log(card->ctx, "SM card CVC is to short"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + cvclen = len = payloadlen - (p - payload); + if (len) { + cvcder = p; /* in rbuf */ + + r = piv_decode_cvc(card, &p, &len, &priv->sm_cvc); + if (r != SC_SUCCESS) { + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + priv->sm_flags |= PIV_SM_FLAGS_SM_CVC_PRESENT; + } + + /* Step H5 Verify Cicc CVC and pubkey */ + /* Verify Cicc (sm_cvc) is signed by sm_in_cvc or PIV_OBJ_SM_CERT_SIGNER */ + /* sm_in_cvc is signed by PIV_OBJ_SM_CERT_SIGNER */ + + /* Verify the cert chain is valid. */ + r = piv_sm_verify_certs(card); + if (r < 0) { + sc_log(card->ctx, "SM piv_sm_verify_certs r:%d", r); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + /* Step H6 need left most 8 bytes of hash of sm_cvc */ + { + u8 hash[SHA256_DIGEST_LENGTH] = {0}; + const u8* tag; + size_t taglen; + const u8* tmpder; + size_t tmpderlen; + + if ((tag = sc_asn1_find_tag(card->ctx, cvcder, cvclen, 0x7F21, &taglen)) == NULL + || *cvcder != 0x7F || *(cvcder + 1) != 0x21) { + + r = SC_ERROR_INTERNAL; + goto err; + } + + /* debug choice */ + tmpder = cvcder; + tmpderlen = cvclen; + + if (EVP_DigestInit(hash_ctx,EVP_sha256()) != 1 + || EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 + || EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) { + sc_log(card->ctx,"IDsicc hash failed"); + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + goto err; + } + memcpy(IDsicc, hash, sizeof(IDsicc)); /* left 8 bytes */ + } + + /* Step H7 get the cards public key Qsicc into OpenSSL Cicc_eckey */ + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if ((Cicc_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL + || (Cicc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL + || (Cicc_pkey = EVP_PKEY_new()) == NULL + || (Cicc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL + || (Cicc_point = EC_POINT_new(Cicc_group)) == NULL + || EC_POINT_oct2point(Cicc_group, Cicc_point, + priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 + || EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 + || EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) { + sc_log(card->ctx,"OpenSSL failed to get card's EC pubkey"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#else + Cicc_params_n = 0; + Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); + Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_octet_string("pub", + priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen); + Cicc_params[Cicc_params_n] = OSSL_PARAM_construct_end(); + + if (!(Cicc_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) + || !EVP_PKEY_fromdata_init(Cicc_ctx) + || !EVP_PKEY_fromdata(Cicc_ctx, &Cicc_pkey, EVP_PKEY_PUBLIC_KEY, Cicc_params) + || !Cicc_pkey) { + sc_log(card->ctx, "OpenSSL failed to set EC pubkey for Cicc"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } +#endif + + /* Qsicc without 04 and expanded x||y */ + Qsicc_OSlen = sizeof(Qsicc_OS); + if (Q2OS(cs->field_length, priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, Qsicc_OS, &Qsicc_OSlen)) { + sc_log(card->ctx,"Q2OS for Qsicc failed"); + r = SC_ERROR_INTERNAL; + goto err; + } + + /* Step H8 Compute the shared secret Z */ + if ((Z_ctx = EVP_PKEY_CTX_new(eph_pkey, NULL)) == NULL + || EVP_PKEY_derive_init(Z_ctx) <= 0 + || EVP_PKEY_derive_set_peer(Z_ctx, Cicc_pkey) <= 0 + || EVP_PKEY_derive(Z_ctx, NULL, &Zlen) <= 0 + || Zlen != cs->Zlen + || (Z = malloc(Zlen)) == NULL + || EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 + || Zlen != cs->Zlen) { + sc_log(card->ctx,"OpenSSL failed to create secret Z"); + piv_log_openssl(card->ctx); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; + } + + sc_log(card->ctx, "debug Zlen:%"SC_FORMAT_LEN_SIZE_T"u Z[0]:0x%2.2x", Zlen, Z[0]); + + /* Step H9 zeroize deh from step H2 */ + EVP_PKEY_free(eph_pkey); /* OpenSSL BN_clear_free calls OPENSSL_cleanse */ + eph_pkey = NULL; + + /* Step H10 Create AES session Keys */ + /* kdf in is 4byte counter || Z || otherinfo 800-56A 5.8.1 */ + + kdf_inlen = 4 + Zlen + cs->otherinfolen; + kdf_in = malloc(kdf_inlen); + if (kdf_in == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + p = kdf_in; + *p++ = 0x00; + *p++ = 0x00; + *p++ = 0x00; + *p++ = 0x01; + memcpy(p, Z, cs->Zlen); + p += Zlen; + + /* otherinfo */ + *p++ = cs->o0len; + for (i = 0; i < cs->o0len; i++) + *p++ = cs->o0_char; /* 0x09 or 0x0d */ + + *p++ = cs->IDshlen; + memcpy(p, IDsh, cs->IDshlen); + p += cs->IDshlen; + + *p++ = cs->CBhlen; + memcpy(p, &CBh, cs->CBhlen); + p += cs->CBhlen; + + *p++ = cs->T16Qehlen; + /* First 16 bytes of Qeh without 04 800-56A Appendix C.2 */ + memcpy(p, Qeh_OS, cs->T16Qehlen); + p += cs->T16Qehlen; + + *p++ = cs->IDsicclen; + memcpy(p, IDsicc, cs->IDsicclen); + p += cs->IDsicclen; + + *p++ = cs->Nicclen; + memcpy(p, Nicc, cs->Nicclen); + p += cs->Nicclen; + + *p++ = cs->CBicclen; + memcpy(p, &CBicc, cs->CBicclen); + p += cs->CBicclen; + + if (p != kdf_in + kdf_inlen) { + r = SC_ERROR_INTERNAL; + goto err; + } + + /* 4 keys needs reps = ceil (naeskeys * aeskeylen) / kdf_hash_size) */ + /* 800-56A-2007, 5.8.1 Process and 800-56C rev 3 2018 4.1 Process. */ + /* so it is 2 times for 128 or 3 times for 256 bit AES keys */ + p = aeskeys; /* 4 keys + overflow */ + reps = (cs->naeskeys * cs->aeskeylen + cs->kdf_hash_size - 1) / (cs->kdf_hash_size); + + EVP_MD_CTX_reset(hash_ctx); + for (i = 0; i < reps; i++) { + if (EVP_DigestInit(hash_ctx,(*cs->kdf_md)()) != 1 + || EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 + || EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) { + sc_log(card->ctx,"KDF hash failed"); + r = SC_ERROR_INTERNAL; + goto err; + } + kdf_in[3]++; /* inc the counter */ + p += cs->kdf_hash_size; + } + + /* copy keys used for APDU */ + memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); /* clear */ + priv->sm_session.aes_size = cs->aeskeylen; + memcpy(&priv->sm_session.SKcfrm, &aeskeys[cs->aeskeylen * 0], cs->aeskeylen); + memcpy(&priv->sm_session.SKmac, &aeskeys[cs->aeskeylen * 1], cs->aeskeylen); + memcpy(&priv->sm_session.SKenc, &aeskeys[cs->aeskeylen * 2], cs->aeskeylen); + memcpy(&priv->sm_session.SKrmac, &aeskeys[cs->aeskeylen * 3], cs->aeskeylen); + sc_mem_clear(&aeskeys, sizeof(aeskeys)); + + priv->sm_session.enc_counter[15] = 0x01; + priv->sm_session.resp_enc_counter[0] = 0x80; + priv->sm_session.resp_enc_counter[15] = 0x01; + /* C_MCV is zero */ + /* R_MCV is zero */ + + /* Step H11 Zeroize Z (and kdf_in which has Z) */ + if (Z && Zlen) { + sc_mem_clear(Z, Zlen); + free(Z); + Z=NULL; + Zlen = 0; + } + if (kdf_in && kdf_inlen) { + sc_mem_clear(kdf_in, kdf_inlen); + free(kdf_in); + kdf_in = NULL; + kdf_inlen = 0; + } + + /* Step H12 check AuthCryptogramting our version */ + /* Generate CMAC */ + + { + u8 Check_AuthCryptogram[32]; + size_t Check_Alen = 0; + + u8 MacData[200]; + int MacDatalen; + memset(MacData, 0, sizeof(MacData)); + + p = MacData; + memcpy(p, "\x4B\x43\x5f\x31\x5f\x56", 6); + p += 6; + memcpy(p, IDsicc, cs->IDsicclen); + p += cs->IDsicclen; + memcpy(p, IDsh, cs->IDshlen); + p += cs->IDshlen; + + memcpy(p, Qeh_OS, Qeh_OSlen); + p += Qeh_OSlen; + MacDatalen = p - MacData; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + if ((cmac_ctx = CMAC_CTX_new()) == NULL + || CMAC_Init(cmac_ctx, priv->sm_session.SKcfrm, cs->aeskeylen, (*cs->cipher_cbc)(), NULL) != 1 + || CMAC_Update(cmac_ctx, MacData, MacDatalen) != 1 + || CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) { + r = SC_ERROR_INTERNAL; + sc_log(card->ctx,"AES_CMAC failed %d",r); + goto err; + } +#else + mac = EVP_MAC_fetch(NULL, "cmac", NULL); + cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); + + cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); + if (mac == NULL + || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL + || !EVP_MAC_init(cmac_ctx, priv->sm_session.SKcfrm, + priv->sm_session.aes_size, cmac_params) + || !EVP_MAC_update( cmac_ctx, MacData, MacDatalen) + || !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) { + piv_log_openssl(card->ctx); + r = SC_ERROR_INTERNAL; + sc_log(card->ctx,"AES_CMAC failed %d",r); + goto err; + } +#endif + + rc = memcmp(AuthCryptogram, Check_AuthCryptogram, cs->AuthCryptogramlen); + if (rc == 0) { + sc_log(card->ctx,"AuthCryptogram compare"); + r = 0; + } else { + sc_log(card->ctx,"AuthCryptogram compare failed"); + r = SC_ERROR_SM_AUTHENTICATION_FAILED; + } + } + + /* VCI only needed for contactless */ + if (priv->init_flags & PIV_INIT_CONTACTLESS) { + /* Is pairing code required? */ + if (!(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC)) { + r = piv_send_vci_pairing_code(card, priv->pairing_code); + if (r < 0) + goto err; + } + } + + r = 0; + priv->sm_flags |= PIV_SM_FLAGS_SM_IS_ACTIVE; + card->sm_ctx.sm_mode = SM_MODE_TRANSMIT; + +err: + priv->sm_flags &= ~PIV_SM_FLAGS_DEFER_OPEN; + if (r != 0) + memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); + piv_log_openssl(card->ctx); /* catch any not logged above */ + + sc_unlock(card); + + free(sbuf); + free(kdf_in); + free(Z); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_GROUP_free(Cicc_group); + EC_POINT_free(Cicc_point); + EC_KEY_free(Cicc_eckey); +#endif + + EVP_PKEY_free(eph_pkey); /* in case not cleared in step H9 */ + EVP_PKEY_CTX_free(eph_ctx); + EVP_PKEY_free(Cicc_pkey); + EVP_PKEY_CTX_free(Cicc_ctx); + EVP_PKEY_CTX_free(Z_ctx); + EVP_MD_CTX_free(hash_ctx); + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + CMAC_CTX_free(cmac_ctx); +#else + EVP_MAC_CTX_free(cmac_ctx); + EVP_MAC_free(mac); + OPENSSL_free(Qehx); +#endif + + LOG_FUNC_RETURN(card->ctx, r); +} +#endif /* ENABLE_PIV_SM */ + +/* Add the PIV-II operations */ +/* Should use our own keydata, actually should be common to all cards */ +/* RSA and EC are added. */ + +static int piv_generate_key(sc_card_t *card, + sc_cardctl_piv_genkey_info_t *keydata) +{ + int r; + u8 rbuf[4096]; + u8 *p; + const u8 *tag; + u8 tagbuf[16]; + u8 outdata[3]; /* we could also add tag 81 for exponent */ + size_t taglen; + size_t out_len; + size_t in_len; + unsigned int cla_out, tag_out; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + keydata->exponent = NULL; + keydata->exponent_len = 0; + keydata->pubkey = NULL; + keydata->pubkey_len = 0; + keydata->ecparam = NULL; /* will show size as we only support 2 curves */ + keydata->ecparam_len = 0; + keydata->ecpoint = NULL; + keydata->ecpoint_len = 0; + + out_len = 3; + outdata[0] = 0x80; + outdata[1] = 0x01; + outdata[2] = keydata->key_algid; + switch (keydata->key_algid) { + case 0x05: keydata->key_bits = 3072; break; + case 0x06: keydata->key_bits = 1024; break; + case 0x07: keydata->key_bits = 2048; break; + case 0x11: keydata->key_bits = 0; + keydata->ecparam = 0; /* we only support prime256v1 for 11 */ + keydata->ecparam_len =0; + break; + case 0x14: keydata->key_bits = 0; + keydata->ecparam = 0; /* we only support secp384r1 */ + keydata->ecparam_len = 0; + break; + default: + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + + p = tagbuf; + + r = sc_asn1_put_tag(0xAC, outdata, out_len, tagbuf, sizeof(tagbuf), &p); + if (r != SC_SUCCESS) { + sc_log(card->ctx, "Failed to encode ASN1 tag"); + goto err; + } + + r = piv_general_io(card, 0x47, 0x00, keydata->key_num, + tagbuf, p - tagbuf, rbuf, sizeof rbuf); + + if (r >= 0) { + const u8 *cp; + + cp = rbuf; + in_len = r; + + /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */ + r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len); + if (r < 0 || cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) { + r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; + } + if (r != SC_SUCCESS) { + sc_log(card->ctx, "Tag buffer not found"); + goto err; + } + + /* if RSA vs EC */ + if (keydata->key_bits > 0 ) { + tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen); + if (tag != NULL && taglen <= 4) { + keydata->exponent = malloc(taglen); + if (keydata->exponent == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + keydata->exponent_len = taglen; + memcpy (keydata->exponent, tag, taglen); + } + + tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x81, &taglen); + if (tag != NULL && taglen > 0) { + keydata->pubkey = malloc(taglen); + if (keydata->pubkey == NULL) { + free(keydata->exponent); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + keydata->pubkey_len = taglen; + memcpy (keydata->pubkey, tag, taglen); + } + } + else { /* must be EC */ + tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x86, &taglen); + if (tag != NULL && taglen > 0) { + keydata->ecpoint = malloc(taglen); + if (keydata->ecpoint == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + keydata->ecpoint_len = taglen; + memcpy (keydata->ecpoint, tag, taglen); + } + } + + /* TODO: -DEE Could add key to cache so could use engine to generate key, + * and sign req in single operation */ + r = 0; + } + +err: + LOG_FUNC_RETURN(card->ctx, r); +} static int piv_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, size_t *responselen) @@ -734,88 +2812,91 @@ static int piv_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, static int piv_find_aid(sc_card_t * card) { - sc_apdu_t apdu; + piv_private_data_t * priv = PIV_DATA(card); u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r,i; const u8 *tag; size_t taglen; + const u8 *nextac; const u8 *pix; size_t pixlen; + const u8 *actag; /* Cipher Suite */ + size_t actaglen; + const u8 *csai; /* Cipher Suite Algorithm Identifier */ + size_t csailen; size_t resplen = sizeof(rbuf); +#ifdef ENABLE_PIV_SM + int found_csai = 0; +#endif SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + /* first see if the default application will return a template * that we know about. */ r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen); + if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) { + LOG_FUNC_RETURN(card->ctx,SC_SUCCESS); + /* no need to parse again, same as last time */ + } if (r >= 0 && resplen > 2 ) { tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, 0x61, &taglen); if (tag != NULL) { + priv->init_flags |= PIV_INIT_AID_PARSED; + /* look for 800-73-4 0xAC for Cipher Suite Algorithm Identifier Table 14 */ + /* There may be more than one 0xAC tag, loop to find all */ + + nextac = tag; + while((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag), + 0xAC, &actaglen)) != NULL) { + nextac = actag + actaglen; + + csai = sc_asn1_find_tag(card->ctx, actag, actaglen, 0x80, &csailen); + if (csai != NULL) { + if (csailen == 1) { + sc_log(card->ctx,"found csID=0x%2.2x",*csai); +#ifdef ENABLE_PIV_SM + for (i = 0; i < PIV_CSS_SIZE; i++) { + if (*csai != css[i].id) + continue; + if (found_csai) { + sc_log(card->ctx,"found multiple csIDs, using first"); + } else { + priv->cs = &css[i]; + priv->csID = *csai; + found_csai++; + priv->init_flags |= PIV_INIT_AID_AC; + } + } +#endif /* ENABLE_PIV_SM */ + } + } + } + pix = sc_asn1_find_tag(card->ctx, tag, taglen, 0x4F, &pixlen); if (pix != NULL ) { sc_log(card->ctx, "found PIX"); /* early cards returned full AID, rather then just the pix */ for (i = 0; piv_aids[i].len_long != 0; i++) { - if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, - piv_aids[i].len_long - 5 ) == 0) - || ((pixlen >= piv_aids[i].len_short && - memcmp(pix, piv_aids[i].value, - piv_aids[i].len_short) == 0))) { - if (card->type > SC_CARD_TYPE_PIV_II_BASE && - card->type < SC_CARD_TYPE_PIV_II_BASE+1000 && - card->type == piv_aids[i].enumtag) { - LOG_FUNC_RETURN(card->ctx, i); - } else { - LOG_FUNC_RETURN(card->ctx, i); + if ((pixlen >= 6 && memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5 ) == 0) + || ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value, + piv_aids[i].len_short) == 0))) { + free(priv->aid_der.value); /* free previous value if any */ + if ((priv->aid_der.value = malloc(resplen)) == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); } + memcpy(priv->aid_der.value, rbuf, resplen); + priv->aid_der.len = resplen; + LOG_FUNC_RETURN(card->ctx,i); } } } } } - /* for testing, we can force the use of a specific AID - * by using the card= parameter in conf file - */ - for (i = 0; piv_aids[i].len_long != 0; i++) { - if (card->type > SC_CARD_TYPE_PIV_II_BASE && - card->type < SC_CARD_TYPE_PIV_II_BASE+1000 && - card->type != piv_aids[i].enumtag) { - continue; - } - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00); - apdu.lc = piv_aids[i].len_long; - apdu.data = piv_aids[i].value; - - apdu.datalen = apdu.lc; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; - - r = sc_transmit_apdu(card, &apdu); - LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) { - if (card->type != 0 && card->type == piv_aids[i].enumtag) - LOG_FUNC_RETURN(card->ctx, (r < 0)? r: i); - continue; - } - - if ( apdu.resplen == 0 && r == 0) { - /* could be the MSU card */ - continue; /* other cards will return a FCI */ - } - - if (apdu.resp[0] != 0x6f || apdu.resp[1] > apdu.resplen - 2 ) - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT); - - LOG_FUNC_RETURN(card->ctx, i); - } - LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT); } @@ -855,6 +2936,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, goto err; } body = tagbuf; + /* accept any tag for now, just get length */ r_tag = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen); if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) || body == NULL) { @@ -869,6 +2951,7 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, goto err; } memcpy(*buf, tagbuf, len); /* copy first or only part */ + /* read rest of file */ if (rbuflen > len + sizeof(tagbuf)) { len = read(f, *buf + sizeof(tagbuf), rbuflen - sizeof(tagbuf)); /* read rest */ if (len != rbuflen - sizeof(tagbuf)) { @@ -890,13 +2973,19 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename, static int piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) { + piv_private_data_t * priv = PIV_DATA(card); u8 *p; + u8 *tbuf; int r = 0; u8 tagbuf[8]; size_t tag_len; + int alloc_buf = 0; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, "#%d", enumtag); + + /* assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); */ + + sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name); r = sc_lock(card); /* do check len and get data in same transaction */ if (r != SC_SUCCESS) { @@ -904,8 +2993,6 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) return r; } - /* assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); */ - tag_len = piv_objects[enumtag].tag_len; p = tagbuf; @@ -915,31 +3002,9 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) goto err; } - if (*buf_len == 1 && *buf == NULL) { /* we need to get the length */ - u8 rbufinitbuf[8]; /* tag of 53 with 82 xx xx will fit in 4 */ - size_t bodylen; - unsigned int cla_out, tag_out; - const u8 *body; - - sc_log(card->ctx, "get len of #%d", enumtag); - r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, rbufinitbuf, sizeof rbufinitbuf); - if (r > 0) { - int r_tag; - body = rbufinitbuf; - r_tag = sc_asn1_read_tag(&body, r, &cla_out, &tag_out, &bodylen); - if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) - || body == NULL) { - sc_log(card->ctx, "r_tag:%d body:%p", r_tag, body); - r = SC_ERROR_FILE_NOT_FOUND; - goto err; - } - *buf_len = (body - rbufinitbuf) + bodylen; - } else if ( r == 0 ) { - r = SC_ERROR_FILE_NOT_FOUND; - goto err; - } else { - goto err; - } + if (*buf_len == 1 && *buf == NULL){ + *buf_len = priv->max_object_size; /* will allocate below */ + alloc_buf = 1; } sc_log(card->ctx, @@ -947,18 +3012,75 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) enumtag, *buf, *buf_len); if (*buf == NULL && *buf_len > 0) { if (*buf_len > MAX_FILE_SIZE) { + r = SC_ERROR_INTERNAL; goto err; } *buf = malloc(*buf_len); - if (*buf == NULL ) { + if (*buf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } } +#ifdef ENABLE_PIV_SM + /* + * Over contact reader, OK to read non sensitive object in clear even when SM is active + * but only if using default policy and we are not in reader_lock_obtained + * Discovery object will use SM from reader_lock_obtained to catch if SM is still valid + * i.e. no interference from other applications + */ + sc_log(card->ctx,"enumtag:%d sm_ctx.sm_mode:%d piv_objects[enumtag].flags:0x%8.8x sm_flags:0x%8.8lx it_flags:0x%8.8x", + enumtag, card->sm_ctx.sm_mode, piv_objects[enumtag].flags, priv->sm_flags, priv->init_flags); + if (priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE + && enumtag != PIV_OBJ_DISCOVERY + && card->sm_ctx.sm_mode == SM_MODE_TRANSMIT + && !(piv_objects[enumtag].flags & PIV_OBJECT_NEEDS_PIN) + && !(priv->sm_flags & (PIV_SM_FLAGS_NEVER | PIV_SM_FLAGS_ALWAYS)) + && !(priv->init_flags & ( PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) { + sc_log(card->ctx,"Set PIV_SM_GET_DATA_IN_CLEAR"); + priv->sm_flags |= PIV_SM_GET_DATA_IN_CLEAR; + } + +#endif /* ENABLE_PIV_SM */ r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, *buf, *buf_len); + if (r > 0) { + int r_tag; + unsigned int cla_out, tag_out; + size_t bodylen = 0; + const u8 *body = *buf; + r_tag = sc_asn1_read_tag(&body, r, &cla_out, &tag_out, &bodylen); + if (r_tag != SC_SUCCESS + || body == NULL + || !piv_is_expected_tag(cla_out, tag_out, piv_objects[enumtag].resp_tag)) { + sc_log(card->ctx, "invalid tag or length r_tag:%d body:%p", r_tag, body); + r = SC_ERROR_FILE_NOT_FOUND; + goto err; + } + *buf_len = (body - *buf) + bodylen; + } else if ( r == 0 ) { + r = SC_ERROR_FILE_NOT_FOUND; + goto err; + } else { + goto err; + } + + if (alloc_buf && *buf) { + tbuf = malloc(r); + if (tbuf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + memcpy(tbuf, *buf, r); + free (*buf); + alloc_buf = 0; + *buf = tbuf; + } err: + if (alloc_buf) { + free(*buf); + *buf = NULL; + } sc_unlock(card); LOG_FUNC_RETURN(card->ctx, r); } @@ -974,21 +3096,21 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) size_t rbuflen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - sc_log(card->ctx, "#%d", enumtag); assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); + sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name); + /* see if we have it cached */ if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_VALID) { sc_log(card->ctx, - "found #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", - enumtag, - priv->obj_cache[enumtag].obj_data, - priv->obj_cache[enumtag].obj_len, - priv->obj_cache[enumtag].internal_obj_data, - priv->obj_cache[enumtag].internal_obj_len); - + "found #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", + enumtag, + priv->obj_cache[enumtag].obj_data, + priv->obj_cache[enumtag].obj_len, + priv->obj_cache[enumtag].internal_obj_data, + priv->obj_cache[enumtag].internal_obj_len); if (priv->obj_cache[enumtag].obj_len == 0) { r = SC_ERROR_FILE_NOT_FOUND; @@ -1005,6 +3127,7 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) * If we know it can not be on the card i.e. History object * has been read, and we know what other certs may or * may not be on the card. We can avoid extra overhead + * Also used if object on card was not parsable */ if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_NOT_PRESENT) { @@ -1025,12 +3148,12 @@ piv_get_cached_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) *buf_len = r; sc_log(card->ctx, - "added #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", - enumtag, - priv->obj_cache[enumtag].obj_data, - priv->obj_cache[enumtag].obj_len, - priv->obj_cache[enumtag].internal_obj_data, - priv->obj_cache[enumtag].internal_obj_len); + "added #%d %p:%"SC_FORMAT_LEN_SIZE_T"u %p:%"SC_FORMAT_LEN_SIZE_T"u", + enumtag, + priv->obj_cache[enumtag].obj_data, + priv->obj_cache[enumtag].obj_len, + priv->obj_cache[enumtag].internal_obj_data, + priv->obj_cache[enumtag].internal_obj_len); } else { free(rbuf); @@ -1058,15 +3181,20 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) size_t taglen; size_t bodylen; int compressed = 0; + int r = SC_SUCCESS; +#ifdef ENABLE_PIV_SM + u8* cvc_start = NULL; + size_t cvc_len = 0; +#endif /* if already cached */ if (priv->obj_cache[enumtag].internal_obj_data && priv->obj_cache[enumtag].internal_obj_len) { sc_log(card->ctx, - "#%d found internal %p:%"SC_FORMAT_LEN_SIZE_T"u", - enumtag, - priv->obj_cache[enumtag].internal_obj_data, - priv->obj_cache[enumtag].internal_obj_len); - LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + "#%d found internal %p:%"SC_FORMAT_LEN_SIZE_T"u", + enumtag, + priv->obj_cache[enumtag].internal_obj_data, + priv->obj_cache[enumtag].internal_obj_len); + LOG_FUNC_RETURN(card->ctx, r); } body = sc_asn1_find_tag(card->ctx, @@ -1086,6 +3214,10 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) if (tag && taglen > 0 && (((*tag) & 0x80) || ((*tag) & 0x01))) compressed = 1; +#ifdef ENABLE_PIV_SM + cvc_start = (u8 *)tag + taglen; /* save for later as cvs (if present) follows 0x71 */ +#endif + tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x70, &taglen); if (tag == NULL) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); @@ -1103,8 +3235,29 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen); priv->obj_cache[enumtag].internal_obj_len = taglen; +#ifdef ENABLE_PIV_SM + /* PIV_OBJ_SM_CERT_SIGNER CERT OBJECT may also have a intermediate CVC */ + if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_CVC) { + /* cvc if present should be at cvc_start. + * find the tag(T) and get value(V) and len(L) from TLV. + * Could reconstruct ASN1 of (T)(L) stating location from length and known tag. + * as the size of (L) depends on the length of value + */ + if ((tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x7F21, &taglen)) != NULL + && cvc_start && cvc_start < tag + && cvc_start[0] == 0x7f && cvc_start[1] == 0x21) { + cvc_len = tag - cvc_start + taglen; + /* decode the intermediate CVC */ + r = piv_decode_cvc(card, &cvc_start, &cvc_len, &priv->sm_in_cvc); + if (r < 0) { + sc_log(card->ctx,"unable to parse intermediate CVC: %d skipping",r); + } + priv->sm_flags |= PIV_SM_FLAGS_SM_IN_CVC_PRESENT; + } + } +#endif /* ENABLE_PIV_SM */ + /* convert pub key to internal */ -/* TODO: -DEE need to fix ... would only be used if we cache the pub key, but we don't today */ } else if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) { tag = sc_asn1_find_tag(card->ctx, body, bodylen, *body, &taglen); @@ -1151,7 +3304,7 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (priv->selected_obj < 0) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); enumtag = piv_objects[priv->selected_obj].enumtag; if (priv->rwb_state == -1) { @@ -1164,6 +3317,9 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co r = SC_ERROR_FILE_NOT_FOUND; goto err; } + + /* TODO Biometric Information Templates Group Template uses tag 7f61 */ + body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, rbuf[0], &bodylen); if (body == NULL) { /* if missing, assume its the body */ @@ -1174,8 +3330,8 @@ piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t co } if (bodylen > body - rbuf + rbuflen) { sc_log(card->ctx, - " ***** tag length > then data: %"SC_FORMAT_LEN_SIZE_T"u>%"SC_FORMAT_LEN_PTRDIFF_T"u+%"SC_FORMAT_LEN_SIZE_T"u", - bodylen, body - rbuf, rbuflen); + " ***** tag length > then data: %"SC_FORMAT_LEN_SIZE_T"u>%"SC_FORMAT_LEN_PTRDIFF_T"u+%"SC_FORMAT_LEN_SIZE_T"u", + bodylen, body - rbuf, rbuflen); r = SC_ERROR_INVALID_DATA; goto err; } @@ -1273,8 +3429,8 @@ piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned lon size_t taglen; if ((tmplen = sc_asn1_put_tag(0x70, buf, count, NULL, 0, NULL)) <= 0 || - (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 || - (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) { + (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 || + (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } @@ -1350,17 +3506,7 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, /* if cached, remove old entry */ if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_VALID) { - priv->obj_cache[enumtag].flags = 0; - if (priv->obj_cache[enumtag].obj_data) { - free(priv->obj_cache[enumtag].obj_data); - priv->obj_cache[enumtag].obj_data = NULL; - priv->obj_cache[enumtag].obj_len = 0; - } - if (priv->obj_cache[enumtag].internal_obj_data) { - free(priv->obj_cache[enumtag].internal_obj_data); - priv->obj_cache[enumtag].internal_obj_data = NULL; - priv->obj_cache[enumtag].internal_obj_len = 0; - } + piv_obj_cache_free_entry(card, enumtag, 0); } if (idx != 0) @@ -1532,9 +3678,9 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l tkey = malloc(expected_keylen); if (!tkey) { - sc_log(card->ctx, " Unable to allocate key memory"); - r = SC_ERROR_OUT_OF_MEMORY; - goto err; + sc_log(card->ctx, " Unable to allocate key memory"); + r = SC_ERROR_OUT_OF_MEMORY; + goto err; } if (fsize == expected_keylen) { /* it must be binary */ @@ -1622,6 +3768,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, cipher = get_cipher_for_algo(card, alg_id); if(!cipher) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); + piv_log_openssl(card->ctx); r = SC_ERROR_INVALID_ARGUMENTS; goto err; } @@ -1662,7 +3809,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Get the witness data indicated by the TAG 0x80 */ witness_data = sc_asn1_find_tag(card->ctx, body, body_len, 0x80, &witness_len); - if (!witness_len) { + if (!witness_len || body_len == 0 || body[0] != 0x80) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data none found in TLV\n"); r = SC_ERROR_INVALID_DATA; goto err; @@ -1679,6 +3826,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* decrypt the data from the card */ if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { /* may fail if des parity of key is wrong. depends on OpenSSL options */ + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1686,6 +3834,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, p = plain_text; if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, witness_len)) { + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1693,6 +3842,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, p += tmplen; if(!EVP_DecryptFinal(ctx, p, &N)) { + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1825,6 +3975,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, EVP_CIPHER_CTX_reset(ctx); if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1832,6 +3983,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, tmp = decrypted_reponse; if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, challenge_response_len)) { + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1839,6 +3991,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, tmp += tmplen; if(!EVP_DecryptFinal(ctx, tmp, &N)) { + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1847,8 +4000,8 @@ static int piv_general_mutual_authenticate(sc_card_t *card, if (decrypted_reponse_len != nonce_len || memcmp(nonce, decrypted_reponse, nonce_len) != 0) { sc_log(card->ctx, - "mutual authentication failed, card returned wrong value %"SC_FORMAT_LEN_SIZE_T"u:%"SC_FORMAT_LEN_SIZE_T"u", - decrypted_reponse_len, nonce_len); + "mutual authentication failed, card returned wrong value %"SC_FORMAT_LEN_SIZE_T"u:%"SC_FORMAT_LEN_SIZE_T"u", + decrypted_reponse_len, nonce_len); r = SC_ERROR_DECRYPT_FAILED; goto err; } @@ -1909,8 +4062,8 @@ static int piv_general_external_authenticate(sc_card_t *card, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; + r = SC_ERROR_OUT_OF_MEMORY; + goto err; } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id); @@ -1973,12 +4126,12 @@ static int piv_general_external_authenticate(sc_card_t *card, } /* Store this to sanity check that plaintext length and ciphertext lengths match */ - /* TODO is this required */ tmplen = challenge_len; /* Encrypt the challenge with the secret */ if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt fail\n"); + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -1993,6 +4146,7 @@ static int piv_general_external_authenticate(sc_card_t *card, EVP_CIPHER_CTX_set_padding(ctx,0); if (!EVP_EncryptUpdate(ctx, cypher_text, &outlen, challenge_data, challenge_len)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n"); + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -2000,6 +4154,7 @@ static int piv_general_external_authenticate(sc_card_t *card, if (!EVP_EncryptFinal(ctx, cypher_text + cypher_text_len, &outlen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Final fail\n"); + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -2011,6 +4166,7 @@ static int piv_general_external_authenticate(sc_card_t *card, */ if (cypher_text_len != (size_t)tmplen) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Length test fail\n"); + piv_log_openssl(card->ctx); r = SC_ERROR_INTERNAL; goto err; } @@ -2091,6 +4247,9 @@ static int piv_general_external_authenticate(sc_card_t *card, } +/* + * with sp800-73-4 and SM GUID is also in sm_cvc.subjectID + */ static int piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) { @@ -2133,13 +4292,13 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) } } sc_log(card->ctx, - "fascn=%p,fascnlen=%"SC_FORMAT_LEN_SIZE_T"u,guid=%p,guidlen=%"SC_FORMAT_LEN_SIZE_T"u,gbits=%2.2x", - fascn, fascnlen, guid, guidlen, gbits); + "fascn=%p,fascnlen=%"SC_FORMAT_LEN_SIZE_T"u,guid=%p,guidlen=%"SC_FORMAT_LEN_SIZE_T"u,gbits=%2.2x", + fascn, fascnlen, guid, guidlen, gbits); if (fascn && fascnlen == 25) { /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */ if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 - && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { + && fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) { /* fascnlen is 25 */ serial->len = fascnlen; memcpy (serial->value, fascn, serial->len); @@ -2247,7 +4406,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) const u8 *p; size_t out_len = 0; int r; - unsigned int tag, cla; + unsigned int tag_out, cla_out; piv_private_data_t * priv = PIV_DATA(card); LOG_FUNC_CALLED(card->ctx); @@ -2275,13 +4434,13 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len) LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed"); p = rbuf; - r = sc_asn1_read_tag(&p, r, &cla, &tag, &out_len); - if (r < 0 || (cla|tag) != 0x7C) { + r = sc_asn1_read_tag(&p, r, &cla_out, &tag_out, &out_len); + if (r < 0 || (cla_out|tag_out) != 0x7C) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template"); } - r = sc_asn1_read_tag(&p, out_len, &cla, &tag, &out_len); - if (r < 0 || (cla|tag) != 0x81) { + r = sc_asn1_read_tag(&p, out_len, &cla_out, &tag_out, &out_len); + if (r < 0 || (cla_out|tag_out) != 0x81) { LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge"); } @@ -2306,9 +4465,9 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_log(card->ctx, - "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u", - env->flags, env->operation, env->algorithm, env->algorithm_flags, - env->algorithm_ref, env->key_ref[0], env->key_ref_len); + "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u", + env->flags, env->operation, env->algorithm, env->algorithm_flags, + env->algorithm_ref, env->key_ref[0], env->key_ref_len); priv->operation = env->operation; priv->algorithm = env->algorithm; @@ -2332,7 +4491,7 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) } else r = SC_ERROR_NO_CARD_SUPPORT; } else - r = SC_ERROR_NO_CARD_SUPPORT; + r = SC_ERROR_NO_CARD_SUPPORT; priv->key_ref = env->key_ref[0]; LOG_FUNC_RETURN(card->ctx, r); @@ -2446,7 +4605,6 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 rbuf[128]; /* For EC conversions 384 will fit */ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* The PIV returns a DER SEQUENCE{INTEGER, INTEGER} * Which may have leading 00 to force a positive integer * But PKCS11 just wants 2* field_length in bytes @@ -2458,8 +4616,8 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, nLen = (priv->key_size + 7) / 8; if (outlen < 2*nLen) { sc_log(card->ctx, - " output too small for EC signature %"SC_FORMAT_LEN_SIZE_T"u < %"SC_FORMAT_LEN_SIZE_T"u", - outlen, 2 * nLen); + " output too small for EC signature %"SC_FORMAT_LEN_SIZE_T"u < %"SC_FORMAT_LEN_SIZE_T"u", + outlen, 2 * nLen); r = SC_ERROR_INVALID_DATA; goto err; } @@ -2596,10 +4754,12 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a size_t pinplen; unsigned int cla_out, tag_out; - if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS + || body == NULL + || bodylen == 0 + || ((cla_out|tag_out) != 0x7E)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -2608,27 +4768,30 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a sc_log(card->ctx, "Discovery 0x%2.2x 0x%2.2x %p:%"SC_FORMAT_LEN_SIZE_T"u", cla_out, tag_out, body, bodylen); - if ( cla_out+tag_out == 0x7E && body != NULL && bodylen != 0) { - aidlen = 0; - aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen); - if (aid == NULL || aidlen < piv_aids[0].len_short || - memcmp(aid,piv_aids[0].value,piv_aids[0].len_short) != 0) { /*TODO look at long */ - sc_log(card->ctx, "Discovery object not PIV"); - r = SC_ERROR_INVALID_CARD; /* This is an error */ - goto err; - } - if (aid_only == 0) { - pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen); - if (pinp && pinplen == 2) { - sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); - r = SC_SUCCESS; - if ((*pinp & 0x60) == 0x60 && *(pinp+1) == 0x20) { /* use Global pin */ - sc_log(card->ctx, "Pin Preference - Global"); - priv->pin_preference = 0x00; - } + aidlen = 0; + aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen); + if (aid == NULL || aidlen < piv_aids[0].len_short || + memcmp(aid,piv_aids[0].value,piv_aids[0].len_short) != 0) { + sc_log(card->ctx, "Discovery object not PIV"); + r = SC_ERROR_INVALID_CARD; /* This is an error */ + goto err; + } + if (aid_only == 0) { + pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen); + if (pinp && pinplen == 2) { + priv->init_flags |= PIV_INIT_DISCOVERY_PP; + priv->pin_policy = (*pinp << 8) + *(pinp + 1); + sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1)); + if ((priv->pin_policy & (PIV_PP_PIN | PIV_PP_GLOBAL)) + == (PIV_PP_PIN | PIV_PP_GLOBAL) + && priv->pin_policy & PIV_PP_GLOBAL_PRIMARY) { + sc_log(card->ctx, "Pin Preference - Global"); + priv->pin_preference = 0x00; } } } + r = SC_SUCCESS; + priv->init_flags |= PIV_INIT_DISCOVERY_PARSED; } err: @@ -2660,7 +4823,7 @@ static int piv_process_discovery(sc_card_t *card) * We read the CCC using the PIV API. * Look for CAC RID=A0 00 00 00 79 */ - static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) +static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen) { int r = 0; const u8 * body; @@ -2682,7 +4845,10 @@ static int piv_process_discovery(sc_card_t *card) /* Outer layer is a DER tlv */ body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS + || body == NULL + || bodylen == 0 + || !piv_is_expected_tag(cla_out, tag_out, piv_objects[PIV_OBJ_CCC].resp_tag)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -2742,30 +4908,46 @@ static int piv_process_ccc(sc_card_t *card) static int piv_find_discovery(sc_card_t *card) { int r = 0; - u8 rbuf[256]; - size_t rbuflen = sizeof(rbuf); - u8 * arbuf = rbuf; + size_t rbuflen; + u8 * rbuf = NULL; piv_private_data_t * priv = PIV_DATA(card); SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* - * During piv_match or piv_card_reader_lock_obtained, + * During piv_card_reader_lock_obtained, * we use the discovery object to test if card present, and - * if PIV AID is active. So we can not use the cache + * if PIV AID is active. */ + if (priv->obj_cache[PIV_OBJ_DISCOVERY].flags & PIV_OBJ_CACHE_NOT_PRESENT) { + r = SC_ERROR_DATA_OBJECT_NOT_FOUND; + goto end; + } - /* If not valid, read, cache and test */ + /* If not valid: read, test, cache */ if (!(priv->obj_cache[PIV_OBJ_DISCOVERY].flags & PIV_OBJ_CACHE_VALID)) { r = piv_process_discovery(card); } else { /* if already in cache,force read */ - r = piv_get_data(card, PIV_OBJ_DISCOVERY, &arbuf, &rbuflen); - if (r >= 0) - /* make sure it is PIV AID */ - r = piv_parse_discovery(card, rbuf, rbuflen, 1); + rbuflen = 1; + r = piv_get_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen); + /* if same response as last, no need to parse */ + if ( r == 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == 0) + goto end; + + if (r >= 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == rbuflen + && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data + && !memcmp(rbuf, priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data, rbuflen)) { + goto end; + } + /* This should not happen bad card */ + sc_log(card->ctx,"Discovery not the same as previously read object"); + r = SC_ERROR_CORRUPTED_DATA; + goto end; } +end: + free(rbuf); LOG_FUNC_RETURN(card->ctx, r); } @@ -2821,18 +5003,19 @@ piv_process_history(sc_card_t *card) /* the object is now cached, see what we have */ if (rbuflen != 0) { body = rbuf; - if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) { + if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS + || !piv_is_expected_tag(cla_out, tag_out, piv_objects[PIV_OBJ_HISTORY].resp_tag)) { sc_log(card->ctx, "DER problem %d",r); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } - if ( cla_out+tag_out == 0x53 && body != NULL && bodylen != 0) { + if (body != NULL && bodylen != 0) { numlen = 0; num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC1, &numlen); if (num) { if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20-PIV_OBJ_RETIRED_X509_1+1) { - r = SC_ERROR_INTERNAL; /* TODO some other error */ + r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -2843,7 +5026,7 @@ piv_process_history(sc_card_t *card) num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC2, &numlen); if (num) { if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20-PIV_OBJ_RETIRED_X509_1+1) { - r = SC_ERROR_INTERNAL; /* TODO some other error */ + r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -2860,6 +5043,7 @@ piv_process_history(sc_card_t *card) } else { sc_log(card->ctx, "Problem with History object\n"); + r = SC_SUCCESS; /* OK if not found */ goto err; } } @@ -2921,9 +5105,10 @@ piv_process_history(sc_card_t *card) */ body = ocfhfbuf; - if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, - &tag_out, &bodylen) != SC_SUCCESS - || cla_out+tag_out != 0x30) { + if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS + || body == NULL + || bodylen == 0 + || (cla_out|tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -2931,9 +5116,10 @@ piv_process_history(sc_card_t *card) seq = body; while (bodylen > 0) { seqtag = seq; - if (sc_asn1_read_tag(&seq, bodylen, &cla_out, - &tag_out, &seqlen) != SC_SUCCESS - || cla_out+tag_out != 0x30) { + if (sc_asn1_read_tag(&seq, bodylen, &cla_out, &tag_out, &seqlen) != SC_SUCCESS + || seq == 0 + || seqlen == 0 + || (cla_out|tag_out) != 0x30) { sc_log(card->ctx, "DER problem"); r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; @@ -2954,13 +5140,13 @@ piv_process_history(sc_card_t *card) if ((tmplen = sc_asn1_put_tag(0x70, NULL, certlen, NULL, 0, NULL)) <= 0 || (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 || (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) { - r = SC_ERROR_INTERNAL; + r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } i2 = tmplen + tmplen2 + tmplen3; tmplen = sc_asn1_put_tag(0x53, NULL, i2, NULL, 0, NULL); if (tmplen <= 0) { - r = SC_ERROR_INTERNAL; + r = SC_ERROR_INVALID_ASN1_OBJECT; goto err; } @@ -3008,6 +5194,24 @@ piv_process_history(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } +static int +piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags) +{ + piv_private_data_t * priv = PIV_DATA(card); + + if (priv->obj_cache[enumtag].obj_data) + free(priv->obj_cache[enumtag].obj_data); + priv->obj_cache[enumtag].obj_data = NULL; + priv->obj_cache[enumtag].obj_len = 0; + + if (priv->obj_cache[enumtag].internal_obj_data) + free(priv->obj_cache[enumtag].internal_obj_data); + priv->obj_cache[enumtag].internal_obj_data = NULL; + priv->obj_cache[enumtag].internal_obj_len = 0; + priv->obj_cache[enumtag].flags = flags; + +return SC_SUCCESS; +} static int piv_finish(sc_card_t *card) @@ -3022,16 +5226,20 @@ piv_finish(sc_card_t *card) priv->context_specific = 0; sc_unlock(card); } + free(priv->aid_der.value); if (priv->w_buf) free(priv->w_buf); if (priv->offCardCertURL) free(priv->offCardCertURL); for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++) { - if (priv->obj_cache[i].obj_data) - free(priv->obj_cache[i].obj_data); - if (priv->obj_cache[i].internal_obj_data) - free(priv->obj_cache[i].internal_obj_data); + piv_obj_cache_free_entry(card, i, 0); } +#ifdef ENABLE_PIV_SM + piv_clear_cvc_content(&priv->sm_cvc); + piv_clear_cvc_content(&priv->sm_in_cvc); + piv_clear_sm_session(&priv->sm_session); +#endif /* ENABLE_PIV_SM */ + free(priv); card->drv_data = NULL; /* priv */ } @@ -3044,7 +5252,7 @@ static int piv_match_card(sc_card_t *card) sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type); /* piv_match_card may be called with card->type, set by opensc.conf */ - /* user provide card type must be one we know */ + /* user provided card type must be one we know */ switch (card->type) { case -1: case SC_CARD_TYPE_PIV_II_GENERIC: @@ -3059,40 +5267,50 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: case SC_CARD_TYPE_PIV_II_SWISSBIT: + case SC_CARD_TYPE_PIV_II_800_73_4: break; default: + /* User can not set SC_CARD_TYPE_PIV_II_BASE */ return 0; /* can not handle the card */ } + /* its one we know, or we can test for it in piv_init */ - /* - * We will call piv_match_card_continued here then - * again in piv_init to avoid any issues with passing - * anything from piv_match_card - * to piv_init as had been done in the past - */ r = piv_match_card_continued(card); - if (r == 1) { + if (r < 0 || !card->drv_data) { /* clean up what we left in card */ sc_unlock(card); piv_finish(card); + return 0; /* match failed */ } sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type,r); - return r; + return 1; /* matched */ } static int piv_match_card_continued(sc_card_t *card) { - int i, r = 0; + int i, r = 0, r2 = 0; int type = -1; piv_private_data_t *priv = NULL; int saved_type = card->type; + sc_apdu_t apdu; + u8 yubico_version_buf[3] = {0}; + + r = sc_lock(card); /* hold until match or init is complete */ + if (r != SC_SUCCESS) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "sc_lock failed\n"); + piv_finish(card); + card->type = saved_type; + LOG_FUNC_RETURN(card->ctx, r); + } /* piv_match_card may be called with card->type, set by opensc.conf */ - /* user provide card type must be one we know */ + /* User provided card type must be one we know */ + switch (card->type) { case -1: + case SC_CARD_TYPE_PIV_II_BASE: case SC_CARD_TYPE_PIV_II_GENERIC: case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: @@ -3105,16 +5323,16 @@ static int piv_match_card_continued(sc_card_t *card) case SC_CARD_TYPE_PIV_II_OBERTHUR: case SC_CARD_TYPE_PIV_II_PIVKEY: case SC_CARD_TYPE_PIV_II_SWISSBIT: + case SC_CARD_TYPE_PIV_II_800_73_4: type = card->type; break; default: - return 0; /* can not handle the card */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD); } sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); if (type == -1) { - /* - *try to identify card by ATR or historical data in ATR + * Try to identify card by ATR or historical data in ATR * currently all PIV card will respond to piv_find_aid * the same. But in future may need to know card type first, * so do it here. @@ -3129,6 +5347,11 @@ static int piv_match_card_continued(sc_card_t *card) !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) { type = SC_CARD_TYPE_PIV_II_NEO; } + else if (card->reader->atr_info.hist_bytes_len >= 6 && + !(memcmp(card->reader->atr_info.hist_bytes, "PIVKEY", 6))) { + type = SC_CARD_TYPE_PIV_II_PIVKEY; + } + /* look for TLV historic data */ else if (card->reader->atr_info.hist_bytes_len > 0 && card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */ size_t datalen; @@ -3167,195 +5390,78 @@ static int piv_match_card_continued(sc_card_t *card) /* use known ATRs */ i = _sc_match_atr(card, piv_atrs, &type); if (i < 0) - type = SC_CARD_TYPE_PIV_II_GENERIC; /* may still be CAC with PIV Endpoint */ + type = SC_CARD_TYPE_PIV_II_BASE; /* May be some newer unknown card including CAC or PIV-like card */ + } } + card->type = type; + + /* we either found via ATR historic bytes or ATR directly */ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r); - /* allocate and init basic fields */ + /* allocate and init basic fields */ priv = calloc(1, sizeof(piv_private_data_t)); if (!priv) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - if (card->type == -1) - card->type = type; - card->drv_data = priv; /* will free if no match, or pass on to piv_init */ + priv->max_object_size = PIV_MAX_OBJECT_SIZE; /* may be reset later */ priv->selected_obj = -1; priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */ /* TODO Dual CAC/PIV are bases on 800-73-1 where priv->pin_preference = 0. need to check later */ priv->logged_in = SC_PIN_STATE_UNKNOWN; priv->pstate = PIV_STATE_MATCH; - /* Some objects will only be present if History object says so */ - for (i=0; i < PIV_OBJ_LAST_ENUM -1; i++) - if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) - priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; +#ifdef ENABLE_PIV_SM + memset(&card->sm_ctx, 0, sizeof card->sm_ctx); + card->sm_ctx.ops.open = piv_sm_open; + card->sm_ctx.ops.get_sm_apdu = piv_get_sm_apdu; + card->sm_ctx.ops.free_sm_apdu = piv_free_sm_apdu; + card->sm_ctx.ops.close = piv_sm_close; +#endif /* ENABLE_PIV_SM */ - r = sc_lock(card); - if (r != SC_SUCCESS) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "sc_lock failed\n"); - piv_finish(card); - card->type = saved_type; - return 0; + /* see if contactless */ + if (card->reader->atr.len >= 4 + && card->reader->atr.value[0] == 0x3b + && (card->reader->atr.value[1] & 0xF0) == 0x80 + && card->reader->atr.value[2] == 0x80 + && card->reader->atr.value[3] == 0x01) { + priv->init_flags |= PIV_INIT_CONTACTLESS; } + for (i=0; i < PIV_OBJ_LAST_ENUM -1; i++) + if(piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT) + priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT; /* * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card * and PIV must be the default application. * Try to avoid doing a select_aid and losing the login state on some cards. * We may get interference on some cards by other drivers trying SELECT_AID before - * we get to see if PIV application is still active - * putting PIV driver first might help. - * This may fail if the wrong AID is active. - * Discovery Object introduced in 800-73-3 so will return 0 if found and PIV applet active. + * we get to see if PIV application is still active. Putting PIV driver first might help. + * + * Discovery Object introduced in 800-73-3 so will return OK if found and PIV applet active. * Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object. * But some other card could also return SC_ERROR_FILE_NOT_FOUND. - * Will fail for other reasons if wrong applet is selected, or bad PIV implementation. + * Will fail for other reasons if wrong applet is selected or bad PIV implementation. */ - - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); - if (priv->card_issues & CI_DISCOVERY_USELESS) /* TODO may be in wrong place */ - i = -1; - else - i = piv_find_discovery(card); - - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); - if (i < 0) { - /* Detect by selecting applet */ - i = piv_find_aid(card); - } - - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); - if (i >= 0) { - int iccc = 0; - /* We now know PIV AID is active, test CCC object 800-73-* say CCC is required */ - switch (card->type) { - /* - * For cards that may also be CAC, try and read the CCC - * CCC is required and all Dual PIV/CAC will have a CCC - * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History - */ - case SC_CARD_TYPE_PIV_II_GENERIC: /* i.e. really dont know what this is */ - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_GI_DE: - case SC_CARD_TYPE_PIV_II_GEMALTO: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - case SC_CARD_TYPE_PIV_II_SWISSBIT: - iccc = piv_process_ccc(card); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d iccc:%d ccc_flags:%08x CI:%08x r:%d\n", - card->type, iccc, priv->ccc_flags, priv->card_issues, r); - /* ignore an error? */ - /* if CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ - if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { - switch (card->type) { - case SC_CARD_TYPE_PIV_II_GENERIC: - case SC_CARD_TYPE_PIV_II_HIST: - case SC_CARD_TYPE_PIV_II_GI_DE: - card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO: - card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR: - card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC; - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - } - } - break; - - /* if user forced it to be one of the CAC types, assume it is CAC */ - case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: - case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - break; - } - } - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); - if (i >= 0 && (priv->card_issues & CI_DISCOVERY_USELESS) == 0) { - /* - * We now know PIV AID is active, test DISCOVERY object again - * Some PIV don't support DISCOVERY and return - * SC_ERROR_INCORRECT_PARAMETERS. Any error - * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery - * to test for active AID. - */ - int i7e = piv_find_discovery(card); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i7e:%d CI:%08x r:%d\n", card->type, i7e, priv->card_issues, r); - if (i7e < 0) { - priv->card_issues |= CI_DISCOVERY_USELESS; - priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; - } - } + /* first test if PIV is active applet without using AID If fails use the AID */ - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); - if (i < 0) { - /* don't match. Does not have a PIV applet. */ - sc_unlock(card); - piv_finish(card); - card->type = saved_type; - return 0; + r = piv_find_discovery(card); + if (r < 0) { + piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache on failure */ + r = piv_find_aid(card); } - - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r); - /* Matched, caller will use or free priv and sc_lock as needed */ - priv->pstate=PIV_STATE_INIT; - return 1; /* match */ -} - - -static int piv_init(sc_card_t *card) -{ - int r = 0; - piv_private_data_t * priv = NULL; - sc_apdu_t apdu; - unsigned long flags; - unsigned long ext_flags; - u8 yubico_version_buf[3]; - - SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - - /* continue the matching get a lock and the priv */ - r = piv_match_card_continued(card); - if (r != 1) { - sc_log(card->ctx,"piv_match_card_continued failed card->type:%d", card->type); - piv_finish(card); - /* tell sc_connect_card to try other drivers */ - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + + /*if both fail, its not a PIV card */ + if (r < 0) { + goto err; } - - priv = PIV_DATA(card); - - /* can not force the PIV driver to use non-PIV cards as tested in piv_card_match_continued */ - if (!priv || card->type == -1) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); - sc_log(card->ctx, - "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type = %d", - card->max_send_size, card->max_recv_size, card->type); - card->cla = 0x00; - if(card->name == NULL) - card->name = card->driver->name; - - /* - * Set card_issues based on card type either set by piv_match_card or by opensc.conf - */ - - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); - switch(card->type) { + /* TODO Move up as discovery is useless Get Yubico version. Assumes all Yubikey cards are identified via ATR Historic bytes */ + switch (card->type) { case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00); @@ -3365,11 +5471,85 @@ static int piv_init(sc_card_t *card) apdu.resp = yubico_version_buf; apdu.resplen = sizeof(yubico_version_buf); apdu.le = apdu.resplen; - r = sc_transmit_apdu(card, &apdu); - priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; - sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); + r2 = sc_transmit_apdu(card, &apdu); /* on error yubico_version == 0 */ + if (r2 >= 3) { + priv->yubico_version = (yubico_version_buf[0]<<16) | (yubico_version_buf[1] <<8) | yubico_version_buf[2]; + sc_log(card->ctx, "Yubico card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version); + } + } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + + /* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */ + /* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */ + switch (card->type) { + /* + * For cards that may also be CAC, try and read the CCC + * CCC is required and all Dual PIV/CAC will have a CCC + * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History + */ + case SC_CARD_TYPE_PIV_II_BASE: /* i.e. really dont know what this is */ + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + case SC_CARD_TYPE_PIV_II_GEMALTO: + case SC_CARD_TYPE_PIV_II_OBERTHUR: + r2 = piv_process_ccc(card); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d ccc_flags:%08x CI:%08x r:%d\n", + card->type, r2, priv->ccc_flags, priv->card_issues, r); + /* Ignore any error. */ + /* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */ + if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) { + switch (card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_GENERIC: + case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_GI_DE: + card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_GEMALTO: + card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + case SC_CARD_TYPE_PIV_II_OBERTHUR: + card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC; + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; + break; + } + } + break; + + case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC: + case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC: + priv->card_issues |= CI_DISCOVERY_USELESS; + priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT; break; } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + + /* AID also says if SM is supported or not */ + if (!(priv->init_flags & PIV_INIT_AID_PARSED)) { + switch(card->type) { + case SC_CARD_TYPE_PIV_II_BASE: + case SC_CARD_TYPE_PIV_II_800_73_4: + r2 = piv_find_aid(card); + if (priv->init_flags & PIV_INIT_AID_AC) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } + } + } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + +#ifdef ENABLE_PIV_SM + /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */ + if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } +#endif /* * Set card_issues flags based card->type and version numbers if available. @@ -3412,7 +5592,9 @@ static int piv_init(sc_card_t *card) priv->card_issues |= 0; /* could add others here */ break; + case SC_CARD_TYPE_PIV_II_BASE: case SC_CARD_TYPE_PIV_II_HIST: + case SC_CARD_TYPE_PIV_II_800_73_4: priv->card_issues |= 0; /* could add others here */ break; @@ -3426,11 +5608,9 @@ static int piv_init(sc_card_t *card) /* TODO may need more research */ break; - case SC_CARD_TYPE_PIV_II_GENERIC: priv->card_issues |= CI_VERIFY_LC0_FAIL | CI_OTHER_AID_LOSE_STATE; - /* TODO may need more research */ break; case SC_CARD_TYPE_PIV_II_PIVKEY: @@ -3450,8 +5630,71 @@ static int piv_init(sc_card_t *card) card->type = SC_CARD_TYPE_PIV_II_GENERIC; } sc_log(card->ctx, "PIV card-type=%d card_issues=0x%08x", card->type, priv->card_issues); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r); + if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED) ) { + /* + * We now know PIV AID is active, test DISCOVERY object again + * Some PIV don't support DISCOVERY and return + * SC_ERROR_INCORRECT_PARAMETERS. Any error + * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery + * to test for active AID. + */ + r2 = piv_find_discovery(card); + + if (r2 < 0) { + priv->card_issues |= CI_DISCOVERY_USELESS; + piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY,PIV_OBJ_CACHE_NOT_PRESENT); + } + } + + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + /* Matched, caller will use or free priv and sc_lock as needed */ + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + +err: + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); + /* don't match. Does not have a PIV applet. */ + sc_unlock(card); + piv_finish(card); + card->type = saved_type; + LOG_FUNC_RETURN(card->ctx, r); +} + + +static int piv_init(sc_card_t *card) +{ + int r = 0; + piv_private_data_t * priv = PIV_DATA(card); + unsigned long flags; + unsigned long ext_flags; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* piv_match_card_continued called from card match should have left card->drv_data */ + if (priv == NULL) { + r = piv_match_card_continued(card); + priv = PIV_DATA(card); + if (r < 0 || !priv) { + sc_log(card->ctx,"piv_match_card_continued failed card->type:%d", card->type); + sc_unlock(card); + piv_finish(card); + /* tell sc_connect_card to try other driver */ + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); + } + } + + /* read "card_driver PIV-II" opensc.conf options, and env parameters */ + piv_load_options(card); + + priv->pstate=PIV_STATE_INIT; + + sc_log(card->ctx, + "Max send = %"SC_FORMAT_LEN_SIZE_T"u recv = %"SC_FORMAT_LEN_SIZE_T"u card->type = %d", + card->max_send_size, card->max_recv_size, card->type); + card->cla = 0x00; + if (card->name == NULL) + card->name = card->driver->name; priv->enumtag = piv_aids[0].enumtag; @@ -3488,19 +5731,67 @@ static int piv_init(sc_card_t *card) card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; /* - * 800-73-3 cards may have a history object and/or a discovery object - * We want to process them now as this has information on what - * keys and certs the card has and how the pin might be used. - * If they fail, ignore it there are optional and introduced in - * NIST 800-73-3 and NIST 800-73-2 so some older cards may - * not handle the request. + * 800-73-3 cards may have discovery. "piv-like cards may or may not. + * 800-73-4 with VCI must have it as it has the pin policy needed for VCI . */ - piv_process_history(card); - piv_process_discovery(card); +#ifdef ENABLE_PIV_SM + /* + * 800-73-4 + * Response of AID says if SM is supported. Look for Cipher Suite + */ + if (priv->csID && priv->cs != NULL) { + /* + * TODO look closer at reset of card by other process + * Main point in SM and VCI is to allow contactless access + */ + /* Only piv_init and piv_reader_lock_obtained should call piv_sm_open */ + + /* If user said PIV_SM_FLAGS_NEVER, dont start SM; implies limited contatless access */ + if (priv->sm_flags & PIV_SM_FLAGS_NEVER) { + sc_log(card->ctx,"User has requested PIV_SM_FLAGS_NEVER"); + r = SC_SUCCESS; /* Users choice */ + + } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) + && !(priv->pin_policy & PIV_PP_VCI_IMPL)) { + sc_log(card->ctx,"Contactless and no card support for VCI"); + r = SC_SUCCESS; /* User should know VCI is not possible with their card; use like 800-73-3 contactless */ + + } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) + && !(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) + && (priv->pairing_code[0] == 0x00)) { + sc_log(card->ctx,"Contactless, pairing_code required and no pairing code"); + r = SC_ERROR_PIN_CODE_INCORRECT; /* User should know they need to set pairing code */ + + } else { + priv->sm_flags |= PIV_SM_FLAGS_DEFER_OPEN; /* tell priv_sm_open, OK to open */ + r = piv_sm_open(card); + sc_log(card->ctx,"piv_sm_open returned:%d", r); + } + + /* If failed, and user said PIV_SM_FLAGS_ALWAYS quit */ + if (priv->sm_flags & PIV_SM_FLAGS_ALWAYS && r < 0) { + sc_log(card->ctx,"User has requested PIV_SM_FLAGS_ALWAYS, SM has failed to start, don't use the card"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); + } + + /* user has wrong or no required pairing code */ + if (r == SC_ERROR_PIN_CODE_INCORRECT) + LOG_FUNC_RETURN(card->ctx, r); + + /* If SM did not start, or is not expected to start, continue on without it */ + } +#endif /* ENABLE_PIV_SM */ + + /* + * 800-73-3 cards may have a history object + * We want to process it now as this has information on what + * keys and certs. "piv like" cards may or may not have history + */ + piv_process_history(card); priv->pstate=PIV_STATE_NORMAL; - sc_unlock(card) ; /* obtained in piv_match */ + sc_unlock(card) ; /* obtained in piv_match_card_continued */ LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } @@ -3510,17 +5801,25 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); int r; +#ifdef ENABLE_PIV_SM + int i; +#endif piv_private_data_t * priv = PIV_DATA(card); - /* may be called before piv_init has allocated priv */ + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + + /* may be called before piv_init has allocated priv */ if (priv) { /* need to save sw1 and sw2 if trying to determine card_state from pin_cmd */ + if (priv->pin_cmd_verify) { priv->pin_cmd_verify_sw1 = sw1; priv->pin_cmd_verify_sw2 = sw2; } else { - /* a command has completed and it is not verify */ - /* If we are in a context_specific sequence, unlock */ + /* a command has completed and it is not verify + * If we are in a context_specific sequence, unlock + * This just decrements the extra lock count + */ if (priv->context_specific) { sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC lock"); priv->context_specific = 0; @@ -3544,6 +5843,18 @@ static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2 } } } +#ifdef ENABLE_PIV_SM + /* Note 6982 is map to SC_ERROR_SM_NO_SESSION_KEYS but iso maps it to SC_ERROR_SECURITY_STATUS_NOT_SATISFIED */ + /* we do this because 6982 could also mean a verify is not allowed over contactless without VCI */ + /* we stashed the sw1 and sw2 above for verify */ + /* Check specific NIST sp800-73-4 SM errors */ + for (i = 0; piv_sm_errors[i].SWs != 0; i++) { + if (piv_sm_errors[i].SWs == ((sw1 << 8) | sw2)) { + sc_log(card->ctx, "%s", piv_sm_errors[i].errorstr); + return piv_sm_errors[i].errorno; + } + } +#endif r = iso_drv->ops->check_sw(card, sw1, sw2); return r; } @@ -3696,6 +6007,14 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) r = iso_drv->ops->pin_cmd(card, data, tries_left); priv->pin_cmd_verify = 0; + /* tell user verify not supported on contactless without VCI */ + if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 + && priv->init_flags & PIV_INIT_CONTACTLESS + && card->type == SC_CARD_TYPE_PIV_II_800_73_4) { + /* TODO maybe true for other contactless cards */ + r = SC_ERROR_NOT_SUPPORTED; + } + /* if verify failed, release the lock */ if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) { sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC"); @@ -3772,7 +6091,6 @@ static int piv_logout(sc_card_t *card) LOG_FUNC_RETURN(card->ctx, r); } - /* * Called when a sc_lock gets a reader lock and PCSC SCardBeginTransaction * If SCardBeginTransaction may pass back that a card reset was seen since @@ -3784,10 +6102,19 @@ static int piv_logout(sc_card_t *card) * this is very similar to what the piv_match routine does, */ +/* TODO card.c also calls piv_sm_open before this if a reset was done, but + * does not say if a reset was done or not. May need to ignore the call + * the piv_sm_open in this case, but how? may need a open is active flag, + * in case it is the APDU done from open caused triggered the case. + */ + /* TODO may be called recursively to handle reset. + * need we are active, and if called again with was_reset save this + * and return to let first call handle the reset + */ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) { int r = 0; - u8 temp[256]; + u8 temp[SC_MAX_APDU_BUFFER_SIZE]; size_t templen = sizeof(temp); piv_private_data_t * priv = PIV_DATA(card); /* may be null */ @@ -3801,6 +6128,8 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) goto err; } + priv->init_flags |= PIV_INIT_IN_READER_LOCK_OBTAINED; + /* make sure our application is active */ /* first see if AID is active AID by reading discovery object '7E' */ @@ -3808,16 +6137,30 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) /* but if card does not support DISCOVERY object we can not use it */ if (priv->card_issues & CI_DISCOVERY_USELESS) { - r = SC_ERROR_NO_CARD_SUPPORT; + r = SC_ERROR_NO_CARD_SUPPORT; } else { - r = piv_find_discovery(card); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_find_discovery card->type:%d r:%d\n", card->type, r); + r = piv_find_discovery(card); +#ifdef ENABLE_PIV_SM + /* + * All 800-73-4 cards that support SM, also have a discovery object with + * the pin_policy, so can not have CI_DISCOVERY_USELESS + * Discovery object can be read with contact or contactless + * If read with SM and fails with 69 88 SC_ERROR_SM_INVALID_SESSION_KEY + * sm.c will close the SM connectrion, and set defer + * TODO may be with reset? + */ + if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) { + sc_log(card->ctx,"SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN"); + piv_sm_open(card); + r = piv_find_discovery(card); + } +#endif /* ENABLE_PIV_SM */ } if (r < 0) { if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) { r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen); - sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_select_aid card->type:%d r:%d\n", card->type, r); + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "piv_select_aid card->type:%d r:%d\n", card->type, r); } else { r = 0; /* can't do anything with this card, hope there was no interference */ } @@ -3832,6 +6175,8 @@ static int piv_card_reader_lock_obtained(sc_card_t *card, int was_reset) r = 0; err: + if (priv) + priv->init_flags &= ~PIV_INIT_IN_READER_LOCK_OBTAINED; LOG_FUNC_RETURN(card->ctx, r); } @@ -3863,11 +6208,8 @@ static struct sc_card_driver * sc_get_driver(void) return &piv_drv; } - -#if 1 struct sc_card_driver * sc_get_piv_driver(void) { return sc_get_driver(); } -#endif diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 250b4331d0..b4e0243f2d 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -138,6 +138,7 @@ enum { SC_CARD_TYPE_PIV_II_OBERTHUR, SC_CARD_TYPE_PIV_II_PIVKEY, SC_CARD_TYPE_PIV_II_SWISSBIT, + SC_CARD_TYPE_PIV_II_800_73_4, /* MuscleApplet */ SC_CARD_TYPE_MUSCLE_BASE = 15000, diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 266136335d..06135c23cb 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -4,6 +4,7 @@ * * Copyright (C) 2005,2006,2007,2008,2009,2010 * Douglas E. Engert + * Copyright (C) 2020 Douglas E. Engert * 2004, Nils Larsch * Copyright (C) 2006, Identity Alliance, * Thomas Harning @@ -236,8 +237,8 @@ static int piv_detect_card(sc_pkcs15_card_t *p15card) sc_card_t *card = p15card->card; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - if (card->type < SC_CARD_TYPE_PIV_II_GENERIC - || card->type >= SC_CARD_TYPE_PIV_II_GENERIC+1000) + if (card->type < SC_CARD_TYPE_PIV_II_BASE + || card->type >= SC_CARD_TYPE_PIV_II_BASE + 1000) return SC_ERROR_INVALID_CARD; return SC_SUCCESS; } @@ -320,21 +321,30 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) "2.16.840.1.101.3.7.2.16.19", NULL, "1013", 0}, {"34", "Retired X.509 Certificate for Key Management 20", "2.16.840.1.101.3.7.2.16.20", NULL, "1014", 0}, + /* new in 800-73-4 */ + {"35", "Biometric Information Templates Group Template", + "2.16.840.1.101.3.7.2.16.22", NULL, "1016", 0}, + {"36", "Secure Messaging Certificate Signer", + "2.16.840.1.101.3.7.2.16.23", NULL, "1017", 0}, + {"37", "Pairing Code Reference Data Container", + "2.16.840.1.101.3.7.2.16.24", NULL, "1018", SC_PKCS15_CO_FLAG_PRIVATE}, {NULL, NULL, NULL, NULL, NULL, 0} }; // clang-format on - /* - * NIST 800-73-1 lifted the restriction on + /* NIST 800-73-1 lifted the restriction on * requiring pin protected certs. Thus the default is to * not require this. + * + * Certs will be pulled out from the cert objects + * But there may be extra certs (SM Signer cert) that do + * not have a private keys on the card. These certs must be last */ - /* certs will be pulled out from the cert objects */ - /* the number of cert, pubkey and prkey triplets */ -#define PIV_NUM_CERTS_AND_KEYS 24 +#define PIV_NUM_CERTS 25 +#define PIV_NUM_KEYS 24 // clang-format off - static const cdata certs[PIV_NUM_CERTS_AND_KEYS] = { + static const cdata certs[PIV_NUM_CERTS] = { {"01", "Certificate for PIV Authentication", "0101cece", 0, 0}, {"02", "Certificate for Digital Signature", "0100cece", 0, 0}, {"03", "Certificate for Key Management", "0102cece", 0, 0}, @@ -358,7 +368,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) {"21", "Retired Certificate for Key Management 17", "1011cece", 0, 0}, {"22", "Retired Certificate for Key Management 18", "1012cece", 0, 0}, {"23", "Retired Certificate for Key Management 19", "1013cece", 0, 0}, - {"24", "Retired Certificate for Key Management 20", "1014cece", 0, 0} + {"24", "Retired Certificate for Key Management 20", "1014cece", 0, 0}, + {"25", "Secure Messaging Certificate Signer", "1017cece", 0, 0} /* no keys on card */ }; // clang-format on @@ -395,7 +406,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) * RSA and EC have different sets of usage */ // clang-format off - static const pubdata pubkeys[PIV_NUM_CERTS_AND_KEYS] = { + static const pubdata pubkeys[PIV_NUM_KEYS] = { { "01", "PIV AUTH pubkey", /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP | @@ -505,11 +516,14 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) // clang-format on /* - * note some of the SC_PKCS15_PRKEY values are dependent + * Note some of the SC_PKCS15_PRKEY values are dependent * on the key algorithm, and will be reset. + + * No SM Signer private Key on card + * The 04 SM ECC CVC pubkey is in response to SELECT AID */ // clang-format off - static const prdata prkeys[PIV_NUM_CERTS_AND_KEYS] = { + static const prdata prkeys[PIV_NUM_KEYS] = { { "01", "PIV AUTH key", /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP | @@ -614,6 +628,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP, /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE, "", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0} + /* SM Signer certificate does not have private key on card */ }; // clang-format on @@ -621,7 +636,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) sc_card_t *card = p15card->card; sc_serial_number_t serial; char buf[SC_MAX_SERIALNR * 2 + 1]; - common_key_info ckis[PIV_NUM_CERTS_AND_KEYS]; + common_key_info ckis[PIV_NUM_CERTS]; int follows_nist_fascn = 0; char *token_name = NULL; @@ -685,6 +700,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); + if (r < 0) LOG_FUNC_RETURN(card->ctx, r); /* TODO @@ -716,7 +732,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) */ /* set certs */ sc_log(card->ctx, "PIV-II adding certs..."); - for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { + for (i = 0; i < PIV_NUM_CERTS; i++) { struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; sc_pkcs15_der_t cert_der; @@ -991,7 +1007,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) * at a later time. The piv-tool can stash pubkey in file */ sc_log(card->ctx, "PIV-II adding pub keys..."); - for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { + for (i = 0; i < PIV_NUM_KEYS; i++) { struct sc_pkcs15_pubkey_info pubkey_info; struct sc_pkcs15_object pubkey_obj; struct sc_pkcs15_pubkey *p15_key = NULL; @@ -1141,7 +1157,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) /* set private keys */ sc_log(card->ctx, "PIV-II adding private keys..."); - for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { + for (i = 0; i < PIV_NUM_KEYS; i++) { struct sc_pkcs15_prkey_info prkey_info; struct sc_pkcs15_object prkey_obj; @@ -1218,7 +1234,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); err: - for (i = 0; i < PIV_NUM_CERTS_AND_KEYS; i++) { + for (i = 0; i < PIV_NUM_CERTS; i++) { sc_pkcs15_free_pubkey(ckis[i].pubkey_from_cert); } sc_pkcs15_card_clear(p15card); diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 6f7494ca2d..7eea3fa826 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -311,7 +311,7 @@ typedef struct sc_file { #define SC_APDU_FLAGS_NO_RETRY_WL 0x00000004UL /* APDU is from Secure Messaging */ #define SC_APDU_FLAGS_NO_SM 0x00000008UL -/* let SM do the comand haining */ +/* let SM do the command chaining */ #define SC_APDU_FLAGS_SM_CHAINING 0x00000010UL #define SC_APDU_ALLOCATE_FLAG 0x01 From e227f68d3c6a6e1cae1b16114ea96525a6c692ea Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Mon, 30 Jan 2023 16:24:40 -0600 Subject: [PATCH 3084/4321] card-piv.c various improvments Update PIV conf and env in opensc.conf.5.xml.in Improved card match and testing for SM cards Allow force of SC_CARD_TYPE_PIV_II_BASE, which will test for all posible type of cards tested including 800-74-4 supported features. Tested with ID-One with SM, Older NIST beta cards: Gemalto and Oberthur, YubiKey: 4 and 5 NFC and PIVKey C910. Allow testing PIV SM with or without github.com/OpenSC/OpenSC/pull/2712 Clear CVC contents if CVC fails to encode In responses to https://github.com/OpenSC/OpenSC/pull/2053#discussion_r1102504801 For example, if the CVC can not be parsed, clear it by calling piv_clear_cvc_content Add PIV SM functions prototypes as static PIV Use piv_free_sm_apdu to cleanup if piv_encode_apdu fails This is in response to: https://github.com/OpenSC/OpenSC/pull/2053#discussion_r1102512477 and https://github.com/OpenSC/OpenSC/pull/2053#discussion_r1102516064 PIV Improve testing of AuthCryptogram This is in response to: https://github.com/OpenSC/OpenSC/pull/2053#discussion_r1102625542 PIV goto err if AuthCryptogram check fails PIV Add check for plain->resp == NULL Handle case where apdu resp == NULL and resplen > 0 which would be a programming error. card-piv.c With SM and no data returned set plain->resplen=0 Fixes https://github.com/OpenSC/OpenSC/pull/2053#issuecomment-1501913641 PIV fix checking of padding Fixes: https://github.com/OpenSC/OpenSC/pull/2053#discussion_r1202793082 PIV SM - Unzip SM Certificate Signer Certificate With SM, the Cert Signer certificate may be ziped. card-piv.c needs to extract the public key before pkcs15 emulation is setup. Call sc_decompress_alloc. Changes to be committed: modified: doc/files/opensc.conf.5.xml.in modified: src/libopensc/card-piv.c --- doc/files/opensc.conf.5.xml.in | 59 +++++++++++++++++ src/libopensc/card-piv.c | 116 +++++++++++++++++++++++++-------- 2 files changed, 147 insertions(+), 28 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 0fa0735089..987d84e459 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -800,6 +800,53 @@ app application { + + Configuration Options for PIV Card + + + + + + + Max size of a PIV object. The default of 16384 bytes should + work for most cards. It might be overwritten by + PIV_MAX_OBJECT_SIZE environment variable. + + + + + + + Use optional secure messaging as define by NIST SP 800-73-4 + name is one of: + + always + - Use secure messaging for commands. + + never + - Used for debugging. Card may still require use of secure messaging. + + + Ignored if card does not support secure messaging. + Default is use secure messaging as required by card issuer + policies which are different for contact and contactless. + It might be overwritten by PIV_USE_SM + environment variable. + + + + + + + Ignored if card does not support piv_pairing_code. + Card issuer may require a pairing code be used especially over contactless + reader. Not normally used in conf file because pairing code is card specific. + Use PIV_PAIRING_CODE environment variable. + + + + + Configuration based on ATR @@ -1779,6 +1826,18 @@ app application { piv-tool. + + + PIV_MAX_OBJECT, + PIV_USE_SM, + PIV_PAIRING_CODE + + + PIV configuration during initialization + See Configuration Options for PIV Card. + + + diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index ae0dcfaa4c..9fd8946802 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -61,6 +61,7 @@ #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) && !defined(OPENSSL_NO_EC) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L #define ENABLE_PIV_SM #include +#include "compression.h" #endif #include "internal.h" @@ -182,6 +183,13 @@ enum { #define PIV_CS_CS7 0x2E #ifdef ENABLE_PIV_SM +/* TODO temp to test with or without LIBCTX PR */ +#ifdef USE_OPENSSL3_LIBCTX +#define PIV_LIBCTX card->ctx->ossl3ctx->libctx +#else +#define PIV_LIBCTX NULL +#endif + /* Table 14 and other constants */ typedef struct cipher_suite { u8 id; /* taken from AID "AC" tag */ @@ -853,6 +861,26 @@ static int piv_is_expected_tag(unsigned int cla, unsigned int tag, unsigned int } #ifdef ENABLE_PIV_SM +static void piv_inc(u8 *counter, size_t size); +static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu); +static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu); +static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu); +static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth); +static int piv_sm_open(struct sc_card *card); +static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu); +static int piv_sm_close(sc_card_t *card); +static void piv_clear_cvc_content(piv_cvc_t *cvc); +static void piv_clear_sm_session(piv_sm_session_t *session); +static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, piv_cvc_t *cvc); +static int piv_parse_pairing_code(sc_card_t *card, const char *option); +static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 * OS, size_t *OSlen); +static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code); +static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type, + EVP_PKEY *pkey, u8 *data, size_t data_size, + unsigned char *sig, size_t siglen); +static int piv_sm_verify_certs(struct sc_card *card); + + static void piv_inc(u8 *counter, size_t size) { unsigned int c = 1; @@ -915,7 +943,7 @@ static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } #else - mac = EVP_MAC_fetch(NULL, "cmac", NULL); + mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL); cmac_params_n = 0; cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); @@ -1142,9 +1170,7 @@ static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apd r = piv_encode_apdu(card, plain, *sm_apdu); if (r < 0 && *sm_apdu) { - free((*sm_apdu)->resp); - free(*sm_apdu); - *sm_apdu = NULL; + piv_free_sm_apdu(card, NULL, sm_apdu); } LOG_FUNC_RETURN(card->ctx, r); @@ -1224,6 +1250,11 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } + /* if no data returned clear plain resplen */ + if (!(asn1_sm_response[0].flags & SC_ASN1_PRESENT)) { + plain->resplen = 0; + } + if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 || (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) { sc_log(card->ctx,"SM missing status or R-MAC"); @@ -1247,7 +1278,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu goto err; } #else - mac = EVP_MAC_fetch(NULL, "cmac", NULL); + mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL); cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { @@ -1309,7 +1340,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu p = ee.value; inlen = ee.len; if (inlen < 17 || *p != 0x01) { /*padding indicator is required */ - sc_log(card->ctx, "SM padding indicatior not 0x01"); + sc_log(card->ctx, "SM padding indicator not 0x01"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } @@ -1330,7 +1361,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu */ inlen -= 16; - if (plain->resplen < (unsigned) inlen) { + if (plain->resplen < (unsigned) inlen || plain->resp == NULL) { sc_log(card->ctx, "SM response will not fit in resp,resplen"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; @@ -1354,7 +1385,7 @@ static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu } /* unpad last block and get bytes in last block */ - for (i = 15; i >= 0 ; i--) { + for (i = 15; i > 0 ; i--) { if (lastb[i] == 0x80) break; if (lastb[i] == 0x00) @@ -1543,7 +1574,11 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, sc_format_asn1_entry(asn1_piv_cvc, &asn1_piv_cvc_body, NULL, 1); r = sc_asn1_decode(card->ctx, asn1_piv_cvc, *buf, *buflen, NULL, NULL) ; /*(const u8 **) &buf_tmp, &len);*/ - LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate"); + if (r < 0) { + piv_clear_cvc_content(cvc); + sc_log(card->ctx, "Could not decode card verifiable certificate"); + LOG_FUNC_RETURN(card->ctx, r); + } cvc->signaturelen = signaturebits / 8; @@ -1577,7 +1612,7 @@ static int piv_decode_cvc(sc_card_t * card, u8 **buf, size_t *buflen, } -int piv_parse_pairing_code(sc_card_t *card, const char *option) +static int piv_parse_pairing_code(sc_card_t *card, const char *option) { size_t i; @@ -1618,7 +1653,7 @@ static int piv_load_options(sc_card_t *card) if (priv->max_object_size < PIV_MAX_OBJECT_SIZE) priv->max_object_size = PIV_MAX_OBJECT_SIZE; else - priv->max_object_size = MAX_FILE_SIZE; /* conserative value if error */ + priv->max_object_size = MAX_FILE_SIZE; /* conservative value if error */ } else piv_max_object_size_found = 1; sc_log(card->ctx," priv->max_object_size:%d", priv->max_object_size); @@ -1926,8 +1961,10 @@ static int piv_sm_verify_certs(struct sc_card *card) piv_private_data_t * priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; int r = 0; - const u8 *cert_blob = {0}; + u8 *cert_blob_unzipped = NULL; /* free */ + u8 *cert_blob = NULL; /* do not free */ size_t cert_bloblen = 0; + u8 *rbuf; /* do not free*/ size_t rbuflen; X509 *cert = NULL; @@ -1957,7 +1994,7 @@ static int piv_sm_verify_certs(struct sc_card *card) /* * Get the PIV_OBJ_SM_CERT_SIGNER and optional sm_in_cvc in cache * both are in same object. Rbuf, and rbuflen are needed but not used here - * sm_cvc and sm_in_cvc both have EC_keys sm_in_cvc may have RSA sginature + * sm_cvc and sm_in_cvc both have EC_keys sm_in_cvc may have RSA signature */ r = piv_get_cached_data(card, PIV_OBJ_SM_CERT_SIGNER, &rbuf, &rbuflen); if (r < 0) { @@ -1973,15 +2010,33 @@ static int piv_sm_verify_certs(struct sc_card *card) priv->sm_flags |= PIV_SM_FLAGS_SM_CERT_SIGNER_PRESENT; /* set for debugging */ /* get PIV_OBJ_SM_CERT_SIGNER cert DER from cache */ - cert_blob = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data; - cert_bloblen = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len; + if (priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].flags & PIV_OBJ_CACHE_COMPRESSED) { +#ifdef ENABLE_ZLIB + if (SC_SUCCESS != sc_decompress_alloc(&cert_blob_unzipped, &cert_bloblen, + priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data, + priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len, + COMPRESSION_AUTO)) { + sc_log(card->ctx, "PIV decompression of SM CERT_SIGNER failed"); + r = SC_ERROR_OBJECT_NOT_VALID; + goto err; + } + cert_blob = cert_blob_unzipped; +#else + sc_log(card->ctx, "PIV compression not supported, no zlib"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); +#endif + + } else { + cert_blob = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data; + cert_bloblen = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len; + } if (cert_blob == NULL || cert_bloblen == 0) { r = SC_ERROR_SM_AUTHENTICATION_FAILED; goto err; } - if ((cert = d2i_X509(NULL, &cert_blob, cert_bloblen)) == NULL + if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL || (cert_pkey = X509_get0_pubkey(cert)) == NULL) { sc_log(card->ctx,"OpenSSL failed to get pubkey from SM_CERT_SIGNER"); piv_log_openssl(card->ctx); @@ -2021,7 +2076,7 @@ static int piv_sm_verify_certs(struct sc_card *card) priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen); params[params_n] = OSSL_PARAM_construct_end(); - if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) + if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) || !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) || !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) || !in_cvc_pkey) { @@ -2065,6 +2120,8 @@ static int piv_sm_verify_certs(struct sc_card *card) */ err: X509_free(cert); + free(cert_blob_unzipped); + #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_GROUP_free(in_cvc_group); EC_POINT_free(in_cvc_point); @@ -2088,7 +2145,6 @@ static int piv_sm_open(struct sc_card *card) piv_private_data_t * priv = PIV_DATA(card); cipher_suite_t *cs = priv->cs; int r = 0; - int rc = 0; int i; int reps; u8 CBh; @@ -2221,7 +2277,7 @@ static int piv_sm_open(struct sc_card *card) eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "group", cs->curve_group, 0); eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string( "point-format","uncompressed", 0); eph_params[eph_params_n] = OSSL_PARAM_construct_end(); - if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) /* TODO should be FIPS */ + if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) /* TODO should be FIPS */ || !EVP_PKEY_keygen_init(eph_ctx) || !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) || !EVP_PKEY_generate(eph_ctx, &eph_pkey) @@ -2585,7 +2641,7 @@ static int piv_sm_open(struct sc_card *card) goto err; } #else - mac = EVP_MAC_fetch(NULL, "cmac", NULL); + mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL); cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0); cmac_params[cmac_params_n] = OSSL_PARAM_construct_end(); @@ -2602,13 +2658,13 @@ static int piv_sm_open(struct sc_card *card) } #endif - rc = memcmp(AuthCryptogram, Check_AuthCryptogram, cs->AuthCryptogramlen); - if (rc == 0) { + if (0 == memcmp(AuthCryptogram, Check_AuthCryptogram, cs->AuthCryptogramlen)) { sc_log(card->ctx,"AuthCryptogram compare"); r = 0; } else { sc_log(card->ctx,"AuthCryptogram compare failed"); r = SC_ERROR_SM_AUTHENTICATION_FAILED; + goto err; } } @@ -5255,6 +5311,7 @@ static int piv_match_card(sc_card_t *card) /* user provided card type must be one we know */ switch (card->type) { case -1: + case SC_CARD_TYPE_PIV_II_BASE: case SC_CARD_TYPE_PIV_II_GENERIC: case SC_CARD_TYPE_PIV_II_HIST: case SC_CARD_TYPE_PIV_II_NEO: @@ -5270,7 +5327,6 @@ static int piv_match_card(sc_card_t *card) case SC_CARD_TYPE_PIV_II_800_73_4: break; default: - /* User can not set SC_CARD_TYPE_PIV_II_BASE */ return 0; /* can not handle the card */ } @@ -5460,7 +5516,7 @@ static int piv_match_card_continued(sc_card_t *card) goto err; } - /* TODO Move up as discovery is useless Get Yubico version. Assumes all Yubikey cards are identified via ATR Historic bytes */ + /* Assumes all Yubikey cards are identified via ATR Historic bytes */ switch (card->type) { case SC_CARD_TYPE_PIV_II_NEO: case SC_CARD_TYPE_PIV_II_YUBIKEY4: @@ -5531,17 +5587,20 @@ static int piv_match_card_continued(sc_card_t *card) } sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); - /* AID also says if SM is supported or not */ + /* Read AID if needed for these cards types */ if (!(priv->init_flags & PIV_INIT_AID_PARSED)) { switch(card->type) { case SC_CARD_TYPE_PIV_II_BASE: case SC_CARD_TYPE_PIV_II_800_73_4: r2 = piv_find_aid(card); - if (priv->init_flags & PIV_INIT_AID_AC) { - card->type = SC_CARD_TYPE_PIV_II_800_73_4; - } } } + + /* If SM is supported, set SC_CARD_TYPE_PIV_II_800_73_4 */ + if (priv->init_flags & PIV_INIT_AID_AC) { + card->type = SC_CARD_TYPE_PIV_II_800_73_4; + } + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); #ifdef ENABLE_PIV_SM @@ -5550,6 +5609,7 @@ static int piv_match_card_continued(sc_card_t *card) card->type = SC_CARD_TYPE_PIV_II_800_73_4; } #endif + sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d\n", card->type, r2, priv->card_issues, r); /* * Set card_issues flags based card->type and version numbers if available. From a36db5f3b87bf9600e185b3b073e3072d2f04bf6 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Tue, 18 Jul 2023 11:43:57 -0500 Subject: [PATCH 3085/4321] card-piv.c - Do not enable PIV SM by default This is in response to: https://github.com/OpenSC/OpenSC/pull/2053#issuecomment-1638038085 configure.ac add --enable-piv-sm option with default disabled Changes to be committed: modified: configure.ac modified: doc/files/opensc.conf.5.xml.in modified: etc/opensc.conf.example.in modified: src/libopensc/card-piv.c --- configure.ac | 12 ++++++++++++ doc/files/opensc.conf.5.xml.in | 2 ++ etc/opensc.conf.example.in | 4 ++++ src/libopensc/card-piv.c | 13 +++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index de7e57ae6d..414d9a67a8 100644 --- a/configure.ac +++ b/configure.ac @@ -259,6 +259,13 @@ AC_ARG_ENABLE( [enable_sm="yes"] ) +AC_ARG_ENABLE( + [piv-sm], + [AS_HELP_STRING([--enable-piv-sm],[enable SM in PIV card driver linkage @<:@disabled@:>@])], + , + [enable_piv_sm="no"] +) + AC_ARG_ENABLE( [man], [AS_HELP_STRING([--disable-man],[disable installation of manuals @<:@enabled for none Windows@:>@])], @@ -854,6 +861,10 @@ else OPENPACE_LIBS="" fi +if test "${enable_piv_sm}" = "yes"; then + AC_DEFINE([ENABLE_PIV_SM], [1], [Enable PIV SM]) +fi + if test "${enable_openct}" = "yes"; then PKG_CHECK_MODULES( [OPENCT], @@ -1236,6 +1247,7 @@ minidriver support: ${enable_minidriver} SM support: ${enable_sm} SM default module: ${DEFAULT_SM_MODULE} SM default path: $(eval eval eval echo "${DEFAULT_SM_MODULE_PATH}") +PIV SM support: ${enable_piv_sm} DNIe UI support: ${enable_dnie_ui} Notification support: ${enable_notify} Code coverage: ${enable_code_coverage} diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 987d84e459..bd4d5b1c96 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -813,6 +813,7 @@ app application { PIV_MAX_OBJECT_SIZE environment variable. + diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 2d02b54cee..e4904a9e4d 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -237,6 +237,10 @@ app default { # piv_max_object_size = 16384; # May be set via environment: PIV_MAX_OBJECT_SIZE=16384 + # *NOTE* The following are only useble if OpenSC is configured with --enable-piv-sm + # The names and locations are likely to change in the future + # See: https://github.com/OpenSC/OpenSC/pull/2053/files#r1267388721 + # "piv_use_sm" # NIST sp800-73-4 supports Secure Messaging (SM), an optional feature. # diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 9fd8946802..abf0711b64 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -39,7 +39,7 @@ #endif #ifdef ENABLE_OPENSSL - /* openssl needed for card administration */ + /* openssl needed for card administration and SM */ #include #include #include @@ -59,7 +59,11 @@ /* 800-73-4 SM and VCI need: ECC, SM and real OpenSSL >= 1.1 */ #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) && !defined(OPENSSL_NO_EC) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L -#define ENABLE_PIV_SM +#else +#undef ENABLE_PIV_SM +#endif + +#ifdef ENABLE_PIV_SM #include #include "compression.h" #endif @@ -1694,6 +1698,11 @@ static int piv_load_options(sc_card_t *card) for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { #ifdef ENABLE_PIV_SM + +/* + * FIXME TODO - Names and locations of piv_pairing_code and piv_use_sm are likely to change in the future. + * See https://github.com/OpenSC/OpenSC/pull/2053/files#r1267388721 + */ /* * "piv_use_sm" if card supports NIST sp800-73-4 sm, when should it be used * never - use card like 800-73-3, i.e. contactless is very limited on From 8f52f82f20e7381845c7e310275f4093d1c4a350 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Fri, 21 Jul 2023 19:11:40 -0500 Subject: [PATCH 3086/4321] card-piv.c add sc_log for verify failure over contactless See: https://github.com/OpenSC/OpenSC/pull/2053/files#r1267420364 On branch PIV-4-extensions Changes to be committed: modified: card-piv.c --- src/libopensc/card-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index abf0711b64..6a3d87e97a 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -3048,8 +3048,6 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - /* assert(enumtag >= 0 && enumtag < PIV_OBJ_LAST_ENUM); */ - sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name); r = sc_lock(card); /* do check len and get data in same transaction */ @@ -6080,10 +6078,12 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 && priv->init_flags & PIV_INIT_CONTACTLESS && card->type == SC_CARD_TYPE_PIV_II_800_73_4) { + sc_log(card->ctx, "Token does not support pin verify over contacless reader"); /* TODO maybe true for other contactless cards */ r = SC_ERROR_NOT_SUPPORTED; } + /* if verify failed, release the lock */ if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) { sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC"); From fde759aa113bfe667fbdb1c5bea6b5cb842ce79a Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 22 Jul 2023 09:26:44 -0500 Subject: [PATCH 3087/4321] pkcs15-piv.c fix memory leak of one pubkey found by valgrind The Secure Messaging Certificate Signer does not have a private key on the card. The public key was extracted from the certificate but never freed later while creating private key entries. On branch PIV-4-extensions Changes to be committed: modified: pkcs15-piv.c --- src/libopensc/pkcs15-piv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 06135c23cb..223bb089de 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -340,6 +340,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) * not have a private keys on the card. These certs must be last */ + /* Any certs on card without private key must be last */ #define PIV_NUM_CERTS 25 #define PIV_NUM_KEYS 24 @@ -943,8 +944,10 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card) sc_log(card->ctx, "Unsupported key.algorithm %d", cert_out->key->algorithm); ckis[i].pubkey_len = 0; /* set some value for now */ } - ckis[i].pubkey_from_cert = cert_out->key; - cert_out->key = NULL; + if (i < PIV_NUM_KEYS) { /* Only save pub key if card can have private key */ + ckis[i].pubkey_from_cert = cert_out->key; + cert_out->key = NULL; + } sc_pkcs15_free_certificate(cert_out); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); From ccb6f3c71995e262487b764abb4b0b9d035d8431 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Mon, 14 Aug 2023 20:43:50 +0200 Subject: [PATCH 3088/4321] replace PIV_MAX_OBJECT_SIZE with MAX_FILE_SIZE simplify code and configuration options --- doc/files/opensc.conf.5.xml.in | 11 ---------- etc/opensc.conf.example.in | 10 --------- src/libopensc/card-piv.c | 40 +++++----------------------------- 3 files changed, 6 insertions(+), 55 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index bd4d5b1c96..80a00c4c6f 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -803,16 +803,6 @@ app application { Configuration Options for PIV Card - - - - - - Max size of a PIV object. The default of 16384 bytes should - work for most cards. It might be overwritten by - PIV_MAX_OBJECT_SIZE environment variable. - -

    OpenSC Manual Pages: Section 5


    Table of Contents

    opensc.conf — configuration file for OpenSC
    pkcs15-profile — format of profile for pkcs15-init

    Name

    opensc.conf — configuration file for OpenSC

    Description

    + -->

    OpenSC Manual Pages: Section 5


    Table of Contents

    opensc.conf — configuration file for OpenSC
    pkcs15-profile — format of profile for pkcs15-init

    Name

    opensc.conf — configuration file for OpenSC

    Description

    OpenSC obtains configuration data from the following sources in the following order

    1. command-line options @@ -57,7 +57,7 @@ HKEY_LOCAL_MACHINE (if available)

    2. system-wide configuration file - (/usr/etc/opensc.conf) + (/etc/opensc.conf)

    The configuration file, opensc.conf, is composed @@ -89,6 +89,8 @@ application specifies one of:

    • + filename: Configuration block for the application with specified file path. +

    • default: The fall-back configuration block for all applications

    • opensc-pkcs11: Configuration block for the PKCS#11 module (opensc-pkcs11.so) @@ -143,7 +145,7 @@ profile_dir = filename;

    PKCS#15 initialization/personalization profiles - directory for + directory for pkcs15-init(1). (Default: /usr/share/opensc). @@ -212,16 +214,16 @@

    Configuration of the smart card reader driver where name is one of:

    - See the section called “Configuration of Smart Card Reader Driver”. + See the section called “Configuration of Smart Card Reader Driverâ€.

    card_driver name { block_contents @@ -230,13 +232,15 @@

    Configuration of the card driver where name is one of:

    @@ -251,27 +255,26 @@ the driver using the card_atr block.

    - For details see the section called “Configuration based on ATR”. + For details see the section called “Configuration based on ATRâ€.

    - disable_hw_pkcs1_padding = value; -

    + disable_hw_pkcs1_padding = value; +

    Disabling PKCS#1 v1.5 padding in HW when card supports doing raw RSA operations. Known parameters: -

    • - no: - PKCS#1 v1.5 padding is enabled in HW when card supports it. +

      • + no: PKCS#1 v1.5 padding is enabled in HW when card supports it.

      • sign: PKCS#1 v1.5 padding - is disabled only for signatures (PKCS#1 v1.5 type 1). + is disabled only for signatures (PKCS#1 v1.5 type 1).

      • decipher: PKCS#1 v1.5 padding - is disabled only for decryption (PKCS#1 v1.5 type 2). + is disabled only for decryption (PKCS#1 v1.5 type 2).

      • both: PKCS#1 v1.5 padding - is disabled both for signatures and decryption (PKCS#1 v1.5 type 1 and 2). + is disabled both for signatures and decryption (PKCS#1 v1.5 type 1 and 2).

      - (Default: decipher). -

    + (Default: decipher). +

    secure_messaging name { block_contents } @@ -286,7 +289,7 @@ module_path = filename;

    Directory with external SM module - (Default: /usr/lib). + (Default: /usr/lib64).

    If this configuration value is not found on Windows, the registry key @@ -348,9 +351,9 @@

    Internal configuration options where name is one of:

    pkcs11 { @@ -360,7 +363,7 @@

    Parameters for the OpenSC PKCS11 module.

    - For details see the section called “Configuration of PKCS#11”. + For details see the section called “Configuration of PKCS#11â€.

    Configuration of Smart Card Reader Driver

    Configuration Options for all Reader Drivers

    max_send_size = num; max_recv_size = num; @@ -478,8 +481,8 @@ card driver will do everything necessary before sending the data (hash code) to the card. -

    - PKCS#1 v1.5 padding in HW can be globally disabled by option disable_hw_pkcs1_padding. +

    + PKCS#1 v1.5 padding in HW can be globally disabled by option disable_hw_pkcs1_padding. When the global option is used to disable padding, the padding will be disabled even though the MyEID-specific option does not turn it off.

    Configuration Options for German ID Card

    can = value; @@ -533,14 +536,26 @@

    Configuration Options for Polish eID Card

    can = value;

    - CAN (Card Access Number – 6 digit number + CAN (Card Access Number – 6 digit number printed on the right bottom corner of the front side of the document) is required to establish connection with the card. It might be overwritten by EDO_CAN environment variable. Currently, it is not possible to set it in any other way. -

    Configuration based on ATR

    +

    Configuration Options for Slovenian eID Card

    + can = value; +

    + CAN (Card Access Number – 6 digit number + printed on the right bottom corner of the + front side of the document) is required + to establish connection with the card. + It might be overwritten by EOI_CAN + environment variable. As CAN is also stored on the card + (in encrypted form) it can be used to automatically establish + secure connection, but only if the card is accessed over the + contact interface. +

    Configuration Options for PIV Card

    Configuration based on ATR

    atrmask = hexstring;

    @@ -798,7 +813,6 @@ jpki, MaskTech, mcrd, - MyEID, npa, nqapplet, tcos and otherwise no). @@ -829,6 +843,15 @@ cached information. Note that the cached files may contain personal data such as name and mail address. +

    + The PIV-II card driver supports the history object's + list of retired keys and certificates if they are + readable in the file cache directory. + If the specified object's URL is + "http://"DNS name"/"ASCII-HEX OffCardKeyHistoryFile, + then the searches for the file name + OffCardKeyHistoryFile + in the cache directory.

    use_pin_caching = bool;

    @@ -960,6 +983,14 @@ Do not expose application in PKCS#15 framework (Default: false) +

    + user_pin = name; +

    + Name of the User PIN object that will be used as the main PIN. +

    + sign_pin = name; +

    + Name of the PIN object that will be used for signing.